mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-26 14:40:41 +00:00
41575d8e4c
This construct is quite long-winded. In earlier days it made some sense since auto-allocation was a strange concept. But with driver model now used pretty universally, we can shorten this to 'auto'. This reduces verbosity and makes it easier to read. Coincidentally it also ensures that every declaration is on one line, thus making dtoc's job easier. Signed-off-by: Simon Glass <sjg@chromium.org>
93 lines
2.1 KiB
C
93 lines
2.1 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
/*
|
|
* Amlogic Meson Reset Controller driver
|
|
*
|
|
* Copyright (c) 2018 BayLibre, SAS.
|
|
* Author: Neil Armstrong <narmstrong@baylibre.com>
|
|
*/
|
|
|
|
#include <common.h>
|
|
#include <dm.h>
|
|
#include <log.h>
|
|
#include <malloc.h>
|
|
#include <reset-uclass.h>
|
|
#include <regmap.h>
|
|
#include <linux/bitops.h>
|
|
|
|
#define REG_COUNT 8
|
|
#define BITS_PER_REG 32
|
|
#define LEVEL_OFFSET 0x7c
|
|
|
|
struct meson_reset_priv {
|
|
struct regmap *regmap;
|
|
};
|
|
|
|
static int meson_reset_request(struct reset_ctl *reset_ctl)
|
|
{
|
|
if (reset_ctl->id > (REG_COUNT * BITS_PER_REG))
|
|
return -EINVAL;
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int meson_reset_free(struct reset_ctl *reset_ctl)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static int meson_reset_level(struct reset_ctl *reset_ctl, bool assert)
|
|
{
|
|
struct meson_reset_priv *priv = dev_get_priv(reset_ctl->dev);
|
|
uint bank = reset_ctl->id / BITS_PER_REG;
|
|
uint offset = reset_ctl->id % BITS_PER_REG;
|
|
uint reg_offset = LEVEL_OFFSET + (bank << 2);
|
|
uint val;
|
|
|
|
regmap_read(priv->regmap, reg_offset, &val);
|
|
if (assert)
|
|
val &= ~BIT(offset);
|
|
else
|
|
val |= BIT(offset);
|
|
regmap_write(priv->regmap, reg_offset, val);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int meson_reset_assert(struct reset_ctl *reset_ctl)
|
|
{
|
|
return meson_reset_level(reset_ctl, true);
|
|
}
|
|
|
|
static int meson_reset_deassert(struct reset_ctl *reset_ctl)
|
|
{
|
|
return meson_reset_level(reset_ctl, false);
|
|
}
|
|
|
|
struct reset_ops meson_reset_ops = {
|
|
.request = meson_reset_request,
|
|
.rfree = meson_reset_free,
|
|
.rst_assert = meson_reset_assert,
|
|
.rst_deassert = meson_reset_deassert,
|
|
};
|
|
|
|
static const struct udevice_id meson_reset_ids[] = {
|
|
{ .compatible = "amlogic,meson-gxbb-reset" },
|
|
{ .compatible = "amlogic,meson-axg-reset" },
|
|
{ }
|
|
};
|
|
|
|
static int meson_reset_probe(struct udevice *dev)
|
|
{
|
|
struct meson_reset_priv *priv = dev_get_priv(dev);
|
|
|
|
return regmap_init_mem(dev_ofnode(dev), &priv->regmap);
|
|
}
|
|
|
|
U_BOOT_DRIVER(meson_reset) = {
|
|
.name = "meson_reset",
|
|
.id = UCLASS_RESET,
|
|
.of_match = meson_reset_ids,
|
|
.probe = meson_reset_probe,
|
|
.ops = &meson_reset_ops,
|
|
.priv_auto = sizeof(struct meson_reset_priv),
|
|
};
|