Devicetree
 help / color / mirror / Atom feed
* Re: [PATCH 1/3] ARM: dra762: hwmod: Add MCAN support
From: Tony Lindgren @ 2018-05-15 17:18 UTC (permalink / raw)
  To: Faiz Abbas
  Cc: linux-kernel, linux-omap, devicetree, bcousson, robh+dt,
	mark.rutland, paul, lokeshvutla, linux
In-Reply-To: <20180515171459.GP98604@atomide.com>

* Tony Lindgren <tony@atomide.com> [180515 17:17]:
> * Faiz Abbas <faiz_abbas@ti.com> [180515 06:05]:
> > Hi Tony,
> > 
> > On Tuesday 01 May 2018 08:56 PM, Tony Lindgren wrote:
> > > Hi,
> > > 
> > > * Faiz Abbas <faiz_abbas@ti.com> [180408 09:59]:
> > >> From: Lokesh Vutla <lokeshvutla@ti.com>
> > >>
> > >> Add MCAN hwmod data and register it for dra762 silicons.
> > >>
> > >> Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com>
> > >> Signed-off-by: Faiz Abbas <faiz_abbas@ti.com>
> > >> ---
> > >>  arch/arm/mach-omap2/omap_hwmod_7xx_data.c | 32 +++++++++++++++++++++++++++++++
> > >>  1 file changed, 32 insertions(+)
> > >>
> > >> diff --git a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c
> > >> index 62352d1..a2cd7f8 100644
> > >> --- a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c
> > >> +++ b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c
> > >> @@ -1356,6 +1356,29 @@ static struct omap_hwmod dra7xx_mailbox13_hwmod = {
> > >>  };
> > >>  
> > >>  /*
> > >> + * 'mcan' class
> > >> + *
> > >> + */
> > >> +static struct omap_hwmod_class dra76x_mcan_hwmod_class = {
> > >> +	.name	= "mcan",
> > >> +};
> > > 
> > > Looks like you're missing the related struct omap_hwmod_class_sysconfig
> > > entry for this with the rev and sysconfig registers.
> > > 
> > 
> > Sorry, I missed this email earlier. The MCAN module doesn't have
> > sysconfig registers.
> 
> If there's no sysconfig register you should have no need for adding
> anything to omap_hwmod_7xx_data.c. We now have the dts clkctrl
> clocks, you can just add that to the dts node for the device.

However.. My guess is there is somewhere a top level interconnect
target module that uses DRA7XX_CM_WKUPAON_ADC_CLKCTRL. And that
module may have multiple child devices.

Regards,

Tony

^ permalink raw reply

* Re: [PATCH 2/3] ARM: dts: dra762: Add MCAN clock support
From: Tony Lindgren @ 2018-05-15 17:16 UTC (permalink / raw)
  To: Faiz Abbas
  Cc: linux-kernel, linux-omap, devicetree, bcousson, robh+dt,
	mark.rutland, paul, lokeshvutla, linux, Tero Kristo
In-Reply-To: <1523181542-3770-3-git-send-email-faiz_abbas@ti.com>

* Faiz Abbas <faiz_abbas@ti.com> [180408 09:59]:
> From: Lokesh Vutla <lokeshvutla@ti.com>
> 
> MCAN is clocked by H14 divider of DPLL_GMAC. Unlike other
> DPLL dividers this DPLL_GMAC H14 divider is controlled by
> control module. Adding support for these clocks.

Adding Tero to Cc on this one.

> Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com>
> Signed-off-by: Faiz Abbas <faiz_abbas@ti.com>
> ---
>  arch/arm/boot/dts/dra76x.dtsi | 33 +++++++++++++++++++++++++++++++++
>  1 file changed, 33 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/dra76x.dtsi b/arch/arm/boot/dts/dra76x.dtsi
> index 1c88c58..bfc8263 100644
> --- a/arch/arm/boot/dts/dra76x.dtsi
> +++ b/arch/arm/boot/dts/dra76x.dtsi
> @@ -17,3 +17,36 @@
>  &crossbar_mpu {
>  	ti,irqs-skip = <10 67 68 133 139 140>;
>  };
> +
> +&scm_conf_clocks {
> +	dpll_gmac_h14x2_ctrl_ck: dpll_gmac_h14x2_ctrl_ck@3fc {
> +		#clock-cells = <0>;
> +		compatible = "ti,divider-clock";
> +		clocks = <&dpll_gmac_x2_ck>;
> +		ti,max-div = <63>;
> +		reg = <0x03fc>;
> +		ti,bit-shift=<20>;
> +		ti,latch-bit=<26>;
> +		assigned-clocks = <&dpll_gmac_h14x2_ctrl_ck>;
> +		assigned-clock-rates = <80000000>;
> +	};
> +
> +	dpll_gmac_h14x2_ctrl_mux_ck: dpll_gmac_h14x2_ctrl_mux_ck@3fc {
> +		#clock-cells = <0>;
> +		compatible = "ti,mux-clock";
> +		clocks = <&dpll_gmac_ck>, <&dpll_gmac_h14x2_ctrl_ck>;
> +		reg = <0x3fc>;
> +		ti,bit-shift = <29>;
> +		ti,latch-bit=<26>;
> +		assigned-clocks = <&dpll_gmac_h14x2_ctrl_mux_ck>;
> +		assigned-clock-parents = <&dpll_gmac_h14x2_ctrl_ck>;
> +	};
> +
> +	mcan_clk: mcan_clk@3fc {
> +		#clock-cells = <0>;
> +		compatible = "ti,gate-clock";
> +		clocks = <&dpll_gmac_h14x2_ctrl_mux_ck>;
> +		ti,bit-shift = <27>;
> +		reg = <0x3fc>;
> +	};
> +};
> -- 
> 2.7.4
> 

^ permalink raw reply

* Re: [PATCH 1/3] ARM: dra762: hwmod: Add MCAN support
From: Tony Lindgren @ 2018-05-15 17:14 UTC (permalink / raw)
  To: Faiz Abbas
  Cc: linux-kernel, linux-omap, devicetree, bcousson, robh+dt,
	mark.rutland, paul, lokeshvutla, linux
In-Reply-To: <b4d95a08-82fd-9f39-53e7-977351788c88@ti.com>

* Faiz Abbas <faiz_abbas@ti.com> [180515 06:05]:
> Hi Tony,
> 
> On Tuesday 01 May 2018 08:56 PM, Tony Lindgren wrote:
> > Hi,
> > 
> > * Faiz Abbas <faiz_abbas@ti.com> [180408 09:59]:
> >> From: Lokesh Vutla <lokeshvutla@ti.com>
> >>
> >> Add MCAN hwmod data and register it for dra762 silicons.
> >>
> >> Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com>
> >> Signed-off-by: Faiz Abbas <faiz_abbas@ti.com>
> >> ---
> >>  arch/arm/mach-omap2/omap_hwmod_7xx_data.c | 32 +++++++++++++++++++++++++++++++
> >>  1 file changed, 32 insertions(+)
> >>
> >> diff --git a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c
> >> index 62352d1..a2cd7f8 100644
> >> --- a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c
> >> +++ b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c
> >> @@ -1356,6 +1356,29 @@ static struct omap_hwmod dra7xx_mailbox13_hwmod = {
> >>  };
> >>  
> >>  /*
> >> + * 'mcan' class
> >> + *
> >> + */
> >> +static struct omap_hwmod_class dra76x_mcan_hwmod_class = {
> >> +	.name	= "mcan",
> >> +};
> > 
> > Looks like you're missing the related struct omap_hwmod_class_sysconfig
> > entry for this with the rev and sysconfig registers.
> > 
> 
> Sorry, I missed this email earlier. The MCAN module doesn't have
> sysconfig registers.

If there's no sysconfig register you should have no need for adding
anything to omap_hwmod_7xx_data.c. We now have the dts clkctrl
clocks, you can just add that to the dts node for the device.

Regards,

Tony

^ permalink raw reply

* Re: [PATCH v9 07/11] arm64: kexec_file: add crash dump support
From: James Morse @ 2018-05-15 17:12 UTC (permalink / raw)
  To: AKASHI Takahiro
  Cc: catalin.marinas, will.deacon, dhowells, vgoyal, herbert, davem,
	dyoung, bhe, arnd, ard.biesheuvel, bhsharma, kexec,
	linux-arm-kernel, linux-kernel, devicetree, Rob Herring
In-Reply-To: <20180425062629.29404-8-takahiro.akashi@linaro.org>

Hi guys,

(CC: +RobH, devicetree list)

On 25/04/18 07:26, AKASHI Takahiro wrote:
> Enabling crash dump (kdump) includes
> * prepare contents of ELF header of a core dump file, /proc/vmcore,
>   using crash_prepare_elf64_headers(), and
> * add two device tree properties, "linux,usable-memory-range" and
>   "linux,elfcorehdr", which represent repsectively a memory range
>   to be used by crash dump kernel and the header's location

kexec_file_load() on arm64 needs to be able to create a prop encoded array to
the FDT, but there doesn't appear to be a libfdt helper to do this.

Akashi's code below adds fdt_setprop_range() to the arch code, and duplicates
bits of libfdt_internal.h to do the work.

How should this be done? I'm assuming this is something we need a new API in
libfdt.h for. How do these come about, and is there an interim step we can use
until then?

Thanks!

James

