Merge branch 'akpm' (patches from Andrew)
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 14 Mar 2019 22:10:10 +0000 (15:10 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 14 Mar 2019 22:10:10 +0000 (15:10 -0700)
Merge misc patches from Andrew Morton:

- a little bit more MM

- a few fixups

[ The "little bit more MM" is actually just one of the three patches
  Andrew sent for mm/filemap.c, I'm still mulling over two more of them
  from Josef Bacik     - Linus ]

* emailed patches from Andrew Morton <akpm@linux-foundation.org>:
  include/linux/swap.h: use offsetof() instead of custom __swapoffset macro
  tools/testing/selftests/proc/proc-pid-vm.c: test with vsyscall in mind
  zram: default to lzo-rle instead of lzo
  filemap: pass vm_fault to the mmap ra helpers

393 files changed:
Documentation/acpi/aml-debugger.txt
Documentation/devicetree/bindings/clock/actions,owl-cmu.txt
Documentation/devicetree/bindings/clock/amlogic,gxbb-aoclkc.txt
Documentation/devicetree/bindings/clock/amlogic,gxbb-clkc.txt
Documentation/devicetree/bindings/clock/exynos5433-clock.txt
Documentation/devicetree/bindings/clock/fixed-clock.txt [deleted file]
Documentation/devicetree/bindings/clock/fixed-clock.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/clock/fixed-factor-clock.txt [deleted file]
Documentation/devicetree/bindings/clock/fixed-factor-clock.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/clock/fixed-mmio-clock.txt [new file with mode: 0644]
Documentation/devicetree/bindings/clock/imx8mm-clock.txt [new file with mode: 0644]
Documentation/devicetree/bindings/clock/qcom,rpmcc.txt
Documentation/devicetree/bindings/dma/dma.txt
Documentation/devicetree/bindings/dma/fsl-qdma.txt [new file with mode: 0644]
Documentation/devicetree/bindings/dma/k3dma.txt
Documentation/devicetree/bindings/dma/snps-dma.txt
Documentation/devicetree/bindings/dma/sprd-dma.txt
Documentation/devicetree/bindings/dma/xilinx/xilinx_dma.txt
Documentation/devicetree/bindings/mailbox/xlnx,zynqmp-ipi-mailbox.txt [new file with mode: 0644]
Documentation/devicetree/bindings/net/dsa/dsa.txt
Documentation/devicetree/bindings/pwm/atmel-pwm.txt
Documentation/devicetree/bindings/pwm/pwm-hibvt.txt
Documentation/devicetree/bindings/remoteproc/qcom,adsp-pil.txt
Documentation/devicetree/bindings/remoteproc/qcom,adsp.txt
Documentation/devicetree/bindings/remoteproc/qcom,q6v5.txt
Documentation/driver-api/dmaengine/client.rst
Documentation/driver-api/dmaengine/dmatest.rst
Documentation/driver-model/devres.txt
MAINTAINERS
arch/alpha/include/uapi/asm/socket.h
arch/arm/mach-omap2/omap_hwmod.c
arch/microblaze/kernel/setup.c
arch/mips/include/uapi/asm/socket.h
arch/parisc/include/uapi/asm/socket.h
arch/sparc/include/uapi/asm/socket.h
drivers/acpi/acpi_configfs.c
drivers/acpi/acpi_lpss.c
drivers/acpi/device_sysfs.c
drivers/acpi/nfit/core.c
drivers/acpi/nfit/nfit.h
drivers/acpi/pptt.c
drivers/acpi/sysfs.c
drivers/base/power/domain.c
drivers/base/power/domain_governor.c
drivers/base/power/main.c
drivers/base/power/power.h
drivers/base/power/qos.c
drivers/base/power/runtime.c
drivers/base/power/sysfs.c
drivers/base/power/trace.c
drivers/base/power/wakeup.c
drivers/clk/Kconfig
drivers/clk/Makefile
drivers/clk/actions/Kconfig
drivers/clk/actions/Makefile
drivers/clk/actions/owl-pll.c
drivers/clk/actions/owl-pll.h
drivers/clk/actions/owl-s500.c [new file with mode: 0644]
drivers/clk/at91/clk-audio-pll.c
drivers/clk/at91/clk-programmable.c
drivers/clk/at91/sama5d2.c
drivers/clk/clk-clps711x.c
drivers/clk/clk-devres.c
drivers/clk/clk-fixed-mmio.c [new file with mode: 0644]
drivers/clk/clk-fractional-divider.c
drivers/clk/clk-gpio.c
drivers/clk/clk-highbank.c
drivers/clk/clk-max77686.c
drivers/clk/clk-qoriq.c
drivers/clk/clk-stm32mp1.c
drivers/clk/clk-twl6040.c
drivers/clk/clk.c
drivers/clk/clk.h
drivers/clk/clkdev.c
drivers/clk/imx/Kconfig
drivers/clk/imx/Makefile
drivers/clk/imx/clk-composite-8m.c
drivers/clk/imx/clk-imx51-imx53.c
drivers/clk/imx/clk-imx6q.c
drivers/clk/imx/clk-imx6sx.c
drivers/clk/imx/clk-imx7d.c
drivers/clk/imx/clk-imx7ulp.c
drivers/clk/imx/clk-imx8mm.c [new file with mode: 0644]
drivers/clk/imx/clk-imx8mq.c
drivers/clk/imx/clk-imx8qxp.c
drivers/clk/imx/clk-pll14xx.c [new file with mode: 0644]
drivers/clk/imx/clk-sccg-pll.c
drivers/clk/imx/clk-scu.c
drivers/clk/imx/clk-scu.h
drivers/clk/imx/clk-vf610.c
drivers/clk/imx/clk.h
drivers/clk/ingenic/cgu.c
drivers/clk/ingenic/cgu.h
drivers/clk/ingenic/jz4740-cgu.c
drivers/clk/mediatek/clk-gate.c
drivers/clk/mediatek/clk-gate.h
drivers/clk/mediatek/clk-mt2701.c
drivers/clk/mediatek/clk-mt2712.c
drivers/clk/mediatek/clk-mt6797.c
drivers/clk/mediatek/clk-mt8173.c
drivers/clk/mediatek/clk-mtk.c
drivers/clk/mediatek/clk-mtk.h
drivers/clk/meson/Kconfig
drivers/clk/meson/Makefile
drivers/clk/meson/axg-aoclk.c
drivers/clk/meson/axg-aoclk.h
drivers/clk/meson/axg-audio.c
drivers/clk/meson/axg.c
drivers/clk/meson/clk-dualdiv.c [new file with mode: 0644]
drivers/clk/meson/clk-dualdiv.h [new file with mode: 0644]
drivers/clk/meson/clk-input.c
drivers/clk/meson/clk-input.h [new file with mode: 0644]
drivers/clk/meson/clk-mpll.c
drivers/clk/meson/clk-mpll.h [new file with mode: 0644]
drivers/clk/meson/clk-phase.c
drivers/clk/meson/clk-phase.h [new file with mode: 0644]
drivers/clk/meson/clk-pll.c
drivers/clk/meson/clk-pll.h [new file with mode: 0644]
drivers/clk/meson/clk-regmap.c
drivers/clk/meson/clk-regmap.h
drivers/clk/meson/clk-triphase.c [deleted file]
drivers/clk/meson/clkc-audio.h [deleted file]
drivers/clk/meson/clkc.h [deleted file]
drivers/clk/meson/g12a-aoclk.c [new file with mode: 0644]
drivers/clk/meson/g12a-aoclk.h [new file with mode: 0644]
drivers/clk/meson/g12a.c [new file with mode: 0644]
drivers/clk/meson/g12a.h [new file with mode: 0644]
drivers/clk/meson/gxbb-aoclk-32k.c [deleted file]
drivers/clk/meson/gxbb-aoclk.c
drivers/clk/meson/gxbb-aoclk.h
drivers/clk/meson/gxbb.c
drivers/clk/meson/meson-aoclk.c
drivers/clk/meson/meson-aoclk.h
drivers/clk/meson/meson-eeclk.c [new file with mode: 0644]
drivers/clk/meson/meson-eeclk.h [new file with mode: 0644]
drivers/clk/meson/meson8b.c
drivers/clk/meson/meson8b.h
drivers/clk/meson/parm.h [new file with mode: 0644]
drivers/clk/meson/sclk-div.c
drivers/clk/meson/sclk-div.h [new file with mode: 0644]
drivers/clk/meson/vid-pll-div.c
drivers/clk/meson/vid-pll-div.h [new file with mode: 0644]
drivers/clk/mmp/clk-of-mmp2.c
drivers/clk/mvebu/armada-370.c
drivers/clk/mvebu/armada-xp.c
drivers/clk/mvebu/dove.c
drivers/clk/mvebu/kirkwood.c
drivers/clk/mvebu/mv98dx3236.c
drivers/clk/qcom/clk-rcg.h
drivers/clk/qcom/clk-rcg2.c
drivers/clk/qcom/clk-rpmh.c
drivers/clk/qcom/clk-smd-rpm.c
drivers/clk/qcom/common.c
drivers/clk/qcom/common.h
drivers/clk/qcom/gcc-ipq8074.c
drivers/clk/qcom/gcc-mdm9615.c
drivers/clk/qcom/gcc-msm8996.c
drivers/clk/qcom/gcc-msm8998.c
drivers/clk/qcom/gcc-qcs404.c
drivers/clk/qcom/gcc-sdm660.c
drivers/clk/qcom/gcc-sdm845.c
drivers/clk/qcom/mmcc-msm8996.c
drivers/clk/renesas/r8a774a1-cpg-mssr.c
drivers/clk/renesas/r8a774c0-cpg-mssr.c
drivers/clk/renesas/r8a77980-cpg-mssr.c
drivers/clk/renesas/rcar-gen3-cpg.c
drivers/clk/renesas/rcar-gen3-cpg.h
drivers/clk/rockchip/clk-rk3188.c
drivers/clk/rockchip/clk-rk3328.c
drivers/clk/samsung/clk-exynos4.c
drivers/clk/samsung/clk-exynos5-subcmu.c
drivers/clk/samsung/clk-exynos5433.c
drivers/clk/samsung/clk-s3c2443.c
drivers/clk/samsung/clk.h
drivers/clk/socfpga/clk-gate.c
drivers/clk/socfpga/clk-pll-a10.c
drivers/clk/socfpga/clk-pll.c
drivers/clk/sunxi-ng/ccu-sun8i-a23.c
drivers/clk/tegra/clk-dfll.c
drivers/clk/ti/adpll.c
drivers/clk/ti/apll.c
drivers/clk/ti/autoidle.c
drivers/clk/ti/clk.c
drivers/clk/ti/clkctrl.c
drivers/clk/ti/clock.h
drivers/clk/ti/clockdomain.c
drivers/clk/ti/divider.c
drivers/clk/ti/dpll.c
drivers/clk/ti/dpll3xxx.c
drivers/clk/ti/gate.c
drivers/clk/ti/interface.c
drivers/clk/ti/mux.c
drivers/clk/uniphier/clk-uniphier-cpugear.c
drivers/clk/x86/clk-lpt.c
drivers/clk/x86/clk-st.c
drivers/cpufreq/cpufreq.c
drivers/cpufreq/intel_pstate.c
drivers/cpufreq/pxa2xx-cpufreq.c
drivers/cpuidle/governor.c
drivers/cpuidle/governors/menu.c
drivers/crypto/caam/caamalg.c
drivers/crypto/caam/caamalg_qi.c
drivers/crypto/caam/caamhash.c
drivers/crypto/caam/caampkc.c
drivers/crypto/caam/caamrng.c
drivers/crypto/s5p-sss.c
drivers/dax/super.c
drivers/dma/Kconfig
drivers/dma/Makefile
drivers/dma/at_hdmac.c
drivers/dma/bcm2835-dma.c
drivers/dma/dma-axi-dmac.c
drivers/dma/dma-jz4780.c
drivers/dma/dmatest.c
drivers/dma/dw-axi-dmac/dw-axi-dmac.h
drivers/dma/dw/Kconfig
drivers/dma/dw/Makefile
drivers/dma/dw/core.c
drivers/dma/dw/dw.c [new file with mode: 0644]
drivers/dma/dw/idma32.c [new file with mode: 0644]
drivers/dma/dw/internal.h
drivers/dma/dw/pci.c
drivers/dma/dw/platform.c
drivers/dma/dw/regs.h
drivers/dma/fsl-edma-common.c
drivers/dma/fsl-edma-common.h
drivers/dma/fsl-edma.c
drivers/dma/fsl-qdma.c [new file with mode: 0644]
drivers/dma/fsldma.c
drivers/dma/fsldma.h
drivers/dma/imx-dma.c
drivers/dma/imx-sdma.c
drivers/dma/ioat/dma.c
drivers/dma/ioat/dma.h
drivers/dma/ioat/hw.h
drivers/dma/ioat/init.c
drivers/dma/ioat/registers.h
drivers/dma/k3dma.c
drivers/dma/mcf-edma.c
drivers/dma/mv_xor.c
drivers/dma/pl330.c
drivers/dma/qcom/bam_dma.c
drivers/dma/qcom/hidma.c
drivers/dma/qcom/hidma_mgmt.c
drivers/dma/sa11x0-dma.c
drivers/dma/sh/usb-dmac.c
drivers/dma/sprd-dma.c
drivers/dma/st_fdma.c
drivers/dma/stm32-dma.c
drivers/dma/stm32-dmamux.c
drivers/dma/stm32-mdma.c
drivers/dma/tegra20-apb-dma.c
drivers/dma/tegra210-adma.c
drivers/dma/timb_dma.c
drivers/dma/xilinx/xilinx_dma.c
drivers/isdn/hardware/mISDN/hfcpci.c
drivers/mailbox/Kconfig
drivers/mailbox/Makefile
drivers/mailbox/imx-mailbox.c
drivers/mailbox/mailbox-test.c
drivers/mailbox/stm32-ipcc.c
drivers/mailbox/tegra-hsp.c
drivers/mailbox/zynqmp-ipi-mailbox.c [new file with mode: 0644]
drivers/mtd/ubi/cdev.c
drivers/mtd/ubi/ubi.h
drivers/mtd/ubi/wl.c
drivers/net/ethernet/8390/pcnet_cs.c
drivers/net/ethernet/cavium/liquidio/lio_core.c
drivers/net/ethernet/cavium/liquidio/lio_main.c
drivers/net/ethernet/cavium/thunder/nicvf_main.c
drivers/net/ethernet/fujitsu/fmvj18x_cs.c
drivers/net/ethernet/mellanox/mlx4/cmd.c
drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
drivers/net/ethernet/mellanox/mlx5/core/fs_core.h
drivers/net/ethernet/mellanox/mlx5/core/lag.c
drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h
drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
drivers/net/ethernet/mellanox/mlxsw/minimal.c
drivers/net/ethernet/microchip/lan743x_main.c
drivers/net/ethernet/qlogic/qla3xxx.c
drivers/net/ethernet/qlogic/qlge/qlge_main.c
drivers/net/ethernet/renesas/sh_eth.c
drivers/net/ethernet/rocker/rocker_main.c
drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
drivers/net/ppp/pptp.c
drivers/nvdimm/btt.c
drivers/nvdimm/btt.h
drivers/nvdimm/btt_devs.c
drivers/nvdimm/dimm_devs.c
drivers/nvdimm/label.c
drivers/nvdimm/namespace_devs.c
drivers/nvdimm/of_pmem.c
drivers/nvdimm/pfn_devs.c
drivers/nvdimm/region_devs.c
drivers/opp/core.c
drivers/opp/of.c
drivers/pwm/Kconfig
drivers/pwm/Makefile
drivers/pwm/core.c
drivers/pwm/pwm-atmel.c
drivers/pwm/pwm-bcm-kona.c
drivers/pwm/pwm-hibvt.c
drivers/pwm/pwm-imx.c [deleted file]
drivers/pwm/pwm-imx1.c [new file with mode: 0644]
drivers/pwm/pwm-imx27.c [new file with mode: 0644]
drivers/pwm/pwm-mtk-disp.c
drivers/pwm/pwm-rcar.c
drivers/remoteproc/qcom_q6v5_adsp.c
drivers/remoteproc/qcom_q6v5_mss.c
drivers/remoteproc/qcom_q6v5_pas.c
drivers/remoteproc/qcom_sysmon.c
drivers/remoteproc/qcom_wcnss.c
drivers/remoteproc/remoteproc_core.c
drivers/remoteproc/remoteproc_debugfs.c
drivers/remoteproc/remoteproc_internal.h
drivers/remoteproc/remoteproc_virtio.c
drivers/remoteproc/st_remoteproc.c
drivers/rpmsg/virtio_rpmsg_bus.c
drivers/tty/serial/8250/8250_lpss.c
fs/dax.c
fs/ubifs/ioctl.c
include/dt-bindings/clock/actions,s500-cmu.h [new file with mode: 0644]
include/dt-bindings/clock/axg-aoclkc.h
include/dt-bindings/clock/exynos5433.h
include/dt-bindings/clock/g12a-aoclkc.h [new file with mode: 0644]
include/dt-bindings/clock/g12a-clkc.h [new file with mode: 0644]
include/dt-bindings/clock/gxbb-aoclkc.h
include/dt-bindings/clock/imx5-clock.h
include/dt-bindings/clock/imx8mm-clock.h [new file with mode: 0644]
include/dt-bindings/clock/imx8mq-clock.h
include/dt-bindings/clock/marvell,mmp2.h
include/dt-bindings/clock/meson8b-clkc.h
include/dt-bindings/clock/mt2712-clk.h
include/dt-bindings/clock/mt8173-clk.h
include/dt-bindings/clock/qcom,rpmcc.h
include/dt-bindings/clock/qcom,rpmh.h
include/dt-bindings/clock/r8a774a1-cpg-mssr.h
include/dt-bindings/clock/r8a774c0-cpg-mssr.h
include/dt-bindings/clock/stm32mp1-clks.h
include/dt-bindings/reset/g12a-aoclkc.h [new file with mode: 0644]
include/linux/clk-provider.h
include/linux/clk.h
include/linux/clk/ti.h
include/linux/clkdev.h
include/linux/dma/dw.h
include/linux/libnvdimm.h
include/linux/mailbox/zynqmp-ipi-message.h [new file with mode: 0644]
include/linux/platform_data/clk-lpss.h [deleted file]
include/linux/platform_data/dma-dw.h
include/linux/platform_data/dma-imx.h
include/linux/platform_data/x86/clk-lpss.h [new file with mode: 0644]
include/linux/pm.h
include/linux/pm_wakeup.h
include/linux/pwm.h
include/linux/remoteproc.h
include/net/netfilter/nf_tables.h
include/trace/events/tegra_apb_dma.h [new file with mode: 0644]
include/uapi/asm-generic/socket.h
include/uapi/linux/ndctl.h
include/uapi/mtd/ubi-user.h
net/ipv4/tcp_ipv4.c
net/ipv6/sit.c
net/l2tp/l2tp_ip6.c
net/netfilter/nf_nat_masquerade.c
net/netfilter/nf_tables_api.c
net/netfilter/nft_dynset.c
net/netfilter/nft_lookup.c
net/netfilter/nft_objref.c
net/sched/cls_api.c
net/sched/sch_api.c
net/tls/tls_device.c
net/tls/tls_main.c
net/x25/af_x25.c
scripts/kconfig/Makefile
scripts/kconfig/expr.h
scripts/kconfig/lexer.l [new file with mode: 0644]
scripts/kconfig/lkc.h
scripts/kconfig/parser.y [new file with mode: 0644]
scripts/kconfig/qconf.cc
scripts/kconfig/qconf.h
scripts/kconfig/zconf.l [deleted file]
scripts/kconfig/zconf.y [deleted file]
security/apparmor/apparmorfs.c
security/apparmor/policy_unpack.c
security/selinux/hooks.c
tools/power/cpupower/lib/cpufreq.c
tools/power/cpupower/lib/cpufreq.h
tools/power/cpupower/utils/cpufreq-info.c

index e851cc5de63f29e8e8b89bc9c5f95e660f51f856..75ebeb64ab29a8806776f41901859495a1c52d64 100644 (file)
@@ -23,7 +23,7 @@ kernel.
 
    The resultant userspace tool binary is then located at:
 
-     tools/acpi/power/acpi/acpidbg/acpidbg
+     tools/power/acpi/acpidbg
 
    It can be installed to system directories by running "make install" (as a
    sufficiently privileged user).
@@ -35,7 +35,7 @@ kernel.
 
    # mount -t debugfs none /sys/kernel/debug
    # modprobe acpi_dbg
-   # tools/acpi/power/acpi/acpidbg/acpidbg
+   # tools/power/acpi/acpidbg
 
    That spawns the interactive AML debugger environment where you can execute
    debugger commands.
index 2ef86ae96df8cb1ad98b39d92f8b7e7213a67134..d19885b7c73fc6aa21bfe124bbdad2341fcbe155 100644 (file)
@@ -2,13 +2,14 @@
 
 The Actions Semi Owl Clock Management Unit generates and supplies clock
 to various controllers within the SoC. The clock binding described here is
-applicable to S900 and S700 SoC's.
+applicable to S900, S700 and S500 SoC's.
 
 Required Properties:
 
 - compatible: should be one of the following,
        "actions,s900-cmu"
        "actions,s700-cmu"
+       "actions,s500-cmu"
 - reg: physical base address of the controller and length of memory mapped
   region.
 - clocks: Reference to the parent clocks ("hosc", "losc")
@@ -19,8 +20,8 @@ Each clock is assigned an identifier, and client nodes can use this identifier
 to specify the clock which they consume.
 
 All available clocks are defined as preprocessor macros in corresponding
-dt-bindings/clock/actions,s900-cmu.h or actions,s700-cmu.h header and can be
-used in device tree sources.
+dt-bindings/clock/actions,s900-cmu.h or actions,s700-cmu.h or
+actions,s500-cmu.h header and can be used in device tree sources.
 
 External clocks:
 
index 79511d7bb321831c7909928b0f20b6b4aa6d142c..c41f0be5d4384c93bc223f4cd0c454831c885146 100644 (file)
@@ -10,6 +10,7 @@ Required Properties:
        - GXL (S905X, S905D) : "amlogic,meson-gxl-aoclkc"
        - GXM (S912) : "amlogic,meson-gxm-aoclkc"
        - AXG (A113D, A113X) : "amlogic,meson-axg-aoclkc"
+       - G12A (S905X2, S905D2, S905Y2) : "amlogic,meson-g12a-aoclkc"
        followed by the common "amlogic,meson-gx-aoclkc"
 - clocks: list of clock phandle, one for each entry clock-names.
 - clock-names: should contain the following:
index a6871953bf0448a1317a31140ec546929f04cab1..5c8b105be4d66a8de398c1f4330e469892414ac9 100644 (file)
@@ -9,6 +9,7 @@ Required Properties:
                "amlogic,gxbb-clkc" for GXBB SoC,
                "amlogic,gxl-clkc" for GXL and GXM SoC,
                "amlogic,axg-clkc" for AXG SoC.
+               "amlogic,g12a-clkc" for G12A SoC.
 - clocks : list of clock phandle, one for each entry clock-names.
 - clock-names : should contain the following:
   * "xtal": the platform xtal
index 50d5897c9849134cd9ebc30f5780de05ab5190e2..183c327a7d6bddc05862bddb060a7e36c2b3938b 100644 (file)
@@ -50,6 +50,8 @@ Required Properties:
     IPs.
   - "samsung,exynos5433-cmu-cam1" - clock controller compatible for CMU_CAM1
     which generates clocks for Cortex-A5/MIPI_CSIS2/FIMC-LITE_C/FIMC-FD IPs.
+  - "samsung,exynos5433-cmu-imem"   - clock controller compatible for CMU_IMEM
+    which generates clocks for SSS (Security SubSystem) and SlimSSS IPs.
 
 - reg: physical base address of the controller and length of memory mapped
   region.
@@ -168,6 +170,12 @@ Required Properties:
                - aclk_cam1_400
                - aclk_cam1_552
 
+       Input clocks for imem clock controller:
+               - oscclk
+               - aclk_imem_sssx_266
+               - aclk_imem_266
+               - aclk_imem_200
+
 Optional properties:
   - power-domains: a phandle to respective power domain node as described by
        generic PM domain bindings (see power/power_domain.txt for more
@@ -469,6 +477,21 @@ Example 2: Examples of clock controller nodes are listed below.
                power-domains = <&pd_cam1>;
        };
 
+       cmu_imem: clock-controller@11060000 {
+               compatible = "samsung,exynos5433-cmu-imem";
+               reg = <0x11060000 0x1000>;
+               #clock-cells = <1>;
+
+               clock-names = "oscclk",
+                       "aclk_imem_sssx_266",
+                       "aclk_imem_266",
+                       "aclk_imem_200";
+               clocks = <&xxti>,
+                       <&cmu_top CLK_DIV_ACLK_IMEM_SSSX_266>,
+                       <&cmu_top CLK_DIV_ACLK_IMEM_266>,
+                       <&cmu_top CLK_DIV_ACLK_IMEM_200>;
+       };
+
 Example 3: UART controller node that consumes the clock generated by the clock
           controller.
 
diff --git a/Documentation/devicetree/bindings/clock/fixed-clock.txt b/Documentation/devicetree/bindings/clock/fixed-clock.txt
deleted file mode 100644 (file)
index 0641a66..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-Binding for simple fixed-rate clock sources.
-
-This binding uses the common clock binding[1].
-
-[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
-
-Required properties:
-- compatible : shall be "fixed-clock".
-- #clock-cells : from common clock binding; shall be set to 0.
-- clock-frequency : frequency of clock in Hz. Should be a single cell.
-
-Optional properties:
-- clock-accuracy : accuracy of clock in ppb (parts per billion).
-                  Should be a single cell.
-- clock-output-names : From common clock binding.
-
-Example:
-       clock {
-               compatible = "fixed-clock";
-               #clock-cells = <0>;
-               clock-frequency = <1000000000>;
-               clock-accuracy = <100>;
-       };
diff --git a/Documentation/devicetree/bindings/clock/fixed-clock.yaml b/Documentation/devicetree/bindings/clock/fixed-clock.yaml
new file mode 100644 (file)
index 0000000..b657ecd
--- /dev/null
@@ -0,0 +1,44 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/fixed-clock.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Binding for simple fixed-rate clock sources
+
+maintainers:
+  - Michael Turquette <mturquette@baylibre.com>
+  - Stephen Boyd <sboyd@kernel.org>
+
+properties:
+  compatible:
+    const: fixed-clock
+
+  "#clock-cells":
+    const: 0
+
+  clock-frequency: true
+
+  clock-accuracy:
+    description: accuracy of clock in ppb (parts per billion).
+    $ref: /schemas/types.yaml#/definitions/uint32
+
+  clock-output-names:
+    maxItems: 1
+
+required:
+  - compatible
+  - "#clock-cells"
+  - clock-frequency
+
+additionalProperties: false
+
+examples:
+  - |
+    clock {
+      compatible = "fixed-clock";
+      #clock-cells = <0>;
+      clock-frequency = <1000000000>;
+      clock-accuracy = <100>;
+    };
+...
diff --git a/Documentation/devicetree/bindings/clock/fixed-factor-clock.txt b/Documentation/devicetree/bindings/clock/fixed-factor-clock.txt
deleted file mode 100644 (file)
index 189467a..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-Binding for simple fixed factor rate clock sources.
-
-This binding uses the common clock binding[1].
-
-[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
-
-Required properties:
-- compatible : shall be "fixed-factor-clock".
-- #clock-cells : from common clock binding; shall be set to 0.
-- clock-div: fixed divider.
-- clock-mult: fixed multiplier.
-- clocks: parent clock.
-
-Optional properties:
-- clock-output-names : From common clock binding.
-
-Some clocks that require special treatments are also handled by that
-driver, with the compatibles:
-  - allwinner,sun4i-a10-pll3-2x-clk
-
-Example:
-       clock {
-               compatible = "fixed-factor-clock";
-               clocks = <&parentclk>;
-               #clock-cells = <0>;
-               clock-div = <2>;
-               clock-mult = <1>;
-       };
diff --git a/Documentation/devicetree/bindings/clock/fixed-factor-clock.yaml b/Documentation/devicetree/bindings/clock/fixed-factor-clock.yaml
new file mode 100644 (file)
index 0000000..b567f80
--- /dev/null
@@ -0,0 +1,56 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/fixed-factor-clock.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Binding for simple fixed factor rate clock sources
+
+maintainers:
+  - Michael Turquette <mturquette@baylibre.com>
+  - Stephen Boyd <sboyd@kernel.org>
+
+properties:
+  compatible:
+    enum:
+      - allwinner,sun4i-a10-pll3-2x-clk
+      - fixed-factor-clock
+
+  "#clock-cells":
+    const: 0
+
+  clocks:
+    maxItems: 1
+
+  clock-div:
+    description: Fixed divider
+    allOf:
+      - $ref: /schemas/types.yaml#/definitions/uint32
+      - minimum: 1
+
+  clock-mult:
+    description: Fixed multiplier
+    $ref: /schemas/types.yaml#/definitions/uint32
+
+  clock-output-names:
+    maxItems: 1
+
+required:
+  - compatible
+  - clocks
+  - "#clock-cells"
+  - clock-div
+  - clock-mult
+
+additionalProperties: false
+
+examples:
+  - |
+    clock {
+      compatible = "fixed-factor-clock";
+      clocks = <&parentclk>;
+      #clock-cells = <0>;
+      clock-div = <2>;
+      clock-mult = <1>;
+    };
+...
diff --git a/Documentation/devicetree/bindings/clock/fixed-mmio-clock.txt b/Documentation/devicetree/bindings/clock/fixed-mmio-clock.txt
new file mode 100644 (file)
index 0000000..c359367
--- /dev/null
@@ -0,0 +1,24 @@
+Binding for simple memory mapped io fixed-rate clock sources.
+The driver reads a clock frequency value from a single 32-bit memory mapped
+I/O register and registers it as a fixed rate clock.
+
+It was designed for test systems, like FPGA, not for complete, finished SoCs.
+
+This binding uses the common clock binding[1].
+
+[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
+
+Required properties:
+- compatible : shall be "fixed-mmio-clock".
+- #clock-cells : from common clock binding; shall be set to 0.
+- reg : Address and length of the clock value register set.
+
+Optional properties:
+- clock-output-names : From common clock binding.
+
+Example:
+sysclock: sysclock@fd020004 {
+       #clock-cells = <0>;
+       compatible = "fixed-mmio-clock";
+       reg = <0xfd020004 0x4>;
+};
diff --git a/Documentation/devicetree/bindings/clock/imx8mm-clock.txt b/Documentation/devicetree/bindings/clock/imx8mm-clock.txt
new file mode 100644 (file)
index 0000000..8e4ab9e
--- /dev/null
@@ -0,0 +1,29 @@
+* Clock bindings for NXP i.MX8M Mini
+
+Required properties:
+- compatible: Should be "fsl,imx8mm-ccm"
+- reg: Address and length of the register set
+- #clock-cells: Should be <1>
+- clocks: list of clock specifiers, must contain an entry for each required
+          entry in clock-names
+- clock-names: should include the following entries:
+    - "osc_32k"
+    - "osc_24m"
+    - "clk_ext1"
+    - "clk_ext2"
+    - "clk_ext3"
+    - "clk_ext4"
+
+clk: clock-controller@30380000 {
+       compatible = "fsl,imx8mm-ccm";
+       reg = <0x0 0x30380000 0x0 0x10000>;
+       #clock-cells = <1>;
+       clocks = <&osc_32k>, <&osc_24m>, <&clk_ext1>, <&clk_ext2>,
+                <&clk_ext3>, <&clk_ext4>;
+       clock-names = "osc_32k", "osc_24m", "clk_ext1", "clk_ext2",
+                     "clk_ext3", "clk_ext4";
+};
+
+The clock consumer should specify the desired clock by having the clock
+ID in its "clocks" phandle cell. See include/dt-bindings/clock/imx8mm-clock.h
+for the full list of i.MX8M Mini clock IDs.
index 87b4949e9bc8e81c2cdaa5b8de040be571da006f..944719bd586f7f4e9a4a5e207affe26a1b60d51e 100644 (file)
@@ -16,6 +16,7 @@ Required properties :
                        "qcom,rpmcc-msm8974", "qcom,rpmcc"
                        "qcom,rpmcc-apq8064", "qcom,rpmcc"
                        "qcom,rpmcc-msm8996", "qcom,rpmcc"
+                       "qcom,rpmcc-msm8998", "qcom,rpmcc"
                        "qcom,rpmcc-qcs404", "qcom,rpmcc"
 
 - #clock-cells : shall contain 1
index 6312fb00ce8d31d0c8c455af0e82e3a3d86ff008..eeb4e4d1771ed42c33951d6f326f434b0607fb5a 100644 (file)
@@ -16,6 +16,9 @@ Optional properties:
 - dma-channels:        Number of DMA channels supported by the controller.
 - dma-requests:        Number of DMA request signals supported by the
                        controller.
+- dma-channel-mask:    Bitmask of available DMA channels in ascending order
+                       that are not reserved by firmware and are available to
+                       the kernel. i.e. first channel corresponds to LSB.
 
 Example:
 
@@ -29,6 +32,7 @@ Example:
                #dma-cells = <1>;
                dma-channels = <32>;
                dma-requests = <127>;
+               dma-channel-mask = <0xfffe>
        };
 
 * DMA router
diff --git a/Documentation/devicetree/bindings/dma/fsl-qdma.txt b/Documentation/devicetree/bindings/dma/fsl-qdma.txt
new file mode 100644 (file)
index 0000000..6a0ff90
--- /dev/null
@@ -0,0 +1,57 @@
+NXP Layerscape SoC qDMA Controller
+==================================
+
+This device follows the generic DMA bindings defined in dma/dma.txt.
+
+Required properties:
+
+- compatible:          Must be one of
+                        "fsl,ls1021a-qdma": for LS1021A Board
+                        "fsl,ls1043a-qdma": for ls1043A Board
+                        "fsl,ls1046a-qdma": for ls1046A Board
+- reg:                 Should contain the register's base address and length.
+- interrupts:          Should contain a reference to the interrupt used by this
+                       device.
+- interrupt-names:     Should contain interrupt names:
+                        "qdma-queue0": the block0 interrupt
+                        "qdma-queue1": the block1 interrupt
+                        "qdma-queue2": the block2 interrupt
+                        "qdma-queue3": the block3 interrupt
+                        "qdma-error":  the error interrupt
+- fsl,dma-queues:      Should contain number of queues supported.
+- dma-channels:        Number of DMA channels supported
+- block-number:        the virtual block number
+- block-offset:        the offset of different virtual block
+- status-sizes:        status queue size of per virtual block
+- queue-sizes:         command queue size of per virtual block, the size number
+                       based on queues
+
+Optional properties:
+
+- dma-channels:                Number of DMA channels supported by the controller.
+- big-endian:          If present registers and hardware scatter/gather descriptors
+                       of the qDMA are implemented in big endian mode, otherwise in little
+                       mode.
+
+Examples:
+
+       qdma: dma-controller@8390000 {
+                       compatible = "fsl,ls1021a-qdma";
+                       reg = <0x0 0x8388000 0x0 0x1000>, /* Controller regs */
+                             <0x0 0x8389000 0x0 0x1000>, /* Status regs */
+                             <0x0 0x838a000 0x0 0x2000>; /* Block regs */
+                       interrupts = <GIC_SPI 185 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "qdma-error",
+                               "qdma-queue0", "qdma-queue1";
+                       dma-channels = <8>;
+                       block-number = <2>;
+                       block-offset = <0x1000>;
+                       fsl,dma-queues = <2>;
+                       status-sizes = <64>;
+                       queue-sizes = <64 64>;
+                       big-endian;
+               };
+
+DMA clients must use the format described in dma/dma.txt file.
index 4945aeac4dc4f0b12499a6b947227fcf785325f5..10a2f15b08a38305e1508c6b04cf600e71f91190 100644 (file)
@@ -3,7 +3,9 @@
 See dma.txt first
 
 Required properties:
-- compatible: Should be "hisilicon,k3-dma-1.0"
+- compatible: Must be one of
+-              "hisilicon,k3-dma-1.0"
+-              "hisilicon,hisi-pcm-asp-dma-1.0"
 - reg: Should contain DMA registers location and length.
 - interrupts: Should contain one interrupt shared by all channel
 - #dma-cells: see dma.txt, should be 1, para number
index db757df7057df69f6f95d4c54f3bc141affd78ed..0bedceed1963548a938db67e7a1ce66b85f63cac 100644 (file)
@@ -23,8 +23,6 @@ Deprecated properties:
 
 
 Optional properties:
-- is_private: The device channels should be marked as private and not for by the
-  general purpose DMA channel allocator. False if not passed.
 - multi-block: Multi block transfers supported by hardware. Array property with
   one cell per channel. 0: not supported, 1 (default): supported.
 - snps,dma-protection-control: AHB HPROT[3:1] protection setting.
index 7a10fea2e51bdfd1f2d7578781a07d701d3496c9..adccea9941f1bc493c382e9ef146e2b38bfb2934 100644 (file)
@@ -31,7 +31,7 @@ DMA clients connected to the Spreadtrum DMA controller must use the format
 described in the dma.txt file, using a two-cell specifier for each channel.
 The two cells in order are:
 1. A phandle pointing to the DMA controller.
-2. The channel id.
+2. The slave id.
 
 spi0: spi@70a00000{
        ...
index 174af2c45e7774ca5c15de325d4db580cca694e5..93b6d961dd4fa81b155813c2cac3e4f46696b333 100644 (file)
@@ -37,10 +37,11 @@ Required properties:
 Required properties for VDMA:
 - xlnx,num-fstores: Should be the number of framebuffers as configured in h/w.
 
-Optional properties:
-- xlnx,include-sg: Tells configured for Scatter-mode in
-       the hardware.
 Optional properties for AXI DMA:
+- xlnx,sg-length-width: Should be set to the width in bits of the length
+       register as configured in h/w. Takes values {8...26}. If the property
+       is missing or invalid then the default value 23 is used. This is the
+       maximum value that is supported by all IP versions.
 - xlnx,mcdma: Tells whether configured for multi-channel mode in the hardware.
 Optional properties for VDMA:
 - xlnx,flush-fsync: Tells which channel to Flush on Frame sync.
diff --git a/Documentation/devicetree/bindings/mailbox/xlnx,zynqmp-ipi-mailbox.txt b/Documentation/devicetree/bindings/mailbox/xlnx,zynqmp-ipi-mailbox.txt
new file mode 100644 (file)
index 0000000..4438432
--- /dev/null
@@ -0,0 +1,127 @@
+Xilinx IPI Mailbox Controller
+========================================
+
+The Xilinx IPI(Inter Processor Interrupt) mailbox controller is to manage
+messaging between two Xilinx Zynq UltraScale+ MPSoC IPI agents. Each IPI
+agent owns registers used for notification and buffers for message.
+
+               +-------------------------------------+
+               | Xilinx ZynqMP IPI Controller        |
+               +-------------------------------------+
+    +--------------------------------------------------+
+ATF                    |                     |
+                       |                     |
+                       |                     |
+    +--------------------------+             |
+                       |                     |
+                       |                     |
+    +--------------------------------------------------+
+            +------------------------------------------+
+            |  +----------------+   +----------------+ |
+Hardware    |  |  IPI Agent     |   |  IPI Buffers   | |
+            |  |  Registers     |   |                | |
+            |  |                |   |                | |
+            |  +----------------+   +----------------+ |
+            |                                          |
+            | Xilinx IPI Agent Block                   |
+            +------------------------------------------+
+
+
+Controller Device Node:
+===========================
+Required properties:
+--------------------
+IPI agent node:
+- compatible:          Shall be: "xlnx,zynqmp-ipi-mailbox"
+- interrupt-parent:    Phandle for the interrupt controller
+- interrupts:          Interrupt information corresponding to the
+                       interrupt-names property.
+- xlnx,ipi-id:         local Xilinx IPI agent ID
+- #address-cells:      number of address cells of internal IPI mailbox nodes
+- #size-cells:         number of size cells of internal IPI mailbox nodes
+
+Internal IPI mailbox node:
+- reg:                 IPI buffers address ranges
+- reg-names:           Names of the reg resources. It should have:
+                       * local_request_region
+                         - IPI request msg buffer written by local and read
+                           by remote
+                       * local_response_region
+                         - IPI response msg buffer written by local and read
+                           by remote
+                       * remote_request_region
+                         - IPI request msg buffer written by remote and read
+                           by local
+                       * remote_response_region
+                         - IPI response msg buffer written by remote and read
+                           by local
+- #mbox-cells:         Shall be 1. It contains:
+                       * tx(0) or rx(1) channel
+- xlnx,ipi-id:         remote Xilinx IPI agent ID of which the mailbox is
+                       connected to.
+
+Optional properties:
+--------------------
+- method:              The method of accessing the IPI agent registers.
+                       Permitted values are: "smc" and "hvc". Default is
+                       "smc".
+
+Client Device Node:
+===========================
+Required properties:
+--------------------
+- mboxes:              Standard property to specify a mailbox
+                       (See ./mailbox.txt)
+- mbox-names:          List of identifier  strings for each mailbox
+                       channel.
+
+Example:
+===========================
+       zynqmp_ipi {
+               compatible = "xlnx,zynqmp-ipi-mailbox";
+               interrupt-parent = <&gic>;
+               interrupts = <0 29 4>;
+               xlnx,ipi-id = <0>;
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges;
+
+               /* APU<->RPU0 IPI mailbox controller */
+               ipi_mailbox_rpu0: mailbox@ff90400 {
+                       reg = <0xff990400 0x20>,
+                             <0xff990420 0x20>,
+                             <0xff990080 0x20>,
+                             <0xff9900a0 0x20>;
+                       reg-names = "local_request_region",
+                                   "local_response_region",
+                                   "remote_request_region",
+                                   "remote_response_region";
+                       #mbox-cells = <1>;
+                       xlnx,ipi-id = <1>;
+               };
+               /* APU<->RPU1 IPI mailbox controller */
+               ipi_mailbox_rpu1: mailbox@ff990440 {
+                       reg = <0xff990440 0x20>,
+                             <0xff990460 0x20>,
+                             <0xff990280 0x20>,
+                             <0xff9902a0 0x20>;
+                       reg-names = "local_request_region",
+                                   "local_response_region",
+                                   "remote_request_region",
+                                   "remote_response_region";
+                       #mbox-cells = <1>;
+                       xlnx,ipi-id = <2>;
+               };
+       };
+       rpu0 {
+               ...
+               mboxes = <&ipi_mailbox_rpu0 0>,
+                        <&ipi_mailbox_rpu0 1>;
+               mbox-names = "tx", "rx";
+       };
+       rpu1 {
+               ...
+               mboxes = <&ipi_mailbox_rpu1 0>,
+                        <&ipi_mailbox_rpu1 1>;
+               mbox-names = "tx", "rx";
+       };
index 35694c0c376b91c8b51982d1dce992682b983d92..d66a5292b9d326cc7d4a68062fd4bfb9f3adb256 100644 (file)
@@ -71,6 +71,10 @@ properties, described in binding documents:
                          Documentation/devicetree/bindings/net/fixed-link.txt
                          for details.
 
+- local-mac-address    : See
+                         Documentation/devicetree/bindings/net/ethernet.txt
+                         for details.
+
 Example
 
 The following example shows three switches on three MDIO busses,
@@ -97,6 +101,7 @@ linked into one DSA cluster.
                        port@1 {
                                reg = <1>;
                                label = "lan1";
+                               local-mac-address = [00 00 00 00 00 00];
                        };
 
                        port@2 {
index c8c831d7b0d1bb9d90cfc9b3022b57b9e6a2f74d..591ecdd39c7b93f41c3f1da70ce987e04ddc6415 100644 (file)
@@ -5,6 +5,7 @@ Required properties:
     - "atmel,at91sam9rl-pwm"
     - "atmel,sama5d3-pwm"
     - "atmel,sama5d2-pwm"
+    - "microchip,sam9x60-pwm"
   - reg: physical base address and length of the controller's registers
   - #pwm-cells: Should be 3. See pwm.txt in this directory for a
     description of the cells format.
index fa7849d67836b1dbc39c69f65e2767e7128c1310..daedfef09bb61c244442a2015a08d8d21b9c8400 100644 (file)
@@ -5,6 +5,8 @@ Required properties:
  The SoC specific strings supported including:
        "hisilicon,hi3516cv300-pwm"
        "hisilicon,hi3519v100-pwm"
+       "hisilicon,hi3559v100-shub-pwm"
+       "hisilicon,hi3559v100-pwm
 - reg: physical base address and length of the controller's registers.
 - clocks: phandle and clock specifier of the PWM reference clock.
 - resets: phandle and reset specifier for the PWM controller reset.
index a842a782b55764ef1c1caf9e4cbb8fc38b6a727f..66af2c30944f4d6e103958ff92921fc1b7f6a668 100644 (file)
@@ -35,7 +35,7 @@ on the Qualcomm Technology Inc. ADSP Hexagon core.
        Value type: <stringlist>
        Definition: List of clock input name strings sorted in the same
                    order as the clocks property. Definition must have
-                   "xo", "sway_cbcr", "lpass_aon", "lpass_ahbs_aon_cbcr",
+                   "xo", "sway_cbcr", "lpass_ahbs_aon_cbcr",
                    "lpass_ahbm_aon_cbcr", "qdsp6ss_xo", "qdsp6ss_sleep"
                    and "qdsp6ss_core".
 
@@ -100,13 +100,12 @@ ADSP, as it is found on SDM845 boards.
 
                clocks = <&rpmhcc RPMH_CXO_CLK>,
                        <&gcc GCC_LPASS_SWAY_CLK>,
-                       <&lpasscc LPASS_AUDIO_WRAPPER_AON_CLK>,
                        <&lpasscc LPASS_Q6SS_AHBS_AON_CLK>,
                        <&lpasscc LPASS_Q6SS_AHBM_AON_CLK>,
                        <&lpasscc LPASS_QDSP6SS_XO_CLK>,
                        <&lpasscc LPASS_QDSP6SS_SLEEP_CLK>,
                        <&lpasscc LPASS_QDSP6SS_CORE_CLK>;
-               clock-names = "xo", "sway_cbcr", "lpass_aon",
+               clock-names = "xo", "sway_cbcr",
                        "lpass_ahbs_aon_cbcr",
                        "lpass_ahbm_aon_cbcr", "qdsp6ss_xo",
                        "qdsp6ss_sleep", "qdsp6ss_core";
index 9c0cff3a5ed8506dd164b42316ec83d63eac404f..292dfda9770d7fb0eae771e125899c437823d003 100644 (file)
@@ -19,13 +19,30 @@ on the Qualcomm ADSP Hexagon core.
 - interrupts-extended:
        Usage: required
        Value type: <prop-encoded-array>
-       Definition: must list the watchdog, fatal IRQs ready, handover and
-                   stop-ack IRQs
+       Definition: reference to the interrupts that match interrupt-names
 
 - interrupt-names:
        Usage: required
        Value type: <stringlist>
-       Definition: must be "wdog", "fatal", "ready", "handover", "stop-ack"
+       Definition: The interrupts needed depends on the compatible
+                   string:
+       qcom,msm8974-adsp-pil:
+       qcom,msm8996-adsp-pil:
+       qcom,msm8996-slpi-pil:
+       qcom,qcs404-adsp-pas:
+       qcom,qcs404-cdsp-pas:
+       qcom,sdm845-adsp-pas:
+       qcom,sdm845-cdsp-pas:
+                   must be "wdog", "fatal", "ready", "handover", "stop-ack"
+       qcom,qcs404-wcss-pas:
+                   must be "wdog", "fatal", "ready", "handover", "stop-ack",
+                   "shutdown-ack"
+
+- firmware-name:
+       Usage: optional
+       Value type: <string>
+       Definition: must list the relative firmware image path for the
+                   Hexagon Core.
 
 - clocks:
        Usage: required
index 9ff5b0309417cc49aa5b8c0adf97b801f01d53c3..41ca5df5be5ac78537ea6312214d00b08bafe3be 100644 (file)
@@ -28,24 +28,51 @@ on the Qualcomm Hexagon core.
 - interrupts-extended:
        Usage: required
        Value type: <prop-encoded-array>
-       Definition: must list the watchdog, fatal IRQs ready, handover and
-                   stop-ack IRQs
+       Definition: reference to the interrupts that match interrupt-names
 
 - interrupt-names:
        Usage: required
        Value type: <stringlist>
-       Definition: must be "wdog", "fatal", "ready", "handover", "stop-ack"
+       Definition: The interrupts needed depends on the the compatible
+                   string:
+       qcom,q6v5-pil:
+       qcom,ipq8074-wcss-pil:
+       qcom,msm8916-mss-pil:
+       qcom,msm8974-mss-pil:
+                   must be "wdog", "fatal", "ready", "handover", "stop-ack"
+       qcom,msm8996-mss-pil:
+       qcom,sdm845-mss-pil:
+                   must be "wdog", "fatal", "ready", "handover", "stop-ack",
+                   "shutdown-ack"
+
+- firmware-name:
+       Usage: optional
+       Value type: <stringlist>
+       Definition: must list the relative firmware image paths for mba and
+                   modem. They are used for booting and authenticating the
+                   Hexagon core.
 
 - clocks:
        Usage: required
        Value type: <phandle>
-       Definition: reference to the iface, bus and mem clocks to be held on
-                   behalf of the booting of the Hexagon core
+       Definition: reference to the clocks that match clock-names
 
 - clock-names:
        Usage: required
        Value type: <stringlist>
-       Definition: must be "iface", "bus", "mem"
+       Definition: The clocks needed depend on the compatible string:
+       qcom,ipq8074-wcss-pil:
+                   no clock names required
+       qcom,q6v5-pil:
+       qcom,msm8916-mss-pil:
+       qcom,msm8974-mss-pil:
+                   must be "iface", "bus", "mem", "xo"
+       qcom,msm8996-mss-pil:
+                   must be "iface", "bus", "mem", "xo", "gpll0_mss",
+                   "snoc_axi", "mnoc_axi", "pnoc", "qdss"
+       qcom,sdm845-mss-pil:
+                   must be "iface", "bus", "mem", "xo", "gpll0_mss",
+                   "snoc_axi", "mnoc_axi", "prng"
 
 - resets:
        Usage: required
@@ -65,6 +92,19 @@ on the Qualcomm Hexagon core.
                    must be "mss_restart", "pdc_reset" for the modem
                    sub-system on SDM845 SoCs
 
+For the compatible strings below the following supplies are required:
+  "qcom,q6v5-pil"
+  "qcom,msm8916-mss-pil",
+- cx-supply:
+- mx-supply:
+- pll-supply:
+       Usage: required
+       Value type: <phandle>
+       Definition: reference to the regulators to be held on behalf of the
+                   booting of the Hexagon core
+
+For the compatible string below the following supplies are required:
+  "qcom,msm8974-mss-pil"
 - cx-supply:
 - mss-supply:
 - mx-supply:
@@ -74,6 +114,33 @@ on the Qualcomm Hexagon core.
        Definition: reference to the regulators to be held on behalf of the
                    booting of the Hexagon core
 
+For the compatible string below the following supplies are required:
+  "qcom,msm8996-mss-pil"
+- pll-supply:
+       Usage: required
+       Value type: <phandle>
+       Definition: reference to the regulators to be held on behalf of the
+                   booting of the Hexagon core
+
+- power-domains:
+       Usage: required
+       Value type: <phandle>
+       Definition: reference to power-domains that match power-domain-names
+
+- power-domain-names:
+       Usage: required
+       Value type: <stringlist>
+       Definition: The power-domains needed depend on the compatible string:
+       qcom,q6v5-pil:
+       qcom,ipq8074-wcss-pil:
+       qcom,msm8916-mss-pil:
+       qcom,msm8974-mss-pil:
+                   no power-domain names required
+       qcom,msm8996-mss-pil:
+                   must be "cx", "mx"
+       qcom,sdm845-mss-pil:
+                   must be "cx", "mx", "mss", "load_state"
+
 - qcom,smem-states:
        Usage: required
        Value type: <phandle>
index d728e50105eb3d82c09758ba6584cd65cba07f8a..45953f17150007d750b5b12b41e0ac31599f302e 100644 (file)
@@ -172,7 +172,7 @@ The details of these operations are:
 
       After calling ``dmaengine_submit()`` the submitted transfer descriptor
       (``struct dma_async_tx_descriptor``) belongs to the DMA engine.
-      Consequentially, the client must consider invalid the pointer to that
+      Consequently, the client must consider invalid the pointer to that
       descriptor.
 
 5. Issue pending DMA requests and wait for callback notification
index 8d81f1a7169b7c23cd1a226633a535d9c0f1f0b8..e78d070bb468f9bd41e6330d28ccaaee267c6895 100644 (file)
@@ -59,6 +59,7 @@ parameter, that specific channel is requested using the dmaengine and a thread
 is created with the existing parameters. This thread is set as pending
 and will be executed once run is set to 1. Any parameters set after the thread
 is created are not applied.
+
 .. hint::
   available channel list could be extracted by running the following command::
 
index b277cafce71eb25effa455c90f3c24d14430856d..d7d6f01e81fff52ed25f0930532c5cc10875c2dc 100644 (file)
@@ -242,9 +242,11 @@ certainly invest a bit more effort into libata core layer).
 
 CLOCK
   devm_clk_get()
+  devm_clk_get_optional()
   devm_clk_put()
   devm_clk_hw_register()
   devm_of_clk_add_hw_provider()
+  devm_clk_hw_register_clkdev()
 
 DMA
   dmaenginem_async_device_register()
index 4f004dc0a0f21ef2a9babf48e1f3e0d108df1b48..f8ff9ae52c21085372c31d04a1c7ed4f02cd1494 100644 (file)
@@ -3204,6 +3204,7 @@ F:        drivers/phy/broadcom/phy-brcm-usb*
 BROADCOM GENET ETHERNET DRIVER
 M:     Doug Berger <opendmb@gmail.com>
 M:     Florian Fainelli <f.fainelli@gmail.com>
+L:     bcm-kernel-feedback-list@broadcom.com
 L:     netdev@vger.kernel.org
 S:     Supported
 F:     drivers/net/ethernet/broadcom/genet/
@@ -3311,6 +3312,7 @@ F:        drivers/spi/spi-iproc-qspi.c
 
 BROADCOM SYSTEMPORT ETHERNET DRIVER
 M:     Florian Fainelli <f.fainelli@gmail.com>
+L:     bcm-kernel-feedback-list@broadcom.com
 L:     netdev@vger.kernel.org
 S:     Supported
 F:     drivers/net/ethernet/broadcom/bcmsysport.*
@@ -4643,10 +4645,11 @@ S:      Maintained
 F:     drivers/i2c/busses/i2c-diolan-u2c.c
 
 FILESYSTEM DIRECT ACCESS (DAX)
-M:     Matthew Wilcox <willy@infradead.org>
-M:     Ross Zwisler <zwisler@kernel.org>
-M:     Jan Kara <jack@suse.cz>
+M:     Dan Williams <dan.j.williams@intel.com>
+R:     Matthew Wilcox <willy@infradead.org>
+R:     Jan Kara <jack@suse.cz>
 L:     linux-fsdevel@vger.kernel.org
+L:     linux-nvdimm@lists.01.org
 S:     Supported
 F:     fs/dax.c
 F:     include/linux/dax.h
@@ -4654,9 +4657,9 @@ F:        include/trace/events/fs_dax.h
 
 DEVICE DIRECT ACCESS (DAX)
 M:     Dan Williams <dan.j.williams@intel.com>
-M:     Dave Jiang <dave.jiang@intel.com>
-M:     Ross Zwisler <zwisler@kernel.org>
 M:     Vishal Verma <vishal.l.verma@intel.com>
+M:     Keith Busch <keith.busch@intel.com>
+M:     Dave Jiang <dave.jiang@intel.com>
 L:     linux-nvdimm@lists.01.org
 S:     Supported
 F:     drivers/dax/
@@ -8812,7 +8815,6 @@ S:        Maintained
 F:     tools/lib/lockdep/
 
 LIBNVDIMM BLK: MMIO-APERTURE DRIVER
-M:     Ross Zwisler <zwisler@kernel.org>
 M:     Dan Williams <dan.j.williams@intel.com>
 M:     Vishal Verma <vishal.l.verma@intel.com>
 M:     Dave Jiang <dave.jiang@intel.com>
@@ -8825,7 +8827,6 @@ F:        drivers/nvdimm/region_devs.c
 LIBNVDIMM BTT: BLOCK TRANSLATION TABLE
 M:     Vishal Verma <vishal.l.verma@intel.com>
 M:     Dan Williams <dan.j.williams@intel.com>
-M:     Ross Zwisler <zwisler@kernel.org>
 M:     Dave Jiang <dave.jiang@intel.com>
 L:     linux-nvdimm@lists.01.org
 Q:     https://patchwork.kernel.org/project/linux-nvdimm/list/
@@ -8833,7 +8834,6 @@ S:        Supported
 F:     drivers/nvdimm/btt*
 
 LIBNVDIMM PMEM: PERSISTENT MEMORY DRIVER
-M:     Ross Zwisler <zwisler@kernel.org>
 M:     Dan Williams <dan.j.williams@intel.com>
 M:     Vishal Verma <vishal.l.verma@intel.com>
 M:     Dave Jiang <dave.jiang@intel.com>
@@ -8852,9 +8852,10 @@ F:       Documentation/devicetree/bindings/pmem/pmem-region.txt
 
 LIBNVDIMM: NON-VOLATILE MEMORY DEVICE SUBSYSTEM
 M:     Dan Williams <dan.j.williams@intel.com>
-M:     Ross Zwisler <zwisler@kernel.org>
 M:     Vishal Verma <vishal.l.verma@intel.com>
 M:     Dave Jiang <dave.jiang@intel.com>
+M:     Keith Busch <keith.busch@intel.com>
+M:     Ira Weiny <ira.weiny@intel.com>
 L:     linux-nvdimm@lists.01.org
 Q:     https://patchwork.kernel.org/project/linux-nvdimm/list/
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm.git
index 0d0fddb7e738841f8f01a8ca507cc5f38843ccad..976e89b116e5b5747d1e282b748befefd3634cdf 100644 (file)
@@ -2,8 +2,8 @@
 #ifndef _UAPI_ASM_SOCKET_H
 #define _UAPI_ASM_SOCKET_H
 
+#include <linux/posix_types.h>
 #include <asm/sockios.h>
-#include <asm/bitsperlong.h>
 
 /* For setsockopt(2) */
 /*
index b5531dd3ae9c36b5b165b314ba39d2e0a9cd8264..3a04c73ac03c372c6b2dff678ed90bdb369aaa62 100644 (file)
@@ -1002,8 +1002,10 @@ static int _enable_clocks(struct omap_hwmod *oh)
                clk_enable(oh->_clk);
 
        list_for_each_entry(os, &oh->slave_ports, node) {
-               if (os->_clk && (os->flags & OCPIF_SWSUP_IDLE))
+               if (os->_clk && (os->flags & OCPIF_SWSUP_IDLE)) {
+                       omap2_clk_deny_idle(os->_clk);
                        clk_enable(os->_clk);
+               }
        }
 
        /* The opt clocks are controlled by the device driver. */
@@ -1055,8 +1057,10 @@ static int _disable_clocks(struct omap_hwmod *oh)
                clk_disable(oh->_clk);
 
        list_for_each_entry(os, &oh->slave_ports, node) {
-               if (os->_clk && (os->flags & OCPIF_SWSUP_IDLE))
+               if (os->_clk && (os->flags & OCPIF_SWSUP_IDLE)) {
                        clk_disable(os->_clk);
+                       omap2_clk_allow_idle(os->_clk);
+               }
        }
 
        if (oh->flags & HWMOD_OPT_CLKS_NEEDED)
@@ -2436,9 +2440,13 @@ static void _setup_iclk_autoidle(struct omap_hwmod *oh)
                        continue;
 
                if (os->flags & OCPIF_SWSUP_IDLE) {
-                       /* XXX omap_iclk_deny_idle(c); */
+                       /*
+                        * we might have multiple users of one iclk with
+                        * different requirements, disable autoidle when
+                        * the module is enabled, e.g. dss iclk
+                        */
                } else {
-                       /* XXX omap_iclk_allow_idle(c); */
+                       /* we are enabling autoidle afterwards anyways */
                        clk_enable(os->_clk);
                }
        }
index bbd6968ce55b5fbaec58f1fef21bdfd17826f779..522a0c5d9c59c47fc33b76378d1be5cd4bec44c8 100644 (file)
@@ -192,23 +192,14 @@ struct dentry *of_debugfs_root;
 static int microblaze_debugfs_init(void)
 {
        of_debugfs_root = debugfs_create_dir("microblaze", NULL);
-
-       return of_debugfs_root == NULL;
+       return 0;
 }
 arch_initcall(microblaze_debugfs_init);
 
 # ifdef CONFIG_MMU
 static int __init debugfs_tlb(void)
 {
-       struct dentry *d;
-
-       if (!of_debugfs_root)
-               return -ENODEV;
-
-       d = debugfs_create_u32("tlb_skip", S_IRUGO, of_debugfs_root, &tlb_skip);
-       if (!d)
-               return -ENOMEM;
-
+       debugfs_create_u32("tlb_skip", S_IRUGO, of_debugfs_root, &tlb_skip);
        return 0;
 }
 device_initcall(debugfs_tlb);
index eb9f33f8a8b374d18d53bf557cb036edccf2687b..d41765cfbc6ebae8af75fc892c7ac2e71c301393 100644 (file)
@@ -10,8 +10,8 @@
 #ifndef _UAPI_ASM_SOCKET_H
 #define _UAPI_ASM_SOCKET_H
 
+#include <linux/posix_types.h>
 #include <asm/sockios.h>
-#include <asm/bitsperlong.h>
 
 /*
  * For setsockopt(2)
index 16e428f03526a6a5d003585a63dde35c5bcf7e64..66c5dd245ac7551dcccdcfeb204d2aa5d675c41e 100644 (file)
@@ -2,8 +2,8 @@
 #ifndef _UAPI_ASM_SOCKET_H
 #define _UAPI_ASM_SOCKET_H
 
+#include <linux/posix_types.h>
 #include <asm/sockios.h>
-#include <asm/bitsperlong.h>
 
 /* For setsockopt(2) */
 #define SOL_SOCKET     0xffff
index 88fe4f978acab417a6064b3ea7022e09601697ae..9265a9eece15f498563eb658001aa41ac4d0f756 100644 (file)
@@ -2,8 +2,8 @@
 #ifndef _ASM_SOCKET_H
 #define _ASM_SOCKET_H
 
+#include <linux/posix_types.h>
 #include <asm/sockios.h>
-#include <asm/bitsperlong.h>
 
 /* For setsockopt(2) */
 #define SOL_SOCKET     0xffff
index b588503890941c552749458520a8909056742573..81bfc61972931caa91183b5a865940ecfd242143 100644 (file)
@@ -97,12 +97,12 @@ static ssize_t acpi_table_aml_read(struct config_item *cfg,
 
 CONFIGFS_BIN_ATTR(acpi_table_, aml, NULL, MAX_ACPI_TABLE_SIZE);
 
-struct configfs_bin_attribute *acpi_table_bin_attrs[] = {
+static struct configfs_bin_attribute *acpi_table_bin_attrs[] = {
        &acpi_table_attr_aml,
        NULL,
 };
 
-ssize_t acpi_table_signature_show(struct config_item *cfg, char *str)
+static ssize_t acpi_table_signature_show(struct config_item *cfg, char *str)
 {
        struct acpi_table_header *h = get_header(cfg);
 
@@ -112,7 +112,7 @@ ssize_t acpi_table_signature_show(struct config_item *cfg, char *str)
        return sprintf(str, "%.*s\n", ACPI_NAME_SIZE, h->signature);
 }
 
-ssize_t acpi_table_length_show(struct config_item *cfg, char *str)
+static ssize_t acpi_table_length_show(struct config_item *cfg, char *str)
 {
        struct acpi_table_header *h = get_header(cfg);
 
@@ -122,7 +122,7 @@ ssize_t acpi_table_length_show(struct config_item *cfg, char *str)
        return sprintf(str, "%d\n", h->length);
 }
 
-ssize_t acpi_table_revision_show(struct config_item *cfg, char *str)
+static ssize_t acpi_table_revision_show(struct config_item *cfg, char *str)
 {
        struct acpi_table_header *h = get_header(cfg);
 
@@ -132,7 +132,7 @@ ssize_t acpi_table_revision_show(struct config_item *cfg, char *str)
        return sprintf(str, "%d\n", h->revision);
 }
 
-ssize_t acpi_table_oem_id_show(struct config_item *cfg, char *str)
+static ssize_t acpi_table_oem_id_show(struct config_item *cfg, char *str)
 {
        struct acpi_table_header *h = get_header(cfg);
 
@@ -142,7 +142,7 @@ ssize_t acpi_table_oem_id_show(struct config_item *cfg, char *str)
        return sprintf(str, "%.*s\n", ACPI_OEM_ID_SIZE, h->oem_id);
 }
 
-ssize_t acpi_table_oem_table_id_show(struct config_item *cfg, char *str)
+static ssize_t acpi_table_oem_table_id_show(struct config_item *cfg, char *str)
 {
        struct acpi_table_header *h = get_header(cfg);
 
@@ -152,7 +152,7 @@ ssize_t acpi_table_oem_table_id_show(struct config_item *cfg, char *str)
        return sprintf(str, "%.*s\n", ACPI_OEM_TABLE_ID_SIZE, h->oem_table_id);
 }
 
-ssize_t acpi_table_oem_revision_show(struct config_item *cfg, char *str)
+static ssize_t acpi_table_oem_revision_show(struct config_item *cfg, char *str)
 {
        struct acpi_table_header *h = get_header(cfg);
 
@@ -162,7 +162,8 @@ ssize_t acpi_table_oem_revision_show(struct config_item *cfg, char *str)
        return sprintf(str, "%d\n", h->oem_revision);
 }
 
-ssize_t acpi_table_asl_compiler_id_show(struct config_item *cfg, char *str)
+static ssize_t acpi_table_asl_compiler_id_show(struct config_item *cfg,
+                                              char *str)
 {
        struct acpi_table_header *h = get_header(cfg);
 
@@ -172,8 +173,8 @@ ssize_t acpi_table_asl_compiler_id_show(struct config_item *cfg, char *str)
        return sprintf(str, "%.*s\n", ACPI_NAME_SIZE, h->asl_compiler_id);
 }
 
-ssize_t acpi_table_asl_compiler_revision_show(struct config_item *cfg,
-                                             char *str)
+static ssize_t acpi_table_asl_compiler_revision_show(struct config_item *cfg,
+                                                    char *str)
 {
        struct acpi_table_header *h = get_header(cfg);
 
@@ -192,7 +193,7 @@ CONFIGFS_ATTR_RO(acpi_table_, oem_revision);
 CONFIGFS_ATTR_RO(acpi_table_, asl_compiler_id);
 CONFIGFS_ATTR_RO(acpi_table_, asl_compiler_revision);
 
-struct configfs_attribute *acpi_table_attrs[] = {
+static struct configfs_attribute *acpi_table_attrs[] = {
        &acpi_table_attr_signature,
        &acpi_table_attr_length,
        &acpi_table_attr_revision,
@@ -232,7 +233,7 @@ static void acpi_table_drop_item(struct config_group *group,
        acpi_tb_unload_table(table->index);
 }
 
-struct configfs_group_operations acpi_table_group_ops = {
+static struct configfs_group_operations acpi_table_group_ops = {
        .make_item = acpi_table_make_item,
        .drop_item = acpi_table_drop_item,
 };
index 5f94c35d165fe917151fa90127819b6f1d686db3..1e2a10a06b9dcec92accab9e1fd6e485cb19e052 100644 (file)
@@ -18,7 +18,7 @@
 #include <linux/mutex.h>
 #include <linux/pci.h>
 #include <linux/platform_device.h>
-#include <linux/platform_data/clk-lpss.h>
+#include <linux/platform_data/x86/clk-lpss.h>
 #include <linux/platform_data/x86/pmc_atom.h>
 #include <linux/pm_domain.h>
 #include <linux/pm_runtime.h>
index 545e91420cded88ac3b2621d97b1f1176696f348..8940054d6250f92c56a82f637d0a326256b4eed8 100644 (file)
@@ -202,11 +202,15 @@ static int create_of_modalias(struct acpi_device *acpi_dev, char *modalias,
 {
        struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER };
        const union acpi_object *of_compatible, *obj;
+       acpi_status status;
        int len, count;
        int i, nval;
        char *c;
 
-       acpi_get_name(acpi_dev->handle, ACPI_SINGLE_NAME, &buf);
+       status = acpi_get_name(acpi_dev->handle, ACPI_SINGLE_NAME, &buf);
+       if (ACPI_FAILURE(status))
+               return -ENODEV;
+
        /* DT strings are all in lower case */
        for (c = buf.pointer; *c != '\0'; c++)
                *c = tolower(*c);
index e18ade5d74e9ecf38126bce5301f027073779bc3..df8979008dd4ec6496c1e5600ec856a300dec08f 100644 (file)
@@ -55,6 +55,10 @@ static bool no_init_ars;
 module_param(no_init_ars, bool, 0644);
 MODULE_PARM_DESC(no_init_ars, "Skip ARS run at nfit init time");
 
+static bool force_labels;
+module_param(force_labels, bool, 0444);
+MODULE_PARM_DESC(force_labels, "Opt-in to labels despite missing methods");
+
 LIST_HEAD(acpi_descs);
 DEFINE_MUTEX(acpi_desc_lock);
 
@@ -415,7 +419,7 @@ static int cmd_to_func(struct nfit_mem *nfit_mem, unsigned int cmd,
        if (call_pkg) {
                int i;
 
-               if (nfit_mem->family != call_pkg->nd_family)
+               if (nfit_mem && nfit_mem->family != call_pkg->nd_family)
                        return -ENOTTY;
 
                for (i = 0; i < ARRAY_SIZE(call_pkg->nd_reserved2); i++)
@@ -424,6 +428,10 @@ static int cmd_to_func(struct nfit_mem *nfit_mem, unsigned int cmd,
                return call_pkg->nd_command;
        }
 
+       /* In the !call_pkg case, bus commands == bus functions */
+       if (!nfit_mem)
+               return cmd;
+
        /* Linux ND commands == NVDIMM_FAMILY_INTEL function numbers */
        if (nfit_mem->family == NVDIMM_FAMILY_INTEL)
                return cmd;
@@ -454,17 +462,18 @@ int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc, struct nvdimm *nvdimm,
        if (cmd_rc)
                *cmd_rc = -EINVAL;
 
+       if (cmd == ND_CMD_CALL)
+               call_pkg = buf;
+       func = cmd_to_func(nfit_mem, cmd, call_pkg);
+       if (func < 0)
+               return func;
+
        if (nvdimm) {
                struct acpi_device *adev = nfit_mem->adev;
 
                if (!adev)
                        return -ENOTTY;
 
-               if (cmd == ND_CMD_CALL)
-                       call_pkg = buf;
-               func = cmd_to_func(nfit_mem, cmd, call_pkg);
-               if (func < 0)
-                       return func;
                dimm_name = nvdimm_name(nvdimm);
                cmd_name = nvdimm_cmd_name(cmd);
                cmd_mask = nvdimm_cmd_mask(nvdimm);
@@ -475,12 +484,9 @@ int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc, struct nvdimm *nvdimm,
        } else {
                struct acpi_device *adev = to_acpi_dev(acpi_desc);
 
-               func = cmd;
                cmd_name = nvdimm_bus_cmd_name(cmd);
                cmd_mask = nd_desc->cmd_mask;
-               dsm_mask = cmd_mask;
-               if (cmd == ND_CMD_CALL)
-                       dsm_mask = nd_desc->bus_dsm_mask;
+               dsm_mask = nd_desc->bus_dsm_mask;
                desc = nd_cmd_bus_desc(cmd);
                guid = to_nfit_uuid(NFIT_DEV_BUS);
                handle = adev->handle;
@@ -554,6 +560,13 @@ int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc, struct nvdimm *nvdimm,
                return -EINVAL;
        }
 
+       if (out_obj->type != ACPI_TYPE_BUFFER) {
+               dev_dbg(dev, "%s unexpected output object type cmd: %s type: %d\n",
+                               dimm_name, cmd_name, out_obj->type);
+               rc = -EINVAL;
+               goto out;
+       }
+
        if (call_pkg) {
                call_pkg->nd_fw_size = out_obj->buffer.length;
                memcpy(call_pkg->nd_payload + call_pkg->nd_size_in,
@@ -572,13 +585,6 @@ int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc, struct nvdimm *nvdimm,
                return 0;
        }
 
-       if (out_obj->package.type != ACPI_TYPE_BUFFER) {
-               dev_dbg(dev, "%s unexpected output object type cmd: %s type: %d\n",
-                               dimm_name, cmd_name, out_obj->type);
-               rc = -EINVAL;
-               goto out;
-       }
-
        dev_dbg(dev, "%s cmd: %s output length: %d\n", dimm_name,
                        cmd_name, out_obj->buffer.length);
        print_hex_dump_debug(cmd_name, DUMP_PREFIX_OFFSET, 4, 4,
@@ -1317,19 +1323,30 @@ static ssize_t scrub_show(struct device *dev,
                struct device_attribute *attr, char *buf)
 {
        struct nvdimm_bus_descriptor *nd_desc;
+       struct acpi_nfit_desc *acpi_desc;
        ssize_t rc = -ENXIO;
+       bool busy;
 
        device_lock(dev);
        nd_desc = dev_get_drvdata(dev);
-       if (nd_desc) {
-               struct acpi_nfit_desc *acpi_desc = to_acpi_desc(nd_desc);
+       if (!nd_desc) {
+               device_unlock(dev);
+               return rc;
+       }
+       acpi_desc = to_acpi_desc(nd_desc);
 
-               mutex_lock(&acpi_desc->init_mutex);
-               rc = sprintf(buf, "%d%s", acpi_desc->scrub_count,
-                               acpi_desc->scrub_busy
-                               && !acpi_desc->cancel ? "+\n" : "\n");
-               mutex_unlock(&acpi_desc->init_mutex);
+       mutex_lock(&acpi_desc->init_mutex);
+       busy = test_bit(ARS_BUSY, &acpi_desc->scrub_flags)
+               && !test_bit(ARS_CANCEL, &acpi_desc->scrub_flags);
+       rc = sprintf(buf, "%d%s", acpi_desc->scrub_count, busy ? "+\n" : "\n");
+       /* Allow an admin to poll the busy state at a higher rate */
+       if (busy && capable(CAP_SYS_RAWIO) && !test_and_set_bit(ARS_POLL,
+                               &acpi_desc->scrub_flags)) {
+               acpi_desc->scrub_tmo = 1;
+               mod_delayed_work(nfit_wq, &acpi_desc->dwork, HZ);
        }
+
+       mutex_unlock(&acpi_desc->init_mutex);
        device_unlock(dev);
        return rc;
 }
@@ -1759,14 +1776,14 @@ static bool acpi_nvdimm_has_method(struct acpi_device *adev, char *method)
 
 __weak void nfit_intel_shutdown_status(struct nfit_mem *nfit_mem)
 {
+       struct device *dev = &nfit_mem->adev->dev;
        struct nd_intel_smart smart = { 0 };
        union acpi_object in_buf = {
-               .type = ACPI_TYPE_BUFFER,
-               .buffer.pointer = (char *) &smart,
-               .buffer.length = sizeof(smart),
+               .buffer.type = ACPI_TYPE_BUFFER,
+               .buffer.length = 0,
        };
        union acpi_object in_obj = {
-               .type = ACPI_TYPE_PACKAGE,
+               .package.type = ACPI_TYPE_PACKAGE,
                .package.count = 1,
                .package.elements = &in_buf,
        };
@@ -1781,8 +1798,15 @@ __weak void nfit_intel_shutdown_status(struct nfit_mem *nfit_mem)
                return;
 
        out_obj = acpi_evaluate_dsm(handle, guid, revid, func, &in_obj);
-       if (!out_obj)
+       if (!out_obj || out_obj->type != ACPI_TYPE_BUFFER
+                       || out_obj->buffer.length < sizeof(smart)) {
+               dev_dbg(dev->parent, "%s: failed to retrieve initial health\n",
+                               dev_name(dev));
+               ACPI_FREE(out_obj);
                return;
+       }
+       memcpy(&smart, out_obj->buffer.pointer, sizeof(smart));
+       ACPI_FREE(out_obj);
 
        if (smart.flags & ND_INTEL_SMART_SHUTDOWN_VALID) {
                if (smart.shutdown_state)
@@ -1793,7 +1817,6 @@ __weak void nfit_intel_shutdown_status(struct nfit_mem *nfit_mem)
                set_bit(NFIT_MEM_DIRTY_COUNT, &nfit_mem->flags);
                nfit_mem->dirty_shutdown = smart.shutdown_count;
        }
-       ACPI_FREE(out_obj);
 }
 
 static void populate_shutdown_status(struct nfit_mem *nfit_mem)
@@ -1861,9 +1884,17 @@ static int acpi_nfit_add_dimm(struct acpi_nfit_desc *acpi_desc,
        dev_set_drvdata(&adev_dimm->dev, nfit_mem);
 
        /*
-        * Until standardization materializes we need to consider 4
-        * different command sets.  Note, that checking for function0 (bit0)
-        * tells us if any commands are reachable through this GUID.
+        * There are 4 "legacy" NVDIMM command sets
+        * (NVDIMM_FAMILY_{INTEL,MSFT,HPE1,HPE2}) that were created before
+        * an EFI working group was established to constrain this
+        * proliferation. The nfit driver probes for the supported command
+        * set by GUID. Note, if you're a platform developer looking to add
+        * a new command set to this probe, consider using an existing set,
+        * or otherwise seek approval to publish the command set at
+        * http://www.uefi.org/RFIC_LIST.
+        *
+        * Note, that checking for function0 (bit0) tells us if any commands
+        * are reachable through this GUID.
         */
        for (i = 0; i <= NVDIMM_FAMILY_MAX; i++)
                if (acpi_check_dsm(adev_dimm->handle, to_nfit_uuid(i), 1, 1))
@@ -1886,6 +1917,8 @@ static int acpi_nfit_add_dimm(struct acpi_nfit_desc *acpi_desc,
                        dsm_mask &= ~(1 << 8);
        } else if (nfit_mem->family == NVDIMM_FAMILY_MSFT) {
                dsm_mask = 0xffffffff;
+       } else if (nfit_mem->family == NVDIMM_FAMILY_HYPERV) {
+               dsm_mask = 0x1f;
        } else {
                dev_dbg(dev, "unknown dimm command family\n");
                nfit_mem->family = -1;
@@ -1915,18 +1948,32 @@ static int acpi_nfit_add_dimm(struct acpi_nfit_desc *acpi_desc,
                | 1 << ND_CMD_SET_CONFIG_DATA;
        if (family == NVDIMM_FAMILY_INTEL
                        && (dsm_mask & label_mask) == label_mask)
-               return 0;
+               /* skip _LS{I,R,W} enabling */;
+       else {
+               if (acpi_nvdimm_has_method(adev_dimm, "_LSI")
+                               && acpi_nvdimm_has_method(adev_dimm, "_LSR")) {
+                       dev_dbg(dev, "%s: has _LSR\n", dev_name(&adev_dimm->dev));
+                       set_bit(NFIT_MEM_LSR, &nfit_mem->flags);
+               }
 
-       if (acpi_nvdimm_has_method(adev_dimm, "_LSI")
-                       && acpi_nvdimm_has_method(adev_dimm, "_LSR")) {
-               dev_dbg(dev, "%s: has _LSR\n", dev_name(&adev_dimm->dev));
-               set_bit(NFIT_MEM_LSR, &nfit_mem->flags);
-       }
+               if (test_bit(NFIT_MEM_LSR, &nfit_mem->flags)
+                               && acpi_nvdimm_has_method(adev_dimm, "_LSW")) {
+                       dev_dbg(dev, "%s: has _LSW\n", dev_name(&adev_dimm->dev));
+                       set_bit(NFIT_MEM_LSW, &nfit_mem->flags);
+               }
 
-       if (test_bit(NFIT_MEM_LSR, &nfit_mem->flags)
-                       && acpi_nvdimm_has_method(adev_dimm, "_LSW")) {
-               dev_dbg(dev, "%s: has _LSW\n", dev_name(&adev_dimm->dev));
-               set_bit(NFIT_MEM_LSW, &nfit_mem->flags);
+               /*
+                * Quirk read-only label configurations to preserve
+                * access to label-less namespaces by default.
+                */
+               if (!test_bit(NFIT_MEM_LSW, &nfit_mem->flags)
+                               && !force_labels) {
+                       dev_dbg(dev, "%s: No _LSW, disable labels\n",
+                                       dev_name(&adev_dimm->dev));
+                       clear_bit(NFIT_MEM_LSR, &nfit_mem->flags);
+               } else
+                       dev_dbg(dev, "%s: Force enable labels\n",
+                                       dev_name(&adev_dimm->dev));
        }
 
        populate_shutdown_status(nfit_mem);
@@ -2027,6 +2074,10 @@ static int acpi_nfit_register_dimms(struct acpi_nfit_desc *acpi_desc)
                        cmd_mask |= nfit_mem->dsm_mask & NVDIMM_STANDARD_CMDMASK;
                }
 
+               /* Quirk to ignore LOCAL for labels on HYPERV DIMMs */
+               if (nfit_mem->family == NVDIMM_FAMILY_HYPERV)
+                       set_bit(NDD_NOBLK, &flags);
+
                if (test_bit(NFIT_MEM_LSR, &nfit_mem->flags)) {
                        set_bit(ND_CMD_GET_CONFIG_SIZE, &cmd_mask);
                        set_bit(ND_CMD_GET_CONFIG_DATA, &cmd_mask);
@@ -2050,7 +2101,7 @@ static int acpi_nfit_register_dimms(struct acpi_nfit_desc *acpi_desc)
                if ((mem_flags & ACPI_NFIT_MEM_FAILED_MASK) == 0)
                        continue;
 
-               dev_info(acpi_desc->dev, "%s flags:%s%s%s%s%s\n",
+               dev_err(acpi_desc->dev, "Error found in NVDIMM %s flags:%s%s%s%s%s\n",
                                nvdimm_name(nvdimm),
                  mem_flags & ACPI_NFIT_MEM_SAVE_FAILED ? " save_fail" : "",
                  mem_flags & ACPI_NFIT_MEM_RESTORE_FAILED ? " restore_fail":"",
@@ -2641,7 +2692,10 @@ static int ars_start(struct acpi_nfit_desc *acpi_desc,
 
        if (rc < 0)
                return rc;
-       return cmd_rc;
+       if (cmd_rc < 0)
+               return cmd_rc;
+       set_bit(ARS_VALID, &acpi_desc->scrub_flags);
+       return 0;
 }
 
 static int ars_continue(struct acpi_nfit_desc *acpi_desc)
@@ -2651,11 +2705,11 @@ static int ars_continue(struct acpi_nfit_desc *acpi_desc)
        struct nvdimm_bus_descriptor *nd_desc = &acpi_desc->nd_desc;
        struct nd_cmd_ars_status *ars_status = acpi_desc->ars_status;
 
-       memset(&ars_start, 0, sizeof(ars_start));
-       ars_start.address = ars_status->restart_address;
-       ars_start.length = ars_status->restart_length;
-       ars_start.type = ars_status->type;
-       ars_start.flags = acpi_desc->ars_start_flags;
+       ars_start = (struct nd_cmd_ars_start) {
+               .address = ars_status->restart_address,
+               .length = ars_status->restart_length,
+               .type = ars_status->type,
+       };
        rc = nd_desc->ndctl(nd_desc, NULL, ND_CMD_ARS_START, &ars_start,
                        sizeof(ars_start), &cmd_rc);
        if (rc < 0)
@@ -2734,6 +2788,17 @@ static int ars_status_process_records(struct acpi_nfit_desc *acpi_desc)
         */
        if (ars_status->out_length < 44)
                return 0;
+
+       /*
+        * Ignore potentially stale results that are only refreshed
+        * after a start-ARS event.
+        */
+       if (!test_and_clear_bit(ARS_VALID, &acpi_desc->scrub_flags)) {
+               dev_dbg(acpi_desc->dev, "skip %d stale records\n",
+                               ars_status->num_records);
+               return 0;
+       }
+
        for (i = 0; i < ars_status->num_records; i++) {
                /* only process full records */
                if (ars_status->out_length
@@ -3004,14 +3069,16 @@ static int ars_register(struct acpi_nfit_desc *acpi_desc,
 {
        int rc;
 
-       if (no_init_ars || test_bit(ARS_FAILED, &nfit_spa->ars_state))
+       if (test_bit(ARS_FAILED, &nfit_spa->ars_state))
                return acpi_nfit_register_region(acpi_desc, nfit_spa);
 
        set_bit(ARS_REQ_SHORT, &nfit_spa->ars_state);
-       set_bit(ARS_REQ_LONG, &nfit_spa->ars_state);
+       if (!no_init_ars)
+               set_bit(ARS_REQ_LONG, &nfit_spa->ars_state);
 
        switch (acpi_nfit_query_poison(acpi_desc)) {
        case 0:
+       case -ENOSPC:
        case -EAGAIN:
                rc = ars_start(acpi_desc, nfit_spa, ARS_REQ_SHORT);
                /* shouldn't happen, try again later */
@@ -3036,7 +3103,6 @@ static int ars_register(struct acpi_nfit_desc *acpi_desc,
                break;
        case -EBUSY:
        case -ENOMEM:
-       case -ENOSPC:
                /*
                 * BIOS was using ARS, wait for it to complete (or
                 * resources to become available) and then perform our
@@ -3071,7 +3137,7 @@ static unsigned int __acpi_nfit_scrub(struct acpi_nfit_desc *acpi_desc,
 
        lockdep_assert_held(&acpi_desc->init_mutex);
 
-       if (acpi_desc->cancel)
+       if (test_bit(ARS_CANCEL, &acpi_desc->scrub_flags))
                return 0;
 
        if (query_rc == -EBUSY) {
@@ -3145,7 +3211,7 @@ static void __sched_ars(struct acpi_nfit_desc *acpi_desc, unsigned int tmo)
 {
        lockdep_assert_held(&acpi_desc->init_mutex);
 
-       acpi_desc->scrub_busy = 1;
+       set_bit(ARS_BUSY, &acpi_desc->scrub_flags);
        /* note this should only be set from within the workqueue */
        if (tmo)
                acpi_desc->scrub_tmo = tmo;
@@ -3161,7 +3227,7 @@ static void notify_ars_done(struct acpi_nfit_desc *acpi_desc)
 {
        lockdep_assert_held(&acpi_desc->init_mutex);
 
-       acpi_desc->scrub_busy = 0;
+       clear_bit(ARS_BUSY, &acpi_desc->scrub_flags);
        acpi_desc->scrub_count++;
        if (acpi_desc->scrub_count_state)
                sysfs_notify_dirent(acpi_desc->scrub_count_state);
@@ -3182,6 +3248,7 @@ static void acpi_nfit_scrub(struct work_struct *work)
        else
                notify_ars_done(acpi_desc);
        memset(acpi_desc->ars_status, 0, acpi_desc->max_ars);
+       clear_bit(ARS_POLL, &acpi_desc->scrub_flags);
        mutex_unlock(&acpi_desc->init_mutex);
 }
 
@@ -3216,6 +3283,7 @@ static int acpi_nfit_register_regions(struct acpi_nfit_desc *acpi_desc)
        struct nfit_spa *nfit_spa;
        int rc;
 
+       set_bit(ARS_VALID, &acpi_desc->scrub_flags);
        list_for_each_entry(nfit_spa, &acpi_desc->spas, list) {
                switch (nfit_spa_type(nfit_spa->spa)) {
                case NFIT_SPA_VOLATILE:
@@ -3450,7 +3518,7 @@ int acpi_nfit_ars_rescan(struct acpi_nfit_desc *acpi_desc,
        struct nfit_spa *nfit_spa;
 
        mutex_lock(&acpi_desc->init_mutex);
-       if (acpi_desc->cancel) {
+       if (test_bit(ARS_CANCEL, &acpi_desc->scrub_flags)) {
                mutex_unlock(&acpi_desc->init_mutex);
                return 0;
        }
@@ -3529,7 +3597,7 @@ void acpi_nfit_shutdown(void *data)
        mutex_unlock(&acpi_desc_lock);
 
        mutex_lock(&acpi_desc->init_mutex);
-       acpi_desc->cancel = 1;
+       set_bit(ARS_CANCEL, &acpi_desc->scrub_flags);
        cancel_delayed_work_sync(&acpi_desc->dwork);
        mutex_unlock(&acpi_desc->init_mutex);
 
@@ -3729,6 +3797,7 @@ static __init int nfit_init(void)
        guid_parse(UUID_NFIT_DIMM_N_HPE1, &nfit_uuid[NFIT_DEV_DIMM_N_HPE1]);
        guid_parse(UUID_NFIT_DIMM_N_HPE2, &nfit_uuid[NFIT_DEV_DIMM_N_HPE2]);
        guid_parse(UUID_NFIT_DIMM_N_MSFT, &nfit_uuid[NFIT_DEV_DIMM_N_MSFT]);
+       guid_parse(UUID_NFIT_DIMM_N_HYPERV, &nfit_uuid[NFIT_DEV_DIMM_N_HYPERV]);
 
        nfit_wq = create_singlethread_workqueue("nfit");
        if (!nfit_wq)
index 33691aecfcee8a48bafb23e71c39ab8109724cf7..2f8cf2a11e3bf0ecae57507fb325bdf429d11d6e 100644 (file)
 /* https://msdn.microsoft.com/library/windows/hardware/mt604741 */
 #define UUID_NFIT_DIMM_N_MSFT "1ee68b36-d4bd-4a1a-9a16-4f8e53d46e05"
 
+/* http://www.uefi.org/RFIC_LIST (see "Virtual NVDIMM 0x1901") */
+#define UUID_NFIT_DIMM_N_HYPERV "5746c5f2-a9a2-4264-ad0e-e4ddc9e09e80"
+
 #define ACPI_NFIT_MEM_FAILED_MASK (ACPI_NFIT_MEM_SAVE_FAILED \
                | ACPI_NFIT_MEM_RESTORE_FAILED | ACPI_NFIT_MEM_FLUSH_FAILED \
                | ACPI_NFIT_MEM_NOT_ARMED | ACPI_NFIT_MEM_MAP_FAILED)
 
-#define NVDIMM_FAMILY_MAX NVDIMM_FAMILY_MSFT
+#define NVDIMM_FAMILY_MAX NVDIMM_FAMILY_HYPERV
 
 #define NVDIMM_STANDARD_CMDMASK \
 (1 << ND_CMD_SMART | 1 << ND_CMD_SMART_THRESHOLD | 1 << ND_CMD_DIMM_FLAGS \
@@ -94,6 +97,7 @@ enum nfit_uuids {
        NFIT_DEV_DIMM_N_HPE1 = NVDIMM_FAMILY_HPE1,
        NFIT_DEV_DIMM_N_HPE2 = NVDIMM_FAMILY_HPE2,
        NFIT_DEV_DIMM_N_MSFT = NVDIMM_FAMILY_MSFT,
+       NFIT_DEV_DIMM_N_HYPERV = NVDIMM_FAMILY_HYPERV,
        NFIT_SPA_VOLATILE,
        NFIT_SPA_PM,
        NFIT_SPA_DCR,
@@ -210,6 +214,13 @@ struct nfit_mem {
        int family;
 };
 
+enum scrub_flags {
+       ARS_BUSY,
+       ARS_CANCEL,
+       ARS_VALID,
+       ARS_POLL,
+};
+
 struct acpi_nfit_desc {
        struct nvdimm_bus_descriptor nd_desc;
        struct acpi_table_header acpi_header;
@@ -223,7 +234,6 @@ struct acpi_nfit_desc {
        struct list_head idts;
        struct nvdimm_bus *nvdimm_bus;
        struct device *dev;
-       u8 ars_start_flags;
        struct nd_cmd_ars_status *ars_status;
        struct nfit_spa *scrub_spa;
        struct delayed_work dwork;
@@ -232,8 +242,7 @@ struct acpi_nfit_desc {
        unsigned int max_ars;
        unsigned int scrub_count;
        unsigned int scrub_mode;
-       unsigned int scrub_busy:1;
-       unsigned int cancel:1;
+       unsigned long scrub_flags;
        unsigned long dimm_cmd_force_en;
        unsigned long bus_cmd_force_en;
        unsigned long bus_nfit_cmd_force_en;
index ad31c50de3be8582f483057efcae8d2476552f45..065c4fc245d117ff84b938790c232bbf555c0cb8 100644 (file)
@@ -209,6 +209,9 @@ static int acpi_pptt_leaf_node(struct acpi_table_header *table_hdr,
        struct acpi_pptt_processor *cpu_node;
        u32 proc_sz;
 
+       if (table_hdr->revision > 1)
+               return (node->flags & ACPI_PPTT_ACPI_LEAF_NODE);
+
        table_end = (unsigned long)table_hdr + table_hdr->length;
        node_entry = ACPI_PTR_DIFF(node, table_hdr);
        entry = ACPI_ADD_PTR(struct acpi_subtable_header, table_hdr,
index 41324f0b1bee26b73a55ddc027fb8f52928a31a5..fa76f5e41b5ca419978c804e8df8d8b2b714e329 100644 (file)
@@ -648,26 +648,29 @@ static void acpi_global_event_handler(u32 event_type, acpi_handle device,
        }
 }
 
-static int get_status(u32 index, acpi_event_status *status,
+static int get_status(u32 index, acpi_event_status *ret,
                      acpi_handle *handle)
 {
-       int result;
+       acpi_status status;
 
        if (index >= num_gpes + ACPI_NUM_FIXED_EVENTS)
                return -EINVAL;
 
        if (index < num_gpes) {
-               result = acpi_get_gpe_device(index, handle);
-               if (result) {
+               status = acpi_get_gpe_device(index, handle);
+               if (ACPI_FAILURE(status)) {
                        ACPI_EXCEPTION((AE_INFO, AE_NOT_FOUND,
                                        "Invalid GPE 0x%x", index));
-                       return result;
+                       return -ENXIO;
                }
-               result = acpi_get_gpe_status(*handle, index, status);
-       } else if (index < (num_gpes + ACPI_NUM_FIXED_EVENTS))
-               result = acpi_get_event_status(index - num_gpes, status);
+               status = acpi_get_gpe_status(*handle, index, ret);
+       } else {
+               status = acpi_get_event_status(index - num_gpes, ret);
+       }
+       if (ACPI_FAILURE(status))
+               return -EIO;
 
-       return result;
+       return 0;
 }
 
 static ssize_t counter_show(struct kobject *kobj,
index 2c334c01fc43cf986d707fe470e3414ddeafc5f9..76c9969b7124c11cf1638a82cc223999ae5e1b8a 100644 (file)
@@ -6,6 +6,8 @@
  * This file is released under the GPLv2.
  */
 
+#define pr_fmt(fmt) "PM: " fmt
+
 #include <linux/delay.h>
 #include <linux/kernel.h>
 #include <linux/io.h>
@@ -457,19 +459,19 @@ static int _genpd_power_off(struct generic_pm_domain *genpd, bool timed)
 
        time_start = ktime_get();
        ret = genpd->power_off(genpd);
-       if (ret == -EBUSY)
+       if (ret)
                return ret;
 
        elapsed_ns = ktime_to_ns(ktime_sub(ktime_get(), time_start));
        if (elapsed_ns <= genpd->states[state_idx].power_off_latency_ns)
-               return ret;
+               return 0;
 
        genpd->states[state_idx].power_off_latency_ns = elapsed_ns;
        genpd->max_off_time_changed = true;
        pr_debug("%s: Power-%s latency exceeded, new value %lld ns\n",
                 genpd->name, "off", elapsed_ns);
 
-       return ret;
+       return 0;
 }
 
 /**
@@ -1657,8 +1659,8 @@ int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd,
        genpd_lock_nested(genpd, SINGLE_DEPTH_NESTING);
 
        if (!list_empty(&subdomain->master_links) || subdomain->device_count) {
-               pr_warn("%s: unable to remove subdomain %s\n", genpd->name,
-                       subdomain->name);
+               pr_warn("%s: unable to remove subdomain %s\n",
+                       genpd->name, subdomain->name);
                ret = -EBUSY;
                goto out;
        }
@@ -1766,8 +1768,8 @@ int pm_genpd_init(struct generic_pm_domain *genpd,
                ret = genpd_set_default_power_state(genpd);
                if (ret)
                        return ret;
-       } else if (!gov) {
-               pr_warn("%s : no governor for states\n", genpd->name);
+       } else if (!gov && genpd->state_count > 1) {
+               pr_warn("%s: no governor for states\n", genpd->name);
        }
 
        device_initialize(&genpd->dev);
@@ -2514,7 +2516,7 @@ static int genpd_parse_state(struct genpd_power_state *genpd_state,
                                                &entry_latency);
        if (err) {
                pr_debug(" * %pOF missing entry-latency-us property\n",
-                                               state_node);
+                        state_node);
                return -EINVAL;
        }
 
@@ -2522,7 +2524,7 @@ static int genpd_parse_state(struct genpd_power_state *genpd_state,
                                                &exit_latency);
        if (err) {
                pr_debug(" * %pOF missing exit-latency-us property\n",
-                                               state_node);
+                        state_node);
                return -EINVAL;
        }
 
index 99896fbf18e439003095ccf18f2689ec6b7c1be3..4d07e38a8247f8ab354a79c9252a9d79d5746f84 100644 (file)
@@ -128,7 +128,6 @@ static bool __default_power_down_ok(struct dev_pm_domain *pd,
        off_on_time_ns = genpd->states[state].power_off_latency_ns +
                genpd->states[state].power_on_latency_ns;
 
-
        min_off_time_ns = -1;
        /*
         * Check if subdomains can be off for enough time.
index 5a8149829ab3954d74b76004c8b82886343d47ae..f80d298de3fa42d1e535e035e012975054920c6a 100644 (file)
@@ -17,6 +17,8 @@
  * subsystem list maintains.
  */
 
+#define pr_fmt(fmt) "PM: " fmt
+
 #include <linux/device.h>
 #include <linux/export.h>
 #include <linux/mutex.h>
@@ -128,7 +130,7 @@ void device_pm_add(struct device *dev)
        if (device_pm_not_required(dev))
                return;
 
-       pr_debug("PM: Adding info for %s:%s\n",
+       pr_debug("Adding info for %s:%s\n",
                 dev->bus ? dev->bus->name : "No Bus", dev_name(dev));
        device_pm_check_callbacks(dev);
        mutex_lock(&dpm_list_mtx);
@@ -149,7 +151,7 @@ void device_pm_remove(struct device *dev)
        if (device_pm_not_required(dev))
                return;
 
-       pr_debug("PM: Removing info for %s:%s\n",
+       pr_debug("Removing info for %s:%s\n",
                 dev->bus ? dev->bus->name : "No Bus", dev_name(dev));
        complete_all(&dev->power.completion);
        mutex_lock(&dpm_list_mtx);
@@ -168,7 +170,7 @@ void device_pm_remove(struct device *dev)
  */
 void device_pm_move_before(struct device *deva, struct device *devb)
 {
-       pr_debug("PM: Moving %s:%s before %s:%s\n",
+       pr_debug("Moving %s:%s before %s:%s\n",
                 deva->bus ? deva->bus->name : "No Bus", dev_name(deva),
                 devb->bus ? devb->bus->name : "No Bus", dev_name(devb));
        /* Delete deva from dpm_list and reinsert before devb. */
@@ -182,7 +184,7 @@ void device_pm_move_before(struct device *deva, struct device *devb)
  */
 void device_pm_move_after(struct device *deva, struct device *devb)
 {
-       pr_debug("PM: Moving %s:%s after %s:%s\n",
+       pr_debug("Moving %s:%s after %s:%s\n",
                 deva->bus ? deva->bus->name : "No Bus", dev_name(deva),
                 devb->bus ? devb->bus->name : "No Bus", dev_name(devb));
        /* Delete deva from dpm_list and reinsert after devb. */
@@ -195,7 +197,7 @@ void device_pm_move_after(struct device *deva, struct device *devb)
  */
 void device_pm_move_last(struct device *dev)
 {
-       pr_debug("PM: Moving %s:%s to end of list\n",
+       pr_debug("Moving %s:%s to end of list\n",
                 dev->bus ? dev->bus->name : "No Bus", dev_name(dev));
        list_move_tail(&dev->power.entry, &dpm_list);
 }
@@ -418,8 +420,8 @@ static void pm_dev_dbg(struct device *dev, pm_message_t state, const char *info)
 static void pm_dev_err(struct device *dev, pm_message_t state, const char *info,
                        int error)
 {
-       printk(KERN_ERR "PM: Device %s failed to %s%s: error %d\n",
-               dev_name(dev), pm_verb(state.event), info, error);
+       pr_err("Device %s failed to %s%s: error %d\n",
+              dev_name(dev), pm_verb(state.event), info, error);
 }
 
 static void dpm_show_time(ktime_t starttime, pm_message_t state, int error,
@@ -2022,8 +2024,7 @@ int dpm_prepare(pm_message_t state)
                                error = 0;
                                continue;
                        }
-                       printk(KERN_INFO "PM: Device %s not prepared "
-                               "for power transition: code %d\n",
+                       pr_info("Device %s not prepared for power transition: code %d\n",
                                dev_name(dev), error);
                        put_device(dev);
                        break;
@@ -2062,7 +2063,7 @@ EXPORT_SYMBOL_GPL(dpm_suspend_start);
 void __suspend_report_result(const char *function, void *fn, int ret)
 {
        if (ret)
-               printk(KERN_ERR "%s(): %pF returns %d\n", function, fn, ret);
+               pr_err("%s(): %pF returns %d\n", function, fn, ret);
 }
 EXPORT_SYMBOL_GPL(__suspend_report_result);
 
index c511def48b48621ba8ed13b84e23d34b1e47a899..ec33fbdb919b3506219928a52267de1a6275aa8b 100644 (file)
@@ -21,6 +21,7 @@ static inline void pm_runtime_early_init(struct device *dev)
 extern void pm_runtime_init(struct device *dev);
 extern void pm_runtime_reinit(struct device *dev);
 extern void pm_runtime_remove(struct device *dev);
+extern u64 pm_runtime_active_time(struct device *dev);
 
 #define WAKE_IRQ_DEDICATED_ALLOCATED   BIT(0)
 #define WAKE_IRQ_DEDICATED_MANAGED     BIT(1)
index 3382542b39b77fc0af6676f7be940f4d0a5c331f..f80e402ef778621511b72942f6697c1d74a112c4 100644 (file)
@@ -22,7 +22,7 @@
  * per-device constraint data struct.
  *
  * Note about the per-device constraint data struct allocation:
- * . The per-device constraints data struct ptr is tored into the device
+ * . The per-device constraints data struct ptr is stored into the device
  *    dev_pm_info.
  * . To minimize the data usage by the per-device constraints, the data struct
  *   is only allocated at the first call to dev_pm_qos_add_request.
index a80dbf08a99c533d93200af99d54ac82c7348ee2..977db40378b07e59fbb9943aacb437f9e47bc438 100644 (file)
@@ -64,7 +64,7 @@ static int rpm_suspend(struct device *dev, int rpmflags);
  * runtime_status field is updated, to account the time in the old state
  * correctly.
  */
-void update_pm_runtime_accounting(struct device *dev)
+static void update_pm_runtime_accounting(struct device *dev)
 {
        u64 now, last, delta;
 
@@ -98,7 +98,7 @@ static void __update_runtime_status(struct device *dev, enum rpm_status status)
        dev->power.runtime_status = status;
 }
 
-u64 pm_runtime_suspended_time(struct device *dev)
+static u64 rpm_get_accounted_time(struct device *dev, bool suspended)
 {
        u64 time;
        unsigned long flags;
@@ -106,12 +106,22 @@ u64 pm_runtime_suspended_time(struct device *dev)
        spin_lock_irqsave(&dev->power.lock, flags);
 
        update_pm_runtime_accounting(dev);
-       time = dev->power.suspended_time;
+       time = suspended ? dev->power.suspended_time : dev->power.active_time;
 
        spin_unlock_irqrestore(&dev->power.lock, flags);
 
        return time;
 }
+
+u64 pm_runtime_active_time(struct device *dev)
+{
+       return rpm_get_accounted_time(dev, false);
+}
+
+u64 pm_runtime_suspended_time(struct device *dev)
+{
+       return rpm_get_accounted_time(dev, true);
+}
 EXPORT_SYMBOL_GPL(pm_runtime_suspended_time);
 
 /**
index c6bf76124184c07ebdc0a10ea974b954f4f2489b..1226e441ddfede746d5652076e4396d41f3fa86f 100644 (file)
@@ -125,13 +125,9 @@ static ssize_t runtime_active_time_show(struct device *dev,
                                struct device_attribute *attr, char *buf)
 {
        int ret;
-       u64 tmp;
-       spin_lock_irq(&dev->power.lock);
-       update_pm_runtime_accounting(dev);
-       tmp = dev->power.active_time;
+       u64 tmp = pm_runtime_active_time(dev);
        do_div(tmp, NSEC_PER_MSEC);
        ret = sprintf(buf, "%llu\n", tmp);
-       spin_unlock_irq(&dev->power.lock);
        return ret;
 }
 
@@ -141,13 +137,9 @@ static ssize_t runtime_suspended_time_show(struct device *dev,
                                struct device_attribute *attr, char *buf)
 {
        int ret;
-       u64 tmp;
-       spin_lock_irq(&dev->power.lock);
-       update_pm_runtime_accounting(dev);
-       tmp = dev->power.suspended_time;
+       u64 tmp = pm_runtime_suspended_time(dev);
        do_div(tmp, NSEC_PER_MSEC);
        ret = sprintf(buf, "%llu\n", tmp);
-       spin_unlock_irq(&dev->power.lock);
        return ret;
 }
 
index b11f47a1e8193b447780f1176daf1b8b081eb034..2bd9d2c744cadf0365e7272c0bd049db9e991b58 100644 (file)
@@ -7,6 +7,8 @@
  * devices may be working.
  */
 
+#define pr_fmt(fmt) "PM: " fmt
+
 #include <linux/pm-trace.h>
 #include <linux/export.h>
 #include <linux/rtc.h>
index f1fee72ed970a50e7501c7be11ebe34da38c580a..bb1ae175fae136a57cd85e7566af617706e29232 100644 (file)
@@ -6,6 +6,8 @@
  * This file is released under the GPLv2.
  */
 
+#define pr_fmt(fmt) "PM: " fmt
+
 #include <linux/device.h>
 #include <linux/slab.h>
 #include <linux/sched/signal.h>
@@ -106,23 +108,6 @@ struct wakeup_source *wakeup_source_create(const char *name)
 }
 EXPORT_SYMBOL_GPL(wakeup_source_create);
 
-/**
- * wakeup_source_drop - Prepare a struct wakeup_source object for destruction.
- * @ws: Wakeup source to prepare for destruction.
- *
- * Callers must ensure that __pm_stay_awake() or __pm_wakeup_event() will never
- * be run in parallel with this function for the same wakeup source object.
- */
-void wakeup_source_drop(struct wakeup_source *ws)
-{
-       if (!ws)
-               return;
-
-       del_timer_sync(&ws->timer);
-       __pm_relax(ws);
-}
-EXPORT_SYMBOL_GPL(wakeup_source_drop);
-
 /*
  * Record wakeup_source statistics being deleted into a dummy wakeup_source.
  */
@@ -162,7 +147,7 @@ void wakeup_source_destroy(struct wakeup_source *ws)
        if (!ws)
                return;
 
-       wakeup_source_drop(ws);
+       __pm_relax(ws);
        wakeup_source_record(ws);
        kfree_const(ws->name);
        kfree(ws);
@@ -205,6 +190,13 @@ void wakeup_source_remove(struct wakeup_source *ws)
        list_del_rcu(&ws->entry);
        raw_spin_unlock_irqrestore(&events_lock, flags);
        synchronize_srcu(&wakeup_srcu);
+
+       del_timer_sync(&ws->timer);
+       /*
+        * Clear timer.function to make wakeup_source_not_registered() treat
+        * this wakeup source as not registered.
+        */
+       ws->timer.function = NULL;
 }
 EXPORT_SYMBOL_GPL(wakeup_source_remove);
 
@@ -853,7 +845,7 @@ bool pm_wakeup_pending(void)
        raw_spin_unlock_irqrestore(&events_lock, flags);
 
        if (ret) {
-               pr_debug("PM: Wakeup pending, aborting suspend\n");
+               pr_debug("Wakeup pending, aborting suspend\n");
                pm_print_active_wakeup_sources();
        }
 
index d2f0bb5ba47eabd3702a9c249f51f81f8d25a318..e705aab9e38ba8f6b82fc74ba74bbee5e3ec9843 100644 (file)
@@ -290,6 +290,12 @@ config COMMON_CLK_BD718XX
          This driver supports ROHM BD71837 and ROHM BD71847
          PMICs clock gates.
 
+config COMMON_CLK_FIXED_MMIO
+       bool "Clock driver for Memory Mapped Fixed values"
+       depends on COMMON_CLK && OF
+       help
+         Support for Memory Mapped IO Fixed clocks
+
 source "drivers/clk/actions/Kconfig"
 source "drivers/clk/bcm/Kconfig"
 source "drivers/clk/hisilicon/Kconfig"
index 8a9440a9750043ad80969367ed1938a6a9be1029..1db133652f0c3889a5f4d716ac32a32d403afd72 100644 (file)
@@ -27,6 +27,7 @@ obj-$(CONFIG_COMMON_CLK_CDCE925)      += clk-cdce925.o
 obj-$(CONFIG_ARCH_CLPS711X)            += clk-clps711x.o
 obj-$(CONFIG_COMMON_CLK_CS2000_CP)     += clk-cs2000-cp.o
 obj-$(CONFIG_ARCH_EFM32)               += clk-efm32gg.o
+obj-$(CONFIG_COMMON_CLK_FIXED_MMIO)    += clk-fixed-mmio.o
 obj-$(CONFIG_COMMON_CLK_GEMINI)                += clk-gemini.o
 obj-$(CONFIG_COMMON_CLK_ASPEED)                += clk-aspeed.o
 obj-$(CONFIG_ARCH_HIGHBANK)            += clk-highbank.o
@@ -78,7 +79,7 @@ obj-$(CONFIG_ARCH_K3)                 += keystone/
 obj-$(CONFIG_ARCH_KEYSTONE)            += keystone/
 obj-$(CONFIG_MACH_LOONGSON32)          += loongson1/
 obj-y                                  += mediatek/
-obj-$(CONFIG_COMMON_CLK_AMLOGIC)       += meson/
+obj-$(CONFIG_ARCH_MESON)               += meson/
 obj-$(CONFIG_MACH_PIC32)               += microchip/
 ifeq ($(CONFIG_COMMON_CLK), y)
 obj-$(CONFIG_ARCH_MMP)                 += mmp/
index 04f0a6355726f0503cfd0c4f84747b02a7d06089..5b45ca35757e837cb9fd18c5c60aede91a12c939 100644 (file)
@@ -9,6 +9,11 @@ if CLK_ACTIONS
 
 # SoC Drivers
 
+config CLK_OWL_S500
+       bool "Support for the Actions Semi OWL S500 clocks"
+       depends on ARCH_ACTIONS || COMPILE_TEST
+       default ARCH_ACTIONS
+
 config CLK_OWL_S700
        bool "Support for the Actions Semi OWL S700 clocks"
        depends on (ARM64 && ARCH_ACTIONS) || COMPILE_TEST
index ccfdf9781ceffd65be8a45a12b6321afe9a60e14..a2588e55c7902d76e008deb6d8f9d635b2a2f501 100644 (file)
@@ -10,5 +10,6 @@ clk-owl-y                     += owl-pll.o
 clk-owl-y                      += owl-reset.o
 
 # SoC support
+obj-$(CONFIG_CLK_OWL_S500)     += owl-s500.o
 obj-$(CONFIG_CLK_OWL_S700)     += owl-s700.o
 obj-$(CONFIG_CLK_OWL_S900)     += owl-s900.o
index 058e06d7099f6a6bc19722c37910bd8ebe0d05f6..02437bdedf4dbfe931026e4cd55c779e89e79eb3 100644 (file)
@@ -179,7 +179,7 @@ static int owl_pll_set_rate(struct clk_hw *hw, unsigned long rate,
 
        regmap_write(common->regmap, pll_hw->reg, reg);
 
-       udelay(PLL_STABILITY_WAIT_US);
+       udelay(pll_hw->delay);
 
        return 0;
 }
index 0aae30abd5dc7a14ca6a0cbca24169998b519f9a..6fb0d45bb0882b2ae06a1095939cca49ea08cbb0 100644 (file)
@@ -13,6 +13,8 @@
 
 #include "owl-common.h"
 
+#define OWL_PLL_DEF_DELAY      50
+
 /* last entry should have rate = 0 */
 struct clk_pll_table {
        unsigned int            val;
@@ -27,6 +29,7 @@ struct owl_pll_hw {
        u8                      width;
        u8                      min_mul;
        u8                      max_mul;
+       u8                      delay;
        const struct clk_pll_table *table;
 };
 
@@ -36,7 +39,7 @@ struct owl_pll {
 };
 
 #define OWL_PLL_HW(_reg, _bfreq, _bit_idx, _shift,                     \
-                  _width, _min_mul, _max_mul, _table)                  \
+                  _width, _min_mul, _max_mul, _delay, _table)          \
        {                                                               \
                .reg            = _reg,                                 \
                .bfreq          = _bfreq,                               \
@@ -45,6 +48,7 @@ struct owl_pll {
                .width          = _width,                               \
                .min_mul        = _min_mul,                             \
                .max_mul        = _max_mul,                             \
+               .delay          = _delay,                               \
                .table          = _table,                               \
        }
 
@@ -52,8 +56,8 @@ struct owl_pll {
                _shift, _width, _min_mul, _max_mul, _table, _flags)     \
        struct owl_pll _struct = {                                      \
                .pll_hw = OWL_PLL_HW(_reg, _bfreq, _bit_idx, _shift,    \
-                                    _width, _min_mul,                  \
-                                    _max_mul, _table),                 \
+                                    _width, _min_mul, _max_mul,        \
+                                    OWL_PLL_DEF_DELAY, _table),        \
                .common = {                                             \
                        .regmap = NULL,                                 \
                        .hw.init = CLK_HW_INIT(_name,                   \
@@ -67,8 +71,23 @@ struct owl_pll {
                _shift, _width, _min_mul, _max_mul, _table, _flags)     \
        struct owl_pll _struct = {                                      \
                .pll_hw = OWL_PLL_HW(_reg, _bfreq, _bit_idx, _shift,    \
-                                    _width, _min_mul,                  \
-                                    _max_mul, _table),                 \
+                                    _width, _min_mul, _max_mul,        \
+                                    OWL_PLL_DEF_DELAY, _table),        \
+               .common = {                                             \
+                       .regmap = NULL,                                 \
+                       .hw.init = CLK_HW_INIT_NO_PARENT(_name,         \
+                                              &owl_pll_ops,            \
+                                              _flags),                 \
+               },                                                      \
+       }
+
+#define OWL_PLL_NO_PARENT_DELAY(_struct, _name, _reg, _bfreq, _bit_idx,        \
+               _shift, _width, _min_mul, _max_mul, _delay, _table,     \
+               _flags)                                                 \
+       struct owl_pll _struct = {                                      \
+               .pll_hw = OWL_PLL_HW(_reg, _bfreq, _bit_idx, _shift,    \
+                                    _width, _min_mul,  _max_mul,       \
+                                    _delay, _table),                   \
                .common = {                                             \
                        .regmap = NULL,                                 \
                        .hw.init = CLK_HW_INIT_NO_PARENT(_name,         \
@@ -78,7 +97,6 @@ struct owl_pll {
        }
 
 #define mul_mask(m)            ((1 << ((m)->width)) - 1)
-#define PLL_STABILITY_WAIT_US  (50)
 
 static inline struct owl_pll *hw_to_owl_pll(const struct clk_hw *hw)
 {
diff --git a/drivers/clk/actions/owl-s500.c b/drivers/clk/actions/owl-s500.c
new file mode 100644 (file)
index 0000000..e2007ac
--- /dev/null
@@ -0,0 +1,525 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Actions Semi Owl S500 SoC clock driver
+ *
+ * Copyright (c) 2014 Actions Semi Inc.
+ * Author: David Liu <liuwei@actions-semi.com>
+ *
+ * Copyright (c) 2018 Linaro Ltd.
+ * Author: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+ *
+ * Copyright (c) 2018 LSI-TEC - Caninos Loucos
+ * Author: Edgar Bernardi Righi <edgar.righi@lsitec.org.br>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+
+#include "owl-common.h"
+#include "owl-composite.h"
+#include "owl-divider.h"
+#include "owl-factor.h"
+#include "owl-fixed-factor.h"
+#include "owl-gate.h"
+#include "owl-mux.h"
+#include "owl-pll.h"
+
+#include <dt-bindings/clock/actions,s500-cmu.h>
+
+#define CMU_COREPLL                    (0x0000)
+#define CMU_DEVPLL                     (0x0004)
+#define CMU_DDRPLL                     (0x0008)
+#define CMU_NANDPLL                    (0x000C)
+#define CMU_DISPLAYPLL                 (0x0010)
+#define CMU_AUDIOPLL                   (0x0014)
+#define CMU_TVOUTPLL                   (0x0018)
+#define CMU_BUSCLK                     (0x001C)
+#define CMU_SENSORCLK                  (0x0020)
+#define CMU_LCDCLK                     (0x0024)
+#define CMU_DSICLK                     (0x0028)
+#define CMU_CSICLK                     (0x002C)
+#define CMU_DECLK                      (0x0030)
+#define CMU_BISPCLK                    (0x0034)
+#define CMU_BUSCLK1                    (0x0038)
+#define CMU_VDECLK                     (0x0040)
+#define CMU_VCECLK                     (0x0044)
+#define CMU_NANDCCLK                   (0x004C)
+#define CMU_SD0CLK                     (0x0050)
+#define CMU_SD1CLK                     (0x0054)
+#define CMU_SD2CLK                     (0x0058)
+#define CMU_UART0CLK                   (0x005C)
+#define CMU_UART1CLK                   (0x0060)
+#define CMU_UART2CLK                   (0x0064)
+#define CMU_PWM4CLK                    (0x0068)
+#define CMU_PWM5CLK                    (0x006C)
+#define CMU_PWM0CLK                    (0x0070)
+#define CMU_PWM1CLK                    (0x0074)
+#define CMU_PWM2CLK                    (0x0078)
+#define CMU_PWM3CLK                    (0x007C)
+#define CMU_USBPLL                     (0x0080)
+#define CMU_ETHERNETPLL                        (0x0084)
+#define CMU_CVBSPLL                    (0x0088)
+#define CMU_LENSCLK                    (0x008C)
+#define CMU_GPU3DCLK                   (0x0090)
+#define CMU_CORECTL                    (0x009C)
+#define CMU_DEVCLKEN0                  (0x00A0)
+#define CMU_DEVCLKEN1                  (0x00A4)
+#define CMU_DEVRST0                    (0x00A8)
+#define CMU_DEVRST1                    (0x00AC)
+#define CMU_UART3CLK                   (0x00B0)
+#define CMU_UART4CLK                   (0x00B4)
+#define CMU_UART5CLK                   (0x00B8)
+#define CMU_UART6CLK                   (0x00BC)
+#define CMU_SSCLK                      (0x00C0)
+#define CMU_DIGITALDEBUG               (0x00D0)
+#define CMU_ANALOGDEBUG                        (0x00D4)
+#define CMU_COREPLLDEBUG               (0x00D8)
+#define CMU_DEVPLLDEBUG                        (0x00DC)
+#define CMU_DDRPLLDEBUG                        (0x00E0)
+#define CMU_NANDPLLDEBUG               (0x00E4)
+#define CMU_DISPLAYPLLDEBUG            (0x00E8)
+#define CMU_TVOUTPLLDEBUG              (0x00EC)
+#define CMU_DEEPCOLORPLLDEBUG          (0x00F4)
+#define CMU_AUDIOPLL_ETHPLLDEBUG       (0x00F8)
+#define CMU_CVBSPLLDEBUG               (0x00FC)
+
+#define OWL_S500_COREPLL_DELAY         (150)
+#define OWL_S500_DDRPLL_DELAY          (63)
+#define OWL_S500_DEVPLL_DELAY          (28)
+#define OWL_S500_NANDPLL_DELAY         (44)
+#define OWL_S500_DISPLAYPLL_DELAY      (57)
+#define OWL_S500_ETHERNETPLL_DELAY     (25)
+#define OWL_S500_AUDIOPLL_DELAY                (100)
+
+static const struct clk_pll_table clk_audio_pll_table[] = {
+       { 0, 45158400 }, { 1, 49152000 },
+       { 0, 0 },
+};
+
+/* pll clocks */
+static OWL_PLL_NO_PARENT_DELAY(ethernet_pll_clk, "ethernet_pll_clk", CMU_ETHERNETPLL, 500000000, 0, 0, 0, 0, 0, OWL_S500_ETHERNETPLL_DELAY, NULL, CLK_IGNORE_UNUSED);
+static OWL_PLL_NO_PARENT_DELAY(core_pll_clk, "core_pll_clk", CMU_COREPLL, 12000000, 9, 0, 8, 4, 134, OWL_S500_COREPLL_DELAY, NULL, CLK_IGNORE_UNUSED);
+static OWL_PLL_NO_PARENT_DELAY(ddr_pll_clk, "ddr_pll_clk", CMU_DDRPLL, 12000000, 8, 0, 8, 1, 67, OWL_S500_DDRPLL_DELAY, NULL, CLK_IGNORE_UNUSED);
+static OWL_PLL_NO_PARENT_DELAY(nand_pll_clk, "nand_pll_clk", CMU_NANDPLL, 6000000, 8, 0, 7, 2, 86, OWL_S500_NANDPLL_DELAY, NULL, CLK_IGNORE_UNUSED);
+static OWL_PLL_NO_PARENT_DELAY(display_pll_clk, "display_pll_clk", CMU_DISPLAYPLL, 6000000, 8, 0, 8, 2, 126, OWL_S500_DISPLAYPLL_DELAY, NULL, CLK_IGNORE_UNUSED);
+static OWL_PLL_NO_PARENT_DELAY(dev_pll_clk, "dev_pll_clk", CMU_DEVPLL, 6000000, 8, 0, 7, 8, 126, OWL_S500_DEVPLL_DELAY, NULL, CLK_IGNORE_UNUSED);
+static OWL_PLL_NO_PARENT_DELAY(audio_pll_clk, "audio_pll_clk", CMU_AUDIOPLL, 0, 4, 0, 1, 0, 0, OWL_S500_AUDIOPLL_DELAY, clk_audio_pll_table, CLK_IGNORE_UNUSED);
+
+static const char * const dev_clk_mux_p[] = { "hosc", "dev_pll_clk" };
+static const char * const bisp_clk_mux_p[] = { "display_pll_clk", "dev_clk" };
+static const char * const sensor_clk_mux_p[] = { "hosc", "bisp_clk" };
+static const char * const sd_clk_mux_p[] = { "dev_clk", "nand_pll_clk" };
+static const char * const pwm_clk_mux_p[] = { "losc", "hosc" };
+static const char * const ahbprediv_clk_mux_p[] = { "dev_clk", "display_pll_clk", "nand_pll_clk", "ddr_pll_clk" };
+static const char * const uart_clk_mux_p[] = { "hosc", "dev_pll_clk" };
+static const char * const de_clk_mux_p[] = { "display_pll_clk", "dev_clk" };
+static const char * const i2s_clk_mux_p[] = { "audio_pll_clk" };
+static const char * const hde_clk_mux_p[] = { "dev_clk", "display_pll_clk", "nand_pll_clk", "ddr_pll_clk" };
+static const char * const nand_clk_mux_p[] = { "nand_pll_clk", "display_pll_clk", "dev_clk", "ddr_pll_clk" };
+
+static struct clk_factor_table sd_factor_table[] = {
+       /* bit0 ~ 4 */
+       { 0, 1, 1 }, { 1, 1, 2 }, { 2, 1, 3 }, { 3, 1, 4 },
+       { 4, 1, 5 }, { 5, 1, 6 }, { 6, 1, 7 }, { 7, 1, 8 },
+       { 8, 1, 9 }, { 9, 1, 10 }, { 10, 1, 11 }, { 11, 1, 12 },
+       { 12, 1, 13 }, { 13, 1, 14 }, { 14, 1, 15 }, { 15, 1, 16 },
+       { 16, 1, 17 }, { 17, 1, 18 }, { 18, 1, 19 }, { 19, 1, 20 },
+       { 20, 1, 21 }, { 21, 1, 22 }, { 22, 1, 23 }, { 23, 1, 24 },
+       { 24, 1, 25 }, { 25, 1, 26 }, { 26, 1, 27 }, { 27, 1, 28 },
+       { 28, 1, 29 }, { 29, 1, 30 }, { 30, 1, 31 }, { 31, 1, 32 },
+
+       /* bit8: /128 */
+       { 256, 1, 1 * 128 }, { 257, 1, 2 * 128 }, { 258, 1, 3 * 128 }, { 259, 1, 4 * 128 },
+       { 260, 1, 5 * 128 }, { 261, 1, 6 * 128 }, { 262, 1, 7 * 128 }, { 263, 1, 8 * 128 },
+       { 264, 1, 9 * 128 }, { 265, 1, 10 * 128 }, { 266, 1, 11 * 128 }, { 267, 1, 12 * 128 },
+       { 268, 1, 13 * 128 }, { 269, 1, 14 * 128 }, { 270, 1, 15 * 128 }, { 271, 1, 16 * 128 },
+       { 272, 1, 17 * 128 }, { 273, 1, 18 * 128 }, { 274, 1, 19 * 128 }, { 275, 1, 20 * 128 },
+       { 276, 1, 21 * 128 }, { 277, 1, 22 * 128 }, { 278, 1, 23 * 128 }, { 279, 1, 24 * 128 },
+       { 280, 1, 25 * 128 }, { 281, 1, 26 * 128 }, { 282, 1, 27 * 128 }, { 283, 1, 28 * 128 },
+       { 284, 1, 29 * 128 }, { 285, 1, 30 * 128 }, { 286, 1, 31 * 128 }, { 287, 1, 32 * 128 },
+       { 0, 0, 0 },
+};
+
+static struct clk_factor_table bisp_factor_table[] = {
+       { 0, 1, 1 }, { 1, 1, 2 }, { 2, 1, 3 }, { 3, 1, 4 },
+       { 4, 1, 5 }, { 5, 1, 6 }, { 6, 1, 7 }, { 7, 1, 8 },
+       { 0, 0, 0 },
+};
+
+static struct clk_factor_table ahb_factor_table[] = {
+       { 1, 1, 2 }, { 2, 1, 3 },
+       { 0, 0, 0 },
+};
+
+static struct clk_div_table rmii_ref_div_table[] = {
+       { 0, 4 }, { 1, 10 },
+       { 0, 0 },
+};
+
+static struct clk_div_table i2s_div_table[] = {
+       { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 4 },
+       { 4, 6 }, { 5, 8 }, { 6, 12 }, { 7, 16 },
+       { 8, 24 },
+       { 0, 0 },
+};
+
+static struct clk_div_table nand_div_table[] = {
+       { 0, 1 }, { 1, 2 }, { 2, 4 }, { 3, 6 },
+       { 4, 8 }, { 5, 10 }, { 6, 12 }, { 7, 14 },
+       { 8, 16 }, { 9, 18 }, { 10, 20 }, { 11, 22 },
+       { 0, 0 },
+};
+
+/* mux clock */
+static OWL_MUX(dev_clk, "dev_clk", dev_clk_mux_p, CMU_DEVPLL, 12, 1, CLK_SET_RATE_PARENT);
+static OWL_MUX(ahbprediv_clk, "ahbprediv_clk", ahbprediv_clk_mux_p, CMU_BUSCLK1, 8, 3, CLK_SET_RATE_PARENT);
+
+/* gate clocks */
+static OWL_GATE(spi0_clk, "spi0_clk", "ahb_clk", CMU_DEVCLKEN1, 10, 0, CLK_IGNORE_UNUSED);
+static OWL_GATE(spi1_clk, "spi1_clk", "ahb_clk", CMU_DEVCLKEN1, 11, 0, CLK_IGNORE_UNUSED);
+static OWL_GATE(spi2_clk, "spi2_clk", "ahb_clk", CMU_DEVCLKEN1, 12, 0, CLK_IGNORE_UNUSED);
+static OWL_GATE(spi3_clk, "spi3_clk", "ahb_clk", CMU_DEVCLKEN1, 13, 0, CLK_IGNORE_UNUSED);
+static OWL_GATE(timer_clk, "timer_clk", "hosc", CMU_DEVCLKEN1, 27, 0, 0);
+static OWL_GATE(hdmi_clk, "hdmi_clk", "hosc", CMU_DEVCLKEN1, 3, 0, 0);
+
+/* divider clocks */
+static OWL_DIVIDER(h_clk, "h_clk", "ahbprevdiv_clk", CMU_BUSCLK1, 12, 2, NULL, 0, 0);
+static OWL_DIVIDER(rmii_ref_clk, "rmii_ref_clk", "ethernet_pll_clk", CMU_ETHERNETPLL, 1, 1, rmii_ref_div_table, 0, 0);
+
+/* factor clocks */
+static OWL_FACTOR(ahb_clk, "ahb_clk", "h_clk", CMU_BUSCLK1, 2, 2, ahb_factor_table, 0, 0);
+static OWL_FACTOR(de1_clk, "de_clk1", "de_clk", CMU_DECLK, 0, 3, bisp_factor_table, 0, 0);
+static OWL_FACTOR(de2_clk, "de_clk2", "de_clk", CMU_DECLK, 4, 3, bisp_factor_table, 0, 0);
+
+/* composite clocks */
+static OWL_COMP_FACTOR(vce_clk, "vce_clk", hde_clk_mux_p,
+                       OWL_MUX_HW(CMU_VCECLK, 4, 2),
+                       OWL_GATE_HW(CMU_DEVCLKEN0, 26, 0),
+                       OWL_FACTOR_HW(CMU_VCECLK, 0, 3, 0, bisp_factor_table),
+                       0);
+
+static OWL_COMP_FACTOR(vde_clk, "vde_clk", hde_clk_mux_p,
+                       OWL_MUX_HW(CMU_VDECLK, 4, 2),
+                       OWL_GATE_HW(CMU_DEVCLKEN0, 25, 0),
+                       OWL_FACTOR_HW(CMU_VDECLK, 0, 3, 0, bisp_factor_table),
+                       0);
+
+static OWL_COMP_FACTOR(bisp_clk, "bisp_clk", bisp_clk_mux_p,
+                       OWL_MUX_HW(CMU_BISPCLK, 4, 1),
+                       OWL_GATE_HW(CMU_DEVCLKEN0, 14, 0),
+                       OWL_FACTOR_HW(CMU_BISPCLK, 0, 3, 0, bisp_factor_table),
+                       0);
+
+static OWL_COMP_FACTOR(sensor0_clk, "sensor0_clk", sensor_clk_mux_p,
+                       OWL_MUX_HW(CMU_SENSORCLK, 4, 1),
+                       OWL_GATE_HW(CMU_DEVCLKEN0, 14, 0),
+                       OWL_FACTOR_HW(CMU_SENSORCLK, 0, 3, 0, bisp_factor_table),
+                       CLK_IGNORE_UNUSED);
+
+static OWL_COMP_FACTOR(sensor1_clk, "sensor1_clk", sensor_clk_mux_p,
+                       OWL_MUX_HW(CMU_SENSORCLK, 4, 1),
+                       OWL_GATE_HW(CMU_DEVCLKEN0, 14, 0),
+                       OWL_FACTOR_HW(CMU_SENSORCLK, 8, 3, 0, bisp_factor_table),
+                       CLK_IGNORE_UNUSED);
+
+static OWL_COMP_FACTOR(sd0_clk, "sd0_clk", sd_clk_mux_p,
+                       OWL_MUX_HW(CMU_SD0CLK, 9, 1),
+                       OWL_GATE_HW(CMU_DEVCLKEN0, 5, 0),
+                       OWL_FACTOR_HW(CMU_SD0CLK, 0, 9, 0, sd_factor_table),
+                       0);
+
+static OWL_COMP_FACTOR(sd1_clk, "sd1_clk", sd_clk_mux_p,
+                       OWL_MUX_HW(CMU_SD1CLK, 9, 1),
+                       OWL_GATE_HW(CMU_DEVCLKEN0, 6, 0),
+                       OWL_FACTOR_HW(CMU_SD1CLK, 0, 9, 0, sd_factor_table),
+                       0);
+
+static OWL_COMP_FACTOR(sd2_clk, "sd2_clk", sd_clk_mux_p,
+                       OWL_MUX_HW(CMU_SD2CLK, 9, 1),
+                       OWL_GATE_HW(CMU_DEVCLKEN0, 7, 0),
+                       OWL_FACTOR_HW(CMU_SD2CLK, 0, 9, 0, sd_factor_table),
+                       0);
+
+static OWL_COMP_DIV(pwm0_clk, "pwm0_clk", pwm_clk_mux_p,
+                       OWL_MUX_HW(CMU_PWM0CLK, 12, 1),
+                       OWL_GATE_HW(CMU_DEVCLKEN1, 23, 0),
+                       OWL_DIVIDER_HW(CMU_PWM0CLK, 0, 10, 0, NULL),
+                       0);
+
+static OWL_COMP_DIV(pwm1_clk, "pwm1_clk", pwm_clk_mux_p,
+                       OWL_MUX_HW(CMU_PWM1CLK, 12, 1),
+                       OWL_GATE_HW(CMU_DEVCLKEN1, 24, 0),
+                       OWL_DIVIDER_HW(CMU_PWM1CLK, 0, 10, 0, NULL),
+                       0);
+
+static OWL_COMP_DIV(pwm2_clk, "pwm2_clk", pwm_clk_mux_p,
+                       OWL_MUX_HW(CMU_PWM2CLK, 12, 1),
+                       OWL_GATE_HW(CMU_DEVCLKEN1, 25, 0),
+                       OWL_DIVIDER_HW(CMU_PWM2CLK, 0, 10, 0, NULL),
+                       0);
+
+static OWL_COMP_DIV(pwm3_clk, "pwm3_clk", pwm_clk_mux_p,
+                       OWL_MUX_HW(CMU_PWM3CLK, 12, 1),
+                       OWL_GATE_HW(CMU_DEVCLKEN1, 26, 0),
+                       OWL_DIVIDER_HW(CMU_PWM3CLK, 0, 10, 0, NULL),
+                       0);
+
+static OWL_COMP_DIV(pwm4_clk, "pwm4_clk", pwm_clk_mux_p,
+                       OWL_MUX_HW(CMU_PWM4CLK, 12, 1),
+                       OWL_GATE_HW(CMU_DEVCLKEN0, 11, 0),
+                       OWL_DIVIDER_HW(CMU_PWM4CLK, 0, 10, 0, NULL),
+                       0);
+
+static OWL_COMP_DIV(pwm5_clk, "pwm5_clk", pwm_clk_mux_p,
+                       OWL_MUX_HW(CMU_PWM5CLK, 12, 1),
+                       OWL_GATE_HW(CMU_DEVCLKEN0, 0, 0),
+                       OWL_DIVIDER_HW(CMU_PWM5CLK, 0, 10, 0, NULL),
+                       0);
+
+static OWL_COMP_PASS(de_clk, "de_clk", de_clk_mux_p,
+                       OWL_MUX_HW(CMU_DECLK, 12, 1),
+                       OWL_GATE_HW(CMU_DEVCLKEN0, 8, 0),
+                       0);
+
+static OWL_COMP_FIXED_FACTOR(i2c0_clk, "i2c0_clk", "ethernet_pll_clk",
+                       OWL_GATE_HW(CMU_DEVCLKEN1, 14, 0),
+                       1, 5, 0);
+
+static OWL_COMP_FIXED_FACTOR(i2c1_clk, "i2c1_clk", "ethernet_pll_clk",
+                       OWL_GATE_HW(CMU_DEVCLKEN1, 15, 0),
+                       1, 5, 0);
+
+static OWL_COMP_FIXED_FACTOR(i2c2_clk, "i2c2_clk", "ethernet_pll_clk",
+                       OWL_GATE_HW(CMU_DEVCLKEN1, 30, 0),
+                       1, 5, 0);
+
+static OWL_COMP_FIXED_FACTOR(i2c3_clk, "i2c3_clk", "ethernet_pll_clk",
+                       OWL_GATE_HW(CMU_DEVCLKEN1, 31, 0),
+                       1, 5, 0);
+
+static OWL_COMP_DIV(uart0_clk, "uart0_clk", uart_clk_mux_p,
+                       OWL_MUX_HW(CMU_UART0CLK, 16, 1),
+                       OWL_GATE_HW(CMU_DEVCLKEN1, 6, 0),
+                       OWL_DIVIDER_HW(CMU_UART1CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL),
+                       CLK_IGNORE_UNUSED);
+
+static OWL_COMP_DIV(uart1_clk, "uart1_clk", uart_clk_mux_p,
+                       OWL_MUX_HW(CMU_UART1CLK, 16, 1),
+                       OWL_GATE_HW(CMU_DEVCLKEN1, 7, 0),
+                       OWL_DIVIDER_HW(CMU_UART1CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL),
+                       CLK_IGNORE_UNUSED);
+
+static OWL_COMP_DIV(uart2_clk, "uart2_clk", uart_clk_mux_p,
+                       OWL_MUX_HW(CMU_UART2CLK, 16, 1),
+                       OWL_GATE_HW(CMU_DEVCLKEN1, 8, 0),
+                       OWL_DIVIDER_HW(CMU_UART1CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL),
+                       CLK_IGNORE_UNUSED);
+
+static OWL_COMP_DIV(uart3_clk, "uart3_clk", uart_clk_mux_p,
+                       OWL_MUX_HW(CMU_UART3CLK, 16, 1),
+                       OWL_GATE_HW(CMU_DEVCLKEN1, 19, 0),
+                       OWL_DIVIDER_HW(CMU_UART1CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL),
+                       CLK_IGNORE_UNUSED);
+
+static OWL_COMP_DIV(uart4_clk, "uart4_clk", uart_clk_mux_p,
+                       OWL_MUX_HW(CMU_UART4CLK, 16, 1),
+                       OWL_GATE_HW(CMU_DEVCLKEN1, 20, 0),
+                       OWL_DIVIDER_HW(CMU_UART1CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL),
+                       CLK_IGNORE_UNUSED);
+
+static OWL_COMP_DIV(uart5_clk, "uart5_clk", uart_clk_mux_p,
+                       OWL_MUX_HW(CMU_UART5CLK, 16, 1),
+                       OWL_GATE_HW(CMU_DEVCLKEN1, 21, 0),
+                       OWL_DIVIDER_HW(CMU_UART1CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL),
+                       CLK_IGNORE_UNUSED);
+
+static OWL_COMP_DIV(uart6_clk, "uart6_clk", uart_clk_mux_p,
+                       OWL_MUX_HW(CMU_UART6CLK, 16, 1),
+                       OWL_GATE_HW(CMU_DEVCLKEN1, 18, 0),
+                       OWL_DIVIDER_HW(CMU_UART1CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL),
+                       CLK_IGNORE_UNUSED);
+
+static OWL_COMP_DIV(i2srx_clk, "i2srx_clk", i2s_clk_mux_p,
+                       OWL_MUX_HW(CMU_AUDIOPLL, 24, 1),
+                       OWL_GATE_HW(CMU_DEVCLKEN0, 21, 0),
+                       OWL_DIVIDER_HW(CMU_AUDIOPLL, 20, 4, 0, i2s_div_table),
+                       0);
+
+static OWL_COMP_DIV(i2stx_clk, "i2stx_clk", i2s_clk_mux_p,
+                       OWL_MUX_HW(CMU_AUDIOPLL, 24, 1),
+                       OWL_GATE_HW(CMU_DEVCLKEN0, 20, 0),
+                       OWL_DIVIDER_HW(CMU_AUDIOPLL, 16, 4, 0, i2s_div_table),
+                       0);
+
+static OWL_COMP_DIV(hdmia_clk, "hdmia_clk", i2s_clk_mux_p,
+                       OWL_MUX_HW(CMU_AUDIOPLL, 24, 1),
+                       OWL_GATE_HW(CMU_DEVCLKEN0, 22, 0),
+                       OWL_DIVIDER_HW(CMU_AUDIOPLL, 24, 4, 0, i2s_div_table),
+                       0);
+
+static OWL_COMP_DIV(spdif_clk, "spdif_clk", i2s_clk_mux_p,
+                       OWL_MUX_HW(CMU_AUDIOPLL, 24, 1),
+                       OWL_GATE_HW(CMU_DEVCLKEN0, 23, 0),
+                       OWL_DIVIDER_HW(CMU_AUDIOPLL, 28, 4, 0, i2s_div_table),
+                       0);
+
+static OWL_COMP_DIV(nand_clk, "nand_clk", nand_clk_mux_p,
+                       OWL_MUX_HW(CMU_NANDCCLK, 8, 2),
+                       OWL_GATE_HW(CMU_DEVCLKEN0, 4, 0),
+                       OWL_DIVIDER_HW(CMU_NANDCCLK, 0, 3, 0, nand_div_table),
+                       CLK_SET_RATE_PARENT);
+
+static OWL_COMP_DIV(ecc_clk, "ecc_clk", nand_clk_mux_p,
+                       OWL_MUX_HW(CMU_NANDCCLK, 8, 2),
+                       OWL_GATE_HW(CMU_DEVCLKEN0, 4, 0),
+                       OWL_DIVIDER_HW(CMU_NANDCCLK, 4, 3, 0, nand_div_table),
+                       CLK_SET_RATE_PARENT);
+
+static struct owl_clk_common *s500_clks[] = {
+       &ethernet_pll_clk.common,
+       &core_pll_clk.common,
+       &ddr_pll_clk.common,
+       &dev_pll_clk.common,
+       &nand_pll_clk.common,
+       &audio_pll_clk.common,
+       &display_pll_clk.common,
+       &dev_clk.common,
+       &timer_clk.common,
+       &i2c0_clk.common,
+       &i2c1_clk.common,
+       &i2c2_clk.common,
+       &i2c3_clk.common,
+       &uart0_clk.common,
+       &uart1_clk.common,
+       &uart2_clk.common,
+       &uart3_clk.common,
+       &uart4_clk.common,
+       &uart5_clk.common,
+       &uart6_clk.common,
+       &pwm0_clk.common,
+       &pwm1_clk.common,
+       &pwm2_clk.common,
+       &pwm3_clk.common,
+       &pwm4_clk.common,
+       &pwm5_clk.common,
+       &sensor0_clk.common,
+       &sensor1_clk.common,
+       &sd0_clk.common,
+       &sd1_clk.common,
+       &sd2_clk.common,
+       &bisp_clk.common,
+       &ahb_clk.common,
+       &ahbprediv_clk.common,
+       &h_clk.common,
+       &spi0_clk.common,
+       &spi1_clk.common,
+       &spi2_clk.common,
+       &spi3_clk.common,
+       &rmii_ref_clk.common,
+       &de_clk.common,
+       &de1_clk.common,
+       &de2_clk.common,
+       &i2srx_clk.common,
+       &i2stx_clk.common,
+       &hdmia_clk.common,
+       &hdmi_clk.common,
+       &vce_clk.common,
+       &vde_clk.common,
+       &spdif_clk.common,
+       &nand_clk.common,
+       &ecc_clk.common,
+};
+
+static struct clk_hw_onecell_data s500_hw_clks = {
+       .hws = {
+               [CLK_ETHERNET_PLL]      = &ethernet_pll_clk.common.hw,
+               [CLK_CORE_PLL]          = &core_pll_clk.common.hw,
+               [CLK_DDR_PLL]           = &ddr_pll_clk.common.hw,
+               [CLK_NAND_PLL]          = &nand_pll_clk.common.hw,
+               [CLK_DISPLAY_PLL]       = &display_pll_clk.common.hw,
+               [CLK_DEV_PLL]           = &dev_pll_clk.common.hw,
+               [CLK_AUDIO_PLL]         = &audio_pll_clk.common.hw,
+               [CLK_TIMER]             = &timer_clk.common.hw,
+               [CLK_DEV]               = &dev_clk.common.hw,
+               [CLK_DE]                = &de_clk.common.hw,
+               [CLK_DE1]               = &de1_clk.common.hw,
+               [CLK_DE2]               = &de2_clk.common.hw,
+               [CLK_I2C0]              = &i2c0_clk.common.hw,
+               [CLK_I2C1]              = &i2c1_clk.common.hw,
+               [CLK_I2C2]              = &i2c2_clk.common.hw,
+               [CLK_I2C3]              = &i2c3_clk.common.hw,
+               [CLK_I2SRX]             = &i2srx_clk.common.hw,
+               [CLK_I2STX]             = &i2stx_clk.common.hw,
+               [CLK_UART0]             = &uart0_clk.common.hw,
+               [CLK_UART1]             = &uart1_clk.common.hw,
+               [CLK_UART2]             = &uart2_clk.common.hw,
+               [CLK_UART3]             = &uart3_clk.common.hw,
+               [CLK_UART4]             = &uart4_clk.common.hw,
+               [CLK_UART5]             = &uart5_clk.common.hw,
+               [CLK_UART6]             = &uart6_clk.common.hw,
+               [CLK_PWM0]              = &pwm0_clk.common.hw,
+               [CLK_PWM1]              = &pwm1_clk.common.hw,
+               [CLK_PWM2]              = &pwm2_clk.common.hw,
+               [CLK_PWM3]              = &pwm3_clk.common.hw,
+               [CLK_PWM4]              = &pwm4_clk.common.hw,
+               [CLK_PWM5]              = &pwm5_clk.common.hw,
+               [CLK_SENSOR0]           = &sensor0_clk.common.hw,
+               [CLK_SENSOR1]           = &sensor1_clk.common.hw,
+               [CLK_SD0]               = &sd0_clk.common.hw,
+               [CLK_SD1]               = &sd1_clk.common.hw,
+               [CLK_SD2]               = &sd2_clk.common.hw,
+               [CLK_BISP]              = &bisp_clk.common.hw,
+               [CLK_SPI0]              = &spi0_clk.common.hw,
+               [CLK_SPI1]              = &spi1_clk.common.hw,
+               [CLK_SPI2]              = &spi2_clk.common.hw,
+               [CLK_SPI3]              = &spi3_clk.common.hw,
+               [CLK_AHB]               = &ahb_clk.common.hw,
+               [CLK_H]                 = &h_clk.common.hw,
+               [CLK_AHBPREDIV]         = &ahbprediv_clk.common.hw,
+               [CLK_RMII_REF]          = &rmii_ref_clk.common.hw,
+               [CLK_HDMI_AUDIO]        = &hdmia_clk.common.hw,
+               [CLK_HDMI]              = &hdmi_clk.common.hw,
+               [CLK_VDE]               = &vde_clk.common.hw,
+               [CLK_VCE]               = &vce_clk.common.hw,
+               [CLK_SPDIF]             = &spdif_clk.common.hw,
+               [CLK_NAND]              = &nand_clk.common.hw,
+               [CLK_ECC]               = &ecc_clk.common.hw,
+       },
+       .num = CLK_NR_CLKS,
+};
+
+static struct owl_clk_desc s500_clk_desc = {
+       .clks       = s500_clks,
+       .num_clks   = ARRAY_SIZE(s500_clks),
+
+       .hw_clks    = &s500_hw_clks,
+};
+
+static int s500_clk_probe(struct platform_device *pdev)
+{
+       struct owl_clk_desc *desc;
+
+       desc = &s500_clk_desc;
+       owl_clk_regmap_init(pdev, desc);
+
+       return owl_clk_probe(&pdev->dev, desc->hw_clks);
+}
+
+static const struct of_device_id s500_clk_of_match[] = {
+       { .compatible = "actions,s500-cmu", },
+       { /* sentinel */ }
+};
+
+static struct platform_driver s500_clk_driver = {
+       .probe = s500_clk_probe,
+       .driver = {
+               .name = "s500-cmu",
+               .of_match_table = s500_clk_of_match,
+       },
+};
+
+static int __init s500_clk_init(void)
+{
+       return platform_driver_register(&s500_clk_driver);
+}
+core_initcall(s500_clk_init);
index 36d77146a3bd428c3f42aa5b73c3e69253fd58ea..3cc4a82f4e9fba347e4cc1fa837d4722c7f75f36 100644 (file)
@@ -340,7 +340,12 @@ static long clk_audio_pll_pmc_round_rate(struct clk_hw *hw, unsigned long rate,
        pr_debug("A PLL/PMC: %s, rate = %lu (parent_rate = %lu)\n", __func__,
                 rate, *parent_rate);
 
-       for (div = 1; div <= AUDIO_PLL_QDPMC_MAX; div++) {
+       if (!rate)
+               return 0;
+
+       best_parent_rate = clk_round_rate(pclk->clk, 1);
+       div = max(best_parent_rate / rate, 1UL);
+       for (; div <= AUDIO_PLL_QDPMC_MAX; div++) {
                best_parent_rate = clk_round_rate(pclk->clk, rate * div);
                tmp_rate = best_parent_rate / div;
                tmp_diff = abs(rate - tmp_rate);
@@ -350,6 +355,8 @@ static long clk_audio_pll_pmc_round_rate(struct clk_hw *hw, unsigned long rate,
                        best_rate = tmp_rate;
                        best_diff = tmp_diff;
                        tmp_qd = div;
+                       if (!best_diff)
+                               break;  /* got exact match */
                }
        }
 
index 5bc68b9c5498496b6f6af33ad87422804dd62ef4..89d6f3736dbf605036e4eefb70efd2ef2ee4f386 100644 (file)
@@ -132,11 +132,8 @@ static int clk_programmable_set_rate(struct clk_hw *hw, unsigned long rate,
        struct clk_programmable *prog = to_clk_programmable(hw);
        const struct clk_programmable_layout *layout = prog->layout;
        unsigned long div = parent_rate / rate;
-       unsigned int pckr;
        int shift = 0;
 
-       regmap_read(prog->regmap, AT91_PMC_PCKR(prog->id), &pckr);
-
        if (!div)
                return -EINVAL;
 
index cd0ef7274fdbf1ddab7f167724aa7868a5b92ae0..1f70cb164b06f310d867d54797dfd0d87be0a1d3 100644 (file)
@@ -241,13 +241,14 @@ static void __init sama5d2_pmc_setup(struct device_node *np)
        parent_names[2] = "plladivck";
        parent_names[3] = "utmick";
        parent_names[4] = "masterck";
+       parent_names[5] = "audiopll_pmcck";
        for (i = 0; i < 3; i++) {
                char name[6];
 
                snprintf(name, sizeof(name), "prog%d", i);
 
                hw = at91_clk_register_programmable(regmap, name,
-                                                   parent_names, 5, i,
+                                                   parent_names, 6, i,
                                                    &at91sam9x5_programmable_layout);
                if (IS_ERR(hw))
                        goto err_free;
index 2c04396402ab4a788f9d94c08db78bbcabd831ea..c36c47bdba0250fdf697e00aa845fb3abd9febd8 100644 (file)
@@ -44,21 +44,21 @@ struct clps711x_clk {
        struct clk_hw_onecell_data      clk_data;
 };
 
-static struct clps711x_clk * __init _clps711x_clk_init(void __iomem *base,
-                                                      u32 fref)
+static void __init clps711x_clk_init_dt(struct device_node *np)
 {
-       u32 tmp, f_cpu, f_pll, f_bus, f_tim, f_pwm, f_spi;
+       u32 tmp, f_cpu, f_pll, f_bus, f_tim, f_pwm, f_spi, fref = 0;
        struct clps711x_clk *clps711x_clk;
-       unsigned i;
+       void __iomem *base;
+
+       WARN_ON(of_property_read_u32(np, "startup-frequency", &fref));
 
-       if (!base)
-               return ERR_PTR(-ENOMEM);
+       base = of_iomap(np, 0);
+       BUG_ON(!base);
 
        clps711x_clk = kzalloc(struct_size(clps711x_clk, clk_data.hws,
                                           CLPS711X_CLK_MAX),
                               GFP_KERNEL);
-       if (!clps711x_clk)
-               return ERR_PTR(-ENOMEM);
+       BUG_ON(!clps711x_clk);
 
        spin_lock_init(&clps711x_clk->lock);
 
@@ -137,52 +137,13 @@ static struct clps711x_clk * __init _clps711x_clk_init(void __iomem *base,
                clk_hw_register_fixed_factor(NULL, "uart", "bus", 0, 1, 10);
        clps711x_clk->clk_data.hws[CLPS711X_CLK_TICK] =
                clk_hw_register_fixed_rate(NULL, "tick", NULL, 0, 64);
-       for (i = 0; i < CLPS711X_CLK_MAX; i++)
-               if (IS_ERR(clps711x_clk->clk_data.hws[i]))
+       for (tmp = 0; tmp < CLPS711X_CLK_MAX; tmp++)
+               if (IS_ERR(clps711x_clk->clk_data.hws[tmp]))
                        pr_err("clk %i: register failed with %ld\n",
-                              i, PTR_ERR(clps711x_clk->clk_data.hws[i]));
-
-       return clps711x_clk;
-}
-
-void __init clps711x_clk_init(void __iomem *base)
-{
-       struct clps711x_clk *clps711x_clk;
-
-       clps711x_clk = _clps711x_clk_init(base, 73728000);
-
-       BUG_ON(IS_ERR(clps711x_clk));
-
-       /* Clocksource */
-       clk_hw_register_clkdev(clps711x_clk->clk_data.hws[CLPS711X_CLK_TIMER1],
-                           NULL, "clps711x-timer.0");
-       clk_hw_register_clkdev(clps711x_clk->clk_data.hws[CLPS711X_CLK_TIMER2],
-                           NULL, "clps711x-timer.1");
-
-       /* Drivers */
-       clk_hw_register_clkdev(clps711x_clk->clk_data.hws[CLPS711X_CLK_PWM],
-                           NULL, "clps711x-pwm");
-       clk_hw_register_clkdev(clps711x_clk->clk_data.hws[CLPS711X_CLK_UART],
-                           NULL, "clps711x-uart.0");
-       clk_hw_register_clkdev(clps711x_clk->clk_data.hws[CLPS711X_CLK_UART],
-                           NULL, "clps711x-uart.1");
-}
-
-#ifdef CONFIG_OF
-static void __init clps711x_clk_init_dt(struct device_node *np)
-{
-       void __iomem *base = of_iomap(np, 0);
-       struct clps711x_clk *clps711x_clk;
-       u32 fref = 0;
-
-       WARN_ON(of_property_read_u32(np, "startup-frequency", &fref));
-
-       clps711x_clk = _clps711x_clk_init(base, fref);
-       BUG_ON(IS_ERR(clps711x_clk));
+                              tmp, PTR_ERR(clps711x_clk->clk_data.hws[tmp]));
 
        clps711x_clk->clk_data.num = CLPS711X_CLK_MAX;
        of_clk_add_hw_provider(np, of_clk_hw_onecell_get,
                               &clps711x_clk->clk_data);
 }
 CLK_OF_DECLARE(clps711x, "cirrus,ep7209-clk", clps711x_clk_init_dt);
-#endif
index c9a86156ced85e29b85177b54fc93ee5d586a0f3..daa1fc8fba5370e8135e1b5a8fd2a9854c91c278 100644 (file)
@@ -29,6 +29,17 @@ struct clk *devm_clk_get(struct device *dev, const char *id)
 }
 EXPORT_SYMBOL(devm_clk_get);
 
+struct clk *devm_clk_get_optional(struct device *dev, const char *id)
+{
+       struct clk *clk = devm_clk_get(dev, id);
+
+       if (clk == ERR_PTR(-ENOENT))
+               return NULL;
+
+       return clk;
+}
+EXPORT_SYMBOL(devm_clk_get_optional);
+
 struct clk_bulk_devres {
        struct clk_bulk_data *clks;
        int num_clks;
diff --git a/drivers/clk/clk-fixed-mmio.c b/drivers/clk/clk-fixed-mmio.c
new file mode 100644 (file)
index 0000000..d1a97d9
--- /dev/null
@@ -0,0 +1,101 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/*
+ * Memory Mapped IO Fixed clock driver
+ *
+ * Copyright (C) 2018 Cadence Design Systems, Inc.
+ *
+ * Authors:
+ *     Jan Kotas <jank@cadence.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/of_address.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+static struct clk_hw *fixed_mmio_clk_setup(struct device_node *node)
+{
+       struct clk_hw *clk;
+       const char *clk_name = node->name;
+       void __iomem *base;
+       u32 freq;
+       int ret;
+
+       base = of_iomap(node, 0);
+       if (!base) {
+               pr_err("%pOFn: failed to map address\n", node);
+               return ERR_PTR(-EIO);
+       }
+
+       freq = readl(base);
+       iounmap(base);
+       of_property_read_string(node, "clock-output-names", &clk_name);
+
+       clk = clk_hw_register_fixed_rate(NULL, clk_name, NULL, 0, freq);
+       if (IS_ERR(clk)) {
+               pr_err("%pOFn: failed to register fixed rate clock\n", node);
+               return clk;
+       }
+
+       ret = of_clk_add_hw_provider(node, of_clk_hw_simple_get, clk);
+       if (ret) {
+               pr_err("%pOFn: failed to add clock provider\n", node);
+               clk_hw_unregister(clk);
+               clk = ERR_PTR(ret);
+       }
+
+       return clk;
+}
+
+static void __init of_fixed_mmio_clk_setup(struct device_node *node)
+{
+       fixed_mmio_clk_setup(node);
+}
+CLK_OF_DECLARE(fixed_mmio_clk, "fixed-mmio-clock", of_fixed_mmio_clk_setup);
+
+/**
+ * This is not executed when of_fixed_mmio_clk_setup succeeded.
+ */
+static int of_fixed_mmio_clk_probe(struct platform_device *pdev)
+{
+       struct clk_hw *clk;
+
+       clk = fixed_mmio_clk_setup(pdev->dev.of_node);
+       if (IS_ERR(clk))
+               return PTR_ERR(clk);
+
+       platform_set_drvdata(pdev, clk);
+
+       return 0;
+}
+
+static int of_fixed_mmio_clk_remove(struct platform_device *pdev)
+{
+       struct clk_hw *clk = platform_get_drvdata(pdev);
+
+       of_clk_del_provider(pdev->dev.of_node);
+       clk_hw_unregister_fixed_rate(clk);
+
+       return 0;
+}
+
+static const struct of_device_id of_fixed_mmio_clk_ids[] = {
+       { .compatible = "fixed-mmio-clock" },
+       { }
+};
+MODULE_DEVICE_TABLE(of, of_fixed_mmio_clk_ids);
+
+static struct platform_driver of_fixed_mmio_clk_driver = {
+       .driver = {
+               .name = "of_fixed_mmio_clk",
+               .of_match_table = of_fixed_mmio_clk_ids,
+       },
+       .probe = of_fixed_mmio_clk_probe,
+       .remove = of_fixed_mmio_clk_remove,
+};
+module_platform_driver(of_fixed_mmio_clk_driver);
+
+MODULE_AUTHOR("Jan Kotas <jank@cadence.com>");
+MODULE_DESCRIPTION("Memory Mapped IO Fixed clock driver");
+MODULE_LICENSE("GPL v2");
index 545dceec0bbf0230f72163a1d0506f1dc8401b49..fdfe2e423d1506e96a059cdb054796dd9c955bd6 100644 (file)
@@ -79,7 +79,7 @@ static long clk_fd_round_rate(struct clk_hw *hw, unsigned long rate,
        unsigned long m, n;
        u64 ret;
 
-       if (!rate || rate >= *parent_rate)
+       if (!rate || (!clk_hw_can_set_rate_parent(hw) && rate >= *parent_rate))
                return *parent_rate;
 
        if (fd->approximation)
index 25eed3e0251f3ef99bfec457e7d628337a307847..c2f07f0d077c7659727cdbe39d0c970821db5c9b 100644 (file)
@@ -58,6 +58,35 @@ const struct clk_ops clk_gpio_gate_ops = {
 };
 EXPORT_SYMBOL_GPL(clk_gpio_gate_ops);
 
+static int clk_sleeping_gpio_gate_prepare(struct clk_hw *hw)
+{
+       struct clk_gpio *clk = to_clk_gpio(hw);
+
+       gpiod_set_value_cansleep(clk->gpiod, 1);
+
+       return 0;
+}
+
+static void clk_sleeping_gpio_gate_unprepare(struct clk_hw *hw)
+{
+       struct clk_gpio *clk = to_clk_gpio(hw);
+
+       gpiod_set_value_cansleep(clk->gpiod, 0);
+}
+
+static int clk_sleeping_gpio_gate_is_prepared(struct clk_hw *hw)
+{
+       struct clk_gpio *clk = to_clk_gpio(hw);
+
+       return gpiod_get_value_cansleep(clk->gpiod);
+}
+
+static const struct clk_ops clk_sleeping_gpio_gate_ops = {
+       .prepare = clk_sleeping_gpio_gate_prepare,
+       .unprepare = clk_sleeping_gpio_gate_unprepare,
+       .is_prepared = clk_sleeping_gpio_gate_is_prepared,
+};
+
 /**
  * DOC: basic clock multiplexer which can be controlled with a gpio output
  * Traits of this clock:
@@ -144,10 +173,16 @@ struct clk_hw *clk_hw_register_gpio_gate(struct device *dev, const char *name,
                const char *parent_name, struct gpio_desc *gpiod,
                unsigned long flags)
 {
+       const struct clk_ops *ops;
+
+       if (gpiod_cansleep(gpiod))
+               ops = &clk_sleeping_gpio_gate_ops;
+       else
+               ops = &clk_gpio_gate_ops;
+
        return clk_register_gpio(dev, name,
                        (parent_name ? &parent_name : NULL),
-                       (parent_name ? 1 : 0), gpiod, flags,
-                       &clk_gpio_gate_ops);
+                       (parent_name ? 1 : 0), gpiod, flags, ops);
 }
 EXPORT_SYMBOL_GPL(clk_hw_register_gpio_gate);
 
index 727ed8e1bb726fd424f97427507abe6f46fe84a9..8e4581004695c44f11ea66250773c60720f4bbb8 100644 (file)
@@ -293,6 +293,7 @@ static __init struct clk *hb_clk_init(struct device_node *node, const struct clk
        /* Map system registers */
        srnp = of_find_compatible_node(NULL, NULL, "calxeda,hb-sregs");
        hb_clk->reg = of_iomap(srnp, 0);
+       of_node_put(srnp);
        BUG_ON(!hb_clk->reg);
        hb_clk->reg += reg;
 
index 22c937644c93eb6aaaf3e35153235a943c742ee0..3727d54724500d4978766ba52ee2cc1e08510001 100644 (file)
@@ -235,8 +235,9 @@ static int max77686_clk_probe(struct platform_device *pdev)
                        return ret;
                }
 
-               ret = clk_hw_register_clkdev(&max_clk_data->hw,
-                                            max_clk_data->clk_idata.name, NULL);
+               ret = devm_clk_hw_register_clkdev(dev, &max_clk_data->hw,
+                                                 max_clk_data->clk_idata.name,
+                                                 NULL);
                if (ret < 0) {
                        dev_err(dev, "Failed to clkdev register: %d\n", ret);
                        return ret;
@@ -244,8 +245,8 @@ static int max77686_clk_probe(struct platform_device *pdev)
        }
 
        if (parent->of_node) {
-               ret = of_clk_add_hw_provider(parent->of_node, of_clk_max77686_get,
-                                            drv_data);
+               ret = devm_of_clk_add_hw_provider(dev, of_clk_max77686_get,
+                                                 drv_data);
 
                if (ret < 0) {
                        dev_err(dev, "Failed to register OF clock provider: %d\n",
@@ -261,27 +262,11 @@ static int max77686_clk_probe(struct platform_device *pdev)
                                         1 << MAX77802_CLOCK_LOW_JITTER_SHIFT);
                if (ret < 0) {
                        dev_err(dev, "Failed to config low-jitter: %d\n", ret);
-                       goto remove_of_clk_provider;
+                       return ret;
                }
        }
 
        return 0;
-
-remove_of_clk_provider:
-       if (parent->of_node)
-               of_clk_del_provider(parent->of_node);
-
-       return ret;
-}
-
-static int max77686_clk_remove(struct platform_device *pdev)
-{
-       struct device *parent = pdev->dev.parent;
-
-       if (parent->of_node)
-               of_clk_del_provider(parent->of_node);
-
-       return 0;
 }
 
 static const struct platform_device_id max77686_clk_id[] = {
@@ -297,7 +282,6 @@ static struct platform_driver max77686_clk_driver = {
                .name  = "max77686-clk",
        },
        .probe = max77686_clk_probe,
-       .remove = max77686_clk_remove,
        .id_table = max77686_clk_id,
 };
 
index 5baa9e051110c3036570b884b6914dd6245b0233..1212a9be7e80f0d389b00670b1b345f409b63448 100644 (file)
@@ -1148,8 +1148,8 @@ static void __init create_one_pll(struct clockgen *cg, int idx)
                pll->div[i].clk = clk;
                ret = clk_register_clkdev(clk, pll->div[i].name, NULL);
                if (ret != 0)
-                       pr_err("%s: %s: register to lookup table failed %ld\n",
-                              __func__, pll->div[i].name, PTR_ERR(clk));
+                       pr_err("%s: %s: register to lookup table failed %d\n",
+                              __func__, pll->div[i].name, ret);
 
        }
 }
@@ -1389,6 +1389,7 @@ static void __init clockgen_init(struct device_node *np)
                                pr_err("%s: Couldn't map %pOF regs\n", __func__,
                                       guts);
                        }
+                       of_node_put(guts);
                }
 
        }
index 6a31f7f434ce47739bdeb548aa6154a013dfe1ae..a0ae8dc1690905f2960b3ba42f2bb3185b156a36 100644 (file)
@@ -121,7 +121,7 @@ static const char * const cpu_src[] = {
 };
 
 static const char * const axi_src[] = {
-       "ck_hsi", "ck_hse", "pll2_p", "pll3_p"
+       "ck_hsi", "ck_hse", "pll2_p"
 };
 
 static const char * const per_src[] = {
@@ -225,19 +225,19 @@ static const char * const usart6_src[] = {
 };
 
 static const char * const fdcan_src[] = {
-       "ck_hse", "pll3_q", "pll4_q"
+       "ck_hse", "pll3_q", "pll4_q", "pll4_r"
 };
 
 static const char * const sai_src[] = {
-       "pll4_q", "pll3_q", "i2s_ckin", "ck_per"
+       "pll4_q", "pll3_q", "i2s_ckin", "ck_per", "pll3_r"
 };
 
 static const char * const sai2_src[] = {
-       "pll4_q", "pll3_q", "i2s_ckin", "ck_per", "spdif_ck_symb"
+       "pll4_q", "pll3_q", "i2s_ckin", "ck_per", "spdif_ck_symb", "pll3_r"
 };
 
 static const char * const adc12_src[] = {
-       "pll4_q", "ck_per"
+       "pll4_r", "ck_per", "pll3_q"
 };
 
 static const char * const dsi_src[] = {
@@ -269,7 +269,7 @@ static const struct clk_div_table axi_div_table[] = {
 static const struct clk_div_table mcu_div_table[] = {
        { 0, 1 }, { 1, 2 }, { 2, 4 }, { 3, 8 },
        { 4, 16 }, { 5, 32 }, { 6, 64 }, { 7, 128 },
-       { 8, 512 }, { 9, 512 }, { 10, 512}, { 11, 512 },
+       { 8, 256 }, { 9, 512 }, { 10, 512}, { 11, 512 },
        { 12, 512 }, { 13, 512 }, { 14, 512}, { 15, 512 },
        { 0 },
 };
@@ -1286,10 +1286,11 @@ _clk_stm32_register_composite(struct device *dev,
        MGATE_MP1(_id, _name, _parent, _flags, _mgate)
 
 #define KCLK(_id, _name, _parents, _flags, _mgate, _mmux)\
-            COMPOSITE(_id, _name, _parents, CLK_OPS_PARENT_ENABLE | _flags,\
-                 _MGATE_MP1(_mgate),\
-                 _MMUX(_mmux),\
-                 _NO_DIV)
+            COMPOSITE(_id, _name, _parents, CLK_OPS_PARENT_ENABLE |\
+                      CLK_SET_RATE_NO_REPARENT | _flags,\
+                      _MGATE_MP1(_mgate),\
+                      _MMUX(_mmux),\
+                      _NO_DIV)
 
 enum {
        G_SAI1,
@@ -1655,12 +1656,14 @@ static const struct stm32_mux_cfg ker_mux_cfg[M_LAST] = {
 
 static const struct clock_config stm32mp1_clock_cfg[] = {
        /* Oscillator divider */
-       DIV(NO_ID, "clk-hsi-div", "clk-hsi", 0, RCC_HSICFGR, 0, 2,
-           CLK_DIVIDER_READ_ONLY),
+       DIV(NO_ID, "clk-hsi-div", "clk-hsi", CLK_DIVIDER_POWER_OF_TWO,
+           RCC_HSICFGR, 0, 2, CLK_DIVIDER_READ_ONLY),
 
        /*  External / Internal Oscillators */
        GATE_MP1(CK_HSE, "ck_hse", "clk-hse", 0, RCC_OCENSETR, 8, 0),
-       GATE_MP1(CK_CSI, "ck_csi", "clk-csi", 0, RCC_OCENSETR, 4, 0),
+       /* ck_csi is used by IO compensation and should be critical */
+       GATE_MP1(CK_CSI, "ck_csi", "clk-csi", CLK_IS_CRITICAL,
+                RCC_OCENSETR, 4, 0),
        GATE_MP1(CK_HSI, "ck_hsi", "clk-hsi-div", 0, RCC_OCENSETR, 0, 0),
        GATE(CK_LSI, "ck_lsi", "clk-lsi", 0, RCC_RDLSICR, 0, 0),
        GATE(CK_LSE, "ck_lse", "clk-lse", 0, RCC_BDCR, 0, 0),
@@ -1952,14 +1955,14 @@ static const struct clock_config stm32mp1_clock_cfg[] = {
        MGATE_MP1(GPU_K, "gpu_k", "pll2_q", 0, G_GPU),
        MGATE_MP1(DAC12_K, "dac12_k", "ck_lsi", 0, G_DAC12),
 
-       COMPOSITE(ETHPTP_K, "ethptp_k", eth_src, CLK_OPS_PARENT_ENABLE,
+       COMPOSITE(ETHPTP_K, "ethptp_k", eth_src, CLK_OPS_PARENT_ENABLE |
+                 CLK_SET_RATE_NO_REPARENT,
                  _NO_GATE,
                  _MMUX(M_ETHCK),
-                 _DIV(RCC_ETHCKSELR, 4, 4, CLK_DIVIDER_ALLOW_ZERO, NULL)),
+                 _DIV(RCC_ETHCKSELR, 4, 4, 0, NULL)),
 
        /* RTC clock */
-       DIV(NO_ID, "ck_hse_rtc", "ck_hse", 0, RCC_RTCDIVR, 0, 7,
-           CLK_DIVIDER_ALLOW_ZERO),
+       DIV(NO_ID, "ck_hse_rtc", "ck_hse", 0, RCC_RTCDIVR, 0, 6, 0),
 
        COMPOSITE(RTC, "ck_rtc", rtc_src, CLK_OPS_PARENT_ENABLE |
                   CLK_SET_RATE_PARENT,
index ea846f77750b82db151ca8c46fa9c29ac1386458..0cad5748bf0ec0462d64580d02d4127538d1ecef 100644 (file)
@@ -41,6 +41,43 @@ static int twl6040_pdmclk_is_prepared(struct clk_hw *hw)
        return pdmclk->enabled;
 }
 
+static int twl6040_pdmclk_reset_one_clock(struct twl6040_pdmclk *pdmclk,
+                                         unsigned int reg)
+{
+       const u8 reset_mask = TWL6040_HPLLRST;  /* Same for HPPLL and LPPLL */
+       int ret;
+
+       ret = twl6040_set_bits(pdmclk->twl6040, reg, reset_mask);
+       if (ret < 0)
+               return ret;
+
+       ret = twl6040_clear_bits(pdmclk->twl6040, reg, reset_mask);
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+
+/*
+ * TWL6040A2 Phoenix Audio IC erratum #6: "PDM Clock Generation Issue At
+ * Cold Temperature". This affects cold boot and deeper idle states it
+ * seems. The workaround consists of resetting HPPLL and LPPLL.
+ */
+static int twl6040_pdmclk_quirk_reset_clocks(struct twl6040_pdmclk *pdmclk)
+{
+       int ret;
+
+       ret = twl6040_pdmclk_reset_one_clock(pdmclk, TWL6040_REG_HPPLLCTL);
+       if (ret)
+               return ret;
+
+       ret = twl6040_pdmclk_reset_one_clock(pdmclk, TWL6040_REG_LPPLLCTL);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
 static int twl6040_pdmclk_prepare(struct clk_hw *hw)
 {
        struct twl6040_pdmclk *pdmclk = container_of(hw, struct twl6040_pdmclk,
@@ -48,8 +85,20 @@ static int twl6040_pdmclk_prepare(struct clk_hw *hw)
        int ret;
 
        ret = twl6040_power(pdmclk->twl6040, 1);
-       if (!ret)
-               pdmclk->enabled = 1;
+       if (ret)
+               return ret;
+
+       ret = twl6040_pdmclk_quirk_reset_clocks(pdmclk);
+       if (ret)
+               goto out_err;
+
+       pdmclk->enabled = 1;
+
+       return 0;
+
+out_err:
+       dev_err(pdmclk->dev, "%s: error %i\n", __func__, ret);
+       twl6040_power(pdmclk->twl6040, 0);
 
        return ret;
 }
index d2477a5058ac2eb2d7925f04ae435479ff1efc9a..96053a96fe2fc4878250aabf92601de729838cd3 100644 (file)
@@ -57,6 +57,7 @@ struct clk_core {
        struct clk_core         *new_child;
        unsigned long           flags;
        bool                    orphan;
+       bool                    rpm_enabled;
        unsigned int            enable_count;
        unsigned int            prepare_count;
        unsigned int            protect_count;
@@ -81,6 +82,7 @@ struct clk_core {
 
 struct clk {
        struct clk_core *core;
+       struct device *dev;
        const char *dev_id;
        const char *con_id;
        unsigned long min_rate;
@@ -92,9 +94,9 @@ struct clk {
 /***           runtime pm          ***/
 static int clk_pm_runtime_get(struct clk_core *core)
 {
-       int ret = 0;
+       int ret;
 
-       if (!core->dev)
+       if (!core->rpm_enabled)
                return 0;
 
        ret = pm_runtime_get_sync(core->dev);
@@ -103,7 +105,7 @@ static int clk_pm_runtime_get(struct clk_core *core)
 
 static void clk_pm_runtime_put(struct clk_core *core)
 {
-       if (!core->dev)
+       if (!core->rpm_enabled)
                return;
 
        pm_runtime_put_sync(core->dev);
@@ -223,7 +225,7 @@ static bool clk_core_is_enabled(struct clk_core *core)
         * taking enable spinlock, but the below check is needed if one tries
         * to call it from other places.
         */
-       if (core->dev) {
+       if (core->rpm_enabled) {
                pm_runtime_get_noresume(core->dev);
                if (!pm_runtime_active(core->dev)) {
                        ret = false;
@@ -233,7 +235,7 @@ static bool clk_core_is_enabled(struct clk_core *core)
 
        ret = core->ops->is_enabled(core->hw);
 done:
-       if (core->dev)
+       if (core->rpm_enabled)
                pm_runtime_put(core->dev);
 
        return ret;
@@ -394,16 +396,19 @@ bool clk_hw_is_prepared(const struct clk_hw *hw)
 {
        return clk_core_is_prepared(hw->core);
 }
+EXPORT_SYMBOL_GPL(clk_hw_is_prepared);
 
 bool clk_hw_rate_is_protected(const struct clk_hw *hw)
 {
        return clk_core_rate_is_protected(hw->core);
 }
+EXPORT_SYMBOL_GPL(clk_hw_rate_is_protected);
 
 bool clk_hw_is_enabled(const struct clk_hw *hw)
 {
        return clk_core_is_enabled(hw->core);
 }
+EXPORT_SYMBOL_GPL(clk_hw_is_enabled);
 
 bool __clk_is_enabled(struct clk *clk)
 {
@@ -3209,42 +3214,105 @@ unlock:
        return ret;
 }
 
-struct clk *__clk_create_clk(struct clk_hw *hw, const char *dev_id,
+/**
+ * clk_core_link_consumer - Add a clk consumer to the list of consumers in a clk_core
+ * @core: clk to add consumer to
+ * @clk: consumer to link to a clk
+ */
+static void clk_core_link_consumer(struct clk_core *core, struct clk *clk)
+{
+       clk_prepare_lock();
+       hlist_add_head(&clk->clks_node, &core->clks);
+       clk_prepare_unlock();
+}
+
+/**
+ * clk_core_unlink_consumer - Remove a clk consumer from the list of consumers in a clk_core
+ * @clk: consumer to unlink
+ */
+static void clk_core_unlink_consumer(struct clk *clk)
+{
+       lockdep_assert_held(&prepare_lock);
+       hlist_del(&clk->clks_node);
+}
+
+/**
+ * alloc_clk - Allocate a clk consumer, but leave it unlinked to the clk_core
+ * @core: clk to allocate a consumer for
+ * @dev_id: string describing device name
+ * @con_id: connection ID string on device
+ *
+ * Returns: clk consumer left unlinked from the consumer list
+ */
+static struct clk *alloc_clk(struct clk_core *core, const char *dev_id,
                             const char *con_id)
 {
        struct clk *clk;
 
-       /* This is to allow this function to be chained to others */
-       if (IS_ERR_OR_NULL(hw))
-               return ERR_CAST(hw);
-
        clk = kzalloc(sizeof(*clk), GFP_KERNEL);
        if (!clk)
                return ERR_PTR(-ENOMEM);
 
-       clk->core = hw->core;
+       clk->core = core;
        clk->dev_id = dev_id;
        clk->con_id = kstrdup_const(con_id, GFP_KERNEL);
        clk->max_rate = ULONG_MAX;
 
-       clk_prepare_lock();
-       hlist_add_head(&clk->clks_node, &hw->core->clks);
-       clk_prepare_unlock();
-
        return clk;
 }
 
-/* keep in sync with __clk_put */
-void __clk_free_clk(struct clk *clk)
+/**
+ * free_clk - Free a clk consumer
+ * @clk: clk consumer to free
+ *
+ * Note, this assumes the clk has been unlinked from the clk_core consumer
+ * list.
+ */
+static void free_clk(struct clk *clk)
 {
-       clk_prepare_lock();
-       hlist_del(&clk->clks_node);
-       clk_prepare_unlock();
-
        kfree_const(clk->con_id);
        kfree(clk);
 }
 
+/**
+ * clk_hw_create_clk: Allocate and link a clk consumer to a clk_core given
+ * a clk_hw
+ * @dev: clk consumer device
+ * @hw: clk_hw associated with the clk being consumed
+ * @dev_id: string describing device name
+ * @con_id: connection ID string on device
+ *
+ * This is the main function used to create a clk pointer for use by clk
+ * consumers. It connects a consumer to the clk_core and clk_hw structures
+ * used by the framework and clk provider respectively.
+ */
+struct clk *clk_hw_create_clk(struct device *dev, struct clk_hw *hw,
+                             const char *dev_id, const char *con_id)
+{
+       struct clk *clk;
+       struct clk_core *core;
+
+       /* This is to allow this function to be chained to others */
+       if (IS_ERR_OR_NULL(hw))
+               return ERR_CAST(hw);
+
+       core = hw->core;
+       clk = alloc_clk(core, dev_id, con_id);
+       if (IS_ERR(clk))
+               return clk;
+       clk->dev = dev;
+
+       if (!try_module_get(core->owner)) {
+               free_clk(clk);
+               return ERR_PTR(-ENOENT);
+       }
+
+       kref_get(&core->ref);
+       clk_core_link_consumer(core, clk);
+
+       return clk;
+}
+
 /**
  * clk_register - allocate a new clock, register it and return an opaque cookie
  * @dev: device that is registering this clock
@@ -3280,7 +3348,8 @@ struct clk *clk_register(struct device *dev, struct clk_hw *hw)
        core->ops = hw->init->ops;
 
        if (dev && pm_runtime_enabled(dev))
-               core->dev = dev;
+               core->rpm_enabled = true;
+       core->dev = dev;
        if (dev && dev->driver)
                core->owner = dev->driver->owner;
        core->hw = hw;
@@ -3320,17 +3389,27 @@ struct clk *clk_register(struct device *dev, struct clk_hw *hw)
 
        INIT_HLIST_HEAD(&core->clks);
 
-       hw->clk = __clk_create_clk(hw, NULL, NULL);
+       /*
+        * Don't call clk_hw_create_clk() here because that would pin the
+        * provider module to itself and prevent it from ever being removed.
+        */
+       hw->clk = alloc_clk(core, NULL, NULL);
        if (IS_ERR(hw->clk)) {
                ret = PTR_ERR(hw->clk);
                goto fail_parents;
        }
 
+       clk_core_link_consumer(hw->core, hw->clk);
+
        ret = __clk_core_init(core);
        if (!ret)
                return hw->clk;
 
-       __clk_free_clk(hw->clk);
+       clk_prepare_lock();
+       clk_core_unlink_consumer(hw->clk);
+       clk_prepare_unlock();
+
+       free_clk(hw->clk);
        hw->clk = NULL;
 
 fail_parents:
@@ -3601,20 +3680,7 @@ EXPORT_SYMBOL_GPL(devm_clk_hw_unregister);
 /*
  * clkdev helpers
  */
-int __clk_get(struct clk *clk)
-{
-       struct clk_core *core = !clk ? NULL : clk->core;
-
-       if (core) {
-               if (!try_module_get(core->owner))
-                       return 0;
 
-               kref_get(&core->ref);
-       }
-       return 1;
-}
-
-/* keep in sync with __clk_free_clk */
 void __clk_put(struct clk *clk)
 {
        struct module *owner;
@@ -3648,8 +3714,7 @@ void __clk_put(struct clk *clk)
 
        module_put(owner);
 
-       kfree_const(clk->con_id);
-       kfree(clk);
+       free_clk(clk);
 }
 
 /***        clk rate change notifiers        ***/
@@ -4006,6 +4071,49 @@ void devm_of_clk_del_provider(struct device *dev)
 }
 EXPORT_SYMBOL(devm_of_clk_del_provider);
 
+/*
+ * Beware the return values when np is valid, but no clock provider is found.
+ * If name == NULL, the function returns -ENOENT.
+ * If name != NULL, the function returns -EINVAL. This is because
+ * of_parse_phandle_with_args() is called even if of_property_match_string()
+ * returns an error.
+ */
+static int of_parse_clkspec(const struct device_node *np, int index,
+                           const char *name, struct of_phandle_args *out_args)
+{
+       int ret = -ENOENT;
+
+       /* Walk up the tree of devices looking for a clock property that matches */
+       while (np) {
+               /*
+                * For named clocks, first look up the name in the
+                * "clock-names" property.  If it cannot be found, then index
+                * will be an error code and of_parse_phandle_with_args() will
+                * return -EINVAL.
+                */
+               if (name)
+                       index = of_property_match_string(np, "clock-names", name);
+               ret = of_parse_phandle_with_args(np, "clocks", "#clock-cells",
+                                                index, out_args);
+               if (!ret)
+                       break;
+               if (name && index >= 0)
+                       break;
+
+               /*
+                * No matching clock found on this node.  If the parent node
+                * has a "clock-ranges" property, then we can try one of its
+                * clocks.
+                */
+               np = np->parent;
+               if (np && !of_get_property(np, "clock-ranges", NULL))
+                       break;
+               index = 0;
+       }
+
+       return ret;
+}
+
 static struct clk_hw *
 __of_clk_get_hw_from_provider(struct of_clk_provider *provider,
                              struct of_phandle_args *clkspec)
@@ -4021,36 +4129,26 @@ __of_clk_get_hw_from_provider(struct of_clk_provider *provider,
        return __clk_get_hw(clk);
 }
 
-struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec,
-                                      const char *dev_id, const char *con_id)
+static struct clk_hw *
+of_clk_get_hw_from_clkspec(struct of_phandle_args *clkspec)
 {
        struct of_clk_provider *provider;
-       struct clk *clk = ERR_PTR(-EPROBE_DEFER);
-       struct clk_hw *hw;
+       struct clk_hw *hw = ERR_PTR(-EPROBE_DEFER);
 
        if (!clkspec)
                return ERR_PTR(-EINVAL);
 
-       /* Check if we have such a provider in our array */
        mutex_lock(&of_clk_mutex);
        list_for_each_entry(provider, &of_clk_providers, link) {
                if (provider->node == clkspec->np) {
                        hw = __of_clk_get_hw_from_provider(provider, clkspec);
-                       clk = __clk_create_clk(hw, dev_id, con_id);
-               }
-
-               if (!IS_ERR(clk)) {
-                       if (!__clk_get(clk)) {
-                               __clk_free_clk(clk);
-                               clk = ERR_PTR(-ENOENT);
-                       }
-
-                       break;
+                       if (!IS_ERR(hw))
+                               break;
                }
        }
        mutex_unlock(&of_clk_mutex);
 
-       return clk;
+       return hw;
 }
 
 /**
@@ -4063,10 +4161,62 @@ struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec,
  */
 struct clk *of_clk_get_from_provider(struct of_phandle_args *clkspec)
 {
-       return __of_clk_get_from_provider(clkspec, NULL, __func__);
+       struct clk_hw *hw = of_clk_get_hw_from_clkspec(clkspec);
+
+       return clk_hw_create_clk(NULL, hw, NULL, __func__);
 }
 EXPORT_SYMBOL_GPL(of_clk_get_from_provider);
 
+struct clk_hw *of_clk_get_hw(struct device_node *np, int index,
+                            const char *con_id)
+{
+       int ret;
+       struct clk_hw *hw;
+       struct of_phandle_args clkspec;
+
+       ret = of_parse_clkspec(np, index, con_id, &clkspec);
+       if (ret)
+               return ERR_PTR(ret);
+
+       hw = of_clk_get_hw_from_clkspec(&clkspec);
+       of_node_put(clkspec.np);
+
+       return hw;
+}
+
+static struct clk *__of_clk_get(struct device_node *np,
+                               int index, const char *dev_id,
+                               const char *con_id)
+{
+       struct clk_hw *hw = of_clk_get_hw(np, index, con_id);
+
+       return clk_hw_create_clk(NULL, hw, dev_id, con_id);
+}
+
+struct clk *of_clk_get(struct device_node *np, int index)
+{
+       return __of_clk_get(np, index, np->full_name, NULL);
+}
+EXPORT_SYMBOL(of_clk_get);
+
+/**
+ * of_clk_get_by_name() - Parse and lookup a clock referenced by a device node
+ * @np: pointer to clock consumer node
+ * @name: name of consumer's clock input, or NULL for the first clock reference
+ *
+ * This function parses the clocks and clock-names properties,
+ * and uses them to look up the struct clk from the registered list of clock
+ * providers.
+ */
+struct clk *of_clk_get_by_name(struct device_node *np, const char *name)
+{
+       if (!np)
+               return ERR_PTR(-ENOENT);
+
+       return __of_clk_get(np, 0, np->full_name, name);
+}
+EXPORT_SYMBOL(of_clk_get_by_name);
+
 /**
  * of_clk_get_parent_count() - Count the number of clocks a device node has
  * @np: device node to count
index b02f5e604e69c91db044351f94cb6fffa83d900d..553f531cc232e5531c25f7278a3a080df5d5bf25 100644 (file)
@@ -5,31 +5,36 @@
  */
 
 struct clk_hw;
+struct device;
+struct of_phandle_args;
 
 #if defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK)
-struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec,
-                                      const char *dev_id, const char *con_id);
+struct clk_hw *of_clk_get_hw(struct device_node *np,
+                                   int index, const char *con_id);
+#else /* !CONFIG_COMMON_CLK || !CONFIG_OF */
+static inline struct clk_hw *of_clk_get_hw(struct device_node *np,
+                                   int index, const char *con_id)
+{
+       return ERR_PTR(-ENOENT);
+}
 #endif
 
 #ifdef CONFIG_COMMON_CLK
-struct clk *__clk_create_clk(struct clk_hw *hw, const char *dev_id,
-                            const char *con_id);
-void __clk_free_clk(struct clk *clk);
-int __clk_get(struct clk *clk);
+struct clk *clk_hw_create_clk(struct device *dev, struct clk_hw *hw,
+                             const char *dev_id, const char *con_id);
 void __clk_put(struct clk *clk);
 #else
 /* All these casts to avoid ifdefs in clkdev... */
 static inline struct clk *
-__clk_create_clk(struct clk_hw *hw, const char *dev_id, const char *con_id)
+clk_hw_create_clk(struct device *dev, struct clk_hw *hw, const char *dev_id,
+                 const char *con_id)
 {
        return (struct clk *)hw;
 }
-static inline void __clk_free_clk(struct clk *clk) { }
 static struct clk_hw *__clk_get_hw(struct clk *clk)
 {
        return (struct clk_hw *)clk;
 }
-static inline int __clk_get(struct clk *clk) { return 1; }
 static inline void __clk_put(struct clk *clk) { }
 
 #endif
index 9ab3db8b3988375d02b88c5e76f0843a9a6c475f..8c4435c53f09c255f83adb10426e254bc3cf485b 100644 (file)
 static LIST_HEAD(clocks);
 static DEFINE_MUTEX(clocks_mutex);
 
-#if defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK)
-static struct clk *__of_clk_get(struct device_node *np, int index,
-                              const char *dev_id, const char *con_id)
-{
-       struct of_phandle_args clkspec;
-       struct clk *clk;
-       int rc;
-
-       rc = of_parse_phandle_with_args(np, "clocks", "#clock-cells", index,
-                                       &clkspec);
-       if (rc)
-               return ERR_PTR(rc);
-
-       clk = __of_clk_get_from_provider(&clkspec, dev_id, con_id);
-       of_node_put(clkspec.np);
-
-       return clk;
-}
-
-struct clk *of_clk_get(struct device_node *np, int index)
-{
-       return __of_clk_get(np, index, np->full_name, NULL);
-}
-EXPORT_SYMBOL(of_clk_get);
-
-static struct clk *__of_clk_get_by_name(struct device_node *np,
-                                       const char *dev_id,
-                                       const char *name)
-{
-       struct clk *clk = ERR_PTR(-ENOENT);
-
-       /* Walk up the tree of devices looking for a clock that matches */
-       while (np) {
-               int index = 0;
-
-               /*
-                * For named clocks, first look up the name in the
-                * "clock-names" property.  If it cannot be found, then
-                * index will be an error code, and of_clk_get() will fail.
-                */
-               if (name)
-                       index = of_property_match_string(np, "clock-names", name);
-               clk = __of_clk_get(np, index, dev_id, name);
-               if (!IS_ERR(clk)) {
-                       break;
-               } else if (name && index >= 0) {
-                       if (PTR_ERR(clk) != -EPROBE_DEFER)
-                               pr_err("ERROR: could not get clock %pOF:%s(%i)\n",
-                                       np, name ? name : "", index);
-                       return clk;
-               }
-
-               /*
-                * No matching clock found on this node.  If the parent node
-                * has a "clock-ranges" property, then we can try one of its
-                * clocks.
-                */
-               np = np->parent;
-               if (np && !of_get_property(np, "clock-ranges", NULL))
-                       break;
-       }
-
-       return clk;
-}
-
-/**
- * of_clk_get_by_name() - Parse and lookup a clock referenced by a device node
- * @np: pointer to clock consumer node
- * @name: name of consumer's clock input, or NULL for the first clock reference
- *
- * This function parses the clocks and clock-names properties,
- * and uses them to look up the struct clk from the registered list of clock
- * providers.
- */
-struct clk *of_clk_get_by_name(struct device_node *np, const char *name)
-{
-       if (!np)
-               return ERR_PTR(-ENOENT);
-
-       return __of_clk_get_by_name(np, np->full_name, name);
-}
-EXPORT_SYMBOL(of_clk_get_by_name);
-
-#else /* defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK) */
-
-static struct clk *__of_clk_get_by_name(struct device_node *np,
-                                       const char *dev_id,
-                                       const char *name)
-{
-       return ERR_PTR(-ENOENT);
-}
-#endif
-
 /*
  * Find the correct struct clk for the device and connection ID.
  * We do slightly fuzzy matching here:
@@ -163,7 +70,8 @@ static struct clk_lookup *clk_find(const char *dev_id, const char *con_id)
        return cl;
 }
 
-struct clk *clk_get_sys(const char *dev_id, const char *con_id)
+static struct clk *__clk_get_sys(struct device *dev, const char *dev_id,
+                                const char *con_id)
 {
        struct clk_lookup *cl;
        struct clk *clk = NULL;
@@ -174,35 +82,33 @@ struct clk *clk_get_sys(const char *dev_id, const char *con_id)
        if (!cl)
                goto out;
 
-       clk = __clk_create_clk(cl->clk_hw, dev_id, con_id);
+       clk = clk_hw_create_clk(dev, cl->clk_hw, dev_id, con_id);
        if (IS_ERR(clk))
-               goto out;
-
-       if (!__clk_get(clk)) {
-               __clk_free_clk(clk);
                cl = NULL;
-               goto out;
-       }
-
 out:
        mutex_unlock(&clocks_mutex);
 
        return cl ? clk : ERR_PTR(-ENOENT);
 }
+
+struct clk *clk_get_sys(const char *dev_id, const char *con_id)
+{
+       return __clk_get_sys(NULL, dev_id, con_id);
+}
 EXPORT_SYMBOL(clk_get_sys);
 
 struct clk *clk_get(struct device *dev, const char *con_id)
 {
        const char *dev_id = dev ? dev_name(dev) : NULL;
-       struct clk *clk;
+       struct clk_hw *hw;
 
        if (dev && dev->of_node) {
-               clk = __of_clk_get_by_name(dev->of_node, dev_id, con_id);
-               if (!IS_ERR(clk) || PTR_ERR(clk) == -EPROBE_DEFER)
-                       return clk;
+               hw = of_clk_get_hw(dev->of_node, 0, con_id);
+               if (!IS_ERR(hw) || PTR_ERR(hw) == -EPROBE_DEFER)
+                       return clk_hw_create_clk(dev, hw, dev_id, con_id);
        }
 
-       return clk_get_sys(dev_id, con_id);
+       return __clk_get_sys(dev, dev_id, con_id);
 }
 EXPORT_SYMBOL(clk_get);
 
@@ -401,6 +307,23 @@ static struct clk_lookup *__clk_register_clkdev(struct clk_hw *hw,
        return cl;
 }
 
+static int do_clk_register_clkdev(struct clk_hw *hw,
+       struct clk_lookup **cl, const char *con_id, const char *dev_id)
+{
+       if (IS_ERR(hw))
+               return PTR_ERR(hw);
+       /*
+        * Since dev_id can be NULL, and NULL is handled specially, we must
+        * pass it as either a NULL format string, or with "%s".
+        */
+       if (dev_id)
+               *cl = __clk_register_clkdev(hw, con_id, "%s", dev_id);
+       else
+               *cl = __clk_register_clkdev(hw, con_id, NULL);
+
+       return *cl ? 0 : -ENOMEM;
+}
+
 /**
  * clk_register_clkdev - register one clock lookup for a struct clk
  * @clk: struct clk to associate with all clk_lookups
@@ -423,17 +346,8 @@ int clk_register_clkdev(struct clk *clk, const char *con_id,
        if (IS_ERR(clk))
                return PTR_ERR(clk);
 
-       /*
-        * Since dev_id can be NULL, and NULL is handled specially, we must
-        * pass it as either a NULL format string, or with "%s".
-        */
-       if (dev_id)
-               cl = __clk_register_clkdev(__clk_get_hw(clk), con_id, "%s",
-                                          dev_id);
-       else
-               cl = __clk_register_clkdev(__clk_get_hw(clk), con_id, NULL);
-
-       return cl ? 0 : -ENOMEM;
+       return do_clk_register_clkdev(__clk_get_hw(clk), &cl, con_id,
+                                             dev_id);
 }
 EXPORT_SYMBOL(clk_register_clkdev);
 
@@ -456,18 +370,75 @@ int clk_hw_register_clkdev(struct clk_hw *hw, const char *con_id,
 {
        struct clk_lookup *cl;
 
-       if (IS_ERR(hw))
-               return PTR_ERR(hw);
+       return do_clk_register_clkdev(hw, &cl, con_id, dev_id);
+}
+EXPORT_SYMBOL(clk_hw_register_clkdev);
 
-       /*
-        * Since dev_id can be NULL, and NULL is handled specially, we must
-        * pass it as either a NULL format string, or with "%s".
-        */
-       if (dev_id)
-               cl = __clk_register_clkdev(hw, con_id, "%s", dev_id);
-       else
-               cl = __clk_register_clkdev(hw, con_id, NULL);
+static void devm_clkdev_release(struct device *dev, void *res)
+{
+       clkdev_drop(*(struct clk_lookup **)res);
+}
+
+static int devm_clk_match_clkdev(struct device *dev, void *res, void *data)
+{
+       struct clk_lookup **l = res;
 
-       return cl ? 0 : -ENOMEM;
+       return *l == data;
 }
-EXPORT_SYMBOL(clk_hw_register_clkdev);
+
+/**
+ * devm_clk_release_clkdev - Resource managed clkdev lookup release
+ * @dev: device this lookup is bound
+ * @con_id: connection ID string on device
+ * @dev_id: format string describing device name
+ *
+ * Drop the clkdev lookup created with devm_clk_hw_register_clkdev.
+ * Normally this function will not need to be called and the resource
+ * management code will ensure that the resource is freed.
+ */
+void devm_clk_release_clkdev(struct device *dev, const char *con_id,
+                            const char *dev_id)
+{
+       struct clk_lookup *cl;
+       int rval;
+
+       cl = clk_find(dev_id, con_id);
+       WARN_ON(!cl);
+       rval = devres_release(dev, devm_clkdev_release,
+                             devm_clk_match_clkdev, cl);
+       WARN_ON(rval);
+}
+EXPORT_SYMBOL(devm_clk_release_clkdev);
+
+/**
+ * devm_clk_hw_register_clkdev - managed clk lookup registration for clk_hw
+ * @dev: device this lookup is bound
+ * @hw: struct clk_hw to associate with all clk_lookups
+ * @con_id: connection ID string on device
+ * @dev_id: format string describing device name
+ *
+ * con_id or dev_id may be NULL as a wildcard, just as in the rest of
+ * clkdev.
+ *
+ * To make things easier for mass registration, we detect error clk_hws
+ * from a previous clk_hw_register_*() call, and return the error code for
+ * those.  This is to permit this function to be called immediately
+ * after clk_hw_register_*().
+ */
+int devm_clk_hw_register_clkdev(struct device *dev, struct clk_hw *hw,
+                               const char *con_id, const char *dev_id)
+{
+       int rval = -ENOMEM;
+       struct clk_lookup **cl;
+
+       cl = devres_alloc(devm_clkdev_release, sizeof(*cl), GFP_KERNEL);
+       if (cl) {
+               rval = do_clk_register_clkdev(hw, cl, con_id, dev_id);
+               if (!rval)
+                       devres_add(dev, cl);
+               else
+                       devres_free(cl);
+       }
+       return rval;
+}
+EXPORT_SYMBOL(devm_clk_hw_register_clkdev);
index 4aae31a23449025271e3e21de59e034f6dad5e7d..0eaf418482800d5593586c1cfa290ea1fc07e178 100644 (file)
@@ -8,6 +8,12 @@ config MXC_CLK_SCU
        bool
        depends on IMX_SCU
 
+config CLK_IMX8MM
+       bool "IMX8MM CCM Clock Driver"
+       depends on ARCH_MXC && ARM64
+       help
+           Build the driver for i.MX8MM CCM Clock Driver
+
 config CLK_IMX8MQ
        bool "IMX8MQ CCM Clock Driver"
        depends on ARCH_MXC && ARM64
index 73119fbfa5479144ee3f5af5aa01b207cce7d53c..0d5180fbe9883b1b94eebc0498039d75f4b0f6bf 100644 (file)
@@ -18,12 +18,14 @@ obj-$(CONFIG_MXC_CLK) += \
        clk-pllv2.o \
        clk-pllv3.o \
        clk-pllv4.o \
-       clk-sccg-pll.o
+       clk-sccg-pll.o \
+       clk-pll14xx.o
 
 obj-$(CONFIG_MXC_CLK_SCU) += \
        clk-scu.o \
        clk-lpcg-scu.o
 
+obj-$(CONFIG_CLK_IMX8MM) += clk-imx8mm.o
 obj-$(CONFIG_CLK_IMX8MQ) += clk-imx8mq.o
 obj-$(CONFIG_CLK_IMX8QXP) += clk-imx8qxp.o clk-imx8qxp-lpcg.o
 
index 527ade1d6933198a3491d73c3ce0ee8025e64fa2..574fac1a169f46c5699a37355aa2f7f280db1efd 100644 (file)
@@ -123,7 +123,7 @@ static const struct clk_ops imx8m_clk_composite_divider_ops = {
 };
 
 struct clk *imx8m_clk_composite_flags(const char *name,
-                                       const char **parent_names,
+                                       const char * const *parent_names,
                                        int num_parents, void __iomem *reg,
                                        unsigned long flags)
 {
index fc8e782d817bd727b3a77fe340cb47128ea9b092..e91c826bce7072b537f6e8b24cd905be4fa09f46 100644 (file)
@@ -428,6 +428,7 @@ static void __init mx51_clocks_init(struct device_node *np)
        clk[IMX5_CLK_ESDHC4_PER_GATE]   = imx_clk_gate2("esdhc4_per_gate", "esdhc_d_sel", MXC_CCM_CCGR3, 14);
        clk[IMX5_CLK_USB_PHY_GATE]      = imx_clk_gate2("usb_phy_gate", "usb_phy_sel", MXC_CCM_CCGR2, 0);
        clk[IMX5_CLK_HSI2C_GATE]        = imx_clk_gate2("hsi2c_gate", "ipg", MXC_CCM_CCGR1, 22);
+       clk[IMX5_CLK_SCC2_IPG_GATE]     = imx_clk_gate2("scc2_gate", "ipg", MXC_CCM_CCGR1, 30);
        clk[IMX5_CLK_MIPI_HSC1_GATE]    = imx_clk_gate2_flags("mipi_hsc1_gate", "ipg", MXC_CCM_CCGR4, 6, CLK_IS_CRITICAL);
        clk[IMX5_CLK_MIPI_HSC2_GATE]    = imx_clk_gate2_flags("mipi_hsc2_gate", "ipg", MXC_CCM_CCGR4, 8, CLK_IS_CRITICAL);
        clk[IMX5_CLK_MIPI_ESC_GATE]     = imx_clk_gate2_flags("mipi_esc_gate", "ipg", MXC_CCM_CCGR4, 10, CLK_IS_CRITICAL);
index 716eac3136b4d712f5865476db52188bf11b6a85..708e7c5590ddc89f01f691623748a731396fc26c 100644 (file)
@@ -471,6 +471,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
        np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-anatop");
        anatop_base = base = of_iomap(np, 0);
        WARN_ON(!base);
+       of_node_put(np);
 
        /* Audio/video PLL post dividers do not work on i.MX6q revision 1.0 */
        if (clk_on_imx6q() && imx_get_soc_revision() == IMX_CHIP_REVISION_1_0) {
index 18527a335ace30c1c8b308085578561b4f61f483..91558b09bf9eb04a92b60ab4a43a37e6ce4c19fa 100644 (file)
@@ -151,6 +151,7 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node)
        np = of_find_compatible_node(NULL, NULL, "fsl,imx6sx-anatop");
        base = of_iomap(np, 0);
        WARN_ON(!base);
+       of_node_put(np);
 
        clks[IMX6SX_PLL1_BYPASS_SRC] = imx_clk_mux("pll1_bypass_src", base + 0x00, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
        clks[IMX6SX_PLL2_BYPASS_SRC] = imx_clk_mux("pll2_bypass_src", base + 0x30, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
index 06c105d580a45e75390e7ac87eb7b2641a6f5027..cfbd8d4edb8599b9cddbaec02f1a2832faa02bf7 100644 (file)
@@ -404,6 +404,7 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
        np = of_find_compatible_node(NULL, NULL, "fsl,imx7d-anatop");
        base = of_iomap(np, 0);
        WARN_ON(!base);
+       of_node_put(np);
 
        clks[IMX7D_PLL_ARM_MAIN_SRC]  = imx_clk_mux("pll_arm_main_src", base + 0x60, 14, 2, pll_bypass_src_sel, ARRAY_SIZE(pll_bypass_src_sel));
        clks[IMX7D_PLL_DRAM_MAIN_SRC] = imx_clk_mux("pll_dram_main_src", base + 0x70, 14, 2, pll_bypass_src_sel, ARRAY_SIZE(pll_bypass_src_sel));
index 4e18f629f8236284b6865c5dcd5ac3922ab72124..ce306631e84410d007afea1543a1c85df32fd0b7 100644 (file)
@@ -48,8 +48,8 @@ static void __init imx7ulp_clk_scg1_init(struct device_node *np)
        struct clk_hw **clks;
        void __iomem *base;
 
-       clk_data = kzalloc(sizeof(*clk_data) + sizeof(*clk_data->hws) *
-                          IMX7ULP_CLK_SCG1_END, GFP_KERNEL);
+       clk_data = kzalloc(struct_size(clk_data, hws, IMX7ULP_CLK_SCG1_END),
+                          GFP_KERNEL);
        if (!clk_data)
                return;
 
@@ -136,8 +136,8 @@ static void __init imx7ulp_clk_pcc2_init(struct device_node *np)
        struct clk_hw **clks;
        void __iomem *base;
 
-       clk_data = kzalloc(sizeof(*clk_data) + sizeof(*clk_data->hws) *
-                          IMX7ULP_CLK_PCC2_END, GFP_KERNEL);
+       clk_data = kzalloc(struct_size(clk_data, hws, IMX7ULP_CLK_PCC2_END),
+                          GFP_KERNEL);
        if (!clk_data)
                return;
 
@@ -183,8 +183,8 @@ static void __init imx7ulp_clk_pcc3_init(struct device_node *np)
        struct clk_hw **clks;
        void __iomem *base;
 
-       clk_data = kzalloc(sizeof(*clk_data) + sizeof(*clk_data->hws) *
-                          IMX7ULP_CLK_PCC3_END, GFP_KERNEL);
+       clk_data = kzalloc(struct_size(clk_data, hws, IMX7ULP_CLK_PCC3_END),
+                          GFP_KERNEL);
        if (!clk_data)
                return;
 
@@ -228,8 +228,8 @@ static void __init imx7ulp_clk_smc1_init(struct device_node *np)
        struct clk_hw **clks;
        void __iomem *base;
 
-       clk_data = kzalloc(sizeof(*clk_data) + sizeof(*clk_data->hws) *
-                          IMX7ULP_CLK_SMC1_END, GFP_KERNEL);
+       clk_data = kzalloc(struct_size(clk_data, hws, IMX7ULP_CLK_SMC1_END),
+                          GFP_KERNEL);
        if (!clk_data)
                return;
 
diff --git a/drivers/clk/imx/clk-imx8mm.c b/drivers/clk/imx/clk-imx8mm.c
new file mode 100644 (file)
index 0000000..1ef8438
--- /dev/null
@@ -0,0 +1,675 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2017-2018 NXP.
+ */
+
+#include <dt-bindings/clock/imx8mm-clock.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+
+#include "clk.h"
+
+static u32 share_count_sai1;
+static u32 share_count_sai2;
+static u32 share_count_sai3;
+static u32 share_count_sai4;
+static u32 share_count_sai5;
+static u32 share_count_sai6;
+static u32 share_count_dcss;
+static u32 share_count_pdm;
+static u32 share_count_nand;
+
+#define PLL_1416X_RATE(_rate, _m, _p, _s)              \
+       {                                               \
+               .rate   =       (_rate),                \
+               .mdiv   =       (_m),                   \
+               .pdiv   =       (_p),                   \
+               .sdiv   =       (_s),                   \
+       }
+
+#define PLL_1443X_RATE(_rate, _m, _p, _s, _k)          \
+       {                                               \
+               .rate   =       (_rate),                \
+               .mdiv   =       (_m),                   \
+               .pdiv   =       (_p),                   \
+               .sdiv   =       (_s),                   \
+               .kdiv   =       (_k),                   \
+       }
+
+static const struct imx_pll14xx_rate_table imx8mm_pll1416x_tbl[] = {
+       PLL_1416X_RATE(1800000000U, 225, 3, 0),
+       PLL_1416X_RATE(1600000000U, 200, 3, 0),
+       PLL_1416X_RATE(1200000000U, 300, 3, 1),
+       PLL_1416X_RATE(1000000000U, 250, 3, 1),
+       PLL_1416X_RATE(800000000U,  200, 3, 1),
+       PLL_1416X_RATE(750000000U,  250, 2, 2),
+       PLL_1416X_RATE(700000000U,  350, 3, 2),
+       PLL_1416X_RATE(600000000U,  300, 3, 2),
+};
+
+static const struct imx_pll14xx_rate_table imx8mm_audiopll_tbl[] = {
+       PLL_1443X_RATE(786432000U, 655, 5, 2, 23593),
+       PLL_1443X_RATE(722534400U, 301, 5, 1, 3670),
+};
+
+static const struct imx_pll14xx_rate_table imx8mm_videopll_tbl[] = {
+       PLL_1443X_RATE(650000000U, 325, 3, 2, 0),
+       PLL_1443X_RATE(594000000U, 198, 2, 2, 0),
+};
+
+static const struct imx_pll14xx_rate_table imx8mm_drampll_tbl[] = {
+       PLL_1443X_RATE(650000000U, 325, 3, 2, 0),
+};
+
+static struct imx_pll14xx_clk imx8mm_audio_pll __initdata = {
+               .type = PLL_1443X,
+               .rate_table = imx8mm_audiopll_tbl,
+               .rate_count = ARRAY_SIZE(imx8mm_audiopll_tbl),
+};
+
+static struct imx_pll14xx_clk imx8mm_video_pll __initdata = {
+               .type = PLL_1443X,
+               .rate_table = imx8mm_videopll_tbl,
+               .rate_count = ARRAY_SIZE(imx8mm_videopll_tbl),
+};
+
+static struct imx_pll14xx_clk imx8mm_dram_pll __initdata = {
+               .type = PLL_1443X,
+               .rate_table = imx8mm_drampll_tbl,
+               .rate_count = ARRAY_SIZE(imx8mm_drampll_tbl),
+};
+
+static struct imx_pll14xx_clk imx8mm_arm_pll __initdata = {
+               .type = PLL_1416X,
+               .rate_table = imx8mm_pll1416x_tbl,
+               .rate_count = ARRAY_SIZE(imx8mm_pll1416x_tbl),
+};
+
+static struct imx_pll14xx_clk imx8mm_gpu_pll __initdata = {
+               .type = PLL_1416X,
+               .rate_table = imx8mm_pll1416x_tbl,
+               .rate_count = ARRAY_SIZE(imx8mm_pll1416x_tbl),
+};
+
+static struct imx_pll14xx_clk imx8mm_vpu_pll __initdata = {
+               .type = PLL_1416X,
+               .rate_table = imx8mm_pll1416x_tbl,
+               .rate_count = ARRAY_SIZE(imx8mm_pll1416x_tbl),
+};
+
+static struct imx_pll14xx_clk imx8mm_sys_pll __initdata = {
+               .type = PLL_1416X,
+               .rate_table = imx8mm_pll1416x_tbl,
+               .rate_count = ARRAY_SIZE(imx8mm_pll1416x_tbl),
+};
+
+static const char *pll_ref_sels[] = { "osc_24m", "dummy", "dummy", "dummy", };
+static const char *audio_pll1_bypass_sels[] = {"audio_pll1", "audio_pll1_ref_sel", };
+static const char *audio_pll2_bypass_sels[] = {"audio_pll2", "audio_pll2_ref_sel", };
+static const char *video_pll1_bypass_sels[] = {"video_pll1", "video_pll1_ref_sel", };
+static const char *dram_pll_bypass_sels[] = {"dram_pll", "dram_pll_ref_sel", };
+static const char *gpu_pll_bypass_sels[] = {"gpu_pll", "gpu_pll_ref_sel", };
+static const char *vpu_pll_bypass_sels[] = {"vpu_pll", "vpu_pll_ref_sel", };
+static const char *arm_pll_bypass_sels[] = {"arm_pll", "arm_pll_ref_sel", };
+static const char *sys_pll1_bypass_sels[] = {"sys_pll1", "sys_pll1_ref_sel", };
+static const char *sys_pll2_bypass_sels[] = {"sys_pll2", "sys_pll2_ref_sel", };
+static const char *sys_pll3_bypass_sels[] = {"sys_pll3", "sys_pll3_ref_sel", };
+
+/* CCM ROOT */
+static const char *imx8mm_a53_sels[] = {"osc_24m", "arm_pll_out", "sys_pll2_500m", "sys_pll2_1000m",
+                                       "sys_pll1_800m", "sys_pll1_400m", "audio_pll1_out", "sys_pll3_out", };
+
+static const char *imx8mm_m4_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll2_250m", "sys_pll1_266m",
+                                      "sys_pll1_800m", "audio_pll1_out", "video_pll1_out", "sys_pll3_out", };
+
+static const char *imx8mm_vpu_sels[] = {"osc_24m", "arm_pll_out", "sys_pll2_500m", "sys_pll2_1000m",
+                                       "sys_pll1_800m", "sys_pll1_400m", "audio_pll1_out", "vpu_pll_out", };
+
+static const char *imx8mm_gpu3d_sels[] = {"osc_24m", "gpu_pll_out", "sys_pll1_800m", "sys_pll3_out",
+                                         "sys_pll2_1000m", "audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
+
+static const char *imx8mm_gpu2d_sels[] = {"osc_24m", "gpu_pll_out", "sys_pll1_800m", "sys_pll3_out",
+                                         "sys_pll2_1000m", "audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
+
+static const char *imx8mm_main_axi_sels[] = {"osc_24m", "sys_pll2_333m", "sys_pll1_800m", "sys_pll2_250m",
+                                            "sys_pll2_1000m", "audio_pll1_out", "video_pll1_out", "sys_pll1_100m",};
+
+static const char *imx8mm_enet_axi_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll1_800m", "sys_pll2_250m",
+                                            "sys_pll2_200m", "audio_pll1_out", "video_pll1_out", "sys_pll3_out", };
+
+static const char *imx8mm_nand_usdhc_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll1_800m", "sys_pll2_200m",
+                                              "sys_pll1_133m", "sys_pll3_out", "sys_pll2_250m", "audio_pll1_out", };
+
+static const char *imx8mm_vpu_bus_sels[] = {"osc_24m", "sys_pll1_800m", "vpu_pll_out", "audio_pll2_out",
+                                           "sys_pll3_out", "sys_pll2_1000m", "sys_pll2_200m", "sys_pll1_100m", };
+
+static const char *imx8mm_disp_axi_sels[] = {"osc_24m", "sys_pll2_1000m", "sys_pll1_800m", "sys_pll3_out",
+                                            "sys_pll1_40m", "audio_pll2_out", "clk_ext1", "clk_ext4", };
+
+static const char *imx8mm_disp_apb_sels[] = {"osc_24m", "sys_pll2_125m", "sys_pll1_800m", "sys_pll3_out",
+                                            "sys_pll1_40m", "audio_pll2_out", "clk_ext1", "clk_ext3", };
+
+static const char *imx8mm_disp_rtrm_sels[] = {"osc_24m", "sys_pll1_800m", "sys_pll2_200m", "sys_pll2_1000m",
+                                             "audio_pll1_out", "video_pll1_out", "clk_ext2", "clk_ext3", };
+
+static const char *imx8mm_usb_bus_sels[] = {"osc_24m", "sys_pll2_500m", "sys_pll1_800m", "sys_pll2_100m",
+                                           "sys_pll2_200m", "clk_ext2", "clk_ext4", "audio_pll2_out", };
+
+static const char *imx8mm_gpu_axi_sels[] = {"osc_24m", "sys_pll1_800m", "gpu_pll_out", "sys_pll3_out", "sys_pll2_1000m",
+                                           "audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
+
+static const char *imx8mm_gpu_ahb_sels[] = {"osc_24m", "sys_pll1_800m", "gpu_pll_out", "sys_pll3_out", "sys_pll2_1000m",
+                                           "audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
+
+static const char *imx8mm_noc_sels[] = {"osc_24m", "sys_pll1_800m", "sys_pll3_out", "sys_pll2_1000m", "sys_pll2_500m",
+                                       "audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
+
+static const char *imx8mm_noc_apb_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll3_out", "sys_pll2_333m", "sys_pll2_200m",
+                                           "sys_pll1_800m", "audio_pll1_out", "video_pll1_out", };
+
+static const char *imx8mm_ahb_sels[] = {"osc_24m", "sys_pll1_133m", "sys_pll1_800m", "sys_pll1_400m",
+                                       "sys_pll2_125m", "sys_pll3_out", "audio_pll1_out", "video_pll1_out", };
+
+static const char *imx8mm_audio_ahb_sels[] = {"osc_24m", "sys_pll2_500m", "sys_pll1_800m", "sys_pll2_1000m",
+                                             "sys_pll2_166m", "sys_pll3_out", "audio_pll1_out", "video_pll1_out", };
+
+static const char *imx8mm_dram_alt_sels[] = {"osc_24m", "sys_pll1_800m", "sys_pll1_100m", "sys_pll2_500m",
+                                            "sys_pll2_1000m", "sys_pll3_out", "audio_pll1_out", "sys_pll1_266m", };
+
+static const char *imx8mm_dram_apb_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_40m", "sys_pll1_160m",
+                                            "sys_pll1_800m", "sys_pll3_out", "sys_pll2_250m", "audio_pll2_out", };
+
+static const char *imx8mm_vpu_g1_sels[] = {"osc_24m", "vpu_pll_out", "sys_pll1_800m", "sys_pll2_1000m",
+                                          "sys_pll1_100m", "sys_pll2_125m", "sys_pll3_out", "audio_pll1_out", };
+
+static const char *imx8mm_vpu_g2_sels[] = {"osc_24m", "vpu_pll_out", "sys_pll1_800m", "sys_pll2_1000m",
+                                          "sys_pll1_100m", "sys_pll2_125m", "sys_pll3_out", "audio_pll1_out", };
+
+static const char *imx8mm_disp_dtrc_sels[] = {"osc_24m", "video_pll2_out", "sys_pll1_800m", "sys_pll2_1000m",
+                                             "sys_pll1_160m", "video_pll1_out", "sys_pll3_out", "audio_pll2_out", };
+
+static const char *imx8mm_disp_dc8000_sels[] = {"osc_24m", "video_pll2_out", "sys_pll1_800m", "sys_pll2_1000m",
+                                               "sys_pll1_160m", "video_pll1_out", "sys_pll3_out", "audio_pll2_out", };
+
+static const char *imx8mm_pcie1_ctrl_sels[] = {"osc_24m", "sys_pll2_250m", "sys_pll2_200m", "sys_pll1_266m",
+                                              "sys_pll1_800m", "sys_pll2_500m", "sys_pll2_333m", "sys_pll3_out", };
+
+static const char *imx8mm_pcie1_phy_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll2_500m", "clk_ext1", "clk_ext2",
+                                             "clk_ext3", "clk_ext4", "sys_pll1_400m", };
+
+static const char *imx8mm_pcie1_aux_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll2_50m", "sys_pll3_out",
+                                             "sys_pll2_100m", "sys_pll1_80m", "sys_pll1_160m", "sys_pll1_200m", };
+
+static const char *imx8mm_dc_pixel_sels[] = {"osc_24m", "video_pll1_out", "audio_pll2_out", "audio_pll1_out",
+                                            "sys_pll1_800m", "sys_pll2_1000m", "sys_pll3_out", "clk_ext4", };
+
+static const char *imx8mm_lcdif_pixel_sels[] = {"osc_24m", "video_pll1_out", "audio_pll2_out", "audio_pll1_out",
+                                               "sys_pll1_800m", "sys_pll2_1000m", "sys_pll3_out", "clk_ext4", };
+
+static const char *imx8mm_sai1_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
+                                        "sys_pll1_133m", "osc_hdmi", "clk_ext1", "clk_ext2", };
+
+static const char *imx8mm_sai2_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
+                                        "sys_pll1_133m", "osc_hdmi", "clk_ext2", "clk_ext3", };
+
+static const char *imx8mm_sai3_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
+                                        "sys_pll1_133m", "osc_hdmi", "clk_ext3", "clk_ext4", };
+
+static const char *imx8mm_sai4_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
+                                        "sys_pll1_133m", "osc_hdmi", "clk_ext1", "clk_ext2", };
+
+static const char *imx8mm_sai5_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
+                                        "sys_pll1_133m", "osc_hdmi", "clk_ext2", "clk_ext3", };
+
+static const char *imx8mm_sai6_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
+                                        "sys_pll1_133m", "osc_hdmi", "clk_ext3", "clk_ext4", };
+
+static const char *imx8mm_spdif1_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
+                                          "sys_pll1_133m", "osc_hdmi", "clk_ext2", "clk_ext3", };
+
+static const char *imx8mm_spdif2_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
+                                          "sys_pll1_133m", "osc_hdmi", "clk_ext3", "clk_ext4", };
+
+static const char *imx8mm_enet_ref_sels[] = {"osc_24m", "sys_pll2_125m", "sys_pll2_50m", "sys_pll2_100m",
+                                            "sys_pll1_160m", "audio_pll1_out", "video_pll1_out", "clk_ext4", };
+
+static const char *imx8mm_enet_timer_sels[] = {"osc_24m", "sys_pll2_100m", "audio_pll1_out", "clk_ext1", "clk_ext2",
+                                              "clk_ext3", "clk_ext4", "video_pll1_out", };
+
+static const char *imx8mm_enet_phy_sels[] = {"osc_24m", "sys_pll2_50m", "sys_pll2_125m", "sys_pll2_200m",
+                                            "sys_pll2_500m", "video_pll1_out", "audio_pll2_out", };
+
+static const char *imx8mm_nand_sels[] = {"osc_24m", "sys_pll2_500m", "audio_pll1_out", "sys_pll1_400m",
+                                        "audio_pll2_out", "sys_pll3_out", "sys_pll2_250m", "video_pll1_out", };
+
+static const char *imx8mm_qspi_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll1_800m", "sys_pll2_500m",
+                                        "audio_pll2_out", "sys_pll1_266m", "sys_pll3_out", "sys_pll1_100m", };
+
+static const char *imx8mm_usdhc1_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll1_800m", "sys_pll2_500m",
+                                          "sys_pll3_out", "sys_pll1_266m", "audio_pll2_out", "sys_pll1_100m", };
+
+static const char *imx8mm_usdhc2_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll1_800m", "sys_pll2_500m",
+                                          "sys_pll3_out", "sys_pll1_266m", "audio_pll2_out", "sys_pll1_100m", };
+
+static const char *imx8mm_i2c1_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m", "sys_pll3_out", "audio_pll1_out",
+                                        "video_pll1_out", "audio_pll2_out", "sys_pll1_133m", };
+
+static const char *imx8mm_i2c2_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m", "sys_pll3_out", "audio_pll1_out",
+                                        "video_pll1_out", "audio_pll2_out", "sys_pll1_133m", };
+
+static const char *imx8mm_i2c3_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m", "sys_pll3_out", "audio_pll1_out",
+                                        "video_pll1_out", "audio_pll2_out", "sys_pll1_133m", };
+
+static const char *imx8mm_i2c4_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m", "sys_pll3_out", "audio_pll1_out",
+                                        "video_pll1_out", "audio_pll2_out", "sys_pll1_133m", };
+
+static const char *imx8mm_uart1_sels[] = {"osc_24m", "sys_pll1_80m", "sys_pll2_200m", "sys_pll2_100m",
+                                         "sys_pll3_out", "clk_ext2", "clk_ext4", "audio_pll2_out", };
+
+static const char *imx8mm_uart2_sels[] = {"osc_24m", "sys_pll1_80m", "sys_pll2_200m", "sys_pll2_100m",
+                                         "sys_pll3_out", "clk_ext2", "clk_ext3", "audio_pll2_out", };
+
+static const char *imx8mm_uart3_sels[] = {"osc_24m", "sys_pll1_80m", "sys_pll2_200m", "sys_pll2_100m",
+                                         "sys_pll3_out", "clk_ext2", "clk_ext4", "audio_pll2_out", };
+
+static const char *imx8mm_uart4_sels[] = {"osc_24m", "sys_pll1_80m", "sys_pll2_200m", "sys_pll2_100m",
+                                         "sys_pll3_out", "clk_ext2", "clk_ext3", "audio_pll2_out", };
+
+static const char *imx8mm_usb_core_sels[] = {"osc_24m", "sys_pll1_100m", "sys_pll1_40m", "sys_pll2_100m",
+                                            "sys_pll2_200m", "clk_ext2", "clk_ext3", "audio_pll2_out", };
+
+static const char *imx8mm_usb_phy_sels[] = {"osc_24m", "sys_pll1_100m", "sys_pll1_40m", "sys_pll2_100m",
+                                            "sys_pll2_200m", "clk_ext2", "clk_ext3", "audio_pll2_out", };
+
+static const char *imx8mm_ecspi1_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_40m", "sys_pll1_160m",
+                                          "sys_pll1_800m", "sys_pll3_out", "sys_pll2_250m", "audio_pll2_out", };
+
+static const char *imx8mm_ecspi2_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_40m", "sys_pll1_160m",
+                                          "sys_pll1_800m", "sys_pll3_out", "sys_pll2_250m", "audio_pll2_out", };
+
+static const char *imx8mm_pwm1_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m", "sys_pll1_40m",
+                                        "sys_pll3_out", "clk_ext1", "sys_pll1_80m", "video_pll1_out", };
+
+static const char *imx8mm_pwm2_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m", "sys_pll1_40m",
+                                        "sys_pll3_out", "clk_ext1", "sys_pll1_80m", "video_pll1_out", };
+
+static const char *imx8mm_pwm3_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m", "sys_pll1_40m",
+                                        "sys3_pll2_out", "clk_ext2", "sys_pll1_80m", "video_pll1_out", };
+
+static const char *imx8mm_pwm4_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m", "sys_pll1_40m",
+                                        "sys_pll3_out", "clk_ext2", "sys_pll1_80m", "video_pll1_out", };
+
+static const char *imx8mm_gpt1_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m", "sys_pll1_40m",
+                                        "video_pll1_out", "sys_pll1_800m", "audio_pll1_out", "clk_ext1" };
+
+static const char *imx8mm_wdog_sels[] = {"osc_24m", "sys_pll1_133m", "sys_pll1_160m", "vpu_pll_out",
+                                        "sys_pll2_125m", "sys_pll3_out", "sys_pll1_80m", "sys_pll2_166m", };
+
+static const char *imx8mm_wrclk_sels[] = {"osc_24m", "sys_pll1_40m", "vpu_pll_out", "sys_pll3_out", "sys_pll2_200m",
+                                         "sys_pll1_266m", "sys_pll2_500m", "sys_pll1_100m", };
+
+static const char *imx8mm_dsi_core_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_250m", "sys_pll1_800m",
+                                            "sys_pll2_1000m", "sys_pll3_out", "audio_pll2_out", "video_pll1_out", };
+
+static const char *imx8mm_dsi_phy_sels[] = {"osc_24m", "sys_pll2_125m", "sys_pll2_100m", "sys_pll1_800m",
+                                           "sys_pll2_1000m", "clk_ext2", "audio_pll2_out", "video_pll1_out", };
+
+static const char *imx8mm_dsi_dbi_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_100m", "sys_pll1_800m",
+                                           "sys_pll2_1000m", "sys_pll3_out", "audio_pll2_out", "video_pll1_out", };
+
+static const char *imx8mm_usdhc3_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll1_800m", "sys_pll2_500m",
+                                          "sys_pll3_out", "sys_pll1_266m", "audio_pll2_clk", "sys_pll1_100m", };
+
+static const char *imx8mm_csi1_core_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_250m", "sys_pll1_800m",
+                                             "sys_pll2_1000m", "sys_pll3_out", "audio_pll2_out", "video_pll1_out", };
+
+static const char *imx8mm_csi1_phy_sels[] = {"osc_24m", "sys_pll2_333m", "sys_pll2_100m", "sys_pll1_800m",
+                                            "sys_pll2_1000m", "clk_ext2", "audio_pll2_out", "video_pll1_out", };
+
+static const char *imx8mm_csi1_esc_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_80m", "sys_pll1_800m",
+                                            "sys_pll2_1000m", "sys_pll3_out", "clk_ext3", "audio_pll2_out", };
+
+static const char *imx8mm_csi2_core_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_250m", "sys_pll1_800m",
+                                             "sys_pll2_1000m", "sys_pll3_out", "audio_pll2_out", "video_pll1_out", };
+
+static const char *imx8mm_csi2_phy_sels[] = {"osc_24m", "sys_pll2_333m", "sys_pll2_100m", "sys_pll1_800m",
+                                            "sys_pll2_1000m", "clk_ext2", "audio_pll2_out", "video_pll1_out", };
+
+static const char *imx8mm_csi2_esc_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_80m", "sys_pll1_800m",
+                                            "sys_pll2_1000m", "sys_pll3_out", "clk_ext3", "audio_pll2_out", };
+
+static const char *imx8mm_pcie2_ctrl_sels[] = {"osc_24m", "sys_pll2_250m", "sys_pll2_200m", "sys_pll1_266m",
+                                              "sys_pll1_800m", "sys_pll2_500m", "sys_pll2_333m", "sys_pll3_out", };
+
+static const char *imx8mm_pcie2_phy_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll2_500m", "clk_ext1",
+                                             "clk_ext2", "clk_ext3", "clk_ext4", "sys_pll1_400m", };
+
+static const char *imx8mm_pcie2_aux_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll2_50m", "sys_pll3_out",
+                                             "sys_pll2_100m", "sys_pll1_80m", "sys_pll1_160m", "sys_pll1_200m", };
+
+static const char *imx8mm_ecspi3_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_40m", "sys_pll1_160m",
+                                          "sys_pll1_800m", "sys_pll3_out", "sys_pll2_250m", "audio_pll2_out", };
+
+static const char *imx8mm_pdm_sels[] = {"osc_24m", "sys_pll2_100m", "audio_pll1_out", "sys_pll1_800m",
+                                       "sys_pll2_1000m", "sys_pll3_out", "clk_ext3", "audio_pll2_out", };
+
+static const char *imx8mm_vpu_h1_sels[] = {"osc_24m", "vpu_pll_out", "sys_pll1_800m", "sys_pll2_1000m",
+                                          "audio_pll2_clk", "sys_pll2_125m", "sys_pll3_clk", "audio_pll1_out", };
+
+static const char *imx8mm_dram_core_sels[] = {"dram_pll_out", "dram_alt_root", };
+
+static const char *imx8mm_clko1_sels[] = {"osc_24m", "sys_pll1_800m", "osc_27m", "sys_pll1_200m", "audio_pll2_clk",
+                                        "vpu_pll", "sys_pll1_80m", };
+
+static struct clk *clks[IMX8MM_CLK_END];
+static struct clk_onecell_data clk_data;
+
+static struct clk ** const uart_clks[] __initconst = {
+       &clks[IMX8MM_CLK_UART1_ROOT],
+       &clks[IMX8MM_CLK_UART2_ROOT],
+       &clks[IMX8MM_CLK_UART3_ROOT],
+       &clks[IMX8MM_CLK_UART4_ROOT],
+       NULL
+};
+
+static int __init imx8mm_clocks_init(struct device_node *ccm_node)
+{
+       struct device_node *np;
+       void __iomem *base;
+       int ret;
+
+       clks[IMX8MM_CLK_DUMMY] = imx_clk_fixed("dummy", 0);
+       clks[IMX8MM_CLK_24M] = of_clk_get_by_name(ccm_node, "osc_24m");
+       clks[IMX8MM_CLK_32K] = of_clk_get_by_name(ccm_node, "osc_32k");
+       clks[IMX8MM_CLK_EXT1] = of_clk_get_by_name(ccm_node, "clk_ext1");
+       clks[IMX8MM_CLK_EXT2] = of_clk_get_by_name(ccm_node, "clk_ext2");
+       clks[IMX8MM_CLK_EXT3] = of_clk_get_by_name(ccm_node, "clk_ext3");
+       clks[IMX8MM_CLK_EXT4] = of_clk_get_by_name(ccm_node, "clk_ext4");
+
+       np = of_find_compatible_node(NULL, NULL, "fsl,imx8mm-anatop");
+       base = of_iomap(np, 0);
+       if (WARN_ON(!base))
+               return -ENOMEM;
+
+       clks[IMX8MM_AUDIO_PLL1_REF_SEL] = imx_clk_mux("audio_pll1_ref_sel", base + 0x0, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+       clks[IMX8MM_AUDIO_PLL2_REF_SEL] = imx_clk_mux("audio_pll2_ref_sel", base + 0x14, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+       clks[IMX8MM_VIDEO_PLL1_REF_SEL] = imx_clk_mux("video_pll1_ref_sel", base + 0x28, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+       clks[IMX8MM_DRAM_PLL_REF_SEL] = imx_clk_mux("dram_pll_ref_sel", base + 0x50, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+       clks[IMX8MM_GPU_PLL_REF_SEL] = imx_clk_mux("gpu_pll_ref_sel", base + 0x64, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+       clks[IMX8MM_VPU_PLL_REF_SEL] = imx_clk_mux("vpu_pll_ref_sel", base + 0x74, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+       clks[IMX8MM_ARM_PLL_REF_SEL] = imx_clk_mux("arm_pll_ref_sel", base + 0x84, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+       clks[IMX8MM_SYS_PLL1_REF_SEL] = imx_clk_mux("sys_pll1_ref_sel", base + 0x94, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+       clks[IMX8MM_SYS_PLL2_REF_SEL] = imx_clk_mux("sys_pll2_ref_sel", base + 0x104, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+       clks[IMX8MM_SYS_PLL3_REF_SEL] = imx_clk_mux("sys_pll3_ref_sel", base + 0x114, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+
+       clks[IMX8MM_AUDIO_PLL1] = imx_clk_pll14xx("audio_pll1", "audio_pll1_ref_sel", base, &imx8mm_audio_pll);
+       clks[IMX8MM_AUDIO_PLL2] = imx_clk_pll14xx("audio_pll2", "audio_pll2_ref_sel", base + 0x14, &imx8mm_audio_pll);
+       clks[IMX8MM_VIDEO_PLL1] = imx_clk_pll14xx("video_pll1", "video_pll1_ref_sel", base + 0x28, &imx8mm_video_pll);
+       clks[IMX8MM_DRAM_PLL] = imx_clk_pll14xx("dram_pll", "dram_pll_ref_sel", base + 0x50, &imx8mm_dram_pll);
+       clks[IMX8MM_GPU_PLL] = imx_clk_pll14xx("gpu_pll", "gpu_pll_ref_sel", base + 0x64, &imx8mm_gpu_pll);
+       clks[IMX8MM_VPU_PLL] = imx_clk_pll14xx("vpu_pll", "vpu_pll_ref_sel", base + 0x74, &imx8mm_vpu_pll);
+       clks[IMX8MM_ARM_PLL] = imx_clk_pll14xx("arm_pll", "arm_pll_ref_sel", base + 0x84, &imx8mm_arm_pll);
+       clks[IMX8MM_SYS_PLL1] = imx_clk_pll14xx("sys_pll1", "sys_pll1_ref_sel", base + 0x94, &imx8mm_sys_pll);
+       clks[IMX8MM_SYS_PLL2] = imx_clk_pll14xx("sys_pll2", "sys_pll2_ref_sel", base + 0x104, &imx8mm_sys_pll);
+       clks[IMX8MM_SYS_PLL3] = imx_clk_pll14xx("sys_pll3", "sys_pll3_ref_sel", base + 0x114, &imx8mm_sys_pll);
+
+       /* PLL bypass out */
+       clks[IMX8MM_AUDIO_PLL1_BYPASS] = imx_clk_mux_flags("audio_pll1_bypass", base, 4, 1, audio_pll1_bypass_sels, ARRAY_SIZE(audio_pll1_bypass_sels), CLK_SET_RATE_PARENT);
+       clks[IMX8MM_AUDIO_PLL2_BYPASS] = imx_clk_mux_flags("audio_pll2_bypass", base + 0x14, 4, 1, audio_pll2_bypass_sels, ARRAY_SIZE(audio_pll2_bypass_sels), CLK_SET_RATE_PARENT);
+       clks[IMX8MM_VIDEO_PLL1_BYPASS] = imx_clk_mux_flags("video_pll1_bypass", base + 0x28, 4, 1, video_pll1_bypass_sels, ARRAY_SIZE(video_pll1_bypass_sels), CLK_SET_RATE_PARENT);
+       clks[IMX8MM_DRAM_PLL_BYPASS] = imx_clk_mux_flags("dram_pll_bypass", base + 0x50, 4, 1, dram_pll_bypass_sels, ARRAY_SIZE(dram_pll_bypass_sels), CLK_SET_RATE_PARENT);
+       clks[IMX8MM_GPU_PLL_BYPASS] = imx_clk_mux_flags("gpu_pll_bypass", base + 0x64, 4, 1, gpu_pll_bypass_sels, ARRAY_SIZE(gpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
+       clks[IMX8MM_VPU_PLL_BYPASS] = imx_clk_mux_flags("vpu_pll_bypass", base + 0x74, 4, 1, vpu_pll_bypass_sels, ARRAY_SIZE(vpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
+       clks[IMX8MM_ARM_PLL_BYPASS] = imx_clk_mux_flags("arm_pll_bypass", base + 0x84, 4, 1, arm_pll_bypass_sels, ARRAY_SIZE(arm_pll_bypass_sels), CLK_SET_RATE_PARENT);
+       clks[IMX8MM_SYS_PLL1_BYPASS] = imx_clk_mux_flags("sys_pll1_bypass", base + 0x94, 4, 1, sys_pll1_bypass_sels, ARRAY_SIZE(sys_pll1_bypass_sels), CLK_SET_RATE_PARENT);
+       clks[IMX8MM_SYS_PLL2_BYPASS] = imx_clk_mux_flags("sys_pll2_bypass", base + 0x104, 4, 1, sys_pll2_bypass_sels, ARRAY_SIZE(sys_pll2_bypass_sels), CLK_SET_RATE_PARENT);
+       clks[IMX8MM_SYS_PLL3_BYPASS] = imx_clk_mux_flags("sys_pll3_bypass", base + 0x114, 4, 1, sys_pll3_bypass_sels, ARRAY_SIZE(sys_pll3_bypass_sels), CLK_SET_RATE_PARENT);
+
+       /* unbypass all the plls */
+       clk_set_parent(clks[IMX8MM_AUDIO_PLL1_BYPASS], clks[IMX8MM_AUDIO_PLL1]);
+       clk_set_parent(clks[IMX8MM_AUDIO_PLL2_BYPASS], clks[IMX8MM_AUDIO_PLL2]);
+       clk_set_parent(clks[IMX8MM_VIDEO_PLL1_BYPASS], clks[IMX8MM_VIDEO_PLL1]);
+       clk_set_parent(clks[IMX8MM_DRAM_PLL_BYPASS], clks[IMX8MM_DRAM_PLL]);
+       clk_set_parent(clks[IMX8MM_GPU_PLL_BYPASS], clks[IMX8MM_GPU_PLL]);
+       clk_set_parent(clks[IMX8MM_VPU_PLL_BYPASS], clks[IMX8MM_VPU_PLL]);
+       clk_set_parent(clks[IMX8MM_ARM_PLL_BYPASS], clks[IMX8MM_ARM_PLL]);
+       clk_set_parent(clks[IMX8MM_SYS_PLL1_BYPASS], clks[IMX8MM_SYS_PLL1]);
+       clk_set_parent(clks[IMX8MM_SYS_PLL2_BYPASS], clks[IMX8MM_SYS_PLL2]);
+       clk_set_parent(clks[IMX8MM_SYS_PLL3_BYPASS], clks[IMX8MM_SYS_PLL3]);
+
+       /* PLL out gate */
+       clks[IMX8MM_AUDIO_PLL1_OUT] = imx_clk_gate("audio_pll1_out", "audio_pll1_bypass", base, 13);
+       clks[IMX8MM_AUDIO_PLL2_OUT] = imx_clk_gate("audio_pll2_out", "audio_pll2_bypass", base + 0x14, 13);
+       clks[IMX8MM_VIDEO_PLL1_OUT] = imx_clk_gate("video_pll1_out", "video_pll1_bypass", base + 0x28, 13);
+       clks[IMX8MM_DRAM_PLL_OUT] = imx_clk_gate("dram_pll_out", "dram_pll_bypass", base + 0x50, 13);
+       clks[IMX8MM_GPU_PLL_OUT] = imx_clk_gate("gpu_pll_out", "gpu_pll_bypass", base + 0x64, 13);
+    &