Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 5/7] ARM: perf_event: Fully support Krait CPU PMU events
From: Stephen Boyd @ 2014-01-22 20:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <52DEBE6B.7000904@codeaurora.org>

On 01/21/14 10:37, Stephen Boyd wrote:
> On 01/21/14 10:07, Will Deacon wrote:
>> Do you need isbs to ensure the pmresrn side-effects have happened, or are
>> the registers self-synchronising? Similarly for your other IMP DEF
>> registers.
> There aren't any isbs in the downstream android sources so I assume
> they're self synchronizing. I'll confirm with the CPU designers to make
> sure.
>

CPU folks say no need for isb. They mentioned that the lack of an isb
after the armv7_pmnc_enable_counter() call will leave the action of
enabling the counter "in-flight". The window is probably pretty short on
an SMP kernel because of the spin_unlock right after with the barriers
in it, but the same can't be said for a UP kernel.

Also, the fuzzer didn't find anything else, but I found a bug in the
bitmap logic, updated and reran the fuzzer this morning. Everything
looks good.

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation

^ permalink raw reply

* [PATCH 0/5] ARM: firmware: improvements to Trusted Foundations support
From: Stephen Warren @ 2014-01-22 20:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1390299016-14105-1-git-send-email-acourbot@nvidia.com>

On 01/21/2014 03:10 AM, Alexandre Courbot wrote:
> These (mostly minor) patches fix a few typos, improve points that
> were agreed upon when the Trusted Foundation series was initially
> submitted, and more importantly add support for the do_idle() firmware
> operation that is needed for cpuidle to be supported. Tegra's cpuidle
> driver is also updated accordingly.
> 
> These patches should be the last step before the device trees for NVIDIA
> SHIELD and Tegra Note 7 can be submitted.

Russell, once these patches are reviewed, should Alex submit them to the
ARM patch tracker, or will you Ack them so they can go through the Tegra
tree? Either way I can put them in a separate branch based on 3.14-rc1
in order to easily resolve any conflicts.

^ permalink raw reply

* [PATCH v8 3/4] ohci-platform: Add support for controllers with big-endian regs / descriptors
From: Sergei Shtylyov @ 2014-01-22 20:46 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1390419177-6481-4-git-send-email-hdegoede@redhat.com>

Hello.

On 01/22/2014 10:32 PM, Hans de Goede wrote:

> Note this commit uses the same devicetree booleans for this as the ones
> already existing in the usb-ehci bindings, see:
> Documentation/devicetree/bindings/usb/usb-ehci.txt

> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
[...]

> diff --git a/drivers/usb/host/ohci-platform.c b/drivers/usb/host/ohci-platform.c
> index b2d0e1e..71e9d8e 100644
> --- a/drivers/usb/host/ohci-platform.c
> +++ b/drivers/usb/host/ohci-platform.c
[...]
> @@ -164,8 +165,34 @@ static int ohci_platform_probe(struct platform_device *dev)
[...]
> +#ifndef CONFIG_USB_OHCI_BIG_ENDIAN_MMIO
> +		if (ohci->flags & OHCI_QUIRK_BE_MMIO) {
> +			dev_err(&dev->dev,
> +				"Error big-endian-regs not compiled in\n");
> +			err = -EINVAL;
> +			goto err_put_hcd;
> +		}
> +#endif
> +#ifndef CONFIG_USB_OHCI_BIG_ENDIAN_DESC
> +		if (ohci->flags & OHCI_QUIRK_BE_DESC) {
> +			dev_err(&dev->dev,
> +				"Error big-endian-desc not compiled in\n");

    Small grammar nits (sorry): some punctuation like comma or semicolon 
wouldn't hurt after "Error" word here and above. The same for ehci-platfrom.c. 
Also, "support" word wouldn't hurt after the property names in the same message.

WBR, Sergei

^ permalink raw reply

* [PATCH 5/5] ARM: tegra: cpuidle: use firmware call for power down
From: Stephen Warren @ 2014-01-22 20:45 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1390299016-14105-6-git-send-email-acourbot@nvidia.com>

On 01/21/2014 03:10 AM, Alexandre Courbot wrote:
> Invoke the do_idle() firmware call before suspending a CPU so that the
> underlying firmware (if any) can take necessary action.

> diff --git a/arch/arm/mach-tegra/cpuidle-tegra114.c b/arch/arm/mach-tegra/cpuidle-tegra114.c

> @@ -45,6 +46,8 @@ static int tegra114_idle_power_down(struct cpuidle_device *dev,
>  
>  	clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu);
>  
> +	call_firmware_op(do_idle);
> +
>  	cpu_suspend(0, tegra30_sleep_cpu_secondary_finish);
>  
>  	clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu);

Don't you need to have the kernel also *not* do something when entering
idle; doesn't the FW op replace some of the register writes that the
kernel would otherwise be doing?

^ permalink raw reply

* [PATCH 4/5] ARM: trusted_foundations: implement do_idle()
From: Stephen Warren @ 2014-01-22 20:43 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1390299016-14105-5-git-send-email-acourbot@nvidia.com>

On 01/21/2014 03:10 AM, Alexandre Courbot wrote:
> Support the do_idle() firmware call, which is necessary to properly
> support cpuidle.

> diff --git a/arch/arm/firmware/trusted_foundations.c b/arch/arm/firmware/trusted_foundations.c

> +#define TF_CPU_PM		 0xfffffffc
> +#define TF_CPU_PM_LP0		 0xffffffe3
> +#define TF_CPU_PM_LP1		 0xffffffe6
> +#define TF_CPU_PM_LP1_NO_MC_CLK	 0xffffffe5
> +#define TF_CPU_PM_LP2		 0xffffffe4
> +#define TF_CPU_PM_LP2_NOFLUSH_L2 0xffffffe7

Hmm. This must be Tegra-specific, not generic to any TF client, since
aren't the names of the suspend states (LP0, LP1, LP2) entirely specific
to Tegra?

^ permalink raw reply

* [PATCH 3/5] ARM: firmware: enable Trusted Foundations by default
From: Stephen Warren @ 2014-01-22 20:42 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1390299016-14105-4-git-send-email-acourbot@nvidia.com>

