提交 09d28d2c 编写于 作者: J Jarkko Nikula 提交者: Tony Lindgren

ARM: OMAP: mcbsp: Start generalize omap2_mcbsp_set_clks_src

This generalizes the omap2_mcbsp_set_clks_src implementation between generic
McBSP and OMAP2 specific McBSP code. Currently this function is used to
select either internal fclk or clks pin as a McBSP CLKS source on OMAP2+.

Implement generalization by having an optional set_clk_src function pointer
in platform data that is used to select parent for a given clock. Idea is to
pass higher level source clock name (later coming from client driver) that
platform specific code will map to platform specific clock name.

API cleanup between McBSP and client code comes later.
Signed-off-by: NJarkko Nikula <jarkko.nikula@bitmer.com>
Acked-by: NPeter Ujfalusi <peter.ujfalusi@ti.com>
Tested-by: NJanusz Krzysztofik <jkrzyszt@tis.icnet.pl>
Signed-off-by: NTony Lindgren <tony@atomide.com>
上级 6e574123
...@@ -63,37 +63,30 @@ void omap2_mcbsp1_mux_fsr_src(u8 mux) ...@@ -63,37 +63,30 @@ void omap2_mcbsp1_mux_fsr_src(u8 mux)
EXPORT_SYMBOL(omap2_mcbsp1_mux_fsr_src); EXPORT_SYMBOL(omap2_mcbsp1_mux_fsr_src);
/* McBSP CLKS source switching function */ /* McBSP CLKS source switching function */
static int omap2_mcbsp_set_clk_src(struct device *dev, struct clk *clk,
int omap2_mcbsp_set_clks_src(u8 id, u8 fck_src_id) const char *src)
{ {
struct omap_mcbsp *mcbsp;
struct clk *fck_src; struct clk *fck_src;
char *fck_src_name; char *fck_src_name;
int r; int r;
if (!omap_mcbsp_check_valid_id(id)) { if (!strcmp(src, "clks_ext"))
pr_err("%s: Invalid id (%d)\n", __func__, id + 1);
return -EINVAL;
}
mcbsp = id_to_mcbsp_ptr(id);
if (fck_src_id == MCBSP_CLKS_PAD_SRC)
fck_src_name = "pad_fck"; fck_src_name = "pad_fck";
else if (fck_src_id == MCBSP_CLKS_PRCM_SRC) else if (!strcmp(src, "clks_fclk"))
fck_src_name = "prcm_fck"; fck_src_name = "prcm_fck";
else else
return -EINVAL; return -EINVAL;
fck_src = clk_get(mcbsp->dev, fck_src_name); fck_src = clk_get(dev, fck_src_name);
if (IS_ERR_OR_NULL(fck_src)) { if (IS_ERR_OR_NULL(fck_src)) {
pr_err("omap-mcbsp: %s: could not clk_get() %s\n", "clks", pr_err("omap-mcbsp: %s: could not clk_get() %s\n", "clks",
fck_src_name); fck_src_name);
return -EINVAL; return -EINVAL;
} }
pm_runtime_put_sync(mcbsp->dev); pm_runtime_put_sync(dev);
r = clk_set_parent(mcbsp->fclk, fck_src); r = clk_set_parent(clk, fck_src);
if (IS_ERR_VALUE(r)) { if (IS_ERR_VALUE(r)) {
pr_err("omap-mcbsp: %s: could not clk_set_parent() to %s\n", pr_err("omap-mcbsp: %s: could not clk_set_parent() to %s\n",
"clks", fck_src_name); "clks", fck_src_name);
...@@ -101,13 +94,12 @@ int omap2_mcbsp_set_clks_src(u8 id, u8 fck_src_id) ...@@ -101,13 +94,12 @@ int omap2_mcbsp_set_clks_src(u8 id, u8 fck_src_id)
return -EINVAL; return -EINVAL;
} }
pm_runtime_get_sync(mcbsp->dev); pm_runtime_get_sync(dev);
clk_put(fck_src); clk_put(fck_src);
return 0; return 0;
} }
EXPORT_SYMBOL(omap2_mcbsp_set_clks_src);
static int omap3_enable_st_clock(unsigned int id, bool enable) static int omap3_enable_st_clock(unsigned int id, bool enable)
{ {
...@@ -188,6 +180,7 @@ static int omap_init_mcbsp(struct omap_hwmod *oh, void *unused) ...@@ -188,6 +180,7 @@ static int omap_init_mcbsp(struct omap_hwmod *oh, void *unused)
name, oh->name); name, oh->name);
return PTR_ERR(pdev); return PTR_ERR(pdev);
} }
pdata->set_clk_src = omap2_mcbsp_set_clk_src;
omap_mcbsp_count++; omap_mcbsp_count++;
return 0; return 0;
} }
......
...@@ -296,7 +296,6 @@ typedef enum { ...@@ -296,7 +296,6 @@ typedef enum {
struct omap_mcbsp_ops { struct omap_mcbsp_ops {
void (*request)(unsigned int); void (*request)(unsigned int);
void (*free)(unsigned int); void (*free)(unsigned int);
int (*set_clks_src)(u8, u8);
}; };
struct omap_mcbsp_platform_data { struct omap_mcbsp_platform_data {
...@@ -309,6 +308,7 @@ struct omap_mcbsp_platform_data { ...@@ -309,6 +308,7 @@ struct omap_mcbsp_platform_data {
bool has_wakeup; /* Wakeup capability */ bool has_wakeup; /* Wakeup capability */
bool has_ccr; /* Transceiver has configuration control registers */ bool has_ccr; /* Transceiver has configuration control registers */
int (*enable_st_clock)(unsigned int, bool); int (*enable_st_clock)(unsigned int, bool);
int (*set_clk_src)(struct device *dev, struct clk *clk, const char *src);
}; };
struct omap_mcbsp_st_data { struct omap_mcbsp_st_data {
...@@ -359,9 +359,6 @@ struct omap_mcbsp_dev_attr { ...@@ -359,9 +359,6 @@ struct omap_mcbsp_dev_attr {
extern struct omap_mcbsp **mcbsp_ptr; extern struct omap_mcbsp **mcbsp_ptr;
extern int omap_mcbsp_count; extern int omap_mcbsp_count;
#define omap_mcbsp_check_valid_id(id) (id < omap_mcbsp_count)
#define id_to_mcbsp_ptr(id) mcbsp_ptr[id];
int omap_mcbsp_init(void); int omap_mcbsp_init(void);
void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg * config); void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg * config);
void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold); void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold);
......
...@@ -29,6 +29,9 @@ ...@@ -29,6 +29,9 @@
struct omap_mcbsp **mcbsp_ptr; struct omap_mcbsp **mcbsp_ptr;
int omap_mcbsp_count; int omap_mcbsp_count;
#define omap_mcbsp_check_valid_id(id) (id < omap_mcbsp_count)
#define id_to_mcbsp_ptr(id) mcbsp_ptr[id];
static void omap_mcbsp_write(struct omap_mcbsp *mcbsp, u16 reg, u32 val) static void omap_mcbsp_write(struct omap_mcbsp *mcbsp, u16 reg, u32 val)
{ {
void __iomem *addr = mcbsp->io_base + reg * mcbsp->pdata->reg_step; void __iomem *addr = mcbsp->io_base + reg * mcbsp->pdata->reg_step;
...@@ -894,18 +897,32 @@ void omap_mcbsp_stop(unsigned int id, int tx, int rx) ...@@ -894,18 +897,32 @@ void omap_mcbsp_stop(unsigned int id, int tx, int rx)
} }
EXPORT_SYMBOL(omap_mcbsp_stop); EXPORT_SYMBOL(omap_mcbsp_stop);
/*
* The following functions are only required on an OMAP1-only build.
* mach-omap2/mcbsp.c contains the real functions
*/
#ifndef CONFIG_ARCH_OMAP2PLUS
int omap2_mcbsp_set_clks_src(u8 id, u8 fck_src_id) int omap2_mcbsp_set_clks_src(u8 id, u8 fck_src_id)
{ {
WARN(1, "%s: should never be called on an OMAP1-only kernel\n", struct omap_mcbsp *mcbsp;
__func__); const char *src;
return -EINVAL;
if (!omap_mcbsp_check_valid_id(id)) {
pr_err("%s: Invalid id (%d)\n", __func__, id + 1);
return -EINVAL;
}
mcbsp = id_to_mcbsp_ptr(id);
if (fck_src_id == MCBSP_CLKS_PAD_SRC)
src = "clks_ext";
else if (fck_src_id == MCBSP_CLKS_PRCM_SRC)
src = "clks_fclk";
else
return -EINVAL;
if (mcbsp->pdata->set_clk_src)
return mcbsp->pdata->set_clk_src(mcbsp->dev, mcbsp->fclk, src);
else
return -EINVAL;
} }
EXPORT_SYMBOL(omap2_mcbsp_set_clks_src);
#ifndef CONFIG_ARCH_OMAP2PLUS
void omap2_mcbsp1_mux_clkr_src(u8 mux) void omap2_mcbsp1_mux_clkr_src(u8 mux)
{ {
WARN(1, "%s: should never be called on an OMAP1-only kernel\n", WARN(1, "%s: should never be called on an OMAP1-only kernel\n",
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册