All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dan Carpenter <dan.carpenter@linaro.org>
To: Aaron Kling <webgeek1234@gmail.com>
Cc: linux-tegra@vger.kernel.org
Subject: [bug report] memory: tegra210: Support interconnect framework
Date: Fri, 21 Nov 2025 12:32:55 +0300	[thread overview]
Message-ID: <aSAxxzcRZduavJQT@stanley.mountain> (raw)

Hello Aaron Kling,

Commit b33c93babead ("memory: tegra210: Support interconnect
framework") from Oct 27, 2025 (linux-next), leads to the following
Smatch static checker warning:

	drivers/memory/tegra/tegra210-emc-core.c:2230 tegra210_emc_probe()
	warn: missing unwind goto?

drivers/memory/tegra/tegra210-emc-core.c
  2070  static int tegra210_emc_probe(struct platform_device *pdev)
  2071  {
  2072          struct thermal_cooling_device *cd;
  2073          unsigned long current_rate;
  2074          struct tegra210_emc *emc;
  2075          struct device_node *np;
  2076          unsigned int i;
  2077          int err;
  2078  
  2079          emc = devm_kzalloc(&pdev->dev, sizeof(*emc), GFP_KERNEL);
  2080          if (!emc)
  2081                  return -ENOMEM;
  2082  
  2083          emc->clk = devm_clk_get(&pdev->dev, "emc");
  2084          if (IS_ERR(emc->clk))
  2085                  return PTR_ERR(emc->clk);
  2086  
  2087          platform_set_drvdata(pdev, emc);
  2088          spin_lock_init(&emc->lock);
  2089          emc->dev = &pdev->dev;
  2090  
  2091          emc->mc = devm_tegra_memory_controller_get(&pdev->dev);
  2092          if (IS_ERR(emc->mc))
  2093                  return PTR_ERR(emc->mc);
  2094  
  2095          emc->regs = devm_platform_ioremap_resource(pdev, 0);
  2096          if (IS_ERR(emc->regs))
  2097                  return PTR_ERR(emc->regs);
  2098  
  2099          for (i = 0; i < 2; i++) {
  2100                  emc->channel[i] = devm_platform_ioremap_resource(pdev, 1 + i);
  2101                  if (IS_ERR(emc->channel[i]))
  2102                          return PTR_ERR(emc->channel[i]);
  2103  
  2104          }
  2105  
  2106          tegra210_emc_detect(emc);
  2107          np = pdev->dev.of_node;
  2108  
  2109          /* attach to the nominal and (optional) derated tables */
  2110          err = of_reserved_mem_device_init_by_name(emc->dev, np, "nominal");
  2111          if (err < 0) {
  2112                  dev_err(emc->dev, "failed to get nominal EMC table: %d\n", err);
  2113                  return err;
  2114          }
  2115  
  2116          err = of_reserved_mem_device_init_by_name(emc->dev, np, "derated");
  2117          if (err < 0 && err != -ENODEV) {
  2118                  dev_err(emc->dev, "failed to get derated EMC table: %d\n", err);
  2119                  goto release;
  2120          }
  2121  
  2122          /* validate the tables */
  2123          if (emc->nominal) {
  2124                  err = tegra210_emc_validate_timings(emc, emc->nominal,
  2125                                                      emc->num_timings);
  2126                  if (err < 0)
  2127                          goto release;
  2128          }
  2129  
  2130          if (emc->derated) {
  2131                  err = tegra210_emc_validate_timings(emc, emc->derated,
  2132                                                      emc->num_timings);
  2133                  if (err < 0)
  2134                          goto release;
  2135          }
  2136  
  2137          /* default to the nominal table */
  2138          emc->timings = emc->nominal;
  2139  
  2140          /* pick the current timing based on the current EMC clock rate */
  2141          current_rate = clk_get_rate(emc->clk) / 1000;
  2142  
  2143          for (i = 0; i < emc->num_timings; i++) {
  2144                  if (emc->timings[i].rate == current_rate) {
  2145                          emc->last = &emc->timings[i];
  2146                          break;
  2147                  }
  2148          }
  2149  
  2150          if (i == emc->num_timings) {
  2151                  dev_err(emc->dev, "no EMC table entry found for %lu kHz\n",
  2152                          current_rate);
  2153                  err = -ENOENT;
  2154                  goto release;
  2155          }
  2156  
  2157          /* pick a compatible clock change sequence for the EMC table */
  2158          for (i = 0; i < ARRAY_SIZE(tegra210_emc_sequences); i++) {
  2159                  const struct tegra210_emc_sequence *sequence =
  2160                                  tegra210_emc_sequences[i];
  2161  
  2162                  if (emc->timings[0].revision == sequence->revision) {
  2163                          emc->sequence = sequence;
  2164                          break;
  2165                  }
  2166          }
  2167  
  2168          if (!emc->sequence) {
  2169                  dev_err(&pdev->dev, "sequence %u not supported\n",
  2170                          emc->timings[0].revision);
  2171                  err = -ENOTSUPP;
  2172                  goto release;
  2173          }
  2174  
  2175          emc->offsets = &tegra210_emc_table_register_offsets;
  2176          emc->refresh = TEGRA210_EMC_REFRESH_NOMINAL;
  2177  
  2178          emc->provider.owner = THIS_MODULE;
  2179          emc->provider.dev = &pdev->dev;
  2180          emc->provider.set_rate = tegra210_emc_set_rate;
  2181  
  2182          emc->provider.configs = devm_kcalloc(&pdev->dev, emc->num_timings,
  2183                                               sizeof(*emc->provider.configs),
  2184                                               GFP_KERNEL);
  2185          if (!emc->provider.configs) {
  2186                  err = -ENOMEM;
  2187                  goto release;
  2188          }
  2189  
  2190          emc->provider.num_configs = emc->num_timings;
  2191  
  2192          for (i = 0; i < emc->provider.num_configs; i++) {
  2193                  struct tegra210_emc_timing *timing = &emc->timings[i];
  2194                  struct tegra210_clk_emc_config *config =
  2195                                  &emc->provider.configs[i];
  2196                  u32 value;
  2197  
  2198                  config->rate = timing->rate * 1000UL;
  2199                  config->value = timing->clk_src_emc;
  2200  
  2201                  value = timing->burst_mc_regs[MC_EMEM_ARB_MISC0_INDEX];
  2202  
  2203                  if ((value & MC_EMEM_ARB_MISC0_EMC_SAME_FREQ) == 0)
  2204                          config->same_freq = false;
  2205                  else
  2206                          config->same_freq = true;
  2207          }
  2208  
  2209          err = tegra210_clk_emc_attach(emc->clk, &emc->provider);
  2210          if (err < 0) {
  2211                  dev_err(&pdev->dev, "failed to attach to EMC clock: %d\n", err);
  2212                  goto release;
  2213          }
  2214  
  2215          emc->clkchange_delay = 100;
  2216          emc->training_interval = 100;
  2217          dev_set_drvdata(emc->dev, emc);
  2218  
  2219          timer_setup(&emc->refresh_timer, tegra210_emc_poll_refresh,
  2220                      TIMER_DEFERRABLE);
  2221          atomic_set(&emc->refresh_poll, 0);
  2222          emc->refresh_poll_interval = 1000;
  2223  
  2224          timer_setup(&emc->training, tegra210_emc_train, 0);
  2225  
  2226          tegra210_emc_debugfs_init(emc);
  2227  
  2228          err = tegra210_emc_opp_table_init(emc);
  2229          if (!err) {
  2230                  tegra210_emc_rate_requests_init(emc);
  2231                  tegra210_emc_interconnect_init(emc);
  2232          } else if (err != -ENODEV) {
  2233                  return err;

This should be goto detach.  The other issue is that
tegra210_emc_opp_table_init() needs to be cleaned up as well.

void tegra210_emc_opp_table_cleanup()
{
        dev_pm_opp_of_remove_table(emc->dev);
        dev_pm_opp_put_supported_hw(opp_token);
}

  2234          }
  2235  
  2236          cd = devm_thermal_of_cooling_device_register(emc->dev, np, "emc", emc,
  2237                                                       &tegra210_emc_cd_ops);
  2238          if (IS_ERR(cd)) {
  2239                  err = PTR_ERR(cd);
  2240                  dev_err(emc->dev, "failed to register cooling device: %d\n",
  2241                          err);
  2242                  goto detach;

goto cleanup_table;

  2243          }
  2244  
  2245          return 0;
  2246  

cleanup_table:
	tegra210_emc_opp_table_cleanup();

  2247  detach:
  2248          debugfs_remove_recursive(emc->debugfs.root);
  2249          tegra210_clk_emc_detach(emc->clk);
  2250  release:
  2251          of_reserved_mem_device_release(emc->dev);
  2252  
  2253          return err;
  2254  }
  2255  
  2256  static void tegra210_emc_remove(struct platform_device *pdev)
  2257  {
  2258          struct tegra210_emc *emc = platform_get_drvdata(pdev);
  2259  

Same here:

	tegra210_emc_opp_table_cleanup();

  2260          debugfs_remove_recursive(emc->debugfs.root);
  2261          tegra210_clk_emc_detach(emc->clk);
  2262          of_reserved_mem_device_release(emc->dev);
  2263  }

regards,
dan carpenter

                 reply	other threads:[~2025-11-21  9:33 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=aSAxxzcRZduavJQT@stanley.mountain \
    --to=dan.carpenter@linaro.org \
    --cc=linux-tegra@vger.kernel.org \
    --cc=webgeek1234@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.