1. Implementation of: reset_reason reset_level These APIs provide information about tegra reset reason and level respectively. 2. sysfs entries: /sys/devices/platform/<address>.pmc/reset_reason and /sys/devices/platform/<address>.pmc/reset_level These attributes are implemented in readonly mode to fetch tegra reset reason and tegra reset level information. These sysfs nodes provide reset reason and reset level information on production software. Signed-off-by: Sandipan Patra <spatra@xxxxxxxxxx> --- Changes since V2: 1. Followed as per with idiomatic version by keeping space between * and const 2. tegra_legacy_* is changed to tegra30_* 3. functionalities moved inside the attributes to avoid additional function definitions 4. device_create_file is properly used with its return value considered drivers/soc/tegra/pmc.c | 80 ++++++++++++++++++++++--------------------------- 1 file changed, 35 insertions(+), 45 deletions(-) diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c index 18ee90b..9761f60 100644 --- a/drivers/soc/tegra/pmc.c +++ b/drivers/soc/tegra/pmc.c @@ -181,13 +181,13 @@ struct tegra_pmc_soc { struct device_node *np, bool invert); - const char *const *reset_sources; + const char * const *reset_sources; unsigned int num_reset_sources; - const char *const *reset_levels; + const char * const *reset_levels; unsigned int num_reset_levels; }; -static const char *const tegra186_reset_sources[] = { +static const char * const tegra186_reset_sources[] = { "SYS_RESET", "AOWDT", "MCCPLEXWDT", @@ -205,11 +205,11 @@ static const char *const tegra186_reset_sources[] = { "CORESIGHT" }; -static const char *const tegra186_reset_levels[] = { +static const char * const tegra186_reset_levels[] = { "L0", "L1", "L2", "WARM" }; -static const char *const tegra_legacy_reset_sources[] = { +static const char * const tegra30_reset_sources[] = { "POWER_ON_RESET", "WATCHDOG", "SENSOR", @@ -703,31 +703,6 @@ int tegra_pmc_cpu_remove_clamping(unsigned int cpuid) } #endif /* CONFIG_SMP */ -/** - * tegra_pmc_get_system_reset_reason() - last reset reason status - */ -static const char *tegra_pmc_get_system_reset_reason(void) -{ - u32 value, rst_src; - - value = tegra_pmc_readl(pmc->soc->regs->rst_status); - rst_src = (value & pmc->soc->regs->rst_source_mask) >> - pmc->soc->regs->rst_source_shift; - - return pmc->soc->reset_sources[rst_src]; -} - -static const char *tegra_pmc_get_system_reset_level(void) -{ - u32 value, rst_lvl; - - value = tegra_pmc_readl(pmc->soc->regs->rst_status); - rst_lvl = (value & pmc->soc->regs->rst_level_mask) >> - pmc->soc->regs->rst_level_shift; - - return pmc->soc->reset_levels[rst_lvl]; -} - static int tegra_pmc_restart_notify(struct notifier_block *this, unsigned long action, void *data) { @@ -1612,7 +1587,13 @@ static int tegra_pmc_pinctrl_init(struct tegra_pmc *pmc) static ssize_t reset_reason_show(struct device *dev, struct device_attribute *attr, char *buf) { - return sprintf(buf, "%s\n", tegra_pmc_get_system_reset_reason()); + u32 value, rst_src; + + value = tegra_pmc_readl(pmc->soc->regs->rst_status); + rst_src = (value & pmc->soc->regs->rst_source_mask) >> + pmc->soc->regs->rst_source_shift; + + return sprintf(buf, "%s\n", pmc->soc->reset_sources[rst_src]); } static DEVICE_ATTR_RO(reset_reason); @@ -1620,26 +1601,36 @@ static DEVICE_ATTR_RO(reset_reason); static ssize_t reset_level_show(struct device *dev, struct device_attribute *attr, char *buf) { - return sprintf(buf, "%s\n", tegra_pmc_get_system_reset_level()); + u32 value, rst_lvl; + + value = tegra_pmc_readl(pmc->soc->regs->rst_status); + rst_lvl = (value & pmc->soc->regs->rst_level_mask) >> + pmc->soc->regs->rst_level_shift; + + return sprintf(buf, "%s\n", pmc->soc->reset_levels[rst_lvl]); } static DEVICE_ATTR_RO(reset_level); -static void tegra_pmc_reset_sysfs_init(struct device *dev) +static void tegra_pmc_reset_sysfs_init(struct tegra_pmc *pmc) { + struct device *dev = pmc->dev; + int err = 0; if (pmc->soc->reset_sources) { - if (device_create_file(dev, &dev_attr_reset_reason)) { + err = device_create_file(dev, &dev_attr_reset_reason); + if (err < 0) dev_warn(dev, - "Failed to create sysfs node - tegra_reset_reason\n"); - } + "failed to create attr \"reset_reason\": %d\n", + err); } if (pmc->soc->reset_levels) { - if (device_create_file(dev, &dev_attr_reset_level)) { + err = device_create_file(dev, &dev_attr_reset_level); + if (err < 0) dev_warn(dev, - "Failed to create sysfs node - tegra_reset_level\n"); - } + "failed to create attr \"reset_level\": %d\n", + err); } } @@ -1712,7 +1703,7 @@ static int tegra_pmc_probe(struct platform_device *pdev) tegra_pmc_init_tsense_reset(pmc); - tegra_pmc_reset_sysfs_init(&pdev->dev); + tegra_pmc_reset_sysfs_init(pmc); if (IS_ENABLED(CONFIG_DEBUG_FS)) { err = tegra_powergate_debugfs_init(); @@ -1887,7 +1878,7 @@ static const struct tegra_pmc_soc tegra30_pmc_soc = { .regs = &tegra20_pmc_regs, .init = tegra20_pmc_init, .setup_irq_polarity = tegra20_pmc_setup_irq_polarity, - .reset_sources = tegra_legacy_reset_sources, + .reset_sources = tegra30_reset_sources, .num_reset_sources = 5, .reset_levels = NULL, .num_reset_levels = 0, @@ -1936,7 +1927,7 @@ static const struct tegra_pmc_soc tegra114_pmc_soc = { .regs = &tegra20_pmc_regs, .init = tegra20_pmc_init, .setup_irq_polarity = tegra20_pmc_setup_irq_polarity, - .reset_sources = tegra_legacy_reset_sources, + .reset_sources = tegra30_reset_sources, .num_reset_sources = 5, .reset_levels = NULL, .num_reset_levels = 0, @@ -2045,7 +2036,7 @@ static const struct tegra_pmc_soc tegra124_pmc_soc = { .regs = &tegra20_pmc_regs, .init = tegra20_pmc_init, .setup_irq_polarity = tegra20_pmc_setup_irq_polarity, - .reset_sources = tegra_legacy_reset_sources, + .reset_sources = tegra30_reset_sources, .num_reset_sources = 5, .reset_levels = NULL, .num_reset_levels = 0, @@ -2150,7 +2141,7 @@ static const struct tegra_pmc_soc tegra210_pmc_soc = { .regs = &tegra20_pmc_regs, .init = tegra20_pmc_init, .setup_irq_polarity = tegra20_pmc_setup_irq_polarity, - .reset_sources = tegra_legacy_reset_sources, + .reset_sources = tegra30_reset_sources, .num_reset_sources = 5, .reset_levels = NULL, .num_reset_levels = 0, @@ -2216,7 +2207,6 @@ static const struct tegra_pmc_regs tegra186_pmc_regs = { .rst_source_mask = 0x3C, .rst_level_shift = 0x0, .rst_level_mask = 0x3, - }; static void tegra186_pmc_setup_irq_polarity(struct tegra_pmc *pmc, -- 2.7.4