Commit 5617c122 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux

Pull clk framework updates from Stephen Boyd:
 "The core clk framework changes are small again. They're mostly minor
  fixes that weren't causing enough problems (or any problems when we're
  just clarifying things) to warrant sending outside the merge window.
  The majority of changes are in drivers for various SoCs. Full details
  are in the logs, but here's the summary.

  Core:

   - Better support for DeviceTree overlays with the addition of the
     CLK_OF_DECLARE_DRIVER macro. Now we won't probe a clk driver for a
     device node that matched during of_clk_init(), unless the driver
     uses CLK_OF_DECLARE_DRIVER instead of CLK_OF_DECLARE. This allows
     overlays to work cleanly for drivers that must probe before the
     device model is ready, and also after it's ready when an overlay is
     loaded.

   - Clarification in the code around how clk_hw pointers are returned
     from of clk providers

   - Proper migration of prepare/enable counts to parents when the clk
     tree is constructed

  New Drivers:

   - Socionext's UniPhier SoCs
   - Loongson1C
   - ZTE ZX296718
   - Qualcomm MDM9615
   - Amlogic GXBB AO clocks and resets
   - Broadcom BCM53573 ILP
   - Maxim MAX77620

 Updates:

   - Four Allwinner SoCs are migrated to the new style clk driver (A31,
     A31s, A23 and A33)
   - Exynos 5xxx audio and DRAM clks
   - Loongson1B AC97, DMA and NAND clks
   - Rockchip DDR clks and rk3399 driver tweaks
   - Renesas R-Car M3-W (r8a7796) SoC SDHI interface and Watchdog timer
     clks
   - Renasas R-Car H3 and M3-W CMT clks and RAVB+Thermal clks for M3-W
   - Amlogic GXBB MMC gate clks
   - at91 sama5d4 sckc
   - Removal of STiH415 and STiH416 clk support as the SoC is being
     removed
   - Rework of STiH4xx clk support for new style bindings
   - Continuation of driver migration to clk_hw based registration APIs
   - xgene PMD support
   - bcm2835 critical clk markings
   - ARM versatile ICST"

* tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux: (199 commits)
  CLK: Add Loongson1C clock support
  clk: Loongson1: Make use of GENMASK
  clk: Loongson1: Update clocks of Loongson1B
  clk: Loongson1: Refactor Loongson1 clock
  clk: change the type of clk_hw_onecell_data.num to unsigned int
  clk: zx296718: register driver earlier with core_initcall
  clk: mvebu: dynamically allocate resources in Armada CP110 system controller
  clk: mvebu: fix setting unwanted flags in CP110 gate clock
  clk: nxp: clk-lpc32xx: Unmap region obtained by of_iomap
  clk: mediatek: clk-mt8173: Unmap region obtained by of_iomap
  clk: sunxi-ng: Fix reset offset for the A23 and A33
  clk: at91: sckc: optimize boot time
  clk: at91: Add sama5d4 sckc support
  clk: at91: move slow clock controller clocks to sckc.c
  clk: imx6: initialize GPU clocks
  clk: imx6: fix i.MX6DL clock tree to reflect reality
  clk: imx53: Add clocks configuration
  clk: uniphier: add clock data for UniPhier SoCs
  clk: uniphier: add core support code for UniPhier clock driver
  clk: bcm: Add driver for BCM53573 ILP clock
  ...
