Devicetree
 help / color / mirror / Atom feed
* Re: Re: [PATCH v2 03/11] dt-bindings: add device tree binding for X-Powers AXP803 PMIC
From: Lee Jones @ 2017-04-11 16:29 UTC (permalink / raw)
  To: Chen-Yu Tsai
  Cc: Icenowy Zheng, devicetree, linux-kernel, linux-sunxi,
	Liam Girdwood, Rob Herring, Maxime Ripard, linux-arm-kernel
In-Reply-To: <CAGb2v65UiFqjYES3hF-S6THZ5Xu-HRS9R7Ngk8xeP1rZajsr7w-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>

On Tue, 11 Apr 2017, Chen-Yu Tsai wrote:

> Hi,
> 
> On Tue, Apr 11, 2017 at 11:00 PM, Icenowy Zheng <icenowy-h8G6r0blFSE@public.gmane.org> wrote:
> >
> >
> > On Tue, 11 Apr 2017, Lee Jones wrote:
> >
> >> On Sat, 08 Apr 2017, Icenowy Zheng wrote:
> >>
> >>> AXP803 is a PMIC produced by Shenzhen X-Powers, with either I2C or RSB
> >>> bus.
> >>>
> >>> Add a compatible for it.
> >>>
> >>> Signed-off-by: Icenowy Zheng <icenowy-h8G6r0blFSE@public.gmane.org>
> >>> Acked-by: Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>
> >>> ---
> >>> Changes in v2:
> >>> - Place AXP803 before AXP806/809.
> >>> - Added Chen-Yu's ACK.
> >>>
> >>>  Documentation/devicetree/bindings/mfd/axp20x.txt | 5 +++--
> >>>  1 file changed, 3 insertions(+), 2 deletions(-)
> >>
> >>
> >> For my own reference:
> >>  Acked-for-MFD-by: Lee Jones <lee.jones-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> >
> >
> > Excuse me... Who will apply this patch?

Excuse you?  Are you trying to be polite, or rude?

I'm guessing due to the lagging '...', that it's the latter?

> > I think this patch should be applied by you as it's in bindings/mfd
> > directory, however, if I'm wrong, please point out ;-)
>
> We need the DT maintainers to ack it first. :)

We don't really need the DT Maintainers to get involved here.

What I do need is either clear direction as to how this
patch-set should be applied, or an indication of which patches are
dependant on others and which are orthogonal and can be applied
independently.

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

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

^ permalink raw reply

* Re: [PATCH] drm/panel: simple: Add support for Seiko 43WVF1G
From: Rob Herring @ 2017-04-11 16:36 UTC (permalink / raw)
  To: Fabio Estevam
  Cc: Thierry Reding, Breno Lima, Shawn Guo, David Airlie, Mark Rutland,
	DRI mailing list,
	devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	Breno Matheus Lima, Fabio Estevam
In-Reply-To: <CAOMZO5C21w9eGbFciZn3PEdB14eqPJ0dwbtVw=F4dTafyng0aQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>

On Sat, Apr 8, 2017 at 3:45 PM, Fabio Estevam <festevam-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
> Thierry/Rob,
>
> On Tue, Feb 7, 2017 at 10:48 PM, Fabio Estevam <festevam-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
>> On Tue, Feb 7, 2017 at 9:36 PM, Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> wrote:
>>
>>> Except I have no way of knowing whether: a) you omitted a supply
>>> because you don't (yet) care, b) the panel has a single supply and you
>>> are using power-supply or c) the panel has multiple supplies and your
>>> binding is wrong.
>>>
>>> I can only eliminate A if you list the supplies. Just need something
>>> like "power-supply : see simple-panel.txt". I've still got to go read
>>> the panel spec if I really want to check the binding.
>>
>> Just checked the panel datasheet at
>> http://www.glyn.de/data/glyn/media/doc/43wvf1g-0.pdf and it lists two
>> supplies:
>> DVDD (Digital power supply) and AVDD (Analog power supply).
>>
>> Our dts was just providing a single 'power-supply' which referred to a
>> GPIO enabled regulator that drives DVDD.
>>
>> So it seems we missed to pass AVDD (not software controlled in our
>> case, but we need to describe it in dts anyway).
>>
>> Does this mean we cannot use simple-panel for this particular panel
>> and we should add a separate driver for it?
>
> Please confirm if we need to create a separate driver for this panel, thanks.

The binding should list both. They can be optional though. Maybe you
can parameterize the supply name in the driver for the single
(controlled) supply case. Or provide power on/off hooks.

Rob
--
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 4/5] mtd: nand: add support for Micron on-die ECC
From: Bean Huo (beanhuo) @ 2017-04-11 17:01 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: Thomas Petazzoni,
	devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	pawel.moll-5wv7dgnIgG8@public.gmane.org, Campbell,
	richard-/L3Ra7n9ekc@public.gmane.org, Mark Rutland,
	marek.vasut-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org, Rob Herring,
	linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
	galak-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org, Cyrille Pitchen,
	computersforpeace-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org
In-Reply-To: <20170411173051.7aafb717@bbrezillon>

>On Tue, 11 Apr 2017 15:02:22 +0000
>"Bean Huo (beanhuo)" <beanhuo-AL4WhLSQfzjQT0dZR+AlfA@public.gmane.org> wrote:
>
>> Hi, Boris and Thomas
>> Let me do some explanation.
>>
>> >> if (NAND == SLC ) { // on-die ECC only exists in SLC //check device
>> >> ID byte 4
>> >>      if ((ID.byte4 & 0x02) == 0x02) {// internal ECC level ==10b
>> >
>> >So here the MT29F1G08ABADAWP datasheet says 0x2 <=> 4bit/512bytes ECC.
>> >
>>
>> If the NAND supports on-die ECC, here should be 10b, not matter it is
>> 8bit or 4bit, You are correct, MT29F1G08ABADAWP is 0x2, its explanation is
>4bit/512bytes ECC.
>> But for the 70s, it is 8bit on-die ECC, but it is still 10b.
>> So that why here using these two bits to determine if exist on-die ECC.
>> What's more, for some old products, they don't support on-die ECC,
>> Sometimes, here is still 01b, so still need following codes to do
>> further determinations.
>
>Okay, then here is the differentiator. Did you check that on SLC NANDs there's no
>collision on ID[4].bits[1:0]. I've seen NAND vendors changing their ID scheme in
>incompatible ways (old fields were replaced by new ones with completely
>different meanings).


Yes, this is true, there is no one standard to define and formalize ID.byte4,
It is always changing. Also, sometimes it definitely conflicts with other NAND without
On-die ECC. For the Micron both serials SLC NAND with on-die ECC, bits[1:0] is defined
Internal ECC level. 

>I'd really like to make sure we're not mis-interpreting READ_ID information, so
>maybe we should restrict the test on ONFI NANDs if all NANDs supporting on-die
>ECC are ONFI compliant. We should probably also check that chip->id.len >= 5.
>
>
>>
>> >> 	if (ID.byte4 & 0x80) {//on-Die ECC enabled
>> >
>> >Did you read my last reply?
>> >Thomas discovered that ID[4].bit7 is actually reflecting the ECC
>> >engine state (1 if the engine is enabled, 0 if it's disabled), not
>> >whether the NAND supports on-die ECC or not, so no this test is not reliable.
>> >
>> For the on-die ECC, it is not always default enabled. It depends on requirement
>from costumers.
>> If on-die ECC is not enabled, bit7 is 0. It can be switched through "Feature
>Operations".
>
>So this check is not needed, right?

Here is much complicated. One question is that what main purpose of on-die ECC.
there are two types of usage model:
1.  on-die ECC default enabled:
Normally before bootloader and kernel, there is no any ECC to correct and maintain
Bootloader reliability.  For this kind of customer, I think, they mainly want to have reliable booting.
Rather than for store user data. Per this kind of condition, we don't check, because on-die ECC
Always be enabled, cannot be disabled.

2. on-die ECC default disabled:
I think this is used for some important user data. Unless the bootrom of CPU can issue 
SET_FEATURE to enable on-die ECC, and until Linux running, on-die ECC is still enabled.
Otherwise, we need to check if it enables or not.

>BTW, do you have NANDs where the on-die ECC is always enabled, and if this is
>the case, what happens when you call
>SET_FEATURE(disable/enable-ECC) on these NANDs?

If this NAND is on-die ECC defaulted enabled, the on-die ECC cannot
Disabled later. Why? This is related to specific user model.
We have one PPT on Micron domain website, it is "on die ECC training",
It opens and can freely download. It clearly describes this.
If you cannot download, please let me know, I send to you.

As for the on-die ECC default disabled, you can freely switch on or off
by SET_FEATURE(disable/enable-ECC).

>
>>
>> >>                     if (ONFI.byte112 == 4)
>> >> 		 60s SLC NAND with on-die ECC
>> >> 	    else if (ONFI.byte112 == 8)
>> >>      	              70s SLC NAND with on-die ECC
>> >
>> >This is completely fucked up! Now the ONFI param page says the NAND
>> >requires 8bits/512bytes, while the ID bytes advertised an on-die ECC
>> >providing 4bits/512bytes correctability.
>>
>> I think, my previous answers can answer this confusion.
>
>Yep. BTW, sorry for being so harsh in my previous reply.
Don't sorry, open source community should like this. And if you have any confusion and
Something fucked up about Micron NAND, please freely speak out and let me know.
If we can give any support, we are very happy. 
--
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 v6 0/6] genirq/gpio: Add driver for ThunderX and OCTEON-TX SoCs
From: David Daney @ 2017-04-11 17:21 UTC (permalink / raw)
  To: Linus Walleij, Alexandre Courbot, Rob Herring, Mark Rutland,
	Marc Zyngier, Thomas Gleixner, linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA
  Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA, David Daney

The ThunderX/OCTEON-TX GPIO hardware looks like a PCIe device, with
the interrupt signal from each GPIO line being routed to a dedicated
MSI-X.  This interrupt routing requires that we add some custom
processing to the beginning of the MSI-X irqdomain hierarchy.

Changes from v5:

 - Added .irq_{request,release}_resources() functions to irq_chip.

 - Quit calling irq_set_irq_type() in the irq_map() function.

 - Added more error condition checking to irq_domain_{push,pop}_irq()

Changes from v4:

 - Rebased to post-v4.10 to support .set_config() function.

 - Added .get_direction() support.

 - Added PIN_CONFIG_INPUT_DEBOUNCE support.

 - Removed some improper use of ENOSYS.

Changes from v3:

 - Add some "depends on" to the driver Kconfig to avoid build errors
   in some architectures when doing COMPILE_TEST builds.

Changes from v2:

 - in 4/6: Added Rob Harring's Acked-by

 - Added three patches to genirq/irqdomain to support interrupt code
   in the driver.

 - Rewrite irq code in driver to use irqdomain hierarchy.

 - Other naming and style changes as recommended by Linus Walleij.

Changes from v1:

 - in 1/3: Addressed Rob Harring's comments.

 - in 2/3: Trivial cleanups found in internal review + add some
   comments.

David Daney (6):
  genirq: Export more irq_chip_*_parent() functions.
  genirq: Add handle_fasteoi_{level,edge}_irq flow handlers.
  irqdomain: Add irq_domain_{push,pop}_irq() functions.
  dt-bindings: gpio: Add binding documentation for gpio-thunderx
  gpio: Add gpio driver support for ThunderX and OCTEON-TX
  MAINTAINERS: Add entry for THUNDERX GPIO Driver.

 .../devicetree/bindings/gpio/gpio-thunderx.txt     |  27 +
 MAINTAINERS                                        |   5 +
 drivers/gpio/Kconfig                               |   8 +
 drivers/gpio/Makefile                              |   1 +
 drivers/gpio/gpio-thunderx.c                       | 639 +++++++++++++++++++++
 include/linux/irq.h                                |   2 +
 include/linux/irqdomain.h                          |   3 +
 kernel/irq/chip.c                                  | 105 ++++
 kernel/irq/irqdomain.c                             | 178 ++++++
 9 files changed, 968 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/gpio-thunderx.txt
 create mode 100644 drivers/gpio/gpio-thunderx.c

-- 
1.8.3.1

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

^ permalink raw reply

* [PATCH v6 1/6] genirq: Export more irq_chip_*_parent() functions.
From: David Daney @ 2017-04-11 17:21 UTC (permalink / raw)
  To: Linus Walleij, Alexandre Courbot, Rob Herring, Mark Rutland,
	Marc Zyngier, Thomas Gleixner, linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA
  Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA, David Daney
In-Reply-To: <1491931269-15650-1-git-send-email-david.daney-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org>

Many of the family of functions including irq_chip_mask_parent(),
irq_chip_unmask_parent() are exported, but not all.

Add EXPORT_SYMBOL_GPL to irq_chip_enable_parent,
irq_chip_disable_parent and irq_chip_set_affinity_parent, so they
likewise are usable from modules.

Signed-off-by: David Daney <david.daney-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org>
---
 kernel/irq/chip.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index be3c34e..73ea90b 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -993,6 +993,7 @@ void irq_chip_enable_parent(struct irq_data *data)
 	else
 		data->chip->irq_unmask(data);
 }
+EXPORT_SYMBOL_GPL(irq_chip_enable_parent);
 
 /**
  * irq_chip_disable_parent - Disable the parent interrupt (defaults to mask if
@@ -1007,6 +1008,7 @@ void irq_chip_disable_parent(struct irq_data *data)
 	else
 		data->chip->irq_mask(data);
 }
+EXPORT_SYMBOL_GPL(irq_chip_disable_parent);
 
 /**
  * irq_chip_ack_parent - Acknowledge the parent interrupt
@@ -1069,6 +1071,7 @@ int irq_chip_set_affinity_parent(struct irq_data *data,
 
 	return -ENOSYS;
 }
+EXPORT_SYMBOL_GPL(irq_chip_set_affinity_parent);
 
 /**
  * irq_chip_set_type_parent - Set IRQ type on the parent interrupt
-- 
1.8.3.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 v6 2/6] genirq: Add handle_fasteoi_{level,edge}_irq flow handlers.
From: David Daney @ 2017-04-11 17:21 UTC (permalink / raw)
  To: Linus Walleij, Alexandre Courbot, Rob Herring, Mark Rutland,
	Marc Zyngier, Thomas Gleixner, linux-gpio, devicetree
  Cc: linux-kernel, David Daney
In-Reply-To: <1491931269-15650-1-git-send-email-david.daney@cavium.com>

Follow-on patch for gpio-thunderx uses a irqdomain hierarchy which
requires slightly different flow handlers, add them to chip.c which
contains most of the other flow handlers.

Signed-off-by: David Daney <david.daney@cavium.com>
---
 include/linux/irq.h |   2 ++
 kernel/irq/chip.c   | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 104 insertions(+)

diff --git a/include/linux/irq.h b/include/linux/irq.h
index f887351..3db0eb8 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -518,6 +518,8 @@ static inline int irq_set_parent(int irq, int parent_irq)
 extern int irq_chip_pm_get(struct irq_data *data);
 extern int irq_chip_pm_put(struct irq_data *data);
 #ifdef	CONFIG_IRQ_DOMAIN_HIERARCHY
+extern void handle_fasteoi_edge_irq(struct irq_desc *desc);
+extern void handle_fasteoi_level_irq(struct irq_desc *desc);
 extern void irq_chip_enable_parent(struct irq_data *data);
 extern void irq_chip_disable_parent(struct irq_data *data);
 extern void irq_chip_ack_parent(struct irq_data *data);
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index 73ea90b..213105d 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -981,6 +981,108 @@ void irq_cpu_offline(void)
 
 #ifdef	CONFIG_IRQ_DOMAIN_HIERARCHY
 /**
+ *	handle_fasteoi_edge_irq - irq handler for edge hierarchy
+ *	stacked on transparent controllers
+ *
+ *	@desc:	the interrupt description structure for this irq
+ *
+ *	Like handle_fasteoi_irq(), but for use with hierarchy where
+ *	the irq_chip also needs to have its ->irq_ack() function
+ *	called.
+ */
+void handle_fasteoi_edge_irq(struct irq_desc *desc)
+{
+	struct irq_chip *chip = desc->irq_data.chip;
+
+	raw_spin_lock(&desc->lock);
+
+	if (!irq_may_run(desc))
+		goto out;
+
+	desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING);
+
+	/*
+	 * If its disabled or no action available
+	 * then mask it and get out of here:
+	 */
+	if (unlikely(!desc->action || irqd_irq_disabled(&desc->irq_data))) {
+		desc->istate |= IRQS_PENDING;
+		mask_irq(desc);
+		goto out;
+	}
+
+	kstat_incr_irqs_this_cpu(desc);
+	if (desc->istate & IRQS_ONESHOT)
+		mask_irq(desc);
+
+	/* Start handling the irq */
+	desc->irq_data.chip->irq_ack(&desc->irq_data);
+
+	preflow_handler(desc);
+	handle_irq_event(desc);
+
+	cond_unmask_eoi_irq(desc, chip);
+
+	raw_spin_unlock(&desc->lock);
+	return;
+out:
+	if (!(chip->flags & IRQCHIP_EOI_IF_HANDLED))
+		chip->irq_eoi(&desc->irq_data);
+	raw_spin_unlock(&desc->lock);
+}
+EXPORT_SYMBOL_GPL(handle_fasteoi_edge_irq);
+
+/**
+ *	handle_fasteoi_level_irq - irq handler for level hierarchy
+ *	stacked on transparent controllers
+ *
+ *	@desc:	the interrupt description structure for this irq
+ *
+ *	Like handle_fasteoi_irq(), but for use with hierarchy where
+ *	the irq_chip also needs to have its ->irq_mask_ack() function
+ *	called.
+ */
+void handle_fasteoi_level_irq(struct irq_desc *desc)
+{
+	struct irq_chip *chip = desc->irq_data.chip;
+
+	raw_spin_lock(&desc->lock);
+	mask_ack_irq(desc);
+
+	if (!irq_may_run(desc))
+		goto out;
+
+	desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING);
+
+	/*
+	 * If its disabled or no action available
+	 * then mask it and get out of here:
+	 */
+	if (unlikely(!desc->action || irqd_irq_disabled(&desc->irq_data))) {
+		desc->istate |= IRQS_PENDING;
+		mask_irq(desc);
+		goto out;
+	}
+
+	kstat_incr_irqs_this_cpu(desc);
+	if (desc->istate & IRQS_ONESHOT)
+		mask_irq(desc);
+
+	preflow_handler(desc);
+	handle_irq_event(desc);
+
+	cond_unmask_eoi_irq(desc, chip);
+
+	raw_spin_unlock(&desc->lock);
+	return;
+out:
+	if (!(chip->flags & IRQCHIP_EOI_IF_HANDLED))
+		chip->irq_eoi(&desc->irq_data);
+	raw_spin_unlock(&desc->lock);
+}
+EXPORT_SYMBOL_GPL(handle_fasteoi_level_irq);
+
+/**
  * irq_chip_enable_parent - Enable the parent interrupt (defaults to unmask if
  * NULL)
  * @data:	Pointer to interrupt specific data
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH v6 3/6] irqdomain: Add irq_domain_{push,pop}_irq() functions.
From: David Daney @ 2017-04-11 17:21 UTC (permalink / raw)
  To: Linus Walleij, Alexandre Courbot, Rob Herring, Mark Rutland,
	Marc Zyngier, Thomas Gleixner, linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA
  Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA, David Daney
In-Reply-To: <1491931269-15650-1-git-send-email-david.daney-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org>

For an already existing irqdomain hierarchy, as might be obtained via
a call to pci_enable_msix_range(), a PCI driver wishing to add an
additional irqdomain to the hierarchy needs to be able to insert the
irqdomain to that already initialized hierarchy.  Calling
irq_domain_create_hierarchy() allows the new irqdomain to be created,
but no existing code allows for initializing the associated irq_data.

Add a couple of helper functions (irq_domain_push_irq() and
irq_domain_pop_irq()) to initialize the irq_data for the new
irqdomain added to an existing hierarchy.

Signed-off-by: David Daney <david.daney-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org>
---
 include/linux/irqdomain.h |   3 +
 kernel/irq/irqdomain.c    | 178 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 181 insertions(+)

diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index 9f36160..0316846 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -425,6 +425,9 @@ extern void irq_domain_free_irqs_common(struct irq_domain *domain,
 extern void irq_domain_free_irqs_top(struct irq_domain *domain,
 				     unsigned int virq, unsigned int nr_irqs);
 
+extern int irq_domain_push_irq(struct irq_domain *domain, int virq, void *arg);
+extern int irq_domain_pop_irq(struct irq_domain *domain, int virq);
+
 extern int irq_domain_alloc_irqs_parent(struct irq_domain *domain,
 					unsigned int irq_base,
 					unsigned int nr_irqs, void *arg);
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 31805f2..ea9d30d 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -1304,6 +1304,184 @@ int __irq_domain_alloc_irqs(struct irq_domain *domain, int irq_base,
 	return ret;
 }
 
+/* The irq_data was moved, fix the revmap to refer to the new location */
+static void irq_domain_fix_revmap(struct irq_data *d)
+{
+	void **slot;
+
+	if (d->hwirq < d->domain->revmap_size)
+		return; /* Not using radix tree. */
+
+	/* Fix up the revmap. */
+	mutex_lock(&revmap_trees_mutex);
+	slot = radix_tree_lookup_slot(&d->domain->revmap_tree, d->hwirq);
+	if (slot)
+		radix_tree_replace_slot(&d->domain->revmap_tree, slot, d);
+	mutex_unlock(&revmap_trees_mutex);
+}
+
+/**
+ * irq_domain_push_irq() - Push a domain in to the top of a hierarchy.
+ * @domain:	Domain to push.
+ * @virq:	Irq to push the domain in to.
+ * @arg:	Passed to the irq_domain_ops alloc() function.
+ *
+ * For an already existing irqdomain hierarchy, as might be obtained
+ * via a call to pci_enable_msix(), add an additional domain to the
+ * head of the processing chain.  Must be called before request_irq()
+ * has been called.
+ */
+int irq_domain_push_irq(struct irq_domain *domain, int virq, void *arg)
+{
+	struct irq_data *child_irq_data;
+	struct irq_data *root_irq_data = irq_get_irq_data(virq);
+	struct irq_desc *desc;
+	int rv = 0;
+
+	/*
+	 * Check that no action has been set, which indicates the virq
+	 * is in a state where this function doesn't have to deal with
+	 * races between interrupt handling and maintaining the
+	 * hierarchy.  This will catch gross misuse.  Attempting to
+	 * make the check race free would require holding locks across
+	 * calls to struct irq_domain_ops->alloc(), which could lead
+	 * to deadlock, so we just do a simple check before starting.
+	 */
+	desc = irq_to_desc(virq);
+	if (!desc)
+		return -EINVAL;
+	if (WARN_ON(desc->action))
+		return -EBUSY;
+
+	if (domain == NULL)
+		return -EINVAL;
+
+	if (WARN_ON(!domain->ops->alloc))
+		return -EINVAL;
+
+	if (!root_irq_data)
+		return -EINVAL;
+
+	child_irq_data = kzalloc_node(sizeof(*child_irq_data), GFP_KERNEL,
+				      irq_data_get_node(root_irq_data));
+	if (!child_irq_data)
+		return -ENOMEM;
+
+	mutex_lock(&irq_domain_mutex);
+
+	/* Copy the original irq_data. */
+	*child_irq_data = *root_irq_data;
+
+	irq_domain_fix_revmap(child_irq_data);
+
+	/*
+	 * Overwrite the root_irq_data, which is embedded in struct
+	 * irq_desc, with values for this domain.
+	 */
+	root_irq_data->parent_data = child_irq_data;
+	root_irq_data->domain = domain;
+	root_irq_data->mask = 0;
+	root_irq_data->hwirq = 0;
+	root_irq_data->chip = NULL;
+	root_irq_data->chip_data = NULL;
+	rv = domain->ops->alloc(domain, virq, 1, arg);
+	if (rv) {
+		/* Restore the original irq_data. */
+		*root_irq_data = *child_irq_data;
+		irq_domain_fix_revmap(root_irq_data);
+		goto error;
+	}
+
+	if (root_irq_data->hwirq < domain->revmap_size) {
+		domain->linear_revmap[root_irq_data->hwirq] = virq;
+	} else {
+		mutex_lock(&revmap_trees_mutex);
+		radix_tree_insert(&domain->revmap_tree,
+				  root_irq_data->hwirq, root_irq_data);
+		mutex_unlock(&revmap_trees_mutex);
+	}
+error:
+	mutex_unlock(&irq_domain_mutex);
+
+	return rv;
+}
+EXPORT_SYMBOL_GPL(irq_domain_push_irq);
+
+/**
+ * irq_domain_pop_irq() - Remove a domain from the top of a hierarchy.
+ * @domain:	Domain to remove.
+ * @virq:	Irq to remove the domain from.
+ *
+ * Undo the effects of a call to irq_domain_push_irq().  Must be
+ * called either before request_irq() or after free_irq().
+ */
+int irq_domain_pop_irq(struct irq_domain *domain, int virq)
+{
+	struct irq_data *root_irq_data = irq_get_irq_data(virq);
+	struct irq_data *child_irq_data;
+	struct irq_data *tmp_irq_data;
+	struct irq_desc *desc;
+
+	/*
+	 * Check that no action is set, which indicates the virq is in
+	 * a state where this function doesn't have to deal with races
+	 * between interrupt handling and maintaining the hierarchy.
+	 * This will catch gross misuse.  Attempting to make the check
+	 * race free would require holding locks across calls to
+	 * struct irq_domain_ops->free(), which could lead to
+	 * deadlock, so we just do a simple check before starting.
+	 */
+	desc = irq_to_desc(virq);
+	if (!desc)
+		return -EINVAL;
+	if (WARN_ON(desc->action))
+		return -EBUSY;
+
+	if (domain == NULL)
+		return -EINVAL;
+
+	if (!root_irq_data)
+		return -EINVAL;
+
+	tmp_irq_data = irq_domain_get_irq_data(domain, virq);
+
+	/* We can only "pop" if this domain is at the top of the list */
+	if (WARN_ON(root_irq_data != tmp_irq_data))
+		return -EINVAL;
+
+	if (WARN_ON(root_irq_data->domain != domain))
+		return -EINVAL;
+
+	child_irq_data = root_irq_data->parent_data;
+	if (WARN_ON(!child_irq_data))
+		return -EINVAL;
+
+	mutex_lock(&irq_domain_mutex);
+
+	root_irq_data->parent_data = NULL;
+
+	if (root_irq_data->hwirq >= domain->revmap_size) {
+		mutex_lock(&revmap_trees_mutex);
+		radix_tree_delete(&domain->revmap_tree, root_irq_data->hwirq);
+		mutex_unlock(&revmap_trees_mutex);
+	}
+
+	if (domain->ops->free)
+		domain->ops->free(domain, virq, 1);
+
+	/* Restore the original irq_data. */
+	*root_irq_data = *child_irq_data;
+
+	irq_domain_fix_revmap(root_irq_data);
+
+	mutex_unlock(&irq_domain_mutex);
+
+	kfree(child_irq_data);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(irq_domain_pop_irq);
+
 /**
  * irq_domain_free_irqs - Free IRQ number and associated data structures
  * @virq:	base IRQ number
-- 
1.8.3.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 v6 4/6] dt-bindings: gpio: Add binding documentation for gpio-thunderx
From: David Daney @ 2017-04-11 17:21 UTC (permalink / raw)
  To: Linus Walleij, Alexandre Courbot, Rob Herring, Mark Rutland,
	Marc Zyngier, Thomas Gleixner, linux-gpio, devicetree
  Cc: linux-kernel, David Daney
In-Reply-To: <1491931269-15650-1-git-send-email-david.daney@cavium.com>

Signed-off-by: David Daney <david.daney@cavium.com>
Acked-by: Rob Herring <robh@kernel.org>
---
 .../devicetree/bindings/gpio/gpio-thunderx.txt     | 27 ++++++++++++++++++++++
 1 file changed, 27 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/gpio-thunderx.txt

diff --git a/Documentation/devicetree/bindings/gpio/gpio-thunderx.txt b/Documentation/devicetree/bindings/gpio/gpio-thunderx.txt
new file mode 100644
index 0000000..3f883ae
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/gpio-thunderx.txt
@@ -0,0 +1,27 @@
+Cavium ThunderX/OCTEON-TX GPIO controller bindings
+
+Required Properties:
+- reg: The controller bus address.
+- gpio-controller: Marks the device node as a GPIO controller.
+- #gpio-cells: Must be 2.
+  - First cell is the GPIO pin number relative to the controller.
+  - Second cell is a standard generic flag bitfield as described in gpio.txt.
+
+Optional Properties:
+- compatible: "cavium,thunder-8890-gpio", unused as PCI driver binding is used.
+- interrupt-controller: Marks the device node as an interrupt controller.
+- #interrupt-cells: Must be present and have value of 2 if
+                    "interrupt-controller" is present.
+  - First cell is the GPIO pin number relative to the controller.
+  - Second cell is triggering flags as defined in interrupts.txt.
+
+Example:
+
+gpio_6_0: gpio@6,0 {
+	compatible = "cavium,thunder-8890-gpio";
+	reg = <0x3000 0 0 0 0>; /*  DEVFN = 0x30 (6:0) */
+	gpio-controller;
+	#gpio-cells = <2>;
+	interrupt-controller;
+	#interrupt-cells = <2>;
+};
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH v6 5/6] gpio: Add gpio driver support for ThunderX and OCTEON-TX
From: David Daney @ 2017-04-11 17:21 UTC (permalink / raw)
  To: Linus Walleij, Alexandre Courbot, Rob Herring, Mark Rutland,
	Marc Zyngier, Thomas Gleixner, linux-gpio, devicetree
  Cc: linux-kernel, David Daney
In-Reply-To: <1491931269-15650-1-git-send-email-david.daney@cavium.com>

Cavium ThunderX and OCTEON-TX are arm64 based SoCs.  Add driver for
the on-chip GPIO pins.

Signed-off-by: David Daney <david.daney@cavium.com>
---
 drivers/gpio/Kconfig         |   8 +
 drivers/gpio/Makefile        |   1 +
 drivers/gpio/gpio-thunderx.c | 639 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 648 insertions(+)
 create mode 100644 drivers/gpio/gpio-thunderx.c

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 0504307..9291750 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -439,6 +439,14 @@ config GPIO_TS4800
 	help
 	  This driver support TS-4800 FPGA GPIO controllers.
 
+config GPIO_THUNDERX
+	tristate "Cavium ThunderX/OCTEON-TX GPIO"
+	depends on ARCH_THUNDER || (64BIT && COMPILE_TEST)
+	depends on PCI_MSI && IRQ_DOMAIN_HIERARCHY
+	help
+	  Say yes here to support the on-chip GPIO lines on the ThunderX
+	  and OCTEON-TX families of SoCs.
+
 config GPIO_TZ1090
 	bool "Toumaz Xenif TZ1090 GPIO support"
 	depends on SOC_TZ1090
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index becb96c..8d8eb15 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -111,6 +111,7 @@ obj-$(CONFIG_GPIO_SYSCON)	+= gpio-syscon.o
 obj-$(CONFIG_GPIO_TB10X)	+= gpio-tb10x.o
 obj-$(CONFIG_GPIO_TC3589X)	+= gpio-tc3589x.o
 obj-$(CONFIG_GPIO_TEGRA)	+= gpio-tegra.o
+obj-$(CONFIG_GPIO_THUNDERX)	+= gpio-thunderx.o
 obj-$(CONFIG_GPIO_TIMBERDALE)	+= gpio-timberdale.o
 obj-$(CONFIG_GPIO_PALMAS)	+= gpio-palmas.o
 obj-$(CONFIG_GPIO_TPIC2810)	+= gpio-tpic2810.o
