summaryrefslogtreecommitdiffstats
path: root/sound/soc/sh
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/sh')
-rw-r--r--sound/soc/sh/fsi.c71
-rw-r--r--sound/soc/sh/rcar/core.c28
-rw-r--r--sound/soc/sh/rcar/dvc.c17
-rw-r--r--sound/soc/sh/rcar/rsnd.h11
-rw-r--r--sound/soc/sh/rcar/src.c17
-rw-r--r--sound/soc/sh/rcar/ssi.c17
6 files changed, 113 insertions, 48 deletions
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index b87b22e88e43..0c2af21b0b82 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -1876,7 +1876,40 @@ static void fsi_handler_init(struct fsi_priv *fsi,
}
}
-static struct of_device_id fsi_of_match[];
+static const struct fsi_core fsi1_core = {
+ .ver = 1,
+
+ /* Interrupt */
+ .int_st = INT_ST,
+ .iemsk = IEMSK,
+ .imsk = IMSK,
+};
+
+static const struct fsi_core fsi2_core = {
+ .ver = 2,
+
+ /* Interrupt */
+ .int_st = CPU_INT_ST,
+ .iemsk = CPU_IEMSK,
+ .imsk = CPU_IMSK,
+ .a_mclk = A_MST_CTLR,
+ .b_mclk = B_MST_CTLR,
+};
+
+static const struct of_device_id fsi_of_match[] = {
+ { .compatible = "renesas,sh_fsi", .data = &fsi1_core},
+ { .compatible = "renesas,sh_fsi2", .data = &fsi2_core},
+ {},
+};
+MODULE_DEVICE_TABLE(of, fsi_of_match);
+
+static const struct platform_device_id fsi_id_table[] = {
+ { "sh_fsi", (kernel_ulong_t)&fsi1_core },
+ { "sh_fsi2", (kernel_ulong_t)&fsi2_core },
+ {},
+};
+MODULE_DEVICE_TABLE(platform, fsi_id_table);
+
static int fsi_probe(struct platform_device *pdev)
{
struct fsi_master *master;
@@ -2072,40 +2105,6 @@ static struct dev_pm_ops fsi_pm_ops = {
.resume = fsi_resume,
};
-static struct fsi_core fsi1_core = {
- .ver = 1,
-
- /* Interrupt */
- .int_st = INT_ST,
- .iemsk = IEMSK,
- .imsk = IMSK,
-};
-
-static struct fsi_core fsi2_core = {
- .ver = 2,
-
- /* Interrupt */
- .int_st = CPU_INT_ST,
- .iemsk = CPU_IEMSK,
- .imsk = CPU_IMSK,
- .a_mclk = A_MST_CTLR,
- .b_mclk = B_MST_CTLR,
-};
-
-static struct of_device_id fsi_of_match[] = {
- { .compatible = "renesas,sh_fsi", .data = &fsi1_core},
- { .compatible = "renesas,sh_fsi2", .data = &fsi2_core},
- {},
-};
-MODULE_DEVICE_TABLE(of, fsi_of_match);
-
-static struct platform_device_id fsi_id_table[] = {
- { "sh_fsi", (kernel_ulong_t)&fsi1_core },
- { "sh_fsi2", (kernel_ulong_t)&fsi2_core },
- {},
-};
-MODULE_DEVICE_TABLE(platform, fsi_id_table);
-
static struct platform_driver fsi_driver = {
.driver = {
.name = "fsi-pcm-audio",
@@ -2119,7 +2118,7 @@ static struct platform_driver fsi_driver = {
module_platform_driver(fsi_driver);
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("SuperH onchip FSI audio driver");
MODULE_AUTHOR("Kuninori Morimoto <morimoto.kuninori@renesas.com>");
MODULE_ALIAS("platform:fsi-pcm-audio");
diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c
index 1b53605f7154..31202e95be1e 100644
--- a/sound/soc/sh/rcar/core.c
+++ b/sound/soc/sh/rcar/core.c
@@ -149,16 +149,29 @@ char *rsnd_mod_dma_name(struct rsnd_mod *mod)
return mod->ops->dma_name(mod);
}
-void rsnd_mod_init(struct rsnd_mod *mod,
+int rsnd_mod_init(struct rsnd_mod *mod,
struct rsnd_mod_ops *ops,
struct clk *clk,
enum rsnd_mod_type type,
int id)
{
+ int ret = clk_prepare(clk);
+
+ if (ret)
+ return ret;
+
mod->id = id;
mod->ops = ops;
mod->type = type;
mod->clk = clk;
+
+ return ret;
+}
+
+void rsnd_mod_quit(struct rsnd_mod *mod)
+{
+ if (mod->clk)
+ clk_unprepare(mod->clk);
}
/*
@@ -1252,6 +1265,8 @@ static int rsnd_probe(struct platform_device *pdev)
goto exit_snd_probe;
}
+ dev_set_drvdata(dev, priv);
+
/*
* asoc register
*/
@@ -1268,8 +1283,6 @@ static int rsnd_probe(struct platform_device *pdev)
goto exit_snd_soc;
}
- dev_set_drvdata(dev, priv);
-
pm_runtime_enable(dev);
dev_info(dev, "probed\n");
@@ -1290,6 +1303,12 @@ static int rsnd_remove(struct platform_device *pdev)
{
struct rsnd_priv *priv = dev_get_drvdata(&pdev->dev);
struct rsnd_dai *rdai;
+ void (*remove_func[])(struct platform_device *pdev,
+ struct rsnd_priv *priv) = {
+ rsnd_ssi_remove,
+ rsnd_src_remove,
+ rsnd_dvc_remove,
+ };
int ret = 0, i;
pm_runtime_disable(&pdev->dev);
@@ -1299,6 +1318,9 @@ static int rsnd_remove(struct platform_device *pdev)
ret |= rsnd_dai_call(remove, &rdai->capture, priv);
}
+ for (i = 0; i < ARRAY_SIZE(remove_func); i++)
+ remove_func[i](pdev, priv);
+
snd_soc_unregister_component(&pdev->dev);
snd_soc_unregister_platform(&pdev->dev);
diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c
index d7f9ed959c4e..261997a3f589 100644
--- a/sound/soc/sh/rcar/dvc.c
+++ b/sound/soc/sh/rcar/dvc.c
@@ -333,7 +333,7 @@ int rsnd_dvc_probe(struct platform_device *pdev,
struct rsnd_dvc *dvc;
struct clk *clk;
char name[RSND_DVC_NAME_SIZE];
- int i, nr;
+ int i, nr, ret;
rsnd_of_parse_dvc(pdev, of_data, priv);
@@ -366,11 +366,24 @@ int rsnd_dvc_probe(struct platform_device *pdev,
dvc->info = &info->dvc_info[i];
- rsnd_mod_init(&dvc->mod, &rsnd_dvc_ops,
+ ret = rsnd_mod_init(&dvc->mod, &rsnd_dvc_ops,
clk, RSND_MOD_DVC, i);
+ if (ret)
+ return ret;
dev_dbg(dev, "CMD%d probed\n", i);
}
return 0;
}
+
+void rsnd_dvc_remove(struct platform_device *pdev,
+ struct rsnd_priv *priv)
+{
+ struct rsnd_dvc *dvc;
+ int i;
+
+ for_each_rsnd_dvc(dvc, priv, i) {
+ rsnd_mod_quit(&dvc->mod);
+ }
+}
diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h
index e7914bd610e2..1bccc5515b5a 100644
--- a/sound/soc/sh/rcar/rsnd.h
+++ b/sound/soc/sh/rcar/rsnd.h
@@ -260,14 +260,15 @@ struct rsnd_mod {
#define rsnd_dma_to_mod(_dma) container_of((_dma), struct rsnd_mod, dma)
#define rsnd_mod_to_io(mod) ((mod)->io)
#define rsnd_mod_id(mod) ((mod)->id)
-#define rsnd_mod_hw_start(mod) clk_prepare_enable((mod)->clk)
-#define rsnd_mod_hw_stop(mod) clk_disable_unprepare((mod)->clk)
+#define rsnd_mod_hw_start(mod) clk_enable((mod)->clk)
+#define rsnd_mod_hw_stop(mod) clk_disable((mod)->clk)
-void rsnd_mod_init(struct rsnd_mod *mod,
+int rsnd_mod_init(struct rsnd_mod *mod,
struct rsnd_mod_ops *ops,
struct clk *clk,
enum rsnd_mod_type type,
int id);
+void rsnd_mod_quit(struct rsnd_mod *mod);
char *rsnd_mod_name(struct rsnd_mod *mod);
char *rsnd_mod_dma_name(struct rsnd_mod *mod);
@@ -480,6 +481,8 @@ int rsnd_kctrl_new_e(struct rsnd_mod *mod,
int rsnd_src_probe(struct platform_device *pdev,
const struct rsnd_of_data *of_data,
struct rsnd_priv *priv);
+void rsnd_src_remove(struct platform_device *pdev,
+ struct rsnd_priv *priv);
struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id);
unsigned int rsnd_src_get_ssi_rate(struct rsnd_priv *priv,
struct rsnd_dai_stream *io,
@@ -498,6 +501,8 @@ int rsnd_src_ssi_irq_disable(struct rsnd_mod *ssi_mod);
int rsnd_ssi_probe(struct platform_device *pdev,
const struct rsnd_of_data *of_data,
struct rsnd_priv *priv);
+void rsnd_ssi_remove(struct platform_device *pdev,
+ struct rsnd_priv *priv);
struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id);
int rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod);
int rsnd_ssi_is_dma_mode(struct rsnd_mod *mod);
diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c
index 81c182b4bad5..c77d059edc84 100644
--- a/sound/soc/sh/rcar/src.c
+++ b/sound/soc/sh/rcar/src.c
@@ -850,7 +850,7 @@ int rsnd_src_probe(struct platform_device *pdev,
struct rsnd_mod_ops *ops;
struct clk *clk;
char name[RSND_SRC_NAME_SIZE];
- int i, nr;
+ int i, nr, ret;
ops = NULL;
if (rsnd_is_gen1(priv))
@@ -890,10 +890,23 @@ int rsnd_src_probe(struct platform_device *pdev,
src->info = &info->src_info[i];
- rsnd_mod_init(&src->mod, ops, clk, RSND_MOD_SRC, i);
+ ret = rsnd_mod_init(&src->mod, ops, clk, RSND_MOD_SRC, i);
+ if (ret)
+ return ret;
dev_dbg(dev, "SRC%d probed\n", i);
}
return 0;
}
+
+void rsnd_src_remove(struct platform_device *pdev,
+ struct rsnd_priv *priv)
+{
+ struct rsnd_src *src;
+ int i;
+
+ for_each_rsnd_src(src, priv, i) {
+ rsnd_mod_quit(&src->mod);
+ }
+}
diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c
index 9e7b627c08e2..f7cb1fd635a0 100644
--- a/sound/soc/sh/rcar/ssi.c
+++ b/sound/soc/sh/rcar/ssi.c
@@ -697,7 +697,7 @@ int rsnd_ssi_probe(struct platform_device *pdev,
struct clk *clk;
struct rsnd_ssi *ssi;
char name[RSND_SSI_NAME_SIZE];
- int i, nr;
+ int i, nr, ret;
rsnd_of_parse_ssi(pdev, of_data, priv);
@@ -732,10 +732,23 @@ int rsnd_ssi_probe(struct platform_device *pdev,
else if (rsnd_ssi_pio_available(ssi))
ops = &rsnd_ssi_pio_ops;
- rsnd_mod_init(&ssi->mod, ops, clk, RSND_MOD_SSI, i);
+ ret = rsnd_mod_init(&ssi->mod, ops, clk, RSND_MOD_SSI, i);
+ if (ret)
+ return ret;
rsnd_ssi_parent_clk_setup(priv, ssi);
}
return 0;
}
+
+void rsnd_ssi_remove(struct platform_device *pdev,
+ struct rsnd_priv *priv)
+{
+ struct rsnd_ssi *ssi;
+ int i;
+
+ for_each_rsnd_ssi(ssi, priv, i) {
+ rsnd_mod_quit(&ssi->mod);
+ }
+}