parents 77b0a4aa b4626a7f
......@@ -5,7 +5,8 @@ The Mediatek apmixedsys controller provides the PLLs to the system.
Required Properties:
- compatible: Should be:
- compatible: Should be one of:
- "mediatek,mt2701-apmixedsys"
- "mediatek,mt8135-apmixedsys"
- "mediatek,mt8173-apmixedsys"
- #clock-cells: Must be 1
......
Mediatek bdpsys controller
============================
The Mediatek bdpsys controller provides various clocks to the system.
Required Properties:
- compatible: Should be:
- "mediatek,mt2701-bdpsys", "syscon"
- #clock-cells: Must be 1
The bdpsys controller uses the common clk binding from
Documentation/devicetree/bindings/clock/clock-bindings.txt
The available clocks are defined in dt-bindings/clock/mt*-clk.h.
Example:
bdpsys: clock-controller@1c000000 {
compatible = "mediatek,mt2701-bdpsys", "syscon";
reg = <0 0x1c000000 0 0x1000>;
#clock-cells = <1>;
};
Mediatek ethsys controller
============================
The Mediatek ethsys controller provides various clocks to the system.
Required Properties:
- compatible: Should be:
- "mediatek,mt2701-ethsys", "syscon"
- #clock-cells: Must be 1
The ethsys controller uses the common clk binding from
Documentation/devicetree/bindings/clock/clock-bindings.txt
The available clocks are defined in dt-bindings/clock/mt*-clk.h.
Example:
ethsys: clock-controller@1b000000 {
compatible = "mediatek,mt2701-ethsys", "syscon";
reg = <0 0x1b000000 0 0x1000>;
#clock-cells = <1>;
};
Mediatek hifsys controller
============================
The Mediatek hifsys controller provides various clocks and reset
outputs to the system.
Required Properties:
- compatible: Should be:
- "mediatek,mt2701-hifsys", "syscon"
- #clock-cells: Must be 1
The hifsys controller uses the common clk binding from
Documentation/devicetree/bindings/clock/clock-bindings.txt
The available clocks are defined in dt-bindings/clock/mt*-clk.h.
Example:
hifsys: clock-controller@1a000000 {
compatible = "mediatek,mt2701-hifsys", "syscon";
reg = <0 0x1a000000 0 0x1000>;
#clock-cells = <1>;
#reset-cells = <1>;
};
......@@ -5,7 +5,8 @@ The Mediatek imgsys controller provides various clocks to the system.
Required Properties:
- compatible: Should be:
- compatible: Should be one of:
- "mediatek,mt2701-imgsys", "syscon"
- "mediatek,mt8173-imgsys", "syscon"
- #clock-cells: Must be 1
......
......@@ -6,7 +6,8 @@ outputs to the system.
Required Properties:
- compatible: Should be:
- compatible: Should be one of:
- "mediatek,mt2701-infracfg", "syscon"
- "mediatek,mt8135-infracfg", "syscon"
- "mediatek,mt8173-infracfg", "syscon"
- #clock-cells: Must be 1
......
......@@ -5,7 +5,8 @@ The Mediatek mmsys controller provides various clocks to the system.
Required Properties:
- compatible: Should be:
- compatible: Should be one of:
- "mediatek,mt2701-mmsys", "syscon"
- "mediatek,mt8173-mmsys", "syscon"
- #clock-cells: Must be 1
......
......@@ -6,7 +6,8 @@ outputs to the system.
Required Properties:
- compatible: Should be:
- compatible: Should be one of:
- "mediatek,mt2701-pericfg", "syscon"
- "mediatek,mt8135-pericfg", "syscon"
- "mediatek,mt8173-pericfg", "syscon"
- #clock-cells: Must be 1
......
......@@ -5,7 +5,8 @@ The Mediatek topckgen controller provides various clocks to the system.
Required Properties:
- compatible: Should be:
- compatible: Should be one of:
- "mediatek,mt2701-topckgen"
- "mediatek,mt8135-topckgen"
- "mediatek,mt8173-topckgen"
- #clock-cells: Must be 1
......
......@@ -5,7 +5,8 @@ The Mediatek vdecsys controller provides various clocks to the system.
Required Properties:
- compatible: Should be:
- compatible: Should be one of:
- "mediatek,mt2701-vdecsys", "syscon"
- "mediatek,mt8173-vdecsys", "syscon"
- #clock-cells: Must be 1
......
* Amlogic GXBB AO Clock and Reset Unit
The Amlogic GXBB AO clock controller generates and supplies clock to various
controllers within the Always-On part of the SoC.
Required Properties:
- compatible: should be "amlogic,gxbb-aoclkc"
- reg: physical base address of the clock controller and length of memory
mapped region.
- #clock-cells: should be 1.
Each clock is assigned an identifier and client nodes can use this identifier
to specify the clock which they consume. All available clocks are defined as
preprocessor macros in the dt-bindings/clock/gxbb-aoclkc.h header and can be
used in device tree sources.
- #reset-cells: should be 1.
Each reset is assigned an identifier and client nodes can use this identifier
to specify the reset which they consume. All available resets are defined as
preprocessor macros in the dt-bindings/reset/gxbb-aoclkc.h header and can be
used in device tree sources.
Example: AO Clock controller node:
clkc_AO: clock-controller@040 {
compatible = "amlogic,gxbb-aoclkc";
reg = <0x0 0x040 0x0 0x4>;
#clock-cells = <1>;
#reset-cells = <1>;
};
Example: UART controller node that consumes the clock and reset generated
by the clock controller:
uart_AO: serial@4c0 {
compatible = "amlogic,meson-uart";
reg = <0x4c0 0x14>;
interrupts = <0 90 1>;
clocks = <&clkc_AO CLKID_AO_UART1>;
resets = <&clkc_AO RESET_AO_UART1>;
status = "disabled";
};
......@@ -5,20 +5,50 @@ Technology (IDT). ARM integrated these oscillators deeply into their
reference designs by adding special control registers that manage such
oscillators to their system controllers.
The ARM system controller contains logic to serialize and initialize
The various ARM system controllers contain logic to serialize and initialize
an ICST clock request after a write to the 32 bit register at an offset
into the system controller. Furthermore, to even be able to alter one of
these frequencies, the system controller must first be unlocked by
writing a special token to another offset in the system controller.
Some ARM hardware contain special versions of the serial interface that only
connects the low 8 bits of the VDW (missing one bit), hardwires RDW to
different values and sometimes also hardwire the output divider. They
therefore have special compatible strings as per this table (the OD value is
the value on the pins, not the resulting output divider):
Hardware variant: RDW OD VDW
Integrator/AP 22 1 Bit 8 0, rest variable
integratorap-cm
Integrator/AP 46 3 Bit 8 0, rest variable
integratorap-sys
Integrator/AP 22 or 1 17 or (33 or 25 MHz)
integratorap-pci 14 1 14
Integrator/CP 22 variable Bit 8 0, rest variable
integratorcp-cm-core
Integrator/CP 22 variable Bit 8 0, rest variable
integratorcp-cm-mem
The ICST oscillator must be provided inside a system controller node.
Required properties:
- compatible: must be one of
"arm,syscon-icst525"
"arm,syscon-icst307"
"arm,syscon-icst525-integratorap-cm"
"arm,syscon-icst525-integratorap-sys"
"arm,syscon-icst525-integratorap-pci"
"arm,syscon-icst525-integratorcp-cm-core"
"arm,syscon-icst525-integratorcp-cm-mem"
- lock-offset: the offset address into the system controller where the
unlocking register is located
- vco-offset: the offset address into the system controller where the
ICST control register is located (even 32 bit address)
- compatible: must be one of "arm,syscon-icst525" or "arm,syscon-icst307"
- #clock-cells: must be <0>
- clocks: parent clock, since the ICST needs a parent clock to derive its
frequency from, this attribute is compulsory.
......
* Peripheral Clock bindings for Marvell Armada 37xx SoCs
Marvell Armada 37xx SoCs provide peripheral clocks which are
used as clock source for the peripheral of the SoC.
There are two different blocks associated to north bridge and south
bridge.
The peripheral clock consumer should specify the desired clock by
having the clock ID in its "clocks" phandle cell.
The following is a list of provided IDs for Armada 370 North bridge clocks:
ID Clock name Description
-----------------------------------
0 mmc MMC controller
1 sata_host Sata Host
2 sec_at Security AT
3 sac_dap Security DAP
4 tsecm Security Engine
5 setm_tmx Serial Embedded Trace Module
6 avs Adaptive Voltage Scaling
7 sqf SPI
8 pwm PWM
9 i2c_2 I2C 2
10 i2c_1 I2C 1
11 ddr_phy DDR PHY
12 ddr_fclk DDR F clock
13 trace Trace
14 counter Counter
15 eip97 EIP 97
16 cpu CPU
The following is a list of provided IDs for Armada 370 South bridge clocks:
ID Clock name Description
-----------------------------------
0 gbe-50 50 MHz parent clock for Gigabit Ethernet
1 gbe-core parent clock for Gigabit Ethernet core
2 gbe-125 125 MHz parent clock for Gigabit Ethernet
3 gbe1-50 50 MHz clock for Gigabit Ethernet port 1
4 gbe0-50 50 MHz clock for Gigabit Ethernet port 0
5 gbe1-125 125 MHz clock for Gigabit Ethernet port 1
6 gbe0-125 125 MHz clock for Gigabit Ethernet port 0
7 gbe1-core Gigabit Ethernet core port 1
8 gbe0-core Gigabit Ethernet core port 0
9 gbe-bm Gigabit Ethernet Buffer Manager
10 sdio SDIO
11 usb32-sub2-sys USB 2 clock
12 usb32-ss-sys USB 3 clock
Required properties:
- compatible : shall be "marvell,armada-3700-periph-clock-nb" for the
north bridge block, or
"marvell,armada-3700-periph-clock-sb" for the south bridge block
- reg : must be the register address of North/South Bridge Clock register
- #clock-cells : from common clock binding; shall be set to 1
- clocks : list of the parent clock phandle in the following order:
TBG-A P, TBG-B P, TBG-A S, TBG-B S and finally the xtal clock.
Example:
nb_perih_clk: nb-periph-clk@13000{
compatible = "marvell,armada-3700-periph-clock-nb";
reg = <0x13000 0x1000>;
clocks = <&tbg 0>, <&tbg 1>, <&tbg 2>,
<&tbg 3>, <&xtalclk>;
#clock-cells = <1>;
};
* Time Base Generator Clock bindings for Marvell Armada 37xx SoCs
Marvell Armada 37xx SoCs provde Time Base Generator clocks which are
used as parent clocks for the peripheral clocks.
The TBG clock consumer should specify the desired clock by having the
clock ID in its "clocks" phandle cell.
The following is a list of provided IDs and clock names on Armada 3700:
0 = TBG A P
1 = TBG B P
2 = TBG A S
3 = TBG B S
Required properties:
- compatible : shall be "marvell,armada-3700-tbg-clock"
- reg : must be the register address of North Bridge PLL register
- #clock-cells : from common clock binding; shall be set to 1
Example:
tbg: tbg@13200 {
compatible = "marvell,armada-3700-tbg-clock";
reg = <0x13200 0x1000>;
clocks = <&xtalclk>;
#clock-cells = <1>;
};
* Xtal Clock bindings for Marvell Armada 37xx SoCs
Marvell Armada 37xx SoCs allow to determine the xtal clock frequencies by
reading the gpio latch register.
This node must be a subnode of the node exposing the register address
of the GPIO block where the gpio latch is located.
Required properties:
- compatible : shall be one of the following:
"marvell,armada-3700-xtal-clock"
- #clock-cells : from common clock binding; shall be set to 0
Optional properties:
- clock-output-names : from common clock binding; allows overwrite default clock
output names ("xtal")
Example:
gpio1: gpio@13800 {
compatible = "marvell,armada-3700-gpio", "syscon", "simple-mfd";
reg = <0x13800 0x1000>;
xtalclk: xtal-clk {
compatible = "marvell,armada-3700-xtal-clock";
clock-output-names = "xtal";
#clock-cells = <0>;
};
};
......@@ -6,7 +6,8 @@ This binding uses the common clock binding[1].
Required properties:
- compatible : shall be one of the following:
"atmel,at91sam9x5-sckc":
"atmel,at91sam9x5-sckc" or
"atmel,sama5d4-sckc":
at91 SCKC (Slow Clock Controller)
This node contains the slow clock definitions.
......
Broadcom BCM53573 ILP clock
===========================
This binding uses the common clock binding:
Documentation/devicetree/bindings/clock/clock-bindings.txt
This binding is used for ILP clock (sometimes referred as "slow clock")
on Broadcom BCM53573 devices using Cortex-A7 CPU.
ILP's rate has to be calculated on runtime and it depends on ALP clock
which has to be referenced.
This clock is part of PMU (Power Management Unit), a Broadcom's device
handing power-related aspects. Its node must be sub-node of the PMU
device.
Required properties:
- compatible: "brcm,bcm53573-ilp"
- clocks: has to reference an ALP clock
- #clock-cells: should be <0>
- clock-output-names: from common clock bindings, should contain clock
name
Example:
pmu@18012000 {
compatible = "simple-mfd", "syscon";
reg = <0x18012000 0x00001000>;
ilp {
compatible = "brcm,bcm53573-ilp";
clocks = <&alp>;
#clock-cells = <0>;
clock-output-names = "ilp";
};
};
......@@ -10,6 +10,8 @@ Required Properties:
- "samsung,exynos4210-audss-clock" - controller compatible with all Exynos4 SoCs.
- "samsung,exynos5250-audss-clock" - controller compatible with Exynos5250
SoCs.
- "samsung,exynos5410-audss-clock" - controller compatible with Exynos5410
SoCs.
- "samsung,exynos5420-audss-clock" - controller compatible with Exynos5420
SoCs.
- reg: physical base address and length of the controller's register set.
......@@ -91,5 +93,5 @@ i2s0: i2s@03830000 {
<&clock_audss EXYNOS_MOUT_AUDSS>,
<&clock_audss EXYNOS_MOUT_I2S>;
clock-names = "iis", "i2s_opclk0", "i2s_opclk1",
"mout_audss", "mout_i2s";
"mout_audss", "mout_i2s";
};
......@@ -12,24 +12,29 @@ Required Properties:
- #clock-cells: should be 1.
- clocks: should contain an entry specifying the root clock from external
oscillator supplied through XXTI or XusbXTI pin. This clock should be
defined using standard clock bindings with "fin_pll" clock-output-name.
That clock is being passed internally to the 9 PLLs.
All available clocks are defined as preprocessor macros in
dt-bindings/clock/exynos5410.h header and can be used in device
tree sources.
External clock:
There is clock that is generated outside the SoC. It
is expected that it is defined using standard clock bindings
with following clock-output-name:
- "fin_pll" - PLL input clock from XXTI
Example 1: An example of a clock controller node is listed below.
fin_pll: xxti {
compatible = "fixed-clock";
clock-frequency = <24000000>;
clock-output-names = "fin_pll";
#clock-cells = <0>;
};
clock: clock-controller@0x10010000 {
compatible = "samsung,exynos5410-clock";
reg = <0x10010000 0x30000>;
#clock-cells = <1>;
clocks = <&fin_pll>;
};
Example 2: UART controller node that consumes the clock generated by the clock
......
Binding for Maxim MAX77686 32k clock generator block
Binding for Maxim MAX77686/MAX77802/MAX77620 32k clock generator block
This is a part of device tree bindings of MAX77686 multi-function device.
More information can be found in bindings/mfd/max77686.txt file.
This is a part of device tree bindings of MAX77686/MAX77802/MAX77620
multi-function device. More information can be found in MFD DT binding
doc as follows:
bindings/mfd/max77686.txt for MAX77686 and
bindings/mfd/max77802.txt for MAX77802 and
bindings/mfd/max77620.txt for MAX77620.
The MAX77686 contains three 32.768khz clock outputs that can be controlled
(gated/ungated) over I2C.
(gated/ungated) over I2C. Clocks are defined as preprocessor macros in
dt-bindings/clock/maxim,max77686.h.
The MAX77802 contains two 32.768khz clock outputs that can be controlled
(gated/ungated) over I2C. Clocks are defined as preprocessor macros in
dt-bindings/clock/maxim,max77802.h.
The MAX77686 contains one 32.768khz clock outputs that can be controlled
(gated/ungated) over I2C. Clocks are defined as preprocessor macros in
dt-bindings/clock/maxim,max77620.h.
Following properties should be presend in main device node of the MFD chip.
......@@ -17,30 +31,84 @@ Optional properties:
Each clock is assigned an identifier and client nodes can use this identifier
to specify the clock which they consume. Following indices are allowed:
- 0: 32khz_ap clock,
- 1: 32khz_cp clock,
- 2: 32khz_pmic clock.
- 0: 32khz_ap clock (max77686, max77802), 32khz_out0 (max77620)
- 1: 32khz_cp clock (max77686, max77802),
- 2: 32khz_pmic clock (max77686).
Clocks are defined as preprocessor macros in above dt-binding header for
respective chips.
Example:
1. With MAX77686:
#include <dt-bindings/clock/maxim,max77686.h>
/* ... */
Node of the MFD chip
max77686: max77686@09 {
compatible = "maxim,max77686";
interrupt-parent = <&wakeup_eint>;
interrupts = <26 0>;
reg = <0x09>;
#clock-cells = <1>;
/* ... */
};
Clock consumer node
foo@0 {
compatible = "bar,foo";
/* ... */
clock-names = "my-clock";
clocks = <&max77686 MAX77686_CLK_PMIC>;
};
2. With MAX77802:
#include <dt-bindings/clock/maxim,max77802.h>
/* ... */
Node of the MFD chip
max77802: max77802@09 {
compatible = "maxim,max77802";
interrupt-parent = <&wakeup_eint>;
interrupts = <26 0>;
reg = <0x09>;
#clock-cells = <1>;
/* ... */
};
Clock consumer node
foo@0 {
compatible = "bar,foo";
/* ... */
clock-names = "my-clock";
clocks = <&max77802 MAX77802_CLK_32K_AP>;
};
Clocks are defined as preprocessor macros in dt-bindings/clock/maxim,max77686.h
header and can be used in device tree sources.
Example: Node of the MFD chip
3. With MAX77620:
max77686: max77686@09 {
compatible = "maxim,max77686";
interrupt-parent = <&wakeup_eint>;
interrupts = <26 0>;
reg = <0x09>;
#clock-cells = <1>;
#include <dt-bindings/clock/maxim,max77620.h>
/* ... */
/* ... */
};
Node of the MFD chip
max77620: max77620@3c {
compatible = "maxim,max77620";
reg = <0x3c>;
#clock-cells = <1>;
/* ... */
};
Example: Clock consumer node
Clock consumer node
foo@0 {
compatible = "bar,foo";
/* ... */
clock-names = "my-clock";
clocks = <&max77686 MAX77686_CLK_PMIC>;
};
foo@0 {
compatible = "bar,foo";
/* ... */
clock-names = "my-clock";
clocks = <&max77620 MAX77620_CLK_32K_OUT0>;
};
Binding for Maxim MAX77802 32k clock generator block
This is a part of device tree bindings of MAX77802 multi-function device.
More information can be found in bindings/mfd/max77802.txt file.
The MAX77802 contains two 32.768khz clock outputs that can be controlled
(gated/ungated) over I2C.
Following properties should be present in main device node of the MFD chip.
Required properties:
- #clock-cells: From common clock binding; shall be set to 1.
Optional properties:
- clock-output-names: From common clock binding.
Each clock is assigned an identifier and client nodes can use this identifier
to specify the clock which they consume. Following indices are allowed:
- 0: 32khz_ap clock,
- 1: 32khz_cp clock.
Clocks are defined as preprocessor macros in dt-bindings/clock/maxim,max77802.h
header and can be used in device tree sources.
Example: Node of the MFD chip
max77802: max77802@09 {
compatible = "maxim,max77802";
interrupt-parent = <&wakeup_eint>;
interrupts = <26 0>;
reg = <0x09>;
#clock-cells = <1>;
/* ... */
};
Example: Clock consumer node
foo@0 {
compatible = "bar,foo";
/* ... */
clock-names = "my-clock";
clocks = <&max77802 MAX77802_CLK_32K_AP>;
};
......@@ -86,6 +86,8 @@ ID Clock Peripheral
7 pex3 PCIe 3
8 pex0 PCIe 0
9 usb3h0 USB3 Host 0
10 usb3h1 USB3 Host 1
15 sata0 SATA 0
17 sdio SDIO
22 xor0 XOR 0
28 xor1 XOR 1
......
......@@ -15,6 +15,7 @@ Required properties :
"qcom,gcc-msm8974pro"
"qcom,gcc-msm8974pro-ac"
"qcom,gcc-msm8996"
"qcom,gcc-mdm9615"
- reg : shall contain base register location and length
- #clock-cells : shall contain 1
......
......@@ -7,6 +7,7 @@ Required properties :
"qcom,lcc-msm8960"
"qcom,lcc-apq8064"
"qcom,lcc-ipq8064"
"qcom,lcc-mdm9615"
- reg : shall contain base register location and length
- #clock-cells : shall contain 1
......
Binding for a ST divider and multiplexer clock driver.
This binding uses the common clock binding[1].
Base address is located to the parent node. See clock binding[2]
[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
[2] Documentation/devicetree/bindings/clock/st/st,clkgen.txt
Required properties:
- compatible : shall be:
"st,clkgena-divmux-c65-hs", "st,clkgena-divmux"
"st,clkgena-divmux-c65-ls", "st,clkgena-divmux"
"st,clkgena-divmux-c32-odf0", "st,clkgena-divmux"
"st,clkgena-divmux-c32-odf1", "st,clkgena-divmux"
"st,clkgena-divmux-c32-odf2", "st,clkgena-divmux"
"st,clkgena-divmux-c32-odf3", "st,clkgena-divmux"
- #clock-cells : From common clock binding; shall be set to 1.
- clocks : From common clock binding
- clock-output-names : From common clock binding.
Example:
clockgen-a@fd345000 {
reg = <0xfd345000 0xb50>;
clk_m_a1_div1: clk-m-a1-div1 {
#clock-cells = <1>;
compatible = "st,clkgena-divmux-c32-odf1",
"st,clkgena-divmux";
clocks = <&clk_m_a1_osc_prediv>,
<&clk_m_a1_pll0 1>, /* PLL0 PHI1 */
<&clk_m_a1_pll1 1>; /* PLL1 PHI1 */
clock-output-names = "clk-m-rx-icn-ts",
"clk-m-rx-icn-vdp-0",
"", /* unused */
"clk-m-prv-t1-bus",
"clk-m-icn-reg-12",
"clk-m-icn-reg-10",
"", /* unused */
"clk-m-icn-st231";
};
};
......@@ -10,14 +10,7 @@ This binding uses the common clock binding[1].
Required properties:
- compatible : shall be:
"st,stih416-clkgenc-vcc-hd", "st,clkgen-mux"
"st,stih416-clkgenf-vcc-fvdp", "st,clkgen-mux"
"st,stih416-clkgenf-vcc-hva", "st,clkgen-mux"
"st,stih416-clkgenf-vcc-hd", "st,clkgen-mux"
"st,stih416-clkgenf-vcc-sd", "st,clkgen-mux"
"st,stih415-clkgen-a9-mux", "st,clkgen-mux"
"st,stih416-clkgen-a9-mux", "st,clkgen-mux"
"st,stih407-clkgen-a9-mux", "st,clkgen-mux"
"st,stih407-clkgen-a9-mux"
- #clock-cells : from common clock binding; shall be set to 0.
......@@ -27,10 +20,13 @@ Required properties:
Example:
clk_m_hva: clk-m-hva@fd690868 {
clk_m_a9: clk-m-a9@92b0000 {
#clock-cells = <0>;
compatible = "st,stih416-clkgenf-vcc-hva", "st,clkgen-mux";
reg = <0xfd690868 4>;
compatible = "st,stih407-clkgen-a9-mux";
reg = <0x92b0000 0x10000>;
clocks = <&clockgen_f 1>, <&clk_m_a1_div0 3>;
clocks = <&clockgen_a9_pll 0>,
<&clockgen_a9_pll 0>,
<&clk_s_c0_flexgen 13>,
<&clk_m_a9_ext2f_div2>;
};
......@@ -9,24 +9,10 @@ Base address is located to the parent node. See clock binding[2]
Required properties:
- compatible : shall be:
"st,clkgena-prediv-c65", "st,clkgena-prediv"
"st,clkgena-prediv-c32", "st,clkgena-prediv"
"st,clkgena-plls-c65"
"st,plls-c32-a1x-0", "st,clkgen-plls-c32"
"st,plls-c32-a1x-1", "st,clkgen-plls-c32"
"st,stih415-plls-c32-a9", "st,clkgen-plls-c32"
"st,stih415-plls-c32-ddr", "st,clkgen-plls-c32"
"st,stih416-plls-c32-a9", "st,clkgen-plls-c32"
"st,stih416-plls-c32-ddr", "st,clkgen-plls-c32"
"st,stih407-plls-c32-a0", "st,clkgen-plls-c32"
"st,stih407-plls-c32-a9", "st,clkgen-plls-c32"
"sst,plls-c32-cx_0", "st,clkgen-plls-c32"
"sst,plls-c32-cx_1", "st,clkgen-plls-c32"
"st,stih418-plls-c28-a9", "st,clkgen-plls-c32"
"st,stih415-gpu-pll-c32", "st,clkgengpu-pll-c32"
"st,stih416-gpu-pll-c32", "st,clkgengpu-pll-c32"
"st,clkgen-pll0"
"st,clkgen-pll1"
"st,stih407-clkgen-plla9"
"st,stih418-clkgen-plla9"
- #clock-cells : From common clock binding; shall be set to 1.
......@@ -36,17 +22,16 @@ Required properties:
Example:
clockgen-a@fee62000 {
reg = <0xfee62000 0xb48>;
clockgen-a9@92b0000 {
compatible = "st,clkgen-c32";
reg = <0x92b0000 0xffff>;
clk_s_a0_pll: clk-s-a0-pll {
clockgen_a9_pll: clockgen-a9-pll {
#clock-cells = <1>;
compatible = "st,clkgena-plls-c65";
compatible = "st,stih407-clkgen-plla9";
clocks = <&clk_sysin>;
clock-output-names = "clk-s-a0-pll0-hs",
"clk-s-a0-pll0-ls",
"clk-s-a0-pll1";
clock-output-names = "clockgen-a9-pll-odf";
};
};
Binding for a ST pre-divider clock driver.
This binding uses the common clock binding[1].
Base address is located to the parent node. See clock binding[2]
[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
[2] Documentation/devicetree/bindings/clock/st/st,clkgen.txt
Required properties:
- compatible : shall be:
"st,clkgena-prediv-c65", "st,clkgena-prediv"
"st,clkgena-prediv-c32", "st,clkgena-prediv"
- #clock-cells : From common clock binding; shall be set to 0.
- clocks : From common clock binding
- clock-output-names : From common clock binding.
Example:
clockgen-a@fd345000 {
reg = <0xfd345000 0xb50>;
clk_m_a2_osc_prediv: clk-m-a2-osc-prediv {
#clock-cells = <0>;
compatible = "st,clkgena-prediv-c32",
"st,clkgena-prediv";
clocks = <&clk_sysin>;
clock-output-names = "clk-m-a2-osc-prediv";
};
};
Binding for a type of STMicroelectronics clock crossbar (VCC).
The crossbar can take up to 4 input clocks and control up to 16
output clocks. Not all inputs or outputs have to be in use in a
particular instantiation. Each output can be individually enabled,
select any of the input clocks and apply a divide (by 1,2,4 or 8) to
that selected clock.
This binding uses the common clock binding[1].
[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
Required properties:
- compatible : shall be:
"st,stih416-clkgenc", "st,vcc"
"st,stih416-clkgenf", "st,vcc"
- #clock-cells : from common clock binding; shall be set to 1.
- reg : A Base address and length of the register set.
- clocks : from common clock binding
- clock-output-names : From common clock binding. The block has 16
clock outputs but not all of them in a specific instance
have to be used in the SoC. If a clock name is left as
an empty string then no clock will be created for the
output associated with that string index. If fewer than
16 strings are provided then no clocks will be created
for the remaining outputs.
Example:
clockgen_c_vcc: clockgen-c-vcc@0xfe8308ac {
#clock-cells = <1>;
compatible = "st,stih416-clkgenc", "st,clkgen-vcc";
reg = <0xfe8308ac 12>;
clocks = <&clk_s_vcc_hd>,
<&clockgen_c 1>,
<&clk_s_tmds_fromphy>,
<&clockgen_c 2>;
clock-output-names = "clk-s-pix-hdmi",
"clk-s-pix-dvo",
"clk-s-out-dvo",
"clk-s-pix-hd",
"clk-s-hddac",
"clk-s-denc",
"clk-s-sddac",
"clk-s-pix-main",
"clk-s-pix-aux",
"clk-s-stfe-frc-0",
"clk-s-ref-mcru",
"clk-s-slave-mcru",
"clk-s-tmds-hdmi",
"clk-s-hdmi-reject-pll",
"clk-s-thsens";
};
......@@ -13,14 +13,6 @@ address is common of all subnode.
...
};
prediv_node {
...
};
divmux_node {
...
};
quadfs_node {
...
};
......@@ -29,10 +21,6 @@ address is common of all subnode.
...
};
vcc_node {
...
};
flexgen_node {
...
};
......@@ -43,11 +31,8 @@ This binding uses the common clock binding[1].
Each subnode should use the binding described in [2]..[7]
[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
[2] Documentation/devicetree/bindings/clock/st,clkgen-divmux.txt
[3] Documentation/devicetree/bindings/clock/st,clkgen-mux.txt
[4] Documentation/devicetree/bindings/clock/st,clkgen-pll.txt
[5] Documentation/devicetree/bindings/clock/st,clkgen-prediv.txt
[6] Documentation/devicetree/bindings/clock/st,vcc.txt
[7] Documentation/devicetree/bindings/clock/st,quadfs.txt
[8] Documentation/devicetree/bindings/clock/st,flexgen.txt
......@@ -57,44 +42,27 @@ Required properties:
Example:
clockgen-a@fee62000 {
reg = <0xfee62000 0xb48>;
clockgen-a@090ff000 {
compatible = "st,clkgen-c32";
reg = <0x90ff000 0x1000>;
clk_s_a0_pll: clk-s-a0-pll {
#clock-cells = <1>;
compatible = "st,clkgena-plls-c65";
clocks = <&clk-sysin>;
clock-output-names = "clk-s-a0-pll0-hs",
"clk-s-a0-pll0-ls",
"clk-s-a0-pll1";
};
clk_s_a0_osc_prediv: clk-s-a0-osc-prediv {
#clock-cells = <0>;
compatible = "st,clkgena-prediv-c65",
"st,clkgena-prediv";
compatible = "st,clkgen-pll0";
clocks = <&clk_sysin>;
clock-output-names = "clk-s-a0-osc-prediv";
clock-output-names = "clk-s-a0-pll-ofd-0";
};
clk_s_a0_hs: clk-s-a0-hs {
clk_s_a0_flexgen: clk-s-a0-flexgen {
compatible = "st,flexgen";
#clock-cells = <1>;
compatible = "st,clkgena-divmux-c65-hs",
"st,clkgena-divmux";
clocks = <&clk-s_a0_osc_prediv>,
<&clk-s_a0_pll 0>, /* pll0 hs */
<&clk-s_a0_pll 2>; /* pll1 */
clocks = <&clk_s_a0_pll 0>,
<&clk_sysin>;
clock-output-names = "clk-s-fdma-0",
"clk-s-fdma-1",
""; /* clk-s-jit-sense */
/* fourth output unused */
clock-output-names = "clk-ic-lmi0";
};
};
......@@ -60,6 +60,10 @@ This binding uses the common clock binding[2].
Required properties:
- compatible : shall be:
"st,flexgen"
"st,flexgen-audio", "st,flexgen" (enable clock propagation on parent for
audio use case)
"st,flexgen-video", "st,flexgen" (enable clock propagation on parent
and activate synchronous mode)
- #clock-cells : from common clock binding; shall be set to 1 (multiple clock
outputs).
......
......@@ -11,12 +11,8 @@ This binding uses the common clock binding[1].
Required properties:
- compatible : shall be:
"st,stih416-quadfs216", "st,quadfs"
"st,stih416-quadfs432", "st,quadfs"
"st,stih416-quadfs660-E", "st,quadfs"
"st,stih416-quadfs660-F", "st,quadfs"
"st,stih407-quadfs660-C", "st,quadfs"
"st,stih407-quadfs660-D", "st,quadfs"
"st,quadfs"
"st,quadfs-pll"
- #clock-cells : from common clock binding; shall be set to 1.
......@@ -35,14 +31,15 @@ Required properties:
Example:
clockgen_e: clockgen-e@fd3208bc {
#clock-cells = <1>;
compatible = "st,stih416-quadfs660-E", "st,quadfs";
reg = <0xfd3208bc 0xB0>;
clocks = <&clk_sysin>;
clock-output-names = "clk-m-pix-mdtp-0",
"clk-m-pix-mdtp-1",
"clk-m-pix-mdtp-2",
"clk-m-mpelpc";
};
clk_s_c0_quadfs: clk-s-c0-quadfs@9103000 {
#clock-cells = <1>;
compatible = "st,quadfs-pll";
reg = <0x9103000 0x1000>;
clocks = <&clk_sysin>;
clock-output-names = "clk-s-c0-fs0-ch0",
"clk-s-c0-fs0-ch1",
"clk-s-c0-fs0-ch2",
"clk-s-c0-fs0-ch3";
};
......@@ -2,7 +2,10 @@ Allwinner Clock Control Unit Binding
------------------------------------
Required properties :
- compatible: must contain one of the following compatible:
- compatible: must contain one of the following compatibles:
- "allwinner,sun6i-a31-ccu"
- "allwinner,sun8i-a23-ccu"
- "allwinner,sun8i-a33-ccu"
- "allwinner,sun8i-h3-ccu"
- reg: Must contain the registers base address and length
......
UniPhier clock controller
System clock
------------
Required properties:
- compatible: should be one of the following:
"socionext,uniphier-sld3-clock" - for sLD3 SoC.
"socionext,uniphier-ld4-clock" - for LD4 SoC.
"socionext,uniphier-pro4-clock" - for Pro4 SoC.
"socionext,uniphier-sld8-clock" - for sLD8 SoC.
"socionext,uniphier-pro5-clock" - for Pro5 SoC.
"socionext,uniphier-pxs2-clock" - for PXs2/LD6b SoC.
"socionext,uniphier-ld11-clock" - for LD11 SoC.
"socionext,uniphier-ld20-clock" - for LD20 SoC.
- #clock-cells: should be 1.
Example:
sysctrl@61840000 {
compatible = "socionext,uniphier-sysctrl",
"simple-mfd", "syscon";
reg = <0x61840000 0x4000>;
clock {
compatible = "socionext,uniphier-ld20-clock";
#clock-cells = <1>;
};
other nodes ...
};
Provided clocks:
8: ST DMAC
12: GIO (Giga bit stream I/O)
14: USB3 ch0 host
15: USB3 ch1 host
16: USB3 ch0 PHY0
17: USB3 ch0 PHY1
20: USB3 ch1 PHY0
21: USB3 ch1 PHY1
Media I/O (MIO) clock
---------------------
Required properties:
- compatible: should be one of the following:
"socionext,uniphier-sld3-mio-clock" - for sLD3 SoC.
"socionext,uniphier-ld4-mio-clock" - for LD4 SoC.
"socionext,uniphier-pro4-mio-clock" - for Pro4 SoC.
"socionext,uniphier-sld8-mio-clock" - for sLD8 SoC.
"socionext,uniphier-pro5-mio-clock" - for Pro5 SoC.
"socionext,uniphier-pxs2-mio-clock" - for PXs2/LD6b SoC.
"socionext,uniphier-ld11-mio-clock" - for LD11 SoC.
"socionext,uniphier-ld20-mio-clock" - for LD20 SoC.
- #clock-cells: should be 1.
Example:
mioctrl@59810000 {
compatible = "socionext,uniphier-mioctrl",
"simple-mfd", "syscon";
reg = <0x59810000 0x800>;
clock {
compatible = "socionext,uniphier-ld20-mio-clock";
#clock-cells = <1>;
};
other nodes ...
};
Provided clocks:
0: SD ch0 host
1: eMMC host
2: SD ch1 host
7: MIO DMAC
8: USB2 ch0 host
9: USB2 ch1 host
10: USB2 ch2 host
11: USB2 ch3 host
12: USB2 ch0 PHY
13: USB2 ch1 PHY
14: USB2 ch2 PHY
15: USB2 ch3 PHY
Peripheral clock
----------------
Required properties:
- compatible: should be one of the following:
"socionext,uniphier-sld3-peri-clock" - for sLD3 SoC.
"socionext,uniphier-ld4-peri-clock" - for LD4 SoC.
"socionext,uniphier-pro4-peri-clock" - for Pro4 SoC.
"socionext,uniphier-sld8-peri-clock" - for sLD8 SoC.
"socionext,uniphier-pro5-peri-clock" - for Pro5 SoC.
"socionext,uniphier-pxs2-peri-clock" - for PXs2/LD6b SoC.
"socionext,uniphier-ld11-peri-clock" - for LD11 SoC.
"socionext,uniphier-ld20-peri-clock" - for LD20 SoC.
- #clock-cells: should be 1.
Example:
perictrl@59820000 {
compatible = "socionext,uniphier-perictrl",
"simple-mfd", "syscon";
reg = <0x59820000 0x200>;
clock {
compatible = "socionext,uniphier-ld20-peri-clock";
#clock-cells = <1>;
};
other nodes ...
};
Provided clocks:
0: UART ch0
1: UART ch1
2: UART ch2
3: UART ch3
4: I2C ch0
5: I2C ch1
6: I2C ch2
7: I2C ch3
8: I2C ch4
9: I2C ch5
10: I2C ch6
......@@ -8,6 +8,7 @@ Required properties:
- compatible : shall be one of the following:
"apm,xgene-socpll-clock" - for a X-Gene SoC PLL clock
"apm,xgene-pcppll-clock" - for a X-Gene PCP PLL clock
"apm,xgene-pmd-clock" - for a X-Gene PMD clock
"apm,xgene-device-clock" - for a X-Gene device clock
"apm,xgene-socpll-v2-clock" - for a X-Gene SoC PLL v2 clock
"apm,xgene-pcppll-v2-clock" - for a X-Gene PCP PLL v2 clock
......@@ -22,6 +23,15 @@ Required properties for SoC or PCP PLL clocks:
Optional properties for PLL clocks:
- clock-names : shall be the name of the PLL. If missing, use the device name.
Required properties for PMD clocks:
- reg : shall be the physical register address for the pmd clock.
- clocks : shall be the input parent clock phandle for the clock.
- #clock-cells : shall be set to 1.
- clock-output-names : shall be the name of the clock referenced by derive
clock.
Optional properties for PLL clocks:
- clock-names : shall be the name of the clock. If missing, use the device name.
Required properties for device clocks:
- reg : shall be a list of address and length pairs describing the CSR
reset and/or the divider. Either may be omitted, but at least
......@@ -59,6 +69,14 @@ For example:
type = <0>;
};
pmd0clk: pmd0clk@7e200200 {
compatible = "apm,xgene-pmd-clock";
#clock-cells = <1>;
clocks = <&pmdpll 0>;
reg = <0x0 0x7e200200 0x0 0x10>;
clock-output-names = "pmd0clk";
};
socpll: socpll@17000120 {
compatible = "apm,xgene-socpll-clock";
#clock-cells = <1>;
......
Device Tree Clock bindings for ZTE zx296718
This binding uses the common clock binding[1].
[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
Required properties:
- compatible : shall be one of the following:
"zte,zx296718-topcrm":
zx296718 top clock selection, divider and gating
"zte,zx296718-lsp0crm" and
"zte,zx296718-lsp1crm":
zx296718 device level clock selection and gating
- reg: Address and length of the register set
The clock consumer should specify the desired clock by having the clock
ID in its "clocks" phandle cell. See include/dt-bindings/clock/zx296718-clock.h
for the full list of zx296718 clock IDs.
topclk: topcrm@1461000 {
compatible = "zte,zx296718-topcrm-clk";
reg = <0x01461000 0x1000>;
#clock-cells = <1>;
};
usbphy0:usb-phy0 {
compatible = "zte,zx296718-usb-phy";
#phy-cells = <0>;
clocks = <&topclk USB20_PHY_CLK>;
clock-names = "phyclk";
status = "okay";
};
......@@ -1847,6 +1847,7 @@ F: arch/arm/mach-uniphier/
F: arch/arm/mm/cache-uniphier.c
F: arch/arm64/boot/dts/socionext/
F: drivers/bus/uniphier-system-bus.c
F: drivers/clk/uniphier/
F: drivers/i2c/busses/i2c-uniphier*
F: drivers/pinctrl/uniphier/
F: drivers/tty/serial/8250/8250_uniphier.c
......@@ -3164,6 +3165,7 @@ COMMON CLK FRAMEWORK
M: Michael Turquette <mturquette@baylibre.com>
M: Stephen Boyd <sboyd@codeaurora.org>
L: linux-clk@vger.kernel.org
Q: http://patchwork.kernel.org/project/linux-clk/list/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git
S: Maintained
F: Documentation/devicetree/bindings/clock/
......@@ -9950,6 +9952,12 @@ F: drivers/rpmsg/
F: Documentation/rpmsg.txt
F: include/linux/rpmsg.h
RENESAS CLOCK DRIVERS
M: Geert Uytterhoeven <geert+renesas@glider.be>
L: linux-renesas-soc@vger.kernel.org
S: Supported
F: drivers/clk/renesas/
RENESAS ETHERNET DRIVERS
R: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
L: netdev@vger.kernel.org
......@@ -10293,9 +10301,12 @@ F: drivers/nfc/s3fwrn5
SAMSUNG SOC CLOCK DRIVERS
M: Sylwester Nawrocki <s.nawrocki@samsung.com>
M: Tomasz Figa <tomasz.figa@gmail.com>
M: Chanwoo Choi <cw00.choi@samsung.com>
S: Supported
L: linux-samsung-soc@vger.kernel.org (moderated for non-subscribers)
F: drivers/clk/samsung/
F: include/dt-bindings/clock/exynos*.h
F: Documentation/devicetree/bindings/clock/exynos*.txt
SAMSUNG SPI DRIVERS
M: Kukjin Kim <kgene@kernel.org>
......
......@@ -15,7 +15,6 @@ config ARCH_BCM_IPROC
select HAVE_ARM_SCU if SMP
select HAVE_ARM_TWD if SMP
select ARM_GLOBAL_TIMER
select COMMON_CLK_IPROC
select CLKSRC_MMIO
select GPIOLIB
select ARM_AMBA
......
......@@ -31,22 +31,12 @@ config COMMON_CLK_WM831X
source "drivers/clk/versatile/Kconfig"
config COMMON_CLK_MAX_GEN
bool
config COMMON_CLK_MAX77686
tristate "Clock driver for Maxim 77686 MFD"
depends on MFD_MAX77686
select COMMON_CLK_MAX_GEN
---help---
This driver supports Maxim 77686 crystal oscillator clock.
config COMMON_CLK_MAX77802
tristate "Clock driver for Maxim 77802 PMIC"
depends on MFD_MAX77686
select COMMON_CLK_MAX_GEN
tristate "Clock driver for Maxim 77620/77686/77802 MFD"
depends on MFD_MAX77686 || MFD_MAX77620
---help---
This driver supports Maxim 77802 crystal oscillator clock.
This driver supports Maxim 77620/77686/77802 crystal oscillator
clock.
config COMMON_CLK_RK808
tristate "Clock driver for RK808/RK818"
......@@ -210,6 +200,7 @@ config COMMON_CLK_OXNAS
source "drivers/clk/bcm/Kconfig"
source "drivers/clk/hisilicon/Kconfig"
source "drivers/clk/mediatek/Kconfig"
source "drivers/clk/meson/Kconfig"
source "drivers/clk/mvebu/Kconfig"
source "drivers/clk/qcom/Kconfig"
......@@ -218,5 +209,6 @@ source "drivers/clk/samsung/Kconfig"
source "drivers/clk/sunxi-ng/Kconfig"
source "drivers/clk/tegra/Kconfig"
source "drivers/clk/ti/Kconfig"
source "drivers/clk/uniphier/Kconfig"
endmenu
......@@ -26,10 +26,7 @@ obj-$(CONFIG_ARCH_CLPS711X) += clk-clps711x.o
obj-$(CONFIG_COMMON_CLK_CS2000_CP) += clk-cs2000-cp.o
obj-$(CONFIG_ARCH_EFM32) += clk-efm32gg.o
obj-$(CONFIG_ARCH_HIGHBANK) += clk-highbank.o
obj-$(CONFIG_MACH_LOONGSON32) += clk-ls1x.o
obj-$(CONFIG_COMMON_CLK_MAX_GEN) += clk-max-gen.o
obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o
obj-$(CONFIG_COMMON_CLK_MAX77802) += clk-max77802.o
obj-$(CONFIG_ARCH_MB86S7X) += clk-mb86s7x.o
obj-$(CONFIG_ARCH_MOXART) += clk-moxart.o
obj-$(CONFIG_ARCH_NOMADIK) += clk-nomadik.o
......@@ -63,6 +60,7 @@ obj-$(CONFIG_ARCH_HISI) += hisilicon/
obj-$(CONFIG_ARCH_MXC) += imx/
obj-$(CONFIG_MACH_INGENIC) += ingenic/
obj-$(CONFIG_COMMON_CLK_KEYSTONE) += keystone/
obj-$(CONFIG_MACH_LOONGSON32) += loongson1/
obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/
obj-$(CONFIG_COMMON_CLK_AMLOGIC) += meson/
obj-$(CONFIG_MACH_PIC32) += microchip/
......@@ -86,6 +84,7 @@ obj-$(CONFIG_ARCH_SUNXI) += sunxi/
obj-$(CONFIG_ARCH_SUNXI) += sunxi-ng/
obj-$(CONFIG_ARCH_TEGRA) += tegra/
obj-y += ti/
obj-$(CONFIG_CLK_UNIPHIER) += uniphier/
obj-$(CONFIG_ARCH_U8500) += ux500/
obj-$(CONFIG_COMMON_CLK_VERSATILE) += versatile/
obj-$(CONFIG_X86) += x86/
......
......@@ -233,14 +233,16 @@ static void clk_generated_startup(struct clk_generated *gck)
>> AT91_PMC_PCR_GCKDIV_OFFSET;
}
static struct clk * __init
at91_clk_register_generated(struct regmap *regmap, spinlock_t *lock, const char
*name, const char **parent_names, u8 num_parents,
u8 id, const struct clk_range *range)
static struct clk_hw * __init
at91_clk_register_generated(struct regmap *regmap, spinlock_t *lock,
const char *name, const char **parent_names,
u8 num_parents, u8 id,
const struct clk_range *range)
{
struct clk_generated *gck;
struct clk *clk = NULL;
struct clk_init_data init;
struct clk_hw *hw;
int ret;
gck = kzalloc(sizeof(*gck), GFP_KERNEL);
if (!gck)
......@@ -258,13 +260,15 @@ at91_clk_register_generated(struct regmap *regmap, spinlock_t *lock, const char
gck->lock = lock;
gck->range = *range;
clk = clk_register(NULL, &gck->hw);
if (IS_ERR(clk))
hw = &gck->hw;
ret = clk_hw_register(NULL, &gck->hw);
if (ret) {
kfree(gck);
else
hw = ERR_PTR(ret);
} else
clk_generated_startup(gck);
return clk;
return hw;
}
static void __init of_sama5d2_clk_generated_setup(struct device_node *np)
......@@ -272,7 +276,7 @@ static void __init of_sama5d2_clk_generated_setup(struct device_node *np)
int num;
u32 id;
const char *name;
struct clk *clk;
struct clk_hw *hw;
unsigned int num_parents;
const char *parent_names[GENERATED_SOURCE_MAX];
struct device_node *gcknp;
......@@ -306,13 +310,13 @@ static void __init of_sama5d2_clk_generated_setup(struct device_node *np)
of_at91_get_clk_range(gcknp, "atmel,clk-output-range",
&range);
clk = at91_clk_register_generated(regmap, &pmc_pcr_lock, name,
hw = at91_clk_register_generated(regmap, &pmc_pcr_lock, name,
parent_names, num_parents,
id, &range);
if (IS_ERR(clk))
if (IS_ERR(hw))
continue;
of_clk_add_provider(gcknp, of_clk_src_simple_get, clk);
of_clk_add_hw_provider(gcknp, of_clk_hw_simple_get, hw);
}
}
CLK_OF_DECLARE(of_sama5d2_clk_generated_setup, "atmel,sama5d2-clk-generated",
......
......@@ -92,7 +92,7 @@ static void __init of_sama5d4_clk_h32mx_setup(struct device_node *np)
struct clk_init_data init;
const char *parent_name;
struct regmap *regmap;
struct clk *clk;
int ret;
regmap = syscon_node_to_regmap(of_get_parent(np));
if (IS_ERR(regmap))
......@@ -113,13 +113,13 @@ static void __init of_sama5d4_clk_h32mx_setup(struct device_node *np)
h32mxclk->hw.init = &init;
h32mxclk->regmap = regmap;
clk = clk_register(NULL, &h32mxclk->hw);
if (IS_ERR(clk)) {
ret = clk_hw_register(NULL, &h32mxclk->hw);
if (ret) {
kfree(h32mxclk);
return;
}
of_clk_add_provider(np, of_clk_src_simple_get, clk);
of_clk_add_hw_provider(np, of_clk_hw_simple_get, &h32mxclk->hw);
}
CLK_OF_DECLARE(of_sama5d4_clk_h32mx_setup, "atmel,sama5d4-clk-h32mx",
of_sama5d4_clk_h32mx_setup);
......@@ -128,15 +128,16 @@ static const struct clk_ops main_osc_ops = {
.is_prepared = clk_main_osc_is_prepared,
};
static struct clk * __init
static struct clk_hw * __init
at91_clk_register_main_osc(struct regmap *regmap,
const char *name,
const char *parent_name,
bool bypass)
{
struct clk_main_osc *osc;
struct clk *clk = NULL;
struct clk_init_data init;
struct clk_hw *hw;
int ret;
if (!name || !parent_name)
return ERR_PTR(-EINVAL);
......@@ -160,16 +161,19 @@ at91_clk_register_main_osc(struct regmap *regmap,
AT91_PMC_MOSCEN,
AT91_PMC_OSCBYPASS | AT91_PMC_KEY);
clk = clk_register(NULL, &osc->hw);
if (IS_ERR(clk))
hw = &osc->hw;
ret = clk_hw_register(NULL, &osc->hw);
if (ret) {
kfree(osc);
hw = ERR_PTR(ret);
}
return clk;
return hw;
}
static void __init of_at91rm9200_clk_main_osc_setup(struct device_node *np)
{
struct clk *clk;
struct clk_hw *hw;
const char *name = np->name;
const char *parent_name;
struct regmap *regmap;
......@@ -183,11 +187,11 @@ static void __init of_at91rm9200_clk_main_osc_setup(struct device_node *np)
if (IS_ERR(regmap))
return;
clk = at91_clk_register_main_osc(regmap, name, parent_name, bypass);
if (IS_ERR(clk))
hw = at91_clk_register_main_osc(regmap, name, parent_name, bypass);
if (IS_ERR(hw))
return;
of_clk_add_provider(np, of_clk_src_simple_get, clk);
of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
}
CLK_OF_DECLARE(at91rm9200_clk_main_osc, "atmel,at91rm9200-clk-main-osc",
of_at91rm9200_clk_main_osc_setup);
......@@ -271,14 +275,15 @@ static const struct clk_ops main_rc_osc_ops = {
.recalc_accuracy = clk_main_rc_osc_recalc_accuracy,
};
static struct clk * __init
static struct clk_hw * __init
at91_clk_register_main_rc_osc(struct regmap *regmap,
const char *name,
u32 frequency, u32 accuracy)
{
struct clk_main_rc_osc *osc;
struct clk *clk = NULL;
struct clk_init_data init;
struct clk_hw *hw;
int ret;
if (!name || !frequency)
return ERR_PTR(-EINVAL);
......@@ -298,16 +303,19 @@ at91_clk_register_main_rc_osc(struct regmap *regmap,
osc->frequency = frequency;
osc->accuracy = accuracy;
clk = clk_register(NULL, &osc->hw);
if (IS_ERR(clk))
hw = &osc->hw;
ret = clk_hw_register(NULL, hw);
if (ret) {
kfree(osc);
hw = ERR_PTR(ret);
}
return clk;
return hw;
}
static void __init of_at91sam9x5_clk_main_rc_osc_setup(struct device_node *np)
{
struct clk *clk;
struct clk_hw *hw;
u32 frequency = 0;
u32 accuracy = 0;
const char *name = np->name;
......@@ -321,11 +329,11 @@ static void __init of_at91sam9x5_clk_main_rc_osc_setup(struct device_node *np)
if (IS_ERR(regmap))
return;
clk = at91_clk_register_main_rc_osc(regmap, name, frequency, accuracy);
if (IS_ERR(clk))
hw = at91_clk_register_main_rc_osc(regmap, name, frequency, accuracy);
if (IS_ERR(hw))
return;
of_clk_add_provider(np, of_clk_src_simple_get, clk);
of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
}
CLK_OF_DECLARE(at91sam9x5_clk_main_rc_osc, "atmel,at91sam9x5-clk-main-rc-osc",
of_at91sam9x5_clk_main_rc_osc_setup);
......@@ -395,14 +403,15 @@ static const struct clk_ops rm9200_main_ops = {
.recalc_rate = clk_rm9200_main_recalc_rate,
};
static struct clk * __init
static struct clk_hw * __init
at91_clk_register_rm9200_main(struct regmap *regmap,
const char *name,
const char *parent_name)
{
struct clk_rm9200_main *clkmain;
struct clk *clk = NULL;
struct clk_init_data init;
struct clk_hw *hw;
int ret;
if (!name)
return ERR_PTR(-EINVAL);
......@@ -423,16 +432,19 @@ at91_clk_register_rm9200_main(struct regmap *regmap,
clkmain->hw.init = &init;
clkmain->regmap = regmap;
clk = clk_register(NULL, &clkmain->hw);
if (IS_ERR(clk))
hw = &clkmain->hw;
ret = clk_hw_register(NULL, &clkmain->hw);
if (ret) {
kfree(clkmain);
hw = ERR_PTR(ret);
}
return clk;
return hw;
}
static void __init of_at91rm9200_clk_main_setup(struct device_node *np)
{
struct clk *clk;
struct clk_hw *hw;
const char *parent_name;
const char *name = np->name;
struct regmap *regmap;
......@@ -444,11 +456,11 @@ static void __init of_at91rm9200_clk_main_setup(struct device_node *np)
if (IS_ERR(regmap))
return;
clk = at91_clk_register_rm9200_main(regmap, name, parent_name);
if (IS_ERR(clk))
hw = at91_clk_register_rm9200_main(regmap, name, parent_name);
if (IS_ERR(hw))
return;
of_clk_add_provider(np, of_clk_src_simple_get, clk);
of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
}
CLK_OF_DECLARE(at91rm9200_clk_main, "atmel,at91rm9200-clk-main",
of_at91rm9200_clk_main_setup);
......@@ -529,16 +541,17 @@ static const struct clk_ops sam9x5_main_ops = {
.get_parent = clk_sam9x5_main_get_parent,
};
static struct clk * __init
static struct clk_hw * __init
at91_clk_register_sam9x5_main(struct regmap *regmap,
const char *name,
const char **parent_names,
int num_parents)
{
struct clk_sam9x5_main *clkmain;
struct clk *clk = NULL;
struct clk_init_data init;
unsigned int status;
struct clk_hw *hw;
int ret;
if (!name)
return ERR_PTR(-EINVAL);
......@@ -561,16 +574,19 @@ at91_clk_register_sam9x5_main(struct regmap *regmap,
regmap_read(clkmain->regmap, AT91_CKGR_MOR, &status);
clkmain->parent = status & AT91_PMC_MOSCEN ? 1 : 0;
clk = clk_register(NULL, &clkmain->hw);
if (IS_ERR(clk))
hw = &clkmain->hw;
ret = clk_hw_register(NULL, &clkmain->hw);
if (ret) {
kfree(clkmain);
hw = ERR_PTR(ret);
}
return clk;
return hw;
}
static void __init of_at91sam9x5_clk_main_setup(struct device_node *np)
{
struct clk *clk;
struct clk_hw *hw;
const char *parent_names[2];
unsigned int num_parents;
const char *name = np->name;
......@@ -587,12 +603,12 @@ static void __init of_at91sam9x5_clk_main_setup(struct device_node *np)
of_property_read_string(np, "clock-output-names", &name);
clk = at91_clk_register_sam9x5_main(regmap, name, parent_names,
hw = at91_clk_register_sam9x5_main(regmap, name, parent_names,
num_parents);
if (IS_ERR(clk))
if (IS_ERR(hw))
return;
of_clk_add_provider(np, of_clk_src_simple_get, clk);
of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
}
CLK_OF_DECLARE(at91sam9x5_clk_main, "atmel,at91sam9x5-clk-main",
of_at91sam9x5_clk_main_setup);
......@@ -120,7 +120,7 @@ static const struct clk_ops master_ops = {
.get_parent = clk_master_get_parent,
};
static struct clk * __init
static struct clk_hw * __init
at91_clk_register_master(struct regmap *regmap,
const char *name, int num_parents,
const char **parent_names,
......@@ -128,8 +128,9 @@ at91_clk_register_master(struct regmap *regmap,
const struct clk_master_characteristics *characteristics)
{
struct clk_master *master;
struct clk *clk = NULL;
struct clk_init_data init;
struct clk_hw *hw;
int ret;
if (!name || !num_parents || !parent_names)
return ERR_PTR(-EINVAL);
......@@ -149,12 +150,14 @@ at91_clk_register_master(struct regmap *regmap,
master->characteristics = characteristics;
master->regmap = regmap;
clk = clk_register(NULL, &master->hw);
if (IS_ERR(clk)) {
hw = &master->hw;
ret = clk_hw_register(NULL, &master->hw);
if (ret) {
kfree(master);
hw = ERR_PTR(ret);
}
return clk;
return hw;
}
......@@ -198,7 +201,7 @@ static void __init
of_at91_clk_master_setup(struct device_node *np,
const struct clk_master_layout *layout)
{
struct clk *clk;
struct clk_hw *hw;
unsigned int num_parents;
const char *parent_names[MASTER_SOURCE_MAX];
const char *name = np->name;
......@@ -221,13 +224,13 @@ of_at91_clk_master_setup(struct device_node *np,
if (IS_ERR(regmap))
return;
clk = at91_clk_register_master(regmap, name, num_parents,
hw = at91_clk_register_master(regmap, name, num_parents,
parent_names, layout,
characteristics);
if (IS_ERR(clk))
if (IS_ERR(hw))
goto out_free_characteristics;
of_clk_add_provider(np, of_clk_src_simple_get, clk);
of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
return;
out_free_characteristics:
......
......@@ -104,13 +104,14 @@ static const struct clk_ops peripheral_ops = {
.is_enabled = clk_peripheral_is_enabled,
};
static struct clk * __init
static struct clk_hw * __init
at91_clk_register_peripheral(struct regmap *regmap, const char *name,
const char *parent_name, u32 id)
{
struct clk_peripheral *periph;
struct clk *clk = NULL;
struct clk_init_data init;
struct clk_hw *hw;
int ret;
if (!name || !parent_name || id > PERIPHERAL_ID_MAX)
return ERR_PTR(-EINVAL);
......@@ -129,11 +130,14 @@ at91_clk_register_peripheral(struct regmap *regmap, const char *name,
periph->hw.init = &init;
periph->regmap = regmap;
clk = clk_register(NULL, &periph->hw);
if (IS_ERR(clk))
hw = &periph->hw;
ret = clk_hw_register(NULL, &periph->hw);
if (ret) {
kfree(periph);
hw = ERR_PTR(ret);
}
return clk;
return hw;
}
static void clk_sam9x5_peripheral_autodiv(struct clk_sam9x5_peripheral *periph)
......@@ -327,14 +331,15 @@ static const struct clk_ops sam9x5_peripheral_ops = {
.set_rate = clk_sam9x5_peripheral_set_rate,
};
static struct clk * __init
static struct clk_hw * __init
at91_clk_register_sam9x5_peripheral(struct regmap *regmap, spinlock_t *lock,
const char *name, const char *parent_name,
u32 id, const struct clk_range *range)
{
struct clk_sam9x5_peripheral *periph;
struct clk *clk = NULL;
struct clk_init_data init;
struct clk_hw *hw;
int ret;
if (!name || !parent_name)
return ERR_PTR(-EINVAL);
......@@ -357,13 +362,15 @@ at91_clk_register_sam9x5_peripheral(struct regmap *regmap, spinlock_t *lock,
periph->auto_div = true;
periph->range = *range;
clk = clk_register(NULL, &periph->hw);
if (IS_ERR(clk))
hw = &periph->hw;
ret = clk_hw_register(NULL, &periph->hw);
if (ret) {
kfree(periph);
else
hw = ERR_PTR(ret);
} else
clk_sam9x5_peripheral_autodiv(periph);
return clk;
return hw;
}
static void __init
......@@ -371,7 +378,7 @@ of_at91_clk_periph_setup(struct device_node *np, u8 type)
{
int num;
u32 id;
struct clk *clk;
struct clk_hw *hw;
const char *parent_name;
const char *name;
struct device_node *periphclknp;
......@@ -400,7 +407,7 @@ of_at91_clk_periph_setup(struct device_node *np, u8 type)
name = periphclknp->name;
if (type == PERIPHERAL_AT91RM9200) {
clk = at91_clk_register_peripheral(regmap, name,
hw = at91_clk_register_peripheral(regmap, name,
parent_name, id);
} else {
struct clk_range range = CLK_RANGE(0, 0);
......@@ -409,17 +416,17 @@ of_at91_clk_periph_setup(struct device_node *np, u8 type)
"atmel,clk-output-range",
&range);
clk = at91_clk_register_sam9x5_peripheral(regmap,
hw = at91_clk_register_sam9x5_peripheral(regmap,
&pmc_pcr_lock,
name,
parent_name,
id, &range);
}
if (IS_ERR(clk))
if (IS_ERR(hw))
continue;
of_clk_add_provider(periphclknp, of_clk_src_simple_get, clk);
of_clk_add_hw_provider(periphclknp, of_clk_hw_simple_get, hw);
}
}
......
......@@ -296,17 +296,18 @@ static const struct clk_ops pll_ops = {
.set_rate = clk_pll_set_rate,
};
static struct clk * __init
static struct clk_hw * __init
at91_clk_register_pll(struct regmap *regmap, const char *name,
const char *parent_name, u8 id,
const struct clk_pll_layout *layout,
const struct clk_pll_characteristics *characteristics)
{
struct clk_pll *pll;
struct clk *clk = NULL;
struct clk_hw *hw;
struct clk_init_data init;
int offset = PLL_REG(id);
unsigned int pllr;
int ret;
if (id > PLL_MAX_ID)
return ERR_PTR(-EINVAL);
......@@ -330,12 +331,14 @@ at91_clk_register_pll(struct regmap *regmap, const char *name,
pll->div = PLL_DIV(pllr);
pll->mul = PLL_MUL(pllr, layout);
clk = clk_register(NULL, &pll->hw);
if (IS_ERR(clk)) {
hw = &pll->hw;
ret = clk_hw_register(NULL, &pll->hw);
if (ret) {
kfree(pll);
hw = ERR_PTR(ret);
}
return clk;
return hw;
}
......@@ -465,7 +468,7 @@ of_at91_clk_pll_setup(struct device_node *np,
const struct clk_pll_layout *layout)
{
u32 id;
struct clk *clk;
struct clk_hw *hw;
struct regmap *regmap;
const char *parent_name;
const char *name = np->name;
......@@ -486,12 +489,12 @@ of_at91_clk_pll_setup(struct device_node *np,
if (!characteristics)
return;
clk = at91_clk_register_pll(regmap, name, parent_name, id, layout,
hw = at91_clk_register_pll(regmap, name, parent_name, id, layout,
characteristics);
if (IS_ERR(clk))
if (IS_ERR(hw))
goto out_free_characteristics;
of_clk_add_provider(np, of_clk_src_simple_get, clk);
of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
return;
out_free_characteristics:
......
......@@ -75,13 +75,14 @@ static const struct clk_ops plldiv_ops = {
.set_rate = clk_plldiv_set_rate,
};
static struct clk * __init
static struct clk_hw * __init
at91_clk_register_plldiv(struct regmap *regmap, const char *name,
const char *parent_name)
{
struct clk_plldiv *plldiv;
struct clk *clk = NULL;
struct clk_hw *hw;
struct clk_init_data init;
int ret;
plldiv = kzalloc(sizeof(*plldiv), GFP_KERNEL);
if (!plldiv)
......@@ -96,18 +97,20 @@ at91_clk_register_plldiv(struct regmap *regmap, const char *name,
plldiv->hw.init = &init;
plldiv->regmap = regmap;
clk = clk_register(NULL, &plldiv->hw);
if (IS_ERR(clk))
hw = &plldiv->hw;
ret = clk_hw_register(NULL, &plldiv->hw);
if (ret) {
kfree(plldiv);
hw = ERR_PTR(ret);
}
return clk;
return hw;
}
static void __init
of_at91sam9x5_clk_plldiv_setup(struct device_node *np)
{
struct clk *clk;
struct clk_hw *hw;
const char *parent_name;
const char *name = np->name;
struct regmap *regmap;
......@@ -120,12 +123,11 @@ of_at91sam9x5_clk_plldiv_setup(struct device_node *np)
if (IS_ERR(regmap))
return;
clk = at91_clk_register_plldiv(regmap, name, parent_name);
if (IS_ERR(clk))
hw = at91_clk_register_plldiv(regmap, name, parent_name);
if (IS_ERR(hw))
return;
of_clk_add_provider(np, of_clk_src_simple_get, clk);
return;
of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
}
CLK_OF_DECLARE(at91sam9x5_clk_plldiv, "atmel,at91sam9x5-clk-plldiv",
of_at91sam9x5_clk_plldiv_setup);
......@@ -170,15 +170,16 @@ static const struct clk_ops programmable_ops = {
.set_rate = clk_programmable_set_rate,
};
static struct clk * __init
static struct clk_hw * __init
at91_clk_register_programmable(struct regmap *regmap,
const char *name, const char **parent_names,
u8 num_parents, u8 id,
const struct clk_programmable_layout *layout)
{
struct clk_programmable *prog;
struct clk *clk = NULL;
struct clk_hw *hw;
struct clk_init_data init;
int ret;
if (id > PROG_ID_MAX)
return ERR_PTR(-EINVAL);
......@@ -198,11 +199,14 @@ at91_clk_register_programmable(struct regmap *regmap,
prog->hw.init = &init;
prog->regmap = regmap;
clk = clk_register(NULL, &prog->hw);
if (IS_ERR(clk))
hw = &prog->hw;
ret = clk_hw_register(NULL, &prog->hw);
if (ret) {
kfree(prog);
hw = &prog->hw;
}
return clk;
return hw;
}
static const struct clk_programmable_layout at91rm9200_programmable_layout = {
......@@ -229,7 +233,7 @@ of_at91_clk_prog_setup(struct device_node *np,
{
int num;
u32 id;
struct clk *clk;
struct clk_hw *hw;
unsigned int num_parents;
const char *parent_names[PROG_SOURCE_MAX];
const char *name;
......@@ -257,13 +261,13 @@ of_at91_clk_prog_setup(struct device_node *np,
if (of_property_read_string(np, "clock-output-names", &name))
name = progclknp->name;
clk = at91_clk_register_programmable(regmap, name,
hw = at91_clk_register_programmable(regmap, name,
parent_names, num_parents,
id, layout);
if (IS_ERR(clk))
if (IS_ERR(hw))
continue;
of_clk_add_provider(progclknp, of_clk_src_simple_get, clk);
of_clk_add_hw_provider(progclknp, of_clk_hw_simple_get, hw);
}
}
......
This diff is collapsed.
......@@ -111,13 +111,14 @@ static const struct clk_ops at91sam9x5_smd_ops = {
.set_rate = at91sam9x5_clk_smd_set_rate,
};
static struct clk * __init
static struct clk_hw * __init
at91sam9x5_clk_register_smd(struct regmap *regmap, const char *name,
const char **parent_names, u8 num_parents)
{
struct at91sam9x5_clk_smd *smd;
struct clk *clk = NULL;
struct clk_hw *hw;
struct clk_init_data init;
int ret;
smd = kzalloc(sizeof(*smd), GFP_KERNEL);
if (!smd)
......@@ -132,16 +133,19 @@ at91sam9x5_clk_register_smd(struct regmap *regmap, const char *name,
smd->hw.init = &init;
smd->regmap = regmap;
clk = clk_register(NULL, &smd->hw);
if (IS_ERR(clk))
hw = &smd->hw;
ret = clk_hw_register(NULL, &smd->hw);
if (ret) {
kfree(smd);
hw = ERR_PTR(ret);
}
return clk;
return hw;
}
static void __init of_at91sam9x5_clk_smd_setup(struct device_node *np)
{
struct clk *clk;
struct clk_hw *hw;
unsigned int num_parents;
const char *parent_names[SMD_SOURCE_MAX];
const char *name = np->name;
......@@ -159,12 +163,12 @@ static void __init of_at91sam9x5_clk_smd_setup(struct device_node *np)
if (IS_ERR(regmap))
return;
clk = at91sam9x5_clk_register_smd(regmap, name, parent_names,
hw = at91sam9x5_clk_register_smd(regmap, name, parent_names,
num_parents);
if (IS_ERR(clk))
if (IS_ERR(hw))
return;
of_clk_add_provider(np, of_clk_src_simple_get, clk);
of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
}
CLK_OF_DECLARE(at91sam9x5_clk_smd, "atmel,at91sam9x5-clk-smd",
of_at91sam9x5_clk_smd_setup);
......@@ -88,13 +88,14 @@ static const struct clk_ops system_ops = {
.is_prepared = clk_system_is_prepared,
};
static struct clk * __init
static struct clk_hw * __init
at91_clk_register_system(struct regmap *regmap, const char *name,
const char *parent_name, u8 id)
{
struct clk_system *sys;
struct clk *clk = NULL;
struct clk_hw *hw;
struct clk_init_data init;
int ret;
if (!parent_name || id > SYSTEM_MAX_ID)
return ERR_PTR(-EINVAL);
......@@ -113,18 +114,21 @@ at91_clk_register_system(struct regmap *regmap, const char *name,
sys->hw.init = &init;
sys->regmap = regmap;
clk = clk_register(NULL, &sys->hw);
if (IS_ERR(clk))
hw = &sys->hw;
ret = clk_hw_register(NULL, &sys->hw);
if (ret) {
kfree(sys);
hw = ERR_PTR(ret);
}
return clk;
return hw;
}
static void __init of_at91rm9200_clk_sys_setup(struct device_node *np)
{
int num;
u32 id;
struct clk *clk;
struct clk_hw *hw;
const char *name;
struct device_node *sysclknp;
const char *parent_name;
......@@ -147,11 +151,11 @@ static void __init of_at91rm9200_clk_sys_setup(struct device_node *np)
parent_name = of_clk_get_parent_name(sysclknp, 0);
clk = at91_clk_register_system(regmap, name, parent_name, id);
if (IS_ERR(clk))
hw = at91_clk_register_system(regmap, name, parent_name, id);
if (IS_ERR(hw))
continue;
of_clk_add_provider(sysclknp, of_clk_src_simple_get, clk);
of_clk_add_hw_provider(sysclknp, of_clk_hw_simple_get, hw);
}
}
CLK_OF_DECLARE(at91rm9200_clk_sys, "atmel,at91rm9200-clk-system",
......
......@@ -192,13 +192,14 @@ static const struct clk_ops at91sam9n12_usb_ops = {
.set_rate = at91sam9x5_clk_usb_set_rate,
};
static struct clk * __init
static struct clk_hw * __init
at91sam9x5_clk_register_usb(struct regmap *regmap, const char *name,
const char **parent_names, u8 num_parents)
{
struct at91sam9x5_clk_usb *usb;
struct clk *clk = NULL;
struct clk_hw *hw;
struct clk_init_data init;
int ret;
usb = kzalloc(sizeof(*usb), GFP_KERNEL);
if (!usb)
......@@ -214,20 +215,24 @@ at91sam9x5_clk_register_usb(struct regmap *regmap, const char *name,
usb->hw.init = &init;
usb->regmap = regmap;
clk = clk_register(NULL, &usb->hw);
if (IS_ERR(clk))
hw = &usb->hw;
ret = clk_hw_register(NULL, &usb->hw);
if (ret) {
kfree(usb);
hw = ERR_PTR(ret);
}
return clk;
return hw;
}
static struct clk * __init
static struct clk_hw * __init
at91sam9n12_clk_register_usb(struct regmap *regmap, const char *name,
const char *parent_name)
{
struct at91sam9x5_clk_usb *usb;
struct clk *clk = NULL;
struct clk_hw *hw;
struct clk_init_data init;
int ret;
usb = kzalloc(sizeof(*usb), GFP_KERNEL);
if (!usb)
......@@ -242,11 +247,14 @@ at91sam9n12_clk_register_usb(struct regmap *regmap, const char *name,
usb->hw.init = &init;
usb->regmap = regmap;
clk = clk_register(NULL, &usb->hw);
if (IS_ERR(clk))
hw = &usb->hw;
ret = clk_hw_register(NULL, &usb->hw);
if (ret) {
kfree(usb);
hw = ERR_PTR(ret);
}
return clk;
return hw;
}
static unsigned long at91rm9200_clk_usb_recalc_rate(struct clk_hw *hw,
......@@ -334,13 +342,14 @@ static const struct clk_ops at91rm9200_usb_ops = {
.set_rate = at91rm9200_clk_usb_set_rate,
};
static struct clk * __init
static struct clk_hw * __init
at91rm9200_clk_register_usb(struct regmap *regmap, const char *name,
const char *parent_name, const u32 *divisors)
{
struct at91rm9200_clk_usb *usb;
struct clk *clk = NULL;
struct clk_hw *hw;
struct clk_init_data init;
int ret;
usb = kzalloc(sizeof(*usb), GFP_KERNEL);
if (!usb)
......@@ -356,16 +365,19 @@ at91rm9200_clk_register_usb(struct regmap *regmap, const char *name,
usb->regmap = regmap;
memcpy(usb->divisors, divisors, sizeof(usb->divisors));
clk = clk_register(NULL, &usb->hw);
if (IS_ERR(clk))
hw = &usb->hw;
ret = clk_hw_register(NULL, &usb->hw);
if (ret) {
kfree(usb);
hw = ERR_PTR(ret);
}
return clk;
return hw;
}
static void __init of_at91sam9x5_clk_usb_setup(struct device_node *np)
{
struct clk *clk;
struct clk_hw *hw;
unsigned int num_parents;
const char *parent_names[USB_SOURCE_MAX];
const char *name = np->name;
......@@ -383,19 +395,19 @@ static void __init of_at91sam9x5_clk_usb_setup(struct device_node *np)
if (IS_ERR(regmap))
return;
clk = at91sam9x5_clk_register_usb(regmap, name, parent_names,
num_parents);
if (IS_ERR(clk))
hw = at91sam9x5_clk_register_usb(regmap, name, parent_names,
num_parents);
if (IS_ERR(hw))
return;
of_clk_add_provider(np, of_clk_src_simple_get, clk);
of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
}
CLK_OF_DECLARE(at91sam9x5_clk_usb, "atmel,at91sam9x5-clk-usb",
of_at91sam9x5_clk_usb_setup);
static void __init of_at91sam9n12_clk_usb_setup(struct device_node *np)
{
struct clk *clk;
struct clk_hw *hw;
const char *parent_name;
const char *name = np->name;
struct regmap *regmap;
......@@ -410,18 +422,18 @@ static void __init of_at91sam9n12_clk_usb_setup(struct device_node *np)
if (IS_ERR(regmap))
return;
clk = at91sam9n12_clk_register_usb(regmap, name, parent_name);
if (IS_ERR(clk))
hw = at91sam9n12_clk_register_usb(regmap, name, parent_name);
if (IS_ERR(hw))
return;
of_clk_add_provider(np, of_clk_src_simple_get, clk);
of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
}
CLK_OF_DECLARE(at91sam9n12_clk_usb, "atmel,at91sam9n12-clk-usb",
of_at91sam9n12_clk_usb_setup);
static void __init of_at91rm9200_clk_usb_setup(struct device_node *np)
{
struct clk *clk;
struct clk_hw *hw;
const char *parent_name;
const char *name = np->name;
u32 divisors[4] = {0, 0, 0, 0};
......@@ -440,12 +452,11 @@ static void __init of_at91rm9200_clk_usb_setup(struct device_node *np)
regmap = syscon_node_to_regmap(of_get_parent(np));
if (IS_ERR(regmap))
return;
clk = at91rm9200_clk_register_usb(regmap, name, parent_name, divisors);
if (IS_ERR(clk))
hw = at91rm9200_clk_register_usb(regmap, name, parent_name, divisors);
if (IS_ERR(hw))
return;
of_clk_add_provider(np, of_clk_src_simple_get, clk);
of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
}
CLK_OF_DECLARE(at91rm9200_clk_usb, "atmel,at91rm9200-clk-usb",
of_at91rm9200_clk_usb_setup);
......@@ -77,13 +77,14 @@ static const struct clk_ops utmi_ops = {
.recalc_rate = clk_utmi_recalc_rate,
};
static struct clk * __init
static struct clk_hw * __init
at91_clk_register_utmi(struct regmap *regmap,
const char *name, const char *parent_name)
{
struct clk_utmi *utmi;
struct clk *clk = NULL;
struct clk_hw *hw;
struct clk_init_data init;
int ret;
utmi = kzalloc(sizeof(*utmi), GFP_KERNEL);
if (!utmi)
......@@ -98,16 +99,19 @@ at91_clk_register_utmi(struct regmap *regmap,
utmi->hw.init = &init;
utmi->regmap = regmap;
clk = clk_register(NULL, &utmi->hw);
if (IS_ERR(clk))
hw = &utmi->hw;
ret = clk_hw_register(NULL, &utmi->hw);
if (ret) {
kfree(utmi);
hw = ERR_PTR(ret);
}
return clk;
return hw;
}
static void __init of_at91sam9x5_clk_utmi_setup(struct device_node *np)
{
struct clk *clk;
struct clk_hw *hw;
const char *parent_name;
const char *name = np->name;
struct regmap *regmap;
......@@ -120,11 +124,11 @@ static void __init of_at91sam9x5_clk_utmi_setup(struct device_node *np)
if (IS_ERR(regmap))
return;
clk = at91_clk_register_utmi(regmap, name, parent_name);
if (IS_ERR(clk))
hw = at91_clk_register_utmi(regmap, name, parent_name);
if (IS_ERR(hw))
return;
of_clk_add_provider(np, of_clk_src_simple_get, clk);
of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
return;
}
CLK_OF_DECLARE(at91sam9x5_clk_utmi, "atmel,at91sam9x5-clk-utmi",
......
This diff is collapsed.
/*
* drivers/clk/at91/sckc.h
*
* Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#ifndef __AT91_SCKC_H_
#define __AT91_SCKC_H_
extern void __init of_at91sam9x5_clk_slow_osc_setup(struct device_node *np,
void __iomem *sckcr);
extern void __init of_at91sam9x5_clk_slow_rc_osc_setup(struct device_node *np,
void __iomem *sckcr);
extern void __init of_at91sam9x5_clk_slow_setup(struct device_node *np,
void __iomem *sckcr);
#endif /* __AT91_SCKC_H_ */
......@@ -113,8 +113,8 @@ static void of_artpec6_clkctrl_setup(struct device_node *np)
of_clk_add_provider(np, of_clk_src_onecell_get, &clkdata->clk_data);
}
CLK_OF_DECLARE(artpec6_clkctrl, "axis,artpec6-clkctrl",
of_artpec6_clkctrl_setup);
CLK_OF_DECLARE_DRIVER(artpec6_clkctrl, "axis,artpec6-clkctrl",
of_artpec6_clkctrl_setup);
static int artpec6_clkctrl_probe(struct platform_device *pdev)
{
......
......@@ -19,8 +19,36 @@ config CLK_BCM_KONA
in the BCM281xx and BCM21664 families.
config COMMON_CLK_IPROC
bool
bool "Broadcom iProc clock support"
depends on ARCH_BCM_IPROC || COMPILE_TEST
depends on COMMON_CLK
default ARCH_BCM_IPROC
help
Enable common clock framework support for Broadcom SoCs
based on the iProc architecture
if COMMON_CLK_IPROC
config CLK_BCM_CYGNUS
bool "Broadcom Cygnus clock support"
depends on ARCH_BCM_CYGNUS || COMPILE_TEST
default ARCH_BCM_CYGNUS
help
Enable common clock framework support for the Broadcom Cygnus SoC
config CLK_BCM_NSP
bool "Broadcom Northstar/Northstar Plus clock support"
depends on ARCH_BCM_5301X || ARCH_BCM_NSP || COMPILE_TEST
default ARCH_BCM_5301X || ARCH_BCM_NSP
help
Enable common clock framework support for the Broadcom Northstar and
Northstar Plus SoCs
config CLK_BCM_NS2
bool "Broadcom Northstar 2 clock support"
depends on ARCH_BCM_IPROC || COMPILE_TEST
default ARCH_BCM_IPROC
help
Enable common clock framework support for the Broadcom Northstar 2 SoC
endif
......@@ -6,7 +6,7 @@ obj-$(CONFIG_CLK_BCM_KONA) += clk-bcm21664.o
obj-$(CONFIG_COMMON_CLK_IPROC) += clk-iproc-armpll.o clk-iproc-pll.o clk-iproc-asiu.o
obj-$(CONFIG_ARCH_BCM2835) += clk-bcm2835.o
obj-$(CONFIG_ARCH_BCM2835) += clk-bcm2835-aux.o
obj-$(CONFIG_COMMON_CLK_IPROC) += clk-ns2.o
obj-$(CONFIG_ARCH_BCM_CYGNUS) += clk-cygnus.o
obj-$(CONFIG_ARCH_BCM_NSP) += clk-nsp.o
obj-$(CONFIG_ARCH_BCM_5301X) += clk-nsp.o
obj-$(CONFIG_ARCH_BCM_53573) += clk-bcm53573-ilp.o
obj-$(CONFIG_CLK_BCM_CYGNUS) += clk-cygnus.o
obj-$(CONFIG_CLK_BCM_NSP) += clk-nsp.o
obj-$(CONFIG_CLK_BCM_NS2) += clk-ns2.o
......@@ -25,7 +25,7 @@
static int bcm2835_aux_clk_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct clk_onecell_data *onecell;
struct clk_hw_onecell_data *onecell;
const char *parent;
struct clk *parent_clk;
struct resource *res;
......@@ -41,28 +41,24 @@ static int bcm2835_aux_clk_probe(struct platform_device *pdev)
if (IS_ERR(reg))
return PTR_ERR(reg);
onecell = devm_kmalloc(dev, sizeof(*onecell), GFP_KERNEL);
onecell = devm_kmalloc(dev, sizeof(*onecell) + sizeof(*onecell->hws) *
BCM2835_AUX_CLOCK_COUNT, GFP_KERNEL);
if (!onecell)
return -ENOMEM;
onecell->clk_num = BCM2835_AUX_CLOCK_COUNT;
onecell->clks = devm_kcalloc(dev, BCM2835_AUX_CLOCK_COUNT,
sizeof(*onecell->clks), GFP_KERNEL);
if (!onecell->clks)
return -ENOMEM;
onecell->num = BCM2835_AUX_CLOCK_COUNT;
gate = reg + BCM2835_AUXENB;
onecell->clks[BCM2835_AUX_CLOCK_UART] =
clk_register_gate(dev, "aux_uart", parent, 0, gate, 0, 0, NULL);
onecell->clks[BCM2835_AUX_CLOCK_SPI1] =
clk_register_gate(dev, "aux_spi1", parent, 0, gate, 1, 0, NULL);
onecell->hws[BCM2835_AUX_CLOCK_UART] =
clk_hw_register_gate(dev, "aux_uart", parent, 0, gate, 0, 0, NULL);
onecell->clks[BCM2835_AUX_CLOCK_SPI2] =
clk_register_gate(dev, "aux_spi2", parent, 0, gate, 2, 0, NULL);
onecell->hws[BCM2835_AUX_CLOCK_SPI1] =
clk_hw_register_gate(dev, "aux_spi1", parent, 0, gate, 1, 0, NULL);
of_clk_add_provider(pdev->dev.of_node, of_clk_src_onecell_get, onecell);
onecell->hws[BCM2835_AUX_CLOCK_SPI2] =
clk_hw_register_gate(dev, "aux_spi2", parent, 0, gate, 2, 0, NULL);
return 0;
return of_clk_add_hw_provider(pdev->dev.of_node, of_clk_hw_onecell_get,
onecell);
}
static const struct of_device_id bcm2835_aux_clk_of_match[] = {
......
......@@ -36,6 +36,7 @@
#include <linux/clk-provider.h>
#include <linux/clkdev.h>
#include <linux/clk.h>
#include <linux/clk/bcm2835.h>
#include <linux/debugfs.h>
#include <linux/module.h>
......@@ -302,8 +303,8 @@ struct bcm2835_cprman {
spinlock_t regs_lock; /* spinlock for all clocks */
const char *osc_name;
struct clk_onecell_data onecell;
struct clk *clks[];
/* Must be last */
struct clk_hw_onecell_data onecell;
};
static inline void cprman_write(struct bcm2835_cprman *cprman, u32 reg, u32 val)
......@@ -344,24 +345,24 @@ static int bcm2835_debugfs_regset(struct bcm2835_cprman *cprman, u32 base,
*/
void __init bcm2835_init_clocks(void)
{
struct clk *clk;
struct clk_hw *hw;
int ret;
clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL, 0, 126000000);
if (IS_ERR(clk))
hw = clk_hw_register_fixed_rate(NULL, "apb_pclk", NULL, 0, 126000000);
if (IS_ERR(hw))
pr_err("apb_pclk not registered\n");
clk = clk_register_fixed_rate(NULL, "uart0_pclk", NULL, 0, 3000000);
if (IS_ERR(clk))
hw = clk_hw_register_fixed_rate(NULL, "uart0_pclk", NULL, 0, 3000000);
if (IS_ERR(hw))
pr_err("uart0_pclk not registered\n");
ret = clk_register_clkdev(clk, NULL, "20201000.uart");
ret = clk_hw_register_clkdev(hw, NULL, "20201000.uart");
if (ret)
pr_err("uart0_pclk alias not registered\n");
clk = clk_register_fixed_rate(NULL, "uart1_pclk", NULL, 0, 125000000);
if (IS_ERR(clk))
hw = clk_hw_register_fixed_rate(NULL, "uart1_pclk", NULL, 0, 125000000);
if (IS_ERR(hw))
pr_err("uart1_pclk not registered\n");
ret = clk_register_clkdev(clk, NULL, "20215000.uart");
ret = clk_hw_register_clkdev(hw, NULL, "20215000.uart");
if (ret)
pr_err("uart1_pclk alias not registered\n");
}
......@@ -443,6 +444,8 @@ struct bcm2835_clock_data {
/* Number of fractional bits in the divider */
u32 frac_bits;
u32 flags;
bool is_vpu_clock;
bool is_mash_clock;
};
......@@ -1006,16 +1009,28 @@ static int bcm2835_clock_set_rate(struct clk_hw *hw,
return 0;
}
static bool
bcm2835_clk_is_pllc(struct clk_hw *hw)
{
if (!hw)
return false;
return strncmp(clk_hw_get_name(hw), "pllc", 4) == 0;
}
static int bcm2835_clock_determine_rate(struct clk_hw *hw,
struct clk_rate_request *req)
{
struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw);
struct clk_hw *parent, *best_parent = NULL;
bool current_parent_is_pllc;
unsigned long rate, best_rate = 0;
unsigned long prate, best_prate = 0;
size_t i;
u32 div;
current_parent_is_pllc = bcm2835_clk_is_pllc(clk_hw_get_parent(hw));
/*
* Select parent clock that results in the closest but lower rate
*/
......@@ -1023,6 +1038,17 @@ static int bcm2835_clock_determine_rate(struct clk_hw *hw,
parent = clk_hw_get_parent_by_index(hw, i);
if (!parent)
continue;
/*
* Don't choose a PLLC-derived clock as our parent
* unless it had been manually set that way. PLLC's
* frequency gets adjusted by the firmware due to
* over-temp or under-voltage conditions, without
* prior notification to our clock consumer.
*/
if (bcm2835_clk_is_pllc(parent) && !current_parent_is_pllc)
continue;
prate = clk_hw_get_rate(parent);
div = bcm2835_clock_choose_div(hw, req->rate, prate, true);
rate = bcm2835_clock_rate_from_divisor(clock, prate, div);
......@@ -1121,11 +1147,12 @@ static const struct clk_ops bcm2835_vpu_clock_clk_ops = {
.debug_init = bcm2835_clock_debug_init,
};
static struct clk *bcm2835_register_pll(struct bcm2835_cprman *cprman,
const struct bcm2835_pll_data *data)
static struct clk_hw *bcm2835_register_pll(struct bcm2835_cprman *cprman,
const struct bcm2835_pll_data *data)
{
struct bcm2835_pll *pll;
struct clk_init_data init;
int ret;
memset(&init, 0, sizeof(init));
......@@ -1144,17 +1171,20 @@ static struct clk *bcm2835_register_pll(struct bcm2835_cprman *cprman,
pll->data = data;
pll->hw.init = &init;
return devm_clk_register(cprman->dev, &pll->hw);
ret = devm_clk_hw_register(cprman->dev, &pll->hw);
if (ret)
return NULL;
return &pll->hw;
}
static struct clk *
static struct clk_hw *
bcm2835_register_pll_divider(struct bcm2835_cprman *cprman,
const struct bcm2835_pll_divider_data *data)
{
struct bcm2835_pll_divider *divider;
struct clk_init_data init;
struct clk *clk;
const char *divider_name;
int ret;
if (data->fixed_divider != 1) {
divider_name = devm_kasprintf(cprman->dev, GFP_KERNEL,
......@@ -1188,32 +1218,33 @@ bcm2835_register_pll_divider(struct bcm2835_cprman *cprman,
divider->cprman = cprman;
divider->data = data;
clk = devm_clk_register(cprman->dev, &divider->div.hw);
if (IS_ERR(clk))
return clk;
ret = devm_clk_hw_register(cprman->dev, &divider->div.hw);
if (ret)
return ERR_PTR(ret);
/*
* PLLH's channels have a fixed divide by 10 afterwards, which
* is what our consumers are actually using.
*/
if (data->fixed_divider != 1) {
return clk_register_fixed_factor(cprman->dev, data->name,
divider_name,
CLK_SET_RATE_PARENT,
1,
data->fixed_divider);
return clk_hw_register_fixed_factor(cprman->dev, data->name,
divider_name,
CLK_SET_RATE_PARENT,
1,
data->fixed_divider);
}
return clk;
return &divider->div.hw;
}
static struct clk *bcm2835_register_clock(struct bcm2835_cprman *cprman,
static struct clk_hw *bcm2835_register_clock(struct bcm2835_cprman *cprman,
const struct bcm2835_clock_data *data)
{
struct bcm2835_clock *clock;
struct clk_init_data init;
const char *parents[1 << CM_SRC_BITS];
size_t i;
int ret;
/*
* Replace our "xosc" references with the oscillator's
......@@ -1230,13 +1261,19 @@ static struct clk *bcm2835_register_clock(struct bcm2835_cprman *cprman,
init.parent_names = parents;
init.num_parents = data->num_mux_parents;
init.name = data->name;
init.flags = CLK_IGNORE_UNUSED;
init.flags = data->flags | CLK_IGNORE_UNUSED;
if (data->is_vpu_clock) {
init.ops = &bcm2835_vpu_clock_clk_ops;
} else {
init.ops = &bcm2835_clock_clk_ops;
init.flags |= CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE;
/* If the clock wasn't actually enabled at boot, it's not
* critical.
*/
if (!(cprman_read(cprman, data->ctl_reg) & CM_ENABLE))
init.flags &= ~CLK_IS_CRITICAL;
}
clock = devm_kzalloc(cprman->dev, sizeof(*clock), GFP_KERNEL);
......@@ -1247,7 +1284,10 @@ static struct clk *bcm2835_register_clock(struct bcm2835_cprman *cprman,
clock->data = data;
clock->hw.init = &init;
return devm_clk_register(cprman->dev, &clock->hw);
ret = devm_clk_hw_register(cprman->dev, &clock->hw);
if (ret)
return ERR_PTR(ret);
return &clock->hw;
}
static struct clk *bcm2835_register_gate(struct bcm2835_cprman *cprman,
......@@ -1259,8 +1299,8 @@ static struct clk *bcm2835_register_gate(struct bcm2835_cprman *cprman,
CM_GATE_BIT, 0, &cprman->regs_lock);
}
typedef struct clk *(*bcm2835_clk_register)(struct bcm2835_cprman *cprman,
const void *data);
typedef struct clk_hw *(*bcm2835_clk_register)(struct bcm2835_cprman *cprman,
const void *data);
struct bcm2835_clk_desc {
bcm2835_clk_register clk_register;
const void *data;
......@@ -1649,6 +1689,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.div_reg = CM_VPUDIV,
.int_bits = 12,
.frac_bits = 8,
.flags = CLK_IS_CRITICAL,
.is_vpu_clock = true),
/* clocks with per parent mux */
......@@ -1705,13 +1746,15 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.div_reg = CM_GP1DIV,
.int_bits = 12,
.frac_bits = 12,
.flags = CLK_IS_CRITICAL,
.is_mash_clock = true),
[BCM2835_CLOCK_GP2] = REGISTER_PER_CLK(
.name = "gp2",
.ctl_reg = CM_GP2CTL,
.div_reg = CM_GP2DIV,
.int_bits = 12,
.frac_bits = 12),
.frac_bits = 12,
.flags = CLK_IS_CRITICAL),
/* HDMI state machine */
[BCM2835_CLOCK_HSM] = REGISTER_PER_CLK(
......@@ -1790,18 +1833,38 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.ctl_reg = CM_PERIICTL),
};
/*
* Permanently take a reference on the parent of the SDRAM clock.
*
* While the SDRAM is being driven by its dedicated PLL most of the
* time, there is a little loop running in the firmware that
* periodically switches the SDRAM to using our CM clock to do PVT
* recalibration, with the assumption that the previously configured
* SDRAM parent is still enabled and running.
*/
static int bcm2835_mark_sdc_parent_critical(struct clk *sdc)
{
struct clk *parent = clk_get_parent(sdc);
if (IS_ERR(parent))
return PTR_ERR(parent);
return clk_prepare_enable(parent);
}
static int bcm2835_clk_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct clk **clks;
struct clk_hw **hws;
struct bcm2835_cprman *cprman;
struct resource *res;
const struct bcm2835_clk_desc *desc;
const size_t asize = ARRAY_SIZE(clk_desc_array);
size_t i;
int ret;
cprman = devm_kzalloc(dev,
sizeof(*cprman) + asize * sizeof(*clks),
cprman = devm_kzalloc(dev, sizeof(*cprman) +
sizeof(*cprman->onecell.hws) * asize,
GFP_KERNEL);
if (!cprman)
return -ENOMEM;
......@@ -1819,18 +1882,21 @@ static int bcm2835_clk_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, cprman);
cprman->onecell.clk_num = asize;
cprman->onecell.clks = cprman->clks;
clks = cprman->clks;
cprman->onecell.num = asize;
hws = cprman->onecell.hws;
for (i = 0; i < asize; i++) {
desc = &clk_desc_array[i];
if (desc->clk_register && desc->data)
clks[i] = desc->clk_register(cprman, desc->data);
hws[i] = desc->clk_register(cprman, desc->data);
}
return of_clk_add_provider(dev->of_node, of_clk_src_onecell_get,
&cprman->onecell);
ret = bcm2835_mark_sdc_parent_critical(hws[BCM2835_CLOCK_SDRAM]->clk);
if (ret)
return ret;
return of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get,
&cprman->onecell);
}
static const struct of_device_id bcm2835_clk_of_match[] = {
......
/*
* Copyright (C) 2016 Rafał Miłecki <rafal@milecki.pl>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/clk-provider.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/mfd/syscon.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/regmap.h>
#include <linux/slab.h>
#define PMU_XTAL_FREQ_RATIO 0x66c
#define XTAL_ALP_PER_4ILP 0x00001fff
#define XTAL_CTL_EN 0x80000000
#define PMU_SLOW_CLK_PERIOD 0x6dc
struct bcm53573_ilp {
struct clk_hw hw;
struct regmap *regmap;
};
static int bcm53573_ilp_enable(struct clk_hw *hw)
{
struct bcm53573_ilp *ilp = container_of(hw, struct bcm53573_ilp, hw);
regmap_write(ilp->regmap, PMU_SLOW_CLK_PERIOD, 0x10199);
regmap_write(ilp->regmap, 0x674, 0x10000);
return 0;
}
static void bcm53573_ilp_disable(struct clk_hw *hw)
{
struct bcm53573_ilp *ilp = container_of(hw, struct bcm53573_ilp, hw);
regmap_write(ilp->regmap, PMU_SLOW_CLK_PERIOD, 0);
regmap_write(ilp->regmap, 0x674, 0);
}
static unsigned long bcm53573_ilp_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
struct bcm53573_ilp *ilp = container_of(hw, struct bcm53573_ilp, hw);
struct regmap *regmap = ilp->regmap;
u32 last_val, cur_val;
int sum = 0, num = 0, loop_num = 0;
int avg;
/* Enable measurement */
regmap_write(regmap, PMU_XTAL_FREQ_RATIO, XTAL_CTL_EN);
/* Read initial value */
regmap_read(regmap, PMU_XTAL_FREQ_RATIO, &last_val);
last_val &= XTAL_ALP_PER_4ILP;
/*
* At minimum we should loop for a bit to let hardware do the
* measurement. This isn't very accurate however, so for a better
* precision lets try getting 20 different values for and use average.
*/
while (num < 20) {
regmap_read(regmap, PMU_XTAL_FREQ_RATIO, &cur_val);
cur_val &= XTAL_ALP_PER_4ILP;
if (cur_val != last_val) {
/* Got different value, use it */
sum += cur_val;
num++;
loop_num = 0;
last_val = cur_val;
} else if (++loop_num > 5000) {
/* Same value over and over, give up */
sum += cur_val;
num++;
break;
}
cpu_relax();
}
/* Disable measurement to save power */
regmap_write(regmap, PMU_XTAL_FREQ_RATIO, 0x0);
avg = sum / num;
return parent_rate * 4 / avg;
}
static const struct clk_ops bcm53573_ilp_clk_ops = {
.enable = bcm53573_ilp_enable,
.disable = bcm53573_ilp_disable,
.recalc_rate = bcm53573_ilp_recalc_rate,
};
static void bcm53573_ilp_init(struct device_node *np)
{
struct bcm53573_ilp *ilp;
struct clk_init_data init = { };
const char *parent_name;
int err;
ilp = kzalloc(sizeof(*ilp), GFP_KERNEL);
if (!ilp)
return;
parent_name = of_clk_get_parent_name(np, 0);
if (!parent_name) {
err = -ENOENT;
goto err_free_ilp;
}
ilp->regmap = syscon_node_to_regmap(of_get_parent(np));
if (IS_ERR(ilp->regmap)) {
err = PTR_ERR(ilp->regmap);
goto err_free_ilp;
}
init.name = np->name;
init.ops = &bcm53573_ilp_clk_ops;
init.parent_names = &parent_name;
init.num_parents = 1;
ilp->hw.init = &init;
err = clk_hw_register(NULL, &ilp->hw);
if (err)
goto err_free_ilp;
err = of_clk_add_hw_provider(np, of_clk_hw_simple_get, &ilp->hw);
if (err)
goto err_clk_hw_unregister;
return;
err_clk_hw_unregister:
clk_hw_unregister(&ilp->hw);
err_free_ilp:
kfree(ilp);
pr_err("Failed to init ILP clock: %d\n", err);
}
/* We need it very early for arch code, before device model gets ready */
CLK_OF_DECLARE(bcm53573_ilp_clk, "brcm,bcm53573-ilp", bcm53573_ilp_init);
......@@ -586,8 +586,8 @@ static u32 *parent_process(const char *clocks[],
}
/* There is at least one parent, so allocate a selector array */
parent_sel = kmalloc(parent_count * sizeof(*parent_sel), GFP_KERNEL);
parent_sel = kmalloc_array(parent_count, sizeof(*parent_sel),
GFP_KERNEL);
if (!parent_sel) {
pr_err("%s: error allocating %u parent selectors\n", __func__,
parent_count);
......@@ -696,77 +696,69 @@ static void bcm_clk_teardown(struct kona_clk *bcm_clk)
bcm_clk->type = bcm_clk_none;
}
static void kona_clk_teardown(struct clk *clk)
static void kona_clk_teardown(struct clk_hw *hw)
{
struct clk_hw *hw;
struct kona_clk *bcm_clk;
if (!clk)
if (!hw)
return;
hw = __clk_get_hw(clk);
if (!hw) {
pr_err("%s: clk %p has null hw pointer\n", __func__, clk);
return;
}
clk_unregister(clk);
clk_hw_unregister(hw);
bcm_clk = to_kona_clk(hw);
bcm_clk_teardown(bcm_clk);
}
struct clk *kona_clk_setup(struct kona_clk *bcm_clk)
static int kona_clk_setup(struct kona_clk *bcm_clk)
{
int ret;
struct clk_init_data *init_data = &bcm_clk->init_data;
struct clk *clk = NULL;
switch (bcm_clk->type) {
case bcm_clk_peri:
if (peri_clk_setup(bcm_clk->u.data, init_data))
return NULL;
ret = peri_clk_setup(bcm_clk->u.data, init_data);
if (ret)
return ret;
break;
default:
pr_err("%s: clock type %d invalid for %s\n", __func__,
(int)bcm_clk->type, init_data->name);
return NULL;
return -EINVAL;
}
/* Make sure everything makes sense before we set it up */
if (!kona_clk_valid(bcm_clk)) {
pr_err("%s: clock data invalid for %s\n", __func__,
init_data->name);
ret = -EINVAL;
goto out_teardown;
}
bcm_clk->hw.init = init_data;
clk = clk_register(NULL, &bcm_clk->hw);
if (IS_ERR(clk)) {
pr_err("%s: error registering clock %s (%ld)\n", __func__,
init_data->name, PTR_ERR(clk));
ret = clk_hw_register(NULL, &bcm_clk->hw);
if (ret) {
pr_err("%s: error registering clock %s (%d)\n", __func__,
init_data->name, ret);
goto out_teardown;
}
BUG_ON(!clk);
return clk;
return 0;
out_teardown:
bcm_clk_teardown(bcm_clk);
return NULL;
return ret;
}
static void ccu_clks_teardown(struct ccu_data *ccu)
{
u32 i;
for (i = 0; i < ccu->clk_data.clk_num; i++)
kona_clk_teardown(ccu->clk_data.clks[i]);
kfree(ccu->clk_data.clks);
for (i = 0; i < ccu->clk_num; i++)
kona_clk_teardown(&ccu->kona_clks[i].hw);
}
static void kona_ccu_teardown(struct ccu_data *ccu)
{
kfree(ccu->clk_data.clks);
ccu->clk_data.clks = NULL;
if (!ccu->base)
return;
......@@ -793,6 +785,20 @@ static bool ccu_data_valid(struct ccu_data *ccu)
return true;
}
static struct clk_hw *
of_clk_kona_onecell_get(struct of_phandle_args *clkspec, void *data)
{
struct ccu_data *ccu = data;
unsigned int idx = clkspec->args[0];
if (idx >= ccu->clk_num) {
pr_err("%s: invalid index %u\n", __func__, idx);
return ERR_PTR(-EINVAL);
}
return &ccu->kona_clks[idx].hw;
}
/*
* Set up a CCU. Call the provided ccu_clks_setup callback to
* initialize the array of clocks provided by the CCU.
......@@ -805,18 +811,6 @@ void __init kona_dt_ccu_setup(struct ccu_data *ccu,
unsigned int i;
int ret;
if (ccu->clk_data.clk_num) {
size_t size;
size = ccu->clk_data.clk_num * sizeof(*ccu->clk_data.clks);
ccu->clk_data.clks = kzalloc(size, GFP_KERNEL);
if (!ccu->clk_data.clks) {
pr_err("%s: unable to allocate %u clocks for %s\n",
__func__, ccu->clk_data.clk_num, node->name);
return;
}
}
ret = of_address_to_resource(node, 0, &res);
if (ret) {
pr_err("%s: no valid CCU registers found for %s\n", __func__,
......@@ -851,13 +845,13 @@ void __init kona_dt_ccu_setup(struct ccu_data *ccu,
* the clock framework clock array (in ccu->data). Then
* register as a provider for these clocks.
*/
for (i = 0; i < ccu->clk_data.clk_num; i++) {
for (i = 0; i < ccu->clk_num; i++) {
if (!ccu->kona_clks[i].ccu)
continue;
ccu->clk_data.clks[i] = kona_clk_setup(&ccu->kona_clks[i]);
kona_clk_setup(&ccu->kona_clks[i]);
}
ret = of_clk_add_provider(node, of_clk_src_onecell_get, &ccu->clk_data);
ret = of_clk_add_hw_provider(node, of_clk_kona_onecell_get, ccu);
if (ret) {
pr_err("%s: error adding ccu %s as provider (%d)\n", __func__,
node->name, ret);
......
......@@ -1256,19 +1256,18 @@ bool __init kona_ccu_init(struct ccu_data *ccu)
{
unsigned long flags;
unsigned int which;
struct clk **clks = ccu->clk_data.clks;
struct kona_clk *kona_clks = ccu->kona_clks;
bool success = true;
flags = ccu_lock(ccu);
__ccu_write_enable(ccu);
for (which = 0; which < ccu->clk_data.clk_num; which++) {
struct kona_clk *bcm_clk;
for (which = 0; which < ccu->clk_num; which++) {
struct kona_clk *bcm_clk = &kona_clks[which];
if (!clks[which])
if (!bcm_clk->ccu)
continue;
bcm_clk = &kona_clks[which];
success &= __kona_clk_init(bcm_clk);
}
......
......@@ -481,7 +481,7 @@ struct ccu_data {
bool write_enabled; /* write access is currently enabled */
struct ccu_policy policy;
struct device_node *node;
struct clk_onecell_data clk_data;
size_t clk_num;
const char *name;
u32 range; /* byte range of address space */
struct kona_clk kona_clks[]; /* must be last */
......@@ -491,9 +491,7 @@ struct ccu_data {
#define KONA_CCU_COMMON(_prefix, _name, _ccuname) \
.name = #_name "_ccu", \
.lock = __SPIN_LOCK_UNLOCKED(_name ## _ccu_data.lock), \
.clk_data = { \
.clk_num = _prefix ## _ ## _ccuname ## _CCU_CLOCK_COUNT, \
}
.clk_num = _prefix ## _ ## _ccuname ## _CCU_CLOCK_COUNT
/* Exported globals */
......@@ -505,7 +503,6 @@ extern u64 scaled_div_max(struct bcm_clk_div *div);
extern u64 scaled_div_build(struct bcm_clk_div *div, u32 div_value,
u32 billionths);
extern struct clk *kona_clk_setup(struct kona_clk *bcm_clk);
extern void __init kona_dt_ccu_setup(struct ccu_data *ccu,
struct device_node *node);
extern bool __init kona_ccu_init(struct ccu_data *ccu);
......
......@@ -188,7 +188,7 @@ static const struct clk_ops berlin2_avpll_vco_ops = {
.recalc_rate = berlin2_avpll_vco_recalc_rate,
};
struct clk * __init berlin2_avpll_vco_register(void __iomem *base,
int __init berlin2_avpll_vco_register(void __iomem *base,
const char *name, const char *parent_name,
u8 vco_flags, unsigned long flags)
{
......@@ -197,7 +197,7 @@ struct clk * __init berlin2_avpll_vco_register(void __iomem *base,
vco = kzalloc(sizeof(*vco), GFP_KERNEL);
if (!vco)
return ERR_PTR(-ENOMEM);
return -ENOMEM;
vco->base = base;
vco->flags = vco_flags;
......@@ -208,7 +208,7 @@ struct clk * __init berlin2_avpll_vco_register(void __iomem *base,
init.num_parents = 1;
init.flags = flags;
return clk_register(NULL, &vco->hw);
return clk_hw_register(NULL, &vco->hw);
}
struct berlin2_avpll_channel {
......@@ -364,7 +364,7 @@ static const struct clk_ops berlin2_avpll_channel_ops = {
*/
static const u8 quirk_index[] __initconst = { 0, 6, 5, 4, 3, 2, 1, 7 };
struct clk * __init berlin2_avpll_channel_register(void __iomem *base,
int __init berlin2_avpll_channel_register(void __iomem *base,
const char *name, u8 index, const char *parent_name,
u8 ch_flags, unsigned long flags)
{
......@@ -373,7 +373,7 @@ struct clk * __init berlin2_avpll_channel_register(void __iomem *base,
ch = kzalloc(sizeof(*ch), GFP_KERNEL);
if (!ch)
return ERR_PTR(-ENOMEM);
return -ENOMEM;
ch->base = base;
if (ch_flags & BERLIN2_AVPLL_SCRAMBLE_QUIRK)
......@@ -389,5 +389,5 @@ struct clk * __init berlin2_avpll_channel_register(void __iomem *base,
init.num_parents = 1;
init.flags = flags;
return clk_register(NULL, &ch->hw);
return clk_hw_register(NULL, &ch->hw);
}
......@@ -19,17 +19,13 @@
#ifndef __BERLIN2_AVPLL_H
#define __BERLIN2_AVPLL_H
struct clk;
#define BERLIN2_AVPLL_BIT_QUIRK BIT(0)
#define BERLIN2_AVPLL_SCRAMBLE_QUIRK BIT(1)
struct clk * __init
berlin2_avpll_vco_register(void __iomem *base, const char *name,
int berlin2_avpll_vco_register(void __iomem *base, const char *name,
const char *parent_name, u8 vco_flags, unsigned long flags);
struct clk * __init
berlin2_avpll_channel_register(void __iomem *base, const char *name,
int berlin2_avpll_channel_register(void __iomem *base, const char *name,
u8 index, const char *parent_name, u8 ch_flags,
unsigned long flags);
......
......@@ -234,7 +234,7 @@ static const struct clk_ops berlin2_div_mux_ops = {
.get_parent = berlin2_div_get_parent,
};
struct clk * __init
struct clk_hw * __init
berlin2_div_register(const struct berlin2_div_map *map,
void __iomem *base, const char *name, u8 div_flags,
const char **parent_names, int num_parents,
......@@ -259,7 +259,7 @@ berlin2_div_register(const struct berlin2_div_map *map,
if ((div_flags & BERLIN2_DIV_HAS_MUX) == 0)
mux_ops = NULL;
return clk_register_composite(NULL, name, parent_names, num_parents,
return clk_hw_register_composite(NULL, name, parent_names, num_parents,
&div->hw, mux_ops, &div->hw, rate_ops,
&div->hw, gate_ops, flags);
}
......@@ -19,7 +19,7 @@
#ifndef __BERLIN2_DIV_H
#define __BERLIN2_DIV_H
struct clk;
struct clk_hw;
#define BERLIN2_DIV_HAS_GATE BIT(0)
#define BERLIN2_DIV_HAS_MUX BIT(1)
......@@ -80,7 +80,7 @@ struct berlin2_div_data {
u8 div_flags;
};
struct clk * __init
struct clk_hw *
berlin2_div_register(const struct berlin2_div_map *map,
void __iomem *base, const char *name, u8 div_flags,
const char **parent_names, int num_parents,
......
......@@ -84,7 +84,7 @@ static const struct clk_ops berlin2_pll_ops = {
.recalc_rate = berlin2_pll_recalc_rate,
};
struct clk * __init
int __init
berlin2_pll_register(const struct berlin2_pll_map *map,
void __iomem *base, const char *name,
const char *parent_name, unsigned long flags)
......@@ -94,7 +94,7 @@ berlin2_pll_register(const struct berlin2_pll_map *map,
pll = kzalloc(sizeof(*pll), GFP_KERNEL);
if (!pll)
return ERR_PTR(-ENOMEM);
return -ENOMEM;
/* copy pll_map to allow __initconst */
memcpy(&pll->map, map, sizeof(*map));
......@@ -106,5 +106,5 @@ berlin2_pll_register(const struct berlin2_pll_map *map,
init.num_parents = 1;
init.flags = flags;
return clk_register(NULL, &pll->hw);
return clk_hw_register(NULL, &pll->hw);
}
......@@ -19,8 +19,6 @@
#ifndef __BERLIN2_PLL_H
#define __BERLIN2_PLL_H
struct clk;
struct berlin2_pll_map {
const u8 vcodiv[16];
u8 mult;
......@@ -29,9 +27,8 @@ struct berlin2_pll_map {
u8 divsel_shift;
};
struct clk * __init
berlin2_pll_register(const struct berlin2_pll_map *map,
void __iomem *base, const char *name,
const char *parent_name, unsigned long flags);
int berlin2_pll_register(const struct berlin2_pll_map *map,
void __iomem *base, const char *name,
const char *parent_name, unsigned long flags);
#endif /* __BERLIN2_PLL_H */
......@@ -92,8 +92,7 @@
*/
#define MAX_CLKS 41
static struct clk *clks[MAX_CLKS];
static struct clk_onecell_data clk_data;
static struct clk_hw_onecell_data *clk_data;
static DEFINE_SPINLOCK(lock);
static void __iomem *gbase;
......@@ -505,8 +504,17 @@ static void __init berlin2_clock_setup(struct device_node *np)
struct device_node *parent_np = of_get_parent(np);
const char *parent_names[9];
struct clk *clk;
struct clk_hw *hw;
struct clk_hw **hws;
u8 avpll_flags = 0;
int n;
int n, ret;
clk_data = kzalloc(sizeof(*clk_data) +
sizeof(*clk_data->hws) * MAX_CLKS, GFP_KERNEL);
if (!clk_data)
return;
clk_data->num = MAX_CLKS;
hws = clk_data->hws;
gbase = of_iomap(parent_np, 0);
if (!gbase)
......@@ -526,118 +534,118 @@ static void __init berlin2_clock_setup(struct device_node *np)
}
/* simple register PLLs */
clk = berlin2_pll_register(&bg2_pll_map, gbase + REG_SYSPLLCTL0,
ret = berlin2_pll_register(&bg2_pll_map, gbase + REG_SYSPLLCTL0,
clk_names[SYSPLL], clk_names[REFCLK], 0);
if (IS_ERR(clk))
if (ret)
goto bg2_fail;
clk = berlin2_pll_register(&bg2_pll_map, gbase + REG_MEMPLLCTL0,
ret = berlin2_pll_register(&bg2_pll_map, gbase + REG_MEMPLLCTL0,
clk_names[MEMPLL], clk_names[REFCLK], 0);
if (IS_ERR(clk))
if (ret)
goto bg2_fail;
clk = berlin2_pll_register(&bg2_pll_map, gbase + REG_CPUPLLCTL0,
ret = berlin2_pll_register(&bg2_pll_map, gbase + REG_CPUPLLCTL0,
clk_names[CPUPLL], clk_names[REFCLK], 0);
if (IS_ERR(clk))
if (ret)
goto bg2_fail;
if (of_device_is_compatible(np, "marvell,berlin2-global-register"))
avpll_flags |= BERLIN2_AVPLL_SCRAMBLE_QUIRK;
/* audio/video VCOs */
clk = berlin2_avpll_vco_register(gbase + REG_AVPLLCTL0, "avpll_vcoA",
ret = berlin2_avpll_vco_register(gbase + REG_AVPLLCTL0, "avpll_vcoA",
clk_names[REFCLK], avpll_flags, 0);
if (IS_ERR(clk))
if (ret)
goto bg2_fail;
for (n = 0; n < 8; n++) {
clk = berlin2_avpll_channel_register(gbase + REG_AVPLLCTL0,
ret = berlin2_avpll_channel_register(gbase + REG_AVPLLCTL0,
clk_names[AVPLL_A1 + n], n, "avpll_vcoA",
avpll_flags, 0);
if (IS_ERR(clk))
if (ret)
goto bg2_fail;
}
clk = berlin2_avpll_vco_register(gbase + REG_AVPLLCTL31, "avpll_vcoB",
ret = berlin2_avpll_vco_register(gbase + REG_AVPLLCTL31, "avpll_vcoB",
clk_names[REFCLK], BERLIN2_AVPLL_BIT_QUIRK |
avpll_flags, 0);
if (IS_ERR(clk))
if (ret)
goto bg2_fail;
for (n = 0; n < 8; n++) {
clk = berlin2_avpll_channel_register(gbase + REG_AVPLLCTL31,
ret = berlin2_avpll_channel_register(gbase + REG_AVPLLCTL31,
clk_names[AVPLL_B1 + n], n, "avpll_vcoB",
BERLIN2_AVPLL_BIT_QUIRK | avpll_flags, 0);
if (IS_ERR(clk))
if (ret)
goto bg2_fail;
}
/* reference clock bypass switches */
parent_names[0] = clk_names[SYSPLL];
parent_names[1] = clk_names[REFCLK];
clk = clk_register_mux(NULL, "syspll_byp", parent_names, 2,
hw = clk_hw_register_mux(NULL, "syspll_byp", parent_names, 2,
0, gbase + REG_CLKSWITCH0, 0, 1, 0, &lock);
if (IS_ERR(clk))
if (IS_ERR(hw))
goto bg2_fail;
clk_names[SYSPLL] = __clk_get_name(clk);
clk_names[SYSPLL] = clk_hw_get_name(hw);
parent_names[0] = clk_names[MEMPLL];
parent_names[1] = clk_names[REFCLK];
clk = clk_register_mux(NULL, "mempll_byp", parent_names, 2,
hw = clk_hw_register_mux(NULL, "mempll_byp", parent_names, 2,
0, gbase + REG_CLKSWITCH0, 1, 1, 0, &lock);
if (IS_ERR(clk))
if (IS_ERR(hw))
goto bg2_fail;
clk_names[MEMPLL] = __clk_get_name(clk);
clk_names[MEMPLL] = clk_hw_get_name(hw);
parent_names[0] = clk_names[CPUPLL];
parent_names[1] = clk_names[REFCLK];
clk = clk_register_mux(NULL, "cpupll_byp", parent_names, 2,
hw = clk_hw_register_mux(NULL, "cpupll_byp", parent_names, 2,
0, gbase + REG_CLKSWITCH0, 2, 1, 0, &lock);
if (IS_ERR(clk))
if (IS_ERR(hw))
goto bg2_fail;
clk_names[CPUPLL] = __clk_get_name(clk);
clk_names[CPUPLL] = clk_hw_get_name(hw);
/* clock muxes */
parent_names[0] = clk_names[AVPLL_B3];
parent_names[1] = clk_names[AVPLL_A3];
clk = clk_register_mux(NULL, clk_names[AUDIO1_PLL], parent_names, 2,
hw = clk_hw_register_mux(NULL, clk_names[AUDIO1_PLL], parent_names, 2,
0, gbase + REG_CLKSELECT2, 29, 1, 0, &lock);
if (IS_ERR(clk))
if (IS_ERR(hw))
goto bg2_fail;
parent_names[0] = clk_names[VIDEO0_PLL];
parent_names[1] = clk_names[VIDEO_EXT0];
clk = clk_register_mux(NULL, clk_names[VIDEO0_IN], parent_names, 2,
hw = clk_hw_register_mux(NULL, clk_names[VIDEO0_IN], parent_names, 2,
0, gbase + REG_CLKSELECT3, 4, 1, 0, &lock);
if (IS_ERR(clk))
if (IS_ERR(hw))
goto bg2_fail;
parent_names[0] = clk_names[VIDEO1_PLL];
parent_names[1] = clk_names[VIDEO_EXT0];
clk = clk_register_mux(NULL, clk_names[VIDEO1_IN], parent_names, 2,
hw = clk_hw_register_mux(NULL, clk_names[VIDEO1_IN], parent_names, 2,
0, gbase + REG_CLKSELECT3, 6, 1, 0, &lock);
if (IS_ERR(clk))
if (IS_ERR(hw))
goto bg2_fail;
parent_names[0] = clk_names[AVPLL_A2];
parent_names[1] = clk_names[AVPLL_B2];
clk = clk_register_mux(NULL, clk_names[VIDEO1_PLL], parent_names, 2,
hw = clk_hw_register_mux(NULL, clk_names[VIDEO1_PLL], parent_names, 2,
0, gbase + REG_CLKSELECT3, 7, 1, 0, &lock);
if (IS_ERR(clk))
if (IS_ERR(hw))
goto bg2_fail;
parent_names[0] = clk_names[VIDEO2_PLL];
parent_names[1] = clk_names[VIDEO_EXT0];
clk = clk_register_mux(NULL, clk_names[VIDEO2_IN], parent_names, 2,
hw = clk_hw_register_mux(NULL, clk_names[VIDEO2_IN], parent_names, 2,
0, gbase + REG_CLKSELECT3, 9, 1, 0, &lock);
if (IS_ERR(clk))
if (IS_ERR(hw))
goto bg2_fail;
parent_names[0] = clk_names[AVPLL_B1];
parent_names[1] = clk_names[AVPLL_A5];
clk = clk_register_mux(NULL, clk_names[VIDEO2_PLL], parent_names, 2,
hw = clk_hw_register_mux(NULL, clk_names[VIDEO2_PLL], parent_names, 2,
0, gbase + REG_CLKSELECT3, 10, 1, 0, &lock);
if (IS_ERR(clk))
if (IS_ERR(hw))
goto bg2_fail;
/* clock divider cells */
......@@ -648,7 +656,7 @@ static void __init berlin2_clock_setup(struct device_node *np)
for (k = 0; k < dd->num_parents; k++)
parent_names[k] = clk_names[dd->parent_ids[k]];
clks[CLKID_SYS + n] = berlin2_div_register(&dd->map, gbase,
hws[CLKID_SYS + n] = berlin2_div_register(&dd->map, gbase,
dd->name, dd->div_flags, parent_names,
dd->num_parents, dd->flags, &lock);
}
......@@ -657,18 +665,18 @@ static void __init berlin2_clock_setup(struct device_node *np)
for (n = 0; n < ARRAY_SIZE(bg2_gates); n++) {
const struct berlin2_gate_data *gd = &bg2_gates[n];
clks[CLKID_GETH0 + n] = clk_register_gate(NULL, gd->name,
hws[CLKID_GETH0 + n] = clk_hw_register_gate(NULL, gd->name,
gd->parent_name, gd->flags, gbase + REG_CLKENABLE,
gd->bit_idx, 0, &lock);
}
/* twdclk is derived from cpu/3 */
clks[CLKID_TWD] =
clk_register_fixed_factor(NULL, "twd", "cpu", 0, 1, 3);
hws[CLKID_TWD] =
clk_hw_register_fixed_factor(NULL, "twd", "cpu", 0, 1, 3);
/* check for errors on leaf clocks */
for (n = 0; n < MAX_CLKS; n++) {
if (!IS_ERR(clks[n]))
if (!IS_ERR(hws[n]))
continue;
pr_err("%s: Unable to register leaf clock %d\n",
......@@ -677,9 +685,7 @@ static void __init berlin2_clock_setup(struct device_node *np)
}
/* register clk-provider */
clk_data.clks = clks;
clk_data.clk_num = MAX_CLKS;
of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
of_clk_add_hw_provider(np, of_clk_hw_onecell_get, &clk_data);
return;
......
......@@ -46,8 +46,7 @@
#define REG_SDIO1XIN_CLKCTL 0x015c
#define MAX_CLKS 28
static struct clk *clks[MAX_CLKS];
static struct clk_onecell_data clk_data;
static struct clk_hw_onecell_data *clk_data;
static DEFINE_SPINLOCK(lock);
static void __iomem *gbase;
static void __iomem *cpupll_base;
......@@ -293,7 +292,15 @@ static void __init berlin2q_clock_setup(struct device_node *np)
struct device_node *parent_np = of_get_parent(np);
const char *parent_names[9];
struct clk *clk;
int n;
struct clk_hw **hws;
int n, ret;
clk_data = kzalloc(sizeof(*clk_data) +
sizeof(*clk_data->hws) * MAX_CLKS, GFP_KERNEL);
if (!clk_data)
return;
clk_data->num = MAX_CLKS;
hws = clk_data->hws;
gbase = of_iomap(parent_np, 0);
if (!gbase) {
......@@ -317,14 +324,14 @@ static void __init berlin2q_clock_setup(struct device_node *np)
}
/* simple register PLLs */
clk = berlin2_pll_register(&bg2q_pll_map, gbase + REG_SYSPLLCTL0,
ret = berlin2_pll_register(&bg2q_pll_map, gbase + REG_SYSPLLCTL0,
clk_names[SYSPLL], clk_names[REFCLK], 0);
if (IS_ERR(clk))
if (ret)
goto bg2q_fail;
clk = berlin2_pll_register(&bg2q_pll_map, cpupll_base,
ret = berlin2_pll_register(&bg2q_pll_map, cpupll_base,
clk_names[CPUPLL], clk_names[REFCLK], 0);
if (IS_ERR(clk))
if (ret)
goto bg2q_fail;
/* TODO: add BG2Q AVPLL */
......@@ -342,7 +349,7 @@ static void __init berlin2q_clock_setup(struct device_node *np)
for (k = 0; k < dd->num_parents; k++)
parent_names[k] = clk_names[dd->parent_ids[k]];
clks[CLKID_SYS + n] = berlin2_div_register(&dd->map, gbase,
hws[CLKID_SYS + n] = berlin2_div_register(&dd->map, gbase,
dd->name, dd->div_flags, parent_names,
dd->num_parents, dd->flags, &lock);
}
......@@ -351,22 +358,22 @@ static void __init berlin2q_clock_setup(struct device_node *np)
for (n = 0; n < ARRAY_SIZE(bg2q_gates); n++) {
const struct berlin2_gate_data *gd = &bg2q_gates[n];
clks[CLKID_GFX2DAXI + n] = clk_register_gate(NULL, gd->name,
hws[CLKID_GFX2DAXI + n] = clk_hw_register_gate(NULL, gd->name,
gd->parent_name, gd->flags, gbase + REG_CLKENABLE,
gd->bit_idx, 0, &lock);
}
/* cpuclk divider is fixed to 1 */
clks[CLKID_CPU] =
clk_register_fixed_factor(NULL, "cpu", clk_names[CPUPLL],
hws[CLKID_CPU] =
clk_hw_register_fixed_factor(NULL, "cpu", clk_names[CPUPLL],
0, 1, 1);
/* twdclk is derived from cpu/3 */
clks[CLKID_TWD] =
clk_register_fixed_factor(NULL, "twd", "cpu", 0, 1, 3);
hws[CLKID_TWD] =
clk_hw_register_fixed_factor(NULL, "twd", "cpu", 0, 1, 3);
/* check for errors on leaf clocks */
for (n = 0; n < MAX_CLKS; n++) {
if (!IS_ERR(clks[n]))
if (!IS_ERR(hws[n]))
continue;
pr_err("%s: Unable to register leaf clock %d\n",
......@@ -375,9 +382,7 @@ static void __init berlin2q_clock_setup(struct device_node *np)
}
/* register clk-provider */
clk_data.clks = clks;
clk_data.clk_num = MAX_CLKS;
of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
of_clk_add_hw_provider(np, of_clk_hw_onecell_get, &clk_data);
return;
......
......@@ -68,8 +68,7 @@
#define HW_LCDCLKDIV 0x01fc
#define HW_ADCANACLKDIV 0x0200
static struct clk *clks[MAX_CLKS];
static struct clk_onecell_data clk_data;
static struct clk_hw_onecell_data *clk_data;
static DEFINE_SPINLOCK(asm9260_clk_lock);
struct asm9260_div_clk {
......@@ -267,12 +266,20 @@ static struct asm9260_mux_clock asm9260_mux_clks[] __initdata = {
static void __init asm9260_acc_init(struct device_node *np)
{
struct clk *clk;
struct clk_hw *hw;
struct clk_hw **hws;
const char *ref_clk, *pll_clk = "pll";
u32 rate;
int n;
u32 accuracy = 0;
clk_data = kzalloc(sizeof(*clk_data) +
sizeof(*clk_data->hws) * MAX_CLKS, GFP_KERNEL);
if (!clk_data)
return;
clk_data->num = MAX_CLKS;
hws = clk_data->hws;
base = of_io_request_and_map(np, 0, np->name);
if (IS_ERR(base))
panic("%s: unable to map resource", np->name);
......@@ -282,10 +289,10 @@ static void __init asm9260_acc_init(struct device_node *np)
ref_clk = of_clk_get_parent_name(np, 0);
accuracy = clk_get_accuracy(__clk_lookup(ref_clk));
clk = clk_register_fixed_rate_with_accuracy(NULL, pll_clk,
hw = clk_hw_register_fixed_rate_with_accuracy(NULL, pll_clk,
ref_clk, 0, rate, accuracy);
if (IS_ERR(clk))
if (IS_ERR(hw))
panic("%s: can't register REFCLK. Check DT!", np->name);
for (n = 0; n < ARRAY_SIZE(asm9260_mux_clks); n++) {
......@@ -293,7 +300,7 @@ static void __init asm9260_acc_init(struct device_node *np)
mc->parent_names[0] = ref_clk;
mc->parent_names[1] = pll_clk;
clk = clk_register_mux_table(NULL, mc->name, mc->parent_names,
hw = clk_hw_register_mux_table(NULL, mc->name, mc->parent_names,
mc->num_parents, mc->flags, base + mc->offset,
0, mc->mask, 0, mc->table, &asm9260_clk_lock);
}
......@@ -302,7 +309,7 @@ static void __init asm9260_acc_init(struct device_node *np)
for (n = 0; n < ARRAY_SIZE(asm9260_mux_gates); n++) {
const struct asm9260_gate_data *gd = &asm9260_mux_gates[n];
clk = clk_register_gate(NULL, gd->name,
hw = clk_hw_register_gate(NULL, gd->name,
gd->parent_name, gd->flags | CLK_SET_RATE_PARENT,
base + gd->reg, gd->bit_idx, 0, &asm9260_clk_lock);
}
......@@ -311,7 +318,7 @@ static void __init asm9260_acc_init(struct device_node *np)
for (n = 0; n < ARRAY_SIZE(asm9260_div_clks); n++) {
const struct asm9260_div_clk *dc = &asm9260_div_clks[n];
clks[dc->idx] = clk_register_divider(NULL, dc->name,
hws[dc->idx] = clk_hw_register_divider(NULL, dc->name,
dc->parent_name, CLK_SET_RATE_PARENT,
base + dc->reg, 0, 8, CLK_DIVIDER_ONE_BASED,
&asm9260_clk_lock);
......@@ -321,14 +328,14 @@ static void __init asm9260_acc_init(struct device_node *np)
for (n = 0; n < ARRAY_SIZE(asm9260_ahb_gates); n++) {
const struct asm9260_gate_data *gd = &asm9260_ahb_gates[n];
clks[gd->idx] = clk_register_gate(NULL, gd->name,
hws[gd->idx] = clk_hw_register_gate(NULL, gd->name,
gd->parent_name, gd->flags, base + gd->reg,
gd->bit_idx, 0, &asm9260_clk_lock);
}
/* check for errors on leaf clocks */
for (n = 0; n < MAX_CLKS; n++) {
if (!IS_ERR(clks[n]))
if (!IS_ERR(hws[n]))
continue;
pr_err("%s: Unable to register leaf clock %d\n",
......@@ -337,9 +344,7 @@ static void __init asm9260_acc_init(struct device_node *np)
}
/* register clk-provider */
clk_data.clks = clks;
clk_data.clk_num = MAX_CLKS;
of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_data);
return;
fail:
iounmap(base);
......
......@@ -392,8 +392,8 @@ static int axi_clkgen_probe(struct platform_device *pdev)
const char *parent_names[2];
const char *clk_name;
struct resource *mem;
struct clk *clk;
unsigned int i;
int ret;
if (!pdev->dev.of_node)
return -ENODEV;
......@@ -433,12 +433,12 @@ static int axi_clkgen_probe(struct platform_device *pdev)
axi_clkgen_mmcm_enable(axi_clkgen, false);
axi_clkgen->clk_hw.init = &init;
clk = devm_clk_register(&pdev->dev, &axi_clkgen->clk_hw);
if (IS_ERR(clk))
return PTR_ERR(clk);
ret = devm_clk_hw_register(&pdev->dev, &axi_clkgen->clk_hw);
if (ret)
return ret;
return of_clk_add_provider(pdev->dev.of_node, of_clk_src_simple_get,
clk);
return of_clk_add_hw_provider(pdev->dev.of_node, of_clk_hw_simple_get,
&axi_clkgen->clk_hw);
}
static int axi_clkgen_remove(struct platform_device *pdev)
......
......@@ -516,6 +516,19 @@ static struct axxia_clk *axmclk_clocks[] = {
[AXXIA_CLK_MMC] = &clk_mmc_mux.aclk,
};
static struct clk_hw *
of_clk_axmclk_get(struct of_phandle_args *clkspec, void *unused)
{
unsigned int idx = clkspec->args[0];
if (idx >= ARRAY_SIZE(axmclk_clocks)) {
pr_err("%s: invalid index %u\n", __func__, idx);
return ERR_PTR(-EINVAL);
}
return &axmclk_clocks[idx]->hw;
}
static const struct regmap_config axmclk_regmap_config = {
.reg_bits = 32,
.reg_stride = 4,
......@@ -530,21 +543,14 @@ static const struct of_device_id axmclk_match_table[] = {
};
MODULE_DEVICE_TABLE(of, axmclk_match_table);
struct axmclk_priv {
struct clk_onecell_data onecell;
struct clk *clks[];
};
static int axmclk_probe(struct platform_device *pdev)
{
void __iomem *base;
struct resource *res;
int i, ret;
struct device *dev = &pdev->dev;
struct clk *clk;
struct regmap *regmap;
size_t num_clks;
struct axmclk_priv *priv;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
base = devm_ioremap_resource(dev, res);
......@@ -557,29 +563,18 @@ static int axmclk_probe(struct platform_device *pdev)
num_clks = ARRAY_SIZE(axmclk_clocks);
pr_info("axmclk: supporting %zu clocks\n", num_clks);
priv = devm_kzalloc(dev, sizeof(*priv) + sizeof(*priv->clks) * num_clks,
GFP_KERNEL);
if (!priv)
return -ENOMEM;
priv->onecell.clks = priv->clks;
priv->onecell.clk_num = num_clks;
/* Update each entry with the allocated regmap and register the clock
* with the common clock framework
*/
for (i = 0; i < num_clks; i++) {
axmclk_clocks[i]->regmap = regmap;
clk = devm_clk_register(dev, &axmclk_clocks[i]->hw);
if (IS_ERR(clk))
return PTR_ERR(clk);
priv->clks[i] = clk;
ret = devm_clk_hw_register(dev, &axmclk_clocks[i]->hw);
if (ret)
return ret;
}
ret = of_clk_add_provider(dev->of_node,
of_clk_src_onecell_get, &priv->onecell);
return ret;
return of_clk_add_hw_provider(dev->of_node, of_clk_axmclk_get, NULL);
}
static int axmclk_remove(struct platform_device *pdev)
......
......@@ -71,7 +71,6 @@ struct cdce706_hw_data {
struct cdce706_dev_data *dev_data;
unsigned idx;
unsigned parent;
struct clk *clk;
struct clk_hw hw;
unsigned div;
unsigned mul;
......@@ -81,8 +80,6 @@ struct cdce706_hw_data {
struct cdce706_dev_data {
struct i2c_client *client;
struct regmap *regmap;
struct clk_onecell_data onecell;
struct clk *clks[6];
struct clk *clkin_clk[2];
const char *clkin_name[2];
struct cdce706_hw_data clkin[1];
......@@ -455,18 +452,19 @@ static int cdce706_register_hw(struct cdce706_dev_data *cdce,
struct clk_init_data *init)
{
unsigned i;
int ret;
for (i = 0; i < num_hw; ++i, ++hw) {
init->name = clk_names[i];
hw->dev_data = cdce;
hw->idx = i;
hw->hw.init = init;
hw->clk = devm_clk_register(&cdce->client->dev,
ret = devm_clk_hw_register(&cdce->client->dev,
&hw->hw);
if (IS_ERR(hw->clk)) {
if (ret) {
dev_err(&cdce->client->dev, "Failed to register %s\n",
clk_names[i]);
return PTR_ERR(hw->clk);
return ret;
}
}
return 0;
......@@ -613,13 +611,23 @@ static int cdce706_register_clkouts(struct cdce706_dev_data *cdce)
cdce->clkout[i].parent);
}
ret = cdce706_register_hw(cdce, cdce->clkout,
ARRAY_SIZE(cdce->clkout),
cdce706_clkout_name, &init);
for (i = 0; i < ARRAY_SIZE(cdce->clkout); ++i)
cdce->clks[i] = cdce->clkout[i].clk;
return cdce706_register_hw(cdce, cdce->clkout,
ARRAY_SIZE(cdce->clkout),
cdce706_clkout_name, &init);
}
return ret;
static struct clk_hw *
of_clk_cdce_get(struct of_phandle_args *clkspec, void *data)
{
struct cdce706_dev_data *cdce = data;
unsigned int idx = clkspec->args[0];
if (idx >= ARRAY_SIZE(cdce->clkout)) {
pr_err("%s: invalid index %u\n", __func__, idx);
return ERR_PTR(-EINVAL);
}
return &cdce->clkout[idx].hw;
}
static int cdce706_probe(struct i2c_client *client,
......@@ -657,12 +665,8 @@ static int cdce706_probe(struct i2c_client *client,
ret = cdce706_register_clkouts(cdce);
if (ret < 0)
return ret;
cdce->onecell.clks = cdce->clks;
cdce->onecell.clk_num = ARRAY_SIZE(cdce->clks);
ret = of_clk_add_provider(client->dev.of_node, of_clk_src_onecell_get,
&cdce->onecell);
return ret;
return of_clk_add_hw_provider(client->dev.of_node, of_clk_cdce_get,
cdce);
}
static int cdce706_remove(struct i2c_client *client)
......
......@@ -62,8 +62,6 @@ struct clk_cdce925_chip {
struct i2c_client *i2c_client;
struct clk_cdce925_pll pll[NUMBER_OF_PLLS];
struct clk_cdce925_output clk[NUMBER_OF_OUTPUTS];
struct clk *dt_clk[NUMBER_OF_OUTPUTS];
struct clk_onecell_data onecell;
};
/* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */
......@@ -557,6 +555,20 @@ static int cdce925_regmap_i2c_read(void *context,
return -EIO;
}
static struct clk_hw *
of_clk_cdce925_get(struct of_phandle_args *clkspec, void *_data)
{
struct clk_cdce925_chip *data = _data;
unsigned int idx = clkspec->args[0];
if (idx >= ARRAY_SIZE(data->clk)) {
pr_err("%s: invalid index %u\n", __func__, idx);
return ERR_PTR(-EINVAL);
}
return &data->clk[idx].hw;
}
/* The CDCE925 uses a funky way to read/write registers. Bulk mode is
* just weird, so just use the single byte mode exclusively. */
static struct regmap_bus regmap_cdce925_bus = {
......@@ -572,7 +584,6 @@ static int cdce925_probe(struct i2c_client *client,
const char *parent_name;
const char *pll_clk_name[NUMBER_OF_PLLS] = {NULL,};
struct clk_init_data init;
struct clk *clk;
u32 value;
int i;
int err;
......@@ -622,10 +633,9 @@ static int cdce925_probe(struct i2c_client *client,
data->pll[i].chip = data;
data->pll[i].hw.init = &init;
data->pll[i].index = i;
clk = devm_clk_register(&client->dev, &data->pll[i].hw);
if (IS_ERR(clk)) {
err = devm_clk_hw_register(&client->dev, &data->pll[i].hw);
if (err) {
dev_err(&client->dev, "Failed register PLL %d\n", i);
err = PTR_ERR(clk);
goto error;
}
sprintf(child_name, "PLL%d", i+1);
......@@ -634,7 +644,7 @@ static int cdce925_probe(struct i2c_client *client,
continue;
if (!of_property_read_u32(np_output,
"clock-frequency", &value)) {
err = clk_set_rate(clk, value);
err = clk_set_rate(data->pll[i].hw.clk, value);
if (err)
dev_err(&client->dev,
"unable to set PLL frequency %ud\n",
......@@ -663,14 +673,12 @@ static int cdce925_probe(struct i2c_client *client,
data->clk[0].hw.init = &init;
data->clk[0].index = 0;
data->clk[0].pdiv = 1;
clk = devm_clk_register(&client->dev, &data->clk[0].hw);
err = devm_clk_hw_register(&client->dev, &data->clk[0].hw);
kfree(init.name); /* clock framework made a copy of the name */
if (IS_ERR(clk)) {
if (err) {
dev_err(&client->dev, "clock registration Y1 failed\n");
err = PTR_ERR(clk);
goto error;
}
data->dt_clk[0] = clk;
/* Register output clocks Y2 .. Y5*/
init.ops = &cdce925_clk_ops;
......@@ -695,21 +703,17 @@ static int cdce925_probe(struct i2c_client *client,
init.parent_names = &pll_clk_name[1];
break;
}
clk = devm_clk_register(&client->dev, &data->clk[i].hw);
err = devm_clk_hw_register(&client->dev, &data->clk[i].hw);
kfree(init.name); /* clock framework made a copy of the name */
if (IS_ERR(clk)) {
if (err) {
dev_err(&client->dev, "clock registration failed\n");
err = PTR_ERR(clk);
goto error;
}
data->dt_clk[i] = clk;
}
/* Register the output clocks */
data->onecell.clk_num = NUMBER_OF_OUTPUTS;
data->onecell.clks = data->dt_clk;
err = of_clk_add_provider(client->dev.of_node, of_clk_src_onecell_get,
&data->onecell);
err = of_clk_add_hw_provider(client->dev.of_node, of_clk_cdce925_get,
data);
if (err)
dev_err(&client->dev, "unable to add OF clock provider\n");
......
......@@ -40,9 +40,8 @@ static const struct clk_div_table timer_div_table[] = {
};
struct clps711x_clk {
struct clk_onecell_data clk_data;
spinlock_t lock;
struct clk *clks[CLPS711X_CLK_MAX];
spinlock_t lock;
struct clk_hw_onecell_data clk_data;
};
static struct clps711x_clk * __init _clps711x_clk_init(void __iomem *base,
......@@ -55,7 +54,9 @@ static struct clps711x_clk * __init _clps711x_clk_init(void __iomem *base,
if (!base)
return ERR_PTR(-ENOMEM);
clps711x_clk = kzalloc(sizeof(*clps711x_clk), GFP_KERNEL);
clps711x_clk = kzalloc(sizeof(*clps711x_clk) +
sizeof(*clps711x_clk->clk_data.hws) * CLPS711X_CLK_MAX,
GFP_KERNEL);
if (!clps711x_clk)
return ERR_PTR(-ENOMEM);
......@@ -106,40 +107,40 @@ static struct clps711x_clk * __init _clps711x_clk_init(void __iomem *base,
tmp |= SYSCON1_TC2M | SYSCON1_TC2S;
writel(tmp, base + CLPS711X_SYSCON1);
clps711x_clk->clks[CLPS711X_CLK_DUMMY] =
clk_register_fixed_rate(NULL, "dummy", NULL, 0, 0);
clps711x_clk->clks[CLPS711X_CLK_CPU] =
clk_register_fixed_rate(NULL, "cpu", NULL, 0, f_cpu);
clps711x_clk->clks[CLPS711X_CLK_BUS] =
clk_register_fixed_rate(NULL, "bus", NULL, 0, f_bus);
clps711x_clk->clks[CLPS711X_CLK_PLL] =
clk_register_fixed_rate(NULL, "pll", NULL, 0, f_pll);
clps711x_clk->clks[CLPS711X_CLK_TIMERREF] =
clk_register_fixed_rate(NULL, "timer_ref", NULL, 0, f_tim);
clps711x_clk->clks[CLPS711X_CLK_TIMER1] =
clk_register_divider_table(NULL, "timer1", "timer_ref", 0,
clps711x_clk->clk_data.hws[CLPS711X_CLK_DUMMY] =
clk_hw_register_fixed_rate(NULL, "dummy", NULL, 0, 0);
clps711x_clk->clk_data.hws[CLPS711X_CLK_CPU] =
clk_hw_register_fixed_rate(NULL, "cpu", NULL, 0, f_cpu);
clps711x_clk->clk_data.hws[CLPS711X_CLK_BUS] =
clk_hw_register_fixed_rate(NULL, "bus", NULL, 0, f_bus);
clps711x_clk->clk_data.hws[CLPS711X_CLK_PLL] =
clk_hw_register_fixed_rate(NULL, "pll", NULL, 0, f_pll);
clps711x_clk->clk_data.hws[CLPS711X_CLK_TIMERREF] =
clk_hw_register_fixed_rate(NULL, "timer_ref", NULL, 0, f_tim);
clps711x_clk->clk_data.hws[CLPS711X_CLK_TIMER1] =
clk_hw_register_divider_table(NULL, "timer1", "timer_ref", 0,
base + CLPS711X_SYSCON1, 5, 1, 0,
timer_div_table, &clps711x_clk->lock);
clps711x_clk->clks[CLPS711X_CLK_TIMER2] =
clk_register_divider_table(NULL, "timer2", "timer_ref", 0,
clps711x_clk->clk_data.hws[CLPS711X_CLK_TIMER2] =
clk_hw_register_divider_table(NULL, "timer2", "timer_ref", 0,
base + CLPS711X_SYSCON1, 7, 1, 0,
timer_div_table, &clps711x_clk->lock);
clps711x_clk->clks[CLPS711X_CLK_PWM] =
clk_register_fixed_rate(NULL, "pwm", NULL, 0, f_pwm);
clps711x_clk->clks[CLPS711X_CLK_SPIREF] =
clk_register_fixed_rate(NULL, "spi_ref", NULL, 0, f_spi);
clps711x_clk->clks[CLPS711X_CLK_SPI] =
clk_register_divider_table(NULL, "spi", "spi_ref", 0,
clps711x_clk->clk_data.hws[CLPS711X_CLK_PWM] =
clk_hw_register_fixed_rate(NULL, "pwm", NULL, 0, f_pwm);
clps711x_clk->clk_data.hws[CLPS711X_CLK_SPIREF] =
clk_hw_register_fixed_rate(NULL, "spi_ref", NULL, 0, f_spi);
clps711x_clk->clk_data.hws[CLPS711X_CLK_SPI] =
clk_hw_register_divider_table(NULL, "spi", "spi_ref", 0,
base + CLPS711X_SYSCON1, 16, 2, 0,
spi_div_table, &clps711x_clk->lock);
clps711x_clk->clks[CLPS711X_CLK_UART] =
clk_register_fixed_factor(NULL, "uart", "bus", 0, 1, 10);
clps711x_clk->clks[CLPS711X_CLK_TICK] =
clk_register_fixed_rate(NULL, "tick", NULL, 0, 64);
clps711x_clk->clk_data.hws[CLPS711X_CLK_UART] =
clk_hw_register_fixed_factor(NULL, "uart", "bus", 0, 1, 10);
clps711x_clk->clk_data.hws[CLPS711X_CLK_TICK] =
clk_hw_register_fixed_rate(NULL, "tick", NULL, 0, 64);
for (i = 0; i < CLPS711X_CLK_MAX; i++)
if (IS_ERR(clps711x_clk->clks[i]))
if (IS_ERR(clps711x_clk->clk_data.hws[i]))
pr_err("clk %i: register failed with %ld\n",
i, PTR_ERR(clps711x_clk->clks[i]));
i, PTR_ERR(clps711x_clk->clk_data.hws[i]));
return clps711x_clk;
}
......@@ -153,17 +154,17 @@ void __init clps711x_clk_init(void __iomem *base)
BUG_ON(IS_ERR(clps711x_clk));
/* Clocksource */
clk_register_clkdev(clps711x_clk->clks[CLPS711X_CLK_TIMER1],
clk_hw_register_clkdev(clps711x_clk->clk_data.hws[CLPS711X_CLK_TIMER1],
NULL, "clps711x-timer.0");
clk_register_clkdev(clps711x_clk->clks[CLPS711X_CLK_TIMER2],
clk_hw_register_clkdev(clps711x_clk->clk_data.hws[CLPS711X_CLK_TIMER2],
NULL, "clps711x-timer.1");
/* Drivers */
clk_register_clkdev(clps711x_clk->clks[CLPS711X_CLK_PWM],
clk_hw_register_clkdev(clps711x_clk->clk_data.hws[CLPS711X_CLK_PWM],
NULL, "clps711x-pwm");
clk_register_clkdev(clps711x_clk->clks[CLPS711X_CLK_UART],
clk_hw_register_clkdev(clps711x_clk->clk_data.hws[CLPS711X_CLK_UART],
NULL, "clps711x-uart.0");
clk_register_clkdev(clps711x_clk->clks[CLPS711X_CLK_UART],
clk_hw_register_clkdev(clps711x_clk->clk_data.hws[CLPS711X_CLK_UART],
NULL, "clps711x-uart.1");
}
......@@ -179,10 +180,9 @@ static void __init clps711x_clk_init_dt(struct device_node *np)
clps711x_clk = _clps711x_clk_init(base, fref);
BUG_ON(IS_ERR(clps711x_clk));
clps711x_clk->clk_data.clks = clps711x_clk->clks;
clps711x_clk->clk_data.clk_num = CLPS711X_CLK_MAX;
of_clk_add_provider(np, of_clk_src_onecell_get,
&clps711x_clk->clk_data);
clps711x_clk->clk_data.num = CLPS711X_CLK_MAX;
of_clk_add_hw_provider(np, of_clk_hw_onecell_get,
&clps711x_clk->clk_data);
}
CLK_OF_DECLARE(clps711x, "cirrus,ep7209-clk", clps711x_clk_init_dt);
#endif
......@@ -59,7 +59,6 @@ struct cs2000_priv {
struct i2c_client *client;
struct clk *clk_in;
struct clk *ref_clk;
struct clk *clk_out;
};
static const struct of_device_id cs2000_of_match[] = {
......@@ -371,7 +370,6 @@ static int cs2000_clk_register(struct cs2000_priv *priv)
struct device_node *np = dev->of_node;
struct clk_init_data init;
const char *name = np->name;
struct clk *clk;
static const char *parent_names[CLK_MAX];
int ch = 0; /* it uses ch0 only at this point */
int rate;
......@@ -400,18 +398,16 @@ static int cs2000_clk_register(struct cs2000_priv *priv)
priv->hw.init = &init;
clk = clk_register(dev, &priv->hw);
if (IS_ERR(clk))
return PTR_ERR(clk);
ret = clk_hw_register(dev, &priv->hw);
if (ret)
return ret;
ret = of_clk_add_provider(np, of_clk_src_simple_get, clk);
ret = of_clk_add_hw_provider(np, of_clk_hw_simple_get, &priv->hw);
if (ret < 0) {
clk_unregister(clk);
clk_hw_unregister(&priv->hw);
return ret;
}
priv->clk_out = clk;
return 0;
}
......@@ -454,7 +450,7 @@ static int cs2000_remove(struct i2c_client *client)
of_clk_del_provider(np);
clk_unregister(priv->clk_out);
clk_hw_unregister(&priv->hw);
return 0;
}
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment