uboot/drivers/reset/reset-syscon.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Copyright (C) 2020 Sean Anderson
   4 */
   5
   6#include <common.h>
   7#include <dm.h>
   8#include <regmap.h>
   9#include <reset.h>
  10#include <reset-uclass.h>
  11#include <syscon.h>
  12#include <linux/bitops.h>
  13#include <linux/err.h>
  14
  15struct syscon_reset_priv {
  16        struct regmap *regmap;
  17        uint offset;
  18        uint mask;
  19        bool assert_high;
  20};
  21
  22static int syscon_reset_request(struct reset_ctl *rst)
  23{
  24        struct syscon_reset_priv *priv = dev_get_priv(rst->dev);
  25
  26        if (BIT(rst->id) & priv->mask)
  27                return 0;
  28        else
  29                return -EINVAL;
  30}
  31
  32static int syscon_reset_assert(struct reset_ctl *rst)
  33{
  34        struct syscon_reset_priv *priv = dev_get_priv(rst->dev);
  35
  36        return regmap_update_bits(priv->regmap, priv->offset, BIT(rst->id),
  37                                  priv->assert_high ? BIT(rst->id) : 0);
  38}
  39
  40static int syscon_reset_deassert(struct reset_ctl *rst)
  41{
  42        struct syscon_reset_priv *priv = dev_get_priv(rst->dev);
  43
  44        return regmap_update_bits(priv->regmap, priv->offset, BIT(rst->id),
  45                                  priv->assert_high ? 0 : BIT(rst->id));
  46}
  47
  48static const struct reset_ops syscon_reset_ops = {
  49        .request = syscon_reset_request,
  50        .rst_assert = syscon_reset_assert,
  51        .rst_deassert = syscon_reset_deassert,
  52};
  53
  54int syscon_reset_probe(struct udevice *dev)
  55{
  56        struct syscon_reset_priv *priv = dev_get_priv(dev);
  57
  58        priv->regmap = syscon_regmap_lookup_by_phandle(dev, "regmap");
  59        if (IS_ERR(priv->regmap))
  60                return -ENODEV;
  61
  62        priv->offset = dev_read_u32_default(dev, "offset", 0);
  63        priv->mask = dev_read_u32_default(dev, "mask", 0);
  64        priv->assert_high = dev_read_u32_default(dev, "assert-high", true);
  65
  66        return 0;
  67}
  68
  69static const struct udevice_id syscon_reset_ids[] = {
  70        { .compatible = "syscon-reset" },
  71        { },
  72};
  73
  74U_BOOT_DRIVER(syscon_reset) = {
  75        .name = "syscon_reset",
  76        .id = UCLASS_RESET,
  77        .of_match = syscon_reset_ids,
  78        .probe = syscon_reset_probe,
  79        .priv_auto      = sizeof(struct syscon_reset_priv),
  80        .ops = &syscon_reset_ops,
  81};
  82