Skip to content

Commit

Permalink
reset: Add support for resets provided by SCMI
Browse files Browse the repository at this point in the history
On some ARM based systems, a separate Cortex-M based System Control
Processor(SCP) provides the overall power, clock, reset and system
control. System Control and Management Interface(SCMI) Message Protocol
is defined for the communication between the Application Cores(AP)
and the SCP.

Adds support for the resets provided using SCMI protocol for performing
reset management of various devices present on the SoC. Various reset
functionalities are achieved by the means of different ARM SCMI device
operations provided by the ARM SCMI framework.

Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
  • Loading branch information
Sudeep Holla committed Aug 12, 2019
1 parent 95a15d8 commit c8ae9c2
Show file tree
Hide file tree
Showing 4 changed files with 137 additions and 0 deletions.
1 change: 1 addition & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -15545,6 +15545,7 @@ F: drivers/clk/clk-sc[mp]i.c
F: drivers/cpufreq/sc[mp]i-cpufreq.c
F: drivers/firmware/arm_scpi.c
F: drivers/firmware/arm_scmi/
F: drivers/reset/reset-scmi.c
F: include/linux/sc[mp]i_protocol.h

SYSTEM RESET/SHUTDOWN DRIVERS
Expand Down
11 changes: 11 additions & 0 deletions drivers/reset/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,17 @@ config RESET_QCOM_PDC
to control reset signals provided by PDC for Modem, Compute,
Display, GPU, Debug, AOP, Sensors, Audio, SP and APPS.

config RESET_SCMI
tristate "Reset driver controlled via ARM SCMI interface"
depends on ARM_SCMI_PROTOCOL || COMPILE_TEST
default ARM_SCMI_PROTOCOL
help
This driver provides support for reset signal/domains that are
controlled by firmware that implements the SCMI interface.

This driver uses SCMI Message Protocol to interact with the
firmware controlling all the reset signals.

config RESET_SIMPLE
bool "Simple Reset Controller Driver" if COMPILE_TEST
default ARCH_STM32 || ARCH_STRATIX10 || ARCH_SUNXI || ARCH_ZX || ARCH_ASPEED || ARCH_BITMAIN
Expand Down
1 change: 1 addition & 0 deletions drivers/reset/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ obj-$(CONFIG_RESET_OXNAS) += reset-oxnas.o
obj-$(CONFIG_RESET_PISTACHIO) += reset-pistachio.o
obj-$(CONFIG_RESET_QCOM_AOSS) += reset-qcom-aoss.o
obj-$(CONFIG_RESET_QCOM_PDC) += reset-qcom-pdc.o
obj-$(CONFIG_RESET_SCMI) += reset-scmi.o
obj-$(CONFIG_RESET_SIMPLE) += reset-simple.o
obj-$(CONFIG_RESET_STM32MP157) += reset-stm32mp1.o
obj-$(CONFIG_RESET_SOCFPGA) += reset-socfpga.o
Expand Down
124 changes: 124 additions & 0 deletions drivers/reset/reset-scmi.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
// SPDX-License-Identifier: GPL-2.0
/*
* ARM System Control and Management Interface (ARM SCMI) reset driver
*
* Copyright (C) 2019 ARM Ltd.
*/

#include <linux/module.h>
#include <linux/of.h>
#include <linux/device.h>
#include <linux/reset-controller.h>
#include <linux/scmi_protocol.h>

/**
* struct scmi_reset_data - reset controller information structure
* @rcdev: reset controller entity
* @handle: ARM SCMI handle used for communication with system controller
*/
struct scmi_reset_data {
struct reset_controller_dev rcdev;
const struct scmi_handle *handle;
};

#define to_scmi_reset_data(p) container_of((p), struct scmi_reset_data, rcdev)
#define to_scmi_handle(p) (to_scmi_reset_data(p)->handle)

/**
* scmi_reset_assert() - assert device reset
* @rcdev: reset controller entity
* @id: ID of the reset to be asserted
*
* This function implements the reset driver op to assert a device's reset
* using the ARM SCMI protocol.
*
* Return: 0 for successful request, else a corresponding error value
*/
static int
scmi_reset_assert(struct reset_controller_dev *rcdev, unsigned long id)
{
const struct scmi_handle *handle = to_scmi_handle(rcdev);

return handle->reset_ops->assert(handle, id);
}

/**
* scmi_reset_deassert() - deassert device reset
* @rcdev: reset controller entity
* @id: ID of the reset to be deasserted
*
* This function implements the reset driver op to deassert a device's reset
* using the ARM SCMI protocol.
*
* Return: 0 for successful request, else a corresponding error value
*/
static int
scmi_reset_deassert(struct reset_controller_dev *rcdev, unsigned long id)
{
const struct scmi_handle *handle = to_scmi_handle(rcdev);

return handle->reset_ops->deassert(handle, id);
}

/**
* scmi_reset_reset() - reset the device
* @rcdev: reset controller entity
* @id: ID of the reset signal to be reset(assert + deassert)
*
* This function implements the reset driver op to trigger a device's
* reset signal using the ARM SCMI protocol.
*
* Return: 0 for successful request, else a corresponding error value
*/
static int
scmi_reset_reset(struct reset_controller_dev *rcdev, unsigned long id)
{
const struct scmi_handle *handle = to_scmi_handle(rcdev);

return handle->reset_ops->reset(handle, id);
}

static const struct reset_control_ops scmi_reset_ops = {
.assert = scmi_reset_assert,
.deassert = scmi_reset_deassert,
.reset = scmi_reset_reset,
};

static int scmi_reset_probe(struct scmi_device *sdev)
{
struct scmi_reset_data *data;
struct device *dev = &sdev->dev;
struct device_node *np = dev->of_node;
const struct scmi_handle *handle = sdev->handle;

if (!handle || !handle->reset_ops)
return -ENODEV;

data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
if (!data)
return -ENOMEM;

data->rcdev.ops = &scmi_reset_ops;
data->rcdev.owner = THIS_MODULE;
data->rcdev.of_node = np;
data->rcdev.nr_resets = handle->reset_ops->num_domains_get(handle);

return devm_reset_controller_register(dev, &data->rcdev);
}

static const struct scmi_device_id scmi_id_table[] = {
{ SCMI_PROTOCOL_RESET },
{ },
};
MODULE_DEVICE_TABLE(scmi, scmi_id_table);

static struct scmi_driver scmi_reset_driver = {
.name = "scmi-reset",
.probe = scmi_reset_probe,
.id_table = scmi_id_table,
};
module_scmi_driver(scmi_reset_driver);

MODULE_AUTHOR("Sudeep Holla <sudeep.holla@arm.com>");
MODULE_DESCRIPTION("ARM SCMI reset controller driver");
MODULE_LICENSE("GPL v2");

0 comments on commit c8ae9c2

Please sign in to comment.