uboot/drivers/reset/reset-mediatek.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Copyright (C) 2018 MediaTek Inc.
   4 *
   5 * Author: Ryder Lee <ryder.lee@mediatek.com>
   6 *         Weijie Gao <weijie.gao@mediatek.com>
   7 */
   8
   9#include <common.h>
  10#include <dm.h>
  11#include <dm/lists.h>
  12#include <regmap.h>
  13#include <reset-uclass.h>
  14#include <syscon.h>
  15
  16struct mediatek_reset_priv {
  17        struct regmap *regmap;
  18        u32 regofs;
  19        u32 nr_resets;
  20};
  21
  22static int mediatek_reset_request(struct reset_ctl *reset_ctl)
  23{
  24        return 0;
  25}
  26
  27static int mediatek_reset_free(struct reset_ctl *reset_ctl)
  28{
  29        return 0;
  30}
  31
  32static int mediatek_reset_assert(struct reset_ctl *reset_ctl)
  33{
  34        struct mediatek_reset_priv *priv = dev_get_priv(reset_ctl->dev);
  35        int id = reset_ctl->id;
  36
  37        if (id >= priv->nr_resets)
  38                return -EINVAL;
  39
  40        return regmap_update_bits(priv->regmap,
  41                priv->regofs + ((id / 32) << 2), BIT(id % 32), BIT(id % 32));
  42}
  43
  44static int mediatek_reset_deassert(struct reset_ctl *reset_ctl)
  45{
  46        struct mediatek_reset_priv *priv = dev_get_priv(reset_ctl->dev);
  47        int id = reset_ctl->id;
  48
  49        if (id >= priv->nr_resets)
  50                return -EINVAL;
  51
  52        return regmap_update_bits(priv->regmap,
  53                priv->regofs + ((id / 32) << 2), BIT(id % 32), 0);
  54}
  55
  56struct reset_ops mediatek_reset_ops = {
  57        .request = mediatek_reset_request,
  58        .free = mediatek_reset_free,
  59        .rst_assert = mediatek_reset_assert,
  60        .rst_deassert = mediatek_reset_deassert,
  61};
  62
  63static int mediatek_reset_probe(struct udevice *dev)
  64{
  65        struct mediatek_reset_priv *priv = dev_get_priv(dev);
  66
  67        if (!priv->regofs && !priv->nr_resets)
  68                return -EINVAL;
  69
  70        priv->regmap = syscon_node_to_regmap(dev_ofnode(dev));
  71        if (IS_ERR(priv->regmap))
  72                return PTR_ERR(priv->regmap);
  73
  74        return 0;
  75}
  76
  77int mediatek_reset_bind(struct udevice *pdev, u32 regofs, u32 num_regs)
  78{
  79        struct udevice *rst_dev;
  80        struct mediatek_reset_priv *priv;
  81        int ret;
  82
  83        ret = device_bind_driver_to_node(pdev, "mediatek_reset", "reset",
  84                                         dev_ofnode(pdev), &rst_dev);
  85        if (ret)
  86                return ret;
  87
  88        priv = malloc(sizeof(struct mediatek_reset_priv));
  89        priv->regofs = regofs;
  90        priv->nr_resets = num_regs * 32;
  91        rst_dev->priv = priv;
  92
  93        return 0;
  94}
  95
  96U_BOOT_DRIVER(mediatek_reset) = {
  97        .name = "mediatek_reset",
  98        .id = UCLASS_RESET,
  99        .probe = mediatek_reset_probe,
 100        .ops = &mediatek_reset_ops,
 101        .priv_auto_alloc_size = sizeof(struct mediatek_reset_priv),
 102};
 103