From 887758c325487ac747e03d552de42ec0ceaf214d Mon Sep 17 00:00:00 2001 From: Shawn Lin Date: Thu, 25 May 2017 15:58:24 +0800 Subject: soc: rockchip: disable jtag switching for RK3328 Soc Disable IO function switching between sdmmc and jtag for RK3328 Soc. Signed-off-by: Shawn Lin Signed-off-by: Heiko Stuebner --- drivers/soc/rockchip/grf.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'drivers') diff --git a/drivers/soc/rockchip/grf.c b/drivers/soc/rockchip/grf.c index d61db34ad6dd..15e71fd6c513 100644 --- a/drivers/soc/rockchip/grf.c +++ b/drivers/soc/rockchip/grf.c @@ -54,6 +54,17 @@ static const struct rockchip_grf_info rk3288_grf __initconst = { .num_values = ARRAY_SIZE(rk3288_defaults), }; +#define RK3328_GRF_SOC_CON4 0x410 + +static const struct rockchip_grf_value rk3328_defaults[] __initconst = { + { "jtag switching", RK3328_GRF_SOC_CON4, HIWORD_UPDATE(0, 1, 12) }, +}; + +static const struct rockchip_grf_info rk3328_grf __initconst = { + .values = rk3328_defaults, + .num_values = ARRAY_SIZE(rk3328_defaults), +}; + #define RK3368_GRF_SOC_CON15 0x43c static const struct rockchip_grf_value rk3368_defaults[] __initconst = { @@ -83,6 +94,9 @@ static const struct of_device_id rockchip_grf_dt_match[] __initconst = { }, { .compatible = "rockchip,rk3288-grf", .data = (void *)&rk3288_grf, + }, { + .compatible = "rockchip,rk3328-grf", + .data = (void *)&rk3328_grf, }, { .compatible = "rockchip,rk3368-grf", .data = (void *)&rk3368_grf, -- cgit v1.2.3-59-g8ed1b From 01da10e11f7b5a3944df5a77fefb1c2021a63092 Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Tue, 13 Jun 2017 10:22:32 +0530 Subject: reset: zx2967: constify zx2967_reset_ops. File size before: text data bss dec hex filename 794 232 0 1026 402 drivers/reset/reset-zx2967.o File size After adding 'const': text data bss dec hex filename 842 184 0 1026 402 drivers/reset/reset-zx2967.o Signed-off-by: Arvind Yadav Reviewed-by: Baoyou Xie Signed-off-by: Philipp Zabel --- drivers/reset/reset-zx2967.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/reset/reset-zx2967.c b/drivers/reset/reset-zx2967.c index 4dabb9ec4841..4f319f7753d4 100644 --- a/drivers/reset/reset-zx2967.c +++ b/drivers/reset/reset-zx2967.c @@ -55,7 +55,7 @@ static int zx2967_reset_deassert(struct reset_controller_dev *rcdev, return zx2967_reset_act(rcdev, id, false); } -static struct reset_control_ops zx2967_reset_ops = { +static const struct reset_control_ops zx2967_reset_ops = { .assert = zx2967_reset_assert, .deassert = zx2967_reset_deassert, }; -- cgit v1.2.3-59-g8ed1b From 17c82e206d2a3cd876b64921c59116f1ecdce6ad Mon Sep 17 00:00:00 2001 From: Vivek Gautam Date: Mon, 22 May 2017 16:53:25 +0530 Subject: reset: Add APIs to manage array of resets Many devices may want to request a bunch of resets and control them. So it's better to manage them as an array. Add APIs to _get() an array of reset_control, reusing the _assert(), _deassert(), and _reset() APIs for single reset controls. Since reset controls already may control multiple reset lines with a single hardware bit, from the user perspective, reset control arrays are not at all different from single reset controls. Note that these APIs don't guarantee that the reset lines managed in the array are handled in any particular order. Cc: Felipe Balbi Cc: Jon Hunter Signed-off-by: Vivek Gautam [p.zabel@pengutronix.de: changed API to hide reset control arrays behind struct reset_control] Signed-off-by: Philipp Zabel --- drivers/reset/core.c | 211 +++++++++++++++++++++++++++++++++++++++++++++++++- include/linux/reset.h | 68 ++++++++++++++++ 2 files changed, 278 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/reset/core.c b/drivers/reset/core.c index 0090784ff410..c8fb4426b218 100644 --- a/drivers/reset/core.c +++ b/drivers/reset/core.c @@ -43,10 +43,23 @@ struct reset_control { unsigned int id; struct kref refcnt; bool shared; + bool array; atomic_t deassert_count; atomic_t triggered_count; }; +/** + * struct reset_control_array - an array of reset controls + * @base: reset control for compatibility with reset control API functions + * @num_rstcs: number of reset controls + * @rstc: array of reset controls + */ +struct reset_control_array { + struct reset_control base; + unsigned int num_rstcs; + struct reset_control *rstc[]; +}; + /** * of_reset_simple_xlate - translate reset_spec to the reset line number * @rcdev: a pointer to the reset controller device @@ -135,6 +148,65 @@ int devm_reset_controller_register(struct device *dev, } EXPORT_SYMBOL_GPL(devm_reset_controller_register); +static inline struct reset_control_array * +rstc_to_array(struct reset_control *rstc) { + return container_of(rstc, struct reset_control_array, base); +} + +static int reset_control_array_reset(struct reset_control_array *resets) +{ + int ret, i; + + for (i = 0; i < resets->num_rstcs; i++) { + ret = reset_control_reset(resets->rstc[i]); + if (ret) + return ret; + } + + return 0; +} + +static int reset_control_array_assert(struct reset_control_array *resets) +{ + int ret, i; + + for (i = 0; i < resets->num_rstcs; i++) { + ret = reset_control_assert(resets->rstc[i]); + if (ret) + goto err; + } + + return 0; + +err: + while (i--) + reset_control_deassert(resets->rstc[i]); + return ret; +} + +static int reset_control_array_deassert(struct reset_control_array *resets) +{ + int ret, i; + + for (i = 0; i < resets->num_rstcs; i++) { + ret = reset_control_deassert(resets->rstc[i]); + if (ret) + goto err; + } + + return 0; + +err: + while (i--) + reset_control_assert(resets->rstc[i]); + return ret; +} + +static inline bool reset_control_is_array(struct reset_control *rstc) +{ + return rstc->array; +} + /** * reset_control_reset - reset the controlled device * @rstc: reset controller @@ -158,6 +230,9 @@ int reset_control_reset(struct reset_control *rstc) if (WARN_ON(IS_ERR(rstc))) return -EINVAL; + if (reset_control_is_array(rstc)) + return reset_control_array_reset(rstc_to_array(rstc)); + if (!rstc->rcdev->ops->reset) return -ENOTSUPP; @@ -202,6 +277,9 @@ int reset_control_assert(struct reset_control *rstc) if (WARN_ON(IS_ERR(rstc))) return -EINVAL; + if (reset_control_is_array(rstc)) + return reset_control_array_assert(rstc_to_array(rstc)); + if (!rstc->rcdev->ops->assert) return -ENOTSUPP; @@ -240,6 +318,9 @@ int reset_control_deassert(struct reset_control *rstc) if (WARN_ON(IS_ERR(rstc))) return -EINVAL; + if (reset_control_is_array(rstc)) + return reset_control_array_deassert(rstc_to_array(rstc)); + if (!rstc->rcdev->ops->deassert) return -ENOTSUPP; @@ -266,7 +347,7 @@ int reset_control_status(struct reset_control *rstc) if (!rstc) return 0; - if (WARN_ON(IS_ERR(rstc))) + if (WARN_ON(IS_ERR(rstc)) || reset_control_is_array(rstc)) return -EINVAL; if (rstc->rcdev->ops->status) @@ -404,6 +485,16 @@ struct reset_control *__reset_control_get(struct device *dev, const char *id, } EXPORT_SYMBOL_GPL(__reset_control_get); +static void reset_control_array_put(struct reset_control_array *resets) +{ + int i; + + mutex_lock(&reset_list_mutex); + for (i = 0; i < resets->num_rstcs; i++) + __reset_control_put_internal(resets->rstc[i]); + mutex_unlock(&reset_list_mutex); +} + /** * reset_control_put - free the reset controller * @rstc: reset controller @@ -413,6 +504,11 @@ void reset_control_put(struct reset_control *rstc) if (IS_ERR_OR_NULL(rstc)) return; + if (reset_control_is_array(rstc)) { + reset_control_array_put(rstc_to_array(rstc)); + return; + } + mutex_lock(&reset_list_mutex); __reset_control_put_internal(rstc); mutex_unlock(&reset_list_mutex); @@ -472,3 +568,116 @@ int device_reset(struct device *dev) return ret; } EXPORT_SYMBOL_GPL(device_reset); + +/** + * APIs to manage an array of reset controls. + */ +/** + * of_reset_control_get_count - Count number of resets available with a device + * + * @node: device node that contains 'resets'. + * + * Returns positive reset count on success, or error number on failure and + * on count being zero. + */ +static int of_reset_control_get_count(struct device_node *node) +{ + int count; + + if (!node) + return -EINVAL; + + count = of_count_phandle_with_args(node, "resets", "#reset-cells"); + if (count == 0) + count = -ENOENT; + + return count; +} + +/** + * of_reset_control_array_get - Get a list of reset controls using + * device node. + * + * @np: device node for the device that requests the reset controls array + * @shared: whether reset controls are shared or not + * @optional: whether it is optional to get the reset controls + * + * Returns pointer to allocated reset_control_array on success or + * error on failure + */ +struct reset_control * +of_reset_control_array_get(struct device_node *np, bool shared, bool optional) +{ + struct reset_control_array *resets; + struct reset_control *rstc; + int num, i; + + num = of_reset_control_get_count(np); + if (num < 0) + return optional ? NULL : ERR_PTR(num); + + resets = kzalloc(sizeof(*resets) + sizeof(resets->rstc[0]) * num, + GFP_KERNEL); + if (!resets) + return ERR_PTR(-ENOMEM); + + for (i = 0; i < num; i++) { + rstc = __of_reset_control_get(np, NULL, i, shared, optional); + if (IS_ERR(rstc)) + goto err_rst; + resets->rstc[i] = rstc; + } + resets->num_rstcs = num; + resets->base.array = true; + + return &resets->base; + +err_rst: + mutex_lock(&reset_list_mutex); + while (--i >= 0) + __reset_control_put_internal(resets->rstc[i]); + mutex_unlock(&reset_list_mutex); + + kfree(resets); + + return rstc; +} +EXPORT_SYMBOL_GPL(of_reset_control_array_get); + +/** + * devm_reset_control_array_get - Resource managed reset control array get + * + * @dev: device that requests the list of reset controls + * @shared: whether reset controls are shared or not + * @optional: whether it is optional to get the reset controls + * + * The reset control array APIs are intended for a list of resets + * that just have to be asserted or deasserted, without any + * requirements on the order. + * + * Returns pointer to allocated reset_control_array on success or + * error on failure + */ +struct reset_control * +devm_reset_control_array_get(struct device *dev, bool shared, bool optional) +{ + struct reset_control **devres; + struct reset_control *rstc; + + devres = devres_alloc(devm_reset_control_release, sizeof(*devres), + GFP_KERNEL); + if (!devres) + return ERR_PTR(-ENOMEM); + + rstc = of_reset_control_array_get(dev->of_node, shared, optional); + if (IS_ERR(rstc)) { + devres_free(devres); + return rstc; + } + + *devres = rstc; + devres_add(dev, devres); + + return rstc; +} +EXPORT_SYMBOL_GPL(devm_reset_control_array_get); diff --git a/include/linux/reset.h b/include/linux/reset.h index 13d8681210d5..56463f37f3e6 100644 --- a/include/linux/reset.h +++ b/include/linux/reset.h @@ -25,6 +25,11 @@ struct reset_control *__devm_reset_control_get(struct device *dev, int __must_check device_reset(struct device *dev); +struct reset_control *devm_reset_control_array_get(struct device *dev, + bool shared, bool optional); +struct reset_control *of_reset_control_array_get(struct device_node *np, + bool shared, bool optional); + static inline int device_reset_optional(struct device *dev) { return device_reset(dev); @@ -89,6 +94,18 @@ static inline struct reset_control *__devm_reset_control_get( return optional ? NULL : ERR_PTR(-ENOTSUPP); } +static inline struct reset_control * +devm_reset_control_array_get(struct device *dev, bool shared, bool optional) +{ + return optional ? NULL : ERR_PTR(-ENOTSUPP); +} + +static inline struct reset_control * +of_reset_control_array_get(struct device_node *np, bool shared, bool optional) +{ + return optional ? NULL : ERR_PTR(-ENOTSUPP); +} + #endif /* CONFIG_RESET_CONTROLLER */ /** @@ -374,4 +391,55 @@ static inline struct reset_control *devm_reset_control_get_by_index( { return devm_reset_control_get_exclusive_by_index(dev, index); } + +/* + * APIs to manage a list of reset controllers + */ +static inline struct reset_control * +devm_reset_control_array_get_exclusive(struct device *dev) +{ + return devm_reset_control_array_get(dev, false, false); +} + +static inline struct reset_control * +devm_reset_control_array_get_shared(struct device *dev) +{ + return devm_reset_control_array_get(dev, true, false); +} + +static inline struct reset_control * +devm_reset_control_array_get_optional_exclusive(struct device *dev) +{ + return devm_reset_control_array_get(dev, false, true); +} + +static inline struct reset_control * +devm_reset_control_array_get_optional_shared(struct device *dev) +{ + return devm_reset_control_array_get(dev, true, true); +} + +static inline struct reset_control * +of_reset_control_array_get_exclusive(struct device_node *node) +{ + return of_reset_control_array_get(node, false, false); +} + +static inline struct reset_control * +of_reset_control_array_get_shared(struct device_node *node) +{ + return of_reset_control_array_get(node, true, false); +} + +static inline struct reset_control * +of_reset_control_array_get_optional_exclusive(struct device_node *node) +{ + return of_reset_control_array_get(node, false, true); +} + +static inline struct reset_control * +of_reset_control_array_get_optional_shared(struct device_node *node) +{ + return of_reset_control_array_get(node, true, true); +} #endif -- cgit v1.2.3-59-g8ed1b From 21240eb94f1f6df30aa88f7e7b754ed46024d666 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Wed, 12 Jul 2017 17:51:22 +0200 Subject: reset: make (de)assert report success for self-deasserting reset drivers By now there are drivers using shared reset controls and (de)assert calls on platforms with self-deasserting reset lines and thus reset drivers that do not implement .assert() and .deassert(). As long as the initial state of the reset line is deasserted, there is no reason for a reset_control_assert call to return an error for shared reset controls, or for a reset_control_deassert call to return an error for either shared or exclusive reset controls: after a call to reset_control_deassert the reset line is guaranteed to be deasserted, and after a call to reset_control_assert it is valid for the reset line to stay deasserted for shared reset controls. Signed-off-by: Philipp Zabel Reviewed-by: Linus Walleij --- drivers/reset/core.c | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/reset/core.c b/drivers/reset/core.c index c8fb4426b218..1d21c6f7d56c 100644 --- a/drivers/reset/core.c +++ b/drivers/reset/core.c @@ -280,9 +280,6 @@ int reset_control_assert(struct reset_control *rstc) if (reset_control_is_array(rstc)) return reset_control_array_assert(rstc_to_array(rstc)); - if (!rstc->rcdev->ops->assert) - return -ENOTSUPP; - if (rstc->shared) { if (WARN_ON(atomic_read(&rstc->triggered_count) != 0)) return -EINVAL; @@ -292,6 +289,21 @@ int reset_control_assert(struct reset_control *rstc) if (atomic_dec_return(&rstc->deassert_count) != 0) return 0; + + /* + * Shared reset controls allow the reset line to be in any state + * after this call, so doing nothing is a valid option. + */ + if (!rstc->rcdev->ops->assert) + return 0; + } else { + /* + * If the reset controller does not implement .assert(), there + * is no way to guarantee that the reset line is asserted after + * this call. + */ + if (!rstc->rcdev->ops->assert) + return -ENOTSUPP; } return rstc->rcdev->ops->assert(rstc->rcdev, rstc->id); @@ -321,9 +333,6 @@ int reset_control_deassert(struct reset_control *rstc) if (reset_control_is_array(rstc)) return reset_control_array_deassert(rstc_to_array(rstc)); - if (!rstc->rcdev->ops->deassert) - return -ENOTSUPP; - if (rstc->shared) { if (WARN_ON(atomic_read(&rstc->triggered_count) != 0)) return -EINVAL; @@ -332,6 +341,16 @@ int reset_control_deassert(struct reset_control *rstc) return 0; } + /* + * If the reset controller does not implement .deassert(), we assume + * that it handles self-deasserting reset lines via .reset(). In that + * case, the reset lines are deasserted by default. If that is not the + * case, the reset controller driver should implement .deassert() and + * return -ENOTSUPP. + */ + if (!rstc->rcdev->ops->deassert) + return 0; + return rstc->rcdev->ops->deassert(rstc->rcdev, rstc->id); } EXPORT_SYMBOL_GPL(reset_control_deassert); -- cgit v1.2.3-59-g8ed1b From e0be864f14240cb1bd92247a672796239d6ef2fa Mon Sep 17 00:00:00 2001 From: Eugeniy Paltsev Date: Wed, 19 Jul 2017 21:45:11 +0300 Subject: ARC: reset: introduce HSDKv1 reset driver The HSDK v1 periphery IPs can be reset by accessing some registers from the CGU block. The list of available reset lines is documented in the DT bindings. Signed-off-by: Eugeniy Paltsev Signed-off-by: Philipp Zabel --- MAINTAINERS | 7 ++ drivers/reset/Kconfig | 6 ++ drivers/reset/Makefile | 1 + drivers/reset/reset-hsdk-v1.c | 137 +++++++++++++++++++++++++ include/dt-bindings/reset/snps,hsdk-v1-reset.h | 17 +++ 5 files changed, 168 insertions(+) create mode 100644 drivers/reset/reset-hsdk-v1.c create mode 100644 include/dt-bindings/reset/snps,hsdk-v1-reset.h (limited to 'drivers') diff --git a/MAINTAINERS b/MAINTAINERS index 205d3977ac46..57853844969b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -11662,6 +11662,13 @@ L: linux-mmc@vger.kernel.org S: Maintained F: drivers/mmc/host/dw_mmc* +SYNOPSYS HSDK RESET CONTROLLER DRIVER +M: Eugeniy Paltsev +S: Supported +F: drivers/reset/reset-hsdk-v1.c +F: include/dt-bindings/reset/snps,hsdk-v1-reset.h +F: Documentation/devicetree/bindings/reset/snps,hsdk-v1-reset.txt + SYSTEM TRACE MODULE CLASS M: Alexander Shishkin S: Maintained diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index 608c071e4bbf..c4c4a4cbcf49 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -41,6 +41,12 @@ config RESET_GEMINI help This enables the reset controller driver for Cortina Systems Gemini. +config RESET_HSDK_V1 + bool "HSDK v1 Reset Driver" + default n + help + This enables the reset controller driver for HSDK v1. + config RESET_IMX7 bool "i.MX7 Reset Driver" if COMPILE_TEST default SOC_IMX7D diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile index 7081f9da2599..9373040efc63 100644 --- a/drivers/reset/Makefile +++ b/drivers/reset/Makefile @@ -6,6 +6,7 @@ obj-$(CONFIG_RESET_A10SR) += reset-a10sr.o obj-$(CONFIG_RESET_ATH79) += reset-ath79.o obj-$(CONFIG_RESET_BERLIN) += reset-berlin.o obj-$(CONFIG_RESET_GEMINI) += reset-gemini.o +obj-$(CONFIG_RESET_HSDK_V1) += reset-hsdk-v1.o obj-$(CONFIG_RESET_IMX7) += reset-imx7.o obj-$(CONFIG_RESET_LPC18XX) += reset-lpc18xx.o obj-$(CONFIG_RESET_MESON) += reset-meson.o diff --git a/drivers/reset/reset-hsdk-v1.c b/drivers/reset/reset-hsdk-v1.c new file mode 100644 index 000000000000..bca13e4bf622 --- /dev/null +++ b/drivers/reset/reset-hsdk-v1.c @@ -0,0 +1,137 @@ +/* + * Copyright (C) 2017 Synopsys. + * + * Synopsys HSDKv1 SDP reset driver. + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define to_hsdkv1_rst(p) container_of((p), struct hsdkv1_rst, rcdev) + +struct hsdkv1_rst { + void __iomem *regs_ctl; + void __iomem *regs_rst; + spinlock_t lock; + struct reset_controller_dev rcdev; +}; + +static const u32 rst_map[] = { + BIT(16), /* APB_RST */ + BIT(17), /* AXI_RST */ + BIT(18), /* ETH_RST */ + BIT(19), /* USB_RST */ + BIT(20), /* SDIO_RST */ + BIT(21), /* HDMI_RST */ + BIT(22), /* GFX_RST */ + BIT(25), /* DMAC_RST */ + BIT(31), /* EBI_RST */ +}; + +#define HSDK_MAX_RESETS ARRAY_SIZE(rst_map) + +#define CGU_SYS_RST_CTRL 0x0 +#define CGU_IP_SW_RESET 0x0 +#define CGU_IP_SW_RESET_DELAY_SHIFT 16 +#define CGU_IP_SW_RESET_DELAY_MASK GENMASK(31, CGU_IP_SW_RESET_DELAY_SHIFT) +#define CGU_IP_SW_RESET_DELAY 0 +#define CGU_IP_SW_RESET_RESET BIT(0) +#define SW_RESET_TIMEOUT 10000 + +static void hsdkv1_reset_config(struct hsdkv1_rst *rst, unsigned long id) +{ + writel(rst_map[id], rst->regs_ctl + CGU_SYS_RST_CTRL); +} + +static int hsdkv1_reset_do(struct hsdkv1_rst *rst) +{ + u32 reg; + + reg = readl(rst->regs_rst + CGU_IP_SW_RESET); + reg &= ~CGU_IP_SW_RESET_DELAY_MASK; + reg |= CGU_IP_SW_RESET_DELAY << CGU_IP_SW_RESET_DELAY_SHIFT; + reg |= CGU_IP_SW_RESET_RESET; + writel(reg, rst->regs_rst + CGU_IP_SW_RESET); + + /* wait till reset bit is back to 0 */ + return readl_poll_timeout_atomic(rst->regs_rst + CGU_IP_SW_RESET, reg, + !(reg & CGU_IP_SW_RESET_RESET), 5, SW_RESET_TIMEOUT); +} + +static int hsdkv1_reset_reset(struct reset_controller_dev *rcdev, + unsigned long id) +{ + struct hsdkv1_rst *rst = to_hsdkv1_rst(rcdev); + unsigned long flags; + int ret; + + spin_lock_irqsave(&rst->lock, flags); + hsdkv1_reset_config(rst, id); + ret = hsdkv1_reset_do(rst); + spin_unlock_irqrestore(&rst->lock, flags); + + return ret; +} + +static const struct reset_control_ops hsdkv1_reset_ops = { + .reset = hsdkv1_reset_reset, +}; + +static int hsdkv1_reset_probe(struct platform_device *pdev) +{ + struct hsdkv1_rst *rst; + struct resource *mem; + + rst = devm_kzalloc(&pdev->dev, sizeof(*rst), GFP_KERNEL); + if (!rst) + return -ENOMEM; + + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + rst->regs_ctl = devm_ioremap_resource(&pdev->dev, mem); + if (IS_ERR(rst->regs_ctl)) + return PTR_ERR(rst->regs_ctl); + + mem = platform_get_resource(pdev, IORESOURCE_MEM, 1); + rst->regs_rst = devm_ioremap_resource(&pdev->dev, mem); + if (IS_ERR(rst->regs_rst)) + return PTR_ERR(rst->regs_rst); + + spin_lock_init(&rst->lock); + + rst->rcdev.owner = THIS_MODULE; + rst->rcdev.ops = &hsdkv1_reset_ops; + rst->rcdev.of_node = pdev->dev.of_node; + rst->rcdev.nr_resets = HSDK_MAX_RESETS; + rst->rcdev.of_reset_n_cells = 1; + + return reset_controller_register(&rst->rcdev); +} + +static const struct of_device_id hsdkv1_reset_dt_match[] = { + { .compatible = "snps,hsdk-v1.0-reset" }, + { }, +}; + +static struct platform_driver hsdkv1_reset_driver = { + .probe = hsdkv1_reset_probe, + .driver = { + .name = "hsdk-v1.0-reset", + .of_match_table = hsdkv1_reset_dt_match, + }, +}; +builtin_platform_driver(hsdkv1_reset_driver); + +MODULE_AUTHOR("Eugeniy Paltsev "); +MODULE_DESCRIPTION("Synopsys HSDKv1 SDP reset driver"); +MODULE_LICENSE("GPL v2"); diff --git a/include/dt-bindings/reset/snps,hsdk-v1-reset.h b/include/dt-bindings/reset/snps,hsdk-v1-reset.h new file mode 100644 index 000000000000..d898c89b7123 --- /dev/null +++ b/include/dt-bindings/reset/snps,hsdk-v1-reset.h @@ -0,0 +1,17 @@ +/** + * This header provides index for the HSDK v1 reset controller. + */ +#ifndef _DT_BINDINGS_RESET_CONTROLLER_HSDK_V1 +#define _DT_BINDINGS_RESET_CONTROLLER_HSDK_V1 + +#define HSDK_V1_APB_RESET 0 +#define HSDK_V1_AXI_RESET 1 +#define HSDK_V1_ETH_RESET 2 +#define HSDK_V1_USB_RESET 3 +#define HSDK_V1_SDIO_RESET 4 +#define HSDK_V1_HDMI_RESET 5 +#define HSDK_V1_GFX_RESET 6 +#define HSDK_V1_DMAC_RESET 7 +#define HSDK_V1_EBI_RESET 8 + +#endif /*_DT_BINDINGS_RESET_CONTROLLER_HSDK_V1*/ -- cgit v1.2.3-59-g8ed1b From bd85f4b76916f9d9d7130e58601662133399079a Mon Sep 17 00:00:00 2001 From: Elaine Zhang Date: Fri, 14 Jul 2017 15:02:43 +0800 Subject: soc: rockchip: power-domain: add power domain support for rk3366 This driver is modified to support RK3366 SoC. Signed-off-by: Elaine Zhang Signed-off-by: Heiko Stuebner --- drivers/soc/rockchip/pm_domains.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'drivers') diff --git a/drivers/soc/rockchip/pm_domains.c b/drivers/soc/rockchip/pm_domains.c index 796c46a6cbe7..40b75748835f 100644 --- a/drivers/soc/rockchip/pm_domains.c +++ b/drivers/soc/rockchip/pm_domains.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -730,6 +731,16 @@ static const struct rockchip_domain_info rk3328_pm_domains[] = { [RK3328_PD_VPU] = DOMAIN_RK3328(-1, 9, 9, false), }; +static const struct rockchip_domain_info rk3366_pm_domains[] = { + [RK3366_PD_PERI] = DOMAIN_RK3368(10, 10, 6, true), + [RK3366_PD_VIO] = DOMAIN_RK3368(14, 14, 8, false), + [RK3366_PD_VIDEO] = DOMAIN_RK3368(13, 13, 7, false), + [RK3366_PD_RKVDEC] = DOMAIN_RK3368(11, 11, 7, false), + [RK3366_PD_WIFIBT] = DOMAIN_RK3368(8, 8, 9, false), + [RK3366_PD_VPU] = DOMAIN_RK3368(12, 12, 7, false), + [RK3366_PD_GPU] = DOMAIN_RK3368(15, 15, 2, false), +}; + static const struct rockchip_domain_info rk3368_pm_domains[] = { [RK3368_PD_PERI] = DOMAIN_RK3368(13, 12, 6, true), [RK3368_PD_VIO] = DOMAIN_RK3368(15, 14, 8, false), @@ -794,6 +805,23 @@ static const struct rockchip_pmu_info rk3328_pmu = { .domain_info = rk3328_pm_domains, }; +static const struct rockchip_pmu_info rk3366_pmu = { + .pwr_offset = 0x0c, + .status_offset = 0x10, + .req_offset = 0x3c, + .idle_offset = 0x40, + .ack_offset = 0x40, + + .core_pwrcnt_offset = 0x48, + .gpu_pwrcnt_offset = 0x50, + + .core_power_transition_time = 24, + .gpu_power_transition_time = 24, + + .num_domains = ARRAY_SIZE(rk3366_pm_domains), + .domain_info = rk3366_pm_domains, +}; + static const struct rockchip_pmu_info rk3368_pmu = { .pwr_offset = 0x0c, .status_offset = 0x10, @@ -833,6 +861,10 @@ static const struct of_device_id rockchip_pm_domain_dt_match[] = { .compatible = "rockchip,rk3328-power-controller", .data = (void *)&rk3328_pmu, }, + { + .compatible = "rockchip,rk3366-power-controller", + .data = (void *)&rk3366_pmu, + }, { .compatible = "rockchip,rk3368-power-controller", .data = (void *)&rk3368_pmu, -- cgit v1.2.3-59-g8ed1b From e83a71981181a36d36e18e2f2dae3ec84fc37429 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Tue, 18 Jul 2017 16:43:30 -0500 Subject: soc: samsung: Use kbasename instead of open coding In preparation to not store the full path of nodes in full_name, use kbasename instead as it will work either with the full path or not. Signed-off-by: Rob Herring Cc: Kukjin Kim Cc: Krzysztof Kozlowski Cc: linux-samsung-soc@vger.kernel.org Signed-off-by: Krzysztof Kozlowski --- drivers/soc/samsung/pm_domains.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/soc/samsung/pm_domains.c b/drivers/soc/samsung/pm_domains.c index a6a5d807cc2b..b3d36aed784f 100644 --- a/drivers/soc/samsung/pm_domains.c +++ b/drivers/soc/samsung/pm_domains.c @@ -147,7 +147,7 @@ static __init const char *exynos_get_domain_name(struct device_node *node) const char *name; if (of_property_read_string(node, "label", &name) < 0) - name = strrchr(node->full_name, '/') + 1; + name = kbasename(node->full_name); return kstrdup_const(name, GFP_KERNEL); } -- cgit v1.2.3-59-g8ed1b From 1b954784e0d47db184ccf0bc3b684520c508664f Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 20 Jul 2017 14:34:51 +0200 Subject: soc: renesas: Identify R-Car D3 Signed-off-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- drivers/soc/renesas/renesas-soc.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/soc/renesas/renesas-soc.c b/drivers/soc/renesas/renesas-soc.c index ca26f13d399c..90d6b7a4340a 100644 --- a/drivers/soc/renesas/renesas-soc.c +++ b/drivers/soc/renesas/renesas-soc.c @@ -144,6 +144,11 @@ static const struct renesas_soc soc_rcar_m3_w __initconst __maybe_unused = { .id = 0x52, }; +static const struct renesas_soc soc_rcar_d3 __initconst __maybe_unused = { + .family = &fam_rcar_gen3, + .id = 0x58, +}; + static const struct renesas_soc soc_shmobile_ag5 __initconst __maybe_unused = { .family = &fam_shmobile, .id = 0x37, @@ -199,6 +204,9 @@ static const struct of_device_id renesas_socs[] __initconst = { #ifdef CONFIG_ARCH_R8A7796 { .compatible = "renesas,r8a7796", .data = &soc_rcar_m3_w }, #endif +#ifdef CONFIG_ARCH_R8A77995 + { .compatible = "renesas,r8a77995", .data = &soc_rcar_d3 }, +#endif #ifdef CONFIG_ARCH_SH73A0 { .compatible = "renesas,sh73a0", .data = &soc_shmobile_ag5 }, #endif -- cgit v1.2.3-59-g8ed1b From eed17c427f8b16dc9ca68f80d6b0d39a62b8eee3 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 20 Jul 2017 14:34:53 +0200 Subject: soc: renesas: rcar-sysc: Add support for R-Car D3 power areas Signed-off-by: Geert Uytterhoeven Acked-by: Rob Herring Signed-off-by: Simon Horman --- .../bindings/power/renesas,rcar-sysc.txt | 1 + drivers/soc/renesas/Kconfig | 5 ++++ drivers/soc/renesas/Makefile | 1 + drivers/soc/renesas/r8a77995-sysc.c | 31 ++++++++++++++++++++++ drivers/soc/renesas/rcar-sysc.c | 3 +++ drivers/soc/renesas/rcar-sysc.h | 1 + 6 files changed, 42 insertions(+) create mode 100644 drivers/soc/renesas/r8a77995-sysc.c (limited to 'drivers') diff --git a/Documentation/devicetree/bindings/power/renesas,rcar-sysc.txt b/Documentation/devicetree/bindings/power/renesas,rcar-sysc.txt index d91715bc8d52..98cc8c09d02d 100644 --- a/Documentation/devicetree/bindings/power/renesas,rcar-sysc.txt +++ b/Documentation/devicetree/bindings/power/renesas,rcar-sysc.txt @@ -17,6 +17,7 @@ Required properties: - "renesas,r8a7794-sysc" (R-Car E2) - "renesas,r8a7795-sysc" (R-Car H3) - "renesas,r8a7796-sysc" (R-Car M3-W) + - "renesas,r8a77995-sysc" (R-Car D3) - reg: Address start and address range for the device. - #power-domain-cells: Must be 1. diff --git a/drivers/soc/renesas/Kconfig b/drivers/soc/renesas/Kconfig index 87a4be46bd98..680a5a29837b 100644 --- a/drivers/soc/renesas/Kconfig +++ b/drivers/soc/renesas/Kconfig @@ -13,6 +13,7 @@ config SOC_RENESAS select SYSC_R8A7794 if ARCH_R8A7794 select SYSC_R8A7795 if ARCH_R8A7795 select SYSC_R8A7796 if ARCH_R8A7796 + select SYSC_R8A77995 if ARCH_R8A77995 if SOC_RENESAS @@ -53,6 +54,10 @@ config SYSC_R8A7796 bool "R-Car M3-W System Controller support" if COMPILE_TEST select SYSC_RCAR +config SYSC_R8A77995 + bool "R-Car D3 System Controller support" if COMPILE_TEST + select SYSC_RCAR + # Family config RST_RCAR bool "R-Car Reset Controller support" if COMPILE_TEST diff --git a/drivers/soc/renesas/Makefile b/drivers/soc/renesas/Makefile index 1a1a297b26a7..6b6e7f16104c 100644 --- a/drivers/soc/renesas/Makefile +++ b/drivers/soc/renesas/Makefile @@ -11,6 +11,7 @@ obj-$(CONFIG_SYSC_R8A7792) += r8a7792-sysc.o obj-$(CONFIG_SYSC_R8A7794) += r8a7794-sysc.o obj-$(CONFIG_SYSC_R8A7795) += r8a7795-sysc.o obj-$(CONFIG_SYSC_R8A7796) += r8a7796-sysc.o +obj-$(CONFIG_SYSC_R8A77995) += r8a77995-sysc.o # Family obj-$(CONFIG_RST_RCAR) += rcar-rst.o diff --git a/drivers/soc/renesas/r8a77995-sysc.c b/drivers/soc/renesas/r8a77995-sysc.c new file mode 100644 index 000000000000..f718429cab02 --- /dev/null +++ b/drivers/soc/renesas/r8a77995-sysc.c @@ -0,0 +1,31 @@ +/* + * Renesas R-Car D3 System Controller + * + * Copyright (C) 2017 Glider bvba + * + * 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; version 2 of the License. + */ + +#include +#include +#include + +#include + +#include "rcar-sysc.h" + +static struct rcar_sysc_area r8a77995_areas[] __initdata = { + { "always-on", 0, 0, R8A77995_PD_ALWAYS_ON, -1, PD_ALWAYS_ON }, + { "ca53-scu", 0x140, 0, R8A77995_PD_CA53_SCU, R8A77995_PD_ALWAYS_ON, + PD_SCU }, + { "ca53-cpu0", 0x200, 0, R8A77995_PD_CA53_CPU0, R8A77995_PD_CA53_SCU, + PD_CPU_NOCR }, +}; + + +const struct rcar_sysc_info r8a77995_sysc_info __initconst = { + .areas = r8a77995_areas, + .num_areas = ARRAY_SIZE(r8a77995_areas), +}; diff --git a/drivers/soc/renesas/rcar-sysc.c b/drivers/soc/renesas/rcar-sysc.c index 7c8da3c90011..e4d3b0101dfb 100644 --- a/drivers/soc/renesas/rcar-sysc.c +++ b/drivers/soc/renesas/rcar-sysc.c @@ -283,6 +283,9 @@ static const struct of_device_id rcar_sysc_matches[] = { #endif #ifdef CONFIG_SYSC_R8A7796 { .compatible = "renesas,r8a7796-sysc", .data = &r8a7796_sysc_info }, +#endif +#ifdef CONFIG_SYSC_R8A77995 + { .compatible = "renesas,r8a77995-sysc", .data = &r8a77995_sysc_info }, #endif { /* sentinel */ } }; diff --git a/drivers/soc/renesas/rcar-sysc.h b/drivers/soc/renesas/rcar-sysc.h index 1a5bebaf54ba..2f524922c4d2 100644 --- a/drivers/soc/renesas/rcar-sysc.h +++ b/drivers/soc/renesas/rcar-sysc.h @@ -58,6 +58,7 @@ extern const struct rcar_sysc_info r8a7792_sysc_info; extern const struct rcar_sysc_info r8a7794_sysc_info; extern const struct rcar_sysc_info r8a7795_sysc_info; extern const struct rcar_sysc_info r8a7796_sysc_info; +extern const struct rcar_sysc_info r8a77995_sysc_info; /* -- cgit v1.2.3-59-g8ed1b From 105ae504a3eb6c2e188e8d67db59b71186f11967 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 20 Jul 2017 14:34:54 +0200 Subject: soc: renesas: rcar-rst: Add support for R-Car D3 Signed-off-by: Geert Uytterhoeven Cc: devicetree@vger.kernel.org Acked-by: Rob Herring Signed-off-by: Simon Horman --- Documentation/devicetree/bindings/reset/renesas,rst.txt | 1 + drivers/soc/renesas/Kconfig | 2 +- drivers/soc/renesas/rcar-rst.c | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/Documentation/devicetree/bindings/reset/renesas,rst.txt b/Documentation/devicetree/bindings/reset/renesas,rst.txt index fe5e0f37b3c9..e5a03ffe04fb 100644 --- a/Documentation/devicetree/bindings/reset/renesas,rst.txt +++ b/Documentation/devicetree/bindings/reset/renesas,rst.txt @@ -26,6 +26,7 @@ Required properties: - "renesas,r8a7794-rst" (R-Car E2) - "renesas,r8a7795-rst" (R-Car H3) - "renesas,r8a7796-rst" (R-Car M3-W) + - "renesas,r8a77995-rst" (R-Car D3) - reg: Address start and address range for the device. diff --git a/drivers/soc/renesas/Kconfig b/drivers/soc/renesas/Kconfig index 680a5a29837b..567414cb42ba 100644 --- a/drivers/soc/renesas/Kconfig +++ b/drivers/soc/renesas/Kconfig @@ -3,7 +3,7 @@ config SOC_RENESAS default y if ARCH_RENESAS select SOC_BUS select RST_RCAR if ARCH_RCAR_GEN1 || ARCH_RCAR_GEN2 || \ - ARCH_R8A7795 || ARCH_R8A7796 + ARCH_R8A7795 || ARCH_R8A7796 || ARCH_R8A77995 select SYSC_R8A7743 if ARCH_R8A7743 select SYSC_R8A7745 if ARCH_R8A7745 select SYSC_R8A7779 if ARCH_R8A7779 diff --git a/drivers/soc/renesas/rcar-rst.c b/drivers/soc/renesas/rcar-rst.c index a6d1c26d3167..d27d0abe6c2a 100644 --- a/drivers/soc/renesas/rcar-rst.c +++ b/drivers/soc/renesas/rcar-rst.c @@ -41,6 +41,7 @@ static const struct of_device_id rcar_rst_matches[] __initconst = { /* R-Car Gen3 is handled like R-Car Gen2 */ { .compatible = "renesas,r8a7795-rst", .data = &rcar_rst_gen2 }, { .compatible = "renesas,r8a7796-rst", .data = &rcar_rst_gen2 }, + { .compatible = "renesas,r8a77995-rst", .data = &rcar_rst_gen2 }, { /* sentinel */ } }; -- cgit v1.2.3-59-g8ed1b From a9daaba2965e8b132424514e184fc40ee6f9e00c Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Fri, 23 Jun 2017 10:28:18 +0200 Subject: soc: Add Amlogic SoC Information driver Amlogic SoCs have a SoC information register for SoC type, package type and revision information. This patchs adds support for this register decoding and exposing with the SoC bus infrastructure. Signed-off-by: Neil Armstrong Signed-off-by: Kevin Hilman --- drivers/soc/Kconfig | 1 + drivers/soc/Makefile | 1 + drivers/soc/amlogic/Kconfig | 12 +++ drivers/soc/amlogic/Makefile | 1 + drivers/soc/amlogic/meson-gx-socinfo.c | 177 +++++++++++++++++++++++++++++++++ 5 files changed, 192 insertions(+) create mode 100644 drivers/soc/amlogic/Kconfig create mode 100644 drivers/soc/amlogic/Makefile create mode 100644 drivers/soc/amlogic/meson-gx-socinfo.c (limited to 'drivers') diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig index 07fc0ac51c52..fc9e98047421 100644 --- a/drivers/soc/Kconfig +++ b/drivers/soc/Kconfig @@ -1,6 +1,7 @@ menu "SOC (System On Chip) specific Drivers" source "drivers/soc/actions/Kconfig" +source "drivers/soc/amlogic/Kconfig" source "drivers/soc/atmel/Kconfig" source "drivers/soc/bcm/Kconfig" source "drivers/soc/fsl/Kconfig" diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile index 9241125416ba..280a6a91a9e2 100644 --- a/drivers/soc/Makefile +++ b/drivers/soc/Makefile @@ -10,6 +10,7 @@ obj-$(CONFIG_MACH_DOVE) += dove/ obj-y += fsl/ obj-$(CONFIG_ARCH_MXC) += imx/ obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/ +obj-$(CONFIG_ARCH_MESON) += amlogic/ obj-$(CONFIG_ARCH_QCOM) += qcom/ obj-y += renesas/ obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/ diff --git a/drivers/soc/amlogic/Kconfig b/drivers/soc/amlogic/Kconfig new file mode 100644 index 000000000000..22acf064531f --- /dev/null +++ b/drivers/soc/amlogic/Kconfig @@ -0,0 +1,12 @@ +menu "Amlogic SoC drivers" + +config MESON_GX_SOCINFO + bool "Amlogic Meson GX SoC Information driver" + depends on ARCH_MESON || COMPILE_TEST + default ARCH_MESON + select SOC_BUS + help + Say yes to support decoding of Amlogic Meson GX SoC family + information about the type, package and version. + +endmenu diff --git a/drivers/soc/amlogic/Makefile b/drivers/soc/amlogic/Makefile new file mode 100644 index 000000000000..3e85fc462c21 --- /dev/null +++ b/drivers/soc/amlogic/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_MESON_GX_SOCINFO) += meson-gx-socinfo.o diff --git a/drivers/soc/amlogic/meson-gx-socinfo.c b/drivers/soc/amlogic/meson-gx-socinfo.c new file mode 100644 index 000000000000..89f4cf507be6 --- /dev/null +++ b/drivers/soc/amlogic/meson-gx-socinfo.c @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2017 BayLibre, SAS + * Author: Neil Armstrong + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define AO_SEC_SD_CFG8 0xe0 +#define AO_SEC_SOCINFO_OFFSET AO_SEC_SD_CFG8 + +#define SOCINFO_MAJOR GENMASK(31, 24) +#define SOCINFO_MINOR GENMASK(23, 16) +#define SOCINFO_PACK GENMASK(15, 8) +#define SOCINFO_MISC GENMASK(7, 0) + +static const struct meson_gx_soc_id { + const char *name; + unsigned int id; +} soc_ids[] = { + { "GXBB", 0x1f }, + { "GXTVBB", 0x20 }, + { "GXL", 0x21 }, + { "GXM", 0x22 }, + { "TXL", 0x23 }, +}; + +static const struct meson_gx_package_id { + const char *name; + unsigned int major_id; + unsigned int pack_id; +} soc_packages[] = { + { "S905", 0x1f, 0 }, + { "S905M", 0x1f, 0x20 }, + { "S905D", 0x21, 0 }, + { "S905X", 0x21, 0x80 }, + { "S905L", 0x21, 0xc0 }, + { "S905M2", 0x21, 0xe0 }, + { "S912", 0x22, 0 }, +}; + +static inline unsigned int socinfo_to_major(u32 socinfo) +{ + return FIELD_GET(SOCINFO_MAJOR, socinfo); +} + +static inline unsigned int socinfo_to_minor(u32 socinfo) +{ + return FIELD_GET(SOCINFO_MINOR, socinfo); +} + +static inline unsigned int socinfo_to_pack(u32 socinfo) +{ + return FIELD_GET(SOCINFO_PACK, socinfo); +} + +static inline unsigned int socinfo_to_misc(u32 socinfo) +{ + return FIELD_GET(SOCINFO_MISC, socinfo); +} + +static const char *socinfo_to_package_id(u32 socinfo) +{ + unsigned int pack = socinfo_to_pack(socinfo) & 0xf0; + unsigned int major = socinfo_to_major(socinfo); + int i; + + for (i = 0 ; i < ARRAY_SIZE(soc_packages) ; ++i) { + if (soc_packages[i].major_id == major && + soc_packages[i].pack_id == pack) + return soc_packages[i].name; + } + + return "Unknown"; +} + +static const char *socinfo_to_soc_id(u32 socinfo) +{ + unsigned int id = socinfo_to_major(socinfo); + int i; + + for (i = 0 ; i < ARRAY_SIZE(soc_ids) ; ++i) { + if (soc_ids[i].id == id) + return soc_ids[i].name; + } + + return "Unknown"; +} + +int __init meson_gx_socinfo_init(void) +{ + struct soc_device_attribute *soc_dev_attr; + struct soc_device *soc_dev; + struct device_node *np; + struct regmap *regmap; + unsigned int socinfo; + struct device *dev; + int ret; + + /* look up for chipid node */ + np = of_find_compatible_node(NULL, NULL, "amlogic,meson-gx-ao-secure"); + if (!np) + return -ENODEV; + + /* check if interface is enabled */ + if (!of_device_is_available(np)) + return -ENODEV; + + /* check if chip-id is available */ + if (!of_property_read_bool(np, "amlogic,has-chip-id")) + return -ENODEV; + + /* node should be a syscon */ + regmap = syscon_node_to_regmap(np); + of_node_put(np); + if (IS_ERR(regmap)) { + pr_err("%s: failed to get regmap\n", __func__); + return -ENODEV; + } + + ret = regmap_read(regmap, AO_SEC_SOCINFO_OFFSET, &socinfo); + if (ret < 0) + return ret; + + if (!socinfo) { + pr_err("%s: invalid chipid value\n", __func__); + return -EINVAL; + } + + soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); + if (!soc_dev_attr) + return -ENODEV; + + soc_dev_attr->family = "Amlogic Meson"; + + np = of_find_node_by_path("/"); + of_property_read_string(np, "model", &soc_dev_attr->machine); + of_node_put(np); + + soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%x:%x - %x:%x", + socinfo_to_major(socinfo), + socinfo_to_minor(socinfo), + socinfo_to_pack(socinfo), + socinfo_to_misc(socinfo)); + soc_dev_attr->soc_id = kasprintf(GFP_KERNEL, "%s (%s)", + socinfo_to_soc_id(socinfo), + socinfo_to_package_id(socinfo)); + + soc_dev = soc_device_register(soc_dev_attr); + if (IS_ERR(soc_dev)) { + kfree(soc_dev_attr->revision); + kfree_const(soc_dev_attr->soc_id); + kfree(soc_dev_attr); + return PTR_ERR(soc_dev); + } + dev = soc_device_to_device(soc_dev); + + dev_info(dev, "Amlogic Meson %s Revision %x:%x (%x:%x) Detected\n", + soc_dev_attr->soc_id, + socinfo_to_major(socinfo), + socinfo_to_minor(socinfo), + socinfo_to_pack(socinfo), + socinfo_to_misc(socinfo)); + + return 0; +} +device_initcall(meson_gx_socinfo_init); -- cgit v1.2.3-59-g8ed1b From 0c106e57dea709395b5b5eb004987b7ddad251ad Mon Sep 17 00:00:00 2001 From: Tuomas Tynkkynen Date: Sat, 29 Jul 2017 02:58:43 +0300 Subject: soc/tegra: Fix bad of_node_put() in powergate init The for_each_child_of_node macro itself maintains the correct reference count of the nodes so the explicit of_node_put() call causes a warning: [ 0.098960] OF: ERROR: Bad of_node_put() on /pmc@7000e400/powergates/xusba [ 0.098981] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.11.3 #1-NixOS [ 0.098996] Hardware name: NVIDIA Jetson TX1 Developer Kit (DT) [ 0.099011] Call trace: [ 0.099034] [] dump_backtrace+0x0/0x2a0 [ 0.099051] [] show_stack+0x24/0x30 [ 0.099069] [] dump_stack+0x9c/0xc0 [ 0.099090] [] of_node_release+0xa4/0xa8 [ 0.099107] [] kobject_put+0x90/0x1f8 [ 0.099124] [] of_node_put+0x24/0x30 [ 0.099140] [] __of_get_next_child+0x4c/0x70 [ 0.099155] [] of_get_next_child+0x40/0x68 [ 0.099173] [] tegra_pmc_early_init+0x4e8/0x5ac [ 0.099189] [] do_one_initcall+0x5c/0x168 [ 0.099206] [] kernel_init_freeable+0xd4/0x240 [ 0.099224] [] kernel_init+0x18/0x108 [ 0.099238] [] ret_from_fork+0x10/0x50 (It's not very apparent from the OF documentation that of_node_put() is not needed; the macro itself has no docstring and of_get_next_child() used in the implementation begins with "Returns a node pointer with refcount incremented" but then only at the very end of the docstring the crucial part "Decrements the refcount of prev" is mentioned.) Fixes: a38045121bf42 ("soc/tegra: pmc: Add generic PM domain support") Signed-off-by: Tuomas Tynkkynen Signed-off-by: Thierry Reding --- drivers/soc/tegra/pmc.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c index e233dd5dcab3..0453ff6839a7 100644 --- a/drivers/soc/tegra/pmc.c +++ b/drivers/soc/tegra/pmc.c @@ -918,10 +918,8 @@ static void tegra_powergate_init(struct tegra_pmc *pmc, if (!np) return; - for_each_child_of_node(np, child) { + for_each_child_of_node(np, child) tegra_powergate_add(pmc, child); - of_node_put(child); - } of_node_put(np); } -- cgit v1.2.3-59-g8ed1b From 2ae24fb16ca48882995fc229e40ca7806acd2b00 Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Wed, 28 Jun 2017 10:28:21 +0530 Subject: soc: mtk-pmic-wrap: make of_device_ids const. of_device_ids are not supposed to change at runtime. All functions working with of_device_ids provided by work with const of_device_ids. So mark the non-const structs as const. Signed-off-by: Arvind Yadav Acked-by: Chen Zhong Signed-off-by: Matthias Brugger --- drivers/soc/mediatek/mtk-pmic-wrap.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/soc/mediatek/mtk-pmic-wrap.c b/drivers/soc/mediatek/mtk-pmic-wrap.c index c80a04e1b2b1..0ae72867e9dc 100644 --- a/drivers/soc/mediatek/mtk-pmic-wrap.c +++ b/drivers/soc/mediatek/mtk-pmic-wrap.c @@ -1067,7 +1067,7 @@ static const struct pmic_wrapper_type pwrap_mt2701 = { .init_soc_specific = pwrap_mt2701_init_soc_specific, }; -static struct pmic_wrapper_type pwrap_mt8135 = { +static const struct pmic_wrapper_type pwrap_mt8135 = { .regs = mt8135_regs, .type = PWRAP_MT8135, .arb_en_all = 0x1ff, @@ -1079,7 +1079,7 @@ static struct pmic_wrapper_type pwrap_mt8135 = { .init_soc_specific = pwrap_mt8135_init_soc_specific, }; -static struct pmic_wrapper_type pwrap_mt8173 = { +static const struct pmic_wrapper_type pwrap_mt8173 = { .regs = mt8173_regs, .type = PWRAP_MT8173, .arb_en_all = 0x3f, @@ -1091,7 +1091,7 @@ static struct pmic_wrapper_type pwrap_mt8173 = { .init_soc_specific = pwrap_mt8173_init_soc_specific, }; -static struct of_device_id of_pwrap_match_tbl[] = { +static const struct of_device_id of_pwrap_match_tbl[] = { { .compatible = "mediatek,mt2701-pwrap", .data = &pwrap_mt2701, -- cgit v1.2.3-59-g8ed1b From efb14036bd7f8914f721e1e82891d4ba617cc784 Mon Sep 17 00:00:00 2001 From: Jens Wiklander Date: Mon, 15 May 2017 11:09:28 +0200 Subject: tee: optee: fix uninitialized symbol 'parg' Fixes the static checker warning in optee_release(). error: uninitialized symbol 'parg'. Reported-by: Dan Carpenter Signed-off-by: Jens Wiklander --- drivers/tee/optee/core.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/tee/optee/core.c b/drivers/tee/optee/core.c index 58169e519422..857141e29e80 100644 --- a/drivers/tee/optee/core.c +++ b/drivers/tee/optee/core.c @@ -224,13 +224,14 @@ static void optee_release(struct tee_context *ctx) if (!IS_ERR(shm)) { arg = tee_shm_get_va(shm, 0); /* - * If va2pa fails for some reason, we can't call - * optee_close_session(), only free the memory. Secure OS - * will leak sessions and finally refuse more sessions, but - * we will at least let normal world reclaim its memory. + * If va2pa fails for some reason, we can't call into + * secure world, only free the memory. Secure OS will leak + * sessions and finally refuse more sessions, but we will + * at least let normal world reclaim its memory. */ if (!IS_ERR(arg)) - tee_shm_va2pa(shm, arg, &parg); + if (tee_shm_va2pa(shm, arg, &parg)) + arg = NULL; /* prevent usage of parg below */ } list_for_each_entry_safe(sess, sess_tmp, &ctxdata->sess_list, -- cgit v1.2.3-59-g8ed1b From 53e3ca5cee24f5fafe4e9ff5fe4b230e1a1b85ed Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Sat, 1 Jul 2017 17:56:06 +0530 Subject: tee: tee_shm: Constify dma_buf_ops structures. dma_buf_ops are not supposed to change at runtime. All functions working with dma_buf_ops provided by work with const dma_buf_ops. So mark the non-const structs as const. File size before: text data bss dec hex filename 2026 112 0 2138 85a drivers/tee/tee_shm.o File size After adding 'const': text data bss dec hex filename 2138 0 0 2138 85a drivers/tee/tee_shm.o Signed-off-by: Arvind Yadav Signed-off-by: Jens Wiklander --- drivers/tee/tee_shm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/tee/tee_shm.c b/drivers/tee/tee_shm.c index d356d7f025eb..4bc7956cefc4 100644 --- a/drivers/tee/tee_shm.c +++ b/drivers/tee/tee_shm.c @@ -80,7 +80,7 @@ static int tee_shm_op_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma) size, vma->vm_page_prot); } -static struct dma_buf_ops tee_shm_dma_buf_ops = { +static const struct dma_buf_ops tee_shm_dma_buf_ops = { .map_dma_buf = tee_shm_op_map_dma_buf, .unmap_dma_buf = tee_shm_op_unmap_dma_buf, .release = tee_shm_op_release, -- cgit v1.2.3-59-g8ed1b From 96e72ddeec4546fda0e194298c2ee39e394a3ab7 Mon Sep 17 00:00:00 2001 From: Bhumika Goyal Date: Thu, 29 Jun 2017 15:05:04 +0530 Subject: tee: optee: add const to tee_driver_ops and tee_desc structures Add const to tee_desc structures as they are only passed as an argument to the function tee_device_alloc. This argument is of type const, so declare these structures as const too. Add const to tee_driver_ops structures as they are only stored in the ops field of a tee_desc structure. This field is of type const, so declare these structure types as const. Signed-off-by: Bhumika Goyal Signed-off-by: Jens Wiklander --- drivers/tee/optee/core.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/tee/optee/core.c b/drivers/tee/optee/core.c index 857141e29e80..7952357df9c8 100644 --- a/drivers/tee/optee/core.c +++ b/drivers/tee/optee/core.c @@ -259,7 +259,7 @@ static void optee_release(struct tee_context *ctx) } } -static struct tee_driver_ops optee_ops = { +static const struct tee_driver_ops optee_ops = { .get_version = optee_get_version, .open = optee_open, .release = optee_release, @@ -269,13 +269,13 @@ static struct tee_driver_ops optee_ops = { .cancel_req = optee_cancel_req, }; -static struct tee_desc optee_desc = { +static const struct tee_desc optee_desc = { .name = DRIVER_NAME "-clnt", .ops = &optee_ops, .owner = THIS_MODULE, }; -static struct tee_driver_ops optee_supp_ops = { +static const struct tee_driver_ops optee_supp_ops = { .get_version = optee_get_version, .open = optee_open, .release = optee_release, @@ -283,7 +283,7 @@ static struct tee_driver_ops optee_supp_ops = { .supp_send = optee_supp_send, }; -static struct tee_desc optee_supp_desc = { +static const struct tee_desc optee_supp_desc = { .name = DRIVER_NAME "-supp", .ops = &optee_supp_ops, .owner = THIS_MODULE, -- cgit v1.2.3-59-g8ed1b From a9980e947ec97297e03d2332d6beff06f5131a98 Mon Sep 17 00:00:00 2001 From: tiger-yu99 Date: Sat, 6 May 2017 00:20:32 +0800 Subject: tee: optee: interruptible RPC sleep Prior to this patch RPC sleep was uninterruptible since msleep() is uninterruptible. Change to use msleep_interruptible() instead. Signed-off-by: Tiger Yu Reviewed-by: Joakim Bech Signed-off-by: Jerome Forissier Signed-off-by: Jens Wiklander --- drivers/tee/optee/rpc.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/tee/optee/rpc.c b/drivers/tee/optee/rpc.c index 8814eca06021..9488ed1541bc 100644 --- a/drivers/tee/optee/rpc.c +++ b/drivers/tee/optee/rpc.c @@ -140,11 +140,8 @@ static void handle_rpc_func_cmd_wait(struct optee_msg_arg *arg) msec_to_wait = arg->params[0].u.value.a; - /* set task's state to interruptible sleep */ - set_current_state(TASK_INTERRUPTIBLE); - - /* take a nap */ - msleep(msec_to_wait); + /* Go to interruptible sleep */ + msleep_interruptible(msec_to_wait); arg->ret = TEEC_SUCCESS; return; -- cgit v1.2.3-59-g8ed1b From 059cf566e123ca7eb7434285c6455d7afafb4e02 Mon Sep 17 00:00:00 2001 From: Jens Wiklander Date: Thu, 16 Feb 2017 09:07:02 +0100 Subject: tee: indicate privileged dev in gen_caps Mirrors the TEE_DESC_PRIVILEGED bit of struct tee_desc:flags into struct tee_ioctl_version_data:gen_caps as TEE_GEN_CAP_PRIVILEGED in tee_ioctl_version() Reviewed-by: Jerome Forissier Signed-off-by: Jens Wiklander --- drivers/tee/tee_core.c | 5 +++++ include/uapi/linux/tee.h | 1 + 2 files changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/tee/tee_core.c b/drivers/tee/tee_core.c index 5c60bf4423e6..58a5009eacc3 100644 --- a/drivers/tee/tee_core.c +++ b/drivers/tee/tee_core.c @@ -90,8 +90,13 @@ static int tee_ioctl_version(struct tee_context *ctx, struct tee_ioctl_version_data vers; ctx->teedev->desc->ops->get_version(ctx->teedev, &vers); + + if (ctx->teedev->desc->flags & TEE_DESC_PRIVILEGED) + vers.gen_caps |= TEE_GEN_CAP_PRIVILEGED; + if (copy_to_user(uvers, &vers, sizeof(vers))) return -EFAULT; + return 0; } diff --git a/include/uapi/linux/tee.h b/include/uapi/linux/tee.h index 370d8845ab21..688782e90140 100644 --- a/include/uapi/linux/tee.h +++ b/include/uapi/linux/tee.h @@ -49,6 +49,7 @@ #define TEE_MAX_ARG_SIZE 1024 #define TEE_GEN_CAP_GP (1 << 0)/* GlobalPlatform compliant TEE */ +#define TEE_GEN_CAP_PRIVILEGED (1 << 1)/* Privileged device (for supplicant) */ /* * TEE Implementation ID -- cgit v1.2.3-59-g8ed1b From 39e6519a3f135b143dee4d4fb5ac0438e75454e2 Mon Sep 17 00:00:00 2001 From: David Wang Date: Thu, 16 Feb 2017 16:43:44 +0800 Subject: tee: optee: sync with new naming of interrupts In the latest changes of optee_os, the interrupts' names are changed to "native" and "foreign" interrupts. Signed-off-by: David Wang Signed-off-by: Jerome Forissier Signed-off-by: Jens Wiklander --- drivers/tee/optee/optee_smc.h | 12 ++++++------ drivers/tee/optee/rpc.c | 8 ++++---- 2 files changed, 10 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/tee/optee/optee_smc.h b/drivers/tee/optee/optee_smc.h index 13b7c98cdf25..069c8e1429de 100644 --- a/drivers/tee/optee/optee_smc.h +++ b/drivers/tee/optee/optee_smc.h @@ -298,7 +298,7 @@ struct optee_smc_disable_shm_cache_result { OPTEE_SMC_FAST_CALL_VAL(OPTEE_SMC_FUNCID_ENABLE_SHM_CACHE) /* - * Resume from RPC (for example after processing an IRQ) + * Resume from RPC (for example after processing a foreign interrupt) * * Call register usage: * a0 SMC Function ID, OPTEE_SMC_CALL_RETURN_FROM_RPC @@ -383,19 +383,19 @@ struct optee_smc_disable_shm_cache_result { OPTEE_SMC_RPC_VAL(OPTEE_SMC_RPC_FUNC_FREE) /* - * Deliver an IRQ in normal world. + * Deliver foreign interrupt to normal world. * * "Call" register usage: - * a0 OPTEE_SMC_RETURN_RPC_IRQ + * a0 OPTEE_SMC_RETURN_RPC_FOREIGN_INTR * a1-7 Resume information, must be preserved * * "Return" register usage: * a0 SMC Function ID, OPTEE_SMC_CALL_RETURN_FROM_RPC. * a1-7 Preserved */ -#define OPTEE_SMC_RPC_FUNC_IRQ 4 -#define OPTEE_SMC_RETURN_RPC_IRQ \ - OPTEE_SMC_RPC_VAL(OPTEE_SMC_RPC_FUNC_IRQ) +#define OPTEE_SMC_RPC_FUNC_FOREIGN_INTR 4 +#define OPTEE_SMC_RETURN_RPC_FOREIGN_INTR \ + OPTEE_SMC_RPC_VAL(OPTEE_SMC_RPC_FUNC_FOREIGN_INTR) /* * Do an RPC request. The supplied struct optee_msg_arg tells which diff --git a/drivers/tee/optee/rpc.c b/drivers/tee/optee/rpc.c index 9488ed1541bc..cef417f4f4d2 100644 --- a/drivers/tee/optee/rpc.c +++ b/drivers/tee/optee/rpc.c @@ -371,11 +371,11 @@ void optee_handle_rpc(struct tee_context *ctx, struct optee_rpc_param *param) shm = reg_pair_to_ptr(param->a1, param->a2); tee_shm_free(shm); break; - case OPTEE_SMC_RPC_FUNC_IRQ: + case OPTEE_SMC_RPC_FUNC_FOREIGN_INTR: /* - * An IRQ was raised while secure world was executing, - * since all IRQs are handled in Linux a dummy RPC is - * performed to let Linux take the IRQ through the normal + * A foreign interrupt was raised while secure world was + * executing, since they are handled in Linux a dummy RPC is + * performed to let Linux take the interrupt through the normal * vector. */ break; -- cgit v1.2.3-59-g8ed1b From a3843bee7771dab97c814957533e753117638873 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Fri, 4 Aug 2017 22:32:32 +0200 Subject: Revert "reset: Add a Gemini reset controller" This reverts commit 2acb037fc42b8ce5ae59a7d5db3c9b35672e3dd7. We ended up merging the reset controller into the clock controller so we can now get rid of this stand-alone implementation. Signed-off-by: Linus Walleij Signed-off-by: Philipp Zabel --- drivers/reset/Kconfig | 7 --- drivers/reset/Makefile | 1 - drivers/reset/reset-gemini.c | 110 ------------------------------------------- 3 files changed, 118 deletions(-) delete mode 100644 drivers/reset/reset-gemini.c (limited to 'drivers') diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index c4c4a4cbcf49..52d5251660b9 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -34,13 +34,6 @@ config RESET_BERLIN help This enables the reset controller driver for Marvell Berlin SoCs. -config RESET_GEMINI - bool "Gemini Reset Driver" if COMPILE_TEST - default ARCH_GEMINI - select MFD_SYSCON - help - This enables the reset controller driver for Cortina Systems Gemini. - config RESET_HSDK_V1 bool "HSDK v1 Reset Driver" default n diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile index 9373040efc63..b62783f50fe5 100644 --- a/drivers/reset/Makefile +++ b/drivers/reset/Makefile @@ -5,7 +5,6 @@ obj-$(CONFIG_ARCH_TEGRA) += tegra/ obj-$(CONFIG_RESET_A10SR) += reset-a10sr.o obj-$(CONFIG_RESET_ATH79) += reset-ath79.o obj-$(CONFIG_RESET_BERLIN) += reset-berlin.o -obj-$(CONFIG_RESET_GEMINI) += reset-gemini.o obj-$(CONFIG_RESET_HSDK_V1) += reset-hsdk-v1.o obj-$(CONFIG_RESET_IMX7) += reset-imx7.o obj-$(CONFIG_RESET_LPC18XX) += reset-lpc18xx.o diff --git a/drivers/reset/reset-gemini.c b/drivers/reset/reset-gemini.c deleted file mode 100644 index a2478997c75b..000000000000 --- a/drivers/reset/reset-gemini.c +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Cortina Gemini Reset controller driver - * Copyright (C) 2017 Linus Walleij - * - * 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 -#include -#include -#include -#include -#include -#include -#include - -/** - * struct gemini_reset - gemini reset controller - * @map: regmap to access the containing system controller - * @rcdev: reset controller device - */ -struct gemini_reset { - struct regmap *map; - struct reset_controller_dev rcdev; -}; - -#define GEMINI_GLOBAL_SOFT_RESET 0x0c - -#define to_gemini_reset(p) \ - container_of((p), struct gemini_reset, rcdev) - -/* - * This is a self-deasserting reset controller. - */ -static int gemini_reset(struct reset_controller_dev *rcdev, - unsigned long id) -{ - struct gemini_reset *gr = to_gemini_reset(rcdev); - - /* Manual says to always set BIT 30 (CPU1) to 1 */ - return regmap_write(gr->map, - GEMINI_GLOBAL_SOFT_RESET, - BIT(GEMINI_RESET_CPU1) | BIT(id)); -} - -static int gemini_reset_status(struct reset_controller_dev *rcdev, - unsigned long id) -{ - struct gemini_reset *gr = to_gemini_reset(rcdev); - u32 val; - int ret; - - ret = regmap_read(gr->map, GEMINI_GLOBAL_SOFT_RESET, &val); - if (ret) - return ret; - - return !!(val & BIT(id)); -} - -static const struct reset_control_ops gemini_reset_ops = { - .reset = gemini_reset, - .status = gemini_reset_status, -}; - -static int gemini_reset_probe(struct platform_device *pdev) -{ - struct gemini_reset *gr; - struct device *dev = &pdev->dev; - struct device_node *np = dev->of_node; - int ret; - - gr = devm_kzalloc(dev, sizeof(*gr), GFP_KERNEL); - if (!gr) - return -ENOMEM; - - gr->map = syscon_node_to_regmap(np); - if (IS_ERR(gr->map)) { - ret = PTR_ERR(gr->map); - dev_err(dev, "unable to get regmap (%d)", ret); - return ret; - } - gr->rcdev.owner = THIS_MODULE; - gr->rcdev.nr_resets = 32; - gr->rcdev.ops = &gemini_reset_ops; - gr->rcdev.of_node = pdev->dev.of_node; - - ret = devm_reset_controller_register(&pdev->dev, &gr->rcdev); - if (ret) - return ret; - - dev_info(dev, "registered Gemini reset controller\n"); - return 0; -} - -static const struct of_device_id gemini_reset_dt_ids[] = { - { .compatible = "cortina,gemini-syscon", }, - { /* sentinel */ }, -}; - -static struct platform_driver gemini_reset_driver = { - .probe = gemini_reset_probe, - .driver = { - .name = "gemini-reset", - .of_match_table = gemini_reset_dt_ids, - .suppress_bind_attrs = true, - }, -}; -builtin_platform_driver(gemini_reset_driver); -- cgit v1.2.3-59-g8ed1b From 3e8b55411468ef9aa4401282a869715c45b0310b Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Fri, 30 Jun 2017 11:47:21 -0400 Subject: soc: qcom: smsm: fix of_node refcnting problem of_find_node_with_property() drops the reference to the 'from' node, which eventually (after enough -EPROBE_DEFERs) drops the last reference to the node causing all sorts of fun problems, and this nice splat. BUG: sleeping function called from invalid context at ../kernel/locking/mutex.c:747 in_atomic(): 1, irqs_disabled(): 128, pid: 33, name: kworker/0:1 4 locks held by kworker/0:1/33: #0: ("events"){.+.+.+}, at: [] process_one_work+0x1a4/0x728 #1: (deferred_probe_work){+.+.+.}, at: [] process_one_work+0x1a4/0x728 #2: (&dev->mutex){......}, at: [] __device_attach+0x30/0x168 #3: (devtree_lock){......}, at: [] of_find_node_with_property+0x30/0xe0 irq event stamp: 18976 hardirqs last enabled at (18975): [] __down_trylock_console_sem+0x74/0xb8 hardirqs last disabled at (18976): [] _raw_spin_lock_irqsave+0x2c/0x78 softirqs last enabled at (16880): [] __do_softirq+0x580/0x640 softirqs last disabled at (16871): [] irq_exit+0xe4/0x138 CPU: 0 PID: 33 Comm: kworker/0:1 Tainted: G E 4.12.0-rc5+ #1455 Hardware name: qualcomm dragonboard410c/dragonboard410c, BIOS 2017.07-rc1-00234-g22fa70a-dirty 06/26/2017 Workqueue: events deferred_probe_work_func Call trace: [] dump_backtrace+0x0/0x230 [] show_stack+0x24/0x30 [] dump_stack+0xac/0xe8 [] ___might_sleep+0x150/0x230 [] __might_sleep+0x58/0x90 [] __mutex_lock+0x50/0x870 [] mutex_lock_nested+0x3c/0x50 [] kernfs_remove+0x30/0x50 [] sysfs_remove_dir+0x58/0x70 [] kobject_del+0x1c/0x58 [] kobject_put+0xb4/0x208 [] of_node_put+0x24/0x30 [] of_find_node_with_property+0x78/0xe0 [] qcom_smsm_probe+0x194/0x720 [smsm] [] platform_drv_probe+0x74/0x110 [] driver_probe_device+0x2b4/0x420 [] __device_attach_driver+0xd0/0x150 [] bus_for_each_drv+0x68/0xa8 [] __device_attach+0xd4/0x168 [] device_initial_probe+0x24/0x30 [] bus_probe_device+0xa0/0xa8 [] deferred_probe_work_func+0xb8/0xf8 [] process_one_work+0x25c/0x728 [] worker_thread+0x54/0x3d8 [] kthread+0x110/0x140 [] ret_from_fork+0x10/0x40 OF: ERROR: Bad of_node_put() on /smsm CPU: 0 PID: 33 Comm: kworker/0:1 Tainted: G W E 4.12.0-rc5+ #1455 Hardware name: qualcomm dragonboard410c/dragonboard410c, BIOS 2017.07-rc1-00234-g22fa70a-dirty 06/26/2017 Workqueue: events deferred_probe_work_func Signed-off-by: Rob Clark Signed-off-by: Andy Gross --- drivers/soc/qcom/smsm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/soc/qcom/smsm.c b/drivers/soc/qcom/smsm.c index dc540ea92e9d..403bea9d546b 100644 --- a/drivers/soc/qcom/smsm.c +++ b/drivers/soc/qcom/smsm.c @@ -496,7 +496,8 @@ static int qcom_smsm_probe(struct platform_device *pdev) if (!smsm->hosts) return -ENOMEM; - local_node = of_find_node_with_property(pdev->dev.of_node, "#qcom,smem-state-cells"); + local_node = of_find_node_with_property(of_node_get(pdev->dev.of_node), + "#qcom,smem-state-cells"); if (!local_node) { dev_err(&pdev->dev, "no state entry\n"); return -EINVAL; -- cgit v1.2.3-59-g8ed1b From b83399090135e6315660d5cce68899174161843b Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Sun, 2 Jul 2017 09:23:36 -0400 Subject: soc: qcom: wcnss_ctrl: add missing MODULE_DEVICE_TABLE() This fixes a problem of wifi module not loading on db410c. Signed-off-by: Rob Clark Reviewed-by: Bjorn Andersson Signed-off-by: Andy Gross --- drivers/soc/qcom/wcnss_ctrl.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/soc/qcom/wcnss_ctrl.c b/drivers/soc/qcom/wcnss_ctrl.c index b9069184df19..d008e5b82db4 100644 --- a/drivers/soc/qcom/wcnss_ctrl.c +++ b/drivers/soc/qcom/wcnss_ctrl.c @@ -347,6 +347,7 @@ static const struct of_device_id wcnss_ctrl_of_match[] = { { .compatible = "qcom,wcnss", }, {} }; +MODULE_DEVICE_TABLE(of, wcnss_ctrl_of_match); static struct rpmsg_driver wcnss_ctrl_driver = { .probe = wcnss_ctrl_probe, -- cgit v1.2.3-59-g8ed1b From 2a464815d3262e441a5cff7cbece69c0b76b14d6 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Wed, 26 Jul 2017 17:27:16 +0200 Subject: soc: qcom: bring all qcom drivers into a submenu As the number of qcom drivers increase, entries in SOC menu looks scattered with other SOC drivers. Make a submenu for Qcom drivers to make it visibly clear while selecting qcom SOC specific drivers. Signed-off-by: Srinivas Kandagatla Signed-off-by: Andy Gross --- drivers/soc/qcom/Kconfig | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig index 9fca977ef18d..5f12657fc552 100644 --- a/drivers/soc/qcom/Kconfig +++ b/drivers/soc/qcom/Kconfig @@ -1,6 +1,8 @@ # # QCOM Soc drivers # +menu "Qualcomm SoC drivers" + config QCOM_GSBI tristate "QCOM General Serial Bus Interface" depends on ARCH_QCOM @@ -74,3 +76,5 @@ config QCOM_WCNSS_CTRL help Client driver for the WCNSS_CTRL SMD channel, used to download nv firmware to a newly booted WCNSS chip. + +endmenu -- cgit v1.2.3-59-g8ed1b From 445c2410a449ae29c0ec0bb9cee8f38078c4a2f1 Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Mon, 26 Jun 2017 13:36:59 -0700 Subject: soc: qcom: mdt_loader: Use request_firmware_into_buf() By switching to the request_firmware_into_buf() we load the segment data straight into the preallocated buffers, reducing the need for allocating scratch buffers for these. In particular the modem firmware consists of multiple segments in the range 5-15MB, making this worth while. Signed-off-by: Bjorn Andersson Signed-off-by: Andy Gross --- drivers/soc/qcom/mdt_loader.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/soc/qcom/mdt_loader.c b/drivers/soc/qcom/mdt_loader.c index bd63df0d14e0..08bd8549242a 100644 --- a/drivers/soc/qcom/mdt_loader.c +++ b/drivers/soc/qcom/mdt_loader.c @@ -178,14 +178,13 @@ int qcom_mdt_load(struct device *dev, const struct firmware *fw, if (phdr->p_filesz) { sprintf(fw_name + fw_name_len - 3, "b%02d", i); - ret = request_firmware(&seg_fw, fw_name, dev); + ret = request_firmware_into_buf(&seg_fw, fw_name, dev, + ptr, phdr->p_filesz); if (ret) { dev_err(dev, "failed to load %s\n", fw_name); break; } - memcpy(ptr, seg_fw->data, seg_fw->size); - release_firmware(seg_fw); } -- cgit v1.2.3-59-g8ed1b From 5281036a054020b7d4ec186a9d9852b6c3bea452 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 6 Aug 2017 11:44:01 +0900 Subject: reset: uniphier: remove sLD3 SoC support This SoC is too old. It is difficult to maintain any longer. Signed-off-by: Masahiro Yamada Acked-by: Rob Herring Signed-off-by: Philipp Zabel --- .../devicetree/bindings/reset/uniphier-reset.txt | 2 - drivers/reset/reset-uniphier.c | 48 ++++++++-------------- 2 files changed, 16 insertions(+), 34 deletions(-) (limited to 'drivers') diff --git a/Documentation/devicetree/bindings/reset/uniphier-reset.txt b/Documentation/devicetree/bindings/reset/uniphier-reset.txt index 83ab0f599c40..b80ccc03ab9f 100644 --- a/Documentation/devicetree/bindings/reset/uniphier-reset.txt +++ b/Documentation/devicetree/bindings/reset/uniphier-reset.txt @@ -6,7 +6,6 @@ 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 @@ -37,7 +36,6 @@ 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 diff --git a/drivers/reset/reset-uniphier.c b/drivers/reset/reset-uniphier.c index c4ba89832796..3947fc2ef52c 100644 --- a/drivers/reset/reset-uniphier.c +++ b/drivers/reset/reset-uniphier.c @@ -50,18 +50,12 @@ struct uniphier_reset_data { } /* System reset data */ -#define UNIPHIER_SLD3_SYS_RESET_NAND(id) \ - UNIPHIER_RESETX((id), 0x2004, 2) - #define UNIPHIER_LD11_SYS_RESET_NAND(id) \ UNIPHIER_RESETX((id), 0x200c, 0) #define UNIPHIER_LD11_SYS_RESET_EMMC(id) \ UNIPHIER_RESETX((id), 0x200c, 2) -#define UNIPHIER_SLD3_SYS_RESET_STDMAC(id) \ - UNIPHIER_RESETX((id), 0x2000, 10) - #define UNIPHIER_LD11_SYS_RESET_STDMAC(id) \ UNIPHIER_RESETX((id), 0x200c, 8) @@ -74,15 +68,15 @@ struct uniphier_reset_data { #define UNIPHIER_PRO4_SYS_RESET_USB3(id, ch) \ UNIPHIER_RESETX((id), 0x2000 + 0x4 * (ch), 17) -static const struct uniphier_reset_data uniphier_sld3_sys_reset_data[] = { - UNIPHIER_SLD3_SYS_RESET_NAND(2), - UNIPHIER_SLD3_SYS_RESET_STDMAC(8), /* Ether, HSC, MIO */ +static const struct uniphier_reset_data uniphier_ld4_sys_reset_data[] = { + UNIPHIER_RESETX(2, 0x2000, 2), /* NAND */ + UNIPHIER_RESETX(8, 0x2000, 10), /* STDMAC (Ether, HSC, MIO) */ UNIPHIER_RESET_END, }; static const struct uniphier_reset_data uniphier_pro4_sys_reset_data[] = { - UNIPHIER_SLD3_SYS_RESET_NAND(2), - UNIPHIER_SLD3_SYS_RESET_STDMAC(8), /* HSC, MIO, RLE */ + UNIPHIER_RESETX(2, 0x2000, 2), /* NAND */ + UNIPHIER_RESETX(8, 0x2000, 10), /* STDMAC (HSC, MIO, RLE) */ UNIPHIER_PRO4_SYS_RESET_GIO(12), /* Ether, SATA, USB3 */ UNIPHIER_PRO4_SYS_RESET_USB3(14, 0), UNIPHIER_PRO4_SYS_RESET_USB3(15, 1), @@ -90,8 +84,8 @@ static const struct uniphier_reset_data uniphier_pro4_sys_reset_data[] = { }; static const struct uniphier_reset_data uniphier_pro5_sys_reset_data[] = { - UNIPHIER_SLD3_SYS_RESET_NAND(2), - UNIPHIER_SLD3_SYS_RESET_STDMAC(8), /* HSC */ + UNIPHIER_RESETX(2, 0x2000, 2), /* NAND */ + UNIPHIER_RESETX(8, 0x2000, 10), /* STDMAC (HSC) */ UNIPHIER_PRO4_SYS_RESET_GIO(12), /* PCIe, USB3 */ UNIPHIER_PRO4_SYS_RESET_USB3(14, 0), UNIPHIER_PRO4_SYS_RESET_USB3(15, 1), @@ -99,8 +93,8 @@ static const struct uniphier_reset_data uniphier_pro5_sys_reset_data[] = { }; static const struct uniphier_reset_data uniphier_pxs2_sys_reset_data[] = { - UNIPHIER_SLD3_SYS_RESET_NAND(2), - UNIPHIER_SLD3_SYS_RESET_STDMAC(8), /* HSC, RLE */ + UNIPHIER_RESETX(2, 0x2000, 2), /* NAND */ + UNIPHIER_RESETX(8, 0x2000, 10), /* STDMAC (HSC, RLE) */ UNIPHIER_PRO4_SYS_RESET_USB3(14, 0), UNIPHIER_PRO4_SYS_RESET_USB3(15, 1), UNIPHIER_RESETX(16, 0x2014, 4), /* USB30-PHY0 */ @@ -151,7 +145,7 @@ static const struct uniphier_reset_data uniphier_ld20_sys_reset_data[] = { #define UNIPHIER_MIO_RESET_DMAC(id) \ UNIPHIER_RESETX((id), 0x110, 17) -static const struct uniphier_reset_data uniphier_sld3_mio_reset_data[] = { +static const struct uniphier_reset_data uniphier_ld4_mio_reset_data[] = { UNIPHIER_MIO_RESET_SD(0, 0), UNIPHIER_MIO_RESET_SD(1, 1), UNIPHIER_MIO_RESET_SD(2, 2), @@ -163,11 +157,9 @@ static const struct uniphier_reset_data uniphier_sld3_mio_reset_data[] = { UNIPHIER_MIO_RESET_USB2(8, 0), UNIPHIER_MIO_RESET_USB2(9, 1), UNIPHIER_MIO_RESET_USB2(10, 2), - UNIPHIER_MIO_RESET_USB2(11, 3), UNIPHIER_MIO_RESET_USB2_BRIDGE(12, 0), UNIPHIER_MIO_RESET_USB2_BRIDGE(13, 1), UNIPHIER_MIO_RESET_USB2_BRIDGE(14, 2), - UNIPHIER_MIO_RESET_USB2_BRIDGE(15, 3), UNIPHIER_RESET_END, }; @@ -345,13 +337,9 @@ static int uniphier_reset_probe(struct platform_device *pdev) static const struct of_device_id uniphier_reset_match[] = { /* System reset */ - { - .compatible = "socionext,uniphier-sld3-reset", - .data = uniphier_sld3_sys_reset_data, - }, { .compatible = "socionext,uniphier-ld4-reset", - .data = uniphier_sld3_sys_reset_data, + .data = uniphier_ld4_sys_reset_data, }, { .compatible = "socionext,uniphier-pro4-reset", @@ -359,7 +347,7 @@ static const struct of_device_id uniphier_reset_match[] = { }, { .compatible = "socionext,uniphier-sld8-reset", - .data = uniphier_sld3_sys_reset_data, + .data = uniphier_ld4_sys_reset_data, }, { .compatible = "socionext,uniphier-pro5-reset", @@ -378,21 +366,17 @@ static const struct of_device_id uniphier_reset_match[] = { .data = uniphier_ld20_sys_reset_data, }, /* Media I/O reset, SD reset */ - { - .compatible = "socionext,uniphier-sld3-mio-reset", - .data = uniphier_sld3_mio_reset_data, - }, { .compatible = "socionext,uniphier-ld4-mio-reset", - .data = uniphier_sld3_mio_reset_data, + .data = uniphier_ld4_mio_reset_data, }, { .compatible = "socionext,uniphier-pro4-mio-reset", - .data = uniphier_sld3_mio_reset_data, + .data = uniphier_ld4_mio_reset_data, }, { .compatible = "socionext,uniphier-sld8-mio-reset", - .data = uniphier_sld3_mio_reset_data, + .data = uniphier_ld4_mio_reset_data, }, { .compatible = "socionext,uniphier-pro5-sd-reset", @@ -404,7 +388,7 @@ static const struct of_device_id uniphier_reset_match[] = { }, { .compatible = "socionext,uniphier-ld11-mio-reset", - .data = uniphier_sld3_mio_reset_data, + .data = uniphier_ld4_mio_reset_data, }, { .compatible = "socionext,uniphier-ld11-sd-reset", -- cgit v1.2.3-59-g8ed1b From dec173ccbcb730686084ca37afe933e42023c0e7 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 6 Aug 2017 11:44:02 +0900 Subject: reset: uniphier: do not use per-SoC macro for system reset block This macro turned out not so useful as I had expected. Hardware engineers said they would change reset bit assignments for every SoC going forward. This means we can not share the macros among SoCs. Just use primitive macros. Signed-off-by: Masahiro Yamada Signed-off-by: Philipp Zabel --- drivers/reset/reset-uniphier.c | 48 +++++++++++++----------------------------- 1 file changed, 15 insertions(+), 33 deletions(-) (limited to 'drivers') diff --git a/drivers/reset/reset-uniphier.c b/drivers/reset/reset-uniphier.c index 3947fc2ef52c..954b2c4e6ca7 100644 --- a/drivers/reset/reset-uniphier.c +++ b/drivers/reset/reset-uniphier.c @@ -50,24 +50,6 @@ struct uniphier_reset_data { } /* System reset data */ -#define UNIPHIER_LD11_SYS_RESET_NAND(id) \ - UNIPHIER_RESETX((id), 0x200c, 0) - -#define UNIPHIER_LD11_SYS_RESET_EMMC(id) \ - UNIPHIER_RESETX((id), 0x200c, 2) - -#define UNIPHIER_LD11_SYS_RESET_STDMAC(id) \ - UNIPHIER_RESETX((id), 0x200c, 8) - -#define UNIPHIER_PRO4_SYS_RESET_GIO(id) \ - UNIPHIER_RESETX((id), 0x2000, 6) - -#define UNIPHIER_LD20_SYS_RESET_GIO(id) \ - UNIPHIER_RESETX((id), 0x200c, 5) - -#define UNIPHIER_PRO4_SYS_RESET_USB3(id, ch) \ - UNIPHIER_RESETX((id), 0x2000 + 0x4 * (ch), 17) - static const struct uniphier_reset_data uniphier_ld4_sys_reset_data[] = { UNIPHIER_RESETX(2, 0x2000, 2), /* NAND */ UNIPHIER_RESETX(8, 0x2000, 10), /* STDMAC (Ether, HSC, MIO) */ @@ -77,26 +59,26 @@ static const struct uniphier_reset_data uniphier_ld4_sys_reset_data[] = { static const struct uniphier_reset_data uniphier_pro4_sys_reset_data[] = { UNIPHIER_RESETX(2, 0x2000, 2), /* NAND */ UNIPHIER_RESETX(8, 0x2000, 10), /* STDMAC (HSC, MIO, RLE) */ - UNIPHIER_PRO4_SYS_RESET_GIO(12), /* Ether, SATA, USB3 */ - UNIPHIER_PRO4_SYS_RESET_USB3(14, 0), - UNIPHIER_PRO4_SYS_RESET_USB3(15, 1), + UNIPHIER_RESETX(12, 0x2000, 6), /* GIO (Ether, SATA, USB3) */ + UNIPHIER_RESETX(14, 0x2000, 17), /* USB30 */ + UNIPHIER_RESETX(15, 0x2004, 17), /* USB31 */ UNIPHIER_RESET_END, }; static const struct uniphier_reset_data uniphier_pro5_sys_reset_data[] = { UNIPHIER_RESETX(2, 0x2000, 2), /* NAND */ UNIPHIER_RESETX(8, 0x2000, 10), /* STDMAC (HSC) */ - UNIPHIER_PRO4_SYS_RESET_GIO(12), /* PCIe, USB3 */ - UNIPHIER_PRO4_SYS_RESET_USB3(14, 0), - UNIPHIER_PRO4_SYS_RESET_USB3(15, 1), + UNIPHIER_RESETX(12, 0x2000, 6), /* GIO (PCIe, USB3) */ + UNIPHIER_RESETX(14, 0x2000, 17), /* USB30 */ + UNIPHIER_RESETX(15, 0x2004, 17), /* USB31 */ UNIPHIER_RESET_END, }; static const struct uniphier_reset_data uniphier_pxs2_sys_reset_data[] = { UNIPHIER_RESETX(2, 0x2000, 2), /* NAND */ UNIPHIER_RESETX(8, 0x2000, 10), /* STDMAC (HSC, RLE) */ - UNIPHIER_PRO4_SYS_RESET_USB3(14, 0), - UNIPHIER_PRO4_SYS_RESET_USB3(15, 1), + UNIPHIER_RESETX(14, 0x2000, 17), /* USB30 */ + UNIPHIER_RESETX(15, 0x2004, 17), /* USB31 */ UNIPHIER_RESETX(16, 0x2014, 4), /* USB30-PHY0 */ UNIPHIER_RESETX(17, 0x2014, 0), /* USB30-PHY1 */ UNIPHIER_RESETX(18, 0x2014, 2), /* USB30-PHY2 */ @@ -108,17 +90,17 @@ static const struct uniphier_reset_data uniphier_pxs2_sys_reset_data[] = { }; static const struct uniphier_reset_data uniphier_ld11_sys_reset_data[] = { - UNIPHIER_LD11_SYS_RESET_NAND(2), - UNIPHIER_LD11_SYS_RESET_EMMC(4), - UNIPHIER_LD11_SYS_RESET_STDMAC(8), /* HSC, MIO */ + UNIPHIER_RESETX(2, 0x200c, 0), /* NAND */ + UNIPHIER_RESETX(4, 0x200c, 2), /* eMMC */ + UNIPHIER_RESETX(8, 0x200c, 8), /* STDMAC (HSC, MIO) */ UNIPHIER_RESET_END, }; static const struct uniphier_reset_data uniphier_ld20_sys_reset_data[] = { - UNIPHIER_LD11_SYS_RESET_NAND(2), - UNIPHIER_LD11_SYS_RESET_EMMC(4), - UNIPHIER_LD11_SYS_RESET_STDMAC(8), /* HSC */ - UNIPHIER_LD20_SYS_RESET_GIO(12), /* PCIe, USB3 */ + UNIPHIER_RESETX(2, 0x200c, 0), /* NAND */ + UNIPHIER_RESETX(4, 0x200c, 2), /* eMMC */ + UNIPHIER_RESETX(8, 0x200c, 8), /* STDMAC (HSC) */ + UNIPHIER_RESETX(12, 0x200c, 5), /* GIO (PCIe, USB3) */ UNIPHIER_RESETX(16, 0x200c, 12), /* USB30-PHY0 */ UNIPHIER_RESETX(17, 0x200c, 13), /* USB30-PHY1 */ UNIPHIER_RESETX(18, 0x200c, 14), /* USB30-PHY2 */ -- cgit v1.2.3-59-g8ed1b From 726cc791c9b9cbbc6ef5a4e266af2bbf3c360b5b Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Fri, 11 Aug 2017 12:33:57 +0200 Subject: reset: sunxi: fix number of reset lines The Allwinner reset controller has 32-bit registers, but resource_size is measured in bytes, not number of registers. Signed-off-by: Philipp Zabel Acked-by: Chen-Yu Tsai --- drivers/reset/reset-sunxi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/reset/reset-sunxi.c b/drivers/reset/reset-sunxi.c index cd585cd2f04d..2c7dd1fd08df 100644 --- a/drivers/reset/reset-sunxi.c +++ b/drivers/reset/reset-sunxi.c @@ -107,7 +107,7 @@ static int sunxi_reset_init(struct device_node *np) spin_lock_init(&data->lock); data->rcdev.owner = THIS_MODULE; - data->rcdev.nr_resets = size * 32; + data->rcdev.nr_resets = size * 8; data->rcdev.ops = &sunxi_reset_ops; data->rcdev.of_node = np; @@ -162,7 +162,7 @@ static int sunxi_reset_probe(struct platform_device *pdev) spin_lock_init(&data->lock); data->rcdev.owner = THIS_MODULE; - data->rcdev.nr_resets = resource_size(res) * 32; + data->rcdev.nr_resets = resource_size(res) * 8; data->rcdev.ops = &sunxi_reset_ops; data->rcdev.of_node = pdev->dev.of_node; -- cgit v1.2.3-59-g8ed1b From 94e10c221e970e9591a3f984e38ac0c5a651c6cf Mon Sep 17 00:00:00 2001 From: Katsuhiro Suzuki Date: Sun, 13 Aug 2017 18:00:41 +0900 Subject: reset: uniphier: add audio systems reset control Add reset lines for audio subsystem (AIO) and SoC internal audio codec (EVEA) on UniPhier LD11/LD20 SoCs. Signed-off-by: Katsuhiro Suzuki Acked-by: Masahiro Yamada Signed-off-by: Philipp Zabel --- drivers/reset/reset-uniphier.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/reset/reset-uniphier.c b/drivers/reset/reset-uniphier.c index 954b2c4e6ca7..90c52a96f775 100644 --- a/drivers/reset/reset-uniphier.c +++ b/drivers/reset/reset-uniphier.c @@ -93,6 +93,8 @@ static const struct uniphier_reset_data uniphier_ld11_sys_reset_data[] = { UNIPHIER_RESETX(2, 0x200c, 0), /* NAND */ UNIPHIER_RESETX(4, 0x200c, 2), /* eMMC */ UNIPHIER_RESETX(8, 0x200c, 8), /* STDMAC (HSC, MIO) */ + UNIPHIER_RESETX(40, 0x2008, 0), /* AIO */ + UNIPHIER_RESETX(41, 0x2008, 1), /* EVEA */ UNIPHIER_RESET_END, }; @@ -105,6 +107,8 @@ static const struct uniphier_reset_data uniphier_ld20_sys_reset_data[] = { UNIPHIER_RESETX(17, 0x200c, 13), /* USB30-PHY1 */ UNIPHIER_RESETX(18, 0x200c, 14), /* USB30-PHY2 */ UNIPHIER_RESETX(19, 0x200c, 15), /* USB30-PHY3 */ + UNIPHIER_RESETX(40, 0x2008, 0), /* AIO */ + UNIPHIER_RESETX(41, 0x2008, 1), /* EVEA */ UNIPHIER_RESET_END, }; -- cgit v1.2.3-59-g8ed1b From 0f1954355d1b8804f70c26e275b87c7ccba04234 Mon Sep 17 00:00:00 2001 From: Katsuhiro Suzuki Date: Sun, 13 Aug 2017 18:00:42 +0900 Subject: reset: uniphier: add video input subsystem reset control Add a reset line for video input subsystem (EXIV) on UniPhier LD11/LD20 SoCs. Signed-off-by: Katsuhiro Suzuki Acked-by: Masahiro Yamada Signed-off-by: Philipp Zabel --- drivers/reset/reset-uniphier.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/reset/reset-uniphier.c b/drivers/reset/reset-uniphier.c index 90c52a96f775..f60c137c17cb 100644 --- a/drivers/reset/reset-uniphier.c +++ b/drivers/reset/reset-uniphier.c @@ -95,6 +95,7 @@ static const struct uniphier_reset_data uniphier_ld11_sys_reset_data[] = { UNIPHIER_RESETX(8, 0x200c, 8), /* STDMAC (HSC, MIO) */ UNIPHIER_RESETX(40, 0x2008, 0), /* AIO */ UNIPHIER_RESETX(41, 0x2008, 1), /* EVEA */ + UNIPHIER_RESETX(42, 0x2010, 2), /* EXIV */ UNIPHIER_RESET_END, }; @@ -109,6 +110,7 @@ static const struct uniphier_reset_data uniphier_ld20_sys_reset_data[] = { UNIPHIER_RESETX(19, 0x200c, 15), /* USB30-PHY3 */ UNIPHIER_RESETX(40, 0x2008, 0), /* AIO */ UNIPHIER_RESETX(41, 0x2008, 1), /* EVEA */ + UNIPHIER_RESETX(42, 0x2010, 2), /* EXIV */ UNIPHIER_RESET_END, }; -- cgit v1.2.3-59-g8ed1b From ac0c735ac3dd6697055299cac01617527aa6a695 Mon Sep 17 00:00:00 2001 From: Katsuhiro Suzuki Date: Sun, 13 Aug 2017 18:00:43 +0900 Subject: reset: uniphier: add analog amplifiers reset control Add a reset line for analog signal amplifier core (ADAMV) on UniPhier LD11/LD20 SoCs. Signed-off-by: Katsuhiro Suzuki Acked-by: Masahiro Yamada Signed-off-by: Philipp Zabel --- .../devicetree/bindings/reset/uniphier-reset.txt | 25 ++++++++++++++++++++++ drivers/reset/reset-uniphier.c | 15 +++++++++++++ 2 files changed, 40 insertions(+) (limited to 'drivers') diff --git a/Documentation/devicetree/bindings/reset/uniphier-reset.txt b/Documentation/devicetree/bindings/reset/uniphier-reset.txt index b80ccc03ab9f..68a6f487c409 100644 --- a/Documentation/devicetree/bindings/reset/uniphier-reset.txt +++ b/Documentation/devicetree/bindings/reset/uniphier-reset.txt @@ -90,3 +90,28 @@ Example: other nodes ... }; + + +Analog signal amplifier reset +----------------------------- + +Required properties: +- compatible: should be one of the following: + "socionext,uniphier-ld11-adamv-reset" - for LD11 SoC + "socionext,uniphier-ld20-adamv-reset" - for LD20 SoC +- #reset-cells: should be 1. + +Example: + + adamv@57920000 { + compatible = "socionext,uniphier-ld11-adamv", + "simple-mfd", "syscon"; + reg = <0x57920000 0x1000>; + + adamv_rst: reset { + compatible = "socionext,uniphier-ld11-adamv-reset"; + #reset-cells = <1>; + }; + + other nodes ... + }; diff --git a/drivers/reset/reset-uniphier.c b/drivers/reset/reset-uniphier.c index f60c137c17cb..bda2dd196ae5 100644 --- a/drivers/reset/reset-uniphier.c +++ b/drivers/reset/reset-uniphier.c @@ -196,6 +196,12 @@ static const struct uniphier_reset_data uniphier_pro4_peri_reset_data[] = { UNIPHIER_RESET_END, }; +/* Analog signal amplifiers reset data */ +static const struct uniphier_reset_data uniphier_ld11_adamv_reset_data[] = { + UNIPHIER_RESETX(0, 0x10, 6), /* EVEA */ + UNIPHIER_RESET_END, +}; + /* core implementaton */ struct uniphier_reset_priv { struct reset_controller_dev rcdev; @@ -415,6 +421,15 @@ static const struct of_device_id uniphier_reset_match[] = { .compatible = "socionext,uniphier-ld20-peri-reset", .data = uniphier_pro4_peri_reset_data, }, + /* Analog signal amplifiers reset */ + { + .compatible = "socionext,uniphier-ld11-adamv-reset", + .data = uniphier_ld11_adamv_reset_data, + }, + { + .compatible = "socionext,uniphier-ld20-adamv-reset", + .data = uniphier_ld11_adamv_reset_data, + }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, uniphier_reset_match); -- cgit v1.2.3-59-g8ed1b From 53fddb1a66ddf07774e46e220be410acbf6f3557 Mon Sep 17 00:00:00 2001 From: Sean Wang Date: Mon, 7 Aug 2017 15:24:35 +0800 Subject: soc: mediatek: reduce code duplication of scpsys_probe across all SoCs Reduce code duplication of scpsys_probe_mtXXXX across all SoCs using the more generic scpsys_probe all covering all cases to avoid starting to bloat the driver when more MediaTek SoCs supported are added. Suggested-by: Matthias Brugger Signed-off-by: Sean Wang Reviewed-by: Ulf Hansson Signed-off-by: Matthias Brugger --- drivers/soc/mediatek/mtk-scpsys.c | 182 +++++++++++++++++--------------------- 1 file changed, 79 insertions(+), 103 deletions(-) (limited to 'drivers') diff --git a/drivers/soc/mediatek/mtk-scpsys.c b/drivers/soc/mediatek/mtk-scpsys.c index ceb2cc495cd0..6268b28ed44d 100644 --- a/drivers/soc/mediatek/mtk-scpsys.c +++ b/drivers/soc/mediatek/mtk-scpsys.c @@ -124,6 +124,19 @@ struct scp { struct scp_ctrl_reg ctrl_reg; }; +struct scp_subdomain { + int origin; + int subdomain; +}; + +struct scp_soc_data { + const struct scp_domain_data *domains; + int num_domains; + const struct scp_subdomain *subdomains; + int num_subdomains; + const struct scp_ctrl_reg regs; +}; + static int scpsys_domain_is_on(struct scp_domain *scpd) { struct scp *scp = scpd->scp; @@ -357,7 +370,7 @@ static void init_clks(struct platform_device *pdev, struct clk **clk) static struct scp *init_scp(struct platform_device *pdev, const struct scp_domain_data *scp_domain_data, int num, - struct scp_ctrl_reg *scp_ctrl_reg) + const struct scp_ctrl_reg *scp_ctrl_reg) { struct genpd_onecell_data *pd_data; struct resource *res; @@ -565,26 +578,6 @@ static const struct scp_domain_data scp_domain_data_mt2701[] = { }, }; -#define NUM_DOMAINS_MT2701 ARRAY_SIZE(scp_domain_data_mt2701) - -static int __init scpsys_probe_mt2701(struct platform_device *pdev) -{ - struct scp *scp; - struct scp_ctrl_reg scp_reg; - - scp_reg.pwr_sta_offs = SPM_PWR_STATUS; - scp_reg.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND; - - scp = init_scp(pdev, scp_domain_data_mt2701, NUM_DOMAINS_MT2701, - &scp_reg); - if (IS_ERR(scp)) - return PTR_ERR(scp); - - mtk_register_power_domains(pdev, scp, NUM_DOMAINS_MT2701); - - return 0; -} - /* * MT6797 power domain support */ @@ -649,51 +642,15 @@ static const struct scp_domain_data scp_domain_data_mt6797[] = { }, }; -#define NUM_DOMAINS_MT6797 ARRAY_SIZE(scp_domain_data_mt6797) #define SPM_PWR_STATUS_MT6797 0x0180 #define SPM_PWR_STATUS_2ND_MT6797 0x0184 -static int __init scpsys_probe_mt6797(struct platform_device *pdev) -{ - struct scp *scp; - struct genpd_onecell_data *pd_data; - int ret; - struct scp_ctrl_reg scp_reg; - - scp_reg.pwr_sta_offs = SPM_PWR_STATUS_MT6797; - scp_reg.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND_MT6797; - - scp = init_scp(pdev, scp_domain_data_mt6797, NUM_DOMAINS_MT6797, - &scp_reg); - if (IS_ERR(scp)) - return PTR_ERR(scp); - - mtk_register_power_domains(pdev, scp, NUM_DOMAINS_MT6797); - - pd_data = &scp->pd_data; - - ret = pm_genpd_add_subdomain(pd_data->domains[MT6797_POWER_DOMAIN_MM], - pd_data->domains[MT6797_POWER_DOMAIN_VDEC]); - if (ret && IS_ENABLED(CONFIG_PM)) - dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret); - - ret = pm_genpd_add_subdomain(pd_data->domains[MT6797_POWER_DOMAIN_MM], - pd_data->domains[MT6797_POWER_DOMAIN_ISP]); - if (ret && IS_ENABLED(CONFIG_PM)) - dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret); - - ret = pm_genpd_add_subdomain(pd_data->domains[MT6797_POWER_DOMAIN_MM], - pd_data->domains[MT6797_POWER_DOMAIN_VENC]); - if (ret && IS_ENABLED(CONFIG_PM)) - dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret); - - ret = pm_genpd_add_subdomain(pd_data->domains[MT6797_POWER_DOMAIN_MM], - pd_data->domains[MT6797_POWER_DOMAIN_MJC]); - if (ret && IS_ENABLED(CONFIG_PM)) - dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret); - - return 0; -} +static const struct scp_subdomain scp_subdomain_mt6797[] = { + {MT6797_POWER_DOMAIN_MM, MT6797_POWER_DOMAIN_VDEC}, + {MT6797_POWER_DOMAIN_MM, MT6797_POWER_DOMAIN_ISP}, + {MT6797_POWER_DOMAIN_MM, MT6797_POWER_DOMAIN_VENC}, + {MT6797_POWER_DOMAIN_MM, MT6797_POWER_DOMAIN_MJC}, +}; /* * MT8173 power domain support @@ -789,39 +746,41 @@ static const struct scp_domain_data scp_domain_data_mt8173[] = { }, }; -#define NUM_DOMAINS_MT8173 ARRAY_SIZE(scp_domain_data_mt8173) - -static int __init scpsys_probe_mt8173(struct platform_device *pdev) -{ - struct scp *scp; - struct genpd_onecell_data *pd_data; - int ret; - struct scp_ctrl_reg scp_reg; - - scp_reg.pwr_sta_offs = SPM_PWR_STATUS; - scp_reg.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND; - - scp = init_scp(pdev, scp_domain_data_mt8173, NUM_DOMAINS_MT8173, - &scp_reg); - if (IS_ERR(scp)) - return PTR_ERR(scp); - - mtk_register_power_domains(pdev, scp, NUM_DOMAINS_MT8173); - - pd_data = &scp->pd_data; +static const struct scp_subdomain scp_subdomain_mt8173[] = { + {MT8173_POWER_DOMAIN_MFG_ASYNC, MT8173_POWER_DOMAIN_MFG_2D}, + {MT8173_POWER_DOMAIN_MFG_2D, MT8173_POWER_DOMAIN_MFG}, +}; - ret = pm_genpd_add_subdomain(pd_data->domains[MT8173_POWER_DOMAIN_MFG_ASYNC], - pd_data->domains[MT8173_POWER_DOMAIN_MFG_2D]); - if (ret && IS_ENABLED(CONFIG_PM)) - dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret); +static const struct scp_soc_data mt2701_data = { + .domains = scp_domain_data_mt2701, + .num_domains = ARRAY_SIZE(scp_domain_data_mt2701), + .regs = { + .pwr_sta_offs = SPM_PWR_STATUS, + .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND + } +}; - ret = pm_genpd_add_subdomain(pd_data->domains[MT8173_POWER_DOMAIN_MFG_2D], - pd_data->domains[MT8173_POWER_DOMAIN_MFG]); - if (ret && IS_ENABLED(CONFIG_PM)) - dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret); +static const struct scp_soc_data mt6797_data = { + .domains = scp_domain_data_mt6797, + .num_domains = ARRAY_SIZE(scp_domain_data_mt6797), + .subdomains = scp_subdomain_mt6797, + .num_subdomains = ARRAY_SIZE(scp_subdomain_mt6797), + .regs = { + .pwr_sta_offs = SPM_PWR_STATUS_MT6797, + .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND_MT6797 + } +}; - return 0; -} +static const struct scp_soc_data mt8173_data = { + .domains = scp_domain_data_mt8173, + .num_domains = ARRAY_SIZE(scp_domain_data_mt8173), + .subdomains = scp_subdomain_mt8173, + .num_subdomains = ARRAY_SIZE(scp_subdomain_mt8173), + .regs = { + .pwr_sta_offs = SPM_PWR_STATUS, + .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND + } +}; /* * scpsys driver init @@ -830,13 +789,13 @@ static int __init scpsys_probe_mt8173(struct platform_device *pdev) static const struct of_device_id of_scpsys_match_tbl[] = { { .compatible = "mediatek,mt2701-scpsys", - .data = scpsys_probe_mt2701, + .data = &mt2701_data, }, { .compatible = "mediatek,mt6797-scpsys", - .data = scpsys_probe_mt6797, + .data = &mt6797_data, }, { .compatible = "mediatek,mt8173-scpsys", - .data = scpsys_probe_mt8173, + .data = &mt8173_data, }, { /* sentinel */ } @@ -844,16 +803,33 @@ static const struct of_device_id of_scpsys_match_tbl[] = { static int scpsys_probe(struct platform_device *pdev) { - int (*probe)(struct platform_device *); - const struct of_device_id *of_id; + const struct of_device_id *match; + const struct scp_subdomain *sd; + const struct scp_soc_data *soc; + struct scp *scp; + struct genpd_onecell_data *pd_data; + int i, ret; - of_id = of_match_node(of_scpsys_match_tbl, pdev->dev.of_node); - if (!of_id || !of_id->data) - return -EINVAL; + match = of_match_device(of_scpsys_match_tbl, &pdev->dev); + soc = (const struct scp_soc_data *)match->data; - probe = of_id->data; + scp = init_scp(pdev, soc->domains, soc->num_domains, &soc->regs); + if (IS_ERR(scp)) + return PTR_ERR(scp); + + mtk_register_power_domains(pdev, scp, soc->num_domains); + + pd_data = &scp->pd_data; + + for (i = 0, sd = soc->subdomains ; i < soc->num_subdomains ; i++) { + ret = pm_genpd_add_subdomain(pd_data->domains[sd->origin], + pd_data->domains[sd->subdomain]); + if (ret && IS_ENABLED(CONFIG_PM)) + dev_err(&pdev->dev, "Failed to add subdomain: %d\n", + ret); + } - return probe(pdev); + return 0; } static struct platform_driver scpsys_drv = { -- cgit v1.2.3-59-g8ed1b From 52510ee934885ec846faaa5d029329c9ba0e6ecc Mon Sep 17 00:00:00 2001 From: Sean Wang Date: Mon, 7 Aug 2017 15:24:37 +0800 Subject: soc: mediatek: add SCPSYS power domain driver for MediaTek MT7622 SoC Add SCPSYS power domain driver for MT7622 SoC having four power domains which are respectively ETHSYS for Ethernet including embedded switch, WBSYS for WIFI and Bluetooth, HIF0SYS for PCI-E and SATA, and HIF1SYS for USB. Those functions could be selectively powered gated when the corresponding function is no longer to use in order to reach more minimal power dissipation. Signed-off-by: Chen Zhong Signed-off-by: Sean Wang Reviewed-by: Ulf Hansson Signed-off-by: Matthias Brugger --- drivers/soc/mediatek/mtk-scpsys.c | 71 +++++++++++++++++++++++++++++++++++ include/linux/soc/mediatek/infracfg.h | 7 ++++ 2 files changed, 78 insertions(+) (limited to 'drivers') diff --git a/drivers/soc/mediatek/mtk-scpsys.c b/drivers/soc/mediatek/mtk-scpsys.c index 6268b28ed44d..e1ce8b1b5090 100644 --- a/drivers/soc/mediatek/mtk-scpsys.c +++ b/drivers/soc/mediatek/mtk-scpsys.c @@ -22,6 +22,7 @@ #include #include +#include #include #define SPM_VDE_PWR_CON 0x0210 @@ -39,6 +40,11 @@ #define SPM_MFG_2D_PWR_CON 0x02c0 #define SPM_MFG_ASYNC_PWR_CON 0x02c4 #define SPM_USB_PWR_CON 0x02cc +#define SPM_ETHSYS_PWR_CON 0x02e0 /* MT7622 */ +#define SPM_HIF0_PWR_CON 0x02e4 /* MT7622 */ +#define SPM_HIF1_PWR_CON 0x02e8 /* MT7622 */ +#define SPM_WB_PWR_CON 0x02ec /* MT7622 */ + #define SPM_PWR_STATUS 0x060c #define SPM_PWR_STATUS_2ND 0x0610 @@ -64,6 +70,10 @@ #define PWR_STATUS_MFG_ASYNC BIT(23) #define PWR_STATUS_AUDIO BIT(24) #define PWR_STATUS_USB BIT(25) +#define PWR_STATUS_ETHSYS BIT(24) /* MT7622 */ +#define PWR_STATUS_HIF0 BIT(25) /* MT7622 */ +#define PWR_STATUS_HIF1 BIT(26) /* MT7622 */ +#define PWR_STATUS_WB BIT(27) /* MT7622 */ enum clk_id { CLK_NONE, @@ -73,6 +83,7 @@ enum clk_id { CLK_VENC_LT, CLK_ETHIF, CLK_VDEC, + CLK_HIFSEL, CLK_MAX, }; @@ -84,6 +95,7 @@ static const char * const clk_names[] = { "venc_lt", "ethif", "vdec", + "hif_sel", NULL, }; @@ -652,6 +664,53 @@ static const struct scp_subdomain scp_subdomain_mt6797[] = { {MT6797_POWER_DOMAIN_MM, MT6797_POWER_DOMAIN_MJC}, }; +/* + * MT7622 power domain support + */ + +static const struct scp_domain_data scp_domain_data_mt7622[] = { + [MT7622_POWER_DOMAIN_ETHSYS] = { + .name = "ethsys", + .sta_mask = PWR_STATUS_ETHSYS, + .ctl_offs = SPM_ETHSYS_PWR_CON, + .sram_pdn_bits = GENMASK(11, 8), + .sram_pdn_ack_bits = GENMASK(15, 12), + .clk_id = {CLK_NONE}, + .bus_prot_mask = MT7622_TOP_AXI_PROT_EN_ETHSYS, + .active_wakeup = true, + }, + [MT7622_POWER_DOMAIN_HIF0] = { + .name = "hif0", + .sta_mask = PWR_STATUS_HIF0, + .ctl_offs = SPM_HIF0_PWR_CON, + .sram_pdn_bits = GENMASK(11, 8), + .sram_pdn_ack_bits = GENMASK(15, 12), + .clk_id = {CLK_HIFSEL}, + .bus_prot_mask = MT7622_TOP_AXI_PROT_EN_HIF0, + .active_wakeup = true, + }, + [MT7622_POWER_DOMAIN_HIF1] = { + .name = "hif1", + .sta_mask = PWR_STATUS_HIF1, + .ctl_offs = SPM_HIF1_PWR_CON, + .sram_pdn_bits = GENMASK(11, 8), + .sram_pdn_ack_bits = GENMASK(15, 12), + .clk_id = {CLK_HIFSEL}, + .bus_prot_mask = MT7622_TOP_AXI_PROT_EN_HIF1, + .active_wakeup = true, + }, + [MT7622_POWER_DOMAIN_WB] = { + .name = "wb", + .sta_mask = PWR_STATUS_WB, + .ctl_offs = SPM_WB_PWR_CON, + .sram_pdn_bits = 0, + .sram_pdn_ack_bits = 0, + .clk_id = {CLK_NONE}, + .bus_prot_mask = MT7622_TOP_AXI_PROT_EN_WB, + .active_wakeup = true, + }, +}; + /* * MT8173 power domain support */ @@ -771,6 +830,15 @@ static const struct scp_soc_data mt6797_data = { } }; +static const struct scp_soc_data mt7622_data = { + .domains = scp_domain_data_mt7622, + .num_domains = ARRAY_SIZE(scp_domain_data_mt7622), + .regs = { + .pwr_sta_offs = SPM_PWR_STATUS, + .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND + } +}; + static const struct scp_soc_data mt8173_data = { .domains = scp_domain_data_mt8173, .num_domains = ARRAY_SIZE(scp_domain_data_mt8173), @@ -793,6 +861,9 @@ static const struct of_device_id of_scpsys_match_tbl[] = { }, { .compatible = "mediatek,mt6797-scpsys", .data = &mt6797_data, + }, { + .compatible = "mediatek,mt7622-scpsys", + .data = &mt7622_data, }, { .compatible = "mediatek,mt8173-scpsys", .data = &mt8173_data, diff --git a/include/linux/soc/mediatek/infracfg.h b/include/linux/soc/mediatek/infracfg.h index a5714e93fb34..a0182ec2a621 100644 --- a/include/linux/soc/mediatek/infracfg.h +++ b/include/linux/soc/mediatek/infracfg.h @@ -20,6 +20,13 @@ #define MT8173_TOP_AXI_PROT_EN_MFG_M1 BIT(22) #define MT8173_TOP_AXI_PROT_EN_MFG_SNOOP_OUT BIT(23) +#define MT7622_TOP_AXI_PROT_EN_ETHSYS (BIT(3) | BIT(17)) +#define MT7622_TOP_AXI_PROT_EN_HIF0 (BIT(24) | BIT(25)) +#define MT7622_TOP_AXI_PROT_EN_HIF1 (BIT(26) | BIT(27) | \ + BIT(28)) +#define MT7622_TOP_AXI_PROT_EN_WB (BIT(2) | BIT(6) | \ + BIT(7) | BIT(8)) + int mtk_infracfg_set_bus_protection(struct regmap *infracfg, u32 mask); int mtk_infracfg_clear_bus_protection(struct regmap *infracfg, u32 mask); -- cgit v1.2.3-59-g8ed1b From 9deee319072286142ea23e9d3b0d789a216ffe20 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Tue, 18 Jul 2017 16:43:01 -0500 Subject: firmware: Convert to using %pOF instead of full_name Now that we have a custom printf format specifier, convert users of full_name to use %pOF instead. This is preparation to remove storing of the full path string for each node. Signed-off-by: Rob Herring Acked-by: Sudeep Holla Cc: Mark Rutland Cc: Lorenzo Pieralisi Cc: linux-arm-kernel@lists.infradead.org Signed-off-by: Arnd Bergmann --- drivers/firmware/arm_scpi.c | 2 +- drivers/firmware/psci.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/firmware/arm_scpi.c b/drivers/firmware/arm_scpi.c index 8043e51de897..59190c374696 100644 --- a/drivers/firmware/arm_scpi.c +++ b/drivers/firmware/arm_scpi.c @@ -965,7 +965,7 @@ static int scpi_probe(struct platform_device *pdev) count = of_count_phandle_with_args(np, "mboxes", "#mbox-cells"); if (count < 0) { - dev_err(dev, "no mboxes property in '%s'\n", np->full_name); + dev_err(dev, "no mboxes property in '%pOF'\n", np); return -ENODEV; } diff --git a/drivers/firmware/psci.c b/drivers/firmware/psci.c index 493a56a4cfc4..d687ca3d5049 100644 --- a/drivers/firmware/psci.c +++ b/drivers/firmware/psci.c @@ -280,8 +280,8 @@ static int psci_dt_cpu_init_idle(struct device_node *cpu_node, int cpu) "arm,psci-suspend-param", &state); if (ret) { - pr_warn(" * %s missing arm,psci-suspend-param property\n", - state_node->full_name); + pr_warn(" * %pOF missing arm,psci-suspend-param property\n", + state_node); of_node_put(state_node); goto free_mem; } -- cgit v1.2.3-59-g8ed1b From 9c0982d809fd81cc63438926c465e5919fd97acd Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Tue, 18 Jul 2017 16:42:51 -0500 Subject: bus: Convert to using %pOF instead of full_name Now that we have a custom printf format specifier, convert users of full_name to use %pOF instead. This is preparation to remove storing of the full path string for each node. Signed-off-by: Rob Herring Acked-by: Maxime Ripard Cc: Chen-Yu Tsai Cc: linux-arm-kernel@lists.infradead.org Signed-off-by: Arnd Bergmann --- drivers/bus/arm-cci.c | 12 ++++++------ drivers/bus/imx-weim.c | 8 ++++---- drivers/bus/sunxi-rsb.c | 22 +++++++++++----------- 3 files changed, 21 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/bus/arm-cci.c b/drivers/bus/arm-cci.c index c49da15d9790..3c29d36702a8 100644 --- a/drivers/bus/arm-cci.c +++ b/drivers/bus/arm-cci.c @@ -2124,8 +2124,8 @@ int notrace __cci_control_port_by_device(struct device_node *dn, bool enable) return -ENODEV; port = __cci_ace_get_port(dn, ACE_LITE_PORT); - if (WARN_ONCE(port < 0, "node %s ACE lite port look-up failure\n", - dn->full_name)) + if (WARN_ONCE(port < 0, "node %pOF ACE lite port look-up failure\n", + dn)) return -ENODEV; cci_port_control(port, enable); return 0; @@ -2200,14 +2200,14 @@ static int cci_probe_ports(struct device_node *np) if (of_property_read_string(cp, "interface-type", &match_str)) { - WARN(1, "node %s missing interface-type property\n", - cp->full_name); + WARN(1, "node %pOF missing interface-type property\n", + cp); continue; } is_ace = strcmp(match_str, "ace") == 0; if (!is_ace && strcmp(match_str, "ace-lite")) { - WARN(1, "node %s containing invalid interface-type property, skipping it\n", - cp->full_name); + WARN(1, "node %pOF containing invalid interface-type property, skipping it\n", + cp); continue; } diff --git a/drivers/bus/imx-weim.c b/drivers/bus/imx-weim.c index 4bd361d64270..3d56ebcda720 100644 --- a/drivers/bus/imx-weim.c +++ b/drivers/bus/imx-weim.c @@ -156,8 +156,8 @@ static int __init weim_parse_dt(struct platform_device *pdev, ret = weim_timing_setup(child, base, devtype); if (ret) - dev_warn(&pdev->dev, "%s set timing failed.\n", - child->full_name); + dev_warn(&pdev->dev, "%pOF set timing failed.\n", + child); else have_child = 1; } @@ -166,8 +166,8 @@ static int __init weim_parse_dt(struct platform_device *pdev, ret = of_platform_default_populate(pdev->dev.of_node, NULL, &pdev->dev); if (ret) - dev_err(&pdev->dev, "%s fail to create devices.\n", - pdev->dev.of_node->full_name); + dev_err(&pdev->dev, "%pOF fail to create devices.\n", + pdev->dev.of_node); return ret; } diff --git a/drivers/bus/sunxi-rsb.c b/drivers/bus/sunxi-rsb.c index 795c9d9c96a6..328ca93781cf 100644 --- a/drivers/bus/sunxi-rsb.c +++ b/drivers/bus/sunxi-rsb.c @@ -556,20 +556,20 @@ static int of_rsb_register_devices(struct sunxi_rsb *rsb) /* Runtime addresses for all slaves should be set first */ for_each_available_child_of_node(np, child) { - dev_dbg(dev, "setting child %s runtime address\n", - child->full_name); + dev_dbg(dev, "setting child %pOF runtime address\n", + child); ret = of_property_read_u32(child, "reg", &hwaddr); if (ret) { - dev_err(dev, "%s: invalid 'reg' property: %d\n", - child->full_name, ret); + dev_err(dev, "%pOF: invalid 'reg' property: %d\n", + child, ret); continue; } rtaddr = sunxi_rsb_get_rtaddr(hwaddr); if (!rtaddr) { - dev_err(dev, "%s: unknown hardware device address\n", - child->full_name); + dev_err(dev, "%pOF: unknown hardware device address\n", + child); continue; } @@ -586,15 +586,15 @@ static int of_rsb_register_devices(struct sunxi_rsb *rsb) /* send command */ ret = _sunxi_rsb_run_xfer(rsb); if (ret) - dev_warn(dev, "%s: set runtime address failed: %d\n", - child->full_name, ret); + dev_warn(dev, "%pOF: set runtime address failed: %d\n", + child, ret); } /* Then we start adding devices and probing them */ for_each_available_child_of_node(np, child) { struct sunxi_rsb_device *rdev; - dev_dbg(dev, "adding child %s\n", child->full_name); + dev_dbg(dev, "adding child %pOF\n", child); ret = of_property_read_u32(child, "reg", &hwaddr); if (ret) @@ -606,8 +606,8 @@ static int of_rsb_register_devices(struct sunxi_rsb *rsb) rdev = sunxi_rsb_device_create(rsb, child, hwaddr, rtaddr); if (IS_ERR(rdev)) - dev_err(dev, "failed to add child device %s: %ld\n", - child->full_name, PTR_ERR(rdev)); + dev_err(dev, "failed to add child device %pOF: %ld\n", + child, PTR_ERR(rdev)); } return 0; -- cgit v1.2.3-59-g8ed1b From 37c342cba5ef1ccb51f88a4aa5c1e74f793750c7 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Tue, 18 Jul 2017 16:43:29 -0500 Subject: soc: Convert to using %pOF instead of full_name Now that we have a custom printf format specifier, convert users of full_name to use %pOF instead. This is preparation to remove storing of the full path string for each node. Signed-off-by: Rob Herring Acked-by: Krzysztof Kozlowski Reviewed-by: Geert Uytterhoeven Acked-by: Matthias Brugger Acked-by: Simon Horman Cc: Scott Wood Cc: Qiang Zhao Cc: Magnus Damm Cc: Kukjin Kim Cc: Javier Martinez Canillas Signed-off-by: Arnd Bergmann --- drivers/soc/fsl/qbman/bman_ccsr.c | 10 +++++----- drivers/soc/fsl/qbman/bman_portal.c | 8 +++----- drivers/soc/fsl/qbman/qman_ccsr.c | 12 ++++++------ drivers/soc/fsl/qbman/qman_portal.c | 11 ++++------- drivers/soc/fsl/qe/gpio.c | 4 ++-- drivers/soc/mediatek/mtk-pmic-wrap.c | 4 ++-- drivers/soc/renesas/rcar-rst.c | 4 ++-- drivers/soc/renesas/rcar-sysc.c | 6 +++--- drivers/soc/samsung/pm_domains.c | 8 ++++---- 9 files changed, 31 insertions(+), 36 deletions(-) (limited to 'drivers') diff --git a/drivers/soc/fsl/qbman/bman_ccsr.c b/drivers/soc/fsl/qbman/bman_ccsr.c index a8e8389a6894..eaa9585c7347 100644 --- a/drivers/soc/fsl/qbman/bman_ccsr.c +++ b/drivers/soc/fsl/qbman/bman_ccsr.c @@ -177,8 +177,8 @@ static int fsl_bman_probe(struct platform_device *pdev) res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { - dev_err(dev, "Can't get %s property 'IORESOURCE_MEM'\n", - node->full_name); + dev_err(dev, "Can't get %pOF property 'IORESOURCE_MEM'\n", + node); return -ENXIO; } bm_ccsr_start = devm_ioremap(dev, res->start, resource_size(res)); @@ -205,14 +205,14 @@ static int fsl_bman_probe(struct platform_device *pdev) err_irq = platform_get_irq(pdev, 0); if (err_irq <= 0) { - dev_info(dev, "Can't get %s IRQ\n", node->full_name); + dev_info(dev, "Can't get %pOF IRQ\n", node); return -ENODEV; } ret = devm_request_irq(dev, err_irq, bman_isr, IRQF_SHARED, "bman-err", dev); if (ret) { - dev_err(dev, "devm_request_irq() failed %d for '%s'\n", - ret, node->full_name); + dev_err(dev, "devm_request_irq() failed %d for '%pOF'\n", + ret, node); return ret; } /* Disable Buffer Pool State Change */ diff --git a/drivers/soc/fsl/qbman/bman_portal.c b/drivers/soc/fsl/qbman/bman_portal.c index 8354d4dabdad..39b39c8f1399 100644 --- a/drivers/soc/fsl/qbman/bman_portal.c +++ b/drivers/soc/fsl/qbman/bman_portal.c @@ -103,16 +103,14 @@ static int bman_portal_probe(struct platform_device *pdev) addr_phys[0] = platform_get_resource(pdev, IORESOURCE_MEM, DPAA_PORTAL_CE); if (!addr_phys[0]) { - dev_err(dev, "Can't get %s property 'reg::CE'\n", - node->full_name); + dev_err(dev, "Can't get %pOF property 'reg::CE'\n", node); return -ENXIO; } addr_phys[1] = platform_get_resource(pdev, IORESOURCE_MEM, DPAA_PORTAL_CI); if (!addr_phys[1]) { - dev_err(dev, "Can't get %s property 'reg::CI'\n", - node->full_name); + dev_err(dev, "Can't get %pOF property 'reg::CI'\n", node); return -ENXIO; } @@ -120,7 +118,7 @@ static int bman_portal_probe(struct platform_device *pdev) irq = platform_get_irq(pdev, 0); if (irq <= 0) { - dev_err(dev, "Can't get %s IRQ'\n", node->full_name); + dev_err(dev, "Can't get %pOF IRQ'\n", node); return -ENXIO; } pcfg->irq = irq; diff --git a/drivers/soc/fsl/qbman/qman_ccsr.c b/drivers/soc/fsl/qbman/qman_ccsr.c index 90bc40c48675..835ce947ffca 100644 --- a/drivers/soc/fsl/qbman/qman_ccsr.c +++ b/drivers/soc/fsl/qbman/qman_ccsr.c @@ -695,8 +695,8 @@ static int fsl_qman_probe(struct platform_device *pdev) res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { - dev_err(dev, "Can't get %s property 'IORESOURCE_MEM'\n", - node->full_name); + dev_err(dev, "Can't get %pOF property 'IORESOURCE_MEM'\n", + node); return -ENXIO; } qm_ccsr_start = devm_ioremap(dev, res->start, resource_size(res)); @@ -740,15 +740,15 @@ static int fsl_qman_probe(struct platform_device *pdev) err_irq = platform_get_irq(pdev, 0); if (err_irq <= 0) { - dev_info(dev, "Can't get %s property 'interrupts'\n", - node->full_name); + dev_info(dev, "Can't get %pOF property 'interrupts'\n", + node); return -ENODEV; } ret = devm_request_irq(dev, err_irq, qman_isr, IRQF_SHARED, "qman-err", dev); if (ret) { - dev_err(dev, "devm_request_irq() failed %d for '%s'\n", - ret, node->full_name); + dev_err(dev, "devm_request_irq() failed %d for '%pOF'\n", + ret, node); return ret; } diff --git a/drivers/soc/fsl/qbman/qman_portal.c b/drivers/soc/fsl/qbman/qman_portal.c index adbaa30d3c5a..cbacdf4f98ed 100644 --- a/drivers/soc/fsl/qbman/qman_portal.c +++ b/drivers/soc/fsl/qbman/qman_portal.c @@ -237,30 +237,27 @@ static int qman_portal_probe(struct platform_device *pdev) addr_phys[0] = platform_get_resource(pdev, IORESOURCE_MEM, DPAA_PORTAL_CE); if (!addr_phys[0]) { - dev_err(dev, "Can't get %s property 'reg::CE'\n", - node->full_name); + dev_err(dev, "Can't get %pOF property 'reg::CE'\n", node); return -ENXIO; } addr_phys[1] = platform_get_resource(pdev, IORESOURCE_MEM, DPAA_PORTAL_CI); if (!addr_phys[1]) { - dev_err(dev, "Can't get %s property 'reg::CI'\n", - node->full_name); + dev_err(dev, "Can't get %pOF property 'reg::CI'\n", node); return -ENXIO; } err = of_property_read_u32(node, "cell-index", &val); if (err) { - dev_err(dev, "Can't get %s property 'cell-index'\n", - node->full_name); + dev_err(dev, "Can't get %pOF property 'cell-index'\n", node); return err; } pcfg->channel = val; pcfg->cpu = -1; irq = platform_get_irq(pdev, 0); if (irq <= 0) { - dev_err(dev, "Can't get %s IRQ\n", node->full_name); + dev_err(dev, "Can't get %pOF IRQ\n", node); return -ENXIO; } pcfg->irq = irq; diff --git a/drivers/soc/fsl/qe/gpio.c b/drivers/soc/fsl/qe/gpio.c index 0aaf429f31d5..3b27075c21a7 100644 --- a/drivers/soc/fsl/qe/gpio.c +++ b/drivers/soc/fsl/qe/gpio.c @@ -304,8 +304,8 @@ static int __init qe_add_gpiochips(void) goto err; continue; err: - pr_err("%s: registration failed with status %d\n", - np->full_name, ret); + pr_err("%pOF: registration failed with status %d\n", + np, ret); kfree(qe_gc); /* try others anyway */ } diff --git a/drivers/soc/mediatek/mtk-pmic-wrap.c b/drivers/soc/mediatek/mtk-pmic-wrap.c index c80a04e1b2b1..af9768db42b4 100644 --- a/drivers/soc/mediatek/mtk-pmic-wrap.c +++ b/drivers/soc/mediatek/mtk-pmic-wrap.c @@ -1233,8 +1233,8 @@ static int pwrap_probe(struct platform_device *pdev) ret = of_platform_populate(np, NULL, NULL, wrp->dev); if (ret) { - dev_dbg(wrp->dev, "failed to create child devices at %s\n", - np->full_name); + dev_dbg(wrp->dev, "failed to create child devices at %pOF\n", + np); goto err_out2; } diff --git a/drivers/soc/renesas/rcar-rst.c b/drivers/soc/renesas/rcar-rst.c index a6d1c26d3167..78c40d5dd62b 100644 --- a/drivers/soc/renesas/rcar-rst.c +++ b/drivers/soc/renesas/rcar-rst.c @@ -61,7 +61,7 @@ static int __init rcar_rst_init(void) base = of_iomap(np, 0); if (!base) { - pr_warn("%s: Cannot map regs\n", np->full_name); + pr_warn("%pOF: Cannot map regs\n", np); error = -ENOMEM; goto out_put; } @@ -70,7 +70,7 @@ static int __init rcar_rst_init(void) cfg = match->data; saved_mode = ioread32(base + cfg->modemr); - pr_debug("%s: MODE = 0x%08x\n", np->full_name, saved_mode); + pr_debug("%pOF: MODE = 0x%08x\n", np, saved_mode); out_put: of_node_put(np); diff --git a/drivers/soc/renesas/rcar-sysc.c b/drivers/soc/renesas/rcar-sysc.c index 7c8da3c90011..cd387347fa94 100644 --- a/drivers/soc/renesas/rcar-sysc.c +++ b/drivers/soc/renesas/rcar-sysc.c @@ -323,7 +323,7 @@ static int __init rcar_sysc_pd_init(void) base = of_iomap(np, 0); if (!base) { - pr_warn("%s: Cannot map regs\n", np->full_name); + pr_warn("%pOF: Cannot map regs\n", np); error = -ENOMEM; goto out_put; } @@ -348,13 +348,13 @@ static int __init rcar_sysc_pd_init(void) */ syscimr = ioread32(base + SYSCIMR); syscimr |= syscier; - pr_debug("%s: syscimr = 0x%08x\n", np->full_name, syscimr); + pr_debug("%pOF: syscimr = 0x%08x\n", np, syscimr); iowrite32(syscimr, base + SYSCIMR); /* * SYSC needs all interrupt sources enabled to control power. */ - pr_debug("%s: syscier = 0x%08x\n", np->full_name, syscier); + pr_debug("%pOF: syscier = 0x%08x\n", np, syscier); iowrite32(syscier, base + SYSCIER); for (i = 0; i < info->num_areas; i++) { diff --git a/drivers/soc/samsung/pm_domains.c b/drivers/soc/samsung/pm_domains.c index a6a5d807cc2b..c630eba32066 100644 --- a/drivers/soc/samsung/pm_domains.c +++ b/drivers/soc/samsung/pm_domains.c @@ -237,11 +237,11 @@ no_clk: continue; if (of_genpd_add_subdomain(&parent, &child)) - pr_warn("%s failed to add subdomain: %s\n", - parent.np->full_name, child.np->full_name); + pr_warn("%pOF failed to add subdomain: %pOF\n", + parent.np, child.np); else - pr_info("%s has as child subdomain: %s.\n", - parent.np->full_name, child.np->full_name); + pr_info("%pOF has as child subdomain: %pOF.\n", + parent.np, child.np); } return 0; -- cgit v1.2.3-59-g8ed1b From db749d17cb917c0506f62eb3006950e25acb737f Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Tue, 18 Jul 2017 16:43:14 -0500 Subject: memory: Convert to using %pOF instead of full_name Now that we have a custom printf format specifier, convert users of full_name to use %pOF instead. This is preparation to remove storing of the full path string for each node. Signed-off-by: Rob Herring Acked-by: Alexandre Belloni Acked-by: Roger Quadros Cc: Nicolas Ferre Cc: Alexandre Belloni Cc: Tony Lindgren Cc: linux-arm-kernel@lists.infradead.org Cc: linux-omap@vger.kernel.org Signed-off-by: Arnd Bergmann --- drivers/memory/atmel-ebi.c | 17 ++++++++--------- drivers/memory/jz4780-nemc.c | 12 ++++++------ drivers/memory/mvebu-devbus.c | 12 ++++++------ drivers/memory/omap-gpmc.c | 16 ++++++++-------- 4 files changed, 28 insertions(+), 29 deletions(-) (limited to 'drivers') diff --git a/drivers/memory/atmel-ebi.c b/drivers/memory/atmel-ebi.c index 99e644cda4d1..597282e35c69 100644 --- a/drivers/memory/atmel-ebi.c +++ b/drivers/memory/atmel-ebi.c @@ -156,8 +156,8 @@ static int atmel_ebi_xslate_smc_timings(struct atmel_ebi_dev *ebid, out: if (ret) { dev_err(ebid->ebi->dev, - "missing or invalid timings definition in %s", - np->full_name); + "missing or invalid timings definition in %pOF", + np); return ret; } @@ -267,8 +267,8 @@ static int atmel_ebi_xslate_smc_config(struct atmel_ebi_dev *ebid, return -EINVAL; if ((ret > 0 && !required) || (!ret && required)) { - dev_err(ebid->ebi->dev, "missing atmel,smc- properties in %s", - np->full_name); + dev_err(ebid->ebi->dev, "missing atmel,smc- properties in %pOF", + np); return -EINVAL; } @@ -311,8 +311,7 @@ static int atmel_ebi_dev_setup(struct atmel_ebi *ebi, struct device_node *np, if (cs >= AT91_MATRIX_EBI_NUM_CS || !(ebi->caps->available_cs & BIT(cs))) { - dev_err(dev, "invalid reg property in %s\n", - np->full_name); + dev_err(dev, "invalid reg property in %pOF\n", np); return -EINVAL; } @@ -321,7 +320,7 @@ static int atmel_ebi_dev_setup(struct atmel_ebi *ebi, struct device_node *np, } if (!numcs) { - dev_err(dev, "invalid reg property in %s\n", np->full_name); + dev_err(dev, "invalid reg property in %pOF\n", np); return -EINVAL; } @@ -569,8 +568,8 @@ static int atmel_ebi_probe(struct platform_device *pdev) ret = atmel_ebi_dev_setup(ebi, child, reg_cells); if (ret) { - dev_err(dev, "failed to configure EBI bus for %s, disabling the device", - child->full_name); + dev_err(dev, "failed to configure EBI bus for %pOF, disabling the device", + child); ret = atmel_ebi_dev_disable(ebi, child); if (ret) diff --git a/drivers/memory/jz4780-nemc.c b/drivers/memory/jz4780-nemc.c index 919d1925acb9..bcf06adefc96 100644 --- a/drivers/memory/jz4780-nemc.c +++ b/drivers/memory/jz4780-nemc.c @@ -322,8 +322,8 @@ static int jz4780_nemc_probe(struct platform_device *pdev) bank = of_read_number(prop, 1); if (bank < 1 || bank >= JZ4780_NEMC_NUM_BANKS) { dev_err(nemc->dev, - "%s requests invalid bank %u\n", - child->full_name, bank); + "%pOF requests invalid bank %u\n", + child, bank); /* Will continue the outer loop below. */ referenced = 0; @@ -334,12 +334,12 @@ static int jz4780_nemc_probe(struct platform_device *pdev) } if (!referenced) { - dev_err(nemc->dev, "%s has no addresses\n", - child->full_name); + dev_err(nemc->dev, "%pOF has no addresses\n", + child); continue; } else if (nemc->banks_present & referenced) { - dev_err(nemc->dev, "%s conflicts with another node\n", - child->full_name); + dev_err(nemc->dev, "%pOF conflicts with another node\n", + child); continue; } diff --git a/drivers/memory/mvebu-devbus.c b/drivers/memory/mvebu-devbus.c index 24852812fd44..981860879d02 100644 --- a/drivers/memory/mvebu-devbus.c +++ b/drivers/memory/mvebu-devbus.c @@ -105,8 +105,8 @@ static int get_timing_param_ps(struct devbus *devbus, err = of_property_read_u32(node, name, &time_ps); if (err < 0) { - dev_err(devbus->dev, "%s has no '%s' property\n", - name, node->full_name); + dev_err(devbus->dev, "%pOF has no '%s' property\n", + node, name); return err; } @@ -127,8 +127,8 @@ static int devbus_get_timing_params(struct devbus *devbus, err = of_property_read_u32(node, "devbus,bus-width", &r->bus_width); if (err < 0) { dev_err(devbus->dev, - "%s has no 'devbus,bus-width' property\n", - node->full_name); + "%pOF has no 'devbus,bus-width' property\n", + node); return err; } @@ -180,8 +180,8 @@ static int devbus_get_timing_params(struct devbus *devbus, &w->sync_enable); if (err < 0) { dev_err(devbus->dev, - "%s has no 'devbus,sync-enable' property\n", - node->full_name); + "%pOF has no 'devbus,sync-enable' property\n", + node); return err; } } diff --git a/drivers/memory/omap-gpmc.c b/drivers/memory/omap-gpmc.c index a80e17de906d..7059bbda2fac 100644 --- a/drivers/memory/omap-gpmc.c +++ b/drivers/memory/omap-gpmc.c @@ -1930,8 +1930,8 @@ static int gpmc_probe_onenand_child(struct platform_device *pdev, struct omap_onenand_platform_data *gpmc_onenand_data; if (of_property_read_u32(child, "reg", &val) < 0) { - dev_err(&pdev->dev, "%s has no 'reg' property\n", - child->full_name); + dev_err(&pdev->dev, "%pOF has no 'reg' property\n", + child); return -ENODEV; } @@ -1979,14 +1979,14 @@ static int gpmc_probe_generic_child(struct platform_device *pdev, struct gpmc_device *gpmc = platform_get_drvdata(pdev); if (of_property_read_u32(child, "reg", &cs) < 0) { - dev_err(&pdev->dev, "%s has no 'reg' property\n", - child->full_name); + dev_err(&pdev->dev, "%pOF has no 'reg' property\n", + child); return -ENODEV; } if (of_address_to_resource(child, 0, &res) < 0) { - dev_err(&pdev->dev, "%s has malformed 'reg' property\n", - child->full_name); + dev_err(&pdev->dev, "%pOF has malformed 'reg' property\n", + child); return -ENODEV; } @@ -2084,8 +2084,8 @@ static int gpmc_probe_generic_child(struct platform_device *pdev, ret = of_property_read_u32(child, "bank-width", &gpmc_s.device_width); if (ret < 0) { - dev_err(&pdev->dev, "%s has no 'bank-width' property\n", - child->full_name); + dev_err(&pdev->dev, "%pOF has no 'bank-width' property\n", + child); goto err; } } -- cgit v1.2.3-59-g8ed1b From 122954edfdf5888dbd532acf2b945af15660da66 Mon Sep 17 00:00:00 2001 From: Timo Alho Date: Thu, 17 Aug 2017 12:49:11 +0300 Subject: firmware: tegra: set drvdata earlier Subdevices of bpmp, such as bpmp-i2c, require the bpmp device's drvdata to be set during their probe. Currently this is not always the case. Fix this by calling platform_set_drvdata() earlier during bpmp's probe. Signed-off-by: Timo Alho Signed-off-by: Thierry Reding --- drivers/firmware/tegra/bpmp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/firmware/tegra/bpmp.c b/drivers/firmware/tegra/bpmp.c index b25179517cc5..73ca55b7b7ec 100644 --- a/drivers/firmware/tegra/bpmp.c +++ b/drivers/firmware/tegra/bpmp.c @@ -806,6 +806,8 @@ static int tegra_bpmp_probe(struct platform_device *pdev) dev_info(&pdev->dev, "firmware: %s\n", tag); + platform_set_drvdata(pdev, bpmp); + err = of_platform_default_populate(pdev->dev.of_node, NULL, &pdev->dev); if (err < 0) goto free_mrq; @@ -822,8 +824,6 @@ static int tegra_bpmp_probe(struct platform_device *pdev) if (err < 0) goto free_mrq; - platform_set_drvdata(pdev, bpmp); - return 0; free_mrq: -- cgit v1.2.3-59-g8ed1b From 27a0342ac162bf2ba30c288cfb7b72eabed38d8b Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Thu, 17 Aug 2017 16:42:17 +0200 Subject: soc/tegra: Register SoC device Move this code from arch/arm/mach-tegra and make it common among 32-bit and 64-bit Tegra SoCs. This is slightly complicated by the fact that on 32-bit Tegra, the SoC device is used as the parent for all devices that are instantiated from device tree. Signed-off-by: Thierry Reding --- arch/arm/mach-tegra/tegra.c | 29 +--------------------- drivers/soc/tegra/Kconfig | 5 ++++ drivers/soc/tegra/fuse/fuse-tegra.c | 48 +++++++++++++++++++++++++++++++++++-- include/soc/tegra/fuse.h | 2 ++ 4 files changed, 54 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/arch/arm/mach-tegra/tegra.c b/arch/arm/mach-tegra/tegra.c index 649e9e8c7bcc..02e712d2ea30 100644 --- a/arch/arm/mach-tegra/tegra.c +++ b/arch/arm/mach-tegra/tegra.c @@ -84,35 +84,8 @@ static void __init tegra_dt_init_irq(void) static void __init tegra_dt_init(void) { - struct soc_device_attribute *soc_dev_attr; - struct soc_device *soc_dev; - struct device *parent = NULL; + struct device *parent = tegra_soc_device_register(); - soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); - if (!soc_dev_attr) - goto out; - - soc_dev_attr->family = kasprintf(GFP_KERNEL, "Tegra"); - soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%d", - tegra_sku_info.revision); - soc_dev_attr->soc_id = kasprintf(GFP_KERNEL, "%u", tegra_get_chip_id()); - - soc_dev = soc_device_register(soc_dev_attr); - if (IS_ERR(soc_dev)) { - kfree(soc_dev_attr->family); - kfree(soc_dev_attr->revision); - kfree(soc_dev_attr->soc_id); - kfree(soc_dev_attr); - goto out; - } - - parent = soc_device_to_device(soc_dev); - - /* - * Finished with the static registrations now; fill in the missing - * devices - */ -out: of_platform_default_populate(NULL, NULL, parent); } diff --git a/drivers/soc/tegra/Kconfig b/drivers/soc/tegra/Kconfig index 1beb7c347344..e9e277178c94 100644 --- a/drivers/soc/tegra/Kconfig +++ b/drivers/soc/tegra/Kconfig @@ -107,6 +107,11 @@ config ARCH_TEGRA_186_SOC endif endif +config SOC_TEGRA_FUSE + def_bool y + depends on ARCH_TEGRA + select SOC_BUS + config SOC_TEGRA_FLOWCTRL bool diff --git a/drivers/soc/tegra/fuse/fuse-tegra.c b/drivers/soc/tegra/fuse/fuse-tegra.c index 7413f60fa855..e4f78de8f95f 100644 --- a/drivers/soc/tegra/fuse/fuse-tegra.c +++ b/drivers/soc/tegra/fuse/fuse-tegra.c @@ -19,10 +19,12 @@ #include #include #include -#include +#include #include #include -#include +#include +#include +#include #include #include @@ -210,6 +212,31 @@ static void tegra_enable_fuse_clk(void __iomem *base) writel(reg, base + 0x14); } +struct device * __init tegra_soc_device_register(void) +{ + struct soc_device_attribute *attr; + struct soc_device *dev; + + attr = kzalloc(sizeof(*attr), GFP_KERNEL); + if (!attr) + return NULL; + + attr->family = kasprintf(GFP_KERNEL, "Tegra"); + attr->revision = kasprintf(GFP_KERNEL, "%d", tegra_sku_info.revision); + attr->soc_id = kasprintf(GFP_KERNEL, "%u", tegra_get_chip_id()); + + dev = soc_device_register(attr); + if (IS_ERR(dev)) { + kfree(attr->soc_id); + kfree(attr->revision); + kfree(attr->family); + kfree(attr); + return ERR_CAST(dev); + } + + return soc_device_to_device(dev); +} + static int __init tegra_init_fuse(void) { const struct of_device_id *match; @@ -311,6 +338,23 @@ static int __init tegra_init_fuse(void) pr_debug("Tegra CPU Speedo ID %d, SoC Speedo ID %d\n", tegra_sku_info.cpu_speedo_id, tegra_sku_info.soc_speedo_id); + return 0; } early_initcall(tegra_init_fuse); + +#ifdef CONFIG_ARM64 +static int __init tegra_init_soc(void) +{ + struct device *soc; + + soc = tegra_soc_device_register(); + if (IS_ERR(soc)) { + pr_err("failed to register SoC device: %ld\n", PTR_ERR(soc)); + return PTR_ERR(soc); + } + + return 0; +} +device_initcall(tegra_init_soc) +#endif diff --git a/include/soc/tegra/fuse.h b/include/soc/tegra/fuse.h index b4c9219e7f95..9b6ea0c72117 100644 --- a/include/soc/tegra/fuse.h +++ b/include/soc/tegra/fuse.h @@ -65,6 +65,8 @@ int tegra_fuse_readl(unsigned long offset, u32 *value); extern struct tegra_sku_info tegra_sku_info; +struct device *tegra_soc_device_register(void); + #endif /* __ASSEMBLY__ */ #endif /* __SOC_TEGRA_FUSE_H__ */ -- cgit v1.2.3-59-g8ed1b From dc1a37b2b9eda3b9847f39c18b3d443dad64d54c Mon Sep 17 00:00:00 2001 From: Jagan Teki Date: Sat, 12 Aug 2017 11:10:41 +0530 Subject: bus: sunxi-rsb: Enable by default for ARM64 Allwinner's A64 SoC uses the "Reduced Serial Bus" to communicate with its companion PMIC. Since arm64 does not have separate defconfigs for each platform or processor family, enable this driver by default for ARM64 as well. Note that the Kconfig symbol already depends on ARCH_SUNXI. Signed-off-by: Jagan Teki [wens@csie.org: Refined commit message] Signed-off-by: Chen-Yu Tsai --- drivers/bus/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig index 2408ea38a39c..ae3d8f3444b9 100644 --- a/drivers/bus/Kconfig +++ b/drivers/bus/Kconfig @@ -132,7 +132,7 @@ config SIMPLE_PM_BUS config SUNXI_RSB tristate "Allwinner sunXi Reduced Serial Bus Driver" - default MACH_SUN8I || MACH_SUN9I + default MACH_SUN8I || MACH_SUN9I || ARM64 depends on ARCH_SUNXI select REGMAP help -- cgit v1.2.3-59-g8ed1b From 2262a65f0bcdfe372b088d20c325c1987cec4332 Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Wed, 9 Aug 2017 16:56:25 +0800 Subject: drivers: soc: sunxi: fix error processing on base address when claiming When claiming SRAM, if the base is set to an error, it means that the SRAM controller has been probed, but failed to remap the controller memory zone. If the base is zero, thus the SRAM controller should be not probed at all, and it should return -EPROBE_DEFER. However, currently we returned -EPROBE_DEFER in the former situation, and ignored the latter situation (which will lead to the kernel to panic). Fix the behavior on abnormal base address processing when claiming. Signed-off-by: Icenowy Zheng Fixes: 4af34b572a85 ("drivers: soc: sunxi: Introduce SoC driver to map SRAMs") Signed-off-by: Chen-Yu Tsai --- drivers/soc/sunxi/sunxi_sram.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/soc/sunxi/sunxi_sram.c b/drivers/soc/sunxi/sunxi_sram.c index 99e354c8f53f..c1ff7fa62cb4 100644 --- a/drivers/soc/sunxi/sunxi_sram.c +++ b/drivers/soc/sunxi/sunxi_sram.c @@ -190,6 +190,9 @@ int sunxi_sram_claim(struct device *dev) u32 val, mask; if (IS_ERR(base)) + return PTR_ERR(base); + + if (!base) return -EPROBE_DEFER; if (!dev || !dev->of_node) -- cgit v1.2.3-59-g8ed1b From 8fed2ce98eec31f33fd4df96c584525dcae4d9be Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Wed, 9 Aug 2017 16:56:26 +0800 Subject: drivers: soc: sunxi: add support for remapping func value to reg value On some Allwinner SoCs, sometimes the value needed to write into the register to claim SRAM is not equal to the value specified in the device tree. The device tree binding defines 0 as "mapped to CPU" and 1 as "mapped to X device". This matches the value written to the configuration register for the SRAM blocks currently supported. However, the not yet supported VE SRAM block is claimed for the device by writing 0x7fffffff, which is vastly different from the other blocks. On the A64, SRAM C is claimed by the device by writing a 0, which is the opposite of the current design. Add a value remapping in sunxi_sram_func structure, and let the sunxi_sram_of_parse function set the remapped register value. This allows us to keep the convention currently used in the device tree binding. Signed-off-by: Icenowy Zheng [wens@csie.org: Clarified commit message] Signed-off-by: Chen-Yu Tsai --- drivers/soc/sunxi/sunxi_sram.c | 43 +++++++++++++++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/soc/sunxi/sunxi_sram.c b/drivers/soc/sunxi/sunxi_sram.c index c1ff7fa62cb4..edc993480020 100644 --- a/drivers/soc/sunxi/sunxi_sram.c +++ b/drivers/soc/sunxi/sunxi_sram.c @@ -23,6 +23,7 @@ struct sunxi_sram_func { char *func; u8 val; + u32 reg_val; }; struct sunxi_sram_data { @@ -39,10 +40,11 @@ struct sunxi_sram_desc { bool claimed; }; -#define SUNXI_SRAM_MAP(_val, _func) \ +#define SUNXI_SRAM_MAP(_reg_val, _val, _func) \ { \ .func = _func, \ .val = _val, \ + .reg_val = _reg_val, \ } #define SUNXI_SRAM_DATA(_name, _reg, _off, _width, ...) \ @@ -57,14 +59,14 @@ struct sunxi_sram_desc { static struct sunxi_sram_desc sun4i_a10_sram_a3_a4 = { .data = SUNXI_SRAM_DATA("A3-A4", 0x4, 0x4, 2, - SUNXI_SRAM_MAP(0, "cpu"), - SUNXI_SRAM_MAP(1, "emac")), + SUNXI_SRAM_MAP(0, 0, "cpu"), + SUNXI_SRAM_MAP(1, 1, "emac")), }; static struct sunxi_sram_desc sun4i_a10_sram_d = { .data = SUNXI_SRAM_DATA("D", 0x4, 0x0, 1, - SUNXI_SRAM_MAP(0, "cpu"), - SUNXI_SRAM_MAP(1, "usb-otg")), + SUNXI_SRAM_MAP(0, 0, "cpu"), + SUNXI_SRAM_MAP(1, 1, "usb-otg")), }; static const struct of_device_id sunxi_sram_dt_ids[] = { @@ -121,7 +123,8 @@ static int sunxi_sram_show(struct seq_file *s, void *data) for (func = sram_data->func; func->func; func++) { seq_printf(s, "\t\t%s%c\n", func->func, - func->val == val ? '*' : ' '); + func->reg_val == val ? + '*' : ' '); } } @@ -149,10 +152,13 @@ static inline struct sunxi_sram_desc *to_sram_desc(const struct sunxi_sram_data } static const struct sunxi_sram_data *sunxi_sram_of_parse(struct device_node *node, - unsigned int *value) + unsigned int *reg_value) { const struct of_device_id *match; + const struct sunxi_sram_data *data; + struct sunxi_sram_func *func; struct of_phandle_args args; + u8 val; int ret; ret = of_parse_phandle_with_fixed_args(node, "allwinner,sram", 1, 0, @@ -165,8 +171,7 @@ static const struct sunxi_sram_data *sunxi_sram_of_parse(struct device_node *nod goto err; } - if (value) - *value = args.args[0]; + val = args.args[0]; match = of_match_node(sunxi_sram_dt_ids, args.np); if (!match) { @@ -174,6 +179,26 @@ static const struct sunxi_sram_data *sunxi_sram_of_parse(struct device_node *nod goto err; } + data = match->data; + if (!data) { + ret = -EINVAL; + goto err; + }; + + for (func = data->func; func->func; func++) { + if (val == func->val) { + if (reg_value) + *reg_value = func->reg_val; + + break; + } + } + + if (!func->func) { + ret = -EINVAL; + goto err; + } + of_node_put(args.np); return match->data; -- cgit v1.2.3-59-g8ed1b From 5e4fb6429761ebe8f5acb5a761fa57d02a91ac6f Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Wed, 9 Aug 2017 16:56:27 +0800 Subject: drivers: soc: sunxi: add support for A64 and its SRAM C Allwinner A64's display engine claims the SRAM C section to work. Add support for the A64 SRAM controller and the SRAM C section of it. Signed-off-by: Icenowy Zheng Signed-off-by: Chen-Yu Tsai --- drivers/soc/sunxi/sunxi_sram.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'drivers') diff --git a/drivers/soc/sunxi/sunxi_sram.c b/drivers/soc/sunxi/sunxi_sram.c index edc993480020..882be5ed7e84 100644 --- a/drivers/soc/sunxi/sunxi_sram.c +++ b/drivers/soc/sunxi/sunxi_sram.c @@ -69,6 +69,12 @@ static struct sunxi_sram_desc sun4i_a10_sram_d = { SUNXI_SRAM_MAP(1, 1, "usb-otg")), }; +static struct sunxi_sram_desc sun50i_a64_sram_c = { + .data = SUNXI_SRAM_DATA("C", 0x4, 24, 1, + SUNXI_SRAM_MAP(0, 1, "cpu"), + SUNXI_SRAM_MAP(1, 0, "de2")), +}; + static const struct of_device_id sunxi_sram_dt_ids[] = { { .compatible = "allwinner,sun4i-a10-sram-a3-a4", @@ -78,6 +84,10 @@ static const struct of_device_id sunxi_sram_dt_ids[] = { .compatible = "allwinner,sun4i-a10-sram-d", .data = &sun4i_a10_sram_d.data, }, + { + .compatible = "allwinner,sun50i-a64-sram-c", + .data = &sun50i_a64_sram_c.data, + }, {} }; @@ -295,6 +305,7 @@ static int sunxi_sram_probe(struct platform_device *pdev) static const struct of_device_id sunxi_sram_dt_match[] = { { .compatible = "allwinner,sun4i-a10-sram-controller" }, + { .compatible = "allwinner,sun50i-a64-sram-controller" }, { }, }; MODULE_DEVICE_TABLE(of, sunxi_sram_dt_match); -- cgit v1.2.3-59-g8ed1b From 226cff485c803ac0f3a6bc52b9b638eb2c41181c Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Wed, 23 Aug 2017 11:25:08 +0200 Subject: soc/tegra: Restrict SoC device registration to Tegra Commit 8a46828e623c ("soc/tegra: Register SoC device") added an initcall to register the SoC device on Tegra. However, that code is unrestricted and will run on all platforms, causing unwanted warnings. Fix this by first checking that we're running on hardware that supports the fuses block that we use to provide SoC information. Fixes: 8a46828e623c ("soc/tegra: Register SoC device") Reported-by: Sudeep Holla Tested-by: Sudeep Holla Signed-off-by: Thierry Reding Signed-off-by: Arnd Bergmann --- drivers/soc/tegra/fuse/fuse-tegra.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/soc/tegra/fuse/fuse-tegra.c b/drivers/soc/tegra/fuse/fuse-tegra.c index e4f78de8f95f..be003d04383f 100644 --- a/drivers/soc/tegra/fuse/fuse-tegra.c +++ b/drivers/soc/tegra/fuse/fuse-tegra.c @@ -346,8 +346,16 @@ early_initcall(tegra_init_fuse); #ifdef CONFIG_ARM64 static int __init tegra_init_soc(void) { + struct device_node *np; struct device *soc; + /* make sure we're running on Tegra */ + np = of_find_matching_node(NULL, tegra_fuse_match); + if (!np) + return 0; + + of_node_put(np); + soc = tegra_soc_device_register(); if (IS_ERR(soc)) { pr_err("failed to register SoC device: %ld\n", PTR_ERR(soc)); -- cgit v1.2.3-59-g8ed1b From 9261b43e70b79106deca8f734a5217134ce68f3d Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Wed, 23 Aug 2017 11:25:09 +0200 Subject: soc/tegra: fuse: Add missing semi-colon Commit 8a46828e623c ("soc/tegra: Register SoC device") added a new initcall, but forgot to terminate the line with a semi-colon. Some recent versions of GCC seem to report this as an error. Fixes: 8a46828e623c ("soc/tegra: Register SoC device") Reported-by: Arnd Bergmann Signed-off-by: Thierry Reding Signed-off-by: Arnd Bergmann --- drivers/soc/tegra/fuse/fuse-tegra.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/soc/tegra/fuse/fuse-tegra.c b/drivers/soc/tegra/fuse/fuse-tegra.c index be003d04383f..b7c552e3133c 100644 --- a/drivers/soc/tegra/fuse/fuse-tegra.c +++ b/drivers/soc/tegra/fuse/fuse-tegra.c @@ -364,5 +364,5 @@ static int __init tegra_init_soc(void) return 0; } -device_initcall(tegra_init_soc) +device_initcall(tegra_init_soc); #endif -- cgit v1.2.3-59-g8ed1b From 0d30176819c8738b012ec623c7b3db19df818e70 Mon Sep 17 00:00:00 2001 From: Sudeep Holla Date: Fri, 18 Aug 2017 15:39:28 +0100 Subject: firmware: arm_scpi: fix endianness of dev_id in struct dev_pstate_set scpi_device_{g,s}et_power_state correctly handles the conversion of endianness for dev_id using cpu_to_le16. However dev_id is declared as u16 in struct dev_pstate_set which is incorrect. This patch fixes the endianness of dev_id in dev_pstate_set structure. Fixes: 37a441dcd5f4 ("firmware: arm_scpi: add support for device power state management") Signed-off-by: Sudeep Holla --- drivers/firmware/arm_scpi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/firmware/arm_scpi.c b/drivers/firmware/arm_scpi.c index 8043e51de897..ab52f1bcd277 100644 --- a/drivers/firmware/arm_scpi.c +++ b/drivers/firmware/arm_scpi.c @@ -357,7 +357,7 @@ struct sensor_value { } __packed; struct dev_pstate_set { - u16 dev_id; + __le16 dev_id; u8 pstate; } __packed; -- cgit v1.2.3-59-g8ed1b