ASoC: sh_fsi: avoid using global variable

Current FSI driver use global variable to access device data.
But this style will be broken
if SuperH come with multiple FSI blocks in future.
To solve this problem, this patch use cpu_dai->private_data.

Signed-off-by: Kuninori Morimoto <morimoto.kuninori@renesas.com>
Acked-by: Liam Girdwood <lrg@slimlogic.co.uk>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index 9c49c11..7506ef6 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -92,6 +92,7 @@
 struct fsi_priv {
 	void __iomem *base;
 	struct snd_pcm_substream *substream;
+	struct fsi_master *master;
 
 	int fifo_max;
 	int chan;
@@ -110,8 +111,6 @@
 	struct sh_fsi_platform_info *info;
 };
 
-static struct fsi_master *master;
-
 /************************************************************************
 
 
@@ -166,7 +165,7 @@
 	return __fsi_reg_mask_set((u32)(fsi->base + reg), mask, data);
 }
 
-static int fsi_master_write(u32 reg, u32 data)
+static int fsi_master_write(struct fsi_master *master, u32 reg, u32 data)
 {
 	if ((reg < MREG_START) ||
 	    (reg > MREG_END))
@@ -175,7 +174,7 @@
 	return __fsi_reg_write((u32)(master->base + reg), data);
 }
 
-static u32 fsi_master_read(u32 reg)
+static u32 fsi_master_read(struct fsi_master *master, u32 reg)
 {
 	if ((reg < MREG_START) ||
 	    (reg > MREG_END))
@@ -184,7 +183,8 @@
 	return __fsi_reg_read((u32)(master->base + reg));
 }
 
-static int fsi_master_mask_set(u32 reg, u32 mask, u32 data)
+static int fsi_master_mask_set(struct fsi_master *master,
+			       u32 reg, u32 mask, u32 data)
 {
 	if ((reg < MREG_START) ||
 	    (reg > MREG_END))
@@ -200,43 +200,29 @@
 
 
 ************************************************************************/
-static struct fsi_priv *fsi_get(struct snd_pcm_substream *substream)
+static struct fsi_master *fsi_get_master(struct fsi_priv *fsi)
 {
-	struct snd_soc_pcm_runtime *rtd;
-	struct fsi_priv *fsi = NULL;
-
-	if (!substream || !master)
-		return NULL;
-
-	rtd = substream->private_data;
-	switch (rtd->dai->cpu_dai->id) {
-	case 0:
-		fsi = &master->fsia;
-		break;
-	case 1:
-		fsi = &master->fsib;
-		break;
-	}
-
-	return fsi;
+	return fsi->master;
 }
 
 static int fsi_is_port_a(struct fsi_priv *fsi)
 {
-	/* return
-	 * 1 : port a
-	 * 0 : port b
-	 */
+	return fsi->master->base == fsi->base;
+}
 
-	if (fsi == &master->fsia)
-		return 1;
+static struct fsi_priv *fsi_get_priv(struct snd_pcm_substream *substream)
+{
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct snd_soc_dai_link *machine = rtd->dai;
+	struct snd_soc_dai *dai = machine->cpu_dai;
 
-	return 0;
+	return dai->private_data;
 }
 
 static u32 fsi_get_info_flags(struct fsi_priv *fsi)
 {
 	int is_porta = fsi_is_port_a(fsi);
+	struct fsi_master *master = fsi_get_master(fsi);
 
 	return is_porta ? master->info->porta_flags :
 		master->info->portb_flags;
@@ -314,27 +300,30 @@
 static void fsi_irq_enable(struct fsi_priv *fsi, int is_play)
 {
 	u32 data = fsi_port_ab_io_bit(fsi, is_play);
+	struct fsi_master *master = fsi_get_master(fsi);
 
-	fsi_master_mask_set(IMSK,  data, data);
-	fsi_master_mask_set(IEMSK, data, data);
+	fsi_master_mask_set(master, IMSK,  data, data);
+	fsi_master_mask_set(master, IEMSK, data, data);
 }
 
 static void fsi_irq_disable(struct fsi_priv *fsi, int is_play)
 {
 	u32 data = fsi_port_ab_io_bit(fsi, is_play);
+	struct fsi_master *master = fsi_get_master(fsi);
 
-	fsi_master_mask_set(IMSK,  data, 0);
-	fsi_master_mask_set(IEMSK, data, 0);
+	fsi_master_mask_set(master, IMSK,  data, 0);
+	fsi_master_mask_set(master, IEMSK, data, 0);
 }
 
 static void fsi_clk_ctrl(struct fsi_priv *fsi, int enable)
 {
 	u32 val = fsi_is_port_a(fsi) ? (1 << 0) : (1 << 4);
+	struct fsi_master *master = fsi_get_master(fsi);
 
 	if (enable)
-		fsi_master_mask_set(CLK_RST, val, val);
+		fsi_master_mask_set(master, CLK_RST, val, val);
 	else
-		fsi_master_mask_set(CLK_RST, val, 0);
+		fsi_master_mask_set(master, CLK_RST, val, 0);
 }
 
 static void fsi_irq_init(struct fsi_priv *fsi, int is_play)
@@ -355,23 +344,23 @@
 	fsi_reg_mask_set(fsi, ctrl, FIFO_CLR, FIFO_CLR);
 
 	/* clear interrupt factor */
-	fsi_master_mask_set(INT_ST, data, 0);
+	fsi_master_mask_set(fsi_get_master(fsi), INT_ST, data, 0);
 }
 
-static void fsi_soft_all_reset(void)
+static void fsi_soft_all_reset(struct fsi_master *master)
 {
-	u32 status = fsi_master_read(SOFT_RST);
+	u32 status = fsi_master_read(master, SOFT_RST);
 
 	/* port AB reset */
 	status &= 0x000000ff;
-	fsi_master_write(SOFT_RST, status);
+	fsi_master_write(master, SOFT_RST, status);
 	mdelay(10);
 
 	/* soft reset */
 	status &= 0x000000f0;
-	fsi_master_write(SOFT_RST, status);
+	fsi_master_write(master, SOFT_RST, status);
 	status |= 0x00000001;
-	fsi_master_write(SOFT_RST, status);
+	fsi_master_write(master, SOFT_RST, status);
 	mdelay(10);
 }
 
@@ -517,12 +506,13 @@
 
 static irqreturn_t fsi_interrupt(int irq, void *data)
 {
-	u32 status = fsi_master_read(SOFT_RST) & ~0x00000010;
-	u32 int_st = fsi_master_read(INT_ST);
+	struct fsi_master *master = data;
+	u32 status = fsi_master_read(master, SOFT_RST) & ~0x00000010;
+	u32 int_st = fsi_master_read(master, INT_ST);
 
 	/* clear irq status */
-	fsi_master_write(SOFT_RST, status);
-	fsi_master_write(SOFT_RST, status | 0x00000010);
+	fsi_master_write(master, SOFT_RST, status);
+	fsi_master_write(master, SOFT_RST, status | 0x00000010);
 
 	if (int_st & INT_A_OUT)
 		fsi_data_push(&master->fsia);
@@ -533,7 +523,7 @@
 	if (int_st & INT_B_IN)
 		fsi_data_pop(&master->fsib);
 
-	fsi_master_write(INT_ST, 0x0000000);
+	fsi_master_write(master, INT_ST, 0x0000000);
 
 	return IRQ_HANDLED;
 }
@@ -548,7 +538,7 @@
 static int fsi_dai_startup(struct snd_pcm_substream *substream,
 			   struct snd_soc_dai *dai)
 {
-	struct fsi_priv *fsi = fsi_get(substream);
+	struct fsi_priv *fsi = fsi_get_priv(substream);
 	const char *msg;
 	u32 flags = fsi_get_info_flags(fsi);
 	u32 fmt;
@@ -667,7 +657,7 @@
 static void fsi_dai_shutdown(struct snd_pcm_substream *substream,
 			     struct snd_soc_dai *dai)
 {
-	struct fsi_priv *fsi = fsi_get(substream);
+	struct fsi_priv *fsi = fsi_get_priv(substream);
 	int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
 
 	fsi_irq_disable(fsi, is_play);
@@ -679,7 +669,7 @@
 static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd,
 			   struct snd_soc_dai *dai)
 {
-	struct fsi_priv *fsi = fsi_get(substream);
+	struct fsi_priv *fsi = fsi_get_priv(substream);
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
 	int ret = 0;
@@ -760,7 +750,7 @@
 static snd_pcm_uframes_t fsi_pointer(struct snd_pcm_substream *substream)
 {
 	struct snd_pcm_runtime *runtime = substream->runtime;
-	struct fsi_priv *fsi = fsi_get(substream);
+	struct fsi_priv *fsi = fsi_get_priv(substream);
 	long location;
 
 	location = (fsi->byte_offset - 1);
@@ -870,10 +860,16 @@
 ************************************************************************/
 static int fsi_probe(struct platform_device *pdev)
 {
+	struct fsi_master *master;
 	struct resource *res;
 	unsigned int irq;
 	int ret;
 
+	if (0 != pdev->id) {
+		dev_err(&pdev->dev, "current fsi support id 0 only now\n");
+		return -ENODEV;
+	}
+
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	irq = platform_get_irq(pdev, 0);
 	if (!res || !irq) {
@@ -899,15 +895,19 @@
 	master->irq		= irq;
 	master->info		= pdev->dev.platform_data;
 	master->fsia.base	= master->base;
+	master->fsia.master	= master;
 	master->fsib.base	= master->base + 0x40;
+	master->fsib.master	= master;
 
 	pm_runtime_enable(&pdev->dev);
 	pm_runtime_resume(&pdev->dev);
 
 	fsi_soc_dai[0].dev		= &pdev->dev;
+	fsi_soc_dai[0].private_data	= &master->fsia;
 	fsi_soc_dai[1].dev		= &pdev->dev;
+	fsi_soc_dai[1].private_data	= &master->fsib;
 
-	fsi_soft_all_reset();
+	fsi_soft_all_reset(master);
 
 	ret = request_irq(irq, &fsi_interrupt, IRQF_DISABLED, "fsi", master);
 	if (ret) {
@@ -937,6 +937,10 @@
 
 static int fsi_remove(struct platform_device *pdev)
 {
+	struct fsi_master *master;
+
+	master = fsi_get_master(fsi_soc_dai[0].private_data);
+
 	snd_soc_unregister_dais(fsi_soc_dai, ARRAY_SIZE(fsi_soc_dai));
 	snd_soc_unregister_platform(&fsi_soc_platform);
 
@@ -946,7 +950,12 @@
 
 	iounmap(master->base);
 	kfree(master);
-	master = NULL;
+
+	fsi_soc_dai[0].dev		= NULL;
+	fsi_soc_dai[0].private_data	= NULL;
+	fsi_soc_dai[1].dev		= NULL;
+	fsi_soc_dai[1].private_data	= NULL;
+
 	return 0;
 }