Merge branches 'clk-renesas', 'clk-samsung', 'clk-starfive', 'clk-tenstorrent' and 'clk-pile' into clk-next

* clk-renesas: (25 commits)
  clk: renesas: r8a78000: Add SGASYNCD8_PERW_BUS
  clk: renesas: rzg2l: Fix internal clock names
  clk: renesas: r9a08g046: Add TSU and ADC1 clocks and resets
  clk: renesas: Add support for RZ/G2M v3.0
  clk: renesas: r9a08g046: Add CANFD clocks and resets
  clk: renesas: r9a08g046: Propagate clk rate for ETH TX mux clocks
  dt-bindings: clock: Add r8a774a3 CPG Core Clock definitions
  clk: renesas: r8a779g0: Add ZG clocks
  clk: renesas: rcar-gen4: Tidy up DEF_GEN4_Z()
  clk: renesas: r9a09g077: Register SYSC regmap
  clk: renesas: rcar-gen3: Use FIELD_GET()
  clk: renesas: rzv2h: Convert to clk_hw based provider API
  clk: renesas: rzv2h: Drop duplicated parent lookup in fixed_mod_status_clk_register()
  clk: renesas: r9a08g046: Add PCIe clocks and reset
  clk: renesas: Make sure clk_init_data is fully initialized
  clk: renesas: r9a08g046: Add clock and reset entries for LVDS
  clk: renesas: r9a08g046: Add MIPI DSI and LCDC clock/reset entries
  clk: renesas: r9a08g046: Sort macro definitions alphabetically
  clk: renesas: rzg2l: Add support for RZ/G3L DSI mux
  clk: renesas: rzg2l: Add support for LVDS fixed-factor divider with 4:7 duty cycle
  ...

* clk-samsung:
  clk: samsung: acpm: add Exynos850 support
  clk: samsung: acpm: introduce driver data for SoC-specific clocks
  clk: samsung: Introduce Exynos5515 clock driver
  clk: samsung: clk-pll: Add support for pll_309
  dt-bindings: clock: Add Exynos5515 SoC

* clk-starfive:
  dt-bindings: soc: starfive: Add StarFive JHB100 syscon modules
  dt-bindings: clock: Add StarFive JHB100 Peripheral-3 clock and reset generator
  dt-bindings: clock: Add StarFive JHB100 Peripheral-2 clock and reset generator
  dt-bindings: clock: Add StarFive JHB100 Peripheral-1 clock and reset generator
  dt-bindings: clock: Add StarFive JHB100 Peripheral-0 clock and reset generator
  dt-bindings: clock: Add StarFive JHB100 System-2 clock and reset generator
  dt-bindings: clock: Add StarFive JHB100 System-1 clock and reset generator
  dt-bindings: clock: Add StarFive JHB100 System-0 clock and reset generator

* clk-tenstorrent:
  MAINTAINERS: Update RISC-V Tenstorrent SoC entry
  clk: tenstorrent: use regmap_assign_bits() for conditional set/clear
  clk: tenstorrent: Fix refcount leak on shared gate clk enable failure
  clk: tenstorrent: Assign .num before accessing .hws

