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: ...@@ -24,6 +24,9 @@ properties:
reg: reg:
maxItems: 1 maxItems: 1
interrupts:
maxItems: 2
clocks: clocks:
minItems: 6 minItems: 6
maxItems: 7 maxItems: 7
......
...@@ -98,9 +98,9 @@ required: ...@@ -98,9 +98,9 @@ required:
patternProperties: patternProperties:
"^usb-phy@[a-f0-9]+$": "^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]+$": "^mac-phy-ctrl@[a-f0-9]+$":
allOf: [ $ref: "../net/ingenic,mac.yaml#" ] $ref: /schemas/net/ingenic,mac.yaml#
additionalProperties: false additionalProperties: false
......
...@@ -48,7 +48,7 @@ properties: ...@@ -48,7 +48,7 @@ properties:
patternProperties: patternProperties:
"^dma-router@[a-f0-9]+$": "^dma-router@[a-f0-9]+$":
type: object type: object
$ref: "../dma/renesas,rzn1-dmamux.yaml#" $ref: /schemas/dma/renesas,rzn1-dmamux.yaml#
required: required:
- compatible - 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: ...@@ -16,7 +16,6 @@ properties:
- ti,am654-ehrpwm-tbclk - ti,am654-ehrpwm-tbclk
- ti,am64-epwm-tbclk - ti,am64-epwm-tbclk
- ti,am62-epwm-tbclk - ti,am62-epwm-tbclk
- const: syscon
"#clock-cells": "#clock-cells":
const: 1 const: 1
...@@ -33,8 +32,8 @@ additionalProperties: false ...@@ -33,8 +32,8 @@ additionalProperties: false
examples: examples:
- | - |
ehrpwm_tbclk: syscon@4140 { ehrpwm_tbclk: clock@4140 {
compatible = "ti,am654-ehrpwm-tbclk", "syscon"; compatible = "ti,am654-ehrpwm-tbclk";
reg = <0x4140 0x18>; reg = <0x4140 0x18>;
#clock-cells = <1>; #clock-cells = <1>;
}; };
...@@ -2365,6 +2365,7 @@ F: arch/arm/configs/mvebu_*_defconfig ...@@ -2365,6 +2365,7 @@ F: arch/arm/configs/mvebu_*_defconfig
F: arch/arm/mach-mvebu/ F: arch/arm/mach-mvebu/
F: arch/arm64/boot/dts/marvell/armada* F: arch/arm64/boot/dts/marvell/armada*
F: arch/arm64/boot/dts/marvell/cn913* F: arch/arm64/boot/dts/marvell/cn913*
F: drivers/clk/mvebu/
F: drivers/cpufreq/armada-37xx-cpufreq.c F: drivers/cpufreq/armada-37xx-cpufreq.c
F: drivers/cpufreq/armada-8k-cpufreq.c F: drivers/cpufreq/armada-8k-cpufreq.c
F: drivers/cpufreq/mvebu-cpufreq.c F: drivers/cpufreq/mvebu-cpufreq.c
......
...@@ -356,9 +356,9 @@ static int raspberrypi_discover_clocks(struct raspberrypi_clk *rpi, ...@@ -356,9 +356,9 @@ static int raspberrypi_discover_clocks(struct raspberrypi_clk *rpi,
while (clks->id) { while (clks->id) {
struct raspberrypi_clk_variant *variant; 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", 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; return -EINVAL;
} }
......
...@@ -701,6 +701,10 @@ static int cdce925_probe(struct i2c_client *client) ...@@ -701,6 +701,10 @@ static int cdce925_probe(struct i2c_client *client)
for (i = 0; i < data->chip_info->num_plls; ++i) { for (i = 0; i < data->chip_info->num_plls; ++i) {
pll_clk_name[i] = kasprintf(GFP_KERNEL, "%pOFn.pll%d", pll_clk_name[i] = kasprintf(GFP_KERNEL, "%pOFn.pll%d",
client->dev.of_node, i); client->dev.of_node, i);
if (!pll_clk_name[i]) {
err = -ENOMEM;
goto error;
}
init.name = pll_clk_name[i]; init.name = pll_clk_name[i];
data->pll[i].chip = data; data->pll[i].chip = data;
data->pll[i].hw.init = &init; data->pll[i].hw.init = &init;
...@@ -742,6 +746,10 @@ static int cdce925_probe(struct i2c_client *client) ...@@ -742,6 +746,10 @@ static int cdce925_probe(struct i2c_client *client)
init.num_parents = 1; init.num_parents = 1;
init.parent_names = &parent_name; /* Mux Y1 to input */ init.parent_names = &parent_name; /* Mux Y1 to input */
init.name = kasprintf(GFP_KERNEL, "%pOFn.Y1", client->dev.of_node); 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].chip = data;
data->clk[0].hw.init = &init; data->clk[0].hw.init = &init;
data->clk[0].index = 0; data->clk[0].index = 0;
...@@ -760,6 +768,10 @@ static int cdce925_probe(struct i2c_client *client) ...@@ -760,6 +768,10 @@ static int cdce925_probe(struct i2c_client *client)
for (i = 1; i < data->chip_info->num_outputs; ++i) { for (i = 1; i < data->chip_info->num_outputs; ++i) {
init.name = kasprintf(GFP_KERNEL, "%pOFn.Y%d", init.name = kasprintf(GFP_KERNEL, "%pOFn.Y%d",
client->dev.of_node, i+1); client->dev.of_node, i+1);
if (!init.name) {
err = -ENOMEM;
goto error;
}
data->clk[i].chip = data; data->clk[i].chip = data;
data->clk[i].hw.init = &init; data->clk[i].hw.init = &init;
data->clk[i].index = i; data->clk[i].index = i;
......
...@@ -1556,7 +1556,7 @@ static int si5341_probe(struct i2c_client *client) ...@@ -1556,7 +1556,7 @@ static int si5341_probe(struct i2c_client *client)
struct clk_init_data init; struct clk_init_data init;
struct clk *input; struct clk *input;
const char *root_clock_name; const char *root_clock_name;
const char *synth_clock_names[SI5341_NUM_SYNTH]; const char *synth_clock_names[SI5341_NUM_SYNTH] = { NULL };
int err; int err;
unsigned int i; unsigned int i;
struct clk_si5341_output_config config[SI5341_MAX_NUM_OUTPUTS]; struct clk_si5341_output_config config[SI5341_MAX_NUM_OUTPUTS];
...@@ -1700,6 +1700,10 @@ static int si5341_probe(struct i2c_client *client) ...@@ -1700,6 +1700,10 @@ static int si5341_probe(struct i2c_client *client)
for (i = 0; i < data->num_synth; ++i) { for (i = 0; i < data->num_synth; ++i) {
synth_clock_names[i] = devm_kasprintf(&client->dev, GFP_KERNEL, synth_clock_names[i] = devm_kasprintf(&client->dev, GFP_KERNEL,
"%s.N%u", client->dev.of_node->name, i); "%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]; init.name = synth_clock_names[i];
data->synth[i].index = i; data->synth[i].index = i;
data->synth[i].data = data; data->synth[i].data = data;
...@@ -1708,6 +1712,7 @@ static int si5341_probe(struct i2c_client *client) ...@@ -1708,6 +1712,7 @@ static int si5341_probe(struct i2c_client *client)
if (err) { if (err) {
dev_err(&client->dev, dev_err(&client->dev,
"synth N%u registration failed\n", i); "synth N%u registration failed\n", i);
goto free_clk_names;
} }
} }
...@@ -1717,6 +1722,10 @@ static int si5341_probe(struct i2c_client *client) ...@@ -1717,6 +1722,10 @@ static int si5341_probe(struct i2c_client *client)
for (i = 0; i < data->num_outputs; ++i) { for (i = 0; i < data->num_outputs; ++i) {
init.name = kasprintf(GFP_KERNEL, "%s.%d", init.name = kasprintf(GFP_KERNEL, "%s.%d",
client->dev.of_node->name, i); 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; init.flags = config[i].synth_master ? CLK_SET_RATE_PARENT : 0;
data->clk[i].index = i; data->clk[i].index = i;
data->clk[i].data = data; data->clk[i].data = data;
...@@ -1738,7 +1747,7 @@ static int si5341_probe(struct i2c_client *client) ...@@ -1738,7 +1747,7 @@ static int si5341_probe(struct i2c_client *client)
if (err) { if (err) {
dev_err(&client->dev, dev_err(&client->dev,
"output %u registration failed\n", i); "output %u registration failed\n", i);
goto cleanup; goto free_clk_names;
} }
if (config[i].always_on) if (config[i].always_on)
clk_prepare(data->clk[i].hw.clk); clk_prepare(data->clk[i].hw.clk);
...@@ -1748,7 +1757,7 @@ static int si5341_probe(struct i2c_client *client) ...@@ -1748,7 +1757,7 @@ static int si5341_probe(struct i2c_client *client)
data); data);
if (err) { if (err) {
dev_err(&client->dev, "unable to add clk provider\n"); dev_err(&client->dev, "unable to add clk provider\n");
goto cleanup; goto free_clk_names;
} }
if (initialization_required) { if (initialization_required) {
...@@ -1756,11 +1765,11 @@ static int si5341_probe(struct i2c_client *client) ...@@ -1756,11 +1765,11 @@ static int si5341_probe(struct i2c_client *client)
regcache_cache_only(data->regmap, false); regcache_cache_only(data->regmap, false);
err = regcache_sync(data->regmap); err = regcache_sync(data->regmap);
if (err < 0) if (err < 0)
goto cleanup; goto free_clk_names;
err = si5341_finalize_defaults(data); err = si5341_finalize_defaults(data);
if (err < 0) if (err < 0)
goto cleanup; goto free_clk_names;
} }
/* wait for device to report input clock present and PLL lock */ /* wait for device to report input clock present and PLL lock */
...@@ -1769,33 +1778,32 @@ static int si5341_probe(struct i2c_client *client) ...@@ -1769,33 +1778,32 @@ static int si5341_probe(struct i2c_client *client)
10000, 250000); 10000, 250000);
if (err) { if (err) {
dev_err(&client->dev, "Error waiting for input clock or PLL lock\n"); 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 */ /* clear sticky alarm bits from initialization */
err = regmap_write(data->regmap, SI5341_STATUS_STICKY, 0); err = regmap_write(data->regmap, SI5341_STATUS_STICKY, 0);
if (err) { if (err) {
dev_err(&client->dev, "unable to clear sticky status\n"); 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); err = sysfs_create_files(&client->dev.kobj, si5341_attributes);
if (err) { if (err)
dev_err(&client->dev, "unable to create sysfs files\n"); dev_err(&client->dev, "unable to create sysfs files\n");
goto cleanup;
}
free_clk_names:
/* Free the names, clk framework makes copies */ /* Free the names, clk framework makes copies */
for (i = 0; i < data->num_synth; ++i) for (i = 0; i < data->num_synth; ++i)
devm_kfree(&client->dev, (void *)synth_clock_names[i]); devm_kfree(&client->dev, (void *)synth_clock_names[i]);
return 0;
cleanup: cleanup:
if (err) {
for (i = 0; i < SI5341_MAX_NUM_OUTPUTS; ++i) { for (i = 0; i < SI5341_MAX_NUM_OUTPUTS; ++i) {
if (data->clk[i].vddo_reg) if (data->clk[i].vddo_reg)
regulator_disable(data->clk[i].vddo_reg); regulator_disable(data->clk[i].vddo_reg);
} }
}
return err; return err;
} }
......
...@@ -1031,6 +1031,11 @@ static int vc5_probe(struct i2c_client *client) ...@@ -1031,6 +1031,11 @@ static int vc5_probe(struct i2c_client *client)
} }
init.name = kasprintf(GFP_KERNEL, "%pOFn.mux", client->dev.of_node); 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.ops = &vc5_mux_ops;
init.flags = 0; init.flags = 0;
init.parent_names = parent_names; init.parent_names = parent_names;
...@@ -1045,6 +1050,10 @@ static int vc5_probe(struct i2c_client *client) ...@@ -1045,6 +1050,10 @@ static int vc5_probe(struct i2c_client *client)
memset(&init, 0, sizeof(init)); memset(&init, 0, sizeof(init));
init.name = kasprintf(GFP_KERNEL, "%pOFn.dbl", init.name = kasprintf(GFP_KERNEL, "%pOFn.dbl",
client->dev.of_node); client->dev.of_node);
if (!init.name) {
ret = -ENOMEM;
goto err_clk;
}
init.ops = &vc5_dbl_ops; init.ops = &vc5_dbl_ops;
init.flags = CLK_SET_RATE_PARENT; init.flags = CLK_SET_RATE_PARENT;
init.parent_names = parent_names; init.parent_names = parent_names;
...@@ -1060,6 +1069,10 @@ static int vc5_probe(struct i2c_client *client) ...@@ -1060,6 +1069,10 @@ static int vc5_probe(struct i2c_client *client)
/* Register PFD */ /* Register PFD */
memset(&init, 0, sizeof(init)); memset(&init, 0, sizeof(init));
init.name = kasprintf(GFP_KERNEL, "%pOFn.pfd", client->dev.of_node); 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.ops = &vc5_pfd_ops;
init.flags = CLK_SET_RATE_PARENT; init.flags = CLK_SET_RATE_PARENT;
init.parent_names = parent_names; init.parent_names = parent_names;
...@@ -1077,6 +1090,10 @@ static int vc5_probe(struct i2c_client *client) ...@@ -1077,6 +1090,10 @@ static int vc5_probe(struct i2c_client *client)
/* Register PLL */ /* Register PLL */
memset(&init, 0, sizeof(init)); memset(&init, 0, sizeof(init));
init.name = kasprintf(GFP_KERNEL, "%pOFn.pll", client->dev.of_node); 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.ops = &vc5_pll_ops;
init.flags = CLK_SET_RATE_PARENT; init.flags = CLK_SET_RATE_PARENT;
init.parent_names = parent_names; init.parent_names = parent_names;
...@@ -1096,6 +1113,10 @@ static int vc5_probe(struct i2c_client *client) ...@@ -1096,6 +1113,10 @@ static int vc5_probe(struct i2c_client *client)
memset(&init, 0, sizeof(init)); memset(&init, 0, sizeof(init));
init.name = kasprintf(GFP_KERNEL, "%pOFn.fod%d", init.name = kasprintf(GFP_KERNEL, "%pOFn.fod%d",
client->dev.of_node, idx); client->dev.of_node, idx);
if (!init.name) {
ret = -ENOMEM;
goto err_clk;
}
init.ops = &vc5_fod_ops; init.ops = &vc5_fod_ops;
init.flags = CLK_SET_RATE_PARENT; init.flags = CLK_SET_RATE_PARENT;
init.parent_names = parent_names; init.parent_names = parent_names;
...@@ -1114,6 +1135,10 @@ static int vc5_probe(struct i2c_client *client) ...@@ -1114,6 +1135,10 @@ static int vc5_probe(struct i2c_client *client)
memset(&init, 0, sizeof(init)); memset(&init, 0, sizeof(init));
init.name = kasprintf(GFP_KERNEL, "%pOFn.out0_sel_i2cb", init.name = kasprintf(GFP_KERNEL, "%pOFn.out0_sel_i2cb",
client->dev.of_node); client->dev.of_node);
if (!init.name) {
ret = -ENOMEM;
goto err_clk;
}
init.ops = &vc5_clk_out_ops; init.ops = &vc5_clk_out_ops;
init.flags = CLK_SET_RATE_PARENT; init.flags = CLK_SET_RATE_PARENT;
init.parent_names = parent_names; init.parent_names = parent_names;
...@@ -1140,6 +1165,10 @@ static int vc5_probe(struct i2c_client *client) ...@@ -1140,6 +1165,10 @@ static int vc5_probe(struct i2c_client *client)
memset(&init, 0, sizeof(init)); memset(&init, 0, sizeof(init));
init.name = kasprintf(GFP_KERNEL, "%pOFn.out%d", init.name = kasprintf(GFP_KERNEL, "%pOFn.out%d",
client->dev.of_node, idx + 1); client->dev.of_node, idx + 1);
if (!init.name) {
ret = -ENOMEM;
goto err_clk;
}
init.ops = &vc5_clk_out_ops; init.ops = &vc5_clk_out_ops;
init.flags = CLK_SET_RATE_PARENT; init.flags = CLK_SET_RATE_PARENT;
init.parent_names = parent_names; init.parent_names = parent_names;
......
...@@ -4741,6 +4741,7 @@ int devm_clk_notifier_register(struct device *dev, struct clk *clk, ...@@ -4741,6 +4741,7 @@ int devm_clk_notifier_register(struct device *dev, struct clk *clk,
if (!ret) { if (!ret) {
devres->clk = clk; devres->clk = clk;
devres->nb = nb; devres->nb = nb;
devres_add(dev, devres);
} else { } else {
devres_free(devres); devres_free(devres);
} }
......
...@@ -119,10 +119,41 @@ static int imx8m_clk_composite_divider_set_rate(struct clk_hw *hw, ...@@ -119,10 +119,41 @@ static int imx8m_clk_composite_divider_set_rate(struct clk_hw *hw,
return ret; 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 = { static const struct clk_ops imx8m_clk_composite_divider_ops = {
.recalc_rate = imx8m_clk_composite_divider_recalc_rate, .recalc_rate = imx8m_clk_composite_divider_recalc_rate,
.round_rate = imx8m_clk_composite_divider_round_rate, .round_rate = imx8m_clk_composite_divider_round_rate,
.set_rate = imx8m_clk_composite_divider_set_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) 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) ...@@ -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_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_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_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_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_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_flags("ldb_di1_sel", base + 0x2c, 12, 3, ldb_di1_sels, ARRAY_SIZE(ldb_di1_sels), CLK_SET_RATE_PARENT); 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_flags("ldb_di0_sel", base + 0x2c, 9, 3, ldb_di0_sels, ARRAY_SIZE(ldb_di0_sels), CLK_SET_RATE_PARENT); 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_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); 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) ...@@ -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_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); 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); CLK_OF_DECLARE(imx6ul, "fsl,imx6ul-ccm", imx6ul_clocks_init);
...@@ -323,7 +323,7 @@ static int imx8mn_clocks_probe(struct platform_device *pdev) ...@@ -323,7 +323,7 @@ static int imx8mn_clocks_probe(struct platform_device *pdev)
void __iomem *base; void __iomem *base;
int ret; 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); IMX8MN_CLK_END), GFP_KERNEL);
if (WARN_ON(!clk_hw_data)) if (WARN_ON(!clk_hw_data))
return -ENOMEM; return -ENOMEM;
...@@ -340,10 +340,10 @@ static int imx8mn_clocks_probe(struct platform_device *pdev) ...@@ -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"); hws[IMX8MN_CLK_EXT4] = imx_get_clk_hw_by_name(np, "clk_ext4");
np = of_find_compatible_node(NULL, NULL, "fsl,imx8mn-anatop"); 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); of_node_put(np);
if (WARN_ON(!base)) { if (WARN_ON(IS_ERR(base))) {
ret = -ENOMEM; ret = PTR_ERR(base);
goto unregister_hws; goto unregister_hws;
} }
......
...@@ -414,25 +414,22 @@ static int imx8mp_clocks_probe(struct platform_device *pdev) ...@@ -414,25 +414,22 @@ static int imx8mp_clocks_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct device_node *np; struct device_node *np;
void __iomem *anatop_base, *ccm_base; void __iomem *anatop_base, *ccm_base;
int err;
np = of_find_compatible_node(NULL, NULL, "fsl,imx8mp-anatop"); 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); of_node_put(np);
if (WARN_ON(!anatop_base)) if (WARN_ON(IS_ERR(anatop_base)))
return -ENOMEM; return PTR_ERR(anatop_base);
np = dev->of_node; np = dev->of_node;
ccm_base = devm_platform_ioremap_resource(pdev, 0); ccm_base = devm_platform_ioremap_resource(pdev, 0);
if (WARN_ON(IS_ERR(ccm_base))) { if (WARN_ON(IS_ERR(ccm_base)))
iounmap(anatop_base);
return PTR_ERR(ccm_base); return PTR_ERR(ccm_base);
}
clk_hw_data = kzalloc(struct_size(clk_hw_data, hws, IMX8MP_CLK_END), GFP_KERNEL); clk_hw_data = devm_kzalloc(dev, struct_size(clk_hw_data, hws, IMX8MP_CLK_END), GFP_KERNEL);
if (WARN_ON(!clk_hw_data)) { if (WARN_ON(!clk_hw_data))
iounmap(anatop_base);
return -ENOMEM; return -ENOMEM;
}
clk_hw_data->num = IMX8MP_CLK_END; clk_hw_data->num = IMX8MP_CLK_END;
hws = clk_hw_data->hws; hws = clk_hw_data->hws;
...@@ -722,7 +719,12 @@ static int imx8mp_clocks_probe(struct platform_device *pdev) ...@@ -722,7 +719,12 @@ static int imx8mp_clocks_probe(struct platform_device *pdev)
imx_check_clk_hws(hws, IMX8MP_CLK_END); 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(); imx_register_uart_clocks();
......
...@@ -264,7 +264,7 @@ static int imx93_clocks_probe(struct platform_device *pdev) ...@@ -264,7 +264,7 @@ static int imx93_clocks_probe(struct platform_device *pdev)
void __iomem *base, *anatop_base; void __iomem *base, *anatop_base;
int i, ret; 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); IMX93_CLK_END), GFP_KERNEL);
if (!clk_hw_data) if (!clk_hw_data)
return -ENOMEM; return -ENOMEM;
...@@ -288,10 +288,12 @@ static int imx93_clocks_probe(struct platform_device *pdev) ...@@ -288,10 +288,12 @@ static int imx93_clocks_probe(struct platform_device *pdev)
"sys_pll_pfd2", 1, 2); "sys_pll_pfd2", 1, 2);
np = of_find_compatible_node(NULL, NULL, "fsl,imx93-anatop"); 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); of_node_put(np);
if (WARN_ON(!anatop_base)) if (WARN_ON(IS_ERR(anatop_base))) {
return -ENOMEM; ret = PTR_ERR(base);
goto unregister_hws;
}
clks[IMX93_CLK_ARM_PLL] = imx_clk_fracn_gppll_integer("arm_pll", "osc_24m", clks[IMX93_CLK_ARM_PLL] = imx_clk_fracn_gppll_integer("arm_pll", "osc_24m",
anatop_base + 0x1000, anatop_base + 0x1000,
...@@ -304,8 +306,8 @@ static int imx93_clocks_probe(struct platform_device *pdev) ...@@ -304,8 +306,8 @@ static int imx93_clocks_probe(struct platform_device *pdev)
np = dev->of_node; np = dev->of_node;
base = devm_platform_ioremap_resource(pdev, 0); base = devm_platform_ioremap_resource(pdev, 0);
if (WARN_ON(IS_ERR(base))) { if (WARN_ON(IS_ERR(base))) {
iounmap(anatop_base); ret = PTR_ERR(base);
return PTR_ERR(base); goto unregister_hws;
} }
for (i = 0; i < ARRAY_SIZE(root_array); i++) { for (i = 0; i < ARRAY_SIZE(root_array); i++) {
...@@ -345,7 +347,6 @@ static int imx93_clocks_probe(struct platform_device *pdev) ...@@ -345,7 +347,6 @@ static int imx93_clocks_probe(struct platform_device *pdev)
unregister_hws: unregister_hws:
imx_unregister_hw_clocks(clks, IMX93_CLK_END); imx_unregister_hw_clocks(clks, IMX93_CLK_END);
iounmap(anatop_base);
return ret; return ret;
} }
......
...@@ -42,7 +42,7 @@ static int imxrt1050_clocks_probe(struct platform_device *pdev) ...@@ -42,7 +42,7 @@ static int imxrt1050_clocks_probe(struct platform_device *pdev)
struct device_node *anp; struct device_node *anp;
int ret; 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); IMXRT1050_CLK_END), GFP_KERNEL);
if (WARN_ON(!clk_hw_data)) if (WARN_ON(!clk_hw_data))
return -ENOMEM; return -ENOMEM;
...@@ -53,10 +53,12 @@ static int imxrt1050_clocks_probe(struct platform_device *pdev) ...@@ -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"); hws[IMXRT1050_CLK_OSC] = imx_get_clk_hw_by_name(np, "osc");
anp = of_find_compatible_node(NULL, NULL, "fsl,imxrt-anatop"); 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); of_node_put(anp);
if (WARN_ON(!pll_base)) if (WARN_ON(IS_ERR(pll_base))) {
return -ENOMEM; ret = PTR_ERR(pll_base);
goto unregister_hws;
}
/* Anatop clocks */ /* Anatop clocks */
hws[IMXRT1050_CLK_DUMMY] = imx_clk_hw_fixed("dummy", 0UL); hws[IMXRT1050_CLK_DUMMY] = imx_clk_hw_fixed("dummy", 0UL);
...@@ -104,8 +106,10 @@ static int imxrt1050_clocks_probe(struct platform_device *pdev) ...@@ -104,8 +106,10 @@ static int imxrt1050_clocks_probe(struct platform_device *pdev)
/* CCM clocks */ /* CCM clocks */
ccm_base = devm_platform_ioremap_resource(pdev, 0); ccm_base = devm_platform_ioremap_resource(pdev, 0);
if (WARN_ON(IS_ERR(ccm_base))) if (WARN_ON(IS_ERR(ccm_base))) {
return PTR_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_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, 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) ...@@ -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); ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data);
if (ret < 0) { if (ret < 0) {
dev_err(dev, "Failed to register clks for i.MXRT1050.\n"); 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; return ret;
} }
static const struct of_device_id imxrt1050_clk_of_match[] = { 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, ...@@ -724,11 +724,11 @@ struct clk_hw *imx_clk_scu_alloc_dev(const char *name,
void imx_clk_scu_unregister(void) void imx_clk_scu_unregister(void)
{ {
struct imx_scu_clk_node *clk; struct imx_scu_clk_node *clk, *n;
int i; int i;
for (i = 0; i < IMX_SC_R_LAST; 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); clk_hw_unregister(clk->hw);
kfree(clk); kfree(clk);
} }
......
...@@ -20,14 +20,6 @@ EXPORT_SYMBOL_GPL(imx_ccm_lock); ...@@ -20,14 +20,6 @@ EXPORT_SYMBOL_GPL(imx_ccm_lock);
bool mcore_booted; bool mcore_booted;
EXPORT_SYMBOL_GPL(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) void imx_unregister_hw_clocks(struct clk_hw *hws[], unsigned int count)
{ {
unsigned int i; unsigned int i;
......
...@@ -19,7 +19,6 @@ static inline void imx_register_uart_clocks(void) ...@@ -19,7 +19,6 @@ static inline void imx_register_uart_clocks(void)
} }
#endif #endif
void imx_mmdc_mask_handshake(void __iomem *ccm_base, unsigned int chn); 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); void imx_unregister_hw_clocks(struct clk_hw *hws[], unsigned int count);
extern void imx_cscmr1_fixup(u32 *val); extern void imx_cscmr1_fixup(u32 *val);
......
...@@ -294,6 +294,8 @@ static int _sci_clk_build(struct sci_clk_provider *provider, ...@@ -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, name = kasprintf(GFP_KERNEL, "clk:%d:%d", sci_clk->dev_id,
sci_clk->clk_id); sci_clk->clk_id);
if (!name)
return -ENOMEM;
init.name = name; init.name = name;
......
...@@ -4,10 +4,12 @@ ...@@ -4,10 +4,12 @@
*/ */
#include <linux/clk-provider.h> #include <linux/clk-provider.h>
#include <linux/kernel.h>
#include <linux/mfd/syscon.h> #include <linux/mfd/syscon.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/regmap.h> #include <linux/regmap.h>
#include <linux/slab.h>
struct ti_syscon_gate_clk_priv { struct ti_syscon_gate_clk_priv {
struct clk_hw hw; struct clk_hw hw;
...@@ -61,21 +63,31 @@ static const struct clk_ops ti_syscon_gate_clk_ops = { ...@@ -61,21 +63,31 @@ static const struct clk_ops ti_syscon_gate_clk_ops = {
static struct clk_hw static struct clk_hw
*ti_syscon_gate_clk_register(struct device *dev, struct regmap *regmap, *ti_syscon_gate_clk_register(struct device *dev, struct regmap *regmap,
const char *parent_name,
const struct ti_syscon_gate_clk_data *data) const struct ti_syscon_gate_clk_data *data)
{ {
struct ti_syscon_gate_clk_priv *priv; struct ti_syscon_gate_clk_priv *priv;
struct clk_init_data init; struct clk_init_data init;
char *name = NULL;
int ret; int ret;
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv) if (!priv)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
init.name = data->name;
init.ops = &ti_syscon_gate_clk_ops; init.ops = &ti_syscon_gate_clk_ops;
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.parent_names = NULL;
init.num_parents = 0; init.num_parents = 0;
init.flags = 0; init.flags = 0;
}
priv->regmap = regmap; priv->regmap = regmap;
priv->reg = data->offset; priv->reg = data->offset;
...@@ -83,6 +95,10 @@ static struct clk_hw ...@@ -83,6 +95,10 @@ static struct clk_hw
priv->hw.init = &init; priv->hw.init = &init;
ret = devm_clk_hw_register(dev, &priv->hw); ret = devm_clk_hw_register(dev, &priv->hw);
if (name)
kfree(init.name);
if (ret) if (ret)
return ERR_PTR(ret); return ERR_PTR(ret);
...@@ -94,22 +110,30 @@ static int ti_syscon_gate_clk_probe(struct platform_device *pdev) ...@@ -94,22 +110,30 @@ static int ti_syscon_gate_clk_probe(struct platform_device *pdev)
const struct ti_syscon_gate_clk_data *data, *p; const struct ti_syscon_gate_clk_data *data, *p;
struct clk_hw_onecell_data *hw_data; struct clk_hw_onecell_data *hw_data;
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
int num_clks, num_parents, i;
const char *parent_name;
struct regmap *regmap; struct regmap *regmap;
int num_clks, i;
data = device_get_match_data(dev); data = device_get_match_data(dev);
if (!data) if (!data)
return -EINVAL; return -EINVAL;
regmap = syscon_node_to_regmap(dev->of_node); regmap = device_node_to_regmap(dev->of_node);
if (IS_ERR(regmap)) if (IS_ERR(regmap))
return dev_err_probe(dev, PTR_ERR(regmap), return dev_err_probe(dev, PTR_ERR(regmap),
"failed to find parent regmap\n"); "failed to get regmap\n");
num_clks = 0; num_clks = 0;
for (p = data; p->name; p++) for (p = data; p->name; p++)
num_clks++; 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), hw_data = devm_kzalloc(dev, struct_size(hw_data, hws, num_clks),
GFP_KERNEL); GFP_KERNEL);
if (!hw_data) if (!hw_data)
...@@ -117,8 +141,10 @@ static int ti_syscon_gate_clk_probe(struct platform_device *pdev) ...@@ -117,8 +141,10 @@ static int ti_syscon_gate_clk_probe(struct platform_device *pdev)
hw_data->num = num_clks; hw_data->num = num_clks;
parent_name = of_clk_get_parent_name(dev->of_node, 0);
for (i = 0; i < num_clks; i++) { for (i = 0; i < num_clks; i++) {
hw_data->hws[i] = ti_syscon_gate_clk_register(dev, regmap, hw_data->hws[i] = ti_syscon_gate_clk_register(dev, regmap,
parent_name,
&data[i]); &data[i]);
if (IS_ERR(hw_data->hws[i])) if (IS_ERR(hw_data->hws[i]))
dev_warn(dev, "failed to register %s\n", dev_warn(dev, "failed to register %s\n",
...@@ -166,6 +192,11 @@ static const struct ti_syscon_gate_clk_data am62_clk_data[] = { ...@@ -166,6 +192,11 @@ static const struct ti_syscon_gate_clk_data am62_clk_data[] = {
{ /* Sentinel */ }, { /* 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[] = { static const struct of_device_id ti_syscon_gate_clk_ids[] = {
{ {
.compatible = "ti,am654-ehrpwm-tbclk", .compatible = "ti,am654-ehrpwm-tbclk",
...@@ -179,6 +210,10 @@ static const struct of_device_id ti_syscon_gate_clk_ids[] = { ...@@ -179,6 +210,10 @@ static const struct of_device_id ti_syscon_gate_clk_ids[] = {
.compatible = "ti,am62-epwm-tbclk", .compatible = "ti,am62-epwm-tbclk",
.data = &am62_clk_data, .data = &am62_clk_data,
}, },
{
.compatible = "ti,am62-audio-refclk",
.data = &am62_audio_clk_data,
},
{ } { }
}; };
MODULE_DEVICE_TABLE(of, ti_syscon_gate_clk_ids); MODULE_DEVICE_TABLE(of, ti_syscon_gate_clk_ids);
......
...@@ -5,8 +5,8 @@ config COMMON_CLK_PIC32 ...@@ -5,8 +5,8 @@ config COMMON_CLK_PIC32
config MCHP_CLK_MPFS config MCHP_CLK_MPFS
bool "Clk driver for PolarFire SoC" bool "Clk driver for PolarFire SoC"
depends on SOC_MICROCHIP_POLARFIRE || COMPILE_TEST depends on ARCH_MICROCHIP_POLARFIRE || COMPILE_TEST
default SOC_MICROCHIP_POLARFIRE default ARCH_MICROCHIP_POLARFIRE
select AUXILIARY_BUS select AUXILIARY_BUS
help help
Supports Clock Configuration for PolarFire SoC Supports Clock Configuration for PolarFire SoC
...@@ -184,7 +184,7 @@ static int pic32mzda_clk_probe(struct platform_device *pdev) ...@@ -184,7 +184,7 @@ static int pic32mzda_clk_probe(struct platform_device *pdev)
clks[UPLLCLK] = clk_register_fixed_rate(&pdev->dev, "usbphy_clk", NULL, clks[UPLLCLK] = clk_register_fixed_rate(&pdev->dev, "usbphy_clk", NULL,
0, 24000000); 0, 24000000);
/* fixed rate (optional) clock */ /* 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"); pr_info("pic32-clk: dt requests SOSC.\n");
clks[SOSCCLK] = pic32_sosc_clk_register(&sosc_clk, core); clks[SOSCCLK] = pic32_sosc_clk_register(&sosc_clk, core);
} }
......
...@@ -253,12 +253,12 @@ static int ap_cpu_clock_probe(struct platform_device *pdev) ...@@ -253,12 +253,12 @@ static int ap_cpu_clock_probe(struct platform_device *pdev)
*/ */
nclusters = 1; nclusters = 1;
for_each_of_cpu_node(dn) { for_each_of_cpu_node(dn) {
int cpu, err; u64 cpu;
err = of_property_read_u32(dn, "reg", &cpu); cpu = of_get_cpu_hwid(dn, 0);
if (WARN_ON(err)) { if (WARN_ON(cpu == OF_BAD_ADDR)) {
of_node_put(dn); of_node_put(dn);
return err; return -EINVAL;
} }
/* If cpu2 or cpu3 is enabled */ /* If cpu2 or cpu3 is enabled */
...@@ -288,12 +288,12 @@ static int ap_cpu_clock_probe(struct platform_device *pdev) ...@@ -288,12 +288,12 @@ static int ap_cpu_clock_probe(struct platform_device *pdev)
struct clk_init_data init; struct clk_init_data init;
const char *parent_name; const char *parent_name;
struct clk *parent; struct clk *parent;
int cpu, err; u64 cpu;
err = of_property_read_u32(dn, "reg", &cpu); cpu = of_get_cpu_hwid(dn, 0);
if (WARN_ON(err)) { if (WARN_ON(cpu == OF_BAD_ADDR)) {
of_node_put(dn); of_node_put(dn);
return err; return -EINVAL;
} }
cluster_index = cpu & APN806_CLUSTER_NUM_MASK; cluster_index = cpu & APN806_CLUSTER_NUM_MASK;
......
...@@ -16,15 +16,13 @@ ...@@ -16,15 +16,13 @@
char *ap_cp_unique_name(struct device *dev, struct device_node *np, char *ap_cp_unique_name(struct device *dev, struct device_node *np,
const char *name) const char *name)
{ {
const __be32 *reg; struct resource res;
u64 addr;
/* Do not create a name if there is no clock */ /* Do not create a name if there is no clock */
if (!name) if (!name)
return NULL; return NULL;
reg = of_get_property(np, "reg", NULL); of_address_to_resource(np, 0, &res);
addr = of_translate_address(np, reg);
return devm_kasprintf(dev, GFP_KERNEL, "%llx-%s", 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) ...@@ -168,8 +168,8 @@ static void __init of_cpu_clk_setup(struct device_node *node)
struct cpu_clk *cpuclk; struct cpu_clk *cpuclk;
void __iomem *clock_complex_base = of_iomap(node, 0); void __iomem *clock_complex_base = of_iomap(node, 0);
void __iomem *pmu_dfs_base = of_iomap(node, 1); void __iomem *pmu_dfs_base = of_iomap(node, 1);
int ncpus = 0; int ncpus = num_possible_cpus();
struct device_node *dn; int cpu;
if (clock_complex_base == NULL) { if (clock_complex_base == NULL) {
pr_err("%s: clock-complex base register not set\n", 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) ...@@ -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", pr_warn("%s: pmu-dfs base register not set, dynamic frequency scaling not available\n",
__func__); __func__);
for_each_of_cpu_node(dn)
ncpus++;
cpuclk = kcalloc(ncpus, sizeof(*cpuclk), GFP_KERNEL); cpuclk = kcalloc(ncpus, sizeof(*cpuclk), GFP_KERNEL);
if (WARN_ON(!cpuclk)) if (WARN_ON(!cpuclk))
goto cpuclk_out; goto cpuclk_out;
...@@ -192,19 +189,14 @@ static void __init of_cpu_clk_setup(struct device_node *node) ...@@ -192,19 +189,14 @@ static void __init of_cpu_clk_setup(struct device_node *node)
if (WARN_ON(!clks)) if (WARN_ON(!clks))
goto clks_out; goto clks_out;
for_each_of_cpu_node(dn) { for_each_possible_cpu(cpu) {
struct clk_init_data init; struct clk_init_data init;
struct clk *clk; struct clk *clk;
char *clk_name = kzalloc(5, GFP_KERNEL); char *clk_name = kzalloc(5, GFP_KERNEL);
int cpu, err;
if (WARN_ON(!clk_name)) if (WARN_ON(!clk_name))
goto bail_out; goto bail_out;
err = of_property_read_u32(dn, "reg", &cpu);
if (WARN_ON(err))
goto bail_out;
sprintf(clk_name, "cpu%d", cpu); sprintf(clk_name, "cpu%d", cpu);
cpuclk[cpu].parent_name = of_clk_get_parent_name(node, 0); 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, ...@@ -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) static int sifive_prci_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct resource *res;
struct __prci_data *pd; struct __prci_data *pd;
const struct prci_clk_desc *desc; const struct prci_clk_desc *desc;
int r; int r;
...@@ -578,8 +577,7 @@ static int sifive_prci_probe(struct platform_device *pdev) ...@@ -578,8 +577,7 @@ static int sifive_prci_probe(struct platform_device *pdev)
if (!pd) if (!pd)
return -ENOMEM; return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); pd->va = devm_platform_ioremap_resource(pdev, 0);
pd->va = devm_ioremap_resource(dev, res);
if (IS_ERR(pd->va)) if (IS_ERR(pd->va))
return PTR_ERR(pd->va); return PTR_ERR(pd->va);
......
...@@ -464,6 +464,7 @@ static int load_timings_from_dt(struct tegra_clk_emc *tegra, ...@@ -464,6 +464,7 @@ static int load_timings_from_dt(struct tegra_clk_emc *tegra,
err = load_one_timing_from_dt(tegra, timing, child); err = load_one_timing_from_dt(tegra, timing, child);
if (err) { if (err) {
of_node_put(child); of_node_put(child);
kfree(tegra->timings);
return err; return err;
} }
...@@ -515,6 +516,7 @@ struct clk *tegra124_clk_register_emc(void __iomem *base, struct device_node *np ...@@ -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); err = load_timings_from_dt(tegra, node, node_ram_code);
if (err) { if (err) {
of_node_put(node); of_node_put(node);
kfree(tegra);
return ERR_PTR(err); return ERR_PTR(err);
} }
} }
......
...@@ -258,6 +258,9 @@ static const char * __init clkctrl_get_clock_name(struct device_node *np, ...@@ -258,6 +258,9 @@ static const char * __init clkctrl_get_clock_name(struct device_node *np,
if (clkctrl_name && !legacy_naming) { if (clkctrl_name && !legacy_naming) {
clock_name = kasprintf(GFP_KERNEL, "%s-clkctrl:%04x:%d", clock_name = kasprintf(GFP_KERNEL, "%s-clkctrl:%04x:%d",
clkctrl_name, offset, index); clkctrl_name, offset, index);
if (!clock_name)
return NULL;
strreplace(clock_name, '_', '-'); strreplace(clock_name, '_', '-');
return clock_name; return clock_name;
...@@ -586,6 +589,10 @@ static void __init _ti_omap4_clkctrl_setup(struct device_node *node) ...@@ -586,6 +589,10 @@ static void __init _ti_omap4_clkctrl_setup(struct device_node *node)
if (clkctrl_name) { if (clkctrl_name) {
provider->clkdm_name = kasprintf(GFP_KERNEL, provider->clkdm_name = kasprintf(GFP_KERNEL,
"%s_clkdm", clkctrl_name); "%s_clkdm", clkctrl_name);
if (!provider->clkdm_name) {
kfree(provider);
return;
}
goto clkdm_found; goto clkdm_found;
} }
......
...@@ -525,7 +525,7 @@ static struct clk *clk_wzrd_register_divider(struct device *dev, ...@@ -525,7 +525,7 @@ static struct clk *clk_wzrd_register_divider(struct device *dev,
hw = &div->hw; hw = &div->hw;
ret = devm_clk_hw_register(dev, hw); ret = devm_clk_hw_register(dev, hw);
if (ret) if (ret)
hw = ERR_PTR(ret); return ERR_PTR(ret);
return hw->clk; return hw->clk;
} }
...@@ -648,6 +648,11 @@ static int clk_wzrd_probe(struct platform_device *pdev) ...@@ -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)); 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) { if (nr_outputs == 1) {
clk_wzrd->clkout[0] = clk_wzrd_register_divider clk_wzrd->clkout[0] = clk_wzrd_register_divider
(&pdev->dev, clkout_name, (&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 * 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_ #ifndef _DT_BINDINGS_STM32MP13_CLKS_H_
......
/* 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 * 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_ #ifndef _DT_BINDINGS_STM32MP13_RESET_H_
......
...@@ -415,7 +415,7 @@ struct clk *clk_register_fixed_rate(struct device *dev, const char *name, ...@@ -415,7 +415,7 @@ struct clk *clk_register_fixed_rate(struct device *dev, const char *name,
* @flags: framework-specific flags * @flags: framework-specific flags
* @fixed_rate: non-adjustable clock rate * @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) \ fixed_rate) \
__clk_hw_register_fixed_rate((dev), NULL, (name), NULL, NULL, \ __clk_hw_register_fixed_rate((dev), NULL, (name), NULL, NULL, \
(parent_data), (flags), (fixed_rate), 0, \ (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