Here's the clk changes for the merge window which is dominated in the diffstat

by Qualcomm churning out new SoCs that need clk drivers. Looking beyond the
 sheer amount of lines of mostly data there we have a clk nexus DT binding
 change in the core clk framework and a driver core patch to add a subsys driver
 macro. The clock nexus support is useful for devices that map clks internally
 or for connectors on a board that route clock signals to another board. I
 suspect the use of this will expand in the future, so we have unit tests to
 make sure it doesn't break. The driver core change adds subsys_driver() and
 subsys_platform_driver() so we can register early drivers without open-coding
 that all (module_platform_driver() is at device initcall level so it isn't be
 used).
 
 Beyond the core framework bits we have lots of changes all over the tree to
 initialize 'struct clk_init_data'. The potential risk here is that someone
 forgets to initialize all the members of that structure and either the clk
 flags cause weird behavior later on or the parents are pointing at junk and the
 clk is orphaned forever. The patches just initialize the thing with zeroes to
 be safe. Longer term we should probably move this struct out of 'struct clk_hw'
 and pass it during clk registration time. That's a much bigger change and would
 require restructuring entire drivers that rely on the pointer being there.
 
 Finally, we have the usual fixes like calculation updates for dividers,
 handling error paths during clk registration, or fixing clk data now that
 drivers are using them. Those patches are dwarfed by the amount of new SoC
 support and only affect those SoCs and the consumers of those clks. Overall I'm
 more concerned the clk_init_data patches are going to expose some latent bugs
 that we didn't notice before because something was relying on clks being
 orphaned and now they're not.
 
 Core:
  - subsys_driver() / subsys_platform_driver() macros
  - Clock nexus DT binding support (with KUnit tests)
  - Spread-spectrum configuration validation
  - Fully initialize struct clk_init_data across many drivers
 
 New Drivers:
  - Anlogic DR1V90 CRU
  - ZTE zx297520v3 top, matrix, and LSP clocks
  - Samsung Exynos5515 and ACPM driver extended to Exynos850.
  - Qualcomm Eliza camera, camera-BIST, GPU, and video clks
  - Qualcomm Hawi / Maili camera and GPU controllers
  - Qualcomm Kuno global, RPMh
  - Qualcomm MSM8952 global, RPM
  - Qualcomm Nord camera/video clocks, EMAC interconnect, PHY resets
  - Qualcomm IPQ5210 / IPQ9650 network clocks
  - i.MX93 350 MHz fractional-N GP-PLL for display
  - i.MX pll14xx spread-spectrum clock generation
  - Amlogic A9 SCMI clock controller
  - Allwinner single-divider "update bit" support
  - EN7523 Serdes port selection
 -----BEGIN PGP SIGNATURE-----
 
 iQJIBAABCAAyFiEE9L57QeeUxqYDyoaDrQKIl8bklSUFAmri0R4UHHN3Ym95ZEBj
 aHJvbWl1bS5vcmcACgkQrQKIl8bklSWcAA//YrAnklSwDggOqJ3FwYZ8DHwXfcjU
 LQO4guUzlfNl3Lq4js1av5XetKtHk7ndtDxhbP6kLgFIZ+b2LbkPDEUOlxiPZ/47
 MjrveKqgXgEVk6yAl1S8HpmL0BMSO+GZsr61Mcha3kjEUfgen4cZDGzETgyaxniW
 cqIrP6IRa/Z60c6IydRyK+kN/317TGp/VKPcXudtecey5FB+WlpaUQV9ntiOGBZZ
 6icxy2O76v31XU/HJnb+IjTZ0Jc449rBDE+/T12OvoZ1z1Lv59mRgxJgZ0BwdMOP
 PoqTXLq6hby1IH37pCjSEp2X9qVhMsT9I40HM/Nn5uPZIvlDk6mZ4GXh0/sWZqC/
 yYaf9gVouORSKV3DTMSD/njtsNKANoo/aj08Gxfr+hJHrA/7ohehntpeKobWlk9K
 X+0uzT0N1h6PgqlmDHDv0MvYYzUnNif1PRuN+0JFrpvf5Y1cc6jCKdapYVvQtr6i
 NzOs7XG1IbigWPlccUTl3hn0Bs15dLhOVUrWo1c9aPF4vkGpPtyHib8nLdCerbuP
 7mICMzZ3PM76l9rl7VvO8wLNvBHBa+8f90jXE9Zz/0oyAj0fIdrNsXL6Nu+5usDA
 zT8T5Z2PfGgkx6TsftRmk0SZErROG0YakGRstSSSTYytHig0+JezVAH7NY26z7Dz
 Vcft0XmRGbL1jbU=
 =Vb8R
 -----END PGP SIGNATURE-----

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

Pull clk updates from Stephen Boyd:
 "Here's the clk changes for the merge window which is dominated in the
  diffstat by Qualcomm churning out new SoCs that need clk drivers.

  Looking beyond the sheer amount of lines of mostly data there we have
  a clk nexus DT binding change in the core clk framework and a driver
  core patch to add a subsys driver macro.

  The clock nexus support is useful for devices that map clks internally
  or for connectors on a board that route clock signals to another
  board. I suspect the use of this will expand in the future, so we have
  unit tests to make sure it doesn't break.

  The driver core change adds subsys_driver() and
  subsys_platform_driver() so we can register early drivers without
  open-coding that all (module_platform_driver() is at device initcall
  level so it isn't be used).

  Beyond the core framework bits we have lots of changes all over the
  tree to initialize 'struct clk_init_data'. The potential risk here is
  that someone forgets to initialize all the members of that structure
  and either the clk flags cause weird behavior later on or the parents
  are pointing at junk and the clk is orphaned forever. The patches just
  initialize the thing with zeroes to be safe. Longer term we should
  probably move this struct out of 'struct clk_hw' and pass it during
  clk registration time. That's a much bigger change and would require
  restructuring entire drivers that rely on the pointer being there.

  Finally, we have the usual fixes like calculation updates for
  dividers, handling error paths during clk registration, or fixing clk
  data now that drivers are using them. Those patches are dwarfed by the
  amount of new SoC support and only affect those SoCs and the consumers
  of those clks. Overall I'm more concerned the clk_init_data patches
  are going to expose some latent bugs that we didn't notice before
  because something was relying on clks being orphaned and now they're
  not.

  Core:
   - subsys_driver() / subsys_platform_driver() macros
   - Clock nexus DT binding support (with KUnit tests)
   - Spread-spectrum configuration validation
   - Fully initialize struct clk_init_data across many drivers

  New Drivers:
   - Anlogic DR1V90 CRU
   - ZTE zx297520v3 top, matrix, and LSP clocks
   - Samsung Exynos5515 and ACPM driver extended to Exynos850.
   - Qualcomm Eliza camera, camera-BIST, GPU, and video clks
   - Qualcomm Hawi / Maili camera and GPU controllers
   - Qualcomm Kuno global, RPMh
   - Qualcomm MSM8952 global, RPM
   - Qualcomm Nord camera/video clocks, EMAC interconnect, PHY resets
   - Qualcomm IPQ5210 / IPQ9650 network clocks
   - i.MX93 350 MHz fractional-N GP-PLL for display
   - i.MX pll14xx spread-spectrum clock generation
   - Amlogic A9 SCMI clock controller
   - Allwinner single-divider "update bit" support
   - EN7523 Serdes port selection"

* tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux: (316 commits)
  clk: imx: pll14xx: support spread spectrum clock generation
  clk: cdce925: Size the PLL child name buffer for any int
  clk: stm32: fix clock array size for STM32MP21
  dt-bindings: clock: Convert HiSilicon clocks to DT schema
  clk: lmk04832: Handle reset GPIO lookup errors
  dt-bindings: clock: anlogic,dr1v90-cru: make external clocks optional
  clk: tegra: bpmp: remove kcalloc
  clk: mmp2-audio: add missing PM_CLK dependency
  clk: zte: Introduce a driver for zx297520v3 LSP clocks
  clk: zte: Introduce a driver for zx297520v3 matrix clocks
  clk: zte: Introduce a driver for zx297520v3 top clocks
  clk: zte: Add zx PLL support infrastructure
  clk: zte: Add regmap-based clocks
  clk: zte: Add Clock registration infrastructure
  dt-bindings: clk: zte: Add zx297520v3 LSP clock and reset controller
  dt-bindings: clk: zte: Add zx297520v3 matrix clock and reset controller
  dt-bindings: clk: zte: Add zx297520v3 top clock and reset controller
  clk: nuvoton: ma35d1: Add missing WDT/WWDT parent clocks
  dt-bindings: clock: ma35d1: Add missing WDT/WWDT parent clocks
  dt-bindings: clock: ma35d1: Drop CLK_MAX_IDX define
  ...
This commit is contained in:
Linus Torvalds 2026-10-30 06:18:43 -10:00
commit 4517b5a6c8
411 changed files with 27861 additions and 2647 deletions

View File

@ -23,6 +23,7 @@ description: |
All these identifiers can be found in:
[1]: <include/dt-bindings/clock/en7523-clk.h>.
[2]: <include/dt-bindings/soc/airoha,scu-ssr.h>.
The clocks are provided inside a system controller node.
@ -50,6 +51,12 @@ properties:
description: ID of the controller reset line
const: 1
'#phy-cells':
description:
The first cell indicates the serdes phy number, see [2] for the
available serdes port.
const: 1
required:
- compatible
- reg
@ -65,12 +72,23 @@ allOf:
reg:
minItems: 2
'#phy-cells': false
- if:
properties:
compatible:
enum:
- airoha,en7581-scu
- econet,en751221-scu
const: econet,en751221-scu
then:
properties:
reg:
maxItems: 1
'#phy-cells': false
- if:
properties:
compatible:
const: airoha,en7581-scu
then:
properties:
reg:

View File

@ -0,0 +1,62 @@
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/anlogic,dr1v90-cru.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Anlogic DR1V90 Clock and Reset Unit (CRU)
maintainers:
- Junhui Liu <junhui.liu@pigmoral.tech>
properties:
compatible:
const: anlogic,dr1v90-cru
reg:
maxItems: 1
clocks:
minItems: 1
maxItems: 3
description:
The main oscillator is always required. Either or both of the external CAN
and WDT clocks may also be provided if the board routes them to the SoC.
clock-names:
minItems: 1
items:
- const: osc
- enum: [can_ext, wdt_ext]
- const: wdt_ext
"#clock-cells":
const: 1
description:
Refer <dt-bindings/clock/anlogic,dr1v90-cru.h> for valid indices.
"#reset-cells":
const: 1
description:
Refer <dt-bindings/reset/anlogic,dr1v90-cru.h> for valid indices.
required:
- compatible
- reg
- clocks
- clock-names
- "#clock-cells"
- "#reset-cells"
additionalProperties: false
examples:
- |
clock-controller@f8801000 {
compatible = "anlogic,dr1v90-cru";
reg = <0xf8801000 0x400>;
clocks = <&osc>, <&can_ext>, <&wdt_ext>;
clock-names = "osc", "can_ext", "wdt_ext";
#clock-cells = <1>;
#reset-cells = <1>;
};

View File

@ -1,35 +0,0 @@
* Palmas 32KHz clocks *
Palmas device has two clock output pins for 32KHz, KG and KG_AUDIO.
This binding uses the common clock binding ./clock-bindings.txt.
Required properties:
- compatible : "ti,palmas-clk32kg" for clk32kg clock
"ti,palmas-clk32kgaudio" for clk32kgaudio clock
- #clock-cells : shall be set to 0.
Optional property:
- ti,external-sleep-control: The external enable input pins controlled the
enable/disable of clocks. The external enable input pins ENABLE1,
ENABLE2 and NSLEEP. The valid values for the external pins are:
PALMAS_EXT_CONTROL_PIN_ENABLE1 for ENABLE1 pin
PALMAS_EXT_CONTROL_PIN_ENABLE2 for ENABLE2 pin
PALMAS_EXT_CONTROL_PIN_NSLEEP for NSLEEP pin
Option 0 or missing this property means the clock is enabled/disabled
via register access and these pins do not have any control.
The macros of external control pins for DTS is defined at
dt-bindings/mfd/palmas.h
Example:
#include <dt-bindings/mfd/palmas.h>
...
palmas: tps65913@58 {
...
clk32kg: palmas_clk32k@0 {
compatible = "ti,palmas-clk32kg";
#clock-cells = <0>;
ti,external-sleep-control = <PALMAS_EXT_CONTROL_PIN_NSLEEP>;
};
...
};

View File

@ -0,0 +1,30 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/clock-nexus-node.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Clock Nexus
description: >
A nexus node allows to remap a clock specifier list in a consumer node
through a container or a connector node in a generic way. With this
remapping, the consumer node needs to know only about the nexus
node. Resources behind the nexus node are decoupled by the nexus node
itself.
maintainers:
- Miquel Raynal <miquel.raynal@bootlin.com>
select: true
properties:
clock-map:
$ref: /schemas/types.yaml#/definitions/uint32-matrix
dependentRequired:
clock-map: ['#clock-cells']
additionalProperties: true
# See the original pwm-nexus-node.yaml description for examples

View File

@ -1,47 +0,0 @@
* Hisilicon Hi3660 Clock Controller
The Hi3660 clock controller generates and supplies clock to various
controllers within the Hi3660 SoC.
Required Properties:
- compatible: the compatible should be one of the following strings to
indicate the clock controller functionality.
- "hisilicon,hi3660-crgctrl"
- "hisilicon,hi3660-pctrl"
- "hisilicon,hi3660-pmuctrl"
- "hisilicon,hi3660-sctrl"
- "hisilicon,hi3660-iomcu"
- "hisilicon,hi3660-stub-clk"
- reg: physical base address of the controller and length of memory mapped
region.
- #clock-cells: should be 1.
Optional Properties:
- mboxes: Phandle to the mailbox for sending message to MCU.
(See: ../mailbox/hisilicon,hi3660-mailbox.txt for more info)
Each clock is assigned an identifier and client nodes use this identifier
to specify the clock which they consume.
All these identifier could be found in <dt-bindings/clock/hi3660-clock.h>.
Examples:
crg_ctrl: clock-controller@fff35000 {
compatible = "hisilicon,hi3660-crgctrl", "syscon";
reg = <0x0 0xfff35000 0x0 0x1000>;
#clock-cells = <1>;
};
uart0: serial@fdf02000 {
compatible = "arm,pl011", "arm,primecell";
reg = <0x0 0xfdf02000 0x0 0x1000>;
interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&crg_ctrl HI3660_CLK_MUX_UART0>,
<&crg_ctrl HI3660_PCLK>;
clock-names = "uartclk", "apb_pclk";
};

View File

@ -1,43 +0,0 @@
* Hisilicon Hi3670 Clock Controller
The Hi3670 clock controller generates and supplies clock to various
controllers within the Hi3670 SoC.
Required Properties:
- compatible: the compatible should be one of the following strings to
indicate the clock controller functionality.
- "hisilicon,hi3670-crgctrl"
- "hisilicon,hi3670-pctrl"
- "hisilicon,hi3670-pmuctrl"
- "hisilicon,hi3670-sctrl"
- "hisilicon,hi3670-iomcu"
- "hisilicon,hi3670-media1-crg"
- "hisilicon,hi3670-media2-crg"
- reg: physical base address of the controller and length of memory mapped
region.
- #clock-cells: should be 1.
Each clock is assigned an identifier and client nodes use this identifier
to specify the clock which they consume.
All these identifier could be found in <dt-bindings/clock/hi3670-clock.h>.
Examples:
crg_ctrl: clock-controller@fff35000 {
compatible = "hisilicon,hi3670-crgctrl", "syscon";
reg = <0x0 0xfff35000 0x0 0x1000>;
#clock-cells = <1>;
};
uart0: serial@fdf02000 {
compatible = "arm,pl011", "arm,primecell";
reg = <0x0 0xfdf02000 0x0 0x1000>;
interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&crg_ctrl HI3670_CLK_GATE_UART0>,
<&crg_ctrl HI3670_PCLK>;
clock-names = "uartclk", "apb_pclk";
};

View File

@ -1,52 +0,0 @@
* Hisilicon Hi6220 Clock Controller
Clock control registers reside in different Hi6220 system controllers,
please refer the following document to know more about the binding rules
for these system controllers:
Documentation/devicetree/bindings/arm/hisilicon/hisilicon.yaml
Required Properties:
- compatible: the compatible should be one of the following strings to
indicate the clock controller functionality.
- "hisilicon,hi6220-acpu-sctrl"
- "hisilicon,hi6220-aoctrl"
- "hisilicon,hi6220-sysctrl"
- "hisilicon,hi6220-mediactrl"
- "hisilicon,hi6220-pmctrl"
- "hisilicon,hi6220-stub-clk"
- reg: physical base address of the controller and length of memory mapped
region.
- #clock-cells: should be 1.
Optional Properties:
- hisilicon,hi6220-clk-sram: phandle to the syscon managing the SoC internal sram;
the driver need use the sram to pass parameters for frequency change.
- mboxes: use the label reference for the mailbox as the first parameter, the
second parameter is the channel number.
Example 1:
sys_ctrl: sys_ctrl@f7030000 {
compatible = "hisilicon,hi6220-sysctrl", "syscon";
reg = <0x0 0xf7030000 0x0 0x2000>;
#clock-cells = <1>;
};
Example 2:
stub_clock: stub_clock {
compatible = "hisilicon,hi6220-stub-clk";
hisilicon,hi6220-clk-sram = <&sram>;
#clock-cells = <1>;
mboxes = <&mailbox 1>;
};
Each clock is assigned an identifier and client nodes use this identifier
to specify the clock which they consume.
All these identifier could be found in <dt-bindings/clock/hi6220-clock.h>.

View File

@ -0,0 +1,51 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/hisilicon,clocks.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Hisilicon Hi6220/Hi3660/Hi3670 Clock Controllers
maintainers:
- Wei Xu <xuwei5@hisilicon.com>
description: >
The Hi3670 clock controller generates and supplies clock to various
controllers within the Hi3670 SoC.
All these identifiers can be found in:
dt-bindings/clock/hi3660-clock.h.
dt-bindings/clock/hi3670-clock.h.
dt-bindings/clock/hi6220-clock.h.
properties:
compatible:
items:
- enum:
- hisilicon,hi3660-crgctrl
- hisilicon,hi3660-pctrl
- hisilicon,hi3660-pmuctrl
- hisilicon,hi3660-sctrl
- hisilicon,hi3660-iomcu
- hisilicon,hi3670-crgctrl
- hisilicon,hi3670-pctrl
- hisilicon,hi3670-pmuctrl
- hisilicon,hi3670-sctrl
- hisilicon,hi3670-iomcu
- hisilicon,hi3670-media1-crg
- hisilicon,hi3670-media2-crg
- hisilicon,hi6220-acpu-sctrl
- const: syscon
reg:
maxItems: 1
'#clock-cells':
const: 1
required:
- compatible
- reg
- '#clock-cells'
additionalProperties: false

View File

@ -0,0 +1,49 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/hisilicon,hi6220-stub-clk.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Hisilicon Stub Clock Controller
maintainers:
- Wei Xu <xuwei5@hisilicon.com>
description: >
Each clock is assigned an identifier and client nodes use this identifier
to specify the clock which they consume.
All these identifiers can be found in:
dt-bindings/clock/hi3660-clock.h.
dt-bindings/clock/hi6220-clock.h.
properties:
compatible:
enum:
- hisilicon,hi3660-stub-clk
- hisilicon,hi6220-stub-clk
reg:
maxItems: 1
'#clock-cells':
const: 1
hisilicon,hi6220-clk-sram:
description:
syscon managing the SoC internal SRAM; driver needs the SRAM to pass
parameters for frequency change.
$ref: /schemas/types.yaml#/definitions/phandle
mboxes:
maxItems: 1
mbox-names:
const: mbox-tx
required:
- compatible
- '#clock-cells'
- mboxes
additionalProperties: false

View File

@ -29,7 +29,18 @@ properties:
const: 1
clocks:
maxItems: 1
minItems: 1
maxItems: 2
description:
The controller takes 2 crystal oscillator inputs from the board.
HXT is a 24 MHz crystal feeding the internal PLLs. LXT is a 32.768
kHz crystal, for RTC and low power operations.
clock-names:
minItems: 1
items:
- const: hxt
- const: lxt
nuvoton,pll-mode:
description:
@ -58,6 +69,7 @@ examples:
compatible = "nuvoton,ma35d1-clk";
reg = <0x40460200 0x100>;
#clock-cells = <1>;
clocks = <&clk_hxt>;
clocks = <&clk_hxt>, <&clk_lxt>;
clock-names = "hxt", "lxt";
};
...

View File

@ -0,0 +1,65 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/qcom,gcc-msm8952.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm Global Clock & Reset Controller on MSM8952
maintainers:
- Muzaffer Kadir <muzafferkadir@mainlining.org>
description: |
Qualcomm global clock control module provides the clocks, resets and power
domains on MSM8952.
See also:
include/dt-bindings/clock/qcom,gcc-msm8952.h
properties:
compatible:
enum:
- qcom,gcc-msm8952
clocks:
items:
- description: XO source
- description: Always-on XO source
- description: DSI phy instance 0 dsi clock
- description: DSI phy instance 0 byte clock
power-domains:
items:
- description: CX power domain
required:
- compatible
- clocks
- power-domains
- '#power-domain-cells'
allOf:
- $ref: qcom,gcc.yaml#
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/clock/qcom,dsi-phy-28nm.h>
#include <dt-bindings/clock/qcom,gcc-msm8952.h>
#include <dt-bindings/clock/qcom,rpmcc.h>
#include <dt-bindings/power/qcom-rpmpd.h>
clock-controller@1800000 {
compatible = "qcom,gcc-msm8952";
reg = <0x01800000 0x80000>;
clocks = <&rpmcc RPM_SMD_XO_CLK_SRC>,
<&rpmcc RPM_SMD_XO_A_CLK_SRC>,
<&mdss_dsi0_phy DSI_PIXEL_PLL_CLK>,
<&mdss_dsi0_phy DSI_BYTE_PLL_CLK>;
power-domains = <&rpmpd RPMPD_VDDCX>;
#clock-cells = <1>;
#reset-cells = <1>;
#power-domain-cells = <1>;
};
...

View File

@ -31,11 +31,13 @@ properties:
maxItems: 5
power-domains:
maxItems: 1
items:
- description: CX power domain
required:
- compatible
- '#power-domain-cells'
- power-domains
allOf:
- $ref: qcom,gcc.yaml#
@ -85,6 +87,7 @@ examples:
# Example for GCC for SDM845:
- |
#include <dt-bindings/clock/qcom,rpmh.h>
#include <dt-bindings/power/qcom,rpmhpd.h>
clock-controller@100000 {
compatible = "qcom,gcc-sdm845";
reg = <0x100000 0x1f0000>;
@ -94,6 +97,7 @@ examples:
<&pcie0_lane>,
<&pcie1_lane>;
clock-names = "bi_tcxo", "bi_tcxo_ao", "sleep_clk", "pcie_0_pipe_clk", "pcie_1_pipe_clk";
power-domains = <&rpmhpd SDM845_CX>;
#clock-cells = <1>;
#reset-cells = <1>;
#power-domain-cells = <1>;

View File

@ -31,10 +31,15 @@ properties:
- const: bi_tcxo_ao
- const: sleep_clk
power-domains:
items:
- description: CX power domain
required:
- compatible
- clocks
- clock-names
- power-domains
- '#power-domain-cells'
allOf:
@ -45,12 +50,14 @@ unevaluatedProperties: false
examples:
- |
#include <dt-bindings/clock/qcom,rpmh.h>
#include <dt-bindings/power/qcom,rpmhpd.h>
clock-controller@100000 {
compatible = "qcom,gcc-sm6350";
reg = <0x00100000 0x1f0000>;
clocks = <&rpmhcc RPMH_CXO_CLK>,
<&rpmhcc RPMH_CXO_CLK_A>,
<&sleep_clk>;
power-domains = <&rpmhpd RPMHPD_CX>;
clock-names = "bi_tcxo", "bi_tcxo_ao", "sleep_clk";
#clock-cells = <1>;
#reset-cells = <1>;

View File

@ -30,10 +30,15 @@ properties:
- const: bi_tcxo
- const: sleep_clk
power-domains:
items:
- description: CX power domain
required:
- compatible
- clocks
- clock-names
- power-domains
- '#power-domain-cells'
allOf:
@ -44,12 +49,14 @@ unevaluatedProperties: false
examples:
- |
#include <dt-bindings/clock/qcom,rpmh.h>
#include <dt-bindings/power/qcom,rpmhpd.h>
clock-controller@100000 {
compatible = "qcom,gcc-sm8150";
reg = <0x00100000 0x1f0000>;
clocks = <&rpmhcc RPMH_CXO_CLK>,
<&sleep_clk>;
clock-names = "bi_tcxo", "sleep_clk";
power-domains = <&rpmhpd SM8150_CX>;
#clock-cells = <1>;
#reset-cells = <1>;
#power-domain-cells = <1>;

View File

@ -32,10 +32,15 @@ properties:
- const: bi_tcxo_ao
- const: sleep_clk
power-domains:
items:
- description: CX power domain
required:
- compatible
- clocks
- clock-names
- power-domains
- '#power-domain-cells'
allOf:
@ -46,6 +51,7 @@ unevaluatedProperties: false
examples:
- |
#include <dt-bindings/clock/qcom,rpmh.h>
#include <dt-bindings/power/qcom,rpmhpd.h>
clock-controller@100000 {
compatible = "qcom,gcc-sm8250";
reg = <0x00100000 0x1f0000>;
@ -53,6 +59,7 @@ examples:
<&rpmhcc RPMH_CXO_CLK_A>,
<&sleep_clk>;
clock-names = "bi_tcxo", "bi_tcxo_ao", "sleep_clk";
power-domains = <&rpmhpd RPMHPD_CX>;
#clock-cells = <1>;
#reset-cells = <1>;
#power-domain-cells = <1>;

View File

@ -51,10 +51,15 @@ properties:
- const: usb3_uni_phy_sec_gcc_usb30_pipe_clk # Optional clock
minItems: 2
power-domains:
items:
- description: CX power domain
required:
- compatible
- clocks
- clock-names
- power-domains
- '#power-domain-cells'
allOf:
@ -65,12 +70,14 @@ unevaluatedProperties: false
examples:
- |
#include <dt-bindings/clock/qcom,rpmh.h>
#include <dt-bindings/power/qcom,rpmhpd.h>
clock-controller@100000 {
compatible = "qcom,gcc-sm8350";
reg = <0x00100000 0x1f0000>;
clocks = <&rpmhcc RPMH_CXO_CLK>,
<&sleep_clk>;
clock-names = "bi_tcxo", "sleep_clk";
power-domains = <&rpmhpd RPMHPD_CX>;
#clock-cells = <1>;
#reset-cells = <1>;
#power-domain-cells = <1>;

View File

@ -47,10 +47,15 @@ properties:
- const: usb3_phy_wrapper_gcc_usb30_pipe_clk # Optional clock
minItems: 2
power-domains:
items:
- description: CX power domain
required:
- compatible
- clocks
- clock-names
- power-domains
- '#power-domain-cells'
allOf:
@ -61,11 +66,13 @@ unevaluatedProperties: false
examples:
- |
#include <dt-bindings/clock/qcom,rpmh.h>
#include <dt-bindings/power/qcom,rpmhpd.h>
clock-controller@100000 {
compatible = "qcom,gcc-sm8450";
reg = <0x00100000 0x001f4200>;
clocks = <&rpmhcc RPMH_CXO_CLK>, <&sleep_clk>;
clock-names = "bi_tcxo", "sleep_clk";
power-domains = <&rpmhpd RPMHPD_CX>;
#clock-cells = <1>;
#reset-cells = <1>;
#power-domain-cells = <1>;

View File

@ -25,6 +25,7 @@ properties:
compatible:
enum:
- qcom,ipq5018-cmn-pll
- qcom,ipq5210-cmn-pll
- qcom,ipq5332-cmn-pll
- qcom,ipq5424-cmn-pll
- qcom,ipq6018-cmn-pll

View File

@ -0,0 +1,52 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/qcom,kuno-gcc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm Global Clock & Reset Controller on Kuno
maintainers:
- Hardeep Sharma <hardeep.sharma@oss.qualcomm.com>
description: |
Qualcomm global clock control module provides the clocks and resets on Kuno.
See also: include/dt-bindings/clock/qcom,kuno-gcc.h
properties:
compatible:
const: qcom,kuno-gcc
clocks:
items:
- description: Board XO source
- description: Board active-only XO source
- description: Sleep clock source
- description: PCIe pipe clock source
required:
- compatible
- clocks
- '#power-domain-cells'
allOf:
- $ref: qcom,gcc.yaml#
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/clock/qcom,rpmh.h>
clock-controller@80000 {
compatible = "qcom,kuno-gcc";
reg = <0x00080000 0x1f4200>;
clocks = <&rpmhcc RPMH_CXO_CLK>,
<&rpmhcc RPMH_CXO_CLK_A>,
<&sleep_clk>,
<&pcie_pipe_clk>;
#clock-cells = <1>;
#reset-cells = <1>;
#power-domain-cells = <1>;
};
...

View File

@ -31,10 +31,15 @@ properties:
- const: bi_tcxo_ao
- const: sleep_clk
power-domains:
items:
- description: CX power domain
required:
- compatible
- clocks
- clock-names
- power-domains
- '#power-domain-cells'
allOf:
@ -45,6 +50,7 @@ unevaluatedProperties: false
examples:
- |
#include <dt-bindings/clock/qcom,rpmh.h>
#include <dt-bindings/power/qcom,rpmhpd.h>
clock-controller@100000 {
compatible = "qcom,qcs615-gcc";
reg = <0x00100000 0x1f0000>;
@ -52,6 +58,7 @@ examples:
<&rpmhcc RPMH_CXO_CLK_A>,
<&sleep_clk>;
clock-names = "bi_tcxo", "bi_tcxo_ao", "sleep_clk";
power-domains = <&rpmhpd RPMHPD_CX>;
#clock-cells = <1>;
#reset-cells = <1>;
#power-domain-cells = <1>;

View File

@ -33,9 +33,14 @@ properties:
- description: UFS Phy Tx symbol 0 clock source
- description: USB3 Phy wrapper pipe clock source
power-domains:
items:
- description: CX power domain
required:
- compatible
- clocks
- power-domains
- '#power-domain-cells'
allOf:
@ -46,6 +51,7 @@ unevaluatedProperties: false
examples:
- |
#include <dt-bindings/clock/qcom,rpmh.h>
#include <dt-bindings/power/qcom,rpmhpd.h>
clock-controller@100000 {
compatible = "qcom,qcs8300-gcc";
reg = <0x00100000 0xc7018>;
@ -59,6 +65,7 @@ examples:
<&ufs_phy_rx_symbol_1_clk>,
<&ufs_phy_tx_symbol_0_clk>,
<&usb3_phy_wrapper_gcc_usb30_prim_pipe_clk>;
power-domains = <&rpmhpd RPMHPD_CX>;
#clock-cells = <1>;
#reset-cells = <1>;
#power-domain-cells = <1>;

View File

@ -56,6 +56,11 @@ properties:
- qcom,rpmcc-shikra
- const: qcom,rpmcc-qcm2290
- const: qcom,rpmcc
- items:
- enum:
- qcom,rpmcc-msm8952
- const: qcom,rpmcc-msm8976
- const: qcom,rpmcc
'#clock-cells':
const: 1

View File

@ -22,6 +22,7 @@ properties:
- qcom,glymur-rpmh-clk
- qcom,hawi-rpmh-clk
- qcom,kaanapali-rpmh-clk
- qcom,kuno-rpmh-clk
- qcom,milos-rpmh-clk
- qcom,nord-rpmh-clk
- qcom,qcs615-rpmh-clk
@ -39,6 +40,7 @@ properties:
- qcom,sdx75-rpmh-clk
- qcom,sm4450-rpmh-clk
- qcom,sm6350-rpmh-clk
- qcom,sm7250-rpmh-clk
- qcom,sm8150-rpmh-clk
- qcom,sm8250-rpmh-clk
- qcom,sm8350-rpmh-clk

View File

@ -38,9 +38,14 @@ properties:
- description: PCIE Pipe clock source
- description: USB3 phy wrapper pipe clock source
power-domains:
items:
- description: CX power domain
required:
- compatible
- clocks
- power-domains
- '#power-domain-cells'
allOf:
@ -51,6 +56,7 @@ unevaluatedProperties: false
examples:
- |
#include <dt-bindings/clock/qcom,rpmh.h>
#include <dt-bindings/power/qcom,rpmhpd.h>
clock-controller@80000 {
compatible = "qcom,sdx75-gcc";
reg = <0x80000 0x1f7400>;
@ -59,6 +65,7 @@ examples:
<&emac1_sgmiiphy_mac_rclk>, <&emac1_sgmiiphy_mac_tclk>, <&emac1_sgmiiphy_rclk>,
<&emac1_sgmiiphy_tclk>, <&pcie20_phy_aux_clk>, <&pcie_1_pipe_clk>,
<&pcie_2_pipe_clk>, <&pcie_pipe_clk>, <&usb3_phy_wrapper_gcc_usb30_pipe_clk>;
power-domains = <&rpmhpd RPMHPD_CX>;
#clock-cells = <1>;
#reset-cells = <1>;
#power-domain-cells = <1>;

View File

@ -29,9 +29,14 @@ properties:
- description: UFS Phy Tx symbol 0 clock source
- description: USB3 Phy wrapper pipe clock source
power-domains:
items:
- description: CX power domain
required:
- compatible
- clocks
- power-domains
- '#power-domain-cells'
allOf:
@ -42,12 +47,14 @@ unevaluatedProperties: false
examples:
- |
#include <dt-bindings/clock/qcom,rpmh.h>
#include <dt-bindings/power/qcom,rpmhpd.h>
clock-controller@100000 {
compatible = "qcom,sm4450-gcc";
reg = <0x00100000 0x001f4200>;
clocks = <&rpmhcc RPMH_CXO_CLK>, <&sleep_clk>,
<&ufs_mem_phy 0>, <&ufs_mem_phy 1>,
<&ufs_mem_phy 2>, <&usb_1_qmpphy>;
power-domains = <&rpmhpd RPMHPD_CX>;
#clock-cells = <1>;
#reset-cells = <1>;
#power-domain-cells = <1>;

View File

@ -4,10 +4,13 @@
$id: http://devicetree.org/schemas/clock/qcom,sm6375-gcc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm Global Clock & Reset Controller on SM6375
title: Qualcomm Global Clock & Reset Controller on SM6375 and SM7150
maintainers:
- Konrad Dybcio <konradybcio@kernel.org>
- Bjorn Andersson <andersson@kernel.org>
- Danila Tikhonov <danila@jiaxyga.com>
- David Wronek <davidwronek@gmail.com>
description: |
Qualcomm global clock control module provides the clocks, resets and power
@ -20,7 +23,9 @@ allOf:
properties:
compatible:
const: qcom,sm6375-gcc
enum:
- qcom,sm6375-gcc
- qcom,sm7150-gcc
clocks:
items:

View File

@ -1,53 +0,0 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/qcom,sm7150-gcc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm Global Clock & Reset Controller on SM7150
maintainers:
- Bjorn Andersson <andersson@kernel.org>
- Danila Tikhonov <danila@jiaxyga.com>
- David Wronek <davidwronek@gmail.com>
description: |
Qualcomm global clock control module provides the clocks, resets and power
domains on SM7150
See also: include/dt-bindings/clock/qcom,sm7150-gcc.h
properties:
compatible:
const: qcom,sm7150-gcc
clocks:
items:
- description: Board XO source
- description: Board XO Active-Only source
- description: Sleep clock source
required:
- compatible
- clocks
- '#power-domain-cells'
allOf:
- $ref: qcom,gcc.yaml#
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/clock/qcom,rpmh.h>
clock-controller@100000 {
compatible = "qcom,sm7150-gcc";
reg = <0x00100000 0x001f0000>;
clocks = <&rpmhcc RPMH_CXO_CLK>,
<&rpmhcc RPMH_CXO_CLK_A>,
<&sleep_clk>;
#clock-cells = <1>;
#reset-cells = <1>;
#power-domain-cells = <1>;
};
...

View File

@ -31,9 +31,14 @@ properties:
- description: UFS Phy Tx symbol 0 clock source
- description: USB3 Phy wrapper pipe clock source
power-domains:
items:
- description: CX power domain
required:
- compatible
- clocks
- power-domains
- '#power-domain-cells'
allOf:
@ -44,6 +49,7 @@ unevaluatedProperties: false
examples:
- |
#include <dt-bindings/clock/qcom,rpmh.h>
#include <dt-bindings/power/qcom,rpmhpd.h>
clock-controller@100000 {
compatible = "qcom,sm8550-gcc";
reg = <0x00100000 0x001f4200>;
@ -55,6 +61,7 @@ examples:
<&ufs_mem_phy 1>,
<&ufs_mem_phy 2>,
<&usb_1_qmpphy>;
power-domains = <&rpmhpd RPMHPD_CX>;
#clock-cells = <1>;
#reset-cells = <1>;
#power-domain-cells = <1>;

View File

@ -36,7 +36,6 @@ properties:
- qcom,sm8550-tcsr
- qcom,sm8650-tcsr
- qcom,sm8750-tcsr
- qcom,x1e80100-tcsr
- const: syscon
- items:
- enum:

View File

@ -32,9 +32,14 @@ properties:
- description: UFS Phy Tx symbol 0 clock source
- description: USB3 Phy wrapper pipe clock source
power-domains:
items:
- description: CX power domain
required:
- compatible
- clocks
- power-domains
- '#power-domain-cells'
allOf:
@ -45,6 +50,7 @@ unevaluatedProperties: false
examples:
- |
#include <dt-bindings/clock/qcom,rpmh.h>
#include <dt-bindings/power/qcom,rpmhpd.h>
clock-controller@100000 {
compatible = "qcom,sm8650-gcc";
reg = <0x00100000 0x001f4200>;
@ -58,6 +64,7 @@ examples:
<&ufs_mem_phy 1>,
<&ufs_mem_phy 2>,
<&usb_1_qmpphy>;
power-domains = <&rpmhpd RPMHPD_CX>;
#clock-cells = <1>;
#reset-cells = <1>;
#power-domain-cells = <1>;

View File

@ -34,9 +34,14 @@ properties:
- description: UFS Phy Tx symbol 0 clock source
- description: USB3 Phy wrapper pipe clock source
power-domains:
items:
- description: CX power domain
required:
- compatible
- clocks
- power-domains
- '#power-domain-cells'
allOf:
@ -47,6 +52,7 @@ unevaluatedProperties: false
examples:
- |
#include <dt-bindings/clock/qcom,rpmh.h>
#include <dt-bindings/power/qcom,rpmhpd.h>
clock-controller@100000 {
compatible = "qcom,sm8750-gcc";
reg = <0x00100000 0x001f4200>;
@ -58,6 +64,7 @@ examples:
<&ufs_mem_phy 1>,
<&ufs_mem_phy 2>,
<&usb_1_qmpphy>;
power-domains = <&rpmhpd RPMHPD_CX>;
#clock-cells = <1>;
#reset-cells = <1>;
#power-domain-cells = <1>;

View File

@ -0,0 +1,114 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/qcom,x1e80100-tcsr.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm TCSR Clock Controller on X1E80100
maintainers:
- Bjorn Andersson <andersson@kernel.org>
- Taniya Das <taniya.das@oss.qualcomm.com>
description: |
Qualcomm TCSR clock control module provides the clocks on X1E80100
See also:
- include/dt-bindings/clock/qcom,x1e80100-tcsr.h
properties:
compatible:
items:
- enum:
- qcom,x1e80100-tcsr
- const: syscon
clocks:
items:
- description: TCXO pad clock
reg:
maxItems: 1
'#clock-cells':
const: 1
vdda-qrefrpt0-0p9-supply: true
vdda-qrefrpt1-0p9-supply: true
vdda-qrefrpt2-0p9-supply: true
vdda-qrefrpt3-0p9-supply: true
vdda-qrefrpt4-0p9-supply: true
vdda-qrefrx0-0p9-supply: true
vdda-qrefrx1-0p9-supply: true
vdda-qrefrx2-0p9-supply: true
vdda-qrefrx3-0p9-supply: true
vdda-qrefrx4-0p9-supply: true
vdda-qreftx0-0p9-supply: true
vdda-qreftx0-1p2-supply: true
vdda-qreftx1-0p9-supply: true
vdda-qreftx1-1p2-supply: true
vdda-refgen0-0p9-supply: true
vdda-refgen0-1p2-supply: true
vdda-refgen2-0p9-supply: true
vdda-refgen2-1p2-supply: true
required:
- compatible
- clocks
- '#clock-cells'
- vdda-qrefrpt0-0p9-supply
- vdda-qrefrpt1-0p9-supply
- vdda-qrefrpt2-0p9-supply
- vdda-qrefrpt3-0p9-supply
- vdda-qrefrpt4-0p9-supply
- vdda-qrefrx0-0p9-supply
- vdda-qrefrx1-0p9-supply
- vdda-qrefrx2-0p9-supply
- vdda-qrefrx3-0p9-supply
- vdda-qrefrx4-0p9-supply
- vdda-qreftx0-0p9-supply
- vdda-qreftx0-1p2-supply
- vdda-qreftx1-0p9-supply
- vdda-qreftx1-1p2-supply
- vdda-refgen0-0p9-supply
- vdda-refgen0-1p2-supply
- vdda-refgen2-0p9-supply
- vdda-refgen2-1p2-supply
additionalProperties: false
examples:
- |
#include <dt-bindings/clock/qcom,rpmh.h>
soc {
#address-cells = <2>;
#size-cells = <2>;
clock-controller@1fc0000 {
compatible = "qcom,x1e80100-tcsr", "syscon";
reg = <0x0 0x1fc0000 0x0 0x30000>;
clocks = <&rpmhcc RPMH_CXO_CLK>;
#clock-cells = <1>;
vdda-qrefrpt0-0p9-supply = <&vreg_l1a>;
vdda-qrefrpt1-0p9-supply = <&vreg_l1a>;
vdda-qrefrpt2-0p9-supply = <&vreg_l1a>;
vdda-qrefrpt3-0p9-supply = <&vreg_l1a>;
vdda-qrefrpt4-0p9-supply = <&vreg_l1a>;
vdda-qrefrx0-0p9-supply = <&vreg_l1a>;
vdda-qrefrx1-0p9-supply = <&vreg_l1a>;
vdda-qrefrx2-0p9-supply = <&vreg_l1a>;
vdda-qrefrx3-0p9-supply = <&vreg_l1a>;
vdda-qrefrx4-0p9-supply = <&vreg_l1a>;
vdda-qreftx0-0p9-supply = <&vreg_l1a>;
vdda-qreftx0-1p2-supply = <&vreg_l2a>;
vdda-qreftx1-0p9-supply = <&vreg_l1a>;
vdda-qreftx1-1p2-supply = <&vreg_l2a>;
vdda-refgen0-0p9-supply = <&vreg_l1a>;
vdda-refgen0-1p2-supply = <&vreg_l2a>;
vdda-refgen2-0p9-supply = <&vreg_l1a>;
vdda-refgen2-1p2-supply = <&vreg_l2a>;
};
};
...

View File

@ -0,0 +1,145 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/samsung,exynos5515-cmu.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Samsung Exynos5515 SoC clock controller
maintainers:
- Aiden Isik <aidenisik+git@member.fsf.org>
- Chanwoo Choi <cw00.choi@samsung.com>
- Krzysztof Kozlowski <krzk@kernel.org>
description: |
Exynos5515 clock controller is comprised of several CMU units, generating
clocks for different domains. Those CMU units are modeled as separate device
tree nodes, and might depend on each other. The root clock in that root tree
is an external clock: OSCCLK (26 MHz). This external clock must be defined
as a fixed-rate clock in dts.
CMU_TOP is a top-level CMU, where all base clocks are prepared using PLLs and
dividers; all other clocks of function blocks (other CMUs) are usually
derived from CMU_TOP.
Each clock is assigned an identifier and client nodes can use this identifier
to specify the clock which they consume. All clocks available for usage
in clock consumer nodes are defined as preprocessor macros in
'include/dt-bindings/clock/samsung,exynos5515-cmu.h' header.
properties:
compatible:
enum:
- samsung,exynos5515-cmu-fsys
- samsung,exynos5515-cmu-peri
- samsung,exynos5515-cmu-top
clocks:
minItems: 1
maxItems: 5
clock-names:
minItems: 1
maxItems: 5
"#clock-cells":
const: 1
reg:
maxItems: 1
samsung,sysreg:
$ref: /schemas/types.yaml#/definitions/phandle
description:
Phandle to system registers interface.
required:
- compatible
- clocks
- clock-names
- "#clock-cells"
- reg
- samsung,sysreg
allOf:
- if:
properties:
compatible:
contains:
enum:
- samsung,exynos5515-cmu-fsys
then:
properties:
clocks:
items:
- description: External reference clock (26MHz)
- description: CMU_FSYS BUS clock (from CMU_TOP)
- description: CMU_FSYS MMC card clock (from CMU_TOP)
- description: CMU_FSYS MMC embedded clock (from CMU_TOP)
- description: CMU_FSYS USB20DRD clock (from CMU_TOP)
clock-names:
items:
- const: oscclk
- const: bus
- const: mmc_card
- const: mmc_embd
- const: usb20drd
- if:
properties:
compatible:
contains:
enum:
- samsung,exynos5515-cmu-peri
then:
properties:
clocks:
items:
- description: External reference clock (26MHz)
- description: CMU_PERI BUS clock (from CMU_TOP)
- description: CMU_PERI IP clock (from CMU_TOP)
- description: CMU_PERI UART clock (from CMU_TOP)
clock-names:
items:
- const: oscclk
- const: bus
- const: ip
- const: uart
- if:
properties:
compatible:
contains:
const: samsung,exynos5515-cmu-top
then:
properties:
clocks:
items:
- description: External reference clock (26 MHz)
clock-names:
items:
- const: oscclk
additionalProperties: false
examples:
- |
#include <dt-bindings/clock/samsung,exynos5515-cmu.h>
cmu_top: clock-controller@15410000 {
compatible = "samsung,exynos5515-cmu-top";
reg = <0x15410000 0x10000>;
#clock-cells = <1>;
clocks = <&oscclk>;
clock-names = "oscclk";
samsung,sysreg = <&sysreg_top>;
};
...

View File

@ -0,0 +1,56 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/ti,palmas-clk32kg.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Texas Instruments Palmas 32KHz Clocks
maintainers:
- Eduard Bostina <egbostina@gmail.com>
description:
The Palmas device family has two clock output pins for 32KHz,
KG and KG_AUDIO.
allOf:
- $ref: /schemas/clock/clock.yaml#
properties:
compatible:
enum:
- ti,palmas-clk32kg
- ti,palmas-clk32kgaudio
"#clock-cells":
const: 0
ti,external-sleep-control:
$ref: /schemas/types.yaml#/definitions/uint32
enum: [ 0, 1, 2, 3 ]
description: |
The external enable input pins control the enable/disable of clocks.
The valid values (defined in dt-bindings/mfd/palmas.h) are:
1: PALMAS_EXT_CONTROL_PIN_ENABLE1
2: PALMAS_EXT_CONTROL_PIN_ENABLE2
3: PALMAS_EXT_CONTROL_PIN_NSLEEP
Option 0 or missing this property means the clock is enabled/disabled
via register access and these pins do not have any control.
required:
- compatible
- "#clock-cells"
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/mfd/palmas.h>
pmic {
clock-controller {
compatible = "ti,palmas-clk32kg";
#clock-cells = <0>;
ti,external-sleep-control = <PALMAS_EXT_CONTROL_PIN_NSLEEP>;
};
};

View File

@ -1,39 +0,0 @@
Binding for Texas Instruments ADPLL clock.
This binding uses the common clock binding[1]. It assumes a
register-mapped ADPLL with two to three selectable input clocks
and three to four children.
[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
Required properties:
- compatible : shall be one of "ti,dm814-adpll-s-clock" or
"ti,dm814-adpll-lj-clock" depending on the type of the ADPLL
- #clock-cells : from common clock binding; shall be set to 1.
- clocks : link phandles of parent clocks clkinp and clkinpulow, note
that the adpll-s-clock also has an optional clkinphif
- reg : address and length of the register set for controlling the ADPLL.
Examples:
adpll_mpu_ck: adpll@40 {
#clock-cells = <1>;
compatible = "ti,dm814-adpll-s-clock";
reg = <0x40 0x40>;
clocks = <&devosc_ck &devosc_ck &devosc_ck>;
clock-names = "clkinp", "clkinpulow", "clkinphif";
clock-output-names = "481c5040.adpll.dcoclkldo",
"481c5040.adpll.clkout",
"481c5040.adpll.clkoutx2",
"481c5040.adpll.clkouthif";
};
adpll_dsp_ck: adpll@80 {
#clock-cells = <1>;
compatible = "ti,dm814-adpll-lj-clock";
reg = <0x80 0x30>;
clocks = <&devosc_ck &devosc_ck>;
clock-names = "clkinp", "clkinpulow";
clock-output-names = "481c5080.adpll.dcoclkldo",
"481c5080.adpll.clkout",
"481c5080.adpll.clkoutldo";
};

View File

@ -1,96 +0,0 @@
Binding for TI DaVinci PLL Controllers
The PLL provides clocks to most of the components on the SoC. In addition
to the PLL itself, this controller also contains bypasses, gates, dividers,
an multiplexers for various clock signals.
Required properties:
- compatible: shall be one of:
- "ti,da850-pll0" for PLL0 on DA850/OMAP-L138/AM18XX
- "ti,da850-pll1" for PLL1 on DA850/OMAP-L138/AM18XX
- reg: physical base address and size of the controller's register area.
- clocks: phandles corresponding to the clock names
- clock-names: names of the clock sources - depends on compatible string
- for "ti,da850-pll0", shall be "clksrc", "extclksrc"
- for "ti,da850-pll1", shall be "clksrc"
Optional properties:
- ti,clkmode-square-wave: Indicates that the board is supplying a square
wave input on the OSCIN pin instead of using a crystal oscillator.
This property is only valid when compatible = "ti,da850-pll0".
Optional child nodes:
pllout
Describes the main PLL clock output (before POSTDIV). The node name must
be "pllout".
Required properties:
- #clock-cells: shall be 0
sysclk
Describes the PLLDIVn divider clocks that provide the SYSCLKn clock
domains. The node name must be "sysclk". Consumers of this node should
use "n" in "SYSCLKn" as the index parameter for the clock cell.
Required properties:
- #clock-cells: shall be 1
auxclk
Describes the AUXCLK output of the PLL. The node name must be "auxclk".
This child node is only valid when compatible = "ti,da850-pll0".
Required properties:
- #clock-cells: shall be 0
obsclk
Describes the OBSCLK output of the PLL. The node name must be "obsclk".
Required properties:
- #clock-cells: shall be 0
Examples:
pll0: clock-controller@11000 {
compatible = "ti,da850-pll0";
reg = <0x11000 0x1000>;
clocks = <&ref_clk>, <&pll1_sysclk 3>;
clock-names = "clksrc", "extclksrc";
ti,clkmode-square-wave;
pll0_pllout: pllout {
#clock-cells = <0>;
};
pll0_sysclk: sysclk {
#clock-cells = <1>;
};
pll0_auxclk: auxclk {
#clock-cells = <0>;
};
pll0_obsclk: obsclk {
#clock-cells = <0>;
};
};
pll1: clock-controller@21a000 {
compatible = "ti,da850-pll1";
reg = <0x21a000 0x1000>;
clocks = <&ref_clk>;
clock-names = "clksrc";
pll0_sysclk: sysclk {
#clock-cells = <1>;
};
pll0_obsclk: obsclk {
#clock-cells = <0>;
};
};
Also see:
- Documentation/devicetree/bindings/clock/clock-bindings.txt

View File

@ -0,0 +1,164 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/ti/davinci/ti,da850-pll.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: TI DaVinci PLL Controllers
maintainers:
- David Lechner <david@lechnology.com>
description:
The PLL provides clocks to most of the components on the SoC. In addition to
the PLL itself, this controller also contains bypasses, gates, dividers, an
multiplexers for various clock signals.
properties:
compatible:
enum:
- ti,da850-pll0
- ti,da850-pll1
reg:
maxItems: 1
clocks:
minItems: 1
items:
- description: Primary reference clock input
- description: External clock source
clock-names:
minItems: 1
items:
- const: clksrc
- const: extclksrc
ti,clkmode-square-wave:
type: boolean
description:
Indicates that the board is supplying a square wave input on the OSCIN
pin instead of using a crystal oscillator.
pllout:
type: object
description:
Main PLL clock output before POSTDIV.
properties:
'#clock-cells':
const: 0
required:
- '#clock-cells'
additionalProperties: false
sysclk:
type: object
description:
PLLDIVn divider clocks that provide the SYSCLKn clock domains. Consumers
of this node should use "n" in "SYSCLKn" as the index parameter for the
clock cell.
properties:
'#clock-cells':
const: 1
required:
- '#clock-cells'
additionalProperties: false
auxclk:
type: object
description:
AUXCLK output of the PLL
properties:
'#clock-cells':
const: 0
required:
- '#clock-cells'
additionalProperties: false
obsclk:
type: object
description:
the OBSCLK output of the PLL.
properties:
'#clock-cells':
const: 0
required:
- '#clock-cells'
additionalProperties: false
required:
- compatible
- reg
- clocks
- clock-names
additionalProperties: false
allOf:
- if:
properties:
compatible:
const: ti,da850-pll1
then:
properties:
clocks:
maxItems: 1
clock-names:
maxItems: 1
ti,clkmode-square-wave: false
auxclk: false
examples:
- |
clock-controller@11000 {
compatible = "ti,da850-pll0";
reg = <0x11000 0x1000>;
clocks = <&ref_clk>, <&pll1_sysclk 3>;
clock-names = "clksrc", "extclksrc";
ti,clkmode-square-wave;
pllout {
#clock-cells = <0>;
};
sysclk {
#clock-cells = <1>;
};
auxclk {
#clock-cells = <0>;
};
obsclk {
#clock-cells = <0>;
};
};
- |
clock-controller@21a000 {
compatible = "ti,da850-pll1";
reg = <0x21a000 0x1000>;
clocks = <&ref_clk>;
clock-names = "clksrc";
sysclk {
#clock-cells = <1>;
};
obsclk {
#clock-cells = <0>;
};
};

View File

@ -1,94 +0,0 @@
Device Tree Clock bindings for ATL (Audio Tracking Logic) of DRA7 SoC.
The ATL IP is used to generate clock to be used to synchronize baseband and
audio codec. A single ATL IP provides four ATL clock instances sharing the same
functional clock but can be configured to provide different clocks.
ATL can maintain a clock averages to some desired frequency based on the bws/aws
signals - can compensate the drift between the two ws signal.
In order to provide the support for ATL and its output clocks (which can be used
internally within the SoC or external components) two sets of bindings is needed:
Clock tree binding:
This binding uses the common clock binding[1].
To be able to integrate the ATL clocks with DT clock tree.
Provides ccf level representation of the ATL clocks to be used by drivers.
Since the clock instances are part of a single IP this binding is used as a node
for the DT clock tree, the IP driver is needed to handle the actual configuration
of the IP.
[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
Required properties:
- compatible : shall be "ti,dra7-atl-clock"
- #clock-cells : from common clock binding; shall be set to 0.
- clocks : link phandles to functional clock of ATL
Binding for the IP driver:
This binding is used to configure the IP driver which is going to handle the
configuration of the IP for the ATL clock instances.
Required properties:
- compatible : shall be "ti,dra7-atl"
- reg : base address for the ATL IP
- ti,provided-clocks : List of phandles to the clocks associated with the ATL
- clocks : link phandles to functional clock of ATL
- clock-names : Shall be set to "fck"
- ti,hwmods : Shall be set to "atl"
Optional properties:
Configuration of ATL instances:
- atl{0/1/2/3} {
- bws : Baseband word select signal selection
- aws : Audio word select signal selection
};
For valid word select signals, see the dt-bindings/clock/ti-dra7-atl.h include
file.
Examples:
/* clock bindings for atl provided clocks */
atl_clkin0_ck: atl_clkin0_ck {
#clock-cells = <0>;
compatible = "ti,dra7-atl-clock";
clocks = <&atl_gfclk_mux>;
};
atl_clkin1_ck: atl_clkin1_ck {
#clock-cells = <0>;
compatible = "ti,dra7-atl-clock";
clocks = <&atl_gfclk_mux>;
};
atl_clkin2_ck: atl_clkin2_ck {
#clock-cells = <0>;
compatible = "ti,dra7-atl-clock";
clocks = <&atl_gfclk_mux>;
};
atl_clkin3_ck: atl_clkin3_ck {
#clock-cells = <0>;
compatible = "ti,dra7-atl-clock";
clocks = <&atl_gfclk_mux>;
};
/* binding for the IP */
atl: atl@4843c000 {
compatible = "ti,dra7-atl";
reg = <0x4843c000 0x3ff>;
ti,hwmods = "atl";
ti,provided-clocks = <&atl_clkin0_ck>, <&atl_clkin1_ck>,
<&atl_clkin2_ck>, <&atl_clkin3_ck>;
clocks = <&atl_gfclk_mux>;
clock-names = "fck";
};
#include <dt-bindings/clock/ti-dra7-atl.h>
&atl {
atl2 {
bws = <DRA7_ATL_WS_MCASP2_FSX>;
aws = <DRA7_ATL_WS_MCASP3_FSX>;
};
};

View File

@ -1,31 +0,0 @@
Binding for Texas Instruments FAPLL clock.
This binding uses the common clock binding[1]. It assumes a
register-mapped FAPLL with usually two selectable input clocks
(reference clock and bypass clock), and one or more child
syntesizers.
[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
Required properties:
- compatible : shall be "ti,dm816-fapll-clock"
- #clock-cells : from common clock binding; shall be set to 0.
- clocks : link phandles of parent clocks (clk-ref and clk-bypass)
- reg : address and length of the register set for controlling the FAPLL.
Examples:
main_fapll: main_fapll {
#clock-cells = <1>;
compatible = "ti,dm816-fapll-clock";
reg = <0x400 0x40>;
clocks = <&sys_clkin_ck &sys_clkin_ck>;
clock-indices = <1>, <2>, <3>, <4>, <5>,
<6>, <7>;
clock-output-names = "main_pll_clk1",
"main_pll_clk2",
"main_pll_clk3",
"main_pll_clk4",
"main_pll_clk5",
"main_pll_clk6",
"main_pll_clk7";
};

View File

@ -0,0 +1,88 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/ti/ti,dm814-adpll-clock.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Texas Instruments DM814x ADPLL Clock
maintainers:
- Tony Lindgren <tony@atomide.com>
description:
The ADPLL is a register-mapped clock generator found on TI DM814x SoCs. It
provides multiple output clocks from two or three selectable input clocks and
three to four children.
properties:
compatible:
enum:
- ti,dm814-adpll-s-clock
- ti,dm814-adpll-lj-clock
reg:
maxItems: 1
'#clock-cells':
const: 1
clocks:
minItems: 2
maxItems: 3
clock-names:
minItems: 2
items:
- const: clkinp
- const: clkinpulow
- const: clkinphif
clock-output-names:
minItems: 3
maxItems: 4
required:
- compatible
- reg
- '#clock-cells'
- clocks
- clock-output-names
if:
properties:
compatible:
contains:
const: ti,dm814-adpll-s-clock
then:
properties:
clocks:
minItems: 3
clock-names:
minItems: 3
clock-output-names:
minItems: 4
else:
properties:
clocks:
maxItems: 2
clock-names:
maxItems: 2
clock-output-names:
maxItems: 3
additionalProperties: false
examples:
- |
adpll@40 {
compatible = "ti,dm814-adpll-s-clock";
reg = <0x40 0x40>;
#clock-cells = <1>;
clocks = <&devosc_ck &devosc_ck &devosc_ck>;
clock-names = "clkinp", "clkinpulow", "clkinphif";
clock-output-names = "481c5040.adpll.dcoclkldo",
"481c5040.adpll.clkout",
"481c5040.adpll.clkoutx2",
"481c5040.adpll.clkouthif";
};

View File

@ -0,0 +1,71 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/ti/ti,dm816-fapll-clock.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Texas Instruments FAPLL clock
maintainers:
- Tony Lindgren <tony@atomide.com>
- Tero Kristo <kristo@kernel.org>
description:
FAPLL is register-mapped with usually two selectable input clocks
(reference clock and bypass clock), and one or more child synthesizers.
properties:
compatible:
const: ti,dm816-fapll-clock
"#clock-cells":
const: 1
reg:
maxItems: 1
clocks:
items:
- description: parent clock clk-ref
- description: parent clock clk-bypass
clock-indices:
description:
Maps child synthesizers to physical indices 1-7. Index 0 is physically
reserved for the Master PLL.
minItems: 1
maxItems: 7
items:
minimum: 1
maximum: 7
clock-output-names:
description:
Names of the child synthesizer outputs. The length of this array must
match clock-indices.
minItems: 1
maxItems: 7
required:
- compatible
- reg
- clocks
- "#clock-cells"
- clock-indices
- clock-output-names
additionalProperties: false
examples:
- |
clock-controller@400 {
#clock-cells = <1>;
compatible = "ti,dm816-fapll-clock";
reg = <0x400 0x40>;
clocks = <&sys_clkin_ck &sys_clkin_ck>;
clock-indices = <1>, <2>, <3>, <4>, <5>, <6>, <7>;
clock-output-names = "main_pll_clk1", "main_pll_clk2", "main_pll_clk3",
"main_pll_clk4", "main_pll_clk5", "main_pll_clk6",
"main_pll_clk7";
};

View File

@ -0,0 +1,38 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/ti/ti,dra7-atl-clock.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: TI DRA7 ATL (Audio Tracking Logic) clock output
maintainers:
- Peter Ujfalusi <peter.ujfalusi@ti.com>
properties:
compatible:
const: ti,dra7-atl-clock
"#clock-cells":
const: 0
clocks:
maxItems: 1
clock-output-names:
maxItems: 1
required:
- compatible
- "#clock-cells"
- clocks
additionalProperties: false
examples:
- |
atl_clkin0_ck {
compatible = "ti,dra7-atl-clock";
#clock-cells = <0>;
clocks = <&atl_gfclk_mux>;
};

View File

@ -0,0 +1,100 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/ti/ti,dra7-atl.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: TI DRA7 ATL (Audio Tracking Logic) Clock Controller
maintainers:
- Peter Ujfalusi <peter.ujfalusi@ti.com>
description:
The ATL IP is used to generate clock to be used to synchronize baseband and
audio codec. A single ATL IP provides four ATL clock instances sharing the
same functional clock but can be configured to provide different clocks.
ATL can maintain a clock averages to some desired frequency based on the
bws/aws signals - can compensate the drift between the two ws signal.
See also Documentation/devicetree/bindings/clock/ti/ti,dra7-atl-clock.yaml
properties:
compatible:
const: ti,dra7-atl
reg:
maxItems: 1
clocks:
maxItems: 1
clock-names:
items:
- const: fck
ti,provided-clocks:
$ref: /schemas/types.yaml#/definitions/phandle-array
description:
List of phandles to the clocks associated with the ATL.
minItems: 4
maxItems: 4
items:
maxItems: 1
ti,hwmods:
$ref: /schemas/types.yaml#/definitions/string
description:
Name of the hwmod associated with the ATL.
deprecated: true
const: atl
patternProperties:
"^atl[0-3]$":
type: object
additionalProperties: false
description:
Configuration of ATL instances.
properties:
bws:
$ref: /schemas/types.yaml#/definitions/uint32
description:
Baseband word select signal selection.
maximum: 15
aws:
$ref: /schemas/types.yaml#/definitions/uint32
description:
Audio word select signal selection.
maximum: 15
required:
- bws
- aws
required:
- compatible
- reg
- clocks
- clock-names
- ti,provided-clocks
additionalProperties: false
examples:
- |
#include <dt-bindings/clock/ti-dra7-atl.h>
atl@4843c000 {
compatible = "ti,dra7-atl";
reg = <0x4843c000 0x3ff>;
clocks = <&atl_gfclk_mux>;
clock-names = "fck";
ti,provided-clocks = <&atl_clkin0_ck>, <&atl_clkin1_ck>,
<&atl_clkin2_ck>, <&atl_clkin3_ck>;
atl2 {
bws = <DRA7_ATL_WS_MCASP2_FSX>;
aws = <DRA7_ATL_WS_MCASP3_FSX>;
};
};

View File

@ -0,0 +1,101 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/zte,zx297520v3-lspcrm.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: ZTE zx297520v3 SoC LSP clock and reset controller
maintainers:
- Stefan Dösinger <stefandoesinger@gmail.com>
description: |
This clock and reset controller controls low speed peripherals on the board.
This is a relatively isolated subsystem containing UART, I2C, I2S and SPI
devices. The controller is responsible for bringing the devices out of reset
and enabling their clocks as needed.
The controller receives its clock signals from the matrix controller, and
these signals need to be declared as clock inputs.
All available clocks are defined as preprocessor macros in the
"include/dt-bindings/clock/zte,zx297520v3-clk.h" header. Resets are defined in
the "include/dt-bindings/reset/zte,zx297520v3-reset.h" header.
properties:
compatible:
const: zte,zx297520v3-lspcrm
reg:
maxItems: 1
clocks:
items:
- description: Main PLL divided by 5 output from matrixcrm (124.8 MHz)
- description: Main PLL divided by 4 output from matrixcrm (156 MHz)
- description: Main PLL divided by 6 output from matrixcrm (104 MHz)
- description: Main PLL divided by 8 output from matrixcrm (78 MHz)
- description: Main PLL divided by 12 output from matrixcrm (52 MHz)
- description: Main oscillator output from matrixcrm (26 MHz)
- description: Timer oscillator output from matrixcrm (32 kHz)
- description: LSP pclk output from matrixcrm (26 MHz)
- description: TDM wclk mux output from matrixcrm
- description: DPLL divided by 4 output from matrixcrm (122.88 MHz)
clock-names:
items:
- const: mpll-d5
- const: mpll-d4
- const: mpll-d6
- const: mpll-d8
- const: mpll-d12
- const: osc26m
- const: osc32k
- const: pclk
- const: tdm-wclk
- const: dpll-d4
resets:
maxItems: 1
"#clock-cells":
const: 1
"#reset-cells":
const: 1
required:
- compatible
- reg
- clocks
- clock-names
- resets
- "#clock-cells"
- "#reset-cells"
additionalProperties: false
examples:
- |
#include <dt-bindings/clock/zte,zx297520v3-clk.h>
#include <dt-bindings/reset/zte,zx297520v3-reset.h>
clock-controller@1400000 {
compatible = "zte,zx297520v3-lspcrm";
reg = <0x01400000 0x100>;
#clock-cells = <1>;
clocks = <&matrixcrm ZX297520V3_LSP_MPLL_D5_WCLK>,
<&matrixcrm ZX297520V3_LSP_MPLL_D4_WCLK>,
<&matrixcrm ZX297520V3_LSP_MPLL_D6_WCLK>,
<&matrixcrm ZX297520V3_LSP_MPLL_D8_WCLK>,
<&matrixcrm ZX297520V3_LSP_MPLL_D12_WCLK>,
<&matrixcrm ZX297520V3_LSP_OSC26M_WCLK>,
<&matrixcrm ZX297520V3_LSP_OSC32K_WCLK>,
<&matrixcrm ZX297520V3_LSP_PCLK>,
<&matrixcrm ZX297520V3_LSP_TDM_WCLK>,
<&matrixcrm ZX297520V3_LSP_DPLL_D4_WCLK>;
clock-names = "mpll-d5", "mpll-d4", "mpll-d6", "mpll-d8", "mpll-d12",
"osc26m", "osc32k", "pclk", "tdm-wclk", "dpll-d4";
#reset-cells = <1>;
resets = <&matrixcrm ZX297520V3_LSP_RESET>;
};

View File

@ -0,0 +1,98 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/zte,zx297520v3-matrixcrm.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: ZTE zx297520v3 SoC matrix clock and reset controller
maintainers:
- Stefan Dösinger <stefandoesinger@gmail.com>
description: |
This controller contains clock and reset controls for high speed devices on
the zx297520v3 board: The CPU, RAM, SDIO and Ethernet clocks and resets are
found here. This controller requires PLL-generated clocks from Topcrm as well
as the fixed 26 MHz and 32 kHz oscillators found on this board.
This controller also contains hardware mutex registers for synchronization
with different processors on this board.
An additional curiosity are registers that allow setting (but not reading) the
ARM architected timer's CNTVAL. This is not exposed in the binding because
there shouldn't be a need to access it.
All available clocks are defined as preprocessor macros in the
"include/dt-bindings/clock/zte,zx297520v3-clk.h" header. Resets are defined in
the "include/dt-bindings/reset/zte,zx297520v3-reset.h" header.
properties:
compatible:
const: zte,zx297520v3-matrixcrm
reg:
maxItems: 1
clocks:
items:
- description: 26 MHz external oscillator
- description: 32 kHz external oscillator
- description: AHB clock from topcrm
- description: Main PLL output from topcrm (usually 624 MHz)
- description: Main PLL subdivision factor 5
- description: Dpll output from topcrm (usually 491.52 MHz)
- description: Gpll output from topcrm (usually 200 MHz)
- description: Gpll subdivision factor 2
- description: osc26m work clock from topcrm
clock-names:
items:
- const: osc26m
- const: osc32k
- const: ahb
- const: mpll
- const: mpll-d5
- const: dpll
- const: gpll
- const: gpll-d2
- const: wclk-osc26m
"#clock-cells":
const: 1
"#hwlock-cells":
const: 1
"#reset-cells":
const: 1
required:
- compatible
- reg
- clocks
- clock-names
- "#clock-cells"
- "#hwlock-cells"
- "#reset-cells"
additionalProperties: false
examples:
- |
#include <dt-bindings/clock/zte,zx297520v3-clk.h>
#include <dt-bindings/reset/zte,zx297520v3-reset.h>
clock-controller@1306000 {
compatible = "zte,zx297520v3-matrixcrm";
reg = <0x01306000 0x400>;
#clock-cells = <1>;
clocks = <&osc26m>, <&osc32k>, <&topcrm ZX297520V3_AHB_PCLK>,
<&topcrm ZX297520V3_MPLL>, <&topcrm ZX297520V3_MPLL_D5>,
<&topcrm ZX297520V3_DPLL>, <&topcrm ZX297520V3_GPLL>,
<&topcrm ZX297520V3_GPLL_D2>,
<&topcrm ZX297520V3_GATED_OSC26M>;
clock-names = "osc26m", "osc32k", "ahb", "mpll", "mpll-d5", "dpll",
"gpll", "gpll-d2", "wclk-osc26m";
#hwlock-cells = <1>;
#reset-cells = <1>;
};

View File

@ -0,0 +1,122 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/zte,zx297520v3-topcrm.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: ZTE zx297520v3 SoC top clock and reset controller
maintainers:
- Stefan Dösinger <stefandoesinger@gmail.com>
description: |
The zx297520v3 top clock and reset controller generates clocks for core
devices on the board like the main bus, USB and timers. In addition to clocks
it has reset controls for peripherals, a global board reset, watchdog reset
controls and a USB status register.
The controller has two clock inputs: a 26 MHz and a 32 kHz external
oscillator. They need to be provided as input clocks. The controller provides
PLL output frequencies to downstream clock controllers.
The USB PHY is exposed as two PHYs, one for USB and another for HSIC. Note
that while the controls for both PHYs are always present, the PHYs themselves
may be absent. If this is the case the controller never signals that the
missing PHY is ready.
All available clocks are defined as preprocessor macros in the
"include/dt-bindings/clock/zte,zx297520v3-clk.h" header. The resets are
defined in the "include/dt-bindings/reset/zte,zx297520v3-reset.h" header. PHY
defines are found in "include/dt-bindings/phy/zte,zx297520v3-topcrm.h".
properties:
compatible:
items:
- const: zte,zx297520v3-topcrm
- const: syscon
reg:
maxItems: 1
clocks:
items:
- description: 26 MHz external oscillator
- description: 32 kHz external oscillator
clock-names:
items:
- const: osc26m
- const: osc32k
interrupts:
items:
- description: IRQ reporting USB connection
- description: IRQ reporting USB disconnection
- description: IRQ reporting HSIC connection
- description: IRQ reporting HSIC disconnection
interrupt-names:
items:
- const: usb-up
- const: usb-down
- const: hsic-up
- const: hsic-down
"#clock-cells":
const: 1
"#phy-cells":
const: 1
"#reset-cells":
const: 1
reboot:
type: object
$ref: /schemas/power/reset/syscon-reboot.yaml#
unevaluatedProperties: false
description:
Reboot method for the SoC.
required:
- compatible
- reg
- clocks
- clock-names
- interrupts
- interrupt-names
- reboot
- "#clock-cells"
- "#phy-cells"
- "#reset-cells"
additionalProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/reset/zte,zx297520v3-reset.h>
#include <dt-bindings/phy/zte,zx297520v3-topcrm.h>
#include <dt-bindings/clock/zte,zx297520v3-clk.h>
clock-controller@13b000 {
compatible = "zte,zx297520v3-topcrm", "syscon";
reg = <0x0013b000 0x400>;
#clock-cells = <1>;
clocks = <&osc26m>, <&osc32k>;
clock-names = "osc26m", "osc32k";
interrupts = <GIC_SPI 42 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 43 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 45 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 46 IRQ_TYPE_EDGE_RISING>;
interrupt-names = "usb-up", "usb-down", "hsic-up", "hsic-down";
#phy-cells = <1>;
#reset-cells = <1>;
reboot {
compatible = "syscon-reboot";
mask = <0x1>;
offset = <0x0>;
value = <0x1>;
};
};

View File

@ -2069,6 +2069,15 @@ M: Jiaxun Yang <jiaxun.yang@flygoat.com>
S: Supported
F: drivers/rtc/rtc-goldfish.c
ANLOGIC DR1V90 CRU DRIVER
M: Junhui Liu <junhui.liu@pigmoral.tech>
S: Maintained
F: Documentation/devicetree/bindings/clock/anlogic,dr1v90-cru.yaml
F: drivers/clk/anlogic/cru?dr1*
F: drivers/reset/reset-dr1v90.c
F: include/dt-bindings/clock/anlogic,dr1v90-cru.h
F: include/dt-bindings/reset/anlogic,dr1v90-cru.h
AOA (Apple Onboard Audio) ALSA DRIVER
M: Johannes Berg <johannes@sipsolutions.net>
L: linuxppc-dev@lists.ozlabs.org
@ -3963,8 +3972,15 @@ L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Odd fixes
F: Documentation/arch/arm/zte/
F: Documentation/devicetree/bindings/arm/zte.yaml
F: Documentation/devicetree/bindings/clock/zte,zx297520v3-lspcrm.yaml
F: Documentation/devicetree/bindings/clock/zte,zx297520v3-matrixcrm.yaml
F: Documentation/devicetree/bindings/clock/zte,zx297520v3-topcrm.yaml
F: arch/arm/boot/dts/zte/
F: arch/arm/mach-zte/
F: drivers/clk/zte/
F: include/dt-bindings/clock/zte,zx297520v3-clk.h
F: include/dt-bindings/phy/zte,zx297520v3-topcrm.h
F: include/dt-bindings/reset/zte,zx297520v3-reset.h
ARM/ZYNQ ARCHITECTURE
M: Michal Simek <michal.simek@amd.com>
@ -6635,7 +6651,7 @@ M: Jerome Brunet <jbrunet+clk@baylibre.com>
L: linux-clk@vger.kernel.org
S: Maintained
Q: http://patchwork.kernel.org/project/linux-clk/list/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git
T: git git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git clk-next
F: Documentation/devicetree/bindings/clock/
F: drivers/clk/
F: include/dt-bindings/clock/
@ -16958,6 +16974,17 @@ M: Sean Wang <sean.wang@mediatek.com>
S: Maintained
F: drivers/media/rc/mtk-cir.c
MEDIATEK CLOCK DRIVERS
M: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
L: linux-clk@vger.kernel.org
L: linux-mediatek@lists.infradead.org (moderated for non-subscribers)
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mediatek/linux.git
F: Documentation/devicetree/bindings/clock/mediatek,*
F: drivers/clk/mediatek/
F: include/dt-bindings/clock/mediatek,*.h
F: include/dt-bindings/clock/mt*-clk.h
MEDIATEK DMA DRIVER
M: Sean Wang <sean.wang@mediatek.com>
L: dmaengine@vger.kernel.org
@ -22846,6 +22873,7 @@ F: drivers/media/platform/qcom/camss/
QUALCOMM CLOCK DRIVERS
M: Bjorn Andersson <andersson@kernel.org>
R: Abel Vesa <abelvesa@kernel.org>
L: linux-arm-msm@vger.kernel.org
S: Supported
T: git git://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux.git
@ -24138,11 +24166,12 @@ N: spacemit
K: spacemit
RISC-V TENSTORRENT SoC SUPPORT
M: Drew Fustini <dfustini@oss.tenstorrent.com>
M: Drew Fustini <fustini@kernel.org>
M: Joel Stanley <jms@oss.tenstorrent.com>
M: Anirudh Srinivasan <asrinivasan@oss.tenstorrent.com>
L: linux-riscv@lists.infradead.org
S: Maintained
T: git https://github.com/tenstorrent/linux.git
T: git git://git.kernel.org/pub/scm/linux/kernel/git/tenstorrent/linux.git
F: Documentation/devicetree/bindings/clock/tenstorrent,atlantis-prcm-rcpu.yaml
F: Documentation/devicetree/bindings/riscv/tenstorrent.yaml
F: arch/riscv/boot/dts/tenstorrent/

View File

@ -221,6 +221,7 @@ config COMMON_CLK_EN7523
bool "Clock driver for Airoha/EcoNet SoC system clocks"
depends on OF
depends on ARCH_AIROHA || ECONET || COMPILE_TEST
select GENERIC_PHY
default ARCH_AIROHA
help
This driver provides the fixed clocks and gates present on Airoha
@ -450,14 +451,17 @@ config COMMON_CLK_STM32H7
config COMMON_CLK_MMP2
def_bool COMMON_CLK && (MACH_MMP2_DT || MACH_MMP3_DT)
select COMMON_CLK_MMP
help
Support for Marvell MMP2 and MMP3 SoC clocks
config COMMON_CLK_MMP2_AUDIO
tristate "Clock driver for MMP2 Audio subsystem"
depends on COMMON_CLK_MMP2 || COMPILE_TEST
help
This driver supports clocks for Audio subsystem on MMP2 SoC.
tristate "Clock driver for MMP2 Audio subsystem"
depends on COMMON_CLK_MMP2 || COMPILE_TEST
depends on PM_CLK
select COMMON_CLK_MMP
help
This driver supports clocks for Audio subsystem on MMP2 SoC.
config COMMON_CLK_BD718XX
tristate "Clock driver for 32K clk gates on ROHM PMICs"
@ -507,9 +511,11 @@ config COMMON_CLK_RPMI
source "drivers/clk/actions/Kconfig"
source "drivers/clk/analogbits/Kconfig"
source "drivers/clk/anlogic/Kconfig"
source "drivers/clk/aspeed/Kconfig"
source "drivers/clk/bcm/Kconfig"
source "drivers/clk/cix/Kconfig"
source "drivers/clk/davinci/Kconfig"
source "drivers/clk/eswin/Kconfig"
source "drivers/clk/hisilicon/Kconfig"
source "drivers/clk/imgtec/Kconfig"
@ -547,6 +553,7 @@ source "drivers/clk/uniphier/Kconfig"
source "drivers/clk/visconti/Kconfig"
source "drivers/clk/x86/Kconfig"
source "drivers/clk/xilinx/Kconfig"
source "drivers/clk/zte/Kconfig"
source "drivers/clk/zynqmp/Kconfig"
# Kunit test cases

View File

@ -29,6 +29,7 @@ clk-test-y := clk_test.o \
kunit_clk_assigned_sscs_zero.dtbo.o \
kunit_clk_assigned_sscs_zero_consumer.dtbo.o \
kunit_clk_hw_get_dev_of_node.dtbo.o \
kunit_clk_parse_clkspec.dtbo.o \
kunit_clk_parent_data_test.dtbo.o
obj-$(CONFIG_COMMON_CLK) += clk-divider.o
obj-$(CONFIG_CLK_DIVIDER_KUNIT_TEST) += clk-divider_test.o
@ -125,6 +126,7 @@ obj-$(CONFIG_COMMON_CLK_XGENE) += clk-xgene.o
# please keep this section sorted lexicographically by directory path name
obj-y += actions/
obj-y += analogbits/
obj-y += anlogic/
obj-y += aspeed/
obj-$(CONFIG_COMMON_CLK_AT91) += at91/
obj-$(CONFIG_ARCH_ARTPEC) += axis/
@ -132,7 +134,7 @@ obj-$(CONFIG_ARC_PLAT_AXS10X) += axs10x/
obj-y += bcm/
obj-$(CONFIG_ARCH_BERLIN) += berlin/
obj-y += cix/
obj-$(CONFIG_ARCH_DAVINCI) += davinci/
obj-$(CONFIG_COMMON_CLK_DAVINCI) += davinci/
obj-$(CONFIG_COMMON_CLK_ESWIN) += eswin/
obj-$(CONFIG_COMMON_CLK_HISI) += hisilicon/
obj-y += imgtec/
@ -143,12 +145,12 @@ obj-y += mediatek/
obj-$(CONFIG_ARCH_MESON) += meson/
obj-y += microchip/
ifeq ($(CONFIG_COMMON_CLK), y)
obj-$(CONFIG_ARCH_MMP) += mmp/
obj-$(CONFIG_COMMON_CLK_MMP) += mmp/
endif
obj-y += mstar/
obj-y += mvebu/
obj-$(CONFIG_ARCH_MXS) += mxs/
obj-$(CONFIG_ARCH_MA35) += nuvoton/
obj-y += nuvoton/
obj-$(CONFIG_COMMON_CLK_NXP) += nxp/
obj-$(CONFIG_COMMON_CLK_PISTACHIO) += pistachio/
obj-$(CONFIG_COMMON_CLK_PXA) += pxa/
@ -181,5 +183,6 @@ ifeq ($(CONFIG_COMMON_CLK), y)
obj-$(CONFIG_X86) += x86/
endif
obj-y += xilinx/
obj-$(CONFIG_COMMON_CLK_ZTE) += zte/
obj-$(CONFIG_ARCH_ZYNQ) += zynq/
obj-$(CONFIG_COMMON_CLK_ZYNQMP) += zynqmp/

View File

@ -119,6 +119,5 @@ extern const struct clk_ops owl_comp_div_ops;
extern const struct clk_ops owl_comp_fact_ops;
extern const struct clk_ops owl_comp_fix_fact_ops;
extern const struct clk_ops owl_comp_pass_ops;
extern const struct clk_ops clk_fixed_factor_ops;
#endif /* _OWL_COMPOSITE_H_ */

View File

@ -23,6 +23,4 @@
_flags), \
}
extern const struct clk_ops clk_fixed_factor_ops;
#endif /* _OWL_FIXED_FACTOR_H_ */

View File

@ -186,7 +186,7 @@ static int owl_pll_set_rate(struct clk_hw *hw, unsigned long rate,
regmap_write(common->regmap, pll_hw->reg, reg);
udelay(pll_hw->delay);
udelay((unsigned long)pll_hw->delay);
return 0;
}

View File

@ -0,0 +1,21 @@
# SPDX-License-Identifier: GPL-2.0-only
config ANLOGIC_DR1_CRU
tristate "Clock support for Anlogic DR1 series SoCs"
depends on ARCH_ANLOGIC || COMPILE_TEST
select AUXILIARY_BUS
default ARCH_ANLOGIC
help
Say Y to enable clock controller unit support for Anlogic DR1 series
SoCs.
if ANLOGIC_DR1_CRU
config ANLOGIC_DR1V90_CRU
tristate "Anlogic DR1V90 clock support"
depends on ARCH_ANLOGIC || COMPILE_TEST
default ARCH_ANLOGIC
help
Support for the Clock and Reset Unit in Anlogic DR1V90 SoCs.
endif

View File

@ -0,0 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-only
obj-$(CONFIG_ANLOGIC_DR1_CRU) += anlogic-dr1-cru.o
anlogic-dr1-cru-y += cru_dr1.o
obj-$(CONFIG_ANLOGIC_DR1V90_CRU) += anlogic-dr1v90-cru.o
anlogic-dr1v90-cru-y += cru-dr1v90.o

View File

@ -0,0 +1,192 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (C) 2024-2025 Anlogic, Inc.
* Copyright (C) 2026 Junhui Liu <junhui.liu@pigmoral.tech>
*/
#include <linux/array_size.h>
#include <linux/clk-provider.h>
#include <linux/device.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include "cru_dr1.h"
#include <dt-bindings/clock/anlogic,dr1v90-cru.h>
static const struct clk_div_table cru_div_table_24[] = {
{ 0xFFFFFF, 1 }, { 0x555555, 2 }, { 0x249249, 3 }, { 0x111111, 4 },
{ 0x084210, 5 }, { 0x041041, 6 }, { 0x020408, 7 }, { 0x010101, 8 },
{ 0x008040, 9 }, { 0x004010, 10 }, { 0x002004, 11 }, { 0x001001, 12 },
{ 0x000800, 13 }, { 0x000400, 14 }, { 0x000200, 15 }, { 0x000100, 16 },
{ 0x000080, 17 }, { 0x000040, 18 }, { 0x000020, 19 }, { 0x000010, 20 },
{ 0x000008, 21 }, { 0x000004, 22 }, { 0x000002, 23 }, { 0x000001, 24 },
{ /* sentinel */ }
};
static const struct clk_div_table cru_div_table_32[] = {
{ 0xFFFFFFFF, 1 }, { 0x55555555, 2 }, { 0x24924924, 3 },
{ 0x11111111, 4 }, { 0x08421084, 5 }, { 0x04104104, 6 },
{ 0x02040810, 7 }, { 0x01010101, 8 }, { 0x00804020, 9 },
{ 0x00401004, 10 }, { 0x00200400, 11 }, { 0x00100100, 12 },
{ 0x00080040, 13 }, { 0x00040010, 14 }, { 0x00020004, 15 },
{ 0x00010001, 16 }, { 0x00008000, 17 }, { 0x00004000, 18 },
{ 0x00002000, 19 }, { 0x00001000, 20 }, { 0x00000800, 21 },
{ 0x00000400, 22 }, { 0x00000200, 23 }, { 0x00000100, 24 },
{ 0x00000080, 25 }, { 0x00000040, 26 }, { 0x00000020, 27 },
{ 0x00000010, 28 }, { 0x00000008, 29 }, { 0x00000004, 30 },
{ 0x00000002, 31 }, { 0x00000001, 32 }, { /* sentinel */ }
};
CLK_FIXED_FACTOR_FW_NAME(osc_div2, "osc_div2", "osc", 2, 1, 0);
CRU_PLL_NM_DEFINE(cpu_pll, CRU_PARENT_NAME(osc), 0x120);
CRU_PLL_C_DEFINE(cpu_pll_4x, CRU_PARENT_HW(cpu_pll), 0x14c);
CRU_DIV_DEFINE(cpu_4x_div1, CRU_PARENT_HW(cpu_pll_4x), 0x010, 0, 24,
cru_div_table_24, CLK_DIVIDER_READ_ONLY);
CRU_DIV_DEFINE(cpu_4x_div2, CRU_PARENT_HW(cpu_pll_4x), 0x014, 0, 24,
cru_div_table_24, CLK_DIVIDER_READ_ONLY);
CRU_DIV_DEFINE(cpu_4x_div4, CRU_PARENT_HW(cpu_pll_4x), 0x018, 0, 24,
cru_div_table_24, CLK_DIVIDER_READ_ONLY);
CRU_PLL_NM_DEFINE(io_pll, CRU_PARENT_NAME(osc), 0x220);
CRU_PLL_C_DEFINE(io_1000m, CRU_PARENT_HW(io_pll), 0x248);
CRU_PLL_C_DEFINE(io_400m, CRU_PARENT_HW(io_pll), 0x24c);
CRU_PLL_C_DEFINE(io_25m, CRU_PARENT_HW(io_pll), 0x250);
CRU_PLL_C_DEFINE(io_80m, CRU_PARENT_HW(io_pll), 0x254);
CRU_DIV_DEFINE(io_400m_div2, CRU_PARENT_HW(io_400m), 0x020, 0, 32,
cru_div_table_32, CLK_DIVIDER_READ_ONLY);
CRU_DIV_DEFINE(io_400m_div4, CRU_PARENT_HW(io_400m), 0x024, 0, 32,
cru_div_table_32, CLK_DIVIDER_READ_ONLY);
CRU_DIV_DEFINE(io_400m_div8, CRU_PARENT_HW(io_400m), 0x028, 0, 32,
cru_div_table_32, CLK_DIVIDER_READ_ONLY);
CRU_DIV_DEFINE(io_400m_div16, CRU_PARENT_HW(io_400m), 0x02c, 0, 32,
cru_div_table_32, CLK_DIVIDER_READ_ONLY);
CRU_DIV_GATE_DEFINE(qspi, CRU_PARENT_HW(io_1000m), 0x030, 0, 6, NULL, 0, 2);
CRU_DIV_GATE_DEFINE(spi, CRU_PARENT_HW(io_1000m), 0x030, 8, 6, NULL, 0, 4);
CRU_DIV_GATE_DEFINE(smc, CRU_PARENT_HW(io_1000m), 0x030, 16, 6, NULL, 0, 4);
CRU_DIV_DEFINE(sdio, CRU_PARENT_HW(io_400m), 0x030, 24, 6, NULL, 0);
CRU_DIV_GATE_DEFINE(gpio_db, CRU_PARENT_HW(io_25m), 0x034, 0, 6, NULL, 0, 1);
CRU_DIV_GATE_DEFINE(efuse, CRU_PARENT_HW(io_25m), 0x034, 8, 6, NULL, 0, 1);
CRU_DIV_GATE_DEFINE(tvs, CRU_PARENT_HW(io_25m), 0x034, 16, 6, NULL, 0, 1);
CRU_DIV_GATE_DEFINE(trng, CRU_PARENT_HW(io_25m), 0x034, 24, 7, NULL, 0, 1);
CRU_DIV_GATE_DEFINE(osc_div, CRU_PARENT_NAME(osc), 0x038, 0, 6, NULL, 0, 1);
CRU_DIV_GATE_DEFINE(pwm, CRU_PARENT_NAME(osc), 0x038, 8, 12, NULL, 0, 1);
CRU_DIV_GATE_DEFINE(fclk0, CRU_PARENT_HW(io_400m), 0x03c, 0, 6, NULL, 0, 1);
CRU_DIV_GATE_DEFINE(fclk1, CRU_PARENT_HW(io_400m), 0x03c, 8, 6, NULL, 0, 1);
CRU_DIV_GATE_DEFINE(fclk2, CRU_PARENT_HW(io_400m), 0x03c, 16, 6, NULL, 0, 1);
CRU_DIV_GATE_DEFINE(fclk3, CRU_PARENT_HW(io_400m), 0x03c, 24, 6, NULL, 0, 1);
static const struct clk_parent_data wdt_parents[] = {
CRU_PARENT_HW(osc_div2),
CRU_PARENT_NAME(wdt_ext)
};
CRU_MUX_DEFINE(wdt_sel, wdt_parents, 0x040, 1, 1);
static const struct clk_parent_data efuse_parents[] = {
CRU_PARENT_NAME(osc),
CRU_PARENT_DIV_HW(efuse)
};
CRU_MUX_DEFINE(efuse_sel, efuse_parents, 0x040, 2, 1);
static const struct clk_parent_data can_parents[] = {
CRU_PARENT_HW(io_80m),
CRU_PARENT_NAME(can_ext)
};
CRU_MUX_DEFINE(can_sel, can_parents, 0x040, 3, 1);
static const struct clk_parent_data cpu_parents[] = {
CRU_PARENT_HW(cpu_4x_div1),
CRU_PARENT_HW(cpu_4x_div2)
};
CRU_MUX_DEFINE(cpu_sel, cpu_parents, 0x040, 5, 1);
CRU_GATE_DEFINE(can0, CRU_PARENT_HW(can_sel), 0x08c, 20, CLK_GATE_SET_TO_DISABLE);
CRU_GATE_DEFINE(can1, CRU_PARENT_HW(can_sel), 0x08c, 21, CLK_GATE_SET_TO_DISABLE);
static const struct cru_clk dr1v90_cru_clks[] = {
[CLK_OSC_DIV2] = { &osc_div2.hw, NULL },
[CLK_CPU_PLL] = { &cpu_pll.hw, &cpu_pll.reg },
[CLK_CPU_PLL_4X] = { &cpu_pll_4x.hw, &cpu_pll_4x.reg },
[CLK_CPU_4X] = { &cpu_4x_div1.hw, &cpu_4x_div1.reg },
[CLK_CPU_2X] = { &cpu_4x_div2.hw, &cpu_4x_div2.reg },
[CLK_CPU_1X] = { &cpu_4x_div4.hw, &cpu_4x_div4.reg },
[CLK_IO_PLL] = { &io_pll.hw, &io_pll.reg },
[CLK_IO_1000M] = { &io_1000m.hw, &io_1000m.reg },
[CLK_IO_400M] = { &io_400m.hw, &io_400m.reg },
[CLK_IO_25M] = { &io_25m.hw, &io_25m.reg },
[CLK_IO_80M] = { &io_80m.hw, &io_80m.reg },
[CLK_IO_400M_DIV2] = { &io_400m_div2.hw, &io_400m_div2.reg },
[CLK_IO_400M_DIV4] = { &io_400m_div4.hw, &io_400m_div4.reg },
[CLK_IO_400M_DIV8] = { &io_400m_div8.hw, &io_400m_div8.reg },
[CLK_IO_400M_DIV16] = { &io_400m_div16.hw, &io_400m_div16.reg },
[CLK_QSPI] = { &qspi.divider.hw, &qspi.divider.reg },
[CLK_SPI] = { &spi.divider.hw, &spi.divider.reg },
[CLK_SMC] = { &smc.divider.hw, &smc.divider.reg },
[CLK_SDIO] = { &sdio.hw, &sdio.reg },
[CLK_GPIO_DB] = { &gpio_db.divider.hw, &gpio_db.divider.reg },
[CLK_EFUSE] = { &efuse.divider.hw, &efuse.divider.reg },
[CLK_TVS] = { &tvs.divider.hw, &tvs.divider.reg },
[CLK_TRNG] = { &trng.divider.hw, &trng.divider.reg },
[CLK_OSC_DIV] = { &osc_div.divider.hw, &osc_div.divider.reg },
[CLK_PWM] = { &pwm.divider.hw, &pwm.divider.reg },
[CLK_FCLK0] = { &fclk0.divider.hw, &fclk0.divider.reg },
[CLK_FCLK1] = { &fclk1.divider.hw, &fclk1.divider.reg },
[CLK_FCLK2] = { &fclk2.divider.hw, &fclk2.divider.reg },
[CLK_FCLK3] = { &fclk3.divider.hw, &fclk3.divider.reg },
[CLK_WDT_SEL] = { &wdt_sel.hw, &wdt_sel.reg },
[CLK_EFUSE_SEL] = { &efuse_sel.hw, &efuse_sel.reg },
[CLK_CAN_SEL] = { &can_sel.hw, &can_sel.reg },
[CLK_CPU_SEL] = { &cpu_sel.hw, &cpu_sel.reg },
[CLK_CAN0] = { &can0.hw, &can0.reg },
[CLK_CAN1] = { &can1.hw, &can1.reg }
};
static int dr1v90_cru_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
void __iomem *base;
int ret;
base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(base))
return PTR_ERR(base);
ret = dr1_cru_clk_register(dev, base, dr1v90_cru_clks,
ARRAY_SIZE(dr1v90_cru_clks));
if (ret)
return dev_err_probe(dev, ret, "failed to register clocks\n");
ret = dr1_cru_reset_register(dev, base);
if (ret)
return dev_err_probe(dev, ret, "failed to register resets\n");
return 0;
}
static const struct of_device_id dr1v90_cru_ids[] = {
{ .compatible = "anlogic,dr1v90-cru" },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, dr1v90_cru_ids);
static struct platform_driver dr1v90_cru_driver = {
.driver = {
.name = "dr1v90-cru",
.of_match_table = dr1v90_cru_ids,
},
.probe = dr1v90_cru_probe,
};
module_platform_driver(dr1v90_cru_driver);
MODULE_AUTHOR("Fushan Zeng <fushan.zeng@anlogic.com>");
MODULE_AUTHOR("Junhui Liu <junhui.liu@pigmoral.tech>");
MODULE_DESCRIPTION("Anlogic DR1V90 CRU driver");
MODULE_IMPORT_NS("CLK_ANLOGIC");
MODULE_LICENSE("GPL");

View File

@ -0,0 +1,226 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (C) 2024-2025 Anlogic, Inc.
* Copyright (C) 2026 Junhui Liu <junhui.liu@pigmoral.tech>
*/
#include <linux/auxiliary_bus.h>
#include <linux/bitfield.h>
#include <linux/bits.h>
#include <linux/clk-provider.h>
#include <linux/device.h>
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/types.h>
#include "cru_dr1.h"
static unsigned long cru_pll_nm_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
struct cru_pll *pll = hw_to_cru_pll(hw);
u32 mult, div;
div = FIELD_GET(GENMASK(6, 0), readl(pll->reg)) + 1;
mult = FIELD_GET(GENMASK(6, 0), readl(pll->reg + 4)) + 1;
return parent_rate * mult / div;
}
const struct clk_ops dr1_cru_pll_nm_ops = {
.recalc_rate = cru_pll_nm_recalc_rate,
};
EXPORT_SYMBOL_NS_GPL(dr1_cru_pll_nm_ops, "CLK_ANLOGIC");
static unsigned long cru_pll_c_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
struct cru_pll *pll = hw_to_cru_pll(hw);
u32 div;
div = FIELD_GET(GENMASK(30, 24), readl(pll->reg)) + 1;
return parent_rate / div;
}
const struct clk_ops dr1_cru_pll_c_ops = {
.recalc_rate = cru_pll_c_recalc_rate,
};
EXPORT_SYMBOL_NS_GPL(dr1_cru_pll_c_ops, "CLK_ANLOGIC");
static void cru_div_gate_endisable(struct clk_hw *hw, int enable)
{
struct cru_div_gate *div_gate = hw_to_cru_div_gate(hw);
struct clk_divider *divider = &div_gate->divider;
u32 reg;
reg = readl(divider->reg);
reg &= ~(clk_div_mask(divider->width) << divider->shift);
if (enable)
reg |= div_gate->val << divider->shift;
writel(reg, divider->reg);
}
static int cru_div_gate_enable(struct clk_hw *hw)
{
cru_div_gate_endisable(hw, 1);
return 0;
}
static void cru_div_gate_disable(struct clk_hw *hw)
{
cru_div_gate_endisable(hw, 0);
}
static int cru_div_gate_is_enabled(struct clk_hw *hw)
{
struct cru_div_gate *div_gate = hw_to_cru_div_gate(hw);
struct clk_divider *divider = &div_gate->divider;
u32 val;
val = readl(divider->reg) >> divider->shift;
val &= clk_div_mask(divider->width);
return !!val;
}
static unsigned long cru_div_gate_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
struct cru_div_gate *div_gate = hw_to_cru_div_gate(hw);
struct clk_divider *divider = &div_gate->divider;
unsigned int val;
val = readl(divider->reg) >> divider->shift;
val &= clk_div_mask(divider->width);
if (val < div_gate->min)
return 0;
return divider_recalc_rate(hw, parent_rate, val, divider->table,
divider->flags, divider->width);
}
static int cru_div_gate_determine_rate(struct clk_hw *hw,
struct clk_rate_request *req)
{
struct cru_div_gate *div_gate = hw_to_cru_div_gate(hw);
struct clk_divider *divider = &div_gate->divider;
unsigned long maxdiv, mindiv;
int div = 0;
maxdiv = clk_div_mask(divider->width) + 1;
mindiv = div_gate->min + 1;
div = DIV_ROUND_UP_ULL(req->best_parent_rate, req->rate);
div = div > maxdiv ? maxdiv : div;
div = div < mindiv ? mindiv : div;
req->rate = DIV_ROUND_UP_ULL(req->best_parent_rate, div);
return 0;
}
static int cru_div_gate_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
struct cru_div_gate *div_gate = hw_to_cru_div_gate(hw);
struct clk_divider *divider = &div_gate->divider;
int value;
u32 reg;
if (!__clk_is_enabled(hw->clk))
return 0;
value = divider_get_val(rate, parent_rate, divider->table,
divider->width, divider->flags);
if (value < 0)
return value;
if (value < div_gate->min)
value = div_gate->min;
reg = readl(divider->reg);
reg &= ~(clk_div_mask(divider->width) << divider->shift);
reg |= (u32)value << divider->shift;
writel(reg, divider->reg);
div_gate->val = value;
return 0;
}
static int cru_div_gate_init(struct clk_hw *hw)
{
struct cru_div_gate *div_gate = hw_to_cru_div_gate(hw);
struct clk_divider *divider = &div_gate->divider;
u32 val;
val = readl(divider->reg) >> divider->shift;
val &= clk_div_mask(divider->width);
div_gate->val = val;
return 0;
}
const struct clk_ops dr1_cru_div_gate_ops = {
.enable = cru_div_gate_enable,
.disable = cru_div_gate_disable,
.is_enabled = cru_div_gate_is_enabled,
.recalc_rate = cru_div_gate_recalc_rate,
.determine_rate = cru_div_gate_determine_rate,
.set_rate = cru_div_gate_set_rate,
.init = cru_div_gate_init,
};
EXPORT_SYMBOL_NS_GPL(dr1_cru_div_gate_ops, "CLK_ANLOGIC");
int dr1_cru_clk_register(struct device *dev, void __iomem *base,
const struct cru_clk *clks, int nr_clks)
{
struct clk_hw_onecell_data *priv;
int i, ret;
priv = devm_kzalloc(dev, struct_size(priv, hws, nr_clks), GFP_KERNEL);
if (!priv)
return -ENOMEM;
for (i = 0; i < nr_clks; i++) {
const struct cru_clk *clk = &clks[i];
if (clk->reg)
*(clk->reg) += (uintptr_t)base;
ret = devm_clk_hw_register(dev, clk->hw);
if (ret)
return ret;
priv->hws[i] = clk->hw;
}
priv->num = nr_clks;
ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, priv);
if (ret)
dev_err(dev, "failed to add clock hardware provider\n");
return ret;
}
EXPORT_SYMBOL_NS_GPL(dr1_cru_clk_register, "CLK_ANLOGIC");
int dr1_cru_reset_register(struct device *dev, void __iomem *base)
{
struct auxiliary_device *adev;
adev = devm_auxiliary_device_create(dev, "reset", base);
if (!adev)
return -ENODEV;
return 0;
}
EXPORT_SYMBOL_NS_GPL(dr1_cru_reset_register, "CLK_ANLOGIC");
MODULE_DESCRIPTION("Anlogic DR1 CRU driver");
MODULE_LICENSE("GPL");

View File

@ -0,0 +1,117 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (C) 2024-2025 Anlogic, Inc.
* Copyright (C) 2026 Junhui Liu <junhui.liu@pigmoral.tech>
*/
#ifndef _CRU_DR1_H_
#define _CRU_DR1_H_
#include <linux/clk-provider.h>
struct cru_pll {
struct clk_hw hw;
void __iomem *reg;
};
struct cru_div_gate {
struct clk_divider divider;
u32 val; /* Cached divider value for restoring on enable */
u8 min; /* Minimum divider value to avoid timing issues */
};
struct cru_clk {
struct clk_hw *hw;
void **reg;
};
#define CRU_PARENT_NAME(_name) { .fw_name = #_name }
#define CRU_PARENT_HW(_parent) { .hw = &_parent.hw }
#define CRU_PARENT_DIV_HW(_parent) { .hw = &_parent.divider.hw }
#define CRU_INITHW(_name, _parent, _ops) \
.hw.init = &(struct clk_init_data) { \
.name = #_name, \
.parent_data = (const struct clk_parent_data[]) \
{ _parent }, \
.num_parents = 1, \
.ops = &_ops, \
}
#define CRU_INITHW_PARENTS(_name, _parents, _ops) \
.hw.init = CLK_HW_INIT_PARENTS_DATA(#_name, _parents, &_ops, 0)
#define CRU_PLL_NM_DEFINE(_name, _parent, _reg) \
static struct cru_pll _name = { \
.reg = (void __iomem *)(_reg), \
CRU_INITHW(_name, _parent, dr1_cru_pll_nm_ops), \
}
#define CRU_PLL_C_DEFINE(_name, _parent, _reg) \
static struct cru_pll _name = { \
.reg = (void __iomem *)(_reg), \
CRU_INITHW(_name, _parent, dr1_cru_pll_c_ops), \
}
#define CRU_DIV_DEFINE(_name, _parent, _reg, _shift, _width, _table, \
_flags) \
static struct clk_divider _name = { \
.shift = _shift, \
.width = _width, \
.flags = _flags, \
.table = _table, \
.reg = (void __iomem *)(_reg), \
CRU_INITHW(_name, _parent, clk_divider_ops), \
}
#define CRU_DIV_GATE_DEFINE(_name, _parent, _reg, _shift, _width, \
_table, _flags, _min) \
static struct cru_div_gate _name = { \
.min = _min, \
.divider = { \
.shift = _shift, \
.width = _width, \
.flags = _flags, \
.table = _table, \
.reg = (void __iomem *)(_reg), \
CRU_INITHW(_name, _parent, dr1_cru_div_gate_ops), \
} \
}
#define CRU_MUX_DEFINE(_name, _parents, _reg, _shift, _width) \
static struct clk_mux _name = { \
.shift = _shift, \
.mask = GENMASK(_width - 1, 0), \
.reg = (void __iomem *)(_reg), \
CRU_INITHW_PARENTS(_name, _parents, clk_mux_ops) \
}
#define CRU_GATE_DEFINE(_name, _parent, _reg, _bit_idx, _flags) \
static struct clk_gate _name = { \
.bit_idx = _bit_idx, \
.flags = _flags, \
.reg = (void __iomem *)(_reg), \
CRU_INITHW(_name, _parent, clk_gate_ops) \
}
static inline struct cru_pll *hw_to_cru_pll(struct clk_hw *hw)
{
return container_of(hw, struct cru_pll, hw);
}
static inline struct cru_div_gate *hw_to_cru_div_gate(struct clk_hw *hw)
{
struct clk_divider *divider = to_clk_divider(hw);
return container_of(divider, struct cru_div_gate, divider);
}
extern const struct clk_ops dr1_cru_pll_nm_ops;
extern const struct clk_ops dr1_cru_pll_c_ops;
extern const struct clk_ops dr1_cru_div_gate_ops;
int dr1_cru_clk_register(struct device *dev, void __iomem *base,
const struct cru_clk *clks, int nr_clks);
int dr1_cru_reset_register(struct device *dev, void __iomem *base);
#endif /* _CRU_DR1_H_ */

View File

@ -15,6 +15,7 @@ config COMMON_CLK_ASPEED
config COMMON_CLK_AST2700
bool "Clock driver for AST2700 SoC"
depends on ARCH_ASPEED || COMPILE_TEST
select AUXILIARY_BUS
help
This driver provides support for clock on AST2700 SoC.
The driver is responsible for managing the various clocks required

View File

@ -349,8 +349,8 @@ static struct clk_hw *aspeed_clk_hw_register_gate(struct device *dev,
struct regmap *map, u8 clock_idx, u8 reset_idx,
u8 clk_gate_flags, spinlock_t *lock)
{
struct clk_init_data init = {};
struct aspeed_clk_gate *gate;
struct clk_init_data init;
struct clk_hw *hw;
int ret;

View File

@ -425,8 +425,8 @@ static struct clk_hw *aspeed_g6_clk_hw_register_gate(struct device *dev,
struct regmap *map, u8 clock_idx, u8 reset_idx,
u8 clk_gate_flags, spinlock_t *lock)
{
struct clk_init_data init = {};
struct aspeed_clk_gate *gate;
struct clk_init_data init;
struct clk_hw *hw;
int ret;

View File

@ -824,7 +824,7 @@ static struct clk_hw *ast2700_clk_hw_register_gate(struct device *dev, const cha
void __iomem *reg, u8 clock_idx,
unsigned long flags, spinlock_t *lock)
{
struct clk_init_data init;
struct clk_init_data init = {};
struct clk_gate *gate;
struct clk_hw *hw;
int ret = -EINVAL;

View File

@ -486,8 +486,8 @@ struct clk_hw * __init
at91_clk_register_audio_pll_pad(struct regmap *regmap, const char *name,
const char *parent_name)
{
struct clk_init_data init = {};
struct clk_audio_pad *apad_ck;
struct clk_init_data init;
int ret;
apad_ck = kzalloc_obj(*apad_ck);
@ -517,8 +517,8 @@ struct clk_hw * __init
at91_clk_register_audio_pll_pmc(struct regmap *regmap, const char *name,
const char *parent_name)
{
struct clk_init_data init = {};
struct clk_audio_pmc *apmc_ck;
struct clk_init_data init;
int ret;
apmc_ck = kzalloc_obj(*apmc_ck);

View File

@ -97,7 +97,7 @@ at91_clk_register_h32mx(struct regmap *regmap, const char *name,
const char *parent_name)
{
struct clk_sama5d4_h32mx *h32mxclk;
struct clk_init_data init;
struct clk_init_data init = {};
int ret;
h32mxclk = kzalloc_obj(*h32mxclk);

View File

@ -170,7 +170,7 @@ at91_clk_register_main_osc(struct regmap *regmap,
init.name = name;
init.ops = &main_osc_ops;
if (parent_data)
init.parent_data = (const struct clk_parent_data *)parent_data;
init.parent_data = parent_data;
else
init.parent_names = &parent_name;
init.num_parents = 1;
@ -298,8 +298,8 @@ at91_clk_register_main_rc_osc(struct regmap *regmap,
const char *name,
u32 frequency, u32 accuracy)
{
struct clk_init_data init = {};
struct clk_main_rc_osc *osc;
struct clk_init_data init;
struct clk_hw *hw;
int ret;

View File

@ -318,7 +318,7 @@ at91_clk_register_pll(struct regmap *regmap, const char *name,
{
struct clk_pll *pll;
struct clk_hw *hw;
struct clk_init_data init;
struct clk_init_data init = {};
int offset = PLL_REG(id);
unsigned int pllr;
int ret;

View File

@ -86,9 +86,9 @@ struct clk_hw * __init
at91_clk_register_plldiv(struct regmap *regmap, const char *name,
const char *parent_name)
{
struct clk_init_data init = {};
struct clk_plldiv *plldiv;
struct clk_hw *hw;
struct clk_init_data init;
int ret;
plldiv = kzalloc_obj(*plldiv);

View File

@ -42,8 +42,8 @@ at91_clk_register_sam9260_slow(struct regmap *regmap,
int num_parents)
{
struct clk_sam9260_slow *slowck;
struct clk_init_data init = {};
struct clk_hw *hw;
struct clk_init_data init;
int ret;
if (!name)

View File

@ -113,9 +113,9 @@ struct clk_hw * __init
at91sam9x5_clk_register_smd(struct regmap *regmap, const char *name,
const char **parent_names, u8 num_parents)
{
struct clk_init_data init = {};
struct at91sam9x5_clk_smd *smd;
struct clk_hw *hw;
struct clk_init_data init;
int ret;
smd = kzalloc_obj(*smd);

View File

@ -224,9 +224,9 @@ _at91sam9x5_clk_register_usb(struct regmap *regmap, const char *name,
const char **parent_names, u8 num_parents,
u32 usbs_mask)
{
struct clk_init_data init = {};
struct at91sam9x5_clk_usb *usb;
struct clk_hw *hw;
struct clk_init_data init;
int ret;
usb = kzalloc_obj(*usb);
@ -275,9 +275,9 @@ struct clk_hw * __init
at91sam9n12_clk_register_usb(struct regmap *regmap, const char *name,
const char *parent_name)
{
struct clk_init_data init = {};
struct at91sam9x5_clk_usb *usb;
struct clk_hw *hw;
struct clk_init_data init;
int ret;
usb = kzalloc_obj(*usb);
@ -394,9 +394,9 @@ struct clk_hw * __init
at91rm9200_clk_register_usb(struct regmap *regmap, const char *name,
const char *parent_name, const u32 *divisors)
{
struct clk_init_data init = {};
struct at91rm9200_clk_usb *usb;
struct clk_hw *hw;
struct clk_init_data init;
int ret;
usb = kzalloc_obj(*usb);

View File

@ -231,9 +231,9 @@ at91_clk_register_slow_rc_osc(void __iomem *sckcr,
unsigned long startup,
const struct clk_slow_bits *bits)
{
struct clk_init_data init = {};
struct clk_slow_rc_osc *osc;
struct clk_hw *hw;
struct clk_init_data init;
int ret;
if (!sckcr || !name)

View File

@ -235,7 +235,7 @@ void __init iproc_armpll_setup(struct device_node *node)
{
int ret;
struct iproc_arm_pll *pll;
struct clk_init_data init;
struct clk_init_data init = {};
const char *parent_name;
pll = kzalloc_obj(*pll);

View File

@ -206,7 +206,7 @@ void __init iproc_asiu_setup(struct device_node *node,
goto err_iomap_gate;
for (i = 0; i < num_clks; i++) {
struct clk_init_data init;
struct clk_init_data init = {};
const char *parent_name;
struct iproc_asiu_clk *asiu_clk;
const char *clk_name;

View File

@ -722,7 +722,7 @@ void iproc_pll_clk_setup(struct device_node *node,
int i, ret;
struct iproc_pll *pll;
struct iproc_clk *iclk;
struct clk_init_data init;
struct clk_init_data init = {};
const char *parent_name;
struct iproc_clk *iclk_array;
struct clk_hw_onecell_data *clk_data;

View File

@ -553,6 +553,8 @@ static int raspberrypi_clk_probe(struct platform_device *pdev)
rpi->cpufreq = platform_device_register_data(dev, "raspberrypi-cpufreq",
-1, NULL, 0);
if (IS_ERR(rpi->cpufreq))
return PTR_ERR(rpi->cpufreq);
return 0;
}

View File

@ -181,8 +181,8 @@ int __init berlin2_avpll_vco_register(void __iomem *base,
const char *name, const char *parent_name,
u8 vco_flags, unsigned long flags)
{
struct clk_init_data init = {};
struct berlin2_avpll_vco *vco;
struct clk_init_data init;
vco = kzalloc_obj(*vco);
if (!vco)
@ -358,7 +358,7 @@ int __init berlin2_avpll_channel_register(void __iomem *base,
u8 ch_flags, unsigned long flags)
{
struct berlin2_avpll_channel *ch;
struct clk_init_data init;
struct clk_init_data init = {};
ch = kzalloc_obj(*ch);
if (!ch)

View File

@ -78,7 +78,7 @@ berlin2_pll_register(const struct berlin2_pll_map *map,
void __iomem *base, const char *name,
const char *parent_name, unsigned long flags)
{
struct clk_init_data init;
struct clk_init_data init = {};
struct berlin2_pll *pll;
pll = kzalloc_obj(*pll);

View File

@ -568,7 +568,7 @@ static int axi_clkgen_probe(struct platform_device *pdev)
const struct axi_clkgen_limits *dflt_limits;
struct axi_clkgen *axi_clkgen;
unsigned int pcore_version;
struct clk_init_data init;
struct clk_init_data init = {};
const char *parent_names[2];
const char *clk_name;
struct clk *axi_clk;

View File

@ -620,12 +620,17 @@ static int cdce925_probe(struct i2c_client *client)
struct device_node *node = client->dev.of_node;
const char *parent_name;
const char *pll_clk_name[MAX_NUMBER_OF_PLLS] = {NULL,};
struct clk_init_data init;
struct clk_init_data init = {};
u32 value;
int i;
int err;
struct device_node *np_output;
char child_name[6];
/*
* The PLL number isn't a compile time constant so GCC can't infer
* the number. Make the stack buffer large enough to hold any int
* so Wformat-truncation does not complain.
*/
char child_name[15];
struct regmap_config config = {
.name = "configuration0",
.reg_bits = 8,
@ -697,7 +702,7 @@ static int cdce925_probe(struct i2c_client *client)
dev_err(&client->dev, "Failed register PLL %d\n", i);
goto error;
}
sprintf(child_name, "PLL%d", i+1);
snprintf(child_name, sizeof(child_name), "PLL%d", i + 1);
np_output = of_get_child_by_name(node, child_name);
if (!np_output)
continue;

View File

@ -25,8 +25,8 @@ static int __set_clk_parents(struct device_node *node, bool clk_supplier)
node);
for (index = 0; index < num_parents; index++) {
rc = of_parse_phandle_with_args(node, "assigned-clock-parents",
"#clock-cells", index, &clkspec);
rc = of_parse_phandle_with_args_map(node, "assigned-clock-parents",
"clock", index, &clkspec);
if (rc < 0) {
/* skip empty (null) phandles */
if (rc == -ENOENT)
@ -47,8 +47,8 @@ static int __set_clk_parents(struct device_node *node, bool clk_supplier)
return PTR_ERR(pclk);
}
rc = of_parse_phandle_with_args(node, "assigned-clocks",
"#clock-cells", index, &clkspec);
rc = of_parse_phandle_with_args_map(node, "assigned-clocks",
"clock", index, &clkspec);
if (rc < 0)
goto err;
if (clkspec.np == node && !clk_supplier) {
@ -121,8 +121,8 @@ static int __set_clk_rates(struct device_node *node, bool clk_supplier)
rate = rates[index];
if (rate) {
rc = of_parse_phandle_with_args(node, "assigned-clocks",
"#clock-cells", index, &clkspec);
rc = of_parse_phandle_with_args_map(node, "assigned-clocks",
"clock", index, &clkspec);
if (rc < 0) {
/* skip empty (null) phandles */
if (rc == -ENOENT)

View File

@ -461,7 +461,7 @@ static int cs2000_clk_register(struct cs2000_priv *priv)
{
struct device *dev = priv_to_dev(priv);
struct device_node *np = dev->of_node;
struct clk_init_data init;
struct clk_init_data init = {};
const char *name = np->name;
static const char *parent_names[CLK_MAX];
u32 aux_out = 0;

View File

@ -6,14 +6,18 @@
#include <linux/io.h>
#include <linux/mfd/syscon.h>
#include <linux/platform_device.h>
#include <linux/phy.h>
#include <linux/phy/phy.h>
#include <linux/property.h>
#include <linux/regmap.h>
#include <linux/reset-controller.h>
#include <linux/spinlock.h>
#include <dt-bindings/clock/en7523-clk.h>
#include <dt-bindings/reset/airoha,en7523-reset.h>
#include <dt-bindings/reset/airoha,en7581-reset.h>
#include <dt-bindings/clock/econet,en751221-scu.h>
#include <dt-bindings/reset/econet,en751221-scu.h>
#include <dt-bindings/soc/airoha,scu-ssr.h>
#define RST_NR_PER_BANK 32
@ -40,9 +44,22 @@
#define REG_HIR_MASK GENMASK(31, 16)
/* EN7581 */
#define REG_NP_SCU_PCIC 0x88
#define REG_NP_SCU_SSR3 0x94
#define REG_SSUSB_HSGMII_SEL_MASK BIT(29)
#define REG_SSUSB_HSGMII_SEL_HSGMII FIELD_PREP_CONST(REG_SSUSB_HSGMII_SEL_MASK, 0x0)
#define REG_SSUSB_HSGMII_SEL_USB FIELD_PREP_CONST(REG_SSUSB_HSGMII_SEL_MASK, 0x1)
#define REG_NP_SCU_SSTR 0x9c
#define REG_PCIE_XSI0_SEL_MASK GENMASK(14, 13)
#define REG_PCIE_XSI0_SEL_PCIE FIELD_PREP_CONST(REG_PCIE_XSI0_SEL_MASK, 0x0)
#define REG_PCIE_XSI0_SEL_XFI FIELD_PREP_CONST(REG_PCIE_XSI0_SEL_MASK, 0x1)
#define REG_PCIE_XSI0_SEL_HSGMII FIELD_PREP_CONST(REG_PCIE_XSI0_SEL_MASK, 0x2)
#define REG_PCIE_XSI1_SEL_MASK GENMASK(12, 11)
#define REG_PCIE_XSI1_SEL_PCIE FIELD_PREP_CONST(REG_PCIE_XSI1_SEL_MASK, 0x0)
#define REG_PCIE_XSI1_SEL_XFI FIELD_PREP_CONST(REG_PCIE_XSI1_SEL_MASK, 0x1)
#define REG_PCIE_XSI1_SEL_HSGMII FIELD_PREP_CONST(REG_PCIE_XSI1_SEL_MASK, 0x2)
#define REG_USB_PCIE_SEL_MASK BIT(3)
#define REG_USB_PCIE_SEL_PCIE FIELD_PREP_CONST(REG_USB_PCIE_SEL_MASK, 0x0)
#define REG_USB_PCIE_SEL_USB FIELD_PREP_CONST(REG_USB_PCIE_SEL_MASK, 0x1)
#define REG_CRYPTO_CLKSRC2 0x20c
/* EN751221 */
#define EN751221_REG_SPI_DIV 0x0cc
@ -82,6 +99,8 @@ enum en_hir {
HIR_MAX = 14,
};
#define EN_SERDES_PHY_NUM 4
struct en_clk_desc {
int id;
const char *name;
@ -114,6 +133,18 @@ struct en_rst_data {
struct reset_controller_dev rcdev;
};
struct en_serdes_phy_instance {
struct phy *phy;
unsigned int serdes_port;
};
struct en_clk_priv {
void __iomem *base;
/* protect SCU register */
spinlock_t lock;
struct en_serdes_phy_instance *serdes_phys[EN_SERDES_PHY_NUM];
};
struct en_clk_soc_data {
u32 num_clocks;
const struct clk_ops pcie_ops;
@ -847,12 +878,179 @@ static int en7581_reset_register(struct device *dev, void __iomem *base,
return devm_reset_controller_register(dev, &rst_data->rcdev);
}
static int en7581_serdes_phy_set_mode(struct phy *phy, enum phy_mode mode,
int submode)
{
struct en_serdes_phy_instance *instance = phy_get_drvdata(phy);
struct en_clk_priv *priv = dev_get_drvdata(phy->dev.parent);
u32 reg, mask, sel, val;
unsigned long flags;
switch (instance->serdes_port) {
case AIROHA_SCU_SERDES_PCIE1:
reg = REG_NP_SCU_SSTR;
mask = REG_PCIE_XSI0_SEL_MASK;
if (mode != PHY_MODE_ETHERNET && mode != PHY_MODE_PCIE)
return -EINVAL;
if (mode == PHY_MODE_ETHERNET) {
switch (submode) {
case PHY_INTERFACE_MODE_USXGMII:
case PHY_INTERFACE_MODE_10GBASER:
sel = REG_PCIE_XSI0_SEL_XFI;
break;
case PHY_INTERFACE_MODE_SGMII:
case PHY_INTERFACE_MODE_1000BASEX:
case PHY_INTERFACE_MODE_2500BASEX:
sel = REG_PCIE_XSI0_SEL_HSGMII;
break;
default:
return -EINVAL;
}
} else {
sel = REG_PCIE_XSI0_SEL_PCIE;
}
break;
case AIROHA_SCU_SERDES_PCIE2:
reg = REG_NP_SCU_SSTR;
mask = REG_PCIE_XSI1_SEL_MASK;
if (mode != PHY_MODE_ETHERNET && mode != PHY_MODE_PCIE)
return -EINVAL;
if (mode == PHY_MODE_ETHERNET) {
switch (submode) {
case PHY_INTERFACE_MODE_USXGMII:
case PHY_INTERFACE_MODE_10GBASER:
sel = REG_PCIE_XSI1_SEL_XFI;
break;
case PHY_INTERFACE_MODE_SGMII:
case PHY_INTERFACE_MODE_1000BASEX:
case PHY_INTERFACE_MODE_2500BASEX:
sel = REG_PCIE_XSI1_SEL_HSGMII;
break;
default:
return -EINVAL;
}
} else {
sel = REG_PCIE_XSI1_SEL_PCIE;
}
break;
case AIROHA_SCU_SERDES_USB1:
reg = REG_NP_SCU_SSR3;
mask = REG_SSUSB_HSGMII_SEL_MASK;
if (mode != PHY_MODE_ETHERNET && mode != PHY_MODE_USB_DEVICE &&
mode != PHY_MODE_USB_DEVICE_SS)
return -EINVAL;
if (mode == PHY_MODE_ETHERNET)
sel = REG_SSUSB_HSGMII_SEL_HSGMII;
else
sel = REG_SSUSB_HSGMII_SEL_USB;
break;
case AIROHA_SCU_SERDES_USB2:
reg = REG_NP_SCU_SSTR;
mask = REG_USB_PCIE_SEL_MASK;
if (mode != PHY_MODE_PCIE && mode != PHY_MODE_USB_DEVICE &&
mode != PHY_MODE_USB_DEVICE_SS)
return -EINVAL;
if (mode == PHY_MODE_PCIE)
sel = REG_USB_PCIE_SEL_PCIE;
else
sel = REG_USB_PCIE_SEL_USB;
break;
default:
return -EINVAL;
}
spin_lock_irqsave(&priv->lock, flags);
val = readl(priv->base + reg);
val &= ~mask;
val |= sel;
writel(val, priv->base + reg);
spin_unlock_irqrestore(&priv->lock, flags);
return 0;
}
static const struct phy_ops en7581_serdes_phy_ops = {
.set_mode = en7581_serdes_phy_set_mode,
.owner = THIS_MODULE,
};
static struct phy *en7581_serdes_phy_xlate(struct device *dev,
const struct of_phandle_args *args)
{
struct en_clk_priv *priv = dev_get_drvdata(dev);
struct en_serdes_phy_instance *instance;
unsigned int serdes_port;
if (args->args_count != 1) {
dev_err(dev, "invalid number of cells in 'phy' property\n");
return ERR_PTR(-EINVAL);
}
serdes_port = args->args[0];
if (serdes_port >= EN_SERDES_PHY_NUM) {
dev_err(dev, "invalid serdes port: %d\n", serdes_port);
return ERR_PTR(-EINVAL);
}
instance = priv->serdes_phys[serdes_port];
if (!instance) {
dev_err(dev, "failed to find appropriate serdes phy\n");
return ERR_PTR(-EINVAL);
}
return instance->phy;
}
static int en7581_serdes_phy_register(struct device *dev)
{
struct en_clk_priv *priv = dev_get_drvdata(dev);
struct phy_provider *phy_provider;
int i;
for (i = 0; i < EN_SERDES_PHY_NUM; i++) {
struct en_serdes_phy_instance *instance;
instance = devm_kzalloc(dev, sizeof(*instance),
GFP_KERNEL);
if (!instance)
return -ENOMEM;
instance->phy = devm_phy_create(dev, NULL,
&en7581_serdes_phy_ops);
if (IS_ERR(instance->phy))
return dev_err_probe(dev, PTR_ERR(instance->phy), "failed to create phy\n");
instance->serdes_port = i;
priv->serdes_phys[i] = instance;
phy_set_drvdata(instance->phy, instance);
}
phy_provider = devm_of_phy_provider_register(dev, en7581_serdes_phy_xlate);
return PTR_ERR_OR_ZERO(phy_provider);
}
static int en7581_clk_hw_init(struct platform_device *pdev,
struct clk_hw_onecell_data *clk_data)
{
struct en_clk_priv *priv = platform_get_drvdata(pdev);
struct regmap *map;
void __iomem *base;
u32 val;
int ret;
map = syscon_regmap_lookup_by_compatible("airoha,en7581-chip-scu");
if (IS_ERR(map))
@ -862,6 +1060,8 @@ static int en7581_clk_hw_init(struct platform_device *pdev,
if (IS_ERR(base))
return PTR_ERR(base);
priv->base = base;
en7581_register_clocks(&pdev->dev, clk_data, map, base);
val = readl(base + REG_NP_SCU_SSTR);
@ -876,9 +1076,12 @@ static int en7581_clk_hw_init(struct platform_device *pdev,
val &= ~REG_PCIE_HB_RST;
writel(val, base + REG_RST_CTRL1);
return en7581_reset_register(&pdev->dev, base, en7581_rst_map,
ARRAY_SIZE(en7581_rst_map),
en7581_rst_ofs);
ret = en7581_reset_register(&pdev->dev, base, en7581_rst_map,
ARRAY_SIZE(en7581_rst_map), en7581_rst_ofs);
if (ret)
return ret;
return en7581_serdes_phy_register(&pdev->dev);
}
static enum en_hir get_hw_id(void __iomem *np_base)
@ -985,16 +1188,25 @@ static int en7523_clk_probe(struct platform_device *pdev)
struct device_node *node = pdev->dev.of_node;
const struct en_clk_soc_data *soc_data;
struct clk_hw_onecell_data *clk_data;
struct en_clk_priv *priv;
int r;
soc_data = device_get_match_data(&pdev->dev);
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
spin_lock_init(&priv->lock);
clk_data = devm_kzalloc(&pdev->dev,
struct_size(clk_data, hws, soc_data->num_clocks),
GFP_KERNEL);
if (!clk_data)
return -ENOMEM;
platform_set_drvdata(pdev, priv);
clk_data->num = soc_data->num_clocks;
r = soc_data->hw_init(pdev, clk_data);
if (r)

View File

@ -513,21 +513,16 @@ static int eqc_probe(struct platform_device *pdev)
const struct eqc_match_data *data;
struct clk_hw_onecell_data *cells;
unsigned int i, clk_count;
struct resource *res;
void __iomem *base;
int ret;
base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(base))
return PTR_ERR(base);
data = device_get_match_data(dev);
if (!data)
return 0; /* No clocks nor auxdevs, we are done. */
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res)
return -ENODEV;
base = ioremap(res->start, resource_size(res));
if (!base)
return -ENOMEM;
return 0; /* No clocks nor auxdevs, stop here but keep resource reserved */
/* Init optional auxiliary devices. */
eqc_auxdev_create_optional(dev, base, data->reset_auxdev_name);
@ -559,7 +554,20 @@ static int eqc_probe(struct platform_device *pdev)
dev_warn(dev, "failed probing clock %s: %d\n", clk->name, ret);
}
return of_clk_add_hw_provider(np, of_clk_hw_onecell_get, cells);
ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, cells);
if (ret) {
for (i = 0; i < data->clk_count; i++) {
const struct eqc_clock *clk = &data->clks[i];
struct clk_hw *hw = cells->hws[clk->index];
if (!IS_ERR_OR_NULL(hw) && clk->unregister)
clk->unregister(hw);
}
kfree(cells);
}
return ret;
}
#define DIV(_index, _parent_idx, _name, _parent_name, \
@ -1175,6 +1183,7 @@ static const struct of_device_id eqc_match_table[] = {
{ .compatible = "mobileye,eyeq5-olb", .data = &eqc_eyeq5_match_data },
{ .compatible = "mobileye,eyeq6l-olb", .data = &eqc_eyeq6l_match_data },
{ .compatible = "mobileye,eyeq6lplus-olb", .data = &eqc_eyeq6lplus_match_data },
{ .compatible = "mobileye,eyeq6h-central-olb" /* no data, early only */ },
{ .compatible = "mobileye,eyeq6h-west-olb", .data = &eqc_eyeq6h_west_match_data },
{ .compatible = "mobileye,eyeq6h-east-olb", .data = &eqc_eyeq6h_east_match_data },
{ .compatible = "mobileye,eyeq6h-south-olb", .data = &eqc_eyeq6h_south_match_data },

View File

@ -271,7 +271,7 @@ struct clk_hw *clk_hw_register_fractional_divider(struct device *dev,
u8 clk_divider_flags, spinlock_t *lock)
{
struct clk_fractional_divider *fd;
struct clk_init_data init;
struct clk_init_data init = {};
struct clk_hw *hw;
int ret;

View File

@ -193,8 +193,8 @@ static struct clk_hw *gemini_pci_clk_setup(const char *name,
const char *parent_name,
struct regmap *map)
{
struct clk_init_data init = {};
struct clk_gemini_pci *pciclk;
struct clk_init_data init;
int ret;
pciclk = kzalloc_obj(*pciclk);

View File

@ -214,7 +214,7 @@ static int gpio_clk_driver_probe(struct platform_device *pdev)
gpiod = devm_gpiod_get(dev, gpio_name, GPIOD_OUT_LOW);
if (IS_ERR(gpiod))
return dev_err_probe(dev, PTR_ERR(gpiod),
"Can't get '%s' named GPIO property\n", gpio_name);
"Can't get '%s' GPIO\n", gpio_name);
if (is_mux)
hw = clk_hw_register_gpio_mux(dev, gpiod);

View File

@ -269,7 +269,7 @@ static void __init hb_clk_init(struct device_node *node, const struct clk_ops *o
struct hb_clk *hb_clk;
const char *clk_name = node->name;
const char *parent_name;
struct clk_init_data init;
struct clk_init_data init = {};
struct device_node *srnp;
int rc;

View File

@ -587,8 +587,8 @@ static const struct clk_ops lmk04832_vco_ops = {
*/
static int lmk04832_register_vco(struct lmk04832 *lmk)
{
struct clk_init_data init = {};
const char *parent_names[1];
struct clk_init_data init;
int ret;
init.name = "lmk-vco";
@ -947,8 +947,8 @@ static const struct clk_ops lmk04832_sclk_ops = {
static int lmk04832_register_sclk(struct lmk04832 *lmk)
{
struct clk_init_data init = {};
const char *parent_names[1];
struct clk_init_data init;
int ret;
init.name = "lmk-sclk";
@ -1292,8 +1292,8 @@ static int lmk04832_register_clkout(struct lmk04832 *lmk, const int num)
{
char name[] = "lmk-clkoutXX";
char dclk_name[] = "lmk-dclkXX_YY";
struct clk_init_data init = {};
const char *parent_names[2];
struct clk_init_data init;
int dclk_num = num / 2;
int ret;
@ -1410,6 +1410,9 @@ static int lmk04832_probe(struct spi_device *spi)
lmk->reset_gpio = devm_gpiod_get_optional(&spi->dev, "reset",
GPIOD_OUT_LOW);
if (IS_ERR(lmk->reset_gpio))
return dev_err_probe(lmk->dev, PTR_ERR(lmk->reset_gpio),
"failed to get reset GPIO\n");
lmk->dclk = devm_kcalloc(lmk->dev, info->num_channels >> 1,
sizeof(struct lmk_dclk), GFP_KERNEL);

View File

@ -328,9 +328,9 @@ static struct clk_hw *m10v_clk_hw_register_mux(struct device *dev,
u8 shift, u32 mask, u8 clk_mux_flags, u32 *table,
spinlock_t *lock)
{
struct clk_init_data init = {};
struct clk_mux *mux;
struct clk_hw *hw;
struct clk_init_data init;
int ret;
mux = kzalloc_obj(*mux);
@ -410,8 +410,8 @@ static int m10v_clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
struct m10v_clk_divider *divider = to_m10v_div(hw);
int value;
unsigned long flags = 0;
int value, ret = 0;
u32 val;
u32 write_en = BIT(divider->width - 1);
@ -433,8 +433,10 @@ static int m10v_clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,
if (divider->write_valid_reg) {
writel(M10V_DCHREQ, divider->write_valid_reg);
if (readl_poll_timeout(divider->write_valid_reg, val,
!val, M10V_UPOLL_RATE, M10V_UTIMEOUT))
ret = readl_poll_timeout_atomic(divider->write_valid_reg, val,
!val, M10V_UPOLL_RATE,
M10V_UTIMEOUT);
if (ret)
pr_err("%s:%s couldn't stabilize\n",
__func__, clk_hw_get_name(hw));
}
@ -444,7 +446,7 @@ static int m10v_clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,
else
__release(divider->lock);
return 0;
return ret;
}
static const struct clk_ops m10v_clk_divider_ops = {
@ -459,9 +461,9 @@ static struct clk_hw *m10v_clk_hw_register_divider(struct device *dev,
u8 clk_divider_flags, const struct clk_div_table *table,
spinlock_t *lock, void __iomem *write_valid_reg)
{
struct clk_init_data init = {};
struct m10v_clk_divider *div;
struct clk_hw *hw;
struct clk_init_data init;
int ret;
div = kzalloc_obj(*div);

View File

@ -263,7 +263,7 @@ pll_clk_register(struct device *dev, const char *name,
{
int ret;
struct clk_pll *pll;
struct clk_init_data init;
struct clk_init_data init = {};
if (id != 1 && id != 2) {
pr_err("%s: the Nomadik has only PLL 1 & 2\n", __func__);
@ -355,7 +355,7 @@ src_clk_register(struct device *dev, const char *name,
{
int ret;
struct clk_src *sclk;
struct clk_init_data init;
struct clk_init_data init = {};
sclk = kzalloc_obj(*sclk);
if (!sclk)

View File

@ -69,8 +69,8 @@ static struct clk_hw *
npcm7xx_clk_register_pll(void __iomem *pllcon, const char *name,
const char *parent_name, unsigned long flags)
{
struct clk_init_data init = {};
struct npcm7xx_clk_pll *pll;
struct clk_init_data init;
struct clk_hw *hw;
int ret;

View File

@ -95,7 +95,7 @@ static const struct clk_ops clk_pwm_ops = {
static int clk_pwm_probe(struct platform_device *pdev)
{
struct device_node *node = pdev->dev.of_node;
struct clk_init_data init;
struct clk_init_data init = {};
struct clk_pwm *clk_pwm;
struct pwm_device *pwm;
struct pwm_args pargs;

View File

@ -63,10 +63,11 @@ struct rs9_driver_data {
struct i2c_client *client;
struct regmap *regmap;
const struct rs9_chip_info *chip_info;
struct clk_hw *clk_dif[8];
u8 pll_amplitude;
u8 pll_ssc;
u8 clk_dif_sr;
/* must be last */
struct clk_hw_onecell_data onecell;
};
/*
@ -270,32 +271,28 @@ static void rs9_update_config(struct rs9_driver_data *rs9)
}
}
static struct clk_hw *
rs9_of_clk_get(struct of_phandle_args *clkspec, void *data)
{
struct rs9_driver_data *rs9 = data;
unsigned int idx = clkspec->args[0];
return rs9->clk_dif[idx];
}
static int rs9_probe(struct i2c_client *client)
{
const struct rs9_chip_info *chip_info;
unsigned char name[5] = "DIF0";
struct rs9_driver_data *rs9;
unsigned int vid, did;
struct clk_hw *hw;
int i, ret;
rs9 = devm_kzalloc(&client->dev, sizeof(*rs9), GFP_KERNEL);
chip_info = i2c_get_match_data(client);
if (!chip_info)
return -EINVAL;
rs9 = devm_kzalloc(&client->dev, struct_size(rs9, onecell.hws,
chip_info->num_clks), GFP_KERNEL);
if (!rs9)
return -ENOMEM;
i2c_set_clientdata(client, rs9);
rs9->client = client;
rs9->chip_info = i2c_get_match_data(client);
if (!rs9->chip_info)
return -EINVAL;
rs9->chip_info = chip_info;
rs9->onecell.num = chip_info->num_clks;
/* Fetch common configuration from DT (if specified) */
ret = rs9_get_common_config(rs9);
@ -303,7 +300,7 @@ static int rs9_probe(struct i2c_client *client)
return ret;
/* Fetch DIFx output configuration from DT (if specified) */
for (i = 0; i < rs9->chip_info->num_clks; i++) {
for (i = 0; i < rs9->onecell.num; i++) {
ret = rs9_get_output_config(rs9, i);
if (ret)
return ret;
@ -329,24 +326,24 @@ static int rs9_probe(struct i2c_client *client)
return ret;
vid &= RS9_REG_VID_MASK;
if (vid != RS9_REG_VID_IDT || did != rs9->chip_info->did)
if (vid != RS9_REG_VID_IDT || did != chip_info->did)
return dev_err_probe(&client->dev, -ENODEV,
"Incorrect VID/DID: %#02x, %#02x. Expected %#02x, %#02x\n",
vid, did, RS9_REG_VID_IDT,
rs9->chip_info->did);
vid, did, RS9_REG_VID_IDT, chip_info->did);
/* Register clock */
for (i = 0; i < rs9->chip_info->num_clks; i++) {
for (i = 0; i < rs9->onecell.num; i++) {
snprintf(name, 5, "DIF%d", i);
hw = devm_clk_hw_register_fixed_factor_index(&client->dev, name,
0, 0, 4, 1);
if (IS_ERR(hw))
return PTR_ERR(hw);
rs9->clk_dif[i] = hw;
rs9->onecell.hws[i] = hw;
}
ret = devm_of_clk_add_hw_provider(&client->dev, rs9_of_clk_get, rs9);
ret = devm_of_clk_add_hw_provider(&client->dev, of_clk_hw_onecell_get,
&rs9->onecell);
if (!ret)
rs9_update_config(rs9);
@ -370,8 +367,10 @@ static int rs9_resume(struct device *dev)
regcache_cache_only(rs9->regmap, false);
ret = regcache_sync(rs9->regmap);
if (ret)
if (ret) {
regcache_cache_only(rs9->regmap, true);
dev_err(dev, "Failed to restore register map: %d\n", ret);
}
return ret;
}

View File

@ -192,8 +192,10 @@ static int s2mps11_clk_probe(struct platform_device *pdev)
clk_data->hws[i] = &s2mps11_clks[i].hw;
}
of_clk_add_hw_provider(s2mps11_clks->clk_np, of_clk_hw_onecell_get,
clk_data);
ret = of_clk_add_hw_provider(s2mps11_clks->clk_np,
of_clk_hw_onecell_get, clk_data);
if (ret)
goto err_reg;
platform_set_drvdata(pdev, s2mps11_clks);
@ -201,8 +203,10 @@ static int s2mps11_clk_probe(struct platform_device *pdev)
err_reg:
of_node_put(s2mps11_clks[0].clk_np);
while (--i >= 0)
clkdev_drop(s2mps11_clks[i].lookup);
while (--i >= 0) {
if (s2mps11_clks[i].lookup)
clkdev_drop(s2mps11_clks[i].lookup);
}
return ret;
}

View File

@ -128,7 +128,7 @@ static int
scpi_clk_ops_init(struct device *dev, const struct of_device_id *match,
struct scpi_clk *sclk, const char *name)
{
struct clk_init_data init;
struct clk_init_data init = {};
unsigned long min = 0, max = 0;
int ret;

View File

@ -337,8 +337,8 @@ static const struct regmap_config si514_regmap_config = {
static int si514_probe(struct i2c_client *client)
{
struct clk_init_data init = {};
struct clk_si514 *data;
struct clk_init_data init;
int err;
data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);

View File

@ -13,6 +13,7 @@
*/
#include <linux/bitfield.h>
#include <linux/bitops.h>
#include <linux/bitrev.h>
#include <linux/clk-provider.h>
#include <linux/i2c.h>
@ -255,18 +256,24 @@ static void si521xx_diff_idx_to_reg_bit(const u16 chip_info, const int idx,
struct si_clk *clk)
{
unsigned long mask;
int oe, b, ctr = 0;
unsigned int bit;
int oe = 1;
for (oe = 1; oe <= 2; oe++) {
mask = bitrev8(SI521XX_OE_MAP_GET_OE(oe, chip_info));
for_each_set_bit(b, &mask, 8) {
if (ctr++ != idx)
continue;
clk->reg = SI521XX_REG_OE(oe);
clk->bit = 7 - b;
return;
}
}
mask = bitrev8(SI521XX_OE_MAP_GET_OE(1, chip_info));
bit = fns(mask, idx);
if (bit < 8)
goto out;
oe = 2;
bit = idx - hweight8(mask);
mask = bitrev8(SI521XX_OE_MAP_GET_OE(2, chip_info));
bit = fns(mask, bit);
if (bit >= 8)
return;
out:
clk->reg = SI521XX_REG_OE(oe);
clk->bit = 7 - bit;
}
static struct clk_hw *
@ -341,7 +348,7 @@ static int si521xx_probe(struct i2c_client *client)
return ret;
}
static int __maybe_unused si521xx_suspend(struct device *dev)
static int si521xx_suspend(struct device *dev)
{
struct si521xx *si = dev_get_drvdata(dev);
@ -351,15 +358,17 @@ static int __maybe_unused si521xx_suspend(struct device *dev)
return 0;
}
static int __maybe_unused si521xx_resume(struct device *dev)
static int si521xx_resume(struct device *dev)
{
struct si521xx *si = dev_get_drvdata(dev);
int ret;
regcache_cache_only(si->regmap, false);
ret = regcache_sync(si->regmap);
if (ret)
if (ret) {
regcache_cache_only(si->regmap, true);
dev_err(dev, "Failed to restore register map: %d\n", ret);
}
return ret;
}
@ -374,17 +383,17 @@ MODULE_DEVICE_TABLE(i2c, si521xx_id);
static const struct of_device_id clk_si521xx_of_match[] = {
{ .compatible = "skyworks,si52144", .data = (void *)SI521XX_OE_MAP(0x5, 0xc0) },
{ .compatible = "skyworks,si52146", .data = (void *)SI521XX_OE_MAP(0x15, 0xe0) },
{ .compatible = "skyworks,si52147", .data = (void *)SI521XX_OE_MAP(0x15, 0xf8) },
{ .compatible = "skyworks,si52147", .data = (void *)SI521XX_OE_MAP(0x17, 0xf8) },
{ }
};
MODULE_DEVICE_TABLE(of, clk_si521xx_of_match);
static SIMPLE_DEV_PM_OPS(si521xx_pm_ops, si521xx_suspend, si521xx_resume);
static DEFINE_SIMPLE_DEV_PM_OPS(si521xx_pm_ops, si521xx_suspend, si521xx_resume);
static struct i2c_driver si521xx_driver = {
.driver = {
.name = "clk-si521xx",
.pm = &si521xx_pm_ops,
.pm = pm_sleep_ptr(&si521xx_pm_ops),
.of_match_table = clk_si521xx_of_match,
},
.probe = si521xx_probe,

View File

@ -1556,8 +1556,8 @@ static const struct attribute *si5341_attributes[] = {
static int si5341_probe(struct i2c_client *client)
{
struct clk_init_data init = {};
struct clk_si5341 *data;
struct clk_init_data init;
struct clk *input;
const char *root_clock_name;
const char *synth_clock_names[SI5341_NUM_SYNTH] = { NULL };

View File

@ -907,7 +907,7 @@ static int _si5351_clkout_set_disable_state(
return 0;
}
static void _si5351_clkout_reset_pll(struct si5351_driver_data *drvdata, int num)
static int _si5351_clkout_reset_pll(struct si5351_driver_data *drvdata, int num)
{
u8 val = si5351_reg_read(drvdata, SI5351_CLK0_CTRL + num);
u8 mask = val & SI5351_CLK_PLL_SELECT ? SI5351_PLL_RESET_B :
@ -918,7 +918,7 @@ static void _si5351_clkout_reset_pll(struct si5351_driver_data *drvdata, int num
switch (val & SI5351_CLK_INPUT_MASK) {
case SI5351_CLK_INPUT_XTAL:
case SI5351_CLK_INPUT_CLKIN:
return; /* pll not used, no need to reset */
return 0; /* pll not used, no need to reset */
}
si5351_reg_write(drvdata, SI5351_PLL_RESET, mask);
@ -931,6 +931,8 @@ static void _si5351_clkout_reset_pll(struct si5351_driver_data *drvdata, int num
dev_dbg(&drvdata->client->dev, "%s - %s: pll = %d\n",
__func__, clk_hw_get_name(&drvdata->clkout[num].hw),
(val & SI5351_CLK_PLL_SELECT) ? 1 : 0);
return err;
}
static int si5351_clkout_prepare(struct clk_hw *hw)
@ -947,8 +949,18 @@ static int si5351_clkout_prepare(struct clk_hw *hw)
* Do a pll soft reset on the parent pll -- needed to get a
* deterministic phase relationship between the output clocks.
*/
if (pdata->clkout[hwdata->num].pll_reset)
_si5351_clkout_reset_pll(hwdata->drvdata, hwdata->num);
if (pdata->clkout[hwdata->num].pll_reset) {
int ret;
ret = _si5351_clkout_reset_pll(hwdata->drvdata, hwdata->num);
if (ret) {
si5351_set_bits(hwdata->drvdata,
SI5351_CLK0_CTRL + hwdata->num,
SI5351_CLK_POWERDOWN,
SI5351_CLK_POWERDOWN);
return ret;
}
}
si5351_set_bits(hwdata->drvdata, SI5351_OUTPUT_ENABLE_CTRL,
(1 << hwdata->num), 0);

View File

@ -445,8 +445,8 @@ static const struct regmap_config si544_regmap_config = {
static int si544_probe(struct i2c_client *client)
{
struct clk_init_data init = {};
struct clk_si544 *data;
struct clk_init_data init;
int err;
data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);

View File

@ -412,7 +412,7 @@ static const struct regmap_config si570_regmap_config = {
static int si570_probe(struct i2c_client *client)
{
struct clk_si570 *data;
struct clk_init_data init;
struct clk_init_data init = {};
u32 initial_fout, factory_fout, stability;
bool skip_recall;
int err;

Some files were not shown because too many files have changed in this diff Show More