1 // SPDX-License-Identifier: GPL-2.0-only
3 * Pistachio SoC Reset Controller driver
5 * Copyright (C) 2015 Imagination Technologies Ltd.
7 * Author: Damien Horsley <Damien.Horsley@imgtec.com>
10 #include <linux/init.h>
12 #include <linux/platform_device.h>
13 #include <linux/regmap.h>
14 #include <linux/reset-controller.h>
15 #include <linux/slab.h>
16 #include <linux/mfd/syscon.h>
18 #include <dt-bindings/reset/pistachio-resets.h>
20 #define PISTACHIO_SOFT_RESET 0
22 struct pistachio_reset_data
{
23 struct reset_controller_dev rcdev
;
24 struct regmap
*periph_regs
;
27 static inline int pistachio_reset_shift(unsigned long id
)
30 case PISTACHIO_RESET_I2C0
:
31 case PISTACHIO_RESET_I2C1
:
32 case PISTACHIO_RESET_I2C2
:
33 case PISTACHIO_RESET_I2C3
:
34 case PISTACHIO_RESET_I2S_IN
:
35 case PISTACHIO_RESET_PRL_OUT
:
36 case PISTACHIO_RESET_SPDIF_OUT
:
37 case PISTACHIO_RESET_SPI
:
38 case PISTACHIO_RESET_PWM_PDM
:
39 case PISTACHIO_RESET_UART0
:
40 case PISTACHIO_RESET_UART1
:
41 case PISTACHIO_RESET_QSPI
:
42 case PISTACHIO_RESET_MDC
:
43 case PISTACHIO_RESET_SDHOST
:
44 case PISTACHIO_RESET_ETHERNET
:
45 case PISTACHIO_RESET_IR
:
46 case PISTACHIO_RESET_HASH
:
47 case PISTACHIO_RESET_TIMER
:
49 case PISTACHIO_RESET_I2S_OUT
:
50 case PISTACHIO_RESET_SPDIF_IN
:
51 case PISTACHIO_RESET_EVT
:
53 case PISTACHIO_RESET_USB_H
:
54 case PISTACHIO_RESET_USB_PR
:
55 case PISTACHIO_RESET_USB_PHY_PR
:
56 case PISTACHIO_RESET_USB_PHY_PON
:
63 static int pistachio_reset_assert(struct reset_controller_dev
*rcdev
,
66 struct pistachio_reset_data
*rd
;
70 rd
= container_of(rcdev
, struct pistachio_reset_data
, rcdev
);
71 shift
= pistachio_reset_shift(id
);
76 return regmap_update_bits(rd
->periph_regs
, PISTACHIO_SOFT_RESET
,
80 static int pistachio_reset_deassert(struct reset_controller_dev
*rcdev
,
83 struct pistachio_reset_data
*rd
;
87 rd
= container_of(rcdev
, struct pistachio_reset_data
, rcdev
);
88 shift
= pistachio_reset_shift(id
);
93 return regmap_update_bits(rd
->periph_regs
, PISTACHIO_SOFT_RESET
,
97 static const struct reset_control_ops pistachio_reset_ops
= {
98 .assert = pistachio_reset_assert
,
99 .deassert
= pistachio_reset_deassert
,
102 static int pistachio_reset_probe(struct platform_device
*pdev
)
104 struct pistachio_reset_data
*rd
;
105 struct device
*dev
= &pdev
->dev
;
106 struct device_node
*np
= pdev
->dev
.of_node
;
108 rd
= devm_kzalloc(dev
, sizeof(*rd
), GFP_KERNEL
);
112 rd
->periph_regs
= syscon_node_to_regmap(np
->parent
);
113 if (IS_ERR(rd
->periph_regs
))
114 return PTR_ERR(rd
->periph_regs
);
116 rd
->rcdev
.owner
= THIS_MODULE
;
117 rd
->rcdev
.nr_resets
= PISTACHIO_RESET_MAX
+ 1;
118 rd
->rcdev
.ops
= &pistachio_reset_ops
;
119 rd
->rcdev
.of_node
= np
;
121 return devm_reset_controller_register(dev
, &rd
->rcdev
);
124 static const struct of_device_id pistachio_reset_dt_ids
[] = {
125 { .compatible
= "img,pistachio-reset", },
129 static struct platform_driver pistachio_reset_driver
= {
130 .probe
= pistachio_reset_probe
,
132 .name
= "pistachio-reset",
133 .of_match_table
= pistachio_reset_dt_ids
,
136 builtin_platform_driver(pistachio_reset_driver
);