Devicetree
 help / color / mirror / Atom feed
* Re: [PATCH 1/7] arm64: dts: imx8-ss-lsio: fix pwm lpcg indices
From: Frank Li @ 2024-04-02 15:09 UTC (permalink / raw)
  To: Fabio Estevam
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Shawn Guo,
	Sascha Hauer, Pengutronix Kernel Team, NXP Linux Team,
	Marcel Ziswiler, Philippe Schenker, Max Krummenacher,
	Alexander Stein, Joakim Zhang, devicetree, linux-arm-kernel,
	linux-kernel, stable
In-Reply-To: <CAOMZO5AJrQ5jyV4A-tvX93-R0_nEWpEO9YY3f5DpeXaAFO4cSA@mail.gmail.com>

On Mon, Apr 01, 2024 at 08:04:56PM -0300, Fabio Estevam wrote:
> On Mon, Apr 1, 2024 at 7:25 PM Frank Li <Frank.Li@nxp.com> wrote:
> >
> > lpcg's arg0 should use clock indices instead of index.
> >
> > pwm0_lpcg: clock-controller@5d400000 {
> >         ...                                                // Col1  Col2
> >         clocks = <&clk IMX_SC_R_PWM_0 IMX_SC_PM_CLK_PER>,  // 0     0
> >                  <&clk IMX_SC_R_PWM_0 IMX_SC_PM_CLK_PER>,  // 1     1
> >                  <&clk IMX_SC_R_PWM_0 IMX_SC_PM_CLK_PER>,  // 2     4
> >                  <&lsio_bus_clk>,                          // 3     5
> >                  <&clk IMX_SC_R_PWM_0 IMX_SC_PM_CLK_PER>;  // 4     6
> >         clock-indices = <IMX_LPCG_CLK_0>, <IMX_LPCG_CLK_1>,
> >                         <IMX_LPCG_CLK_4>, <IMX_LPCG_CLK_5>,
> >                         <IMX_LPCG_CLK_6>;
> > };
> >
> > Col1: index, which exited dts try to get.
> 
> I cannot understand this sentence, sorry.

This base on downstream dts code.  Downstream code use index in 'Col1' to
get clock.

For example:
<&pwm0_lpcg 3> means &lsio_bus_clk.

When someone do upstream, miss understand or omit upsteam lpcg driver's
difference between downstream and upstream version. And it also work even
index is wrong.

I realize this problem when I try to enable audio device for qm. The
difference cause audio can't work.  The grep lpcg [0-9] to find this
problem.

> 
> > Col2: actual index in lpcg driver.
> 
> You should not describe DT in terms of Linux driver.

It just descript the actual hehavior in current drivers to explain why it
can work even arg0 is wrong.


for example: <&pwm0_lpcg 4>, developer intent to get 
	<&clk IMX_SC_R_PWM_0 IMX_SC_PM_CLK_PER>;  // 4     6

but lpcg driver device device arg0 (4) by 4, get 1. So below clock return
	<&clk IMX_SC_R_PWM_0 IMX_SC_PM_CLK_PER>,  // 1     1 

Both it is IMX_SC_PM_CLK_PER, so pwm works luckly.

But correct code should be <&pwm0_lpcg IMX_LPCG_CLK_6>. 


Frank

^ permalink raw reply

* Re: [RFC PATCH v2 1/5] clk: meson: axg: move reset controller's code to separate module
From: Jerome Brunet @ 2024-04-02 14:52 UTC (permalink / raw)
  To: Jan Dakinevich, Stephen Boyd, Philipp Zabel
  Cc: Neil Armstrong, Jerome Brunet, Michael Turquette, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Kevin Hilman,
	Martin Blumenstingl, linux-amlogic, linux-clk, devicetree,
	linux-kernel, linux-arm-kernel
In-Reply-To: <20240328010831.884487-2-jan.dakinevich@salutedevices.com>


On Thu 28 Mar 2024 at 04:08, Jan Dakinevich <jan.dakinevich@salutedevices.com> wrote:

> This code will by reused by A1 SoC.

Could expand a bit please ?

>
> Signed-off-by: Jan Dakinevich <jan.dakinevich@salutedevices.com>

In general, I like the idea.

We do have a couple a reset registers lost in middle of clocks and this
change makes it possible to re-use the code instead duplicating it.

The exported function would be used by audio clock controllers, but the
module created would be purely about reset.

One may wonder how it ended up in the clock tree, especially since the
kernel as a reset tree too.

I'm not sure if this should move to the reset framework or if it would
be an unnecessary churn. Stephen, Philipp, do you have an opinion on
this ?

