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-zynqmp.c (3564B)


      1// SPDX-License-Identifier: GPL-2.0+
      2/*
      3 * Copyright (C) 2018 Xilinx, Inc.
      4 *
      5 */
      6
      7#include <linux/err.h>
      8#include <linux/of.h>
      9#include <linux/platform_device.h>
     10#include <linux/reset-controller.h>
     11#include <linux/firmware/xlnx-zynqmp.h>
     12#include <linux/of_device.h>
     13
     14#define ZYNQMP_NR_RESETS (ZYNQMP_PM_RESET_END - ZYNQMP_PM_RESET_START)
     15#define ZYNQMP_RESET_ID ZYNQMP_PM_RESET_START
     16#define VERSAL_NR_RESETS	95
     17
     18struct zynqmp_reset_soc_data {
     19	u32 reset_id;
     20	u32 num_resets;
     21};
     22
     23struct zynqmp_reset_data {
     24	struct reset_controller_dev rcdev;
     25	const struct zynqmp_reset_soc_data *data;
     26};
     27
     28static inline struct zynqmp_reset_data *
     29to_zynqmp_reset_data(struct reset_controller_dev *rcdev)
     30{
     31	return container_of(rcdev, struct zynqmp_reset_data, rcdev);
     32}
     33
     34static int zynqmp_reset_assert(struct reset_controller_dev *rcdev,
     35			       unsigned long id)
     36{
     37	struct zynqmp_reset_data *priv = to_zynqmp_reset_data(rcdev);
     38
     39	return zynqmp_pm_reset_assert(priv->data->reset_id + id,
     40				      PM_RESET_ACTION_ASSERT);
     41}
     42
     43static int zynqmp_reset_deassert(struct reset_controller_dev *rcdev,
     44				 unsigned long id)
     45{
     46	struct zynqmp_reset_data *priv = to_zynqmp_reset_data(rcdev);
     47
     48	return zynqmp_pm_reset_assert(priv->data->reset_id + id,
     49				      PM_RESET_ACTION_RELEASE);
     50}
     51
     52static int zynqmp_reset_status(struct reset_controller_dev *rcdev,
     53			       unsigned long id)
     54{
     55	struct zynqmp_reset_data *priv = to_zynqmp_reset_data(rcdev);
     56	int err;
     57	u32 val;
     58
     59	err = zynqmp_pm_reset_get_status(priv->data->reset_id + id, &val);
     60	if (err)
     61		return err;
     62
     63	return val;
     64}
     65
     66static int zynqmp_reset_reset(struct reset_controller_dev *rcdev,
     67			      unsigned long id)
     68{
     69	struct zynqmp_reset_data *priv = to_zynqmp_reset_data(rcdev);
     70
     71	return zynqmp_pm_reset_assert(priv->data->reset_id + id,
     72				      PM_RESET_ACTION_PULSE);
     73}
     74
     75static int zynqmp_reset_of_xlate(struct reset_controller_dev *rcdev,
     76				 const struct of_phandle_args *reset_spec)
     77{
     78	return reset_spec->args[0];
     79}
     80
     81static const struct zynqmp_reset_soc_data zynqmp_reset_data = {
     82	.reset_id = ZYNQMP_RESET_ID,
     83	.num_resets = ZYNQMP_NR_RESETS,
     84};
     85
     86static const struct zynqmp_reset_soc_data versal_reset_data = {
     87	.reset_id = 0,
     88	.num_resets = VERSAL_NR_RESETS,
     89};
     90
     91static const struct reset_control_ops zynqmp_reset_ops = {
     92	.reset = zynqmp_reset_reset,
     93	.assert = zynqmp_reset_assert,
     94	.deassert = zynqmp_reset_deassert,
     95	.status = zynqmp_reset_status,
     96};
     97
     98static int zynqmp_reset_probe(struct platform_device *pdev)
     99{
    100	struct zynqmp_reset_data *priv;
    101
    102	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
    103	if (!priv)
    104		return -ENOMEM;
    105
    106	priv->data = of_device_get_match_data(&pdev->dev);
    107	if (!priv->data)
    108		return -EINVAL;
    109
    110	platform_set_drvdata(pdev, priv);
    111
    112	priv->rcdev.ops = &zynqmp_reset_ops;
    113	priv->rcdev.owner = THIS_MODULE;
    114	priv->rcdev.of_node = pdev->dev.of_node;
    115	priv->rcdev.nr_resets = priv->data->num_resets;
    116	priv->rcdev.of_reset_n_cells = 1;
    117	priv->rcdev.of_xlate = zynqmp_reset_of_xlate;
    118
    119	return devm_reset_controller_register(&pdev->dev, &priv->rcdev);
    120}
    121
    122static const struct of_device_id zynqmp_reset_dt_ids[] = {
    123	{ .compatible = "xlnx,zynqmp-reset", .data = &zynqmp_reset_data, },
    124	{ .compatible = "xlnx,versal-reset", .data = &versal_reset_data, },
    125	{ /* sentinel */ },
    126};
    127
    128static struct platform_driver zynqmp_reset_driver = {
    129	.probe	= zynqmp_reset_probe,
    130	.driver = {
    131		.name		= KBUILD_MODNAME,
    132		.of_match_table	= zynqmp_reset_dt_ids,
    133	},
    134};
    135
    136static int __init zynqmp_reset_init(void)
    137{
    138	return platform_driver_register(&zynqmp_reset_driver);
    139}
    140
    141arch_initcall(zynqmp_reset_init);