Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Copyright (C) 2016 Maxime Ripard
0004  * Maxime Ripard <maxime.ripard@free-electrons.com>
0005  */
0006 
0007 #include <linux/delay.h>
0008 #include <linux/io.h>
0009 #include <linux/reset-controller.h>
0010 
0011 #include "ccu_reset.h"
0012 
0013 static int ccu_reset_assert(struct reset_controller_dev *rcdev,
0014                 unsigned long id)
0015 {
0016     struct ccu_reset *ccu = rcdev_to_ccu_reset(rcdev);
0017     const struct ccu_reset_map *map = &ccu->reset_map[id];
0018     unsigned long flags;
0019     u32 reg;
0020 
0021     spin_lock_irqsave(ccu->lock, flags);
0022 
0023     reg = readl(ccu->base + map->reg);
0024     writel(reg & ~map->bit, ccu->base + map->reg);
0025 
0026     spin_unlock_irqrestore(ccu->lock, flags);
0027 
0028     return 0;
0029 }
0030 
0031 static int ccu_reset_deassert(struct reset_controller_dev *rcdev,
0032                   unsigned long id)
0033 {
0034     struct ccu_reset *ccu = rcdev_to_ccu_reset(rcdev);
0035     const struct ccu_reset_map *map = &ccu->reset_map[id];
0036     unsigned long flags;
0037     u32 reg;
0038 
0039     spin_lock_irqsave(ccu->lock, flags);
0040 
0041     reg = readl(ccu->base + map->reg);
0042     writel(reg | map->bit, ccu->base + map->reg);
0043 
0044     spin_unlock_irqrestore(ccu->lock, flags);
0045 
0046     return 0;
0047 }
0048 
0049 static int ccu_reset_reset(struct reset_controller_dev *rcdev,
0050                unsigned long id)
0051 {
0052     ccu_reset_assert(rcdev, id);
0053     udelay(10);
0054     ccu_reset_deassert(rcdev, id);
0055 
0056     return 0;
0057 }
0058 
0059 static int ccu_reset_status(struct reset_controller_dev *rcdev,
0060                 unsigned long id)
0061 {
0062     struct ccu_reset *ccu = rcdev_to_ccu_reset(rcdev);
0063     const struct ccu_reset_map *map = &ccu->reset_map[id];
0064 
0065     /*
0066      * The reset control API expects 0 if reset is not asserted,
0067      * which is the opposite of what our hardware uses.
0068      */
0069     return !(map->bit & readl(ccu->base + map->reg));
0070 }
0071 
0072 const struct reset_control_ops ccu_reset_ops = {
0073     .assert     = ccu_reset_assert,
0074     .deassert   = ccu_reset_deassert,
0075     .reset      = ccu_reset_reset,
0076     .status     = ccu_reset_status,
0077 };
0078 EXPORT_SYMBOL_NS_GPL(ccu_reset_ops, SUNXI_CCU);