diff --git a/drivers/gpio/gpio-thunderx.c b/drivers/gpio/gpio-thunderx.c
new file mode 100644
index 0000000..c93b377
--- /dev/null
+++ b/drivers/gpio/gpio-thunderx.c
@@ -0,0 +1,639 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2016, 2017 Cavium Inc.
+ */
+
+#include <linux/bitops.h>
+#include <linux/gpio/driver.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/spinlock.h>
+
+
+#define GPIO_RX_DAT	0x0
+#define GPIO_TX_SET	0x8
+#define GPIO_TX_CLR	0x10
+#define GPIO_CONST	0x90
+#define  GPIO_CONST_GPIOS_MASK 0xff
+#define GPIO_BIT_CFG	0x400
+#define  GPIO_BIT_CFG_TX_OE		BIT(0)
+#define  GPIO_BIT_CFG_PIN_XOR		BIT(1)
+#define  GPIO_BIT_CFG_INT_EN		BIT(2)
+#define  GPIO_BIT_CFG_INT_TYPE		BIT(3)
+#define  GPIO_BIT_CFG_FIL_MASK		GENMASK(11, 4)
+#define  GPIO_BIT_CFG_FIL_CNT_SHIFT	4
+#define  GPIO_BIT_CFG_FIL_SEL_SHIFT	8
+#define  GPIO_BIT_CFG_TX_OD		BIT(12)
+#define  GPIO_BIT_CFG_PIN_SEL_MASK	GENMASK(25, 16)
+#define GPIO_INTR	0x800
+#define  GPIO_INTR_INTR			BIT(0)
+#define  GPIO_INTR_INTR_W1S		BIT(1)
+#define  GPIO_INTR_ENA_W1C		BIT(2)
+#define  GPIO_INTR_ENA_W1S		BIT(3)
+#define GPIO_2ND_BANK	0x1400
+
+#define GLITCH_FILTER_400NS ((4u << GPIO_BIT_CFG_FIL_SEL_SHIFT) | \
+			     (9u << GPIO_BIT_CFG_FIL_CNT_SHIFT))
+
+struct thunderx_gpio;
+
+struct thunderx_line {
+	struct thunderx_gpio	*txgpio;
+	unsigned int		line;
+	unsigned int		fil_bits;
+};
+
+struct thunderx_gpio {
+	struct gpio_chip	chip;
+	u8 __iomem		*register_base;
+	struct irq_domain	*irqd;
+	struct msix_entry	*msix_entries;	/* per line MSI-X */
+	struct thunderx_line	*line_entries;	/* per line irq info */
+	raw_spinlock_t		lock;
+	unsigned long		invert_mask[2];
+	unsigned long		od_mask[2];
+	int			base_msi;
+};
+
+static unsigned int bit_cfg_reg(unsigned int line)
+{
+	return 8 * line + GPIO_BIT_CFG;
+}
+
+static unsigned int intr_reg(unsigned int line)
+{
+	return 8 * line + GPIO_INTR;
+}
+
+static bool thunderx_gpio_is_gpio_nowarn(struct thunderx_gpio *txgpio,
+					 unsigned int line)
+{
+	u64 bit_cfg = readq(txgpio->register_base + bit_cfg_reg(line));
+
+	return (bit_cfg & GPIO_BIT_CFG_PIN_SEL_MASK) == 0;
+}
+
+/*
+ * Check (and WARN) that the pin is available for GPIO.  We will not
+ * allow modification of the state of non-GPIO pins from this driver.
+ */
+static bool thunderx_gpio_is_gpio(struct thunderx_gpio *txgpio,
+				  unsigned int line)
+{
+	bool rv = thunderx_gpio_is_gpio_nowarn(txgpio, line);
+
+	WARN_RATELIMIT(!rv, "Pin %d not available for GPIO\n", line);
+
+	return rv;
+}
+
+static int thunderx_gpio_request(struct gpio_chip *chip, unsigned int line)
+{
+	struct thunderx_gpio *txgpio = gpiochip_get_data(chip);
+
+	return thunderx_gpio_is_gpio(txgpio, line) ? 0 : -EIO;
+}
+
+static int thunderx_gpio_dir_in(struct gpio_chip *chip, unsigned int line)
+{
+	struct thunderx_gpio *txgpio = gpiochip_get_data(chip);
+
+	if (!thunderx_gpio_is_gpio(txgpio, line))
+		return -EIO;
+
+	raw_spin_lock(&txgpio->lock);
+	clear_bit(line, txgpio->invert_mask);
+	clear_bit(line, txgpio->od_mask);
+	writeq(txgpio->line_entries[line].fil_bits,
+	       txgpio->register_base + bit_cfg_reg(line));
+	raw_spin_unlock(&txgpio->lock);
+	return 0;
+}
+
+static void thunderx_gpio_set(struct gpio_chip *chip, unsigned int line,
+			      int value)
+{
+	struct thunderx_gpio *txgpio = gpiochip_get_data(chip);
+	int bank = line / 64;
+	int bank_bit = line % 64;
+
+	void __iomem *reg = txgpio->register_base +
+		(bank * GPIO_2ND_BANK) + (value ? GPIO_TX_SET : GPIO_TX_CLR);
+
+	writeq(BIT_ULL(bank_bit), reg);
+}
+
+static int thunderx_gpio_dir_out(struct gpio_chip *chip, unsigned int line,
+				 int value)
+{
+	struct thunderx_gpio *txgpio = gpiochip_get_data(chip);
+	u64 bit_cfg = txgpio->line_entries[line].fil_bits | GPIO_BIT_CFG_TX_OE;
+
+	if (!thunderx_gpio_is_gpio(txgpio, line))
+		return -EIO;
+
+	raw_spin_lock(&txgpio->lock);
+
+	thunderx_gpio_set(chip, line, value);
+
+	if (test_bit(line, txgpio->invert_mask))
+		bit_cfg |= GPIO_BIT_CFG_PIN_XOR;
+
+	if (test_bit(line, txgpio->od_mask))
+		bit_cfg |= GPIO_BIT_CFG_TX_OD;
+
+	writeq(bit_cfg, txgpio->register_base + bit_cfg_reg(line));
+
+	raw_spin_unlock(&txgpio->lock);
+	return 0;
+}
+
+static int thunderx_gpio_get_direction(struct gpio_chip *chip, unsigned int line)
+{
+	struct thunderx_gpio *txgpio = gpiochip_get_data(chip);
+	u64 bit_cfg;
+
+	if (!thunderx_gpio_is_gpio_nowarn(txgpio, line))
+		/*
+		 * Say it is input for now to avoid WARNing on
+		 * gpiochip_add_data().  We will WARN if someone
+		 * requests it or tries to use it.
+		 */
+		return 1;
+
+	bit_cfg = readq(txgpio->register_base + bit_cfg_reg(line));
+
+	return !(bit_cfg & GPIO_BIT_CFG_TX_OE);
+}
+
+static int thunderx_gpio_set_config(struct gpio_chip *chip,
+				    unsigned int line,
+				    unsigned long cfg)
+{
+	bool orig_invert, orig_od, orig_dat, new_invert, new_od;
+	u32 arg, sel;
+	u64 bit_cfg;
+	int bank = line / 64;
+	int bank_bit = line % 64;
+	int ret = -ENOTSUPP;
+	struct thunderx_gpio *txgpio = gpiochip_get_data(chip);
+	void __iomem *reg = txgpio->register_base + (bank * GPIO_2ND_BANK) + GPIO_TX_SET;
+
+	if (!thunderx_gpio_is_gpio(txgpio, line))
+		return -EIO;
+
+	raw_spin_lock(&txgpio->lock);
+	orig_invert = test_bit(line, txgpio->invert_mask);
+	new_invert  = orig_invert;
+	orig_od = test_bit(line, txgpio->od_mask);
+	new_od = orig_od;
+	orig_dat = ((readq(reg) >> bank_bit) & 1) ^ orig_invert;
+	bit_cfg = readq(txgpio->register_base + bit_cfg_reg(line));
+	switch (pinconf_to_config_param(cfg)) {
+	case PIN_CONFIG_DRIVE_OPEN_DRAIN:
+		/*
+		 * Weird, setting open-drain mode causes signal
+		 * inversion.  Note this so we can compensate in the
+		 * dir_out function.
+		 */
+		set_bit(line, txgpio->invert_mask);
+		new_invert  = true;
+		set_bit(line, txgpio->od_mask);
+		new_od = true;
+		ret = 0;
+		break;
+	case PIN_CONFIG_DRIVE_PUSH_PULL:
+		clear_bit(line, txgpio->invert_mask);
+		new_invert  = false;
+		clear_bit(line, txgpio->od_mask);
+		new_od  = false;
+		ret = 0;
+		break;
+	case PIN_CONFIG_INPUT_DEBOUNCE:
+		arg = pinconf_to_config_argument(cfg);
+		if (arg > 1228) { /* 15 * 2^15 * 2.5nS maximum */
+			ret = -EINVAL;
+			break;
+		}
+		arg *= 400; /* scale to 2.5nS clocks. */
+		sel = 0;
+		while (arg > 15) {
+			sel++;
+			arg++; /* always round up */
+			arg >>= 1;
+		}
+		txgpio->line_entries[line].fil_bits =
+			(sel << GPIO_BIT_CFG_FIL_SEL_SHIFT) |
+			(arg << GPIO_BIT_CFG_FIL_CNT_SHIFT);
+		bit_cfg &= ~GPIO_BIT_CFG_FIL_MASK;
+		bit_cfg |= txgpio->line_entries[line].fil_bits;
+		writeq(bit_cfg, txgpio->register_base + bit_cfg_reg(line));
+		ret = 0;
+		break;
+	default:
+		break;
+	}
+	raw_spin_unlock(&txgpio->lock);
+
+	/*
+	 * If currently output and OPEN_DRAIN changed, install the new
+	 * settings
+	 */
+	if ((new_invert != orig_invert || new_od != orig_od) &&
+	    (bit_cfg & GPIO_BIT_CFG_TX_OE))
+		ret = thunderx_gpio_dir_out(chip, line, orig_dat ^ new_invert);
+
+	return ret;
+}
+
+static int thunderx_gpio_get(struct gpio_chip *chip, unsigned int line)
+{
+	struct thunderx_gpio *txgpio = gpiochip_get_data(chip);
+	int bank = line / 64;
+	int bank_bit = line % 64;
+	u64 read_bits = readq(txgpio->register_base + (bank * GPIO_2ND_BANK) + GPIO_RX_DAT);
+	u64 masked_bits = read_bits & BIT_ULL(bank_bit);
+
+	if (test_bit(line, txgpio->invert_mask))
+		return masked_bits == 0;
+	else
+		return masked_bits != 0;
+}
+
+static void thunderx_gpio_set_multiple(struct gpio_chip *chip,
+				       unsigned long *mask,
+				       unsigned long *bits)
+{
+	int bank;
+	u64 set_bits, clear_bits;
+	struct thunderx_gpio *txgpio = gpiochip_get_data(chip);
+
+	for (bank = 0; bank <= chip->ngpio / 64; bank++) {
+		set_bits = bits[bank] & mask[bank];
+		clear_bits = ~bits[bank] & mask[bank];
+		writeq(set_bits, txgpio->register_base + (bank * GPIO_2ND_BANK) + GPIO_TX_SET);
+		writeq(clear_bits, txgpio->register_base + (bank * GPIO_2ND_BANK) + GPIO_TX_CLR);
+	}
+}
+
+static void thunderx_gpio_irq_ack(struct irq_data *data)
+{
+	struct thunderx_line *txline = irq_data_get_irq_chip_data(data);
+
+	writeq(GPIO_INTR_INTR,
+	       txline->txgpio->register_base + intr_reg(txline->line));
+}
+
+static void thunderx_gpio_irq_mask(struct irq_data *data)
+{
+	struct thunderx_line *txline = irq_data_get_irq_chip_data(data);
+
+	writeq(GPIO_INTR_ENA_W1C,
+	       txline->txgpio->register_base + intr_reg(txline->line));
+}
+
+static void thunderx_gpio_irq_mask_ack(struct irq_data *data)
+{
+	struct thunderx_line *txline = irq_data_get_irq_chip_data(data);
+
+	writeq(GPIO_INTR_ENA_W1C | GPIO_INTR_INTR,
+	       txline->txgpio->register_base + intr_reg(txline->line));
+}
+
+static void thunderx_gpio_irq_unmask(struct irq_data *data)
+{
+	struct thunderx_line *txline = irq_data_get_irq_chip_data(data);
+
+	writeq(GPIO_INTR_ENA_W1S,
+	       txline->txgpio->register_base + intr_reg(txline->line));
+}
+
+static int thunderx_gpio_irq_set_type(struct irq_data *data,
+				      unsigned int flow_type)
+{
+	struct thunderx_line *txline = irq_data_get_irq_chip_data(data);
+	struct thunderx_gpio *txgpio = txline->txgpio;
+	u64 bit_cfg;
+
+	irqd_set_trigger_type(data, flow_type);
+
+	bit_cfg = txline->fil_bits | GPIO_BIT_CFG_INT_EN;
+
+	if (flow_type & IRQ_TYPE_EDGE_BOTH) {
+		irq_set_handler_locked(data, handle_fasteoi_edge_irq);
+		bit_cfg |= GPIO_BIT_CFG_INT_TYPE;
+	} else {
+		irq_set_handler_locked(data, handle_fasteoi_level_irq);
+	}
+
+	raw_spin_lock(&txgpio->lock);
+	if (flow_type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_LEVEL_LOW)) {
+		bit_cfg |= GPIO_BIT_CFG_PIN_XOR;
+		set_bit(txline->line, txgpio->invert_mask);
+	} else {
+		clear_bit(txline->line, txgpio->invert_mask);
+	}
+	clear_bit(txline->line, txgpio->od_mask);
+	writeq(bit_cfg, txgpio->register_base + bit_cfg_reg(txline->line));
+	raw_spin_unlock(&txgpio->lock);
+
+	return IRQ_SET_MASK_OK;
+}
+
+static void thunderx_gpio_irq_enable(struct irq_data *data)
+{
+	irq_chip_enable_parent(data);
+	thunderx_gpio_irq_unmask(data);
+}
+
+static void thunderx_gpio_irq_disable(struct irq_data *data)
+{
+	thunderx_gpio_irq_mask(data);
+	irq_chip_disable_parent(data);
+}
+
+static int thunderx_gpio_irq_request_resources(struct irq_data *data)
+{
+	struct thunderx_line *txline = irq_data_get_irq_chip_data(data);
+	struct thunderx_gpio *txgpio = txline->txgpio;
+	struct irq_data *parent_data = data->parent_data;
+	int r;
+
+	r = gpiochip_lock_as_irq(&txgpio->chip, txline->line);
+	if (r)
+		return r;
+
+	if (parent_data && parent_data->chip->irq_request_resources) {
+		r = parent_data->chip->irq_request_resources(parent_data);
+		if (r)
+			goto error;
+	}
+
+	return 0;
+error:
+	gpiochip_unlock_as_irq(&txgpio->chip, txline->line);
+	return r;
+}
+
+static void thunderx_gpio_irq_release_resources(struct irq_data *data)
+{
+	struct thunderx_line *txline = irq_data_get_irq_chip_data(data);
+	struct thunderx_gpio *txgpio = txline->txgpio;
+	struct irq_data *parent_data = data->parent_data;
+
+	if (parent_data && parent_data->chip->irq_release_resources)
+		parent_data->chip->irq_release_resources(parent_data);
+
+	gpiochip_unlock_as_irq(&txgpio->chip, txline->line);
+}
+
+/*
+ * Interrupts are chained from underlying MSI-X vectors.  We have
+ * these irq_chip functions to be able to handle level triggering
+ * semantics and other acknowledgment tasks associated with the GPIO
+ * mechanism.
+ */
+static struct irq_chip thunderx_gpio_irq_chip = {
+	.name			= "GPIO",
+	.irq_enable		= thunderx_gpio_irq_enable,
+	.irq_disable		= thunderx_gpio_irq_disable,
+	.irq_ack		= thunderx_gpio_irq_ack,
+	.irq_mask		= thunderx_gpio_irq_mask,
+	.irq_mask_ack		= thunderx_gpio_irq_mask_ack,
+	.irq_unmask		= thunderx_gpio_irq_unmask,
+	.irq_eoi		= irq_chip_eoi_parent,
+	.irq_set_affinity	= irq_chip_set_affinity_parent,
+	.irq_request_resources	= thunderx_gpio_irq_request_resources,
+	.irq_release_resources	= thunderx_gpio_irq_release_resources,
+	.irq_set_type		= thunderx_gpio_irq_set_type,
+
+	.flags			= IRQCHIP_SET_TYPE_MASKED
+};
+
+static int thunderx_gpio_irq_map(struct irq_domain *d, unsigned int irq,
+				 irq_hw_number_t hwirq)
+{
+	struct thunderx_gpio *txgpio = d->host_data;
+
+	if (hwirq >= txgpio->chip.ngpio)
+		return -EINVAL;
+	if (!thunderx_gpio_is_gpio_nowarn(txgpio, hwirq))
+		return -EPERM;
+	return 0;
+}
+
+static int thunderx_gpio_irq_translate(struct irq_domain *d,
+				       struct irq_fwspec *fwspec,
+				       irq_hw_number_t *hwirq,
+				       unsigned int *type)
+{
+	struct thunderx_gpio *txgpio = d->host_data;
+
+	if (WARN_ON(fwspec->param_count < 2))
+		return -EINVAL;
+	if (fwspec->param[0] >= txgpio->chip.ngpio)
+		return -EINVAL;
+	*hwirq = fwspec->param[0];
+	*type = fwspec->param[1] & IRQ_TYPE_SENSE_MASK;
+	return 0;
+}
+
+static int thunderx_gpio_irq_alloc(struct irq_domain *d, unsigned int virq,
+				   unsigned int nr_irqs, void *arg)
+{
+	struct thunderx_line *txline = arg;
+
+	return irq_domain_set_hwirq_and_chip(d, virq, txline->line,
+					     &thunderx_gpio_irq_chip, txline);
+}
+
+static const struct irq_domain_ops thunderx_gpio_irqd_ops = {
+	.map		= thunderx_gpio_irq_map,
+	.alloc		= thunderx_gpio_irq_alloc,
+	.translate	= thunderx_gpio_irq_translate
+};
+
+static int thunderx_gpio_to_irq(struct gpio_chip *chip, unsigned int offset)
+{
+	struct thunderx_gpio *txgpio = gpiochip_get_data(chip);
+
+	return irq_find_mapping(txgpio->irqd, offset);
+}
+
+static int thunderx_gpio_probe(struct pci_dev *pdev,
+			       const struct pci_device_id *id)
+{
+	void __iomem * const *tbl;
+	struct device *dev = &pdev->dev;
+	struct thunderx_gpio *txgpio;
+	struct gpio_chip *chip;
+	int ngpio, i;
+	int err = 0;
+
+	txgpio = devm_kzalloc(dev, sizeof(*txgpio), GFP_KERNEL);
+	if (!txgpio)
+		return -ENOMEM;
+
+	raw_spin_lock_init(&txgpio->lock);
+	chip = &txgpio->chip;
+
+	pci_set_drvdata(pdev, txgpio);
+
+	err = pcim_enable_device(pdev);
+	if (err) {
+		dev_err(dev, "Failed to enable PCI device: err %d\n", err);
+		goto out;
+	}
+
+	err = pcim_iomap_regions(pdev, 1 << 0, KBUILD_MODNAME);
+	if (err) {
+		dev_err(dev, "Failed to iomap PCI device: err %d\n", err);
+		goto out;
+	}
+
+	tbl = pcim_iomap_table(pdev);
+	txgpio->register_base = tbl[0];
+	if (!txgpio->register_base) {
+		dev_err(dev, "Cannot map PCI resource\n");
+		err = -ENOMEM;
+		goto out;
+	}
+
+	if (pdev->subsystem_device == 0xa10a) {
+		/* CN88XX has no GPIO_CONST register*/
+		ngpio = 50;
+		txgpio->base_msi = 48;
+	} else {
+		u64 c = readq(txgpio->register_base + GPIO_CONST);
+
+		ngpio = c & GPIO_CONST_GPIOS_MASK;
+		txgpio->base_msi = (c >> 8) & 0xff;
+	}
+
+	txgpio->msix_entries = devm_kzalloc(dev,
+					  sizeof(struct msix_entry) * ngpio,
+					  GFP_KERNEL);
+	if (!txgpio->msix_entries) {
+		err = -ENOMEM;
+		goto out;
+	}
+
+	txgpio->line_entries = devm_kzalloc(dev,
+					    sizeof(struct thunderx_line) * ngpio,
+					    GFP_KERNEL);
+	if (!txgpio->line_entries) {
+		err = -ENOMEM;
+		goto out;
+	}
+
+	for (i = 0; i < ngpio; i++) {
+		u64 bit_cfg = readq(txgpio->register_base + bit_cfg_reg(i));
+
+		txgpio->msix_entries[i].entry = txgpio->base_msi + (2 * i);
+		txgpio->line_entries[i].line = i;
+		txgpio->line_entries[i].txgpio = txgpio;
+		/*
+		 * If something has already programmed the pin, use
+		 * the existing glitch filter settings, otherwise go
+		 * to 400nS.
+		 */
+		txgpio->line_entries[i].fil_bits = bit_cfg ?
+			(bit_cfg & GPIO_BIT_CFG_FIL_MASK) : GLITCH_FILTER_400NS;
+
+		if ((bit_cfg & GPIO_BIT_CFG_TX_OE) && (bit_cfg & GPIO_BIT_CFG_TX_OD))
+			set_bit(i, txgpio->od_mask);
+		if (bit_cfg & GPIO_BIT_CFG_PIN_XOR)
+			set_bit(i, txgpio->invert_mask);
+	}
+
+
+	/* Enable all MSI-X for interrupts on all possible lines. */
+	err = pci_enable_msix_range(pdev, txgpio->msix_entries, ngpio, ngpio);
+	if (err < 0)
+		goto out;
+
+	/*
+	 * Push GPIO specific irqdomain on hierarchy created as a side
+	 * effect of the pci_enable_msix()
+	 */
+	txgpio->irqd = irq_domain_create_hierarchy(irq_get_irq_data(txgpio->msix_entries[0].vector)->domain,
+						   0, 0, of_node_to_fwnode(dev->of_node),
+						   &thunderx_gpio_irqd_ops, txgpio);
+	if (!txgpio->irqd)
+		goto out;
+
+	/* Push on irq_data and the domain for each line. */
+	for (i = 0; i < ngpio; i++) {
+		err = irq_domain_push_irq(txgpio->irqd,
+					  txgpio->msix_entries[i].vector,
+					  &txgpio->line_entries[i]);
+		if (err < 0)
+			dev_err(dev, "irq_domain_push_irq: %d\n", err);
+	}
+
+	chip->label = KBUILD_MODNAME;
+	chip->parent = dev;
+	chip->owner = THIS_MODULE;
+	chip->request = thunderx_gpio_request;
+	chip->base = -1; /* System allocated */
+	chip->can_sleep = false;
+	chip->ngpio = ngpio;
+	chip->get_direction = thunderx_gpio_get_direction;
+	chip->direction_input = thunderx_gpio_dir_in;
+	chip->get = thunderx_gpio_get;
+	chip->direction_output = thunderx_gpio_dir_out;
+	chip->set = thunderx_gpio_set;
+	chip->set_multiple = thunderx_gpio_set_multiple;
+	chip->set_config = thunderx_gpio_set_config;
+	chip->to_irq = thunderx_gpio_to_irq;
+	err = devm_gpiochip_add_data(dev, chip, txgpio);
+	if (err)
+		goto out;
+
+	dev_info(dev, "ThunderX GPIO: %d lines with base %d.\n",
+		 ngpio, chip->base);
+	return 0;
+out:
+	pci_set_drvdata(pdev, NULL);
+	return err;
+}
+
+static void thunderx_gpio_remove(struct pci_dev *pdev)
+{
+	int i;
+	struct thunderx_gpio *txgpio = pci_get_drvdata(pdev);
+
+	for (i = 0; i < txgpio->chip.ngpio; i++)
+		irq_domain_pop_irq(txgpio->irqd,
+				   txgpio->msix_entries[i].vector);
+
+	irq_domain_remove(txgpio->irqd);
+
+	pci_set_drvdata(pdev, NULL);
+}
+
+static const struct pci_device_id thunderx_gpio_id_table[] = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_CAVIUM, 0xA00A) },
+	{ 0, }	/* end of table */
+};
+
+MODULE_DEVICE_TABLE(pci, thunderx_gpio_id_table);
+
+static struct pci_driver thunderx_gpio_driver = {
+	.name = KBUILD_MODNAME,
+	.id_table = thunderx_gpio_id_table,
+	.probe = thunderx_gpio_probe,
+	.remove = thunderx_gpio_remove,
+};
+
+module_pci_driver(thunderx_gpio_driver);
+
+MODULE_DESCRIPTION("Cavium Inc. ThunderX/OCTEON-TX GPIO Driver");
+MODULE_LICENSE("GPL");
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH v6 6/6] MAINTAINERS: Add entry for THUNDERX GPIO Driver.
From: David Daney @ 2017-04-11 17:21 UTC (permalink / raw)
  To: Linus Walleij, Alexandre Courbot, Rob Herring, Mark Rutland,
	Marc Zyngier, Thomas Gleixner, linux-gpio, devicetree
  Cc: linux-kernel, David Daney
In-Reply-To: <1491931269-15650-1-git-send-email-david.daney@cavium.com>

Signed-off-by: David Daney <david.daney@cavium.com>
---
 MAINTAINERS | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index c45c02b..040b7b7 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11084,6 +11084,11 @@ M:	Andreas Noever <andreas.noever@gmail.com>
 S:	Maintained
 F:	drivers/thunderbolt/
 
+THUNDERX GPIO DRIVER
+M:	David Daney <david.daney@cavium.com>
+S:	Maintained
+F:	drivers/gpio/gpio-thunderx.c
+
 TI BQ27XXX POWER SUPPLY DRIVER
 R:	Andrew F. Davis <afd@ti.com>
 F:	include/linux/power/bq27xxx_battery.h
-- 
1.8.3.1

^ permalink raw reply related

* Re: [PATCH v2 1/5] dt-bindings: gpu: add bindings for the ARM Mali Midgard GPU
From: Guillaume Tucker @ 2017-04-11 17:40 UTC (permalink / raw)
  To: Neil Armstrong, Rob Herring, Mark Rutland, Heiko Stuebner
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, Sjoerd Simons, Wookey,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-rockchip-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, John Reitan,
	Enric Balletbo i Serra,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <a01a50d3-bb1b-2c56-2a15-30651fa2fac9-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>

On 03/04/17 09:12, Neil Armstrong wrote:
> On 04/02/2017 09:59 AM, Guillaume Tucker wrote:
>> The ARM Mali Midgard GPU family is present in a number of SoCs
>> from many different vendors such as Samsung Exynos and Rockchip.
>>
>> Import the device tree bindings documentation from the r16p0
>> release of the Mali Midgard GPU kernel driver:
>>
>>   https://developer.arm.com/-/media/Files/downloads/mali-drivers/kernel/mali-midgard-gpu/TX011-SW-99002-r16p0-00rel0.tgz
>>
>> The following optional bindings have been omitted in this initial
>> version as they are only used in very specific cases:
>>
>>   * snoop_enable_smc
>>   * snoop_disable_smc
>>   * jm_config
>>   * power_model
>>   * system-coherency
>>   * ipa-model
>>
>> The example has been simplified accordingly.
>>
>> The compatible string definition has been limited to
>> "arm,mali-midgard" to avoid checkpatch.pl warnings and to match
>> what the driver actually expects (as of r16p0 out-of-tree).
>>
>> CC: John Reitan <john.reitan-5wv7dgnIgG8@public.gmane.org>
>> Signed-off-by: Guillaume Tucker <guillaume.tucker-ZGY8ohtN/8qB+jHODAdFcQ@public.gmane.org>
>> ---
>>  .../devicetree/bindings/gpu/arm,mali-midgard.txt   | 53 ++++++++++++++++++++++
>>  1 file changed, 53 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/gpu/arm,mali-midgard.txt
>>
>> diff --git a/Documentation/devicetree/bindings/gpu/arm,mali-midgard.txt b/Documentation/devicetree/bindings/gpu/arm,mali-midgard.txt
>> new file mode 100644
>> index 000000000000..da8fc6d21bbf
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/gpu/arm,mali-midgard.txt
>> @@ -0,0 +1,53 @@
>> +#
>> +# (C) COPYRIGHT 2013-2016 ARM Limited.
>> +# Copyright (C) 2017 Collabora Ltd
>> +#
>> +# This program is free software and is provided to you under the terms of the
>> +# GNU General Public License version 2 as published by the Free Software
>> +# Foundation, and any use by you of this program is subject to the terms
>> +# of such GNU licence.
>> +#
> Hi Guillaume,
> This is unnecessary, please remove.

Hi Neil,

I see most other documentation files don't have such a header,
including the arm,mali-utgard.txt one.  I left it in my patch
after copying the file from the driver tarball as removing it
didn't seem right from a GPL and copyright point of view.  If
it's safe in practice to remove it then fine.

>> +
>> +
>> +ARM Mali Midgard GPU
>> +====================
>> +
>> +Required properties:
>> +
>> +- compatible : Should be "arm,mali-midgard".
>> +- reg : Physical base address of the device and length of the register area.
>> +- interrupts : Contains the three IRQ lines required by Mali Midgard devices.
>> +- interrupt-names : Contains the names of IRQ resources in the order they were
>> +  provided in the interrupts property. Must contain: "JOB, "MMU", "GPU".
>
>
> Please follow the bindings introduced for the utgard family :
> https://patchwork.kernel.org/patch/9553745/
>
> - an entry for each mali-midgard revision, i.e. "arm,mali-t820"

Sure.  It's a bit more complicated with Midgard (more variants,
some have the number of cores in the last digit...) but it should
be possible to put together a suitable list in v3.

> - an entry for each vendor specific wrapping if necessary, i.e. "amlogic,meson-gxm-mali"

Well, fine although I'm a bit confused about this - please see
below.

> - low-case for interrupt names

OK, can change that in v3.  It means however that the out-of-tree
driver will need to be patched as it's looking for these names in
capital letters.  This shouldn't be a big issue but adds a bit of
work to anyone maintaining a kernel driver package.

>> +
>> +Optional:
>> +
>> +- clocks : Phandle to clock for the Mali Midgard device.
>> +- clock-names : Shall be "clk_mali".
>> +- mali-supply : Phandle to regulator for the Mali device. Refer to
>> +  Documentation/devicetree/bindings/regulator/regulator.txt for details.
>> +- operating-points : Refer to Documentation/devicetree/bindings/power/opp.txt
>> +  for details.
>
> Please add :
>    * Must be one of the following:
>       "arm,mali-t820"
>    * And, optionally, one of the vendor specific compatible:
>       "amlogic,meson-gxm-mali"
>
> with my Ack for the amlogic platform.

It seems to me that as long as the GPU architecture hasn't been
modified (I don't think I've ever encountered such a case) then
it has to be a standard ARM Mali type regardless of the SoC
vendor.  So unless a Mali-T820 in the Amlogic S912 SoC is not the
same as a T820 in a different SoC, please forgive me but I don't
understand why a vendor compatible string is needed.  My main
concern is that it's going to be very hard to keep that list
up-to-date with all existing Midgard SoC variants.  If do we need
to add vendor compatible strings to correctly describe the
hardware then I'm happy to add the amlogic one in my patch v3; I
would just like to understand why that's necessary.


Thanks,
Guillaume


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

^ permalink raw reply

* Re: [PATCH 1/2] leds: Add driver for Qualcomm LPG
From: Pavel Machek @ 2017-04-11 17:54 UTC (permalink / raw)
  To: Bjorn Andersson
  Cc: Jacek Anaszewski, Rob Herring, Richard Purdie, linux-kernel,
	linux-leds, linux-arm-msm, Mark Rutland, devicetree
In-Reply-To: <20170410191948.GE15143@minitux>

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

Hi!

> > > How do we do with patterns that are implementable by the LP5xx but are
> > > not with the LPG? Should we reject those or should we do some sort of
> > > best-effort approach in the kernel?
> > 
> > Lets say you get series of
> > 
> > (red, green, blue, delta_t )
> > 
> > points, meaning "in delta_t msec, change color to red, green,
> > blue. Lets ignore other channels for now. delta_t of 0 would be step
> > change. Would such interface work for you?
> 
> So I presume this would be input to the RGB trigger that we discussed.
> But in my current device I have 6 LEDs, that are not in any RGB-like
> configuration. So we would need to come up with an interface that looks
> to be the same in both single-LED and RGB-LED setups.

Ok.

> This should be sufficient to describe a subset of the patterns I've seen
> so far in products.
> 
> But let's consider the standard use case for an RGB LED on an Android
> phone; continuously blinking (pulsing based on patterns) as you have
> some notifications waiting. In this case you want the LED hardware to do
> all the work, so that you can deep-idle the CPU. So we would need to
> introduce a "repeat pattern"-command.

I'd say have additional parameter with number of repetitions. Yes. In
your case you can do 1 and infinity, LP5XX can do 1-255 or infinity.

> Then consider the fact that you want your patterns to have decent
> resolution, but you have a limited amount of storage. So we either have
> to be able to detect palindromes or have a way to represent this.

I'm not sure how common hardware support for palindromes is going to
be. I'd say "detect", but...

> > Simple compiler from this to LP5XX code should not be hard to
> > do.
> 
> It sounds fairly straight forward to convert a pattern to instructions,
> but we do have an extremely limited amount of storage so it must be a
> quite good implementation for people to be able to use it for anything
> real.
> 
> We could implement some optimization steps where we try to detect slopes
> and generate ramp-instructions instead of set-pwm + wait instructions,
> use some variables to handle ramp up/down and we could probably generate
> some jump instructions to implement loops.

Actually it is easier than that. Hardware can do slopes itself. If we
see change with non-zero delta_t, we issue slope, otherwise we issue
set_value.

Here's example "compiler": https://gitlab.com/tui/tui/blob/master/ofone/notcc.py
Here's example "program": https://gitlab.com/tui/tui/blob/master/ofone/tests.notcc/primes.nc

> But do we really want this logic in the kernel, for each LED chip
> supporting patterns?

I'd say so, yes. It should be, dunno, 200? 500? lines of code for
LP5XX?  Sounds acceptable.

Otherwise we'd have to have led-chip-dependend part in userspace. That
would be ok... but we'd _still_ need led-chip-dependend part in the
kernel... and driver spread between kernel and userland is difficult.

The code needs to be created, anyway, so lets put it in kernel.

> > AS3676 ... I'm not sure what to do, AFAICT it is too limited.
> > 
> 
> So out of the three examples I've looked at we're skipping one and we're
> abstracting away most functionality from another.

Well. We don't need to _skip_ AS3676, but its pattern engine is
basically useless for anything involving different PWM levels.

And abstracting away most of LP5XX functionality... well, you can
compute prime numbers on that chip (see example above), but you better
should not. And patterns we'll pretty much expose all the functionality.

> I'm sorry for being pessimistic about this, but while I can see the
> theoretical benefit of providing a uniform interface for this to user
> space I see three very different pieces of hardware that would be used
> in three different ways in products.

Three different pieces of hardware, at least two of them used in
phones to provide blinking leds... I'd say common interface is the
right thing to do.
								Pavel
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 181 bytes --]

^ permalink raw reply

* Re: Re: [PATCH v2 03/11] dt-bindings: add device tree binding for X-Powers AXP803 PMIC
From: Icenowy Zheng @ 2017-04-11 18:08 UTC (permalink / raw)
  To: Lee Jones
  Cc: linux-arm-kernel, linux-sunxi, Rob Herring, linux-kernel,
	Liam Girdwood, devicetree, Maxime Ripard, Chen-Yu Tsai


2017年4月12日 上午12:29于 Lee Jones <lee.jones-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>写道:
>
> On Tue, 11 Apr 2017, Chen-Yu Tsai wrote:
>
> > Hi,
> > 
> > On Tue, Apr 11, 2017 at 11:00 PM, Icenowy Zheng <icenowy-h8G6r0blFSE@public.gmane.org> wrote:
> > >
> > >
> > > On Tue, 11 Apr 2017, Lee Jones wrote:
> > >
> > >> On Sat, 08 Apr 2017, Icenowy Zheng wrote:
> > >>
> > >>> AXP803 is a PMIC produced by Shenzhen X-Powers, with either I2C or RSB
> > >>> bus.
> > >>>
> > >>> Add a compatible for it.
> > >>>
> > >>> Signed-off-by: Icenowy Zheng <icenowy-h8G6r0blFSE@public.gmane.org>
> > >>> Acked-by: Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>
> > >>> ---
> > >>> Changes in v2:
> > >>> - Place AXP803 before AXP806/809.
> > >>> - Added Chen-Yu's ACK.
> > >>>
> > >>>  Documentation/devicetree/bindings/mfd/axp20x.txt | 5 +++--
> > >>>  1 file changed, 3 insertions(+), 2 deletions(-)
> > >>
> > >>
> > >> For my own reference:
> > >>  Acked-for-MFD-by: Lee Jones <lee.jones-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> > >
> > >
> > > Excuse me... Who will apply this patch?
>
> Excuse you?  Are you trying to be polite, or rude?
>
> I'm guessing due to the lagging '...', that it's the latter?

Oh sorry, I mean the former...

>
> > > I think this patch should be applied by you as it's in bindings/mfd
> > > directory, however, if I'm wrong, please point out ;-)
> >
> > We need the DT maintainers to ack it first. :)
>
> We don't really need the DT Maintainers to get involved here.
>
> What I do need is either clear direction as to how this
> patch-set should be applied, or an indication of which patches are
> dependant on others and which are orthogonal and can be applied
> independently.

This patch is independent, although the regulator binding patch
depends on it.

The real driver patches will need the binding patches to be merged
first.

And the dt patches depend on also the binding patches.

>
> -- 
> Lee Jones
> Linaro STMicroelectronics Landing Team Lead
> Linaro.org │ Open source software for ARM SoCs
> Follow Linaro: Facebook | Twitter | Blog
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

^ permalink raw reply

* Re: [linux-sunxi] Re: [PATCH v2 03/11] dt-bindings: add device tree binding for X-Powers AXP803 PMIC
From: Icenowy Zheng @ 2017-04-11 18:08 UTC (permalink / raw)
  To: Lee Jones
  Cc: linux-arm-kernel, linux-sunxi, Rob Herring, linux-kernel,
	Liam Girdwood, devicetree, Maxime Ripard, Chen-Yu Tsai


2017年4月12日 上午12:29于 Lee Jones <lee.jones@linaro.org>写道:
>
> On Tue, 11 Apr 2017, Chen-Yu Tsai wrote:
>
> > Hi,
> > 
> > On Tue, Apr 11, 2017 at 11:00 PM, Icenowy Zheng <icenowy@aosc.io> wrote:
> > >
> > >
> > > On Tue, 11 Apr 2017, Lee Jones wrote:
> > >
> > >> On Sat, 08 Apr 2017, Icenowy Zheng wrote:
> > >>
> > >>> AXP803 is a PMIC produced by Shenzhen X-Powers, with either I2C or RSB
> > >>> bus.
> > >>>
> > >>> Add a compatible for it.
> > >>>
> > >>> Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
> > >>> Acked-by: Chen-Yu Tsai <wens@csie.org>
> > >>> ---
> > >>> Changes in v2:
> > >>> - Place AXP803 before AXP806/809.
> > >>> - Added Chen-Yu's ACK.
> > >>>
> > >>>  Documentation/devicetree/bindings/mfd/axp20x.txt | 5 +++--
> > >>>  1 file changed, 3 insertions(+), 2 deletions(-)
> > >>
> > >>
> > >> For my own reference:
> > >>  Acked-for-MFD-by: Lee Jones <lee.jones@linaro.org>
> > >
> > >
> > > Excuse me... Who will apply this patch?
>
> Excuse you?  Are you trying to be polite, or rude?
>
> I'm guessing due to the lagging '...', that it's the latter?

Oh sorry, I mean the former...

>
> > > I think this patch should be applied by you as it's in bindings/mfd
> > > directory, however, if I'm wrong, please point out ;-)
> >
> > We need the DT maintainers to ack it first. :)
>
> We don't really need the DT Maintainers to get involved here.
>
> What I do need is either clear direction as to how this
> patch-set should be applied, or an indication of which patches are
> dependant on others and which are orthogonal and can be applied
> independently.

This patch is independent, although the regulator binding patch
depends on it.

The real driver patches will need the binding patches to be merged
first.

And the dt patches depend on also the binding patches.

>
> -- 
> Lee Jones
> Linaro STMicroelectronics Landing Team Lead
> Linaro.org │ Open source software for ARM SoCs
> Follow Linaro: Facebook | Twitter | Blog
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH v2 2/2] mtd: spi-nor: add driver for STM32 quad spi flash controller
From: Marek Vasut @ 2017-04-11 18:31 UTC (permalink / raw)
  To: Ludovic BARRE, Cyrille Pitchen
  Cc: David Woodhouse, Brian Norris, Boris Brezillon,
	Richard Weinberger, Alexandre Torgue, Rob Herring,
	linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <f9b4b8b0-4987-7f67-df3b-d32d6c130818-qxv4g6HH51o@public.gmane.org>

On 04/10/2017 06:52 PM, Ludovic BARRE wrote:
> hi Marek
> 
> tomorrow, I send a v3 with your/Rob reviews.

Super, thanks! I'll be pretty busy till Friday, so please keep in mind
the final review might take a bit.

> BR
> 
> Ludo
> 
> 
> On 04/10/2017 06:15 PM, Marek Vasut wrote:
>> On 04/10/2017 11:08 AM, Ludovic BARRE wrote:
>>> On 04/07/2017 01:55 AM, Marek Vasut wrote:
>>>> On 03/31/2017 07:02 PM, Ludovic Barre wrote:
>>>>> From: Ludovic Barre <ludovic.barre-qxv4g6HH51o@public.gmane.org>
>>>>>
>>>>> The quadspi is a specialized communication interface targeting single,
>>>>> dual or quad SPI Flash memories.
>>>>>
>>>>> It can operate in any of the following modes:
>>>>> -indirect mode: all the operations are performed using the quadspi
>>>>>    registers
>>>>> -read memory-mapped mode: the external Flash memory is mapped to the
>>>>>    microcontroller address space and is seen by the system as if it
>>>>> was
>>>>>    an internal memory
>>>>>
>>>>> Signed-off-by: Ludovic Barre <ludovic.barre-qxv4g6HH51o@public.gmane.org>
>>>>> ---
>>>>>    drivers/mtd/spi-nor/Kconfig         |   7 +
>>>>>    drivers/mtd/spi-nor/Makefile        |   1 +
>>>>>    drivers/mtd/spi-nor/stm32-quadspi.c | 690
>>>>> ++++++++++++++++++++++++++++++++++++
>>>>>    3 files changed, 698 insertions(+)
>>>>>    create mode 100644 drivers/mtd/spi-nor/stm32-quadspi.c
>>>>>
>>>> [...]
>>>>
>>>>> +struct stm32_qspi_flash {
>>>>> +    struct spi_nor nor;
>>>>> +    u32 cs;
>>>>> +    u32 fsize;
>>>>> +    u32 presc;
>>>>> +    struct stm32_qspi *qspi;
>>>>> +};
>>>> [...]
>>>>
>>>>> +struct stm32_qspi_cmd {
>>>>> +    struct {
>>>>> +        u8 addr_width;
>>>>> +        u8 dummy;
>>>>> +        u8 data;
>>>>> +    } conf;
>>>> Is there any benefit in having this structure here or could you just
>>>> make the struct stm32_qspi_cmd flat ?
>>> no benefit, it was just to regroup,  so I can do a flat structure
>> Well, as you like, but I think it does make sense to just make it flat.
>>
>>>>> +    u8 opcode;
>>>>> +    u32 framemode;
>>>>> +    u32 qspimode;
>>>>> +    u32 addr;
>>>>> +    size_t len;
>>>>> +    void *buf;
>>>>> +};
>>>> [...]
>>>>
>>>>> +static ssize_t stm32_qspi_read(struct spi_nor *nor, loff_t from,
>>>>> size_t len,
>>>>> +                   u_char *buf)
>>>>> +{
>>>>> +    struct stm32_qspi_flash *flash = nor->priv;
>>>>> +    struct stm32_qspi *qspi = flash->qspi;
>>>>> +    struct stm32_qspi_cmd cmd;
>>>>> +    int err;
>>>>> +
>>>>> +    dev_dbg(qspi->dev, "read(%#.2x): buf:%p from:%#.8x len:%#x\n",
>>>>> +        nor->read_opcode, buf, (u32)from, len);
>>>>> +
>>>>> +    memset(&cmd, 0, sizeof(cmd));
>>>>> +    cmd.opcode = nor->read_opcode;
>>>>> +    cmd.conf.addr_width = nor->addr_width;
>>>>> +    cmd.addr = (u32)from;
>>>> loff_t (from) can be 64bit ... how do we handle this ?
>>> I'm surprise by the question,
>>> the SPI NOR device uses 3 Bytes or 4 bytes address mode.
>>> So, the stm32 qspi controller has a 32 bit register for NOR address.
>>> On the other hand the framework and other drivers used this variable
>>> (from) like
>>> a 32 bits.
>> Hmmm, (rhetorical question) then why do we even use loff_t in the
>> framework ?
>>
>> Anyway, this is no problem then.
> In fact, the loff_t 64 bit come from mtd interface
> (needed to address biggest device constraint) but not needed for spi-nor
> devices.
>>>>> +    cmd.conf.data = 1;
>>>>> +    cmd.conf.dummy = nor->read_dummy;
>>>>> +    cmd.len = len;
>>>>> +    cmd.buf = buf;
>>>>> +    cmd.qspimode = qspi->read_mode;
>>>>> +
>>>>> +    stm32_qspi_set_framemode(nor, &cmd, true);
>>>>> +    err = stm32_qspi_send(flash, &cmd);
>>>>> +
>>>>> +    return err ? err : len;
>>>>> +}
>>>> [...]
>>>>
>>>>> +static irqreturn_t stm32_qspi_irq(int irq, void *dev_id)
>>>>> +{
>>>>> +    struct stm32_qspi *qspi = (struct stm32_qspi *)dev_id;
>>>>> +    u32 cr, sr, fcr = 0;
>>>>> +
>>>>> +    cr = readl_relaxed(qspi->io_base + QUADSPI_CR);
>>>>> +    sr = readl_relaxed(qspi->io_base + QUADSPI_SR);
>>>>> +
>>>>> +    if ((cr & CR_TCIE) && (sr & SR_TCF)) {
>>>>> +        /* tx complete */
>>>>> +        fcr |= FCR_CTCF;
>>>>> +        complete(&qspi->cmd_completion);
>>>>> +    } else {
>>>>> +        dev_info(qspi->dev, "spurious interrupt\n");
>>>> You probably want to ratelimit this one ...
>>> yes it's better if there is an issue.
>> Yep
>>
>>>>> +    }
>>>>> +
>>>>> +    writel_relaxed(fcr, qspi->io_base + QUADSPI_FCR);
>>>>> +
>>>>> +    return IRQ_HANDLED;
>>>>> +}
>>>>> +
>>>>> +static int stm32_qspi_prep(struct spi_nor *nor, enum spi_nor_ops ops)
>>>>> +{
>>>>> +    struct stm32_qspi_flash *flash = nor->priv;
>>>>> +    struct stm32_qspi *qspi = flash->qspi;
>>>>> +
>>>>> +    mutex_lock(&qspi->lock);
>>>>> +    return 0;
>>>>> +}
>>>>> +
>>>>> +static void stm32_qspi_unprep(struct spi_nor *nor, enum spi_nor_ops
>>>>> ops)
>>>>> +{
>>>>> +    struct stm32_qspi_flash *flash = nor->priv;
>>>>> +    struct stm32_qspi *qspi = flash->qspi;
>>>>> +
>>>>> +    mutex_unlock(&qspi->lock);
>>>>> +}
>>>>> +
>>>>> +static int stm32_qspi_flash_setup(struct stm32_qspi *qspi,
>>>>> +                  struct device_node *np)
>>>>> +{
>>>>> +    u32 width, flash_read, presc, cs_num, max_rate = 0;
>>>>> +    struct stm32_qspi_flash *flash;
>>>>> +    struct mtd_info *mtd;
>>>>> +    int ret;
>>>>> +
>>>>> +    of_property_read_u32(np, "reg", &cs_num);
>>>>> +    if (cs_num >= STM32_MAX_NORCHIP)
>>>>> +        return -EINVAL;
>>>>> +
>>>>> +    of_property_read_u32(np, "spi-max-frequency", &max_rate);
>>>>> +    if (!max_rate)
>>>>> +        return -EINVAL;
>>>>> +
>>>>> +    presc = DIV_ROUND_UP(qspi->clk_rate, max_rate) - 1;
>>>>> +
>>>>> +    if (of_property_read_u32(np, "spi-rx-bus-width", &width))
>>>>> +        width = 1;
>>>>> +
>>>>> +    if (width == 4)
>>>>> +        flash_read = SPI_NOR_QUAD;
>>>>> +    else if (width == 2)
>>>>> +        flash_read = SPI_NOR_DUAL;
>>>>> +    else if (width == 1)
>>>>> +        flash_read = SPI_NOR_NORMAL;
>>>>> +    else
>>>>> +        return -EINVAL;
>>>>> +
>>>>> +    flash = &qspi->flash[cs_num];
>>>>> +    flash->qspi = qspi;
>>>>> +    flash->cs = cs_num;
>>>>> +    flash->presc = presc;
>>>>> +
>>>>> +    flash->nor.dev = qspi->dev;
>>>>> +    spi_nor_set_flash_node(&flash->nor, np);
>>>>> +    flash->nor.priv = flash;
>>>>> +    mtd = &flash->nor.mtd;
>>>>> +    mtd->priv = &flash->nor;
>>>>> +
>>>>> +    flash->nor.read = stm32_qspi_read;
>>>>> +    flash->nor.write = stm32_qspi_write;
>>>>> +    flash->nor.erase = stm32_qspi_erase;
>>>>> +    flash->nor.read_reg = stm32_qspi_read_reg;
>>>>> +    flash->nor.write_reg = stm32_qspi_write_reg;
>>>>> +    flash->nor.prepare = stm32_qspi_prep;
>>>>> +    flash->nor.unprepare = stm32_qspi_unprep;
>>>>> +
>>>>> +    writel_relaxed(LPTR_DFT_TIMEOUT, qspi->io_base + QUADSPI_LPTR);
>>>>> +
>>>>> +    writel_relaxed(CR_PRESC(presc) | CR_FTHRES(3) | CR_TCEN |
>>>>> CR_SSHIFT
>>>>> +               | CR_EN, qspi->io_base + QUADSPI_CR);
>>>>> +
>>>>> +    /*
>>>>> +     * in stm32 qspi controller, QUADSPI_DCR register has a fsize
>>>>> field
>>>>> +     * which define the size of nor flash.
>>>>> +     * if fsize is NULL, the controller can't sent spi-nor command.
>>>>> +     * set a temporary value just to discover the nor flash with
>>>>> +     * "spi_nor_scan". After, the right value (mtd->size) can be set.
>>>>> +     */
>>>> Is 25 the smallest value ? Use a macro for this ...
>>> 25 is an arbitrary choice, I will define a smallest value
>> Cool, thanks!
>>
> 


-- 
Best regards,
Marek Vasut
--
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 06/16] regulator: madera-ldo1: LDO1 driver for Cirrus Logic Madera codecs
From: Rob Herring @ 2017-04-11 19:20 UTC (permalink / raw)
  To: Mark Brown
  Cc: Richard Fitzgerald, Linus Walleij, Alexandre Courbot,
	Thomas Gleixner, Jason Cooper, Lee Jones, Linux-ALSA,
	patches-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E,
	linux-gpio-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <20170410181136.btpvcat2ijwiebvm-GFdadSzt00ze9xe1eoZjHA@public.gmane.org>

On Mon, Apr 10, 2017 at 1:11 PM, Mark Brown <broonie-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> wrote:
> On Mon, Apr 10, 2017 at 12:49:17PM -0500, Rob Herring wrote:
>
>> Same question as Mark. Should this share bindings with arizona? The
>> arizona one looks a bit strange, so not sure we'd want to just copy it.
>
> In what way?  Other than the -gpios stuff (which would just be a trivial
> thing if we wanted to change it)?

That's mainly it. It's not clear which node wlf,ldoena goes in either.
In the parent? ldo1?

Rob
--
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: [GIT PULL] PCI: Support for configurable PCI endpoint
From: Bjorn Helgaas @ 2017-04-11 19:34 UTC (permalink / raw)
  To: Kishon Vijay Abraham I
  Cc: devicetree, Joao Pinto, linux-doc, linux-pci, nsekhar,
	linux-kernel, hch, Bjorn Helgaas, linux-omap, linux-arm-kernel
In-Reply-To: <20170410154328.GB13170@bhelgaas-glaptop.roam.corp.google.com>

On Mon, Apr 10, 2017 at 10:43:28AM -0500, Bjorn Helgaas wrote:
> On Wed, Apr 05, 2017 at 02:22:20PM +0530, Kishon Vijay Abraham I wrote:
> > Hi Bjorn,
> > 
> > Please find the pull request for PCI endpoint support below. I've
> > also included all the history here.
> 
> Thanks, I applied these (with v7 of the first patch) to pci/host-designware
> for v4.12.

Ok, sorry, I screwed this up.  I think my branch actually had v5, not
v6.  But I *think* I fixed it.  Here's the diff from my branch to your
git tree.  Apparently you haven't pushed the v7 patch there, so I
*think* the diff below is the diff between v6 and v7 of that first
patch.

$ git diff pci/host-designware a5c85ba45c96
diff --git a/drivers/pci/endpoint/pci-epc-core.c b/drivers/pci/endpoint/pci-epc-core.c
index caa7be10e473..9ae9e59b2a74 100644
--- a/drivers/pci/endpoint/pci-epc-core.c
+++ b/drivers/pci/endpoint/pci-epc-core.c
@@ -83,7 +83,6 @@ struct pci_epc *pci_epc_get(const char *epc_name)
 			goto err;
 		}
 
-		class_dev_iter_exit(&iter);
 		get_device(&epc->dev);
 		return epc;
 	}
diff --git a/drivers/pci/endpoint/pci-epf-core.c b/drivers/pci/endpoint/pci-epf-core.c
index 6877d6a5bcc9..92db7dcd911c 100644
--- a/drivers/pci/endpoint/pci-epf-core.c
+++ b/drivers/pci/endpoint/pci-epf-core.c
@@ -40,10 +40,8 @@ static struct device_type pci_epf_type;
  */
 void pci_epf_linkup(struct pci_epf *epf)
 {
-	if (!epf->driver) {
+	if (!epf->driver)
 		dev_WARN(&epf->dev, "epf device not bound to driver\n");
-		return;
-	}
 
 	epf->driver->ops->linkup(epf);
 }
@@ -59,10 +57,8 @@ EXPORT_SYMBOL_GPL(pci_epf_linkup);
  */
 void pci_epf_unbind(struct pci_epf *epf)
 {
-	if (!epf->driver) {
+	if (!epf->driver)
 		dev_WARN(&epf->dev, "epf device not bound to driver\n");
-		return;
-	}
 
 	epf->driver->ops->unbind(epf);
 	module_put(epf->driver->owner);
@@ -78,10 +74,8 @@ EXPORT_SYMBOL_GPL(pci_epf_unbind);
  */
 int pci_epf_bind(struct pci_epf *epf)
 {
-	if (!epf->driver) {
+	if (!epf->driver)
 		dev_WARN(&epf->dev, "epf device not bound to driver\n");
-		return -EINVAL;
-	}
 
 	if (!try_module_get(epf->driver->owner))
 		return -EAGAIN;
@@ -233,7 +227,7 @@ struct pci_epf *pci_epf_create(const char *name)
 	epf->name = kstrdup(func_name, GFP_KERNEL);
 	if (!epf->name) {
 		ret = -ENOMEM;
-		goto free_func_name;
+		goto free_epf;
 	}
 
 	dev = &epf->dev;
@@ -255,8 +249,6 @@ struct pci_epf *pci_epf_create(const char *name)
 put_dev:
 	put_device(dev);
 	kfree(epf->name);
-
-free_func_name:
 	kfree(func_name);
 
 free_epf:

^ permalink raw reply related

* Re: [PATCH v2 1/2] clk: imx7d: fix USDHC NAND clock
From: Dong Aisheng @ 2017-04-11 19:59 UTC (permalink / raw)
  To: Stefan Agner
  Cc: shawnguo-DgEjT+Ai2ygdnm+yROfE0A, kernel-bIcnvbaLZ9MEGnE8C9+IrQ,
	sboyd-sgV2jX0FEOL9JmXXK+q4OQ, aisheng.dong-3arQi8VN3Tc,
	fabio.estevam-3arQi8VN3Tc, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	mark.rutland-5wv7dgnIgG8,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-clk-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20170410210015.1620-1-stefan-XLVq0VzYD2Y@public.gmane.org>

On Mon, Apr 10, 2017 at 02:00:14PM -0700, Stefan Agner wrote:
> The USDHC NAND root clock is not gated by any CCM clock gate. Remove
> the bogus gate definition.
> 
> Signed-off-by: Stefan Agner <stefan-XLVq0VzYD2Y@public.gmane.org>

Acked-by: Dong Aisheng <aisheng.dong-3arQi8VN3Tc@public.gmane.org>

Regards
Dong Aisheng

> ---
>  drivers/clk/imx/clk-imx7d.c | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
> 
> diff --git a/drivers/clk/imx/clk-imx7d.c b/drivers/clk/imx/clk-imx7d.c
> index 562055129ed8..93b03640da9b 100644
> --- a/drivers/clk/imx/clk-imx7d.c
> +++ b/drivers/clk/imx/clk-imx7d.c
> @@ -724,7 +724,7 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
>  	clks[IMX7D_MAIN_AXI_ROOT_DIV] = imx_clk_divider2("axi_post_div", "axi_pre_div", base + 0x8800, 0, 6);
>  	clks[IMX7D_DISP_AXI_ROOT_DIV] = imx_clk_divider2("disp_axi_post_div", "disp_axi_pre_div", base + 0x8880, 0, 6);
>  	clks[IMX7D_ENET_AXI_ROOT_DIV] = imx_clk_divider2("enet_axi_post_div", "enet_axi_pre_div", base + 0x8900, 0, 6);
> -	clks[IMX7D_NAND_USDHC_BUS_ROOT_DIV] = imx_clk_divider2("nand_usdhc_post_div", "nand_usdhc_pre_div", base + 0x8980, 0, 6);
> +	clks[IMX7D_NAND_USDHC_BUS_ROOT_CLK] = imx_clk_divider2("nand_usdhc_root_clk", "nand_usdhc_pre_div", base + 0x8980, 0, 6);
>  	clks[IMX7D_AHB_CHANNEL_ROOT_DIV] = imx_clk_divider2("ahb_root_clk", "ahb_pre_div", base + 0x9000, 0, 6);
>  	clks[IMX7D_IPG_ROOT_CLK] = imx_clk_divider2("ipg_root_clk", "ahb_root_clk", base + 0x9080, 0, 2);
>  	clks[IMX7D_DRAM_ROOT_DIV] = imx_clk_divider2("dram_post_div", "dram_cg", base + 0x9880, 0, 3);
> @@ -798,7 +798,6 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
>  	clks[IMX7D_ENET_AXI_ROOT_CLK] = imx_clk_gate4("enet_axi_root_clk", "enet_axi_post_div", base + 0x4060, 0);
>  	clks[IMX7D_OCRAM_CLK] = imx_clk_gate4("ocram_clk", "axi_post_div", base + 0x4110, 0);
>  	clks[IMX7D_OCRAM_S_CLK] = imx_clk_gate4("ocram_s_clk", "ahb_root_clk", base + 0x4120, 0);
> -	clks[IMX7D_NAND_USDHC_BUS_ROOT_CLK] = imx_clk_gate4("nand_usdhc_root_clk", "nand_usdhc_post_div", base + 0x4130, 0);
>  	clks[IMX7D_DRAM_ROOT_CLK] = imx_clk_gate4("dram_root_clk", "dram_post_div", base + 0x4130, 0);
>  	clks[IMX7D_DRAM_PHYM_ROOT_CLK] = imx_clk_gate4("dram_phym_root_clk", "dram_phym_cg", base + 0x4130, 0);
>  	clks[IMX7D_DRAM_PHYM_ALT_ROOT_CLK] = imx_clk_gate4("dram_phym_alt_root_clk", "dram_phym_alt_post_div", base + 0x4130, 0);
> -- 
> 2.12.1
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-clk" in
> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH v2 2/2] ARM: dts: imx7: add USDHC NAND and IPG clock to SDHC instances
From: Dong Aisheng @ 2017-04-11 20:00 UTC (permalink / raw)
  To: Stefan Agner
  Cc: shawnguo, kernel, sboyd, aisheng.dong, fabio.estevam, robh+dt,
	mark.rutland, linux-arm-kernel, devicetree, linux-clk,
	linux-kernel
In-Reply-To: <20170410210015.1620-2-stefan@agner.ch>

On Mon, Apr 10, 2017 at 02:00:15PM -0700, Stefan Agner wrote:
> The USDHC instances need the USDHC NAND and IPG clock in order to
> operate. Reference them properly by replacing the dummy clocks with
> the actual clocks.
> 
> Note that both clocks are currently implicitly enabled since they
> are part of the i.MX 7 clock drivers init_on list. This might
> change in the future.
> 
> Signed-off-by: Stefan Agner <stefan@agner.ch>

Acked-by: Dong Aisheng <aisheng.dong@nxp.com>

Regards
Dong Aisheng

> ---
> This patch depends on "clk: imx7d: add the missing ipg_root_clk"
> which adds the IPG clock.
> 
> --
> Stefan
> 
>  arch/arm/boot/dts/imx7s.dtsi | 12 ++++++------
>  1 file changed, 6 insertions(+), 6 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/imx7s.dtsi b/arch/arm/boot/dts/imx7s.dtsi
> index c4f12fd2e044..843eb379e1ea 100644
> --- a/arch/arm/boot/dts/imx7s.dtsi
> +++ b/arch/arm/boot/dts/imx7s.dtsi
> @@ -934,8 +934,8 @@
>  				compatible = "fsl,imx7d-usdhc", "fsl,imx6sl-usdhc";
>  				reg = <0x30b40000 0x10000>;
>  				interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
> -				clocks = <&clks IMX7D_CLK_DUMMY>,
> -					<&clks IMX7D_CLK_DUMMY>,
> +				clocks = <&clks IMX7D_IPG_ROOT_CLK>,
> +					<&clks IMX7D_NAND_USDHC_BUS_ROOT_CLK>,
>  					<&clks IMX7D_USDHC1_ROOT_CLK>;
>  				clock-names = "ipg", "ahb", "per";
>  				bus-width = <4>;
> @@ -946,8 +946,8 @@
>  				compatible = "fsl,imx7d-usdhc", "fsl,imx6sl-usdhc";
>  				reg = <0x30b50000 0x10000>;
>  				interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
> -				clocks = <&clks IMX7D_CLK_DUMMY>,
> -					<&clks IMX7D_CLK_DUMMY>,
> +				clocks = <&clks IMX7D_IPG_ROOT_CLK>,
> +					<&clks IMX7D_NAND_USDHC_BUS_ROOT_CLK>,
>  					<&clks IMX7D_USDHC2_ROOT_CLK>;
>  				clock-names = "ipg", "ahb", "per";
>  				bus-width = <4>;
> @@ -958,8 +958,8 @@
>  				compatible = "fsl,imx7d-usdhc", "fsl,imx6sl-usdhc";
>  				reg = <0x30b60000 0x10000>;
>  				interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
> -				clocks = <&clks IMX7D_CLK_DUMMY>,
> -					<&clks IMX7D_CLK_DUMMY>,
> +				clocks = <&clks IMX7D_IPG_ROOT_CLK>,
> +					<&clks IMX7D_NAND_USDHC_BUS_ROOT_CLK>,
>  					<&clks IMX7D_USDHC3_ROOT_CLK>;
>  				clock-names = "ipg", "ahb", "per";
>  				bus-width = <4>;
> -- 
> 2.12.1
> 

^ permalink raw reply

* Re: [PATCH 06/16] regulator: madera-ldo1: LDO1 driver for Cirrus Logic Madera codecs
From: Mark Brown @ 2017-04-11 20:03 UTC (permalink / raw)
  To: Rob Herring
  Cc: Richard Fitzgerald, Linus Walleij, Alexandre Courbot,
	Thomas Gleixner, Jason Cooper, Lee Jones, Linux-ALSA,
	patches-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E,
	linux-gpio-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <CAL_JsqLYi8txm2xb5emGvbC0P2cvtW2wXLdA=2qCO-wt_4JXXA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>

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

On Tue, Apr 11, 2017 at 02:20:31PM -0500, Rob Herring wrote:
> On Mon, Apr 10, 2017 at 1:11 PM, Mark Brown <broonie-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> wrote:

> > In what way?  Other than the -gpios stuff (which would just be a trivial
> > thing if we wanted to change it)?

> That's mainly it.

I don't see that as meaningful or a good reason to duplicate the driver
or the binding, it'd be better to just add the new property and
deprecate the old.

>                   It's not clear which node wlf,ldoena goes in either.
> In the parent? ldo1?

Parent since it's looked up in device context, this is also something
that it seems better to fix in one binding rather than duplicate.

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

^ permalink raw reply

* Re: [PATCH 1/2] leds: cpcap: new driver
From: Pavel Machek @ 2017-04-11 20:19 UTC (permalink / raw)
  To: Sebastian Reichel
  Cc: Tony Lindgren, Richard Purdie, Jacek Anaszewski, Rob Herring,
	Mark Rutland, linux-leds-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20170307171926.wscaogsrdmxc2opz@earth>

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

Hi!

> On Mon, Mar 06, 2017 at 11:11:47PM +0100, Pavel Machek wrote:
> > > Motorola CPCAP is a PMIC found in multiple smartphones.
> > > This driver adds support for the chip's LED controllers.
> > > It has explicit support for all controllers used by the
> > > Droid 4. Since no datasheets are available the other
> > > available controllers are not supported until somebody
> > > verified, that the register layout matches.
> > 
> > This of course leads me to two questions:
> > 
> > 1) Where can I get Droid 4?
> 
> I got a used one on Ebay for 42€ incl. shipping & customs. The trick
> is clicking the worldwide option, since they are pretty expensive in
> EU (they only exist with US LTE modem, so they were not sold here
> officially).
> 
> > 2) How well is it supported?
> 
> UART + WLAN works with mainline master branch. As written by Tony
> we have a couple of patches ready for 4.12. Big open tasks are the
> cameras and the modems. Cameras are handled via co-processor in the
> stock system (that's about all I know about them so far) and modems are
> connected via USB + GPIOs (and for the 2G/3G modem an additional UART).
> LTE modem support seems simple (USB-CDC based), but does not work
> in EU and 2G/3G looks like much work. Modem voice support will be
> simpler than on N900, though (data goes directly to the audio codec).
> Speaking about audio codec: I'm currently working on that.

Thanks for all the information. It looks like a nice and powerful
machine, but I'm looking for a phone, first. (I'd actually like
something smaller than n900, preferably 3 times smaller... but... as
long as it calls it will have to do :-) ).

Best regards,
								Pavel

-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 181 bytes --]

^ permalink raw reply

* Re: [PATCH 1/2] dt-bindings: Document STM32 I2S bindings
From: Mark Brown @ 2017-04-11 20:19 UTC (permalink / raw)
  To: Rob Herring
  Cc: Mark Rutland, devicetree@vger.kernel.org, Linux-ALSA,
	olivier moysan, Alexandre Torgue, Arnaud POULIQUEN, Takashi Iwai,
	Liam Girdwood, Maxime Coquelin,
	linux-arm-kernel@lists.infradead.org, Benjamin Gaignard
In-Reply-To: <CAL_Jsq+bsh8Byow4poT7cdpLY_skb7QxbzkAmj4q7Cf6Z88GWA@mail.gmail.com>


[-- Attachment #1.1: Type: text/plain, Size: 1535 bytes --]

On Tue, Apr 11, 2017 at 11:02:57AM -0500, Rob Herring wrote:
> On Tue, Apr 11, 2017 at 9:32 AM, Mark Brown <broonie@kernel.org> wrote:

> > The graph card is blocked on your review...

> Maybe if there were more reviewers it would move faster. I don't know
> ASoC that well.

The times I've looked at it recently it's been stuck in DT style issues
rather than anything substantially ASoC related, as far as I can tell
the binding is essentially empty from an ASoC point of view and
inherited from the of_graph binding.  There's bits in that are a bit
random like specifically listing the CPU DAIs and only them but that
just looks like one of these random DT things that's predetermined.  I
really can't see anything at all in there to review from an ASoC point
of view, I've applied the changes that don't seem blocked on the
binding.  If there's something you're looking for then please say...

We never seem to make any progress on the generic changes in drivers/of at
the start of the series either...

> > I'm also not clear how
> > without something like this we'd be able to identify a specific DAI
> > within a device if we don't have a way of identifying them.

> Isn't that what the graph does? "dais" points to a list of ports which
> are the specific DAIs whether there are multiple ones in a single
> device or multiple devices with a single DAI each.

But the ports can still have indexes AFAICT (the examples show port@0,
port@1 and so on) so we still need to define what those indexes mean
which is what this is doing?

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

[-- Attachment #2: Type: text/plain, Size: 0 bytes --]



^ permalink raw reply

* Re: [PATCH 1/2] leds: cpcap: new driver
From: Pavel Machek @ 2017-04-11 20:20 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Sebastian Reichel, Richard Purdie, Jacek Anaszewski, Rob Herring,
	Mark Rutland, linux-leds, devicetree, linux-kernel
In-Reply-To: <20170307162640.GS20572@atomide.com>

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

On Tue 2017-03-07 08:26:40, Tony Lindgren wrote:
> * Pavel Machek <pavel@ucw.cz> [170307 03:57]:
> > 2 cores and more importantly 1GB of RAM. Nice. OTOH, I'm avoiding N950
> > due to its crazy "security" system and this one is even worse.
> 
> Yeah this security crap sucks big time in general. It just slows
> down Linux development on usable devices making most of them throw
> away bricks that nobody bothers to work on.
> 
> > Anyway, good luck, and thanks for the pointers. I will get Droid 4 if
> > it is easy. But I guess I'll stick to N900 for now. I want something
> > that can do voice calls.
> 
> Yeah.. For a security free solution, let's hope pyra will be able to
> make voice calls too :)
> 
> Meanwhile, using droid 4 with a lapdock as a low power laptop is
> probably few weeks away, which means I can use it :p

Turning phones into laptops, nice ;-). I think I'll keep the thinkpad
for a while, but yes, interesting machine.
									Pavel
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 181 bytes --]

^ permalink raw reply

* Re: [PATCH 2/2] devicetree: Document the max31760 device binding.
From: Guenter Roeck @ 2017-04-11 20:27 UTC (permalink / raw)
  To: John Muir
  Cc: Rob Herring, Jean Delvare, Jonathan Corbet, Pawel Moll,
	Ian Campbell, Kumar Gala, devicetree, linux-hwmon, linux-doc,
	Anatol Pomazau, Mark Segal
