cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

reset-oxnas.c (2785B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Oxford Semiconductor Reset Controller driver
      4 *
      5 * Copyright (C) 2016 Neil Armstrong <narmstrong@baylibre.com>
      6 * Copyright (C) 2014 Ma Haijun <mahaijuns@gmail.com>
      7 * Copyright (C) 2009 Oxford Semiconductor Ltd
      8 */
      9#include <linux/err.h>
     10#include <linux/init.h>
     11#include <linux/of.h>
     12#include <linux/platform_device.h>
     13#include <linux/reset-controller.h>
     14#include <linux/slab.h>
     15#include <linux/delay.h>
     16#include <linux/types.h>
     17#include <linux/regmap.h>
     18#include <linux/mfd/syscon.h>
     19
     20/* Regmap offsets */
     21#define RST_SET_REGOFFSET	0x34
     22#define RST_CLR_REGOFFSET	0x38
     23
     24struct oxnas_reset {
     25	struct regmap *regmap;
     26	struct reset_controller_dev rcdev;
     27};
     28
     29static int oxnas_reset_reset(struct reset_controller_dev *rcdev,
     30			      unsigned long id)
     31{
     32	struct oxnas_reset *data =
     33		container_of(rcdev, struct oxnas_reset, rcdev);
     34
     35	regmap_write(data->regmap, RST_SET_REGOFFSET, BIT(id));
     36	msleep(50);
     37	regmap_write(data->regmap, RST_CLR_REGOFFSET, BIT(id));
     38
     39	return 0;
     40}
     41
     42static int oxnas_reset_assert(struct reset_controller_dev *rcdev,
     43			      unsigned long id)
     44{
     45	struct oxnas_reset *data =
     46		container_of(rcdev, struct oxnas_reset, rcdev);
     47
     48	regmap_write(data->regmap, RST_SET_REGOFFSET, BIT(id));
     49
     50	return 0;
     51}
     52
     53static int oxnas_reset_deassert(struct reset_controller_dev *rcdev,
     54				unsigned long id)
     55{
     56	struct oxnas_reset *data =
     57		container_of(rcdev, struct oxnas_reset, rcdev);
     58
     59	regmap_write(data->regmap, RST_CLR_REGOFFSET, BIT(id));
     60
     61	return 0;
     62}
     63
     64static const struct reset_control_ops oxnas_reset_ops = {
     65	.reset		= oxnas_reset_reset,
     66	.assert		= oxnas_reset_assert,
     67	.deassert	= oxnas_reset_deassert,
     68};
     69
     70static const struct of_device_id oxnas_reset_dt_ids[] = {
     71	 { .compatible = "oxsemi,ox810se-reset", },
     72	 { .compatible = "oxsemi,ox820-reset", },
     73	 { /* sentinel */ },
     74};
     75
     76static int oxnas_reset_probe(struct platform_device *pdev)
     77{
     78	struct oxnas_reset *data;
     79	struct device *parent;
     80
     81	parent = pdev->dev.parent;
     82	if (!parent) {
     83		dev_err(&pdev->dev, "no parent\n");
     84		return -ENODEV;
     85	}
     86
     87	data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
     88	if (!data)
     89		return -ENOMEM;
     90
     91	data->regmap = syscon_node_to_regmap(parent->of_node);
     92	if (IS_ERR(data->regmap)) {
     93		dev_err(&pdev->dev, "failed to get parent regmap\n");
     94		return PTR_ERR(data->regmap);
     95	}
     96
     97	platform_set_drvdata(pdev, data);
     98
     99	data->rcdev.owner = THIS_MODULE;
    100	data->rcdev.nr_resets = 32;
    101	data->rcdev.ops = &oxnas_reset_ops;
    102	data->rcdev.of_node = pdev->dev.of_node;
    103
    104	return devm_reset_controller_register(&pdev->dev, &data->rcdev);
    105}
    106
    107static struct platform_driver oxnas_reset_driver = {
    108	.probe	= oxnas_reset_probe,
    109	.driver = {
    110		.name		= "oxnas-reset",
    111		.of_match_table	= oxnas_reset_dt_ids,
    112	},
    113};
    114builtin_platform_driver(oxnas_reset_driver);