]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/commitdiff
Merge tag 'clk-for-linus-3.20' of git://git.linaro.org/people/mike.turquette/linux
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 21 Feb 2015 20:30:30 +0000 (12:30 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 21 Feb 2015 20:30:30 +0000 (12:30 -0800)
Pull clock framework updates from Mike Turquette:
 "The clock framework changes contain the usual driver additions,
  enhancements and fixes mostly for ARM32, ARM64, MIPS and Power-based
  devices.

  Additionally the framework core underwent a bit of surgery with two
  major changes:

   - The boundary between the clock core and clock providers (e.g clock
     drivers) is now more well defined with dedicated provider helper
     functions.  struct clk no longer maps 1:1 with the hardware clock
     but is a true per-user cookie which helps us tracker users of
     hardware clocks and debug bad behavior.

   - The addition of rate constraints for clocks.  Rate ranges are now
     supported which are analogous to the voltage ranges in the
     regulator framework.

  Unfortunately these changes to the core created some breakeage.  We
  think we fixed it all up but for this reason there are lots of last
  minute commits trying to undo the damage"

* tag 'clk-for-linus-3.20' of git://git.linaro.org/people/mike.turquette/linux: (113 commits)
  clk: Only recalculate the rate if needed
  Revert "clk: mxs: Fix invalid 32-bit access to frac registers"
  clk: qoriq: Add support for the platform PLL
  powerpc/corenet: Enable CLK_QORIQ
  clk: Replace explicit clk assignment with __clk_hw_set_clk
  clk: Add __clk_hw_set_clk helper function
  clk: Don't dereference parent clock if is NULL
  MIPS: Alchemy: Remove bogus args from alchemy_clk_fgcs_detr
  clkdev: Always allocate a struct clk and call __clk_get() w/ CCF
  clk: shmobile: div6: Avoid division by zero in .round_rate()
  clk: mxs: Fix invalid 32-bit access to frac registers
  clk: omap: compile legacy omap3 clocks conditionally
  clkdev: Export clk_register_clkdev
  clk: Add rate constraints to clocks
  clk: remove clk-private.h
  pci: xgene: do not use clk-private.h
  arm: omap2+ remove dead clock code
  clk: Make clk API return per-user struct clk instances
  clk: tegra: Define PLLD_DSI and remove dsia(b)_mux
  clk: tegra: Add support for the Tegra132 CAR IP block
  ...

22 files changed:
1  2 
MAINTAINERS
arch/arm/boot/dts/sun4i-a10.dtsi
arch/arm/boot/dts/sun5i-a10s.dtsi
arch/arm/boot/dts/sun5i-a13.dtsi
arch/arm/boot/dts/sun6i-a31.dtsi
arch/arm/boot/dts/sun7i-a20.dtsi
arch/arm/boot/dts/sun8i-a23.dtsi
arch/arm/mach-omap2/Makefile
arch/arm/mach-omap2/clock.c
arch/arm/mach-omap2/clock.h
arch/arm/mach-omap2/dpll44xx.c
arch/arm/mach-omap2/io.c
arch/arm/mach-omap2/prm_common.c
arch/powerpc/configs/corenet32_smp_defconfig
arch/powerpc/configs/corenet64_smp_defconfig
arch/powerpc/kernel/time.c
drivers/clk/Kconfig
drivers/clk/clk.c
drivers/clk/rockchip/clk-rk3288.c
drivers/clk/shmobile/Makefile
drivers/clk/sunxi/clk-sunxi.c
drivers/mmc/host/sunxi-mmc.c

diff --combined MAINTAINERS
index 7cfcee4e2bea2f7402c2e6bce16df6943aeb2c5c,8fbc5f759a044d5e273fac588420a61736d45fe1..574321803958647a11cd88b4089ced0a0b7f718a
@@@ -34,7 -34,7 +34,7 @@@ trivial patch so apply some common sens
        generalized kernel feature ready for next time.
  
        PLEASE check your patch with the automated style checker
 -      (scripts/checkpatch.pl) to catch trival style violations.
 +      (scripts/checkpatch.pl) to catch trivial style violations.
        See Documentation/CodingStyle for guidance here.
  
        PLEASE CC: the maintainers and mailing lists that are generated
@@@ -270,12 -270,12 +270,12 @@@ F:      drivers/acpi
  F:    drivers/pnp/pnpacpi/
  F:    include/linux/acpi.h
  F:    include/acpi/
 -F:    Documentation/acpi
 +F:    Documentation/acpi/
  F:    Documentation/ABI/testing/sysfs-bus-acpi
  F:    drivers/pci/*acpi*
  F:    drivers/pci/*/*acpi*
  F:    drivers/pci/*/*/*acpi*
 -F:    tools/power/acpi
 +F:    tools/power/acpi/
  
  ACPI COMPONENT ARCHITECTURE (ACPICA)
  M:    Robert Moore <robert.moore@intel.com>
@@@ -563,12 -563,6 +563,12 @@@ S:       Odd Fixe
  L:    linux-alpha@vger.kernel.org
  F:    arch/alpha/
  
 +ALTERA MAILBOX DRIVER
 +M:    Ley Foon Tan <lftan@altera.com>
 +L:    nios2-dev@lists.rocketboards.org (moderated for non-subscribers)
 +S:    Maintained
 +F:    drivers/mailbox/mailbox-altera.c
 +
  ALTERA TRIPLE SPEED ETHERNET DRIVER
  M:    Vince Bridgers <vbridger@opensource.altera.com>
  L:    netdev@vger.kernel.org
@@@ -630,8 -624,6 +630,8 @@@ L:      dri-devel@lists.freedesktop.or
  T:      git git://people.freedesktop.org/~gabbayo/linux.git
  S:      Supported
  F:      drivers/gpu/drm/amd/amdkfd/
 +F:    drivers/gpu/drm/amd/include/cik_structs.h
 +F:    drivers/gpu/drm/amd/include/kgd_kfd_interface.h
  F:      drivers/gpu/drm/radeon/radeon_kfd.c
  F:      drivers/gpu/drm/radeon/radeon_kfd.h
  F:      include/uapi/linux/kfd_ioctl.h
@@@ -667,13 -659,6 +667,13 @@@ L:       linux-media@vger.kernel.or
  S:    Maintained
  F:    drivers/media/i2c/ad9389b*
  
 +ANALOG DEVICES INC ADV7180 DRIVER
 +M:    Lars-Peter Clausen <lars@metafoo.de>
 +L:    linux-media@vger.kernel.org
 +W:    http://ez.analog.com/community/linux-device-drivers
 +S:    Supported
 +F:    drivers/media/i2c/adv7180.c
 +
  ANALOG DEVICES INC ADV7511 DRIVER
  M:    Hans Verkuil <hans.verkuil@cisco.com>
  L:    linux-media@vger.kernel.org
@@@ -895,7 -880,6 +895,7 @@@ F: arch/arm/boot/dts/at91*.dt
  F:    arch/arm/boot/dts/at91*.dtsi
  F:    arch/arm/boot/dts/sama*.dts
  F:    arch/arm/boot/dts/sama*.dtsi
 +F:    arch/arm/include/debug/at91.S
  
  ARM/ATMEL AT91 Clock Support
  M:    Boris Brezillon <boris.brezillon@free-electrons.com>
@@@ -977,7 -961,7 +977,7 @@@ S: Maintaine
  F:    arch/arm/mach-prima2/
  F:    drivers/clk/sirf/
  F:    drivers/clocksource/timer-prima2.c
 -F:    drivers/clocksource/timer-marco.c
 +F:    drivers/clocksource/timer-atlas7.c
  N:    [^a-z]sirf
  
  ARM/EBSA110 MACHINE SUPPORT
@@@ -1176,7 -1160,6 +1176,7 @@@ M:      Sebastian Hesselbarth <sebastian.hes
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
  S:    Maintained
  F:    arch/arm/mach-mvebu/
 +F:    drivers/rtc/armada38x-rtc
  
  ARM/Marvell Berlin SoC support
  M:    Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
@@@ -1310,13 -1293,10 +1310,13 @@@ S:   Maintaine
  
  ARM/QUALCOMM SUPPORT
  M:    Kumar Gala <galak@codeaurora.org>
 +M:    Andy Gross <agross@codeaurora.org>
  M:    David Brown <davidb@codeaurora.org>
  L:    linux-arm-msm@vger.kernel.org
 +L:    linux-soc@vger.kernel.org
  S:    Maintained
  F:    arch/arm/mach-qcom/
 +F:    drivers/soc/qcom/
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/galak/linux-qcom.git
  
  ARM/RADISYS ENP2611 MACHINE SUPPORT
@@@ -1418,6 -1398,7 +1418,6 @@@ F:      arch/arm/configs/ape6evm_defconfi
  F:    arch/arm/configs/armadillo800eva_defconfig
  F:    arch/arm/configs/bockw_defconfig
  F:    arch/arm/configs/kzm9g_defconfig
 -F:    arch/arm/configs/lager_defconfig
  F:    arch/arm/configs/mackerel_defconfig
  F:    arch/arm/configs/marzen_defconfig
  F:    arch/arm/configs/shmobile_defconfig
@@@ -1605,14 -1586,12 +1605,14 @@@ N:   xilin
  F:    drivers/clocksource/cadence_ttc_timer.c
  F:    drivers/i2c/busses/i2c-cadence.c
  F:    drivers/mmc/host/sdhci-of-arasan.c
 +F:    drivers/edac/synopsys_edac.c
  
  ARM SMMU DRIVER
  M:    Will Deacon <will.deacon@arm.com>
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
  S:    Maintained
  F:    drivers/iommu/arm-smmu.c
 +F:    drivers/iommu/io-pgtable-arm.c
  
  ARM64 PORT (AARCH64 ARCHITECTURE)
  M:    Catalin Marinas <catalin.marinas@arm.com>
@@@ -1681,6 -1660,7 +1681,6 @@@ M:      Jiri Slaby <jirislaby@gmail.com
  M:    Nick Kossifidis <mickflemm@gmail.com>
  M:    "Luis R. Rodriguez" <mcgrof@do-not-panic.com>
  L:    linux-wireless@vger.kernel.org
 -L:    ath5k-devel@lists.ath5k.org
  W:    http://wireless.kernel.org/en/users/Drivers/ath5k
  S:    Maintained
  F:    drivers/net/wireless/ath/ath5k/
@@@ -2147,7 -2127,7 +2147,7 @@@ F:      arch/arm/boot/dts/bcm470
  BROADCOM BCM63XX ARM ARCHITECTURE
  M:    Florian Fainelli <f.fainelli@gmail.com>
  L:    linux-arm-kernel@lists.infradead.org
 -T:    git git://git.github.com/brcm/linux.git
 +T:    git git://github.com/broadcom/arm-bcm63xx.git
  S:    Maintained
  F:    arch/arm/mach-bcm/bcm63xx.c
  F:    arch/arm/include/debug/bcm63xx.S
@@@ -2164,7 -2144,6 +2164,7 @@@ M:      Brian Norris <computersforpeace@gmai
  M:    Gregory Fong <gregory.0xf0@gmail.com>
  M:    Florian Fainelli <f.fainelli@gmail.com>
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 +T:    git git://github.com/broadcom/stblinux.git
  S:    Maintained
  F:    arch/arm/mach-bcm/*brcmstb*
  F:    arch/arm/boot/dts/bcm7*.dts*
@@@ -2174,7 -2153,6 +2174,7 @@@ BROADCOM BMIPS MIPS ARCHITECTUR
  M:    Kevin Cernekee <cernekee@gmail.com>
  M:    Florian Fainelli <f.fainelli@gmail.com>
  L:    linux-mips@linux-mips.org
 +T:    git git://github.com/broadcom/stblinux.git
  S:    Maintained
  F:    arch/mips/bmips/*
  F:    arch/mips/include/asm/mach-bmips/*
@@@ -2217,7 -2195,7 +2217,7 @@@ M:      Ray Jui <rjui@broadcom.com
  M:    Scott Branden <sbranden@broadcom.com>
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
  L:    bcm-kernel-feedback-list@broadcom.com
 -T:    git git://git.github.com/brcm/linux.git
 +T:    git git://github.com/broadcom/cygnus-linux.git
  S:    Maintained
  N:    iproc
  N:    cygnus
@@@ -2406,12 -2384,6 +2406,12 @@@ F:    security/capability.
  F:    security/commoncap.c
  F:    kernel/capability.c
  
 +CAPELLA MICROSYSTEMS LIGHT SENSOR DRIVER
 +M:    Kevin Tsai <ktsai@capellamicro.com>
 +S:    Maintained
 +F:    drivers/iio/light/cm*
 +F:    Documentation/devicetree/bindings/i2c/trivial-devices.txt
 +
  CC2520 IEEE-802.15.4 RADIO DRIVER
  M:    Varka Bhadram <varkabhadram@gmail.com>
  L:    linux-wpan@vger.kernel.org
@@@ -2433,8 -2405,7 +2433,8 @@@ F:      arch/powerpc/oprofile/*cell
  F:    arch/powerpc/platforms/cell/
  
  CEPH DISTRIBUTED FILE SYSTEM CLIENT
 -M:    Sage Weil <sage@inktank.com>
 +M:    Yan, Zheng <zyan@redhat.com>
 +M:    Sage Weil <sage@redhat.com>
  L:    ceph-devel@vger.kernel.org
  W:    http://ceph.com/
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client.git
@@@ -2971,12 -2942,6 +2971,12 @@@ S:    Supporte
  F:    drivers/input/touchscreen/cyttsp*
  F:    include/linux/input/cyttsp.h
  
 +DALLAS/MAXIM DS1685-FAMILY REAL TIME CLOCK
 +M:    Joshua Kinard <kumba@gentoo.org>
 +S:    Maintained
 +F:    drivers/rtc/rtc-ds1685.c
 +F:    include/linux/rtc/ds1685.h
 +
  DAMA SLAVE for AX.25
  M:    Joerg Reuter <jreuter@yaina.de>
  W:    http://yaina.de/jreuter/
@@@ -3053,7 -3018,6 +3053,7 @@@ F:      drivers/platform/x86/dell-laptop.
  
  DELL LAPTOP SMM DRIVER
  M:    Guenter Roeck <linux@roeck-us.net>
 +S:    Maintained
  F:    drivers/char/i8k.c
  F:    include/uapi/linux/i8k.h
  
@@@ -3069,7 -3033,7 +3069,7 @@@ S:      Maintaine
  F:    drivers/platform/x86/dell-wmi.c
  
  DESIGNWARE USB2 DRD IP DRIVER
 -M:    Paul Zimmerman <paulz@synopsys.com>
 +M:    John Youn <johnyoun@synopsys.com>
  L:    linux-usb@vger.kernel.org
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb.git
  S:    Maintained
@@@ -3165,12 -3129,6 +3165,12 @@@ L:    linux-i2c@vger.kernel.or
  S:    Maintained
  F:    drivers/i2c/busses/i2c-diolan-u2c.c
  
 +DIRECT ACCESS (DAX)
 +M:    Matthew Wilcox <willy@linux.intel.com>
 +L:    linux-fsdevel@vger.kernel.org
 +S:    Supported
 +F:    fs/dax.c
 +
  DIRECTORY NOTIFICATION (DNOTIFY)
  M:    Eric Paris <eparis@parisplace.org>
  S:    Maintained
@@@ -3255,7 -3213,6 +3255,7 @@@ F:      Documentation
  X:    Documentation/ABI/
  X:    Documentation/devicetree/
  X:    Documentation/[a-z][a-z]_[A-Z][A-Z]/
 +T:    git git://git.lwn.net/linux-2.6.git docs-next
  
  DOUBLETALK DRIVER
  M:    "James R. Van Zandt" <jrv@vanzandt.mv.com>
@@@ -3515,14 -3472,6 +3515,14 @@@ M:    "Maciej W. Rozycki" <macro@linux-mip
  S:    Maintained
  F:    drivers/tty/serial/dz.*
  
 +E3X0 POWER BUTTON DRIVER
 +M:    Moritz Fischer <moritz.fischer@ettus.com>
 +L:    usrp-users@lists.ettus.com
 +W:    http://www.ettus.com
 +S:    Supported
 +F:    drivers/input/misc/e3x0-button.c
 +F:    Documentation/devicetree/bindings/input/e3x0-button.txt
 +
  E4000 MEDIA DRIVER
  M:    Antti Palosaari <crope@iki.fi>
  L:    linux-media@vger.kernel.org
@@@ -3564,8 -3513,6 +3564,8 @@@ M:      Borislav Petkov <bp@alien8.de
  M:    Mauro Carvalho Chehab <mchehab@osg.samsung.com>
  L:    linux-edac@vger.kernel.org
  W:    bluesmoke.sourceforge.net
 +T:    git://git.kernel.org/pub/scm/linux/kernel/git/bp/bp.git#for-next
 +T:    git://git.kernel.org/pub/linux/kernel/git/mchehab/linux-edac.git#linux_next
  S:    Supported
  F:    Documentation/edac.txt
  F:    drivers/edac/
@@@ -3930,12 -3877,6 +3930,12 @@@ S:    Supporte
  F:    Documentation/fault-injection/
  F:    lib/fault-inject.c
  
 +FBTFT Framebuffer drivers
 +M:    Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
 +M:    Noralf Trønnes <noralf@tronnes.org>
 +S:    Maintained
 +F:    drivers/staging/fbtft/
 +
  FCOE SUBSYSTEM (libfc, libfcoe, fcoe)
  M:    Robert Love <robert.w.love@intel.com>
  L:    fcoe-devel@open-fcoe.org
@@@ -4093,12 -4034,6 +4093,12 @@@ S:    Maintaine
  F:    include/linux/platform_data/video-imxfb.h
  F:    drivers/video/fbdev/imxfb.c
  
 +FREESCALE QUAD SPI DRIVER
 +M:    Han Xu <han.xu@freescale.com>
 +L:    linux-mtd@lists.infradead.org
 +S:    Maintained
 +F:    drivers/mtd/spi-nor/fsl-quadspi.c
 +
  FREESCALE SOC FS_ENET DRIVER
  M:    Pantelis Antoniou <pantelis.antoniou@gmail.com>
  M:    Vitaly Bordug <vbordug@ru.mvista.com>
@@@ -4239,11 -4174,6 +4239,11 @@@ W:    http://www.icp-vortex.com
  S:    Supported
  F:    drivers/scsi/gdt*
  
 +GDB KERNEL DEBUGGING HELPER SCRIPTS
 +M:    Jan Kiszka <jan.kiszka@siemens.com>
 +S:    Supported
 +F:    scripts/gdb/
 +
  GEMTEK FM RADIO RECEIVER DRIVER
  M:    Hans Verkuil <hverkuil@xs4all.nl>
  L:    linux-media@vger.kernel.org
@@@ -4478,7 -4408,6 +4478,7 @@@ F:      include/linux/hwmon*.
  HARDWARE RANDOM NUMBER GENERATOR CORE
  M:    Matt Mackall <mpm@selenic.com>
  M:    Herbert Xu <herbert@gondor.apana.org.au>
 +L:    linux-crypto@vger.kernel.org
  S:    Odd fixes
  F:    Documentation/hw_random.txt
  F:    drivers/char/hw_random/
@@@ -4964,7 -4893,7 +4964,7 @@@ F:      drivers/ipack
  
  INTEGRITY MEASUREMENT ARCHITECTURE (IMA)
  M:    Mimi Zohar <zohar@linux.vnet.ibm.com>
 -M:    Dmitry Kasatkin <d.kasatkin@samsung.com>
 +M:    Dmitry Kasatkin <dmitry.kasatkin@gmail.com>
  L:    linux-ima-devel@lists.sourceforge.net
  L:    linux-ima-user@lists.sourceforge.net
  L:    linux-security-module@vger.kernel.org
@@@ -5024,16 -4953,6 +5024,16 @@@ F:    Documentation/input/multi-touch-prot
  F:    drivers/input/input-mt.c
  K:    \b(ABS|SYN)_MT_
  
 +INTEL ASoC BDW/HSW DRIVERS
 +M:    Jie Yang <yang.jie@linux.intel.com>
 +L:    alsa-devel@alsa-project.org
 +S:    Supported
 +F:    sound/soc/intel/sst-haswell*
 +F:    sound/soc/intel/sst-dsp*
 +F:    sound/soc/intel/sst-firmware.c
 +F:    sound/soc/intel/broadwell.c
 +F:    sound/soc/intel/haswell.c
 +
  INTEL C600 SERIES SAS CONTROLLER DRIVER
  M:    Intel SCU Linux support <intel-linux-scu@intel.com>
  M:    Artur Paszkiewicz <artur.paszkiewicz@intel.com>
@@@ -5921,21 -5840,6 +5921,21 @@@ F:    Documentation/misc-devices/lis3lv02
  F:    drivers/misc/lis3lv02d/
  F:    drivers/platform/x86/hp_accel.c
  
 +LIVE PATCHING
 +M:    Josh Poimboeuf <jpoimboe@redhat.com>
 +M:    Seth Jennings <sjenning@redhat.com>
 +M:    Jiri Kosina <jkosina@suse.cz>
 +M:    Vojtech Pavlik <vojtech@suse.cz>
 +S:    Maintained
 +F:    kernel/livepatch/
 +F:    include/linux/livepatch.h
 +F:    arch/x86/include/asm/livepatch.h
 +F:    arch/x86/kernel/livepatch.c
 +F:    Documentation/ABI/testing/sysfs-kernel-livepatch
 +F:    samples/livepatch/
 +L:    live-patching@vger.kernel.org
 +T:    git git://git.kernel.org/pub/scm/linux/kernel/git/jikos/livepatching.git
 +
  LLC (802.2)
  M:    Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
  S:    Maintained
@@@ -6234,33 -6138,6 +6234,33 @@@ F:    Documentation/devicetree/bindings/i2
  F:    drivers/hwmon/max6697.c
  F:    include/linux/platform_data/max6697.h
  
 +MAXIM MUIC CHARGER DRIVERS FOR EXYNOS BASED BOARDS
 +M:    Krzysztof Kozlowski <k.kozlowski@samsung.com>
 +L:    linux-pm@vger.kernel.org
 +S:    Supported
 +F:    drivers/power/max14577_charger.c
 +F:    drivers/power/max77693_charger.c
 +
 +MAXIM PMIC AND MUIC DRIVERS FOR EXYNOS BASED BOARDS
 +M:    Chanwoo Choi <cw00.choi@samsung.com>
 +M:    Krzysztof Kozlowski <k.kozlowski@samsung.com>
 +L:    linux-kernel@vger.kernel.org
 +S:    Supported
 +F:    drivers/*/max14577.c
 +F:    drivers/*/max77686.c
 +F:    drivers/*/max77693.c
 +F:    drivers/extcon/extcon-max14577.c
 +F:    drivers/extcon/extcon-max77693.c
 +F:    drivers/rtc/rtc-max77686.c
 +F:    drivers/clk/clk-max77686.c
 +F:    Documentation/devicetree/bindings/mfd/max14577.txt
 +F:    Documentation/devicetree/bindings/mfd/max77686.txt
 +F:    Documentation/devicetree/bindings/mfd/max77693.txt
 +F:    Documentation/devicetree/bindings/clock/maxim,max77686.txt
 +F:    include/linux/mfd/max14577*.h
 +F:    include/linux/mfd/max77686*.h
 +F:    include/linux/mfd/max77693*.h
 +
  MAXIRADIO FM RADIO RECEIVER DRIVER
  M:    Hans Verkuil <hverkuil@xs4all.nl>
  L:    linux-media@vger.kernel.org
@@@ -6291,6 -6168,14 +6291,6 @@@ F:     include/uapi/linux/meye.
  F:    include/uapi/linux/ivtv*
  F:    include/uapi/linux/uvcvideo.h
  
 -MEDIAVISION PRO MOVIE STUDIO DRIVER
 -M:    Hans Verkuil <hverkuil@xs4all.nl>
 -L:    linux-media@vger.kernel.org
 -T:    git git://linuxtv.org/media_tree.git
 -W:    http://linuxtv.org
 -S:    Odd Fixes
 -F:    drivers/media/parport/pms*
 -
  MEGARAID SCSI/SAS DRIVERS
  M:    Kashyap Desai <kashyap.desai@avagotech.com>
  M:    Sumit Saxena <sumit.saxena@avagotech.com>
@@@ -6708,10 -6593,9 +6708,10 @@@ F:    include/uapi/linux/netrom.
  F:    net/netrom/
  
  NETWORK BLOCK DEVICE (NBD)
 -M:    Paul Clements <Paul.Clements@steeleye.com>
 +M:    Markus Pargmann <mpa@pengutronix.de>
  S:    Maintained
  L:    nbd-general@lists.sourceforge.net
 +T:    git git://git.pengutronix.de/git/mpa/linux-nbd.git
  F:    Documentation/blockdev/nbd.txt
  F:    drivers/block/nbd.c
  F:    include/linux/nbd.h
@@@ -6740,7 -6624,6 +6740,7 @@@ F:      include/linux/netdevice.
  F:    include/uapi/linux/in.h
  F:    include/uapi/linux/net.h
  F:    include/uapi/linux/netdevice.h
 +F:    include/uapi/linux/net_namespace.h
  F:    tools/net/
  F:    tools/testing/selftests/net/
  F:    lib/random32.c
@@@ -6845,7 -6728,6 +6845,7 @@@ F:      Documentation/devicetree/bindings/ne
  
  NFS, SUNRPC, AND LOCKD CLIENTS
  M:    Trond Myklebust <trond.myklebust@primarydata.com>
 +M:    Anna Schumaker <anna.schumaker@netapp.com>
  L:    linux-nfs@vger.kernel.org
  W:    http://client.linux-nfs.org
  T:    git git://git.linux-nfs.org/projects/trondmy/linux-nfs.git
@@@ -6888,7 -6770,7 +6888,7 @@@ F:      drivers/scsi/nsp32
  NIOS2 ARCHITECTURE
  M:    Ley Foon Tan <lftan@altera.com>
  L:    nios2-dev@lists.rocketboards.org (moderated for non-subscribers)
 -T:    git git://git.rocketboards.org/linux-socfpga.git
 +T:    git git://git.rocketboards.org/linux-socfpga-next.git
  S:    Maintained
  F:    arch/nios2/
  
@@@ -7061,12 -6943,6 +7061,12 @@@ L:    linux-omap@vger.kernel.or
  S:    Maintained
  F:    arch/arm/mach-omap2/omap_hwmod.*
  
 +OMAP HWMOD DATA
 +M:    Paul Walmsley <paul@pwsan.com>
 +L:    linux-omap@vger.kernel.org
 +S:    Maintained
 +F:    arch/arm/mach-omap2/omap_hwmod*data*
 +
  OMAP HWMOD DATA FOR OMAP4-BASED DEVICES
  M:    Benoît Cousson <bcousson@baylibre.com>
  L:    linux-omap@vger.kernel.org
@@@ -7186,12 -7062,11 +7186,12 @@@ F:   arch/openrisc
  
  OPENVSWITCH
  M:    Pravin Shelar <pshelar@nicira.com>
 +L:    netdev@vger.kernel.org
  L:    dev@openvswitch.org
  W:    http://openvswitch.org
 -T:    git git://git.kernel.org/pub/scm/linux/kernel/git/pshelar/openvswitch.git
  S:    Maintained
  F:    net/openvswitch/
 +F:    include/uapi/linux/openvswitch.h
  
  OPL4 DRIVER
  M:    Clemens Ladisch <clemens@ladisch.de>
@@@ -7303,7 -7178,7 +7303,7 @@@ M:      Alok Kataria <akataria@vmware.com
  M:    Rusty Russell <rusty@rustcorp.com.au>
  L:    virtualization@lists.linux-foundation.org
  S:    Supported
 -F:    Documentation/ia64/paravirt_ops.txt
 +F:    Documentation/virtual/paravirt_ops.txt
  F:    arch/*/kernel/paravirt*
  F:    arch/*/include/asm/paravirt.h
  
@@@ -7389,14 -7264,6 +7389,14 @@@ F:    include/linux/pci
  F:    arch/x86/pci/
  F:    arch/x86/kernel/quirks.c
  
 +PCI DRIVER FOR ARM VERSATILE PLATFORM
 +M:    Rob Herring <robh@kernel.org>
 +L:    linux-pci@vger.kernel.org
 +L:    linux-arm-kernel@lists.infradead.org
 +S:    Maintained
 +F:    Documentation/devicetree/bindings/pci/versatile.txt
 +F:    drivers/pci/host/pci-versatile.c
 +
  PCI DRIVER FOR APPLIEDMICRO XGENE
  M:    Tanmay Inamdar <tinamdar@apm.com>
  L:    linux-pci@vger.kernel.org
@@@ -7998,9 -7865,17 +7998,9 @@@ T:     git git://github.com/KrasnikovEugene
  S:    Supported
  F:    drivers/net/wireless/ath/wcn36xx/
  
 -QUICKCAM PARALLEL PORT WEBCAMS
 -M:    Hans Verkuil <hverkuil@xs4all.nl>
 -L:    linux-media@vger.kernel.org
 -T:    git git://linuxtv.org/media_tree.git
 -W:    http://linuxtv.org
 -S:    Odd Fixes
 -F:    drivers/media/parport/*-qcam*
 -
  RADOS BLOCK DEVICE (RBD)
 -M:    Yehuda Sadeh <yehuda@inktank.com>
 -M:    Sage Weil <sage@inktank.com>
 +M:    Ilya Dryomov <idryomov@gmail.com>
 +M:    Sage Weil <sage@redhat.com>
  M:    Alex Elder <elder@kernel.org>
  M:    ceph-devel@vger.kernel.org
  W:    http://ceph.com/
@@@ -8186,13 -8061,6 +8186,13 @@@ S:    Maintaine
  F:    Documentation/rfkill.txt
  F:    net/rfkill/
  
 +RHASHTABLE
 +M:    Thomas Graf <tgraf@suug.ch>
 +L:    netdev@vger.kernel.org
 +S:    Maintained
 +F:    lib/rhashtable.c
 +F:    include/linux/rhashtable.h
 +
  RICOH SMARTMEDIA/XD DRIVER
  M:    Maxim Levitsky <maximlevitsky@gmail.com>
  S:    Maintained
@@@ -8504,7 -8372,6 +8504,7 @@@ SYNOPSYS DESIGNWARE DMAC DRIVE
  M:    Viresh Kumar <viresh.linux@gmail.com>
  M:    Andy Shevchenko <andriy.shevchenko@linux.intel.com>
  S:    Maintained
 +F:    include/linux/dma/dw.h
  F:    include/linux/platform_data/dma-dw.h
  F:    drivers/dma/dw/
  
@@@ -8536,6 -8403,12 +8536,6 @@@ F:     kernel/time/clocksource.
  F:    kernel/time/time*.c
  F:    kernel/time/ntp.c
  
 -TLG2300 VIDEO4LINUX-2 DRIVER
 -M:    Huang Shijie <shijie8@gmail.com>
 -M:    Hans Verkuil <hverkuil@xs4all.nl>
 -S:    Odd Fixes
 -F:    drivers/media/usb/tlg2300/
 -
  SC1200 WDT DRIVER
  M:    Zwane Mwaikambo <zwanem@gmail.com>
  S:    Maintained
@@@ -8901,15 -8774,6 +8901,15 @@@ S:    Maintaine
  F:    drivers/media/platform/davinci/
  F:    include/media/davinci/
  
 +TI AM437X VPFE DRIVER
 +M:    Lad, Prabhakar <prabhakar.csengg@gmail.com>
 +L:    linux-media@vger.kernel.org
 +W:    http://linuxtv.org/
 +Q:    http://patchwork.linuxtv.org/project/linux-media/list/
 +T:    git git://linuxtv.org/mhadli/v4l-dvb-davinci_devices.git
 +S:    Maintained
 +F:    drivers/media/platform/am437x/
 +
  SIS 190 ETHERNET DRIVER
  M:    Francois Romieu <romieu@fr.zoreil.com>
  L:    netdev@vger.kernel.org
@@@ -8991,8 -8855,6 +8991,8 @@@ F:      drivers/media/i2c/smiapp
  F:    include/media/smiapp.h
  F:    drivers/media/i2c/smiapp-pll.c
  F:    drivers/media/i2c/smiapp-pll.h
 +F:    include/uapi/linux/smiapp.h
 +F:    Documentation/devicetree/bindings/media/i2c/nokia,smia.txt
  
  SMM665 HARDWARE MONITOR DRIVER
  M:    Guenter Roeck <linux@roeck-us.net>
@@@ -9059,7 -8921,6 +9059,7 @@@ SOFTLOGIC 6x10 MPEG CODE
  M:    Bluecherry Maintainers <maintainers@bluecherrydvr.com>
  M:    Andrey Utkin <andrey.utkin@corp.bluecherry.net>
  M:    Andrey Utkin <andrey.krieger.utkin@gmail.com>
 +M:    Ismael Luceno <ismael@iodev.co.uk>
  L:    linux-media@vger.kernel.org
  S:    Supported
  F:    drivers/media/pci/solo6x10/
@@@ -9332,14 -9193,6 +9332,14 @@@ L:    linux-wireless@vger.kernel.or
  S:    Maintained
  F:    drivers/staging/rtl8723au/
  
 +STAGING - SILICON MOTION SM7XX FRAME BUFFER DRIVER
 +M:    Sudip Mukherjee <sudipm.mukherjee@gmail.com>
 +M:    Teddy Wang <teddy.wang@siliconmotion.com>
 +M:    Sudip Mukherjee <sudip@vectorindia.org>
 +L:    linux-fbdev@vger.kernel.org
 +S:    Maintained
 +F:    drivers/staging/sm7xxfb/
 +
  STAGING - SLICOSS
  M:    Lior Dotan <liodot@gmail.com>
  M:    Christopher Harrer <charrer@alacritech.com>
@@@ -9380,13 -9233,6 +9380,13 @@@ F:    arch/m68k/sun3*
  F:    arch/m68k/include/asm/sun3*
  F:    drivers/net/ethernet/i825xx/sun3*
  
 +SUN4I LOW RES ADC ATTACHED TABLET KEYS DRIVER
 +M:    Hans de Goede <hdegoede@redhat.com>
 +L:    linux-input@vger.kernel.org
 +S:    Maintained
 +F:    Documentation/devicetree/bindings/input/sun4i-lradc-keys.txt
 +F:    drivers/input/keyboard/sun4i-lradc-keys.c
 +
  SUNDANCE NETWORK DRIVER
  M:    Denis Kirjanov <kda@linux-powerpc.org>
  L:    netdev@vger.kernel.org
@@@ -9395,6 -9241,7 +9395,6 @@@ F:      drivers/net/ethernet/dlink/sundance.
  
  SUPERH
  L:    linux-sh@vger.kernel.org
 -W:    http://www.linux-sh.org
  Q:    http://patchwork.kernel.org/project/linux-sh/list/
  S:    Orphan
  F:    Documentation/sh/
@@@ -9719,6 -9566,11 +9719,11 @@@ L:    linux-omap@vger.kernel.or
  S:    Maintained
  F:    drivers/thermal/ti-soc-thermal/
  
+ TI CDCE706 CLOCK DRIVER
+ M:    Max Filippov <jcmvbkbc@gmail.com>
+ S:    Maintained
+ F:    drivers/clk/clk-cdce706.c
  TI CLOCK DRIVER
  M:    Tero Kristo <t-kristo@ti.com>
  L:    linux-omap@vger.kernel.org
@@@ -9773,13 -9625,6 +9778,13 @@@ F:    drivers/power/lp8788-charger.
  F:    drivers/regulator/lp8788-*.c
  F:    include/linux/mfd/lp8788*.h
  
 +TI NETCP ETHERNET DRIVER
 +M:    Wingman Kwok <w-kwok2@ti.com>
 +M:    Murali Karicheri <m-karicheri2@ti.com>
 +L:    netdev@vger.kernel.org
 +S:    Maintained
 +F:    drivers/net/ethernet/ti/netcp*
 +
  TI TWL4030 SERIES SOC CODEC DRIVER
  M:    Peter Ujfalusi <peter.ujfalusi@ti.com>
  L:    alsa-devel@alsa-project.org (moderated for non-subscribers)
@@@ -9807,7 -9652,7 +9812,7 @@@ F:      net/tipc
  
  TILE ARCHITECTURE
  M:    Chris Metcalf <cmetcalf@ezchip.com>
 -W:    http://www.tilera.com/scm/
 +W:    http://www.ezchip.com/scm/
  S:    Supported
  F:    arch/tile/
  F:    drivers/char/tile-srom.c
@@@ -9900,21 -9745,13 +9905,21 @@@ F:   drivers/media/pci/tw68
  
  TPM DEVICE DRIVER
  M:    Peter Huewe <peterhuewe@gmx.de>
 -M:    Ashley Lai <ashley@ashleylai.com>
  M:    Marcel Selhorst <tpmdd@selhorst.net>
  W:    http://tpmdd.sourceforge.net
  L:    tpmdd-devel@lists.sourceforge.net (moderated for non-subscribers)
 +Q:    git git://github.com/PeterHuewe/linux-tpmdd.git
 +T:    https://github.com/PeterHuewe/linux-tpmdd
  S:    Maintained
  F:    drivers/char/tpm/
  
 +TPM IBM_VTPM DEVICE DRIVER
 +M:    Ashley Lai <ashleydlai@gmail.com>
 +W:    http://tpmdd.sourceforge.net
 +L:    tpmdd-devel@lists.sourceforge.net (moderated for non-subscribers)
 +S:    Maintained
 +F:    drivers/char/tpm/tpm_ibmvtpm*
 +
  TRACING
  M:    Steven Rostedt <rostedt@goodmis.org>
  M:    Ingo Molnar <mingo@redhat.com>
@@@ -10069,15 -9906,20 +10074,15 @@@ F: drivers/scsi/ufs
  
  UNSORTED BLOCK IMAGES (UBI)
  M:    Artem Bityutskiy <dedekind1@gmail.com>
 +M:    Richard Weinberger <richard@nod.at>
  W:    http://www.linux-mtd.infradead.org/
  L:    linux-mtd@lists.infradead.org
  T:    git git://git.infradead.org/ubifs-2.6.git
 -S:    Maintained
 +S:    Supported
  F:    drivers/mtd/ubi/
  F:    include/linux/mtd/ubi.h
  F:    include/uapi/mtd/ubi-user.h
  
 -UNSORTED BLOCK IMAGES (UBI) Fastmap
 -M:    Richard Weinberger <richard@nod.at>
 -L:    linux-mtd@lists.infradead.org
 -S:    Maintained
 -F:    drivers/mtd/ubi/fastmap.c
 -
  USB ACM DRIVER
  M:    Oliver Neukum <oliver@neukum.org>
  L:    linux-usb@vger.kernel.org
@@@ -10767,7 -10609,6 +10772,7 @@@ F:   drivers/pci/*xen
  
  XEN BLOCK SUBSYSTEM
  M:    Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
 +M:    Roger Pau Monné <roger.pau@citrix.com>
  L:    xen-devel@lists.xenproject.org (moderated for non-subscribers)
  S:    Supported
  F:    drivers/block/xen-blkback/*
@@@ -10823,7 -10664,6 +10828,7 @@@ M:   Max Filippov <jcmvbkbc@gmail.com
  L:    linux-xtensa@linux-xtensa.org
  S:    Maintained
  F:    drivers/spi/spi-xtensa-xtfpga.c
 +F:    sound/soc/xtensa/xtfpga-i2s.c
  
  YAM DRIVER FOR AX.25
  M:    Jean-Paul Roubelat <jpr@f6fbb.org>
index 8ca3c1a2063deeb0eb426a7b320b269f77e4b04d,47d594e2db0bdae91e76fcfbc756ddc905c915f9..5c2925831f2038318258003ae6cd3736da71c0de
   * http://www.gnu.org/copyleft/gpl.html
   */
  
 -/include/ "skeleton.dtsi"
 +#include "skeleton.dtsi"
 +
 +#include <dt-bindings/thermal/thermal.h>
 +
 +#include <dt-bindings/dma/sun4i-a10.h>
 +#include <dt-bindings/pinctrl/sun4i-a10.h>
  
  / {
        interrupt-parent = <&intc>;
                                 <&ahb_gates 44>, <&ahb_gates 46>;
                        status = "disabled";
                };
 +
 +              framebuffer@2 {
 +                      compatible = "allwinner,simple-framebuffer",
 +                                   "simple-framebuffer";
 +                      allwinner,pipeline = "de_fe0-de_be0-lcd0";
 +                      clocks = <&pll5 1>, <&ahb_gates 36>, <&ahb_gates 44>,
 +                               <&ahb_gates 46>;
 +                      status = "disabled";
 +              };
 +
 +              framebuffer@3 {
 +                      compatible = "allwinner,simple-framebuffer",
 +                                   "simple-framebuffer";
 +                      allwinner,pipeline = "de_fe0-de_be0-lcd0-tve0";
 +                      clocks = <&pll5 1>, <&ahb_gates 34>, <&ahb_gates 36>,
 +                               <&ahb_gates 44>, <&ahb_gates 46>;
 +                      status = "disabled";
 +              };
        };
  
        cpus {
                #address-cells = <1>;
                #size-cells = <0>;
 -              cpu@0 {
 +              cpu0: cpu@0 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a8";
                        reg = <0x0>;
 +                      clocks = <&cpu>;
 +                      clock-latency = <244144>; /* 8 32k periods */
 +                      operating-points = <
 +                              /* kHz    uV */
 +                              1056000 1500000
 +                              1008000 1400000
 +                              912000  1350000
 +                              864000  1300000
 +                              624000  1250000
 +                              >;
 +                      #cooling-cells = <2>;
 +                      cooling-min-level = <0>;
 +                      cooling-max-level = <4>;
 +              };
 +      };
 +
 +      thermal-zones {
 +              cpu_thermal {
 +                      /* milliseconds */
 +                      polling-delay-passive = <250>;
 +                      polling-delay = <1000>;
 +                      thermal-sensors = <&rtp>;
 +
 +                      cooling-maps {
 +                              map0 {
 +                                      trip = <&cpu_alert0>;
 +                                      cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
 +                              };
 +                      };
 +
 +                      trips {
 +                              cpu_alert0: cpu_alert0 {
 +                                      /* milliCelsius */
 +                                      temperature = <850000>;
 +                                      hysteresis = <2000>;
 +                                      type = "passive";
 +                              };
 +
 +                              cpu_crit: cpu_crit {
 +                                      /* milliCelsius */
 +                                      temperature = <100000>;
 +                                      hysteresis = <2000>;
 +                                      type = "critical";
 +                              };
 +                      };
                };
        };
  
                };
  
                mmc0_clk: clk@01c20088 {
-                       #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-a10-mod0-clk";
+                       #clock-cells = <1>;
+                       compatible = "allwinner,sun4i-a10-mmc-clk";
                        reg = <0x01c20088 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-                       clock-output-names = "mmc0";
+                       clock-output-names = "mmc0",
+                                            "mmc0_output",
+                                            "mmc0_sample";
                };
  
                mmc1_clk: clk@01c2008c {
-                       #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-a10-mod0-clk";
+                       #clock-cells = <1>;
+                       compatible = "allwinner,sun4i-a10-mmc-clk";
                        reg = <0x01c2008c 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-                       clock-output-names = "mmc1";
+                       clock-output-names = "mmc1",
+                                            "mmc1_output",
+                                            "mmc1_sample";
                };
  
                mmc2_clk: clk@01c20090 {
-                       #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-a10-mod0-clk";
+                       #clock-cells = <1>;
+                       compatible = "allwinner,sun4i-a10-mmc-clk";
                        reg = <0x01c20090 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-                       clock-output-names = "mmc2";
+                       clock-output-names = "mmc2",
+                                            "mmc2_output",
+                                            "mmc2_sample";
                };
  
                mmc3_clk: clk@01c20094 {
-                       #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-a10-mod0-clk";
+                       #clock-cells = <1>;
+                       compatible = "allwinner,sun4i-a10-mmc-clk";
                        reg = <0x01c20094 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-                       clock-output-names = "mmc3";
+                       clock-output-names = "mmc3",
+                                            "mmc3_output",
+                                            "mmc3_sample";
                };
  
                ts_clk: clk@01c20098 {
                        interrupts = <10>;
                        clocks = <&ahb_gates 20>, <&spi0_clk>;
                        clock-names = "ahb", "mod";
 -                      dmas = <&dma 1 27>, <&dma 1 26>;
 +                      dmas = <&dma SUN4I_DMA_DEDICATED 27>,
 +                             <&dma SUN4I_DMA_DEDICATED 26>;
                        dma-names = "rx", "tx";
                        status = "disabled";
                        #address-cells = <1>;
                        interrupts = <11>;
                        clocks = <&ahb_gates 21>, <&spi1_clk>;
                        clock-names = "ahb", "mod";
 -                      dmas = <&dma 1 9>, <&dma 1 8>;
 +                      dmas = <&dma SUN4I_DMA_DEDICATED 9>,
 +                             <&dma SUN4I_DMA_DEDICATED 8>;
                        dma-names = "rx", "tx";
                        status = "disabled";
                        #address-cells = <1>;
                        status = "disabled";
                };
  
 -              mdio@01c0b080 {
 +              mdio: mdio@01c0b080 {
                        compatible = "allwinner,sun4i-a10-mdio";
                        reg = <0x01c0b080 0x14>;
                        status = "disabled";
                mmc0: mmc@01c0f000 {
                        compatible = "allwinner,sun4i-a10-mmc";
                        reg = <0x01c0f000 0x1000>;
-                       clocks = <&ahb_gates 8>, <&mmc0_clk>;
-                       clock-names = "ahb", "mmc";
+                       clocks = <&ahb_gates 8>,
+                                <&mmc0_clk 0>,
+                                <&mmc0_clk 1>,
+                                <&mmc0_clk 2>;
+                       clock-names = "ahb",
+                                     "mmc",
+                                     "output",
+                                     "sample";
                        interrupts = <32>;
                        status = "disabled";
                };
                mmc1: mmc@01c10000 {
                        compatible = "allwinner,sun4i-a10-mmc";
                        reg = <0x01c10000 0x1000>;
-                       clocks = <&ahb_gates 9>, <&mmc1_clk>;
-                       clock-names = "ahb", "mmc";
+                       clocks = <&ahb_gates 9>,
+                                <&mmc1_clk 0>,
+                                <&mmc1_clk 1>,
+                                <&mmc1_clk 2>;
+                       clock-names = "ahb",
+                                     "mmc",
+                                     "output",
+                                     "sample";
                        interrupts = <33>;
                        status = "disabled";
                };
                mmc2: mmc@01c11000 {
                        compatible = "allwinner,sun4i-a10-mmc";
                        reg = <0x01c11000 0x1000>;
-                       clocks = <&ahb_gates 10>, <&mmc2_clk>;
-                       clock-names = "ahb", "mmc";
+                       clocks = <&ahb_gates 10>,
+                                <&mmc2_clk 0>,
+                                <&mmc2_clk 1>,
+                                <&mmc2_clk 2>;
+                       clock-names = "ahb",
+                                     "mmc",
+                                     "output",
+                                     "sample";
                        interrupts = <34>;
                        status = "disabled";
                };
                mmc3: mmc@01c12000 {
                        compatible = "allwinner,sun4i-a10-mmc";
                        reg = <0x01c12000 0x1000>;
-                       clocks = <&ahb_gates 11>, <&mmc3_clk>;
-                       clock-names = "ahb", "mmc";
+                       clocks = <&ahb_gates 11>,
+                                <&mmc3_clk 0>,
+                                <&mmc3_clk 1>,
+                                <&mmc3_clk 2>;
+                       clock-names = "ahb",
+                                     "mmc",
+                                     "output",
+                                     "sample";
                        interrupts = <35>;
                        status = "disabled";
                };
                        interrupts = <12>;
                        clocks = <&ahb_gates 22>, <&spi2_clk>;
                        clock-names = "ahb", "mod";
 -                      dmas = <&dma 1 29>, <&dma 1 28>;
 +                      dmas = <&dma SUN4I_DMA_DEDICATED 29>,
 +                             <&dma SUN4I_DMA_DEDICATED 28>;
                        dma-names = "rx", "tx";
                        status = "disabled";
                        #address-cells = <1>;
                        interrupts = <50>;
                        clocks = <&ahb_gates 23>, <&spi3_clk>;
                        clock-names = "ahb", "mod";
 -                      dmas = <&dma 1 31>, <&dma 1 30>;
 +                      dmas = <&dma SUN4I_DMA_DEDICATED 31>,
 +                             <&dma SUN4I_DMA_DEDICATED 30>;
                        dma-names = "rx", "tx";
                        status = "disabled";
                        #address-cells = <1>;
                        pwm0_pins_a: pwm0@0 {
                                allwinner,pins = "PB2";
                                allwinner,function = "pwm";
 -                              allwinner,drive = <0>;
 -                              allwinner,pull = <0>;
 +                              allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
                        };
  
                        pwm1_pins_a: pwm1@0 {
                                allwinner,pins = "PI3";
                                allwinner,function = "pwm";
 -                              allwinner,drive = <0>;
 -                              allwinner,pull = <0>;
 +                              allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
                        };
  
                        uart0_pins_a: uart0@0 {
                                allwinner,pins = "PB22", "PB23";
                                allwinner,function = "uart0";
 -                              allwinner,drive = <0>;
 -                              allwinner,pull = <0>;
 +                              allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
                        };
  
                        uart0_pins_b: uart0@1 {
                                allwinner,pins = "PF2", "PF4";
                                allwinner,function = "uart0";
 -                              allwinner,drive = <0>;
 -                              allwinner,pull = <0>;
 +                              allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
                        };
  
                        uart1_pins_a: uart1@0 {
                                allwinner,pins = "PA10", "PA11";
                                allwinner,function = "uart1";
 -                              allwinner,drive = <0>;
 -                              allwinner,pull = <0>;
 +                              allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
                        };
  
                        i2c0_pins_a: i2c0@0 {
                                allwinner,pins = "PB0", "PB1";
                                allwinner,function = "i2c0";
 -                              allwinner,drive = <0>;
 -                              allwinner,pull = <0>;
 +                              allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
                        };
  
                        i2c1_pins_a: i2c1@0 {
                                allwinner,pins = "PB18", "PB19";
                                allwinner,function = "i2c1";
 -                              allwinner,drive = <0>;
 -                              allwinner,pull = <0>;
 +                              allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
                        };
  
                        i2c2_pins_a: i2c2@0 {
                                allwinner,pins = "PB20", "PB21";
                                allwinner,function = "i2c2";
 -                              allwinner,drive = <0>;
 -                              allwinner,pull = <0>;
 +                              allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
                        };
  
                        emac_pins_a: emac0@0 {
                                                "PA11", "PA12", "PA13", "PA14",
                                                "PA15", "PA16";
                                allwinner,function = "emac";
 -                              allwinner,drive = <0>;
 -                              allwinner,pull = <0>;
 +                              allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
                        };
  
                        mmc0_pins_a: mmc0@0 {
                                allwinner,pins = "PF0","PF1","PF2","PF3","PF4","PF5";
                                allwinner,function = "mmc0";
 -                              allwinner,drive = <2>;
 -                              allwinner,pull = <0>;
 +                              allwinner,drive = <SUN4I_PINCTRL_30_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
                        };
  
                        mmc0_cd_pin_reference_design: mmc0_cd_pin@0 {
                                allwinner,pins = "PH1";
                                allwinner,function = "gpio_in";
 -                              allwinner,drive = <0>;
 -                              allwinner,pull = <1>;
 +                              allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
                        };
  
                        ir0_pins_a: ir0@0 {
                                allwinner,pins = "PB3","PB4";
                                allwinner,function = "ir0";
 -                              allwinner,drive = <0>;
 -                              allwinner,pull = <0>;
 +                              allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
                        };
  
                        ir1_pins_a: ir1@0 {
                                allwinner,pins = "PB22","PB23";
                                allwinner,function = "ir1";
 -                              allwinner,drive = <0>;
 -                              allwinner,pull = <0>;
 +                              allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
 +                      };
 +
 +                      spi0_pins_a: spi0@0 {
 +                              allwinner,pins = "PI10", "PI11", "PI12", "PI13";
 +                              allwinner,function = "spi0";
 +                              allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
 +                      };
 +
 +                      spi1_pins_a: spi1@0 {
 +                              allwinner,pins = "PI16", "PI17", "PI18", "PI19";
 +                              allwinner,function = "spi1";
 +                              allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
 +                      };
 +
 +                      spi2_pins_a: spi2@0 {
 +                              allwinner,pins = "PB14", "PB15", "PB16", "PB17";
 +                              allwinner,function = "spi2";
 +                              allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
 +                      };
 +
 +                      spi2_pins_b: spi2@1 {
 +                              allwinner,pins = "PC19", "PC20", "PC21", "PC22";
 +                              allwinner,function = "spi2";
 +                              allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
 +                      };
 +
 +                      ps20_pins_a: ps20@0 {
 +                              allwinner,pins = "PI20", "PI21";
 +                              allwinner,function = "ps2";
 +                              allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
 +                      };
 +
 +                      ps21_pins_a: ps21@0 {
 +                              allwinner,pins = "PH12", "PH13";
 +                              allwinner,function = "ps2";
 +                              allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
                        };
                };
  
                        status = "disabled";
                };
  
 +              lradc: lradc@01c22800 {
 +                      compatible = "allwinner,sun4i-a10-lradc-keys";
 +                      reg = <0x01c22800 0x100>;
 +                      interrupts = <31>;
 +                      status = "disabled";
 +              };
 +
                sid: eeprom@01c23800 {
                        compatible = "allwinner,sun4i-a10-sid";
                        reg = <0x01c23800 0x10>;
                        compatible = "allwinner,sun4i-a10-ts";
                        reg = <0x01c25000 0x100>;
                        interrupts = <29>;
 +                      #thermal-sensor-cells = <0>;
                };
  
                uart0: serial@01c28000 {
                        #address-cells = <1>;
                        #size-cells = <0>;
                };
 +
 +              ps20: ps2@01c2a000 {
 +                      compatible = "allwinner,sun4i-a10-ps2";
 +                      reg = <0x01c2a000 0x400>;
 +                      interrupts = <62>;
 +                      clocks = <&apb1_gates 6>;
 +                      status = "disabled";
 +              };
 +
 +              ps21: ps2@01c2a400 {
 +                      compatible = "allwinner,sun4i-a10-ps2";
 +                      reg = <0x01c2a400 0x400>;
 +                      interrupts = <63>;
 +                      clocks = <&apb1_gates 7>;
 +                      status = "disabled";
 +              };
        };
  };
