lkml.org 
[lkml]   [2020]   [May]   [13]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[PATCH 4/5] power: reset: ocelot: Add support for reset switch on load time
Date
This patch add support for resetting the networking switch core at
reset driver load time. It is useful in order to bring the switch core
in a known state after a reboot or after a bootloader may have been
using the switch for network access.

Signed-off-by: Lars Povlsen <lars.povlsen@microchip.com>
---
drivers/power/reset/ocelot-reset.c | 40 ++++++++++++++++++++++++++++--
1 file changed, 38 insertions(+), 2 deletions(-)

diff --git a/drivers/power/reset/ocelot-reset.c b/drivers/power/reset/ocelot-reset.c
index f74e1dbb4ba36..a203c42e99d42 100644
--- a/drivers/power/reset/ocelot-reset.c
+++ b/drivers/power/reset/ocelot-reset.c
@@ -29,6 +29,7 @@ struct ocelot_reset_context {
struct notifier_block restart_handler;
};

+#define SOFT_SWC_RST BIT(1)
#define SOFT_CHIP_RST BIT(0)

#define ICPU_CFG_CPU_SYSTEM_CTRL_GENERAL_CTRL 0x24
@@ -37,6 +38,32 @@ struct ocelot_reset_context {
#define IF_SI_OWNER_SIBM 1
#define IF_SI_OWNER_SIMC 2

+static int ocelot_switch_core_reset(const struct ocelot_reset_context *ctx)
+{
+
+ const char *driver = "ocelot-reset";
+ int timeout;
+
+ pr_notice("%s: Resetting Switch Core\n", driver);
+
+ /* Make sure the core is PROTECTED from reset */
+ regmap_update_bits(ctx->cpu_ctrl, ctx->props->protect_reg,
+ ctx->props->vcore_protect,
+ ctx->props->vcore_protect);
+
+ writel(SOFT_SWC_RST, ctx->base);
+ for (timeout = 0; timeout < 100; timeout++) {
+ if ((readl(ctx->base) & SOFT_SWC_RST) == 0) {
+ pr_debug("%s: Switch Core Reset complete.\n", driver);
+ return 0;
+ }
+ udelay(1);
+ }
+
+ pr_warn("%s: Switch Core Reset timeout!\n", driver);
+ return -ENXIO;
+}
+
static int ocelot_restart_handle(struct notifier_block *this,
unsigned long mode, void *cmd)
{
@@ -66,7 +93,6 @@ static int ocelot_reset_probe(struct platform_device *pdev)
{
struct ocelot_reset_context *ctx;
struct resource *res;
-
struct device *dev = &pdev->dev;
int err;

@@ -87,6 +113,11 @@ static int ocelot_reset_probe(struct platform_device *pdev)
return PTR_ERR(ctx->cpu_ctrl);
}

+ /* Optionally, call switch reset function */
+ if (of_property_read_bool(pdev->dev.of_node,
+ "microchip,reset-switch-core"))
+ ocelot_switch_core_reset(ctx);
+
ctx->restart_handler.notifier_call = ocelot_restart_handle;
ctx->restart_handler.priority = 192;
err = register_restart_handler(&ctx->restart_handler);
@@ -128,4 +159,9 @@ static struct platform_driver ocelot_reset_driver = {
.of_match_table = ocelot_reset_of_match,
},
};
-builtin_platform_driver(ocelot_reset_driver);
+
+static int __init reset_init(void)
+{
+ return platform_driver_register(&ocelot_reset_driver);
+}
+postcore_initcall(reset_init);
--
2.26.2
\
 
 \ /
  Last update: 2020-05-13 15:10    [W:0.074 / U:0.588 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site