Devicetree
 help / color / mirror / Atom feed
* Re: [PATCH v3 00/12] Initial Tegra186 support
From: Thierry Reding @ 2016-11-28  7:33 UTC (permalink / raw)
  To: Pavel Machek
  Cc: Sivaram Nair, devicetree-u79uwXL29TY76Z2rM5mHXA,
	Peter De Schrijver, Timo Alho, Joseph Lo,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <20161126133927.GE20568-5NIqAleC692hcjWhqY66xCZi+YwRKgec@public.gmane.org>

[-- Attachment #1: Type: text/plain, Size: 662 bytes --]

On Sat, Nov 26, 2016 at 02:39:27PM +0100, Pavel Machek wrote:
> Hi!
> 
> > From: Thierry Reding <treding-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
> > 
> > Hi everyone,
> > 
> > This is a set of patches to add initial support for Tegra186. It is
> > based on Joseph's patches but I rewrote some of the drivers to be a
> > little easier to comprehend and maintain (hopefully). I've also
> > included clock and reset drivers as a proof of concept.
> 
> Is there any phone/tablet on the market with this chipset?

I'm not aware of any. The chip is primarily targetted at automotive
use-cases and probably not suited for phones or tablets.

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

^ permalink raw reply

* [PATCH v2] clkdev: add devm_of_clk_get()
From: Kuninori Morimoto @ 2016-11-28  6:56 UTC (permalink / raw)
  To: Stephen Boyd, Rob Herring, Linux-ALSA, Linux-DT,
	Michael Turquette, Russell King, Linux-Kernel, Mark Brown,
	linux-clk, Linux-ARM

Current Linux has of_clk_get(), but doesn't have devm_of_clk_get().
This patch adds it. This is based on devm_clk_get()

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
v1 -> v2

 - update git log

 drivers/clk/clkdev.c | 26 ++++++++++++++++++++++++++
 include/linux/clk.h  |  7 +++++++
 2 files changed, 33 insertions(+)

diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c
index 89cc700..93a613b 100644
--- a/drivers/clk/clkdev.c
+++ b/drivers/clk/clkdev.c
@@ -55,6 +55,32 @@ struct clk *of_clk_get(struct device_node *np, int index)
 }
 EXPORT_SYMBOL(of_clk_get);
 
+static void devm_of_clk_release(struct device *dev, void *res)
+{
+	clk_put(*(struct clk **)res);
+}
+
+struct clk *devm_of_clk_get(struct device *dev,
+			    struct device_node *np, int index)
+{
+	struct clk **ptr, *clk;
+
+	ptr = devres_alloc(devm_of_clk_release, sizeof(*ptr), GFP_KERNEL);
+	if (!ptr)
+		return ERR_PTR(-ENOMEM);
+
+	clk = of_clk_get(np, index);
+	if (!IS_ERR(clk)) {
+		*ptr = clk;
+		devres_add(dev, ptr);
+	} else {
+		devres_free(ptr);
+	}
+
+	return clk;
+}
+EXPORT_SYMBOL(devm_of_clk_get);
+
 static struct clk *__of_clk_get_by_name(struct device_node *np,
 					const char *dev_id,
 					const char *name)
diff --git a/include/linux/clk.h b/include/linux/clk.h
index a89ba4e..33cd540 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -502,6 +502,8 @@ struct of_phandle_args;
 
 #if defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK)
 struct clk *of_clk_get(struct device_node *np, int index);
+struct clk *devm_of_clk_get(struct device *dev,
+			    struct device_node *np, int index);
 struct clk *of_clk_get_by_name(struct device_node *np, const char *name);
 struct clk *of_clk_get_from_provider(struct of_phandle_args *clkspec);
 #else
@@ -509,6 +511,11 @@ static inline struct clk *of_clk_get(struct device_node *np, int index)
 {
 	return ERR_PTR(-ENOENT);
 }
+static inline struct clk *devm_of_clk_get(struct device *dev,
+			    struct device_node *np, int index)
+{
+	return ERR_PTR(-ENOENT);
+}
 static inline struct clk *of_clk_get_by_name(struct device_node *np,
 					     const char *name)
 {
-- 
1.9.1


^ permalink raw reply related

* Re: [PATCH v2] ARM: dts: da850: add the mstpri and ddrctl nodes
From: Kevin Hilman @ 2016-11-28  6:16 UTC (permalink / raw)
  To: Sekhar Nori
  Cc: Mark Rutland, linux-devicetree, David Lechner, Tomi Valkeinen,
	Michael Turquette, Russell King, linux-drm, LKML, Peter Ujfalusi,
	Bartosz Golaszewski, Rob Herring, Jyri Sarha, Frank Rowand,
	arm-soc, Laurent Pinchart
In-Reply-To: <20fbc946-d56c-31a3-4ae7-cf61df96a3c3@ti.com>

On Wed, Nov 23, 2016 at 9:03 PM, Sekhar Nori <nsekhar@ti.com> wrote:
> On Thursday 24 November 2016 04:18 AM, David Lechner wrote:
>> On 11/23/2016 04:32 PM, Kevin Hilman wrote:
>>> David Lechner <david@lechnology.com> writes:
>>>
>>>> On 11/23/2016 04:27 AM, Bartosz Golaszewski wrote:
>>>>> 2016-11-22 23:23 GMT+01:00 David Lechner <david@lechnology.com>:
>>>>>> On 11/15/2016 05:00 AM, Bartosz Golaszewski wrote:
>>>>>>>
>>>>>>> Add the nodes for the MSTPRI configuration and DDR2/mDDR memory
>>>>>>> controller drivers to da850.dtsi.
>>>>>>>
>>>>>>> Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
>>>>>>> ---
>>>>>>> v1 -> v2:
>>>>>>> - moved the priority controller node above the cfgchip node
>>>>>>> - renamed added nodes to better reflect their purpose
>>>>>>>
>>>>>>>  arch/arm/boot/dts/da850.dtsi | 8 ++++++++
>>>>>>>  1 file changed, 8 insertions(+)
>>>>>>>
>>>>>>> diff --git a/arch/arm/boot/dts/da850.dtsi
>>>>>>> b/arch/arm/boot/dts/da850.dtsi
>>>>>>> index 1bb1f6d..412eec6 100644
>>>>>>> --- a/arch/arm/boot/dts/da850.dtsi
>>>>>>> +++ b/arch/arm/boot/dts/da850.dtsi
>>>>>>> @@ -210,6 +210,10 @@
>>>>>>>                         };
>>>>>>>
>>>>>>>                 };
>>>>>>> +               prictrl: priority-controller@14110 {
>>>>>>> +                       compatible = "ti,da850-mstpri";
>>>>>>> +                       reg = <0x14110 0x0c>;
>>>>>>
>>>>>>
>>>>>> I think we should add status = "disabled"; here and let boards opt in.
>>>>>>
>>>>>>> +               };
>>>>>>>                 cfgchip: chip-controller@1417c {
>>>>>>>                         compatible = "ti,da830-cfgchip", "syscon",
>>>>>>> "simple-mfd";
>>>>>>>                         reg = <0x1417c 0x14>;
>>>>>>> @@ -451,4 +455,8 @@
>>>>>>>                           1 0 0x68000000 0x00008000>;
>>>>>>>                 status = "disabled";
>>>>>>>         };
>>>>>>> +       memctrl: memory-controller@b0000000 {
>>>>>>> +               compatible = "ti,da850-ddr-controller";
>>>>>>> +               reg = <0xb0000000 0xe8>;
>>>>>>
>>>>>>
>>>>>> same here. status = "disabled";
>>>>>>
>>>>>>> +       };
>>>>>>>  };
>>>>>>>
>>>>>
>>>>> Hi David,
>>>>>
>>>>> I did that initially[1][2] and it was rejected by Kevin[3] and
>>>>> Laurent[4].
>>>>>
>>>>> FYI this patch has already been queued by Sekhar.
>>>>
>>>> Thanks. I did not see those threads.
>>>>
>>>> FYI to maintainers, having these enabled by default causes error
>>>> messages in the kernel log for other boards that are not supported by
>>>> the drivers.
>>>
>>> Then the driver is too noisy and should be cleaned up.
>>>
>>>> Since there is only one board that is supported and soon
>>>> to be 2 that are not, I would rather have this disabled by default to
>>>> avoid the error messages.
>>>
>>> IMO, what exactly are the error messages? Sounds like the driver is
>>> being too verbose, and calling things errors that are not really errors.
>>
>> It is just one line per driver.
>>
>>     dev_err(dev, "no master priorities defined for this board\n");
>>
>> and
>>
>>     dev_err(dev, "no settings defined for this board\n");
>>
>>
>> Since "ti,da850-lcdk" is the only board supported in these drivers, all
>> other boards will see these error messages.
>
> Thats pretty bad. Sorry about that. The original justification for
> keeping them enabled all the time was that they are in-SoC modules with
> no external dependencies (like IO lines or voltage rails) so they can be
> enabled on all boards that use DA850. While that remains true, the
> configuration itself is board specific.
>
> I think the error messages are still useful, so instead of silencing
> them, I think we should go back to keeping these nodes disabled by
> default and enabling only on boards which have support for it in the driver.

I don't have a strong preference for the enabled/disabled by default,
but I think the error messages are not error messages.  It seems
perfectly reasonable for boards to accept the reset (or bootloader)
configuration of these registers, and not consider that an error.

Kevin
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply

* RE: BALANCE PAYMENT
From: coral-Yvmzju5463hBWQWeTLFoew @ 2016-11-28  6:03 UTC (permalink / raw)


Dear Sir/s,

Please see attached.


Thanks and regards,

Accounts Department
Al Omraniya Trading Co. LLC
P.O. Box: 10757, Al Khabaisi Area,
Deira 2, Dubai, U.A.E.
Tel: +971 4 268 2730 / Fax: +971 4 268 4117

--
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: BALANCE PAYMENT
From: coral-Yvmzju5463hBWQWeTLFoew @ 2016-11-28  6:03 UTC (permalink / raw)


Dear Sir/s,

Please see attached.


Thanks and regards,

Accounts Department
Al Omraniya Trading Co. LLC
P.O. Box: 10757, Al Khabaisi Area,
Deira 2, Dubai, U.A.E.
Tel: +971 4 268 2730 / Fax: +971 4 268 4117

--
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] ARM: dts: da850: enable the memctrl and mstpri nodes per board
From: Sekhar Nori @ 2016-11-28  5:30 UTC (permalink / raw)
  To: Bartosz Golaszewski, Kevin Hilman, Michael Turquette, Rob Herring,
	Frank Rowand, Mark Rutland, Peter Ujfalusi, Russell King
  Cc: LKML, arm-soc, linux-drm, linux-devicetree, Jyri Sarha,
	Tomi Valkeinen, David Airlie, Laurent Pinchart, Robin Murphy,
	Sudeep Holla
In-Reply-To: <1479979884-9624-1-git-send-email-bgolaszewski-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>

On Thursday 24 November 2016 03:01 PM, Bartosz Golaszewski wrote:
> Currently the memory controller and master priorities drivers are
> enabled in da850.dtsi. For boards for which there are no settings
> defined, this makes these drivers emit error messages.
> 
> Disable the nodes in da850.dtsi and only enable them for da850-lcdk -
> the only board that currently needs them.
> 
> Signed-off-by: Bartosz Golaszewski <bgolaszewski-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>

Applied to v4.10/dt

Thanks,
Sekhar
--
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] ARM: dts: da850-lcdk: Add ethernet0 alias to DT
From: Sekhar Nori @ 2016-11-28  5:26 UTC (permalink / raw)
  To: Fabien Parent, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA
  Cc: khilman-rdvid1DuHRBWk0Htik3J/w, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	mark.rutland-5wv7dgnIgG8
In-Reply-To: <20161124143545.12817-1-fparent-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>

On Thursday 24 November 2016 08:05 PM, Fabien Parent wrote:
> In order to avoid Linux generating a random mac address on every boot,
> add an ethernet0 alias that will allow u-boot to patch the dtb with
> the MAC address programmed into the EEPROM.
> 
> Signed-off-by: Fabien Parent <fparent-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>

Applied to v4.10/dt. Thanks!

Regards,
Sekhar
--
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] ARM: dts: da850: specify the maximum bandwidth for tilcdc
From: Sekhar Nori @ 2016-11-28  5:24 UTC (permalink / raw)
  To: Bartosz Golaszewski, Kevin Hilman, Michael Turquette, Rob Herring,
	Frank Rowand, Mark Rutland, Peter Ujfalusi, Russell King
  Cc: LKML, arm-soc, linux-drm, linux-devicetree, Jyri Sarha,
	Tomi Valkeinen, David Airlie, Laurent Pinchart
In-Reply-To: <1480088245-8368-1-git-send-email-bgolaszewski-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>

On Friday 25 November 2016 09:07 PM, Bartosz Golaszewski wrote:
> It has been determined that the maximum resolution supported correctly
> by tilcdc rev1 on da850 SoCs is 800x600@60. Due to memory throughput
> constraints we must filter out higher modes.
> 
> Specify the max-bandwidth property for the display node for
> da850-based boards.
> 
> Signed-off-by: Bartosz Golaszewski <bgolaszewski-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
> ---
>  arch/arm/boot/dts/da850.dtsi | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/arch/arm/boot/dts/da850.dtsi b/arch/arm/boot/dts/da850.dtsi
> index 8e30d9b..9b7c444 100644
> --- a/arch/arm/boot/dts/da850.dtsi
> +++ b/arch/arm/boot/dts/da850.dtsi
> @@ -452,6 +452,7 @@
>  			compatible = "ti,da850-tilcdc";
>  			reg = <0x213000 0x1000>;
>  			interrupts = <52>;
> +			max-bandwidth = <28800000>;

If this is effectively the max pixel clock that the device supports,
then why not use the datasheet specified value of 37.5 MHz (Tc = 26.66 ns).

Thanks,
Sekhar

--
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 2/2] input: touchscreen: sample averaging for imx6ul_tsc
From: Dmitry Torokhov @ 2016-11-28  4:46 UTC (permalink / raw)
  To: Fabio Estevam
  Cc: Guy Shapiro, Fabio Estevam, Mark Rutland,
	devicetree@vger.kernel.org, Haibo Chen, robh+dt@kernel.org,
	linux-input, linux-arm-kernel@lists.infradead.org
In-Reply-To: <CAOMZO5CCtLdH9_5vGXfqg1rAizngVc_EWaoE+JfcfTrMmJT4xA@mail.gmail.com>

On Sun, Nov 27, 2016 at 10:39:10AM -0200, Fabio Estevam wrote:
> On Sun, Nov 27, 2016 at 5:44 AM, Guy Shapiro <guy.shapiro@mobi-wize.com> wrote:
> > The i.MX6UL internal touchscreen controller contains an option to
> > average upon samples. This feature reduces noise from the produced
> > touch locations.
> >
> > This patch adds sample averaging support to the imx6ul_tsc device
> > driver.
> >
> > Signed-off-by: Guy Shapiro <guy.shapiro@mobi-wize.com>
> 
> Reviewed-by: Fabio Estevam <fabio.estevam@nxp.com>

Folded the binding patch into this one and applied, thank you.

-- 
Dmitry

^ permalink raw reply

* Re: [PATCH v5 14/14] ASoC: add simple-graph-scu-card support
From: kbuild test robot @ 2016-11-28  4:36 UTC (permalink / raw)
  To: Kuninori Morimoto
  Cc: kbuild-all-JC7UmRfGjtg, Rob Herring, Mark Brown, Linux-ALSA,
	Liam Girdwood, Simon, Laurent, Guennadi, Grant Likely,
	Frank Rowand, Linux-DT, Linux-Kernel
In-Reply-To: <87zikkuxps.wl%kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>

[-- Attachment #1: Type: text/plain, Size: 3566 bytes --]

Hi Kuninori,

[auto build test ERROR on robh/for-next]
[also build test ERROR on v4.9-rc7]
[cannot apply to glikely/devicetree/next asoc/for-next next-20161125]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Kuninori-Morimoto/ASoC-add-OF-graph-base-simple-card/20161128-111639
base:   https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
config: i386-allmodconfig (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

All errors (new ones prefixed by >>):

   sound/soc/generic/simple-graph-scu-card.c: In function 'asoc_simple_card_dai_link_of':
>> sound/soc/generic/simple-graph-scu-card.c:167:3: error: implicit declaration of function 'snd_soc_of_parse_audio_prefix_from_node' [-Werror=implicit-function-declaration]
      snd_soc_of_parse_audio_prefix_from_node(&priv->snd_card,
      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   sound/soc/generic/simple-graph-scu-card.c: In function 'asoc_simple_card_parse_of':
>> sound/soc/generic/simple-graph-scu-card.c:214:8: error: implicit declaration of function 'snd_soc_of_parse_audio_routing_from_node' [-Werror=implicit-function-declaration]
     ret = snd_soc_of_parse_audio_routing_from_node(&priv->snd_card,
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   cc1: some warnings being treated as errors

vim +/snd_soc_of_parse_audio_prefix_from_node +167 sound/soc/generic/simple-graph-scu-card.c

   161			ret = asoc_simple_card_set_dailink_name(dev, dai_link,
   162								"be.%s",
   163								dai_link->codec_dai_name);
   164			if (ret < 0)
   165				return ret;
   166	
 > 167			snd_soc_of_parse_audio_prefix_from_node(&priv->snd_card,
   168								port->parent,
   169								&priv->codec_conf,
   170								dai_link->codec_of_node,
   171								PREFIX "prefix");
   172		}
   173	
   174		ret = snd_soc_of_parse_tdm_slot(ep,
   175						&dai_props->tx_slot_mask,
   176						&dai_props->rx_slot_mask,
   177						&dai_props->slots,
   178						&dai_props->slot_width);
   179		if (ret)
   180			return ret;
   181	
   182		ret = asoc_simple_card_canonicalize_dailink(dai_link);
   183		if (ret < 0)
   184			return ret;
   185	
   186		dai_link->dai_fmt		= daifmt;
   187		dai_link->dpcm_playback		= 1;
   188		dai_link->dpcm_capture		= 1;
   189		dai_link->ops			= &asoc_simple_card_ops;
   190		dai_link->init			= asoc_simple_card_dai_init;
   191	
   192		dev_dbg(dev, "\t%s / %04x / %d\n",
   193			dai_link->name,
   194			dai_link->dai_fmt,
   195			dai_props->sysclk);
   196	
   197		return 0;
   198	}
   199	
   200	static int asoc_simple_card_parse_of(struct device_node *node,
   201					     struct simple_card_data *priv)
   202	{
   203		struct device *dev = simple_priv_to_dev(priv);
   204		struct device *cpu_dev = dev->parent;
   205		struct device_node *ports = of_graph_get_top_port(cpu_dev);
   206		struct snd_soc_card *card = &priv->snd_card;
   207		struct device_node *port, *cpu_ep, *r_cpu_ep, *codec_ep;
   208		unsigned int daifmt = 0;
   209		int i, ret, done;
   210	
   211		if (!node)
   212			return -EINVAL;
   213	
 > 214		ret = snd_soc_of_parse_audio_routing_from_node(&priv->snd_card,
   215							       ports, PREFIX "routing");
   216		if (ret)
   217			return ret;

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 56833 bytes --]

^ permalink raw reply

* Re: [PATCH v5 12/14] ASoC: add simple-graph-card support
From: kbuild test robot @ 2016-11-28  4:19 UTC (permalink / raw)
  To: Kuninori Morimoto
  Cc: kbuild-all-JC7UmRfGjtg, Rob Herring, Mark Brown, Linux-ALSA,
	Liam Girdwood, Simon, Laurent, Guennadi, Grant Likely,
	Frank Rowand, Linux-DT, Linux-Kernel
In-Reply-To: <8737icwcbd.wl%kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>

[-- Attachment #1: Type: text/plain, Size: 2293 bytes --]

Hi Kuninori,

[auto build test ERROR on robh/for-next]
[also build test ERROR on v4.9-rc7]
[cannot apply to glikely/devicetree/next asoc/for-next next-20161125]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Kuninori-Morimoto/ASoC-add-OF-graph-base-simple-card/20161128-111639
base:   https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
config: i386-allmodconfig (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

All errors (new ones prefixed by >>):

   sound/soc/generic/simple-graph-card.c: In function 'asoc_simple_card_parse_of':
>> sound/soc/generic/simple-graph-card.c:331:10: error: implicit declaration of function 'snd_soc_of_parse_audio_simple_widgets_from_node' [-Werror=implicit-function-declaration]
       ret = snd_soc_of_parse_audio_simple_widgets_from_node(
             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> sound/soc/generic/simple-graph-card.c:340:10: error: implicit declaration of function 'snd_soc_of_parse_audio_routing_from_node' [-Werror=implicit-function-declaration]
       ret = snd_soc_of_parse_audio_routing_from_node(
             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   cc1: some warnings being treated as errors

vim +/snd_soc_of_parse_audio_simple_widgets_from_node +331 sound/soc/generic/simple-graph-card.c

   325		for_each_of_port(node, port) {
   326			if (!of_graph_port_type_is_sound(port))
   327				continue;
   328	
   329			/* The off-codec widgets */
   330			if (of_property_read_bool(port, PREFIX "widgets")) {
 > 331				ret = snd_soc_of_parse_audio_simple_widgets_from_node(
   332					&priv->snd_card,
   333					port, PREFIX "widgets");
   334				if (ret)
   335					return ret;
   336			}
   337	
   338			/* DAPM routes */
   339			if (of_property_read_bool(port, PREFIX "routing")) {
 > 340				ret = snd_soc_of_parse_audio_routing_from_node(
   341					&priv->snd_card,
   342					port, PREFIX "routing");
   343				if (ret)

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 56831 bytes --]

^ permalink raw reply

* Re: [PATCH v10 3/4] dtc: Plugin and fixup support
From: David Gibson @ 2016-11-28  4:12 UTC (permalink / raw)
  To: Pantelis Antoniou
  Cc: Jon Loeliger, Grant Likely, Frank Rowand, Rob Herring, Jan Luebbe,
	Sascha Hauer, Phil Elwell, Simon Glass, Maxime Ripard,
	Thomas Petazzoni, Boris Brezillon, Antoine Tenart, Stephen Boyd,
	Devicetree Compiler, devicetree-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1480077131-14526-4-git-send-email-pantelis.antoniou-OWPKS81ov/FWk0Htik3J/w@public.gmane.org>

[-- Attachment #1: Type: text/plain, Size: 28762 bytes --]

On Fri, Nov 25, 2016 at 02:32:10PM +0200, Pantelis Antoniou wrote:
> This patch enable the generation of symbols & local fixup information
> for trees compiled with the -@ (--symbols) option.
> 
> Using this patch labels in the tree and their users emit information
> in __symbols__ and __local_fixups__ nodes.
> 
> The __fixups__ node make possible the dynamic resolution of phandle
> references which are present in the plugin tree but lie in the
> tree that are applying the overlay against.
> 
> While there is a new magic number for dynamic device tree/overlays blobs
> it is by default enabled. Remember to use -M to generate compatible
> blobs.
> 
> Signed-off-by: Pantelis Antoniou <pantelis.antoniou-OWPKS81ov/FWk0Htik3J/w@public.gmane.org>
> Signed-off-by: Sascha Hauer <s.hauer-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
> Signed-off-by: Jan Luebbe <jlu-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
> ---
>  Documentation/manual.txt |  25 +++++-
>  checks.c                 |   8 +-
>  dtc-lexer.l              |   5 ++
>  dtc-parser.y             |  50 +++++++++--
>  dtc.c                    |  39 +++++++-
>  dtc.h                    |  20 ++++-
>  fdtdump.c                |   2 +-
>  flattree.c               |  17 ++--
>  fstree.c                 |   2 +-
>  libfdt/fdt.c             |   2 +-
>  libfdt/fdt.h             |   3 +-
>  livetree.c               | 225 ++++++++++++++++++++++++++++++++++++++++++++++-
>  tests/mangle-layout.c    |   7 +-
>  13 files changed, 375 insertions(+), 30 deletions(-)
> 
> diff --git a/Documentation/manual.txt b/Documentation/manual.txt
> index 398de32..094893b 100644
> --- a/Documentation/manual.txt
> +++ b/Documentation/manual.txt
> @@ -119,6 +119,24 @@ Options:
>  	Make space for <number> reserve map entries
>  	Relevant for dtb and asm output only.
>  
> +    -@
> +	Generates a __symbols__ node at the root node of the resulting blob
> +	for any node labels used, and for any local references using phandles
> +	it also generates a __local_fixups__ node that tracks them.
> +
> +	When using the /plugin/ tag all unresolved label references to
> +	be tracked in the __fixups__ node, making dynamic resolution possible.
> +
> +    -A
> +	Generate automatically aliases for all node labels. This is similar to
> +	the -@ option (the __symbols__ node contain identical information) but
> +	the semantics are slightly different since no phandles are automatically
> +	generated for labeled nodes.
> +
> +    -M
> +	Generate blobs with the old FDT magic number for device tree objects.
> +	By default blobs use the DTBO FDT magic number instead.
> +
>      -S <bytes>
>  	Ensure the blob at least <bytes> long, adding additional
>  	space if needed.
> @@ -146,13 +164,18 @@ Additionally, dtc performs various sanity checks on the tree.
>  Here is a very rough overview of the layout of a DTS source file:
>  
>  
> -    sourcefile:   list_of_memreserve devicetree
> +    sourcefile:   versioninfo plugindecl list_of_memreserve devicetree
>  
>      memreserve:   label 'memreserve' ADDR ADDR ';'
>  		| label 'memreserve' ADDR '-' ADDR ';'
>  
>      devicetree:   '/' nodedef
>  
> +    versioninfo:  '/' 'dts-v1' '/' ';'
> +
> +    plugindecl:   '/' 'plugin' '/' ';'
> +                | /* empty */
> +
>      nodedef:      '{' list_of_property list_of_subnode '}' ';'
>  
>      property:     label PROPNAME '=' propdata ';'
> diff --git a/checks.c b/checks.c
> index 2bd27a4..4292f4b 100644
> --- a/checks.c
> +++ b/checks.c
> @@ -487,8 +487,12 @@ static void fixup_phandle_references(struct check *c, struct boot_info *bi,
>  
>  			refnode = get_node_by_ref(dt, m->ref);
>  			if (! refnode) {
> -				FAIL(c, "Reference to non-existent node or label \"%s\"\n",
> -				     m->ref);
> +				if (!(bi->versionflags & VF_PLUGIN))
> +					FAIL(c, "Reference to non-existent node or "
> +							"label \"%s\"\n", m->ref);
> +				else /* mark the entry as unresolved */
> +					*((cell_t *)(prop->val.val + m->offset)) =
> +						cpu_to_fdt32(0xffffffff);
>  				continue;
>  			}
>  
> diff --git a/dtc-lexer.l b/dtc-lexer.l
> index 790fbf6..40bbc87 100644
> --- a/dtc-lexer.l
> +++ b/dtc-lexer.l
> @@ -121,6 +121,11 @@ static void lexical_error(const char *fmt, ...);
>  			return DT_V1;
>  		}
>  
> +<*>"/plugin/"	{
> +			DPRINT("Keyword: /plugin/\n");
> +			return DT_PLUGIN;
> +		}
> +
>  <*>"/memreserve/"	{
>  			DPRINT("Keyword: /memreserve/\n");
>  			BEGIN_DEFAULT();
> diff --git a/dtc-parser.y b/dtc-parser.y
> index 14aaf2e..1a1f660 100644
> --- a/dtc-parser.y
> +++ b/dtc-parser.y
> @@ -19,6 +19,7 @@
>   */
>  %{
>  #include <stdio.h>
> +#include <inttypes.h>
>  
>  #include "dtc.h"
>  #include "srcpos.h"
> @@ -33,6 +34,7 @@ extern void yyerror(char const *s);
>  
>  extern struct boot_info *the_boot_info;
>  extern bool treesource_error;
> +

Extraneous whitespace change here

>  %}
>  
>  %union {
> @@ -52,9 +54,11 @@ extern bool treesource_error;
>  	struct node *nodelist;
>  	struct reserve_info *re;
>  	uint64_t integer;
> +	unsigned int flags;
>  }
>  
>  %token DT_V1
> +%token DT_PLUGIN
>  %token DT_MEMRESERVE
>  %token DT_LSHIFT DT_RSHIFT DT_LE DT_GE DT_EQ DT_NE DT_AND DT_OR
>  %token DT_BITS
> @@ -71,6 +75,8 @@ extern bool treesource_error;
>  
>  %type <data> propdata
>  %type <data> propdataprefix
> +%type <flags> versioninfo
> +%type <flags> plugindecl
>  %type <re> memreserve
>  %type <re> memreserves
>  %type <array> arrayprefix
> @@ -101,16 +107,34 @@ extern bool treesource_error;
>  %%
>  
>  sourcefile:
> -	  v1tag memreserves devicetree
> +	  versioninfo plugindecl memreserves devicetree
> +		{
> +			the_boot_info = build_boot_info($1 | $2, $3, $4,
> +							guess_boot_cpuid($4));
> +		}
> +	;
> +
> +versioninfo:
> +	v1tag
>  		{
> -			the_boot_info = build_boot_info($2, $3,
> -							guess_boot_cpuid($3));
> +			$$ = VF_DT_V1;
>  		}
>  	;
>  
>  v1tag:
>  	  DT_V1 ';'
> +	| DT_V1
>  	| DT_V1 ';' v1tag
> +
> +plugindecl:
> +	DT_PLUGIN ';'
> +		{
> +			$$ = VF_PLUGIN;
> +		}
> +	| /* empty */
> +		{
> +			$$ = 0;
> +		}
>  	;
>  
>  memreserves:
> @@ -161,10 +185,19 @@ devicetree:
>  		{
>  			struct node *target = get_node_by_ref($1, $2);
>  
> -			if (target)
> +			if (target) {
>  				merge_nodes(target, $3);
> -			else
> -				ERROR(&@2, "Label or path %s not found", $2);
> +			} else {
> +				/*
> +				 * We rely on the rule being always:
> +				 *   versioninfo plugindecl memreserves devicetree
> +				 * so $-1 is what we want (plugindecl)
> +				 */
> +				if ($<flags>-1 & VF_PLUGIN)

o_O... ok.  I've never seen negative value references before.  Can you
provide a link to some documentation saying this is actually supported
usage in bison?  I wasn't able to find it when I looked.

> +					add_orphan_node($1, $3, $2);
> +				else
> +					ERROR(&@2, "Label or path %s not found", $2);
> +			}
>  			$$ = $1;
>  		}
>  	| devicetree DT_DEL_NODE DT_REF ';'
> @@ -179,6 +212,11 @@ devicetree:
>  
>  			$$ = $1;
>  		}
> +	| /* empty */
> +		{
> +			/* build empty node */
> +			$$ = name_node(build_node(NULL, NULL), "");
> +		}
>  	;
>  
>  nodedef:
> diff --git a/dtc.c b/dtc.c
> index 9dcf640..06e91bc 100644
> --- a/dtc.c
> +++ b/dtc.c
> @@ -32,6 +32,9 @@ int minsize;		/* Minimum blob size */
>  int padsize;		/* Additional padding to blob */
>  int alignsize;		/* Additional padding to blob accroding to the alignsize */
>  int phandle_format = PHANDLE_BOTH;	/* Use linux,phandle or phandle properties */
> +int symbol_fixup_support;	/* enable symbols & fixup support */
> +int auto_label_aliases;		/* auto generate labels -> aliases */
> +int no_dtbo_magic;		/* use old FDT magic values for objects */
>  
>  static int is_power_of_2(int x)
>  {
> @@ -59,7 +62,7 @@ static void fill_fullpaths(struct node *tree, const char *prefix)
>  #define FDT_VERSION(version)	_FDT_VERSION(version)
>  #define _FDT_VERSION(version)	#version
>  static const char usage_synopsis[] = "dtc [options] <input file>";
> -static const char usage_short_opts[] = "qI:O:o:V:d:R:S:p:a:fb:i:H:sW:E:hv";
> +static const char usage_short_opts[] = "qI:O:o:V:d:R:S:p:a:fb:i:H:sW:E:@AMhv";
>  static struct option const usage_long_opts[] = {
>  	{"quiet",            no_argument, NULL, 'q'},
>  	{"in-format",         a_argument, NULL, 'I'},
> @@ -78,6 +81,9 @@ static struct option const usage_long_opts[] = {
>  	{"phandle",           a_argument, NULL, 'H'},
>  	{"warning",           a_argument, NULL, 'W'},
>  	{"error",             a_argument, NULL, 'E'},
> +	{"symbols",	     no_argument, NULL, '@'},
> +	{"auto-alias",       no_argument, NULL, 'A'},
> +	{"no-dtbo-magic",    no_argument, NULL, 'M'},
>  	{"help",             no_argument, NULL, 'h'},
>  	{"version",          no_argument, NULL, 'v'},
>  	{NULL,               no_argument, NULL, 0x0},
> @@ -109,6 +115,9 @@ static const char * const usage_opts_help[] = {
>  	 "\t\tboth   - Both \"linux,phandle\" and \"phandle\" properties",
>  	"\n\tEnable/disable warnings (prefix with \"no-\")",
>  	"\n\tEnable/disable errors (prefix with \"no-\")",
> +	"\n\tEnable symbols/fixup support",
> +	"\n\tEnable auto-alias of labels",
> +	"\n\tDo not use DTBO magic value for plugin objects",
>  	"\n\tPrint this help and exit",
>  	"\n\tPrint version and exit",
>  	NULL,
> @@ -153,7 +162,7 @@ static const char *guess_input_format(const char *fname, const char *fallback)
>  	fclose(f);
>  
>  	magic = fdt32_to_cpu(magic);
> -	if (magic == FDT_MAGIC)
> +	if (magic == FDT_MAGIC || magic == FDT_MAGIC_DTBO)
>  		return "dtb";
>  
>  	return guess_type_by_name(fname, fallback);
> @@ -172,6 +181,7 @@ int main(int argc, char *argv[])
>  	FILE *outf = NULL;
>  	int outversion = DEFAULT_FDT_VERSION;
>  	long long cmdline_boot_cpuid = -1;
> +	fdt32_t out_magic = FDT_MAGIC;
>  
>  	quiet      = 0;
>  	reservenum = 0;
> @@ -249,6 +259,16 @@ int main(int argc, char *argv[])
>  			parse_checks_option(false, true, optarg);
>  			break;
>  
> +		case '@':
> +			symbol_fixup_support = 1;
> +			break;
> +		case 'A':
> +			auto_label_aliases = 1;
> +			break;
> +		case 'M':
> +			no_dtbo_magic = 1;
> +			break;
> +
>  		case 'h':
>  			usage(NULL);
>  		default:
> @@ -306,6 +326,14 @@ int main(int argc, char *argv[])
>  	fill_fullpaths(bi->dt, "");
>  	process_checks(force, bi);
>  
> +	if (auto_label_aliases)
> +		generate_label_tree(bi->dt, "aliases", false);
> +
> +	if (symbol_fixup_support) {
> +		generate_label_tree(bi->dt, "__symbols__", true);
> +		generate_fixups_tree(bi->dt);

Hang on.. this doesn't seem right.  I thought -@ controlled the
__symbols__ side (i.e. the part upon which we overlay) rather than the
fixups side (the part which overlays).  A dtbo could certainly have
both, of course, but for base trees, wouldn't you have symbols without
fixups?  And should it be illegal to try to build a /plugin/ without
-@?

> +	}
> +
>  	if (sort)
>  		sort_tree(bi);
>  
> @@ -318,12 +346,15 @@ int main(int argc, char *argv[])
>  			    outname, strerror(errno));
>  	}
>  
> +	if (!no_dtbo_magic && (bi->versionflags & VF_PLUGIN))
> +		out_magic = FDT_MAGIC_DTBO;
> +
>  	if (streq(outform, "dts")) {
>  		dt_to_source(outf, bi);
>  	} else if (streq(outform, "dtb")) {
> -		dt_to_blob(outf, bi, outversion);
> +		dt_to_blob(outf, bi, out_magic, outversion);
>  	} else if (streq(outform, "asm")) {
> -		dt_to_asm(outf, bi, outversion);
> +		dt_to_asm(outf, bi, out_magic, outversion);
>  	} else if (streq(outform, "null")) {
>  		/* do nothing */
>  	} else {
> diff --git a/dtc.h b/dtc.h
> index 32009bc..581b3bf 100644
> --- a/dtc.h
> +++ b/dtc.h
> @@ -55,6 +55,9 @@ extern int minsize;		/* Minimum blob size */
>  extern int padsize;		/* Additional padding to blob */
>  extern int alignsize;		/* Additional padding to blob accroding to the alignsize */
>  extern int phandle_format;	/* Use linux,phandle or phandle properties */
> +extern int symbol_fixup_support;/* enable symbols & fixup support */
> +extern int auto_label_aliases;	/* auto generate labels -> aliases */
> +extern int no_dtbo_magic;	/* use old FDT magic values for objects */
>  
>  #define PHANDLE_LEGACY	0x1
>  #define PHANDLE_EPAPR	0x2
> @@ -195,6 +198,7 @@ struct node *build_node_delete(void);
>  struct node *name_node(struct node *node, char *name);
>  struct node *chain_node(struct node *first, struct node *list);
>  struct node *merge_nodes(struct node *old_node, struct node *new_node);
> +void add_orphan_node(struct node *old_node, struct node *new_node, char *ref);
>  
>  void add_property(struct node *node, struct property *prop);
>  void delete_property_by_name(struct node *node, char *name);
> @@ -202,6 +206,8 @@ void delete_property(struct property *prop);
>  void add_child(struct node *parent, struct node *child);
>  void delete_node_by_name(struct node *parent, char *name);
>  void delete_node(struct node *node);
> +void append_to_property(struct node *node,
> +			char *name, const void *data, int len);
>  
>  const char *get_unitname(struct node *node);
>  struct property *get_property(struct node *node, const char *propname);
> @@ -237,14 +243,22 @@ struct reserve_info *add_reserve_entry(struct reserve_info *list,
>  
>  
>  struct boot_info {
> +	unsigned int versionflags;
>  	struct reserve_info *reservelist;
>  	struct node *dt;		/* the device tree */
>  	uint32_t boot_cpuid_phys;
>  };
>  
> -struct boot_info *build_boot_info(struct reserve_info *reservelist,
> +/* version flags definitions */
> +#define VF_DT_V1	0x0001	/* /dts-v1/ */
> +#define VF_PLUGIN	0x0002	/* /plugin/ */
> +
> +struct boot_info *build_boot_info(unsigned int versionflags,
> +				  struct reserve_info *reservelist,
>  				  struct node *tree, uint32_t boot_cpuid_phys);
>  void sort_tree(struct boot_info *bi);
> +void generate_label_tree(struct node *dt, char *gen_node_name, bool allocph);
> +void generate_fixups_tree(struct node *dt);
>  
>  /* Checks */
>  
> @@ -253,8 +267,8 @@ void process_checks(bool force, struct boot_info *bi);
>  
>  /* Flattened trees */
>  
> -void dt_to_blob(FILE *f, struct boot_info *bi, int version);
> -void dt_to_asm(FILE *f, struct boot_info *bi, int version);
> +void dt_to_blob(FILE *f, struct boot_info *bi, fdt32_t magic, int version);
> +void dt_to_asm(FILE *f, struct boot_info *bi, fdt32_t magic, int version);
>  
>  struct boot_info *dt_from_blob(const char *fname);
>  
> diff --git a/fdtdump.c b/fdtdump.c
> index a9a2484..dd63ac2 100644
> --- a/fdtdump.c
> +++ b/fdtdump.c
> @@ -201,7 +201,7 @@ int main(int argc, char *argv[])
>  			p = memchr(p, smagic[0], endp - p - FDT_MAGIC_SIZE);
>  			if (!p)
>  				break;
> -			if (fdt_magic(p) == FDT_MAGIC) {
> +			if (fdt_magic(p) == FDT_MAGIC || fdt_magic(p) == FDT_MAGIC_DTBO) {
>  				/* try and validate the main struct */
>  				off_t this_len = endp - p;
>  				fdt32_t max_version = 17;
> diff --git a/flattree.c b/flattree.c
> index a9d9520..57d76cf 100644
> --- a/flattree.c
> +++ b/flattree.c
> @@ -335,6 +335,7 @@ static struct data flatten_reserve_list(struct reserve_info *reservelist,
>  }
>  
>  static void make_fdt_header(struct fdt_header *fdt,
> +			    fdt32_t magic,
>  			    struct version_info *vi,
>  			    int reservesize, int dtsize, int strsize,
>  			    int boot_cpuid_phys)
> @@ -345,7 +346,7 @@ static void make_fdt_header(struct fdt_header *fdt,
>  
>  	memset(fdt, 0xff, sizeof(*fdt));
>  
> -	fdt->magic = cpu_to_fdt32(FDT_MAGIC);
> +	fdt->magic = cpu_to_fdt32(magic);
>  	fdt->version = cpu_to_fdt32(vi->version);
>  	fdt->last_comp_version = cpu_to_fdt32(vi->last_comp_version);
>  
> @@ -366,7 +367,7 @@ static void make_fdt_header(struct fdt_header *fdt,
>  		fdt->size_dt_struct = cpu_to_fdt32(dtsize);
>  }
>  
> -void dt_to_blob(FILE *f, struct boot_info *bi, int version)
> +void dt_to_blob(FILE *f, struct boot_info *bi, fdt32_t magic, int version)
>  {
>  	struct version_info *vi = NULL;
>  	int i;
> @@ -390,7 +391,7 @@ void dt_to_blob(FILE *f, struct boot_info *bi, int version)
>  	reservebuf = flatten_reserve_list(bi->reservelist, vi);
>  
>  	/* Make header */
> -	make_fdt_header(&fdt, vi, reservebuf.len, dtbuf.len, strbuf.len,
> +	make_fdt_header(&fdt, magic, vi, reservebuf.len, dtbuf.len, strbuf.len,
>  			bi->boot_cpuid_phys);
>  
>  	/*
> @@ -467,7 +468,7 @@ static void dump_stringtable_asm(FILE *f, struct data strbuf)
>  	}
>  }
>  
> -void dt_to_asm(FILE *f, struct boot_info *bi, int version)
> +void dt_to_asm(FILE *f, struct boot_info *bi, fdt32_t magic, int version)
>  {
>  	struct version_info *vi = NULL;
>  	int i;
> @@ -830,6 +831,7 @@ struct boot_info *dt_from_blob(const char *fname)
>  	struct node *tree;
>  	uint32_t val;
>  	int flags = 0;
> +	unsigned int versionflags = VF_DT_V1;
>  
>  	f = srcfile_relative_open(fname, NULL);
>  
> @@ -845,9 +847,12 @@ struct boot_info *dt_from_blob(const char *fname)
>  	}
>  
>  	magic = fdt32_to_cpu(magic);
> -	if (magic != FDT_MAGIC)
> +	if (magic != FDT_MAGIC && magic != FDT_MAGIC_DTBO)
>  		die("Blob has incorrect magic number\n");
>  
> +	if (magic == FDT_MAGIC_DTBO)
> +		versionflags |= VF_PLUGIN;

Not particularly useful yet, but I wonder if we'll want some option to
force treating dtb input as a plugin, for the case of old plugins
which don't have the new magic number.

> +
>  	rc = fread(&totalsize, sizeof(totalsize), 1, f);
>  	if (ferror(f))
>  		die("Error reading DT blob size: %s\n", strerror(errno));
> @@ -942,5 +947,5 @@ struct boot_info *dt_from_blob(const char *fname)
>  
>  	fclose(f);
>  
> -	return build_boot_info(reservelist, tree, boot_cpuid_phys);
> +	return build_boot_info(versionflags, reservelist, tree, boot_cpuid_phys);
>  }
> diff --git a/fstree.c b/fstree.c
> index 6d1beec..54f520b 100644
> --- a/fstree.c
> +++ b/fstree.c
> @@ -86,6 +86,6 @@ struct boot_info *dt_from_fs(const char *dirname)
>  	tree = read_fstree(dirname);
>  	tree = name_node(tree, "");
>  
> -	return build_boot_info(NULL, tree, guess_boot_cpuid(tree));
> +	return build_boot_info(VF_DT_V1, NULL, tree, guess_boot_cpuid(tree));
>  }
>  
> diff --git a/libfdt/fdt.c b/libfdt/fdt.c
> index 22286a1..28d422c 100644
> --- a/libfdt/fdt.c
> +++ b/libfdt/fdt.c
> @@ -57,7 +57,7 @@
>  
>  int fdt_check_header(const void *fdt)
>  {
> -	if (fdt_magic(fdt) == FDT_MAGIC) {
> +	if (fdt_magic(fdt) == FDT_MAGIC || fdt_magic(fdt) == FDT_MAGIC_DTBO) {
>  		/* Complete tree */
>  		if (fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION)
>  			return -FDT_ERR_BADVERSION;
> diff --git a/libfdt/fdt.h b/libfdt/fdt.h
> index 526aedb..493cd55 100644
> --- a/libfdt/fdt.h
> +++ b/libfdt/fdt.h
> @@ -55,7 +55,7 @@
>  #ifndef __ASSEMBLY__
>  
>  struct fdt_header {
> -	fdt32_t magic;			 /* magic word FDT_MAGIC */
> +	fdt32_t magic;			 /* magic word FDT_MAGIC[|_DTBO] */
>  	fdt32_t totalsize;		 /* total size of DT block */
>  	fdt32_t off_dt_struct;		 /* offset to structure */
>  	fdt32_t off_dt_strings;		 /* offset to strings */
> @@ -93,6 +93,7 @@ struct fdt_property {
>  #endif /* !__ASSEMBLY */
>  
>  #define FDT_MAGIC	0xd00dfeed	/* 4: version, 4: total size */
> +#define FDT_MAGIC_DTBO	0xd00dfdb0	/* DTBO magic */
>  #define FDT_TAGSIZE	sizeof(fdt32_t)
>  
>  #define FDT_BEGIN_NODE	0x1		/* Start node: full name */
> diff --git a/livetree.c b/livetree.c
> index 3dc7559..f2c86bd 100644
> --- a/livetree.c
> +++ b/livetree.c
> @@ -216,6 +216,31 @@ struct node *merge_nodes(struct node *old_node, struct node *new_node)
>  	return old_node;
>  }
>  
> +void add_orphan_node(struct node *dt, struct node *new_node, char *ref)
> +{
> +	static unsigned int next_orphan_fragment = 0;
> +	struct node *node = build_node(NULL, NULL);
> +	struct property *p;
> +	struct data d = empty_data;
> +	char *name;
> +
> +	memset(node, 0, sizeof(*node));

You don't need the memset() now that you're using build_node() above.

> +
> +	d = data_add_marker(d, REF_PHANDLE, ref);
> +	d = data_append_integer(d, 0xffffffff, 32);
> +
> +	p = build_property("target", d);
> +	add_property(node, p);
> +
> +	xasprintf(&name, "fragment@%u",
> +			next_orphan_fragment++);
> +	name_node(node, name);
> +	name_node(new_node, "__overlay__");

You can do this more naturally if you do the name_node() here, then
you can just pass the __overlay__ node into build_node() for the
fragment@ node instead of having to explicitly add_child.

> +
> +	add_child(dt, node);
> +	add_child(node, new_node);
> +}
> +
>  struct node *chain_node(struct node *first, struct node *list)
>  {
>  	assert(first->next_sibling == NULL);
> @@ -296,6 +321,23 @@ void delete_node(struct node *node)
>  	delete_labels(&node->labels);
>  }
>  
> +void append_to_property(struct node *node,
> +				    char *name, const void *data, int len)
> +{
> +	struct data d;
> +	struct property *p;
> +
> +	p = get_property(node, name);
> +	if (p) {
> +		d = data_append_data(p->val, data, len);
> +		p->val = d;
> +	} else {
> +		d = data_append_data(empty_data, data, len);
> +		p = build_property(name, d);
> +		add_property(node, p);
> +	}
> +}
> +
>  struct reserve_info *build_reserve_entry(uint64_t address, uint64_t size)
>  {
>  	struct reserve_info *new = xmalloc(sizeof(*new));
> @@ -335,12 +377,14 @@ struct reserve_info *add_reserve_entry(struct reserve_info *list,
>  	return list;
>  }
>  
> -struct boot_info *build_boot_info(struct reserve_info *reservelist,
> +struct boot_info *build_boot_info(unsigned int versionflags,
> +				  struct reserve_info *reservelist,
>  				  struct node *tree, uint32_t boot_cpuid_phys)
>  {
>  	struct boot_info *bi;
>  
>  	bi = xmalloc(sizeof(*bi));
> +	bi->versionflags = versionflags;
>  	bi->reservelist = reservelist;
>  	bi->dt = tree;
>  	bi->boot_cpuid_phys = boot_cpuid_phys;
> @@ -709,3 +753,182 @@ void sort_tree(struct boot_info *bi)
>  	sort_reserve_entries(bi);
>  	sort_node(bi->dt);
>  }
> +
> +/* utility helper to avoid code duplication */
> +static struct node *build_and_name_child_node(struct node *parent, char *name)
> +{
> +	struct node *node;
> +
> +	node = build_node(NULL, NULL);
> +	name_node(node, xstrdup(name));
> +	add_child(parent, node);
> +
> +	return node;
> +}
> +
> +static void generate_label_tree_internal(struct node *dt, struct node *node,
> +					 struct node *an, bool allocph)
> +{
> +	struct node *c;
> +	struct property *p;
> +	struct label *l;
> +
> +	/* if if there are labels */
> +	if (node->labels) {
> +		/* now add the label in the node */
> +		for_each_label(node->labels, l) {
> +			/* check whether the label already exists */
> +			p = get_property(an, l->label);
> +			if (p) {
> +				fprintf(stderr, "WARNING: label %s already"
> +					" exists in /%s", l->label,
> +					an->name);
> +				continue;
> +			}
> +
> +			/* insert it */
> +			p = build_property(l->label,
> +				data_copy_mem(node->fullpath,
> +						strlen(node->fullpath) + 1));
> +			add_property(an, p);
> +		}
> +
> +		/* force allocation of a phandle for this node */
> +		if (allocph)
> +			(void)get_node_phandle(dt, node);
> +	}
> +
> +	for_each_child(node, c)
> +		generate_label_tree_internal(dt, c, an, allocph);
> +}
> +
> +void generate_label_tree(struct node *dt, char *gen_node_name, bool allocph)
> +{
> +	struct node *an;
> +
> +	for_each_child(dt, an)
> +		if (streq(gen_node_name, an->name))
> +			break;
> +
> +	if (!an)
> +		an = build_and_name_child_node(dt, gen_node_name);
> +	if (!an)
> +		die("Could not build label node /%s\n", gen_node_name);
> +
> +	generate_label_tree_internal(dt, dt, an, allocph);
> +}
> +
> +#define FIXUPS	"__fixups__"
> +#define LOCAL_FIXUPS "__local_fixups__"
> +
> +static void add_fixup_entry(struct node *dt, struct node *node,
> +		struct property *prop, struct marker *m)
> +{
> +	struct node *fn;	/* fixup node */
> +	char *entry;
> +
> +	/* m->ref can only be a REF_PHANDLE, but check anyway */
> +	assert(m->type == REF_PHANDLE);
> +
> +	/* fn is the node we're putting entries in */
> +	fn = get_subnode(dt, FIXUPS);
> +	assert(fn != NULL);
> +
> +	/* there shouldn't be any ':' in the arguments */
> +	if (strchr(node->fullpath, ':') || strchr(prop->name, ':'))
> +		die("arguments should not contain ':'\n");
> +
> +	xasprintf(&entry, "%s:%s:%u",
> +			node->fullpath, prop->name, m->offset);
> +	append_to_property(fn, m->ref, entry, strlen(entry) + 1);
> +}
> +
> +static void add_local_fixup_entry(struct node *dt, struct node *node,
> +		struct property *prop, struct marker *m,
> +		struct node *refnode)
> +{
> +	struct node *lfn, *wn, *nwn;	/* local fixup node, walk node, new */
> +	uint32_t value_32;
> +	char *s, *e, *comp;
> +	int len;
> +
> +	/* fn is the node we're putting entries in */
> +	lfn = get_subnode(dt, LOCAL_FIXUPS);
> +	assert(lfn != NULL);
> +
> +	/* walk the path components creating nodes if they don't exist */
> +	comp = xmalloc(strlen(node->fullpath) + 1);
> +	/* start skipping the first / */
> +	s = node->fullpath + 1;
> +	wn = lfn;
> +	while (*s) {
> +		/* retrieve path component */
> +		e = strchr(s, '/');
> +		if (e == NULL)
> +			e = s + strlen(s);
> +		len = e - s;
> +		memcpy(comp, s, len);
> +		comp[len] = '\0';

Parsing the fullpath into components seems an odd way of doing this.
We have an actual handle on the node, and therefore all it's parents,
which already have the individual path components split out.

> +
> +		/* if no node exists, create it */
> +		nwn = get_subnode(wn, comp);
> +		if (!nwn)
> +			nwn = build_and_name_child_node(wn, comp);
> +		wn = nwn;
> +
> +		/* last path component */
> +		if (!*e)
> +			break;
> +
> +		/* next path component */
> +		s = e + 1;
> +	}
> +	free(comp);
> +
> +	value_32 = cpu_to_fdt32(m->offset);
> +	append_to_property(wn, prop->name, &value_32, sizeof(value_32));
> +}
> +
> +static void generate_fixups_tree_internal(struct node *dt, struct node *node)
> +{
> +	struct node *c;
> +	struct property *prop;
> +	struct marker *m;
> +	struct node *refnode;
> +
> +	for_each_property(node, prop) {
> +		m = prop->val.markers;
> +		for_each_marker_of_type(m, REF_PHANDLE) {
> +			refnode = get_node_by_ref(dt, m->ref);
> +			if (!refnode)
> +				add_fixup_entry(dt, node, prop, m);
> +			else
> +				add_local_fixup_entry(dt, node, prop, m,
> +						refnode);
> +		}
> +	}
> +
> +	for_each_child(node, c)
> +		generate_fixups_tree_internal(dt, c);
> +}
> +
> +void generate_fixups_tree(struct node *dt)
> +{
> +	struct node *an;
> +
> +	for_each_child(dt, an)
> +		if (streq(FIXUPS, an->name))
> +			break;
> +
> +	if (!an)
> +		build_and_name_child_node(dt, FIXUPS);
> +
> +	for_each_child(dt, an)
> +		if (streq(LOCAL_FIXUPS, an->name))
> +			break;
> +
> +	if (!an)
> +		build_and_name_child_node(dt, LOCAL_FIXUPS);
> +
> +	generate_fixups_tree_internal(dt, dt);
> +}
> diff --git a/tests/mangle-layout.c b/tests/mangle-layout.c
> index a76e51e..d29ebc6 100644
> --- a/tests/mangle-layout.c
> +++ b/tests/mangle-layout.c
> @@ -42,7 +42,8 @@ static void expand_buf(struct bufstate *buf, int newsize)
>  	buf->size = newsize;
>  }
>  
> -static void new_header(struct bufstate *buf, int version, const void *fdt)
> +static void new_header(struct bufstate *buf, fdt32_t magic, int version,
> +		       const void *fdt)
>  {
>  	int hdrsize;
>  
> @@ -56,7 +57,7 @@ static void new_header(struct bufstate *buf, int version, const void *fdt)
>  	expand_buf(buf, hdrsize);
>  	memset(buf->buf, 0, hdrsize);
>  
> -	fdt_set_magic(buf->buf, FDT_MAGIC);
> +	fdt_set_magic(buf->buf, magic);
>  	fdt_set_version(buf->buf, version);
>  	fdt_set_last_comp_version(buf->buf, 16);
>  	fdt_set_boot_cpuid_phys(buf->buf, fdt_boot_cpuid_phys(fdt));
> @@ -145,7 +146,7 @@ int main(int argc, char *argv[])
>  	if (fdt_version(fdt) < 17)
>  		CONFIG("Input tree must be v17");
>  
> -	new_header(&buf, version, fdt);
> +	new_header(&buf, FDT_MAGIC, version, fdt);
>  
>  	while (*blockorder) {
>  		add_block(&buf, version, *blockorder, fdt);

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply

* Re: [PATCH v5 09/14] ASoC: simple-card-utils: add asoc_simple_card_parse_graph_dai()
From: Kuninori Morimoto @ 2016-11-28  4:10 UTC (permalink / raw)
  To: kbuild test robot
  Cc: kbuild-all-JC7UmRfGjtg, Rob Herring, Mark Brown, Linux-ALSA,
	Liam Girdwood, Simon, Laurent, Guennadi, Grant Likely,
	Frank Rowand, Linux-DT, Linux-Kernel
In-Reply-To: <201611281130.hdPLIlrW%fengguang.wu-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>


Hi

> [auto build test ERROR on robh/for-next]
> [also build test ERROR on v4.9-rc7]
> [cannot apply to glikely/devicetree/next asoc/for-next next-20161125]
> [if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
> 
> url:    https://github.com/0day-ci/linux/commits/Kuninori-Morimoto/ASoC-add-OF-graph-base-simple-card/20161128-111639
> base:   https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
> config: i386-randconfig-x002-201648 (attached as .config)
> compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
> reproduce:
>         # save the attached .config to linux build tree
>         make ARCH=i386 

I didn't indicate, but, this patch-set is based on Mark's this branch

	git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git :: topic/of-graph

Best regards
---
Kuninori Morimoto
--
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 v3] Documentation: pinctrl: palmas: Add ti,palmas-powerhold-override property definition
From: Keerthy @ 2016-11-28  4:01 UTC (permalink / raw)
  To: linus.walleij
  Cc: j-keerthy, t-kristo, robh+dt, tony, devicetree, linux-omap,
	linux-gpio, linux-kernel

GPIO7 is configured in POWERHOLD mode which has higher priority
over DEV_ON bit and keeps the PMIC supplies on even after the DEV_ON
bit is turned off. This property enables driver to over ride the
POWERHOLD value to GPIO7 so as to turn off the PMIC in power off
scenarios.

Signed-off-by: Keerthy <j-keerthy@ti.com>
Acked-by: Rob Herring <robh@kernel.org>
---

Remaining patches of the series are already queued.

Changes in v3: Added Rob's Ack.

 Documentation/devicetree/bindings/pinctrl/pinctrl-palmas.txt | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-palmas.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-palmas.txt
index caf297b..c28d4eb8 100644
--- a/Documentation/devicetree/bindings/pinctrl/pinctrl-palmas.txt
+++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-palmas.txt
@@ -35,6 +35,15 @@ Optional properties:
 - ti,palmas-enable-dvfs2: Enable DVFS2. Configure pins for DVFS2 mode.
 	Selection primary or secondary function associated to GPADC_START
 	and SYSEN2 pin/pad for DVFS2 interface
+- ti,palmas-override-powerhold: This is applicable for PMICs for which
+	GPIO7 is configured in POWERHOLD mode which has higher priority
+	over DEV_ON bit and keeps the PMIC supplies on even after the DEV_ON
+	bit is turned off. This property enables driver to over ride the
+	POWERHOLD value to GPIO7 so as to turn off the PMIC in power off
+	scenarios. So for GPIO7 if ti,palmas-override-powerhold is set
+	then the GPIO_7 field should never be muxed to anything else.
+	It should be set to POWERHOLD by default and only in case of
+	power off scenarios the driver will over ride the mux value.
 
 This binding uses the following generic properties as defined in
 pinctrl-bindings.txt:
-- 
1.9.1


^ permalink raw reply related

* Re: [PATCH v10 1/4] checks: Pass boot_info instead of root node
From: David Gibson @ 2016-11-28  3:53 UTC (permalink / raw)
  To: Pantelis Antoniou
  Cc: Jon Loeliger, Grant Likely, Frank Rowand, Rob Herring, Jan Luebbe,
	Sascha Hauer, Phil Elwell, Simon Glass, Maxime Ripard,
	Thomas Petazzoni, Boris Brezillon, Antoine Tenart, Stephen Boyd,
	Devicetree Compiler, devicetree-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1480077131-14526-2-git-send-email-pantelis.antoniou-OWPKS81ov/FWk0Htik3J/w@public.gmane.org>

[-- Attachment #1: Type: text/plain, Size: 12923 bytes --]

On Fri, Nov 25, 2016 at 02:32:08PM +0200, Pantelis Antoniou wrote:
> As preparation for overlay support we need to pass the boot info
> parameter instead of the root node to each check method.
> 
> The root node can be retrieved by accessing boot info's dt member.
> 
> No other functional changes are made.
> 
> Signed-off-by: Pantelis Antoniou <pantelis.antoniou-OWPKS81ov/FWk0Htik3J/w@public.gmane.org>

I've applied this preliminary patch to the master branch.  I think
I'll also apply (an updated version of) my patch to rename 'boot_info'
to something a bit less silly.  But I'll hold off for now to avoid
creating extra conflicts with your patches.

> ---
>  checks.c | 78 ++++++++++++++++++++++++++++++++++------------------------------
>  1 file changed, 42 insertions(+), 36 deletions(-)
> 
> diff --git a/checks.c b/checks.c
> index 0381c98..2bd27a4 100644
> --- a/checks.c
> +++ b/checks.c
> @@ -40,7 +40,7 @@ enum checkstatus {
>  
>  struct check;
>  
> -typedef void (*check_fn)(struct check *c, struct node *dt, struct node *node);
> +typedef void (*check_fn)(struct check *c, struct boot_info *bi, struct node *node);
>  
>  struct check {
>  	const char *name;
> @@ -97,20 +97,21 @@ static inline void check_msg(struct check *c, const char *fmt, ...)
>  		check_msg((c), __VA_ARGS__); \
>  	} while (0)
>  
> -static void check_nodes_props(struct check *c, struct node *dt, struct node *node)
> +static void check_nodes_props(struct check *c, struct boot_info *bi, struct node *node)
>  {
>  	struct node *child;
>  
>  	TRACE(c, "%s", node->fullpath);
>  	if (c->fn)
> -		c->fn(c, dt, node);
> +		c->fn(c, bi, node);
>  
>  	for_each_child(node, child)
> -		check_nodes_props(c, dt, child);
> +		check_nodes_props(c, bi, child);
>  }
>  
> -static bool run_check(struct check *c, struct node *dt)
> +static bool run_check(struct check *c, struct boot_info *bi)
>  {
> +	struct node *dt = bi->dt;
>  	bool error = false;
>  	int i;
>  
> @@ -123,7 +124,7 @@ static bool run_check(struct check *c, struct node *dt)
>  
>  	for (i = 0; i < c->num_prereqs; i++) {
>  		struct check *prq = c->prereq[i];
> -		error = error || run_check(prq, dt);
> +		error = error || run_check(prq, bi);
>  		if (prq->status != PASSED) {
>  			c->status = PREREQ;
>  			check_msg(c, "Failed prerequisite '%s'",
> @@ -134,7 +135,7 @@ static bool run_check(struct check *c, struct node *dt)
>  	if (c->status != UNCHECKED)
>  		goto out;
>  
> -	check_nodes_props(c, dt, dt);
> +	check_nodes_props(c, bi, dt);
>  
>  	if (c->status == UNCHECKED)
>  		c->status = PASSED;
> @@ -153,14 +154,14 @@ out:
>   */
>  
>  /* A check which always fails, for testing purposes only */
> -static inline void check_always_fail(struct check *c, struct node *dt,
> +static inline void check_always_fail(struct check *c, struct boot_info *bi,
>  				     struct node *node)
>  {
>  	FAIL(c, "always_fail check");
>  }
>  CHECK(always_fail, check_always_fail, NULL);
>  
> -static void check_is_string(struct check *c, struct node *root,
> +static void check_is_string(struct check *c, struct boot_info *bi,
>  			    struct node *node)
>  {
>  	struct property *prop;
> @@ -179,7 +180,7 @@ static void check_is_string(struct check *c, struct node *root,
>  #define ERROR_IF_NOT_STRING(nm, propname) \
>  	ERROR(nm, check_is_string, (propname))
>  
> -static void check_is_cell(struct check *c, struct node *root,
> +static void check_is_cell(struct check *c, struct boot_info *bi,
>  			  struct node *node)
>  {
>  	struct property *prop;
> @@ -202,7 +203,7 @@ static void check_is_cell(struct check *c, struct node *root,
>   * Structural check functions
>   */
>  
> -static void check_duplicate_node_names(struct check *c, struct node *dt,
> +static void check_duplicate_node_names(struct check *c, struct boot_info *bi,
>  				       struct node *node)
>  {
>  	struct node *child, *child2;
> @@ -217,7 +218,7 @@ static void check_duplicate_node_names(struct check *c, struct node *dt,
>  }
>  ERROR(duplicate_node_names, check_duplicate_node_names, NULL);
>  
> -static void check_duplicate_property_names(struct check *c, struct node *dt,
> +static void check_duplicate_property_names(struct check *c, struct boot_info *bi,
>  					   struct node *node)
>  {
>  	struct property *prop, *prop2;
> @@ -239,7 +240,7 @@ ERROR(duplicate_property_names, check_duplicate_property_names, NULL);
>  #define DIGITS		"0123456789"
>  #define PROPNODECHARS	LOWERCASE UPPERCASE DIGITS ",._+*#?-"
>  
> -static void check_node_name_chars(struct check *c, struct node *dt,
> +static void check_node_name_chars(struct check *c, struct boot_info *bi,
>  				  struct node *node)
>  {
>  	int n = strspn(node->name, c->data);
> @@ -250,7 +251,7 @@ static void check_node_name_chars(struct check *c, struct node *dt,
>  }
>  ERROR(node_name_chars, check_node_name_chars, PROPNODECHARS "@");
>  
> -static void check_node_name_format(struct check *c, struct node *dt,
> +static void check_node_name_format(struct check *c, struct boot_info *bi,
>  				   struct node *node)
>  {
>  	if (strchr(get_unitname(node), '@'))
> @@ -259,8 +260,8 @@ static void check_node_name_format(struct check *c, struct node *dt,
>  }
>  ERROR(node_name_format, check_node_name_format, NULL, &node_name_chars);
>  
> -static void check_unit_address_vs_reg(struct check *c, struct node *dt,
> -			     struct node *node)
> +static void check_unit_address_vs_reg(struct check *c, struct boot_info *bi,
> +				      struct node *node)
>  {
>  	const char *unitname = get_unitname(node);
>  	struct property *prop = get_property(node, "reg");
> @@ -283,7 +284,7 @@ static void check_unit_address_vs_reg(struct check *c, struct node *dt,
>  }
>  WARNING(unit_address_vs_reg, check_unit_address_vs_reg, NULL);
>  
> -static void check_property_name_chars(struct check *c, struct node *dt,
> +static void check_property_name_chars(struct check *c, struct boot_info *bi,
>  				      struct node *node)
>  {
>  	struct property *prop;
> @@ -305,10 +306,11 @@ ERROR(property_name_chars, check_property_name_chars, PROPNODECHARS);
>  	((prop) ? (prop)->name : ""), \
>  	((prop) ? "' in " : ""), (node)->fullpath
>  
> -static void check_duplicate_label(struct check *c, struct node *dt,
> +static void check_duplicate_label(struct check *c, struct boot_info *bi,
>  				  const char *label, struct node *node,
>  				  struct property *prop, struct marker *mark)
>  {
> +	struct node *dt = bi->dt;
>  	struct node *othernode = NULL;
>  	struct property *otherprop = NULL;
>  	struct marker *othermark = NULL;
> @@ -331,30 +333,31 @@ static void check_duplicate_label(struct check *c, struct node *dt,
>  		     DESCLABEL_ARGS(othernode, otherprop, othermark));
>  }
>  
> -static void check_duplicate_label_node(struct check *c, struct node *dt,
> +static void check_duplicate_label_node(struct check *c, struct boot_info *bi,
>  				       struct node *node)
>  {
>  	struct label *l;
>  	struct property *prop;
>  
>  	for_each_label(node->labels, l)
> -		check_duplicate_label(c, dt, l->label, node, NULL, NULL);
> +		check_duplicate_label(c, bi, l->label, node, NULL, NULL);
>  
>  	for_each_property(node, prop) {
>  		struct marker *m = prop->val.markers;
>  
>  		for_each_label(prop->labels, l)
> -			check_duplicate_label(c, dt, l->label, node, prop, NULL);
> +			check_duplicate_label(c, bi, l->label, node, prop, NULL);
>  
>  		for_each_marker_of_type(m, LABEL)
> -			check_duplicate_label(c, dt, m->ref, node, prop, m);
> +			check_duplicate_label(c, bi, m->ref, node, prop, m);
>  	}
>  }
>  ERROR(duplicate_label, check_duplicate_label_node, NULL);
>  
> -static cell_t check_phandle_prop(struct check *c, struct node *root,
> +static cell_t check_phandle_prop(struct check *c, struct boot_info *bi,
>  				 struct node *node, const char *propname)
>  {
> +	struct node *root = bi->dt;
>  	struct property *prop;
>  	struct marker *m;
>  	cell_t phandle;
> @@ -398,18 +401,19 @@ static cell_t check_phandle_prop(struct check *c, struct node *root,
>  	return phandle;
>  }
>  
> -static void check_explicit_phandles(struct check *c, struct node *root,
> +static void check_explicit_phandles(struct check *c, struct boot_info *bi,
>  				    struct node *node)
>  {
> +	struct node *root = bi->dt;
>  	struct node *other;
>  	cell_t phandle, linux_phandle;
>  
>  	/* Nothing should have assigned phandles yet */
>  	assert(!node->phandle);
>  
> -	phandle = check_phandle_prop(c, root, node, "phandle");
> +	phandle = check_phandle_prop(c, bi, node, "phandle");
>  
> -	linux_phandle = check_phandle_prop(c, root, node, "linux,phandle");
> +	linux_phandle = check_phandle_prop(c, bi, node, "linux,phandle");
>  
>  	if (!phandle && !linux_phandle)
>  		/* No valid phandles; nothing further to check */
> @@ -433,7 +437,7 @@ static void check_explicit_phandles(struct check *c, struct node *root,
>  }
>  ERROR(explicit_phandles, check_explicit_phandles, NULL);
>  
> -static void check_name_properties(struct check *c, struct node *root,
> +static void check_name_properties(struct check *c, struct boot_info *bi,
>  				  struct node *node)
>  {
>  	struct property **pp, *prop = NULL;
> @@ -467,9 +471,10 @@ ERROR(name_properties, check_name_properties, NULL, &name_is_string);
>   * Reference fixup functions
>   */
>  
> -static void fixup_phandle_references(struct check *c, struct node *dt,
> +static void fixup_phandle_references(struct check *c, struct boot_info *bi,
>  				     struct node *node)
>  {
> +	struct node *dt = bi->dt;
>  	struct property *prop;
>  
>  	for_each_property(node, prop) {
> @@ -495,9 +500,10 @@ static void fixup_phandle_references(struct check *c, struct node *dt,
>  ERROR(phandle_references, fixup_phandle_references, NULL,
>        &duplicate_node_names, &explicit_phandles);
>  
> -static void fixup_path_references(struct check *c, struct node *dt,
> +static void fixup_path_references(struct check *c, struct boot_info *bi,
>  				  struct node *node)
>  {
> +	struct node *dt = bi->dt;
>  	struct property *prop;
>  
>  	for_each_property(node, prop) {
> @@ -534,7 +540,7 @@ WARNING_IF_NOT_STRING(device_type_is_string, "device_type");
>  WARNING_IF_NOT_STRING(model_is_string, "model");
>  WARNING_IF_NOT_STRING(status_is_string, "status");
>  
> -static void fixup_addr_size_cells(struct check *c, struct node *dt,
> +static void fixup_addr_size_cells(struct check *c, struct boot_info *bi,
>  				  struct node *node)
>  {
>  	struct property *prop;
> @@ -558,7 +564,7 @@ WARNING(addr_size_cells, fixup_addr_size_cells, NULL,
>  #define node_size_cells(n) \
>  	(((n)->size_cells == -1) ? 1 : (n)->size_cells)
>  
> -static void check_reg_format(struct check *c, struct node *dt,
> +static void check_reg_format(struct check *c, struct boot_info *bi,
>  			     struct node *node)
>  {
>  	struct property *prop;
> @@ -587,7 +593,7 @@ static void check_reg_format(struct check *c, struct node *dt,
>  }
>  WARNING(reg_format, check_reg_format, NULL, &addr_size_cells);
>  
> -static void check_ranges_format(struct check *c, struct node *dt,
> +static void check_ranges_format(struct check *c, struct boot_info *bi,
>  				struct node *node)
>  {
>  	struct property *prop;
> @@ -631,7 +637,7 @@ WARNING(ranges_format, check_ranges_format, NULL, &addr_size_cells);
>  /*
>   * Style checks
>   */
> -static void check_avoid_default_addr_size(struct check *c, struct node *dt,
> +static void check_avoid_default_addr_size(struct check *c, struct boot_info *bi,
>  					  struct node *node)
>  {
>  	struct property *reg, *ranges;
> @@ -657,9 +663,10 @@ WARNING(avoid_default_addr_size, check_avoid_default_addr_size, NULL,
>  	&addr_size_cells);
>  
>  static void check_obsolete_chosen_interrupt_controller(struct check *c,
> -						       struct node *dt,
> +						       struct boot_info *bi,
>  						       struct node *node)
>  {
> +	struct node *dt = bi->dt;
>  	struct node *chosen;
>  	struct property *prop;
>  
> @@ -765,7 +772,6 @@ void parse_checks_option(bool warn, bool error, const char *arg)
>  
>  void process_checks(bool force, struct boot_info *bi)
>  {
> -	struct node *dt = bi->dt;
>  	int i;
>  	int error = 0;
>  
> @@ -773,7 +779,7 @@ void process_checks(bool force, struct boot_info *bi)
>  		struct check *c = check_table[i];
>  
>  		if (c->warn || c->error)
> -			error = error || run_check(c, dt);
> +			error = error || run_check(c, bi);
>  	}
>  
>  	if (error) {

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply

* Re: [PATCH v2 1/5] Documentation: pinctrl: palmas: Add ti,palmas-powerhold-override property definition
From: Keerthy @ 2016-11-28  3:51 UTC (permalink / raw)
  To: Lee Jones
  Cc: Rob Herring, tony, linux-omap, linux-kernel, devicetree,
	linux-gpio, nm, t-kristo
In-Reply-To: <20161124084544.GS10134@dell.home>



On Thursday 24 November 2016 02:15 PM, Lee Jones wrote:
> On Thu, 24 Nov 2016, Keerthy wrote:
>
>>
>>
>> On Tuesday 15 November 2016 07:13 AM, Rob Herring wrote:
>>> On Thu, Nov 10, 2016 at 10:39:16AM +0530, Keerthy wrote:
>>>> GPIO7 is configured in POWERHOLD mode which has higher priority
>>>> over DEV_ON bit and keeps the PMIC supplies on even after the DEV_ON
>>>> bit is turned off. This property enables driver to over ride the
>>>> POWERHOLD value to GPIO7 so as to turn off the PMIC in power off
>>>> scenarios.
>>>>
>>>> Signed-off-by: Keerthy <j-keerthy@ti.com>
>>>> ---
>>>>  Documentation/devicetree/bindings/pinctrl/pinctrl-palmas.txt | 9 +++++++++
>>>>  1 file changed, 9 insertions(+)
>>>
>>> Acked-by: Rob Herring <robh@kernel.org>
>>
>> Tony,
>>
>> Are you planning to pick this one as well?
>
> This should be taken by LinusW.

Okay. I will post this separately.

>

^ permalink raw reply

* Re: [PATCH v5 09/14] ASoC: simple-card-utils: add asoc_simple_card_parse_graph_dai()
From: kbuild test robot @ 2016-11-28  3:41 UTC (permalink / raw)
  To: Kuninori Morimoto
  Cc: kbuild-all-JC7UmRfGjtg, Rob Herring, Mark Brown, Linux-ALSA,
	Liam Girdwood, Simon, Laurent, Guennadi, Grant Likely,
	Frank Rowand, Linux-DT, Linux-Kernel
In-Reply-To: <877f7owccz.wl%kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>

[-- Attachment #1: Type: text/plain, Size: 5259 bytes --]

Hi Kuninori,

[auto build test ERROR on robh/for-next]
[also build test ERROR on v4.9-rc7]
[cannot apply to glikely/devicetree/next asoc/for-next next-20161125]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Kuninori-Morimoto/ASoC-add-OF-graph-base-simple-card/20161128-111639
base:   https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
config: i386-randconfig-x002-201648 (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

All errors (new ones prefixed by >>):

   sound/soc/generic/simple-card-utils.c: In function 'asoc_simple_card_parse_card_name':
   sound/soc/generic/simple-card-utils.c:92:8: error: implicit declaration of function 'snd_soc_of_parse_card_name_from_node' [-Werror=implicit-function-declaration]
     ret = snd_soc_of_parse_card_name_from_node(card, node, prop);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   sound/soc/generic/simple-card-utils.c: In function 'asoc_simple_card_parse_graph_dai':
>> sound/soc/generic/simple-card-utils.c:210:9: error: implicit declaration of function 'snd_soc_get_dai_name' [-Werror=implicit-function-declaration]
      ret = snd_soc_get_dai_name(&args, dai_name);
            ^~~~~~~~~~~~~~~~~~~~
   cc1: some warnings being treated as errors

vim +/snd_soc_get_dai_name +210 sound/soc/generic/simple-card-utils.c

    86		char prop[128];
    87		int ret;
    88	
    89		snprintf(prop, sizeof(prop), "%sname", prefix);
    90	
    91		/* Parse the card name from DT */
  > 92		ret = snd_soc_of_parse_card_name_from_node(card, node, prop);
    93		if (ret < 0)
    94			return ret;
    95	
    96		if (!card->name && card->dai_link)
    97			card->name = card->dai_link->name;
    98	
    99		return 0;
   100	}
   101	EXPORT_SYMBOL_GPL(asoc_simple_card_parse_card_name);
   102	
   103	int asoc_simple_card_parse_clk(struct device_node *node,
   104				       struct device_node *dai_of_node,
   105				       struct asoc_simple_dai *simple_dai)
   106	{
   107		struct clk *clk;
   108		u32 val;
   109	
   110		/*
   111		 * Parse dai->sysclk come from "clocks = <&xxx>"
   112		 * (if system has common clock)
   113		 *  or "system-clock-frequency = <xxx>"
   114		 *  or device's module clock.
   115		 */
   116		clk = of_clk_get(node, 0);
   117		if (!IS_ERR(clk)) {
   118			simple_dai->sysclk = clk_get_rate(clk);
   119			simple_dai->clk = clk;
   120		} else if (!of_property_read_u32(node, "system-clock-frequency", &val)) {
   121			simple_dai->sysclk = val;
   122		} else {
   123			clk = of_clk_get(dai_of_node, 0);
   124			if (!IS_ERR(clk))
   125				simple_dai->sysclk = clk_get_rate(clk);
   126		}
   127	
   128		return 0;
   129	}
   130	EXPORT_SYMBOL_GPL(asoc_simple_card_parse_clk);
   131	
   132	int asoc_simple_card_parse_dai(struct device_node *node,
   133					    struct device_node **dai_of_node,
   134					    const char **dai_name,
   135					    const char *list_name,
   136					    const char *cells_name,
   137					    int *is_single_link)
   138	{
   139		struct of_phandle_args args;
   140		int ret;
   141	
   142		if (!node)
   143			return 0;
   144	
   145		/*
   146		 * Get node via "sound-dai = <&phandle port>"
   147		 * it will be used as xxx_of_node on soc_bind_dai_link()
   148		 */
   149		ret = of_parse_phandle_with_args(node, list_name, cells_name, 0, &args);
   150		if (ret)
   151			return ret;
   152	
   153		/* Get dai->name */
   154		if (dai_name) {
   155			ret = snd_soc_of_get_dai_name(node, dai_name);
   156			if (ret < 0)
   157				return ret;
   158		}
   159	
   160		*dai_of_node = args.np;
   161	
   162		if (is_single_link)
   163			*is_single_link = !args.args_count;
   164	
   165		return 0;
   166	}
   167	EXPORT_SYMBOL_GPL(asoc_simple_card_parse_dai);
   168	
   169	int asoc_simple_card_parse_graph_dai(struct device_node *ep,
   170					     struct device_node **dai_of_node,
   171					     const char **dai_name)
   172	{
   173		struct device_node *node, *port, *endpoint;
   174		int i, id;
   175	
   176		if (!ep)
   177			return 0;
   178	
   179		/*
   180		 * of_graph_get_port_parent() will call
   181		 * of_node_put(). So, call of_node_get() here
   182		 */
   183		of_node_get(ep);
   184		node = of_graph_get_port_parent(ep);
   185	
   186		i = 0;
   187		id = -1;
   188		for_each_of_port(node, port) {
   189			if (!of_graph_port_type_is_sound(port))
   190				continue;
   191	
   192			for_each_of_endpoint_in_port(port, endpoint) {
   193				if (endpoint == ep)
   194					id = i;
   195				i++;
   196			}
   197		}
   198		if (id < 0)
   199			return -ENODEV;
   200	
   201		/* Get dai->name */
   202		if (dai_name) {
   203			struct of_phandle_args args;
   204			int ret;
   205	
   206			args.np		= node;
   207			args.args[0]	= id;
   208			args.args_count	= (i > 1);
   209	
 > 210			ret = snd_soc_get_dai_name(&args, dai_name);
   211			if (ret < 0)
   212				return ret;
   213		}

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 32707 bytes --]

^ permalink raw reply

* [PATCH v5 14/14] ASoC: add simple-graph-scu-card support
From: Kuninori Morimoto @ 2016-11-28  2:48 UTC (permalink / raw)
  To: Rob Herring, Mark Brown
  Cc: Linux-ALSA, Liam Girdwood, Simon, Laurent, Guennadi, Grant Likely,
	Frank Rowand, Linux-DT, Linux-Kernel
In-Reply-To: <87k2bowckx.wl%kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>


From: Kuninori Morimoto <kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>

graph base DT binding are used on V4L2, and ALSA SoC is using different
style of DT. In case of simple case, ALSA SoC supports simple-card
driver.
In the future, V4L2 / ALSA will support HDMI, and then, DT bindings
between V4L2 / ALSA should be merged somehow.
Sometimes, we would like to use DPCM base simple-card on graph base DT.
This patch adds graph base DT binding of simple-scu-card

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
---
 sound/soc/generic/Kconfig                 |   8 +
 sound/soc/generic/Makefile                |   2 +
 sound/soc/generic/simple-graph-scu-card.c | 441 ++++++++++++++++++++++++++++++
 3 files changed, 451 insertions(+)
 create mode 100644 sound/soc/generic/simple-graph-scu-card.c

diff --git a/sound/soc/generic/Kconfig b/sound/soc/generic/Kconfig
index efefabd..fc11828 100644
--- a/sound/soc/generic/Kconfig
+++ b/sound/soc/generic/Kconfig
@@ -21,3 +21,11 @@ config SND_SIMPLE_GRAPH_CARD
 	select SND_SIMPLE_CARD_UTILS
 	help
 	  This option enables generic simple Graph sound card support
+
+config SND_SIMPLE_GRAPH_SCU_CARD
+	tristate "ASoC Simple Graph SCU sound card support"
+	depends on OF
+	select SND_SIMPLE_CARD_UTILS
+	help
+	  This option enables generic simple Graph SCU sound card support.
+	  It supports DPCM of multi CPU single Codec ststem.
diff --git a/sound/soc/generic/Makefile b/sound/soc/generic/Makefile
index 94eb6f1..fd75b55 100644
--- a/sound/soc/generic/Makefile
+++ b/sound/soc/generic/Makefile
@@ -2,8 +2,10 @@ snd-soc-simple-card-utils-objs	:= simple-card-utils.o
 snd-soc-simple-card-objs	:= simple-card.o
 snd-soc-simple-scu-card-objs	:= simple-scu-card.o
 snd-soc-simple-graph-card-objs	:= simple-graph-card.o
+snd-soc-simple-graph-scu-card-objs	:= simple-graph-scu-card.o
 
 obj-$(CONFIG_SND_SIMPLE_CARD_UTILS)	+= snd-soc-simple-card-utils.o
 obj-$(CONFIG_SND_SIMPLE_CARD)		+= snd-soc-simple-card.o
 obj-$(CONFIG_SND_SIMPLE_SCU_CARD)	+= snd-soc-simple-scu-card.o
 obj-$(CONFIG_SND_SIMPLE_GRAPH_CARD)	+= snd-soc-simple-graph-card.o
+obj-$(CONFIG_SND_SIMPLE_GRAPH_SCU_CARD)	+= snd-soc-simple-graph-scu-card.o
diff --git a/sound/soc/generic/simple-graph-scu-card.c b/sound/soc/generic/simple-graph-scu-card.c
new file mode 100644
index 0000000..f910665
--- /dev/null
+++ b/sound/soc/generic/simple-graph-scu-card.c
@@ -0,0 +1,441 @@
+/*
+ * ASoC simple graph SCU sound card support
+ *
+ * Copyright (C) 2016 Renesas Solutions Corp.
+ * Kuninori Morimoto <kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
+ *
+ * based on
+ *	${LINUX}/sound/soc/generic/simple-graph-card.c
+ *	${LINUX}/sound/soc/generic/simple-scu-card.c
+ *
+ * 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/clk.h>
+#include <linux/device.h>
+#include <linux/gpio.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
+#include <linux/of_graph.h>
+#include <linux/platform_device.h>
+#include <linux/string.h>
+#include <sound/jack.h>
+#include <sound/simple_card_utils.h>
+
+struct simple_card_data {
+	struct snd_soc_card snd_card;
+	struct snd_soc_codec_conf codec_conf;
+	struct asoc_simple_dai *dai_props;
+	struct snd_soc_dai_link *dai_link;
+	u32 convert_rate;
+	u32 convert_channels;
+};
+
+#define simple_priv_to_dev(priv) ((priv)->snd_card.dev)
+#define simple_priv_to_link(priv, i) ((priv)->snd_card.dai_link + (i))
+#define simple_priv_to_props(priv, i) ((priv)->dai_props + (i))
+
+#define PREFIX	"simple-audio-card,"
+
+static int asoc_simple_card_startup(struct snd_pcm_substream *substream)
+{
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct simple_card_data *priv =	snd_soc_card_get_drvdata(rtd->card);
+	struct asoc_simple_dai *dai_props =
+		simple_priv_to_props(priv, rtd->num);
+
+	return clk_prepare_enable(dai_props->clk);
+}
+
+static void asoc_simple_card_shutdown(struct snd_pcm_substream *substream)
+{
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct simple_card_data *priv =	snd_soc_card_get_drvdata(rtd->card);
+	struct asoc_simple_dai *dai_props =
+		simple_priv_to_props(priv, rtd->num);
+
+	clk_disable_unprepare(dai_props->clk);
+}
+
+static struct snd_soc_ops asoc_simple_card_ops = {
+	.startup = asoc_simple_card_startup,
+	.shutdown = asoc_simple_card_shutdown,
+};
+
+static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd)
+{
+	struct simple_card_data *priv =	snd_soc_card_get_drvdata(rtd->card);
+	struct snd_soc_dai *dai;
+	struct snd_soc_dai_link *dai_link;
+	struct asoc_simple_dai *dai_props;
+	int num = rtd->num;
+
+	dai_link	= simple_priv_to_link(priv, num);
+	dai_props	= simple_priv_to_props(priv, num);
+	dai		= dai_link->dynamic ?
+				rtd->cpu_dai :
+				rtd->codec_dai;
+
+	return asoc_simple_card_init_dai(dai, dai_props);
+}
+
+static int asoc_simple_card_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+					       struct snd_pcm_hw_params *params)
+{
+	struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
+	struct snd_interval *rate = hw_param_interval(params,
+						      SNDRV_PCM_HW_PARAM_RATE);
+	struct snd_interval *channels = hw_param_interval(params,
+							  SNDRV_PCM_HW_PARAM_CHANNELS);
+
+	if (priv->convert_rate)
+		rate->min =
+		rate->max = priv->convert_rate;
+
+	if (priv->convert_channels)
+		channels->min =
+		channels->max = priv->convert_channels;
+
+	return 0;
+}
+
+static int asoc_simple_card_dai_link_of(struct device_node *port,
+					struct device_node *ep,
+					struct simple_card_data *priv,
+					unsigned int daifmt,
+					int idx, int is_fe)
+{
+	struct device *dev = simple_priv_to_dev(priv);
+	struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, idx);
+	struct asoc_simple_dai *dai_props = simple_priv_to_props(priv, idx);
+	int ret;
+
+	if (is_fe) {
+		/* BE is dummy */
+		dai_link->codec_of_node		= NULL;
+		dai_link->codec_dai_name	= "snd-soc-dummy-dai";
+		dai_link->codec_name		= "snd-soc-dummy";
+
+		/* FE settings */
+		dai_link->dynamic		= 1;
+		dai_link->dpcm_merged_format	= 1;
+
+		ret = asoc_simple_card_parse_graph_cpu(ep, dai_link);
+		if (ret)
+			return ret;
+
+		ret = asoc_simple_card_parse_clk_cpu(ep, dai_link, dai_props);
+		if (ret < 0)
+			return ret;
+
+		ret = asoc_simple_card_set_dailink_name(dev, dai_link,
+							"fe.%s",
+							dai_link->cpu_dai_name);
+		if (ret < 0)
+			return ret;
+
+		/* snd_card.num_links includes Codec */
+		asoc_simple_card_canonicalize_cpu(dai_link,
+					(priv->snd_card.num_links - 1) == 1);
+	} else {
+		/* FE is dummy */
+		dai_link->cpu_of_node		= NULL;
+		dai_link->cpu_dai_name		= "snd-soc-dummy-dai";
+		dai_link->cpu_name		= "snd-soc-dummy";
+
+		/* BE settings */
+		dai_link->no_pcm		= 1;
+		dai_link->be_hw_params_fixup	= asoc_simple_card_be_hw_params_fixup;
+
+		ret = asoc_simple_card_parse_graph_codec(ep, dai_link);
+		if (ret < 0)
+			return ret;
+
+		ret = asoc_simple_card_parse_clk_codec(ep, dai_link, dai_props);
+		if (ret < 0)
+			return ret;
+
+		ret = asoc_simple_card_set_dailink_name(dev, dai_link,
+							"be.%s",
+							dai_link->codec_dai_name);
+		if (ret < 0)
+			return ret;
+
+		snd_soc_of_parse_audio_prefix_from_node(&priv->snd_card,
+							port->parent,
+							&priv->codec_conf,
+							dai_link->codec_of_node,
+							PREFIX "prefix");
+	}
+
+	ret = snd_soc_of_parse_tdm_slot(ep,
+					&dai_props->tx_slot_mask,
+					&dai_props->rx_slot_mask,
+					&dai_props->slots,
+					&dai_props->slot_width);
+	if (ret)
+		return ret;
+
+	ret = asoc_simple_card_canonicalize_dailink(dai_link);
+	if (ret < 0)
+		return ret;
+
+	dai_link->dai_fmt		= daifmt;
+	dai_link->dpcm_playback		= 1;
+	dai_link->dpcm_capture		= 1;
+	dai_link->ops			= &asoc_simple_card_ops;
+	dai_link->init			= asoc_simple_card_dai_init;
+
+	dev_dbg(dev, "\t%s / %04x / %d\n",
+		dai_link->name,
+		dai_link->dai_fmt,
+		dai_props->sysclk);
+
+	return 0;
+}
+
+static int asoc_simple_card_parse_of(struct device_node *node,
+				     struct simple_card_data *priv)
+{
+	struct device *dev = simple_priv_to_dev(priv);
+	struct device *cpu_dev = dev->parent;
+	struct device_node *ports = of_graph_get_top_port(cpu_dev);
+	struct snd_soc_card *card = &priv->snd_card;
+	struct device_node *port, *cpu_ep, *r_cpu_ep, *codec_ep;
+	unsigned int daifmt = 0;
+	int i, ret, done;
+
+	if (!node)
+		return -EINVAL;
+
+	ret = snd_soc_of_parse_audio_routing_from_node(&priv->snd_card,
+						       ports, PREFIX "routing");
+	if (ret)
+		return ret;
+
+	/* sampling rate convert */
+	of_property_read_u32(ports, PREFIX "convert-rate",
+			     &priv->convert_rate);
+
+	/* channels transfer */
+	of_property_read_u32(ports, PREFIX "convert-channels",
+			     &priv->convert_channels);
+
+	/*
+	 * it supports multi CPU, single CODEC only here.
+	 */
+
+	/* find 1st codec */
+	done = 0;
+	for_each_of_port(node, port) {
+		/* keep for_each for of_node_get/of_node_put */
+		if (done)
+			continue;
+
+		if (!of_graph_port_type_is_sound(port))
+			continue;
+
+		for_each_of_endpoint_in_port(port, cpu_ep) {
+			/* keep for_each for of_node_get/of_node_put */
+			if (done)
+				continue;
+
+			codec_ep = of_graph_get_remote_endpoint(cpu_ep);
+			r_cpu_ep = of_graph_get_remote_endpoint(codec_ep);
+			of_node_put(codec_ep);
+			of_node_put(r_cpu_ep);
+			if (cpu_ep != r_cpu_ep) {
+				ret = -EINVAL;
+				goto parse_of_err;
+			}
+
+			ret = asoc_simple_card_parse_daifmt(dev,
+							    ports, codec_ep,
+							    PREFIX, &daifmt);
+			if (ret < 0)
+				goto parse_of_err;
+
+			done = 1;
+		}
+	}
+
+	/* Front-End (= CPU) */
+	i = 0;
+	for_each_of_port(node, port) {
+		if (!of_graph_port_type_is_sound(port))
+			continue;
+
+		for_each_of_endpoint_in_port(port, cpu_ep) {
+			ret = asoc_simple_card_dai_link_of(
+				port, cpu_ep, priv, daifmt, i, 1);
+			if (ret < 0)
+				goto parse_of_err;
+			i++;
+		}
+	}
+
+	/* Back-End (= Codec) */
+	done = 0;
+	for_each_of_port(node, port) {
+		if (!of_graph_port_type_is_sound(port))
+			continue;
+
+		/* keep for_each for of_node_get/of_node_put */
+		if (done)
+			continue;
+
+		for_each_of_endpoint_in_port(port, cpu_ep) {
+			/* keep for_each for of_node_get/of_node_put */
+			if (done)
+				continue;
+
+			codec_ep = of_graph_get_remote_endpoint(cpu_ep);
+			r_cpu_ep = of_graph_get_remote_endpoint(codec_ep);
+			of_node_put(codec_ep);
+			of_node_put(r_cpu_ep);
+			if (cpu_ep != r_cpu_ep) {
+				ret = -EINVAL;
+				goto parse_of_err;
+			}
+
+			ret = asoc_simple_card_dai_link_of(
+				port, codec_ep, priv, daifmt, i, 0);
+			if (ret < 0)
+				goto parse_of_err;
+			i++;
+
+			done = 1;
+		}
+	}
+
+	ret = asoc_simple_card_parse_card_name(card, ports, PREFIX);
+	if (ret)
+		return ret;
+
+	dev_dbg(dev, "New card: %s\n",
+		priv->snd_card.name ? priv->snd_card.name : "");
+	dev_dbg(dev, "convert_rate     %d\n", priv->convert_rate);
+	dev_dbg(dev, "convert_channels %d\n", priv->convert_channels);
+
+	return 0;
+parse_of_err:
+	of_node_put(port);
+	of_node_put(cpu_ep);
+
+	return ret;
+}
+
+static int asoc_get_sound_port_count(struct device_node *cpu_node)
+{
+	int num;
+
+	/*
+	 * it supports multi CPU, single CODEC only here.
+	 */
+
+	/* CPU */
+	num = of_graph_get_sound_endpoint_count(cpu_node);
+
+	/* Codec */
+	num++;
+
+	return num;
+}
+
+static int asoc_simple_card_probe(struct platform_device *pdev)
+{
+	struct simple_card_data *priv;
+	struct snd_soc_dai_link *dai_link;
+	struct asoc_simple_dai *dai_props;
+	struct device *dev = &pdev->dev;
+	struct device *cpu_dev = pdev->dev.parent;
+	struct device_node *cpu_node = cpu_dev->of_node;
+	int num, ret;
+
+	/* Allocate the private data and the DAI link array */
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	num = asoc_get_sound_port_count(cpu_node);
+
+	dai_props = devm_kzalloc(dev, sizeof(*dai_props) * num, GFP_KERNEL);
+	dai_link  = devm_kzalloc(dev, sizeof(*dai_link)  * num, GFP_KERNEL);
+	if (!dai_props || !dai_link)
+		return -ENOMEM;
+
+	priv->dai_props			= dai_props;
+	priv->dai_link			= dai_link;
+
+	/* Init snd_soc_card */
+	priv->snd_card.owner		= THIS_MODULE;
+	priv->snd_card.dev		= dev;
+	priv->snd_card.dai_link		= priv->dai_link;
+	priv->snd_card.num_links	= num;
+	priv->snd_card.codec_conf	= &priv->codec_conf;
+	priv->snd_card.num_configs	= 1;
+
+	ret = asoc_simple_card_parse_of(cpu_node, priv);
+	if (ret < 0) {
+		if (ret != -EPROBE_DEFER)
+			dev_err(dev, "parse error %d\n", ret);
+		goto err;
+	}
+
+	/*
+	 * FIXME
+	 *
+	 * This driver is assuming that it will be called from
+	 * asoc_simple_card_try_to_probe_graph_card() which
+	 * is using platform_device_register_full().
+	 * This means it is not came from DT. But this driver itself
+	 * will be used as part of ALSA SoC (= sound card).
+	 * Because of these background, it might fail in
+	 * snd_pcm_lib_malloc_pages() on .hw_params.
+	 * Because, noone cares its dma_ops, and result of get_dma_ops()
+	 * is based on its architecture.
+	 * So, it should call arch_setup_dma_ops() from somewhere,
+	 * otherwise, for example, ARM is no problem, but ARM64 will be fail.
+	 * But, of_platform_device_xxx() are not good solution today.
+	 * This driver calls it by itself here. Please fixme
+	 * see also
+	 * linux/sound/soc/generic/simple-card-utils.c ::
+	 *	asoc_simple_card_try_to_probe_graph_card()
+	 */
+	of_dma_configure(dev, dev->of_node);
+
+	snd_soc_card_set_drvdata(&priv->snd_card, priv);
+
+	ret = devm_snd_soc_register_card(dev, &priv->snd_card);
+	if (ret >= 0)
+		return ret;
+err:
+	asoc_simple_card_clean_reference(&priv->snd_card);
+
+	return ret;
+}
+
+static int asoc_simple_card_remove(struct platform_device *pdev)
+{
+	struct snd_soc_card *card = platform_get_drvdata(pdev);
+	struct simple_card_data *priv = snd_soc_card_get_drvdata(card);
+
+	return asoc_simple_card_clean_reference(&priv->snd_card);
+}
+
+static struct platform_driver asoc_simple_card = {
+	.driver = {
+		.name = "asoc-simple-graph-scu-card",
+	},
+	.probe = asoc_simple_card_probe,
+	.remove = asoc_simple_card_remove,
+};
+module_platform_driver(asoc_simple_card);
+
+MODULE_ALIAS("platform:asoc-simple-graph-scu-card");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("ASoC Simple Graph SCU Sound Card");
+MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>");
-- 
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 v5 13/14] ASoC: add simple-graph-scu-card document
From: Kuninori Morimoto @ 2016-11-28  2:48 UTC (permalink / raw)
  To: Rob Herring, Mark Brown
  Cc: Linux-ALSA, Liam Girdwood, Simon, Laurent, Guennadi, Grant Likely,
	Frank Rowand, Linux-DT, Linux-Kernel
In-Reply-To: <87k2bowckx.wl%kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>


From: Kuninori Morimoto <kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
---
 .../bindings/sound/simple-graph-scu-card.txt       | 69 ++++++++++++++++++++++
 1 file changed, 69 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/simple-graph-scu-card.txt

diff --git a/Documentation/devicetree/bindings/sound/simple-graph-scu-card.txt b/Documentation/devicetree/bindings/sound/simple-graph-scu-card.txt
new file mode 100644
index 0000000..b0e46ba
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/simple-graph-scu-card.txt
@@ -0,0 +1,69 @@
+Simple-Graph-SCU-Card:
+
+Simple-Graph-SCU-Card specifies audio DAI connections of SoC <-> codec.
+It is based on common bindings for device graphs.
+see ${LINUX}/Documentation/devicetree/bindings/graph.txt
+
+Basically, Simple-Graph-SCU-Card property is same as Simple-Card / Simple-Graph-Card.
+see ${LINUX}/Documentation/devicetree/bindings/sound/simple-card.txt
+    ${LINUX}/Documentation/devicetree/bindings/sound/simple-graph-card.txt
+
+Main difference between Simple-Graph-Card and Simple-Graph-SCU-Card is that
+Simple-Graph-SCU-Card can use multi CPU.
+
+Required properties:
+
+- compatible				: "asoc-simple-graph-scu-card";
+- type					: "sound";
+- simple-audio-card,routing		: see simple-card.txt
+
+Example
+
+ak4643: codec@12 {
+	compatible = "asahi-kasei,ak4643";
+	...
+	port {
+		type = "sound";
+		ak4643_fe: endpoint@0 {
+			remote-endpoint = <&rsnd_fe>;
+			...
+		};
+		ak4643_be: endpoint@1 {
+			remote-endpoint = <&rsnd_be>;
+			...
+		};
+	};
+};
+
+rcar_sound {
+	...
+	ports {
+		compatible = "asoc-simple-graph-scu-card";
+
+		simple-audio-card,name = "graph-sound";
+		simple-audio-card,format = "left_j";
+		simple-audio-card,bitclock-master = <&rsnd_fe>;
+		simple-audio-card,frame-master = <&rsnd_fe>;
+		simple-audio-card,convert-rate = <48000>;
+		simple-audio-card,convert-channels = <2>;
+		simple-audio-card,prefix = "ak4642";
+		simple-audio-card,routing =
+				"ak4642 Playback", "DAI0 Playback",
+				"ak4642 Playback", "DAI1 Playback";
+
+		port@0 {
+			type = "sound";
+			rsnd_fe: endpoint@0 {
+				remote-endpoint = <&ak4643_fe>;
+				...
+			};
+		};
+		port@1 {
+			type = "sound";
+			rsnd_be: endpoint@1 {
+				remote-endpoint = <&ak4643_be>;
+				...
+			};
+		};
+	};
+};
-- 
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 v5 12/14] ASoC: add simple-graph-card support
From: Kuninori Morimoto @ 2016-11-28  2:48 UTC (permalink / raw)
  To: Rob Herring, Mark Brown
  Cc: Linux-ALSA, Liam Girdwood, Simon, Laurent, Guennadi, Grant Likely,
	Frank Rowand, Linux-DT, Linux-Kernel
In-Reply-To: <87k2bowckx.wl%kuninori.morimoto.gx@renesas.com>


From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>

graph base DT binding are used on V4L2, and ALSA SoC is using different
style of DT. In case of simple case, ALSA SoC supports simple-card
driver.
In the future, V4L2 / ALSA will support HDMI, and then, DT bindings
between V4L2 / ALSA should be merged somehow.
This patch adds graph base DT binding with simple-card style

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
 sound/soc/generic/Kconfig             |   7 +
 sound/soc/generic/Makefile            |   2 +
 sound/soc/generic/simple-graph-card.c | 461 ++++++++++++++++++++++++++++++++++
 3 files changed, 470 insertions(+)
 create mode 100644 sound/soc/generic/simple-graph-card.c

diff --git a/sound/soc/generic/Kconfig b/sound/soc/generic/Kconfig
index d023959..efefabd 100644
--- a/sound/soc/generic/Kconfig
+++ b/sound/soc/generic/Kconfig
@@ -14,3 +14,10 @@ config SND_SIMPLE_SCU_CARD
 	help
 	  This option enables generic simple SCU sound card support.
 	  It supports DPCM of multi CPU single Codec system.
+
+config SND_SIMPLE_GRAPH_CARD
+	tristate "ASoC Simple Graph sound card support"
+	depends on OF
+	select SND_SIMPLE_CARD_UTILS
+	help
+	  This option enables generic simple Graph sound card support
diff --git a/sound/soc/generic/Makefile b/sound/soc/generic/Makefile
index ee750f3..94eb6f1 100644
--- a/sound/soc/generic/Makefile
+++ b/sound/soc/generic/Makefile
@@ -1,7 +1,9 @@
 snd-soc-simple-card-utils-objs	:= simple-card-utils.o
 snd-soc-simple-card-objs	:= simple-card.o
 snd-soc-simple-scu-card-objs	:= simple-scu-card.o
+snd-soc-simple-graph-card-objs	:= simple-graph-card.o
 
 obj-$(CONFIG_SND_SIMPLE_CARD_UTILS)	+= snd-soc-simple-card-utils.o
 obj-$(CONFIG_SND_SIMPLE_CARD)		+= snd-soc-simple-card.o
 obj-$(CONFIG_SND_SIMPLE_SCU_CARD)	+= snd-soc-simple-scu-card.o
+obj-$(CONFIG_SND_SIMPLE_GRAPH_CARD)	+= snd-soc-simple-graph-card.o
diff --git a/sound/soc/generic/simple-graph-card.c b/sound/soc/generic/simple-graph-card.c
new file mode 100644
index 0000000..fd7cddb
--- /dev/null
+++ b/sound/soc/generic/simple-graph-card.c
@@ -0,0 +1,461 @@
+/*
+ * ASoC simple graph sound card support
+ *
+ * Copyright (C) 2016 Renesas Solutions Corp.
+ * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+ *
+ * based on ${LINUX}/sound/soc/generic/simple-card.c
+ *
+ * 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/clk.h>
+#include <linux/device.h>
+#include <linux/gpio.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
+#include <linux/of_graph.h>
+#include <linux/platform_device.h>
+#include <linux/string.h>
+#include <sound/jack.h>
+#include <sound/simple_card_utils.h>
+
+struct asoc_simple_jack {
+	struct snd_soc_jack jack;
+	struct snd_soc_jack_pin pin;
+	struct snd_soc_jack_gpio gpio;
+};
+
+struct simple_card_data {
+	struct snd_soc_card snd_card;
+	struct simple_dai_props {
+		struct asoc_simple_dai cpu_dai;
+		struct asoc_simple_dai codec_dai;
+		unsigned int mclk_fs;
+	} *dai_props;
+	struct asoc_simple_jack hp_jack;
+	struct asoc_simple_jack mic_jack;
+	struct snd_soc_dai_link *dai_link;
+	unsigned int mclk_fs;
+};
+
+#define simple_priv_to_dev(priv) ((priv)->snd_card.dev)
+#define simple_priv_to_link(priv, i) ((priv)->snd_card.dai_link + (i))
+#define simple_priv_to_props(priv, i) ((priv)->dai_props + (i))
+
+#define PREFIX	"simple-audio-card,"
+
+#define asoc_simple_card_init_hp(card, node, sjack, prefix)	\
+	asoc_simple_card_init_jack(card, node, sjack, 1, prefix)
+#define asoc_simple_card_init_mic(card, node, sjack, prefix)	\
+	asoc_simple_card_init_jack(card, node, sjack, 0, prefix)
+static int asoc_simple_card_init_jack(struct snd_soc_card *card,
+				      struct device_node *node,
+				      struct asoc_simple_jack *sjack,
+				      int is_hp, char *prefix)
+{
+	enum of_gpio_flags flags;
+	char prop[128];
+	char *pin_name;
+	char *gpio_name;
+	int mask;
+	int det;
+
+	sjack->gpio.gpio = -ENOENT;
+
+	if (is_hp) {
+		snprintf(prop, sizeof(prop), "%shp-det-gpio", prefix);
+		pin_name	= "Headphones";
+		gpio_name	= "Headphone detection";
+		mask		= SND_JACK_HEADPHONE;
+	} else {
+		snprintf(prop, sizeof(prop), "%smic-det-gpio", prefix);
+		pin_name	= "Mic Jack";
+		gpio_name	= "Mic detection";
+		mask		= SND_JACK_MICROPHONE;
+	}
+
+	det = of_get_named_gpio_flags(node, prop, 0, &flags);
+	if (det == -EPROBE_DEFER)
+		return -EPROBE_DEFER;
+
+	if (gpio_is_valid(det)) {
+		sjack->pin.pin		= pin_name;
+		sjack->pin.mask		= mask;
+
+		sjack->gpio.name	= gpio_name;
+		sjack->gpio.report	= mask;
+		sjack->gpio.gpio	= det;
+		sjack->gpio.invert	= !!(flags & OF_GPIO_ACTIVE_LOW);
+		sjack->gpio.debounce_time = 150;
+
+		snd_soc_card_jack_new(card, pin_name, mask,
+				      &sjack->jack,
+				      &sjack->pin, 1);
+
+		snd_soc_jack_add_gpios(&sjack->jack, 1,
+				       &sjack->gpio);
+	}
+
+	return 0;
+}
+
+static void asoc_simple_card_remove_jack(struct asoc_simple_jack *sjack)
+{
+	if (gpio_is_valid(sjack->gpio.gpio))
+		snd_soc_jack_free_gpios(&sjack->jack, 1, &sjack->gpio);
+}
+
+static int asoc_simple_card_startup(struct snd_pcm_substream *substream)
+{
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct simple_card_data *priv =	snd_soc_card_get_drvdata(rtd->card);
+	struct simple_dai_props *dai_props =
+		simple_priv_to_props(priv, rtd->num);
+	int ret;
+
+	ret = clk_prepare_enable(dai_props->cpu_dai.clk);
+	if (ret)
+		return ret;
+
+	ret = clk_prepare_enable(dai_props->codec_dai.clk);
+	if (ret)
+		clk_disable_unprepare(dai_props->cpu_dai.clk);
+
+	return ret;
+}
+
+static void asoc_simple_card_shutdown(struct snd_pcm_substream *substream)
+{
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct simple_card_data *priv =	snd_soc_card_get_drvdata(rtd->card);
+	struct simple_dai_props *dai_props =
+		simple_priv_to_props(priv, rtd->num);
+
+	clk_disable_unprepare(dai_props->cpu_dai.clk);
+
+	clk_disable_unprepare(dai_props->codec_dai.clk);
+}
+
+static int asoc_simple_card_hw_params(struct snd_pcm_substream *substream,
+				      struct snd_pcm_hw_params *params)
+{
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct snd_soc_dai *codec_dai = rtd->codec_dai;
+	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+	struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
+	struct simple_dai_props *dai_props =
+		simple_priv_to_props(priv, rtd->num);
+	unsigned int mclk, mclk_fs = 0;
+	int ret = 0;
+
+	if (priv->mclk_fs)
+		mclk_fs = priv->mclk_fs;
+	else if (dai_props->mclk_fs)
+		mclk_fs = dai_props->mclk_fs;
+
+	if (mclk_fs) {
+		mclk = params_rate(params) * mclk_fs;
+		ret = snd_soc_dai_set_sysclk(codec_dai, 0, mclk,
+					     SND_SOC_CLOCK_IN);
+		if (ret && ret != -ENOTSUPP)
+			goto err;
+
+		ret = snd_soc_dai_set_sysclk(cpu_dai, 0, mclk,
+					     SND_SOC_CLOCK_OUT);
+		if (ret && ret != -ENOTSUPP)
+			goto err;
+	}
+	return 0;
+err:
+	return ret;
+}
+
+static struct snd_soc_ops asoc_simple_card_ops = {
+	.startup = asoc_simple_card_startup,
+	.shutdown = asoc_simple_card_shutdown,
+	.hw_params = asoc_simple_card_hw_params,
+};
+
+static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd)
+{
+	struct simple_card_data *priv =	snd_soc_card_get_drvdata(rtd->card);
+	struct device *dev = simple_priv_to_dev(priv);
+	struct device *cpu_dev = dev->parent;
+	struct snd_soc_dai *codec = rtd->codec_dai;
+	struct snd_soc_dai *cpu = rtd->cpu_dai;
+	struct snd_soc_card *card = rtd->card;
+	struct simple_dai_props *dai_props =
+		simple_priv_to_props(priv, rtd->num);
+	struct device_node *cpu_port = of_graph_get_top_port(cpu_dev);
+	int ret;
+
+	ret = asoc_simple_card_init_dai(codec, &dai_props->codec_dai);
+	if (ret < 0)
+		return ret;
+
+	ret = asoc_simple_card_init_dai(cpu, &dai_props->cpu_dai);
+	if (ret < 0)
+		return ret;
+
+	ret = asoc_simple_card_init_hp(card, cpu_port, &priv->hp_jack, PREFIX);
+	if (ret < 0)
+		return ret;
+
+	ret = asoc_simple_card_init_mic(card, cpu_port, &priv->hp_jack, PREFIX);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static int asoc_simple_card_dai_link_of(struct device_node *cpu_ep,
+					struct simple_card_data *priv,
+					int idx)
+{
+	struct device *dev = simple_priv_to_dev(priv);
+	struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, idx);
+	struct simple_dai_props *dai_props = simple_priv_to_props(priv, idx);
+	struct asoc_simple_dai *cpu_dai = &dai_props->cpu_dai;
+	struct asoc_simple_dai *codec_dai = &dai_props->codec_dai;
+	struct device_node *cpu_port;
+	struct device_node *cpu_remote_ep;
+	struct device_node *codec_ep;
+	int ret;
+
+	codec_ep	= of_graph_get_remote_endpoint(cpu_ep);
+	cpu_remote_ep	= of_graph_get_remote_endpoint(codec_ep);
+
+	if (cpu_ep != cpu_remote_ep) {
+		dev_err(dev, "endpoint parse error\n");
+		ret = -EINVAL;
+		goto dai_link_of_err;
+	}
+
+	cpu_port	= cpu_ep->parent;
+
+	ret = asoc_simple_card_parse_daifmt(dev, cpu_port, codec_ep,
+					    PREFIX, &dai_link->dai_fmt);
+	if (ret < 0)
+		goto dai_link_of_err;
+
+	of_property_read_u32(cpu_port, "mclk-fs", &dai_props->mclk_fs);
+
+	ret = asoc_simple_card_parse_graph_cpu(cpu_ep, dai_link);
+	if (ret < 0)
+		goto dai_link_of_err;
+
+	ret = asoc_simple_card_parse_graph_codec(codec_ep, dai_link);
+	if (ret < 0)
+		goto dai_link_of_err;
+
+	ret = snd_soc_of_parse_tdm_slot(cpu_ep,
+					&cpu_dai->tx_slot_mask,
+					&cpu_dai->rx_slot_mask,
+					&cpu_dai->slots,
+					&cpu_dai->slot_width);
+	if (ret < 0)
+		goto dai_link_of_err;
+
+	ret = snd_soc_of_parse_tdm_slot(codec_ep,
+					&codec_dai->tx_slot_mask,
+					&codec_dai->rx_slot_mask,
+					&codec_dai->slots,
+					&codec_dai->slot_width);
+	if (ret < 0)
+		goto dai_link_of_err;
+
+	ret = asoc_simple_card_parse_clk_cpu(cpu_ep, dai_link, cpu_dai);
+	if (ret < 0)
+		goto dai_link_of_err;
+
+	ret = asoc_simple_card_parse_clk_codec(codec_ep, dai_link, codec_dai);
+	if (ret < 0)
+		goto dai_link_of_err;
+
+	ret = asoc_simple_card_canonicalize_dailink(dai_link);
+	if (ret < 0)
+		goto dai_link_of_err;
+
+	ret = asoc_simple_card_set_dailink_name(dev, dai_link,
+						"%s-%s",
+						dai_link->cpu_dai_name,
+						dai_link->codec_dai_name);
+	if (ret < 0)
+		goto dai_link_of_err;
+
+	dai_link->ops = &asoc_simple_card_ops;
+	dai_link->init = asoc_simple_card_dai_init;
+
+	dev_dbg(dev, "\tname : %s\n", dai_link->stream_name);
+	dev_dbg(dev, "\tformat : %04x\n", dai_link->dai_fmt);
+	dev_dbg(dev, "\tcpu : %s / %d\n",
+		dai_link->cpu_dai_name,
+		dai_props->cpu_dai.sysclk);
+	dev_dbg(dev, "\tcodec : %s / %d\n",
+		dai_link->codec_dai_name,
+		dai_props->codec_dai.sysclk);
+
+	asoc_simple_card_canonicalize_cpu(dai_link,
+					  priv->snd_card.num_links == 1);
+
+dai_link_of_err:
+	of_node_put(codec_ep);
+	of_node_put(cpu_remote_ep);
+
+	return ret;
+}
+
+static int asoc_simple_card_parse_of(struct device_node *node,
+				     struct simple_card_data *priv)
+{
+	struct device *dev = simple_priv_to_dev(priv);
+	struct device *cpu_dev = dev->parent;
+	struct device_node *top_port = of_graph_get_top_port(cpu_dev);
+	struct snd_soc_card *card = &priv->snd_card;
+	struct device_node *port, *ep;
+	int i = 0, ret;
+
+	if (!node)
+		return -EINVAL;
+
+	for_each_of_port(node, port) {
+		if (!of_graph_port_type_is_sound(port))
+			continue;
+
+		/* The off-codec widgets */
+		if (of_property_read_bool(port, PREFIX "widgets")) {
+			ret = snd_soc_of_parse_audio_simple_widgets_from_node(
+				&priv->snd_card,
+				port, PREFIX "widgets");
+			if (ret)
+				return ret;
+		}
+
+		/* DAPM routes */
+		if (of_property_read_bool(port, PREFIX "routing")) {
+			ret = snd_soc_of_parse_audio_routing_from_node(
+				&priv->snd_card,
+				port, PREFIX "routing");
+			if (ret)
+				return ret;
+		}
+
+		/* Factor to mclk, used in hw_params() */
+		of_property_read_u32(port, PREFIX "mclk-fs", &priv->mclk_fs);
+
+		for_each_of_endpoint_in_port(port, ep) {
+			ret = asoc_simple_card_dai_link_of(ep, priv, i);
+			if (ret < 0) {
+				of_node_put(ep);
+				return ret;
+			}
+			i++;
+		}
+	}
+
+	ret = asoc_simple_card_parse_card_name(card, top_port, PREFIX);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int asoc_simple_card_probe(struct platform_device *pdev)
+{
+	struct simple_card_data *priv;
+	struct snd_soc_dai_link *dai_link;
+	struct simple_dai_props *dai_props;
+	struct device *dev = &pdev->dev;
+	struct device *cpu_dev = pdev->dev.parent;
+	struct device_node *cpu_node = cpu_dev->of_node;
+	int num, ret;
+
+	/* Allocate the private data and the DAI link array */
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	num = of_graph_get_sound_endpoint_count(cpu_node);
+
+	dai_props = devm_kzalloc(dev, sizeof(*dai_props) * num, GFP_KERNEL);
+	dai_link  = devm_kzalloc(dev, sizeof(*dai_link)  * num, GFP_KERNEL);
+	if (!dai_props || !dai_link)
+		return -ENOMEM;
+
+	priv->dai_props			= dai_props;
+	priv->dai_link			= dai_link;
+
+	/* Init snd_soc_card */
+	priv->snd_card.owner		= THIS_MODULE;
+	priv->snd_card.dev		= dev;
+	priv->snd_card.dai_link		= priv->dai_link;
+	priv->snd_card.num_links	= num;
+
+	ret = asoc_simple_card_parse_of(cpu_node, priv);
+	if (ret < 0) {
+		if (ret != -EPROBE_DEFER)
+			dev_err(dev, "parse error %d\n", ret);
+		goto err;
+	}
+
+	/*
+	 * FIXME
+	 *
+	 * This driver is assuming that it will be called from
+	 * asoc_simple_card_try_to_probe_graph_card() which
+	 * is using platform_device_register_full().
+	 * This means it is not came from DT. But this driver itself
+	 * will be used as part of ALSA SoC (= sound card).
+	 * Because of these background, it might fail in
+	 * snd_pcm_lib_malloc_pages() on .hw_params.
+	 * Because, noone cares its dma_ops, and result of get_dma_ops()
+	 * is based on its architecture.
+	 * So, it should call arch_setup_dma_ops() from somewhere,
+	 * otherwise, for example, ARM is no problem, but ARM64 will be fail.
+	 * But, of_platform_device_xxx() are not good solution today.
+	 * This driver calls it by itself here. Please fixme
+	 * see also
+	 * linux/sound/soc/generic/simple-card-utils.c ::
+	 *	asoc_simple_card_try_to_probe_graph_card()
+	 */
+	of_dma_configure(dev, dev->of_node);
+
+	snd_soc_card_set_drvdata(&priv->snd_card, priv);
+
+	ret = devm_snd_soc_register_card(dev, &priv->snd_card);
+	if (ret >= 0)
+		return ret;
+err:
+	asoc_simple_card_clean_reference(&priv->snd_card);
+
+	return ret;
+}
+
+static int asoc_simple_card_remove(struct platform_device *pdev)
+{
+	struct snd_soc_card *card = platform_get_drvdata(pdev);
+	struct simple_card_data *priv = snd_soc_card_get_drvdata(card);
+
+	asoc_simple_card_remove_jack(&priv->hp_jack);
+	asoc_simple_card_remove_jack(&priv->mic_jack);
+
+	return asoc_simple_card_clean_reference(&priv->snd_card);
+}
+
+static struct platform_driver asoc_simple_card = {
+	.driver = {
+		.name = "asoc-simple-graph-card",
+	},
+	.probe = asoc_simple_card_probe,
+	.remove = asoc_simple_card_remove,
+};
+module_platform_driver(asoc_simple_card);
+
+MODULE_ALIAS("platform:asoc-simple-graph-card");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("ASoC Simple Graph Sound Card");
+MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
-- 
1.9.1

^ permalink raw reply related

* [PATCH v5 11/14] ASoC: add simple-graph-card document
From: Kuninori Morimoto @ 2016-11-28  2:47 UTC (permalink / raw)
  To: Rob Herring, Mark Brown
  Cc: Linux-ALSA, Liam Girdwood, Simon, Laurent, Guennadi, Grant Likely,
	Frank Rowand, Linux-DT, Linux-Kernel
In-Reply-To: <87k2bowckx.wl%kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>


From: Kuninori Morimoto <kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
---
 .../bindings/sound/simple-graph-card.txt           | 67 ++++++++++++++++++++++
 1 file changed, 67 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/simple-graph-card.txt

diff --git a/Documentation/devicetree/bindings/sound/simple-graph-card.txt b/Documentation/devicetree/bindings/sound/simple-graph-card.txt
new file mode 100644
index 0000000..3d4c5a8
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/simple-graph-card.txt
@@ -0,0 +1,67 @@
+Simple-Graph-Card:
+
+Simple-Graph-Card specifies audio DAI connections of SoC <-> codec.
+It is based on common bindings for device graphs.
+see ${LINUX}/Documentation/devicetree/bindings/graph.txt
+
+Basically, Simple-Graph-Card property is same as Simple-Card.
+see ${LINUX}/Documentation/devicetree/bindings/sound/simple-card.txt
+
+Below are same as Simple-Card.
+
+- simple-audio-card,name
+- simple-audio-card,widgets
+- simple-audio-card,routing
+- simple-audio-card,mclk-fs
+- simple-audio-card,hp-det-gpio
+- simple-audio-card,mic-det-gpio
+- simple-audio-card,format
+- simple-audio-card,frame-master
+- simple-audio-card,bitclock-master
+- simple-audio-card,bitclock-inversion
+- simple-audio-card,frame-inversion
+- simple-audio-card,mclk-fs
+- simple-audio-card,dai-tdm-slot-num
+- simple-audio-card,dai-tdm-slot-width
+- clocks / system-clock-frequency
+
+In Simple-Graph-Card, above properties need in CPU side port on DT.
+And it needs to have "compatible" property too.
+In addition, CPU side driver needs to call asoc_simple_card_try_to_probe_graph_card().
+It will probe specified Card driver if it could find "compatible" property on port.
+Otherwise, it will do nothing.
+
+Required properties:
+
+- compatible				: "asoc-simple-graph-card";
+- type					: "sound";
+
+Example
+
+ak4643: codec@12 {
+	compatible = "asahi-kasei,ak4643";
+	...
+	port {
+		type = "sound";
+		ak4643_port: endpoint {
+			remote-endpoint = <&rcar_ak4643_port>;
+			...
+		};
+	};
+};
+
+rcar_sound {
+	...
+	port {
+		compatible = "asoc-simple-graph-card";
+
+		simple-audio-card,format = "left_j";
+		simple-audio-card,bitclock-master = <&ak4643_port>;
+		simple-audio-card,frame-master = <&ak4643_port>;
+		type = "sound";
+		rcar_ak4643_port: endpoint {
+			remote-endpoint = <&ak4643_port>;
+			...
+		};
+	};
+};
-- 
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 v5 10/14] ASoC: simple-card-utils: add asoc_simple_card_try_to_probe_graph_card()
From: Kuninori Morimoto @ 2016-11-28  2:47 UTC (permalink / raw)
  To: Rob Herring, Mark Brown
  Cc: Linux-ALSA, Liam Girdwood, Simon, Laurent, Guennadi, Grant Likely,
	Frank Rowand, Linux-DT, Linux-Kernel
In-Reply-To: <87k2bowckx.wl%kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>

From: Kuninori Morimoto <kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>

If CPU/Platform side driver probes successfully, and if it is supporting
both previous normal sound card style and graph style DT, it can call
asoc_simple_card_try_to_probe_graph_card().
It checks graph style DT, and do nothing if it was non graph style DT,
or register new simple-graph-card driver if graph style DT.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
---
 include/sound/simple_card_utils.h     |  2 ++
 sound/soc/generic/simple-card-utils.c | 42 +++++++++++++++++++++++++++++++++++
 2 files changed, 44 insertions(+)

diff --git a/include/sound/simple_card_utils.h b/include/sound/simple_card_utils.h
index c223f79..276e8e4 100644
--- a/include/sound/simple_card_utils.h
+++ b/include/sound/simple_card_utils.h
@@ -79,4 +79,6 @@ void asoc_simple_card_canonicalize_cpu(struct snd_soc_dai_link *dai_link,
 
 int asoc_simple_card_clean_reference(struct snd_soc_card *card);
 
+void asoc_simple_card_try_to_probe_graph_card(struct device *dev);
+
 #endif /* __SIMPLE_CARD_CORE_H */
diff --git a/sound/soc/generic/simple-card-utils.c b/sound/soc/generic/simple-card-utils.c
index 527944d..fdf7d5e 100644
--- a/sound/soc/generic/simple-card-utils.c
+++ b/sound/soc/generic/simple-card-utils.c
@@ -8,6 +8,7 @@
  * published by the Free Software Foundation.
  */
 #include <linux/clk.h>
+#include <linux/dma-mapping.h>
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/of_graph.h>
@@ -292,6 +293,47 @@ int asoc_simple_card_clean_reference(struct snd_soc_card *card)
 }
 EXPORT_SYMBOL_GPL(asoc_simple_card_clean_reference);
 
+void asoc_simple_card_try_to_probe_graph_card(struct device *dev)
+{
+	struct platform_device_info pdevinfo;
+	struct device_node *node;
+	const char *compatible;
+	int ret;
+
+	node = of_graph_get_top_port(dev);
+	if (!node)
+		/*
+		 * It doesn't have graph base sound DT.
+		 * Do nothing here, It assumes that system has
+		 * normal sound card.
+		 */
+		return;
+
+	ret = of_property_read_string(node, "compatible", &compatible);
+	if (ret < 0)
+		goto probe_err;
+
+	/*
+	 * FIXME
+	 *
+	 * It should use of_platform_xxx() instead of
+	 * platform_device_register_full() ? but there is no solution.
+	 * see also
+	 * linux/sound/soc/generic/simple-graph-card.c :: asoc_simple_card_probe
+	 */
+
+	memset(&pdevinfo, 0, sizeof(pdevinfo));
+	pdevinfo.parent		= dev;
+	pdevinfo.id		= PLATFORM_DEVID_AUTO;
+	pdevinfo.name		= compatible;
+	pdevinfo.dma_mask	= DMA_BIT_MASK(32);
+	platform_device_register_full(&pdevinfo);
+
+probe_err:
+	of_node_put(node);
+}
+EXPORT_SYMBOL_GPL(asoc_simple_card_try_to_probe_graph_card);
+
 /* Module information */
 MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>");
 MODULE_DESCRIPTION("ALSA SoC Simple Card Utils");
-- 
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 v5 09/14] ASoC: simple-card-utils: add asoc_simple_card_parse_graph_dai()
From: Kuninori Morimoto @ 2016-11-28  2:47 UTC (permalink / raw)
  To: Rob Herring, Mark Brown
  Cc: Linux-ALSA, Liam Girdwood, Simon, Laurent, Guennadi, Grant Likely,
	Frank Rowand, Linux-DT, Linux-Kernel
In-Reply-To: <87k2bowckx.wl%kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>

From: Kuninori Morimoto <kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>

simple-card already has asoc_simple_card_parse_dai(),
but graph base parsing needs graph specific version of it.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
---
 include/sound/simple_card_utils.h     | 10 +++++++
 sound/soc/generic/simple-card-utils.c | 53 +++++++++++++++++++++++++++++++++++
 2 files changed, 63 insertions(+)

diff --git a/include/sound/simple_card_utils.h b/include/sound/simple_card_utils.h
index 09750ac..c223f79 100644
--- a/include/sound/simple_card_utils.h
+++ b/include/sound/simple_card_utils.h
@@ -60,6 +60,16 @@ int asoc_simple_card_parse_dai(struct device_node *node,
 				  const char *cells_name,
 				  int *is_single_links);
 
+#define asoc_simple_card_parse_graph_cpu(ep, dai_link)			\
+	asoc_simple_card_parse_graph_dai(ep, &dai_link->cpu_of_node,	\
+					 &dai_link->cpu_dai_name)
+#define asoc_simple_card_parse_graph_codec(ep, dai_link)		\
+	asoc_simple_card_parse_graph_dai(ep, &dai_link->codec_of_node,	\
+					 &dai_link->codec_dai_name)
+int asoc_simple_card_parse_graph_dai(struct device_node *ep,
+				     struct device_node **endpoint_np,
+				     const char **dai_name);
+
 int asoc_simple_card_init_dai(struct snd_soc_dai *dai,
 			      struct asoc_simple_dai *simple_dai);
 
diff --git a/sound/soc/generic/simple-card-utils.c b/sound/soc/generic/simple-card-utils.c
index 003331e..527944d 100644
--- a/sound/soc/generic/simple-card-utils.c
+++ b/sound/soc/generic/simple-card-utils.c
@@ -10,6 +10,7 @@
 #include <linux/clk.h>
 #include <linux/module.h>
 #include <linux/of.h>
+#include <linux/of_graph.h>
 #include <sound/simple_card_utils.h>
 
 int asoc_simple_card_parse_daifmt(struct device *dev,
@@ -165,6 +166,58 @@ int asoc_simple_card_parse_dai(struct device_node *node,
 }
 EXPORT_SYMBOL_GPL(asoc_simple_card_parse_dai);
 
+int asoc_simple_card_parse_graph_dai(struct device_node *ep,
+				     struct device_node **dai_of_node,
+				     const char **dai_name)
+{
+	struct device_node *node, *port, *endpoint;
+	int i, id;
+
+	if (!ep)
+		return 0;
+
+	/*
+	 * of_graph_get_port_parent() will call
+	 * of_node_put(). So, call of_node_get() here
+	 */
+	of_node_get(ep);
+	node = of_graph_get_port_parent(ep);
+
+	i = 0;
+	id = -1;
+	for_each_of_port(node, port) {
+		if (!of_graph_port_type_is_sound(port))
+			continue;
+
+		for_each_of_endpoint_in_port(port, endpoint) {
+			if (endpoint == ep)
+				id = i;
+			i++;
+		}
+	}
+	if (id < 0)
+		return -ENODEV;
+
+	/* Get dai->name */
+	if (dai_name) {
+		struct of_phandle_args args;
+		int ret;
+
+		args.np		= node;
+		args.args[0]	= id;
+		args.args_count	= (i > 1);
+
+		ret = snd_soc_get_dai_name(&args, dai_name);
+		if (ret < 0)
+			return ret;
+	}
+
+	*dai_of_node = node;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(asoc_simple_card_parse_graph_dai);
+
 int asoc_simple_card_init_dai(struct snd_soc_dai *dai,
 			      struct asoc_simple_dai *simple_dai)
 {
-- 
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 v5 08/14] ASoC: simple-card-utils: adjust for graph on asoc_simple_card_parse_card_name
From: Kuninori Morimoto @ 2016-11-28  2:46 UTC (permalink / raw)
  To: Rob Herring, Mark Brown
  Cc: Linux-ALSA, Liam Girdwood, Simon, Laurent, Guennadi, Grant Likely,
	Frank Rowand, Linux-DT, Linux-Kernel
In-Reply-To: <87k2bowckx.wl%kuninori.morimoto.gx@renesas.com>

From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>

It is assuming that the card related information is located on
"card" node, but graph case doesn't have it.
This patch adds node parameter to adjust for graph support

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
 include/sound/simple_card_utils.h     | 1 +
 sound/soc/generic/simple-card-utils.c | 3 ++-
 sound/soc/generic/simple-card.c       | 2 +-
 sound/soc/generic/simple-scu-card.c   | 2 +-
 4 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/include/sound/simple_card_utils.h b/include/sound/simple_card_utils.h
index fd641255..09750ac 100644
--- a/include/sound/simple_card_utils.h
+++ b/include/sound/simple_card_utils.h
@@ -32,6 +32,7 @@ int asoc_simple_card_set_dailink_name(struct device *dev,
 				      struct snd_soc_dai_link *dai_link,
 				      const char *fmt, ...);
 int asoc_simple_card_parse_card_name(struct snd_soc_card *card,
+				     struct device_node *node,
 				     char *prefix);
 
 #define asoc_simple_card_parse_clk_cpu(node, dai_link, simple_dai)		\
diff --git a/sound/soc/generic/simple-card-utils.c b/sound/soc/generic/simple-card-utils.c
index 1cb3930..003331e 100644
--- a/sound/soc/generic/simple-card-utils.c
+++ b/sound/soc/generic/simple-card-utils.c
@@ -79,6 +79,7 @@ int asoc_simple_card_set_dailink_name(struct device *dev,
 EXPORT_SYMBOL_GPL(asoc_simple_card_set_dailink_name);
 
 int asoc_simple_card_parse_card_name(struct snd_soc_card *card,
+				     struct device_node *node,
 				     char *prefix)
 {
 	char prop[128];
@@ -87,7 +88,7 @@ int asoc_simple_card_parse_card_name(struct snd_soc_card *card,
 	snprintf(prop, sizeof(prop), "%sname", prefix);
 
 	/* Parse the card name from DT */
-	ret = snd_soc_of_parse_card_name(card, prop);
+	ret = snd_soc_of_parse_card_name_from_node(card, node, prop);
 	if (ret < 0)
 		return ret;
 
diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c
index f608f8d2..342ff53 100644
--- a/sound/soc/generic/simple-card.c
+++ b/sound/soc/generic/simple-card.c
@@ -401,7 +401,7 @@ static int asoc_simple_card_parse_of(struct device_node *node,
 			goto card_parse_end;
 	}
 
-	ret = asoc_simple_card_parse_card_name(&priv->snd_card, PREFIX);
+	ret = asoc_simple_card_parse_card_name(&priv->snd_card, NULL, PREFIX);
 	if (ret < 0)
 		goto card_parse_end;
 
diff --git a/sound/soc/generic/simple-scu-card.c b/sound/soc/generic/simple-scu-card.c
index b9973a5..129dd8f 100644
--- a/sound/soc/generic/simple-scu-card.c
+++ b/sound/soc/generic/simple-scu-card.c
@@ -272,7 +272,7 @@ static int asoc_simple_card_parse_of(struct device_node *node,
 	if (ret < 0)
 		return ret;
 
-	ret = asoc_simple_card_parse_card_name(&priv->snd_card, PREFIX);
+	ret = asoc_simple_card_parse_card_name(&priv->snd_card, NULL, PREFIX);
 	if (ret < 0)
 		return ret;
 
-- 
1.9.1

^ permalink raw reply related

* [PATCH v5 07/14] of_graph: add of_graph_get_endpoint_count()
From: Kuninori Morimoto @ 2016-11-28  2:46 UTC (permalink / raw)
  To: Rob Herring, Mark Brown
  Cc: Linux-ALSA, Liam Girdwood, Simon, Laurent, Guennadi, Grant Likely,
	Frank Rowand, Linux-DT, Linux-Kernel
In-Reply-To: <87k2bowckx.wl%kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>


From: Kuninori Morimoto <kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>

OF graph want to count its endpoint number, same as
of_get_child_count(). This patch adds of_graph_get_endpoint_count()
which can check specific type. It will count all endpoint if type
was NULL.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
---
 drivers/of/base.c        | 16 ++++++++++++++++
 include/linux/of_graph.h |  8 ++++++++
 2 files changed, 24 insertions(+)

diff --git a/drivers/of/base.c b/drivers/of/base.c
index 705ea15..76d2819 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -2596,3 +2596,19 @@ bool of_graph_port_type_is(struct device_node *port, char *type)
 	return false;
 }
 EXPORT_SYMBOL(of_graph_port_type_is);
+
+int of_graph_get_endpoint_count(const struct device_node *np, char *type)
+{
+	struct device_node *port, *endpoint;
+	int num = 0;
+
+	for_each_of_endpoint(np, port, endpoint) {
+		if (!type)
+			num++;
+		else
+			num += of_graph_port_type_is(port, type);
+	}
+
+	return num;
+}
+EXPORT_SYMBOL(of_graph_get_endpoint_count);
diff --git a/include/linux/of_graph.h b/include/linux/of_graph.h
index 7f735f8..826752f 100644
--- a/include/linux/of_graph.h
+++ b/include/linux/of_graph.h
@@ -52,11 +52,13 @@ struct of_endpoint {
 	     child = of_graph_get_next_endpoint(parent, child))
 
 #define of_graph_port_type_is_sound(n)		of_graph_port_type_is(n, "sound")
+#define of_graph_get_sound_endpoint_count(n)	of_graph_get_endpoint_count(n, "sound")
 
 #ifdef CONFIG_OF
 int of_graph_parse_endpoint(const struct device_node *node,
 				struct of_endpoint *endpoint);
 bool of_graph_port_type_is(struct device_node *port, char *type);
+int of_graph_get_endpoint_count(const struct device_node *np, char *type);
 struct device_node *of_graph_get_port_by_id(struct device_node *node, u32 id);
 struct device_node *of_graph_get_top_port(struct device *dev);
 struct device_node *of_graph_get_next_port(const struct device_node *parent,
@@ -87,6 +89,12 @@ static bool of_graph_port_type_is(struct device_node *port, char *type)
 	return false;
 }
 
+static inline int of_graph_get_endpoint_count(const struct device_node *np,
+					      char *type)
+{
+	return 0;
+}
+
 static inline struct device_node *of_graph_get_port_by_id(
 					struct device_node *node, u32 id)
 {
-- 
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


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