diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2021-11-03 17:00:52 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2021-11-03 17:00:52 -0700 |
| commit | d461e96cd22b5aeb1df448536b92e8d8e88c4a05 (patch) | |
| tree | ffd7a4ddc858c79a9a30952bedf14652ac10a2e4 /drivers | |
| parent | ae45d84fc36d01dcb1007f4298871eec37907904 (diff) | |
| parent | 6a03568932b2711c91e1572f08867690b52a18df (diff) | |
| download | linux-d461e96cd22b5aeb1df448536b92e8d8e88c4a05.tar.gz linux-d461e96cd22b5aeb1df448536b92e8d8e88c4a05.tar.bz2 linux-d461e96cd22b5aeb1df448536b92e8d8e88c4a05.zip | |
Merge tag 'drivers-5.16' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc
Pull ARM SoC driver updates from Arnd Bergmann:
"These are all the driver updates for SoC specific drivers. There are a
couple of subsystems with individual maintainers picking up their
patches here:
- The reset controller subsystem add support for a few new SoC
variants to existing drivers, along with other minor improvements
- The OP-TEE subsystem gets a driver for the ARM FF-A transport
- The memory controller subsystem has improvements for Tegra,
Mediatek, Renesas, Freescale and Broadcom specific drivers.
- The tegra cpuidle driver changes get merged through this tree this
time. There are only minor changes, but they depend on other tegra
driver updates here.
- The ep93xx platform finally moves to using the drivers/clk/
subsystem, moving the code out of arch/arm in the process. This
depends on a small sound driver change that is included here as
well.
- There are some minor updates for Qualcomm and Tegra specific
firmware drivers.
The other driver updates are mainly for drivers/soc, which contains a
mixture of vendor specific drivers that don't really fit elsewhere:
- Mediatek drivers gain more support for MT8192, with new support for
hw-mutex and mmsys routing, plus support for reset lines in the
mmsys driver.
- Qualcomm gains a new "sleep stats" driver, and support for the
"Generic Packet Router" in the APR driver.
- There is a new user interface for routing the UARTS on ASpeed BMCs,
something that apparently nobody else has needed so far.
- More drivers can now be built as loadable modules, in particular
for Broadcom and Samsung platforms.
- Lots of improvements to the TI sysc driver for better
suspend/resume support"
Finally, there are lots of minor cleanups and new device IDs for
amlogic, renesas, tegra, qualcomm, mediateka, samsung, imx,
layerscape, allwinner, broadcom, and omap"
* tag 'drivers-5.16' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc: (179 commits)
optee: Fix spelling mistake "reclain" -> "reclaim"
Revert "firmware: qcom: scm: Add support for MC boot address API"
qcom: spm: allow compile-testing
firmware: arm_ffa: Remove unused 'compat_version' variable
soc: samsung: exynos-chipid: add exynosautov9 SoC support
firmware: qcom: scm: Don't break compile test on non-ARM platforms
soc: qcom: smp2p: Add of_node_put() before goto
soc: qcom: apr: Add of_node_put() before return
soc: qcom: qcom_stats: Fix client votes offset
soc: qcom: rpmhpd: fix sm8350_mxc's peer domain
dt-bindings: arm: cpus: Document qcom,msm8916-smp enable-method
ARM: qcom: Add qcom,msm8916-smp enable-method identical to MSM8226
firmware: qcom: scm: Add support for MC boot address API
soc: qcom: spm: Add 8916 SPM register data
dt-bindings: soc: qcom: spm: Document qcom,msm8916-saw2-v3.0-cpu
soc: qcom: socinfo: Add PM8150C and SMB2351 models
firmware: qcom_scm: Fix error retval in __qcom_scm_is_call_available()
soc: aspeed: Add UART routing support
soc: fsl: dpio: rename the enqueue descriptor variable
soc: fsl: dpio: use an explicit NULL instead of 0
...
Diffstat (limited to 'drivers')
96 files changed, 6617 insertions, 2355 deletions
diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig index a4cf3d692dc3..3c68e174a113 100644 --- a/drivers/bus/Kconfig +++ b/drivers/bus/Kconfig @@ -30,7 +30,7 @@ config ARM_INTEGRATOR_LM found on the ARM Integrator AP (Application Platform) config BRCMSTB_GISB_ARB - bool "Broadcom STB GISB bus arbiter" + tristate "Broadcom STB GISB bus arbiter" depends on ARM || ARM64 || MIPS default ARCH_BRCMSTB || BMIPS_GENERIC help diff --git a/drivers/bus/brcmstb_gisb.c b/drivers/bus/brcmstb_gisb.c index 6551286a60cc..4c2f7d61cb9b 100644 --- a/drivers/bus/brcmstb_gisb.c +++ b/drivers/bus/brcmstb_gisb.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (C) 2014-2017 Broadcom + * Copyright (C) 2014-2021 Broadcom */ #include <linux/init.h> @@ -536,6 +536,7 @@ static struct platform_driver brcmstb_gisb_arb_driver = { .name = "brcm-gisb-arb", .of_match_table = brcmstb_gisb_arb_of_match, .pm = &brcmstb_gisb_arb_pm_ops, + .suppress_bind_attrs = true, }, }; @@ -546,3 +547,7 @@ static int __init brcm_gisb_driver_init(void) } module_init(brcm_gisb_driver_init); + +MODULE_AUTHOR("Broadcom"); +MODULE_DESCRIPTION("Broadcom STB GISB arbiter driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/bus/sun50i-de2.c b/drivers/bus/sun50i-de2.c index 672518741f86..414f29cdedf0 100644 --- a/drivers/bus/sun50i-de2.c +++ b/drivers/bus/sun50i-de2.c @@ -15,10 +15,9 @@ static int sun50i_de2_bus_probe(struct platform_device *pdev) int ret; ret = sunxi_sram_claim(&pdev->dev); - if (ret) { - dev_err(&pdev->dev, "Error couldn't map SRAM to device\n"); - return ret; - } + if (ret) + return dev_err_probe(&pdev->dev, ret, + "Couldn't map SRAM to device\n"); of_platform_populate(np, NULL, NULL, &pdev->dev); diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c index 6a8b7fb5be58..54c0ee6dda30 100644 --- a/drivers/bus/ti-sysc.c +++ b/drivers/bus/ti-sysc.c @@ -6,6 +6,7 @@ #include <linux/io.h> #include <linux/clk.h> #include <linux/clkdev.h> +#include <linux/cpu_pm.h> #include <linux/delay.h> #include <linux/list.h> #include <linux/module.h> @@ -17,6 +18,7 @@ #include <linux/of_platform.h> #include <linux/slab.h> #include <linux/sys_soc.h> +#include <linux/timekeeping.h> #include <linux/iopoll.h> #include <linux/platform_data/ti-sysc.h> @@ -51,11 +53,18 @@ struct sysc_address { struct list_head node; }; +struct sysc_module { + struct sysc *ddata; + struct list_head node; +}; + struct sysc_soc_info { unsigned long general_purpose:1; enum sysc_soc soc; - struct mutex list_lock; /* disabled modules list lock */ + struct mutex list_lock; /* disabled and restored modules list lock */ struct list_head disabled_modules; + struct list_head restored_modules; + struct notifier_block nb; }; enum sysc_clocks { @@ -131,6 +140,7 @@ struct sysc { struct ti_sysc_cookie cookie; const char *name; u32 revision; + u32 sysconfig; unsigned int reserved:1; unsigned int enabled:1; unsigned int needs_resume:1; @@ -147,6 +157,7 @@ struct sysc { static void sysc_parse_dts_quirks(struct sysc *ddata, struct device_node *np, bool is_child); +static int sysc_reset(struct sysc *ddata); static void sysc_write(struct sysc *ddata, int offset, u32 value) { @@ -223,37 +234,77 @@ static u32 sysc_read_sysstatus(struct sysc *ddata) return sysc_read(ddata, offset); } -/* Poll on reset status */ -static int sysc_wait_softreset(struct sysc *ddata) +static int sysc_poll_reset_sysstatus(struct sysc *ddata) { - u32 sysc_mask, syss_done, rstval; - int syss_offset, error = 0; - - if (ddata->cap->regbits->srst_shift < 0) - return 0; - - syss_offset = ddata->offsets[SYSC_SYSSTATUS]; - sysc_mask = BIT(ddata->cap->regbits->srst_shift); + int error, retries; + u32 syss_done, rstval; if (ddata->cfg.quirks & SYSS_QUIRK_RESETDONE_INVERTED) syss_done = 0; else syss_done = ddata->cfg.syss_mask; - if (syss_offset >= 0) { + if (likely(!timekeeping_suspended)) { error = readx_poll_timeout_atomic(sysc_read_sysstatus, ddata, rstval, (rstval & ddata->cfg.syss_mask) == syss_done, 100, MAX_MODULE_SOFTRESET_WAIT); + } else { + retries = MAX_MODULE_SOFTRESET_WAIT; + while (retries--) { + rstval = sysc_read_sysstatus(ddata); + if ((rstval & ddata->cfg.syss_mask) == syss_done) + return 0; + udelay(2); /* Account for udelay flakeyness */ + } + error = -ETIMEDOUT; + } + + return error; +} + +static int sysc_poll_reset_sysconfig(struct sysc *ddata) +{ + int error, retries; + u32 sysc_mask, rstval; + + sysc_mask = BIT(ddata->cap->regbits->srst_shift); - } else if (ddata->cfg.quirks & SYSC_QUIRK_RESET_STATUS) { + if (likely(!timekeeping_suspended)) { error = readx_poll_timeout_atomic(sysc_read_sysconfig, ddata, rstval, !(rstval & sysc_mask), 100, MAX_MODULE_SOFTRESET_WAIT); + } else { + retries = MAX_MODULE_SOFTRESET_WAIT; + while (retries--) { + rstval = sysc_read_sysconfig(ddata); + if (!(rstval & sysc_mask)) + return 0; + udelay(2); /* Account for udelay flakeyness */ + } + error = -ETIMEDOUT; } return error; } +/* Poll on reset status */ +static int sysc_wait_softreset(struct sysc *ddata) +{ + int syss_offset, error = 0; + + if (ddata->cap->regbits->srst_shift < 0) + return 0; + + syss_offset = ddata->offsets[SYSC_SYSSTATUS]; + + if (syss_offset >= 0) + error = sysc_poll_reset_sysstatus(ddata); + else if (ddata->cfg.quirks & SYSC_QUIRK_RESET_STATUS) + error = sysc_poll_reset_sysconfig(ddata); + + return error; +} + static int sysc_add_named_clock_from_child(struct sysc *ddata, const char *name, const char *optfck_name) @@ -1094,7 +1145,8 @@ set_midle: best_mode = fls(ddata->cfg.midlemodes) - 1; if (best_mode > SYSC_IDLE_MASK) { dev_err(dev, "%s: invalid midlemode\n", __func__); - return -EINVAL; + error = -EINVAL; + goto save_context; } if (ddata->cfg.quirks & SYSC_QUIRK_SWSUP_MSTANDBY) @@ -1112,13 +1164,16 @@ set_autoidle: sysc_write_sysconfig(ddata, reg); } - /* Flush posted write */ - sysc_read(ddata, ddata->offsets[SYSC_SYSCONFIG]); + error = 0; + +save_context: + /* Save context and flush posted write */ + ddata->sysconfig = sysc_read(ddata, ddata->offsets[SYSC_SYSCONFIG]); if (ddata->module_enable_quirk) ddata->module_enable_quirk(ddata); - return 0; + return error; } static int sysc_best_idle_mode(u32 idlemodes, u32 *best_mode) @@ -1175,8 +1230,10 @@ static int sysc_disable_module(struct device *dev) set_sidle: /* Set SIDLE mode */ idlemodes = ddata->cfg.sidlemodes; - if (!idlemodes || regbits->sidle_shift < 0) - return 0; + if (!idlemodes || regbits->sidle_shift < 0) { + ret = 0; + goto save_context; + } if (ddata->cfg.quirks & SYSC_QUIRK_SWSUP_SIDLE) { best_mode = SYSC_IDLE_FORCE; @@ -1184,7 +1241,8 @@ set_sidle: ret = sysc_best_idle_mode(idlemodes, &best_mode); if (ret) { dev_err(dev, "%s: invalid sidlemode\n", __func__); - return ret; + ret = -EINVAL; + goto save_context; } } @@ -1195,10 +1253,13 @@ set_sidle: reg |= 1 << regbits->autoidle_shift; |
