diff mbox series

[5/6] soc/tegra: fuse: Add ACPI support for Tegra194 and Tegra234

Message ID 20230818093028.7807-6-kkartik@nvidia.com
State Superseded
Headers show
Series soc/tegra: fuse: Add ACPI support | expand

Commit Message

Kartik Rajput Aug. 18, 2023, 9:30 a.m. UTC
Add tegra_fuse_acpi_probe() to initialize Tegra fuse while using ACPI.
Also, drop '__init' keyword for tegra_soc_device_register() as this is also
used by tegra_fuse_acpi_probe().

Note that as ACPI subsystem initialize at subsys init, function
tegra_fuse_acpi_probe() also contains the necessary initialization
that we are currently doing for device-tree boot as a part of
early init.

Signed-off-by: Kartik <kkartik@nvidia.com>
---
 drivers/soc/tegra/fuse/fuse-tegra.c | 67 ++++++++++++++++++++++++++++-
 1 file changed, 65 insertions(+), 2 deletions(-)

Comments

Andy Shevchenko Aug. 18, 2023, 3:07 p.m. UTC | #1
On Fri, Aug 18, 2023 at 03:00:27PM +0530, Kartik wrote:
> Add tegra_fuse_acpi_probe() to initialize Tegra fuse while using ACPI.
> Also, drop '__init' keyword for tegra_soc_device_register() as this is also
> used by tegra_fuse_acpi_probe().
> 
> Note that as ACPI subsystem initialize at subsys init, function
> tegra_fuse_acpi_probe() also contains the necessary initialization
> that we are currently doing for device-tree boot as a part of
> early init.

...

> +#include <linux/acpi.h>

You meed mod_devicetable.h and possibly property.h, not this header
(see below).

...

> +static const struct acpi_device_id tegra_fuse_acpi_match[] = {
> +	{
> +		.id = "NVDA200F",
> +	},

Single line, no inner comma.

> +	{ /* sentinel */ },

The idea of sentinel is to guard, the trailing comma ruins this contract.

> +};

...

> +static int tegra_fuse_acpi_probe(struct platform_device *pdev)
> +{

Why you need a separate function?

> +	struct resource *res;
> +	u8 chip;
> +	int err;
> +
> +	tegra_acpi_init_apbmisc();
> +
> +	chip = tegra_get_chip_id();
> +	switch (chip) {
> +#if defined(CONFIG_ARCH_TEGRA_194_SOC)

Can we avoid ugly ifdeffery?

> +	case TEGRA194:
> +		fuse->soc = &tegra194_fuse_soc;
> +		break;
> +#endif
> +#if defined(CONFIG_ARCH_TEGRA_234_SOC)

Ditto.

> +	case TEGRA234:
> +		fuse->soc = &tegra234_fuse_soc;
> +		break;
> +#endif
> +	default:
> +		dev_err(&pdev->dev, "Unsupported SoC: %02x\n", chip);
> +		return -EINVAL;

		return dev_err_probe(...);

> +	}
> +
> +	fuse->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
> +	if (IS_ERR(fuse->base))
> +		return PTR_ERR(fuse->base);
> +	fuse->phys = res->start;

> +	platform_set_drvdata(pdev, fuse);

Is it being used?

> +	fuse->dev = &pdev->dev;
> +
> +	err = tegra_fuse_nvmem_register(fuse, &pdev->dev);
> +	if (err)
> +		return err;
> +
> +	fuse->soc->init(fuse);
> +	tegra_soc_device_register();
> +	tegra_fuse_pr_sku_info(&tegra_sku_info);
> +
> +	err = tegra_fuse_add_lookups(fuse);
> +	if (err) {

> +		dev_err(&pdev->dev, "failed to add FUSE lookups\n");
> +		return err;

		return dev_err_probe(...);

> +	}
> +
> +	return 0;
> +}

...

> +	if (has_acpi_companion(&pdev->dev))
> +		return tegra_fuse_acpi_probe(pdev);

Why is the ACPI so special here? Why you can't go same flow?

...

> +	/* fuse->clk is not required when ACPI is used. */
> +	if (!fuse->read || (!fuse->clk && !has_acpi_companion(fuse->dev)))

No, just make CLK optional and that's it.

