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-scmi.c (3637B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * ARM System Control and Management Interface (ARM SCMI) reset driver
      4 *
      5 * Copyright (C) 2019-2021 ARM Ltd.
      6 */
      7
      8#include <linux/module.h>
      9#include <linux/of.h>
     10#include <linux/device.h>
     11#include <linux/reset-controller.h>
     12#include <linux/scmi_protocol.h>
     13
     14static const struct scmi_reset_proto_ops *reset_ops;
     15
     16/**
     17 * struct scmi_reset_data - reset controller information structure
     18 * @rcdev: reset controller entity
     19 * @ph: ARM SCMI protocol handle used for communication with system controller
     20 */
     21struct scmi_reset_data {
     22	struct reset_controller_dev rcdev;
     23	const struct scmi_protocol_handle *ph;
     24};
     25
     26#define to_scmi_reset_data(p)	container_of((p), struct scmi_reset_data, rcdev)
     27#define to_scmi_handle(p)	(to_scmi_reset_data(p)->ph)
     28
     29/**
     30 * scmi_reset_assert() - assert device reset
     31 * @rcdev: reset controller entity
     32 * @id: ID of the reset to be asserted
     33 *
     34 * This function implements the reset driver op to assert a device's reset
     35 * using the ARM SCMI protocol.
     36 *
     37 * Return: 0 for successful request, else a corresponding error value
     38 */
     39static int
     40scmi_reset_assert(struct reset_controller_dev *rcdev, unsigned long id)
     41{
     42	const struct scmi_protocol_handle *ph = to_scmi_handle(rcdev);
     43
     44	return reset_ops->assert(ph, id);
     45}
     46
     47/**
     48 * scmi_reset_deassert() - deassert device reset
     49 * @rcdev: reset controller entity
     50 * @id: ID of the reset to be deasserted
     51 *
     52 * This function implements the reset driver op to deassert a device's reset
     53 * using the ARM SCMI protocol.
     54 *
     55 * Return: 0 for successful request, else a corresponding error value
     56 */
     57static int
     58scmi_reset_deassert(struct reset_controller_dev *rcdev, unsigned long id)
     59{
     60	const struct scmi_protocol_handle *ph = to_scmi_handle(rcdev);
     61
     62	return reset_ops->deassert(ph, id);
     63}
     64
     65/**
     66 * scmi_reset_reset() - reset the device
     67 * @rcdev: reset controller entity
     68 * @id: ID of the reset signal to be reset(assert + deassert)
     69 *
     70 * This function implements the reset driver op to trigger a device's
     71 * reset signal using the ARM SCMI protocol.
     72 *
     73 * Return: 0 for successful request, else a corresponding error value
     74 */
     75static int
     76scmi_reset_reset(struct reset_controller_dev *rcdev, unsigned long id)
     77{
     78	const struct scmi_protocol_handle *ph = to_scmi_handle(rcdev);
     79
     80	return reset_ops->reset(ph, id);
     81}
     82
     83static const struct reset_control_ops scmi_reset_ops = {
     84	.assert		= scmi_reset_assert,
     85	.deassert	= scmi_reset_deassert,
     86	.reset		= scmi_reset_reset,
     87};
     88
     89static int scmi_reset_probe(struct scmi_device *sdev)
     90{
     91	struct scmi_reset_data *data;
     92	struct device *dev = &sdev->dev;
     93	struct device_node *np = dev->of_node;
     94	const struct scmi_handle *handle = sdev->handle;
     95	struct scmi_protocol_handle *ph;
     96
     97	if (!handle)
     98		return -ENODEV;
     99
    100	reset_ops = handle->devm_protocol_get(sdev, SCMI_PROTOCOL_RESET, &ph);
    101	if (IS_ERR(reset_ops))
    102		return PTR_ERR(reset_ops);
    103
    104	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
    105	if (!data)
    106		return -ENOMEM;
    107
    108	data->rcdev.ops = &scmi_reset_ops;
    109	data->rcdev.owner = THIS_MODULE;
    110	data->rcdev.of_node = np;
    111	data->rcdev.nr_resets = reset_ops->num_domains_get(ph);
    112	data->ph = ph;
    113
    114	return devm_reset_controller_register(dev, &data->rcdev);
    115}
    116
    117static const struct scmi_device_id scmi_id_table[] = {
    118	{ SCMI_PROTOCOL_RESET, "reset" },
    119	{ },
    120};
    121MODULE_DEVICE_TABLE(scmi, scmi_id_table);
    122
    123static struct scmi_driver scmi_reset_driver = {
    124	.name = "scmi-reset",
    125	.probe = scmi_reset_probe,
    126	.id_table = scmi_id_table,
    127};
    128module_scmi_driver(scmi_reset_driver);
    129
    130MODULE_AUTHOR("Sudeep Holla <sudeep.holla@arm.com>");
    131MODULE_DESCRIPTION("ARM SCMI reset controller driver");
    132MODULE_LICENSE("GPL v2");