mirror of https://gitee.com/openkylin/linux.git
clk: bcm2835: Migrate to clk_hw based registration and OF APIs
Now that we have clk_hw based provider APIs to register clks, we can get rid of struct clk pointers while registering clks in these drivers, allowing us to move closer to a clear split of consumer and provider clk APIs. Cc: Eric Anholt <eric@anholt.net> Cc: Martin Sperl <kernel@martin.sperl.org> Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
This commit is contained in:
parent
f4e8715099
commit
b19f009d45
|
@ -25,7 +25,7 @@
|
||||||
static int bcm2835_aux_clk_probe(struct platform_device *pdev)
|
static int bcm2835_aux_clk_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct device *dev = &pdev->dev;
|
struct device *dev = &pdev->dev;
|
||||||
struct clk_onecell_data *onecell;
|
struct clk_hw_onecell_data *onecell;
|
||||||
const char *parent;
|
const char *parent;
|
||||||
struct clk *parent_clk;
|
struct clk *parent_clk;
|
||||||
struct resource *res;
|
struct resource *res;
|
||||||
|
@ -41,28 +41,24 @@ static int bcm2835_aux_clk_probe(struct platform_device *pdev)
|
||||||
if (IS_ERR(reg))
|
if (IS_ERR(reg))
|
||||||
return PTR_ERR(reg);
|
return PTR_ERR(reg);
|
||||||
|
|
||||||
onecell = devm_kmalloc(dev, sizeof(*onecell), GFP_KERNEL);
|
onecell = devm_kmalloc(dev, sizeof(*onecell) + sizeof(*onecell->hws) *
|
||||||
|
BCM2835_AUX_CLOCK_COUNT, GFP_KERNEL);
|
||||||
if (!onecell)
|
if (!onecell)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
onecell->clk_num = BCM2835_AUX_CLOCK_COUNT;
|
onecell->num = BCM2835_AUX_CLOCK_COUNT;
|
||||||
onecell->clks = devm_kcalloc(dev, BCM2835_AUX_CLOCK_COUNT,
|
|
||||||
sizeof(*onecell->clks), GFP_KERNEL);
|
|
||||||
if (!onecell->clks)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
gate = reg + BCM2835_AUXENB;
|
gate = reg + BCM2835_AUXENB;
|
||||||
onecell->clks[BCM2835_AUX_CLOCK_UART] =
|
onecell->hws[BCM2835_AUX_CLOCK_UART] =
|
||||||
clk_register_gate(dev, "aux_uart", parent, 0, gate, 0, 0, NULL);
|
clk_hw_register_gate(dev, "aux_uart", parent, 0, gate, 0, 0, NULL);
|
||||||
|
|
||||||
onecell->clks[BCM2835_AUX_CLOCK_SPI1] =
|
onecell->hws[BCM2835_AUX_CLOCK_SPI1] =
|
||||||
clk_register_gate(dev, "aux_spi1", parent, 0, gate, 1, 0, NULL);
|
clk_hw_register_gate(dev, "aux_spi1", parent, 0, gate, 1, 0, NULL);
|
||||||
|
|
||||||
onecell->clks[BCM2835_AUX_CLOCK_SPI2] =
|
onecell->hws[BCM2835_AUX_CLOCK_SPI2] =
|
||||||
clk_register_gate(dev, "aux_spi2", parent, 0, gate, 2, 0, NULL);
|
clk_hw_register_gate(dev, "aux_spi2", parent, 0, gate, 2, 0, NULL);
|
||||||
|
|
||||||
of_clk_add_provider(pdev->dev.of_node, of_clk_src_onecell_get, onecell);
|
return of_clk_add_hw_provider(pdev->dev.of_node, of_clk_hw_onecell_get,
|
||||||
|
onecell);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct of_device_id bcm2835_aux_clk_of_match[] = {
|
static const struct of_device_id bcm2835_aux_clk_of_match[] = {
|
||||||
|
|
|
@ -303,8 +303,8 @@ struct bcm2835_cprman {
|
||||||
spinlock_t regs_lock; /* spinlock for all clocks */
|
spinlock_t regs_lock; /* spinlock for all clocks */
|
||||||
const char *osc_name;
|
const char *osc_name;
|
||||||
|
|
||||||
struct clk_onecell_data onecell;
|
/* Must be last */
|
||||||
struct clk *clks[];
|
struct clk_hw_onecell_data onecell;
|
||||||
};
|
};
|
||||||
|
|
||||||
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)
|
||||||
|
@ -345,24 +345,24 @@ static int bcm2835_debugfs_regset(struct bcm2835_cprman *cprman, u32 base,
|
||||||
*/
|
*/
|
||||||
void __init bcm2835_init_clocks(void)
|
void __init bcm2835_init_clocks(void)
|
||||||
{
|
{
|
||||||
struct clk *clk;
|
struct clk_hw *hw;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL, 0, 126000000);
|
hw = clk_hw_register_fixed_rate(NULL, "apb_pclk", NULL, 0, 126000000);
|
||||||
if (IS_ERR(clk))
|
if (IS_ERR(hw))
|
||||||
pr_err("apb_pclk not registered\n");
|
pr_err("apb_pclk not registered\n");
|
||||||
|
|
||||||
clk = clk_register_fixed_rate(NULL, "uart0_pclk", NULL, 0, 3000000);
|
hw = clk_hw_register_fixed_rate(NULL, "uart0_pclk", NULL, 0, 3000000);
|
||||||
if (IS_ERR(clk))
|
if (IS_ERR(hw))
|
||||||
pr_err("uart0_pclk not registered\n");
|
pr_err("uart0_pclk not registered\n");
|
||||||
ret = clk_register_clkdev(clk, NULL, "20201000.uart");
|
ret = clk_hw_register_clkdev(hw, NULL, "20201000.uart");
|
||||||
if (ret)
|
if (ret)
|
||||||
pr_err("uart0_pclk alias not registered\n");
|
pr_err("uart0_pclk alias not registered\n");
|
||||||
|
|
||||||
clk = clk_register_fixed_rate(NULL, "uart1_pclk", NULL, 0, 125000000);
|
hw = clk_hw_register_fixed_rate(NULL, "uart1_pclk", NULL, 0, 125000000);
|
||||||
if (IS_ERR(clk))
|
if (IS_ERR(hw))
|
||||||
pr_err("uart1_pclk not registered\n");
|
pr_err("uart1_pclk not registered\n");
|
||||||
ret = clk_register_clkdev(clk, NULL, "20215000.uart");
|
ret = clk_hw_register_clkdev(hw, NULL, "20215000.uart");
|
||||||
if (ret)
|
if (ret)
|
||||||
pr_err("uart1_pclk alias not registered\n");
|
pr_err("uart1_pclk alias not registered\n");
|
||||||
}
|
}
|
||||||
|
@ -1147,11 +1147,12 @@ static const struct clk_ops bcm2835_vpu_clock_clk_ops = {
|
||||||
.debug_init = bcm2835_clock_debug_init,
|
.debug_init = bcm2835_clock_debug_init,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct clk *bcm2835_register_pll(struct bcm2835_cprman *cprman,
|
static struct clk_hw *bcm2835_register_pll(struct bcm2835_cprman *cprman,
|
||||||
const struct bcm2835_pll_data *data)
|
const struct bcm2835_pll_data *data)
|
||||||
{
|
{
|
||||||
struct bcm2835_pll *pll;
|
struct bcm2835_pll *pll;
|
||||||
struct clk_init_data init;
|
struct clk_init_data init;
|
||||||
|
int ret;
|
||||||
|
|
||||||
memset(&init, 0, sizeof(init));
|
memset(&init, 0, sizeof(init));
|
||||||
|
|
||||||
|
@ -1170,17 +1171,20 @@ static struct clk *bcm2835_register_pll(struct bcm2835_cprman *cprman,
|
||||||
pll->data = data;
|
pll->data = data;
|
||||||
pll->hw.init = &init;
|
pll->hw.init = &init;
|
||||||
|
|
||||||
return devm_clk_register(cprman->dev, &pll->hw);
|
ret = devm_clk_hw_register(cprman->dev, &pll->hw);
|
||||||
|
if (ret)
|
||||||
|
return NULL;
|
||||||
|
return &pll->hw;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct clk *
|
static struct clk_hw *
|
||||||
bcm2835_register_pll_divider(struct bcm2835_cprman *cprman,
|
bcm2835_register_pll_divider(struct bcm2835_cprman *cprman,
|
||||||
const struct bcm2835_pll_divider_data *data)
|
const struct bcm2835_pll_divider_data *data)
|
||||||
{
|
{
|
||||||
struct bcm2835_pll_divider *divider;
|
struct bcm2835_pll_divider *divider;
|
||||||
struct clk_init_data init;
|
struct clk_init_data init;
|
||||||
struct clk *clk;
|
|
||||||
const char *divider_name;
|
const char *divider_name;
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (data->fixed_divider != 1) {
|
if (data->fixed_divider != 1) {
|
||||||
divider_name = devm_kasprintf(cprman->dev, GFP_KERNEL,
|
divider_name = devm_kasprintf(cprman->dev, GFP_KERNEL,
|
||||||
|
@ -1214,32 +1218,33 @@ bcm2835_register_pll_divider(struct bcm2835_cprman *cprman,
|
||||||
divider->cprman = cprman;
|
divider->cprman = cprman;
|
||||||
divider->data = data;
|
divider->data = data;
|
||||||
|
|
||||||
clk = devm_clk_register(cprman->dev, ÷r->div.hw);
|
ret = devm_clk_hw_register(cprman->dev, ÷r->div.hw);
|
||||||
if (IS_ERR(clk))
|
if (ret)
|
||||||
return clk;
|
return ERR_PTR(ret);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* PLLH's channels have a fixed divide by 10 afterwards, which
|
* PLLH's channels have a fixed divide by 10 afterwards, which
|
||||||
* is what our consumers are actually using.
|
* is what our consumers are actually using.
|
||||||
*/
|
*/
|
||||||
if (data->fixed_divider != 1) {
|
if (data->fixed_divider != 1) {
|
||||||
return clk_register_fixed_factor(cprman->dev, data->name,
|
return clk_hw_register_fixed_factor(cprman->dev, data->name,
|
||||||
divider_name,
|
divider_name,
|
||||||
CLK_SET_RATE_PARENT,
|
CLK_SET_RATE_PARENT,
|
||||||
1,
|
1,
|
||||||
data->fixed_divider);
|
data->fixed_divider);
|
||||||
}
|
}
|
||||||
|
|
||||||
return clk;
|
return ÷r->div.hw;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct clk *bcm2835_register_clock(struct bcm2835_cprman *cprman,
|
static struct clk_hw *bcm2835_register_clock(struct bcm2835_cprman *cprman,
|
||||||
const struct bcm2835_clock_data *data)
|
const struct bcm2835_clock_data *data)
|
||||||
{
|
{
|
||||||
struct bcm2835_clock *clock;
|
struct bcm2835_clock *clock;
|
||||||
struct clk_init_data init;
|
struct clk_init_data init;
|
||||||
const char *parents[1 << CM_SRC_BITS];
|
const char *parents[1 << CM_SRC_BITS];
|
||||||
size_t i;
|
size_t i;
|
||||||
|
int ret;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Replace our "xosc" references with the oscillator's
|
* Replace our "xosc" references with the oscillator's
|
||||||
|
@ -1279,7 +1284,10 @@ static struct clk *bcm2835_register_clock(struct bcm2835_cprman *cprman,
|
||||||
clock->data = data;
|
clock->data = data;
|
||||||
clock->hw.init = &init;
|
clock->hw.init = &init;
|
||||||
|
|
||||||
return devm_clk_register(cprman->dev, &clock->hw);
|
ret = devm_clk_hw_register(cprman->dev, &clock->hw);
|
||||||
|
if (ret)
|
||||||
|
return ERR_PTR(ret);
|
||||||
|
return &clock->hw;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct clk *bcm2835_register_gate(struct bcm2835_cprman *cprman,
|
static struct clk *bcm2835_register_gate(struct bcm2835_cprman *cprman,
|
||||||
|
@ -1291,8 +1299,8 @@ static struct clk *bcm2835_register_gate(struct bcm2835_cprman *cprman,
|
||||||
CM_GATE_BIT, 0, &cprman->regs_lock);
|
CM_GATE_BIT, 0, &cprman->regs_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct clk *(*bcm2835_clk_register)(struct bcm2835_cprman *cprman,
|
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;
|
||||||
const void *data;
|
const void *data;
|
||||||
|
@ -1847,7 +1855,7 @@ static int bcm2835_mark_sdc_parent_critical(struct clk *sdc)
|
||||||
static int bcm2835_clk_probe(struct platform_device *pdev)
|
static int bcm2835_clk_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct device *dev = &pdev->dev;
|
struct device *dev = &pdev->dev;
|
||||||
struct clk **clks;
|
struct clk_hw **hws;
|
||||||
struct bcm2835_cprman *cprman;
|
struct bcm2835_cprman *cprman;
|
||||||
struct resource *res;
|
struct resource *res;
|
||||||
const struct bcm2835_clk_desc *desc;
|
const struct bcm2835_clk_desc *desc;
|
||||||
|
@ -1855,8 +1863,8 @@ static int bcm2835_clk_probe(struct platform_device *pdev)
|
||||||
size_t i;
|
size_t i;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
cprman = devm_kzalloc(dev,
|
cprman = devm_kzalloc(dev, sizeof(*cprman) +
|
||||||
sizeof(*cprman) + asize * sizeof(*clks),
|
sizeof(*cprman->onecell.hws) * asize,
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
if (!cprman)
|
if (!cprman)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
@ -1874,22 +1882,21 @@ static int bcm2835_clk_probe(struct platform_device *pdev)
|
||||||
|
|
||||||
platform_set_drvdata(pdev, cprman);
|
platform_set_drvdata(pdev, cprman);
|
||||||
|
|
||||||
cprman->onecell.clk_num = asize;
|
cprman->onecell.num = asize;
|
||||||
cprman->onecell.clks = cprman->clks;
|
hws = cprman->onecell.hws;
|
||||||
clks = cprman->clks;
|
|
||||||
|
|
||||||
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)
|
||||||
clks[i] = desc->clk_register(cprman, desc->data);
|
hws[i] = desc->clk_register(cprman, desc->data);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = bcm2835_mark_sdc_parent_critical(clks[BCM2835_CLOCK_SDRAM]);
|
ret = bcm2835_mark_sdc_parent_critical(hws[BCM2835_CLOCK_SDRAM]->clk);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
return of_clk_add_provider(dev->of_node, of_clk_src_onecell_get,
|
return of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get,
|
||||||
&cprman->onecell);
|
&cprman->onecell);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct of_device_id bcm2835_clk_of_match[] = {
|
static const struct of_device_id bcm2835_clk_of_match[] = {
|
||||||
|
|
Loading…
Reference in New Issue