* Re: [PATCH RFCv2 9/9] arm64: Support async page fault
From: Paolo Bonzini @ 2020-05-28 10:53 UTC (permalink / raw)
To: Marc Zyngier, Gavin Shan
Cc: catalin.marinas, linux-kernel, shan.gavin, will, kvmarm,
linux-arm-kernel
In-Reply-To: <8b09c298fab15e2629c65e8ee98a8a29@kernel.org>
On 28/05/20 09:03, Marc Zyngier wrote:
> The current state of the architecture doesn't seem to leave much leeway in
> terms of SW creativity here. You just can't allocate your own ISS encoding
> without risking a clash with future revisions of the architecture.
> It isn't even clear whether the value you put would stick in ESR_EL1
> if it isn't a valid value for this CPU (see the definition of 'Reserved'
> in the ARM ARM).
>
> Allocating such a syndrome would require from ARM:
>
> - the guarantee that no existing implementation, irrespective of the
> implementer, can cope with the ISS encoding of your choice,
>
> - the written promise in the architecture that some EC/ISS values
> are reserved for SW, and that promise to apply retrospectively.
>
> This is somewhat unlikely to happen.
Well, that's a euphemism probably. On x86 we're somewhat lucky that
there's an architectural way for injecting hypervisor vmexit directly in
the guest, and we can piggyback on that for async page faults (which are
essentially stage2 page faults that are processed by the guest).
Is it possible to reuse EL2 exception codes / syndromes somehow? (I
haven't checked in the ARM ARM the differences between the EL1 and EL2
syndrome registers).
Paolo
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH RFCv2 9/9] arm64: Support async page fault
From: Paolo Bonzini @ 2020-05-28 10:48 UTC (permalink / raw)
To: Gavin Shan, kvmarm
Cc: maz, linux-kernel, shan.gavin, catalin.marinas, will,
linux-arm-kernel
In-Reply-To: <a6addc25-29af-3690-8392-efa5e8381e98@redhat.com>
On 28/05/20 08:14, Gavin Shan wrote:
>> - for x86 we're also thinking of initiating the page fault from the
>> exception handler, rather than doing so from the hypervisor before
>> injecting the exception. If ARM leads the way here, we would do our
>> best to share code when x86 does the same.
>
> Sorry, Paolo, I don't follow your idea here. Could you please provide
> more details?
The idea is to inject stage2 page faults into the guest even before the
host starts populates the page. The guest then invokes a hypercall,
telling the host to populate the page table and inject the 'page ready'
event (interrupt) when it's done.
For x86 the advantage is that the processor can take care of raising the
stage2 page fault in the guest, so it's faster.
Paolo
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH 0/5] vexpress: modularize power reset driver
From: Arnd Bergmann @ 2020-05-28 10:34 UTC (permalink / raw)
To: Rob Herring
Cc: SoC Team, Anders Roxell, linux-kernel@vger.kernel.org,
moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
Linus Walleij
In-Reply-To: <CAL_JsqKDfcX1YUTmkMbMNfPHnW5YcB7FaAmvrb42wgmsdfTqng@mail.gmail.com>
On Wed, May 27, 2020 at 3:35 PM Rob Herring <robh@kernel.org> wrote:
>
> On Wed, May 27, 2020 at 5:26 AM Anders Roxell <anders.roxell@linaro.org> wrote:
> >
> > Hi,
> >
> > This patchset contains a bugfixe, a cleanup and fixes allmodconfig build breakages
> > on arm and arm64. Also making the vexpress power reset driver a module.
> >
> > Cheers,
> > Anders
> >
> > Anders Roxell (5):
> > power: vexpress: add suppress_bind_attrs to true
> > power: vexpress: cleanup: use builtin_platform_driver
> > Revert "ARM: vexpress: Don't select VEXPRESS_CONFIG"
> > power: reset: vexpress: fix build issue
> > power: vexpress: make the reset driver a module
>
> IMO, patches 3 and 4 should be applied to fix the kconfig issues.
> Making the driver a module can be addressed separately.
I've applied patches 1 through 4 now but left the last one.
If we can find someone to write and test a .remove callback,
I'll prefer that for v5.9, otherwise I'd consider taking Anders'
version instead.
Arnd
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH 5/5] power: vexpress: make the reset driver a module
From: Arnd Bergmann @ 2020-05-28 10:28 UTC (permalink / raw)
To: Rob Herring
Cc: SoC Team, Anders Roxell, linux-kernel@vger.kernel.org,
moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
Linus Walleij
In-Reply-To: <CAL_Jsq+bwnwQBpxf_Q5GNhCz8+-psH-ovpW80LMk=MK=zcbYcA@mail.gmail.com>
On Wed, May 27, 2020 at 3:32 PM Rob Herring <robh@kernel.org> wrote:
>
> On Wed, May 27, 2020 at 5:26 AM Anders Roxell <anders.roxell@linaro.org> wrote:
> >
> > Today the vexpress power driver can only be builtin. Rework so it's
> > possible for the vexpress power driver to be a module.
>
> This is the same incomplete patch I did[1]. As a module, it needs to
> clean-up everything probe did like overwriting global variables.
>
> Rob
>
> [1] https://lore.kernel.org/linux-arm-kernel/20200419170810.5738-5-robh@kernel.org/
Your version was actually broken because it allowed unloading the
driver again. The version that Anders sent is a bit better because it
explicitly forbids unloading by having a module_init but not module_exit
function, so as long as the .suppress_bind_attrs flag is set, this will
not crash the kernel.
It would be nice to have a .remove callback, but for the merge window
I'm happy with a patch that fixes the build regression.
Arnd
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [RESEND PATCH v11 2/3] drivers: input: keyboard: Add mtk keypad driver
From: Andy Shevchenko @ 2020-05-28 10:27 UTC (permalink / raw)
To: Fengping Yu
Cc: Dmitry Torokhov, Marco Felsch, linux-mediatek, linux-input,
Yingjoe Chen, linux-arm-kernel
In-Reply-To: <20200528090144.54033-3-fengping.yu@mediatek.com>
On Thu, May 28, 2020 at 05:01:47PM +0800, Fengping Yu wrote:
> From: "fengping.yu" <fengping.yu@mediatek.com>
>
> This adds matrix keypad support for Mediatek SoCs.
...
> +config KEYBOARD_MTK_KPD
> + tristate "MediaTek Keypad Support"
> + depends on ARCH_MEDIATEK || COMPILE_TEST
> + select CONFIG_REGMAP_MMIO
This is wrong.
> + select INPUT_MATRIXKMAP
...
> + ret = devm_add_action_or_reset(&pdev->dev, kpd_clk_disable,
> + keypad->clk);
I would leave on one line (only 81 characters).
> + if (ret)
> + return ret;
--
With Best Regards,
Andy Shevchenko
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH 1/5] power: vexpress: add suppress_bind_attrs to true
From: Arnd Bergmann @ 2020-05-28 10:25 UTC (permalink / raw)
To: Rob Herring
Cc: SoC Team, Anders Roxell, linux-kernel@vger.kernel.org,
moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
Linus Walleij
In-Reply-To: <CAL_Jsq+vrEE2DBY+c3iVyMLf9oOaGVHVvdiMgdYEGCjJwX7Hcw@mail.gmail.com>
On Wed, May 27, 2020 at 3:27 PM Rob Herring <robh@kernel.org> wrote:
>
> On Wed, May 27, 2020 at 5:26 AM Anders Roxell <anders.roxell@linaro.org> wrote:
> >
> > Make sure that the POWER_RESET_VEXPRESS driver won't have bind/unbind
> > attributes available via the sysfs, so lets be explicit here and use
> > ".suppress_bind_attrs = true" to prevent userspace from doing something
> > silly.
>
> This doesn't really make sense if we're going to make this a module.
> Module unloading and unbind introduce the same requirements of
> cleaning up (undoing whatever probe did).
I still want this change as a separate patch so we can backport it to stable
kernels for correctness.
Also, as long as we don't have a working (and tested) .remove callback,
we can only allow making the driver a loadable module but not also
allowing the module to be removed.
Arnd
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [RESEND PATCH v11] Add matrix keypad driver support for Mediatek SoCs
From: Andy Shevchenko @ 2020-05-28 10:24 UTC (permalink / raw)
To: Fengping Yu
Cc: Dmitry Torokhov, Marco Felsch, linux-mediatek, linux-input,
Yingjoe Chen, linux-arm-kernel
In-Reply-To: <20200528090144.54033-1-fengping.yu@mediatek.com>
On Thu, May 28, 2020 at 05:01:42PM +0800, Fengping Yu wrote:
>
> Change since v10:
> - add wakeup source setting in probe function
You forgot tags by Marco
>
> fengping.yu (3):
> dt-bindings: Add keypad devicetree documentation
> drivers: input: keyboard: Add mtk keypad driver
> configs: defconfig: Add CONFIG_KEYBOARD_MTK_KPD=m
>
> .../devicetree/bindings/input/mtk-kpd.yaml | 95 ++++++++
> arch/arm64/configs/defconfig | 1 +
> drivers/input/keyboard/Kconfig | 11 +
> drivers/input/keyboard/Makefile | 1 +
> drivers/input/keyboard/mtk-kpd.c | 206 ++++++++++++++++++
> 5 files changed, 314 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/input/mtk-kpd.yaml
> create mode 100644 drivers/input/keyboard/mtk-kpd.c
>
> --
> 2.18.0
>
--
With Best Regards,
Andy Shevchenko
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* RE: [PATCH 0/4] Change i.MX/MXS SoCs ocotp/iim node name to efuse
From: Andy Duan @ 2020-05-28 10:23 UTC (permalink / raw)
To: Anson Huang, robh+dt@kernel.org, shawnguo@kernel.org,
s.hauer@pengutronix.de, kernel@pengutronix.de, festevam@gmail.com,
Daniel Baluta, Leonard Crestez, Peng Fan, aford173@gmail.com,
Jun Li, S.j. Wang, Horia Geanta, Aisheng Dong, agx@sigxcpu.org,
l.stach@pengutronix.de, andrew.smirnov@gmail.com,
devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org
Cc: dl-linux-imx
In-Reply-To: <1590635570-8541-1-git-send-email-Anson.Huang@nxp.com>
From: Anson Huang <Anson.Huang@nxp.com> Sent: Thursday, May 28, 2020 11:13 AM
> In the nvmem yaml schema, it requires the nodename to be one of
> "eeprom|efuse|nvram", so need to change all i.MX/MXS SoCs ocotp/iim node
> name to efuse:
>
> MXS platforms: i.MX23/28;
> i.MX platforms with IIM: i.MX25/27/31/35/51/53.
> i.MX ARMv7 platforms with OCOTP: i.MX6QDL/6SL/6SX/6SLL/6UL/7S/7ULP.
> i.MX ARMv8 platforms with OCOTP: i.MX8MQ/8MM/8MN/8MP.
Reviewed-by: Fugang Duan <fugang.duan@nxp.com>
>
> Anson Huang (4):
> ARM: dts: imx: change ocotp node name on i.MX6/7 SoCs
> arm64: dts: imx8m: change ocotp node name on i.MX8M SoCs
> ARM: dts: imx: change ocotp node name on MXS SoCs
> ARM: dts: imx: change iim node name on i.MX SoCs
>
> arch/arm/boot/dts/imx23.dtsi | 2 +-
> arch/arm/boot/dts/imx25.dtsi | 2 +-
> arch/arm/boot/dts/imx27.dtsi | 2 +-
> arch/arm/boot/dts/imx28.dtsi | 2 +-
> arch/arm/boot/dts/imx31.dtsi | 2 +-
> arch/arm/boot/dts/imx35.dtsi | 2 +-
> arch/arm/boot/dts/imx51.dtsi | 2 +-
> arch/arm/boot/dts/imx53.dtsi | 2 +-
> arch/arm/boot/dts/imx6qdl.dtsi | 2 +-
> arch/arm/boot/dts/imx6sl.dtsi | 2 +-
> arch/arm/boot/dts/imx6sll.dtsi | 2 +-
> arch/arm/boot/dts/imx6sx.dtsi | 2 +-
> arch/arm/boot/dts/imx6ul.dtsi | 2 +-
> arch/arm/boot/dts/imx7s.dtsi | 2 +-
> arch/arm/boot/dts/imx7ulp.dtsi | 2 +-
> arch/arm64/boot/dts/freescale/imx8mm.dtsi | 2 +-
> arch/arm64/boot/dts/freescale/imx8mn.dtsi | 2 +-
> arch/arm64/boot/dts/freescale/imx8mp.dtsi | 2 +-
> arch/arm64/boot/dts/freescale/imx8mq.dtsi | 2 +-
> 19 files changed, 19 insertions(+), 19 deletions(-)
>
> --
> 2.7.4
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH] Bluetooth: btmtkuart: add missed functions in the error paths of btmtuart_probe()
From: Chuhong Yuan @ 2020-05-28 10:20 UTC (permalink / raw)
Cc: Johan Hedberg, Marcel Holtmann, Sean Wang, Chuhong Yuan,
linux-kernel, linux-bluetooth, linux-mediatek, Matthias Brugger,
linux-arm-kernel
btmtuart_probe() misses several function calls in its error paths,
including hci_free_dev() and clk_disable_unprepare().
Refactor the code and call correct undo functions to fix the error
paths.
Signed-off-by: Chuhong Yuan <hslester96@gmail.com>
---
drivers/bluetooth/btmtkuart.c | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/drivers/bluetooth/btmtkuart.c b/drivers/bluetooth/btmtkuart.c
index e11169ad8247..8a81fbca5c9d 100644
--- a/drivers/bluetooth/btmtkuart.c
+++ b/drivers/bluetooth/btmtkuart.c
@@ -1015,7 +1015,7 @@ static int btmtkuart_probe(struct serdev_device *serdev)
if (btmtkuart_is_standalone(bdev)) {
err = clk_prepare_enable(bdev->osc);
if (err < 0)
- return err;
+ goto err_hci_free_dev;
if (bdev->boot) {
gpiod_set_value_cansleep(bdev->boot, 1);
@@ -1028,10 +1028,8 @@ static int btmtkuart_probe(struct serdev_device *serdev)
/* Power on */
err = regulator_enable(bdev->vcc);
- if (err < 0) {
- clk_disable_unprepare(bdev->osc);
- return err;
- }
+ if (err < 0)
+ goto err_clk_disable_unprepare;
/* Reset if the reset-gpios is available otherwise the board
* -level design should be guaranteed.
@@ -1063,7 +1061,6 @@ static int btmtkuart_probe(struct serdev_device *serdev)
err = hci_register_dev(hdev);
if (err < 0) {
dev_err(&serdev->dev, "Can't register HCI device\n");
- hci_free_dev(hdev);
goto err_regulator_disable;
}
@@ -1072,6 +1069,11 @@ static int btmtkuart_probe(struct serdev_device *serdev)
err_regulator_disable:
if (btmtkuart_is_standalone(bdev))
regulator_disable(bdev->vcc);
+err_clk_disable_unprepare:
+ if (btmtkuart_is_standalone(bdev))
+ clk_disable_unprepare(bdev->osc);
+err_hci_free_dev:
+ hci_free_dev(hdev);
return err;
}
--
2.26.2
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* Re: [PATCH] mmc: sdhci-of-at91: fix CALCR register being rewritten
From: Ulf Hansson @ 2020-05-28 10:14 UTC (permalink / raw)
To: Eugen Hristev
Cc: Ludovic Desroches, linux-mmc@vger.kernel.org, Adrian Hunter,
Linux ARM, Linux Kernel Mailing List
In-Reply-To: <20200527105659.142560-1-eugen.hristev@microchip.com>
On Wed, 27 May 2020 at 12:57, Eugen Hristev <eugen.hristev@microchip.com> wrote:
>
> When enabling calibration at reset, the CALCR register was completely
> rewritten. This may cause certain bits being deleted unintentedly.
> Fix by issuing a read-modify-write operation.
>
> Fixes: 727d836a375a ("mmc: sdhci-of-at91: add DT property to enable calibration on full reset")
> Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com>
Applied for next and by adding a stable tag, thanks!
Kind regards
Uffe
> ---
> drivers/mmc/host/sdhci-of-at91.c | 7 +++++--
> 1 file changed, 5 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/mmc/host/sdhci-of-at91.c b/drivers/mmc/host/sdhci-of-at91.c
> index 25f4e0f4f53b..1ece2c50042c 100644
> --- a/drivers/mmc/host/sdhci-of-at91.c
> +++ b/drivers/mmc/host/sdhci-of-at91.c
> @@ -121,9 +121,12 @@ static void sdhci_at91_reset(struct sdhci_host *host, u8 mask)
> || mmc_gpio_get_cd(host->mmc) >= 0)
> sdhci_at91_set_force_card_detect(host);
>
> - if (priv->cal_always_on && (mask & SDHCI_RESET_ALL))
> - sdhci_writel(host, SDMMC_CALCR_ALWYSON | SDMMC_CALCR_EN,
> + if (priv->cal_always_on && (mask & SDHCI_RESET_ALL)) {
> + u32 calcr = sdhci_readl(host, SDMMC_CALCR);
> +
> + sdhci_writel(host, calcr | SDMMC_CALCR_ALWYSON | SDMMC_CALCR_EN,
> SDMMC_CALCR);
> + }
> }
>
> static const struct sdhci_ops sdhci_at91_sama5d2_ops = {
> --
> 2.25.1
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH 2/2] mmc: mmci_sdmmc: fix DMA API warning max segment size
From: Ulf Hansson @ 2020-05-28 10:14 UTC (permalink / raw)
To: Ludovic Barre
Cc: DTML, Alexandre Torgue, linux-mmc@vger.kernel.org,
Linux Kernel Mailing List, Rob Herring, Srini Kandagatla,
Maxime Coquelin, linux-stm32, Linux ARM
In-Reply-To: <20200526155103.12514-3-ludovic.barre@st.com>
On Tue, 26 May 2020 at 17:51, Ludovic Barre <ludovic.barre@st.com> wrote:
>
> Turning on CONFIG_DMA_API_DEBUG_SG results in the following warning:
> WARNING: CPU: 1 PID: 85 at kernel/dma/debug.c:1302 debug_dma_map_sg+0x2a0/0x3cc
> mmci-pl18x 58005000.sdmmc: DMA-API: mapping sg segment longer than device claims to support [len=126976] [max=65536]
>
> dma api debug checks and compares the segment size to
> dma_get_max_seg_size (dev->dma_parms->max_segment_size),
> the sdmmc variant has an internal DMA and should define
> its max_segment_size constraint to avoid this warning.
>
> This Patch defines the dev->dma_parms->max_segment_size
> with the constraint already set for mmc core
> (host->mmc->max_seg_size).
>
> Signed-off-by: Ludovic Barre <ludovic.barre@st.com>
Applied for next, thanks!
Note, a manual backport is needed for stable, as
dma_set_max_seg_size() will fail for older kernels.
We needed to revert 9495b7e92f7 ("driver core: platform: Initialize
dma_parms for platform devices"), for stable kernels [1].
Kind regards
Uffe
[1]
https://lkml.org/lkml/2020/5/26/1216
> ---
> drivers/mmc/host/mmci_stm32_sdmmc.c | 11 +++++------
> 1 file changed, 5 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/mmc/host/mmci_stm32_sdmmc.c b/drivers/mmc/host/mmci_stm32_sdmmc.c
> index 2965b1c062e1..51db30acf4dc 100644
> --- a/drivers/mmc/host/mmci_stm32_sdmmc.c
> +++ b/drivers/mmc/host/mmci_stm32_sdmmc.c
> @@ -119,20 +119,19 @@ static void sdmmc_idma_unprep_data(struct mmci_host *host,
> static int sdmmc_idma_setup(struct mmci_host *host)
> {
> struct sdmmc_idma *idma;
> + struct device *dev = mmc_dev(host->mmc);
>
> - idma = devm_kzalloc(mmc_dev(host->mmc), sizeof(*idma), GFP_KERNEL);
> + idma = devm_kzalloc(dev, sizeof(*idma), GFP_KERNEL);
> if (!idma)
> return -ENOMEM;
>
> host->dma_priv = idma;
>
> if (host->variant->dma_lli) {
> - idma->sg_cpu = dmam_alloc_coherent(mmc_dev(host->mmc),
> - SDMMC_LLI_BUF_LEN,
> + idma->sg_cpu = dmam_alloc_coherent(dev, SDMMC_LLI_BUF_LEN,
> &idma->sg_dma, GFP_KERNEL);
> if (!idma->sg_cpu) {
> - dev_err(mmc_dev(host->mmc),
> - "Failed to alloc IDMA descriptor\n");
> + dev_err(dev, "Failed to alloc IDMA descriptor\n");
> return -ENOMEM;
> }
> host->mmc->max_segs = SDMMC_LLI_BUF_LEN /
> @@ -143,7 +142,7 @@ static int sdmmc_idma_setup(struct mmci_host *host)
> host->mmc->max_seg_size = host->mmc->max_req_size;
> }
>
> - return 0;
> + return dma_set_max_seg_size(dev, host->mmc->max_seg_size);
> }
>
> static int sdmmc_idma_start(struct mmci_host *host, unsigned int *datactrl)
> --
> 2.17.1
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH 1/2] mmc: mmci_sdmmc: fix DMA API warning overlapping mappings
From: Ulf Hansson @ 2020-05-28 10:14 UTC (permalink / raw)
To: Ludovic Barre
Cc: DTML, Alexandre Torgue, linux-mmc@vger.kernel.org,
Linux Kernel Mailing List, Rob Herring, Srini Kandagatla,
Maxime Coquelin, linux-stm32, Linux ARM
In-Reply-To: <20200526155103.12514-2-ludovic.barre@st.com>
On Tue, 26 May 2020 at 17:51, Ludovic Barre <ludovic.barre@st.com> wrote:
>
> Turning on CONFIG_DMA_API_DEBUG_SG results in the following warning:
> WARNING: CPU: 1 PID: 20 at kernel/dma/debug.c:500 add_dma_entry+0x16c/0x17c
> DMA-API: exceeded 7 overlapping mappings of cacheline 0x031d2645
> Modules linked in:
> CPU: 1 PID: 20 Comm: kworker/1:1 Not tainted 5.5.0-rc2-00021-gdeda30999c2b-dirty #49
> Hardware name: STM32 (Device Tree Support)
> Workqueue: events_freezable mmc_rescan
> [<c03138c0>] (unwind_backtrace) from [<c030d760>] (show_stack+0x10/0x14)
> [<c030d760>] (show_stack) from [<c0f2eb28>] (dump_stack+0xc0/0xd4)
> [<c0f2eb28>] (dump_stack) from [<c034a14c>] (__warn+0xd0/0xf8)
> [<c034a14c>] (__warn) from [<c034a530>] (warn_slowpath_fmt+0x94/0xb8)
> [<c034a530>] (warn_slowpath_fmt) from [<c03bca0c>] (add_dma_entry+0x16c/0x17c)
> [<c03bca0c>] (add_dma_entry) from [<c03bdf54>] (debug_dma_map_sg+0xe4/0x3d4)
> [<c03bdf54>] (debug_dma_map_sg) from [<c0d09244>] (sdmmc_idma_prep_data+0x94/0xf8)
> [<c0d09244>] (sdmmc_idma_prep_data) from [<c0d05a2c>] (mmci_prep_data+0x2c/0xb0)
> [<c0d05a2c>] (mmci_prep_data) from [<c0d073ec>] (mmci_start_data+0x134/0x2f0)
> [<c0d073ec>] (mmci_start_data) from [<c0d078d0>] (mmci_request+0xe8/0x154)
> [<c0d078d0>] (mmci_request) from [<c0cecb44>] (mmc_start_request+0x94/0xbc)
>
> DMA api debug brings to light leaking dma-mappings, dma_map_sg and
> dma_unmap_sg are not correctly balanced.
>
> If a request is prepared, the dma_map/unmap are done in asynchronous
> call pre_req (prep_data) and post_req (unprep_data). In this case
> the dma-mapping is right balanced.
>
> But if the request was not prepared, the data->host_cookie is
> define to zero and the dma_map/unmap must be done in the request.
> The dma_map is called by mmci_dma_start (prep_data), but there is
> no dma_unmap in this case.
>
> This patch adds dma_unmap_sg when the dma is finalized and
> the data cookie is zero (request not prepared).
>
> Signed-off-by: Ludovic Barre <ludovic.barre@st.com>
Applied for next by adding a fixes tag and a stable tag, thanks!
Fixes: 46b723dd867d ("mmc: mmci: add stm32 sdmmc variant")
Kind regards
Uffe
> ---
> drivers/mmc/host/mmci_stm32_sdmmc.c | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/drivers/mmc/host/mmci_stm32_sdmmc.c b/drivers/mmc/host/mmci_stm32_sdmmc.c
> index 14f99d8aa3f0..2965b1c062e1 100644
> --- a/drivers/mmc/host/mmci_stm32_sdmmc.c
> +++ b/drivers/mmc/host/mmci_stm32_sdmmc.c
> @@ -188,6 +188,9 @@ static int sdmmc_idma_start(struct mmci_host *host, unsigned int *datactrl)
> static void sdmmc_idma_finalize(struct mmci_host *host, struct mmc_data *data)
> {
> writel_relaxed(0, host->base + MMCI_STM32_IDMACTRLR);
> +
> + if (!data->host_cookie)
> + sdmmc_idma_unprep_data(host, data, 0);
> }
>
> static void mmci_sdmmc_set_clkreg(struct mmci_host *host, unsigned int desired)
> --
> 2.17.1
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH v4 2/4] dmaengine: mediatek-cqdma: remove redundant queue structure
From: EastL @ 2020-05-28 9:57 UTC (permalink / raw)
To: Sean Wang
Cc: mark.rutland, devicetree, wsd_upstream, linux-kernel, EastL,
dmaengine, vkoul, robh+dt, linux-mediatek, matthias.bgg,
linux-arm-kernel
In-Reply-To: <1590659832-31476-1-git-send-email-EastL.Lee@mediatek.com>
This patch introduces active_vdec to indicate the virtual descriptor
under processing by the CQDMA dmaengine, and simplify the control logic
by removing redundant queue structure, tasklets, and completion
management.
Signed-off-by: EastL <EastL.Lee@mediatek.com>
---
drivers/dma/mediatek/mtk-cqdma.c | 383 ++++++++++-----------------------------
1 file changed, 93 insertions(+), 290 deletions(-)
diff --git a/drivers/dma/mediatek/mtk-cqdma.c b/drivers/dma/mediatek/mtk-cqdma.c
index 6bf838e..905bbcb 100644
--- a/drivers/dma/mediatek/mtk-cqdma.c
+++ b/drivers/dma/mediatek/mtk-cqdma.c
@@ -22,6 +22,7 @@
#include <linux/of_dma.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
+#include <linux/preempt.h>
#include <linux/refcount.h>
#include <linux/slab.h>
@@ -47,7 +48,6 @@
#define MTK_CQDMA_SRC 0x1c
#define MTK_CQDMA_DST 0x20
#define MTK_CQDMA_LEN1 0x24
-#define MTK_CQDMA_LEN2 0x28
#define MTK_CQDMA_SRC2 0x60
#define MTK_CQDMA_DST2 0x64
@@ -69,45 +69,32 @@
* descriptor (CVD)
* @vd: An instance for struct virt_dma_desc
* @len: The total data size device wants to move
- * @residue: The remaining data size device will move
* @dest: The destination address device wants to move to
* @src: The source address device wants to move from
* @ch: The pointer to the corresponding dma channel
- * @node: The lise_head struct to build link-list for VDs
- * @parent: The pointer to the parent CVD
*/
struct mtk_cqdma_vdesc {
struct virt_dma_desc vd;
size_t len;
- size_t residue;
dma_addr_t dest;
dma_addr_t src;
struct dma_chan *ch;
-
- struct list_head node;
- struct mtk_cqdma_vdesc *parent;
};
/**
* struct mtk_cqdma_pchan - The struct holding info describing physical
* channel (PC)
- * @queue: Queue for the PDs issued to this PC
+ * @active_vdesc: The pointer to the CVD which is under processing
* @base: The mapped register I/O base of this PC
* @irq: The IRQ that this PC are using
* @refcnt: Track how many VCs are using this PC
- * @tasklet: Tasklet for this PC
* @lock: Lock protect agaisting multiple VCs access PC
*/
struct mtk_cqdma_pchan {
- struct list_head queue;
+ struct mtk_cqdma_vdesc *active_vdesc;
void __iomem *base;
u32 irq;
-
refcount_t refcnt;
-
- struct tasklet_struct tasklet;
-
- /* lock to protect PC */
spinlock_t lock;
};
@@ -116,14 +103,11 @@ struct mtk_cqdma_pchan {
* channel (VC)
* @vc: An instance for struct virt_dma_chan
* @pc: The pointer to the underlying PC
- * @issue_completion: The wait for all issued descriptors completited
- * @issue_synchronize: Bool indicating channel synchronization starts
*/
struct mtk_cqdma_vchan {
struct virt_dma_chan vc;
struct mtk_cqdma_pchan *pc;
- struct completion issue_completion;
- bool issue_synchronize;
+ struct completion cmp;
};
/**
@@ -202,22 +186,22 @@ static void mtk_cqdma_vdesc_free(struct virt_dma_desc *vd)
kfree(to_cqdma_vdesc(vd));
}
-static int mtk_cqdma_poll_engine_done(struct mtk_cqdma_pchan *pc, bool atomic)
+static int mtk_cqdma_poll_engine_done(struct mtk_cqdma_pchan *pc)
{
u32 status = 0;
- if (!atomic)
+ if (in_task())
+ return readl_poll_timeout_atomic(pc->base + MTK_CQDMA_EN,
+ status,
+ !(status & MTK_CQDMA_EN_BIT),
+ MTK_CQDMA_USEC_POLL,
+ MTK_CQDMA_TIMEOUT_POLL);
+ else
return readl_poll_timeout(pc->base + MTK_CQDMA_EN,
status,
!(status & MTK_CQDMA_EN_BIT),
MTK_CQDMA_USEC_POLL,
MTK_CQDMA_TIMEOUT_POLL);
-
- return readl_poll_timeout_atomic(pc->base + MTK_CQDMA_EN,
- status,
- !(status & MTK_CQDMA_EN_BIT),
- MTK_CQDMA_USEC_POLL,
- MTK_CQDMA_TIMEOUT_POLL);
}
static int mtk_cqdma_hard_reset(struct mtk_cqdma_pchan *pc)
@@ -225,20 +209,17 @@ static int mtk_cqdma_hard_reset(struct mtk_cqdma_pchan *pc)
mtk_dma_set(pc, MTK_CQDMA_RESET, MTK_CQDMA_HARD_RST_BIT);
mtk_dma_clr(pc, MTK_CQDMA_RESET, MTK_CQDMA_HARD_RST_BIT);
- return mtk_cqdma_poll_engine_done(pc, true);
+ return mtk_cqdma_poll_engine_done(pc);
}
static void mtk_cqdma_start(struct mtk_cqdma_pchan *pc,
struct mtk_cqdma_vdesc *cvd)
{
- /* wait for the previous transaction done */
- if (mtk_cqdma_poll_engine_done(pc, true) < 0)
- dev_err(cqdma2dev(to_cqdma_dev(cvd->ch)), "cqdma wait transaction timeout\n");
-
/* warm reset the dma engine for the new transaction */
mtk_dma_set(pc, MTK_CQDMA_RESET, MTK_CQDMA_WARM_RST_BIT);
- if (mtk_cqdma_poll_engine_done(pc, true) < 0)
- dev_err(cqdma2dev(to_cqdma_dev(cvd->ch)), "cqdma warm reset timeout\n");
+ if (mtk_cqdma_poll_engine_done(pc) < 0)
+ dev_err(cqdma2dev(to_cqdma_dev(cvd->ch)),
+ "cqdma warm reset timeout\n");
/* setup the source */
mtk_dma_set(pc, MTK_CQDMA_SRC, cvd->src & MTK_CQDMA_ADDR_LIMIT);
@@ -257,7 +238,8 @@ static void mtk_cqdma_start(struct mtk_cqdma_pchan *pc,
#endif
/* setup the length */
- mtk_dma_set(pc, MTK_CQDMA_LEN1, cvd->len);
+ mtk_dma_set(pc, MTK_CQDMA_LEN1, (cvd->len < MTK_CQDMA_MAX_LEN) ?
+ cvd->len : MTK_CQDMA_MAX_LEN);
/* start dma engine */
mtk_dma_set(pc, MTK_CQDMA_EN, MTK_CQDMA_EN_BIT);
@@ -265,30 +247,17 @@ static void mtk_cqdma_start(struct mtk_cqdma_pchan *pc,
static void mtk_cqdma_issue_vchan_pending(struct mtk_cqdma_vchan *cvc)
{
- struct virt_dma_desc *vd, *vd2;
+ struct virt_dma_desc *vd;
struct mtk_cqdma_pchan *pc = cvc->pc;
- struct mtk_cqdma_vdesc *cvd;
- bool trigger_engine = false;
lockdep_assert_held(&cvc->vc.lock);
lockdep_assert_held(&pc->lock);
- list_for_each_entry_safe(vd, vd2, &cvc->vc.desc_issued, node) {
- /* need to trigger dma engine if PC's queue is empty */
- if (list_empty(&pc->queue))
- trigger_engine = true;
-
- cvd = to_cqdma_vdesc(vd);
-
- /* add VD into PC's queue */
- list_add_tail(&cvd->node, &pc->queue);
-
- /* start the dma engine */
- if (trigger_engine)
- mtk_cqdma_start(pc, cvd);
+ vd = vchan_next_desc(&cvc->vc);
- /* remove VD from list desc_issued */
- list_del(&vd->node);
+ if (vd && !pc->active_vdesc) {
+ pc->active_vdesc = to_cqdma_vdesc(vd);
+ mtk_cqdma_start(pc, pc->active_vdesc);
}
}
@@ -298,100 +267,55 @@ static void mtk_cqdma_issue_vchan_pending(struct mtk_cqdma_vchan *cvc)
*/
static bool mtk_cqdma_is_vchan_active(struct mtk_cqdma_vchan *cvc)
{
- struct mtk_cqdma_vdesc *cvd;
-
- list_for_each_entry(cvd, &cvc->pc->queue, node)
- if (cvc == to_cqdma_vchan(cvd->ch))
- return true;
-
- return false;
+ return (!cvc->pc->active_vdesc) ? false :
+ (cvc == to_cqdma_vchan(cvc->pc->active_vdesc->ch));
}
-/*
- * return the pointer of the CVD that is just consumed by the PC
- */
-static struct mtk_cqdma_vdesc
-*mtk_cqdma_consume_work_queue(struct mtk_cqdma_pchan *pc)
+static void mtk_cqdma_complete_vdesc(struct mtk_cqdma_pchan *pc)
{
struct mtk_cqdma_vchan *cvc;
- struct mtk_cqdma_vdesc *cvd, *ret = NULL;
-
- /* consume a CVD from PC's queue */
- cvd = list_first_entry_or_null(&pc->queue,
- struct mtk_cqdma_vdesc, node);
- if (unlikely(!cvd || !cvd->parent))
- return NULL;
+ struct mtk_cqdma_vdesc *cvd;
+ struct virt_dma_desc *vd;
+ size_t tlen;
+ cvd = pc->active_vdesc;
cvc = to_cqdma_vchan(cvd->ch);
- ret = cvd;
-
- /* update residue of the parent CVD */
- cvd->parent->residue -= cvd->len;
- /* delete CVD from PC's queue */
- list_del(&cvd->node);
+ tlen = (cvd->len < MTK_CQDMA_MAX_LEN) ? cvd->len : MTK_CQDMA_MAX_LEN;
+ cvd->len -= tlen;
+ cvd->src += tlen;
+ cvd->dest += tlen;
spin_lock(&cvc->vc.lock);
- /* check whether all the child CVDs completed */
- if (!cvd->parent->residue) {
- /* add the parent VD into list desc_completed */
- vchan_cookie_complete(&cvd->parent->vd);
+ /* check whether the VD completed */
+ if (!cvd->len) {
+ /* delete VD from desc_issued */
+ list_del(&cvd->vd.node);
- /* setup completion if this VC is under synchronization */
- if (cvc->issue_synchronize && !mtk_cqdma_is_vchan_active(cvc)) {
- complete(&cvc->issue_completion);
- cvc->issue_synchronize = false;
- }
- }
-
- spin_unlock(&cvc->vc.lock);
+ /* add the VD into list desc_completed */
+ vchan_cookie_complete(&cvd->vd);
- /* start transaction for next CVD in the queue */
- cvd = list_first_entry_or_null(&pc->queue,
- struct mtk_cqdma_vdesc, node);
- if (cvd)
- mtk_cqdma_start(pc, cvd);
-
- return ret;
-}
-
-static void mtk_cqdma_tasklet_cb(unsigned long data)
-{
- struct mtk_cqdma_pchan *pc = (struct mtk_cqdma_pchan *)data;
- struct mtk_cqdma_vdesc *cvd = NULL;
- unsigned long flags;
-
- spin_lock_irqsave(&pc->lock, flags);
- /* consume the queue */
- cvd = mtk_cqdma_consume_work_queue(pc);
- spin_unlock_irqrestore(&pc->lock, flags);
-
- /* submit the next CVD */
- if (cvd) {
- dma_run_dependencies(&cvd->vd.tx);
-
- /*
- * free child CVD after completion.
- * the parent CVD would be freeed with desc_free by user.
- */
- if (cvd->parent != cvd)
- kfree(cvd);
+ /* get the next active VD */
+ vd = vchan_next_desc(&cvc->vc);
+ pc->active_vdesc = (!vd) ? NULL : to_cqdma_vdesc(vd);
}
- /* re-enable interrupt before leaving tasklet */
- enable_irq(pc->irq);
+ /* start the next transaction */
+ if (pc->active_vdesc)
+ mtk_cqdma_start(pc, pc->active_vdesc);
+
+ spin_unlock(&cvc->vc.lock);
}
static irqreturn_t mtk_cqdma_irq(int irq, void *devid)
{
struct mtk_cqdma_device *cqdma = devid;
irqreturn_t ret = IRQ_NONE;
- bool schedule_tasklet = false;
u32 i;
/* clear interrupt flags for each PC */
- for (i = 0; i < cqdma->dma_channels; ++i, schedule_tasklet = false) {
+ for (i = 0; i < cqdma->dma_channels; ++i) {
spin_lock(&cqdma->pc[i]->lock);
if (mtk_dma_read(cqdma->pc[i],
MTK_CQDMA_INT_FLAG) & MTK_CQDMA_INT_FLAG_BIT) {
@@ -399,72 +323,21 @@ static irqreturn_t mtk_cqdma_irq(int irq, void *devid)
mtk_dma_clr(cqdma->pc[i], MTK_CQDMA_INT_FLAG,
MTK_CQDMA_INT_FLAG_BIT);
- schedule_tasklet = true;
+ mtk_cqdma_complete_vdesc(cqdma->pc[i]);
+
ret = IRQ_HANDLED;
}
spin_unlock(&cqdma->pc[i]->lock);
-
- if (schedule_tasklet) {
- /* disable interrupt */
- disable_irq_nosync(cqdma->pc[i]->irq);
-
- /* schedule the tasklet to handle the transactions */
- tasklet_schedule(&cqdma->pc[i]->tasklet);
- }
}
return ret;
}
-static struct virt_dma_desc *mtk_cqdma_find_active_desc(struct dma_chan *c,
- dma_cookie_t cookie)
-{
- struct mtk_cqdma_vchan *cvc = to_cqdma_vchan(c);
- struct virt_dma_desc *vd;
- unsigned long flags;
-
- spin_lock_irqsave(&cvc->pc->lock, flags);
- list_for_each_entry(vd, &cvc->pc->queue, node)
- if (vd->tx.cookie == cookie) {
- spin_unlock_irqrestore(&cvc->pc->lock, flags);
- return vd;
- }
- spin_unlock_irqrestore(&cvc->pc->lock, flags);
-
- list_for_each_entry(vd, &cvc->vc.desc_issued, node)
- if (vd->tx.cookie == cookie)
- return vd;
-
- return NULL;
-}
-
static enum dma_status mtk_cqdma_tx_status(struct dma_chan *c,
dma_cookie_t cookie,
struct dma_tx_state *txstate)
{
- struct mtk_cqdma_vchan *cvc = to_cqdma_vchan(c);
- struct mtk_cqdma_vdesc *cvd;
- struct virt_dma_desc *vd;
- enum dma_status ret;
- unsigned long flags;
- size_t bytes = 0;
-
- ret = dma_cookie_status(c, cookie, txstate);
- if (ret == DMA_COMPLETE || !txstate)
- return ret;
-
- spin_lock_irqsave(&cvc->vc.lock, flags);
- vd = mtk_cqdma_find_active_desc(c, cookie);
- spin_unlock_irqrestore(&cvc->vc.lock, flags);
-
- if (vd) {
- cvd = to_cqdma_vdesc(vd);
- bytes = cvd->residue;
- }
-
- dma_set_residue(txstate, bytes);
-
- return ret;
+ return dma_cookie_status(c, cookie, txstate);
}
static void mtk_cqdma_issue_pending(struct dma_chan *c)
@@ -473,13 +346,17 @@ static void mtk_cqdma_issue_pending(struct dma_chan *c)
unsigned long pc_flags;
unsigned long vc_flags;
- /* acquire PC's lock before VS's lock for lock dependency in tasklet */
+ /* acquire PC's lock before VC's lock for lock dependency in ISR */
spin_lock_irqsave(&cvc->pc->lock, pc_flags);
spin_lock_irqsave(&cvc->vc.lock, vc_flags);
+ init_completion(&cvc->cmp);
+
if (vchan_issue_pending(&cvc->vc))
mtk_cqdma_issue_vchan_pending(cvc);
+ complete(&cvc->cmp);
+
spin_unlock_irqrestore(&cvc->vc.lock, vc_flags);
spin_unlock_irqrestore(&cvc->pc->lock, pc_flags);
}
@@ -488,125 +365,50 @@ static void mtk_cqdma_issue_pending(struct dma_chan *c)
mtk_cqdma_prep_dma_memcpy(struct dma_chan *c, dma_addr_t dest,
dma_addr_t src, size_t len, unsigned long flags)
{
- struct mtk_cqdma_vdesc **cvd;
- struct dma_async_tx_descriptor *tx = NULL, *prev_tx = NULL;
- size_t i, tlen, nr_vd;
-
- /*
- * In the case that trsanction length is larger than the
- * DMA engine supports, a single memcpy transaction needs
- * to be separated into several DMA transactions.
- * Each DMA transaction would be described by a CVD,
- * and the first one is referred as the parent CVD,
- * while the others are child CVDs.
- * The parent CVD's tx descriptor is the only tx descriptor
- * returned to the DMA user, and it should not be completed
- * until all the child CVDs completed.
- */
- nr_vd = DIV_ROUND_UP(len, MTK_CQDMA_MAX_LEN);
- cvd = kcalloc(nr_vd, sizeof(*cvd), GFP_NOWAIT);
+ struct mtk_cqdma_vdesc *cvd;
+
+ cvd = kzalloc(sizeof(*cvd), GFP_NOWAIT);
if (!cvd)
return NULL;
- for (i = 0; i < nr_vd; ++i) {
- cvd[i] = kzalloc(sizeof(*cvd[i]), GFP_NOWAIT);
- if (!cvd[i]) {
- for (; i > 0; --i)
- kfree(cvd[i - 1]);
- return NULL;
- }
-
- /* setup dma channel */
- cvd[i]->ch = c;
-
- /* setup sourece, destination, and length */
- tlen = (len > MTK_CQDMA_MAX_LEN) ? MTK_CQDMA_MAX_LEN : len;
- cvd[i]->len = tlen;
- cvd[i]->src = src;
- cvd[i]->dest = dest;
-
- /* setup tx descriptor */
- tx = vchan_tx_prep(to_virt_chan(c), &cvd[i]->vd, flags);
- tx->next = NULL;
+ /* setup dma channel */
+ cvd->ch = c;
- if (!i) {
- cvd[0]->residue = len;
- } else {
- prev_tx->next = tx;
- cvd[i]->residue = tlen;
- }
-
- cvd[i]->parent = cvd[0];
-
- /* update the src, dest, len, prev_tx for the next CVD */
- src += tlen;
- dest += tlen;
- len -= tlen;
- prev_tx = tx;
- }
+ /* setup sourece, destination, and length */
+ cvd->len = len;
+ cvd->src = src;
+ cvd->dest = dest;
- return &cvd[0]->vd.tx;
+ return vchan_tx_prep(to_virt_chan(c), &cvd->vd, flags);
}
-static void mtk_cqdma_free_inactive_desc(struct dma_chan *c)
-{
- struct virt_dma_chan *vc = to_virt_chan(c);
- unsigned long flags;
- LIST_HEAD(head);
-
- /*
- * set desc_allocated, desc_submitted,
- * and desc_issued as the candicates to be freed
- */
- spin_lock_irqsave(&vc->lock, flags);
- list_splice_tail_init(&vc->desc_allocated, &head);
- list_splice_tail_init(&vc->desc_submitted, &head);
- list_splice_tail_init(&vc->desc_issued, &head);
- spin_unlock_irqrestore(&vc->lock, flags);
-
- /* free descriptor lists */
- vchan_dma_desc_free_list(vc, &head);
-}
-
-static void mtk_cqdma_free_active_desc(struct dma_chan *c)
+static int mtk_cqdma_terminate_all(struct dma_chan *c)
{
struct mtk_cqdma_vchan *cvc = to_cqdma_vchan(c);
- bool sync_needed = false;
+ struct virt_dma_chan *vc = to_virt_chan(c);
unsigned long pc_flags;
unsigned long vc_flags;
+ LIST_HEAD(head);
+
+ /* wait for the VC to be inactive */
+ if (!wait_for_completion_timeout(&cvc->cmp, msecs_to_jiffies(3000)))
+ return -EAGAIN;
/* acquire PC's lock first due to lock dependency in dma ISR */
spin_lock_irqsave(&cvc->pc->lock, pc_flags);
spin_lock_irqsave(&cvc->vc.lock, vc_flags);
- /* synchronization is required if this VC is active */
- if (mtk_cqdma_is_vchan_active(cvc)) {
- cvc->issue_synchronize = true;
- sync_needed = true;
- }
+ /* get VDs from lists */
+ vchan_get_all_descriptors(vc, &head);
+
+ /* free all the VDs */
+ vchan_dma_desc_free_list(vc, &head);
spin_unlock_irqrestore(&cvc->vc.lock, vc_flags);
spin_unlock_irqrestore(&cvc->pc->lock, pc_flags);
- /* waiting for the completion of this VC */
- if (sync_needed)
- wait_for_completion(&cvc->issue_completion);
-
- /* free all descriptors in list desc_completed */
vchan_synchronize(&cvc->vc);
- WARN_ONCE(!list_empty(&cvc->vc.desc_completed),
- "Desc pending still in list desc_completed\n");
-}
-
-static int mtk_cqdma_terminate_all(struct dma_chan *c)
-{
- /* free descriptors not processed yet by hardware */
- mtk_cqdma_free_inactive_desc(c);
-
- /* free descriptors being processed by hardware */
- mtk_cqdma_free_active_desc(c);
-
return 0;
}
@@ -618,7 +420,7 @@ static int mtk_cqdma_alloc_chan_resources(struct dma_chan *c)
u32 i, min_refcnt = U32_MAX, refcnt;
unsigned long flags;
- /* allocate PC with the minimun refcount */
+ /* allocate PC with the minimum refcount */
for (i = 0; i < cqdma->dma_channels; ++i) {
refcnt = refcount_read(&cqdma->pc[i]->refcnt);
if (refcnt < min_refcnt) {
@@ -671,8 +473,9 @@ static void mtk_cqdma_free_chan_resources(struct dma_chan *c)
mtk_dma_set(cvc->pc, MTK_CQDMA_FLUSH, MTK_CQDMA_FLUSH_BIT);
/* wait for the completion of flush operation */
- if (mtk_cqdma_poll_engine_done(cvc->pc, true) < 0)
- dev_err(cqdma2dev(to_cqdma_dev(c)), "cqdma flush timeout\n");
+ if (mtk_cqdma_poll_engine_done(cvc->pc) < 0)
+ dev_err(cqdma2dev(to_cqdma_dev(c)),
+ "cqdma flush timeout\n");
/* clear the flush bit and interrupt flag */
mtk_dma_clr(cvc->pc, MTK_CQDMA_FLUSH, MTK_CQDMA_FLUSH_BIT);
@@ -816,10 +619,18 @@ static int mtk_cqdma_probe(struct platform_device *pdev)
if (!cqdma->pc[i])
return -ENOMEM;
- INIT_LIST_HEAD(&cqdma->pc[i]->queue);
+ cqdma->pc[i]->active_vdesc = NULL;
spin_lock_init(&cqdma->pc[i]->lock);
refcount_set(&cqdma->pc[i]->refcnt, 0);
- cqdma->pc[i]->base = devm_platform_ioremap_resource(pdev, i);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, i);
+ if (!res) {
+ dev_err(&pdev->dev, "No mem resource for %s\n",
+ dev_name(&pdev->dev));
+ return -EINVAL;
+ }
+
+ cqdma->pc[i]->base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(cqdma->pc[i]->base))
return PTR_ERR(cqdma->pc[i]->base);
@@ -852,7 +663,6 @@ static int mtk_cqdma_probe(struct platform_device *pdev)
vc = &cqdma->vc[i];
vc->vc.desc_free = mtk_cqdma_vdesc_free;
vchan_init(&vc->vc, dd);
- init_completion(&vc->issue_completion);
}
err = dma_async_device_register(dd);
@@ -876,11 +686,6 @@ static int mtk_cqdma_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, cqdma);
- /* initialize tasklet for each PC */
- for (i = 0; i < cqdma->dma_channels; ++i)
- tasklet_init(&cqdma->pc[i]->tasklet, mtk_cqdma_tasklet_cb,
- (unsigned long)cqdma->pc[i]);
-
dev_info(&pdev->dev, "MediaTek CQDMA driver registered\n");
return 0;
@@ -915,8 +720,6 @@ static int mtk_cqdma_remove(struct platform_device *pdev)
/* Waits for any pending IRQ handlers to complete */
synchronize_irq(cqdma->pc[i]->irq);
-
- tasklet_kill(&cqdma->pc[i]->tasklet);
}
/* disable hardware */
--
1.9.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v4 4/4] dmaengine: mediatek-cqdma: add dma mask for capability
From: EastL @ 2020-05-28 9:57 UTC (permalink / raw)
To: Sean Wang
Cc: mark.rutland, devicetree, wsd_upstream, linux-kernel, EastL,
dmaengine, vkoul, robh+dt, linux-mediatek, matthias.bgg,
linux-arm-kernel
In-Reply-To: <1590659832-31476-1-git-send-email-EastL.Lee@mediatek.com>
This patch add dma mask for capability.
Change-Id: I31f4622f9541d769702029532e5f5f185815dda2
Signed-off-by: EastL <EastL.Lee@mediatek.com>
---
drivers/dma/mediatek/mtk-cqdma.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/drivers/dma/mediatek/mtk-cqdma.c b/drivers/dma/mediatek/mtk-cqdma.c
index bca7118..1805a76 100644
--- a/drivers/dma/mediatek/mtk-cqdma.c
+++ b/drivers/dma/mediatek/mtk-cqdma.c
@@ -117,6 +117,7 @@ struct mtk_cqdma_vchan {
* @clk: The clock that device internal is using
* @dma_requests: The number of VCs the device supports to
* @dma_channels: The number of PCs the device supports to
+ * @dma_mask: A mask for DMA capability
* @vc: The pointer to all available VCs
* @pc: The pointer to all the underlying PCs
*/
@@ -126,6 +127,7 @@ struct mtk_cqdma_device {
u32 dma_requests;
u32 dma_channels;
+ u32 dma_mask;
struct mtk_cqdma_vchan *vc;
struct mtk_cqdma_pchan **pc;
};
@@ -549,6 +551,7 @@ static void mtk_cqdma_hw_deinit(struct mtk_cqdma_device *cqdma)
};
MODULE_DEVICE_TABLE(of, mtk_cqdma_match);
+static u64 cqdma_dmamask;
static int mtk_cqdma_probe(struct platform_device *pdev)
{
struct mtk_cqdma_device *cqdma;
@@ -607,6 +610,16 @@ static int mtk_cqdma_probe(struct platform_device *pdev)
cqdma->dma_channels = MTK_CQDMA_NR_PCHANS;
}
+ if (pdev->dev.of_node && of_property_read_u32(pdev->dev.of_node,
+ "dma-channel-mask",
+ &cqdma->dma_mask)) {
+ dev_info(&pdev->dev,
+ "Using 0 as missing dma-channel-mask property\n");
+ } else {
+ cqdma_dmamask = DMA_BIT_MASK(cqdma->dma_mask);
+ pdev->dev.dma_mask = &cqdma_dmamask;
+ }
+
cqdma->pc = devm_kcalloc(&pdev->dev, cqdma->dma_channels,
sizeof(*cqdma->pc), GFP_KERNEL);
if (!cqdma->pc)
--
1.9.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v4] dmaengine: mediatek-cqdma: add dt-bindings and remove redundant queue
From: EastL @ 2020-05-28 9:57 UTC (permalink / raw)
To: Sean Wang
Cc: mark.rutland, devicetree, wsd_upstream, linux-kernel, dmaengine,
vkoul, robh+dt, linux-mediatek, matthias.bgg, linux-arm-kernel
This patch set adds document the devicetree bindings for MediaTek Command-Queue DMA controller,
and remove redundant queue structure, add dma-channel-mask for DMA capability and fix compatible.
Changes since v3:
- fix dt_binding_check errors
Changes since v2:
- add devicetree bindings for MediaTek Command-Queue DMA controller
Changes since v1:
- remove redundant queue structure
- fix wrong description and tags in the earlier patch
- add dma-channel-mask for DMA capability
- fix compatible for common
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH v4 1/4] dt-bindings: dmaengine: Add MediaTek Command-Queue DMA controller bindings
From: EastL @ 2020-05-28 9:57 UTC (permalink / raw)
To: Sean Wang
Cc: mark.rutland, devicetree, wsd_upstream, linux-kernel, EastL,
dmaengine, vkoul, robh+dt, linux-mediatek, matthias.bgg,
linux-arm-kernel
In-Reply-To: <1590659832-31476-1-git-send-email-EastL.Lee@mediatek.com>
Document the devicetree bindings for MediaTek Command-Queue DMA controller
which could be found on MT6779 SoC or other similar Mediatek SoCs.
Signed-off-by: EastL <EastL.Lee@mediatek.com>
---
.../devicetree/bindings/dma/mtk-cqdma.yaml | 100 +++++++++++++++++++++
1 file changed, 100 insertions(+)
create mode 100644 Documentation/devicetree/bindings/dma/mtk-cqdma.yaml
diff --git a/Documentation/devicetree/bindings/dma/mtk-cqdma.yaml b/Documentation/devicetree/bindings/dma/mtk-cqdma.yaml
new file mode 100644
index 0000000..045aa0c
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/mtk-cqdma.yaml
@@ -0,0 +1,100 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/dma/mtk-cqdma.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek Command-Queue DMA controller Device Tree Binding
+
+maintainers:
+ - EastL <EastL.Lee@mediatek.com>
+
+description:
+ MediaTek Command-Queue DMA controller (CQDMA) on Mediatek SoC
+ is dedicated to memory-to-memory transfer through queue based
+ descriptor management.
+
+properties:
+ "#dma-cells":
+ minimum: 1
+ # Should be enough
+ maximum: 255
+ description:
+ Used to provide DMA controller specific information.
+
+ compatible:
+ const: mediatek,cqdma
+
+ reg:
+ minItems: 1
+ maxItems: 255
+
+ interrupts:
+ minItems: 1
+ maxItems: 255
+
+ clocks:
+ maxItems: 1
+
+ clock-names:
+ const: cqdma
+
+ dma-channel-mask:
+ description:
+ Bitmask of available DMA channels in ascending order that are
+ not reserved by firmware and are available to the
+ kernel. i.e. first channel corresponds to LSB.
+ The first item in the array is for channels 0-31, the second is for
+ channels 32-63, etc.
+ allOf:
+ - $ref: /schemas/types.yaml#/definitions/uint32-array
+ items:
+ minItems: 1
+ # Should be enough
+ maxItems: 255
+
+ dma-channels:
+ $ref: /schemas/types.yaml#definitions/uint32
+ description:
+ Number of DMA channels supported by the controller.
+
+ dma-requests:
+ $ref: /schemas/types.yaml#definitions/uint32
+ description:
+ Number of DMA request signals supported by the controller.
+
+required:
+ - "#dma-cells"
+ - compatible
+ - reg
+ - interrupts
+ - clocks
+ - clock-names
+ - dma-channel-mask
+ - dma-channels
+ - dma-requests
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/irq.h>
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/clock/mt6779-clk.h>
+ cqdma: dma-controller@10212000 {
+ compatible = "mediatek,cqdma";
+ reg = <0 0x10212000 0 0x80>,
+ <0 0x10212080 0 0x80>,
+ <0 0x10212100 0 0x80>;
+ interrupts = <GIC_SPI 139 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_SPI 140 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_SPI 141 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&infracfg_ao CLK_INFRA_CQ_DMA>;
+ clock-names = "cqdma";
+ dma-channel-mask = <63>;
+ dma-channels = <3>;
+ dma-requests = <32>;
+ #dma-cells = <1>;
+ };
+
+...
--
1.9.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v4 3/4] dmaengine: mediatek-cqdma: fix compatible
From: EastL @ 2020-05-28 9:57 UTC (permalink / raw)
To: Sean Wang
Cc: mark.rutland, devicetree, wsd_upstream, linux-kernel, EastL,
dmaengine, vkoul, robh+dt, linux-mediatek, matthias.bgg,
linux-arm-kernel
In-Reply-To: <1590659832-31476-1-git-send-email-EastL.Lee@mediatek.com>
This patch fixes mediatek-cqdma compatible to common.
Signed-off-by: EastL <EastL.Lee@mediatek.com>
---
drivers/dma/mediatek/mtk-cqdma.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/dma/mediatek/mtk-cqdma.c b/drivers/dma/mediatek/mtk-cqdma.c
index 905bbcb..bca7118 100644
--- a/drivers/dma/mediatek/mtk-cqdma.c
+++ b/drivers/dma/mediatek/mtk-cqdma.c
@@ -544,7 +544,7 @@ static void mtk_cqdma_hw_deinit(struct mtk_cqdma_device *cqdma)
}
static const struct of_device_id mtk_cqdma_match[] = {
- { .compatible = "mediatek,mt6765-cqdma" },
+ { .compatible = "mediatek,cqdma" },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, mtk_cqdma_match);
--
1.9.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* Re: [PATCH] arm64: vdso32: force vdso32 to be compiled as -marm
From: Catalin Marinas @ 2020-05-28 9:41 UTC (permalink / raw)
To: Peter Smith
Cc: Naohiro Aota, Stephen Boyd, Arnd Bergmann, Will Deacon,
Masahiro Yamada, Nick Desaulniers, LKML,
david.spickett@linaro.org, Manoj Gupta, Kristof Beyls,
Luis Lozano, Nathan Chancellor, Vincenzo Frascino, Robin Murphy,
Victor Campos, Linux ARM
In-Reply-To: <VI1PR08MB319868AFBEDCD0925C53701AF88E0@VI1PR08MB3198.eurprd08.prod.outlook.com>
On Thu, May 28, 2020 at 09:05:08AM +0100, Peter Smith wrote:
> I suggest using Arm if you need a frame pointer, and disable the
> frame pointer if you want/need to use Thumb. My understanding is that
> runtime unwinding using the frame pointer in Thumb is already difficult
> due to Arm and Thumb functions using different registers for the frame
> pointer.
IIRC from the Thumb-2 kernel porting days, even in the absence of
ARM/Thumb interworking, the Thumb-2 frame pointer was pretty useless for
unwinding since it points to the bottom of the current stack frame (the
reason I think is that some LDR/STR instructions with negative indexing
are not available). So finding the previous frame pointer was not
possible and had to rely on the exception unwinding information.
--
Catalin
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH] irqchip/irq-mtk-sysirq: replace spinlock with raw_spinlock
From: Bartosz Golaszewski @ 2020-05-28 9:35 UTC (permalink / raw)
To: Thomas Gleixner, Jason Cooper, Marc Zyngier, Matthias Brugger
Cc: Stephane Le Provost, Bartosz Golaszewski, Pedro Tsai,
linux-kernel, Fabien Parent, linux-mediatek, Andrew Perepech,
linux-arm-kernel
From: Bartosz Golaszewski <bgolaszewski@baylibre.com>
This driver may take a regular spinlock when a raw spinlock
(irq_desc->lock) is already taken which results in the following
lockdep splat:
=============================
[ BUG: Invalid wait context ]
5.7.0-rc7 #1 Not tainted
-----------------------------
swapper/0/0 is trying to lock:
ffffff800303b798 (&chip_data->lock){....}-{3:3}, at: mtk_sysirq_set_type+0x48/0xc0
other info that might help us debug this:
context-{5:5}
2 locks held by swapper/0/0:
#0: ffffff800302ee68 (&desc->request_mutex){....}-{4:4}, at: __setup_irq+0xc4/0x8a0
#1: ffffff800302ecf0 (&irq_desc_lock_class){....}-{2:2}, at: __setup_irq+0xe4/0x8a0
stack backtrace:
CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.7.0-rc7 #1
Hardware name: Pumpkin MT8516 (DT)
Call trace:
dump_backtrace+0x0/0x180
show_stack+0x14/0x20
dump_stack+0xd0/0x118
__lock_acquire+0x8c8/0x2270
lock_acquire+0xf8/0x470
_raw_spin_lock_irqsave+0x50/0x78
mtk_sysirq_set_type+0x48/0xc0
__irq_set_trigger+0x58/0x170
__setup_irq+0x420/0x8a0
request_threaded_irq+0xd8/0x190
timer_of_init+0x1e8/0x2c4
mtk_gpt_init+0x5c/0x1dc
timer_probe+0x74/0xf4
time_init+0x14/0x44
start_kernel+0x394/0x4f0
Replace the spinlock_t with raw_spinlock_t to avoid this warning.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
drivers/irqchip/irq-mtk-sysirq.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/irqchip/irq-mtk-sysirq.c b/drivers/irqchip/irq-mtk-sysirq.c
index 73eae5966a40..6ff98b87e5c0 100644
--- a/drivers/irqchip/irq-mtk-sysirq.c
+++ b/drivers/irqchip/irq-mtk-sysirq.c
@@ -15,7 +15,7 @@
#include <linux/spinlock.h>
struct mtk_sysirq_chip_data {
- spinlock_t lock;
+ raw_spinlock_t lock;
u32 nr_intpol_bases;
void __iomem **intpol_bases;
u32 *intpol_words;
@@ -37,7 +37,7 @@ static int mtk_sysirq_set_type(struct irq_data *data, unsigned int type)
reg_index = chip_data->which_word[hwirq];
offset = hwirq & 0x1f;
- spin_lock_irqsave(&chip_data->lock, flags);
+ raw_spin_lock_irqsave(&chip_data->lock, flags);
value = readl_relaxed(base + reg_index * 4);
if (type == IRQ_TYPE_LEVEL_LOW || type == IRQ_TYPE_EDGE_FALLING) {
if (type == IRQ_TYPE_LEVEL_LOW)
@@ -53,7 +53,7 @@ static int mtk_sysirq_set_type(struct irq_data *data, unsigned int type)
data = data->parent_data;
ret = data->chip->irq_set_type(data, type);
- spin_unlock_irqrestore(&chip_data->lock, flags);
+ raw_spin_unlock_irqrestore(&chip_data->lock, flags);
return ret;
}
@@ -212,7 +212,7 @@ static int __init mtk_sysirq_of_init(struct device_node *node,
ret = -ENOMEM;
goto out_free_which_word;
}
- spin_lock_init(&chip_data->lock);
+ raw_spin_lock_init(&chip_data->lock);
return 0;
--
2.25.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH 3/3] ARM: imx7: add support for iotmaxx GW4100
From: Steffen Trumtrar @ 2020-05-28 9:31 UTC (permalink / raw)
To: Shawn Guo, Rob Herring
Cc: linux-arm-kernel, Fabio Estevam, NXP Linux Team,
Pengutronix Kernel Team
In-Reply-To: <20200528093115.28268-1-s.trumtrar@pengutronix.de>
The GW4100 will be an i.MX7D based board from IoTMaxx.
The support is almost complete apart from the pmic setup which currently
can not be used because of a hardware bug. This can and will be changed
once it is fixed in hardware.
Signed-off-by: Steffen Trumtrar <s.trumtrar@pengutronix.de>
---
arch/arm/boot/dts/Makefile | 1 +
arch/arm/boot/dts/imx7d-iotmaxx-gw4100.dts | 574 +++++++++++++++++++++
2 files changed, 575 insertions(+)
create mode 100644 arch/arm/boot/dts/imx7d-iotmaxx-gw4100.dts
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index e8dd99201397..f596492a115c 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -623,6 +623,7 @@ dtb-$(CONFIG_SOC_IMX7D) += \
imx7d-colibri-emmc-aster.dtb \
imx7d-colibri-emmc-eval-v3.dtb \
imx7d-colibri-eval-v3.dtb \
+ imx7d-iotmaxx-gw4100.dtb \
imx7d-mba7.dtb \
imx7d-meerkat96.dtb \
imx7d-nitrogen7.dtb \
diff --git a/arch/arm/boot/dts/imx7d-iotmaxx-gw4100.dts b/arch/arm/boot/dts/imx7d-iotmaxx-gw4100.dts
new file mode 100644
index 000000000000..cc78dac80da2
--- /dev/null
+++ b/arch/arm/boot/dts/imx7d-iotmaxx-gw4100.dts
@@ -0,0 +1,574 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+* Copyright (C) 2020 Steffen Trumtrar <s.trumtrar@pengutronix.de>
+*/
+
+/dts-v1/;
+#include "imx7d.dtsi"
+
+/ {
+ model = "IoTMAXX i.MX7D GW4100 Gateway";
+ compatible = "iotmaxx,imx7d-gw4100", "fsl,imx7d";
+
+ chosen {
+ stdout-path = &uart3;
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x80000000 0x40000000>;
+ };
+
+ iio-hwmon {
+ compatible = "iio-hwmon";
+ io-channels = <&adc1 0>, <&adc1 1>, <&adc1 2>, <&adc1 3>,
+ <&adc2 0>, <&adc2 1>, <&adc2 2>;
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+ pinctrl-0 = <&pinctrl_leds_usr>;
+ pinctrl-names = "default";
+
+ usr1 {
+ label = "iotmaxx:green:usr1";
+ gpios = <&gpio4 15 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "heartbeat";
+ };
+
+ usr2 {
+ label = "iotmaxx:green:usr2";
+ gpios = <&gpio4 14 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ reg_ldo_emmc_3v3: ldo_emmc_3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "ldo_emmc_v3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ reg_ldo_misc_3v3: ldo_misc_3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "ldo_misc_v3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ reg_dcdc_1v8: ldo_dcdc_1v8 {
+ compatible = "regulator-fixed";
+ regulator-name = "ldo_dcdc_1v8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ reg_vadc_1v8: regulator-vadc-1v8 {
+ compatible = "regulator-fixed";
+ regulator-name = "vadc_1v8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ reg_5v_periph: regulator-5v-periph {
+ compatible = "regulator-fixed";
+ regulator-name = "5v_periph";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio2 2 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ regulator-always-on;
+ };
+
+ reg_usb_gsm_vbus: regulator-usb-gsm-vbus {
+ compatible = "regulator-fixed";
+ regulator-name = "usb_gsm_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio3 4 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ regulator-always-on;
+ };
+
+ reg_gsm_pwr_en_3v3: regulator-gsm-pwr-en-3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "gsm_pwr_en_3v3";
+ pinctrl-names = "default";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio2 15 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ regulator-always-on;
+ };
+
+ reg_usb_otg1_vbus: regulator-usb-otg1-vbus {
+ compatible = "regulator-fixed";
+ regulator-name = "usb_otg1_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ };
+
+ reg_usb_otg2_vbus: regulator-usb-otg2-vbus {
+ compatible = "regulator-fixed";
+ regulator-name = "usb_otg2_vbus";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb_otg2_vbus_reg>;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio1 7 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+};
+
+&adc1 {
+ vref-supply = <®_vadc_1v8>;
+ status = "okay";
+};
+
+&adc2 {
+ vref-supply = <®_vadc_1v8>;
+ status = "okay";
+};
+
+&fec2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet2>,
+ <&pinctrl_mdio>,
+ <&pinctrl_rmii_phy>;
+ /* set the enet_ref_clk and enet_out with a 50MHz clock */
+ assigned-clocks = <&clks IMX7D_ENET_PHY_REF_ROOT_DIV>;
+ assigned-clock-parents = <&clks IMX7D_PLL_ENET_MAIN_100M_CLK>;
+ assigned-clock-rates = <50000000>;
+ clocks = <&clks IMX7D_ENET2_IPG_ROOT_CLK>,
+ <&clks IMX7D_ENET_AXI_ROOT_CLK>,
+ <&clks IMX7D_ENET2_TIME_ROOT_CLK>,
+ <&clks IMX7D_PLL_ENET_MAIN_50M_CLK>,
+ <&clks IMX7D_ENET2_REF_ROOT_DIV>;
+ clock-names = "ipg", "ahb", "ptp",
+ "enet_clk_ref", "enet_out";
+ phy-handle = <ðphy1>;
+ phy-mode = "rmii";
+ phy-reset-gpios = <&gpio2 27 GPIO_ACTIVE_LOW>;
+ fsl,magic-packet;
+ status = "okay";
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethphy1: ethernet-phy@1 {
+ interrupt-parent = <&gpio2>;
+ interrupts = <25 IRQ_TYPE_LEVEL_LOW>;
+
+ clocks = <&clks IMX7D_ENET2_REF_ROOT_DIV>;
+ clock-names = "rmii-ref";
+ reg = <1>;
+ };
+ };
+};
+
+&flexcan1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan1>;
+ xceiver-supply = <®_5v_periph>;
+ status = "okay";
+};
+
+&gpio1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio1>;
+
+ gpio-line-names = "gpio1_highside",
+ "gpio1_lowside", "gpio1_pullup", "n_gpio1_in", "gpio2_highside", "gpio2_lowside",
+ "n_usb_ext_oc", "usb_ext_pwr", "", "", "",
+ "", "", "", "", "",
+ "", "", "", "", "",
+ "", "", "", "", "",
+ "", "", "", "", "",
+ "";
+};
+
+&gpio2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio2>;
+ status = "okay";
+
+ gpio-line-names = "",
+ "", "5v_periph_en", "", "sim_cd1", "sim_cd2",
+ "", "", "", "", "",
+ "", "", "", "", "gsm_pwr_en_3v3",
+ "", "", "n_usbhub_int", "usbhub_connect", "",
+ "", "", "", "", "",
+ "", "", "", "", "n_usbhub_rst",
+ "";
+};
+
+&gpio3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio3>;
+ status = "okay";
+
+ gpio-line-names = "",
+ "", "", "", "vusb_gsm_en", "",
+ "", "", "", "", "",
+ "", "", "", "", "",
+ "", "", "", "", "",
+ "", "", "", "", "sim_enable",
+ "", "", "", "", "",
+ "";
+};
+
+&gpio4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio4>,
+ <&pinctrl_gpio4_hog>;
+ status = "okay";
+
+ gpio-line-names = "",
+ "", "", "", "", "",
+ "", "", "", "", "",
+ "", "n_can_term_en", "", "led_usr2", "led_usr1",
+ "sim_sel", "gsm_reset", "", "n_gsm_pwr_ind", "",
+ "", "", "", "", "",
+ "", "", "", "", "",
+ "";
+
+ gsm-pwr-on-off {
+ gpio-hog;
+ gpios = <18 GPIO_ACTIVE_HIGH>;
+ output-high;
+ line-name = "gsm_power_on_off";
+ };
+};
+
+&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ status = "okay";
+
+ 1wiremaster@18 {
+ compatible = "ds2482";
+ reg = <0x18>;
+ };
+};
+
+/* CTRL_I2C */
+&i2c3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c3>;
+ status = "okay";
+
+ usb_hub: usb-hub@8 {
+ compatible = "smsc,usb3503";
+ reg = <0x8>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbhub>;
+ initial-mode = <1>; /* HUB mode */
+ reset-gpios = <&gpio2 30 GPIO_ACTIVE_LOW>;
+ intn-gpios = <&gpio2 18 GPIO_ACTIVE_LOW>;
+ connect-gpios = <&gpio2 19 GPIO_ACTIVE_HIGH>;
+ clocks = <&clks IMX7D_OSC_24M_CLK>;
+ clock-names = "refclk";
+ };
+
+ tpm: tpm@20 {
+ compatible = "infineon,slb9645tt";
+ reg = <0x20>;
+ };
+
+ eeprom: eeprom@50 {
+ compatible = "atmel,24c01";
+ vcc-supply = <®_ldo_misc_3v3>;
+ pagesize = <8>;
+ reg = <0x50>;
+ };
+
+ pcf85363: pcf85363@51 {
+ compatible = "nxp,pcf85363";
+ reg = <0x51>;
+ };
+};
+
+/* EXP_I2C */
+&i2c4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c4>;
+ status = "okay";
+};
+
+&iomuxc {
+ pinctrl_mdio: mdiogrp {
+ fsl,pins = <
+ MX7D_PAD_UART2_RX_DATA__ENET2_MDIO 0x3 /* ENET_MDIO */
+ MX7D_PAD_UART2_TX_DATA__ENET2_MDC 0x3 /* ENET_MDC */
+ >;
+ };
+ pinctrl_enet2: enet2grp {
+ fsl,pins = <
+ MX7D_PAD_EPDC_SDCE0__ENET2_RGMII_RX_CTL 0x5 /* ENET2_CRS_DV */
+ MX7D_PAD_EPDC_SDCE1__ENET2_RX_ER 0x5 /* ENET2_RXER */
+ MX7D_PAD_EPDC_SDCE2__ENET2_RGMII_TD0 0x5 /* ENET2_TXD0 */
+ MX7D_PAD_EPDC_SDCE3__ENET2_RGMII_TD1 0x5 /* ENET2_TXD1 */
+ MX7D_PAD_EPDC_SDCLK__ENET2_RGMII_RD0 0x5 /* ENET2_RXD0 */
+ MX7D_PAD_EPDC_SDLE__ENET2_RGMII_RD1 0x5 /* ENET2_RXD1 */
+ MX7D_PAD_EPDC_GDCLK__GPIO2_IO24 0x5 /* ENET2_B-CAST_OFF */
+ MX7D_PAD_EPDC_GDRL__ENET2_RGMII_TX_CTL 0x5 /* ENET2_TXEN */
+ MX7D_PAD_EPDC_BDR0__CCM_ENET_REF_CLK2 0x40000001 /* ENET2_TX_CLK */
+ >;
+ };
+ pinctrl_rmii_phy: phygrp {
+ fsl,pins = <
+ MX7D_PAD_EPDC_GDSP__GPIO2_IO27 0x59 /* !ENET2_RST */
+ MX7D_PAD_EPDC_GDOE__GPIO2_IO25 0x59 /* !ENET2_INT */
+ >;
+ };
+
+ pinctrl_flexcan1: flexcan1grp {
+ fsl,pins = <
+ MX7D_PAD_GPIO1_IO12__FLEXCAN1_RX 0x5a
+ MX7D_PAD_GPIO1_IO13__FLEXCAN1_TX 0x52
+ >;
+ };
+
+ pinctrl_gpio2: gpio2grp {
+ fsl,pins = <
+ MX7D_PAD_EPDC_DATA02__GPIO2_IO2 0x14 /* 5V_PERIPH_EN */
+ MX7D_PAD_EPDC_DATA15__GPIO2_IO15 0x14 /* GSM_PWR_EN_3V3 */
+ MX7D_PAD_EPDC_DATA04__GPIO2_IO4 0x14 /* SIM_CD1 */
+ MX7D_PAD_EPDC_DATA05__GPIO2_IO5 0x14 /* SIM_CD2 */
+ >;
+ };
+
+ pinctrl_gpio3: gpio3grp {
+ fsl,pins = <
+ MX7D_PAD_LCD_RESET__GPIO3_IO4 0x79 /* VUSB_GSM_EN */
+ MX7D_PAD_LCD_DATA20__GPIO3_IO25 0x14 /* SIM_ENABLE */
+ >;
+ };
+
+ pinctrl_gpio4: gpio4grp {
+ fsl,pins = <
+ MX7D_PAD_ECSPI1_SS0__GPIO4_IO19 0x59 /* !GSM_PWR_IND */
+ MX7D_PAD_ECSPI1_SCLK__GPIO4_IO16 0x59 /* SIM_SEL */
+ MX7D_PAD_I2C3_SCL__GPIO4_IO12 0x59 /* !CAN_TERM_EN */
+ MX7D_PAD_ECSPI1_MOSI__GPIO4_IO17 0x03 /* GSM_RST */
+ >;
+ };
+
+ pinctrl_gpio4_hog: gpio4hoggrp {
+ fsl,pins = <
+ MX7D_PAD_ECSPI1_MISO__GPIO4_IO18 0x73 /* GSM_POWER_ON_OFF */
+ >;
+ };
+
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins = <
+ MX7D_PAD_UART1_RX_DATA__I2C1_SCL 0x40000078
+ MX7D_PAD_UART1_TX_DATA__I2C1_SDA 0x40000078
+ >;
+ };
+
+ pinctrl_i2c3: i2c3grp {
+ fsl,pins = <
+ MX7D_PAD_ENET1_RGMII_RD1__I2C3_SDA 0x40000078
+ MX7D_PAD_ENET1_RGMII_RD0__I2C3_SCL 0x40000078
+ >;
+ };
+
+ pinctrl_i2c4: i2c4grp {
+ fsl,pins = <
+ MX7D_PAD_ENET1_RGMII_TD3__I2C4_SDA 0x40000078
+ MX7D_PAD_ENET1_RGMII_TD2__I2C4_SCL 0x40000078
+ >;
+ };
+
+ pinctrl_leds_usr: ledsusrgrp {
+ fsl,pins = <
+ MX7D_PAD_I2C4_SDA__GPIO4_IO15 0x51 /* LED USR1 */
+ MX7D_PAD_I2C4_SCL__GPIO4_IO14 0x51 /* LED USR2 */
+ >;
+ };
+
+ pinctrl_uart3: uart3grp {
+ fsl,pins = <
+ MX7D_PAD_UART3_RX_DATA__UART3_DCE_RX 0x79
+ MX7D_PAD_UART3_TX_DATA__UART3_DCE_TX 0x79
+ MX7D_PAD_UART3_RTS_B__UART3_DCE_RTS 0x79
+ MX7D_PAD_UART3_CTS_B__UART3_DCE_CTS 0x79
+ >;
+ };
+
+ pinctrl_uart4: uart4grp {
+ fsl,pins = <
+ MX7D_PAD_I2C1_SCL__GPIO4_IO8 0x79 /* RS485_DE */
+ MX7D_PAD_I2C2_SCL__UART4_DCE_RX 0x79 /* RS485_R */
+ MX7D_PAD_I2C2_SDA__UART4_DCE_TX 0x79 /* RS458_D */
+ >;
+ };
+
+ pinctrl_usbhub: usbhubgrp {
+ fsl,pins = <
+ MX7D_PAD_EPDC_PWR_COM__GPIO2_IO30 0x59 /* !USBHUB_RST */
+ MX7D_PAD_EPDC_SDOE__GPIO2_IO18 0x59 /* !USBHUB_INT */
+ MX7D_PAD_EPDC_SDSHR__GPIO2_IO19 0x59 /* USBHUB_CONNECT */
+ >;
+ };
+
+ pinctrl_usdhc2: usdhc2grp {
+ fsl,pins = <
+ MX7D_PAD_SD2_CMD__SD2_CMD 0x59
+ MX7D_PAD_SD2_CLK__SD2_CLK 0x19
+ MX7D_PAD_SD2_DATA0__SD2_DATA0 0x59
+ MX7D_PAD_SD2_DATA1__SD2_DATA1 0x59
+ MX7D_PAD_SD2_DATA2__SD2_DATA2 0x59
+ MX7D_PAD_SD2_DATA3__SD2_DATA3 0x59
+ MX7D_PAD_SD2_CD_B__SD2_CD_B 0x59
+ >;
+ };
+
+ pinctrl_usdhc3: usdhc3grp {
+ fsl,pins = <
+ MX7D_PAD_SD3_CMD__SD3_CMD 0x59
+ MX7D_PAD_SD3_CLK__SD3_CLK 0x19
+ MX7D_PAD_SD3_DATA0__SD3_DATA0 0x59
+ MX7D_PAD_SD3_DATA1__SD3_DATA1 0x59
+ MX7D_PAD_SD3_DATA2__SD3_DATA2 0x59
+ MX7D_PAD_SD3_DATA3__SD3_DATA3 0x59
+ MX7D_PAD_SD3_DATA4__SD3_DATA4 0x59
+ MX7D_PAD_SD3_DATA5__SD3_DATA5 0x59
+ MX7D_PAD_SD3_DATA6__SD3_DATA6 0x59
+ MX7D_PAD_SD3_DATA7__SD3_DATA7 0x59
+ MX7D_PAD_SD3_STROBE__SD3_STROBE 0x19
+ >;
+ };
+
+ pinctrl_usdhc3_100mhz: usdhc3grp_100mhz {
+ fsl,pins = <
+ MX7D_PAD_SD3_CMD__SD3_CMD 0x5a
+ MX7D_PAD_SD3_CLK__SD3_CLK 0x1a
+ MX7D_PAD_SD3_DATA0__SD3_DATA0 0x5a
+ MX7D_PAD_SD3_DATA1__SD3_DATA1 0x5a
+ MX7D_PAD_SD3_DATA2__SD3_DATA2 0x5a
+ MX7D_PAD_SD3_DATA3__SD3_DATA3 0x5a
+ MX7D_PAD_SD3_DATA4__SD3_DATA4 0x5a
+ MX7D_PAD_SD3_DATA5__SD3_DATA5 0x5a
+ MX7D_PAD_SD3_DATA6__SD3_DATA6 0x5a
+ MX7D_PAD_SD3_DATA7__SD3_DATA7 0x5a
+ MX7D_PAD_SD3_STROBE__SD3_STROBE 0x1a
+ >;
+ };
+
+ pinctrl_usdhc3_200mhz: usdhc3grp_200mhz {
+ fsl,pins = <
+ MX7D_PAD_SD3_CMD__SD3_CMD 0x5b
+ MX7D_PAD_SD3_CLK__SD3_CLK 0x1b
+ MX7D_PAD_SD3_DATA0__SD3_DATA0 0x5b
+ MX7D_PAD_SD3_DATA1__SD3_DATA1 0x5b
+ MX7D_PAD_SD3_DATA2__SD3_DATA2 0x5b
+ MX7D_PAD_SD3_DATA3__SD3_DATA3 0x5b
+ MX7D_PAD_SD3_DATA4__SD3_DATA4 0x5b
+ MX7D_PAD_SD3_DATA5__SD3_DATA5 0x5b
+ MX7D_PAD_SD3_DATA6__SD3_DATA6 0x5b
+ MX7D_PAD_SD3_DATA7__SD3_DATA7 0x5b
+ MX7D_PAD_SD3_STROBE__SD3_STROBE 0x1b
+ >;
+ };
+};
+
+&iomuxc_lpsr {
+ pinctrl_gpio1: gpio1grp {
+ fsl,pins = <
+ MX7D_PAD_LPSR_GPIO1_IO00__GPIO1_IO0 0x00 /* GPIO1_HIGHSIDE */
+ MX7D_PAD_LPSR_GPIO1_IO01__GPIO1_IO1 0x00 /* GPIO1_LOWSIDE */
+ MX7D_PAD_LPSR_GPIO1_IO02__GPIO1_IO2 0x00 /* GPIO1_PULLUP */
+ MX7D_PAD_LPSR_GPIO1_IO03__GPIO1_IO3 0x00 /* GPIO1_IN */
+ MX7D_PAD_LPSR_GPIO1_IO04__GPIO1_IO4 0x00 /* GPIO2_HIGHSIDE */
+ MX7D_PAD_LPSR_GPIO1_IO05__GPIO1_IO5 0x00 /* GPIO2_LOWSIDE */
+ MX7D_PAD_LPSR_GPIO1_IO06__GPIO1_IO6 0x00 /* !USB_EXT_OC */
+ >;
+ };
+
+ pinctrl_usb_otg2_vbus_reg: usbotg2vbusreggrp {
+ fsl,pins = <
+ MX7D_PAD_LPSR_GPIO1_IO07__GPIO1_IO7 0x14 /* USB_EXT_PWR */
+ >;
+ };
+};
+
+&uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart3>;
+ assigned-clocks = <&clks IMX7D_UART3_ROOT_SRC>;
+ assigned-clock-parents = <&clks IMX7D_OSC_24M_CLK>;
+ uart-has-rtscts;
+ status = "okay";
+};
+
+/* Maxlinear SP483 RS-485 transceiver */
+&uart4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart4>;
+ rts-gpios = <&gpio4 8 GPIO_ACTIVE_HIGH>;
+ linux,rs485-enabled-at-boot-time;
+ status = "okay";
+};
+
+&usbphynop3 {
+ vcc-supply = <®_ldo_misc_3v3>;
+};
+
+&usbh {
+ disable-over-current;
+ status = "okay";
+};
+
+&usbphynop1 {
+ vcc-supply = <®_usb_otg1_vbus>;
+};
+
+&usbotg1 {
+ vbus-supply = <®_ldo_misc_3v3>;
+ dr_mode = "otg";
+ disable-over-current;
+ status = "okay";
+};
+
+&usbphynop2 {
+ vcc-supply = <®_usb_otg2_vbus>;
+};
+
+&usbotg2 {
+ vbus-supply = <®_usb_otg2_vbus>;
+ dr_mode = "host";
+ disable-over-current;
+ status = "okay";
+};
+
+&usdhc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc2>;
+ status = "okay";
+};
+
+&usdhc3 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc3>;
+ pinctrl-1 = <&pinctrl_usdhc3_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc3_200mhz>;
+ assigned-clocks = <&clks IMX7D_USDHC3_ROOT_CLK>;
+ assigned-clock-rates = <400000000>;
+ bus-width = <8>;
+ no-sd;
+ no-sdio;
+ disable-wp;
+ fsl,tuning-step = <2>;
+ non-removable;
+ vmmc-supply = <®_ldo_emmc_3v3>;
+ vqmmc-supply = <®_dcdc_1v8>;
+ status = "okay";
+};
--
2.26.2
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH 2/3] dt-bindings: Add vendor prefix for IoTmaxx GmbH
From: Steffen Trumtrar @ 2020-05-28 9:31 UTC (permalink / raw)
To: Shawn Guo, Rob Herring
Cc: linux-arm-kernel, Fabio Estevam, NXP Linux Team,
Pengutronix Kernel Team
In-Reply-To: <20200528093115.28268-1-s.trumtrar@pengutronix.de>
IoTmaxx GmbH is a developer of IoT solutions. The website is
https://www.iotmaxx.com/
Signed-off-by: Steffen Trumtrar <s.trumtrar@pengutronix.de>
---
Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index d3891386d671..4ab5bac4bc9d 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -481,6 +481,8 @@ patternProperties:
description: Inverse Path
"^iom,.*":
description: Iomega Corporation
+ "^iotmaxx,.*":
+ description: IoTmaxx GmbH
"^isee,.*":
description: ISEE 2007 S.L.
"^isil,.*":
--
2.26.2
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH 1/3] ARM: imx7d: add enet2 clk sel
From: Steffen Trumtrar @ 2020-05-28 9:31 UTC (permalink / raw)
To: Shawn Guo, Rob Herring
Cc: linux-arm-kernel, Fabio Estevam, NXP Linux Team,
Pengutronix Kernel Team
Add clock source init for the second ethernet port.
This changes the clock direction and clock selection in a way that the
ethernet phy reference clock is routed as an output.
Signed-off-by: Steffen Trumtrar <s.trumtrar@pengutronix.de>
---
I know, that this is not a "good solution", but I don't know how we can
handle this in a better way. Open for suggestions.
arch/arm/mach-imx/mach-imx7d.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/arch/arm/mach-imx/mach-imx7d.c b/arch/arm/mach-imx/mach-imx7d.c
index ebb27592a9f7..2f9c0151d5be 100644
--- a/arch/arm/mach-imx/mach-imx7d.c
+++ b/arch/arm/mach-imx/mach-imx7d.c
@@ -65,6 +65,9 @@ static void __init imx7d_enet_clk_sel(void)
if (!IS_ERR(gpr)) {
regmap_update_bits(gpr, IOMUXC_GPR1, IMX7D_GPR1_ENET_TX_CLK_SEL_MASK, 0);
regmap_update_bits(gpr, IOMUXC_GPR1, IMX7D_GPR1_ENET_CLK_DIR_MASK, 0);
+ regmap_update_bits(gpr, IOMUXC_GPR1, IMX7D_GPR1_ENET2_TX_CLK_SEL_MASK, 0);
+ regmap_update_bits(gpr, IOMUXC_GPR1, IMX7D_GPR1_ENET2_CLK_DIR_MASK,
+ IMX7D_GPR1_ENET2_CLK_DIR_MASK);
} else {
pr_err("failed to find fsl,imx7d-iomux-gpr regmap\n");
}
--
2.26.2
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* Re: [PATCH v10 3/3] configs: defconfig: Add CONFIG_KEYBOARD_MTK_KPD=m
From: Marco Felsch @ 2020-05-28 9:26 UTC (permalink / raw)
To: Fengping Yu
Cc: Dmitry Torokhov, linux-mediatek, linux-input, Yingjoe Chen,
Andy Shevchenko, linux-arm-kernel
In-Reply-To: <20200528084143.36482-4-fengping.yu@mediatek.com>
On 20-05-28 16:41, Fengping Yu wrote:
> From: "fengping.yu" <fengping.yu@mediatek.com>
>
> Add Mediatek matrix keypad support in defconfig.
>
> Signed-off-by: fengping.yu <fengping.yu@mediatek.com>
Reviewed-by: Marco Felsch <m.felsch@pengutronix.de>
> ---
> arch/arm64/configs/defconfig | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
> index 24e534d85045..112ced090b21 100644
> --- a/arch/arm64/configs/defconfig
> +++ b/arch/arm64/configs/defconfig
> @@ -349,6 +349,7 @@ CONFIG_KEYBOARD_GPIO=y
> CONFIG_KEYBOARD_SNVS_PWRKEY=m
> CONFIG_KEYBOARD_IMX_SC_KEY=m
> CONFIG_KEYBOARD_CROS_EC=y
> +CONFIG_KEYBOARD_MTK_KPD=m
> CONFIG_INPUT_TOUCHSCREEN=y
> CONFIG_TOUCHSCREEN_ATMEL_MXT=m
> CONFIG_INPUT_MISC=y
> --
> 2.18.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v10 2/3] drivers: input: keyboard: Add mtk keypad driver
From: Marco Felsch @ 2020-05-28 9:26 UTC (permalink / raw)
To: Fengping Yu
Cc: Dmitry Torokhov, linux-mediatek, linux-input, Yingjoe Chen,
Andy Shevchenko, linux-arm-kernel
In-Reply-To: <20200528084143.36482-3-fengping.yu@mediatek.com>
On 20-05-28 16:41, Fengping Yu wrote:
> From: "fengping.yu" <fengping.yu@mediatek.com>
>
> This adds matrix keypad support for Mediatek SoCs.
>
> Signed-off-by: fengping.yu <fengping.yu@mediatek.com>
Reviewed-by: Marco Felsch <m.felsch@pengutronix.de>
> ---
> drivers/input/keyboard/Kconfig | 11 ++
> drivers/input/keyboard/Makefile | 1 +
> drivers/input/keyboard/mtk-kpd.c | 206 +++++++++++++++++++++++++++++++
> 3 files changed, 218 insertions(+)
> create mode 100644 drivers/input/keyboard/mtk-kpd.c
>
> diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
> index 28de965a08d5..c55230c4c344 100644
> --- a/drivers/input/keyboard/Kconfig
> +++ b/drivers/input/keyboard/Kconfig
> @@ -782,6 +782,17 @@ config KEYBOARD_BCM
> To compile this driver as a module, choose M here: the
> module will be called bcm-keypad.
>
> +config KEYBOARD_MTK_KPD
> + tristate "MediaTek Keypad Support"
> + depends on ARCH_MEDIATEK || COMPILE_TEST
> + select CONFIG_REGMAP_MMIO
> + select INPUT_MATRIXKMAP
> + help
> + Say Y here if you want to use the keypad on MediaTek SoCs.
> + If unsure, say N.
> + To compile this driver as a module, choose M here: the
> + module will be called mtk-kpd.
> +
> config KEYBOARD_MTK_PMIC
> tristate "MediaTek PMIC keys support"
> depends on MFD_MT6397
> diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile
> index 1d689fdd5c00..6c9d852c377e 100644
> --- a/drivers/input/keyboard/Makefile
> +++ b/drivers/input/keyboard/Makefile
> @@ -43,6 +43,7 @@ obj-$(CONFIG_KEYBOARD_MATRIX) += matrix_keypad.o
> obj-$(CONFIG_KEYBOARD_MAX7359) += max7359_keypad.o
> obj-$(CONFIG_KEYBOARD_MCS) += mcs_touchkey.o
> obj-$(CONFIG_KEYBOARD_MPR121) += mpr121_touchkey.o
> +obj-$(CONFIG_KEYBOARD_MTK_KPD) += mtk-kpd.o
> obj-$(CONFIG_KEYBOARD_MTK_PMIC) += mtk-pmic-keys.o
> obj-$(CONFIG_KEYBOARD_NEWTON) += newtonkbd.o
> obj-$(CONFIG_KEYBOARD_NOMADIK) += nomadik-ske-keypad.o
> diff --git a/drivers/input/keyboard/mtk-kpd.c b/drivers/input/keyboard/mtk-kpd.c
> new file mode 100644
> index 000000000000..2900487c8f60
> --- /dev/null
> +++ b/drivers/input/keyboard/mtk-kpd.c
> @@ -0,0 +1,206 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2019 MediaTek Inc.
> + * Author Terry Chang <terry.chang@mediatek.com>
> + */
> +#include <linux/bitops.h>
> +#include <linux/clk.h>
> +#include <linux/input/matrix_keypad.h>
> +#include <linux/interrupt.h>
> +#include <linux/module.h>
> +#include <linux/property.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +
> +#define MTK_KPD_NAME "mtk-kpd"
> +#define MTK_KPD_MEM 0x0004
> +#define MTK_KPD_DEBOUNCE 0x0018
> +#define MTK_KPD_DEBOUNCE_MASK GENMASK(13, 0)
> +#define MTK_KPD_DEBOUNCE_MAX_US 256000
> +#define MTK_KPD_NUM_MEMS 5
> +#define MTK_KPD_NUM_BITS 136 /* 4*32+8 MEM5 only use 8 BITS */
> +
> +struct mtk_keypad {
> + struct regmap *regmap;
> + struct input_dev *input_dev;
> + struct clk *clk;
> + void __iomem *base;
> + u32 n_rows;
> + u32 n_cols;
> + DECLARE_BITMAP(keymap_state, MTK_KPD_NUM_BITS);
> +};
> +
> +static const struct regmap_config keypad_regmap_cfg = {
> + .reg_bits = 32,
> + .val_bits = 32,
> + .reg_stride = sizeof(u32),
> + .max_register = 36,
> +};
> +
> +static irqreturn_t kpd_irq_handler(int irq, void *dev_id)
> +{
> + struct mtk_keypad *keypad = dev_id;
> + unsigned short *keycode = keypad->input_dev->keycode;
> + DECLARE_BITMAP(new_state, MTK_KPD_NUM_BITS);
> + DECLARE_BITMAP(change, MTK_KPD_NUM_BITS);
> + int bit_nr;
> + int pressed;
> + unsigned short code;
> +
> + regmap_raw_read(keypad->regmap, MTK_KPD_MEM,
> + new_state, MTK_KPD_NUM_MEMS);
> +
> + bitmap_xor(change, new_state, keypad->keymap_state, MTK_KPD_NUM_BITS);
> +
> + for_each_set_bit(bit_nr, change, MTK_KPD_NUM_BITS) {
> + /* 1: not pressed, 0: pressed */
> + pressed = !test_bit(bit_nr, new_state);
> + dev_dbg(&keypad->input_dev->dev, "%s",
> + pressed ? "pressed" : "released");
> +
> + /* 32bit register only use low 16bit as keypad mem register */
> + code = keycode[bit_nr - 16 * (BITS_TO_U32(bit_nr) - 1)];
> +
> + input_report_key(keypad->input_dev, code, pressed);
> + input_sync(keypad->input_dev);
> +
> + dev_dbg(&keypad->input_dev->dev,
> + "report Linux keycode = %d\n", code);
> + }
> +
> + bitmap_copy(keypad->keymap_state, new_state, MTK_KPD_NUM_BITS);
> +
> + return IRQ_HANDLED;
> +}
> +
> +static void kpd_clk_disable(void *data)
> +{
> + clk_disable_unprepare(data);
> +}
> +
> +static int kpd_pdrv_probe(struct platform_device *pdev)
> +{
> + struct mtk_keypad *keypad;
> + unsigned int irq;
> + u32 debounce;
> + bool wakeup;
> + int ret;
> +
> + keypad = devm_kzalloc(&pdev->dev, sizeof(*keypad), GFP_KERNEL);
> + if (!keypad)
> + return -ENOMEM;
> +
> + keypad->base = devm_platform_ioremap_resource(pdev, 0);
> + if (IS_ERR(keypad->base))
> + return PTR_ERR(keypad->base);
> +
> + keypad->regmap = devm_regmap_init_mmio(&pdev->dev,
> + keypad->base,
> + &keypad_regmap_cfg);
> + if (IS_ERR(keypad->regmap)) {
> + dev_err(&pdev->dev,
> + "regmap init failed:%ld\n", PTR_ERR(keypad->regmap));
> + return PTR_ERR(keypad->regmap);
> + }
> +
> + bitmap_fill(keypad->keymap_state, MTK_KPD_NUM_BITS);
> +
> + keypad->input_dev = devm_input_allocate_device(&pdev->dev);
> + if (!keypad->input_dev) {
> + dev_err(&pdev->dev, "Failed to allocate input dev\n");
> + return -ENOMEM;
> + }
> +
> + keypad->input_dev->name = MTK_KPD_NAME;
> + keypad->input_dev->id.bustype = BUS_HOST;
> +
> + ret = matrix_keypad_parse_properties(&pdev->dev, &keypad->n_rows,
> + &keypad->n_cols);
> + if (ret) {
> + dev_err(&pdev->dev, "Failed to parse keypad params\n");
> + return ret;
> + }
> +
> + if (device_property_read_u32(&pdev->dev, "mediatek,debounce-us",
> + &debounce))
> + debounce = 16000;
> +
> + if (debounce > MTK_KPD_DEBOUNCE_MAX_US) {
> + dev_err(&pdev->dev, "Debounce time exceeds the maximum allowed time %dus\n",
> + MTK_KPD_DEBOUNCE_MAX_US);
> + return -EINVAL;
> + }
> +
> + wakeup = device_property_read_bool(&pdev->dev, "wakeup-source");
> +
> + dev_dbg(&pdev->dev, "n_row=%d n_col=%d debounce=%d\n",
> + keypad->n_rows, keypad->n_cols, debounce);
> +
> + ret = matrix_keypad_build_keymap(NULL, NULL,
> + keypad->n_rows,
> + keypad->n_cols,
> + NULL,
> + keypad->input_dev);
> + if (ret) {
> + dev_err(&pdev->dev, "Failed to build keymap\n");
> + return ret;
> + }
> +
> + regmap_write(keypad->regmap, MTK_KPD_DEBOUNCE,
> + debounce * 32 / 1000 & MTK_KPD_DEBOUNCE_MASK);
> +
> + keypad->clk = devm_clk_get(&pdev->dev, "kpd");
> + if (IS_ERR(keypad->clk))
> + return keypad->clk;
> +
> + ret = clk_prepare_enable(keypad->clk);
> + if (ret) {
> + dev_err(&pdev->dev, "cannot prepare/enable keypad clock\n");
> + return ret;
> + }
> +
> + ret = devm_add_action_or_reset(&pdev->dev, kpd_clk_disable,
> + keypad->clk);
> + if (ret)
> + return ret;
> +
> + irq = platform_get_irq(pdev, 0);
> + if (irq < 0)
> + return irq;
> +
> + ret = devm_request_threaded_irq(&pdev->dev, irq,
> + NULL, kpd_irq_handler, 0,
> + MTK_KPD_NAME, keypad);
> + if (ret) {
> + dev_err(&pdev->dev, "Failed to request IRQ#%d:%d\n",
> + irq, ret);
> + return ret;
> + }
> +
> + ret = input_register_device(keypad->input_dev);
> + if (ret) {
> + dev_err(&pdev->dev, "Failed to register device\n");
> + return ret;
> + }
> +
> + return device_init_wakeup(&pdev->dev, wakeup);
> +}
> +
> +static const struct of_device_id kpd_of_match[] = {
> + { .compatible = "mediatek,mt6779-keypad" },
> + { .compatible = "mediatek,mt6873-keypad" },
> + { /* sentinel */ }
> +};
> +
> +static struct platform_driver kpd_pdrv = {
> + .probe = kpd_pdrv_probe,
> + .driver = {
> + .name = MTK_KPD_NAME,
> + .of_match_table = kpd_of_match,
> + },
> +};
> +module_platform_driver(kpd_pdrv);
> +
> +MODULE_AUTHOR("Mediatek Corporation");
> +MODULE_DESCRIPTION("MTK Keypad (KPD) Driver");
> +MODULE_LICENSE("GPL");
> --
> 2.18.0
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v10 1/3] dt-bindings: Add keypad devicetree documentation
From: Marco Felsch @ 2020-05-28 9:24 UTC (permalink / raw)
To: Fengping Yu
Cc: Dmitry Torokhov, linux-mediatek, linux-input, Yingjoe Chen,
Andy Shevchenko, linux-arm-kernel
In-Reply-To: <20200528084143.36482-2-fengping.yu@mediatek.com>
On 20-05-28 16:41, Fengping Yu wrote:
> From: "fengping.yu" <fengping.yu@mediatek.com>
...
> + mediatek,debounce-us:
> + description: Debounce interval in microseconds
> + maximum: 256000
Nit, I would mention that 16000 is the default value which is applied if
not given.
Appart of this feel free to add my:
Reviewed-by: Marco Felsch <m.felsch@pengutronix.de>
Regards,
Marco
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox