linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v10 0/9] Per-user clock constraints
@ 2014-09-09 14:02 Tomeu Vizoso
  2014-09-09 14:02 ` [PATCH v10 1/9] clk: Add temporary mapping to the existing API Tomeu Vizoso
                   ` (2 more replies)
  0 siblings, 3 replies; 15+ messages in thread
From: Tomeu Vizoso @ 2014-09-09 14:02 UTC (permalink / raw)
  To: Mike Turquette
  Cc: Stephen Warren, Thierry Reding, tomasz.figa, Peter De Schrijver,
	rabin, linux-kernel, linux-arm-kernel, Javier Martinez Canillas,
	Tomeu Vizoso

Hello,

I'm sending this v10 to update the conversion to the latest changes now in
linux-next and also to address comments from Stephen Boyd. The later are in
separate commits to make it easier for merging in the upcoming clk-next, but
can be squashed if that's more convenient.

Follows the original cover letter blurb:

I'm retaking Rabin's patches [0] for splitting the clk API in two: one API for
clk consumers and another for providers. The consumer API uses a clk structure
that just keeps track of the consumer and has a reference to the actual
clk_core struct, which is used internally.

I have kept a patch from Rabin that aims to aid in debugging nested
enable/disable calls, though my personal aim is to allow more than one consumer
to influence the final, effective frequency rate. For now this is limited to
setting floor and ceiling constraints, with the short-term aim of allowing
devfreq and thermal drivers to set floor and ceiling frequencies on the memory
clock, respectively.

For those functions in the consumer clk API that were called from providers, I
have added variants to clk-provider.h that are the same only that accept a
clk_core instead. These functions are prefixed with clk_provider_.

Patch 1/9 just adds a bunch of defines with the goal of having all the renames
in their own commit while preserving git-bisectability, with patch 2/9
containing the rename itself as generated by the Coccinelle script in [1].  The
actual implementation of the API split comes in patch 3/9. I will be happy to
organize the refactoring differently if anybody has a better idea.

Patch 4/9 warns when there's an unbalanced usage of the enable and disable
APIs, and patch 5/9 adds the API for setting floor and ceiling frequencies, per
consumer. Patch 6/9 will warn when prepare/unprepare are used unbalanced,
printing the code location of the last call to unprepare.

Patches 7/9 and 8/9 add some locking when manipulating shared structures and
9/9 adds a bit to the API docs.

[0] http://thread.gmane.org/gmane.linux.kernel/1402006
[1] http://cgit.collabora.com/git/user/tomeu/linux.git/log/?h=clk-refactoring-10

Thanks,

Tomeu

Tomeu Vizoso (9):
  clk: Add temporary mapping to the existing API
  clk: Move all drivers to use internal API
  clk: use struct clk only for external API
  clk: per-user clock accounting for debug
  clk: Add floor and ceiling constraints to clock rates
  clk: Warn of unbalanced clk_prepare() calls
  clk: Take the prepare lock when updating the list of per-user clks
  clk: Take the prepare lock when updating the per-user constraints
  clk: Add docs about calling clk_put after clk_get_parent

 arch/arm/mach-dove/common.c                   |  10 +-
 arch/arm/mach-imx/clk-busy.c                  |   9 +-
 arch/arm/mach-imx/clk-fixup-div.c             |   4 +-
 arch/arm/mach-imx/clk-fixup-mux.c             |   4 +-
 arch/arm/mach-imx/clk-gate-exclusive.c        |   4 +-
 arch/arm/mach-imx/clk-gate2.c                 |   4 +-
 arch/arm/mach-imx/clk-imx1.c                  |   3 +-
 arch/arm/mach-imx/clk-imx21.c                 |   3 +-
 arch/arm/mach-imx/clk-imx25.c                 |   9 +-
 arch/arm/mach-imx/clk-imx27.c                 |   5 +-
 arch/arm/mach-imx/clk-imx31.c                 |  11 +-
 arch/arm/mach-imx/clk-imx35.c                 |  23 +-
 arch/arm/mach-imx/clk-imx51-imx53.c           |  78 +--
 arch/arm/mach-imx/clk-imx6q.c                 |  75 ++-
 arch/arm/mach-imx/clk-imx6sl.c                |  43 +-
 arch/arm/mach-imx/clk-imx6sx.c                | 119 +++--
 arch/arm/mach-imx/clk-pfd.c                   |   5 +-
 arch/arm/mach-imx/clk-pllv1.c                 |   5 +-
 arch/arm/mach-imx/clk-pllv2.c                 |   5 +-
 arch/arm/mach-imx/clk-pllv3.c                 |   5 +-
 arch/arm/mach-imx/clk-vf610.c                 |  45 +-
 arch/arm/mach-imx/clk.c                       |  11 +-
 arch/arm/mach-imx/clk.h                       |  44 +-
 arch/arm/mach-msm/clock-pcom.c                |   2 +-
 arch/arm/mach-msm/clock.c                     |   2 +-
 arch/arm/mach-mv78xx0/common.c                |   2 +-
 arch/arm/mach-omap2/board-cm-t35.c            |   2 +-
 arch/arm/mach-omap2/cclock3xxx_data.c         | 371 +++++++------
 arch/arm/mach-omap2/clkt2xxx_dpll.c           |   5 +-
 arch/arm/mach-omap2/clkt2xxx_dpllcore.c       |   5 +-
 arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c  |  11 +-
 arch/arm/mach-omap2/clkt34xx_dpll3m2.c        |   3 +-
 arch/arm/mach-omap2/clkt_clksel.c             |  46 +-
 arch/arm/mach-omap2/clkt_dpll.c               |   8 +-
 arch/arm/mach-omap2/clock.c                   |  52 +-
 arch/arm/mach-omap2/clock.h                   |  18 +-
 arch/arm/mach-omap2/clock3xxx.c               |  23 +-
 arch/arm/mach-omap2/clock3xxx.h               |   4 +-
 arch/arm/mach-omap2/clock_common_data.c       |   2 +-
 arch/arm/mach-omap2/clockdomain.c             |   9 +-
 arch/arm/mach-omap2/clockdomain.h             |   4 +-
 arch/arm/mach-omap2/display.c                 |   6 +-
 arch/arm/mach-omap2/dpll3xxx.c                |  29 +-
 arch/arm/mach-omap2/dpll44xx.c                |   5 +-
 arch/arm/mach-omap2/mcbsp.c                   |   5 +-
 arch/arm/mach-omap2/omap_device.c             |  10 +-
 arch/arm/mach-omap2/omap_hwmod.c              |  42 +-
 arch/arm/mach-omap2/omap_hwmod.h              |  12 +-
 arch/arm/mach-omap2/pm24xx.c                  |  12 +-
 arch/arm/mach-orion5x/common.c                |   2 +-
 arch/arm/mach-shmobile/clock.c                |  10 +-
 arch/arm/mach-vexpress/spc.c                  |   4 +-
 arch/arm/plat-orion/common.c                  |  22 +-
 arch/arm/plat-orion/include/plat/common.h     |  12 +-
 arch/mips/alchemy/common/clock.c              |  42 +-
 arch/powerpc/platforms/512x/clock-commonclk.c |  48 +-
 drivers/acpi/acpi_lpss.c                      |   5 +-
 drivers/clk/at91/clk-main.c                   |  24 +-
 drivers/clk/at91/clk-master.c                 |   6 +-
 drivers/clk/at91/clk-peripheral.c             |  12 +-
 drivers/clk/at91/clk-pll.c                    |   6 +-
 drivers/clk/at91/clk-plldiv.c                 |   6 +-
 drivers/clk/at91/clk-programmable.c           |  10 +-
 drivers/clk/at91/clk-slow.c                   |  24 +-
 drivers/clk/at91/clk-smd.c                    |   6 +-
 drivers/clk/at91/clk-system.c                 |   6 +-
 drivers/clk/at91/clk-usb.c                    |  20 +-
 drivers/clk/at91/clk-utmi.c                   |   6 +-
 drivers/clk/bcm/clk-kona-setup.c              |   6 +-
 drivers/clk/bcm/clk-kona.c                    |  12 +-
 drivers/clk/bcm/clk-kona.h                    |   2 +-
 drivers/clk/berlin/berlin2-avpll.c            |   4 +-
 drivers/clk/berlin/berlin2-avpll.h            |   4 +-
 drivers/clk/berlin/berlin2-div.c              |   2 +-
 drivers/clk/berlin/berlin2-div.h              |   2 +-
 drivers/clk/berlin/berlin2-pll.c              |   2 +-
 drivers/clk/berlin/berlin2-pll.h              |   2 +-
 drivers/clk/berlin/bg2.c                      |  14 +-
 drivers/clk/berlin/bg2q.c                     |  10 +-
 drivers/clk/clk-axi-clkgen.c                  |   3 +-
 drivers/clk/clk-axm5516.c                     |   4 +-
 drivers/clk/clk-bcm2835.c                     |   2 +-
 drivers/clk/clk-clps711x.c                    |   3 +-
 drivers/clk/clk-composite.c                   |  11 +-
 drivers/clk/clk-conf.c                        |  18 +-
 drivers/clk/clk-devres.c                      |  31 ++
 drivers/clk/clk-divider.c                     |   8 +-
 drivers/clk/clk-efm32gg.c                     |   3 +-
 drivers/clk/clk-fixed-factor.c                |   6 +-
 drivers/clk/clk-fixed-rate.c                  |   8 +-
 drivers/clk/clk-fractional-divider.c          |   4 +-
 drivers/clk/clk-gate.c                        |   4 +-
 drivers/clk/clk-highbank.c                    |   8 +-
 drivers/clk/clk-ls1x.c                        |  16 +-
 drivers/clk/clk-max77686.c                    |  10 +-
 drivers/clk/clk-moxart.c                      |   8 +-
 drivers/clk/clk-mux.c                         |   7 +-
 drivers/clk/clk-nomadik.c                     |  15 +-
 drivers/clk/clk-nspire.c                      |   4 +-
 drivers/clk/clk-palmas.c                      |   7 +-
 drivers/clk/clk-ppc-corenet.c                 |   8 +-
 drivers/clk/clk-s2mps11.c                     |   6 +-
 drivers/clk/clk-si5351.c                      |  17 +-
 drivers/clk/clk-si570.c                       |   4 +-
 drivers/clk/clk-twl6040.c                     |   3 +-
 drivers/clk/clk-u300.c                        |  13 +-
 drivers/clk/clk-vt8500.c                      |   4 +-
 drivers/clk/clk-wm831x.c                      |   7 +-
 drivers/clk/clk-xgene.c                       |  12 +-
 drivers/clk/clk.c                             | 741 +++++++++++++++++---------
 drivers/clk/clk.h                             |  12 +-
 drivers/clk/clkdev.c                          | 130 ++++-
 drivers/clk/hisilicon/clk-hi3620.c            |   9 +-
 drivers/clk/hisilicon/clk-hip04.c             |   1 -
 drivers/clk/hisilicon/clk.c                   |  17 +-
 drivers/clk/hisilicon/clk.h                   |   2 +-
 drivers/clk/hisilicon/clkgate-separated.c     |   5 +-
 drivers/clk/keystone/gate.c                   |   7 +-
 drivers/clk/keystone/pll.c                    |  11 +-
 drivers/clk/mmp/clk-apbc.c                    |   5 +-
 drivers/clk/mmp/clk-apmu.c                    |   5 +-
 drivers/clk/mmp/clk-frac.c                    |   4 +-
 drivers/clk/mmp/clk-mmp2.c                    |  14 +-
 drivers/clk/mmp/clk-pxa168.c                  |  12 +-
 drivers/clk/mmp/clk-pxa910.c                  |  12 +-
 drivers/clk/mmp/clk.h                         |   8 +-
 drivers/clk/mvebu/clk-corediv.c               |   4 +-
 drivers/clk/mvebu/clk-cpu.c                   |   8 +-
 drivers/clk/mvebu/common.c                    |  15 +-
 drivers/clk/mvebu/kirkwood.c                  |   6 +-
 drivers/clk/mxs/clk-div.c                     |   5 +-
 drivers/clk/mxs/clk-frac.c                    |   5 +-
 drivers/clk/mxs/clk-imx23.c                   |   5 +-
 drivers/clk/mxs/clk-imx28.c                   |   5 +-
 drivers/clk/mxs/clk-pll.c                     |   5 +-
 drivers/clk/mxs/clk-ref.c                     |   5 +-
 drivers/clk/mxs/clk-ssp.c                     |   3 +-
 drivers/clk/mxs/clk.h                         |  17 +-
 drivers/clk/qcom/clk-rcg.c                    |   8 +-
 drivers/clk/qcom/clk-rcg2.c                   |  14 +-
 drivers/clk/qcom/clk-regmap.c                 |   2 +-
 drivers/clk/qcom/clk-regmap.h                 |   2 +-
 drivers/clk/qcom/common.c                     |   6 +-
 drivers/clk/qcom/gcc-apq8084.c                |   2 +-
 drivers/clk/qcom/gcc-ipq806x.c                |   2 +-
 drivers/clk/qcom/gcc-msm8660.c                |   2 +-
 drivers/clk/qcom/gcc-msm8960.c                |   2 +-
 drivers/clk/qcom/gcc-msm8974.c                |   2 +-
 drivers/clk/qcom/mmcc-msm8960.c               |   6 +-
 drivers/clk/rockchip/clk-pll.c                |   9 +-
 drivers/clk/rockchip/clk-rk3188.c             |   2 +-
 drivers/clk/rockchip/clk-rk3288.c             |   2 +-
 drivers/clk/rockchip/clk-rockchip.c           |   2 +-
 drivers/clk/rockchip/clk.c                    |  23 +-
 drivers/clk/rockchip/clk.h                    |   5 +-
 drivers/clk/samsung/clk-exynos-audss.c        |  16 +-
 drivers/clk/samsung/clk-exynos-clkout.c       |   9 +-
 drivers/clk/samsung/clk-exynos3250.c          |   1 -
 drivers/clk/samsung/clk-exynos4.c             |   7 +-
 drivers/clk/samsung/clk-exynos5250.c          |   1 -
 drivers/clk/samsung/clk-exynos5260.c          |   1 -
 drivers/clk/samsung/clk-exynos5410.c          |   1 -
 drivers/clk/samsung/clk-exynos5420.c          |   1 -
 drivers/clk/samsung/clk-exynos5440.c          |   1 -
 drivers/clk/samsung/clk-pll.c                 |   6 +-
 drivers/clk/samsung/clk-pll.h                 |   2 +-
 drivers/clk/samsung/clk-s3c2410-dclk.c        |  30 +-
 drivers/clk/samsung/clk-s3c2410.c             |   1 -
 drivers/clk/samsung/clk-s3c2412.c             |   1 -
 drivers/clk/samsung/clk-s3c2443.c             |   1 -
 drivers/clk/samsung/clk-s3c64xx.c             |   1 -
 drivers/clk/samsung/clk-s5pv210-audss.c       |  16 +-
 drivers/clk/samsung/clk-s5pv210.c             |   1 -
 drivers/clk/samsung/clk.c                     |  22 +-
 drivers/clk/samsung/clk.h                     |   3 +-
 drivers/clk/shmobile/clk-div6.c               |   2 +-
 drivers/clk/shmobile/clk-emev2.c              |   4 +-
 drivers/clk/shmobile/clk-mstp.c               |   6 +-
 drivers/clk/shmobile/clk-r8a7740.c            |   6 +-
 drivers/clk/shmobile/clk-r8a7779.c            |   6 +-
 drivers/clk/shmobile/clk-rcar-gen2.c          |  10 +-
 drivers/clk/shmobile/clk-rz.c                 |   6 +-
 drivers/clk/sirf/clk-atlas6.c                 |   3 +-
 drivers/clk/sirf/clk-common.c                 |  30 +-
 drivers/clk/sirf/clk-prima2.c                 |   3 +-
 drivers/clk/socfpga/clk-gate.c                |   3 +-
 drivers/clk/socfpga/clk-periph.c              |   3 +-
 drivers/clk/socfpga/clk-pll.c                 |   5 +-
 drivers/clk/spear/clk-aux-synth.c             |   8 +-
 drivers/clk/spear/clk-frac-synth.c            |   4 +-
 drivers/clk/spear/clk-gpt-synth.c             |   4 +-
 drivers/clk/spear/clk-vco-pll.c               |   8 +-
 drivers/clk/spear/clk.h                       |  14 +-
 drivers/clk/spear/spear1310_clock.c           |   3 +-
 drivers/clk/spear/spear1340_clock.c           |   3 +-
 drivers/clk/spear/spear3xx_clock.c            |  17 +-
 drivers/clk/spear/spear6xx_clock.c            |   3 +-
 drivers/clk/st/clk-flexgen.c                  |  12 +-
 drivers/clk/st/clkgen-fsyn.c                  |  22 +-
 drivers/clk/st/clkgen-mux.c                   |  32 +-
 drivers/clk/st/clkgen-pll.c                   |  34 +-
 drivers/clk/sunxi/clk-a10-hosc.c              |   2 +-
 drivers/clk/sunxi/clk-a20-gmac.c              |   2 +-
 drivers/clk/sunxi/clk-factors.c               |   4 +-
 drivers/clk/sunxi/clk-sun6i-apb0-gates.c      |   2 +-
 drivers/clk/sunxi/clk-sun6i-apb0.c            |   2 +-
 drivers/clk/sunxi/clk-sun6i-ar100.c           |   6 +-
 drivers/clk/sunxi/clk-sun8i-apb0.c            |   2 +-
 drivers/clk/sunxi/clk-sunxi.c                 |  18 +-
 drivers/clk/tegra/clk-audio-sync.c            |   4 +-
 drivers/clk/tegra/clk-divider.c               |   5 +-
 drivers/clk/tegra/clk-periph-gate.c           |   5 +-
 drivers/clk/tegra/clk-periph.c                |   9 +-
 drivers/clk/tegra/clk-pll-out.c               |   5 +-
 drivers/clk/tegra/clk-pll.c                   |  41 +-
 drivers/clk/tegra/clk-super.c                 |   5 +-
 drivers/clk/tegra/clk-tegra-audio.c           |   5 +-
 drivers/clk/tegra/clk-tegra-fixed.c           |   9 +-
 drivers/clk/tegra/clk-tegra-periph.c          |  13 +-
 drivers/clk/tegra/clk-tegra-pmc.c             |   5 +-
 drivers/clk/tegra/clk-tegra-super-gen4.c      |   9 +-
 drivers/clk/tegra/clk-tegra114.c              |  11 +-
 drivers/clk/tegra/clk-tegra124.c              |   7 +-
 drivers/clk/tegra/clk-tegra20.c               |  13 +-
 drivers/clk/tegra/clk-tegra30.c               |   9 +-
 drivers/clk/tegra/clk.c                       |  25 +-
 drivers/clk/tegra/clk.h                       |  38 +-
 drivers/clk/ti/apll.c                         |   8 +-
 drivers/clk/ti/clk-2xxx.c                     |   8 +-
 drivers/clk/ti/clk-33xx.c                     |  18 +-
 drivers/clk/ti/clk-3xxx.c                     |   8 +-
 drivers/clk/ti/clk-43xx.c                     |   8 +-
 drivers/clk/ti/clk-44xx.c                     |  16 +-
 drivers/clk/ti/clk-54xx.c                     |  25 +-
 drivers/clk/ti/clk-7xx.c                      |  28 +-
 drivers/clk/ti/clk-dra7-atl.c                 |   6 +-
 drivers/clk/ti/clk.c                          |   2 +-
 drivers/clk/ti/clockdomain.c                  |   4 +-
 drivers/clk/ti/composite.c                    |   2 +-
 drivers/clk/ti/divider.c                      |   6 +-
 drivers/clk/ti/dpll.c                         |   8 +-
 drivers/clk/ti/fixed-factor.c                 |   2 +-
 drivers/clk/ti/gate.c                         |   2 +-
 drivers/clk/ti/interface.c                    |   2 +-
 drivers/clk/ti/mux.c                          |   6 +-
 drivers/clk/ux500/abx500-clk.c                |   3 +-
 drivers/clk/ux500/clk-prcc.c                  |   8 +-
 drivers/clk/ux500/clk-prcmu.c                 |  16 +-
 drivers/clk/ux500/clk-sysctrl.c               |  10 +-
 drivers/clk/ux500/clk.h                       |  23 +-
 drivers/clk/ux500/u8500_clk.c                 |   3 +-
 drivers/clk/ux500/u8500_of_clk.c              |  13 +-
 drivers/clk/ux500/u8540_clk.c                 |   3 +-
 drivers/clk/ux500/u9540_clk.c                 |   1 -
 drivers/clk/versatile/clk-icst.c              |   5 +-
 drivers/clk/versatile/clk-icst.h              |   2 +-
 drivers/clk/versatile/clk-impd1.c             |  19 +-
 drivers/clk/versatile/clk-realview.c          |   3 +-
 drivers/clk/versatile/clk-sp810.c             |  30 +-
 drivers/clk/versatile/clk-versatile.c         |   3 +-
 drivers/clk/versatile/clk-vexpress-osc.c      |   2 +-
 drivers/clk/versatile/clk-vexpress.c          |   6 +-
 drivers/clk/x86/clk-lpt.c                     |   3 +-
 drivers/clk/zynq/clkc.c                       |  22 +-
 drivers/clk/zynq/pll.c                        |   4 +-
 drivers/gpu/drm/msm/hdmi/hdmi_phy_8960.c      |   3 +-
 drivers/media/platform/exynos4-is/media-dev.c |  18 +-
 drivers/media/platform/exynos4-is/media-dev.h |   7 +-
 drivers/media/platform/omap3isp/isp.h         |   2 +-
 drivers/rtc/rtc-hym8563.c                     |   4 +-
 drivers/spi/spi-pxa2xx-pci.c                  |   1 -
 drivers/staging/imx-drm/imx-tve.c             |  27 +-
 include/asm-generic/clkdev.h                  |   6 +-
 include/linux/clk-private.h                   |  51 +-
 include/linux/clk-provider.h                  | 137 +++--
 include/linux/clk.h                           |  53 +-
 include/linux/clk/ti.h                        |  10 +-
 include/linux/clk/zynq.h                      |   3 +-
 include/linux/clkdev.h                        |  24 +-
 include/linux/platform_data/si5351.h          |   4 +-
 sound/soc/mxs/mxs-saif.c                      |   4 +-
 281 files changed, 2370 insertions(+), 1919 deletions(-)

-- 
1.9.3


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v10 1/9] clk: Add temporary mapping to the existing API
  2014-09-09 14:02 [PATCH v10 0/9] Per-user clock constraints Tomeu Vizoso