> ---
>  drivers/clk/meson/Kconfig            |   5 ++
>  drivers/clk/meson/Makefile           |   1 +
>  drivers/clk/meson/axg-audio.c        |  95 +----------------------
>  drivers/clk/meson/meson-audio-rstc.c | 109 +++++++++++++++++++++++++++
>  drivers/clk/meson/meson-audio-rstc.h |  12 +++
>  5 files changed, 130 insertions(+), 92 deletions(-)
>  create mode 100644 drivers/clk/meson/meson-audio-rstc.c
>  create mode 100644 drivers/clk/meson/meson-audio-rstc.h
>
> diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
> index 29ffd14d267b..d6a2fa5f7e88 100644
> --- a/drivers/clk/meson/Kconfig
> +++ b/drivers/clk/meson/Kconfig
> @@ -48,6 +48,10 @@ config COMMON_CLK_MESON_CPU_DYNDIV
>  	tristate
>  	select COMMON_CLK_MESON_REGMAP
>  
> +config COMMON_CLK_MESON_AUDIO_RSTC
> +	tristate
> +	select RESET_CONTROLLER
> +
>  config COMMON_CLK_MESON8B
>  	bool "Meson8 SoC Clock controller support"
>  	depends on ARM
> @@ -101,6 +105,7 @@ config COMMON_CLK_AXG_AUDIO
>  	select COMMON_CLK_MESON_PHASE
>  	select COMMON_CLK_MESON_SCLK_DIV
>  	select COMMON_CLK_MESON_CLKC_UTILS
> +	select COMMON_CLK_MESON_AUDIO_RSTC
>  	select REGMAP_MMIO
>  	help
>  	  Support for the audio clock controller on AmLogic A113D devices,
> diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
> index 9ee4b954c896..88d94921a4dc 100644
> --- a/drivers/clk/meson/Makefile
> +++ b/drivers/clk/meson/Makefile
> @@ -12,6 +12,7 @@ obj-$(CONFIG_COMMON_CLK_MESON_PLL) += clk-pll.o
>  obj-$(CONFIG_COMMON_CLK_MESON_REGMAP) += clk-regmap.o
>  obj-$(CONFIG_COMMON_CLK_MESON_SCLK_DIV) += sclk-div.o
>  obj-$(CONFIG_COMMON_CLK_MESON_VID_PLL_DIV) += vid-pll-div.o
> +obj-$(CONFIG_COMMON_CLK_MESON_AUDIO_RSTC) += meson-audio-rstc.o
>  
>  # Amlogic Clock controllers
>  
> diff --git a/drivers/clk/meson/axg-audio.c b/drivers/clk/meson/axg-audio.c
> index ac3482960903..990203a7ad5c 100644
> --- a/drivers/clk/meson/axg-audio.c
> +++ b/drivers/clk/meson/axg-audio.c
> @@ -12,10 +12,10 @@
>  #include <linux/platform_device.h>
>  #include <linux/regmap.h>
>  #include <linux/reset.h>
> -#include <linux/reset-controller.h>
>  #include <linux/slab.h>
>  
>  #include "meson-clkc-utils.h"
> +#include "meson-audio-rstc.h"
>  #include "axg-audio.h"
>  #include "clk-regmap.h"
>  #include "clk-phase.h"
> @@ -1648,84 +1648,6 @@ static struct clk_regmap *const sm1_clk_regmaps[] = {
>  	&sm1_sysclk_b_en,
>  };
>  
> -struct axg_audio_reset_data {
> -	struct reset_controller_dev rstc;
> -	struct regmap *map;
> -	unsigned int offset;
> -};
> -
> -static void axg_audio_reset_reg_and_bit(struct axg_audio_reset_data *rst,
> -					unsigned long id,
> -					unsigned int *reg,
> -					unsigned int *bit)
> -{
> -	unsigned int stride = regmap_get_reg_stride(rst->map);
> -
> -	*reg = (id / (stride * BITS_PER_BYTE)) * stride;
> -	*reg += rst->offset;
> -	*bit = id % (stride * BITS_PER_BYTE);
> -}
> -
> -static int axg_audio_reset_update(struct reset_controller_dev *rcdev,
> -				unsigned long id, bool assert)
> -{
> -	struct axg_audio_reset_data *rst =
> -		container_of(rcdev, struct axg_audio_reset_data, rstc);
> -	unsigned int offset, bit;
> -
> -	axg_audio_reset_reg_and_bit(rst, id, &offset, &bit);
> -
> -	regmap_update_bits(rst->map, offset, BIT(bit),
> -			assert ? BIT(bit) : 0);
> -
> -	return 0;
> -}
> -
> -static int axg_audio_reset_status(struct reset_controller_dev *rcdev,
> -				unsigned long id)
> -{
> -	struct axg_audio_reset_data *rst =
> -		container_of(rcdev, struct axg_audio_reset_data, rstc);
> -	unsigned int val, offset, bit;
> -
> -	axg_audio_reset_reg_and_bit(rst, id, &offset, &bit);
> -
> -	regmap_read(rst->map, offset, &val);
> -
> -	return !!(val & BIT(bit));
> -}
> -
> -static int axg_audio_reset_assert(struct reset_controller_dev *rcdev,
> -				unsigned long id)
> -{
> -	return axg_audio_reset_update(rcdev, id, true);
> -}
> -
> -static int axg_audio_reset_deassert(struct reset_controller_dev *rcdev,
> -				unsigned long id)
> -{
> -	return axg_audio_reset_update(rcdev, id, false);
> -}
> -
> -static int axg_audio_reset_toggle(struct reset_controller_dev *rcdev,
> -				unsigned long id)
> -{
> -	int ret;
> -
> -	ret = axg_audio_reset_assert(rcdev, id);
> -	if (ret)
> -		return ret;
> -
> -	return axg_audio_reset_deassert(rcdev, id);
> -}
> -
> -static const struct reset_control_ops axg_audio_rstc_ops = {
> -	.assert = axg_audio_reset_assert,
> -	.deassert = axg_audio_reset_deassert,
> -	.reset = axg_audio_reset_toggle,
> -	.status = axg_audio_reset_status,
> -};
> -
>  static const struct regmap_config axg_audio_regmap_cfg = {
>  	.reg_bits	= 32,
>  	.val_bits	= 32,
> @@ -1745,7 +1667,6 @@ static int axg_audio_clkc_probe(struct platform_device *pdev)
>  {
>  	struct device *dev = &pdev->dev;
>  	const struct audioclk_data *data;
> -	struct axg_audio_reset_data *rst;
>  	struct regmap *map;
>  	void __iomem *regs;
>  	struct clk_hw *hw;
> @@ -1807,18 +1728,8 @@ static int axg_audio_clkc_probe(struct platform_device *pdev)
>  	if (!data->reset_num)
>  		return 0;
>  
> -	rst = devm_kzalloc(dev, sizeof(*rst), GFP_KERNEL);
> -	if (!rst)
> -		return -ENOMEM;
> -
> -	rst->map = map;
> -	rst->offset = data->reset_offset;
> -	rst->rstc.nr_resets = data->reset_num;
> -	rst->rstc.ops = &axg_audio_rstc_ops;
> -	rst->rstc.of_node = dev->of_node;
> -	rst->rstc.owner = THIS_MODULE;
> -
> -	return devm_reset_controller_register(dev, &rst->rstc);
> +	return meson_audio_rstc_register(dev, map, data->reset_offset,
> +					 data->reset_num);
>  }
>  
>  static const struct audioclk_data axg_audioclk_data = {
> diff --git a/drivers/clk/meson/meson-audio-rstc.c b/drivers/clk/meson/meson-audio-rstc.c
> new file mode 100644
> index 000000000000..2079d24c40f4
> --- /dev/null
> +++ b/drivers/clk/meson/meson-audio-rstc.c
> @@ -0,0 +1,109 @@
> +// SPDX-License-Identifier: (GPL-2.0 OR MIT)
> +/*
> + * Copyright (c) 2018 BayLibre, SAS.
> + * Author: Jerome Brunet <jbrunet@baylibre.com>
> + */
> +
> +#include <linux/reset-controller.h>
> +
> +#include "meson-audio-rstc.h"
> +
> +struct meson_audio_reset_data {
> +	struct reset_controller_dev rstc;
> +	struct regmap *map;
> +	unsigned int offset;
> +};
> +
> +static void meson_audio_reset_reg_and_bit(struct meson_audio_reset_data *rst,
> +					  unsigned long id,
> +					  unsigned int *reg,
> +					  unsigned int *bit)
> +{
> +	unsigned int stride = regmap_get_reg_stride(rst->map);
> +
> +	*reg = (id / (stride * BITS_PER_BYTE)) * stride;
> +	*reg += rst->offset;
> +	*bit = id % (stride * BITS_PER_BYTE);
> +}
> +
> +static int meson_audio_reset_update(struct reset_controller_dev *rcdev,
> +				    unsigned long id, bool assert)
> +{
> +	struct meson_audio_reset_data *rst =
> +		container_of(rcdev, struct meson_audio_reset_data, rstc);
> +	unsigned int offset, bit;
> +
> +	meson_audio_reset_reg_and_bit(rst, id, &offset, &bit);
> +
> +	regmap_update_bits(rst->map, offset, BIT(bit),
> +			assert ? BIT(bit) : 0);
> +
> +	return 0;
> +}
> +
> +static int meson_audio_reset_status(struct reset_controller_dev *rcdev,
> +				    unsigned long id)
> +{
> +	struct meson_audio_reset_data *rst =
> +		container_of(rcdev, struct meson_audio_reset_data, rstc);
> +	unsigned int val, offset, bit;
> +
> +	meson_audio_reset_reg_and_bit(rst, id, &offset, &bit);
> +
> +	regmap_read(rst->map, offset, &val);
> +
> +	return !!(val & BIT(bit));
> +}
> +
> +static int meson_audio_reset_assert(struct reset_controller_dev *rcdev,
> +				    unsigned long id)
> +{
> +	return meson_audio_reset_update(rcdev, id, true);
> +}
> +
> +static int meson_audio_reset_deassert(struct reset_controller_dev *rcdev,
> +				      unsigned long id)
> +{
> +	return meson_audio_reset_update(rcdev, id, false);
> +}
> +
> +static int meson_audio_reset_toggle(struct reset_controller_dev *rcdev,
> +				    unsigned long id)
> +{
> +	int ret;
> +
> +	ret = meson_audio_reset_assert(rcdev, id);
> +	if (ret)
> +		return ret;
> +
> +	return meson_audio_reset_deassert(rcdev, id);
> +}
> +
> +static const struct reset_control_ops meson_audio_rstc_ops = {
> +	.assert = meson_audio_reset_assert,
> +	.deassert = meson_audio_reset_deassert,
> +	.reset = meson_audio_reset_toggle,
> +	.status = meson_audio_reset_status,
> +};
> +
> +int meson_audio_rstc_register(struct device *dev, struct regmap *map,
> +			      unsigned int offset, unsigned int num)
> +{
> +	struct meson_audio_reset_data *rst;
> +
> +	rst = devm_kzalloc(dev, sizeof(*rst), GFP_KERNEL);
> +	if (!rst)
> +		return -ENOMEM;
> +
> +	rst->map = map;
> +	rst->offset = offset;
> +	rst->rstc.nr_resets = num;
> +	rst->rstc.ops = &meson_audio_rstc_ops;
> +	rst->rstc.of_node = dev->of_node;
> +	rst->rstc.owner = THIS_MODULE;
> +
> +	return devm_reset_controller_register(dev, &rst->rstc);
> +}
> +EXPORT_SYMBOL_GPL(meson_audio_rstc_register);
> +
> +MODULE_LICENSE("GPL v2");
> diff --git a/drivers/clk/meson/meson-audio-rstc.h b/drivers/clk/meson/meson-audio-rstc.h
> new file mode 100644
> index 000000000000..6b441549de03
> --- /dev/null
> +++ b/drivers/clk/meson/meson-audio-rstc.h
> @@ -0,0 +1,12 @@
> +/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */
> +
> +#ifndef __MESON_AUDIO_RSTC_H
> +#define __MESON_AUDIO_RSTC_H
> +
> +#include <linux/device.h>
> +#include <linux/regmap.h>
> +
> +int meson_audio_rstc_register(struct device *dev, struct regmap *map,
> +			      unsigned int offset, unsigned int num);
> +
> +#endif /* __MESON_AUDIO_RSTC_H */


-- 
Jerome

^ permalink raw reply

* Re: [PATCH v1 2/6] clk: meson: a1: pll: support 'syspll' general-purpose PLL for CPU clock
From: Dmitry Rokosov @ 2024-04-02 15:00 UTC (permalink / raw)
  To: Jerome Brunet
  Cc: neil.armstrong, mturquette, sboyd, robh+dt,
	krzysztof.kozlowski+dt, khilman, martin.blumenstingl, kernel,
	rockosov, linux-amlogic, linux-clk, devicetree, linux-kernel,
	linux-arm-kernel
In-Reply-To: <1jmsqbj0md.fsf@starbuckisacylon.baylibre.com>

On Tue, Apr 02, 2024 at 04:27:17PM +0200, Jerome Brunet wrote:
> 
> On Tue 02 Apr 2024 at 15:15, Dmitry Rokosov <ddrokosov@salutedevices.com> wrote:
> 
> > On Tue, Apr 02, 2024 at 11:00:42AM +0200, Jerome Brunet wrote:
> >> 
> >> On Fri 29 Mar 2024 at 23:58, Dmitry Rokosov <ddrokosov@salutedevices.com> wrote:
> >> 
> >> > The 'syspll' PLL, also known as the system PLL, is a general and
> >> > essential PLL responsible for generating the CPU clock frequency.
> >> > With its wide-ranging capabilities, it is designed to accommodate
> >> > frequencies within the range of 768MHz to 1536MHz.
> >> >
> >> > Signed-off-by: Dmitry Rokosov <ddrokosov@salutedevices.com>
> >> > ---
> >> >  drivers/clk/meson/a1-pll.c | 78 ++++++++++++++++++++++++++++++++++++++
> >> >  drivers/clk/meson/a1-pll.h |  6 +++
> >> >  2 files changed, 84 insertions(+)
> >> >
> >> > diff --git a/drivers/clk/meson/a1-pll.c b/drivers/clk/meson/a1-pll.c
> >> > index 60b2e53e7e51..02fd2d325cc6 100644
> >> > --- a/drivers/clk/meson/a1-pll.c
> >> > +++ b/drivers/clk/meson/a1-pll.c
> >> > @@ -138,6 +138,81 @@ static struct clk_regmap hifi_pll = {
> >> >  	},
> >> >  };
> >> >  
> >> > +static const struct pll_mult_range sys_pll_mult_range = {
> >> > +	.min = 32,
> >> > +	.max = 64,
> >> > +};
> >> > +
> >> > +/*
> >> > + * We assume that the sys_pll_clk has already been set up by the low-level
> >> > + * bootloaders as the main CPU PLL source. Therefore, it is not necessary to
> >> > + * run the initialization sequence.
> >> > + */
> >> 
> >> I see no reason to make such assumption.
> >> This clock is no read-only, it apparently is able to re-lock so assuming
> >> anything from the bootloader is just asking from trouble
> >> 
> >
> > Indeed, I have implemented the following initialization sequence. I have
> > dumped the bootloader setup and included it in the definition of my
> > sys_pll. However, I have encountered an issue with the enable bit. If I
> > leave the enable bit switched on by default, there is a possibility that
> > the bootloader selects a fixed CPU clock while the sys_pll should be
> > switched off. On the other hand, if I keep the enable bit switched off
> > by default, the bootloader might configure the CPU clock to use sys_pll,
> > resulting in the execution halting when the initialization sequence is
> > run. This situation has led me to assume that we should place our trust
> > in the bootloader setup.
> >
> > If you believe it is necessary to include the initialization sequence, I
> > can prepare it with the sys_pll enabled by default.
> 
> I just noted your initial comment is misleading.
> 
> You could submit a patch to apply the init sequence only if the PLL is
> not already enabled. Maybe even condition that to flag in the pll data
> to avoid applying it to the other platforms for now.
> 

Ah, I see. Okay, no problem, I will prepare such patch to common meson
clk-pll.

[...]

-- 
Thank you,
Dmitry

^ permalink raw reply

* Re: [PATCH v7 2/2] dmaengine: Loongson1: Add Loongson-1 APB DMA driver
From: Huacai Chen @ 2024-04-02 14:50 UTC (permalink / raw)
  To: Keguang Zhang
  Cc: Vinod Koul, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	linux-mips, dmaengine, devicetree, linux-kernel
In-Reply-To: <CAJhJPsWNuFMPEgDGsjdUdE1gYO3eVWLQ0QbYMXRTaMHv5bz9Ug@mail.gmail.com>

On Tue, Apr 2, 2024 at 6:51 PM Keguang Zhang <keguang.zhang@gmail.com> wrote:
>
> On Tue, Apr 2, 2024 at 5:04 PM Huacai Chen <chenhuacai@kernel.org> wrote:
> >
> > On Tue, Apr 2, 2024 at 9:56 AM Keguang Zhang <keguang.zhang@gmail.com> wrote:
> > >
> > > On Mon, Apr 1, 2024 at 9:24 PM Huacai Chen <chenhuacai@kernel.org> wrote:
> > > >
> > > > On Mon, Apr 1, 2024 at 7:10 PM Keguang Zhang <keguang.zhang@gmail.com> wrote:
> > > > >
> > > > > On Mon, Apr 1, 2024 at 5:06 PM Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > > >
> > > > > > On Mon, Apr 1, 2024 at 10:45 AM Keguang Zhang <keguang.zhang@gmail.com> wrote:
> > > > > > >
> > > > > > > Hi Huacai,
> > > > > > >
> > > > > > > On Sat, Mar 30, 2024 at 9:59 PM Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > > > > >
> > > > > > > > Hi, Keguang,
> > > > > > > >
> > > > > > > > On Fri, Mar 29, 2024 at 7:28 PM Keguang Zhang via B4 Relay
> > > > > > > > <devnull+keguang.zhang.gmail.com@kernel.org> wrote:
> > > > > > > > >
> > > > > > > > > From: Keguang Zhang <keguang.zhang@gmail.com>
> > > > > > > > >
> > > > > > > > > This patch adds APB DMA driver for Loongson-1 SoCs.
> > > > > > > > >
> > > > > > > > > Signed-off-by: Keguang Zhang <keguang.zhang@gmail.com>
> > > > > > > > > ---
> > > > > > > > > Changes in v7:
> > > > > > > > > - Change the comptible to 'loongson,ls1*-apbdma'
> > > > > > > > > - Update Kconfig and Makefile accordingly
> > > > > > > > > - Rename the file to loongson1-apb-dma.c to keep the consistency
> > > > > > > > >
> > > > > > > > > Changes in v6:
> > > > > > > > > - Implement .device_prep_dma_cyclic for Loongson1 audio driver,
> > > > > > > > > - as well as .device_pause and .device_resume.
> > > > > > > > > - Set the limitation LS1X_DMA_MAX_DESC and put all descriptors
> > > > > > > > > - into one page to save memory
> > > > > > > > > - Move dma_pool_zalloc() into ls1x_dma_alloc_desc()
> > > > > > > > > - Drop dma_slave_config structure
> > > > > > > > > - Use .remove_new instead of .remove
> > > > > > > > > - Use KBUILD_MODNAME for the driver name
> > > > > > > > > - Improve the debug information
> > > > > > > > >
> > > > > > > > > Changes in v5:
> > > > > > > > > - Add DT support
> > > > > > > > > - Use DT data instead of platform data
> > > > > > > > > - Use chan_id of struct dma_chan instead of own id
> > > > > > > > > - Use of_dma_xlate_by_chan_id() instead of ls1x_dma_filter()
> > > > > > > > > - Update the author information to my official name
> > > > > > > > >
> > > > > > > > > Changes in v4:
> > > > > > > > > - Use dma_slave_map to find the proper channel.
> > > > > > > > > - Explicitly call devm_request_irq() and tasklet_kill().
> > > > > > > > > - Fix namespace issue.
> > > > > > > > > - Some minor fixes and cleanups.
> > > > > > > > >
> > > > > > > > > Changes in v3:
> > > > > > > > > - Rename ls1x_dma_filter_fn to ls1x_dma_filter.
> > > > > > > > >
> > > > > > > > > Changes in v2:
> > > > > > > > > - Change the config from 'DMA_LOONGSON1' to 'LOONGSON1_DMA',
> > > > > > > > > - and rearrange it in alphabetical order in Kconfig and Makefile.
> > > > > > > > > - Fix comment style.
> > > > > > > > > ---
> > > > > > > > >  drivers/dma/Kconfig             |   9 +
> > > > > > > > >  drivers/dma/Makefile            |   1 +
> > > > > > > > >  drivers/dma/loongson1-apb-dma.c | 665 ++++++++++++++++++++++++++++++++++++++++
> > > > > > > > >  3 files changed, 675 insertions(+)
> > > > > > > > >
> > > > > > > > > diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
> > > > > > > > > index 002a5ec80620..f7b06c4cdf3f 100644
> > > > > > > > > --- a/drivers/dma/Kconfig
> > > > > > > > > +++ b/drivers/dma/Kconfig
> > > > > > > > > @@ -369,6 +369,15 @@ config K3_DMA
> > > > > > > > >           Support the DMA engine for Hisilicon K3 platform
> > > > > > > > >           devices.
> > > > > > > > >
> > > > > > > > > +config LOONGSON1_APB_DMA
> > > > > > > > > +       tristate "Loongson1 APB DMA support"
> > > > > > > > > +       depends on MACH_LOONGSON32 || COMPILE_TEST
> > > > > > > > > +       select DMA_ENGINE
> > > > > > > > > +       select DMA_VIRTUAL_CHANNELS
> > > > > > > > > +       help
> > > > > > > > > +         This selects support for the APB DMA controller in Loongson1 SoCs,
> > > > > > > > > +         which is required by Loongson1 NAND and audio support.
> > > > > > > > Why not rename to LS1X_APB_DMA and put it just before LS2X_APB_DMA
> > > > > > > > (and also the driver file name)?
> > > > > > > >
> > > > > > > So far all Kconfig entries of Loongson-1 drivers are named with the
> > > > > > > keyword "LOONGSON1".
> > > > > > > The same is true for these file names.
> > > > > > > Therefore, I need to keep the consistency.
> > > > > > But I see LS1X_IRQ in drivers/irqchip/Kconfig
> > > > > >
> > > > > Indeed, that's an exception, which was submitted by Jiaxun several years ago.
> > > > > Actually, most drivers of Loongson family use the keyword "LOONGSON"
> > > > > for Kconfig and "loongson" for filename.
> > > > > Thus I take this keywork as the naming convention.
> > > > But I think keeping consistency in a same subsystem is better than
> > > > keeping consistency in a same SoC (but cross subsystems).
> > > >
> > > In my opinion, "LS*X" is too short and may be confused with other SoCs.
> > > Meanwhile, there are only four drivers that use this keyword.
> > >   config I2C_LS2X
> > >   config LS2K_RESET
> > >   config LS2X_APB_DMA
> > >   config LS1X_IRQ
> > > Then, my suggestion is to change these "LS*X" to "LOONGSON*" to get a
> > > clear meaning.
> > We have made a naming conversion some years before with Jiaxun.
> > 1, Use "Loongson" for CPU in arch code;
> > 2, Use "LS7A" or something like this for bridges and devices.
> > 3, For drivers in SoC, if the driver is specific to Loongson-1, use
> > LS1X, if it is to Loongson-2, use LS2X, if it is shared by both
> > Loongson-1 and Loongson-2, use LOONGSON.
> >
> OK. But the doesn't the answer the question of confusion, such as
> "Freescale LS1021A".
> The same problem happens to the filenames.
>   ./drivers/gpu/drm/nouveau/nvkm/nvfw/ls.c
>   ./drivers/gpu/drm/nouveau/nvkm/subdev/acr/lsfw.c
>   ./drivers/gpu/drm/amd/amdgpu/lsdma_v6_0.c
>   ./drivers/gpu/drm/amd/amdgpu/lsdma_v7_0.c
>   ./arch/powerpc/platforms/embedded6xx/ls_uart.c
> Regarding "LS*X" itself, it contains the wildcard character "X" which
> itself is confusing.
> Therefore, I don't think "LS*X" is clear enough.
>
> On the other hand, I see "LOONGSON2_*" strings are still there.
> In addition, some of "LOONGSON_" definitions are not applicable for
> Loongson-1 at all, which breaks your convention.
>   config SND_SOC_LOONGSON_I2S_PCI  /* Loongson-1 doesn't support I2S */
>   config SND_SOC_LOONGSON_CARD
They are shared by LS2K and LS7A.

>   config DWMAC_LOONGSON1
>   config DWMAC_LOONGSON  /* This glue layer doesn't support Loongson-1 */
>   config COMMON_CLK_LOONGSON2
>   config RTC_DRV_LOONGSON
RTC is shared by LS2K and LS7A.

>   config SPI_LOONGSON_CORE
>   config SPI_LOONGSON_PCI  /* N/A for Loongson-1 */
>   config SPI_LOONGSON_PLATFORM
SPI is also shared by LS2K and LS7A.

>   config LOONGSON2_CPUFREQ
>   config DRM_LOONGSON  /* N/A for Loongson-1 */
DRM is also shared by LS2K and LS7A.

>   config LOONGSON1_WDT
>   config CLKSRC_LOONGSON1_PWM
>   config LOONGSON_LIOINTC  /* N/A for Loongson-1 */
>   config LOONGSON_EIOINTC  /* N/A for Loongson-1 */
>   config LOONGSON_HTPIC  /* N/A for Loongson-1 */
>   config LOONGSON_HTVEC  /* N/A for Loongson-1 */
>   config LOONGSON_PCH_PIC  /* N/A for Loongson-1 */
>   config LOONGSON_PCH_MSI  /* N/A for Loongson-1 */
>   config LOONGSON_PCH_LPC  /* N/A for Loongson-1 */
All interrupt controllers are shared by Loongson-2 and Loongson-3.

>   config PINCTRL_LOONGSON2
>   config LOONGSON2_THERMAL
>   config LOONGSON2_GUTS
>   config LOONGSON2_PM
>   config LOONGSON_LAPTOP  /* N/A for Loongson-1 */
Laptop driver is shared by Loongson-2 and Loongson-3.

>   config GPIO_LOONGSON
>   config GPIO_LOONGSON_64BIT  -> N/A for Loongson-1
>   config GPIO_LOONGSON1
GPIO driver is shared by LS2K and LS7A.

>   config PCI_LOONGSON
PCI driver is shared by Loongson-2 and Loongson-3.

>
> What's your plan about the above Kconfig entries?
Yes, there are exceptions indeed, but very rare. And some of the
exceptions are due to the limited spare time of Jiaxun and me. But in
this case, it is better to keep consistency in the DMA subsystem.

Huacai

> Why can't we use LOONGSON1/LOONGSON2 for drivers?
>
>
> > Huacai
> >
> > >
> > > > Huacai
> > > >
> > > > >
> > > > > > Huacai
> > > > > >
> > > > > > >
> > > > > > >
> > > > > > > > Huacai
> > > > > > > >
> > > > > > > > > +
> > > > > > > > >  config LPC18XX_DMAMUX
> > > > > > > > >         bool "NXP LPC18xx/43xx DMA MUX for PL080"
> > > > > > > > >         depends on ARCH_LPC18XX || COMPILE_TEST
> > > > > > > > > diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
> > > > > > > > > index dfd40d14e408..b26f6677978a 100644
> > > > > > > > > --- a/drivers/dma/Makefile
> > > > > > > > > +++ b/drivers/dma/Makefile
> > > > > > > > > @@ -47,6 +47,7 @@ obj-$(CONFIG_INTEL_IDMA64) += idma64.o
> > > > > > > > >  obj-$(CONFIG_INTEL_IOATDMA) += ioat/
> > > > > > > > >  obj-y += idxd/
> > > > > > > > >  obj-$(CONFIG_K3_DMA) += k3dma.o
> > > > > > > > > +obj-$(CONFIG_LOONGSON1_APB_DMA) += loongson1-apb-dma.o
> > > > > > > > >  obj-$(CONFIG_LPC18XX_DMAMUX) += lpc18xx-dmamux.o
> > > > > > > > >  obj-$(CONFIG_LS2X_APB_DMA) += ls2x-apb-dma.o
> > > > > > > > >  obj-$(CONFIG_MILBEAUT_HDMAC) += milbeaut-hdmac.o
> > > > > > > > > diff --git a/drivers/dma/loongson1-apb-dma.c b/drivers/dma/loongson1-apb-dma.c
> > > > > > > > > new file mode 100644
> > > > > > > > > index 000000000000..d474a2601e6e
> > > > > > > > > --- /dev/null
> > > > > > > > > +++ b/drivers/dma/loongson1-apb-dma.c
> > > > > > > > > @@ -0,0 +1,665 @@
> > > > > > > > > +// SPDX-License-Identifier: GPL-2.0-or-later
> > > > > > > > > +/*
> > > > > > > > > + * Driver for Loongson-1 APB DMA Controller
> > > > > > > > > + *
> > > > > > > > > + * Copyright (C) 2015-2024 Keguang Zhang <keguang.zhang@gmail.com>
> > > > > > > > > + */
> > > > > > > > > +
> > > > > > > > > +#include <linux/dmapool.h>
> > > > > > > > > +#include <linux/dma-mapping.h>
> > > > > > > > > +#include <linux/init.h>
> > > > > > > > > +#include <linux/interrupt.h>
> > > > > > > > > +#include <linux/iopoll.h>
> > > > > > > > > +#include <linux/module.h>
> > > > > > > > > +#include <linux/of.h>
> > > > > > > > > +#include <linux/of_dma.h>
> > > > > > > > > +#include <linux/platform_device.h>
> > > > > > > > > +#include <linux/slab.h>
> > > > > > > > > +
> > > > > > > > > +#include "dmaengine.h"
> > > > > > > > > +#include "virt-dma.h"
> > > > > > > > > +
> > > > > > > > > +/* Loongson-1 DMA Control Register */
> > > > > > > > > +#define DMA_CTRL                       0x0
> > > > > > > > > +
> > > > > > > > > +/* DMA Control Register Bits */
> > > > > > > > > +#define DMA_STOP                       BIT(4)
> > > > > > > > > +#define DMA_START                      BIT(3)
> > > > > > > > > +#define DMA_ASK_VALID                  BIT(2)
> > > > > > > > > +
> > > > > > > > > +#define DMA_ADDR_MASK                  GENMASK(31, 6)
> > > > > > > > > +
> > > > > > > > > +/* DMA Next Field Bits */
> > > > > > > > > +#define DMA_NEXT_VALID                 BIT(0)
> > > > > > > > > +
> > > > > > > > > +/* DMA Command Field Bits */
> > > > > > > > > +#define DMA_RAM2DEV                    BIT(12)
> > > > > > > > > +#define DMA_INT                                BIT(1)
> > > > > > > > > +#define DMA_INT_MASK                   BIT(0)
> > > > > > > > > +
> > > > > > > > > +#define LS1X_DMA_MAX_CHANNELS          3
> > > > > > > > > +
> > > > > > > > > +/* Size of allocations for hardware descriptors */
> > > > > > > > > +#define LS1X_DMA_DESCS_SIZE            PAGE_SIZE
> > > > > > > > > +#define LS1X_DMA_MAX_DESC              \
> > > > > > > > > +       (LS1X_DMA_DESCS_SIZE / sizeof(struct ls1x_dma_hwdesc))
> > > > > > > > > +
> > > > > > > > > +struct ls1x_dma_hwdesc {
> > > > > > > > > +       u32 next;               /* next descriptor address */
> > > > > > > > > +       u32 saddr;              /* memory DMA address */
> > > > > > > > > +       u32 daddr;              /* device DMA address */
> > > > > > > > > +       u32 length;
> > > > > > > > > +       u32 stride;
> > > > > > > > > +       u32 cycles;
> > > > > > > > > +       u32 cmd;
> > > > > > > > > +       u32 stats;
> > > > > > > > > +};
> > > > > > > > > +
> > > > > > > > > +struct ls1x_dma_desc {
> > > > > > > > > +       struct virt_dma_desc vdesc;
> > > > > > > > > +       enum dma_transfer_direction dir;
> > > > > > > > > +       enum dma_transaction_type type;
> > > > > > > > > +       unsigned int bus_width;
> > > > > > > > > +
> > > > > > > > > +       unsigned int nr_descs;  /* number of descriptors */
> > > > > > > > > +
> > > > > > > > > +       struct ls1x_dma_hwdesc *hwdesc;
> > > > > > > > > +       dma_addr_t hwdesc_phys;
> > > > > > > > > +};
> > > > > > > > > +
> > > > > > > > > +struct ls1x_dma_chan {
> > > > > > > > > +       struct virt_dma_chan vchan;
> > > > > > > > > +       struct dma_pool *desc_pool;
> > > > > > > > > +       phys_addr_t src_addr;
> > > > > > > > > +       phys_addr_t dst_addr;
> > > > > > > > > +       enum dma_slave_buswidth src_addr_width;
> > > > > > > > > +       enum dma_slave_buswidth dst_addr_width;
> > > > > > > > > +
> > > > > > > > > +       void __iomem *reg_base;
> > > > > > > > > +       int irq;
> > > > > > > > > +
> > > > > > > > > +       struct ls1x_dma_desc *desc;
> > > > > > > > > +
> > > > > > > > > +       struct ls1x_dma_hwdesc *curr_hwdesc;
> > > > > > > > > +       dma_addr_t curr_hwdesc_phys;
> > > > > > > > > +};
> > > > > > > > > +
> > > > > > > > > +struct ls1x_dma {
> > > > > > > > > +       struct dma_device ddev;
> > > > > > > > > +       void __iomem *reg_base;
> > > > > > > > > +
> > > > > > > > > +       unsigned int nr_chans;
> > > > > > > > > +       struct ls1x_dma_chan chan[];
> > > > > > > > > +};
> > > > > > > > > +
> > > > > > > > > +#define to_ls1x_dma_chan(dchan)                \
> > > > > > > > > +       container_of(dchan, struct ls1x_dma_chan, vchan.chan)
> > > > > > > > > +
> > > > > > > > > +#define to_ls1x_dma_desc(vd)           \
> > > > > > > > > +       container_of(vd, struct ls1x_dma_desc, vdesc)
> > > > > > > > > +
> > > > > > > > > +/* macros for registers read/write */
> > > > > > > > > +#define chan_readl(chan, off)          \
> > > > > > > > > +       readl((chan)->reg_base + (off))
> > > > > > > > > +
> > > > > > > > > +#define chan_writel(chan, off, val)    \
> > > > > > > > > +       writel((val), (chan)->reg_base + (off))
> > > > > > > > > +
> > > > > > > > > +static inline struct device *chan2dev(struct dma_chan *chan)
> > > > > > > > > +{
> > > > > > > > > +       return &chan->dev->device;
> > > > > > > > > +}
> > > > > > > > > +
> > > > > > > > > +static inline int ls1x_dma_query(struct ls1x_dma_chan *chan,
> > > > > > > > > +                                dma_addr_t *hwdesc_phys)
> > > > > > > > > +{
> > > > > > > > > +       struct dma_chan *dchan = &chan->vchan.chan;
> > > > > > > > > +       int val, ret;
> > > > > > > > > +
> > > > > > > > > +       val = *hwdesc_phys & DMA_ADDR_MASK;
> > > > > > > > > +       val |= DMA_ASK_VALID;
> > > > > > > > > +       val |= dchan->chan_id;
> > > > > > > > > +       chan_writel(chan, DMA_CTRL, val);
> > > > > > > > > +       ret = readl_poll_timeout_atomic(chan->reg_base + DMA_CTRL, val,
> > > > > > > > > +                                       !(val & DMA_ASK_VALID), 0, 3000);
> > > > > > > > > +       if (ret)
> > > > > > > > > +               dev_err(chan2dev(dchan), "failed to query DMA\n");
> > > > > > > > > +
> > > > > > > > > +       return ret;
> > > > > > > > > +}
> > > > > > > > > +
> > > > > > > > > +static inline int ls1x_dma_start(struct ls1x_dma_chan *chan,
> > > > > > > > > +                                dma_addr_t *hwdesc_phys)
> > > > > > > > > +{
> > > > > > > > > +       struct dma_chan *dchan = &chan->vchan.chan;
> > > > > > > > > +       int val, ret;
> > > > > > > > > +
> > > > > > > > > +       dev_dbg(chan2dev(dchan), "cookie=%d, starting hwdesc=%x\n",
> > > > > > > > > +               dchan->cookie, *hwdesc_phys);
> > > > > > > > > +
> > > > > > > > > +       val = *hwdesc_phys & DMA_ADDR_MASK;
> > > > > > > > > +       val |= DMA_START;
> > > > > > > > > +       val |= dchan->chan_id;
> > > > > > > > > +       chan_writel(chan, DMA_CTRL, val);
> > > > > > > > > +       ret = readl_poll_timeout(chan->reg_base + DMA_CTRL, val,
> > > > > > > > > +                                !(val & DMA_START), 0, 3000);
> > > > > > > > > +       if (ret)
> > > > > > > > > +               dev_err(chan2dev(dchan), "failed to start DMA\n");
> > > > > > > > > +
> > > > > > > > > +       return ret;
> > > > > > > > > +}
> > > > > > > > > +
> > > > > > > > > +static inline void ls1x_dma_stop(struct ls1x_dma_chan *chan)
> > > > > > > > > +{
> > > > > > > > > +       chan_writel(chan, DMA_CTRL, chan_readl(chan, DMA_CTRL) | DMA_STOP);
> > > > > > > > > +}
> > > > > > > > > +
> > > > > > > > > +static void ls1x_dma_free_chan_resources(struct dma_chan *dchan)
> > > > > > > > > +{
> > > > > > > > > +       struct ls1x_dma_chan *chan = to_ls1x_dma_chan(dchan);
> > > > > > > > > +
> > > > > > > > > +       dma_free_coherent(chan2dev(dchan), sizeof(struct ls1x_dma_hwdesc),
> > > > > > > > > +                         chan->curr_hwdesc, chan->curr_hwdesc_phys);
> > > > > > > > > +       vchan_free_chan_resources(&chan->vchan);
> > > > > > > > > +       dma_pool_destroy(chan->desc_pool);
> > > > > > > > > +       chan->desc_pool = NULL;
> > > > > > > > > +}
> > > > > > > > > +
> > > > > > > > > +static int ls1x_dma_alloc_chan_resources(struct dma_chan *dchan)
> > > > > > > > > +{
> > > > > > > > > +       struct ls1x_dma_chan *chan = to_ls1x_dma_chan(dchan);
> > > > > > > > > +
> > > > > > > > > +       chan->desc_pool = dma_pool_create(dma_chan_name(dchan),
> > > > > > > > > +                                         chan2dev(dchan),
> > > > > > > > > +                                         sizeof(struct ls1x_dma_hwdesc),
> > > > > > > > > +                                         __alignof__(struct ls1x_dma_hwdesc),
> > > > > > > > > +                                         0);
> > > > > > > > > +       if (!chan->desc_pool)
> > > > > > > > > +               return -ENOMEM;
> > > > > > > > > +
> > > > > > > > > +       /* allocate memory for querying current HW descriptor */
> > > > > > > > > +       dma_set_coherent_mask(chan2dev(dchan), DMA_BIT_MASK(32));
> > > > > > > > > +       chan->curr_hwdesc = dma_alloc_coherent(chan2dev(dchan),
> > > > > > > > > +                                              sizeof(struct ls1x_dma_hwdesc),
> > > > > > > > > +                                              &chan->curr_hwdesc_phys,
> > > > > > > > > +                                              GFP_KERNEL);
> > > > > > > > > +       if (!chan->curr_hwdesc)
> > > > > > > > > +               return -ENOMEM;
> > > > > > > > > +
> > > > > > > > > +       return 0;
> > > > > > > > > +}
> > > > > > > > > +
> > > > > > > > > +static void ls1x_dma_free_desc(struct virt_dma_desc *vdesc)
> > > > > > > > > +{
> > > > > > > > > +       struct ls1x_dma_desc *desc = to_ls1x_dma_desc(vdesc);
> > > > > > > > > +       struct ls1x_dma_chan *chan = to_ls1x_dma_chan(vdesc->tx.chan);
> > > > > > > > > +
> > > > > > > > > +       dma_pool_free(chan->desc_pool, desc->hwdesc, desc->hwdesc_phys);
> > > > > > > > > +       chan->desc = NULL;
> > > > > > > > > +       kfree(desc);
> > > > > > > > > +}
> > > > > > > > > +
> > > > > > > > > +static struct ls1x_dma_desc *
> > > > > > > > > +ls1x_dma_alloc_desc(struct dma_chan *dchan, int sg_len,
> > > > > > > > > +                   enum dma_transfer_direction direction,
> > > > > > > > > +                   enum dma_transaction_type type)
> > > > > > > > > +{
> > > > > > > > > +       struct ls1x_dma_chan *chan = to_ls1x_dma_chan(dchan);
> > > > > > > > > +       struct ls1x_dma_desc *desc;
> > > > > > > > > +
> > > > > > > > > +       if (sg_len > LS1X_DMA_MAX_DESC) {
> > > > > > > > > +               dev_err(chan2dev(dchan), "sg_len %u exceeds limit %lu",
> > > > > > > > > +                       sg_len, LS1X_DMA_MAX_DESC);
> > > > > > > > > +               return NULL;
> > > > > > > > > +       }
> > > > > > > > > +
> > > > > > > > > +       desc = kzalloc(sizeof(*desc), GFP_NOWAIT);
> > > > > > > > > +       if (!desc)
> > > > > > > > > +               return NULL;
> > > > > > > > > +
> > > > > > > > > +       /* allocate HW descriptors */
> > > > > > > > > +       desc->hwdesc = dma_pool_zalloc(chan->desc_pool, GFP_NOWAIT,
> > > > > > > > > +                                      &desc->hwdesc_phys);
> > > > > > > > > +       if (!desc->hwdesc) {
> > > > > > > > > +               dev_err(chan2dev(dchan), "failed to alloc HW descriptors\n");
> > > > > > > > > +               ls1x_dma_free_desc(&desc->vdesc);
> > > > > > > > > +               return NULL;
> > > > > > > > > +       }
> > > > > > > > > +
> > > > > > > > > +       desc->dir = direction;
> > > > > > > > > +       desc->type = type;
> > > > > > > > > +       desc->nr_descs = sg_len;
> > > > > > > > > +
> > > > > > > > > +       return desc;
> > > > > > > > > +}
> > > > > > > > > +
> > > > > > > > > +static int ls1x_dma_setup_hwdescs(struct dma_chan *dchan,
> > > > > > > > > +                                 struct ls1x_dma_desc *desc,
> > > > > > > > > +                                 struct scatterlist *sgl, unsigned int sg_len)
> > > > > > > > > +{
> > > > > > > > > +       struct ls1x_dma_chan *chan = to_ls1x_dma_chan(dchan);
> > > > > > > > > +       dma_addr_t next_hwdesc_phys = desc->hwdesc_phys;
> > > > > > > > > +
> > > > > > > > > +       struct scatterlist *sg;
> > > > > > > > > +       unsigned int dev_addr, cmd, i;
> > > > > > > > > +
> > > > > > > > > +       switch (desc->dir) {
> > > > > > > > > +       case DMA_MEM_TO_DEV:
> > > > > > > > > +               dev_addr = chan->dst_addr;
> > > > > > > > > +               desc->bus_width = chan->dst_addr_width;
> > > > > > > > > +               cmd = DMA_RAM2DEV | DMA_INT;
> > > > > > > > > +               break;
> > > > > > > > > +       case DMA_DEV_TO_MEM:
> > > > > > > > > +               dev_addr = chan->src_addr;
> > > > > > > > > +               desc->bus_width = chan->src_addr_width;
> > > > > > > > > +               cmd = DMA_INT;
> > > > > > > > > +               break;
> > > > > > > > > +       default:
> > > > > > > > > +               dev_err(chan2dev(dchan), "unsupported DMA direction: %s\n",
> > > > > > > > > +                       dmaengine_get_direction_text(desc->dir));
> > > > > > > > > +               return -EINVAL;
> > > > > > > > > +       }
> > > > > > > > > +
> > > > > > > > > +       /* setup HW descriptors */
> > > > > > > > > +       for_each_sg(sgl, sg, sg_len, i) {
> > > > > > > > > +               dma_addr_t buf_addr = sg_dma_address(sg);
> > > > > > > > > +               size_t buf_len = sg_dma_len(sg);
> > > > > > > > > +               struct ls1x_dma_hwdesc *hwdesc = &desc->hwdesc[i];
> > > > > > > > > +
> > > > > > > > > +               if (!is_dma_copy_aligned(dchan->device, buf_addr, 0, buf_len)) {
> > > > > > > > > +                       dev_err(chan2dev(dchan), "buffer is not aligned!\n");
> > > > > > > > > +                       return -EINVAL;
> > > > > > > > > +               }
> > > > > > > > > +
> > > > > > > > > +               hwdesc->saddr = buf_addr;
> > > > > > > > > +               hwdesc->daddr = dev_addr;
> > > > > > > > > +               hwdesc->length = buf_len / desc->bus_width;
> > > > > > > > > +               hwdesc->stride = 0;
> > > > > > > > > +               hwdesc->cycles = 1;
> > > > > > > > > +               hwdesc->cmd = cmd;
> > > > > > > > > +
> > > > > > > > > +               if (i) {
> > > > > > > > > +                       next_hwdesc_phys += sizeof(*hwdesc);
> > > > > > > > > +                       desc->hwdesc[i - 1].next = next_hwdesc_phys
> > > > > > > > > +                           | DMA_NEXT_VALID;
> > > > > > > > > +               }
> > > > > > > > > +       }
> > > > > > > > > +
> > > > > > > > > +       if (desc->type == DMA_CYCLIC)
> > > > > > > > > +               desc->hwdesc[i - 1].next = desc->hwdesc_phys | DMA_NEXT_VALID;
> > > > > > > > > +
> > > > > > > > > +       for_each_sg(sgl, sg, sg_len, i) {
> > > > > > > > > +               struct ls1x_dma_hwdesc *hwdesc = &desc->hwdesc[i];
> > > > > > > > > +
> > > > > > > > > +               print_hex_dump_debug("HW DESC: ", DUMP_PREFIX_OFFSET, 16, 4,
> > > > > > > > > +                                    hwdesc, sizeof(*hwdesc), false);
> > > > > > > > > +       }
> > > > > > > > > +
> > > > > > > > > +       return 0;
> > > > > > > > > +}
> > > > > > > > > +
> > > > > > > > > +static struct dma_async_tx_descriptor *
> > > > > > > > > +ls1x_dma_prep_slave_sg(struct dma_chan *dchan,
> > > > > > > > > +                      struct scatterlist *sgl, unsigned int sg_len,
> > > > > > > > > +                      enum dma_transfer_direction direction,
> > > > > > > > > +                      unsigned long flags, void *context)
> > > > > > > > > +{
> > > > > > > > > +       struct ls1x_dma_chan *chan = to_ls1x_dma_chan(dchan);
> > > > > > > > > +       struct ls1x_dma_desc *desc;
> > > > > > > > > +
> > > > > > > > > +       dev_dbg(chan2dev(dchan), "sg_len=%u flags=0x%lx dir=%s\n",
> > > > > > > > > +               sg_len, flags, dmaengine_get_direction_text(direction));
> > > > > > > > > +
> > > > > > > > > +       desc = ls1x_dma_alloc_desc(dchan, sg_len, direction, DMA_SLAVE);
> > > > > > > > > +       if (!desc)
> > > > > > > > > +               return NULL;
> > > > > > > > > +
> > > > > > > > > +       if (ls1x_dma_setup_hwdescs(dchan, desc, sgl, sg_len)) {
> > > > > > > > > +               ls1x_dma_free_desc(&desc->vdesc);
> > > > > > > > > +               return NULL;
> > > > > > > > > +       }
> > > > > > > > > +
> > > > > > > > > +       return vchan_tx_prep(&chan->vchan, &desc->vdesc, flags);
> > > > > > > > > +}
> > > > > > > > > +
> > > > > > > > > +static struct dma_async_tx_descriptor *
> > > > > > > > > +ls1x_dma_prep_dma_cyclic(struct dma_chan *dchan,
> > > > > > > > > +                        dma_addr_t buf_addr, size_t buf_len, size_t period_len,
> > > > > > > > > +                        enum dma_transfer_direction direction,
> > > > > > > > > +                        unsigned long flags)
> > > > > > > > > +{
> > > > > > > > > +       struct ls1x_dma_chan *chan = to_ls1x_dma_chan(dchan);
> > > > > > > > > +       struct ls1x_dma_desc *desc;
> > > > > > > > > +       struct scatterlist *sgl;
> > > > > > > > > +       unsigned int sg_len;
> > > > > > > > > +       unsigned int i;
> > > > > > > > > +
> > > > > > > > > +       dev_dbg(chan2dev(dchan),
> > > > > > > > > +               "buf_len=%d period_len=%zu flags=0x%lx dir=%s\n", buf_len,
> > > > > > > > > +               period_len, flags, dmaengine_get_direction_text(direction));
> > > > > > > > > +
> > > > > > > > > +       sg_len = buf_len / period_len;
> > > > > > > > > +       desc = ls1x_dma_alloc_desc(dchan, sg_len, direction, DMA_CYCLIC);
> > > > > > > > > +       if (!desc)
> > > > > > > > > +               return NULL;
> > > > > > > > > +
> > > > > > > > > +       /* allocate the scatterlist */
> > > > > > > > > +       sgl = kmalloc_array(sg_len, sizeof(*sgl), GFP_NOWAIT);
> > > > > > > > > +       if (!sgl)
> > > > > > > > > +               return NULL;
> > > > > > > > > +
> > > > > > > > > +       sg_init_table(sgl, sg_len);
> > > > > > > > > +       for (i = 0; i < sg_len; ++i) {
> > > > > > > > > +               sg_set_page(&sgl[i], pfn_to_page(PFN_DOWN(buf_addr)),
> > > > > > > > > +                           period_len, offset_in_page(buf_addr));
> > > > > > > > > +               sg_dma_address(&sgl[i]) = buf_addr;
> > > > > > > > > +               sg_dma_len(&sgl[i]) = period_len;
> > > > > > > > > +               buf_addr += period_len;
> > > > > > > > > +       }
> > > > > > > > > +
> > > > > > > > > +       if (ls1x_dma_setup_hwdescs(dchan, desc, sgl, sg_len)) {
> > > > > > > > > +               ls1x_dma_free_desc(&desc->vdesc);
> > > > > > > > > +               return NULL;
> > > > > > > > > +       }
> > > > > > > > > +
> > > > > > > > > +       kfree(sgl);
> > > > > > > > > +
> > > > > > > > > +       return vchan_tx_prep(&chan->vchan, &desc->vdesc, flags);
> > > > > > > > > +}
> > > > > > > > > +
> > > > > > > > > +static int ls1x_dma_slave_config(struct dma_chan *dchan,
> > > > > > > > > +                                struct dma_slave_config *config)
> > > > > > > > > +{
> > > > > > > > > +       struct ls1x_dma_chan *chan = to_ls1x_dma_chan(dchan);
> > > > > > > > > +
> > > > > > > > > +       chan->src_addr = config->src_addr;
> > > > > > > > > +       chan->src_addr_width = config->src_addr_width;
> > > > > > > > > +       chan->dst_addr = config->dst_addr;
> > > > > > > > > +       chan->dst_addr_width = config->dst_addr_width;
> > > > > > > > > +
> > > > > > > > > +       return 0;
> > > > > > > > > +}
> > > > > > > > > +
> > > > > > > > > +static int ls1x_dma_pause(struct dma_chan *dchan)
> > > > > > > > > +{
> > > > > > > > > +       struct ls1x_dma_chan *chan = to_ls1x_dma_chan(dchan);
> > > > > > > > > +       unsigned long flags;
> > > > > > > > > +       int ret;
> > > > > > > > > +
> > > > > > > > > +       spin_lock_irqsave(&chan->vchan.lock, flags);
> > > > > > > > > +       ret = ls1x_dma_query(chan, &chan->curr_hwdesc_phys);
> > > > > > > > > +       if (!ret)
> > > > > > > > > +               ls1x_dma_stop(chan);
> > > > > > > > > +       spin_unlock_irqrestore(&chan->vchan.lock, flags);
> > > > > > > > > +
> > > > > > > > > +       return ret;
> > > > > > > > > +}
> > > > > > > > > +
> > > > > > > > > +static int ls1x_dma_resume(struct dma_chan *dchan)
> > > > > > > > > +{
> > > > > > > > > +       struct ls1x_dma_chan *chan = to_ls1x_dma_chan(dchan);
> > > > > > > > > +       unsigned long flags;
> > > > > > > > > +       int ret;
> > > > > > > > > +
> > > > > > > > > +       spin_lock_irqsave(&chan->vchan.lock, flags);
> > > > > > > > > +       ret = ls1x_dma_start(chan, &chan->curr_hwdesc_phys);
> > > > > > > > > +       spin_unlock_irqrestore(&chan->vchan.lock, flags);
> > > > > > > > > +
> > > > > > > > > +       return ret;
> > > > > > > > > +}
> > > > > > > > > +
> > > > > > > > > +static int ls1x_dma_terminate_all(struct dma_chan *dchan)
> > > > > > > > > +{
> > > > > > > > > +       struct ls1x_dma_chan *chan = to_ls1x_dma_chan(dchan);
> > > > > > > > > +       unsigned long flags;
> > > > > > > > > +       LIST_HEAD(head);
> > > > > > > > > +
> > > > > > > > > +       spin_lock_irqsave(&chan->vchan.lock, flags);
> > > > > > > > > +       ls1x_dma_stop(chan);
> > > > > > > > > +       vchan_get_all_descriptors(&chan->vchan, &head);
> > > > > > > > > +       spin_unlock_irqrestore(&chan->vchan.lock, flags);
> > > > > > > > > +
> > > > > > > > > +       vchan_dma_desc_free_list(&chan->vchan, &head);
> > > > > > > > > +
> > > > > > > > > +       return 0;
> > > > > > > > > +}
> > > > > > > > > +
> > > > > > > > > +static enum dma_status ls1x_dma_tx_status(struct dma_chan *dchan,
> > > > > > > > > +                                         dma_cookie_t cookie,
> > > > > > > > > +                                         struct dma_tx_state *state)
> > > > > > > > > +{
> > > > > > > > > +       struct ls1x_dma_chan *chan = to_ls1x_dma_chan(dchan);
> > > > > > > > > +       struct virt_dma_desc *vdesc;
> > > > > > > > > +       enum dma_status status;
> > > > > > > > > +       size_t bytes = 0;
> > > > > > > > > +       unsigned long flags;
> > > > > > > > > +
> > > > > > > > > +       status = dma_cookie_status(dchan, cookie, state);
> > > > > > > > > +       if (status == DMA_COMPLETE)
> > > > > > > > > +               return status;
> > > > > > > > > +
> > > > > > > > > +       spin_lock_irqsave(&chan->vchan.lock, flags);
> > > > > > > > > +       vdesc = vchan_find_desc(&chan->vchan, cookie);
> > > > > > > > > +       if (chan->desc && cookie == chan->desc->vdesc.tx.cookie) {
> > > > > > > > > +               struct ls1x_dma_desc *desc = chan->desc;
> > > > > > > > > +               int i;
> > > > > > > > > +
> > > > > > > > > +               if (ls1x_dma_query(chan, &chan->curr_hwdesc_phys))
> > > > > > > > > +                       return status;
> > > > > > > > > +
> > > > > > > > > +               /* locate the current HW descriptor */
> > > > > > > > > +               for (i = 0; i < desc->nr_descs; i++)
> > > > > > > > > +                       if (desc->hwdesc[i].next == chan->curr_hwdesc->next)
> > > > > > > > > +                               break;
> > > > > > > > > +
> > > > > > > > > +               /* count the residues */
> > > > > > > > > +               for (; i < desc->nr_descs; i++)
> > > > > > > > > +                       bytes += desc->hwdesc[i].length * desc->bus_width;
> > > > > > > > > +
> > > > > > > > > +               dma_set_residue(state, bytes);
> > > > > > > > > +       }
> > > > > > > > > +       spin_unlock_irqrestore(&chan->vchan.lock, flags);
> > > > > > > > > +
> > > > > > > > > +       return status;
> > > > > > > > > +}
> > > > > > > > > +
> > > > > > > > > +static void ls1x_dma_issue_pending(struct dma_chan *dchan)
> > > > > > > > > +{
> > > > > > > > > +       struct ls1x_dma_chan *chan = to_ls1x_dma_chan(dchan);
> > > > > > > > > +       struct virt_dma_desc *vdesc;
> > > > > > > > > +       unsigned long flags;
> > > > > > > > > +
> > > > > > > > > +       spin_lock_irqsave(&chan->vchan.lock, flags);
> > > > > > > > > +       if (vchan_issue_pending(&chan->vchan) && !chan->desc) {
> > > > > > > > > +               vdesc = vchan_next_desc(&chan->vchan);
> > > > > > > > > +               if (!vdesc) {
> > > > > > > > > +                       chan->desc = NULL;
> > > > > > > > > +                       return;
> > > > > > > > > +               }
> > > > > > > > > +               chan->desc = to_ls1x_dma_desc(vdesc);
> > > > > > > > > +               ls1x_dma_start(chan, &chan->desc->hwdesc_phys);
> > > > > > > > > +       }
> > > > > > > > > +       spin_unlock_irqrestore(&chan->vchan.lock, flags);
> > > > > > > > > +}
> > > > > > > > > +
> > > > > > > > > +static irqreturn_t ls1x_dma_irq_handler(int irq, void *data)
> > > > > > > > > +{
> > > > > > > > > +       struct ls1x_dma_chan *chan = data;
> > > > > > > > > +       struct ls1x_dma_desc *desc = chan->desc;
> > > > > > > > > +       struct dma_chan *dchan = &chan->vchan.chan;
> > > > > > > > > +
> > > > > > > > > +       if (!desc) {
> > > > > > > > > +               dev_warn(chan2dev(dchan),
> > > > > > > > > +                        "IRQ %d with no active descriptor on channel %d\n",
> > > > > > > > > +                        irq, dchan->chan_id);
> > > > > > > > > +               return IRQ_NONE;
> > > > > > > > > +       }
> > > > > > > > > +
> > > > > > > > > +       dev_dbg(chan2dev(dchan), "DMA IRQ %d on channel %d\n", irq,
> > > > > > > > > +               dchan->chan_id);
> > > > > > > > > +
> > > > > > > > > +       spin_lock(&chan->vchan.lock);
> > > > > > > > > +
> > > > > > > > > +       if (desc->type == DMA_CYCLIC) {
> > > > > > > > > +               vchan_cyclic_callback(&desc->vdesc);
> > > > > > > > > +       } else {
> > > > > > > > > +               list_del(&desc->vdesc.node);
> > > > > > > > > +               vchan_cookie_complete(&desc->vdesc);
> > > > > > > > > +               chan->desc = NULL;
> > > > > > > > > +       }
> > > > > > > > > +
> > > > > > > > > +       spin_unlock(&chan->vchan.lock);
> > > > > > > > > +       return IRQ_HANDLED;
> > > > > > > > > +}
> > > > > > > > > +
> > > > > > > > > +static int ls1x_dma_chan_probe(struct platform_device *pdev,
> > > > > > > > > +                              struct ls1x_dma *dma, int chan_id)
> > > > > > > > > +{
> > > > > > > > > +       struct device *dev = &pdev->dev;
> > > > > > > > > +       struct ls1x_dma_chan *chan = &dma->chan[chan_id];
> > > > > > > > > +       char pdev_irqname[4];
> > > > > > > > > +       char *irqname;
> > > > > > > > > +       int ret;
> > > > > > > > > +
> > > > > > > > > +       sprintf(pdev_irqname, "ch%u", chan_id);
> > > > > > > > > +       chan->irq = platform_get_irq_byname(pdev, pdev_irqname);
> > > > > > > > > +       if (chan->irq < 0)
> > > > > > > > > +               return -ENODEV;
> > > > > > > > > +
> > > > > > > > > +       irqname = devm_kasprintf(dev, GFP_KERNEL, "%s:%s",
> > > > > > > > > +                                dev_name(dev), pdev_irqname);
> > > > > > > > > +       if (!irqname)
> > > > > > > > > +               return -ENOMEM;
> > > > > > > > > +
> > > > > > > > > +       ret = devm_request_irq(dev, chan->irq, ls1x_dma_irq_handler,
> > > > > > > > > +                              IRQF_SHARED, irqname, chan);
> > > > > > > > > +       if (ret)
> > > > > > > > > +               return dev_err_probe(dev, ret,
> > > > > > > > > +                                    "failed to request IRQ %u!\n", chan->irq);
> > > > > > > > > +
> > > > > > > > > +       chan->reg_base = dma->reg_base;
> > > > > > > > > +       chan->vchan.desc_free = ls1x_dma_free_desc;
> > > > > > > > > +       vchan_init(&chan->vchan, &dma->ddev);
> > > > > > > > > +       dev_info(dev, "%s (irq %d) initialized\n", pdev_irqname, chan->irq);
> > > > > > > > > +
> > > > > > > > > +       return 0;
> > > > > > > > > +}
> > > > > > > > > +
> > > > > > > > > +static void ls1x_dma_chan_remove(struct ls1x_dma *dma, int chan_id)
> > > > > > > > > +{
> > > > > > > > > +       struct device *dev = dma->ddev.dev;
> > > > > > > > > +       struct ls1x_dma_chan *chan = &dma->chan[chan_id];
> > > > > > > > > +
> > > > > > > > > +       devm_free_irq(dev, chan->irq, chan);
> > > > > > > > > +       list_del(&chan->vchan.chan.device_node);
> > > > > > > > > +       tasklet_kill(&chan->vchan.task);
> > > > > > > > > +}
> > > > > > > > > +
> > > > > > > > > +static int ls1x_dma_probe(struct platform_device *pdev)
> > > > > > > > > +{
> > > > > > > > > +       struct device *dev = &pdev->dev;
> > > > > > > > > +       struct dma_device *ddev;
> > > > > > > > > +       struct ls1x_dma *dma;
> > > > > > > > > +       int nr_chans, ret, i;
> > > > > > > > > +
> > > > > > > > > +       nr_chans = platform_irq_count(pdev);
> > > > > > > > > +       if (nr_chans <= 0)
> > > > > > > > > +               return nr_chans;
> > > > > > > > > +       if (nr_chans > LS1X_DMA_MAX_CHANNELS)
> > > > > > > > > +               return dev_err_probe(dev, -EINVAL,
> > > > > > > > > +                                    "nr_chans=%d exceeds the maximum\n",
> > > > > > > > > +                                    nr_chans);
> > > > > > > > > +
> > > > > > > > > +       dma = devm_kzalloc(dev, struct_size(dma, chan, nr_chans), GFP_KERNEL);
> > > > > > > > > +       if (!dma)
> > > > > > > > > +               return -ENOMEM;
> > > > > > > > > +
> > > > > > > > > +       /* initialize DMA device */
> > > > > > > > > +       dma->reg_base = devm_platform_ioremap_resource(pdev, 0);
> > > > > > > > > +       if (IS_ERR(dma->reg_base))
> > > > > > > > > +               return PTR_ERR(dma->reg_base);
> > > > > > > > > +
> > > > > > > > > +       ddev = &dma->ddev;
> > > > > > > > > +       ddev->dev = dev;
> > > > > > > > > +       ddev->copy_align = DMAENGINE_ALIGN_4_BYTES;
> > > > > > > > > +       ddev->src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
> > > > > > > > > +           BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | BIT(DMA_SLAVE_BUSWIDTH_4_BYTES);
> > > > > > > > > +       ddev->dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
> > > > > > > > > +           BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | BIT(DMA_SLAVE_BUSWIDTH_4_BYTES);
> > > > > > > > > +       ddev->directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
> > > > > > > > > +       ddev->max_sg_burst = LS1X_DMA_MAX_DESC;
> > > > > > > > > +       ddev->residue_granularity = DMA_RESIDUE_GRANULARITY_SEGMENT;
> > > > > > > > > +       ddev->device_alloc_chan_resources = ls1x_dma_alloc_chan_resources;
> > > > > > > > > +       ddev->device_free_chan_resources = ls1x_dma_free_chan_resources;
> > > > > > > > > +       ddev->device_prep_slave_sg = ls1x_dma_prep_slave_sg;
> > > > > > > > > +       ddev->device_prep_dma_cyclic = ls1x_dma_prep_dma_cyclic;
> > > > > > > > > +       ddev->device_config = ls1x_dma_slave_config;
> > > > > > > > > +       ddev->device_pause = ls1x_dma_pause;
> > > > > > > > > +       ddev->device_resume = ls1x_dma_resume;
> > > > > > > > > +       ddev->device_terminate_all = ls1x_dma_terminate_all;
> > > > > > > > > +       ddev->device_tx_status = ls1x_dma_tx_status;
> > > > > > > > > +       ddev->device_issue_pending = ls1x_dma_issue_pending;
> > > > > > > > > +
> > > > > > > > > +       dma_cap_set(DMA_SLAVE, ddev->cap_mask);
> > > > > > > > > +       INIT_LIST_HEAD(&ddev->channels);
> > > > > > > > > +
> > > > > > > > > +       /* initialize DMA channels */
> > > > > > > > > +       for (i = 0; i < nr_chans; i++) {
> > > > > > > > > +               ret = ls1x_dma_chan_probe(pdev, dma, i);
> > > > > > > > > +               if (ret)
> > > > > > > > > +                       return ret;
> > > > > > > > > +       }
> > > > > > > > > +       dma->nr_chans = nr_chans;
> > > > > > > > > +
> > > > > > > > > +       ret = dmaenginem_async_device_register(ddev);
> > > > > > > > > +       if (ret) {
> > > > > > > > > +               dev_err(dev, "failed to register DMA device! %d\n", ret);
> > > > > > > > > +               return ret;
> > > > > > > > > +       }
> > > > > > > > > +
> > > > > > > > > +       ret =
> > > > > > > > > +           of_dma_controller_register(dev->of_node, of_dma_xlate_by_chan_id,
> > > > > > > > > +                                      ddev);
> > > > > > > > > +       if (ret) {
> > > > > > > > > +               dev_err(dev, "failed to register DMA controller! %d\n", ret);
> > > > > > > > > +               return ret;
> > > > > > > > > +       }
> > > > > > > > > +
> > > > > > > > > +       platform_set_drvdata(pdev, dma);
> > > > > > > > > +       dev_info(dev, "Loongson1 DMA driver registered\n");
> > > > > > > > > +
> > > > > > > > > +       return 0;
> > > > > > > > > +}
> > > > > > > > > +
> > > > > > > > > +static void ls1x_dma_remove(struct platform_device *pdev)
> > > > > > > > > +{
> > > > > > > > > +       struct ls1x_dma *dma = platform_get_drvdata(pdev);
> > > > > > > > > +       int i;
> > > > > > > > > +
> > > > > > > > > +       of_dma_controller_free(pdev->dev.of_node);
> > > > > > > > > +
> > > > > > > > > +       for (i = 0; i < dma->nr_chans; i++)
> > > > > > > > > +               ls1x_dma_chan_remove(dma, i);
> > > > > > > > > +}
> > > > > > > > > +
> > > > > > > > > +static const struct of_device_id ls1x_dma_match[] = {
> > > > > > > > > +       { .compatible = "loongson,ls1b-apbdma" },
> > > > > > > > > +       { .compatible = "loongson,ls1c-apbdma" },
> > > > > > > > > +       { /* sentinel */ }
> > > > > > > > > +};
> > > > > > > > > +MODULE_DEVICE_TABLE(of, ls1x_dma_match);
> > > > > > > > > +
> > > > > > > > > +static struct platform_driver ls1x_dma_driver = {
> > > > > > > > > +       .probe = ls1x_dma_probe,
> > > > > > > > > +       .remove_new = ls1x_dma_remove,
> > > > > > > > > +       .driver = {
> > > > > > > > > +               .name = KBUILD_MODNAME,
> > > > > > > > > +               .of_match_table = ls1x_dma_match,
> > > > > > > > > +       },
> > > > > > > > > +};
> > > > > > > > > +
> > > > > > > > > +module_platform_driver(ls1x_dma_driver);
> > > > > > > > > +
> > > > > > > > > +MODULE_AUTHOR("Keguang Zhang <keguang.zhang@gmail.com>");
> > > > > > > > > +MODULE_DESCRIPTION("Loongson-1 APB DMA Controller driver");
> > > > > > > > > +MODULE_LICENSE("GPL");
> > > > > > > > >
> > > > > > > > > --
> > > > > > > > > 2.40.1
> > > > > > > > >
> > > > > > > > >
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > > > --
> > > > > > > Best regards,
> > > > > > >
> > > > > > > Keguang Zhang
> > > > > > >
> > > > >
> > > > >
> > > > >
> > > > > --
> > > > > Best regards,
> > > > >
> > > > > Keguang Zhang
> > >
> > >
> > >
> > > --
> > > Best regards,
> > >
> > > Keguang Zhang
>
>
>
> --
> Best regards,
>
> Keguang Zhang

^ permalink raw reply

* Re: [PATCH v6 2/6] interconnect: icc-clk: Remove tristate from INTERCONNECT_CLK
From: Konrad Dybcio @ 2024-04-02 14:49 UTC (permalink / raw)
  To: Dmitry Baryshkov, Varadarajan Narayanan
  Cc: andersson, mturquette, sboyd, robh, krzysztof.kozlowski+dt,
	conor+dt, djakov, quic_anusha, linux-arm-msm, linux-clk,
	devicetree, linux-kernel, linux-pm, kernel test robot
In-Reply-To: <CAA8EJppyuagb5zkP4LCjjJwConw3mw3iS-+dO7YB01=7-waRTw@mail.gmail.com>

On 2.04.2024 12:39 PM, Dmitry Baryshkov wrote:
> On Tue, 2 Apr 2024 at 13:34, Varadarajan Narayanan
> <quic_varada@quicinc.com> wrote:
>>
>> drivers/clk/qcom/common.c uses devm_icc_clk_register under
>> IS_ENABLED(CONFIG_INTERCONNECT_CLK). However, in kernel bot
>> random config build test, with the following combination
>>
>>         CONFIG_COMMON_CLK_QCOM=y
>>                 and
>>         CONFIG_INTERCONNECT_CLK=m
>>
>> the following error is seen as devm_icc_clk_register is in a
>> module and being referenced from vmlinux.
>>
>>         powerpc64-linux-ld: drivers/clk/qcom/common.o: in function `qcom_cc_really_probe':
>>         >> common.c:(.text+0x980): undefined reference to `devm_icc_clk_register'
>>
>> Hence, ensure INTERCONNECT_CLK is not selected as a module.
> 
> NAK. Please use `depends on INTERCONNECT_CLK || !INTERCONNECT_CLK` in
> your Kconfig dependencies.

Should icc-clk ever be built as a module? It really seems like it should be
a part of the core framework.. And dependency management would be easier

Konrad

^ permalink raw reply

* Re: [PATCH 3/3] arm64: dts: msm8996: add fastrpc nodes
From: Konrad Dybcio @ 2024-04-02 14:47 UTC (permalink / raw)
  To: Dmitry Baryshkov, Bjorn Andersson, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Mathieu Poirier, Sibi Sankar
  Cc: linux-arm-msm, devicetree, linux-remoteproc, linux-kernel,
	Srinivas Kandagatla
In-Reply-To: <20240401-msm8996-remoteproc-v1-3-f02ab47fc728@linaro.org>

On 31.03.2024 11:10 PM, Dmitry Baryshkov wrote:
> From: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
> 
> The ADSP provides fastrpc/compute capabilities. Enable support for the
> fastrpc on this DSP.
> 
> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---
>  arch/arm64/boot/dts/qcom/msm8996.dtsi | 57 +++++++++++++++++++++++++++++++++++
>  1 file changed, 57 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi
> index 7ae499fa7d91..cf7ab01f3af6 100644
> --- a/arch/arm64/boot/dts/qcom/msm8996.dtsi
> +++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi
> @@ -3545,6 +3545,63 @@ q6routing: routing {
>  						};
>  					};
>  				};
> +
> +				fastrpc {
> +					compatible = "qcom,fastrpc";
> +					qcom,smd-channels = "fastrpcsmd-apps-dsp";
> +					label = "adsp";
> +					qcom,non-secure-domain;
> +					#address-cells = <1>;
> +					#size-cells = <0>;
> +
> +					cb@8 {
> +						compatible = "qcom,fastrpc-compute-cb";
> +						reg = <8>;
> +						iommus = <&lpass_q6_smmu 8>;
> +					};
> +
> +					cb@9 {
> +						compatible = "qcom,fastrpc-compute-cb";
> +						reg = <9>;
> +						iommus = <&lpass_q6_smmu 9>;
> +					};
> +
> +					cb@10 {
> +						compatible = "qcom,fastrpc-compute-cb";
> +						reg = <10>;
> +						iommus = <&lpass_q6_smmu 10>;
> +					};
> +
> +					cb@11 {
> +						compatible = "qcom,fastrpc-compute-cb";
> +						reg = <11>;
> +						iommus = <&lpass_q6_smmu 11>;
> +					};
> +
> +					cb@12 {
> +						compatible = "qcom,fastrpc-compute-cb";
> +						reg = <12>;
> +						iommus = <&lpass_q6_smmu 12>;
> +					};
> +
> +					cb@5 {
> +						compatible = "qcom,fastrpc-compute-cb";
> +						reg = <5>;

No need to copy downstream's creative alphabetical-but-not-numerical
sorting.. The entries look OK though.. although, any reason we have
such a weird binding including faux child nodes and not just an array
of iommus? Is the only way to discover the fastrpc nodes' properties
such as qcom,non-secure-domain or vmid belonging through hardcoding?

Konrad

Konrad

^ permalink raw reply

* Re: [PATCH v4 4/4] arm64: dts: S32G3: Introduce device tree for S32G-VNP-RDB3
From: Shawn Guo @ 2024-04-02 14:41 UTC (permalink / raw)
  To: Wadim Mueller
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Ulf Hansson,
	Shawn Guo, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
	NXP Linux Team, Greg Kroah-Hartman, Jiri Slaby, Chester Lin,
	Andreas Färber, Matthias Brugger, NXP S32 Linux Team,
	Tim Harvey, Marco Felsch, Marek Vasut, Gregor Herburger,
	Hugo Villeneuve, Joao Paulo Goncalves, Markus Niebel,
	Matthias Schiffer, Stefan Wahren, Bjorn Helgaas,
	Philippe Schenker, Josua Mayer, Li Yang, devicetree, linux-kernel,
	linux-mmc, linux-arm-kernel, linux-serial
In-Reply-To: <20240324214329.29988-5-wafgo01@gmail.com>

On Sun, Mar 24, 2024 at 10:43:26PM +0100, Wadim Mueller wrote:
> This commit adds device tree support for the NXP S32G3-based
> S32G-VNP-RDB3 Board [1].
> 
> The S32G3 features an 8-core ARM Cortex-A53 based SoC developed by NXP.
> 
> The device tree files are derived from the official NXP downstream
> Linux tree [2].
> 
> This addition encompasses a limited selection of peripherals that
> are upstream-supported. Apart from the ARM System Modules
> (GIC, Generic Timer, etc.), the following IPs have been validated:
> 
>     * UART: fsl-linflexuart
>     * SDHC: fsl-imx-esdhc
> 
> Clock settings for the chip rely on ATF Firmware [3].
> Pin control integration into the device tree is pending and currently
> relies on Firmware/U-Boot settings [4].
> 
> These changes were validated using BSP39 Firmware/U-Boot from NXP [5].
> 
> The modifications enable booting the official Ubuntu 22.04 from NXP on
> the RDB3 with default settings from the SD card and eMMC.
> 
> [1] https://www.nxp.com/design/design-center/designs/s32g3-vehicle-networking-reference-design:S32G-VNP-RDB3
> [2] https://github.com/nxp-auto-linux/linux
> [3] https://github.com/nxp-auto-linux/arm-trusted-firmware
> [4] https://github.com/nxp-auto-linux/u-boot
> [5] https://github.com/nxp-auto-linux/auto_yocto_bsp
> 
> Signed-off-by: Wadim Mueller <wafgo01@gmail.com>
> ---
>  arch/arm64/boot/dts/freescale/Makefile        |   1 +
>  arch/arm64/boot/dts/freescale/s32g3.dtsi      | 233 ++++++++++++++++++
>  .../boot/dts/freescale/s32g399a-rdb3.dts      |  45 ++++
>  3 files changed, 279 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/freescale/s32g3.dtsi
>  create mode 100644 arch/arm64/boot/dts/freescale/s32g399a-rdb3.dts
> 
> diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile
> index 2cb0212b63c6..e701008dbc7b 100644
> --- a/arch/arm64/boot/dts/freescale/Makefile
> +++ b/arch/arm64/boot/dts/freescale/Makefile
> @@ -252,3 +252,4 @@ dtb-$(CONFIG_ARCH_MXC) += imx8mp-venice-gw74xx-rpidsi.dtb
>  dtb-$(CONFIG_ARCH_S32) += s32g274a-evb.dtb
>  dtb-$(CONFIG_ARCH_S32) += s32g274a-rdb2.dtb
>  dtb-$(CONFIG_ARCH_S32) += s32v234-evb.dtb
> +dtb-$(CONFIG_ARCH_S32) += s32g399a-rdb3.dtb

The list is alphabetically sorted, so it should be added before
s32v234-evb.dtb.  I fixed it up and applied the patch.

Shawn


^ permalink raw reply

* [PATCH v5 4/4] dts: arm64: imx8dxl-evk: add lpuart1 and cm40 uart
From: Frank Li @ 2024-04-02 14:41 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Shawn Guo,
	Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam
  Cc: devicetree, imx, linux-arm-kernel, linux-kernel, Frank Li
In-Reply-To: <20240402-m4_lpuart-v5-0-3292629ba808@nxp.com>

Add lpuart1 and cm40 uart.

Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
 arch/arm64/boot/dts/freescale/imx8dxl-evk.dts | 37 +++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8dxl-evk.dts b/arch/arm64/boot/dts/freescale/imx8dxl-evk.dts
index 2123d431e0613..2412ab145c066 100644
--- a/arch/arm64/boot/dts/freescale/imx8dxl-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8dxl-evk.dts
@@ -16,6 +16,8 @@ aliases {
 		mmc0 = &usdhc1;
 		mmc1 = &usdhc2;
 		serial0 = &lpuart0;
+		serial1 = &lpuart1;
+		serial6 = &cm40_lpuart;
 	};
 
 	chosen {
@@ -51,6 +53,16 @@ linux,cma {
 		};
 	};
 
+	m2_uart1_sel: regulator-m2uart1sel {
+		compatible = "regulator-fixed";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-name = "m2_uart1_sel";
+		gpio = <&pca6416_1 6 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+		regulator-always-on;
+	};
+
 	mux3_en: regulator-0 {
 		compatible = "regulator-fixed";
 		regulator-min-microvolt = <3300000>;
@@ -340,6 +352,12 @@ &lpuart0 {
 	status = "okay";
 };
 
+&lpuart1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_lpuart1>;
+	status = "okay";
+};
+
 &flexcan2 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_flexcan2>;
@@ -354,6 +372,16 @@ &flexcan3 {
 	status = "okay";
 };
 
+&cm40_intmux {
+	status = "disabled";
+};
+
+&cm40_lpuart {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_cm40_lpuart>;
+	status = "disabled";
+};
+
 &lsio_gpio4 {
 	status = "okay";
 };
@@ -595,6 +623,15 @@ IMX8DXL_UART0_TX_ADMA_UART0_TX		0x06000020
 		>;
 	};
 
+	pinctrl_lpuart1: lpuart1grp {
+		fsl,pins = <
+			IMX8DXL_UART1_TX_ADMA_UART1_TX          0x06000020
+			IMX8DXL_UART1_RX_ADMA_UART1_RX          0x06000020
+			IMX8DXL_UART1_RTS_B_ADMA_UART1_RTS_B    0x06000020
+			IMX8DXL_UART1_CTS_B_ADMA_UART1_CTS_B    0x06000020
+		>;
+	};
+
 	pinctrl_usdhc1: usdhc1grp {
 		fsl,pins = <
 			IMX8DXL_EMMC0_CLK_CONN_EMMC0_CLK	0x06000041

-- 
2.34.1


^ permalink raw reply related

* [PATCH v5 3/4] arm64: dts: imx8dxl: update cm40 irq number information
From: Frank Li @ 2024-04-02 14:41 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Shawn Guo,
	Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam
  Cc: devicetree, imx, linux-arm-kernel, linux-kernel, Frank Li
In-Reply-To: <20240402-m4_lpuart-v5-0-3292629ba808@nxp.com>

Update cm40 irq number for imx8dxl chip.

Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
 arch/arm64/boot/dts/freescale/imx8dxl.dtsi | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8dxl.dtsi b/arch/arm64/boot/dts/freescale/imx8dxl.dtsi
index 9d49c75a26222..b9d137d69f5a7 100644
--- a/arch/arm64/boot/dts/freescale/imx8dxl.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8dxl.dtsi
@@ -243,3 +243,14 @@ xtal24m: clock-xtal24m {
 #include "imx8dxl-ss-conn.dtsi"
 #include "imx8dxl-ss-lsio.dtsi"
 #include "imx8dxl-ss-ddr.dtsi"
+
+&cm40_intmux {
+	interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
+		     <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
+		     <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
+		     <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
+		     <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
+		     <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
+		     <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>,
+		     <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
+};

-- 
2.34.1


^ permalink raw reply related

* [PATCH v5 2/4] arm64: dts: imx8dxl: add lpuart device in cm40 subsystem
From: Frank Li @ 2024-04-02 14:41 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Shawn Guo,
	Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam
  Cc: devicetree, imx, linux-arm-kernel, linux-kernel, Frank Li,
	Alice Guo, Peng Fan, Alexander Stein
In-Reply-To: <20240402-m4_lpuart-v5-0-3292629ba808@nxp.com>

From: Alice Guo <alice.guo@nxp.com>

Add lpuart device in cm40 subsystem.

Signed-off-by: Alice Guo <alice.guo@nxp.com>
Reviewed-by: Peng Fan <peng.fan@nxp.com>
Reviewed-by: Alexander Stein <alexander.stein@ew.tq-group.com>
Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
 arch/arm64/boot/dts/freescale/imx8-ss-cm40.dtsi | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8-ss-cm40.dtsi b/arch/arm64/boot/dts/freescale/imx8-ss-cm40.dtsi
index 84d7ae01e5f40..92752c0c5eb5b 100644
--- a/arch/arm64/boot/dts/freescale/imx8-ss-cm40.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8-ss-cm40.dtsi
@@ -20,6 +20,18 @@ cm40_subsys: bus@34000000 {
 	ranges = <0x34000000 0x0 0x34000000 0x4000000>;
 	interrupt-parent = <&cm40_intmux>;
 
+	cm40_lpuart: serial@37220000 {
+		compatible = "fsl,imx8qxp-lpuart";
+		reg = <0x37220000 0x1000>;
+		interrupts = <7 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cm40_uart_lpcg IMX_LPCG_CLK_1>, <&cm40_uart_lpcg IMX_LPCG_CLK_0>;
+		clock-names = "ipg", "baud";
+		assigned-clocks = <&clk IMX_SC_R_M4_0_UART IMX_SC_PM_CLK_PER>;
+		assigned-clock-rates = <24000000>;
+		power-domains = <&pd IMX_SC_R_M4_0_UART>;
+		status = "disabled";
+	};
+
 	cm40_i2c: i2c@37230000 {
 		compatible = "fsl,imx8qxp-lpi2c", "fsl,imx7ulp-lpi2c";
 		reg = <0x37230000 0x1000>;
@@ -53,6 +65,18 @@ cm40_intmux: intmux@37400000 {
 		status = "disabled";
 	};
 
+	cm40_uart_lpcg: clock-controller@37620000 {
+		compatible = "fsl,imx8qxp-lpcg";
+		reg = <0x37620000 0x1000>;
+		#clock-cells = <1>;
+		clocks = <&clk IMX_SC_R_M4_0_UART IMX_SC_PM_CLK_PER>,
+			 <&cm40_ipg_clk>;
+		clock-indices = <IMX_LPCG_CLK_0>, <IMX_LPCG_CLK_1>;
+		clock-output-names = "cm40_lpcg_uart_clk",
+				     "cm40_lpcg_uart_ipg_clk";
+		power-domains = <&pd IMX_SC_R_M4_0_UART>;
+	};
+
 	cm40_i2c_lpcg: clock-controller@37630000 {
 		compatible = "fsl,imx8qxp-lpcg";
 		reg = <0x37630000 0x1000>;

-- 
2.34.1


^ permalink raw reply related

* [PATCH v5 1/4] arm64: dts: imx8: add cm40 subsystem dtsi
From: Frank Li @ 2024-04-02 14:41 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Shawn Guo,
	Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam
  Cc: devicetree, imx, linux-arm-kernel, linux-kernel, Frank Li,
	Dong Aisheng, Peng Fan, Alexander Stein
In-Reply-To: <20240402-m4_lpuart-v5-0-3292629ba808@nxp.com>

From: Dong Aisheng <aisheng.dong@nxp.com>

Add cm40 subsystem dtsi.

Reviewed-by: Peng Fan <peng.fan@nxp.com>
Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
Reviewed-by: Alexander Stein <alexander.stein@ew.tq-group.com>
Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
 arch/arm64/boot/dts/freescale/imx8-ss-cm40.dtsi | 67 +++++++++++++++++++++++++
 arch/arm64/boot/dts/freescale/imx8dxl.dtsi      |  2 +
 arch/arm64/boot/dts/freescale/imx8qxp.dtsi      |  1 +
 3 files changed, 70 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8-ss-cm40.dtsi b/arch/arm64/boot/dts/freescale/imx8-ss-cm40.dtsi
new file mode 100644
index 0000000000000..84d7ae01e5f40
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8-ss-cm40.dtsi
@@ -0,0 +1,67 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2024 NXP
+ *	Dong Aisheng <aisheng.dong@nxp.com>
+ */
+
+#include <dt-bindings/firmware/imx/rsrc.h>
+
+cm40_ipg_clk: clock-cm40-ipg {
+	compatible = "fixed-clock";
+	#clock-cells = <0>;
+	clock-frequency = <132000000>;
+	clock-output-names = "cm40_ipg_clk";
+};
+
+cm40_subsys: bus@34000000 {
+	compatible = "simple-bus";
+	#address-cells = <1>;
+	#size-cells = <1>;
+	ranges = <0x34000000 0x0 0x34000000 0x4000000>;
+	interrupt-parent = <&cm40_intmux>;
+
+	cm40_i2c: i2c@37230000 {
+		compatible = "fsl,imx8qxp-lpi2c", "fsl,imx7ulp-lpi2c";
+		reg = <0x37230000 0x1000>;
+		interrupts = <9 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cm40_i2c_lpcg IMX_LPCG_CLK_0>,
+			 <&cm40_i2c_lpcg IMX_LPCG_CLK_4>;
+		clock-names = "per", "ipg";
+		assigned-clocks = <&clk IMX_SC_R_M4_0_I2C IMX_SC_PM_CLK_PER>;
+		assigned-clock-rates = <24000000>;
+		power-domains = <&pd IMX_SC_R_M4_0_I2C>;
+		status = "disabled";
+	};
+
+	cm40_intmux: intmux@37400000 {
+		compatible = "fsl,imx-intmux";
+		reg = <0x37400000 0x1000>;
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		clocks = <&cm40_ipg_clk>;
+		clock-names = "ipg";
+		power-domains = <&pd IMX_SC_R_M4_0_INTMUX>;
+		status = "disabled";
+	};
+
+	cm40_i2c_lpcg: clock-controller@37630000 {
+		compatible = "fsl,imx8qxp-lpcg";
+		reg = <0x37630000 0x1000>;
+		#clock-cells = <1>;
+		clocks = <&clk IMX_SC_R_M4_0_I2C IMX_SC_PM_CLK_PER>,
+			 <&cm40_ipg_clk>;
+		clock-indices = <IMX_LPCG_CLK_0>, <IMX_LPCG_CLK_4>;
+		clock-output-names = "cm40_lpcg_i2c_clk",
+				     "cm40_lpcg_i2c_ipg_clk";
+		power-domains = <&pd IMX_SC_R_M4_0_I2C>;
+	};
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8dxl.dtsi b/arch/arm64/boot/dts/freescale/imx8dxl.dtsi
index a0674c5c55766..9d49c75a26222 100644
--- a/arch/arm64/boot/dts/freescale/imx8dxl.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8dxl.dtsi
@@ -5,6 +5,7 @@
 
 #include <dt-bindings/clock/imx8-clock.h>
 #include <dt-bindings/dma/fsl-edma.h>
+#include <dt-bindings/clock/imx8-lpcg.h>
 #include <dt-bindings/firmware/imx/rsrc.h>
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
@@ -231,6 +232,7 @@ xtal24m: clock-xtal24m {
 	};
 
 	/* sorted in register address */
+	#include "imx8-ss-cm40.dtsi"
 	#include "imx8-ss-adma.dtsi"
 	#include "imx8-ss-conn.dtsi"
 	#include "imx8-ss-ddr.dtsi"
diff --git a/arch/arm64/boot/dts/freescale/imx8qxp.dtsi b/arch/arm64/boot/dts/freescale/imx8qxp.dtsi
index 10e16d84c0c3b..0313f295de2e9 100644
--- a/arch/arm64/boot/dts/freescale/imx8qxp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8qxp.dtsi
@@ -317,6 +317,7 @@ map0 {
 	/* sorted in register address */
 	#include "imx8-ss-img.dtsi"
 	#include "imx8-ss-vpu.dtsi"
+	#include "imx8-ss-cm40.dtsi"
 	#include "imx8-ss-gpu0.dtsi"
 	#include "imx8-ss-adma.dtsi"
 	#include "imx8-ss-conn.dtsi"

-- 
2.34.1


^ permalink raw reply related

* [PATCH v5 0/4] arm64: dts: imx8: add cm40 and cm40_uart
From: Frank Li @ 2024-04-02 14:41 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Shawn Guo,
	Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam
  Cc: devicetree, imx, linux-arm-kernel, linux-kernel, Frank Li,
	Dong Aisheng, Peng Fan, Alexander Stein, Alice Guo

Add cm40 subsystem.
Add cm40_lpuart and lpurt1 for 8dxl evk boards.

Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
Changes in v5:
- update copyright year to 2024
- Link to v4: https://lore.kernel.org/r/20240329-m4_lpuart-v4-0-c11d9ca2a317@nxp.com

Changes in v4:
- fixed lpcg index.
- fixed typo 'informaiton'.
- fixed fixregulator name
- Link to v3: https://lore.kernel.org/r/20240305-m4_lpuart-v3-0-592463ef1d22@nxp.com

Changes in v3:
- Add Alexander review tags
- move interrupt-parent below range.
- move interrupt-parent before interrutps at intmux node
- Link to v2: https://lore.kernel.org/r/20240302-m4_lpuart-v2-0-89a5952043b6@nxp.com

Changes in v2:
- commit message "Adding" to Add
- fixed regulator@101 warning
- remove 'modem reset'
- order nodes by access
- move interrupt-parent under top bus
- clean up other dtb check warning
- Link to v1: https://lore.kernel.org/r/20240228-m4_lpuart-v1-0-9e6947be15e7@nxp.com

---
Alice Guo (1):
      arm64: dts: imx8dxl: add lpuart device in cm40 subsystem

Dong Aisheng (1):
      arm64: dts: imx8: add cm40 subsystem dtsi

Frank Li (2):
      arm64: dts: imx8dxl: update cm40 irq number information
      dts: arm64: imx8dxl-evk: add lpuart1 and cm40 uart

 arch/arm64/boot/dts/freescale/imx8-ss-cm40.dtsi | 91 +++++++++++++++++++++++++
 arch/arm64/boot/dts/freescale/imx8dxl-evk.dts   | 37 ++++++++++
 arch/arm64/boot/dts/freescale/imx8dxl.dtsi      | 13 ++++
 arch/arm64/boot/dts/freescale/imx8qxp.dtsi      |  1 +
 4 files changed, 142 insertions(+)
---
base-commit: 9acc053fc8f256959e849cb6588a054074daebcd
change-id: 20240228-m4_lpuart-30791c032f2a

Best regards,
---
Frank Li <Frank.Li@nxp.com>


^ permalink raw reply

* Re: [PATCH v3 9/9] arm64: dts: qcom: sm8150-hdk: rename Type-C HS endpoints
From: Konrad Dybcio @ 2024-04-02 14:41 UTC (permalink / raw)
  To: Dmitry Baryshkov, Bjorn Andersson, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Bryan O'Donoghue
  Cc: linux-arm-msm, devicetree, linux-kernel, Luca Weiss
In-Reply-To: <20240401-typec-fix-sm8250-v3-9-604dce3ad103@linaro.org>

On 1.04.2024 10:33 PM, Dmitry Baryshkov wrote:
> Follow other Qualcomm platforms and rename pm8150b_role_switch_in to
> pm8150_hs_in. Corresponding port is described as HS port rather than
> role switching.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---

Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>

Konrad

^ permalink raw reply

* Re: [PATCH v3 8/9] arm64: dts: qcom: x1e80100: describe USB signals properly
From: Konrad Dybcio @ 2024-04-02 14:41 UTC (permalink / raw)
  To: Dmitry Baryshkov, Bjorn Andersson, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Bryan O'Donoghue
  Cc: linux-arm-msm, devicetree, linux-kernel, Luca Weiss
In-Reply-To: <20240401-typec-fix-sm8250-v3-8-604dce3ad103@linaro.org>

On 1.04.2024 10:33 PM, Dmitry Baryshkov wrote:
> Follow example of other platforms. Rename HS graph nodes to contain
> 'dwc3_hs' and link SS lanes from DWC3 controllers to QMP PHYs.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---
>  arch/arm64/boot/dts/qcom/x1e80100.dtsi | 149 +++++++++++++++++++++++++++++++--
>  1 file changed, 141 insertions(+), 8 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/qcom/x1e80100.dtsi b/arch/arm64/boot/dts/qcom/x1e80100.dtsi
> index f5a3b39ae70e..3213eccc3a3a 100644
> --- a/arch/arm64/boot/dts/qcom/x1e80100.dtsi
> +++ b/arch/arm64/boot/dts/qcom/x1e80100.dtsi
> @@ -2543,6 +2543,33 @@ usb_1_ss0_qmpphy: phy@fd5000 {
>  			#phy-cells = <1>;
>  
>  			status = "disabled";
> +
> +			ports {
> +				#address-cells = <1>;
> +				#size-cells = <0>;
> +
> +				port@0 {
> +					reg = <0>;
> +
> +					usb_1_ss0_qmpphy_out: endpoint {
> +					};
> +				};
> +
> +				port@1 {
> +					reg = <1>;
> +
> +					usb_1_ss0_qmpphy_usb_ss_in: endpoint {
> +						remote-endpoint = <&usb_1_ss0_dwc3_ss>;
> +					};
> +				};
> +
> +				port@2 {
> +					reg = <2>;
> +
> +					usb_1_ss0_qmpphy_dp_in: endpoint {

This is more than just DP AFAIU, please call it SBU

Konrad

^ permalink raw reply

* Re: [PATCH v3 7/9] arm64: dts: qcom: sc8280xp: describe USB signals properly
From: Konrad Dybcio @ 2024-04-02 14:40 UTC (permalink / raw)
  To: Dmitry Baryshkov, Bjorn Andersson, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Bryan O'Donoghue
  Cc: linux-arm-msm, devicetree, linux-kernel, Luca Weiss
In-Reply-To: <20240401-typec-fix-sm8250-v3-7-604dce3ad103@linaro.org>

On 1.04.2024 10:33 PM, Dmitry Baryshkov wrote:
> Follow example of other platforms. Rename HS graph nodes to contain
> 'dwc3_hs' and link SS lanes from DWC3 controllers to QMP PHYs.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---

Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>

Konrad

^ permalink raw reply

* Re: [Patch v2 1/2] dt-bindings: make sid and broadcast reg optional
From: Rob Herring @ 2024-04-02 14:40 UTC (permalink / raw)
  To: Sumit Gupta
  Cc: amhetre, conor+dt, maz, mark.rutland, treding, devicetree, bbasu,
	jonathanh, linux-kernel, linux-tegra, krzysztof.kozlowski
In-Reply-To: <20240402132626.24693-2-sumitg@nvidia.com>


On Tue, 02 Apr 2024 18:56:25 +0530, Sumit Gupta wrote:
> MC SID and Broadbast channel register access is restricted for Guest VM.
> Make both the regions as optional for SoC's from Tegra186 onwards.
> Tegra MC driver will skip access to the restricted registers from Guest
> if the respective regions are not present in the memory-controller node
> of Guest DT.
> 
> Signed-off-by: Sumit Gupta <sumitg@nvidia.com>
> ---
>  .../memory-controllers/nvidia,tegra186-mc.yaml | 18 +++++++++---------
>  1 file changed, 9 insertions(+), 9 deletions(-)
> 

My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):

yamllint warnings/errors:

dtschema/dtc warnings/errors:
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra186-mc.example.dtb: memory-controller@2c00000: reg: [[0, 46137344, 0, 65536], [0, 46202880, 0, 65536], [0, 46268416, 0, 65536], [0, 46333952, 0, 65536], [0, 46399488, 0, 65536], [0, 46465024, 0, 65536]] is too long
	from schema $id: http://devicetree.org/schemas/memory-controllers/nvidia,tegra186-mc.yaml#
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra186-mc.example.dtb: memory-controller@2c00000: reg-names:0: 'ch0' was expected
	from schema $id: http://devicetree.org/schemas/memory-controllers/nvidia,tegra186-mc.yaml#
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra186-mc.example.dtb: memory-controller@2c00000: reg-names:1: 'ch1' was expected
	from schema $id: http://devicetree.org/schemas/memory-controllers/nvidia,tegra186-mc.yaml#
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra186-mc.example.dtb: memory-controller@2c00000: reg-names:2: 'ch2' was expected
	from schema $id: http://devicetree.org/schemas/memory-controllers/nvidia,tegra186-mc.yaml#
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra186-mc.example.dtb: memory-controller@2c00000: reg-names:3: 'ch3' was expected
	from schema $id: http://devicetree.org/schemas/memory-controllers/nvidia,tegra186-mc.yaml#
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra186-mc.example.dtb: memory-controller@2c00000: reg-names:4: 'sid' was expected
	from schema $id: http://devicetree.org/schemas/memory-controllers/nvidia,tegra186-mc.yaml#
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra186-mc.example.dtb: memory-controller@2c00000: reg-names:5: 'broadcast' was expected
	from schema $id: http://devicetree.org/schemas/memory-controllers/nvidia,tegra186-mc.yaml#

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20240402132626.24693-2-sumitg@nvidia.com

The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.


^ permalink raw reply

* Re: [PATCH v3 6/9] arm64: dts: qcom: sc8180x: describe USB signals properly
From: Konrad Dybcio @ 2024-04-02 14:39 UTC (permalink / raw)
  To: Dmitry Baryshkov, Bjorn Andersson, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Bryan O'Donoghue
  Cc: linux-arm-msm, devicetree, linux-kernel, Luca Weiss
In-Reply-To: <20240401-typec-fix-sm8250-v3-6-604dce3ad103@linaro.org>

On 1.04.2024 10:33 PM, Dmitry Baryshkov wrote:
> Follow example of other platforms. Rename HS graph nodes to contain
> 'dwc3_hs' and link SS lanes from DWC3 controllers to QMP PHYs.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---

Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>

Konrad

^ permalink raw reply

* Re: [PATCH v3 4/9] arm64: dts: qcom: sm8250: add a link between DWC3 and QMP PHY
From: Konrad Dybcio @ 2024-04-02 14:39 UTC (permalink / raw)
  To: Dmitry Baryshkov, Bjorn Andersson, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Bryan O'Donoghue
  Cc: linux-arm-msm, devicetree, linux-kernel, Luca Weiss
In-Reply-To: <20240401-typec-fix-sm8250-v3-4-604dce3ad103@linaro.org>

On 1.04.2024 10:33 PM, Dmitry Baryshkov wrote:
> The SuperSpeed signals originate from the DWC3 host controller and then
> are routed through the Combo QMP PHY, where they are multiplexed with
> the DisplayPort signals. Add corresponding OF graph link.
> 
> Reported-by: Luca Weiss <luca.weiss@fairphone.com>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---

Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>

Konrad

^ permalink raw reply

* Re: [PATCH v3 3/9] arm64: dts: qcom: sm8250: describe HS signals properly
From: Konrad Dybcio @ 2024-04-02 14:39 UTC (permalink / raw)
  To: Dmitry Baryshkov, Bjorn Andersson, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Bryan O'Donoghue
  Cc: linux-arm-msm, devicetree, linux-kernel, Luca Weiss
In-Reply-To: <20240401-typec-fix-sm8250-v3-3-604dce3ad103@linaro.org>

On 1.04.2024 10:33 PM, Dmitry Baryshkov wrote:
> The OF graph should describe physical signals. There is no 'role switch'
> signal between Type-C connector and the DWC3 USB controller. Instead
> there is a HighSpeed signal lane between DWC3 controller and the USB-C
> connector. Rename endpoints in accordance to that (this follows the
> example lead by other plaforms, including QRB2210 RB1, QRB4210 RB2 and
> all PMIC GLINK platforms).
> 
> Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---

Hot discussions aside, this is consistent with bindings, so:

Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>

Konrad

^ permalink raw reply

* Re: [PATCH v4 1/4] dt-bindings: arm: fsl: add NXP S32G3 board
From: Shawn Guo @ 2024-04-02 14:34 UTC (permalink / raw)
  To: Wadim Mueller
  Cc: Krzysztof Kozlowski, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Ulf Hansson, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, NXP Linux Team,
	Greg Kroah-Hartman, Jiri Slaby, Chester Lin, Andreas Färber,
	Matthias Brugger, NXP S32 Linux Team, Tim Harvey, Alexander Stein,
	Marek Vasut, Gregor Herburger, Hugo Villeneuve,
	Joao Paulo Goncalves, Markus Niebel, Marco Felsch,
	Matthias Schiffer, Stefan Wahren, Bjorn Helgaas, Josua Mayer,
	Li Yang, devicetree, linux-kernel, linux-mmc, linux-arm-kernel,
	linux-serial
In-Reply-To: <20240324214329.29988-2-wafgo01@gmail.com>

On Sun, Mar 24, 2024 at 10:43:23PM +0100, Wadim Mueller wrote:
> Add bindings for NXP S32G3 Reference Design Board 3 (S32G-VNP-RDB3) [1]
> 
> [1]
> https://www.nxp.com/design/design-center/designs/s32g3-vehicle-networking-reference-design:S32G-VNP-RDB3
> 
> Signed-off-by: Wadim Mueller <wafgo01@gmail.com>
> Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>

Applied, thanks!


^ permalink raw reply

* [PATCH] dt-bindings: timer: renesas,tmu: Add R-Car V4M support
From: Geert Uytterhoeven @ 2024-04-02 14:37 UTC (permalink / raw)
  To: Daniel Lezcano, Thomas Gleixner, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Laurent Pinchart
  Cc: devicetree, linux-renesas-soc, linux-kernel, Geert Uytterhoeven

Document support for the Timer Unit (TMU) in the Renesas R-Car V4M
(R8A779H0) SoC.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
 Documentation/devicetree/bindings/timer/renesas,tmu.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/timer/renesas,tmu.yaml b/Documentation/devicetree/bindings/timer/renesas,tmu.yaml
index 50b5225ceb10b64c..75b0e7c70b62c89f 100644
--- a/Documentation/devicetree/bindings/timer/renesas,tmu.yaml
+++ b/Documentation/devicetree/bindings/timer/renesas,tmu.yaml
@@ -50,6 +50,7 @@ properties:
           - renesas,tmu-r8a779a0 # R-Car V3U
           - renesas,tmu-r8a779f0 # R-Car S4-8
           - renesas,tmu-r8a779g0 # R-Car V4H
+          - renesas,tmu-r8a779h0 # R-Car V4M
       - const: renesas,tmu
 
   reg:
-- 
2.34.1


^ permalink raw reply related

* Re: [PATCH 1/3] dt-bindings: leds: add LED_FUNCTION_FNLOCK
From: Gergo Koteles @ 2024-04-02 14:36 UTC (permalink / raw)
  To: Krzysztof Kozlowski, Ike Panhc, Hans de Goede, Ilpo Järvinen,
	Pavel Machek, Lee Jones, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley
  Cc: platform-driver-x86, linux-kernel, linux-leds, devicetree
In-Reply-To: <6b47886e-09ac-4cb9-ab53-ca64f5320005@linaro.org>

Hi Krzysztof,

On Tue, 2024-04-02 at 15:55 +0200, Krzysztof Kozlowski wrote:
> 
> Do we really need to define all these possible LED functions? Please
> link to DTS user for this.
> 

I think for userspace it's easier to support an LED with a specified
name than to use various sysfs attributes. LED devices are easy to find
because they available are in the /sys/class/leds/ directory.
So I think it's a good thing to define LED names somewhere.

J Luke missed this LED from /sys/class/leds/, that's where the idea
came from. The scrollock, numlock, capslock and kbd_backlight LEDs are
already exported.

https://github.com/tomsom/yoga-linux/issues/58#issuecomment-2029926094

Best regards,
Gergo


^ permalink raw reply

* [PATCH] dt-bindings: timer: renesas,cmt: Add R-Car V4M support
From: Geert Uytterhoeven @ 2024-04-02 14:36 UTC (permalink / raw)
  To: Daniel Lezcano, Thomas Gleixner, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Laurent Pinchart
  Cc: devicetree, linux-renesas-soc, linux-kernel, Geert Uytterhoeven

Document support for the Compare Match Timer Type0 (CMT0) and Type1
(CMT1) in the Renesas R-Car V4M (R8A779H0) SoC.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
 Documentation/devicetree/bindings/timer/renesas,cmt.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/timer/renesas,cmt.yaml b/Documentation/devicetree/bindings/timer/renesas,cmt.yaml
index a0be1755ea28b996..5e09c04da30e47d5 100644
--- a/Documentation/devicetree/bindings/timer/renesas,cmt.yaml
+++ b/Documentation/devicetree/bindings/timer/renesas,cmt.yaml
@@ -103,6 +103,7 @@ properties:
               - renesas,r8a779a0-cmt0     # 32-bit CMT0 on R-Car V3U
               - renesas,r8a779f0-cmt0     # 32-bit CMT0 on R-Car S4-8
               - renesas,r8a779g0-cmt0     # 32-bit CMT0 on R-Car V4H
+              - renesas,r8a779h0-cmt0     # 32-bit CMT0 on R-Car V4M
           - const: renesas,rcar-gen4-cmt0 # 32-bit CMT0 on R-Car Gen4
 
       - items:
@@ -110,6 +111,7 @@ properties:
               - renesas,r8a779a0-cmt1     # 48-bit CMT on R-Car V3U
               - renesas,r8a779f0-cmt1     # 48-bit CMT on R-Car S4-8
               - renesas,r8a779g0-cmt1     # 48-bit CMT on R-Car V4H
+              - renesas,r8a779h0-cmt1     # 48-bit CMT on R-Car V4M
           - const: renesas,rcar-gen4-cmt1 # 48-bit CMT on R-Car Gen4
 
   reg:
-- 
2.34.1


^ permalink raw reply related

* Re: [PATCH v7 3/4] ASoc: PCM6240: Add compile item for PCM6240 Family driver
From: Dan Carpenter @ 2024-04-02 14:35 UTC (permalink / raw)
  To: oe-kbuild, Shenghao Ding, linux-kernel
  Cc: lkp, oe-kbuild-all, lgirdwood, broonie, robh+dt,
	krzysztof.kozlowski+dt, conor+dt, linux-sound, devicetree, perex,
	tiwai, 13916275206, mohit.chawla, soyer, jkhuang3, tiwai,
	pdjuandi, manisha.agrawal, s-hari, aviel, hnagalla, praneeth,
	Baojun.Xu, Shenghao Ding
In-Reply-To: <20240331021835.1470-4-shenghao-ding@ti.com>

Hi Shenghao,

kernel test robot noticed the following build warnings:

https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Shenghao-Ding/ASoc-PCM6240-Create-PCM6240-Family-driver-code/20240331-102303
base:   v6.9-rc1
patch link:    https://lore.kernel.org/r/20240331021835.1470-4-shenghao-ding%40ti.com
patch subject: [PATCH v7 3/4] ASoc: PCM6240: Add compile item for PCM6240 Family driver
config: um-randconfig-r081-20240402 (https://download.01.org/0day-ci/archive/20240402/202404021225.mx5KlUlV-lkp@intel.com/config)
compiler: gcc-7 (Ubuntu 7.5.0-6ubuntu2) 7.5.0

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
| Closes: https://lore.kernel.org/r/202404021225.mx5KlUlV-lkp@intel.com/

smatch warnings:
sound/soc/codecs/pcm6240.c:1715 pcmdevice_process_block() warn: inconsistent indenting

vim +/fw_entry +1577 sound/soc/codecs/pcm6240.c

051d749b6eaeb0 Shenghao Ding 2024-03-31  1619  static int pcmdevice_process_block(void *ctxt, unsigned char *data,
051d749b6eaeb0 Shenghao Ding 2024-03-31  1620  	unsigned char dev_idx, int sublocksize)
051d749b6eaeb0 Shenghao Ding 2024-03-31  1621  {
051d749b6eaeb0 Shenghao Ding 2024-03-31  1622  	struct pcmdevice_priv *pcm_dev = (struct pcmdevice_priv *)ctxt;
051d749b6eaeb0 Shenghao Ding 2024-03-31  1623  	int subblk_offset = 2, chn, chnend, ret;
051d749b6eaeb0 Shenghao Ding 2024-03-31  1624  	unsigned char subblk_typ = data[1];
051d749b6eaeb0 Shenghao Ding 2024-03-31  1625  
051d749b6eaeb0 Shenghao Ding 2024-03-31  1626  	if (dev_idx) {
051d749b6eaeb0 Shenghao Ding 2024-03-31  1627  		chn = dev_idx - 1;
051d749b6eaeb0 Shenghao Ding 2024-03-31  1628  		chnend = dev_idx;
051d749b6eaeb0 Shenghao Ding 2024-03-31  1629  	} else {
051d749b6eaeb0 Shenghao Ding 2024-03-31  1630  		chn = 0;
051d749b6eaeb0 Shenghao Ding 2024-03-31  1631  		chnend = pcm_dev->ndev;
051d749b6eaeb0 Shenghao Ding 2024-03-31  1632  	}
051d749b6eaeb0 Shenghao Ding 2024-03-31  1633  
051d749b6eaeb0 Shenghao Ding 2024-03-31  1634  	for (; chn < chnend; chn++) {
051d749b6eaeb0 Shenghao Ding 2024-03-31  1635  		switch (subblk_typ) {
051d749b6eaeb0 Shenghao Ding 2024-03-31  1636  		case PCMDEVICE_CMD_SING_W: {
051d749b6eaeb0 Shenghao Ding 2024-03-31  1637  			unsigned short len = get_unaligned_be16(&data[2]);
051d749b6eaeb0 Shenghao Ding 2024-03-31  1638  			int i = 0;
051d749b6eaeb0 Shenghao Ding 2024-03-31  1639  
051d749b6eaeb0 Shenghao Ding 2024-03-31  1640  			subblk_offset += 2;
051d749b6eaeb0 Shenghao Ding 2024-03-31  1641  			if (subblk_offset + 4 * len > sublocksize) {
051d749b6eaeb0 Shenghao Ding 2024-03-31  1642  				dev_err(pcm_dev->dev,
051d749b6eaeb0 Shenghao Ding 2024-03-31  1643  					"%s: byt wr out of boundary\n",
051d749b6eaeb0 Shenghao Ding 2024-03-31  1644  					__func__);
051d749b6eaeb0 Shenghao Ding 2024-03-31  1645  				break;
051d749b6eaeb0 Shenghao Ding 2024-03-31  1646  			}
051d749b6eaeb0 Shenghao Ding 2024-03-31  1647  
051d749b6eaeb0 Shenghao Ding 2024-03-31  1648  			for (i = 0; i < len; i++) {
051d749b6eaeb0 Shenghao Ding 2024-03-31  1649  				ret = pcmdev_dev_write(pcm_dev, chn,
051d749b6eaeb0 Shenghao Ding 2024-03-31  1650  					PCMDEVICE_REG(data[subblk_offset + 1],
051d749b6eaeb0 Shenghao Ding 2024-03-31  1651  						data[subblk_offset + 2]),
051d749b6eaeb0 Shenghao Ding 2024-03-31  1652  					data[subblk_offset + 3]);
051d749b6eaeb0 Shenghao Ding 2024-03-31  1653  				if (ret < 0)
051d749b6eaeb0 Shenghao Ding 2024-03-31  1654  					dev_err(pcm_dev->dev,
051d749b6eaeb0 Shenghao Ding 2024-03-31  1655  						"%s: single write error\n",
051d749b6eaeb0 Shenghao Ding 2024-03-31  1656  						__func__);
051d749b6eaeb0 Shenghao Ding 2024-03-31  1657  
051d749b6eaeb0 Shenghao Ding 2024-03-31  1658  				subblk_offset += 4;
051d749b6eaeb0 Shenghao Ding 2024-03-31  1659  			}
051d749b6eaeb0 Shenghao Ding 2024-03-31  1660  		}
051d749b6eaeb0 Shenghao Ding 2024-03-31  1661  		break;
051d749b6eaeb0 Shenghao Ding 2024-03-31  1662  		case PCMDEVICE_CMD_BURST: {
051d749b6eaeb0 Shenghao Ding 2024-03-31  1663  			unsigned short len = get_unaligned_be16(&data[2]);
051d749b6eaeb0 Shenghao Ding 2024-03-31  1664  
051d749b6eaeb0 Shenghao Ding 2024-03-31  1665  			subblk_offset += 2;
051d749b6eaeb0 Shenghao Ding 2024-03-31  1666  			if (subblk_offset + 4 + len > sublocksize) {
051d749b6eaeb0 Shenghao Ding 2024-03-31  1667  				dev_err(pcm_dev->dev,
051d749b6eaeb0 Shenghao Ding 2024-03-31  1668  					"%s: burst Out of boundary\n",
051d749b6eaeb0 Shenghao Ding 2024-03-31  1669  					__func__);
051d749b6eaeb0 Shenghao Ding 2024-03-31  1670  				break;
051d749b6eaeb0 Shenghao Ding 2024-03-31  1671  			}
051d749b6eaeb0 Shenghao Ding 2024-03-31  1672  			if (len % 4) {
051d749b6eaeb0 Shenghao Ding 2024-03-31  1673  				dev_err(pcm_dev->dev,
051d749b6eaeb0 Shenghao Ding 2024-03-31  1674  					"%s: burst-len(%u) not div by 4\n",
051d749b6eaeb0 Shenghao Ding 2024-03-31  1675  					__func__, len);
051d749b6eaeb0 Shenghao Ding 2024-03-31  1676  				break;
051d749b6eaeb0 Shenghao Ding 2024-03-31  1677  			}
051d749b6eaeb0 Shenghao Ding 2024-03-31  1678  			ret = pcmdev_dev_bulk_write(pcm_dev, chn,
051d749b6eaeb0 Shenghao Ding 2024-03-31  1679  				PCMDEVICE_REG(data[subblk_offset + 1],
051d749b6eaeb0 Shenghao Ding 2024-03-31  1680  				data[subblk_offset + 2]),
051d749b6eaeb0 Shenghao Ding 2024-03-31  1681  				&(data[subblk_offset + 4]), len);
051d749b6eaeb0 Shenghao Ding 2024-03-31  1682  			if (ret < 0)
051d749b6eaeb0 Shenghao Ding 2024-03-31  1683  				dev_err(pcm_dev->dev,
051d749b6eaeb0 Shenghao Ding 2024-03-31  1684  					"%s: bulk_write err = %d\n",
051d749b6eaeb0 Shenghao Ding 2024-03-31  1685  					__func__, ret);
051d749b6eaeb0 Shenghao Ding 2024-03-31  1686  
051d749b6eaeb0 Shenghao Ding 2024-03-31  1687  			subblk_offset += (len + 4);
051d749b6eaeb0 Shenghao Ding 2024-03-31  1688  		}
051d749b6eaeb0 Shenghao Ding 2024-03-31  1689  			break;
051d749b6eaeb0 Shenghao Ding 2024-03-31  1690  		case PCMDEVICE_CMD_DELAY: {
051d749b6eaeb0 Shenghao Ding 2024-03-31  1691  			unsigned int delay_time = 0;
051d749b6eaeb0 Shenghao Ding 2024-03-31  1692  
051d749b6eaeb0 Shenghao Ding 2024-03-31  1693  			if (subblk_offset + 2 > sublocksize) {
051d749b6eaeb0 Shenghao Ding 2024-03-31  1694  				dev_err(pcm_dev->dev,
051d749b6eaeb0 Shenghao Ding 2024-03-31  1695  					"%s: deley out of boundary\n",
051d749b6eaeb0 Shenghao Ding 2024-03-31  1696  					__func__);
051d749b6eaeb0 Shenghao Ding 2024-03-31  1697  				break;
051d749b6eaeb0 Shenghao Ding 2024-03-31  1698  			}
051d749b6eaeb0 Shenghao Ding 2024-03-31  1699  			delay_time = get_unaligned_be16(&data[2]) * 1000;
051d749b6eaeb0 Shenghao Ding 2024-03-31  1700  			usleep_range(delay_time, delay_time + 50);
051d749b6eaeb0 Shenghao Ding 2024-03-31  1701  			subblk_offset += 2;
051d749b6eaeb0 Shenghao Ding 2024-03-31  1702  		}
051d749b6eaeb0 Shenghao Ding 2024-03-31  1703  			break;
051d749b6eaeb0 Shenghao Ding 2024-03-31  1704  		case PCMDEVICE_CMD_FIELD_W:
051d749b6eaeb0 Shenghao Ding 2024-03-31  1705  		if (subblk_offset + 6 > sublocksize) {
051d749b6eaeb0 Shenghao Ding 2024-03-31  1706  			dev_err(pcm_dev->dev,
051d749b6eaeb0 Shenghao Ding 2024-03-31  1707  				"%s: bit write out of memory\n", __func__);
051d749b6eaeb0 Shenghao Ding 2024-03-31  1708  			break;
051d749b6eaeb0 Shenghao Ding 2024-03-31  1709  		}
051d749b6eaeb0 Shenghao Ding 2024-03-31  1710  			ret = pcmdev_dev_update_bits(pcm_dev, chn,
051d749b6eaeb0 Shenghao Ding 2024-03-31  1711  				PCMDEVICE_REG(data[subblk_offset + 3],
051d749b6eaeb0 Shenghao Ding 2024-03-31  1712  				data[subblk_offset + 4]),
051d749b6eaeb0 Shenghao Ding 2024-03-31  1713  				data[subblk_offset + 1],
051d749b6eaeb0 Shenghao Ding 2024-03-31  1714  				data[subblk_offset + 5]);

This line is indented too far.

051d749b6eaeb0 Shenghao Ding 2024-03-31 @1715  		if (ret < 0)
051d749b6eaeb0 Shenghao Ding 2024-03-31  1716  			dev_err(pcm_dev->dev, "%s: update_bits err = %d\n",
051d749b6eaeb0 Shenghao Ding 2024-03-31  1717  				__func__, ret);
051d749b6eaeb0 Shenghao Ding 2024-03-31  1718  
051d749b6eaeb0 Shenghao Ding 2024-03-31  1719  		subblk_offset += 6;
051d749b6eaeb0 Shenghao Ding 2024-03-31  1720  			break;
051d749b6eaeb0 Shenghao Ding 2024-03-31  1721  		default:
051d749b6eaeb0 Shenghao Ding 2024-03-31  1722  			break;
051d749b6eaeb0 Shenghao Ding 2024-03-31  1723  		}
051d749b6eaeb0 Shenghao Ding 2024-03-31  1724  	}
051d749b6eaeb0 Shenghao Ding 2024-03-31  1725  
051d749b6eaeb0 Shenghao Ding 2024-03-31  1726  	return subblk_offset;
051d749b6eaeb0 Shenghao Ding 2024-03-31  1727  }

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


^ permalink raw reply

* RE: [PATCH v6 3/4] firmware: arm_scmi: Add SCMI v3.2 pincontrol protocol basic support
From: Peng Fan @ 2024-04-02 14:35 UTC (permalink / raw)
  To: Andy Shevchenko, Cristian Marussi
  Cc: Peng Fan (OSS), Sudeep Holla, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Linus Walleij, Dan Carpenter,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, devicetree@vger.kernel.org,
	linux-gpio@vger.kernel.org, Oleksii Moisieiev
In-Reply-To: <DU0PR04MB94172B29B33AC0002CF6991B883E2@DU0PR04MB9417.eurprd04.prod.outlook.com>

Hi Andy,

> Subject: RE: [PATCH v6 3/4] firmware: arm_scmi: Add SCMI v3.2 pincontrol
> protocol basic support
> 
> > Subject: Re: [PATCH v6 3/4] firmware: arm_scmi: Add SCMI v3.2
> > pincontrol protocol basic support
> >
> > On Tue, Apr 2, 2024 at 10:48 AM Cristian Marussi
> > <cristian.marussi@arm.com> wrote:
> > > On Sun, Mar 31, 2024 at 01:44:28PM +0000, Peng Fan wrote:
> > > > > Sat, Mar 23, 2024 at 08:15:16PM +0800, Peng Fan (OSS) kirjoitti:
> >
> > ...
> >
> > > > > > +#include <linux/module.h>
> > > > > > +#include <linux/scmi_protocol.h> #include <linux/slab.h>
> > > > >
> > > > > This is semi-random list of headers. Please, follow IWYU
> > > > > principle (include what you use). There are a lot of inclusions
> > > > > I see missing (just in the context of this page I see bits.h,
> > > > > types.h, and
> > asm/byteorder.h).
> > > >
> > > > Is there any documentation about this requirement?
> > > > Some headers are already included by others.
> >
> > The documentation here is called "a common sense".
> > The C language is built like this and we expect that nobody will
> > invest into the dependency hell that we have already, that's why IWYU
> > principle, please follow it.
> >
> > > Andy made (mostly) the same remarks on this same patch ~1-year ago
> > > on this same patch while it was posted by Oleksii.
> > >
> > > And I told that time that most of the remarks around devm_ usage
> > > were wrong due to how the SCMI core handles protocol initialization
> > > (using a devres group transparently).
> > >
> > > This is what I answered that time.
> > >
> > > https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Flo
> > > re
> > > .kernel.org%2Flinux-arm-kernel%2FZJ78hBcjAhiU%2BZBO%40e120937-
> > lin%2F%2
> > >
> >
> 3t&data=05%7C02%7Cpeng.fan%40nxp.com%7C3f8c12062db048608e2a08d
> > c5315bed
> > >
> >
> 0%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C6384766000583
> > 40430%7CUn
> > >
> >
> known%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6I
> > k1haW
> > >
> >
> wiLCJXVCI6Mn0%3D%7C0%7C%7C%7C&sdata=Whn3ehZjXy%2BcKG4irlWjQ6
> > K3HF%2FofD
> > > Yu7j0Lrm8dN5k%3D&reserved=0
> > >
> > > I wont repeat myself, but, in a nutshell the memory allocation like
> > > it is now is fine: a bit happens via devm_ at protocol
> > > initialization, the other is doe via explicit kmalloc at runtime and
> > > freed via kfree at remove time (if needed...i.e. checking the
> > > present flag of some
> > > structs)
> >
> > This sounds like a mess. devm_ is expected to be used only for the
> > ->probe() stage, otherwise you may consider cleanup.h (__free() macro)
> > to have automatic free at the paths where memory is not needed.
> >
> > And the function naming doesn't suggest that you have a probe-remove
> pair.
> > Moreover, if the init-deinit part is called in the probe-remove, the
> > devm_ must not be mixed with non-devm ones, as it breaks the order and
> > leads to subtle mistakes.
> 
> I am new to __free() honestly. I'll let Cristian and Sudeep to comment on
> what should I do for v8.

Just give a look. But since most scmi firmware drivers are using
devm_x APIs in protocol init. I would follow the style to use
devm_x as of now.

And for pinctrl protocol deinit phase, I will add a comment on why
use kfree and what it is to free.

For the __free macro, people drop all the scmi firmware drivers
using devm_x APIs in init phase in a future patch.

Is this ok?

Thanks,
Peng.

> 
> Thanks,
> Peng.
> 
> >
> > > I'll made further remarks on v7 that you just posted.
> >
> > --
> > With Best Regards,
> > Andy Shevchenko

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox