[PATCH v2 08/41] media: atomisp: get rid of memory_access.c
Now that we have everything in place, we can get rid of the memory_access abstraction layer. Now, everything related to heterogeneous memory management (hmm) is under hmm.c & related pools. Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/atomisp/Makefile| 1 - .../staging/media/atomisp/include/hmm/hmm.h | 3 + .../staging/media/atomisp/pci/atomisp_acc.c | 3 +- .../staging/media/atomisp/pci/atomisp_fops.c | 1 - .../atomisp/pci/base/refcount/src/refcount.c | 3 +- .../pci/hive_isp_css_common/host/debug.c | 3 +- .../hive_isp_css_common/host/debug_private.h | 1 - .../memory_access/memory_access.h | 94 --- .../media/atomisp/pci/ia_css_memory_access.c | 20 .../pci/isp/kernels/bh/bh_2/ia_css_bh.host.c | 1 - .../isp/kernels/dvs/dvs_1.0/ia_css_dvs.host.c | 3 +- .../raw_aa_binning_1.0/ia_css_raa.host.c | 1 - .../kernels/sdis/sdis_1.0/ia_css_sdis.host.c | 5 +- .../kernels/sdis/sdis_2/ia_css_sdis2.host.c | 5 +- .../media/atomisp/pci/mmu/sh_mmu_mrfld.c | 1 - .../atomisp/pci/runtime/binary/src/binary.c | 4 +- .../pci/runtime/debug/src/ia_css_debug.c | 3 +- .../atomisp/pci/runtime/event/src/event.c | 1 - .../atomisp/pci/runtime/frame/src/frame.c | 21 +++-- .../pci/runtime/isp_param/src/isp_param.c | 5 +- .../pci/runtime/pipeline/src/pipeline.c | 3 +- .../pci/runtime/queue/src/queue_access.c | 3 +- .../atomisp/pci/runtime/rmgr/src/rmgr_vbuf.c | 4 +- .../atomisp/pci/runtime/spctrl/src/spctrl.c | 5 +- drivers/staging/media/atomisp/pci/sh_css.c| 3 +- .../media/atomisp/pci/sh_css_firmware.c | 5 +- .../staging/media/atomisp/pci/sh_css_mmu.c| 1 - .../media/atomisp/pci/sh_css_param_dvs.c | 1 - .../staging/media/atomisp/pci/sh_css_params.c | 46 + drivers/staging/media/atomisp/pci/sh_css_sp.c | 3 +- 30 files changed, 79 insertions(+), 174 deletions(-) delete mode 100644 drivers/staging/media/atomisp/pci/hive_isp_css_include/memory_access/memory_access.h delete mode 100644 drivers/staging/media/atomisp/pci/ia_css_memory_access.c diff --git a/drivers/staging/media/atomisp/Makefile b/drivers/staging/media/atomisp/Makefile index 4a77d6d6910d..01764c487b52 100644 --- a/drivers/staging/media/atomisp/Makefile +++ b/drivers/staging/media/atomisp/Makefile @@ -54,7 +54,6 @@ atomisp-objs += \ pci/hmm/hmm.o \ pci/hmm/hmm_reserved_pool.o \ pci/ia_css_device_access.o \ - pci/ia_css_memory_access.o \ pci/isp/kernels/aa/aa_2/ia_css_aa2.host.o \ pci/isp/kernels/anr/anr_1.0/ia_css_anr.host.o \ pci/isp/kernels/anr/anr_2/ia_css_anr2.host.o \ diff --git a/drivers/staging/media/atomisp/include/hmm/hmm.h b/drivers/staging/media/atomisp/include/hmm/hmm.h index a661c039a2cc..5d725a6b6e10 100644 --- a/drivers/staging/media/atomisp/include/hmm/hmm.h +++ b/drivers/staging/media/atomisp/include/hmm/hmm.h @@ -28,6 +28,9 @@ #include "hmm/hmm_pool.h" #include "ia_css_types.h" +#define mmgr_NULL ((ia_css_ptr)0) +#define mmgr_EXCEPTION ((ia_css_ptr)-1) + int hmm_pool_register(unsigned int pool_size, enum hmm_pool_type pool_type); void hmm_pool_unregister(enum hmm_pool_type pool_type); diff --git a/drivers/staging/media/atomisp/pci/atomisp_acc.c b/drivers/staging/media/atomisp/pci/atomisp_acc.c index 5e7f4cd47c8f..8633afdc3f39 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_acc.c +++ b/drivers/staging/media/atomisp/pci/atomisp_acc.c @@ -23,12 +23,13 @@ #include #include +#include "hmm.h" + #include "atomisp_acc.h" #include "atomisp_internal.h" #include "atomisp_compat.h" #include "atomisp_cmd.h" -#include "memory_access/memory_access.h" #include "ia_css.h" static const struct { diff --git a/drivers/staging/media/atomisp/pci/atomisp_fops.c b/drivers/staging/media/atomisp/pci/atomisp_fops.c index fc3043bded46..1588e84a6b91 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_fops.c +++ b/drivers/staging/media/atomisp/pci/atomisp_fops.c @@ -36,7 +36,6 @@ #include "type_support.h" #include "device_access/device_access.h" -#include "memory_access/memory_access.h" #include "atomisp_acc.h" diff --git a/drivers/staging/media/atomisp/pci/base/refcount/src/refcount.c b/drivers/staging/media/atomisp/pci/base/refcount/src/refcount.c index 52c40aaa1e52..1616f3a38ddd 100644 --- a/drivers/staging/media/atomisp/pci/base/refcount/src/refcount.c +++ b/drivers/staging/media/atomisp/pci/base/refcount/src/refcount.c @@ -12,8 +12,9 @@ * more details. */ +#include "hmm.h" + #include "ia_css_refcount.h" -#include "memory_access/memory_access.h" #include "sh_css_defs.h" #include "platform_support.h" diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/debug.c b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/debug.c index 3a5414b8912a..85b054c5ec80 100644 --- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/debug.c +
[PATCH v2 22/41] media: atomisp: Remove second increment of count in atomisp_subdev_probe
From: Nathan Chancellor Clang warns: ../drivers/staging/media/atomisp/pci/atomisp_v4l2.c:1097:3: warning: variable 'count' is incremented both in the loop header and in the loop body [-Wfor-loop-analysis] count++; ^ This was probably unintentional, remove it. Link: https://github.com/ClangBuiltLinux/linux/issues/1036 Reported-by: kbuild test robot Signed-off-by: Nathan Chancellor Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/atomisp/pci/atomisp_v4l2.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c index c89d477a3948..374b1bb6c339 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c +++ b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c @@ -1098,7 +1098,6 @@ static int atomisp_subdev_probe(struct atomisp_device *isp) if (camera_count) break; msleep(SUBDEV_WAIT_TIMEOUT); - count++; } /* Wait more time to give more time for subdev init code to finish */ msleep(5 * SUBDEV_WAIT_TIMEOUT); -- 2.26.2
[PATCH v2 10/41] media: atomisp: add debug message to help debugging hmm code
The hmm code is partially based on a fork from 3.10 code, and has bugs. Add debug there to help tracking what happens there. Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/atomisp/pci/hmm/hmm_bo.c | 5 + 1 file changed, 5 insertions(+) diff --git a/drivers/staging/media/atomisp/pci/hmm/hmm_bo.c b/drivers/staging/media/atomisp/pci/hmm/hmm_bo.c index 6fce8c95be1d..b6dcd246d7af 100644 --- a/drivers/staging/media/atomisp/pci/hmm/hmm_bo.c +++ b/drivers/staging/media/atomisp/pci/hmm/hmm_bo.c @@ -1015,6 +1015,11 @@ static int alloc_user_pages(struct hmm_buffer_object *bo, bo->mem_type = HMM_BO_MEM_TYPE_USER; } + dev_dbg(atomisp_dev, "%s: %d %s pages were allocated as 0x%08x\n", + __func__, + bo->pgnr, + bo->mem_type == HMM_BO_MEM_TYPE_USER ? "user" : "pfn", page_nr); + /* can be written by caller, not forced */ if (page_nr != bo->pgnr) { dev_err(atomisp_dev, -- 2.26.2
Re: [PATCH V2] mm, memory_failure: don't send BUS_MCEERR_AO for action required error
> Some processes dont't want to be killed early, but in "Action Required" > case, those also may be killed by BUS_MCEERR_AO when sharing memory > with other which is accessing the fail memory. > And sending SIGBUS with BUS_MCEERR_AO for action required error is > strange, so ignore the non-current processes here. > > Suggested-by: Naoya Horiguchi > Signed-off-by: Wetp Zhang > --- > mm/memory-failure.c | 15 +-- > 1 file changed, 9 insertions(+), 6 deletions(-) > > diff --git a/mm/memory-failure.c b/mm/memory-failure.c > index a96364be8ab4..dd3862fcf2e9 100644 > --- a/mm/memory-failure.c > +++ b/mm/memory-failure.c > @@ -210,14 +210,17 @@ static int kill_proc(struct to_kill *tk, unsigned long > pfn, int flags) > { > struct task_struct *t = tk->tsk; > short addr_lsb = tk->size_shift; > - int ret; > + int ret = 0; > > - pr_err("Memory failure: %#lx: Sending SIGBUS to %s:%d due to hardware > memory corruption\n", > - pfn, t->comm, t->pid); > + if ((t->mm == current->mm) || !(flags & MF_ACTION_REQUIRED)) > + pr_err("Memory failure: %#lx: Sending SIGBUS to %s:%d due to > hardware memory corruption\n", > + pfn, t->comm, t->pid); Maybe we can generalize the message condition for better readability. Thought a bit but did not get any other idea. > > - if ((flags & MF_ACTION_REQUIRED) && t->mm == current->mm) { > - ret = force_sig_mceerr(BUS_MCEERR_AR, (void __user *)tk->addr, > - addr_lsb); > + if (flags & MF_ACTION_REQUIRED) { > + if (t->mm == current->mm) > + ret = force_sig_mceerr(BUS_MCEERR_AR, > +(void __user *)tk->addr, addr_lsb); > + /* send no signal to non-current processes */ > } else { > /* > * Don't use force here, it's convenient if the signal > -- Looks good to me. Acked-by: Pankaj Gupta
Re: Lost PCIe PME after a914ff2d78ce ("PCI/ASPM: Don't select CONFIG_PCIEASPM by default")
On Sat, May 30, 2020 at 08:33:50AM +0200, Heiner Kallweit wrote: > It *was* default y. This changed with a914ff2d78ce ("PCI/ASPM: Don't > select CONFIG_PCIEASPM by default") and that's what triggered the > problem. If there's no easy solution, then maybe it's best to revert > the change for now. Oh, sorry, I was looking at mainline. CONFIG_PCIEASPM should *definitely* be enabled by default - platforms expect the OS to support it. If we want to get rid of default y then I think it'd make more sense to have a CONFIG_DISABLE_PCIEASPM that's under EXPERT, and people who really want to disable the code can do so. -- Matthew Garrett | mj...@srcf.ucam.org
checkpatch warnings with PCI DT compatible string
Hi there, When I was trying to create dts for my platform that need PCI DeviceTree sub node to express interrupt of children devices under the bridge, like this: pci@1a00 { compatible = "loongson,ls7a-pci"; device_type = "pci"; #address-cells = <3>; #size-cells = <2>; #interrupt-cells = <2>; msi-parent = <&msi>; reg = <0 0x1a00 0 0x0200>, <0xefe 0x 0 0x2000>; ranges = <0x0100 0x0 0x0002 0x0 0x0002 0x0 0x0002>, <0x0200 0x0 0x4000 0x0 0x4000 0x0 0x4000>; ohci@4,0 { compatible = "pci0014,7a24.0", "pci0014,7a24", "pciclass0c0310", "pciclass0c03"; reg = <0x2000 0x0 0x0 0x0 0x0>; interrupts = <49 IRQ_TYPE_LEVEL_HIGH>; interrupt-parent = <&pic>; }; }; I got such checkpatch warnings: WARNING: DT compatible string "pci0014,7a24.0" appears un-documented -- check ./Documentation/devicetree/bindings/ #206: FILE: arch/mips/boot/dts/loongson/ls7a-pch.dtsi:38: + compatible = "pci0014,7a24.0", WARNING: DT compatible string vendor "pci0014" appears un-documented -- check ./Documentation/devicetree/bindings/vendor-prefixes.yaml #206: FILE: arch/mips/boot/dts/loongson/ls7a-pch.dtsi:38: + compatible = "pci0014,7a24.0", Just wonder if using such compatible string is allowed? I've saw some some usages like mine in the tree, such as arch/x86/platform/ce4100/falconfalls.dts, and arch/mips/boot/dts/img/boston.dts. If that's allowed, should we surpress these warnings in checkpatch script? Thanks. -- Jiaxun Yang
[PATCH] scsi: powertec: Fix different dev_id between 'request_irq()' and 'free_irq()'
The dev_id used in 'request_irq()' and 'free_irq()' should match. So use 'host' in both cases. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Christophe JAILLET --- drivers/scsi/arm/powertec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/arm/powertec.c b/drivers/scsi/arm/powertec.c index 772a13e5fd91..723b80084498 100644 --- a/drivers/scsi/arm/powertec.c +++ b/drivers/scsi/arm/powertec.c @@ -354,7 +354,7 @@ static int powertecscsi_probe(struct expansion_card *ec, goto out_free; ret = request_irq(ec->irq, powertecscsi_intr, - 0, "powertec", info); + 0, "powertec", host); if (ret) { printk("scsi%d: IRQ%d not free: %d\n", host->host_no, ec->irq, ret); -- 2.25.1
[PATCH v2] misc: mic: Remove the error message as the call will print it
From: Liao Pingfang The message should just be dropped as the call will print the failure message anyway. Signed-off-by: Liao Pingfang --- changes in v2: remove the message instead of changing it. drivers/misc/mic/host/mic_main.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/misc/mic/host/mic_main.c b/drivers/misc/mic/host/mic_main.c index be0784f..ea46085 100644 --- a/drivers/misc/mic/host/mic_main.c +++ b/drivers/misc/mic/host/mic_main.c @@ -164,7 +164,6 @@ static int mic_probe(struct pci_dev *pdev, mdev = kzalloc(sizeof(*mdev), GFP_KERNEL); if (!mdev) { rc = -ENOMEM; - dev_err(&pdev->dev, "mdev kmalloc failed rc %d\n", rc); goto mdev_alloc_fail; } mdev->id = ida_simple_get(&g_mic_ida, 0, MIC_MAX_NUM_DEVS, GFP_KERNEL); -- 2.9.5
[PATCH] scsi: eesox: Fix different dev_id between 'request_irq()' and 'free_irq()'
The dev_id used in 'request_irq()' and 'free_irq()' should match. So use 'host' in both cases. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Christophe JAILLET --- drivers/scsi/arm/eesox.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/arm/eesox.c b/drivers/scsi/arm/eesox.c index 6e204a2e0c8d..af0bb401ca23 100644 --- a/drivers/scsi/arm/eesox.c +++ b/drivers/scsi/arm/eesox.c @@ -546,7 +546,7 @@ static int eesoxscsi_probe(struct expansion_card *ec, const struct ecard_id *id) if (ret) goto out_free; - ret = request_irq(ec->irq, eesoxscsi_intr, 0, "eesoxscsi", info); + ret = request_irq(ec->irq, eesoxscsi_intr, 0, "eesoxscsi", host); if (ret) { printk("scsi%d: IRQ%d not free: %d\n", host->host_no, ec->irq, ret); -- 2.25.1
[PATCH] scsi: cumana_2: Fix different dev_id between 'request_irq()' and 'free_irq()'
The dev_id used in 'request_irq()' and 'free_irq()' should match. So use 'host' in both cases. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Christophe JAILLET --- drivers/scsi/arm/cumana_2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/arm/cumana_2.c b/drivers/scsi/arm/cumana_2.c index 65691c21f133..3a3bf53fa925 100644 --- a/drivers/scsi/arm/cumana_2.c +++ b/drivers/scsi/arm/cumana_2.c @@ -426,7 +426,7 @@ static int cumanascsi2_probe(struct expansion_card *ec, goto out_free; ret = request_irq(ec->irq, cumanascsi_2_intr, - 0, "cumanascsi2", info); + 0, "cumanascsi2", host); if (ret) { printk("scsi%d: IRQ%d not free: %d\n", host->host_no, ec->irq, ret); -- 2.25.1
[PATCH v4 5/7] watchdog: dw_wdt: Support devices with asynch clocks
DW Watchdog IP core can be synthesised with asynchronous timer/APB clocks support (WDT_ASYNC_CLK_MODE_ENABLE == 1). In this case separate clock signals are supposed to be used to feed watchdog timer and APB interface of the device. Currently the driver supports the synchronous mode only. Since there is no way to determine which mode was actually activated for device from its registers, we have to rely on the platform device configuration data. If optional "pclk" clock source is supplied, we consider the device working in asynchronous mode, otherwise the driver falls back to the synchronous configuration. Signed-off-by: Serge Semin Reviewed-by: Guenter Roeck Cc: Alexey Malahov Cc: Thomas Bogendoerfer Cc: Arnd Bergmann Cc: Rob Herring Cc: linux-m...@vger.kernel.org Cc: devicet...@vger.kernel.org --- Changelog v2: - Rearrange SoBs. --- drivers/watchdog/dw_wdt.c | 48 +++ 1 file changed, 43 insertions(+), 5 deletions(-) diff --git a/drivers/watchdog/dw_wdt.c b/drivers/watchdog/dw_wdt.c index 693c0d1fd796..efbc36872670 100644 --- a/drivers/watchdog/dw_wdt.c +++ b/drivers/watchdog/dw_wdt.c @@ -68,6 +68,7 @@ struct dw_wdt_timeout { struct dw_wdt { void __iomem*regs; struct clk *clk; + struct clk *pclk; unsigned long rate; struct dw_wdt_timeout timeouts[DW_WDT_NUM_TOPS]; struct watchdog_device wdd; @@ -274,6 +275,7 @@ static int dw_wdt_suspend(struct device *dev) dw_wdt->control = readl(dw_wdt->regs + WDOG_CONTROL_REG_OFFSET); dw_wdt->timeout = readl(dw_wdt->regs + WDOG_TIMEOUT_RANGE_REG_OFFSET); + clk_disable_unprepare(dw_wdt->pclk); clk_disable_unprepare(dw_wdt->clk); return 0; @@ -287,6 +289,12 @@ static int dw_wdt_resume(struct device *dev) if (err) return err; + err = clk_prepare_enable(dw_wdt->pclk); + if (err) { + clk_disable_unprepare(dw_wdt->clk); + return err; + } + writel(dw_wdt->timeout, dw_wdt->regs + WDOG_TIMEOUT_RANGE_REG_OFFSET); writel(dw_wdt->control, dw_wdt->regs + WDOG_CONTROL_REG_OFFSET); @@ -393,9 +401,18 @@ static int dw_wdt_drv_probe(struct platform_device *pdev) if (IS_ERR(dw_wdt->regs)) return PTR_ERR(dw_wdt->regs); - dw_wdt->clk = devm_clk_get(dev, NULL); - if (IS_ERR(dw_wdt->clk)) - return PTR_ERR(dw_wdt->clk); + /* +* Try to request the watchdog dedicated timer clock source. It must +* be supplied if asynchronous mode is enabled. Otherwise fallback +* to the common timer/bus clocks configuration, in which the very +* first found clock supply both timer and APB signals. +*/ + dw_wdt->clk = devm_clk_get(dev, "tclk"); + if (IS_ERR(dw_wdt->clk)) { + dw_wdt->clk = devm_clk_get(dev, NULL); + if (IS_ERR(dw_wdt->clk)) + return PTR_ERR(dw_wdt->clk); + } ret = clk_prepare_enable(dw_wdt->clk); if (ret) @@ -407,10 +424,27 @@ static int dw_wdt_drv_probe(struct platform_device *pdev) goto out_disable_clk; } + /* +* Request APB clock if device is configured with async clocks mode. +* In this case both tclk and pclk clocks are supposed to be specified. +* Alas we can't know for sure whether async mode was really activated, +* so the pclk phandle reference is left optional. If it couldn't be +* found we consider the device configured in synchronous clocks mode. +*/ + dw_wdt->pclk = devm_clk_get_optional(dev, "pclk"); + if (IS_ERR(dw_wdt->pclk)) { + ret = PTR_ERR(dw_wdt->pclk); + goto out_disable_clk; + } + + ret = clk_prepare_enable(dw_wdt->pclk); + if (ret) + goto out_disable_clk; + dw_wdt->rst = devm_reset_control_get_optional_shared(&pdev->dev, NULL); if (IS_ERR(dw_wdt->rst)) { ret = PTR_ERR(dw_wdt->rst); - goto out_disable_clk; + goto out_disable_pclk; } reset_control_deassert(dw_wdt->rst); @@ -449,10 +483,13 @@ static int dw_wdt_drv_probe(struct platform_device *pdev) ret = watchdog_register_device(wdd); if (ret) - goto out_disable_clk; + goto out_disable_pclk; return 0; +out_disable_pclk: + clk_disable_unprepare(dw_wdt->pclk); + out_disable_clk: clk_disable_unprepare(dw_wdt->clk); return ret; @@ -464,6 +501,7 @@ static int dw_wdt_drv_remove(struct platform_device *pdev) watchdog_unregister_device(&dw_wdt->wdd); reset_control_assert(dw_wdt->rst); + clk_disable_unprepare(dw_wdt->pclk); clk_disable_unprepare(dw_wdt->clk); return 0; -- 2.26.2
[PATCH v4 2/7] dt-bindings: watchdog: dw-wdt: Support devices with asynch clocks
DW Watchdog IP core can be synthesised with asynchronous timer/APB clocks support (WDT_ASYNC_CLK_MODE_ENABLE == 1). In this case separate clock signals are supposed to be used to feed watchdog timer and APB interface of the device. Let's update the DW Watchdog DT node schema so it would support the optional APB3 bus clock specified along with the mandatory watchdog timer reference clock. Signed-off-by: Serge Semin Reviewed-by: Rob Herring Reviewed-by: Guenter Roeck Cc: Alexey Malahov Cc: Thomas Bogendoerfer Cc: Arnd Bergmann Cc: linux-m...@vger.kernel.org --- Changelog v2: - It's a new patch unpinned from the previous one. --- .../devicetree/bindings/watchdog/snps,dw-wdt.yaml | 8 1 file changed, 8 insertions(+) diff --git a/Documentation/devicetree/bindings/watchdog/snps,dw-wdt.yaml b/Documentation/devicetree/bindings/watchdog/snps,dw-wdt.yaml index 4f6944756ab4..5bf6dc6377f3 100644 --- a/Documentation/devicetree/bindings/watchdog/snps,dw-wdt.yaml +++ b/Documentation/devicetree/bindings/watchdog/snps,dw-wdt.yaml @@ -24,8 +24,16 @@ properties: maxItems: 1 clocks: +minItems: 1 items: - description: Watchdog timer reference clock + - description: APB3 interface clock + + clock-names: +minItems: 1 +items: + - const: tclk + - const: pclk resets: description: Phandle to the DW Watchdog reset lane -- 2.26.2
[PATCH v4 4/7] watchdog: dw_wdt: Support devices with non-fixed TOP values
In case if the DW Watchdog IP core is synthesised with WDT_USE_FIX_TOP == false, the TOP interval indexes make the device to load a custom periods to the counter. These periods are hardwired at the IP synthesis stage and can be within [2^8, 2^(WDT_CNT_WIDTH - 1)]. Alas their values can't be detected at runtime and must be somehow supplied to the driver so one could properly determine the watchdog timeout intervals. For this purpose we suggest to have a vendor- specific dts property "snps,watchdog-tops" utilized, which would provide an array of sixteen counter values. At device probe stage they will be used to initialize the watchdog device timeouts determined from the array values and current clocks source rate. In order to have custom TOP values supported the driver must be altered in the following way. First of all the fixed-top values ready-to-use array must be determined for compatibility with currently supported devices, which were synthesised with WDT_USE_FIX_TOP == true. It will be used if either fixed TOP feature is detected being enabled or no custom TOPs are fetched from the device dt node. Secondly at the probe stage we must initialize an array of the watchdog timeouts corresponding to the detected TOPs list and the reference clock rate. For generality the procedure of initialization is designed in a way to support the TOPs array with no limitations on the items order or value. Finally the watchdog period search methods should be altered to support the new timeouts data structure. Signed-off-by: Serge Semin Reviewed-by: Guenter Roeck Cc: Alexey Malahov Cc: Thomas Bogendoerfer Cc: Arnd Bergmann Cc: Rob Herring Cc: linux-m...@vger.kernel.org Cc: devicet...@vger.kernel.org --- Changelog v2: - Rearrange SoBs. - Add "ms" suffix to the methods returning msec and convert the methods with no "ms" suffix to return a timeout in sec. - Make sure minimum timeout is at least 1 sec. - Refactor the timeouts calculation procedure to retain the timeouts in the ascending order. - Make sure there is no integer overflow in milliseconds calculation. It is saved in a dedicated uint field of the timeout structure. --- drivers/watchdog/dw_wdt.c | 191 +- 1 file changed, 167 insertions(+), 24 deletions(-) diff --git a/drivers/watchdog/dw_wdt.c b/drivers/watchdog/dw_wdt.c index fba21de2bbad..693c0d1fd796 100644 --- a/drivers/watchdog/dw_wdt.c +++ b/drivers/watchdog/dw_wdt.c @@ -13,6 +13,8 @@ */ #include +#include +#include #include #include #include @@ -34,21 +36,40 @@ #define WDOG_CURRENT_COUNT_REG_OFFSET 0x08 #define WDOG_COUNTER_RESTART_REG_OFFSET 0x0c #define WDOG_COUNTER_RESTART_KICK_VALUE0x76 +#define WDOG_COMP_PARAMS_1_REG_OFFSET 0xf4 +#define WDOG_COMP_PARAMS_1_USE_FIX_TOP BIT(6) -/* The maximum TOP (timeout period) value that can be set in the watchdog. */ -#define DW_WDT_MAX_TOP 15 +/* There are sixteen TOPs (timeout periods) that can be set in the watchdog. */ +#define DW_WDT_NUM_TOPS16 +#define DW_WDT_FIX_TOP(_idx) (1U << (16 + _idx)) #define DW_WDT_DEFAULT_SECONDS 30 +static const u32 dw_wdt_fix_tops[DW_WDT_NUM_TOPS] = { + DW_WDT_FIX_TOP(0), DW_WDT_FIX_TOP(1), DW_WDT_FIX_TOP(2), + DW_WDT_FIX_TOP(3), DW_WDT_FIX_TOP(4), DW_WDT_FIX_TOP(5), + DW_WDT_FIX_TOP(6), DW_WDT_FIX_TOP(7), DW_WDT_FIX_TOP(8), + DW_WDT_FIX_TOP(9), DW_WDT_FIX_TOP(10), DW_WDT_FIX_TOP(11), + DW_WDT_FIX_TOP(12), DW_WDT_FIX_TOP(13), DW_WDT_FIX_TOP(14), + DW_WDT_FIX_TOP(15) +}; + static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started " "(default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); +struct dw_wdt_timeout { + u32 top_val; + unsigned int sec; + unsigned int msec; +}; + struct dw_wdt { void __iomem*regs; struct clk *clk; unsigned long rate; + struct dw_wdt_timeout timeouts[DW_WDT_NUM_TOPS]; struct watchdog_device wdd; struct reset_control*rst; /* Save/restore */ @@ -64,20 +85,66 @@ static inline int dw_wdt_is_enabled(struct dw_wdt *dw_wdt) WDOG_CONTROL_REG_WDT_EN_MASK; } -static inline int dw_wdt_top_in_seconds(struct dw_wdt *dw_wdt, unsigned top) +static unsigned int dw_wdt_find_best_top(struct dw_wdt *dw_wdt, +unsigned int timeout, u32 *top_val) { + int idx; + /* -* There are 16 possible timeout values in 0..15 where the number of -* cycles is 2 ^ (16 + i) and the watchdog counts down. +* Find a TOP with timeout greater or equal to the requested number. +* Note we'll select a TOP with maximum timeout if the requested +* timeout couldn't be reached. */ - return (1U << (16 + top)) / dw_wdt->rate; + for (idx = 0; idx < DW_
[PATCH v4 6/7] watchdog: dw_wdt: Add pre-timeouts support
DW Watchdog can rise an interrupt in case if IRQ request mode is enabled and timer reaches the zero value. In this case the IRQ lane is left pending until either the next watchdog kick event (watchdog restart) or until the WDT_EOI register is read or the device/system reset. This interface can be used to implement the pre-timeout functionality optionally provided by the Linux kernel watchdog devices. IRQ mode provides a two stages timeout interface. It means the IRQ is raised when the counter reaches zero, while the system reset occurs only after subsequent timeout if the timer restart is not performed. Due to this peculiarity the pre-timeout value is actually set to the achieved hardware timeout, while the real watchdog timeout is considered to be twice as much of it. This applies a significant limitation on the pre-timeout values, so current implementation supports either zero value, which disables the pre-timeout events, or non-zero values, which imply the pre-timeout to be at least half of the current watchdog timeout. Note that we ask the interrupt controller to detect the rising-edge pre-timeout interrupts to prevent the high-level-IRQs flood, since if the pre-timeout happens, the IRQ lane will be left pending until it's cleared by the timer restart. Signed-off-by: Serge Semin Reviewed-by: Guenter Roeck Cc: Alexey Malahov Cc: Thomas Bogendoerfer Cc: Arnd Bergmann Cc: Rob Herring Cc: linux-m...@vger.kernel.org Cc: devicet...@vger.kernel.org --- Changelog v2: - Rearrange SoBs. - Make the Pre-timeout IRQ being optionally supported. Changelog v4: - Linux IRQ > 0 is only valid so make sure we request IRQ only if valid number is returned from platform_get_irq_optional(). --- drivers/watchdog/dw_wdt.c | 138 +++--- 1 file changed, 130 insertions(+), 8 deletions(-) diff --git a/drivers/watchdog/dw_wdt.c b/drivers/watchdog/dw_wdt.c index efbc36872670..7a171920dd21 100644 --- a/drivers/watchdog/dw_wdt.c +++ b/drivers/watchdog/dw_wdt.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -36,6 +37,8 @@ #define WDOG_CURRENT_COUNT_REG_OFFSET 0x08 #define WDOG_COUNTER_RESTART_REG_OFFSET 0x0c #define WDOG_COUNTER_RESTART_KICK_VALUE0x76 +#define WDOG_INTERRUPT_STATUS_REG_OFFSET0x10 +#define WDOG_INTERRUPT_CLEAR_REG_OFFSET 0x14 #define WDOG_COMP_PARAMS_1_REG_OFFSET 0xf4 #define WDOG_COMP_PARAMS_1_USE_FIX_TOP BIT(6) @@ -59,6 +62,11 @@ module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started " "(default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); +enum dw_wdt_rmod { + DW_WDT_RMOD_RESET = 1, + DW_WDT_RMOD_IRQ = 2 +}; + struct dw_wdt_timeout { u32 top_val; unsigned int sec; @@ -70,6 +78,7 @@ struct dw_wdt { struct clk *clk; struct clk *pclk; unsigned long rate; + enum dw_wdt_rmodrmod; struct dw_wdt_timeout timeouts[DW_WDT_NUM_TOPS]; struct watchdog_device wdd; struct reset_control*rst; @@ -86,6 +95,20 @@ static inline int dw_wdt_is_enabled(struct dw_wdt *dw_wdt) WDOG_CONTROL_REG_WDT_EN_MASK; } +static void dw_wdt_update_mode(struct dw_wdt *dw_wdt, enum dw_wdt_rmod rmod) +{ + u32 val; + + val = readl(dw_wdt->regs + WDOG_CONTROL_REG_OFFSET); + if (rmod == DW_WDT_RMOD_IRQ) + val |= WDOG_CONTROL_REG_RESP_MODE_MASK; + else + val &= ~WDOG_CONTROL_REG_RESP_MODE_MASK; + writel(val, dw_wdt->regs + WDOG_CONTROL_REG_OFFSET); + + dw_wdt->rmod = rmod; +} + static unsigned int dw_wdt_find_best_top(struct dw_wdt *dw_wdt, unsigned int timeout, u32 *top_val) { @@ -145,7 +168,11 @@ static unsigned int dw_wdt_get_timeout(struct dw_wdt *dw_wdt) break; } - return dw_wdt->timeouts[idx].sec; + /* +* In IRQ mode due to the two stages counter, the actual timeout is +* twice greater than the TOP setting. +*/ + return dw_wdt->timeouts[idx].sec * dw_wdt->rmod; } static int dw_wdt_ping(struct watchdog_device *wdd) @@ -164,7 +191,20 @@ static int dw_wdt_set_timeout(struct watchdog_device *wdd, unsigned int top_s) unsigned int timeout; u32 top_val; - timeout = dw_wdt_find_best_top(dw_wdt, top_s, &top_val); + /* +* Note IRQ mode being enabled means having a non-zero pre-timeout +* setup. In this case we try to find a TOP as close to the half of the +* requested timeout as possible since DW Watchdog IRQ mode is designed +* in two stages way - first timeout rises the pre-timeout interrupt, +* second timeout performs the system reset. So basically the effective +* watchdog-caused reset happens after two watchdog TOPs elapsed. +*/ +
[PATCH v4 1/7] dt-bindings: watchdog: Convert DW WDT binding to DT schema
Modern device tree bindings are supposed to be created as YAML-files in accordance with dt-schema. This commit replaces the DW Watchdog legacy bare text bindings with YAML file. As before the binding states that the corresponding dts node is supposed to have a registers range, a watchdog timer references clock source, optional reset line and pre-timeout interrupt. Signed-off-by: Serge Semin Reviewed-by: Rob Herring Reviewed-by: Guenter Roeck Cc: Alexey Malahov Cc: Thomas Bogendoerfer Cc: Arnd Bergmann Cc: linux-m...@vger.kernel.org --- Changelog v2: - Rearrange SoBs. - Discard BE copyright header. - Replace "additionalProperties: false" with "unevaluatedProperties: false" property. - Discard interrupts property from the required properties list. - Remove a label definition from the binding example. - Move the asynchronous APB3 clock support into a dedicated patch. --- .../devicetree/bindings/watchdog/dw_wdt.txt | 24 - .../bindings/watchdog/snps,dw-wdt.yaml| 50 +++ 2 files changed, 50 insertions(+), 24 deletions(-) delete mode 100644 Documentation/devicetree/bindings/watchdog/dw_wdt.txt create mode 100644 Documentation/devicetree/bindings/watchdog/snps,dw-wdt.yaml diff --git a/Documentation/devicetree/bindings/watchdog/dw_wdt.txt b/Documentation/devicetree/bindings/watchdog/dw_wdt.txt deleted file mode 100644 index eb0914420c7c.. --- a/Documentation/devicetree/bindings/watchdog/dw_wdt.txt +++ /dev/null @@ -1,24 +0,0 @@ -Synopsys Designware Watchdog Timer - -Required Properties: - -- compatible : Should contain "snps,dw-wdt" -- reg : Base address and size of the watchdog timer registers. -- clocks : phandle + clock-specifier for the clock that drives the - watchdog timer. - -Optional Properties: - -- interrupts : The interrupt used for the watchdog timeout warning. -- resets : phandle pointing to the system reset controller with - line index for the watchdog. - -Example: - - watchdog0: wd@ffd02000 { - compatible = "snps,dw-wdt"; - reg = <0xffd02000 0x1000>; - interrupts = <0 171 4>; - clocks = <&per_base_clk>; - resets = <&rst WDT0_RESET>; - }; diff --git a/Documentation/devicetree/bindings/watchdog/snps,dw-wdt.yaml b/Documentation/devicetree/bindings/watchdog/snps,dw-wdt.yaml new file mode 100644 index ..4f6944756ab4 --- /dev/null +++ b/Documentation/devicetree/bindings/watchdog/snps,dw-wdt.yaml @@ -0,0 +1,50 @@ +# SPDX-License-Identifier: GPL-2.0-only +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/watchdog/snps,dw-wdt.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Synopsys Designware Watchdog Timer + +allOf: + - $ref: "watchdog.yaml#" + +maintainers: + - Jamie Iles + +properties: + compatible: +const: snps,dw-wdt + + reg: +maxItems: 1 + + interrupts: +description: DW Watchdog pre-timeout interrupt +maxItems: 1 + + clocks: +items: + - description: Watchdog timer reference clock + + resets: +description: Phandle to the DW Watchdog reset lane +maxItems: 1 + +unevaluatedProperties: false + +required: + - compatible + - reg + - clocks + +examples: + - | +watchdog@ffd02000 { + compatible = "snps,dw-wdt"; + reg = <0xffd02000 0x1000>; + interrupts = <0 171 4>; + clocks = <&per_base_clk>; + resets = <&wdt_rst>; +}; +... -- 2.26.2
[PATCH v4 0/7] watchdog: dw_wdt: Take Baikal-T1 DW WDT peculiarities into account
Merge window is upon us. Please review/merge in/whatever the rest of the patches. There were a few features enabled at the time of the Baikal-T1 SoC DW WDT IP synthesis, which weren't taken into account in the DW WDT driver available in the kernel. First of all the SoC engineers synthesized the watchdog core with WDT_USE_FIX_TOP set to false (don't really know why, but they did). Due to this the timer reset values weren't fixed as the driver expected but were initialized with a pre-defined values selected by the engineers. Secondly the driver expected that the watchdog APB bus and the timer had synchronous reference clocks, while Baikal-T1 SoC DW WDT was created with asynchronous ones. So the driver should enable two clock devices: APB bus clocks and a separate timer reference clock. Finally DW Watchdog Timer is capable of generating a pre-timeout interrupt if corresponding config is enabled. The problem was that the pre-timeout IRQ happens when the set timeout elapses, while the actual WDT expiration and subsequent reboot take place in the next timeout. This makes the pre-timeout functionality implementation a bit tricky, since in this case we would have to find a WDT timeout twice smaller the requested timeout. All of the changes described above are provided by the patches in this patchset. In addition traditionally we replaced the legacy plain text-based dt-binding file with yaml-based one and added the controller registers dump DebugFS node to ease the driver debug procedure. This patchset is rebased and tested on the mainline Linux kernel 5.6-rc4: base-commit: 0e698dfa2822 ("Linux 5.7-rc4") tag: v5.7-rc4 Changelog v2: - Rearrange SoBs. - Discard BE copyright header from the binding file. - Replace "additionalProperties: false" with "unevaluatedProperties: false" property in the binding. - Move the APB3 clocks support declared in the dt binding file into a dedicated patch. - Move $ref to the root level of the "snps,watchdog-tops" property so does the constraints. - Make Pre-timeout IRQs support being optional. - Add "ms" suffix to the methods returning msec and convert the methods with no "ms" suffix to return a timeout in sec. - Make sure minimum timeout is at least 1 sec. - Refactor the timeouts calculation procedure to to retain the timeouts in the ascending order. - Make sure there is no integer overflow in milliseconds calculation. It is saved in a dedicated uint field of the timeout structure. - Discard timeout/pretimeout/ping/enable DebugFS nodes. Registers state dump node is only left. Link: https://lore.kernel.org/linux-watchdog/20200510105807.880-1-sergey.se...@baikalelectronics.ru/ Changelog v3: - Add Rob's Reviewed-by tag to the DT-related patches. - Remove items from the "snps,watchdog-tops" property and move the minItems and maxItems constraints to the root level of it. Link: https://lore.kernel.org/linux-watchdog/20200526154123.24402-1-sergey.se...@baikalelectronics.ru Changelog v4: - Add Guenter's Reviewed-by tags. - IRQ > 0 is only valid in Linux so make sure we request IRQ only if valid number is returned from platform_get_irq_optional(). Signed-off-by: Serge Semin Cc: Alexey Malahov Cc: Maxim Kaurkin Cc: Pavel Parkhomenko Cc: Ramil Zaripov Cc: Ekaterina Skachko Cc: Vadim Vlasov Cc: Alexey Kolotnikov Cc: Thomas Bogendoerfer Cc: Arnd Bergmann Cc: Rob Herring Cc: linux-m...@vger.kernel.org Cc: linux-watch...@vger.kernel.org Cc: devicet...@vger.kernel.org Cc: linux-kernel@vger.kernel.org Serge Semin (7): dt-bindings: watchdog: Convert DW WDT binding to DT schema dt-bindings: watchdog: dw-wdt: Support devices with asynch clocks dt-bindings: watchdog: dw-wdt: Add watchdog TOPs array property watchdog: dw_wdt: Support devices with non-fixed TOP values watchdog: dw_wdt: Support devices with asynch clocks watchdog: dw_wdt: Add pre-timeouts support watchdog: dw_wdt: Add DebugFS files .../devicetree/bindings/watchdog/dw_wdt.txt | 24 - .../bindings/watchdog/snps,dw-wdt.yaml| 90 drivers/watchdog/dw_wdt.c | 437 -- 3 files changed, 494 insertions(+), 57 deletions(-) delete mode 100644 Documentation/devicetree/bindings/watchdog/dw_wdt.txt create mode 100644 Documentation/devicetree/bindings/watchdog/snps,dw-wdt.yaml -- 2.26.2
[PATCH v4 3/7] dt-bindings: watchdog: dw-wdt: Add watchdog TOPs array property
In case if DW Watchdog IP core is built with WDT_USE_FIX_TOP == false, a custom timeout periods are used to preset the timer counter. In this case that periods should be specified in a new "snps,watchdog-tops" property of the DW watchdog dts node. Signed-off-by: Serge Semin Reviewed-by: Rob Herring Reviewed-by: Guenter Roeck Cc: Alexey Malahov Cc: Thomas Bogendoerfer Cc: Arnd Bergmann Cc: linux-m...@vger.kernel.org --- Changelog v2: - Rearrange SoBs. - Move $ref to the root level of the "snps,watchdog-tops" property so does the constraints. - Add default TOP values array. - Discard the label definition from the new bindings example. Changelog v3: - Remove items property and move the minItems and maxItems constraints to the root level of the snps,watchdog-tops property. --- .../bindings/watchdog/snps,dw-wdt.yaml| 32 +++ 1 file changed, 32 insertions(+) diff --git a/Documentation/devicetree/bindings/watchdog/snps,dw-wdt.yaml b/Documentation/devicetree/bindings/watchdog/snps,dw-wdt.yaml index 5bf6dc6377f3..d9fc7bb851b1 100644 --- a/Documentation/devicetree/bindings/watchdog/snps,dw-wdt.yaml +++ b/Documentation/devicetree/bindings/watchdog/snps,dw-wdt.yaml @@ -39,6 +39,23 @@ properties: description: Phandle to the DW Watchdog reset lane maxItems: 1 + snps,watchdog-tops: +$ref: /schemas/types.yaml#/definitions/uint32-array +description: | + DW APB Watchdog custom timer intervals - Timeout Period ranges (TOPs). + Each TOP is a number loaded into the watchdog counter at the moment of + the timer restart. The counter decrementing happens each tick of the + reference clock. Therefore the TOPs array is equivalent to an array of + the timer expiration intervals supported by the DW APB Watchdog. Note + DW APB Watchdog IP-core might be synthesized with fixed TOP values, + in which case this property is unnecessary with default TOPs utilized. +default: [0x0001000 0x0002000 0x0004000 0x0008000 + 0x001 0x002 0x004 0x008 + 0x010 0x020 0x040 0x080 + 0x100 0x200 0x400 0x800] +minItems: 16 +maxItems: 16 + unevaluatedProperties: false required: @@ -55,4 +72,19 @@ examples: clocks = <&per_base_clk>; resets = <&wdt_rst>; }; + + - | +watchdog@ffd02000 { + compatible = "snps,dw-wdt"; + reg = <0xffd02000 0x1000>; + interrupts = <0 171 4>; + clocks = <&per_base_clk>; + clock-names = "tclk"; + snps,watchdog-tops = <0x00FF 0x01FF 0x03FF +0x07FF 0x 0x0001 +0x0003 0x0007 0x000F +0x001F 0x003F 0x007F +0x00FF 0x01FF 0x03FF +0x07FF>; +}; ... -- 2.26.2
[PATCH v4 7/7] watchdog: dw_wdt: Add DebugFS files
For the sake of the easier device-driver debug procedure, we added a DebugFS file with the controller registers state. It's available only if kernel is configured with DebugFS support. Signed-off-by: Serge Semin Reviewed-by: Guenter Roeck Cc: Alexey Malahov Cc: Thomas Bogendoerfer Cc: Arnd Bergmann Cc: Rob Herring Cc: linux-m...@vger.kernel.org Cc: devicet...@vger.kernel.org --- Changelog v2: - Rearrange SoBs. - Discard timeout/pretimeout/ping/enable DebugFS nodes. Registers state dump node is only left. --- drivers/watchdog/dw_wdt.c | 68 +++ 1 file changed, 68 insertions(+) diff --git a/drivers/watchdog/dw_wdt.c b/drivers/watchdog/dw_wdt.c index 7a171920dd21..4fec2c6a3c01 100644 --- a/drivers/watchdog/dw_wdt.c +++ b/drivers/watchdog/dw_wdt.c @@ -28,6 +28,7 @@ #include #include #include +#include #define WDOG_CONTROL_REG_OFFSET0x00 #define WDOG_CONTROL_REG_WDT_EN_MASK 0x01 @@ -39,8 +40,14 @@ #define WDOG_COUNTER_RESTART_KICK_VALUE0x76 #define WDOG_INTERRUPT_STATUS_REG_OFFSET0x10 #define WDOG_INTERRUPT_CLEAR_REG_OFFSET 0x14 +#define WDOG_COMP_PARAMS_5_REG_OFFSET 0xe4 +#define WDOG_COMP_PARAMS_4_REG_OFFSET 0xe8 +#define WDOG_COMP_PARAMS_3_REG_OFFSET 0xec +#define WDOG_COMP_PARAMS_2_REG_OFFSET 0xf0 #define WDOG_COMP_PARAMS_1_REG_OFFSET 0xf4 #define WDOG_COMP_PARAMS_1_USE_FIX_TOP BIT(6) +#define WDOG_COMP_VERSION_REG_OFFSET0xf8 +#define WDOG_COMP_TYPE_REG_OFFSET 0xfc /* There are sixteen TOPs (timeout periods) that can be set in the watchdog. */ #define DW_WDT_NUM_TOPS16 @@ -85,6 +92,10 @@ struct dw_wdt { /* Save/restore */ u32 control; u32 timeout; + +#ifdef CONFIG_DEBUG_FS + struct dentry *dbgfs_dir; +#endif }; #define to_dw_wdt(wdd) container_of(wdd, struct dw_wdt, wdd) @@ -484,6 +495,59 @@ static int dw_wdt_init_timeouts(struct dw_wdt *dw_wdt, struct device *dev) return 0; } +#ifdef CONFIG_DEBUG_FS + +#define DW_WDT_DBGFS_REG(_name, _off) \ +{\ + .name = _name,\ + .offset = _off\ +} + +static const struct debugfs_reg32 dw_wdt_dbgfs_regs[] = { + DW_WDT_DBGFS_REG("cr", WDOG_CONTROL_REG_OFFSET), + DW_WDT_DBGFS_REG("torr", WDOG_TIMEOUT_RANGE_REG_OFFSET), + DW_WDT_DBGFS_REG("ccvr", WDOG_CURRENT_COUNT_REG_OFFSET), + DW_WDT_DBGFS_REG("crr", WDOG_COUNTER_RESTART_REG_OFFSET), + DW_WDT_DBGFS_REG("stat", WDOG_INTERRUPT_STATUS_REG_OFFSET), + DW_WDT_DBGFS_REG("param5", WDOG_COMP_PARAMS_5_REG_OFFSET), + DW_WDT_DBGFS_REG("param4", WDOG_COMP_PARAMS_4_REG_OFFSET), + DW_WDT_DBGFS_REG("param3", WDOG_COMP_PARAMS_3_REG_OFFSET), + DW_WDT_DBGFS_REG("param2", WDOG_COMP_PARAMS_2_REG_OFFSET), + DW_WDT_DBGFS_REG("param1", WDOG_COMP_PARAMS_1_REG_OFFSET), + DW_WDT_DBGFS_REG("version", WDOG_COMP_VERSION_REG_OFFSET), + DW_WDT_DBGFS_REG("type", WDOG_COMP_TYPE_REG_OFFSET) +}; + +static void dw_wdt_dbgfs_init(struct dw_wdt *dw_wdt) +{ + struct device *dev = dw_wdt->wdd.parent; + struct debugfs_regset32 *regset; + + regset = devm_kzalloc(dev, sizeof(*regset), GFP_KERNEL); + if (!regset) + return; + + regset->regs = dw_wdt_dbgfs_regs; + regset->nregs = ARRAY_SIZE(dw_wdt_dbgfs_regs); + regset->base = dw_wdt->regs; + + dw_wdt->dbgfs_dir = debugfs_create_dir(dev_name(dev), NULL); + + debugfs_create_regset32("registers", 0444, dw_wdt->dbgfs_dir, regset); +} + +static void dw_wdt_dbgfs_clear(struct dw_wdt *dw_wdt) +{ + debugfs_remove_recursive(dw_wdt->dbgfs_dir); +} + +#else /* !CONFIG_DEBUG_FS */ + +static void dw_wdt_dbgfs_init(struct dw_wdt *dw_wdt) {} +static void dw_wdt_dbgfs_clear(struct dw_wdt *dw_wdt) {} + +#endif /* !CONFIG_DEBUG_FS */ + static int dw_wdt_drv_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -607,6 +671,8 @@ static int dw_wdt_drv_probe(struct platform_device *pdev) if (ret) goto out_disable_pclk; + dw_wdt_dbgfs_init(dw_wdt); + return 0; out_disable_pclk: @@ -621,6 +687,8 @@ static int dw_wdt_drv_remove(struct platform_device *pdev) { struct dw_wdt *dw_wdt = platform_get_drvdata(pdev); + dw_wdt_dbgfs_clear(dw_wdt); + watchdog_unregister_device(&dw_wdt->wdd); reset_control_assert(dw_wdt->rst); clk_disable_unprepare(dw_wdt->pclk); -- 2.26.2
Re: PANIC: double fault in fixup_bad_iret
Peter Zijlstra writes: > On Fri, May 29, 2020 at 06:07:11PM +0200, Peter Zijlstra wrote: >> Like with KCSAN, we should blanket kill KASAN/UBSAN and friends (at the >> very least in arch/x86/) until they get that function attribute stuff >> sorted. > > Something like so. We have noinstr in kernel/rcu as well but that at least has a halfways correct state, but still Thanks, tglx
Re: [PATCH v2] orangefs: convert get_user_pages() --> pin_user_pages()
On 2020-05-22 20:59, John Hubbard wrote: This code was using get_user_pages*(), in a "Case 1" scenario (Direct IO), using the categorization from [1]. That means that it's time to convert the get_user_pages*() + put_page() calls to pin_user_pages*() + unpin_user_pages() calls. There is some helpful background in [2]: basically, this is a small part of fixing a long-standing disconnect between pinning pages, and file systems' use of those pages. [1] Documentation/core-api/pin_user_pages.rst [2] "Explicit pinning of user-space pages": https://lwn.net/Articles/807108/ Cc: Mike Marshall Cc: Martin Brandenburg Cc: de...@lists.orangefs.org Cc: linux-fsde...@vger.kernel.org Signed-off-by: John Hubbard --- Hi, Note that I have only compile-tested this patch, although that does also include cross-compiling for a few other arches. An update on the run-time testing: Just now, I got basic orangefs tests running in xfstests, with this patch applied, and it all looks normal. thanks, -- John Hubbard NVIDIA Changes since v1 [3]: correct the commit description, so that it refers to "Case 1" instead of "Case 2". [3] https://lore.kernel.org/r/20200518060139.2828423-1-jhubb...@nvidia.com thanks, John Hubbard NVIDIA fs/orangefs/orangefs-bufmap.c | 9 +++-- 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/fs/orangefs/orangefs-bufmap.c b/fs/orangefs/orangefs-bufmap.c index 2bb916d68576..538e839590ef 100644 --- a/fs/orangefs/orangefs-bufmap.c +++ b/fs/orangefs/orangefs-bufmap.c @@ -168,10 +168,7 @@ static DEFINE_SPINLOCK(orangefs_bufmap_lock); static void orangefs_bufmap_unmap(struct orangefs_bufmap *bufmap) { - int i; - - for (i = 0; i < bufmap->page_count; i++) - put_page(bufmap->page_array[i]); + unpin_user_pages(bufmap->page_array, bufmap->page_count); } static void @@ -268,7 +265,7 @@ orangefs_bufmap_map(struct orangefs_bufmap *bufmap, int offset = 0, ret, i; /* map the pages */ - ret = get_user_pages_fast((unsigned long)user_desc->ptr, + ret = pin_user_pages_fast((unsigned long)user_desc->ptr, bufmap->page_count, FOLL_WRITE, bufmap->page_array); if (ret < 0) @@ -280,7 +277,7 @@ orangefs_bufmap_map(struct orangefs_bufmap *bufmap, for (i = 0; i < ret; i++) { SetPageError(bufmap->page_array[i]); - put_page(bufmap->page_array[i]); + unpin_user_page(bufmap->page_array[i]); } return -ENOMEM; }
[PATCH] input: tablet: aiptek: fix possible buffer overflow caused by bad DMA value in aiptek_irq()
The value aiptek->data is stored in DMA memory, and it is assigned to data. Thus in the code: macro = get_unaligned_le16(data + 1); The value of marco can be modified by malicious hardware. In this case, buffer overflow may occur when the code "macroKeyEvents[macro - 1]" and "macroKeyEvents[macro]" is executed. To fix these possible bugs, macro is checked before being used. Signed-off-by: Jia-Ju Bai --- drivers/input/tablet/aiptek.c | 7 --- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/input/tablet/aiptek.c b/drivers/input/tablet/aiptek.c index e08b0ef078e8..e353e538fb51 100644 --- a/drivers/input/tablet/aiptek.c +++ b/drivers/input/tablet/aiptek.c @@ -737,11 +737,11 @@ static void aiptek_irq(struct urb *urb) */ else if (data[0] == 6) { macro = get_unaligned_le16(data + 1); - if (macro > 0) { + if (macro > 0 && macro < 34) { input_report_key(inputdev, macroKeyEvents[macro - 1], 0); } - if (macro < 25) { + if (marco > 0 && macro < 25) { input_report_key(inputdev, macroKeyEvents[macro + 1], 0); } @@ -760,7 +760,8 @@ static void aiptek_irq(struct urb *urb) aiptek->curSetting.toolMode; } - input_report_key(inputdev, macroKeyEvents[macro], 1); + if (macro > 0 && macro < 33) + input_report_key(inputdev, macroKeyEvents[macro], 1); input_report_abs(inputdev, ABS_MISC, 1 | AIPTEK_REPORT_TOOL_UNKNOWN); input_sync(inputdev); -- 2.17.1
[tip: irq/core] irqchip/sifive-plic: Setup cpuhp once after boot CPU handler is present
The following commit has been merged into the irq/core branch of tip: Commit-ID: 2234ae846ccb9ebdf4c391824cb79e73674dceda Gitweb: https://git.kernel.org/tip/2234ae846ccb9ebdf4c391824cb79e73674dceda Author:Anup Patel AuthorDate:Mon, 18 May 2020 14:44:40 +05:30 Committer: Marc Zyngier CommitterDate: Mon, 25 May 2020 10:36:53 +01:00 irqchip/sifive-plic: Setup cpuhp once after boot CPU handler is present For multiple PLIC instances, the plic_init() is called once for each PLIC instance. Due to this we have two issues: 1. cpuhp_setup_state() is called multiple times 2. plic_starting_cpu() can crash for boot CPU if cpuhp_setup_state() is called before boot CPU PLIC handler is available. Address both issues by only initializing the HP notifiers when the boot CPU setup is complete. Fixes: f1ad1133b18f ("irqchip/sifive-plic: Add support for multiple PLICs") Signed-off-by: Anup Patel Signed-off-by: Marc Zyngier Reviewed-by: Palmer Dabbelt Acked-by: Palmer Dabbelt Cc: sta...@vger.kernel.org Link: https://lore.kernel.org/r/20200518091441.94843-3-anup.pa...@wdc.com --- drivers/irqchip/irq-sifive-plic.c | 14 -- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/irqchip/irq-sifive-plic.c b/drivers/irqchip/irq-sifive-plic.c index 9f7f8ce..6c54abf 100644 --- a/drivers/irqchip/irq-sifive-plic.c +++ b/drivers/irqchip/irq-sifive-plic.c @@ -76,6 +76,7 @@ struct plic_handler { void __iomem*enable_base; struct plic_priv*priv; }; +static bool plic_cpuhp_setup_done; static DEFINE_PER_CPU(struct plic_handler, plic_handlers); static inline void plic_toggle(struct plic_handler *handler, @@ -285,6 +286,7 @@ static int __init plic_init(struct device_node *node, int error = 0, nr_contexts, nr_handlers = 0, i; u32 nr_irqs; struct plic_priv *priv; + struct plic_handler *handler; priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (!priv) @@ -313,7 +315,6 @@ static int __init plic_init(struct device_node *node, for (i = 0; i < nr_contexts; i++) { struct of_phandle_args parent; - struct plic_handler *handler; irq_hw_number_t hwirq; int cpu, hartid; @@ -367,9 +368,18 @@ done: nr_handlers++; } - cpuhp_setup_state(CPUHP_AP_IRQ_SIFIVE_PLIC_STARTING, + /* +* We can have multiple PLIC instances so setup cpuhp state only +* when context handler for current/boot CPU is present. +*/ + handler = this_cpu_ptr(&plic_handlers); + if (handler->present && !plic_cpuhp_setup_done) { + cpuhp_setup_state(CPUHP_AP_IRQ_SIFIVE_PLIC_STARTING, "irqchip/sifive/plic:starting", plic_starting_cpu, plic_dying_cpu); + plic_cpuhp_setup_done = true; + } + pr_info("mapped %d interrupts with %d handlers for %d contexts.\n", nr_irqs, nr_handlers, nr_contexts); set_handle_irq(plic_handle_irq);
[tip: irq/core] irqchip/sifive-plic: Improve boot prints for multiple PLIC instances
The following commit has been merged into the irq/core branch of tip: Commit-ID: 0e375f51017bcc86c23979118b10445c424ef5ad Gitweb: https://git.kernel.org/tip/0e375f51017bcc86c23979118b10445c424ef5ad Author:Anup Patel AuthorDate:Mon, 18 May 2020 14:44:41 +05:30 Committer: Marc Zyngier CommitterDate: Mon, 25 May 2020 10:38:25 +01:00 irqchip/sifive-plic: Improve boot prints for multiple PLIC instances We improve PLIC banner to help distinguish multiple PLIC instances in boot time prints. Signed-off-by: Anup Patel Signed-off-by: Marc Zyngier Reviewed-by: Palmer Dabbelt Acked-by: Palmer Dabbelt Link: https://lore.kernel.org/r/20200518091441.94843-4-anup.pa...@wdc.com --- drivers/irqchip/irq-sifive-plic.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/irqchip/irq-sifive-plic.c b/drivers/irqchip/irq-sifive-plic.c index 6c54abf..d9c53f8 100644 --- a/drivers/irqchip/irq-sifive-plic.c +++ b/drivers/irqchip/irq-sifive-plic.c @@ -380,8 +380,8 @@ done: plic_cpuhp_setup_done = true; } - pr_info("mapped %d interrupts with %d handlers for %d contexts.\n", - nr_irqs, nr_handlers, nr_contexts); + pr_info("%pOFP: mapped %d interrupts with %d handlers for" + " %d contexts.\n", node, nr_irqs, nr_handlers, nr_contexts); set_handle_irq(plic_handle_irq); return 0;
[tip: irq/core] irqchip/gic-v3-its: Balance initial LPI affinity across CPUs
The following commit has been merged into the irq/core branch of tip: Commit-ID: c5d6082d35e0bcc20a26a067ffcfddcb5257e580 Gitweb: https://git.kernel.org/tip/c5d6082d35e0bcc20a26a067ffcfddcb5257e580 Author:Marc Zyngier AuthorDate:Fri, 15 May 2020 17:57:52 +01:00 Committer: Marc Zyngier CommitterDate: Wed, 20 May 2020 11:00:00 +01:00 irqchip/gic-v3-its: Balance initial LPI affinity across CPUs When mapping a LPI, the ITS driver picks the first possible affinity, which is in most cases CPU0, assuming that if that's not suitable, someone will come and set the affinity to something more interesting. It apparently isn't the case, and people complain of poor performance when many interrupts are glued to the same CPU. So let's place the interrupts by finding the "least loaded" CPU (that is, the one that has the fewer LPIs mapped to it). So called 'managed' interrupts are an interesting case where the affinity is actually dictated by the kernel itself, and we should honor this. Reported-by: John Garry Signed-off-by: Marc Zyngier Tested-by: John Garry Link: https://lore.kernel.org/r/1575642904-58295-1-git-send-email-john.ga...@huawei.com Link: https://lore.kernel.org/r/20200515165752.121296-3-...@kernel.org --- drivers/irqchip/irq-gic-v3-its.c | 127 +++--- 1 file changed, 100 insertions(+), 27 deletions(-) diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index 4eb8441..cd685f5 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -1541,15 +1541,104 @@ static void its_dec_lpi_count(struct irq_data *d, int cpu) atomic_dec(&per_cpu_ptr(&cpu_lpi_count, cpu)->unmanaged); } +static unsigned int cpumask_pick_least_loaded(struct irq_data *d, + const struct cpumask *cpu_mask) +{ + unsigned int cpu = nr_cpu_ids, tmp; + int count = S32_MAX; + + for_each_cpu(tmp, cpu_mask) { + int this_count = its_read_lpi_count(d, tmp); + if (this_count < count) { + cpu = tmp; + count = this_count; + } + } + + return cpu; +} + +/* + * As suggested by Thomas Gleixner in: + * https://lore.kernel.org/r/87h80q2aoc@nanos.tec.linutronix.de + */ +static int its_select_cpu(struct irq_data *d, + const struct cpumask *aff_mask) +{ + struct its_device *its_dev = irq_data_get_irq_chip_data(d); + cpumask_var_t tmpmask; + int cpu, node; + + if (!alloc_cpumask_var(&tmpmask, GFP_ATOMIC)) + return -ENOMEM; + + node = its_dev->its->numa_node; + + if (!irqd_affinity_is_managed(d)) { + /* First try the NUMA node */ + if (node != NUMA_NO_NODE) { + /* +* Try the intersection of the affinity mask and the +* node mask (and the online mask, just to be safe). +*/ + cpumask_and(tmpmask, cpumask_of_node(node), aff_mask); + cpumask_and(tmpmask, tmpmask, cpu_online_mask); + + /* +* Ideally, we would check if the mask is empty, and +* try again on the full node here. +* +* But it turns out that the way ACPI describes the +* affinity for ITSs only deals about memory, and +* not target CPUs, so it cannot describe a single +* ITS placed next to two NUMA nodes. +* +* Instead, just fallback on the online mask. This +* diverges from Thomas' suggestion above. +*/ + cpu = cpumask_pick_least_loaded(d, tmpmask); + if (cpu < nr_cpu_ids) + goto out; + + /* If we can't cross sockets, give up */ + if ((its_dev->its->flags & ITS_FLAGS_WORKAROUND_CAVIUM_23144)) + goto out; + + /* If the above failed, expand the search */ + } + + /* Try the intersection of the affinity and online masks */ + cpumask_and(tmpmask, aff_mask, cpu_online_mask); + + /* If that doesn't fly, the online mask is the last resort */ + if (cpumask_empty(tmpmask)) + cpumask_copy(tmpmask, cpu_online_mask); + + cpu = cpumask_pick_least_loaded(d, tmpmask); + } else { + cpumask_and(tmpmask, irq_data_get_affinity_mask(d), cpu_online_mask); + + /* If we cannot cross sockets, limit the search to that node */ + if ((its_dev->its->flags & ITS_FLAGS_WORKAROUND_CAVIUM_23144) && +
[tip: irq/core] irqdomain: Make irq_domain_reset_irq_data() available to non-hierarchical users
The following commit has been merged into the irq/core branch of tip: Commit-ID: 5c8f77a278737a6af44a892f0700d9aadb2b0de0 Gitweb: https://git.kernel.org/tip/5c8f77a278737a6af44a892f0700d9aadb2b0de0 Author:Bartosz Golaszewski AuthorDate:Thu, 14 May 2020 10:39:00 +02:00 Committer: Marc Zyngier CommitterDate: Mon, 18 May 2020 10:29:26 +01:00 irqdomain: Make irq_domain_reset_irq_data() available to non-hierarchical users irq_domain_reset_irq_data() doesn't modify the parent data, so it can be made available even if irq domain hierarchy is not being built. We'll subsequently use it in irq_sim code. Signed-off-by: Bartosz Golaszewski Signed-off-by: Marc Zyngier Reviewed-by: Linus Walleij Link: https://lore.kernel.org/r/20200514083901.23445-2-b...@bgdev.pl --- include/linux/irqdomain.h | 2 +- kernel/irq/irqdomain.c| 24 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h index 8d062e8..b37350c 100644 --- a/include/linux/irqdomain.h +++ b/include/linux/irqdomain.h @@ -450,6 +450,7 @@ extern void irq_domain_set_info(struct irq_domain *domain, unsigned int virq, irq_hw_number_t hwirq, struct irq_chip *chip, void *chip_data, irq_flow_handler_t handler, void *handler_data, const char *handler_name); +extern void irq_domain_reset_irq_data(struct irq_data *irq_data); #ifdef CONFIG_IRQ_DOMAIN_HIERARCHY extern struct irq_domain *irq_domain_create_hierarchy(struct irq_domain *parent, unsigned int flags, unsigned int size, @@ -491,7 +492,6 @@ extern int irq_domain_set_hwirq_and_chip(struct irq_domain *domain, irq_hw_number_t hwirq, struct irq_chip *chip, void *chip_data); -extern void irq_domain_reset_irq_data(struct irq_data *irq_data); extern void irq_domain_free_irqs_common(struct irq_domain *domain, unsigned int virq, unsigned int nr_irqs); diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c index 35b8d97..e2aa128 100644 --- a/kernel/irq/irqdomain.c +++ b/kernel/irq/irqdomain.c @@ -1047,6 +1047,18 @@ int irq_domain_alloc_descs(int virq, unsigned int cnt, irq_hw_number_t hwirq, return virq; } +/** + * irq_domain_reset_irq_data - Clear hwirq, chip and chip_data in @irq_data + * @irq_data: The pointer to irq_data + */ +void irq_domain_reset_irq_data(struct irq_data *irq_data) +{ + irq_data->hwirq = 0; + irq_data->chip = &no_irq_chip; + irq_data->chip_data = NULL; +} +EXPORT_SYMBOL_GPL(irq_domain_reset_irq_data); + #ifdef CONFIG_IRQ_DOMAIN_HIERARCHY /** * irq_domain_create_hierarchy - Add a irqdomain into the hierarchy @@ -1248,18 +1260,6 @@ void irq_domain_set_info(struct irq_domain *domain, unsigned int virq, EXPORT_SYMBOL(irq_domain_set_info); /** - * irq_domain_reset_irq_data - Clear hwirq, chip and chip_data in @irq_data - * @irq_data: The pointer to irq_data - */ -void irq_domain_reset_irq_data(struct irq_data *irq_data) -{ - irq_data->hwirq = 0; - irq_data->chip = &no_irq_chip; - irq_data->chip_data = NULL; -} -EXPORT_SYMBOL_GPL(irq_domain_reset_irq_data); - -/** * irq_domain_free_irqs_common - Clear irq_data and free the parent * @domain:Interrupt domain to match * @virq: IRQ number to start with
[tip: irq/core] platform-msi: Fix typos in comment
The following commit has been merged into the irq/core branch of tip: Commit-ID: ae0bb9fda405c881848f7f6e94d912b35f6e31d2 Gitweb: https://git.kernel.org/tip/ae0bb9fda405c881848f7f6e94d912b35f6e31d2 Author:Shaokun Zhang AuthorDate:Mon, 18 May 2020 11:00:59 +08:00 Committer: Marc Zyngier CommitterDate: Mon, 18 May 2020 10:28:30 +01:00 platform-msi: Fix typos in comment Fix up one typos @nev -> @nr_irqs. Signed-off-by: Shaokun Zhang Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/1589770859-19340-1-git-send-email-zhangshao...@hisilicon.com --- drivers/base/platform-msi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/base/platform-msi.c b/drivers/base/platform-msi.c index 8da314b..c4a17e5 100644 --- a/drivers/base/platform-msi.c +++ b/drivers/base/platform-msi.c @@ -387,7 +387,7 @@ void platform_msi_domain_free(struct irq_domain *domain, unsigned int virq, * * @domain:The platform-msi domain * @virq: The base irq from which to perform the allocate operation - * @nvec: How many interrupts to free from @virq + * @nr_irqs: How many interrupts to free from @virq * * Return 0 on success, or an error code on failure. Must be called * with irq_domain_mutex held (which can only be done as part of a
[tip: irq/core] irqchip/sifive-plic: Remove incorrect requirement about number of irq contexts
The following commit has been merged into the irq/core branch of tip: Commit-ID: 82f2202ddc97490994fad0dbfec04a014fa5163d Gitweb: https://git.kernel.org/tip/82f2202ddc97490994fad0dbfec04a014fa5163d Author:Wesley W. Terpstra AuthorDate:Tue, 12 May 2020 10:26:36 -07:00 Committer: Marc Zyngier CommitterDate: Mon, 18 May 2020 10:28:30 +01:00 irqchip/sifive-plic: Remove incorrect requirement about number of irq contexts A PLIC may not be connected to all the cores. In that case, nr_contexts may be less than num_possible_cpus. This requirement is only valid a single PLIC is the only interrupt controller for the whole system. Signed-off-by: Atish Patra Signed-off-by: "Wesley W. Terpstra" Signed-off-by: Marc Zyngier Reviewed-by: Palmer Dabbelt Acked-by: Palmer Dabbelt Link: https://lore.kernel.org/r/20200512172636.96299-1-atish.pa...@wdc.com [Atish: Modified the commit text] --- drivers/irqchip/irq-sifive-plic.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/irqchip/irq-sifive-plic.c b/drivers/irqchip/irq-sifive-plic.c index d0a71fe..822e074 100644 --- a/drivers/irqchip/irq-sifive-plic.c +++ b/drivers/irqchip/irq-sifive-plic.c @@ -301,8 +301,6 @@ static int __init plic_init(struct device_node *node, nr_contexts = of_irq_count(node); if (WARN_ON(!nr_contexts)) goto out_iounmap; - if (WARN_ON(nr_contexts < num_possible_cpus())) - goto out_iounmap; error = -ENOMEM; priv->irqdomain = irq_domain_add_linear(node, nr_irqs + 1,
[tip: irq/core] genirq/irq_sim: Simplify the API
The following commit has been merged into the irq/core branch of tip: Commit-ID: 337cbeb2c13eb4cab84f576fd402d7ae4ed31ae1 Gitweb: https://git.kernel.org/tip/337cbeb2c13eb4cab84f576fd402d7ae4ed31ae1 Author:Bartosz Golaszewski AuthorDate:Thu, 14 May 2020 10:39:01 +02:00 Committer: Marc Zyngier CommitterDate: Mon, 18 May 2020 10:30:21 +01:00 genirq/irq_sim: Simplify the API The interrupt simulator API exposes a lot of custom data structures and functions and doesn't reuse the interfaces already exposed by the irq subsystem. This patch tries to address it. We hide all the simulator-related data structures from users and instead rely on the well-known irq domain. When creating the interrupt simulator the user receives a pointer to a newly created irq_domain and can use it to create mappings for simulated interrupts. It is also possible to pass a handle to fwnode when creating the simulator domain and retrieve it using irq_find_matching_fwnode(). The irq_sim_fire() function is dropped as well. Instead we implement the irq_get/set_irqchip_state interface. We modify the two modules that use the simulator at the same time as adding these changes in order to reduce the intermediate bloat that would result when trying to migrate the drivers in separate patches. Signed-off-by: Bartosz Golaszewski Signed-off-by: Marc Zyngier Reviewed-by: Linus Walleij Acked-by: Jonathan Cameron #for IIO Link: https://lore.kernel.org/r/20200514083901.23445-3-b...@bgdev.pl --- drivers/gpio/gpio-mockup.c | 53 +++-- drivers/iio/dummy/iio_dummy_evgen.c | 34 +-- include/linux/irq_sim.h | 33 +--- kernel/irq/Kconfig | 1 +- kernel/irq/irq_sim.c| 267 --- 5 files changed, 237 insertions(+), 151 deletions(-) diff --git a/drivers/gpio/gpio-mockup.c b/drivers/gpio/gpio-mockup.c index 3eb94f3..bc34518 100644 --- a/drivers/gpio/gpio-mockup.c +++ b/drivers/gpio/gpio-mockup.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -48,7 +49,7 @@ struct gpio_mockup_line_status { struct gpio_mockup_chip { struct gpio_chip gc; struct gpio_mockup_line_status *lines; - struct irq_sim irqsim; + struct irq_domain *irq_sim_domain; struct dentry *dbg_dir; struct mutex lock; }; @@ -144,14 +145,12 @@ static void gpio_mockup_set_multiple(struct gpio_chip *gc, static int gpio_mockup_apply_pull(struct gpio_mockup_chip *chip, unsigned int offset, int value) { + int curr, irq, irq_type, ret = 0; struct gpio_desc *desc; struct gpio_chip *gc; - struct irq_sim *sim; - int curr, irq, irq_type; gc = &chip->gc; desc = &gc->gpiodev->descs[offset]; - sim = &chip->irqsim; mutex_lock(&chip->lock); @@ -161,14 +160,28 @@ static int gpio_mockup_apply_pull(struct gpio_mockup_chip *chip, if (curr == value) goto out; - irq = irq_sim_irqnum(sim, offset); + irq = irq_find_mapping(chip->irq_sim_domain, offset); + if (!irq) + /* +* This is fine - it just means, nobody is listening +* for interrupts on this line, otherwise +* irq_create_mapping() would have been called from +* the to_irq() callback. +*/ + goto set_value; + irq_type = irq_get_trigger_type(irq); if ((value == 1 && (irq_type & IRQ_TYPE_EDGE_RISING)) || - (value == 0 && (irq_type & IRQ_TYPE_EDGE_FALLING))) - irq_sim_fire(sim, offset); + (value == 0 && (irq_type & IRQ_TYPE_EDGE_FALLING))) { + ret = irq_set_irqchip_state(irq, IRQCHIP_STATE_PENDING, + true); + if (ret) + goto out; + } } +set_value: /* Change the value unless we're actively driving the line. */ if (!test_bit(FLAG_REQUESTED, &desc->flags) || !test_bit(FLAG_IS_OUT, &desc->flags)) @@ -177,7 +190,7 @@ static int gpio_mockup_apply_pull(struct gpio_mockup_chip *chip, out: chip->lines[offset].pull = value; mutex_unlock(&chip->lock); - return 0; + return ret; } static int gpio_mockup_set_config(struct gpio_chip *gc, @@ -236,7 +249,7 @@ static int gpio_mockup_to_irq(struct gpio_chip *gc, unsigned int offset) { struct gpio_mockup_chip *chip = gpiochip_get_data(gc); - return irq_sim_irqnum(&chip->irqsim, offset); + return irq_create_mapping(chip->irq_sim_domain, offset); } static void gpio_mockup_free(struct gpio_chip *gc, unsigned int offset) @@ -389,6 +402,19 @@ static int gpio_mockup_
[tip: irq/core] irqdomain: Get rid of special treatment for ACPI in __irq_domain_add()
The following commit has been merged into the irq/core branch of tip: Commit-ID: 87526603c89256e18ad2c23821fdaf376b072fc8 Gitweb: https://git.kernel.org/tip/87526603c89256e18ad2c23821fdaf376b072fc8 Author:Andy Shevchenko AuthorDate:Wed, 20 May 2020 19:49:26 +03:00 Committer: Marc Zyngier CommitterDate: Thu, 21 May 2020 10:51:50 +01:00 irqdomain: Get rid of special treatment for ACPI in __irq_domain_add() Now that __irq_domain_add() is able to better deals with generic fwnodes, there is no need to special-case ACPI anymore. Get rid of the special treatment for ACPI. Signed-off-by: Andy Shevchenko Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20200520164927.39090-2-andriy.shevche...@linux.intel.com --- kernel/irq/irqdomain.c | 17 + 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c index 7649f38..5d14d91 100644 --- a/kernel/irq/irqdomain.c +++ b/kernel/irq/irqdomain.c @@ -161,22 +161,7 @@ struct irq_domain *__irq_domain_add(struct fwnode_handle *fwnode, int size, domain->name = fwid->name; break; } -#ifdef CONFIG_ACPI - } else if (is_acpi_device_node(fwnode)) { - struct acpi_buffer buf = { - .length = ACPI_ALLOCATE_BUFFER, - }; - acpi_handle handle; - - handle = acpi_device_handle(to_acpi_device_node(fwnode)); - if (acpi_get_name(handle, ACPI_FULL_PATHNAME, &buf) == AE_OK) { - domain->name = buf.pointer; - domain->flags |= IRQ_DOMAIN_NAME_ALLOCATED; - } - - domain->fwnode = fwnode; -#endif - } else if (is_of_node(fwnode)) { + } else if (is_of_node(fwnode) || is_acpi_device_node(fwnode)) { char *name; /*
[tip: irq/core] irqchip/gic-v3-its: Track LPI distribution on a per CPU basis
The following commit has been merged into the irq/core branch of tip: Commit-ID: 2f13ff1d1d5c0257c97ea76b86a2d9c99c44a4b9 Gitweb: https://git.kernel.org/tip/2f13ff1d1d5c0257c97ea76b86a2d9c99c44a4b9 Author:Marc Zyngier AuthorDate:Fri, 15 May 2020 17:57:51 +01:00 Committer: Marc Zyngier CommitterDate: Mon, 18 May 2020 10:30:42 +01:00 irqchip/gic-v3-its: Track LPI distribution on a per CPU basis In order to improve the distribution of LPIs among CPUs, let start by tracking the number of LPIs assigned to CPUs, both for managed and non-managed interrupts (as separate counters). Signed-off-by: Marc Zyngier Tested-by: John Garry Link: https://lore.kernel.org/r/20200515165752.121296-2-...@kernel.org --- drivers/irqchip/irq-gic-v3-its.c | 49 +-- 1 file changed, 46 insertions(+), 3 deletions(-) diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index 124251b..4eb8441 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -174,6 +174,13 @@ static struct { int next_victim; } vpe_proxy; +struct cpu_lpi_count { + atomic_tmanaged; + atomic_tunmanaged; +}; + +static DEFINE_PER_CPU(struct cpu_lpi_count, cpu_lpi_count); + static LIST_HEAD(its_nodes); static DEFINE_RAW_SPINLOCK(its_lock); static struct rdists *gic_rdists; @@ -1510,6 +1517,30 @@ static void its_unmask_irq(struct irq_data *d) lpi_update_config(d, 0, LPI_PROP_ENABLED); } +static __maybe_unused u32 its_read_lpi_count(struct irq_data *d, int cpu) +{ + if (irqd_affinity_is_managed(d)) + return atomic_read(&per_cpu_ptr(&cpu_lpi_count, cpu)->managed); + + return atomic_read(&per_cpu_ptr(&cpu_lpi_count, cpu)->unmanaged); +} + +static void its_inc_lpi_count(struct irq_data *d, int cpu) +{ + if (irqd_affinity_is_managed(d)) + atomic_inc(&per_cpu_ptr(&cpu_lpi_count, cpu)->managed); + else + atomic_inc(&per_cpu_ptr(&cpu_lpi_count, cpu)->unmanaged); +} + +static void its_dec_lpi_count(struct irq_data *d, int cpu) +{ + if (irqd_affinity_is_managed(d)) + atomic_dec(&per_cpu_ptr(&cpu_lpi_count, cpu)->managed); + else + atomic_dec(&per_cpu_ptr(&cpu_lpi_count, cpu)->unmanaged); +} + static int its_set_affinity(struct irq_data *d, const struct cpumask *mask_val, bool force) { @@ -1518,34 +1549,44 @@ static int its_set_affinity(struct irq_data *d, const struct cpumask *mask_val, struct its_device *its_dev = irq_data_get_irq_chip_data(d); struct its_collection *target_col; u32 id = its_get_event_id(d); + int prev_cpu; /* A forwarded interrupt should use irq_set_vcpu_affinity */ if (irqd_is_forwarded_to_vcpu(d)) return -EINVAL; + prev_cpu = its_dev->event_map.col_map[id]; + its_dec_lpi_count(d, prev_cpu); + /* lpi cannot be routed to a redistributor that is on a foreign node */ if (its_dev->its->flags & ITS_FLAGS_WORKAROUND_CAVIUM_23144) { if (its_dev->its->numa_node >= 0) { cpu_mask = cpumask_of_node(its_dev->its->numa_node); if (!cpumask_intersects(mask_val, cpu_mask)) - return -EINVAL; + goto err; } } cpu = cpumask_any_and(mask_val, cpu_mask); if (cpu >= nr_cpu_ids) - return -EINVAL; + goto err; /* don't set the affinity when the target cpu is same as current one */ - if (cpu != its_dev->event_map.col_map[id]) { + if (cpu != prev_cpu) { target_col = &its_dev->its->collections[cpu]; its_send_movi(its_dev, target_col, id); its_dev->event_map.col_map[id] = cpu; irq_data_update_effective_affinity(d, cpumask_of(cpu)); } + its_inc_lpi_count(d, cpu); + return IRQ_SET_MASK_OK_DONE; + +err: + its_inc_lpi_count(d, prev_cpu); + return -EINVAL; } static u64 its_irq_get_msi_base(struct its_device *its_dev) @@ -3448,6 +3489,7 @@ static int its_irq_domain_activate(struct irq_domain *domain, cpu = cpumask_first(cpu_online_mask); } + its_inc_lpi_count(d, cpu); its_dev->event_map.col_map[event] = cpu; irq_data_update_effective_affinity(d, cpumask_of(cpu)); @@ -3462,6 +3504,7 @@ static void its_irq_domain_deactivate(struct irq_domain *domain, struct its_device *its_dev = irq_data_get_irq_chip_data(d); u32 event = its_get_event_id(d); + its_dec_lpi_count(d, its_dev->event_map.col_map[event]); /* Stop the delivery of interrupts */ its_send_discard(its_dev, event); }
[tip: irq/core] irqchip/gic-v3: Fix missing "__init" for gic_smp_init()
The following commit has been merged into the irq/core branch of tip: Commit-ID: 8a94c1ab34d53476617f83610521cfb6674db8d4 Gitweb: https://git.kernel.org/tip/8a94c1ab34d53476617f83610521cfb6674db8d4 Author:Ingo Rohloff AuthorDate:Wed, 22 Apr 2020 13:28:57 +02:00 Committer: Marc Zyngier CommitterDate: Mon, 18 May 2020 10:28:30 +01:00 irqchip/gic-v3: Fix missing "__init" for gic_smp_init() With an SMP configuration, gic_smp_init() calls set_smp_cross_call(). set_smp_cross_call() is marked with "__init". So gic_smp_init() should also be marked with "__init". gic_smp_init() is only called from gic_init_bases(). gic_init_bases() is also marked with "__init"; So marking gic_smp_init() with "__init" is fine. Signed-off-by: Ingo Rohloff Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20200422112857.4300-1-ingo.rohl...@lauterbach.com --- drivers/irqchip/irq-gic-v3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index d7006ef..98c886d 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c @@ -1150,7 +1150,7 @@ static void gic_raise_softirq(const struct cpumask *mask, unsigned int irq) isb(); } -static void gic_smp_init(void) +static void __init gic_smp_init(void) { set_smp_cross_call(gic_raise_softirq); cpuhp_setup_state_nocalls(CPUHP_AP_IRQ_GIC_STARTING,
[tip: irq/core] irqdomain: Allow software nodes for IRQ domain creation
The following commit has been merged into the irq/core branch of tip: Commit-ID: 9ed78b05f998050784ae863bd5ba4aea2e2141ed Gitweb: https://git.kernel.org/tip/9ed78b05f998050784ae863bd5ba4aea2e2141ed Author:Andy Shevchenko AuthorDate:Wed, 20 May 2020 19:49:27 +03:00 Committer: Marc Zyngier CommitterDate: Thu, 21 May 2020 10:53:17 +01:00 irqdomain: Allow software nodes for IRQ domain creation In some cases we need to have an IRQ domain created out of software node. One of such cases is DesignWare GPIO driver when it's instantiated from half-baked ACPI table (alas, we can't fix it for devices which are few years on market) and thus using software nodes to quirk this. But the driver is using IRQ domains based on per GPIO port firmware nodes, which are in the above case software ones. This brings a warning message to be printed [ 73.957183] irq: Invalid fwnode type for irqdomain and creates an anonymous IRQ domain without a debugfs entry. Allowing software nodes to be valid for IRQ domains rids us of the warning and debugs gets correctly populated. % ls -1 /sys/kernel/debug/irq/domains/ ... intel-quark-dw-apb-gpio:portA Signed-off-by: Andy Shevchenko [maz: refactored commit message] Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20200520164927.39090-3-andriy.shevche...@linux.intel.com --- kernel/irq/irqdomain.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c index 5d14d91..a4c2c91 100644 --- a/kernel/irq/irqdomain.c +++ b/kernel/irq/irqdomain.c @@ -161,7 +161,8 @@ struct irq_domain *__irq_domain_add(struct fwnode_handle *fwnode, int size, domain->name = fwid->name; break; } - } else if (is_of_node(fwnode) || is_acpi_device_node(fwnode)) { + } else if (is_of_node(fwnode) || is_acpi_device_node(fwnode) || + is_software_node(fwnode)) { char *name; /*
[tip: irq/core] iio: dummy_evgen: Fix use after free on error in iio_dummy_evgen_create()
The following commit has been merged into the irq/core branch of tip: Commit-ID: 128516e49de67d10d52fba62ef8d482b220ac4b0 Gitweb: https://git.kernel.org/tip/128516e49de67d10d52fba62ef8d482b220ac4b0 Author:Dan Carpenter AuthorDate:Wed, 20 May 2020 15:03:06 +03:00 Committer: Marc Zyngier CommitterDate: Wed, 20 May 2020 13:11:41 +01:00 iio: dummy_evgen: Fix use after free on error in iio_dummy_evgen_create() We need to preserve the "iio_evgen->irq_sim_domain" error code before we free "iio_evgen" otherwise it leads to a use after free. Fixes: 337cbeb2c13e ("genirq/irq_sim: Simplify the API") Signed-off-by: Dan Carpenter Signed-off-by: Marc Zyngier --- drivers/iio/dummy/iio_dummy_evgen.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/iio/dummy/iio_dummy_evgen.c b/drivers/iio/dummy/iio_dummy_evgen.c index 409fe0f..ee85d59 100644 --- a/drivers/iio/dummy/iio_dummy_evgen.c +++ b/drivers/iio/dummy/iio_dummy_evgen.c @@ -45,6 +45,8 @@ static struct iio_dummy_eventgen *iio_evgen; static int iio_dummy_evgen_create(void) { + int ret; + iio_evgen = kzalloc(sizeof(*iio_evgen), GFP_KERNEL); if (!iio_evgen) return -ENOMEM; @@ -52,8 +54,9 @@ static int iio_dummy_evgen_create(void) iio_evgen->irq_sim_domain = irq_domain_create_sim(NULL, IIO_EVENTGEN_NO); if (IS_ERR(iio_evgen->irq_sim_domain)) { + ret = PTR_ERR(iio_evgen->irq_sim_domain); kfree(iio_evgen); - return PTR_ERR(iio_evgen->irq_sim_domain); + return ret; } mutex_init(&iio_evgen->lock);
[tip: irq/core] irqdomain: Make __irq_domain_add() less OF-dependent
The following commit has been merged into the irq/core branch of tip: Commit-ID: 181e9d4efaf6aa8d1e7d510aeb7114c0f276fad7 Gitweb: https://git.kernel.org/tip/181e9d4efaf6aa8d1e7d510aeb7114c0f276fad7 Author:Andy Shevchenko AuthorDate:Wed, 20 May 2020 19:49:25 +03:00 Committer: Marc Zyngier CommitterDate: Thu, 21 May 2020 10:50:30 +01:00 irqdomain: Make __irq_domain_add() less OF-dependent __irq_domain_add() relies in some places on the fact that the fwnode can be only of type OF. This prevents refactoring of the code to support other types of fwnode. Make it less OF-dependent by switching it to use the fwnode directly where it makes sense. Signed-off-by: Andy Shevchenko Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20200520164927.39090-1-andriy.shevche...@linux.intel.com --- kernel/irq/irqdomain.c | 13 ++--- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c index e2aa128..7649f38 100644 --- a/kernel/irq/irqdomain.c +++ b/kernel/irq/irqdomain.c @@ -132,14 +132,13 @@ struct irq_domain *__irq_domain_add(struct fwnode_handle *fwnode, int size, const struct irq_domain_ops *ops, void *host_data) { - struct device_node *of_node = to_of_node(fwnode); struct irqchip_fwid *fwid; struct irq_domain *domain; static atomic_t unknown_domains; domain = kzalloc_node(sizeof(*domain) + (sizeof(unsigned int) * size), - GFP_KERNEL, of_node_to_nid(of_node)); + GFP_KERNEL, of_node_to_nid(to_of_node(fwnode))); if (!domain) return NULL; @@ -177,15 +176,15 @@ struct irq_domain *__irq_domain_add(struct fwnode_handle *fwnode, int size, domain->fwnode = fwnode; #endif - } else if (of_node) { + } else if (is_of_node(fwnode)) { char *name; /* -* DT paths contain '/', which debugfs is legitimately +* fwnode paths contain '/', which debugfs is legitimately * unhappy about. Replace them with ':', which does * the trick and is not as offensive as '\'... */ - name = kasprintf(GFP_KERNEL, "%pOF", of_node); + name = kasprintf(GFP_KERNEL, "%pfw", fwnode); if (!name) { kfree(domain); return NULL; @@ -210,7 +209,7 @@ struct irq_domain *__irq_domain_add(struct fwnode_handle *fwnode, int size, domain->flags |= IRQ_DOMAIN_NAME_ALLOCATED; } - of_node_get(of_node); + fwnode_handle_get(fwnode); /* Fill structure */ INIT_RADIX_TREE(&domain->revmap_tree, GFP_KERNEL); @@ -259,7 +258,7 @@ void irq_domain_remove(struct irq_domain *domain) pr_debug("Removed domain %s\n", domain->name); - of_node_put(irq_domain_get_of_node(domain)); + fwnode_handle_put(domain->fwnode); if (domain->flags & IRQ_DOMAIN_NAME_ALLOCATED) kfree(domain->name); kfree(domain);
[tip: irq/core] irqchip/gic-v2, v3: Drop extra IRQ_NOAUTOEN setting for (E)PPIs
The following commit has been merged into the irq/core branch of tip: Commit-ID: cc86432aa8cc5a81f99d79eea2a29099da694df3 Gitweb: https://git.kernel.org/tip/cc86432aa8cc5a81f99d79eea2a29099da694df3 Author:Valentin Schneider AuthorDate:Thu, 21 May 2020 23:35:00 +01:00 Committer: Marc Zyngier CommitterDate: Mon, 25 May 2020 10:32:51 +01:00 irqchip/gic-v2, v3: Drop extra IRQ_NOAUTOEN setting for (E)PPIs (E)PPIs are per-CPU interrupts, so we want each CPU to go and enable them via enable_percpu_irq(); this also means we want IRQ_NOAUTOEN for them as the autoenable would lead to calling irq_enable() instead of the more appropriate irq_percpu_enable(). Calling irq_set_percpu_devid() is enough to get just that since it trickles down to irq_set_percpu_devid_flags(), which gives us IRQ_NOAUTOEN (and a few others). Setting IRQ_NOAUTOEN *again* right after this call is just redundant, so don't do it. Signed-off-by: Valentin Schneider Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20200521223500.834-1-valentin.schnei...@arm.com --- drivers/irqchip/irq-gic-v3.c | 1 - drivers/irqchip/irq-gic.c| 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index 98c886d..cc46bc2 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c @@ -1282,7 +1282,6 @@ static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq, irq_set_percpu_devid(irq); irq_domain_set_info(d, irq, hw, chip, d->host_data, handle_percpu_devid_irq, NULL, NULL); - irq_set_status_flags(irq, IRQ_NOAUTOEN); break; case SPI_RANGE: diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index 30ab623..00de05a 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c @@ -982,7 +982,6 @@ static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq, irq_set_percpu_devid(irq); irq_domain_set_info(d, irq, hw, &gic->chip, d->host_data, handle_percpu_devid_irq, NULL, NULL); - irq_set_status_flags(irq, IRQ_NOAUTOEN); } else { irq_domain_set_info(d, irq, hw, &gic->chip, d->host_data, handle_fasteoi_irq, NULL, NULL);
[tip: irq/core] irqchip: Add Loongson HyperTransport Vector support
The following commit has been merged into the irq/core branch of tip: Commit-ID: 818e915fbac518e8c78e1877a0048d92d4965e5a Gitweb: https://git.kernel.org/tip/818e915fbac518e8c78e1877a0048d92d4965e5a Author:Jiaxun Yang AuthorDate:Thu, 28 May 2020 23:27:49 +08:00 Committer: Marc Zyngier CommitterDate: Fri, 29 May 2020 09:42:18 +01:00 irqchip: Add Loongson HyperTransport Vector support This controller appears on Loongson-3 chips for receiving interrupt vectors from PCH's PIC and PCH's PCIe MSI interrupts. Signed-off-by: Jiaxun Yang Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20200528152757.1028711-2-jiaxun.y...@flygoat.com --- drivers/irqchip/Kconfig | 8 +- drivers/irqchip/Makefile | 1 +- drivers/irqchip/irq-loongson-htvec.c | 214 ++- 3 files changed, 223 insertions(+) create mode 100644 drivers/irqchip/irq-loongson-htvec.c diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index a85aada..de4564e 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig @@ -532,4 +532,12 @@ config LOONGSON_HTPIC help Support for the Loongson-3 HyperTransport PIC Controller. +config LOONGSON_HTVEC + bool "Loongson3 HyperTransport Interrupt Vector Controller" + depends on MACH_LOONGSON64 || COMPILE_TEST + default MACH_LOONGSON64 + select IRQ_DOMAIN_HIERARCHY + help + Support for the Loongson3 HyperTransport Interrupt Vector Controller. + endmenu diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index 37bbe39..7456187 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile @@ -107,3 +107,4 @@ obj-$(CONFIG_TI_SCI_INTR_IRQCHIP) += irq-ti-sci-intr.o obj-$(CONFIG_TI_SCI_INTA_IRQCHIP) += irq-ti-sci-inta.o obj-$(CONFIG_LOONGSON_LIOINTC) += irq-loongson-liointc.o obj-$(CONFIG_LOONGSON_HTPIC) += irq-loongson-htpic.o +obj-$(CONFIG_LOONGSON_HTVEC) += irq-loongson-htvec.o diff --git a/drivers/irqchip/irq-loongson-htvec.c b/drivers/irqchip/irq-loongson-htvec.c new file mode 100644 index 000..1ece933 --- /dev/null +++ b/drivers/irqchip/irq-loongson-htvec.c @@ -0,0 +1,214 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2020, Jiaxun Yang + * Loongson HyperTransport Interrupt Vector support + */ + +#define pr_fmt(fmt) "htvec: " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Registers */ +#define HTVEC_EN_OFF 0x20 +#define HTVEC_MAX_PARENT_IRQ 4 + +#define VEC_COUNT_PER_REG 32 +#define VEC_REG_COUNT 4 +#define VEC_COUNT (VEC_COUNT_PER_REG * VEC_REG_COUNT) +#define VEC_REG_IDX(irq_id)((irq_id) / VEC_COUNT_PER_REG) +#define VEC_REG_BIT(irq_id)((irq_id) % VEC_COUNT_PER_REG) + +struct htvec { + void __iomem*base; + struct irq_domain *htvec_domain; + raw_spinlock_t htvec_lock; +}; + +static void htvec_irq_dispatch(struct irq_desc *desc) +{ + int i; + u32 pending; + bool handled = false; + struct irq_chip *chip = irq_desc_get_chip(desc); + struct htvec *priv = irq_desc_get_handler_data(desc); + + chained_irq_enter(chip, desc); + + for (i = 0; i < VEC_REG_COUNT; i++) { + pending = readl(priv->base + 4 * i); + while (pending) { + int bit = __ffs(pending); + + generic_handle_irq(irq_linear_revmap(priv->htvec_domain, bit + +VEC_COUNT_PER_REG * i)); + pending &= ~BIT(bit); + handled = true; + } + } + + if (!handled) + spurious_interrupt(); + + chained_irq_exit(chip, desc); +} + +static void htvec_ack_irq(struct irq_data *d) +{ + struct htvec *priv = irq_data_get_irq_chip_data(d); + + writel(BIT(VEC_REG_BIT(d->hwirq)), + priv->base + VEC_REG_IDX(d->hwirq) * 4); +} + +static void htvec_mask_irq(struct irq_data *d) +{ + u32 reg; + void __iomem *addr; + struct htvec *priv = irq_data_get_irq_chip_data(d); + + raw_spin_lock(&priv->htvec_lock); + addr = priv->base + HTVEC_EN_OFF; + addr += VEC_REG_IDX(d->hwirq) * 4; + reg = readl(addr); + reg &= ~BIT(VEC_REG_BIT(d->hwirq)); + writel(reg, addr); + raw_spin_unlock(&priv->htvec_lock); +} + +static void htvec_unmask_irq(struct irq_data *d) +{ + u32 reg; + void __iomem *addr; + struct htvec *priv = irq_data_get_irq_chip_data(d); + + raw_spin_lock(&priv->htvec_lock); + addr = priv->base + HTVEC_EN_OFF; + addr += VEC_REG_IDX(d->hwirq) * 4; + reg = readl(addr); + reg |= BIT(VEC_REG_BIT(d->hwirq)); + writel(reg, addr); + raw_spin_unlock(&priv->htvec_lock); +} + +static struct irq_ch
[tip: irq/core] irqchip/sifive-plic: Set default irq affinity in plic_irqdomain_map()
The following commit has been merged into the irq/core branch of tip: Commit-ID: 2458ed31e9b9ab40d78a452ab2650a0857556e85 Gitweb: https://git.kernel.org/tip/2458ed31e9b9ab40d78a452ab2650a0857556e85 Author:Anup Patel AuthorDate:Mon, 18 May 2020 14:44:39 +05:30 Committer: Marc Zyngier CommitterDate: Mon, 25 May 2020 10:36:09 +01:00 irqchip/sifive-plic: Set default irq affinity in plic_irqdomain_map() For multiple PLIC instances, each PLIC can only target a subset of CPUs which is represented by "lmask" in the "struct plic_priv". Currently, the default irq affinity for each PLIC interrupt is all online CPUs which is illegal value for default irq affinity when we have multiple PLIC instances. To fix this, we now set "lmask" as the default irq affinity in for each interrupt in plic_irqdomain_map(). Fixes: f1ad1133b18f ("irqchip/sifive-plic: Add support for multiple PLICs") Signed-off-by: Anup Patel Signed-off-by: Marc Zyngier Reviewed-by: Palmer Dabbelt Acked-by: Palmer Dabbelt Cc: sta...@vger.kernel.org Link: https://lore.kernel.org/r/20200518091441.94843-2-anup.pa...@wdc.com --- drivers/irqchip/irq-sifive-plic.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/irqchip/irq-sifive-plic.c b/drivers/irqchip/irq-sifive-plic.c index 822e074..9f7f8ce 100644 --- a/drivers/irqchip/irq-sifive-plic.c +++ b/drivers/irqchip/irq-sifive-plic.c @@ -176,9 +176,12 @@ static struct irq_chip plic_chip = { static int plic_irqdomain_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hwirq) { + struct plic_priv *priv = d->host_data; + irq_domain_set_info(d, irq, hwirq, &plic_chip, d->host_data, handle_fasteoi_irq, NULL, NULL); irq_set_noprobe(irq); + irq_set_affinity(irq, &priv->lmask); return 0; }
[tip: irq/core] dt-bindings: interrupt-controller: Add Loongson HTVEC
The following commit has been merged into the irq/core branch of tip: Commit-ID: 6c2832c3c6edc38ab58bad29731b4951c0a90cf8 Gitweb: https://git.kernel.org/tip/6c2832c3c6edc38ab58bad29731b4951c0a90cf8 Author:Jiaxun Yang AuthorDate:Thu, 28 May 2020 23:27:50 +08:00 Committer: Marc Zyngier CommitterDate: Fri, 29 May 2020 09:42:18 +01:00 dt-bindings: interrupt-controller: Add Loongson HTVEC Add binding for Loongson-3 HyperTransport Interrupt Vector Controller. Reviewed-by: Rob Herring Signed-off-by: Jiaxun Yang Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20200528152757.1028711-3-jiaxun.y...@flygoat.com --- Documentation/devicetree/bindings/interrupt-controller/loongson,htvec.yaml | 57 + 1 file changed, 57 insertions(+) create mode 100644 Documentation/devicetree/bindings/interrupt-controller/loongson,htvec.yaml diff --git a/Documentation/devicetree/bindings/interrupt-controller/loongson,htvec.yaml b/Documentation/devicetree/bindings/interrupt-controller/loongson,htvec.yaml new file mode 100644 index 000..e865cd8 --- /dev/null +++ b/Documentation/devicetree/bindings/interrupt-controller/loongson,htvec.yaml @@ -0,0 +1,57 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: "http://devicetree.org/schemas/interrupt-controller/loongson,htvec.yaml#"; +$schema: "http://devicetree.org/meta-schemas/core.yaml#"; + +title: Loongson-3 HyperTransport Interrupt Vector Controller + +maintainers: + - Jiaxun Yang + +description: + This interrupt controller is found in the Loongson-3 family of chips for + receiving vectorized interrupts from PCH's interrupt controller. + +properties: + compatible: +const: loongson,htvec-1.0 + + reg: +maxItems: 1 + + interrupts: +minItems: 1 +maxItems: 4 +description: Four parent interrupts that receive chained interrupts. + + interrupt-controller: true + + '#interrupt-cells': +const: 1 + +required: + - compatible + - reg + - interrupts + - interrupt-controller + - '#interrupt-cells' + +additionalProperties: false + +examples: + - | +#include +htvec: interrupt-controller@fb80 { + compatible = "loongson,htvec-1.0"; + reg = <0xfb80 0x40>; + interrupt-controller; + #interrupt-cells = <1>; + + interrupt-parent = <&liointc>; + interrupts = <24 IRQ_TYPE_LEVEL_HIGH>, +<25 IRQ_TYPE_LEVEL_HIGH>, +<26 IRQ_TYPE_LEVEL_HIGH>, +<27 IRQ_TYPE_LEVEL_HIGH>; +}; +...
[tip: irq/core] dt-bindings: interrupt-controller: Add Loongson PCH PIC
The following commit has been merged into the irq/core branch of tip: Commit-ID: b6e4bc125fc517969f97d901b1845ebf47bbea26 Gitweb: https://git.kernel.org/tip/b6e4bc125fc517969f97d901b1845ebf47bbea26 Author:Jiaxun Yang AuthorDate:Thu, 28 May 2020 23:27:52 +08:00 Committer: Marc Zyngier CommitterDate: Fri, 29 May 2020 09:42:18 +01:00 dt-bindings: interrupt-controller: Add Loongson PCH PIC Add binding for Loongson PCH PIC Controller. Reviewed-by: Rob Herring Signed-off-by: Jiaxun Yang Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20200528152757.1028711-5-jiaxun.y...@flygoat.com --- Documentation/devicetree/bindings/interrupt-controller/loongson,pch-pic.yaml | 56 1 file changed, 56 insertions(+) create mode 100644 Documentation/devicetree/bindings/interrupt-controller/loongson,pch-pic.yaml diff --git a/Documentation/devicetree/bindings/interrupt-controller/loongson,pch-pic.yaml b/Documentation/devicetree/bindings/interrupt-controller/loongson,pch-pic.yaml new file mode 100644 index 000..274adea --- /dev/null +++ b/Documentation/devicetree/bindings/interrupt-controller/loongson,pch-pic.yaml @@ -0,0 +1,56 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: "http://devicetree.org/schemas/interrupt-controller/loongson,pch-pic.yaml#"; +$schema: "http://devicetree.org/meta-schemas/core.yaml#"; + +title: Loongson PCH PIC Controller + +maintainers: + - Jiaxun Yang + +description: + This interrupt controller is found in the Loongson LS7A family of PCH for + transforming interrupts from on-chip devices into HyperTransport vectorized + interrupts. + +properties: + compatible: +const: loongson,pch-pic-1.0 + + reg: +maxItems: 1 + + loongson,pic-base-vec: +description: + u32 value of the base of parent HyperTransport vector allocated + to PCH PIC. +allOf: + - $ref: "/schemas/types.yaml#/definitions/uint32" + - minimum: 0 +maximum: 192 + + interrupt-controller: true + + '#interrupt-cells': +const: 2 + +required: + - compatible + - reg + - loongson,pic-base-vec + - interrupt-controller + - '#interrupt-cells' + +examples: + - | +#include +pic: interrupt-controller@1000 { + compatible = "loongson,pch-pic-1.0"; + reg = <0x1000 0x400>; + interrupt-controller; + #interrupt-cells = <2>; + loongson,pic-base-vec = <64>; + interrupt-parent = <&htvec>; +}; +...
[tip: irq/core] irqchip: Add Loongson PCH MSI controller
The following commit has been merged into the irq/core branch of tip: Commit-ID: 632dcc2c75ef6de3272aa4ddd8f19da1f1ace323 Gitweb: https://git.kernel.org/tip/632dcc2c75ef6de3272aa4ddd8f19da1f1ace323 Author:Jiaxun Yang AuthorDate:Thu, 28 May 2020 23:27:53 +08:00 Committer: Marc Zyngier CommitterDate: Fri, 29 May 2020 09:42:18 +01:00 irqchip: Add Loongson PCH MSI controller This controller appears on Loongson LS7A family of PCH to transform interrupts from PCI MSI into HyperTransport vectorized interrrupts and send them to procrssor's HT vector controller. Signed-off-by: Jiaxun Yang Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20200528152757.1028711-6-jiaxun.y...@flygoat.com --- drivers/irqchip/Kconfig| 10 +- drivers/irqchip/Makefile | 1 +- drivers/irqchip/irq-loongson-pch-msi.c | 255 - 3 files changed, 266 insertions(+) create mode 100644 drivers/irqchip/irq-loongson-pch-msi.c diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index 5524a62..0b6b826 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig @@ -549,4 +549,14 @@ config LOONGSON_PCH_PIC help Support for the Loongson PCH PIC Controller. +config LOONGSON_PCH_MSI + bool "Loongson PCH PIC Controller" + depends on MACH_LOONGSON64 || COMPILE_TEST + depends on PCI + default MACH_LOONGSON64 + select IRQ_DOMAIN_HIERARCHY + select PCI_MSI + help + Support for the Loongson PCH MSI Controller. + endmenu diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index acc7233..3a4ce28 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile @@ -109,3 +109,4 @@ obj-$(CONFIG_LOONGSON_LIOINTC) += irq-loongson-liointc.o obj-$(CONFIG_LOONGSON_HTPIC) += irq-loongson-htpic.o obj-$(CONFIG_LOONGSON_HTVEC) += irq-loongson-htvec.o obj-$(CONFIG_LOONGSON_PCH_PIC) += irq-loongson-pch-pic.o +obj-$(CONFIG_LOONGSON_PCH_MSI) += irq-loongson-pch-msi.o diff --git a/drivers/irqchip/irq-loongson-pch-msi.c b/drivers/irqchip/irq-loongson-pch-msi.c new file mode 100644 index 000..50becd2 --- /dev/null +++ b/drivers/irqchip/irq-loongson-pch-msi.c @@ -0,0 +1,255 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2020, Jiaxun Yang + * Loongson PCH MSI support + */ + +#define pr_fmt(fmt) "pch-msi: " fmt + +#include +#include +#include +#include +#include +#include +#include +#include + +struct pch_msi_data { + struct mutexmsi_map_lock; + phys_addr_t doorbell; + u32 irq_first; /* The vector number that MSIs starts */ + u32 num_irqs; /* The number of vectors for MSIs */ + unsigned long *msi_map; +}; + +static void pch_msi_mask_msi_irq(struct irq_data *d) +{ + pci_msi_mask_irq(d); + irq_chip_mask_parent(d); +} + +static void pch_msi_unmask_msi_irq(struct irq_data *d) +{ + irq_chip_unmask_parent(d); + pci_msi_unmask_irq(d); +} + +static struct irq_chip pch_msi_irq_chip = { + .name = "PCH PCI MSI", + .irq_mask = pch_msi_mask_msi_irq, + .irq_unmask = pch_msi_unmask_msi_irq, + .irq_ack= irq_chip_ack_parent, + .irq_set_affinity = irq_chip_set_affinity_parent, +}; + +static int pch_msi_allocate_hwirq(struct pch_msi_data *priv, int num_req) +{ + int first; + + mutex_lock(&priv->msi_map_lock); + + first = bitmap_find_free_region(priv->msi_map, priv->num_irqs, + get_count_order(num_req)); + if (first < 0) { + mutex_unlock(&priv->msi_map_lock); + return -ENOSPC; + } + + mutex_unlock(&priv->msi_map_lock); + + return priv->irq_first + first; +} + +static void pch_msi_free_hwirq(struct pch_msi_data *priv, + int hwirq, int num_req) +{ + int first = hwirq - priv->irq_first; + + mutex_lock(&priv->msi_map_lock); + bitmap_release_region(priv->msi_map, first, get_count_order(num_req)); + mutex_unlock(&priv->msi_map_lock); +} + +static void pch_msi_compose_msi_msg(struct irq_data *data, + struct msi_msg *msg) +{ + struct pch_msi_data *priv = irq_data_get_irq_chip_data(data); + + msg->address_hi = upper_32_bits(priv->doorbell); + msg->address_lo = lower_32_bits(priv->doorbell); + msg->data = data->hwirq; +} + +static struct msi_domain_info pch_msi_domain_info = { + .flags = MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS | + MSI_FLAG_MULTI_PCI_MSI | MSI_FLAG_PCI_MSIX, + .chip = &pch_msi_irq_chip, +}; + +static struct irq_chip middle_irq_chip = { + .name = "PCH MSI", + .irq_mask = irq_chip_mask_parent, + .irq_unmask
[tip: irq/core] irqchip: Add Loongson PCH PIC controller
The following commit has been merged into the irq/core branch of tip: Commit-ID: ef8c01eb64ca6719da449dab0aa9424e13c58bd0 Gitweb: https://git.kernel.org/tip/ef8c01eb64ca6719da449dab0aa9424e13c58bd0 Author:Jiaxun Yang AuthorDate:Thu, 28 May 2020 23:27:51 +08:00 Committer: Marc Zyngier CommitterDate: Fri, 29 May 2020 09:42:18 +01:00 irqchip: Add Loongson PCH PIC controller This controller appears on Loongson LS7A family of PCH to transform interrupts from devices into HyperTransport vectorized interrrupts and send them to procrssor's HT vector controller. Signed-off-by: Jiaxun Yang Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20200528152757.1028711-4-jiaxun.y...@flygoat.com --- drivers/irqchip/Kconfig| 9 +- drivers/irqchip/Makefile | 1 +- drivers/irqchip/irq-loongson-pch-pic.c | 243 - 3 files changed, 253 insertions(+) create mode 100644 drivers/irqchip/irq-loongson-pch-pic.c diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index de4564e..5524a62 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig @@ -540,4 +540,13 @@ config LOONGSON_HTVEC help Support for the Loongson3 HyperTransport Interrupt Vector Controller. +config LOONGSON_PCH_PIC + bool "Loongson PCH PIC Controller" + depends on MACH_LOONGSON64 || COMPILE_TEST + default MACH_LOONGSON64 + select IRQ_DOMAIN_HIERARCHY + select IRQ_FASTEOI_HIERARCHY_HANDLERS + help + Support for the Loongson PCH PIC Controller. + endmenu diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index 7456187..acc7233 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile @@ -108,3 +108,4 @@ obj-$(CONFIG_TI_SCI_INTA_IRQCHIP) += irq-ti-sci-inta.o obj-$(CONFIG_LOONGSON_LIOINTC) += irq-loongson-liointc.o obj-$(CONFIG_LOONGSON_HTPIC) += irq-loongson-htpic.o obj-$(CONFIG_LOONGSON_HTVEC) += irq-loongson-htvec.o +obj-$(CONFIG_LOONGSON_PCH_PIC) += irq-loongson-pch-pic.o diff --git a/drivers/irqchip/irq-loongson-pch-pic.c b/drivers/irqchip/irq-loongson-pch-pic.c new file mode 100644 index 000..2a05b93 --- /dev/null +++ b/drivers/irqchip/irq-loongson-pch-pic.c @@ -0,0 +1,243 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2020, Jiaxun Yang + * Loongson PCH PIC support + */ + +#define pr_fmt(fmt) "pch-pic: " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Registers */ +#define PCH_PIC_MASK 0x20 +#define PCH_PIC_HTMSI_EN 0x40 +#define PCH_PIC_EDGE 0x60 +#define PCH_PIC_CLR0x80 +#define PCH_PIC_AUTO0 0xc0 +#define PCH_PIC_AUTO1 0xe0 +#define PCH_INT_ROUTE(irq) (0x100 + irq) +#define PCH_INT_HTVEC(irq) (0x200 + irq) +#define PCH_PIC_POL0x3e0 + +#define PIC_COUNT_PER_REG 32 +#define PIC_REG_COUNT 2 +#define PIC_COUNT (PIC_COUNT_PER_REG * PIC_REG_COUNT) +#define PIC_REG_IDX(irq_id)((irq_id) / PIC_COUNT_PER_REG) +#define PIC_REG_BIT(irq_id)((irq_id) % PIC_COUNT_PER_REG) + +struct pch_pic { + void __iomem*base; + struct irq_domain *pic_domain; + u32 ht_vec_base; + raw_spinlock_t pic_lock; +}; + +static void pch_pic_bitset(struct pch_pic *priv, int offset, int bit) +{ + u32 reg; + void __iomem *addr = priv->base + offset + PIC_REG_IDX(bit) * 4; + + raw_spin_lock(&priv->pic_lock); + reg = readl(addr); + reg |= BIT(PIC_REG_BIT(bit)); + writel(reg, addr); + raw_spin_unlock(&priv->pic_lock); +} + +static void pch_pic_bitclr(struct pch_pic *priv, int offset, int bit) +{ + u32 reg; + void __iomem *addr = priv->base + offset + PIC_REG_IDX(bit) * 4; + + raw_spin_lock(&priv->pic_lock); + reg = readl(addr); + reg &= ~BIT(PIC_REG_BIT(bit)); + writel(reg, addr); + raw_spin_unlock(&priv->pic_lock); +} + +static void pch_pic_eoi_irq(struct irq_data *d) +{ + u32 idx = PIC_REG_IDX(d->hwirq); + struct pch_pic *priv = irq_data_get_irq_chip_data(d); + + writel(BIT(PIC_REG_BIT(d->hwirq)), + priv->base + PCH_PIC_CLR + idx * 4); +} + +static void pch_pic_mask_irq(struct irq_data *d) +{ + struct pch_pic *priv = irq_data_get_irq_chip_data(d); + + pch_pic_bitset(priv, PCH_PIC_MASK, d->hwirq); + irq_chip_mask_parent(d); +} + +static void pch_pic_unmask_irq(struct irq_data *d) +{ + struct pch_pic *priv = irq_data_get_irq_chip_data(d); + + irq_chip_unmask_parent(d); + pch_pic_bitclr(priv, PCH_PIC_MASK, d->hwirq); +} + +static int pch_pic_set_type(struct irq_data *d, unsigned int type) +{ + struct pch_pic *priv = irq_data_get_irq_chip_data(d); + int ret = 0; + + switch (type) { + case IRQ_TYPE_EDGE_RISING: +
[tip: irq/core] dt-bindings: interrupt-controller: Add Loongson PCH MSI
The following commit has been merged into the irq/core branch of tip: Commit-ID: da10a4b626657387845f32d37141fc7d48ebbdb3 Gitweb: https://git.kernel.org/tip/da10a4b626657387845f32d37141fc7d48ebbdb3 Author:Jiaxun Yang AuthorDate:Thu, 28 May 2020 23:27:54 +08:00 Committer: Marc Zyngier CommitterDate: Fri, 29 May 2020 09:42:19 +01:00 dt-bindings: interrupt-controller: Add Loongson PCH MSI Add binding for Loongson PCH MSI controller. Signed-off-by: Jiaxun Yang Reviewed-by: Rob Herring Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20200528152757.1028711-7-jiaxun.y...@flygoat.com --- Documentation/devicetree/bindings/interrupt-controller/loongson,pch-msi.yaml | 62 ++ 1 file changed, 62 insertions(+) create mode 100644 Documentation/devicetree/bindings/interrupt-controller/loongson,pch-msi.yaml diff --git a/Documentation/devicetree/bindings/interrupt-controller/loongson,pch-msi.yaml b/Documentation/devicetree/bindings/interrupt-controller/loongson,pch-msi.yaml new file mode 100644 index 000..1a5ebbd --- /dev/null +++ b/Documentation/devicetree/bindings/interrupt-controller/loongson,pch-msi.yaml @@ -0,0 +1,62 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: "http://devicetree.org/schemas/interrupt-controller/loongson,pch-msi.yaml#"; +$schema: "http://devicetree.org/meta-schemas/core.yaml#"; + +title: Loongson PCH MSI Controller + +maintainers: + - Jiaxun Yang + +description: + This interrupt controller is found in the Loongson LS7A family of PCH for + transforming interrupts from PCIe MSI into HyperTransport vectorized + interrupts. + +properties: + compatible: +const: loongson,pch-msi-1.0 + + reg: +maxItems: 1 + + loongson,msi-base-vec: +description: + u32 value of the base of parent HyperTransport vector allocated + to PCH MSI. +allOf: + - $ref: "/schemas/types.yaml#/definitions/uint32" + - minimum: 0 +maximum: 255 + + loongson,msi-num-vecs: +description: + u32 value of the number of parent HyperTransport vectors allocated + to PCH MSI. +allOf: + - $ref: "/schemas/types.yaml#/definitions/uint32" + - minimum: 1 +maximum: 256 + + msi-controller: true + +required: + - compatible + - reg + - msi-controller + - loongson,msi-base-vec + - loongson,msi-num-vecs + +examples: + - | +#include +msi: msi-controller@2ff0 { + compatible = "loongson,pch-msi-1.0"; + reg = <0x2ff0 0x4>; + msi-controller; + loongson,msi-base-vec = <64>; + loongson,msi-num-vecs = <64>; + interrupt-parent = <&htvec>; +}; +...
Re: [PATCH v2 4/4] pinctrl: bcm2835: Add support for wake-up interrupts
Hi Florian, Am 29.05.20 um 21:15 schrieb Florian Fainelli: > Leverage the IRQCHIP_MASK_ON_SUSPEND flag in order to avoid having to > specifically treat the GPIO interrupts during suspend and resume, and > simply implement an irq_set_wake() callback that is responsible for > enabling the parent wake-up interrupt as a wake-up interrupt. > > To avoid allocating unnecessary resources for other chips, the wake-up > interrupts are only initialized if we have a brcm,bcm7211-gpio > compatibility string. > > Signed-off-by: Florian Fainelli > --- > drivers/pinctrl/bcm/pinctrl-bcm2835.c | 76 ++- > 1 file changed, 75 insertions(+), 1 deletion(-) > > diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2835.c > b/drivers/pinctrl/bcm/pinctrl-bcm2835.c > index 1b00d93aa66e..1fbf067a3eed 100644 > --- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c > +++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c > @@ -19,6 +19,7 @@ > #include > #include > #include > +#include > #include > #include > #include > @@ -76,6 +77,7 @@ > struct bcm2835_pinctrl { > struct device *dev; > void __iomem *base; > + int *wake_irq; > > /* note: locking assumes each bank will have its own unsigned long */ > unsigned long enabled_irq_map[BCM2835_NUM_BANKS]; > @@ -435,6 +437,11 @@ static void bcm2835_gpio_irq_handler(struct irq_desc > *desc) > chained_irq_exit(host_chip, desc); > } > > +static irqreturn_t bcm2835_gpio_wake_irq_handler(int irq, void *dev_id) > +{ > + return IRQ_HANDLED; > +} > + > static inline void __bcm2835_gpio_irq_config(struct bcm2835_pinctrl *pc, > unsigned reg, unsigned offset, bool enable) > { > @@ -634,6 +641,34 @@ static void bcm2835_gpio_irq_ack(struct irq_data *data) > bcm2835_gpio_set_bit(pc, GPEDS0, gpio); > } > > +static int bcm2835_gpio_irq_set_wake(struct irq_data *data, unsigned int on) > +{ > + struct gpio_chip *chip = irq_data_get_irq_chip_data(data); > + struct bcm2835_pinctrl *pc = gpiochip_get_data(chip); > + unsigned gpio = irqd_to_hwirq(data); > + unsigned int irqgroup; > + int ret = -EINVAL; > + > + if (!pc->wake_irq) > + return ret; > + > + if (gpio <= 27) > + irqgroup = 0; > + else if (gpio >= 28 && gpio <= 45) > + irqgroup = 1; > + else if (gpio >= 46 && gpio <= 53) > + irqgroup = 2; in case the BCM7211 has 58 GPIOs, but the wake up interrupts are only available for the first 54 this should deserve a comment. > + else > + return ret; > + > + if (on) > + ret = enable_irq_wake(pc->wake_irq[irqgroup]); > + else > + ret = disable_irq_wake(pc->wake_irq[irqgroup]); > + > + return ret; > +} > + > static struct irq_chip bcm2835_gpio_irq_chip = { > .name = MODULE_NAME, > .irq_enable = bcm2835_gpio_irq_enable, > @@ -642,6 +677,8 @@ static struct irq_chip bcm2835_gpio_irq_chip = { > .irq_ack = bcm2835_gpio_irq_ack, > .irq_mask = bcm2835_gpio_irq_disable, > .irq_unmask = bcm2835_gpio_irq_enable, > + .irq_set_wake = bcm2835_gpio_irq_set_wake, > + .flags = IRQCHIP_MASK_ON_SUSPEND, > }; > > static int bcm2835_pctl_get_groups_count(struct pinctrl_dev *pctldev) > @@ -1154,6 +1191,7 @@ static int bcm2835_pinctrl_probe(struct platform_device > *pdev) > struct resource iomem; > int err, i; > const struct of_device_id *match; > + int is_7211 = 0; > > BUILD_BUG_ON(ARRAY_SIZE(bcm2835_gpio_pins) != BCM2711_NUM_GPIOS); > BUILD_BUG_ON(ARRAY_SIZE(bcm2835_gpio_groups) != BCM2711_NUM_GPIOS); > @@ -1180,6 +1218,7 @@ static int bcm2835_pinctrl_probe(struct platform_device > *pdev) > return -EINVAL; > > pdata = match->data; > + is_7211 = of_device_is_compatible(np, "brcm,bcm7211-gpio"); > > pc->gpio_chip = *pdata->gpio_chip; > pc->gpio_chip.parent = dev; > @@ -1214,6 +1253,15 @@ static int bcm2835_pinctrl_probe(struct > platform_device *pdev) >GFP_KERNEL); > if (!girq->parents) > return -ENOMEM; > + > + if (is_7211) { > + pc->wake_irq = devm_kcalloc(dev, BCM2835_NUM_IRQS, > + sizeof(*pc->wake_irq), > + GFP_KERNEL); > + if (!pc->wake_irq) > + return -ENOMEM; > + } > + > /* >* Use the same handler for all groups: this is necessary >* since we use one gpiochip to cover all lines - the > @@ -1221,8 +1269,34 @@ static int bcm2835_pinctrl_probe(struct > platform_device *pdev) >* bank that was firing the IRQ and look up the per-group >* and bank data. >*/ > - for (i = 0; i < BCM2835_NUM_IRQS; i++) > + for (i = 0; i < BCM2835_NUM_IRQS; i++) { > + int len; > + char *name; > + > girq->parents[i] = irq_of_parse_and_map(np, i); > + i
Re: [PATCH v2] misc: mic: Remove the error message as the call will print it
On Sat, May 30, 2020 at 03:34:01PM +0800, Yi Wang wrote: > From: Liao Pingfang > > The message should just be dropped as the call will print the failure > message anyway. > > Signed-off-by: Liao Pingfang > --- > changes in v2: remove the message instead of changing it. > > drivers/misc/mic/host/mic_main.c | 1 - > 1 file changed, 1 deletion(-) > > diff --git a/drivers/misc/mic/host/mic_main.c > b/drivers/misc/mic/host/mic_main.c > index be0784f..ea46085 100644 > --- a/drivers/misc/mic/host/mic_main.c > +++ b/drivers/misc/mic/host/mic_main.c > @@ -164,7 +164,6 @@ static int mic_probe(struct pci_dev *pdev, > mdev = kzalloc(sizeof(*mdev), GFP_KERNEL); > if (!mdev) { > rc = -ENOMEM; > - dev_err(&pdev->dev, "mdev kmalloc failed rc %d\n", rc); > goto mdev_alloc_fail; > } > mdev->id = ida_simple_get(&g_mic_ida, 0, MIC_MAX_NUM_DEVS, GFP_KERNEL); > -- > 2.9.5 > Hi, This is the friendly semi-automated patch-bot of Greg Kroah-Hartman. You have sent him a patch that has triggered this response. Right now, the development tree you have sent a patch for is "closed" due to the timing of the merge window. Don't worry, the patch(es) you have sent are not lost, and will be looked at after the merge window is over (after the -rc1 kernel is released by Linus). So thank you for your patience and your patches will be reviewed at this later time, you do not have to do anything further, this is just a short note to let you know the patch status and so you don't worry they didn't make it through. thanks, greg k-h's patch email bot
Re: [PATCH] refperf: work around 64-bit division
On Sat, May 30, 2020 at 5:52 AM Nathan Chancellor wrote: > On Fri, May 29, 2020 at 10:15:51PM +0200, Arnd Bergmann wrote: > > strcat(buf, "Threads\tTime(ns)\n"); > > > > for (exp = 0; exp < nruns; exp++) { > > + u64 avg; > > + u32 rem; > > + > > if (errexit) > > break; > > - sprintf(buf1, "%d\t%llu.%03d\n", exp + 1, result_avg[exp] / > > 1000, (int)(result_avg[exp] % 1000)); > > + > > + avg = div_s64_rem(result_avg[exp], 1000, &rem); > > Shouldn't this be div_u64_rem? result_avg is u64. Yes, you are right. Actually that would be an important optimization since div_u64_rem() optimizes for constant divisors while div_s64_rem uses the slow path. > > + sprintf(buf1, "%d\t%llu.%03d\n", exp + 1, avg, rem); > > Would %03u be the better specifier since rem is u32? Yes, though this makes no difference in practice. Paul, should I send a fixup for these two, or do you prefer to just edit it in place? Arnd
Re: [GIT PULL] sh: remove sh5 support
On 5/29/20 7:53 PM, Rich Felker wrote: > Frustratingly, I _still_ don't have an official tree on kernel.org for > the purpose of being the canonical place for linux-next to pull from, > due to policies around pgp keys and nobody following up on signing > mine. This is all really silly since there are ridiculously many > independent channels I could cryptographically validate identity > through with vanishing probability that they're all compromised. For > the time being I'll reactivate my repo on git.musl-libc.org. May I suggest to pick up these patches, for example? There might be more I missed, but getting these merged should already help a lot with the clean-up of arch/sh. > [RESEND PATCH v2] sh: sh4a: Bring back tmu3_device early device > https://marc.info/?l=linux-sh&m=159061283109675&w=2 > [PATCH] sh: Drop CONFIG_MTD_M25P80 in sh7757lcr_defconfig > https://marc.info/?l=linux-sh&m=158839364811658&w=2 > [PATCH v2] sh: Replace CONFIG_MTD_M25P80 with CONFIG_MTD_SPI_NOR in > sh7757lcr_defconfig > https://marc.info/?l=linux-sh&m=158841749817761&w=2 > [PATCH 1/1] sh: remove sh5 support > https://marc.info/?l=linux-sh&m=158776683125080&w=2 > sh/mm: Fix a build failure via adding a missing bracket > https://marc.info/?l=linux-sh&m=158736532105299&w=2 > [PATCH 1/2] arch/sh: vmlinux.scr > https://marc.info/?l=linux-sh&m=158429470120959&w=2 > [PATCH] sh: configs: Cleanup old Kconfig IO scheduler options > https://marc.info/?l=linux-sh&m=158195850120215&w=2 > [PATCH resend 0/3] SH: compile fixup patches > https://marc.info/?l=linux-renesas-soc&m=157948330821790&w=2 > https://marc.info/?l=linux-sh&m=157852970316892&w=2 > https://marc.info/?l=linux-sh&m=157852984016938&w=2 > [PATCH][repost] sh: clkfwk: remove r8/r16/r32 > https://marc.info/?l=linux-renesas-soc&m=157852973916903&w=2 > [PATCH] sh: clk: Fix discarding const qualifier warning > https://marc.info/?l=linux-sh&m=15783010776&w=2 > [PATCH next] sh: remove call to memset after dma_alloc_coherent > https://marc.info/?l=linux-sh&m=157793031102356&w=2 > [PATCH] sh: use generic strncpy() > https://marc.info/?l=linux-renesas-soc&m=157664657013309&w=2 > [PATCH v2] SH: Convert ins[bwl]/outs[bwl] macros to inline functions > https://marc.info/?l=linux-sh&m=157656907716201&w=2 > [PATCH v2] SH: Convert iounmap() macros to inline functions > https://marc.info/?l=linux-sh&m=157656903716172&w=2 > [PATCH v2] sh: add missing DECLARE_EXPORT() for __ashiftrt_r4_xx > https://marc.info/?l=linux-sh&m=157619891030685&w=2 > [PATCH] sh: add missing EXPORT_SYMBOL() for __delay > https://marc.info/?l=linux-kernel&m=157611811927852&w=2 > [PATCH] sh: kgdb: Mark expected switch fall-throughs > https://marc.info/?l=linux-sh&m=157241987926081&w=2 Adrian -- .''`. John Paul Adrian Glaubitz : :' : Debian Developer - glaub...@debian.org `. `' Freie Universitaet Berlin - glaub...@physik.fu-berlin.de `-GPG: 62FF 8A75 84E0 2956 9546 0006 7426 3B37 F5B5 F913
[PATCH v4 00/17] Clean up "mediatek,larb" after adding device_link
MediaTek IOMMU block diagram always like below: M4U | smi-common | - | | ... | | larb1 larb2 | | vdec venc All the consumer connect with smi-larb, then connect with smi-common. MediaTek IOMMU don't have its power-domain. When the consumer works, it should enable the smi-larb's power which also need enable the smi-common's power firstly. Thus, Firstly, use the device link connect the consumer and the smi-larbs. then add device link between the smi-larb and smi-common. After adding the device_link, then "mediatek,larb" property can be removed. the iommu consumer don't need call the mtk_smi_larb_get/put to enable the power and clock of smi-larb and smi-common. This patchset depends on v5.7-rc1 and several patchset. Mainly venc and MDP adjust their flow, then this patchset can work successfully. a) IOMMU depend on [1][2]. b) MDP depend on [3][4][5]. c) VENC depend on [6]. [1] iommu: Move iommu_group setup to IOMMU core code https://lore.kernel.org/linux-iommu/20200429133712.31431-1-j...@8bytes.org/ [2] iommu/mediatek-v1: Fix a build warning for a unused variable 'data' https://lore.kernel.org/linux-iommu/1589875064-662-1-git-send-email-yong...@mediatek.com/ [3] arm64: dts: mt8173: fix mdp aliases property name https://lore.kernel.org/linux-mediatek/20200414030815.192104-1-hsi...@chromium.org/ [4] MTK MDP driver cleanups to prep for futher work https://lore.kernel.org/linux-mediatek/20200507102345.81849-1-ei...@chromium.org/ [5] Refactor MDP driver and add dummy component driver https://lore.kernel.org/linux-mediatek/20200506084039.249977-1-ei...@chromium.org/ [6] media: mtk-vcodec: venc: support for MT8183 https://lore.kernel.org/linux-mediatek/20200520082723.96136-1-acour...@chromium.org/ [1][2][3] have already been in lastest linux-next. Change notes: v4: base on v5.7-rc1. 1) Move drm PM patch before smi patchs. 2) Change builtin_platform_driver to module_platform_driver since we may need build as module. 3) Rebase many patchset as above. v3: https://lore.kernel.org/linux-iommu/1567503456-24725-1-git-send-email-yong...@mediatek.com/ 1) rebase on v5.3-rc1 and the latest mt8183 patchset. 2) Use device_is_bound to check whether the driver is ready from Matthias. 3) Add DL_FLAG_STATELESS flag when calling device_link_add and explain the reason in the commit message[3/14]. 4) Add a display patch[12/14] into this series. otherwise it may affect display HW fastlogo even though it don't happen in mt8183. v2: http://lists.infradead.org/pipermail/linux-mediatek/2019-June/020440.html 1) rebase on v5.2-rc1. 2) Move adding device_link between the consumer and smi-larb into iommu_add_device from Robin. 3) add DL_FLAG_AUTOREMOVE_CONSUMER even though the smi is built-in from Evan. 4) Remove the shutdown callback in iommu. v1: https://lists.linuxfoundation.org/pipermail/iommu/2019-January/032387.html Irui Wang (1): arm64: dts: mt8173: Separate mtk-vcodec-enc node Maoguang Meng (2): media: dt-binding: mtk-vcodec: Separating mtk-vcodec encode node. media: mtk-vcodec: separate mtk-vcodec-enc node. Yong Wu (13): dt-binding: mediatek: Get rid of mediatek,larb for multimedia HW iommu/mediatek: Add probe_defer for smi-larb iommu/mediatek: Add device_link between the consumer and the larb devices memory: mtk-smi: Add device-link between smi-larb and smi-common media: mtk-jpeg: Get rid of mtk_smi_larb_get/put media: mtk-mdp: Get rid of mtk_smi_larb_get/put media: mtk-vcodec: Get rid of mtk_smi_larb_get/put drm/mediatek: Get rid of mtk_smi_larb_get/put memory: mtk-smi: Get rid of mtk_smi_larb_get/put iommu/mediatek: Use module_platform_driver memory: mtk-smi: Use device_is_bound to check if smi-common is ready arm: dts: mediatek: Get rid of mediatek,larb for MM nodes arm64: dts: mediatek: Get rid of mediatek,larb for MM nodes Yongqiang Niu (1): drm/mediatek: Add pm runtime support for ovl and rdma .../bindings/display/mediatek/mediatek,disp.txt| 9 -- .../bindings/media/mediatek-jpeg-decoder.txt | 4 - .../devicetree/bindings/media/mediatek-mdp.txt | 8 -- .../devicetree/bindings/media/mediatek-vcodec.txt | 58 +- arch/arm/boot/dts/mt2701.dtsi | 1 - arch/arm/boot/dts/mt7623.dtsi | 1 - arch/arm64/boot/dts/mediatek/mt8173.dtsi | 72 +--- drivers/gpu/drm/mediatek/mtk_disp_ovl.c| 9 +- drivers/gpu/drm/mediatek/mtk_disp_rdma.c | 9 +- drivers/gpu/drm/mediatek/mtk_drm_crtc.c| 19 +-- drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c| 21 +--- drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h| 2 +- drivers/iommu/mtk_iommu.c | 44 --- drivers/iommu/mtk_iommu_v1.c | 39 +-- drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c
[PATCH v4 01/17] media: dt-binding: mtk-vcodec: Separating mtk-vcodec encode node.
From: Maoguang Meng Update binding document since the avc and vp8 hardware encoder in mt8173 are now separated. Separate "mediatek,mt8173-vcodec-enc" to "mediatek,mt8173-vcodec-vp8-enc" and "mediatek,mt8173-vcodec-avc-enc". This is a preparing patch for smi cleaning up "mediatek,larb". Signed-off-by: Maoguang Meng Signed-off-by: Hsin-Yi Wang Signed-off-by: Irui Wang Signed-off-by: Yong Wu --- .../devicetree/bindings/media/mediatek-vcodec.txt | 58 -- 1 file changed, 31 insertions(+), 27 deletions(-) diff --git a/Documentation/devicetree/bindings/media/mediatek-vcodec.txt b/Documentation/devicetree/bindings/media/mediatek-vcodec.txt index 8093335..1023740 100644 --- a/Documentation/devicetree/bindings/media/mediatek-vcodec.txt +++ b/Documentation/devicetree/bindings/media/mediatek-vcodec.txt @@ -4,7 +4,9 @@ Mediatek Video Codec is the video codec hw present in Mediatek SoCs which supports high resolution encoding and decoding functionalities. Required properties: -- compatible : "mediatek,mt8173-vcodec-enc" for MT8173 encoder +- compatible : must be one of the following string: + "mediatek,mt8173-vcodec-vp8-enc" for mt8173 vp8 encoder. + "mediatek,mt8173-vcodec-avc-enc" for mt8173 avc encoder. "mediatek,mt8183-vcodec-enc" for MT8183 encoder. "mediatek,mt8173-vcodec-dec" for MT8173 decoder. - reg : Physical base address of the video codec registers and length of @@ -13,10 +15,11 @@ Required properties: - mediatek,larb : must contain the local arbiters in the current Socs. - clocks : list of clock specifiers, corresponding to entries in the clock-names property. -- clock-names: encoder must contain "venc_sel_src", "venc_sel",, - "venc_lt_sel_src", "venc_lt_sel", decoder must contain "vcodecpll", - "univpll_d2", "clk_cci400_sel", "vdec_sel", "vdecpll", "vencpll", - "venc_lt_sel", "vdec_bus_clk_src". +- clock-names: + avc venc must contain "venc_sel"; + vp8 venc must contain "venc_lt_sel"; + decoder must contain "vcodecpll", "univpll_d2", "clk_cci400_sel", + "vdec_sel", "vdecpll", "vencpll", "venc_lt_sel", "vdec_bus_clk_src". - iommus : should point to the respective IOMMU block with master port as argument, see Documentation/devicetree/bindings/iommu/mediatek,iommu.txt for details. @@ -80,14 +83,10 @@ vcodec_dec: vcodec@1600 { assigned-clock-rates = <0>, <0>, <0>, <148200>, <8>; }; - vcodec_enc: vcodec@18002000 { -compatible = "mediatek,mt8173-vcodec-enc"; -reg = <0 0x18002000 0 0x1000>,/*VENC_SYS*/ - <0 0x19002000 0 0x1000>;/*VENC_LT_SYS*/ -interrupts = , -; -mediatek,larb = <&larb3>, - <&larb5>; +vcodec_enc: vcodec@18002000 { +compatible = "mediatek,mt8173-vcodec-avc-enc"; +reg = <0 0x18002000 0 0x1000>; +interrupts = ; iommus = <&iommu M4U_PORT_VENC_RCPU>, <&iommu M4U_PORT_VENC_REC>, <&iommu M4U_PORT_VENC_BSDMA>, @@ -98,8 +97,20 @@ vcodec_dec: vcodec@1600 { <&iommu M4U_PORT_VENC_REF_LUMA>, <&iommu M4U_PORT_VENC_REF_CHROMA>, <&iommu M4U_PORT_VENC_NBM_RDMA>, - <&iommu M4U_PORT_VENC_NBM_WDMA>, - <&iommu M4U_PORT_VENC_RCPU_SET2>, + <&iommu M4U_PORT_VENC_NBM_WDMA>; +mediatek,larb = <&larb3>; +mediatek,vpu = <&vpu>; +clocks = <&topckgen CLK_TOP_VENC_SEL>; +clock-names = "venc_sel"; +assigned-clocks = <&topckgen CLK_TOP_VENC_SEL>; +assigned-clock-parents = <&topckgen CLK_TOP_VCODECPLL>; + }; + +vcodec_enc_lt: vcodec@19002000 { +compatible = "mediatek,mt8173-vcodec-vp8-enc"; +reg = <0 0x19002000 0 0x1000>;/* VENC_LT_SYS */ +interrupts = ; +iommus = <&iommu M4U_PORT_VENC_RCPU_SET2>, <&iommu M4U_PORT_VENC_REC_FRM_SET2>, <&iommu M4U_PORT_VENC_BSDMA_SET2>, <&iommu M4U_PORT_VENC_SV_COMA_SET2>, @@ -108,17 +119,10 @@ vcodec_dec: vcodec@1600 { <&iommu M4U_PORT_VENC_CUR_CHROMA_SET2>, <&iommu M4U_PORT_VENC_REF_LUMA_SET2>, <&iommu M4U_PORT_VENC_REC_CHROMA_SET2>; +mediatek,larb = <&larb5>; mediatek,vpu = <&vpu>; -clocks = <&topckgen CLK_TOP_VENCPLL_D2>, - <&topckgen CLK_TOP_VENC_SEL>, - <&topckgen CLK_TOP_UNIVPLL1_D2>, - <&topckgen CLK_TOP_VENC_LT_SEL>; -clock-names = "venc_sel_src", - "venc_sel", - "venc_lt_sel_src", - "venc_lt_sel"; -assigned-clocks = <&topckgen CLK_TOP_VENC_SEL>, - <&topckgen CLK_TOP_VENC_LT_SEL>; -assigned-clock-parents = <&topckgen CLK_TOP_VENCPLL_D2>, - <&topckgen CLK_TOP_UNIVPLL1_D2>; +clocks = <&topckgen CLK_TOP_VENC_LT_SEL>; +clock-names = "venc_lt_sel"; +assigned-clocks = <&topckgen CLK_TOP_VENC_LT_SEL>; +assigned-clock-parents = <&topckgen CLK_TOP_VCODECPLL_370P5>; }; -- 1.9.1
[PATCH v4 03/17] iommu/mediatek: Add probe_defer for smi-larb
The iommu consumer should use device_link to connect with the smi-larb(supplier). then the smi-larb should run before the iommu consumer. Here we delay the iommu driver until the smi driver is ready, then all the iommu consumer always is after the smi driver. When there is no this patch, if some consumer drivers run before smi-larb, the supplier link_status is DL_DEV_NO_DRIVER(0) in the device_link_add, then device_links_driver_bound will use WARN_ON to complain that the link_status of supplier is not right. This is a preparing patch for adding device_link. Signed-off-by: Yong Wu --- drivers/iommu/mtk_iommu.c| 8 +++- drivers/iommu/mtk_iommu_v1.c | 7 ++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c index 2be96f1..7d8f3d0 100644 --- a/drivers/iommu/mtk_iommu.c +++ b/drivers/iommu/mtk_iommu.c @@ -643,6 +643,7 @@ static int mtk_iommu_probe(struct platform_device *pdev) for (i = 0; i < larb_nr; i++) { struct device_node *larbnode; struct platform_device *plarbdev; + bool larbdev_is_bound = false; u32 id; larbnode = of_parse_phandle(dev->of_node, "mediatek,larbs", i); @@ -659,7 +660,12 @@ static int mtk_iommu_probe(struct platform_device *pdev) id = i; plarbdev = of_find_device_by_node(larbnode); - if (!plarbdev) { + if (plarbdev) { + device_lock(&plarbdev->dev); + larbdev_is_bound = device_is_bound(&plarbdev->dev); + device_unlock(&plarbdev->dev); + } + if (!plarbdev || !larbdev_is_bound) { of_node_put(larbnode); return -EPROBE_DEFER; } diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c index 1245e0c..02858a0 100644 --- a/drivers/iommu/mtk_iommu_v1.c +++ b/drivers/iommu/mtk_iommu_v1.c @@ -591,10 +591,15 @@ static int mtk_iommu_probe(struct platform_device *pdev) plarbdev = of_find_device_by_node(larb_spec.np); if (!plarbdev) { + bool larbdev_is_bound; + plarbdev = of_platform_device_create( larb_spec.np, NULL, platform_bus_type.dev_root); - if (!plarbdev) { + device_lock(&plarbdev->dev); + larbdev_is_bound = device_is_bound(&plarbdev->dev); + device_unlock(&plarbdev->dev); + if (!plarbdev || !larbdev_is_bound) { of_node_put(larb_spec.np); return -EPROBE_DEFER; } -- 1.9.1
[PATCH v4 04/17] iommu/mediatek: Add device_link between the consumer and the larb devices
MediaTek IOMMU don't have its power-domain. all the consumer connect with smi-larb, then connect with smi-common. M4U | smi-common | - | |... | | larb1 larb2 | | vdec venc When the consumer works, it should enable the smi-larb's power which also need enable the smi-common's power firstly. Thus, First of all, use the device link connect the consumer and the smi-larbs. then add device link between the smi-larb and smi-common. This patch adds device_link between the consumer and the larbs. When device_link_add, I add the flag DL_FLAG_STATELESS to avoid calling pm_runtime_xx to keep the original status of clocks. It can avoid two issues: 1) Display HW show fastlogo abnormally reported in [1]. At the beggining, all the clocks are enabled before entering kernel, but the clocks for display HW(always in larb0) will be gated after clk_enable and clk_disable called from device_link_add(->pm_runtime_resume) and rpm_idle. The clock operation happened before display driver probe. At that time, the display HW will be abnormal. 2) A deadlock issue reported in [2]. Use DL_FLAG_STATELESS to skip pm_runtime_xx to avoid the deadlock. Corresponding, DL_FLAG_AUTOREMOVE_CONSUMER can't be added, then device_link_removed should be added explicitly. [1] http://lists.infradead.org/pipermail/linux-mediatek/2019-July/ 021500.html [2] https://lore.kernel.org/patchwork/patch/1086569/ Suggested-by: Tomasz Figa Signed-off-by: Yong Wu --- drivers/iommu/mtk_iommu.c| 18 ++ drivers/iommu/mtk_iommu_v1.c | 20 +++- 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c index 7d8f3d0..5c3a6ba 100644 --- a/drivers/iommu/mtk_iommu.c +++ b/drivers/iommu/mtk_iommu.c @@ -445,22 +445,40 @@ static struct iommu_device *mtk_iommu_probe_device(struct device *dev) { struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); struct mtk_iommu_data *data; + struct device_link *link; + struct device *larbdev; + unsigned int larbid; if (!fwspec || fwspec->ops != &mtk_iommu_ops) return ERR_PTR(-ENODEV); /* Not a iommu client device */ data = dev_iommu_priv_get(dev); + /* Link the consumer device with the smi-larb device(supplier) */ + larbid = MTK_M4U_TO_LARB(fwspec->ids[0]); + larbdev = data->larb_imu[larbid].dev; + link = device_link_add(dev, larbdev, + DL_FLAG_PM_RUNTIME | DL_FLAG_STATELESS); + if (!link) + dev_err(dev, "Unable to link %s\n", dev_name(larbdev)); return &data->iommu; } static void mtk_iommu_release_device(struct device *dev) { struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); + struct mtk_iommu_data *data; + struct device *larbdev; + unsigned int larbid; if (!fwspec || fwspec->ops != &mtk_iommu_ops) return; + data = dev_iommu_priv_get(dev); + larbid = MTK_M4U_TO_LARB(fwspec->ids[0]); + larbdev = data->larb_imu[larbid].dev; + device_link_remove(dev, larbdev); + iommu_fwspec_free(dev); } diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c index 02858a0..26b6c79 100644 --- a/drivers/iommu/mtk_iommu_v1.c +++ b/drivers/iommu/mtk_iommu_v1.c @@ -422,7 +422,9 @@ static struct iommu_device *mtk_iommu_probe_device(struct device *dev) struct of_phandle_args iommu_spec; struct of_phandle_iterator it; struct mtk_iommu_data *data; - int err; + struct device_link *link; + struct device *larbdev; + int err, larbid; of_for_each_phandle(&it, err, dev->of_node, "iommus", "#iommu-cells", -1) { @@ -444,6 +446,14 @@ static struct iommu_device *mtk_iommu_probe_device(struct device *dev) data = dev_iommu_priv_get(dev); + /* Link the consumer device with the smi-larb device(supplier) */ + larbid = mt2701_m4u_to_larb(fwspec->ids[0]); + larbdev = data->larb_imu[larbid].dev; + link = device_link_add(dev, larbdev, + DL_FLAG_PM_RUNTIME | DL_FLAG_STATELESS); + if (!link) + dev_err(dev, "Unable to link %s\n", dev_name(larbdev)); + return &data->iommu; } @@ -465,10 +475,18 @@ static void mtk_iommu_probe_finalize(struct device *dev) static void mtk_iommu_release_device(struct device *dev) { struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); + struct mtk_iommu_data *data; + struct device *larbdev; + unsigned int larbid; if (!fwspec || fwspec->ops != &mtk_iommu_ops) return; + data = dev_iommu_priv_get(dev); + larbid = mt2701_m4u_to_larb(fwspec->ids[0]); + larbdev = data->larb_imu[larbid].dev; + device_link_remove(dev, larbdev); + iommu_fwspec_f
[PATCH v4 02/17] dt-binding: mediatek: Get rid of mediatek,larb for multimedia HW
After adding device_link between the consumer with the smi-larbs, if the consumer call its owner pm_runtime_get(_sync), the pm_runtime_get(_sync) of smi-larb and smi-common will be called automatically. Thus, the consumer don't need the property. And IOMMU also know which larb this consumer connects with from iommu id in the "iommus=" property. Signed-off-by: Yong Wu Reviewed-by: Rob Herring Reviewed-by: Evan Green --- .../devicetree/bindings/display/mediatek/mediatek,disp.txt | 9 - .../devicetree/bindings/media/mediatek-jpeg-decoder.txt | 4 Documentation/devicetree/bindings/media/mediatek-mdp.txt | 8 Documentation/devicetree/bindings/media/mediatek-vcodec.txt | 4 4 files changed, 25 deletions(-) diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt b/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt index b91e709..c7e2eb8 100644 --- a/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt @@ -60,8 +60,6 @@ Required properties (DMA function blocks): "mediatek,-disp-rdma" "mediatek,-disp-wdma" the supported chips are mt2701 and mt8173. -- larb: Should contain a phandle pointing to the local arbiter device as defined - in Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt - iommus: Should point to the respective IOMMU block with master port as argument, see Documentation/devicetree/bindings/iommu/mediatek,iommu.txt for details. @@ -82,7 +80,6 @@ ovl0: ovl@1400c000 { power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; clocks = <&mmsys CLK_MM_DISP_OVL0>; iommus = <&iommu M4U_PORT_DISP_OVL0>; - mediatek,larb = <&larb0>; }; ovl1: ovl@1400d000 { @@ -92,7 +89,6 @@ ovl1: ovl@1400d000 { power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; clocks = <&mmsys CLK_MM_DISP_OVL1>; iommus = <&iommu M4U_PORT_DISP_OVL1>; - mediatek,larb = <&larb4>; }; rdma0: rdma@1400e000 { @@ -102,7 +98,6 @@ rdma0: rdma@1400e000 { power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; clocks = <&mmsys CLK_MM_DISP_RDMA0>; iommus = <&iommu M4U_PORT_DISP_RDMA0>; - mediatek,larb = <&larb0>; }; rdma1: rdma@1400f000 { @@ -112,7 +107,6 @@ rdma1: rdma@1400f000 { power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; clocks = <&mmsys CLK_MM_DISP_RDMA1>; iommus = <&iommu M4U_PORT_DISP_RDMA1>; - mediatek,larb = <&larb4>; }; rdma2: rdma@1401 { @@ -122,7 +116,6 @@ rdma2: rdma@1401 { power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; clocks = <&mmsys CLK_MM_DISP_RDMA2>; iommus = <&iommu M4U_PORT_DISP_RDMA2>; - mediatek,larb = <&larb4>; }; wdma0: wdma@14011000 { @@ -132,7 +125,6 @@ wdma0: wdma@14011000 { power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; clocks = <&mmsys CLK_MM_DISP_WDMA0>; iommus = <&iommu M4U_PORT_DISP_WDMA0>; - mediatek,larb = <&larb0>; }; wdma1: wdma@14012000 { @@ -142,7 +134,6 @@ wdma1: wdma@14012000 { power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; clocks = <&mmsys CLK_MM_DISP_WDMA1>; iommus = <&iommu M4U_PORT_DISP_WDMA1>; - mediatek,larb = <&larb4>; }; color0: color@14013000 { diff --git a/Documentation/devicetree/bindings/media/mediatek-jpeg-decoder.txt b/Documentation/devicetree/bindings/media/mediatek-jpeg-decoder.txt index 044b119..7978f21 100644 --- a/Documentation/devicetree/bindings/media/mediatek-jpeg-decoder.txt +++ b/Documentation/devicetree/bindings/media/mediatek-jpeg-decoder.txt @@ -15,9 +15,6 @@ Required properties: - clock-names: must contain "jpgdec-smi" and "jpgdec". - power-domains: a phandle to the power domain, see Documentation/devicetree/bindings/power/power_domain.txt for details. -- mediatek,larb: must contain the local arbiters in the current Socs, see - Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt - for details. - iommus: should point to the respective IOMMU block with master port as argument, see Documentation/devicetree/bindings/iommu/mediatek,iommu.txt for details. @@ -32,7 +29,6 @@ Example: clock-names = "jpgdec-smi", "jpgdec"; power-domains = <&scpsys MT2701_POWER_DOMAIN_ISP>; - mediatek,larb = <&larb2>; iommus = <&iommu MT2701_M4U_PORT_JPGDEC_WDMA>, <&iommu MT2701_M4U_PORT_JPGDEC_BSDMA>; }; diff --git a/Documentation/devicetree/bindings/media/mediatek-mdp.txt b/Documentation/devicetree/bindings/media/mediatek-mdp.txt index 0d03e3a..df69c5a 100644 --- a/Documentation/devicetree/bindings/media/mediatek-mdp.txt +++ b/Documentation/devicetree/bindings/media/mediatek-mdp.txt @@ -27,9 +27,6 @@ Required properties (DMA function blocks, child node): - iommus: sho
[PATCH v4 06/17] media: mtk-jpeg: Get rid of mtk_smi_larb_get/put
MediaTek IOMMU has already added device_link between the consumer and smi-larb device. If the jpg device call the pm_runtime_get_sync, the smi-larb's pm_runtime_get_sync also be called automatically. CC: Rick Chang Signed-off-by: Yong Wu Reviewed-by: Evan Green --- drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c | 22 -- drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h | 2 -- 2 files changed, 24 deletions(-) diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c index f82a81a..21fba6f 100644 --- a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c +++ b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c @@ -21,7 +21,6 @@ #include #include #include -#include #include "mtk_jpeg_hw.h" #include "mtk_jpeg_core.h" @@ -893,11 +892,6 @@ static int mtk_jpeg_queue_init(void *priv, struct vb2_queue *src_vq, static void mtk_jpeg_clk_on(struct mtk_jpeg_dev *jpeg) { - int ret; - - ret = mtk_smi_larb_get(jpeg->larb); - if (ret) - dev_err(jpeg->dev, "mtk_smi_larb_get larbvdec fail %d\n", ret); clk_prepare_enable(jpeg->clk_jdec_smi); clk_prepare_enable(jpeg->clk_jdec); } @@ -906,7 +900,6 @@ static void mtk_jpeg_clk_off(struct mtk_jpeg_dev *jpeg) { clk_disable_unprepare(jpeg->clk_jdec); clk_disable_unprepare(jpeg->clk_jdec_smi); - mtk_smi_larb_put(jpeg->larb); } static irqreturn_t mtk_jpeg_dec_irq(int irq, void *priv) @@ -1051,21 +1044,6 @@ static int mtk_jpeg_release(struct file *file) static int mtk_jpeg_clk_init(struct mtk_jpeg_dev *jpeg) { - struct device_node *node; - struct platform_device *pdev; - - node = of_parse_phandle(jpeg->dev->of_node, "mediatek,larb", 0); - if (!node) - return -EINVAL; - pdev = of_find_device_by_node(node); - if (WARN_ON(!pdev)) { - of_node_put(node); - return -EINVAL; - } - of_node_put(node); - - jpeg->larb = &pdev->dev; - jpeg->clk_jdec = devm_clk_get(jpeg->dev, "jpgdec"); if (IS_ERR(jpeg->clk_jdec)) return PTR_ERR(jpeg->clk_jdec); diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h index 999bd14..8579494 100644 --- a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h +++ b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h @@ -47,7 +47,6 @@ enum mtk_jpeg_ctx_state { * @dec_reg_base: JPEG registers mapping * @clk_jdec: JPEG hw working clock * @clk_jdec_smi: JPEG SMI bus clock - * @larb: SMI device */ struct mtk_jpeg_dev { struct mutexlock; @@ -61,7 +60,6 @@ struct mtk_jpeg_dev { void __iomem*dec_reg_base; struct clk *clk_jdec; struct clk *clk_jdec_smi; - struct device *larb; }; /** -- 1.9.1
[PATCH v4 05/17] memory: mtk-smi: Add device-link between smi-larb and smi-common
Normally, If the smi-larb HW need work, we should enable the smi-common HW power and clock firstly. This patch adds device-link between the smi-larb dev and the smi-common dev. then If pm_runtime_get_sync(smi-larb-dev), the pm_runtime_get_sync (smi-common-dev) will be called automatically. Also, Add DL_FLAG_STATELESS to avoid the smi-common clocks be gated when probe. CC: Matthias Brugger Suggested-by: Tomasz Figa Signed-off-by: Yong Wu --- drivers/memory/mtk-smi.c | 19 ++- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c index a113e81..6cdefda 100644 --- a/drivers/memory/mtk-smi.c +++ b/drivers/memory/mtk-smi.c @@ -273,6 +273,7 @@ static int mtk_smi_larb_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct device_node *smi_node; struct platform_device *smi_pdev; + struct device_link *link; larb = devm_kzalloc(dev, sizeof(*larb), GFP_KERNEL); if (!larb) @@ -312,6 +313,12 @@ static int mtk_smi_larb_probe(struct platform_device *pdev) if (!platform_get_drvdata(smi_pdev)) return -EPROBE_DEFER; larb->smi_common_dev = &smi_pdev->dev; + link = device_link_add(dev, larb->smi_common_dev, + DL_FLAG_PM_RUNTIME | DL_FLAG_STATELESS); + if (!link) { + dev_err(dev, "Unable to link smi-common dev\n"); + return -ENODEV; + } } else { dev_err(dev, "Failed to get the smi_common device\n"); return -EINVAL; @@ -324,6 +331,9 @@ static int mtk_smi_larb_probe(struct platform_device *pdev) static int mtk_smi_larb_remove(struct platform_device *pdev) { + struct mtk_smi_larb *larb = platform_get_drvdata(pdev); + + device_link_remove(&pdev->dev, larb->smi_common_dev); pm_runtime_disable(&pdev->dev); component_del(&pdev->dev, &mtk_smi_larb_component_ops); return 0; @@ -335,17 +345,9 @@ static int __maybe_unused mtk_smi_larb_resume(struct device *dev) const struct mtk_smi_larb_gen *larb_gen = larb->larb_gen; int ret; - /* Power on smi-common. */ - ret = pm_runtime_get_sync(larb->smi_common_dev); - if (ret < 0) { - dev_err(dev, "Failed to pm get for smi-common(%d).\n", ret); - return ret; - } - ret = mtk_smi_clk_enable(&larb->smi); if (ret < 0) { dev_err(dev, "Failed to enable clock(%d).\n", ret); - pm_runtime_put_sync(larb->smi_common_dev); return ret; } @@ -360,7 +362,6 @@ static int __maybe_unused mtk_smi_larb_suspend(struct device *dev) struct mtk_smi_larb *larb = dev_get_drvdata(dev); mtk_smi_clk_disable(&larb->smi); - pm_runtime_put_sync(larb->smi_common_dev); return 0; } -- 1.9.1
[PATCH v4 08/17] media: mtk-vcodec: separate mtk-vcodec-enc node.
From: Maoguang Meng MTK H264 Encoder(VENC_SYS) and VP8 Encoder(VENC_LT_SYS) are two independent hardware instance. They have their owner interrupt, register mapping, and special clocks. This patch seperates the two instance. This is a preparing patch for adding device_link between the larbs and venc-device. It's mainly for fixing the problem: https://lkml.org/lkml/2019/9/3/316 User Call "VIDIOC_QUERYCAP": H264 Encoder return driver name "mtk-vcodec-enc"; VP8 Encoder return driver name "mtk-venc-vp8. Signed-off-by: Maoguang Meng Signed-off-by: Hsin-Yi Wang Signed-off-by: Irui Wang --- drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h | 10 +- drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c | 23 +++- .../media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c | 127 + .../media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c | 31 + .../media/platform/mtk-vcodec/mtk_vcodec_enc_pm.h | 1 - .../media/platform/mtk-vcodec/venc/venc_vp8_if.c | 4 +- 6 files changed, 80 insertions(+), 116 deletions(-) diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h index a2716117..52d1ce1 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h @@ -19,6 +19,7 @@ #define MTK_VCODEC_DRV_NAME"mtk_vcodec_drv" #define MTK_VCODEC_DEC_NAME"mtk-vcodec-dec" #define MTK_VCODEC_ENC_NAME"mtk-vcodec-enc" +#define MTK_VENC_VP8_NAME "mtk-venc-vp8" #define MTK_PLATFORM_STR "platform:mt8173" #define MTK_VCODEC_MAX_PLANES 3 @@ -193,7 +194,6 @@ struct mtk_vcodec_pm { struct mtk_vcodec_clk venc_clk; struct device *larbvenc; - struct device *larbvenclt; struct device *dev; struct mtk_vcodec_dev *mtkdev; }; @@ -311,25 +311,27 @@ enum mtk_chip { * @chip: chip this encoder is compatible with * * @uses_ext: whether the encoder uses the extended firmware messaging format - * @has_lt_irq: whether the encoder uses the LT irq + * @name: whether the encoder core is vp8 * @min_birate: minimum supported encoding bitrate * @max_bitrate: maximum supported encoding bitrate * @capture_formats: array of supported capture formats * @num_capture_formats: number of entries in capture_formats * @output_formats: array of supported output formats * @num_output_formats: number of entries in output_formats + * @core_id: stand for h264 or vp8 encode index */ struct mtk_vcodec_enc_pdata { enum mtk_chip chip; bool uses_ext; - bool has_lt_irq; + const char *name; unsigned long min_bitrate; unsigned long max_bitrate; const struct mtk_video_fmt *capture_formats; size_t num_capture_formats; const struct mtk_video_fmt *output_formats; size_t num_output_formats; + int core_id; }; /** @@ -359,7 +361,6 @@ struct mtk_vcodec_enc_pdata { * * @dec_irq: decoder irq resource * @enc_irq: h264 encoder irq resource - * @enc_lt_irq: vp8 encoder irq resource * * @dec_mutex: decoder hardware lock * @enc_mutex: encoder hardware lock. @@ -395,7 +396,6 @@ struct mtk_vcodec_dev { int dec_irq; int enc_irq; - int enc_lt_irq; struct mutex dec_mutex; struct mutex enc_mutex; diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c index f0af78f..5301dca 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c @@ -9,6 +9,7 @@ #include #include #include +#include #include "mtk_vcodec_drv.h" #include "mtk_vcodec_enc.h" @@ -174,7 +175,10 @@ static int vidioc_enum_fmt_vid_out(struct file *file, void *priv, static int vidioc_venc_querycap(struct file *file, void *priv, struct v4l2_capability *cap) { - strscpy(cap->driver, MTK_VCODEC_ENC_NAME, sizeof(cap->driver)); + const struct mtk_vcodec_enc_pdata *pdata = + fh_to_ctx(priv)->dev->venc_pdata; + + strscpy(cap->driver, pdata->name, sizeof(cap->driver)); strscpy(cap->bus_info, MTK_PLATFORM_STR, sizeof(cap->bus_info)); strscpy(cap->card, MTK_PLATFORM_STR, sizeof(cap->card)); @@ -788,7 +792,7 @@ static int vb2ops_venc_start_streaming(struct vb2_queue *q, unsigned int count) */ if ((ctx->state == MTK_STATE_ABORT) || (ctx->state == MTK_STATE_FREE)) { ret = -EIO; - goto err_set_param; + goto err_start_stream; } /* Do the initialization when both start_streaming have been called */ @@ -800,6 +804,12 @@ static int vb2ops_venc_start_streaming(struct vb2_queue *q, unsigned int count) return 0; } + ret = pm_runtime_get_sync(&ctx->dev->plat_dev->dev); + if (ret < 0) { + mtk_v4l2_err("pm_runtime_get_sync fail %d", r
[PATCH v4 10/17] drm/mediatek: Add pm runtime support for ovl and rdma
From: Yongqiang Niu Display use the dispsys device to call pm_rumtime_get_sync before. This patch add pm_runtime_xx with ovl and rdma device whose nodes has "iommus" property, then display could help pm_runtime_get for smi via ovl or rdma device. This is a preparing patch that smi cleaning up "mediatek,larb". CC: CK Hu Signed-off-by: Yongqiang Niu Signed-off-by: Yong Wu --- drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 9 - drivers/gpu/drm/mediatek/mtk_disp_rdma.c| 9 - drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 12 +++- drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 2 ++ drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 1 + 5 files changed, 30 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c index 891d80c..17c9baa 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include "mtk_drm_crtc.h" @@ -399,9 +400,13 @@ static int mtk_disp_ovl_probe(struct platform_device *pdev) return ret; } + pm_runtime_enable(dev); + ret = component_add(dev, &mtk_disp_ovl_component_ops); - if (ret) + if (ret) { + pm_runtime_disable(dev); dev_err(dev, "Failed to add component: %d\n", ret); + } return ret; } @@ -410,6 +415,8 @@ static int mtk_disp_ovl_remove(struct platform_device *pdev) { component_del(&pdev->dev, &mtk_disp_ovl_component_ops); + pm_runtime_disable(&pdev->dev); + return 0; } diff --git a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c index 0cb848d..5ea8fb6 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include "mtk_drm_crtc.h" @@ -313,9 +314,13 @@ static int mtk_disp_rdma_probe(struct platform_device *pdev) platform_set_drvdata(pdev, priv); + pm_runtime_enable(dev); + ret = component_add(dev, &mtk_disp_rdma_component_ops); - if (ret) + if (ret) { + pm_runtime_disable(dev); dev_err(dev, "Failed to add component: %d\n", ret); + } return ret; } @@ -324,6 +329,8 @@ static int mtk_disp_rdma_remove(struct platform_device *pdev) { component_del(&pdev->dev, &mtk_disp_rdma_component_ops); + pm_runtime_disable(&pdev->dev); + return 0; } diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c index fe85e48..c9bc844 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c @@ -538,9 +538,15 @@ static void mtk_drm_crtc_atomic_enable(struct drm_crtc *crtc, return; } + ret = pm_runtime_get_sync(comp->dev); + if (ret < 0) + DRM_DEV_ERROR(comp->dev, "Failed to enable power domain: %d\n", + ret); + ret = mtk_crtc_ddp_hw_init(mtk_crtc); if (ret) { mtk_smi_larb_put(comp->larb_dev); + pm_runtime_put(comp->dev); return; } @@ -553,7 +559,7 @@ static void mtk_drm_crtc_atomic_disable(struct drm_crtc *crtc, { struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc); struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0]; - int i; + int i, ret; DRM_DEBUG_DRIVER("%s %d\n", __func__, crtc->base.id); if (!mtk_crtc->enabled) @@ -577,6 +583,10 @@ static void mtk_drm_crtc_atomic_disable(struct drm_crtc *crtc, drm_crtc_vblank_off(crtc); mtk_crtc_ddp_hw_fini(mtk_crtc); mtk_smi_larb_put(comp->larb_dev); + ret = pm_runtime_put(comp->dev); + if (ret < 0) + DRM_DEV_ERROR(comp->dev, "Failed to disable power domain: %d\n", + ret); mtk_crtc->enabled = false; } diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c index 57c88de..593027a 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c @@ -493,6 +493,8 @@ int mtk_ddp_comp_init(struct device *dev, struct device_node *node, comp->larb_dev = &larb_pdev->dev; + comp->dev = dev; + #if IS_REACHABLE(CONFIG_MTK_CMDQ) if (of_address_to_resource(node, 0, &res) != 0) { dev_err(dev, "Missing reg in %s node\n", node->full_name); diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h index debe363..4c063e0 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h @@ -99,6 +99,7 @@ struct mtk_ddp_comp { void __iomem *regs; int irq; struct device *larb_dev; +
[PATCH v4 07/17] media: mtk-mdp: Get rid of mtk_smi_larb_get/put
MediaTek IOMMU has already added the device_link between the consumer and smi-larb device. If the mdp device call the pm_runtime_get_sync, the smi-larb's pm_runtime_get_sync also be called automatically. CC: Minghsiu Tsai CC: Houlong Wei Signed-off-by: Yong Wu Reviewed-by: Evan Green --- drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 44 +-- drivers/media/platform/mtk-mdp/mtk_mdp_comp.h | 2 -- drivers/media/platform/mtk-mdp/mtk_mdp_core.c | 1 - 3 files changed, 1 insertion(+), 46 deletions(-) diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c index 228c58f..388ae67 100644 --- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include @@ -58,18 +57,6 @@ void mtk_mdp_comp_clock_on(struct mtk_mdp_comp *comp) { int i, err; - if (comp->larb_dev) { - err = mtk_smi_larb_get(comp->larb_dev); - if (err) { - enum mtk_mdp_comp_type comp_type = - (enum mtk_mdp_comp_type) - of_device_get_match_data(comp->dev); - dev_err(comp->dev, - "failed to get larb, err %d. type:%d\n", - err, comp_type); - } - } - err = pm_runtime_get_sync(comp->dev); if (err < 0) dev_err(comp->dev, @@ -97,9 +84,6 @@ void mtk_mdp_comp_clock_off(struct mtk_mdp_comp *comp) clk_disable_unprepare(comp->clk[i]); } - if (comp->larb_dev) - mtk_smi_larb_put(comp->larb_dev); - pm_runtime_put_sync(comp->dev); } @@ -132,12 +116,10 @@ static void mtk_mdp_comp_unbind(struct device *dev, struct device *master, int mtk_mdp_comp_init(struct mtk_mdp_comp *comp, struct device *dev) { - struct device_node *larb_node; - struct platform_device *larb_pdev; - int i; struct device_node *node = dev->of_node; enum mtk_mdp_comp_type comp_type = (enum mtk_mdp_comp_type)of_device_get_match_data(dev); + int i; INIT_LIST_HEAD(&comp->node); comp->dev = dev; @@ -156,30 +138,6 @@ int mtk_mdp_comp_init(struct mtk_mdp_comp *comp, struct device *dev) break; } - /* Only DMA capable components need the LARB property */ - comp->larb_dev = NULL; - if (comp_type != MTK_MDP_RDMA && - comp_type != MTK_MDP_WDMA && - comp_type != MTK_MDP_WROT) - return 0; - - larb_node = of_parse_phandle(node, "mediatek,larb", 0); - if (!larb_node) { - dev_err(dev, - "Missing mediadek,larb phandle in %pOF node\n", node); - return -EINVAL; - } - - larb_pdev = of_find_device_by_node(larb_node); - if (!larb_pdev) { - dev_warn(dev, "Waiting for larb device %pOF\n", larb_node); - of_node_put(larb_node); - return -EPROBE_DEFER; - } - of_node_put(larb_node); - - comp->larb_dev = &larb_pdev->dev; - return 0; } diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h index de158d3..355e226 100644 --- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h @@ -11,13 +11,11 @@ * struct mtk_mdp_comp - the MDP's function component data * @node: list node to track sibing MDP components * @clk: clocks required for component - * @larb_dev: SMI device required for component * @dev: component's device */ struct mtk_mdp_comp { struct list_headnode; struct clk *clk[2]; - struct device *larb_dev; struct device *dev; }; diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c index 133d107..bc5472d 100644 --- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c @@ -18,7 +18,6 @@ #include #include #include -#include #include "mtk_mdp_comp.h" #include "mtk_mdp_core.h" -- 1.9.1
[PATCH v4 09/17] media: mtk-vcodec: Get rid of mtk_smi_larb_get/put
MediaTek IOMMU has already added the device_link between the consumer and smi-larb device. If the vcodec device call the pm_runtime_get_sync, the smi-larb's pm_runtime_get_sync also be called automatically. CC: Tiffany Lin Signed-off-by: Yong Wu Reviewed-by: Evan Green --- .../media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c | 19 --- drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h | 3 --- drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c | 1 - .../media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c | 27 -- 4 files changed, 50 deletions(-) diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c index 36dfe3f..1d7d14d 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c @@ -8,14 +8,12 @@ #include #include #include -#include #include "mtk_vcodec_dec_pm.h" #include "mtk_vcodec_util.h" int mtk_vcodec_init_dec_pm(struct mtk_vcodec_dev *mtkdev) { - struct device_node *node; struct platform_device *pdev; struct mtk_vcodec_pm *pm; struct mtk_vcodec_clk *dec_clk; @@ -26,18 +24,7 @@ int mtk_vcodec_init_dec_pm(struct mtk_vcodec_dev *mtkdev) pm = &mtkdev->pm; pm->mtkdev = mtkdev; dec_clk = &pm->vdec_clk; - node = of_parse_phandle(pdev->dev.of_node, "mediatek,larb", 0); - if (!node) { - mtk_v4l2_err("of_parse_phandle mediatek,larb fail!"); - return -1; - } - pdev = of_find_device_by_node(node); - of_node_put(node); - if (WARN_ON(!pdev)) { - return -1; - } - pm->larbvdec = &pdev->dev; pdev = mtkdev->plat_dev; pm->dev = &pdev->dev; @@ -113,11 +100,6 @@ void mtk_vcodec_dec_clock_on(struct mtk_vcodec_pm *pm) } } - ret = mtk_smi_larb_get(pm->larbvdec); - if (ret) { - mtk_v4l2_err("mtk_smi_larb_get larbvdec fail %d", ret); - goto error; - } return; error: @@ -130,7 +112,6 @@ void mtk_vcodec_dec_clock_off(struct mtk_vcodec_pm *pm) struct mtk_vcodec_clk *dec_clk = &pm->vdec_clk; int i = 0; - mtk_smi_larb_put(pm->larbvdec); for (i = dec_clk->clk_num - 1; i >= 0; i--) clk_disable_unprepare(dec_clk->clk_info[i].vcodec_clk); } diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h index 52d1ce1..7d3966a 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h @@ -190,10 +190,7 @@ struct mtk_vcodec_clk { */ struct mtk_vcodec_pm { struct mtk_vcodec_clk vdec_clk; - struct device *larbvdec; - struct mtk_vcodec_clk venc_clk; - struct device *larbvenc; struct device *dev; struct mtk_vcodec_dev *mtkdev; }; diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c index 5301dca..18025f7 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c @@ -8,7 +8,6 @@ #include #include #include -#include #include #include "mtk_vcodec_drv.h" diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c index 01c6a55..047919e 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c @@ -8,44 +8,25 @@ #include #include #include -#include #include "mtk_vcodec_enc_pm.h" #include "mtk_vcodec_util.h" int mtk_vcodec_init_enc_pm(struct mtk_vcodec_dev *mtkdev) { - struct device_node *node; struct platform_device *pdev; struct mtk_vcodec_pm *pm; struct mtk_vcodec_clk *enc_clk; struct mtk_vcodec_clk_info *clk_info; int ret = 0, i = 0; - struct device *dev; pdev = mtkdev->plat_dev; pm = &mtkdev->pm; memset(pm, 0, sizeof(struct mtk_vcodec_pm)); pm->mtkdev = mtkdev; pm->dev = &pdev->dev; - dev = &pdev->dev; enc_clk = &pm->venc_clk; - node = of_parse_phandle(dev->of_node, "mediatek,larb", 0); - if (!node) { - mtk_v4l2_err("no mediatek,larb found"); - return -ENODEV; - } - pdev = of_find_device_by_node(node); - of_node_put(node); - if (!pdev) { - mtk_v4l2_err("no mediatek,larb device found"); - return -ENODEV; - } - pm->larbvenc = &pdev->dev; - pdev = mtkdev->plat_dev; - pm->dev = &pdev->dev; - enc_clk->clk_num = of_property_count_strings(pdev->dev.of_node, "clock-names"); if (enc_clk->clk_num > 0) { @@ -93,13 +74,6 @@ void mtk_vcodec_enc_clock_on(struct mtk_vcodec_pm
[PATCH v4 12/17] memory: mtk-smi: Get rid of mtk_smi_larb_get/put
After adding device_link between the iommu consumer and smi-larb, the pm_runtime_get(_sync) of smi-larb and smi-common will be called automatically. we can get rid of mtk_smi_larb_get/put. CC: Matthias Brugger Signed-off-by: Yong Wu Reviewed-by: Evan Green --- drivers/memory/mtk-smi.c | 14 -- include/soc/mediatek/smi.h | 20 2 files changed, 34 deletions(-) diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c index 6cdefda..19c3949 100644 --- a/drivers/memory/mtk-smi.c +++ b/drivers/memory/mtk-smi.c @@ -125,20 +125,6 @@ static void mtk_smi_clk_disable(const struct mtk_smi *smi) clk_disable_unprepare(smi->clk_apb); } -int mtk_smi_larb_get(struct device *larbdev) -{ - int ret = pm_runtime_get_sync(larbdev); - - return (ret < 0) ? ret : 0; -} -EXPORT_SYMBOL_GPL(mtk_smi_larb_get); - -void mtk_smi_larb_put(struct device *larbdev) -{ - pm_runtime_put_sync(larbdev); -} -EXPORT_SYMBOL_GPL(mtk_smi_larb_put); - static int mtk_smi_larb_bind(struct device *dev, struct device *master, void *data) { diff --git a/include/soc/mediatek/smi.h b/include/soc/mediatek/smi.h index 5a34b87..f8bf595 100644 --- a/include/soc/mediatek/smi.h +++ b/include/soc/mediatek/smi.h @@ -20,26 +20,6 @@ struct mtk_smi_larb_iommu { unsigned int mmu; }; -/* - * mtk_smi_larb_get: Enable the power domain and clocks for this local arbiter. - * It also initialize some basic setting(like iommu). - * mtk_smi_larb_put: Disable the power domain and clocks for this local arbiter. - * Both should be called in non-atomic context. - * - * Returns 0 if successful, negative on failure. - */ -int mtk_smi_larb_get(struct device *larbdev); -void mtk_smi_larb_put(struct device *larbdev); - -#else - -static inline int mtk_smi_larb_get(struct device *larbdev) -{ - return 0; -} - -static inline void mtk_smi_larb_put(struct device *larbdev) { } - #endif #endif -- 1.9.1
[PATCH v4 16/17] arm64: dts: mt8173: Separate mtk-vcodec-enc node
From: Irui Wang There are two separate hardware encoder blocks inside MT8173. Split the current mtk-vcodec-enc node to match the hardware architecture. Signed-off-by: Irui Wang Signed-off-by: Hsin-Yi Wang --- arch/arm64/boot/dts/mediatek/mt8173.dtsi | 60 +--- 1 file changed, 31 insertions(+), 29 deletions(-) diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi b/arch/arm64/boot/dts/mediatek/mt8173.dtsi index fb21a6b..9fccbec 100644 --- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi @@ -1364,13 +1364,10 @@ }; vcodec_enc: vcodec@18002000 { - compatible = "mediatek,mt8173-vcodec-enc"; - reg = <0 0x18002000 0 0x1000>, /* VENC_SYS */ - <0 0x19002000 0 0x1000>; /* VENC_LT_SYS */ - interrupts = , -; - mediatek,larb = <&larb3>, - <&larb5>; + compatible = "mediatek,mt8173-vcodec-avc-enc"; + reg = <0 0x18002000 0 0x1000>; /* VENC_SYS */ + interrupts = ; + mediatek,larb = <&larb3>; iommus = <&iommu M4U_PORT_VENC_RCPU>, <&iommu M4U_PORT_VENC_REC>, <&iommu M4U_PORT_VENC_BSDMA>, @@ -1381,29 +1378,12 @@ <&iommu M4U_PORT_VENC_REF_LUMA>, <&iommu M4U_PORT_VENC_REF_CHROMA>, <&iommu M4U_PORT_VENC_NBM_RDMA>, -<&iommu M4U_PORT_VENC_NBM_WDMA>, -<&iommu M4U_PORT_VENC_RCPU_SET2>, -<&iommu M4U_PORT_VENC_REC_FRM_SET2>, -<&iommu M4U_PORT_VENC_BSDMA_SET2>, -<&iommu M4U_PORT_VENC_SV_COMA_SET2>, -<&iommu M4U_PORT_VENC_RD_COMA_SET2>, -<&iommu M4U_PORT_VENC_CUR_LUMA_SET2>, -<&iommu M4U_PORT_VENC_CUR_CHROMA_SET2>, -<&iommu M4U_PORT_VENC_REF_LUMA_SET2>, -<&iommu M4U_PORT_VENC_REC_CHROMA_SET2>; +<&iommu M4U_PORT_VENC_NBM_WDMA>; mediatek,vpu = <&vpu>; - clocks = <&topckgen CLK_TOP_VENCPLL_D2>, -<&topckgen CLK_TOP_VENC_SEL>, -<&topckgen CLK_TOP_UNIVPLL1_D2>, -<&topckgen CLK_TOP_VENC_LT_SEL>; - clock-names = "venc_sel_src", - "venc_sel", - "venc_lt_sel_src", - "venc_lt_sel"; - assigned-clocks = <&topckgen CLK_TOP_VENC_SEL>, - <&topckgen CLK_TOP_VENC_LT_SEL>; - assigned-clock-parents = <&topckgen CLK_TOP_VENCPLL_D2>, -<&topckgen CLK_TOP_UNIVPLL1_D2>; + clocks = <&topckgen CLK_TOP_VENC_SEL>; + clock-names = "venc_sel"; + assigned-clocks = <&topckgen CLK_TOP_VENC_SEL>; + assigned-clock-parents = <&topckgen CLK_TOP_VCODECPLL>; }; jpegdec: jpegdec@18004000 { @@ -1435,6 +1415,28 @@ <&vencltsys CLK_VENCLT_CKE0>; clock-names = "apb", "smi"; }; + + vcodec_enc_lt: vcodec@19002000 { + compatible = "mediatek,mt8173-vcodec-vp8-enc"; + reg = <0 0x19002000 0 0x1000>; /* VENC_LT_SYS */ + interrupts = ; + iommus = <&iommu M4U_PORT_VENC_RCPU_SET2>, +<&iommu M4U_PORT_VENC_REC_FRM_SET2>, +<&iommu M4U_PORT_VENC_BSDMA_SET2>, +<&iommu M4U_PORT_VENC_SV_COMA_SET2>, +<&iommu M4U_PORT_VENC_RD_COMA_SET2>, +<&iommu M4U_PORT_VENC_CUR_LUMA_SET2>, +<&iommu M4U_PORT_VENC_CUR_CHROMA_SET2>, +<&iommu M4U_PORT_VENC_REF_LUMA_SET2>, +<&iommu M4U_PORT_VENC_REC_CHROMA_SET2>; + mediatek,larb = <&larb5>; + mediatek,vpu = <&vpu>; + clocks = <&topckgen CLK_TOP_VENC_LT_SEL>; + clock-names = "venc_lt_sel"; + assigned-clocks = <&topckgen CLK_TOP_VENC_LT_SEL>; + assigned-clock-parents = <&topckgen +
[PATCH v4 11/17] drm/mediatek: Get rid of mtk_smi_larb_get/put
MediaTek IOMMU has already added the device_link between the consumer and smi-larb device. If the drm device call the pm_runtime_get_sync, the smi-larb's pm_runtime_get_sync also be called automatically. CC: CK Hu CC: Philipp Zabel Signed-off-by: Yong Wu Reviewed-by: Evan Green --- drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 9 - drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 21 - drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 1 - 3 files changed, 31 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c index c9bc844..d4c4078 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c @@ -8,7 +8,6 @@ #include #include -#include #include #include @@ -532,12 +531,6 @@ static void mtk_drm_crtc_atomic_enable(struct drm_crtc *crtc, DRM_DEBUG_DRIVER("%s %d\n", __func__, crtc->base.id); - ret = mtk_smi_larb_get(comp->larb_dev); - if (ret) { - DRM_ERROR("Failed to get larb: %d\n", ret); - return; - } - ret = pm_runtime_get_sync(comp->dev); if (ret < 0) DRM_DEV_ERROR(comp->dev, "Failed to enable power domain: %d\n", @@ -545,7 +538,6 @@ static void mtk_drm_crtc_atomic_enable(struct drm_crtc *crtc, ret = mtk_crtc_ddp_hw_init(mtk_crtc); if (ret) { - mtk_smi_larb_put(comp->larb_dev); pm_runtime_put(comp->dev); return; } @@ -582,7 +574,6 @@ static void mtk_drm_crtc_atomic_disable(struct drm_crtc *crtc, drm_crtc_vblank_off(crtc); mtk_crtc_ddp_hw_fini(mtk_crtc); - mtk_smi_larb_put(comp->larb_dev); ret = pm_runtime_put(comp->dev); if (ret < 0) DRM_DEV_ERROR(comp->dev, "Failed to disable power domain: %d\n", diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c index 593027a..a6e7f3a 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c @@ -432,8 +432,6 @@ int mtk_ddp_comp_init(struct device *dev, struct device_node *node, const struct mtk_ddp_comp_funcs *funcs) { enum mtk_ddp_comp_type type; - struct device_node *larb_node; - struct platform_device *larb_pdev; #if IS_REACHABLE(CONFIG_MTK_CMDQ) struct resource res; struct cmdq_client_reg cmdq_reg; @@ -468,31 +466,12 @@ int mtk_ddp_comp_init(struct device *dev, struct device_node *node, if (IS_ERR(comp->clk)) return PTR_ERR(comp->clk); - /* Only DMA capable components need the LARB property */ - comp->larb_dev = NULL; if (type != MTK_DISP_OVL && type != MTK_DISP_OVL_2L && type != MTK_DISP_RDMA && type != MTK_DISP_WDMA) return 0; - larb_node = of_parse_phandle(node, "mediatek,larb", 0); - if (!larb_node) { - dev_err(dev, - "Missing mediadek,larb phandle in %pOF node\n", node); - return -EINVAL; - } - - larb_pdev = of_find_device_by_node(larb_node); - if (!larb_pdev) { - dev_warn(dev, "Waiting for larb device %pOF\n", larb_node); - of_node_put(larb_node); - return -EPROBE_DEFER; - } - of_node_put(larb_node); - - comp->larb_dev = &larb_pdev->dev; - comp->dev = dev; #if IS_REACHABLE(CONFIG_MTK_CMDQ) diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h index 4c063e0..11c7120 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h @@ -98,7 +98,6 @@ struct mtk_ddp_comp { struct clk *clk; void __iomem *regs; int irq; - struct device *larb_dev; struct device *dev; enum mtk_ddp_comp_id id; const struct mtk_ddp_comp_funcs *funcs; -- 1.9.1
[PATCH v4 15/17] arm: dts: mediatek: Get rid of mediatek,larb for MM nodes
After adding device_link between the IOMMU consumer and smi, the mediatek,larb is unnecessary now. CC: Matthias Brugger Signed-off-by: Yong Wu Reviewed-by: Evan Green --- arch/arm/boot/dts/mt2701.dtsi | 1 - arch/arm/boot/dts/mt7623.dtsi | 1 - 2 files changed, 2 deletions(-) diff --git a/arch/arm/boot/dts/mt2701.dtsi b/arch/arm/boot/dts/mt2701.dtsi index 2093b38..79da94c 100644 --- a/arch/arm/boot/dts/mt2701.dtsi +++ b/arch/arm/boot/dts/mt2701.dtsi @@ -564,7 +564,6 @@ clock-names = "jpgdec-smi", "jpgdec"; power-domains = <&scpsys MT2701_POWER_DOMAIN_ISP>; - mediatek,larb = <&larb2>; iommus = <&iommu MT2701_M4U_PORT_JPGDEC_WDMA>, <&iommu MT2701_M4U_PORT_JPGDEC_BSDMA>; }; diff --git a/arch/arm/boot/dts/mt7623.dtsi b/arch/arm/boot/dts/mt7623.dtsi index f76b4a3..f334039 100644 --- a/arch/arm/boot/dts/mt7623.dtsi +++ b/arch/arm/boot/dts/mt7623.dtsi @@ -783,7 +783,6 @@ clock-names = "jpgdec-smi", "jpgdec"; power-domains = <&scpsys MT2701_POWER_DOMAIN_ISP>; - mediatek,larb = <&larb2>; iommus = <&iommu MT2701_M4U_PORT_JPGDEC_WDMA>, <&iommu MT2701_M4U_PORT_JPGDEC_BSDMA>; }; -- 1.9.1
[PATCH v4 13/17] iommu/mediatek: Use module_platform_driver
MediaTek IOMMU should wait for smi larb which need wait for the power domain(mtk-scpsys.c) and the multimedia ccf, both are module init. Thus, subsys_initcall for MediaTek IOMMU is not helpful. Switch to module_platform_driver. Correspondingly, add the module license information. Signed-off-by: Yong Wu --- for iommu v1: honghui's mail address is not valid now. I will be responsible for that file too, So I add myself in it. --- drivers/iommu/mtk_iommu.c| 18 ++ drivers/iommu/mtk_iommu_v1.c | 12 +++- 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c index 5c3a6ba..0740ca9 100644 --- a/drivers/iommu/mtk_iommu.c +++ b/drivers/iommu/mtk_iommu.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -823,16 +824,9 @@ static int __maybe_unused mtk_iommu_resume(struct device *dev) .pm = &mtk_iommu_pm_ops, } }; +module_platform_driver(mtk_iommu_driver); -static int __init mtk_iommu_init(void) -{ - int ret; - - ret = platform_driver_register(&mtk_iommu_driver); - if (ret != 0) - pr_err("Failed to register MTK IOMMU driver\n"); - - return ret; -} - -subsys_initcall(mtk_iommu_init) +MODULE_DESCRIPTION("IOMMU API for MediaTek M4U implementations"); +MODULE_AUTHOR("Yong Wu "); +MODULE_ALIAS("platform:MediaTek-M4U"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c index 26b6c79..0852cb3 100644 --- a/drivers/iommu/mtk_iommu_v1.c +++ b/drivers/iommu/mtk_iommu_v1.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -711,9 +712,10 @@ static int __maybe_unused mtk_iommu_resume(struct device *dev) .pm = &mtk_iommu_pm_ops, } }; +module_platform_driver(mtk_iommu_driver); -static int __init m4u_init(void) -{ - return platform_driver_register(&mtk_iommu_driver); -} -subsys_initcall(m4u_init); +MODULE_DESCRIPTION("IOMMU API for MediaTek M4U v1 implementations"); +MODULE_AUTHOR("Yong Wu "); +MODULE_AUTHOR("Honghui Zhang "); +MODULE_ALIAS("platform:MediaTek-M4U-v1"); +MODULE_LICENSE("GPL v2"); -- 1.9.1
[PATCH v4 14/17] memory: mtk-smi: Use device_is_bound to check if smi-common is ready
smi-larb driver should run after smi-common, Use device_is_bound to confirm whether smicommon driver is ready. CC: Matthias Brugger Signed-off-by: Yong Wu --- drivers/memory/mtk-smi.c | 8 +++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c index 19c3949..0f8cd50 100644 --- a/drivers/memory/mtk-smi.c +++ b/drivers/memory/mtk-smi.c @@ -296,8 +296,14 @@ static int mtk_smi_larb_probe(struct platform_device *pdev) smi_pdev = of_find_device_by_node(smi_node); of_node_put(smi_node); if (smi_pdev) { - if (!platform_get_drvdata(smi_pdev)) + bool smicommon_is_bound; + + device_lock(&smi_pdev->dev); + smicommon_is_bound = device_is_bound(&smi_pdev->dev); + device_unlock(&smi_pdev->dev); + if (!smicommon_is_bound) return -EPROBE_DEFER; + larb->smi_common_dev = &smi_pdev->dev; link = device_link_add(dev, larb->smi_common_dev, DL_FLAG_PM_RUNTIME | DL_FLAG_STATELESS); -- 1.9.1
[PATCH v4 17/17] arm64: dts: mediatek: Get rid of mediatek,larb for MM nodes
After adding device_link between the IOMMU consumer and smi, the mediatek,larb is unnecessary now. CC: Matthias Brugger Signed-off-by: Yong Wu Reviewed-by: Evan Green --- arch/arm64/boot/dts/mediatek/mt8173.dtsi | 16 1 file changed, 16 deletions(-) diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi b/arch/arm64/boot/dts/mediatek/mt8173.dtsi index 9fccbec..7eed8c8 100644 --- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi @@ -926,7 +926,6 @@ <&mmsys CLK_MM_MUTEX_32K>; power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; iommus = <&iommu M4U_PORT_MDP_RDMA0>; - mediatek,larb = <&larb0>; mediatek,vpu = <&vpu>; }; @@ -937,7 +936,6 @@ <&mmsys CLK_MM_MUTEX_32K>; power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; iommus = <&iommu M4U_PORT_MDP_RDMA1>; - mediatek,larb = <&larb4>; }; mdp_rsz0: rsz@14003000 { @@ -967,7 +965,6 @@ clocks = <&mmsys CLK_MM_MDP_WDMA>; power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; iommus = <&iommu M4U_PORT_MDP_WDMA>; - mediatek,larb = <&larb0>; }; mdp_wrot0: wrot@14007000 { @@ -976,7 +973,6 @@ clocks = <&mmsys CLK_MM_MDP_WROT0>; power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; iommus = <&iommu M4U_PORT_MDP_WROT0>; - mediatek,larb = <&larb0>; }; mdp_wrot1: wrot@14008000 { @@ -985,7 +981,6 @@ clocks = <&mmsys CLK_MM_MDP_WROT1>; power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; iommus = <&iommu M4U_PORT_MDP_WROT1>; - mediatek,larb = <&larb4>; }; ovl0: ovl@1400c000 { @@ -995,7 +990,6 @@ power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; clocks = <&mmsys CLK_MM_DISP_OVL0>; iommus = <&iommu M4U_PORT_DISP_OVL0>; - mediatek,larb = <&larb0>; }; ovl1: ovl@1400d000 { @@ -1005,7 +999,6 @@ power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; clocks = <&mmsys CLK_MM_DISP_OVL1>; iommus = <&iommu M4U_PORT_DISP_OVL1>; - mediatek,larb = <&larb4>; }; rdma0: rdma@1400e000 { @@ -1015,7 +1008,6 @@ power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; clocks = <&mmsys CLK_MM_DISP_RDMA0>; iommus = <&iommu M4U_PORT_DISP_RDMA0>; - mediatek,larb = <&larb0>; }; rdma1: rdma@1400f000 { @@ -1025,7 +1017,6 @@ power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; clocks = <&mmsys CLK_MM_DISP_RDMA1>; iommus = <&iommu M4U_PORT_DISP_RDMA1>; - mediatek,larb = <&larb4>; }; rdma2: rdma@1401 { @@ -1035,7 +1026,6 @@ power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; clocks = <&mmsys CLK_MM_DISP_RDMA2>; iommus = <&iommu M4U_PORT_DISP_RDMA2>; - mediatek,larb = <&larb4>; }; wdma0: wdma@14011000 { @@ -1045,7 +1035,6 @@ power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; clocks = <&mmsys CLK_MM_DISP_WDMA0>; iommus = <&iommu M4U_PORT_DISP_WDMA0>; - mediatek,larb = <&larb0>; }; wdma1: wdma@14012000 { @@ -1055,7 +1044,6 @@ power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; clocks = <&mmsys CLK_MM_DISP_WDMA1>; iommus = <&iommu M4U_PORT_DISP_WDMA1>; - mediatek,larb = <&larb4>; }; color0: color@14013000 { @@ -1299,7 +1287,6 @@ <0 0x16027800 0 0x800>, /* VDEC_HWB */ <0 0x16028400 0 0x400>; /* VDEC_HWG */ interrupts = ; - mediatek,larb = <&larb1>; iommus = <&iommu M4U_PORT_HW_VDEC_MC_EXT>, <&iommu M4U_PORT_HW_VDEC_PP_EXT>, <&iommu M4U_PORT_HW_VDEC_AVC_MV_EXT>, @@ -1367,7 +1354,6 @@ compatible = "mediatek,mt8173-vcodec-avc-enc";
[PATCH] scsi: acornscsi: Fix an error handling path in 'acornscsi_probe()'
'ret' is known to be 0 at this point. So, explicitly return -ENOMEM if one of the 'ecardm_iomap()' calls fail. Fixes: e95a1b656a98 ("[ARM] rpc: acornscsi: update to new style ecard driver") Signed-off-by: Christophe JAILLET --- drivers/scsi/arm/acornscsi.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/arm/acornscsi.c b/drivers/scsi/arm/acornscsi.c index ddb52e7ba622..9a912fd0f70b 100644 --- a/drivers/scsi/arm/acornscsi.c +++ b/drivers/scsi/arm/acornscsi.c @@ -2911,8 +2911,10 @@ static int acornscsi_probe(struct expansion_card *ec, const struct ecard_id *id) ashost->base = ecardm_iomap(ec, ECARD_RES_MEMC, 0, 0); ashost->fast = ecardm_iomap(ec, ECARD_RES_IOCFAST, 0, 0); - if (!ashost->base || !ashost->fast) + if (!ashost->base || !ashost->fast) { + ret = -ENOMEM; goto out_put; + } host->irq = ec->irq; ashost->host = host; -- 2.25.1
[PATCH 2/3] perf tests: Don't tail call optimize in unwind test
The tail call optimization can unexpectedly make the stack smaller and cause the test to fail. Signed-off-by: Ian Rogers --- tools/perf/tests/dwarf-unwind.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tools/perf/tests/dwarf-unwind.c b/tools/perf/tests/dwarf-unwind.c index 779ce280a0e9..2a0dac81f44c 100644 --- a/tools/perf/tests/dwarf-unwind.c +++ b/tools/perf/tests/dwarf-unwind.c @@ -94,7 +94,7 @@ static int unwind_entry(struct unwind_entry *entry, void *arg) return strcmp((const char *) symbol, funcs[idx]); } -noinline int test_dwarf_unwind__thread(struct thread *thread) +__no_tail_call noinline int test_dwarf_unwind__thread(struct thread *thread) { struct perf_sample sample; unsigned long cnt = 0; @@ -125,7 +125,7 @@ noinline int test_dwarf_unwind__thread(struct thread *thread) static int global_unwind_retval = -INT_MAX; -noinline int test_dwarf_unwind__compare(void *p1, void *p2) +__no_tail_call noinline int test_dwarf_unwind__compare(void *p1, void *p2) { /* Any possible value should be 'thread' */ struct thread *thread = *(struct thread **)p1; @@ -144,7 +144,7 @@ noinline int test_dwarf_unwind__compare(void *p1, void *p2) return p1 - p2; } -noinline int test_dwarf_unwind__krava_3(struct thread *thread) +__no_tail_call noinline int test_dwarf_unwind__krava_3(struct thread *thread) { struct thread *array[2] = {thread, thread}; void *fp = &bsearch; @@ -163,12 +163,12 @@ noinline int test_dwarf_unwind__krava_3(struct thread *thread) return global_unwind_retval; } -noinline int test_dwarf_unwind__krava_2(struct thread *thread) +__no_tail_call noinline int test_dwarf_unwind__krava_2(struct thread *thread) { return test_dwarf_unwind__krava_3(thread); } -noinline int test_dwarf_unwind__krava_1(struct thread *thread) +__no_tail_call noinline int test_dwarf_unwind__krava_1(struct thread *thread) { return test_dwarf_unwind__krava_2(thread); } -- 2.27.0.rc2.251.g90737beb825-goog
[PATCH 1/3] tools compiler.h: Add attribute to disable tail calls
Tail call optimizations can remove stack frames that are used in unwinding tests. Add an attribute that can be used to disable the tail call optimization. Tested on clang and GCC. Signed-off-by: Ian Rogers --- tools/include/linux/compiler-gcc.h | 8 tools/include/linux/compiler.h | 3 +++ 2 files changed, 11 insertions(+) diff --git a/tools/include/linux/compiler-gcc.h b/tools/include/linux/compiler-gcc.h index 95c072b70d0e..cda555b47d3d 100644 --- a/tools/include/linux/compiler-gcc.h +++ b/tools/include/linux/compiler-gcc.h @@ -27,6 +27,14 @@ #define __pure__attribute__((pure)) #endif #define noinline __attribute__((noinline)) +#ifdef __has_attribute +#if __has_attribute(disable_tail_calls) +#define __no_tail_call __attribute__((disable_tail_calls)) +#endif +#endif +#ifndef __no_tail_call +#define __no_tail_call __attribute__((optimize("no-optimize-sibling-calls"))) +#endif #ifndef __packed #define __packed __attribute__((packed)) #endif diff --git a/tools/include/linux/compiler.h b/tools/include/linux/compiler.h index 180f7714a5f1..9f9002734e19 100644 --- a/tools/include/linux/compiler.h +++ b/tools/include/linux/compiler.h @@ -47,6 +47,9 @@ #ifndef noinline #define noinline #endif +#ifndef __no_tail_call +#define __no_tail_call +#endif /* Are two types/vars the same type (ignoring qualifiers)? */ #ifndef __same_type -- 2.27.0.rc2.251.g90737beb825-goog
[PATCH 3/3] perf test: Initialize memory in dwarf-unwind
Avoid a false positive caused by assembly code in arch/x86. In tests, zero the perf_event to avoid uninitialized memory uses. Warnings were caught using clang with -fsanitize=memory. Signed-off-by: Ian Rogers --- tools/perf/arch/x86/tests/dwarf-unwind.c | 8 tools/perf/tests/dwarf-unwind.c | 1 + 2 files changed, 9 insertions(+) diff --git a/tools/perf/arch/x86/tests/dwarf-unwind.c b/tools/perf/arch/x86/tests/dwarf-unwind.c index ef43be9b6ec2..4e40402a4f81 100644 --- a/tools/perf/arch/x86/tests/dwarf-unwind.c +++ b/tools/perf/arch/x86/tests/dwarf-unwind.c @@ -55,6 +55,14 @@ int test__arch_unwind_sample(struct perf_sample *sample, return -1; } +#ifdef MEMORY_SANITIZER + /* +* Assignments to buf in the assembly function perf_regs_load aren't +* seen by memory sanitizer. Zero the memory to convince memory +* sanitizer the memory is initialized. +*/ + memset(buf, 0, sizeof(u64) * PERF_REGS_MAX); +#endif perf_regs_load(buf); regs->abi = PERF_SAMPLE_REGS_ABI; regs->regs = buf; diff --git a/tools/perf/tests/dwarf-unwind.c b/tools/perf/tests/dwarf-unwind.c index 2a0dac81f44c..2491d167bf76 100644 --- a/tools/perf/tests/dwarf-unwind.c +++ b/tools/perf/tests/dwarf-unwind.c @@ -37,6 +37,7 @@ static int init_live_machine(struct machine *machine) union perf_event event; pid_t pid = getpid(); + memset(&event, 0, sizeof(event)); return perf_event__synthesize_mmap_events(NULL, &event, pid, pid, mmap_handler, machine, true); } -- 2.27.0.rc2.251.g90737beb825-goog
[PATCH 0/3] perf test: Unwind fixes
Fix stack frame count and memory sanitizer issues when running the dwarf unwinding test with the elfutils/libdw unwinder (libunwind disabled). Ian Rogers (3): tools compiler.h: Add attribute to disable tail calls perf tests: Don't tail call optimize in unwind test perf test: Initialize memory in dwarf-unwind tools/include/linux/compiler-gcc.h | 8 tools/include/linux/compiler.h | 3 +++ tools/perf/arch/x86/tests/dwarf-unwind.c | 8 tools/perf/tests/dwarf-unwind.c | 11 ++- 4 files changed, 25 insertions(+), 5 deletions(-) -- 2.27.0.rc2.251.g90737beb825-goog
[PATCH] dlm: Fix a typo in a comment
s/locksapce/lockspace/ Signed-off-by: Christophe JAILLET --- fs/dlm/lockspace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/dlm/lockspace.c b/fs/dlm/lockspace.c index e93670ecfae5..f17e091daab3 100644 --- a/fs/dlm/lockspace.c +++ b/fs/dlm/lockspace.c @@ -859,7 +859,7 @@ static int release_lockspace(struct dlm_ls *ls, int force) * until this returns. * * Force has 4 possible values: - * 0 - don't destroy locksapce if it has any LKBs + * 0 - don't destroy lockspace if it has any LKBs * 1 - destroy lockspace if it has remote LKBs but not if it has local LKBs * 2 - destroy lockspace regardless of LKBs * 3 - destroy lockspace as part of a forced shutdown -- 2.25.1
Re: linux-next: manual merge of the arm tree with Linus' tree
On Thu, May 28, 2020 at 09:01:55AM +0200, Ard Biesheuvel wrote: > On Thu, 28 May 2020 at 01:23, Russell King - ARM Linux admin > wrote: > > > > Ard, > > > > Please take a look. Obviously, whatever the resolution is going to be > > needed when Linus opens the merge window. > > > > Sorry for that. > > I have pushed the signed tag below to resolve it. Those changes were > already in v5.7-rc2, so I wouldn't expect this to cause more trouble. > If you prefer, you could merge v5.7-rc2 into your tree directly > instead. In light of Stephen's report of a different conflict on the 29th, I haven't pulled this. I don't know if that's a side effect of this change having been picked up by -next or not. -- RMK's Patch system: https://www.armlinux.org.uk/developer/patches/ FTTC for 0.8m (est. 1762m) line in suburbia: sync at 13.1Mbps down 424kbps up
Re: [PATCH v2 09/12] iio: imu: inv_icm42600: add buffer support in iio devices
Hi Jean-Baptiste, Thank you for the patch! Yet something to improve: [auto build test ERROR on iio/togreg] [also build test ERROR on robh/for-next linus/master v5.7-rc7 next-20200529] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system. BTW, we also suggest to use '--base' option to specify the base tree in git format-patch, please see https://stackoverflow.com/a/37406982] url: https://github.com/0day-ci/linux/commits/Jean-Baptiste-Maneyrol/iio-imu-new-inv_icm42600-driver/20200528-030632 base: https://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio.git togreg config: i386-randconfig-c001-20200529 (attached as .config) compiler: gcc-9 (Debian 9.3.0-13) 9.3.0 If you fix the issue, kindly add following tag as appropriate Reported-by: kbuild test robot All errors (new ones prefixed by >>, old ones prefixed by <<): ld: drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.o: in function `inv_icm42600_buffer_update_watermark': drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c:215: undefined reference to `__moddi3' >> ld: drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c:212: undefined >> reference to `__moddi3' --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-...@lists.01.org .config.gz Description: application/gzip
Re: [PATCH v7 1/4] bitops: Introduce the the for_each_set_clump macro
On Sat, May 30, 2020 at 3:49 AM Andy Shevchenko wrote: > > On Sat, May 30, 2020 at 1:11 AM Syed Nayyar Waris > wrote: > > On Sat, May 30, 2020 at 3:13 AM Andy Shevchenko > > wrote: > > > On Fri, May 29, 2020 at 11:07 PM Syed Nayyar Waris > > > wrote: > > > > On Sat, May 30, 2020 at 12:08 AM Andy Shevchenko > > > > wrote: > > > > > On Fri, May 29, 2020 at 11:38:18PM +0530, Syed Nayyar Waris wrote: > > > > > > On Sun, May 24, 2020 at 8:15 PM kbuild test robot > > > > > > wrote: > > > > > > ... > > > > > > > > > Taking the example statement (in my patch) where compilation warning > > > > > > is getting reported: > > > > > > return (map[index] >> offset) & GENMASK(nbits - 1, 0); > > > > > > > > > > > > 'nbits' is of type 'unsigned long'. > > > > > > In above, the sanity check is comparing '0' with unsigned value. And > > > > > > unsigned value can't be less than '0' ever, hence the warning. > > > > > > But this warning will occur whenever there will be '0' as one of the > > > > > > 'argument' and an unsigned variable as another 'argument' for > > > > > > GENMASK. > > > > > > > > Proper fix is to fix GENMASK(), but allowed workaround is to use > > > > > (BIT(nbits) - 1) > > > > > instead. > > > > > > > When I used BIT macro (earlier), I had faced a problem. I want to tell > > > > you about that. > > > > > > > > Inside functions 'bitmap_set_value' and 'bitmap_get_value' when nbits > > > > (or > > > > clump size) is BITS_PER_LONG, unexpected calculation happens. > > > > > > > > Explanation: > > > > Actually when nbits (clump size) is 64 (BITS_PER_LONG is 64 on my > > > > computer), > > > > (BIT(nbits) - 1) > > > > gives a value of zero and when this zero is ANDed with any value, it > > > > makes it full zero. This is unexpected and incorrect calculation > > > > happening. > > > > > > > > What actually happens is in the macro expansion of BIT(64), that is 1 > > > > << 64, the '1' overflows from leftmost bit position (most significant > > > > bit) and re-enters at the rightmost bit position (least significant > > > > bit), therefore 1 << 64 becomes '0x1', and when another '1' is > > > > subtracted from this, the final result becomes 0. > > > > > > > > Since this macro is being used in both bitmap_get_value and > > > > bitmap_set_value functions, it will give unexpected results when nbits > > > > or clump > > > > size is BITS_PER_LONG (32 or 64 depending on arch). > > > > > > I see, something like > > > https://elixir.bootlin.com/linux/latest/source/include/linux/dma-mapping.h#L139 > > > should be done. > > > But yes, let's try to fix GENMASK(). > > > > > > So, if we modify the following > > > > > > #define GENMASK_INPUT_CHECK(h, l) \ > > > (BUILD_BUG_ON_ZERO(__builtin_choose_expr( \ > > > __builtin_constant_p((l) > (h)), (l) > (h), 0))) > > > > > > to be > > > > > > #define GENMASK_INPUT_CHECK(h, l) \ > > > (BUILD_BUG_ON_ZERO(__builtin_choose_expr( \ > > > __builtin_constant_p((l) > (h)), (l) ? (l) > (h) : 0, 0))) > > > > > > would it work? > > > > Sorry Andy it is not working. Actually the warning will be thrown, > > whenever there will be comparison between 'h' and 'l'. If one of them > > is '0' and the other is unsigned variable. > > In above, still there is comparison being done between 'h' and 'l', so > > the warning is getting thrown. > > Ah, okay > > what about (l) && ((l) > (h)) ? When I finally changed: __builtin_constant_p((l) > (h)), (l) > (h), 0))) to: __builtin_constant_p((l) && ((l) > (h))), (l) ? (l) > (h) : 0, 0))) It is still throwing same compilation error at the same location where comparison is being done between 'l' and 'h'. Actually the short-circuit logic is not happening. For: (l) && ((l) > (h)) Even if 'l' is zero, it still proceeds to compare 'l' and 'h' , that is '((l) > (h))' is checked. I think it is happening because '__builtin_constant_p' will check the complete argument: (l) && ((l) > (h)), '__builtin_constant_p' checks whether the argument is compile time constant or not, so therefore, it will evaluate the WHOLE argument, that is (including) the comparison operation. https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html I am still investigating more on this. Let me know if you have any suggestions. > > > > > William also knows about this issue: > > > > "This is undefined behavior in the C standard (section 6.5.7 in the > > > > N1124)" > > > > > > I think it is about 6.5.7.3 here, 1U << 31 (or 63) is okay. > > > > Actually for: > > (BIT(nbits) - 1) > > When nbits will be BITS_PER_LONG it will be 1U << 32 (or 64). Isn't it ? > > The expression, > > BIT(64) - 1 > > can become unexpectedly zero (incorrectly). > > Yes, that's why I pointed out to the paragraph. It's about right > operand to be "great than or equal to" the size of type of left > operand. > Thank You. I understand now. :-) Regards Syed Nayyar Waris
Re: [GIT PULL] sh: remove sh5 support
On Sat, May 30, 2020 at 10:08 AM John Paul Adrian Glaubitz wrote: > On 5/29/20 7:53 PM, Rich Felker wrote: > > Frustratingly, I _still_ don't have an official tree on kernel.org for > > the purpose of being the canonical place for linux-next to pull from, > > due to policies around pgp keys and nobody following up on signing > > mine. This is all really silly since there are ridiculously many > > independent channels I could cryptographically validate identity > > through with vanishing probability that they're all compromised. For > > the time being I'll reactivate my repo on git.musl-libc.org. > > May I suggest to pick up these patches, for example? There might be > more I missed, but getting these merged should already help a lot with > the clean-up of arch/sh. And https://marc.info/?l=linux-arch&m=153337991312146&w=2 Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
Re: linux-next: manual merge of the arm tree with Linus' tree
On Sat, 30 May 2020 at 10:41, Russell King - ARM Linux admin wrote: > > On Thu, May 28, 2020 at 09:01:55AM +0200, Ard Biesheuvel wrote: > > On Thu, 28 May 2020 at 01:23, Russell King - ARM Linux admin > > wrote: > > > > > > Ard, > > > > > > Please take a look. Obviously, whatever the resolution is going to be > > > needed when Linus opens the merge window. > > > > > > > Sorry for that. > > > > I have pushed the signed tag below to resolve it. Those changes were > > already in v5.7-rc2, so I wouldn't expect this to cause more trouble. > > If you prefer, you could merge v5.7-rc2 into your tree directly > > instead. > > In light of Stephen's report of a different conflict on the 29th, I > haven't pulled this. I don't know if that's a side effect of this > change having been picked up by -next or not. > Fair enough. Both conflicts are unambiguous and self explanatory so I don't think it should be a problem, right?
[PATCH v3] firewire: Remove function callback casts
In 1394 OHCI specification, Isochronous Receive DMA context has several modes. One of mode is 'BufferFill' and Linux FireWire stack uses it to receive isochronous packets for multiple isochronous channel as FW_ISO_CONTEXT_RECEIVE_MULTICHANNEL. The mode is not used by in-kernel driver, while it's available for userspace. The character device driver in firewire-core includes cast of function callback for the mode since the type of callback function is different from the other modes. The case is inconvenient to effort of Control Flow Integrity builds due to -Wcast-function-type warning. This commit removes the cast. A static helper function is newly added to initialize isochronous context for the mode. The helper function arranges isochronous context to assign specific callback function after call of existent kernel API. It's noticeable that the number of isochronous channel, speed, and the size of header are not required for the mode. The helper function is used for the mode by character device driver instead of direct call of existent kernel API. The same goal can be achieved (in the ioctl_create_iso_context function) without this helper function as follows: - Call the fw_iso_context_create function passing NULL to the callback parameter. - Then setting the context->callback.sc or context->callback.mc variables based on the a->type value. However using the helper function created in this patch makes code more clear and declarative. This way avoid the call to a function with one purpose to achieved another one. Co-developed-by: Takashi Sakamoto Signed-off-by: Takashi Sakamoto Co-developed-by: Stefan Richter Signed-off-by: Stefan Richter Signed-off-by: Oscar Carter --- Hi, this is another proposal to achieved the goal of remove function callback cast start by me with the first [1] and second [2] versions, and followed by the work of Takashi Sakamoto with his first [3] and second [4] versions, and the code of Stefan Richter [5]. The purpose of this third version is to put together all the work done until now following the comments of all reviewed patches. I've added the "Co-developed-by" and "Signed-off-by" tags to give credit to Takashi Sakamoto and Stefan Richter if there are no objections. Changelog v1->v2 -Set explicity to NULL the "ctx->callback.sc" variable and return an error code in "fw_iso_context_create" function if both callback parameters are NULL as Lev R. Oshvang suggested. -Modify the commit changelog accordingly. Changelog v2->v3 -Put togeher all the work done in different patches by different authors. -Modify the previous work following the comments in the reviewed patches. [1] https://lore.kernel.org/lkml/20200516173934.31527-1-oscar.car...@gmx.com/ [2] https://lore.kernel.org/lkml/20200519173425.4724-1-oscar.car...@gmx.com/ [3] https://lore.kernel.org/lkml/20200520064726.31838-1-o-taka...@sakamocchi.jp/ [4] https://lore.kernel.org/lkml/20200524132048.243223-1-o-taka...@sakamocchi.jp/ [5] https://lore.kernel.org/lkml/20200525015532.0055f9df@kant/ drivers/firewire/core-cdev.c | 32 ++-- include/linux/firewire.h | 11 +++ 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c index 6e291d8f3a27..f7212331f245 100644 --- a/drivers/firewire/core-cdev.c +++ b/drivers/firewire/core-cdev.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -953,11 +954,25 @@ static enum dma_data_direction iso_dma_direction(struct fw_iso_context *context) return DMA_FROM_DEVICE; } +static struct fw_iso_context *fw_iso_mc_context_create(struct fw_card *card, + fw_iso_mc_callback_t callback, + void *callback_data) +{ + struct fw_iso_context *ctx; + + ctx = fw_iso_context_create(card, FW_ISO_CONTEXT_RECEIVE_MULTICHANNEL, + 0, 0, 0, NULL, callback_data); + if (!IS_ERR(ctx)) + ctx->callback.mc = callback; + + return ctx; +} + static int ioctl_create_iso_context(struct client *client, union ioctl_arg *arg) { struct fw_cdev_create_iso_context *a = &arg->create_iso_context; struct fw_iso_context *context; - fw_iso_callback_t cb; + union fw_iso_callback cb; int ret; BUILD_BUG_ON(FW_CDEV_ISO_CONTEXT_TRANSMIT != FW_ISO_CONTEXT_TRANSMIT || @@ -970,7 +985,7 @@ static int ioctl_create_iso_context(struct client *client, union ioctl_arg *arg) if (a->speed > SCODE_3200 || a->channel > 63) return -EINVAL; - cb = iso_callback; + cb.sc = iso_callback; break; case FW_ISO_CONTEXT_RECEIVE: @@ -978,19 +993,24 @@ static int ioctl_create_iso_context(struct client *client, union ioctl_arg *arg) a->channel > 63)
Re: linux-next: manual merge of the arm tree with Linus' tree
On Sat, May 30, 2020 at 10:51:32AM +0200, Ard Biesheuvel wrote: > On Sat, 30 May 2020 at 10:41, Russell King - ARM Linux admin > wrote: > > > > On Thu, May 28, 2020 at 09:01:55AM +0200, Ard Biesheuvel wrote: > > > On Thu, 28 May 2020 at 01:23, Russell King - ARM Linux admin > > > wrote: > > > > > > > > Ard, > > > > > > > > Please take a look. Obviously, whatever the resolution is going to be > > > > needed when Linus opens the merge window. > > > > > > > > > > Sorry for that. > > > > > > I have pushed the signed tag below to resolve it. Those changes were > > > already in v5.7-rc2, so I wouldn't expect this to cause more trouble. > > > If you prefer, you could merge v5.7-rc2 into your tree directly > > > instead. > > > > In light of Stephen's report of a different conflict on the 29th, I > > haven't pulled this. I don't know if that's a side effect of this > > change having been picked up by -next or not. > > > > Fair enough. Both conflicts are unambiguous and self explanatory so I > don't think it should be a problem, right? I don't know - I don't have a resolution for the first one, Stephen didn't provide a 3-way diff with his report, and I was expecting a 3-way diff from you for it rather than another pull request. I now also don't know whether the conflict on the 28th still exists or not. I'm completely confused, and I'm considering dropping the original EFI pull request on the grounds that the merge window opens tomorrow, and there isn't going to be another -next before that happens, so we don't know what's going to happen whatever action we take. -- RMK's Patch system: https://www.armlinux.org.uk/developer/patches/ FTTC for 0.8m (est. 1762m) line in suburbia: sync at 13.1Mbps down 424kbps up
Re: [PATCH v7 1/4] bitops: Introduce the the for_each_set_clump macro
On Sat, May 30, 2020 at 11:45 AM Syed Nayyar Waris wrote: > On Sat, May 30, 2020 at 3:49 AM Andy Shevchenko > wrote: ... > I am still investigating more on this. Let me know if you have any > suggestions. As far as I understand the start pointers are implementations of abs() macro followed by min()/max(). I think in the latter case it's actually something which might help here. Sorry, right now I have no time to dive deeper. -- With Best Regards, Andy Shevchenko
Re: [PATCH] opp: avoid uninitialized-variable use
On 29-05-20, 22:17, Arnd Bergmann wrote: > An uninitialized pointer is passed into another function but > ignored there: > > drivers/opp/core.c:875:32: error: variable 'opp' is uninitialized when used > here [-Werror,-Wuninitialized] > ret = _set_opp_bw(opp_table, opp, dev, true); > ^~~ > drivers/opp/core.c:849:34: note: initialize the variable 'opp' to silence > this warning > struct dev_pm_opp *old_opp, *opp; > ^ > > gcc no longer warns about this, but it seems it really should, > so change the code to just pass a NULL pointer here. > > See-also: 78a5255ffb6a ("Stop the ad-hoc games with -Wno-maybe-initialized") > Fixes: c57afacc9270 ("opp: Remove bandwidth votes when target_freq is zero") > Signed-off-by: Arnd Bergmann > --- > drivers/opp/core.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/opp/core.c b/drivers/opp/core.c > index df12c3804533..7302f2631f8d 100644 > --- a/drivers/opp/core.c > +++ b/drivers/opp/core.c > @@ -872,7 +872,7 @@ int dev_pm_opp_set_rate(struct device *dev, unsigned long > target_freq) > goto put_opp_table; > } > > - ret = _set_opp_bw(opp_table, opp, dev, true); > + ret = _set_opp_bw(opp_table, NULL, dev, true); > if (ret) > return ret; > Not sure why people are still seeing this, I pushed a fix for this 2 days back. -- viresh
Re: [PATCH 1/9] staging: media: atomisp: fix incorrect NULL pointer check
Em Fri, 29 May 2020 22:31:44 +0200 Arnd Bergmann escreveu: > On Fri, May 29, 2020 at 10:23 PM Arnd Bergmann wrote: > > > > On Fri, May 29, 2020 at 10:04 PM 'Nick Desaulniers' via Clang Built > > Linux wrote: > > > > > > See also Nathan's 7 patch series. > > > https://lore.kernel.org/lkml/20200527071150.3381228-1-natechancel...@gmail.com/ > > > > > > Might be some overlap between series? > > > > > > > Probably. I really should have checked when I saw the number of warnings. > > > > At least this gives Mauro a chance to double-check the changes and see if > > Nathan and I came to different conclusions on any of them. > > I checked now and found that the overlap is smaller than I expected. > In each case, Nathans' solution seems more complete than mine, > so this patch ("staging: media: atomisp: fix incorrect NULL pointer check") > and also "staging: media: atomisp: fix a type conversion warning" can be > dropped, but I think the others are still needed. Hi Arnd, I applied most of the patches from you. I had to add two extra patches before this one: [PATCH 5/9] staging: media: atomisp: fix stack overflow in init_pipe_defaults() And rebase it, because otherwise gcc would fail to compile here. I'm placing the patches I have so far ready for atomisp on this tree: https://git.linuxtv.org/mchehab/media-next.git/log/ Thanks, Mauro
Re: [PATCH] usb: cdns3: fix possible buffer overflow caused by bad DMA value
> To fix these possible bugs, index is checked before being used. How do you think about a wording variant like the following? Thus check the index before using it further. Would you like to add the tag “Fixes” to the commit message? Regards, Markus
Re: [PATCH] ARM: dts: imx53: ppd: alarm LEDs use kernel LED interface
Hi! > On Fri, May 29, 2020 at 06:02:04PM +0200, Pavel Machek wrote: > > > ping? > > > > Well, I thought that we maybe do not need standard LEDs on medical hardware. > > The discussion died and the patch was not applied :) In general > IDK how worthwhile it is to use standard LED names for them. I > suppose the number of people planning to create something like > OpenWRT for medical devices is not so big. :-) > > > > The device is a medical patient monitor and these are alarm LEDs > > > > informing about critical device or patient status. They are > > > > referenced by their color (those are discrete LEDs, not a > > > > multi-color one) basically everywhere. The only exception is > > > > "silenced", which means that audible alarm is surpressed. I > > > > don't think we have something comparable for any of those LEDs > > > > in the mainline tree. > > > > Actually, we have "platform:*:mute" LEDs, that could be used for > > "silenced". > > I see you point, but wonder if mute is the right choice. The LED > signals a silenced alarm, which IMHO is not the same: > > * The alarm silencing is temporary and system unsilences after > 1-2 minutes. > * LED is usually blinking instead of solid like a laptop mute LED > (so that operator is aware of silenced alarm) > * Device usually cannot be put into silenced mode before the alarm > appears > * Some medical devices still generate perodic beeps > > AFAIK this is named alarm silencing by basically everyone for > medical devices. So I think naming this platfrom:*:mute would > increase the mess. Ok, I guess it does not matter much. Generally no two LEDs behave exactly the same, and I'd believe this would be close enough, but ... it really does not matter. Best regards, Pavel -- (english) http://www.livejournal.com/~pavelmachek (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html signature.asc Description: PGP signature
[PATCH] dm writecache: reinitialize lru in writeback instead of endio
From: Huaisheng Ye When wc_entry has been removed from wbl->list in writeback, it will be not used again except waiting to be set free in writecache_free_entry. That is a little of annoying, it has to reinitialize lru of wc_entry in endio before calling writecache_free_entry. Using list_del_init instead of list_del in writeback for simpler code. Signed-off-by: Huaisheng Ye --- drivers/md/dm-writecache.c | 10 -- 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/md/dm-writecache.c b/drivers/md/dm-writecache.c index 7bbc21b..66f3a3b 100644 --- a/drivers/md/dm-writecache.c +++ b/drivers/md/dm-writecache.c @@ -1519,7 +1519,6 @@ static void __writecache_endio_pmem(struct dm_writecache *wc, struct list_head * e = wb->wc_list[i]; BUG_ON(!e->write_in_progress); e->write_in_progress = false; - INIT_LIST_HEAD(&e->lru); if (!writecache_has_error(wc)) writecache_free_entry(wc, e); BUG_ON(!wc->writeback_size); @@ -1555,7 +1554,6 @@ static void __writecache_endio_ssd(struct dm_writecache *wc, struct list_head *l do { BUG_ON(!e->write_in_progress); e->write_in_progress = false; - INIT_LIST_HEAD(&e->lru); if (!writecache_has_error(wc)) writecache_free_entry(wc, e); @@ -1654,7 +1652,7 @@ static void __writecache_writeback_pmem(struct dm_writecache *wc, struct writeba while (wbl->size) { wbl->size--; e = container_of(wbl->list.prev, struct wc_entry, lru); - list_del(&e->lru); + list_del_init(&e->lru); max_pages = e->wc_list_contiguous; @@ -1685,7 +1683,7 @@ static void __writecache_writeback_pmem(struct dm_writecache *wc, struct writeba if (!wc_add_block(wb, f, GFP_NOWAIT | __GFP_NOWARN)) break; wbl->size--; - list_del(&f->lru); + list_del_init(&f->lru); wb->wc_list[wb->wc_list_n++] = f; e = f; } @@ -1712,7 +1710,7 @@ static void __writecache_writeback_ssd(struct dm_writecache *wc, struct writebac wbl->size--; e = container_of(wbl->list.prev, struct wc_entry, lru); - list_del(&e->lru); + list_del_init(&e->lru); n_sectors = e->wc_list_contiguous << (wc->block_size_bits - SECTOR_SHIFT); @@ -1732,7 +1730,7 @@ static void __writecache_writeback_ssd(struct dm_writecache *wc, struct writebac wbl->size--; f = container_of(wbl->list.prev, struct wc_entry, lru); BUG_ON(f != e + 1); - list_del(&f->lru); + list_del_init(&f->lru); e = f; } -- 1.8.3.1
[PATCH] drivers/block/zram/zram_drv.c: remove ret check for invalid io request
From: Yue Hu There is no need to goto out to check ret if it's an invalid io request since we know ret = -EINVAL. Let's return the error directly in that case. Signed-off-by: Yue Hu --- drivers/block/zram/zram_drv.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c index 1bdb5793842b..bdca06930504 100644 --- a/drivers/block/zram/zram_drv.c +++ b/drivers/block/zram/zram_drv.c @@ -1639,8 +1639,7 @@ static int zram_rw_page(struct block_device *bdev, sector_t sector, if (!valid_io_request(zram, sector, PAGE_SIZE)) { atomic64_inc(&zram->stats.invalid_io); - ret = -EINVAL; - goto out; + return -EINVAL; } index = sector >> SECTORS_PER_PAGE_SHIFT; @@ -1651,7 +1650,7 @@ static int zram_rw_page(struct block_device *bdev, sector_t sector, bv.bv_offset = 0; ret = zram_bvec_rw(zram, &bv, index, offset, op, NULL); -out: + /* * If I/O fails, just return error(ie, non-zero) without * calling page_endio. -- 2.11.0
Re: [PATCH v2] check: Add 10bit/slave i2c reg flags support
> + addr = reg & 0x3FFFU; > + snprintf(unit_addr, sizeof(unit_addr), "%x", addr); Hmm, this hardcoded value will not work if we ever need to add another bit. I hope this will never happen, though. > + if ((reg & (1U << 31)) && addr > 0x3ff) Same here with bit 31. I haven't checked DTC but can't we import the header with the defines into the project? Or is this then a circular dependency? signature.asc Description: PGP signature
Re: [PATCH v3 2/2] drivers/irqchip: Use new macro ACPI_DECLARE_SUBTABLE_PROBE_ENTRY
Hi Oscar, On 2020-05-29 18:18, Oscar Carter wrote: In an effort to enable -Wcast-function-type in the top-level Makefile to support Control Flow Integrity builds, there are the need to remove all the function callback casts. To do this, modify the IRQCHIP_ACPI_DECLARE macro to use the new defined macro ACPI_DECLARE_SUBTABLE_PROBE_ENTRY instead of the macro ACPI_DECLARE_PROBE_ENTRY. This is necessary to be able to initialize the the acpi_probe_entry struct using the probe_subtbl field instead of the probe_table field and avoid function cast mismatches. Also, modify the prototype of the functions used by the invocation of the IRQCHIP_ACPI_DECLARE macro to match all the parameters. Co-developed-by: Marc Zyngier Signed-off-by: Marc Zyngier Signed-off-by: Oscar Carter --- drivers/irqchip/irq-gic-v3.c | 2 +- drivers/irqchip/irq-gic.c| 2 +- include/linux/irqchip.h | 5 +++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index d7006ef18a0d..3870e9d4d3a8 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c @@ -2117,7 +2117,7 @@ static void __init gic_acpi_setup_kvm_info(void) } static int __init -gic_acpi_init(struct acpi_subtable_header *header, const unsigned long end) +gic_acpi_init(union acpi_subtable_headers *header, const unsigned long end) { struct acpi_madt_generic_distributor *dist; struct fwnode_handle *domain_handle; diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index 30ab623343d3..fc431857ce90 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c @@ -1593,7 +1593,7 @@ static void __init gic_acpi_setup_kvm_info(void) gic_set_kvm_info(&gic_v2_kvm_info); } -static int __init gic_v2_acpi_init(struct acpi_subtable_header *header, +static int __init gic_v2_acpi_init(union acpi_subtable_headers *header, const unsigned long end) { struct acpi_madt_generic_distributor *dist; diff --git a/include/linux/irqchip.h b/include/linux/irqchip.h index 950e4b2458f0..447f22880a69 100644 --- a/include/linux/irqchip.h +++ b/include647b532275bbe/linux/irqchip.h @@ -39,8 +39,9 @@ * @fn: initialization function */ #define IRQCHIP_ACPI_DECLARE(name, subtable, validate, data, fn) \ - ACPI_DECLARE_PROBE_ENTRY(irqchip, name, ACPI_SIG_MADT, \ -subtable, validate, data, fn) + ACPI_DECLARE_SUBTABLE_PROBE_ENTRY(irqchip, name,\ + ACPI_SIG_MADT, subtable, \ + validate, data, fn) #ifdef CONFIG_IRQCHIP void irqchip_init(void); -- 2.20.1 I can't help but notice that you have left the cast in ACPI_DECLARE_PROBE_ENTRY, which should definitely go. Probably worth a third patch. Thanks, M. -- Jazz is not dead. It just smells funny...
Re: [PATCH v6 01/11] dt-bindings: i2c: Convert DW I2C binding to DT schema
Just double checking: > Signed-off-by: Serge Semin > Reviewed-by: Rob Herring Rob, what about this checkpatch warning? WARNING: DT binding documents should be licensed (GPL-2.0-only OR BSD-2-Clause) signature.asc Description: PGP signature
[RFC PATCH regulator] regulator: max8998: max8998_get_current_limit() can be static
Fixes: 4ffea5e083f8 ("regulator: max8998: Add charger regulator") Signed-off-by: kbuild test robot --- max8998.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/regulator/max8998.c b/drivers/regulator/max8998.c index 668ced0064179..ab16790a02068 100644 --- a/drivers/regulator/max8998.c +++ b/drivers/regulator/max8998.c @@ -415,7 +415,7 @@ int max8998_set_current_limit(struct regulator_dev *rdev, sel, rdev->desc->csel_mask); } -int max8998_get_current_limit(struct regulator_dev *rdev) +static int max8998_get_current_limit(struct regulator_dev *rdev) { struct max8998_data *max8998 = rdev_get_drvdata(rdev); struct i2c_client *i2c = max8998->iodev->i2c;
[PATCH 2/2] scsi: sr: Fix sr_probe() missing deallocate of device minor
If the cdrom fails to be registered then the device minor should be deallocated. Signed-off-by: Simon Arlott --- drivers/scsi/sr.c | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index 8d062d4f3ce0..1e13c6a0f0ca 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -797,7 +797,7 @@ static int sr_probe(struct device *dev) cd->cdi.disk = disk; if (register_cdrom(&cd->cdi)) - goto fail_put; + goto fail_minor; /* * Initialize block layer runtime PM stuffs before the @@ -815,6 +815,10 @@ static int sr_probe(struct device *dev) return 0; +fail_minor: + spin_lock(&sr_index_lock); + clear_bit(minor, sr_index_bits); + spin_unlock(&sr_index_lock); fail_put: put_disk(disk); mutex_destroy(&cd->lock); -- 2.17.1 -- Simon Arlott
[PATCH 1/2] scsi: sr: Fix sr_probe() missing mutex_destroy
If the device minor cannot be allocated or the cdrom fails to be registered then the mutex should be destroyed. Signed-off-by: Simon Arlott --- drivers/scsi/sr.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index d2fe3fa470f9..8d062d4f3ce0 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -817,6 +817,7 @@ static int sr_probe(struct device *dev) fail_put: put_disk(disk); + mutex_destroy(&cd->lock); fail_free: kfree(cd); fail: -- 2.17.1 -- Simon Arlott
Re: [PATCH] scsi: cumana_2: Fix different dev_id between 'request_irq()' and 'free_irq()'
On Sat, May 30, 2020 at 09:35:55AM +0200, Christophe JAILLET wrote: > The dev_id used in 'request_irq()' and 'free_irq()' should match. > So use 'host' in both cases. > > Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") > Signed-off-by: Christophe JAILLET This is itself wrong. cumanascsi_2_intr() requires "info" as the devid. Either cumanascsi_2_intr() needs changing to use shost_priv(host) along with this change, or free_irq() needs changing to use "info". Likely the same for the other patches, I haven't looked. -- RMK's Patch system: https://www.armlinux.org.uk/developer/patches/ FTTC for 0.8m (est. 1762m) line in suburbia: sync at 13.1Mbps down 424kbps up
Re: [PATCH] media: venus: Fix possible buffer overflow in venus_sfr_print()
Please avoid typos in the patch subject. > To fix this possible bug, sfr->buf_size is assigned to a local variable, > and then this variable is checked before being used. How do you think about a wording variant like the following? Thus assign the data structure member “buf_size” to a local variable and check it before further usage. Would you like to add the tag “Fixes” to the commit message? Regards, Markus
Re: linux-next: manual merge of the arm tree with Linus' tree
Hi Russell, On Sat, 30 May 2020 10:17:47 +0100 Russell King - ARM Linux admin wrote: > > I don't know - I don't have a resolution for the first one, Stephen > didn't provide a 3-way diff with his report, and I was expecting a > 3-way diff from you for it rather than another pull request. There is no 3-way diff, because "I just used the latter" i.e. I used the arm tree version of the conflicted section of the file. -- Cheers, Stephen Rothwell pgpFK08cto5PP.pgp Description: OpenPGP digital signature
[v3] ASoC: AMD: Use mixer control to switch between DMICs
Having mixer control to switch between DMICs prevents user to initiate capture simultaneously on both the DMIcs. Earlier 2 separate devices, one for each DMIC, gave an option of using them simultaneously, which is not supported. Signed-off-by: Akshu Agrawal --- v2: Modified "Front Mic" to "DMIC Switch" v3: Changed to using of Mux sound/soc/amd/acp3x-rt5682-max9836.c | 58 +++- 1 file changed, 31 insertions(+), 27 deletions(-) diff --git a/sound/soc/amd/acp3x-rt5682-max9836.c b/sound/soc/amd/acp3x-rt5682-max9836.c index e499c00e0c66..f745b42dfd23 100644 --- a/sound/soc/amd/acp3x-rt5682-max9836.c +++ b/sound/soc/amd/acp3x-rt5682-max9836.c @@ -188,25 +188,27 @@ static int acp3x_ec_dmic0_startup(struct snd_pcm_substream *substream) machine->cap_i2s_instance = I2S_BT_INSTANCE; snd_soc_dai_set_bclk_ratio(codec_dai, 64); - if (dmic_sel) - gpiod_set_value(dmic_sel, 0); return rt5682_clk_enable(substream); } -static int acp3x_ec_dmic1_startup(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_card *card = rtd->card; - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); - struct acp3x_platform_info *machine = snd_soc_card_get_drvdata(card); +static int dmic_switch; - machine->cap_i2s_instance = I2S_BT_INSTANCE; - snd_soc_dai_set_bclk_ratio(codec_dai, 64); - if (dmic_sel) - gpiod_set_value(dmic_sel, 1); +static int dmic_get(struct snd_kcontrol *kcontrol, +struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = dmic_switch; + return 0; +} - return rt5682_clk_enable(substream); +static int dmic_set(struct snd_kcontrol *kcontrol, +struct snd_ctl_elem_value *ucontrol) +{ + if (dmic_sel) { + dmic_switch = ucontrol->value.integer.value[0]; + gpiod_set_value(dmic_sel, dmic_switch); + } + return 0; } static void rt5682_shutdown(struct snd_pcm_substream *substream) @@ -229,11 +231,6 @@ static const struct snd_soc_ops acp3x_ec_cap0_ops = { .shutdown = rt5682_shutdown, }; -static const struct snd_soc_ops acp3x_ec_cap1_ops = { - .startup = acp3x_ec_dmic1_startup, - .shutdown = rt5682_shutdown, -}; - SND_SOC_DAILINK_DEF(acp3x_i2s, DAILINK_COMP_ARRAY(COMP_CPU("acp3x_i2s_playcap.0"))); SND_SOC_DAILINK_DEF(acp3x_bt, @@ -279,21 +276,26 @@ static struct snd_soc_dai_link acp3x_dai_5682_98357[] = { .ops = &acp3x_ec_cap0_ops, SND_SOC_DAILINK_REG(acp3x_bt, cros_ec, platform), }, - { - .name = "acp3x-ec-dmic1-capture", - .stream_name = "Capture DMIC1", - .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF - | SND_SOC_DAIFMT_CBS_CFS, - .dpcm_capture = 1, - .ops = &acp3x_ec_cap1_ops, - SND_SOC_DAILINK_REG(acp3x_bt, cros_ec, platform), - }, }; +static const char * const dmic_mux_text[] = { + "Front Mic", + "Rear Mic", +}; + +static SOC_ENUM_SINGLE_DECL( + acp3x_dmic_enum, SND_SOC_NOPM, 0, dmic_mux_text); + +static const struct snd_kcontrol_new acp3x_dmic_mux_control = + SOC_DAPM_ENUM_EXT("DMIC Select Mux", acp3x_dmic_enum, + dmic_get, dmic_set); + static const struct snd_soc_dapm_widget acp3x_widgets[] = { SND_SOC_DAPM_HP("Headphone Jack", NULL), SND_SOC_DAPM_SPK("Spk", NULL), SND_SOC_DAPM_MIC("Headset Mic", NULL), + SND_SOC_DAPM_MUX("Dmic Mux", SND_SOC_NOPM, 0, 0, +&acp3x_dmic_mux_control), }; static const struct snd_soc_dapm_route acp3x_audio_route[] = { @@ -301,6 +303,8 @@ static const struct snd_soc_dapm_route acp3x_audio_route[] = { {"Headphone Jack", NULL, "HPOR"}, {"IN1P", NULL, "Headset Mic"}, {"Spk", NULL, "Speaker"}, + {"Dmic Mux", "Front Mic", "DMIC"}, + {"Dmic Mux", "Rear Mic", "DMIC"}, }; static const struct snd_kcontrol_new acp3x_mc_controls[] = { -- 2.20.1
[tip: x86/entry] x86/hw_breakpoint: Prevent data breakpoints on user_pcid_flush_mask
The following commit has been merged into the x86/entry branch of tip: Commit-ID: 87aa9b64e0ccb779db3970e2e9af1cc5930c2c3d Gitweb: https://git.kernel.org/tip/87aa9b64e0ccb779db3970e2e9af1cc5930c2c3d Author:Lai Jiangshan AuthorDate:Fri, 29 May 2020 23:27:32 +02:00 Committer: Thomas Gleixner CommitterDate: Sat, 30 May 2020 10:00:06 +02:00 x86/hw_breakpoint: Prevent data breakpoints on user_pcid_flush_mask The per-CPU user_pcid_flush_mask is used in the low level entry code. A data breakpoint can cause #DB recursion. Protect the full cpu_tlbstate structure for simplicity. Signed-off-by: Lai Jiangshan Signed-off-by: Peter Zijlstra (Intel) Signed-off-by: Thomas Gleixner Link: https://lkml.kernel.org/r/20200526014221.2119-5-la...@linux.alibaba.com Link: https://lkml.kernel.org/r/20200529213320.955117...@infradead.org --- arch/x86/kernel/hw_breakpoint.c | 11 +++ 1 file changed, 11 insertions(+) diff --git a/arch/x86/kernel/hw_breakpoint.c b/arch/x86/kernel/hw_breakpoint.c index f311bbf..fc1743a 100644 --- a/arch/x86/kernel/hw_breakpoint.c +++ b/arch/x86/kernel/hw_breakpoint.c @@ -33,6 +33,7 @@ #include #include #include +#include /* Per cpu debug control register value */ DEFINE_PER_CPU(unsigned long, cpu_dr7); @@ -264,6 +265,16 @@ static inline bool within_cpu_entry(unsigned long addr, unsigned long end) (unsigned long)&per_cpu(cpu_tss_rw, cpu), sizeof(struct tss_struct))) return true; + + /* +* cpu_tlbstate.user_pcid_flush_mask is used for CPU entry. +* If a data breakpoint on it, it will cause an unwanted #DB. +* Protect the full cpu_tlbstate structure to be sure. +*/ + if (within_area(addr, end, + (unsigned long)&per_cpu(cpu_tlbstate, cpu), + sizeof(struct tlb_state))) + return true; } return false;
[tip: x86/entry] x86/hw_breakpoint: Prevent data breakpoints on per_cpu cpu_tss_rw
The following commit has been merged into the x86/entry branch of tip: Commit-ID: 9a06f99a03a0f961047bbae4ee80ce9265757bfe Gitweb: https://git.kernel.org/tip/9a06f99a03a0f961047bbae4ee80ce9265757bfe Author:Lai Jiangshan AuthorDate:Fri, 29 May 2020 23:27:31 +02:00 Committer: Thomas Gleixner CommitterDate: Sat, 30 May 2020 10:00:06 +02:00 x86/hw_breakpoint: Prevent data breakpoints on per_cpu cpu_tss_rw cpu_tss_rw is not directly referenced by hardware, but cpu_tss_rw is accessed in CPU entry code, especially when #DB shifts its stacks. If a data breakpoint would be set on cpu_tss_rw.x86_tss.ist[IST_INDEX_DB], it would cause recursive #DB ending up in a double fault. Add it to the list of protected items. Signed-off-by: Lai Jiangshan Signed-off-by: Peter Zijlstra (Intel) Signed-off-by: Thomas Gleixner Link: https://lkml.kernel.org/r/20200526014221.2119-4-la...@linux.alibaba.com Link: https://lkml.kernel.org/r/20200529213320.897976...@infradead.org --- arch/x86/kernel/hw_breakpoint.c | 9 + 1 file changed, 9 insertions(+) diff --git a/arch/x86/kernel/hw_breakpoint.c b/arch/x86/kernel/hw_breakpoint.c index f859095..f311bbf 100644 --- a/arch/x86/kernel/hw_breakpoint.c +++ b/arch/x86/kernel/hw_breakpoint.c @@ -255,6 +255,15 @@ static inline bool within_cpu_entry(unsigned long addr, unsigned long end) if (within_area(addr, end, (unsigned long)get_cpu_gdt_rw(cpu), GDT_SIZE)) return true; + + /* +* cpu_tss_rw is not directly referenced by hardware, but +* cpu_tss_rw is also used in CPU entry code, +*/ + if (within_area(addr, end, + (unsigned long)&per_cpu(cpu_tss_rw, cpu), + sizeof(struct tss_struct))) + return true; } return false;
[tip: x86/entry] x86/hw_breakpoint: Prevent data breakpoints on direct GDT
The following commit has been merged into the x86/entry branch of tip: Commit-ID: 92a6521bf846dd08768bc4de447b79e8bd2cdb2f Gitweb: https://git.kernel.org/tip/92a6521bf846dd08768bc4de447b79e8bd2cdb2f Author:Lai Jiangshan AuthorDate:Fri, 29 May 2020 23:27:30 +02:00 Committer: Thomas Gleixner CommitterDate: Sat, 30 May 2020 10:00:06 +02:00 x86/hw_breakpoint: Prevent data breakpoints on direct GDT A data breakpoint on the GDT can be fatal and must be avoided. The GDT in the CPU entry area is already protected, but not the direct GDT. Add the necessary protection. Signed-off-by: Lai Jiangshan Signed-off-by: Peter Zijlstra (Intel) Signed-off-by: Thomas Gleixner Link: https://lkml.kernel.org/r/20200526014221.2119-3-la...@linux.alibaba.com Link: https://lkml.kernel.org/r/20200529213320.840953...@infradead.org --- arch/x86/kernel/hw_breakpoint.c | 30 ++ 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/arch/x86/kernel/hw_breakpoint.c b/arch/x86/kernel/hw_breakpoint.c index c149c7b..f859095 100644 --- a/arch/x86/kernel/hw_breakpoint.c +++ b/arch/x86/kernel/hw_breakpoint.c @@ -32,6 +32,7 @@ #include #include #include +#include /* Per cpu debug control register value */ DEFINE_PER_CPU(unsigned long, cpu_dr7); @@ -237,13 +238,26 @@ static inline bool within_area(unsigned long addr, unsigned long end, } /* - * Checks whether the range from addr to end, inclusive, overlaps the CPU - * entry area range. + * Checks whether the range from addr to end, inclusive, overlaps the fixed + * mapped CPU entry area range or other ranges used for CPU entry. */ -static inline bool within_cpu_entry_area(unsigned long addr, unsigned long end) +static inline bool within_cpu_entry(unsigned long addr, unsigned long end) { - return within_area(addr, end, CPU_ENTRY_AREA_BASE, - CPU_ENTRY_AREA_TOTAL_SIZE); + int cpu; + + /* CPU entry erea is always used for CPU entry */ + if (within_area(addr, end, CPU_ENTRY_AREA_BASE, + CPU_ENTRY_AREA_TOTAL_SIZE)) + return true; + + for_each_possible_cpu(cpu) { + /* The original rw GDT is being used after load_direct_gdt() */ + if (within_area(addr, end, (unsigned long)get_cpu_gdt_rw(cpu), + GDT_SIZE)) + return true; + } + + return false; } static int arch_build_bp_info(struct perf_event *bp, @@ -257,12 +271,12 @@ static int arch_build_bp_info(struct perf_event *bp, return -EINVAL; /* -* Prevent any breakpoint of any type that overlaps the -* cpu_entry_area. This protects the IST stacks and also +* Prevent any breakpoint of any type that overlaps the CPU +* entry area and data. This protects the IST stacks and also * reduces the chance that we ever find out what happens if * there's a data breakpoint on the GDT, IDT, or TSS. */ - if (within_cpu_entry_area(attr->bp_addr, bp_end)) + if (within_cpu_entry(attr->bp_addr, bp_end)) return -EINVAL; hw->address = attr->bp_addr;
[tip: x86/entry] x86/idt: Mark init only functions __init
The following commit has been merged into the x86/entry branch of tip: Commit-ID: f841aea13b3ba6d7ad19b1d0744593e2d2448d2f Gitweb: https://git.kernel.org/tip/f841aea13b3ba6d7ad19b1d0744593e2d2448d2f Author:Thomas Gleixner AuthorDate:Thu, 28 May 2020 16:53:16 +02:00 Committer: Thomas Gleixner CommitterDate: Sat, 30 May 2020 11:50:11 +02:00 x86/idt: Mark init only functions __init Since 8175cfbbbfcb ("x86/idt: Remove update_intr_gate()") set_intr_gate() and idt_setup_from_table() are only called from __init functions. Mark them as well. Signed-off-by: Thomas Gleixner Link: https://lkml.kernel.org/r/20200528145522.715816...@linutronix.de --- arch/x86/kernel/idt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/idt.c b/arch/x86/kernel/idt.c index 226c992..4b99f7b 100644 --- a/arch/x86/kernel/idt.c +++ b/arch/x86/kernel/idt.c @@ -197,7 +197,7 @@ static inline void idt_init_desc(gate_desc *gate, const struct idt_data *d) #endif } -static void +static __init void idt_setup_from_table(gate_desc *idt, const struct idt_data *t, int size, bool sys) { gate_desc desc; @@ -210,7 +210,7 @@ idt_setup_from_table(gate_desc *idt, const struct idt_data *t, int size, bool sy } } -static void set_intr_gate(unsigned int n, const void *addr) +static __init void set_intr_gate(unsigned int n, const void *addr) { struct idt_data data;
[tip: x86/entry] x86/hw_breakpoint: Add within_area() to check data breakpoints
The following commit has been merged into the x86/entry branch of tip: Commit-ID: 83f7a80367e99cca0023be95538635abacec07ae Gitweb: https://git.kernel.org/tip/83f7a80367e99cca0023be95538635abacec07ae Author:Lai Jiangshan AuthorDate:Fri, 29 May 2020 23:27:29 +02:00 Committer: Thomas Gleixner CommitterDate: Sat, 30 May 2020 10:00:05 +02:00 x86/hw_breakpoint: Add within_area() to check data breakpoints Add a within_area() helper to checking whether the data breakpoints overlap with cpu_entry_area. It will be used to completely prevent data breakpoints on GDT, IDT, or TSS. Signed-off-by: Lai Jiangshan Signed-off-by: Peter Zijlstra (Intel) Signed-off-by: Thomas Gleixner Link: https://lkml.kernel.org/r/20200526014221.2119-2-la...@linux.alibaba.com Link: https://lkml.kernel.org/r/20200529213320.784524...@infradead.org --- arch/x86/kernel/hw_breakpoint.c | 13 +++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/hw_breakpoint.c b/arch/x86/kernel/hw_breakpoint.c index 9ddf441..c149c7b 100644 --- a/arch/x86/kernel/hw_breakpoint.c +++ b/arch/x86/kernel/hw_breakpoint.c @@ -228,13 +228,22 @@ int arch_check_bp_in_kernelspace(struct arch_hw_breakpoint *hw) } /* + * Checks whether the range [addr, end], overlaps the area [base, base + size). + */ +static inline bool within_area(unsigned long addr, unsigned long end, + unsigned long base, unsigned long size) +{ + return end >= base && addr < (base + size); +} + +/* * Checks whether the range from addr to end, inclusive, overlaps the CPU * entry area range. */ static inline bool within_cpu_entry_area(unsigned long addr, unsigned long end) { - return end >= CPU_ENTRY_AREA_BASE && - addr < (CPU_ENTRY_AREA_BASE + CPU_ENTRY_AREA_TOTAL_SIZE); + return within_area(addr, end, CPU_ENTRY_AREA_BASE, + CPU_ENTRY_AREA_TOTAL_SIZE); } static int arch_build_bp_info(struct perf_event *bp,
[tip: x86/entry] x86/entry, mce: Disallow #DB during #MC
The following commit has been merged into the x86/entry branch of tip: Commit-ID: ff98610a03285516b578821549973f969118d6a3 Gitweb: https://git.kernel.org/tip/ff98610a03285516b578821549973f969118d6a3 Author:Peter Zijlstra AuthorDate:Fri, 29 May 2020 23:27:35 +02:00 Committer: Thomas Gleixner CommitterDate: Sat, 30 May 2020 10:00:08 +02:00 x86/entry, mce: Disallow #DB during #MC #MC is fragile as heck, don't tempt fate. Signed-off-by: Peter Zijlstra (Intel) Signed-off-by: Thomas Gleixner Link: https://lkml.kernel.org/r/20200529213321.131187...@infradead.org --- arch/x86/kernel/cpu/mce/core.c | 12 1 file changed, 12 insertions(+) diff --git a/arch/x86/kernel/cpu/mce/core.c b/arch/x86/kernel/cpu/mce/core.c index 068e6ca..be49926 100644 --- a/arch/x86/kernel/cpu/mce/core.c +++ b/arch/x86/kernel/cpu/mce/core.c @@ -1943,22 +1943,34 @@ static __always_inline void exc_machine_check_user(struct pt_regs *regs) /* MCE hit kernel mode */ DEFINE_IDTENTRY_MCE(exc_machine_check) { + unsigned long dr7; + + dr7 = local_db_save(); exc_machine_check_kernel(regs); + local_db_restore(dr7); } /* The user mode variant. */ DEFINE_IDTENTRY_MCE_USER(exc_machine_check) { + unsigned long dr7; + + dr7 = local_db_save(); exc_machine_check_user(regs); + local_db_restore(dr7); } #else /* 32bit unified entry point */ DEFINE_IDTENTRY_MCE(exc_machine_check) { + unsigned long dr7; + + dr7 = local_db_save(); if (user_mode(regs)) exc_machine_check_user(regs); else exc_machine_check_kernel(regs); + local_db_restore(dr7); } #endif