1 // SPDX-License-Identifier: GPL-2.0-only
3 * Toshiba Visconti ARM SoC reset controller
5 * Copyright (c) 2021 TOSHIBA CORPORATION
6 * Copyright (c) 2021 Toshiba Electronic Devices & Storage Corporation
8 * Nobuhiro Iwamatsu <nobuhiro1.iwamatsu@toshiba.co.jp>
10 #include <linux/delay.h>
11 #include <linux/device.h>
12 #include <linux/mfd/syscon.h>
13 #include <linux/regmap.h>
14 #include <linux/slab.h>
18 static inline struct visconti_reset
*to_visconti_reset(struct reset_controller_dev
*rcdev
)
20 return container_of(rcdev
, struct visconti_reset
, rcdev
);
23 static int visconti_reset_assert(struct reset_controller_dev
*rcdev
, unsigned long id
)
25 struct visconti_reset
*reset
= to_visconti_reset(rcdev
);
26 const struct visconti_reset_data
*data
= &reset
->resets
[id
];
27 u32 rst
= BIT(data
->rs_idx
);
31 spin_lock_irqsave(reset
->lock
, flags
);
32 ret
= regmap_update_bits(reset
->regmap
, data
->rson_offset
, rst
, rst
);
33 spin_unlock_irqrestore(reset
->lock
, flags
);
38 static int visconti_reset_deassert(struct reset_controller_dev
*rcdev
, unsigned long id
)
40 struct visconti_reset
*reset
= to_visconti_reset(rcdev
);
41 const struct visconti_reset_data
*data
= &reset
->resets
[id
];
42 u32 rst
= BIT(data
->rs_idx
);
46 spin_lock_irqsave(reset
->lock
, flags
);
47 ret
= regmap_update_bits(reset
->regmap
, data
->rsoff_offset
, rst
, rst
);
48 spin_unlock_irqrestore(reset
->lock
, flags
);
53 static int visconti_reset_reset(struct reset_controller_dev
*rcdev
, unsigned long id
)
55 visconti_reset_assert(rcdev
, id
);
57 visconti_reset_deassert(rcdev
, id
);
62 static int visconti_reset_status(struct reset_controller_dev
*rcdev
, unsigned long id
)
64 struct visconti_reset
*reset
= to_visconti_reset(rcdev
);
65 const struct visconti_reset_data
*data
= &reset
->resets
[id
];
70 spin_lock_irqsave(reset
->lock
, flags
);
71 ret
= regmap_read(reset
->regmap
, data
->rson_offset
, ®
);
72 spin_unlock_irqrestore(reset
->lock
, flags
);
76 return !(reg
& data
->rs_idx
);
79 const struct reset_control_ops visconti_reset_ops
= {
80 .assert = visconti_reset_assert
,
81 .deassert
= visconti_reset_deassert
,
82 .reset
= visconti_reset_reset
,
83 .status
= visconti_reset_status
,
86 int visconti_register_reset_controller(struct device
*dev
,
87 struct regmap
*regmap
,
88 const struct visconti_reset_data
*resets
,
89 unsigned int num_resets
,
90 const struct reset_control_ops
*reset_ops
,
93 struct visconti_reset
*reset
;
95 reset
= devm_kzalloc(dev
, sizeof(*reset
), GFP_KERNEL
);
99 reset
->regmap
= regmap
;
100 reset
->resets
= resets
;
101 reset
->rcdev
.ops
= reset_ops
;
102 reset
->rcdev
.nr_resets
= num_resets
;
103 reset
->rcdev
.of_node
= dev
->of_node
;
106 return devm_reset_controller_register(dev
, &reset
->rcdev
);