Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2] ARM: dts: OMAP3: Add GPMC controller
From: Florian Vaussard @ 2013-02-04 10:36 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CABxcv=k_gwB3ExQYUeappDZ6FE4L7x8Acer4ZQpDH09BL6LG0Q@mail.gmail.com>

Hi Javier,

On 02/04/2013 10:27 AM, Javier Martinez Canillas wrote:
> Hi Florian,
>
> On Mon, Jan 28, 2013 at 6:54 PM, Florian Vaussard
> <florian.vaussard@epfl.ch> wrote:
>> Add device-tree support for the GPMC controller on the OMAP3.
>>
>> Signed-off-by: Florian Vaussard <florian.vaussard@epfl.ch>
>> ---
>>   arch/arm/boot/dts/omap3.dtsi |   11 +++++++++++
>>   1 files changed, 11 insertions(+), 0 deletions(-)
>>
>> diff --git a/arch/arm/boot/dts/omap3.dtsi b/arch/arm/boot/dts/omap3.dtsi
>> index 6c63118..2ddae38 100644
>> --- a/arch/arm/boot/dts/omap3.dtsi
>> +++ b/arch/arm/boot/dts/omap3.dtsi
>> @@ -403,5 +403,16 @@
>>                          ti,timer-alwon;
>>                          ti,timer-secure;
>>                  };
>> +
>> +               gpmc: gpmc at 6e000000 {
>> +                       compatible = "ti,omap3430-gpmc";
>> +                       ti,hwmods = "gpmc";
>> +                       reg = <0x6e000000 0x1000000>;
>> +                       interrupts = <20>;
>> +                       gpmc,num-cs = <8>;
>> +                       gpmc,num-waitpins = <4>;
>> +                       #address-cells = <2>;
>> +                       #size-cells = <1>;
>> +               };
>>          };
>>   };
>
> I had the same patch on a tree I was working on to add DT support for
> gpmc-smsc911x on an OMAP3 board but I was waiting for Daniel's patches
> to hit mainline before sending the RFC. So please feel free to add:
>
> Reviewed-by: Javier Martinez Canillas <javier.martinez@collabora.co.uk>
>

Great, the smsc911x was on my TODO list, I can cross it out :) BTW,
do you have a public git for this, so I can test your work on my setup?

For the GPMC support, I will have to make a few more more as discussed with
Tony, and as I will be away for more than 2 weeks, feel free to go ahead
before me. This patchset was only at an RFC stage.

Regards,

Florian

^ permalink raw reply

* Qestion about page->_count and page reclaim
From: Li Haifeng @ 2013-02-04 10:29 UTC (permalink / raw)
  To: linux-arm-kernel

Hi, all in kernel.

The page->_count is the page frame's usage count.
When page is allocated, the page will be refcounted, and page->_cout will
be set 1.

After be allocated from buddy system, the page will be used by process.
 get_page and put_page/put_page_testzero will used in pairs. is it right?

When the page is reclaimed to buddy system, the page->_count should be 0.
However, Because the initialization of page->_count is 1, get_page() and
put_page() is called in pairs, I coufused how page->_count will be 0?

Thanks.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20130204/7de0ef46/attachment-0001.html>

^ permalink raw reply

* [PATCH] ARM: imx27: clk-imx27: SPI: Rename IPG clock and add PER clock
From: gwenhael.goavec @ 2013-02-04 10:19 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1359209221-24346-1-git-send-email-gwenhael.goavec-merou@armadeus.com>


Ping?
Gwenhael

On Sat, 26 Jan 2013 15:07:01 +0100
Gwenhael Goavec-Merou <gwenhael.goavec-merou@armadeus.com> wrote:

> spi-imx driver needs two clock: ipg and per. The first clock must be named and
> the second must be added.
> 
> Signed-off-by: Gwenhael Goavec-Merou <gwenhael.goavec-merou@armadeus.com>
> ---
>  arch/arm/mach-imx/clk-imx27.c | 9 ++++++---
>  1 file changed, 6 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arm/mach-imx/clk-imx27.c b/arch/arm/mach-imx/clk-imx27.c
> index 4c1d1e4..c599839 100644
> --- a/arch/arm/mach-imx/clk-imx27.c
> +++ b/arch/arm/mach-imx/clk-imx27.c
> @@ -228,9 +228,12 @@ int __init mx27_clocks_init(unsigned long fref)
>  	clk_register_clkdev(clk[sdhc2_ipg_gate], "ipg", "imx21-mmc.1");
>  	clk_register_clkdev(clk[per2_gate], "per", "imx21-mmc.2");
>  	clk_register_clkdev(clk[sdhc2_ipg_gate], "ipg", "imx21-mmc.2");
> -	clk_register_clkdev(clk[cspi1_ipg_gate], NULL, "imx27-cspi.0");
> -	clk_register_clkdev(clk[cspi2_ipg_gate], NULL, "imx27-cspi.1");
> -	clk_register_clkdev(clk[cspi3_ipg_gate], NULL, "imx27-cspi.2");
> +	clk_register_clkdev(clk[per2_gate], "per", "imx27-cspi.0");
> +	clk_register_clkdev(clk[cspi1_ipg_gate], "ipg", "imx27-cspi.0");
> +	clk_register_clkdev(clk[per2_gate], "per", "imx27-cspi.1");
> +	clk_register_clkdev(clk[cspi2_ipg_gate], "ipg", "imx27-cspi.1");
> +	clk_register_clkdev(clk[per2_gate], "per", "imx27-cspi.2");
> +	clk_register_clkdev(clk[cspi3_ipg_gate], "ipg", "imx27-cspi.2");
>  	clk_register_clkdev(clk[per3_gate], "per", "imx21-fb.0");
>  	clk_register_clkdev(clk[lcdc_ipg_gate], "ipg", "imx21-fb.0");
>  	clk_register_clkdev(clk[lcdc_ahb_gate], "ahb", "imx21-fb.0");
> -- 
> 1.7.12.4
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 

^ permalink raw reply

* [PATCH] pinctrl: sirf: replace of_gpio_simple_xlate by sirf specific of_xlate
From: Barry Song @ 2013-02-04  9:53 UTC (permalink / raw)
  To: linux-arm-kernel

From: Barry Song <Baohua.Song@csr.com>

the default of_gpio_simple_xlate() will make us fail while getting gpios
bigger than 32 by of_get_named_gpio() or related APIs.
this patch adds a specific of_xlate callback for sirf gpio_chip and fix
the problem.

Signed-off-by: Barry Song <Baohua.Song@csr.com>
---
 drivers/pinctrl/pinctrl-sirf.c |   18 ++++++++++++++++++
 1 files changed, 18 insertions(+), 0 deletions(-)

diff --git a/drivers/pinctrl/pinctrl-sirf.c b/drivers/pinctrl/pinctrl-sirf.c
index fc76f28..7051874 100644
--- a/drivers/pinctrl/pinctrl-sirf.c
+++ b/drivers/pinctrl/pinctrl-sirf.c
@@ -1246,6 +1246,22 @@ static void __iomem *sirfsoc_rsc_of_iomap(void)
 	return of_iomap(np, 0);
 }
 
+static int sirfsoc_gpio_of_xlate(struct gpio_chip *gc,
+       const struct of_phandle_args *gpiospec,
+       u32 *flags)
+{
+       if (gpiospec->args[0] > SIRFSOC_GPIO_NO_OF_BANKS * SIRFSOC_GPIO_BANK_SIZE)
+               return -EINVAL;
+
+       if (gc != &sgpio_bank[gpiospec->args[0] / SIRFSOC_GPIO_BANK_SIZE].chip.gc)
+               return -EINVAL;
+
+       if (flags)
+               *flags = gpiospec->args[1];
+
+       return gpiospec->args[0] % SIRFSOC_GPIO_BANK_SIZE;
+}
+
 static int sirfsoc_pinmux_probe(struct platform_device *pdev)
 {
 	int ret;
@@ -1747,6 +1763,8 @@ static int sirfsoc_gpio_probe(struct device_node *np)
 		bank->chip.gc.ngpio = SIRFSOC_GPIO_BANK_SIZE;
 		bank->chip.gc.label = kstrdup(np->full_name, GFP_KERNEL);
 		bank->chip.gc.of_node = np;
+		bank->chip.gc.of_xlate = sirfsoc_gpio_of_xlate;
+		bank->chip.gc.of_gpio_n_cells = 2;
 		bank->chip.regs = regs;
 		bank->id = i;
 		bank->is_marco = is_marco;
-- 
1.7.5.4



Member of the CSR plc group of companies. CSR plc registered in England and Wales, registered number 4187346, registered office Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, United Kingdom
More information can be found at www.csr.com. Follow CSR on Twitter at http://twitter.com/CSR_PLC and read our blog at www.csr.com/blog

^ permalink raw reply related

* [PATCH V2] clk: Add composite clock type
From: Hiroshi Doyu @ 2013-02-04  9:37 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1359965482-29655-1-git-send-email-pgaikwad@nvidia.com>

Hi Prashant,

Prashant Gaikwad <pgaikwad@nvidia.com> wrote @ Mon, 4 Feb 2013 09:11:22 +0100:

> +struct clk *clk_register_composite(struct device *dev, const char *name,
> +                       const char **parent_names, int num_parents,
> +                       struct clk_hw *mux_hw, const struct clk_ops *mux_ops,
> +                       struct clk_hw *div_hw, const struct clk_ops *div_ops,
> +                       struct clk_hw *gate_hw, const struct clk_ops *gate_ops,
> +                       unsigned long flags)
> +{
> +       struct clk *clk;
> +       struct clk_init_data init;
> +       struct clk_composite *composite;
> +       struct clk_ops *clk_composite_ops;
> +
> +       composite = kzalloc(sizeof(*composite), GFP_KERNEL);
> +       if (!composite) {
> +               pr_err("%s: could not allocate composite clk\n", __func__);
> +               return ERR_PTR(-ENOMEM);
> +       }
> +
> +       init.name = name;
> +       init.flags = flags | CLK_IS_BASIC;
> +       init.parent_names = parent_names;
> +       init.num_parents = num_parents;
> +
> +       /* allocate the clock ops */
> +       clk_composite_ops = kzalloc(sizeof(*clk_composite_ops), GFP_KERNEL);

The members of "clk_composite_ops" seems to be always assigned
statically. Istead of dynamically allocating/assigning, can't we just
have "clk_composite_ops" statically as below?

static struct clk_ops clk_composite_ops = {
	.get_parent = clk_composite_get_parent;
	.set_parent = clk_composite_set_parent;
	.recalc_rate = clk_composite_recalc_rate;
	.round_rate = clk_composite_round_rate;
	.set_rate = clk_composite_set_rate;
	.is_enabled = clk_composite_is_enabled;
	.enable = clk_composite_enable;
	.disable = clk_composite_disable;
};

struct clk *clk_register_composite(struct device *dev, const char *name,
		       const char **parent_names, int num_parents,
		       struct clk_hw *mux_hw, const struct clk_ops *mux_ops,
		       struct clk_hw *div_hw, const struct clk_ops *div_ops,
		       struct clk_hw *gate_hw, const struct clk_ops *gate_ops,
		       unsigned long flags)
{
	.....

	init.ops = &clk_composite_ops;

^ permalink raw reply

* [PATCHv5 15/16] ARM: hyp: initialize CNTVOFF to zero
From: Mark Rutland @ 2013-02-04  9:29 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20130201180753.GB1970@linaro.org>

On Fri, Feb 01, 2013 at 06:07:53PM +0000, Dave Martin wrote:
> On Fri, Feb 01, 2013 at 11:46:41AM +0000, Mark Rutland wrote:
> > On Fri, Feb 01, 2013 at 11:13:50AM +0000, Dave Martin wrote:
> > > On Thu, Jan 31, 2013 at 12:15:38PM +0000, Mark Rutland wrote:
> > > > From: Marc Zyngier <Marc.Zyngier@arm.com>
> > > > 
> > > > In order to be able to use the virtual counter in a safe way,
> > > > make sure it is initialized to zero before dropping to SVC.
> > > > 
> > > > Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> > > > Signed-off-by: Mark Rutland <mark.rutland@arm.com>
> > > > Cc: Dave Martin <dave.martin@arm.com>
> > > > ---
> > > >  arch/arm/kernel/hyp-stub.S | 3 +++
> > > >  1 file changed, 3 insertions(+)
> > > > 
> > > > diff --git a/arch/arm/kernel/hyp-stub.S b/arch/arm/kernel/hyp-stub.S
> > > > index 65b2417..455603a 100644
> > > > --- a/arch/arm/kernel/hyp-stub.S
> > > > +++ b/arch/arm/kernel/hyp-stub.S
> > > > @@ -152,6 +152,9 @@ THUMB(	orr	r7, #(1 << 30)	)	@ HSCTLR.TE
> > > >  	mrc	p15, 4, r7, c14, c1, 0	@ CNTHCTL
> > > >  	orr	r7, r7, #3		@ PL1PCEN | PL1PCTEN
> > > >  	mcr	p15, 4, r7, c14, c1, 0	@ CNTHCTL
> > > > +	mov	r6, #0
> > > > +	mov	r7, #0
> > > > +	mcrr	p15, 4, r6, r7, c14	@ CNTVOFF
> > > 
> > > Is this required for safety, or is it more a sanity feature?
> > 
> > This makes more sense with the next patch, which makes the arch_timer
> > driver always use the virtual counters (to avoid indirection in the fast
> > path and messy races with the setup of function pointers otherwise).
> > 
> > It's required for safety when hyp mode is enabled, and the arch_timer
> > driver uses the physical timers in combination with the virtual
> > counters. Either the driver has to apply CNTVOFF manually when setting
> > the physical timers, or the physical timers and virtual counters need
> > the same view of time (i.e. CNTVOFF == 0).
> > 
> > It also brings us in line with arm64, which always uses the virtual
> > counter for its vDSO.
> 
> OK.  This definitely sounds like the correct model.

Good to hear.

> 
> > 
> > > 
> > > The architected timer counters are supposed to be monotonic time sources
> > > only, so applying a random offset shouldn't really change anything.
> > 
> > This is true except when we want to use the physical timers as described above.
> > 
> > > 
> > > The main thing I can think of is that it is easier for the host to
> > > manage guests' virtual counter offsets if the host's offset is 0 (and
> > > we don't really want to be changing the host offset after the host kernel
> > > boots).
> > 
> > That's pretty much it. We don't want to have to further separate the handling
> > of the timer for host and guest. By having CNTVOFF as zero for the host, we
> > don't need to duplicate reading of the timers and/or incur an additional
> > overhead on reading them.
> 
> That all sounds sensible.  FWIW:
> 
> Reviewed-by: Dave Martin <dave.martin@linaro.org>

Thanks!

Mark.

^ permalink raw reply

* [PATCH 09/26] mfd: ab8500-debugfs: Provide a means for a user subscribe to IRQs
From: Lee Jones @ 2013-02-04  9:27 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20130203170158.GO8476@sortiz-mobl>

> > > > I'm going to have to put this patch-set in the bin. Pulling this
> > > > patch, causes lots of conflicts to the remaining patches in the
> > > > set.
> > > I bet removing this one causes a lot of conflicts. I'm not saying it should
> > > absolutely be removed, but I'm afraid once it's upstream no one is going to
> > > look at improving it.
> > 
> > This is really not the case. 
> I trust you here, but usually people get busy with other stuff after their
> patchset is upstreamed and never get back to me on the initial issues.
> 
> > I have every intention of fixing each and
> > every issue which are brought to my attention during the upstreaming
> > process of 'drivers/regulators', 'drivers/power' and 'drivers/mfd'.
> > 
> > All I'm doing is making a list of all the fixups and re-writes and
> > I'll address them on the completion of the push. Hence if you're happy
> > for this to go in with my promise of improvement, it would certainly
> > make this task a great deal easier for me.
> I'll take your words here. I'll apply this one once you adressed the other
> issues I commented about on this patchset.

Fixups complete, pull-request sent.

> > > And to be honest, having an IRQ handler from debugfs
> > > code looks weird to me. I know you can put all sort of crazyness into a
> > > debugfs entry, but still.
> > >  
> > > > I'll start again from scratch and find another way to sync the ab* MFD
> > > > drivers. I might even have to do it manually i.e. throw out all
> > > > commit history and upstream it as my own patches pulled in from diffs.
> > > I don't have any problems with that.
> > 
> > I'm sure you don't, but it's me that's doing all the hard work. ;)
> What's wrong with that ? ;)

Hmmm... :D

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

^ permalink raw reply

* [PATCH 1/2] ARM: dts: OMAP3: Add GPMC controller
From: Javier Martinez Canillas @ 2013-02-04  9:27 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1359395648-2137-2-git-send-email-florian.vaussard@epfl.ch>

Hi Florian,

On Mon, Jan 28, 2013 at 6:54 PM, Florian Vaussard
<florian.vaussard@epfl.ch> wrote:
> Add device-tree support for the GPMC controller on the OMAP3.
>
> Signed-off-by: Florian Vaussard <florian.vaussard@epfl.ch>
> ---
>  arch/arm/boot/dts/omap3.dtsi |   11 +++++++++++
>  1 files changed, 11 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm/boot/dts/omap3.dtsi b/arch/arm/boot/dts/omap3.dtsi
> index 6c63118..2ddae38 100644
> --- a/arch/arm/boot/dts/omap3.dtsi
> +++ b/arch/arm/boot/dts/omap3.dtsi
> @@ -403,5 +403,16 @@
>                         ti,timer-alwon;
>                         ti,timer-secure;
>                 };
> +
> +               gpmc: gpmc at 6e000000 {
> +                       compatible = "ti,omap3430-gpmc";
> +                       ti,hwmods = "gpmc";
> +                       reg = <0x6e000000 0x1000000>;
> +                       interrupts = <20>;
> +                       gpmc,num-cs = <8>;
> +                       gpmc,num-waitpins = <4>;
> +                       #address-cells = <2>;
> +                       #size-cells = <1>;
> +               };
>         };
>  };

I had the same patch on a tree I was working on to add DT support for
gpmc-smsc911x on an OMAP3 board but I was waiting for Daniel's patches
to hit mainline before sending the RFC. So please feel free to add:

Reviewed-by: Javier Martinez Canillas <javier.martinez@collabora.co.uk>

Best regards,
Javier

^ permalink raw reply

* [GIT PULL] mfd: First patch-set to update the AB8500 series
From: Lee Jones @ 2013-02-04  9:26 UTC (permalink / raw)
  To: linux-arm-kernel

The following changes since commit 949db153b6466c6f7cad5a427ecea94985927311:

  Linux 3.8-rc5 (2013-01-25 11:57:28 -0800)

are available in the git repository at:

  git://git.linaro.org/people/ljones/linux-3.0-ux500.git for-mfd

for you to fetch changes up to 8908c04985ed67b9138c6e06be2c81867f24e2d4:

  mfd: ab8500-gpadc: Use new ab8500_gpadc_get() with name parameter (2013-02-04 08:33:30 +0000)

----------------------------------------------------------------
Ashok G (1):
      mfd: ab8500-debugfs: sizeof() mismatch bugfix

Bengt Jonsson (1):
      mfd: ab8500-debugfs: Add interrupt debug

John Beckett (1):
      mfd: ab8500-debugfs: Export all AB8500 ADCs as debugfs nodes

Jonas Aaberg (4):
      mfd: ab8500-sysctrl: If a charger is present, reboot instead
      mfd: ab8500-sysctrl: Only reboot into charging mode if battery type is known
      mfd: ab8500-sysctrl.c: Provide charging as reset reason
      mfd: ab8500-sysctrl: export read/write symbols

Kennet Wallden (1):
      mfd: ab8500-sysctrl: Provide configuration for SysClkReqRfClkBuf registers

Lee Jones (7):
      mfd: ab8500-sysctrl: Provide a platform specific pm_power_off() call-back
      mfd: ab8500-gpadc: Change to usleep_range() for greater resolution
      mfd: ab8500-debugfs: Provide a means for a user subscribe to IRQs
      mfd: ab8500-debugfs: Use NULL to initialise remaining NULL pointer
      mfd: ab8500-gpadc: Add runtime pm support
      mfd: ab8500-gpadc: Reduce conversion timeout
      mfd: ab8500-gpadc: Remove unused 'struct ab8500_gpadc'

Linus Walleij (1):
      mfd: ab8500-debugfs: Allow number of IRQs to be provided more dynamically

Mattias Wallin (1):
      mfd: ab8500-debugfs: Keep count of IRQs in debugfs

Mian Yousaf Kaukab (3):
      mfd: abx500-core: Provide an API to dump all ABx500 registers
      mfd: ab8500-debugfs: add debugfs node to read all registers
      mfd: ab8500-core: Allow the possibility to dump all AB8500 registers

Michel JAOUEN (1):
      mfd ab8500-gpadc: Introduce new AB version detection

Philippe Langlais (2):
      mfd: ab8500-debugfs: Set the USB charging current to 300mA for ABV3
      mfd: ab8500-gpadc: Use new ab8500_gpadc_get() with name parameter

carriere etienne (1):
      mfd: ab8500-debugfs: Formated access AB8500 registers from debugfs entry

 drivers/mfd/ab8500-core.c                 |    2 +
 drivers/mfd/ab8500-debugfs.c              | 1249 +++++++++++++++++++++++++++--
 drivers/mfd/ab8500-gpadc.c                |   90 ++-
 drivers/mfd/ab8500-sysctrl.c              |   92 +++
 drivers/mfd/abx500-core.c                 |   16 +
 include/linux/mfd/abx500.h                |    2 +
 include/linux/mfd/abx500/ab8500-sysctrl.h |    5 +
 include/linux/mfd/abx500/ab8500.h         |   12 +
 8 files changed, 1394 insertions(+), 74 deletions(-)

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

^ permalink raw reply

* [PATCH 1/2] ARM: dts: add support for some modules in imx6q sabresd
From: Zhang Quan-B13634 @ 2013-02-04  9:19 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20130203105830.GC26233@S2101-09.ap.freescale.net>

Hi Shawn,
Please see the comments inline, thanks!


Best Regards
Gary