@ 2014-09-09 14:02 ` Tomeu Vizoso
  2014-09-09 14:06 ` [PATCH v10 3/9] clk: use struct clk only for external API Tomeu Vizoso
       [not found] ` <1410271497-27148-1-git-send-email-tomeu.vizoso@collabora.com>
  2 siblings, 0 replies; 15+ messages in thread
From: Tomeu Vizoso @ 2014-09-09 14:02 UTC (permalink / raw)
  To: Mike Turquette
  Cc: Stephen Warren, Thierry Reding, tomasz.figa, Peter De Schrijver,
	rabin, linux-kernel, linux-arm-kernel, Javier Martinez Canillas,
	Tomeu Vizoso

To preserve git-bisectability, add aliases from the future provider API to the
existing public API.

Also includes clk-provider.h and clk-dev.h in a few places so the right
functions are defined.

Signed-off-by: Tomeu Vizoso <tomeu.vizoso@collabora.com>
Acked-by: Tony Lindgren <tony@atomide.com>
Acked-by: Jason Cooper <jason@lakedaemon.net>
Acked-by: Simon Horman <horms+renesas@verge.net.au>
Acked-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
Tested-by: Heiko Stuebner <heiko@sntech.de>

---
v9: * Add mapping for clk_get_name

v7: * Add mappings for clk_notifier_[un]register
    * Add more clk-provider.h includes to clk implementations

v4: * Add more clk-provider.h includes to clk implementations
    * Add mapping for clk_provider_round_rate
---
 arch/arm/mach-omap2/display.c                 |  1 +
 arch/arm/mach-omap2/omap_device.c             |  1 +
 arch/arm/mach-shmobile/clock.c                |  1 +
 arch/arm/plat-orion/common.c                  |  1 +
 drivers/clk/berlin/bg2.c                      |  1 +
 drivers/clk/berlin/bg2q.c                     |  1 +
 drivers/clk/clk-conf.c                        |  1 +
 drivers/clk/clkdev.c                          |  1 +
 drivers/media/platform/exynos4-is/media-dev.c |  1 +
 include/linux/clk-provider.h                  | 27 +++++++++++++++++++++++++++
 include/linux/clk/zynq.h                      |  1 +
 11 files changed, 37 insertions(+)

diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c
index bf852d7..0f9e479 100644
--- a/arch/arm/mach-omap2/display.c
+++ b/arch/arm/mach-omap2/display.c
@@ -21,6 +21,7 @@
 #include <linux/platform_device.h>
 #include <linux/io.h>
 #include <linux/clk.h>
+#include <linux/clk-provider.h>
 #include <linux/err.h>
 #include <linux/delay.h>
 #include <linux/of.h>
diff --git a/arch/arm/mach-omap2/omap_device.c b/arch/arm/mach-omap2/omap_device.c
index d22c30d..f138a62 100644
--- a/arch/arm/mach-omap2/omap_device.c
+++ b/arch/arm/mach-omap2/omap_device.c
@@ -32,6 +32,7 @@
 #include <linux/io.h>
 #include <linux/clk.h>
 #include <linux/clkdev.h>
+#include <linux/clk-provider.h>
 #include <linux/pm_runtime.h>
 #include <linux/of.h>
 #include <linux/notifier.h>
diff --git a/arch/arm/mach-shmobile/clock.c b/arch/arm/mach-shmobile/clock.c
index 806f940..ed415dc 100644
--- a/arch/arm/mach-shmobile/clock.c
+++ b/arch/arm/mach-shmobile/clock.c
@@ -24,6 +24,7 @@
 
 #ifdef CONFIG_COMMON_CLK
 #include <linux/clk.h>
+#include <linux/clk-provider.h>
 #include <linux/clkdev.h>
 #include "clock.h"
 
diff --git a/arch/arm/plat-orion/common.c b/arch/arm/plat-orion/common.c
index 3ec6e8e..961b593 100644
--- a/arch/arm/plat-orion/common.c
+++ b/arch/arm/plat-orion/common.c
@@ -15,6 +15,7 @@
 #include <linux/serial_8250.h>
 #include <linux/ata_platform.h>
 #include <linux/clk.h>
+#include <linux/clk-provider.h>
 #include <linux/clkdev.h>
 #include <linux/mv643xx_eth.h>
 #include <linux/mv643xx_i2c.h>
diff --git a/drivers/clk/berlin/bg2.c b/drivers/clk/berlin/bg2.c
index 515fb13..4c81e09 100644
--- a/drivers/clk/berlin/bg2.c
+++ b/drivers/clk/berlin/bg2.c
@@ -19,6 +19,7 @@
 
 #include <linux/clk.h>
 #include <linux/clk-provider.h>
+#include <linux/clkdev.h>
 #include <linux/kernel.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
diff --git a/drivers/clk/berlin/bg2q.c b/drivers/clk/berlin/bg2q.c
index 21784e4..748da9b 100644
--- a/drivers/clk/berlin/bg2q.c
+++ b/drivers/clk/berlin/bg2q.c
@@ -19,6 +19,7 @@
 
 #include <linux/clk.h>
 #include <linux/clk-provider.h>
+#include <linux/clkdev.h>
 #include <linux/kernel.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
diff --git a/drivers/clk/clk-conf.c b/drivers/clk/clk-conf.c
index aad4796..d36a7b3 100644
--- a/drivers/clk/clk-conf.c
+++ b/drivers/clk/clk-conf.c
@@ -8,6 +8,7 @@
  */
 
 #include <linux/clk.h>
+#include <linux/clkdev.h>
 #include <linux/clk-provider.h>
 #include <linux/clk/clk-conf.h>
 #include <linux/device.h>
diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c
index da4bda8..c751d0c 100644
--- a/drivers/clk/clkdev.c
+++ b/drivers/clk/clkdev.c
@@ -18,6 +18,7 @@
 #include <linux/string.h>
 #include <linux/mutex.h>
 #include <linux/clk.h>
+#include <linux/clk-provider.h>
 #include <linux/clkdev.h>
 #include <linux/of.h>
 
diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c
index 344718d..2620c48 100644
--- a/drivers/media/platform/exynos4-is/media-dev.c
+++ b/drivers/media/platform/exynos4-is/media-dev.c
@@ -13,6 +13,7 @@
 #include <linux/bug.h>
 #include <linux/clk.h>
 #include <linux/clk-provider.h>
+#include <linux/clkdev.h>
 #include <linux/device.h>
 #include <linux/errno.h>
 #include <linux/i2c.h>
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index 411dd7e..99b906f 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -16,6 +16,33 @@
 
 #ifdef CONFIG_COMMON_CLK
 
+/* Temporarily map the to-be-added API to the old API, just so stuff compiles */
+#define clk_core			clk
+
+#define __clk_create_clk
+
+#define clk_provider_get			clk_get
+#define clk_provider_get_sys			clk_get_sys
+#define devm_clk_provider_get			devm_clk_get
+#define of_clk_provider_get			of_clk_get
+#define of_clk_provider_get_by_name		of_clk_get_by_name
+
+#define clk_provider_set_rate			clk_set_rate
+#define clk_provider_get_rate			clk_get_rate
+#define clk_provider_round_rate			clk_round_rate
+#define clk_provider_set_parent			clk_set_parent
+#define clk_provider_get_parent			clk_get_parent
+#define clk_provider_prepare			clk_prepare
+#define clk_provider_unprepare			clk_unprepare
+#define clk_provider_enable			clk_enable
+#define clk_provider_disable			clk_disable
+#define clk_provider_prepare_enable		clk_prepare_enable
+#define clk_provider_disable_unprepare		clk_unprepare
+#define clk_provider_notifier_register		clk_notifier_register
+#define clk_provider_notifier_unregister	clk_notifier_unregister
+
+#define clk_get_name				__clk_get_name
+
 /*
  * flags used across common struct clk.  these flags should only affect the
  * top-level framework.  custom flags for dealing with hardware specifics
diff --git a/include/linux/clk/zynq.h b/include/linux/clk/zynq.h
index 7a5633b..a990a59 100644
--- a/include/linux/clk/zynq.h
+++ b/include/linux/clk/zynq.h
@@ -21,6 +21,7 @@
 #define __LINUX_CLK_ZYNQ_H_
 
 #include <linux/spinlock.h>
+#include <linux/clk-provider.h>
 
 void zynq_clock_init(void);
 
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v10 3/9] clk: use struct clk only for external API
  2014-09-09 14:02 [PATCH v10 0/9] Per-user clock constraints Tomeu Vizoso
  2014-09-09 14:02 ` [PATCH v10 1/9] clk: Add temporary mapping to the existing API Tomeu Vizoso
@ 2014-09-09 14:06 ` Tomeu Vizoso
  2014-09-09 14:06   ` [PATCH v10 4/9] clk: per-user clock accounting for debug Tomeu Vizoso
                     ` (5 more replies)
       [not found] ` <1410271497-27148-1-git-send-email-tomeu.vizoso@collabora.com>
  2 siblings, 6 replies; 15+ messages in thread
From: Tomeu Vizoso @ 2014-09-09 14:06 UTC (permalink / raw)
  To: Mike Turquette
  Cc: Stephen Warren, Thierry Reding, tomasz.figa, Peter De Schrijver,
	rabin, linux-kernel, linux-arm-kernel, Javier Martinez Canillas,
	Tomeu Vizoso

In order to provide per-user accounting, this separates the struct clk
used in the common clock framework into two structures 'struct clk_core'
and 'struct clk'. struct clk_core will be used for internal
manipulation and struct clk will be used in the clock API
implementation.

In this patch, struct clk is simply renamed to struct clk_core and a new
struct clk is implemented which simply wraps it. In the next patch, the
new struct clk will be used to implement per-user clock enable
accounting.

Based on previous work by Rabin Vincent <rabin@rab.in>.

NOTE: with this patch, clk_get_parent() behaves like clk_get(), i.e. it
needs to be matched with a clk_put().  Otherwise, memory will leak.

Signed-off-by: Tomeu Vizoso <tomeu.vizoso@collabora.com>
Tested-by: Heiko Stuebner <heiko@sntech.de>

---

v9: * Removed superfluous variable

v7: * convert clk_is_enabled to clk_core
    * add clk_provider_notifier_[un]register

v4: * export clk_to_clk_core so mach-msm can use it for clk_reset
    * add clk_provider_round_rate, for mach-imx
    * fix build with !CONFIG_COMMON_CLK
    * keep handling NULL struct clk gracefully as before

v3: * Allocate and release the per-user struct clk
    * Have clk_core_to_clk return any error it's passed, so calls to it can be chained
    * Add provider API for enable and disable
    * Remove clk_free_clk for now
    * Have clk_to_clk_core be an inline function to benefit of type-checking
    * Have devres wrap the clk struct instead of clk_core
    * Rename clk_core_to_clk to __clk_create_clk to make more clear that it allocates
---
 arch/arm/mach-msm/clock.c    |   2 +-
 drivers/clk/clk-devres.c     |  31 ++
 drivers/clk/clk.c            | 669 ++++++++++++++++++++++++++-----------------
 drivers/clk/clk.h            |   6 +
 drivers/clk/clkdev.c         | 123 ++++++--
 include/linux/clk-private.h  |  38 +--
 include/linux/clk-provider.h | 164 ++++++-----
 include/linux/clk.h          |  32 ++-
 include/linux/clkdev.h       |  24 +-
 9 files changed, 701 insertions(+), 388 deletions(-)

diff --git a/arch/arm/mach-msm/clock.c b/arch/arm/mach-msm/clock.c
index 35ea02b5..1de0b5a 100644
--- a/arch/arm/mach-msm/clock.c
+++ b/arch/arm/mach-msm/clock.c
@@ -21,7 +21,7 @@
 
 int clk_reset(struct clk *clk, enum clk_reset_action action)
 {
-	struct clk_hw *hw = __clk_get_hw(clk);
+	struct clk_hw *hw = __clk_get_hw(clk_to_clk_core(clk));
 	struct msm_clk *m = to_msm_clk(hw);
 	return m->reset(hw, action);
 }
diff --git a/drivers/clk/clk-devres.c b/drivers/clk/clk-devres.c
index 8f57154..79cd4d3 100644
--- a/drivers/clk/clk-devres.c
+++ b/drivers/clk/clk-devres.c
@@ -5,10 +5,14 @@
  */
 
 #include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
 #include <linux/device.h>
 #include <linux/export.h>
 #include <linux/gfp.h>
 
+#include "clk.h"
+
 static void devm_clk_release(struct device *dev, void *res)
 {
 	clk_put(*(struct clk **)res);
@@ -34,6 +38,33 @@ struct clk *devm_clk_get(struct device *dev, const char *id)
 }
 EXPORT_SYMBOL(devm_clk_get);
 
