Commit c8952516 authored by Olof Johansson's avatar Olof Johansson
Browse files

Merge tag 'reset-for-v5.10' of git://git.pengutronix.de/pza/linux into arm/drivers

Reset controller updates for v5.10

This tag allows to build reset-imx7 as a module, and adds support to
reset the Cortex-M4 processor on i.MX8MQ to it, adds support for the
Versal platform to the reset-zynqmp driver, and fixes some kerneldoc
comments in the core and in sti/reset-syscfg.

* tag 'reset-for-v5.10' of git://git.pengutronix.de/pza/linux:
  reset: sti: reset-syscfg: fix struct description warnings
  reset: imx7: add the cm4 reset for i.MX8MQ
  dt-bindings: reset: imx8mq: add m4 reset
  reset: Fix and extend kerneldoc
  reset: reset-zynqmp: Added support for Versal platform
  dt-bindings: reset: Updated binding for Versal reset driver
  reset: imx7: Support module build

Link: https://lore.kernel.org/r/2b77c90d2b970eb8fa09000b9ecb564bffa76374.camel@pengutronix.de


Signed-off-by: default avatarOlof Johansson <olof@lixom.net>
parents e863e45e 68a21516
Loading
Loading
Loading
Loading
+7 −4
Original line number Diff line number Diff line
--------------------------------------------------------------------------
 =  Zynq UltraScale+ MPSoC reset driver binding =
 =  Zynq UltraScale+ MPSoC and Versal reset driver binding =
--------------------------------------------------------------------------
The Zynq UltraScale+ MPSoC has several different resets.
The Zynq UltraScale+ MPSoC and Versal has several different resets.

See Chapter 36 of the Zynq UltraScale+ MPSoC TRM (UG) for more information
about zynqmp resets.
@@ -10,7 +10,8 @@ Please also refer to reset.txt in this directory for common reset
controller binding usage.

Required Properties:
- compatible:	"xlnx,zynqmp-reset"
- compatible:	"xlnx,zynqmp-reset" for Zynq UltraScale+ MPSoC platform
		"xlnx,versal-reset" for Versal platform
- #reset-cells:	Specifies the number of cells needed to encode reset
		line, should be 1

@@ -37,8 +38,10 @@ Device nodes that need access to reset lines should
specify them as a reset phandle in their corresponding node as
specified in reset.txt.

For list of all valid reset indicies see
For list of all valid reset indices for Zynq UltraScale+ MPSoC see
<dt-bindings/reset/xlnx-zynqmp-resets.h>
For list of all valid reset indices for Versal see
<dt-bindings/reset/xlnx-versal-resets.h>

Example:

+3 −2
Original line number Diff line number Diff line
@@ -65,9 +65,10 @@ config RESET_HSDK
	  This enables the reset controller driver for HSDK board.

config RESET_IMX7
	bool "i.MX7/8 Reset Driver" if COMPILE_TEST
	tristate "i.MX7/8 Reset Driver"
	depends on HAS_IOMEM
	default SOC_IMX7D || (ARM64 && ARCH_MXC)
	depends on SOC_IMX7D || (ARM64 && ARCH_MXC) || COMPILE_TEST
	default y if SOC_IMX7D
	select MFD_SYSCON
	help
	  This enables the reset controller driver for i.MX7 SoCs.
+2 −1
Original line number Diff line number Diff line
@@ -32,7 +32,8 @@ static LIST_HEAD(reset_lookup_list);
 * @refcnt: Number of gets of this reset_control
 * @acquired: Only one reset_control may be acquired for a given rcdev and id.
 * @shared: Is this a shared (1), or an exclusive (0) reset_control?
 * @deassert_cnt: Number of times this reset line has been deasserted
 * @array: Is this an array of reset controls (1)?
 * @deassert_count: Number of times this reset line has been deasserted
 * @triggered_count: Number of times this reset line has been reset. Currently
 *                   only used for shared resets, which means that the value
 *                   will be either 0 or 1.
+11 −2
Original line number Diff line number Diff line
@@ -8,7 +8,7 @@
 */

#include <linux/mfd/syscon.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/reset-controller.h>
@@ -178,6 +178,9 @@ static const struct imx7_src_signal imx8mq_src_signals[IMX8MQ_RESET_NUM] = {
	[IMX8MQ_RESET_A53_SOC_DBG_RESET]	= { SRC_A53RCR0, BIT(20) },
	[IMX8MQ_RESET_A53_L2RESET]		= { SRC_A53RCR0, BIT(21) },
	[IMX8MQ_RESET_SW_NON_SCLR_M4C_RST]	= { SRC_M4RCR, BIT(0) },
	[IMX8MQ_RESET_SW_M4C_RST]		= { SRC_M4RCR, BIT(1) },
	[IMX8MQ_RESET_SW_M4P_RST]		= { SRC_M4RCR, BIT(2) },
	[IMX8MQ_RESET_M4_ENABLE]		= { SRC_M4RCR, BIT(3) },
	[IMX8MQ_RESET_OTG1_PHY_RESET]		= { SRC_USBOPHY1_RCR, BIT(0) },
	[IMX8MQ_RESET_OTG2_PHY_RESET]		= { SRC_USBOPHY2_RCR, BIT(0) },
	[IMX8MQ_RESET_MIPI_DSI_RESET_BYTE_N]	= { SRC_MIPIPHY_RCR, BIT(1) },
@@ -238,6 +241,7 @@ static int imx8mq_reset_set(struct reset_controller_dev *rcdev,
	case IMX8MQ_RESET_MIPI_DSI_DPI_RESET_N:	/* fallthrough */
	case IMX8MQ_RESET_MIPI_DSI_RESET_N:	/* fallthrough */
	case IMX8MQ_RESET_MIPI_DSI_RESET_BYTE_N:	/* fallthrough */
	case IMX8MQ_RESET_M4_ENABLE:
		value = assert ? 0 : bit;
		break;
	}
@@ -386,6 +390,7 @@ static const struct of_device_id imx7_reset_dt_ids[] = {
	{ .compatible = "fsl,imx8mp-src", .data = &variant_imx8mp },
	{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, imx7_reset_dt_ids);

static struct platform_driver imx7_reset_driver = {
	.probe	= imx7_reset_probe,
@@ -394,4 +399,8 @@ static struct platform_driver imx7_reset_driver = {
		.of_match_table	= imx7_reset_dt_ids,
	},
};
builtin_platform_driver(imx7_reset_driver);
module_platform_driver(imx7_reset_driver);

MODULE_AUTHOR("Andrey Smirnov <andrew.smirnov@gmail.com>");
MODULE_DESCRIPTION("NXP i.MX7 reset driver");
MODULE_LICENSE("GPL v2");
+44 −6
Original line number Diff line number Diff line
@@ -9,12 +9,20 @@
#include <linux/platform_device.h>
#include <linux/reset-controller.h>
#include <linux/firmware/xlnx-zynqmp.h>
#include <linux/of_device.h>

#define ZYNQMP_NR_RESETS (ZYNQMP_PM_RESET_END - ZYNQMP_PM_RESET_START)
#define ZYNQMP_RESET_ID ZYNQMP_PM_RESET_START
#define VERSAL_NR_RESETS	95

struct zynqmp_reset_soc_data {
	u32 reset_id;
	u32 num_resets;
};

struct zynqmp_reset_data {
	struct reset_controller_dev rcdev;
	const struct zynqmp_reset_soc_data *data;
};

static inline struct zynqmp_reset_data *
@@ -26,23 +34,28 @@ to_zynqmp_reset_data(struct reset_controller_dev *rcdev)
static int zynqmp_reset_assert(struct reset_controller_dev *rcdev,
			       unsigned long id)
{
	return zynqmp_pm_reset_assert(ZYNQMP_RESET_ID + id,
	struct zynqmp_reset_data *priv = to_zynqmp_reset_data(rcdev);

	return zynqmp_pm_reset_assert(priv->data->reset_id + id,
				      PM_RESET_ACTION_ASSERT);
}

static int zynqmp_reset_deassert(struct reset_controller_dev *rcdev,
				 unsigned long id)
{
	return zynqmp_pm_reset_assert(ZYNQMP_RESET_ID + id,
	struct zynqmp_reset_data *priv = to_zynqmp_reset_data(rcdev);

	return zynqmp_pm_reset_assert(priv->data->reset_id + id,
				      PM_RESET_ACTION_RELEASE);
}

static int zynqmp_reset_status(struct reset_controller_dev *rcdev,
			       unsigned long id)
{
	struct zynqmp_reset_data *priv = to_zynqmp_reset_data(rcdev);
	int val, err;

	err = zynqmp_pm_reset_get_status(ZYNQMP_RESET_ID + id, &val);
	err = zynqmp_pm_reset_get_status(priv->data->reset_id + id, &val);
	if (err)
		return err;

@@ -52,10 +65,28 @@ static int zynqmp_reset_status(struct reset_controller_dev *rcdev,
static int zynqmp_reset_reset(struct reset_controller_dev *rcdev,
			      unsigned long id)
{
	return zynqmp_pm_reset_assert(ZYNQMP_RESET_ID + id,
	struct zynqmp_reset_data *priv = to_zynqmp_reset_data(rcdev);

	return zynqmp_pm_reset_assert(priv->data->reset_id + id,
				      PM_RESET_ACTION_PULSE);
}

static int zynqmp_reset_of_xlate(struct reset_controller_dev *rcdev,
				 const struct of_phandle_args *reset_spec)
{
	return reset_spec->args[0];
}

static const struct zynqmp_reset_soc_data zynqmp_reset_data = {
	.reset_id = ZYNQMP_RESET_ID,
	.num_resets = ZYNQMP_NR_RESETS,
};

static const struct zynqmp_reset_soc_data versal_reset_data = {
        .reset_id = 0,
        .num_resets = VERSAL_NR_RESETS,
};

static const struct reset_control_ops zynqmp_reset_ops = {
	.reset = zynqmp_reset_reset,
	.assert = zynqmp_reset_assert,
@@ -71,18 +102,25 @@ static int zynqmp_reset_probe(struct platform_device *pdev)
	if (!priv)
		return -ENOMEM;

	priv->data = of_device_get_match_data(&pdev->dev);
	if (!priv->data)
		return -EINVAL;

	platform_set_drvdata(pdev, priv);

	priv->rcdev.ops = &zynqmp_reset_ops;
	priv->rcdev.owner = THIS_MODULE;
	priv->rcdev.of_node = pdev->dev.of_node;
	priv->rcdev.nr_resets = ZYNQMP_NR_RESETS;
	priv->rcdev.nr_resets = priv->data->num_resets;
	priv->rcdev.of_reset_n_cells = 1;
	priv->rcdev.of_xlate = zynqmp_reset_of_xlate;

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

static const struct of_device_id zynqmp_reset_dt_ids[] = {
	{ .compatible = "xlnx,zynqmp-reset", },
	{ .compatible = "xlnx,zynqmp-reset", .data = &zynqmp_reset_data, },
	{ .compatible = "xlnx,versal-reset", .data = &versal_reset_data, },
	{ /* sentinel */ },
};

Loading