void __iomem *modrst_base;
};
+/*
+ * For compatibility with Kernels that don't support peripheral reset, this
+ * driver can keep the old behaviour of not asserting peripheral reset before
+ * starting the OS and deasserting all peripheral resets (enabling all
+ * peripherals).
+ *
+ * For that, the reset driver checks the environment variable
+ * "socfpga_legacy_reset_compat". If this variable is '1', perihperals are not
+ * reset again once taken out of reset and all peripherals in 'permodrst' are
+ * taken out of reset before booting into the OS.
+ * Note that this should be required for gen5 systems only that are running
+ * Linux kernels without proper peripheral reset support for all drivers used.
+ */
+static bool socfpga_reset_keep_enabled(void)
+{
+#if !defined(CONFIG_SPL_BUILD) || CONFIG_IS_ENABLED(ENV_SUPPORT)
+ const char *env_str;
+ long val;
+
+ env_str = env_get("socfpga_legacy_reset_compat");
+ if (env_str) {
+ val = simple_strtol(env_str, NULL, 0);
+ if (val == 1)
+ return true;
+ }
+#endif
+
+ return false;
+}
+
static int socfpga_reset_assert(struct reset_ctl *reset_ctl)
{
struct socfpga_reset_data *data = dev_get_priv(reset_ctl->dev);
return 0;
}
+static int socfpga_reset_remove(struct udevice *dev)
+{
+ struct socfpga_reset_data *data = dev_get_priv(dev);
+
+ if (socfpga_reset_keep_enabled()) {
+ puts("Deasserting all peripheral resets\n");
+ writel(0, data->modrst_base + 4);
+ }
+
+ return 0;
+}
+
static const struct udevice_id socfpga_reset_match[] = {
{ .compatible = "altr,rst-mgr" },
{ /* sentinel */ },
.probe = socfpga_reset_probe,
.priv_auto_alloc_size = sizeof(struct socfpga_reset_data),
.ops = &socfpga_reset_ops,
+ .remove = socfpga_reset_remove,
+ .flags = DM_FLAG_OS_PREPARE,
};