>  		return -EPROBE_DEFER;
Kartik Rajput Aug. 21, 2023, 11:38 a.m. UTC | #2
On Fri, 2023-08-18 at 18:07 +0300, Andy Shevchenko wrote:
>On Fri, Aug 18, 2023 at 03:00:27PM +0530, Kartik wrote:
>> Add tegra_fuse_acpi_probe() to initialize Tegra fuse while using ACPI.
>> Also, drop '__init' keyword for tegra_soc_device_register() as this is also
>> used by tegra_fuse_acpi_probe().
>> 
>> Note that as ACPI subsystem initialize at subsys init, function
>> tegra_fuse_acpi_probe() also contains the necessary initialization
>> that we are currently doing for device-tree boot as a part of
>> early init.
>
>...
>
>> +#include <linux/acpi.h>
>
>You meed mod_devicetable.h and possibly property.h, not this header
>(see below).
>
>...
>
>> +static const struct acpi_device_id tegra_fuse_acpi_match[] = {
>> +	{
>> +		.id = "NVDA200F",
>> +	},
>
>Single line, no inner comma.

ACK.

>
>> +	{ /* sentinel */ },
>
>The idea of sentinel is to guard, the trailing comma ruins this contract.
>
>> +};

ACK.

>
>...
>
>> +static int tegra_fuse_acpi_probe(struct platform_device *pdev)
>> +{
>
>Why you need a separate function?
>
>> +	struct resource *res;
>> +	u8 chip;
>> +	int err;
>> +
>> +	tegra_acpi_init_apbmisc();
>> +
>> +	chip = tegra_get_chip_id();
>> +	switch (chip) {
>> +#if defined(CONFIG_ARCH_TEGRA_194_SOC)
>
>Can we avoid ugly ifdeffery?
>

No, the SoC data is defined only when the SoC specific config is
enabled. So, guarding these with ifdef's is required here.

>> +	case TEGRA194:
>> +		fuse->soc = &tegra194_fuse_soc;
>> +		break;
>> +#endif
>> +#if defined(CONFIG_ARCH_TEGRA_234_SOC)
>
>Ditto.
>
>> +	case TEGRA234:
>> +		fuse->soc = &tegra234_fuse_soc;
>> +		break;
>> +#endif
>> +	default:
>> +		dev_err(&pdev->dev, "Unsupported SoC: %02x\n", chip);
>> +		return -EINVAL;
>
>		return dev_err_probe(...);
>

ACK.

>> +	}
>> +
>> +	fuse->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
>> +	if (IS_ERR(fuse->base))
>> +		return PTR_ERR(fuse->base);
>> +	fuse->phys = res->start;
>
>> +	platform_set_drvdata(pdev, fuse);
>
>Is it being used?
>

Looks like this is not being used.

>> +	fuse->dev = &pdev->dev;
>> +
>> +	err = tegra_fuse_nvmem_register(fuse, &pdev->dev);
>> +	if (err)
>> +		return err;
>> +
>> +	fuse->soc->init(fuse);
>> +	tegra_soc_device_register();
>> +	tegra_fuse_pr_sku_info(&tegra_sku_info);
>> +
>> +	err = tegra_fuse_add_lookups(fuse);
>> +	if (err) {
>
>> +		dev_err(&pdev->dev, "failed to add FUSE lookups\n");
>> +		return err;
>
>		return dev_err_probe(...);
>
>> +	}
>> +
>> +	return 0;
>> +}
>
>...
>
>> +	if (has_acpi_companion(&pdev->dev))
>> +		return tegra_fuse_acpi_probe(pdev);
>
>Why is the ACPI so special here? Why you can't go same flow?
>
>...
>

We need to initialize the soc data before we continue the probe.
I guess we can have a conditional here for this initialization.
and re-use the same function. I will update this in the next patch.

>> +	/* fuse->clk is not required when ACPI is used. */
>> +	if (!fuse->read || (!fuse->clk && !has_acpi_companion(fuse->dev)))
>
>No, just make CLK optional and that's it.
>
>>  		return -EPROBE_DEFER;
>
>-- 

If the Fuse driver is probed using device-tree. Then we need to make
sure that fuse->clk has been initilaized.

>With Best Regards,
>Andy Shevchenko

Regards,
Kartik
Andy Shevchenko Aug. 21, 2023, 12:45 p.m. UTC | #3
On Mon, Aug 21, 2023 at 05:08:19PM +0530, Kartik wrote:
> On Fri, 2023-08-18 at 18:07 +0300, Andy Shevchenko wrote:
> >On Fri, Aug 18, 2023 at 03:00:27PM +0530, Kartik wrote:

...

> >> +	/* fuse->clk is not required when ACPI is used. */
> >> +	if (!fuse->read || (!fuse->clk && !has_acpi_companion(fuse->dev)))
> >
> >No, just make CLK optional and that's it.
> >
> >>  		return -EPROBE_DEFER;
> >
> If the Fuse driver is probed using device-tree. Then we need to make
> sure that fuse->clk has been initilaized.

