1
0
mirror of https://xff.cz/git/u-boot/ synced 2025-09-05 10:42:10 +02:00
Clock patches for v2022.04-rc2

This has an assortment of cleanups and the occasional bugfix. Also present
is the addition of the clock subsystem documentation to HTML docs.

CI: https://source.denx.de/u-boot/custodians/u-boot-clk/-/pipelines/11075
This commit is contained in:
Tom Rini
2022-02-25 11:21:32 -05:00
17 changed files with 394 additions and 399 deletions

View File

@@ -99,20 +99,6 @@ static int do_clk_dump(struct cmd_tbl *cmdtp, int flag, int argc,
} }
#if CONFIG_IS_ENABLED(DM) && CONFIG_IS_ENABLED(CLK) #if CONFIG_IS_ENABLED(DM) && CONFIG_IS_ENABLED(CLK)
struct udevice *clk_lookup(const char *name)
{
int i = 0;
struct udevice *dev;
do {
uclass_get_device(UCLASS_CLK, i++, &dev);
if (!strcmp(name, dev->name))
return dev;
} while (dev);
return NULL;
}
static int do_clk_setfreq(struct cmd_tbl *cmdtp, int flag, int argc, static int do_clk_setfreq(struct cmd_tbl *cmdtp, int flag, int argc,
char *const argv[]) char *const argv[])
{ {
@@ -120,16 +106,17 @@ static int do_clk_setfreq(struct cmd_tbl *cmdtp, int flag, int argc,
s32 freq; s32 freq;
struct udevice *dev; struct udevice *dev;
if (argc != 3)
return CMD_RET_USAGE;
freq = dectoul(argv[2], NULL); freq = dectoul(argv[2], NULL);
dev = clk_lookup(argv[1]); if (!uclass_get_device_by_name(UCLASS_CLK, argv[1], &dev))
if (dev)
clk = dev_get_clk_ptr(dev); clk = dev_get_clk_ptr(dev);
if (!clk) { if (!clk) {
printf("clock '%s' not found.\n", argv[1]); printf("clock '%s' not found.\n", argv[1]);
return -EINVAL; return CMD_RET_FAILURE;
} }
freq = clk_set_rate(clk, freq); freq = clk_set_rate(clk, freq);
@@ -173,7 +160,7 @@ static int do_clk(struct cmd_tbl *cmdtp, int flag, int argc,
#ifdef CONFIG_SYS_LONGHELP #ifdef CONFIG_SYS_LONGHELP
static char clk_help_text[] = static char clk_help_text[] =
"dump - Print clock frequencies\n" "dump - Print clock frequencies\n"
"setfreq [clk] [freq] - Set clock frequency"; "clk setfreq [clk] [freq] - Set clock frequency";
#endif #endif
U_BOOT_CMD(clk, 4, 1, do_clk, "CLK sub-system", clk_help_text); U_BOOT_CMD(clk, 4, 1, do_clk, "CLK sub-system", clk_help_text);

View File

@@ -157,7 +157,7 @@ CONFIG_REGMAP=y
CONFIG_AXI=y CONFIG_AXI=y
CONFIG_IHS_AXI=y CONFIG_IHS_AXI=y
CONFIG_CLK=y CONFIG_CLK=y
CONFIG_ICS8N3QV01=y CONFIG_CLK_ICS8N3QV01=y
CONFIG_CPU=y CONFIG_CPU=y
CONFIG_CPU_MPC83XX=y CONFIG_CPU_MPC83XX=y
CONFIG_SYS_BR0_PRELIM_BOOL=y CONFIG_SYS_BR0_PRELIM_BOOL=y

19
doc/api/clk.rst Normal file
View File

@@ -0,0 +1,19 @@
.. SPDX-License-Identifier: GPL-2.0+
Clock API
=========
.. kernel-doc:: include/clk.h
:doc: Overview
Client API
----------
.. kernel-doc:: include/clk.h
:internal:
Driver API
----------
.. kernel-doc:: include/clk-uclass.h
:internal:

View File

@@ -6,6 +6,7 @@ U-Boot API documentation
.. toctree:: .. toctree::
:maxdepth: 2 :maxdepth: 2
clk
dfu dfu
dm dm
efi efi

View File

@@ -30,22 +30,6 @@ config TPL_CLK
setting up clocks within TPL, and allows the same drivers to be setting up clocks within TPL, and allows the same drivers to be
used as U-Boot proper. used as U-Boot proper.
config CLK_BCM6345
bool "Clock controller driver for BCM6345"
depends on CLK && ARCH_BMIPS
default y
help
This clock driver adds support for enabling and disabling peripheral
clocks on BCM6345 SoCs. HW has no rate changing capabilities.
config CLK_BOSTON
def_bool y if TARGET_BOSTON
depends on CLK
select REGMAP
select SYSCON
help
Enable this to support the clocks
config SPL_CLK_CCF config SPL_CLK_CCF
bool "SPL Common Clock Framework [CCF] support " bool "SPL Common Clock Framework [CCF] support "
depends on SPL depends on SPL
@@ -73,6 +57,37 @@ config CLK_COMPOSITE_CCF
Enable this option if you want to (re-)use the Linux kernel's Common Enable this option if you want to (re-)use the Linux kernel's Common
Clock Framework [CCF] composite code in U-Boot's clock driver. Clock Framework [CCF] composite code in U-Boot's clock driver.
config CLK_BCM6345
bool "Clock controller driver for BCM6345"
depends on CLK && ARCH_BMIPS
default y
help
This clock driver adds support for enabling and disabling peripheral
clocks on BCM6345 SoCs. HW has no rate changing capabilities.
config CLK_BOSTON
def_bool y if TARGET_BOSTON
depends on CLK
select REGMAP
select SYSCON
help
Enable this to support the clocks
config CLK_CDCE9XX
bool "Enable CDCD9XX clock driver"
depends on CLK
help
Enable the clock synthesizer driver for CDCE913/925/937/949
series of chips.
config CLK_ICS8N3QV01
bool "Enable ICS8N3QV01 VCXO driver"
depends on CLK
help
Support for the ICS8N3QV01 Quad-Frequency VCXO (Voltage-Controlled
Crystal Oscillator). The output frequency can be programmed via an
I2C interface.
config CLK_INTEL config CLK_INTEL
bool "Enable clock driver for Intel x86" bool "Enable clock driver for Intel x86"
depends on CLK && X86 depends on CLK && X86
@@ -83,6 +98,25 @@ config CLK_INTEL
set up by U-Boot itself but only statically. Thus the driver does not set up by U-Boot itself but only statically. Thus the driver does not
support changing clock rates, only querying them. support changing clock rates, only querying them.
config CLK_K210
bool "Clock support for Kendryte K210"
depends on CLK
help
This enables support clock driver for Kendryte K210 platforms.
config CLK_K210_SET_RATE
bool "Enable setting the Kendryte K210 PLL rate"
depends on CLK_K210
help
Add functionality to calculate new rates for K210 PLLs. Enabling this
feature adds around 1K to U-Boot's final size.
config CLK_MPC83XX
bool "Enable MPC83xx clock driver"
depends on CLK
help
Support for the clock driver of the MPC83xx series of SoCs.
config CLK_OCTEON config CLK_OCTEON
bool "Clock controller driver for Marvell MIPS Octeon" bool "Clock controller driver for Marvell MIPS Octeon"
depends on CLK && ARCH_OCTEON depends on CLK && ARCH_OCTEON
@@ -90,6 +124,22 @@ config CLK_OCTEON
help help
Enable this to support the clocks on Octeon MIPS platforms. Enable this to support the clocks on Octeon MIPS platforms.
config SANDBOX_CLK_CCF
bool "Sandbox Common Clock Framework [CCF] support "
depends on SANDBOX
select CLK_CCF
help
Enable this option if you want to test the Linux kernel's Common
Clock Framework [CCF] code in U-Boot's Sandbox clock driver.
config CLK_SCMI
bool "Enable SCMI clock driver"
depends on SCMI_FIRMWARE
help
Enable this option if you want to support clock devices exposed
by a SCMI agent based on SCMI clock protocol communication
with a SCMI server.
config CLK_STM32F config CLK_STM32F
bool "Enable clock driver support for STM32F family" bool "Enable clock driver support for STM32F family"
depends on CLK && (STM32F7 || STM32F4) depends on CLK && (STM32F7 || STM32F4)
@@ -98,6 +148,14 @@ config CLK_STM32F
This clock driver adds support for RCC clock management This clock driver adds support for RCC clock management
for STM32F4 and STM32F7 SoCs. for STM32F4 and STM32F7 SoCs.
config CLK_STM32MP1
bool "Enable RCC clock driver for STM32MP1"
depends on ARCH_STM32MP && CLK
default y
help
Enable the STM32 clock (RCC) driver. Enable support for
manipulating STM32MP1's on-SoC clocks.
config CLK_HSDK config CLK_HSDK
bool "Enable cgu clock driver for HSDK boards" bool "Enable cgu clock driver for HSDK boards"
depends on CLK && TARGET_HSDK depends on CLK && TARGET_HSDK
@@ -105,6 +163,15 @@ config CLK_HSDK
Enable this to support the cgu clocks on Synopsys ARC HSDK and Enable this to support the cgu clocks on Synopsys ARC HSDK and
Synopsys ARC HSDK-4xD boards Synopsys ARC HSDK-4xD boards
config CLK_VERSACLOCK
tristate "Enable VersaClock 5/6 devices"
depends on CLK
depends on CLK_CCF
depends on OF_CONTROL
help
This driver supports the IDT VersaClock 5 and VersaClock 6
programmable clock generators.
config CLK_VERSAL config CLK_VERSAL
bool "Enable clock driver support for Versal" bool "Enable clock driver support for Versal"
depends on ARCH_VERSAL depends on ARCH_VERSAL
@@ -120,14 +187,6 @@ config CLK_VEXPRESS_OSC
This clock driver adds support for clock generators present on This clock driver adds support for clock generators present on
Arm Versatile Express platforms. Arm Versatile Express platforms.
config CLK_ZYNQ
bool "Enable clock driver support for Zynq"
depends on CLK && ARCH_ZYNQ
default y
help
This clock driver adds support for clock related settings for
Zynq platform.
config CLK_XLNX_CLKWZRD config CLK_XLNX_CLKWZRD
bool "Xilinx Clocking Wizard" bool "Xilinx Clocking Wizard"
depends on CLK depends on CLK
@@ -139,6 +198,14 @@ config CLK_XLNX_CLKWZRD
set_duty_cycle API, this driver only supports set_rate to modify set_duty_cycle API, this driver only supports set_rate to modify
the frequency. the frequency.
config CLK_ZYNQ
bool "Enable clock driver support for Zynq"
depends on CLK && ARCH_ZYNQ
default y
help
This clock driver adds support for clock related settings for
Zynq platform.
config CLK_ZYNQMP config CLK_ZYNQMP
bool "Enable clock driver support for ZynqMP" bool "Enable clock driver support for ZynqMP"
depends on ARCH_ZYNQMP depends on ARCH_ZYNQMP
@@ -147,42 +214,6 @@ config CLK_ZYNQMP
This clock driver adds support for clock realted settings for This clock driver adds support for clock realted settings for
ZynqMP platform. ZynqMP platform.
config CLK_STM32MP1
bool "Enable RCC clock driver for STM32MP1"
depends on ARCH_STM32MP && CLK
default y
help
Enable the STM32 clock (RCC) driver. Enable support for
manipulating STM32MP1's on-SoC clocks.
config CLK_CDCE9XX
bool "Enable CDCD9XX clock driver"
depends on CLK
help
Enable the clock synthesizer driver for CDCE913/925/937/949
series of chips.
config CLK_SCMI
bool "Enable SCMI clock driver"
depends on SCMI_FIRMWARE
help
Enable this option if you want to support clock devices exposed
by a SCMI agent based on SCMI clock protocol communication
with a SCMI server.
config CLK_K210
bool "Clock support for Kendryte K210"
depends on CLK
help
This enables support clock driver for Kendryte K210 platforms.
config CLK_K210_SET_RATE
bool "Enable setting the Kendryte K210 PLL rate"
depends on CLK_K210
help
Add functionality to calculate new rates for K210 PLLs. Enabling this
feature adds around 1K to U-Boot's final size.
source "drivers/clk/analogbits/Kconfig" source "drivers/clk/analogbits/Kconfig"
source "drivers/clk/at91/Kconfig" source "drivers/clk/at91/Kconfig"
source "drivers/clk/exynos/Kconfig" source "drivers/clk/exynos/Kconfig"
@@ -198,35 +229,4 @@ source "drivers/clk/tegra/Kconfig"
source "drivers/clk/ti/Kconfig" source "drivers/clk/ti/Kconfig"
source "drivers/clk/uniphier/Kconfig" source "drivers/clk/uniphier/Kconfig"
config ICS8N3QV01
bool "Enable ICS8N3QV01 VCXO driver"
depends on CLK
help
Support for the ICS8N3QV01 Quad-Frequency VCXO (Voltage-Controlled
Crystal Oscillator). The output frequency can be programmed via an
I2C interface.
config CLK_MPC83XX
bool "Enable MPC83xx clock driver"
depends on CLK
help
Support for the clock driver of the MPC83xx series of SoCs.
config SANDBOX_CLK_CCF
bool "Sandbox Common Clock Framework [CCF] support "
depends on SANDBOX
select CLK_CCF
help
Enable this option if you want to test the Linux kernel's Common
Clock Framework [CCF] code in U-Boot's Sandbox clock driver.
config CLK_VERSACLOCK
tristate "Enable VersaClock 5/6 devices"
depends on CLK
depends on CLK_CCF
depends on OF_CONTROL
help
This driver supports the IDT VersaClock 5 and VersaClock 6
programmable clock generators.
endmenu endmenu

View File

@@ -15,41 +15,41 @@ obj-y += analogbits/
obj-y += imx/ obj-y += imx/
obj-y += tegra/ obj-y += tegra/
obj-y += ti/ obj-y += ti/
obj-$(CONFIG_$(SPL_TPL_)CLK_INTEL) += intel/
obj-$(CONFIG_ARCH_ASPEED) += aspeed/ obj-$(CONFIG_ARCH_ASPEED) += aspeed/
obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/ obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/
obj-$(CONFIG_ARCH_MTMIPS) += mtmips/
obj-$(CONFIG_ARCH_MESON) += meson/ obj-$(CONFIG_ARCH_MESON) += meson/
obj-$(CONFIG_ARCH_MTMIPS) += mtmips/
obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/ obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/
obj-$(CONFIG_ARCH_SOCFPGA) += altera/ obj-$(CONFIG_ARCH_SOCFPGA) += altera/
obj-$(CONFIG_ARCH_SUNXI) += sunxi/
obj-$(CONFIG_CLK_AT91) += at91/ obj-$(CONFIG_CLK_AT91) += at91/
obj-$(CONFIG_CLK_MVEBU) += mvebu/
obj-$(CONFIG_CLK_BCM6345) += clk_bcm6345.o obj-$(CONFIG_CLK_BCM6345) += clk_bcm6345.o
obj-$(CONFIG_CLK_BOSTON) += clk_boston.o obj-$(CONFIG_CLK_BOSTON) += clk_boston.o
obj-$(CONFIG_CLK_CDCE9XX) += clk-cdce9xx.o
obj-$(CONFIG_CLK_EXYNOS) += exynos/ obj-$(CONFIG_CLK_EXYNOS) += exynos/
obj-$(CONFIG_$(SPL_TPL_)CLK_INTEL) += intel/
obj-$(CONFIG_CLK_HSDK) += clk-hsdk-cgu.o obj-$(CONFIG_CLK_HSDK) += clk-hsdk-cgu.o
obj-$(CONFIG_CLK_K210) += clk_kendryte.o obj-$(CONFIG_CLK_K210) += clk_kendryte.o
obj-$(CONFIG_CLK_MPC83XX) += mpc83xx_clk.o obj-$(CONFIG_CLK_MPC83XX) += mpc83xx_clk.o
obj-$(CONFIG_CLK_MPFS) += microchip/ obj-$(CONFIG_CLK_MPFS) += microchip/
obj-$(CONFIG_CLK_MVEBU) += mvebu/
obj-$(CONFIG_CLK_OCTEON) += clk_octeon.o obj-$(CONFIG_CLK_OCTEON) += clk_octeon.o
obj-$(CONFIG_CLK_OWL) += owl/ obj-$(CONFIG_CLK_OWL) += owl/
obj-$(CONFIG_CLK_RENESAS) += renesas/ obj-$(CONFIG_CLK_RENESAS) += renesas/
obj-$(CONFIG_CLK_SCMI) += clk_scmi.o obj-$(CONFIG_CLK_SCMI) += clk_scmi.o
obj-$(CONFIG_CLK_SIFIVE) += sifive/ obj-$(CONFIG_CLK_SIFIVE) += sifive/
obj-$(CONFIG_ARCH_SUNXI) += sunxi/
obj-$(CONFIG_CLK_STM32F) += clk_stm32f.o obj-$(CONFIG_CLK_STM32F) += clk_stm32f.o
obj-$(CONFIG_CLK_STM32MP1) += clk_stm32mp1.o obj-$(CONFIG_CLK_STM32MP1) += clk_stm32mp1.o
obj-$(CONFIG_CLK_UNIPHIER) += uniphier/ obj-$(CONFIG_CLK_UNIPHIER) += uniphier/
obj-$(CONFIG_CLK_VERSACLOCK) += clk_versaclock.o
obj-$(CONFIG_CLK_VERSAL) += clk_versal.o
obj-$(CONFIG_CLK_VEXPRESS_OSC) += clk_vexpress_osc.o obj-$(CONFIG_CLK_VEXPRESS_OSC) += clk_vexpress_osc.o
obj-$(CONFIG_CLK_XLNX_CLKWZRD) += clk-xlnx-clock-wizard.o
obj-$(CONFIG_CLK_ZYNQ) += clk_zynq.o obj-$(CONFIG_CLK_ZYNQ) += clk_zynq.o
obj-$(CONFIG_CLK_ZYNQMP) += clk_zynqmp.o obj-$(CONFIG_CLK_ZYNQMP) += clk_zynqmp.o
obj-$(CONFIG_CLK_XLNX_CLKWZRD) += clk-xlnx-clock-wizard.o obj-$(CONFIG_CLK_ICS8N3QV01) += ics8n3qv01.o
obj-$(CONFIG_ICS8N3QV01) += ics8n3qv01.o
obj-$(CONFIG_MACH_PIC32) += clk_pic32.o obj-$(CONFIG_MACH_PIC32) += clk_pic32.o
obj-$(CONFIG_SANDBOX_CLK_CCF) += clk_sandbox_ccf.o
obj-$(CONFIG_SANDBOX) += clk_sandbox.o obj-$(CONFIG_SANDBOX) += clk_sandbox.o
obj-$(CONFIG_SANDBOX) += clk_sandbox_test.o obj-$(CONFIG_SANDBOX) += clk_sandbox_test.o
obj-$(CONFIG_SANDBOX_CLK_CCF) += clk_sandbox_ccf.o
obj-$(CONFIG_STM32H7) += clk_stm32h7.o obj-$(CONFIG_STM32H7) += clk_stm32h7.o
obj-$(CONFIG_CLK_VERSAL) += clk_versal.o
obj-$(CONFIG_CLK_CDCE9XX) += clk-cdce9xx.o
obj-$(CONFIG_CLK_VERSACLOCK) += clk_versaclock.o

View File

@@ -86,19 +86,13 @@ static int cdce9xx_reg_write(struct udevice *dev, u8 addr, u8 val)
return ret; return ret;
} }
static int cdce9xx_clk_of_xlate(struct clk *clk, static int cdce9xx_clk_request(struct clk *clk)
struct ofnode_phandle_args *args)
{ {
struct cdce9xx_clk_data *data = dev_get_priv(clk->dev); struct cdce9xx_clk_data *data = dev_get_priv(clk->dev);
if (args->args_count != 1) if (clk->id > data->chip->num_outputs)
return -EINVAL; return -EINVAL;
if (args->args[0] > data->chip->num_outputs)
return -EINVAL;
clk->id = args->args[0];
return 0; return 0;
} }
@@ -241,7 +235,7 @@ static const struct udevice_id cdce9xx_clk_of_match[] = {
}; };
static const struct clk_ops cdce9xx_clk_ops = { static const struct clk_ops cdce9xx_clk_ops = {
.of_xlate = cdce9xx_clk_of_xlate, .request = cdce9xx_clk_request,
.get_rate = cdce9xx_clk_get_rate, .get_rate = cdce9xx_clk_get_rate,
.set_rate = cdce9xx_clk_set_rate, .set_rate = cdce9xx_clk_set_rate,
}; };

View File

@@ -432,17 +432,6 @@ int clk_get_by_name_nodev(ofnode node, const char *name, struct clk *clk)
return clk_get_by_index_nodev(node, index, clk); return clk_get_by_index_nodev(node, index, clk);
} }
int clk_get_optional_nodev(ofnode node, const char *name, struct clk *clk)
{
int ret;
ret = clk_get_by_name_nodev(node, name, clk);
if (ret == -ENODATA)
return 0;
return ret;
}
int clk_release_all(struct clk *clk, int count) int clk_release_all(struct clk *clk, int count)
{ {
int i, ret; int i, ret;
@@ -652,7 +641,7 @@ int clk_enable(struct clk *clk)
return 0; return 0;
} }
if (clkp->dev->parent && if (clkp->dev->parent &&
device_get_uclass_id(clkp->dev) == UCLASS_CLK) { device_get_uclass_id(clkp->dev->parent) == UCLASS_CLK) {
ret = clk_enable(dev_get_clk_ptr(clkp->dev->parent)); ret = clk_enable(dev_get_clk_ptr(clkp->dev->parent));
if (ret) { if (ret) {
printf("Enable %s failed\n", printf("Enable %s failed\n",
@@ -726,7 +715,7 @@ int clk_disable(struct clk *clk)
} }
if (clkp && clkp->dev->parent && if (clkp && clkp->dev->parent &&
device_get_uclass_id(clkp->dev) == UCLASS_CLK) { device_get_uclass_id(clkp->dev->parent) == UCLASS_CLK) {
ret = clk_disable(dev_get_clk_ptr(clkp->dev->parent)); ret = clk_disable(dev_get_clk_ptr(clkp->dev->parent));
if (ret) { if (ret) {
printf("Disable %s failed\n", printf("Disable %s failed\n",
@@ -823,16 +812,6 @@ struct clk *devm_clk_get(struct udevice *dev, const char *id)
return clk; return clk;
} }
struct clk *devm_clk_get_optional(struct udevice *dev, const char *id)
{
struct clk *clk = devm_clk_get(dev, id);
if (PTR_ERR(clk) == -ENODATA)
return NULL;
return clk;
}
void devm_clk_put(struct udevice *dev, struct clk *clk) void devm_clk_put(struct udevice *dev, struct clk *clk)
{ {
int rc; int rc;

View File

@@ -618,24 +618,6 @@ static int vc5_clk_out_set_parent(struct vc5_driver_data *vc, u8 num, u8 index)
return vc5_update_bits(vc->i2c, VC5_OUT_DIV_CONTROL(num), mask, src); return vc5_update_bits(vc->i2c, VC5_OUT_DIV_CONTROL(num), mask, src);
} }
/*
* The device references to the Versaclock point to the head, so xlate needs to
* redirect it to clk_out[idx]
*/
static int vc5_clk_out_xlate(struct clk *hw, struct ofnode_phandle_args *args)
{
unsigned int idx = args->args[0];
if (args->args_count != 1) {
debug("Invalid args_count: %d\n", args->args_count);
return -EINVAL;
}
hw->id = idx;
return 0;
}
static unsigned long vc5_clk_out_set_rate(struct clk *hw, unsigned long rate) static unsigned long vc5_clk_out_set_rate(struct clk *hw, unsigned long rate)
{ {
struct udevice *dev; struct udevice *dev;
@@ -671,7 +653,6 @@ static const struct clk_ops vc5_clk_out_sel_ops = {
static const struct clk_ops vc5_clk_ops = { static const struct clk_ops vc5_clk_ops = {
.enable = vc5_clk_out_prepare, .enable = vc5_clk_out_prepare,
.disable = vc5_clk_out_unprepare, .disable = vc5_clk_out_unprepare,
.of_xlate = vc5_clk_out_xlate,
.set_rate = vc5_clk_out_set_rate, .set_rate = vc5_clk_out_set_rate,
.get_rate = vc5_clk_out_get_rate, .get_rate = vc5_clk_out_get_rate,
}; };

View File

@@ -472,8 +472,9 @@ static int zynq_clk_probe(struct udevice *dev)
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
sprintf(name, "gem%d_emio_clk", i); sprintf(name, "gem%d_emio_clk", i);
ret = clk_get_by_name(dev, name, &priv->gem_emio_clk[i]); ret = clk_get_by_name_optional(dev, name,
if (ret < 0 && ret != -ENODATA) { &priv->gem_emio_clk[i]);
if (ret) {
dev_err(dev, "failed to get %s clock\n", name); dev_err(dev, "failed to get %s clock\n", name);
return ret; return ret;
} }

View File

@@ -180,11 +180,6 @@ static ulong ics8n3qv01_set_rate(struct clk *clk, ulong fout)
return 0; return 0;
} }
static int ics8n3qv01_request(struct clk *clock)
{
return 0;
}
static ulong ics8n3qv01_get_rate(struct clk *clk) static ulong ics8n3qv01_get_rate(struct clk *clk)
{ {
struct ics8n3qv01_priv *priv = dev_get_priv(clk->dev); struct ics8n3qv01_priv *priv = dev_get_priv(clk->dev);
@@ -203,7 +198,6 @@ static int ics8n3qv01_disable(struct clk *clk)
} }
static const struct clk_ops ics8n3qv01_ops = { static const struct clk_ops ics8n3qv01_ops = {
.request = ics8n3qv01_request,
.get_rate = ics8n3qv01_get_rate, .get_rate = ics8n3qv01_get_rate,
.set_rate = ics8n3qv01_set_rate, .set_rate = ics8n3qv01_set_rate,
.enable = ics8n3qv01_enable, .enable = ics8n3qv01_enable,

View File

@@ -30,14 +30,6 @@ static int tegra_car_clk_request(struct clk *clk)
return 0; return 0;
} }
static int tegra_car_clk_free(struct clk *clk)
{
debug("%s(clk=%p) (dev=%p, id=%lu)\n", __func__, clk, clk->dev,
clk->id);
return 0;
}
static ulong tegra_car_clk_get_rate(struct clk *clk) static ulong tegra_car_clk_get_rate(struct clk *clk)
{ {
enum clock_id parent; enum clock_id parent;
@@ -82,7 +74,6 @@ static int tegra_car_clk_disable(struct clk *clk)
static struct clk_ops tegra_car_clk_ops = { static struct clk_ops tegra_car_clk_ops = {
.request = tegra_car_clk_request, .request = tegra_car_clk_request,
.rfree = tegra_car_clk_free,
.get_rate = tegra_car_clk_get_rate, .get_rate = tegra_car_clk_get_rate,
.set_rate = tegra_car_clk_set_rate, .set_rate = tegra_car_clk_set_rate,
.enable = tegra_car_clk_enable, .enable = tegra_car_clk_enable,

View File

@@ -64,18 +64,6 @@ static int ti_sci_clk_of_xlate(struct clk *clk,
return 0; return 0;
} }
static int ti_sci_clk_request(struct clk *clk)
{
debug("%s(clk=%p)\n", __func__, clk);
return 0;
}
static int ti_sci_clk_free(struct clk *clk)
{
debug("%s(clk=%p)\n", __func__, clk);
return 0;
}
static ulong ti_sci_clk_get_rate(struct clk *clk) static ulong ti_sci_clk_get_rate(struct clk *clk)
{ {
struct ti_sci_clk_data *data = dev_get_priv(clk->dev); struct ti_sci_clk_data *data = dev_get_priv(clk->dev);
@@ -208,8 +196,6 @@ static const struct udevice_id ti_sci_clk_of_match[] = {
static struct clk_ops ti_sci_clk_ops = { static struct clk_ops ti_sci_clk_ops = {
.of_xlate = ti_sci_clk_of_xlate, .of_xlate = ti_sci_clk_of_xlate,
.request = ti_sci_clk_request,
.rfree = ti_sci_clk_free,
.get_rate = ti_sci_clk_get_rate, .get_rate = ti_sci_clk_get_rate,
.set_rate = ti_sci_clk_set_rate, .set_rate = ti_sci_clk_set_rate,
.set_parent = ti_sci_clk_set_parent, .set_parent = ti_sci_clk_set_parent,

View File

@@ -723,13 +723,13 @@ static int mtk_tphy_probe(struct udevice *dev)
tphy->phys[index] = instance; tphy->phys[index] = instance;
index++; index++;
err = clk_get_optional_nodev(subnode, "ref", err = clk_get_by_name_nodev_optional(subnode, "ref",
&instance->ref_clk); &instance->ref_clk);
if (err) if (err)
return err; return err;
err = clk_get_optional_nodev(subnode, "da_ref", err = clk_get_by_name_nodev_optional(subnode, "da_ref",
&instance->da_ref_clk); &instance->da_ref_clk);
if (err) if (err)
return err; return err;
} }

View File

@@ -91,8 +91,8 @@ static int meson_rng_of_to_plat(struct udevice *dev)
return -ENODEV; return -ENODEV;
/* Get optional "core" clock */ /* Get optional "core" clock */
err = clk_get_by_name(dev, "core", &pdata->clk); err = clk_get_by_name_optional(dev, "core", &pdata->clk);
if (err && err != -ENODATA) if (err)
return err; return err;
return 0; return 0;

View File

@@ -16,96 +16,127 @@ struct ofnode_phandle_args;
/** /**
* struct clk_ops - The functions that a clock driver must implement. * struct clk_ops - The functions that a clock driver must implement.
* @of_xlate: Translate a client's device-tree (OF) clock specifier.
* @request: Request a translated clock.
* @rfree: Free a previously requested clock.
* @round_rate: Adjust a rate to the exact rate a clock can provide.
* @get_rate: Get current clock rate.
* @set_rate: Set current clock rate.
* @set_parent: Set current clock parent
* @enable: Enable a clock.
* @disable: Disable a clock.
*
* The individual methods are described more fully below.
*/ */
struct clk_ops { struct clk_ops {
/**
* of_xlate - Translate a client's device-tree (OF) clock specifier.
*
* The clock core calls this function as the first step in implementing
* a client's clk_get_by_*() call.
*
* If this function pointer is set to NULL, the clock core will use a
* default implementation, which assumes #clock-cells = <1>, and that
* the DT cell contains a simple integer clock ID.
*
* At present, the clock API solely supports device-tree. If this
* changes, other xxx_xlate() functions may be added to support those
* other mechanisms.
*
* @clock: The clock struct to hold the translation result.
* @args: The clock specifier values from device tree.
* @return 0 if OK, or a negative error code.
*/
int (*of_xlate)(struct clk *clock, int (*of_xlate)(struct clk *clock,
struct ofnode_phandle_args *args); struct ofnode_phandle_args *args);
/**
* request - Request a translated clock.
*
* The clock core calls this function as the second step in
* implementing a client's clk_get_by_*() call, following a successful
* xxx_xlate() call, or as the only step in implementing a client's
* clk_request() call.
*
* @clock: The clock struct to request; this has been fille in by
* a previoux xxx_xlate() function call, or by the caller
* of clk_request().
* @return 0 if OK, or a negative error code.
*/
int (*request)(struct clk *clock); int (*request)(struct clk *clock);
/**
* rfree - Free a previously requested clock.
*
* This is the implementation of the client clk_free() API.
*
* @clock: The clock to free.
* @return 0 if OK, or a negative error code.
*/
int (*rfree)(struct clk *clock); int (*rfree)(struct clk *clock);
/**
* round_rate() - Adjust a rate to the exact rate a clock can provide.
*
* @clk: The clock to manipulate.
* @rate: Desidered clock rate in Hz.
* @return rounded rate in Hz, or -ve error code.
*/
ulong (*round_rate)(struct clk *clk, ulong rate); ulong (*round_rate)(struct clk *clk, ulong rate);
/**
* get_rate() - Get current clock rate.
*
* @clk: The clock to query.
* @return clock rate in Hz, or -ve error code
*/
ulong (*get_rate)(struct clk *clk); ulong (*get_rate)(struct clk *clk);
/**
* set_rate() - Set current clock rate.
*
* @clk: The clock to manipulate.
* @rate: New clock rate in Hz.
* @return new rate, or -ve error code.
*/
ulong (*set_rate)(struct clk *clk, ulong rate); ulong (*set_rate)(struct clk *clk, ulong rate);
/**
* set_parent() - Set current clock parent
*
* @clk: The clock to manipulate.
* @parent: New clock parent.
* @return zero on success, or -ve error code.
*/
int (*set_parent)(struct clk *clk, struct clk *parent); int (*set_parent)(struct clk *clk, struct clk *parent);
/**
* enable() - Enable a clock.
*
* @clk: The clock to manipulate.
* @return zero on success, or -ve error code.
*/
int (*enable)(struct clk *clk); int (*enable)(struct clk *clk);
/**
* disable() - Disable a clock.
*
* @clk: The clock to manipulate.
* @return zero on success, or -ve error code.
*/
int (*disable)(struct clk *clk); int (*disable)(struct clk *clk);
}; };
#if 0 /* For documentation only */
/**
* of_xlate() - Translate a client's device-tree (OF) clock specifier.
* @clock: The clock struct to hold the translation result.
* @args: The clock specifier values from device tree.
*
* The clock core calls this function as the first step in implementing
* a client's clk_get_by_*() call.
*
* If this function pointer is set to NULL, the clock core will use a
* default implementation, which assumes #clock-cells = <1>, and that
* the DT cell contains a simple integer clock ID.
*
* At present, the clock API solely supports device-tree. If this
* changes, other xxx_xlate() functions may be added to support those
* other mechanisms.
*
* Return: 0 if OK, or a negative error code.
*/
int of_xlate(struct clk *clock, struct ofnode_phandle_args *args);
/**
* request() - Request a translated clock.
* @clock: The clock struct to request; this has been fille in by
* a previoux xxx_xlate() function call, or by the caller
* of clk_request().
*
* The clock core calls this function as the second step in
* implementing a client's clk_get_by_*() call, following a successful
* xxx_xlate() call, or as the only step in implementing a client's
* clk_request() call.
*
* Return: 0 if OK, or a negative error code.
*/
int request(struct clk *clock);
/**
* rfree() - Free a previously requested clock.
* @clock: The clock to free.
*
* This is the implementation of the client clk_free() API.
*
* Return: 0 if OK, or a negative error code.
*/
int rfree(struct clk *clock);
/**
* round_rate() - Adjust a rate to the exact rate a clock can provide.
* @clk: The clock to manipulate.
* @rate: Desidered clock rate in Hz.
*
* Return: rounded rate in Hz, or -ve error code.
*/
ulong round_rate(struct clk *clk, ulong rate);
/**
* get_rate() - Get current clock rate.
* @clk: The clock to query.
*
* Return: clock rate in Hz, or -ve error code
*/
ulong get_rate(struct clk *clk);
/**
* set_rate() - Set current clock rate.
* @clk: The clock to manipulate.
* @rate: New clock rate in Hz.
*
* Return: new rate, or -ve error code.
*/
ulong set_rate(struct clk *clk, ulong rate);
/**
* set_parent() - Set current clock parent
* @clk: The clock to manipulate.
* @parent: New clock parent.
*
* Return: zero on success, or -ve error code.
*/
int set_parent(struct clk *clk, struct clk *parent);
/**
* enable() - Enable a clock.
* @clk: The clock to manipulate.
*
* Return: zero on success, or -ve error code.
*/
int enable(struct clk *clk);
/**
* disable() - Disable a clock.
* @clk: The clock to manipulate.
*
* Return: zero on success, or -ve error code.
*/
int disable(struct clk *clk);
#endif
#endif #endif

View File

@@ -14,6 +14,8 @@
#include <linux/types.h> #include <linux/types.h>
/** /**
* DOC: Overview
*
* A clock is a hardware signal that oscillates autonomously at a specific * A clock is a hardware signal that oscillates autonomously at a specific
* frequency and duty cycle. Most hardware modules require one or more clock * frequency and duty cycle. Most hardware modules require one or more clock
* signal to drive their operation. Clock signals are typically generated * signal to drive their operation. Clock signals are typically generated
@@ -34,22 +36,22 @@ struct udevice;
/** /**
* struct clk - A handle to (allowing control of) a single clock. * struct clk - A handle to (allowing control of) a single clock.
* @dev: The device which implements the clock signal.
* @rate: The clock rate (in HZ).
* @flags: Flags used across common clock structure (e.g. %CLK_)
* Clock IP blocks specific flags (i.e. mux, div, gate, etc) are defined
* in struct's for those devices (e.g. &struct clk_mux).
* @enable_count: The number of times this clock has been enabled.
* @id: The clock signal ID within the provider.
* @data: An optional data field for scenarios where a single integer ID is not
* sufficient. If used, it can be populated through an .of_xlate op and
* processed during the various clock ops.
* *
* Clients provide storage for clock handles. The content of the structure is * Clients provide storage for clock handles. The content of the structure is
* managed solely by the clock API and clock drivers. A clock struct is * managed solely by the clock API and clock drivers. A clock struct is
* initialized by "get"ing the clock struct. The clock struct is passed to all * initialized by "get"ing the clock struct. The clock struct is passed to all
* other clock APIs to identify which clock signal to operate upon. * other clock APIs to identify which clock signal to operate upon.
* *
* @dev: The device which implements the clock signal.
* @rate: The clock rate (in HZ).
* @flags: Flags used across common clock structure (e.g. CLK_)
* Clock IP blocks specific flags (i.e. mux, div, gate, etc) are defined
* in struct's for those devices (e.g. struct clk_mux).
* @id: The clock signal ID within the provider.
* @data: An optional data field for scenarios where a single integer ID is not
* sufficient. If used, it can be populated through an .of_xlate op and
* processed during the various clock ops.
*
* Should additional information to identify and configure any clock signal * Should additional information to identify and configure any clock signal
* for any provider be required in the future, the struct could be expanded to * for any provider be required in the future, the struct could be expanded to
* either (a) add more fields to allow clock providers to store additional * either (a) add more fields to allow clock providers to store additional
@@ -72,15 +74,14 @@ struct clk {
/** /**
* struct clk_bulk - A handle to (allowing control of) a bulk of clocks. * struct clk_bulk - A handle to (allowing control of) a bulk of clocks.
* @clks: An array of clock handles.
* @count: The number of clock handles in the clks array.
* *
* Clients provide storage for the clock bulk. The content of the structure is * Clients provide storage for the clock bulk. The content of the structure is
* managed solely by the clock API. A clock bulk struct is * managed solely by the clock API. A clock bulk struct is
* initialized by "get"ing the clock bulk struct. * initialized by "get"ing the clock bulk struct.
* The clock bulk struct is passed to all other bulk clock APIs to apply * The clock bulk struct is passed to all other bulk clock APIs to apply
* the API to all the clock in the bulk struct. * the API to all the clock in the bulk struct.
*
* @clks: An array of clock handles.
* @count: The number of clock handles in the clks array.
*/ */
struct clk_bulk { struct clk_bulk {
struct clk *clks; struct clk *clks;
@@ -91,16 +92,19 @@ struct clk_bulk {
struct phandle_1_arg; struct phandle_1_arg;
/** /**
* clk_get_by_phandle() - Get a clock by its phandle information (of-platadata) * clk_get_by_phandle() - Get a clock by its phandle information (of-platadata)
* @dev: Device containing the phandle
* @cells: Phandle info
* @clk: A pointer to a clock struct to initialise
* *
* This function is used when of-platdata is enabled. * This function is used when of-platdata is enabled.
* *
* This looks up a clock using the phandle info. With dtoc, each phandle in the * This looks up a clock using the phandle info. With dtoc, each phandle in the
* 'clocks' property is transformed into an idx representing the device. For * 'clocks' property is transformed into an idx representing the device.
* example: * For example::
* *
* clocks = <&dpll_mpu_ck 23>; * clocks = <&dpll_mpu_ck 23>;
* *
* might result in: * might result in::
* *
* .clocks = {1, {23}},}, * .clocks = {1, {23}},},
* *
@@ -109,9 +113,6 @@ struct phandle_1_arg;
* this example it would return a clock containing the 'dpll_mpu_ck' device and * this example it would return a clock containing the 'dpll_mpu_ck' device and
* the clock ID 23. * the clock ID 23.
* *
* @dev: Device containing the phandle
* @cells: Phandle info
* @clock: A pointer to a clock struct to initialise
* Return: 0 if OK, or a negative error code. * Return: 0 if OK, or a negative error code.
*/ */
int clk_get_by_phandle(struct udevice *dev, const struct phandle_1_arg *cells, int clk_get_by_phandle(struct udevice *dev, const struct phandle_1_arg *cells,
@@ -119,6 +120,10 @@ int clk_get_by_phandle(struct udevice *dev, const struct phandle_1_arg *cells,
/** /**
* clk_get_by_index() - Get/request a clock by integer index. * clk_get_by_index() - Get/request a clock by integer index.
* @dev: The client device.
* @index: The index of the clock to request, within the client's list of
* clocks.
* @clk: A pointer to a clock struct to initialize.
* *
* This looks up and requests a clock. The index is relative to the client * This looks up and requests a clock. The index is relative to the client
* device; each device is assumed to have n clocks associated with it somehow, * device; each device is assumed to have n clocks associated with it somehow,
@@ -126,30 +131,26 @@ int clk_get_by_phandle(struct udevice *dev, const struct phandle_1_arg *cells,
* device clock indices to provider clocks may be via device-tree properties, * device clock indices to provider clocks may be via device-tree properties,
* board-provided mapping tables, or some other mechanism. * board-provided mapping tables, or some other mechanism.
* *
* @dev: The client device.
* @index: The index of the clock to request, within the client's list of
* clocks.
* @clock A pointer to a clock struct to initialize.
* Return: 0 if OK, or a negative error code. * Return: 0 if OK, or a negative error code.
*/ */
int clk_get_by_index(struct udevice *dev, int index, struct clk *clk); int clk_get_by_index(struct udevice *dev, int index, struct clk *clk);
/** /**
* clk_get_by_index_nodev - Get/request a clock by integer index * clk_get_by_index_nodev() - Get/request a clock by integer index without a
* without a device. * device.
*
* This is a version of clk_get_by_index() that does not use a device.
*
* @node: The client ofnode. * @node: The client ofnode.
* @index: The index of the clock to request, within the client's list of * @index: The index of the clock to request, within the client's list of
* clocks. * clocks.
* @clock A pointer to a clock struct to initialize. * @clk: A pointer to a clock struct to initialize.
*
* Return: 0 if OK, or a negative error code. * Return: 0 if OK, or a negative error code.
*/ */
int clk_get_by_index_nodev(ofnode node, int index, struct clk *clk); int clk_get_by_index_nodev(ofnode node, int index, struct clk *clk);
/** /**
* clk_get_bulk - Get/request all clocks of a device. * clk_get_bulk() - Get/request all clocks of a device.
* @dev: The client device.
* @bulk: A pointer to a clock bulk struct to initialize.
* *
* This looks up and requests all clocks of the client device; each device is * This looks up and requests all clocks of the client device; each device is
* assumed to have n clocks associated with it somehow, and this function finds * assumed to have n clocks associated with it somehow, and this function finds
@@ -157,14 +158,16 @@ int clk_get_by_index_nodev(ofnode node, int index, struct clk *clk);
* device clock indices to provider clocks may be via device-tree properties, * device clock indices to provider clocks may be via device-tree properties,
* board-provided mapping tables, or some other mechanism. * board-provided mapping tables, or some other mechanism.
* *
* @dev: The client device.
* @bulk A pointer to a clock bulk struct to initialize.
* Return: 0 if OK, or a negative error code. * Return: 0 if OK, or a negative error code.
*/ */
int clk_get_bulk(struct udevice *dev, struct clk_bulk *bulk); int clk_get_bulk(struct udevice *dev, struct clk_bulk *bulk);
/** /**
* clk_get_by_name - Get/request a clock by name. * clk_get_by_name() - Get/request a clock by name.
* @dev: The client device.
* @name: The name of the clock to request, within the client's list of
* clocks.
* @clk: A pointer to a clock struct to initialize.
* *
* This looks up and requests a clock. The name is relative to the client * This looks up and requests a clock. The name is relative to the client
* device; each device is assumed to have n clocks associated with it somehow, * device; each device is assumed to have n clocks associated with it somehow,
@@ -172,83 +175,71 @@ int clk_get_bulk(struct udevice *dev, struct clk_bulk *bulk);
* device clock names to provider clocks may be via device-tree properties, * device clock names to provider clocks may be via device-tree properties,
* board-provided mapping tables, or some other mechanism. * board-provided mapping tables, or some other mechanism.
* *
* @dev: The client device.
* @name: The name of the clock to request, within the client's list of
* clocks.
* @clock: A pointer to a clock struct to initialize.
* Return: 0 if OK, or a negative error code. * Return: 0 if OK, or a negative error code.
*/ */
int clk_get_by_name(struct udevice *dev, const char *name, struct clk *clk); int clk_get_by_name(struct udevice *dev, const char *name, struct clk *clk);
/** /**
* clk_get_by_name_nodev - Get/request a clock by name without a device. * clk_get_by_name_nodev - Get/request a clock by name without a device.
*
* This is a version of clk_get_by_name() that does not use a device.
*
* @node: The client ofnode. * @node: The client ofnode.
* @name: The name of the clock to request, within the client's list of * @name: The name of the clock to request, within the client's list of
* clocks. * clocks.
* @clock: A pointer to a clock struct to initialize. * @clk: A pointer to a clock struct to initialize.
*
* Return: 0 if OK, or a negative error code. * Return: 0 if OK, or a negative error code.
*/ */
int clk_get_by_name_nodev(ofnode node, const char *name, struct clk *clk); int clk_get_by_name_nodev(ofnode node, const char *name, struct clk *clk);
/** /**
* clk_get_optional_nodev - Get/request an optinonal clock by name * devm_clk_get() - lookup and obtain a managed reference to a clock producer.
* without a device.
* @node: The client ofnode.
* @name: The name of the clock to request.
* @name: The name of the clock to request, within the client's list of
* clocks.
* @clock: A pointer to a clock struct to initialize.
*
* Behaves the same as clk_get_by_name_nodev() except where there is
* no clock producer, in this case, skip the error number -ENODATA, and
* the function returns 0.
*/
int clk_get_optional_nodev(ofnode node, const char *name, struct clk *clk);
/**
* devm_clk_get - lookup and obtain a managed reference to a clock producer.
* @dev: device for clock "consumer" * @dev: device for clock "consumer"
* @id: clock consumer ID * @id: clock consumer ID
* *
* Returns a struct clk corresponding to the clock producer, or * The implementation uses @dev and @id to determine the clock consumer, and
* valid IS_ERR() condition containing errno. The implementation * thereby the clock producer. (IOW, @id may be identical strings, but clk_get
* uses @dev and @id to determine the clock consumer, and thereby * may return different clock producers depending on @dev.)
* the clock producer. (IOW, @id may be identical strings, but
* clk_get may return different clock producers depending on @dev.)
* *
* Drivers must assume that the clock source is not enabled. * Drivers must assume that the clock source is not enabled.
* *
* devm_clk_get should not be called from within interrupt context.
*
* The clock will automatically be freed when the device is unbound * The clock will automatically be freed when the device is unbound
* from the bus. * from the bus.
*
* Return:
* a struct clk corresponding to the clock producer, or
* valid IS_ERR() condition containing errno
*/ */
struct clk *devm_clk_get(struct udevice *dev, const char *id); struct clk *devm_clk_get(struct udevice *dev, const char *id);
/** /**
* devm_clk_get_optional - lookup and obtain a managed reference to an optional * devm_clk_get_optional() - lookup and obtain a managed reference to an
* clock producer. * optional clock producer.
* @dev: device for clock "consumer" * @dev: device for clock "consumer"
* @id: clock consumer ID * @id: clock consumer ID
* *
* Behaves the same as devm_clk_get() except where there is no clock producer. * Behaves the same as devm_clk_get() except where there is no clock producer.
* In this case, instead of returning -ENOENT, the function returns NULL. * In this case, instead of returning -%ENOENT, the function returns NULL.
*/ */
struct clk *devm_clk_get_optional(struct udevice *dev, const char *id); static inline struct clk *devm_clk_get_optional(struct udevice *dev,
const char *id)
{
struct clk *clk = devm_clk_get(dev, id);
if (PTR_ERR(clk) == -ENODATA)
return NULL;
return clk;
}
/** /**
* clk_release_all() - Disable (turn off)/Free an array of previously * clk_release_all() - Disable (turn off)/Free an array of previously
* requested clocks. * requested clocks.
* @clk: A clock struct array that was previously successfully
* requested by clk_request/get_by_*().
* @count: Number of clock contained in the array
* *
* For each clock contained in the clock array, this function will check if * For each clock contained in the clock array, this function will check if
* clock has been previously requested and then will disable and free it. * clock has been previously requested and then will disable and free it.
* *
* @clk: A clock struct array that was previously successfully
* requested by clk_request/get_by_*().
* @count Number of clock contained in the array
* Return: zero on success, or -ve error code. * Return: zero on success, or -ve error code.
*/ */
int clk_release_all(struct clk *clk, int count); int clk_release_all(struct clk *clk, int count);
@@ -290,18 +281,60 @@ clk_get_by_name_nodev(ofnode node, const char *name, struct clk *clk)
return -ENOSYS; return -ENOSYS;
} }
static inline int
clk_get_optional_nodev(ofnode node, const char *name, struct clk *clk)
{
return -ENOSYS;
}
static inline int clk_release_all(struct clk *clk, int count) static inline int clk_release_all(struct clk *clk, int count)
{ {
return -ENOSYS; return -ENOSYS;
} }
#endif #endif
/**
* clk_get_by_name_optional() - Get/request a optional clock by name.
* @dev: The client device.
* @name: The name of the clock to request, within the client's list of
* clocks.
* @clk: A pointer to a clock struct to initialize.
*
* Behaves the same as clk_get_by_name(), except when there is no clock
* provider. In the latter case, return 0.
*
* Return: 0 if OK, or a negative error code.
*/
static inline int clk_get_by_name_optional(struct udevice *dev,
const char *name, struct clk *clk)
{
int ret;
ret = clk_get_by_name(dev, name, clk);
if (ret == -ENODATA)
return 0;
return ret;
}
/**
* clk_get_by_name_nodev_optional - Get/request an optinonal clock by name
* without a device.
* @node: The client ofnode.
* @name: The name of the clock to request, within the client's list of
* clocks.
* @clk: A pointer to a clock struct to initialize.
*
* Behaves the same as clk_get_by_name_nodev() except where there is
* no clock producer, in this case, skip the error number -%ENODATA, and
* the function returns 0.
*/
static inline int clk_get_by_name_nodev_optional(ofnode node, const char *name,
struct clk *clk)
{
int ret;
ret = clk_get_by_name_nodev(node, name, clk);
if (ret == -ENODATA)
return 0;
return ret;
}
/** /**
* enum clk_defaults_stage - What stage clk_set_defaults() is called at * enum clk_defaults_stage - What stage clk_set_defaults() is called at
* @CLK_DEFAULTS_PRE: Called before probe. Setting of defaults for clocks owned * @CLK_DEFAULTS_PRE: Called before probe. Setting of defaults for clocks owned
@@ -327,12 +360,13 @@ enum clk_defaults_stage {
#if CONFIG_IS_ENABLED(OF_REAL) && CONFIG_IS_ENABLED(CLK) #if CONFIG_IS_ENABLED(OF_REAL) && CONFIG_IS_ENABLED(CLK)
/** /**
* clk_set_defaults - Process 'assigned-{clocks/clock-parents/clock-rates}' * clk_set_defaults - Process ``assigned-{clocks/clock-parents/clock-rates}``
* properties to configure clocks * properties to configure clocks
*
* @dev: A device to process (the ofnode associated with this device * @dev: A device to process (the ofnode associated with this device
* will be processed). * will be processed).
* @stage: The stage of the probing process this function is called during. * @stage: The stage of the probing process this function is called during.
*
* Return: zero on success, or -ve error code.
*/ */
int clk_set_defaults(struct udevice *dev, enum clk_defaults_stage stage); int clk_set_defaults(struct udevice *dev, enum clk_defaults_stage stage);
#else #else
@@ -345,12 +379,12 @@ static inline int clk_set_defaults(struct udevice *dev, int stage)
/** /**
* clk_release_bulk() - Disable (turn off)/Free an array of previously * clk_release_bulk() - Disable (turn off)/Free an array of previously
* requested clocks in a clock bulk struct. * requested clocks in a clock bulk struct.
* @bulk: A clock bulk struct that was previously successfully
* requested by clk_get_bulk().
* *
* For each clock contained in the clock bulk struct, this function will check * For each clock contained in the clock bulk struct, this function will check
* if clock has been previously requested and then will disable and free it. * if clock has been previously requested and then will disable and free it.
* *
* @clk: A clock bulk struct that was previously successfully
* requested by clk_get_bulk().
* Return: zero on success, or -ve error code. * Return: zero on success, or -ve error code.
*/ */
static inline int clk_release_bulk(struct clk_bulk *bulk) static inline int clk_release_bulk(struct clk_bulk *bulk)
@@ -360,35 +394,35 @@ static inline int clk_release_bulk(struct clk_bulk *bulk)
#if CONFIG_IS_ENABLED(CLK) #if CONFIG_IS_ENABLED(CLK)
/** /**
* clk_request - Request a clock by provider-specific ID. * clk_request() - Request a clock by provider-specific ID.
* @dev: The clock provider device.
* @clk: A pointer to a clock struct to initialize. The caller must
* have already initialized any field in this struct which the
* clock provider uses to identify the clock.
* *
* This requests a clock using a provider-specific ID. Generally, this function * This requests a clock using a provider-specific ID. Generally, this function
* should not be used, since clk_get_by_index/name() provide an interface that * should not be used, since clk_get_by_index/name() provide an interface that
* better separates clients from intimate knowledge of clock providers. * better separates clients from intimate knowledge of clock providers.
* However, this function may be useful in core SoC-specific code. * However, this function may be useful in core SoC-specific code.
* *
* @dev: The clock provider device.
* @clock: A pointer to a clock struct to initialize. The caller must
* have already initialized any field in this struct which the
* clock provider uses to identify the clock.
* Return: 0 if OK, or a negative error code. * Return: 0 if OK, or a negative error code.
*/ */
int clk_request(struct udevice *dev, struct clk *clk); int clk_request(struct udevice *dev, struct clk *clk);
/** /**
* clk_free - Free a previously requested clock. * clk_free() - Free a previously requested clock.
* * @clk: A clock struct that was previously successfully requested by
* @clock: A clock struct that was previously successfully requested by
* clk_request/get_by_*(). * clk_request/get_by_*().
*
* Return: 0 if OK, or a negative error code. * Return: 0 if OK, or a negative error code.
*/ */
int clk_free(struct clk *clk); int clk_free(struct clk *clk);
/** /**
* clk_get_rate() - Get current clock rate. * clk_get_rate() - Get current clock rate.
*
* @clk: A clock struct that was previously successfully requested by * @clk: A clock struct that was previously successfully requested by
* clk_request/get_by_*(). * clk_request/get_by_*().
*
* Return: clock rate in Hz on success, 0 for invalid clock, or -ve error code * Return: clock rate in Hz on success, 0 for invalid clock, or -ve error code
* for other errors. * for other errors.
*/ */
@@ -396,98 +430,98 @@ ulong clk_get_rate(struct clk *clk);
/** /**
* clk_get_parent() - Get current clock's parent. * clk_get_parent() - Get current clock's parent.
*
* @clk: A clock struct that was previously successfully requested by * @clk: A clock struct that was previously successfully requested by
* clk_request/get_by_*(). * clk_request/get_by_*().
*
* Return: pointer to parent's struct clk, or error code passed as pointer * Return: pointer to parent's struct clk, or error code passed as pointer
*/ */
struct clk *clk_get_parent(struct clk *clk); struct clk *clk_get_parent(struct clk *clk);
/** /**
* clk_get_parent_rate() - Get parent of current clock rate. * clk_get_parent_rate() - Get parent of current clock rate.
*
* @clk: A clock struct that was previously successfully requested by * @clk: A clock struct that was previously successfully requested by
* clk_request/get_by_*(). * clk_request/get_by_*().
*
* Return: clock rate in Hz, or -ve error code. * Return: clock rate in Hz, or -ve error code.
*/ */
long long clk_get_parent_rate(struct clk *clk); long long clk_get_parent_rate(struct clk *clk);
/** /**
* clk_round_rate() - Adjust a rate to the exact rate a clock can provide * clk_round_rate() - Adjust a rate to the exact rate a clock can provide
* @clk: A clock struct that was previously successfully requested by
* clk_request/get_by_*().
* @rate: desired clock rate in Hz.
* *
* This answers the question "if I were to pass @rate to clk_set_rate(), * This answers the question "if I were to pass @rate to clk_set_rate(),
* what clock rate would I end up with?" without changing the hardware * what clock rate would I end up with?" without changing the hardware
* in any way. In other words: * in any way. In other words::
* *
* rate = clk_round_rate(clk, r); * rate = clk_round_rate(clk, r);
* *
* and: * and::
* *
* rate = clk_set_rate(clk, r); * rate = clk_set_rate(clk, r);
* *
* are equivalent except the former does not modify the clock hardware * are equivalent except the former does not modify the clock hardware
* in any way. * in any way.
* *
* @clk: A clock struct that was previously successfully requested by
* clk_request/get_by_*().
* @rate: desired clock rate in Hz.
* Return: rounded rate in Hz, or -ve error code. * Return: rounded rate in Hz, or -ve error code.
*/ */
ulong clk_round_rate(struct clk *clk, ulong rate); ulong clk_round_rate(struct clk *clk, ulong rate);
/** /**
* clk_set_rate() - Set current clock rate. * clk_set_rate() - Set current clock rate.
*
* @clk: A clock struct that was previously successfully requested by * @clk: A clock struct that was previously successfully requested by
* clk_request/get_by_*(). * clk_request/get_by_*().
* @rate: New clock rate in Hz. * @rate: New clock rate in Hz.
*
* Return: new rate, or -ve error code. * Return: new rate, or -ve error code.
*/ */
ulong clk_set_rate(struct clk *clk, ulong rate); ulong clk_set_rate(struct clk *clk, ulong rate);
/** /**
* clk_set_parent() - Set current clock parent. * clk_set_parent() - Set current clock parent.
*
* @clk: A clock struct that was previously successfully requested by * @clk: A clock struct that was previously successfully requested by
* clk_request/get_by_*(). * clk_request/get_by_*().
* @parent: A clock struct that was previously successfully requested by * @parent: A clock struct that was previously successfully requested by
* clk_request/get_by_*(). * clk_request/get_by_*().
*
* Return: new rate, or -ve error code. * Return: new rate, or -ve error code.
*/ */
int clk_set_parent(struct clk *clk, struct clk *parent); int clk_set_parent(struct clk *clk, struct clk *parent);
/** /**
* clk_enable() - Enable (turn on) a clock. * clk_enable() - Enable (turn on) a clock.
*
* @clk: A clock struct that was previously successfully requested by * @clk: A clock struct that was previously successfully requested by
* clk_request/get_by_*(). * clk_request/get_by_*().
*
* Return: zero on success, or -ve error code. * Return: zero on success, or -ve error code.
*/ */
int clk_enable(struct clk *clk); int clk_enable(struct clk *clk);
/** /**
* clk_enable_bulk() - Enable (turn on) all clocks in a clock bulk struct. * clk_enable_bulk() - Enable (turn on) all clocks in a clock bulk struct.
*
* @bulk: A clock bulk struct that was previously successfully requested * @bulk: A clock bulk struct that was previously successfully requested
* by clk_get_bulk(). * by clk_get_bulk().
*
* Return: zero on success, or -ve error code. * Return: zero on success, or -ve error code.
*/ */
int clk_enable_bulk(struct clk_bulk *bulk); int clk_enable_bulk(struct clk_bulk *bulk);
/** /**
* clk_disable() - Disable (turn off) a clock. * clk_disable() - Disable (turn off) a clock.
*
* @clk: A clock struct that was previously successfully requested by * @clk: A clock struct that was previously successfully requested by
* clk_request/get_by_*(). * clk_request/get_by_*().
*
* Return: zero on success, or -ve error code. * Return: zero on success, or -ve error code.
*/ */
int clk_disable(struct clk *clk); int clk_disable(struct clk *clk);
/** /**
* clk_disable_bulk() - Disable (turn off) all clocks in a clock bulk struct. * clk_disable_bulk() - Disable (turn off) all clocks in a clock bulk struct.
*
* @bulk: A clock bulk struct that was previously successfully requested * @bulk: A clock bulk struct that was previously successfully requested
* by clk_get_bulk(). * by clk_get_bulk().
*
* Return: zero on success, or -ve error code. * Return: zero on success, or -ve error code.
*/ */
int clk_disable_bulk(struct clk_bulk *bulk); int clk_disable_bulk(struct clk_bulk *bulk);
@@ -497,28 +531,25 @@ int clk_disable_bulk(struct clk_bulk *bulk);
* @p: clk compared against q * @p: clk compared against q
* @q: clk compared against p * @q: clk compared against p
* *
* Returns true if the two struct clk pointers both point to the same hardware * Return:
* clock node. * %true if the two struct clk pointers both point to the same hardware clock
* * node, and %false otherwise. Note that two %NULL clks are treated as matching.
* Returns false otherwise. Note that two NULL clks are treated as matching.
*/ */
bool clk_is_match(const struct clk *p, const struct clk *q); bool clk_is_match(const struct clk *p, const struct clk *q);
/** /**
* clk_get_by_id() - Get the clock by its ID * clk_get_by_id() - Get the clock by its ID
*
* @id: The clock ID to search for * @id: The clock ID to search for
*
* @clkp: A pointer to clock struct that has been found among added clocks * @clkp: A pointer to clock struct that has been found among added clocks
* to UCLASS_CLK * to UCLASS_CLK
*
* Return: zero on success, or -ENOENT on error * Return: zero on success, or -ENOENT on error
*/ */
int clk_get_by_id(ulong id, struct clk **clkp); int clk_get_by_id(ulong id, struct clk **clkp);
/** /**
* clk_dev_binded() - Check whether the clk has a device binded * clk_dev_binded() - Check whether the clk has a device binded
* * @clk: A pointer to the clk
* @clk A pointer to the clk
* *
* Return: true on binded, or false on no * Return: true on binded, or false on no
*/ */
@@ -604,8 +635,8 @@ static inline bool clk_dev_binded(struct clk *clk)
/** /**
* clk_valid() - check if clk is valid * clk_valid() - check if clk is valid
*
* @clk: the clock to check * @clk: the clock to check
*
* Return: true if valid, or false * Return: true if valid, or false
*/ */
static inline bool clk_valid(struct clk *clk) static inline bool clk_valid(struct clk *clk)