> diff --git a/arch/arm64/kernel/machine_kexec_file.c b/arch/arm64/kernel/machine_kexec_file.c
> index 37c0a9dc2e47..ec674f4d267c 100644
> --- a/arch/arm64/kernel/machine_kexec_file.c
> +++ b/arch/arm64/kernel/machine_kexec_file.c
> @@ -76,6 +81,78 @@ int arch_kexec_walk_mem(struct kexec_buf *kbuf,
>  	return ret;
>  }
>  
> +static int __init arch_kexec_file_init(void)
> +{
> +	/* Those values are used later on loading the kernel */
> +	__dt_root_addr_cells = dt_root_addr_cells;
> +	__dt_root_size_cells = dt_root_size_cells;
> +
> +	return 0;
> +}
> +late_initcall(arch_kexec_file_init);
> +
> +#define FDT_ALIGN(x, a)	(((x) + (a) - 1) & ~((a) - 1))
> +#define FDT_TAGALIGN(x)	(FDT_ALIGN((x), FDT_TAGSIZE))
> +
> +static int fdt_prop_len(const char *prop_name, int len)
> +{
> +	return (strlen(prop_name) + 1) +
> +		sizeof(struct fdt_property) +
> +		FDT_TAGALIGN(len);
> +}
> +
> +static bool cells_size_fitted(unsigned long base, unsigned long size)
> +{
> +	/* if *_cells >= 2, cells can hold 64-bit values anyway */
> +	if ((__dt_root_addr_cells == 1) && (base >= (1ULL << 32)))
> +		return false;
> +
> +	if ((__dt_root_size_cells == 1) && (size >= (1ULL << 32)))
> +		return false;
> +
> +	return true;
> +}
> +
> +static void fill_property(void *buf, u64 val64, int cells)
> +{
> +	u32 val32;
> +
> +	if (cells == 1) {
> +		val32 = cpu_to_fdt32((u32)val64);
> +		memcpy(buf, &val32, sizeof(val32));
> +	} else {
> +		memset(buf, 0, cells * sizeof(u32) - sizeof(u64));
> +		buf += cells * sizeof(u32) - sizeof(u64);
> +
> +		val64 = cpu_to_fdt64(val64);
> +		memcpy(buf, &val64, sizeof(val64));
> +	}
> +}
> +
> +static int fdt_setprop_range(void *fdt, int nodeoffset, const char *name,
> +				unsigned long addr, unsigned long size)
> +{
> +	void *buf, *prop;
> +	size_t buf_size;
> +	int result;
> +
> +	buf_size = (__dt_root_addr_cells + __dt_root_size_cells) * sizeof(u32);
> +	prop = buf = vmalloc(buf_size);
> +	if (!buf)
> +		return -ENOMEM;
> +
> +	fill_property(prop, addr, __dt_root_addr_cells);
> +	prop += __dt_root_addr_cells * sizeof(u32);
> +
> +	fill_property(prop, size, __dt_root_size_cells);
> +
> +	result = fdt_setprop(fdt, nodeoffset, name, buf, buf_size);
> +
> +	vfree(buf);
> +
> +	return result;
> +}
> +
>  static int setup_dtb(struct kimage *image,
>  		unsigned long initrd_load_addr, unsigned long initrd_len,
>  		char *cmdline, unsigned long cmdline_len,
> @@ -88,10 +165,26 @@ static int setup_dtb(struct kimage *image,
>  	int range_len;
>  	int ret;
>  
> +	/* check ranges against root's #address-cells and #size-cells */
> +	if (image->type == KEXEC_TYPE_CRASH &&
> +		(!cells_size_fitted(image->arch.elf_load_addr,
> +				image->arch.elf_headers_sz) ||
> +		 !cells_size_fitted(crashk_res.start,
> +				crashk_res.end - crashk_res.start + 1))) {
> +		pr_err("Crash memory region doesn't fit into DT's root cell sizes.\n");
> +		ret = -EINVAL;
> +		goto out_err;
> +	}
> +
>  	/* duplicate dt blob */
>  	buf_size = fdt_totalsize(initial_boot_params);
>  	range_len = (__dt_root_addr_cells + __dt_root_size_cells) * sizeof(u32);
>  
> +	if (image->type == KEXEC_TYPE_CRASH)
> +		buf_size += fdt_prop_len("linux,elfcorehdr", range_len)
> +				+ fdt_prop_len("linux,usable-memory-range",
> +								range_len);
> +
>  	if (initrd_load_addr)
>  		buf_size += fdt_prop_len("linux,initrd-start", sizeof(u64))
>  				+ fdt_prop_len("linux,initrd-end", sizeof(u64));
> @@ -113,6 +206,23 @@ static int setup_dtb(struct kimage *image,
>  	if (nodeoffset < 0)
>  		goto out_err;
>  
> +	if (image->type == KEXEC_TYPE_CRASH) {
> +		/* add linux,elfcorehdr */
> +		ret = fdt_setprop_range(buf, nodeoffset, "linux,elfcorehdr",
> +				image->arch.elf_load_addr,
> +				image->arch.elf_headers_sz);
> +		if (ret)
> +			goto out_err;
> +
> +		/* add linux,usable-memory-range */
> +		ret = fdt_setprop_range(buf, nodeoffset,
> +				"linux,usable-memory-range",
> +				crashk_res.start,
> +				crashk_res.end - crashk_res.start + 1);
> +		if (ret)
> +			goto out_err;
> +	}
> +
>  	/* add bootargs */
>  	if (cmdline) {
>  		ret = fdt_setprop(buf, nodeoffset, "bootargs",

^ permalink raw reply

* Re: [PATCH] clk: rockchip: remove deprecated gate-clk code and dt-binding
From: Stephen Boyd @ 2018-05-15 16:57 UTC (permalink / raw)
  To: mturquette-rdvid1DuHRBWk0Htik3J/w
  Cc: mark.rutland-5wv7dgnIgG8, devicetree-u79uwXL29TY76Z2rM5mHXA,
	Heiko Stuebner, linux-rockchip-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, linux-clk-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20180512143038.30447-1-heiko-4mtYJXux2i+zQB+pC5nmwQ@public.gmane.org>

Quoting Heiko Stuebner (2018-05-12 07:30:38)
> Initially we tried modeling clocks via the devicetree before switching
> to clocks declared in the clock drivers and only exporting specific
> ids to the devicetree.
> 
> As the old code was in the kernel for 1-2 releases when the new mode
> of operation was added we kept it for backwards compatibility.
> 
> That deprecation notice is in the binding since july 2014, so nearly
> 4 years now and I think it's time to drop the old cruft.
> 
> Especially as at the time using the mainline kernel on Rockchip devices
> was not really possible, except for experiments on the really old socs of
> the rk3066 + rk3188 line, so there shouldn't be any devicetrees still
> around that rely on that code.
> 
> Signed-off-by: Heiko Stuebner <heiko-4mtYJXux2i+zQB+pC5nmwQ@public.gmane.org>
> ---

Alright, let's see how things go.

Acked-by: Stephen Boyd <sboyd-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>

^ permalink raw reply

* Re: [RESEND PATCH v2 1/1] net: phy: micrel: add 125MHz reference clock workaround
From: Andrew Lunn @ 2018-05-15 16:33 UTC (permalink / raw)
  To: Marco Felsch
  Cc: robh+dt, mark.rutland, f.fainelli, netdev, devicetree, kernel,
	niebelm
In-Reply-To: <20180515081856.23322-2-m.felsch@pengutronix.de>

On Tue, May 15, 2018 at 10:18:56AM +0200, Marco Felsch wrote:
> From: Markus Niebel <Markus.Niebel@tqs.de>
> 
> The micrel KSZ9031 phy has a optional clock pin (CLK125_NDO) which can be
> used as reference clock for the MAC unit. The clock signal must meet the
> RGMII requirements to ensure the correct data transmission between the
> MAC and the PHY. The KSZ9031 phy does not fulfill the duty cycle
> requirement if the phy is configured as slave. For a complete
> describtion look at the errata sheets: DS80000691D or DS80000692D.
> 
> The errata sheet recommends to force the phy into master mode whenever
> there is a 1000Base-T link-up as work around. Only set the
> "micrel,force-master" property if you use the phy reference clock provided
> by CLK125_NDO pin as MAC reference clock in your application.
> 
> Attenation, this workaround is only usable if the link partner can
> be configured to slave mode for 1000Base-T.

Thanks for adding all the documentation.

Reviewed-by: Andrew Lunn <andrew@lunn.ch>

    Andrew

^ permalink raw reply

* RE: [PATCH V2 8/8] dt-bindings: stm32: add compatible for syscon
From: Christophe ROULLIER @ 2018-05-15 16:19 UTC (permalink / raw)
  To: Rob Herring
  Cc: mark.rutland@arm.com, andrew@lunn.ch, Alexandre TORGUE,
	devicetree@vger.kernel.org, netdev@vger.kernel.org,
	mcoquelin.stm32@gmail.com, Peppe CAVALLARO,
	linux-arm-kernel@lists.infradead.org
In-Reply-To: <20180507163537.GA15212@rob-hp-laptop>

Hi Rob,

I do not understand, so let me explain our status:

We have syscfg IP Harware in our SOC. 
But we do not have SoC specific driver to manage syscfg, we are using a generic driver "syscon".
So can you tell me what you wish to describe this part in our SOC bindings ?

Thanks for your help.

Christophe.

-----Original Message-----
From: Rob Herring [mailto:robh@kernel.org] 
Sent: lundi 7 mai 2018 18:36
To: Christophe ROULLIER <christophe.roullier@st.com>
Cc: mark.rutland@arm.com; mcoquelin.stm32@gmail.com; Alexandre TORGUE <alexandre.torgue@st.com>; Peppe CAVALLARO <peppe.cavallaro@st.com>; devicetree@vger.kernel.org; andrew@lunn.ch; linux-arm-kernel@lists.infradead.org; netdev@vger.kernel.org
Subject: Re: [PATCH V2 8/8] dt-bindings: stm32: add compatible for syscon

On Wed, May 02, 2018 at 04:18:43PM +0200, Christophe Roullier wrote:
> This patch describes syscon DT bindings.
> 
> Signed-off-by: Christophe Roullier <christophe.roullier@st.com>
> ---
>  Documentation/devicetree/bindings/arm/stm32.txt | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/arm/stm32.txt 
> b/Documentation/devicetree/bindings/arm/stm32.txt
> index 6808ed9..06e3834 100644
> --- a/Documentation/devicetree/bindings/arm/stm32.txt
> +++ b/Documentation/devicetree/bindings/arm/stm32.txt
> @@ -8,3 +8,7 @@ using one of the following compatible strings:
>    st,stm32f746
>    st,stm32h743
>    st,stm32mp157
> +
> +Required nodes:
> +- syscon: the soc bus node must have a system controller node 
> +pointing to the
> +  global control registers, with the compatible string "syscon";

You misunderstood my prior comment. 'syscon' alone is not valid. You need SoC specific compatible string for it and 'stm32' is not SoC specific. IOW, the compatible property for a syscon should imply every single register field in the block.

Rob

^ permalink raw reply

* Re: [PATCH/RFT v3 1/3] thermal: rcar_thermal: add r8a77995 support
From: Yoshihiro Kaneko @ 2018-05-15 16:03 UTC (permalink / raw)
  To: Simon Horman
  Cc: Eduardo Valentin, Rob Herring, Zhang Rui,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Linux PM list, Linux-Renesas
In-Reply-To: <20180515072618.r6ag2qe5c4xensqj@verge.net.au>

2018-05-15 16:26 GMT+09:00 Simon Horman <horms@verge.net.au>:
> On Mon, May 14, 2018 at 06:11:59AM +0900, Yoshihiro Kaneko wrote:
>> Hi Simon-san,
>>
>> 2018年5月10日(木) 3:11 Simon Horman <horms@verge.net.au>:
>>
>> > On Tue, Apr 03, 2018 at 09:43:03PM +0900, Yoshihiro Kaneko wrote:
>> > > Add support for R-Car D3 (r8a77995) thermal sensor.
>> > >
>> > > Signed-off-by: Yoshihiro Kaneko <ykaneko0929@gmail.com>
>> > > ---
>> > >  drivers/thermal/rcar_thermal.c | 154
>> > ++++++++++++++++++++++++++++++++---------
>> > >  1 file changed, 122 insertions(+), 32 deletions(-)
>> > >
>> > > diff --git a/drivers/thermal/rcar_thermal.c
>> > b/drivers/thermal/rcar_thermal.c
>> > > index 73e5fee..5ec47a9 100644
>> > > --- a/drivers/thermal/rcar_thermal.c
>> > > +++ b/drivers/thermal/rcar_thermal.c
>> > > @@ -58,10 +58,43 @@ struct rcar_thermal_common {
>> > >       spinlock_t lock;
>> > >  };
>> > >
>> > > +struct rcar_thermal_chip {
>> > > +     unsigned int use_of_thermal : 1;
>> > > +     unsigned int has_filonoff : 1;
>> > > +     unsigned int irq_per_ch : 1;
>> > > +     unsigned int needs_suspend_resume : 1;
>> > > +     unsigned int nirqs;
>> > > +};
>> > > +
>> > > +static const struct rcar_thermal_chip rcar_thermal = {
>> > > +     .use_of_thermal = 0,
>> > > +     .has_filonoff = 1,
>> > > +     .irq_per_ch = 0,
>> > > +     .needs_suspend_resume = 0,
>> > > +     .nirqs = 1,
>> > > +};
>> > > +
>> > > +static const struct rcar_thermal_chip rcar_gen2_thermal = {
>> > > +     .use_of_thermal = 1,
>> > > +     .has_filonoff = 1,
>> > > +     .irq_per_ch = 0,
>> > > +     .needs_suspend_resume = 0,
>> > > +     .nirqs = 1,
>> > > +};
>> > > +
>> > > +static const struct rcar_thermal_chip rcar_gen3_thermal = {
>> > > +     .use_of_thermal = 1,
>> > > +     .has_filonoff = 0,
>> > > +     .irq_per_ch = 1,
>> > > +     .needs_suspend_resume = 1,
>> > > +     .nirqs = 2,
>> > > +};
>> >
>> > The binding and dts patches in this series describe 3 interrupts
>> > for R-Car D3. But the above specifies two. Am I missing something obvious?
>>
>>
>> R-Car D3 has 3 interrupts, but this driver uses only 2 interrupts to detect
>> a temperature change, rise or fall.
>
> Thanks, that makes perfect sense.
>
> Perhaps a comment above ".nirqs = 2" would make it more obvious to the casual
> observer?

I agree with you.
I will update this patch.

^ permalink raw reply

* [PATCH v6 2/2] leds: lm3601x: Introduce the lm3601x LED driver
From: Dan Murphy @ 2018-05-15 15:43 UTC (permalink / raw)
  To: robh+dt, mark.rutland, jacek.anaszewski, pavel
  Cc: devicetree, linux-kernel, linux-leds, Dan Murphy
In-Reply-To: <20180515154352.20263-1-dmurphy@ti.com>

Introduce the family of LED devices that can
drive a torch, strobe or IR LED.

The LED driver can be configured with a strobe
timer to execute a strobe flash.  The IR LED
brightness is controlled via the torch brightness
register.

The data sheet for each the LM36010 and LM36011
LED drivers can be found here:
http://www.ti.com/product/LM36010
http://www.ti.com/product/LM36011

Signed-off-by: Dan Murphy <dmurphy@ti.com>
---

v6 - This driver has been heavily modified from v5.  There is no longer reading
of individual child nodes.  There are too many changes to list here see -
https://patchwork.kernel.org/patch/10392123/

v5 - Fixed magic numbers, change reg cache type, added of_put_node to release
the dt node ref, and I did not change the remove function to leave the LED in its
state on driver removal - https://patchwork.kernel.org/patch/10391741/
v4 - Fixed Cocci issue using ARRAY_SIZE - https://patchwork.kernel.org/patch/10389259/
v3 - removed wildcard dt compatible, fixed copyright, fixed struct doc, removed
RO registers from default, added regmap volatile for FLAGS_REG, updated regmap cache type,
fixed unlock and extra semi colon in strobe_set, removed unnecessary out label
in led register and fixed checking of the ret in brightness_set - https://patchwork.kernel.org/patch/10386243/
v2 - Fixed kbuild issue and removed unused cdev_strobe - https://patchwork.kernel.org/patch/10384585/

 drivers/leds/Kconfig        |   9 +
 drivers/leds/Makefile       |   1 +
 drivers/leds/leds-lm3601x.c | 595 ++++++++++++++++++++++++++++++++++++
 3 files changed, 605 insertions(+)
 create mode 100644 drivers/leds/leds-lm3601x.c

diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index 2c896c0e69e1..50ae536f343f 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -145,6 +145,15 @@ config LEDS_LM3692X
 	  This option enables support for the TI LM3692x family
 	  of white LED string drivers used for backlighting.
 
+config LEDS_LM3601X
+	tristate "LED support for LM3601x Chips"
+	depends on LEDS_CLASS && I2C && OF
+	depends on LEDS_CLASS_FLASH
+	select REGMAP_I2C
+	help
+	  This option enables support for the TI LM3601x family
+	  of flash, torch and indicator classes.
+
 config LEDS_LOCOMO
 	tristate "LED Support for Locomo device"
 	depends on LEDS_CLASS
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index 91eca81cae82..b79807fe1b67 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -76,6 +76,7 @@ obj-$(CONFIG_LEDS_MLXREG)		+= leds-mlxreg.o
 obj-$(CONFIG_LEDS_NIC78BX)		+= leds-nic78bx.o
 obj-$(CONFIG_LEDS_MT6323)		+= leds-mt6323.o
 obj-$(CONFIG_LEDS_LM3692X)		+= leds-lm3692x.o
+obj-$(CONFIG_LEDS_LM3601X)		+= leds-lm3601x.o
 
 # LED SPI Drivers
 obj-$(CONFIG_LEDS_DAC124S085)		+= leds-dac124s085.o
diff --git a/drivers/leds/leds-lm3601x.c b/drivers/leds/leds-lm3601x.c
new file mode 100644
index 000000000000..fa87da5d5159
--- /dev/null
+++ b/drivers/leds/leds-lm3601x.c
@@ -0,0 +1,595 @@
+// SPDX-License-Identifier: GPL-2.0
+// Flash and torch driver for Texas Instruments LM3601X LED
+// Flash driver chip family
+// Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
+
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/leds.h>
+#include <linux/led-class-flash.h>
+#include <linux/module.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <uapi/linux/uleds.h>
+
+#define LM3601X_LED_TORCH	0x0
+#define LM3601X_LED_IR		0x1
+
+/* Registers */
+#define LM3601X_ENABLE_REG	0x01
+#define LM3601X_CFG_REG		0x02
+#define LM3601X_LED_FLASH_REG	0x03
+#define LM3601X_LED_TORCH_REG	0x04
+#define LM3601X_FLAGS_REG	0x05
+#define LM3601X_DEV_ID_REG	0x06
+
+#define LM3601X_SW_RESET	BIT(7)
+
+/* Enable Mode bits */
+#define LM3601X_MODE_STANDBY	0x00
+#define LM3601X_MODE_IR_DRV	BIT(0)
+#define LM3601X_MODE_TORCH	BIT(1)
+#define LM3601X_MODE_STROBE	(BIT(0) | BIT(1))
+#define LM3601X_STRB_EN		BIT(2)
+#define LM3601X_STRB_LVL_TRIG	~BIT(3)
+#define LM3601X_STRB_EDGE_TRIG	BIT(3)
+#define LM3601X_IVFM_EN		BIT(4)
+
+#define LM36010_BOOST_LIMIT_19	~BIT(5)
+#define LM36010_BOOST_LIMIT_28	BIT(5)
+#define LM36010_BOOST_FREQ_2MHZ	~BIT(6)
+#define LM36010_BOOST_FREQ_4MHZ	BIT(6)
+#define LM36010_BOOST_MODE_NORM	~BIT(7)
+#define LM36010_BOOST_MODE_PASS	BIT(7)
+
+/* Flag Mask */
+#define LM3601X_FLASH_TIME_OUT	BIT(0)
+#define LM3601X_UVLO_FAULT	BIT(1)
+#define LM3601X_THERM_SHUTDOWN	BIT(2)
+#define LM3601X_THERM_CURR	BIT(3)
+#define LM36010_CURR_LIMIT	BIT(4)
+#define LM3601X_SHORT_FAULT	BIT(5)
+#define LM3601X_IVFM_TRIP	BIT(6)
+#define LM36010_OVP_FAULT	BIT(7)
+
+#define LM3601X_MIN_TORCH_I_UA	2400
+#define LM3601X_MIN_STROBE_I_MA	11
+
+#define LM3601X_TIMEOUT_MASK	0x1e
+#define LM3601X_ENABLE_MASK	0x03
+
+enum lm3601x_type {
+	CHIP_LM36010 = 0,
+	CHIP_LM36011,
+};
+
+/**
+ * struct lm3601x_max_timeouts -
+ * @timeout: timeout value in ms
+ * @regval: the value of the register to write
+ */
+struct lm3601x_max_timeouts {
+	int timeout;
+	int reg_val;
+};
+
+/**
+ * struct lm3601x_led -
+ * @lock: Lock for reading/writing the device
+ * @regmap: Devices register map
+ * @client: Pointer to the I2C client
+ * @led_node: DT device node for the led
+ * @cdev_torch: led class device pointer for the torch
+ * @cdev_ir: led class device pointer for infrared
+ * @fled_cdev: flash led class device pointer
+ * @led_name: LED label for the Torch or IR LED
+ * @strobe: LED label for the strobe
+ * @last_flag: last known flags register value
+ * @strobe_timeout: the timeout for the strobe
+ * @torch_current_max: maximum current for the torch
+ * @strobe_current_max: maximum current for the strobe
+ * @max_strobe_timeout: maximum timeout for the strobe
+ * @led_mode: The mode to enable either IR or Torch
+ */
+struct lm3601x_led {
+	struct mutex lock;
+	struct regmap *regmap;
+	struct i2c_client *client;
+
+	struct device_node *led_node;
+
+	struct led_classdev cdev_torch;
+	struct led_classdev cdev_ir;
+
+	struct led_classdev_flash fled_cdev;
+
+	char led_name[LED_MAX_NAME_SIZE];
+	char strobe[LED_MAX_NAME_SIZE];
+
+	unsigned int last_flag;
+	unsigned int strobe_timeout;
+
+	u32 torch_current_max;
+	u32 strobe_current_max;
+	u32 max_strobe_timeout;
+
+	int led_mode;
+};
+
+static const struct lm3601x_max_timeouts strobe_timeouts[] = {
+	{ 40000, 0x00 },
+	{ 80000, 0x01 },
+	{ 120000, 0x02 },
+	{ 160000, 0x03 },
+	{ 200000, 0x04 },
+	{ 240000, 0x05 },
+	{ 280000, 0x06 },
+	{ 320000, 0x07 },
+	{ 360000, 0x08 },
+	{ 400000, 0x09 },
+	{ 600000, 0x0a },
+	{ 800000, 0x0b },
+	{ 1000000, 0x0c },
+	{ 1200000, 0x0d },
+	{ 1400000, 0x0e },
+	{ 1600000, 0x0f },
+};
+
+static const struct reg_default lm3601x_regmap_defs[] = {
+	{ LM3601X_ENABLE_REG, 0x20 },
+	{ LM3601X_CFG_REG, 0x15 },
+	{ LM3601X_LED_FLASH_REG, 0x00 },
+	{ LM3601X_LED_TORCH_REG, 0x00 },
+};
+
+static bool lm3601x_volatile_reg(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case LM3601X_FLAGS_REG:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static const struct regmap_config lm3601x_regmap = {
+	.reg_bits = 8,
+	.val_bits = 8,
+
+	.max_register = LM3601X_DEV_ID_REG,
+	.reg_defaults = lm3601x_regmap_defs,
+	.num_reg_defaults = ARRAY_SIZE(lm3601x_regmap_defs),
+	.cache_type = REGCACHE_RBTREE,
+	.volatile_reg = lm3601x_volatile_reg,
+};
+
+static struct lm3601x_led *fled_cdev_to_led(
+				struct led_classdev_flash *fled_cdev)
+{
+	return container_of(fled_cdev, struct lm3601x_led, fled_cdev);
+}
+
+static int lm3601x_read_faults(struct lm3601x_led *led)
+{
+	int flags_val;
+	int ret;
+
+	ret = regmap_read(led->regmap, LM3601X_FLAGS_REG, &flags_val);
+	if (ret < 0)
+		return -EIO;
+
+	led->last_flag = 0;
+
+	if (flags_val & LM36010_OVP_FAULT)
+		led->last_flag |= LED_FAULT_OVER_VOLTAGE;
+
+	if (flags_val & (LM3601X_THERM_SHUTDOWN | LM3601X_THERM_CURR))
+		led->last_flag |= LED_FAULT_OVER_TEMPERATURE;
+
+	if (flags_val & LM3601X_SHORT_FAULT)
+		led->last_flag |= LED_FAULT_SHORT_CIRCUIT;
+
+	if (flags_val & LM36010_CURR_LIMIT)
+		led->last_flag |= LED_FAULT_OVER_CURRENT;
+
+	if (flags_val & LM3601X_UVLO_FAULT)
+		led->last_flag |= LED_FAULT_UNDER_VOLTAGE;
+
+	if (flags_val & LM3601X_IVFM_TRIP)
+		led->last_flag |= LED_FAULT_INPUT_VOLTAGE;
+
+	if (flags_val & LM3601X_THERM_SHUTDOWN)
+		led->last_flag |= LED_FAULT_LED_OVER_TEMPERATURE;
+
+	return led->last_flag;
+}
+
+static int lm3601x_brightness_set(struct led_classdev *cdev,
+					enum led_brightness brightness)
+{
+	struct lm3601x_led *led =
+	    container_of(cdev, struct lm3601x_led, cdev_torch);
+	u8 brightness_val;
+	int ret, led_mode_val;
+
+	mutex_lock(&led->lock);
+
+	ret = lm3601x_read_faults(led);
+	if (ret < 0)
+		goto out;
+
+	if (led->led_mode == LM3601X_LED_TORCH)
+		led_mode_val = LM3601X_MODE_TORCH;
+	else
+		led_mode_val = LM3601X_MODE_IR_DRV;
+
+	if (brightness == LED_OFF) {
+		ret = regmap_update_bits(led->regmap, LM3601X_ENABLE_REG,
+					led_mode_val, LED_OFF);
+		goto out;
+	}
+
+	if (brightness == LED_ON)
+		brightness_val = LED_ON;
+	else
+		brightness_val = (brightness/2);
+
+	ret = regmap_write(led->regmap, LM3601X_LED_TORCH_REG, brightness_val);
+	if (ret < 0)
+		goto out;
+
+	ret = regmap_update_bits(led->regmap, LM3601X_ENABLE_REG,
+					led_mode_val,
+					led_mode_val);
+
+out:
+	mutex_unlock(&led->lock);
+	return ret;
+}
+
+static int lm3601x_strobe_set(struct led_classdev_flash *fled_cdev,
+				bool state)
+{
+	struct lm3601x_led *led = fled_cdev_to_led(fled_cdev);
+	int ret;
+	int current_timeout;
+	int reg_count;
+	int i;
+	int timeout_reg_val = 0;
+
+	mutex_lock(&led->lock);
+
+	ret = regmap_read(led->regmap, LM3601X_CFG_REG, &current_timeout);
+	if (ret < 0)
+		goto out;
+
+	reg_count = ARRAY_SIZE(strobe_timeouts);
+	for (i = 0; i < reg_count; i++) {
+		if (led->strobe_timeout > strobe_timeouts[i].timeout)
+			continue;
+
+		if (led->strobe_timeout <= strobe_timeouts[i].timeout) {
+			timeout_reg_val = (strobe_timeouts[i].reg_val << 1);
+			break;
+		}
+
+		ret = -EINVAL;
+		goto out;
+	}
+
+	if (led->strobe_timeout != current_timeout)
+		ret = regmap_update_bits(led->regmap, LM3601X_CFG_REG,
+					LM3601X_TIMEOUT_MASK, timeout_reg_val);
+
+	if (state)
+		ret = regmap_update_bits(led->regmap, LM3601X_ENABLE_REG,
+					LM3601X_MODE_STROBE,
+					LM3601X_MODE_STROBE);
+	else
+		ret = regmap_update_bits(led->regmap, LM3601X_ENABLE_REG,
+					LM3601X_MODE_STROBE, LED_OFF);
+
+	ret = lm3601x_read_faults(led);
+out:
+	mutex_unlock(&led->lock);
+	return ret;
+}
+
+static int lm3601x_strobe_brightness_set(struct led_classdev *cdev,
+					 enum led_brightness brightness)
+{
+	struct led_classdev_flash *fled_cdev = lcdev_to_flcdev(cdev);
+	struct lm3601x_led *led = fled_cdev_to_led(fled_cdev);
+	int ret;
+	u8 brightness_val;
+
+	mutex_lock(&led->lock);
+	ret = lm3601x_read_faults(led);
+	if (ret < 0)
+		goto out;
+
+	if (brightness == LED_OFF) {
+		ret = regmap_update_bits(led->regmap, LM3601X_ENABLE_REG,
+					LM3601X_MODE_STROBE, LED_OFF);
+		goto out;
+	}
+
+	if (brightness == LED_ON)
+		brightness_val = LED_ON;
+	else
+		brightness_val = (brightness/2);
+
+	ret = regmap_write(led->regmap, LM3601X_LED_FLASH_REG, brightness_val);
+
+out:
+	mutex_unlock(&led->lock);
+	return ret;
+}
+
+static int lm3601x_strobe_timeout_set(struct led_classdev_flash *fled_cdev,
+				u32 timeout)
+{
+	struct lm3601x_led *led = fled_cdev_to_led(fled_cdev);
+	int ret = 0;
+
+	mutex_lock(&led->lock);
+
+	led->strobe_timeout = timeout;
+
+	mutex_unlock(&led->lock);
+
+	return ret;
+}
+
+static int lm3601x_strobe_get(struct led_classdev_flash *fled_cdev,
+				bool *state)
+{
+	struct lm3601x_led *led = fled_cdev_to_led(fled_cdev);
+	int ret;
+	int strobe_state;
+
+	mutex_lock(&led->lock);
+
+	ret = regmap_read(led->regmap, LM3601X_ENABLE_REG, &strobe_state);
+	if (ret < 0)
+		goto out;
+
+	*state = strobe_state & LM3601X_MODE_STROBE;
+
+out:
+	mutex_unlock(&led->lock);
+	return ret;
+}
+
+static int lm3601x_strobe_fault_get(struct led_classdev_flash *fled_cdev,
+				u32 *fault)
+{
+	struct lm3601x_led *led = fled_cdev_to_led(fled_cdev);
+
+	lm3601x_read_faults(led);
+
+	*fault = led->last_flag;
+
+	return 0;
+}
+
+static const struct led_flash_ops strobe_ops = {
+	.strobe_set		= lm3601x_strobe_set,
+	.strobe_get		= lm3601x_strobe_get,
+	.timeout_set		= lm3601x_strobe_timeout_set,
+	.fault_get		= lm3601x_strobe_fault_get,
+};
+
+static int lm3601x_register_leds(struct lm3601x_led *led)
+{
+	struct led_classdev_flash *fled_cdev;
+	struct led_classdev *led_cdev;
+	int err = -ENODEV;
+
+	led->cdev_torch.name = led->led_name;
+	led->cdev_torch.max_brightness = LED_FULL;
+	led->cdev_torch.brightness_set_blocking = lm3601x_brightness_set;
+	err = devm_led_classdev_register(&led->client->dev,
+			&led->cdev_torch);
+	if (err < 0)
+		return err;
+
+	fled_cdev = &led->fled_cdev;
+	fled_cdev->ops = &strobe_ops;
+
+	led_cdev = &fled_cdev->led_cdev;
+	led_cdev->name = led->strobe;
+	led_cdev->max_brightness = LED_FULL;
+	led_cdev->brightness_set_blocking = lm3601x_strobe_brightness_set;
+	led_cdev->flags |= LED_DEV_CAP_FLASH;
+
+	err = led_classdev_flash_register(&led->client->dev,
+			fled_cdev);
+
+	return err;
+}
+
+static void lm3601x_init_flash_timeout(struct lm3601x_led *led)
+{
+	struct led_flash_setting *setting;
+
+	setting = &led->fled_cdev.timeout;
+	setting->min = strobe_timeouts[0].timeout;
+	setting->max = led->max_strobe_timeout;
+	setting->step = 40;
+	setting->val = led->max_strobe_timeout;
+}
+
+static int lm3601x_parse_node(struct lm3601x_led *led,
+			      struct device_node *node)
+{
+	struct device_node *child_node;
+	const char *name;
+	char *mode_name;
+	int ret = -ENODEV;
+
+	for_each_available_child_of_node(node, child_node) {
+		led->led_node = of_node_get(child_node);
+		if (!led->led_node) {
+			dev_err(&led->client->dev,
+				"No LED Child node\n");
+
+			goto out_err;
+		}
+
+		ret = of_property_read_u32(led->led_node, "led-sources",
+					   &led->led_mode);
+		if (ret) {
+			dev_err(&led->client->dev,
+				"led-sources DT property missing\n");
+			goto out_err;
+		}
+
+		if (led->led_mode < LM3601X_LED_TORCH ||
+		    led->led_mode > LM3601X_LED_IR) {
+			dev_warn(&led->client->dev,
+				"Invalid led mode requested\n");
+
+			goto out_err;
+
+		}
+	}
+
+	if (led->led_mode == LM3601X_LED_TORCH) {
+		ret = of_property_read_string(led->led_node, "label", &name);
+		if (!ret)
+			snprintf(led->led_name, sizeof(led->led_name),
+				"%s:%s", led->led_node->name, name);
+		else
+			snprintf(led->led_name, sizeof(led->led_name),
+				"%s:torch", led->led_node->name);
+
+		ret = of_property_read_u32(led->led_node, "led-max-microamp",
+					&led->torch_current_max);
+		if (ret < 0) {
+			dev_warn(&led->client->dev,
+				"led-max-microamp DT property missing\n");
+
+			goto out_err;
+		}
+
+		mode_name = "torch";
+
+	} else if (led->led_mode == LM3601X_LED_IR) {
+		ret = of_property_read_string(led->led_node, "label", &name);
+		if (!ret)
+			snprintf(led->led_name, sizeof(led->led_name),
+				"%s:%s", led->led_node->name, name);
+		else
+			snprintf(led->led_name, sizeof(led->led_name),
+				"%s::infrared", led->led_node->name);
+
+		mode_name = "ir";
+
+	} else {
+		dev_warn(&led->client->dev,
+			"No LED mode is selected exiting probe\n");
+
+		goto out_err;
+	}
+
+	/* Flash mode is available in IR or Torch mode so read the DT */
+	snprintf(led->strobe, sizeof(led->strobe),
+			"%s:%s:strobe", led->led_node->name, mode_name);
+
+	ret = of_property_read_u32(led->led_node,
+				"flash-max-microamp",
+				&led->strobe_current_max);
+	if (ret < 0) {
+		dev_warn(&led->client->dev,
+			 "flash-max-microamp DT property missing\n");
+		goto out_err;
+	}
+
+	ret = of_property_read_u32(led->led_node,
+				"flash-max-timeout-us",
+				&led->max_strobe_timeout);
+	if (ret < 0) {
+		dev_warn(&led->client->dev,
+			 "flash-max-timeout-us DT property missing\n");
+
+		goto out_err;
+	}
+
+	lm3601x_init_flash_timeout(led);
+
+out_err:
+	of_node_put(led->led_node);
+	return ret;
+}
+
+static int lm3601x_probe(struct i2c_client *client,
+			const struct i2c_device_id *id)
+{
+	struct lm3601x_led *led;
+	int err;
+
+	led = devm_kzalloc(&client->dev,
+			    sizeof(struct lm3601x_led), GFP_KERNEL);
+	if (!led)
+		return -ENOMEM;
+
+	err = lm3601x_parse_node(led, client->dev.of_node);
+	if (err < 0)
+		return -ENODEV;
+
+	led->client = client;
+	led->regmap = devm_regmap_init_i2c(client, &lm3601x_regmap);
+	if (IS_ERR(led->regmap)) {
+		err = PTR_ERR(led->regmap);
+		dev_err(&client->dev,
+			"Failed to allocate register map: %d\n", err);
+		return err;
+	}
+
+	mutex_init(&led->lock);
+	i2c_set_clientdata(client, led);
+	err = lm3601x_register_leds(led);
+
+	return err;
+}
+
+static int lm3601x_remove(struct i2c_client *client)
+{
+	struct lm3601x_led *led = i2c_get_clientdata(client);
+
+	regmap_update_bits(led->regmap, LM3601X_ENABLE_REG,
+			   LM3601X_ENABLE_MASK,
+			   LM3601X_MODE_STANDBY);
+
+	return 0;
+}
+
+static const struct i2c_device_id lm3601x_id[] = {
+	{ "LM36010", CHIP_LM36010 },
+	{ "LM36011", CHIP_LM36011 },
+	{ },
+};
+MODULE_DEVICE_TABLE(i2c, lm3601x_id);
+
+static const struct of_device_id of_lm3601x_leds_match[] = {
+	{ .compatible = "ti,lm36010", },
+	{ .compatible = "ti,lm36011", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, of_lm3601x_leds_match);
+
+static struct i2c_driver lm3601x_i2c_driver = {
+	.driver = {
+		.name = "lm3601x",
+		.of_match_table = of_lm3601x_leds_match,
+	},
+	.probe = lm3601x_probe,
+	.remove = lm3601x_remove,
+	.id_table = lm3601x_id,
+};
+module_i2c_driver(lm3601x_i2c_driver);
+
+MODULE_DESCRIPTION("Texas Instruments Flash Lighting driver for LM3601X");
+MODULE_AUTHOR("Dan Murphy <dmurphy@ti.com>");
+MODULE_LICENSE("GPL v2");
-- 
2.17.0.582.gccdcbd54c

^ permalink raw reply related

* [PATCH v6 1/2] dt: bindings: lm3601x: Introduce the lm3601x driver
From: Dan Murphy @ 2018-05-15 15:43 UTC (permalink / raw)
  To: robh+dt, mark.rutland, jacek.anaszewski, pavel
  Cc: devicetree, linux-kernel, linux-leds, Dan Murphy

Introduce the device tree bindings for the lm3601x
family of LED torch, flash and IR drivers.

Signed-off-by: Dan Murphy <dmurphy@ti.com>
---

v6 - Removed multiple led child nodes, fixed example to display micro ranges
for corresponding child nodes and added led-sources to define the current driver -
https://patchwork.kernel.org/patch/10392121/

v5 - No changes - https://patchwork.kernel.org/patch/10391743/
v4 - Added " " around "=", changed strobe to flash on label, removed "support and
register" comment and change ir lable to ir:torch - See v2 patchworks for comments
v3 - Removed wildcard compatible - https://patchwork.kernel.org/patch/10386241/
v2 - No changes - https://patchwork.kernel.org/patch/10384587/

 .../devicetree/bindings/leds/leds-lm3601x.txt | 47 +++++++++++++++++++
 1 file changed, 47 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/leds/leds-lm3601x.txt

diff --git a/Documentation/devicetree/bindings/leds/leds-lm3601x.txt b/Documentation/devicetree/bindings/leds/leds-lm3601x.txt
new file mode 100644
index 000000000000..27930a89e9a5
--- /dev/null
+++ b/Documentation/devicetree/bindings/leds/leds-lm3601x.txt
@@ -0,0 +1,47 @@
+* Texas Instruments - lm3601x Single-LED Flash Driver
+
+The LM3601X are ultra-small LED flash drivers that
+provide a high level of adjustability.
+
+Required properties:
+	- compatible : Can be one of the following
+		"ti,lm36010"
+		"ti,lm36011"
+	- reg : I2C slave address
+	- #address-cells : 1
+	- #size-cells : 0
+
+Required child properties:
+	- reg : 0
+	- led-sources:	0 - Indicates a IR mode
+			1 - Indicates a Torch (white LED) mode
+
+Required properties for flash LED child nodes:
+	See Documentation/devicetree/bindings/leds/common.txt
+	- flash-max-microamp : Range from 11mA -> 1.5A
+	- flash-max-timeout-us : Range from 40ms -> 1600ms
+	- led-max-microamp : Range from 2.4mA -> 376mA
+
+Optional child properties:
+	- label : see Documentation/devicetree/bindings/leds/common.txt
+
+Example:
+led-controller@64 {
+	compatible = "ti,lm36010";
+	#address-cells = <1>;
+	#size-cells = <0>;
+	reg = <0x64>;
+
+	led@0 {
+		reg = <0>;
+		label = "white:torch";
+		led-max-microamp = <376000>;
+		flash-max-microamp = <1500000>;
+		flash-max-timeout-us = <1600000>;
+		led-sources = <1>;
+	};
+}
+
+For more product information please see the links below:
+http://www.ti.com/product/LM36010
+http://www.ti.com/product/LM36011
-- 
2.17.0.582.gccdcbd54c

^ permalink raw reply related

* Re: [PATCH v10 02/27] clk: davinci: da850-pll: change PLL0 to CLK_OF_DECLARE
From: David Lechner @ 2018-05-15 15:42 UTC (permalink / raw)
  To: Sekhar Nori, linux-clk, devicetree, linux-arm-kernel
  Cc: Michael Turquette, Stephen Boyd, Rob Herring, Mark Rutland,
	Kevin Hilman, Bartosz Golaszewski, Adam Ford, linux-kernel
In-Reply-To: <9203489d-0a5a-103a-67ea-d3e89bb7ebc4@ti.com>

On 05/15/2018 08:31 AM, Sekhar Nori wrote:
> On Wednesday 09 May 2018 10:55 PM, David Lechner wrote:
>> +void of_da850_pll0_init(struct device_node *node)
>>   {
>> -	return of_davinci_pll_init(dev, dev->of_node, &da850_pll0_info,
>> -				   &da850_pll0_obsclk_info,
>> -				   da850_pll0_sysclk_info, 7, base, cfgchip);
>> +	void __iomem *base;
>> +	struct regmap *cfgchip;
>> +
>> +	base = of_iomap(node, 0);
>> +	if (!base) {
>> +		pr_err("%s: ioremap failed\n", __func__);
>> +		return;
>> +	}
>> +
>> +	cfgchip = syscon_regmap_lookup_by_compatible("ti,da830-cfgchip");

In your previous review, you pointed out that the error did not need to
be handled here because it is handled later in davinci_pll_clk_register().

We get a warning there because cfgchip is only needed for unlocking the
PLL for CPU frequency scaling and is not critical for operation of the
clocks.

> 
> It will be nice to handle the error case here.
> 
>> +
>> +	of_davinci_pll_init(NULL, node, &da850_pll0_info,
>> +			    &da850_pll0_obsclk_info,
>> +			    da850_pll0_sysclk_info, 7, base, cfgchip);
> 
> Apart from that, it looks good to me.
> 
> Reviewed-by: Sekhar Nori <nsekhar@ti.com>
> 
> Thanks,
> Sekhar
> 

^ permalink raw reply

* Re: [PATCH] iio: adc: stm32-dfsdm: Add support for stm32mp1
From: Fabrice Gasnier @ 2018-05-15 15:23 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: mark.rutland, Rob Herring, benjamin.gaignard, lars,
	alexandre.torgue, devicetree, linux-iio, pmeerw, arnaud.pouliquen,
	linux-kernel, mcoquelin.stm32, knaack.h, linux-arm-kernel
In-Reply-To: <20180512103324.5068c893@archlinux>

On 05/12/2018 11:33 AM, Jonathan Cameron wrote:
> On Mon, 7 May 2018 15:51:51 -0500
> Rob Herring <robh@kernel.org> wrote:
> 
>> On Wed, May 02, 2018 at 03:05:23PM +0200, Fabrice Gasnier wrote:
>>> Add support for DFSDM (Digital Filter For Sigma Delta Modulators)
>>> to STM32MP1. This variant is close to STM32H7 DFSDM, it implements
>>> 6 filter instances. Registers map is also increased.
>>>
>>> Signed-off-by: Fabrice Gasnier <fabrice.gasnier@st.com>
>>> ---
>>>  .../bindings/iio/adc/st,stm32-dfsdm-adc.txt         |  7 +++++--
>>>  drivers/iio/adc/stm32-dfsdm-core.c                  | 21 +++++++++++++++++++++
>>>  2 files changed, 26 insertions(+), 2 deletions(-)  
>>
>> Reviewed-by: Rob Herring <robh@kernel.org>
> Applied.   Whilst doing this I note that I'm getting a few sparse
> warnings for this driver that would be nice to clean up...
> 
>   CHECK   drivers/iio/adc/stm32-dfsdm-adc.c
> drivers/iio/adc/stm32-dfsdm-adc.c:503:21: warning: expression using sizeof(void)
> drivers/iio/adc/stm32-dfsdm-adc.c:503:21: warning: expression using sizeof(void)
> 
> Which is mystifying at first glance... Something deep and dirty in the min macro
> but I can't see what..

Hi Jonathan,

I just sent a patch to clean bellow warning. But this is more obscure
regarding min macro...

Many thanks,
Fabrice

> 
> drivers/iio/adc/stm32-dfsdm-adc.c:680:5: warning: symbol 'stm32_dfsdm_get_buff_cb' was not declared. Should it be static?
> drivers/iio/adc/stm32-dfsdm-adc.c:703:5: warning: symbol 'stm32_dfsdm_release_buff_cb' was not declared. Should it be static?
> 
> Are rather more obvious
> 

^ permalink raw reply

* Re: [PATCHv2] arm64: dts: stratix10: Add QSPI support for Stratix10
From: Dinh Nguyen @ 2018-05-15 15:11 UTC (permalink / raw)
  To: thor.thayer, robh+dt, mark.rutland
  Cc: catalin.marinas, will.deacon, devicetree, linux-arm-kernel,
	linux-kernel
In-Reply-To: <1526055052-11371-1-git-send-email-thor.thayer@linux.intel.com>



On 05/11/2018 11:10 AM, thor.thayer@linux.intel.com wrote:
> From: Thor Thayer <thor.thayer@linux.intel.com>
> 
> Add qspi_clock
>    The qspi_clk frequency is updated by U-Boot before starting Linux.
> Add QSPI interface node.
> Add QSPI flash memory child node.
>    Setup the QSPI memory in 2 partitions.
> 
> Signed-off-by: Thor Thayer <thor.thayer@linux.intel.com>
> ---
> v2  s/_/-/ in qspi-clk
>     rename flash node.
>     use partition child node notation
> ---
>  arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi  | 22 ++++++++++++++
>  .../boot/dts/altera/socfpga_stratix10_socdk.dts    | 35 ++++++++++++++++++++++
>  2 files changed, 57 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi b/arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi
> index e6b059378dc0..bac01b0b7907 100644
> --- a/arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi
> +++ b/arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi
> @@ -119,6 +119,12 @@
>  				#clock-cells = <0>;
>  				compatible = "fixed-clock";
>  			};
> +
> +			qspi_clk: qspi-clk {
> +				#clock-cells = <0>;
> +				compatible = "fixed-clock";
> +				clock-frequency = <200000000>;
> +			};
>  		};
>  
>  		gmac0: ethernet@ff800000 {
> @@ -466,5 +472,21 @@
>  				interrupts = <16 4>, <48 4>;
>  			};
>  		};
> +
> +		qspi: spi@ff8d2000 {
> +			compatible = "cdns,qspi-nor";
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			reg = <0xff8d2000 0x100>,
> +			      <0xff900000 0x100000>;
> +			interrupts = <0 3 4>;
> +			cdns,fifo-depth = <128>;
> +			cdns,fifo-width = <4>;
> +			cdns,trigger-address = <0x00000000>;
> +			clocks = <&qspi_clk>;
> +			bus-num = <1>;

I don't you need "bus-num" anymore right? I don't see it getting used
anywhere in the driver.

Dinh

^ permalink raw reply

* Re: [PATCH v2 0/4] Add DesignWare EP support
From: Lorenzo Pieralisi @ 2018-05-15 15:10 UTC (permalink / raw)
  To: Gustavo Pimentel
  Cc: bhelgaas, Joao.Pinto, jingoohan1, kishon, robh+dt, mark.rutland,
	linux-pci, linux-kernel, devicetree
In-Reply-To: <cover.1526395185.git.gustavo.pimentel@synopsys.com>

On Tue, May 15, 2018 at 03:41:40PM +0100, Gustavo Pimentel wrote:
> Patch set was made against the Lorenzo's pci/dwc branch.
> 
> The PCIe controller dual mode is capable of operating in RC mode as well
> as EP mode by configuration option. Till now only RC mode was supported,
> with this patch is add EP support to the DesignWare driver.
> 
> Gustavo Pimentel (4):
>   bindings: PCI: designware: Example update
>   PCI: dwc: Add support for EP mode
>   bindings: PCI: designware: Add support for EP in DesignWare driver
>   misc: pci_endpoint_test: Add DesignWare EP entry
> 
>  .../devicetree/bindings/pci/designware-pcie.txt    |  24 +++-
>  drivers/misc/pci_endpoint_test.c                   |   1 +
>  drivers/pci/dwc/Kconfig                            |  37 +++--
>  drivers/pci/dwc/pcie-designware-ep.c               |   3 +
>  drivers/pci/dwc/pcie-designware-plat.c             | 149 +++++++++++++++++++--
>  drivers/pci/endpoint/functions/pci-epf-test.c      |   7 +
>  include/linux/pci-epc.h                            |   8 ++
>  7 files changed, 205 insertions(+), 24 deletions(-)

Applied to pci/dwc for v4.18 with some small commit log tweaks.

Thanks,
Lorenzo

^ permalink raw reply

* Re: [PATCH v2 0/5] Hi3660: enable power management features
From: Leo Yan @ 2018-05-15 14:54 UTC (permalink / raw)
  To: Wei Xu
  Cc: Rob Herring, Mark Rutland, Michael Turquette, Stephen Boyd,
	Jassi Brar, Arnd Bergmann, Olof Johansson, Daniel Lezcano,
	linux-arm-kernel, devicetree, linux-kernel, linux-clk
In-Reply-To: <5AFAF3CE.70601@hisilicon.com>

On Tue, May 15, 2018 at 03:50:54PM +0100, Wei Xu wrote:
> Hi Leo,
> 
> On 2018/5/15 3:53, Leo Yan wrote:
> > Since hi3660 drivers have been merged into Linux kernel (mailbox driver is in
> > Linux-next branch and other drivers are existed in Linux mainline kernel), so
> > this patch series is to enable power management features on hi3660.
> > 
> > This patch series includes device tree binding for mailbox, stub clock and CPU
> > OPPs, and has one patch to consolidate the Kconfigs for driver modules.
> > 
> > This patch set have been tested on Hikey960 and also verified the patch 'hisi:
> > Consolidate the Kconfigs for the CLOCK_STUB and the MAILBOX' for Hikey620.
> > 
> > Changes from v1:
> > * Changed patch subject from "dts: arm64: hi3660" to "arm64: dts: hi3660".
> > 
> > 
> > Daniel Lezcano (1):
> >   hisi: Consolidate the Kconfigs for the CLOCK_STUB and the MAILBOX
> > 
> > Kaihua Zhong (2):
> >   arm64: dts: hi3660: Add mailbox node
> >   arm64: dts: hi3660: Add stub clock node
> > 
> > Leo Yan (1):
> >   arm64: dts: hi3660: Add CPU frequency scaling support
> > 
> > Tao Wang (1):
> >   arm64: dts: hi3660: Add thermal cooling management
> > 
> >  arch/arm64/boot/dts/hisilicon/hi3660.dtsi | 145 ++++++++++++++++++++++++++++++
> >  arch/arm64/configs/defconfig              |   1 -
> >  drivers/clk/hisilicon/Kconfig             |  13 +--
> >  drivers/mailbox/Kconfig                   |  12 ++-
> >  4 files changed, 161 insertions(+), 10 deletions(-)
> > 
> 
> Applied patch 1 to 4.
> Thanks!

Thanks a lot, Wei.

> Best Regards,
> Wei
> 

^ permalink raw reply

* Re: [PATCH v2 11/11] docs: fix broken references with multiple hints
From: Steven Rostedt @ 2018-05-15 14:52 UTC (permalink / raw)
  To: Mauro Carvalho Chehab
  Cc: Mark Rutland, linux-fbdev, linux-usb, Linux Doc Mailing List,
	David Airlie, Linus Walleij, dri-devel, Harry Wei, devel,
	Jonathan Corbet, James Morris, Ingo Molnar, linux-input,
	Roy Pledge, devicetree, Bartlomiej Zolnierkiewicz, Jiri Kosina,
	Mauro Carvalho Chehab, linux-gpio, Rob Herring,
	Greg Kroah-Hartman, Dmitry Torokhov, linux-kernel,
	linux-security-module, Benjamin
In-Reply-To: <63a4f8a93f9115475bc184d0f37d076c9b9c75ff.1525870886.git.mchehab+samsung@kernel.org>

On Wed,  9 May 2018 10:18:54 -0300
Mauro Carvalho Chehab <mchehab+samsung@kernel.org> wrote:


> diff --git a/Documentation/trace/events.rst b/Documentation/trace/events.rst
> index 7b6b1236ec2e..c292117b83a9 100644
> --- a/Documentation/trace/events.rst
> +++ b/Documentation/trace/events.rst
> @@ -8,7 +8,7 @@ Event Tracing
>  1. Introduction
>  ===============
>  
> -Tracepoints (see Documentation/trace/tracepoints.txt) can be used
> +Tracepoints (see Documentation/trace/tracepoints.rst) can be used
>  without creating custom kernel modules to register probe functions
>  using the event tracing infrastructure.
>  
> diff --git a/Documentation/trace/tracepoint-analysis.rst b/Documentation/trace/tracepoint-analysis.rst
> index b0c9c21f129d..716326b9f152 100644
> --- a/Documentation/trace/tracepoint-analysis.rst
> +++ b/Documentation/trace/tracepoint-analysis.rst
> @@ -6,7 +6,7 @@ Notes on Analysing Behaviour Using Events and Tracepoints
>  1. Introduction
>  ===============
>  
> -Tracepoints (see Documentation/trace/tracepoints.txt) can be used without
> +Tracepoints (see Documentation/trace/tracepoints.rst) can be used without
>  creating custom kernel modules to register probe functions using the event
>  tracing infrastructure.
>  

> diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h
> index c94f466d57ef..19a690b559ca 100644
> --- a/include/linux/tracepoint.h
> +++ b/include/linux/tracepoint.h
> @@ -4,7 +4,7 @@
>  /*
>   * Kernel Tracepoint API.
>   *
> - * See Documentation/trace/tracepoints.txt.
> + * See Documentation/trace/tracepoints.rst.
>   *
>   * Copyright (C) 2008-2014 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
>   *

Acked-by: Steven Rostedt (VMware) <rostedt@goodmis.org>

-- Steve

^ permalink raw reply

* Re: [PATCH v2 0/5] Hi3660: enable power management features
From: Wei Xu @ 2018-05-15 14:50 UTC (permalink / raw)
  To: Leo Yan, Rob Herring, Mark Rutland, Michael Turquette,
	Stephen Boyd, Jassi Brar, Arnd Bergmann, Olof Johansson,
	Daniel Lezcano, linux-arm-kernel, devicetree, linux-kernel,
	linux-clk
In-Reply-To: <1526352795-6991-1-git-send-email-leo.yan@linaro.org>

Hi Leo,

On 2018/5/15 3:53, Leo Yan wrote:
> Since hi3660 drivers have been merged into Linux kernel (mailbox driver is in
> Linux-next branch and other drivers are existed in Linux mainline kernel), so
> this patch series is to enable power management features on hi3660.
> 
> This patch series includes device tree binding for mailbox, stub clock and CPU
> OPPs, and has one patch to consolidate the Kconfigs for driver modules.
> 
> This patch set have been tested on Hikey960 and also verified the patch 'hisi:
> Consolidate the Kconfigs for the CLOCK_STUB and the MAILBOX' for Hikey620.
> 
> Changes from v1:
> * Changed patch subject from "dts: arm64: hi3660" to "arm64: dts: hi3660".
> 
> 
> Daniel Lezcano (1):
>   hisi: Consolidate the Kconfigs for the CLOCK_STUB and the MAILBOX
> 
> Kaihua Zhong (2):
>   arm64: dts: hi3660: Add mailbox node
>   arm64: dts: hi3660: Add stub clock node
> 
> Leo Yan (1):
>   arm64: dts: hi3660: Add CPU frequency scaling support
> 
> Tao Wang (1):
>   arm64: dts: hi3660: Add thermal cooling management
> 
>  arch/arm64/boot/dts/hisilicon/hi3660.dtsi | 145 ++++++++++++++++++++++++++++++
>  arch/arm64/configs/defconfig              |   1 -
>  drivers/clk/hisilicon/Kconfig             |  13 +--
>  drivers/mailbox/Kconfig                   |  12 ++-
>  4 files changed, 161 insertions(+), 10 deletions(-)
> 

Applied patch 1 to 4.
Thanks!

Best Regards,
Wei

^ permalink raw reply

* Re: [PATCH 3/3] arm64: dts: renesas: r8a7795: add ccree binding
From: Geert Uytterhoeven @ 2018-05-15 14:50 UTC (permalink / raw)
  To: Gilad Ben-Yossef
  Cc: Simon Horman, Magnus Damm, Rob Herring, Mark Rutland,
	Catalin Marinas, Will Deacon, Geert Uytterhoeven,
	Michael Turquette, Stephen Boyd, Herbert Xu, David S. Miller,
	Ofir Drang, Linux-Renesas,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Linux ARM, Linux Kernel Mailing List, linux-clk
In-Reply-To: <1526387370-17142-4-git-send-email-gilad@benyossef.com>

Hi Gilad,

On Tue, May 15, 2018 at 2:29 PM, Gilad Ben-Yossef <gilad@benyossef.com> wrote:
> Add bindings for CryptoCell instance in the SoC.
>
> Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com>

Thanks for your patch!

> --- a/arch/arm64/boot/dts/renesas/r8a7795.dtsi
> +++ b/arch/arm64/boot/dts/renesas/r8a7795.dtsi
> @@ -528,6 +528,14 @@
>                         status = "disabled";
>                 };
>
> +               arm_cc630p: crypto@e6601000 {
> +                       compatible = "arm,cryptocell-630p-ree";
> +                       interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
> +                       #interrupt-cells = <2>;

I believe the #interrupt-cells property is not needed.

> +                       reg = <0x0 0xe6601000 0 0x1000>;
> +                       clocks = <&cpg CPG_MOD 229>;
> +               };

The rest looks good, but I cannot verify the register block.

> +
>                 i2c3: i2c@e66d0000 {
>                         #address-cells = <1>;
>                         #size-cells = <0>;

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply

* Re: [PATCH 2/3] clk: renesas: r8a7795: Add ccree clock
From: Geert Uytterhoeven @ 2018-05-15 14:47 UTC (permalink / raw)
  To: Gilad Ben-Yossef
  Cc: Simon Horman, Magnus Damm, Rob Herring, Mark Rutland,
	Catalin Marinas, Will Deacon, Geert Uytterhoeven,
	Michael Turquette, Stephen Boyd, Herbert Xu, David S. Miller,
	Ofir Drang, Linux-Renesas,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Linux ARM, Linux Kernel Mailing List, linux-clk
In-Reply-To: <1526387370-17142-3-git-send-email-gilad@benyossef.com>

Hi Gilad,

On Tue, May 15, 2018 at 2:29 PM, Gilad Ben-Yossef <gilad@benyossef.com> wrote:
> This patch adds the clock used by the CryptoCell 630p instance in the SoC.
>
> Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com>

Thanks for your patch!

> --- a/drivers/clk/renesas/r8a7795-cpg-mssr.c
> +++ b/drivers/clk/renesas/r8a7795-cpg-mssr.c
> @@ -132,6 +132,7 @@ static struct mssr_mod_clk r8a7795_mod_clks[] __initdata = {
>         DEF_MOD("sys-dmac2",             217,   R8A7795_CLK_S0D3),
>         DEF_MOD("sys-dmac1",             218,   R8A7795_CLK_S0D3),
>         DEF_MOD("sys-dmac0",             219,   R8A7795_CLK_S0D3),
> +       DEF_MOD("ccree",                 229,   R8A7795_CLK_S3D2),

I don't know if "ccree" is the proper name for this clock, as there
may be multiple
instances.
I also can't verify the parent clock.

>         DEF_MOD("cmt3",                  300,   R8A7795_CLK_R),
>         DEF_MOD("cmt2",                  301,   R8A7795_CLK_R),
>         DEF_MOD("cmt1",                  302,   R8A7795_CLK_R),

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply

* Re: [PATCH] iio: dac: Add regulator framework to LTC2632 device driver
From: Silvan Murer @ 2018-05-15 14:43 UTC (permalink / raw)
  To: Lars-Peter Clausen, Jonathan Cameron; +Cc: linux-iio, devicetree
In-Reply-To: <687efcfb-a9a8-99e7-8a81-150c3a4712a3@metafoo.de>

Thanks Lars for the feedback.
I created just now, a new patch which includes just the of_match_table
fix. For the other stuffe i will create a new version of the patch (v2)
soon. 

On Mon, 2018-05-14 at 13:14 +0200, Lars-Peter Clausen wrote:
> On 05/14/2018 12:31 PM, Silvan Murer wrote:
> > 
> > This patch adds support for external reference voltage through the
> > regulator framework.
> > The patch add also the remove function to the device driver.
> > 
> > Signed-off-by: Silvan Murer <silvan.murer@gmail.com>
> Hi,
> 
> Thanks for the patch. A few comments.
> 
> > 
> > ---
> >  .../devicetree/bindings/iio/dac/ltc2632.txt        |  9 +++
> >  drivers/iio/dac/ltc2632.c                          | 86
> > +++++++++++++++++-----
> >  2 files changed, 78 insertions(+), 17 deletions(-)
> > 
> > diff --git a/Documentation/devicetree/bindings/iio/dac/ltc2632.txt
> > b/Documentation/devicetree/bindings/iio/dac/ltc2632.txt
> > index eb911e5..d369a4b 100644
> > --- a/Documentation/devicetree/bindings/iio/dac/ltc2632.txt
> > +++ b/Documentation/devicetree/bindings/iio/dac/ltc2632.txt
> > @@ -14,10 +14,19 @@ apply. In particular, "reg" and "spi-max-
> > frequency" properties must be given.
> >  
> >  Example:
> >  
> > +	vref: regulator-vref {
> > +		compatible = "regulator-fixed";
> > +		regulator-name = "vref-ltc2632";
> > +		regulator-min-microvolt = <1250000>;
> > +		regulator-max-microvolt = <1250000>;
> > +		regulator-always-on;
> > +	};
> > +
> >  	spi_master {
> >  		dac: ltc2632@0 {
> >  			compatible = "lltc,ltc2632-l12";
> >  			reg = <0>; /* CS0 */
> >  			spi-max-frequency = <1000000>;
> > +			vref-supply = <&vref>; /* optional */
> This should not only update the example, but also add a 'optional
> properties' section where the property is documented.
> 
> > 
> >  		};
> >  	};
> > diff --git a/drivers/iio/dac/ltc2632.c b/drivers/iio/dac/ltc2632.c
> > index ac5e05f..4a5c5bd 100644
> > --- a/drivers/iio/dac/ltc2632.c
> > +++ b/drivers/iio/dac/ltc2632.c
> [...
> > 
> >  enum ltc2632_supported_device_ids {
> > @@ -90,7 +96,7 @@ static int ltc2632_read_raw(struct iio_dev
> > *indio_dev,
> >  
> >  	switch (m) {
> >  	case IIO_CHAN_INFO_SCALE:
> > -		*val = chip_info->vref_mv;
> > +		*val = st->vref_mv;
> >  		*val2 = chan->scan_type.realbits;
> >  		return IIO_VAL_FRACTIONAL_LOG2;
> >  	}
> > @@ -247,6 +253,41 @@ static int ltc2632_probe(struct spi_device
> > *spi)
> >  	chip_info = (struct ltc2632_chip_info *)
> >  			spi_get_device_id(spi)->driver_data;
> >  
> > +	st->vref_reg = devm_regulator_get_optional(&spi->dev,
> > "vref");
> > +	if (IS_ERR(st->vref_reg)) {
> There are two error cases that should be handled. One is no regulator
> is
> specified and the other is a regulator is specified, but something
> went
> wrong. In the later case the error should be reported and not
> ignored. Have
> a look at e.g. ad5592r-base.c as an example.
> 
> > 
> > +		/* use internal reference voltage */
> > +		st->vref_reg = NULL;
> > +		st->vref_mv = chip_info->vref_mv;
> > +
> > +		ret = ltc2632_spi_write(spi,
> > LTC2632_CMD_INTERNAL_REFER,
> > +				0, 0, 0);
> > +		if (ret) {
> > +			dev_err(&spi->dev,
> > +				"Set internal reference command
> > failed, %d\n",
> > +				ret);
> > +			return ret;
> > +		}
> > +	} else {
> > +		/* use external reference voltage */
> > +		ret = regulator_enable(st->vref_reg);
> > +		if (ret) {
> > +			dev_err(&spi->dev,
> > +				"enable reference regulator
> > failed, %d\n",
> > +				ret);
> > +			return ret;
> > +		}
> > +		st->vref_mv = regulator_get_voltage(st-
> > >vref_reg)/1000;
> Should be space around '/'.
> 
> > 
> > +
> > +		ret = ltc2632_spi_write(spi,
> > LTC2632_CMD_EXTERNAL_REFER,
> > +				0, 0, 0);
> > +		if (ret) {
> > +			dev_err(&spi->dev,
> > +				"Set external reference command
> > failed, %d\n",
> > +				ret);
> > +			return ret;
> > +		}
> > +	}
> > +
> >  	indio_dev->dev.parent = &spi->dev;
> >  	indio_dev->name = dev_of_node(&spi->dev) ?
> > dev_of_node(&spi->dev)->name
> >  						 :
> > spi_get_device_id(spi)->name;
> > @@ -255,14 +296,23 @@ static int ltc2632_probe(struct spi_device
> > *spi)
> >  	indio_dev->channels = chip_info->channels;
> >  	indio_dev->num_channels = LTC2632_DAC_CHANNELS;
> >  
> > -	ret = ltc2632_spi_write(spi, LTC2632_CMD_INTERNAL_REFER,
> > 0, 0, 0);
> > -	if (ret) {
> > -		dev_err(&spi->dev,
> > -			"Set internal reference command failed,
> > %d\n", ret);
> > -		return ret;
> > +	return devm_iio_device_register(&spi->dev, indio_dev);
> > +}
> > +
> > +static int ltc2632_remove(struct spi_device *spi)
> > +{
> > +	struct iio_dev *indio_dev = spi_get_drvdata(spi);
> > +	struct ltc2632_state *st = iio_priv(indio_dev);
> > +
> > +	devm_iio_device_unregister(&spi->dev, indio_dev);
> > +
> > +	if (st->vref_reg != NULL) {
> > +		regulator_disable(st->vref_reg);
> > +		devm_regulator_put(st->vref_reg);
> >  	}
> >  
> > -	return devm_iio_device_register(&spi->dev, indio_dev);
> > +	devm_iio_device_free(&spi->dev, indio_dev);
> The idea behind the devm_* interface is that you do not explicitly
> call it
> in the remove() callback. It will automatically run after the remove
> function.
> 
> This means in this case you can remove the devm_regulator_put() and
> devm_iio_device_free().
> 
> The devm_iio_device_unregister() still needs to say since we have to
> unregister the device before we disable the regulator. But you can
> simplify
> this by using the non-managed API
> (iio_device_unregister()/iio_device_unregister()).
> 
> > 
> > +	return 0;
> >  }
> >  
> >  static const struct spi_device_id ltc2632_id[] = {
> > @@ -276,15 +326,6 @@ static const struct spi_device_id ltc2632_id[]
> > = {
> >  };
> >  MODULE_DEVICE_TABLE(spi, ltc2632_id);
> >  
> > -static struct spi_driver ltc2632_driver = {
> > -	.driver		= {
> > -		.name	= "ltc2632",
> > -	},
> > -	.probe		= ltc2632_probe,
> > -	.id_table	= ltc2632_id,
> > -};
> > -module_spi_driver(ltc2632_driver);
> > -
> >  static const struct of_device_id ltc2632_of_match[] = {
> >  	{
> >  		.compatible = "lltc,ltc2632-l12",
> > @@ -309,6 +350,17 @@ static const struct of_device_id
> > ltc2632_of_match[] = {
> >  };
> >  MODULE_DEVICE_TABLE(of, ltc2632_of_match);
> >  
> > +static struct spi_driver ltc2632_driver = {
> > +	.driver		= {
> > +		.name	= "ltc2632",
> > +		.of_match_table = of_match_ptr(ltc2632_of_match),
> It's a bit strange that of_match_table was not assigned in the first
> place.
> I think this should be a separate change and be declared as a fix.
> 
> > 
> > +	},
> > +	.probe		= ltc2632_probe,
> > +	.remove     = ltc2632_remove,
> This line uses tabs for alignment, while all the other lines use
> tabs.
> 
> > 
> > +	.id_table	= ltc2632_id,
> > +};
> > +module_spi_driver(ltc2632_driver);

^ permalink raw reply

* [PATCH v2 4/4] misc: pci_endpoint_test: Add DesignWare EP entry
From: Gustavo Pimentel @ 2018-05-15 14:41 UTC (permalink / raw)
  To: bhelgaas, lorenzo.pieralisi, Joao.Pinto, jingoohan1, kishon,
	robh+dt, mark.rutland
  Cc: linux-pci, linux-kernel, devicetree, Gustavo Pimentel
In-Reply-To: <cover.1526395185.git.gustavo.pimentel@synopsys.com>

Add the DesignWare EP device ID entry to pci_endpoint_test driver table.

Allow the device to be recognize and handle by the pci_endpoint_test
driver.

Signed-off-by: Gustavo Pimentel <gustavo.pimentel@synopsys.com>
Acked-by: Kishon Vijay Abraham I <kishon@ti.com>
---
 drivers/misc/pci_endpoint_test.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/misc/pci_endpoint_test.c b/drivers/misc/pci_endpoint_test.c
index fe8897e..58a88ba 100644
--- a/drivers/misc/pci_endpoint_test.c
+++ b/drivers/misc/pci_endpoint_test.c
@@ -634,6 +634,7 @@ static void pci_endpoint_test_remove(struct pci_dev *pdev)
 static const struct pci_device_id pci_endpoint_test_tbl[] = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_DRA74x) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_DRA72x) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_SYNOPSYS, 0xedda) },
 	{ }
 };
 MODULE_DEVICE_TABLE(pci, pci_endpoint_test_tbl);
-- 
2.7.4

^ permalink raw reply related

* [PATCH v2 3/4] bindings: PCI: designware: Add support for EP in DesignWare driver
From: Gustavo Pimentel @ 2018-05-15 14:41 UTC (permalink / raw)
  To: bhelgaas, lorenzo.pieralisi, Joao.Pinto, jingoohan1, kishon,
	robh+dt, mark.rutland
  Cc: linux-pci, linux-kernel, devicetree, Gustavo Pimentel
In-Reply-To: <cover.1526395185.git.gustavo.pimentel@synopsys.com>

Add device tree binding documentation for the EP in PCIe DesignWare driver.

Signed-off-by: Gustavo Pimentel <gustavo.pimentel@synopsys.com>
Reviewed-by: Rob Herring <robh@kernel.org>
---
 Documentation/devicetree/bindings/pci/designware-pcie.txt | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/Documentation/devicetree/bindings/pci/designware-pcie.txt b/Documentation/devicetree/bindings/pci/designware-pcie.txt
index 7f9804d..c124f9b 100644
--- a/Documentation/devicetree/bindings/pci/designware-pcie.txt
+++ b/Documentation/devicetree/bindings/pci/designware-pcie.txt
@@ -3,6 +3,7 @@
 Required properties:
 - compatible:
 	"snps,dw-pcie" for RC mode;
+	"snps,dw-pcie-ep" for EP mode;
 - reg: Should contain the configuration address space.
 - reg-names: Must be "config" for the PCIe configuration space.
     (The old way of getting the configuration address space from "ranges"
@@ -56,3 +57,14 @@ Example configuration:
 		#interrupt-cells = <1>;
 		num-lanes = <1>;
 	};
+or
+	pcie: pcie@dfc00000 {
+		compatible = "snps,dw-pcie-ep";
+		reg = <0xdfc00000 0x0001000>, /* IP registers 1 */
+		      <0xdfc01000 0x0001000>, /* IP registers 2 */
+		      <0xd0000000 0x2000000>; /* Configuration space */
+		reg-names = "dbi", "dbi2", "addr_space";
+		num-ib-windows = <6>;
+		num-ob-windows = <2>;
+		num-lanes = <1>;
+	};
-- 
2.7.4

^ permalink raw reply related

* [PATCH v2 2/4] PCI: dwc: Add support for EP mode
From: Gustavo Pimentel @ 2018-05-15 14:41 UTC (permalink / raw)
  To: bhelgaas, lorenzo.pieralisi, Joao.Pinto, jingoohan1, kishon,
	robh+dt, mark.rutland
  Cc: linux-pci, linux-kernel, devicetree, Gustavo Pimentel
In-Reply-To: <cover.1526395185.git.gustavo.pimentel@synopsys.com>

The PCIe controller dual mode is capable of operating in RC mode as well
as EP mode by configuration option. Till now only RC mode was supported,
with this patch is add EP support to the DesignWare driver.

Add new property on pci_epc structure which allow to configure
pci_epf_test driver accordingly to the controller specific requirements.

Signed-off-by: Gustavo Pimentel <gustavo.pimentel@synopsys.com>
Acked-by: Kishon Vijay Abraham I <kishon@ti.com>
---
 drivers/pci/dwc/Kconfig                       |  37 +++++--
 drivers/pci/dwc/pcie-designware-ep.c          |   3 +
 drivers/pci/dwc/pcie-designware-plat.c        | 149 ++++++++++++++++++++++++--
 drivers/pci/endpoint/functions/pci-epf-test.c |   7 ++
 include/linux/pci-epc.h                       |   8 ++
 5 files changed, 186 insertions(+), 18 deletions(-)

diff --git a/drivers/pci/dwc/Kconfig b/drivers/pci/dwc/Kconfig
index 8c1a516..ce9e5a5 100644
--- a/drivers/pci/dwc/Kconfig
+++ b/drivers/pci/dwc/Kconfig
@@ -51,16 +51,37 @@ config PCI_DRA7XX_EP
 	  This uses the DesignWare core.
 
 config PCIE_DW_PLAT
-	bool "Platform bus based DesignWare PCIe Controller"
-	depends on PCI_MSI_IRQ_DOMAIN
-	select PCIE_DW_HOST
-	---help---
-	 This selects the DesignWare PCIe controller support. Select this if
-	 you have a PCIe controller on Platform bus.
+	bool
 
-	 If you have a controller with this interface, say Y or M here.
+config PCIE_DW_PLAT_HOST
+	bool "Platform bus based DesignWare PCIe Controller - Host mode"
+	depends on PCI && PCI_MSI_IRQ_DOMAIN
+	select PCIE_DW_HOST
+	select PCIE_DW_PLAT
+	default y
+	help
+	  Enables support for the PCIe controller in the Designware IP to
+	  work in host mode. There are two instances of PCIe controller in
+	  Designware IP.
+	  This controller can work either as EP or RC. In order to enable
+	  host-specific features PCIE_DW_PLAT_HOST must be selected and in
+	  order to enable device-specific features PCI_DW_PLAT_EP must be
+	  selected.
 
-	 If unsure, say N.
+config PCIE_DW_PLAT_EP
+	bool "Platform bus based DesignWare PCIe Controller - Endpoint mode"
+	depends on PCI && PCI_MSI_IRQ_DOMAIN
+	depends on PCI_ENDPOINT
+	select PCIE_DW_EP
+	select PCIE_DW_PLAT
+	help
+	  Enables support for the PCIe controller in the Designware IP to
+	  work in endpoint mode. There are two instances of PCIe controller
+	  in Designware IP.
+	  This controller can work either as EP or RC. In order to enable
+	  host-specific features PCIE_DW_PLAT_HOST must be selected and in
+	  order to enable device-specific features PCI_DW_PLAT_EP must be
+	  selected.
 
 config PCI_EXYNOS
 	bool "Samsung Exynos PCIe controller"
diff --git a/drivers/pci/dwc/pcie-designware-ep.c b/drivers/pci/dwc/pcie-designware-ep.c
index 15b22a6..1eec441 100644
--- a/drivers/pci/dwc/pcie-designware-ep.c
+++ b/drivers/pci/dwc/pcie-designware-ep.c
@@ -411,6 +411,9 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
 		return -ENOMEM;
 	}
 
+	epc->features = EPC_FEATURE_NO_LINKUP_NOTIFIER;
+	EPC_FEATURE_SET_BAR(epc->features, BAR_0);
+
 	ep->epc = epc;
 	epc_set_drvdata(epc, ep);
 	dw_pcie_setup(pci);
diff --git a/drivers/pci/dwc/pcie-designware-plat.c b/drivers/pci/dwc/pcie-designware-plat.c
index 80a2782..5937fed 100644
--- a/drivers/pci/dwc/pcie-designware-plat.c
+++ b/drivers/pci/dwc/pcie-designware-plat.c
@@ -12,19 +12,29 @@
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/of_device.h>
 #include <linux/of_gpio.h>
 #include <linux/pci.h>
 #include <linux/platform_device.h>
 #include <linux/resource.h>
 #include <linux/signal.h>
 #include <linux/types.h>
+#include <linux/regmap.h>
 
 #include "pcie-designware.h"
 
 struct dw_plat_pcie {
-	struct dw_pcie		*pci;
+	struct dw_pcie			*pci;
+	struct regmap			*regmap;
+	enum dw_pcie_device_mode	mode;
 };
 
+struct dw_plat_pcie_of_data {
+	enum dw_pcie_device_mode	mode;
+};
+
+static const struct of_device_id dw_plat_pcie_of_match[];
+
 static int dw_plat_pcie_host_init(struct pcie_port *pp)
 {
 	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
@@ -48,9 +58,53 @@ static const struct dw_pcie_host_ops dw_plat_pcie_host_ops = {
 	.set_num_vectors = dw_plat_set_num_vectors,
 };
 
-static int dw_plat_add_pcie_port(struct pcie_port *pp,
+static int dw_plat_pcie_establish_link(struct dw_pcie *pci)
+{
+	return 0;
+}
+
+static const struct dw_pcie_ops dw_pcie_ops = {
+	.start_link = dw_plat_pcie_establish_link,
+};
+
+static void dw_plat_pcie_ep_init(struct dw_pcie_ep *ep)
+{
+	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
+	enum pci_barno bar;
+
+	for (bar = BAR_0; bar <= BAR_5; bar++)
+		dw_pcie_ep_reset_bar(pci, bar);
+}
+
+static int dw_plat_pcie_ep_raise_irq(struct dw_pcie_ep *ep, u8 func_no,
+				     enum pci_epc_irq_type type,
+				     u8 interrupt_num)
+{
+	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
+
+	switch (type) {
+	case PCI_EPC_IRQ_LEGACY:
+		dev_err(pci->dev, "EP cannot trigger legacy IRQs\n");
+		return -EINVAL;
+	case PCI_EPC_IRQ_MSI:
+		return dw_pcie_ep_raise_msi_irq(ep, func_no, interrupt_num);
+	default:
+		dev_err(pci->dev, "UNKNOWN IRQ type\n");
+	}
+
+	return 0;
+}
+
+static struct dw_pcie_ep_ops pcie_ep_ops = {
+	.ep_init = dw_plat_pcie_ep_init,
+	.raise_irq = dw_plat_pcie_ep_raise_irq,
+};
+
+static int dw_plat_add_pcie_port(struct dw_plat_pcie *dw_plat_pcie,
 				 struct platform_device *pdev)
 {
+	struct dw_pcie *pci = dw_plat_pcie->pci;
+	struct pcie_port *pp = &pci->pp;
 	struct device *dev = &pdev->dev;
 	int ret;
 
@@ -69,15 +123,44 @@ static int dw_plat_add_pcie_port(struct pcie_port *pp,
 
 	ret = dw_pcie_host_init(pp);
 	if (ret) {
-		dev_err(dev, "failed to initialize host\n");
+		dev_err(dev, "Failed to initialize host\n");
 		return ret;
 	}
 
 	return 0;
 }
 
-static const struct dw_pcie_ops dw_pcie_ops = {
-};
+static int dw_plat_add_pcie_ep(struct dw_plat_pcie *dw_plat_pcie,
+			       struct platform_device *pdev)
+{
+	int ret;
+	struct dw_pcie_ep *ep;
+	struct resource *res;
+	struct device *dev = &pdev->dev;
+	struct dw_pcie *pci = dw_plat_pcie->pci;
+
+	ep = &pci->ep;
+	ep->ops = &pcie_ep_ops;
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi2");
+	pci->dbi_base2 = devm_ioremap_resource(dev, res);
+	if (IS_ERR(pci->dbi_base2))
+		return PTR_ERR(pci->dbi_base2);
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "addr_space");
+	if (!res)
+		return -EINVAL;
+
+	ep->phys_base = res->start;
+	ep->addr_size = resource_size(res);
+
+	ret = dw_pcie_ep_init(ep);
+	if (ret) {
+		dev_err(dev, "Failed to initialize endpoint\n");
+		return ret;
+	}
+	return 0;
+}
 
 static int dw_plat_pcie_probe(struct platform_device *pdev)
 {
@@ -86,6 +169,16 @@ static int dw_plat_pcie_probe(struct platform_device *pdev)
 	struct dw_pcie *pci;
 	struct resource *res;  /* Resource from DT */
 	int ret;
+	const struct of_device_id *match;
+	const struct dw_plat_pcie_of_data *data;
+	enum dw_pcie_device_mode mode;
+
+	match = of_match_device(dw_plat_pcie_of_match, dev);
+	if (!match)
+		return -EINVAL;
+
+	data = (struct dw_plat_pcie_of_data *)match->data;
+	mode = (enum dw_pcie_device_mode)data->mode;
 
 	dw_plat_pcie = devm_kzalloc(dev, sizeof(*dw_plat_pcie), GFP_KERNEL);
 	if (!dw_plat_pcie)
@@ -99,23 +192,59 @@ static int dw_plat_pcie_probe(struct platform_device *pdev)
 	pci->ops = &dw_pcie_ops;
 
 	dw_plat_pcie->pci = pci;
+	dw_plat_pcie->mode = mode;
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi");
+	if (!res)
+		res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	pci->dbi_base = devm_ioremap_resource(dev, res);
 	if (IS_ERR(pci->dbi_base))
 		return PTR_ERR(pci->dbi_base);
 
 	platform_set_drvdata(pdev, dw_plat_pcie);
 
-	ret = dw_plat_add_pcie_port(&pci->pp, pdev);
-	if (ret < 0)
-		return ret;
+	switch (dw_plat_pcie->mode) {
+	case DW_PCIE_RC_TYPE:
+		if (!IS_ENABLED(CONFIG_PCIE_DW_PLAT_HOST))
+			return -ENODEV;
+
+		ret = dw_plat_add_pcie_port(dw_plat_pcie, pdev);
+		if (ret < 0)
+			return ret;
+		break;
+	case DW_PCIE_EP_TYPE:
+		if (!IS_ENABLED(CONFIG_PCIE_DW_PLAT_EP))
+			return -ENODEV;
+
+		ret = dw_plat_add_pcie_ep(dw_plat_pcie, pdev);
+		if (ret < 0)
+			return ret;
+		break;
+	default:
+		dev_err(dev, "INVALID device type %d\n", dw_plat_pcie->mode);
+	}
 
 	return 0;
 }
 
+static const struct dw_plat_pcie_of_data dw_plat_pcie_rc_of_data = {
+	.mode = DW_PCIE_RC_TYPE,
+};
+
+static const struct dw_plat_pcie_of_data dw_plat_pcie_ep_of_data = {
+	.mode = DW_PCIE_EP_TYPE,
+};
+
 static const struct of_device_id dw_plat_pcie_of_match[] = {
-	{ .compatible = "snps,dw-pcie", },
+	{
+		.compatible = "snps,dw-pcie",
+		.data = &dw_plat_pcie_rc_of_data,
+	},
+	{
+		.compatible = "snps,dw-pcie-ep",
+		.data = &dw_plat_pcie_ep_of_data,
+	},
 	{},
 };
 
diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c
index 7cef851..bee401d 100644
--- a/drivers/pci/endpoint/functions/pci-epf-test.c
+++ b/drivers/pci/endpoint/functions/pci-epf-test.c
@@ -435,6 +435,13 @@ static int pci_epf_test_bind(struct pci_epf *epf)
 	if (WARN_ON_ONCE(!epc))
 		return -EINVAL;
 
+	if (epc->features & EPC_FEATURE_NO_LINKUP_NOTIFIER)
+		epf_test->linkup_notifier = false;
+	else
+		epf_test->linkup_notifier = true;
+
+	epf_test->test_reg_bar = EPC_FEATURE_GET_BAR(epc->features);
+
 	ret = pci_epc_write_header(epc, epf->func_no, header);
 	if (ret) {
 		dev_err(dev, "configuration header write failed\n");
diff --git a/include/linux/pci-epc.h b/include/linux/pci-epc.h
index af657ca..243eaa5 100644
--- a/include/linux/pci-epc.h
+++ b/include/linux/pci-epc.h
@@ -90,8 +90,16 @@ struct pci_epc {
 	struct config_group		*group;
 	/* spinlock to protect against concurrent access of EP controller */
 	spinlock_t			lock;
+	unsigned int			features;
 };
 
+#define EPC_FEATURE_NO_LINKUP_NOTIFIER		BIT(0)
+#define EPC_FEATURE_BAR_MASK			(BIT(1) | BIT(2) | BIT(3))
+#define EPC_FEATURE_SET_BAR(features, bar)	\
+		(features |= (EPC_FEATURE_BAR_MASK & (bar << 1)))
+#define EPC_FEATURE_GET_BAR(features)		\
+		((features & EPC_FEATURE_BAR_MASK) >> 1)
+
 #define to_pci_epc(device) container_of((device), struct pci_epc, dev)
 
 #define pci_epc_create(dev, ops)    \
-- 
2.7.4

^ permalink raw reply related

* [PATCH v2 1/4] bindings: PCI: designware: Example update
From: Gustavo Pimentel @ 2018-05-15 14:41 UTC (permalink / raw)
  To: bhelgaas, lorenzo.pieralisi, Joao.Pinto, jingoohan1, kishon,
	robh+dt, mark.rutland
  Cc: linux-pci, linux-kernel, devicetree, Gustavo Pimentel
In-Reply-To: <cover.1526395185.git.gustavo.pimentel@synopsys.com>

Replace "ctrlreg" reg-name by "dbi" to be coherent with similar drivers,
however it still be compatible with any previous DT that uses the old
reg-name.

Replace the PCIe base address example by a real PCIe base address in use.

Signed-off-by: Gustavo Pimentel <gustavo.pimentel@synopsys.com>
Reviewed-by: Rob Herring <robh@kernel.org>
---
 Documentation/devicetree/bindings/pci/designware-pcie.txt | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/Documentation/devicetree/bindings/pci/designware-pcie.txt b/Documentation/devicetree/bindings/pci/designware-pcie.txt
index 1da7ade..7f9804d 100644
--- a/Documentation/devicetree/bindings/pci/designware-pcie.txt
+++ b/Documentation/devicetree/bindings/pci/designware-pcie.txt
@@ -1,7 +1,8 @@
 * Synopsys DesignWare PCIe interface
 
 Required properties:
-- compatible: should contain "snps,dw-pcie" to identify the core.
+- compatible:
+	"snps,dw-pcie" for RC mode;
 - reg: Should contain the configuration address space.
 - reg-names: Must be "config" for the PCIe configuration space.
     (The old way of getting the configuration address space from "ranges"
@@ -41,11 +42,11 @@ EP mode:
 
 Example configuration:
 
-	pcie: pcie@dffff000 {
+	pcie: pcie@dfc00000 {
 		compatible = "snps,dw-pcie";
-		reg = <0xdffff000 0x1000>, /* Controller registers */
-		      <0xd0000000 0x2000>; /* PCI config space */
-		reg-names = "ctrlreg", "config";
+		reg = <0xdfc00000 0x0001000>, /* IP registers */
+		      <0xd0000000 0x0002000>; /* Configuration space */
+		reg-names = "dbi", "config";
 		#address-cells = <3>;
 		#size-cells = <2>;
 		device_type = "pci";
@@ -54,5 +55,4 @@ Example configuration:
 		interrupts = <25>, <24>;
 		#interrupt-cells = <1>;
 		num-lanes = <1>;
-		num-viewport = <3>;
 	};
-- 
2.7.4

^ permalink raw reply related

* [PATCH v2 0/4] Add DesignWare EP support
From: Gustavo Pimentel @ 2018-05-15 14:41 UTC (permalink / raw)
  To: bhelgaas, lorenzo.pieralisi, Joao.Pinto, jingoohan1, kishon,
	robh+dt, mark.rutland
  Cc: linux-pci, linux-kernel, devicetree, Gustavo Pimentel

Patch set was made against the Lorenzo's pci/dwc branch.

The PCIe controller dual mode is capable of operating in RC mode as well
as EP mode by configuration option. Till now only RC mode was supported,
with this patch is add EP support to the DesignWare driver.

Gustavo Pimentel (4):
  bindings: PCI: designware: Example update
  PCI: dwc: Add support for EP mode
  bindings: PCI: designware: Add support for EP in DesignWare driver
  misc: pci_endpoint_test: Add DesignWare EP entry

 .../devicetree/bindings/pci/designware-pcie.txt    |  24 +++-
 drivers/misc/pci_endpoint_test.c                   |   1 +
 drivers/pci/dwc/Kconfig                            |  37 +++--
 drivers/pci/dwc/pcie-designware-ep.c               |   3 +
 drivers/pci/dwc/pcie-designware-plat.c             | 149 +++++++++++++++++++--
 drivers/pci/endpoint/functions/pci-epf-test.c      |   7 +
 include/linux/pci-epc.h                            |   8 ++
 7 files changed, 205 insertions(+), 24 deletions(-)

-- 
2.7.4

^ 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