So, I recommend to think about it more, maybe you can find better solution
than above.

And actually don't use has_acpi_companion() in this case. What you need is
is_acpi_node() or is_of_node() depending on the case you want to check for.
diff mbox series

Patch

diff --git a/drivers/soc/tegra/fuse/fuse-tegra.c b/drivers/soc/tegra/fuse/fuse-tegra.c
index 70e8eeddcbd9..9c5596d968a2 100644
--- a/drivers/soc/tegra/fuse/fuse-tegra.c
+++ b/drivers/soc/tegra/fuse/fuse-tegra.c
@@ -3,6 +3,7 @@ 
  * Copyright (c) 2013-2023, NVIDIA CORPORATION.  All rights reserved.
  */
 
+#include <linux/acpi.h>
 #include <linux/clk.h>
 #include <linux/device.h>
 #include <linux/kobject.h>
@@ -94,6 +95,13 @@  static const struct of_device_id tegra_fuse_match[] = {
 	{ /* sentinel */ }
 };
 
+static const struct acpi_device_id tegra_fuse_acpi_match[] = {
+	{
+		.id = "NVDA200F",
+	},
+	{ /* sentinel */ },
+};
+
 static int tegra_fuse_read(void *priv, unsigned int offset, void *value,
 			   size_t bytes)
 {
@@ -176,12 +184,65 @@  static void tegra_fuse_pr_sku_info(struct tegra_sku_info *tegra_sku_info)
 		tegra_sku_info->cpu_speedo_id, tegra_sku_info->soc_speedo_id);
 }
 
+static int tegra_fuse_acpi_probe(struct platform_device *pdev)
+{
+	struct resource *res;
+	u8 chip;
+	int err;
+
+	tegra_acpi_init_apbmisc();
+
+	chip = tegra_get_chip_id();
+	switch (chip) {
+#if defined(CONFIG_ARCH_TEGRA_194_SOC)
+	case TEGRA194:
+		fuse->soc = &tegra194_fuse_soc;
+		break;
+#endif
+#if defined(CONFIG_ARCH_TEGRA_234_SOC)
+	case TEGRA234:
+		fuse->soc = &tegra234_fuse_soc;
+		break;
+#endif
+	default:
+		dev_err(&pdev->dev, "Unsupported SoC: %02x\n", chip);
+		return -EINVAL;
+	}
+
+	fuse->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
+	if (IS_ERR(fuse->base))
+		return PTR_ERR(fuse->base);
+	fuse->phys = res->start;
+
+	platform_set_drvdata(pdev, fuse);
+	fuse->dev = &pdev->dev;
+
+	err = tegra_fuse_nvmem_register(fuse, &pdev->dev);
+	if (err)
+		return err;
+
+	fuse->soc->init(fuse);
+	tegra_soc_device_register();
+	tegra_fuse_pr_sku_info(&tegra_sku_info);
+
+	err = tegra_fuse_add_lookups(fuse);
+	if (err) {
+		dev_err(&pdev->dev, "failed to add FUSE lookups\n");
+		return err;
+	}
+
+	return 0;
+}
+
 static int tegra_fuse_probe(struct platform_device *pdev)
 {
 	void __iomem *base = fuse->base;
 	struct resource *res;
 	int err;
 
+	if (has_acpi_companion(&pdev->dev))
+		return tegra_fuse_acpi_probe(pdev);
+
 	err = devm_add_action(&pdev->dev, tegra_fuse_restore, (void __force *)base);
 	if (err)
 		return err;
@@ -306,6 +367,7 @@  static struct platform_driver tegra_fuse_driver = {
 	.driver = {
 		.name = "tegra-fuse",
 		.of_match_table = tegra_fuse_match,
+		.acpi_match_table = tegra_fuse_acpi_match,
 		.pm = &tegra_fuse_pm,
 		.suppress_bind_attrs = true,
 	},
@@ -327,7 +389,8 @@  u32 __init tegra_fuse_read_early(unsigned int offset)
 
 int tegra_fuse_readl(unsigned long offset, u32 *value)
 {
-	if (!fuse->read || !fuse->clk)
+	/* fuse->clk is not required when ACPI is used. */
+	if (!fuse->read || (!fuse->clk && !has_acpi_companion(fuse->dev)))
 		return -EPROBE_DEFER;
 
 	if (IS_ERR(fuse->clk))
@@ -410,7 +473,7 @@  const struct attribute_group tegra194_soc_attr_group = {
 };
 #endif
 
-struct device * __init tegra_soc_device_register(void)
+struct device *tegra_soc_device_register(void)
 {
 	struct soc_device_attribute *attr;
 	struct soc_device *dev;