Devicetree
 help / color / mirror / Atom feed
* Re: [PATCH v5 2/2] DW DMAC: add multi-block property to device tree
From: Andy Shevchenko @ 2016-11-24 15:52 UTC (permalink / raw)
  To: Eugeniy Paltsev, devicetree-u79uwXL29TY76Z2rM5mHXA
  Cc: robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	vinod.koul-ral2JQCrhuEAvxtiuMwx3w,
	dmaengine-u79uwXL29TY76Z2rM5mHXA, arnd-r2nGTMty4D4,
	linux-snps-arc-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	vireshk-DgEjT+Ai2ygdnm+yROfE0A,
	shiraz.linux.kernel-Re5JQEeQqe8AvxtiuMwx3w,
	christian.ruppert-Yycd8EPnGM5BDgjK7y7TUQ
In-Reply-To: <1479999878-19120-3-git-send-email-Eugeniy.Paltsev-HKixBCOQz3hWk0Htik3J/w@public.gmane.org>

On Thu, 2016-11-24 at 18:04 +0300, Eugeniy Paltsev wrote:
> Several versions of DW DMAC have multi block transfers hardware
> support. Hardware support of multi block transfers is disabled
> by default if we use DT to configure DMAC and software emulation
> of multi block transfers used instead.
> Add multi-block property, so it is possible to enable hardware
> multi block transfers (if present) via DT.
> 
> Switch from per device is_nollp variable to multi_block array
> to be able enable/disable multi block transfers separately per
> channel.

Thanks for an update. Basically I'm fine with this one.

So, we still have question about autoconfiguration in SPEAr SoCs, and
your ARC SoC but it's a different story. I would expect once you will
clarify it.

Another one is minor listed below, otherwise

Acked-by: Andy Shevchenko <andriy.shevchenko-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>

> Signed-off-by: Eugeniy Paltsev <Eugeniy.Paltsev-HKixBCOQz3hWk0Htik3J/w@public.gmane.org>

> --- a/drivers/dma/dw/platform.c
> +++ b/drivers/dma/dw/platform.c
> @@ -102,7 +102,7 @@ dw_dma_parse_dt(struct platform_device *pdev)
>  {
>  	struct device_node *np = pdev->dev.of_node;
>  	struct dw_dma_platform_data *pdata;
> -	u32 tmp, arr[DW_DMA_MAX_NR_MASTERS];
> +	u32 tmp, arr[DW_DMA_MAX_NR_MASTERS],
> chan[DW_DMA_MAX_NR_CHANNELS];

chan here will confuse people...

> @@ -152,6 +154,11 @@ dw_dma_parse_dt(struct platform_device *pdev)
>  			pdata->data_width[tmp] = BIT(arr[tmp] &
> 0x07);
>  	}
>  
> +	if (!of_property_read_u32_array(np, "multi-block", chan,
> nr_channels)) {
> +		for (tmp = 0; tmp < nr_channels; tmp++)
> +			pdata->multi_block[tmp] = chan[tmp];

...mb (as short of multi-block) would suit better.

-- 
Andy Shevchenko <andriy.shevchenko-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
Intel Finland Oy
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [net-next PATCH v1 0/2] stmmac: dwmac-meson8b: configurable RGMII TX delay
From: Jerome Brunet @ 2016-11-24 15:56 UTC (permalink / raw)
  To: Martin Blumenstingl, linux-amlogic, devicetree, netdev, davem,
	khilman, mark.rutland, robh+dt
  Cc: linux-arm-kernel, alexandre.torgue, peppe.cavallaro, carlo
In-Reply-To: <20161124143417.10178-1-martin.blumenstingl@googlemail.com>

On Thu, 2016-11-24 at 15:34 +0100, Martin Blumenstingl wrote:
> Currently the dwmac-meson8b stmmac glue driver uses a hardcoded 1/4
> cycle TX clock delay. This seems to work fine for many boards (for
> example Odroid-C2 or Amlogic's reference boards) but there are some
> others where TX traffic is simply broken.
> There are probably multiple reasons why it's working on some boards
> while it's broken on others:
> - some of Amlogic's reference boards are using a Micrel PHY
> - hardware circuit design
> - maybe more...
> 
> This raises a question though:
> Which device is supposed to enable the TX delay when both MAC and PHY
> support it? And should we implement it for each PHY / MAC separately
> or should we think about a more generic solution (currently it's not
> possible to disable the TX delay generated by the RTL8211F PHY via
> devicetree when using phy-mode "rgmii")?

Actually you can skip the part which activate the Tx-delay on the phy
by setting "phy-mode = "rgmii-id" instead of "rgmii"

phy->interface will no longer be PHY_INTERFACE_MODE_RGMII
but PHY_INTERFACE_MODE_RGMII_ID.

> 
> iperf3 results on my Mecool BB2 board (Meson GXM, RTL8211F PHY) with
> TX clock delay disabled on the MAC (as it's enabled in the PHY
> driver).
> TX throughput was virtually zero before:
> $ iperf3 -c 192.168.1.100 -R          
> Connecting to host 192.168.1.100, port 5201
> Reverse mode, remote host 192.168.1.100 is sending
> [  4] local 192.168.1.206 port 52828 connected to 192.168.1.100 port
> 5201
> [ ID] Interval           Transfer     Bandwidth
> [  4]   0.00-1.00   sec   108 MBytes   901
> Mbits/sec                  
> [  4]   1.00-2.00   sec  94.2 MBytes   791
> Mbits/sec                  
> [  4]   2.00-3.00   sec  96.5 MBytes   810
> Mbits/sec                  
> [  4]   3.00-4.00   sec  96.2 MBytes   808
> Mbits/sec                  
> [  4]   4.00-5.00   sec  96.6 MBytes   810
> Mbits/sec                  
> [  4]   5.00-6.00   sec  96.5 MBytes   810
> Mbits/sec                  
> [  4]   6.00-7.00   sec  96.6 MBytes   810
> Mbits/sec                  
> [  4]   7.00-8.00   sec  96.5 MBytes   809
> Mbits/sec                  
> [  4]   8.00-9.00   sec   105 MBytes   884
> Mbits/sec                  
> [  4]   9.00-10.00  sec   111 MBytes   934
> Mbits/sec                  
> - - - - - - - - - - - - - - - - - - - - - - - - -
> [ ID] Interval           Transfer     Bandwidth       Retr
> [  4]   0.00-10.00  sec  1000 MBytes   839
> Mbits/sec    0             sender
> [  4]   0.00-10.00  sec   998 MBytes   837
> Mbits/sec                  receiver
> 
> iperf Done.
> $ iperf3 -c 192.168.1.100   
> Connecting to host 192.168.1.100, port 5201
> [  4] local 192.168.1.206 port 52832 connected to 192.168.1.100 port
> 5201
> [ ID] Interval           Transfer     Bandwidth       Retr  Cwnd
> [  4]   0.00-1.01   sec  99.5 MBytes   829 Mbits/sec  117    139
> KBytes       
> [  4]   1.01-2.00   sec   105 MBytes   884 Mbits/sec  129   70.7
> KBytes       
> [  4]   2.00-3.01   sec   107 MBytes   889 Mbits/sec  106    187
> KBytes       
> [  4]   3.01-4.01   sec   105 MBytes   878 Mbits/sec   92    143
> KBytes       
> [  4]   4.01-5.00   sec   105 MBytes   882 Mbits/sec  140    129
> KBytes       
> [  4]   5.00-6.01   sec   106 MBytes   883 Mbits/sec  115    195
> KBytes       
> [  4]   6.01-7.00   sec   102 MBytes   863 Mbits/sec  133   70.7
> KBytes       
> [  4]   7.00-8.01   sec   106 MBytes   884 Mbits/sec  143   97.6
> KBytes       
> [  4]   8.01-9.01   sec   104 MBytes   875 Mbits/sec  124    107
> KBytes       
> [  4]   9.01-10.01  sec   105 MBytes   876 Mbits/sec   90    139
> KBytes       
> - - - - - - - - - - - - - - - - - - - - - - - - -
> [ ID] Interval           Transfer     Bandwidth       Retr
> [  4]   0.00-10.01  sec  1.02 GBytes   874
> Mbits/sec  1189             sender
> [  4]   0.00-10.01  sec  1.02 GBytes   873
> Mbits/sec                  receiver
> 
> iperf Done.

> 
> 
> Martin Blumenstingl (2):
>   net: dt-bindings: add RGMII TX delay configuration to meson8b-dwmac
>   net: stmmac: dwmac-meson8b: make the RGMII TX delay configurable
> 
>  Documentation/devicetree/bindings/net/meson-dwmac.txt | 11
> +++++++++++
>  drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c   | 16
> +++++++++++-----
>  include/dt-bindings/net/dwmac-meson8b.h               | 18
> ++++++++++++++++++
>  3 files changed, 40 insertions(+), 5 deletions(-)
>  create mode 100644 include/dt-bindings/net/dwmac-meson8b.h
> 

^ permalink raw reply

* Re: [PATCH v5 2/2] DW DMAC: add multi-block property to device tree
From: Andy Shevchenko @ 2016-11-24 15:58 UTC (permalink / raw)
  To: Eugeniy Paltsev, devicetree-u79uwXL29TY76Z2rM5mHXA
  Cc: robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	vinod.koul-ral2JQCrhuEAvxtiuMwx3w,
	dmaengine-u79uwXL29TY76Z2rM5mHXA, arnd-r2nGTMty4D4,
	linux-snps-arc-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	vireshk-DgEjT+Ai2ygdnm+yROfE0A,
	shiraz.linux.kernel-Re5JQEeQqe8AvxtiuMwx3w,
	christian.ruppert-Yycd8EPnGM5BDgjK7y7TUQ
In-Reply-To: <1480002728.20074.15.camel-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>

On Thu, 2016-11-24 at 17:52 +0200, Andy Shevchenko wrote:
> On Thu, 2016-11-24 at 18:04 +0300, Eugeniy Paltsev wrote:
> > Several versions of DW DMAC have multi block transfers hardware
> > support. Hardware support of multi block transfers is disabled
> > by default if we use DT to configure DMAC and software emulation
> > of multi block transfers used instead.
> > Add multi-block property, so it is possible to enable hardware
> > multi block transfers (if present) via DT.
> > 
> > Switch from per device is_nollp variable to multi_block array
> > to be able enable/disable multi block transfers separately per
> > channel.
> 
> Thanks for an update. Basically I'm fine with this one.
> 
> So, we still have question about autoconfiguration in SPEAr SoCs, and
> your ARC SoC but it's a different story. I would expect once you will
> clarify it.
> 
> Another one is minor listed below, otherwise
> 
> Acked-by: Andy Shevchenko <andriy.shevchenko-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>

> > @@ -152,6 +154,11 @@ dw_dma_parse_dt(struct platform_device *pdev)
> >  			pdata->data_width[tmp] = BIT(arr[tmp] &
> > 0x07);
> >  	}
> >  
> > +	if (!of_property_read_u32_array(np, "multi-block", chan,
> > nr_channels)) {
> > +		for (tmp = 0; tmp < nr_channels; tmp++)
> > +			pdata->multi_block[tmp] = chan[tmp];
> 
> ...mb (as short of multi-block) would suit better.

Oh, sorry, guys, but one more important thing. If there is no such
property, keep a default to "supported". Otherwise you will break old
(working) DTBs.

-- 
Andy Shevchenko <andriy.shevchenko-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
Intel Finland Oy
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [RFC PATCH net v2 0/3] Fix OdroidC2 Gigabit Tx link issue
From: Jerome Brunet @ 2016-11-24 16:01 UTC (permalink / raw)
  To: Martin Blumenstingl
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA, devicetree-u79uwXL29TY76Z2rM5mHXA,
	Florian Fainelli, Carlo Caione, Kevin Hilman, Giuseppe Cavallaro,
	Alexandre TORGUE, Andre Roth, Neil Armstrong,
	linux-amlogic-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <CAFBinCCexmS_z9FCX-ud5NgGhhP7xJ_cLxpC7TEc=mLAdafosg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>

On Thu, 2016-11-24 at 15:40 +0100, Martin Blumenstingl wrote:
> Hi Jerome,
> 
> On Mon, Nov 21, 2016 at 4:35 PM, Jerome Brunet <jbrunet-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
> wrote:
> > 
> > This patchset fixes an issue with the OdroidC2 board (DWMAC +
> > RTL8211F).
> > Initially reported as a low Tx throughput issue at gigabit speed,
> > the
> > platform enters LPI too often. This eventually break the link (both
> > Tx
> > and Rx), and require to bring the interface down and up again to
> > get the
> > Rx path working again.
> > 
> > The root cause of this issue is not fully understood yet but
> > disabling EEE
> > advertisement on the PHY prevent this feature to be negotiated.
> > With this change, the link is stable and reliable, with the
> > expected
> > throughput performance.
> I have just sent a series which allows configuring the TX delay on
> the
> MAC (dwmac-meson8b glue) side: [0]
> Disabling the TX delay generated by the MAC fixes TX throughput for
> me, even when leaving EEE enabled in the RTL8211F PHY driver!
> 
> Unfortunately the RTL8211F PHY is a black-box for the community
> because there is no public datasheeet available.
> *maybe* (pure speculation!) they're enabling the TX delay based on
> some internal magic only when EEE is enabled.

Hi already tried acting on the register setting the TX_delay. I also
tried on the PHY. I never been able to improve situation on the
Odroic2. Only disabling EEE improved the situation.

To make sure, i tried again with your patch but the result remains
unchanged. With Tx_delay disabled (either the mac or the phy), the
situation is even worse, it seems that nothing gets through

> 
> Jerome, could you please re-test the behavior on your Odroid-C2 when
> you have EEE still enabled but the TX-delay disabled?
> In my case throughput is fine, and "$ ethtool -S eth0 | grep lpi"
> gives:
>     irq_tx_path_in_lpi_mode_n: 0
>     irq_tx_path_exit_lpi_mode_n: 0
>     irq_rx_path_in_lpi_mode_n: 0
>     irq_rx_path_exit_lpi_mode_n: 0
> 

I still have lpi interrupts on my side. I don't get how a properly
configured tx_delay would disable EEE. I must be missing something
here.

> 
> Regards,
> Martin
> 
> 
> [0] http://lists.infradead.org/pipermail/linux-amlogic/2016-November/
> 001674.html
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH 1/3] of: Support parsing phandle argument lists through a nexus node
From: Pantelis Antoniou @ 2016-11-24 16:05 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: Rob Herring, Frank Rowand, linux-arm-kernel,
	linux-kernel @ vger . kernel . org, devicetree, linux-gpio,
	Linus Walleij, Mark Brown
In-Reply-To: <20161124102529.20212-2-stephen.boyd@linaro.org>

Hi Stephen,

> On Nov 24, 2016, at 12:25 , Stephen Boyd <stephen.boyd@linaro.org> wrote:
> 
> Platforms like 96boards have a standardized connector/expansion
> slot that exposes signals like GPIOs to expansion boards in an
> SoC agnostic way. We'd like the DT overlays for the expansion
> boards to be written once without knowledge of the SoC on the
> other side of the connector. This avoids the unscalable
> combinatorial explosion of a different DT overlay for each
> expansion board and SoC pair.
> 
> We need a way to describe the GPIOs routed through the connector
> in an SoC agnostic way. Let's introduce nexus property parsing
> into the OF core to do this. This is largely based on the
> interrupt nexus support we already have. This allows us to remap
> a phandle list in a consumer node (e.g. reset-gpios) through a
> connector in a generic way (e.g. via gpio-map). Do this in a
> generic routine so that we can remap any sort of variable length
> phandle list.
> 
> Taking GPIOs as an example, the connector would be a GPIO nexus,
> supporting the remapping of a GPIO specifier space to multiple
> GPIO providers on the SoC. DT would look as shown below, where
> 'soc_gpio1' and 'soc_gpio2' are inside the SoC, 'connector' is an
> expansion port where boards can be plugged in, and
> 'expansion_device' is a device on the expansion board.
> 
> 	soc {
> 		soc_gpio1: gpio-controller1 {
> 			#gpio-cells = <2>;
> 		};
> 
> 		soc_gpio2: gpio-controller2 {
> 			#gpio-cells = <2>;
> 		};
> 	};
> 
> 	connector: connector {
> 		#gpio-cells = <2>;
> 		gpio-map = <0 GPIO_ACTIVE_LOW &soc_gpio1 1 GPIO_ACTIVE_LOW>,
> 			   <1 GPIO_ACTIVE_LOW &soc_gpio2 4 GPIO_ACTIVE_LOW>,
> 			   <2 GPIO_ACTIVE_LOW &soc_gpio1 3 GPIO_ACTIVE_LOW>,
> 			   <3 GPIO_ACTIVE_LOW &soc_gpio2 2 GPIO_ACTIVE_LOW>;
> 		gpio-map-mask = <0xf 0x1>;
> 	};
> 
> 	expansion_device {
> 		reset-gpios = <&connector 2 GPIO_ACTIVE_LOW>;
> 	};
> 
> The GPIO core would use of_parse_phandle_with_args_map() instead
> of of_parse_phandle_with_args() and arrive at the same type of
> result, a phandle and argument list. The difference is that the
> phandle and arguments will be remapped through the nexus node to
> the underlying SoC GPIO controller node. In the example above,
> we would remap 'reset-gpios' from <&connector 2 GPIO_ACTIVE_LOW>
> to <&soc_gpio1 3 GPIO_ACTIVE_LOW>.
> 

Very good. My only point would be to elaborate a little bit on the
documentation part about how there might be different #list-cells values
pointed at, and how the lookup is performed in steps.

> Cc: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
> Cc: Linus Walleij <linus.walleij@linaro.org>
> Cc: Mark Brown <broonie@kernel.org>
> Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
> ---
> drivers/of/base.c  | 146 +++++++++++++++++++++++++++++++++++++++++++++++++++++
> include/linux/of.h |  14 +++++
> 2 files changed, 160 insertions(+)
> 
> diff --git a/drivers/of/base.c b/drivers/of/base.c
> index d687e6de24a0..693b73f33675 100644
> --- a/drivers/of/base.c
> +++ b/drivers/of/base.c
> @@ -1772,6 +1772,152 @@ int of_parse_phandle_with_args(const struct device_node *np, const char *list_na
> EXPORT_SYMBOL(of_parse_phandle_with_args);
> 
> /**
> + * of_parse_phandle_with_args_map() - Find a node pointed by phandle in a list and remap it
> + * @np:		pointer to a device tree node containing a list
> + * @list_name:	property name that contains a list
> + * @cells_name:	property name that specifies phandles' arguments count
> + * @index:	index of a phandle to parse out
> + * @out_args:	optional pointer to output arguments structure (will be filled)
> + *
> + * This function is useful to parse lists of phandles and their arguments.
> + * Returns 0 on success and fills out_args, on error returns appropriate
> + * errno value.
> + *
> + * Caller is responsible to call of_node_put() on the returned out_args->np
> + * pointer.
> + *
> + * Example:
> + *
> + * phandle1: node1 {
> + *	#list-cells = <2>;
> + * }
> + *
> + * phandle2: node2 {
> + *	#list-cells = <1>;
> + * }
> + *
> + * phandle3: node3 {
> + * 	#list-cells = <1>;
> + * 	list-map = <0 &phandle2 3>,
> + * 		   <1 &phandle2 2>,
> + * 		   <2 &phandle1 5 1>;
> + *	list-map-mask = <0x3>;
> + * };
> + *
> + * node4 {
> + *	list = <&phandle1 1 2 &phandle3 0>;
> + * }
> + *
> + * To get a device_node of the `node2' node you may call this:
> + * of_parse_phandle_with_args(node4, "list", "#list-cells", "list-map",
> + * 			      "list-map-mask", 1, &args);
> + */
> +int of_parse_phandle_with_args_map(const struct device_node *np,
> +				   const char *list_name,
> +				   const char *cells_name,
> +				   const char *map_name,
> +				   const char *mask_name,
> +				   int index, struct of_phandle_args *out_args)
> +{
> +	struct device_node *cur, *new = NULL;
> +	const __be32 *map, *mask, *tmp;
> +	const __be32 dummy_mask[] = { [0 ... MAX_PHANDLE_ARGS] = ~0 };
> +	__be32 initial_match_array[MAX_PHANDLE_ARGS];
> +	const __be32 *match_array = initial_match_array;
> +	int i, ret, map_len, match;
> +	u32 list_size, new_size;
> +
> +	if (index < 0)
> +		return -EINVAL;
> +
> +	ret = __of_parse_phandle_with_args(np, list_name, cells_name, 0, index,
> +					   out_args);
> +	if (ret)
> +		return ret;
> +
> +	/* Get the #<list>-cells property */
> +	cur = out_args->np;
> +	ret = of_property_read_u32(cur, cells_name, &list_size);
> +	if (ret < 0)
> +		goto fail;
> +
> +	/* Precalculate the match array - this simplifies match loop */
> +	for (i = 0; i < list_size; i++)
> +		initial_match_array[i] = cpu_to_be32(out_args->args[i]);
> +
> +	while (cur) {
> +		/* Get the <list>-map property */
> +		map = of_get_property(cur, map_name, &map_len);
> +		if (!map)
> +			return 0;
> +		map_len /= sizeof(u32);
> +
> +		/* Get the <list>-map-mask property (optional) */
> +		mask = of_get_property(cur, mask_name, NULL);
> +		if (!mask)
> +			mask = dummy_mask;
> +
> +		/* Iterate through <list>-map property */
> +		match = 0;
> +		while (map_len > (list_size + 1) && !match) {
> +			/* Compare specifiers */
> +			match = 1;
> +			for (i = 0; i < list_size; i++, map_len--)
> +				match &= !((match_array[i] ^ *map++) & mask[i]);
> +
> +			of_node_put(new);
> +			new = of_find_node_by_phandle(be32_to_cpup(map));
> +			map++;
> +			map_len--;
> +
> +			/* Check if not found */
> +			if (!new)
> +				goto fail;
> +
> +			if (!of_device_is_available(new))
> +				match = 0;
> +
> +			tmp = of_get_property(new, cells_name, NULL);
> +			if (!tmp)
> +				goto fail;
> +
> +			new_size = be32_to_cpu(*tmp);
> +
> +			/* Check for malformed properties */
> +			if (WARN_ON(new_size > MAX_PHANDLE_ARGS))
> +				goto fail;
> +			if (map_len < new_size)
> +				goto fail;
> +
> +			/* Move forward by new node's #<list>-cells amount */
> +			map += new_size;
> +			map_len -= new_size;
> +		}
> +		if (!match)
> +			goto fail;
> +
> +		/*
> +		 * Successfully parsed a <list>-map translation; copy new
> +		 * specifier into the out_args structure.
> +		 */
> +		match_array = map - new_size;
> +		for (i = 0; i < new_size; i++)
> +			out_args->args[i] = be32_to_cpup(map - new_size + i);
> +		out_args->args_count = list_size = new_size;
> +		/* Iterate again with new provider */
> +		out_args->np = new;
> +		of_node_put(cur);
> +		cur = new;
> +	}
> +fail:
> +	of_node_put(cur);
> +	of_node_put(new);
> +
> +	return -EINVAL;
> +}
> +EXPORT_SYMBOL(of_parse_phandle_with_args_map);
> +
> +/**
>  * of_parse_phandle_with_fixed_args() - Find a node pointed by phandle in a list
>  * @np:		pointer to a device tree node containing a list
>  * @list_name:	property name that contains a list
> diff --git a/include/linux/of.h b/include/linux/of.h
> index d3a9c2e69001..65ff306403a2 100644
> --- a/include/linux/of.h
> +++ b/include/linux/of.h
> @@ -344,6 +344,9 @@ extern struct device_node *of_parse_phandle(const struct device_node *np,
> extern int of_parse_phandle_with_args(const struct device_node *np,
> 	const char *list_name, const char *cells_name, int index,
> 	struct of_phandle_args *out_args);
> +extern int of_parse_phandle_with_args_map(const struct device_node *np,
> +	const char *list_name, const char *cells_name, const char *map_name,
> +	const char *mask_name, int index, struct of_phandle_args *out_args);
> extern int of_parse_phandle_with_fixed_args(const struct device_node *np,
> 	const char *list_name, int cells_count, int index,
> 	struct of_phandle_args *out_args);
> @@ -738,6 +741,17 @@ static inline int of_parse_phandle_with_args(const struct device_node *np,
> 	return -ENOSYS;
> }
> 
> +static inline int of_parse_phandle_with_args_map(const struct device_node *np,
> +						 const char *list_name,
> +						 const char *cells_name,
> +						 const char *map_name,
> +						 const char *mask_name,
> +						 int index,
> +						 struct of_phandle_args *out_args)
> +{
> +	return -ENOSYS;
> +}
> +
> static inline int of_parse_phandle_with_fixed_args(const struct device_node *np,
> 	const char *list_name, int cells_count, int index,
> 	struct of_phandle_args *out_args)
> -- 
> 2.10.0.297.gf6727b0
> 


^ permalink raw reply

* Re: [net-next PATCH v1 0/2] stmmac: dwmac-meson8b: configurable RGMII TX delay
From: Jerome Brunet @ 2016-11-24 16:08 UTC (permalink / raw)
  To: Martin Blumenstingl, linux-amlogic, devicetree, netdev, davem,
	khilman, mark.rutland, robh+dt
  Cc: linux-arm-kernel, alexandre.torgue, peppe.cavallaro, carlo
In-Reply-To: <20161124143417.10178-1-martin.blumenstingl@googlemail.com>

On Thu, 2016-11-24 at 15:34 +0100, Martin Blumenstingl wrote:
> Currently the dwmac-meson8b stmmac glue driver uses a hardcoded 1/4
> cycle TX clock delay. This seems to work fine for many boards (for
> example Odroid-C2 or Amlogic's reference boards) but there are some
> others where TX traffic is simply broken.
> There are probably multiple reasons why it's working on some boards
> while it's broken on others:
> - some of Amlogic's reference boards are using a Micrel PHY
> - hardware circuit design
> - maybe more...
> 
> This raises a question though:
> Which device is supposed to enable the TX delay when both MAC and PHY
> support it? And should we implement it for each PHY / MAC separately
> or should we think about a more generic solution (currently it's not
> possible to disable the TX delay generated by the RTL8211F PHY via
> devicetree when using phy-mode "rgmii")?
> 
> iperf3 results on my Mecool BB2 board (Meson GXM, RTL8211F PHY) with
> TX clock delay disabled on the MAC (as it's enabled in the PHY
> driver).
> TX throughput was virtually zero before:
> $ iperf3 -c 192.168.1.100 -R          
> Connecting to host 192.168.1.100, port 5201
> Reverse mode, remote host 192.168.1.100 is sending
> [  4] local 192.168.1.206 port 52828 connected to 192.168.1.100 port
> 5201
> [ ID] Interval           Transfer     Bandwidth
> [  4]   0.00-1.00   sec   108 MBytes   901
> Mbits/sec                  
> [  4]   1.00-2.00   sec  94.2 MBytes   791
> Mbits/sec                  
> [  4]   2.00-3.00   sec  96.5 MBytes   810
> Mbits/sec                  
> [  4]   3.00-4.00   sec  96.2 MBytes   808
> Mbits/sec                  
> [  4]   4.00-5.00   sec  96.6 MBytes   810
> Mbits/sec                  
> [  4]   5.00-6.00   sec  96.5 MBytes   810
> Mbits/sec                  
> [  4]   6.00-7.00   sec  96.6 MBytes   810
> Mbits/sec                  
> [  4]   7.00-8.00   sec  96.5 MBytes   809
> Mbits/sec                  
> [  4]   8.00-9.00   sec   105 MBytes   884
> Mbits/sec                  
> [  4]   9.00-10.00  sec   111 MBytes   934
> Mbits/sec                  
> - - - - - - - - - - - - - - - - - - - - - - - - -
> [ ID] Interval           Transfer     Bandwidth       Retr
> [  4]   0.00-10.00  sec  1000 MBytes   839
> Mbits/sec    0             sender
> [  4]   0.00-10.00  sec   998 MBytes   837
> Mbits/sec                  receiver
> 
> iperf Done.
> $ iperf3 -c 192.168.1.100   
> Connecting to host 192.168.1.100, port 5201
> [  4] local 192.168.1.206 port 52832 connected to 192.168.1.100 port
> 5201
> [ ID] Interval           Transfer     Bandwidth       Retr  Cwnd
> [  4]   0.00-1.01   sec  99.5 MBytes   829 Mbits/sec  117    139
> KBytes       
> [  4]   1.01-2.00   sec   105 MBytes   884 Mbits/sec  129   70.7
> KBytes       
> [  4]   2.00-3.01   sec   107 MBytes   889 Mbits/sec  106    187
> KBytes       
> [  4]   3.01-4.01   sec   105 MBytes   878 Mbits/sec   92    143
> KBytes       
> [  4]   4.01-5.00   sec   105 MBytes   882 Mbits/sec  140    129
> KBytes       
> [  4]   5.00-6.01   sec   106 MBytes   883 Mbits/sec  115    195
> KBytes       
> [  4]   6.01-7.00   sec   102 MBytes   863 Mbits/sec  133   70.7
> KBytes       
> [  4]   7.00-8.01   sec   106 MBytes   884 Mbits/sec  143   97.6
> KBytes       
> [  4]   8.01-9.01   sec   104 MBytes   875 Mbits/sec  124    107
> KBytes       
> [  4]   9.01-10.01  sec   105 MBytes   876 Mbits/sec   90    139
> KBytes       
> - - - - - - - - - - - - - - - - - - - - - - - - -
> [ ID] Interval           Transfer     Bandwidth       Retr
> [  4]   0.00-10.01  sec  1.02 GBytes   874
> Mbits/sec  1189             sender
> [  4]   0.00-10.01  sec  1.02 GBytes   873
> Mbits/sec                  receiver
> 

Cool, one more board working ;)
I tried your patch on another board (MXQ_V2.1, with sheep printed on
the PCB). It 's not improving the situation for this one unfortunately.
Actually I already tried playing with the TX delay on the MAC and PHY
but I could get any good results with the boards I have.

It is strange that we can adjust the delay by 2ns steps, when delay
seens by the phy should be 2ns ...

> iperf Done.
> 
> 
> Martin Blumenstingl (2):
>   net: dt-bindings: add RGMII TX delay configuration to meson8b-dwmac
>   net: stmmac: dwmac-meson8b: make the RGMII TX delay configurable
> 
>  Documentation/devicetree/bindings/net/meson-dwmac.txt | 11
> +++++++++++
>  drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c   | 16
> +++++++++++-----
>  include/dt-bindings/net/dwmac-meson8b.h               | 18
> ++++++++++++++++++
>  3 files changed, 40 insertions(+), 5 deletions(-)
>  create mode 100644 include/dt-bindings/net/dwmac-meson8b.h
> 

^ permalink raw reply

* Re: [PATCH RESEND 2/2] gpio: axp209: add pinctrl support
From: Chen-Yu Tsai @ 2016-11-24 16:08 UTC (permalink / raw)
  To: Quentin Schulz
  Cc: Linus Walleij, Alexandre Courbot, Rob Herring, Mark Rutland,
	Chen-Yu Tsai, Maxime Ripard, linux-gpio@vger.kernel.org,
	devicetree, linux-kernel, linux-arm-kernel, Thomas Petazzoni
In-Reply-To: <20161123141151.25315-3-quentin.schulz@free-electrons.com>

On Wed, Nov 23, 2016 at 10:11 PM, Quentin Schulz
<quentin.schulz@free-electrons.com> wrote:
> The GPIOs present in the AXP209 PMIC have multiple functions. They
> typically allow a pin to be used as GPIO input or output and can also be
> used as ADC or regulator for example.[1]
>
> This adds the possibility to use all functions of the GPIOs present in
> the AXP209 PMIC thanks to pinctrl subsystem.
>
> [1] see registers 90H, 92H and 93H at
>     http://dl.linux-sunxi.org/AXP/AXP209_Datasheet_v1.0en.pdf
>
> Signed-off-by: Quentin Schulz <quentin.schulz@free-electrons.com>
> ---
>  .../devicetree/bindings/gpio/gpio-axp209.txt       |  28 +-
>  drivers/gpio/gpio-axp209.c                         | 551 ++++++++++++++++++---
>  2 files changed, 503 insertions(+), 76 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/gpio/gpio-axp209.txt b/Documentation/devicetree/bindings/gpio/gpio-axp209.txt
> index a661130..a5bfe87 100644
> --- a/Documentation/devicetree/bindings/gpio/gpio-axp209.txt
> +++ b/Documentation/devicetree/bindings/gpio/gpio-axp209.txt
> @@ -1,4 +1,4 @@
> -AXP209 GPIO controller
> +AXP209 GPIO & pinctrl controller
>
>  This driver follows the usual GPIO bindings found in
>  Documentation/devicetree/bindings/gpio/gpio.txt
> @@ -28,3 +28,29 @@ axp209: pmic@34 {
>                 #gpio-cells = <2>;
>         };
>  };
> +
> +The GPIOs can be muxed to other functions and therefore, must be a subnode of
> +axp_gpio.
> +
> +Example:
> +
> +&axp_gpio {
> +       gpio0_adc: gpio0_adc {
> +               pin = "GPIO0";
> +               function = "adc";
> +       };
> +};
> +
> +&example_node {
> +       pinctrl-names = "default";
> +       pinctrl-0 = <&gpio0_adc>;
> +};
> +
> +GPIOs and their functions
> +-------------------------
> +
> +GPIO   |       Functions
> +------------------------
> +GPIO0  |       gpio_in, gpio_out, ldo, adc
> +GPIO1  |       gpio_in, gpio_out, ldo, adc
> +GPIO2  |       gpio_in, gpio_out
> diff --git a/drivers/gpio/gpio-axp209.c b/drivers/gpio/gpio-axp209.c
> index 4a346b7..0a64cfc 100644
> --- a/drivers/gpio/gpio-axp209.c
> +++ b/drivers/gpio/gpio-axp209.c
> @@ -1,7 +1,8 @@
>  /*
> - * AXP20x GPIO driver
> + * AXP20x Pin control driver
>   *
>   * Copyright (C) 2016 Maxime Ripard <maxime.ripard@free-electrons.com>
> + * Copyright (C) 2016 Quentin Schulz <quentin.schulz@free-electrons.com>
>   *
>   * This program is free software; you can redistribute it and/or modify it
>   * under  the terms of the GNU General  Public License as published by the
> @@ -21,52 +22,103 @@
>  #include <linux/platform_device.h>
>  #include <linux/regmap.h>
>  #include <linux/slab.h>
> +#include <linux/pinctrl/pinctrl.h>
> +#include <linux/pinctrl/pinmux.h>
> +#include <linux/pinctrl/pinconf-generic.h>
>
>  #define AXP20X_GPIO_FUNCTIONS          0x7
>  #define AXP20X_GPIO_FUNCTION_OUT_LOW   0
>  #define AXP20X_GPIO_FUNCTION_OUT_HIGH  1
>  #define AXP20X_GPIO_FUNCTION_INPUT     2
>
> -struct axp20x_gpio {
> -       struct gpio_chip        chip;
> -       struct regmap           *regmap;
> -};
> +#define AXP20X_PINCTRL_PIN(_pin_num, _pin, _regs)              \
> +       {                                                       \
> +               .number = _pin_num,                             \
> +               .name = _pin,                                   \
> +               .drv_data = _regs,                              \
> +       }
>
> -static int axp20x_gpio_get_reg(unsigned offset)
> -{
> -       switch (offset) {
> -       case 0:
> -               return AXP20X_GPIO0_CTRL;
> -       case 1:
> -               return AXP20X_GPIO1_CTRL;
> -       case 2:
> -               return AXP20X_GPIO2_CTRL;
> +#define AXP20X_PIN(_pin, ...)                                  \
> +       {                                                       \
> +               .pin = _pin,                                    \
> +               .functions = (struct axp20x_desc_function[]) {  \
> +                             __VA_ARGS__, { } },               \
>         }
>
> -       return -EINVAL;
> -}
> +#define AXP20X_FUNCTION(_val, _name)                           \
> +       {                                                       \
> +               .name = _name,                                  \
> +               .muxval = _val,                                 \
> +       }
>
> -static int axp20x_gpio_input(struct gpio_chip *chip, unsigned offset)
> -{
> -       struct axp20x_gpio *gpio = gpiochip_get_data(chip);
> -       int reg;
> +struct axp20x_desc_function {
> +       const char      *name;
> +       u8              muxval;
> +};
>
> -       reg = axp20x_gpio_get_reg(offset);
> -       if (reg < 0)
> -               return reg;
> +struct axp20x_desc_pin {
> +       struct pinctrl_pin_desc         pin;
> +       struct axp20x_desc_function     *functions;
> +};
>
> -       return regmap_update_bits(gpio->regmap, reg,
> -                                 AXP20X_GPIO_FUNCTIONS,
> -                                 AXP20X_GPIO_FUNCTION_INPUT);
> -}
> +struct axp20x_pinctrl_desc {
> +       const struct axp20x_desc_pin    *pins;
> +       int                             npins;
> +       unsigned int                    pin_base;

You do not need pin_base.

> +};
> +
> +struct axp20x_pinctrl_function {
> +       const char      *name;
> +       const char      **groups;
> +       unsigned int    ngroups;
> +};
> +
> +struct axp20x_pinctrl_group {
> +       const char      *name;
> +       unsigned long   config;
> +       unsigned int    pin;
> +};
> +
> +struct axp20x_pctl {
> +       struct pinctrl_dev                      *pctl_dev;
> +       struct device                           *dev;
> +       struct gpio_chip                        chip;
> +       struct regmap                           *regmap;
> +       const struct axp20x_pinctrl_desc        *desc;
> +       struct axp20x_pinctrl_group             *groups;
> +       unsigned int                            ngroups;
> +       struct axp20x_pinctrl_function          *functions;
> +       unsigned int                            nfunctions;
> +};
> +
> +static const struct axp20x_desc_pin axp209_pins[] = {
> +       AXP20X_PIN(AXP20X_PINCTRL_PIN(0, "GPIO0", (void *)AXP20X_GPIO0_CTRL),
> +                  AXP20X_FUNCTION(0x0, "gpio_out"),
> +                  AXP20X_FUNCTION(0x2, "gpio_in"),
> +                  AXP20X_FUNCTION(0x3, "ldo"),
> +                  AXP20X_FUNCTION(0x4, "adc")),
> +       AXP20X_PIN(AXP20X_PINCTRL_PIN(1, "GPIO1", (void *)AXP20X_GPIO1_CTRL),
> +                  AXP20X_FUNCTION(0x0, "gpio_out"),
> +                  AXP20X_FUNCTION(0x2, "gpio_in"),
> +                  AXP20X_FUNCTION(0x3, "ldo"),
> +                  AXP20X_FUNCTION(0x4, "adc")),
> +       AXP20X_PIN(AXP20X_PINCTRL_PIN(2, "GPIO2", (void *)AXP20X_GPIO2_CTRL),
> +                  AXP20X_FUNCTION(0x0, "gpio_out"),
> +                  AXP20X_FUNCTION(0x2, "gpio_in")),
> +};
> +
> +static const struct axp20x_pinctrl_desc axp20x_pinctrl_data = {
> +       .pins   = axp209_pins,
> +       .npins  = ARRAY_SIZE(axp209_pins),
> +};
>
>  static int axp20x_gpio_get(struct gpio_chip *chip, unsigned offset)
>  {
> -       struct axp20x_gpio *gpio = gpiochip_get_data(chip);
> +       struct axp20x_pctl *pctl = gpiochip_get_data(chip);
>         unsigned int val;
>         int ret;
>
> -       ret = regmap_read(gpio->regmap, AXP20X_GPIO20_SS, &val);
> +       ret = regmap_read(pctl->regmap, AXP20X_GPIO20_SS, &val);
>         if (ret)
>                 return ret;
>
> @@ -75,15 +127,12 @@ static int axp20x_gpio_get(struct gpio_chip *chip, unsigned offset)
>
>  static int axp20x_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
>  {
> -       struct axp20x_gpio *gpio = gpiochip_get_data(chip);
> +       struct axp20x_pctl *pctl = gpiochip_get_data(chip);
> +       int pin_reg = (int)pctl->desc->pins[offset].pin.drv_data;
>         unsigned int val;
> -       int reg, ret;
> -
> -       reg = axp20x_gpio_get_reg(offset);
> -       if (reg < 0)
> -               return reg;
> +       int ret;
>
> -       ret = regmap_read(gpio->regmap, reg, &val);
> +       ret = regmap_read(pctl->regmap, pin_reg, &val);
>         if (ret)
>                 return ret;
>
> @@ -102,33 +151,335 @@ static int axp20x_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
>         return val & 2;
>  }
>
> -static int axp20x_gpio_output(struct gpio_chip *chip, unsigned offset,
> +static void axp20x_gpio_set(struct gpio_chip *chip, unsigned int offset,
> +                           int value)
> +{
> +       struct axp20x_pctl *pctl = gpiochip_get_data(chip);
> +       int pin_reg = (int)pctl->desc->pins[offset].pin.drv_data;
> +
> +       regmap_update_bits(pctl->regmap, pin_reg,
> +                          AXP20X_GPIO_FUNCTIONS,
> +                          value ? AXP20X_GPIO_FUNCTION_OUT_HIGH
> +                                : AXP20X_GPIO_FUNCTION_OUT_LOW);
> +}
> +
> +static int axp20x_gpio_input(struct gpio_chip *chip, unsigned int offset)
> +{
> +       return pinctrl_gpio_direction_input(chip->base + offset);
> +}
> +
> +static int axp20x_gpio_output(struct gpio_chip *chip, unsigned int offset,
>                               int value)
>  {
> -       struct axp20x_gpio *gpio = gpiochip_get_data(chip);
> -       int reg;
> +       chip->set(chip, offset, value);
>
> -       reg = axp20x_gpio_get_reg(offset);
> -       if (reg < 0)
> -               return reg;
> +       return 0;
> +}
>
> -       return regmap_update_bits(gpio->regmap, reg,
> -                                 AXP20X_GPIO_FUNCTIONS,
> -                                 value ? AXP20X_GPIO_FUNCTION_OUT_HIGH
> -                                 : AXP20X_GPIO_FUNCTION_OUT_LOW);
> +static int axp20x_pmx_set(struct pinctrl_dev *pctldev, unsigned int offset,
> +                         u8 config)
> +{
> +       struct axp20x_pctl *pctl = pinctrl_dev_get_drvdata(pctldev);
> +       int pin_reg = (int)pctl->desc->pins[offset].pin.drv_data;
> +
> +       return regmap_update_bits(pctl->regmap, pin_reg, AXP20X_GPIO_FUNCTIONS,
> +                                 config);
>  }
>
> -static void axp20x_gpio_set(struct gpio_chip *chip, unsigned offset,
> -                           int value)
> +static int axp20x_pmx_func_cnt(struct pinctrl_dev *pctldev)
> +{
> +       struct axp20x_pctl *pctl = pinctrl_dev_get_drvdata(pctldev);
> +
> +       return pctl->nfunctions;
> +}
> +
> +static const char *axp20x_pmx_func_name(struct pinctrl_dev *pctldev,
> +                                       unsigned int selector)
> +{
> +       struct axp20x_pctl *pctl = pinctrl_dev_get_drvdata(pctldev);
> +
> +       return pctl->functions[selector].name;
> +}
> +
> +static int axp20x_pmx_func_groups(struct pinctrl_dev *pctldev,
> +                                 unsigned int selector,
> +                                 const char * const **groups,
> +                                 unsigned int *num_groups)
> +{
> +       struct axp20x_pctl *pctl = pinctrl_dev_get_drvdata(pctldev);
> +
> +       *groups = pctl->functions[selector].groups;
> +       *num_groups = pctl->functions[selector].ngroups;
> +
> +       return 0;
> +}
> +
> +static struct axp20x_desc_function *
> +axp20x_pinctrl_desc_find_func_by_name(struct axp20x_pctl *pctl,
> +                                     const char *group, const char *func)
> +{
> +       const struct axp20x_desc_pin *pin;
> +       struct axp20x_desc_function *desc_func;
> +       int i;
> +
> +       for (i = 0; i < pctl->desc->npins; i++) {
> +               pin = &pctl->desc->pins[i];
> +
> +               if (!strcmp(pin->pin.name, group)) {
> +                       desc_func = pin->functions;
> +
> +                       while (desc_func->name) {
> +                               if (!strcmp(desc_func->name, func))
> +                                       return desc_func;
> +                               desc_func++;
> +                       }
> +
> +                       /*
> +                        * Pins are uniquely named. Groups are named after one
> +                        * pin name. If one pin matches group name but its
> +                        * function cannot be found, no other pin will match
> +                        * group name.
> +                        */
> +                       return NULL;
> +               }
> +       }
> +
> +       return NULL;
> +}
> +
> +static int axp20x_pmx_set_mux(struct pinctrl_dev *pctldev,
> +                             unsigned int function, unsigned int group)
> +{
> +       struct axp20x_pctl *pctl = pinctrl_dev_get_drvdata(pctldev);
> +       struct axp20x_pinctrl_group *g = pctl->groups + group;
> +       struct axp20x_pinctrl_function *func = pctl->functions + function;
> +       struct axp20x_desc_function *desc_func =
> +               axp20x_pinctrl_desc_find_func_by_name(pctl, g->name,
> +                                                     func->name);
> +       if (!desc_func)
> +               return -EINVAL;
> +
> +       return axp20x_pmx_set(pctldev, g->pin, desc_func->muxval);
> +}
> +
> +static struct axp20x_desc_function *
> +axp20x_pctl_desc_find_func_by_pin(struct axp20x_pctl *pctl, unsigned int offset,
> +                                 const char *func)
> +{
> +       const struct axp20x_desc_pin *pin;
> +       struct axp20x_desc_function *desc_func;
> +       int i;
> +
> +       for (i = 0; i < pctl->desc->npins; i++) {
> +               pin = &pctl->desc->pins[i];
> +
> +               if (pin->pin.number == offset) {
> +                       desc_func = pin->functions;
> +
> +                       while (desc_func->name) {
> +                               if (!strcmp(desc_func->name, func))
> +                                       return desc_func;
> +
> +                               desc_func++;
> +                       }
> +               }
> +       }
> +
> +       return NULL;
> +}
> +
> +static int axp20x_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
> +                                        struct pinctrl_gpio_range *range,
> +                                        unsigned int offset, bool input)
> +{
> +       struct axp20x_pctl *pctl = pinctrl_dev_get_drvdata(pctldev);
> +       struct axp20x_desc_function *desc_func;
> +       const char *func;
> +
> +       if (input)
> +               func = "gpio_in";
> +       else
> +               func = "gpio_out";
> +
> +       desc_func = axp20x_pctl_desc_find_func_by_pin(pctl, offset, func);
> +       if (!desc_func)
> +               return -EINVAL;
> +
> +       return axp20x_pmx_set(pctldev, offset, desc_func->muxval);
> +}
> +
> +static const struct pinmux_ops axp20x_pmx_ops = {
> +       .get_functions_count    = axp20x_pmx_func_cnt,
> +       .get_function_name      = axp20x_pmx_func_name,
> +       .get_function_groups    = axp20x_pmx_func_groups,
> +       .set_mux                = axp20x_pmx_set_mux,
> +       .gpio_set_direction     = axp20x_pmx_gpio_set_direction,
> +       .strict                 = true,
> +};
> +
> +static int axp20x_groups_cnt(struct pinctrl_dev *pctldev)
> +{
> +       struct axp20x_pctl *pctl = pinctrl_dev_get_drvdata(pctldev);
> +
> +       return pctl->ngroups;
> +}
> +
> +static int axp20x_group_pins(struct pinctrl_dev *pctldev, unsigned int selector,
> +                            const unsigned int **pins, unsigned int *num_pins)
> +{
> +       struct axp20x_pctl *pctl = pinctrl_dev_get_drvdata(pctldev);
> +       struct axp20x_pinctrl_group *g = pctl->groups + selector;
> +
> +       *pins = (unsigned int *)&g->pin;
> +       *num_pins = 1;
> +
> +       return 0;
> +}
> +
> +static const char *axp20x_group_name(struct pinctrl_dev *pctldev,
> +                                    unsigned int selector)
> +{
> +       struct axp20x_pctl *pctl = pinctrl_dev_get_drvdata(pctldev);
> +
> +       return pctl->groups[selector].name;
> +}
> +
> +static const struct pinctrl_ops axp20x_pctrl_ops = {
> +       .dt_node_to_map         = pinconf_generic_dt_node_to_map_group,
> +       .dt_free_map            = pinconf_generic_dt_free_map,
> +       .get_groups_count       = axp20x_groups_cnt,
> +       .get_group_name         = axp20x_group_name,
> +       .get_group_pins         = axp20x_group_pins,
> +};
> +
> +static struct axp20x_pinctrl_function *
> +axp20x_pinctrl_function_by_name(struct axp20x_pctl *pctl, const char *name)
> +{
> +       struct axp20x_pinctrl_function *func = pctl->functions;
> +
> +       while (func->name) {
> +               if (!strcmp(func->name, name))
> +                       return func;
> +               func++;
> +       }
> +
> +       return NULL;
> +}
> +
> +static int axp20x_pinctrl_add_function(struct axp20x_pctl *pctl,
> +                                      const char *name)
>  {
> -       axp20x_gpio_output(chip, offset, value);
> +       struct axp20x_pinctrl_function *func = pctl->functions;
> +
> +       while (func->name) {
> +               if (!strcmp(func->name, name)) {
> +                       func->ngroups++;
> +                       return -EEXIST;
> +               }
> +
> +               func++;
> +       }
> +
> +       func->name = name;
> +       func->ngroups = 1;
> +
> +       pctl->nfunctions++;
> +
> +       return 0;
>  }
>
> -static int axp20x_gpio_probe(struct platform_device *pdev)
> +static int axp20x_attach_group_function(struct platform_device *pdev,
> +                                       const struct axp20x_desc_pin *pin)
> +{
> +       struct axp20x_pctl *pctl = platform_get_drvdata(pdev);
> +       struct axp20x_desc_function *desc_func = pin->functions;
> +       struct axp20x_pinctrl_function *func;
> +       const char **func_grp;
> +
> +       while (desc_func->name) {
> +               func = axp20x_pinctrl_function_by_name(pctl, desc_func->name);
> +               if (!func)
> +                       return -EINVAL;
> +
> +               if (!func->groups) {
> +                       func->groups = devm_kzalloc(&pdev->dev,
> +                                                   func->ngroups * sizeof(const char *),
> +                                                   GFP_KERNEL);
> +                       if (!func->groups)
> +                               return -ENOMEM;
> +               }
> +
> +               func_grp = func->groups;
> +               while (*func_grp)
> +                       func_grp++;
> +
> +               *func_grp = pin->pin.name;
> +               desc_func++;
> +       }
> +
> +       return 0;
> +}
> +
> +static int axp20x_build_state(struct platform_device *pdev)
> +{
> +       struct axp20x_pctl *pctl = platform_get_drvdata(pdev);
> +       unsigned int npins = pctl->desc->npins;
> +       const struct axp20x_desc_pin *pin;
> +       struct axp20x_desc_function *func;
> +       int i, ret;
> +
> +       pctl->ngroups = npins;
> +       pctl->groups = devm_kzalloc(&pdev->dev,
> +                                   pctl->ngroups * sizeof(*pctl->groups),
> +                                   GFP_KERNEL);
> +       if (!pctl->groups)
> +               return -ENOMEM;
> +
> +       for (i = 0; i < npins; i++) {
> +               pctl->groups[i].name = pctl->desc->pins[i].pin.name;
> +               pctl->groups[i].pin = pctl->desc->pins[i].pin.number;
> +       }
> +
> +       /* We assume 4 functions per pin should be enough as a default max */
> +       pctl->functions = devm_kzalloc(&pdev->dev,
> +                                      npins * 4 * sizeof(*pctl->functions),
> +                                      GFP_KERNEL);
> +       if (!pctl->functions)
> +               return -ENOMEM;
> +
> +       /* Create a list of uniquely named functions */
> +       for (i = 0; i < npins; i++) {
> +               pin = &pctl->desc->pins[i];
> +               func = pin->functions;
> +
> +               while (func->name) {
> +                       axp20x_pinctrl_add_function(pctl, func->name);
> +                       func++;
> +               }
> +       }
> +
> +       pctl->functions = krealloc(pctl->functions,
> +                                  pctl->nfunctions * sizeof(*pctl->functions),
> +                                  GFP_KERNEL);
> +
> +       for (i = 0; i < npins; i++) {
> +               pin = &pctl->desc->pins[i];
> +               ret = axp20x_attach_group_function(pdev, pin);
> +               if (ret)
> +                       return ret;
> +       }
> +
> +       return 0;
> +}
> +
> +static int axp20x_pctl_probe(struct platform_device *pdev)
>  {
>         struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
> -       struct axp20x_gpio *gpio;
> -       int ret;
> +       const struct axp20x_desc_pin *pin;
> +       struct axp20x_pctl *pctl;
> +       struct pinctrl_desc *pctrl_desc;
> +       struct pinctrl_pin_desc *pins;
> +       int ret, i;
>
>         if (!of_device_is_available(pdev->dev.of_node))
>                 return -ENODEV;
> @@ -138,51 +489,101 @@ static int axp20x_gpio_probe(struct platform_device *pdev)
>                 return -EINVAL;
>         }
>
> -       gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL);
> -       if (!gpio)
> +       pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL);
> +       if (!pctl)
> +               return -ENOMEM;
> +
> +       pctl->chip.base                 = -1;
> +       pctl->chip.can_sleep            = true;
> +       pctl->chip.request              = gpiochip_generic_request;
> +       pctl->chip.free                 = gpiochip_generic_free;
> +       pctl->chip.parent               = &pdev->dev;
> +       pctl->chip.label                = dev_name(&pdev->dev);
> +       pctl->chip.owner                = THIS_MODULE;
> +       pctl->chip.get                  = axp20x_gpio_get;
> +       pctl->chip.get_direction        = axp20x_gpio_get_direction;
> +       pctl->chip.set                  = axp20x_gpio_set;
> +       pctl->chip.direction_input      = axp20x_gpio_input;
> +       pctl->chip.direction_output     = axp20x_gpio_output;
> +       pctl->chip.ngpio                = 3;
> +       pctl->chip.can_sleep            = true;
> +
> +       pctl->regmap = axp20x->regmap;
> +
> +       pctl->desc = &axp20x_pinctrl_data;
> +       pctl->dev = &pdev->dev;
> +
> +       platform_set_drvdata(pdev, pctl);
> +
> +       ret = axp20x_build_state(pdev);
> +       if (ret)
> +               return ret;
> +
> +       pins = devm_kzalloc(&pdev->dev, pctl->desc->npins * sizeof(*pins),
> +                           GFP_KERNEL);
> +       if (!pins)
>                 return -ENOMEM;
>
> -       gpio->chip.base                 = -1;
> -       gpio->chip.can_sleep            = true;
> -       gpio->chip.parent               = &pdev->dev;
> -       gpio->chip.label                = dev_name(&pdev->dev);
> -       gpio->chip.owner                = THIS_MODULE;
> -       gpio->chip.get                  = axp20x_gpio_get;
> -       gpio->chip.get_direction        = axp20x_gpio_get_direction;
> -       gpio->chip.set                  = axp20x_gpio_set;
> -       gpio->chip.direction_input      = axp20x_gpio_input;
> -       gpio->chip.direction_output     = axp20x_gpio_output;
> -       gpio->chip.ngpio                = 3;
> -
> -       gpio->regmap = axp20x->regmap;
> -
> -       ret = devm_gpiochip_add_data(&pdev->dev, &gpio->chip, gpio);
> +       for (i = 0; i < pctl->desc->npins; i++)
> +               pins[i] = pctl->desc->pins[i].pin;
> +
> +       pctrl_desc = devm_kzalloc(&pdev->dev, sizeof(*pctrl_desc), GFP_KERNEL);
> +       if (!pctrl_desc)
> +               return -ENOMEM;
> +
> +       pctrl_desc->name = dev_name(&pdev->dev);
> +       pctrl_desc->owner = THIS_MODULE;
> +       pctrl_desc->pins = pins;
> +       pctrl_desc->npins = pctl->desc->npins;
> +       pctrl_desc->pctlops = &axp20x_pctrl_ops;
> +       pctrl_desc->pmxops = &axp20x_pmx_ops;
> +
> +       pctl->pctl_dev = devm_pinctrl_register(&pdev->dev, pctrl_desc, pctl);
> +       if (IS_ERR(pctl->pctl_dev)) {
> +               dev_err(&pdev->dev, "couldn't register pinctrl driver\n");
> +               return PTR_ERR(pctl->pctl_dev);
> +       }
> +
> +       ret = devm_gpiochip_add_data(&pdev->dev, &pctl->chip, pctl);
>         if (ret) {
>                 dev_err(&pdev->dev, "Failed to register GPIO chip\n");
>                 return ret;
>         }
>
> +       for (i = 0; i < pctl->desc->npins; i++) {
> +               pin = pctl->desc->pins + i;
> +
> +               ret = gpiochip_add_pin_range(&pctl->chip, dev_name(&pdev->dev),
> +                                            pin->pin.number, pin->pin.number,
> +                                            1);

The pins, unlike in sunxi, are sequential and contiguous. There's no need for
the loop. Just add them in one go.

> +               if (ret) {
> +                       dev_err(&pdev->dev, "failed to add pin range\n");
> +                       return ret;
> +               }
> +       }
> +
>         dev_info(&pdev->dev, "AXP209 GPIO driver loaded\n");
>
>         return 0;
>  }
>
> -static const struct of_device_id axp20x_gpio_match[] = {
> +static const struct of_device_id axp20x_pctl_match[] = {
>         { .compatible = "x-powers,axp209-gpio" },
>         { }
>  };
> -MODULE_DEVICE_TABLE(of, axp20x_gpio_match);
> +MODULE_DEVICE_TABLE(of, axp20x_pctl_match);
>
> -static struct platform_driver axp20x_gpio_driver = {
> -       .probe          = axp20x_gpio_probe,
> +static struct platform_driver axp20x_pctl_driver = {
> +       .probe          = axp20x_pctl_probe,
>         .driver = {
>                 .name           = "axp20x-gpio",
> -               .of_match_table = axp20x_gpio_match,
> +               .of_match_table = axp20x_pctl_match,
>         },
>  };
>
> -module_platform_driver(axp20x_gpio_driver);
> +module_platform_driver(axp20x_pctl_driver);
>
>  MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>");
> +MODULE_AUTHOR("Quentin Schulz <quentin.schulz@free-electrons.com>");
>  MODULE_DESCRIPTION("AXP20x PMIC GPIO driver");
>  MODULE_LICENSE("GPL");
> --
> 2.9.3
>

Apart from the minor comments above, and Thomas' earlier comments,
this patch looks good to me.

ChenYu

^ permalink raw reply

* [PATCH v2 0/2] can: Add r8a7796 support to CAN/CAN FD
From: Chris Paterson @ 2016-11-24 16:11 UTC (permalink / raw)
  To: Marc Kleine-Budde
  Cc: Wolfgang Grandegger, Rob Herring, Mark Rutland,
	Geert Uytterhoeven, Simon Horman, Ramesh Shanmugasundaram,
	linux-can, netdev, devicetree, linux-renesas-soc, Chris Paterson
In-Reply-To: <1479903243-1860-1-git-send-email-chris.paterson2@renesas.com>

This series adds support for r8a7796 to rcar_can and rcar_canfd.

Original series: [PATCH 0/3] arm64: dts: r8a7796: Add CAN/CAN FD support.

Changes since v1:
- Split bindings documentation changes from device tree changes.
- Rebased on renesas-devel-20161123v2-v4.9-rc6.


Chris Paterson (2):
  can: rcar_can: Add r8a7796 support
  can: rcar_canfd: Add r8a7796 support

 Documentation/devicetree/bindings/net/can/rcar_can.txt   | 12 +++++++-----
 Documentation/devicetree/bindings/net/can/rcar_canfd.txt | 12 +++++++-----
 2 files changed, 14 insertions(+), 10 deletions(-)

-- 
1.9.1

^ permalink raw reply

* [PATCH v2 1/2] can: rcar_can: Add r8a7796 support
From: Chris Paterson @ 2016-11-24 16:11 UTC (permalink / raw)
  To: Marc Kleine-Budde
  Cc: Wolfgang Grandegger, Rob Herring, Mark Rutland,
	Geert Uytterhoeven, Simon Horman, Ramesh Shanmugasundaram,
	linux-can-u79uwXL29TY76Z2rM5mHXA, netdev-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-renesas-soc-u79uwXL29TY76Z2rM5mHXA, Chris Paterson
In-Reply-To: <1480003917-3953-1-git-send-email-chris.paterson2-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>

Signed-off-by: Chris Paterson <chris.paterson2-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
Reviewed-by: Geert Uytterhoeven <geert+renesas-gXvu3+zWzMSzQB+pC5nmwQ@public.gmane.org>
Acked-by: Marc Kleine-Budde <mkl-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
---
 Documentation/devicetree/bindings/net/can/rcar_can.txt | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/Documentation/devicetree/bindings/net/can/rcar_can.txt b/Documentation/devicetree/bindings/net/can/rcar_can.txt
index 8d40ab2..06bb7cc 100644
--- a/Documentation/devicetree/bindings/net/can/rcar_can.txt
+++ b/Documentation/devicetree/bindings/net/can/rcar_can.txt
@@ -10,6 +10,7 @@ Required properties:
 	      "renesas,can-r8a7793" if CAN controller is a part of R8A7793 SoC.
 	      "renesas,can-r8a7794" if CAN controller is a part of R8A7794 SoC.
 	      "renesas,can-r8a7795" if CAN controller is a part of R8A7795 SoC.
+	      "renesas,can-r8a7796" if CAN controller is a part of R8A7796 SoC.
 	      "renesas,rcar-gen1-can" for a generic R-Car Gen1 compatible device.
 	      "renesas,rcar-gen2-can" for a generic R-Car Gen2 compatible device.
 	      "renesas,rcar-gen3-can" for a generic R-Car Gen3 compatible device.
@@ -24,11 +25,12 @@ Required properties:
 - pinctrl-0: pin control group to be used for this controller.
 - pinctrl-names: must be "default".
 
-Required properties for "renesas,can-r8a7795" compatible:
-In R8A7795 SoC, "clkp2" can be CANFD clock. This is a div6 clock and can be
-used by both CAN and CAN FD controller at the same time. It needs to be scaled
-to maximum frequency if any of these controllers use it. This is done using
-the below properties.
+Required properties for "renesas,can-r8a7795" and "renesas,can-r8a7796"
+compatible:
+In R8A7795 and R8A7796 SoCs, "clkp2" can be CANFD clock. This is a div6 clock
+and can be used by both CAN and CAN FD controller at the same time. It needs to
+be scaled to maximum frequency if any of these controllers use it. This is done
+using the below properties:
 
 - assigned-clocks: phandle of clkp2(CANFD) clock.
 - assigned-clock-rates: maximum frequency of this clock.
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related

* [PATCH v2 2/2] can: rcar_canfd: Add r8a7796 support
From: Chris Paterson @ 2016-11-24 16:11 UTC (permalink / raw)
  To: Marc Kleine-Budde
  Cc: Wolfgang Grandegger, Rob Herring, Mark Rutland,
	Geert Uytterhoeven, Simon Horman, Ramesh Shanmugasundaram,
	linux-can, netdev, devicetree, linux-renesas-soc, Chris Paterson
In-Reply-To: <1480003917-3953-1-git-send-email-chris.paterson2@renesas.com>

Signed-off-by: Chris Paterson <chris.paterson2@renesas.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Acked-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
 Documentation/devicetree/bindings/net/can/rcar_canfd.txt | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/Documentation/devicetree/bindings/net/can/rcar_canfd.txt b/Documentation/devicetree/bindings/net/can/rcar_canfd.txt
index 22a6f10..788f273 100644
--- a/Documentation/devicetree/bindings/net/can/rcar_canfd.txt
+++ b/Documentation/devicetree/bindings/net/can/rcar_canfd.txt
@@ -5,6 +5,7 @@ Required properties:
 - compatible: Must contain one or more of the following:
   - "renesas,rcar-gen3-canfd" for R-Car Gen3 compatible controller.
   - "renesas,r8a7795-canfd" for R8A7795 (R-Car H3) compatible controller.
+  - "renesas,r8a7796-canfd" for R8A7796 (R-Car M3) compatible controller.
 
   When compatible with the generic version, nodes must list the
   SoC-specific version corresponding to the platform first, followed by the
@@ -23,11 +24,12 @@ The name of the child nodes are "channel0" and "channel1" respectively. Each
 child node supports the "status" property only, which is used to
 enable/disable the respective channel.
 
-Required properties for "renesas,r8a7795-canfd" compatible:
-In R8A7795 SoC, canfd clock is a div6 clock and can be used by both CAN
-and CAN FD controller at the same time. It needs to be scaled to maximum
-frequency if any of these controllers use it. This is done using the
-below properties.
+Required properties for "renesas,r8a7795-canfd" and "renesas,r8a7796-canfd"
+compatible:
+In R8A7795 and R8A7796 SoCs, canfd clock is a div6 clock and can be used by both
+CAN and CAN FD controller at the same time. It needs to be scaled to maximum
+frequency if any of these controllers use it. This is done using the below
+properties:
 
 - assigned-clocks: phandle of canfd clock.
 - assigned-clock-rates: maximum frequency of this clock.
-- 
1.9.1

^ permalink raw reply related

* [PATCH v2 0/3] arm64: dts: r8a7796: Add CAN/CAN FD support
From: Chris Paterson @ 2016-11-24 16:13 UTC (permalink / raw)
  To: Simon Horman
  Cc: Marc Kleine-Budde, Rob Herring, Mark Rutland, Geert Uytterhoeven,
	Ramesh Shanmugasundaram,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-renesas-soc-u79uwXL29TY76Z2rM5mHXA, Chris Paterson
In-Reply-To: <1479903243-1860-1-git-send-email-chris.paterson2-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>

This series adds CAN and CAN FD support to the r8a7796.

Changes since v1:
- Split device tree changes from bindings documentation.
- Rebased on renesas-devel-20161123v2-v4.9-rc6.


Chris Paterson (3):
  arm64: dts: r8a7796: Add CAN external clock support
  arm64: dts: r8a7796: Add CAN support
  arm64: dts: r8a7796: Add CAN FD support

 arch/arm64/boot/dts/renesas/r8a7796.dtsi | 61 ++++++++++++++++++++++++++++++++
 1 file changed, 61 insertions(+)

-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* [PATCH v2 1/3] arm64: dts: r8a7796: Add CAN external clock support
From: Chris Paterson @ 2016-11-24 16:13 UTC (permalink / raw)
  To: Simon Horman
  Cc: Marc Kleine-Budde, Rob Herring, Mark Rutland, Geert Uytterhoeven,
	Ramesh Shanmugasundaram,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-renesas-soc-u79uwXL29TY76Z2rM5mHXA, Chris Paterson
In-Reply-To: <1480004021-4037-1-git-send-email-chris.paterson2-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>

Adds external CAN clock node for r8a7796. This clock can be used as
fCAN clock of CAN and CAN FD controller.

Based on a patch for r8a7795 by Ramesh Shanmugasundaram.

Signed-off-by: Chris Paterson <chris.paterson2-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
Reviewed-by: Geert Uytterhoeven <geert+renesas-gXvu3+zWzMSzQB+pC5nmwQ@public.gmane.org>
Acked-by: Marc Kleine-Budde <mkl-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
---
 arch/arm64/boot/dts/renesas/r8a7796.dtsi | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm64/boot/dts/renesas/r8a7796.dtsi b/arch/arm64/boot/dts/renesas/r8a7796.dtsi
index c34c684..61d165b 100644
--- a/arch/arm64/boot/dts/renesas/r8a7796.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a7796.dtsi
@@ -69,6 +69,13 @@
 		clock-frequency = <0>;
 	};
 
+	/* External CAN clock - to be overridden by boards that provide it */
+	can_clk: can {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <0>;
+	};
+
 	/* External SCIF clock - to be overridden by boards that provide it */
 	scif_clk: scif {
 		compatible = "fixed-clock";
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related

* [PATCH v2 2/3] arm64: dts: r8a7796: Add CAN support
From: Chris Paterson @ 2016-11-24 16:13 UTC (permalink / raw)
  To: Simon Horman
  Cc: Marc Kleine-Budde, Rob Herring, Mark Rutland, Geert Uytterhoeven,
	Ramesh Shanmugasundaram, linux-arm-kernel, devicetree,
	linux-renesas-soc, Chris Paterson
In-Reply-To: <1480004021-4037-1-git-send-email-chris.paterson2@renesas.com>

Adds CAN controller nodes for r8a7796.

Based on a patch for r8a7795 by Ramesh Shanmugasundaram.

Signed-off-by: Chris Paterson <chris.paterson2@renesas.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Acked-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
 arch/arm64/boot/dts/renesas/r8a7796.dtsi | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/arch/arm64/boot/dts/renesas/r8a7796.dtsi b/arch/arm64/boot/dts/renesas/r8a7796.dtsi
index 61d165b..47fa29c 100644
--- a/arch/arm64/boot/dts/renesas/r8a7796.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a7796.dtsi
@@ -362,6 +362,36 @@
 			status = "disabled";
 		};
 
+		can0: can@e6c30000 {
+			compatible = "renesas,can-r8a7796",
+				     "renesas,rcar-gen3-can";
+			reg = <0 0xe6c30000 0 0x1000>;
+			interrupts = <GIC_SPI 186 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 916>,
+			       <&cpg CPG_CORE R8A7796_CLK_CANFD>,
+			       <&can_clk>;
+			clock-names = "clkp1", "clkp2", "can_clk";
+			assigned-clocks = <&cpg CPG_CORE R8A7796_CLK_CANFD>;
+			assigned-clock-rates = <40000000>;
+			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+			status = "disabled";
+		};
+
+		can1: can@e6c38000 {
+			compatible = "renesas,can-r8a7796",
+				     "renesas,rcar-gen3-can";
+			reg = <0 0xe6c38000 0 0x1000>;
+			interrupts = <GIC_SPI 187 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 915>,
+			       <&cpg CPG_CORE R8A7796_CLK_CANFD>,
+			       <&can_clk>;
+			clock-names = "clkp1", "clkp2", "can_clk";
+			assigned-clocks = <&cpg CPG_CORE R8A7796_CLK_CANFD>;
+			assigned-clock-rates = <40000000>;
+			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+			status = "disabled";
+		};
+
 		scif2: serial@e6e88000 {
 			compatible = "renesas,scif-r8a7796",
 				     "renesas,rcar-gen3-scif", "renesas,scif";
-- 
1.9.1

^ permalink raw reply related

* [PATCH v2 3/3] arm64: dts: r8a7796: Add CAN FD support
From: Chris Paterson @ 2016-11-24 16:13 UTC (permalink / raw)
  To: Simon Horman
  Cc: Marc Kleine-Budde, Rob Herring, Mark Rutland, Geert Uytterhoeven,
	Ramesh Shanmugasundaram, linux-arm-kernel, devicetree,
	linux-renesas-soc, Chris Paterson
In-Reply-To: <1480004021-4037-1-git-send-email-chris.paterson2@renesas.com>

Adds CAN FD controller node for r8a7796.

Based on a patch for r8a7795 by Ramesh Shanmugasundaram.

Signed-off-by: Chris Paterson <chris.paterson2@renesas.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Acked-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
 arch/arm64/boot/dts/renesas/r8a7796.dtsi | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/arch/arm64/boot/dts/renesas/r8a7796.dtsi b/arch/arm64/boot/dts/renesas/r8a7796.dtsi
index 47fa29c..1ed1886 100644
--- a/arch/arm64/boot/dts/renesas/r8a7796.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a7796.dtsi
@@ -392,6 +392,30 @@
 			status = "disabled";
 		};
 
+		canfd: can@e66c0000 {
+			compatible = "renesas,r8a7796-canfd",
+				     "renesas,rcar-gen3-canfd";
+			reg = <0 0xe66c0000 0 0x8000>;
+			interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>,
+				   <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 914>,
+			       <&cpg CPG_CORE R8A7796_CLK_CANFD>,
+			       <&can_clk>;
+			clock-names = "fck", "canfd", "can_clk";
+			assigned-clocks = <&cpg CPG_CORE R8A7796_CLK_CANFD>;
+			assigned-clock-rates = <40000000>;
+			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+			status = "disabled";
+
+			channel0 {
+				status = "disabled";
+			};
+
+			channel1 {
+				status = "disabled";
+			};
+		};
+
 		scif2: serial@e6e88000 {
 			compatible = "renesas,scif-r8a7796",
 				     "renesas,rcar-gen3-scif", "renesas,scif";
-- 
1.9.1

^ permalink raw reply related

* Re: [PATCH 0/3] arm64: dts: r8a7796: Add CAN/CAN FD support
From: Geert Uytterhoeven @ 2016-11-24 16:41 UTC (permalink / raw)
  To: Chris Paterson
  Cc: Simon Horman, Marc Kleine-Budde, Wolfgang Grandegger, Magnus Damm,
	Rob Herring, Mark Rutland, Ramesh Shanmugasundaram,
	linux-renesas-soc-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
	linux-can-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <HK2PR0601MB1329C747CA5C6B5222C02C3FB7B60-5BHi1SMfQIfsvBovKiDY8NK/flDYrvD0nBOFsp37pqbUKgpGm//BTAC/G2K4zDHf@public.gmane.org>

Hi Chris,

On Thu, Nov 24, 2016 at 3:25 PM, Chris Paterson
<Chris.Paterson2-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org> wrote:
> From: Simon Horman [mailto:horms-/R6kz+dDXgpPR4JQBCEnsQ@public.gmane.org]
> Sent: 24 November 2016 10:18
>> On Thu, Nov 24, 2016 at 10:05:08AM +0000, Chris Paterson wrote:
>> > From: Simon Horman [mailto:horms-/R6kz+dDXgpPR4JQBCEnsQ@public.gmane.org]
>> > > Regarding the arch/arm64/boot/dts/renesas/ portion, I would like
>> > > some consideration given to what effect enabling memory above 4Gb
>> > > (64bit
>> > > addressing) would have.
>> >
>> > Can you give me some guidance here? I'm not sure what you're referring
>> > to. As far as I know the DT reg definition here is 64-bit, or are you
>> > referring to DMA usage? If the later, neither CAN driver uses DMA.
>>
>> Sorry for not being clearer.
>>
>> What I would like to know is if there are any problems in the CAN driver or
>> hardware that would prevent it from functioning with memory that requires
>> 64bit addressing present.
>>
>> If the CAN hardware cannot use DMA then DMA doesn't need to be taken
>> into account. But if it DMA could be enabled in future for CAN, for example
>> after some driver enhancements, then it would be good to know if 64bit
>> memory can be supported - if not it would imply DMA cannot be enabled.
>
> Thank you for the clarification.
>
> The CAN interface for r8a7795/6 does not support DMA.
>
> With CAN FD there is currently a H/W issue that means DMA is unusable.

Is that issue present on R-Car M3-W, or only on R-Car H3 ES1.x?

> Potentially this issue could be fixed in the future and DMA support could
> be added to the driver. If this happens I can see no reason why the CAN FD
> IP wouldn't be able to handle DMA transfers when using 64bit addressing.

Yep, AFAIK it uses SYS-DMAC, which supports 64-bit addressing.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.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
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [net-next PATCH v1 1/2] net: dt-bindings: add RGMII TX delay configuration to meson8b-dwmac
From: Martin Blumenstingl @ 2016-11-24 16:52 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: linux-amlogic-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA, netdev-u79uwXL29TY76Z2rM5mHXA,
	davem-fT/PcQaiUtIeIZ0/mPfg9Q, khilman-rdvid1DuHRBWk0Htik3J/w,
	mark.rutland-5wv7dgnIgG8, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	alexandre.torgue-qxv4g6HH51o, peppe.cavallaro-qxv4g6HH51o,
	carlo-KA+7E9HrN00dnm+yROfE0A, jbrunet-rdvid1DuHRBWk0Htik3J/w
In-Reply-To: <20161124154858.GB20455-g2DYL2Zd6BY@public.gmane.org>

Hi Andrew,

On Thu, Nov 24, 2016 at 4:48 PM, Andrew Lunn <andrew-g2DYL2Zd6BY@public.gmane.org> wrote:
>> The configuration values are provided as preprocessor macros to make the
>> devicetree files easier to read.
>
> Hi Martin
>
> If i'm reading the code/comments correctly, you can set the delay to
> 0, 2, 4 or 6ns? So calling this property amlogic,tx-delay-ns would be
> even easier to read.
indeed, this sounds like a very nice idea (as it moves the calculation
from the programmer's brain to dwmac-meson8b.c)!

I'll send an updated version once I received enough feedback (in case
something else is wrong with the patches)
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: Re: [RFC PATCH 0/5] arm64: Allwinner H5 support
From: Ian Campbell @ 2016-11-24 17:03 UTC (permalink / raw)
  To: andre.przywara-5wv7dgnIgG8, Maxime Ripard
  Cc: Chen-Yu Tsai, Icenowy Zheng, linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Mark Rutland,
	Rob Herring, devicetree-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <560f873c-7ad9-5614-21f6-489879380ebe-5wv7dgnIgG8@public.gmane.org>

On Thu, 2016-11-24 at 11:05 +0000, Andre Przywara wrote:
> 
> > I don't have any major comments but I guess it all depends on the DT
> > maintainers view on the symbolic link to share the DTSI.
> 
> I am curious too ;-)
> But I saw symlinks for the RaspberryPi 3 (check
> arch/arm64/boot/dts/broadcom) and VExpress, so I picked that low hanging
> fruit ;-)

See http://git.kernel.org/torvalds/linux/c/8ee57b8182c4 and the ML
discussion around the posting of that for some background on why the
symlinks are being used in preference to #include or /include/.

IIRC there was some further discussion on some lists when http://git.ke
rnel.org/torvalds/linux/c/76aa75916880 was posted too.

Ian.

-- 
You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/d/optout.

^ permalink raw reply

* Re: [net-next PATCH v1 0/2] stmmac: dwmac-meson8b: configurable RGMII TX delay
From: Martin Blumenstingl @ 2016-11-24 17:05 UTC (permalink / raw)
  To: Jerome Brunet, f.fainelli-Re5JQEeQqe8AvxtiuMwx3w
  Cc: linux-amlogic-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA, netdev-u79uwXL29TY76Z2rM5mHXA,
	davem-fT/PcQaiUtIeIZ0/mPfg9Q, khilman-rdvid1DuHRBWk0Htik3J/w,
	mark.rutland-5wv7dgnIgG8, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	alexandre.torgue-qxv4g6HH51o, peppe.cavallaro-qxv4g6HH51o,
	carlo-KA+7E9HrN00dnm+yROfE0A
In-Reply-To: <1480002964.17538.131.camel-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>

On Thu, Nov 24, 2016 at 4:56 PM, Jerome Brunet <jbrunet-rdvid1DuHRBWk0Htik3J/w@public.gmane.org> wrote:
> On Thu, 2016-11-24 at 15:34 +0100, Martin Blumenstingl wrote:
>> Currently the dwmac-meson8b stmmac glue driver uses a hardcoded 1/4
>> cycle TX clock delay. This seems to work fine for many boards (for
>> example Odroid-C2 or Amlogic's reference boards) but there are some
>> others where TX traffic is simply broken.
>> There are probably multiple reasons why it's working on some boards
>> while it's broken on others:
>> - some of Amlogic's reference boards are using a Micrel PHY
>> - hardware circuit design
>> - maybe more...
>>
>> This raises a question though:
>> Which device is supposed to enable the TX delay when both MAC and PHY
>> support it? And should we implement it for each PHY / MAC separately
>> or should we think about a more generic solution (currently it's not
>> possible to disable the TX delay generated by the RTL8211F PHY via
>> devicetree when using phy-mode "rgmii")?
>
> Actually you can skip the part which activate the Tx-delay on the phy
> by setting "phy-mode = "rgmii-id" instead of "rgmii"
>
> phy->interface will no longer be PHY_INTERFACE_MODE_RGMII
> but PHY_INTERFACE_MODE_RGMII_ID.
unfortunately this is not true for RTL8211F (I did my previous tests
with the same expectation in mind)!
the code seems to suggest that TX-delay is disabled whenever mode !=
PHY_INTERFACE_MODE_RGMII.
BUT: on my device RTL8211F_TX_DELAY is set even before
"phy_write(phydev, 0x11, reg);"!

Based on what I found it seems that rgmii-id, rgmii-txid and
rgmii-rxid are supposed to be handled by the PHY.
That would mean that we have two problems here:
1) drivers/net/phy/realtek.c:rtl8211f_config_init should check for
PHY_INTERFACE_MODE_RGMII_ID or PHY_INTERFACE_MODE_RGMII_TXID and
enable the TX-delay in that case - otherwise explicitly disable it
2) dwmac-meson8b.c should only use the configured TX-delay for
PHY_INTERFACE_MODE_RGMII
@Florian: could you please share your thoughts on this (who handles
the TX delay in which case)?


Regards,
Martin
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [RFC PATCH net v2 0/3] Fix OdroidC2 Gigabit Tx link issue
From: Martin Blumenstingl @ 2016-11-24 17:10 UTC (permalink / raw)
  To: Jerome Brunet
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA, devicetree-u79uwXL29TY76Z2rM5mHXA,
	Florian Fainelli, Carlo Caione, Kevin Hilman, Giuseppe Cavallaro,
	Alexandre TORGUE, Andre Roth, Neil Armstrong,
	linux-amlogic-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1480003306.17538.137.camel-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>

On Thu, Nov 24, 2016 at 5:01 PM, Jerome Brunet <jbrunet-rdvid1DuHRBWk0Htik3J/w@public.gmane.org> wrote:
> On Thu, 2016-11-24 at 15:40 +0100, Martin Blumenstingl wrote:
>> Hi Jerome,
>>
>> On Mon, Nov 21, 2016 at 4:35 PM, Jerome Brunet <jbrunet-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
>> wrote:
>> >
>> > This patchset fixes an issue with the OdroidC2 board (DWMAC +
>> > RTL8211F).
>> > Initially reported as a low Tx throughput issue at gigabit speed,
>> > the
>> > platform enters LPI too often. This eventually break the link (both
>> > Tx
>> > and Rx), and require to bring the interface down and up again to
>> > get the
>> > Rx path working again.
>> >
>> > The root cause of this issue is not fully understood yet but
>> > disabling EEE
>> > advertisement on the PHY prevent this feature to be negotiated.
>> > With this change, the link is stable and reliable, with the
>> > expected
>> > throughput performance.
>> I have just sent a series which allows configuring the TX delay on
>> the
>> MAC (dwmac-meson8b glue) side: [0]
>> Disabling the TX delay generated by the MAC fixes TX throughput for
>> me, even when leaving EEE enabled in the RTL8211F PHY driver!
>>
>> Unfortunately the RTL8211F PHY is a black-box for the community
>> because there is no public datasheeet available.
>> *maybe* (pure speculation!) they're enabling the TX delay based on
>> some internal magic only when EEE is enabled.
>
> Hi already tried acting on the register setting the TX_delay. I also
> tried on the PHY. I never been able to improve situation on the
> Odroic2. Only disabling EEE improved the situation.
OK, thanks for clarifying this!

> To make sure, i tried again with your patch but the result remains
> unchanged. With Tx_delay disabled (either the mac or the phy), the
> situation is even worse, it seems that nothing gets through
This is interesting, because in your case you should have a 4ns TX
delay (2ns from the MAC and presumably 2ns from the PHY).
Maybe that is also the reason why the TX delay is configurable in 2ns
steps in PRG_ETHERNET0 on Amlogic SoCs.

out of curiosity: have you tried setting a 4ns (half clock-cycle) TX
delay for the MAC and disabling it in the PHY?


Regards,
Martin
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* RE: [PATCH 0/3] arm64: dts: r8a7796: Add CAN/CAN FD support
From: Chris Paterson @ 2016-11-24 17:12 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Simon Horman, Marc Kleine-Budde, Wolfgang Grandegger, Magnus Damm,
	Rob Herring, Mark Rutland, Ramesh Shanmugasundaram,
	linux-renesas-soc@vger.kernel.org, devicetree@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org, linux-can@vger.kernel.org
In-Reply-To: <CAMuHMdXO=uFuJCXPjkdYB_CeyfPMqy6cMrOW=s1DZzcJ9Gp33A@mail.gmail.com>

Hello Geert,

From: geert.uytterhoeven@gmail.com
Sent: 24 November 2016 16:42
> Hi Chris,
> 
> On Thu, Nov 24, 2016 at 3:25 PM, Chris Paterson
> <Chris.Paterson2@renesas.com> wrote:
> > From: Simon Horman [mailto:horms@verge.net.au]
> > Sent: 24 November 2016 10:18
> >> On Thu, Nov 24, 2016 at 10:05:08AM +0000, Chris Paterson wrote:
> >> > From: Simon Horman [mailto:horms@verge.net.au]
> >> > > Regarding the arch/arm64/boot/dts/renesas/ portion, I would like
> >> > > some consideration given to what effect enabling memory above 4Gb
> >> > > (64bit
> >> > > addressing) would have.
> >> >
> >> > Can you give me some guidance here? I'm not sure what you're
> >> > referring to. As far as I know the DT reg definition here is
> >> > 64-bit, or are you referring to DMA usage? If the later, neither CAN
> driver uses DMA.
> >>
> >> Sorry for not being clearer.
> >>
> >> What I would like to know is if there are any problems in the CAN
> >> driver or hardware that would prevent it from functioning with memory
> >> that requires 64bit addressing present.
> >>
> >> If the CAN hardware cannot use DMA then DMA doesn't need to be
> taken
> >> into account. But if it DMA could be enabled in future for CAN, for
> >> example after some driver enhancements, then it would be good to know
> >> if 64bit memory can be supported - if not it would imply DMA cannot be
> enabled.
> >
> > Thank you for the clarification.
> >
> > The CAN interface for r8a7795/6 does not support DMA.
> >
> > With CAN FD there is currently a H/W issue that means DMA is unusable.
> 
> Is that issue present on R-Car M3-W, or only on R-Car H3 ES1.x?

Both

> 
> > Potentially this issue could be fixed in the future and DMA support
> > could be added to the driver. If this happens I can see no reason why
> > the CAN FD IP wouldn't be able to handle DMA transfers when using 64bit
> addressing.
> 
> Yep, AFAIK it uses SYS-DMAC, which supports 64-bit addressing.

Yep

> 
> 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 v28 9/9] Documentation: dt: chosen properties for arm64 kdump
From: Catalin Marinas @ 2016-11-24 17:14 UTC (permalink / raw)
  To: robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8
  Cc: AKASHI Takahiro, will.deacon-5wv7dgnIgG8,
	devicetree-u79uwXL29TY76Z2rM5mHXA, geoff-wEGCiKHe2LqWVfeAwA7xHQ,
	kexec-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, james.morse-5wv7dgnIgG8,
	bauerman-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8,
	dyoung-H+wXaHxf7aLQT0dZR+AlfA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <20161124095944.7167-1-takahiro.akashi-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>

On Thu, Nov 24, 2016 at 06:59:44PM +0900, AKASHI Takahiro wrote:
> From: James Morse <james.morse-5wv7dgnIgG8@public.gmane.org>
> 
> Add documentation for
> 	linux,crashkernel-base and crashkernel-size,
> 	linux,usable-memory-range
> 	linux,elfcorehdr
> used by arm64 kdump to decribe the kdump reserved area, and
> the elfcorehdr's location within it.
> 
> Signed-off-by: James Morse <james.morse-5wv7dgnIgG8@public.gmane.org>
> [takahiro.akashi-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org: added "linux,crashkernel-base" and "-size" ]
> Signed-off-by: AKASHI Takahiro <takahiro.akashi-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> Cc: devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> Cc: Rob Herring <robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> Cc: Mark Rutland <mark.rutland-5wv7dgnIgG8@public.gmane.org>

Rob, Mark, are you ok with this patch?

-- 
Catalin
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH v8 3/8] drivers:input:tsc2007: add iio interface to read external ADC input and temperature
From: Jonathan Cameron @ 2016-11-24 17:38 UTC (permalink / raw)
  To: H. Nikolaus Schaller, Sebastian Reichel, Dmitry Torokhov,
	Mark Rutland, Benoît Cousson, Tony Lindgren, Russell King,
	Arnd Bergmann, Michael Welling, Mika Penttilä,
	Javier Martinez Canillas, Igor Grinberg, Andrew F. Davis,
	Mark Brown, Jonathan Cameron, Rob Herring, Alexander Stein,
	Eric Engestrom
  Cc: linux-input-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-omap-u79uwXL29TY76Z2rM5mHXA,
	letux-kernel-S0jZdbWzriLCfDggNXIi3w,
	linux-iio-u79uwXL29TY76Z2rM5mHXA,
	kernel-Jl6IXVxNIMRxAtABVqVhTwC/G2K4zDHf
In-Reply-To: <99f236df48b03b3188e12f94a20097f8440db7a5.1479823354.git.hns-xXXSsgcRVICgSpxsJD1C4w@public.gmane.org>



On 22 November 2016 14:02:30 GMT+00:00, "H. Nikolaus Schaller" <hns-xXXSsgcRVICgSpxsJD1C4w@public.gmane.org> wrote:
>The tsc2007 chip not only has a resistive touch screen controller but
>also an external AUX adc imput which can be used for an ambient
>light sensor, battery voltage monitoring or any general purpose.
>
>Additionally it can measure the chip temperature.
>
>This extension provides an iio interface for these adc channels.
>
>Since it is not wasting much resources and is very straightforward,
>we simply provide all other adc channels as optional iio interfaces
>as weel. This can be used for debugging or special applications.
>
>This patch also splits the tsc2007 driver in several source files:
>tsc2007.h -- constants, structs and stubs
>tsc2007_core.c -- functional parts of the original driver
>tsc2007_iio.c -- the optional iio stuff
>
>Makefile magic allows to conditionally link the iio stuff
>if CONFIG_IIO=y or =m in a way that it works with
>CONFIG_TOUCHSCREEN_TSC2007=m.
>
>Signed-off-by: H. Nikolaus Schaller <hns-xXXSsgcRVICgSpxsJD1C4w@public.gmane.org>
>Reviewed-by: Jonathan Cameron <jic23-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
>---
> drivers/input/touchscreen/Makefile                 |   7 +
>drivers/input/touchscreen/tsc2007.h                | 116
>++++++++++++++++
> .../touchscreen/{tsc2007.c => tsc2007_core.c}      |  95 +++----------
>drivers/input/touchscreen/tsc2007_iio.c            | 150
>+++++++++++++++++++++
> 4 files changed, 294 insertions(+), 74 deletions(-)
> create mode 100644 drivers/input/touchscreen/tsc2007.h
> rename drivers/input/touchscreen/{tsc2007.c => tsc2007_core.c} (86%)
> create mode 100644 drivers/input/touchscreen/tsc2007_iio.c
>
>diff --git a/drivers/input/touchscreen/Makefile
>b/drivers/input/touchscreen/Makefile
>index 81b8645..3be0d19 100644
>--- a/drivers/input/touchscreen/Makefile
>+++ b/drivers/input/touchscreen/Makefile
>@@ -80,6 +80,13 @@ obj-$(CONFIG_TOUCHSCREEN_TSC_SERIO)	+= tsc40.o
> obj-$(CONFIG_TOUCHSCREEN_TSC200X_CORE)	+= tsc200x-core.o
> obj-$(CONFIG_TOUCHSCREEN_TSC2004)	+= tsc2004.o
> obj-$(CONFIG_TOUCHSCREEN_TSC2005)	+= tsc2005.o
>+tsc2007-y				:= tsc2007_core.o
>+ifeq ($(CONFIG_IIO),y)
>+tsc2007-y				+= tsc2007_iio.o
>+endif
>+ifeq ($(CONFIG_IIO),m)
>+tsc2007-y				+= tsc2007_iio.o

Not tsc2007-m ?

I don't follow how this works!
>+endif
> obj-$(CONFIG_TOUCHSCREEN_TSC2007)	+= tsc2007.o
> obj-$(CONFIG_TOUCHSCREEN_UCB1400)	+= ucb1400_ts.o
> obj-$(CONFIG_TOUCHSCREEN_WACOM_W8001)	+= wacom_w8001.o
>diff --git a/drivers/input/touchscreen/tsc2007.h
>b/drivers/input/touchscreen/tsc2007.h
>new file mode 100644
>index 0000000..c25932f
>--- /dev/null
>+++ b/drivers/input/touchscreen/tsc2007.h
>@@ -0,0 +1,116 @@
>+/*
>+ * Copyright (c) 2008 MtekVision Co., Ltd.
>+ *	Kwangwoo Lee <kwlee-ec7hoAtq5SbSUeElwK9/Pw@public.gmane.org>
>+ *
>+ * Using code from:
>+ *  - ads7846.c
>+ *	Copyright (c) 2005 David Brownell
>+ *	Copyright (c) 2006 Nokia Corporation
>+ *  - corgi_ts.c
>+ *	Copyright (C) 2004-2005 Richard Purdie
>+ *  - omap_ts.[hc], ads7846.h, ts_osk.c
>+ *	Copyright (C) 2002 MontaVista Software
>+ *	Copyright (C) 2004 Texas Instruments
>+ *	Copyright (C) 2005 Dirk Behme
>+ *
>+ *  This program is free software; you can redistribute it and/or
>modify
>+ *  it under the terms of the GNU General Public License version 2 as
>+ *  published by the Free Software Foundation.
>+ */
>+
>+#include <linux/input/touchscreen.h>
>+
>+#define TSC2007_MEASURE_TEMP0		(0x0 << 4)
>+#define TSC2007_MEASURE_AUX		(0x2 << 4)
>+#define TSC2007_MEASURE_TEMP1		(0x4 << 4)
>+#define TSC2007_ACTIVATE_XN		(0x8 << 4)
>+#define TSC2007_ACTIVATE_YN		(0x9 << 4)
>+#define TSC2007_ACTIVATE_YP_XN		(0xa << 4)
>+#define TSC2007_SETUP			(0xb << 4)
>+#define TSC2007_MEASURE_X		(0xc << 4)
>+#define TSC2007_MEASURE_Y		(0xd << 4)
>+#define TSC2007_MEASURE_Z1		(0xe << 4)
>+#define TSC2007_MEASURE_Z2		(0xf << 4)
>+
>+#define TSC2007_POWER_OFF_IRQ_EN	(0x0 << 2)
>+#define TSC2007_ADC_ON_IRQ_DIS0		(0x1 << 2)
>+#define TSC2007_ADC_OFF_IRQ_EN		(0x2 << 2)
>+#define TSC2007_ADC_ON_IRQ_DIS1		(0x3 << 2)
>+
>+#define TSC2007_12BIT			(0x0 << 1)
>+#define TSC2007_8BIT			(0x1 << 1)
>+
>+#define	MAX_12BIT			((1 << 12) - 1)
>+
>+#define ADC_ON_12BIT	(TSC2007_12BIT | TSC2007_ADC_ON_IRQ_DIS0)
>+
>+#define READ_Y		(ADC_ON_12BIT | TSC2007_MEASURE_Y)
>+#define READ_Z1		(ADC_ON_12BIT | TSC2007_MEASURE_Z1)
>+#define READ_Z2		(ADC_ON_12BIT | TSC2007_MEASURE_Z2)
>+#define READ_X		(ADC_ON_12BIT | TSC2007_MEASURE_X)
>+#define PWRDOWN		(TSC2007_12BIT | TSC2007_POWER_OFF_IRQ_EN)
>+
>+struct ts_event {
>+	u16	x;
>+	u16	y;
>+	u16	z1, z2;
>+};
>+
>+struct tsc2007 {
>+	struct input_dev	*input;
>+	char			phys[32];
>+
>+	struct i2c_client	*client;
>+
>+	u16			model;
>+	u16			x_plate_ohms;
>+
>+	struct touchscreen_properties prop;
>+
>+	bool			report_resistance;
>+	u16			min_x;
>+	u16			min_y;
>+	u16			max_x;
>+	u16			max_y;
>+	u16			max_rt;
>+	unsigned long		poll_period; /* in jiffies */
>+	int			fuzzx;
>+	int			fuzzy;
>+	int			fuzzz;
>+
>+	unsigned int		gpio;
>+	int			irq;
>+
>+	wait_queue_head_t	wait;
>+	bool			stopped;
>+	bool			pendown;
>+
>+	int			(*get_pendown_state)(struct device *);
>+	void			(*clear_penirq)(void);
>+
>+	struct mutex		mlock;
>+	struct iio_dev		*iio_dev;	/* optional */
>+};
>+
>+int tsc2007_xfer(struct tsc2007 *tsc, u8 cmd);
>+u32 tsc2007_calculate_resistance(struct tsc2007 *tsc,
>+					struct ts_event *tc);
>+bool tsc2007_is_pen_down(struct tsc2007 *ts);
>+
>+#if IS_ENABLED(CONFIG_IIO)
>+
>+/* defined in tsc2007_iio.c */
>+int tsc2007_iio_configure(struct tsc2007 *ts);
>+void tsc2007_iio_unconfigure(struct tsc2007 *ts);
>+
>+#else /* CONFIG_IIO */
>+
>+static inline int tsc2007_iio_configure(struct tsc2007 *ts)
>+{
>+	return 0;
>+}
>+static inline void tsc2007_iio_unconfigure(struct tsc2007 *ts)
>+{
>+}
>+
>+#endif /* CONFIG_IIO */
>diff --git a/drivers/input/touchscreen/tsc2007.c
>b/drivers/input/touchscreen/tsc2007_core.c
>similarity index 86%
>rename from drivers/input/touchscreen/tsc2007.c
>rename to drivers/input/touchscreen/tsc2007_core.c
>index 76b462b..812ded8 100644
>--- a/drivers/input/touchscreen/tsc2007.c
>+++ b/drivers/input/touchscreen/tsc2007_core.c
>@@ -27,79 +27,11 @@
> #include <linux/i2c.h>
> #include <linux/i2c/tsc2007.h>
> #include <linux/of_device.h>
>-#include <linux/of.h>
> #include <linux/of_gpio.h>
>-#include <linux/input/touchscreen.h>
>-
>-#define TSC2007_MEASURE_TEMP0		(0x0 << 4)
>-#define TSC2007_MEASURE_AUX		(0x2 << 4)
>-#define TSC2007_MEASURE_TEMP1		(0x4 << 4)
>-#define TSC2007_ACTIVATE_XN		(0x8 << 4)
>-#define TSC2007_ACTIVATE_YN		(0x9 << 4)
>-#define TSC2007_ACTIVATE_YP_XN		(0xa << 4)
>-#define TSC2007_SETUP			(0xb << 4)
>-#define TSC2007_MEASURE_X		(0xc << 4)
>-#define TSC2007_MEASURE_Y		(0xd << 4)
>-#define TSC2007_MEASURE_Z1		(0xe << 4)
>-#define TSC2007_MEASURE_Z2		(0xf << 4)
>-
>-#define TSC2007_POWER_OFF_IRQ_EN	(0x0 << 2)
>-#define TSC2007_ADC_ON_IRQ_DIS0		(0x1 << 2)
>-#define TSC2007_ADC_OFF_IRQ_EN		(0x2 << 2)
>-#define TSC2007_ADC_ON_IRQ_DIS1		(0x3 << 2)
>-
>-#define TSC2007_12BIT			(0x0 << 1)
>-#define TSC2007_8BIT			(0x1 << 1)
>-
>-#define	MAX_12BIT			((1 << 12) - 1)
>-
>-#define ADC_ON_12BIT	(TSC2007_12BIT | TSC2007_ADC_ON_IRQ_DIS0)
>-
>-#define READ_Y		(ADC_ON_12BIT | TSC2007_MEASURE_Y)
>-#define READ_Z1		(ADC_ON_12BIT | TSC2007_MEASURE_Z1)
>-#define READ_Z2		(ADC_ON_12BIT | TSC2007_MEASURE_Z2)
>-#define READ_X		(ADC_ON_12BIT | TSC2007_MEASURE_X)
>-#define PWRDOWN		(TSC2007_12BIT | TSC2007_POWER_OFF_IRQ_EN)
>-
>-struct ts_event {
>-	u16	x;
>-	u16	y;
>-	u16	z1, z2;
>-};
>-
>-struct tsc2007 {
>-	struct input_dev	*input;
>-	char			phys[32];
>-
>-	struct i2c_client	*client;
>-
>-	u16			model;
>-	u16			x_plate_ohms;
>-
>-	struct touchscreen_properties prop;
>-
>-	bool			report_resistance;
>-	u16			min_x;
>-	u16			min_y;
>-	u16			max_x;
>-	u16			max_y;
>-	u16			max_rt;
>-	unsigned long		poll_period; /* in jiffies */
>-	int			fuzzx;
>-	int			fuzzy;
>-	int			fuzzz;
>-
>-	unsigned		gpio;
>-	int			irq;
>-
>-	wait_queue_head_t	wait;
>-	bool			stopped;
>+#include "tsc2007.h"
> 
>-	int			(*get_pendown_state)(struct device *);
>-	void			(*clear_penirq)(void);
>-};
> 
>-static inline int tsc2007_xfer(struct tsc2007 *tsc, u8 cmd)
>+int tsc2007_xfer(struct tsc2007 *tsc, u8 cmd)
> {
> 	s32 data;
> 	u16 val;
>@@ -137,7 +69,7 @@ static void tsc2007_read_values(struct tsc2007 *tsc,
>struct ts_event *tc)
> 	tsc2007_xfer(tsc, PWRDOWN);
> }
> 
>-static u32 tsc2007_calculate_resistance(struct tsc2007 *tsc,
>+u32 tsc2007_calculate_resistance(struct tsc2007 *tsc,
> 					struct ts_event *tc)
> {
> 	u32 rt = 0;
>@@ -158,7 +90,7 @@ static u32 tsc2007_calculate_resistance(struct
>tsc2007 *tsc,
> 	return rt;
> }
> 
>-static bool tsc2007_is_pen_down(struct tsc2007 *ts)
>+bool tsc2007_is_pen_down(struct tsc2007 *ts)
> {
> 	/*
> 	 * NOTE: We can't rely on the pressure to determine the pen down
>@@ -191,7 +123,10 @@ static irqreturn_t tsc2007_soft_irq(int irq, void
>*handle)
> 	while (!ts->stopped && tsc2007_is_pen_down(ts)) {
> 
> 		/* pen is down, continue with the measurement */
>+
>+		mutex_lock(&ts->mlock);
> 		tsc2007_read_values(ts, &tc);
>+		mutex_unlock(&ts->mlock);
> 
> 		rt = tsc2007_calculate_resistance(ts, &tc);
> 
>@@ -441,7 +376,8 @@ static void tsc2007_call_exit_platform_hw(void
>*data)
> static int tsc2007_probe(struct i2c_client *client,
> 			 const struct i2c_device_id *id)
> {
>-	const struct tsc2007_platform_data *pdata =
>dev_get_platdata(&client->dev);
>+	const struct tsc2007_platform_data *pdata =
>+		dev_get_platdata(&client->dev);
> 	struct tsc2007 *ts;
> 	struct input_dev *input_dev;
> 	int err;
>@@ -463,7 +399,9 @@ static int tsc2007_probe(struct i2c_client *client,
> 	ts->client = client;
> 	ts->irq = client->irq;
> 	ts->input = input_dev;
>+
> 	init_waitqueue_head(&ts->wait);
>+	mutex_init(&ts->mlock);
> 
> 	snprintf(ts->phys, sizeof(ts->phys),
> 		 "%s/input0", dev_name(&client->dev));
>@@ -534,7 +472,7 @@ static int tsc2007_probe(struct i2c_client *client,
> 	if (err < 0) {
> 		dev_err(&client->dev,
> 			"Failed to setup chip: %d\n", err);
>-		return err;	/* usually, chip does not respond */
>+		return err;	/* chip does not respond */
> 	}
> 
> 	err = input_register_device(input_dev);
>@@ -544,6 +482,14 @@ static int tsc2007_probe(struct i2c_client
>*client,
> 		return err;
> 	}
> 
>+	return tsc2007_iio_configure(ts);
>+}
>+
>+static int tsc2007_remove(struct i2c_client *client)
>+{
>+	struct tsc2007 *ts = i2c_get_clientdata(client);
>+
>+	tsc2007_iio_unconfigure(ts);
> 	return 0;
> }
> 
>@@ -569,6 +515,7 @@ static struct i2c_driver tsc2007_driver = {
> 	},
> 	.id_table	= tsc2007_idtable,
> 	.probe		= tsc2007_probe,
>+	.remove		= tsc2007_remove,
> };
> 
> module_i2c_driver(tsc2007_driver);
>diff --git a/drivers/input/touchscreen/tsc2007_iio.c
>b/drivers/input/touchscreen/tsc2007_iio.c
>new file mode 100644
>index 0000000..ed79944
>--- /dev/null
>+++ b/drivers/input/touchscreen/tsc2007_iio.c
>@@ -0,0 +1,150 @@
>+/*
>+ * Copyright (c) 2016 Golden Delicious Comp. GmbH&Co. KG
>+ *	Nikolaus Schaller <hns-xXXSsgcRVICgSpxsJD1C4w@public.gmane.org>
>+ *
>+ *  This program is free software; you can redistribute it and/or
>modify
>+ *  it under the terms of the GNU General Public License version 2 as
>+ *  published by the Free Software Foundation.
>+ */
>+
>+#include <linux/i2c.h>
>+#include <linux/iio/iio.h>
>+#include "tsc2007.h"
>+
>+struct tsc2007_iio {
>+	struct tsc2007 *ts;
>+};
>+
>+#define TSC2007_CHAN_IIO(_chan, _name, _type, _chan_info) \
>+{ \
>+	.datasheet_name = _name, \
>+	.type = _type, \
>+	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |	\
>+			BIT(_chan_info), \
>+	.indexed = 1, \
>+	.channel = _chan, \
>+}
>+
>+static const struct iio_chan_spec tsc2007_iio_channel[] = {
>+	TSC2007_CHAN_IIO(0, "x", IIO_VOLTAGE, IIO_CHAN_INFO_RAW),
>+	TSC2007_CHAN_IIO(1, "y", IIO_VOLTAGE, IIO_CHAN_INFO_RAW),
>+	TSC2007_CHAN_IIO(2, "z1", IIO_VOLTAGE, IIO_CHAN_INFO_RAW),
>+	TSC2007_CHAN_IIO(3, "z2", IIO_VOLTAGE, IIO_CHAN_INFO_RAW),
>+	TSC2007_CHAN_IIO(4, "adc", IIO_VOLTAGE, IIO_CHAN_INFO_RAW),
>+	TSC2007_CHAN_IIO(5, "rt", IIO_VOLTAGE, IIO_CHAN_INFO_RAW), /* Ohms?
>*/
>+	TSC2007_CHAN_IIO(6, "pen", IIO_PRESSURE, IIO_CHAN_INFO_RAW),
>+	TSC2007_CHAN_IIO(7, "temp0", IIO_TEMP, IIO_CHAN_INFO_RAW),
>+	TSC2007_CHAN_IIO(8, "temp1", IIO_TEMP, IIO_CHAN_INFO_RAW),
>+};
>+
>+static int tsc2007_read_raw(struct iio_dev *indio_dev,
>+	struct iio_chan_spec const *chan, int *val, int *val2, long mask)
>+{
>+	struct tsc2007_iio *iio = iio_priv(indio_dev);
>+	struct tsc2007 *tsc = iio->ts;
>+	int adc_chan = chan->channel;
>+	int ret = 0;
>+
>+	if (adc_chan >= ARRAY_SIZE(tsc2007_iio_channel))
>+		return -EINVAL;
>+
>+	if (mask != IIO_CHAN_INFO_RAW)
>+		return -EINVAL;
>+
>+	mutex_lock(&tsc->mlock);
>+
>+	switch (chan->channel) {
>+	case 0:
>+		*val = tsc2007_xfer(tsc, READ_X);
>+		break;
>+	case 1:
>+		*val = tsc2007_xfer(tsc, READ_Y);
>+		break;
>+	case 2:
>+		*val = tsc2007_xfer(tsc, READ_Z1);
>+		break;
>+	case 3:
>+		*val = tsc2007_xfer(tsc, READ_Z2);
>+		break;
>+	case 4:
>+		*val = tsc2007_xfer(tsc, (ADC_ON_12BIT | TSC2007_MEASURE_AUX));
>+		break;
>+	case 5: {
>+		struct ts_event tc;
>+
>+		tc.x = tsc2007_xfer(tsc, READ_X);
>+		tc.z1 = tsc2007_xfer(tsc, READ_Z1);
>+		tc.z2 = tsc2007_xfer(tsc, READ_Z2);
>+		*val = tsc2007_calculate_resistance(tsc, &tc);
>+		break;
>+	}
>+	case 6:
>+		*val = tsc2007_is_pen_down(tsc);
>+		break;
>+	case 7:
>+		*val = tsc2007_xfer(tsc,
>+				    (ADC_ON_12BIT | TSC2007_MEASURE_TEMP0));
>+		break;
>+	case 8:
>+		*val = tsc2007_xfer(tsc,
>+				    (ADC_ON_12BIT | TSC2007_MEASURE_TEMP1));
>+		break;
>+	}
>+
>+	/* Prepare for next touch reading - power down ADC, enable PENIRQ */
>+	tsc2007_xfer(tsc, PWRDOWN);
>+
>+	mutex_unlock(&tsc->mlock);
>+
>+	ret = IIO_VAL_INT;
>+
>+	return ret;
>+}
>+
>+static const struct iio_info tsc2007_iio_info = {
>+	.read_raw = tsc2007_read_raw,
>+	.driver_module = THIS_MODULE,
>+};
>+
>+int tsc2007_iio_configure(struct tsc2007 *ts)
>+{
>+	int err;
>+	struct iio_dev *indio_dev;
>+	struct tsc2007_iio *iio;
>+
>+	indio_dev = devm_iio_device_alloc(&ts->client->dev,
>+		sizeof(struct tsc2007_iio));
>+	if (!indio_dev) {
>+		dev_err(&ts->client->dev, "iio_device_alloc failed\n");
>+		return -ENOMEM;
>+	}
>+
>+	iio = iio_priv(indio_dev);
>+	iio->ts = ts;
>+	ts->iio_dev = (void *) indio_dev;
>+
>+	indio_dev->name = "tsc2007";
>+	indio_dev->dev.parent = &ts->client->dev;
>+	indio_dev->info = &tsc2007_iio_info;
>+	indio_dev->modes = INDIO_DIRECT_MODE;
>+	indio_dev->channels = tsc2007_iio_channel;
>+	indio_dev->num_channels = ARRAY_SIZE(tsc2007_iio_channel);
>+
>+	err = iio_device_register(indio_dev);
>+	if (err < 0) {
>+		dev_err(&ts->client->dev, "iio_device_register() failed: %d\n",
>+			err);
>+		return err;
>+	}
>+
>+	return 0;
>+}
>+EXPORT_SYMBOL(tsc2007_iio_configure);
>+
>+void tsc2007_iio_unconfigure(struct tsc2007 *ts)
>+{
>+	struct iio_dev *indio_dev = ts->iio_dev;
>+
>+	iio_device_unregister(indio_dev);
>+}
>+EXPORT_SYMBOL(tsc2007_iio_unconfigure);

-- 
Sent from my Android device with K-9 Mail. Please excuse my brevity.
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH 1/4] bindings: net: stmmac: correct note about TSO
From: Alexandre Torgue @ 2016-11-24 17:42 UTC (permalink / raw)
  To: Niklas Cassel, Rob Herring, Mark Rutland, David S. Miller,
	Giuseppe CAVALLARO, Phil Reid, Niklas Cassel, Eric Engestrom
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1479911066-19752-1-git-send-email-niklass-VrBV9hrLPhE@public.gmane.org>

Hi Niklas,

On 11/23/2016 03:24 PM, Niklas Cassel wrote:
> From: Niklas Cassel <niklas.cassel-VrBV9hrLPhE@public.gmane.org>
>
> snps,tso was previously placed under AXI BUS Mode parameters,
> suggesting that the property should be in the stmmac-axi-config node.
>
> TSO (TCP Segmentation Offloading) has nothing to do with AXI BUS Mode
> parameters, and the parser actually expects it to be in the root node,
> not in the stmmac-axi-config.
>
> Also added a note about snps,tso only being available on GMAC4 and newer.
>
> Signed-off-by: Niklas Cassel <niklas.cassel-VrBV9hrLPhE@public.gmane.org>
> ---
>  Documentation/devicetree/bindings/net/stmmac.txt | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/net/stmmac.txt b/Documentation/devicetree/bindings/net/stmmac.txt
> index 41b49e6075f5..b95ff998ba73 100644
> --- a/Documentation/devicetree/bindings/net/stmmac.txt
> +++ b/Documentation/devicetree/bindings/net/stmmac.txt
> @@ -1,7 +1,7 @@
>  * STMicroelectronics 10/100/1000 Ethernet driver (GMAC)
>
>  Required properties:
> -- compatible: Should be "snps,dwmac-<ip_version>" "snps,dwmac"
> +- compatible: Should be "snps,dwmac-<ip_version>", "snps,dwmac"
>  	For backwards compatibility: "st,spear600-gmac" is also supported.
>  - reg: Address and length of the register set for the device
>  - interrupt-parent: Should be the phandle for the interrupt controller
> @@ -50,6 +50,8 @@ Optional properties:
>  - snps,ps-speed: port selection speed that can be passed to the core when
>  		 PCS is supported. For example, this is used in case of SGMII
>  		 and MAC2MAC connection.
> +- snps,tso: this enables the TSO feature otherwise it will be managed by
> +		 MAC HW capability register. Only for GMAC4 and newer.
>  - AXI BUS Mode parameters: below the list of all the parameters to program the
>  			   AXI register inside the DMA module:
>  	- snps,lpi_en: enable Low Power Interface
> @@ -62,8 +64,6 @@ Optional properties:
>  	- snps,fb: fixed-burst
>  	- snps,mb: mixed-burst
>  	- snps,rb: rebuild INCRx Burst
> -	- snps,tso: this enables the TSO feature otherwise it will be managed by
> -	    MAC HW capability register.
>  - mdio: with compatible = "snps,dwmac-mdio", create and register mdio bus.
>
>  Examples:
>
Acked-by: <alexandre.torgue-qxv4g6HH51o@public.gmane.org>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH v8 3/8] drivers:input:tsc2007: add iio interface to read external ADC input and temperature
From: H. Nikolaus Schaller @ 2016-11-24 18:05 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: Sebastian Reichel, Dmitry Torokhov, Mark Rutland,
	Benoît Cousson, Tony Lindgren, Russell King, Arnd Bergmann,
	Michael Welling, Mika Penttilä, Javier Martinez Canillas,
	Igor Grinberg, Andrew F. Davis, Mark Brown, Jonathan Cameron,
	Rob Herring, Alexander Stein, Eric Engestrom, Hans de Goede
In-Reply-To: <E42B1EF7-222E-46D6-878B-30C789CFBBC5-tko9wxEg+fIOOJlXag/Snyp2UmYkHbXO@public.gmane.org>


> Am 24.11.2016 um 18:38 schrieb Jonathan Cameron <jic23-tko9wxEg+fIOOJlXag/Snyp2UmYkHbXO@public.gmane.org>:
> 
> 
> 
> On 22 November 2016 14:02:30 GMT+00:00, "H. Nikolaus Schaller" <hns-xXXSsgcRVICgSpxsJD1C4w@public.gmane.org> wrote:
>> The tsc2007 chip not only has a resistive touch screen controller but
>> also an external AUX adc imput which can be used for an ambient
>> light sensor, battery voltage monitoring or any general purpose.
>> 
>> Additionally it can measure the chip temperature.
>> 
>> This extension provides an iio interface for these adc channels.
>> 
>> Since it is not wasting much resources and is very straightforward,
>> we simply provide all other adc channels as optional iio interfaces
>> as weel. This can be used for debugging or special applications.
>> 
>> This patch also splits the tsc2007 driver in several source files:
>> tsc2007.h -- constants, structs and stubs
>> tsc2007_core.c -- functional parts of the original driver
>> tsc2007_iio.c -- the optional iio stuff
>> 
>> Makefile magic allows to conditionally link the iio stuff
>> if CONFIG_IIO=y or =m in a way that it works with
>> CONFIG_TOUCHSCREEN_TSC2007=m.
>> 
>> Signed-off-by: H. Nikolaus Schaller <hns-xXXSsgcRVICgSpxsJD1C4w@public.gmane.org>
>> Reviewed-by: Jonathan Cameron <jic23-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
>> ---
>> drivers/input/touchscreen/Makefile                 |   7 +
>> drivers/input/touchscreen/tsc2007.h                | 116
>> ++++++++++++++++
>> .../touchscreen/{tsc2007.c => tsc2007_core.c}      |  95 +++----------
>> drivers/input/touchscreen/tsc2007_iio.c            | 150
>> +++++++++++++++++++++
>> 4 files changed, 294 insertions(+), 74 deletions(-)
>> create mode 100644 drivers/input/touchscreen/tsc2007.h
>> rename drivers/input/touchscreen/{tsc2007.c => tsc2007_core.c} (86%)
>> create mode 100644 drivers/input/touchscreen/tsc2007_iio.c
>> 
>> diff --git a/drivers/input/touchscreen/Makefile
>> b/drivers/input/touchscreen/Makefile
>> index 81b8645..3be0d19 100644
>> --- a/drivers/input/touchscreen/Makefile
>> +++ b/drivers/input/touchscreen/Makefile
>> @@ -80,6 +80,13 @@ obj-$(CONFIG_TOUCHSCREEN_TSC_SERIO)	+= tsc40.o
>> obj-$(CONFIG_TOUCHSCREEN_TSC200X_CORE)	+= tsc200x-core.o
>> obj-$(CONFIG_TOUCHSCREEN_TSC2004)	+= tsc2004.o
>> obj-$(CONFIG_TOUCHSCREEN_TSC2005)	+= tsc2005.o
>> +tsc2007-y				:= tsc2007_core.o
>> +ifeq ($(CONFIG_IIO),y)
>> +tsc2007-y				+= tsc2007_iio.o
>> +endif
>> +ifeq ($(CONFIG_IIO),m)
>> +tsc2007-y				+= tsc2007_iio.o
> 
> Not tsc2007-m ?
> 
> I don't follow how this works!

I guess tsc2007-y is an internal collector variable name
for multiple .o components. Sort of a "library" object.

While

obj-y += tsc2007.o adds it to the kernel
obj-m += tsc2007.o adds it to the modules

I am not sure if my explanation is correct but it appears
to work that way.

Anyways what shall we do? If CONFIG_TOUCHSCREEN_TSC2007=y
and IIO=m we have a problem that we need dynamic binding.

>> +endif
>> obj-$(CONFIG_TOUCHSCREEN_TSC2007)	+= tsc2007.o
>> obj-$(CONFIG_TOUCHSCREEN_UCB1400)	+= ucb1400_ts.o
>> obj-$(CONFIG_TOUCHSCREEN_WACOM_W8001)	+= wacom_w8001.o
>> diff --git a/drivers/input/touchscreen/tsc2007.h
>> b/drivers/input/touchscreen/tsc2007.h
>> new file mode 100644
>> index 0000000..c25932f
>> --- /dev/null
>> +++ b/drivers/input/touchscreen/tsc2007.h
>> @@ -0,0 +1,116 @@
>> +/*
>> + * Copyright (c) 2008 MtekVision Co., Ltd.
>> + *	Kwangwoo Lee <kwlee-ec7hoAtq5SbSUeElwK9/Pw@public.gmane.org>
>> + *
>> + * Using code from:
>> + *  - ads7846.c
>> + *	Copyright (c) 2005 David Brownell
>> + *	Copyright (c) 2006 Nokia Corporation
>> + *  - corgi_ts.c
>> + *	Copyright (C) 2004-2005 Richard Purdie
>> + *  - omap_ts.[hc], ads7846.h, ts_osk.c
>> + *	Copyright (C) 2002 MontaVista Software
>> + *	Copyright (C) 2004 Texas Instruments
>> + *	Copyright (C) 2005 Dirk Behme
>> + *
>> + *  This program is free software; you can redistribute it and/or
>> modify
>> + *  it under the terms of the GNU General Public License version 2 as
>> + *  published by the Free Software Foundation.
>> + */
>> +
>> +#include <linux/input/touchscreen.h>
>> +
>> +#define TSC2007_MEASURE_TEMP0		(0x0 << 4)
>> +#define TSC2007_MEASURE_AUX		(0x2 << 4)
>> +#define TSC2007_MEASURE_TEMP1		(0x4 << 4)
>> +#define TSC2007_ACTIVATE_XN		(0x8 << 4)
>> +#define TSC2007_ACTIVATE_YN		(0x9 << 4)
>> +#define TSC2007_ACTIVATE_YP_XN		(0xa << 4)
>> +#define TSC2007_SETUP			(0xb << 4)
>> +#define TSC2007_MEASURE_X		(0xc << 4)
>> +#define TSC2007_MEASURE_Y		(0xd << 4)
>> +#define TSC2007_MEASURE_Z1		(0xe << 4)
>> +#define TSC2007_MEASURE_Z2		(0xf << 4)
>> +
>> +#define TSC2007_POWER_OFF_IRQ_EN	(0x0 << 2)
>> +#define TSC2007_ADC_ON_IRQ_DIS0		(0x1 << 2)
>> +#define TSC2007_ADC_OFF_IRQ_EN		(0x2 << 2)
>> +#define TSC2007_ADC_ON_IRQ_DIS1		(0x3 << 2)
>> +
>> +#define TSC2007_12BIT			(0x0 << 1)
>> +#define TSC2007_8BIT			(0x1 << 1)
>> +
>> +#define	MAX_12BIT			((1 << 12) - 1)
>> +
>> +#define ADC_ON_12BIT	(TSC2007_12BIT | TSC2007_ADC_ON_IRQ_DIS0)
>> +
>> +#define READ_Y		(ADC_ON_12BIT | TSC2007_MEASURE_Y)
>> +#define READ_Z1		(ADC_ON_12BIT | TSC2007_MEASURE_Z1)
>> +#define READ_Z2		(ADC_ON_12BIT | TSC2007_MEASURE_Z2)
>> +#define READ_X		(ADC_ON_12BIT | TSC2007_MEASURE_X)
>> +#define PWRDOWN		(TSC2007_12BIT | TSC2007_POWER_OFF_IRQ_EN)
>> +
>> +struct ts_event {
>> +	u16	x;
>> +	u16	y;
>> +	u16	z1, z2;
>> +};
>> +
>> +struct tsc2007 {
>> +	struct input_dev	*input;
>> +	char			phys[32];
>> +
>> +	struct i2c_client	*client;
>> +
>> +	u16			model;
>> +	u16			x_plate_ohms;
>> +
>> +	struct touchscreen_properties prop;
>> +
>> +	bool			report_resistance;
>> +	u16			min_x;
>> +	u16			min_y;
>> +	u16			max_x;
>> +	u16			max_y;
>> +	u16			max_rt;
>> +	unsigned long		poll_period; /* in jiffies */
>> +	int			fuzzx;
>> +	int			fuzzy;
>> +	int			fuzzz;
>> +
>> +	unsigned int		gpio;
>> +	int			irq;
>> +
>> +	wait_queue_head_t	wait;
>> +	bool			stopped;
>> +	bool			pendown;
>> +
>> +	int			(*get_pendown_state)(struct device *);
>> +	void			(*clear_penirq)(void);
>> +
>> +	struct mutex		mlock;
>> +	struct iio_dev		*iio_dev;	/* optional */
>> +};
>> +
>> +int tsc2007_xfer(struct tsc2007 *tsc, u8 cmd);
>> +u32 tsc2007_calculate_resistance(struct tsc2007 *tsc,
>> +					struct ts_event *tc);
>> +bool tsc2007_is_pen_down(struct tsc2007 *ts);
>> +
>> +#if IS_ENABLED(CONFIG_IIO)
>> +
>> +/* defined in tsc2007_iio.c */
>> +int tsc2007_iio_configure(struct tsc2007 *ts);
>> +void tsc2007_iio_unconfigure(struct tsc2007 *ts);
>> +
>> +#else /* CONFIG_IIO */
>> +
>> +static inline int tsc2007_iio_configure(struct tsc2007 *ts)
>> +{
>> +	return 0;
>> +}
>> +static inline void tsc2007_iio_unconfigure(struct tsc2007 *ts)
>> +{
>> +}
>> +
>> +#endif /* CONFIG_IIO */
>> diff --git a/drivers/input/touchscreen/tsc2007.c
>> b/drivers/input/touchscreen/tsc2007_core.c
>> similarity index 86%
>> rename from drivers/input/touchscreen/tsc2007.c
>> rename to drivers/input/touchscreen/tsc2007_core.c
>> index 76b462b..812ded8 100644
>> --- a/drivers/input/touchscreen/tsc2007.c
>> +++ b/drivers/input/touchscreen/tsc2007_core.c
>> @@ -27,79 +27,11 @@
>> #include <linux/i2c.h>
>> #include <linux/i2c/tsc2007.h>
>> #include <linux/of_device.h>
>> -#include <linux/of.h>
>> #include <linux/of_gpio.h>
>> -#include <linux/input/touchscreen.h>
>> -
>> -#define TSC2007_MEASURE_TEMP0		(0x0 << 4)
>> -#define TSC2007_MEASURE_AUX		(0x2 << 4)
>> -#define TSC2007_MEASURE_TEMP1		(0x4 << 4)
>> -#define TSC2007_ACTIVATE_XN		(0x8 << 4)
>> -#define TSC2007_ACTIVATE_YN		(0x9 << 4)
>> -#define TSC2007_ACTIVATE_YP_XN		(0xa << 4)
>> -#define TSC2007_SETUP			(0xb << 4)
>> -#define TSC2007_MEASURE_X		(0xc << 4)
>> -#define TSC2007_MEASURE_Y		(0xd << 4)
>> -#define TSC2007_MEASURE_Z1		(0xe << 4)
>> -#define TSC2007_MEASURE_Z2		(0xf << 4)
>> -
>> -#define TSC2007_POWER_OFF_IRQ_EN	(0x0 << 2)
>> -#define TSC2007_ADC_ON_IRQ_DIS0		(0x1 << 2)
>> -#define TSC2007_ADC_OFF_IRQ_EN		(0x2 << 2)
>> -#define TSC2007_ADC_ON_IRQ_DIS1		(0x3 << 2)
>> -
>> -#define TSC2007_12BIT			(0x0 << 1)
>> -#define TSC2007_8BIT			(0x1 << 1)
>> -
>> -#define	MAX_12BIT			((1 << 12) - 1)
>> -
>> -#define ADC_ON_12BIT	(TSC2007_12BIT | TSC2007_ADC_ON_IRQ_DIS0)
>> -
>> -#define READ_Y		(ADC_ON_12BIT | TSC2007_MEASURE_Y)
>> -#define READ_Z1		(ADC_ON_12BIT | TSC2007_MEASURE_Z1)
>> -#define READ_Z2		(ADC_ON_12BIT | TSC2007_MEASURE_Z2)
>> -#define READ_X		(ADC_ON_12BIT | TSC2007_MEASURE_X)
>> -#define PWRDOWN		(TSC2007_12BIT | TSC2007_POWER_OFF_IRQ_EN)
>> -
>> -struct ts_event {
>> -	u16	x;
>> -	u16	y;
>> -	u16	z1, z2;
>> -};
>> -
>> -struct tsc2007 {
>> -	struct input_dev	*input;
>> -	char			phys[32];
>> -
>> -	struct i2c_client	*client;
>> -
>> -	u16			model;
>> -	u16			x_plate_ohms;
>> -
>> -	struct touchscreen_properties prop;
>> -
>> -	bool			report_resistance;
>> -	u16			min_x;
>> -	u16			min_y;
>> -	u16			max_x;
>> -	u16			max_y;
>> -	u16			max_rt;
>> -	unsigned long		poll_period; /* in jiffies */
>> -	int			fuzzx;
>> -	int			fuzzy;
>> -	int			fuzzz;
>> -
>> -	unsigned		gpio;
>> -	int			irq;
>> -
>> -	wait_queue_head_t	wait;
>> -	bool			stopped;
>> +#include "tsc2007.h"
>> 
>> -	int			(*get_pendown_state)(struct device *);
>> -	void			(*clear_penirq)(void);
>> -};
>> 
>> -static inline int tsc2007_xfer(struct tsc2007 *tsc, u8 cmd)
>> +int tsc2007_xfer(struct tsc2007 *tsc, u8 cmd)
>> {
>> 	s32 data;
>> 	u16 val;
>> @@ -137,7 +69,7 @@ static void tsc2007_read_values(struct tsc2007 *tsc,
>> struct ts_event *tc)
>> 	tsc2007_xfer(tsc, PWRDOWN);
>> }
>> 
>> -static u32 tsc2007_calculate_resistance(struct tsc2007 *tsc,
>> +u32 tsc2007_calculate_resistance(struct tsc2007 *tsc,
>> 					struct ts_event *tc)
>> {
>> 	u32 rt = 0;
>> @@ -158,7 +90,7 @@ static u32 tsc2007_calculate_resistance(struct
>> tsc2007 *tsc,
>> 	return rt;
>> }
>> 
>> -static bool tsc2007_is_pen_down(struct tsc2007 *ts)
>> +bool tsc2007_is_pen_down(struct tsc2007 *ts)
>> {
>> 	/*
>> 	 * NOTE: We can't rely on the pressure to determine the pen down
>> @@ -191,7 +123,10 @@ static irqreturn_t tsc2007_soft_irq(int irq, void
>> *handle)
>> 	while (!ts->stopped && tsc2007_is_pen_down(ts)) {
>> 
>> 		/* pen is down, continue with the measurement */
>> +
>> +		mutex_lock(&ts->mlock);
>> 		tsc2007_read_values(ts, &tc);
>> +		mutex_unlock(&ts->mlock);
>> 
>> 		rt = tsc2007_calculate_resistance(ts, &tc);
>> 
>> @@ -441,7 +376,8 @@ static void tsc2007_call_exit_platform_hw(void
>> *data)
>> static int tsc2007_probe(struct i2c_client *client,
>> 			 const struct i2c_device_id *id)
>> {
>> -	const struct tsc2007_platform_data *pdata =
>> dev_get_platdata(&client->dev);
>> +	const struct tsc2007_platform_data *pdata =
>> +		dev_get_platdata(&client->dev);
>> 	struct tsc2007 *ts;
>> 	struct input_dev *input_dev;
>> 	int err;
>> @@ -463,7 +399,9 @@ static int tsc2007_probe(struct i2c_client *client,
>> 	ts->client = client;
>> 	ts->irq = client->irq;
>> 	ts->input = input_dev;
>> +
>> 	init_waitqueue_head(&ts->wait);
>> +	mutex_init(&ts->mlock);
>> 
>> 	snprintf(ts->phys, sizeof(ts->phys),
>> 		 "%s/input0", dev_name(&client->dev));
>> @@ -534,7 +472,7 @@ static int tsc2007_probe(struct i2c_client *client,
>> 	if (err < 0) {
>> 		dev_err(&client->dev,
>> 			"Failed to setup chip: %d\n", err);
>> -		return err;	/* usually, chip does not respond */
>> +		return err;	/* chip does not respond */
>> 	}
>> 
>> 	err = input_register_device(input_dev);
>> @@ -544,6 +482,14 @@ static int tsc2007_probe(struct i2c_client
>> *client,
>> 		return err;
>> 	}
>> 
>> +	return tsc2007_iio_configure(ts);
>> +}
>> +
>> +static int tsc2007_remove(struct i2c_client *client)
>> +{
>> +	struct tsc2007 *ts = i2c_get_clientdata(client);
>> +
>> +	tsc2007_iio_unconfigure(ts);
>> 	return 0;
>> }
>> 
>> @@ -569,6 +515,7 @@ static struct i2c_driver tsc2007_driver = {
>> 	},
>> 	.id_table	= tsc2007_idtable,
>> 	.probe		= tsc2007_probe,
>> +	.remove		= tsc2007_remove,
>> };
>> 
>> module_i2c_driver(tsc2007_driver);
>> diff --git a/drivers/input/touchscreen/tsc2007_iio.c
>> b/drivers/input/touchscreen/tsc2007_iio.c
>> new file mode 100644
>> index 0000000..ed79944
>> --- /dev/null
>> +++ b/drivers/input/touchscreen/tsc2007_iio.c
>> @@ -0,0 +1,150 @@
>> +/*
>> + * Copyright (c) 2016 Golden Delicious Comp. GmbH&Co. KG
>> + *	Nikolaus Schaller <hns-xXXSsgcRVICgSpxsJD1C4w@public.gmane.org>
>> + *
>> + *  This program is free software; you can redistribute it and/or
>> modify
>> + *  it under the terms of the GNU General Public License version 2 as
>> + *  published by the Free Software Foundation.
>> + */
>> +
>> +#include <linux/i2c.h>
>> +#include <linux/iio/iio.h>
>> +#include "tsc2007.h"
>> +
>> +struct tsc2007_iio {
>> +	struct tsc2007 *ts;
>> +};
>> +
>> +#define TSC2007_CHAN_IIO(_chan, _name, _type, _chan_info) \
>> +{ \
>> +	.datasheet_name = _name, \
>> +	.type = _type, \
>> +	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |	\
>> +			BIT(_chan_info), \
>> +	.indexed = 1, \
>> +	.channel = _chan, \
>> +}
>> +
>> +static const struct iio_chan_spec tsc2007_iio_channel[] = {
>> +	TSC2007_CHAN_IIO(0, "x", IIO_VOLTAGE, IIO_CHAN_INFO_RAW),
>> +	TSC2007_CHAN_IIO(1, "y", IIO_VOLTAGE, IIO_CHAN_INFO_RAW),
>> +	TSC2007_CHAN_IIO(2, "z1", IIO_VOLTAGE, IIO_CHAN_INFO_RAW),
>> +	TSC2007_CHAN_IIO(3, "z2", IIO_VOLTAGE, IIO_CHAN_INFO_RAW),
>> +	TSC2007_CHAN_IIO(4, "adc", IIO_VOLTAGE, IIO_CHAN_INFO_RAW),
>> +	TSC2007_CHAN_IIO(5, "rt", IIO_VOLTAGE, IIO_CHAN_INFO_RAW), /* Ohms?
>> */
>> +	TSC2007_CHAN_IIO(6, "pen", IIO_PRESSURE, IIO_CHAN_INFO_RAW),
>> +	TSC2007_CHAN_IIO(7, "temp0", IIO_TEMP, IIO_CHAN_INFO_RAW),
>> +	TSC2007_CHAN_IIO(8, "temp1", IIO_TEMP, IIO_CHAN_INFO_RAW),
>> +};
>> +
>> +static int tsc2007_read_raw(struct iio_dev *indio_dev,
>> +	struct iio_chan_spec const *chan, int *val, int *val2, long mask)
>> +{
>> +	struct tsc2007_iio *iio = iio_priv(indio_dev);
>> +	struct tsc2007 *tsc = iio->ts;
>> +	int adc_chan = chan->channel;
>> +	int ret = 0;
>> +
>> +	if (adc_chan >= ARRAY_SIZE(tsc2007_iio_channel))
>> +		return -EINVAL;
>> +
>> +	if (mask != IIO_CHAN_INFO_RAW)
>> +		return -EINVAL;
>> +
>> +	mutex_lock(&tsc->mlock);
>> +
>> +	switch (chan->channel) {
>> +	case 0:
>> +		*val = tsc2007_xfer(tsc, READ_X);
>> +		break;
>> +	case 1:
>> +		*val = tsc2007_xfer(tsc, READ_Y);
>> +		break;
>> +	case 2:
>> +		*val = tsc2007_xfer(tsc, READ_Z1);
>> +		break;
>> +	case 3:
>> +		*val = tsc2007_xfer(tsc, READ_Z2);
>> +		break;
>> +	case 4:
>> +		*val = tsc2007_xfer(tsc, (ADC_ON_12BIT | TSC2007_MEASURE_AUX));
>> +		break;
>> +	case 5: {
>> +		struct ts_event tc;
>> +
>> +		tc.x = tsc2007_xfer(tsc, READ_X);
>> +		tc.z1 = tsc2007_xfer(tsc, READ_Z1);
>> +		tc.z2 = tsc2007_xfer(tsc, READ_Z2);
>> +		*val = tsc2007_calculate_resistance(tsc, &tc);
>> +		break;
>> +	}
>> +	case 6:
>> +		*val = tsc2007_is_pen_down(tsc);
>> +		break;
>> +	case 7:
>> +		*val = tsc2007_xfer(tsc,
>> +				    (ADC_ON_12BIT | TSC2007_MEASURE_TEMP0));
>> +		break;
>> +	case 8:
>> +		*val = tsc2007_xfer(tsc,
>> +				    (ADC_ON_12BIT | TSC2007_MEASURE_TEMP1));
>> +		break;
>> +	}
>> +
>> +	/* Prepare for next touch reading - power down ADC, enable PENIRQ */
>> +	tsc2007_xfer(tsc, PWRDOWN);
>> +
>> +	mutex_unlock(&tsc->mlock);
>> +
>> +	ret = IIO_VAL_INT;
>> +
>> +	return ret;
>> +}
>> +
>> +static const struct iio_info tsc2007_iio_info = {
>> +	.read_raw = tsc2007_read_raw,
>> +	.driver_module = THIS_MODULE,
>> +};
>> +
>> +int tsc2007_iio_configure(struct tsc2007 *ts)
>> +{
>> +	int err;
>> +	struct iio_dev *indio_dev;
>> +	struct tsc2007_iio *iio;
>> +
>> +	indio_dev = devm_iio_device_alloc(&ts->client->dev,
>> +		sizeof(struct tsc2007_iio));
>> +	if (!indio_dev) {
>> +		dev_err(&ts->client->dev, "iio_device_alloc failed\n");
>> +		return -ENOMEM;
>> +	}
>> +
>> +	iio = iio_priv(indio_dev);
>> +	iio->ts = ts;
>> +	ts->iio_dev = (void *) indio_dev;
>> +
>> +	indio_dev->name = "tsc2007";
>> +	indio_dev->dev.parent = &ts->client->dev;
>> +	indio_dev->info = &tsc2007_iio_info;
>> +	indio_dev->modes = INDIO_DIRECT_MODE;
>> +	indio_dev->channels = tsc2007_iio_channel;
>> +	indio_dev->num_channels = ARRAY_SIZE(tsc2007_iio_channel);
>> +
>> +	err = iio_device_register(indio_dev);
>> +	if (err < 0) {
>> +		dev_err(&ts->client->dev, "iio_device_register() failed: %d\n",
>> +			err);
>> +		return err;
>> +	}
>> +
>> +	return 0;
>> +}
>> +EXPORT_SYMBOL(tsc2007_iio_configure);
>> +
>> +void tsc2007_iio_unconfigure(struct tsc2007 *ts)
>> +{
>> +	struct iio_dev *indio_dev = ts->iio_dev;
>> +
>> +	iio_device_unregister(indio_dev);
>> +}
>> +EXPORT_SYMBOL(tsc2007_iio_unconfigure);
> 
> -- 
> Sent from my Android device with K-9 Mail. Please excuse my brevity.

^ permalink raw reply

* [PATCH mmc/next] mmc: sh_mmcif: Document r8a73a4, r8a7779 and sh73a0 DT bindings
From: Simon Horman @ 2016-11-24 18:17 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: linux-mmc, devicetree, Magnus Damm, linux-renesas-soc,
	Simon Horman

Simply document new compatibility strings as the driver is already
activated using a fallback compatibility string.

These compat strings are in keeping with those for all other
Renesas ARM based SoCs with sh_mmcif enabled in mainline.

Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
---
I plan to follow-up with patches to use these new compat strings
to bring the DT files of the SoCs in question in-line with those
for other Renesas ARM based SoCs with sh_mmcif enabled in mainline.
---
 Documentation/devicetree/bindings/mmc/renesas,mmcif.txt | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/Documentation/devicetree/bindings/mmc/renesas,mmcif.txt b/Documentation/devicetree/bindings/mmc/renesas,mmcif.txt
index ff611fa66871..e4ba92aa035e 100644
--- a/Documentation/devicetree/bindings/mmc/renesas,mmcif.txt
+++ b/Documentation/devicetree/bindings/mmc/renesas,mmcif.txt
@@ -8,11 +8,14 @@ Required properties:
 
 - compatible: should be "renesas,mmcif-<soctype>", "renesas,sh-mmcif" as a
   fallback. Examples with <soctype> are:
+	- "renesas,mmcif-r8a73a4" for the MMCIF found in r8a73a4 SoCs
 	- "renesas,mmcif-r8a7740" for the MMCIF found in r8a7740 SoCs
+	- "renesas,mmcif-r8a7778" for the MMCIF found in r8a7778 SoCs
 	- "renesas,mmcif-r8a7790" for the MMCIF found in r8a7790 SoCs
 	- "renesas,mmcif-r8a7791" for the MMCIF found in r8a7791 SoCs
 	- "renesas,mmcif-r8a7793" for the MMCIF found in r8a7793 SoCs
 	- "renesas,mmcif-r8a7794" for the MMCIF found in r8a7794 SoCs
+	- "renesas,mmcif-sh73a0" for the MMCIF found in sh73a0 SoCs
 
 - clocks: reference to the functional clock
 
-- 
2.7.0.rc3.207.g0ac5344

^ permalink raw reply related


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