>  -----Original Message-----
>  From: Shawn Guo [mailto:shawn.guo at linaro.org]
>  Sent: Sunday, February 03, 2013 18:59
>  To: Zhang Quan-B13634
>  Cc: linux at arm.linux.org.uk; linux-arm-kernel at lists.infradead.org
>  Subject: Re: [PATCH 1/2] ARM: dts: add support for some modules in imx6q
>  sabresd
>  
>  On Fri, Feb 01, 2013 at 02:46:38PM +0800, Gary Zhang wrote:
>  > add I2C/I2S/clk/fixed regulator/sound card and other related supports
>  > in imx6q sabresd
>  >
>  > Signed-off-by: Gary Zhang <b13634@freescale.com>
>  > ---
>  >  arch/arm/boot/dts/imx6q-sabresd.dts |   76
>  +++++++++++++++++++++++++++++++++++
>  >  arch/arm/boot/dts/imx6q.dtsi        |   23 ++++++++++
>  >  2 files changed, 99 insertions(+), 0 deletions(-)
>  >
>  > diff --git a/arch/arm/boot/dts/imx6q-sabresd.dts
>  > b/arch/arm/boot/dts/imx6q-sabresd.dts
>  > index a424025..383fcf0 100644
>  > --- a/arch/arm/boot/dts/imx6q-sabresd.dts
>  > +++ b/arch/arm/boot/dts/imx6q-sabresd.dts
>  > @@ -29,6 +29,10 @@
>  >  					pinctrl-0 = <&pinctrl_uart1_1>;
>  >  					status = "okay";
>  >  				};
>  > +				ssi2: ssi at 0202c000 {
>  
>  We generally have a blank line between nodes, so please follow the pattern.
[Gary-b13634] OK, I will correct it
>  
>  > +					fsl,mode = "i2s-slave";
>  > +					status = "okay";
>  > +				};
>  >  			};
>  >
>  >  			iomuxc at 020e0000 {
>  > @@ -73,6 +77,33 @@
>  >  				wp-gpios = <&gpio2 1 0>;
>  >  				status = "okay";
>  >  			};
>  > +
>  > +			audmux at 021d8000 {
>  > +				status = "okay";
>  
>  Nit: we usually have "status" be the last one in the property list.
[Gary-b13634] OK, I will correct it
>  
>  > +				pinctrl-names = "default";
>  > +				pinctrl-0 = <&pinctrl_audmux_2>;
>  > +			};
>  > +
>  > +			i2c at 021a0000 { /* I2C1 */
>  > +				status = "okay";
>  > +				clock-frequency = <100000>;
>  > +				pinctrl-names = "default";
>  > +				pinctrl-0 = <&pinctrl_i2c1_2>;
>  > +
>  > +				codec: wm8962 at 1a {
>  > +					compatible = "fsl,wm8962";
>  
>  This does not seem right, as wm8962 is not a codec produced by FSL.
>  I suspect you can have your driver work even without this compatible since it's
>  a I2C device.  If so, you can choose to simply drop it.
>  
>  Shawn
[Gary-b13634] this should be changed to "wlf, wm8962"; but it can't be dropped,
Or else codec driver will be failed to load.
>  
>  > +					reg = <0x1a>;
>  > +					clocks = <&clks 169>;
>  > +					DCVDD-supply = <&reg_1p8v>;
>  > +					DBVDD-supply = <&reg_1p8v>;
>  > +					AVDD-supply = <&reg_1p8v>;
>  > +					CPVDD-supply = <&reg_1p8v>;
>  > +					MICVDD-supply = <&reg_3p3v>;
>  > +					PLLVDD-supply = <&reg_1p8v>;
>  > +					SPKVDD1-supply = <&reg_4p2v>;
>  > +					SPKVDD2-supply = <&reg_4p2v>;
>  > +				};
>  > +			};
>  >  		};
>  >  	};
>  >
>  > @@ -91,4 +122,49 @@
>  >  			linux,code = <114>; /* KEY_VOLUMEDOWN */
>  >  		};
>  >  	};
>  > +	regulators {
>  > +		compatible = "simple-bus";
>  > +
>  > +		reg_1p8v: 1p8v {
>  > +			compatible = "regulator-fixed";
>  > +			regulator-name = "1P8V";
>  > +			regulator-min-microvolt = <1800000>;
>  > +			regulator-max-microvolt = <1800000>;
>  > +			regulator-always-on;
>  > +			enable-active-high;
>  > +		};
>  > +		reg_3p3v: 3p3v {
>  > +			compatible = "regulator-fixed";
>  > +			regulator-name = "3P3V";
>  > +			regulator-min-microvolt = <3300000>;
>  > +			regulator-max-microvolt = <3300000>;
>  > +			regulator-always-on;
>  > +			enable-active-high;
>  > +		};
>  > +		reg_4p2v: 4p2v {
>  > +			compatible = "regulator-fixed";
>  > +			regulator-name = "4P2V";
>  > +			regulator-min-microvolt = <4200000>;
>  > +			regulator-max-microvolt = <4200000>;
>  > +			gpio = <&gpio4 10 0>;
>  > +			regulator-always-on;
>  > +			regulator-boot-on;
>  > +			enable-active-high;
>  > +		};
>  > +	};
>  > +
>  > +	sound {
>  > +		compatible = "fsl,imx6q-sabresd-wm8962",
>  > +			     "fsl,imx-audio-wm8962";
>  > +		model = "imx6q-sabresd-wm8962";
>  > +		pinctrl-names = "default";
>  > +		pinctrl-0 = <&pinctrl_clko_1>;
>  > +		ssi-controller = <&ssi2>;
>  > +		audio-codec = <&codec>;
>  > +		audio-routing =
>  > +			"Headphone Jack", "HPOUTL",
>  > +			"Headphone Jack", "HPOUTR";
>  > +		mux-int-port = <2>;
>  > +		mux-ext-port = <3>;
>  > +	};
>  >  };
>  > diff --git a/arch/arm/boot/dts/imx6q.dtsi
>  > b/arch/arm/boot/dts/imx6q.dtsi index d6265ca..b612269 100644
>  > --- a/arch/arm/boot/dts/imx6q.dtsi
>  > +++ b/arch/arm/boot/dts/imx6q.dtsi
>  > @@ -582,6 +582,23 @@
>  >  							3    0x80000000	/*
>  MX6Q_PAD_SD2_DAT1__AUDMUX_AUD4_TXFS */
>  >  						>;
>  >  					};
>  > +
>  > +					pinctrl_audmux_2: audmux-2 {
>  > +						fsl,pins = <
>  > +							1117 0x80000000	/*
>  MX6Q_PAD_CSI0_DAT7__AUDMUX_AUD3_RXD */
>  > +							1093 0x80000000	/*
>  MX6Q_PAD_CSI0_DAT4__AUDMUX_AUD3_TXC */
>  > +							1101 0x80000000	/*
>  MX6Q_PAD_CSI0_DAT5__AUDMUX_AUD3_TXD */
>  > +							1109 0x80000000	/*
>  MX6Q_PAD_CSI0_DAT6__AUDMUX_AUD3_TXFS */
>  > +						>;
>  > +					};
>  > +				};
>  > +
>  > +				clko {
>  > +					pinctrl_clko_1: clkogrp-1 {
>  > +						fsl,pins = <
>  > +							953 0x130b0  /*
>  MX6Q_PAD_GPIO_0__CCM_CLKO */
>  > +						>;
>  > +					};
>  >  				};
>  >
>  >  				ecspi1 {
>  > @@ -670,6 +687,12 @@
>  >  							196 0x4001b8b1	/*
>  MX6Q_PAD_EIM_D28__I2C1_SDA */
>  >  						>;
>  >  					};
>  > +					pinctrl_i2c1_2: i2c1grp-2 {
>  > +						fsl,pins = <
>  > +							1125 0x4001b8b1	/*
>  MX6Q_PAD_CSI0_DAT8__I2C1_SDA */
>  > +							1133 0x4001b8b1 /*
>  MX6Q_PAD_CSI0_DAT9__I2C1_SCL */
>  > +						>;
>  > +					};
>  >  				};
>  >
>  >  				uart1 {
>  > --
>  > 1.7.0.4
>  >
>  >

^ permalink raw reply

* [PATCH 0/2] ARM: dts: omap3-overo: Add pwm-leds and audio support
From: Florian Vaussard @ 2013-02-04  9:14 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <5101273A.9090800@ti.com>

Hello Benoit,

On 01/24/2013 01:21 PM, Benoit Cousson wrote:
> + Peter who did the original PWM
>
> Hi Florian,
>
> On 01/23/2013 06:56 PM, Florian Vaussard wrote:
>> Hello Benoit,
>>
>> This patchset adds some new DT supports to the Overo products. The
>> first patch converts the PMIC LEDB output to use the pwm-leds,
>> newly merged in your branch for_3.9/dts. The second patch adds the
>> audio support.
>
> Excellent, that looks very good to me, but I'd like to get the
> feedback from Peter before merging it.
>

So a patch is being merged to handle triggers in the case of pwm leds [1].
When done, we will be able to add back the default trigger. Do you want
to wait on it to merge this series?

Regards,

Florian

[1] https://patchwork.kernel.org/patch/2056191/

^ permalink raw reply

* [PATCH 1/2] mtd: gpmi: set the Golois Field bit for mx6q's BCH
From: Huang Shijie @ 2013-02-04  9:11 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1359966688.13791.16.camel@sauron.fi.intel.com>

? 2013?02?04? 16:31, Artem Bityutskiy ??:
> On Fri, 2013-01-25 at 14:04 +0800, Huang Shijie wrote:
>> +#define BF_BCH_FLASH0LAYOUT0_GF(v, x)				\
>> +	((GPMI_IS_MX6Q(x)&&  ((v) == 14))			\
>> +		? (((1)<<  MX6Q_BP_BCH_FLASH0LAYOUT0_GF_13_14)	\
>> +			&  MX6Q_BM_BCH_FLASH0LAYOUT0_GF_13_14)	\
>> +		: 0						\
>> +	)
> Did you consider using static inline functions instead of macro
These macros are only used  when the different archs have different 
definitions about
the some registers. Yes, it's ok to use the functions to replace them.

I am not sure if there is still a need to add the similar macros, if it 
does, i can change to use
the inline functions.

thanks
Huang Shijie

^ permalink raw reply

* [RFC] i2c: Providing hooks for i2c multimaster bus arbitration.
From: Yuvaraj Kumar C D @ 2013-02-04  9:03 UTC (permalink / raw)
  To: linux-arm-kernel

This RFC patch is w.r.t multimaster bus arbitration which is already
being discussing in the mainline.
This patch provides hooks for the i2c multimaster bus arbitration
and to have the arbitration parameters.

Signed-off-by: Yuvaraj Kumar C D <yuvaraj.cd@samsung.com>
---
 drivers/i2c/i2c-core.c |   13 ++++++++++++-
 include/linux/i2c.h    |   12 ++++++++++++
 2 files changed, 24 insertions(+), 1 deletion(-)

diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index e388590..ed89fc8 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -1408,18 +1408,29 @@ int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
 				(msgs[ret].flags & I2C_M_RECV_LEN) ? "+" : "");
 		}
 #endif
+		if (adap->mm_arbit_algo) {
+			ret = adap->mm_arbit_algo->i2c_mm_bus_get(adap);
+			if (ret)
+				/* I2C bus under control of another master. */
+				return -EAGAIN;
+		}
 
 		if (in_atomic() || irqs_disabled()) {
 			ret = i2c_trylock_adapter(adap);
-			if (!ret)
+			if (!ret && adap->mm_arbit_algo) {
+				adap->mm_arbit_algo->i2c_mm_bus_release(adap);
+
 				/* I2C activity is ongoing. */
 				return -EAGAIN;
+			}
 		} else {
 			i2c_lock_adapter(adap);
 		}
 
 		ret = __i2c_transfer(adap, msgs, num);
 		i2c_unlock_adapter(adap);
+		if (adap->mm_arbit_algo)
+			adap->mm_arbit_algo->i2c_mm_bus_release(adap);
 
 		return ret;
 	} else {
diff --git a/include/linux/i2c.h b/include/linux/i2c.h
index d0c4db7..61fbfe3 100644
--- a/include/linux/i2c.h
+++ b/include/linux/i2c.h
@@ -371,6 +371,17 @@ struct i2c_algorithm {
 };
 
 /*
+ *This struct provides hooks for i2c multi-master arbitration needs.
+ */
+struct i2c_mm_arbitration {
+	void *arbitration_data;
+
+	/* Should return 0 if mastership could be successfully established */
+	int (*i2c_mm_bus_get)(struct i2c_adapter *adap);
+	void (*i2c_mm_bus_release)(struct i2c_adapter *adap);
+};
+
+/*
  * i2c_adapter is the structure used to identify a physical i2c bus along
  * with the access algorithms necessary to access it.
  */
@@ -393,6 +404,7 @@ struct i2c_adapter {
 
 	struct mutex userspace_clients_lock;
 	struct list_head userspace_clients;
+	struct i2c_mm_arbitration *mm_arbit_algo;
 };
 #define to_i2c_adapter(d) container_of(d, struct i2c_adapter, dev)
 
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH] ARM:omap2: using strlcpy instead of strncpy
From: Peter Ujfalusi @ 2013-02-04  9:00 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20130201224546.GG22517@atomide.com>

Hi Tony,

On 02/01/2013 11:45 PM, Tony Lindgren wrote:
> * Chen Gang <gang.chen@asianux.com> [130130 03:50]:
>>
>>   the fields must be null-terminated:
>>   the caller may use it as null-terminted string, next.
> 
> Added Peter to cc on this one too, it's best that he queues
> all the twl changes.

