diff options
author | Arnd Bergmann <arnd@arndb.de> | 2015-12-12 00:22:28 (GMT) |
---|---|---|
committer | Arnd Bergmann <arnd@arndb.de> | 2015-12-12 00:22:28 (GMT) |
commit | bd8f27ba828efa2538bc86010f299a635e79249b (patch) | |
tree | d644f8854beee1daad492d49e2876dde6659e80f | |
parent | 7eccfebf65f0ba2d41dbd053e29a9b6287f406da (diff) | |
parent | ba64e27e9d3c558549f765869c6a471114c0f328 (diff) | |
download | linux-bd8f27ba828efa2538bc86010f299a635e79249b.tar.xz |
Merge tag 'reset-for-4.5-2' of git://git.pengutronix.de/git/pza/linux into next/drivers
Merge "Reset controller changes for v4.5 v2" from Philipp Zabel:
- oftree support for getting reset devices by index
- fixed return value consistency of of_reset_control_get
- added support for STi co-processor resets
- added STi status callback
- added HiSilicon Hi6220 reset driver
- added ath79 system restart support
- various fixes
* tag 'reset-for-4.5-2' of git://git.pengutronix.de/git/pza/linux:
reset: ath79: Add system restart support
arm64: dts: Add reset dts config for Hisilicon Hi6220 SoC
reset: hi6220: Reset driver for hisilicon hi6220 SoC
reset: hisilicon: document hisi-hi6220 reset controllers bindings
reset: remove unused device pointer from struct reset_control
-rw-r--r-- | Documentation/devicetree/bindings/reset/hisilicon,hi6220-reset.txt | 34 | ||||
-rw-r--r-- | arch/arm64/boot/dts/hisilicon/hi6220.dtsi | 1 | ||||
-rw-r--r-- | drivers/reset/Kconfig | 1 | ||||
-rw-r--r-- | drivers/reset/Makefile | 1 | ||||
-rw-r--r-- | drivers/reset/core.c | 9 | ||||
-rw-r--r-- | drivers/reset/hisilicon/Kconfig | 5 | ||||
-rw-r--r-- | drivers/reset/hisilicon/Makefile | 1 | ||||
-rw-r--r-- | drivers/reset/hisilicon/hi6220_reset.c | 108 | ||||
-rw-r--r-- | drivers/reset/reset-ath79.c | 30 | ||||
-rw-r--r-- | include/dt-bindings/reset/hisi,hi6220-resets.h | 67 |
10 files changed, 248 insertions, 9 deletions
diff --git a/Documentation/devicetree/bindings/reset/hisilicon,hi6220-reset.txt b/Documentation/devicetree/bindings/reset/hisilicon,hi6220-reset.txt new file mode 100644 index 0000000..e0b185a --- /dev/null +++ b/Documentation/devicetree/bindings/reset/hisilicon,hi6220-reset.txt @@ -0,0 +1,34 @@ +Hisilicon System Reset Controller +====================================== + +Please also refer to reset.txt in this directory for common reset +controller binding usage. + +The reset controller registers are part of the system-ctl block on +hi6220 SoC. + +Required properties: +- compatible: may be "hisilicon,hi6220-sysctrl" +- reg: should be register base and length as documented in the + datasheet +- #reset-cells: 1, see below + +Example: +sys_ctrl: sys_ctrl@f7030000 { + compatible = "hisilicon,hi6220-sysctrl", "syscon"; + reg = <0x0 0xf7030000 0x0 0x2000>; + #clock-cells = <1>; + #reset-cells = <1>; +}; + +Specifying reset lines connected to IP modules +============================================== +example: + + uart1: serial@..... { + ... + resets = <&sys_ctrl PERIPH_RSTEN3_UART1>; + ... + }; + +The index could be found in <dt-bindings/reset/hisi,hi6220-resets.h>. diff --git a/arch/arm64/boot/dts/hisilicon/hi6220.dtsi b/arch/arm64/boot/dts/hisilicon/hi6220.dtsi index 82d2488..ad1f1eb 100644 --- a/arch/arm64/boot/dts/hisilicon/hi6220.dtsi +++ b/arch/arm64/boot/dts/hisilicon/hi6220.dtsi @@ -147,6 +147,7 @@ compatible = "hisilicon,hi6220-sysctrl", "syscon"; reg = <0x0 0xf7030000 0x0 0x2000>; #clock-cells = <1>; + #reset-cells = <1>; }; media_ctrl: media_ctrl@f4410000 { diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index 0615f50..df37212 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -13,3 +13,4 @@ menuconfig RESET_CONTROLLER If unsure, say no. source "drivers/reset/sti/Kconfig" +source "drivers/reset/hisilicon/Kconfig" diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile index f191cf33..4d7178e 100644 --- a/drivers/reset/Makefile +++ b/drivers/reset/Makefile @@ -4,5 +4,6 @@ obj-$(CONFIG_ARCH_SOCFPGA) += reset-socfpga.o obj-$(CONFIG_ARCH_BERLIN) += reset-berlin.o obj-$(CONFIG_ARCH_SUNXI) += reset-sunxi.o obj-$(CONFIG_ARCH_STI) += sti/ +obj-$(CONFIG_ARCH_HISI) += hisilicon/ obj-$(CONFIG_ARCH_ZYNQ) += reset-zynq.o obj-$(CONFIG_ATH79) += reset-ath79.o diff --git a/drivers/reset/core.c b/drivers/reset/core.c index 9ab9290..8737663 100644 --- a/drivers/reset/core.c +++ b/drivers/reset/core.c @@ -30,7 +30,6 @@ static LIST_HEAD(reset_controller_list); */ struct reset_control { struct reset_controller_dev *rcdev; - struct device *dev; unsigned int id; }; @@ -236,16 +235,10 @@ EXPORT_SYMBOL_GPL(of_reset_control_get); */ struct reset_control *reset_control_get(struct device *dev, const char *id) { - struct reset_control *rstc; - if (!dev) return ERR_PTR(-EINVAL); - rstc = of_reset_control_get(dev->of_node, id); - if (!IS_ERR(rstc)) - rstc->dev = dev; - - return rstc; + return of_reset_control_get(dev->of_node, id); } EXPORT_SYMBOL_GPL(reset_control_get); diff --git a/drivers/reset/hisilicon/Kconfig b/drivers/reset/hisilicon/Kconfig new file mode 100644 index 0000000..26bf95a --- /dev/null +++ b/drivers/reset/hisilicon/Kconfig @@ -0,0 +1,5 @@ +config COMMON_RESET_HI6220 + tristate "Hi6220 Reset Driver" + depends on (ARCH_HISI && RESET_CONTROLLER) + help + Build the Hisilicon Hi6220 reset driver. diff --git a/drivers/reset/hisilicon/Makefile b/drivers/reset/hisilicon/Makefile new file mode 100644 index 0000000..c932f86 --- /dev/null +++ b/drivers/reset/hisilicon/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_COMMON_RESET_HI6220) += hi6220_reset.o diff --git a/drivers/reset/hisilicon/hi6220_reset.c b/drivers/reset/hisilicon/hi6220_reset.c new file mode 100644 index 0000000..d17c910 --- /dev/null +++ b/drivers/reset/hisilicon/hi6220_reset.c @@ -0,0 +1,108 @@ +/* + * Hisilicon Hi6220 reset controller driver + * + * Copyright (c) 2015 Hisilicon Limited. + * + * Author: Feng Chen <puck.chen@hisilicon.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/io.h> +#include <linux/init.h> +#include <linux/bitops.h> +#include <linux/of.h> +#include <linux/reset-controller.h> +#include <linux/reset.h> +#include <linux/platform_device.h> + +#define ASSERT_OFFSET 0x300 +#define DEASSERT_OFFSET 0x304 +#define MAX_INDEX 0x509 + +#define to_reset_data(x) container_of(x, struct hi6220_reset_data, rc_dev) + +struct hi6220_reset_data { + void __iomem *assert_base; + void __iomem *deassert_base; + struct reset_controller_dev rc_dev; +}; + +static int hi6220_reset_assert(struct reset_controller_dev *rc_dev, + unsigned long idx) +{ + struct hi6220_reset_data *data = to_reset_data(rc_dev); + + int bank = idx >> 8; + int offset = idx & 0xff; + + writel(BIT(offset), data->assert_base + (bank * 0x10)); + + return 0; +} + +static int hi6220_reset_deassert(struct reset_controller_dev *rc_dev, + unsigned long idx) +{ + struct hi6220_reset_data *data = to_reset_data(rc_dev); + + int bank = idx >> 8; + int offset = idx & 0xff; + + writel(BIT(offset), data->deassert_base + (bank * 0x10)); + + return 0; +} + +static struct reset_control_ops hi6220_reset_ops = { + .assert = hi6220_reset_assert, + .deassert = hi6220_reset_deassert, +}; + +static int hi6220_reset_probe(struct platform_device *pdev) +{ + struct hi6220_reset_data *data; + struct resource *res; + void __iomem *src_base; + + data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + src_base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(src_base)) + return PTR_ERR(src_base); + + data->assert_base = src_base + ASSERT_OFFSET; + data->deassert_base = src_base + DEASSERT_OFFSET; + data->rc_dev.nr_resets = MAX_INDEX; + data->rc_dev.ops = &hi6220_reset_ops; + data->rc_dev.of_node = pdev->dev.of_node; + + reset_controller_register(&data->rc_dev); + + return 0; +} + +static const struct of_device_id hi6220_reset_match[] = { + { .compatible = "hisilicon,hi6220-sysctrl" }, + { }, +}; + +static struct platform_driver hi6220_reset_driver = { + .probe = hi6220_reset_probe, + .driver = { + .name = "reset-hi6220", + .of_match_table = hi6220_reset_match, + }, +}; + +static int __init hi6220_reset_init(void) +{ + return platform_driver_register(&hi6220_reset_driver); +} + +postcore_initcall(hi6220_reset_init); diff --git a/drivers/reset/reset-ath79.c b/drivers/reset/reset-ath79.c index 9aaf646..692fc89 100644 --- a/drivers/reset/reset-ath79.c +++ b/drivers/reset/reset-ath79.c @@ -15,13 +15,17 @@ #include <linux/module.h> #include <linux/platform_device.h> #include <linux/reset-controller.h> +#include <linux/reboot.h> struct ath79_reset { struct reset_controller_dev rcdev; + struct notifier_block restart_nb; void __iomem *base; spinlock_t lock; }; +#define FULL_CHIP_RESET 24 + static int ath79_reset_update(struct reset_controller_dev *rcdev, unsigned long id, bool assert) { @@ -72,10 +76,22 @@ static struct reset_control_ops ath79_reset_ops = { .status = ath79_reset_status, }; +static int ath79_reset_restart_handler(struct notifier_block *nb, + unsigned long action, void *data) +{ + struct ath79_reset *ath79_reset = + container_of(nb, struct ath79_reset, restart_nb); + + ath79_reset_assert(&ath79_reset->rcdev, FULL_CHIP_RESET); + + return NOTIFY_DONE; +} + static int ath79_reset_probe(struct platform_device *pdev) { struct ath79_reset *ath79_reset; struct resource *res; + int err; ath79_reset = devm_kzalloc(&pdev->dev, sizeof(*ath79_reset), GFP_KERNEL); @@ -96,13 +112,25 @@ static int ath79_reset_probe(struct platform_device *pdev) ath79_reset->rcdev.of_reset_n_cells = 1; ath79_reset->rcdev.nr_resets = 32; - return reset_controller_register(&ath79_reset->rcdev); + err = reset_controller_register(&ath79_reset->rcdev); + if (err) + return err; + + ath79_reset->restart_nb.notifier_call = ath79_reset_restart_handler; + ath79_reset->restart_nb.priority = 128; + + err = register_restart_handler(&ath79_reset->restart_nb); + if (err) + dev_warn(&pdev->dev, "Failed to register restart handler\n"); + + return 0; } static int ath79_reset_remove(struct platform_device *pdev) { struct ath79_reset *ath79_reset = platform_get_drvdata(pdev); + unregister_restart_handler(&ath79_reset->restart_nb); reset_controller_unregister(&ath79_reset->rcdev); return 0; diff --git a/include/dt-bindings/reset/hisi,hi6220-resets.h b/include/dt-bindings/reset/hisi,hi6220-resets.h new file mode 100644 index 0000000..ca08a7e --- /dev/null +++ b/include/dt-bindings/reset/hisi,hi6220-resets.h @@ -0,0 +1,67 @@ +/** + * This header provides index for the reset controller + * based on hi6220 SoC. + */ +#ifndef _DT_BINDINGS_RESET_CONTROLLER_HI6220 +#define _DT_BINDINGS_RESET_CONTROLLER_HI6220 + +#define PERIPH_RSTDIS0_MMC0 0x000 +#define PERIPH_RSTDIS0_MMC1 0x001 +#define PERIPH_RSTDIS0_MMC2 0x002 +#define PERIPH_RSTDIS0_NANDC 0x003 +#define PERIPH_RSTDIS0_USBOTG_BUS 0x004 +#define PERIPH_RSTDIS0_POR_PICOPHY 0x005 +#define PERIPH_RSTDIS0_USBOTG 0x006 +#define PERIPH_RSTDIS0_USBOTG_32K 0x007 +#define PERIPH_RSTDIS1_HIFI 0x100 +#define PERIPH_RSTDIS1_DIGACODEC 0x105 +#define PERIPH_RSTEN2_IPF 0x200 +#define PERIPH_RSTEN2_SOCP 0x201 +#define PERIPH_RSTEN2_DMAC 0x202 +#define PERIPH_RSTEN2_SECENG 0x203 +#define PERIPH_RSTEN2_ABB 0x204 +#define PERIPH_RSTEN2_HPM0 0x205 +#define PERIPH_RSTEN2_HPM1 0x206 +#define PERIPH_RSTEN2_HPM2 0x207 +#define PERIPH_RSTEN2_HPM3 0x208 +#define PERIPH_RSTEN3_CSSYS 0x300 +#define PERIPH_RSTEN3_I2C0 0x301 +#define PERIPH_RSTEN3_I2C1 0x302 +#define PERIPH_RSTEN3_I2C2 0x303 +#define PERIPH_RSTEN3_I2C3 0x304 +#define PERIPH_RSTEN3_UART1 0x305 +#define PERIPH_RSTEN3_UART2 0x306 +#define PERIPH_RSTEN3_UART3 0x307 +#define PERIPH_RSTEN3_UART4 0x308 +#define PERIPH_RSTEN3_SSP 0x309 +#define PERIPH_RSTEN3_PWM 0x30a +#define PERIPH_RSTEN3_BLPWM 0x30b +#define PERIPH_RSTEN3_TSENSOR 0x30c +#define PERIPH_RSTEN3_DAPB 0x312 +#define PERIPH_RSTEN3_HKADC 0x313 +#define PERIPH_RSTEN3_CODEC_SSI 0x314 +#define PERIPH_RSTEN3_PMUSSI1 0x316 +#define PERIPH_RSTEN8_RS0 0x400 +#define PERIPH_RSTEN8_RS2 0x401 +#define PERIPH_RSTEN8_RS3 0x402 +#define PERIPH_RSTEN8_MS0 0x403 +#define PERIPH_RSTEN8_MS2 0x405 +#define PERIPH_RSTEN8_XG2RAM0 0x406 +#define PERIPH_RSTEN8_X2SRAM_TZMA 0x407 +#define PERIPH_RSTEN8_SRAM 0x408 +#define PERIPH_RSTEN8_HARQ 0x40a +#define PERIPH_RSTEN8_DDRC 0x40c +#define PERIPH_RSTEN8_DDRC_APB 0x40d +#define PERIPH_RSTEN8_DDRPACK_APB 0x40e +#define PERIPH_RSTEN8_DDRT 0x411 +#define PERIPH_RSDIST9_CARM_DAP 0x500 +#define PERIPH_RSDIST9_CARM_ATB 0x501 +#define PERIPH_RSDIST9_CARM_LBUS 0x502 +#define PERIPH_RSDIST9_CARM_POR 0x503 +#define PERIPH_RSDIST9_CARM_CORE 0x504 +#define PERIPH_RSDIST9_CARM_DBG 0x505 +#define PERIPH_RSDIST9_CARM_L2 0x506 +#define PERIPH_RSDIST9_CARM_SOCDBG 0x507 +#define PERIPH_RSDIST9_CARM_ETM 0x508 + +#endif /*_DT_BINDINGS_RESET_CONTROLLER_HI6220*/ |