On 01/21/2014 03:10 AM, Alexandre Courbot wrote:
> As discussed previously (https://lkml.org/lkml/2013/11/26/289), enable
> Trusted Foundation support by default since it already depends on a
> supporting architecture being selected.
> 
> Doing so allows us to remove it from tegra_defconfig.

>  arch/arm/configs/tegra_defconfig | 1 -
>  arch/arm/firmware/Kconfig        | 1 +

Can we split out the defconfig and code changes into separate patches?
They need to go through seperate branches, possibly even separate repos.

The defconfig change might not even be necessary; at some point I'll
just rebuild it via "make tegra_defconfig; make savedefconfig" on top of
some linux-next that includes the Kconfig change, and it'll happen
automatically. Still, I guess there's no harm explicitly sending the patch.

^ permalink raw reply

* [PATCH 2/2] ehci-platform: Add support for controllers with big-endian regs / descriptors
From: Jonas Gorski @ 2014-01-22 20:34 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <52E01BDA.8000606@redhat.com>

Hi,

On Wed, 22 Jan 2014 20:28:26 +0100
Hans de Goede <hdegoede@redhat.com> wrote:
> Hi,
> 
> On 01/21/2014 08:39 PM, Florian Fainelli wrote:
> > 2014/1/21 Hans de Goede <hdegoede@redhat.com>:
> >> This uses the already documented devicetree booleans for this.
> >
> > (I would greatly appreciate if you could CC people who gave you
> > feedback on this before)
> 
> Will do.
> 
> > A more informative commit message would be welcome, along with a
> > reference to which Device Tree binding documentation you are referring
> > to.
> 
> I've added a reference to the bindings doc in the commit msg for my next version.
> 
> >> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> >> ---
> >>   drivers/usb/host/Kconfig         |  3 +++
> >>   drivers/usb/host/ehci-platform.c | 33 +++++++++++++++++++++++++++++++--
> >>   2 files changed, 34 insertions(+), 2 deletions(-)
> >>
> >> diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
> >> index 237d7b1..4af41f3 100644
> >> --- a/drivers/usb/host/Kconfig
> >> +++ b/drivers/usb/host/Kconfig
> >> @@ -256,6 +256,9 @@ config USB_EHCI_ATH79
> >>   config USB_EHCI_HCD_PLATFORM
> >>          tristate "Generic EHCI driver for a platform device"
> >>          depends on !PPC_OF
> >> +       # Support BE on architectures which have readl_be
> >> +       select USB_EHCI_BIG_ENDIAN_DESC if (AVR32 || MIPS || MICROBLAZE || SPARC || PPC32 || PPC64)
> >> +       select USB_EHCI_BIG_ENDIAN_MMIO if (AVR32 || MIPS || MICROBLAZE || SPARC || PPC32 || PPC64)
> >
> > I do not think this is that simple nor correct for at least Microblaze
> > and MIPS since they can run in either BE or LE mode, and those
> > specific platforms should already do the proper select at the
> > board/SoC level. This *might* be correct for SPARC, PPC32 and PPC64,
> > although I believe some specific PPC64 boards can run in little-endian
> > mode like the P-series, SPARC might too.
> >
> > It seems to me that you should not touch this and keep the existing
> > selects in place, if it turns out that the selects are missing the
> > error messages you added below are catching those misuses.
> 
> As discussed with Alan, I will drop these lines from my next version.
> 
> >>          default n
> >>          ---help---
> >>            Adds an EHCI host driver for a generic platform device, which
> >> diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c
> >> index d8aebc0..5888abb 100644
> >> --- a/drivers/usb/host/ehci-platform.c
> >> +++ b/drivers/usb/host/ehci-platform.c
> >> @@ -55,8 +55,10 @@ static int ehci_platform_reset(struct usb_hcd *hcd)
> >>
> >>          hcd->has_tt = pdata->has_tt;
> >>          ehci->has_synopsys_hc_bug = pdata->has_synopsys_hc_bug;
> >> -       ehci->big_endian_desc = pdata->big_endian_desc;
> >> -       ehci->big_endian_mmio = pdata->big_endian_mmio;
> >> +       if (pdata->big_endian_desc)
> >> +               ehci->big_endian_desc = 1;
> >> +       if (pdata->big_endian_mmio)
> >> +               ehci->big_endian_mmio = 1;
> >>
> >>          if (pdata->pre_setup) {
> >>                  retval = pdata->pre_setup(hcd);
> >> @@ -142,6 +144,7 @@ static int ehci_platform_probe(struct platform_device *dev)
> >>          struct resource *res_mem;
> >>          struct usb_ehci_pdata *pdata = dev_get_platdata(&dev->dev);
> >>          struct ehci_platform_priv *priv;
> >> +       struct ehci_hcd *ehci;
> >>          int err, irq, clk = 0;
> >>
> >>          if (usb_disabled())
> >> @@ -177,8 +180,34 @@ static int ehci_platform_probe(struct platform_device *dev)
> >>          platform_set_drvdata(dev, hcd);
> >>          dev->dev.platform_data = pdata;
> >>          priv = hcd_to_ehci_priv(hcd);
> >> +       ehci = hcd_to_ehci(hcd);
> >>
> >>          if (pdata == &ehci_platform_defaults && dev->dev.of_node) {
> >> +               if (of_property_read_bool(dev->dev.of_node, "big-endian-regs"))
> >> +                       ehci->big_endian_mmio = 1;
> >> +
> >> +               if (of_property_read_bool(dev->dev.of_node, "big-endian-desc"))
> >> +                       ehci->big_endian_desc = 1;
> >> +
> >> +               if (of_property_read_bool(dev->dev.of_node, "big-endian"))
> >> +                       ehci->big_endian_mmio = ehci->big_endian_desc = 1;
> >
> > Ok, so I am confused now, should you update
> > pdata->ehci_big_endian_{desc,mmio} here or is it valid to directly
> > modify ehci->big_endian_{desc,mmio}, is not there any risk  to undo
> > what is done in ehci_platform_reset(), or is ehci_platform_reset()
> > only called for non-DT cases?
> 
> Both the pdata checks in ehci_platform_reset() and the dt checks here only
> ever set these flags, neither code path clears them. And in the dt case pdata
> will be NULL and vice versa.

If it's safe to set ehci->big_endian_{desc,mmio} from the _probe()
routine, then maybe the pdata sets in _reset() should be moved into here
instead of adding extra cludges/checks into _reset().

> 
> >
> >> +
> >> +#ifndef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO
> >> +               if (ehci->big_endian_mmio) {
> >> +                       dev_err(&dev->dev,
> >> +                               "Error big-endian-regs not compiled in\n");
> >
> > I do not think using the Device Tree property name would be very
> > informative since this is supposed to guard against misconfigurations
> > for both DT and non-DT enabled platforms
> 
> Nope this is in a dt only code path.

Then these built-in checks could be done for both paths, as !DT also
has the issue, just doesn't warn/error out with it.

I also agree with Florian that the error message could be better
worded, or should be at least have a ":" after "Error". When seeing
the error message the fist time, I would wonder what "error
big-endian-regs" are, and why I would want to have them ;)

Finally, IS_ENABLED()* allows you to drop those ugly #ifndefs:

	if (ehci->big_endian_mmio &&
	    !IS_ENABLED(CONFIG_USB_EHCI_BIG_ENDIAN_MMIO)) {
                       dev_err(&dev->dev,
                               "Error big-endian-regs not compiled in\n");

looks much nicer IMHO ;)



Regards
Jonas


*Yes, I know IS_BUILTIN() would be more formal correct, but IS_ENABLED()
reads IMHO nicer, and I doubt these config symbols will ever go
tristate ;)

^ permalink raw reply

* [PATCH v2 06/15] watchdog: orion: Remove unneeded BRIDGE_CAUSE clear
From: Sebastian Hesselbarth @ 2014-01-22 20:31 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140122173417.GT18269@obsidianresearch.com>

On 01/22/2014 06:34 PM, Jason Gunthorpe wrote:
> On Wed, Jan 22, 2014 at 01:49:05PM -0300, Ezequiel Garcia wrote:
>>> Looking at this patch in isolation it looks to me like the clear
>>> bridge lines should be replaced with a request_irq (as that does the
>>> clear) - is the request_irq in the wrong spot?
>>
>> In that case, I thought that requesting the IRQ at probe time was enough
>> to ensure the BRIDGE_CAUSE would be cleared by the time the watchdog is
>> started. However, after reading through the irqchip code again, I'm no longer
>> sure this is the case.
>
> The watchdog should ideally be fully stopped before request_irq so
> there is no possible race.
>
>> It looks like the BRIDGE_CAUSE register is cleared when the interruption
>> is acked (which happens in the handler if I understood the code right).
>> So requesting the IRQ is useless...
>
> IMHO, the IRQ stuff should clear out pending edge triggered interrupts
> at request_irq time. It makes no sense to take an interrupt for a
> stale edge event.
>
> I had always assumed the core code did this via irq_gc_ack_clr_bit -
> but I don't see an obvious path..
>
>> Sebastian: If the above is correct, do you think we can add a cause clear to
>> the orion irqchip? (supposing it's harmful) Something like this:

Ezequiel,

irqchip/irq-orion.c does mask all interrupts but you are right, it 
should also clear pending interrupts right after that.

So
	/* mask all interrupts */
	writel(0, gc->reg_base + ORION_BRIDGE_IRQ_MASK);

should become

	/* mask and clear all interrupts */
	writel(0, gc->reg_base + ORION_BRIDGE_IRQ_MASK);
	writel(~0, gc->reg_base + ORION_BRIDGE_IRQ_CAUSE);

Could also be clear on write 0, I'll check that. I already had some
beer, so I'll postpone any patches till tomorrow.

Clearing BRIDGE_CAUSE will only clear all currently pending upstream
IRQs, of course. If WDT IRQ will be re-raised right after that in
BRIDGE_CAUSE depends on the actual HW implementation, i.e. we do no
clear the causing IRQ itself but just what it raised in BRIDGE_CAUSE.

So, you should also clear WDT's irq in the driver yourself to clear a
possible pending upstream BRIDGE_CAUSE.

Sebastian

^ permalink raw reply

* [PATCH 04/11] iommu/arm-smmu: Introduce automatic stream-id-masking
From: Andreas Herrmann @ 2014-01-22 20:15 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140122152622.GD14108@mudshark.cambridge.arm.com>

On Wed, Jan 22, 2014 at 03:26:22PM +0000, Will Deacon wrote:
> Hi Andreas,
> 
> This patch always requires some extra brain cycles when reviewing!
> 
> On Thu, Jan 16, 2014 at 12:44:16PM +0000, Andreas Herrmann wrote:
> > Try to determine a mask that can be used for all StreamIDs of a master
> > device. This allows to use just one SMR group instead of
> > number-of-streamids SMR groups for a master device.
> > 
> > Changelog:
> 
> You can put the change log and notes after the '---' so they don't appear in
> the commit log, although the commit message could probably use a brief
> description of your algorithm.

Yep, will fix this.

> > * Sorting of stream IDs (to make usage of S2CR independend of sequence of
> >   stream IDs in DT)
> >   - intentionally not implemented
> >   - code does not rely on sorting
> >   - in fact sorting might make things worse with this simple
> >     implementation
> >     + Example: master with stream IDs 4, 5, 6, 0xe, 0xf requires 3
> >       SMRs when IDs are specified in this sorted order (one to map 4,
> >       5, one to map 6, one to map 0xe, 0xf) but just 2 SMRs when
> >       specified as 4, 5, 0xe, 0xf, 6 (one to map 4, 5, 0xe, 0xf and
> >       one SMR to map 6)
> >   - thus by modifying the DT information you can affect the number of
> >     S2CRs required for stream matching
> >   => I'd say "use common sense" when specifying stream IDs for a master
> >    device in DT.
> 
> Then we probably want a comment in the driver helping people work out what
> the best ordering is.

Hmm, yes indeed. Or maybe deliver some tool to calculate the best
ordering. (Doing this in kernel is overkill but calculate it once and
store the result in DTB seems to be the right approach.)

> > @@ -1025,10 +1030,109 @@ static void arm_smmu_domain_destroy(struct iommu_domain *domain)
> >  	kfree(smmu_domain);
> >  }
> >  
> > +static int determine_smr_mask(struct arm_smmu_device *smmu,
> > +			struct arm_smmu_master *master,
> > +			struct arm_smmu_smr *smr, int start, int order)
> > +{
> > +	u16 i, zero_bits_mask, one_bits_mask, const_mask;
> > +	int nr;
> > +
> > +	nr = 1 << order;
> > +
> > +	if (nr == 1) {
> > +		/* no mask, use streamid to match and be done with it */
> > +		smr->mask = 0;
> > +		smr->id = master->streamids[start];
> > +		return 0;
> > +	}
> > +
> > +	zero_bits_mask = 0;
> > +	one_bits_mask = 0xffff;
> > +	for (i = start; i < start + nr; i++) {
> > +		zero_bits_mask |= master->streamids[i];   /* const 0 bits */
> > +		one_bits_mask &= master->streamids[i]; /* const 1 bits */
> > +	}
> > +	zero_bits_mask = ~zero_bits_mask;
> > +
> > +	/* bits having constant values (either 0 or 1) */
> > +	const_mask = zero_bits_mask | one_bits_mask;
> > +
> > +	i = hweight16(~const_mask);
> > +	if ((1 << i) == nr) {
> > +		smr->mask = ~const_mask;
> > +		smr->id = one_bits_mask;
> 
> This part always confuses me. Why do we check (1 << i) against nr?

(I think, I could change this check to (i == order).)

The reason for this check is:

If there is a mismatch it means that the calculated mask/id pair
either covers

(1) more than nr stream IDs (that were used for the calculation)
    (then (1<<i) > nr)

or

(2) less than nr stream IDs (that were used for the calculation)
   (then (1<<i) < nr)

Only if there is a match, then we know that the calculated mask/id
pair match exactly nr stream IDs (and the matched IDs are those used
for the calculation).

> In fact, in your example where we have SIDs {4,5,e,f,6}, then we'll
> call this initially with start = 0, order = 2 and try to allocate an
> smr for {4,5,e,f}. That will succeed with mask 1011b and id 0100b,
> but the mask has a hamming weight of 3, which is != nr (2).

Arrgh, which means that the example is complete bogus:

4	0b00100
5	0b00101
0xe	0b01110
0xf	0b01111

calculation of const bit masks:
- bits being always zero:	0xfff0	(zero_bits_mask)
- bits being always one:	0x0004	(one_bits_mask)
- thus for const_mask we get:	0xfff4

hweight16(0x1011) != nr (1 << 2). So the algorithm would refuse to use
the calculated mask/id pair to program an SMR. Another iteration would
be done and one SMR for 4, 5 and after that another SMR for 0xe, 0xf
would be set up. The point is that with mask 1011b and id 0100b not
just 4, 5, 0xe, 0xf would be mapped but in fact all following stream
IDs would be mapped:

0b0100	(4)
0b0101  (5)
0b0110  (6)
0b0111  (7)
0b1100  (0xc)
0b1101  (0xd)
0b1110  (0xe)
0b1111  (0xf)

It's eight stream IDs that would be mapped but we considered only 4
stream IDs for the cacluation. We have to dismiss the mask/id pair.

I really should have written down the mask/id stuff to avoid
this wrong example. For a correct example I should have used
4, 5, 6, 0xc, 0xd.

4	0b00100
5	0b00101
0xc	0b01100
0xd	0b01101

calculation of const bit masks:
- bits being always zero:		 0xfff2	(zero_bits_mask)
- bits being always one:		 0x0004	(one_bits_mask)
- thus for const_mask we get:		 0xfff6

(hweight16(0b1001) = 2 which matches order = 2)

With mask 0b1001 and id 0b0100 following IDs match:
0100
0101
1100
1101

0-3, 8-0xb don't match (bit 2 is not set, but it should)
6, 7, 0xe, 0xf don't match (bit 1 is set, but it shouldn't)

> Where am I getting this wrong?

No.

But my example was crap. So providing a tool to correctly calculate
things is required I think.

> I also still need to convince myself that we can't end up generating
> smrs which match the same SID. Is that what your check above is
> trying to handle?

Yes, that should do the trick.

> > +static int determine_smr_mapping(struct arm_smmu_device *smmu,
> > +				struct arm_smmu_master *master,
> > +				struct arm_smmu_smr *smrs, int max_smrs)
> > +{
> > +	int nr_sid, nr, i, bit, start;
> > +
> > +	/*
> > +	 * This function is called only once -- when a master is added
> > +	 * to a domain. If master->num_s2crs != 0 then this master
> > +	 * was already added to a domain.
> > +	 */
> > +	BUG_ON(master->num_s2crs);
> 
> I think I'd rather WARN and return -EINVAL. We needn't kill the kernel for
> this.

Agreed.

> > +
> > +	start = nr = 0;
> > +	nr_sid = master->num_streamids;
> > +	do {
> > +		/*
> > +		 * largest power-of-2 number of streamids for which to
> > +		 * determine a usable mask/id pair for stream matching
> > +		 */
> > +		bit = fls(nr_sid);
> 
> If you use __fls...
> 
> > +		if (!bit)
> > +			return 0;
> > +
> > +		/*
> > +		 * iterate over power-of-2 numbers to determine
> > +		 * largest possible mask/id pair for stream matching
> > +		 * of next 2**i streamids
> > +		 */
> > +		for (i = bit - 1; i >= 0; i--) {
> 
> ... then you don't need this -1.

Ok.

> > +			if(!determine_smr_mask(smmu, master,
> 
> Cosmetic: space after 'if'.

Oops, sorry.

> >  	/* It worked! Now, poke the actual hardware */
> > -	for (i = 0; i < master->num_streamids; ++i) {
> > +	for (i = 0; i < master->num_s2crs; ++i) {
> >  		u32 reg = SMR_VALID | smrs[i].id << SMR_ID_SHIFT |
> >  			  smrs[i].mask << SMR_MASK_SHIFT;
> > +		dev_dbg(smmu->dev, "SMR%d: 0x%x\n", smrs[i].idx, reg);
> 
> I think we can drop the dev_dbg statements from this patch.

Ok.

Andreas

^ permalink raw reply

* [PATCH] clk: Fix notifier documentation
From: Soren Brinkmann @ 2014-01-22 19:48 UTC (permalink / raw)
  To: linux-arm-kernel

Contradicting to documenation, the notifier callbacks do receive
the original clock rate in struct clk_notifier_data.old_rate and the new
frequency struct clk_notifier_data.new_rate, independent of the
notification reason.

This behavior also seems to make more sense, since callbacks can use the
same code to deterimine whether clocks are scaled up or down. Something
which would not even possible in the post-rate-change case if the
behavior was as documented.

Signed-off-by: Soren Brinkmann <soren.brinkmann@xilinx.com>
---
Hi Mike,

I am working with some clock notifiers and if my results are correct the
notifiers behave differently from how they are documented.
I think the actual behavior makes more sense than the documented and my original
plan was to change the behavior, but it seems I might get away with a
doc-update.

	Thanks,
	S?ren

 drivers/clk/clk.c | 15 +++------------
 1 file changed, 3 insertions(+), 12 deletions(-)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 2cf2ea6b77a1..26825db03e64 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -1983,20 +1983,11 @@ EXPORT_SYMBOL_GPL(devm_clk_unregister);
  * re-enter into the clk framework by calling any top-level clk APIs;
  * this will cause a nested prepare_lock mutex.
  *
- * Pre-change notifier callbacks will be passed the current, pre-change
- * rate of the clk via struct clk_notifier_data.old_rate.  The new,
- * post-change rate of the clk is passed via struct
+ * In all notification cases cases (pre, post and abort rate change) the
+ * original clock rate is passed to the callback via struct
+ * clk_notifier_data.old_rate and the new frequency is passed via struct
  * clk_notifier_data.new_rate.
  *
- * Post-change notifiers will pass the now-current, post-change rate of
- * the clk in both struct clk_notifier_data.old_rate and struct
- * clk_notifier_data.new_rate.
- *
- * Abort-change notifiers are effectively the opposite of pre-change
- * notifiers: the original pre-change clk rate is passed in via struct
- * clk_notifier_data.new_rate and the failed post-change rate is passed
- * in via struct clk_notifier_data.old_rate.
- *
  * clk_notifier_register() must be called from non-atomic context.
  * Returns -EINVAL if called with null arguments, -ENOMEM upon
  * allocation failure; otherwise, passes along the return value of
-- 
1.8.5.3

^ permalink raw reply related

* [PATCH v2 1/5] ARM: dts: omap3: Add support for INCOstartec a83x module
From: Nishanth Menon @ 2014-01-22 19:48 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1390417460-3134-2-git-send-email-chf.fritz@googlemail.com>

On 01/22/2014 01:04 PM, Christoph Fritz wrote:
> INCOstartec LILLY-A83X module is a TI DM3730xx100 (OMAP3) SoC
> computer-on-module.
> 
> This patch adds device tree support for most of its features.
> 
> Signed-off-by: Christoph Fritz <chf.fritz@googlemail.com>
> ---
>  arch/arm/boot/dts/omap3-lilly-a83x.dtsi |  445 +++++++++++++++++++++++++++++++
>  1 file changed, 445 insertions(+)
>  create mode 100644 arch/arm/boot/dts/omap3-lilly-a83x.dtsi
> 
> diff --git a/arch/arm/boot/dts/omap3-lilly-a83x.dtsi b/arch/arm/boot/dts/omap3-lilly-a83x.dtsi
> new file mode 100644
> index 0000000..5e2137a
> --- /dev/null
> +++ b/arch/arm/boot/dts/omap3-lilly-a83x.dtsi
> @@ -0,0 +1,445 @@
> +/*
> + * Copyright (C) 2014 Christoph Fritz <chf.fritzc@googlemail.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + */
> +
> +#include "omap36xx.dtsi"
> +
> +/ {
> +	model = "INCOstartec LILLY-A83X module (DM3730)";
> +	compatible = "incostartec,omap3-lilly-a83x", "ti,omap36xx", "ti,omap3";
> +
> +	chosen {
> +			bootargs = "console=ttyO0,115200n8 vt.global_cursor_default=0 consoleblank=0";
> +	};
> +
> +	memory {
> +		device_type = "memory";
> +		reg = <0x80000000 0x8000000>;   /* 128 MB */
> +	};
> +
> +	leds {
> +		compatible = "gpio-leds";
> +
> +		heartbeat1 {
> +			label = "lilly-a83x::led1";
> +			gpios = <&gpio1 29 GPIO_ACTIVE_LOW>;
> +			linux,default-trigger = "default-on";
> +		};
> +
> +	};
> +
> +	sound {
> +		compatible = "ti,omap-twl4030";
> +		ti,model = "lilly-a83x";
> +
> +		ti,mcbsp = <&mcbsp2>;
> +		ti,codec = <&twl_audio>;
> +	};
> +
> +	regulators {
> +		compatible = "simple-bus";
Shrug, just moving the fixed regulator to root also will do the job,
not sure simple-bus much sense here :(

> +		reg_vcc3: vcc3 {
> +                        compatible = "regulator-fixed";
> +                        regulator-name = "VCC3";
> +                        regulator-min-microvolt = <3300000>;
> +                        regulator-max-microvolt = <3300000>;
> +                        regulator-always-on;
> +		};
> +	};
> +
> +	hsusb1_phy: hsusb1_phy {
> +		compatible = "usb-nop-xceiv";
> +		vcc-supply = <&reg_vcc3>;
> +	};
> +};
> +
> +&omap3_pmx_wkup {
> +	pinctrl-names = "default";
> +
> +	lan9221_pins: pinmux_lan9221_pins {
> +		pinctrl-single,pins = <
> +			0x5A (PIN_INPUT | MUX_MODE4)   /* gpio_129 */
umm.. you might want to follow the convention as you followed later in
comments.
> +		>;
> +	};
> +
> +	tsc2048_pins: pinmux_tsc2048_pins {
> +		pinctrl-single,pins = <
> +			0x16 (PIN_INPUT_PULLUP | MUX_MODE4)   /* gpio_8 */
umm.. you might want to follow the convention as you followed later in
comments.
> +		>;
> +	};
> +
> +	mmc1cd_pins: pinmux_mmc1cd_pins {
> +		pinctrl-single,pins = <
> +			0x56 (PIN_INPUT | MUX_MODE4)   /* gpio_126 */
umm.. you might want to follow the convention as you followed later in
comments.
> +		>;
> +	};
> +};
> +
> +&omap3_pmx_core {
> +	pinctrl-names = "default";
> +
> +	gpio1_pins: pinmux_gpio1_pins {
> +		pinctrl-single,pins = <
> +			0x5ca (PIN_OUTPUT_PULLDOWN | MUX_MODE4)   /* gpio_29 */
umm.. you might want to follow the convention as you followed later in
comments.
> +		>;
> +	};
> +
> +	uart1_pins: pinmux_uart1_pins {
> +		pinctrl-single,pins = <
> +			0x14c (PIN_OUTPUT | MUX_MODE0)   /* uart1_tx.uart1_tx */
> +			0x14e (PIN_OUTPUT | MUX_MODE0)   /* uart1_rts.uart1_rts */
> +			0x150 (PIN_INPUT | MUX_MODE0)    /* uart1_cts.uart1_cts */
> +			0x152 (PIN_INPUT | MUX_MODE0)    /* uart1_rx.uart1_rx */
> +		>;
you may be interested in include/dt-bindings/pinctrl/omap.h
OMAP3_CORE1_IOPAD, OMAP3_CORE2_IOPAD as needed here.

> +	};
> +
> +	uart2_pins: pinmux_uart2_pins {
> +		pinctrl-single,pins = <
> +			0x140 (PIN_OUTPUT | MUX_MODE1)   /* mcbsp3_clkx.uart2_tx */
> +			0x142 (PIN_INPUT | MUX_MODE1)    /* mcbsp3_fsx.uart2_rx */
> +		>;
> +	};
> +
> +	uart3_pins: pinmux_uart3_pins {
> +		pinctrl-single,pins = <
> +			0x16e (PIN_INPUT | MUX_MODE0)    /* uart3_rx_irrx.uart3_rx_irrx */
> +			0x170 (PIN_OUTPUT | MUX_MODE0)   /* uart3_tx_irtx.uart3_tx_irtx */
> +		>;
> +	};
> +
> +	i2c1_pins: pinmux_i2c1_pins {
> +		pinctrl-single,pins = <
> +			0x18a (PIN_INPUT_PULLUP | MUX_MODE0)    /* i2c1_scl */
> +			0x18c (PIN_INPUT_PULLUP | MUX_MODE0)    /* i2c1_sda */
umm.. you might want to follow the convention as you followed
elsewhere in comments.
> +		>;
> +	};
> +
> +	i2c2_pins: pinmux_i2c2_pins {
> +		pinctrl-single,pins = <
> +			0x18e (PIN_INPUT | MUX_MODE0)   /* i2c2_scl.i2c2_scl */
> +			0x190 (PIN_INPUT | MUX_MODE0)   /* i2c2_sda.i2c2_sda */
> +		>;
> +	};
> +
> +	i2c3_pins: pinmux_i2c3_pins {
> +		pinctrl-single,pins = <
> +			0x192 (PIN_INPUT | MUX_MODE0)   /* i2c3_scl.i2c3_scl */
> +			0x194 (PIN_INPUT | MUX_MODE0)   /* i2c3_sda.i2c3_sda */
> +		>;
> +	};
> +
> +	hsusb1_pins: pinmux_hsusb1_pins {
> +		pinctrl-single,pins = <
> +			0x5a8 (PIN_OUTPUT | MUX_MODE3)  /* etk_clk.hsusb1_stp */
&omap3_pmx_core2 and OMAP3_CORE2_IOPAD probably here. and probably see
similar usage in other board dtsi.
> +			0x5aa (PIN_INPUT | MUX_MODE3)   /* etk_ctl.hsusb1_clk */
> +			0x5ac (PIN_INPUT | MUX_MODE3)   /* etk_d0.hsusb1_data0 */
> +			0x5ae (PIN_INPUT | MUX_MODE3)   /* etk_d1.hsusb1_data1 */
> +			0x5b0 (PIN_INPUT | MUX_MODE3)   /* etk_d2.hsusb1_data2 */
> +			0x5b2 (PIN_INPUT | MUX_MODE3)   /* etk_d3.hsusb1_data7 */
> +			0x5b4 (PIN_INPUT | MUX_MODE3)   /* etk_d4.hsusb1_data4 */
> +			0x5b6 (PIN_INPUT | MUX_MODE3)   /* etk_d5.hsusb1_data5 */
> +			0x5b8 (PIN_INPUT | MUX_MODE3)   /* etk_d6.hsusb1_data6 */
> +			0x5ba (PIN_INPUT | MUX_MODE3)   /* etk_d7.hsusb1_data3 */
> +			0x5bc (PIN_INPUT | MUX_MODE3)   /* etk_d8.hsusb1_dir */
> +			0x5be (PIN_INPUT | MUX_MODE3)   /* etk_d9.hsusb1_nxt */
> +
> +			/* GPIO 128 controls USB-Hub reset. But USB-Phy its
> +			 * reset can't be controlled. So we clamp this GPIO to
> +			 * high (PIN_OFF_OUTPUT_HIGH) to always enable USB-Hub.
> +			 */
> +
> +			0x1ae (PIN_OUTPUT_PULLUP | PIN_OFF_OUTPUT_HIGH | MUX_MODE4)   /* gpio_182 */
> +		>;
> +	};
> +
> +	hsusb_otg_pins: pinmux_hsusb_otg_pins {
> +		pinctrl-single,pins = <
> +			0x172 (PIN_INPUT | MUX_MODE0)   /* hsusb0_clk.hsusb0_clk */
> +			0x174 (PIN_OUTPUT | MUX_MODE0)  /* hsusb0_stp.hsusb0_stp */
> +			0x176 (PIN_INPUT | MUX_MODE0)   /* hsusb0_dir.hsusb0_dir */
> +			0x178 (PIN_INPUT | MUX_MODE0)   /* hsusb0_nxt.hsusb0_nxt */
> +			0x17a (PIN_INPUT | MUX_MODE0)   /* hsusb0_data0.hsusb0_data0 */
> +			0x17c (PIN_INPUT | MUX_MODE0)   /* hsusb0_data1.hsusb0_data1 */
> +			0x17e (PIN_INPUT | MUX_MODE0)   /* hsusb0_data2.hsusb0_data2 */
> +			0x180 (PIN_INPUT | MUX_MODE0)   /* hsusb0_data3.hsusb0_data3 */
> +			0x182 (PIN_INPUT | MUX_MODE0)   /* hsusb0_data4.hsusb0_data4 */
> +			0x184 (PIN_INPUT | MUX_MODE0)   /* hsusb0_data5.hsusb0_data5 */
> +			0x186 (PIN_INPUT | MUX_MODE0)   /* hsusb0_data6.hsusb0_data6 */
> +			0x188 (PIN_INPUT | MUX_MODE0)   /* hsusb0_data7.hsusb0_data7 */
> +		>;
> +	};
> +
> +	mmc1_pins: pinmux_mmc1_pins {
> +		pinctrl-single,pins = <
> +			0x114 (PIN_INPUT_PULLUP | MUX_MODE0)   /* sdmmc1_clk.sdmmc1_clk */
> +			0x116 (PIN_INPUT_PULLUP | MUX_MODE0)   /* sdmmc1_cmd.sdmmc1_cmd */
> +			0x118 (PIN_INPUT_PULLUP | MUX_MODE0)   /* sdmmc1_dat0.sdmmc1_dat0 */
> +			0x11a (PIN_INPUT_PULLUP | MUX_MODE0)   /* sdmmc1_dat1.sdmmc1_dat1 */
> +			0x11c (PIN_INPUT_PULLUP | MUX_MODE0)   /* sdmmc1_dat2.sdmmc1_dat2 */
> +			0x11e (PIN_INPUT_PULLUP | MUX_MODE0)   /* sdmmc1_dat3.sdmmc1_dat3 */
> +		>;
> +	};
> +
> +	spi2_pins: pinmux_spi2_pins {
> +		pinctrl-single,pins = <
> +			0x1a6 (PIN_INPUT_PULLDOWN | MUX_MODE0)   /* mcspi2_clk.mcspi2_clk */
> +			0x1a8 (PIN_INPUT_PULLDOWN | MUX_MODE0)   /* mcspi2_simo.mcspi2_simo */
> +			0x1aa (PIN_INPUT_PULLDOWN | MUX_MODE0)   /* mcspi2_somi.mcspi2_somi */
> +			0x1ac (PIN_OUTPUT | MUX_MODE0)   /* mcspi2_cs0.mcspi2_cs0 */
> +		>;
> +	};
> +};
> +
> +&gpio1 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&gpio1_pins>;
> +};
> +
> +&i2c1 {
> +	clock-frequency = <2600000>;
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&i2c1_pins>;
> +
> +	twl: twl at 48 {
> +		reg = <0x48>;
> +		interrupts = <7>;   /* SYS_NIRQ cascaded to intc */
> +		interrupt-parent = <&intc>;
> +
> +		twl_audio: audio {
> +			compatible = "ti,twl4030-audio";
> +			codec {
> +			};
> +		};
> +	};
> +};
> +
> +#include "twl4030.dtsi"
> +#include "twl4030_omap3.dtsi"
> +
> +&twl {
> +	vmmc1: regulator-vmmc1 {
> +		regulator-always-on;
> +	};
> +
> +	vdd1: regulator-vdd1 {
> +		regulator-always-on;
> +	};
> +
> +	vdd2: regulator-vdd2 {
> +		regulator-always-on;
> +	};
I hope you have covered all required regulators here including the
ones you might need for IO.1P8 perhaps?

> +};
> +
> +&i2c2 {
> +	clock-frequency = <2600000>;
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&i2c2_pins>;
> +};
> +
> +&i2c3 {
> +	clock-frequency = <2600000>;
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&i2c3_pins>;
> +		gpiom1: gpio at 20 {
> +			compatible = "mcp,mcp23017";
> +			gpio-controller;
> +			#gpio-cells = <2>;
> +			reg = <0x20>;
> +		};
> +};
> +
> +&uart1 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&uart1_pins>;
> +};
> +
> +&uart2 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&uart2_pins>;
> +};
> +
> +&uart3 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&uart3_pins>;
> +};
> +
> +&uart4 {
> +	status = "disabled";
> +};
> +
> +&mmc1 {
> +	reg = <0x4809c000 0x400>;
little curious as to why this. is that to override length 0x200 to
0x400? that belongs to soc.dtsi then.

> +	cd-gpios = <&gpio4 30 IRQ_TYPE_LEVEL_LOW>;
> +	cd-inverted;
> +	vmmc-supply = <&vmmc1>;
> +	bus-width = <4>;
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&mmc1_pins &mmc1cd_pins>;
> +	cap-sdio-irq;
> +	cap-sd-highspeed;
> +	cap-mmc-highspeed;
> +};
> +
> +&mmc2 {
> +	status = "disabled";
> +};
> +
> +&mmc3 {
> +	status = "disabled";
> +};
> +
> +&mcspi2 {
> +	status = "okay";
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&spi2_pins>;
> +
> +	tsc2046 at 0 {
> +		reg = <0>;   /* CS0 */
> +		compatible = "ti,tsc2046";
> +		interrupt-parent = <&gpio1>;
> +		interrupts = <8 0>;   /* boot6 / gpio_8 */
> +		spi-max-frequency = <1000000>;
> +		pendown-gpio = <&gpio1 8 0>;
> +		vcc-supply = <&reg_vcc3>;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&tsc2048_pins>;
> +
> +		ti,x-min = <300>;
> +		ti,x-max = <3000>;
> +		ti,y-min = <600>;
> +		ti,y-max = <3600>;
> +		ti,x-plate-ohms = <80>;
> +		ti,pressure-max = <255>;
> +		ti,swap-xy;
> +
> +		linux,wakeup;
> +	};
> +};
> +
> +&usbhsehci {
> +	phys = <&hsusb1_phy>;
> +};
> +
> +&usbhshost {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&hsusb1_pins>;
> +	num-ports = <2>;
> +	port1-mode = "ehci-phy";
> +};
> +
> +&usb_otg_hs {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&hsusb_otg_pins>;
> +	interface-type = <0>;
> +	usb-phy = <&usb2_phy>;
> +	phys = <&usb2_phy>;
> +	phy-names = "usb2-phy";
> +	mode = <3>;
> +	power = <50>;
> +};
> +
> +&gpmc {
> +	ranges = <0 0 0x30000000 0x1000000>,
> +		<7 0 0x15000000 0x01000000>;
> +
> +	nand at 0,0 {
> +		reg = <0 0 0x1000000>;
> +		nand-bus-width = <16>;
> +		ti,nand-ecc-opt = "bch8";
> +		/* no elm on omap3 */
> +
> +		gpmc,mux-add-data = <0>;
> +		gpmc,device-nand;
> +		gpmc,device-width = <2>;
> +		gpmc,wait-pin = <0>;
> +		gpmc,wait-monitoring-ns = <0>;
> +		gpmc,burst-length= <4>;
> +		gpmc,cs-on-ns = <0>;
> +		gpmc,cs-rd-off-ns = <100>;
> +		gpmc,cs-wr-off-ns = <100>;
> +		gpmc,adv-on-ns = <0>;
> +		gpmc,adv-rd-off-ns = <100>;
> +		gpmc,adv-wr-off-ns = <100>;
> +		gpmc,oe-on-ns = <5>;
> +		gpmc,oe-off-ns = <75>;
> +		gpmc,we-on-ns = <5>;
> +		gpmc,we-off-ns = <75>;
> +		gpmc,rd-cycle-ns = <100>;
> +		gpmc,wr-cycle-ns = <100>;
> +		gpmc,access-ns = <60>;
> +		gpmc,page-burst-access-ns = <5>;
> +		gpmc,bus-turnaround-ns = <0>;
> +		gpmc,cycle2cycle-samecsen;
> +		gpmc,cycle2cycle-delay-ns = <50>;
> +		gpmc,wr-data-mux-bus-ns = <75>;
> +		gpmc,wr-access-ns = <155>;
> +
> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +
> +		partition at 0 {
> +			label = "MLO";
> +			reg = <0 0x80000>;
> +		};
> +
> +		partition at 0x80000 {
> +			label = "u-boot";
> +			reg = <0x80000 0x1e0000>;
> +		};
> +
> +		partition at 0x260000 {
> +			label = "u-boot-environment";
> +			reg = <0x260000 0x20000>;
> +		};
> +
> +		partition at 0x280000 {
> +			label = "kernel";
> +			reg = <0x280000 0x500000>;
> +		};
> +
> +		partition at 0x780000 {
> +			label = "filesystem";
> +			reg = <0x780000 0xf880000>;
> +		};
> +	};
> +
> +	ethernet at 7,0 {
> +		compatible = "smsc,lan9221", "smsc,lan9115";
> +		bank-width = <2>;
> +		gpmc,mux-add-data = <2>;
> +		gpmc,cs-on-ns = <10>;
> +		gpmc,cs-rd-off-ns = <60>;
> +		gpmc,cs-wr-off-ns = <60>;
> +		gpmc,adv-on-ns = <0>;
> +		gpmc,adv-rd-off-ns = <10>;
> +		gpmc,adv-wr-off-ns = <10>;
> +		gpmc,oe-on-ns = <10>;
> +		gpmc,oe-off-ns = <60>;
> +		gpmc,we-on-ns = <10>;
> +		gpmc,we-off-ns = <60>;
> +		gpmc,rd-cycle-ns = <100>;
> +		gpmc,wr-cycle-ns = <100>;
> +		gpmc,access-ns = <50>;
> +		gpmc,page-burst-access-ns = <5>;
> +		gpmc,bus-turnaround-ns = <0>;
> +		gpmc,cycle2cycle-delay-ns = <75>;
> +		gpmc,wr-data-mux-bus-ns = <15>;
> +		gpmc,wr-access-ns = <75>;
> +		gpmc,cycle2cycle-samecsen;
> +		gpmc,cycle2cycle-diffcsen;
> +		vddvario-supply = <&reg_vcc3>;
> +		vdd33a-supply = <&reg_vcc3>;
> +		reg-io-width = <4>;
> +		interrupt-parent = <&gpio5>;
> +		interrupts = <1 0x2>;
> +		reg = <7 0 0xff>;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&lan9221_pins>;
> +		phy-mode = "mii";
> +	};
> +};
> 


-- 
Regards,
Nishanth Menon

^ permalink raw reply

* [PATCH 2/2] ARM: dts: imx6: edmqmx6: remove wrong gpio in usb_otg_vbus regulator
From: Silvio F @ 2014-01-22 19:39 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1390419567-2643-1-git-send-email-silvio.fricke@gmail.com>

Signed-off-by: Silvio F <silvio.fricke@gmail.com>
---
 arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts b/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts
index 6706d1b..de54e46 100644
--- a/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts
+++ b/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts
@@ -46,7 +46,6 @@
 			regulator-name = "usb_otg_vbus";
 			regulator-min-microvolt = <5000000>;
 			regulator-max-microvolt = <5000000>;
-			gpio = <&gpio7 12 0>;
 		};
 
 		reg_usb_host1: regulator at 2 {
-- 
1.8.5.2

^ permalink raw reply related

* [PATCH 1/2] ARM: dts: imx6: edmqmx6: fix wrong usbotg pingroup
From: Silvio F @ 2014-01-22 19:39 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1390419567-2643-1-git-send-email-silvio.fricke@gmail.com>

Signed-off-by: Silvio F <silvio.fricke@gmail.com>
---
 arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts b/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts
index b8a1ff4..6706d1b 100644
--- a/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts
+++ b/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts
@@ -266,7 +266,7 @@
 		};
 
 		pinctrl_usbotg: usbotggrp {
-			fsl,pins = <MX6QDL_USBOTG_PINGRP1>;
+			fsl,pins = <MX6QDL_USBOTG_PINGRP2>;
 		};
 
 		pinctrl_usdhc3: usdhc3grp {
-- 
1.8.5.2

^ permalink raw reply related

* [PATCH] dts: edmqmx6: some fixes
From: Silvio F @ 2014-01-22 19:39 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

please review and add this patches.

Thanks and Cheers,
       Silvio F.

^ permalink raw reply

* [PATCH v2 4/5] ARM: OMAP2+: Add pdata quirk for sys_clkout2 for omap3 DBB056
From: Nishanth Menon @ 2014-01-22 19:33 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1390417460-3134-5-git-send-email-chf.fritz@googlemail.com>

On 01/22/2014 01:04 PM, Christoph Fritz wrote:
> Full device tree support for clock control is not yet accomplished. Until
> then, configure the 24Mhz of sys_clkout2 to feed an USB-Hub here.
> 
> Signed-off-by: Christoph Fritz <chf.fritz@googlemail.com>
> ---
>  arch/arm/mach-omap2/pdata-quirks.c |   37 ++++++++++++++++++++++++++++++++++++
>  1 file changed, 37 insertions(+)
> 
> diff --git a/arch/arm/mach-omap2/pdata-quirks.c b/arch/arm/mach-omap2/pdata-quirks.c
> index a58590f..9ef7ca8 100644
> --- a/arch/arm/mach-omap2/pdata-quirks.c
> +++ b/arch/arm/mach-omap2/pdata-quirks.c
> @@ -171,6 +171,43 @@ static void __init am3517_evm_legacy_init(void)
>  }
>  static void __init omap3_dbb056_legacy_init(void)
>  {
> +	struct clk *clkout2;
> +	struct clk *cm96fck;
> +
> +	/* Reparent clkout2 to 96M_FCK */
> +	pr_info("a83x-quirk: Late Reparent clkout2 to 96M_FCK\n");
what'd be a83x?

> +	clkout2 = clk_get(NULL, "clkout2_src_ck");
> +	if(clkout2 < 0) {
> +		pr_err("a83x-quirk: couldn't get clkout2_src_ck\n");
> +		return;
> +	}
> +	cm96fck = clk_get(NULL, "cm_96m_fck");
> +	if(cm96fck < 0) {
> +		pr_err("a83x-quirk: couldn't get cm_96m_fck\n");
> +		return;
> +	}
> +	if(clk_set_parent(clkout2, cm96fck) < 0) {
> +		pr_err("a83x-quirk: couldn't reparent clkout2_src_ck\n");
> +		return;
> +	}
yep - we have bunch of similar code in drivers/clk/ti -> but we'd need
a generic property to handle this.
> +
> +	/* Set clkout2 to 24MHz for internal usb hub*/
> +	pr_info("a83x-quirk: Set clkout2 to 24MHz for internal usb hub\n");
> +	clkout2 = clk_get(NULL, "sys_clkout2");
> +	if(clkout2 < 0) {
> +		pr_err("a83x-quirk: couldn't get sys_clkout2\n");
> +		return;
> +	}
> +	if(clk_set_rate(clkout2, 24000000) < 0) {
same here.
> +		printk(KERN_ERR "board-omap3evm: couldn't set sys_clkout2 rate\n");
"board-omap3evm:" copy paste?
any reason why not pr_err?

> +		return;
> +	}
> +	if(clk_prepare_enable(clkout2) < 0) {
> +		pr_err("a83x-quirk: couldn't enable sys_clkout2\n");
> +		return;
> +	}
> +
> +	/* Initialize display */
>  	omap3_dbb056_display_init_of();
>  }
>  #endif /* CONFIG_ARCH_OMAP3 */
> 

looking at the coding style, I assume we'd missed running
checkpatch.pl --strict?

ERROR: space required before the open parenthesis '('
#44: FILE: arch/arm/mach-omap2/pdata-quirks.c:180:
+	if(clkout2 < 0) {

ERROR: space required before the open parenthesis '('
#49: FILE: arch/arm/mach-omap2/pdata-quirks.c:185:
+	if(cm96fck < 0) {

ERROR: space required before the open parenthesis '('
#53: FILE: arch/arm/mach-omap2/pdata-quirks.c:189:
+	if(clk_set_parent(clkout2, cm96fck) < 0) {

ERROR: space required before the open parenthesis '('
#61: FILE: arch/arm/mach-omap2/pdata-quirks.c:197:
+	if(clkout2 < 0) {

ERROR: space required before the open parenthesis '('
#65: FILE: arch/arm/mach-omap2/pdata-quirks.c:201:
+	if(clk_set_rate(clkout2, 24000000) < 0) {

WARNING: Prefer netdev_err(netdev, ... then dev_err(dev, ... then
pr_err(...  to printk(KERN_ERR ...
#66: FILE: arch/arm/mach-omap2/pdata-quirks.c:202:
+		printk(KERN_ERR "board-omap3evm: couldn't set sys_clkout2 rate\n");

ERROR: space required before the open parenthesis '('
#69: FILE: arch/arm/mach-omap2/pdata-quirks.c:205:
+	if(clk_prepare_enable(clkout2) < 0) {

total: 6 errors, 1 warnings, 0 checks, 43 lines checked

 has style problems, please review.

If any of these errors are false positives, please report
them to the maintainer, see CHECKPATCH in MAINTAINERS.

you might want to run something like aiaiai[1] or
kernel_patch_verify[2] or patman... etc.. to help you clean up for
minimum needs.

[1] https://lwn.net/Articles/488992/
[2] https://github.com/nmenon/kernel_patch_verify

-- 
Regards,
Nishanth Menon

^ permalink raw reply

* [PATCH v8 4/4] ehci-platform: Add support for controllers with big-endian regs / descriptors
From: Hans de Goede @ 2014-01-22 19:32 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1390419177-6481-1-git-send-email-hdegoede@redhat.com>

This uses the already documented devicetree booleans for this, see:
Documentation/devicetree/bindings/usb/usb-ehci.txt

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/usb/host/ehci-platform.c | 33 +++++++++++++++++++++++++++++++--
 1 file changed, 31 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c
index d8aebc0..5888abb 100644
--- a/drivers/usb/host/ehci-platform.c
+++ b/drivers/usb/host/ehci-platform.c
@@ -55,8 +55,10 @@ static int ehci_platform_reset(struct usb_hcd *hcd)
 
 	hcd->has_tt = pdata->has_tt;
 	ehci->has_synopsys_hc_bug = pdata->has_synopsys_hc_bug;
-	ehci->big_endian_desc = pdata->big_endian_desc;
-	ehci->big_endian_mmio = pdata->big_endian_mmio;
+	if (pdata->big_endian_desc)
+		ehci->big_endian_desc = 1;
+	if (pdata->big_endian_mmio)
+		ehci->big_endian_mmio = 1;
 
 	if (pdata->pre_setup) {
 		retval = pdata->pre_setup(hcd);
@@ -142,6 +144,7 @@ static int ehci_platform_probe(struct platform_device *dev)
 	struct resource *res_mem;
 	struct usb_ehci_pdata *pdata = dev_get_platdata(&dev->dev);
 	struct ehci_platform_priv *priv;
+	struct ehci_hcd *ehci;
 	int err, irq, clk = 0;
 
 	if (usb_disabled())
@@ -177,8 +180,34 @@ static int ehci_platform_probe(struct platform_device *dev)
 	platform_set_drvdata(dev, hcd);
 	dev->dev.platform_data = pdata;
 	priv = hcd_to_ehci_priv(hcd);
+	ehci = hcd_to_ehci(hcd);
 
 	if (pdata == &ehci_platform_defaults && dev->dev.of_node) {
+		if (of_property_read_bool(dev->dev.of_node, "big-endian-regs"))
+			ehci->big_endian_mmio = 1;
+
+		if (of_property_read_bool(dev->dev.of_node, "big-endian-desc"))
+			ehci->big_endian_desc = 1;
+
+		if (of_property_read_bool(dev->dev.of_node, "big-endian"))
+			ehci->big_endian_mmio = ehci->big_endian_desc = 1;
+
+#ifndef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO
+		if (ehci->big_endian_mmio) {
+			dev_err(&dev->dev,
+				"Error big-endian-regs not compiled in\n");
+			err = -EINVAL;
+			goto err_put_hcd;
+		}
+#endif
+#ifndef CONFIG_USB_EHCI_BIG_ENDIAN_DESC
+		if (ehci->big_endian_desc) {
+			dev_err(&dev->dev,
+				"Error big-endian-desc not compiled in\n");
+			err = -EINVAL;
+			goto err_put_hcd;
+		}
+#endif
 		priv->phy = devm_phy_get(&dev->dev, "usb");
 		if (IS_ERR(priv->phy)) {
 			err = PTR_ERR(priv->phy);
-- 
1.8.5.3

^ permalink raw reply related

* [PATCH v8 3/4] ohci-platform: Add support for controllers with big-endian regs / descriptors
From: Hans de Goede @ 2014-01-22 19:32 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1390419177-6481-1-git-send-email-hdegoede@redhat.com>

Note this commit uses the same devicetree booleans for this as the ones
already existing in the usb-ehci bindings, see:
Documentation/devicetree/bindings/usb/usb-ehci.txt

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 Documentation/devicetree/bindings/usb/usb-ohci.txt |  3 +++
 drivers/usb/host/ohci-platform.c                   | 27 ++++++++++++++++++++++
 2 files changed, 30 insertions(+)

diff --git a/Documentation/devicetree/bindings/usb/usb-ohci.txt b/Documentation/devicetree/bindings/usb/usb-ohci.txt
index 6ba38d9..6933b0c 100644
--- a/Documentation/devicetree/bindings/usb/usb-ohci.txt
+++ b/Documentation/devicetree/bindings/usb/usb-ohci.txt
@@ -6,6 +6,9 @@ Required properties:
 - interrupts : ohci controller interrupt
 
 Optional properties:
+- big-endian-regs : boolean, set this for hcds with big-endian registers
+- big-endian-desc : boolean, set this for hcds with big-endian descriptors
+- big-endian : boolean, for hcds with big-endian-regs + big-endian-desc
 - clocks : a list of phandle + clock specifier pairs
 - phys : phandle + phy specifier pair
 - phy-names : "usb"
diff --git a/drivers/usb/host/ohci-platform.c b/drivers/usb/host/ohci-platform.c
index b2d0e1e..71e9d8e 100644
--- a/drivers/usb/host/ohci-platform.c
+++ b/drivers/usb/host/ohci-platform.c
@@ -128,6 +128,7 @@ static int ohci_platform_probe(struct platform_device *dev)
 	struct resource *res_mem;
 	struct usb_ohci_pdata *pdata = dev_get_platdata(&dev->dev);
 	struct ohci_platform_priv *priv;
+	struct ohci_hcd *ohci;
 	int err, irq, clk = 0;
 
 	if (usb_disabled())
@@ -164,8 +165,34 @@ static int ohci_platform_probe(struct platform_device *dev)
 	platform_set_drvdata(dev, hcd);
 	dev->dev.platform_data = pdata;
 	priv = hcd_to_ohci_priv(hcd);
+	ohci = hcd_to_ohci(hcd);
 
 	if (pdata == &ohci_platform_defaults && dev->dev.of_node) {
+		if (of_property_read_bool(dev->dev.of_node, "big-endian-regs"))
+			ohci->flags |= OHCI_QUIRK_BE_MMIO;
+
+		if (of_property_read_bool(dev->dev.of_node, "big-endian-desc"))
+			ohci->flags |= OHCI_QUIRK_BE_DESC;
+
+		if (of_property_read_bool(dev->dev.of_node, "big-endian"))
+			ohci->flags |= OHCI_QUIRK_BE_MMIO | OHCI_QUIRK_BE_DESC;
+
+#ifndef CONFIG_USB_OHCI_BIG_ENDIAN_MMIO
+		if (ohci->flags & OHCI_QUIRK_BE_MMIO) {
+			dev_err(&dev->dev,
+				"Error big-endian-regs not compiled in\n");
+			err = -EINVAL;
+			goto err_put_hcd;
+		}
+#endif
+#ifndef CONFIG_USB_OHCI_BIG_ENDIAN_DESC
+		if (ohci->flags & OHCI_QUIRK_BE_DESC) {
+			dev_err(&dev->dev,
+				"Error big-endian-desc not compiled in\n");
+			err = -EINVAL;
+			goto err_put_hcd;
+		}
+#endif
 		priv->phy = devm_phy_get(&dev->dev, "usb");
 		if (IS_ERR(priv->phy)) {
 			err = PTR_ERR(priv->phy);
-- 
1.8.5.3

^ permalink raw reply related

* [PATCH v8 2/4] ehci-platform: Add support for clks and phy passed through devicetree
From: Hans de Goede @ 2014-01-22 19:32 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1390419177-6481-1-git-send-email-hdegoede@redhat.com>

Currently ehci-platform is only used in combination with devicetree when used
with some Via socs. By extending it to (optionally) get clks and a phy from
devicetree, and enabling / disabling those on power_on / off, it can be used
more generically. Specifically after this commit it can be used for the
ehci controller on Allwinner sunxi SoCs.

Since ehci-platform is intended to handle any generic enough non pci ehci
device, add a "usb-ehci" compatibility string.

There already is a usb-ehci device-tree bindings document, update this
with clks and phy bindings info.

Although actually quite generic so far the via,vt8500 compatibilty string
had its own bindings document. Somehow we even ended up with 2 of them. Since
these provide no extra information over the generic usb-ehci documentation,
this patch removes them.

The ehci-ppc-of.c driver also claims the usb-ehci compatibility string,
even though it mostly is ibm,usb-ehci-440epx specific. ehci-platform.c is
not needed on ppc platforms, so add a !PPC_OF dependency to it to avoid
2 drivers claiming the same compatibility string getting build on ppc.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
---
 Documentation/devicetree/bindings/usb/usb-ehci.txt |  25 +++-
 .../devicetree/bindings/usb/via,vt8500-ehci.txt    |  15 ---
 .../devicetree/bindings/usb/vt8500-ehci.txt        |  12 --
 drivers/usb/host/Kconfig                           |   1 +
 drivers/usb/host/ehci-platform.c                   | 149 +++++++++++++++++----
 5 files changed, 142 insertions(+), 60 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/usb/via,vt8500-ehci.txt
 delete mode 100644 Documentation/devicetree/bindings/usb/vt8500-ehci.txt

diff --git a/Documentation/devicetree/bindings/usb/usb-ehci.txt b/Documentation/devicetree/bindings/usb/usb-ehci.txt
index fa18612..2c1aeeb 100644
--- a/Documentation/devicetree/bindings/usb/usb-ehci.txt
+++ b/Documentation/devicetree/bindings/usb/usb-ehci.txt
@@ -7,13 +7,14 @@ Required properties:
     (debug-port or other) can be also specified here, but only after
     definition of standard EHCI registers.
   - interrupts : one EHCI interrupt should be described here.
-If device registers are implemented in big endian mode, the device
-node should have "big-endian-regs" property.
-If controller implementation operates with big endian descriptors,
-"big-endian-desc" property should be specified.
-If both big endian registers and descriptors are used by the controller
-implementation, "big-endian" property can be specified instead of having
-both "big-endian-regs" and "big-endian-desc".
+
+Optional properties:
+ - big-endian-regs : boolean, set this for hcds with big-endian registers
+ - big-endian-desc : boolean, set this for hcds with big-endian descriptors
+ - big-endian : boolean, for hcds with big-endian-regs + big-endian-desc
+ - clocks : a list of phandle + clock specifier pairs
+ - phys : phandle + phy specifier pair
+ - phy-names : "usb"
 
 Example (Sequoia 440EPx):
     ehci at e0000300 {
@@ -23,3 +24,13 @@ Example (Sequoia 440EPx):
 	   reg = <0 e0000300 90 0 e0000390 70>;
 	   big-endian;
    };
+
+Example (Allwinner sun4i A10 SoC):
+   ehci0: usb at 01c14000 {
+	   compatible = "allwinner,sun4i-a10-ehci", "usb-ehci";
+	   reg = <0x01c14000 0x100>;
+	   interrupts = <39>;
+	   clocks = <&ahb_gates 1>;
+	   phys = <&usbphy 1>;
+	   phy-names = "usb";
+   };
diff --git a/Documentation/devicetree/bindings/usb/via,vt8500-ehci.txt b/Documentation/devicetree/bindings/usb/via,vt8500-ehci.txt
deleted file mode 100644
index 17b3ad1..0000000
--- a/Documentation/devicetree/bindings/usb/via,vt8500-ehci.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-VIA/Wondermedia VT8500 EHCI Controller
------------------------------------------------------
-
-Required properties:
-- compatible : "via,vt8500-ehci"
-- reg : Should contain 1 register ranges(address and length)
-- interrupts : ehci controller interrupt
-
-Example:
-
-	ehci at d8007900 {
-		compatible = "via,vt8500-ehci";
-		reg = <0xd8007900 0x200>;
-		interrupts = <43>;
-	};
diff --git a/Documentation/devicetree/bindings/usb/vt8500-ehci.txt b/Documentation/devicetree/bindings/usb/vt8500-ehci.txt
deleted file mode 100644
index 5fb8fd6..0000000
--- a/Documentation/devicetree/bindings/usb/vt8500-ehci.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-VIA VT8500 and Wondermedia WM8xxx SoC USB controllers.
-
-Required properties:
- - compatible: Should be "via,vt8500-ehci" or "wm,prizm-ehci".
- - reg: Address range of the ehci registers. size should be 0x200
- - interrupts: Should contain the ehci interrupt.
-
-usb: ehci at D8007100 {
-	compatible = "wm,prizm-ehci", "usb-ehci";
-	reg = <0xD8007100 0x200>;
-	interrupts = <1>;
-};
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index a9707da..e28cbe0 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -255,6 +255,7 @@ config USB_EHCI_ATH79
 
 config USB_EHCI_HCD_PLATFORM
 	tristate "Generic EHCI driver for a platform device"
+	depends on !PPC_OF
 	default n
 	---help---
 	  Adds an EHCI host driver for a generic platform device, which
diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c
index 7f30b71..d8aebc0 100644
--- a/drivers/usb/host/ehci-platform.c
+++ b/drivers/usb/host/ehci-platform.c
@@ -3,6 +3,7 @@
  *
  * Copyright 2007 Steven Brown <sbrown@cortland.com>
  * Copyright 2010-2012 Hauke Mehrtens <hauke@hauke-m.de>
+ * Copyright 2014 Hans de Goede <hdegoede@redhat.com>
  *
  * Derived from the ohci-ssb driver
  * Copyright 2007 Michael Buesch <m@bues.ch>
@@ -18,6 +19,7 @@
  *
  * Licensed under the GNU/GPL. See COPYING for details.
  */
+#include <linux/clk.h>
 #include <linux/dma-mapping.h>
 #include <linux/err.h>
 #include <linux/kernel.h>
@@ -25,6 +27,7 @@
 #include <linux/io.h>
 #include <linux/module.h>
 #include <linux/of.h>
+#include <linux/phy/phy.h>
 #include <linux/platform_device.h>
 #include <linux/usb.h>
 #include <linux/usb/hcd.h>
@@ -33,6 +36,13 @@
 #include "ehci.h"
 
 #define DRIVER_DESC "EHCI generic platform driver"
+#define EHCI_MAX_CLKS 3
+#define hcd_to_ehci_priv(h) ((struct ehci_platform_priv *)hcd_to_ehci(h)->priv)
+
+struct ehci_platform_priv {
+	struct clk *clks[EHCI_MAX_CLKS];
+	struct phy *phy;
+};
 
 static const char hcd_name[] = "ehci-platform";
 
@@ -64,38 +74,90 @@ static int ehci_platform_reset(struct usb_hcd *hcd)
 	return 0;
 }
 
+static int ehci_platform_power_on(struct platform_device *dev)
+{
+	struct usb_hcd *hcd = platform_get_drvdata(dev);
+	struct ehci_platform_priv *priv = hcd_to_ehci_priv(hcd);
+	int clk, ret;
+
+	for (clk = 0; clk < EHCI_MAX_CLKS && priv->clks[clk]; clk++) {
+		ret = clk_prepare_enable(priv->clks[clk]);
+		if (ret)
+			goto err_disable_clks;
+	}
+
+	if (priv->phy) {
+		ret = phy_init(priv->phy);
+		if (ret)
+			goto err_disable_clks;
+
+		ret = phy_power_on(priv->phy);
+		if (ret)
+			goto err_exit_phy;
+	}
+
+	return 0;
+
+err_exit_phy:
+	phy_exit(priv->phy);
+err_disable_clks:
+	while (--clk >= 0)
+		clk_disable_unprepare(priv->clks[clk]);
+
+	return ret;
+}
+
+static void ehci_platform_power_off(struct platform_device *dev)
+{
+	struct usb_hcd *hcd = platform_get_drvdata(dev);
+	struct ehci_platform_priv *priv = hcd_to_ehci_priv(hcd);
+	int clk;
+
+	if (priv->phy) {
+		phy_power_off(priv->phy);
+		phy_exit(priv->phy);
+	}
+
+	for (clk = EHCI_MAX_CLKS - 1; clk >= 0; clk--)
+		if (priv->clks[clk])
+			clk_disable_unprepare(priv->clks[clk]);
+}
+
 static struct hc_driver __read_mostly ehci_platform_hc_driver;
 
 static const struct ehci_driver_overrides platform_overrides __initconst = {
-	.reset =	ehci_platform_reset,
+	.reset =		ehci_platform_reset,
+	.extra_priv_size =	sizeof(struct ehci_platform_priv),
 };
 
-static struct usb_ehci_pdata ehci_platform_defaults;
+static struct usb_ehci_pdata ehci_platform_defaults = {
+	.power_on =		ehci_platform_power_on,
+	.power_suspend =	ehci_platform_power_off,
+	.power_off =		ehci_platform_power_off,
+};
 
 static int ehci_platform_probe(struct platform_device *dev)
 {
 	struct usb_hcd *hcd;
 	struct resource *res_mem;
-	struct usb_ehci_pdata *pdata;
-	int irq;
-	int err;
+	struct usb_ehci_pdata *pdata = dev_get_platdata(&dev->dev);
+	struct ehci_platform_priv *priv;
+	int err, irq, clk = 0;
 
 	if (usb_disabled())
 		return -ENODEV;
 
 	/*
-	 * use reasonable defaults so platforms don't have to provide these.
-	 * with DT probing on ARM, none of these are set.
+	 * Use reasonable defaults so platforms don't have to provide these
+	 * with DT probing on ARM.
 	 */
-	if (!dev_get_platdata(&dev->dev))
-		dev->dev.platform_data = &ehci_platform_defaults;
+	if (!pdata)
+		pdata = &ehci_platform_defaults;
 
 	err = dma_coerce_mask_and_coherent(&dev->dev, DMA_BIT_MASK(32));
 	if (err)
 		return err;
 
-	pdata = dev_get_platdata(&dev->dev);
-
 	irq = platform_get_irq(dev, 0);
 	if (irq < 0) {
 		dev_err(&dev->dev, "no irq provided");
@@ -107,17 +169,40 @@ static int ehci_platform_probe(struct platform_device *dev)
 		return -ENXIO;
 	}
 
+	hcd = usb_create_hcd(&ehci_platform_hc_driver, &dev->dev,
+			     dev_name(&dev->dev));
+	if (!hcd)
+		return -ENOMEM;
+
+	platform_set_drvdata(dev, hcd);
+	dev->dev.platform_data = pdata;
+	priv = hcd_to_ehci_priv(hcd);
+
+	if (pdata == &ehci_platform_defaults && dev->dev.of_node) {
+		priv->phy = devm_phy_get(&dev->dev, "usb");
+		if (IS_ERR(priv->phy)) {
+			err = PTR_ERR(priv->phy);
+			if (err == -EPROBE_DEFER)
+				goto err_put_hcd;
+			priv->phy = NULL;
+		}
+
+		for (clk = 0; clk < EHCI_MAX_CLKS; clk++) {
+			priv->clks[clk] = of_clk_get(dev->dev.of_node, clk);
+			if (IS_ERR(priv->clks[clk])) {
+				err = PTR_ERR(priv->clks[clk]);
+				if (err == -EPROBE_DEFER)
+					goto err_put_clks;
+				priv->clks[clk] = NULL;
+				break;
+			}
+		}
+	}
+
 	if (pdata->power_on) {
 		err = pdata->power_on(dev);
 		if (err < 0)
-			return err;
-	}
-
-	hcd = usb_create_hcd(&ehci_platform_hc_driver, &dev->dev,
-			     dev_name(&dev->dev));
-	if (!hcd) {
-		err = -ENOMEM;
-		goto err_power;
+			goto err_put_clks;
 	}
 
 	hcd->rsrc_start = res_mem->start;
@@ -126,21 +211,25 @@ static int ehci_platform_probe(struct platform_device *dev)
 	hcd->regs = devm_ioremap_resource(&dev->dev, res_mem);
 	if (IS_ERR(hcd->regs)) {
 		err = PTR_ERR(hcd->regs);
-		goto err_put_hcd;
+		goto err_power;
 	}
 	err = usb_add_hcd(hcd, irq, IRQF_SHARED);
 	if (err)
-		goto err_put_hcd;
-
-	platform_set_drvdata(dev, hcd);
+		goto err_power;
 
 	return err;
 
-err_put_hcd:
-	usb_put_hcd(hcd);
 err_power:
 	if (pdata->power_off)
 		pdata->power_off(dev);
+err_put_clks:
+	while (--clk >= 0)
+		clk_put(priv->clks[clk]);
+err_put_hcd:
+	if (pdata == &ehci_platform_defaults)
+		dev->dev.platform_data = NULL;
+
+	usb_put_hcd(hcd);
 
 	return err;
 }
@@ -149,13 +238,19 @@ static int ehci_platform_remove(struct platform_device *dev)
 {
 	struct usb_hcd *hcd = platform_get_drvdata(dev);
 	struct usb_ehci_pdata *pdata = dev_get_platdata(&dev->dev);
+	struct ehci_platform_priv *priv = hcd_to_ehci_priv(hcd);
+	int clk;
 
 	usb_remove_hcd(hcd);
-	usb_put_hcd(hcd);
 
 	if (pdata->power_off)
 		pdata->power_off(dev);
 
+	for (clk = 0; clk < EHCI_MAX_CLKS && priv->clks[clk]; clk++)
+		clk_put(priv->clks[clk]);
+
+	usb_put_hcd(hcd);
+
 	if (pdata == &ehci_platform_defaults)
 		dev->dev.platform_data = NULL;
 
@@ -206,8 +301,10 @@ static int ehci_platform_resume(struct device *dev)
 static const struct of_device_id vt8500_ehci_ids[] = {
 	{ .compatible = "via,vt8500-ehci", },
 	{ .compatible = "wm,prizm-ehci", },
+	{ .compatible = "usb-ehci", },
 	{}
 };
+MODULE_DEVICE_TABLE(of, vt8500_ehci_ids);
 
 static const struct platform_device_id ehci_platform_table[] = {
 	{ "ehci-platform", 0 },
-- 
1.8.5.3

^ permalink raw reply related

* [PATCH v8 1/4] ohci-platform: Add support for devicetree instantiation
From: Hans de Goede @ 2014-01-22 19:32 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1390419177-6481-1-git-send-email-hdegoede@redhat.com>

Add support for ohci-platform instantiation from devicetree, including
optionally getting clks and a phy from devicetree, and enabling / disabling
those on power_on / off.

This should allow using ohci-platform from devicetree in various cases.
Specifically after this commit it can be used for the ohci controller found
on Allwinner sunxi SoCs.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
---
 Documentation/devicetree/bindings/usb/usb-ohci.txt |  22 +++
 drivers/usb/host/ohci-platform.c                   | 164 ++++++++++++++++++---
 2 files changed, 162 insertions(+), 24 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/usb/usb-ohci.txt

diff --git a/Documentation/devicetree/bindings/usb/usb-ohci.txt b/Documentation/devicetree/bindings/usb/usb-ohci.txt
new file mode 100644
index 0000000..6ba38d9
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/usb-ohci.txt
@@ -0,0 +1,22 @@
+USB OHCI controllers
+
+Required properties:
+- compatible : "usb-ohci"
+- reg : ohci controller register range (address and length)
+- interrupts : ohci controller interrupt
+
+Optional properties:
+- clocks : a list of phandle + clock specifier pairs
+- phys : phandle + phy specifier pair
+- phy-names : "usb"
+
+Example:
+
+	ohci0: usb at 01c14400 {
+		compatible = "allwinner,sun4i-a10-ohci", "usb-ohci";
+		reg = <0x01c14400 0x100>;
+		interrupts = <64>;
+		clocks = <&usb_clk 6>, <&ahb_gates 2>;
+		phys = <&usbphy 1>;
+		phy-names = "usb";
+	};
diff --git a/drivers/usb/host/ohci-platform.c b/drivers/usb/host/ohci-platform.c
index f351ff5..b2d0e1e 100644
--- a/drivers/usb/host/ohci-platform.c
+++ b/drivers/usb/host/ohci-platform.c
@@ -3,6 +3,7 @@
  *
  * Copyright 2007 Michael Buesch <m@bues.ch>
  * Copyright 2011-2012 Hauke Mehrtens <hauke@hauke-m.de>
+ * Copyright 2014 Hans de Goede <hdegoede@redhat.com>
  *
  * Derived from the OCHI-SSB driver
  * Derived from the OHCI-PCI driver
@@ -14,11 +15,14 @@
  * Licensed under the GNU/GPL. See COPYING for details.
  */
 
+#include <linux/clk.h>
+#include <linux/dma-mapping.h>
 #include <linux/hrtimer.h>
 #include <linux/io.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/err.h>
+#include <linux/phy/phy.h>
 #include <linux/platform_device.h>
 #include <linux/usb/ohci_pdriver.h>
 #include <linux/usb.h>
@@ -27,6 +31,13 @@
 #include "ohci.h"
 
 #define DRIVER_DESC "OHCI generic platform driver"
+#define OHCI_MAX_CLKS 3
+#define hcd_to_ohci_priv(h) ((struct ohci_platform_priv *)hcd_to_ohci(h)->priv)
+
+struct ohci_platform_priv {
+	struct clk *clks[OHCI_MAX_CLKS];
+	struct phy *phy;
+};
 
 static const char hcd_name[] = "ohci-platform";
 
@@ -48,11 +59,67 @@ static int ohci_platform_reset(struct usb_hcd *hcd)
 	return ohci_setup(hcd);
 }
 
+static int ohci_platform_power_on(struct platform_device *dev)
+{
+	struct usb_hcd *hcd = platform_get_drvdata(dev);
+	struct ohci_platform_priv *priv = hcd_to_ohci_priv(hcd);
+	int clk, ret;
+
+	for (clk = 0; clk < OHCI_MAX_CLKS && priv->clks[clk]; clk++) {
+		ret = clk_prepare_enable(priv->clks[clk]);
+		if (ret)
+			goto err_disable_clks;
+	}
+
+	if (priv->phy) {
+		ret = phy_init(priv->phy);
+		if (ret)
+			goto err_disable_clks;
+
+		ret = phy_power_on(priv->phy);
+		if (ret)
+			goto err_exit_phy;
+	}
+
+	return 0;
+
+err_exit_phy:
+	phy_exit(priv->phy);
+err_disable_clks:
+	while (--clk >= 0)
+		clk_disable_unprepare(priv->clks[clk]);
+
+	return ret;
+}
+
+static void ohci_platform_power_off(struct platform_device *dev)
+{
+	struct usb_hcd *hcd = platform_get_drvdata(dev);
+	struct ohci_platform_priv *priv = hcd_to_ohci_priv(hcd);
+	int clk;
+
+	if (priv->phy) {
+		phy_power_off(priv->phy);
+		phy_exit(priv->phy);
+	}
+
+	for (clk = OHCI_MAX_CLKS - 1; clk >= 0; clk--)
+		if (priv->clks[clk])
+			clk_disable_unprepare(priv->clks[clk]);
+}
+
 static struct hc_driver __read_mostly ohci_platform_hc_driver;
 
 static const struct ohci_driver_overrides platform_overrides __initconst = {
-	.product_desc =	"Generic Platform OHCI controller",
-	.reset =	ohci_platform_reset,
+	.product_desc =		"Generic Platform OHCI controller",
+	.reset =		ohci_platform_reset,
+	.extra_priv_size =	sizeof(struct ohci_platform_priv),
+};
+
+static struct usb_ohci_pdata ohci_platform_defaults = {
+	.power_on =		ohci_platform_power_on,
+	.power_suspend =	ohci_platform_power_off,
+	.power_off =		ohci_platform_power_off,
 };
 
 static int ohci_platform_probe(struct platform_device *dev)
@@ -60,17 +127,23 @@ static int ohci_platform_probe(struct platform_device *dev)
 	struct usb_hcd *hcd;
 	struct resource *res_mem;
 	struct usb_ohci_pdata *pdata = dev_get_platdata(&dev->dev);
-	int irq;
-	int err = -ENOMEM;
-
-	if (!pdata) {
-		WARN_ON(1);
-		return -ENODEV;
-	}
+	struct ohci_platform_priv *priv;
+	int err, irq, clk = 0;
 
 	if (usb_disabled())
 		return -ENODEV;
 
+	/*
+	 * Use reasonable defaults so platforms don't have to provide these
+	 * with DT probing on ARM.
+	 */
+	if (!pdata)
+		pdata = &ohci_platform_defaults;
+
+	err = dma_coerce_mask_and_coherent(&dev->dev, DMA_BIT_MASK(32));
+	if (err)
+		return err;
+
 	irq = platform_get_irq(dev, 0);
 	if (irq < 0) {
 		dev_err(&dev->dev, "no irq provided");
@@ -83,17 +156,40 @@ static int ohci_platform_probe(struct platform_device *dev)
 		return -ENXIO;
 	}
 
+	hcd = usb_create_hcd(&ohci_platform_hc_driver, &dev->dev,
+			dev_name(&dev->dev));
+	if (!hcd)
+		return -ENOMEM;
+
+	platform_set_drvdata(dev, hcd);
+	dev->dev.platform_data = pdata;
+	priv = hcd_to_ohci_priv(hcd);
+
+	if (pdata == &ohci_platform_defaults && dev->dev.of_node) {
+		priv->phy = devm_phy_get(&dev->dev, "usb");
+		if (IS_ERR(priv->phy)) {
+			err = PTR_ERR(priv->phy);
+			if (err == -EPROBE_DEFER)
+				goto err_put_hcd;
+			priv->phy = NULL;
+		}
+
+		for (clk = 0; clk < OHCI_MAX_CLKS; clk++) {
+			priv->clks[clk] = of_clk_get(dev->dev.of_node, clk);
+			if (IS_ERR(priv->clks[clk])) {
+				err = PTR_ERR(priv->clks[clk]);
+				if (err == -EPROBE_DEFER)
+					goto err_put_clks;
+				priv->clks[clk] = NULL;
+				break;
+			}
+		}
+	}
+
 	if (pdata->power_on) {
 		err = pdata->power_on(dev);
 		if (err < 0)
-			return err;
-	}
-
-	hcd = usb_create_hcd(&ohci_platform_hc_driver, &dev->dev,
-			dev_name(&dev->dev));
-	if (!hcd) {
-		err = -ENOMEM;
-		goto err_power;
+			goto err_put_clks;
 	}
 
 	hcd->rsrc_start = res_mem->start;
@@ -102,21 +198,25 @@ static int ohci_platform_probe(struct platform_device *dev)
 	hcd->regs = devm_ioremap_resource(&dev->dev, res_mem);
 	if (IS_ERR(hcd->regs)) {
 		err = PTR_ERR(hcd->regs);
-		goto err_put_hcd;
+		goto err_power;
 	}
 	err = usb_add_hcd(hcd, irq, IRQF_SHARED);
 	if (err)
-		goto err_put_hcd;
-
-	platform_set_drvdata(dev, hcd);
+		goto err_power;
 
 	return err;
 
-err_put_hcd:
-	usb_put_hcd(hcd);
 err_power:
 	if (pdata->power_off)
 		pdata->power_off(dev);
+err_put_clks:
+	while (--clk >= 0)
+		clk_put(priv->clks[clk]);
+err_put_hcd:
+	if (pdata == &ohci_platform_defaults)
+		dev->dev.platform_data = NULL;
+
+	usb_put_hcd(hcd);
 
 	return err;
 }
@@ -125,13 +225,22 @@ static int ohci_platform_remove(struct platform_device *dev)
 {
 	struct usb_hcd *hcd = platform_get_drvdata(dev);
 	struct usb_ohci_pdata *pdata = dev_get_platdata(&dev->dev);
+	struct ohci_platform_priv *priv = hcd_to_ohci_priv(hcd);
+	int clk;
 
 	usb_remove_hcd(hcd);
-	usb_put_hcd(hcd);
 
 	if (pdata->power_off)
 		pdata->power_off(dev);
 
+	for (clk = 0; clk < OHCI_MAX_CLKS && priv->clks[clk]; clk++)
+		clk_put(priv->clks[clk]);
+
+	usb_put_hcd(hcd);
+
+	if (pdata == &ohci_platform_defaults)
+		dev->dev.platform_data = NULL;
+
 	return 0;
 }
 
@@ -178,6 +287,12 @@ static int ohci_platform_resume(struct device *dev)
 #define ohci_platform_resume	NULL
 #endif /* CONFIG_PM */
 
+static const struct of_device_id ohci_platform_ids[] = {
+	{ .compatible = "usb-ohci", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, ohci_platform_ids);
+
 static const struct platform_device_id ohci_platform_table[] = {
 	{ "ohci-platform", 0 },
 	{ }
@@ -198,6 +313,7 @@ static struct platform_driver ohci_platform_driver = {
 		.owner	= THIS_MODULE,
 		.name	= "ohci-platform",
 		.pm	= &ohci_platform_pm_ops,
+		.of_match_table = ohci_platform_ids,
 	}
 };
 
-- 
1.8.5.3

^ permalink raw reply related

* [PATCH v8 0/4] ohci and ehci-platform clks, phy, be and dt support
From: Hans de Goede @ 2014-01-22 19:32 UTC (permalink / raw)
  To: linux-arm-kernel

Hi All,

Although v7 was intended as the final version here is a v8, compared to v7
this contains 2 small fixes to the dt-bindings documentation so that the
examples there match the dt-node naming rules.

Besides that I've also rolled v2 of my patches to also add support for
specifying controller endianness through dt into this set.

Regards,

Hans

^ permalink raw reply

* [PATCH 2/2] ehci-platform: Add support for controllers with big-endian regs / descriptors
From: Hans de Goede @ 2014-01-22 19:28 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAGVrzcZJBjVvJm5WkpXpp_u3a-q4qMqgHvcxCJF=RUoeEwdzjQ@mail.gmail.com>

Hi,

On 01/21/2014 08:39 PM, Florian Fainelli wrote:
> 2014/1/21 Hans de Goede <hdegoede@redhat.com>:
>> This uses the already documented devicetree booleans for this.
>
> (I would greatly appreciate if you could CC people who gave you
> feedback on this before)

Will do.

> A more informative commit message would be welcome, along with a
> reference to which Device Tree binding documentation you are referring
> to.

I've added a reference to the bindings doc in the commit msg for my next version.

>> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
>> ---
>>   drivers/usb/host/Kconfig         |  3 +++
>>   drivers/usb/host/ehci-platform.c | 33 +++++++++++++++++++++++++++++++--
>>   2 files changed, 34 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
>> index 237d7b1..4af41f3 100644
>> --- a/drivers/usb/host/Kconfig
>> +++ b/drivers/usb/host/Kconfig
>> @@ -256,6 +256,9 @@ config USB_EHCI_ATH79
>>   config USB_EHCI_HCD_PLATFORM
>>          tristate "Generic EHCI driver for a platform device"
>>          depends on !PPC_OF
>> +       # Support BE on architectures which have readl_be
>> +       select USB_EHCI_BIG_ENDIAN_DESC if (AVR32 || MIPS || MICROBLAZE || SPARC || PPC32 || PPC64)
>> +       select USB_EHCI_BIG_ENDIAN_MMIO if (AVR32 || MIPS || MICROBLAZE || SPARC || PPC32 || PPC64)
>
> I do not think this is that simple nor correct for at least Microblaze
> and MIPS since they can run in either BE or LE mode, and those
> specific platforms should already do the proper select at the
> board/SoC level. This *might* be correct for SPARC, PPC32 and PPC64,
> although I believe some specific PPC64 boards can run in little-endian
> mode like the P-series, SPARC might too.
>
> It seems to me that you should not touch this and keep the existing
> selects in place, if it turns out that the selects are missing the
> error messages you added below are catching those misuses.

As discussed with Alan, I will drop these lines from my next version.

>>          default n
>>          ---help---
>>            Adds an EHCI host driver for a generic platform device, which
>> diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c
>> index d8aebc0..5888abb 100644
>> --- a/drivers/usb/host/ehci-platform.c
>> +++ b/drivers/usb/host/ehci-platform.c
>> @@ -55,8 +55,10 @@ static int ehci_platform_reset(struct usb_hcd *hcd)
>>
>>          hcd->has_tt = pdata->has_tt;
>>          ehci->has_synopsys_hc_bug = pdata->has_synopsys_hc_bug;
>> -       ehci->big_endian_desc = pdata->big_endian_desc;
>> -       ehci->big_endian_mmio = pdata->big_endian_mmio;
>> +       if (pdata->big_endian_desc)
>> +               ehci->big_endian_desc = 1;
>> +       if (pdata->big_endian_mmio)
>> +               ehci->big_endian_mmio = 1;
>>
>>          if (pdata->pre_setup) {
>>                  retval = pdata->pre_setup(hcd);
>> @@ -142,6 +144,7 @@ static int ehci_platform_probe(struct platform_device *dev)
>>          struct resource *res_mem;
>>          struct usb_ehci_pdata *pdata = dev_get_platdata(&dev->dev);
>>          struct ehci_platform_priv *priv;
>> +       struct ehci_hcd *ehci;
>>          int err, irq, clk = 0;
>>
>>          if (usb_disabled())
>> @@ -177,8 +180,34 @@ static int ehci_platform_probe(struct platform_device *dev)
>>          platform_set_drvdata(dev, hcd);
>>          dev->dev.platform_data = pdata;
>>          priv = hcd_to_ehci_priv(hcd);
>> +       ehci = hcd_to_ehci(hcd);
>>
>>          if (pdata == &ehci_platform_defaults && dev->dev.of_node) {
>> +               if (of_property_read_bool(dev->dev.of_node, "big-endian-regs"))
>> +                       ehci->big_endian_mmio = 1;
>> +
>> +               if (of_property_read_bool(dev->dev.of_node, "big-endian-desc"))
>> +                       ehci->big_endian_desc = 1;
>> +
>> +               if (of_property_read_bool(dev->dev.of_node, "big-endian"))
>> +                       ehci->big_endian_mmio = ehci->big_endian_desc = 1;
>
> Ok, so I am confused now, should you update
> pdata->ehci_big_endian_{desc,mmio} here or is it valid to directly
> modify ehci->big_endian_{desc,mmio}, is not there any risk  to undo
> what is done in ehci_platform_reset(), or is ehci_platform_reset()
> only called for non-DT cases?

Both the pdata checks in ehci_platform_reset() and the dt checks here only
ever set these flags, neither code path clears them. And in the dt case pdata
will be NULL and vice versa.

>
>> +
>> +#ifndef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO
>> +               if (ehci->big_endian_mmio) {
>> +                       dev_err(&dev->dev,
>> +                               "Error big-endian-regs not compiled in\n");
>
> I do not think using the Device Tree property name would be very
> informative since this is supposed to guard against misconfigurations
> for both DT and non-DT enabled platforms

Nope this is in a dt only code path.

>> +                       err = -EINVAL;
>> +                       goto err_put_hcd;
>> +               }
>> +#endif
>> +#ifndef CONFIG_USB_EHCI_BIG_ENDIAN_DESC
>> +               if (ehci->big_endian_desc) {
>> +                       dev_err(&dev->dev,
>> +                               "Error big-endian-desc not compiled in\n");
>> +                       err = -EINVAL;
>> +                       goto err_put_hcd;
>
> And here "support for big-endian descriptors not enabled".
>
>> +               }
>> +#endif
>>                  priv->phy = devm_phy_get(&dev->dev, "usb");
>>                  if (IS_ERR(priv->phy)) {
>>                          err = PTR_ERR(priv->phy);

Regards,

Hans

^ permalink raw reply

* [PATCH v2 5/5] [RFC] omapdss: remove FEAT_DPI_USES_VDDS_DSI from omap3
From: Javier Martinez Canillas @ 2014-01-22 19:21 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1390417460-3134-6-git-send-email-chf.fritz@googlemail.com>

Hello Christoph,

On 01/22/2014 04:04 PM, Christoph Fritz wrote:
> DBB056 doesn't use DSI for its display, but omap3 forces this
> erroneously for all its boards:
> 
>   | OMAP DSS rev 2.0
>   | omapdss DPI error: can't get VDDS_DSI regulator
>   | omapfb omapfb: failed to connect default display
>   | omapfb omapfb: failed to init overlay connections
>   | omapfb omapfb: failed to setup omapfb
>   | platform omapfb: Driver omapfb requests probe deferral
> 
> So this patch just disables it for omap3. Consider this as a hack!
> Is there a proper fix for this issue?

It is also a hack but I solved on the IGEPv2 board by adding a regulator-name =
"vdds_dsi" to the VPLL2 regulator as suggested by Tony.

Look at commit 2f2befd8 ("ARM: dts: omap3-igep0020: name twl4030 VPLL2 regulator
as vdds_dsi")

Having the workaround in the Device Tree is better IMHO since this is a
per-board configuration. That can be later removed once the DSS DT bindings are
added to mainline.

Thanks a lot and best regards,
Javier

^ permalink raw reply

* [PATCH RFC v2 2/2] Documentation: arm: define DT C-states bindings
From: Lorenzo Pieralisi @ 2014-01-22 19:20 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAKfTPtAbYXuis1bfyDLiHRaYwosre3RAG+iNQSz-y+cWfc3uQA@mail.gmail.com>

Hi Vincent,

On Tue, Jan 21, 2014 at 11:16:46AM +0000, Vincent Guittot wrote:
> Hi Lorenzo,
> 
> On 20 January 2014 18:47, Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> wrote:
> > ARM based platforms implement a variety of power management schemes that
> > allow processors to enter at run-time low-power states, aka C-states
> > in ACPI jargon. The parameters defining these C-states vary on a per-platform
> > basis forcing the OS to hardcode the state parameters in platform
> > specific static tables whose size grows as the number of platforms supported
> > in the kernel increases and hampers device drivers standardization.
> >
> > Therefore, this patch aims at standardizing C-state device tree bindings for
> > ARM platforms. Bindings define C-state parameters inclusive of entry methods
> > and state latencies, to allow operating systems to retrieve the
> > configuration entries from the device tree and initialize the related
> > power management drivers, paving the way for common code in the kernel
> > to deal with power states and removing the need for static data in current
> > and previous kernel versions.
> >
> > Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> > ---
> >  Documentation/devicetree/bindings/arm/c-states.txt | 774 +++++++++++++++++++++
> >  Documentation/devicetree/bindings/arm/cpus.txt     |  10 +
> >  2 files changed, 784 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/arm/c-states.txt
> >
> > diff --git a/Documentation/devicetree/bindings/arm/c-states.txt b/Documentation/devicetree/bindings/arm/c-states.txt
> > new file mode 100644
> > index 0000000..0b5617b
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/arm/c-states.txt
> > @@ -0,0 +1,774 @@
> > +==========================================
> > +ARM C-states binding description
> > +==========================================
> > +
> > +==========================================
> > +1 - Introduction
> > +==========================================
> > +
> > +ARM systems contain HW capable of managing power consumption dynamically,
> > +where cores can be put in different low-power states (ranging from simple
> > +wfi to power gating) according to OSPM policies. Borrowing concepts
> > +from the ACPI specification[1], the CPU states representing the range of
> > +dynamic states that a processor can enter at run-time, aka C-state, can be
> > +specified through device tree bindings representing the parameters required to
> > +enter/exit specific C-states on a given processor.
> > +
> > +The state an ARM CPU can be put into is loosely identified by one of the
> > +following operating modes:
> > +
> > +- Running:
> > +        # Processor core is executing instructions
> > +
> > +- Wait for Interrupt:
> > +       # An ARM processor enters wait for interrupt (WFI) low power
> > +         state by executing a wfi instruction. When a processor enters
> > +         wfi state it disables most of the clocks while keeping the processor
> > +         powered up. This state is standard on all ARM processors and it is
> > +         defined as C1 in the remainder of this document.
> > +
> 
> > +- Dormant:
> > +       # Dormant mode is entered by executing wfi instructions and by sending
> > +         platform specific commands to the platform power controller (coupled
> > +         with processor specific SW/HW control sequences).
> > +         In dormant mode, most of the processor control and debug logic is
> > +         powered up but cache RAM can be put in retention state, providing
> 
> Base on your description, it's not clear for me what is on, what is
> lost and what is power down ?
> My understand of the dormant mode that you described above is : the
> cache is preserved (and especially the cache RAM) but the processor
> state is lost (registers ...). Do I understand correctly ?
> 
> What about retention mode where the contents of processor and cache
> are preserved but the power consumption is reduced ? it can be seen as
> a special wfi mode which need specific SW/HW control sequences but i'm
> not sure to understand how to describe such state with your proposal.

I had an idea. To simplify things, I think that one possibility is to
add a parameter to the power domain specifier (platform specific, see
Tomasz bindings):

Documentation/devicetree/bindings/power/power_domain.txt

http://lists.infradead.org/pipermail/linux-arm-kernel/2014-January/224928.html

to represent, when that state is entered the behavior of the power
controller (ie cache RAM retention or cache shutdown or in general any
substate within a power domain). Since it is platform specific, and since
we are able to link caches to the power domain, the power controller will
actually define what happens to the cache when that state is entered
(basically we use the power domain specifier additional parameter to define
a "substate" in that power domain e.g.:

Example:

foo_power_controller {
	[...]
	/*
	 * first cell is register index, second one is the state index
	 * that in turn implies the state behavior - eg cache lost or
	 * retained
	 */
	#power-domain-cells = <2>;
};

l1-cache {
	[...]
	/*
	 * syntax: power-domains = list of power domain specifiers
		<[&power_domain_phandle register-index state],[&power_domain_phandle register-index state]>;
		The syntax is defined by the power controller du jour
		as described by Tomasz bindings
	*/
	power-domains =<&foo_power_controller 0 0 &foo_power_controller 0 1>;

}:

and then

state0 {
	index = <2>;
	compatible = "arm,cpu-power-state";
	latency = <...>;
	/*
	 * This means that when the state is entered, the power
	 * controller should use register index 0 and state 0,
	 * whose meaning is power controller specific. Since we
	 * know all components affected (for every component
	 * we declare its power domain(s) and states so we
	 * know what components are affected by the state entry.
	 * Given the cache node above and this phandle, the state
	 * implies that the cache is retained, register index == 0 state == 0
	 /*
	power-domain =<&foo_power_controller 0 0>;
};

state1 {
	index = <3>;
	compatible = "arm,cpu-power-state";
	latency = <...>;
	/*
	 * This means that when the state is entered, the power
	 * controller should use register index 0 and state 1,
	 * whose meaning is power controller specific. Since we
	 * know all components affected (for every component
	 * we declare its power domain(s) and states so we
	 * know what components are affected by the state entry.
	 * Given the cache node above and this phandle, the state
	 * implies that the cache is lost, register index == 0 state == 1
	 /*
	power-domain =<&foo_power_controller 0 1>;
};

It is complex but it is probably the cleanest way. And it leaves complexity
to power controller implementations (if managed in the kernel....), which
actually makes sense because it is up to power controller to define the
behavior of certain states.

All in all it is just an idea, feel free to scotch it, it is complex but
we have to sort it out, one way or another.

Vincent, Tomasz, anyone, thoughts ?
Lorenzo

^ permalink raw reply

* [PATCH v3 02/11] iommu/arm-smmu: Introduce iommu_group notifier block
From: Varun Sethi @ 2014-01-22 19:07 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140122153352.GE14108@mudshark.cambridge.arm.com>



> -----Original Message-----
> From: Will Deacon [mailto:will.deacon at arm.com]
> Sent: Wednesday, January 22, 2014 9:04 PM
> To: Sethi Varun-B16395
> Cc: Andreas Herrmann; iommu at lists.linux-foundation.org; linux-arm-
> kernel at lists.infradead.org; Andreas Herrmann
> Subject: Re: [PATCH v3 02/11] iommu/arm-smmu: Introduce iommu_group
> notifier block
> 
> On Wed, Jan 22, 2014 at 01:54:11PM +0000, Varun Sethi wrote:
> > > > > Ok, so are you suggesting that we perform the isolation mapping
> > > > > in arm_smmu_add_device and drop the notifier altogether?
> > > > I think that should be fine, until we want to delay mapping
> > > > creation till driver bind time.
> > >
> > > Is there a hard dependency on that?
> > >
> > Not sure, may be Andreas can answer that.
> 
> Ok. Andreas? I would have thought doing this *earlier* shouldn't be a
> problem (the DMA ops must be swizzled before the driver is probed).
> 
> > > > But the "isolate device" property should dictate iommu group
> creation.
> > >
> > > The reason we added automatic group creation (per-device) is for
> > > VFIO, which expects all devices to be in a group regardless of the
> > > device isolation configuration.
> > >
> > IIUC, with the "isolate devices" property we ensure that there would
> > be independent SMR and S2CR per device. Is that correct?
> 
> Yes, as part of giving them independent sets of page tables. Initially
> these tables don't have any valid mappings, but the dma-mapping API will
> populate them in response to dma_map_*/dma_alloc/etc.
> 
> Not sure what this has to do with us putting devices into their own
> groups...
[Sethi Varun-B16395] Devices in an iommu group would share the dma mapping, so shouldn't they be sharing the SMR and context registers? In case of the "isolate devices"  property, each device would have its own SMR and context registers, thus allowing the devices to have independent mappings and allowing them to fall in separate iommu groups.

-Varun

^ permalink raw reply

* [PATCH v5 14/14] ARM: sun7i: dts: Add ahci / sata support
From: Hans de Goede @ 2014-01-22 19:04 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1390417489-5354-1-git-send-email-hdegoede@redhat.com>

This patch adds sunxi sata support to A20 boards that have such a connector.
Some boards also feature a regulator via a GPIO and support for this is also
added.

Signed-off-by: Olliver Schinagl <oliver@schinagl.nl>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 arch/arm/boot/dts/sun7i-a20-cubieboard2.dts     |  6 ++++++
 arch/arm/boot/dts/sun7i-a20-cubietruck.dts      | 20 ++++++++++++++++++++
 arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts |  6 ++++++
 arch/arm/boot/dts/sun7i-a20.dtsi                |  8 ++++++++
 4 files changed, 40 insertions(+)

diff --git a/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts b/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts
index 48777cd..1cab521 100644
--- a/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts
+++ b/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts
@@ -13,6 +13,7 @@
 
 /dts-v1/;
 /include/ "sun7i-a20.dtsi"
+/include/ "sunxi-ahci-reg.dtsi"
 
 / {
 	model = "Cubietech Cubieboard2";
@@ -28,6 +29,11 @@
 			status = "okay";
 		};
 
+		ahci: sata at 01c18000 {
+			target-supply = <&reg_ahci_5v>;
+			status = "okay";
+		};
+
 		pinctrl at 01c20800 {
 			mmc0_cd_pin_cubieboard2: mmc0_cd_pin at 0 {
 				allwinner,pins = "PH1";
diff --git a/arch/arm/boot/dts/sun7i-a20-cubietruck.dts b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
index 2684f27..1247ea1 100644
--- a/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
+++ b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
@@ -13,6 +13,7 @@
 
 /dts-v1/;
 /include/ "sun7i-a20.dtsi"
+/include/ "sunxi-ahci-reg.dtsi"
 
 / {
 	model = "Cubietech Cubietruck";
@@ -28,6 +29,11 @@
 			status = "okay";
 		};
 
+		ahci: sata at 01c18000 {
+			target-supply = <&reg_ahci_5v>;
+			status = "okay";
+		};
+
 		pinctrl at 01c20800 {
 			mmc0_cd_pin_cubietruck: mmc0_cd_pin at 0 {
 				allwinner,pins = "PH1";
@@ -36,6 +42,13 @@
 				allwinner,pull = <0>;
 			};
 
+			ahci_pwr_pin_cubietruck: ahci_pwr_pin at 1 {
+				allwinner,pins = "PH12";
+				allwinner,function = "gpio_out";
+				allwinner,drive = <0>;
+				allwinner,pull = <0>;
+			};
+
 			led_pins_cubietruck: led_pins at 0 {
 				allwinner,pins = "PH7", "PH11", "PH20", "PH21";
 				allwinner,function = "gpio_out";
@@ -84,4 +97,11 @@
 			gpios = <&pio 7 7 0>;
 		};
 	};
+
+	regulators {
+		reg_ahci_5v: ahci-5v {
+			pinctrl-0 = <&ahci_pwr_pin_cubietruck>;
+			gpio = <&pio 7 12 0>;
+		};
+	};
 };
diff --git a/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts b/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts
index bf6f6c8..f135886 100644
--- a/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts
+++ b/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts
@@ -13,6 +13,7 @@
 
 /dts-v1/;
 /include/ "sun7i-a20.dtsi"
+/include/ "sunxi-ahci-reg.dtsi"
 
 / {
 	model = "Olimex A20-Olinuxino Micro";
@@ -37,6 +38,11 @@
 			status = "okay";
 		};
 
+		ahci: sata at 01c18000 {
+			target-supply = <&reg_ahci_5v>;
+			status = "okay";
+		};
+
 		pinctrl at 01c20800 {
 			mmc0_cd_pin_olinuxinom: mmc0_cd_pin at 0 {
 				allwinner,pins = "PH1";
diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
index c9c123a..0657bad 100644
--- a/arch/arm/boot/dts/sun7i-a20.dtsi
+++ b/arch/arm/boot/dts/sun7i-a20.dtsi
@@ -347,6 +347,14 @@
 			status = "disabled";
 		};
 
+		ahci: sata at 01c18000 {
+			compatible = "allwinner,sun4i-a10-ahci";
+			reg = <0x01c18000 0x1000>;
+			interrupts = <0 56 1>;
+			clocks = <&pll6 0>, <&ahb_gates 25>;
+			status = "disabled";
+		};
+
 		pio: pinctrl at 01c20800 {
 			compatible = "allwinner,sun7i-a20-pinctrl";
 			reg = <0x01c20800 0x400>;
-- 
1.8.5.3

^ permalink raw reply related


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