1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) STMicroelectronics 2018 - All Rights Reserved
4 * Author: Gabriel Fernandez <gabriel.fernandez@st.com> for STMicroelectronics.
7 #include <linux/device.h>
11 #include <linux/platform_device.h>
12 #include <linux/reset-controller.h>
14 #define CLR_OFFSET 0x4
16 struct stm32_reset_data
{
17 struct reset_controller_dev rcdev
;
18 void __iomem
*membase
;
21 static inline struct stm32_reset_data
*
22 to_stm32_reset_data(struct reset_controller_dev
*rcdev
)
24 return container_of(rcdev
, struct stm32_reset_data
, rcdev
);
27 static int stm32_reset_update(struct reset_controller_dev
*rcdev
,
28 unsigned long id
, bool assert)
30 struct stm32_reset_data
*data
= to_stm32_reset_data(rcdev
);
31 int reg_width
= sizeof(u32
);
32 int bank
= id
/ (reg_width
* BITS_PER_BYTE
);
33 int offset
= id
% (reg_width
* BITS_PER_BYTE
);
36 addr
= data
->membase
+ (bank
* reg_width
);
40 writel(BIT(offset
), addr
);
45 static int stm32_reset_assert(struct reset_controller_dev
*rcdev
,
48 return stm32_reset_update(rcdev
, id
, true);
51 static int stm32_reset_deassert(struct reset_controller_dev
*rcdev
,
54 return stm32_reset_update(rcdev
, id
, false);
57 static int stm32_reset_status(struct reset_controller_dev
*rcdev
,
60 struct stm32_reset_data
*data
= to_stm32_reset_data(rcdev
);
61 int reg_width
= sizeof(u32
);
62 int bank
= id
/ (reg_width
* BITS_PER_BYTE
);
63 int offset
= id
% (reg_width
* BITS_PER_BYTE
);
66 reg
= readl(data
->membase
+ (bank
* reg_width
));
68 return !!(reg
& BIT(offset
));
71 static const struct reset_control_ops stm32_reset_ops
= {
72 .assert = stm32_reset_assert
,
73 .deassert
= stm32_reset_deassert
,
74 .status
= stm32_reset_status
,
77 static const struct of_device_id stm32_reset_dt_ids
[] = {
78 { .compatible
= "st,stm32mp1-rcc"},
82 static int stm32_reset_probe(struct platform_device
*pdev
)
84 struct device
*dev
= &pdev
->dev
;
85 struct stm32_reset_data
*data
;
86 void __iomem
*membase
;
89 data
= devm_kzalloc(dev
, sizeof(*data
), GFP_KERNEL
);
93 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
94 membase
= devm_ioremap_resource(dev
, res
);
96 return PTR_ERR(membase
);
98 data
->membase
= membase
;
99 data
->rcdev
.owner
= THIS_MODULE
;
100 data
->rcdev
.nr_resets
= resource_size(res
) * BITS_PER_BYTE
;
101 data
->rcdev
.ops
= &stm32_reset_ops
;
102 data
->rcdev
.of_node
= dev
->of_node
;
104 return devm_reset_controller_register(dev
, &data
->rcdev
);
107 static struct platform_driver stm32_reset_driver
= {
108 .probe
= stm32_reset_probe
,
110 .name
= "stm32mp1-reset",
111 .of_match_table
= stm32_reset_dt_ids
,
115 builtin_platform_driver(stm32_reset_driver
);