brintos

brintos / linux-shallow public Read only

0
0
Text · 3.8 KiB · 56be64d Raw
153 lines · c
1// SPDX-License-Identifier: (GPL-2.0 OR MIT)2/*3 * Microsemi MIPS SoC reset driver4 *5 * License: Dual MIT/GPL6 * Copyright (c) 2017 Microsemi Corporation7 */8#include <linux/delay.h>9#include <linux/io.h>10#include <linux/notifier.h>11#include <linux/mod_devicetable.h>12#include <linux/mfd/syscon.h>13#include <linux/platform_device.h>14#include <linux/property.h>15#include <linux/reboot.h>16#include <linux/regmap.h>17 18struct reset_props {19	const char *syscon;20	u32 protect_reg;21	u32 vcore_protect;22	u32 if_si_owner_bit;23};24 25struct ocelot_reset_context {26	void __iomem *base;27	struct regmap *cpu_ctrl;28	const struct reset_props *props;29	struct notifier_block restart_handler;30};31 32#define BIT_OFF_INVALID				3233 34#define SOFT_CHIP_RST BIT(0)35 36#define ICPU_CFG_CPU_SYSTEM_CTRL_GENERAL_CTRL	0x2437#define IF_SI_OWNER_MASK			GENMASK(1, 0)38#define IF_SI_OWNER_SISL			039#define IF_SI_OWNER_SIBM			140#define IF_SI_OWNER_SIMC			241 42static int ocelot_restart_handle(struct notifier_block *this,43				 unsigned long mode, void *cmd)44{45	struct ocelot_reset_context *ctx = container_of(this, struct46							ocelot_reset_context,47							restart_handler);48	u32 if_si_owner_bit = ctx->props->if_si_owner_bit;49 50	/* Make sure the core is not protected from reset */51	regmap_update_bits(ctx->cpu_ctrl, ctx->props->protect_reg,52			   ctx->props->vcore_protect, 0);53 54	/* Make the SI back to boot mode */55	if (if_si_owner_bit != BIT_OFF_INVALID)56		regmap_update_bits(ctx->cpu_ctrl,57				   ICPU_CFG_CPU_SYSTEM_CTRL_GENERAL_CTRL,58				   IF_SI_OWNER_MASK << if_si_owner_bit,59				   IF_SI_OWNER_SIBM << if_si_owner_bit);60 61	pr_emerg("Resetting SoC\n");62 63	writel(SOFT_CHIP_RST, ctx->base);64 65	pr_emerg("Unable to restart system\n");66	return NOTIFY_DONE;67}68 69static int ocelot_reset_probe(struct platform_device *pdev)70{71	struct ocelot_reset_context *ctx;72	struct device *dev = &pdev->dev;73	int err;74 75	ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);76	if (!ctx)77		return -ENOMEM;78 79	ctx->base = devm_platform_ioremap_resource(pdev, 0);80	if (IS_ERR(ctx->base))81		return PTR_ERR(ctx->base);82 83	ctx->props = device_get_match_data(dev);84 85	ctx->cpu_ctrl = syscon_regmap_lookup_by_compatible(ctx->props->syscon);86	if (IS_ERR(ctx->cpu_ctrl)) {87		dev_err(dev, "No syscon map: %s\n", ctx->props->syscon);88		return PTR_ERR(ctx->cpu_ctrl);89	}90 91	ctx->restart_handler.notifier_call = ocelot_restart_handle;92	ctx->restart_handler.priority = 192;93	err = register_restart_handler(&ctx->restart_handler);94	if (err)95		dev_err(dev, "can't register restart notifier (err=%d)\n", err);96 97	return err;98}99 100static const struct reset_props reset_props_jaguar2 = {101	.syscon		 = "mscc,ocelot-cpu-syscon",102	.protect_reg     = 0x20,103	.vcore_protect   = BIT(2),104	.if_si_owner_bit = 6,105};106 107static const struct reset_props reset_props_luton = {108	.syscon		 = "mscc,ocelot-cpu-syscon",109	.protect_reg     = 0x20,110	.vcore_protect   = BIT(2),111	.if_si_owner_bit = BIT_OFF_INVALID, /* n/a */112};113 114static const struct reset_props reset_props_ocelot = {115	.syscon		 = "mscc,ocelot-cpu-syscon",116	.protect_reg     = 0x20,117	.vcore_protect   = BIT(2),118	.if_si_owner_bit = 4,119};120 121static const struct reset_props reset_props_sparx5 = {122	.syscon		 = "microchip,sparx5-cpu-syscon",123	.protect_reg     = 0x84,124	.vcore_protect   = BIT(10),125	.if_si_owner_bit = 6,126};127 128static const struct of_device_id ocelot_reset_of_match[] = {129	{130		.compatible = "mscc,jaguar2-chip-reset",131		.data = &reset_props_jaguar2132	}, {133		.compatible = "mscc,luton-chip-reset",134		.data = &reset_props_luton135	}, {136		.compatible = "mscc,ocelot-chip-reset",137		.data = &reset_props_ocelot138	}, {139		.compatible = "microchip,sparx5-chip-reset",140		.data = &reset_props_sparx5141	},142	{ /*sentinel*/ }143};144 145static struct platform_driver ocelot_reset_driver = {146	.probe = ocelot_reset_probe,147	.driver = {148		.name = "ocelot-chip-reset",149		.of_match_table = ocelot_reset_of_match,150	},151};152builtin_platform_driver(ocelot_reset_driver);153