162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (c) 2013, The Linux Foundation. All rights reserved. 462306a36Sopenharmony_ci */ 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci#include <linux/bitops.h> 762306a36Sopenharmony_ci#include <linux/export.h> 862306a36Sopenharmony_ci#include <linux/regmap.h> 962306a36Sopenharmony_ci#include <linux/reset-controller.h> 1062306a36Sopenharmony_ci#include <linux/delay.h> 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci#include "reset.h" 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_cistatic int qcom_reset(struct reset_controller_dev *rcdev, unsigned long id) 1562306a36Sopenharmony_ci{ 1662306a36Sopenharmony_ci struct qcom_reset_controller *rst = to_qcom_reset_controller(rcdev); 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci rcdev->ops->assert(rcdev, id); 1962306a36Sopenharmony_ci fsleep(rst->reset_map[id].udelay ?: 1); /* use 1 us as default */ 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci rcdev->ops->deassert(rcdev, id); 2262306a36Sopenharmony_ci return 0; 2362306a36Sopenharmony_ci} 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_cistatic int qcom_reset_set_assert(struct reset_controller_dev *rcdev, 2662306a36Sopenharmony_ci unsigned long id, bool assert) 2762306a36Sopenharmony_ci{ 2862306a36Sopenharmony_ci struct qcom_reset_controller *rst; 2962306a36Sopenharmony_ci const struct qcom_reset_map *map; 3062306a36Sopenharmony_ci u32 mask; 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_ci rst = to_qcom_reset_controller(rcdev); 3362306a36Sopenharmony_ci map = &rst->reset_map[id]; 3462306a36Sopenharmony_ci mask = map->bitmask ? map->bitmask : BIT(map->bit); 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_ci regmap_update_bits(rst->regmap, map->reg, mask, assert ? mask : 0); 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_ci /* Read back the register to ensure write completion, ignore the value */ 3962306a36Sopenharmony_ci regmap_read(rst->regmap, map->reg, &mask); 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_ci return 0; 4262306a36Sopenharmony_ci} 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_cistatic int qcom_reset_assert(struct reset_controller_dev *rcdev, unsigned long id) 4562306a36Sopenharmony_ci{ 4662306a36Sopenharmony_ci return qcom_reset_set_assert(rcdev, id, true); 4762306a36Sopenharmony_ci} 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_cistatic int qcom_reset_deassert(struct reset_controller_dev *rcdev, unsigned long id) 5062306a36Sopenharmony_ci{ 5162306a36Sopenharmony_ci return qcom_reset_set_assert(rcdev, id, false); 5262306a36Sopenharmony_ci} 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ciconst struct reset_control_ops qcom_reset_ops = { 5562306a36Sopenharmony_ci .reset = qcom_reset, 5662306a36Sopenharmony_ci .assert = qcom_reset_assert, 5762306a36Sopenharmony_ci .deassert = qcom_reset_deassert, 5862306a36Sopenharmony_ci}; 5962306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(qcom_reset_ops); 60