aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJarkko Nikula <jarkko.nikula@bitmer.com>2011-09-26 03:45:48 -0400
committerTony Lindgren <tony@atomide.com>2011-09-26 20:48:59 -0400
commit09d28d2c19fe5c2d51b3133329584166dec89f86 (patch)
tree90f327bc24348d6f4157e305d4efe6ac6b834ecb
parent6e574123712b4fb89546b1304dd5438669057723 (diff)
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: Jarkko Nikula <jarkko.nikula@bitmer.com> Acked-by: Peter Ujfalusi <peter.ujfalusi@ti.com> Tested-by: Janusz Krzysztofik <jkrzyszt@tis.icnet.pl> Signed-off-by: Tony Lindgren <tony@atomide.com>
-rw-r--r--arch/arm/mach-omap2/mcbsp.c25
-rw-r--r--arch/arm/plat-omap/include/plat/mcbsp.h5
-rw-r--r--arch/arm/plat-omap/mcbsp.c33
3 files changed, 35 insertions, 28 deletions
diff --git a/arch/arm/mach-omap2/mcbsp.c b/arch/arm/mach-omap2/mcbsp.c
index 92bd5e22a24e..3dd4c473809e 100644
--- a/arch/arm/mach-omap2/mcbsp.c
+++ b/arch/arm/mach-omap2/mcbsp.c
@@ -63,37 +63,30 @@ void omap2_mcbsp1_mux_fsr_src(u8 mux)
63EXPORT_SYMBOL(omap2_mcbsp1_mux_fsr_src); 63EXPORT_SYMBOL(omap2_mcbsp1_mux_fsr_src);
64 64
65/* McBSP CLKS source switching function */ 65/* McBSP CLKS source switching function */
66 66static int omap2_mcbsp_set_clk_src(struct device *dev, struct clk *clk,
67int omap2_mcbsp_set_clks_src(u8 id, u8 fck_src_id) 67 const char *src)
68{ 68{
69 struct omap_mcbsp *mcbsp;
70 struct clk *fck_src; 69 struct clk *fck_src;
71 char *fck_src_name; 70 char *fck_src_name;
72 int r; 71 int r;
73 72
74 if (!omap_mcbsp_check_valid_id(id)) { 73 if (!strcmp(src, "clks_ext"))
75 pr_err("%s: Invalid id (%d)\n", __func__, id + 1);
76 return -EINVAL;
77 }
78 mcbsp = id_to_mcbsp_ptr(id);
79
80 if (fck_src_id == MCBSP_CLKS_PAD_SRC)
81 fck_src_name = "pad_fck"; 74 fck_src_name = "pad_fck";
82 else if (fck_src_id == MCBSP_CLKS_PRCM_SRC) 75 else if (!strcmp(src, "clks_fclk"))
83 fck_src_name = "prcm_fck"; 76 fck_src_name = "prcm_fck";
84 else 77 else
85 return -EINVAL; 78 return -EINVAL;
86 79
87 fck_src = clk_get(mcbsp->dev, fck_src_name); 80 fck_src = clk_get(dev, fck_src_name);
88 if (IS_ERR_OR_NULL(fck_src)) { 81 if (IS_ERR_OR_NULL(fck_src)) {
89 pr_err("omap-mcbsp: %s: could not clk_get() %s\n", "clks", 82 pr_err("omap-mcbsp: %s: could not clk_get() %s\n", "clks",
90 fck_src_name); 83 fck_src_name);
91 return -EINVAL; 84 return -EINVAL;
92 } 85 }
93 86
94 pm_runtime_put_sync(mcbsp->dev); 87 pm_runtime_put_sync(dev);
95 88
96 r = clk_set_parent(mcbsp->fclk, fck_src); 89 r = clk_set_parent(clk, fck_src);
97 if (IS_ERR_VALUE(r)) { 90 if (IS_ERR_VALUE(r)) {
98 pr_err("omap-mcbsp: %s: could not clk_set_parent() to %s\n", 91 pr_err("omap-mcbsp: %s: could not clk_set_parent() to %s\n",
99 "clks", fck_src_name); 92 "clks", fck_src_name);
@@ -101,13 +94,12 @@ int omap2_mcbsp_set_clks_src(u8 id, u8 fck_src_id)
101 return -EINVAL; 94 return -EINVAL;
102 } 95 }
103 96
104 pm_runtime_get_sync(mcbsp->dev); 97 pm_runtime_get_sync(dev);
105 98
106 clk_put(fck_src); 99 clk_put(fck_src);
107 100
108 return 0; 101 return 0;
109} 102}
110EXPORT_SYMBOL(omap2_mcbsp_set_clks_src);
111 103
112static int omap3_enable_st_clock(unsigned int id, bool enable) 104static int omap3_enable_st_clock(unsigned int id, bool enable)
113{ 105{
@@ -188,6 +180,7 @@ static int omap_init_mcbsp(struct omap_hwmod *oh, void *unused)
188 name, oh->name); 180 name, oh->name);
189 return PTR_ERR(pdev); 181 return PTR_ERR(pdev);
190 } 182 }
183 pdata->set_clk_src = omap2_mcbsp_set_clk_src;
191 omap_mcbsp_count++; 184 omap_mcbsp_count++;
192 return 0; 185 return 0;
193} 186}
diff --git a/arch/arm/plat-omap/include/plat/mcbsp.h b/arch/arm/plat-omap/include/plat/mcbsp.h
index af5824a38f9d..c8ebfc9e92ff 100644
--- a/arch/arm/plat-omap/include/plat/mcbsp.h
+++ b/arch/arm/plat-omap/include/plat/mcbsp.h
@@ -296,7 +296,6 @@ typedef enum {
296struct omap_mcbsp_ops { 296struct omap_mcbsp_ops {
297 void (*request)(unsigned int); 297 void (*request)(unsigned int);
298 void (*free)(unsigned int); 298 void (*free)(unsigned int);
299 int (*set_clks_src)(u8, u8);
300}; 299};
301 300
302struct omap_mcbsp_platform_data { 301struct omap_mcbsp_platform_data {
@@ -309,6 +308,7 @@ struct omap_mcbsp_platform_data {
309 bool has_wakeup; /* Wakeup capability */ 308 bool has_wakeup; /* Wakeup capability */
310 bool has_ccr; /* Transceiver has configuration control registers */ 309 bool has_ccr; /* Transceiver has configuration control registers */
311 int (*enable_st_clock)(unsigned int, bool); 310 int (*enable_st_clock)(unsigned int, bool);
311 int (*set_clk_src)(struct device *dev, struct clk *clk, const char *src);
312}; 312};
313 313
314struct omap_mcbsp_st_data { 314struct omap_mcbsp_st_data {
@@ -359,9 +359,6 @@ struct omap_mcbsp_dev_attr {
359extern struct omap_mcbsp **mcbsp_ptr; 359extern struct omap_mcbsp **mcbsp_ptr;
360extern int omap_mcbsp_count; 360extern int omap_mcbsp_count;
361 361
362#define omap_mcbsp_check_valid_id(id) (id < omap_mcbsp_count)
363#define id_to_mcbsp_ptr(id) mcbsp_ptr[id];
364
365int omap_mcbsp_init(void); 362int omap_mcbsp_init(void);
366void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg * config); 363void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg * config);
367void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold); 364void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold);
diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c
index f92227f99f86..38b67d9be5b3 100644
--- a/arch/arm/plat-omap/mcbsp.c
+++ b/arch/arm/plat-omap/mcbsp.c
@@ -29,6 +29,9 @@
29struct omap_mcbsp **mcbsp_ptr; 29struct omap_mcbsp **mcbsp_ptr;
30int omap_mcbsp_count; 30int omap_mcbsp_count;
31 31
32#define omap_mcbsp_check_valid_id(id) (id < omap_mcbsp_count)
33#define id_to_mcbsp_ptr(id) mcbsp_ptr[id];
34
32static void omap_mcbsp_write(struct omap_mcbsp *mcbsp, u16 reg, u32 val) 35static void omap_mcbsp_write(struct omap_mcbsp *mcbsp, u16 reg, u32 val)
33{ 36{
34 void __iomem *addr = mcbsp->io_base + reg * mcbsp->pdata->reg_step; 37 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} 897}
895EXPORT_SYMBOL(omap_mcbsp_stop); 898EXPORT_SYMBOL(omap_mcbsp_stop);
896 899
897/*
898 * The following functions are only required on an OMAP1-only build.
899 * mach-omap2/mcbsp.c contains the real functions
900 */
901#ifndef CONFIG_ARCH_OMAP2PLUS
902int omap2_mcbsp_set_clks_src(u8 id, u8 fck_src_id) 900int omap2_mcbsp_set_clks_src(u8 id, u8 fck_src_id)
903{ 901{
904 WARN(1, "%s: should never be called on an OMAP1-only kernel\n", 902 struct omap_mcbsp *mcbsp;
905 __func__); 903 const char *src;
906 return -EINVAL; 904
905 if (!omap_mcbsp_check_valid_id(id)) {
906 pr_err("%s: Invalid id (%d)\n", __func__, id + 1);
907 return -EINVAL;
908 }
909 mcbsp = id_to_mcbsp_ptr(id);
910
911 if (fck_src_id == MCBSP_CLKS_PAD_SRC)
912 src = "clks_ext";
913 else if (fck_src_id == MCBSP_CLKS_PRCM_SRC)
914 src = "clks_fclk";
915 else
916 return -EINVAL;
917
918 if (mcbsp->pdata->set_clk_src)
919 return mcbsp->pdata->set_clk_src(mcbsp->dev, mcbsp->fclk, src);
920 else
921 return -EINVAL;
907} 922}
923EXPORT_SYMBOL(omap2_mcbsp_set_clks_src);
908 924
925#ifndef CONFIG_ARCH_OMAP2PLUS
909void omap2_mcbsp1_mux_clkr_src(u8 mux) 926void omap2_mcbsp1_mux_clkr_src(u8 mux)
910{ 927{
911 WARN(1, "%s: should never be called on an OMAP1-only kernel\n", 928 WARN(1, "%s: should never be called on an OMAP1-only kernel\n",