I can create a branch for you in our gitorious tree
(git://gitorious.org/omap-audio/linux-audio.git) for this patch. But I think
for now it would be best if you could take this via linux-omap (the file is
under arch/arm/mach-omap2 anyways)

Regards,
P?ter

> 
> Tony
>  
>> Signed-off-by: Chen Gang <gang.chen@asianux.com>
>> ---
>>  arch/arm/mach-omap2/twl-common.c |    3 ++-
>>  1 file changed, 2 insertions(+), 1 deletion(-)
>>
>> diff --git a/arch/arm/mach-omap2/twl-common.c b/arch/arm/mach-omap2/twl-common.c
>> index e49b40b..6a7aec6 100644
>> --- a/arch/arm/mach-omap2/twl-common.c
>> +++ b/arch/arm/mach-omap2/twl-common.c
>> @@ -23,6 +23,7 @@
>>  #include <linux/i2c.h>
>>  #include <linux/i2c/twl.h>
>>  #include <linux/gpio.h>
>> +#include <linux/string.h>
>>  #include <linux/regulator/machine.h>
>>  #include <linux/regulator/fixed.h>
>>  
>> @@ -56,7 +57,7 @@ void __init omap_pmic_init(int bus, u32 clkrate,
>>  			   struct twl4030_platform_data *pmic_data)
>>  {
>>  	omap_mux_init_signal("sys_nirq", OMAP_PIN_INPUT_PULLUP | OMAP_PIN_OFF_WAKEUPENABLE);
>> -	strncpy(pmic_i2c_board_info.type, pmic_type,
>> +	strlcpy(pmic_i2c_board_info.type, pmic_type,
>>  		sizeof(pmic_i2c_board_info.type));
>>  	pmic_i2c_board_info.irq = pmic_irq;
>>  	pmic_i2c_board_info.platform_data = pmic_data;
>> -- 
>> 1.7.10.4

^ permalink raw reply

* [PATCH v7 8/8] usb: chipidea: udc: fix the oops when plugs in usb cable after rmmod gadget
From: Peter Chen @ 2013-02-04  8:59 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1359968390-317-1-git-send-email-peter.chen@freescale.com>

When we rmmod gadget, the ci->driver needs to be cleared.
Otherwise, we plug in usb cable again, the driver will
consider gadget is there, in fact, it is removed.
Below is the oops this patch fixes.

root at freescale ~$ ci_hdrc ci_hdrc.0: Connected to host
Unable to handle kernel paging request at virtual address 7f01171c
pgd = 80004000
[7f01171c] *pgd=4fa1e811, *pte=00000000, *ppte=00000000
Internal error: Oops: 7 [#1] SMP ARM
Modules linked in: f_acm libcomposite u_serial [last unloaded: g_serial]
CPU: 0    Not tainted  (3.8.0-rc5+ #221)
	PC is at _gadget_stop_activity+0xbc/0x128
	LR is at ep_fifo_flush+0x68/0xa0
	pc : [<803634cc>]    lr : [<80363938>]    psr: 20000193
	sp : 806c7dc8  ip : 00000000  fp : 806c7de4
	r10: 00000000  r9 : 80710ea4  r8 : 00000000
	r7 : bf834094  r6 : bf834098  r5 : bf834010  r4 : bf8340a0
	r3 : 7f011708  r2 : 01940194  r1 : a0000193  r0 : bf834014
	Flags: nzCv  IRQs off  FIQs on  Mode SVC_32  ISA ARM  Segment kernel
	Control: 10c53c7d  Table: 4f06404a  DAC: 00000017
	Process swapper/0 (pid: 0, stack limit = 0x806c6238)
	Stack: (0x806c7dc8 to 0x806c8000)
	7dc0:                   bf834010 bf809950 bf834010 0000004b 806c7e44 806c7de8
	7de0: 80365400 8036341c 0000ec1c 00000000 0000ec1c 00000040 fff5ede0 bf834014
	7e00: 000a1220 00000000 0000002e ffffd958 806c7e3c 806c7e20 8004e870 bf834010
	7e20: bf809950 0000004b 0000004b 00000000 80710ea4 00000000 806c7e5c 806c7e48
	7e40: 80362888 80365154 bfb35180 bf809950 806c7e9c 806c7e60 8008111c 803627f4
	7e60: 00989680 00000000 bf809900 bf809964 812df8c0 bf809900 bf809950 806c3f2c
	7e80: 0000004b 00000000 412fc09a 00000000 806c7eb4 806c7ea0 80081368 800810b8
	7ea0: bf809900 bf809950 806c7ecc 806c7eb8 800843c8 8008130c 0000004b 806cf748
	7ec0: 806c7ee4 806c7ed0 80081088 8008432c 806c6000 806cf748 806c7f0c 806c7ee8
	7ee0: 8000fa44 8008105c f400010c 806ce974 806c7f30 f4000110 806d29e8 412fc09a
	7f00: 806c7f2c 806c7f10 80008584 8000f9f4 8000fbd0 60000013 ffffffff 806c7f64
	7f20: 806c7f84 806c7f30 8000eac0 80008554 00000000 00000000 0000000f 8001aea0
	7f40: 806c6000 80712a48 804f0040 00000000 806d29e8 412fc09a 00000000 806c7f84
	7f60: 806c7f88 806c7f78 8000fbcc 8000fbd0 60000013 ffffffff 806c7fac 806c7f88
	7f80: 8001015c 8000fb9c 806cf5b0 80712980 806a4528 8fffffff 1000406a 412fc09a
	7fa0: 806c7fbc 806c7fb0 804e5334 800100ac 806c7ff4 806c7fc0 80668940 804e52d4
	7fc0: ffffffff ffffffff 806684bc 00000000 00000000 806a4528 10c53c7d 806ce94c
	7fe0: 806a4524 806d29dc 00000000 806c7ff8 10008078 806686b0 00000000 00000000
	Backtrace:
	[<80363410>] (_gadget_stop_activity+0x0/0x128) from [<80365400>] (udc_irq+0x2b8/0xf38)
	 r7:0000004b r6:bf834010 r5:bf809950 r4:bf834010
	 [<80365148>] (udc_irq+0x0/0xf38) from [<80362888>] (ci_irq+0xa0/0xf4)
	[<803627e8>] (ci_irq+0x0/0xf4) from [<8008111c>] (handle_irq_event_percpu+0x70/0x254)
	 r5:bf809950 r4:bfb35180
	 [<800810ac>] (handle_irq_event_percpu+0x0/0x254) from [<80081368>] (handle_irq_event+0x68/0x88)
	[<80081300>] (handle_irq_event+0x0/0x88) from [<800843c8>] (handle_fasteoi_irq+0xa8/0x178)
	 r5:bf809950 r4:bf809900
	 [<80084320>] (handle_fasteoi_irq+0x0/0x178) from [<80081088>] (generic_handle_irq+0x38/0x40)
	 r5:806cf748 r4:0000004b
	 [<80081050>] (generic_handle_irq+0x0/0x40) from [<8000fa44>] (handle_IRQ+0x5c/0xbc)
	 r5:806cf748 r4:806c6000
	 [<8000f9e8>] (handle_IRQ+0x0/0xbc) from [<80008584>] (gic_handle_irq+0x3c/0x70)
	 r9:412fc09a r8:806d29e8 r7:f4000110 r6:806c7f30 r5:806ce974
	 r4:f400010c
	 [<80008548>] (gic_handle_irq+0x0/0x70) from [<8000eac0>] (__irq_svc+0x40/0x54)
	Exception stack(0x806c7f30 to 0x806c7f78)
	7f20:                                     00000000 00000000 0000000f 8001aea0
	7f40: 806c6000 80712a48 804f0040 00000000 806d29e8 412fc09a 00000000 806c7f84
	7f60: 806c7f88 806c7f78 8000fbcc 8000fbd0 60000013 ffffffff
	 r7:806c7f64 r6:ffffffff r5:60000013 r4:8000fbd0
	 [<8000fb90>] (default_idle+0x0/0x4c) from [<8001015c>] (cpu_idle+0xbc/0xf8)
	[<800100a0>] (cpu_idle+0x0/0xf8) from [<804e5334>] (rest_init+0x6c/0x84)
	 r9:412fc09a r8:1000406a r7:8fffffff r6:806a4528 r5:80712980
	 r4:806cf5b0
	 [<804e52c8>] (rest_init+0x0/0x84) from [<80668940>] (start_kernel+0x29c/0x2ec)
	[<806686a4>] (start_kernel+0x0/0x2ec) from [<10008078>] (0x10008078)
	Code: e12fff33 e5953200 e3530000 0a000002 (e5933014)
	---[ end trace aade28ad434062bd ]---
	Kernel panic - not syncing: 0xbf8bdfa8)
	df60: 00000000 00000000 0000000f 8001aea0 bf8bc000 80712a48 804f0040 00000000
	df80: 806d29e8 412fc09a 00000000 bf8bdfb4 bf8bdfb8 bf8bdfa8 8000fbcc 8000fbd0
	dfa0: 60000013 ffffffff
	 r7:bf8bdf94 r6:ffffffff r5:60000013 r4:8000fbd0
	 [<8000fb90>] (default_idle+0x0/0x4c) from [<8001015c>] (cpu_idle+0xbc/0xf8)
	[<800100a0>] (cpu_idle+0x0/0xf8) from [<804e7930>] (secondary_start_kernel+0x120/0x148)
	 r9:412fc09a r8:1000406a r7:80712d20 r6:10c03c7d r5:00000002
	 r4:806e2008
	 [<804e7810>] (secondary_start_kernel+0x0/0x148) from [<104e7148>] (0x104e7148)
	 r5:0000001f r4:4f8a806a
	 CPU3: stopping
	 Backtrace:
	 [<800132e8>] (dump_backtrace+0x0/0x114) from [<804ea684>] (dump_stack+0x20/0x24)
	 r7:00000000 r6:806c3f2c r5:806cf748 r4:80712d18
	 [<804ea664>] (dump_stack+0x0/0x24) from [<80014adc>] (handle_IPI+0x140/0x18c)
	[<8001499c>] (handle_IPI+0x0/0x18c) from [<800085b0>] (gic_handle_irq+0x68/0x70)
	 r9:412fc09a r8:806d29e8 r7:f4000110 r6:bf8bff60 r5:806ce974
	 r4:f400010c
	 [<80008548>] (gic_handle_irq+0x0/0x70) from [<8000eac0>] (__irq_svc+0x40/0x54)
	Exception stack(0xbf8bff60 to 0xbf8bffa8)
	ff60: 00000000 00000000 0000000f 8001aea0 bf8be000 80712a48 804f0040 00000000
	ff80: 806d29e8 412fc09a 00000000 bf8bffb4 bf8bffb8 bf8bffa8 8000fbcc 8000fbd0
	ffa0: 60000013 ffffffff
	 r7:bf8bff94 r6:ffffffff r5:60000013 r4:8000fbd0
	 [<8000fb90>] (default_idle+0x0/0x4c) from [<8001015c>] (cpu_idle+0xbc/0xf8)
	[<800100a0>] (cpu_idle+0x0/0xf8) from [<804e7930>] (secondary_start_kernel+0x120/0x148)
	 r9:412fc09a r8:1000406a r7:80712d20 r6:10c03c7d r5:00000003
	 r4:806e2008
	 [<804e7810>] (secondary_start_kernel+0x0/0x148) from [<104e7148>] (0x104e7148)
	 r5:0000001f r4:4f8a806a
	 CPU1: stopping
	 Backtrace:
	 [<800132e8>] (dump_backtrace+0x0/0x114) from [<804ea684>] (dump_stack+0x20/0x24)
	 r7:00000000 r6:806c3f2c r5:806cf748 r4:80712d18
	 [<804ea664>] (dump_stack+0x0/0x24) from [<80014adc>] (handle_IPI+0x140/0x18c)
	[<8001499c>] (handle_IPI+0x0/0x18c) from [<800085b0>] (gic_handle_irq+0x68/0x70)
	 r9:412fc09a r8:806d29e8 r7:f4000110 r6:bf8bbf60 r5:806ce974
	 r4:f400010c
	 [<80008548>] (gic_handle_irq+0x0/0x70) from [<8000eac0>] (__irq_svc+0x40/0x54)
	Exception stack(0xbf8bbf60 to 0xbf8bbfa8)
	bf60: 00000000 00000000 0000000f 8001aea0 bf8ba000 80712a48 804f0040 00000000
	bf80: 806d29e8 412fc09a 00000000 bf8bbfb4 bf8bbfb8 bf8bbfa8 8000fbcc 8000fbd0
	bfa0: 60000013 ffffffff
	 r7:bf8bbf94 r6:ffffffff r5:60000013 r4:8000fbd0
	 [<8000fb90>] (default_idle+0x0/0x4c) from [<8001015c>] (cpu_idle+0xbc/0xf8)
	[<800100a0>] (cpu_idle+0x0/0xf8) from [<804e7930>] (secondary_start_kernel+0x120/0x148)
	 r9:412fc09a r8:1000406a r7:80712d20 r6:10c03c7d r5:00000001
	 r4:806e2008

Signed-off-by: Peter Chen <peter.chen@freescale.com>
---
 drivers/usb/chipidea/udc.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
index b57b735..40820aa 100644
--- a/drivers/usb/chipidea/udc.c
+++ b/drivers/usb/chipidea/udc.c
@@ -1585,6 +1585,8 @@ static int ci13xxx_stop(struct usb_gadget *gadget,
 		_gadget_stop_activity(&ci->gadget);
 		spin_lock_irqsave(&ci->lock, flags);
 		pm_runtime_put(&ci->gadget.dev);
+	} else {
+		ci->driver = NULL;
 	}
 
 	spin_unlock_irqrestore(&ci->lock, flags);
-- 
1.7.0.4

^ permalink raw reply related

* [PATCH v7 7/8] usb: chipidea: imx: add internal vbus regulator control
From: Peter Chen @ 2013-02-04  8:59 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1359968390-317-1-git-send-email-peter.chen@freescale.com>

- For host, the vbus should always be on.
- For otg, the vbus is off defaultly, the vbus needs to be
turned on/off when usb role switches.

Signed-off-by: Peter Chen <peter.chen@freescale.com>
---
 drivers/usb/chipidea/ci.h          |    2 +
 drivers/usb/chipidea/ci13xxx_imx.c |   80 ++++++++++++++++++++++++++++--------
 2 files changed, 64 insertions(+), 18 deletions(-)

diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h
index 3ebe87a..bd78078 100644
--- a/drivers/usb/chipidea/ci.h
+++ b/drivers/usb/chipidea/ci.h
@@ -131,6 +131,7 @@ struct hw_bank {
  * @hcd: pointer to usb_hcd for ehci host driver
  * @otg: for otg support
  * @events: events for otg, and handled at ci_role_work
+ * @reg_vbus: used to control internal vbus regulator
  */
 struct ci13xxx {
 	struct device			*dev;
@@ -170,6 +171,7 @@ struct ci13xxx {
 	struct usb_otg      		otg;
 	bool				id_event;
 	bool				b_sess_valid_event;
+	struct regulator		*reg_vbus;
 };
 
 static inline struct ci_role_driver *ci_role(struct ci13xxx *ci)
diff --git a/drivers/usb/chipidea/ci13xxx_imx.c b/drivers/usb/chipidea/ci13xxx_imx.c
index 3b91ff4..4c9df98 100644
--- a/drivers/usb/chipidea/ci13xxx_imx.c
+++ b/drivers/usb/chipidea/ci13xxx_imx.c
@@ -88,14 +88,47 @@ EXPORT_SYMBOL_GPL(usbmisc_get_init_data);
 static struct ci13xxx_platform_data ci13xxx_imx_platdata  = {
 	.name			= "ci13xxx_imx",
 	.flags			= CI13XXX_REQUIRE_TRANSCEIVER |
-				  CI13XXX_DISABLE_STREAMING,
+				  CI13XXX_DISABLE_STREAMING |
+				  CI13XXX_REGS_SHARED,
 	.capoffset		= DEF_CAPOFFSET,
 };
 
+static int ci13xxx_otg_set_vbus(struct usb_otg *otg, bool enabled)
+{
+	struct ci13xxx	*ci = container_of(otg, struct ci13xxx, otg);
+	struct regulator *reg_vbus = ci->reg_vbus;
+	int ret;
+
+	WARN_ON(!reg_vbus);
+
+	if (reg_vbus) {
+		if (enabled) {
+			ret = regulator_enable(reg_vbus);
+			if (ret) {
+				dev_err(ci->dev,
+				"Failed to enable vbus regulator, ret=%d\n",
+				ret);
+				return ret;
+			}
+		} else {
+			ret = regulator_disable(reg_vbus);
+			if (ret) {
+				dev_err(ci->dev,
+				"Failed to disable vbus regulator, ret=%d\n",
+				ret);
+				return ret;
+			}
+		}
+	}
+
+	return 0;
+}
+
 static int ci13xxx_imx_probe(struct platform_device *pdev)
 {
 	struct ci13xxx_imx_data *data;
 	struct platform_device *plat_ci, *phy_pdev;
+	struct ci13xxx	*ci;
 	struct device_node *phy_np;
 	struct resource *res;
 	struct regulator *reg_vbus;
@@ -152,20 +185,11 @@ static int ci13xxx_imx_probe(struct platform_device *pdev)
 		}
 	}
 
-	/* we only support host now, so enable vbus here */
 	reg_vbus = devm_regulator_get(&pdev->dev, "vbus");
-	if (!IS_ERR(reg_vbus)) {
-		ret = regulator_enable(reg_vbus);
-		if (ret) {
-			dev_err(&pdev->dev,
-				"Failed to enable vbus regulator, err=%d\n",
-				ret);
-			goto put_np;
-		}
+	if (!IS_ERR(reg_vbus))
 		data->reg_vbus = reg_vbus;
-	} else {
+	else
 		reg_vbus = NULL;
-	}
 
 	ci13xxx_imx_platdata.phy = data->phy;
 
@@ -175,7 +199,7 @@ static int ci13xxx_imx_probe(struct platform_device *pdev)
 		if (!pdev->dev.dma_mask) {
 			ret = -ENOMEM;
 			dev_err(&pdev->dev, "Failed to alloc dma_mask!\n");
-			goto err;
+			goto put_np;
 		}
 		*pdev->dev.dma_mask = DMA_BIT_MASK(32);
 		dma_set_coherent_mask(&pdev->dev, *pdev->dev.dma_mask);
@@ -186,7 +210,7 @@ static int ci13xxx_imx_probe(struct platform_device *pdev)
 		if (ret) {
 			dev_err(&pdev->dev,
 				"usbmisc init failed, ret=%d\n", ret);
-			goto err;
+			goto put_np;
 		}
 	}
 
@@ -198,24 +222,44 @@ static int ci13xxx_imx_probe(struct platform_device *pdev)
 		dev_err(&pdev->dev,
 			"Can't register ci_hdrc platform device, err=%d\n",
 			ret);
-		goto err;
+		goto put_np;
 	}
 
 	data->ci_pdev = plat_ci;
 	platform_set_drvdata(pdev, data);
 
+	ci = platform_get_drvdata(plat_ci);
+	/*
+	 * Internal vbus on/off policy
+	 * - Always on for host only function
+	 * - Always off for gadget only function
+	 * - call otg.set_vbus to control on/off according usb role
+	 */
+
+	if (ci->roles[CI_ROLE_HOST] && !ci->roles[CI_ROLE_GADGET]
+			&& reg_vbus) {
+		ret = regulator_enable(reg_vbus);
+		if (ret) {
+			dev_err(&pdev->dev,
+				"Failed to enable vbus regulator, ret=%d\n",
+				ret);
+			goto put_np;
+		}
+	} else if (ci->is_otg) {
+		ci->otg.set_vbus = ci13xxx_otg_set_vbus;
+		ci->reg_vbus = data->reg_vbus;
+	}
+
 	pm_runtime_no_callbacks(&pdev->dev);
 	pm_runtime_enable(&pdev->dev);
 
 	return 0;
 
-err:
-	if (reg_vbus)
-		regulator_disable(reg_vbus);
 put_np:
 	if (phy_np)
 		of_node_put(phy_np);
 	clk_disable_unprepare(data->clk);
+
 	return ret;
 }
 
-- 
1.7.0.4

^ permalink raw reply related

* [PATCH v7 6/8] usb: chipidea: udc: retire the flag CI13_PULLUP_ON_VBUS
From: Peter Chen @ 2013-02-04  8:59 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1359968390-317-1-git-send-email-peter.chen@freescale.com>

(change CI13XXX to CI13 to avoid junk email check)
Now, we have handled vbus session in core driver when the
vbus interrupt occurs, so our pullup operations are all
according to vbus.
Of cource, the software can still call .pullup when device connects
to host if it wants to connect/disconnect with host.

Signed-off-by: Peter Chen <peter.chen@freescale.com>
---
 drivers/usb/chipidea/ci13xxx_imx.c |    1 -
 drivers/usb/chipidea/ci13xxx_msm.c |    1 -
 drivers/usb/chipidea/udc.c         |   23 ++++++++---------------
 include/linux/usb/chipidea.h       |    1 -
 4 files changed, 8 insertions(+), 18 deletions(-)

diff --git a/drivers/usb/chipidea/ci13xxx_imx.c b/drivers/usb/chipidea/ci13xxx_imx.c
index 8c29122..3b91ff4 100644
--- a/drivers/usb/chipidea/ci13xxx_imx.c
+++ b/drivers/usb/chipidea/ci13xxx_imx.c
@@ -88,7 +88,6 @@ EXPORT_SYMBOL_GPL(usbmisc_get_init_data);
 static struct ci13xxx_platform_data ci13xxx_imx_platdata  = {
 	.name			= "ci13xxx_imx",
 	.flags			= CI13XXX_REQUIRE_TRANSCEIVER |
-				  CI13XXX_PULLUP_ON_VBUS |
 				  CI13XXX_DISABLE_STREAMING,
 	.capoffset		= DEF_CAPOFFSET,
 };
diff --git a/drivers/usb/chipidea/ci13xxx_msm.c b/drivers/usb/chipidea/ci13xxx_msm.c
index 7d16681..5755ee8 100644
--- a/drivers/usb/chipidea/ci13xxx_msm.c
+++ b/drivers/usb/chipidea/ci13xxx_msm.c
@@ -49,7 +49,6 @@ static struct ci13xxx_platform_data ci13xxx_msm_platdata = {
 	.name			= "ci13xxx_msm",
 	.flags			= CI13XXX_REGS_SHARED |
 				  CI13XXX_REQUIRE_TRANSCEIVER |
-				  CI13XXX_PULLUP_ON_VBUS |
 				  CI13XXX_DISABLE_STREAMING,
 
 	.notify_event		= ci13xxx_msm_notify_event,
diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
index 597ae64..b57b735 100644
--- a/drivers/usb/chipidea/udc.c
+++ b/drivers/usb/chipidea/udc.c
@@ -1360,9 +1360,6 @@ static int ci13xxx_vbus_session(struct usb_gadget *_gadget, int is_active)
 	unsigned long flags;
 	int gadget_ready = 0;
 
-	if (!(ci->platdata->flags & CI13XXX_PULLUP_ON_VBUS))
-		return -EOPNOTSUPP;
-
 	spin_lock_irqsave(&ci->lock, flags);
 	ci->vbus_active = is_active;
 	if (ci->driver)
@@ -1426,8 +1423,7 @@ static int ci13xxx_pullup(struct usb_gadget *_gadget, int is_on)
 {
 	struct ci13xxx *ci = container_of(_gadget, struct ci13xxx, gadget);
 
-	if ((ci->platdata->flags & CI13XXX_PULLUP_ON_VBUS) &&
-			!ci->vbus_active)
+	if (!ci->vbus_active)
 		return -ENOTSUPP;
 
 	if (is_on)
@@ -1551,14 +1547,12 @@ static int ci13xxx_start(struct usb_gadget *gadget,
 
 	ci->driver = driver;
 	pm_runtime_get_sync(&ci->gadget.dev);
-	if (ci->platdata->flags & CI13XXX_PULLUP_ON_VBUS) {
-		if (ci->vbus_active) {
-			if (ci->platdata->flags & CI13XXX_REGS_SHARED)
-				hw_device_reset(ci, USBMODE_CM_DC);
-		} else {
-			pm_runtime_put_sync(&ci->gadget.dev);
-			goto done;
-		}
+	if (ci->vbus_active) {
+		if (ci->platdata->flags & CI13XXX_REGS_SHARED)
+			hw_device_reset(ci, USBMODE_CM_DC);
+	} else {
+		pm_runtime_put_sync(&ci->gadget.dev);
+		goto done;
 	}
 
 	retval = hw_device_state(ci, ci->ep0out->qh.dma);
@@ -1581,8 +1575,7 @@ static int ci13xxx_stop(struct usb_gadget *gadget,
 
 	spin_lock_irqsave(&ci->lock, flags);
 
-	if (!(ci->platdata->flags & CI13XXX_PULLUP_ON_VBUS) ||
-			ci->vbus_active) {
+	if (ci->vbus_active) {
 		hw_device_state(ci, 0);
 		if (ci->platdata->notify_event)
 			ci->platdata->notify_event(ci,
diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h
index 544825d..37821b3 100644
--- a/include/linux/usb/chipidea.h
+++ b/include/linux/usb/chipidea.h
@@ -17,7 +17,6 @@ struct ci13xxx_platform_data {
 	unsigned long	 flags;
 #define CI13XXX_REGS_SHARED		BIT(0)
 #define CI13XXX_REQUIRE_TRANSCEIVER	BIT(1)
-#define CI13XXX_PULLUP_ON_VBUS		BIT(2)
 #define CI13XXX_DISABLE_STREAMING	BIT(3)
 
 #define CI13XXX_CONTROLLER_RESET_EVENT		0
-- 
1.7.0.4

^ permalink raw reply related

* [PATCH v7 5/8] usb: chipidea: udc: add pullup/pulldown dp at hw_device_state
From: Peter Chen @ 2013-02-04  8:59 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1359968390-317-1-git-send-email-peter.chen@freescale.com>

- During the connect/disconnect host, we need to pullup
and pulldown dp
- Make sure the dp is not pullup until the vbus is on when
flag CI13XXX_PULLUP_ON_VBUS is set
- Using hw_device_state when set run/stop bit

Signed-off-by: Peter Chen <peter.chen@freescale.com>
---
 drivers/usb/chipidea/udc.c |   10 ++++++++--
 1 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
index e82dae4..597ae64 100644
--- a/drivers/usb/chipidea/udc.c
+++ b/drivers/usb/chipidea/udc.c
@@ -91,8 +91,10 @@ static int hw_device_state(struct ci13xxx *ci, u32 dma)
 		/* interrupt, error, port change, reset, sleep/suspend */
 		hw_write(ci, OP_USBINTR, ~0,
 			     USBi_UI|USBi_UEI|USBi_PCI|USBi_URI|USBi_SLI);
+		hw_write(ci, OP_USBCMD, USBCMD_RS, USBCMD_RS);
 	} else {
 		hw_write(ci, OP_USBINTR, ~0, 0);
+		hw_write(ci, OP_USBCMD, USBCMD_RS, 0);
 	}
 	return 0;
 }
@@ -1424,10 +1426,14 @@ static int ci13xxx_pullup(struct usb_gadget *_gadget, int is_on)
 {
 	struct ci13xxx *ci = container_of(_gadget, struct ci13xxx, gadget);
 
+	if ((ci->platdata->flags & CI13XXX_PULLUP_ON_VBUS) &&
+			!ci->vbus_active)
+		return -ENOTSUPP;
+
 	if (is_on)
-		hw_write(ci, OP_USBCMD, USBCMD_RS, USBCMD_RS);
+		hw_device_state(ci, ci->ep0out->qh.dma);
 	else
-		hw_write(ci, OP_USBCMD, USBCMD_RS, 0);
+		hw_device_state(ci, 0);
 
 	return 0;
 }
-- 
1.7.0.4

^ permalink raw reply related

* [PATCH v7 4/8] usb: chipidea: consolidate kinds of APIs for both roles
From: Peter Chen @ 2013-02-04  8:59 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1359968390-317-1-git-send-email-peter.chen@freescale.com>

- Create/destroy the gadget at udc's init and destory function
- start/stop API are used at otg id switch and probe routine
- Defer some gadget operations at ci's delayed work queue

Signed-off-by: Peter Chen <peter.chen@freescale.com>
---
 drivers/usb/chipidea/ci.h   |    1 -
 drivers/usb/chipidea/core.c |   78 +++++++++++++++++--------------------------
 drivers/usb/chipidea/host.c |    6 +++
 drivers/usb/chipidea/host.h |    4 ++-
 drivers/usb/chipidea/udc.c  |   37 +++++++++++++++-----
 drivers/usb/chipidea/udc.h  |    4 ++-
 6 files changed, 71 insertions(+), 59 deletions(-)

diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h
index 325d790..3ebe87a 100644
--- a/drivers/usb/chipidea/ci.h
+++ b/drivers/usb/chipidea/ci.h
@@ -205,7 +205,6 @@ static inline void ci_role_stop(struct ci13xxx *ci)
 
 	ci->roles[role]->stop(ci);
 }
-
 /******************************************************************************
  * REGISTERS
  *****************************************************************************/
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index 8857b2c..dd1fd87 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -323,27 +323,16 @@ static void ci_handle_id_switch(struct ci13xxx *ci)
 			ci_role(ci)->name, ci->roles[role]->name);
 
 		/* 1. Finish the current role */
-		if (ci->role == CI_ROLE_GADGET) {
-			usb_gadget_vbus_disconnect(&ci->gadget);
-			/* host doesn't care B_SESSION_VALID event */
-			ci_clear_otg_interrupt(ci, OTGSC_BSVIS);
-			ci_disable_otg_interrupt(ci, OTGSC_BSVIE);
-			ci->role = CI_ROLE_END;
-			/* reset controller */
-			hw_device_reset(ci, USBMODE_CM_IDLE);
-		} else if (ci->role == CI_ROLE_HOST) {
-			ci_role_stop(ci);
-			/* reset controller */
-			hw_device_reset(ci, USBMODE_CM_IDLE);
-		}
+		ci_role_stop(ci);
+		hw_device_reset(ci, USBMODE_CM_IDLE);
 
 		/* 2. Turn on/off vbus according to coming role */
-		if (ci_otg_role(ci) == CI_ROLE_GADGET) {
+		if (role == CI_ROLE_GADGET) {
 			otg_set_vbus(&ci->otg, false);
 			/* wait vbus lower than OTGSC_BSV */
 			hw_wait_reg(ci, OP_OTGSC, OTGSC_BSV, 0,
 					CI_VBUS_STABLE_TIMEOUT);
-		} else if (ci_otg_role(ci) == CI_ROLE_HOST) {
+		} else if (role == CI_ROLE_HOST) {
 			otg_set_vbus(&ci->otg, true);
 			/* wait vbus higher than OTGSC_AVV */
 			hw_wait_reg(ci, OP_OTGSC, OTGSC_AVV, OTGSC_AVV,
@@ -351,13 +340,7 @@ static void ci_handle_id_switch(struct ci13xxx *ci)
 		}
 
 		/* 3. Begin the new role */
-		if (ci_otg_role(ci) == CI_ROLE_GADGET) {
-			ci->role = role;
-			ci_clear_otg_interrupt(ci, OTGSC_BSVIS);
-			ci_enable_otg_interrupt(ci, OTGSC_BSVIE);
-		} else if (ci_otg_role(ci) == CI_ROLE_HOST) {
-			ci_role_start(ci, role);
-		}
+		ci_role_start(ci, role);
 	}
 }
 
@@ -396,8 +379,24 @@ static void ci_delayed_work(struct work_struct *work)
 	struct delayed_work *dwork = to_delayed_work(work);
 	struct ci13xxx *ci = container_of(dwork, struct ci13xxx, dwork);
 
-	otg_set_vbus(&ci->otg, true);
+	if (ci->role == CI_ROLE_GADGET) {
+		/*
+		 * if it is device mode:
+		 * - Enable vbus detect
+		 * - If it has already connected to host, notify udc
+		 */
+		ci_enable_otg_interrupt(ci, OTGSC_BSVIE);
+		ci_handle_vbus_change(ci);
+	} else if (ci->is_otg && (ci->role == CI_ROLE_HOST)) {
+		/* USB Device at the MicroB to A cable */
+		otg_set_vbus(&ci->otg, true);
+	}
+}
 
+static inline void ci_role_destroy(struct ci13xxx *ci)
+{
+	ci_hdrc_gadget_destroy(ci);
+	ci_hdrc_host_destroy(ci);
 }
 
 static ssize_t show_role(struct device *dev, struct device_attribute *attr,
@@ -594,7 +593,7 @@ static int ci_hdrc_probe(struct platform_device *pdev)
 
 	ret = ci_hdrc_gadget_init(ci);
 	if (ret)
-		dev_info(dev, "doesn't support gadget\n");
+		dev_info(dev, "doesn't support gadget, ret=%d\n", ret);
 
 	if (!ci->roles[CI_ROLE_HOST] && !ci->roles[CI_ROLE_GADGET]) {
 		dev_err(dev, "no supported roles\n");
@@ -616,23 +615,9 @@ static int ci_hdrc_probe(struct platform_device *pdev)
 			: CI_ROLE_GADGET;
 	}
 
-	ret = ci_role_start(ci, ci->role);
-	if (ret) {
-		dev_err(dev, "can't start %s role\n", ci_role(ci)->name);
-		ret = -ENODEV;
-		goto rm_wq;
-	}
+	ci_role_start(ci, ci->role);
 
 	otgsc = hw_read(ci, OP_OTGSC, ~0);
-	/*
-	 * if it is device mode:
-	 * - Enable vbus detect
-	 * - If it has already connected to host, notify udc
-	 */
-	if (ci->role == CI_ROLE_GADGET) {
-		ci_enable_otg_interrupt(ci, OTGSC_BSVIE);
-		ci_handle_vbus_change(ci);
-	}
 
 	platform_set_drvdata(pdev, ci);
 	ret = request_irq(ci->irq, ci_irq, IRQF_SHARED, ci->platdata->name,
@@ -642,18 +627,17 @@ static int ci_hdrc_probe(struct platform_device *pdev)
 
 	ret = device_create_file(dev, &dev_attr_role);
 	if (ret)
-		goto rm_attr;
+		goto free_irq;
 
-	/* Handle the situation that usb device at the MicroB to A cable */
-	if (ci->is_otg && !(otgsc & OTGSC_ID))
-		queue_delayed_work(ci->wq, &ci->dwork, msecs_to_jiffies(500));
+	/* Defer some operations */
+	queue_delayed_work(ci->wq, &ci->dwork, msecs_to_jiffies(200));
 
 	return ret;
 
-rm_attr:
-	device_remove_file(dev, &dev_attr_role);
+free_irq:
+	free_irq(ci->irq, ci);
 stop:
-	ci_role_stop(ci);
+	ci_role_destroy(ci);
 rm_wq:
 	flush_workqueue(ci->wq);
 	destroy_workqueue(ci->wq);
@@ -669,7 +653,7 @@ static int ci_hdrc_remove(struct platform_device *pdev)
 	destroy_workqueue(ci->wq);
 	device_remove_file(ci->dev, &dev_attr_role);
 	free_irq(ci->irq, ci);
-	ci_role_stop(ci);
+	ci_role_destroy(ci);
 
 	return 0;
 }
diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c
index 8e9d312..ead3158 100644
--- a/drivers/usb/chipidea/host.c
+++ b/drivers/usb/chipidea/host.c
@@ -105,3 +105,9 @@ int ci_hdrc_host_init(struct ci13xxx *ci)
 
 	return 0;
 }
+
+void ci_hdrc_host_destroy(struct ci13xxx *ci)
+{
+	if (ci->role == CI_ROLE_HOST)
+		host_stop(ci);
+}
diff --git a/drivers/usb/chipidea/host.h b/drivers/usb/chipidea/host.h
index 761fb1f..5fd03a4 100644
--- a/drivers/usb/chipidea/host.h
+++ b/drivers/usb/chipidea/host.h
@@ -4,13 +4,15 @@
 #ifdef CONFIG_USB_CHIPIDEA_HOST
 
 int ci_hdrc_host_init(struct ci13xxx *ci);
-
+void ci_hdrc_host_destroy(struct ci13xxx *ci);
 #else
 
 static inline int ci_hdrc_host_init(struct ci13xxx *ci)
 {
 	return -ENXIO;
 }
+static void ci_hdrc_host_destroy(struct ci13xxx *ci)
+{}
 
 #endif
 
diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
index 83e54bb..e82dae4 100644
--- a/drivers/usb/chipidea/udc.c
+++ b/drivers/usb/chipidea/udc.c
@@ -31,6 +31,7 @@
 
 #include "ci.h"
 #include "udc.h"
+#include "otg.h"
 #include "bits.h"
 #include "debug.h"
 
@@ -1743,7 +1744,12 @@ static int udc_start(struct ci13xxx *ci)
 	if (!IS_ERR_OR_NULL(ci->transceiver)) {
 		retval = otg_set_peripheral(ci->transceiver->otg,
 						&ci->gadget);
-		if (retval)
+		/* 
+		 * If we implement all USB functions using chipidea drivers,
+		 * it doesn't need to call above API, meanwhile, if we only
+		 * use gadget function, calling above API is useless.
+		 */
+		if (retval && retval != -ENOTSUPP)
 			goto remove_dbg;
 	}
 
@@ -1780,12 +1786,27 @@ free_qh_pool:
 	return retval;
 }
 
+static int udc_id_switch_for_device(struct ci13xxx *ci)
+{
+	ci_clear_otg_interrupt(ci, OTGSC_BSVIS);
+	ci_enable_otg_interrupt(ci, OTGSC_BSVIE);
+
+	return 0;
+}
+
+static void udc_id_switch_for_host(struct ci13xxx *ci)
+{
+	/* host doesn't care B_SESSION_VALID event */
+	ci_clear_otg_interrupt(ci, OTGSC_BSVIS);
+	ci_disable_otg_interrupt(ci, OTGSC_BSVIE);
+}
+
 /**
- * udc_remove: parent remove must call this to remove UDC
+ * ci_hdrc_gadget_destroy: parent remove must call this to remove UDC
  *
  * No interrupts active, the IRQ has been released
  */
-static void udc_stop(struct ci13xxx *ci)
+void ci_hdrc_gadget_destroy(struct ci13xxx *ci)
 {
 	if (ci == NULL)
 		return;
@@ -1804,15 +1825,13 @@ static void udc_stop(struct ci13xxx *ci)
 	}
 	dbg_remove_files(&ci->gadget.dev);
 	device_unregister(&ci->gadget.dev);
-	/* my kobject is dynamic, I swear! */
-	memset(&ci->gadget, 0, sizeof(ci->gadget));
 }
 
 /**
  * ci_hdrc_gadget_init - initialize device related bits
  * ci: the controller
  *
- * This function enables the gadget role, if the device is "device capable".
+ * This function initializes gadget, if the device is "device capable".
  */
 int ci_hdrc_gadget_init(struct ci13xxx *ci)
 {
@@ -1825,11 +1844,11 @@ int ci_hdrc_gadget_init(struct ci13xxx *ci)
 	if (!rdrv)
 		return -ENOMEM;
 
-	rdrv->start	= udc_start;
-	rdrv->stop	= udc_stop;
+	rdrv->start	= udc_id_switch_for_device;
+	rdrv->stop	= udc_id_switch_for_host;
 	rdrv->irq	= udc_irq;
 	rdrv->name	= "gadget";
 	ci->roles[CI_ROLE_GADGET] = rdrv;
 
-	return 0;
+	return udc_start(ci);
 }
diff --git a/drivers/usb/chipidea/udc.h b/drivers/usb/chipidea/udc.h
index 4ff2384..6c42d49 100644
--- a/drivers/usb/chipidea/udc.h
+++ b/drivers/usb/chipidea/udc.h
@@ -80,6 +80,7 @@ struct ci13xxx_req {
 #ifdef CONFIG_USB_CHIPIDEA_UDC
 
 int ci_hdrc_gadget_init(struct ci13xxx *ci);
+void ci_hdrc_gadget_destroy(struct ci13xxx *ci);
 
 #else
 
@@ -87,7 +88,8 @@ static inline int ci_hdrc_gadget_init(struct ci13xxx *ci)
 {
 	return -ENXIO;
 }
-
+static void ci_hdrc_gadget_destroy(struct ci13xxx *ci)
+{}
 #endif
 
 #endif /* __DRIVERS_USB_CHIPIDEA_UDC_H */
-- 
1.7.0.4

^ permalink raw reply related

* [PATCH v7 3/8] usb: chipidea: add otg id switch and vbus connect/disconnect detect
From: Peter Chen @ 2013-02-04  8:59 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1359968390-317-1-git-send-email-peter.chen@freescale.com>

The main design flow is the same with msm otg driver, that is the id and
vbus interrupt are handled at core driver, others are handled by
individual drivers.

- At former design, when switch usb role from device->host, it will call
udc_stop, it will remove the gadget driver, so when switch role
from host->device, it can't add gadget driver any more.
At new design, when role switch occurs, the gadget just calls
usb_gadget_vbus_disconnect/usb_gadget_vbus_connect as well as
reset controller, it will not free any device/gadget structure

- Add vbus connect and disconnect to core interrupt handler, it can
notify udc driver by calling usb_gadget_vbus_disconnect
/usb_gadget_vbus_connect.

Signed-off-by: Peter Chen <peter.chen@freescale.com>
---
 drivers/usb/chipidea/bits.h |   10 +++
 drivers/usb/chipidea/ci.h   |    6 ++
 drivers/usb/chipidea/core.c |  182 +++++++++++++++++++++++++++++++++++++++----
 drivers/usb/chipidea/otg.c  |   28 ++++---
 drivers/usb/chipidea/otg.h  |    3 +
 drivers/usb/chipidea/udc.c  |    2 +
 6 files changed, 206 insertions(+), 25 deletions(-)

diff --git a/drivers/usb/chipidea/bits.h b/drivers/usb/chipidea/bits.h
index 050de85..ba9c6ef 100644
--- a/drivers/usb/chipidea/bits.h
+++ b/drivers/usb/chipidea/bits.h
@@ -65,11 +65,21 @@
 #define OTGSC_ASVIS	      BIT(18)
 #define OTGSC_BSVIS	      BIT(19)
 #define OTGSC_BSEIS	      BIT(20)
+#define OTGSC_1MSIS	      BIT(21)
+#define OTGSC_DPIS	      BIT(22)
 #define OTGSC_IDIE	      BIT(24)
 #define OTGSC_AVVIE	      BIT(25)
 #define OTGSC_ASVIE	      BIT(26)
 #define OTGSC_BSVIE	      BIT(27)
 #define OTGSC_BSEIE	      BIT(28)
+#define OTGSC_1MSIE	      BIT(29)
+#define OTGSC_DPIE	      BIT(30)
+#define OTGSC_INT_EN_BITS	(OTGSC_IDIE | OTGSC_AVVIE | OTGSC_ASVIE \
+				| OTGSC_BSVIE | OTGSC_BSEIE | OTGSC_1MSIE \
+				| OTGSC_DPIE)
+#define OTGSC_INT_STATUS_BITS	(OTGSC_IDIS | OTGSC_AVVIS | OTGSC_ASVIS	\
+				| OTGSC_BSVIS | OTGSC_BSEIS | OTGSC_1MSIS \
+				| OTGSC_DPIS)
 
 /* USBMODE */
 #define USBMODE_CM            (0x03UL <<  0)
diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h
index 697e369..325d790 100644
--- a/drivers/usb/chipidea/ci.h
+++ b/drivers/usb/chipidea/ci.h
@@ -130,6 +130,7 @@ struct hw_bank {
  * @transceiver: pointer to USB PHY, if any
  * @hcd: pointer to usb_hcd for ehci host driver
  * @otg: for otg support
+ * @events: events for otg, and handled@ci_role_work
  */
 struct ci13xxx {
 	struct device			*dev;
@@ -140,6 +141,7 @@ struct ci13xxx {
 	enum ci_role			role;
 	bool				is_otg;
 	struct work_struct		work;
+	struct delayed_work		dwork;
 	struct workqueue_struct		*wq;
 
 	struct dma_pool			*qh_pool;
@@ -166,6 +168,8 @@ struct ci13xxx {
 	struct usb_phy			*transceiver;
 	struct usb_hcd			*hcd;
 	struct usb_otg      		otg;
+	bool				id_event;
+	bool				b_sess_valid_event;
 };
 
 static inline struct ci_role_driver *ci_role(struct ci13xxx *ci)
@@ -314,4 +318,6 @@ int hw_port_test_set(struct ci13xxx *ci, u8 mode);
 
 u8 hw_port_test_get(struct ci13xxx *ci);
 
+void ci_handle_vbus_change(struct ci13xxx *ci);
+
 #endif	/* __DRIVERS_USB_CHIPIDEA_CI_H */
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index 57cae1f..8857b2c 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -73,6 +73,7 @@
 #include "bits.h"
 #include "host.h"
 #include "debug.h"
+#include "otg.h"
 
 /* Controller register map */
 static uintptr_t ci_regs_nolpm[] = {
@@ -199,6 +200,14 @@ static int hw_device_init(struct ci13xxx *ci, void __iomem *base)
 	if (ci->hw_ep_max > ENDPT_MAX)
 		return -ENODEV;
 
+	/* Disable all interrupts bits */
+	hw_write(ci, OP_USBINTR, 0xffffffff, 0);
+	ci_disable_otg_interrupt(ci, OTGSC_INT_EN_BITS);
+
+	/* Clear all interrupts status bits*/
+	hw_write(ci, OP_USBSTS, 0xffffffff, 0xffffffff);
+	ci_clear_otg_interrupt(ci, OTGSC_INT_STATUS_BITS);
+
 	dev_dbg(ci->dev, "ChipIdea HDRC found, lpm: %d; cap: %p op: %p\n",
 		ci->hw_bank.lpm, ci->hw_bank.cap, ci->hw_bank.op);
 
@@ -265,24 +274,132 @@ static enum ci_role ci_otg_role(struct ci13xxx *ci)
 }
 
 /**
- * ci_role_work - perform role changing based on ID pin
- * @work: work struct
+ * hw_wait_reg: wait the register value
+ *
+ * Sometimes, it needs to wait register value before going on.
+ * Eg, when switch to device mode, the vbus value should be lower
+ * than OTGSC_BSV before connects to host.
+ *
+ * @ci: the controller
+ * @reg: register index
+ * @mask: mast bit
+ * @value: the bit value to wait
+ * @timeout: timeout to indicate an error
+ *
+ * This function returns an error code if timeout
  */
-static void ci_role_work(struct work_struct *work)
+static int hw_wait_reg(struct ci13xxx *ci, enum ci13xxx_regs reg, u32 mask,
+				u32 value, unsigned long timeout)
+{
+	unsigned long elapse = jiffies + timeout;
+
+	while (hw_read(ci, reg, mask) != value) {
+		if (time_after(jiffies, elapse)) {
+			dev_err(ci->dev, "timeout waiting for %08x in %d\n",
+					mask, reg);
+			return -ETIMEDOUT;
+		}
+		msleep(20);
+	}
+
+	return 0;
+}
+
+/* 
+ * Since there are some capacitances at vbus, the vbus may not
+ * change very quickly when we stop/start internal 5v.
+ * Below is a vbus stable timeout value, the routine will quit
+ * if the vbus gets the required value, we can think there are some
+ * problems for hardware if the vbus can't get the required value
+ * within 5 seconds.
+ */
+#define CI_VBUS_STABLE_TIMEOUT 500
+static void ci_handle_id_switch(struct ci13xxx *ci)
 {
-	struct ci13xxx *ci = container_of(work, struct ci13xxx, work);
 	enum ci_role role = ci_otg_role(ci);
 
 	if (role != ci->role) {
 		dev_dbg(ci->dev, "switching from %s to %s\n",
 			ci_role(ci)->name, ci->roles[role]->name);
 
-		ci_role_stop(ci);
-		ci_role_start(ci, role);
-		enable_irq(ci->irq);
+		/* 1. Finish the current role */
+		if (ci->role == CI_ROLE_GADGET) {
+			usb_gadget_vbus_disconnect(&ci->gadget);
+			/* host doesn't care B_SESSION_VALID event */
+			ci_clear_otg_interrupt(ci, OTGSC_BSVIS);
+			ci_disable_otg_interrupt(ci, OTGSC_BSVIE);
+			ci->role = CI_ROLE_END;
+			/* reset controller */
+			hw_device_reset(ci, USBMODE_CM_IDLE);
+		} else if (ci->role == CI_ROLE_HOST) {
+			ci_role_stop(ci);
+			/* reset controller */
+			hw_device_reset(ci, USBMODE_CM_IDLE);
+		}
+
+		/* 2. Turn on/off vbus according to coming role */
+		if (ci_otg_role(ci) == CI_ROLE_GADGET) {
+			otg_set_vbus(&ci->otg, false);
+			/* wait vbus lower than OTGSC_BSV */
+			hw_wait_reg(ci, OP_OTGSC, OTGSC_BSV, 0,
+					CI_VBUS_STABLE_TIMEOUT);
+		} else if (ci_otg_role(ci) == CI_ROLE_HOST) {
+			otg_set_vbus(&ci->otg, true);
+			/* wait vbus higher than OTGSC_AVV */
+			hw_wait_reg(ci, OP_OTGSC, OTGSC_AVV, OTGSC_AVV,
+					CI_VBUS_STABLE_TIMEOUT);
+		}
+
+		/* 3. Begin the new role */
+		if (ci_otg_role(ci) == CI_ROLE_GADGET) {
+			ci->role = role;
+			ci_clear_otg_interrupt(ci, OTGSC_BSVIS);
+			ci_enable_otg_interrupt(ci, OTGSC_BSVIE);
+		} else if (ci_otg_role(ci) == CI_ROLE_HOST) {
+			ci_role_start(ci, role);
+		}
 	}
 }
 
+void ci_handle_vbus_change(struct ci13xxx *ci)
+{
+	u32 otgsc = hw_read(ci, OP_OTGSC, ~0);
+
+	if (otgsc & OTGSC_BSV)
+		usb_gadget_vbus_connect(&ci->gadget);
+	else
+		usb_gadget_vbus_disconnect(&ci->gadget);
+}
+
+/**
+ * ci_otg_work - perform otg (vbus/id) event handle
+ * @work: work struct
+ */
+static void ci_otg_work(struct work_struct *work)
+{
+	struct ci13xxx *ci = container_of(work, struct ci13xxx, work);
+
+	if (ci->id_event) {
+		ci->id_event = false;
+		ci_handle_id_switch(ci);
+	} else if (ci->b_sess_valid_event) {
+		ci->b_sess_valid_event = false;
+		ci_handle_vbus_change(ci);
+	} else
+		dev_err(ci->dev, "unexpected event occurs at %s\n", __func__);
+
+	enable_irq(ci->irq);
+}
+
+static void ci_delayed_work(struct work_struct *work)
+{
+	struct delayed_work *dwork = to_delayed_work(work);
+	struct ci13xxx *ci = container_of(dwork, struct ci13xxx, dwork);
+
+	otg_set_vbus(&ci->otg, true);
+
+}
+
 static ssize_t show_role(struct device *dev, struct device_attribute *attr,
 			 char *buf)
 {
@@ -324,16 +441,34 @@ static irqreturn_t ci_irq(int irq, void *data)
 	if (ci->is_otg)
 		otgsc = hw_read(ci, OP_OTGSC, ~0);
 
-	if (ci->role != CI_ROLE_END)
-		ret = ci_role(ci)->irq(ci);
+	/*
+	 * Handle id change interrupt, it indicates device/host function
+	 * switch.
+	 */
+	if (ci->is_otg && (otgsc & OTGSC_IDIE) && (otgsc & OTGSC_IDIS)) {
+		ci->id_event = true;
+		ci_clear_otg_interrupt(ci, OTGSC_IDIS);
+		disable_irq_nosync(ci->irq);
+		queue_work(ci->wq, &ci->work);
+		return IRQ_HANDLED;
+	}
 
-	if (ci->is_otg && (otgsc & OTGSC_IDIS)) {
-		hw_write(ci, OP_OTGSC, OTGSC_IDIS, OTGSC_IDIS);
+	/*
+	 * Handle vbus change interrupt, it indicates device connection
+	 * and disconnection events.
+	 */
+	if ((otgsc & OTGSC_BSVIE) && (otgsc & OTGSC_BSVIS)) {
+		ci->b_sess_valid_event = true;
+		ci_clear_otg_interrupt(ci, OTGSC_BSVIS);
 		disable_irq_nosync(ci->irq);
 		queue_work(ci->wq, &ci->work);
-		ret = IRQ_HANDLED;
+		return IRQ_HANDLED;
 	}
 
+	/* Handle device/host interrupt */
+	if (ci->role != CI_ROLE_END)
+		ret = ci_role(ci)->irq(ci);
+
 	return ret;
 }
 
@@ -398,6 +533,7 @@ static int ci_hdrc_probe(struct platform_device *pdev)
 	struct resource	*res;
 	void __iomem	*base;
 	int		ret;
+	u32		otgsc;
 
 	if (!dev->platform_data) {
 		dev_err(dev, "platform data missing\n");
@@ -443,7 +579,8 @@ static int ci_hdrc_probe(struct platform_device *pdev)
 		return -ENODEV;
 	}
 
-	INIT_WORK(&ci->work, ci_role_work);
+	INIT_WORK(&ci->work, ci_otg_work);
+	INIT_DELAYED_WORK(&ci->dwork, ci_delayed_work);
 	ci->wq = create_singlethread_workqueue("ci_otg");
 	if (!ci->wq) {
 		dev_err(dev, "can't create workqueue\n");
@@ -466,7 +603,10 @@ static int ci_hdrc_probe(struct platform_device *pdev)
 	}
 
 	if (ci->roles[CI_ROLE_HOST] && ci->roles[CI_ROLE_GADGET]) {
+		dev_dbg(dev, "support otg\n");
 		ci->is_otg = true;
+		/* if otg is supported, create struct usb_otg */
+		ci_hdrc_otg_init(ci);
 		/* ID pin needs 1ms debouce time, we delay 2ms for safe */
 		mdelay(2);
 		ci->role = ci_otg_role(ci);
@@ -483,6 +623,17 @@ static int ci_hdrc_probe(struct platform_device *pdev)
 		goto rm_wq;
 	}
 
+	otgsc = hw_read(ci, OP_OTGSC, ~0);
+	/*
+	 * if it is device mode:
+	 * - Enable vbus detect
+	 * - If it has already connected to host, notify udc
+	 */
+	if (ci->role == CI_ROLE_GADGET) {
+		ci_enable_otg_interrupt(ci, OTGSC_BSVIE);
+		ci_handle_vbus_change(ci);
+	}
+
 	platform_set_drvdata(pdev, ci);
 	ret = request_irq(ci->irq, ci_irq, IRQF_SHARED, ci->platdata->name,
 			  ci);
@@ -493,8 +644,9 @@ static int ci_hdrc_probe(struct platform_device *pdev)
 	if (ret)
 		goto rm_attr;
 
-	if (ci->is_otg)
-		hw_write(ci, OP_OTGSC, OTGSC_IDIE, OTGSC_IDIE);
+	/* Handle the situation that usb device at the MicroB to A cable */
+	if (ci->is_otg && !(otgsc & OTGSC_ID))
+		queue_delayed_work(ci->wq, &ci->dwork, msecs_to_jiffies(500));
 
 	return ret;
 
diff --git a/drivers/usb/chipidea/otg.c b/drivers/usb/chipidea/otg.c
index 7dea3b3..2986d91 100644
--- a/drivers/usb/chipidea/otg.c
+++ b/drivers/usb/chipidea/otg.c
@@ -10,21 +10,28 @@
  * published by the Free Software Foundation.
  */
 
-#include <linux/platform_device.h>
-#include <linux/module.h>
-#include <linux/io.h>
-#include <linux/irq.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/usb/gadget.h>
 #include <linux/usb/otg.h>
+#include <linux/usb/gadget.h>
 #include <linux/usb/chipidea.h>
 
 #include "ci.h"
-#include "udc.h"
 #include "bits.h"
-#include "host.h"
-#include "debug.h"
+
+void ci_clear_otg_interrupt(struct ci13xxx *ci, u32 bits)
+{
+	/* Only clear request bits */
+	hw_write(ci, OP_OTGSC, OTGSC_INT_STATUS_BITS, bits);
+}
+
+void ci_enable_otg_interrupt(struct ci13xxx *ci, u32 bits)
+{
+	hw_write(ci, OP_OTGSC, bits, bits);
+}
+
+void ci_disable_otg_interrupt(struct ci13xxx *ci, u32 bits)
+{
+	hw_write(ci, OP_OTGSC, bits, 0);
+}
 
 static int ci_otg_set_peripheral(struct usb_otg *otg,
 		struct usb_gadget *periph)
@@ -55,6 +62,7 @@ int ci_hdrc_otg_init(struct ci13xxx *ci)
 	ci->otg.set_host = ci_otg_set_host;
 	if (!IS_ERR_OR_NULL(ci->transceiver))
 		ci->transceiver->otg = &ci->otg;
+	ci_enable_otg_interrupt(ci, OTGSC_IDIE);
 
 	return 0;
 }
diff --git a/drivers/usb/chipidea/otg.h b/drivers/usb/chipidea/otg.h
index b4c6b3e..fa30428 100644
--- a/drivers/usb/chipidea/otg.h
+++ b/drivers/usb/chipidea/otg.h
@@ -2,5 +2,8 @@
 #define __DRIVERS_USB_CHIPIDEA_OTG_H
 
 int ci_hdrc_otg_init(struct ci13xxx *ci);
+void ci_clear_otg_interrupt(struct ci13xxx *ci, u32 bits);
+void ci_enable_otg_interrupt(struct ci13xxx *ci, u32 bits);
+void ci_disable_otg_interrupt(struct ci13xxx *ci, u32 bits);
 
 #endif /* __DRIVERS_USB_CHIPIDEA_OTG_H */
diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
index d214448..83e54bb 100644
--- a/drivers/usb/chipidea/udc.c
+++ b/drivers/usb/chipidea/udc.c
@@ -1371,6 +1371,7 @@ static int ci13xxx_vbus_session(struct usb_gadget *_gadget, int is_active)
 			pm_runtime_get_sync(&_gadget->dev);
 			hw_device_reset(ci, USBMODE_CM_DC);
 			hw_device_state(ci, ci->ep0out->qh.dma);
+			dev_dbg(ci->dev, "Connected to host\n");
 		} else {
 			hw_device_state(ci, 0);
 			if (ci->platdata->notify_event)
@@ -1378,6 +1379,7 @@ static int ci13xxx_vbus_session(struct usb_gadget *_gadget, int is_active)
 				CI13XXX_CONTROLLER_STOPPED_EVENT);
 			_gadget_stop_activity(&ci->gadget);
 			pm_runtime_put_sync(&_gadget->dev);
+			dev_dbg(ci->dev, "Disconnected from host\n");
 		}
 	}
 
-- 
1.7.0.4

^ permalink raw reply related

* [PATCH v7 2/8] usb: chipidea: add otg file
From: Peter Chen @ 2013-02-04  8:59 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1359968390-317-1-git-send-email-peter.chen@freescale.com>

Implement struct usb_otg, In that way, calling otg_set_peripheral
will not be failed at udc.c.

Signed-off-by: Peter Chen <peter.chen@freescale.com>
---
 drivers/usb/chipidea/Makefile |    2 +-
 drivers/usb/chipidea/ci.h     |    2 +
 drivers/usb/chipidea/otg.c    |   60 +++++++++++++++++++++++++++++++++++++++++
 drivers/usb/chipidea/otg.h    |    6 ++++
 4 files changed, 69 insertions(+), 1 deletions(-)

diff --git a/drivers/usb/chipidea/Makefile b/drivers/usb/chipidea/Makefile
index d92ca32..11f513c 100644
--- a/drivers/usb/chipidea/Makefile
+++ b/drivers/usb/chipidea/Makefile
@@ -2,7 +2,7 @@ ccflags-$(CONFIG_USB_CHIPIDEA_DEBUG) := -DDEBUG
 
 obj-$(CONFIG_USB_CHIPIDEA)		+= ci_hdrc.o
 
-ci_hdrc-y				:= core.o
+ci_hdrc-y				:= core.o otg.o
 ci_hdrc-$(CONFIG_USB_CHIPIDEA_UDC)	+= udc.o
 ci_hdrc-$(CONFIG_USB_CHIPIDEA_HOST)	+= host.o
 ci_hdrc-$(CONFIG_USB_CHIPIDEA_DEBUG)	+= debug.o
diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h
index d738603..697e369 100644
--- a/drivers/usb/chipidea/ci.h
+++ b/drivers/usb/chipidea/ci.h
@@ -129,6 +129,7 @@ struct hw_bank {
  * @vbus_active: is VBUS active
  * @transceiver: pointer to USB PHY, if any
  * @hcd: pointer to usb_hcd for ehci host driver
+ * @otg: for otg support
  */
 struct ci13xxx {
 	struct device			*dev;
@@ -164,6 +165,7 @@ struct ci13xxx {
 	bool				global_phy;
 	struct usb_phy			*transceiver;
 	struct usb_hcd			*hcd;
+	struct usb_otg      		otg;
 };
 
 static inline struct ci_role_driver *ci_role(struct ci13xxx *ci)
diff --git a/drivers/usb/chipidea/otg.c b/drivers/usb/chipidea/otg.c
new file mode 100644
index 0000000..7dea3b3
--- /dev/null
+++ b/drivers/usb/chipidea/otg.c
@@ -0,0 +1,60 @@
+/*
+ * otg.c - ChipIdea USB IP core OTG driver
+ *
+ * Copyright (C) 2012 Freescale Semiconductor, Inc.
+ *
+ * Author: Peter Chen
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/usb/gadget.h>
+#include <linux/usb/otg.h>
+#include <linux/usb/chipidea.h>
+
+#include "ci.h"
+#include "udc.h"
+#include "bits.h"
+#include "host.h"
+#include "debug.h"
+
+static int ci_otg_set_peripheral(struct usb_otg *otg,
+		struct usb_gadget *periph)
+{
+	otg->gadget = periph;
+
+	return 0;
+}
+
+static int ci_otg_set_host(struct usb_otg *otg, struct usb_bus *host)
+{
+	otg->host = host;
+
+	return 0;
+}
+
+/**
+ * ci_hdrc_otg_init - initialize device related bits
+ * ci: the controller
+ *
+ * This function create otg struct, if the device can switch between
+ * device and host.
+ */
+int ci_hdrc_otg_init(struct ci13xxx *ci)
+{
+	/* Useless at current */
+	ci->otg.set_peripheral = ci_otg_set_peripheral;
+	ci->otg.set_host = ci_otg_set_host;
+	if (!IS_ERR_OR_NULL(ci->transceiver))
+		ci->transceiver->otg = &ci->otg;
+
+	return 0;
+}
diff --git a/drivers/usb/chipidea/otg.h b/drivers/usb/chipidea/otg.h
new file mode 100644
index 0000000..b4c6b3e
--- /dev/null
+++ b/drivers/usb/chipidea/otg.h
@@ -0,0 +1,6 @@
+#ifndef __DRIVERS_USB_CHIPIDEA_OTG_H
+#define __DRIVERS_USB_CHIPIDEA_OTG_H
+
+int ci_hdrc_otg_init(struct ci13xxx *ci);
+
+#endif /* __DRIVERS_USB_CHIPIDEA_OTG_H */
-- 
1.7.0.4

^ permalink raw reply related

* [PATCH v7 1/8] Revert "USB: chipidea: add vbus detect for udc"
From: Peter Chen @ 2013-02-04  8:59 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1359968390-317-1-git-send-email-peter.chen@freescale.com>

vbus register is at otgsc, and vbus detect does not belong
to device function. Revert this patch, and will move
vbus detect function to drivers/usb/chipidea/udc.c

This reverts commit 8c4fc031954b4eb72daf13d3c907a985a3eee208.

Signed-off-by: Peter Chen <peter.chen@freescale.com>
---
 drivers/usb/chipidea/ci.h  |    1 -
 drivers/usb/chipidea/udc.c |   39 +--------------------------------------
 2 files changed, 1 insertions(+), 39 deletions(-)

diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h
index e25d126..d738603 100644
--- a/drivers/usb/chipidea/ci.h
+++ b/drivers/usb/chipidea/ci.h
@@ -139,7 +139,6 @@ struct ci13xxx {
 	enum ci_role			role;
 	bool				is_otg;
 	struct work_struct		work;
-	struct work_struct		vbus_work;
 	struct workqueue_struct		*wq;
 
 	struct dma_pool			*qh_pool;
diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
index 2f45bba..d214448 100644
--- a/drivers/usb/chipidea/udc.c
+++ b/drivers/usb/chipidea/udc.c
@@ -305,18 +305,6 @@ static u32 hw_test_and_clear_intr_active(struct ci13xxx *ci)
 	return reg;
 }
 
-static void hw_enable_vbus_intr(struct ci13xxx *ci)
-{
-	hw_write(ci, OP_OTGSC, OTGSC_AVVIS, OTGSC_AVVIS);
-	hw_write(ci, OP_OTGSC, OTGSC_AVVIE, OTGSC_AVVIE);
-	queue_work(ci->wq, &ci->vbus_work);
-}
-
-static void hw_disable_vbus_intr(struct ci13xxx *ci)
-{
-	hw_write(ci, OP_OTGSC, OTGSC_AVVIE, 0);
-}
-
 /**
  * hw_test_and_clear_setup_guard: test & clear setup guard (execute without
  *                                interruption)
@@ -383,16 +371,6 @@ static int hw_usb_reset(struct ci13xxx *ci)
 	return 0;
 }
 
-static void vbus_work(struct work_struct *work)
-{
-	struct ci13xxx *ci = container_of(work, struct ci13xxx, vbus_work);
-
-	if (hw_read(ci, OP_OTGSC, OTGSC_AVV))
-		usb_gadget_vbus_connect(&ci->gadget);
-	else
-		usb_gadget_vbus_disconnect(&ci->gadget);
-}
-
 /******************************************************************************
  * UTIL block
  *****************************************************************************/
@@ -1392,7 +1370,6 @@ static int ci13xxx_vbus_session(struct usb_gadget *_gadget, int is_active)
 		if (is_active) {
 			pm_runtime_get_sync(&_gadget->dev);
 			hw_device_reset(ci, USBMODE_CM_DC);
-			hw_enable_vbus_intr(ci);
 			hw_device_state(ci, ci->ep0out->qh.dma);
 		} else {
 			hw_device_state(ci, 0);
@@ -1567,10 +1544,8 @@ static int ci13xxx_start(struct usb_gadget *gadget,
 	pm_runtime_get_sync(&ci->gadget.dev);
 	if (ci->platdata->flags & CI13XXX_PULLUP_ON_VBUS) {
 		if (ci->vbus_active) {
-			if (ci->platdata->flags & CI13XXX_REGS_SHARED) {
+			if (ci->platdata->flags & CI13XXX_REGS_SHARED)
 				hw_device_reset(ci, USBMODE_CM_DC);
-				hw_enable_vbus_intr(ci);
-			}
 		} else {
 			pm_runtime_put_sync(&ci->gadget.dev);
 			goto done;
@@ -1676,13 +1651,6 @@ static irqreturn_t udc_irq(struct ci13xxx *ci)
 	} else {
 		retval = IRQ_NONE;
 	}
-
-	intr = hw_read(ci, OP_OTGSC, ~0);
-	hw_write(ci, OP_OTGSC, ~0, intr);
-
-	if (intr & (OTGSC_AVVIE & OTGSC_AVVIS))
-		queue_work(ci->wq, &ci->vbus_work);
-
 	spin_unlock(&ci->lock);
 
 	return retval;
@@ -1758,7 +1726,6 @@ static int udc_start(struct ci13xxx *ci)
 		retval = hw_device_reset(ci, USBMODE_CM_DC);
 		if (retval)
 			goto put_transceiver;
-		hw_enable_vbus_intr(ci);
 	}
 
 	retval = device_register(&ci->gadget.dev);
@@ -1821,9 +1788,6 @@ static void udc_stop(struct ci13xxx *ci)
 	if (ci == NULL)
 		return;
 
-	hw_disable_vbus_intr(ci);
-	cancel_work_sync(&ci->vbus_work);
-
 	usb_del_gadget_udc(&ci->gadget);
 
 	destroy_eps(ci);
@@ -1864,7 +1828,6 @@ int ci_hdrc_gadget_init(struct ci13xxx *ci)
 	rdrv->irq	= udc_irq;
 	rdrv->name	= "gadget";
 	ci->roles[CI_ROLE_GADGET] = rdrv;
-	INIT_WORK(&ci->vbus_work, vbus_work);
 
 	return 0;
 }
-- 
1.7.0.4

^ permalink raw reply related

* [PATCH v7 0/8] Add tested id switch and vbus connect detect support for Chipidea
From: Peter Chen @ 2013-02-04  8:59 UTC (permalink / raw)
  To: linux-arm-kernel

Changes for v6:
For Patch 8/8, we only need to set ci->driver to NULL when usb cable
is not connected, for other changes, it will case some runtime pm
unmatch and un-align with udc-core & composite driver problems.

Changes for v5:
- Add Alex comments for init/destroy function [3/8] [4/8]
- Remove memset(&ci->gadget, 0, sizeof(ci->gadget)) at destory function [4/8]
- Add Kishon's comment: Change the format of struct usb_otg otg at drivers/usb/chipidea/ci.h
[1/8]
- Add comments for CI_VBUS_STABLE_TIMEOUT [3/8]
- Change the otg_set_peripheral return value check as the fully
chipidea driver users don't need it. [4/8]
- Fix one bug that the oops when re-plug in usb cable after
rmmod gadget [8/8]

Anyone who has tested this patchset, please give a tested-by, thanks.

This patchset adds tested otg id switch function and
vbus connect/disconnect detection for chipidea driver.
The mainly design of id/vbus handling follows msm otg driver.
I hope the msm usb maintainer can have a look of this patchset,
and give some comments, and move the whole msm usb driver to
chipidea framework if possible in the future.

This patch is fully tested at imx6 sabrelite platform.
My chipidea repo: https://github.com/hzpeterchen/linux-usb.git
which is rebased of 3.8-rc5.

Peter Chen (8):
  Revert "USB: chipidea: add vbus detect for udc"
  usb: chipidea: add otg file
  usb: chipidea: add otg id switch and vbus connect/disconnect detect
  usb: chipidea: consolidate kinds of APIs for both roles
  usb: chipidea: udc: add pullup/pulldown dp at hw_device_state
  usb: chipidea: udc: retire the flag CI13_PULLUP_ON_VBUS
  usb: chipidea: imx: add internal vbus regulator control
  usb: chipidea: udc: fix the oops when plugs in usb cable after rmmod
    gadget

 drivers/usb/chipidea/Makefile      |    2 +-
 drivers/usb/chipidea/bits.h        |   10 ++
 drivers/usb/chipidea/ci.h          |   12 ++-
 drivers/usb/chipidea/ci13xxx_imx.c |   81 ++++++++++++----
 drivers/usb/chipidea/ci13xxx_msm.c |    1 -
 drivers/usb/chipidea/core.c        |  186 +++++++++++++++++++++++++++++++-----
 drivers/usb/chipidea/host.c        |    6 +
 drivers/usb/chipidea/host.h        |    4 +-
 drivers/usb/chipidea/otg.c         |   68 +++++++++++++
 drivers/usb/chipidea/otg.h         |    9 ++
 drivers/usb/chipidea/udc.c         |  107 +++++++++------------
 drivers/usb/chipidea/udc.h         |    4 +-
 include/linux/usb/chipidea.h       |    1 -
 13 files changed, 379 insertions(+), 112 deletions(-)
 create mode 100644 drivers/usb/chipidea/otg.c
 create mode 100644 drivers/usb/chipidea/otg.h

^ permalink raw reply

* [PATCH 0/2] ARM: dts: OMAP3: Add GPMC controller and NAND memory to Overo
From: Florian Vaussard @ 2013-02-04  8:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20130201221618.GB22517@atomide.com>

>>
>> So how should we handle such case? Having several dtsi depending
>> on the Overo's revision would be a mess to my sense, considering
>> the non-conditional include inside the expansion boards' dts.
>> Or would it make sense to extend the DT binding for partitions?
>
> Yes makes sense to extend the binding to use the full flash memory
> if the size can be probed.
>

Ok, I will see for a patch soon (i.e. in the coming weeks).

Regards,

Florian

^ permalink raw reply

* [PATCHv2 0/2] add omap mcspi device tree data
From: Santosh Shilimkar @ 2013-02-04  8:55 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1359967907-26645-1-git-send-email-sourav.poddar@ti.com>

On Monday 04 February 2013 02:21 PM, Sourav Poddar wrote:
> Patch series adds omap5 evm mcspi nodes and pinctrl
> data in omap5.dtsi and omap5-evm.dts files.
>
> Felipe Balbi (1):
>    arm: dts: omap5: add SPI devices to OMAP5 DeviceTree file
>
> Sourav Poddar (1):
>    arm: dts: omap5-evm: Add mcspi data
>
>   arch/arm/boot/dts/omap5-evm.dts |   46 +++++++++++++++++++++++++++++++++++++++
>   arch/arm/boot/dts/omap5.dtsi    |   40 +++++++++++++++++++++++++++++++++
>   2 files changed, 86 insertions(+), 0 deletions(-)
>
Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com>

^ permalink raw reply


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