Commit b9a40506 authored by Stephen Boyd's avatar Stephen Boyd

Merge branches 'clk-imx', 'clk-microchip', 'clk-cleanup', 'clk-bindings',...

Merge branches 'clk-imx', 'clk-microchip', 'clk-cleanup', 'clk-bindings', 'clk-ti' and 'clk-kasprintf' into clk-next

 - Handle allocation failures from kasprintf() and friends

* clk-imx:
  clk: imx: clk-imx8mp: improve error handling in imx8mp_clocks_probe()
  clk: imx93: fix memory leak and missing unwind goto in imx93_clocks_probe
  clk: imx: clk-imx8mn: fix memory leak in imx8mn_clocks_probe
  dt-bindings: clock: imx8m: Add missing interrupt property
  clk: imx: clk-imxrt1050: fix memory leak in imxrt1050_clocks_probe
  clk: imx: composite-8m: Add imx8m_divider_determine_rate
  clk: imx: scu: use _safe list iterator to avoid a use after free
  clk: imx: drop imx_unregister_clocks
  clk: imx6ul: retain early UART clocks during kernel init
  clk: imx: imx6sx: Remove CLK_SET_RATE_PARENT from the LDB clocks

* clk-microchip:
  dt-bindings: clocks: at91sam9x5-sckc: convert to yaml
  dt-bindings: clocks: atmel,at91rm9200-pmc: convert to yaml
  clk: microchip: Use of_property_read_bool() for boolean properties
  clk: microchip: convert SOC_MICROCHIP_POLARFIRE to ARCH_MICROCHIP_POLARFIRE

* clk-cleanup:
  clk: fix typo in clk_hw_register_fixed_rate_parent_data() macro
  clk: Fix memory leak in devm_clk_notifier_register()
  clk: mvebu: Iterate over possible CPUs instead of DT CPU nodes
  clk: mvebu: Use of_get_cpu_hwid() to read CPU ID
  MAINTAINERS: Add Marvell mvebu clock drivers
  clk: mvebu: Use of_address_to_resource()
  clk: tegra: tegra124-emc: Fix potential memory leak
  clk: clocking-wizard: Fix Oops in clk_wzrd_register_divider()
  clk: bcm: rpi: Fix off by one in raspberrypi_discover_clocks()
  clk: sifive: Use devm_platform_ioremap_resource()

* clk-bindings:
  dt-bindings: clock: drop unneeded quotes and use absolute /schemas path
  dt-bindings: rcc: stm32: Sync with u-boot copy for STM32MP13 SoC

* clk-ti:
  clk: keystone: syscon-clk: Add support for audio refclk
  dt-bindings: clock: Add binding documentation for TI Audio REFCLK
  dt-bindings: clock: ehrpwm: Remove unneeded syscon compatible
  clk: keystone: syscon-clk: Allow the clock node to not be of type syscon

* clk-kasprintf:
  clk: clocking-wizard: check return value of devm_kasprintf()
  clk: ti: clkctrl: check return value of kasprintf()
  clk: keystone: sci-clk: check return value of kasprintf()
  clk: si5341: free unused memory on probe failure
  clk: si5341: check return value of {devm_}kasprintf()
  clk: si5341: return error if one synth clock registration fails
  clk: cdce925: check return value of kasprintf()
  clk: vc5: check memory returned by kasprintf()
