2 * Pistachio SoC Reset Controller driver
4 * Copyright (C) 2015 Imagination Technologies Ltd.
6 * Author: Damien Horsley <Damien.Horsley@imgtec.com>
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms and conditions of the GNU General Public License,
10 * version 2, as published by the Free Software Foundation.
13 #include <linux/init.h>
15 #include <linux/platform_device.h>
16 #include <linux/regmap.h>
17 #include <linux/reset-controller.h>
18 #include <linux/slab.h>
19 #include <linux/mfd/syscon.h>
21 #include <dt-bindings/reset/pistachio-resets.h>
23 #define PISTACHIO_SOFT_RESET 0
25 struct pistachio_reset_data
{
26 struct reset_controller_dev rcdev
;
27 struct regmap
*periph_regs
;
30 static inline int pistachio_reset_shift(unsigned long id
)
33 case PISTACHIO_RESET_I2C0
:
34 case PISTACHIO_RESET_I2C1
:
35 case PISTACHIO_RESET_I2C2
:
36 case PISTACHIO_RESET_I2C3
:
37 case PISTACHIO_RESET_I2S_IN
:
38 case PISTACHIO_RESET_PRL_OUT
:
39 case PISTACHIO_RESET_SPDIF_OUT
:
40 case PISTACHIO_RESET_SPI
:
41 case PISTACHIO_RESET_PWM_PDM
:
42 case PISTACHIO_RESET_UART0
:
43 case PISTACHIO_RESET_UART1
:
44 case PISTACHIO_RESET_QSPI
:
45 case PISTACHIO_RESET_MDC
:
46 case PISTACHIO_RESET_SDHOST
:
47 case PISTACHIO_RESET_ETHERNET
:
48 case PISTACHIO_RESET_IR
:
49 case PISTACHIO_RESET_HASH
:
50 case PISTACHIO_RESET_TIMER
:
52 case PISTACHIO_RESET_I2S_OUT
:
53 case PISTACHIO_RESET_SPDIF_IN
:
54 case PISTACHIO_RESET_EVT
:
56 case PISTACHIO_RESET_USB_H
:
57 case PISTACHIO_RESET_USB_PR
:
58 case PISTACHIO_RESET_USB_PHY_PR
:
59 case PISTACHIO_RESET_USB_PHY_PON
:
66 static int pistachio_reset_assert(struct reset_controller_dev
*rcdev
,
69 struct pistachio_reset_data
*rd
;
73 rd
= container_of(rcdev
, struct pistachio_reset_data
, rcdev
);
74 shift
= pistachio_reset_shift(id
);
79 return regmap_update_bits(rd
->periph_regs
, PISTACHIO_SOFT_RESET
,
83 static int pistachio_reset_deassert(struct reset_controller_dev
*rcdev
,
86 struct pistachio_reset_data
*rd
;
90 rd
= container_of(rcdev
, struct pistachio_reset_data
, rcdev
);
91 shift
= pistachio_reset_shift(id
);
96 return regmap_update_bits(rd
->periph_regs
, PISTACHIO_SOFT_RESET
,
100 static const struct reset_control_ops pistachio_reset_ops
= {
101 .assert = pistachio_reset_assert
,
102 .deassert
= pistachio_reset_deassert
,
105 static int pistachio_reset_probe(struct platform_device
*pdev
)
107 struct pistachio_reset_data
*rd
;
108 struct device
*dev
= &pdev
->dev
;
109 struct device_node
*np
= pdev
->dev
.of_node
;
111 rd
= devm_kzalloc(dev
, sizeof(*rd
), GFP_KERNEL
);
115 rd
->periph_regs
= syscon_node_to_regmap(np
->parent
);
116 if (IS_ERR(rd
->periph_regs
))
117 return PTR_ERR(rd
->periph_regs
);
119 rd
->rcdev
.owner
= THIS_MODULE
;
120 rd
->rcdev
.nr_resets
= PISTACHIO_RESET_MAX
+ 1;
121 rd
->rcdev
.ops
= &pistachio_reset_ops
;
122 rd
->rcdev
.of_node
= np
;
124 return devm_reset_controller_register(dev
, &rd
->rcdev
);
127 static const struct of_device_id pistachio_reset_dt_ids
[] = {
128 { .compatible
= "img,pistachio-reset", },
132 static struct platform_driver pistachio_reset_driver
= {
133 .probe
= pistachio_reset_probe
,
135 .name
= "pistachio-reset",
136 .of_match_table
= pistachio_reset_dt_ids
,
139 builtin_platform_driver(pistachio_reset_driver
);