diff options
| author | Mark Brown <broonie@kernel.org> | 2017-09-01 14:12:20 +0300 | 
|---|---|---|
| committer | Mark Brown <broonie@kernel.org> | 2017-09-01 14:12:20 +0300 | 
| commit | 94e26c07002fa01fa807c68c6b44355b79ba82ac (patch) | |
| tree | 2e021b07ae30d905767a915288ac8bef3cd1d190 | |
| parent | 460f623a6e3cab02c3cda52cf64094a96afece4e (diff) | |
| parent | a5702e1cb3c47221419617089d59f9741cf981e4 (diff) | |
| download | linux-94e26c07002fa01fa807c68c6b44355b79ba82ac.tar.xz | |
Merge remote-tracking branch 'asoc/topic/rcar' into asoc-next
| -rw-r--r-- | Documentation/devicetree/bindings/sound/renesas,rsnd.txt | 68 | ||||
| -rw-r--r-- | sound/soc/sh/dma-sh7760.c | 6 | ||||
| -rw-r--r-- | sound/soc/sh/fsi.c | 6 | ||||
| -rw-r--r-- | sound/soc/sh/migor.c | 2 | ||||
| -rw-r--r-- | sound/soc/sh/rcar/adg.c | 4 | ||||
| -rw-r--r-- | sound/soc/sh/rcar/core.c | 102 | ||||
| -rw-r--r-- | sound/soc/sh/rcar/ctu.c | 5 | ||||
| -rw-r--r-- | sound/soc/sh/rcar/dma.c | 2 | ||||
| -rw-r--r-- | sound/soc/sh/rcar/dvc.c | 5 | ||||
| -rw-r--r-- | sound/soc/sh/rcar/gen.c | 4 | ||||
| -rw-r--r-- | sound/soc/sh/rcar/mix.c | 5 | ||||
| -rw-r--r-- | sound/soc/sh/rcar/rsnd.h | 1 | ||||
| -rw-r--r-- | sound/soc/sh/rcar/src.c | 14 | ||||
| -rw-r--r-- | sound/soc/sh/rcar/ssi.c | 101 | ||||
| -rw-r--r-- | sound/soc/sh/rcar/ssiu.c | 2 | ||||
| -rw-r--r-- | sound/soc/sh/siu_dai.c | 2 | ||||
| -rw-r--r-- | sound/soc/sh/siu_pcm.c | 2 | 
17 files changed, 170 insertions, 161 deletions
diff --git a/Documentation/devicetree/bindings/sound/renesas,rsnd.txt b/Documentation/devicetree/bindings/sound/renesas,rsnd.txt index 7246bb268bf9..a1536fdc60e6 100644 --- a/Documentation/devicetree/bindings/sound/renesas,rsnd.txt +++ b/Documentation/devicetree/bindings/sound/renesas,rsnd.txt @@ -199,10 +199,10 @@ Ex)  	sound {  		compatible = "simple-scu-audio-card";  		... -		simple-audio-card,cpu@0 { +		simple-audio-card,cpu-0 {  			sound-dai = <&rcar_sound 0>;  		}; -		simple-audio-card,cpu@1 { +		simple-audio-card,cpu-1 {  			sound-dai = <&rcar_sound 1>;  		};  		simple-audio-card,codec { @@ -441,79 +441,79 @@ rcar_sound: sound@ec500000 {  			"clk_a", "clk_b", "clk_c", "clk_i";  	rcar_sound,dvc { -		dvc0: dvc@0 { +		dvc0: dvc-0 {  			dmas = <&audma0 0xbc>;  			dma-names = "tx";  		}; -		dvc1: dvc@1 { +		dvc1: dvc-1 {  			dmas = <&audma0 0xbe>;  			dma-names = "tx";  		};  	};  	rcar_sound,mix { -		mix0: mix@0 { }; -		mix1: mix@1 { }; +		mix0: mix-0 { }; +		mix1: mix-1 { };  	};  	rcar_sound,ctu { -		ctu00: ctu@0 { }; -		ctu01: ctu@1 { }; -		ctu02: ctu@2 { }; -		ctu03: ctu@3 { }; -		ctu10: ctu@4 { }; -		ctu11: ctu@5 { }; -		ctu12: ctu@6 { }; -		ctu13: ctu@7 { }; +		ctu00: ctu-0 { }; +		ctu01: ctu-1 { }; +		ctu02: ctu-2 { }; +		ctu03: ctu-3 { }; +		ctu10: ctu-4 { }; +		ctu11: ctu-5 { }; +		ctu12: ctu-6 { }; +		ctu13: ctu-7 { };  	};  	rcar_sound,src { -		src0: src@0 { +		src0: src-0 {  			interrupts = <0 352 IRQ_TYPE_LEVEL_HIGH>;  			dmas = <&audma0 0x85>, <&audma1 0x9a>;  			dma-names = "rx", "tx";  		}; -		src1: src@1 { +		src1: src-1 {  			interrupts = <0 353 IRQ_TYPE_LEVEL_HIGH>;  			dmas = <&audma0 0x87>, <&audma1 0x9c>;  			dma-names = "rx", "tx";  		}; -		src2: src@2 { +		src2: src-2 {  			interrupts = <0 354 IRQ_TYPE_LEVEL_HIGH>;  			dmas = <&audma0 0x89>, <&audma1 0x9e>;  			dma-names = "rx", "tx";  		}; -		src3: src@3 { +		src3: src-3 {  			interrupts = <0 355 IRQ_TYPE_LEVEL_HIGH>;  			dmas = <&audma0 0x8b>, <&audma1 0xa0>;  			dma-names = "rx", "tx";  		}; -		src4: src@4 { +		src4: src-4 {  			interrupts = <0 356 IRQ_TYPE_LEVEL_HIGH>;  			dmas = <&audma0 0x8d>, <&audma1 0xb0>;  			dma-names = "rx", "tx";  		}; -		src5: src@5 { +		src5: src-5 {  			interrupts = <0 357 IRQ_TYPE_LEVEL_HIGH>;  			dmas = <&audma0 0x8f>, <&audma1 0xb2>;  			dma-names = "rx", "tx";  		}; -		src6: src@6 { +		src6: src-6 {  			interrupts = <0 358 IRQ_TYPE_LEVEL_HIGH>;  			dmas = <&audma0 0x91>, <&audma1 0xb4>;  			dma-names = "rx", "tx";  		}; -		src7: src@7 { +		src7: src-7 {  			interrupts = <0 359 IRQ_TYPE_LEVEL_HIGH>;  			dmas = <&audma0 0x93>, <&audma1 0xb6>;  			dma-names = "rx", "tx";  		}; -		src8: src@8 { +		src8: src-8 {  			interrupts = <0 360 IRQ_TYPE_LEVEL_HIGH>;  			dmas = <&audma0 0x95>, <&audma1 0xb8>;  			dma-names = "rx", "tx";  		}; -		src9: src@9 { +		src9: src-9 {  			interrupts = <0 361 IRQ_TYPE_LEVEL_HIGH>;  			dmas = <&audma0 0x97>, <&audma1 0xba>;  			dma-names = "rx", "tx"; @@ -521,52 +521,52 @@ rcar_sound: sound@ec500000 {  	};  	rcar_sound,ssi { -		ssi0: ssi@0 { +		ssi0: ssi-0 {  			interrupts = <0 370 IRQ_TYPE_LEVEL_HIGH>;  			dmas = <&audma0 0x01>, <&audma1 0x02>, <&audma0 0x15>, <&audma1 0x16>;  			dma-names = "rx", "tx", "rxu", "txu";  		}; -		ssi1: ssi@1 { +		ssi1: ssi-1 {  			interrupts = <0 371 IRQ_TYPE_LEVEL_HIGH>;  			dmas = <&audma0 0x03>, <&audma1 0x04>, <&audma0 0x49>, <&audma1 0x4a>;  			dma-names = "rx", "tx", "rxu", "txu";  		}; -		ssi2: ssi@2 { +		ssi2: ssi-2 {  			interrupts = <0 372 IRQ_TYPE_LEVEL_HIGH>;  			dmas = <&audma0 0x05>, <&audma1 0x06>, <&audma0 0x63>, <&audma1 0x64>;  			dma-names = "rx", "tx", "rxu", "txu";  		}; -		ssi3: ssi@3 { +		ssi3: ssi-3 {  			interrupts = <0 373 IRQ_TYPE_LEVEL_HIGH>;  			dmas = <&audma0 0x07>, <&audma1 0x08>, <&audma0 0x6f>, <&audma1 0x70>;  			dma-names = "rx", "tx", "rxu", "txu";  		}; -		ssi4: ssi@4 { +		ssi4: ssi-4 {  			interrupts = <0 374 IRQ_TYPE_LEVEL_HIGH>;  			dmas = <&audma0 0x09>, <&audma1 0x0a>, <&audma0 0x71>, <&audma1 0x72>;  			dma-names = "rx", "tx", "rxu", "txu";  		}; -		ssi5: ssi@5 { +		ssi5: ssi-5 {  			interrupts = <0 375 IRQ_TYPE_LEVEL_HIGH>;  			dmas = <&audma0 0x0b>, <&audma1 0x0c>, <&audma0 0x73>, <&audma1 0x74>;  			dma-names = "rx", "tx", "rxu", "txu";  		}; -		ssi6: ssi@6 { +		ssi6: ssi-6 {  			interrupts = <0 376 IRQ_TYPE_LEVEL_HIGH>;  			dmas = <&audma0 0x0d>, <&audma1 0x0e>, <&audma0 0x75>, <&audma1 0x76>;  			dma-names = "rx", "tx", "rxu", "txu";  		}; -		ssi7: ssi@7 { +		ssi7: ssi-7 {  			interrupts = <0 377 IRQ_TYPE_LEVEL_HIGH>;  			dmas = <&audma0 0x0f>, <&audma1 0x10>, <&audma0 0x79>, <&audma1 0x7a>;  			dma-names = "rx", "tx", "rxu", "txu";  		}; -		ssi8: ssi@8 { +		ssi8: ssi-8 {  			interrupts = <0 378 IRQ_TYPE_LEVEL_HIGH>;  			dmas = <&audma0 0x11>, <&audma1 0x12>, <&audma0 0x7b>, <&audma1 0x7c>;  			dma-names = "rx", "tx", "rxu", "txu";  		}; -		ssi9: ssi@9 { +		ssi9: ssi-9 {  			interrupts = <0 379 IRQ_TYPE_LEVEL_HIGH>;  			dmas = <&audma0 0x13>, <&audma1 0x14>, <&audma0 0x7d>, <&audma1 0x7e>;  			dma-names = "rx", "tx", "rxu", "txu"; diff --git a/sound/soc/sh/dma-sh7760.c b/sound/soc/sh/dma-sh7760.c index 8fad4441c87d..1e7d417b53ef 100644 --- a/sound/soc/sh/dma-sh7760.c +++ b/sound/soc/sh/dma-sh7760.c @@ -89,7 +89,7 @@ struct camelot_pcm {  #define DMABRG_PREALLOC_BUFFER		32 * 1024  #define DMABRG_PREALLOC_BUFFER_MAX	32 * 1024 -static struct snd_pcm_hardware camelot_pcm_hardware = { +static const struct snd_pcm_hardware camelot_pcm_hardware = {  	.info = (SNDRV_PCM_INFO_MMAP |  		SNDRV_PCM_INFO_INTERLEAVED |  		SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -294,7 +294,7 @@ static snd_pcm_uframes_t camelot_pos(struct snd_pcm_substream *substream)  	return bytes_to_frames(runtime, pos);  } -static struct snd_pcm_ops camelot_pcm_ops = { +static const struct snd_pcm_ops camelot_pcm_ops = {  	.open		= camelot_pcm_open,  	.close		= camelot_pcm_close,  	.ioctl		= snd_pcm_lib_ioctl, @@ -320,7 +320,7 @@ static int camelot_pcm_new(struct snd_soc_pcm_runtime *rtd)  	return 0;  } -static struct snd_soc_platform_driver sh7760_soc_platform = { +static const struct snd_soc_platform_driver sh7760_soc_platform = {  	.ops		= &camelot_pcm_ops,  	.pcm_new	= camelot_pcm_new,  }; diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c index 7c4bdd82bb95..39ec772912d5 100644 --- a/sound/soc/sh/fsi.c +++ b/sound/soc/sh/fsi.c @@ -1710,7 +1710,7 @@ static const struct snd_soc_dai_ops fsi_dai_ops = {   *		pcm ops   */ -static struct snd_pcm_hardware fsi_pcm_hardware = { +static const struct snd_pcm_hardware fsi_pcm_hardware = {  	.info =		SNDRV_PCM_INFO_INTERLEAVED	|  			SNDRV_PCM_INFO_MMAP		|  			SNDRV_PCM_INFO_MMAP_VALID, @@ -1755,7 +1755,7 @@ static snd_pcm_uframes_t fsi_pointer(struct snd_pcm_substream *substream)  	return fsi_sample2frame(fsi, io->buff_sample_pos);  } -static struct snd_pcm_ops fsi_pcm_ops = { +static const struct snd_pcm_ops fsi_pcm_ops = {  	.open		= fsi_pcm_open,  	.ioctl		= snd_pcm_lib_ioctl,  	.hw_params	= fsi_hw_params, @@ -1818,7 +1818,7 @@ static struct snd_soc_dai_driver fsi_soc_dai[] = {  	},  }; -static struct snd_soc_platform_driver fsi_soc_platform = { +static const struct snd_soc_platform_driver fsi_soc_platform = {  	.ops		= &fsi_pcm_ops,  	.pcm_new	= fsi_pcm_new,  }; diff --git a/sound/soc/sh/migor.c b/sound/soc/sh/migor.c index 672bcd4c252b..ecb057ff9fbb 100644 --- a/sound/soc/sh/migor.c +++ b/sound/soc/sh/migor.c @@ -98,7 +98,7 @@ static int migor_hw_free(struct snd_pcm_substream *substream)  	return 0;  } -static struct snd_soc_ops migor_dai_ops = { +static const struct snd_soc_ops migor_dai_ops = {  	.hw_params = migor_hw_params,  	.hw_free = migor_hw_free,  }; diff --git a/sound/soc/sh/rcar/adg.c b/sound/soc/sh/rcar/adg.c index 5b5389e5b92b..938baff86ef2 100644 --- a/sound/soc/sh/rcar/adg.c +++ b/sound/soc/sh/rcar/adg.c @@ -586,10 +586,8 @@ int rsnd_adg_probe(struct rsnd_priv *priv)  	int ret;  	adg = devm_kzalloc(dev, sizeof(*adg), GFP_KERNEL); -	if (!adg) { -		dev_err(dev, "ADG allocate failed\n"); +	if (!adg)  		return -ENOMEM; -	}  	ret = rsnd_mod_init(priv, &adg->mod, &adg_ops,  		      NULL, NULL, 0, 0); diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 7fa40fcad59e..107133297e8d 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -843,12 +843,28 @@ static int rsnd_soc_hw_rule_channels(struct snd_pcm_hw_params *params,  				ir, &ic);  } -static void rsnd_soc_hw_constraint(struct snd_pcm_runtime *runtime, -				   struct snd_soc_dai *dai) +static const struct snd_pcm_hardware rsnd_pcm_hardware = { +	.info =		SNDRV_PCM_INFO_INTERLEAVED	| +			SNDRV_PCM_INFO_MMAP		| +			SNDRV_PCM_INFO_MMAP_VALID, +	.buffer_bytes_max	= 64 * 1024, +	.period_bytes_min	= 32, +	.period_bytes_max	= 8192, +	.periods_min		= 1, +	.periods_max		= 32, +	.fifo_size		= 256, +}; + +static int rsnd_soc_dai_startup(struct snd_pcm_substream *substream, +				struct snd_soc_dai *dai)  {  	struct rsnd_dai *rdai = rsnd_dai_to_rdai(dai); +	struct rsnd_priv *priv = rsnd_rdai_to_priv(rdai); +	struct rsnd_dai_stream *io = rsnd_rdai_to_io(rdai, substream);  	struct snd_pcm_hw_constraint_list *constraint = &rdai->constraint; +	struct snd_pcm_runtime *runtime = substream->runtime;  	unsigned int max_channels = rsnd_rdai_channels_get(rdai); +	int ret;  	int i;  	/* @@ -865,34 +881,26 @@ static void rsnd_soc_hw_constraint(struct snd_pcm_runtime *runtime,  		constraint->count = i + 1;  	} +	snd_soc_set_runtime_hwparams(substream, &rsnd_pcm_hardware); +  	snd_pcm_hw_constraint_list(runtime, 0,  				   SNDRV_PCM_HW_PARAM_CHANNELS, constraint); +	snd_pcm_hw_constraint_integer(runtime, +				      SNDRV_PCM_HW_PARAM_PERIODS); +  	/*  	 * Sampling Rate / Channel Limitation  	 * It depends on Clock Master Mode  	 */ -	if (!rsnd_rdai_is_clk_master(rdai)) -		return; - -	snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, -			    rsnd_soc_hw_rule_rate, dai, -			    SNDRV_PCM_HW_PARAM_CHANNELS, -1); -	snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, -			    rsnd_soc_hw_rule_channels, dai, -			    SNDRV_PCM_HW_PARAM_RATE, -1); -} - -static int rsnd_soc_dai_startup(struct snd_pcm_substream *substream, -				struct snd_soc_dai *dai) -{ -	struct rsnd_dai *rdai = rsnd_dai_to_rdai(dai); -	struct rsnd_priv *priv = rsnd_rdai_to_priv(rdai); -	struct rsnd_dai_stream *io = rsnd_rdai_to_io(rdai, substream); -	int ret; - -	/* rsnd_io_to_runtime() is not yet enabled here */ -	rsnd_soc_hw_constraint(substream->runtime, dai); +	if (rsnd_rdai_is_clk_master(rdai)) { +		snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, +				    rsnd_soc_hw_rule_rate, dai, +				    SNDRV_PCM_HW_PARAM_CHANNELS, -1); +		snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, +				    rsnd_soc_hw_rule_channels, dai, +				    SNDRV_PCM_HW_PARAM_RATE, -1); +	}  	/*  	 * call rsnd_dai_call without spinlock @@ -1104,31 +1112,6 @@ static int rsnd_dai_probe(struct rsnd_priv *priv)  /*   *		pcm ops   */ -static struct snd_pcm_hardware rsnd_pcm_hardware = { -	.info =		SNDRV_PCM_INFO_INTERLEAVED	| -			SNDRV_PCM_INFO_MMAP		| -			SNDRV_PCM_INFO_MMAP_VALID, -	.buffer_bytes_max	= 64 * 1024, -	.period_bytes_min	= 32, -	.period_bytes_max	= 8192, -	.periods_min		= 1, -	.periods_max		= 32, -	.fifo_size		= 256, -}; - -static int rsnd_pcm_open(struct snd_pcm_substream *substream) -{ -	struct snd_pcm_runtime *runtime = substream->runtime; -	int ret = 0; - -	snd_soc_set_runtime_hwparams(substream, &rsnd_pcm_hardware); - -	ret = snd_pcm_hw_constraint_integer(runtime, -					    SNDRV_PCM_HW_PARAM_PERIODS); - -	return ret; -} -  static int rsnd_hw_params(struct snd_pcm_substream *substream,  			 struct snd_pcm_hw_params *hw_params)  { @@ -1157,8 +1140,7 @@ static snd_pcm_uframes_t rsnd_pointer(struct snd_pcm_substream *substream)  	return pointer;  } -static struct snd_pcm_ops rsnd_pcm_ops = { -	.open		= rsnd_pcm_open, +static const struct snd_pcm_ops rsnd_pcm_ops = {  	.ioctl		= snd_pcm_lib_ioctl,  	.hw_params	= rsnd_hw_params,  	.hw_free	= snd_pcm_lib_free_pages, @@ -1168,11 +1150,10 @@ static struct snd_pcm_ops rsnd_pcm_ops = {  /*   *		snd_kcontrol   */ -#define kcontrol_to_cfg(kctrl) ((struct rsnd_kctrl_cfg *)kctrl->private_value)  static int rsnd_kctrl_info(struct snd_kcontrol *kctrl,  			   struct snd_ctl_elem_info *uinfo)  { -	struct rsnd_kctrl_cfg *cfg = kcontrol_to_cfg(kctrl); +	struct rsnd_kctrl_cfg *cfg = snd_kcontrol_chip(kctrl);  	if (cfg->texts) {  		uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; @@ -1198,7 +1179,7 @@ static int rsnd_kctrl_info(struct snd_kcontrol *kctrl,  static int rsnd_kctrl_get(struct snd_kcontrol *kctrl,  			  struct snd_ctl_elem_value *uc)  { -	struct rsnd_kctrl_cfg *cfg = kcontrol_to_cfg(kctrl); +	struct rsnd_kctrl_cfg *cfg = snd_kcontrol_chip(kctrl);  	int i;  	for (i = 0; i < cfg->size; i++) @@ -1213,8 +1194,7 @@ static int rsnd_kctrl_get(struct snd_kcontrol *kctrl,  static int rsnd_kctrl_put(struct snd_kcontrol *kctrl,  			  struct snd_ctl_elem_value *uc)  { -	struct rsnd_mod *mod = snd_kcontrol_chip(kctrl); -	struct rsnd_kctrl_cfg *cfg = kcontrol_to_cfg(kctrl); +	struct rsnd_kctrl_cfg *cfg = snd_kcontrol_chip(kctrl);  	int i, change = 0;  	if (!cfg->accept(cfg->io)) @@ -1231,7 +1211,7 @@ static int rsnd_kctrl_put(struct snd_kcontrol *kctrl,  	}  	if (change && cfg->update) -		cfg->update(cfg->io, mod); +		cfg->update(cfg->io, cfg->mod);  	return change;  } @@ -1283,14 +1263,13 @@ int rsnd_kctrl_new(struct rsnd_mod *mod,  		.index		= rtd->num,  		.get		= rsnd_kctrl_get,  		.put		= rsnd_kctrl_put, -		.private_value	= (unsigned long)cfg,  	};  	int ret;  	if (size > RSND_MAX_CHANNELS)  		return -EINVAL; -	kctrl = snd_ctl_new1(&knew, mod); +	kctrl = snd_ctl_new1(&knew, cfg);  	if (!kctrl)  		return -ENOMEM; @@ -1306,6 +1285,7 @@ int rsnd_kctrl_new(struct rsnd_mod *mod,  	cfg->card	= card;  	cfg->kctrl	= kctrl;  	cfg->io		= io; +	cfg->mod	= mod;  	return 0;  } @@ -1338,7 +1318,7 @@ static int rsnd_pcm_new(struct snd_soc_pcm_runtime *rtd)  		PREALLOC_BUFFER, PREALLOC_BUFFER_MAX);  } -static struct snd_soc_platform_driver rsnd_soc_platform = { +static const struct snd_soc_platform_driver rsnd_soc_platform = {  	.ops		= &rsnd_pcm_ops,  	.pcm_new	= rsnd_pcm_new,  }; @@ -1421,10 +1401,8 @@ static int rsnd_probe(struct platform_device *pdev)  	 *	init priv data  	 */  	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); -	if (!priv) { -		dev_err(dev, "priv allocate failed\n"); +	if (!priv)  		return -ENODEV; -	}  	priv->pdev	= pdev;  	priv->flags	= (unsigned long)of_device_get_match_data(dev); diff --git a/sound/soc/sh/rcar/ctu.c b/sound/soc/sh/rcar/ctu.c index 4ba8f2fe7a4c..e7f53f44165d 100644 --- a/sound/soc/sh/rcar/ctu.c +++ b/sound/soc/sh/rcar/ctu.c @@ -394,13 +394,16 @@ int rsnd_ctu_probe(struct rsnd_priv *priv)  		clk = devm_clk_get(dev, name);  		if (IS_ERR(clk)) {  			ret = PTR_ERR(clk); +			of_node_put(np);  			goto rsnd_ctu_probe_done;  		}  		ret = rsnd_mod_init(priv, rsnd_mod_get(ctu), &rsnd_ctu_ops,  				    clk, rsnd_mod_get_status, RSND_MOD_CTU, i); -		if (ret) +		if (ret) { +			of_node_put(np);  			goto rsnd_ctu_probe_done; +		}  		i++;  	} diff --git a/sound/soc/sh/rcar/dma.c b/sound/soc/sh/rcar/dma.c index 60aa5e96a49f..041ec1080d52 100644 --- a/sound/soc/sh/rcar/dma.c +++ b/sound/soc/sh/rcar/dma.c @@ -604,8 +604,8 @@ rsnd_gen2_dma_addr(struct rsnd_dai_stream *io,  		dma_addr_t in_addr;  	} dma_addrs[3][2][3] = {  		/* SRC */ +		/* Capture */  		{{{ 0,				0 }, -		  /* Capture */  		  { RDMA_SRC_O_N(src, id),	RDMA_SRC_I_P(src, id) },  		  { RDMA_CMD_O_N(src, id),	RDMA_SRC_I_P(src, id) } },  		 /* Playback */ diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c index 99d2d9459e75..1743ade3cc55 100644 --- a/sound/soc/sh/rcar/dvc.c +++ b/sound/soc/sh/rcar/dvc.c @@ -380,13 +380,16 @@ int rsnd_dvc_probe(struct rsnd_priv *priv)  		clk = devm_clk_get(dev, name);  		if (IS_ERR(clk)) {  			ret = PTR_ERR(clk); +			of_node_put(np);  			goto rsnd_dvc_probe_done;  		}  		ret = rsnd_mod_init(priv, rsnd_mod_get(dvc), &rsnd_dvc_ops,  				    clk, rsnd_mod_get_status, RSND_MOD_DVC, i); -		if (ret) +		if (ret) { +			of_node_put(np);  			goto rsnd_dvc_probe_done; +		}  		i++;  	} diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c index ee00e3516911..f04c4100043a 100644 --- a/sound/soc/sh/rcar/gen.c +++ b/sound/soc/sh/rcar/gen.c @@ -406,10 +406,8 @@ int rsnd_gen_probe(struct rsnd_priv *priv)  	int ret;  	gen = devm_kzalloc(dev, sizeof(*gen), GFP_KERNEL); -	if (!gen) { -		dev_err(dev, "GEN allocate failed\n"); +	if (!gen)  		return -ENOMEM; -	}  	priv->gen = gen; diff --git a/sound/soc/sh/rcar/mix.c b/sound/soc/sh/rcar/mix.c index 195fc7bb22af..6c4826c189a4 100644 --- a/sound/soc/sh/rcar/mix.c +++ b/sound/soc/sh/rcar/mix.c @@ -168,13 +168,16 @@ int rsnd_mix_probe(struct rsnd_priv *priv)  		clk = devm_clk_get(dev, name);  		if (IS_ERR(clk)) {  			ret = PTR_ERR(clk); +			of_node_put(np);  			goto rsnd_mix_probe_done;  		}  		ret = rsnd_mod_init(priv, rsnd_mod_get(mix), &rsnd_mix_ops,  				    clk, rsnd_mod_get_status, RSND_MOD_MIX, i); -		if (ret) +		if (ret) { +			of_node_put(np);  			goto rsnd_mix_probe_done; +		}  		i++;  	} diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index 99c57611df88..c5de71f2dc8c 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -614,6 +614,7 @@ struct rsnd_kctrl_cfg {  	struct rsnd_dai_stream *io;  	struct snd_card *card;  	struct snd_kcontrol *kctrl; +	struct rsnd_mod *mod;  };  #define RSND_MAX_CHANNELS	8 diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c index 7aa239e28491..510b68a483b4 100644 --- a/sound/soc/sh/rcar/src.c +++ b/sound/soc/sh/rcar/src.c @@ -27,7 +27,6 @@ struct rsnd_src {  #define RSND_SRC_NAME_SIZE 16  #define rsnd_src_get(priv, id) ((struct rsnd_src *)(priv->src) + id) -#define rsnd_src_to_dma(src) ((src)->dma)  #define rsnd_src_nr(priv) ((priv)->src_nr)  #define rsnd_src_sync_is_enabled(mod) (rsnd_mod_to_src(mod)->sen.val) @@ -108,7 +107,6 @@ unsigned int rsnd_src_get_rate(struct rsnd_priv *priv,  	int is_play = rsnd_io_is_play(io);  	/* -	 *  	 * Playback  	 * runtime_rate -> [SRC] -> convert_rate  	 * @@ -203,13 +201,13 @@ static void rsnd_src_set_convert_rate(struct rsnd_dai_stream *io,  	use_src = (fin != fout) | rsnd_src_sync_is_enabled(mod);  	/* -	 *	SRC_ADINR +	 * SRC_ADINR  	 */  	adinr = rsnd_get_adinr_bit(mod, io) |  		rsnd_runtime_channel_original(io);  	/* -	 *	SRC_IFSCR / SRC_IFSVR +	 * SRC_IFSCR / SRC_IFSVR  	 */  	ifscr = 0;  	fsrate = 0; @@ -223,7 +221,7 @@ static void rsnd_src_set_convert_rate(struct rsnd_dai_stream *io,  	}  	/* -	 *	SRC_SRCCR / SRC_ROUTE_MODE0 +	 * SRC_SRCCR / SRC_ROUTE_MODE0  	 */  	cr	= 0x00011110;  	route	= 0x0; @@ -581,20 +579,24 @@ int rsnd_src_probe(struct rsnd_priv *priv)  		src->irq = irq_of_parse_and_map(np, 0);  		if (!src->irq) {  			ret = -EINVAL; +			of_node_put(np);  			goto rsnd_src_probe_done;  		}  		clk = devm_clk_get(dev, name);  		if (IS_ERR(clk)) {  			ret = PTR_ERR(clk); +			of_node_put(np);  			goto rsnd_src_probe_done;  		}  		ret = rsnd_mod_init(priv, rsnd_mod_get(src),  				    &rsnd_src_ops, clk, rsnd_mod_get_status,  				    RSND_MOD_SRC, i); -		if (ret) +		if (ret) { +			of_node_put(np);  			goto rsnd_src_probe_done; +		}  skip:  		i++; diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index 90cc9c13c4e0..fffc07e72627 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c @@ -90,6 +90,7 @@ struct rsnd_ssi {  #define RSND_SSI_NO_BUSIF		(1 << 1) /* SSI+DMA without BUSIF */  #define RSND_SSI_HDMI0			(1 << 2) /* for HDMI0 */  #define RSND_SSI_HDMI1			(1 << 3) /* for HDMI1 */ +#define RSND_SSI_PROBED			(1 << 4)  #define for_each_rsnd_ssi(pos, priv, i)					\  	for (i = 0;							\ @@ -98,25 +99,27 @@ struct rsnd_ssi {  	     i++)  #define rsnd_ssi_get(priv, id) ((struct rsnd_ssi *)(priv->ssi) + id) -#define rsnd_ssi_to_dma(mod) ((ssi)->dma)  #define rsnd_ssi_nr(priv) ((priv)->ssi_nr)  #define rsnd_mod_to_ssi(_mod) container_of((_mod), struct rsnd_ssi, mod) -#define rsnd_ssi_mode_flags(p) ((p)->flags) +#define rsnd_ssi_flags_has(p, f) ((p)->flags & f) +#define rsnd_ssi_flags_set(p, f) ((p)->flags |= f) +#define rsnd_ssi_flags_del(p, f) ((p)->flags = ((p)->flags & ~f))  #define rsnd_ssi_is_parent(ssi, io) ((ssi) == rsnd_io_to_mod_ssip(io))  #define rsnd_ssi_is_multi_slave(mod, io) \  	(rsnd_ssi_multi_slaves(io) & (1 << rsnd_mod_id(mod)))  #define rsnd_ssi_is_run_mods(mod, io) \  	(rsnd_ssi_run_mods(io) & (1 << rsnd_mod_id(mod))) +#define rsnd_ssi_can_output_clk(mod) (!__rsnd_ssi_is_pin_sharing(mod))  int rsnd_ssi_hdmi_port(struct rsnd_dai_stream *io)  {  	struct rsnd_mod *mod = rsnd_io_to_mod_ssi(io);  	struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); -	if (rsnd_ssi_mode_flags(ssi) & RSND_SSI_HDMI0) +	if (rsnd_ssi_flags_has(ssi, RSND_SSI_HDMI0))  		return RSND_SSI_HDMI_PORT0; -	if (rsnd_ssi_mode_flags(ssi) & RSND_SSI_HDMI1) +	if (rsnd_ssi_flags_has(ssi, RSND_SSI_HDMI1))  		return RSND_SSI_HDMI_PORT1;  	return 0; @@ -131,7 +134,7 @@ int rsnd_ssi_use_busif(struct rsnd_dai_stream *io)  	if (!rsnd_ssi_is_dma_mode(mod))  		return 0; -	if (!(rsnd_ssi_mode_flags(ssi) & RSND_SSI_NO_BUSIF)) +	if (!(rsnd_ssi_flags_has(ssi, RSND_SSI_NO_BUSIF)))  		use_busif = 1;  	if (rsnd_io_to_mod_src(io))  		use_busif = 1; @@ -256,7 +259,6 @@ static int rsnd_ssi_master_clk_start(struct rsnd_mod *mod,  	struct device *dev = rsnd_priv_to_dev(priv);  	struct rsnd_dai *rdai = rsnd_io_to_rdai(io);  	struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); -	struct rsnd_mod *ssi_parent_mod = rsnd_io_to_mod_ssip(io);  	int chan = rsnd_runtime_channel_for_ssi(io);  	int idx, ret;  	unsigned int main_rate; @@ -267,7 +269,7 @@ static int rsnd_ssi_master_clk_start(struct rsnd_mod *mod,  	if (!rsnd_rdai_is_clk_master(rdai))  		return 0; -	if (ssi_parent_mod && !rsnd_ssi_is_parent(mod, io)) +	if (!rsnd_ssi_can_output_clk(mod))  		return 0;  	if (rsnd_ssi_is_multi_slave(mod, io)) @@ -318,12 +320,11 @@ static void rsnd_ssi_master_clk_stop(struct rsnd_mod *mod,  {  	struct rsnd_dai *rdai = rsnd_io_to_rdai(io);  	struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); -	struct rsnd_mod *ssi_parent_mod = rsnd_io_to_mod_ssip(io);  	if (!rsnd_rdai_is_clk_master(rdai))  		return; -	if (ssi_parent_mod && !rsnd_ssi_is_parent(mod, io)) +	if (!rsnd_ssi_can_output_clk(mod))  		return;  	if (ssi->usrcnt > 1) @@ -346,6 +347,9 @@ static void rsnd_ssi_config_init(struct rsnd_mod *mod,  	u32 wsr;  	int is_tdm; +	if (rsnd_ssi_is_parent(mod, io)) +		return; +  	is_tdm = rsnd_runtime_is_ssi_tdm(io);  	/* @@ -484,8 +488,7 @@ static int rsnd_ssi_init(struct rsnd_mod *mod,  	if (ret < 0)  		return ret; -	if (!rsnd_ssi_is_parent(mod, io)) -		rsnd_ssi_config_init(mod, io); +	rsnd_ssi_config_init(mod, io);  	rsnd_ssi_register_setup(mod); @@ -782,15 +785,47 @@ static int rsnd_ssi_common_probe(struct rsnd_mod *mod,  	/*  	 * SSI might be called again as PIO fallback  	 * It is easy to manual handling for IRQ request/free +	 * +	 * OTOH, this function might be called many times if platform is +	 * using MIX. It needs xxx_attach() many times on xxx_probe(). +	 * Because of it, we can't control .probe/.remove calling count by +	 * mod->status. +	 * But it don't need to call request_irq() many times. +	 * Let's control it by RSND_SSI_PROBED flag.  	 */ -	ret = request_irq(ssi->irq, -			  rsnd_ssi_interrupt, -			  IRQF_SHARED, -			  dev_name(dev), mod); +	if (!rsnd_ssi_flags_has(ssi, RSND_SSI_PROBED)) { +		ret = request_irq(ssi->irq, +				  rsnd_ssi_interrupt, +				  IRQF_SHARED, +				  dev_name(dev), mod); + +		rsnd_ssi_flags_set(ssi, RSND_SSI_PROBED); +	}  	return ret;  } +static int rsnd_ssi_common_remove(struct rsnd_mod *mod, +				  struct rsnd_dai_stream *io, +				  struct rsnd_priv *priv) +{ +	struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); +	struct rsnd_mod *pure_ssi_mod = rsnd_io_to_mod_ssi(io); + +	/* Do nothing if non SSI (= SSI parent, multi SSI) mod */ +	if (pure_ssi_mod != mod) +		return 0; + +	/* PIO will request IRQ again */ +	if (rsnd_ssi_flags_has(ssi, RSND_SSI_PROBED)) { +		free_irq(ssi->irq, mod); + +		rsnd_ssi_flags_del(ssi, RSND_SSI_PROBED); +	} + +	return 0; +} +  static int rsnd_ssi_pointer(struct rsnd_mod *mod,  			    struct rsnd_dai_stream *io,  			    snd_pcm_uframes_t *pointer) @@ -806,6 +841,7 @@ static int rsnd_ssi_pointer(struct rsnd_mod *mod,  static struct rsnd_mod_ops rsnd_ssi_pio_ops = {  	.name	= SSI_NAME,  	.probe	= rsnd_ssi_common_probe, +	.remove	= rsnd_ssi_common_remove,  	.init	= rsnd_ssi_init,  	.quit	= rsnd_ssi_quit,  	.start	= rsnd_ssi_start, @@ -840,23 +876,6 @@ static int rsnd_ssi_dma_probe(struct rsnd_mod *mod,  	return ret;  } -static int rsnd_ssi_dma_remove(struct rsnd_mod *mod, -			       struct rsnd_dai_stream *io, -			       struct rsnd_priv *priv) -{ -	struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); -	struct rsnd_mod *pure_ssi_mod = rsnd_io_to_mod_ssi(io); - -	/* Do nothing if non SSI (= SSI parent, multi SSI) mod */ -	if (pure_ssi_mod != mod) -		return 0; - -	/* PIO will request IRQ again */ -	free_irq(ssi->irq, mod); - -	return 0; -} -  static int rsnd_ssi_fallback(struct rsnd_mod *mod,  			     struct rsnd_dai_stream *io,  			     struct rsnd_priv *priv) @@ -898,7 +917,7 @@ static struct rsnd_mod_ops rsnd_ssi_dma_ops = {  	.name	= SSI_NAME,  	.dma_req = rsnd_ssi_dma_req,  	.probe	= rsnd_ssi_dma_probe, -	.remove	= rsnd_ssi_dma_remove, +	.remove	= rsnd_ssi_common_remove,  	.init	= rsnd_ssi_init,  	.quit	= rsnd_ssi_quit,  	.start	= rsnd_ssi_start, @@ -984,13 +1003,13 @@ static void __rsnd_ssi_parse_hdmi_connection(struct rsnd_priv *priv,  	ssi  = rsnd_mod_to_ssi(mod);  	if (strstr(remote_ep->full_name, "hdmi0")) { -		ssi->flags |= RSND_SSI_HDMI0; +		rsnd_ssi_flags_set(ssi, RSND_SSI_HDMI0);  		dev_dbg(dev, "%s[%d] connected to HDMI0\n",  			 rsnd_mod_name(mod), rsnd_mod_id(mod));  	}  	if (strstr(remote_ep->full_name, "hdmi1")) { -		ssi->flags |= RSND_SSI_HDMI1; +		rsnd_ssi_flags_set(ssi, RSND_SSI_HDMI1);  		dev_dbg(dev, "%s[%d] connected to HDMI1\n",  			rsnd_mod_name(mod), rsnd_mod_id(mod));  	} @@ -1023,7 +1042,7 @@ int __rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod)  {  	struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); -	return !!(rsnd_ssi_mode_flags(ssi) & RSND_SSI_CLK_PIN_SHARE); +	return !!(rsnd_ssi_flags_has(ssi, RSND_SSI_CLK_PIN_SHARE));  }  static u32 *rsnd_ssi_get_status(struct rsnd_dai_stream *io, @@ -1101,18 +1120,20 @@ int rsnd_ssi_probe(struct rsnd_priv *priv)  		clk = devm_clk_get(dev, name);  		if (IS_ERR(clk)) {  			ret = PTR_ERR(clk); +			of_node_put(np);  			goto rsnd_ssi_probe_done;  		}  		if (of_get_property(np, "shared-pin", NULL)) -			ssi->flags |= RSND_SSI_CLK_PIN_SHARE; +			rsnd_ssi_flags_set(ssi, RSND_SSI_CLK_PIN_SHARE);  		if (of_get_property(np, "no-busif", NULL)) -			ssi->flags |= RSND_SSI_NO_BUSIF; +			rsnd_ssi_flags_set(ssi, RSND_SSI_NO_BUSIF);  		ssi->irq = irq_of_parse_and_map(np, 0);  		if (!ssi->irq) {  			ret = -EINVAL; +			of_node_put(np);  			goto rsnd_ssi_probe_done;  		} @@ -1123,8 +1144,10 @@ int rsnd_ssi_probe(struct rsnd_priv *priv)  		ret = rsnd_mod_init(priv, rsnd_mod_get(ssi), ops, clk,  				    rsnd_ssi_get_status, RSND_MOD_SSI, i); -		if (ret) +		if (ret) { +			of_node_put(np);  			goto rsnd_ssi_probe_done; +		}  		i++;  	} diff --git a/sound/soc/sh/rcar/ssiu.c b/sound/soc/sh/rcar/ssiu.c index bed2c9c0004b..4d948757d300 100644 --- a/sound/soc/sh/rcar/ssiu.c +++ b/sound/soc/sh/rcar/ssiu.c @@ -250,7 +250,7 @@ int rsnd_ssiu_probe(struct rsnd_priv *priv)  {  	struct device *dev = rsnd_priv_to_dev(priv);  	struct rsnd_ssiu *ssiu; -	static struct rsnd_mod_ops *ops; +	struct rsnd_mod_ops *ops;  	int i, nr, ret;  	/* same number to SSI */ diff --git a/sound/soc/sh/siu_dai.c b/sound/soc/sh/siu_dai.c index 4a22aadac294..160502947da2 100644 --- a/sound/soc/sh/siu_dai.c +++ b/sound/soc/sh/siu_dai.c @@ -333,7 +333,7 @@ static void siu_dai_spbstop(struct siu_port *port_info)  /*		API functions		*/  /* Playback and capture hardware properties are identical */ -static struct snd_pcm_hardware siu_dai_pcm_hw = { +static const struct snd_pcm_hardware siu_dai_pcm_hw = {  	.info			= SNDRV_PCM_INFO_INTERLEAVED,  	.formats		= SNDRV_PCM_FMTBIT_S16,  	.rates			= SNDRV_PCM_RATE_8000_48000, diff --git a/sound/soc/sh/siu_pcm.c b/sound/soc/sh/siu_pcm.c index 82902f56e82f..3118cb0ee3f2 100644 --- a/sound/soc/sh/siu_pcm.c +++ b/sound/soc/sh/siu_pcm.c @@ -593,7 +593,7 @@ static void siu_pcm_free(struct snd_pcm *pcm)  	dev_dbg(pcm->card->dev, "%s\n", __func__);  } -static struct snd_pcm_ops siu_pcm_ops = { +static const struct snd_pcm_ops siu_pcm_ops = {  	.open		= siu_pcm_open,  	.close		= siu_pcm_close,  	.ioctl		= snd_pcm_lib_ioctl,  | 
