diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-09-10 20:40:00 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-09-10 20:40:00 -0700 |
commit | ae46654bcff303b33facbbd04a3ad9c21d303f9b (patch) | |
tree | b0027d47d6c949162fa6ae306f34abeb76c559a9 /drivers | |
parent | 7f1b9be13a7dbe8e51ea541bbcd6c47adae39c71 (diff) | |
parent | a48a7b6b54927159bac77735df00e5b9fc3415fb (diff) |
Merge tag 'armsoc-drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull ARM SoC driver updates from Olof Johansson:
"This branch contains platform-related driver updates for ARM and ARM64.
Among them:
- Reset driver updates:
+ New API for dealing with arrays of resets
+ Make unimplemented {de,}assert return success on shared resets
+ MSDKv1 driver
+ Removal of obsolete Gemini reset driver
+ Misc updates for sunxi and Uniphier
- SoC drivers:
+ Platform SoC driver registration on Tegra
+ Shuffle of Qualcomm drivers into a submenu
+ Allwinner A64 support for SRAM
+ Renesas R-Car R3 support
+ Power domains for Rockchip RK3366
- Misc updates and smaller fixes for TEE and memory driver
subsystems"
* tag 'armsoc-drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (54 commits)
firmware: arm_scpi: fix endianness of dev_id in struct dev_pstate_set
soc/tegra: fuse: Add missing semi-colon
soc/tegra: Restrict SoC device registration to Tegra
drivers: soc: sunxi: add support for A64 and its SRAM C
drivers: soc: sunxi: add support for remapping func value to reg value
drivers: soc: sunxi: fix error processing on base address when claiming
dt-bindings: add binding for Allwinner A64 SRAM controller and SRAM C
bus: sunxi-rsb: Enable by default for ARM64
soc/tegra: Register SoC device
firmware: tegra: set drvdata earlier
memory: Convert to using %pOF instead of full_name
soc: Convert to using %pOF instead of full_name
bus: Convert to using %pOF instead of full_name
firmware: Convert to using %pOF instead of full_name
soc: mediatek: add SCPSYS power domain driver for MediaTek MT7622 SoC
soc: mediatek: add header files required for MT7622 SCPSYS dt-binding
soc: mediatek: reduce code duplication of scpsys_probe across all SoCs
dt-bindings: soc: update the binding document for SCPSYS on MediaTek MT7622 SoC
reset: uniphier: add analog amplifiers reset control
reset: uniphier: add video input subsystem reset control
...
Diffstat (limited to 'drivers')
54 files changed, 1102 insertions, 430 deletions
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 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; diff --git a/drivers/firmware/arm_scpi.c b/drivers/firmware/arm_scpi.c index 8043e51de897..7da9f1b83ebe 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; @@ -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; } 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: diff --git a/drivers/memory/atmel-ebi.c b/drivers/memory/atmel-ebi.c index c00a7c7f460a..b907865d4664 100644 --- a/drivers/memory/atmel-ebi.c +++ b/drivers/memory/atmel-ebi.c @@ -159,8 +159,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; } @@ -270,8 +270,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; } @@ -314,8 +314,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; } @@ -324,7 +323,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; } @@ -576,8 +575,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; } } diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index 608c071e4bbf..52d5251660b9 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -34,12 +34,11 @@ 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 +config RESET_HSDK_V1 + bool "HSDK v1 Reset Driver" + default n help - This enables the reset controller driver for Cortina Systems Gemini. + This enables the reset controller driver for HSDK v1. config RESET_IMX7 bool "i.MX7 Reset Driver" if COMPILE_TEST diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile index 7081f9da2599..b62783f50fe5 100644 --- a/drivers/reset/Makefile +++ b/drivers/reset/Makefile @@ -5,7 +5,7 @@ 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 obj-$(CONFIG_RESET_MESON) += reset-meson.o diff --git a/drivers/reset/core.c b/drivers/reset/core.c index 0090784ff410..1d21c6f7d56c 100644 --- a/drivers/reset/core.c +++ b/drivers/reset/core.c @@ -43,11 +43,24 @@ 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 * @reset_spec: reset line specifier as found in the device tree @@ -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,8 +277,8 @@ int reset_control_assert(struct reset_control *rstc) if (WARN_ON(IS_ERR(rstc))) return -EINVAL; - if (!rstc->rcdev->ops->assert) - return -ENOTSUPP; + if (reset_control_is_array(rstc)) + return reset_control_array_assert(rstc_to_array(rstc)); if (rstc->shared) { if (WARN_ON(atomic_read(&rstc->triggered_count) != 0)) @@ -214,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); @@ -240,8 +330,8 @@ int reset_control_deassert(struct reset_control *rstc) if (WARN_ON(IS_ERR(rstc))) return -EINVAL; - if (!rstc->rcdev->ops->deassert) - return -ENOTSUPP; + if (reset_control_is_array(rstc)) + return reset_control_array_deassert(rstc_to_array(rstc)); if (rstc->shared) { if (WARN_ON(atomic_read(&rstc->triggered_count) != 0)) @@ -251,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); @@ -266,7 +366,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 +504,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 +523,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 +587,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 |