sh: clkfwk: Rework legacy CPG clock handling.
This moves out the old legacy CPG clocks to their own file, and converts over the existing users. With these clocks going away and each CPU dealing with them on their own, CPUs can gradually move over to the new interface. Signed-off-by: Paul Mundt <lethal@linux-sh.org>
This commit is contained in:
parent
100890c55e
commit
253b0887b3
13 changed files with 110 additions and 63 deletions
|
@ -513,6 +513,9 @@ config SH_PCLK_FREQ
|
||||||
This is necessary for determining the reference clock value on
|
This is necessary for determining the reference clock value on
|
||||||
platforms lacking an RTC.
|
platforms lacking an RTC.
|
||||||
|
|
||||||
|
config SH_CLK_CPG_LEGACY
|
||||||
|
def_bool y
|
||||||
|
|
||||||
config SH_CLK_MD
|
config SH_CLK_MD
|
||||||
int "CPU Mode Pin Setting"
|
int "CPU Mode Pin Setting"
|
||||||
depends on CPU_SH2
|
depends on CPU_SH2
|
||||||
|
|
|
@ -47,7 +47,7 @@ struct clk_lookup {
|
||||||
#define CLK_ENABLE_ON_INIT (1 << 0)
|
#define CLK_ENABLE_ON_INIT (1 << 0)
|
||||||
|
|
||||||
/* Should be defined by processor-specific code */
|
/* Should be defined by processor-specific code */
|
||||||
void arch_init_clk_ops(struct clk_ops **, int type);
|
void __deprecated arch_init_clk_ops(struct clk_ops **, int type);
|
||||||
int __init arch_clk_init(void);
|
int __init arch_clk_init(void);
|
||||||
|
|
||||||
/* arch/sh/kernel/cpu/clock.c */
|
/* arch/sh/kernel/cpu/clock.c */
|
||||||
|
@ -59,6 +59,9 @@ int clk_reparent(struct clk *child, struct clk *parent);
|
||||||
int clk_register(struct clk *);
|
int clk_register(struct clk *);
|
||||||
void clk_unregister(struct clk *);
|
void clk_unregister(struct clk *);
|
||||||
|
|
||||||
|
/* arch/sh/kernel/cpu/clock-cpg.c */
|
||||||
|
int __init __deprecated cpg_clk_init(void);
|
||||||
|
|
||||||
/* the exported API, in addition to clk_set_rate */
|
/* the exported API, in addition to clk_set_rate */
|
||||||
/**
|
/**
|
||||||
* clk_set_rate_ex - set the clock rate for a clock source, with additional parameter
|
* clk_set_rate_ex - set the clock rate for a clock source, with additional parameter
|
||||||
|
|
|
@ -46,6 +46,8 @@ struct sh_machine_vector {
|
||||||
|
|
||||||
void __iomem *(*mv_ioport_map)(unsigned long port, unsigned int size);
|
void __iomem *(*mv_ioport_map)(unsigned long port, unsigned int size);
|
||||||
void (*mv_ioport_unmap)(void __iomem *);
|
void (*mv_ioport_unmap)(void __iomem *);
|
||||||
|
|
||||||
|
int (*mv_clk_init)(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct sh_machine_vector sh_mv;
|
extern struct sh_machine_vector sh_mv;
|
||||||
|
|
|
@ -17,5 +17,6 @@ obj-$(CONFIG_ARCH_SHMOBILE) += shmobile/
|
||||||
|
|
||||||
obj-$(CONFIG_UBC_WAKEUP) += ubc.o
|
obj-$(CONFIG_UBC_WAKEUP) += ubc.o
|
||||||
obj-$(CONFIG_SH_ADC) += adc.o
|
obj-$(CONFIG_SH_ADC) += adc.o
|
||||||
|
obj-$(CONFIG_SH_CLK_CPG_LEGACY) += clock-cpg.o
|
||||||
|
|
||||||
obj-y += irq/ init.o clock.o
|
obj-y += irq/ init.o clock.o
|
||||||
|
|
60
arch/sh/kernel/cpu/clock-cpg.c
Normal file
60
arch/sh/kernel/cpu/clock-cpg.c
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
#include <linux/clk.h>
|
||||||
|
#include <linux/compiler.h>
|
||||||
|
#include <asm/clock.h>
|
||||||
|
|
||||||
|
static struct clk master_clk = {
|
||||||
|
.name = "master_clk",
|
||||||
|
.flags = CLK_ENABLE_ON_INIT,
|
||||||
|
.rate = CONFIG_SH_PCLK_FREQ,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct clk peripheral_clk = {
|
||||||
|
.name = "peripheral_clk",
|
||||||
|
.parent = &master_clk,
|
||||||
|
.flags = CLK_ENABLE_ON_INIT,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct clk bus_clk = {
|
||||||
|
.name = "bus_clk",
|
||||||
|
.parent = &master_clk,
|
||||||
|
.flags = CLK_ENABLE_ON_INIT,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct clk cpu_clk = {
|
||||||
|
.name = "cpu_clk",
|
||||||
|
.parent = &master_clk,
|
||||||
|
.flags = CLK_ENABLE_ON_INIT,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The ordering of these clocks matters, do not change it.
|
||||||
|
*/
|
||||||
|
static struct clk *onchip_clocks[] = {
|
||||||
|
&master_clk,
|
||||||
|
&peripheral_clk,
|
||||||
|
&bus_clk,
|
||||||
|
&cpu_clk,
|
||||||
|
};
|
||||||
|
|
||||||
|
int __init __deprecated cpg_clk_init(void)
|
||||||
|
{
|
||||||
|
int i, ret = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(onchip_clocks); i++) {
|
||||||
|
struct clk *clk = onchip_clocks[i];
|
||||||
|
arch_init_clk_ops(&clk->ops, i);
|
||||||
|
if (clk->ops)
|
||||||
|
ret |= clk_register(clk);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Placeholder for compatability, until the lazy CPUs do this
|
||||||
|
* on their own.
|
||||||
|
*/
|
||||||
|
int __init __weak arch_clk_init(void)
|
||||||
|
{
|
||||||
|
return cpg_clk_init();
|
||||||
|
}
|
|
@ -30,54 +30,12 @@
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
#include <linux/proc_fs.h>
|
#include <linux/proc_fs.h>
|
||||||
#include <asm/clock.h>
|
#include <asm/clock.h>
|
||||||
|
#include <asm/machvec.h>
|
||||||
|
|
||||||
static LIST_HEAD(clock_list);
|
static LIST_HEAD(clock_list);
|
||||||
static DEFINE_SPINLOCK(clock_lock);
|
static DEFINE_SPINLOCK(clock_lock);
|
||||||
static DEFINE_MUTEX(clock_list_sem);
|
static DEFINE_MUTEX(clock_list_sem);
|
||||||
|
|
||||||
/*
|
|
||||||
* Each subtype is expected to define the init routines for these clocks,
|
|
||||||
* as each subtype (or processor family) will have these clocks at the
|
|
||||||
* very least. These are all provided through the CPG, which even some of
|
|
||||||
* the more quirky parts (such as ST40, SH4-202, etc.) still have.
|
|
||||||
*
|
|
||||||
* The processor-specific code is expected to register any additional
|
|
||||||
* clock sources that are of interest.
|
|
||||||
*/
|
|
||||||
static struct clk master_clk = {
|
|
||||||
.name = "master_clk",
|
|
||||||
.flags = CLK_ENABLE_ON_INIT,
|
|
||||||
.rate = CONFIG_SH_PCLK_FREQ,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk peripheral_clk = {
|
|
||||||
.name = "peripheral_clk",
|
|
||||||
.parent = &master_clk,
|
|
||||||
.flags = CLK_ENABLE_ON_INIT,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk bus_clk = {
|
|
||||||
.name = "bus_clk",
|
|
||||||
.parent = &master_clk,
|
|
||||||
.flags = CLK_ENABLE_ON_INIT,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk cpu_clk = {
|
|
||||||
.name = "cpu_clk",
|
|
||||||
.parent = &master_clk,
|
|
||||||
.flags = CLK_ENABLE_ON_INIT,
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The ordering of these clocks matters, do not change it.
|
|
||||||
*/
|
|
||||||
static struct clk *onchip_clocks[] = {
|
|
||||||
&master_clk,
|
|
||||||
&peripheral_clk,
|
|
||||||
&bus_clk,
|
|
||||||
&cpu_clk,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Used for clocks that always have same value as the parent clock */
|
/* Used for clocks that always have same value as the parent clock */
|
||||||
unsigned long followparent_recalc(struct clk *clk)
|
unsigned long followparent_recalc(struct clk *clk)
|
||||||
{
|
{
|
||||||
|
@ -443,10 +401,6 @@ void clk_put(struct clk *clk)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(clk_put);
|
EXPORT_SYMBOL_GPL(clk_put);
|
||||||
|
|
||||||
int __init __weak arch_clk_init(void)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int show_clocks(char *buf, char **start, off_t off,
|
static int show_clocks(char *buf, char **start, off_t off,
|
||||||
int len, int *eof, void *data)
|
int len, int *eof, void *data)
|
||||||
|
@ -533,18 +487,22 @@ subsys_initcall(clk_sysdev_init);
|
||||||
|
|
||||||
int __init clk_init(void)
|
int __init clk_init(void)
|
||||||
{
|
{
|
||||||
int i, ret = 0;
|
int ret;
|
||||||
|
|
||||||
BUG_ON(!master_clk.rate);
|
ret = arch_clk_init();
|
||||||
|
if (unlikely(ret)) {
|
||||||
for (i = 0; i < ARRAY_SIZE(onchip_clocks); i++) {
|
pr_err("%s: CPU clock registration failed.\n", __func__);
|
||||||
struct clk *clk = onchip_clocks[i];
|
return ret;
|
||||||
|
|
||||||
arch_init_clk_ops(&clk->ops, i);
|
|
||||||
ret |= clk_register(clk);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ret |= arch_clk_init();
|
if (sh_mv.mv_clk_init) {
|
||||||
|
ret = sh_mv.mv_clk_init();
|
||||||
|
if (unlikely(ret)) {
|
||||||
|
pr_err("%s: machvec clock initialization failed.\n",
|
||||||
|
__func__);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Kick the child clocks.. */
|
/* Kick the child clocks.. */
|
||||||
recalculate_root_clocks();
|
recalculate_root_clocks();
|
||||||
|
|
|
@ -152,9 +152,12 @@ static struct clk *sh4202_onchip_clocks[] = {
|
||||||
|
|
||||||
int __init arch_clk_init(void)
|
int __init arch_clk_init(void)
|
||||||
{
|
{
|
||||||
struct clk *clk = clk_get(NULL, "master_clk");
|
struct clk *clk;
|
||||||
int i, ret = 0;
|
int i, ret = 0;
|
||||||
|
|
||||||
|
cpg_clk_init();
|
||||||
|
|
||||||
|
clk = clk_get(NULL, "master_clk");
|
||||||
for (i = 0; i < ARRAY_SIZE(sh4202_onchip_clocks); i++) {
|
for (i = 0; i < ARRAY_SIZE(sh4202_onchip_clocks); i++) {
|
||||||
struct clk *clkp = sh4202_onchip_clocks[i];
|
struct clk *clkp = sh4202_onchip_clocks[i];
|
||||||
|
|
||||||
|
|
|
@ -892,6 +892,8 @@ int __init arch_clk_init(void)
|
||||||
struct clk *clk;
|
struct clk *clk;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
clk_cpg_init();
|
||||||
|
|
||||||
clk = clk_get(NULL, "master_clk");
|
clk = clk_get(NULL, "master_clk");
|
||||||
for (i = 0; i < ARRAY_SIZE(sh7722_clocks); i++) {
|
for (i = 0; i < ARRAY_SIZE(sh7722_clocks); i++) {
|
||||||
pr_debug( "Registering clock '%s'\n", sh7722_clocks[i]->name);
|
pr_debug( "Registering clock '%s'\n", sh7722_clocks[i]->name);
|
||||||
|
|
|
@ -92,9 +92,12 @@ static struct clk *sh7763_onchip_clocks[] = {
|
||||||
|
|
||||||
int __init arch_clk_init(void)
|
int __init arch_clk_init(void)
|
||||||
{
|
{
|
||||||
struct clk *clk = clk_get(NULL, "master_clk");
|
struct clk *clk;
|
||||||
int i, ret = 0;
|
int i, ret = 0;
|
||||||
|
|
||||||
|
cpg_clk_init();
|
||||||
|
|
||||||
|
clk = clk_get(NULL, "master_clk");
|
||||||
for (i = 0; i < ARRAY_SIZE(sh7763_onchip_clocks); i++) {
|
for (i = 0; i < ARRAY_SIZE(sh7763_onchip_clocks); i++) {
|
||||||
struct clk *clkp = sh7763_onchip_clocks[i];
|
struct clk *clkp = sh7763_onchip_clocks[i];
|
||||||
|
|
||||||
|
|
|
@ -98,9 +98,12 @@ static struct clk *sh7780_onchip_clocks[] = {
|
||||||
|
|
||||||
int __init arch_clk_init(void)
|
int __init arch_clk_init(void)
|
||||||
{
|
{
|
||||||
struct clk *clk = clk_get(NULL, "master_clk");
|
struct clk *clk;
|
||||||
int i, ret = 0;
|
int i, ret = 0;
|
||||||
|
|
||||||
|
cpg_clk_init();
|
||||||
|
|
||||||
|
clk = clk_get(NULL, "master_clk");
|
||||||
for (i = 0; i < ARRAY_SIZE(sh7780_onchip_clocks); i++) {
|
for (i = 0; i < ARRAY_SIZE(sh7780_onchip_clocks); i++) {
|
||||||
struct clk *clkp = sh7780_onchip_clocks[i];
|
struct clk *clkp = sh7780_onchip_clocks[i];
|
||||||
|
|
||||||
|
|
|
@ -136,9 +136,12 @@ static struct clk *sh7785_onchip_clocks[] = {
|
||||||
|
|
||||||
int __init arch_clk_init(void)
|
int __init arch_clk_init(void)
|
||||||
{
|
{
|
||||||
struct clk *clk = clk_get(NULL, "master_clk");
|
struct clk *clk;
|
||||||
int i, ret = 0;
|
int i, ret = 0;
|
||||||
|
|
||||||
|
cpg_clk_init();
|
||||||
|
|
||||||
|
clk = clk_get(NULL, "master_clk");
|
||||||
for (i = 0; i < ARRAY_SIZE(sh7785_onchip_clocks); i++) {
|
for (i = 0; i < ARRAY_SIZE(sh7785_onchip_clocks); i++) {
|
||||||
struct clk *clkp = sh7785_onchip_clocks[i];
|
struct clk *clkp = sh7785_onchip_clocks[i];
|
||||||
|
|
||||||
|
|
|
@ -122,9 +122,12 @@ static struct clk *sh7786_onchip_clocks[] = {
|
||||||
|
|
||||||
int __init arch_clk_init(void)
|
int __init arch_clk_init(void)
|
||||||
{
|
{
|
||||||
struct clk *clk = clk_get(NULL, "master_clk");
|
struct clk *clk;
|
||||||
int i, ret = 0;
|
int i, ret = 0;
|
||||||
|
|
||||||
|
cpg_clk_init();
|
||||||
|
|
||||||
|
clk = clk_get(NULL, "master_clk");
|
||||||
for (i = 0; i < ARRAY_SIZE(sh7786_onchip_clocks); i++) {
|
for (i = 0; i < ARRAY_SIZE(sh7786_onchip_clocks); i++) {
|
||||||
struct clk *clkp = sh7786_onchip_clocks[i];
|
struct clk *clkp = sh7786_onchip_clocks[i];
|
||||||
|
|
||||||
|
|
|
@ -109,9 +109,12 @@ static struct clk *shx3_onchip_clocks[] = {
|
||||||
|
|
||||||
int __init arch_clk_init(void)
|
int __init arch_clk_init(void)
|
||||||
{
|
{
|
||||||
struct clk *clk = clk_get(NULL, "master_clk");
|
struct clk *clk;
|
||||||
int i, ret = 0;
|
int i, ret = 0;
|
||||||
|
|
||||||
|
cpg_clk_init();
|
||||||
|
|
||||||
|
clk = clk_get(NULL, "master_clk");
|
||||||
for (i = 0; i < ARRAY_SIZE(shx3_onchip_clocks); i++) {
|
for (i = 0; i < ARRAY_SIZE(shx3_onchip_clocks); i++) {
|
||||||
struct clk *clkp = shx3_onchip_clocks[i];
|
struct clk *clkp = shx3_onchip_clocks[i];
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue