From f9917454d55caf3dafa41b27d8d8274716433a4c Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 23 Jun 2015 15:39:13 -0600 Subject: dm: Add a system reset uclass It is common for system reset to be available at multiple levels in modern hardware. For example, an SoC may provide a reset option, and a board may provide its own reset for reasons of security or thoroughness. It is useful to be able to model this hardware without hard-coding the behaviour in the SoC or board. Also there is a distinction sometimes between resetting just the CPU (leaving GPIO state alone) and resetting all the PMICs, just cutting power. To achieve this, add a simple system reset uclass. It allows multiple devices to provide reset functionality and provides a way to walk through them, requesting a particular reset type until is it provided. Signed-off-by: Simon Glass --- drivers/misc/Kconfig | 9 +++++++ drivers/misc/Makefile | 1 + drivers/misc/reset-uclass.c | 62 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+) create mode 100644 drivers/misc/reset-uclass.c (limited to 'drivers/misc') diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 64b07a3..3b7f76a 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -73,3 +73,12 @@ config PCA9551_I2C_ADDR default 0x60 help The I2C address of the PCA9551 LED controller. + +config RESET + bool "Enable support for reset drivers" + depends on DM + help + Enable reset drivers which can be used to reset the CPU or board. + Each driver can provide a reset method which will be called to + effect a reset. The uclass will try all available drivers when + reset_walk() is called. diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 120babc..5da5178 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -32,3 +32,4 @@ obj-$(CONFIG_TWL4030_LED) += twl4030_led.o obj-$(CONFIG_FSL_IFC) += fsl_ifc.o obj-$(CONFIG_FSL_SEC_MON) += fsl_sec_mon.o obj-$(CONFIG_PCA9551_LED) += pca9551_led.o +obj-$(CONFIG_RESET) += reset-uclass.o diff --git a/drivers/misc/reset-uclass.c b/drivers/misc/reset-uclass.c new file mode 100644 index 0000000..ba27757 --- /dev/null +++ b/drivers/misc/reset-uclass.c @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2015 Google, Inc + * Written by Simon Glass + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int reset_request(struct udevice *dev, enum reset_t type) +{ + struct reset_ops *ops = reset_get_ops(dev); + + if (!ops->request) + return -ENOSYS; + + return ops->request(dev, type); +} + +void reset_walk(enum reset_t type) +{ + struct udevice *dev; + int ret = 0; + + while (ret != -EINPROGRESS && type < RESET_COUNT) { + for (uclass_first_device(UCLASS_RESET, &dev); + dev; + uclass_next_device(&dev)) { + ret = reset_request(dev, type); + if (ret == -EINPROGRESS) + break; + } + } + + /* Wait for the reset to take effect */ + mdelay(100); + + /* Still no reset? Give up */ + printf("Reset not supported on this platform\n"); + hang(); +} + +/** + * reset_cpu() - calls reset_walk(RESET_WARM) + */ +void reset_cpu(ulong addr) +{ + reset_walk(RESET_WARM); +} + +UCLASS_DRIVER(reset) = { + .id = UCLASS_RESET, + .name = "reset", +}; -- cgit v1.1