/* take over the memory region from the early initialization */
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;
/* Initialize the soc data and lookups if using ACPI boot. */ if (is_acpi_node(dev_fwnode(&pdev->dev)) && !fuse->soc) {
u8 chip;
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");
fuse->rst = devm_reset_control_get_optional(&pdev->dev, "fuse"); if (IS_ERR(fuse->rst)) return dev_err_probe(&pdev->dev, PTR_ERR(fuse->rst), "failed to get FUSE reset\n");
/* * FUSE clock is enabled at a boot time, hence this resume/suspend * disables the clock besides the h/w resetting.
*/
err = pm_runtime_resume_and_get(&pdev->dev); if (err) return err;
staticint __maybe_unused tegra_fuse_suspend(struct device *dev)
{ int ret;
/* * Critical for RAM re-repair operation, which must occur on resume * from LP1 system suspend and as part of CCPLEX cluster switching.
*/ if (fuse->soc->clk_suspend_on)
ret = pm_runtime_resume_and_get(dev); else
ret = pm_runtime_force_suspend(dev);
return ret;
}
staticint __maybe_unused tegra_fuse_resume(struct device *dev)
{ int ret = 0;
if (fuse->soc->clk_suspend_on)
pm_runtime_put(dev); else
ret = pm_runtime_force_resume(dev);
/* * Enable FUSE clock. This needs to be hardcoded because the clock * subsystem is not active during early boot.
*/
reg = readl(base + 0x14);
reg |= 1 << 7;
writel(reg, base + 0x14);
}
#if IS_ENABLED(CONFIG_ARCH_TEGRA_194_SOC) || \
IS_ENABLED(CONFIG_ARCH_TEGRA_234_SOC) || \
IS_ENABLED(CONFIG_ARCH_TEGRA_241_SOC) static ssize_t platform_show(struct device *dev, struct device_attribute *attr, char *buf)
{ /* * Displays the value in the 'pre_si_platform' field of the HIDREV * register for Tegra194 devices. A value of 0 indicates that the * platform type is silicon and all other non-zero values indicate * the type of simulation platform is being used.
*/ return sprintf(buf, "%d\n", tegra_get_platform());
}
np = of_find_matching_node_and_match(NULL, tegra_fuse_match, &match); if (!np) { /* * Fall back to legacy initialization for 32-bit ARM only. All * 64-bit ARM device tree files for Tegra are required to have * a FUSE node. * * This is for backwards-compatibility with old device trees * that didn't contain a FUSE node.
*/ if (IS_ENABLED(CONFIG_ARM) && soc_is_tegra()) {
u8 chip = tegra_get_chip_id();
#ifdef CONFIG_ARCH_TEGRA_3x_SOC case TEGRA30:
fuse->soc = &tegra30_fuse_soc; break; #endif
#ifdef CONFIG_ARCH_TEGRA_114_SOC case TEGRA114:
fuse->soc = &tegra114_fuse_soc; break; #endif
#ifdef CONFIG_ARCH_TEGRA_124_SOC case TEGRA124:
fuse->soc = &tegra124_fuse_soc; break; #endif
default:
pr_warn("Unsupported SoC: %02x\n", chip); break;
}
} else { /* * At this point we're not running on Tegra, so play * nice with multi-platform kernels.
*/ return 0;
}
} else { /* * Extract information from the device tree if we've found a * matching node.
*/ if (of_address_to_resource(np, 0, ®s) < 0) {
pr_err("failed to get FUSE register\n"); return -ENXIO;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.