* clk-pile: (126 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:
Brian Masney 2026-10-26 19:48:58 -04:00
279 changed files with 10428 additions and 1006 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,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,70 @@
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/starfive,jhb100-per0crg.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: StarFive JHB100 Peripheral-0 Clock and Reset Generator
maintainers:
- Changhuang Liang <changhuang.liang@starfivetech.com>
properties:
compatible:
const: starfive,jhb100-per0crg
reg:
maxItems: 1
clocks:
items:
- description: Main Oscillator (25 MHz)
- description: PLL6
- description: Configure 400MHz
- description: Configure 800MHZ
- description: Non Coherent NOC Initiator
- description: Non Coherent NOC Target
clock-names:
items:
- const: osc
- const: pll6
- const: cfg_400
- const: cfg_800
- const: ncnoc_init
- const: ncnoc_targ
'#clock-cells':
const: 1
description:
See <dt-bindings/clock/starfive,jhb100-crg.h> for valid indices.
'#reset-cells':
const: 1
description:
See <dt-bindings/reset/starfive,jhb100-crg.h> for valid indices.
required:
- compatible
- reg
- clocks
- clock-names
- '#clock-cells'
- '#reset-cells'
additionalProperties: false
examples:
- |
clock-controller@11a08000 {
compatible = "starfive,jhb100-per0crg";
reg = <0x11a08000 0x1000>;
clocks = <&osc>, <&pll6>, <&sys0crg 71>,
<&sys0crg 72>, <&sys0crg 70>,
<&sys2crg 23>;
clock-names = "osc", "pll6", "cfg_400",
"cfg_800", "ncnoc_init",
"ncnoc_targ";
#clock-cells = <1>;
#reset-cells = <1>;
};

View File

@ -0,0 +1,70 @@
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/starfive,jhb100-per1crg.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: StarFive JHB100 Peripheral-1 Clock and Reset Generator
maintainers:
- Changhuang Liang <changhuang.liang@starfivetech.com>
properties:
compatible:
const: starfive,jhb100-per1crg
reg:
maxItems: 1
clocks:
items:
- description: PLL7
- description: Non Coherent NOC Initiator
- description: Configure 800MHz
- description: Non Coherent NOC Target
- description: Configure 143MHz
clock-names:
items:
- const: pll7
- const: ncnoc_init
- const: cfg_800
- const: ncnoc_targ
- const: cfg_143
'#clock-cells':
const: 1
description:
See <dt-bindings/clock/starfive,jhb100-crg.h> for valid indices.
'#reset-cells':
const: 1
description:
See <dt-bindings/reset/starfive,jhb100-crg.h> for valid indices.
required:
- compatible
- reg
- clocks
- clock-names
- '#clock-cells'
- '#reset-cells'
additionalProperties: false
examples:
- |
clock-controller@11b40000 {
compatible = "starfive,jhb100-per1crg";
reg = <0x11b40000 0x1000>;
clocks = <&pll7>,
<&sys0crg 68>,
<&sys0crg 69>,
<&sys2crg 19>,
<&sys2crg 22>;
clock-names = "pll7", "ncnoc_init",
"cfg_800", "ncnoc_targ",
"cfg_143";
#clock-cells = <1>;
#reset-cells = <1>;
};

View File

@ -0,0 +1,76 @@
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/starfive,jhb100-per2crg.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: StarFive JHB100 Peripheral-2 Clock and Reset Generator
maintainers:
- Changhuang Liang <changhuang.liang@starfivetech.com>
properties:
compatible:
const: starfive,jhb100-per2crg
reg:
maxItems: 1
clocks:
items:
- description: Non Coherent NOC Initiator
- description: Configure 400MHz
- description: Configure 125MHz
- description: GMAC2 RGMII RX
- description: GMAC2 RMII Reference
- description: GMAC3 SGMII TX
- description: GMAC3 SGMII RX
- description: Main Oscillator (25 MHz)
clock-names:
items:
- const: ncnoc_init
- const: cfg_400
- const: cfg_125
- const: gmac2_rgmii_rx
- const: gmac2_rmii_ref
- const: gmac3_sgmii_tx
- const: gmac3_sgmii_rx
- const: osc
'#clock-cells':
const: 1
description:
See <dt-bindings/clock/starfive,jhb100-crg.h> for valid indices.
'#reset-cells':
const: 1
description:
See <dt-bindings/reset/starfive,jhb100-crg.h> for valid indices.
required:
- compatible
- reg
- clocks
- clock-names
- '#clock-cells'
- '#reset-cells'
additionalProperties: false
examples:
- |
clock-controller@11bc0000 {
compatible = "starfive,jhb100-per2crg";
reg = <0x11bc0000 0x1000>;
clocks = <&sys0crg 52>, <&sys0crg 54>, <&sys0crg 55>,
<&per2_gmac2_rgmii_rx>, <&per2_gmac2_rmii_ref>,
<&per2_gmac3_sgmii_tx>, <&per2_gmac3_sgmii_rx>,
<&osc>;
clock-names = "ncnoc_init", "cfg_400", "cfg_125",
"gmac2_rgmii_rx", "gmac2_rmii_ref",
"gmac3_sgmii_tx", "gmac3_sgmii_rx",
"osc";
#clock-cells = <1>;
#reset-cells = <1>;
};

View File

@ -0,0 +1,76 @@
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/starfive,jhb100-per3crg.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: StarFive JHB100 Peripheral-3 Clock and Reset Generator
maintainers:
- Changhuang Liang <changhuang.liang@starfivetech.com>
properties:
compatible:
const: starfive,jhb100-per3crg
reg:
maxItems: 1
clocks:
items:
- description: Non Coherent NOC Initiator
- description: Non Coherent NOC Target
- description: Configure 125MHz
- description: GMAC0 RMII Reference clock
- description: GMAC1 SGMII TX
- description: GMAC1 SGMII RX
- description: Main Oscillator (25 MHz)
clock-names:
items:
- const: ncnoc_init
- const: ncnoc_targ
- const: cfg_125
- const: gmac0_rmii_rclki
- const: gmac1_sgmii_tx
- const: gmac1_sgmii_rx
- const: osc
'#clock-cells':
const: 1
description:
See <dt-bindings/clock/starfive,jhb100-crg.h> for valid indices.
'#reset-cells':
const: 1
description:
See <dt-bindings/reset/starfive,jhb100-crg.h> for valid indices.
required:
- compatible
- reg
- clocks
- clock-names
- '#clock-cells'
- '#reset-cells'
additionalProperties: false
examples:
- |
clock-controller@11c40000 {
compatible = "starfive,jhb100-per3crg";
reg = <0x11c40000 0x1000>;
clocks = <&sys0crg 65>,
<&sys1crg 18>,
<&sys1crg 19>,
<&per3_gmac0_rmii_rclki>,
<&per3_gmac1_sgmii_tx>,
<&per3_gmac1_sgmii_rx>,
<&osc>;
clock-names = "ncnoc_init", "ncnoc_targ", "cfg_125",
"gmac0_rmii_rclki", "gmac1_sgmii_tx",
"gmac1_sgmii_rx", "osc";
#clock-cells = <1>;
#reset-cells = <1>;
};

View File

@ -0,0 +1,63 @@
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/starfive,jhb100-sys0crg.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: StarFive JHB100 System-0 Clock and Reset Generator
maintainers:
- Changhuang Liang <changhuang.liang@starfivetech.com>
properties:
compatible:
const: starfive,jhb100-sys0crg
reg:
maxItems: 1
clocks:
items:
- description: Main Oscillator (25 MHz)
- description: PLL0
- description: PLL1
- description: PLL2
clock-names:
items:
- const: osc
- const: pll0
- const: pll1
- const: pll2
'#clock-cells':
const: 1
description:
See <dt-bindings/clock/starfive,jhb100-crg.h> for valid indices.
'#reset-cells':
const: 1
description:
See <dt-bindings/reset/starfive,jhb100-crg.h> for valid indices.
required:
- compatible
- reg
- clocks
- clock-names
- '#clock-cells'
- '#reset-cells'
additionalProperties: false
examples:
- |
clock-controller@13000000 {
compatible = "starfive,jhb100-sys0crg";
reg = <0x13000000 0x4000>;
clocks = <&osc>, <&pll0>, <&pll1>,
<&syspll 0>;
clock-names = "osc", "pll0", "pll1", "pll2";
#clock-cells = <1>;
#reset-cells = <1>;
};

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/starfive,jhb100-sys1crg.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: StarFive JHB100 System-1 Clock and Reset Generator
maintainers:
- Changhuang Liang <changhuang.liang@starfivetech.com>
properties:
compatible:
const: starfive,jhb100-sys1crg
reg:
maxItems: 1
clocks:
items:
- description: Main Oscillator (25 MHz)
- description: PLL0
- description: PLL1
- description: PLL2
- description: PLL4
- description: PLL5
- description: NPU Non Coherent NOC Initiator
clock-names:
items:
- const: osc
- const: pll0
- const: pll1
- const: pll2
- const: pll4
- const: pll5
- const: npu_ncnoc_init
'#clock-cells':
const: 1
description:
See <dt-bindings/clock/starfive,jhb100-crg.h> for valid indices.
'#reset-cells':
const: 1
description:
See <dt-bindings/reset/starfive,jhb100-crg.h> for valid indices.
required:
- compatible
- reg
- clocks
- clock-names
- '#clock-cells'
- '#reset-cells'
additionalProperties: false
examples:
- |
clock-controller@13004000 {
compatible = "starfive,jhb100-sys1crg";
reg = <0x13004000 0x4000>;
clocks = <&osc>, <&pll0>, <&pll1>,
<&syspll 0>, <&syspll 2>,
<&syspll 3>, <&sys0crg 61>;
clock-names = "osc", "pll0", "pll1", "pll2",
"pll4", "pll5", "npu_ncnoc_init";
#clock-cells = <1>;
#reset-cells = <1>;
};

View File

@ -0,0 +1,64 @@
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/starfive,jhb100-sys2crg.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: StarFive JHB100 System-2 Clock and Reset Generator
maintainers:
- Changhuang Liang <changhuang.liang@starfivetech.com>
properties:
compatible:
const: starfive,jhb100-sys2crg
reg:
maxItems: 1
clocks:
items:
- description: Main Oscillator (25 MHz)
- description: PLL1
- description: GPU0 Non Coherent NOC Initiator
- description: GPU1 Non Coherent NOC Initiator
clock-names:
items:
- const: osc
- const: pll1
- const: gpu0_ncnoc_init
- const: gpu1_ncnoc_init
'#clock-cells':
const: 1
description:
See <dt-bindings/clock/starfive,jhb100-crg.h> for valid indices.
'#reset-cells':
const: 1
description:
See <dt-bindings/reset/starfive,jhb100-crg.h> for valid indices.
required:
- compatible
- reg
- clocks
- clock-names
- '#clock-cells'
- '#reset-cells'
additionalProperties: false
examples:
- |
clock-controller@13008000 {
compatible = "starfive,jhb100-sys2crg";
reg = <0x13008000 0x4000>;
clocks = <&osc>, <&pll1>, <&sys0crg 73>,
<&sys0crg 74>;
clock-names = "osc", "pll1", "gpu0_ncnoc_init",
"gpu1_ncnoc_init";
#clock-cells = <1>;
#reset-cells = <1>;
};

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

@ -0,0 +1,115 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/soc/starfive/starfive,jhb100-syscon.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: StarFive JHB100 SoC system controller
maintainers:
- Kevin Xie <kevin.xie@starfivetech.com>
- Changhuang Liang <changhuang.liang@starfivetech.com>
description:
The StarFive JHB100 SoC system controller contains MMIO registers used by
other hardware modules (e.g., PLL, eMMC, PCIe). These modules access
specific register offsets, bit masks, and shifts within the system
controller region for configuration and status.
properties:
compatible:
items:
- enum:
- starfive,jhb100-b2h-syscon
- starfive,jhb100-gpu-syscon
- starfive,jhb100-h2b-syscon
- starfive,jhb100-host-syscon
- starfive,jhb100-husb-syscon
- starfive,jhb100-husbcmn-syscon
- starfive,jhb100-husbd-syscon
- starfive,jhb100-npu-syscon
- starfive,jhb100-pcieep-ecsr-syscon
- starfive,jhb100-pcierp-ecsr-syscon
- starfive,jhb100-pcierp-syscon
- starfive,jhb100-per0-syscon
- starfive,jhb100-per1-syscon
- starfive,jhb100-per2-syscon
- starfive,jhb100-per3-syscon
- starfive,jhb100-sfc-filter-syscon
- starfive,jhb100-strap-syscon
- starfive,jhb100-sys0-syscon
- starfive,jhb100-sys1-syscon
- starfive,jhb100-sys2-syscon
- starfive,jhb100-usb-syscon
- starfive,jhb100-vout-syscon
- const: syscon
reg:
maxItems: 1
clocks:
maxItems: 1
'#clock-cells':
const: 1
'#reset-cells':
const: 1
required:
- compatible
- reg
allOf:
- if:
properties:
compatible:
contains:
enum:
- starfive,jhb100-per0-syscon
- starfive,jhb100-per1-syscon
- starfive,jhb100-sys0-syscon
then:
required:
- clocks
- '#clock-cells'
else:
properties:
clocks: false
'#clock-cells': false
- if:
properties:
compatible:
contains:
const: starfive,jhb100-pcierp-syscon
then:
required:
- '#reset-cells'
else:
properties:
'#reset-cells': false
additionalProperties: false
examples:
- |
syscon@13010000 {
compatible = "starfive,jhb100-sys0-syscon", "syscon";
reg = <0x13010000 0x2000>;
clocks = <&osc>;
#clock-cells = <1>;
};
syscon@13014000 {
compatible = "starfive,jhb100-sys1-syscon", "syscon";
reg = <0x13014000 0x4000>;
};
syscon@11719000 {
compatible = "starfive,jhb100-pcierp-syscon", "syscon";
reg = <0x11719000 0x1000>;
#reset-cells = <1>;
};
...

View File

@ -2010,6 +2010,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
@ -3900,8 +3909,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>
@ -6500,7 +6516,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/
@ -16613,6 +16629,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
@ -23601,11 +23628,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

@ -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;

View File

@ -485,8 +485,8 @@ static struct clk *clk_register_apb_mul(struct device *dev, const char *name,
const char *parent_name,
unsigned long flags, u8 bit_idx)
{
struct clk_init_data init = {};
struct clk_apb_mul *am;
struct clk_init_data init;
struct clk *clk;
am = kzalloc_obj(*am);
@ -810,8 +810,8 @@ static struct clk_hw *clk_register_pll_div(const char *name,
struct clk_hw *pll_hw, spinlock_t *lock)
{
struct stm32f4_pll_div *pll_div;
struct clk_init_data init = {};
struct clk_hw *hw;
struct clk_init_data init;
int ret;
/* allocate the divider */

View File

@ -462,8 +462,8 @@ static struct clk_hw *clk_register_stm32_timer_ker(struct device *dev,
u8 dppre_shift,
spinlock_t *lock)
{
struct clk_init_data init = {};
struct timer_ker *element;
struct clk_init_data init;
struct clk_hw *hw;
int err;

View File

@ -1223,7 +1223,7 @@ static void vc5_remove(struct i2c_client *client)
clk_unregister_fixed_rate(vc5->pin_xin);
}
static int __maybe_unused vc5_suspend(struct device *dev)
static int vc5_suspend(struct device *dev)
{
struct vc5_driver_data *vc5 = dev_get_drvdata(dev);
@ -1233,15 +1233,17 @@ static int __maybe_unused vc5_suspend(struct device *dev)
return 0;
}
static int __maybe_unused vc5_resume(struct device *dev)
static int vc5_resume(struct device *dev)
{
struct vc5_driver_data *vc5 = dev_get_drvdata(dev);
int ret;
regcache_cache_only(vc5->regmap, false);
ret = regcache_sync(vc5->regmap);
if (ret)
if (ret) {
regcache_cache_only(vc5->regmap, true);
dev_err(dev, "Failed to restore register map: %d\n", ret);
}
return ret;
}
@ -1335,12 +1337,12 @@ static const struct of_device_id clk_vc5_of_match[] = {
};
MODULE_DEVICE_TABLE(of, clk_vc5_of_match);
static SIMPLE_DEV_PM_OPS(vc5_pm_ops, vc5_suspend, vc5_resume);
static DEFINE_SIMPLE_DEV_PM_OPS(vc5_pm_ops, vc5_suspend, vc5_resume);
static struct i2c_driver vc5_driver = {
.driver = {
.name = "vc5",
.pm = &vc5_pm_ops,
.pm = pm_sleep_ptr(&vc5_pm_ops),
.of_match_table = clk_vc5_of_match,
},
.probe = vc5_probe,

View File

@ -227,8 +227,8 @@ static __init void vtwm_device_clk_init(struct device_node *node)
struct clk_hw *hw;
struct clk_device *dev_clk;
const char *clk_name = node->name;
struct clk_init_data init = {};
const char *parent_name;
struct clk_init_data init;
int rc;
int clk_init_flags = 0;
@ -687,8 +687,8 @@ static __init void vtwm_pll_clk_init(struct device_node *node, int pll_type)
struct clk_hw *hw;
struct clk_pll *pll_clk;
const char *clk_name = node->name;
struct clk_init_data init = {};
const char *parent_name;
struct clk_init_data init;
int rc;
if (!pmc_base)

View File

@ -126,9 +126,9 @@ static struct clk *xgene_register_clk_pll(struct device *dev,
unsigned long flags, void __iomem *reg, u32 pll_offset,
u32 type, spinlock_t *lock, int version)
{
struct clk_init_data init = {};
struct xgene_clk_pll *apmclk;
struct clk *clk;
struct clk_init_data init;
/* allocate the APM clock structure */
apmclk = kzalloc_obj(*apmclk);
@ -350,8 +350,8 @@ xgene_register_clk_pmd(struct device *dev,
unsigned long flags, void __iomem *reg, u8 shift,
u8 width, u64 denom, u32 clk_flags, spinlock_t *lock)
{
struct clk_init_data init = {};
struct xgene_clk_pmd *fd;
struct clk_init_data init;
struct clk *clk;
fd = kzalloc_obj(*fd);
@ -634,9 +634,9 @@ static struct clk *xgene_register_clk(struct device *dev,
const char *name, const char *parent_name,
struct xgene_dev_parameters *parameters, spinlock_t *lock)
{
struct clk_init_data init = {};
struct xgene_clk *apmclk;
struct clk *clk;
struct clk_init_data init;
int rc;
/* allocate the APM clock structure */

View File

@ -24,6 +24,7 @@
#include <linux/spinlock.h>
#include <linux/string.h>
#include <linux/stringhash.h>
#include <kunit/visibility.h>
#include "clk.h"
@ -166,6 +167,7 @@ struct clk {
unsigned long max_rate;
unsigned int exclusive_count;
struct hlist_node clks_node;
bool pinning;
};
/*** runtime pm ***/
@ -2851,6 +2853,20 @@ int clk_hw_set_spread_spectrum(struct clk_hw *hw, const struct clk_spread_spectr
if (!hw)
return 0;
switch (ss_conf->method) {
case CLK_SPREAD_NO:
break;
case CLK_SPREAD_CENTER:
case CLK_SPREAD_UP:
case CLK_SPREAD_DOWN:
if (!ss_conf->modfreq_hz || !ss_conf->spread_bp ||
ss_conf->spread_bp > 10000)
return -EINVAL;
break;
default:
return -EINVAL;
}
core = hw->core;
clk_prepare_lock();
@ -4237,13 +4253,15 @@ static void free_clk(struct clk *clk)
* @hw: clk_hw associated with the clk being consumed
* @dev_id: string describing device name
* @con_id: connection ID string on device
* @owner: reference to the module creating the clock
*
* This is the main function used to create a clk pointer for use by clk
* consumers. It connects a consumer to the clk_core and clk_hw structures
* used by the framework and clk provider respectively.
*/
struct clk *clk_hw_create_clk(struct device *dev, struct clk_hw *hw,
const char *dev_id, const char *con_id)
const char *dev_id, const char *con_id,
struct module *owner)
{
struct clk *clk;
struct clk_core *core;
@ -4258,7 +4276,13 @@ struct clk *clk_hw_create_clk(struct device *dev, struct clk_hw *hw,
return clk;
clk->dev = dev;
if (!try_module_get(core->owner)) {
/*
* Pin the provider module only when the consumer lives in a different
* module. A provider getting a clk from its own clk_hw would otherwise
* pin itself and could never be unloaded.
*/
clk->pinning = owner != core->owner;
if (clk->pinning && !try_module_get(core->owner)) {
free_clk(clk);
return ERR_PTR(-ENOENT);
}
@ -4269,24 +4293,19 @@ struct clk *clk_hw_create_clk(struct device *dev, struct clk_hw *hw,
return clk;
}
/**
* clk_hw_get_clk - get clk consumer given an clk_hw
* @hw: clk_hw associated with the clk being consumed
* @con_id: connection ID string on device
*
* Returns: new clk consumer
* This is the function to be used by providers which need
* to get a consumer clk and act on the clock element
* Calls to this function must be balanced with calls clk_put()
/*
* Internal helper backing the clk_hw_get_clk() macro, which passes the caller's
* module via THIS_MODULE.
*/
struct clk *clk_hw_get_clk(struct clk_hw *hw, const char *con_id)
struct clk *__clk_hw_get_clk(struct clk_hw *hw, const char *con_id,
struct module *owner)
{
struct device *dev = hw->core->dev;
const char *name = dev ? dev_name(dev) : NULL;
return clk_hw_create_clk(dev, hw, name, con_id);
return clk_hw_create_clk(dev, hw, name, con_id, owner);
}
EXPORT_SYMBOL(clk_hw_get_clk);
EXPORT_SYMBOL(__clk_hw_get_clk);
static int clk_cpy_name(const char **dst_p, const char *src, bool must_exist)
{
@ -4450,8 +4469,9 @@ __clk_register(struct device *dev, struct device_node *np, struct clk_hw *hw)
INIT_HLIST_HEAD(&core->clks);
/*
* Don't call clk_hw_create_clk() here because that would pin the
* provider module to itself and prevent it from ever being removed.
* Don't call clk_hw_create_clk() here because it would systematically
* add a consumer to the hw clock and all clocks would appear to have
* consumer in the clock summary.
*/
hw->clk = alloc_clk(core, NULL, NULL);
if (IS_ERR(hw->clk)) {
@ -4808,7 +4828,7 @@ struct clk *devm_clk_hw_get_clk(struct device *dev, struct clk_hw *hw,
if (!clkp)
return ERR_PTR(-ENOMEM);
clk = clk_hw_get_clk(hw, con_id);
clk = __clk_hw_get_clk(hw, con_id, dev->driver->owner);
if (!IS_ERR(clk)) {
*clkp = clk;
devres_add(dev, clkp);
@ -4855,7 +4875,8 @@ void __clk_put(struct clk *clk)
owner = clk->core->owner;
kref_put(&clk->core->ref, __clk_release);
module_put(owner);
if (clk->pinning)
module_put(owner);
free_clk(clk);
}
@ -5297,13 +5318,13 @@ static int of_parse_clkspec(const struct device_node *np, int index,
/*
* For named clocks, first look up the name in the
* "clock-names" property. If it cannot be found, then index
* will be an error code and of_parse_phandle_with_args() will
* will be an error code and the OF phandle parser will
* return -EINVAL.
*/
if (name)
index = of_property_match_string(np, "clock-names", name);
ret = of_parse_phandle_with_args(np, "clocks", "#clock-cells",
index, out_args);
ret = of_parse_phandle_with_args_map(np, "clocks", "clock",
index, out_args);
if (!ret)
break;
if (name && index >= 0)
@ -5314,6 +5335,8 @@ static int of_parse_clkspec(const struct device_node *np, int index,
* has a "clock-ranges" property, then we can try one of its
* clocks.
*/
if (of_property_present(np, "clocks"))
break;
np = np->parent;
if (np && !of_property_present(np, "clock-ranges"))
break;
@ -5370,13 +5393,13 @@ of_clk_get_hw_from_clkspec(struct of_phandle_args *clkspec)
*
* This function looks up a struct clk from the registered list of clock
* providers, an input is a clock specifier data structure as returned
* from the of_parse_phandle_with_args() function call.
* from the OF phandle parser.
*/
struct clk *of_clk_get_from_provider(struct of_phandle_args *clkspec)
{
struct clk_hw *hw = of_clk_get_hw_from_clkspec(clkspec);
return clk_hw_create_clk(NULL, hw, NULL, __func__);
return clk_hw_create_clk(NULL, hw, NULL, __func__, NULL);
}
EXPORT_SYMBOL_GPL(of_clk_get_from_provider);
@ -5396,6 +5419,7 @@ struct clk_hw *of_clk_get_hw(struct device_node *np, int index,
return hw;
}
EXPORT_SYMBOL_IF_KUNIT(of_clk_get_hw);
static struct clk *__of_clk_get(struct device_node *np,
int index, const char *dev_id,
@ -5403,7 +5427,7 @@ static struct clk *__of_clk_get(struct device_node *np,
{
struct clk_hw *hw = of_clk_get_hw(np, index, con_id);
return clk_hw_create_clk(NULL, hw, dev_id, con_id);
return clk_hw_create_clk(NULL, hw, dev_id, con_id, NULL);
}
struct clk *of_clk_get(struct device_node *np, int index)
@ -5458,8 +5482,7 @@ const char *of_clk_get_parent_name(const struct device_node *np, int index)
int count;
struct clk *clk;
rc = of_parse_phandle_with_args(np, "clocks", "#clock-cells", index,
&clkspec);
rc = of_parse_clkspec(np, index, NULL, &clkspec);
if (rc)
return NULL;

View File

@ -23,13 +23,14 @@ struct clk_hw *clk_find_hw(const char *dev_id, const char *con_id);
#ifdef CONFIG_COMMON_CLK
struct clk *clk_hw_create_clk(struct device *dev, struct clk_hw *hw,
const char *dev_id, const char *con_id);
const char *dev_id, const char *con_id,
struct module *owner);
void __clk_put(struct clk *clk);
#else
/* All these casts to avoid ifdefs in clkdev... */
static inline struct clk *
clk_hw_create_clk(struct device *dev, struct clk_hw *hw, const char *dev_id,
const char *con_id)
const char *con_id, struct module *owner)
{
return (struct clk *)hw;
}

View File

@ -233,5 +233,36 @@ int of_clk_add_hw_provider_kunit(struct kunit *test, struct device_node *np,
}
EXPORT_SYMBOL_GPL(of_clk_add_hw_provider_kunit);
KUNIT_DEFINE_ACTION_WRAPPER(of_node_put_wrapper, of_node_put, struct device_node *);
/**
* clk_of_find_node_by_name_kunit() - Test managed of_find_node_by_name()
* @test: The test context
* @from: Parent device node to start searching from, or NULL to search from root
* @name: The name string to match against
*
* Just like of_find_node_by_name(), except the device_node is managed by
* the test case and is automatically put after the test case concludes.
*
* Return: the device_node on success, NULL if not found, or an error pointer on failure.
*/
struct device_node *clk_of_find_node_by_name_kunit(struct kunit *test, struct device_node *from,
const char *name)
{
struct device_node *np;
int ret;
np = of_find_node_by_name(from, name);
if (!np)
return NULL;
ret = kunit_add_action_or_reset(test, of_node_put_wrapper, np);
if (ret)
return ERR_PTR(ret);
return np;
}
EXPORT_SYMBOL_GPL(clk_of_find_node_by_name_kunit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("KUnit helpers for clk providers and consumers");

View File

@ -3526,7 +3526,7 @@ static const struct clk_assigned_rates_test_param clk_assigned_sscs_skips_test_p
*/
.desc = "provider missing assigned-clocks",
TEST_PARAM_OVERLAY(kunit_clk_assigned_sscs_without),
.sscs = {50000, 60000, 3},
.sscs = {50000, 600, 3},
},
{
/*
@ -3535,7 +3535,7 @@ static const struct clk_assigned_rates_test_param clk_assigned_sscs_skips_test_p
*/
.desc = "consumer missing assigned-clocks",
TEST_PARAM_OVERLAY(kunit_clk_assigned_sscs_without_consumer),
.sscs = {50000, 60000, 3},
.sscs = {50000, 600, 3},
.consumer_test = true,
},
{
@ -3545,7 +3545,7 @@ static const struct clk_assigned_rates_test_param clk_assigned_sscs_skips_test_p
*/
.desc = "provider assigned-clock-sscs of zero",
TEST_PARAM_OVERLAY(kunit_clk_assigned_sscs_zero),
.sscs = {50000, 60000, 3},
.sscs = {50000, 600, 3},
},
{
/*
@ -3554,7 +3554,7 @@ static const struct clk_assigned_rates_test_param clk_assigned_sscs_skips_test_p
*/
.desc = "consumer assigned-clock-sscs of zero",
TEST_PARAM_OVERLAY(kunit_clk_assigned_sscs_zero_consumer),
.sscs = {50000, 60000, 3},
.sscs = {50000, 600, 3},
.consumer_test = true,
},
{
@ -3564,7 +3564,7 @@ static const struct clk_assigned_rates_test_param clk_assigned_sscs_skips_test_p
*/
.desc = "provider assigned-clocks null phandle",
TEST_PARAM_OVERLAY(kunit_clk_assigned_sscs_null),
.sscs = {50000, 60000, 3},
.sscs = {50000, 600, 3},
},
{
/*
@ -3573,7 +3573,7 @@ static const struct clk_assigned_rates_test_param clk_assigned_sscs_skips_test_p
*/
.desc = "consumer assigned-clocks null phandle",
TEST_PARAM_OVERLAY(kunit_clk_assigned_sscs_null_consumer),
.sscs = {50000, 60000, 3},
.sscs = {50000, 600, 3},
.consumer_test = true,
},
};
@ -3738,11 +3738,149 @@ static struct kunit_suite clk_hw_get_dev_of_node_test_suite = {
.test_cases = clk_hw_get_dev_of_node_test_cases,
};
static const struct clk_init_data clk_parse_clkspec_1_init_data = {
.name = "clk_parse_clkspec_1",
.ops = &empty_clk_ops,
};
static const struct clk_init_data clk_parse_clkspec_2_init_data = {
.name = "clk_parse_clkspec_2",
.ops = &empty_clk_ops,
};
struct clk_parse_clkspec_ctx {
struct device_node *cons_np;
};
static int clk_parse_clkspec_init(struct kunit *test)
{
struct device_node *prov1_np, *prov2_np;
struct clk_parse_clkspec_ctx *ctx;
struct clk_hw *hw1, *hw2;
ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
test->priv = ctx;
KUNIT_ASSERT_EQ(test, 0, of_overlay_apply_kunit(test, kunit_clk_parse_clkspec));
/* Register provider 1 */
hw1 = kunit_kzalloc(test, sizeof(*hw1), GFP_KERNEL);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, hw1);
hw1->init = &clk_parse_clkspec_1_init_data;
prov1_np = of_find_compatible_node(NULL, NULL, "test,clock-provider1");
KUNIT_ASSERT_NOT_NULL(test, prov1_np);
of_node_put_kunit(test, prov1_np);
KUNIT_ASSERT_EQ(test, 0, of_clk_hw_register_kunit(test, prov1_np, hw1));
KUNIT_ASSERT_EQ(test, 0, of_clk_add_hw_provider_kunit(test, prov1_np, of_clk_hw_simple_get, hw1));
/* Register provider 2 */
hw2 = kunit_kzalloc(test, sizeof(*hw2), GFP_KERNEL);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, hw2);
hw2->init = &clk_parse_clkspec_2_init_data;
prov2_np = of_find_compatible_node(NULL, NULL, "test,clock-provider2");
KUNIT_ASSERT_NOT_NULL(test, prov2_np);
of_node_put_kunit(test, prov2_np);
KUNIT_ASSERT_EQ(test, 0, of_clk_hw_register_kunit(test, prov2_np, hw2));
KUNIT_ASSERT_EQ(test, 0, of_clk_add_hw_provider_kunit(test, prov2_np, of_clk_hw_simple_get, hw2));
ctx->cons_np = of_find_compatible_node(NULL, NULL, "test,clock-consumer");
KUNIT_ASSERT_NOT_NULL(test, ctx->cons_np);
of_node_put_kunit(test, ctx->cons_np);
return 0;
}
/* Test DT phandle lookups using correct index or name succeed */
static void clk_parse_clkspec_with_correct_index_and_name(struct kunit *test)
{
struct clk_parse_clkspec_ctx *ctx = test->priv;
struct clk_hw *hw1, *hw2, *hw3, *hw4;
/* Get clocks by index */
hw1 = of_clk_get_hw(ctx->cons_np, 0, NULL);
KUNIT_EXPECT_NOT_ERR_OR_NULL(test, hw1);
hw2 = of_clk_get_hw(ctx->cons_np, 1, NULL);
KUNIT_EXPECT_NOT_ERR_OR_NULL(test, hw2);
KUNIT_EXPECT_PTR_NE(test, hw1, hw2);
/* Get clocks by name */
hw3 = of_clk_get_hw(ctx->cons_np, 0, "first_clock");
KUNIT_EXPECT_NOT_ERR_OR_NULL(test, hw3);
KUNIT_EXPECT_PTR_EQ(test, hw1, hw3);
hw4 = of_clk_get_hw(ctx->cons_np, 0, "second_clock");
KUNIT_EXPECT_NOT_ERR_OR_NULL(test, hw4);
KUNIT_EXPECT_PTR_EQ(test, hw2, hw4);
}
/* Test DT phandle lookups using wrong index or name fail */
static void clk_parse_clkspec_with_incorrect_index_and_name(struct kunit *test)
{
struct clk_parse_clkspec_ctx *ctx = test->priv;
struct clk_hw *hw;
/* Get clock by index */
hw = of_clk_get_hw(ctx->cons_np, 2, NULL);
KUNIT_EXPECT_TRUE(test, IS_ERR(hw));
/* Get clock by name */
hw = of_clk_get_hw(ctx->cons_np, 0, "third_clock");
KUNIT_EXPECT_TRUE(test, IS_ERR(hw));
}
/*
* Verify that of_clk_get_parent_name() returns the correct clock name when
* looking up by index through the consumer's clocks property.
*/
static void of_clk_get_parent_name_gets_parent_name(struct kunit *test)
{
struct clk_parse_clkspec_ctx *ctx = test->priv;
const char *expected_name = "clk_parse_clkspec_1";
KUNIT_EXPECT_STREQ(test, expected_name,
of_clk_get_parent_name(ctx->cons_np, 0));
}
static void of_clk_get_hw_maps_thru_nexus(struct kunit *test)
{
struct clk_parse_clkspec_ctx *ctx = test->priv;
struct clk_hw *expected;
struct device_node *np;
np = clk_of_find_node_by_name_kunit(test, NULL, "kunit-clock-nexus-child");
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, np);
expected = of_clk_get_hw(ctx->cons_np, 1, NULL);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, expected);
KUNIT_EXPECT_PTR_EQ(test, expected, of_clk_get_hw(np, 0, NULL));
}
static struct kunit_case clk_parse_clkspec_test_cases[] = {
KUNIT_CASE(clk_parse_clkspec_with_correct_index_and_name),
KUNIT_CASE(clk_parse_clkspec_with_incorrect_index_and_name),
KUNIT_CASE(of_clk_get_parent_name_gets_parent_name),
KUNIT_CASE(of_clk_get_hw_maps_thru_nexus),
{}
};
/* Test suite to verify clk_parse_clkspec() */
static struct kunit_suite clk_parse_clkspec_test_suite = {
.name = "clk_parse_clkspec",
.init = clk_parse_clkspec_init,
.test_cases = clk_parse_clkspec_test_cases,
};
kunit_test_suites(
&clk_assigned_rates_suite,
&clk_assigned_sscs_suite,
&clk_hw_get_dev_of_node_test_suite,
&clk_parse_clkspec_test_suite,
&clk_leaf_mux_set_rate_parent_test_suite,
&clk_test_suite,
&clk_multiple_parents_mux_test_suite,
@ -3760,4 +3898,5 @@ kunit_test_suites(
&clk_uncached_test_suite,
);
MODULE_DESCRIPTION("Kunit tests for clk framework");
MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING");
MODULE_LICENSE("GPL v2");

View File

@ -88,7 +88,7 @@ static struct clk *__clk_get_sys(struct device *dev, const char *dev_id,
{
struct clk_hw *hw = clk_find_hw(dev_id, con_id);
return clk_hw_create_clk(dev, hw, dev_id, con_id);
return clk_hw_create_clk(dev, hw, dev_id, con_id, NULL);
}
struct clk *clk_get_sys(const char *dev_id, const char *con_id)
@ -105,7 +105,7 @@ struct clk *clk_get(struct device *dev, const char *con_id)
if (dev && dev->of_node) {
hw = of_clk_get_hw(dev->of_node, 0, con_id);
if (!IS_ERR(hw) || PTR_ERR(hw) == -EPROBE_DEFER)
return clk_hw_create_clk(dev, hw, dev_id, con_id);
return clk_hw_create_clk(dev, hw, dev_id, con_id, NULL);
}
return __clk_get_sys(dev, dev_id, con_id);

View File

@ -0,0 +1,10 @@
# SPDX-License-Identifier: GPL-2.0-only
config COMMON_CLK_DAVINCI
bool "Clock drivers for TI DaVinci SoCs"
depends on ARCH_DAVINCI || COMPILE_TEST
depends on HAS_IOMEM
select REGMAP_MMIO
select RESET_CONTROLLER
default ARCH_DAVINCI
help
Support for the clock controllers found on TI DaVinci SoCs.

View File

@ -1,11 +1,9 @@
# SPDX-License-Identifier: GPL-2.0
ifeq ($(CONFIG_COMMON_CLK), y)
obj-$(CONFIG_ARCH_DAVINCI_DA8XX) += da8xx-cfgchip.o
obj-y += da8xx-cfgchip.o
obj-y += pll.o
obj-$(CONFIG_ARCH_DAVINCI_DA850) += pll-da850.o
obj-y += pll-da850.o
obj-y += psc.o
obj-$(CONFIG_ARCH_DAVINCI_DA850) += psc-da850.o
endif
obj-y += psc-da850.o

View File

@ -91,7 +91,7 @@ da8xx_cfgchip_gate_clk_register(struct device *dev,
struct clk *parent;
const char *parent_name;
struct da8xx_cfgchip_gate_clk *gate;
struct clk_init_data init;
struct clk_init_data init = {};
int ret;
parent = devm_clk_get(dev, NULL);
@ -241,7 +241,7 @@ da8xx_cfgchip_mux_clk_register(struct device *dev,
{
const char * const parent_names[] = { info->parent0, info->parent1 };
struct da8xx_cfgchip_mux_clk *mux;
struct clk_init_data init;
struct clk_init_data init = {};
int ret;
mux = devm_kzalloc(dev, sizeof(*mux), GFP_KERNEL);

View File

@ -371,7 +371,7 @@ struct clk *davinci_pll_clk_register(struct device *dev,
char pllout_name[MAX_NAME_SIZE];
char postdiv_name[MAX_NAME_SIZE];
char pllen_name[MAX_NAME_SIZE];
struct clk_init_data init;
struct clk_init_data init = {};
struct davinci_pll_clk *pllout;
struct davinci_pllen_clk *pllen;
struct clk *oscin_clk = NULL;

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