From 5987b4bf512101137fa60c5c0ccac3db51541221 Mon Sep 17 00:00:00 2001 From: Jiancheng Xue Date: Wed, 30 Nov 2016 09:03:32 +0800 Subject: reset: ti_syscon: fix a ti_syscon_reset_status issue If STATUS_SET was not set, ti_syscon_reset_status would always return 0 no matter whether the status_bit was set or not. Signed-off-by: Jiancheng Xue Fixes: cc7c2bb1493c ("reset: add TI SYSCON based reset driver") Signed-off-by: Philipp Zabel --- drivers/reset/reset-ti-syscon.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/reset') diff --git a/drivers/reset/reset-ti-syscon.c b/drivers/reset/reset-ti-syscon.c index 47f0ffd3b013..1799fd423901 100644 --- a/drivers/reset/reset-ti-syscon.c +++ b/drivers/reset/reset-ti-syscon.c @@ -154,8 +154,8 @@ static int ti_syscon_reset_status(struct reset_controller_dev *rcdev, if (ret) return ret; - return (reset_state & BIT(control->status_bit)) && - (control->flags & STATUS_SET); + return !(reset_state & BIT(control->status_bit)) == + !(control->flags & STATUS_SET); } static struct reset_control_ops ti_syscon_reset_ops = { -- cgit v1.2.3 From 1527058736fad60e37ca6103f0de39ca045c5fc5 Mon Sep 17 00:00:00 2001 From: Zhangfei Gao Date: Tue, 6 Dec 2016 09:51:32 +0800 Subject: reset: hisilicon: add reset-hi3660 Add hi3660 reset driver Example of dts usage: iomcu_rst: iomcu_rst_controller { compatible = "hisilicon,hi3660-reset"; hisi,rst-syscon = <&iomcu>; #reset-cells = <2>; }; i2c0: i2c@..... { ... resets = <&iomcu_rst 0x20 3>; /* offset: 0x20; bit: 3 */ ... }; Signed-off-by: Zhangfei Gao Signed-off-by: Philipp Zabel --- drivers/reset/hisilicon/Kconfig | 7 ++ drivers/reset/hisilicon/Makefile | 1 + drivers/reset/hisilicon/reset-hi3660.c | 126 +++++++++++++++++++++++++++++++++ 3 files changed, 134 insertions(+) create mode 100644 drivers/reset/hisilicon/reset-hi3660.c (limited to 'drivers/reset') diff --git a/drivers/reset/hisilicon/Kconfig b/drivers/reset/hisilicon/Kconfig index 1ff8b0c80980..10134dc03fe0 100644 --- a/drivers/reset/hisilicon/Kconfig +++ b/drivers/reset/hisilicon/Kconfig @@ -1,3 +1,10 @@ +config COMMON_RESET_HI3660 + tristate "Hi3660 Reset Driver" + depends on ARCH_HISI || COMPILE_TEST + default ARCH_HISI + help + Build the Hisilicon Hi3660 reset driver. + config COMMON_RESET_HI6220 tristate "Hi6220 Reset Driver" depends on ARCH_HISI || COMPILE_TEST diff --git a/drivers/reset/hisilicon/Makefile b/drivers/reset/hisilicon/Makefile index c932f86e2f10..ab8a7bfcbd8d 100644 --- a/drivers/reset/hisilicon/Makefile +++ b/drivers/reset/hisilicon/Makefile @@ -1 +1,2 @@ obj-$(CONFIG_COMMON_RESET_HI6220) += hi6220_reset.o +obj-$(CONFIG_COMMON_RESET_HI3660) += reset-hi3660.o diff --git a/drivers/reset/hisilicon/reset-hi3660.c b/drivers/reset/hisilicon/reset-hi3660.c new file mode 100644 index 000000000000..17d8bb128e6e --- /dev/null +++ b/drivers/reset/hisilicon/reset-hi3660.c @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2016-2017 Linaro Ltd. + * Copyright (c) 2016-2017 HiSilicon Technologies Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ +#include +#include +#include +#include +#include +#include +#include + +struct hi3660_reset_controller { + struct reset_controller_dev rst; + struct regmap *map; +}; + +#define to_hi3660_reset_controller(_rst) \ + container_of(_rst, struct hi3660_reset_controller, rst) + +static int hi3660_reset_program_hw(struct reset_controller_dev *rcdev, + unsigned long idx, bool assert) +{ + struct hi3660_reset_controller *rc = to_hi3660_reset_controller(rcdev); + unsigned int offset = idx >> 8; + unsigned int mask = BIT(idx & 0x1f); + + if (assert) + return regmap_write(rc->map, offset, mask); + else + return regmap_write(rc->map, offset + 4, mask); +} + +static int hi3660_reset_assert(struct reset_controller_dev *rcdev, + unsigned long idx) +{ + return hi3660_reset_program_hw(rcdev, idx, true); +} + +static int hi3660_reset_deassert(struct reset_controller_dev *rcdev, + unsigned long idx) +{ + return hi3660_reset_program_hw(rcdev, idx, false); +} + +static int hi3660_reset_dev(struct reset_controller_dev *rcdev, + unsigned long idx) +{ + int err; + + err = hi3660_reset_assert(rcdev, idx); + if (err) + return err; + + return hi3660_reset_deassert(rcdev, idx); +} + +static struct reset_control_ops hi3660_reset_ops = { + .reset = hi3660_reset_dev, + .assert = hi3660_reset_assert, + .deassert = hi3660_reset_deassert, +}; + +static int hi3660_reset_xlate(struct reset_controller_dev *rcdev, + const struct of_phandle_args *reset_spec) +{ + unsigned int offset, bit; + + offset = reset_spec->args[0]; + bit = reset_spec->args[1]; + + return (offset << 8) | bit; +} + +static int hi3660_reset_probe(struct platform_device *pdev) +{ + struct hi3660_reset_controller *rc; + struct device_node *np = pdev->dev.of_node; + struct device *dev = &pdev->dev; + + rc = devm_kzalloc(dev, sizeof(*rc), GFP_KERNEL); + if (!rc) + return -ENOMEM; + + rc->map = syscon_regmap_lookup_by_phandle(np, "hisi,rst-syscon"); + if (IS_ERR(rc->map)) { + dev_err(dev, "failed to get hi3660,rst-syscon\n"); + return PTR_ERR(rc->map); + } + + rc->rst.ops = &hi3660_reset_ops, + rc->rst.of_node = np; + rc->rst.of_reset_n_cells = 2; + rc->rst.of_xlate = hi3660_reset_xlate; + + return reset_controller_register(&rc->rst); +} + +static const struct of_device_id hi3660_reset_match[] = { + { .compatible = "hisilicon,hi3660-reset", }, + {}, +}; +MODULE_DEVICE_TABLE(of, hi3660_reset_match); + +static struct platform_driver hi3660_reset_driver = { + .probe = hi3660_reset_probe, + .driver = { + .name = "hi3660-reset", + .of_match_table = hi3660_reset_match, + }, +}; + +static int __init hi3660_reset_init(void) +{ + return platform_driver_register(&hi3660_reset_driver); +} +arch_initcall(hi3660_reset_init); + +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:hi3660-reset"); +MODULE_DESCRIPTION("HiSilicon Hi3660 Reset Driver"); -- cgit v1.2.3 From 1013258814bd396964cfcedc8fc590c9098266b3 Mon Sep 17 00:00:00 2001 From: Bhumika Goyal Date: Mon, 9 Jan 2017 22:23:55 +0530 Subject: reset: constify reset_control_ops structures Declare reset_control_ops structures as const as they are only stored in the ops field of a reset_controller_dev structure. This field is of type const struct reset_control_ops *, so reset_control_ops structures having this property can be declared as const. Done using Coccinelle: @r1 disable optional_qualifier@ identifier i; position p; @@ static struct reset_control_ops i@p={...}; @ok1@ identifier r1.i; position p; struct ti_syscon_reset_data data; @@ data.rcdev.ops=&i@p; @bad@ position p!={r1.p,ok1.p}; identifier r1.i; @@ i@p @depends on !bad disable optional_qualifier@ identifier r1.i; @@ +const struct reset_control_ops i; File size before: drivers/reset/reset-ti-syscon.o text data bss dec hex filename 1329 240 0 1569 621 drivers/reset/reset-ti-syscon.o File size after: drivers/reset/reset-ti-syscon.o text data bss dec hex filename 1377 192 0 1569 621 drivers/reset/reset-ti-syscon.o Signed-off-by: Bhumika Goyal Signed-off-by: Philipp Zabel --- drivers/reset/reset-ti-syscon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/reset') diff --git a/drivers/reset/reset-ti-syscon.c b/drivers/reset/reset-ti-syscon.c index 1799fd423901..99520b0a1329 100644 --- a/drivers/reset/reset-ti-syscon.c +++ b/drivers/reset/reset-ti-syscon.c @@ -158,7 +158,7 @@ static int ti_syscon_reset_status(struct reset_controller_dev *rcdev, !(control->flags & STATUS_SET); } -static struct reset_control_ops ti_syscon_reset_ops = { +static const struct reset_control_ops ti_syscon_reset_ops = { .assert = ti_syscon_reset_assert, .deassert = ti_syscon_reset_deassert, .status = ti_syscon_reset_status, -- cgit v1.2.3 From b38386f46bc7b8871665d863246476c9b6eb89ec Mon Sep 17 00:00:00 2001 From: Baoyou Xie Date: Tue, 17 Jan 2017 11:22:57 +0800 Subject: reset: zx2967: add reset controller driver for ZTE's zx2967 family This patch adds reset controller driver for ZTE's zx2967 family. Signed-off-by: Baoyou Xie Reviewed-by: Shawn Guo Signed-off-by: Philipp Zabel --- drivers/reset/Kconfig | 6 +++ drivers/reset/Makefile | 1 + drivers/reset/reset-zx2967.c | 106 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 113 insertions(+) create mode 100644 drivers/reset/reset-zx2967.c (limited to 'drivers/reset') diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index 172dc966a01f..f4cdfe94b9ec 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -86,6 +86,12 @@ config RESET_UNIPHIER Say Y if you want to control reset signals provided by System Control block, Media I/O block, Peripheral Block. +config RESET_ZX2967 + bool "ZTE ZX2967 Reset Driver" + depends on ARCH_ZX || COMPILE_TEST + help + This enables the reset controller driver for ZTE's zx2967 family. + config RESET_ZYNQ bool "ZYNQ Reset Driver" if COMPILE_TEST default ARCH_ZYNQ diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile index 13b346e03d84..2cd3f6c45165 100644 --- a/drivers/reset/Makefile +++ b/drivers/reset/Makefile @@ -13,4 +13,5 @@ obj-$(CONFIG_RESET_STM32) += reset-stm32.o obj-$(CONFIG_RESET_SUNXI) += reset-sunxi.o obj-$(CONFIG_TI_SYSCON_RESET) += reset-ti-syscon.o obj-$(CONFIG_RESET_UNIPHIER) += reset-uniphier.o +obj-$(CONFIG_RESET_ZX2967) += reset-zx2967.o obj-$(CONFIG_RESET_ZYNQ) += reset-zynq.o diff --git a/drivers/reset/reset-zx2967.c b/drivers/reset/reset-zx2967.c new file mode 100644 index 000000000000..5d821513aa3e --- /dev/null +++ b/drivers/reset/reset-zx2967.c @@ -0,0 +1,106 @@ +/* + * ZTE's zx2967 family reset controller driver + * + * Copyright (C) 2017 ZTE Ltd. + * + * Author: Baoyou Xie + * + * License terms: GNU General Public License (GPL) version 2 + */ + +#include +#include +#include +#include + +struct zx2967_reset { + void __iomem *reg_base; + spinlock_t lock; + struct reset_controller_dev rcdev; +}; + +static int zx2967_reset_act(struct reset_controller_dev *rcdev, + unsigned long id, bool assert) +{ + struct zx2967_reset *reset = NULL; + int bank = id / 32; + int offset = id % 32; + u32 reg; + unsigned long flags; + + reset = container_of(rcdev, struct zx2967_reset, rcdev); + + spin_lock_irqsave(&reset->lock, flags); + + reg = readl_relaxed(reset->reg_base + (bank * 4)); + if (assert) + reg &= ~BIT(offset); + else + reg |= BIT(offset); + writel_relaxed(reg, reset->reg_base + (bank * 4)); + + spin_unlock_irqrestore(&reset->lock, flags); + + return 0; +} + +static int zx2967_reset_assert(struct reset_controller_dev *rcdev, + unsigned long id) +{ + return zx2967_reset_act(rcdev, id, true); +} + +static int zx2967_reset_deassert(struct reset_controller_dev *rcdev, + unsigned long id) +{ + return zx2967_reset_act(rcdev, id, false); +} + +static struct reset_control_ops zx2967_reset_ops = { + .assert = zx2967_reset_assert, + .deassert = zx2967_reset_deassert, +}; + +static int zx2967_reset_probe(struct platform_device *pdev) +{ + struct zx2967_reset *reset; + struct resource *res; + + reset = devm_kzalloc(&pdev->dev, sizeof(*reset), GFP_KERNEL); + if (!reset) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + reset->reg_base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(reset->reg_base)) + return PTR_ERR(reset->reg_base); + + spin_lock_init(&reset->lock); + + reset->rcdev.owner = THIS_MODULE; + reset->rcdev.nr_resets = resource_size(res) * 8; + reset->rcdev.ops = &zx2967_reset_ops; + reset->rcdev.of_node = pdev->dev.of_node; + + return devm_reset_controller_register(&pdev->dev, &reset->rcdev); +} + +static const struct of_device_id zx2967_reset_dt_ids[] = { + { .compatible = "zte,zx296718-reset", }, + {}, +}; +MODULE_DEVICE_TABLE(of, zx2967_reset_dt_ids); + +static struct platform_driver zx2967_reset_driver = { + .probe = zx2967_reset_probe, + .driver = { + .name = "zx2967-reset", + .of_match_table = zx2967_reset_dt_ids, + }, +}; + +builtin_platform_driver(zx2967_reset_driver); + +MODULE_AUTHOR("Baoyou Xie "); +MODULE_DESCRIPTION("ZTE zx2967 Reset Controller Driver"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 88a7f5237dfdd7f02939c4ec7ac7452e14adceab Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 15 Jan 2017 04:04:46 +0900 Subject: reset: uniphier: add compatible string for LD11 SD-reset block The LD11 SoC is equipped with not only MIO-reset but also SD-reset for controlling RST_n pin of the eMMC device. Update the binding document and remove unneeded "." from each line in itemization. Signed-off-by: Masahiro Yamada Signed-off-by: Philipp Zabel --- .../devicetree/bindings/reset/uniphier-reset.txt | 47 +++++++++++----------- drivers/reset/reset-uniphier.c | 4 ++ 2 files changed, 28 insertions(+), 23 deletions(-) (limited to 'drivers/reset') diff --git a/Documentation/devicetree/bindings/reset/uniphier-reset.txt b/Documentation/devicetree/bindings/reset/uniphier-reset.txt index 5020524cddeb..83ab0f599c40 100644 --- a/Documentation/devicetree/bindings/reset/uniphier-reset.txt +++ b/Documentation/devicetree/bindings/reset/uniphier-reset.txt @@ -6,14 +6,14 @@ System reset Required properties: - compatible: should be one of the following: - "socionext,uniphier-sld3-reset" - for sLD3 SoC. - "socionext,uniphier-ld4-reset" - for LD4 SoC. - "socionext,uniphier-pro4-reset" - for Pro4 SoC. - "socionext,uniphier-sld8-reset" - for sLD8 SoC. - "socionext,uniphier-pro5-reset" - for Pro5 SoC. - "socionext,uniphier-pxs2-reset" - for PXs2/LD6b SoC. - "socionext,uniphier-ld11-reset" - for LD11 SoC. - "socionext,uniphier-ld20-reset" - for LD20 SoC. + "socionext,uniphier-sld3-reset" - for sLD3 SoC + "socionext,uniphier-ld4-reset" - for LD4 SoC + "socionext,uniphier-pro4-reset" - for Pro4 SoC + "socionext,uniphier-sld8-reset" - for sLD8 SoC + "socionext,uniphier-pro5-reset" - for Pro5 SoC + "socionext,uniphier-pxs2-reset" - for PXs2/LD6b SoC + "socionext,uniphier-ld11-reset" - for LD11 SoC + "socionext,uniphier-ld20-reset" - for LD20 SoC - #reset-cells: should be 1. Example: @@ -37,14 +37,15 @@ Media I/O (MIO) reset, SD reset Required properties: - compatible: should be one of the following: - "socionext,uniphier-sld3-mio-reset" - for sLD3 SoC. - "socionext,uniphier-ld4-mio-reset" - for LD4 SoC. - "socionext,uniphier-pro4-mio-reset" - for Pro4 SoC. - "socionext,uniphier-sld8-mio-reset" - for sLD8 SoC. - "socionext,uniphier-pro5-sd-reset" - for Pro5 SoC. - "socionext,uniphier-pxs2-sd-reset" - for PXs2/LD6b SoC. - "socionext,uniphier-ld11-mio-reset" - for LD11 SoC. - "socionext,uniphier-ld20-sd-reset" - for LD20 SoC. + "socionext,uniphier-sld3-mio-reset" - for sLD3 SoC + "socionext,uniphier-ld4-mio-reset" - for LD4 SoC + "socionext,uniphier-pro4-mio-reset" - for Pro4 SoC + "socionext,uniphier-sld8-mio-reset" - for sLD8 SoC + "socionext,uniphier-pro5-sd-reset" - for Pro5 SoC + "socionext,uniphier-pxs2-sd-reset" - for PXs2/LD6b SoC + "socionext,uniphier-ld11-mio-reset" - for LD11 SoC (MIO) + "socionext,uniphier-ld11-sd-reset" - for LD11 SoC (SD) + "socionext,uniphier-ld20-sd-reset" - for LD20 SoC - #reset-cells: should be 1. Example: @@ -68,13 +69,13 @@ Peripheral reset Required properties: - compatible: should be one of the following: - "socionext,uniphier-ld4-peri-reset" - for LD4 SoC. - "socionext,uniphier-pro4-peri-reset" - for Pro4 SoC. - "socionext,uniphier-sld8-peri-reset" - for sLD8 SoC. - "socionext,uniphier-pro5-peri-reset" - for Pro5 SoC. - "socionext,uniphier-pxs2-peri-reset" - for PXs2/LD6b SoC. - "socionext,uniphier-ld11-peri-reset" - for LD11 SoC. - "socionext,uniphier-ld20-peri-reset" - for LD20 SoC. + "socionext,uniphier-ld4-peri-reset" - for LD4 SoC + "socionext,uniphier-pro4-peri-reset" - for Pro4 SoC + "socionext,uniphier-sld8-peri-reset" - for sLD8 SoC + "socionext,uniphier-pro5-peri-reset" - for Pro5 SoC + "socionext,uniphier-pxs2-peri-reset" - for PXs2/LD6b SoC + "socionext,uniphier-ld11-peri-reset" - for LD11 SoC + "socionext,uniphier-ld20-peri-reset" - for LD20 SoC - #reset-cells: should be 1. Example: diff --git a/drivers/reset/reset-uniphier.c b/drivers/reset/reset-uniphier.c index 968c3ae4535c..9c11be3d3450 100644 --- a/drivers/reset/reset-uniphier.c +++ b/drivers/reset/reset-uniphier.c @@ -389,6 +389,10 @@ static const struct of_device_id uniphier_reset_match[] = { .compatible = "socionext,uniphier-ld11-mio-reset", .data = uniphier_sld3_mio_reset_data, }, + { + .compatible = "socionext,uniphier-ld11-sd-reset", + .data = uniphier_pro5_sd_reset_data, + }, { .compatible = "socionext,uniphier-ld20-sd-reset", .data = uniphier_pro5_sd_reset_data, -- cgit v1.2.3 From ee48c726d0b014ac8dd5ec803fb63ce0596a42cf Mon Sep 17 00:00:00 2001 From: Ramiro Oliveira Date: Fri, 13 Jan 2017 17:57:40 +0000 Subject: reset: Change shared flag from int to bool Since the new parameter being added is going to be a bool this patch changes the shared flag from int to bool to match the new parameter. Signed-off-by: Ramiro Oliveira Signed-off-by: Philipp Zabel --- drivers/reset/core.c | 8 ++++---- include/linux/reset.h | 32 ++++++++++++++++---------------- 2 files changed, 20 insertions(+), 20 deletions(-) (limited to 'drivers/reset') diff --git a/drivers/reset/core.c b/drivers/reset/core.c index 10368ed8fd13..272c1e4ecb5c 100644 --- a/drivers/reset/core.c +++ b/drivers/reset/core.c @@ -41,7 +41,7 @@ struct reset_control { struct list_head list; unsigned int id; unsigned int refcnt; - int shared; + bool shared; atomic_t deassert_count; atomic_t triggered_count; }; @@ -254,7 +254,7 @@ EXPORT_SYMBOL_GPL(reset_control_status); static struct reset_control *__reset_control_get( struct reset_controller_dev *rcdev, - unsigned int index, int shared) + unsigned int index, bool shared) { struct reset_control *rstc; @@ -299,7 +299,7 @@ static void __reset_control_put(struct reset_control *rstc) } struct reset_control *__of_reset_control_get(struct device_node *node, - const char *id, int index, int shared) + const char *id, int index, bool shared) { struct reset_control *rstc; struct reset_controller_dev *r, *rcdev; @@ -379,7 +379,7 @@ static void devm_reset_control_release(struct device *dev, void *res) } struct reset_control *__devm_reset_control_get(struct device *dev, - const char *id, int index, int shared) + const char *id, int index, bool shared) { struct reset_control **ptr, *rstc; diff --git a/include/linux/reset.h b/include/linux/reset.h index 5daff15722d3..ec1d1fd28f5f 100644 --- a/include/linux/reset.h +++ b/include/linux/reset.h @@ -13,10 +13,10 @@ int reset_control_deassert(struct reset_control *rstc); int reset_control_status(struct reset_control *rstc); struct reset_control *__of_reset_control_get(struct device_node *node, - const char *id, int index, int shared); + const char *id, int index, bool shared); void reset_control_put(struct reset_control *rstc); struct reset_control *__devm_reset_control_get(struct device *dev, - const char *id, int index, int shared); + const char *id, int index, bool shared); int __must_check device_reset(struct device *dev); @@ -69,14 +69,14 @@ static inline int device_reset_optional(struct device *dev) static inline struct reset_control *__of_reset_control_get( struct device_node *node, - const char *id, int index, int shared) + const char *id, int index, bool shared) { return ERR_PTR(-ENOTSUPP); } static inline struct reset_control *__devm_reset_control_get( struct device *dev, - const char *id, int index, int shared) + const char *id, int index, bool shared) { return ERR_PTR(-ENOTSUPP); } @@ -132,19 +132,19 @@ __must_check reset_control_get_exclusive(struct device *dev, const char *id) static inline struct reset_control *reset_control_get_shared( struct device *dev, const char *id) { - return __of_reset_control_get(dev ? dev->of_node : NULL, id, 0, 1); + return __of_reset_control_get(dev ? dev->of_node : NULL, id, 0, true); } static inline struct reset_control *reset_control_get_optional_exclusive( struct device *dev, const char *id) { - return __of_reset_control_get(dev ? dev->of_node : NULL, id, 0, 0); + return __of_reset_control_get(dev ? dev->of_node : NULL, id, 0, false); } static inline struct reset_control *reset_control_get_optional_shared( struct device *dev, const char *id) { - return __of_reset_control_get(dev ? dev->of_node : NULL, id, 0, 1); + return __of_reset_control_get(dev ? dev->of_node : NULL, id, 0, true); } /** @@ -185,7 +185,7 @@ static inline struct reset_control *of_reset_control_get_exclusive( static inline struct reset_control *of_reset_control_get_shared( struct device_node *node, const char *id) { - return __of_reset_control_get(node, id, 0, 1); + return __of_reset_control_get(node, id, 0, true); } /** @@ -202,7 +202,7 @@ static inline struct reset_control *of_reset_control_get_shared( static inline struct reset_control *of_reset_control_get_exclusive_by_index( struct device_node *node, int index) { - return __of_reset_control_get(node, NULL, index, 0); + return __of_reset_control_get(node, NULL, index, false); } /** @@ -230,7 +230,7 @@ static inline struct reset_control *of_reset_control_get_exclusive_by_index( static inline struct reset_control *of_reset_control_get_shared_by_index( struct device_node *node, int index) { - return __of_reset_control_get(node, NULL, index, 1); + return __of_reset_control_get(node, NULL, index, true); } /** @@ -252,7 +252,7 @@ __must_check devm_reset_control_get_exclusive(struct device *dev, #ifndef CONFIG_RESET_CONTROLLER WARN_ON(1); #endif - return __devm_reset_control_get(dev, id, 0, 0); + return __devm_reset_control_get(dev, id, 0, false); } /** @@ -267,19 +267,19 @@ __must_check devm_reset_control_get_exclusive(struct device *dev, static inline struct reset_control *devm_reset_control_get_shared( struct device *dev, const char *id) { - return __devm_reset_control_get(dev, id, 0, 1); + return __devm_reset_control_get(dev, id, 0, true); } static inline struct reset_control *devm_reset_control_get_optional_exclusive( struct device *dev, const char *id) { - return __devm_reset_control_get(dev, id, 0, 0); + return __devm_reset_control_get(dev, id, 0, false); } static inline struct reset_control *devm_reset_control_get_optional_shared( struct device *dev, const char *id) { - return __devm_reset_control_get(dev, id, 0, 1); + return __devm_reset_control_get(dev, id, 0, true); } /** @@ -297,7 +297,7 @@ static inline struct reset_control *devm_reset_control_get_optional_shared( static inline struct reset_control * devm_reset_control_get_exclusive_by_index(struct device *dev, int index) { - return __devm_reset_control_get(dev, NULL, index, 0); + return __devm_reset_control_get(dev, NULL, index, false); } /** @@ -313,7 +313,7 @@ devm_reset_control_get_exclusive_by_index(struct device *dev, int index) static inline struct reset_control * devm_reset_control_get_shared_by_index(struct device *dev, int index) { - return __devm_reset_control_get(dev, NULL, index, 1); + return __devm_reset_control_get(dev, NULL, index, true); } /* -- cgit v1.2.3 From bb475230b8e59a547ab66ac3b02572df21a580e9 Mon Sep 17 00:00:00 2001 From: Ramiro Oliveira Date: Fri, 13 Jan 2017 17:57:41 +0000 Subject: reset: make optional functions really optional The *_get_optional_* functions weren't really optional so this patch makes them really optional. These *_get_optional_* functions will now return NULL instead of an error if no matching reset phandle is found in the DT, and all the reset_control_* functions now accept NULL rstc pointers. Signed-off-by: Ramiro Oliveira Signed-off-by: Philipp Zabel --- drivers/reset/core.c | 49 +++++++++++++++++++++++++++++++++++++++---------- include/linux/reset.h | 45 ++++++++++++++++++++++++++------------------- 2 files changed, 65 insertions(+), 29 deletions(-) (limited to 'drivers/reset') diff --git a/drivers/reset/core.c b/drivers/reset/core.c index 272c1e4ecb5c..c79cce3a7b6d 100644 --- a/drivers/reset/core.c +++ b/drivers/reset/core.c @@ -143,12 +143,18 @@ EXPORT_SYMBOL_GPL(devm_reset_controller_register); * a no-op. * Consumers must not use reset_control_(de)assert on shared reset lines when * reset_control_reset has been used. + * + * If rstc is NULL it is an optional reset and the function will just + * return 0. */ int reset_control_reset(struct reset_control *rstc) { int ret; - if (WARN_ON(IS_ERR_OR_NULL(rstc))) + if (!rstc) + return 0; + + if (WARN_ON(IS_ERR(rstc))) return -EINVAL; if (!rstc->rcdev->ops->reset) @@ -182,10 +188,17 @@ EXPORT_SYMBOL_GPL(reset_control_reset); * internal state to be reset, but must be prepared for this to happen. * Consumers must not use reset_control_reset on shared reset lines when * reset_control_(de)assert has been used. + * return 0. + * + * If rstc is NULL it is an optional reset and the function will just + * return 0. */ int reset_control_assert(struct reset_control *rstc) { - if (WARN_ON(IS_ERR_OR_NULL(rstc))) + if (!rstc) + return 0; + + if (WARN_ON(IS_ERR(rstc))) return -EINVAL; if (!rstc->rcdev->ops->assert) @@ -213,10 +226,17 @@ EXPORT_SYMBOL_GPL(reset_control_assert); * After calling this function, the reset is guaranteed to be deasserted. * Consumers must not use reset_control_reset on shared reset lines when * reset_control_(de)assert has been used. + * return 0. + * + * If rstc is NULL it is an optional reset and the function will just + * return 0. */ int reset_control_deassert(struct reset_control *rstc) { - if (WARN_ON(IS_ERR_OR_NULL(rstc))) + if (!rstc) + return 0; + + if (WARN_ON(IS_ERR(rstc))) return -EINVAL; if (!rstc->rcdev->ops->deassert) @@ -237,12 +257,15 @@ EXPORT_SYMBOL_GPL(reset_control_deassert); /** * reset_control_status - returns a negative errno if not supported, a * positive value if the reset line is asserted, or zero if the reset - * line is not asserted. + * line is not asserted or if the desc is NULL (optional reset). * @rstc: reset controller */ int reset_control_status(struct reset_control *rstc) { - if (WARN_ON(IS_ERR_OR_NULL(rstc))) + if (!rstc) + return 0; + + if (WARN_ON(IS_ERR(rstc))) return -EINVAL; if (rstc->rcdev->ops->status) @@ -299,7 +322,8 @@ static void __reset_control_put(struct reset_control *rstc) } struct reset_control *__of_reset_control_get(struct device_node *node, - const char *id, int index, bool shared) + const char *id, int index, bool shared, + bool optional) { struct reset_control *rstc; struct reset_controller_dev *r, *rcdev; @@ -313,14 +337,18 @@ struct reset_control *__of_reset_control_get(struct device_node *node, if (id) { index = of_property_match_string(node, "reset-names", id); + if (index == -EILSEQ) + return ERR_PTR(index); if (index < 0) - return ERR_PTR(-ENOENT); + return optional ? NULL : ERR_PTR(-ENOENT); } ret = of_parse_phandle_with_args(node, "resets", "#reset-cells", index, &args); - if (ret) + if (ret == -EINVAL) return ERR_PTR(ret); + if (ret) + return optional ? NULL : ERR_PTR(ret); mutex_lock(&reset_list_mutex); rcdev = NULL; @@ -379,7 +407,8 @@ static void devm_reset_control_release(struct device *dev, void *res) } struct reset_control *__devm_reset_control_get(struct device *dev, - const char *id, int index, bool shared) + const char *id, int index, bool shared, + bool optional) { struct reset_control **ptr, *rstc; @@ -389,7 +418,7 @@ struct reset_control *__devm_reset_control_get(struct device *dev, return ERR_PTR(-ENOMEM); rstc = __of_reset_control_get(dev ? dev->of_node : NULL, - id, index, shared); + id, index, shared, optional); if (!IS_ERR(rstc)) { *ptr = rstc; devres_add(dev, ptr); diff --git a/include/linux/reset.h b/include/linux/reset.h index ec1d1fd28f5f..86b4ed75359e 100644 --- a/include/linux/reset.h +++ b/include/linux/reset.h @@ -13,10 +13,12 @@ int reset_control_deassert(struct reset_control *rstc); int reset_control_status(struct reset_control *rstc); struct reset_control *__of_reset_control_get(struct device_node *node, - const char *id, int index, bool shared); + const char *id, int index, bool shared, + bool optional); void reset_control_put(struct reset_control *rstc); struct reset_control *__devm_reset_control_get(struct device *dev, - const char *id, int index, bool shared); + const char *id, int index, bool shared, + bool optional); int __must_check device_reset(struct device *dev); @@ -69,14 +71,15 @@ static inline int device_reset_optional(struct device *dev) static inline struct reset_control *__of_reset_control_get( struct device_node *node, - const char *id, int index, bool shared) + const char *id, int index, bool shared, + bool optional) { return ERR_PTR(-ENOTSUPP); } static inline struct reset_control *__devm_reset_control_get( - struct device *dev, - const char *id, int index, bool shared) + struct device *dev, const char *id, + int index, bool shared, bool optional) { return ERR_PTR(-ENOTSUPP); } @@ -104,7 +107,8 @@ __must_check reset_control_get_exclusive(struct device *dev, const char *id) #ifndef CONFIG_RESET_CONTROLLER WARN_ON(1); #endif - return __of_reset_control_get(dev ? dev->of_node : NULL, id, 0, 0); + return __of_reset_control_get(dev ? dev->of_node : NULL, id, 0, false, + false); } /** @@ -132,19 +136,22 @@ __must_check reset_control_get_exclusive(struct device *dev, const char *id) static inline struct reset_control *reset_control_get_shared( struct device *dev, const char *id) { - return __of_reset_control_get(dev ? dev->of_node : NULL, id, 0, true); + return __of_reset_control_get(dev ? dev->of_node : NULL, id, 0, true, + false); } static inline struct reset_control *reset_control_get_optional_exclusive( struct device *dev, const char *id) { - return __of_reset_control_get(dev ? dev->of_node : NULL, id, 0, false); + return __of_reset_control_get(dev ? dev->of_node : NULL, id, 0, false, + true); } static inline struct reset_control *reset_control_get_optional_shared( struct device *dev, const char *id) { - return __of_reset_control_get(dev ? dev->of_node : NULL, id, 0, true); + return __of_reset_control_get(dev ? dev->of_node : NULL, id, 0, true, + true); } /** @@ -160,7 +167,7 @@ static inline struct reset_control *reset_control_get_optional_shared( static inline struct reset_control *of_reset_control_get_exclusive( struct device_node *node, const char *id) { - return __of_reset_control_get(node, id, 0, 0); + return __of_reset_control_get(node, id, 0, false, false); } /** @@ -185,7 +192,7 @@ static inline struct reset_control *of_reset_control_get_exclusive( static inline struct reset_control *of_reset_control_get_shared( struct device_node *node, const char *id) { - return __of_reset_control_get(node, id, 0, true); + return __of_reset_control_get(node, id, 0, true, false); } /** @@ -202,7 +209,7 @@ static inline struct reset_control *of_reset_control_get_shared( static inline struct reset_control *of_reset_control_get_exclusive_by_index( struct device_node *node, int index) { - return __of_reset_control_get(node, NULL, index, false); + return __of_reset_control_get(node, NULL, index, false, false); } /** @@ -230,7 +237,7 @@ static inline struct reset_control *of_reset_control_get_exclusive_by_index( static inline struct reset_control *of_reset_control_get_shared_by_index( struct device_node *node, int index) { - return __of_reset_control_get(node, NULL, index, true); + return __of_reset_control_get(node, NULL, index, true, false); } /** @@ -252,7 +259,7 @@ __must_check devm_reset_control_get_exclusive(struct device *dev, #ifndef CONFIG_RESET_CONTROLLER WARN_ON(1); #endif - return __devm_reset_control_get(dev, id, 0, false); + return __devm_reset_control_get(dev, id, 0, false, false); } /** @@ -267,19 +274,19 @@ __must_check devm_reset_control_get_exclusive(struct device *dev, static inline struct reset_control *devm_reset_control_get_shared( struct device *dev, const char *id) { - return __devm_reset_control_get(dev, id, 0, true); + return __devm_reset_control_get(dev, id, 0, true, false); } static inline struct reset_control *devm_reset_control_get_optional_exclusive( struct device *dev, const char *id) { - return __devm_reset_control_get(dev, id, 0, false); + return __devm_reset_control_get(dev, id, 0, false, true); } static inline struct reset_control *devm_reset_control_get_optional_shared( struct device *dev, const char *id) { - return __devm_reset_control_get(dev, id, 0, true); + return __devm_reset_control_get(dev, id, 0, true, true); } /** @@ -297,7 +304,7 @@ static inline struct reset_control *devm_reset_control_get_optional_shared( static inline struct reset_control * devm_reset_control_get_exclusive_by_index(struct device *dev, int index) { - return __devm_reset_control_get(dev, NULL, index, false); + return __devm_reset_control_get(dev, NULL, index, false, false); } /** @@ -313,7 +320,7 @@ devm_reset_control_get_exclusive_by_index(struct device *dev, int index) static inline struct reset_control * devm_reset_control_get_shared_by_index(struct device *dev, int index) { - return __devm_reset_control_get(dev, NULL, index, true); + return __devm_reset_control_get(dev, NULL, index, true, false); } /* -- cgit v1.2.3 From 4891486fb2c80eaf3bb0f9eb065d15ecd357702f Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Wed, 1 Feb 2017 08:05:22 +0100 Subject: reset: core: fix reset_control_put Commit "reset: make optional functions really optional" missed to adjust one check in reset_control_put, causing a NULL pointer access for optional resets. Fixes: bb475230b8e5 "reset: make optional functions really optional" Signed-off-by: Heiner Kallweit Signed-off-by: Philipp Zabel --- drivers/reset/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/reset') diff --git a/drivers/reset/core.c b/drivers/reset/core.c index c79cce3a7b6d..71ccf281dce3 100644 --- a/drivers/reset/core.c +++ b/drivers/reset/core.c @@ -392,7 +392,7 @@ EXPORT_SYMBOL_GPL(__of_reset_control_get); void reset_control_put(struct reset_control *rstc) { - if (IS_ERR(rstc)) + if (IS_ERR_OR_NULL(rstc)) return; mutex_lock(&reset_list_mutex); -- cgit v1.2.3 From 7a1ca76dba35d1a443278811fb67625f0e98a713 Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Thu, 2 Feb 2017 09:52:12 -0500 Subject: reset: make zx2967 explicitly non-modular The Kconfig currently controlling compilation of this code is: config RESET_ZX2967 bool "ZTE ZX2967 Reset Driver ...meaning that it currently is not being built as a module by anyone. Lets remove the couple traces of modular infrastructure use, so that when reading the driver there is no doubt it is builtin-only. Since builtin_platform_driver() was already in use, the init ordering remains unchanged with this commit. Also note that MODULE_DEVICE_TABLE is a no-op for non-modular code. We also delete the MODULE_LICENSE tag etc. since all that information is already contained at the top of the file in the comments. We don't replace module.h with init.h since the file does not appear to use __init prefix anywhere. Cc: Jun Nie Signed-off-by: Paul Gortmaker Reviewed-by: Baoyou Xie Signed-off-by: Philipp Zabel --- drivers/reset/reset-zx2967.c | 7 ------- 1 file changed, 7 deletions(-) (limited to 'drivers/reset') diff --git a/drivers/reset/reset-zx2967.c b/drivers/reset/reset-zx2967.c index 5d821513aa3e..4dabb9ec4841 100644 --- a/drivers/reset/reset-zx2967.c +++ b/drivers/reset/reset-zx2967.c @@ -8,7 +8,6 @@ * License terms: GNU General Public License (GPL) version 2 */ -#include #include #include #include @@ -89,7 +88,6 @@ static const struct of_device_id zx2967_reset_dt_ids[] = { { .compatible = "zte,zx296718-reset", }, {}, }; -MODULE_DEVICE_TABLE(of, zx2967_reset_dt_ids); static struct platform_driver zx2967_reset_driver = { .probe = zx2967_reset_probe, @@ -98,9 +96,4 @@ static struct platform_driver zx2967_reset_driver = { .of_match_table = zx2967_reset_dt_ids, }, }; - builtin_platform_driver(zx2967_reset_driver); - -MODULE_AUTHOR("Baoyou Xie "); -MODULE_DESCRIPTION("ZTE zx2967 Reset Controller Driver"); -MODULE_LICENSE("GPL"); -- cgit v1.2.3