Merge branches 'clk-cdce-regulator', 'clk-bcm', 'clk-evict-parent-cache' and 'clk-actions' into clk-next

- Add regulator support to the cdce925 clk driver
 - Add support for Raspberry Pi 4 bcm2711 SoCs
 - Evict parents from parent cache when they're unregistered

* clk-cdce-regulator:
  clk: clk-cdce925: Add regulator support
  dt-bindings: clock: cdce925: Add regulator documentation

* clk-bcm:
  clk: bcm2835: Mark PLLD_PER as CRITICAL
  clk: bcm2835: Add BCM2711_CLOCK_EMMC2 support
  clk: bcm2835: Introduce SoC specific clock registration
  dt-bindings: bcm2835-cprman: Add bcm2711 support

* clk-evict-parent-cache:
  clk: Evict unregistered clks from parent caches

* clk-actions:
  clk: actions: Fix factor clk struct member access
This commit is contained in:
Stephen Boyd 2019-09-19 15:31:46 -07:00
7 changed files with 202 additions and 29 deletions

View File

@ -12,7 +12,9 @@ clock generators, but a few (like the ARM or HDMI) will source from
the PLL dividers directly. the PLL dividers directly.
Required properties: Required properties:
- compatible: Should be "brcm,bcm2835-cprman" - compatible: should be one of the following,
"brcm,bcm2711-cprman"
"brcm,bcm2835-cprman"
- #clock-cells: Should be <1>. The permitted clock-specifier values can be - #clock-cells: Should be <1>. The permitted clock-specifier values can be
found in include/dt-bindings/clock/bcm2835.h found in include/dt-bindings/clock/bcm2835.h
- reg: Specifies base physical address and size of the registers - reg: Specifies base physical address and size of the registers

View File

@ -24,6 +24,8 @@ Required properties:
Optional properties: Optional properties:
- xtal-load-pf: Crystal load-capacitor value to fine-tune performance on a - xtal-load-pf: Crystal load-capacitor value to fine-tune performance on a
board, or to compensate for external influences. board, or to compensate for external influences.
- vdd-supply: A regulator node for Vdd
- vddout-supply: A regulator node for Vddout
For all PLL1, PLL2, ... an optional child node can be used to specify spread For all PLL1, PLL2, ... an optional child node can be used to specify spread
spectrum clocking parameters for a board. spectrum clocking parameters for a board.
@ -41,6 +43,8 @@ Example:
clocks = <&xtal_27Mhz>; clocks = <&xtal_27Mhz>;
#clock-cells = <1>; #clock-cells = <1>;
xtal-load-pf = <5>; xtal-load-pf = <5>;
vdd-supply = <&1v8-reg>;
vddout-supply = <&3v3-reg>;
/* PLL options to get SSC 1% centered */ /* PLL options to get SSC 1% centered */
PLL2 { PLL2 {
spread-spectrum = <4>; spread-spectrum = <4>;

View File

@ -64,11 +64,10 @@ static unsigned int _get_table_val(const struct clk_factor_table *table,
return val; return val;
} }
static int clk_val_best(struct clk_hw *hw, unsigned long rate, static int owl_clk_val_best(const struct owl_factor_hw *factor_hw,
struct clk_hw *hw, unsigned long rate,
unsigned long *best_parent_rate) unsigned long *best_parent_rate)
{ {
struct owl_factor *factor = hw_to_owl_factor(hw);
struct owl_factor_hw *factor_hw = &factor->factor_hw;
const struct clk_factor_table *clkt = factor_hw->table; const struct clk_factor_table *clkt = factor_hw->table;
unsigned long parent_rate, try_parent_rate, best = 0, cur_rate; unsigned long parent_rate, try_parent_rate, best = 0, cur_rate;
unsigned long parent_rate_saved = *best_parent_rate; unsigned long parent_rate_saved = *best_parent_rate;
@ -126,7 +125,7 @@ long owl_factor_helper_round_rate(struct owl_clk_common *common,
const struct clk_factor_table *clkt = factor_hw->table; const struct clk_factor_table *clkt = factor_hw->table;
unsigned int val, mul = 0, div = 1; unsigned int val, mul = 0, div = 1;
val = clk_val_best(&common->hw, rate, parent_rate); val = owl_clk_val_best(factor_hw, &common->hw, rate, parent_rate);
_get_table_div_mul(clkt, val, &mul, &div); _get_table_div_mul(clkt, val, &mul, &div);
return *parent_rate * mul / div; return *parent_rate * mul / div;

View File

@ -31,7 +31,7 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/of.h> #include <linux/of_device.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <dt-bindings/clock/bcm2835.h> #include <dt-bindings/clock/bcm2835.h>
@ -114,6 +114,8 @@
#define CM_AVEODIV 0x1bc #define CM_AVEODIV 0x1bc
#define CM_EMMCCTL 0x1c0 #define CM_EMMCCTL 0x1c0
#define CM_EMMCDIV 0x1c4 #define CM_EMMCDIV 0x1c4
#define CM_EMMC2CTL 0x1d0
#define CM_EMMC2DIV 0x1d4
/* General bits for the CM_*CTL regs */ /* General bits for the CM_*CTL regs */
# define CM_ENABLE BIT(4) # define CM_ENABLE BIT(4)
@ -289,6 +291,10 @@
#define LOCK_TIMEOUT_NS 100000000 #define LOCK_TIMEOUT_NS 100000000
#define BCM2835_MAX_FB_RATE 1750000000u #define BCM2835_MAX_FB_RATE 1750000000u
#define SOC_BCM2835 BIT(0)
#define SOC_BCM2711 BIT(1)
#define SOC_ALL (SOC_BCM2835 | SOC_BCM2711)
/* /*
* Names of clocks used within the driver that need to be replaced * Names of clocks used within the driver that need to be replaced
* with an external parent's name. This array is in the order that * with an external parent's name. This array is in the order that
@ -320,6 +326,10 @@ struct bcm2835_cprman {
struct clk_hw_onecell_data onecell; struct clk_hw_onecell_data onecell;
}; };
struct cprman_plat_data {
unsigned int soc;
};
static inline void cprman_write(struct bcm2835_cprman *cprman, u32 reg, u32 val) static inline void cprman_write(struct bcm2835_cprman *cprman, u32 reg, u32 val)
{ {
writel(CM_PASSWORD | val, cprman->regs + reg); writel(CM_PASSWORD | val, cprman->regs + reg);
@ -1451,22 +1461,28 @@ typedef struct clk_hw *(*bcm2835_clk_register)(struct bcm2835_cprman *cprman,
const void *data); const void *data);
struct bcm2835_clk_desc { struct bcm2835_clk_desc {
bcm2835_clk_register clk_register; bcm2835_clk_register clk_register;
unsigned int supported;
const void *data; const void *data;
}; };
/* assignment helper macros for different clock types */ /* assignment helper macros for different clock types */
#define _REGISTER(f, ...) { .clk_register = (bcm2835_clk_register)f, \ #define _REGISTER(f, s, ...) { .clk_register = (bcm2835_clk_register)f, \
.data = __VA_ARGS__ } .supported = s, \
#define REGISTER_PLL(...) _REGISTER(&bcm2835_register_pll, \ .data = __VA_ARGS__ }
#define REGISTER_PLL(s, ...) _REGISTER(&bcm2835_register_pll, \
s, \
&(struct bcm2835_pll_data) \ &(struct bcm2835_pll_data) \
{__VA_ARGS__}) {__VA_ARGS__})
#define REGISTER_PLL_DIV(...) _REGISTER(&bcm2835_register_pll_divider, \ #define REGISTER_PLL_DIV(s, ...) _REGISTER(&bcm2835_register_pll_divider, \
&(struct bcm2835_pll_divider_data) \ s, \
{__VA_ARGS__}) &(struct bcm2835_pll_divider_data) \
#define REGISTER_CLK(...) _REGISTER(&bcm2835_register_clock, \ {__VA_ARGS__})
#define REGISTER_CLK(s, ...) _REGISTER(&bcm2835_register_clock, \
s, \
&(struct bcm2835_clock_data) \ &(struct bcm2835_clock_data) \
{__VA_ARGS__}) {__VA_ARGS__})
#define REGISTER_GATE(...) _REGISTER(&bcm2835_register_gate, \ #define REGISTER_GATE(s, ...) _REGISTER(&bcm2835_register_gate, \
s, \
&(struct bcm2835_gate_data) \ &(struct bcm2835_gate_data) \
{__VA_ARGS__}) {__VA_ARGS__})
@ -1480,7 +1496,8 @@ static const char *const bcm2835_clock_osc_parents[] = {
"testdebug1" "testdebug1"
}; };
#define REGISTER_OSC_CLK(...) REGISTER_CLK( \ #define REGISTER_OSC_CLK(s, ...) REGISTER_CLK( \
s, \
.num_mux_parents = ARRAY_SIZE(bcm2835_clock_osc_parents), \ .num_mux_parents = ARRAY_SIZE(bcm2835_clock_osc_parents), \
.parents = bcm2835_clock_osc_parents, \ .parents = bcm2835_clock_osc_parents, \
__VA_ARGS__) __VA_ARGS__)
@ -1497,7 +1514,8 @@ static const char *const bcm2835_clock_per_parents[] = {
"pllh_aux", "pllh_aux",
}; };
#define REGISTER_PER_CLK(...) REGISTER_CLK( \ #define REGISTER_PER_CLK(s, ...) REGISTER_CLK( \
s, \
.num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), \ .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), \
.parents = bcm2835_clock_per_parents, \ .parents = bcm2835_clock_per_parents, \
__VA_ARGS__) __VA_ARGS__)
@ -1522,7 +1540,8 @@ static const char *const bcm2835_pcm_per_parents[] = {
"-", "-",
}; };
#define REGISTER_PCM_CLK(...) REGISTER_CLK( \ #define REGISTER_PCM_CLK(s, ...) REGISTER_CLK( \
s, \
.num_mux_parents = ARRAY_SIZE(bcm2835_pcm_per_parents), \ .num_mux_parents = ARRAY_SIZE(bcm2835_pcm_per_parents), \
.parents = bcm2835_pcm_per_parents, \ .parents = bcm2835_pcm_per_parents, \
__VA_ARGS__) __VA_ARGS__)
@ -1541,7 +1560,8 @@ static const char *const bcm2835_clock_vpu_parents[] = {
"pllc_core2", "pllc_core2",
}; };
#define REGISTER_VPU_CLK(...) REGISTER_CLK( \ #define REGISTER_VPU_CLK(s, ...) REGISTER_CLK( \
s, \
.num_mux_parents = ARRAY_SIZE(bcm2835_clock_vpu_parents), \ .num_mux_parents = ARRAY_SIZE(bcm2835_clock_vpu_parents), \
.parents = bcm2835_clock_vpu_parents, \ .parents = bcm2835_clock_vpu_parents, \
__VA_ARGS__) __VA_ARGS__)
@ -1577,12 +1597,14 @@ static const char *const bcm2835_clock_dsi1_parents[] = {
"dsi1_byte_inv", "dsi1_byte_inv",
}; };
#define REGISTER_DSI0_CLK(...) REGISTER_CLK( \ #define REGISTER_DSI0_CLK(s, ...) REGISTER_CLK( \
s, \
.num_mux_parents = ARRAY_SIZE(bcm2835_clock_dsi0_parents), \ .num_mux_parents = ARRAY_SIZE(bcm2835_clock_dsi0_parents), \
.parents = bcm2835_clock_dsi0_parents, \ .parents = bcm2835_clock_dsi0_parents, \
__VA_ARGS__) __VA_ARGS__)
#define REGISTER_DSI1_CLK(...) REGISTER_CLK( \ #define REGISTER_DSI1_CLK(s, ...) REGISTER_CLK( \
s, \
.num_mux_parents = ARRAY_SIZE(bcm2835_clock_dsi1_parents), \ .num_mux_parents = ARRAY_SIZE(bcm2835_clock_dsi1_parents), \
.parents = bcm2835_clock_dsi1_parents, \ .parents = bcm2835_clock_dsi1_parents, \
__VA_ARGS__) __VA_ARGS__)
@ -1602,6 +1624,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
* AUDIO domain is on. * AUDIO domain is on.
*/ */
[BCM2835_PLLA] = REGISTER_PLL( [BCM2835_PLLA] = REGISTER_PLL(
SOC_ALL,
.name = "plla", .name = "plla",
.cm_ctrl_reg = CM_PLLA, .cm_ctrl_reg = CM_PLLA,
.a2w_ctrl_reg = A2W_PLLA_CTRL, .a2w_ctrl_reg = A2W_PLLA_CTRL,
@ -1616,6 +1639,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.max_rate = 2400000000u, .max_rate = 2400000000u,
.max_fb_rate = BCM2835_MAX_FB_RATE), .max_fb_rate = BCM2835_MAX_FB_RATE),
[BCM2835_PLLA_CORE] = REGISTER_PLL_DIV( [BCM2835_PLLA_CORE] = REGISTER_PLL_DIV(
SOC_ALL,
.name = "plla_core", .name = "plla_core",
.source_pll = "plla", .source_pll = "plla",
.cm_reg = CM_PLLA, .cm_reg = CM_PLLA,
@ -1625,6 +1649,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.fixed_divider = 1, .fixed_divider = 1,
.flags = CLK_SET_RATE_PARENT), .flags = CLK_SET_RATE_PARENT),
[BCM2835_PLLA_PER] = REGISTER_PLL_DIV( [BCM2835_PLLA_PER] = REGISTER_PLL_DIV(
SOC_ALL,
.name = "plla_per", .name = "plla_per",
.source_pll = "plla", .source_pll = "plla",
.cm_reg = CM_PLLA, .cm_reg = CM_PLLA,
@ -1634,6 +1659,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.fixed_divider = 1, .fixed_divider = 1,
.flags = CLK_SET_RATE_PARENT), .flags = CLK_SET_RATE_PARENT),
[BCM2835_PLLA_DSI0] = REGISTER_PLL_DIV( [BCM2835_PLLA_DSI0] = REGISTER_PLL_DIV(
SOC_ALL,
.name = "plla_dsi0", .name = "plla_dsi0",
.source_pll = "plla", .source_pll = "plla",
.cm_reg = CM_PLLA, .cm_reg = CM_PLLA,
@ -1642,6 +1668,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.hold_mask = CM_PLLA_HOLDDSI0, .hold_mask = CM_PLLA_HOLDDSI0,
.fixed_divider = 1), .fixed_divider = 1),
[BCM2835_PLLA_CCP2] = REGISTER_PLL_DIV( [BCM2835_PLLA_CCP2] = REGISTER_PLL_DIV(
SOC_ALL,
.name = "plla_ccp2", .name = "plla_ccp2",
.source_pll = "plla", .source_pll = "plla",
.cm_reg = CM_PLLA, .cm_reg = CM_PLLA,
@ -1663,6 +1690,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
* AUDIO domain is on. * AUDIO domain is on.
*/ */
[BCM2835_PLLC] = REGISTER_PLL( [BCM2835_PLLC] = REGISTER_PLL(
SOC_ALL,
.name = "pllc", .name = "pllc",
.cm_ctrl_reg = CM_PLLC, .cm_ctrl_reg = CM_PLLC,
.a2w_ctrl_reg = A2W_PLLC_CTRL, .a2w_ctrl_reg = A2W_PLLC_CTRL,
@ -1677,6 +1705,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.max_rate = 3000000000u, .max_rate = 3000000000u,
.max_fb_rate = BCM2835_MAX_FB_RATE), .max_fb_rate = BCM2835_MAX_FB_RATE),
[BCM2835_PLLC_CORE0] = REGISTER_PLL_DIV( [BCM2835_PLLC_CORE0] = REGISTER_PLL_DIV(
SOC_ALL,
.name = "pllc_core0", .name = "pllc_core0",
.source_pll = "pllc", .source_pll = "pllc",
.cm_reg = CM_PLLC, .cm_reg = CM_PLLC,
@ -1686,6 +1715,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.fixed_divider = 1, .fixed_divider = 1,
.flags = CLK_SET_RATE_PARENT), .flags = CLK_SET_RATE_PARENT),
[BCM2835_PLLC_CORE1] = REGISTER_PLL_DIV( [BCM2835_PLLC_CORE1] = REGISTER_PLL_DIV(
SOC_ALL,
.name = "pllc_core1", .name = "pllc_core1",
.source_pll = "pllc", .source_pll = "pllc",
.cm_reg = CM_PLLC, .cm_reg = CM_PLLC,
@ -1695,6 +1725,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.fixed_divider = 1, .fixed_divider = 1,
.flags = CLK_SET_RATE_PARENT), .flags = CLK_SET_RATE_PARENT),
[BCM2835_PLLC_CORE2] = REGISTER_PLL_DIV( [BCM2835_PLLC_CORE2] = REGISTER_PLL_DIV(
SOC_ALL,
.name = "pllc_core2", .name = "pllc_core2",
.source_pll = "pllc", .source_pll = "pllc",
.cm_reg = CM_PLLC, .cm_reg = CM_PLLC,
@ -1704,6 +1735,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.fixed_divider = 1, .fixed_divider = 1,
.flags = CLK_SET_RATE_PARENT), .flags = CLK_SET_RATE_PARENT),
[BCM2835_PLLC_PER] = REGISTER_PLL_DIV( [BCM2835_PLLC_PER] = REGISTER_PLL_DIV(
SOC_ALL,
.name = "pllc_per", .name = "pllc_per",
.source_pll = "pllc", .source_pll = "pllc",
.cm_reg = CM_PLLC, .cm_reg = CM_PLLC,
@ -1720,6 +1752,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
* AUDIO domain is on. * AUDIO domain is on.
*/ */
[BCM2835_PLLD] = REGISTER_PLL( [BCM2835_PLLD] = REGISTER_PLL(
SOC_ALL,
.name = "plld", .name = "plld",
.cm_ctrl_reg = CM_PLLD, .cm_ctrl_reg = CM_PLLD,
.a2w_ctrl_reg = A2W_PLLD_CTRL, .a2w_ctrl_reg = A2W_PLLD_CTRL,
@ -1734,6 +1767,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.max_rate = 2400000000u, .max_rate = 2400000000u,
.max_fb_rate = BCM2835_MAX_FB_RATE), .max_fb_rate = BCM2835_MAX_FB_RATE),
[BCM2835_PLLD_CORE] = REGISTER_PLL_DIV( [BCM2835_PLLD_CORE] = REGISTER_PLL_DIV(
SOC_ALL,
.name = "plld_core", .name = "plld_core",
.source_pll = "plld", .source_pll = "plld",
.cm_reg = CM_PLLD, .cm_reg = CM_PLLD,
@ -1742,7 +1776,13 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.hold_mask = CM_PLLD_HOLDCORE, .hold_mask = CM_PLLD_HOLDCORE,
.fixed_divider = 1, .fixed_divider = 1,
.flags = CLK_SET_RATE_PARENT), .flags = CLK_SET_RATE_PARENT),
/*
* VPU firmware assumes that PLLD_PER isn't disabled by the ARM core.
* Otherwise this could cause firmware lookups. That's why we mark
* it as critical.
*/
[BCM2835_PLLD_PER] = REGISTER_PLL_DIV( [BCM2835_PLLD_PER] = REGISTER_PLL_DIV(
SOC_ALL,
.name = "plld_per", .name = "plld_per",
.source_pll = "plld", .source_pll = "plld",
.cm_reg = CM_PLLD, .cm_reg = CM_PLLD,
@ -1750,8 +1790,9 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.load_mask = CM_PLLD_LOADPER, .load_mask = CM_PLLD_LOADPER,
.hold_mask = CM_PLLD_HOLDPER, .hold_mask = CM_PLLD_HOLDPER,
.fixed_divider = 1, .fixed_divider = 1,
.flags = CLK_SET_RATE_PARENT), .flags = CLK_IS_CRITICAL | CLK_SET_RATE_PARENT),
[BCM2835_PLLD_DSI0] = REGISTER_PLL_DIV( [BCM2835_PLLD_DSI0] = REGISTER_PLL_DIV(
SOC_ALL,
.name = "plld_dsi0", .name = "plld_dsi0",
.source_pll = "plld", .source_pll = "plld",
.cm_reg = CM_PLLD, .cm_reg = CM_PLLD,
@ -1760,6 +1801,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.hold_mask = CM_PLLD_HOLDDSI0, .hold_mask = CM_PLLD_HOLDDSI0,
.fixed_divider = 1), .fixed_divider = 1),
[BCM2835_PLLD_DSI1] = REGISTER_PLL_DIV( [BCM2835_PLLD_DSI1] = REGISTER_PLL_DIV(
SOC_ALL,
.name = "plld_dsi1", .name = "plld_dsi1",
.source_pll = "plld", .source_pll = "plld",
.cm_reg = CM_PLLD, .cm_reg = CM_PLLD,
@ -1775,6 +1817,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
* It is in the HDMI power domain. * It is in the HDMI power domain.
*/ */
[BCM2835_PLLH] = REGISTER_PLL( [BCM2835_PLLH] = REGISTER_PLL(
SOC_BCM2835,
"pllh", "pllh",
.cm_ctrl_reg = CM_PLLH, .cm_ctrl_reg = CM_PLLH,
.a2w_ctrl_reg = A2W_PLLH_CTRL, .a2w_ctrl_reg = A2W_PLLH_CTRL,
@ -1789,6 +1832,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.max_rate = 3000000000u, .max_rate = 3000000000u,
.max_fb_rate = BCM2835_MAX_FB_RATE), .max_fb_rate = BCM2835_MAX_FB_RATE),
[BCM2835_PLLH_RCAL] = REGISTER_PLL_DIV( [BCM2835_PLLH_RCAL] = REGISTER_PLL_DIV(
SOC_BCM2835,
.name = "pllh_rcal", .name = "pllh_rcal",
.source_pll = "pllh", .source_pll = "pllh",
.cm_reg = CM_PLLH, .cm_reg = CM_PLLH,
@ -1798,6 +1842,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.fixed_divider = 10, .fixed_divider = 10,
.flags = CLK_SET_RATE_PARENT), .flags = CLK_SET_RATE_PARENT),
[BCM2835_PLLH_AUX] = REGISTER_PLL_DIV( [BCM2835_PLLH_AUX] = REGISTER_PLL_DIV(
SOC_BCM2835,
.name = "pllh_aux", .name = "pllh_aux",
.source_pll = "pllh", .source_pll = "pllh",
.cm_reg = CM_PLLH, .cm_reg = CM_PLLH,
@ -1807,6 +1852,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.fixed_divider = 1, .fixed_divider = 1,
.flags = CLK_SET_RATE_PARENT), .flags = CLK_SET_RATE_PARENT),
[BCM2835_PLLH_PIX] = REGISTER_PLL_DIV( [BCM2835_PLLH_PIX] = REGISTER_PLL_DIV(
SOC_BCM2835,
.name = "pllh_pix", .name = "pllh_pix",
.source_pll = "pllh", .source_pll = "pllh",
.cm_reg = CM_PLLH, .cm_reg = CM_PLLH,
@ -1822,6 +1868,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
/* One Time Programmable Memory clock. Maximum 10Mhz. */ /* One Time Programmable Memory clock. Maximum 10Mhz. */
[BCM2835_CLOCK_OTP] = REGISTER_OSC_CLK( [BCM2835_CLOCK_OTP] = REGISTER_OSC_CLK(
SOC_ALL,
.name = "otp", .name = "otp",
.ctl_reg = CM_OTPCTL, .ctl_reg = CM_OTPCTL,
.div_reg = CM_OTPDIV, .div_reg = CM_OTPDIV,
@ -1833,6 +1880,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
* bythe watchdog timer and the camera pulse generator. * bythe watchdog timer and the camera pulse generator.
*/ */
[BCM2835_CLOCK_TIMER] = REGISTER_OSC_CLK( [BCM2835_CLOCK_TIMER] = REGISTER_OSC_CLK(
SOC_ALL,
.name = "timer", .name = "timer",
.ctl_reg = CM_TIMERCTL, .ctl_reg = CM_TIMERCTL,
.div_reg = CM_TIMERDIV, .div_reg = CM_TIMERDIV,
@ -1843,12 +1891,14 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
* Generally run at 2Mhz, max 5Mhz. * Generally run at 2Mhz, max 5Mhz.
*/ */
[BCM2835_CLOCK_TSENS] = REGISTER_OSC_CLK( [BCM2835_CLOCK_TSENS] = REGISTER_OSC_CLK(
SOC_ALL,
.name = "tsens", .name = "tsens",
.ctl_reg = CM_TSENSCTL, .ctl_reg = CM_TSENSCTL,
.div_reg = CM_TSENSDIV, .div_reg = CM_TSENSDIV,
.int_bits = 5, .int_bits = 5,
.frac_bits = 0), .frac_bits = 0),
[BCM2835_CLOCK_TEC] = REGISTER_OSC_CLK( [BCM2835_CLOCK_TEC] = REGISTER_OSC_CLK(
SOC_ALL,
.name = "tec", .name = "tec",
.ctl_reg = CM_TECCTL, .ctl_reg = CM_TECCTL,
.div_reg = CM_TECDIV, .div_reg = CM_TECDIV,
@ -1857,6 +1907,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
/* clocks with vpu parent mux */ /* clocks with vpu parent mux */
[BCM2835_CLOCK_H264] = REGISTER_VPU_CLK( [BCM2835_CLOCK_H264] = REGISTER_VPU_CLK(
SOC_ALL,
.name = "h264", .name = "h264",
.ctl_reg = CM_H264CTL, .ctl_reg = CM_H264CTL,
.div_reg = CM_H264DIV, .div_reg = CM_H264DIV,
@ -1864,6 +1915,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.frac_bits = 8, .frac_bits = 8,
.tcnt_mux = 1), .tcnt_mux = 1),
[BCM2835_CLOCK_ISP] = REGISTER_VPU_CLK( [BCM2835_CLOCK_ISP] = REGISTER_VPU_CLK(
SOC_ALL,
.name = "isp", .name = "isp",
.ctl_reg = CM_ISPCTL, .ctl_reg = CM_ISPCTL,
.div_reg = CM_ISPDIV, .div_reg = CM_ISPDIV,
@ -1876,6 +1928,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
* in the SDRAM controller can't be used. * in the SDRAM controller can't be used.
*/ */
[BCM2835_CLOCK_SDRAM] = REGISTER_VPU_CLK( [BCM2835_CLOCK_SDRAM] = REGISTER_VPU_CLK(
SOC_ALL,
.name = "sdram", .name = "sdram",
.ctl_reg = CM_SDCCTL, .ctl_reg = CM_SDCCTL,
.div_reg = CM_SDCDIV, .div_reg = CM_SDCDIV,
@ -1883,6 +1936,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.frac_bits = 0, .frac_bits = 0,
.tcnt_mux = 3), .tcnt_mux = 3),
[BCM2835_CLOCK_V3D] = REGISTER_VPU_CLK( [BCM2835_CLOCK_V3D] = REGISTER_VPU_CLK(
SOC_ALL,
.name = "v3d", .name = "v3d",
.ctl_reg = CM_V3DCTL, .ctl_reg = CM_V3DCTL,
.div_reg = CM_V3DDIV, .div_reg = CM_V3DDIV,
@ -1896,6 +1950,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
* in various hardware documentation. * in various hardware documentation.
*/ */
[BCM2835_CLOCK_VPU] = REGISTER_VPU_CLK( [BCM2835_CLOCK_VPU] = REGISTER_VPU_CLK(
SOC_ALL,
.name = "vpu", .name = "vpu",
.ctl_reg = CM_VPUCTL, .ctl_reg = CM_VPUCTL,
.div_reg = CM_VPUDIV, .div_reg = CM_VPUDIV,
@ -1907,6 +1962,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
/* clocks with per parent mux */ /* clocks with per parent mux */
[BCM2835_CLOCK_AVEO] = REGISTER_PER_CLK( [BCM2835_CLOCK_AVEO] = REGISTER_PER_CLK(
SOC_ALL,
.name = "aveo", .name = "aveo",
.ctl_reg = CM_AVEOCTL, .ctl_reg = CM_AVEOCTL,
.div_reg = CM_AVEODIV, .div_reg = CM_AVEODIV,
@ -1914,6 +1970,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.frac_bits = 0, .frac_bits = 0,
.tcnt_mux = 38), .tcnt_mux = 38),
[BCM2835_CLOCK_CAM0] = REGISTER_PER_CLK( [BCM2835_CLOCK_CAM0] = REGISTER_PER_CLK(
SOC_ALL,
.name = "cam0", .name = "cam0",
.ctl_reg = CM_CAM0CTL, .ctl_reg = CM_CAM0CTL,
.div_reg = CM_CAM0DIV, .div_reg = CM_CAM0DIV,
@ -1921,6 +1978,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.frac_bits = 8, .frac_bits = 8,
.tcnt_mux = 14), .tcnt_mux = 14),
[BCM2835_CLOCK_CAM1] = REGISTER_PER_CLK( [BCM2835_CLOCK_CAM1] = REGISTER_PER_CLK(
SOC_ALL,
.name = "cam1", .name = "cam1",
.ctl_reg = CM_CAM1CTL, .ctl_reg = CM_CAM1CTL,
.div_reg = CM_CAM1DIV, .div_reg = CM_CAM1DIV,
@ -1928,12 +1986,14 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.frac_bits = 8, .frac_bits = 8,
.tcnt_mux = 15), .tcnt_mux = 15),
[BCM2835_CLOCK_DFT] = REGISTER_PER_CLK( [BCM2835_CLOCK_DFT] = REGISTER_PER_CLK(
SOC_ALL,
.name = "dft", .name = "dft",
.ctl_reg = CM_DFTCTL, .ctl_reg = CM_DFTCTL,
.div_reg = CM_DFTDIV, .div_reg = CM_DFTDIV,
.int_bits = 5, .int_bits = 5,
.frac_bits = 0), .frac_bits = 0),
[BCM2835_CLOCK_DPI] = REGISTER_PER_CLK( [BCM2835_CLOCK_DPI] = REGISTER_PER_CLK(
SOC_ALL,
.name = "dpi", .name = "dpi",
.ctl_reg = CM_DPICTL, .ctl_reg = CM_DPICTL,
.div_reg = CM_DPIDIV, .div_reg = CM_DPIDIV,
@ -1943,6 +2003,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
/* Arasan EMMC clock */ /* Arasan EMMC clock */
[BCM2835_CLOCK_EMMC] = REGISTER_PER_CLK( [BCM2835_CLOCK_EMMC] = REGISTER_PER_CLK(
SOC_ALL,
.name = "emmc", .name = "emmc",
.ctl_reg = CM_EMMCCTL, .ctl_reg = CM_EMMCCTL,
.div_reg = CM_EMMCDIV, .div_reg = CM_EMMCDIV,
@ -1950,8 +2011,19 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.frac_bits = 8, .frac_bits = 8,
.tcnt_mux = 39), .tcnt_mux = 39),
/* EMMC2 clock (only available for BCM2711) */
[BCM2711_CLOCK_EMMC2] = REGISTER_PER_CLK(
SOC_BCM2711,
.name = "emmc2",
.ctl_reg = CM_EMMC2CTL,
.div_reg = CM_EMMC2DIV,
.int_bits = 4,
.frac_bits = 8,
.tcnt_mux = 42),
/* General purpose (GPIO) clocks */ /* General purpose (GPIO) clocks */
[BCM2835_CLOCK_GP0] = REGISTER_PER_CLK( [BCM2835_CLOCK_GP0] = REGISTER_PER_CLK(
SOC_ALL,
.name = "gp0", .name = "gp0",
.ctl_reg = CM_GP0CTL, .ctl_reg = CM_GP0CTL,
.div_reg = CM_GP0DIV, .div_reg = CM_GP0DIV,
@ -1960,6 +2032,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.is_mash_clock = true, .is_mash_clock = true,
.tcnt_mux = 20), .tcnt_mux = 20),
[BCM2835_CLOCK_GP1] = REGISTER_PER_CLK( [BCM2835_CLOCK_GP1] = REGISTER_PER_CLK(
SOC_ALL,
.name = "gp1", .name = "gp1",
.ctl_reg = CM_GP1CTL, .ctl_reg = CM_GP1CTL,
.div_reg = CM_GP1DIV, .div_reg = CM_GP1DIV,
@ -1969,6 +2042,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.is_mash_clock = true, .is_mash_clock = true,
.tcnt_mux = 21), .tcnt_mux = 21),
[BCM2835_CLOCK_GP2] = REGISTER_PER_CLK( [BCM2835_CLOCK_GP2] = REGISTER_PER_CLK(
SOC_ALL,
.name = "gp2", .name = "gp2",
.ctl_reg = CM_GP2CTL, .ctl_reg = CM_GP2CTL,
.div_reg = CM_GP2DIV, .div_reg = CM_GP2DIV,
@ -1978,6 +2052,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
/* HDMI state machine */ /* HDMI state machine */
[BCM2835_CLOCK_HSM] = REGISTER_PER_CLK( [BCM2835_CLOCK_HSM] = REGISTER_PER_CLK(
SOC_ALL,
.name = "hsm", .name = "hsm",
.ctl_reg = CM_HSMCTL, .ctl_reg = CM_HSMCTL,
.div_reg = CM_HSMDIV, .div_reg = CM_HSMDIV,
@ -1985,6 +2060,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.frac_bits = 8, .frac_bits = 8,
.tcnt_mux = 22), .tcnt_mux = 22),
[BCM2835_CLOCK_PCM] = REGISTER_PCM_CLK( [BCM2835_CLOCK_PCM] = REGISTER_PCM_CLK(
SOC_ALL,
.name = "pcm", .name = "pcm",
.ctl_reg = CM_PCMCTL, .ctl_reg = CM_PCMCTL,
.div_reg = CM_PCMDIV, .div_reg = CM_PCMDIV,
@ -1994,6 +2070,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.low_jitter = true, .low_jitter = true,
.tcnt_mux = 23), .tcnt_mux = 23),
[BCM2835_CLOCK_PWM] = REGISTER_PER_CLK( [BCM2835_CLOCK_PWM] = REGISTER_PER_CLK(
SOC_ALL,
.name = "pwm", .name = "pwm",
.ctl_reg = CM_PWMCTL, .ctl_reg = CM_PWMCTL,
.div_reg = CM_PWMDIV, .div_reg = CM_PWMDIV,
@ -2002,6 +2079,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.is_mash_clock = true, .is_mash_clock = true,
.tcnt_mux = 24), .tcnt_mux = 24),
[BCM2835_CLOCK_SLIM] = REGISTER_PER_CLK( [BCM2835_CLOCK_SLIM] = REGISTER_PER_CLK(
SOC_ALL,
.name = "slim", .name = "slim",
.ctl_reg = CM_SLIMCTL, .ctl_reg = CM_SLIMCTL,
.div_reg = CM_SLIMDIV, .div_reg = CM_SLIMDIV,
@ -2010,6 +2088,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.is_mash_clock = true, .is_mash_clock = true,
.tcnt_mux = 25), .tcnt_mux = 25),
[BCM2835_CLOCK_SMI] = REGISTER_PER_CLK( [BCM2835_CLOCK_SMI] = REGISTER_PER_CLK(
SOC_ALL,
.name = "smi", .name = "smi",
.ctl_reg = CM_SMICTL, .ctl_reg = CM_SMICTL,
.div_reg = CM_SMIDIV, .div_reg = CM_SMIDIV,
@ -2017,6 +2096,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.frac_bits = 8, .frac_bits = 8,
.tcnt_mux = 27), .tcnt_mux = 27),
[BCM2835_CLOCK_UART] = REGISTER_PER_CLK( [BCM2835_CLOCK_UART] = REGISTER_PER_CLK(
SOC_ALL,
.name = "uart", .name = "uart",
.ctl_reg = CM_UARTCTL, .ctl_reg = CM_UARTCTL,
.div_reg = CM_UARTDIV, .div_reg = CM_UARTDIV,
@ -2026,6 +2106,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
/* TV encoder clock. Only operating frequency is 108Mhz. */ /* TV encoder clock. Only operating frequency is 108Mhz. */
[BCM2835_CLOCK_VEC] = REGISTER_PER_CLK( [BCM2835_CLOCK_VEC] = REGISTER_PER_CLK(
SOC_ALL,
.name = "vec", .name = "vec",
.ctl_reg = CM_VECCTL, .ctl_reg = CM_VECCTL,
.div_reg = CM_VECDIV, .div_reg = CM_VECDIV,
@ -2040,6 +2121,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
/* dsi clocks */ /* dsi clocks */
[BCM2835_CLOCK_DSI0E] = REGISTER_PER_CLK( [BCM2835_CLOCK_DSI0E] = REGISTER_PER_CLK(
SOC_ALL,
.name = "dsi0e", .name = "dsi0e",
.ctl_reg = CM_DSI0ECTL, .ctl_reg = CM_DSI0ECTL,
.div_reg = CM_DSI0EDIV, .div_reg = CM_DSI0EDIV,
@ -2047,6 +2129,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.frac_bits = 8, .frac_bits = 8,
.tcnt_mux = 18), .tcnt_mux = 18),
[BCM2835_CLOCK_DSI1E] = REGISTER_PER_CLK( [BCM2835_CLOCK_DSI1E] = REGISTER_PER_CLK(
SOC_ALL,
.name = "dsi1e", .name = "dsi1e",
.ctl_reg = CM_DSI1ECTL, .ctl_reg = CM_DSI1ECTL,
.div_reg = CM_DSI1EDIV, .div_reg = CM_DSI1EDIV,
@ -2054,6 +2137,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.frac_bits = 8, .frac_bits = 8,
.tcnt_mux = 19), .tcnt_mux = 19),
[BCM2835_CLOCK_DSI0P] = REGISTER_DSI0_CLK( [BCM2835_CLOCK_DSI0P] = REGISTER_DSI0_CLK(
SOC_ALL,
.name = "dsi0p", .name = "dsi0p",
.ctl_reg = CM_DSI0PCTL, .ctl_reg = CM_DSI0PCTL,
.div_reg = CM_DSI0PDIV, .div_reg = CM_DSI0PDIV,
@ -2061,6 +2145,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.frac_bits = 0, .frac_bits = 0,
.tcnt_mux = 12), .tcnt_mux = 12),
[BCM2835_CLOCK_DSI1P] = REGISTER_DSI1_CLK( [BCM2835_CLOCK_DSI1P] = REGISTER_DSI1_CLK(
SOC_ALL,
.name = "dsi1p", .name = "dsi1p",
.ctl_reg = CM_DSI1PCTL, .ctl_reg = CM_DSI1PCTL,
.div_reg = CM_DSI1PDIV, .div_reg = CM_DSI1PDIV,
@ -2077,6 +2162,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
* non-stop vpu clock. * non-stop vpu clock.
*/ */
[BCM2835_CLOCK_PERI_IMAGE] = REGISTER_GATE( [BCM2835_CLOCK_PERI_IMAGE] = REGISTER_GATE(
SOC_ALL,
.name = "peri_image", .name = "peri_image",
.parent = "vpu", .parent = "vpu",
.ctl_reg = CM_PERIICTL), .ctl_reg = CM_PERIICTL),
@ -2109,9 +2195,14 @@ static int bcm2835_clk_probe(struct platform_device *pdev)
struct resource *res; struct resource *res;
const struct bcm2835_clk_desc *desc; const struct bcm2835_clk_desc *desc;
const size_t asize = ARRAY_SIZE(clk_desc_array); const size_t asize = ARRAY_SIZE(clk_desc_array);
const struct cprman_plat_data *pdata;
size_t i; size_t i;
int ret; int ret;
pdata = of_device_get_match_data(&pdev->dev);
if (!pdata)
return -ENODEV;
cprman = devm_kzalloc(dev, cprman = devm_kzalloc(dev,
struct_size(cprman, onecell.hws, asize), struct_size(cprman, onecell.hws, asize),
GFP_KERNEL); GFP_KERNEL);
@ -2147,8 +2238,10 @@ static int bcm2835_clk_probe(struct platform_device *pdev)
for (i = 0; i < asize; i++) { for (i = 0; i < asize; i++) {
desc = &clk_desc_array[i]; desc = &clk_desc_array[i];
if (desc->clk_register && desc->data) if (desc->clk_register && desc->data &&
(desc->supported & pdata->soc)) {
hws[i] = desc->clk_register(cprman, desc->data); hws[i] = desc->clk_register(cprman, desc->data);
}
} }
ret = bcm2835_mark_sdc_parent_critical(hws[BCM2835_CLOCK_SDRAM]->clk); ret = bcm2835_mark_sdc_parent_critical(hws[BCM2835_CLOCK_SDRAM]->clk);
@ -2159,8 +2252,17 @@ static int bcm2835_clk_probe(struct platform_device *pdev)
&cprman->onecell); &cprman->onecell);
} }
static const struct cprman_plat_data cprman_bcm2835_plat_data = {
.soc = SOC_BCM2835,
};
static const struct cprman_plat_data cprman_bcm2711_plat_data = {
.soc = SOC_BCM2711,
};
static const struct of_device_id bcm2835_clk_of_match[] = { static const struct of_device_id bcm2835_clk_of_match[] = {
{ .compatible = "brcm,bcm2835-cprman", }, { .compatible = "brcm,bcm2835-cprman", .data = &cprman_bcm2835_plat_data },
{ .compatible = "brcm,bcm2711-cprman", .data = &cprman_bcm2711_plat_data },
{} {}
}; };
MODULE_DEVICE_TABLE(of, bcm2835_clk_of_match); MODULE_DEVICE_TABLE(of, bcm2835_clk_of_match);

View File

@ -16,6 +16,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/regmap.h> #include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/gcd.h> #include <linux/gcd.h>
@ -602,6 +603,30 @@ of_clk_cdce925_get(struct of_phandle_args *clkspec, void *_data)
return &data->clk[idx].hw; return &data->clk[idx].hw;
} }
static void cdce925_regulator_disable(void *regulator)
{
regulator_disable(regulator);
}
static int cdce925_regulator_enable(struct device *dev, const char *name)
{
struct regulator *regulator;
int err;
regulator = devm_regulator_get(dev, name);
if (IS_ERR(regulator))
return PTR_ERR(regulator);
err = regulator_enable(regulator);
if (err) {
dev_err(dev, "Failed to enable %s: %d\n", name, err);
return err;
}
return devm_add_action_or_reset(dev, cdce925_regulator_disable,
regulator);
}
/* The CDCE925 uses a funky way to read/write registers. Bulk mode is /* The CDCE925 uses a funky way to read/write registers. Bulk mode is
* just weird, so just use the single byte mode exclusively. */ * just weird, so just use the single byte mode exclusively. */
static struct regmap_bus regmap_cdce925_bus = { static struct regmap_bus regmap_cdce925_bus = {
@ -630,6 +655,15 @@ static int cdce925_probe(struct i2c_client *client,
}; };
dev_dbg(&client->dev, "%s\n", __func__); dev_dbg(&client->dev, "%s\n", __func__);
err = cdce925_regulator_enable(&client->dev, "vdd");
if (err)
return err;
err = cdce925_regulator_enable(&client->dev, "vddout");
if (err)
return err;
data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL); data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
if (!data) if (!data)
return -ENOMEM; return -ENOMEM;

View File

@ -37,6 +37,12 @@ static HLIST_HEAD(clk_root_list);
static HLIST_HEAD(clk_orphan_list); static HLIST_HEAD(clk_orphan_list);
static LIST_HEAD(clk_notifier_list); static LIST_HEAD(clk_notifier_list);
static struct hlist_head *all_lists[] = {
&clk_root_list,
&clk_orphan_list,
NULL,
};
/*** private data structures ***/ /*** private data structures ***/
struct clk_parent_map { struct clk_parent_map {
@ -2841,12 +2847,6 @@ static int inited = 0;
static DEFINE_MUTEX(clk_debug_lock); static DEFINE_MUTEX(clk_debug_lock);
static HLIST_HEAD(clk_debug_list); static HLIST_HEAD(clk_debug_list);
static struct hlist_head *all_lists[] = {
&clk_root_list,
&clk_orphan_list,
NULL,
};
static struct hlist_head *orphan_list[] = { static struct hlist_head *orphan_list[] = {
&clk_orphan_list, &clk_orphan_list,
NULL, NULL,
@ -3777,6 +3777,34 @@ static const struct clk_ops clk_nodrv_ops = {
.set_parent = clk_nodrv_set_parent, .set_parent = clk_nodrv_set_parent,
}; };
static void clk_core_evict_parent_cache_subtree(struct clk_core *root,
struct clk_core *target)
{
int i;
struct clk_core *child;
for (i = 0; i < root->num_parents; i++)
if (root->parents[i].core == target)
root->parents[i].core = NULL;
hlist_for_each_entry(child, &root->children, child_node)
clk_core_evict_parent_cache_subtree(child, target);
}
/* Remove this clk from all parent caches */
static void clk_core_evict_parent_cache(struct clk_core *core)
{
struct hlist_head **lists;
struct clk_core *root;
lockdep_assert_held(&prepare_lock);
for (lists = all_lists; *lists; lists++)
hlist_for_each_entry(root, *lists, child_node)
clk_core_evict_parent_cache_subtree(root, core);
}
/** /**
* clk_unregister - unregister a currently registered clock * clk_unregister - unregister a currently registered clock
* @clk: clock to unregister * @clk: clock to unregister
@ -3815,6 +3843,8 @@ void clk_unregister(struct clk *clk)
clk_core_set_parent_nolock(child, NULL); clk_core_set_parent_nolock(child, NULL);
} }
clk_core_evict_parent_cache(clk->core);
hlist_del_init(&clk->core->child_node); hlist_del_init(&clk->core->child_node);
if (clk->core->prepare_count) if (clk->core->prepare_count)

View File

@ -58,3 +58,5 @@
#define BCM2835_CLOCK_DSI1E 48 #define BCM2835_CLOCK_DSI1E 48
#define BCM2835_CLOCK_DSI0P 49 #define BCM2835_CLOCK_DSI0P 49
#define BCM2835_CLOCK_DSI1P 50 #define BCM2835_CLOCK_DSI1P 50
#define BCM2711_CLOCK_EMMC2 51