In-Reply-To: <996F9836-F468-4FB5-A16E-2E1FAE8752AD@jmuir.com>

On Tue, Apr 11, 2017 at 06:47:28AM -0700, John Muir wrote:
> > On Apr 10, 2017, at 8:42 AM, Rob Herring <robh@kernel.org> wrote:
> > 
> > On Tue, Apr 04, 2017 at 12:20:34PM -0700, John Muir wrote:
> >> +MAX31760 fan controller
> >> +-----------------------
> >> +
> >> +This device supports I2C only. Many properties of this device are configurable
> >> +thorugh the hwmon interface. See also Documentation/hwmon/max31760.
> > 
> > I really think we need to describe the fans as separate nodes and 
> > preferably with a common binding. This is the second fan controller 
> > binding recently[1].
> > 
> > Features of the "hwmon interface" are not relevant to the binding. 
> > Bindings describe h/w.
> 
> It seems to me that referring to the hwmon interface is only helpful. You are suggesting removing those sentences? If so, can I add a link to the data sheet?
> 

Devicetree properties are supposed to be operating system independent.
Any mention of how access to the device is implemented on a given
operating system is out of scope for this document.

Guenter

> > 
> >> +Optional node properties:
> >> +- maxim,fan1-enabled		- 1 to enable, 0 to disable. Default: 1.
> >> +- maxim,fan2-enabled		- 1 to enable, 0 to disable. Default: 1.
> >> +- maxim,fan1-label		- String: Hwmon fan1_label.
> >> +- maxim,fan2-label		- String: Hwmon fan2_label.
> > 
> > Perhaps 2 fan sub nodes. reg for fan number, status for enabled, and 
> > label for label.
> 
> OK.
> 
> Right now a fan’s number of pulses and the PWM frequency are configured using the hwmon sysfs interface (which defines standard controls for those), but as those are characteristics of the hardware, should they also be configured via the device tree binding?
> 
> >> +- maxim,pwm-zero-fan-can-fail	- 0: Fan failure detection disabled when PWM is
> >> +				     ramping to 0%.
> >> +				  1: Fan failure detection enabled for all PWM
> >> +				     values.
> >> +				  Default: 0.
> > 
> > All these can be boolean…
> 
> OK. The only issue I see is when the default is ‘true’ in the device, but I’ll try to avoid that. Sometimes I wish that you could set a boolean to false in DTS files.
> 
> > 
> >> +- maxim,temp1-label		- String: Hwmon temp1_label.
> >> +- maxim,temp2-label		- String: Hwmon temp2_label.
> >> +- maxim,temp2-ideality		- Set ideality factor for the remote temperature
> >> +				  sensor. Integer with range 0 to 63,
> >> +				  representing a multiplication factor of 0.9844
> >> +				  to 1.0489. Default: 24 (1.0080).
> > 
> > No maxim,temp1-ideality?
> No - the device only lets you set the ideality of the ‘external' temperature sensor. I guess if there is an ideality for the internal temperature sensor, it would be hard-wired as a characteristic of the part that was used.
> 
> > Not sure what to do with these, but perhaps 
> > also as sub-nodes. Surely we have some bindings already for devices with 
> > multiple temp sensors. Don't invent something custom here.
> 
> I’ll look into it.
> 
> What is the best way to distinguish between ‘fan’ and ‘temp’ sub-nodes? Do I require a ‘compatible’ string?
> 
> Thanks!
> 
> John.
> 
> 

^ permalink raw reply

* Re: [PATCH v5 04/10] drm/stm: Add STM32 LTDC driver
From: Eric Anholt @ 2017-04-11 20:45 UTC (permalink / raw)
  To: Yannick Fertre, Alexandre TORGUE, Thierry Reding, David Airlie,
	Maxime Coquelin, Russell King, Mark Rutland, Rob Herring,
	Arnd Bergmann, Benjamin Gaignard
  Cc: devicetree, kernel, Philippe Cornu, dri-devel, Fabien Dessenne,
	Mickael Reulier, Vincent Abriou, Gabriel FERNANDEZ,
	linux-arm-kernel
In-Reply-To: <1490694293-18358-5-git-send-email-yannick.fertre@st.com>


[-- Attachment #1.1: Type: text/plain, Size: 8894 bytes --]

Yannick Fertre <yannick.fertre@st.com> writes:

> This controller provides output signals to interface directly a variety
> of LCD and TFT panels. These output signals are: RGB signals
> (up to 24bpp), vertical & horizontal synchronisations, data enable and
> the pixel clock.
>
> Signed-off-by: Yannick Fertre <yannick.fertre@st.com>
> ---
>  drivers/gpu/drm/Kconfig      |    3 +-
>  drivers/gpu/drm/Makefile     |    1 +
>  drivers/gpu/drm/stm/Kconfig  |   16 +
>  drivers/gpu/drm/stm/Makefile |    7 +
>  drivers/gpu/drm/stm/drv.c    |  221 ++++++++
>  drivers/gpu/drm/stm/ltdc.c   | 1210 ++++++++++++++++++++++++++++++++++++++++++
>  drivers/gpu/drm/stm/ltdc.h   |   40 ++
>  7 files changed, 1497 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/gpu/drm/stm/Kconfig
>  create mode 100644 drivers/gpu/drm/stm/Makefile
>  create mode 100644 drivers/gpu/drm/stm/drv.c
>  create mode 100644 drivers/gpu/drm/stm/ltdc.c
>  create mode 100644 drivers/gpu/drm/stm/ltdc.h
>
> diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
> index 78d7fc0..dd5762a 100644
> --- a/drivers/gpu/drm/Kconfig
> +++ b/drivers/gpu/drm/Kconfig
> @@ -203,7 +203,6 @@ config DRM_VGEM
>  	  as used by Mesa's software renderer for enhanced performance.
>  	  If M is selected the module will be called vgem.
>  
> -

Stray whitespace change.

With this removed, the driver is:

Reviewed-by: Eric Anholt <eric@anholt.net>

Apologies for the delay in the second review offered.  The remainder of
my comments are little cleanups, all of which I think are optional and
fine to do after the code lands.

You should probably update MAINTAINERS for your new driver.  If you'd
like to maintain this driver in the drm-misc small drivers collection
(https://01.org/linuxgraphics/gfx-docs/maintainer-tools/drm-misc.html),
send a follow-up patch to the list to add the MAINTAINERS entry, and I
can get that and patches 1-4 merged.  Once you have a few more patches
in, we can add you to the drm-misc committers crew so you can merge
directly after getting review.

I'll also take this moment to plug something: Please feel welcome to
review other people's driver patches on the list.  You've built
something nice here, and probably learned a lot of lessons along the way
that you could share with others.  (I just found out about
of_reset_control in reviewing your code, and I wish I had known about it
back when I was landing vc4!)

> diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c
> new file mode 100644
> index 0000000..922f021
> --- /dev/null
> +++ b/drivers/gpu/drm/stm/ltdc.c

> +static void ltdc_crtc_disable(struct drm_crtc *crtc)
> +{
> +	struct ltdc_device *ldev = crtc_to_ltdc(crtc);
> +	struct drm_pending_vblank_event *event = crtc->state->event;
> +
> +	DRM_DEBUG_DRIVER("\n");
> +
> +	if (!crtc->enabled) {
> +		DRM_DEBUG_DRIVER("already disabled\n");
> +		return;
> +	}

I think this crtc->enabled is a given for the disable() being called.

> +
> +	drm_crtc_vblank_off(crtc);
> +
> +	/* disable LTDC */
> +	reg_clear(ldev->regs, LTDC_GCR, GCR_LTDCEN);
> +
> +	/* disable IRQ */
> +	reg_clear(ldev->regs, LTDC_IER, IER_RRIE | IER_FUIE | IER_TERRIE);
> +
> +	/* immediately commit disable of layers before switching off LTDC */
> +	reg_set(ldev->regs, LTDC_SRCR, SRCR_IMR);
> +
> +	if (event) {
> +		crtc->state->event = NULL;
> +
> +		spin_lock_irq(&crtc->dev->event_lock);
> +		if (crtc->state->active && drm_crtc_vblank_get(crtc) == 0)
> +			drm_crtc_arm_vblank_event(crtc, event);
> +		else
> +			drm_crtc_send_vblank_event(crtc, event);
> +		spin_unlock_irq(&crtc->dev->event_lock);
> +	}

I believe that we're guaranteed that crtc->state->event is NULL in the
disable call, since your atomic_flush() already armed or sent the event
and NULLed out the pointer.

> +struct drm_connector *ltdc_rgb_connector_create(struct drm_device *ddev)
> +{
> +	struct drm_connector *connector;
> +	int err;
> +
> +	connector = devm_kzalloc(ddev->dev, sizeof(*connector), GFP_KERNEL);
> +	if (!connector) {
> +		DRM_ERROR("Failed to allocate connector\n");
> +		return NULL;
> +	}
> +
> +	connector->polled = DRM_CONNECTOR_POLL_HPD;
> +
> +	err = drm_connector_init(ddev, connector, &ltdc_rgb_connector_funcs,
> +				 DRM_MODE_CONNECTOR_LVDS);

I think DRM_MODE_CONNECTOR_DPI (and _ENCODER_DPI) are slightly more
accurate descriptions, if I'm interpreting your pinmux setup right.
It's cosmetic, though.

> +static struct drm_panel *ltdc_get_panel(struct drm_device *ddev)
> +{
> +	struct device *dev = ddev->dev;
> +	struct device_node *np = dev->of_node;
> +	struct device_node *entity, *port = NULL;
> +	struct drm_panel *panel = NULL;
> +
> +	DRM_DEBUG_DRIVER("\n");
> +
> +	/*
> +	 * Parse ltdc node to get remote port and find RGB panel / HDMI slave
> +	 * If a dsi or a bridge (hdmi, lvds...) is connected to ltdc,
> +	 * a remote port & RGB panel will not be found.
> +	 */
> +	for_each_endpoint_of_node(np, entity) {
> +		if (!of_device_is_available(entity))
> +			continue;
> +
> +		port = of_graph_get_remote_port_parent(entity);
> +		if (port) {
> +			panel = of_drm_find_panel(port);
> +			of_node_put(port);
> +			if (panel) {
> +				DRM_DEBUG_DRIVER("remote panel %s\n",
> +						 port->full_name);
> +			} else {
> +				DRM_DEBUG_DRIVER("panel missing\n");
> +				of_node_put(entity);
> +			}
> +		}
> +	}

Future work: You may find the new drm_of_find_panel_or_bridge() useful
to drop this loop.

> +
> +	return panel;
> +}
> +
> +int ltdc_load(struct drm_device *ddev)
> +{
> +	struct platform_device *pdev = to_platform_device(ddev->dev);
> +	struct ltdc_device *ldev = ddev->dev_private;
> +	struct device *dev = ddev->dev;
> +	struct device_node *np = dev->of_node;
> +	struct drm_encoder *encoder;
> +	struct drm_connector *connector = NULL;
> +	struct drm_crtc *crtc;
> +	struct reset_control *rstc;
> +	struct resource res;
> +	int irq, ret, i;
> +
> +	DRM_DEBUG_DRIVER("\n");
> +
> +	ldev->panel = ltdc_get_panel(ddev);
> +	if (!ldev->panel)
> +		return -EPROBE_DEFER;
> +
> +	rstc = of_reset_control_get(np, NULL);
> +
> +	mutex_init(&ldev->err_lock);
> +
> +	ldev->pixel_clk = devm_clk_get(dev, "lcd");
> +	if (IS_ERR(ldev->pixel_clk)) {
> +		DRM_ERROR("Unable to get lcd clock\n");
> +		return -ENODEV;
> +	}
> +
> +	if (clk_prepare_enable(ldev->pixel_clk)) {
> +		DRM_ERROR("Unable to prepare pixel clock\n");
> +		return -ENODEV;
> +	}

Future work: You may want to move the pixel clock enable into the CRTC's
.enable() and disable in .disable().  It sounded in previous versions
like the HW uses that clock for all register accesses, so you'd need to
protect a couple of other places, but that should save power when the
device is off, right?

> +
> +	if (of_address_to_resource(np, 0, &res)) {
> +		DRM_ERROR("Unable to get resource\n");
> +		return -ENODEV;
> +	}
> +
> +	ldev->regs = devm_ioremap_resource(dev, &res);
> +	if (IS_ERR(ldev->regs)) {
> +		DRM_ERROR("Unable to get ltdc registers\n");
> +		return PTR_ERR(ldev->regs);
> +	}
> +
> +	for (i = 0; i < MAX_IRQ; i++) {
> +		irq = platform_get_irq(pdev, i);
> +		if (irq < 0)
> +			continue;
> +
> +		ret = devm_request_threaded_irq(dev, irq, ltdc_irq,
> +						ltdc_irq_thread, IRQF_ONESHOT,
> +						dev_name(dev), ddev);
> +		if (ret) {
> +			DRM_ERROR("Failed to register LTDC interrupt\n");
> +			return ret;
> +		}
> +	}
> +
> +	if (!IS_ERR(rstc))
> +		reset_control_deassert(rstc);
> +
> +	/* Disable interrupts */
> +	reg_clear(ldev->regs, LTDC_IER,
> +		  IER_LIE | IER_RRIE | IER_FUIE | IER_TERRIE);
> +
> +	ret = ltdc_get_caps(ddev);
> +	if (ret) {
> +		DRM_ERROR("hardware identifier (0x%08x) not supported!\n",
> +			  ldev->caps.hw_version);
> +		return ret;
> +	}
> +
> +	DRM_INFO("ltdc hw version 0x%08x - ready\n", ldev->caps.hw_version);
> +
> +	if (ltdc_create_encoders(ddev)) {
> +		DRM_ERROR("Failed to create encoders\n");
> +		return -EINVAL;
> +	}
> +
> +	if (ldev->panel) {
> +		encoder = ltdc_rgb_encoder_find(ddev);
> +		if (!encoder) {
> +			DRM_ERROR("Failed to find RGB encoder\n");
> +			ret = -EINVAL;
> +			goto err;
> +		}

Given that ltdc_create_encoders() only does work if ldev->panel, its
body could probably be moved in here and then ltdc_rgb_encoder_find
could be dropped.

> +
> +		connector = ltdc_rgb_connector_create(ddev);
> +		if (!connector) {
> +			DRM_ERROR("Failed to create RGB connector\n");
> +			ret = -EINVAL;
> +			goto err;
> +		}
> +
> +		ret = drm_mode_connector_attach_encoder(connector, encoder);
> +		if (ret) {
> +			DRM_ERROR("Failed to attach connector to encoder\n");
> +			goto err;
> +		}
> +
> +		drm_panel_attach(ldev->panel, connector);
> +	}

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

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

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

^ permalink raw reply


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