Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Kartik and committed by
Thierry Reding
972167c6 13a69354

+49 -3
+49 -3
drivers/soc/tegra/fuse/fuse-tegra.c
··· 3 3 * Copyright (c) 2013-2023, NVIDIA CORPORATION. All rights reserved. 4 4 */ 5 5 6 + #include <linux/acpi.h> 6 7 #include <linux/clk.h> 7 8 #include <linux/device.h> 8 9 #include <linux/kobject.h> 9 10 #include <linux/init.h> 10 11 #include <linux/io.h> 12 + #include <linux/mod_devicetable.h> 11 13 #include <linux/nvmem-consumer.h> 12 14 #include <linux/nvmem-provider.h> 13 15 #include <linux/of.h> ··· 154 152 return PTR_ERR(fuse->base); 155 153 fuse->phys = res->start; 156 154 157 - fuse->clk = devm_clk_get(&pdev->dev, "fuse"); 155 + /* Initialize the soc data and lookups if using ACPI boot. */ 156 + if (is_acpi_node(dev_fwnode(&pdev->dev)) && !fuse->soc) { 157 + u8 chip; 158 + 159 + tegra_acpi_init_apbmisc(); 160 + 161 + chip = tegra_get_chip_id(); 162 + switch (chip) { 163 + #if defined(CONFIG_ARCH_TEGRA_194_SOC) 164 + case TEGRA194: 165 + fuse->soc = &tegra194_fuse_soc; 166 + break; 167 + #endif 168 + #if defined(CONFIG_ARCH_TEGRA_234_SOC) 169 + case TEGRA234: 170 + fuse->soc = &tegra234_fuse_soc; 171 + break; 172 + #endif 173 + default: 174 + return dev_err_probe(&pdev->dev, -EINVAL, "Unsupported SoC: %02x\n", chip); 175 + } 176 + 177 + fuse->soc->init(fuse); 178 + tegra_fuse_print_sku_info(&tegra_sku_info); 179 + tegra_soc_device_register(); 180 + 181 + err = tegra_fuse_add_lookups(fuse); 182 + if (err) 183 + return dev_err_probe(&pdev->dev, err, "failed to add FUSE lookups\n"); 184 + } 185 + 186 + fuse->clk = devm_clk_get_optional(&pdev->dev, "fuse"); 158 187 if (IS_ERR(fuse->clk)) 159 188 return dev_err_probe(&pdev->dev, PTR_ERR(fuse->clk), "failed to get FUSE clock\n"); 160 189 ··· 308 275 SET_SYSTEM_SLEEP_PM_OPS(tegra_fuse_suspend, tegra_fuse_resume) 309 276 }; 310 277 278 + static const struct acpi_device_id tegra_fuse_acpi_match[] = { 279 + { "NVDA200F" }, 280 + { /* sentinel */ } 281 + }; 282 + MODULE_DEVICE_TABLE(acpi, tegra_fuse_acpi_match); 283 + 311 284 static struct platform_driver tegra_fuse_driver = { 312 285 .driver = { 313 286 .name = "tegra-fuse", 314 287 .of_match_table = tegra_fuse_match, 288 + .acpi_match_table = tegra_fuse_acpi_match, 315 289 .pm = &tegra_fuse_pm, 316 290 .suppress_bind_attrs = true, 317 291 }, ··· 340 300 341 301 int tegra_fuse_readl(unsigned long offset, u32 *value) 342 302 { 343 - if (!fuse->read || !fuse->clk) 303 + /* 304 + * Wait for fuse->clk to be initialized if device-tree boot is used. 305 + */ 306 + if (is_of_node(dev_fwnode(fuse->dev)) && !fuse->clk) 307 + return -EPROBE_DEFER; 308 + 309 + if (!fuse->read) 344 310 return -EPROBE_DEFER; 345 311 346 312 if (IS_ERR(fuse->clk)) ··· 429 383 }; 430 384 #endif 431 385 432 - struct device * __init tegra_soc_device_register(void) 386 + struct device *tegra_soc_device_register(void) 433 387 { 434 388 struct soc_device_attribute *attr; 435 389 struct soc_device *dev;