+#if defined(CONFIG_COMMON_CLK)
+static void devm_clk_core_release(struct device *dev, void *res)
+{
+	__clk_put(*(struct clk_core **)res);
+}
+
+struct clk_core *devm_clk_provider_get(struct device *dev, const char *id)
+{
+	struct clk_core **ptr, *clk;
+
+	ptr = devres_alloc(devm_clk_core_release, sizeof(*ptr), GFP_KERNEL);
+	if (!ptr)
+		return ERR_PTR(-ENOMEM);
+
+	clk = clk_provider_get(dev, id);
+	if (!IS_ERR(clk)) {
+		*ptr = clk;
+		devres_add(dev, ptr);
+	} else {
+		devres_free(ptr);
+	}
+
+	return clk;
+}
+EXPORT_SYMBOL(devm_clk_provider_get);
+#endif
+
 static int devm_clk_match(struct device *dev, void *res, void *data)
 {
 	struct clk **c = res;
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index b76fa69..ce84b1f 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -37,6 +37,8 @@ static HLIST_HEAD(clk_root_list);
 static HLIST_HEAD(clk_orphan_list);
 static LIST_HEAD(clk_notifier_list);
 
+static long __clk_get_accuracy_internal(struct clk_core *clk);
+
 /***           locking             ***/
 static void clk_prepare_lock(void)
 {
@@ -112,7 +114,7 @@ static struct hlist_head *orphan_list[] = {
 	NULL,
 };
 
-static void clk_summary_show_one(struct seq_file *s, struct clk *c, int level)
+static void clk_summary_show_one(struct seq_file *s, struct clk_core *c, int level)
 {
 	if (!c)
 		return;
@@ -120,14 +122,14 @@ static void clk_summary_show_one(struct seq_file *s, struct clk *c, int level)
 	seq_printf(s, "%*s%-*s %11d %12d %11lu %10lu\n",
 		   level * 3 + 1, "",
 		   30 - level * 3, c->name,
-		   c->enable_count, c->prepare_count, clk_get_rate(c),
-		   clk_get_accuracy(c));
+		   c->enable_count, c->prepare_count, clk_provider_get_rate(c),
+		   __clk_get_accuracy_internal(c));
 }
 
-static void clk_summary_show_subtree(struct seq_file *s, struct clk *c,
+static void clk_summary_show_subtree(struct seq_file *s, struct clk_core *c,
 				     int level)
 {
-	struct clk *child;
+	struct clk_core *child;
 
 	if (!c)
 		return;
@@ -140,7 +142,7 @@ static void clk_summary_show_subtree(struct seq_file *s, struct clk *c,
 
 static int clk_summary_show(struct seq_file *s, void *data)
 {
-	struct clk *c;
+	struct clk_core *c;
 	struct hlist_head **lists = (struct hlist_head **)s->private;
 
 	seq_puts(s, "   clock                         enable_cnt  prepare_cnt        rate   accuracy\n");
@@ -170,7 +172,7 @@ static const struct file_operations clk_summary_fops = {
 	.release	= single_release,
 };
 
-static void clk_dump_one(struct seq_file *s, struct clk *c, int level)
+static void clk_dump_one(struct seq_file *s, struct clk_core *c, int level)
 {
 	if (!c)
 		return;
@@ -178,13 +180,13 @@ static void clk_dump_one(struct seq_file *s, struct clk *c, int level)
 	seq_printf(s, "\"%s\": { ", c->name);
 	seq_printf(s, "\"enable_count\": %d,", c->enable_count);
 	seq_printf(s, "\"prepare_count\": %d,", c->prepare_count);
-	seq_printf(s, "\"rate\": %lu", clk_get_rate(c));
-	seq_printf(s, "\"accuracy\": %lu", clk_get_accuracy(c));
+	seq_printf(s, "\"rate\": %lu", clk_provider_get_rate(c));
+	seq_printf(s, "\"accuracy\": %lu", __clk_get_accuracy_internal(c));
 }
 
-static void clk_dump_subtree(struct seq_file *s, struct clk *c, int level)
+static void clk_dump_subtree(struct seq_file *s, struct clk_core *c, int level)
 {
-	struct clk *child;
+	struct clk_core *child;
 
 	if (!c)
 		return;
@@ -201,7 +203,7 @@ static void clk_dump_subtree(struct seq_file *s, struct clk *c, int level)
 
 static int clk_dump(struct seq_file *s, void *data)
 {
-	struct clk *c;
+	struct clk_core *c;
 	bool first_node = true;
 	struct hlist_head **lists = (struct hlist_head **)s->private;
 
@@ -238,7 +240,7 @@ static const struct file_operations clk_dump_fops = {
 };
 
 /* caller must hold prepare_lock */
-static int clk_debug_create_one(struct clk *clk, struct dentry *pdentry)
+static int clk_debug_create_one(struct clk_core *clk, struct dentry *pdentry)
 {
 	struct dentry *d;
 	int ret = -ENOMEM;
@@ -301,9 +303,9 @@ out:
 }
 
 /* caller must hold prepare_lock */
-static int clk_debug_create_subtree(struct clk *clk, struct dentry *pdentry)
+static int clk_debug_create_subtree(struct clk_core *clk, struct dentry *pdentry)
 {
-	struct clk *child;
+	struct clk_core *child;
 	int ret = -EINVAL;;
 
 	if (!clk || !pdentry)
@@ -333,7 +335,7 @@ out:
  * Caller must hold prepare_lock.  Only clk_init calls this function (so
  * far) so this is taken care.
  */
-static int clk_debug_register(struct clk *clk)
+static int clk_debug_register(struct clk_core *clk)
 {
 	int ret = 0;
 
@@ -356,12 +358,12 @@ out:
  *
  * Caller must hold prepare_lock.
  */
-static void clk_debug_unregister(struct clk *clk)
+static void clk_debug_unregister(struct clk_core *clk)
 {
 	debugfs_remove_recursive(clk->dentry);
 }
 
-struct dentry *clk_debugfs_add_file(struct clk *clk, char *name, umode_t mode,
+struct dentry *clk_debugfs_add_file(struct clk_core *clk, char *name, umode_t mode,
 				void *data, const struct file_operations *fops)
 {
 	struct dentry *d = NULL;
@@ -387,7 +389,7 @@ EXPORT_SYMBOL_GPL(clk_debugfs_add_file);
  */
 static int __init clk_debug_init(void)
 {
-	struct clk *clk;
+	struct clk_core *clk;
 	struct dentry *d;
 
 	rootdir = debugfs_create_dir("clk", NULL);
@@ -431,19 +433,19 @@ static int __init clk_debug_init(void)
 }
 late_initcall(clk_debug_init);
 #else
-static inline int clk_debug_register(struct clk *clk) { return 0; }
-static inline void clk_debug_reparent(struct clk *clk, struct clk *new_parent)
+static inline int clk_debug_register(struct clk_core *clk) { return 0; }
+static inline void clk_debug_reparent(struct clk_core *clk, struct clk_core *new_parent)
 {
 }
-static inline void clk_debug_unregister(struct clk *clk)
+static inline void clk_debug_unregister(struct clk_core *clk)
 {
 }
 #endif
 
 /* caller must hold prepare_lock */
-static void clk_unprepare_unused_subtree(struct clk *clk)
+static void clk_unprepare_unused_subtree(struct clk_core *clk)
 {
-	struct clk *child;
+	struct clk_core *child;
 
 	if (!clk)
 		return;
@@ -466,9 +468,9 @@ static void clk_unprepare_unused_subtree(struct clk *clk)
 }
 
 /* caller must hold prepare_lock */
-static void clk_disable_unused_subtree(struct clk *clk)
+static void clk_disable_unused_subtree(struct clk_core *clk)
 {
-	struct clk *child;
+	struct clk_core *child;
 	unsigned long flags;
 
 	if (!clk)
@@ -514,7 +516,7 @@ __setup("clk_ignore_unused", clk_ignore_unused_setup);
 
 static int clk_disable_unused(void)
 {
-	struct clk *clk;
+	struct clk_core *clk;
 
 	if (clk_ignore_unused) {
 		pr_warn("clk: Not disabling unused clocks\n");
@@ -541,33 +543,50 @@ static int clk_disable_unused(void)
 }
 late_initcall_sync(clk_disable_unused);
 
+struct clk *__clk_create_clk(struct clk_core *clk_core)
+{
+	struct clk *clk;
+
+	/* This is to allow this function to be chained to others */
+	if (!clk_core || IS_ERR(clk_core))
+		return (struct clk *) clk_core;
+
+	clk = kzalloc(sizeof(*clk), GFP_KERNEL);
+	if (!clk)
+		return ERR_PTR(-ENOMEM);
+
+	clk->core = clk_core;
+
+	return clk;
+}
+
 /***    helper functions   ***/
 
-const char *__clk_get_name(struct clk *clk)
+const char *__clk_get_name(struct clk_core *clk)
 {
 	return !clk ? NULL : clk->name;
 }
 EXPORT_SYMBOL_GPL(__clk_get_name);
 
-struct clk_hw *__clk_get_hw(struct clk *clk)
+struct clk_hw *__clk_get_hw(struct clk_core *clk)
 {
 	return !clk ? NULL : clk->hw;
 }
 EXPORT_SYMBOL_GPL(__clk_get_hw);
 
-u8 __clk_get_num_parents(struct clk *clk)
+u8 __clk_get_num_parents(struct clk_core *clk)
 {
 	return !clk ? 0 : clk->num_parents;
 }
 EXPORT_SYMBOL_GPL(__clk_get_num_parents);
 
-struct clk *__clk_get_parent(struct clk *clk)
+struct clk_core *__clk_get_parent(struct clk_core *clk)
 {
 	return !clk ? NULL : clk->parent;
 }
 EXPORT_SYMBOL_GPL(__clk_get_parent);
 
-struct clk *clk_get_parent_by_index(struct clk *clk, u8 index)
+struct clk_core *clk_get_parent_by_index(struct clk_core *clk, u8 index)
 {
 	if (!clk || index >= clk->num_parents)
 		return NULL;
@@ -581,17 +600,17 @@ struct clk *clk_get_parent_by_index(struct clk *clk, u8 index)
 }
 EXPORT_SYMBOL_GPL(clk_get_parent_by_index);
 
-unsigned int __clk_get_enable_count(struct clk *clk)
+unsigned int __clk_get_enable_count(struct clk_core *clk)
 {
 	return !clk ? 0 : clk->enable_count;
 }
 
-unsigned int __clk_get_prepare_count(struct clk *clk)
+unsigned int __clk_get_prepare_count(struct clk_core *clk)
 {
 	return !clk ? 0 : clk->prepare_count;
 }
 
-unsigned long __clk_get_rate(struct clk *clk)
+unsigned long __clk_get_rate(struct clk_core *clk)
 {
 	unsigned long ret;
 
@@ -613,7 +632,7 @@ out:
 }
 EXPORT_SYMBOL_GPL(__clk_get_rate);
 
-unsigned long __clk_get_accuracy(struct clk *clk)
+unsigned long __clk_get_accuracy(struct clk_core *clk)
 {
 	if (!clk)
 		return 0;
@@ -621,13 +640,13 @@ unsigned long __clk_get_accuracy(struct clk *clk)
 	return clk->accuracy;
 }
 
-unsigned long __clk_get_flags(struct clk *clk)
+unsigned long __clk_get_flags(struct clk_core *clk)
 {
 	return !clk ? 0 : clk->flags;
 }
 EXPORT_SYMBOL_GPL(__clk_get_flags);
 
-bool __clk_is_prepared(struct clk *clk)
+bool __clk_is_prepared(struct clk_core *clk)
 {
 	int ret;
 
@@ -648,7 +667,7 @@ out:
 	return !!ret;
 }
 
-bool __clk_is_enabled(struct clk *clk)
+bool __clk_is_enabled(struct clk_core *clk)
 {
 	int ret;
 
@@ -670,10 +689,10 @@ out:
 }
 EXPORT_SYMBOL_GPL(__clk_is_enabled);
 
-static struct clk *__clk_lookup_subtree(const char *name, struct clk *clk)
+static struct clk_core *__clk_lookup_subtree(const char *name, struct clk_core *clk)
 {
-	struct clk *child;
-	struct clk *ret;
+	struct clk_core *child;
+	struct clk_core *ret;
 
 	if (!strcmp(clk->name, name))
 		return clk;
@@ -687,10 +706,10 @@ static struct clk *__clk_lookup_subtree(const char *name, struct clk *clk)
 	return NULL;
 }
 
-struct clk *__clk_lookup(const char *name)
+struct clk_core *__clk_lookup(const char *name)
 {
-	struct clk *root_clk;
-	struct clk *ret;
+	struct clk_core *root_clk;
+	struct clk_core *ret;
 
 	if (!name)
 		return NULL;
@@ -719,9 +738,9 @@ struct clk *__clk_lookup(const char *name)
  */
 long __clk_mux_determine_rate(struct clk_hw *hw, unsigned long rate,
 			      unsigned long *best_parent_rate,
-			      struct clk **best_parent_p)
+			      struct clk_core **best_parent_p)
 {
-	struct clk *clk = hw->clk, *parent, *best_parent = NULL;
+	struct clk_core *clk = hw->clk, *parent, *best_parent = NULL;
 	int i, num_parents;
 	unsigned long parent_rate, best = 0;
 
@@ -764,7 +783,7 @@ EXPORT_SYMBOL_GPL(__clk_mux_determine_rate);
 
 /***        clk api        ***/
 
-void __clk_unprepare(struct clk *clk)
+void __clk_unprepare(struct clk_core *clk)
 {
 	if (!clk)
 		return;
@@ -783,9 +802,20 @@ void __clk_unprepare(struct clk *clk)
 	__clk_unprepare(clk->parent);
 }
 
+void clk_provider_unprepare(struct clk_core *clk)
+{
+	if (IS_ERR_OR_NULL(clk))
+		return;
+
+	clk_prepare_lock();
+	__clk_unprepare(clk);
+	clk_prepare_unlock();
+}
+EXPORT_SYMBOL_GPL(clk_provider_unprepare);
+
 /**
  * clk_unprepare - undo preparation of a clock source
- * @clk: the clk being unprepared
+ * @clk_user: the clk being unprepared
  *
  * clk_unprepare may sleep, which differentiates it from clk_disable.  In a
  * simple case, clk_unprepare can be used instead of clk_disable to gate a clk
@@ -794,18 +824,16 @@ void __clk_unprepare(struct clk *clk)
  * part.  It is this reason that clk_unprepare and clk_disable are not mutually
  * exclusive.  In fact clk_disable must be called before clk_unprepare.
  */
-void clk_unprepare(struct clk *clk)
+void clk_unprepare(struct clk *clk_user)
 {
-	if (IS_ERR_OR_NULL(clk))
+	if (IS_ERR_OR_NULL(clk_user))
 		return;
 
-	clk_prepare_lock();
-	__clk_unprepare(clk);
-	clk_prepare_unlock();
+	clk_provider_unprepare(clk_to_clk_core(clk_user));
 }
 EXPORT_SYMBOL_GPL(clk_unprepare);
 
-int __clk_prepare(struct clk *clk)
+int __clk_prepare(struct clk_core *clk)
 {
 	int ret = 0;
 
@@ -831,9 +859,21 @@ int __clk_prepare(struct clk *clk)
 	return 0;
 }
 
+int clk_provider_prepare(struct clk_core *clk)
+{
+	int ret;
+
+	clk_prepare_lock();
+	ret = __clk_prepare(clk);
+	clk_prepare_unlock();
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(clk_provider_prepare);
+
 /**
  * clk_prepare - prepare a clock source
- * @clk: the clk being prepared
+ * @clk_user: the clk being prepared
  *
  * clk_prepare may sleep, which differentiates it from clk_enable.  In a simple
  * case, clk_prepare can be used instead of clk_enable to ungate a clk if the
@@ -843,19 +883,16 @@ int __clk_prepare(struct clk *clk)
  * exclusive.  In fact clk_prepare must be called before clk_enable.
  * Returns 0 on success, -EERROR otherwise.
  */
-int clk_prepare(struct clk *clk)
+int clk_prepare(struct clk *clk_user)
 {
-	int ret;
-
-	clk_prepare_lock();
-	ret = __clk_prepare(clk);
-	clk_prepare_unlock();
+	if (!clk_user)
+		return 0;
 
-	return ret;
+	return clk_provider_prepare(clk_to_clk_core(clk_user));
 }
 EXPORT_SYMBOL_GPL(clk_prepare);
 
-static void __clk_disable(struct clk *clk)
+static void __clk_disable(struct clk_core *clk)
 {
 	if (!clk)
 		return;
@@ -872,9 +909,22 @@ static void __clk_disable(struct clk *clk)
 	__clk_disable(clk->parent);
 }
 
+void clk_provider_disable(struct clk_core *clk)
+{
+	unsigned long flags;
+
+	if (IS_ERR_OR_NULL(clk))
+		return;
+
+	flags = clk_enable_lock();
+	__clk_disable(clk);
+	clk_enable_unlock(flags);
+}
+EXPORT_SYMBOL_GPL(clk_provider_disable);
+
 /**
  * clk_disable - gate a clock
- * @clk: the clk being gated
+ * @clk_user: the clk being gated
  *
  * clk_disable must not sleep, which differentiates it from clk_unprepare.  In
  * a simple case, clk_disable can be used instead of clk_unprepare to gate a
@@ -884,20 +934,16 @@ static void __clk_disable(struct clk *clk)
  * this reason that clk_unprepare and clk_disable are not mutually exclusive.
  * In fact clk_disable must be called before clk_unprepare.
  */
-void clk_disable(struct clk *clk)
+void clk_disable(struct clk *clk_user)
 {
-	unsigned long flags;
-
-	if (IS_ERR_OR_NULL(clk))
+	if (IS_ERR_OR_NULL(clk_user))
 		return;
 
-	flags = clk_enable_lock();
-	__clk_disable(clk);
-	clk_enable_unlock(flags);
+	clk_provider_disable(clk_to_clk_core(clk_user));
 }
 EXPORT_SYMBOL_GPL(clk_disable);
 
-static int __clk_enable(struct clk *clk)
+static int __clk_enable(struct clk_core *clk)
 {
 	int ret = 0;
 
@@ -926,9 +972,22 @@ static int __clk_enable(struct clk *clk)
 	return 0;
 }
 
+int clk_provider_enable(struct clk_core *clk)
+{
+	unsigned long flags;
+	int ret;
+
+	flags = clk_enable_lock();
+	ret = __clk_enable(clk);
+	clk_enable_unlock(flags);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(clk_provider_enable);
+
 /**
  * clk_enable - ungate a clock
- * @clk: the clk being ungated
+ * @clk_user: the clk being ungated
  *
  * clk_enable must not sleep, which differentiates it from clk_prepare.  In a
  * simple case, clk_enable can be used instead of clk_prepare to ungate a clk
@@ -939,16 +998,12 @@ static int __clk_enable(struct clk *clk)
  * must be called before clk_enable.  Returns 0 on success, -EERROR
  * otherwise.
  */
-int clk_enable(struct clk *clk)
+int clk_enable(struct clk *clk_user)
 {
-	unsigned long flags;
-	int ret;
-
-	flags = clk_enable_lock();
-	ret = __clk_enable(clk);
-	clk_enable_unlock(flags);
+	if (!clk_user)
+		return 0;
 
-	return ret;
+	return clk_provider_enable(clk_to_clk_core(clk_user));
 }
 EXPORT_SYMBOL_GPL(clk_enable);
 
@@ -959,10 +1014,10 @@ EXPORT_SYMBOL_GPL(clk_enable);
  *
  * Caller must hold prepare_lock.  Useful for clk_ops such as .set_rate
  */
-unsigned long __clk_round_rate(struct clk *clk, unsigned long rate)
+unsigned long __clk_round_rate(struct clk_core *clk, unsigned long rate)
 {
 	unsigned long parent_rate = 0;
-	struct clk *parent;
+	struct clk_core *parent;
 
 	if (!clk)
 		return 0;
@@ -983,42 +1038,51 @@ unsigned long __clk_round_rate(struct clk *clk, unsigned long rate)
 }
 EXPORT_SYMBOL_GPL(__clk_round_rate);
 
+long clk_provider_round_rate(struct clk_core *clk, unsigned long rate)
+{
+	unsigned long ret;
+
+	clk_prepare_lock();
+	ret = __clk_round_rate(clk, rate);
+	clk_prepare_unlock();
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(clk_provider_round_rate);
+
 /**
  * clk_round_rate - round the given rate for a clk
- * @clk: the clk for which we are rounding a rate
+ * @clk_user: the clk for which we are rounding a rate
  * @rate: the rate which is to be rounded
  *
  * Takes in a rate as input and rounds it to a rate that the clk can actually
  * use which is then returned.  If clk doesn't support round_rate operation
  * then the parent rate is returned.
  */
-long clk_round_rate(struct clk *clk, unsigned long rate)
+long clk_round_rate(struct clk *clk_user, unsigned long rate)
 {
-	unsigned long ret;
-
-	clk_prepare_lock();
-	ret = __clk_round_rate(clk, rate);
-	clk_prepare_unlock();
+	if (!clk_user)
+		return 0;
 
-	return ret;
+	return clk_provider_round_rate(clk_to_clk_core(clk_user), rate);
 }
 EXPORT_SYMBOL_GPL(clk_round_rate);
 
 /**
  * __clk_notify - call clk notifier chain
- * @clk: struct clk * that is changing rate
+ * @clk: struct clk_core * that is changing rate
  * @msg: clk notifier type (see include/linux/clk.h)
  * @old_rate: old clk rate
  * @new_rate: new clk rate
  *
  * Triggers a notifier call chain on the clk rate-change notification
- * for 'clk'.  Passes a pointer to the struct clk and the previous
+ * for 'clk'.  Passes a pointer to the struct clk_core and the previous
  * and current rates to the notifier callback.  Intended to be called by
  * internal clock code only.  Returns NOTIFY_DONE from the last driver
  * called if all went well, or NOTIFY_STOP or NOTIFY_BAD immediately if
  * a driver returns that.
  */
-static int __clk_notify(struct clk *clk, unsigned long msg,
+static int __clk_notify(struct clk_core *clk, unsigned long msg,
 		unsigned long old_rate, unsigned long new_rate)
 {
 	struct clk_notifier *cn;
@@ -1051,10 +1115,10 @@ static int __clk_notify(struct clk *clk, unsigned long msg,
  *
  * Caller must hold prepare_lock.
  */
-static void __clk_recalc_accuracies(struct clk *clk)
+static void __clk_recalc_accuracies(struct clk_core *clk)
 {
 	unsigned long parent_accuracy = 0;
-	struct clk *child;
+	struct clk_core *child;
 
 	if (clk->parent)
 		parent_accuracy = clk->parent->accuracy;
@@ -1069,16 +1133,7 @@ static void __clk_recalc_accuracies(struct clk *clk)
 		__clk_recalc_accuracies(child);
 }
 
-/**
- * clk_get_accuracy - return the accuracy of clk
- * @clk: the clk whose accuracy is being returned
- *
- * Simply returns the cached accuracy of the clk, unless
- * CLK_GET_ACCURACY_NOCACHE flag is set, which means a recalc_rate will be
- * issued.
- * If clk is NULL then returns 0.
- */
-long clk_get_accuracy(struct clk *clk)
+static long __clk_get_accuracy_internal(struct clk_core *clk)
 {
 	unsigned long accuracy;
 
@@ -1091,9 +1146,23 @@ long clk_get_accuracy(struct clk *clk)
 
 	return accuracy;
 }
+
+/**
+ * clk_get_accuracy - return the accuracy of clk
+ * @clk_user: the clk whose accuracy is being returned
+ *
+ * Simply returns the cached accuracy of the clk, unless
+ * CLK_GET_ACCURACY_NOCACHE flag is set, which means a recalc_rate will be
+ * issued.
+ * If clk is NULL then returns 0.
+ */
+long clk_get_accuracy(struct clk *clk_user)
+{
+	return __clk_get_accuracy_internal(clk_to_clk_core(clk_user));
+}
 EXPORT_SYMBOL_GPL(clk_get_accuracy);
 
-static unsigned long clk_recalc(struct clk *clk, unsigned long parent_rate)
+static unsigned long clk_recalc(struct clk_core *clk, unsigned long parent_rate)
 {
 	if (clk->ops->recalc_rate)
 		return clk->ops->recalc_rate(clk->hw, parent_rate);
@@ -1114,11 +1183,11 @@ static unsigned long clk_recalc(struct clk *clk, unsigned long parent_rate)
  *
  * Caller must hold prepare_lock.
  */
-static void __clk_recalc_rates(struct clk *clk, unsigned long msg)
+static void __clk_recalc_rates(struct clk_core *clk, unsigned long msg)
 {
 	unsigned long old_rate;
 	unsigned long parent_rate = 0;
-	struct clk *child;
+	struct clk_core *child;
 
 	old_rate = clk->rate;
 
@@ -1138,15 +1207,7 @@ static void __clk_recalc_rates(struct clk *clk, unsigned long msg)
 		__clk_recalc_rates(child, msg);
 }
 
-/**
- * clk_get_rate - return the rate of clk
- * @clk: the clk whose rate is being returned
- *
- * Simply returns the cached rate of the clk, unless CLK_GET_RATE_NOCACHE flag
- * is set, which means a recalc_rate will be issued.
- * If clk is NULL then returns 0.
- */
-unsigned long clk_get_rate(struct clk *clk)
+unsigned long clk_provider_get_rate(struct clk_core *clk)
 {
 	unsigned long rate;
 
@@ -1160,15 +1221,32 @@ unsigned long clk_get_rate(struct clk *clk)
 
 	return rate;
 }
+EXPORT_SYMBOL_GPL(clk_provider_get_rate);
+
+/**
+ * clk_get_rate - return the rate of clk
+ * @clk_user: the clk whose rate is being returned
+ *
+ * Simply returns the cached rate of the clk, unless CLK_GET_RATE_NOCACHE flag
+ * is set, which means a recalc_rate will be issued.
+ * If clk is NULL then returns 0.
+ */
+unsigned long clk_get_rate(struct clk *clk_user)
+{
+	if (!clk_user)
+		return 0;
+
+	return clk_provider_get_rate(clk_to_clk_core(clk_user));
+}
 EXPORT_SYMBOL_GPL(clk_get_rate);
 
-static int clk_fetch_parent_index(struct clk *clk, struct clk *parent)
+static int clk_fetch_parent_index(struct clk_core *clk, struct clk_core *parent)
 {
 	int i;
 
 	if (!clk->parents) {
 		clk->parents = kcalloc(clk->num_parents,
-					sizeof(struct clk *), GFP_KERNEL);
+					sizeof(struct clk_core *), GFP_KERNEL);
 		if (!clk->parents)
 			return -ENOMEM;
 	}
@@ -1194,7 +1272,7 @@ static int clk_fetch_parent_index(struct clk *clk, struct clk *parent)
 	return -EINVAL;
 }
 
-static void clk_reparent(struct clk *clk, struct clk *new_parent)
+static void clk_reparent(struct clk_core *clk, struct clk_core *new_parent)
 {
 	hlist_del(&clk->child_node);
 
@@ -1211,10 +1289,10 @@ static void clk_reparent(struct clk *clk, struct clk *new_parent)
 	clk->parent = new_parent;
 }
 
-static struct clk *__clk_set_parent_before(struct clk *clk, struct clk *parent)
+static struct clk_core *__clk_set_parent_before(struct clk_core *clk, struct clk_core *parent)
 {
 	unsigned long flags;
-	struct clk *old_parent = clk->parent;
+	struct clk_core *old_parent = clk->parent;
 
 	/*
 	 * Migrate prepare state between parents and prevent race with
@@ -1235,8 +1313,8 @@ static struct clk *__clk_set_parent_before(struct clk *clk, struct clk *parent)
 	 */
 	if (clk->prepare_count) {
 		__clk_prepare(parent);
-		clk_enable(parent);
-		clk_enable(clk);
+		clk_provider_enable(parent);
+		clk_provider_enable(clk);
 	}
 
 	/* update the clk tree topology */
@@ -1247,25 +1325,25 @@ static struct clk *__clk_set_parent_before(struct clk *clk, struct clk *parent)
 	return old_parent;
 }
 
-static void __clk_set_parent_after(struct clk *clk, struct clk *parent,
-		struct clk *old_parent)
+static void __clk_set_parent_after(struct clk_core *clk, struct clk_core *parent,
+		struct clk_core *old_parent)
 {
 	/*
 	 * Finish the migration of prepare state and undo the changes done
 	 * for preventing a race with clk_enable().
 	 */
 	if (clk->prepare_count) {
-		clk_disable(clk);
-		clk_disable(old_parent);
+		clk_provider_disable(clk);
+		clk_provider_disable(old_parent);
 		__clk_unprepare(old_parent);
 	}
 }
 
-static int __clk_set_parent(struct clk *clk, struct clk *parent, u8 p_index)
+static int __clk_set_parent(struct clk_core *clk, struct clk_core *parent, u8 p_index)
 {
 	unsigned long flags;
 	int ret = 0;
-	struct clk *old_parent;
+	struct clk_core *old_parent;
 
 	old_parent = __clk_set_parent_before(clk, parent);
 
@@ -1279,8 +1357,8 @@ static int __clk_set_parent(struct clk *clk, struct clk *parent, u8 p_index)
 		clk_enable_unlock(flags);
 
 		if (clk->prepare_count) {
-			clk_disable(clk);
-			clk_disable(parent);
+			clk_provider_disable(clk);
+			clk_provider_disable(parent);
 			__clk_unprepare(parent);
 		}
 		return ret;
@@ -1307,9 +1385,9 @@ static int __clk_set_parent(struct clk *clk, struct clk *parent, u8 p_index)
  *
  * Caller must hold prepare_lock.
  */
-static int __clk_speculate_rates(struct clk *clk, unsigned long parent_rate)
+static int __clk_speculate_rates(struct clk_core *clk, unsigned long parent_rate)
 {
-	struct clk *child;
+	struct clk_core *child;
 	unsigned long new_rate;
 	int ret = NOTIFY_DONE;
 
@@ -1335,10 +1413,10 @@ out:
 	return ret;
 }
 
-static void clk_calc_subtree(struct clk *clk, unsigned long new_rate,
-			     struct clk *new_parent, u8 p_index)
+static void clk_calc_subtree(struct clk_core *clk, unsigned long new_rate,
+			     struct clk_core *new_parent, u8 p_index)
 {
-	struct clk *child;
+	struct clk_core *child;
 
 	clk->new_rate = new_rate;
 	clk->new_parent = new_parent;
@@ -1358,10 +1436,10 @@ static void clk_calc_subtree(struct clk *clk, unsigned long new_rate,
  * calculate the new rates returning the topmost clock that has to be
  * changed.
  */
-static struct clk *clk_calc_new_rates(struct clk *clk, unsigned long rate)
+static struct clk_core *clk_calc_new_rates(struct clk_core *clk, unsigned long rate)
 {
-	struct clk *top = clk;
-	struct clk *old_parent, *parent;
+	struct clk_core *top = clk;
+	struct clk_core *old_parent, *parent;
 	unsigned long best_parent_rate = 0;
 	unsigned long new_rate;
 	int p_index = 0;
@@ -1427,9 +1505,9 @@ out:
  * so that in case of an error we can walk down the whole tree again and
  * abort the change.
  */
-static struct clk *clk_propagate_rate_change(struct clk *clk, unsigned long event)
+static struct clk_core *clk_propagate_rate_change(struct clk_core *clk, unsigned long event)
 {
-	struct clk *child, *tmp_clk, *fail_clk = NULL;
+	struct clk_core *child, *tmp_clk, *fail_clk = NULL;
 	int ret = NOTIFY_DONE;
 
 	if (clk->rate == clk->new_rate)
@@ -1464,13 +1542,13 @@ static struct clk *clk_propagate_rate_change(struct clk *clk, unsigned long even
  * walk down a subtree and set the new rates notifying the rate
  * change on the way
  */
-static void clk_change_rate(struct clk *clk)
+static void clk_change_rate(struct clk_core *clk)
 {
-	struct clk *child;
+	struct clk_core *child;
 	unsigned long old_rate;
 	unsigned long best_parent_rate = 0;
 	bool skip_set_rate = false;
-	struct clk *old_parent;
+	struct clk_core *old_parent;
 
 	old_rate = clk->rate;
 
@@ -1514,30 +1592,9 @@ static void clk_change_rate(struct clk *clk)
 		clk_change_rate(clk->new_child);
 }
 
-/**
- * clk_set_rate - specify a new rate for clk
- * @clk: the clk whose rate is being changed
- * @rate: the new rate for clk
- *
- * In the simplest case clk_set_rate will only adjust the rate of clk.
- *
- * Setting the CLK_SET_RATE_PARENT flag allows the rate change operation to
- * propagate up to clk's parent; whether or not this happens depends on the
- * outcome of clk's .round_rate implementation.  If *parent_rate is unchanged
- * after calling .round_rate then upstream parent propagation is ignored.  If
- * *parent_rate comes back with a new rate for clk's parent then we propagate
- * up to clk's parent and set its rate.  Upward propagation will continue
- * until either a clk does not support the CLK_SET_RATE_PARENT flag or
- * .round_rate stops requesting changes to clk's parent_rate.
- *
- * Rate changes are accomplished via tree traversal that also recalculates the
- * rates for the clocks and fires off POST_RATE_CHANGE notifiers.
- *
- * Returns 0 on success, -EERROR otherwise.
- */
-int clk_set_rate(struct clk *clk, unsigned long rate)
+int clk_provider_set_rate(struct clk_core *clk, unsigned long rate)
 {
-	struct clk *top, *fail_clk;
+	struct clk_core *top, *fail_clk;
 	int ret = 0;
 
 	if (!clk)
@@ -1547,7 +1604,7 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
 	clk_prepare_lock();
 
 	/* bail early if nothing to do */
-	if (rate == clk_get_rate(clk))
+	if (rate == clk_provider_get_rate(clk))
 		goto out;
 
 	if ((clk->flags & CLK_SET_RATE_GATE) && clk->prepare_count) {
@@ -1580,17 +1637,41 @@ out:
 
 	return ret;
 }
-EXPORT_SYMBOL_GPL(clk_set_rate);
+EXPORT_SYMBOL_GPL(clk_provider_set_rate);
 
 /**
- * clk_get_parent - return the parent of a clk
- * @clk: the clk whose parent gets returned
+ * clk_set_rate - specify a new rate for clk
+ * @clk_user: the clk whose rate is being changed
+ * @rate: the new rate for clk
  *
- * Simply returns clk->parent.  Returns NULL if clk is NULL.
+ * In the simplest case clk_set_rate will only adjust the rate of clk.
+ *
+ * Setting the CLK_SET_RATE_PARENT flag allows the rate change operation to
+ * propagate up to clk's parent; whether or not this happens depends on the
+ * outcome of clk's .round_rate implementation.  If *parent_rate is unchanged
+ * after calling .round_rate then upstream parent propagation is ignored.  If
+ * *parent_rate comes back with a new rate for clk's parent then we propagate
+ * up to clk's parent and set its rate.  Upward propagation will continue
+ * until either a clk does not support the CLK_SET_RATE_PARENT flag or
+ * .round_rate stops requesting changes to clk's parent_rate.
+ *
+ * Rate changes are accomplished via tree traversal that also recalculates the
+ * rates for the clocks and fires off POST_RATE_CHANGE notifiers.
+ *
+ * Returns 0 on success, -EERROR otherwise.
  */
-struct clk *clk_get_parent(struct clk *clk)
+int clk_set_rate(struct clk *clk_user, unsigned long rate)
 {
-	struct clk *parent;
+	if (!clk_user)
+		return 0;
+
+	return clk_provider_set_rate(clk_to_clk_core(clk_user), rate);
+}
+EXPORT_SYMBOL_GPL(clk_set_rate);
+
+struct clk_core *clk_provider_get_parent(struct clk_core *clk)
+{
+	struct clk_core *parent;
 
 	clk_prepare_lock();
 	parent = __clk_get_parent(clk);
@@ -1598,8 +1679,35 @@ struct clk *clk_get_parent(struct clk *clk)
 
 	return parent;
 }
+EXPORT_SYMBOL_GPL(clk_provider_get_parent);
+
+/**
+ * clk_get_parent - return the parent of a clk
+ * @clk_user: the clk whose parent gets returned
+ *
+ * Simply returns clk->parent.  Returns NULL if clk is NULL.
+ */
+struct clk *clk_get_parent(struct clk *clk_user)
+{
+	struct clk_core *clk;
+	struct clk_core *parent;
+
+	if (!clk_user)
+		return NULL;
+
+	clk = clk_to_clk_core(clk_user);
+	parent = clk_provider_get_parent(clk);
+
+	return __clk_create_clk(parent);
+}
 EXPORT_SYMBOL_GPL(clk_get_parent);
 
+const char *clk_get_name(struct clk *clk_user)
+{
+	return __clk_get_name(clk_to_clk_core(clk_user));
+}
+EXPORT_SYMBOL_GPL(clk_get_name);
+
 /*
  * .get_parent is mandatory for clocks with multiple possible parents.  It is
  * optional for single-parent clocks.  Always call .get_parent if it is
@@ -1609,9 +1717,9 @@ EXPORT_SYMBOL_GPL(clk_get_parent);
  * .parents array exists, and if so use it to avoid an expensive tree
  * traversal.  If .parents does not exist then walk the tree with __clk_lookup.
  */
-static struct clk *__clk_init_parent(struct clk *clk)
+static struct clk_core *__clk_init_parent(struct clk_core *clk)
 {
-	struct clk *ret = NULL;
+	struct clk_core *ret = NULL;
 	u8 index;
 
 	/* handle the trivial cases */
@@ -1643,7 +1751,7 @@ static struct clk *__clk_init_parent(struct clk *clk)
 
 	if (!clk->parents)
 		clk->parents =
-			kcalloc(clk->num_parents, sizeof(struct clk *),
+			kcalloc(clk->num_parents, sizeof(struct clk_core *),
 					GFP_KERNEL);
 
 	ret = clk_get_parent_by_index(clk, index);
@@ -1652,31 +1760,14 @@ out:
 	return ret;
 }
 
-void __clk_reparent(struct clk *clk, struct clk *new_parent)
+void __clk_reparent(struct clk_core *clk, struct clk_core *new_parent)
 {
 	clk_reparent(clk, new_parent);
 	__clk_recalc_accuracies(clk);
 	__clk_recalc_rates(clk, POST_RATE_CHANGE);
 }
 
-/**
- * clk_set_parent - switch the parent of a mux clk
- * @clk: the mux clk whose input we are switching
- * @parent: the new input to clk
- *
- * Re-parent clk to use parent as its new input source.  If clk is in
- * prepared state, the clk will get enabled for the duration of this call. If
- * that's not acceptable for a specific clk (Eg: the consumer can't handle
- * that, the reparenting is glitchy in hardware, etc), use the
- * CLK_SET_PARENT_GATE flag to allow reparenting only when clk is unprepared.
- *
- * After successfully changing clk's parent clk_set_parent will update the
- * clk topology, sysfs topology and propagate rate recalculation via
- * __clk_recalc_rates.
- *
- * Returns 0 on success, -EERROR otherwise.
- */
-int clk_set_parent(struct clk *clk, struct clk *parent)
+int clk_provider_set_parent(struct clk_core *clk, struct clk_core *parent)
 {
 	int ret = 0;
 	int p_index = 0;
@@ -1736,6 +1827,38 @@ out:
 
 	return ret;
 }
+EXPORT_SYMBOL_GPL(clk_provider_set_parent);
+
+/**
+ * clk_set_parent - switch the parent of a mux clk
+ * @clk_user: the mux clk whose input we are switching
+ * @parent_user: the new input to clk
+ *
+ * Re-parent clk to use parent as its new input source.  If clk is in
+ * prepared state, the clk will get enabled for the duration of this call. If
+ * that's not acceptable for a specific clk (Eg: the consumer can't handle
+ * that, the reparenting is glitchy in hardware, etc), use the
+ * CLK_SET_PARENT_GATE flag to allow reparenting only when clk is unprepared.
+ *
+ * After successfully changing clk's parent clk_set_parent will update the
+ * clk topology, sysfs topology and propagate rate recalculation via
+ * __clk_recalc_rates.
+ *
+ * Returns 0 on success, -EERROR otherwise.
+ */
+int clk_set_parent(struct clk *clk_user, struct clk *parent_user)
+{
+	struct clk_core *clk;
+	struct clk_core *parent;
+
+	if (!clk_user)
+		return 0;
+
+	clk = clk_to_clk_core(clk_user);
+	parent = clk_to_clk_core(parent_user);
+
+	return clk_provider_set_parent(clk, parent);
+}
 EXPORT_SYMBOL_GPL(clk_set_parent);
 
 /**
@@ -1746,10 +1869,10 @@ EXPORT_SYMBOL_GPL(clk_set_parent);
  * Initializes the lists in struct clk, queries the hardware for the
  * parent and rate and sets them both.
  */
-int __clk_init(struct device *dev, struct clk *clk)
+int __clk_init(struct device *dev, struct clk_core *clk)
 {
 	int i, ret = 0;
-	struct clk *orphan;
+	struct clk_core *orphan;
 	struct hlist_node *tmp2;
 
 	if (!clk)
@@ -1797,7 +1920,7 @@ int __clk_init(struct device *dev, struct clk *clk)
 				__func__, clk->name);
 
 	/*
-	 * Allocate an array of struct clk *'s to avoid unnecessary string
+	 * Allocate an array of struct clk_core *'s to avoid unnecessary string
 	 * look-ups of clk's possible parents.  This can fail for clocks passed
 	 * in to clk_init during early boot; thus any access to clk->parents[]
 	 * must always check for a NULL pointer and try to populate it if
@@ -1807,7 +1930,7 @@ int __clk_init(struct device *dev, struct clk *clk)
 	 * for clock drivers to statically initialize clk->parents.
 	 */
 	if (clk->num_parents > 1 && !clk->parents) {
-		clk->parents = kcalloc(clk->num_parents, sizeof(struct clk *),
+		clk->parents = kcalloc(clk->num_parents, sizeof(struct clk_core *),
 					GFP_KERNEL);
 		/*
 		 * __clk_lookup returns NULL for parents that have not been
@@ -1913,7 +2036,7 @@ out:
  *
  * Same as clk_register, except that the .clk field inside hw shall point to a
  * preallocated (generally statically allocated) struct clk. None of the fields
- * of the struct clk need to be initialized.
+ * of the struct clk_core need to be initialized.
  *
  * The data pointed to by .init and .clk field shall NOT be marked as init
  * data.
@@ -1925,10 +2048,10 @@ out:
  * separate C file from the logic that implements its operations.  Returns 0
  * on success, otherwise an error code.
  */
-struct clk *__clk_register(struct device *dev, struct clk_hw *hw)
+struct clk_core *__clk_register(struct device *dev, struct clk_hw *hw)
 {
 	int ret;
-	struct clk *clk;
+	struct clk_core *clk;
 
 	clk = hw->clk;
 	clk->name = hw->init->name;
@@ -1956,15 +2079,15 @@ EXPORT_SYMBOL_GPL(__clk_register);
  * @hw: link to hardware-specific clock data
  *
  * clk_register is the primary interface for populating the clock tree with new
- * clock nodes.  It returns a pointer to the newly allocated struct clk which
+ * clock nodes.  It returns a pointer to the newly allocated struct clk_core which
  * cannot be dereferenced by driver code but may be used in conjuction with the
  * rest of the clock API.  In the event of an error clk_register will return an
  * error code; drivers must test for an error code after calling clk_register.
  */
-struct clk *clk_register(struct device *dev, struct clk_hw *hw)
+struct clk_core *clk_register(struct device *dev, struct clk_hw *hw)
 {
 	int i, ret;
-	struct clk *clk;
+	struct clk_core *clk;
 
 	clk = kzalloc(sizeof(*clk), GFP_KERNEL);
 	if (!clk) {
@@ -2032,7 +2155,7 @@ EXPORT_SYMBOL_GPL(clk_register);
  */
 static void __clk_release(struct kref *ref)
 {
-	struct clk *clk = container_of(ref, struct clk, ref);
+	struct clk_core *clk = container_of(ref, struct clk_core, ref);
 	int i = clk->num_parents;
 
 	kfree(clk->parents);
@@ -2083,7 +2206,7 @@ static const struct clk_ops clk_nodrv_ops = {
  * clk_unregister - unregister a currently registered clock
  * @clk: clock to unregister
  */
-void clk_unregister(struct clk *clk)
+void clk_unregister(struct clk_core *clk)
 {
 	unsigned long flags;
 
@@ -2105,12 +2228,12 @@ void clk_unregister(struct clk *clk)
 	clk_enable_unlock(flags);
 
 	if (!hlist_empty(&clk->children)) {
-		struct clk *child;
+		struct clk_core *child;
 		struct hlist_node *t;
 
 		/* Reparent all children to the orphan list. */
 		hlist_for_each_entry_safe(child, t, &clk->children, child_node)
-			clk_set_parent(child, NULL);
+			clk_provider_set_parent(child, NULL);
 	}
 
 	clk_debug_unregister(clk);
@@ -2129,9 +2252,15 @@ EXPORT_SYMBOL_GPL(clk_unregister);
 
 static void devm_clk_release(struct device *dev, void *res)
 {
-	clk_unregister(*(struct clk **)res);
+	clk_unregister(*(struct clk_core **)res);
 }
 
+struct clk_core *clk_to_clk_core(struct clk *clk)
+{
+	return clk->core;
+}
+EXPORT_SYMBOL_GPL(clk_to_clk_core);
+
 /**
  * devm_clk_register - resource managed clk_register()
  * @dev: device that is registering this clock
@@ -2141,10 +2270,10 @@ static void devm_clk_release(struct device *dev, void *res)
  * automatically clk_unregister()ed on driver detach. See clk_register() for
  * more information.
  */
-struct clk *devm_clk_register(struct device *dev, struct clk_hw *hw)
+struct clk_core *devm_clk_register(struct device *dev, struct clk_hw *hw)
 {
-	struct clk *clk;
-	struct clk **clkp;
+	struct clk_core *clk;
+	struct clk_core **clkp;
 
 	clkp = devres_alloc(devm_clk_release, sizeof(*clkp), GFP_KERNEL);
 	if (!clkp)
@@ -2164,7 +2293,7 @@ EXPORT_SYMBOL_GPL(devm_clk_register);
 
 static int devm_clk_match(struct device *dev, void *res, void *data)
 {
-	struct clk *c = res;
+	struct clk_core *c = res;
 	if (WARN_ON(!c))
 		return 0;
 	return c == data;
@@ -2178,7 +2307,7 @@ static int devm_clk_match(struct device *dev, void *res, void *data)
  * this function will not need to be called and the resource management
  * code will ensure that the resource is freed.
  */
-void devm_clk_unregister(struct device *dev, struct clk *clk)
+void devm_clk_unregister(struct device *dev, struct clk_core *clk)
 {
 	WARN_ON(devres_release(dev, devm_clk_release, devm_clk_match, clk));
 }
@@ -2187,7 +2316,7 @@ EXPORT_SYMBOL_GPL(devm_clk_unregister);
 /*
  * clkdev helpers
  */
-int __clk_get(struct clk *clk)
+int __clk_get(struct clk_core *clk)
 {
 	if (clk) {
 		if (!try_module_get(clk->owner))
@@ -2198,7 +2327,7 @@ int __clk_get(struct clk *clk)
 	return 1;
 }
 
-void __clk_put(struct clk *clk)
+void __clk_put(struct clk_core *clk)
 {
 	if (!clk || WARN_ON_ONCE(IS_ERR(clk)))
 		return;
@@ -2212,28 +2341,7 @@ void __clk_put(struct clk *clk)
 
 /***        clk rate change notifiers        ***/
 
-/**
- * clk_notifier_register - add a clk rate change notifier
- * @clk: struct clk * to watch
- * @nb: struct notifier_block * with callback info
- *
- * Request notification when clk's rate changes.  This uses an SRCU
- * notifier because we want it to block and notifier unregistrations are
- * uncommon.  The callbacks associated with the notifier must not
- * re-enter into the clk framework by calling any top-level clk APIs;
- * this will cause a nested prepare_lock mutex.
- *
- * In all notification cases cases (pre, post and abort rate change) the
- * original clock rate is passed to the callback via struct
- * clk_notifier_data.old_rate and the new frequency is passed via struct
- * clk_notifier_data.new_rate.
- *
- * clk_notifier_register() must be called from non-atomic context.
- * Returns -EINVAL if called with null arguments, -ENOMEM upon
- * allocation failure; otherwise, passes along the return value of
- * srcu_notifier_chain_register().
- */
-int clk_notifier_register(struct clk *clk, struct notifier_block *nb)
+int clk_provider_notifier_register(struct clk_core *clk, struct notifier_block *nb)
 {
 	struct clk_notifier *cn;
 	int ret = -ENOMEM;
@@ -2269,20 +2377,38 @@ out:
 
 	return ret;
 }
-EXPORT_SYMBOL_GPL(clk_notifier_register);
+EXPORT_SYMBOL_GPL(clk_provider_notifier_register);
 
 /**
- * clk_notifier_unregister - remove a clk rate change notifier
- * @clk: struct clk *
+ * clk_notifier_register - add a clk rate change notifier
+ * @clk_user: struct clk * to watch
  * @nb: struct notifier_block * with callback info
  *
- * Request no further notification for changes to 'clk' and frees memory
- * allocated in clk_notifier_register.
+ * Request notification when clk's rate changes.  This uses an SRCU
+ * notifier because we want it to block and notifier unregistrations are
+ * uncommon.  The callbacks associated with the notifier must not
+ * re-enter into the clk framework by calling any top-level clk APIs;
+ * this will cause a nested prepare_lock mutex.
  *
- * Returns -EINVAL if called with null arguments; otherwise, passes
- * along the return value of srcu_notifier_chain_unregister().
+ * In all notification cases cases (pre, post and abort rate change) the
+ * original clock rate is passed to the callback via struct
+ * clk_notifier_data.old_rate and the new frequency is passed via struct
+ * clk_notifier_data.new_rate.
+ *
+ * clk_notifier_register() must be called from non-atomic context.
+ * Returns -EINVAL if called with null arguments, -ENOMEM upon
+ * allocation failure; otherwise, passes along the return value of
+ * srcu_notifier_chain_register().
  */
-int clk_notifier_unregister(struct clk *clk, struct notifier_block *nb)
+int clk_notifier_register(struct clk *clk_user, struct notifier_block *nb)
+{
+	struct clk_core *clk = clk_to_clk_core(clk_user);
+
+	return clk_provider_notifier_register(clk, nb);
+}
+EXPORT_SYMBOL_GPL(clk_notifier_register);
+
+int clk_provider_notifier_unregister(struct clk_core *clk, struct notifier_block *nb)
 {
 	struct clk_notifier *cn = NULL;
 	int ret = -EINVAL;
@@ -2316,6 +2442,25 @@ int clk_notifier_unregister(struct clk *clk, struct notifier_block *nb)
 
 	return ret;
 }
+EXPORT_SYMBOL_GPL(clk_provider_notifier_unregister);
+
+/**
+ * clk_notifier_unregister - remove a clk rate change notifier
+ * @clk_user: struct clk_core *
+ * @nb: struct notifier_block * with callback info
+ *
+ * Request no further notification for changes to 'clk' and frees memory
+ * allocated in clk_notifier_register.
+ *
+ * Returns -EINVAL if called with null arguments; otherwise, passes
+ * along the return value of srcu_notifier_chain_unregister().
+ */
+int clk_notifier_unregister(struct clk *clk_user, struct notifier_block *nb)
+{
+	struct clk_core *clk = clk_to_clk_core(clk_user);
+
+	return clk_provider_notifier_unregister(clk, nb);
+}
 EXPORT_SYMBOL_GPL(clk_notifier_unregister);
 
 #ifdef CONFIG_OF
@@ -2323,7 +2468,7 @@ EXPORT_SYMBOL_GPL(clk_notifier_unregister);
  * struct of_clk_provider - Clock provider registration structure
  * @link: Entry in global list of clock providers
  * @node: Pointer to device tree node of clock provider
- * @get: Get clock callback.  Returns NULL or a struct clk for the
+ * @get: Get clock callback.  Returns NULL or a struct clk_core for the
  *       given clock specifier
  * @data: context pointer to be passed into @get callback
  */
@@ -2331,7 +2476,7 @@ struct of_clk_provider {
 	struct list_head link;
 
 	struct device_node *node;
-	struct clk *(*get)(struct of_phandle_args *clkspec, void *data);
+	struct clk_core *(*get)(struct of_phandle_args *clkspec, void *data);
 	void *data;
 };
 
@@ -2352,14 +2497,14 @@ void of_clk_unlock(void)
 	mutex_unlock(&of_clk_mutex);
 }
 
-struct clk *of_clk_src_simple_get(struct of_phandle_args *clkspec,
+struct clk_core *of_clk_src_simple_get(struct of_phandle_args *clkspec,
 				     void *data)
 {
 	return data;
 }
 EXPORT_SYMBOL_GPL(of_clk_src_simple_get);
 
-struct clk *of_clk_src_onecell_get(struct of_phandle_args *clkspec, void *data)
+struct clk_core *of_clk_src_onecell_get(struct of_phandle_args *clkspec, void *data)
 {
 	struct clk_onecell_data *clk_data = data;
 	unsigned int idx = clkspec->args[0];
@@ -2380,7 +2525,7 @@ EXPORT_SYMBOL_GPL(of_clk_src_onecell_get);
  * @data: context pointer for @clk_src_get callback.
  */
 int of_clk_add_provider(struct device_node *np,
-			struct clk *(*clk_src_get)(struct of_phandle_args *clkspec,
+			struct clk_core *(*clk_src_get)(struct of_phandle_args *clkspec,
 						   void *data),
 			void *data)
 {
@@ -2429,10 +2574,10 @@ void of_clk_del_provider(struct device_node *np)
 }
 EXPORT_SYMBOL_GPL(of_clk_del_provider);
 
-struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec)
+struct clk_core *__of_clk_get_from_provider(struct of_phandle_args *clkspec)
 {
 	struct of_clk_provider *provider;
-	struct clk *clk = ERR_PTR(-EPROBE_DEFER);
+	struct clk_core *clk = ERR_PTR(-EPROBE_DEFER);
 
 	/* Check if we have such a provider in our array */
 	list_for_each_entry(provider, &of_clk_providers, link) {
@@ -2445,9 +2590,9 @@ struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec)
 	return clk;
 }
 
-struct clk *of_clk_get_from_provider(struct of_phandle_args *clkspec)
+struct clk_core *of_clk_get_from_provider(struct of_phandle_args *clkspec)
 {
-	struct clk *clk;
+	struct clk_core *clk;
 
 	mutex_lock(&of_clk_mutex);
 	clk = __of_clk_get_from_provider(clkspec);
@@ -2522,11 +2667,11 @@ static int parent_ready(struct device_node *np)
 	int i = 0;
 
 	while (true) {
-		struct clk *clk = of_clk_get(np, i);
+		struct clk_core *clk = of_clk_provider_get(np, i);
 
 		/* this parent is ready we can check the next one */
 		if (!IS_ERR(clk)) {
-			clk_put(clk);
+			__clk_put(clk);
 			i++;
 			continue;
 		}
diff --git a/drivers/clk/clk.h b/drivers/clk/clk.h
index d278572..3b3068b 100644
--- a/drivers/clk/clk.h
+++ b/drivers/clk/clk.h
@@ -9,9 +9,15 @@
  * published by the Free Software Foundation.
  */
 
+#include <linux/clk-private.h>
+
 #if defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK)
 struct clk_core *of_clk_get_by_clkspec(struct of_phandle_args *clkspec);
 struct clk_core *__of_clk_get_from_provider(struct of_phandle_args *clkspec);
 void of_clk_lock(void);
 void of_clk_unlock(void);
 #endif
+
+#if defined(CONFIG_COMMON_CLK)
+struct clk *__clk_create_clk(struct clk_core *clk_core);
+#endif
diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c
index c751d0c..080b3df 100644
--- a/drivers/clk/clkdev.c
+++ b/drivers/clk/clkdev.c
@@ -18,6 +18,7 @@
 #include <linux/string.h>
 #include <linux/mutex.h>
 #include <linux/clk.h>
+#include <linux/clk-private.h>
 #include <linux/clk-provider.h>
 #include <linux/clkdev.h>
 #include <linux/of.h>
@@ -33,13 +34,13 @@ static DEFINE_MUTEX(clocks_mutex);
  * of_clk_get_by_clkspec() - Lookup a clock form a clock provider
  * @clkspec: pointer to a clock specifier data structure
  *
- * This function looks up a struct clk from the registered list of clock
+ * This function looks up a struct clk_core from the registered list of clock
  * providers, an input is a clock specifier data structure as returned
  * from the of_parse_phandle_with_args() function call.
  */
-struct clk *of_clk_get_by_clkspec(struct of_phandle_args *clkspec)
+struct clk_core *of_clk_get_by_clkspec(struct of_phandle_args *clkspec)
 {
-	struct clk *clk;
+	struct clk_core *clk;
 
 	if (!clkspec)
 		return ERR_PTR(-EINVAL);
@@ -54,10 +55,10 @@ struct clk *of_clk_get_by_clkspec(struct of_phandle_args *clkspec)
 	return clk;
 }
 
-struct clk *of_clk_get(struct device_node *np, int index)
+struct clk_core *of_clk_provider_get(struct device_node *np, int index)
 {
 	struct of_phandle_args clkspec;
-	struct clk *clk;
+	clk_core_t *clk;
 	int rc;
 
 	if (index < 0)
@@ -72,20 +73,16 @@ struct clk *of_clk_get(struct device_node *np, int index)
 	of_node_put(clkspec.np);
 	return clk;
 }
+
+struct clk *of_clk_get(struct device_node *np, int index)
+{
+	return __clk_create_clk(of_clk_provider_get(np, index));
+}
 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)
+struct clk_core *of_clk_provider_get_by_name(struct device_node *np, const char *name)
 {
-	struct clk *clk = ERR_PTR(-ENOENT);
+	struct clk_core *clk = ERR_PTR(-ENOENT);
 
 	/* Walk up the tree of devices looking for a clock that matches */
 	while (np) {
@@ -98,7 +95,7 @@ struct clk *of_clk_get_by_name(struct device_node *np, const char *name)
 		 */
 		if (name)
 			index = of_property_match_string(np, "clock-names", name);
-		clk = of_clk_get(np, index);
+		clk = of_clk_provider_get(np, index);
 		if (!IS_ERR(clk))
 			break;
 		else if (name && index >= 0) {
@@ -120,11 +117,25 @@ struct clk *of_clk_get_by_name(struct device_node *np, const char *name)
 
 	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 clock from the registered list of clock
+ * providers.
+ */
+struct clk *of_clk_get_by_name(struct device_node *np, const char *name)
+{
+	return __clk_create_clk(of_clk_provider_get_by_name(np, name));
+}
 EXPORT_SYMBOL(of_clk_get_by_name);
 #endif
 
 /*
- * Find the correct struct clk for the device and connection ID.
+ * Find the correct clock for the device and connection ID.
  * We do slightly fuzzy matching here:
  *  An entry with a NULL ID is assumed to be a wildcard.
  *  If an entry has a device ID, it must match
@@ -166,8 +177,32 @@ static struct clk_lookup *clk_find(const char *dev_id, const char *con_id)
 	return cl;
 }
 
+#if defined(CONFIG_COMMON_CLK)
+struct clk_core *clk_provider_get_sys(const char *dev_id, const char *con_id)
+{
+	struct clk_lookup *cl;
+
+	mutex_lock(&clocks_mutex);
+	cl = clk_find(dev_id, con_id);
+	if (cl && !__clk_get(cl->clk))
+		cl = NULL;
+	mutex_unlock(&clocks_mutex);
+
+	if (!cl)
+		return ERR_PTR(-ENOENT);
+
+	return cl->clk;
+}
+EXPORT_SYMBOL_GPL(clk_provider_get_sys);
+#endif
+
 struct clk *clk_get_sys(const char *dev_id, const char *con_id)
 {
+#if defined(CONFIG_COMMON_CLK)
+	struct clk_core *clk = clk_provider_get_sys(dev_id, con_id);
+
+	return __clk_create_clk(clk);
+#else
 	struct clk_lookup *cl;
 
 	mutex_lock(&clocks_mutex);
@@ -176,12 +211,38 @@ struct clk *clk_get_sys(const char *dev_id, const char *con_id)
 		cl = NULL;
 	mutex_unlock(&clocks_mutex);
 
-	return cl ? cl->clk : ERR_PTR(-ENOENT);
+	if (!cl)
+		return ERR_PTR(-ENOENT);
+
+	return cl->clk;
+#endif
 }
 EXPORT_SYMBOL(clk_get_sys);
 
+#if defined(CONFIG_COMMON_CLK)
+struct clk_core *clk_provider_get(struct device *dev, const char *con_id)
+{
+	const char *dev_id = dev ? dev_name(dev) : NULL;
+	struct clk_core *clk;
+
+	if (dev) {
+		clk = of_clk_provider_get_by_name(dev->of_node, con_id);
+		if (!IS_ERR(clk))
+			return clk;
+		if (PTR_ERR(clk) == -EPROBE_DEFER)
+			return clk;
+	}
+
+	return clk_provider_get_sys(dev_id, con_id);
+}
+EXPORT_SYMBOL(clk_provider_get);
+#endif
+
 struct clk *clk_get(struct device *dev, const char *con_id)
 {
+#if defined(CONFIG_COMMON_CLK)
+	return __clk_create_clk(clk_provider_get(dev, con_id));
+#else
 	const char *dev_id = dev ? dev_name(dev) : NULL;
 	struct clk *clk;
 
@@ -194,12 +255,20 @@ struct clk *clk_get(struct device *dev, const char *con_id)
 	}
 
 	return clk_get_sys(dev_id, con_id);
+#endif
 }
 EXPORT_SYMBOL(clk_get);
 
 void clk_put(struct clk *clk)
 {
+#if defined(CONFIG_COMMON_CLK)
+	clk_core_t *core = clk_to_clk_core(clk);
+
+	kfree(clk);
+	__clk_put(core);
+#else
 	__clk_put(clk);
+#endif
 }
 EXPORT_SYMBOL(clk_put);
 
@@ -231,7 +300,7 @@ struct clk_lookup_alloc {
 };
 
 static struct clk_lookup * __init_refok
-vclkdev_alloc(struct clk *clk, const char *con_id, const char *dev_fmt,
+vclkdev_alloc(clk_core_t *clk, const char *con_id, const char *dev_fmt,
 	va_list ap)
 {
 	struct clk_lookup_alloc *cla;
@@ -255,7 +324,7 @@ vclkdev_alloc(struct clk *clk, const char *con_id, const char *dev_fmt,
 }
 
 struct clk_lookup * __init_refok
-clkdev_alloc(struct clk *clk, const char *con_id, const char *dev_fmt, ...)
+clkdev_alloc(clk_core_t *clk, const char *con_id, const char *dev_fmt, ...)
 {
 	struct clk_lookup *cl;
 	va_list ap;
@@ -277,7 +346,11 @@ int clk_add_alias(const char *alias, const char *alias_dev_name, char *id,
 	if (IS_ERR(r))
 		return PTR_ERR(r);
 
+#ifdef CONFIG_COMMON_CLK
+	l = clkdev_alloc(clk_to_clk_core(r), alias, alias_dev_name);
+#else
 	l = clkdev_alloc(r, alias, alias_dev_name);
+#endif
 	clk_put(r);
 	if (!l)
 		return -ENODEV;
@@ -300,7 +373,7 @@ EXPORT_SYMBOL(clkdev_drop);
 
 /**
  * clk_register_clkdev - register one clock lookup for a struct clk
- * @clk: struct clk to associate with all clk_lookups
+ * @clk: clock to associate with all clk_lookups
  * @con_id: connection ID string on device
  * @dev_id: format string describing device name
  *
@@ -312,7 +385,7 @@ EXPORT_SYMBOL(clkdev_drop);
  * those.  This is to permit this function to be called immediately
  * after clk_register().
  */
-int clk_register_clkdev(struct clk *clk, const char *con_id,
+int clk_register_clkdev(clk_core_t *clk, const char *con_id,
 	const char *dev_fmt, ...)
 {
 	struct clk_lookup *cl;
@@ -335,7 +408,7 @@ int clk_register_clkdev(struct clk *clk, const char *con_id,
 
 /**
  * clk_register_clkdevs - register a set of clk_lookup for a struct clk
- * @clk: struct clk to associate with all clk_lookups
+ * @clk: clock to associate with all clk_lookups
  * @cl: array of clk_lookup structures with con_id and dev_id pre-initialized
  * @num: number of clk_lookup structures to register
  *
@@ -344,7 +417,7 @@ int clk_register_clkdev(struct clk *clk, const char *con_id,
  * those.  This is to permit this function to be called immediately
  * after clk_register().
  */
-int clk_register_clkdevs(struct clk *clk, struct clk_lookup *cl, size_t num)
+int clk_register_clkdevs(clk_core_t *clk, struct clk_lookup *cl, size_t num)
 {
 	unsigned i;
 
diff --git a/include/linux/clk-private.h b/include/linux/clk-private.h
index efbf70b..2c1ece9 100644
--- a/include/linux/clk-private.h
+++ b/include/linux/clk-private.h
@@ -28,20 +28,20 @@
 
 struct module;
 
-struct clk {
+struct clk_core {
 	const char		*name;
 	const struct clk_ops	*ops;
 	struct clk_hw		*hw;
 	struct module		*owner;
-	struct clk		*parent;
+	struct clk_core		*parent;
 	const char		**parent_names;
-	struct clk		**parents;
+	struct clk_core		**parents;
 	u8			num_parents;
 	u8			new_parent_index;
 	unsigned long		rate;
 	unsigned long		new_rate;
-	struct clk		*new_parent;
-	struct clk		*new_child;
+	struct clk_core		*new_parent;
+	struct clk_core		*new_child;
 	unsigned long		flags;
 	unsigned int		enable_count;
 	unsigned int		prepare_count;
@@ -55,6 +55,10 @@ struct clk {
 	struct kref		ref;
 };
 
+struct clk {
+	struct clk_core	*core;
+};
+
 /*
  * DOC: Basic clock implementations common to many platforms
  *
@@ -66,7 +70,7 @@ struct clk {
 
 #define DEFINE_CLK(_name, _ops, _flags, _parent_names,		\
 		_parents)					\
-	static struct clk _name = {				\
+	static struct clk_core _name = {				\
 		.name = #_name,					\
 		.ops = &_ops,					\
 		.hw = &_name##_hw.hw,				\
@@ -78,7 +82,7 @@ struct clk {
 
 #define DEFINE_CLK_FIXED_RATE(_name, _flags, _rate,		\
 				_fixed_rate_flags)		\
-	static struct clk _name;				\
+	static struct clk_core _name;				\
 	static const char *_name##_parent_names[] = {};		\
 	static struct clk_fixed_rate _name##_hw = {		\
 		.hw = {						\
@@ -93,11 +97,11 @@ struct clk {
 #define DEFINE_CLK_GATE(_name, _parent_name, _parent_ptr,	\
 				_flags, _reg, _bit_idx,		\
 				_gate_flags, _lock)		\
-	static struct clk _name;				\
+	static struct clk_core _name;				\
 	static const char *_name##_parent_names[] = {		\
 		_parent_name,					\
 	};							\
-	static struct clk *_name##_parents[] = {		\
+	static struct clk_core *_name##_parents[] = {		\
 		_parent_ptr,					\
 	};							\
 	static struct clk_gate _name##_hw = {			\
@@ -115,11 +119,11 @@ struct clk {
 #define _DEFINE_CLK_DIVIDER(_name, _parent_name, _parent_ptr,	\
 				_flags, _reg, _shift, _width,	\
 				_divider_flags, _table, _lock)	\
-	static struct clk _name;				\
+	static struct clk_core _name;				\
 	static const char *_name##_parent_names[] = {		\
 		_parent_name,					\
 	};							\
-	static struct clk *_name##_parents[] = {		\
+	static struct clk_core *_name##_parents[] = {		\
 		_parent_ptr,					\
 	};							\
 	static struct clk_divider _name##_hw = {		\
@@ -154,7 +158,7 @@ struct clk {
 #define DEFINE_CLK_MUX(_name, _parent_names, _parents, _flags,	\
 				_reg, _shift, _width,		\
 				_mux_flags, _lock)		\
-	static struct clk _name;				\
+	static struct clk_core _name;				\
 	static struct clk_mux _name##_hw = {			\
 		.hw = {						\
 			.clk = &_name,				\
@@ -171,11 +175,11 @@ struct clk {
 #define DEFINE_CLK_FIXED_FACTOR(_name, _parent_name,		\
 				_parent_ptr, _flags,		\
 				_mult, _div)			\
-	static struct clk _name;				\
+	static struct clk_core _name;				\
 	static const char *_name##_parent_names[] = {		\
 		_parent_name,					\
 	};							\
-	static struct clk *_name##_parents[] = {		\
+	static struct clk_core *_name##_parents[] = {		\
 		_parent_ptr,					\
 	};							\
 	static struct clk_fixed_factor _name##_hw = {		\
@@ -196,7 +200,7 @@ struct clk {
  * Initializes the lists in struct clk, queries the hardware for the
  * parent and rate and sets them both.
  *
- * Any struct clk passed into __clk_init must have the following members
+ * Any struct clk_core passed into __clk_init must have the following members
  * populated:
  * 	.name
  * 	.ops
@@ -210,9 +214,9 @@ struct clk {
  *
  * Returns 0 on success, otherwise an error code.
  */
-int __clk_init(struct device *dev, struct clk *clk);
+int __clk_init(struct device *dev, struct clk_core *clk);
 
-struct clk *__clk_register(struct device *dev, struct clk_hw *hw);
+struct clk_core *__clk_register(struct device *dev, struct clk_hw *hw);
 
 #endif /* CONFIG_COMMON_CLK */
 #endif /* CLK_PRIVATE_H */
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index 99b906f..edf1beb 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -16,35 +16,8 @@
 
 #ifdef CONFIG_COMMON_CLK
 
-/* Temporarily map the to-be-added API to the old API, just so stuff compiles */
-#define clk_core			clk
-
-#define __clk_create_clk
-
-#define clk_provider_get			clk_get
-#define clk_provider_get_sys			clk_get_sys
-#define devm_clk_provider_get			devm_clk_get
-#define of_clk_provider_get			of_clk_get
-#define of_clk_provider_get_by_name		of_clk_get_by_name
-
-#define clk_provider_set_rate			clk_set_rate
-#define clk_provider_get_rate			clk_get_rate
-#define clk_provider_round_rate			clk_round_rate
-#define clk_provider_set_parent			clk_set_parent
-#define clk_provider_get_parent			clk_get_parent
-#define clk_provider_prepare			clk_prepare
-#define clk_provider_unprepare			clk_unprepare
-#define clk_provider_enable			clk_enable
-#define clk_provider_disable			clk_disable
-#define clk_provider_prepare_enable		clk_prepare_enable
-#define clk_provider_disable_unprepare		clk_unprepare
-#define clk_provider_notifier_register		clk_notifier_register
-#define clk_provider_notifier_unregister	clk_notifier_unregister
-
-#define clk_get_name				__clk_get_name
-
 /*
- * flags used across common struct clk.  these flags should only affect the
+ * flags used across common struct clk_core.  these flags should only affect the
  * top-level framework.  custom flags for dealing with hardware specifics
  * belong in struct clk_foo
  */
@@ -194,7 +167,7 @@ struct clk_ops {
 					unsigned long *parent_rate);
 	long		(*determine_rate)(struct clk_hw *hw, unsigned long rate,
 					unsigned long *best_parent_rate,
-					struct clk **best_parent_clk);
+					struct clk_core **best_parent_clk);
 	int		(*set_parent)(struct clk_hw *hw, u8 index);
 	u8		(*get_parent)(struct clk_hw *hw);
 	int		(*set_rate)(struct clk_hw *hw, unsigned long rate,
@@ -227,19 +200,19 @@ struct clk_init_data {
 };
 
 /**
- * struct clk_hw - handle for traversing from a struct clk to its corresponding
+ * struct clk_hw - handle for traversing from a struct clk_core to its corresponding
  * hardware-specific structure.  struct clk_hw should be declared within struct
- * clk_foo and then referenced by the struct clk instance that uses struct
+ * clk_foo and then referenced by the struct clk_core instance that uses struct
  * clk_foo's clk_ops
  *
- * @clk: pointer to the struct clk instance that points back to this struct
+ * @clk: pointer to the struct clk_core instance that points back to this struct
  * clk_hw instance
  *
  * @init: pointer to struct clk_init_data that contains the init data shared
  * with the common clock framework.
  */
 struct clk_hw {
-	struct clk *clk;
+	struct clk_core *clk;
 	const struct clk_init_data *init;
 };
 
@@ -265,10 +238,10 @@ struct clk_fixed_rate {
 };
 
 extern const struct clk_ops clk_fixed_rate_ops;
-struct clk *clk_register_fixed_rate(struct device *dev, const char *name,
+struct clk_core *clk_register_fixed_rate(struct device *dev, const char *name,
 		const char *parent_name, unsigned long flags,
 		unsigned long fixed_rate);
-struct clk *clk_register_fixed_rate_with_accuracy(struct device *dev,
+struct clk_core *clk_register_fixed_rate_with_accuracy(struct device *dev,
 		const char *name, const char *parent_name, unsigned long flags,
 		unsigned long fixed_rate, unsigned long fixed_accuracy);
 
@@ -306,7 +279,7 @@ struct clk_gate {
 #define CLK_GATE_HIWORD_MASK		BIT(1)
 
 extern const struct clk_ops clk_gate_ops;
-struct clk *clk_register_gate(struct device *dev, const char *name,
+struct clk_core *clk_register_gate(struct device *dev, const char *name,
 		const char *parent_name, unsigned long flags,
 		void __iomem *reg, u8 bit_idx,
 		u8 clk_gate_flags, spinlock_t *lock);
@@ -369,11 +342,11 @@ struct clk_divider {
 
 extern const struct clk_ops clk_divider_ops;
 extern const struct clk_ops clk_divider_ro_ops;
-struct clk *clk_register_divider(struct device *dev, const char *name,
+struct clk_core *clk_register_divider(struct device *dev, const char *name,
 		const char *parent_name, unsigned long flags,
 		void __iomem *reg, u8 shift, u8 width,
 		u8 clk_divider_flags, spinlock_t *lock);
-struct clk *clk_register_divider_table(struct device *dev, const char *name,
+struct clk_core *clk_register_divider_table(struct device *dev, const char *name,
 		const char *parent_name, unsigned long flags,
 		void __iomem *reg, u8 shift, u8 width,
 		u8 clk_divider_flags, const struct clk_div_table *table,
@@ -418,12 +391,12 @@ struct clk_mux {
 extern const struct clk_ops clk_mux_ops;
 extern const struct clk_ops clk_mux_ro_ops;
 
-struct clk *clk_register_mux(struct device *dev, const char *name,
+struct clk_core *clk_register_mux(struct device *dev, const char *name,
 		const char **parent_names, u8 num_parents, unsigned long flags,
 		void __iomem *reg, u8 shift, u8 width,
 		u8 clk_mux_flags, spinlock_t *lock);
 
-struct clk *clk_register_mux_table(struct device *dev, const char *name,
+struct clk_core *clk_register_mux_table(struct device *dev, const char *name,
 		const char **parent_names, u8 num_parents, unsigned long flags,
 		void __iomem *reg, u8 shift, u32 mask,
 		u8 clk_mux_flags, u32 *table, spinlock_t *lock);
@@ -449,7 +422,7 @@ struct clk_fixed_factor {
 };
 
 extern struct clk_ops clk_fixed_factor_ops;
-struct clk *clk_register_fixed_factor(struct device *dev, const char *name,
+struct clk_core *clk_register_fixed_factor(struct device *dev, const char *name,
 		const char *parent_name, unsigned long flags,
 		unsigned int mult, unsigned int div);
 
@@ -479,7 +452,7 @@ struct clk_fractional_divider {
 };
 
 extern const struct clk_ops clk_fractional_divider_ops;
-struct clk *clk_register_fractional_divider(struct device *dev,
+struct clk_core *clk_register_fractional_divider(struct device *dev,
 		const char *name, const char *parent_name, unsigned long flags,
 		void __iomem *reg, u8 mshift, u8 mwidth, u8 nshift, u8 nwidth,
 		u8 clk_divider_flags, spinlock_t *lock);
@@ -508,7 +481,7 @@ struct clk_composite {
 	const struct clk_ops	*gate_ops;
 };
 
-struct clk *clk_register_composite(struct device *dev, const char *name,
+struct clk_core *clk_register_composite(struct device *dev, const char *name,
 		const char **parent_names, int num_parents,
 		struct clk_hw *mux_hw, const struct clk_ops *mux_ops,
 		struct clk_hw *rate_hw, const struct clk_ops *rate_ops,
@@ -521,49 +494,87 @@ struct clk *clk_register_composite(struct device *dev, const char *name,
  * @hw: link to hardware-specific clock data
  *
  * clk_register is the primary interface for populating the clock tree with new
- * clock nodes.  It returns a pointer to the newly allocated struct clk which
+ * clock nodes.  It returns a pointer to the newly allocated struct clk_core which
  * cannot be dereferenced by driver code but may be used in conjuction with the
  * rest of the clock API.  In the event of an error clk_register will return an
  * error code; drivers must test for an error code after calling clk_register.
  */
-struct clk *clk_register(struct device *dev, struct clk_hw *hw);
-struct clk *devm_clk_register(struct device *dev, struct clk_hw *hw);
+struct clk_core *clk_register(struct device *dev, struct clk_hw *hw);
+struct clk_core *devm_clk_register(struct device *dev, struct clk_hw *hw);
 
-void clk_unregister(struct clk *clk);
-void devm_clk_unregister(struct device *dev, struct clk *clk);
+void clk_unregister(struct clk_core *clk);
+void devm_clk_unregister(struct device *dev, struct clk_core *clk);
 
 /* helper functions */
-const char *__clk_get_name(struct clk *clk);
-struct clk_hw *__clk_get_hw(struct clk *clk);
-u8 __clk_get_num_parents(struct clk *clk);
-struct clk *__clk_get_parent(struct clk *clk);
-struct clk *clk_get_parent_by_index(struct clk *clk, u8 index);
-unsigned int __clk_get_enable_count(struct clk *clk);
-unsigned int __clk_get_prepare_count(struct clk *clk);
-unsigned long __clk_get_rate(struct clk *clk);
-unsigned long __clk_get_accuracy(struct clk *clk);
-unsigned long __clk_get_flags(struct clk *clk);
-bool __clk_is_prepared(struct clk *clk);
-bool __clk_is_enabled(struct clk *clk);
-struct clk *__clk_lookup(const char *name);
+const char *__clk_get_name(struct clk_core *clk);
+struct clk_hw *__clk_get_hw(struct clk_core *clk);
+u8 __clk_get_num_parents(struct clk_core *clk);
+struct clk_core *__clk_get_parent(struct clk_core *clk);
+struct clk_core *clk_get_parent_by_index(struct clk_core *clk, u8 index);
+unsigned int __clk_get_enable_count(struct clk_core *clk);
+unsigned int __clk_get_prepare_count(struct clk_core *clk);
+unsigned long __clk_get_rate(struct clk_core *clk);
+unsigned long __clk_get_accuracy(struct clk_core *clk);
+unsigned long __clk_get_flags(struct clk_core *clk);
+bool __clk_is_prepared(struct clk_core *clk);
+bool __clk_is_enabled(struct clk_core *clk);
+struct clk_core *__clk_lookup(const char *name);
 long __clk_mux_determine_rate(struct clk_hw *hw, unsigned long rate,
 			      unsigned long *best_parent_rate,
-			      struct clk **best_parent_p);
+			      struct clk_core **best_parent_p);
+
+int clk_provider_prepare(struct clk_core *clk);
+void clk_provider_unprepare(struct clk_core *clk);
+int clk_provider_enable(struct clk_core *clk);
+void clk_provider_disable(struct clk_core *clk);
+int clk_provider_set_parent(struct clk_core *clk, struct clk_core *parent);
+int clk_provider_set_rate(struct clk_core *clk, unsigned long rate);
+struct clk_core *clk_provider_get_parent(struct clk_core *clk);
+unsigned long clk_provider_get_rate(struct clk_core *clk);
+long clk_provider_round_rate(struct clk_core *clk, unsigned long rate);
+struct clk_core *clk_provider_get_sys(const char *dev_id, const char *con_id);
+struct clk_core *clk_provider_get(struct device *dev, const char *con_id);
+struct clk_core *devm_clk_provider_get(struct device *dev, const char *id);
+int clk_provider_notifier_register(struct clk_core *clk, struct notifier_block *nb);
+int clk_provider_notifier_unregister(struct clk_core *clk, struct notifier_block *nb);
+struct clk_core *clk_to_clk_core(struct clk *clk);
+
+/* clk_provider_prepare_enable helps cases using clk_enable in non-atomic context. */
+static inline int clk_provider_prepare_enable(struct clk_core *clk)
+{
+	int ret;
+
+	ret = clk_provider_prepare(clk);
+	if (ret)
+		return ret;
+	ret = clk_provider_enable(clk);
+	if (ret)
+		clk_provider_unprepare(clk);
+
+	return ret;
+}
+
+/* clk_provider_disable_unprepare helps cases using clk_disable in non-atomic context. */
+static inline void clk_provider_disable_unprepare(struct clk_core *clk)
+{
+	clk_provider_disable(clk);
+	clk_provider_unprepare(clk);
+}
 
 /*
  * FIXME clock api without lock protection
  */
-int __clk_prepare(struct clk *clk);
-void __clk_unprepare(struct clk *clk);
-void __clk_reparent(struct clk *clk, struct clk *new_parent);
-unsigned long __clk_round_rate(struct clk *clk, unsigned long rate);
+int __clk_prepare(struct clk_core *clk);
+void __clk_unprepare(struct clk_core *clk);
+void __clk_reparent(struct clk_core *clk, struct clk_core *new_parent);
+unsigned long __clk_round_rate(struct clk_core *clk, unsigned long rate);
 
 struct of_device_id;
 
 typedef void (*of_clk_init_cb_t)(struct device_node *);
 
 struct clk_onecell_data {
-	struct clk **clks;
+	struct clk_core **clks;
 	unsigned int clk_num;
 };
 
@@ -573,22 +584,23 @@ extern struct of_device_id __clk_of_table;
 
 #ifdef CONFIG_OF
 int of_clk_add_provider(struct device_node *np,
-			struct clk *(*clk_src_get)(struct of_phandle_args *args,
+			struct clk_core *(*clk_src_get)(struct of_phandle_args *args,
 						   void *data),
 			void *data);
 void of_clk_del_provider(struct device_node *np);
-struct clk *of_clk_src_simple_get(struct of_phandle_args *clkspec,
+struct clk_core *of_clk_src_simple_get(struct of_phandle_args *clkspec,
 				  void *data);
-struct clk *of_clk_src_onecell_get(struct of_phandle_args *clkspec, void *data);
+struct clk_core *of_clk_src_onecell_get(struct of_phandle_args *clkspec, void *data);
 int of_clk_get_parent_count(struct device_node *np);
 const char *of_clk_get_parent_name(struct device_node *np, int index);
+struct clk_core *of_clk_provider_get(struct device_node *np, int index);
 
 void of_clk_init(const struct of_device_id *matches);
 
 #else /* !CONFIG_OF */
 
 static inline int of_clk_add_provider(struct device_node *np,
-			struct clk *(*clk_src_get)(struct of_phandle_args *args,
+			struct clk_core *(*clk_src_get)(struct of_phandle_args *args,
 						   void *data),
 			void *data)
 {
@@ -596,12 +608,12 @@ static inline int of_clk_add_provider(struct device_node *np,
 }
 #define of_clk_del_provider(np) \
 	{ while (0); }
-static inline struct clk *of_clk_src_simple_get(
+static inline struct clk_core *of_clk_src_simple_get(
 	struct of_phandle_args *clkspec, void *data)
 {
 	return ERR_PTR(-ENOENT);
 }
-static inline struct clk *of_clk_src_onecell_get(
+static inline struct clk_core *of_clk_src_onecell_get(
 	struct of_phandle_args *clkspec, void *data)
 {
 	return ERR_PTR(-ENOENT);
@@ -611,6 +623,10 @@ static inline const char *of_clk_get_parent_name(struct device_node *np,
 {
 	return NULL;
 }
+static inline struct clk_core *of_clk_provider_get(struct device_node *np, int index)
+{
+	return NULL;
+}
 #define of_clk_init(matches) \
 	{ while (0); }
 #endif /* CONFIG_OF */
@@ -647,7 +663,7 @@ static inline void clk_writel(u32 val, u32 __iomem *reg)
 #endif	/* platform dependent I/O accessors */
 
 #ifdef CONFIG_DEBUG_FS
-struct dentry *clk_debugfs_add_file(struct clk *clk, char *name, umode_t mode,
+struct dentry *clk_debugfs_add_file(struct clk_core *clk, char *name, umode_t mode,
 				void *data, const struct file_operations *fops);
 #endif
 
diff --git a/include/linux/clk.h b/include/linux/clk.h
index fb5e097..f46a2eb 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -22,6 +22,8 @@ struct clk;
 
 #ifdef CONFIG_COMMON_CLK
 
+struct clk_core;
+
 /**
  * DOC: clk notifier callback types
  *
@@ -56,7 +58,7 @@ struct clk;
  * @notifier_head.
  */
 struct clk_notifier {
-	struct clk			*clk;
+	struct clk_core			*clk;
 	struct srcu_notifier_head	notifier_head;
 	struct list_head		node;
 };
@@ -73,7 +75,7 @@ struct clk_notifier {
  * current rate (this was done to optimize the implementation).
  */
 struct clk_notifier_data {
-	struct clk		*clk;
+	struct clk_core		*clk;
 	unsigned long		old_rate;
 	unsigned long		new_rate;
 };
@@ -307,6 +309,14 @@ struct clk *clk_get_parent(struct clk *clk);
  */
 struct clk *clk_get_sys(const char *dev_id, const char *con_id);
 
+/**
+ * clk_get_name - get a clock's name
+ * @clk: clock source
+ *
+ * Returns the name of the provided clock.
+ */
+const char *clk_get_name(struct clk *clk);
+
 #else /* !CONFIG_HAVE_CLK */
 
 static inline struct clk *clk_get(struct device *dev, const char *id)
@@ -398,7 +408,8 @@ struct of_phandle_args;
 #if defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK)
 struct clk *of_clk_get(struct device_node *np, int index);
 struct clk *of_clk_get_by_name(struct device_node *np, const char *name);
-struct clk *of_clk_get_from_provider(struct of_phandle_args *clkspec);
+struct clk_core *of_clk_provider_get_by_name(struct device_node *np, const char *name);
+struct clk_core *of_clk_get_from_provider(struct of_phandle_args *clkspec);
 #else
 static inline struct clk *of_clk_get(struct device_node *np, int index)
 {
@@ -409,6 +420,21 @@ static inline struct clk *of_clk_get_by_name(struct device_node *np,
 {
 	return ERR_PTR(-ENOENT);
 }
+
+#if defined(CONFIG_COMMON_CLK)
+static inline struct clk_core *of_clk_provider_get_by_name(struct device_node *np,
+							   const char *name)
+{
+	return ERR_PTR(-ENOENT);
+}
+#else
+static inline struct clk *of_clk_provider_get_by_name(struct device_node *np,
+						      const char *name)
+{
+	return ERR_PTR(-ENOENT);
+}
+#endif /* CONFIG_COMMON_CLK */
+
 #endif
 
 #endif
diff --git a/include/linux/clkdev.h b/include/linux/clkdev.h
index 94bad77..a6c5d67 100644
--- a/include/linux/clkdev.h
+++ b/include/linux/clkdev.h
@@ -17,11 +17,23 @@
 struct clk;
 struct device;
 
+/*
+ * To avoid a mass-rename of all non-common clock implementations (spread out
+ * in arch-specific code), we let them use struct clk for both the internal and
+ * external view.
+ */
+#ifdef CONFIG_COMMON_CLK
+struct clk_core;
+#define clk_core_t struct clk_core
+#else
+#define clk_core_t struct clk
+#endif
+
 struct clk_lookup {
 	struct list_head	node;
 	const char		*dev_id;
 	const char		*con_id;
-	struct clk		*clk;
+	clk_core_t		*clk;
 };
 
 #define CLKDEV_INIT(d, n, c)	\
@@ -31,7 +43,7 @@ struct clk_lookup {
 		.clk = c,	\
 	}
 
-struct clk_lookup *clkdev_alloc(struct clk *clk, const char *con_id,
+struct clk_lookup *clkdev_alloc(clk_core_t *clk, const char *con_id,
 	const char *dev_fmt, ...);
 
 void clkdev_add(struct clk_lookup *cl);
@@ -40,12 +52,12 @@ void clkdev_drop(struct clk_lookup *cl);
 void clkdev_add_table(struct clk_lookup *, size_t);
 int clk_add_alias(const char *, const char *, char *, struct device *);
 
-int clk_register_clkdev(struct clk *, const char *, const char *, ...);
-int clk_register_clkdevs(struct clk *, struct clk_lookup *, size_t);
+int clk_register_clkdev(clk_core_t *, const char *, const char *, ...);
+int clk_register_clkdevs(clk_core_t *, struct clk_lookup *, size_t);
 
 #ifdef CONFIG_COMMON_CLK
-int __clk_get(struct clk *clk);
-void __clk_put(struct clk *clk);
+int __clk_get(struct clk_core *clk);
+void __clk_put(struct clk_core *clk);
 #endif
 
 #endif
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v10 4/9] clk: per-user clock accounting for debug
  2014-09-09 14:06 ` [PATCH v10 3/9] clk: use struct clk only for external API Tomeu Vizoso
@ 2014-09-09 14:06   ` Tomeu Vizoso
  2014-09-09 14:06   ` [PATCH v10 5/9] clk: Add floor and ceiling constraints to clock rates Tomeu Vizoso
                     ` (4 subsequent siblings)
  5 siblings, 0 replies; 15+ messages in thread
From: Tomeu Vizoso @ 2014-09-09 14:06 UTC (permalink / raw)
  To: Mike Turquette
  Cc: Stephen Warren, Thierry Reding, tomasz.figa, Peter De Schrijver,
	rabin, linux-kernel, linux-arm-kernel, Javier Martinez Canillas,
	Tomeu Vizoso

When a clock has multiple users, the WARNING on imbalance of
enable/disable may not show the guilty party since although they may
have commited the error earlier, the warning is emitted later when some
other user, presumably innocent, disables the clock.

Provide per-user clock enable/disable accounting and disabler tracking
in order to help debug these problems.

Based on previous work by Rabin Vincent <rabin@rab.in>.

Signed-off-by: Tomeu Vizoso <tomeu.vizoso@collabora.com>
Tested-by: Heiko Stuebner <heiko@sntech.de>
---
 drivers/clk/clk.c           | 38 ++++++++++++++++++++++++++++++++++----
 drivers/clk/clk.h           |  3 ++-
 drivers/clk/clkdev.c        | 14 ++++++++++----
 include/linux/clk-private.h |  5 +++++
 4 files changed, 51 insertions(+), 9 deletions(-)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index ce84b1f..61a3492 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -543,7 +543,8 @@ static int clk_disable_unused(void)
 }
 late_initcall_sync(clk_disable_unused);
 
-struct clk *__clk_create_clk(struct clk_core *clk_core)
+struct clk *__clk_create_clk(struct clk_core *clk_core, const char *dev,
+			     const char *con)
 {
 	struct clk *clk;
 
@@ -556,6 +557,8 @@ struct clk *__clk_create_clk(struct clk_core *clk_core)
 		return ERR_PTR(-ENOMEM);
 
 	clk->core = clk_core;
+	clk->dev_id = dev;
+	clk->con_id = con;
 
 	return clk;
 }
@@ -936,10 +939,25 @@ EXPORT_SYMBOL_GPL(clk_provider_disable);
  */
 void clk_disable(struct clk *clk_user)
 {
+	struct clk_core *clk;
+	unsigned long flags;
+
 	if (IS_ERR_OR_NULL(clk_user))
 		return;
 
-	clk_provider_disable(clk_to_clk_core(clk_user));
+	clk = clk_to_clk_core(clk_user);
+
+	flags = clk_enable_lock();
+	if (!WARN(clk_user->enable_count == 0,
+		  "incorrect disable clk dev %s con %s last disabler %pF\n",
+		  clk_user->dev_id, clk_user->con_id, clk_user->last_disable)) {
+
+		clk_user->last_disable = __builtin_return_address(0);
+		clk_user->enable_count--;
+
+		__clk_disable(clk);
+	}
+	clk_enable_unlock(flags);
 }
 EXPORT_SYMBOL_GPL(clk_disable);
 
@@ -1000,10 +1018,22 @@ EXPORT_SYMBOL_GPL(clk_provider_enable);
  */
 int clk_enable(struct clk *clk_user)
 {
+	struct clk_core *clk;
+	unsigned long flags;
+	int ret;
+
 	if (!clk_user)
 		return 0;
 
-	return clk_provider_enable(clk_to_clk_core(clk_user));
+	clk = clk_to_clk_core(clk_user);
+
+	flags = clk_enable_lock();
+	ret = __clk_enable(clk);
+	if (!ret)
+		clk_user->enable_count++;
+	clk_enable_unlock(flags);
+
+	return ret;
 }
 EXPORT_SYMBOL_GPL(clk_enable);
 
@@ -1698,7 +1728,7 @@ struct clk *clk_get_parent(struct clk *clk_user)
 	clk = clk_to_clk_core(clk_user);
 	parent = clk_provider_get_parent(clk);
 
-	return __clk_create_clk(parent);
+	return __clk_create_clk(parent, clk_user->dev_id, clk_user->con_id);
 }
 EXPORT_SYMBOL_GPL(clk_get_parent);
 
diff --git a/drivers/clk/clk.h b/drivers/clk/clk.h
index 3b3068b..49eff38 100644
--- a/drivers/clk/clk.h
+++ b/drivers/clk/clk.h
@@ -19,5 +19,6 @@ void of_clk_unlock(void);
 #endif
 
 #if defined(CONFIG_COMMON_CLK)
-struct clk *__clk_create_clk(struct clk_core *clk_core);
+struct clk *__clk_create_clk(struct clk_core *clk_core, const char *dev,
+			     const char *con);
 #endif
diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c
index 080b3df..f7b352a 100644
--- a/drivers/clk/clkdev.c
+++ b/drivers/clk/clkdev.c
@@ -76,7 +76,9 @@ struct clk_core *of_clk_provider_get(struct device_node *np, int index)
 
 struct clk *of_clk_get(struct device_node *np, int index)
 {
-	return __clk_create_clk(of_clk_provider_get(np, index));
+	struct clk_core *clk = of_clk_provider_get(np, index);
+
+	return __clk_create_clk(clk, np->full_name, NULL);
 }
 EXPORT_SYMBOL(of_clk_get);
 
@@ -129,7 +131,9 @@ struct clk_core *of_clk_provider_get_by_name(struct device_node *np, const char
  */
 struct clk *of_clk_get_by_name(struct device_node *np, const char *name)
 {
-	return __clk_create_clk(of_clk_provider_get_by_name(np, name));
+	struct clk_core *clk = of_clk_provider_get_by_name(np, name);
+
+	return __clk_create_clk(clk, np->full_name, NULL);
 }
 EXPORT_SYMBOL(of_clk_get_by_name);
 #endif
@@ -201,7 +205,7 @@ struct clk *clk_get_sys(const char *dev_id, const char *con_id)
 #if defined(CONFIG_COMMON_CLK)
 	struct clk_core *clk = clk_provider_get_sys(dev_id, con_id);
 
-	return __clk_create_clk(clk);
+	return __clk_create_clk(clk, dev_id, con_id);
 #else
 	struct clk_lookup *cl;
 
@@ -241,7 +245,9 @@ EXPORT_SYMBOL(clk_provider_get);
 struct clk *clk_get(struct device *dev, const char *con_id)
 {
 #if defined(CONFIG_COMMON_CLK)
-	return __clk_create_clk(clk_provider_get(dev, con_id));
+        const char *dev_id = dev ? dev_name(dev) : NULL;
+
+	return __clk_create_clk(clk_provider_get(dev, con_id), dev_id, con_id);
 #else
 	const char *dev_id = dev ? dev_name(dev) : NULL;
 	struct clk *clk;
diff --git a/include/linux/clk-private.h b/include/linux/clk-private.h
index 2c1ece9..ce6a528 100644
--- a/include/linux/clk-private.h
+++ b/include/linux/clk-private.h
@@ -57,6 +57,11 @@ struct clk_core {
 
 struct clk {
 	struct clk_core	*core;
+	const char	*dev_id;
+	const char	*con_id;
+
+	unsigned int	enable_count;
+	void		*last_disable;
 };
 
 /*
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v10 5/9] clk: Add floor and ceiling constraints to clock rates
  2014-09-09 14:06 ` [PATCH v10 3/9] clk: use struct clk only for external API Tomeu Vizoso
  2014-09-09 14:06   ` [PATCH v10 4/9] clk: per-user clock accounting for debug Tomeu Vizoso
@ 2014-09-09 14:06   ` Tomeu Vizoso
  2014-09-09 14:06   ` [PATCH v10 6/9] clk: Warn of unbalanced clk_prepare() calls Tomeu Vizoso
                     ` (3 subsequent siblings)
  5 siblings, 0 replies; 15+ messages in thread
From: Tomeu Vizoso @ 2014-09-09 14:06 UTC (permalink / raw)
  To: Mike Turquette
  Cc: Stephen Warren, Thierry Reding, tomasz.figa, Peter De Schrijver,
	rabin, linux-kernel, linux-arm-kernel, Javier Martinez Canillas,
	Tomeu Vizoso

Adds a way for clock consumers to set maximum and minimum rates. This can be
used for thermal drivers to set ceiling rates, or by misc. drivers to set
floor rates to assure a minimum performance level.

Signed-off-by: Tomeu Vizoso <tomeu.vizoso@collabora.com>
Tested-by: Heiko Stuebner <heiko@sntech.de>

---

v9: * Apply first all the floor constraints, then the ceiling constraints.
    * WARN on ceiling constraints below the current floor, for a given user clk

v5: * Move the storage of constraints to the per-user clk struct, as suggested
      by Stephen Warren.
---
 drivers/clk/clk.c           | 43 +++++++++++++++++++++++++++++++++++++++++++
 drivers/clk/clk.h           |  1 +
 drivers/clk/clkdev.c        |  2 +-
 include/linux/clk-private.h |  5 +++++
 include/linux/clk.h         | 18 ++++++++++++++++++
 5 files changed, 68 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 61a3492..3a961c6 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -560,6 +560,8 @@ struct clk *__clk_create_clk(struct clk_core *clk_core, const char *dev,
 	clk->dev_id = dev;
 	clk->con_id = con;
 
+	hlist_add_head(&clk->child_node, &clk_core->per_user_clks);
+
 	return clk;
 }
 
@@ -1625,6 +1627,7 @@ static void clk_change_rate(struct clk_core *clk)
 int clk_provider_set_rate(struct clk_core *clk, unsigned long rate)
 {
 	struct clk_core *top, *fail_clk;
+	struct clk *clk_user;
 	int ret = 0;
 
 	if (!clk)
@@ -1633,6 +1636,15 @@ int clk_provider_set_rate(struct clk_core *clk, unsigned long rate)
 	/* prevent racing with updates to the clock topology */
 	clk_prepare_lock();
 
+	hlist_for_each_entry(clk_user, &clk->per_user_clks, child_node) {
+		rate = max(rate, clk_user->floor_constraint);
+	}
+
+	hlist_for_each_entry(clk_user, &clk->per_user_clks, child_node) {
+		if (clk_user->ceiling_constraint > 0)
+			rate = min(rate, clk_user->ceiling_constraint);
+	}
+
 	/* bail early if nothing to do */
 	if (rate == clk_provider_get_rate(clk))
 		goto out;
@@ -1699,6 +1711,29 @@ int clk_set_rate(struct clk *clk_user, unsigned long rate)
 }
 EXPORT_SYMBOL_GPL(clk_set_rate);
 
+int clk_set_floor_rate(struct clk *clk_user, unsigned long rate)
+{
+	struct clk_core *clk = clk_to_clk_core(clk_user);
+
+	clk_user->floor_constraint = rate;
+	return clk_provider_set_rate(clk, clk_provider_get_rate(clk));
+}
+EXPORT_SYMBOL_GPL(clk_set_floor_rate);
+
+int clk_set_ceiling_rate(struct clk *clk_user, unsigned long rate)
+{
+	struct clk_core *clk = clk_to_clk_core(clk_user);
+
+	WARN(rate > 0 && rate < clk_user->floor_constraint,
+	     "clk %s dev %s con %s: new ceiling %lu lower than existing floor %lu\n",
+	     __clk_get_name(clk), clk_user->dev_id, clk_user->con_id, rate,
+	     clk_user->floor_constraint);
+
+	clk_user->ceiling_constraint = rate;
+	return clk_provider_set_rate(clk, clk_provider_get_rate(clk));
+}
+EXPORT_SYMBOL_GPL(clk_set_ceiling_rate);
+
 struct clk_core *clk_provider_get_parent(struct clk_core *clk)
 {
 	struct clk_core *parent;
@@ -2043,6 +2078,8 @@ int __clk_init(struct device *dev, struct clk_core *clk)
 			}
 	 }
 
+	INIT_HLIST_HEAD(&clk->per_user_clks);
+
 	/*
 	 * optional platform-specific magic
 	 *
@@ -2493,6 +2530,12 @@ int clk_notifier_unregister(struct clk *clk_user, struct notifier_block *nb)
 }
 EXPORT_SYMBOL_GPL(clk_notifier_unregister);
 
+void __clk_free_clk(struct clk *clk_user)
+{
+	hlist_del(&clk_user->child_node);
+	kfree(clk_user);
+}
+
 #ifdef CONFIG_OF
 /**
  * struct of_clk_provider - Clock provider registration structure
diff --git a/drivers/clk/clk.h b/drivers/clk/clk.h
index 49eff38..005deb3 100644
--- a/drivers/clk/clk.h
+++ b/drivers/clk/clk.h
@@ -21,4 +21,5 @@ void of_clk_unlock(void);
 #if defined(CONFIG_COMMON_CLK)
 struct clk *__clk_create_clk(struct clk_core *clk_core, const char *dev,
 			     const char *con);
+void __clk_free_clk(struct clk *clk_user);
 #endif
diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c
index f7b352a..89193de 100644
--- a/drivers/clk/clkdev.c
+++ b/drivers/clk/clkdev.c
@@ -270,7 +270,7 @@ void clk_put(struct clk *clk)
 #if defined(CONFIG_COMMON_CLK)
 	clk_core_t *core = clk_to_clk_core(clk);
 
-	kfree(clk);
+	__clk_free_clk(clk);
 	__clk_put(core);
 #else
 	__clk_put(clk);
diff --git a/include/linux/clk-private.h b/include/linux/clk-private.h
index ce6a528..8126046 100644
--- a/include/linux/clk-private.h
+++ b/include/linux/clk-private.h
@@ -48,6 +48,7 @@ struct clk_core {
 	unsigned long		accuracy;
 	struct hlist_head	children;
 	struct hlist_node	child_node;
+	struct hlist_head	per_user_clks;
 	unsigned int		notifier_count;
 #ifdef CONFIG_DEBUG_FS
 	struct dentry		*dentry;
@@ -62,6 +63,10 @@ struct clk {
 
 	unsigned int	enable_count;
 	void		*last_disable;
+
+	unsigned long	floor_constraint;
+	unsigned long	ceiling_constraint;
+	struct hlist_node child_node;
 };
 
 /*
diff --git a/include/linux/clk.h b/include/linux/clk.h
index f46a2eb..066b100 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -275,6 +275,24 @@ long clk_round_rate(struct clk *clk, unsigned long rate);
 int clk_set_rate(struct clk *clk, unsigned long rate);
 
 /**
+ * clk_set_floor_rate - set a minimum clock rate for a clock source
+ * @clk: clock source
+ * @rate: desired minimum clock rate in Hz
+ *
+ * Returns success (0) or negative errno.
+ */
+int clk_set_floor_rate(struct clk *clk, unsigned long rate);
+
+/**
+ * clk_set_ceiling_rate - set a maximum clock rate for a clock source
+ * @clk: clock source
+ * @rate: desired maximum clock rate in Hz
+ *
+ * Returns success (0) or negative errno.
+ */
+int clk_set_ceiling_rate(struct clk *clk, unsigned long rate);
+
+/**
  * clk_set_parent - set the parent clock source for this clock
  * @clk: clock source
  * @parent: parent clock source
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v10 6/9] clk: Warn of unbalanced clk_prepare() calls
  2014-09-09 14:06 ` [PATCH v10 3/9] clk: use struct clk only for external API Tomeu Vizoso
  2014-09-09 14:06   ` [PATCH v10 4/9] clk: per-user clock accounting for debug Tomeu Vizoso
  2014-09-09 14:06   ` [PATCH v10 5/9] clk: Add floor and ceiling constraints to clock rates Tomeu Vizoso
@ 2014-09-09 14:06   ` Tomeu Vizoso
  2014-09-09 14:06   ` [PATCH v10 7/9] clk: Take the prepare lock when updating the list of per-user clks Tomeu Vizoso
                     ` (2 subsequent siblings)
  5 siblings, 0 replies; 15+ messages in thread
From: Tomeu Vizoso @ 2014-09-09 14:06 UTC (permalink / raw)
  To: Mike Turquette
  Cc: Stephen Warren, Thierry Reding, tomasz.figa, Peter De Schrijver,
	rabin, linux-kernel, linux-arm-kernel, Javier Martinez Canillas,
	Tomeu Vizoso

The warning will display the clock user that is trying to unprepare the clock,
and the location of the last unprepare call.

Signed-off-by: Tomeu Vizoso <tomeu.vizoso@collabora.com>

---

v8: * Patch added
---
 drivers/clk/clk.c           | 22 ++++++++++++++++++++--
 include/linux/clk-private.h |  3 +++
 2 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 3a961c6..3018f37 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -834,7 +834,17 @@ void clk_unprepare(struct clk *clk_user)
 	if (IS_ERR_OR_NULL(clk_user))
 		return;
 
-	clk_provider_unprepare(clk_to_clk_core(clk_user));
+	clk_prepare_lock();
+	if (!WARN(clk_user->prepare_count == 0,
+		  "incorrect unprepare clk dev %s con %s last caller of unprepare %pF\n",
+		  clk_user->dev_id, clk_user->con_id, clk_user->last_unprepare)) {
+
+		clk_user->last_unprepare = __builtin_return_address(0);
+		clk_user->prepare_count--;
+
+		__clk_unprepare(clk_to_clk_core(clk_user));
+	}
+	clk_prepare_unlock();
 }
 EXPORT_SYMBOL_GPL(clk_unprepare);
 
@@ -890,10 +900,18 @@ EXPORT_SYMBOL_GPL(clk_provider_prepare);
  */
 int clk_prepare(struct clk *clk_user)
 {
+	int ret;
+
 	if (!clk_user)
 		return 0;
 
-	return clk_provider_prepare(clk_to_clk_core(clk_user));
+	clk_prepare_lock();
+	ret = __clk_prepare(clk_to_clk_core(clk_user));
+	if (!ret)
+		clk_user->prepare_count++;
+	clk_prepare_unlock();
+
+	return ret;
 }
 EXPORT_SYMBOL_GPL(clk_prepare);
 
diff --git a/include/linux/clk-private.h b/include/linux/clk-private.h
index 8126046..cf93bde 100644
--- a/include/linux/clk-private.h
+++ b/include/linux/clk-private.h
@@ -64,6 +64,9 @@ struct clk {
 	unsigned int	enable_count;
 	void		*last_disable;
 
+	unsigned int	prepare_count;
+	void		*last_unprepare;
+
 	unsigned long	floor_constraint;
 	unsigned long	ceiling_constraint;
 	struct hlist_node child_node;
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v10 7/9] clk: Take the prepare lock when updating the list of per-user clks
  2014-09-09 14:06 ` [PATCH v10 3/9] clk: use struct clk only for external API Tomeu Vizoso
                     ` (2 preceding siblings ...)
  2014-09-09 14:06   ` [PATCH v10 6/9] clk: Warn of unbalanced clk_prepare() calls Tomeu Vizoso
@ 2014-09-09 14:06   ` Tomeu Vizoso
  2014-09-09 14:06   ` [PATCH v10 8/9] clk: Take the prepare lock when updating the per-user constraints Tomeu Vizoso
  2014-09-09 14:06   ` [PATCH v10 9/9] clk: Add docs about calling clk_put after clk_get_parent Tomeu Vizoso
  5 siblings, 0 replies; 15+ messages in thread
From: Tomeu Vizoso @ 2014-09-09 14:06 UTC (permalink / raw)
  To: Mike Turquette
  Cc: Stephen Warren, Thierry Reding, tomasz.figa, Peter De Schrijver,
	rabin, linux-kernel, linux-arm-kernel, Javier Martinez Canillas,
	Tomeu Vizoso

Signed-off-by: Tomeu Vizoso <tomeu.vizoso@collabora.com>
---
 drivers/clk/clk.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 3018f37..f283dcc 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -560,7 +560,9 @@ struct clk *__clk_create_clk(struct clk_core *clk_core, const char *dev,
 	clk->dev_id = dev;
 	clk->con_id = con;
 
+	clk_prepare_lock();
 	hlist_add_head(&clk->child_node, &clk_core->per_user_clks);
+	clk_prepare_unlock();
 
 	return clk;
 }
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v10 8/9] clk: Take the prepare lock when updating the per-user constraints
  2014-09-09 14:06 ` [PATCH v10 3/9] clk: use struct clk only for external API Tomeu Vizoso
                     ` (3 preceding siblings ...)
  2014-09-09 14:06   ` [PATCH v10 7/9] clk: Take the prepare lock when updating the list of per-user clks Tomeu Vizoso
@ 2014-09-09 14:06   ` Tomeu Vizoso
  2014-09-09 14:06   ` [PATCH v10 9/9] clk: Add docs about calling clk_put after clk_get_parent Tomeu Vizoso
  5 siblings, 0 replies; 15+ messages in thread
From: Tomeu Vizoso @ 2014-09-09 14:06 UTC (permalink / raw)
  To: Mike Turquette
  Cc: Stephen Warren, Thierry Reding, tomasz.figa, Peter De Schrijver,
	rabin, linux-kernel, linux-arm-kernel, Javier Martinez Canillas,
	Tomeu Vizoso

Signed-off-by: Tomeu Vizoso <tomeu.vizoso@collabora.com>
---
 drivers/clk/clk.c | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index f283dcc..1ad8cb7 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -1734,15 +1734,25 @@ EXPORT_SYMBOL_GPL(clk_set_rate);
 int clk_set_floor_rate(struct clk *clk_user, unsigned long rate)
 {
 	struct clk_core *clk = clk_to_clk_core(clk_user);
+	int ret;
+
+	clk_prepare_lock();
 
 	clk_user->floor_constraint = rate;
-	return clk_provider_set_rate(clk, clk_provider_get_rate(clk));
+	ret = clk_provider_set_rate(clk, clk_provider_get_rate(clk));
+
+	clk_prepare_unlock();
+
+	return ret;
 }
 EXPORT_SYMBOL_GPL(clk_set_floor_rate);
 
 int clk_set_ceiling_rate(struct clk *clk_user, unsigned long rate)
 {
 	struct clk_core *clk = clk_to_clk_core(clk_user);
+	int ret;
+
+	clk_prepare_lock();
 
 	WARN(rate > 0 && rate < clk_user->floor_constraint,
 	     "clk %s dev %s con %s: new ceiling %lu lower than existing floor %lu\n",
@@ -1750,7 +1760,11 @@ int clk_set_ceiling_rate(struct clk *clk_user, unsigned long rate)
 	     clk_user->floor_constraint);
 
 	clk_user->ceiling_constraint = rate;
-	return clk_provider_set_rate(clk, clk_provider_get_rate(clk));
+	ret = clk_provider_set_rate(clk, clk_provider_get_rate(clk));
+
+	clk_prepare_unlock();
+
+	return ret;
 }
 EXPORT_SYMBOL_GPL(clk_set_ceiling_rate);
 
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v10 9/9] clk: Add docs about calling clk_put after clk_get_parent
  2014-09-09 14:06 ` [PATCH v10 3/9] clk: use struct clk only for external API Tomeu Vizoso
                     ` (4 preceding siblings ...)
  2014-09-09 14:06   ` [PATCH v10 8/9] clk: Take the prepare lock when updating the per-user constraints Tomeu Vizoso
@ 2014-09-09 14:06   ` Tomeu Vizoso
  5 siblings, 0 replies; 15+ messages in thread
From: Tomeu Vizoso @ 2014-09-09 14:06 UTC (permalink / raw)
  To: Mike Turquette
  Cc: Stephen Warren, Thierry Reding, tomasz.figa, Peter De Schrijver,
	rabin, linux-kernel, linux-arm-kernel, Javier Martinez Canillas,
	Tomeu Vizoso

As otherwise the per-user clk will be leaked.

Signed-off-by: Tomeu Vizoso <tomeu.vizoso@collabora.com>
---
 drivers/clk/clk.c   | 3 ++-
 include/linux/clk.h | 3 ++-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 1ad8cb7..8ac8543 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -1784,7 +1784,8 @@ EXPORT_SYMBOL_GPL(clk_provider_get_parent);
  * clk_get_parent - return the parent of a clk
  * @clk_user: the clk whose parent gets returned
  *
- * Simply returns clk->parent.  Returns NULL if clk is NULL.
+ * Simply returns clk->parent.  Returns NULL if clk is NULL. Caller must call
+ * clk_put() to release the returned struct clk.
  */
 struct clk *clk_get_parent(struct clk *clk_user)
 {
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 066b100..4f54952 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -306,7 +306,8 @@ int clk_set_parent(struct clk *clk, struct clk *parent);
  * @clk: clock source
  *
  * Returns struct clk corresponding to parent clock source, or
- * valid IS_ERR() condition containing errno.
+ * valid IS_ERR() condition containing errno. Caller must call
+ * clk_put() to release the returned struct clk.
  */
 struct clk *clk_get_parent(struct clk *clk);
 
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [PATCH v10 2/9] clk: Move all drivers to use internal API
       [not found] ` <1410271497-27148-1-git-send-email-tomeu.vizoso@collabora.com>
@ 2014-09-09 19:12   ` Mike Turquette
  2014-09-09 19:25     ` Mike Turquette
  2014-09-10  7:36     ` Tomeu Vizoso
  0 siblings, 2 replies; 15+ messages in thread
From: Mike Turquette @ 2014-09-09 19:12 UTC (permalink / raw)
  To: Tomeu Vizoso; +Cc: linux-kernel, linux-arm-kernel, shawn.guo

Quoting Tomeu Vizoso (2014-09-09 07:04:57)
> In preparation to change the public API to return a per-user clk structure,
> remove any usage of this public API from the clock implementations.
> 
> The reason for having this in a separate commit from the one that introduces
> the implementation of the new functions is to separate the changes generated
> with Coccinelle from the rest, and keep the patches' size reasonable.
> 
> Signed-off-by: Tomeu Vizoso <tomeu.vizoso@collabora.com>
> Tested-by: Boris Brezillon <boris.brezillon@free-electrons.com>
> Tested-by: Heiko Stuebner <heiko@sntech.de>
> Acked-by: Boris Brezillon <boris.brezillon@free-electrons.com>
> 
> ---
> 
> v10: * Add a few more files to be converted
>      * Re-generate the patch on top of the latest changes

Hi Tomeu,

Generating this on top of linux-next is a no-go. I can't apply it to my
tree. The best thing is to generate it on top of -rc4, and that is what
I will merge.

Running the script against linux-next is still very useful and lets us
patch up the stuff that is not going through the clk tree. E.g. the LPSS
driver is already in mainline, so just running the semantic patch
against -rc4 is sufficient for it. However a patch like Shawn's "ARM:
imx: add an exclusive gate clock type" came in through the i.MX tree and
we'll need to patch it after the fact.

The best way to do that is for me to host a branch with just your
changes in it that everyone can pull in as a dependency with the same
commit ids.

<snip>

> diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c
> index bcbdbd2..f4c6ccf 100644
> --- a/drivers/acpi/acpi_lpss.c
> +++ b/drivers/acpi/acpi_lpss.c
> @@ -11,7 +11,6 @@
>   */
>  
>  #include <linux/acpi.h>
> -#include <linux/clk.h>
>  #include <linux/clkdev.h>
>  #include <linux/clk-provider.h>
>  #include <linux/err.h>
> @@ -78,7 +77,7 @@ struct lpss_private_data {
>         void __iomem *mmio_base;
>         resource_size_t mmio_size;
>         unsigned int fixed_clk_rate;
> -       struct clk *clk;
> +       struct clk_core *clk;
>         const struct lpss_device_desc *dev_desc;
>         u32 prv_reg_ctx[LPSS_PRV_REG_COUNT];
>  };
> @@ -229,7 +228,7 @@ static int register_device_clock(struct acpi_device *adev,
>  {
>         const struct lpss_device_desc *dev_desc = pdata->dev_desc;
>         const char *devname = dev_name(&adev->dev);
> -       struct clk *clk = ERR_PTR(-ENODEV);
> +       struct clk_core *clk = ERR_PTR(-ENODEV);
>         struct lpss_clk_data *clk_data;
>         const char *parent, *clk_name;
>         void __iomem *prv_base;

I think the following hunk is missing from your change:

--- a/drivers/acpi/acpi_lpss.c
+++ b/drivers/acpi/acpi_lpss.c
@@ -57,7 +57,7 @@ ACPI_MODULE_NAME("acpi_lpss");
 struct lpss_shared_clock {
        const char *name;
        unsigned long rate;
-       struct clk *clk;
+       struct clk_core *clk;
 };


Otherwise register_device_clock will blow up because we are assigning a
struct clk * to a struct clk_core *.

Do you mind testing with ARCH=x86_64 and allmodconfig? That will help
catch issues like this.

Regards,
Mike

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v10 2/9] clk: Move all drivers to use internal API
  2014-09-09 19:12   ` [PATCH v10 2/9] clk: Move all drivers to use internal API Mike Turquette
@ 2014-09-09 19:25     ` Mike Turquette
  2014-09-10  1:53       ` Stephen Boyd
  2014-09-10  8:38       ` Tomeu Vizoso
  2014-09-10  7:36     ` Tomeu Vizoso
  1 sibling, 2 replies; 15+ messages in thread
From: Mike Turquette @ 2014-09-09 19:25 UTC (permalink / raw)
  To: Tomeu Vizoso; +Cc: linux-kernel, linux-arm-kernel, shawn.guo

Quoting Mike Turquette (2014-09-09 12:12:05)
> Quoting Tomeu Vizoso (2014-09-09 07:04:57)
> > In preparation to change the public API to return a per-user clk structure,
> > remove any usage of this public API from the clock implementations.
> > 
> > The reason for having this in a separate commit from the one that introduces
> > the implementation of the new functions is to separate the changes generated
> > with Coccinelle from the rest, and keep the patches' size reasonable.
> > 
> > Signed-off-by: Tomeu Vizoso <tomeu.vizoso@collabora.com>
> > Tested-by: Boris Brezillon <boris.brezillon@free-electrons.com>
> > Tested-by: Heiko Stuebner <heiko@sntech.de>
> > Acked-by: Boris Brezillon <boris.brezillon@free-electrons.com>
> > 
> > ---
> > 
> > v10: * Add a few more files to be converted
> >      * Re-generate the patch on top of the latest changes
> 
> Hi Tomeu,
> 
> Generating this on top of linux-next is a no-go. I can't apply it to my
> tree. The best thing is to generate it on top of -rc4, and that is what
> I will merge.
> 
> Running the script against linux-next is still very useful and lets us
> patch up the stuff that is not going through the clk tree. E.g. the LPSS
> driver is already in mainline, so just running the semantic patch
> against -rc4 is sufficient for it. However a patch like Shawn's "ARM:
> imx: add an exclusive gate clock type" came in through the i.MX tree and
> we'll need to patch it after the fact.
> 
> The best way to do that is for me to host a branch with just your
> changes in it that everyone can pull in as a dependency with the same
> commit ids.
> 
> <snip>
> 
> > diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c
> > index bcbdbd2..f4c6ccf 100644
> > --- a/drivers/acpi/acpi_lpss.c
> > +++ b/drivers/acpi/acpi_lpss.c
> > @@ -11,7 +11,6 @@
> >   */
> >  
> >  #include <linux/acpi.h>
> > -#include <linux/clk.h>
> >  #include <linux/clkdev.h>
> >  #include <linux/clk-provider.h>
> >  #include <linux/err.h>
> > @@ -78,7 +77,7 @@ struct lpss_private_data {
> >         void __iomem *mmio_base;
> >         resource_size_t mmio_size;
> >         unsigned int fixed_clk_rate;
> > -       struct clk *clk;
> > +       struct clk_core *clk;
> >         const struct lpss_device_desc *dev_desc;
> >         u32 prv_reg_ctx[LPSS_PRV_REG_COUNT];
> >  };
> > @@ -229,7 +228,7 @@ static int register_device_clock(struct acpi_device *adev,
> >  {
> >         const struct lpss_device_desc *dev_desc = pdata->dev_desc;
> >         const char *devname = dev_name(&adev->dev);
> > -       struct clk *clk = ERR_PTR(-ENODEV);
> > +       struct clk_core *clk = ERR_PTR(-ENODEV);
> >         struct lpss_clk_data *clk_data;
> >         const char *parent, *clk_name;
> >         void __iomem *prv_base;
> 
> I think the following hunk is missing from your change:
> 
> --- a/drivers/acpi/acpi_lpss.c
> +++ b/drivers/acpi/acpi_lpss.c
> @@ -57,7 +57,7 @@ ACPI_MODULE_NAME("acpi_lpss");
>  struct lpss_shared_clock {
>         const char *name;
>         unsigned long rate;
> -       struct clk *clk;
> +       struct clk_core *clk;
>  };

Looks like this hunk is missing as well:

diff --git a/include/linux/platform_data/clk-lpss.h b/include/linux/platform_data/clk-lpss.h
index 2390199..3c3237c 100644
--- a/include/linux/platform_data/clk-lpss.h
+++ b/include/linux/platform_data/clk-lpss.h
@@ -15,7 +15,7 @@

 struct lpss_clk_data {
        const char *name;
-       struct clk *clk;
+       struct clk_core *clk;
 };



Without that change the following code will explode:


static int register_device_clock(struct acpi_device *adev,
                                 struct lpss_private_data *pdata)
{
        const struct lpss_device_desc *dev_desc = pdata->dev_desc;
        struct lpss_shared_clock *shared_clock = dev_desc->shared_clock;
        const char *devname = dev_name(&adev->dev);
        struct clk_core *clk = ERR_PTR(-ENODEV);
        struct lpss_clk_data *clk_data;
        const char *parent, *clk_name;
        void __iomem *prv_base;

        if (!lpss_clk_dev)
                lpt_register_clock_device();

        clk_data = platform_get_drvdata(lpss_clk_dev);
        if (!clk_data)
                return -ENODEV;

        if (dev_desc->clkdev_name) {
                clk_register_clkdev(clk_data->clk, dev_desc->clkdev_name,
                                    devname);
                return 0;
        }



I'm starting to get nervous about this Coccinelle script... Seems like a
lot of things are slipping through.

Regards,
Mike

> 
> 
> Otherwise register_device_clock will blow up because we are assigning a
> struct clk * to a struct clk_core *.
> 
> Do you mind testing with ARCH=x86_64 and allmodconfig? That will help
> catch issues like this.
> 
> Regards,
> Mike

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [PATCH v10 2/9] clk: Move all drivers to use internal API
  2014-09-09 19:25     ` Mike Turquette
@ 2014-09-10  1:53       ` Stephen Boyd
  2014-09-10  8:38       ` Tomeu Vizoso
  1 sibling, 0 replies; 15+ messages in thread
From: Stephen Boyd @ 2014-09-10  1:53 UTC (permalink / raw)
  To: Mike Turquette, Tomeu Vizoso; +Cc: shawn.guo, linux-kernel, linux-arm-kernel

On 09/09/14 12:25, Mike Turquette wrote:
>
> I'm starting to get nervous about this Coccinelle script... Seems like a
> lot of things are slipping through.
>

Do we need to make this huge invasive change to every clock driver? If
we gave every clk_hw instance it's own private struct clk pointer at
registration time and also created a pointer for the parents of the
clk_hw instance then we could use that pointer throughout the clock
provider drivers. This way we don't have to change any ops signatures
and we don't have to go through every clock provider and fix things up.
The good news is we already have this via hw->clk. We could also make
this an opt-in behavior where the clock provider could register clkdev
lookups and clock providers the old way or the new way. The new way
would be a different registration function and a different clk_src_get
function:

diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index 6dec0b306336..e82b3b987f63 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -573,6 +573,10 @@ int of_clk_add_provider(struct device_node *np,
                        struct clk *(*clk_src_get)(struct of_phandle_args *args,
                                                   void *data),
                        void *data);
+int of_clk_add_provider_hw(struct device_node *np,
+                       struct clk_hw *(*clk_src_get)(struct of_phandle_args *args,
+                                                  void *data),
+                       void *data);
 void of_clk_del_provider(struct device_node *np);
 struct clk *of_clk_src_simple_get(struct of_phandle_args *clkspec,
                                  void *data);

and add a new member to struct of_clk_provider for the new clk_src_get
prototype. Then the clkdev framework wouldn't even need to know in the
OF case that the struct clk pointer is dynamically allocated. If we
really want to pass that con_id and dev_id stuff down into the
allocation layer we can always change the of_clk_get_from_provider()
functions to take more arguments. Note that clk_register() stays the
same here because a clock pointer is always allocated at registration time.

Then we have clkdev_add() and friends to deal with in clkdev. Honestly,
the current patches make it really ugly inside clkdev.c with all those
#ifdefs and clk_core_t typedef. clk_get() and clk_put() are pretty much
different functions depending on if the ccf is used or not, so why even
combine the two together? The fundamental change here is that the clkdev
APIs are struct clk focused and they rely on the struct clk pointer
existing when the lookup is registered. We'd like to change that and
have clk_get() generate the struct clk on the fly. We can support both
at the same time if we do something like:

diff --git a/include/linux/clkdev.h b/include/linux/clkdev.h
index 94bad77eeb4a..5f8af5ec2565 100644
--- a/include/linux/clkdev.h
+++ b/include/linux/clkdev.h
@@ -15,6 +15,7 @@
 #include <asm/clkdev.h>
 
 struct clk;
+struct clk_hw;
 struct device;
 
 struct clk_lookup {
@@ -22,6 +23,9 @@ struct clk_lookup {
        const char              *dev_id;
        const char              *con_id;
        struct clk              *clk;
+#ifdef CONFIG_COMMON_CLK
+       struct clk_hw           *hw;
+#endif
 };
 
 #define CLKDEV_INIT(d, n, c)   \
@@ -41,6 +45,9 @@ void clkdev_add_table(struct clk_lookup *, size_t);
 int clk_add_alias(const char *, const char *, char *, struct device *);
 
 int clk_register_clkdev(struct clk *, const char *, const char *, ...);
+#ifdef CONFIG_COMMON_CLK
+int clk_register_clkdev_hw(struct clk_hw *, const char *, const char *, ...);
+#endif
 int clk_register_clkdevs(struct clk *, struct clk_lookup *, size_t);
 


And then have the clkdev code look for a struct clk_hw pointer in the
lookup. If such a pointer exists, call the ccf function to generate a
struct clk on the fly. Otherwise return the clk pointer that's there.

I must have missed something, perhaps statically allocated struct clk
pointers exist somewhere? Anyway, it seems possible to make this much
less invasive. I would think that we want to have struct clk used in the
clk_ops because that allows us to do per-user constraints for clocks
within the tree, instead of just supporting constraints at the user
boundary (basically we want every clk_hw to have a vote too).

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [PATCH v10 2/9] clk: Move all drivers to use internal API
  2014-09-09 19:12   ` [PATCH v10 2/9] clk: Move all drivers to use internal API Mike Turquette
  2014-09-09 19:25     ` Mike Turquette
@ 2014-09-10  7:36     ` Tomeu Vizoso
  1 sibling, 0 replies; 15+ messages in thread
From: Tomeu Vizoso @ 2014-09-10  7:36 UTC (permalink / raw)
  To: Mike Turquette; +Cc: linux-kernel, linux-arm-kernel, shawn.guo

On 09/09/2014 09:12 PM, Mike Turquette wrote:
> Quoting Tomeu Vizoso (2014-09-09 07:04:57)
>> In preparation to change the public API to return a per-user clk structure,
>> remove any usage of this public API from the clock implementations.
>>
>> The reason for having this in a separate commit from the one that introduces
>> the implementation of the new functions is to separate the changes generated
>> with Coccinelle from the rest, and keep the patches' size reasonable.
>>
>> Signed-off-by: Tomeu Vizoso <tomeu.vizoso@collabora.com>
>> Tested-by: Boris Brezillon <boris.brezillon@free-electrons.com>
>> Tested-by: Heiko Stuebner <heiko@sntech.de>
>> Acked-by: Boris Brezillon <boris.brezillon@free-electrons.com>
>>
>> ---
>>
>> v10: * Add a few more files to be converted
>>      * Re-generate the patch on top of the latest changes
> 
> Hi Tomeu,
> 
> Generating this on top of linux-next is a no-go. I can't apply it to my
> tree. The best thing is to generate it on top of -rc4, and that is what
> I will merge.

Makes sense now, will do that.

> Running the script against linux-next is still very useful and lets us
> patch up the stuff that is not going through the clk tree. E.g. the LPSS
> driver is already in mainline, so just running the semantic patch
> against -rc4 is sufficient for it. However a patch like Shawn's "ARM:
> imx: add an exclusive gate clock type" came in through the i.MX tree and
> we'll need to patch it after the fact.
> 
> The best way to do that is for me to host a branch with just your
> changes in it that everyone can pull in as a dependency with the same
> commit ids.

Sounds good to me.

> <snip>
> 
>> diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c
>> index bcbdbd2..f4c6ccf 100644
>> --- a/drivers/acpi/acpi_lpss.c
>> +++ b/drivers/acpi/acpi_lpss.c
>> @@ -11,7 +11,6 @@
>>   */
>>  
>>  #include <linux/acpi.h>
>> -#include <linux/clk.h>
>>  #include <linux/clkdev.h>
>>  #include <linux/clk-provider.h>
>>  #include <linux/err.h>
>> @@ -78,7 +77,7 @@ struct lpss_private_data {
>>         void __iomem *mmio_base;
>>         resource_size_t mmio_size;
>>         unsigned int fixed_clk_rate;
>> -       struct clk *clk;
>> +       struct clk_core *clk;
>>         const struct lpss_device_desc *dev_desc;
>>         u32 prv_reg_ctx[LPSS_PRV_REG_COUNT];
>>  };
>> @@ -229,7 +228,7 @@ static int register_device_clock(struct acpi_device *adev,
>>  {
>>         const struct lpss_device_desc *dev_desc = pdata->dev_desc;
>>         const char *devname = dev_name(&adev->dev);
>> -       struct clk *clk = ERR_PTR(-ENODEV);
>> +       struct clk_core *clk = ERR_PTR(-ENODEV);
>>         struct lpss_clk_data *clk_data;
>>         const char *parent, *clk_name;
>>         void __iomem *prv_base;
> 
> I think the following hunk is missing from your change:
> 
> --- a/drivers/acpi/acpi_lpss.c
> +++ b/drivers/acpi/acpi_lpss.c
> @@ -57,7 +57,7 @@ ACPI_MODULE_NAME("acpi_lpss");
>  struct lpss_shared_clock {
>         const char *name;
>         unsigned long rate;
> -       struct clk *clk;
> +       struct clk_core *clk;
>  };
> 
> 
> Otherwise register_device_clock will blow up because we are assigning a
> struct clk * to a struct clk_core *.

Yeah, that one isn't there because the code has been removed in
linux-next by this patch:

http://permalink.gmane.org/gmane.linux.acpi.devel/70205

> Do you mind testing with ARCH=x86_64 and allmodconfig? That will help
> catch issues like this.

Will do. I have been having trouble building in a finite amount of time
as many configs as I would have liked, and for some reason I'm not
getting 0day notifications. So sorry about that and I hope no more such
issues will slip through.

Regards,

Tomeu

> Regards,
> Mike
> 


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v10 2/9] clk: Move all drivers to use internal API
  2014-09-09 19:25     ` Mike Turquette
  2014-09-10  1:53       ` Stephen Boyd
@ 2014-09-10  8:38       ` Tomeu Vizoso
  2014-09-10 13:20         ` Tomeu Vizoso
  1 sibling, 1 reply; 15+ messages in thread
From: Tomeu Vizoso @ 2014-09-10  8:38 UTC (permalink / raw)
  To: Mike Turquette; +Cc: linux-kernel, linux-arm-kernel, shawn.guo

On 09/09/2014 09:25 PM, Mike Turquette wrote:
> Quoting Mike Turquette (2014-09-09 12:12:05)
>> Quoting Tomeu Vizoso (2014-09-09 07:04:57)
>>> In preparation to change the public API to return a per-user clk structure,
>>> remove any usage of this public API from the clock implementations.
>>>
>>> The reason for having this in a separate commit from the one that introduces
>>> the implementation of the new functions is to separate the changes generated
>>> with Coccinelle from the rest, and keep the patches' size reasonable.
>>>
>>> Signed-off-by: Tomeu Vizoso <tomeu.vizoso@collabora.com>
>>> Tested-by: Boris Brezillon <boris.brezillon@free-electrons.com>
>>> Tested-by: Heiko Stuebner <heiko@sntech.de>
>>> Acked-by: Boris Brezillon <boris.brezillon@free-electrons.com>
>>>
>>> ---
>>>
>>> v10: * Add a few more files to be converted
>>>      * Re-generate the patch on top of the latest changes
>>
>> Hi Tomeu,
>>
>> Generating this on top of linux-next is a no-go. I can't apply it to my
>> tree. The best thing is to generate it on top of -rc4, and that is what
>> I will merge.
>>
>> Running the script against linux-next is still very useful and lets us
>> patch up the stuff that is not going through the clk tree. E.g. the LPSS
>> driver is already in mainline, so just running the semantic patch
>> against -rc4 is sufficient for it. However a patch like Shawn's "ARM:
>> imx: add an exclusive gate clock type" came in through the i.MX tree and
>> we'll need to patch it after the fact.
>>
>> The best way to do that is for me to host a branch with just your
>> changes in it that everyone can pull in as a dependency with the same
>> commit ids.
>>
>> <snip>
>>
>>> diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c
>>> index bcbdbd2..f4c6ccf 100644
>>> --- a/drivers/acpi/acpi_lpss.c
>>> +++ b/drivers/acpi/acpi_lpss.c
>>> @@ -11,7 +11,6 @@
>>>   */
>>>  
>>>  #include <linux/acpi.h>
>>> -#include <linux/clk.h>
>>>  #include <linux/clkdev.h>
>>>  #include <linux/clk-provider.h>
>>>  #include <linux/err.h>
>>> @@ -78,7 +77,7 @@ struct lpss_private_data {
>>>         void __iomem *mmio_base;
>>>         resource_size_t mmio_size;
>>>         unsigned int fixed_clk_rate;
>>> -       struct clk *clk;
>>> +       struct clk_core *clk;
>>>         const struct lpss_device_desc *dev_desc;
>>>         u32 prv_reg_ctx[LPSS_PRV_REG_COUNT];
>>>  };
>>> @@ -229,7 +228,7 @@ static int register_device_clock(struct acpi_device *adev,
>>>  {
>>>         const struct lpss_device_desc *dev_desc = pdata->dev_desc;
>>>         const char *devname = dev_name(&adev->dev);
>>> -       struct clk *clk = ERR_PTR(-ENODEV);
>>> +       struct clk_core *clk = ERR_PTR(-ENODEV);
>>>         struct lpss_clk_data *clk_data;
>>>         const char *parent, *clk_name;
>>>         void __iomem *prv_base;
>>
>> I think the following hunk is missing from your change:
>>
>> --- a/drivers/acpi/acpi_lpss.c
>> +++ b/drivers/acpi/acpi_lpss.c
>> @@ -57,7 +57,7 @@ ACPI_MODULE_NAME("acpi_lpss");
>>  struct lpss_shared_clock {
>>         const char *name;
>>         unsigned long rate;
>> -       struct clk *clk;
>> +       struct clk_core *clk;
>>  };
> 
> Looks like this hunk is missing as well:
> 
> diff --git a/include/linux/platform_data/clk-lpss.h b/include/linux/platform_data/clk-lpss.h
> index 2390199..3c3237c 100644
> --- a/include/linux/platform_data/clk-lpss.h
> +++ b/include/linux/platform_data/clk-lpss.h
> @@ -15,7 +15,7 @@
> 
>  struct lpss_clk_data {
>         const char *name;
> -       struct clk *clk;
> +       struct clk_core *clk;
>  };
> 
> 
> 
> Without that change the following code will explode:
> 
> 
> static int register_device_clock(struct acpi_device *adev,
>                                  struct lpss_private_data *pdata)
> {
>         const struct lpss_device_desc *dev_desc = pdata->dev_desc;
>         struct lpss_shared_clock *shared_clock = dev_desc->shared_clock;
>         const char *devname = dev_name(&adev->dev);
>         struct clk_core *clk = ERR_PTR(-ENODEV);
>         struct lpss_clk_data *clk_data;
>         const char *parent, *clk_name;
>         void __iomem *prv_base;
> 
>         if (!lpss_clk_dev)
>                 lpt_register_clock_device();
> 
>         clk_data = platform_get_drvdata(lpss_clk_dev);
>         if (!clk_data)
>                 return -ENODEV;
> 
>         if (dev_desc->clkdev_name) {
>                 clk_register_clkdev(clk_data->clk, dev_desc->clkdev_name,
>                                     devname);
>                 return 0;
>         }
> 
> 
> 
> I'm starting to get nervous about this Coccinelle script... Seems like a
> lot of things are slipping through.

I understand your concern. The Coccinelle part of it is very simple, and
so far I haven't seen any problem caused by it. The step that is manual
and that thus is prone to errors is listing the files that need to be
transformed (clock_impl.txt).

What I do to check that there aren't more files that need to be added is
to grep for all files that contain "clk_ops" or include
"clk-provider.h", diff it with the existing clock_impl.txt and visually
inspect each of the new files to see if they are indeed clock
implementations or helpers for them.

The most problematic part of the process are the headers that define
structs that are shared between clock implementations (and sometimes
between both clock drivers and consumers), as is this case. So far I
have only been able to find out what headers need modification by
building and fixing the warnings. And as you have seen, I haven't been
able to test builds as extensively as it would have been ideal.

Was hoping that Intel's 0day build farm would help finding those, but
there seems to be some problem with it and I'm not getting any reports.
Have just asked Fengguang about it.

In the meantime I'm going to make my build script smarter and only spend
time checking bisectability after I'm sure that the head builds fine in
a fair set of defconfigs for all arches.

Cheers,

Tomeu

> Regards,
> Mike
> 
>>
>>
>> Otherwise register_device_clock will blow up because we are assigning a
>> struct clk * to a struct clk_core *.
>>
>> Do you mind testing with ARCH=x86_64 and allmodconfig? That will help
>> catch issues like this.
>>
>> Regards,
>> Mike


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v10 2/9] clk: Move all drivers to use internal API
  2014-09-10  8:38       ` Tomeu Vizoso
@ 2014-09-10 13:20         ` Tomeu Vizoso
  0 siblings, 0 replies; 15+ messages in thread
From: Tomeu Vizoso @ 2014-09-10 13:20 UTC (permalink / raw)
  To: Mike Turquette; +Cc: linux-kernel, linux-arm-kernel, Shawn Guo

On 10 September 2014 10:38, Tomeu Vizoso <tomeu.vizoso@collabora.com> wrote:
> On 09/09/2014 09:25 PM, Mike Turquette wrote:
>> Quoting Mike Turquette (2014-09-09 12:12:05)
>>> Quoting Tomeu Vizoso (2014-09-09 07:04:57)
>>>> In preparation to change the public API to return a per-user clk structure,
>>>> remove any usage of this public API from the clock implementations.
>>>>
>>>> The reason for having this in a separate commit from the one that introduces
>>>> the implementation of the new functions is to separate the changes generated
>>>> with Coccinelle from the rest, and keep the patches' size reasonable.
>>>>
>>>> Signed-off-by: Tomeu Vizoso <tomeu.vizoso@collabora.com>
>>>> Tested-by: Boris Brezillon <boris.brezillon@free-electrons.com>
>>>> Tested-by: Heiko Stuebner <heiko@sntech.de>
>>>> Acked-by: Boris Brezillon <boris.brezillon@free-electrons.com>
>>>>
>>>> ---
>>>>
>>>> v10: * Add a few more files to be converted
>>>>      * Re-generate the patch on top of the latest changes
>>>
>>> Hi Tomeu,
>>>
>>> Generating this on top of linux-next is a no-go. I can't apply it to my
>>> tree. The best thing is to generate it on top of -rc4, and that is what
>>> I will merge.
>>>
>>> Running the script against linux-next is still very useful and lets us
>>> patch up the stuff that is not going through the clk tree. E.g. the LPSS
>>> driver is already in mainline, so just running the semantic patch
>>> against -rc4 is sufficient for it. However a patch like Shawn's "ARM:
>>> imx: add an exclusive gate clock type" came in through the i.MX tree and
>>> we'll need to patch it after the fact.
>>>
>>> The best way to do that is for me to host a branch with just your
>>> changes in it that everyone can pull in as a dependency with the same
>>> commit ids.
>>>
>>> <snip>
>>>
>>>> diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c
>>>> index bcbdbd2..f4c6ccf 100644
>>>> --- a/drivers/acpi/acpi_lpss.c
>>>> +++ b/drivers/acpi/acpi_lpss.c
>>>> @@ -11,7 +11,6 @@
>>>>   */
>>>>
>>>>  #include <linux/acpi.h>
>>>> -#include <linux/clk.h>
>>>>  #include <linux/clkdev.h>
>>>>  #include <linux/clk-provider.h>
>>>>  #include <linux/err.h>
>>>> @@ -78,7 +77,7 @@ struct lpss_private_data {
>>>>         void __iomem *mmio_base;
>>>>         resource_size_t mmio_size;
>>>>         unsigned int fixed_clk_rate;
>>>> -       struct clk *clk;
>>>> +       struct clk_core *clk;
>>>>         const struct lpss_device_desc *dev_desc;
>>>>         u32 prv_reg_ctx[LPSS_PRV_REG_COUNT];
>>>>  };
>>>> @@ -229,7 +228,7 @@ static int register_device_clock(struct acpi_device *adev,
>>>>  {
>>>>         const struct lpss_device_desc *dev_desc = pdata->dev_desc;
>>>>         const char *devname = dev_name(&adev->dev);
>>>> -       struct clk *clk = ERR_PTR(-ENODEV);
>>>> +       struct clk_core *clk = ERR_PTR(-ENODEV);
>>>>         struct lpss_clk_data *clk_data;
>>>>         const char *parent, *clk_name;
>>>>         void __iomem *prv_base;
>>>
>>> I think the following hunk is missing from your change:
>>>
>>> --- a/drivers/acpi/acpi_lpss.c
>>> +++ b/drivers/acpi/acpi_lpss.c
>>> @@ -57,7 +57,7 @@ ACPI_MODULE_NAME("acpi_lpss");
>>>  struct lpss_shared_clock {
>>>         const char *name;
>>>         unsigned long rate;
>>> -       struct clk *clk;
>>> +       struct clk_core *clk;
>>>  };
>>
>> Looks like this hunk is missing as well:
>>
>> diff --git a/include/linux/platform_data/clk-lpss.h b/include/linux/platform_data/clk-lpss.h
>> index 2390199..3c3237c 100644
>> --- a/include/linux/platform_data/clk-lpss.h
>> +++ b/include/linux/platform_data/clk-lpss.h
>> @@ -15,7 +15,7 @@
>>
>>  struct lpss_clk_data {
>>         const char *name;
>> -       struct clk *clk;
>> +       struct clk_core *clk;
>>  };
>>
>>
>>
>> Without that change the following code will explode:
>>
>>
>> static int register_device_clock(struct acpi_device *adev,
>>                                  struct lpss_private_data *pdata)
>> {
>>         const struct lpss_device_desc *dev_desc = pdata->dev_desc;
>>         struct lpss_shared_clock *shared_clock = dev_desc->shared_clock;
>>         const char *devname = dev_name(&adev->dev);
>>         struct clk_core *clk = ERR_PTR(-ENODEV);
>>         struct lpss_clk_data *clk_data;
>>         const char *parent, *clk_name;
>>         void __iomem *prv_base;
>>
>>         if (!lpss_clk_dev)
>>                 lpt_register_clock_device();
>>
>>         clk_data = platform_get_drvdata(lpss_clk_dev);
>>         if (!clk_data)
>>                 return -ENODEV;
>>
>>         if (dev_desc->clkdev_name) {
>>                 clk_register_clkdev(clk_data->clk, dev_desc->clkdev_name,
>>                                     devname);
>>                 return 0;
>>         }
>>
>>
>>
>> I'm starting to get nervous about this Coccinelle script... Seems like a
>> lot of things are slipping through.
>
> I understand your concern. The Coccinelle part of it is very simple, and
> so far I haven't seen any problem caused by it. The step that is manual
> and that thus is prone to errors is listing the files that need to be
> transformed (clock_impl.txt).
>
> What I do to check that there aren't more files that need to be added is
> to grep for all files that contain "clk_ops" or include
> "clk-provider.h", diff it with the existing clock_impl.txt and visually
> inspect each of the new files to see if they are indeed clock
> implementations or helpers for them.
>
> The most problematic part of the process are the headers that define
> structs that are shared between clock implementations (and sometimes
> between both clock drivers and consumers), as is this case. So far I
> have only been able to find out what headers need modification by
> building and fixing the warnings. And as you have seen, I haven't been
> able to test builds as extensively as it would have been ideal.
>
> Was hoping that Intel's 0day build farm would help finding those, but
> there seems to be some problem with it and I'm not getting any reports.
> Have just asked Fengguang about it.

Just an update on this. Fengguang manually enqueued a build of my v10
branch a few hours ago, and I'm currently running a series of build
tests locally on my v11 branch, which is rebased on top of 3.17rc4:

http://cgit.collabora.com/git/user/tomeu/linux.git/log/?h=clk-refactoring-11

Regards,

Tomeu

> In the meantime I'm going to make my build script smarter and only spend
> time checking bisectability after I'm sure that the head builds fine in
> a fair set of defconfigs for all arches.
>
> Cheers,
>
> Tomeu
>
>> Regards,
>> Mike
>>
>>>
>>>
>>> Otherwise register_device_clock will blow up because we are assigning a
>>> struct clk * to a struct clk_core *.
>>>
>>> Do you mind testing with ARCH=x86_64 and allmodconfig? That will help
>>> catch issues like this.
>>>
>>> Regards,
>>> Mike
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2014-09-10 13:20 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-09-09 14:02 [PATCH v10 0/9] Per-user clock constraints Tomeu Vizoso
2014-09-09 14:02 ` [PATCH v10 1/9] clk: Add temporary mapping to the existing API Tomeu Vizoso
2014-09-09 14:06 ` [PATCH v10 3/9] clk: use struct clk only for external API Tomeu Vizoso
2014-09-09 14:06   ` [PATCH v10 4/9] clk: per-user clock accounting for debug Tomeu Vizoso
2014-09-09 14:06   ` [PATCH v10 5/9] clk: Add floor and ceiling constraints to clock rates Tomeu Vizoso
2014-09-09 14:06   ` [PATCH v10 6/9] clk: Warn of unbalanced clk_prepare() calls Tomeu Vizoso
2014-09-09 14:06   ` [PATCH v10 7/9] clk: Take the prepare lock when updating the list of per-user clks Tomeu Vizoso
2014-09-09 14:06   ` [PATCH v10 8/9] clk: Take the prepare lock when updating the per-user constraints Tomeu Vizoso
2014-09-09 14:06   ` [PATCH v10 9/9] clk: Add docs about calling clk_put after clk_get_parent Tomeu Vizoso
     [not found] ` <1410271497-27148-1-git-send-email-tomeu.vizoso@collabora.com>
2014-09-09 19:12   ` [PATCH v10 2/9] clk: Move all drivers to use internal API Mike Turquette
2014-09-09 19:25     ` Mike Turquette
2014-09-10  1:53       ` Stephen Boyd
2014-09-10  8:38       ` Tomeu Vizoso
2014-09-10 13:20         ` Tomeu Vizoso
2014-09-10  7:36     ` Tomeu Vizoso

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).