Device Tree Clock bindings for arch-at91
This binding uses the common clock binding[1].
[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
Slow Clock controller:
Required properties:
- compatible : shall be one of the following:
"atmel,at91sam9x5-sckc",
"atmel,sama5d3-sckc",
"atmel,sama5d4-sckc" or
"microchip,sam9x60-sckc":
at91 SCKC (Slow Clock Controller)
- #clock-cells : shall be 1 for "microchip,sam9x60-sckc" otherwise shall be 0.
- clocks : shall be the input parent clock phandle for the clock.
Optional properties:
- atmel,osc-bypass : boolean property. Set this when a clock signal is directly
provided on XIN.
For example:
sckc@fffffe50 {
compatible = "atmel,at91sam9x5-sckc";
reg = <0xfffffe50 0x4>;
clocks = <&slow_xtal>;
#clock-cells = <0>;
};
Power Management Controller (PMC):
Required properties:
- compatible : shall be "atmel,<chip>-pmc", "syscon" or
"microchip,sam9x60-pmc"
<chip> can be: at91rm9200, at91sam9260, at91sam9261,
at91sam9263, at91sam9g45, at91sam9n12, at91sam9rl, at91sam9g15,
at91sam9g25, at91sam9g35, at91sam9x25, at91sam9x35, at91sam9x5,
sama5d2, sama5d3 or sama5d4.
- #clock-cells : from common clock binding; shall be set to 2. The first entry
is the type of the clock (core, system, peripheral or generated) and the
second entry its index as provided by the datasheet
- clocks : Must contain an entry for each entry in clock-names.
- clock-names: Must include the following entries: "slow_clk", "main_xtal"
Optional properties:
- atmel,osc-bypass : boolean property. Set this when a clock signal is directly
provided on XIN.
For example:
pmc: pmc@f0018000 {
compatible = "atmel,sama5d4-pmc", "syscon";
reg = <0xf0018000 0x120>;
interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
#clock-cells = <2>;
clocks = <&clk32k>, <&main_xtal>;
clock-names = "slow_clk", "main_xtal";
};
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/atmel,at91rm9200-pmc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Atmel Power Management Controller (PMC)
maintainers:
- Claudiu Beznea <claudiu.beznea@microchip.com>
description:
The power management controller optimizes power consumption by controlling all
system and user peripheral clocks. The PMC enables/disables the clock inputs
to many of the peripherals and to the processor.
properties:
compatible:
oneOf:
- items:
- const: atmel,at91sam9g20-pmc
- const: atmel,at91sam9260-pmc
- const: syscon
- items:
- enum:
- atmel,at91sam9g15-pmc
- atmel,at91sam9g25-pmc
- atmel,at91sam9g35-pmc
- atmel,at91sam9x25-pmc
- atmel,at91sam9x35-pmc
- const: atmel,at91sam9x5-pmc
- const: syscon
- items:
- enum:
- atmel,at91rm9200-pmc
- atmel,at91sam9260-pmc
- atmel,at91sam9g45-pmc
- atmel,at91sam9n12-pmc
- atmel,at91sam9rl-pmc
- atmel,at91sam9x5-pmc
- atmel,sama5d2-pmc
- atmel,sama5d3-pmc
- atmel,sama5d4-pmc
- microchip,sam9x60-pmc
- microchip,sama7g5-pmc
- const: syscon
reg:
maxItems: 1
interrupts:
maxItems: 1
"#clock-cells":
description: |
- 1st cell is the clock type, one of PMC_TYPE_CORE, PMC_TYPE_SYSTEM,
PMC_TYPE_PERIPHERAL, PMC_TYPE_GCK, PMC_TYPE_PROGRAMMABLE (as defined
in <dt-bindings/clock/at91.h>)
- 2nd cell is the clock identifier as defined in <dt-bindings/clock/at91.h
(for core clocks) or as defined in datasheet (for system, peripheral,
gck and programmable clocks).
const: 2
clocks:
minItems: 2
maxItems: 3
clock-names:
minItems: 2
maxItems: 3
atmel,osc-bypass:
description: set when a clock signal is directly provided on XIN
type: boolean
required:
- compatible
- reg
- interrupts
- "#clock-cells"
- clocks
- clock-names
allOf:
- if:
properties:
compatible:
contains:
enum:
- microchip,sam9x60-pmc
- microchip,sama7g5-pmc
then:
properties:
clocks:
minItems: 3
maxItems: 3
clock-names:
items:
- const: td_slck
- const: md_slck
- const: main_xtal
- if:
properties:
compatible:
contains:
enum:
- atmel,at91rm9200-pmc
- atmel,at91sam9260-pmc
- atmel,at91sam9g20-pmc
then:
properties:
clocks:
minItems: 2
maxItems: 2
clock-names:
items:
- const: slow_xtal
- const: main_xtal
- if:
properties:
compatible:
contains:
enum:
- atmel,sama5d2-pmc
- atmel,sama5d3-pmc
- atmel,sama5d4-pmc
then:
properties:
clocks:
minItems: 2
maxItems: 2
clock-names:
items:
- const: slow_clk
- const: main_xtal
additionalProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>
pmc: clock-controller@f0018000 {
compatible = "atmel,sama5d4-pmc", "syscon";
reg = <0xf0018000 0x120>;
interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
#clock-cells = <2>;
clocks = <&clk32k>, <&main_xtal>;
clock-names = "slow_clk", "main_xtal";
};
...
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/atmel,at91sam9x5-sckc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Atmel Slow Clock Controller (SCKC)
maintainers:
- Claudiu Beznea <claudiu.beznea@microchip.com>
properties:
compatible:
oneOf:
- enum:
- atmel,at91sam9x5-sckc
- atmel,sama5d3-sckc
- atmel,sama5d4-sckc
- microchip,sam9x60-sckc
- items:
- const: microchip,sama7g5-sckc
- const: microchip,sam9x60-sckc
reg:
maxItems: 1
clocks:
maxItems: 1
"#clock-cells":
enum: [0, 1]
atmel,osc-bypass:
type: boolean
description: set when a clock signal is directly provided on XIN
required:
- compatible
- reg
- clocks
- "#clock-cells"
allOf:
- if:
properties:
compatible:
contains:
enum:
- microchip,sam9x60-sckc
then:
properties:
"#clock-cells":
const: 1
else:
properties:
"#clock-cells":
const: 0
additionalProperties: false
examples:
- |
clk32k: clock-controller@fffffe50 {
compatible = "microchip,sam9x60-sckc";
reg = <0xfffffe50 0x4>;
clocks = <&slow_xtal>;
#clock-cells = <1>;
};
...
......@@ -24,6 +24,9 @@ properties:
reg:
maxItems: 1
interrupts:
maxItems: 2
clocks:
minItems: 6
maxItems: 7
......
......@@ -98,9 +98,9 @@ required:
patternProperties:
"^usb-phy@[a-f0-9]+$":
allOf: [ $ref: "../phy/ingenic,phy-usb.yaml#" ]
$ref: /schemas/phy/ingenic,phy-usb.yaml#
"^mac-phy-ctrl@[a-f0-9]+$":
allOf: [ $ref: "../net/ingenic,mac.yaml#" ]
$ref: /schemas/net/ingenic,mac.yaml#
additionalProperties: false
......
......@@ -48,7 +48,7 @@ properties:
patternProperties:
"^dma-router@[a-f0-9]+$":
type: object
$ref: "../dma/renesas,rzn1-dmamux.yaml#"
$ref: /schemas/dma/renesas,rzn1-dmamux.yaml#
required:
- compatible
......
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/ti,am62-audio-refclk.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: TI Audio Reference Clock
maintainers:
- Jai Luthra <j-luthra@ti.com>
properties:
compatible:
items:
- const: ti,am62-audio-refclk
reg:
maxItems: 1
"#clock-cells":
const: 0
clocks:
maxItems: 1
required:
- compatible
- reg
- "#clock-cells"
- clocks
additionalProperties: false
examples:
- |
audio_refclk0: clock@82e0 {
compatible = "ti,am62-audio-refclk";
reg = <0x82e0 0x4>;
clocks = <&k3_clks 157 0>;
assigned-clocks = <&k3_clks 157 0>;
assigned-clock-parents = <&k3_clks 157 8>;
#clock-cells = <0>;
};
......@@ -16,7 +16,6 @@ properties:
- ti,am654-ehrpwm-tbclk
- ti,am64-epwm-tbclk
- ti,am62-epwm-tbclk
- const: syscon
"#clock-cells":
const: 1
......@@ -33,8 +32,8 @@ additionalProperties: false
examples:
- |
ehrpwm_tbclk: syscon@4140 {
compatible = "ti,am654-ehrpwm-tbclk", "syscon";
ehrpwm_tbclk: clock@4140 {
compatible = "ti,am654-ehrpwm-tbclk";
reg = <0x4140 0x18>;
#clock-cells = <1>;
};
......@@ -2365,6 +2365,7 @@ F: arch/arm/configs/mvebu_*_defconfig
F: arch/arm/mach-mvebu/
F: arch/arm64/boot/dts/marvell/armada*
F: arch/arm64/boot/dts/marvell/cn913*
F: drivers/clk/mvebu/
F: drivers/cpufreq/armada-37xx-cpufreq.c
F: drivers/cpufreq/armada-8k-cpufreq.c
F: drivers/cpufreq/mvebu-cpufreq.c
......
......@@ -356,9 +356,9 @@ static int raspberrypi_discover_clocks(struct raspberrypi_clk *rpi,
while (clks->id) {
struct raspberrypi_clk_variant *variant;
if (clks->id > RPI_FIRMWARE_NUM_CLK_ID) {
if (clks->id >= RPI_FIRMWARE_NUM_CLK_ID) {
dev_err(rpi->dev, "Unknown clock id: %u (max: %u)\n",
clks->id, RPI_FIRMWARE_NUM_CLK_ID);
clks->id, RPI_FIRMWARE_NUM_CLK_ID - 1);
return -EINVAL;
}
......
......@@ -701,6 +701,10 @@ static int cdce925_probe(struct i2c_client *client)
for (i = 0; i < data->chip_info->num_plls; ++i) {
pll_clk_name[i] = kasprintf(GFP_KERNEL, "%pOFn.pll%d",
client->dev.of_node, i);
if (!pll_clk_name[i]) {
err = -ENOMEM;
goto error;
}
init.name = pll_clk_name[i];
data->pll[i].chip = data;
data->pll[i].hw.init = &init;
......@@ -742,6 +746,10 @@ static int cdce925_probe(struct i2c_client *client)
init.num_parents = 1;
init.parent_names = &parent_name; /* Mux Y1 to input */
init.name = kasprintf(GFP_KERNEL, "%pOFn.Y1", client->dev.of_node);
if (!init.name) {
err = -ENOMEM;
goto error;
}
data->clk[0].chip = data;
data->clk[0].hw.init = &init;
data->clk[0].index = 0;
......@@ -760,6 +768,10 @@ static int cdce925_probe(struct i2c_client *client)
for (i = 1; i < data->chip_info->num_outputs; ++i) {
init.name = kasprintf(GFP_KERNEL, "%pOFn.Y%d",
client->dev.of_node, i+1);
if (!init.name) {
err = -ENOMEM;
goto error;
}
data->clk[i].chip = data;
data->clk[i].hw.init = &init;
data->clk[i].index = i;
......
......@@ -1556,7 +1556,7 @@ static int si5341_probe(struct i2c_client *client)
struct clk_init_data init;
struct clk *input;
const char *root_clock_name;
const char *synth_clock_names[SI5341_NUM_SYNTH];
const char *synth_clock_names[SI5341_NUM_SYNTH] = { NULL };
int err;
unsigned int i;
struct clk_si5341_output_config config[SI5341_MAX_NUM_OUTPUTS];
......@@ -1700,6 +1700,10 @@ static int si5341_probe(struct i2c_client *client)
for (i = 0; i < data->num_synth; ++i) {
synth_clock_names[i] = devm_kasprintf(&client->dev, GFP_KERNEL,
"%s.N%u", client->dev.of_node->name, i);
if (!synth_clock_names[i]) {
err = -ENOMEM;
goto free_clk_names;
}
init.name = synth_clock_names[i];
data->synth[i].index = i;
data->synth[i].data = data;
......@@ -1708,6 +1712,7 @@ static int si5341_probe(struct i2c_client *client)
if (err) {
dev_err(&client->dev,
"synth N%u registration failed\n", i);
goto free_clk_names;
}
}
......@@ -1717,6 +1722,10 @@ static int si5341_probe(struct i2c_client *client)
for (i = 0; i < data->num_outputs; ++i) {
init.name = kasprintf(GFP_KERNEL, "%s.%d",
client->dev.of_node->name, i);
if (!init.name) {
err = -ENOMEM;
goto free_clk_names;
}
init.flags = config[i].synth_master ? CLK_SET_RATE_PARENT : 0;
data->clk[i].index = i;
data->clk[i].data = data;
......@@ -1738,7 +1747,7 @@ static int si5341_probe(struct i2c_client *client)
if (err) {
dev_err(&client->dev,
"output %u registration failed\n", i);
goto cleanup;
goto free_clk_names;
}
if (config[i].always_on)
clk_prepare(data->clk[i].hw.clk);
......@@ -1748,7 +1757,7 @@ static int si5341_probe(struct i2c_client *client)
data);
if (err) {
dev_err(&client->dev, "unable to add clk provider\n");
goto cleanup;
goto free_clk_names;
}
if (initialization_required) {
......@@ -1756,11 +1765,11 @@ static int si5341_probe(struct i2c_client *client)
regcache_cache_only(data->regmap, false);
err = regcache_sync(data->regmap);
if (err < 0)
goto cleanup;
goto free_clk_names;
err = si5341_finalize_defaults(data);
if (err < 0)
goto cleanup;
goto free_clk_names;
}
/* wait for device to report input clock present and PLL lock */
......@@ -1769,32 +1778,31 @@ static int si5341_probe(struct i2c_client *client)
10000, 250000);
if (err) {
dev_err(&client->dev, "Error waiting for input clock or PLL lock\n");
goto cleanup;
goto free_clk_names;
}
/* clear sticky alarm bits from initialization */
err = regmap_write(data->regmap, SI5341_STATUS_STICKY, 0);
if (err) {
dev_err(&client->dev, "unable to clear sticky status\n");
goto cleanup;
goto free_clk_names;
}
err = sysfs_create_files(&client->dev.kobj, si5341_attributes);
if (err) {
if (err)
dev_err(&client->dev, "unable to create sysfs files\n");
goto cleanup;
}
free_clk_names:
/* Free the names, clk framework makes copies */
for (i = 0; i < data->num_synth; ++i)
devm_kfree(&client->dev, (void *)synth_clock_names[i]);
return 0;
cleanup:
for (i = 0; i < SI5341_MAX_NUM_OUTPUTS; ++i) {
if (data->clk[i].vddo_reg)
regulator_disable(data->clk[i].vddo_reg);
if (err) {
for (i = 0; i < SI5341_MAX_NUM_OUTPUTS; ++i) {
if (data->clk[i].vddo_reg)
regulator_disable(data->clk[i].vddo_reg);
}
}
return err;
}
......
......@@ -1031,6 +1031,11 @@ static int vc5_probe(struct i2c_client *client)
}
init.name = kasprintf(GFP_KERNEL, "%pOFn.mux", client->dev.of_node);
if (!init.name) {
ret = -ENOMEM;
goto err_clk;
}
init.ops = &vc5_mux_ops;
init.flags = 0;
init.parent_names = parent_names;
......@@ -1045,6 +1050,10 @@ static int vc5_probe(struct i2c_client *client)
memset(&init, 0, sizeof(init));
init.name = kasprintf(GFP_KERNEL, "%pOFn.dbl",
client->dev.of_node);
if (!init.name) {
ret = -ENOMEM;
goto err_clk;
}
init.ops = &vc5_dbl_ops;
init.flags = CLK_SET_RATE_PARENT;
init.parent_names = parent_names;
......@@ -1060,6 +1069,10 @@ static int vc5_probe(struct i2c_client *client)
/* Register PFD */
memset(&init, 0, sizeof(init));
init.name = kasprintf(GFP_KERNEL, "%pOFn.pfd", client->dev.of_node);
if (!init.name) {
ret = -ENOMEM;
goto err_clk;
}
init.ops = &vc5_pfd_ops;
init.flags = CLK_SET_RATE_PARENT;
init.parent_names = parent_names;
......@@ -1077,6 +1090,10 @@ static int vc5_probe(struct i2c_client *client)
/* Register PLL */
memset(&init, 0, sizeof(init));
init.name = kasprintf(GFP_KERNEL, "%pOFn.pll", client->dev.of_node);
if (!init.name) {
ret = -ENOMEM;
goto err_clk;
}
init.ops = &vc5_pll_ops;
init.flags = CLK_SET_RATE_PARENT;
init.parent_names = parent_names;
......@@ -1096,6 +1113,10 @@ static int vc5_probe(struct i2c_client *client)
memset(&init, 0, sizeof(init));
init.name = kasprintf(GFP_KERNEL, "%pOFn.fod%d",
client->dev.of_node, idx);
if (!init.name) {
ret = -ENOMEM;
goto err_clk;
}
init.ops = &vc5_fod_ops;
init.flags = CLK_SET_RATE_PARENT;
init.parent_names = parent_names;
......@@ -1114,6 +1135,10 @@ static int vc5_probe(struct i2c_client *client)
memset(&init, 0, sizeof(init));
init.name = kasprintf(GFP_KERNEL, "%pOFn.out0_sel_i2cb",
client->dev.of_node);
if (!init.name) {
ret = -ENOMEM;
goto err_clk;
}
init.ops = &vc5_clk_out_ops;
init.flags = CLK_SET_RATE_PARENT;
init.parent_names = parent_names;
......@@ -1140,6 +1165,10 @@ static int vc5_probe(struct i2c_client *client)
memset(&init, 0, sizeof(init));
init.name = kasprintf(GFP_KERNEL, "%pOFn.out%d",
client->dev.of_node, idx + 1);
if (!init.name) {
ret = -ENOMEM;
goto err_clk;
}
init.ops = &vc5_clk_out_ops;
init.flags = CLK_SET_RATE_PARENT;
init.parent_names = parent_names;
......
......@@ -4741,6 +4741,7 @@ int devm_clk_notifier_register(struct device *dev, struct clk *clk,
if (!ret) {
devres->clk = clk;
devres->nb = nb;
devres_add(dev, devres);
} else {
devres_free(devres);
}
......
......@@ -119,10 +119,41 @@ static int imx8m_clk_composite_divider_set_rate(struct clk_hw *hw,
return ret;
}
static int imx8m_divider_determine_rate(struct clk_hw *hw,
struct clk_rate_request *req)
{
struct clk_divider *divider = to_clk_divider(hw);
int prediv_value;
int div_value;
/* if read only, just return current value */
if (divider->flags & CLK_DIVIDER_READ_ONLY) {
u32 val;
val = readl(divider->reg);
prediv_value = val >> divider->shift;
prediv_value &= clk_div_mask(divider->width);
prediv_value++;
div_value = val >> PCG_DIV_SHIFT;
div_value &= clk_div_mask(PCG_DIV_WIDTH);
div_value++;
return divider_ro_determine_rate(hw, req, divider->table,
PCG_PREDIV_WIDTH + PCG_DIV_WIDTH,
divider->flags, prediv_value * div_value);
}
return divider_determine_rate(hw, req, divider->table,
PCG_PREDIV_WIDTH + PCG_DIV_WIDTH,
divider->flags);
}
static const struct clk_ops imx8m_clk_composite_divider_ops = {
.recalc_rate = imx8m_clk_composite_divider_recalc_rate,
.round_rate = imx8m_clk_composite_divider_round_rate,
.set_rate = imx8m_clk_composite_divider_set_rate,
.determine_rate = imx8m_divider_determine_rate,
};
static u8 imx8m_clk_composite_mux_get_parent(struct clk_hw *hw)
......
......@@ -302,10 +302,10 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node)
hws[IMX6SX_CLK_CKO2_SEL] = imx_clk_hw_mux("cko2_sel", base + 0x60, 16, 5, cko2_sels, ARRAY_SIZE(cko2_sels));
hws[IMX6SX_CLK_CKO] = imx_clk_hw_mux("cko", base + 0x60, 8, 1, cko_sels, ARRAY_SIZE(cko_sels));
hws[IMX6SX_CLK_LDB_DI1_DIV_SEL] = imx_clk_hw_mux_flags("ldb_di1_div_sel", base + 0x20, 11, 1, ldb_di1_div_sels, ARRAY_SIZE(ldb_di1_div_sels), CLK_SET_RATE_PARENT);
hws[IMX6SX_CLK_LDB_DI0_DIV_SEL] = imx_clk_hw_mux_flags("ldb_di0_div_sel", base + 0x20, 10, 1, ldb_di0_div_sels, ARRAY_SIZE(ldb_di0_div_sels), CLK_SET_RATE_PARENT);
hws[IMX6SX_CLK_LDB_DI1_SEL] = imx_clk_hw_mux_flags("ldb_di1_sel", base + 0x2c, 12, 3, ldb_di1_sels, ARRAY_SIZE(ldb_di1_sels), CLK_SET_RATE_PARENT);
hws[IMX6SX_CLK_LDB_DI0_SEL] = imx_clk_hw_mux_flags("ldb_di0_sel", base + 0x2c, 9, 3, ldb_di0_sels, ARRAY_SIZE(ldb_di0_sels), CLK_SET_RATE_PARENT);
hws[IMX6SX_CLK_LDB_DI1_DIV_SEL] = imx_clk_hw_mux("ldb_di1_div_sel", base + 0x20, 11, 1, ldb_di1_div_sels, ARRAY_SIZE(ldb_di1_div_sels));
hws[IMX6SX_CLK_LDB_DI0_DIV_SEL] = imx_clk_hw_mux("ldb_di0_div_sel", base + 0x20, 10, 1, ldb_di0_div_sels, ARRAY_SIZE(ldb_di0_div_sels));
hws[IMX6SX_CLK_LDB_DI1_SEL] = imx_clk_hw_mux("ldb_di1_sel", base + 0x2c, 12, 3, ldb_di1_sels, ARRAY_SIZE(ldb_di1_sels));
hws[IMX6SX_CLK_LDB_DI0_SEL] = imx_clk_hw_mux("ldb_di0_sel", base + 0x2c, 9, 3, ldb_di0_sels, ARRAY_SIZE(ldb_di0_sels));
hws[IMX6SX_CLK_LCDIF1_PRE_SEL] = imx_clk_hw_mux_flags("lcdif1_pre_sel", base + 0x38, 15, 3, lcdif1_pre_sels, ARRAY_SIZE(lcdif1_pre_sels), CLK_SET_RATE_PARENT);
hws[IMX6SX_CLK_LCDIF1_SEL] = imx_clk_hw_mux_flags("lcdif1_sel", base + 0x38, 9, 3, lcdif1_sels, ARRAY_SIZE(lcdif1_sels), CLK_SET_RATE_PARENT);
......
......@@ -544,6 +544,8 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
clk_set_parent(hws[IMX6UL_CLK_ENET1_REF_SEL]->clk, hws[IMX6UL_CLK_ENET_REF]->clk);
clk_set_parent(hws[IMX6UL_CLK_ENET2_REF_SEL]->clk, hws[IMX6UL_CLK_ENET2_REF]->clk);
imx_register_uart_clocks();
}
CLK_OF_DECLARE(imx6ul, "fsl,imx6ul-ccm", imx6ul_clocks_init);
......@@ -323,7 +323,7 @@ static int imx8mn_clocks_probe(struct platform_device *pdev)
void __iomem *base;
int ret;
clk_hw_data = kzalloc(struct_size(clk_hw_data, hws,
clk_hw_data = devm_kzalloc(dev, struct_size(clk_hw_data, hws,
IMX8MN_CLK_END), GFP_KERNEL);
if (WARN_ON(!clk_hw_data))
return -ENOMEM;
......@@ -340,10 +340,10 @@ static int imx8mn_clocks_probe(struct platform_device *pdev)
hws[IMX8MN_CLK_EXT4] = imx_get_clk_hw_by_name(np, "clk_ext4");
np = of_find_compatible_node(NULL, NULL, "fsl,imx8mn-anatop");
base = of_iomap(np, 0);
base = devm_of_iomap(dev, np, 0, NULL);
of_node_put(np);
if (WARN_ON(!base)) {
ret = -ENOMEM;
if (WARN_ON(IS_ERR(base))) {
ret = PTR_ERR(base);
goto unregister_hws;
}
......
......@@ -414,25 +414,22 @@ static int imx8mp_clocks_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct device_node *np;
void __iomem *anatop_base, *ccm_base;
int err;
np = of_find_compatible_node(NULL, NULL, "fsl,imx8mp-anatop");
anatop_base = of_iomap(np, 0);
anatop_base = devm_of_iomap(dev, np, 0, NULL);
of_node_put(np);
if (WARN_ON(!anatop_base))
return -ENOMEM;
if (WARN_ON(IS_ERR(anatop_base)))
return PTR_ERR(anatop_base);
np = dev->of_node;
ccm_base = devm_platform_ioremap_resource(pdev, 0);
if (WARN_ON(IS_ERR(ccm_base))) {
iounmap(anatop_base);
if (WARN_ON(IS_ERR(ccm_base)))
return PTR_ERR(ccm_base);
}
clk_hw_data = kzalloc(struct_size(clk_hw_data, hws, IMX8MP_CLK_END), GFP_KERNEL);
if (WARN_ON(!clk_hw_data)) {
iounmap(anatop_base);
clk_hw_data = devm_kzalloc(dev, struct_size(clk_hw_data, hws, IMX8MP_CLK_END), GFP_KERNEL);
if (WARN_ON(!clk_hw_data))
return -ENOMEM;
}
clk_hw_data->num = IMX8MP_CLK_END;
hws = clk_hw_data->hws;
......@@ -722,7 +719,12 @@ static int imx8mp_clocks_probe(struct platform_device *pdev)
imx_check_clk_hws(hws, IMX8MP_CLK_END);
of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data);
err = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data);
if (err < 0) {
dev_err(dev, "failed to register hws for i.MX8MP\n");
imx_unregister_hw_clocks(hws, IMX8MP_CLK_END);
return err;
}
imx_register_uart_clocks();
......
......@@ -264,7 +264,7 @@ static int imx93_clocks_probe(struct platform_device *pdev)
void __iomem *base, *anatop_base;
int i, ret;
clk_hw_data = kzalloc(struct_size(clk_hw_data, hws,
clk_hw_data = devm_kzalloc(dev, struct_size(clk_hw_data, hws,
IMX93_CLK_END), GFP_KERNEL);
if (!clk_hw_data)
return -ENOMEM;
......@@ -288,10 +288,12 @@ static int imx93_clocks_probe(struct platform_device *pdev)
"sys_pll_pfd2", 1, 2);
np = of_find_compatible_node(NULL, NULL, "fsl,imx93-anatop");
anatop_base = of_iomap(np, 0);
anatop_base = devm_of_iomap(dev, np, 0, NULL);
of_node_put(np);
if (WARN_ON(!anatop_base))
return -ENOMEM;
if (WARN_ON(IS_ERR(anatop_base))) {
ret = PTR_ERR(base);
goto unregister_hws;
}
clks[IMX93_CLK_ARM_PLL] = imx_clk_fracn_gppll_integer("arm_pll", "osc_24m",
anatop_base + 0x1000,
......@@ -304,8 +306,8 @@ static int imx93_clocks_probe(struct platform_device *pdev)
np = dev->of_node;
base = devm_platform_ioremap_resource(pdev, 0);
if (WARN_ON(IS_ERR(base))) {
iounmap(anatop_base);
return PTR_ERR(base);
ret = PTR_ERR(base);
goto unregister_hws;
}
for (i = 0; i < ARRAY_SIZE(root_array); i++) {
......@@ -345,7 +347,6 @@ static int imx93_clocks_probe(struct platform_device *pdev)
unregister_hws:
imx_unregister_hw_clocks(clks, IMX93_CLK_END);
iounmap(anatop_base);
return ret;
}
......
......@@ -42,7 +42,7 @@ static int imxrt1050_clocks_probe(struct platform_device *pdev)
struct device_node *anp;
int ret;
clk_hw_data = kzalloc(struct_size(clk_hw_data, hws,
clk_hw_data = devm_kzalloc(dev, struct_size(clk_hw_data, hws,
IMXRT1050_CLK_END), GFP_KERNEL);
if (WARN_ON(!clk_hw_data))
return -ENOMEM;
......@@ -53,10 +53,12 @@ static int imxrt1050_clocks_probe(struct platform_device *pdev)
hws[IMXRT1050_CLK_OSC] = imx_get_clk_hw_by_name(np, "osc");
anp = of_find_compatible_node(NULL, NULL, "fsl,imxrt-anatop");
pll_base = of_iomap(anp, 0);
pll_base = devm_of_iomap(dev, anp, 0, NULL);
of_node_put(anp);
if (WARN_ON(!pll_base))
return -ENOMEM;
if (WARN_ON(IS_ERR(pll_base))) {
ret = PTR_ERR(pll_base);
goto unregister_hws;
}
/* Anatop clocks */
hws[IMXRT1050_CLK_DUMMY] = imx_clk_hw_fixed("dummy", 0UL);
......@@ -104,8 +106,10 @@ static int imxrt1050_clocks_probe(struct platform_device *pdev)
/* CCM clocks */
ccm_base = devm_platform_ioremap_resource(pdev, 0);
if (WARN_ON(IS_ERR(ccm_base)))
return PTR_ERR(ccm_base);
if (WARN_ON(IS_ERR(ccm_base))) {
ret = PTR_ERR(ccm_base);
goto unregister_hws;
}
hws[IMXRT1050_CLK_ARM_PODF] = imx_clk_hw_divider("arm_podf", "pll1_arm", ccm_base + 0x10, 0, 3);
hws[IMXRT1050_CLK_PRE_PERIPH_SEL] = imx_clk_hw_mux("pre_periph_sel", ccm_base + 0x18, 18, 2,
......@@ -149,8 +153,12 @@ static int imxrt1050_clocks_probe(struct platform_device *pdev)
ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data);
if (ret < 0) {
dev_err(dev, "Failed to register clks for i.MXRT1050.\n");
imx_unregister_hw_clocks(hws, IMXRT1050_CLK_END);
goto unregister_hws;
}
return 0;
unregister_hws:
imx_unregister_hw_clocks(hws, IMXRT1050_CLK_END);
return ret;
}
static const struct of_device_id imxrt1050_clk_of_match[] = {
......
......@@ -724,11 +724,11 @@ struct clk_hw *imx_clk_scu_alloc_dev(const char *name,
void imx_clk_scu_unregister(void)
{
struct imx_scu_clk_node *clk;
struct imx_scu_clk_node *clk, *n;
int i;
for (i = 0; i < IMX_SC_R_LAST; i++) {
list_for_each_entry(clk, &imx_scu_clks[i], node) {
list_for_each_entry_safe(clk, n, &imx_scu_clks[i], node) {
clk_hw_unregister(clk->hw);
kfree(clk);
}
......
......@@ -20,14 +20,6 @@ EXPORT_SYMBOL_GPL(imx_ccm_lock);
bool mcore_booted;
EXPORT_SYMBOL_GPL(mcore_booted);
void imx_unregister_clocks(struct clk *clks[], unsigned int count)
{
unsigned int i;
for (i = 0; i < count; i++)
clk_unregister(clks[i]);
}
void imx_unregister_hw_clocks(struct clk_hw *hws[], unsigned int count)
{
unsigned int i;
......
......@@ -19,7 +19,6 @@ static inline void imx_register_uart_clocks(void)
}
#endif
void imx_mmdc_mask_handshake(void __iomem *ccm_base, unsigned int chn);
void imx_unregister_clocks(struct clk *clks[], unsigned int count);
void imx_unregister_hw_clocks(struct clk_hw *hws[], unsigned int count);
extern void imx_cscmr1_fixup(u32 *val);
......
......@@ -294,6 +294,8 @@ static int _sci_clk_build(struct sci_clk_provider *provider,
name = kasprintf(GFP_KERNEL, "clk:%d:%d", sci_clk->dev_id,
sci_clk->clk_id);
if (!name)
return -ENOMEM;
init.name = name;
......
......@@ -4,10 +4,12 @@
*/
#include <linux/clk-provider.h>
#include <linux/kernel.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/slab.h>
struct ti_syscon_gate_clk_priv {
struct clk_hw hw;
......@@ -61,21 +63,31 @@ static const struct clk_ops ti_syscon_gate_clk_ops = {
static struct clk_hw
*ti_syscon_gate_clk_register(struct device *dev, struct regmap *regmap,
const char *parent_name,
const struct ti_syscon_gate_clk_data *data)
{
struct ti_syscon_gate_clk_priv *priv;
struct clk_init_data init;
char *name = NULL;
int ret;
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return ERR_PTR(-ENOMEM);
init.name = data->name;
init.ops = &ti_syscon_gate_clk_ops;
init.parent_names = NULL;
init.num_parents = 0;
init.flags = 0;
if (parent_name) {
name = kasprintf(GFP_KERNEL, "%s:%s", data->name, parent_name);
init.name = name;
init.parent_names = &parent_name;
init.num_parents = 1;
init.flags = CLK_SET_RATE_PARENT;
} else {
init.name = data->name;
init.parent_names = NULL;
init.num_parents = 0;
init.flags = 0;
}
priv->regmap = regmap;
priv->reg = data->offset;
......@@ -83,6 +95,10 @@ static struct clk_hw
priv->hw.init = &init;
ret = devm_clk_hw_register(dev, &priv->hw);
if (name)
kfree(init.name);
if (ret)
return ERR_PTR(ret);
......@@ -94,22 +110,30 @@ static int ti_syscon_gate_clk_probe(struct platform_device *pdev)
const struct ti_syscon_gate_clk_data *data, *p;
struct clk_hw_onecell_data *hw_data;
struct device *dev = &pdev->dev;
int num_clks, num_parents, i;
const char *parent_name;
struct regmap *regmap;
int num_clks, i;
data = device_get_match_data(dev);
if (!data)
return -EINVAL;
regmap = syscon_node_to_regmap(dev->of_node);
regmap = device_node_to_regmap(dev->of_node);
if (IS_ERR(regmap))
return dev_err_probe(dev, PTR_ERR(regmap),
"failed to find parent regmap\n");
"failed to get regmap\n");
num_clks = 0;
for (p = data; p->name; p++)
num_clks++;
num_parents = of_clk_get_parent_count(dev->of_node);
if (of_device_is_compatible(dev->of_node, "ti,am62-audio-refclk") &&
num_parents == 0) {
return dev_err_probe(dev, -EINVAL,
"must specify a parent clock\n");
}
hw_data = devm_kzalloc(dev, struct_size(hw_data, hws, num_clks),
GFP_KERNEL);
if (!hw_data)
......@@ -117,8 +141,10 @@ static int ti_syscon_gate_clk_probe(struct platform_device *pdev)
hw_data->num = num_clks;
parent_name = of_clk_get_parent_name(dev->of_node, 0);
for (i = 0; i < num_clks; i++) {
hw_data->hws[i] = ti_syscon_gate_clk_register(dev, regmap,
parent_name,
&data[i]);
if (IS_ERR(hw_data->hws[i]))
dev_warn(dev, "failed to register %s\n",
......@@ -166,6 +192,11 @@ static const struct ti_syscon_gate_clk_data am62_clk_data[] = {
{ /* Sentinel */ },
};
static const struct ti_syscon_gate_clk_data am62_audio_clk_data[] = {
TI_SYSCON_CLK_GATE("audio_refclk", 0x0, 15),
{ /* Sentinel */ },
};
static const struct of_device_id ti_syscon_gate_clk_ids[] = {
{
.compatible = "ti,am654-ehrpwm-tbclk",
......@@ -179,6 +210,10 @@ static const struct of_device_id ti_syscon_gate_clk_ids[] = {
.compatible = "ti,am62-epwm-tbclk",
.data = &am62_clk_data,
},
{
.compatible = "ti,am62-audio-refclk",
.data = &am62_audio_clk_data,
},
{ }
};
MODULE_DEVICE_TABLE(of, ti_syscon_gate_clk_ids);
......
......@@ -5,8 +5,8 @@ config COMMON_CLK_PIC32
config MCHP_CLK_MPFS
bool "Clk driver for PolarFire SoC"
depends on SOC_MICROCHIP_POLARFIRE || COMPILE_TEST
default SOC_MICROCHIP_POLARFIRE
depends on ARCH_MICROCHIP_POLARFIRE || COMPILE_TEST
default ARCH_MICROCHIP_POLARFIRE
select AUXILIARY_BUS
help
Supports Clock Configuration for PolarFire SoC
......@@ -184,7 +184,7 @@ static int pic32mzda_clk_probe(struct platform_device *pdev)
clks[UPLLCLK] = clk_register_fixed_rate(&pdev->dev, "usbphy_clk", NULL,
0, 24000000);
/* fixed rate (optional) clock */
if (of_find_property(np, "microchip,pic32mzda-sosc", NULL)) {
if (of_property_read_bool(np, "microchip,pic32mzda-sosc")) {
pr_info("pic32-clk: dt requests SOSC.\n");
clks[SOSCCLK] = pic32_sosc_clk_register(&sosc_clk, core);
}
......
......@@ -253,12 +253,12 @@ static int ap_cpu_clock_probe(struct platform_device *pdev)
*/
nclusters = 1;
for_each_of_cpu_node(dn) {
int cpu, err;
u64 cpu;
err = of_property_read_u32(dn, "reg", &cpu);
if (WARN_ON(err)) {
cpu = of_get_cpu_hwid(dn, 0);
if (WARN_ON(cpu == OF_BAD_ADDR)) {
of_node_put(dn);
return err;
return -EINVAL;
}
/* If cpu2 or cpu3 is enabled */
......@@ -288,12 +288,12 @@ static int ap_cpu_clock_probe(struct platform_device *pdev)
struct clk_init_data init;
const char *parent_name;
struct clk *parent;
int cpu, err;
u64 cpu;
err = of_property_read_u32(dn, "reg", &cpu);
if (WARN_ON(err)) {
cpu = of_get_cpu_hwid(dn, 0);
if (WARN_ON(cpu == OF_BAD_ADDR)) {
of_node_put(dn);
return err;
return -EINVAL;
}
cluster_index = cpu & APN806_CLUSTER_NUM_MASK;
......
......@@ -16,15 +16,13 @@
char *ap_cp_unique_name(struct device *dev, struct device_node *np,
const char *name)
{
const __be32 *reg;
u64 addr;
struct resource res;
/* Do not create a name if there is no clock */
if (!name)
return NULL;
reg = of_get_property(np, "reg", NULL);
addr = of_translate_address(np, reg);
of_address_to_resource(np, 0, &res);
return devm_kasprintf(dev, GFP_KERNEL, "%llx-%s",
(unsigned long long)addr, name);
(unsigned long long)res.start, name);
}
......@@ -168,8 +168,8 @@ static void __init of_cpu_clk_setup(struct device_node *node)
struct cpu_clk *cpuclk;
void __iomem *clock_complex_base = of_iomap(node, 0);
void __iomem *pmu_dfs_base = of_iomap(node, 1);
int ncpus = 0;
struct device_node *dn;
int ncpus = num_possible_cpus();
int cpu;
if (clock_complex_base == NULL) {
pr_err("%s: clock-complex base register not set\n",
......@@ -181,9 +181,6 @@ static void __init of_cpu_clk_setup(struct device_node *node)
pr_warn("%s: pmu-dfs base register not set, dynamic frequency scaling not available\n",
__func__);
for_each_of_cpu_node(dn)
ncpus++;
cpuclk = kcalloc(ncpus, sizeof(*cpuclk), GFP_KERNEL);
if (WARN_ON(!cpuclk))
goto cpuclk_out;
......@@ -192,19 +189,14 @@ static void __init of_cpu_clk_setup(struct device_node *node)
if (WARN_ON(!clks))
goto clks_out;
for_each_of_cpu_node(dn) {
for_each_possible_cpu(cpu) {
struct clk_init_data init;
struct clk *clk;
char *clk_name = kzalloc(5, GFP_KERNEL);
int cpu, err;
if (WARN_ON(!clk_name))
goto bail_out;
err = of_property_read_u32(dn, "reg", &cpu);
if (WARN_ON(err))
goto bail_out;
sprintf(clk_name, "cpu%d", cpu);
cpuclk[cpu].parent_name = of_clk_get_parent_name(node, 0);
......
......@@ -567,7 +567,6 @@ static int __prci_register_clocks(struct device *dev, struct __prci_data *pd,
static int sifive_prci_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct resource *res;
struct __prci_data *pd;
const struct prci_clk_desc *desc;
int r;
......@@ -578,8 +577,7 @@ static int sifive_prci_probe(struct platform_device *pdev)
if (!pd)
return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
pd->va = devm_ioremap_resource(dev, res);
pd->va = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(pd->va))
return PTR_ERR(pd->va);
......
......@@ -464,6 +464,7 @@ static int load_timings_from_dt(struct tegra_clk_emc *tegra,
err = load_one_timing_from_dt(tegra, timing, child);
if (err) {
of_node_put(child);
kfree(tegra->timings);
return err;
}
......@@ -515,6 +516,7 @@ struct clk *tegra124_clk_register_emc(void __iomem *base, struct device_node *np
err = load_timings_from_dt(tegra, node, node_ram_code);
if (err) {
of_node_put(node);
kfree(tegra);
return ERR_PTR(err);
}
}
......
......@@ -258,6 +258,9 @@ static const char * __init clkctrl_get_clock_name(struct device_node *np,
if (clkctrl_name && !legacy_naming) {
clock_name = kasprintf(GFP_KERNEL, "%s-clkctrl:%04x:%d",
clkctrl_name, offset, index);
if (!clock_name)
return NULL;
strreplace(clock_name, '_', '-');
return clock_name;
......@@ -586,6 +589,10 @@ static void __init _ti_omap4_clkctrl_setup(struct device_node *node)
if (clkctrl_name) {
provider->clkdm_name = kasprintf(GFP_KERNEL,
"%s_clkdm", clkctrl_name);
if (!provider->clkdm_name) {
kfree(provider);
return;
}
goto clkdm_found;
}
......
......@@ -525,7 +525,7 @@ static struct clk *clk_wzrd_register_divider(struct device *dev,
hw = &div->hw;
ret = devm_clk_hw_register(dev, hw);
if (ret)
hw = ERR_PTR(ret);
return ERR_PTR(ret);
return hw->clk;
}
......@@ -648,6 +648,11 @@ static int clk_wzrd_probe(struct platform_device *pdev)
}
clkout_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s_out0", dev_name(&pdev->dev));
if (!clkout_name) {
ret = -ENOMEM;
goto err_disable_clk;
}
if (nr_outputs == 1) {
clk_wzrd->clkout[0] = clk_wzrd_register_divider
(&pdev->dev, clkout_name,
......
/* SPDX-License-Identifier: GPL-2.0+ or BSD-3-Clause */
/* SPDX-License-Identifier: GPL-2.0-only OR BSD-3-Clause */
/*
* Copyright (C) STMicroelectronics 2020 - All Rights Reserved
* Author: Gabriel Fernandez <gabriel.fernandez@st.com> for STMicroelectronics.
* Author: Gabriel Fernandez <gabriel.fernandez@foss.st.com> for STMicroelectronics.
*/
#ifndef _DT_BINDINGS_STM32MP13_CLKS_H_
......@@ -64,7 +64,7 @@
#define CK_MCO1 38
#define CK_MCO2 39
/* IP clocks */
/* IP clocks */
#define SYSCFG 40
#define VREF 41
#define DTS 42
......
/* SPDX-License-Identifier: GPL-2.0 or BSD-3-Clause */
/* SPDX-License-Identifier: GPL-2.0-only OR BSD-3-Clause */
/*
* Copyright (C) STMicroelectronics 2018 - All Rights Reserved
* Author: Gabriel Fernandez <gabriel.fernandez@st.com> for STMicroelectronics.
* Author: Gabriel Fernandez <gabriel.fernandez@foss.st.com> for STMicroelectronics.
*/
#ifndef _DT_BINDINGS_STM32MP13_RESET_H_
......
......@@ -415,7 +415,7 @@ struct clk *clk_register_fixed_rate(struct device *dev, const char *name,
* @flags: framework-specific flags
* @fixed_rate: non-adjustable clock rate
*/
#define clk_hw_register_fixed_rate_parent_data(dev, name, parent_hw, flags, \
#define clk_hw_register_fixed_rate_parent_data(dev, name, parent_data, flags, \
fixed_rate) \
__clk_hw_register_fixed_rate((dev), NULL, (name), NULL, NULL, \
(parent_data), (flags), (fixed_rate), 0, \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment