[PATCH 2/2] reset: simple: Enable stm32mp1 reset driver

From: gabriel.fernandez
Date: Tue Mar 13 2018 - 12:35:29 EST


From: Gabriel Fernandez <gabriel.fernandez@xxxxxx>

The stm32mp1 reset driver is quite similar to simple reset driver.
The difference is that stm32mp1 has a reset SET register and
a reset CLEAR register.

Writing '0' on reset SET register has no effect
Writing '1' on reset SET register
activates the reset of the corresponding peripheral

Writing '0' on reset CLEAR register has no effect
Writing '1' on reset CLEAR register
releases the reset of the corresponding peripheral

Signed-off-by: Gabriel Fernandez <gabriel.fernandez@xxxxxx>
---
drivers/reset/reset-simple.c | 27 +++++++++++++++++++++------
drivers/reset/reset-simple.h | 1 +
2 files changed, 22 insertions(+), 6 deletions(-)

diff --git a/drivers/reset/reset-simple.c b/drivers/reset/reset-simple.c
index f7ce891..57ecb49 100644
--- a/drivers/reset/reset-simple.c
+++ b/drivers/reset/reset-simple.c
@@ -41,15 +41,23 @@ static int reset_simple_update(struct reset_controller_dev *rcdev,
int offset = id % (reg_width * BITS_PER_BYTE);
unsigned long flags;
u32 reg;
+ void __iomem *addr;

spin_lock_irqsave(&data->lock, flags);

- reg = readl(data->membase + (bank * reg_width));
- if (assert ^ data->active_low)
- reg |= BIT(offset);
- else
- reg &= ~BIT(offset);
- writel(reg, data->membase + (bank * reg_width));
+ addr = data->membase + (bank * reg_width);
+ if (data->clr_offset) {
+ reg = BIT(offset);
+ if (!assert)
+ addr += data->clr_offset;
+ } else {
+ reg = readl(addr);
+ if (assert ^ data->active_low)
+ reg |= BIT(offset);
+ else
+ reg &= ~BIT(offset);
+ }
+ writel(reg, addr);

spin_unlock_irqrestore(&data->lock, flags);

@@ -103,6 +111,7 @@ struct reset_simple_devdata {
u32 nr_resets;
bool active_low;
bool status_active_low;
+ u32 clr_offset;
};

#define SOCFPGA_NR_BANKS 8
@@ -118,9 +127,14 @@ struct reset_simple_devdata {
.status_active_low = true,
};

+struct reset_simple_devdata reset_stm32mp1 = {
+ .clr_offset = 0x4,
+};
+
static const struct of_device_id reset_simple_dt_ids[] = {
{ .compatible = "altr,rst-mgr", .data = &reset_simple_socfpga },
{ .compatible = "st,stm32-rcc", },
+ { .compatible = "st,stm32mp1-rcc", .data = &reset_stm32mp1},
{ .compatible = "allwinner,sun6i-a31-clock-reset",
.data = &reset_simple_active_low },
{ .compatible = "zte,zx296718-reset",
@@ -163,6 +177,7 @@ static int reset_simple_probe(struct platform_device *pdev)
data->rcdev.nr_resets = devdata->nr_resets;
data->active_low = devdata->active_low;
data->status_active_low = devdata->status_active_low;
+ data->clr_offset = devdata->clr_offset;
}

if (of_device_is_compatible(dev->of_node, "altr,rst-mgr") &&
diff --git a/drivers/reset/reset-simple.h b/drivers/reset/reset-simple.h
index 8a49602..0bbdd34 100644
--- a/drivers/reset/reset-simple.h
+++ b/drivers/reset/reset-simple.h
@@ -38,6 +38,7 @@ struct reset_simple_data {
struct reset_controller_dev rcdev;
bool active_low;
bool status_active_low;
+ u32 clr_offset;
};

extern const struct reset_control_ops reset_simple_ops;
--
1.9.1