index 905f84d141f03213947def68787c42f905e2b54b,d049f811ba40ae1f76d2b9cf19e474a7b792047c..2fd8988f310c6e25dc2d215a35ed1e633d95f83a
   * http://www.gnu.org/copyleft/gpl.html
   */
  
 -/include/ "skeleton.dtsi"
 +#include "skeleton.dtsi"
 +
 +#include <dt-bindings/dma/sun4i-a10.h>
 +#include <dt-bindings/pinctrl/sun4i-a10.h>
  
  / {
        interrupt-parent = <&intc>;
                                 <&ahb_gates 44>;
                        status = "disabled";
                };
 +
 +              framebuffer@1 {
 +                      compatible = "allwinner,simple-framebuffer",
 +                                   "simple-framebuffer";
 +                      allwinner,pipeline = "de_be0-lcd0";
 +                      clocks = <&pll5 1>, <&ahb_gates 36>, <&ahb_gates 44>;
 +                      status = "disabled";
 +              };
        };
  
        cpus {
                };
  
                mmc0_clk: clk@01c20088 {
-                       #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-a10-mod0-clk";
+                       #clock-cells = <1>;
+                       compatible = "allwinner,sun4i-a10-mmc-clk";
                        reg = <0x01c20088 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-                       clock-output-names = "mmc0";
+                       clock-output-names = "mmc0",
+                                            "mmc0_output",
+                                            "mmc0_sample";
                };
  
                mmc1_clk: clk@01c2008c {
-                       #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-a10-mod0-clk";
+                       #clock-cells = <1>;
+                       compatible = "allwinner,sun4i-a10-mmc-clk";
                        reg = <0x01c2008c 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-                       clock-output-names = "mmc1";
+                       clock-output-names = "mmc1",
+                                            "mmc1_output",
+                                            "mmc1_sample";
                };
  
                mmc2_clk: clk@01c20090 {
-                       #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-a10-mod0-clk";
+                       #clock-cells = <1>;
+                       compatible = "allwinner,sun4i-a10-mmc-clk";
                        reg = <0x01c20090 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-                       clock-output-names = "mmc2";
+                       clock-output-names = "mmc2",
+                                            "mmc2_output",
+                                            "mmc2_sample";
                };
  
                ts_clk: clk@01c20098 {
                        interrupts = <10>;
                        clocks = <&ahb_gates 20>, <&spi0_clk>;
                        clock-names = "ahb", "mod";
 -                      dmas = <&dma 1 27>, <&dma 1 26>;
 +                      dmas = <&dma SUN4I_DMA_DEDICATED 27>,
 +                             <&dma SUN4I_DMA_DEDICATED 26>;
                        dma-names = "rx", "tx";
                        status = "disabled";
                        #address-cells = <1>;
                        interrupts = <11>;
                        clocks = <&ahb_gates 21>, <&spi1_clk>;
                        clock-names = "ahb", "mod";
 -                      dmas = <&dma 1 9>, <&dma 1 8>;
 +                      dmas = <&dma SUN4I_DMA_DEDICATED 9>,
 +                             <&dma SUN4I_DMA_DEDICATED 8>;
                        dma-names = "rx", "tx";
                        status = "disabled";
                        #address-cells = <1>;
                        status = "disabled";
                };
  
 -              mdio@01c0b080 {
 +              mdio: mdio@01c0b080 {
                        compatible = "allwinner,sun4i-a10-mdio";
                        reg = <0x01c0b080 0x14>;
                        status = "disabled";
                mmc0: mmc@01c0f000 {
                        compatible = "allwinner,sun5i-a13-mmc";
                        reg = <0x01c0f000 0x1000>;
-                       clocks = <&ahb_gates 8>, <&mmc0_clk>;
-                       clock-names = "ahb", "mmc";
+                       clocks = <&ahb_gates 8>,
+                                <&mmc0_clk 0>,
+                                <&mmc0_clk 1>,
+                                <&mmc0_clk 2>;
+                       clock-names = "ahb",
+                                     "mmc",
+                                     "output",
+                                     "sample";
                        interrupts = <32>;
                        status = "disabled";
                };
                mmc1: mmc@01c10000 {
                        compatible = "allwinner,sun5i-a13-mmc";
                        reg = <0x01c10000 0x1000>;
-                       clocks = <&ahb_gates 9>, <&mmc1_clk>;
-                       clock-names = "ahb", "mmc";
+                       clocks = <&ahb_gates 9>,
+                                <&mmc1_clk 0>,
+                                <&mmc1_clk 1>,
+                                <&mmc1_clk 2>;
+                       clock-names = "ahb",
+                                     "mmc",
+                                     "output",
+                                     "sample";
                        interrupts = <33>;
                        status = "disabled";
                };
                mmc2: mmc@01c11000 {
                        compatible = "allwinner,sun5i-a13-mmc";
                        reg = <0x01c11000 0x1000>;
-                       clocks = <&ahb_gates 10>, <&mmc2_clk>;
-                       clock-names = "ahb", "mmc";
+                       clocks = <&ahb_gates 10>,
+                                <&mmc2_clk 0>,
+                                <&mmc2_clk 1>,
+                                <&mmc2_clk 2>;
+                       clock-names = "ahb",
+                                     "mmc",
+                                     "output",
+                                     "sample";
                        interrupts = <34>;
                        status = "disabled";
                };
                        interrupts = <12>;
                        clocks = <&ahb_gates 22>, <&spi2_clk>;
                        clock-names = "ahb", "mod";
 -                      dmas = <&dma 1 29>, <&dma 1 28>;
 +                      dmas = <&dma SUN4I_DMA_DEDICATED 29>,
 +                             <&dma SUN4I_DMA_DEDICATED 28>;
                        dma-names = "rx", "tx";
                        status = "disabled";
                        #address-cells = <1>;
                        uart0_pins_a: uart0@0 {
                                allwinner,pins = "PB19", "PB20";
                                allwinner,function = "uart0";
 -                              allwinner,drive = <0>;
 -                              allwinner,pull = <0>;
 +                              allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
                        };
  
                        uart2_pins_a: uart2@0 {
                                allwinner,pins = "PC18", "PC19";
                                allwinner,function = "uart2";
 -                              allwinner,drive = <0>;
 -                              allwinner,pull = <0>;
 +                              allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
                        };
  
                        uart3_pins_a: uart3@0 {
                                allwinner,pins = "PG9", "PG10";
                                allwinner,function = "uart3";
 -                              allwinner,drive = <0>;
 -                              allwinner,pull = <0>;
 +                              allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
                        };
  
                        emac_pins_a: emac0@0 {
                                                "PA11", "PA12", "PA13", "PA14",
                                                "PA15", "PA16";
                                allwinner,function = "emac";
 -                              allwinner,drive = <0>;
 -                              allwinner,pull = <0>;
 +                              allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
                        };
  
                        i2c0_pins_a: i2c0@0 {
                                allwinner,pins = "PB0", "PB1";
                                allwinner,function = "i2c0";
 -                              allwinner,drive = <0>;
 -                              allwinner,pull = <0>;
 +                              allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
                        };
  
                        i2c1_pins_a: i2c1@0 {
                                allwinner,pins = "PB15", "PB16";
                                allwinner,function = "i2c1";
 -                              allwinner,drive = <0>;
 -                              allwinner,pull = <0>;
 +                              allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
                        };
  
                        i2c2_pins_a: i2c2@0 {
                                allwinner,pins = "PB17", "PB18";
                                allwinner,function = "i2c2";
 -                              allwinner,drive = <0>;
 -                              allwinner,pull = <0>;
 +                              allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
                        };
  
                        mmc0_pins_a: mmc0@0 {
                                allwinner,pins = "PF0","PF1","PF2","PF3","PF4","PF5";
                                allwinner,function = "mmc0";
 -                              allwinner,drive = <2>;
 -                              allwinner,pull = <0>;
 +                              allwinner,drive = <SUN4I_PINCTRL_30_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
                        };
  
                        mmc1_pins_a: mmc1@0 {
                                allwinner,pins = "PG3","PG4","PG5","PG6","PG7","PG8";
                                allwinner,function = "mmc1";
 -                              allwinner,drive = <2>;
 -                              allwinner,pull = <0>;
 +                              allwinner,drive = <SUN4I_PINCTRL_30_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
                        };
                };
  
                        reg = <0x01c20c90 0x10>;
                };
  
 +              lradc: lradc@01c22800 {
 +                      compatible = "allwinner,sun4i-a10-lradc-keys";
 +                      reg = <0x01c22800 0x100>;
 +                      interrupts = <31>;
 +                      status = "disabled";
 +              };
 +
                sid: eeprom@01c23800 {
                        compatible = "allwinner,sun4i-a10-sid";
                        reg = <0x01c23800 0x10>;
                        compatible = "allwinner,sun4i-a10-ts";
                        reg = <0x01c25000 0x100>;
                        interrupts = <29>;
 +                      #thermal-sensor-cells = <0>;
                };
  
                uart0: serial@01c28000 {
index 4910393d1b09013bcb929dc6325d8ddbd6a7d945,5c08a9a65689e72c2bc1b26f67271187ea947058..f8818f1edbbef27f16adadc139b8e46ae49823ad
   * http://www.gnu.org/copyleft/gpl.html
   */
  
 -/include/ "skeleton.dtsi"
 +#include "skeleton.dtsi"
 +
 +#include <dt-bindings/thermal/thermal.h>
 +
 +#include <dt-bindings/dma/sun4i-a10.h>
 +#include <dt-bindings/pinctrl/sun4i-a10.h>
  
  / {
        interrupt-parent = <&intc>;
  
 +      chosen {
 +              #address-cells = <1>;
 +              #size-cells = <1>;
 +              ranges;
 +
 +              framebuffer@0 {
 +                      compatible = "allwinner,simple-framebuffer",
 +                                   "simple-framebuffer";
 +                      allwinner,pipeline = "de_be0-lcd0";
 +                      clocks = <&pll5 1>, <&ahb_gates 36>, <&ahb_gates 44>;
 +                      status = "disabled";
 +              };
 +      };
 +
        cpus {
                #address-cells = <1>;
                #size-cells = <0>;
 -              cpu@0 {
 +
 +              cpu0: cpu@0 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a8";
                        reg = <0x0>;
 +                      clocks = <&cpu>;
 +                      clock-latency = <244144>; /* 8 32k periods */
 +                      operating-points = <
 +                              /* kHz    uV */
 +                              1104000 1500000
 +                              1008000 1400000
 +                              912000  1350000
 +                              864000  1300000
 +                              624000  1200000
 +                              576000  1200000
 +                              432000  1200000
 +                              >;
 +                      #cooling-cells = <2>;
 +                      cooling-min-level = <0>;
 +                      cooling-max-level = <6>;
 +              };
 +      };
 +
 +      thermal-zones {
 +              cpu_thermal {
 +                      /* milliseconds */
 +                      polling-delay-passive = <250>;
 +                      polling-delay = <1000>;
 +                      thermal-sensors = <&rtp>;
 +
 +                      cooling-maps {
 +                              map0 {
 +                                      trip = <&cpu_alert0>;
 +                                      cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
 +                              };
 +                      };
 +
 +                      trips {
 +                              cpu_alert0: cpu_alert0 {
 +                                      /* milliCelsius */
 +                                      temperature = <850000>;
 +                                      hysteresis = <2000>;
 +                                      type = "passive";
 +                              };
 +
 +                              cpu_crit: cpu_crit {
 +                                      /* milliCelsius */
 +                                      temperature = <100000>;
 +                                      hysteresis = <2000>;
 +                                      type = "critical";
 +                              };
 +                      };
                };
        };
  
                };
  
                mmc0_clk: clk@01c20088 {
-                       #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-a10-mod0-clk";
+                       #clock-cells = <1>;
+                       compatible = "allwinner,sun4i-a10-mmc-clk";
                        reg = <0x01c20088 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-                       clock-output-names = "mmc0";
+                       clock-output-names = "mmc0",
+                                            "mmc0_output",
+                                            "mmc0_sample";
                };
  
                mmc1_clk: clk@01c2008c {
-                       #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-a10-mod0-clk";
+                       #clock-cells = <1>;
+                       compatible = "allwinner,sun4i-a10-mmc-clk";
                        reg = <0x01c2008c 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-                       clock-output-names = "mmc1";
+                       clock-output-names = "mmc1",
+                                            "mmc1_output",
+                                            "mmc1_sample";
                };
  
                mmc2_clk: clk@01c20090 {
-                       #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-a10-mod0-clk";
+                       #clock-cells = <1>;
+                       compatible = "allwinner,sun4i-a10-mmc-clk";
                        reg = <0x01c20090 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-                       clock-output-names = "mmc2";
+                       clock-output-names = "mmc2",
+                                            "mmc2_output",
+                                            "mmc2_sample";
                };
  
                ts_clk: clk@01c20098 {
                        interrupts = <10>;
                        clocks = <&ahb_gates 20>, <&spi0_clk>;
                        clock-names = "ahb", "mod";
 -                      dmas = <&dma 1 27>, <&dma 1 26>;
 +                      dmas = <&dma SUN4I_DMA_DEDICATED 27>,
 +                             <&dma SUN4I_DMA_DEDICATED 26>;
                        dma-names = "rx", "tx";
                        status = "disabled";
                        #address-cells = <1>;
                        interrupts = <11>;
                        clocks = <&ahb_gates 21>, <&spi1_clk>;
                        clock-names = "ahb", "mod";
 -                      dmas = <&dma 1 9>, <&dma 1 8>;
 +                      dmas = <&dma SUN4I_DMA_DEDICATED 9>,
 +                             <&dma SUN4I_DMA_DEDICATED 8>;
                        dma-names = "rx", "tx";
                        status = "disabled";
                        #address-cells = <1>;
                mmc0: mmc@01c0f000 {
                        compatible = "allwinner,sun5i-a13-mmc";
                        reg = <0x01c0f000 0x1000>;
-                       clocks = <&ahb_gates 8>, <&mmc0_clk>;
-                       clock-names = "ahb", "mmc";
+                       clocks = <&ahb_gates 8>,
+                                <&mmc0_clk 0>,
+                                <&mmc0_clk 1>,
+                                <&mmc0_clk 2>;
+                       clock-names = "ahb",
+                                     "mmc",
+                                     "output",
+                                     "sample";
                        interrupts = <32>;
                        status = "disabled";
                };
                mmc2: mmc@01c11000 {
                        compatible = "allwinner,sun5i-a13-mmc";
                        reg = <0x01c11000 0x1000>;
-                       clocks = <&ahb_gates 10>, <&mmc2_clk>;
-                       clock-names = "ahb", "mmc";
+                       clocks = <&ahb_gates 10>,
+                                <&mmc2_clk 0>,
+                                <&mmc2_clk 1>,
+                                <&mmc2_clk 2>;
+                       clock-names = "ahb",
+                                     "mmc",
+                                     "output",
+                                     "sample";
                        interrupts = <34>;
                        status = "disabled";
                };
                        interrupts = <12>;
                        clocks = <&ahb_gates 22>, <&spi2_clk>;
                        clock-names = "ahb", "mod";
 -                      dmas = <&dma 1 29>, <&dma 1 28>;
 +                      dmas = <&dma SUN4I_DMA_DEDICATED 29>,
 +                             <&dma SUN4I_DMA_DEDICATED 28>;
                        dma-names = "rx", "tx";
                        status = "disabled";
                        #address-cells = <1>;
                        uart1_pins_a: uart1@0 {
                                allwinner,pins = "PE10", "PE11";
                                allwinner,function = "uart1";
 -                              allwinner,drive = <0>;
 -                              allwinner,pull = <0>;
 +                              allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
                        };
  
                        uart1_pins_b: uart1@1 {
                                allwinner,pins = "PG3", "PG4";
                                allwinner,function = "uart1";
 -                              allwinner,drive = <0>;
 -                              allwinner,pull = <0>;
 +                              allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
                        };
  
                        i2c0_pins_a: i2c0@0 {
                                allwinner,pins = "PB0", "PB1";
                                allwinner,function = "i2c0";
 -                              allwinner,drive = <0>;
 -                              allwinner,pull = <0>;
 +                              allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
                        };
  
                        i2c1_pins_a: i2c1@0 {
                                allwinner,pins = "PB15", "PB16";
                                allwinner,function = "i2c1";
 -                              allwinner,drive = <0>;
 -                              allwinner,pull = <0>;
 +                              allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
                        };
  
                        i2c2_pins_a: i2c2@0 {
                                allwinner,pins = "PB17", "PB18";
                                allwinner,function = "i2c2";
 -                              allwinner,drive = <0>;
 -                              allwinner,pull = <0>;
 +                              allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
                        };
  
                        mmc0_pins_a: mmc0@0 {
                                allwinner,pins = "PF0","PF1","PF2","PF3","PF4","PF5";
                                allwinner,function = "mmc0";
 -                              allwinner,drive = <2>;
 -                              allwinner,pull = <0>;
 +                              allwinner,drive = <SUN4I_PINCTRL_30_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
                        };
                };
  
                        reg = <0x01c20c90 0x10>;
                };
  
 +              lradc: lradc@01c22800 {
 +                      compatible = "allwinner,sun4i-a10-lradc-keys";
 +                      reg = <0x01c22800 0x100>;
 +                      interrupts = <31>;
 +                      status = "disabled";
 +              };
 +
                sid: eeprom@01c23800 {
                        compatible = "allwinner,sun4i-a10-sid";
                        reg = <0x01c23800 0x10>;
                        compatible = "allwinner,sun4i-a10-ts";
                        reg = <0x01c25000 0x100>;
                        interrupts = <29>;
 +                      #thermal-sensor-cells = <0>;
                };
  
                uart1: serial@01c28400 {
index 47e557656993fe99f1ea46667a1c1d27e8a2648f,5960ccce5bb4fad816c4e5eac00cd816689a8233..fa2f403ccf28adf4f6aa10c08978dd3b59b6e709
   *     OTHER DEALINGS IN THE SOFTWARE.
   */
  
 -/include/ "skeleton.dtsi"
 +#include "skeleton.dtsi"
 +
 +#include <dt-bindings/interrupt-controller/arm-gic.h>
 +
 +#include <dt-bindings/pinctrl/sun4i-a10.h>
  
  / {
        interrupt-parent = <&gic>;
                        clocks = <&pll6 0>;
                        status = "disabled";
                };
 +
 +              framebuffer@1 {
 +                      compatible = "allwinner,simple-framebuffer",
 +                                   "simple-framebuffer";
 +                      allwinner,pipeline = "de_be0-lcd0";
 +                      clocks = <&pll6 0>;
 +                      status = "disabled";
 +              };
 +      };
 +
 +      timer {
 +              compatible = "arm,armv7-timer";
 +              interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
 +                           <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
 +                           <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
 +                           <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
 +              clock-frequency = <24000000>;
 +              arm,cpu-registers-not-fw-configured;
        };
  
        cpus {
  
        pmu {
                compatible = "arm,cortex-a7-pmu", "arm,cortex-a15-pmu";
 -              interrupts = <0 120 4>,
 -                           <0 121 4>,
 -                           <0 122 4>,
 -                           <0 123 4>;
 +              interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>,
 +                           <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
 +                           <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
 +                           <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
        };
  
        clocks {
                        clock-output-names = "axi";
                };
  
-               ahb1_mux: ahb1_mux@01c20054 {
-                       #clock-cells = <0>;
-                       compatible = "allwinner,sun6i-a31-ahb1-mux-clk";
-                       reg = <0x01c20054 0x4>;
-                       clocks = <&osc32k>, <&osc24M>, <&axi>, <&pll6 0>;
-                       clock-output-names = "ahb1_mux";
-               };
                ahb1: ahb1@01c20054 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-a10-ahb-clk";
+                       compatible = "allwinner,sun6i-a31-ahb1-clk";
                        reg = <0x01c20054 0x4>;
-                       clocks = <&ahb1_mux>;
+                       clocks = <&osc32k>, <&osc24M>, <&axi>, <&pll6 0>;
                        clock-output-names = "ahb1";
                };
  
                };
  
                mmc0_clk: clk@01c20088 {
-                       #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-a10-mod0-clk";
+                       #clock-cells = <1>;
+                       compatible = "allwinner,sun4i-a10-mmc-clk";
                        reg = <0x01c20088 0x4>;
                        clocks = <&osc24M>, <&pll6 0>;
-                       clock-output-names = "mmc0";
+                       clock-output-names = "mmc0",
+                                            "mmc0_output",
+                                            "mmc0_sample";
                };
  
                mmc1_clk: clk@01c2008c {
-                       #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-a10-mod0-clk";
+                       #clock-cells = <1>;
+                       compatible = "allwinner,sun4i-a10-mmc-clk";
                        reg = <0x01c2008c 0x4>;
                        clocks = <&osc24M>, <&pll6 0>;
-                       clock-output-names = "mmc1";
+                       clock-output-names = "mmc1",
+                                            "mmc1_output",
+                                            "mmc1_sample";
                };
  
                mmc2_clk: clk@01c20090 {
-                       #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-a10-mod0-clk";
+                       #clock-cells = <1>;
+                       compatible = "allwinner,sun4i-a10-mmc-clk";
                        reg = <0x01c20090 0x4>;
                        clocks = <&osc24M>, <&pll6 0>;
-                       clock-output-names = "mmc2";
+                       clock-output-names = "mmc2",
+                                            "mmc2_output",
+                                            "mmc2_sample";
                };
  
                mmc3_clk: clk@01c20094 {
-                       #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-a10-mod0-clk";
+                       #clock-cells = <1>;
+                       compatible = "allwinner,sun4i-a10-mmc-clk";
                        reg = <0x01c20094 0x4>;
                        clocks = <&osc24M>, <&pll6 0>;
-                       clock-output-names = "mmc3";
+                       clock-output-names = "mmc3",
+                                            "mmc3_output",
+                                            "mmc3_sample";
                };
  
                spi0_clk: clk@01c200a0 {
                dma: dma-controller@01c02000 {
                        compatible = "allwinner,sun6i-a31-dma";
                        reg = <0x01c02000 0x1000>;
 -                      interrupts = <0 50 4>;
 +                      interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&ahb1_gates 6>;
                        resets = <&ahb1_rst 6>;
                        #dma-cells = <1>;
  
                        /* DMA controller requires AHB1 clocked from PLL6 */
-                       assigned-clocks = <&ahb1_mux>;
+                       assigned-clocks = <&ahb1>;
                        assigned-clock-parents = <&pll6 0>;
                };
  
                mmc0: mmc@01c0f000 {
                        compatible = "allwinner,sun5i-a13-mmc";
                        reg = <0x01c0f000 0x1000>;
-                       clocks = <&ahb1_gates 8>, <&mmc0_clk>;
-                       clock-names = "ahb", "mmc";
+                       clocks = <&ahb1_gates 8>,
+                                <&mmc0_clk 0>,
+                                <&mmc0_clk 1>,
+                                <&mmc0_clk 2>;
+                       clock-names = "ahb",
+                                     "mmc",
+                                     "output",
+                                     "sample";
                        resets = <&ahb1_rst 8>;
                        reset-names = "ahb";
 -                      interrupts = <0 60 4>;
 +                      interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>;
                        status = "disabled";
                };
  
                mmc1: mmc@01c10000 {
                        compatible = "allwinner,sun5i-a13-mmc";
                        reg = <0x01c10000 0x1000>;
-                       clocks = <&ahb1_gates 9>, <&mmc1_clk>;
-                       clock-names = "ahb", "mmc";
+                       clocks = <&ahb1_gates 9>,
+                                <&mmc1_clk 0>,
+                                <&mmc1_clk 1>,
+                                <&mmc1_clk 2>;
+                       clock-names = "ahb",
+                                     "mmc",
+                                     "output",
+                                     "sample";
                        resets = <&ahb1_rst 9>;
                        reset-names = "ahb";
 -                      interrupts = <0 61 4>;
 +                      interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
                        status = "disabled";
                };
  
                mmc2: mmc@01c11000 {
                        compatible = "allwinner,sun5i-a13-mmc";
                        reg = <0x01c11000 0x1000>;
-                       clocks = <&ahb1_gates 10>, <&mmc2_clk>;
-                       clock-names = "ahb", "mmc";
+                       clocks = <&ahb1_gates 10>,
+                                <&mmc2_clk 0>,
+                                <&mmc2_clk 1>,
+                                <&mmc2_clk 2>;
+                       clock-names = "ahb",
+                                     "mmc",
+                                     "output",
+                                     "sample";
                        resets = <&ahb1_rst 10>;
                        reset-names = "ahb";
 -                      interrupts = <0 62 4>;
 +                      interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
                        status = "disabled";
                };
  
                mmc3: mmc@01c12000 {
                        compatible = "allwinner,sun5i-a13-mmc";
                        reg = <0x01c12000 0x1000>;
-                       clocks = <&ahb1_gates 11>, <&mmc3_clk>;
-                       clock-names = "ahb", "mmc";
+                       clocks = <&ahb1_gates 11>,
+                                <&mmc3_clk 0>,
+                                <&mmc3_clk 1>,
+                                <&mmc3_clk 2>;
+                       clock-names = "ahb",
+                                     "mmc",
+                                     "output",
+                                     "sample";
                        resets = <&ahb1_rst 11>;
                        reset-names = "ahb";
 -                      interrupts = <0 63 4>;
 +                      interrupts = <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
                        status = "disabled";
                };
  
                ehci0: usb@01c1a000 {
                        compatible = "allwinner,sun6i-a31-ehci", "generic-ehci";
                        reg = <0x01c1a000 0x100>;
 -                      interrupts = <0 72 4>;
 +                      interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&ahb1_gates 26>;
                        resets = <&ahb1_rst 26>;
                        phys = <&usbphy 1>;
                ohci0: usb@01c1a400 {
                        compatible = "allwinner,sun6i-a31-ohci", "generic-ohci";
                        reg = <0x01c1a400 0x100>;
 -                      interrupts = <0 73 4>;
 +                      interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&ahb1_gates 29>, <&usb_clk 16>;
                        resets = <&ahb1_rst 29>;
                        phys = <&usbphy 1>;
                ehci1: usb@01c1b000 {
                        compatible = "allwinner,sun6i-a31-ehci", "generic-ehci";
                        reg = <0x01c1b000 0x100>;
 -                      interrupts = <0 74 4>;
 +                      interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&ahb1_gates 27>;
                        resets = <&ahb1_rst 27>;
                        phys = <&usbphy 2>;
                ohci1: usb@01c1b400 {
                        compatible = "allwinner,sun6i-a31-ohci", "generic-ohci";
                        reg = <0x01c1b400 0x100>;
 -                      interrupts = <0 75 4>;
 +                      interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&ahb1_gates 30>, <&usb_clk 17>;
                        resets = <&ahb1_rst 30>;
                        phys = <&usbphy 2>;
                ohci2: usb@01c1c400 {
                        compatible = "allwinner,sun6i-a31-ohci", "generic-ohci";
                        reg = <0x01c1c400 0x100>;
 -                      interrupts = <0 77 4>;
 +                      interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&ahb1_gates 31>, <&usb_clk 18>;
                        resets = <&ahb1_rst 31>;
                        status = "disabled";
                pio: pinctrl@01c20800 {
                        compatible = "allwinner,sun6i-a31-pinctrl";
                        reg = <0x01c20800 0x400>;
 -                      interrupts = <0 11 4>,
 -                                   <0 15 4>,
 -                                   <0 16 4>,
 -                                   <0 17 4>;
 +                      interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
 +                                   <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>,
 +                                   <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
 +                                   <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&apb1_gates 5>;
                        gpio-controller;
                        interrupt-controller;
                        uart0_pins_a: uart0@0 {
                                allwinner,pins = "PH20", "PH21";
                                allwinner,function = "uart0";
 -                              allwinner,drive = <0>;
 -                              allwinner,pull = <0>;
 +                              allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
                        };
  
                        i2c0_pins_a: i2c0@0 {
                                allwinner,pins = "PH14", "PH15";
                                allwinner,function = "i2c0";
 -                              allwinner,drive = <0>;
 -                              allwinner,pull = <0>;
 +                              allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
                        };
  
                        i2c1_pins_a: i2c1@0 {
                                allwinner,pins = "PH16", "PH17";
                                allwinner,function = "i2c1";
 -                              allwinner,drive = <0>;
 -                              allwinner,pull = <0>;
 +                              allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
                        };
  
                        i2c2_pins_a: i2c2@0 {
                                allwinner,pins = "PH18", "PH19";
                                allwinner,function = "i2c2";
 -                              allwinner,drive = <0>;
 -                              allwinner,pull = <0>;
 +                              allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
                        };
  
                        mmc0_pins_a: mmc0@0 {
                                allwinner,pins = "PF0","PF1","PF2","PF3","PF4","PF5";
                                allwinner,function = "mmc0";
 -                              allwinner,drive = <2>;
 -                              allwinner,pull = <0>;
 +                              allwinner,drive = <SUN4I_PINCTRL_30_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
                        };
  
                        gmac_pins_mii_a: gmac_mii@0 {
                                                "PA20", "PA21", "PA22", "PA23",
                                                "PA24", "PA26", "PA27";
                                allwinner,function = "gmac";
 -                              allwinner,drive = <0>;
 -                              allwinner,pull = <0>;
 +                              allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
                        };
  
                        gmac_pins_gmii_a: gmac_gmii@0 {
                                 * data lines in GMII mode run at 125MHz and
                                 * might need a higher signal drive strength
                                 */
 -                              allwinner,drive = <2>;
 -                              allwinner,pull = <0>;
 +                              allwinner,drive = <SUN4I_PINCTRL_30_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
                        };
  
                        gmac_pins_rgmii_a: gmac_rgmii@0 {
                                 * data lines in RGMII mode use DDR mode
                                 * and need a higher signal drive strength
                                 */
 -                              allwinner,drive = <3>;
 -                              allwinner,pull = <0>;
 +                              allwinner,drive = <SUN4I_PINCTRL_40_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
                        };
                };
  
                timer@01c20c00 {
                        compatible = "allwinner,sun4i-a10-timer";
                        reg = <0x01c20c00 0xa0>;
 -                      interrupts = <0 18 4>,
 -                                   <0 19 4>,
 -                                   <0 20 4>,
 -                                   <0 21 4>,
 -                                   <0 22 4>;
 +                      interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
 +                                   <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>,
 +                                   <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>,
 +                                   <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>,
 +                                   <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&osc24M>;
                };
  
                        reg = <0x01c20ca0 0x20>;
                };
  
 +              rtp: rtp@01c25000 {
 +                      compatible = "allwinner,sun6i-a31-ts";
 +                      reg = <0x01c25000 0x100>;
 +                      interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
 +                      #thermal-sensor-cells = <0>;
 +              };
 +
                uart0: serial@01c28000 {
                        compatible = "snps,dw-apb-uart";
                        reg = <0x01c28000 0x400>;
 -                      interrupts = <0 0 4>;
 +                      interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>;
                        reg-shift = <2>;
                        reg-io-width = <4>;
                        clocks = <&apb2_gates 16>;
                uart1: serial@01c28400 {
                        compatible = "snps,dw-apb-uart";
                        reg = <0x01c28400 0x400>;
 -                      interrupts = <0 1 4>;
 +                      interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
                        reg-shift = <2>;
                        reg-io-width = <4>;
                        clocks = <&apb2_gates 17>;
                uart2: serial@01c28800 {
                        compatible = "snps,dw-apb-uart";
                        reg = <0x01c28800 0x400>;
 -                      interrupts = <0 2 4>;
 +                      interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
                        reg-shift = <2>;
                        reg-io-width = <4>;
                        clocks = <&apb2_gates 18>;
                uart3: serial@01c28c00 {
                        compatible = "snps,dw-apb-uart";
                        reg = <0x01c28c00 0x400>;
 -                      interrupts = <0 3 4>;
 +                      interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
                        reg-shift = <2>;
                        reg-io-width = <4>;
                        clocks = <&apb2_gates 19>;
                uart4: serial@01c29000 {
                        compatible = "snps,dw-apb-uart";
                        reg = <0x01c29000 0x400>;
 -                      interrupts = <0 4 4>;
 +                      interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
                        reg-shift = <2>;
                        reg-io-width = <4>;
                        clocks = <&apb2_gates 20>;
                uart5: serial@01c29400 {
                        compatible = "snps,dw-apb-uart";
                        reg = <0x01c29400 0x400>;
 -                      interrupts = <0 5 4>;
 +                      interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
                        reg-shift = <2>;
                        reg-io-width = <4>;
                        clocks = <&apb2_gates 21>;
                i2c0: i2c@01c2ac00 {
                        compatible = "allwinner,sun6i-a31-i2c";
                        reg = <0x01c2ac00 0x400>;
 -                      interrupts = <0 6 4>;
 +                      interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&apb2_gates 0>;
                        resets = <&apb2_rst 0>;
                        status = "disabled";
                i2c1: i2c@01c2b000 {
                        compatible = "allwinner,sun6i-a31-i2c";
                        reg = <0x01c2b000 0x400>;
 -                      interrupts = <0 7 4>;
 +                      interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&apb2_gates 1>;
                        resets = <&apb2_rst 1>;
                        status = "disabled";
                i2c2: i2c@01c2b400 {
                        compatible = "allwinner,sun6i-a31-i2c";
                        reg = <0x01c2b400 0x400>;
 -                      interrupts = <0 8 4>;
 +                      interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&apb2_gates 2>;
                        resets = <&apb2_rst 2>;
                        status = "disabled";
                i2c3: i2c@01c2b800 {
                        compatible = "allwinner,sun6i-a31-i2c";
                        reg = <0x01c2b800 0x400>;
 -                      interrupts = <0 9 4>;
 +                      interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&apb2_gates 3>;
                        resets = <&apb2_rst 3>;
                        status = "disabled";
                gmac: ethernet@01c30000 {
                        compatible = "allwinner,sun7i-a20-gmac";
                        reg = <0x01c30000 0x1054>;
 -                      interrupts = <0 82 4>;
 +                      interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
                        interrupt-names = "macirq";
                        clocks = <&ahb1_gates 17>, <&gmac_tx_clk>;
                        clock-names = "stmmaceth", "allwinner_gmac_tx";
                timer@01c60000 {
                        compatible = "allwinner,sun6i-a31-hstimer", "allwinner,sun7i-a20-hstimer";
                        reg = <0x01c60000 0x1000>;
 -                      interrupts = <0 51 4>,
 -                                   <0 52 4>,
 -                                   <0 53 4>,
 -                                   <0 54 4>;
 +                      interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>,
 +                                   <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>,
 +                                   <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>,
 +                                   <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&ahb1_gates 19>;
                        resets = <&ahb1_rst 19>;
                };
                spi0: spi@01c68000 {
                        compatible = "allwinner,sun6i-a31-spi";
                        reg = <0x01c68000 0x1000>;
 -                      interrupts = <0 65 4>;
 +                      interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&ahb1_gates 20>, <&spi0_clk>;
                        clock-names = "ahb", "mod";
                        dmas = <&dma 23>, <&dma 23>;
                spi1: spi@01c69000 {
                        compatible = "allwinner,sun6i-a31-spi";
                        reg = <0x01c69000 0x1000>;
 -                      interrupts = <0 66 4>;
 +                      interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&ahb1_gates 21>, <&spi1_clk>;
                        clock-names = "ahb", "mod";
                        dmas = <&dma 24>, <&dma 24>;
                spi2: spi@01c6a000 {
                        compatible = "allwinner,sun6i-a31-spi";
                        reg = <0x01c6a000 0x1000>;
 -                      interrupts = <0 67 4>;
 +                      interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&ahb1_gates 22>, <&spi2_clk>;
                        clock-names = "ahb", "mod";
                        dmas = <&dma 25>, <&dma 25>;
                spi3: spi@01c6b000 {
                        compatible = "allwinner,sun6i-a31-spi";
                        reg = <0x01c6b000 0x1000>;
 -                      interrupts = <0 68 4>;
 +                      interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&ahb1_gates 23>, <&spi3_clk>;
                        clock-names = "ahb", "mod";
                        dmas = <&dma 26>, <&dma 26>;
                              <0x01c86000 0x2000>;
                        interrupt-controller;
                        #interrupt-cells = <3>;
 -                      interrupts = <1 9 0xf04>;
 +                      interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
                };
  
                rtc: rtc@01f00000 {
                        compatible = "allwinner,sun6i-a31-rtc";
                        reg = <0x01f00000 0x54>;
 -                      interrupts = <0 40 4>, <0 41 4>;
 +                      interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
 +                                   <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
                };
  
                nmi_intc: interrupt-controller@01f00c0c {
                        interrupt-controller;
                        #interrupt-cells = <2>;
                        reg = <0x01f00c0c 0x38>;
 -                      interrupts = <0 32 4>;
 +                      interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
                };
  
                prcm@01f01400 {
                                                "apb0_i2c";
                        };
  
 +                      ir_clk: ir_clk {
 +                              #clock-cells = <0>;
 +                              compatible = "allwinner,sun4i-a10-mod0-clk";
 +                              clocks = <&osc32k>, <&osc24M>;
 +                              clock-output-names = "ir";
 +                      };
 +
                        apb0_rst: apb0_rst {
                                compatible = "allwinner,sun6i-a31-clock-reset";
                                #reset-cells = <1>;
                        reg = <0x01f01c00 0x300>;
                };
  
 +              ir: ir@01f02000 {
 +                      compatible = "allwinner,sun5i-a13-ir";
 +                      clocks = <&apb0_gates 1>, <&ir_clk>;
 +                      clock-names = "apb", "ir";
 +                      resets = <&apb0_rst 1>;
 +                      interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
 +                      reg = <0x01f02000 0x40>;
 +                      status = "disabled";
 +              };
 +
                r_pio: pinctrl@01f02c00 {
                        compatible = "allwinner,sun6i-a31-r-pinctrl";
                        reg = <0x01f02c00 0x400>;
 -                      interrupts = <0 45 4>,
 -                                   <0 46 4>;
 +                      interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>,
 +                                   <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&apb0_gates 0>;
                        resets = <&apb0_rst 0>;
                        gpio-controller;
                        #interrupt-cells = <2>;
                        #size-cells = <0>;
                        #gpio-cells = <3>;
 +
 +                      ir_pins_a: ir@0 {
 +                              allwinner,pins = "PL4";
 +                              allwinner,function = "s_ir";
 +                              allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
 +                      };
                };
        };
  };
index 786d491542ac429567fd6db6142406858090f81c,390ef09d8c450eae8e7643122e8d8778ae2372c7..3a8530b79f1c46200d2b7ee8bbe343198c7106d8
   *     OTHER DEALINGS IN THE SOFTWARE.
   */
  
 -/include/ "skeleton.dtsi"
 +#include "skeleton.dtsi"
 +
 +#include <dt-bindings/interrupt-controller/arm-gic.h>
 +#include <dt-bindings/thermal/thermal.h>
 +
 +#include <dt-bindings/dma/sun4i-a10.h>
 +#include <dt-bindings/pinctrl/sun4i-a10.h>
  
  / {
        interrupt-parent = <&gic>;
                                 <&ahb_gates 44>;
                        status = "disabled";
                };
 +
 +              framebuffer@1 {
 +                      compatible = "allwinner,simple-framebuffer",
 +                                   "simple-framebuffer";
 +                      allwinner,pipeline = "de_be0-lcd0";
 +                      clocks = <&pll5 1>, <&ahb_gates 36>, <&ahb_gates 44>;
 +                      status = "disabled";
 +              };
 +
 +              framebuffer@2 {
 +                      compatible = "allwinner,simple-framebuffer",
 +                                   "simple-framebuffer";
 +                      allwinner,pipeline = "de_be0-lcd0-tve0";
 +                      clocks = <&pll5 1>, <&ahb_gates 34>, <&ahb_gates 36>,
 +                               <&ahb_gates 44>;
 +                      status = "disabled";
 +              };
        };
  
        cpus {
                #address-cells = <1>;
                #size-cells = <0>;
  
 -              cpu@0 {
 +              cpu0: cpu@0 {
                        compatible = "arm,cortex-a7";
                        device_type = "cpu";
                        reg = <0>;
 +                      clocks = <&cpu>;
 +                      clock-latency = <244144>; /* 8 32k periods */
 +                      operating-points = <
 +                              /* kHz    uV */
 +                              1008000 1450000
 +                              960000  1400000
 +                              912000  1400000
 +                              864000  1300000
 +                              720000  1200000
 +                              528000  1100000
 +                              312000  1000000
 +                              144000  900000
 +                              >;
 +                      #cooling-cells = <2>;
 +                      cooling-min-level = <0>;
 +                      cooling-max-level = <7>;
                };
  
                cpu@1 {
                };
        };
  
 +      thermal-zones {
 +              cpu_thermal {
 +                      /* milliseconds */
 +                      polling-delay-passive = <250>;
 +                      polling-delay = <1000>;
 +                      thermal-sensors = <&rtp>;
 +
 +                      cooling-maps {
 +                              map0 {
 +                                      trip = <&cpu_alert0>;
 +                                      cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
 +                              };
 +                      };
 +
 +                      trips {
 +                              cpu_alert0: cpu_alert0 {
 +                                      /* milliCelsius */
 +                                      temperature = <75000>;
 +                                      hysteresis = <2000>;
 +                                      type = "passive";
 +                              };
 +
 +                              cpu_crit: cpu_crit {
 +                                      /* milliCelsius */
 +                                      temperature = <100000>;
 +                                      hysteresis = <2000>;
 +                                      type = "critical";
 +                              };
 +                      };
 +              };
 +      };
 +
        memory {
                reg = <0x40000000 0x80000000>;
        };
  
        timer {
                compatible = "arm,armv7-timer";
 -              interrupts = <1 13 0xf08>,
 -                           <1 14 0xf08>,
 -                           <1 11 0xf08>,
 -                           <1 10 0xf08>;
 +              interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
 +                           <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
 +                           <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
 +                           <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
        };
  
        pmu {
                compatible = "arm,cortex-a7-pmu", "arm,cortex-a15-pmu";
 -              interrupts = <0 120 4>,
 -                           <0 121 4>;
 +              interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>,
 +                           <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>;
        };
  
        clocks {
                };
  
                mmc0_clk: clk@01c20088 {
-                       #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-a10-mod0-clk";
+                       #clock-cells = <1>;
+                       compatible = "allwinner,sun4i-a10-mmc-clk";
                        reg = <0x01c20088 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-                       clock-output-names = "mmc0";
+                       clock-output-names = "mmc0",
+                                            "mmc0_output",
+                                            "mmc0_sample";
                };
  
                mmc1_clk: clk@01c2008c {
-                       #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-a10-mod0-clk";
+                       #clock-cells = <1>;
+                       compatible = "allwinner,sun4i-a10-mmc-clk";
                        reg = <0x01c2008c 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-                       clock-output-names = "mmc1";
+                       clock-output-names = "mmc1",
+                                            "mmc1_output",
+                                            "mmc1_sample";
                };
  
                mmc2_clk: clk@01c20090 {
-                       #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-a10-mod0-clk";
+                       #clock-cells = <1>;
+                       compatible = "allwinner,sun4i-a10-mmc-clk";
                        reg = <0x01c20090 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-                       clock-output-names = "mmc2";
+                       clock-output-names = "mmc2",
+                                            "mmc2_output",
+                                            "mmc2_sample";
                };
  
                mmc3_clk: clk@01c20094 {
-                       #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-a10-mod0-clk";
+                       #clock-cells = <1>;
+                       compatible = "allwinner,sun4i-a10-mmc-clk";
                        reg = <0x01c20094 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-                       clock-output-names = "mmc3";
+                       clock-output-names = "mmc3",
+                                            "mmc3_output",
+                                            "mmc3_sample";
                };
  
                ts_clk: clk@01c20098 {
                        interrupt-controller;
                        #interrupt-cells = <2>;
                        reg = <0x01c00030 0x0c>;
 -                      interrupts = <0 0 4>;
 +                      interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>;
                };
  
                dma: dma-controller@01c02000 {
                        compatible = "allwinner,sun4i-a10-dma";
                        reg = <0x01c02000 0x1000>;
 -                      interrupts = <0 27 4>;
 +                      interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&ahb_gates 6>;
                        #dma-cells = <2>;
                };
                spi0: spi@01c05000 {
                        compatible = "allwinner,sun4i-a10-spi";
                        reg = <0x01c05000 0x1000>;
 -                      interrupts = <0 10 4>;
 +                      interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&ahb_gates 20>, <&spi0_clk>;
                        clock-names = "ahb", "mod";
 -                      dmas = <&dma 1 27>, <&dma 1 26>;
 +                      dmas = <&dma SUN4I_DMA_DEDICATED 27>,
 +                             <&dma SUN4I_DMA_DEDICATED 26>;
                        dma-names = "rx", "tx";
                        status = "disabled";
                        #address-cells = <1>;
                spi1: spi@01c06000 {
                        compatible = "allwinner,sun4i-a10-spi";
                        reg = <0x01c06000 0x1000>;
 -                      interrupts = <0 11 4>;
 +                      interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&ahb_gates 21>, <&spi1_clk>;
                        clock-names = "ahb", "mod";
 -                      dmas = <&dma 1 9>, <&dma 1 8>;
 +                      dmas = <&dma SUN4I_DMA_DEDICATED 9>,
 +                             <&dma SUN4I_DMA_DEDICATED 8>;
                        dma-names = "rx", "tx";
                        status = "disabled";
                        #address-cells = <1>;
                emac: ethernet@01c0b000 {
                        compatible = "allwinner,sun4i-a10-emac";
                        reg = <0x01c0b000 0x1000>;
 -                      interrupts = <0 55 4>;
 +                      interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&ahb_gates 17>;
                        status = "disabled";
                };
  
 -              mdio@01c0b080 {
 +              mdio: mdio@01c0b080 {
                        compatible = "allwinner,sun4i-a10-mdio";
                        reg = <0x01c0b080 0x14>;
                        status = "disabled";
                mmc0: mmc@01c0f000 {
                        compatible = "allwinner,sun5i-a13-mmc";
                        reg = <0x01c0f000 0x1000>;
-                       clocks = <&ahb_gates 8>, <&mmc0_clk>;
-                       clock-names = "ahb", "mmc";
+                       clocks = <&ahb_gates 8>,
+                                <&mmc0_clk 0>,
+                                <&mmc0_clk 1>,
+                                <&mmc0_clk 2>;
+                       clock-names = "ahb",
+                                     "mmc",
+                                     "output",
+                                     "sample";
 -                      interrupts = <0 32 4>;
 +                      interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
                        status = "disabled";
                };
  
                mmc1: mmc@01c10000 {
                        compatible = "allwinner,sun5i-a13-mmc";
                        reg = <0x01c10000 0x1000>;
-                       clocks = <&ahb_gates 9>, <&mmc1_clk>;
-                       clock-names = "ahb", "mmc";
+                       clocks = <&ahb_gates 9>,
+                                <&mmc1_clk 0>,
+                                <&mmc1_clk 1>,
+                                <&mmc1_clk 2>;
+                       clock-names = "ahb",
+                                     "mmc",
+                                     "output",
+                                     "sample";
 -                      interrupts = <0 33 4>;
 +                      interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
                        status = "disabled";
                };
  
                mmc2: mmc@01c11000 {
                        compatible = "allwinner,sun5i-a13-mmc";
                        reg = <0x01c11000 0x1000>;
-                       clocks = <&ahb_gates 10>, <&mmc2_clk>;
-                       clock-names = "ahb", "mmc";
+                       clocks = <&ahb_gates 10>,
+                                <&mmc2_clk 0>,
+                                <&mmc2_clk 1>,
+                                <&mmc2_clk 2>;
+                       clock-names = "ahb",
+                                     "mmc",
+                                     "output",
+                                     "sample";
 -                      interrupts = <0 34 4>;
 +                      interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
                        status = "disabled";
                };
  
                mmc3: mmc@01c12000 {
                        compatible = "allwinner,sun5i-a13-mmc";
                        reg = <0x01c12000 0x1000>;
-                       clocks = <&ahb_gates 11>, <&mmc3_clk>;
-                       clock-names = "ahb", "mmc";
+                       clocks = <&ahb_gates 11>,
+                                <&mmc3_clk 0>,
+                                <&mmc3_clk 1>,
+                                <&mmc3_clk 2>;
+                       clock-names = "ahb",
+                                     "mmc",
+                                     "output",
+                                     "sample";
 -                      interrupts = <0 35 4>;
 +                      interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
                        status = "disabled";
                };
  
                ehci0: usb@01c14000 {
                        compatible = "allwinner,sun7i-a20-ehci", "generic-ehci";
                        reg = <0x01c14000 0x100>;
 -                      interrupts = <0 39 4>;
 +                      interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&ahb_gates 1>;
                        phys = <&usbphy 1>;
                        phy-names = "usb";
                ohci0: usb@01c14400 {
                        compatible = "allwinner,sun7i-a20-ohci", "generic-ohci";
                        reg = <0x01c14400 0x100>;
 -                      interrupts = <0 64 4>;
 +                      interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&usb_clk 6>, <&ahb_gates 2>;
                        phys = <&usbphy 1>;
                        phy-names = "usb";
                spi2: spi@01c17000 {
                        compatible = "allwinner,sun4i-a10-spi";
                        reg = <0x01c17000 0x1000>;
 -                      interrupts = <0 12 4>;
 +                      interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&ahb_gates 22>, <&spi2_clk>;
                        clock-names = "ahb", "mod";
 -                      dmas = <&dma 1 29>, <&dma 1 28>;
 +                      dmas = <&dma SUN4I_DMA_DEDICATED 29>,
 +                             <&dma SUN4I_DMA_DEDICATED 28>;
                        dma-names = "rx", "tx";
                        status = "disabled";
                        #address-cells = <1>;
                ahci: sata@01c18000 {
                        compatible = "allwinner,sun4i-a10-ahci";
                        reg = <0x01c18000 0x1000>;
 -                      interrupts = <0 56 4>;
 +                      interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&pll6 0>, <&ahb_gates 25>;
                        status = "disabled";
                };
                ehci1: usb@01c1c000 {
                        compatible = "allwinner,sun7i-a20-ehci", "generic-ehci";
                        reg = <0x01c1c000 0x100>;
 -                      interrupts = <0 40 4>;
 +                      interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&ahb_gates 3>;
                        phys = <&usbphy 2>;
                        phy-names = "usb";
                ohci1: usb@01c1c400 {
                        compatible = "allwinner,sun7i-a20-ohci", "generic-ohci";
                        reg = <0x01c1c400 0x100>;
 -                      interrupts = <0 65 4>;
 +                      interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&usb_clk 7>, <&ahb_gates 4>;
                        phys = <&usbphy 2>;
                        phy-names = "usb";
                spi3: spi@01c1f000 {
                        compatible = "allwinner,sun4i-a10-spi";
                        reg = <0x01c1f000 0x1000>;
 -                      interrupts = <0 50 4>;
 +                      interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&ahb_gates 23>, <&spi3_clk>;
                        clock-names = "ahb", "mod";
 -                      dmas = <&dma 1 31>, <&dma 1 30>;
 +                      dmas = <&dma SUN4I_DMA_DEDICATED 31>,
 +                             <&dma SUN4I_DMA_DEDICATED 30>;
                        dma-names = "rx", "tx";
                        status = "disabled";
                        #address-cells = <1>;
                pio: pinctrl@01c20800 {
                        compatible = "allwinner,sun7i-a20-pinctrl";
                        reg = <0x01c20800 0x400>;
 -                      interrupts = <0 28 4>;
 +                      interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&apb0_gates 5>;
                        gpio-controller;
                        interrupt-controller;
                        pwm0_pins_a: pwm0@0 {
                                allwinner,pins = "PB2";
                                allwinner,function = "pwm";
 -                              allwinner,drive = <0>;
 -                              allwinner,pull = <0>;
 +                              allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
                        };
  
                        pwm1_pins_a: pwm1@0 {
                                allwinner,pins = "PI3";
                                allwinner,function = "pwm";
 -                              allwinner,drive = <0>;
 -                              allwinner,pull = <0>;
 +                              allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
                        };
  
                        uart0_pins_a: uart0@0 {
                                allwinner,pins = "PB22", "PB23";
                                allwinner,function = "uart0";
 -                              allwinner,drive = <0>;
 -                              allwinner,pull = <0>;
 +                              allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
                        };
  
                        uart2_pins_a: uart2@0 {
                                allwinner,pins = "PI16", "PI17", "PI18", "PI19";
                                allwinner,function = "uart2";
 -                              allwinner,drive = <0>;
 -                              allwinner,pull = <0>;
 +                              allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
                        };
  
                        uart3_pins_a: uart3@0 {
                                allwinner,pins = "PG6", "PG7", "PG8", "PG9";
                                allwinner,function = "uart3";
 -                              allwinner,drive = <0>;
 -                              allwinner,pull = <0>;
 +                              allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
                        };
  
                        uart3_pins_b: uart3@1 {
                                allwinner,pins = "PH0", "PH1";
                                allwinner,function = "uart3";
 -                              allwinner,drive = <0>;
 -                              allwinner,pull = <0>;
 +                              allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
                        };
  
                        uart4_pins_a: uart4@0 {
                                allwinner,pins = "PG10", "PG11";
                                allwinner,function = "uart4";
 -                              allwinner,drive = <0>;
 -                              allwinner,pull = <0>;
 +                              allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
                        };
  
                        uart5_pins_a: uart5@0 {
                                allwinner,pins = "PI10", "PI11";
                                allwinner,function = "uart5";
 -                              allwinner,drive = <0>;
 -                              allwinner,pull = <0>;
 +                              allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
                        };
  
                        uart6_pins_a: uart6@0 {
                                allwinner,pins = "PI12", "PI13";
                                allwinner,function = "uart6";
 -                              allwinner,drive = <0>;
 -                              allwinner,pull = <0>;
 +                              allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
                        };
  
                        uart7_pins_a: uart7@0 {
                                allwinner,pins = "PI20", "PI21";
                                allwinner,function = "uart7";
 -                              allwinner,drive = <0>;
 -                              allwinner,pull = <0>;
 +                              allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
                        };
  
                        i2c0_pins_a: i2c0@0 {
                                allwinner,pins = "PB0", "PB1";
                                allwinner,function = "i2c0";
 -                              allwinner,drive = <0>;
 -                              allwinner,pull = <0>;
 +                              allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
                        };
  
                        i2c1_pins_a: i2c1@0 {
                                allwinner,pins = "PB18", "PB19";
                                allwinner,function = "i2c1";
 -                              allwinner,drive = <0>;
 -                              allwinner,pull = <0>;
 +                              allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
                        };
  
                        i2c2_pins_a: i2c2@0 {
                                allwinner,pins = "PB20", "PB21";
                                allwinner,function = "i2c2";
 -                              allwinner,drive = <0>;
 -                              allwinner,pull = <0>;
 +                              allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
                        };
  
                        i2c3_pins_a: i2c3@0 {
                                allwinner,pins = "PI0", "PI1";
                                allwinner,function = "i2c3";
 -                              allwinner,drive = <0>;
 -                              allwinner,pull = <0>;
 +                              allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
                        };
  
                        emac_pins_a: emac0@0 {
                                                "PA11", "PA12", "PA13", "PA14",
                                                "PA15", "PA16";
                                allwinner,function = "emac";
 -                              allwinner,drive = <0>;
 -                              allwinner,pull = <0>;
 +                              allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
                        };
  
                        clk_out_a_pins_a: clk_out_a@0 {
                                allwinner,pins = "PI12";
                                allwinner,function = "clk_out_a";
 -                              allwinner,drive = <0>;
 -                              allwinner,pull = <0>;
 +                              allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
                        };
  
                        clk_out_b_pins_a: clk_out_b@0 {
                                allwinner,pins = "PI13";
                                allwinner,function = "clk_out_b";
 -                              allwinner,drive = <0>;
 -                              allwinner,pull = <0>;
 +                              allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
                        };
  
                        gmac_pins_mii_a: gmac_mii@0 {
                                                "PA11", "PA12", "PA13", "PA14",
                                                "PA15", "PA16";
                                allwinner,function = "gmac";
 -                              allwinner,drive = <0>;
 -                              allwinner,pull = <0>;
 +                              allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
                        };
  
                        gmac_pins_rgmii_a: gmac_rgmii@0 {
                                 * data lines in RGMII mode use DDR mode
                                 * and need a higher signal drive strength
                                 */
 -                              allwinner,drive = <3>;
 -                              allwinner,pull = <0>;
 +                              allwinner,drive = <SUN4I_PINCTRL_40_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
                        };
  
                        spi0_pins_a: spi0@0 {
                                allwinner,pins = "PI10", "PI11", "PI12", "PI13", "PI14";
                                allwinner,function = "spi0";
 -                              allwinner,drive = <0>;
 -                              allwinner,pull = <0>;
 +                              allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
                        };
  
                        spi1_pins_a: spi1@0 {
                                allwinner,pins = "PI16", "PI17", "PI18", "PI19";
                                allwinner,function = "spi1";
 -                              allwinner,drive = <0>;
 -                              allwinner,pull = <0>;
 +                              allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
                        };
  
                        spi2_pins_a: spi2@0 {
                                allwinner,pins = "PC19", "PC20", "PC21", "PC22";
                                allwinner,function = "spi2";
 -                              allwinner,drive = <0>;
 -                              allwinner,pull = <0>;
 +                              allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
                        };
  
                        spi2_pins_b: spi2@1 {
                                allwinner,pins = "PB14", "PB15", "PB16", "PB17";
                                allwinner,function = "spi2";
 -                              allwinner,drive = <0>;
 -                              allwinner,pull = <0>;
 +                              allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
                        };
  
                        mmc0_pins_a: mmc0@0 {
                                allwinner,pins = "PF0","PF1","PF2","PF3","PF4","PF5";
                                allwinner,function = "mmc0";
 -                              allwinner,drive = <2>;
 -                              allwinner,pull = <0>;
 +                              allwinner,drive = <SUN4I_PINCTRL_30_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
                        };
  
                        mmc0_cd_pin_reference_design: mmc0_cd_pin@0 {
                                allwinner,pins = "PH1";
                                allwinner,function = "gpio_in";
 -                              allwinner,drive = <0>;
 -                              allwinner,pull = <1>;
 +                              allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
                        };
  
                        mmc2_pins_a: mmc2@0 {
                                allwinner,pins = "PC6","PC7","PC8","PC9","PC10","PC11";
                                allwinner,function = "mmc2";
 -                              allwinner,drive = <2>;
 -                              allwinner,pull = <1>;
 +                              allwinner,drive = <SUN4I_PINCTRL_30_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
                        };
  
                        mmc3_pins_a: mmc3@0 {
                                allwinner,pins = "PI4","PI5","PI6","PI7","PI8","PI9";
                                allwinner,function = "mmc3";
 -                              allwinner,drive = <2>;
 -                              allwinner,pull = <0>;
 +                              allwinner,drive = <SUN4I_PINCTRL_30_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
                        };
  
                        ir0_pins_a: ir0@0 {
                                    allwinner,pins = "PB3","PB4";
                                    allwinner,function = "ir0";
 -                                  allwinner,drive = <0>;
 -                                  allwinner,pull = <0>;
 +                                  allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 +                                  allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
                        };
  
                        ir1_pins_a: ir1@0 {
                                    allwinner,pins = "PB22","PB23";
                                    allwinner,function = "ir1";
 -                                  allwinner,drive = <0>;
 -                                  allwinner,pull = <0>;
 +                                  allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 +                                  allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
 +                      };
 +
 +                      ps20_pins_a: ps20@0 {
 +                              allwinner,pins = "PI20", "PI21";
 +                              allwinner,function = "ps2";
 +                              allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
 +                      };
 +
 +                      ps21_pins_a: ps21@0 {
 +                              allwinner,pins = "PH12", "PH13";
 +                              allwinner,function = "ps2";
 +                              allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
                        };
                };
  
                timer@01c20c00 {
                        compatible = "allwinner,sun4i-a10-timer";
                        reg = <0x01c20c00 0x90>;
 -                      interrupts = <0 22 4>,
 -                                   <0 23 4>,
 -                                   <0 24 4>,
 -                                   <0 25 4>,
 -                                   <0 67 4>,
 -                                   <0 68 4>;
 +                      interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>,
 +                                   <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>,
 +                                   <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>,
 +                                   <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>,
 +                                   <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>,
 +                                   <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&osc24M>;
                };
  
                rtc: rtc@01c20d00 {
                        compatible = "allwinner,sun7i-a20-rtc";
                        reg = <0x01c20d00 0x20>;
 -                      interrupts = <0 24 4>;
 +                      interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
                };
  
                pwm: pwm@01c20e00 {
                        compatible = "allwinner,sun4i-a10-ir";
                        clocks = <&apb0_gates 6>, <&ir0_clk>;
                        clock-names = "apb", "ir";
 -                      interrupts = <0 5 4>;
 +                      interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
                        reg = <0x01c21800 0x40>;
                        status = "disabled";
                };
                        compatible = "allwinner,sun4i-a10-ir";
                        clocks = <&apb0_gates 7>, <&ir1_clk>;
                        clock-names = "apb", "ir";
 -                      interrupts = <0 6 4>;
 +                      interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
                        reg = <0x01c21c00 0x40>;
                        status = "disabled";
                };
  
 +              lradc: lradc@01c22800 {
 +                      compatible = "allwinner,sun4i-a10-lradc-keys";
 +                      reg = <0x01c22800 0x100>;
 +                      interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
 +                      status = "disabled";
 +              };
 +
                sid: eeprom@01c23800 {
                        compatible = "allwinner,sun7i-a20-sid";
                        reg = <0x01c23800 0x200>;
                rtp: rtp@01c25000 {
                        compatible = "allwinner,sun4i-a10-ts";
                        reg = <0x01c25000 0x100>;
 -                      interrupts = <0 29 4>;
 +                      interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
 +                      #thermal-sensor-cells = <0>;
                };
  
                uart0: serial@01c28000 {
                        compatible = "snps,dw-apb-uart";
                        reg = <0x01c28000 0x400>;
 -                      interrupts = <0 1 4>;
 +                      interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
                        reg-shift = <2>;
                        reg-io-width = <4>;
                        clocks = <&apb1_gates 16>;
                uart1: serial@01c28400 {
                        compatible = "snps,dw-apb-uart";
                        reg = <0x01c28400 0x400>;
 -                      interrupts = <0 2 4>;
 +                      interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
                        reg-shift = <2>;
                        reg-io-width = <4>;
                        clocks = <&apb1_gates 17>;
                uart2: serial@01c28800 {
                        compatible = "snps,dw-apb-uart";
                        reg = <0x01c28800 0x400>;
 -                      interrupts = <0 3 4>;
 +                      interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
                        reg-shift = <2>;
                        reg-io-width = <4>;
                        clocks = <&apb1_gates 18>;
                uart3: serial@01c28c00 {
                        compatible = "snps,dw-apb-uart";
                        reg = <0x01c28c00 0x400>;
 -                      interrupts = <0 4 4>;
 +                      interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
                        reg-shift = <2>;
                        reg-io-width = <4>;
                        clocks = <&apb1_gates 19>;
                uart4: serial@01c29000 {
                        compatible = "snps,dw-apb-uart";
                        reg = <0x01c29000 0x400>;
 -                      interrupts = <0 17 4>;
 +                      interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
                        reg-shift = <2>;
                        reg-io-width = <4>;
                        clocks = <&apb1_gates 20>;
                uart5: serial@01c29400 {
                        compatible = "snps,dw-apb-uart";
                        reg = <0x01c29400 0x400>;
 -                      interrupts = <0 18 4>;
 +                      interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
                        reg-shift = <2>;
                        reg-io-width = <4>;
                        clocks = <&apb1_gates 21>;
                uart6: serial@01c29800 {
                        compatible = "snps,dw-apb-uart";
                        reg = <0x01c29800 0x400>;
 -                      interrupts = <0 19 4>;
 +                      interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
                        reg-shift = <2>;
                        reg-io-width = <4>;
                        clocks = <&apb1_gates 22>;
                uart7: serial@01c29c00 {
                        compatible = "snps,dw-apb-uart";
                        reg = <0x01c29c00 0x400>;
 -                      interrupts = <0 20 4>;
 +                      interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
                        reg-shift = <2>;
                        reg-io-width = <4>;
                        clocks = <&apb1_gates 23>;
                i2c0: i2c@01c2ac00 {
                        compatible = "allwinner,sun7i-a20-i2c", "allwinner,sun4i-a10-i2c";
                        reg = <0x01c2ac00 0x400>;
 -                      interrupts = <0 7 4>;
 +                      interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&apb1_gates 0>;
                        status = "disabled";
                        #address-cells = <1>;
                i2c1: i2c@01c2b000 {
                        compatible = "allwinner,sun7i-a20-i2c", "allwinner,sun4i-a10-i2c";
                        reg = <0x01c2b000 0x400>;
 -                      interrupts = <0 8 4>;
 +                      interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&apb1_gates 1>;
                        status = "disabled";
                        #address-cells = <1>;
                i2c2: i2c@01c2b400 {
                        compatible = "allwinner,sun7i-a20-i2c", "allwinner,sun4i-a10-i2c";
                        reg = <0x01c2b400 0x400>;
 -                      interrupts = <0 9 4>;
 +                      interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&apb1_gates 2>;
                        status = "disabled";
                        #address-cells = <1>;
                i2c3: i2c@01c2b800 {
                        compatible = "allwinner,sun7i-a20-i2c", "allwinner,sun4i-a10-i2c";
                        reg = <0x01c2b800 0x400>;
 -                      interrupts = <0 88 4>;
 +                      interrupts = <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&apb1_gates 3>;
                        status = "disabled";
                        #address-cells = <1>;
                i2c4: i2c@01c2c000 {
                        compatible = "allwinner,sun7i-a20-i2c", "allwinner,sun4i-a10-i2c";
                        reg = <0x01c2c000 0x400>;
 -                      interrupts = <0 89 4>;
 +                      interrupts = <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&apb1_gates 15>;
                        status = "disabled";
                        #address-cells = <1>;
                gmac: ethernet@01c50000 {
                        compatible = "allwinner,sun7i-a20-gmac";
                        reg = <0x01c50000 0x10000>;
 -                      interrupts = <0 85 4>;
 +                      interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
                        interrupt-names = "macirq";
                        clocks = <&ahb_gates 49>, <&gmac_tx_clk>;
                        clock-names = "stmmaceth", "allwinner_gmac_tx";
                hstimer@01c60000 {
                        compatible = "allwinner,sun7i-a20-hstimer";
                        reg = <0x01c60000 0x1000>;
 -                      interrupts = <0 81 4>,
 -                                   <0 82 4>,
 -                                   <0 83 4>,
 -                                   <0 84 4>;
 +                      interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>,
 +                                   <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>,
 +                                   <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>,
 +                                   <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&ahb_gates 28>;
                };
  
                              <0x01c86000 0x2000>;
                        interrupt-controller;
                        #interrupt-cells = <3>;
 -                      interrupts = <1 9 0xf04>;
 +                      interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
 +              };
 +
 +              ps20: ps2@01c2a000 {
 +                      compatible = "allwinner,sun4i-a10-ps2";
 +                      reg = <0x01c2a000 0x400>;
 +                      interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
 +                      clocks = <&apb1_gates 6>;
 +                      status = "disabled";
 +              };
 +
 +              ps21: ps2@01c2a400 {
 +                      compatible = "allwinner,sun4i-a10-ps2";
 +                      reg = <0x01c2a400 0x400>;
 +                      interrupts = <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
 +                      clocks = <&apb1_gates 7>;
 +                      status = "disabled";
                };
        };
  };
index dd34527293e465d4739cf4518bbd8b292a61989b,edd4d912825872c2ca4c52005bb3bc497a77d1e9..382ebd137ee4fbe97514362eee3f336d4e253047
   *     OTHER DEALINGS IN THE SOFTWARE.
   */
  
 -/include/ "skeleton.dtsi"
 +#include "skeleton.dtsi"
 +
 +#include <dt-bindings/interrupt-controller/arm-gic.h>
 +
 +#include <dt-bindings/pinctrl/sun4i-a10.h>
  
  / {
        interrupt-parent = <&gic>;
  
 +      chosen {
 +              #address-cells = <1>;
 +              #size-cells = <1>;
 +              ranges;
 +
 +              framebuffer@0 {
 +                      compatible = "allwinner,simple-framebuffer",
 +                                   "simple-framebuffer";
 +                      allwinner,pipeline = "de_be0-lcd0";
 +                      clocks = <&pll6 0>;
 +                      status = "disabled";
 +              };
 +      };
 +
        cpus {
                #address-cells = <1>;
                #size-cells = <0>;
                };
  
                /* dummy clock until actually implemented */
-               pll6: pll6_clk {
+               pll5: pll5_clk {
                        #clock-cells = <0>;
                        compatible = "fixed-clock";
-                       clock-frequency = <600000000>;
-                       clock-output-names = "pll6";
+                       clock-frequency = <0>;
+                       clock-output-names = "pll5";
+               };
+               pll6: clk@01c20028 {
+                       #clock-cells = <1>;
+                       compatible = "allwinner,sun6i-a31-pll6-clk";
+                       reg = <0x01c20028 0x4>;
+                       clocks = <&osc24M>;
+                       clock-output-names = "pll6", "pll6x2";
                };
  
                cpu: cpu_clk@01c20050 {
                        clock-output-names = "axi";
                };
  
-               ahb1_mux: ahb1_mux_clk@01c20054 {
-                       #clock-cells = <0>;
-                       compatible = "allwinner,sun6i-a31-ahb1-mux-clk";
-                       reg = <0x01c20054 0x4>;
-                       clocks = <&osc32k>, <&osc24M>, <&axi>, <&pll6>;
-                       clock-output-names = "ahb1_mux";
-               };
                ahb1: ahb1_clk@01c20054 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-a10-ahb-clk";
+                       compatible = "allwinner,sun6i-a31-ahb1-clk";
                        reg = <0x01c20054 0x4>;
-                       clocks = <&ahb1_mux>;
+                       clocks = <&osc32k>, <&osc24M>, <&axi>, <&pll6 0>;
                        clock-output-names = "ahb1";
                };
  
                        #clock-cells = <0>;
                        compatible = "allwinner,sun4i-a10-apb1-clk";
                        reg = <0x01c20058 0x4>;
-                       clocks = <&osc32k>, <&osc24M>, <&pll6>, <&pll6>;
+                       clocks = <&osc32k>, <&osc24M>, <&pll6 0>, <&pll6 0>;
                        clock-output-names = "apb2";
                };
  
                };
  
                mmc0_clk: clk@01c20088 {
-                       #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-a10-mod0-clk";
+                       #clock-cells = <1>;
+                       compatible = "allwinner,sun4i-a10-mmc-clk";
                        reg = <0x01c20088 0x4>;
-                       clocks = <&osc24M>, <&pll6>;
-                       clock-output-names = "mmc0";
+                       clocks = <&osc24M>, <&pll6 0>;
+                       clock-output-names = "mmc0",
+                                            "mmc0_output",
+                                            "mmc0_sample";
                };
  
                mmc1_clk: clk@01c2008c {
-                       #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-a10-mod0-clk";
+                       #clock-cells = <1>;
+                       compatible = "allwinner,sun4i-a10-mmc-clk";
                        reg = <0x01c2008c 0x4>;
-                       clocks = <&osc24M>, <&pll6>;
-                       clock-output-names = "mmc1";
+                       clocks = <&osc24M>, <&pll6 0>;
+                       clock-output-names = "mmc1",
+                                            "mmc1_output",
+                                            "mmc1_sample";
                };
  
                mmc2_clk: clk@01c20090 {
-                       #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-a10-mod0-clk";
+                       #clock-cells = <1>;
+                       compatible = "allwinner,sun4i-a10-mmc-clk";
                        reg = <0x01c20090 0x4>;
-                       clocks = <&osc24M>, <&pll6>;
-                       clock-output-names = "mmc2";
+                       clocks = <&osc24M>, <&pll6 0>;
+                       clock-output-names = "mmc2",
+                                            "mmc2_output",
+                                            "mmc2_sample";
+               };
+               mbus_clk: clk@01c2015c {
+                       #clock-cells = <0>;
+                       compatible = "allwinner,sun8i-a23-mbus-clk";
+                       reg = <0x01c2015c 0x4>;
+                       clocks = <&osc24M>, <&pll6 1>, <&pll5>;
+                       clock-output-names = "mbus";
                };
        };
  
                dma: dma-controller@01c02000 {
                        compatible = "allwinner,sun8i-a23-dma";
                        reg = <0x01c02000 0x1000>;
 -                      interrupts = <0 50 4>;
 +                      interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&ahb1_gates 6>;
                        resets = <&ahb1_rst 6>;
                        #dma-cells = <1>;
                mmc0: mmc@01c0f000 {
                        compatible = "allwinner,sun5i-a13-mmc";
                        reg = <0x01c0f000 0x1000>;
-                       clocks = <&ahb1_gates 8>, <&mmc0_clk>;
-                       clock-names = "ahb", "mmc";
+                       clocks = <&ahb1_gates 8>,
+                                <&mmc0_clk 0>,
+                                <&mmc0_clk 1>,
+                                <&mmc0_clk 2>;
+                       clock-names = "ahb",
+                                     "mmc",
+                                     "output",
+                                     "sample";
                        resets = <&ahb1_rst 8>;
                        reset-names = "ahb";
 -                      interrupts = <0 60 4>;
 +                      interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>;
                        status = "disabled";
                };
  
                mmc1: mmc@01c10000 {
                        compatible = "allwinner,sun5i-a13-mmc";
                        reg = <0x01c10000 0x1000>;
-                       clocks = <&ahb1_gates 9>, <&mmc1_clk>;
-                       clock-names = "ahb", "mmc";
+                       clocks = <&ahb1_gates 9>,
+                                <&mmc1_clk 0>,
+                                <&mmc1_clk 1>,
+                                <&mmc1_clk 2>;
+                       clock-names = "ahb",
+                                     "mmc",
+                                     "output",
+                                     "sample";
                        resets = <&ahb1_rst 9>;
                        reset-names = "ahb";
 -                      interrupts = <0 61 4>;
 +                      interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
                        status = "disabled";
                };
  
                mmc2: mmc@01c11000 {
                        compatible = "allwinner,sun5i-a13-mmc";
                        reg = <0x01c11000 0x1000>;
-                       clocks = <&ahb1_gates 10>, <&mmc2_clk>;
-                       clock-names = "ahb", "mmc";
+                       clocks = <&ahb1_gates 10>,
+                                <&mmc2_clk 0>,
+                                <&mmc2_clk 1>,
+                                <&mmc2_clk 2>;
+                       clock-names = "ahb",
+                                     "mmc",
+                                     "output",
+                                     "sample";
                        resets = <&ahb1_rst 10>;
                        reset-names = "ahb";
 -                      interrupts = <0 62 4>;
 +                      interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
                        status = "disabled";
                };
  
                pio: pinctrl@01c20800 {
                        compatible = "allwinner,sun8i-a23-pinctrl";
                        reg = <0x01c20800 0x400>;
 -                      interrupts = <0 11 4>,
 -                                   <0 15 4>,
 -                                   <0 17 4>;
 +                      interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
 +                                   <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>,
 +                                   <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&apb1_gates 5>;
                        gpio-controller;
                        interrupt-controller;
                        uart0_pins_a: uart0@0 {
                                allwinner,pins = "PF2", "PF4";
                                allwinner,function = "uart0";
 -                              allwinner,drive = <0>;
 -                              allwinner,pull = <0>;
 +                              allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
                        };
  
                        mmc0_pins_a: mmc0@0 {
                                allwinner,pins = "PF0","PF1","PF2","PF3","PF4","PF5";
                                allwinner,function = "mmc0";
 -                              allwinner,drive = <2>;
 -                              allwinner,pull = <0>;
 +                              allwinner,drive = <SUN4I_PINCTRL_30_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
                        };
  
                        mmc1_pins_a: mmc1@0 {
                                allwinner,pins = "PG0","PG1","PG2","PG3","PG4","PG5";
                                allwinner,function = "mmc1";
 -                              allwinner,drive = <2>;
 -                              allwinner,pull = <0>;
 +                              allwinner,drive = <SUN4I_PINCTRL_30_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
                        };
  
                        i2c0_pins_a: i2c0@0 {
                                allwinner,pins = "PH2", "PH3";
                                allwinner,function = "i2c0";
 -                              allwinner,drive = <0>;
 -                              allwinner,pull = <0>;
 +                              allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
                        };
  
                        i2c1_pins_a: i2c1@0 {
                                allwinner,pins = "PH4", "PH5";
                                allwinner,function = "i2c1";
 -                              allwinner,drive = <0>;
 -                              allwinner,pull = <0>;
 +                              allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
                        };
  
                        i2c2_pins_a: i2c2@0 {
                                allwinner,pins = "PE12", "PE13";
                                allwinner,function = "i2c2";
 -                              allwinner,drive = <0>;
 -                              allwinner,pull = <0>;
 +                              allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
                        };
                };
  
                timer@01c20c00 {
                        compatible = "allwinner,sun4i-a10-timer";
                        reg = <0x01c20c00 0xa0>;
 -                      interrupts = <0 18 4>,
 -                                   <0 19 4>;
 +                      interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
 +                                   <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&osc24M>;
                };
  
                wdt0: watchdog@01c20ca0 {
                        compatible = "allwinner,sun6i-a31-wdt";
                        reg = <0x01c20ca0 0x20>;
 -                      interrupts = <0 25 4>;
 +                      interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
 +              };
 +
 +              lradc: lradc@01c22800 {
 +                      compatible = "allwinner,sun4i-a10-lradc-keys";
 +                      reg = <0x01c22800 0x100>;
 +                      interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
 +                      status = "disabled";
                };
  
                uart0: serial@01c28000 {
                        compatible = "snps,dw-apb-uart";
                        reg = <0x01c28000 0x400>;
 -                      interrupts = <0 0 4>;
 +                      interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>;
                        reg-shift = <2>;
                        reg-io-width = <4>;
                        clocks = <&apb2_gates 16>;
                uart1: serial@01c28400 {
                        compatible = "snps,dw-apb-uart";
                        reg = <0x01c28400 0x400>;
 -                      interrupts = <0 1 4>;
 +                      interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
                        reg-shift = <2>;
                        reg-io-width = <4>;
                        clocks = <&apb2_gates 17>;
                uart2: serial@01c28800 {
                        compatible = "snps,dw-apb-uart";
                        reg = <0x01c28800 0x400>;
 -                      interrupts = <0 2 4>;
 +                      interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
                        reg-shift = <2>;
                        reg-io-width = <4>;
                        clocks = <&apb2_gates 18>;
                uart3: serial@01c28c00 {
                        compatible = "snps,dw-apb-uart";
                        reg = <0x01c28c00 0x400>;
 -                      interrupts = <0 3 4>;
 +                      interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
                        reg-shift = <2>;
                        reg-io-width = <4>;
                        clocks = <&apb2_gates 19>;
                uart4: serial@01c29000 {
                        compatible = "snps,dw-apb-uart";
                        reg = <0x01c29000 0x400>;
 -                      interrupts = <0 4 4>;
 +                      interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
                        reg-shift = <2>;
                        reg-io-width = <4>;
                        clocks = <&apb2_gates 20>;
                i2c0: i2c@01c2ac00 {
                        compatible = "allwinner,sun6i-a31-i2c";
                        reg = <0x01c2ac00 0x400>;
 -                      interrupts = <0 6 4>;
 +                      interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&apb2_gates 0>;
                        resets = <&apb2_rst 0>;
                        status = "disabled";
                i2c1: i2c@01c2b000 {
                        compatible = "allwinner,sun6i-a31-i2c";
                        reg = <0x01c2b000 0x400>;
 -                      interrupts = <0 7 4>;
 +                      interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&apb2_gates 1>;
                        resets = <&apb2_rst 1>;
                        status = "disabled";
                i2c2: i2c@01c2b400 {
                        compatible = "allwinner,sun6i-a31-i2c";
                        reg = <0x01c2b400 0x400>;
 -                      interrupts = <0 8 4>;
 +                      interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&apb2_gates 2>;
                        resets = <&apb2_rst 2>;
                        status = "disabled";
                              <0x01c86000 0x2000>;
                        interrupt-controller;
                        #interrupt-cells = <3>;
 -                      interrupts = <1 9 0xf04>;
 +                      interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
                };
  
                rtc: rtc@01f00000 {
                        compatible = "allwinner,sun6i-a31-rtc";
                        reg = <0x01f00000 0x54>;
 -                      interrupts = <0 40 4>, <0 41 4>;
 +                      interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
 +                                   <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
                };
  
                prcm@01f01400 {
                r_uart: serial@01f02800 {
                        compatible = "snps,dw-apb-uart";
                        reg = <0x01f02800 0x400>;
 -                      interrupts = <0 38 4>;
 +                      interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
                        reg-shift = <2>;
                        reg-io-width = <4>;
                        clocks = <&apb0_gates 4>;
                r_pio: pinctrl@01f02c00 {
                        compatible = "allwinner,sun8i-a23-r-pinctrl";
                        reg = <0x01f02c00 0x400>;
 -                      interrupts = <0 45 4>;
 +                      interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&apb0_gates 0>;
                        resets = <&apb0_rst 0>;
                        gpio-controller;
                        r_uart_pins_a: r_uart@0 {
                                allwinner,pins = "PL2", "PL3";
                                allwinner,function = "s_uart";
 -                              allwinner,drive = <0>;
 -                              allwinner,pull = <0>;
 +                              allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 +                              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
                        };
                };
        };
index 00d5d8f9f150ed8e8a475c9103bdc74da2f3cdf1,d2a6b271e85b3908605742ee79ca451c04c3b359..b83f18fcec9b3c693944a6a2d0aafccf8e660a75
@@@ -58,7 -58,6 +58,7 @@@ AFLAGS_sram34xx.o                     :=-Wa,-march=armv7-
  # Restart code (OMAP4/5 currently in omap4-common.c)
  obj-$(CONFIG_SOC_OMAP2420)            += omap2-restart.o
  obj-$(CONFIG_SOC_OMAP2430)            += omap2-restart.o
 +obj-$(CONFIG_SOC_TI81XX)              += ti81xx-restart.o
  obj-$(CONFIG_SOC_AM33XX)              += am33xx-restart.o
  obj-$(CONFIG_SOC_AM43XX)              += omap4-restart.o
  obj-$(CONFIG_ARCH_OMAP3)              += omap3-restart.o
@@@ -121,7 -120,6 +121,7 @@@ obj-$(CONFIG_ARCH_OMAP4)           += $(omap-prc
  obj-$(CONFIG_SOC_OMAP5)                       += $(omap-prcm-4-5-common)
  obj-$(CONFIG_SOC_DRA7XX)              += $(omap-prcm-4-5-common)
  am33xx-43xx-prcm-common                       += prm33xx.o cm33xx.o
 +obj-$(CONFIG_SOC_TI81XX)              += $(am33xx-43xx-prcm-common)
  obj-$(CONFIG_SOC_AM33XX)              += $(am33xx-43xx-prcm-common)
  obj-$(CONFIG_SOC_AM43XX)              += $(omap-prcm-4-5-common) \
                                           $(am33xx-43xx-prcm-common)
@@@ -172,8 -170,6 +172,8 @@@ obj-$(CONFIG_ARCH_OMAP4)           += $(clockdom
  obj-$(CONFIG_ARCH_OMAP4)              += clockdomains44xx_data.o
  obj-$(CONFIG_SOC_AM33XX)              += $(clockdomain-common)
  obj-$(CONFIG_SOC_AM33XX)              += clockdomains33xx_data.o
 +obj-$(CONFIG_SOC_TI81XX)              += $(clockdomain-common)
 +obj-$(CONFIG_SOC_TI81XX)              += clockdomains81xx_data.o
  obj-$(CONFIG_SOC_AM43XX)              += $(clockdomain-common)
  obj-$(CONFIG_SOC_AM43XX)              += clockdomains43xx_data.o
  obj-$(CONFIG_SOC_OMAP5)                       += $(clockdomain-common)
@@@ -185,12 -181,13 +185,12 @@@ obj-$(CONFIG_SOC_DRA7XX)                += clockdomai
  obj-$(CONFIG_ARCH_OMAP2)              += $(clock-common) clock2xxx.o
  obj-$(CONFIG_ARCH_OMAP2)              += clkt2xxx_dpllcore.o
  obj-$(CONFIG_ARCH_OMAP2)              += clkt2xxx_virt_prcm_set.o
 -obj-$(CONFIG_ARCH_OMAP2)              += clkt2xxx_apll.o
  obj-$(CONFIG_ARCH_OMAP2)              += clkt2xxx_dpll.o clkt_iclk.o
  obj-$(CONFIG_SOC_OMAP2430)            += clock2430.o
  obj-$(CONFIG_ARCH_OMAP3)              += $(clock-common) clock3xxx.o
  obj-$(CONFIG_ARCH_OMAP3)              += clock34xx.o clkt34xx_dpll3m2.o
  obj-$(CONFIG_ARCH_OMAP3)              += clock3517.o clock36xx.o
- obj-$(CONFIG_ARCH_OMAP3)              += dpll3xxx.o cclock3xxx_data.o
+ obj-$(CONFIG_ARCH_OMAP3)              += dpll3xxx.o
  obj-$(CONFIG_ARCH_OMAP3)              += clkt_iclk.o
  obj-$(CONFIG_ARCH_OMAP4)              += $(clock-common)
  obj-$(CONFIG_ARCH_OMAP4)              += dpll3xxx.o dpll44xx.o
@@@ -226,7 -223,6 +226,7 @@@ obj-$(CONFIG_SOC_AM33XX)           += omap_hwmod
  obj-$(CONFIG_SOC_AM43XX)              += omap_hwmod_43xx_data.o
  obj-$(CONFIG_SOC_AM43XX)              += omap_hwmod_33xx_43xx_interconnect_data.o
  obj-$(CONFIG_SOC_AM43XX)              += omap_hwmod_33xx_43xx_ipblock_data.o
 +obj-$(CONFIG_SOC_TI81XX)              += omap_hwmod_81xx_data.o
  obj-$(CONFIG_ARCH_OMAP4)              += omap_hwmod_44xx_data.o
  obj-$(CONFIG_SOC_OMAP5)                       += omap_hwmod_54xx_data.o
  obj-$(CONFIG_SOC_DRA7XX)              += omap_hwmod_7xx_data.o
@@@ -254,8 -250,13 +254,8 @@@ obj-$(CONFIG_MACH_NOKIA_RX51)             += board
  obj-$(CONFIG_MACH_NOKIA_RX51)         += board-rx51-peripherals.o
  obj-$(CONFIG_MACH_NOKIA_RX51)         += board-rx51-video.o
  obj-$(CONFIG_MACH_CM_T35)             += board-cm-t35.o
 -obj-$(CONFIG_MACH_CM_T3517)           += board-cm-t3517.o
  obj-$(CONFIG_MACH_TOUCHBOOK)          += board-omap3touchbook.o
  
 -obj-$(CONFIG_MACH_OMAP3517EVM)                += board-am3517evm.o
 -
 -obj-$(CONFIG_MACH_CRANEBOARD)         += board-am3517crane.o
 -
  obj-$(CONFIG_MACH_SBC3530)            += board-omap3stalker.o
  
  # Platform specific device init code
@@@ -285,4 -286,7 +285,4 @@@ ifneq ($(CONFIG_HWSPINLOCK_OMAP),
  obj-y                                 += hwspinlock.o
  endif
  
 -emac-$(CONFIG_TI_DAVINCI_EMAC)                := am35xx-emac.o
 -obj-y                                 += $(emac-m) $(emac-y)
 -
  obj-y                                 += common-board-devices.o twl-common.o dss-common.o
index 4ae4ccebced285e0598282028a3ad909fe3ed26c,d9c128e6a73f5b9a59520adafd5f382a34d2e30d..6124db5c37aebf5d3092b66c355c326bdf6815f9
@@@ -23,7 -23,6 +23,6 @@@
  #include <linux/clk-provider.h>
  #include <linux/io.h>
  #include <linux/bitops.h>
- #include <linux/clk-private.h>
  #include <asm/cpu.h>
  
  #include <trace/events/power.h>
@@@ -620,9 -619,6 +619,9 @@@ void omap2_clk_enable_init_clocks(cons
  
        for (i = 0; i < num_clocks; i++) {
                init_clk = clk_get(NULL, clk_names[i]);
 +              if (WARN(IS_ERR(init_clk), "could not find init clock %s\n",
 +                              clk_names[i]))
 +                      continue;
                clk_prepare_enable(init_clk);
        }
  }
@@@ -632,21 -628,6 +631,6 @@@ const struct clk_hw_omap_ops clkhwops_w
        .find_companion = omap2_clk_dflt_find_companion,
  };
  
- /**
-  * omap_clocks_register - register an array of omap_clk
-  * @ocs: pointer to an array of omap_clk to register
-  */
- void __init omap_clocks_register(struct omap_clk oclks[], int cnt)
- {
-       struct omap_clk *c;
-       for (c = oclks; c < oclks + cnt; c++) {
-               clkdev_add(&c->lk);
-               if (!__clk_init(NULL, c->lk.clk))
-                       omap2_init_clk_hw_omap_clocks(c->lk.clk);
-       }
- }
  /**
   * omap2_clk_switch_mpurate_at_boot - switch ARM MPU rate by boot-time argument
   * @mpurate_ck_name: clk name of the clock to change rate
index 1cf9dd85248abbe6511ac8c59133f9f290327de7,6a10ce3747a06b16d90b2ee41accde6ed759b2b8..a56742f96000a64eb125010903304fb0d7e37414
@@@ -40,23 -40,29 +40,29 @@@ struct omap_clk 
  struct clockdomain;
  
  #define DEFINE_STRUCT_CLK(_name, _parent_array_name, _clkops_name)    \
-       static struct clk _name = {                             \
+       static struct clk_core _name##_core = {                 \
                .name = #_name,                                 \
                .hw = &_name##_hw.hw,                           \
                .parent_names = _parent_array_name,             \
                .num_parents = ARRAY_SIZE(_parent_array_name),  \
                .ops = &_clkops_name,                           \
+       };                                                      \
+       static struct clk _name = {                             \
+               .core = &_name##_core,                          \
        };
  
  #define DEFINE_STRUCT_CLK_FLAGS(_name, _parent_array_name,    \
                                _clkops_name, _flags)           \
-       static struct clk _name = {                             \
+       static struct clk_core _name##_core = {                 \
                .name = #_name,                                 \
                .hw = &_name##_hw.hw,                           \
                .parent_names = _parent_array_name,             \
                .num_parents = ARRAY_SIZE(_parent_array_name),  \
                .ops = &_clkops_name,                           \
                .flags = _flags,                                \
+       };                                                      \
+       static struct clk _name = {                             \
+               .core = &_name##_core,                          \
        };
  
  #define DEFINE_STRUCT_CLK_HW_OMAP(_name, _clkdm_name)         \
@@@ -177,6 -183,7 +183,6 @@@ struct clksel 
  u32 omap3_dpll_autoidle_read(struct clk_hw_omap *clk);
  void omap3_dpll_allow_idle(struct clk_hw_omap *clk);
  void omap3_dpll_deny_idle(struct clk_hw_omap *clk);
 -int omap4_dpllmx_gatectrl_read(struct clk_hw_omap *clk);
  void omap4_dpllmx_allow_gatectrl(struct clk_hw_omap *clk);
  void omap4_dpllmx_deny_gatectrl(struct clk_hw_omap *clk);
  
@@@ -238,7 -245,6 +244,6 @@@ struct ti_clk_features 
  extern struct ti_clk_features ti_clk_features;
  
  extern const struct clkops clkops_omap2_dflt_wait;
- extern const struct clkops clkops_dummy;
  extern const struct clkops clkops_omap2_dflt;
  
  extern struct clk_functions omap2_clk_functions;
@@@ -247,7 -253,6 +252,6 @@@ extern const struct clksel_rate gpt_32k
  extern const struct clksel_rate gpt_sys_rates[];
  extern const struct clksel_rate gfx_l3_rates[];
  extern const struct clksel_rate dsp_ick_rates[];
- extern struct clk dummy_ck;
  
  extern const struct clk_hw_omap_ops clkhwops_iclk_wait;
  extern const struct clk_hw_omap_ops clkhwops_wait;
@@@ -272,7 -277,5 +276,5 @@@ extern void __iomem *clk_memmaps[]
  extern int omap2_clkops_enable_clkdm(struct clk_hw *hw);
  extern void omap2_clkops_disable_clkdm(struct clk_hw *hw);
  
- extern void omap_clocks_register(struct omap_clk *oclks, int cnt);
  void __init ti_clk_init_features(void);
  #endif
index fc712240e5fd9d5173daca2df199d46e3ae521d9,acacb900a58b5df58a0828c81a07f08e17baee0c..f231be05b9a638de8e52cfe03d78765433815764
  /* Static rate multiplier for OMAP4 REGM4XEN clocks */
  #define OMAP4430_REGM4XEN_MULT                                4
  
 -/* Supported only on OMAP4 */
 -int omap4_dpllmx_gatectrl_read(struct clk_hw_omap *clk)
 -{
 -      u32 v;
 -      u32 mask;
 -
 -      if (!clk || !clk->clksel_reg)
 -              return -EINVAL;
 -
 -      mask = clk->flags & CLOCK_CLKOUTX2 ?
 -                      OMAP4430_DPLL_CLKOUTX2_GATE_CTRL_MASK :
 -                      OMAP4430_DPLL_CLKOUT_GATE_CTRL_MASK;
 -
 -      v = omap2_clk_readl(clk, clk->clksel_reg);
 -      v &= mask;
 -      v >>= __ffs(mask);
 -
 -      return v;
 -}
 -
  void omap4_dpllmx_allow_gatectrl(struct clk_hw_omap *clk)
  {
        u32 v;
@@@ -202,6 -222,8 +202,8 @@@ out
   * in failure.
   */
  long omap4_dpll_regm4xen_determine_rate(struct clk_hw *hw, unsigned long rate,
+                                       unsigned long min_rate,
+                                       unsigned long max_rate,
                                        unsigned long *best_parent_rate,
                                        struct clk_hw **best_parent_clk)
  {
diff --combined arch/arm/mach-omap2/io.c
index e60780f0537492fb570e646e9bc4897101cab022,25ea1b176e331545f4d65c79a841f0a721e71247..c4871c55bd8b641544a86a281121cad4c9219e42
@@@ -461,7 -461,17 +461,17 @@@ void __init omap3_init_early(void
        omap3xxx_clockdomains_init();
        omap3xxx_hwmod_init();
        omap_hwmod_init_postsetup();
-       omap_clk_soc_init = omap3xxx_clk_init;
+       if (!of_have_populated_dt()) {
+               omap3_prcm_legacy_iomaps_init();
+               if (soc_is_am35xx())
+                       omap_clk_soc_init = am35xx_clk_legacy_init;
+               else if (cpu_is_omap3630())
+                       omap_clk_soc_init = omap36xx_clk_legacy_init;
+               else if (omap_rev() == OMAP3430_REV_ES1_0)
+                       omap_clk_soc_init = omap3430es1_clk_legacy_init;
+               else
+                       omap_clk_soc_init = omap3430_clk_legacy_init;
+       }
  }
  
  void __init omap3430_init_early(void)
@@@ -492,6 -502,25 +502,6 @@@ void __init am35xx_init_early(void
                omap_clk_soc_init = am35xx_dt_clk_init;
  }
  
 -void __init ti81xx_init_early(void)
 -{
 -      omap2_set_globals_tap(OMAP343X_CLASS,
 -                            OMAP2_L4_IO_ADDRESS(TI81XX_TAP_BASE));
 -      omap2_set_globals_control(OMAP2_L4_IO_ADDRESS(TI81XX_CTRL_BASE),
 -                                NULL);
 -      omap2_set_globals_prm(OMAP2_L4_IO_ADDRESS(TI81XX_PRCM_BASE));
 -      omap2_set_globals_cm(OMAP2_L4_IO_ADDRESS(TI81XX_PRCM_BASE), NULL);
 -      omap3xxx_check_revision();
 -      ti81xx_check_features();
 -      omap3xxx_voltagedomains_init();
 -      omap3xxx_powerdomains_init();
 -      omap3xxx_clockdomains_init();
 -      omap3xxx_hwmod_init();
 -      omap_hwmod_init_postsetup();
 -      if (of_have_populated_dt())
 -              omap_clk_soc_init = ti81xx_dt_clk_init;
 -}
 -
  void __init omap3_init_late(void)
  {
        omap_common_late_init();
@@@ -530,54 -559,11 +540,54 @@@ void __init am35xx_init_late(void
  void __init ti81xx_init_late(void)
  {
        omap_common_late_init();
 -      omap3_pm_init();
        omap2_clk_enable_autoidle_all();
  }
  #endif
  
 +#ifdef CONFIG_SOC_TI81XX
 +void __init ti814x_init_early(void)
 +{
 +      omap2_set_globals_tap(TI814X_CLASS,
 +                            OMAP2_L4_IO_ADDRESS(TI81XX_TAP_BASE));
 +      omap2_set_globals_control(OMAP2_L4_IO_ADDRESS(TI81XX_CTRL_BASE),
 +                                NULL);
 +      omap2_set_globals_prm(OMAP2_L4_IO_ADDRESS(TI81XX_PRCM_BASE));
 +      omap2_set_globals_cm(OMAP2_L4_IO_ADDRESS(TI81XX_PRCM_BASE), NULL);
 +      omap3xxx_check_revision();
 +      ti81xx_check_features();
 +      am33xx_prm_init();
 +      am33xx_cm_init();
 +      omap3xxx_voltagedomains_init();
 +      omap3xxx_powerdomains_init();
 +      ti81xx_clockdomains_init();
 +      ti81xx_hwmod_init();
 +      omap_hwmod_init_postsetup();
 +      if (of_have_populated_dt())
 +              omap_clk_soc_init = ti81xx_dt_clk_init;
 +}
 +
 +void __init ti816x_init_early(void)
 +{
 +      omap2_set_globals_tap(TI816X_CLASS,
 +                            OMAP2_L4_IO_ADDRESS(TI81XX_TAP_BASE));
 +      omap2_set_globals_control(OMAP2_L4_IO_ADDRESS(TI81XX_CTRL_BASE),
 +                                NULL);
 +      omap2_set_globals_prm(OMAP2_L4_IO_ADDRESS(TI81XX_PRCM_BASE));
 +      omap2_set_globals_cm(OMAP2_L4_IO_ADDRESS(TI81XX_PRCM_BASE), NULL);
 +      omap3xxx_check_revision();
 +      ti81xx_check_features();
 +      am33xx_prm_init();
 +      am33xx_cm_init();
 +      omap3xxx_voltagedomains_init();
 +      omap3xxx_powerdomains_init();
 +      ti81xx_clockdomains_init();
 +      ti81xx_hwmod_init();
 +      omap_hwmod_init_postsetup();
 +      if (of_have_populated_dt())
 +              omap_clk_soc_init = ti81xx_dt_clk_init;
 +}
 +#endif
 +
  #ifdef CONFIG_SOC_AM33XX
  void __init am33xx_init_early(void)
  {
@@@ -753,15 -739,17 +763,17 @@@ int __init omap_clk_init(void
  
        ti_clk_init_features();
  
-       ret = of_prcm_init();
-       if (ret)
-               return ret;
+       if (of_have_populated_dt()) {
+               ret = of_prcm_init();
+               if (ret)
+                       return ret;
  
-       of_clk_init(NULL);
+               of_clk_init(NULL);
  
-       ti_dt_clk_init_retry_clks();
+               ti_dt_clk_init_retry_clks();
  
-       ti_dt_clockdomains_setup();
+               ti_dt_clockdomains_setup();
+       }
  
        ret = omap_clk_soc_init();
  
index 264b5e29404d0eded3c9eca764384e8d93a5e563,07a9b8fb084864964117e0d20b8330a30430704d..bfaa7ba595cc832ec7783e759db4425c5e1e58c0
@@@ -35,6 -35,8 +35,8 @@@
  #include "prm44xx.h"
  #include "common.h"
  #include "clock.h"
+ #include "cm.h"
+ #include "control.h"
  
  /*
   * OMAP_PRCM_MAX_NR_PENDING_REG: maximum number of PRM_IRQ*_MPU regs
@@@ -581,10 -583,6 +583,10 @@@ static const struct of_device_id omap_p
        { .compatible = "ti,am3-scrm" },
        { .compatible = "ti,am4-prcm" },
        { .compatible = "ti,am4-scrm" },
 +      { .compatible = "ti,dm814-prcm" },
 +      { .compatible = "ti,dm814-scrm" },
 +      { .compatible = "ti,dm816-prcm" },
 +      { .compatible = "ti,dm816-scrm" },
        { .compatible = "ti,omap2-prcm" },
        { .compatible = "ti,omap2-scrm" },
        { .compatible = "ti,omap3-prm" },
@@@ -641,6 -639,15 +643,15 @@@ int __init of_prcm_init(void
        return 0;
  }
  
+ void __init omap3_prcm_legacy_iomaps_init(void)
+ {
+       ti_clk_ll_ops = &omap_clk_ll_ops;
+       clk_memmaps[TI_CLKM_CM] = cm_base + OMAP3430_IVA2_MOD;
+       clk_memmaps[TI_CLKM_PRM] = prm_base + OMAP3430_IVA2_MOD;
+       clk_memmaps[TI_CLKM_SCRM] = omap_ctrl_base_get();
+ }
  static int __init prm_late_init(void)
  {
        if (prm_ll_data->late_init)
index 51866f17068457038503ff14520ef9a67e3a0d7d,cce62e934e0c421718c05c840cb52f9046d27435..ca7957b09a3cc13ad6882006468a7e3431e7a75f
@@@ -1,12 -1,13 +1,12 @@@
  CONFIG_PPC_85xx=y
  CONFIG_SMP=y
  CONFIG_NR_CPUS=8
 -CONFIG_EXPERIMENTAL=y
  CONFIG_SYSVIPC=y
  CONFIG_POSIX_MQUEUE=y
 -CONFIG_BSD_PROCESS_ACCT=y
  CONFIG_AUDIT=y
  CONFIG_NO_HZ=y
  CONFIG_HIGH_RES_TIMERS=y
 +CONFIG_BSD_PROCESS_ACCT=y
  CONFIG_IKCONFIG=y
  CONFIG_IKCONFIG_PROC=y
  CONFIG_LOG_BUF_SHIFT=14
@@@ -56,6 -57,7 +56,6 @@@ CONFIG_NET_IPIP=
  CONFIG_IP_MROUTE=y
  CONFIG_IP_PIMSM_V1=y
  CONFIG_IP_PIMSM_V2=y
 -CONFIG_ARPD=y
  CONFIG_INET_AH=y
  CONFIG_INET_ESP=y
  CONFIG_INET_IPCOMP=y
@@@ -67,15 -69,17 +67,15 @@@ CONFIG_DEVTMPFS=
  CONFIG_DEVTMPFS_MOUNT=y
  CONFIG_MTD=y
  CONFIG_MTD_CMDLINE_PARTS=y
 -CONFIG_MTD_CHAR=y
  CONFIG_MTD_BLOCK=y
  CONFIG_MTD_CFI=y
  CONFIG_MTD_CFI_INTELEXT=y
  CONFIG_MTD_CFI_AMDSTD=y
  CONFIG_MTD_PHYSMAP_OF=y
 -CONFIG_MTD_M25P80=y
  CONFIG_MTD_NAND=y
  CONFIG_MTD_NAND_FSL_ELBC=y
  CONFIG_MTD_NAND_FSL_IFC=y
 -CONFIG_PROC_DEVICETREE=y
 +CONFIG_MTD_SPI_NOR=y
  CONFIG_BLK_DEV_LOOP=y
  CONFIG_BLK_DEV_RAM=y
  CONFIG_BLK_DEV_RAM_SIZE=131072
@@@ -83,6 -87,7 +83,6 @@@ CONFIG_BLK_DEV_SD=
  CONFIG_CHR_DEV_ST=y
  CONFIG_BLK_DEV_SR=y
  CONFIG_CHR_DEV_SG=y
 -CONFIG_SCSI_MULTI_LUN=y
  CONFIG_SCSI_LOGGING=y
  CONFIG_SCSI_SYM53C8XX_2=y
  CONFIG_ATA=y
@@@ -93,11 -98,10 +93,11 @@@ CONFIG_SATA_SIL=
  CONFIG_PATA_SIL680=y
  CONFIG_NETDEVICES=y
  CONFIG_FSL_PQ_MDIO=y
 +CONFIG_FSL_XGMAC_MDIO=y
  CONFIG_E1000=y
  CONFIG_E1000E=y
 -CONFIG_VITESSE_PHY=y
  CONFIG_AT803X_PHY=y
 +CONFIG_VITESSE_PHY=y
  CONFIG_FIXED_PHY=y
  # CONFIG_INPUT_MOUSEDEV is not set
  # CONFIG_INPUT_KEYBOARD is not set
@@@ -119,6 -123,7 +119,6 @@@ CONFIG_SPI_GPIO=
  CONFIG_SPI_FSL_SPI=y
  CONFIG_SPI_FSL_ESPI=y
  # CONFIG_HWMON is not set
 -CONFIG_VIDEO_OUTPUT_CONTROL=y
  CONFIG_USB_HID=m
  CONFIG_USB=y
  CONFIG_USB_MON=y
@@@ -138,10 -143,11 +138,11 @@@ CONFIG_RTC_DRV_DS1307=
  CONFIG_RTC_DRV_DS1374=y
  CONFIG_RTC_DRV_DS3232=y
  CONFIG_UIO=y
 -CONFIG_STAGING=y
 -CONFIG_MEMORY=y
  CONFIG_VIRT_DRIVERS=y
  CONFIG_FSL_HV_MANAGER=y
 +CONFIG_STAGING=y
 +CONFIG_FSL_CORENET_CF=y
+ CONFIG_CLK_QORIQ=y
  CONFIG_EXT2_FS=y
  CONFIG_EXT3_FS=y
  # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
@@@ -165,15 -171,17 +166,15 @@@ CONFIG_NLS_CODEPAGE_437=
  CONFIG_NLS_CODEPAGE_850=y
  CONFIG_NLS_ISO8859_1=y
  CONFIG_NLS_UTF8=m
 +CONFIG_DEBUG_INFO=y
  CONFIG_MAGIC_SYSRQ=y
  CONFIG_DEBUG_SHIRQ=y
  CONFIG_DETECT_HUNG_TASK=y
 -CONFIG_DEBUG_INFO=y
  CONFIG_RCU_TRACE=y
  CONFIG_CRYPTO_NULL=y
  CONFIG_CRYPTO_PCBC=m
  CONFIG_CRYPTO_MD4=y
  CONFIG_CRYPTO_SHA256=y
  CONFIG_CRYPTO_SHA512=y
 -CONFIG_CRYPTO_AES=y
  # CONFIG_CRYPTO_ANSI_CPRNG is not set
  CONFIG_CRYPTO_DEV_FSL_CAAM=y
 -CONFIG_FSL_CORENET_CF=y
index d6c0c819895288c39bd826085e7fadb6793b360a,c9e80579d9d105ac8324c55a4aa68a955d26e2f7..04737aaa8b6b8ead5bfc2574fabe48afd78c872c
@@@ -69,7 -69,6 +69,7 @@@ CONFIG_MTD_PHYSMAP_OF=
  CONFIG_MTD_NAND=y
  CONFIG_MTD_NAND_FSL_ELBC=y
  CONFIG_MTD_NAND_FSL_IFC=y
 +CONFIG_MTD_SPI_NOR=y
  CONFIG_MTD_UBI=y
  CONFIG_BLK_DEV_LOOP=y
  CONFIG_BLK_DEV_RAM=y
@@@ -80,11 -79,7 +80,11 @@@ CONFIG_SATA_FSL=
  CONFIG_SATA_SIL24=y
  CONFIG_NETDEVICES=y
  CONFIG_DUMMY=y
 +CONFIG_FSL_PQ_MDIO=y
 +CONFIG_FSL_XGMAC_MDIO=y
  CONFIG_E1000E=y
 +CONFIG_VITESSE_PHY=y
 +CONFIG_FIXED_PHY=y
  CONFIG_INPUT_FF_MEMLESS=m
  # CONFIG_INPUT_MOUSEDEV is not set
  # CONFIG_INPUT_KEYBOARD is not set
@@@ -122,7 -117,9 +122,8 @@@ CONFIG_DMADEVICES=
  CONFIG_FSL_DMA=y
  CONFIG_VIRT_DRIVERS=y
  CONFIG_FSL_HV_MANAGER=y
+ CONFIG_CLK_QORIQ=y
  CONFIG_FSL_CORENET_CF=y
 -CONFIG_MEMORY=y
  CONFIG_EXT2_FS=y
  CONFIG_EXT3_FS=y
  CONFIG_ISO9660_FS=m
index 7316dd15278a35f60b710d0a348bc0d9328830fb,df9fa05b5fd3123cb9c3b4a73205511f274d7ce8..2d7b33fab953283cf391679b1e316e81f53852f9
@@@ -54,6 -54,7 +54,7 @@@
  #include <linux/irq.h>
  #include <linux/delay.h>
  #include <linux/irq_work.h>
+ #include <linux/clk-provider.h>
  #include <asm/trace.h>
  
  #include <asm/io.h>
@@@ -621,38 -622,6 +622,38 @@@ unsigned long long sched_clock(void
        return mulhdu(get_tb() - boot_tb, tb_to_ns_scale) << tb_to_ns_shift;
  }
  
 +
 +#ifdef CONFIG_PPC_PSERIES
 +
 +/*
 + * Running clock - attempts to give a view of time passing for a virtualised
 + * kernels.
 + * Uses the VTB register if available otherwise a next best guess.
 + */
 +unsigned long long running_clock(void)
 +{
 +      /*
 +       * Don't read the VTB as a host since KVM does not switch in host
 +       * timebase into the VTB when it takes a guest off the CPU, reading the
 +       * VTB would result in reading 'last switched out' guest VTB.
 +       *
 +       * Host kernels are often compiled with CONFIG_PPC_PSERIES checked, it
 +       * would be unsafe to rely only on the #ifdef above.
 +       */
 +      if (firmware_has_feature(FW_FEATURE_LPAR) &&
 +          cpu_has_feature(CPU_FTR_ARCH_207S))
 +              return mulhdu(get_vtb() - boot_tb, tb_to_ns_scale) << tb_to_ns_shift;
 +
 +      /*
 +       * This is a next best approximation without a VTB.
 +       * On a host which is running bare metal there should never be any stolen
 +       * time and on a host which doesn't do any virtualisation TB *should* equal
 +       * VTB so it makes no difference anyway.
 +       */
 +      return local_clock() - cputime_to_nsecs(kcpustat_this_cpu->cpustat[CPUTIME_STEAL]);
 +}
 +#endif
 +
  static int __init get_freq(char *name, int cells, unsigned long *val)
  {
        struct device_node *cpu;
@@@ -975,6 -944,10 +976,10 @@@ void __init time_init(void
  
        init_decrementer_clockevent();
        tick_setup_hrtimer_broadcast();
+ #ifdef CONFIG_COMMON_CLK
+       of_clk_init(NULL);
+ #endif
  }
  
  
diff --combined drivers/clk/Kconfig
index 91f86131bb7aa62b0c4632e2defa1f8b2f4e6abc,1c0832d9475a7a1dfb62e05da195505ec1371d8c..0b474a04730fe4d2c588cb1a3a1818dbff61f995
@@@ -13,7 -13,6 +13,7 @@@ config COMMON_CL
        bool
        select HAVE_CLK_PREPARE
        select CLKDEV_LOOKUP
 +      select SRCU
        ---help---
          The common clock framework is a single definition of struct
          clk, useful across many platforms, as well as an
@@@ -102,12 -101,12 +102,12 @@@ config COMMON_CLK_AXI_CLKGE
          Support for the Analog Devices axi-clkgen pcore clock generator for Xilinx
          FPGAs. It is commonly used in Analog Devices' reference designs.
  
- config CLK_PPC_CORENET
-       bool "Clock driver for PowerPC corenet platforms"
-       depends on PPC_E500MC && OF
+ config CLK_QORIQ
+       bool "Clock driver for Freescale QorIQ platforms"
+       depends on (PPC_E500MC || ARM) && OF
        ---help---
-         This adds the clock driver support for Freescale PowerPC corenet
-         platforms using common clock framework.
+         This adds the clock driver support for Freescale QorIQ platforms
+         using common clock framework.
  
  config COMMON_CLK_XGENE
        bool "Clock driver for APM XGene SoC"
@@@ -135,6 -134,14 +135,14 @@@ config COMMON_CLK_PX
        ---help---
          Sypport for the Marvell PXA SoC.
  
+ config COMMON_CLK_CDCE706
+       tristate "Clock driver for TI CDCE706 clock synthesizer"
+       depends on I2C
+       select REGMAP_I2C
+       select RATIONAL
+       ---help---
+         This driver supports TI CDCE706 programmable 3-PLL clock synthesizer.
  source "drivers/clk/qcom/Kconfig"
  
  endmenu
diff --combined drivers/clk/clk.c
index 642cf37124d3780024d1739bf9298aa788c336e2,a27f14116cc91b2a7b78faf7d177efb1709092e9..eb0152961d3c60652af108246e9d10be9d13a371
@@@ -9,7 -9,7 +9,7 @@@
   * Standard functionality for the common clock API.  See Documentation/clk.txt
   */
  
- #include <linux/clk-private.h>
+ #include <linux/clk-provider.h>
  #include <linux/clk/clk-conf.h>
  #include <linux/module.h>
  #include <linux/mutex.h>
@@@ -37,6 -37,55 +37,55 @@@ static HLIST_HEAD(clk_root_list)
  static HLIST_HEAD(clk_orphan_list);
  static LIST_HEAD(clk_notifier_list);
  
+ static long clk_core_get_accuracy(struct clk_core *clk);
+ static unsigned long clk_core_get_rate(struct clk_core *clk);
+ static int clk_core_get_phase(struct clk_core *clk);
+ static bool clk_core_is_prepared(struct clk_core *clk);
+ static bool clk_core_is_enabled(struct clk_core *clk);
+ static struct clk_core *clk_core_lookup(const char *name);
+ /***    private data structures    ***/
+ struct clk_core {
+       const char              *name;
+       const struct clk_ops    *ops;
+       struct clk_hw           *hw;
+       struct module           *owner;
+       struct clk_core         *parent;
+       const char              **parent_names;
+       struct clk_core         **parents;
+       u8                      num_parents;
+       u8                      new_parent_index;
+       unsigned long           rate;
+       unsigned long           req_rate;
+       unsigned long           new_rate;
+       struct clk_core         *new_parent;
+       struct clk_core         *new_child;
+       unsigned long           flags;
+       unsigned int            enable_count;
+       unsigned int            prepare_count;
+       unsigned long           accuracy;
+       int                     phase;
+       struct hlist_head       children;
+       struct hlist_node       child_node;
+       struct hlist_node       debug_node;
+       struct hlist_head       clks;
+       unsigned int            notifier_count;
+ #ifdef CONFIG_DEBUG_FS
+       struct dentry           *dentry;
+ #endif
+       struct kref             ref;
+ };
+ struct clk {
+       struct clk_core *core;
+       const char *dev_id;
+       const char *con_id;
+       unsigned long min_rate;
+       unsigned long max_rate;
+       struct hlist_node child_node;
+ };
  /***           locking             ***/
  static void clk_prepare_lock(void)
  {
@@@ -114,7 -163,8 +163,8 @@@ static struct hlist_head *orphan_list[
        NULL,
  };
  
- static void clk_summary_show_one(struct seq_file *s, struct clk *c, int level)
+ static void clk_summary_show_one(struct seq_file *s, struct clk_core *c,
+                                int level)
  {
        if (!c)
                return;
        seq_printf(s, "%*s%-*s %11d %12d %11lu %10lu %-3d\n",
                   level * 3 + 1, "",
                   30 - level * 3, c->name,
-                  c->enable_count, c->prepare_count, clk_get_rate(c),
-                  clk_get_accuracy(c), clk_get_phase(c));
+                  c->enable_count, c->prepare_count, clk_core_get_rate(c),
+                  clk_core_get_accuracy(c), clk_core_get_phase(c));
  }
  
- static void clk_summary_show_subtree(struct seq_file *s, struct clk *c,
+ static void clk_summary_show_subtree(struct seq_file *s, struct clk_core *c,
                                     int level)
  {
-       struct clk *child;
+       struct clk_core *child;
  
        if (!c)
                return;
  
  static int clk_summary_show(struct seq_file *s, void *data)
  {
-       struct clk *c;
+       struct clk_core *c;
        struct hlist_head **lists = (struct hlist_head **)s->private;
  
        seq_puts(s, "   clock                         enable_cnt  prepare_cnt        rate   accuracy   phase\n");
@@@ -172,7 -222,7 +222,7 @@@ static const struct file_operations clk
        .release        = single_release,
  };
  
- static void clk_dump_one(struct seq_file *s, struct clk *c, int level)
+ static void clk_dump_one(struct seq_file *s, struct clk_core *c, int level)
  {
        if (!c)
                return;
        seq_printf(s, "\"%s\": { ", c->name);
        seq_printf(s, "\"enable_count\": %d,", c->enable_count);
        seq_printf(s, "\"prepare_count\": %d,", c->prepare_count);
-       seq_printf(s, "\"rate\": %lu", clk_get_rate(c));
-       seq_printf(s, "\"accuracy\": %lu", clk_get_accuracy(c));
-       seq_printf(s, "\"phase\": %d", clk_get_phase(c));
+       seq_printf(s, "\"rate\": %lu", clk_core_get_rate(c));
+       seq_printf(s, "\"accuracy\": %lu", clk_core_get_accuracy(c));
+       seq_printf(s, "\"phase\": %d", clk_core_get_phase(c));
  }
  
- static void clk_dump_subtree(struct seq_file *s, struct clk *c, int level)
+ static void clk_dump_subtree(struct seq_file *s, struct clk_core *c, int level)
  {
-       struct clk *child;
+       struct clk_core *child;
  
        if (!c)
                return;
  
  static int clk_dump(struct seq_file *s, void *data)
  {
-       struct clk *c;
+       struct clk_core *c;
        bool first_node = true;
        struct hlist_head **lists = (struct hlist_head **)s->private;
  
@@@ -240,7 -290,7 +290,7 @@@ static const struct file_operations clk
        .release        = single_release,
  };
  
- static int clk_debug_create_one(struct clk *clk, struct dentry *pdentry)
+ static int clk_debug_create_one(struct clk_core *clk, struct dentry *pdentry)
  {
        struct dentry *d;
        int ret = -ENOMEM;
@@@ -315,7 -365,7 +365,7 @@@ out
   * initialized.  Otherwise it bails out early since the debugfs clk tree
   * will be created lazily by clk_debug_init as part of a late_initcall.
   */
- static int clk_debug_register(struct clk *clk)
+ static int clk_debug_register(struct clk_core *clk)
  {
        int ret = 0;
  
@@@ -340,16 -390,12 +390,12 @@@ unlock
   * debugfs clk tree if clk->dentry points to debugfs created by
   * clk_debug_register in __clk_init.
   */
- static void clk_debug_unregister(struct clk *clk)
+ static void clk_debug_unregister(struct clk_core *clk)
  {
        mutex_lock(&clk_debug_lock);
-       if (!clk->dentry)
-               goto out;
        hlist_del_init(&clk->debug_node);
        debugfs_remove_recursive(clk->dentry);
        clk->dentry = NULL;
- out:
        mutex_unlock(&clk_debug_lock);
  }
  
@@@ -358,8 -404,9 +404,9 @@@ struct dentry *clk_debugfs_add_file(str
  {
        struct dentry *d = NULL;
  
-       if (hw->clk->dentry)
-               d = debugfs_create_file(name, mode, hw->clk->dentry, data, fops);
+       if (hw->core->dentry)
+               d = debugfs_create_file(name, mode, hw->core->dentry, data,
+                                       fops);
  
        return d;
  }
@@@ -379,7 -426,7 +426,7 @@@ EXPORT_SYMBOL_GPL(clk_debugfs_add_file)
   */
  static int __init clk_debug_init(void)
  {
-       struct clk *clk;
+       struct clk_core *clk;
        struct dentry *d;
  
        rootdir = debugfs_create_dir("clk", NULL);
  }
  late_initcall(clk_debug_init);
  #else
- static inline int clk_debug_register(struct clk *clk) { return 0; }
- static inline void clk_debug_reparent(struct clk *clk, struct clk *new_parent)
+ static inline int clk_debug_register(struct clk_core *clk) { return 0; }
+ static inline void clk_debug_reparent(struct clk_core *clk,
+                                     struct clk_core *new_parent)
  {
  }
- static inline void clk_debug_unregister(struct clk *clk)
+ static inline void clk_debug_unregister(struct clk_core *clk)
  {
  }
  #endif
  
  /* caller must hold prepare_lock */
- static void clk_unprepare_unused_subtree(struct clk *clk)
+ static void clk_unprepare_unused_subtree(struct clk_core *clk)
  {
-       struct clk *child;
-       if (!clk)
-               return;
+       struct clk_core *child;
  
        hlist_for_each_entry(child, &clk->children, child_node)
                clk_unprepare_unused_subtree(child);
        if (clk->flags & CLK_IGNORE_UNUSED)
                return;
  
-       if (__clk_is_prepared(clk)) {
+       if (clk_core_is_prepared(clk)) {
                if (clk->ops->unprepare_unused)
                        clk->ops->unprepare_unused(clk->hw);
                else if (clk->ops->unprepare)
  }
  
  /* caller must hold prepare_lock */
- static void clk_disable_unused_subtree(struct clk *clk)
+ static void clk_disable_unused_subtree(struct clk_core *clk)
  {
-       struct clk *child;
+       struct clk_core *child;
        unsigned long flags;
  
-       if (!clk)
-               goto out;
        hlist_for_each_entry(child, &clk->children, child_node)
                clk_disable_unused_subtree(child);
  
         * sequence.  call .disable_unused if available, otherwise fall
         * back to .disable
         */
-       if (__clk_is_enabled(clk)) {
+       if (clk_core_is_enabled(clk)) {
                if (clk->ops->disable_unused)
                        clk->ops->disable_unused(clk->hw);
                else if (clk->ops->disable)
  
  unlock_out:
        clk_enable_unlock(flags);
- out:
-       return;
  }
  
  static bool clk_ignore_unused;
@@@ -501,7 -540,7 +540,7 @@@ __setup("clk_ignore_unused", clk_ignore
  
  static int clk_disable_unused(void)
  {
-       struct clk *clk;
+       struct clk_core *clk;
  
        if (clk_ignore_unused) {
                pr_warn("clk: Not disabling unused clocks\n");
@@@ -532,48 -571,65 +571,65 @@@ late_initcall_sync(clk_disable_unused)
  
  const char *__clk_get_name(struct clk *clk)
  {
-       return !clk ? NULL : clk->name;
+       return !clk ? NULL : clk->core->name;
  }
  EXPORT_SYMBOL_GPL(__clk_get_name);
  
  struct clk_hw *__clk_get_hw(struct clk *clk)
  {
-       return !clk ? NULL : clk->hw;
+       return !clk ? NULL : clk->core->hw;
  }
  EXPORT_SYMBOL_GPL(__clk_get_hw);
  
  u8 __clk_get_num_parents(struct clk *clk)
  {
-       return !clk ? 0 : clk->num_parents;
+       return !clk ? 0 : clk->core->num_parents;
  }
  EXPORT_SYMBOL_GPL(__clk_get_num_parents);
  
  struct clk *__clk_get_parent(struct clk *clk)
  {
-       return !clk ? NULL : clk->parent;
+       if (!clk)
+               return NULL;
+       /* TODO: Create a per-user clk and change callers to call clk_put */
+       return !clk->core->parent ? NULL : clk->core->parent->hw->clk;
  }
  EXPORT_SYMBOL_GPL(__clk_get_parent);
  
- struct clk *clk_get_parent_by_index(struct clk *clk, u8 index)
+ static struct clk_core *clk_core_get_parent_by_index(struct clk_core *clk,
+                                                        u8 index)
  {
        if (!clk || index >= clk->num_parents)
                return NULL;
        else if (!clk->parents)
-               return __clk_lookup(clk->parent_names[index]);
+               return clk_core_lookup(clk->parent_names[index]);
        else if (!clk->parents[index])
                return clk->parents[index] =
-                       __clk_lookup(clk->parent_names[index]);
+                       clk_core_lookup(clk->parent_names[index]);
        else
                return clk->parents[index];
  }
+ struct clk *clk_get_parent_by_index(struct clk *clk, u8 index)
+ {
+       struct clk_core *parent;
+       if (!clk)
+               return NULL;
+       parent = clk_core_get_parent_by_index(clk->core, index);
+       return !parent ? NULL : parent->hw->clk;
+ }
  EXPORT_SYMBOL_GPL(clk_get_parent_by_index);
  
  unsigned int __clk_get_enable_count(struct clk *clk)
  {
-       return !clk ? 0 : clk->enable_count;
+       return !clk ? 0 : clk->core->enable_count;
  }
  
unsigned long __clk_get_rate(struct clk *clk)
static unsigned long clk_core_get_rate_nolock(struct clk_core *clk)
  {
        unsigned long ret;
  
  out:
        return ret;
  }
+ unsigned long __clk_get_rate(struct clk *clk)
+ {
+       if (!clk)
+               return 0;
+       return clk_core_get_rate_nolock(clk->core);
+ }
  EXPORT_SYMBOL_GPL(__clk_get_rate);
  
- static unsigned long __clk_get_accuracy(struct clk *clk)
+ static unsigned long __clk_get_accuracy(struct clk_core *clk)
  {
        if (!clk)
                return 0;
  
  unsigned long __clk_get_flags(struct clk *clk)
  {
-       return !clk ? 0 : clk->flags;
+       return !clk ? 0 : clk->core->flags;
  }
  EXPORT_SYMBOL_GPL(__clk_get_flags);
  
bool __clk_is_prepared(struct clk *clk)
static bool clk_core_is_prepared(struct clk_core *clk)
  {
        int ret;
  
@@@ -630,7 -694,15 +694,15 @@@ out
        return !!ret;
  }
  
- bool __clk_is_enabled(struct clk *clk)
+ bool __clk_is_prepared(struct clk *clk)
+ {
+       if (!clk)
+               return false;
+       return clk_core_is_prepared(clk->core);
+ }
+ static bool clk_core_is_enabled(struct clk_core *clk)
  {
        int ret;
  
  out:
        return !!ret;
  }
+ bool __clk_is_enabled(struct clk *clk)
+ {
+       if (!clk)
+               return false;
+       return clk_core_is_enabled(clk->core);
+ }
  EXPORT_SYMBOL_GPL(__clk_is_enabled);
  
- static struct clk *__clk_lookup_subtree(const char *name, struct clk *clk)
+ static struct clk_core *__clk_lookup_subtree(const char *name,
+                                            struct clk_core *clk)
  {
-       struct clk *child;
-       struct clk *ret;
+       struct clk_core *child;
+       struct clk_core *ret;
  
        if (!strcmp(clk->name, name))
                return clk;
        return NULL;
  }
  
- struct clk *__clk_lookup(const char *name)
+ static struct clk_core *clk_core_lookup(const char *name)
  {
-       struct clk *root_clk;
-       struct clk *ret;
+       struct clk_core *root_clk;
+       struct clk_core *ret;
  
        if (!name)
                return NULL;
        return NULL;
  }
  
- /*
-  * Helper for finding best parent to provide a given frequency. This can be used
-  * directly as a determine_rate callback (e.g. for a mux), or from a more
-  * complex clock that may combine a mux with other operations.
-  */
- long __clk_mux_determine_rate(struct clk_hw *hw, unsigned long rate,
-                             unsigned long *best_parent_rate,
-                             struct clk_hw **best_parent_p)
+ static bool mux_is_better_rate(unsigned long rate, unsigned long now,
+                          unsigned long best, unsigned long flags)
  {
-       struct clk *clk = hw->clk, *parent, *best_parent = NULL;
+       if (flags & CLK_MUX_ROUND_CLOSEST)
+               return abs(now - rate) < abs(best - rate);
+       return now <= rate && now > best;
+ }
+ static long
+ clk_mux_determine_rate_flags(struct clk_hw *hw, unsigned long rate,
+                            unsigned long min_rate,
+                            unsigned long max_rate,
+                            unsigned long *best_parent_rate,
+                            struct clk_hw **best_parent_p,
+                            unsigned long flags)
+ {
+       struct clk_core *core = hw->core, *parent, *best_parent = NULL;
        int i, num_parents;
        unsigned long parent_rate, best = 0;
  
        /* if NO_REPARENT flag set, pass through to current parent */
-       if (clk->flags & CLK_SET_RATE_NO_REPARENT) {
-               parent = clk->parent;
-               if (clk->flags & CLK_SET_RATE_PARENT)
-                       best = __clk_round_rate(parent, rate);
+       if (core->flags & CLK_SET_RATE_NO_REPARENT) {
+               parent = core->parent;
+               if (core->flags & CLK_SET_RATE_PARENT)
+                       best = __clk_determine_rate(parent ? parent->hw : NULL,
+                                                   rate, min_rate, max_rate);
                else if (parent)
-                       best = __clk_get_rate(parent);
+                       best = clk_core_get_rate_nolock(parent);
                else
-                       best = __clk_get_rate(clk);
+                       best = clk_core_get_rate_nolock(core);
                goto out;
        }
  
        /* find the parent that can provide the fastest rate <= rate */
-       num_parents = clk->num_parents;
+       num_parents = core->num_parents;
        for (i = 0; i < num_parents; i++) {
-               parent = clk_get_parent_by_index(clk, i);
+               parent = clk_core_get_parent_by_index(core, i);
                if (!parent)
                        continue;
-               if (clk->flags & CLK_SET_RATE_PARENT)
-                       parent_rate = __clk_round_rate(parent, rate);
+               if (core->flags & CLK_SET_RATE_PARENT)
+                       parent_rate = __clk_determine_rate(parent->hw, rate,
+                                                          min_rate,
+                                                          max_rate);
                else
-                       parent_rate = __clk_get_rate(parent);
-               if (parent_rate <= rate && parent_rate > best) {
+                       parent_rate = clk_core_get_rate_nolock(parent);
+               if (mux_is_better_rate(rate, parent_rate, best, flags)) {
                        best_parent = parent;
                        best = parent_rate;
                }
@@@ -742,11 -834,63 +834,63 @@@ out
  
        return best;
  }
+ struct clk *__clk_lookup(const char *name)
+ {
+       struct clk_core *core = clk_core_lookup(name);
+       return !core ? NULL : core->hw->clk;
+ }
+ static void clk_core_get_boundaries(struct clk_core *clk,
+                                   unsigned long *min_rate,
+                                   unsigned long *max_rate)
+ {
+       struct clk *clk_user;
+       *min_rate = 0;
+       *max_rate = ULONG_MAX;
+       hlist_for_each_entry(clk_user, &clk->clks, child_node)
+               *min_rate = max(*min_rate, clk_user->min_rate);
+       hlist_for_each_entry(clk_user, &clk->clks, child_node)
+               *max_rate = min(*max_rate, clk_user->max_rate);
+ }
+ /*
+  * Helper for finding best parent to provide a given frequency. This can be used
+  * directly as a determine_rate callback (e.g. for a mux), or from a more
+  * complex clock that may combine a mux with other operations.
+  */
+ long __clk_mux_determine_rate(struct clk_hw *hw, unsigned long rate,
+                             unsigned long min_rate,
+                             unsigned long max_rate,
+                             unsigned long *best_parent_rate,
+                             struct clk_hw **best_parent_p)
+ {
+       return clk_mux_determine_rate_flags(hw, rate, min_rate, max_rate,
+                                           best_parent_rate,
+                                           best_parent_p, 0);
+ }
  EXPORT_SYMBOL_GPL(__clk_mux_determine_rate);
  
+ long __clk_mux_determine_rate_closest(struct clk_hw *hw, unsigned long rate,
+                             unsigned long min_rate,
+                             unsigned long max_rate,
+                             unsigned long *best_parent_rate,
+                             struct clk_hw **best_parent_p)
+ {
+       return clk_mux_determine_rate_flags(hw, rate, min_rate, max_rate,
+                                           best_parent_rate,
+                                           best_parent_p,
+                                           CLK_MUX_ROUND_CLOSEST);
+ }
+ EXPORT_SYMBOL_GPL(__clk_mux_determine_rate_closest);
  /***        clk api        ***/
  
void __clk_unprepare(struct clk *clk)
static void clk_core_unprepare(struct clk_core *clk)
  {
        if (!clk)
                return;
        if (clk->ops->unprepare)
                clk->ops->unprepare(clk->hw);
  
-       __clk_unprepare(clk->parent);
+       clk_core_unprepare(clk->parent);
  }
  
  /**
@@@ -782,12 -926,12 +926,12 @@@ void clk_unprepare(struct clk *clk
                return;
  
        clk_prepare_lock();
-       __clk_unprepare(clk);
+       clk_core_unprepare(clk->core);
        clk_prepare_unlock();
  }
  EXPORT_SYMBOL_GPL(clk_unprepare);
  
int __clk_prepare(struct clk *clk)
static int clk_core_prepare(struct clk_core *clk)
  {
        int ret = 0;
  
                return 0;
  
        if (clk->prepare_count == 0) {
-               ret = __clk_prepare(clk->parent);
+               ret = clk_core_prepare(clk->parent);
                if (ret)
                        return ret;
  
                if (clk->ops->prepare) {
                        ret = clk->ops->prepare(clk->hw);
                        if (ret) {
-                               __clk_unprepare(clk->parent);
+                               clk_core_unprepare(clk->parent);
                                return ret;
                        }
                }
@@@ -829,15 -973,18 +973,18 @@@ int clk_prepare(struct clk *clk
  {
        int ret;
  
+       if (!clk)
+               return 0;
        clk_prepare_lock();
-       ret = __clk_prepare(clk);
+       ret = clk_core_prepare(clk->core);
        clk_prepare_unlock();
  
        return ret;
  }
  EXPORT_SYMBOL_GPL(clk_prepare);
  
- static void __clk_disable(struct clk *clk)
+ static void clk_core_disable(struct clk_core *clk)
  {
        if (!clk)
                return;
        if (clk->ops->disable)
                clk->ops->disable(clk->hw);
  
-       __clk_disable(clk->parent);
+       clk_core_disable(clk->parent);
+ }
+ static void __clk_disable(struct clk *clk)
+ {
+       if (!clk)
+               return;
+       clk_core_disable(clk->core);
  }
  
  /**
@@@ -879,7 -1034,7 +1034,7 @@@ void clk_disable(struct clk *clk
  }
  EXPORT_SYMBOL_GPL(clk_disable);
  
- static int __clk_enable(struct clk *clk)
+ static int clk_core_enable(struct clk_core *clk)
  {
        int ret = 0;
  
                return -ESHUTDOWN;
  
        if (clk->enable_count == 0) {
-               ret = __clk_enable(clk->parent);
+               ret = clk_core_enable(clk->parent);
  
                if (ret)
                        return ret;
                if (clk->ops->enable) {
                        ret = clk->ops->enable(clk->hw);
                        if (ret) {
-                               __clk_disable(clk->parent);
+                               clk_core_disable(clk->parent);
                                return ret;
                        }
                }
        return 0;
  }
  
+ static int __clk_enable(struct clk *clk)
+ {
+       if (!clk)
+               return 0;
+       return clk_core_enable(clk->core);
+ }
  /**
   * clk_enable - ungate a clock
   * @clk: the clk being ungated
@@@ -934,17 -1097,13 +1097,13 @@@ int clk_enable(struct clk *clk
  }
  EXPORT_SYMBOL_GPL(clk_enable);
  
- /**
-  * __clk_round_rate - round the given rate for a clk
-  * @clk: round the rate of this clock
-  * @rate: the rate which is to be rounded
-  *
-  * Caller must hold prepare_lock.  Useful for clk_ops such as .set_rate
-  */
- unsigned long __clk_round_rate(struct clk *clk, unsigned long rate)
+ static unsigned long clk_core_round_rate_nolock(struct clk_core *clk,
+                                               unsigned long rate,
+                                               unsigned long min_rate,
+                                               unsigned long max_rate)
  {
        unsigned long parent_rate = 0;
-       struct clk *parent;
+       struct clk_core *parent;
        struct clk_hw *parent_hw;
  
        if (!clk)
  
        if (clk->ops->determine_rate) {
                parent_hw = parent ? parent->hw : NULL;
-               return clk->ops->determine_rate(clk->hw, rate, &parent_rate,
-                                               &parent_hw);
+               return clk->ops->determine_rate(clk->hw, rate,
+                                               min_rate, max_rate,
+                                               &parent_rate, &parent_hw);
        } else if (clk->ops->round_rate)
                return clk->ops->round_rate(clk->hw, rate, &parent_rate);
        else if (clk->flags & CLK_SET_RATE_PARENT)
-               return __clk_round_rate(clk->parent, rate);
+               return clk_core_round_rate_nolock(clk->parent, rate, min_rate,
+                                                 max_rate);
        else
                return clk->rate;
  }
+ /**
+  * __clk_determine_rate - get the closest rate actually supported by a clock
+  * @hw: determine the rate of this clock
+  * @rate: target rate
+  * @min_rate: returned rate must be greater than this rate
+  * @max_rate: returned rate must be less than this rate
+  *
+  * Caller must hold prepare_lock.  Useful for clk_ops such as .set_rate and
+  * .determine_rate.
+  */
+ unsigned long __clk_determine_rate(struct clk_hw *hw,
+                                  unsigned long rate,
+                                  unsigned long min_rate,
+                                  unsigned long max_rate)
+ {
+       if (!hw)
+               return 0;
+       return clk_core_round_rate_nolock(hw->core, rate, min_rate, max_rate);
+ }
+ EXPORT_SYMBOL_GPL(__clk_determine_rate);
+ /**
+  * __clk_round_rate - round the given rate for a clk
+  * @clk: round the rate of this clock
+  * @rate: the rate which is to be rounded
+  *
+  * Caller must hold prepare_lock.  Useful for clk_ops such as .set_rate
+  */
+ unsigned long __clk_round_rate(struct clk *clk, unsigned long rate)
+ {
+       unsigned long min_rate;
+       unsigned long max_rate;
+       if (!clk)
+               return 0;
+       clk_core_get_boundaries(clk->core, &min_rate, &max_rate);
+       return clk_core_round_rate_nolock(clk->core, rate, min_rate, max_rate);
+ }
  EXPORT_SYMBOL_GPL(__clk_round_rate);
  
  /**
@@@ -980,6 -1183,9 +1183,9 @@@ long clk_round_rate(struct clk *clk, un
  {
        unsigned long ret;
  
+       if (!clk)
+               return 0;
        clk_prepare_lock();
        ret = __clk_round_rate(clk, rate);
        clk_prepare_unlock();
@@@ -1002,22 -1208,21 +1208,21 @@@ EXPORT_SYMBOL_GPL(clk_round_rate)
   * called if all went well, or NOTIFY_STOP or NOTIFY_BAD immediately if
   * a driver returns that.
   */
- static int __clk_notify(struct clk *clk, unsigned long msg,
+ static int __clk_notify(struct clk_core *clk, unsigned long msg,
                unsigned long old_rate, unsigned long new_rate)
  {
        struct clk_notifier *cn;
        struct clk_notifier_data cnd;
        int ret = NOTIFY_DONE;
  
-       cnd.clk = clk;
        cnd.old_rate = old_rate;
        cnd.new_rate = new_rate;
  
        list_for_each_entry(cn, &clk_notifier_list, node) {
-               if (cn->clk == clk) {
+               if (cn->clk->core == clk) {
+                       cnd.clk = cn->clk;
                        ret = srcu_notifier_call_chain(&cn->notifier_head, msg,
                                        &cnd);
-                       break;
                }
        }
  
   *
   * Caller must hold prepare_lock.
   */
- static void __clk_recalc_accuracies(struct clk *clk)
+ static void __clk_recalc_accuracies(struct clk_core *clk)
  {
        unsigned long parent_accuracy = 0;
-       struct clk *child;
+       struct clk_core *child;
  
        if (clk->parent)
                parent_accuracy = clk->parent->accuracy;
                __clk_recalc_accuracies(child);
  }
  
+ static long clk_core_get_accuracy(struct clk_core *clk)
+ {
+       unsigned long accuracy;
+       clk_prepare_lock();
+       if (clk && (clk->flags & CLK_GET_ACCURACY_NOCACHE))
+               __clk_recalc_accuracies(clk);
+       accuracy = __clk_get_accuracy(clk);
+       clk_prepare_unlock();
+       return accuracy;
+ }
  /**
   * clk_get_accuracy - return the accuracy of clk
   * @clk: the clk whose accuracy is being returned
   */
  long clk_get_accuracy(struct clk *clk)
  {
-       unsigned long accuracy;
-       clk_prepare_lock();
-       if (clk && (clk->flags & CLK_GET_ACCURACY_NOCACHE))
-               __clk_recalc_accuracies(clk);
-       accuracy = __clk_get_accuracy(clk);
-       clk_prepare_unlock();
+       if (!clk)
+               return 0;
  
-       return accuracy;
+       return clk_core_get_accuracy(clk->core);
  }
  EXPORT_SYMBOL_GPL(clk_get_accuracy);
  
- static unsigned long clk_recalc(struct clk *clk, unsigned long parent_rate)
+ static unsigned long clk_recalc(struct clk_core *clk,
+                               unsigned long parent_rate)
  {
        if (clk->ops->recalc_rate)
                return clk->ops->recalc_rate(clk->hw, parent_rate);
   *
   * Caller must hold prepare_lock.
   */
- static void __clk_recalc_rates(struct clk *clk, unsigned long msg)
+ static void __clk_recalc_rates(struct clk_core *clk, unsigned long msg)
  {
        unsigned long old_rate;
        unsigned long parent_rate = 0;
-       struct clk *child;
+       struct clk_core *child;
  
        old_rate = clk->rate;
  
                __clk_recalc_rates(child, msg);
  }
  
- /**
-  * clk_get_rate - return the rate of clk
-  * @clk: the clk whose rate is being returned
-  *
-  * Simply returns the cached rate of the clk, unless CLK_GET_RATE_NOCACHE flag
-  * is set, which means a recalc_rate will be issued.
-  * If clk is NULL then returns 0.
-  */
- unsigned long clk_get_rate(struct clk *clk)
+ static unsigned long clk_core_get_rate(struct clk_core *clk)
  {
        unsigned long rate;
  
        if (clk && (clk->flags & CLK_GET_RATE_NOCACHE))
                __clk_recalc_rates(clk, 0);
  
-       rate = __clk_get_rate(clk);
+       rate = clk_core_get_rate_nolock(clk);
        clk_prepare_unlock();
  
        return rate;
  }
+ EXPORT_SYMBOL_GPL(clk_core_get_rate);
+ /**
+  * clk_get_rate - return the rate of clk
+  * @clk: the clk whose rate is being returned
+  *
+  * Simply returns the cached rate of the clk, unless CLK_GET_RATE_NOCACHE flag
+  * is set, which means a recalc_rate will be issued.
+  * If clk is NULL then returns 0.
+  */
+ unsigned long clk_get_rate(struct clk *clk)
+ {
+       if (!clk)
+               return 0;
+       return clk_core_get_rate(clk->core);
+ }
  EXPORT_SYMBOL_GPL(clk_get_rate);
  
- static int clk_fetch_parent_index(struct clk *clk, struct clk *parent)
+ static int clk_fetch_parent_index(struct clk_core *clk,
+                                 struct clk_core *parent)
  {
        int i;
  
        /*
         * find index of new parent clock using cached parent ptrs,
         * or if not yet cached, use string name comparison and cache
-        * them now to avoid future calls to __clk_lookup.
+        * them now to avoid future calls to clk_core_lookup.
         */
        for (i = 0; i < clk->num_parents; i++) {
                if (clk->parents[i] == parent)
                        continue;
  
                if (!strcmp(clk->parent_names[i], parent->name)) {
-                       clk->parents[i] = __clk_lookup(parent->name);
+                       clk->parents[i] = clk_core_lookup(parent->name);
                        return i;
                }
        }
        return -EINVAL;
  }
  
- static void clk_reparent(struct clk *clk, struct clk *new_parent)
+ static void clk_reparent(struct clk_core *clk, struct clk_core *new_parent)
  {
        hlist_del(&clk->child_node);
  
        clk->parent = new_parent;
  }
  
- static struct clk *__clk_set_parent_before(struct clk *clk, struct clk *parent)
+ static struct clk_core *__clk_set_parent_before(struct clk_core *clk,
+                                          struct clk_core *parent)
  {
        unsigned long flags;
-       struct clk *old_parent = clk->parent;
+       struct clk_core *old_parent = clk->parent;
  
        /*
         * Migrate prepare state between parents and prevent race with
         * See also: Comment for clk_set_parent() below.
         */
        if (clk->prepare_count) {
-               __clk_prepare(parent);
-               clk_enable(parent);
-               clk_enable(clk);
+               clk_core_prepare(parent);
+               clk_core_enable(parent);
+               clk_core_enable(clk);
        }
  
        /* update the clk tree topology */
        return old_parent;
  }
  
- static void __clk_set_parent_after(struct clk *clk, struct clk *parent,
-               struct clk *old_parent)
+ static void __clk_set_parent_after(struct clk_core *core,
+                                  struct clk_core *parent,
+                                  struct clk_core *old_parent)
  {
        /*
         * Finish the migration of prepare state and undo the changes done
         * for preventing a race with clk_enable().
         */
-       if (clk->prepare_count) {
-               clk_disable(clk);
-               clk_disable(old_parent);
-               __clk_unprepare(old_parent);
+       if (core->prepare_count) {
+               clk_core_disable(core);
+               clk_core_disable(old_parent);
+               clk_core_unprepare(old_parent);
        }
  }
  
- static int __clk_set_parent(struct clk *clk, struct clk *parent, u8 p_index)
+ static int __clk_set_parent(struct clk_core *clk, struct clk_core *parent,
+                           u8 p_index)
  {
        unsigned long flags;
        int ret = 0;
-       struct clk *old_parent;
+       struct clk_core *old_parent;
  
        old_parent = __clk_set_parent_before(clk, parent);
  
                clk_enable_unlock(flags);
  
                if (clk->prepare_count) {
-                       clk_disable(clk);
-                       clk_disable(parent);
-                       __clk_unprepare(parent);
+                       clk_core_disable(clk);
+                       clk_core_disable(parent);
+                       clk_core_unprepare(parent);
                }
                return ret;
        }
   *
   * Caller must hold prepare_lock.
   */
- static int __clk_speculate_rates(struct clk *clk, unsigned long parent_rate)
+ static int __clk_speculate_rates(struct clk_core *clk,
+                                unsigned long parent_rate)
  {
-       struct clk *child;
+       struct clk_core *child;
        unsigned long new_rate;
        int ret = NOTIFY_DONE;
  
        return ret;
  }
  
- static void clk_calc_subtree(struct clk *clk, unsigned long new_rate,
-                            struct clk *new_parent, u8 p_index)
+ static void clk_calc_subtree(struct clk_core *clk, unsigned long new_rate,
+                            struct clk_core *new_parent, u8 p_index)
  {
-       struct clk *child;
+       struct clk_core *child;
  
        clk->new_rate = new_rate;
        clk->new_parent = new_parent;
   * calculate the new rates returning the topmost clock that has to be
   * changed.
   */
- static struct clk *clk_calc_new_rates(struct clk *clk, unsigned long rate)
+ static struct clk_core *clk_calc_new_rates(struct clk_core *clk,
+                                          unsigned long rate)
  {
-       struct clk *top = clk;
-       struct clk *old_parent, *parent;
+       struct clk_core *top = clk;
+       struct clk_core *old_parent, *parent;
        struct clk_hw *parent_hw;
        unsigned long best_parent_rate = 0;
        unsigned long new_rate;
+       unsigned long min_rate;
+       unsigned long max_rate;
        int p_index = 0;
  
        /* sanity */
        if (parent)
                best_parent_rate = parent->rate;
  
+       clk_core_get_boundaries(clk, &min_rate, &max_rate);
        /* find the closest rate and parent clk/rate */
        if (clk->ops->determine_rate) {
                parent_hw = parent ? parent->hw : NULL;
                new_rate = clk->ops->determine_rate(clk->hw, rate,
+                                                   min_rate,
+                                                   max_rate,
                                                    &best_parent_rate,
                                                    &parent_hw);
-               parent = parent_hw ? parent_hw->clk : NULL;
+               parent = parent_hw ? parent_hw->core : NULL;
        } else if (clk->ops->round_rate) {
                new_rate = clk->ops->round_rate(clk->hw, rate,
                                                &best_parent_rate);
+               if (new_rate < min_rate || new_rate > max_rate)
+                       return NULL;
        } else if (!parent || !(clk->flags & CLK_SET_RATE_PARENT)) {
                /* pass-through clock without adjustable parent */
                clk->new_rate = clk->rate;
        }
  
        /* try finding the new parent index */
-       if (parent) {
+       if (parent && clk->num_parents > 1) {
                p_index = clk_fetch_parent_index(clk, parent);
                if (p_index < 0) {
                        pr_debug("%s: clk %s can not be parent of clk %s\n",
   * so that in case of an error we can walk down the whole tree again and
   * abort the change.
   */
- static struct clk *clk_propagate_rate_change(struct clk *clk, unsigned long event)
+ static struct clk_core *clk_propagate_rate_change(struct clk_core *clk,
+                                                 unsigned long event)
  {
-       struct clk *child, *tmp_clk, *fail_clk = NULL;
+       struct clk_core *child, *tmp_clk, *fail_clk = NULL;
        int ret = NOTIFY_DONE;
  
        if (clk->rate == clk->new_rate)
   * walk down a subtree and set the new rates notifying the rate
   * change on the way
   */
- static void clk_change_rate(struct clk *clk)
+ static void clk_change_rate(struct clk_core *clk)
  {
-       struct clk *child;
+       struct clk_core *child;
        struct hlist_node *tmp;
        unsigned long old_rate;
        unsigned long best_parent_rate = 0;
        bool skip_set_rate = false;
-       struct clk *old_parent;
+       struct clk_core *old_parent;
  
        old_rate = clk->rate;
  
                clk_change_rate(clk->new_child);
  }
  
+ static int clk_core_set_rate_nolock(struct clk_core *clk,
+                                   unsigned long req_rate)
+ {
+       struct clk_core *top, *fail_clk;
+       unsigned long rate = req_rate;
+       int ret = 0;
+       if (!clk)
+               return 0;
+       /* bail early if nothing to do */
+       if (rate == clk_core_get_rate_nolock(clk))
+               return 0;
+       if ((clk->flags & CLK_SET_RATE_GATE) && clk->prepare_count)
+               return -EBUSY;
+       /* calculate new rates and get the topmost changed clock */
+       top = clk_calc_new_rates(clk, rate);
+       if (!top)
+               return -EINVAL;
+       /* notify that we are about to change rates */
+       fail_clk = clk_propagate_rate_change(top, PRE_RATE_CHANGE);
+       if (fail_clk) {
+               pr_debug("%s: failed to set %s rate\n", __func__,
+                               fail_clk->name);
+               clk_propagate_rate_change(top, ABORT_RATE_CHANGE);
+               return -EBUSY;
+       }
+       /* change the rates */
+       clk_change_rate(top);
+       clk->req_rate = req_rate;
+       return ret;
+ }
  /**
   * clk_set_rate - specify a new rate for clk
   * @clk: the clk whose rate is being changed
   */
  int clk_set_rate(struct clk *clk, unsigned long rate)
  {
-       struct clk *top, *fail_clk;
-       int ret = 0;
+       int ret;
  
        if (!clk)
                return 0;
        /* prevent racing with updates to the clock topology */
        clk_prepare_lock();
  
-       /* bail early if nothing to do */
-       if (rate == clk_get_rate(clk))
-               goto out;
+       ret = clk_core_set_rate_nolock(clk->core, rate);
  
-       if ((clk->flags & CLK_SET_RATE_GATE) && clk->prepare_count) {
-               ret = -EBUSY;
-               goto out;
-       }
+       clk_prepare_unlock();
  
-       /* calculate new rates and get the topmost changed clock */
-       top = clk_calc_new_rates(clk, rate);
-       if (!top) {
-               ret = -EINVAL;
-               goto out;
-       }
+       return ret;
+ }
+ EXPORT_SYMBOL_GPL(clk_set_rate);
  
-       /* notify that we are about to change rates */
-       fail_clk = clk_propagate_rate_change(top, PRE_RATE_CHANGE);
-       if (fail_clk) {
-               pr_debug("%s: failed to set %s rate\n", __func__,
-                               fail_clk->name);
-               clk_propagate_rate_change(top, ABORT_RATE_CHANGE);
-               ret = -EBUSY;
-               goto out;
+ /**
+  * clk_set_rate_range - set a rate range for a clock source
+  * @clk: clock source
+  * @min: desired minimum clock rate in Hz, inclusive
+  * @max: desired maximum clock rate in Hz, inclusive
+  *
+  * Returns success (0) or negative errno.
+  */
+ int clk_set_rate_range(struct clk *clk, unsigned long min, unsigned long max)
+ {
+       int ret = 0;
+       if (!clk)
+               return 0;
+       if (min > max) {
+               pr_err("%s: clk %s dev %s con %s: invalid range [%lu, %lu]\n",
+                      __func__, clk->core->name, clk->dev_id, clk->con_id,
+                      min, max);
+               return -EINVAL;
        }
  
-       /* change the rates */
-       clk_change_rate(top);
+       clk_prepare_lock();
+       if (min != clk->min_rate || max != clk->max_rate) {
+               clk->min_rate = min;
+               clk->max_rate = max;
+               ret = clk_core_set_rate_nolock(clk->core, clk->core->req_rate);
+       }
  
- out:
        clk_prepare_unlock();
  
        return ret;
  }
- EXPORT_SYMBOL_GPL(clk_set_rate);
+ EXPORT_SYMBOL_GPL(clk_set_rate_range);
+ /**
+  * clk_set_min_rate - set a minimum clock rate for a clock source
+  * @clk: clock source
+  * @rate: desired minimum clock rate in Hz, inclusive
+  *
+  * Returns success (0) or negative errno.
+  */
+ int clk_set_min_rate(struct clk *clk, unsigned long rate)
+ {
+       if (!clk)
+               return 0;
+       return clk_set_rate_range(clk, rate, clk->max_rate);
+ }
+ EXPORT_SYMBOL_GPL(clk_set_min_rate);
+ /**
+  * clk_set_max_rate - set a maximum clock rate for a clock source
+  * @clk: clock source
+  * @rate: desired maximum clock rate in Hz, inclusive
+  *
+  * Returns success (0) or negative errno.
+  */
+ int clk_set_max_rate(struct clk *clk, unsigned long rate)
+ {
+       if (!clk)
+               return 0;
+       return clk_set_rate_range(clk, clk->min_rate, rate);
+ }
+ EXPORT_SYMBOL_GPL(clk_set_max_rate);
  
  /**
   * clk_get_parent - return the parent of a clk
@@@ -1599,11 -1915,11 +1915,11 @@@ EXPORT_SYMBOL_GPL(clk_get_parent)
   *
   * For single-parent clocks without .get_parent, first check to see if the
   * .parents array exists, and if so use it to avoid an expensive tree
-  * traversal.  If .parents does not exist then walk the tree with __clk_lookup.
+  * traversal.  If .parents does not exist then walk the tree.
   */
- static struct clk *__clk_init_parent(struct clk *clk)
+ static struct clk_core *__clk_init_parent(struct clk_core *clk)
  {
-       struct clk *ret = NULL;
+       struct clk_core *ret = NULL;
        u8 index;
  
        /* handle the trivial cases */
  
        if (clk->num_parents == 1) {
                if (IS_ERR_OR_NULL(clk->parent))
-                       clk->parent = __clk_lookup(clk->parent_names[0]);
+                       clk->parent = clk_core_lookup(clk->parent_names[0]);
                ret = clk->parent;
                goto out;
        }
  
        /*
         * Do our best to cache parent clocks in clk->parents.  This prevents
-        * unnecessary and expensive calls to __clk_lookup.  We don't set
-        * clk->parent here; that is done by the calling function
+        * unnecessary and expensive lookups.  We don't set clk->parent here;
+        * that is done by the calling function.
         */
  
        index = clk->ops->get_parent(clk->hw);
                        kcalloc(clk->num_parents, sizeof(struct clk *),
                                        GFP_KERNEL);
  
-       ret = clk_get_parent_by_index(clk, index);
+       ret = clk_core_get_parent_by_index(clk, index);
  
  out:
        return ret;
  }
  
- void __clk_reparent(struct clk *clk, struct clk *new_parent)
+ static void clk_core_reparent(struct clk_core *clk,
+                                 struct clk_core *new_parent)
  {
        clk_reparent(clk, new_parent);
        __clk_recalc_accuracies(clk);
  }
  
  /**
-  * clk_set_parent - switch the parent of a mux clk
-  * @clk: the mux clk whose input we are switching
-  * @parent: the new input to clk
+  * clk_has_parent - check if a clock is a possible parent for another
+  * @clk: clock source
+  * @parent: parent clock source
   *
-  * Re-parent clk to use parent as its new input source.  If clk is in
-  * prepared state, the clk will get enabled for the duration of this call. If
-  * that's not acceptable for a specific clk (Eg: the consumer can't handle
-  * that, the reparenting is glitchy in hardware, etc), use the
-  * CLK_SET_PARENT_GATE flag to allow reparenting only when clk is unprepared.
-  *
-  * After successfully changing clk's parent clk_set_parent will update the
-  * clk topology, sysfs topology and propagate rate recalculation via
-  * __clk_recalc_rates.
+  * This function can be used in drivers that need to check that a clock can be
+  * the parent of another without actually changing the parent.
   *
-  * Returns 0 on success, -EERROR otherwise.
+  * Returns true if @parent is a possible parent for @clk, false otherwise.
   */
- int clk_set_parent(struct clk *clk, struct clk *parent)
+ bool clk_has_parent(struct clk *clk, struct clk *parent)
+ {
+       struct clk_core *core, *parent_core;
+       unsigned int i;
+       /* NULL clocks should be nops, so return success if either is NULL. */
+       if (!clk || !parent)
+               return true;
+       core = clk->core;
+       parent_core = parent->core;
+       /* Optimize for the case where the parent is already the parent. */
+       if (core->parent == parent_core)
+               return true;
+       for (i = 0; i < core->num_parents; i++)
+               if (strcmp(core->parent_names[i], parent_core->name) == 0)
+                       return true;
+       return false;
+ }
+ EXPORT_SYMBOL_GPL(clk_has_parent);
+ static int clk_core_set_parent(struct clk_core *clk, struct clk_core *parent)
  {
        int ret = 0;
        int p_index = 0;
  
        return ret;
  }
+ /**
+  * clk_set_parent - switch the parent of a mux clk
+  * @clk: the mux clk whose input we are switching
+  * @parent: the new input to clk
+  *
+  * Re-parent clk to use parent as its new input source.  If clk is in
+  * prepared state, the clk will get enabled for the duration of this call. If
+  * that's not acceptable for a specific clk (Eg: the consumer can't handle
+  * that, the reparenting is glitchy in hardware, etc), use the
+  * CLK_SET_PARENT_GATE flag to allow reparenting only when clk is unprepared.
+  *
+  * After successfully changing clk's parent clk_set_parent will update the
+  * clk topology, sysfs topology and propagate rate recalculation via
+  * __clk_recalc_rates.
+  *
+  * Returns 0 on success, -EERROR otherwise.
+  */
+ int clk_set_parent(struct clk *clk, struct clk *parent)
+ {
+       if (!clk)
+               return 0;
+       return clk_core_set_parent(clk->core, parent ? parent->core : NULL);
+ }
  EXPORT_SYMBOL_GPL(clk_set_parent);
  
  /**
@@@ -1764,13 -2123,13 +2123,13 @@@ int clk_set_phase(struct clk *clk, int 
  
        clk_prepare_lock();
  
-       if (!clk->ops->set_phase)
+       if (!clk->core->ops->set_phase)
                goto out_unlock;
  
-       ret = clk->ops->set_phase(clk->hw, degrees);
+       ret = clk->core->ops->set_phase(clk->core->hw, degrees);
  
        if (!ret)
-               clk->phase = degrees;
+               clk->core->phase = degrees;
  
  out_unlock:
        clk_prepare_unlock();
  out:
        return ret;
  }
+ EXPORT_SYMBOL_GPL(clk_set_phase);
  
- /**
-  * clk_get_phase - return the phase shift of a clock signal
-  * @clk: clock signal source
-  *
-  * Returns the phase shift of a clock node in degrees, otherwise returns
-  * -EERROR.
-  */
- int clk_get_phase(struct clk *clk)
+ static int clk_core_get_phase(struct clk_core *clk)
  {
        int ret = 0;
  
  out:
        return ret;
  }
+ EXPORT_SYMBOL_GPL(clk_get_phase);
+ /**
+  * clk_get_phase - return the phase shift of a clock signal
+  * @clk: clock signal source
+  *
+  * Returns the phase shift of a clock node in degrees, otherwise returns
+  * -EERROR.
+  */
+ int clk_get_phase(struct clk *clk)
+ {
+       if (!clk)
+               return 0;
+       return clk_core_get_phase(clk->core);
+ }
  
  /**
   * __clk_init - initialize the data structures in a struct clk
   * @dev:      device initializing this clk, placeholder for now
   * @clk:      clk being initialized
   *
-  * Initializes the lists in struct clk, queries the hardware for the
+  * Initializes the lists in struct clk_core, queries the hardware for the
   * parent and rate and sets them both.
   */
int __clk_init(struct device *dev, struct clk *clk)
static int __clk_init(struct device *dev, struct clk *clk_user)
  {
        int i, ret = 0;
-       struct clk *orphan;
+       struct clk_core *orphan;
        struct hlist_node *tmp2;
+       struct clk_core *clk;
+       unsigned long rate;
  
-       if (!clk)
+       if (!clk_user)
                return -EINVAL;
  
+       clk = clk_user->core;
        clk_prepare_lock();
  
        /* check to see if a clock with this name is already registered */
-       if (__clk_lookup(clk->name)) {
+       if (clk_core_lookup(clk->name)) {
                pr_debug("%s: clk %s already initialized\n",
                                __func__, clk->name);
                ret = -EEXIST;
                clk->parents = kcalloc(clk->num_parents, sizeof(struct clk *),
                                        GFP_KERNEL);
                /*
-                * __clk_lookup returns NULL for parents that have not been
+                * clk_core_lookup returns NULL for parents that have not been
                 * clk_init'd; thus any access to clk->parents[] must check
                 * for a NULL pointer.  We can always perform lazy lookups for
                 * missing parents later on.
                if (clk->parents)
                        for (i = 0; i < clk->num_parents; i++)
                                clk->parents[i] =
-                                       __clk_lookup(clk->parent_names[i]);
+                                       clk_core_lookup(clk->parent_names[i]);
        }
  
        clk->parent = __clk_init_parent(clk);
         * then rate is set to zero.
         */
        if (clk->ops->recalc_rate)
-               clk->rate = clk->ops->recalc_rate(clk->hw,
-                               __clk_get_rate(clk->parent));
+               rate = clk->ops->recalc_rate(clk->hw,
+                               clk_core_get_rate_nolock(clk->parent));
        else if (clk->parent)
-               clk->rate = clk->parent->rate;
+               rate = clk->parent->rate;
        else
-               clk->rate = 0;
+               rate = 0;
+       clk->rate = clk->req_rate = rate;
  
        /*
         * walk the list of orphan clocks and reparent any that are children of
                if (orphan->num_parents && orphan->ops->get_parent) {
                        i = orphan->ops->get_parent(orphan->hw);
                        if (!strcmp(clk->name, orphan->parent_names[i]))
-                               __clk_reparent(orphan, clk);
+                               clk_core_reparent(orphan, clk);
                        continue;
                }
  
                for (i = 0; i < orphan->num_parents; i++)
                        if (!strcmp(clk->name, orphan->parent_names[i])) {
-                               __clk_reparent(orphan, clk);
+                               clk_core_reparent(orphan, clk);
                                break;
                        }
         }
        return ret;
  }
  
- /**
-  * __clk_register - register a clock and return a cookie.
-  *
-  * Same as clk_register, except that the .clk field inside hw shall point to a
-  * preallocated (generally statically allocated) struct clk. None of the fields
-  * of the struct clk need to be initialized.
-  *
-  * The data pointed to by .init and .clk field shall NOT be marked as init
-  * data.
-  *
-  * __clk_register is only exposed via clk-private.h and is intended for use with
-  * very large numbers of clocks that need to be statically initialized.  It is
-  * a layering violation to include clk-private.h from any code which implements
-  * a clock's .ops; as such any statically initialized clock data MUST be in a
-  * separate C file from the logic that implements its operations.  Returns 0
-  * on success, otherwise an error code.
-  */
- struct clk *__clk_register(struct device *dev, struct clk_hw *hw)
+ struct clk *__clk_create_clk(struct clk_hw *hw, const char *dev_id,
+                            const char *con_id)
  {
-       int ret;
        struct clk *clk;
  
-       clk = hw->clk;
-       clk->name = hw->init->name;
-       clk->ops = hw->init->ops;
-       clk->hw = hw;
-       clk->flags = hw->init->flags;
-       clk->parent_names = hw->init->parent_names;
-       clk->num_parents = hw->init->num_parents;
-       if (dev && dev->driver)
-               clk->owner = dev->driver->owner;
-       else
-               clk->owner = NULL;
+       /* This is to allow this function to be chained to others */
+       if (!hw || IS_ERR(hw))
+               return (struct clk *) hw;
  
-       ret = __clk_init(dev, clk);
-       if (ret)
-               return ERR_PTR(ret);
+       clk = kzalloc(sizeof(*clk), GFP_KERNEL);
+       if (!clk)
+               return ERR_PTR(-ENOMEM);
+       clk->core = hw->core;
+       clk->dev_id = dev_id;
+       clk->con_id = con_id;
+       clk->max_rate = ULONG_MAX;
+       clk_prepare_lock();
+       hlist_add_head(&clk->child_node, &hw->core->clks);
+       clk_prepare_unlock();
  
        return clk;
  }
- EXPORT_SYMBOL_GPL(__clk_register);
+ void __clk_free_clk(struct clk *clk)
+ {
+       clk_prepare_lock();
+       hlist_del(&clk->child_node);
+       clk_prepare_unlock();
+       kfree(clk);
+ }
  
  /**
   * clk_register - allocate a new clock, register it and return an opaque cookie
  struct clk *clk_register(struct device *dev, struct clk_hw *hw)
  {
        int i, ret;
-       struct clk *clk;
+       struct clk_core *clk;
  
        clk = kzalloc(sizeof(*clk), GFP_KERNEL);
        if (!clk) {
                goto fail_out;
        }
  
 -      clk->name = kstrdup(hw->init->name, GFP_KERNEL);
 +      clk->name = kstrdup_const(hw->init->name, GFP_KERNEL);
        if (!clk->name) {
                pr_err("%s: could not allocate clk->name\n", __func__);
                ret = -ENOMEM;
        clk->hw = hw;
        clk->flags = hw->init->flags;
        clk->num_parents = hw->init->num_parents;
-       hw->clk = clk;
+       hw->core = clk;
  
        /* allocate local copy in case parent_names is __initdata */
        clk->parent_names = kcalloc(clk->num_parents, sizeof(char *),
  
        /* copy each string name in case parent_names is __initdata */
        for (i = 0; i < clk->num_parents; i++) {
 -              clk->parent_names[i] = kstrdup(hw->init->parent_names[i],
 +              clk->parent_names[i] = kstrdup_const(hw->init->parent_names[i],
                                                GFP_KERNEL);
                if (!clk->parent_names[i]) {
                        pr_err("%s: could not copy parent_names\n", __func__);
                }
        }
  
-       ret = __clk_init(dev, clk);
+       INIT_HLIST_HEAD(&clk->clks);
+       hw->clk = __clk_create_clk(hw, NULL, NULL);
+       if (IS_ERR(hw->clk)) {
+               pr_err("%s: could not allocate per-user clk\n", __func__);
+               ret = PTR_ERR(hw->clk);
+               goto fail_parent_names_copy;
+       }
+       ret = __clk_init(dev, hw->clk);
        if (!ret)
-               return clk;
+               return hw->clk;
+       __clk_free_clk(hw->clk);
+       hw->clk = NULL;
  
  fail_parent_names_copy:
        while (--i >= 0)
 -              kfree(clk->parent_names[i]);
 +              kfree_const(clk->parent_names[i]);
        kfree(clk->parent_names);
  fail_parent_names:
 -      kfree(clk->name);
 +      kfree_const(clk->name);
  fail_name:
        kfree(clk);
  fail_out:
@@@ -2107,15 -2485,15 +2485,15 @@@ EXPORT_SYMBOL_GPL(clk_register)
   */
  static void __clk_release(struct kref *ref)
  {
-       struct clk *clk = container_of(ref, struct clk, ref);
+       struct clk_core *clk = container_of(ref, struct clk_core, ref);
        int i = clk->num_parents;
  
        kfree(clk->parents);
        while (--i >= 0)
 -              kfree(clk->parent_names[i]);
 +              kfree_const(clk->parent_names[i]);
  
        kfree(clk->parent_names);
 -      kfree(clk->name);
 +      kfree_const(clk->name);
        kfree(clk);
  }
  
@@@ -2165,12 -2543,13 +2543,13 @@@ void clk_unregister(struct clk *clk
        if (!clk || WARN_ON_ONCE(IS_ERR(clk)))
                return;
  
-       clk_debug_unregister(clk);
+       clk_debug_unregister(clk->core);
  
        clk_prepare_lock();
  
-       if (clk->ops == &clk_nodrv_ops) {
-               pr_err("%s: unregistered clock: %s\n", __func__, clk->name);
+       if (clk->core->ops == &clk_nodrv_ops) {
+               pr_err("%s: unregistered clock: %s\n", __func__,
+                      clk->core->name);
                return;
        }
        /*
         * a reference to this clock.
         */
        flags = clk_enable_lock();
-       clk->ops = &clk_nodrv_ops;
+       clk->core->ops = &clk_nodrv_ops;
        clk_enable_unlock(flags);
  
-       if (!hlist_empty(&clk->children)) {
-               struct clk *child;
+       if (!hlist_empty(&clk->core->children)) {
+               struct clk_core *child;
                struct hlist_node *t;
  
                /* Reparent all children to the orphan list. */
-               hlist_for_each_entry_safe(child, t, &clk->children, child_node)
-                       clk_set_parent(child, NULL);
+               hlist_for_each_entry_safe(child, t, &clk->core->children,
+                                         child_node)
+                       clk_core_set_parent(child, NULL);
        }
  
-       hlist_del_init(&clk->child_node);
+       hlist_del_init(&clk->core->child_node);
  
-       if (clk->prepare_count)
+       if (clk->core->prepare_count)
                pr_warn("%s: unregistering prepared clock: %s\n",
-                                       __func__, clk->name);
-       kref_put(&clk->ref, __clk_release);
+                                       __func__, clk->core->name);
+       kref_put(&clk->core->ref, __clk_release);
  
        clk_prepare_unlock();
  }
@@@ -2263,11 -2643,13 +2643,13 @@@ EXPORT_SYMBOL_GPL(devm_clk_unregister)
   */
  int __clk_get(struct clk *clk)
  {
-       if (clk) {
-               if (!try_module_get(clk->owner))
+       struct clk_core *core = !clk ? NULL : clk->core;
+       if (core) {
+               if (!try_module_get(core->owner))
                        return 0;
  
-               kref_get(&clk->ref);
+               kref_get(&core->ref);
        }
        return 1;
  }
@@@ -2280,11 -2662,20 +2662,20 @@@ void __clk_put(struct clk *clk
                return;
  
        clk_prepare_lock();
-       owner = clk->owner;
-       kref_put(&clk->ref, __clk_release);
+       hlist_del(&clk->child_node);
+       if (clk->min_rate > clk->core->req_rate ||
+           clk->max_rate < clk->core->req_rate)
+               clk_core_set_rate_nolock(clk->core, clk->core->req_rate);
+       owner = clk->core->owner;
+       kref_put(&clk->core->ref, __clk_release);
        clk_prepare_unlock();
  
        module_put(owner);
+       kfree(clk);
  }
  
  /***        clk rate change notifiers        ***/
@@@ -2339,7 -2730,7 +2730,7 @@@ int clk_notifier_register(struct clk *c
  
        ret = srcu_notifier_chain_register(&cn->notifier_head, nb);
  
-       clk->notifier_count++;
+       clk->core->notifier_count++;
  
  out:
        clk_prepare_unlock();
@@@ -2376,7 -2767,7 +2767,7 @@@ int clk_notifier_unregister(struct clk 
        if (cn->clk == clk) {
                ret = srcu_notifier_chain_unregister(&cn->notifier_head, nb);
  
-               clk->notifier_count--;
+               clk->core->notifier_count--;
  
                /* XXX the notifier code should handle this better */
                if (!cn->notifier_head.head) {
@@@ -2506,7 -2897,8 +2897,8 @@@ void of_clk_del_provider(struct device_
  }
  EXPORT_SYMBOL_GPL(of_clk_del_provider);
  
- struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec)
+ struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec,
+                                      const char *dev_id, const char *con_id)
  {
        struct of_clk_provider *provider;
        struct clk *clk = ERR_PTR(-EPROBE_DEFER);
        list_for_each_entry(provider, &of_clk_providers, link) {
                if (provider->node == clkspec->np)
                        clk = provider->get(clkspec, provider->data);
-               if (!IS_ERR(clk))
+               if (!IS_ERR(clk)) {
+                       clk = __clk_create_clk(__clk_get_hw(clk), dev_id,
+                                              con_id);
+                       if (!IS_ERR(clk) && !__clk_get(clk)) {
+                               __clk_free_clk(clk);
+                               clk = ERR_PTR(-ENOENT);
+                       }
                        break;
+               }
        }
  
        return clk;
@@@ -2527,7 -2928,7 +2928,7 @@@ struct clk *of_clk_get_from_provider(st
        struct clk *clk;
  
        mutex_lock(&of_clk_mutex);
-       clk = __of_clk_get_from_provider(clkspec);
+       clk = __of_clk_get_from_provider(clkspec, NULL, __func__);
        mutex_unlock(&of_clk_mutex);
  
        return clk;
index cbcddcc02475233f53b2d150f8395a99c3b4ba4d,eeadbb6b52061f83058343ff0439337a683be093..05d7a0bc059907872ff1719d0c401a0494082199
@@@ -190,7 -190,7 +190,7 @@@ PNAME(mux_uart2_p) = { "uart2_src", "ua
  PNAME(mux_uart3_p)    = { "uart3_src", "uart3_frac", "xin24m" };
  PNAME(mux_uart4_p)    = { "uart4_src", "uart4_frac", "xin24m" };
  PNAME(mux_cif_out_p)  = { "cif_src", "xin24m" };
 -PNAME(mux_macref_p)   = { "mac_src", "ext_gmac" };
 +PNAME(mux_mac_p)      = { "mac_pll_src", "ext_gmac" };
  PNAME(mux_hsadcout_p) = { "hsadc_src", "ext_hsadc" };
  PNAME(mux_edp_24m_p)  = { "ext_edp_24m", "xin24m" };
  PNAME(mux_tspout_p)   = { "cpll", "gpll", "npll", "xin27m" };
@@@ -535,58 -535,58 +535,58 @@@ static struct rockchip_clk_branch rk328
        COMPOSITE(0, "uart0_src", mux_pll_src_cpll_gll_usb_npll_p, 0,
                        RK3288_CLKSEL_CON(13), 13, 2, MFLAGS, 0, 7, DFLAGS,
                        RK3288_CLKGATE_CON(1), 8, GFLAGS),
-       COMPOSITE_FRAC(0, "uart0_frac", "uart0_src", 0,
+       COMPOSITE_FRAC(0, "uart0_frac", "uart0_src", CLK_SET_RATE_PARENT,
                        RK3288_CLKSEL_CON(17), 0,
                        RK3288_CLKGATE_CON(1), 9, GFLAGS),
-       MUX(SCLK_UART0, "sclk_uart0", mux_uart0_p, 0,
+       MUX(SCLK_UART0, "sclk_uart0", mux_uart0_p, CLK_SET_RATE_PARENT,
                        RK3288_CLKSEL_CON(13), 8, 2, MFLAGS),
        MUX(0, "uart_src", mux_pll_src_cpll_gpll_p, 0,
                        RK3288_CLKSEL_CON(13), 15, 1, MFLAGS),
        COMPOSITE_NOMUX(0, "uart1_src", "uart_src", 0,
                        RK3288_CLKSEL_CON(14), 0, 7, DFLAGS,
                        RK3288_CLKGATE_CON(1), 10, GFLAGS),
-       COMPOSITE_FRAC(0, "uart1_frac", "uart1_src", 0,
+       COMPOSITE_FRAC(0, "uart1_frac", "uart1_src", CLK_SET_RATE_PARENT,
                        RK3288_CLKSEL_CON(18), 0,
                        RK3288_CLKGATE_CON(1), 11, GFLAGS),
-       MUX(SCLK_UART1, "sclk_uart1", mux_uart1_p, 0,
+       MUX(SCLK_UART1, "sclk_uart1", mux_uart1_p, CLK_SET_RATE_PARENT,
                        RK3288_CLKSEL_CON(14), 8, 2, MFLAGS),
        COMPOSITE_NOMUX(0, "uart2_src", "uart_src", 0,
                        RK3288_CLKSEL_CON(15), 0, 7, DFLAGS,
                        RK3288_CLKGATE_CON(1), 12, GFLAGS),
-       COMPOSITE_FRAC(0, "uart2_frac", "uart2_src", 0,
+       COMPOSITE_FRAC(0, "uart2_frac", "uart2_src", CLK_SET_RATE_PARENT,
                        RK3288_CLKSEL_CON(19), 0,
                        RK3288_CLKGATE_CON(1), 13, GFLAGS),
-       MUX(SCLK_UART2, "sclk_uart2", mux_uart2_p, 0,
+       MUX(SCLK_UART2, "sclk_uart2", mux_uart2_p, CLK_SET_RATE_PARENT,
                        RK3288_CLKSEL_CON(15), 8, 2, MFLAGS),
        COMPOSITE_NOMUX(0, "uart3_src", "uart_src", 0,
                        RK3288_CLKSEL_CON(16), 0, 7, DFLAGS,
                        RK3288_CLKGATE_CON(1), 14, GFLAGS),
-       COMPOSITE_FRAC(0, "uart3_frac", "uart3_src", 0,
+       COMPOSITE_FRAC(0, "uart3_frac", "uart3_src", CLK_SET_RATE_PARENT,
                        RK3288_CLKSEL_CON(20), 0,
                        RK3288_CLKGATE_CON(1), 15, GFLAGS),
-       MUX(SCLK_UART3, "sclk_uart3", mux_uart3_p, 0,
+       MUX(SCLK_UART3, "sclk_uart3", mux_uart3_p, CLK_SET_RATE_PARENT,
                        RK3288_CLKSEL_CON(16), 8, 2, MFLAGS),
        COMPOSITE_NOMUX(0, "uart4_src", "uart_src", 0,
                        RK3288_CLKSEL_CON(3), 0, 7, DFLAGS,
                        RK3288_CLKGATE_CON(2), 12, GFLAGS),
-       COMPOSITE_FRAC(0, "uart4_frac", "uart4_src", 0,
+       COMPOSITE_FRAC(0, "uart4_frac", "uart4_src", CLK_SET_RATE_PARENT,
                        RK3288_CLKSEL_CON(7), 0,
                        RK3288_CLKGATE_CON(2), 13, GFLAGS),
-       MUX(SCLK_UART4, "sclk_uart4", mux_uart4_p, 0,
+       MUX(SCLK_UART4, "sclk_uart4", mux_uart4_p, CLK_SET_RATE_PARENT,
                        RK3288_CLKSEL_CON(3), 8, 2, MFLAGS),
  
 -      COMPOSITE(0, "mac_src", mux_pll_src_npll_cpll_gpll_p, 0,
 +      COMPOSITE(0, "mac_pll_src", mux_pll_src_npll_cpll_gpll_p, 0,
                        RK3288_CLKSEL_CON(21), 0, 2, MFLAGS, 8, 5, DFLAGS,
                        RK3288_CLKGATE_CON(2), 5, GFLAGS),
 -      MUX(0, "macref", mux_macref_p, 0,
 +      MUX(SCLK_MAC, "mac_clk", mux_mac_p, 0,
                        RK3288_CLKSEL_CON(21), 4, 1, MFLAGS),
 -      GATE(0, "sclk_macref_out", "macref", 0,
 +      GATE(SCLK_MACREF_OUT, "sclk_macref_out", "mac_clk", 0,
                        RK3288_CLKGATE_CON(5), 3, GFLAGS),
 -      GATE(SCLK_MACREF, "sclk_macref", "macref", 0,
 +      GATE(SCLK_MACREF, "sclk_macref", "mac_clk", 0,
                        RK3288_CLKGATE_CON(5), 2, GFLAGS),
 -      GATE(SCLK_MAC_RX, "sclk_mac_rx", "macref", 0,
 +      GATE(SCLK_MAC_RX, "sclk_mac_rx", "mac_clk", 0,
                        RK3288_CLKGATE_CON(5), 0, GFLAGS),
 -      GATE(SCLK_MAC_TX, "sclk_mac_tx", "macref", 0,
 +      GATE(SCLK_MAC_TX, "sclk_mac_tx", "mac_clk", 0,
                        RK3288_CLKGATE_CON(5), 1, GFLAGS),
  
        COMPOSITE(0, "hsadc_src", mux_pll_src_cpll_gpll_p, 0,
        GATE(0, "jtag", "ext_jtag", 0,
                        RK3288_CLKGATE_CON(4), 14, GFLAGS),
  
-       COMPOSITE_NODIV(0, "usbphy480m_src", mux_usbphy480m_p, 0,
+       COMPOSITE_NODIV(SCLK_USBPHY480M_SRC, "usbphy480m_src", mux_usbphy480m_p, 0,
                        RK3288_CLKSEL_CON(13), 11, 2, MFLAGS,
                        RK3288_CLKGATE_CON(5), 14, GFLAGS),
        COMPOSITE_NODIV(SCLK_HSICPHY480M, "sclk_hsicphy480m", mux_hsicphy480m_p, 0,
  
        GATE(SCLK_LCDC_PWM0, "sclk_lcdc_pwm0", "xin24m", 0, RK3288_CLKGATE_CON(13), 10, GFLAGS),
        GATE(SCLK_LCDC_PWM1, "sclk_lcdc_pwm1", "xin24m", 0, RK3288_CLKGATE_CON(13), 11, GFLAGS),
-       GATE(0, "sclk_pvtm_core", "xin24m", 0, RK3288_CLKGATE_CON(5), 9, GFLAGS),
-       GATE(0, "sclk_pvtm_gpu", "xin24m", 0, RK3288_CLKGATE_CON(5), 10, GFLAGS),
+       GATE(SCLK_PVTM_CORE, "sclk_pvtm_core", "xin24m", 0, RK3288_CLKGATE_CON(5), 9, GFLAGS),
+       GATE(SCLK_PVTM_GPU, "sclk_pvtm_gpu", "xin24m", 0, RK3288_CLKGATE_CON(5), 10, GFLAGS),
        GATE(0, "sclk_mipidsi_24m", "xin24m", 0, RK3288_CLKGATE_CON(5), 15, GFLAGS),
  
        /* sclk_gpu gates */
@@@ -805,6 -805,20 +805,20 @@@ static int rk3288_clk_suspend(void
                rk3288_saved_cru_regs[i] =
                                readl_relaxed(rk3288_cru_base + reg_id);
        }
+       /*
+        * Switch PLLs other than DPLL (for SDRAM) to slow mode to
+        * avoid crashes on resume. The Mask ROM on the system will
+        * put APLL, CPLL, and GPLL into slow mode at resume time
+        * anyway (which is why we restore them), but we might not
+        * even make it to the Mask ROM if this isn't done at suspend
+        * time.
+        *
+        * NOTE: only APLL truly matters here, but we'll do them all.
+        */
+       writel_relaxed(0xf3030000, rk3288_cru_base + RK3288_MODE_CON);
        return 0;
  }
  
@@@ -866,6 -880,14 +880,14 @@@ static void __init rk3288_clk_init(stru
                pr_warn("%s: could not register clock hclk_vcodec_pre: %ld\n",
                        __func__, PTR_ERR(clk));
  
+       /* Watchdog pclk is controlled by RK3288_SGRF_SOC_CON0[1]. */
+       clk = clk_register_fixed_factor(NULL, "pclk_wdt", "pclk_pd_alive", 0, 1, 1);
+       if (IS_ERR(clk))
+               pr_warn("%s: could not register clock pclk_wdt: %ld\n",
+                       __func__, PTR_ERR(clk));
+       else
+               rockchip_clk_add_lookup(clk, PCLK_WDT);
        rockchip_clk_register_plls(rk3288_pll_clks,
                                   ARRAY_SIZE(rk3288_pll_clks),
                                   RK3288_GRF_SOC_STATUS1);
index f83980f2b9568ffa7df081bf5593518e04bcde0b,bef4e4fa6688d31bca7f2343bdad3ff30a868fde..0689d7fb2666b1956728d85f9373b9cbd2c600b1
@@@ -1,10 -1,11 +1,12 @@@
  obj-$(CONFIG_ARCH_EMEV2)              += clk-emev2.o
  obj-$(CONFIG_ARCH_R7S72100)           += clk-rz.o
+ obj-$(CONFIG_ARCH_R8A73A4)            += clk-r8a73a4.o
  obj-$(CONFIG_ARCH_R8A7740)            += clk-r8a7740.o
  obj-$(CONFIG_ARCH_R8A7779)            += clk-r8a7779.o
  obj-$(CONFIG_ARCH_R8A7790)            += clk-rcar-gen2.o
  obj-$(CONFIG_ARCH_R8A7791)            += clk-rcar-gen2.o
+ obj-$(CONFIG_ARCH_R8A7793)            += clk-rcar-gen2.o
  obj-$(CONFIG_ARCH_R8A7794)            += clk-rcar-gen2.o
 +obj-$(CONFIG_ARCH_SH73A0)             += clk-sh73a0.o
  obj-$(CONFIG_ARCH_SHMOBILE_MULTI)     += clk-div6.o
  obj-$(CONFIG_ARCH_SHMOBILE_MULTI)     += clk-mstp.o
index 1818f404538d377d22b8b1d1602a0130e388018a,69937eaba795ccfc96b95c98c11330cd9bd9693d..379324eb5486e1b332d19fcf66fc8d7a0c4aff15
  #include <linux/of_address.h>
  #include <linux/reset-controller.h>
  #include <linux/spinlock.h>
+ #include <linux/log2.h>
  
  #include "clk-factors.h"
  
  static DEFINE_SPINLOCK(clk_lock);
  
+ /**
+  * sun6i_a31_ahb1_clk_setup() - Setup function for a31 ahb1 composite clk
+  */
+ #define SUN6I_AHB1_MAX_PARENTS                4
+ #define SUN6I_AHB1_MUX_PARENT_PLL6    3
+ #define SUN6I_AHB1_MUX_SHIFT          12
+ /* un-shifted mask is what mux_clk expects */
+ #define SUN6I_AHB1_MUX_MASK           0x3
+ #define SUN6I_AHB1_MUX_GET_PARENT(reg)        ((reg >> SUN6I_AHB1_MUX_SHIFT) & \
+                                        SUN6I_AHB1_MUX_MASK)
+ #define SUN6I_AHB1_DIV_SHIFT          4
+ #define SUN6I_AHB1_DIV_MASK           (0x3 << SUN6I_AHB1_DIV_SHIFT)
+ #define SUN6I_AHB1_DIV_GET(reg)               ((reg & SUN6I_AHB1_DIV_MASK) >> \
+                                               SUN6I_AHB1_DIV_SHIFT)
+ #define SUN6I_AHB1_DIV_SET(reg, div)  ((reg & ~SUN6I_AHB1_DIV_MASK) | \
+                                               (div << SUN6I_AHB1_DIV_SHIFT))
+ #define SUN6I_AHB1_PLL6_DIV_SHIFT     6
+ #define SUN6I_AHB1_PLL6_DIV_MASK      (0x3 << SUN6I_AHB1_PLL6_DIV_SHIFT)
+ #define SUN6I_AHB1_PLL6_DIV_GET(reg)  ((reg & SUN6I_AHB1_PLL6_DIV_MASK) >> \
+                                               SUN6I_AHB1_PLL6_DIV_SHIFT)
+ #define SUN6I_AHB1_PLL6_DIV_SET(reg, div) ((reg & ~SUN6I_AHB1_PLL6_DIV_MASK) | \
+                                               (div << SUN6I_AHB1_PLL6_DIV_SHIFT))
+ struct sun6i_ahb1_clk {
+       struct clk_hw hw;
+       void __iomem *reg;
+ };
+ #define to_sun6i_ahb1_clk(_hw) container_of(_hw, struct sun6i_ahb1_clk, hw)
+ static unsigned long sun6i_ahb1_clk_recalc_rate(struct clk_hw *hw,
+                                               unsigned long parent_rate)
+ {
+       struct sun6i_ahb1_clk *ahb1 = to_sun6i_ahb1_clk(hw);
+       unsigned long rate;
+       u32 reg;
+       /* Fetch the register value */
+       reg = readl(ahb1->reg);
+       /* apply pre-divider first if parent is pll6 */
+       if (SUN6I_AHB1_MUX_GET_PARENT(reg) == SUN6I_AHB1_MUX_PARENT_PLL6)
+               parent_rate /= SUN6I_AHB1_PLL6_DIV_GET(reg) + 1;
+       /* clk divider */
+       rate = parent_rate >> SUN6I_AHB1_DIV_GET(reg);
+       return rate;
+ }
+ static long sun6i_ahb1_clk_round(unsigned long rate, u8 *divp, u8 *pre_divp,
+                                u8 parent, unsigned long parent_rate)
+ {
+       u8 div, calcp, calcm = 1;
+       /*
+        * clock can only divide, so we will never be able to achieve
+        * frequencies higher than the parent frequency
+        */
+       if (parent_rate && rate > parent_rate)
+               rate = parent_rate;
+       div = DIV_ROUND_UP(parent_rate, rate);
+       /* calculate pre-divider if parent is pll6 */
+       if (parent == SUN6I_AHB1_MUX_PARENT_PLL6) {
+               if (div < 4)
+                       calcp = 0;
+               else if (div / 2 < 4)
+                       calcp = 1;
+               else if (div / 4 < 4)
+                       calcp = 2;
+               else
+                       calcp = 3;
+               calcm = DIV_ROUND_UP(div, 1 << calcp);
+       } else {
+               calcp = __roundup_pow_of_two(div);
+               calcp = calcp > 3 ? 3 : calcp;
+       }
+       /* we were asked to pass back divider values */
+       if (divp) {
+               *divp = calcp;
+               *pre_divp = calcm - 1;
+       }
+       return (parent_rate / calcm) >> calcp;
+ }
+ static long sun6i_ahb1_clk_determine_rate(struct clk_hw *hw, unsigned long rate,
+                                         unsigned long min_rate,
+                                         unsigned long max_rate,
+                                         unsigned long *best_parent_rate,
+                                         struct clk_hw **best_parent_clk)
+ {
+       struct clk *clk = hw->clk, *parent, *best_parent = NULL;
+       int i, num_parents;
+       unsigned long parent_rate, best = 0, child_rate, best_child_rate = 0;
+       /* find the parent that can help provide the fastest rate <= rate */
+       num_parents = __clk_get_num_parents(clk);
+       for (i = 0; i < num_parents; i++) {
+               parent = clk_get_parent_by_index(clk, i);
+               if (!parent)
+                       continue;
+               if (__clk_get_flags(clk) & CLK_SET_RATE_PARENT)
+                       parent_rate = __clk_round_rate(parent, rate);
+               else
+                       parent_rate = __clk_get_rate(parent);
+               child_rate = sun6i_ahb1_clk_round(rate, NULL, NULL, i,
+                                                 parent_rate);
+               if (child_rate <= rate && child_rate > best_child_rate) {
+                       best_parent = parent;
+                       best = parent_rate;
+                       best_child_rate = child_rate;
+               }
+       }
+       if (best_parent)
+               *best_parent_clk = __clk_get_hw(best_parent);
+       *best_parent_rate = best;
+       return best_child_rate;
+ }
+ static int sun6i_ahb1_clk_set_rate(struct clk_hw *hw, unsigned long rate,
+                                  unsigned long parent_rate)
+ {
+       struct sun6i_ahb1_clk *ahb1 = to_sun6i_ahb1_clk(hw);
+       unsigned long flags;
+       u8 div, pre_div, parent;
+       u32 reg;
+       spin_lock_irqsave(&clk_lock, flags);
+       reg = readl(ahb1->reg);
+       /* need to know which parent is used to apply pre-divider */
+       parent = SUN6I_AHB1_MUX_GET_PARENT(reg);
+       sun6i_ahb1_clk_round(rate, &div, &pre_div, parent, parent_rate);
+       reg = SUN6I_AHB1_DIV_SET(reg, div);
+       reg = SUN6I_AHB1_PLL6_DIV_SET(reg, pre_div);
+       writel(reg, ahb1->reg);
+       spin_unlock_irqrestore(&clk_lock, flags);
+       return 0;
+ }
+ static const struct clk_ops sun6i_ahb1_clk_ops = {
+       .determine_rate = sun6i_ahb1_clk_determine_rate,
+       .recalc_rate    = sun6i_ahb1_clk_recalc_rate,
+       .set_rate       = sun6i_ahb1_clk_set_rate,
+ };
+ static void __init sun6i_ahb1_clk_setup(struct device_node *node)
+ {
+       struct clk *clk;
+       struct sun6i_ahb1_clk *ahb1;
+       struct clk_mux *mux;
+       const char *clk_name = node->name;
+       const char *parents[SUN6I_AHB1_MAX_PARENTS];
+       void __iomem *reg;
+       int i = 0;
+       reg = of_io_request_and_map(node, 0, of_node_full_name(node));
+       /* we have a mux, we will have >1 parents */
+       while (i < SUN6I_AHB1_MAX_PARENTS &&
+              (parents[i] = of_clk_get_parent_name(node, i)) != NULL)
+               i++;
+       of_property_read_string(node, "clock-output-names", &clk_name);
+       ahb1 = kzalloc(sizeof(struct sun6i_ahb1_clk), GFP_KERNEL);
+       if (!ahb1)
+               return;
+       mux = kzalloc(sizeof(struct clk_mux), GFP_KERNEL);
+       if (!mux) {
+               kfree(ahb1);
+               return;
+       }
+       /* set up clock properties */
+       mux->reg = reg;
+       mux->shift = SUN6I_AHB1_MUX_SHIFT;
+       mux->mask = SUN6I_AHB1_MUX_MASK;
+       mux->lock = &clk_lock;
+       ahb1->reg = reg;
+       clk = clk_register_composite(NULL, clk_name, parents, i,
+                                    &mux->hw, &clk_mux_ops,
+                                    &ahb1->hw, &sun6i_ahb1_clk_ops,
+                                    NULL, NULL, 0);
+       if (!IS_ERR(clk)) {
+               of_clk_add_provider(node, of_clk_src_simple_get, clk);
+               clk_register_clkdev(clk, clk_name, NULL);
+       }
+ }
+ CLK_OF_DECLARE(sun6i_a31_ahb1, "allwinner,sun6i-a31-ahb1-clk", sun6i_ahb1_clk_setup);
  /* Maximum number of parents our clocks have */
  #define SUNXI_MAX_PARENTS     5
  
@@@ -354,43 -564,6 +564,6 @@@ static void sun7i_a20_get_out_factors(u
        *p = calcp;
  }
  
- /**
-  * clk_sunxi_mmc_phase_control() - configures MMC clock phase control
-  */
- void clk_sunxi_mmc_phase_control(struct clk *clk, u8 sample, u8 output)
- {
-       #define to_clk_composite(_hw) container_of(_hw, struct clk_composite, hw)
-       #define to_clk_factors(_hw) container_of(_hw, struct clk_factors, hw)
-       struct clk_hw *hw = __clk_get_hw(clk);
-       struct clk_composite *composite = to_clk_composite(hw);
-       struct clk_hw *rate_hw = composite->rate_hw;
-       struct clk_factors *factors = to_clk_factors(rate_hw);
-       unsigned long flags = 0;
-       u32 reg;
-       if (factors->lock)
-               spin_lock_irqsave(factors->lock, flags);
-       reg = readl(factors->reg);
-       /* set sample clock phase control */
-       reg &= ~(0x7 << 20);
-       reg |= ((sample & 0x7) << 20);
-       /* set output clock phase control */
-       reg &= ~(0x7 << 8);
-       reg |= ((output & 0x7) << 8);
-       writel(reg, factors->reg);
-       if (factors->lock)
-               spin_unlock_irqrestore(factors->lock, flags);
- }
- EXPORT_SYMBOL(clk_sunxi_mmc_phase_control);
  /**
   * sunxi_factors_clk_setup() - Setup function for factor clocks
   */
@@@ -413,6 -586,7 +586,7 @@@ static struct clk_factors_config sun6i_
        .kwidth = 2,
        .mshift = 0,
        .mwidth = 2,
+       .n_start = 1,
  };
  
  static struct clk_factors_config sun8i_a23_pll1_config = {
@@@ -520,7 -694,16 +694,16 @@@ static const struct factors_data sun7i_
  static struct clk * __init sunxi_factors_clk_setup(struct device_node *node,
                                                   const struct factors_data *data)
  {
-       return sunxi_factors_register(node, data, &clk_lock);
+       void __iomem *reg;
+       reg = of_iomap(node, 0);
+       if (!reg) {
+               pr_err("Could not get registers for factors-clk: %s\n",
+                      node->name);
+               return NULL;
+       }
+       return sunxi_factors_register(node, data, &clk_lock, reg);
  }
  
  
@@@ -561,7 -744,7 +744,7 @@@ static void __init sunxi_mux_clk_setup(
        of_property_read_string(node, "clock-output-names", &clk_name);
  
        clk = clk_register_mux(NULL, clk_name, parents, i,
-                              CLK_SET_RATE_NO_REPARENT, reg,
+                              CLK_SET_RATE_PARENT, reg,
                               data->shift, SUNXI_MUX_GATE_WIDTH,
                               0, &clk_lock);
  
@@@ -1217,7 -1400,6 +1400,6 @@@ CLK_OF_DECLARE(sun7i_a20_clk_init, "all
  
  static const char *sun6i_critical_clocks[] __initdata = {
        "cpu",
-       "ahb1_sdram",
  };
  
  static void __init sun6i_init_clocks(struct device_node *node)
                          ARRAY_SIZE(sun6i_critical_clocks));
  }
  CLK_OF_DECLARE(sun6i_a31_clk_init, "allwinner,sun6i-a31", sun6i_init_clocks);
 +CLK_OF_DECLARE(sun6i_a31s_clk_init, "allwinner,sun6i-a31s", sun6i_init_clocks);
  CLK_OF_DECLARE(sun8i_a23_clk_init, "allwinner,sun8i-a23", sun6i_init_clocks);
  
  static void __init sun9i_init_clocks(struct device_node *node)
index 6af0a28ba37dd6fe54cc44a4164734597b53886d,c9a6fc0eaa352201fe48898e01a6c25dd587feca..e8a4218b57267f508eb871f216de112e93707d31
@@@ -21,8 -21,6 +21,6 @@@
  #include <linux/err.h>
  
  #include <linux/clk.h>
- #include <linux/clk/sunxi.h>
  #include <linux/gpio.h>
  #include <linux/platform_device.h>
  #include <linux/spinlock.h>
@@@ -229,6 -227,8 +227,8 @@@ struct sunxi_mmc_host 
        /* clock management */
        struct clk      *clk_ahb;
        struct clk      *clk_mmc;
+       struct clk      *clk_sample;
+       struct clk      *clk_output;
  
        /* irq */
        spinlock_t      lock;
@@@ -252,7 -252,7 +252,7 @@@ static int sunxi_mmc_reset_host(struct 
        unsigned long expire = jiffies + msecs_to_jiffies(250);
        u32 rval;
  
 -      mmc_writel(host, REG_CMDR, SDXC_HARDWARE_RESET);
 +      mmc_writel(host, REG_GCTRL, SDXC_HARDWARE_RESET);
        do {
                rval = mmc_readl(host, REG_GCTRL);
        } while (time_before(jiffies, expire) && (rval & SDXC_HARDWARE_RESET));
@@@ -310,9 -310,7 +310,9 @@@ static void sunxi_mmc_init_idma_des(str
        }
  
        pdes[0].config |= SDXC_IDMAC_DES0_FD;
 -      pdes[i - 1].config = SDXC_IDMAC_DES0_OWN | SDXC_IDMAC_DES0_LD;
 +      pdes[i - 1].config |= SDXC_IDMAC_DES0_LD | SDXC_IDMAC_DES0_ER;
 +      pdes[i - 1].config &= ~SDXC_IDMAC_DES0_DIC;
 +      pdes[i - 1].buf_addr_ptr2 = 0;
  
        /*
         * Avoid the io-store starting the idmac hitting io-mem before the
@@@ -572,15 -570,6 +572,15 @@@ static irqreturn_t sunxi_mmc_handle_man
        }
  
        dev_err(mmc_dev(host->mmc), "data error, sending stop command\n");
 +
 +      /*
 +       * We will never have more than one outstanding request,
 +       * and we do not complete the request until after
 +       * we've cleared host->manual_stop_mrq so we do not need to
 +       * spin lock this function.
 +       * Additionally we have wait states within this function
 +       * so having it in a lock is a very bad idea.
 +       */
        sunxi_mmc_send_manual_stop(host, mrq);
  
        spin_lock_irqsave(&host->lock, iflags);
@@@ -653,26 -642,31 +653,31 @@@ static int sunxi_mmc_clk_set_rate(struc
  
        /* determine delays */
        if (rate <= 400000) {
-               oclk_dly = 0;
-               sclk_dly = 7;
+               oclk_dly = 180;
+               sclk_dly = 42;
        } else if (rate <= 25000000) {
-               oclk_dly = 0;
-               sclk_dly = 5;
+               oclk_dly = 180;
+               sclk_dly = 75;
        } else if (rate <= 50000000) {
                if (ios->timing == MMC_TIMING_UHS_DDR50) {
-                       oclk_dly = 2;
-                       sclk_dly = 4;
+                       oclk_dly = 60;
+                       sclk_dly = 120;
                } else {
-                       oclk_dly = 3;
-                       sclk_dly = 5;
+                       oclk_dly = 90;
+                       sclk_dly = 150;
                }
+       } else if (rate <= 100000000) {
+               oclk_dly = 6;
+               sclk_dly = 24;
+       } else if (rate <= 200000000) {
+               oclk_dly = 3;
+               sclk_dly = 12;
        } else {
-               /* rate > 50000000 */
-               oclk_dly = 2;
-               sclk_dly = 4;
+               return -EINVAL;
        }
  
-       clk_sunxi_mmc_phase_control(host->clk_mmc, sclk_dly, oclk_dly);
+       clk_set_phase(host->clk_sample, sclk_dly);
+       clk_set_phase(host->clk_output, oclk_dly);
  
        return sunxi_mmc_oclk_onoff(host, 1);
  }
@@@ -769,7 -763,6 +774,7 @@@ static void sunxi_mmc_request(struct mm
        unsigned long iflags;
        u32 imask = SDXC_INTERRUPT_ERROR_BIT;
        u32 cmd_val = SDXC_START | (cmd->opcode & 0x3f);
 +      bool wait_dma = host->wait_dma;
        int ret;
  
        /* Check for set_ios errors (should never happen) */
                        if (cmd->data->flags & MMC_DATA_WRITE)
                                cmd_val |= SDXC_WRITE;
                        else
 -                              host->wait_dma = true;
 +                              wait_dma = true;
                } else {
                        imask |= SDXC_COMMAND_DONE;
                }
        }
  
        host->mrq = mrq;
 +      host->wait_dma = wait_dma;
        mmc_writel(host, REG_IMASK, host->sdio_imask | imask);
        mmc_writel(host, REG_CARG, cmd->arg);
        mmc_writel(host, REG_CMDR, cmd_val);
@@@ -913,6 -905,18 +918,18 @@@ static int sunxi_mmc_resource_request(s
                return PTR_ERR(host->clk_mmc);
        }
  
+       host->clk_output = devm_clk_get(&pdev->dev, "output");
+       if (IS_ERR(host->clk_output)) {
+               dev_err(&pdev->dev, "Could not get output clock\n");
+               return PTR_ERR(host->clk_output);
+       }
+       host->clk_sample = devm_clk_get(&pdev->dev, "sample");
+       if (IS_ERR(host->clk_sample)) {
+               dev_err(&pdev->dev, "Could not get sample clock\n");
+               return PTR_ERR(host->clk_sample);
+       }
        host->reset = devm_reset_control_get(&pdev->dev, "ahb");
  
        ret = clk_prepare_enable(host->clk_ahb);
                goto error_disable_clk_ahb;
        }
  
+       ret = clk_prepare_enable(host->clk_output);
+       if (ret) {
+               dev_err(&pdev->dev, "Enable output clk err %d\n", ret);
+               goto error_disable_clk_mmc;
+       }
+       ret = clk_prepare_enable(host->clk_sample);
+       if (ret) {
+               dev_err(&pdev->dev, "Enable sample clk err %d\n", ret);
+               goto error_disable_clk_output;
+       }
        if (!IS_ERR(host->reset)) {
                ret = reset_control_deassert(host->reset);
                if (ret) {
                        dev_err(&pdev->dev, "reset err %d\n", ret);
-                       goto error_disable_clk_mmc;
+                       goto error_disable_clk_sample;
                }
        }
  
  error_assert_reset:
        if (!IS_ERR(host->reset))
                reset_control_assert(host->reset);
+ error_disable_clk_sample:
+       clk_disable_unprepare(host->clk_sample);
+ error_disable_clk_output:
+       clk_disable_unprepare(host->clk_output);
  error_disable_clk_mmc:
        clk_disable_unprepare(host->clk_mmc);
  error_disable_clk_ahb: