All of lore.kernel.org
 help / color / mirror / Atom feed
From: Hans de Goede <hdegoede@redhat.com>
To: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>,
	alsa-devel@alsa-project.org
Cc: tiwai@suse.de, Heikki Krogerus <heikki.krogerus@linux.intel.com>,
	broonie@kernel.org,
	Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Subject: Re: [PATCH 2/2] ASoC: Intel: boards: use software node API in Atom boards
Date: Tue, 8 Jun 2021 10:18:08 +0200	[thread overview]
Message-ID: <0e8e01f6-d249-cc3e-2020-f6e5c81a4732@redhat.com> (raw)
In-Reply-To: <20210607223503.584379-3-pierre-louis.bossart@linux.intel.com>

Hi,

On 6/8/21 12:35 AM, Pierre-Louis Bossart wrote:
> From: Heikki Krogerus <heikki.krogerus@linux.intel.com>
> 
> The function device_add_properties() is going to be removed.
> Replacing it with software node API equivalents.
> 
> Co-developed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
> ---
>  sound/soc/intel/boards/bytcht_es8316.c | 25 ++++++++++++--
>  sound/soc/intel/boards/bytcr_rt5640.c  | 42 +++++++++++++++++++----
>  sound/soc/intel/boards/bytcr_rt5651.c  | 47 +++++++++++++++++++++-----
>  3 files changed, 97 insertions(+), 17 deletions(-)
> 
> diff --git a/sound/soc/intel/boards/bytcht_es8316.c b/sound/soc/intel/boards/bytcht_es8316.c
> index a0af91580184..ef8ed3ff53af 100644
> --- a/sound/soc/intel/boards/bytcht_es8316.c
> +++ b/sound/soc/intel/boards/bytcht_es8316.c
> @@ -38,6 +38,7 @@ struct byt_cht_es8316_private {
>  	struct snd_soc_jack jack;
>  	struct gpio_desc *speaker_en_gpio;
>  	bool speaker_en;
> +	struct device *codec_dev;
>  };
>  
>  enum {
> @@ -461,6 +462,7 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
>  	const struct dmi_system_id *dmi_id;
>  	struct device *dev = &pdev->dev;
>  	struct snd_soc_acpi_mach *mach;
> +	struct fwnode_handle *fwnode;
>  	const char *platform_name;
>  	struct acpi_device *adev;
>  	struct device *codec_dev;
> @@ -543,7 +545,16 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
>  		props[cnt++] = PROPERTY_ENTRY_BOOL("everest,jack-detect-inverted");
>  
>  	if (cnt) {
> -		ret = device_add_properties(codec_dev, props);
> +		fwnode = fwnode_create_software_node(props, NULL);
> +		if (IS_ERR(fwnode)) {
> +			put_device(codec_dev);
> +			return PTR_ERR(fwnode);
> +		}
> +
> +		ret = device_add_software_node(codec_dev, to_software_node(fwnode));
> +
> +		fwnode_handle_put(fwnode);
> +
>  		if (ret) {
>  			put_device(codec_dev);
>  			return ret;
> @@ -556,6 +567,7 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
>  				/* see comment in byt_cht_es8316_resume */
>  				GPIOD_OUT_LOW | GPIOD_FLAGS_BIT_NONEXCLUSIVE);
>  	put_device(codec_dev);
> +	priv->codec_dev = codec_dev;
>  
>  	if (IS_ERR(priv->speaker_en_gpio)) {
>  		ret = PTR_ERR(priv->speaker_en_gpio);
> @@ -567,7 +579,7 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
>  			dev_err(dev, "get speaker GPIO failed: %d\n", ret);
>  			fallthrough;
>  		case -EPROBE_DEFER:
> -			return ret;
> +			goto err;
>  		}
>  	}
>  
> @@ -605,10 +617,15 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
>  	if (ret) {
>  		gpiod_put(priv->speaker_en_gpio);
>  		dev_err(dev, "snd_soc_register_card failed: %d\n", ret);
> -		return ret;
> +		goto err;
>  	}
>  	platform_set_drvdata(pdev, &byt_cht_es8316_card);
>  	return 0;
> +
> +err:
> +	device_remove_software_node(priv->codec_dev);
> +
> +	return ret;
>  }
>  
>  static int snd_byt_cht_es8316_mc_remove(struct platform_device *pdev)
> @@ -617,6 +634,8 @@ static int snd_byt_cht_es8316_mc_remove(struct platform_device *pdev)
>  	struct byt_cht_es8316_private *priv = snd_soc_card_get_drvdata(card);
>  
>  	gpiod_put(priv->speaker_en_gpio);
> +	device_remove_software_node(priv->codec_dev);

This is a problem, nothing guarantees codec_dev not going away before
snd_byt_cht_es8316_mc_remove() runs. Although the only thing which I can come up
with where this happens is unbinding the i2c-controller driver I still would like
us to take this scenario into account.

I think it would be better to use device_create_managed_software_node() to tie
the lifetime of the swnode to the lifetime of the device, this also removes
the need for all the goto err cases (and introducing a remove function in
the bytcr_rt5640.c case).

This does mean that we could end up calling device_create_managed_software_node()
on the same device twice, when the machine driver gets unbound + rebound, but
that is an already existing issue with our current device_add_properties() usage.

We could fix this (in a separate commit since it is an already existing issue)
by adding a PROPERTY_ENTRY_BOOL("cht_es8316,swnode-created") property to the
properties and checking for that being set with
device_property_read_bool(codec, "cht_es8316,swnode-created")

Or we could move the device_put(codec_dev) to snd_byt_cht_es8316_mc_remove().

I've a slight preference for using device_create_managed_software_node() +
some mechanism to avoid a double adding of the properties, since I would like
to try and avoid the "goto err" additions.

Ideally device_create_managed_software_node() would detect the double-add
itself and it would return -EEXISTS. Heikki, would that be feasible ?

Regards,

Hans





> +
>  	return 0;
>  }
>  
> diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c
> index 91a6d712eb58..b3597b0f6836 100644
> --- a/sound/soc/intel/boards/bytcr_rt5640.c
> +++ b/sound/soc/intel/boards/bytcr_rt5640.c
> @@ -87,6 +87,7 @@ enum {
>  struct byt_rt5640_private {
>  	struct snd_soc_jack jack;
>  	struct clk *mclk;
> +	struct device *codec_dev;
>  };
>  static bool is_bytcr;
>  
> @@ -912,9 +913,11 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
>   * Note this MUST be called before snd_soc_register_card(), so that the props
>   * are in place before the codec component driver's probe function parses them.
>   */
> -static int byt_rt5640_add_codec_device_props(const char *i2c_dev_name)
> +static int byt_rt5640_add_codec_device_props(const char *i2c_dev_name,
> +					     struct byt_rt5640_private *priv)
>  {
>  	struct property_entry props[MAX_NO_PROPS] = {};
> +	struct fwnode_handle *fwnode;
>  	struct device *i2c_dev;
>  	int ret, cnt = 0;
>  
> @@ -960,7 +963,18 @@ static int byt_rt5640_add_codec_device_props(const char *i2c_dev_name)
>  	if (byt_rt5640_quirk & BYT_RT5640_JD_NOT_INV)
>  		props[cnt++] = PROPERTY_ENTRY_BOOL("realtek,jack-detect-not-inverted");
>  
> -	ret = device_add_properties(i2c_dev, props);
> +	fwnode = fwnode_create_software_node(props, NULL);
> +	if (IS_ERR(fwnode)) {
> +		/* put_device() is not handled in caller */
> +		put_device(i2c_dev);
> +		return PTR_ERR(fwnode);
> +	}
> +
> +	ret = device_add_software_node(i2c_dev, to_software_node(fwnode));
> +
> +	fwnode_handle_put(fwnode);
> +	priv->codec_dev = i2c_dev;
> +
>  	put_device(i2c_dev);
>  
>  	return ret;
> @@ -1401,7 +1415,7 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
>  	}
>  
>  	/* Must be called before register_card, also see declaration comment. */
> -	ret_val = byt_rt5640_add_codec_device_props(byt_rt5640_codec_name);
> +	ret_val = byt_rt5640_add_codec_device_props(byt_rt5640_codec_name, priv);
>  	if (ret_val)
>  		return ret_val;
>  
> @@ -1434,7 +1448,7 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
>  			 * for all other errors, including -EPROBE_DEFER
>  			 */
>  			if (ret_val != -ENOENT)
> -				return ret_val;
> +				goto err;
>  			byt_rt5640_quirk &= ~BYT_RT5640_MCLK_EN;
>  		}
>  	}
> @@ -1467,7 +1481,7 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
>  	ret_val = snd_soc_fixup_dai_links_platform_name(&byt_rt5640_card,
>  							platform_name);
>  	if (ret_val)
> -		return ret_val;
> +		goto err;
>  
>  	sof_parent = snd_soc_acpi_sof_parent(&pdev->dev);
>  
> @@ -1489,10 +1503,25 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
>  	if (ret_val) {
>  		dev_err(&pdev->dev, "devm_snd_soc_register_card failed %d\n",
>  			ret_val);
> -		return ret_val;
> +		goto err;
>  	}
>  	platform_set_drvdata(pdev, &byt_rt5640_card);
>  	return ret_val;
> +
> +err:
> +	device_remove_software_node(priv->codec_dev);
> +
> +	return ret_val;
> +}
> +
> +static int snd_byt_rt5640_mc_remove(struct platform_device *pdev)
> +{
> +	struct snd_soc_card *card = platform_get_drvdata(pdev);
> +	struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card);
> +
> +	device_remove_software_node(priv->codec_dev);
> +
> +	return 0;
>  }
>  
>  static struct platform_driver snd_byt_rt5640_mc_driver = {
> @@ -1500,6 +1529,7 @@ static struct platform_driver snd_byt_rt5640_mc_driver = {
>  		.name = "bytcr_rt5640",
>  	},
>  	.probe = snd_byt_rt5640_mc_probe,
> +	.remove = snd_byt_rt5640_mc_remove
>  };
>  
>  module_platform_driver(snd_byt_rt5640_mc_driver);
> diff --git a/sound/soc/intel/boards/bytcr_rt5651.c b/sound/soc/intel/boards/bytcr_rt5651.c
> index e13c0c63a949..3066d00f3466 100644
> --- a/sound/soc/intel/boards/bytcr_rt5651.c
> +++ b/sound/soc/intel/boards/bytcr_rt5651.c
> @@ -85,6 +85,7 @@ struct byt_rt5651_private {
>  	struct gpio_desc *ext_amp_gpio;
>  	struct gpio_desc *hp_detect;
>  	struct snd_soc_jack jack;
> +	struct device *codec_dev;
>  };
>  
>  static const struct acpi_gpio_mapping *byt_rt5651_gpios;
> @@ -527,10 +528,13 @@ static const struct dmi_system_id byt_rt5651_quirk_table[] = {
>   * Note this MUST be called before snd_soc_register_card(), so that the props
>   * are in place before the codec component driver's probe function parses them.
>   */
> -static int byt_rt5651_add_codec_device_props(struct device *i2c_dev)
> +static int byt_rt5651_add_codec_device_props(struct device *i2c_dev,
> +					     struct byt_rt5651_private *priv)
>  {
>  	struct property_entry props[MAX_NO_PROPS] = {};
> +	struct fwnode_handle *fwnode;
>  	int cnt = 0;
> +	int ret;
>  
>  	props[cnt++] = PROPERTY_ENTRY_U32("realtek,jack-detect-source",
>  				BYT_RT5651_JDSRC(byt_rt5651_quirk));
> @@ -547,7 +551,18 @@ static int byt_rt5651_add_codec_device_props(struct device *i2c_dev)
>  	if (byt_rt5651_quirk & BYT_RT5651_JD_NOT_INV)
>  		props[cnt++] = PROPERTY_ENTRY_BOOL("realtek,jack-detect-not-inverted");
>  
> -	return device_add_properties(i2c_dev, props);
> +	fwnode = fwnode_create_software_node(props, NULL);
> +	if (IS_ERR(fwnode)) {
> +		/* put_device(i2c_dev) is handled in caller */
> +		return PTR_ERR(fwnode);
> +	}
> +
> +	ret = device_add_software_node(i2c_dev, to_software_node(fwnode));
> +
> +	fwnode_handle_put(fwnode);
> +	priv->codec_dev = i2c_dev;
> +
> +	return ret;
>  }
>  
>  static int byt_rt5651_init(struct snd_soc_pcm_runtime *runtime)
> @@ -994,7 +1009,7 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
>  	}
>  
>  	/* Must be called before register_card, also see declaration comment. */
> -	ret_val = byt_rt5651_add_codec_device_props(codec_dev);
> +	ret_val = byt_rt5651_add_codec_device_props(codec_dev, priv);
>  	if (ret_val) {
>  		put_device(codec_dev);
>  		return ret_val;
> @@ -1023,7 +1038,7 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
>  				fallthrough;
>  			case -EPROBE_DEFER:
>  				put_device(codec_dev);
> -				return ret_val;
> +				goto err;
>  			}
>  		}
>  		priv->hp_detect = devm_fwnode_gpiod_get(&pdev->dev,
> @@ -1043,7 +1058,7 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
>  				fallthrough;
>  			case -EPROBE_DEFER:
>  				put_device(codec_dev);
> -				return ret_val;
> +				goto err;
>  			}
>  		}
>  	}
> @@ -1073,7 +1088,7 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
>  			 * for all other errors, including -EPROBE_DEFER
>  			 */
>  			if (ret_val != -ENOENT)
> -				return ret_val;
> +				goto err;
>  			byt_rt5651_quirk &= ~BYT_RT5651_MCLK_EN;
>  		}
>  	}
> @@ -1102,7 +1117,7 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
>  	ret_val = snd_soc_fixup_dai_links_platform_name(&byt_rt5651_card,
>  							platform_name);
>  	if (ret_val)
> -		return ret_val;
> +		goto err;
>  
>  	sof_parent = snd_soc_acpi_sof_parent(&pdev->dev);
>  
> @@ -1124,10 +1139,25 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
>  	if (ret_val) {
>  		dev_err(&pdev->dev, "devm_snd_soc_register_card failed %d\n",
>  			ret_val);
> -		return ret_val;
> +		goto err;
>  	}
>  	platform_set_drvdata(pdev, &byt_rt5651_card);
>  	return ret_val;
> +
> +err:
> +	device_remove_software_node(priv->codec_dev);
> +
> +	return ret_val;
> +}
> +
> +static int snd_byt_rt5651_mc_remove(struct platform_device *pdev)
> +{
> +	struct snd_soc_card *card = platform_get_drvdata(pdev);
> +	struct byt_rt5651_private *priv = snd_soc_card_get_drvdata(card);
> +
> +	device_remove_software_node(priv->codec_dev);
> +
> +	return 0;
>  }
>  
>  static struct platform_driver snd_byt_rt5651_mc_driver = {
> @@ -1135,6 +1165,7 @@ static struct platform_driver snd_byt_rt5651_mc_driver = {
>  		.name = "bytcr_rt5651",
>  	},
>  	.probe = snd_byt_rt5651_mc_probe,
> +	.remove = snd_byt_rt5651_mc_remove,
>  };
>  
>  module_platform_driver(snd_byt_rt5651_mc_driver);
> 


  reply	other threads:[~2021-06-08  8:19 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-06-07 22:35 [PATCH 0/2] ASoC: Intel: boards: use software node API Pierre-Louis Bossart
2021-06-07 22:35 ` [PATCH 1/2] ASoC: Intel: boards: use software node API in SoundWire machines Pierre-Louis Bossart
2021-06-07 22:35 ` [PATCH 2/2] ASoC: Intel: boards: use software node API in Atom boards Pierre-Louis Bossart
2021-06-08  8:18   ` Hans de Goede [this message]
2021-06-08  9:02     ` Andy Shevchenko
2021-06-08  9:19       ` Hans de Goede
2021-06-08 11:22     ` Pierre-Louis Bossart
2021-06-08 12:47       ` Hans de Goede

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=0e8e01f6-d249-cc3e-2020-f6e5c81a4732@redhat.com \
    --to=hdegoede@redhat.com \
    --cc=alsa-devel@alsa-project.org \
    --cc=andriy.shevchenko@linux.intel.com \
    --cc=broonie@kernel.org \
    --cc=heikki.krogerus@linux.intel.com \
    --cc=pierre-louis.bossart@linux.intel.com \
    --cc=tiwai@suse.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.