soc/tegra: fuse: Add ACPI support for Tegra194 and Tegra234

Add ACPI support for Tegra194 & Tegra243 SoC's. This requires
following modifications to the probe when ACPI boot is used:
 - Initialize soc data.
 - Add nvmem lookups.
 - Register soc device.
 - use devm_clk_get_optional() instead of devm_clk_get() to get
   fuse->clk, as fuse clocks are not required when using ACPI boot.

Also, drop '__init' keyword for tegra_soc_device_register() as this is also
used by tegra_fuse_probe() and use dev_err_probe() wherever applicable.

Signed-off-by: Kartik <kkartik@nvidia.com>
Signed-off-by: Thierry Reding <treding@nvidia.com>
This commit is contained in:
Kartik 2023-10-17 10:53:21 +05:30 committed by Thierry Reding
parent 13a6935414
commit 972167c690
1 changed files with 49 additions and 3 deletions

View File

@ -3,11 +3,13 @@
* 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>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/mod_devicetable.h>
#include <linux/nvmem-consumer.h>
#include <linux/nvmem-provider.h>
#include <linux/of.h>
@ -152,7 +154,38 @@ static int tegra_fuse_probe(struct platform_device *pdev)
return PTR_ERR(fuse->base);
fuse->phys = res->start;
fuse->clk = devm_clk_get(&pdev->dev, "fuse");
/* Initialize the soc data and lookups if using ACPI boot. */
if (is_acpi_node(dev_fwnode(&pdev->dev)) && !fuse->soc) {
u8 chip;
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:
return dev_err_probe(&pdev->dev, -EINVAL, "Unsupported SoC: %02x\n", chip);
}
fuse->soc->init(fuse);
tegra_fuse_print_sku_info(&tegra_sku_info);
tegra_soc_device_register();
err = tegra_fuse_add_lookups(fuse);
if (err)
return dev_err_probe(&pdev->dev, err, "failed to add FUSE lookups\n");
}
fuse->clk = devm_clk_get_optional(&pdev->dev, "fuse");
if (IS_ERR(fuse->clk))
return dev_err_probe(&pdev->dev, PTR_ERR(fuse->clk), "failed to get FUSE clock\n");
@ -275,10 +308,17 @@ static const struct dev_pm_ops tegra_fuse_pm = {
SET_SYSTEM_SLEEP_PM_OPS(tegra_fuse_suspend, tegra_fuse_resume)
};
static const struct acpi_device_id tegra_fuse_acpi_match[] = {
{ "NVDA200F" },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(acpi, tegra_fuse_acpi_match);
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,
},
@ -300,7 +340,13 @@ u32 __init tegra_fuse_read_early(unsigned int offset)
int tegra_fuse_readl(unsigned long offset, u32 *value)
{
if (!fuse->read || !fuse->clk)
/*
* Wait for fuse->clk to be initialized if device-tree boot is used.
*/
if (is_of_node(dev_fwnode(fuse->dev)) && !fuse->clk)
return -EPROBE_DEFER;
if (!fuse->read)
return -EPROBE_DEFER;
if (IS_ERR(fuse->clk))
@ -383,7 +429,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;