18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 28c2ecf20Sopenharmony_ci// 38c2ecf20Sopenharmony_ci// Actions Semi Owl SoCs Reset Management Unit driver 48c2ecf20Sopenharmony_ci// 58c2ecf20Sopenharmony_ci// Copyright (c) 2018 Linaro Ltd. 68c2ecf20Sopenharmony_ci// Author: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci#include <linux/delay.h> 98c2ecf20Sopenharmony_ci#include <linux/regmap.h> 108c2ecf20Sopenharmony_ci#include <linux/reset-controller.h> 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ci#include "owl-reset.h" 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_cistatic int owl_reset_assert(struct reset_controller_dev *rcdev, 158c2ecf20Sopenharmony_ci unsigned long id) 168c2ecf20Sopenharmony_ci{ 178c2ecf20Sopenharmony_ci struct owl_reset *reset = to_owl_reset(rcdev); 188c2ecf20Sopenharmony_ci const struct owl_reset_map *map = &reset->reset_map[id]; 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_ci return regmap_update_bits(reset->regmap, map->reg, map->bit, 0); 218c2ecf20Sopenharmony_ci} 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_cistatic int owl_reset_deassert(struct reset_controller_dev *rcdev, 248c2ecf20Sopenharmony_ci unsigned long id) 258c2ecf20Sopenharmony_ci{ 268c2ecf20Sopenharmony_ci struct owl_reset *reset = to_owl_reset(rcdev); 278c2ecf20Sopenharmony_ci const struct owl_reset_map *map = &reset->reset_map[id]; 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_ci return regmap_update_bits(reset->regmap, map->reg, map->bit, map->bit); 308c2ecf20Sopenharmony_ci} 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_cistatic int owl_reset_reset(struct reset_controller_dev *rcdev, 338c2ecf20Sopenharmony_ci unsigned long id) 348c2ecf20Sopenharmony_ci{ 358c2ecf20Sopenharmony_ci owl_reset_assert(rcdev, id); 368c2ecf20Sopenharmony_ci udelay(1); 378c2ecf20Sopenharmony_ci owl_reset_deassert(rcdev, id); 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_ci return 0; 408c2ecf20Sopenharmony_ci} 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_cistatic int owl_reset_status(struct reset_controller_dev *rcdev, 438c2ecf20Sopenharmony_ci unsigned long id) 448c2ecf20Sopenharmony_ci{ 458c2ecf20Sopenharmony_ci struct owl_reset *reset = to_owl_reset(rcdev); 468c2ecf20Sopenharmony_ci const struct owl_reset_map *map = &reset->reset_map[id]; 478c2ecf20Sopenharmony_ci u32 reg; 488c2ecf20Sopenharmony_ci int ret; 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_ci ret = regmap_read(reset->regmap, map->reg, ®); 518c2ecf20Sopenharmony_ci if (ret) 528c2ecf20Sopenharmony_ci return ret; 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_ci /* 558c2ecf20Sopenharmony_ci * The reset control API expects 0 if reset is not asserted, 568c2ecf20Sopenharmony_ci * which is the opposite of what our hardware uses. 578c2ecf20Sopenharmony_ci */ 588c2ecf20Sopenharmony_ci return !(map->bit & reg); 598c2ecf20Sopenharmony_ci} 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ciconst struct reset_control_ops owl_reset_ops = { 628c2ecf20Sopenharmony_ci .assert = owl_reset_assert, 638c2ecf20Sopenharmony_ci .deassert = owl_reset_deassert, 648c2ecf20Sopenharmony_ci .reset = owl_reset_reset, 658c2ecf20Sopenharmony_ci .status = owl_reset_status, 668c2ecf20Sopenharmony_ci}; 67