aboutsummaryrefslogtreecommitdiff
path: root/drivers/reset/reset-microchip-sparx5.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/reset/reset-microchip-sparx5.c')
-rw-r--r--drivers/reset/reset-microchip-sparx5.c38
1 files changed, 37 insertions, 1 deletions
diff --git a/drivers/reset/reset-microchip-sparx5.c b/drivers/reset/reset-microchip-sparx5.c
index 636e85c388b0..aa5464be7053 100644
--- a/drivers/reset/reset-microchip-sparx5.c
+++ b/drivers/reset/reset-microchip-sparx5.c
@@ -62,6 +62,28 @@ static const struct reset_control_ops sparx5_reset_ops = {
.reset = sparx5_reset_noop,
};
+static const struct regmap_config mchp_lan966x_syscon_regmap_config = {
+ .reg_bits = 32,
+ .val_bits = 32,
+ .reg_stride = 4,
+};
+
+static struct regmap *mchp_lan966x_syscon_to_regmap(struct device *dev,
+ struct device_node *syscon_np)
+{
+ struct regmap_config regmap_config = mchp_lan966x_syscon_regmap_config;
+ resource_size_t size;
+ void __iomem *base;
+
+ base = devm_of_iomap(dev, syscon_np, 0, &size);
+ if (IS_ERR(base))
+ return ERR_CAST(base);
+
+ regmap_config.max_register = size - 4;
+
+ return devm_regmap_init_mmio(dev, base, &regmap_config);
+}
+
static int mchp_sparx5_map_syscon(struct platform_device *pdev, char *name,
struct regmap **target)
{
@@ -72,7 +94,18 @@ static int mchp_sparx5_map_syscon(struct platform_device *pdev, char *name,
syscon_np = of_parse_phandle(pdev->dev.of_node, name, 0);
if (!syscon_np)
return -ENODEV;
- regmap = syscon_node_to_regmap(syscon_np);
+
+ /*
+ * The syscon API doesn't support syscon device removal.
+ * When used in LAN966x PCI device, the cpu-syscon device needs to be
+ * removed when the PCI device is removed.
+ * In case of LAN966x, map the syscon device locally to support the
+ * device removal.
+ */
+ if (of_device_is_compatible(pdev->dev.of_node, "microchip,lan966x-switch-reset"))
+ regmap = mchp_lan966x_syscon_to_regmap(&pdev->dev, syscon_np);
+ else
+ regmap = syscon_node_to_regmap(syscon_np);
of_node_put(syscon_np);
if (IS_ERR(regmap)) {
err = PTR_ERR(regmap);
@@ -121,6 +154,7 @@ static int mchp_sparx5_reset_probe(struct platform_device *pdev)
return err;
ctx->rcdev.owner = THIS_MODULE;
+ ctx->rcdev.dev = &pdev->dev;
ctx->rcdev.nr_resets = 1;
ctx->rcdev.ops = &sparx5_reset_ops;
ctx->rcdev.of_node = dn;
@@ -158,6 +192,7 @@ static const struct of_device_id mchp_sparx5_reset_of_match[] = {
},
{ }
};
+MODULE_DEVICE_TABLE(of, mchp_sparx5_reset_of_match);
static struct platform_driver mchp_sparx5_reset_driver = {
.probe = mchp_sparx5_reset_probe,
@@ -180,3 +215,4 @@ postcore_initcall(mchp_sparx5_reset_init);
MODULE_DESCRIPTION("Microchip Sparx5 switch reset driver");
MODULE_AUTHOR("Steen Hegelund <steen.hegelund@microchip.com>");
+MODULE_LICENSE("GPL");