Re: [PATCH v12 00/13] Add tested id switch and vbus connect detect support for Chipidea

2013-07-21 Thread Peter Chen
 the USB OTG ID pin.
Do the same thing I have done at imx28evk, you probably will work
if the ID pin is the same at your board.

If it works, please give a tested-by :).

-- 

Best Regards,
Peter Chen

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v12 00/13] Add tested id switch and vbus connect detect support for Chipidea

2013-07-21 Thread Peter Chen
On Mon, Jul 22, 2013 at 03:40:32AM +0200, Marek Vasut wrote:
 Dear Peter Chen,
 
  On Mon, Jul 22, 2013 at 03:15:28AM +0200, Marek Vasut wrote:
   Hi Peter,
   
On Fri, Jul 12, 2013 at 03:18:31PM +0200, Marek Vasut wrote:
 Hi Peter,
 
  On Fri, Jul 12, 2013 at 06:04:43AM +0200, Marek Vasut wrote:
   Hi Peter,
   
On Thu, Jul 11, 2013 at 07:57:19PM +0200, Marek Vasut wrote:
 Hi Peter,
 
  This patchset adds tested otg id switch function and
  vbus connect and disconnect detection for chipidea driver.
  And fix kinds of bugs found at chipidea drivers after
  enabling id and vbus detection.
  
  This patch is fully tested at imx6 sabresd platform.
  My chipidea repo:
  https://github.com/hzpeterchen/linux-usb.git
  
  Changes for v12:
  - Rebased greg's usb-next tree (3.10.0-rc7+)
  - Split more small patches for single function and fix.
 
 I tested the patchset. Here are the results:
 
 - VBUS switching
 
 I'm no longer getting any ID interrupts at all when I apply
 the patch below. The board stays in HOST mode all the time.
 If I configure it as peripheral, it works as peripheral.
 Note with [1], I was able to switch from Peripheral-Host ,
 not the other way around.

Thanks for your testing. But first, can you have me check
if your ID wakeup is enabled?
   
   ID wakeup? How do I check?
  
  See otgsc at controller register, the ID wakeup enable is bit 24.
 
 Yes, ID interrupt (IDIE) is set.
 
 I noticed this backtrace in the kernel bootlog, but this only happens
 if the dr_mode=otg , it comes from the host-mode irq handler :
 
 [2.757563] irq 238: nobody cared (try booting with the irqpoll
 option) [2.764398] CPU: 0 PID: 1 Comm: swapper Not tainted
 3.10.0- next-20130711-00013-g011c4b3-dirty #703
 [2.773445] [80013878] (unwind_backtrace+0x0/0xe8) from
 [80011644] (show_stack+0x10/0x14)
 [2.782027] [80011644] (show_stack+0x10/0x14) from [800659f4]
 (__report_bad_irq.isra.6+0x20/0xe0)
 [2.791286] [800659f4] (__report_bad_irq.isra.6+0x20/0xe0) from
 [80065c98] (note_interrupt+0x16c/0x230)
 [2.801063] [80065c98] (note_interrupt+0x16c/0x230) from
 [80064000] (handle_irq_event_percpu+0x10c/0x1a4)
 [2.811010] [80064000] (handle_irq_event_percpu+0x10c/0x1a4)
 from [800640e8] (handle_irq_event+0x50/0x78)
 [2.820958] [800640e8] (handle_irq_event+0x50/0x78) from
 [8006652c] (handle_level_irq+0x88/0x10c)
 [2.830210] [8006652c] (handle_level_irq+0x88/0x10c) from
 [800638d0] (generic_handle_irq+0x28/0x3c)
 [2.839637] [800638d0] (generic_handle_irq+0x28/0x3c) from
 [8000f84c] (handle_IRQ+0x30/0x84)
 [2.848461] [8000f84c] (handle_IRQ+0x30/0x84) from [80012160]
 (__irq_svc+0x40/0x6c)
 [2.856510] [80012160] (__irq_svc+0x40/0x6c) from [80022a44]
 (__do_softirq+0x90/0x1d8)
 [2.864812] [80022a44] (__do_softirq+0x90/0x1d8) from
 [80022edc] (irq_exit+0x98/0xd4)
 [2.873025] [80022edc] (irq_exit+0x98/0xd4) from [8000f850]
 (handle_IRQ+0x34/0x84)
 [2.880980] [8000f850] (handle_IRQ+0x34/0x84) from [80012160]
 (__irq_svc+0x40/0x6c)
 [2.889020] [80012160] (__irq_svc+0x40/0x6c) from [8001d724]
 (vprintk_emit+0x1bc/0x524)
 [2.897411] [8001d724] (vprintk_emit+0x1bc/0x524) from
 [804da5a4] (printk+0x30/0x40)
 [2.905551] [804da5a4] (printk+0x30/0x40) from [80630138]
 (mousedev_init+0x4c/0x60)
 [2.913617] [80630138] (mousedev_init+0x4c/0x60) from
 [806178fc] (do_one_initcall+0x94/0x14c)
 [2.922537] [806178fc] (do_one_initcall+0x94/0x14c) from
 [80617b20] (kernel_init_freeable+0x16c/0x22c)
 [2.932230] [80617b20] (kernel_init_freeable+0x16c/0x22c) from
 [804d8cbc] (kernel_init+0x8/0x150)
 [2.941486] [804d8cbc] (kernel_init+0x8/0x150) from [8000ea70]
 (ret_from_fork+0x14/0x24)
 [2.949932] handlers:
 [2.952227] [8033fc58] ci_irq
 [2.955388] Disabling IRQ #238

Marek, I have a test at imx28evk (Freescale imx28evk) for this
patchset, it works well for dual-role switch after adding below dts
change. There is a kernel dump when works at udc mode(due to enable
CONFIG_LOCKUP_DETECTOR), at the first connect, but it does not affect
function, it should be a common chipidea problem, I will check later.
   
   Sorry for the long delay. I finally got further with this, at least now I
   can switch Periph-Host again, but if I do so the other way around
   (unplug host adapter and plug computer cable) and dump the controller
   registers, I still see the controller in host (according to USBMODE
   register) mode. The controller stays in HOST mode even if I force

Re: [PATCH v12 00/13] Add tested id switch and vbus connect detect support for Chipidea

2013-07-25 Thread Peter Chen
On Thu, Jul 25, 2013 at 07:55:23AM +0200, Marek Vasut wrote:
 Hi Peter,
 
  
  I have not tried the manual switching, but first, you need to close your
  vbus supply.
 
 I think we can close this issue, I will now be also getting MX28EVK. Thanks 
 for 
 all your help!
 
 

Great. What's the problem? Any changes for this patchset?

-- 

Best Regards,
Peter Chen

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] chipidea: core: Move hw_phymode_configure() into probe

2013-07-25 Thread Peter Chen
On Thu, Jul 25, 2013 at 06:20:34PM -0300, Fabio Estevam wrote:
 Currently hw_phymode_configure() is located inside hw_device_reset(), which is
 only called by chipidea udc driver.
 
 When operating in host mode, we also need to call hw_phymode_configure() in 
 order to properly configure the PHY mode, so move this function into probe.
 
 After this change, USB Host1 port on mx53qsb board is functional.
 
 Signed-off-by: Fabio Estevam fabio.este...@freescale.com
 ---
  drivers/usb/chipidea/core.c | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)
 
 diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
 index a5df24c..a5b3774 100644
 --- a/drivers/usb/chipidea/core.c
 +++ b/drivers/usb/chipidea/core.c
 @@ -264,8 +264,6 @@ int hw_device_reset(struct ci_hdrc *ci, u32 mode)
   while (hw_read(ci, OP_USBCMD, USBCMD_RST))
   udelay(10); /* not RTOS friendly */
  
 - hw_phymode_configure(ci);
 -
   if (ci-platdata-notify_event)
   ci-platdata-notify_event(ci,
   CI_HDRC_CONTROLLER_RESET_EVENT);
 @@ -457,6 +455,8 @@ static int ci_hdrc_probe(struct platform_device *pdev)
   if (!ci-platdata-phy_mode)
   ci-platdata-phy_mode = of_usb_get_phy_mode(dev-of_node);
  
 + hw_phymode_configure(ci);
 +
   if (!ci-platdata-dr_mode)
   ci-platdata-dr_mode = of_usb_get_dr_mode(dev-of_node);
  
 -- 
 1.8.1.2
 

At old version (not upsteamed), Michael did put it at probe, I don't
know why move it to hw_device_reset later.

Talked with IC guys, usbcmd.rst will not reset PORTSC_PTS at chipidea
core IP default, unless some vendors changes this behaviour(very low
possibilities). So, it is safe to put it at probe, unless we need
consider above uncertain change.

Reviewed-by: Peter Chen peter.c...@freescale.com

-- 

Best Regards,
Peter Chen

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] chipidea: ci_hdrc_imx: Remove unused variable 'res'

2013-07-25 Thread Peter Chen
On Thu, Jul 25, 2013 at 12:55:28AM -0300, Fabio Estevam wrote:
 From: Fabio Estevam fabio.este...@freescale.com
 
 'res' is not used anywhere, so let's get rid of it.
 
 Signed-off-by: Fabio Estevam fabio.este...@freescale.com
 ---
  drivers/usb/chipidea/ci_hdrc_imx.c | 7 ---
  1 file changed, 7 deletions(-)
 
 diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c 
 b/drivers/usb/chipidea/ci_hdrc_imx.c
 index 14362c0..06bc775 100644
 --- a/drivers/usb/chipidea/ci_hdrc_imx.c
 +++ b/drivers/usb/chipidea/ci_hdrc_imx.c
 @@ -96,7 +96,6 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
 CI_HDRC_PULLUP_ON_VBUS |
 CI_HDRC_DISABLE_STREAMING,
   };
 - struct resource *res;
   int ret;
  
   if (of_find_property(pdev-dev.of_node, fsl,usbmisc, NULL)
 @@ -109,12 +108,6 @@ static int ci_hdrc_imx_probe(struct platform_device 
 *pdev)
   return -ENOMEM;
   }
  
 - res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 - if (!res) {
 - dev_err(pdev-dev, Can't get device resources!\n);
 - return -ENOENT;
 - }
 -
   data-clk = devm_clk_get(pdev-dev, NULL);
   if (IS_ERR(data-clk)) {
   dev_err(pdev-dev,
 -- 
 1.8.1.2
 
 

Acked-by: Peter Chen peter.c...@freescale.com

-- 

Best Regards,
Peter Chen

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v13 02/14] usb: chipidea: imx: remove vbus regulator operation

2013-07-26 Thread Peter Chen
Since we have added vbus reguatlor operation at common
host file (chipidea/host.c), the glue layer vbus operation
isn't needed any more.

Tested-by: Marek Vasut ma...@denx.de
Signed-off-by: Peter Chen peter.c...@freescale.com
---
 drivers/usb/chipidea/ci_hdrc_imx.c |   30 +++---
 1 files changed, 7 insertions(+), 23 deletions(-)

diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c 
b/drivers/usb/chipidea/ci_hdrc_imx.c
index 14362c0..d06355e 100644
--- a/drivers/usb/chipidea/ci_hdrc_imx.c
+++ b/drivers/usb/chipidea/ci_hdrc_imx.c
@@ -31,7 +31,6 @@ struct ci_hdrc_imx_data {
struct usb_phy *phy;
struct platform_device *ci_pdev;
struct clk *clk;
-   struct regulator *reg_vbus;
 };
 
 static const struct usbmisc_ops *usbmisc_ops;
@@ -141,22 +140,13 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
goto err_clk;
}
 
-   /* we only support host now, so enable vbus here */
-   data-reg_vbus = devm_regulator_get(pdev-dev, vbus);
-   if (!IS_ERR(data-reg_vbus)) {
-   ret = regulator_enable(data-reg_vbus);
-   if (ret) {
-   dev_err(pdev-dev,
-   Failed to enable vbus regulator, err=%d\n,
-   ret);
-   goto err_clk;
-   }
-   } else {
-   data-reg_vbus = NULL;
-   }
-
pdata.phy = data-phy;
 
+   /* Get the vbus regulator */
+   pdata.reg_vbus = devm_regulator_get(pdev-dev, vbus);
+   if (IS_ERR(pdata.reg_vbus))
+   pdata.reg_vbus = NULL;
+
if (!pdev-dev.dma_mask)
pdev-dev.dma_mask = pdev-dev.coherent_dma_mask;
if (!pdev-dev.coherent_dma_mask)
@@ -167,7 +157,7 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
if (ret) {
dev_err(pdev-dev,
usbmisc init failed, ret=%d\n, ret);
-   goto err;
+   goto err_clk;
}
}
 
@@ -179,7 +169,7 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
dev_err(pdev-dev,
Can't register ci_hdrc platform device, err=%d\n,
ret);
-   goto err;
+   goto err_clk;
}
 
if (usbmisc_ops  usbmisc_ops-post) {
@@ -200,9 +190,6 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
 
 disable_device:
ci_hdrc_remove_device(data-ci_pdev);
-err:
-   if (data-reg_vbus)
-   regulator_disable(data-reg_vbus);
 err_clk:
clk_disable_unprepare(data-clk);
return ret;
@@ -215,9 +202,6 @@ static int ci_hdrc_imx_remove(struct platform_device *pdev)
pm_runtime_disable(pdev-dev);
ci_hdrc_remove_device(data-ci_pdev);
 
-   if (data-reg_vbus)
-   regulator_disable(data-reg_vbus);
-
if (data-phy) {
usb_phy_shutdown(data-phy);
module_put(data-phy-dev-driver-owner);
-- 
1.7.0.4


--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v13 13/14] usb: chipidea: udc: .pullup is valid when vbus is on at CI_HDRC_PULLUP_ON_VBUS

2013-07-26 Thread Peter Chen
When the flag CI_HDRC_PULLUP_ON_VBUS is set, .pullup should only be
called when the vbus is active. When the CI_HDRC_PULLUP_ON_VBUS
is set, the controller only begins to run when the vbus is on,
So, it is only meaningful software set pullup/pulldown after
the controller begins to run.

Tested-by: Marek Vasut ma...@denx.de
Signed-off-by: Peter Chen peter.c...@freescale.com
---
 drivers/usb/chipidea/udc.c |4 
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
index 45abf4d..b7ead5f 100644
--- a/drivers/usb/chipidea/udc.c
+++ b/drivers/usb/chipidea/udc.c
@@ -1514,6 +1514,10 @@ static int ci_udc_pullup(struct usb_gadget *_gadget, int 
is_on)
 {
struct ci_hdrc *ci = container_of(_gadget, struct ci_hdrc, gadget);
 
+   if ((ci-platdata-flags  CI_HDRC_PULLUP_ON_VBUS)
+!ci-vbus_active)
+   return -EOPNOTSUPP;
+
if (is_on)
hw_write(ci, OP_USBCMD, USBCMD_RS, USBCMD_RS);
else
-- 
1.7.0.4


--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v13 12/14] usb: chipidea: udc: misuse flag CI_HDRC_REGS_SHARED and CI_HDRC_PULLUP_ON_VBUS

2013-07-26 Thread Peter Chen
CI_HDRC_REGS_SHARED stands for the controller registers is shared
with other USB drivers, if all USB drivers are at chipidea/, it doesn't
needed to set.
CI_HDRC_PULLUP_ON_VBUS stands for pullup dp when the vbus is on. This
flag doesn't need to set if the vbus is always on for gadget
since dp has always pulled up after the gadget has initialized.

So, the current code seems to misuse this two flags.
- When the gadget initializes, the controller doesn't need to run if
it depends on vbus (CI_HDRC_PULLUP_ON_VBUS), it does not
relate to shared register.
- When the gadget starts (load one gadget module), the controller
can run if vbus is on (CI_HDRC_PULLUP_ON_VBUS), it also does not
relate to shared register.

Tested-by: Marek Vasut ma...@denx.de
Signed-off-by: Peter Chen peter.c...@freescale.com
---
 drivers/usb/chipidea/udc.c |5 ++---
 1 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
index c70ce38..45abf4d 100644
--- a/drivers/usb/chipidea/udc.c
+++ b/drivers/usb/chipidea/udc.c
@@ -1637,8 +1637,7 @@ static int ci_udc_start(struct usb_gadget *gadget,
pm_runtime_get_sync(ci-gadget.dev);
if (ci-platdata-flags  CI_HDRC_PULLUP_ON_VBUS) {
if (ci-vbus_active) {
-   if (ci-platdata-flags  CI_HDRC_REGS_SHARED)
-   hw_device_reset(ci, USBMODE_CM_DC);
+   hw_device_reset(ci, USBMODE_CM_DC);
} else {
pm_runtime_put_sync(ci-gadget.dev);
goto done;
@@ -1801,7 +1800,7 @@ static int udc_start(struct ci_hdrc *ci)
}
}
 
-   if (!(ci-platdata-flags  CI_HDRC_REGS_SHARED)) {
+   if (!(ci-platdata-flags  CI_HDRC_PULLUP_ON_VBUS)) {
retval = hw_device_reset(ci, USBMODE_CM_DC);
if (retval)
goto put_transceiver;
-- 
1.7.0.4


--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v13 01/14] usb: chipidea: add vbus regulator control

2013-07-26 Thread Peter Chen
For boards which have board level vbus control (eg, through gpio), we
need to vbus operation according to below rules:
- For host, we need open vbus before start hcd, and close it
after remove hcd.
- For otg, the vbus needs to be on/off when usb role switches.
When the host roles begins, it opens vbus; when the host role
finishes, it closes vbus.

We put vbus operation to host as host is the only vbus user,
When we are at host mode, the vbus is on, when we are not at
host mode, vbus should be off.

Tested-by: Marek Vasut ma...@denx.de
Signed-off-by: Peter Chen peter.c...@freescale.com
---
 drivers/usb/chipidea/host.c  |   23 ++-
 include/linux/usb/chipidea.h |1 +
 2 files changed, 23 insertions(+), 1 deletions(-)

diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c
index 40d0fda..e94e52b 100644
--- a/drivers/usb/chipidea/host.c
+++ b/drivers/usb/chipidea/host.c
@@ -24,6 +24,7 @@
 #include linux/usb.h
 #include linux/usb/hcd.h
 #include linux/usb/chipidea.h
+#include linux/regulator/consumer.h
 
 #include ../host/ehci.h
 
@@ -64,9 +65,19 @@ static int host_start(struct ci_hdrc *ci)
ehci-caps = ci-hw_bank.cap;
ehci-has_hostpc = ci-hw_bank.lpm;
 
+   if (ci-platdata-reg_vbus) {
+   ret = regulator_enable(ci-platdata-reg_vbus);
+   if (ret) {
+   dev_err(ci-dev,
+   Failed to enable vbus regulator, ret=%d\n,
+   ret);
+   goto put_hcd;
+   }
+   }
+
ret = usb_add_hcd(hcd, 0, 0);
if (ret)
-   usb_put_hcd(hcd);
+   goto disable_reg;
else
ci-hcd = hcd;
 
@@ -74,6 +85,14 @@ static int host_start(struct ci_hdrc *ci)
hw_write(ci, OP_USBMODE, USBMODE_CI_SDIS, USBMODE_CI_SDIS);
 
return ret;
+
+disable_reg:
+   regulator_disable(ci-platdata-reg_vbus);
+
+put_hcd:
+   usb_put_hcd(hcd);
+
+   return ret;
 }
 
 static void host_stop(struct ci_hdrc *ci)
@@ -82,6 +101,8 @@ static void host_stop(struct ci_hdrc *ci)
 
usb_remove_hcd(hcd);
usb_put_hcd(hcd);
+   if (ci-platdata-reg_vbus)
+   regulator_disable(ci-platdata-reg_vbus);
 }
 
 int ci_hdrc_host_init(struct ci_hdrc *ci)
diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h
index 2562994..118bf66 100644
--- a/include/linux/usb/chipidea.h
+++ b/include/linux/usb/chipidea.h
@@ -24,6 +24,7 @@ struct ci_hdrc_platform_data {
 #define CI_HDRC_CONTROLLER_RESET_EVENT 0
 #define CI_HDRC_CONTROLLER_STOPPED_EVENT   1
void(*notify_event) (struct ci_hdrc *ci, unsigned event);
+   struct regulator *reg_vbus;
 };
 
 /* Default offset of capability registers */
-- 
1.7.0.4


--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v13 07/14] usb: chipidea: add flag CI_HDRC_DUAL_ROLE_NOT_OTG

2013-07-26 Thread Peter Chen
Since we need otgsc to know vbus's status at some chipidea
controllers even it is peripheral-only mode. Besides, some
SoCs (eg, AR9331 SoC) don't have otgsc register even
the DCCPARAMS_DC and DCCPARAMS_HC are both 1 at CAP_DCCPARAMS.

We inroduce flag CI_HDRC_DUAL_ROLE_NOT_OTG to indicate if the
controller is dual role, but not supports OTG. If this flag is
not set, we follow the rule that if DCCPARAMS_DC and DCCPARAMS_HC
are both 1 at CAP_DCCPARAMS, then this controller is otg capable.

Signed-off-by: Peter Chen peter.c...@freescale.com
---
 drivers/usb/chipidea/core.c  |   38 +++---
 include/linux/usb/chipidea.h |5 +
 2 files changed, 36 insertions(+), 7 deletions(-)

diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index 93961ff..28983c3 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -405,6 +405,18 @@ static inline void ci_role_destroy(struct ci_hdrc *ci)
ci_hdrc_host_destroy(ci);
 }
 
+static void ci_get_otg_capable(struct ci_hdrc *ci)
+{
+   if (ci-platdata-flags  CI_HDRC_DUAL_ROLE_NOT_OTG)
+   ci-is_otg = false;
+   else
+   ci-is_otg = (hw_read(ci, CAP_DCCPARAMS,
+   DCCPARAMS_DC | DCCPARAMS_HC)
+   == (DCCPARAMS_DC | DCCPARAMS_HC));
+   if (ci-is_otg)
+   dev_dbg(ci-dev, It is OTG capable controller\n);
+}
+
 static int ci_hdrc_probe(struct platform_device *pdev)
 {
struct device   *dev = pdev-dev;
@@ -461,6 +473,9 @@ static int ci_hdrc_probe(struct platform_device *pdev)
return -ENODEV;
}
 
+   /* To know if controller is OTG capable or not */
+   ci_get_otg_capable(ci);
+
if (!ci-platdata-phy_mode)
ci-platdata-phy_mode = of_usb_get_phy_mode(dev-of_node);
 
@@ -491,10 +506,22 @@ static int ci_hdrc_probe(struct platform_device *pdev)
}
 
if (ci-roles[CI_ROLE_HOST]  ci-roles[CI_ROLE_GADGET]) {
-   ci-is_otg = true;
-   /* ID pin needs 1ms debouce time, we delay 2ms for safe */
-   mdelay(2);
-   ci-role = ci_otg_role(ci);
+   if (ci-is_otg) {
+   /*
+* ID pin needs 1ms debouce time,
+* we delay 2ms for safe.
+*/
+   mdelay(2);
+   ci-role = ci_otg_role(ci);
+   ci_hdrc_otg_init(ci);
+   } else {
+   /*
+* If the controller is not OTG capable, but support
+* role switch, the defalt role is gadget, and the
+* user can switch it through debugfs (proc in future?)
+*/
+   ci-role = CI_ROLE_GADGET;
+   }
} else {
ci-role = ci-roles[CI_ROLE_HOST]
? CI_ROLE_HOST
@@ -514,9 +541,6 @@ static int ci_hdrc_probe(struct platform_device *pdev)
if (ret)
goto stop;
 
-   if (ci-is_otg)
-   ci_hdrc_otg_init(ci);
-
ret = dbg_create_files(ci);
if (!ret)
return 0;
diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h
index 118bf66..e94dc2e 100644
--- a/include/linux/usb/chipidea.h
+++ b/include/linux/usb/chipidea.h
@@ -20,6 +20,11 @@ struct ci_hdrc_platform_data {
 #define CI_HDRC_REQUIRE_TRANSCEIVERBIT(1)
 #define CI_HDRC_PULLUP_ON_VBUS BIT(2)
 #define CI_HDRC_DISABLE_STREAMING  BIT(3)
+   /*
+* Only set it when DCCPARAMS.DC==1 and DCCPARAMS.HC==1,
+* but otg is not supported (no register otgsc).
+*/
+#define CI_HDRC_DUAL_ROLE_NOT_OTG  BIT(4)
enum usb_dr_modedr_mode;
 #define CI_HDRC_CONTROLLER_RESET_EVENT 0
 #define CI_HDRC_CONTROLLER_STOPPED_EVENT   1
-- 
1.7.0.4


--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v13 08/14] usb: chipidea: disable all interrupts and clear all interrupts status

2013-07-26 Thread Peter Chen
During the initialization, it needs to disable all interrupts
enable bit as well as clear all interrupts status bits to avoid
exceptional interrupt.

Tested-by: Marek Vasut ma...@denx.de
Signed-off-by: Peter Chen peter.c...@freescale.com
---
 drivers/usb/chipidea/core.c |   11 ++-
 1 files changed, 10 insertions(+), 1 deletions(-)

diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index 28983c3..8884af6 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -198,6 +198,12 @@ static int hw_device_init(struct ci_hdrc *ci, void __iomem 
*base)
if (ci-hw_ep_max  ENDPT_MAX)
return -ENODEV;
 
+   /* Disable all interrupts bits */
+   hw_write(ci, OP_USBINTR, 0x, 0);
+
+   /* Clear all interrupts status bits*/
+   hw_write(ci, OP_USBSTS, 0x, 0x);
+
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);
 
@@ -413,8 +419,11 @@ static void ci_get_otg_capable(struct ci_hdrc *ci)
ci-is_otg = (hw_read(ci, CAP_DCCPARAMS,
DCCPARAMS_DC | DCCPARAMS_HC)
== (DCCPARAMS_DC | DCCPARAMS_HC));
-   if (ci-is_otg)
+   if (ci-is_otg) {
dev_dbg(ci-dev, It is OTG capable controller\n);
+   ci_disable_otg_interrupt(ci, OTGSC_INT_EN_BITS);
+   ci_clear_otg_interrupt(ci, OTGSC_INT_STATUS_BITS);
+   }
 }
 
 static int ci_hdrc_probe(struct platform_device *pdev)
-- 
1.7.0.4


--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v13 10/14] usb: chipidea: add vbus interrupt handler

2013-07-26 Thread Peter Chen
We add vbus interrupt handler at ci_otg_work, it uses OTGSC_BSV(at otgsc)
to know it is connect or disconnet event.
Meanwhile, we introduce two flags id_event and b_sess_valid_event to
indicate it is an id interrupt or a vbus interrupt.

Tested-by: Marek Vasut ma...@denx.de
Signed-off-by: Peter Chen peter.c...@freescale.com
---
 drivers/usb/chipidea/ci.h   |5 +
 drivers/usb/chipidea/core.c |   28 +++-
 drivers/usb/chipidea/otg.c  |   42 +++---
 drivers/usb/chipidea/otg.h  |1 +
 drivers/usb/chipidea/udc.c  |7 +++
 5 files changed, 71 insertions(+), 12 deletions(-)

diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h
index 33cb29f..3160363 100644
--- a/drivers/usb/chipidea/ci.h
+++ b/drivers/usb/chipidea/ci.h
@@ -132,6 +132,9 @@ struct hw_bank {
  * @transceiver: pointer to USB PHY, if any
  * @hcd: pointer to usb_hcd for ehci host driver
  * @debugfs: root dentry for this controller in debugfs
+ * @id_event: indicates there is an id event, and handled at ci_otg_work
+ * @b_sess_valid_event: indicates there is a vbus event, and handled
+ * at ci_otg_work
  */
 struct ci_hdrc {
struct device   *dev;
@@ -168,6 +171,8 @@ struct ci_hdrc {
struct usb_phy  *transceiver;
struct usb_hcd  *hcd;
struct dentry   *debugfs;
+   boolid_event;
+   boolb_sess_valid_event;
 };
 
 static inline struct ci_role_driver *ci_role(struct ci_hdrc *ci)
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index 78c4721..0fbeb45 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -304,16 +304,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 (ci-is_otg  (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;
 }
 
diff --git a/drivers/usb/chipidea/otg.c b/drivers/usb/chipidea/otg.c
index 68f2faf..c74194d 100644
--- a/drivers/usb/chipidea/otg.c
+++ b/drivers/usb/chipidea/otg.c
@@ -52,13 +52,23 @@ enum ci_role ci_otg_role(struct ci_hdrc *ci)
return role;
 }
 
-/**
- * ci_role_work - perform role changing based on ID pin
- * @work: work struct
- */
-static void ci_role_work(struct work_struct *work)
+void ci_handle_vbus_change(struct ci_hdrc *ci)
+{
+   u32 otgsc;
+
+   if (!ci-is_otg)
+   return;
+
+   otgsc = hw_read(ci, OP_OTGSC, ~0);
+
+   if (otgsc  OTGSC_BSV)
+   usb_gadget_vbus_connect(ci-gadget);
+   else
+   usb_gadget_vbus_disconnect(ci-gadget);
+}
+
+static void ci_handle_id_switch(struct ci_hdrc *ci)
 {
-   struct ci_hdrc *ci = container_of(work, struct ci_hdrc, work);
enum ci_role role = ci_otg_role(ci);
 
if (role != ci-role) {
@@ -68,17 +78,35 @@ static void ci_role_work(struct work_struct *work)
ci_role_stop(ci);
ci_role_start(ci, role);
}
+}
+/**
+ * ci_otg_work - perform otg (vbus/id) event handle
+ * @work: work struct
+ */
+static void ci_otg_work(struct work_struct *work)
+{
+   struct ci_hdrc *ci = container_of(work, struct ci_hdrc, 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);
 }
 
+
 /**
  * ci_hdrc_otg_init - initialize otg struct
  * ci: the controller
  */
 int ci_hdrc_otg_init(struct ci_hdrc *ci)
 {
-   INIT_WORK(ci-work, ci_role_work);
+   INIT_WORK(ci-work

[PATCH v13 00/14] Add tested id switch and vbus connect detect support for Chipidea

2013-07-26 Thread Peter Chen
This patchset adds tested otg id switch function and vbus connect
and disconnect detection for chipidea driver. And fix kinds of 
bugs found at chipidea drivers after enabling id and vbus detection.

This patch are fully tested at imx6 sabresd and imx28evk platform by me.
Besides, marek tested it on two STMP3780-based boards (not yet mainline)
and two MX28-based boards.

My chipidea repo: https://github.com/hzpeterchen/linux-usb.git

Chagnes for v13:
- Add Tested-by: Marek Vasut ma...@denx.de
- [Sascha's comments]: Add return value check for devm_regulator_get. [3/14]
- [Marc's comments]: Change timeout usage at hw_wait_reg. [11/14]
- [Alex's comments]: Using platdata flag to indicate dual role but not 
OTG controller. [7/14]

Changes for v12:
- Rebased greg's usb-next tree (3.10.0-rc7+)
- Split more small patches for single function and fix.

Changes for v11:
- mark ci_handle_vbus_change as static as it is only used at core.c
[3/9]
- Move the vbus operation for platform code to host code, as vbus
operation is common operation, and host is the only user for vbus.
When it is host mode, we need to open vbus, when it is out of host
mode, we need to close vbus. [6/9] [8/9]
- Delete the delayed work at core.c as it is not needed. [7/9]

Changes for v10:
- Delete [8/9] at v9, ci core's drvdata must be set for further operation.
[8/8]

Changes for v9:
- Some small comments from Alex like: variable comment for otg event
additional newline. [3/9]
- Import function tell show if the controller has otg capable, if
the controller supports both host and device, we think it is otg
capable, and can read OTGSC. [3/9]
- Merge two otg patches [v8 3/8] and [v8 4/8] to one [v9 3/9]. [3/9]
- Add inline to ci_hdrc_gadget_destroy if CONFIG_USB_CHIPIDEA_UDC
is not defined, it can fix one build warning defined but not used
[3/9]
- One comment from Felipe about changing calling gadget disconnect
API at chipidea's udc driver. I move calling ci-driver-disconnect
from _gadget_stop_activity to which calls _gadget_stop_activity except
ci13xxx_stop, as udc core will call disconnect when do rmmod gadget. [7/9]
- Add ci core probe's return value to ci's platform_data, we do this
for getting core's probe's result at platform layer, and quit it
if the core's probe fails. [8/9] [9/9]

Changes for v8:
- Add ci_supports_gadget helper to know if the controller
supports gadget, if the controller supports gadget, it
needs to read otgsc to know the vbus value, basically,
if the controller supports gadget, it will support host
as well [3/8]
- At ci_hdrc_probe, it needs to add free memory at error path
[3/8]
- Cosolidate ci-driver = NULL at ci13xxx_stop
[8/8]

Changes for v7:
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 v6:
- 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]

Peter Chen (14):
  usb: chipidea: add vbus regulator control
  usb: chipidea: imx: remove vbus regulator operation
  usb: chipidea: imx: add return value check for devm_regulator_get
  usb: chipidea: udc: otg_set_peripheral is useless for some chipidea
users
  usb: chipidea: otg: Add otg file used to access otgsc
  usb: chipidea: Add role init and destory APIs
  usb: chipidea: add flag CI_HDRC_DUAL_ROLE_NOT_OTG
  usb: chipidea: disable all interrupts and clear all interrupts status
  usb: chipidea: move otg relate things to otg file
  usb: chipidea: add vbus interrupt handler
  usb: chipidea: add wait vbus lower than OTGSC_BSV before role starts
  usb: chipidea: udc: misuse flag CI_HDRC_REGS_SHARED and
CI_HDRC_PULLUP_ON_VBUS
  usb: chipidea: udc: .pullup is valid when vbus is on at
CI_HDRC_PULLUP_ON_VBUS
  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  |8 ++
 drivers/usb/chipidea/ci_hdrc_imx.c |   40 -
 drivers/usb/chipidea/core.c|  161 
 drivers/usb/chipidea/host.c|   30 +++-
 drivers/usb/chipidea/host.h|6 ++
 drivers/usb/chipidea/otg.c |  135 ++
 drivers/usb/chipidea/otg.h |   22 +
 drivers/usb/chipidea/udc.c |   72 
 drivers/usb/chipidea/udc.h |6 ++
 include/linux/usb/chipidea.h   |6 ++
 12 files changed, 402 insertions(+), 96 deletions(-)
 create mode 100644 drivers

[PATCH v13 04/14] usb: chipidea: udc: otg_set_peripheral is useless for some chipidea users

2013-07-26 Thread Peter Chen
It is useless at below cases:
- If we implement both usb host and device at chipidea driver.
- If we don't need phy-otg.

Tested-by: Marek Vasut ma...@denx.de
Signed-off-by: Peter Chen peter.c...@freescale.com
---
 drivers/usb/chipidea/udc.c |7 ++-
 1 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
index e475fcd..116c762 100644
--- a/drivers/usb/chipidea/udc.c
+++ b/drivers/usb/chipidea/udc.c
@@ -1805,7 +1805,12 @@ static int udc_start(struct ci_hdrc *ci)
if (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 put_transceiver;
}
 
-- 
1.7.0.4


--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v13 09/14] usb: chipidea: move otg relate things to otg file

2013-07-26 Thread Peter Chen
Move otg relate things to otg file.

Tested-by: Marek Vasut ma...@denx.de
Signed-off-by: Peter Chen peter.c...@freescale.com
---
 drivers/usb/chipidea/core.c |   63 +--
 drivers/usb/chipidea/otg.c  |   57 +-
 drivers/usb/chipidea/otg.h  |2 +
 3 files changed, 70 insertions(+), 52 deletions(-)

diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index 8884af6..78c4721 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -295,40 +295,6 @@ int hw_device_reset(struct ci_hdrc *ci, u32 mode)
return 0;
 }
 
-/**
- * ci_otg_role - pick role based on ID pin state
- * @ci: the controller
- */
-static enum ci_role ci_otg_role(struct ci_hdrc *ci)
-{
-   u32 sts = hw_read(ci, OP_OTGSC, ~0);
-   enum ci_role role = sts  OTGSC_ID
-   ? CI_ROLE_GADGET
-   : CI_ROLE_HOST;
-
-   return role;
-}
-
-/**
- * ci_role_work - perform role changing based on ID pin
- * @work: work struct
- */
-static void ci_role_work(struct work_struct *work)
-{
-   struct ci_hdrc *ci = container_of(work, struct ci_hdrc, 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);
-}
-
 static irqreturn_t ci_irq(int irq, void *data)
 {
struct ci_hdrc *ci = data;
@@ -409,6 +375,8 @@ static inline void ci_role_destroy(struct ci_hdrc *ci)
 {
ci_hdrc_gadget_destroy(ci);
ci_hdrc_host_destroy(ci);
+   if (ci-is_otg)
+   ci_hdrc_otg_destory(ci);
 }
 
 static void ci_get_otg_capable(struct ci_hdrc *ci)
@@ -475,13 +443,6 @@ static int ci_hdrc_probe(struct platform_device *pdev)
return -ENODEV;
}
 
-   INIT_WORK(ci-work, ci_role_work);
-   ci-wq = create_singlethread_workqueue(ci_otg);
-   if (!ci-wq) {
-   dev_err(dev, can't create workqueue\n);
-   return -ENODEV;
-   }
-
/* To know if controller is OTG capable or not */
ci_get_otg_capable(ci);
 
@@ -510,8 +471,15 @@ static int ci_hdrc_probe(struct platform_device *pdev)
 
if (!ci-roles[CI_ROLE_HOST]  !ci-roles[CI_ROLE_GADGET]) {
dev_err(dev, no supported roles\n);
-   ret = -ENODEV;
-   goto rm_wq;
+   return -ENODEV;
+   }
+
+   if (ci-is_otg) {
+   ret = ci_hdrc_otg_init(ci);
+   if (ret) {
+   dev_err(dev, init otg fails, ret = %d\n, ret);
+   goto stop;
+   }
}
 
if (ci-roles[CI_ROLE_HOST]  ci-roles[CI_ROLE_GADGET]) {
@@ -522,7 +490,7 @@ static int ci_hdrc_probe(struct platform_device *pdev)
 */
mdelay(2);
ci-role = ci_otg_role(ci);
-   ci_hdrc_otg_init(ci);
+   ci_enable_otg_interrupt(ci, OTGSC_IDIE);
} else {
/*
 * If the controller is not OTG capable, but support
@@ -541,7 +509,7 @@ static int ci_hdrc_probe(struct platform_device *pdev)
if (ret) {
dev_err(dev, can't start %s role\n, ci_role(ci)-name);
ret = -ENODEV;
-   goto rm_wq;
+   goto stop;
}
 
platform_set_drvdata(pdev, ci);
@@ -557,9 +525,6 @@ static int ci_hdrc_probe(struct platform_device *pdev)
free_irq(ci-irq, ci);
 stop:
ci_role_destroy(ci);
-rm_wq:
-   flush_workqueue(ci-wq);
-   destroy_workqueue(ci-wq);
 
return ret;
 }
@@ -569,8 +534,6 @@ static int ci_hdrc_remove(struct platform_device *pdev)
struct ci_hdrc *ci = platform_get_drvdata(pdev);
 
dbg_remove_files(ci);
-   flush_workqueue(ci-wq);
-   destroy_workqueue(ci-wq);
free_irq(ci-irq, ci);
ci_role_destroy(ci);
 
diff --git a/drivers/usb/chipidea/otg.c b/drivers/usb/chipidea/otg.c
index abefb4d..68f2faf 100644
--- a/drivers/usb/chipidea/otg.c
+++ b/drivers/usb/chipidea/otg.c
@@ -39,12 +39,65 @@ void ci_disable_otg_interrupt(struct ci_hdrc *ci, u32 bits)
 }
 
 /**
- * ci_hdrc_otg_init - initialize otgsc bits
+ * ci_otg_role - pick role based on ID pin state
+ * @ci: the controller
+ */
+enum ci_role ci_otg_role(struct ci_hdrc *ci)
+{
+   u32 sts = hw_read(ci, OP_OTGSC, ~0);
+   enum ci_role role = sts  OTGSC_ID
+   ? CI_ROLE_GADGET
+   : CI_ROLE_HOST;
+
+   return role;
+}
+
+/**
+ * ci_role_work - perform role changing based on ID pin
+ * @work: work struct
+ */
+static void ci_role_work(struct work_struct *work)
+{
+   struct ci_hdrc *ci = container_of(work, struct ci_hdrc, work);
+   enum ci_role role

[PATCH v13 14/14] usb: chipidea: udc: fix the oops when plugs in usb cable after rmmod gadget

2013-07-26 Thread Peter Chen
] (dump_backtrace+0x0/0x114) from [804ea684] 
(dump_stack+0x20/0x24)
 r7: 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:   000f 8001aea0 bf8be000 80712a48 804f0040 
ff80: 806d29e8 412fc09a  bf8bffb4 bf8bffb8 bf8bffa8 8000fbcc 8000fbd0
ffa0: 6013 
 r7:bf8bff94 r6: r5:6013 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:0003
 r4:806e2008
 [804e7810] (secondary_start_kernel+0x0/0x148) from [104e7148] (0x104e7148)
 r5:001f r4:4f8a806a
 CPU1: stopping
 Backtrace:
 [800132e8] (dump_backtrace+0x0/0x114) from [804ea684] 
(dump_stack+0x20/0x24)
 r7: 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:   000f 8001aea0 bf8ba000 80712a48 804f0040 
bf80: 806d29e8 412fc09a  bf8bbfb4 bf8bbfb8 bf8bbfa8 8000fbcc 8000fbd0
bfa0: 6013 
 r7:bf8bbf94 r6: r5:6013 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:0001
 r4:806e2008

Tested-by: Marek Vasut ma...@denx.de
Signed-off-by: Peter Chen peter.c...@freescale.com
---
 drivers/usb/chipidea/udc.c |   13 +
 1 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
index b7ead5f..aeabdcf 100644
--- a/drivers/usb/chipidea/udc.c
+++ b/drivers/usb/chipidea/udc.c
@@ -686,9 +686,6 @@ static int _gadget_stop_activity(struct usb_gadget *gadget)
usb_ep_fifo_flush(ci-ep0out-ep);
usb_ep_fifo_flush(ci-ep0in-ep);
 
-   if (ci-driver)
-   ci-driver-disconnect(gadget);
-
/* make sure to disable all endpoints */
gadget_for_each_ep(ep, gadget) {
usb_ep_disable(ep);
@@ -717,6 +714,11 @@ __acquires(ci-lock)
 {
int retval;
 
+   if (ci-gadget.speed != USB_SPEED_UNKNOWN) {
+   if (ci-driver)
+   ci-driver-disconnect(ci-gadget);
+   }
+
spin_unlock(ci-lock);
retval = _gadget_stop_activity(ci-gadget);
if (retval)
@@ -1464,6 +1466,8 @@ static int ci_udc_vbus_session(struct usb_gadget 
*_gadget, int is_active)
hw_device_state(ci, ci-ep0out-qh.dma);
dev_dbg(ci-dev, Connected to host\n);
} else {
+   if (ci-driver)
+   ci-driver-disconnect(ci-gadget);
hw_device_state(ci, 0);
if (ci-platdata-notify_event)
ci-platdata-notify_event(ci,
@@ -1674,13 +1678,14 @@ static int ci_udc_stop(struct usb_gadget *gadget,
if (ci-platdata-notify_event)
ci-platdata-notify_event(ci,
CI_HDRC_CONTROLLER_STOPPED_EVENT);
-   ci-driver = NULL;
spin_unlock_irqrestore(ci-lock, flags);
_gadget_stop_activity(ci-gadget);
spin_lock_irqsave(ci-lock, flags);
pm_runtime_put(ci-gadget.dev);
}
 
+   ci-driver = NULL;
+
spin_unlock_irqrestore(ci-lock, flags);
 
return 0;
-- 
1.7.0.4


--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v13 05/14] usb: chipidea: otg: Add otg file used to access otgsc

2013-07-26 Thread Peter Chen
This file is mainly used to access otgsc currently, it may
add otg related things in the future.

Tested-by: Marek Vasut ma...@denx.de
Signed-off-by: Peter Chen peter.c...@freescale.com
---
 drivers/usb/chipidea/Makefile |2 +-
 drivers/usb/chipidea/bits.h   |   10 
 drivers/usb/chipidea/core.c   |3 +-
 drivers/usb/chipidea/otg.c|   50 +
 drivers/usb/chipidea/otg.h|   19 +++
 5 files changed, 82 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/chipidea/Makefile b/drivers/usb/chipidea/Makefile
index 6cf5f68..a99d980 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/bits.h b/drivers/usb/chipidea/bits.h
index aefa026..dd0cf9e 100644
--- a/drivers/usb/chipidea/bits.h
+++ b/drivers/usb/chipidea/bits.h
@@ -79,11 +79,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/core.c b/drivers/usb/chipidea/core.c
index a5df24c..761f7e8 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -71,6 +71,7 @@
 #include bits.h
 #include host.h
 #include debug.h
+#include otg.h
 
 /* Controller register map */
 static uintptr_t ci_regs_nolpm[] = {
@@ -508,7 +509,7 @@ static int ci_hdrc_probe(struct platform_device *pdev)
goto stop;
 
if (ci-is_otg)
-   hw_write(ci, OP_OTGSC, OTGSC_IDIE, OTGSC_IDIE);
+   ci_hdrc_otg_init(ci);
 
ret = dbg_create_files(ci);
if (!ret)
diff --git a/drivers/usb/chipidea/otg.c b/drivers/usb/chipidea/otg.c
new file mode 100644
index 000..abefb4d
--- /dev/null
+++ b/drivers/usb/chipidea/otg.c
@@ -0,0 +1,50 @@
+/*
+ * otg.c - ChipIdea USB IP core OTG driver
+ *
+ * Copyright (C) 2013 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.
+ */
+
+/*
+ * This file mainly handles otgsc register, it may include OTG operation
+ * in the future.
+ */
+
+#include linux/usb/otg.h
+#include linux/usb/gadget.h
+#include linux/usb/chipidea.h
+
+#include ci.h
+#include bits.h
+
+void ci_clear_otg_interrupt(struct ci_hdrc *ci, u32 bits)
+{
+   /* Only clear request bits */
+   hw_write(ci, OP_OTGSC, OTGSC_INT_STATUS_BITS, bits);
+}
+
+void ci_enable_otg_interrupt(struct ci_hdrc *ci, u32 bits)
+{
+   hw_write(ci, OP_OTGSC, bits, bits);
+}
+
+void ci_disable_otg_interrupt(struct ci_hdrc *ci, u32 bits)
+{
+   hw_write(ci, OP_OTGSC, bits, 0);
+}
+
+/**
+ * ci_hdrc_otg_init - initialize otgsc bits
+ * ci: the controller
+ */
+int ci_hdrc_otg_init(struct ci_hdrc *ci)
+{
+   ci_enable_otg_interrupt(ci, OTGSC_IDIE);
+
+   return 0;
+}
diff --git a/drivers/usb/chipidea/otg.h b/drivers/usb/chipidea/otg.h
new file mode 100644
index 000..f24ec37
--- /dev/null
+++ b/drivers/usb/chipidea/otg.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2013 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.
+ */
+
+#ifndef __DRIVERS_USB_CHIPIDEA_OTG_H
+#define __DRIVERS_USB_CHIPIDEA_OTG_H
+
+int ci_hdrc_otg_init(struct ci_hdrc *ci);
+void ci_clear_otg_interrupt(struct ci_hdrc *ci, u32 bits);
+void ci_enable_otg_interrupt(struct ci_hdrc *ci, u32 bits);
+void ci_disable_otg_interrupt(struct ci_hdrc *ci, u32 bits);
+
+#endif /* __DRIVERS_USB_CHIPIDEA_OTG_H */
-- 
1.7.0.4


--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body

[PATCH v13 06/14] usb: chipidea: Add role init and destory APIs

2013-07-26 Thread Peter Chen
- The role's init will be called at probe procedure.
- The role's destory will be called at fail patch
at probe and driver's removal.
- The role's start/stop will be called when specific
role has started.

Tested-by: Marek Vasut ma...@denx.de
Signed-off-by: Peter Chen peter.c...@freescale.com
---
 drivers/usb/chipidea/core.c |   10 --
 drivers/usb/chipidea/host.c |7 +++
 drivers/usb/chipidea/host.h |6 ++
 drivers/usb/chipidea/udc.c  |   36 +++-
 drivers/usb/chipidea/udc.h  |6 ++
 5 files changed, 54 insertions(+), 11 deletions(-)

diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index 761f7e8..93961ff 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -399,6 +399,12 @@ void ci_hdrc_remove_device(struct platform_device *pdev)
 }
 EXPORT_SYMBOL_GPL(ci_hdrc_remove_device);
 
+static inline void ci_role_destroy(struct ci_hdrc *ci)
+{
+   ci_hdrc_gadget_destroy(ci);
+   ci_hdrc_host_destroy(ci);
+}
+
 static int ci_hdrc_probe(struct platform_device *pdev)
 {
struct device   *dev = pdev-dev;
@@ -517,7 +523,7 @@ static int ci_hdrc_probe(struct platform_device *pdev)
 
free_irq(ci-irq, ci);
 stop:
-   ci_role_stop(ci);
+   ci_role_destroy(ci);
 rm_wq:
flush_workqueue(ci-wq);
destroy_workqueue(ci-wq);
@@ -533,7 +539,7 @@ static int ci_hdrc_remove(struct platform_device *pdev)
flush_workqueue(ci-wq);
destroy_workqueue(ci-wq);
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 e94e52b..382be5b 100644
--- a/drivers/usb/chipidea/host.c
+++ b/drivers/usb/chipidea/host.c
@@ -105,6 +105,13 @@ static void host_stop(struct ci_hdrc *ci)
regulator_disable(ci-platdata-reg_vbus);
 }
 
+
+void ci_hdrc_host_destroy(struct ci_hdrc *ci)
+{
+   if (ci-role == CI_ROLE_HOST)
+   host_stop(ci);
+}
+
 int ci_hdrc_host_init(struct ci_hdrc *ci)
 {
struct ci_role_driver *rdrv;
diff --git a/drivers/usb/chipidea/host.h b/drivers/usb/chipidea/host.h
index 058875c..5707bf3 100644
--- a/drivers/usb/chipidea/host.h
+++ b/drivers/usb/chipidea/host.h
@@ -4,6 +4,7 @@
 #ifdef CONFIG_USB_CHIPIDEA_HOST
 
 int ci_hdrc_host_init(struct ci_hdrc *ci);
+void ci_hdrc_host_destroy(struct ci_hdrc *ci);
 
 #else
 
@@ -12,6 +13,11 @@ static inline int ci_hdrc_host_init(struct ci_hdrc *ci)
return -ENXIO;
 }
 
+static inline void ci_hdrc_host_destroy(struct ci_hdrc *ci)
+{
+
+}
+
 #endif
 
 #endif /* __DRIVERS_USB_CHIPIDEA_HOST_H */
diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
index 116c762..24a100d 100644
--- a/drivers/usb/chipidea/udc.c
+++ b/drivers/usb/chipidea/udc.c
@@ -27,6 +27,7 @@
 #include udc.h
 #include bits.h
 #include debug.h
+#include otg.h
 
 /* control endpoint description */
 static const struct usb_endpoint_descriptor
@@ -1844,13 +1845,13 @@ free_qh_pool:
 }
 
 /**
- * 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 ci_hdrc *ci)
+void ci_hdrc_gadget_destroy(struct ci_hdrc *ci)
 {
-   if (ci == NULL)
+   if (!ci-roles[CI_ROLE_GADGET])
return;
 
usb_del_gadget_udc(ci-gadget);
@@ -1865,15 +1866,32 @@ static void udc_stop(struct ci_hdrc *ci)
if (ci-global_phy)
usb_put_phy(ci-transceiver);
}
-   /* my kobject is dynamic, I swear! */
-   memset(ci-gadget, 0, sizeof(ci-gadget));
+}
+
+static int udc_id_switch_for_device(struct ci_hdrc *ci)
+{
+   if (ci-is_otg) {
+   ci_clear_otg_interrupt(ci, OTGSC_BSVIS);
+   ci_enable_otg_interrupt(ci, OTGSC_BSVIE);
+   }
+
+   return 0;
+}
+
+static void udc_id_switch_for_host(struct ci_hdrc *ci)
+{
+   if (ci-is_otg) {
+   /* host doesn't care B_SESSION_VALID event */
+   ci_clear_otg_interrupt(ci, OTGSC_BSVIS);
+   ci_disable_otg_interrupt(ci, OTGSC_BSVIE);
+   }
 }
 
 /**
  * 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 the gadget, if the device is device capable.
  */
 int ci_hdrc_gadget_init(struct ci_hdrc *ci)
 {
@@ -1886,11 +1904,11 @@ int ci_hdrc_gadget_init(struct ci_hdrc *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

[PATCH v13 11/14] usb: chipidea: add wait vbus lower than OTGSC_BSV before role starts

2013-07-26 Thread Peter Chen
When the gadget role starts, we need to make sure the vbus is lower
than OTGSC_BSV, or there will be an vbus interrupt since we use
B_SESSION_VALID as vbus interrupt to indicate connect and disconnect.
When the host role starts, it may not be useful to wait vbus to lower
than OTGSC_BSV, but it can indicate some hardware problems like the
vbus is still higher than OTGSC_BSV after we disconnect to host some
time later (5000 milliseconds currently), which is obvious not correct.

Tested-by: Marek Vasut ma...@denx.de
Signed-off-by: Peter Chen peter.c...@freescale.com
---
 drivers/usb/chipidea/ci.h   |3 +++
 drivers/usb/chipidea/core.c |   32 
 drivers/usb/chipidea/otg.c  |4 
 3 files changed, 39 insertions(+), 0 deletions(-)

diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h
index 3160363..1c94fc5 100644
--- a/drivers/usb/chipidea/ci.h
+++ b/drivers/usb/chipidea/ci.h
@@ -308,4 +308,7 @@ int hw_port_test_set(struct ci_hdrc *ci, u8 mode);
 
 u8 hw_port_test_get(struct ci_hdrc *ci);
 
+int hw_wait_reg(struct ci_hdrc *ci, enum ci_hw_regs reg, u32 mask,
+   u32 value, unsigned int timeout_ms);
+
 #endif /* __DRIVERS_USB_CHIPIDEA_CI_H */
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index 0fbeb45..6f9e04d 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -295,6 +295,38 @@ int hw_device_reset(struct ci_hdrc *ci, u32 mode)
return 0;
 }
 
+/**
+ * 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_ms: timeout in millisecond
+ *
+ * This function returns an error code if timeout
+ */
+int hw_wait_reg(struct ci_hdrc *ci, enum ci_hw_regs reg, u32 mask,
+   u32 value, unsigned int timeout_ms)
+{
+   unsigned long elapse = jiffies + msecs_to_jiffies(timeout_ms);
+
+   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;
+}
+
 static irqreturn_t ci_irq(int irq, void *data)
 {
struct ci_hdrc *ci = data;
diff --git a/drivers/usb/chipidea/otg.c b/drivers/usb/chipidea/otg.c
index c74194d..d39cce8 100644
--- a/drivers/usb/chipidea/otg.c
+++ b/drivers/usb/chipidea/otg.c
@@ -67,6 +67,7 @@ void ci_handle_vbus_change(struct ci_hdrc *ci)
usb_gadget_vbus_disconnect(ci-gadget);
 }
 
+#define CI_VBUS_STABLE_TIMEOUT_MS 5000
 static void ci_handle_id_switch(struct ci_hdrc *ci)
 {
enum ci_role role = ci_otg_role(ci);
@@ -76,6 +77,9 @@ static void ci_handle_id_switch(struct ci_hdrc *ci)
ci_role(ci)-name, ci-roles[role]-name);
 
ci_role_stop(ci);
+   /* wait vbus lower than OTGSC_BSV */
+   hw_wait_reg(ci, OP_OTGSC, OTGSC_BSV, 0,
+   CI_VBUS_STABLE_TIMEOUT_MS);
ci_role_start(ci, role);
}
 }
-- 
1.7.0.4


--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Chipidea tree is out of date one month

2013-07-29 Thread Peter Chen
Hi Alex,

Your chipidea tree is out of date more than one month,
https://github.com/virtuoso/linux-ci/commits/ci-for-greg

You have not queued any patches since June 26th, below is the
oldest patch you have not queued.
http://marc.info/?l=linux-usbm=137227196006173w=2

There are two patches you said you will send to Greg after
-rc1, but now, Greg's -rc3 is ready, the patches are still
not there.
http://marc.info/?l=linux-usbm=137344357113728w=2

Besides, please give more comments about patchset, Eg, I
sent patchset about 13 patches in it, but you only gave
one comment for one patch.

-- 

Best Regards,
Peter Chen

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v13 02/14] usb: chipidea: imx: remove vbus regulator operation

2013-07-29 Thread Peter Chen
On Tue, Jul 30, 2013 at 12:30:25AM +0200, Michael Grzeschik wrote:
 Hi Peter,
 
 On Fri, Jul 26, 2013 at 05:18:18PM +0800, Peter Chen wrote:
  Since we have added vbus reguatlor operation at common
  host file (chipidea/host.c), the glue layer vbus operation
  isn't needed any more.
  
  Tested-by: Marek Vasut ma...@denx.de
  Signed-off-by: Peter Chen peter.c...@freescale.com
  ---
   drivers/usb/chipidea/ci_hdrc_imx.c |   30 +++---
   1 files changed, 7 insertions(+), 23 deletions(-)
  
  diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c 
  b/drivers/usb/chipidea/ci_hdrc_imx.c
  index 14362c0..d06355e 100644
  --- a/drivers/usb/chipidea/ci_hdrc_imx.c
  +++ b/drivers/usb/chipidea/ci_hdrc_imx.c
  @@ -31,7 +31,6 @@ struct ci_hdrc_imx_data {
  struct usb_phy *phy;
  struct platform_device *ci_pdev;
  struct clk *clk;
  -   struct regulator *reg_vbus;
   };
   
   static const struct usbmisc_ops *usbmisc_ops;
  @@ -141,22 +140,13 @@ static int ci_hdrc_imx_probe(struct platform_device 
  *pdev)
  goto err_clk;
  }
   
  -   /* we only support host now, so enable vbus here */
  -   data-reg_vbus = devm_regulator_get(pdev-dev, vbus);
  -   if (!IS_ERR(data-reg_vbus)) {
  -   ret = regulator_enable(data-reg_vbus);
  -   if (ret) {
  -   dev_err(pdev-dev,
  -   Failed to enable vbus regulator, err=%d\n,
  -   ret);
  -   goto err_clk;
  -   }
  -   } else {
  -   data-reg_vbus = NULL;
  -   }
  -
  pdata.phy = data-phy;
   
  +   /* Get the vbus regulator */
  +   pdata.reg_vbus = devm_regulator_get(pdev-dev, vbus);
  +   if (IS_ERR(pdata.reg_vbus))
  +   pdata.reg_vbus = NULL;
  +
 
 This hunk needs the reg_vbus variable from the previous patch, therefor
 it should also be added in that patch. As the user of the variable is
 the previous patch, it's the reason to swap their order.
 

The [1/14] implements the vbus operation at common code (host.c)
This one [2/14] implements how the glue layer get the vbus.

I am OK to swap above two, but I still can't see obvious reason.

 Anyway, can't this be done in core.c instead? I don't see why other
 users don't need this code.
 

We still not implement DT support at core.c, it is a big job, this
is the main reason, besides, Alex prefers platform things at
glue layer.
-- 

Best Regards,
Peter Chen

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v13 03/14] usb: chipidea: imx: add return value check for devm_regulator_get

2013-07-29 Thread Peter Chen
On Tue, Jul 30, 2013 at 12:47:17AM +0200, Michael Grzeschik wrote:
 On Fri, Jul 26, 2013 at 05:18:19PM +0800, Peter Chen wrote:
  - If devm_regulator_get returns -EPROBE_DEFER, we also return
  -EPROBE_DEFER to wait regulator being ready later.
  - If devm_regulator_get returns -ENODEV, we think there is
  no vbus-supply node at DT, it means this board doesn't need
  vbus control.
  - If devm_regulator_get returns other error values, it means
  there are something wrong for getting this regulator.
  
  Signed-off-by: Peter Chen peter.c...@freescale.com
  ---
   drivers/usb/chipidea/ci_hdrc_imx.c |   14 --
   1 files changed, 12 insertions(+), 2 deletions(-)
  
  diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c 
  b/drivers/usb/chipidea/ci_hdrc_imx.c
  index d06355e..0ced8c1 100644
  --- a/drivers/usb/chipidea/ci_hdrc_imx.c
  +++ b/drivers/usb/chipidea/ci_hdrc_imx.c
  @@ -144,8 +144,18 @@ static int ci_hdrc_imx_probe(struct platform_device 
  *pdev)
   
  /* Get the vbus regulator */
  pdata.reg_vbus = devm_regulator_get(pdev-dev, vbus);
  -   if (IS_ERR(pdata.reg_vbus))
  -   pdata.reg_vbus = NULL;
  +   if (PTR_ERR(pdata.reg_vbus) == -EPROBE_DEFER) {
  +   ret = -EPROBE_DEFER;
  +   goto err_clk;
  +   } else if (PTR_ERR(pdata.reg_vbus) == -ENODEV) {
  +   pdata.reg_vbus = NULL; /* no vbus regualator is needed */
  +   } else if (IS_ERR(pdata.reg_vbus)) {
  +   dev_err(pdev-dev,
  +   Getting regulator error: %ld\n,
  +   PTR_ERR(pdata.reg_vbus));
  +   ret = PTR_ERR(pdata.reg_vbus);
  +   goto err_clk;
  +   }
   
  if (!pdev-dev.dma_mask)
  pdev-dev.dma_mask = pdev-dev.coherent_dma_mask;
  -- 
 
 This is wrong, you should squash that into the previous patch. And
 as already mentioned, this can probably go into core.c as well.
 
 Pick up the habit *not* to change code in one series which another patch
 of the same series introduced. This only adds *dusty* unused history in the
 patchstack that nobody needs. A *clean* and *coherent* series with discrete
 patches is much easier to review and will get accepted much faster.
 

My rule is do ONE thing at ONE patch, is it not correct?

Previous one[2/14]: Remove the vbus operation at imx glue layer.
This one [3/14]: Fix a bug that vbus may be gotten delay (EPROBE_DEFER),
and vbus is valid at this case.

-- 

Best Regards,
Peter Chen

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/2] usb: chipidea: move vbus regulator operation to core

2013-07-30 Thread Peter Chen
On Tue, Jul 30, 2013 at 02:41:23PM +0200, Michael Grzeschik wrote:
 From: Michael Grzeschik m...@pengutronix.de
 
 This patch moves the regulator code from ci_hdrc_imx gluecode to the
 core layer. It also checks the errorpathes in case the platformglue
 didn't prepare an regulator for this driver.
 
 Signed-off-by: Michael Grzeschik m.grzesc...@pengutronix.de
 ---
  drivers/usb/chipidea/ci_hdrc_imx.c | 26 ++
  drivers/usb/chipidea/core.c| 16 
  include/linux/usb/chipidea.h   |  1 +
  3 files changed, 19 insertions(+), 24 deletions(-)
 
 diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c 
 b/drivers/usb/chipidea/ci_hdrc_imx.c
 index 06bc775..d2937e1 100644
 --- a/drivers/usb/chipidea/ci_hdrc_imx.c
 +++ b/drivers/usb/chipidea/ci_hdrc_imx.c
 @@ -19,7 +19,6 @@
  #include linux/dma-mapping.h
  #include linux/usb/chipidea.h
  #include linux/clk.h
 -#include linux/regulator/consumer.h
  
  #include ci.h
  #include ci_hdrc_imx.h
 @@ -31,7 +30,6 @@ struct ci_hdrc_imx_data {
   struct usb_phy *phy;
   struct platform_device *ci_pdev;
   struct clk *clk;
 - struct regulator *reg_vbus;
  };
  
  static const struct usbmisc_ops *usbmisc_ops;
 @@ -134,20 +132,6 @@ static int ci_hdrc_imx_probe(struct platform_device 
 *pdev)
   goto err_clk;
   }
  
 - /* we only support host now, so enable vbus here */
 - data-reg_vbus = devm_regulator_get(pdev-dev, vbus);
 - if (!IS_ERR(data-reg_vbus)) {
 - ret = regulator_enable(data-reg_vbus);
 - if (ret) {
 - dev_err(pdev-dev,
 - Failed to enable vbus regulator, err=%d\n,
 - ret);
 - goto err_clk;
 - }
 - } else {
 - data-reg_vbus = NULL;
 - }
 -
   pdata.phy = data-phy;
  
   if (!pdev-dev.dma_mask)
 @@ -160,7 +144,7 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
   if (ret) {
   dev_err(pdev-dev,
   usbmisc init failed, ret=%d\n, ret);
 - goto err;
 + goto err_clk;
   }
   }
  
 @@ -172,7 +156,7 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
   dev_err(pdev-dev,
   Can't register ci_hdrc platform device, err=%d\n,
   ret);
 - goto err;
 + goto err_clk;
   }
  
   if (usbmisc_ops  usbmisc_ops-post) {
 @@ -193,9 +177,6 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
  
  disable_device:
   ci_hdrc_remove_device(data-ci_pdev);
 -err:
 - if (data-reg_vbus)
 - regulator_disable(data-reg_vbus);
  err_clk:
   clk_disable_unprepare(data-clk);
   return ret;
 @@ -208,9 +189,6 @@ static int ci_hdrc_imx_remove(struct platform_device 
 *pdev)
   pm_runtime_disable(pdev-dev);
   ci_hdrc_remove_device(data-ci_pdev);
  
 - if (data-reg_vbus)
 - regulator_disable(data-reg_vbus);
 -
   if (data-phy) {
   usb_phy_shutdown(data-phy);
   module_put(data-phy-dev-driver-owner);
 diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
 index a5df24c..178b61d 100644
 --- a/drivers/usb/chipidea/core.c
 +++ b/drivers/usb/chipidea/core.c
 @@ -57,6 +57,7 @@
  #include linux/interrupt.h
  #include linux/io.h
  #include linux/kernel.h
 +#include linux/regulator/consumer.h
  #include linux/slab.h
  #include linux/pm_runtime.h
  #include linux/usb/ch9.h
 @@ -363,6 +364,21 @@ struct platform_device *ci_hdrc_add_device(struct device 
 *dev,
   goto put_id;
   }
  
 + /* Get the vbus regulator */
 + platdata-reg_vbus = devm_regulator_get(dev, vbus);
 + if (PTR_ERR(platdata-reg_vbus) == -EPROBE_DEFER) {
 + ret = -EPROBE_DEFER;
 + goto err;
 + } else if (PTR_ERR(platdata-reg_vbus) == -ENODEV) {
 + platdata-reg_vbus = NULL; /* no vbus regualator is needed */
 + } else if (IS_ERR(platdata-reg_vbus)) {
 + dev_err(pdev-dev,
 + Getting regulator error: %ld\n,
 + PTR_ERR(platdata-reg_vbus));
 + ret = PTR_ERR(platdata-reg_vbus);
 + goto err;
 + }
 +
   pdev-dev.parent = dev;

Michael, thanks to do this for me.

One small suggestion is: it is better add one function like:
ci_get_platdata, and move the vbus stuff to that function.
This function is used to get common thing from glue layer.
And it is better at the beginning of ci_hdrc_add_device,
since the other code at ci_hdrc_add_device are all related to
core device.

I can help to do refine this patch (with some typo which Felipe mentioned)
if you consider it is necessary. I know you may be busy with other things.

-- 

Best Regards,
Peter Chen

--
To unsubscribe from this list: send the line unsubscribe linux-usb

Re: [PATCH 1/2] chipidea: Remove previous MODULE_ALIAS

2013-07-30 Thread Peter Chen
On Tue, Jul 30, 2013 at 10:04:28PM -0300, Fabio Estevam wrote:
 From: Fabio Estevam fabio.este...@freescale.com
 
 After the rename to ci_hdrc we ended up with two MODULE_ALIAS entries, so 
 remove the old one.
 
 Signed-off-by: Fabio Estevam fabio.este...@freescale.com
 ---
  drivers/usb/chipidea/core.c | 1 -
  1 file changed, 1 deletion(-)
 
 diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
 index a5df24c..5cc1b02 100644
 --- a/drivers/usb/chipidea/core.c
 +++ b/drivers/usb/chipidea/core.c
 @@ -548,7 +548,6 @@ static struct platform_driver ci_hdrc_driver = {
  module_platform_driver(ci_hdrc_driver);
  
  MODULE_ALIAS(platform:ci_hdrc);
 -MODULE_ALIAS(platform:ci13xxx);
  MODULE_LICENSE(GPL v2);
  MODULE_AUTHOR(David Lopo dl...@chipidea.mips.com);
  MODULE_DESCRIPTION(ChipIdea HDRC Driver);
 -- 
 1.8.1.2
 
 
Fabio, good eyes.

Reviewed-by: Peter Chen peter.c...@freescale.com

-- 

Best Regards,
Peter Chen

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/2] chipidea: Use devm_request_irq()

2013-07-30 Thread Peter Chen
On Tue, Jul 30, 2013 at 10:04:29PM -0300, Fabio Estevam wrote:
 From: Fabio Estevam fabio.este...@freescale.com
 
 By using devm_request_irq() we don't need to call free_irq(), which simplifies
 the code a bit.
 
 Signed-off-by: Fabio Estevam fabio.este...@freescale.com
 ---
  drivers/usb/chipidea/core.c | 6 ++
  1 file changed, 2 insertions(+), 4 deletions(-)
 
 diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
 index 5cc1b02..d185c41 100644
 --- a/drivers/usb/chipidea/core.c
 +++ b/drivers/usb/chipidea/core.c
 @@ -502,8 +502,8 @@ static int ci_hdrc_probe(struct platform_device *pdev)
   }
  
   platform_set_drvdata(pdev, ci);
 - ret = request_irq(ci-irq, ci_irq, IRQF_SHARED, ci-platdata-name,
 -   ci);
 + ret = devm_request_irq(dev, ci-irq, ci_irq, IRQF_SHARED,
 +ci-platdata-name, ci);
   if (ret)
   goto stop;
  
 @@ -514,7 +514,6 @@ static int ci_hdrc_probe(struct platform_device *pdev)
   if (!ret)
   return 0;
  
 - free_irq(ci-irq, ci);
  stop:
   ci_role_stop(ci);
  rm_wq:
 @@ -531,7 +530,6 @@ static int ci_hdrc_remove(struct platform_device *pdev)
   dbg_remove_files(ci);
   flush_workqueue(ci-wq);
   destroy_workqueue(ci-wq);
 - free_irq(ci-irq, ci);
   ci_role_stop(ci);
  
   return 0;
 -- 
 1.8.1.2
 
 

Reviewed-by: Peter Chen peter.c...@freescale.com

-- 

Best Regards,
Peter Chen

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/2] usb: chipidea: move vbus regulator operation to core

2013-07-31 Thread Peter Chen
On Wed, Jul 31, 2013 at 09:23:56AM +0200, Michael Grzeschik wrote:
 Hi Peter,
 
 On Wed, Jul 31, 2013 at 09:39:50AM +0800, Peter Chen wrote:
  On Tue, Jul 30, 2013 at 02:41:23PM +0200, Michael Grzeschik wrote:
   From: Michael Grzeschik m...@pengutronix.de
   
   This patch moves the regulator code from ci_hdrc_imx gluecode to the
   core layer. It also checks the errorpathes in case the platformglue
   didn't prepare an regulator for this driver.
   
   Signed-off-by: Michael Grzeschik m.grzesc...@pengutronix.de
   ---
drivers/usb/chipidea/ci_hdrc_imx.c | 26 ++
drivers/usb/chipidea/core.c| 16 
include/linux/usb/chipidea.h   |  1 +
3 files changed, 19 insertions(+), 24 deletions(-)
   
   diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c 
   b/drivers/usb/chipidea/ci_hdrc_imx.c
   index 06bc775..d2937e1 100644
   --- a/drivers/usb/chipidea/ci_hdrc_imx.c
   +++ b/drivers/usb/chipidea/ci_hdrc_imx.c
   @@ -19,7 +19,6 @@
#include linux/dma-mapping.h
#include linux/usb/chipidea.h
#include linux/clk.h
   -#include linux/regulator/consumer.h

#include ci.h
#include ci_hdrc_imx.h
   @@ -31,7 +30,6 @@ struct ci_hdrc_imx_data {
 struct usb_phy *phy;
 struct platform_device *ci_pdev;
 struct clk *clk;
   - struct regulator *reg_vbus;
};

static const struct usbmisc_ops *usbmisc_ops;
   @@ -134,20 +132,6 @@ static int ci_hdrc_imx_probe(struct platform_device 
   *pdev)
 goto err_clk;
 }

   - /* we only support host now, so enable vbus here */
   - data-reg_vbus = devm_regulator_get(pdev-dev, vbus);
   - if (!IS_ERR(data-reg_vbus)) {
   - ret = regulator_enable(data-reg_vbus);
   - if (ret) {
   - dev_err(pdev-dev,
   - Failed to enable vbus regulator, err=%d\n,
   - ret);
   - goto err_clk;
   - }
   - } else {
   - data-reg_vbus = NULL;
   - }
   -
 pdata.phy = data-phy;

 if (!pdev-dev.dma_mask)
   @@ -160,7 +144,7 @@ static int ci_hdrc_imx_probe(struct platform_device 
   *pdev)
 if (ret) {
 dev_err(pdev-dev,
 usbmisc init failed, ret=%d\n, ret);
   - goto err;
   + goto err_clk;
 }
 }

   @@ -172,7 +156,7 @@ static int ci_hdrc_imx_probe(struct platform_device 
   *pdev)
 dev_err(pdev-dev,
 Can't register ci_hdrc platform device, err=%d\n,
 ret);
   - goto err;
   + goto err_clk;
 }

 if (usbmisc_ops  usbmisc_ops-post) {
   @@ -193,9 +177,6 @@ static int ci_hdrc_imx_probe(struct platform_device 
   *pdev)

disable_device:
 ci_hdrc_remove_device(data-ci_pdev);
   -err:
   - if (data-reg_vbus)
   - regulator_disable(data-reg_vbus);
err_clk:
 clk_disable_unprepare(data-clk);
 return ret;
   @@ -208,9 +189,6 @@ static int ci_hdrc_imx_remove(struct platform_device 
   *pdev)
 pm_runtime_disable(pdev-dev);
 ci_hdrc_remove_device(data-ci_pdev);

   - if (data-reg_vbus)
   - regulator_disable(data-reg_vbus);
   -
 if (data-phy) {
 usb_phy_shutdown(data-phy);
 module_put(data-phy-dev-driver-owner);
   diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
   index a5df24c..178b61d 100644
   --- a/drivers/usb/chipidea/core.c
   +++ b/drivers/usb/chipidea/core.c
   @@ -57,6 +57,7 @@
#include linux/interrupt.h
#include linux/io.h
#include linux/kernel.h
   +#include linux/regulator/consumer.h
#include linux/slab.h
#include linux/pm_runtime.h
#include linux/usb/ch9.h
   @@ -363,6 +364,21 @@ struct platform_device *ci_hdrc_add_device(struct 
   device *dev,
 goto put_id;
 }

   + /* Get the vbus regulator */
   + platdata-reg_vbus = devm_regulator_get(dev, vbus);
   + if (PTR_ERR(platdata-reg_vbus) == -EPROBE_DEFER) {
   + ret = -EPROBE_DEFER;
   + goto err;
   + } else if (PTR_ERR(platdata-reg_vbus) == -ENODEV) {
   + platdata-reg_vbus = NULL; /* no vbus regualator is needed */
   + } else if (IS_ERR(platdata-reg_vbus)) {
   + dev_err(pdev-dev,
   + Getting regulator error: %ld\n,
   + PTR_ERR(platdata-reg_vbus));
   + ret = PTR_ERR(platdata-reg_vbus);
   + goto err;
   + }
   +
 pdev-dev.parent = dev;
  
  Michael, thanks to do this for me.
  
  One small suggestion is: it is better add one function like:
  ci_get_platdata, and move the vbus stuff to that function.
  This function is used to get common thing from glue layer.
  And it is better at the beginning of ci_hdrc_add_device,
  since the other code at ci_hdrc_add_device are all related to
  core device.
  
  I can help to do refine this patch (with some typo which Felipe mentioned

Re: [PATCH 2/2] chipidea: Use devm_request_irq()

2013-07-31 Thread Peter Chen
On Wed, Jul 31, 2013 at 09:33:06AM +0200, Uwe Kleine-König wrote:
 On Tue, Jul 30, 2013 at 10:04:29PM -0300, Fabio Estevam wrote:
  From: Fabio Estevam fabio.este...@freescale.com
  
  By using devm_request_irq() we don't need to call free_irq(), which 
  simplifies
  the code a bit.
  
  Signed-off-by: Fabio Estevam fabio.este...@freescale.com
  ---
   drivers/usb/chipidea/core.c | 6 ++
   1 file changed, 2 insertions(+), 4 deletions(-)
  
  diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
  index 5cc1b02..d185c41 100644
  --- a/drivers/usb/chipidea/core.c
  +++ b/drivers/usb/chipidea/core.c
  @@ -502,8 +502,8 @@ static int ci_hdrc_probe(struct platform_device *pdev)
  }
   
  platform_set_drvdata(pdev, ci);
  -   ret = request_irq(ci-irq, ci_irq, IRQF_SHARED, ci-platdata-name,
  - ci);
  +   ret = devm_request_irq(dev, ci-irq, ci_irq, IRQF_SHARED,
  +  ci-platdata-name, ci);
 Mark Brown (now on Cc:) replied to one of my patches using
 devm_request_irq:
 
   I'm always deeply suspicous of devm_request_irq() since you need
   to be *very* sure that the interrupt can't fire during cleanup
   and cause the handlers to try to use data structures that are
   already being freed.
 
 and:
 
   devm_request_threaded_irq() is just generally a bit of a warning
   sign since it needs careful checking to tell if it's safe.
 

The probably problem I find is the free_irq will be called after
driver's removal is called, then the problem Mark described will occur.
See __device_release_driver(struct device *dev) at drivers/base/dd.c.

-- 

Best Regards,
Peter Chen

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/2] chipidea: Use devm_request_irq()

2013-07-31 Thread Peter Chen
On Wed, Jul 31, 2013 at 9:27 PM, Mark Brown broo...@kernel.org wrote:
 On Wed, Jul 31, 2013 at 07:55:27AM -0400, Tejun Heo wrote:

 If you have DMA / IRQ / command engine deactivations in devm path
 which often is the case with full conversions, freeing any resources
 including DMA areas and host private data in the wrong order is a
 horrible idea.  It's worse as it won't really be noticeable in most
 cases.

 It's really only interrupts that affect most devices - if there's DMA or
 anything going on after the remove() then as you said earlier the driver
 is probably doing something wrong.

I think the main point is we should allocate managed resource which is used
at interrupt handler before devm_request_irq, and all resources used
at interrupt
handler should be managed.

If we use non-managed resource at interrupt handler, but using managed interrupt
handler, things still will go wrong if there is an odd (unexpected)
interrupt after
we finish deactivation at removal.

-- 
BR,
Peter Chen
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/2] chipidea: Use devm_request_irq()

2013-07-31 Thread Peter Chen
On Wed, Jul 31, 2013 at 10:15:12AM -0400, Tejun Heo wrote:
 hello,
 
 On Wed, Jul 31, 2013 at 09:55:26PM +0800, Peter Chen wrote:
  I think the main point is we should allocate managed resource which is used
  at interrupt handler before devm_request_irq, and all resources used
  at interrupt
  handler should be managed.
  
  If we use non-managed resource at interrupt handler, but using managed 
  interrupt
  handler, things still will go wrong if there is an odd (unexpected)
  interrupt after
  we finish deactivation at removal.
 
 In general, applying devm partially isn't a good idea.  It's very easy
 to get into trouble thanks to release order dependency which isn't
 immediately noticeable and there have been actual bugs caused by that.
 The strategies which seem to work are either
 
 * Convert everything over to devm by wrapping deactivation in a devres
   callback too.  As long as your init sequence is sane (ie. irq
   shouldn't be request before things used by irq are ready).
 
 * Allocate all resources using devres but shut down the execution
   engine in the remove_one().  Again, as all releases are controlled
   by devres, you won't have to worry about messing up the release
   sequencing.
 

thanks, Tejun. So, Alex and Fabio, this patch may not be suitable currently,
since many resources at both EHCI and device side are non-managed.
-- 

Best Regards,
Peter Chen

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/4] usb: chipidea: improve kconfig 2.0

2013-07-31 Thread Peter Chen
On Wed, Jul 31, 2013 at 04:21:13PM +0200, Lothar Waßmann wrote:
 This patch provides a cleaner solution to the problem described in
 commit 20a677fd.
 
 The goal to be achieved is to force USB_CHIPIDEA=m if either
 USB_EHCI_HCD=m or USB_GADGET=m.
 If both are 'y' USB_CHIPIDEA may be selected to be 'm' or 'y'.
 
 The old patch had the drawback, that USB_CHIPIDEA could be chosen as
 'y' though USB_EHCI_HCD or USB_GADGET (or both) were 'm' leading to a
 situation where USB_CHIPIDEA_HOST or USB_CHIPIDEA_UDC vanished from
 the config options producing a compilable but dysfunctional driver.
 
 Signed-off-by: Lothar Waßmann l...@karo-electronics.de
 ---
  drivers/usb/chipidea/Kconfig |7 +++
  1 files changed, 3 insertions(+), 4 deletions(-)
 
 diff --git a/drivers/usb/chipidea/Kconfig b/drivers/usb/chipidea/Kconfig
 index d1bd8ef..4a851e1 100644
 --- a/drivers/usb/chipidea/Kconfig
 +++ b/drivers/usb/chipidea/Kconfig
 @@ -1,6 +1,6 @@
  config USB_CHIPIDEA
   tristate ChipIdea Highspeed Dual Role Controller
 - depends on USB || USB_GADGET
 + depends on (USB_EHCI_HCD  USB_GADGET) || (USB_EHCI_HCD  
 !USB_GADGET) || (!USB_EHCI_HCD  USB_GADGET)
   help
 Say Y here if your system has a dual role high speed USB
 controller based on ChipIdea silicon IP. Currently, only the
 @@ -12,15 +12,14 @@ if USB_CHIPIDEA
  
  config USB_CHIPIDEA_UDC
   bool ChipIdea device controller
 - depends on USB_GADGET=y || (USB_CHIPIDEA=m  USB_GADGET=m)
 + depends on USB_GADGET
   help
 Say Y here to enable device controller functionality of the
 ChipIdea driver.
  
  config USB_CHIPIDEA_HOST
   bool ChipIdea host controller
 - depends on USB=y
 - depends on USB_EHCI_HCD=y || (USB_CHIPIDEA=m  USB_EHCI_HCD=m)
 + depends on USB_EHCI_HCD
   select USB_EHCI_ROOT_HUB_TT
   help
 Say Y here to enable host controller functionality of the
 -- 

Reviewed-by: Peter Chen peter.c...@freescale.com

Hi Alex,

Lothar's solution is better than mine, please forget mine:
http://marc.info/?l=linux-usbm=137331577104110w=2

After you apply Lothar's patch, please also apply mine fixup
ehci host's config patch
http://marc.info/?l=linux-usbm=137331577404223w=2

-- 

Best Regards,
Peter Chen

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/4] usb: chipidea: ci_hdrc_imx: remove an unsolicited module_put() call from ci_hdrc_imx_remove()

2013-08-01 Thread Peter Chen
On Wed, Jul 31, 2013 at 04:21:14PM +0200, Lothar Waßmann wrote:
 This prevents the USB PHY refcount to be decremented below zero upon
 unloading the ci-hdrc-imx module.
 
 Signed-off-by: Lothar Waßmann l...@karo-electronics.de
 ---
  drivers/usb/chipidea/ci_hdrc_imx.c |4 +---
  1 files changed, 1 insertions(+), 3 deletions(-)
 
 diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c 
 b/drivers/usb/chipidea/ci_hdrc_imx.c
 index 14362c0..802eab1 100644
 --- a/drivers/usb/chipidea/ci_hdrc_imx.c
 +++ b/drivers/usb/chipidea/ci_hdrc_imx.c
 @@ -218,10 +218,8 @@ static int ci_hdrc_imx_remove(struct platform_device 
 *pdev)
   if (data-reg_vbus)
   regulator_disable(data-reg_vbus);
  
 - if (data-phy) {
 + if (data-phy)
   usb_phy_shutdown(data-phy);
 - module_put(data-phy-dev-driver-owner);
 - }
  
   clk_disable_unprepare(data-clk);

Have you met warning? devm_usb_get_phy_by_phandle at probe calls
try_module_get.

-- 

Best Regards,
Peter Chen

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 3/4] usb: chipidea: don't clobber return value of ci_role_start()

2013-08-01 Thread Peter Chen
On Wed, Jul 31, 2013 at 04:21:15PM +0200, Lothar Waßmann wrote:
 
 Signed-off-by: Lothar Waßmann l...@karo-electronics.de
 ---
  drivers/usb/chipidea/core.c |1 -
  1 files changed, 0 insertions(+), 1 deletions(-)
 
 diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
 index a5df24c..38b0a7a 100644
 --- a/drivers/usb/chipidea/core.c
 +++ b/drivers/usb/chipidea/core.c
 @@ -497,7 +497,6 @@ static int ci_hdrc_probe(struct platform_device *pdev)
   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;
   }
  

+1, it can help get the error one time, without need to add the code
and get the error number from ci_role_start again.

-- 

Best Regards,
Peter Chen

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 4/4] usb: chipidea: Prevent endless loop registering platform_devices when ci_hdrc_probe() fails.

2013-08-01 Thread Peter Chen
On Wed, Jul 31, 2013 at 04:21:16PM +0200, Lothar Waßmann wrote:
 commit 40dcd0e introduced the following code to the ci_hdrc_probe()
 function:
 
 +   if (!dev-of_node  dev-parent)
 +   dev-of_node = dev-parent-of_node;
 
 This inadvertently associates the ci_hdrc device with the ci_hdrc_imx
 driver (which created the ci_hdrc device in the first place).
 
 This results in ci_hdrc_imx_probe() being run for the ci_hdrc device
 if ci_hdrc_probe() fails for some reason.
 ci_hdrc_imx_probe() will happily create a new ci_hdrc platform_device
 whose probing will likewise fail and trigger a new invocation of
 ci_hdrc_imx_probe() ... ad nauseam.
 

Sorry, I can't understand how it happenes?

-- 

Best Regards,
Peter Chen

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/4] usb: chipidea: ci_hdrc_imx: remove an unsolicited module_put() call from ci_hdrc_imx_remove()

2013-08-01 Thread Peter Chen
On Thu, Aug 01, 2013 at 10:38:18AM +0200, Lothar Waßmann wrote:
 Hi,
 
 Peter Chen writes:
  On Wed, Jul 31, 2013 at 04:21:14PM +0200, Lothar Waßmann wrote:
   This prevents the USB PHY refcount to be decremented below zero upon
   unloading the ci-hdrc-imx module.
   
   Signed-off-by: Lothar Waßmann l...@karo-electronics.de
   ---
drivers/usb/chipidea/ci_hdrc_imx.c |4 +---
1 files changed, 1 insertions(+), 3 deletions(-)
   
   diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c 
   b/drivers/usb/chipidea/ci_hdrc_imx.c
   index 14362c0..802eab1 100644
   --- a/drivers/usb/chipidea/ci_hdrc_imx.c
   +++ b/drivers/usb/chipidea/ci_hdrc_imx.c
   @@ -218,10 +218,8 @@ static int ci_hdrc_imx_remove(struct platform_device 
   *pdev)
 if (data-reg_vbus)
 regulator_disable(data-reg_vbus);

   - if (data-phy) {
   + if (data-phy)
 usb_phy_shutdown(data-phy);
   - module_put(data-phy-dev-driver-owner);
   - }

 clk_disable_unprepare(data-clk);
  
  Have you met warning? devm_usb_get_phy_by_phandle at probe calls
  try_module_get.
  
 Since it is a 'devm_*' function I would vouch that it also takes care
 of the module_put() automagically.
 
 Just try loading and unloading the ci-hdrc-imx module and look at the
 resulting refcount of the mxs_usb_phy module.
 
 refcounting is OK without the module_put() here.
 

Oh, yes, it calls module_put at usb_put_phy when devm_xxx_release is
called.

Acked-by: Peter Chen peter.c...@freescale.com

-- 

Best Regards,
Peter Chen

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 3/4] usb: chipidea: don't clobber return value of ci_role_start()

2013-08-01 Thread Peter Chen
On Thu, Aug 01, 2013 at 10:40:42AM +0200, Lothar Waßmann wrote:
 Hi,
 
 Peter Chen writes:
  On Wed, Jul 31, 2013 at 04:21:15PM +0200, Lothar Waßmann wrote:
   
   Signed-off-by: Lothar Waßmann l...@karo-electronics.de
   ---
drivers/usb/chipidea/core.c |1 -
1 files changed, 0 insertions(+), 1 deletions(-)
   
   diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
   index a5df24c..38b0a7a 100644
   --- a/drivers/usb/chipidea/core.c
   +++ b/drivers/usb/chipidea/core.c
   @@ -497,7 +497,6 @@ static int ci_hdrc_probe(struct platform_device *pdev)
 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;
 }

  
  +1, it can help get the error one time, without need to add the code
  and get the error number from ci_role_start again.
  
 I don't get what you mean.
 

For example, the ci_role_start returns error, the user can't
get error message directly, it can only get -ENODEV. If
the user wants to get what's error at ci_role_start, he
needs to add another debug message and re-compile the kernel.

-- 

Best Regards,
Peter Chen

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 4/4] usb: chipidea: Prevent endless loop registering platform_devices when ci_hdrc_probe() fails.

2013-08-01 Thread Peter Chen
On Thu, Aug 01, 2013 at 10:43:52AM +0200, Lothar Waßmann wrote:
 Hi,
 
 Peter Chen writes:
  On Wed, Jul 31, 2013 at 04:21:16PM +0200, Lothar Waßmann wrote:
   commit 40dcd0e introduced the following code to the ci_hdrc_probe()
   function:
   
   +   if (!dev-of_node  dev-parent)
   +   dev-of_node = dev-parent-of_node;
   
   This inadvertently associates the ci_hdrc device with the ci_hdrc_imx
   driver (which created the ci_hdrc device in the first place).
   
   This results in ci_hdrc_imx_probe() being run for the ci_hdrc device
   if ci_hdrc_probe() fails for some reason.
   ci_hdrc_imx_probe() will happily create a new ci_hdrc platform_device
   whose probing will likewise fail and trigger a new invocation of
   ci_hdrc_imx_probe() ... ad nauseam.
   
  
  Sorry, I can't understand how it happenes?
  
 If ci_hdrc_probe() fails, the driver core will look for other drivers
 that might be able to handle the device. Since the of_node has been
 copied from the parent device imx_usb the driver responsible for
 the DT match of of_node (ci_hdrc_imx) will be called.
 

Good fix.

Reviewed-and-Tested-by: Peter Chen peter.c...@freescale.com

-- 

Best Regards,
Peter Chen

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: USB Interrupt Transaction Scheduling

2013-08-01 Thread Peter Chen
On Thu, Aug 01, 2013 at 12:14:18PM -0300, Fabio Estevam wrote:
 Hi Nate,
 
 On Tue, Jul 30, 2013 at 6:33 PM, Stoddard, Nate (GE Healthcare)
 nate.stodd...@med.ge.com wrote:
 
  So you would expect a temporary CPU increase when a device is connected or 
  reset since the scheduler will need to set up when the packets will be 
  transferred.  Once this is complete, the CPU should return to a lower 
  amount as
 
 The reset function at drivers/usb/chipidea/core.c has the following:
 
 int hw_device_reset(struct ci_hdrc *ci, u32 mode)
 {
   /* should flush  stop before reset */
   hw_write(ci, OP_ENDPTFLUSH, ~0, ~0);
   hw_write(ci, OP_USBCMD, USBCMD_RS, 0);
 
   hw_write(ci, OP_USBCMD, USBCMD_RST, USBCMD_RST);
   while (hw_read(ci, OP_USBCMD, USBCMD_RST))
   udelay(10); /* not RTOS friendly */
 
 Maybe this udelay is impacting your performance?
 
 It seems that this should be rewritten to avoid the busy loop.
 

No, it is not related to this problem, this function is only called
at device mode. All EHCI related is controlled by EHCI core. Currently, 
we still not override anything for host.

-- 

Best Regards,
Peter Chen

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: USB Interrupt Transaction Scheduling

2013-08-01 Thread Peter Chen
On Tue, Jul 30, 2013 at 09:33:39PM +, Stoddard, Nate (GE Healthcare) wrote:
 
  
  The driver has to set up the data structures for the transfers, which 
  includes
  scheduling when the SSPLIT and CSPLIT transactions will occur and figuring
  out how much bandwidth they will consume.  The transactions themselves
  are handled entirely by the EHCI hardware.
  
 
 So you would expect a temporary CPU increase when a device is connected or 
 reset since the scheduler will need to set up when the packets will be 
 transferred.  Once this is complete, the CPU should return to a lower amount 
 as the EHCI hardware would be processing the various packet sending:  setup 
 tokens, ACK/NAK handshaking, and split packets?
 
 I ask because we are seeing much higher constant CPU usage on our target 
 hardware (iMX535) than we are seeing on the test PC.  Do you have any 
 recommendations for a good way to confirm the target EHCI hardware is being 
 utilized?  Is there a location to instrument in one of the ehci host files 
 (ehci-hcd.c or ehci-q.c)?
 

When the transfer begins, the things are almost the same for all SoCs.
The possible reason is you may use an old kernel (2.6.35), and EHCI core
is improved. At your old email, you said the cpu utilities will be
less at higher kernel version at PC. I think the best way is using
newest kernel and newest libusb. Try to find a mx53 board which
is supported by upstream kernel, and re-do the test.

 
I don't see how you could have gotten more than 15 interrupt
endpoints running at the same time unless the endpoints' bInterval
value was larger than 1.
   
On all 7 devices, the IN and OUT interrupt endpoints have bInterval =
   1 wMaxPacketSize = 64.
  
  Do you think this is worth pursuing?  It sounds like a bug, although it 
  might
  not be.
  
 
 We will re-run the tests with more rigor to confirm the results.  I will post 
 the details.
 
 -Nate
 --
 To unsubscribe from this list: send the line unsubscribe linux-usb in
 the body of a message to majord...@vger.kernel.org
 More majordomo info at  http://vger.kernel.org/majordomo-info.html
 

-- 

Best Regards,
Peter Chen

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v14 01/12] usb: chipidea: move vbus regulator operation to core

2013-08-02 Thread Peter Chen
The vbus regulator is a common element for USB vbus operation,
So, move it from glue layer to core.

Tested-by: Marek Vasut ma...@denx.de
Signed-off-by: Michael Grzeschik m.grzesc...@pengutronix.de
Signed-off-by: Peter Chen peter.c...@freescale.com
---
 drivers/usb/chipidea/ci_hdrc_imx.c |   26 ++
 drivers/usb/chipidea/core.c|   23 +++
 include/linux/usb/chipidea.h   |1 +
 3 files changed, 26 insertions(+), 24 deletions(-)

diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c 
b/drivers/usb/chipidea/ci_hdrc_imx.c
index e04611f..b886998 100644
--- a/drivers/usb/chipidea/ci_hdrc_imx.c
+++ b/drivers/usb/chipidea/ci_hdrc_imx.c
@@ -19,7 +19,6 @@
 #include linux/dma-mapping.h
 #include linux/usb/chipidea.h
 #include linux/clk.h
-#include linux/regulator/consumer.h
 
 #include ci.h
 #include ci_hdrc_imx.h
@@ -31,7 +30,6 @@ struct ci_hdrc_imx_data {
struct usb_phy *phy;
struct platform_device *ci_pdev;
struct clk *clk;
-   struct regulator *reg_vbus;
 };
 
 static const struct usbmisc_ops *usbmisc_ops;
@@ -134,20 +132,6 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
goto err_clk;
}
 
-   /* we only support host now, so enable vbus here */
-   data-reg_vbus = devm_regulator_get(pdev-dev, vbus);
-   if (!IS_ERR(data-reg_vbus)) {
-   ret = regulator_enable(data-reg_vbus);
-   if (ret) {
-   dev_err(pdev-dev,
-   Failed to enable vbus regulator, err=%d\n,
-   ret);
-   goto err_clk;
-   }
-   } else {
-   data-reg_vbus = NULL;
-   }
-
pdata.phy = data-phy;
 
if (!pdev-dev.dma_mask)
@@ -160,7 +144,7 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
if (ret) {
dev_err(pdev-dev,
usbmisc init failed, ret=%d\n, ret);
-   goto err;
+   goto err_clk;
}
}
 
@@ -172,7 +156,7 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
dev_err(pdev-dev,
Can't register ci_hdrc platform device, err=%d\n,
ret);
-   goto err;
+   goto err_clk;
}
 
if (usbmisc_ops  usbmisc_ops-post) {
@@ -193,9 +177,6 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
 
 disable_device:
ci_hdrc_remove_device(data-ci_pdev);
-err:
-   if (data-reg_vbus)
-   regulator_disable(data-reg_vbus);
 err_clk:
clk_disable_unprepare(data-clk);
return ret;
@@ -208,9 +189,6 @@ static int ci_hdrc_imx_remove(struct platform_device *pdev)
pm_runtime_disable(pdev-dev);
ci_hdrc_remove_device(data-ci_pdev);
 
-   if (data-reg_vbus)
-   regulator_disable(data-reg_vbus);
-
if (data-phy)
usb_phy_shutdown(data-phy);
 
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index 3126c03..26f6599 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -65,6 +65,7 @@
 #include linux/usb/chipidea.h
 #include linux/usb/of.h
 #include linux/phy.h
+#include linux/regulator/consumer.h
 
 #include ci.h
 #include udc.h
@@ -342,6 +343,24 @@ static irqreturn_t ci_irq(int irq, void *data)
return ret;
 }
 
+static int ci_get_platdata(struct device *dev,
+   struct ci_hdrc_platform_data *platdata)
+{
+   /* Get the vbus regulator */
+   platdata-reg_vbus = devm_regulator_get(dev, vbus);
+   if (PTR_ERR(platdata-reg_vbus) == -EPROBE_DEFER) {
+   return -EPROBE_DEFER;
+   } else if (PTR_ERR(platdata-reg_vbus) == -ENODEV) {
+   platdata-reg_vbus = NULL; /* no vbus regualator is needed */
+   } else if (IS_ERR(platdata-reg_vbus)) {
+   dev_err(dev, Getting regulator error: %ld\n,
+   PTR_ERR(platdata-reg_vbus));
+   return PTR_ERR(platdata-reg_vbus);
+   }
+
+   return 0;
+}
+
 static DEFINE_IDA(ci_ida);
 
 struct platform_device *ci_hdrc_add_device(struct device *dev,
@@ -351,6 +370,10 @@ struct platform_device *ci_hdrc_add_device(struct device 
*dev,
struct platform_device *pdev;
int id, ret;
 
+   ret = ci_get_platdata(dev, platdata);
+   if (ret)
+   return ERR_PTR(ret);
+
id = ida_simple_get(ci_ida, 0, 0, GFP_KERNEL);
if (id  0)
return ERR_PTR(id);
diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h
index 2562994..ce4e1aa 100644
--- a/include/linux/usb/chipidea.h
+++ b/include/linux/usb/chipidea.h
@@ -24,6 +24,7 @@ struct ci_hdrc_platform_data {
 #define CI_HDRC_CONTROLLER_RESET_EVENT 0
 #define CI_HDRC_CONTROLLER_STOPPED_EVENT   1
void(*notify_event) (struct ci_hdrc *ci

[PATCH v14 04/12] usb: chipidea: otg: Add otg file used to access otgsc

2013-08-02 Thread Peter Chen
This file is mainly used to access otgsc currently, it may
add otg related things in the future.

Tested-by: Marek Vasut ma...@denx.de
Signed-off-by: Peter Chen peter.c...@freescale.com
---
 drivers/usb/chipidea/Makefile |2 +-
 drivers/usb/chipidea/bits.h   |   10 
 drivers/usb/chipidea/core.c   |3 +-
 drivers/usb/chipidea/otg.c|   50 +
 drivers/usb/chipidea/otg.h|   19 +++
 5 files changed, 82 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/chipidea/Makefile b/drivers/usb/chipidea/Makefile
index 6cf5f68..a99d980 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/bits.h b/drivers/usb/chipidea/bits.h
index aefa026..dd0cf9e 100644
--- a/drivers/usb/chipidea/bits.h
+++ b/drivers/usb/chipidea/bits.h
@@ -79,11 +79,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/core.c b/drivers/usb/chipidea/core.c
index 26f6599..a4be8a5 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -72,6 +72,7 @@
 #include bits.h
 #include host.h
 #include debug.h
+#include otg.h
 
 /* Controller register map */
 static uintptr_t ci_regs_nolpm[] = {
@@ -530,7 +531,7 @@ static int ci_hdrc_probe(struct platform_device *pdev)
goto stop;
 
if (ci-is_otg)
-   hw_write(ci, OP_OTGSC, OTGSC_IDIE, OTGSC_IDIE);
+   ci_hdrc_otg_init(ci);
 
ret = dbg_create_files(ci);
if (!ret)
diff --git a/drivers/usb/chipidea/otg.c b/drivers/usb/chipidea/otg.c
new file mode 100644
index 000..abefb4d
--- /dev/null
+++ b/drivers/usb/chipidea/otg.c
@@ -0,0 +1,50 @@
+/*
+ * otg.c - ChipIdea USB IP core OTG driver
+ *
+ * Copyright (C) 2013 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.
+ */
+
+/*
+ * This file mainly handles otgsc register, it may include OTG operation
+ * in the future.
+ */
+
+#include linux/usb/otg.h
+#include linux/usb/gadget.h
+#include linux/usb/chipidea.h
+
+#include ci.h
+#include bits.h
+
+void ci_clear_otg_interrupt(struct ci_hdrc *ci, u32 bits)
+{
+   /* Only clear request bits */
+   hw_write(ci, OP_OTGSC, OTGSC_INT_STATUS_BITS, bits);
+}
+
+void ci_enable_otg_interrupt(struct ci_hdrc *ci, u32 bits)
+{
+   hw_write(ci, OP_OTGSC, bits, bits);
+}
+
+void ci_disable_otg_interrupt(struct ci_hdrc *ci, u32 bits)
+{
+   hw_write(ci, OP_OTGSC, bits, 0);
+}
+
+/**
+ * ci_hdrc_otg_init - initialize otgsc bits
+ * ci: the controller
+ */
+int ci_hdrc_otg_init(struct ci_hdrc *ci)
+{
+   ci_enable_otg_interrupt(ci, OTGSC_IDIE);
+
+   return 0;
+}
diff --git a/drivers/usb/chipidea/otg.h b/drivers/usb/chipidea/otg.h
new file mode 100644
index 000..f24ec37
--- /dev/null
+++ b/drivers/usb/chipidea/otg.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2013 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.
+ */
+
+#ifndef __DRIVERS_USB_CHIPIDEA_OTG_H
+#define __DRIVERS_USB_CHIPIDEA_OTG_H
+
+int ci_hdrc_otg_init(struct ci_hdrc *ci);
+void ci_clear_otg_interrupt(struct ci_hdrc *ci, u32 bits);
+void ci_enable_otg_interrupt(struct ci_hdrc *ci, u32 bits);
+void ci_disable_otg_interrupt(struct ci_hdrc *ci, u32 bits);
+
+#endif /* __DRIVERS_USB_CHIPIDEA_OTG_H */
-- 
1.7.0.4


--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body

[PATCH v14 05/12] usb: chipidea: Add role init and destory APIs

2013-08-02 Thread Peter Chen
- The role's init will be called at probe procedure.
- The role's destory will be called at fail patch
at probe and driver's removal.
- The role's start/stop will be called when specific
role has started.

Tested-by: Marek Vasut ma...@denx.de
Signed-off-by: Peter Chen peter.c...@freescale.com
---
 drivers/usb/chipidea/core.c |   10 --
 drivers/usb/chipidea/host.c |7 +++
 drivers/usb/chipidea/host.h |6 ++
 drivers/usb/chipidea/udc.c  |   36 +++-
 drivers/usb/chipidea/udc.h  |6 ++
 5 files changed, 54 insertions(+), 11 deletions(-)

diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index a4be8a5..bfc9aef 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -420,6 +420,12 @@ void ci_hdrc_remove_device(struct platform_device *pdev)
 }
 EXPORT_SYMBOL_GPL(ci_hdrc_remove_device);
 
+static inline void ci_role_destroy(struct ci_hdrc *ci)
+{
+   ci_hdrc_gadget_destroy(ci);
+   ci_hdrc_host_destroy(ci);
+}
+
 static int ci_hdrc_probe(struct platform_device *pdev)
 {
struct device   *dev = pdev-dev;
@@ -539,7 +545,7 @@ static int ci_hdrc_probe(struct platform_device *pdev)
 
free_irq(ci-irq, ci);
 stop:
-   ci_role_stop(ci);
+   ci_role_destroy(ci);
 rm_wq:
flush_workqueue(ci-wq);
destroy_workqueue(ci-wq);
@@ -555,7 +561,7 @@ static int ci_hdrc_remove(struct platform_device *pdev)
flush_workqueue(ci-wq);
destroy_workqueue(ci-wq);
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 e94e52b..382be5b 100644
--- a/drivers/usb/chipidea/host.c
+++ b/drivers/usb/chipidea/host.c
@@ -105,6 +105,13 @@ static void host_stop(struct ci_hdrc *ci)
regulator_disable(ci-platdata-reg_vbus);
 }
 
+
+void ci_hdrc_host_destroy(struct ci_hdrc *ci)
+{
+   if (ci-role == CI_ROLE_HOST)
+   host_stop(ci);
+}
+
 int ci_hdrc_host_init(struct ci_hdrc *ci)
 {
struct ci_role_driver *rdrv;
diff --git a/drivers/usb/chipidea/host.h b/drivers/usb/chipidea/host.h
index 058875c..5707bf3 100644
--- a/drivers/usb/chipidea/host.h
+++ b/drivers/usb/chipidea/host.h
@@ -4,6 +4,7 @@
 #ifdef CONFIG_USB_CHIPIDEA_HOST
 
 int ci_hdrc_host_init(struct ci_hdrc *ci);
+void ci_hdrc_host_destroy(struct ci_hdrc *ci);
 
 #else
 
@@ -12,6 +13,11 @@ static inline int ci_hdrc_host_init(struct ci_hdrc *ci)
return -ENXIO;
 }
 
+static inline void ci_hdrc_host_destroy(struct ci_hdrc *ci)
+{
+
+}
+
 #endif
 
 #endif /* __DRIVERS_USB_CHIPIDEA_HOST_H */
diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
index 116c762..24a100d 100644
--- a/drivers/usb/chipidea/udc.c
+++ b/drivers/usb/chipidea/udc.c
@@ -27,6 +27,7 @@
 #include udc.h
 #include bits.h
 #include debug.h
+#include otg.h
 
 /* control endpoint description */
 static const struct usb_endpoint_descriptor
@@ -1844,13 +1845,13 @@ free_qh_pool:
 }
 
 /**
- * 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 ci_hdrc *ci)
+void ci_hdrc_gadget_destroy(struct ci_hdrc *ci)
 {
-   if (ci == NULL)
+   if (!ci-roles[CI_ROLE_GADGET])
return;
 
usb_del_gadget_udc(ci-gadget);
@@ -1865,15 +1866,32 @@ static void udc_stop(struct ci_hdrc *ci)
if (ci-global_phy)
usb_put_phy(ci-transceiver);
}
-   /* my kobject is dynamic, I swear! */
-   memset(ci-gadget, 0, sizeof(ci-gadget));
+}
+
+static int udc_id_switch_for_device(struct ci_hdrc *ci)
+{
+   if (ci-is_otg) {
+   ci_clear_otg_interrupt(ci, OTGSC_BSVIS);
+   ci_enable_otg_interrupt(ci, OTGSC_BSVIE);
+   }
+
+   return 0;
+}
+
+static void udc_id_switch_for_host(struct ci_hdrc *ci)
+{
+   if (ci-is_otg) {
+   /* host doesn't care B_SESSION_VALID event */
+   ci_clear_otg_interrupt(ci, OTGSC_BSVIS);
+   ci_disable_otg_interrupt(ci, OTGSC_BSVIE);
+   }
 }
 
 /**
  * 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 the gadget, if the device is device capable.
  */
 int ci_hdrc_gadget_init(struct ci_hdrc *ci)
 {
@@ -1886,11 +1904,11 @@ int ci_hdrc_gadget_init(struct ci_hdrc *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

[PATCH v14 06/12] usb: chipidea: add flag CI_HDRC_DUAL_ROLE_NOT_OTG

2013-08-02 Thread Peter Chen
Since we need otgsc to know vbus's status at some chipidea
controllers even it is peripheral-only mode. Besides, some
SoCs (eg, AR9331 SoC) don't have otgsc register even
the DCCPARAMS_DC and DCCPARAMS_HC are both 1 at CAP_DCCPARAMS.

We inroduce flag CI_HDRC_DUAL_ROLE_NOT_OTG to indicate if the
controller is dual role, but not supports OTG. If this flag is
not set, we follow the rule that if DCCPARAMS_DC and DCCPARAMS_HC
are both 1 at CAP_DCCPARAMS, then this controller is otg capable.

Signed-off-by: Peter Chen peter.c...@freescale.com
---
 drivers/usb/chipidea/core.c  |   38 +++---
 include/linux/usb/chipidea.h |5 +
 2 files changed, 36 insertions(+), 7 deletions(-)

diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index bfc9aef..2ae18fd 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -426,6 +426,18 @@ static inline void ci_role_destroy(struct ci_hdrc *ci)
ci_hdrc_host_destroy(ci);
 }
 
+static void ci_get_otg_capable(struct ci_hdrc *ci)
+{
+   if (ci-platdata-flags  CI_HDRC_DUAL_ROLE_NOT_OTG)
+   ci-is_otg = false;
+   else
+   ci-is_otg = (hw_read(ci, CAP_DCCPARAMS,
+   DCCPARAMS_DC | DCCPARAMS_HC)
+   == (DCCPARAMS_DC | DCCPARAMS_HC));
+   if (ci-is_otg)
+   dev_dbg(ci-dev, It is OTG capable controller\n);
+}
+
 static int ci_hdrc_probe(struct platform_device *pdev)
 {
struct device   *dev = pdev-dev;
@@ -482,6 +494,9 @@ static int ci_hdrc_probe(struct platform_device *pdev)
return -ENODEV;
}
 
+   /* To know if controller is OTG capable or not */
+   ci_get_otg_capable(ci);
+
if (!ci-platdata-phy_mode)
ci-platdata-phy_mode = of_usb_get_phy_mode(dev-of_node);
 
@@ -514,10 +529,22 @@ static int ci_hdrc_probe(struct platform_device *pdev)
}
 
if (ci-roles[CI_ROLE_HOST]  ci-roles[CI_ROLE_GADGET]) {
-   ci-is_otg = true;
-   /* ID pin needs 1ms debouce time, we delay 2ms for safe */
-   mdelay(2);
-   ci-role = ci_otg_role(ci);
+   if (ci-is_otg) {
+   /*
+* ID pin needs 1ms debouce time,
+* we delay 2ms for safe.
+*/
+   mdelay(2);
+   ci-role = ci_otg_role(ci);
+   ci_hdrc_otg_init(ci);
+   } else {
+   /*
+* If the controller is not OTG capable, but support
+* role switch, the defalt role is gadget, and the
+* user can switch it through debugfs (proc in future?)
+*/
+   ci-role = CI_ROLE_GADGET;
+   }
} else {
ci-role = ci-roles[CI_ROLE_HOST]
? CI_ROLE_HOST
@@ -536,9 +563,6 @@ static int ci_hdrc_probe(struct platform_device *pdev)
if (ret)
goto stop;
 
-   if (ci-is_otg)
-   ci_hdrc_otg_init(ci);
-
ret = dbg_create_files(ci);
if (!ret)
return 0;
diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h
index ce4e1aa..10a607c 100644
--- a/include/linux/usb/chipidea.h
+++ b/include/linux/usb/chipidea.h
@@ -20,6 +20,11 @@ struct ci_hdrc_platform_data {
 #define CI_HDRC_REQUIRE_TRANSCEIVERBIT(1)
 #define CI_HDRC_PULLUP_ON_VBUS BIT(2)
 #define CI_HDRC_DISABLE_STREAMING  BIT(3)
+   /*
+* Only set it when DCCPARAMS.DC==1 and DCCPARAMS.HC==1,
+* but otg is not supported (no register otgsc).
+*/
+#define CI_HDRC_DUAL_ROLE_NOT_OTG  BIT(4)
enum usb_dr_modedr_mode;
 #define CI_HDRC_CONTROLLER_RESET_EVENT 0
 #define CI_HDRC_CONTROLLER_STOPPED_EVENT   1
-- 
1.7.0.4


--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v14 07/12] usb: chipidea: disable all interrupts and clear all interrupts status

2013-08-02 Thread Peter Chen
During the initialization, it needs to disable all interrupts
enable bit as well as clear all interrupts status bits to avoid
exceptional interrupt.

Tested-by: Marek Vasut ma...@denx.de
Signed-off-by: Peter Chen peter.c...@freescale.com
---
 drivers/usb/chipidea/core.c |   11 ++-
 1 files changed, 10 insertions(+), 1 deletions(-)

diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index 2ae18fd..2223954 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -199,6 +199,12 @@ static int hw_device_init(struct ci_hdrc *ci, void __iomem 
*base)
if (ci-hw_ep_max  ENDPT_MAX)
return -ENODEV;
 
+   /* Disable all interrupts bits */
+   hw_write(ci, OP_USBINTR, 0x, 0);
+
+   /* Clear all interrupts status bits*/
+   hw_write(ci, OP_USBSTS, 0x, 0x);
+
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);
 
@@ -434,8 +440,11 @@ static void ci_get_otg_capable(struct ci_hdrc *ci)
ci-is_otg = (hw_read(ci, CAP_DCCPARAMS,
DCCPARAMS_DC | DCCPARAMS_HC)
== (DCCPARAMS_DC | DCCPARAMS_HC));
-   if (ci-is_otg)
+   if (ci-is_otg) {
dev_dbg(ci-dev, It is OTG capable controller\n);
+   ci_disable_otg_interrupt(ci, OTGSC_INT_EN_BITS);
+   ci_clear_otg_interrupt(ci, OTGSC_INT_STATUS_BITS);
+   }
 }
 
 static int ci_hdrc_probe(struct platform_device *pdev)
-- 
1.7.0.4


--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v14 03/12] usb: chipidea: udc: otg_set_peripheral is useless for some chipidea users

2013-08-02 Thread Peter Chen
It is useless at below cases:
- If we implement both usb host and device at chipidea driver.
- If we don't need phy-otg.

Tested-by: Marek Vasut ma...@denx.de
Signed-off-by: Peter Chen peter.c...@freescale.com
---
 drivers/usb/chipidea/udc.c |7 ++-
 1 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
index e475fcd..116c762 100644
--- a/drivers/usb/chipidea/udc.c
+++ b/drivers/usb/chipidea/udc.c
@@ -1805,7 +1805,12 @@ static int udc_start(struct ci_hdrc *ci)
if (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 put_transceiver;
}
 
-- 
1.7.0.4


--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v14 11/12] usb: chipidea: udc: misuse flag CI_HDRC_REGS_SHARED and CI_HDRC_PULLUP_ON_VBUS

2013-08-02 Thread Peter Chen
CI_HDRC_REGS_SHARED stands for the controller registers is shared
with other USB drivers, if all USB drivers are at chipidea/, it doesn't
needed to set.
CI_HDRC_PULLUP_ON_VBUS stands for pullup dp when the vbus is on. This
flag doesn't need to set if the vbus is always on for gadget
since dp has always pulled up after the gadget has initialized.

So, the current code seems to misuse this two flags.
- When the gadget initializes, the controller doesn't need to run if
it depends on vbus (CI_HDRC_PULLUP_ON_VBUS), it does not
relate to shared register.
- When the gadget starts (load one gadget module), the controller
can run if vbus is on (CI_HDRC_PULLUP_ON_VBUS), it also does not
relate to shared register.

Tested-by: Marek Vasut ma...@denx.de
Signed-off-by: Peter Chen peter.c...@freescale.com
---
 drivers/usb/chipidea/udc.c |5 ++---
 1 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
index c70ce38..45abf4d 100644
--- a/drivers/usb/chipidea/udc.c
+++ b/drivers/usb/chipidea/udc.c
@@ -1637,8 +1637,7 @@ static int ci_udc_start(struct usb_gadget *gadget,
pm_runtime_get_sync(ci-gadget.dev);
if (ci-platdata-flags  CI_HDRC_PULLUP_ON_VBUS) {
if (ci-vbus_active) {
-   if (ci-platdata-flags  CI_HDRC_REGS_SHARED)
-   hw_device_reset(ci, USBMODE_CM_DC);
+   hw_device_reset(ci, USBMODE_CM_DC);
} else {
pm_runtime_put_sync(ci-gadget.dev);
goto done;
@@ -1801,7 +1800,7 @@ static int udc_start(struct ci_hdrc *ci)
}
}
 
-   if (!(ci-platdata-flags  CI_HDRC_REGS_SHARED)) {
+   if (!(ci-platdata-flags  CI_HDRC_PULLUP_ON_VBUS)) {
retval = hw_device_reset(ci, USBMODE_CM_DC);
if (retval)
goto put_transceiver;
-- 
1.7.0.4


--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v14 02/12] usb: chipidea: host: add vbus regulator control

2013-08-02 Thread Peter Chen
For boards which have board level vbus control (eg, through gpio), we
need to vbus operation according to below rules:
- For host, we need open vbus before start hcd, and close it
after remove hcd.
- For otg, the vbus needs to be on/off when usb role switches.
When the host roles begins, it opens vbus; when the host role
finishes, it closes vbus.

We put vbus operation to host as host is the only vbus user,
When we are at host mode, the vbus is on, when we are not at
host mode, vbus should be off.

Tested-by: Marek Vasut ma...@denx.de
Signed-off-by: Peter Chen peter.c...@freescale.com
---
 drivers/usb/chipidea/host.c |   23 ++-
 1 files changed, 22 insertions(+), 1 deletions(-)

diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c
index 40d0fda..e94e52b 100644
--- a/drivers/usb/chipidea/host.c
+++ b/drivers/usb/chipidea/host.c
@@ -24,6 +24,7 @@
 #include linux/usb.h
 #include linux/usb/hcd.h
 #include linux/usb/chipidea.h
+#include linux/regulator/consumer.h
 
 #include ../host/ehci.h
 
@@ -64,9 +65,19 @@ static int host_start(struct ci_hdrc *ci)
ehci-caps = ci-hw_bank.cap;
ehci-has_hostpc = ci-hw_bank.lpm;
 
+   if (ci-platdata-reg_vbus) {
+   ret = regulator_enable(ci-platdata-reg_vbus);
+   if (ret) {
+   dev_err(ci-dev,
+   Failed to enable vbus regulator, ret=%d\n,
+   ret);
+   goto put_hcd;
+   }
+   }
+
ret = usb_add_hcd(hcd, 0, 0);
if (ret)
-   usb_put_hcd(hcd);
+   goto disable_reg;
else
ci-hcd = hcd;
 
@@ -74,6 +85,14 @@ static int host_start(struct ci_hdrc *ci)
hw_write(ci, OP_USBMODE, USBMODE_CI_SDIS, USBMODE_CI_SDIS);
 
return ret;
+
+disable_reg:
+   regulator_disable(ci-platdata-reg_vbus);
+
+put_hcd:
+   usb_put_hcd(hcd);
+
+   return ret;
 }
 
 static void host_stop(struct ci_hdrc *ci)
@@ -82,6 +101,8 @@ static void host_stop(struct ci_hdrc *ci)
 
usb_remove_hcd(hcd);
usb_put_hcd(hcd);
+   if (ci-platdata-reg_vbus)
+   regulator_disable(ci-platdata-reg_vbus);
 }
 
 int ci_hdrc_host_init(struct ci_hdrc *ci)
-- 
1.7.0.4


--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v14 09/12] usb: chipidea: add vbus interrupt handler

2013-08-02 Thread Peter Chen
We add vbus interrupt handler at ci_otg_work, it uses OTGSC_BSV(at otgsc)
to know it is connect or disconnet event.
Meanwhile, we introduce two flags id_event and b_sess_valid_event to
indicate it is an id interrupt or a vbus interrupt.

Tested-by: Marek Vasut ma...@denx.de
Signed-off-by: Peter Chen peter.c...@freescale.com
---
 drivers/usb/chipidea/ci.h   |5 +
 drivers/usb/chipidea/core.c |   28 +++-
 drivers/usb/chipidea/otg.c  |   42 +++---
 drivers/usb/chipidea/otg.h  |1 +
 drivers/usb/chipidea/udc.c  |7 +++
 5 files changed, 71 insertions(+), 12 deletions(-)

diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h
index 33cb29f..3160363 100644
--- a/drivers/usb/chipidea/ci.h
+++ b/drivers/usb/chipidea/ci.h
@@ -132,6 +132,9 @@ struct hw_bank {
  * @transceiver: pointer to USB PHY, if any
  * @hcd: pointer to usb_hcd for ehci host driver
  * @debugfs: root dentry for this controller in debugfs
+ * @id_event: indicates there is an id event, and handled at ci_otg_work
+ * @b_sess_valid_event: indicates there is a vbus event, and handled
+ * at ci_otg_work
  */
 struct ci_hdrc {
struct device   *dev;
@@ -168,6 +171,8 @@ struct ci_hdrc {
struct usb_phy  *transceiver;
struct usb_hcd  *hcd;
struct dentry   *debugfs;
+   boolid_event;
+   boolb_sess_valid_event;
 };
 
 static inline struct ci_role_driver *ci_role(struct ci_hdrc *ci)
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index 30be811..0e69282 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -303,16 +303,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 (ci-is_otg  (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;
 }
 
diff --git a/drivers/usb/chipidea/otg.c b/drivers/usb/chipidea/otg.c
index 68f2faf..c74194d 100644
--- a/drivers/usb/chipidea/otg.c
+++ b/drivers/usb/chipidea/otg.c
@@ -52,13 +52,23 @@ enum ci_role ci_otg_role(struct ci_hdrc *ci)
return role;
 }
 
-/**
- * ci_role_work - perform role changing based on ID pin
- * @work: work struct
- */
-static void ci_role_work(struct work_struct *work)
+void ci_handle_vbus_change(struct ci_hdrc *ci)
+{
+   u32 otgsc;
+
+   if (!ci-is_otg)
+   return;
+
+   otgsc = hw_read(ci, OP_OTGSC, ~0);
+
+   if (otgsc  OTGSC_BSV)
+   usb_gadget_vbus_connect(ci-gadget);
+   else
+   usb_gadget_vbus_disconnect(ci-gadget);
+}
+
+static void ci_handle_id_switch(struct ci_hdrc *ci)
 {
-   struct ci_hdrc *ci = container_of(work, struct ci_hdrc, work);
enum ci_role role = ci_otg_role(ci);
 
if (role != ci-role) {
@@ -68,17 +78,35 @@ static void ci_role_work(struct work_struct *work)
ci_role_stop(ci);
ci_role_start(ci, role);
}
+}
+/**
+ * ci_otg_work - perform otg (vbus/id) event handle
+ * @work: work struct
+ */
+static void ci_otg_work(struct work_struct *work)
+{
+   struct ci_hdrc *ci = container_of(work, struct ci_hdrc, 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);
 }
 
+
 /**
  * ci_hdrc_otg_init - initialize otg struct
  * ci: the controller
  */
 int ci_hdrc_otg_init(struct ci_hdrc *ci)
 {
-   INIT_WORK(ci-work, ci_role_work);
+   INIT_WORK(ci-work

[PATCH v14 10/12] usb: chipidea: add wait vbus lower than OTGSC_BSV before role starts

2013-08-02 Thread Peter Chen
When the gadget role starts, we need to make sure the vbus is lower
than OTGSC_BSV, or there will be an vbus interrupt since we use
B_SESSION_VALID as vbus interrupt to indicate connect and disconnect.
When the host role starts, it may not be useful to wait vbus to lower
than OTGSC_BSV, but it can indicate some hardware problems like the
vbus is still higher than OTGSC_BSV after we disconnect to host some
time later (5000 milliseconds currently), which is obvious not correct.

Tested-by: Marek Vasut ma...@denx.de
Signed-off-by: Peter Chen peter.c...@freescale.com
---
 drivers/usb/chipidea/ci.h   |3 +++
 drivers/usb/chipidea/core.c |   32 
 drivers/usb/chipidea/otg.c  |4 
 3 files changed, 39 insertions(+), 0 deletions(-)

diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h
index 3160363..1c94fc5 100644
--- a/drivers/usb/chipidea/ci.h
+++ b/drivers/usb/chipidea/ci.h
@@ -308,4 +308,7 @@ int hw_port_test_set(struct ci_hdrc *ci, u8 mode);
 
 u8 hw_port_test_get(struct ci_hdrc *ci);
 
+int hw_wait_reg(struct ci_hdrc *ci, enum ci_hw_regs reg, u32 mask,
+   u32 value, unsigned int timeout_ms);
+
 #endif /* __DRIVERS_USB_CHIPIDEA_CI_H */
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index 0e69282..f09b4db 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -294,6 +294,38 @@ int hw_device_reset(struct ci_hdrc *ci, u32 mode)
return 0;
 }
 
+/**
+ * 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_ms: timeout in millisecond
+ *
+ * This function returns an error code if timeout
+ */
+int hw_wait_reg(struct ci_hdrc *ci, enum ci_hw_regs reg, u32 mask,
+   u32 value, unsigned int timeout_ms)
+{
+   unsigned long elapse = jiffies + msecs_to_jiffies(timeout_ms);
+
+   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;
+}
+
 static irqreturn_t ci_irq(int irq, void *data)
 {
struct ci_hdrc *ci = data;
diff --git a/drivers/usb/chipidea/otg.c b/drivers/usb/chipidea/otg.c
index c74194d..d39cce8 100644
--- a/drivers/usb/chipidea/otg.c
+++ b/drivers/usb/chipidea/otg.c
@@ -67,6 +67,7 @@ void ci_handle_vbus_change(struct ci_hdrc *ci)
usb_gadget_vbus_disconnect(ci-gadget);
 }
 
+#define CI_VBUS_STABLE_TIMEOUT_MS 5000
 static void ci_handle_id_switch(struct ci_hdrc *ci)
 {
enum ci_role role = ci_otg_role(ci);
@@ -76,6 +77,9 @@ static void ci_handle_id_switch(struct ci_hdrc *ci)
ci_role(ci)-name, ci-roles[role]-name);
 
ci_role_stop(ci);
+   /* wait vbus lower than OTGSC_BSV */
+   hw_wait_reg(ci, OP_OTGSC, OTGSC_BSV, 0,
+   CI_VBUS_STABLE_TIMEOUT_MS);
ci_role_start(ci, role);
}
 }
-- 
1.7.0.4


--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v14 08/12] usb: chipidea: move otg relate things to otg file

2013-08-02 Thread Peter Chen
Move otg relate things to otg file.

Tested-by: Marek Vasut ma...@denx.de
Signed-off-by: Peter Chen peter.c...@freescale.com
---
 drivers/usb/chipidea/core.c |   63 +--
 drivers/usb/chipidea/otg.c  |   57 +-
 drivers/usb/chipidea/otg.h  |2 +
 3 files changed, 70 insertions(+), 52 deletions(-)

diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index 2223954..30be811 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -294,40 +294,6 @@ int hw_device_reset(struct ci_hdrc *ci, u32 mode)
return 0;
 }
 
-/**
- * ci_otg_role - pick role based on ID pin state
- * @ci: the controller
- */
-static enum ci_role ci_otg_role(struct ci_hdrc *ci)
-{
-   u32 sts = hw_read(ci, OP_OTGSC, ~0);
-   enum ci_role role = sts  OTGSC_ID
-   ? CI_ROLE_GADGET
-   : CI_ROLE_HOST;
-
-   return role;
-}
-
-/**
- * ci_role_work - perform role changing based on ID pin
- * @work: work struct
- */
-static void ci_role_work(struct work_struct *work)
-{
-   struct ci_hdrc *ci = container_of(work, struct ci_hdrc, 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);
-}
-
 static irqreturn_t ci_irq(int irq, void *data)
 {
struct ci_hdrc *ci = data;
@@ -430,6 +396,8 @@ static inline void ci_role_destroy(struct ci_hdrc *ci)
 {
ci_hdrc_gadget_destroy(ci);
ci_hdrc_host_destroy(ci);
+   if (ci-is_otg)
+   ci_hdrc_otg_destory(ci);
 }
 
 static void ci_get_otg_capable(struct ci_hdrc *ci)
@@ -496,13 +464,6 @@ static int ci_hdrc_probe(struct platform_device *pdev)
return -ENODEV;
}
 
-   INIT_WORK(ci-work, ci_role_work);
-   ci-wq = create_singlethread_workqueue(ci_otg);
-   if (!ci-wq) {
-   dev_err(dev, can't create workqueue\n);
-   return -ENODEV;
-   }
-
/* To know if controller is OTG capable or not */
ci_get_otg_capable(ci);
 
@@ -533,8 +494,15 @@ static int ci_hdrc_probe(struct platform_device *pdev)
 
if (!ci-roles[CI_ROLE_HOST]  !ci-roles[CI_ROLE_GADGET]) {
dev_err(dev, no supported roles\n);
-   ret = -ENODEV;
-   goto rm_wq;
+   return -ENODEV;
+   }
+
+   if (ci-is_otg) {
+   ret = ci_hdrc_otg_init(ci);
+   if (ret) {
+   dev_err(dev, init otg fails, ret = %d\n, ret);
+   goto stop;
+   }
}
 
if (ci-roles[CI_ROLE_HOST]  ci-roles[CI_ROLE_GADGET]) {
@@ -545,7 +513,7 @@ static int ci_hdrc_probe(struct platform_device *pdev)
 */
mdelay(2);
ci-role = ci_otg_role(ci);
-   ci_hdrc_otg_init(ci);
+   ci_enable_otg_interrupt(ci, OTGSC_IDIE);
} else {
/*
 * If the controller is not OTG capable, but support
@@ -563,7 +531,7 @@ static int ci_hdrc_probe(struct platform_device *pdev)
ret = ci_role_start(ci, ci-role);
if (ret) {
dev_err(dev, can't start %s role\n, ci_role(ci)-name);
-   goto rm_wq;
+   goto stop;
}
 
platform_set_drvdata(pdev, ci);
@@ -579,9 +547,6 @@ static int ci_hdrc_probe(struct platform_device *pdev)
free_irq(ci-irq, ci);
 stop:
ci_role_destroy(ci);
-rm_wq:
-   flush_workqueue(ci-wq);
-   destroy_workqueue(ci-wq);
 
return ret;
 }
@@ -591,8 +556,6 @@ static int ci_hdrc_remove(struct platform_device *pdev)
struct ci_hdrc *ci = platform_get_drvdata(pdev);
 
dbg_remove_files(ci);
-   flush_workqueue(ci-wq);
-   destroy_workqueue(ci-wq);
free_irq(ci-irq, ci);
ci_role_destroy(ci);
 
diff --git a/drivers/usb/chipidea/otg.c b/drivers/usb/chipidea/otg.c
index abefb4d..68f2faf 100644
--- a/drivers/usb/chipidea/otg.c
+++ b/drivers/usb/chipidea/otg.c
@@ -39,12 +39,65 @@ void ci_disable_otg_interrupt(struct ci_hdrc *ci, u32 bits)
 }
 
 /**
- * ci_hdrc_otg_init - initialize otgsc bits
+ * ci_otg_role - pick role based on ID pin state
+ * @ci: the controller
+ */
+enum ci_role ci_otg_role(struct ci_hdrc *ci)
+{
+   u32 sts = hw_read(ci, OP_OTGSC, ~0);
+   enum ci_role role = sts  OTGSC_ID
+   ? CI_ROLE_GADGET
+   : CI_ROLE_HOST;
+
+   return role;
+}
+
+/**
+ * ci_role_work - perform role changing based on ID pin
+ * @work: work struct
+ */
+static void ci_role_work(struct work_struct *work)
+{
+   struct ci_hdrc *ci = container_of(work, struct ci_hdrc, work);
+   enum ci_role

[PATCH v14 12/12] usb: chipidea: udc: .pullup is valid when vbus is on at CI_HDRC_PULLUP_ON_VBUS

2013-08-02 Thread Peter Chen
When the flag CI_HDRC_PULLUP_ON_VBUS is set, .pullup should only be
called when the vbus is active. When the CI_HDRC_PULLUP_ON_VBUS
is set, the controller only begins to run when the vbus is on,
So, it is only meaningful software set pullup/pulldown after
the controller begins to run.

Tested-by: Marek Vasut ma...@denx.de
Signed-off-by: Peter Chen peter.c...@freescale.com
---
 drivers/usb/chipidea/udc.c |4 
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
index 45abf4d..b7ead5f 100644
--- a/drivers/usb/chipidea/udc.c
+++ b/drivers/usb/chipidea/udc.c
@@ -1514,6 +1514,10 @@ static int ci_udc_pullup(struct usb_gadget *_gadget, int 
is_on)
 {
struct ci_hdrc *ci = container_of(_gadget, struct ci_hdrc, gadget);
 
+   if ((ci-platdata-flags  CI_HDRC_PULLUP_ON_VBUS)
+!ci-vbus_active)
+   return -EOPNOTSUPP;
+
if (is_on)
hw_write(ci, OP_USBCMD, USBCMD_RS, USBCMD_RS);
else
-- 
1.7.0.4


--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/3] usb: chipidea: udc: fix the oops when plugs in usb cable after rmmod gadget

2013-08-02 Thread Peter Chen
] (dump_backtrace+0x0/0x114) from [804ea684] 
(dump_stack+0x20/0x24)
 r7: 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:   000f 8001aea0 bf8be000 80712a48 804f0040 
ff80: 806d29e8 412fc09a  bf8bffb4 bf8bffb8 bf8bffa8 8000fbcc 8000fbd0
ffa0: 6013 
 r7:bf8bff94 r6: r5:6013 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:0003
 r4:806e2008
 [804e7810] (secondary_start_kernel+0x0/0x148) from [104e7148] (0x104e7148)
 r5:001f r4:4f8a806a
 CPU1: stopping
 Backtrace:
 [800132e8] (dump_backtrace+0x0/0x114) from [804ea684] 
(dump_stack+0x20/0x24)
 r7: 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:   000f 8001aea0 bf8ba000 80712a48 804f0040 
bf80: 806d29e8 412fc09a  bf8bbfb4 bf8bbfb8 bf8bbfa8 8000fbcc 8000fbd0
bfa0: 6013 
 r7:bf8bbf94 r6: r5:6013 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:0001
 r4:806e2008

Tested-by: Marek Vasut ma...@denx.de
Signed-off-by: Peter Chen peter.c...@freescale.com
---
 drivers/usb/chipidea/udc.c |   13 +
 1 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
index b7ead5f..aeabdcf 100644
--- a/drivers/usb/chipidea/udc.c
+++ b/drivers/usb/chipidea/udc.c
@@ -686,9 +686,6 @@ static int _gadget_stop_activity(struct usb_gadget *gadget)
usb_ep_fifo_flush(ci-ep0out-ep);
usb_ep_fifo_flush(ci-ep0in-ep);
 
-   if (ci-driver)
-   ci-driver-disconnect(gadget);
-
/* make sure to disable all endpoints */
gadget_for_each_ep(ep, gadget) {
usb_ep_disable(ep);
@@ -717,6 +714,11 @@ __acquires(ci-lock)
 {
int retval;
 
+   if (ci-gadget.speed != USB_SPEED_UNKNOWN) {
+   if (ci-driver)
+   ci-driver-disconnect(ci-gadget);
+   }
+
spin_unlock(ci-lock);
retval = _gadget_stop_activity(ci-gadget);
if (retval)
@@ -1464,6 +1466,8 @@ static int ci_udc_vbus_session(struct usb_gadget 
*_gadget, int is_active)
hw_device_state(ci, ci-ep0out-qh.dma);
dev_dbg(ci-dev, Connected to host\n);
} else {
+   if (ci-driver)
+   ci-driver-disconnect(ci-gadget);
hw_device_state(ci, 0);
if (ci-platdata-notify_event)
ci-platdata-notify_event(ci,
@@ -1674,13 +1678,14 @@ static int ci_udc_stop(struct usb_gadget *gadget,
if (ci-platdata-notify_event)
ci-platdata-notify_event(ci,
CI_HDRC_CONTROLLER_STOPPED_EVENT);
-   ci-driver = NULL;
spin_unlock_irqrestore(ci-lock, flags);
_gadget_stop_activity(ci-gadget);
spin_lock_irqsave(ci-lock, flags);
pm_runtime_put(ci-gadget.dev);
}
 
+   ci-driver = NULL;
+
spin_unlock_irqrestore(ci-lock, flags);
 
return 0;
-- 
1.7.0.4


--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 0/3] Misc Chipidea Patch

2013-08-02 Thread Peter Chen
This patchset is based on my vbus/id patchset

Peter Chen (3):
  usb: chipidea: udc: fix the oops when plugs in usb cable after rmmod
gadget
  usb: chipidea: move platform related things to ci_get_platdata
  usb: host: delete chipidea dependency

 drivers/usb/chipidea/core.c |   21 +
 drivers/usb/chipidea/udc.c  |   13 +
 drivers/usb/host/Kconfig|4 ++--
 3 files changed, 20 insertions(+), 18 deletions(-)


--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 3/3] usb: host: delete chipidea dependency

2013-08-02 Thread Peter Chen
Now, chipidea host has already depended on USB_EHCI_HCD

Signed-off-by: Peter Chen peter.c...@freescale.com
---
 drivers/usb/host/Kconfig |4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index cf521d6..b548554 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -63,7 +63,7 @@ config USB_EHCI_HCD
 
 config USB_EHCI_ROOT_HUB_TT
bool Root Hub Transaction Translators
-   depends on USB_EHCI_HCD || USB_CHIPIDEA_HOST
+   depends on USB_EHCI_HCD
---help---
  Some EHCI chips have vendor-specific extensions to integrate
  transaction translators, so that no OHCI or UHCI companion
@@ -75,7 +75,7 @@ config USB_EHCI_ROOT_HUB_TT
 
 config USB_EHCI_TT_NEWSCHED
bool Improved Transaction Translator scheduling
-   depends on USB_EHCI_HCD || USB_CHIPIDEA_HOST
+   depends on USB_EHCI_HCD
default y
---help---
  This changes the periodic scheduling code to fill more of the low
-- 
1.7.0.4


--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/3] usb: chipidea: move platform related things to ci_get_platdata

2013-08-02 Thread Peter Chen
It will make probe cleaner, meanwhile, it fixes the problem
http://marc.info/?l=linux-usbm=137528143523296w=2
described indirectly.

Signed-off-by: Peter Chen peter.c...@freescale.com
---
 drivers/usb/chipidea/core.c |   21 +
 1 files changed, 9 insertions(+), 12 deletions(-)

diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index f09b4db..61c928c 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -381,6 +381,15 @@ static int ci_get_platdata(struct device *dev,
return PTR_ERR(platdata-reg_vbus);
}
 
+   if (!platdata-phy_mode)
+   platdata-phy_mode = of_usb_get_phy_mode(dev-of_node);
+
+   if (!platdata-dr_mode)
+   platdata-dr_mode = of_usb_get_dr_mode(dev-of_node);
+
+   if (platdata-dr_mode == USB_DR_MODE_UNKNOWN)
+   platdata-dr_mode = USB_DR_MODE_OTG;
+
return 0;
 }
 
@@ -479,9 +488,6 @@ static int ci_hdrc_probe(struct platform_device *pdev)
return -ENODEV;
}
 
-   if (!dev-of_node  dev-parent)
-   dev-of_node = dev-parent-of_node;
-
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
base = devm_ioremap_resource(dev, res);
if (IS_ERR(base))
@@ -517,17 +523,8 @@ static int ci_hdrc_probe(struct platform_device *pdev)
/* To know if controller is OTG capable or not */
ci_get_otg_capable(ci);
 
-   if (!ci-platdata-phy_mode)
-   ci-platdata-phy_mode = of_usb_get_phy_mode(dev-of_node);
-
hw_phymode_configure(ci);
 
-   if (!ci-platdata-dr_mode)
-   ci-platdata-dr_mode = of_usb_get_dr_mode(dev-of_node);
-
-   if (ci-platdata-dr_mode == USB_DR_MODE_UNKNOWN)
-   ci-platdata-dr_mode = USB_DR_MODE_OTG;
-
dr_mode = ci-platdata-dr_mode;
/* initialize role(s) before the interrupt is requested */
if (dr_mode == USB_DR_MODE_OTG || dr_mode == USB_DR_MODE_HOST) {
-- 
1.7.0.4


--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v14 00/12] Add tested id switch and vbus connect detect support for Chipidea

2013-08-02 Thread Peter Chen
This patchset adds tested otg id switch function and vbus connect
and disconnect detection for chipidea driver. And fix kinds of 
bugs found at chipidea drivers after enabling id and vbus detection.

This patch are fully tested at imx6 sabresd and imx28evk platform by me.
Besides, marek tested it on two STMP3780-based boards (not yet mainline)
and two MX28-based boards.

My chipidea repo: https://github.com/hzpeterchen/linux-usb.git

Changes for v14:
- This patchset is based on below recent chipidea patches and newest
usb-next, it can decrease rebase effort.

Fabio Estevam (3):
  chipidea: ci_hdrc_imx: Remove unused variable 'res'
  chipidea: core: Move hw_phymode_configure() into probe
  chipidea: Remove previous MODULE_ALIAS

Lothar Wabmann (3):
  usb: chipidea: improve kconfig 2.0
  usb: chipidea: don't clobber return value of ci_role_start()
  usb: chipidea: ci_hdrc_imx: remove an unsolicited module_put() call
from ci_hdrc_imx_remove()

Peter Chen (1):
  usb: chipidea: fix the build error with randconfig

- [Michael comments]: move vbus operation to core, and squash two vbus
patches. [1/12], [2/12]
- [Michael comments]: move out non vbus and non id related patches. [14/14 at 
v13]

Chagnes for v13:
- Add Tested-by: Marek Vasut ma...@denx.de
- [Sascha's comments]: Add return value check for devm_regulator_get. [3/14]
- [Marc's comments]: Change timeout usage at hw_wait_reg. [11/14]
- [Alex's comments]: Using platdata flag to indicate dual role but not 
OTG controller. [7/14]

Changes for v12:
- Rebased greg's usb-next tree (3.10.0-rc7+)
- Split more small patches for single function and fix.

Peter Chen (12):
  usb: chipidea: move vbus regulator operation to core
  usb: chipidea: host: add vbus regulator control
  usb: chipidea: udc: otg_set_peripheral is useless for some chipidea
users
  usb: chipidea: otg: Add otg file used to access otgsc
  usb: chipidea: Add role init and destory APIs
  usb: chipidea: add flag CI_HDRC_DUAL_ROLE_NOT_OTG
  usb: chipidea: disable all interrupts and clear all interrupts status
  usb: chipidea: move otg relate things to otg file
  usb: chipidea: add vbus interrupt handler
  usb: chipidea: add wait vbus lower than OTGSC_BSV before role starts
  usb: chipidea: udc: misuse flag CI_HDRC_REGS_SHARED and
CI_HDRC_PULLUP_ON_VBUS
  usb: chipidea: udc: .pullup is valid when vbus is on at
CI_HDRC_PULLUP_ON_VBUS

 drivers/usb/chipidea/Makefile  |2 +-
 drivers/usb/chipidea/bits.h|   10 ++
 drivers/usb/chipidea/ci.h  |8 ++
 drivers/usb/chipidea/ci_hdrc_imx.c |   26 +-
 drivers/usb/chipidea/core.c|  184 +---
 drivers/usb/chipidea/host.c|   30 ++-
 drivers/usb/chipidea/host.h|6 +
 drivers/usb/chipidea/otg.c |  135 ++
 drivers/usb/chipidea/otg.h |   22 +
 drivers/usb/chipidea/udc.c |   59 +---
 drivers/usb/chipidea/udc.h |6 +
 include/linux/usb/chipidea.h   |6 +
 12 files changed, 401 insertions(+), 93 deletions(-)
 create mode 100644 drivers/usb/chipidea/otg.c
 create mode 100644 drivers/usb/chipidea/otg.h


--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/1] usb: chipidea: refine the operation of creating register mapping

2013-08-05 Thread Peter Chen
- The old operation needs to call hw_alloc_regmap two times, and
the first operation is only used to know if the controller is
lpm supported, besides, there is a kfree before kzalloc, it is also
tricky.

- Fix the memory leak for ci-hw_bank.regmap when unload module.

Signed-off-by: Peter Chen peter.c...@freescale.com
---
 drivers/usb/chipidea/ci.h   |2 +-
 drivers/usb/chipidea/core.c |   11 ---
 2 files changed, 5 insertions(+), 8 deletions(-)

diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h
index 1c94fc5..e5cb585 100644
--- a/drivers/usb/chipidea/ci.h
+++ b/drivers/usb/chipidea/ci.h
@@ -92,7 +92,7 @@ struct ci_role_driver {
  * @regmap: register lookup table
  */
 struct hw_bank {
-   unsignedlpm;
+   boollpm;
resource_size_t phys;
void __iomem*abs;
void __iomem*cap;
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index 135f7f9..8d7a600 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -123,8 +123,6 @@ static int hw_alloc_regmap(struct ci_hdrc *ci, bool is_lpm)
 {
int i;
 
-   kfree(ci-hw_bank.regmap);
-
ci-hw_bank.regmap = kzalloc((OP_LAST + 1) * sizeof(void *),
 GFP_KERNEL);
if (!ci-hw_bank.regmap)
@@ -183,11 +181,9 @@ static int hw_device_init(struct ci_hdrc *ci, void __iomem 
*base)
ci-hw_bank.cap += ci-platdata-capoffset;
ci-hw_bank.op = ci-hw_bank.cap + (ioread32(ci-hw_bank.cap)  0xff);
 
-   hw_alloc_regmap(ci, false);
-   reg = hw_read(ci, CAP_HCCPARAMS, HCCPARAMS_LEN) 
-   __ffs(HCCPARAMS_LEN);
-   ci-hw_bank.lpm  = reg;
-   hw_alloc_regmap(ci, !!reg);
+   ci-hw_bank.lpm  = !!(ioread32(ci-hw_bank.cap + 
+   ci_regs_nolpm[CAP_HCCPARAMS])  HCCPARAMS_LEN);
+   hw_alloc_regmap(ci, ci-hw_bank.lpm);
ci-hw_bank.size = ci-hw_bank.op - ci-hw_bank.abs;
ci-hw_bank.size += OP_LAST;
ci-hw_bank.size /= sizeof(u32);
@@ -602,6 +598,7 @@ static int ci_hdrc_remove(struct platform_device *pdev)
 {
struct ci_hdrc *ci = platform_get_drvdata(pdev);
 
+   kfree(ci-hw_bank.regmap);
dbg_remove_files(ci);
free_irq(ci-irq, ci);
ci_role_destroy(ci);
-- 
1.7.1


--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/1] usb: chipidea: refine the operation of creating register mapping

2013-08-05 Thread Peter Chen
On Mon, Aug 05, 2013 at 10:05:56AM +0300, Alexander Shishkin wrote:
 Peter Chen peter.c...@freescale.com writes:
 
  - The old operation needs to call hw_alloc_regmap two times, and
  the first operation is only used to know if the controller is
  lpm supported, besides, there is a kfree before kzalloc, it is also
  tricky.
 
 Why tricky? kfree() is called from either NULL or a valid pointer, both
 of which is perfectly valid.
 

I know it is valid, it is just strange that you call kfree before kmalloc.

  - Fix the memory leak for ci-hw_bank.regmap when unload module.
 
  ci-hw_bank.op = ci-hw_bank.cap + (ioread32(ci-hw_bank.cap)  0xff);
   
  -   hw_alloc_regmap(ci, false);
  -   reg = hw_read(ci, CAP_HCCPARAMS, HCCPARAMS_LEN) 
  -   __ffs(HCCPARAMS_LEN);
  -   ci-hw_bank.lpm  = reg;
  -   hw_alloc_regmap(ci, !!reg);
  +   ci-hw_bank.lpm  = !!(ioread32(ci-hw_bank.cap + 
  +   ci_regs_nolpm[CAP_HCCPARAMS])  HCCPARAMS_LEN);
  +   hw_alloc_regmap(ci, ci-hw_bank.lpm);
 
 The idea of the original code is to avoid this ioread and have all the
 register offset maths done by hw_read(), since it's done there
 anyway. And it kind of looks better to me the way it's done right
 now. So unless you really want to optimize away one call to
 hw_alloc_regmap(), I'd prefer to keep it as it is.
 

I do this just because it is strange that calling hw_alloc_regmap
two times at the first glance, and the first time is just to know
if it is lpm supported, besides, calling kfree before kmalloc is a
strange thing, don't you think so?

  @@ -602,6 +598,7 @@ static int ci_hdrc_remove(struct platform_device *pdev)
   {
  struct ci_hdrc *ci = platform_get_drvdata(pdev);
   
  +   kfree(ci-hw_bank.regmap);
 
 This one seems perfectly valid.
 
 Regards,
 --
 Alex
 

-- 

Best Regards,
Peter Chen

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/1] usb: gadget: zero: Add flexible auto remote wakeup test method

2013-08-05 Thread Peter Chen
In order to increase test coverage, we can change the interval between
two remote wakeups every time, and the interval can be any user defined
value. This change will no affect current behavior if the user does not
use two introduced module paramters.

Signed-off-by: Peter Chen peter.c...@freescale.com
---
 drivers/usb/gadget/zero.c |   26 +++---
 1 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c
index 0deb9d6..076f2be 100644
--- a/drivers/usb/gadget/zero.c
+++ b/drivers/usb/gadget/zero.c
@@ -38,7 +38,6 @@
  */
 
 /* #define VERBOSE_DEBUG */
-
 #include linux/kernel.h
 #include linux/slab.h
 #include linux/device.h
@@ -95,6 +94,18 @@ unsigned autoresume = DEFAULT_AUTORESUME;
 module_param(autoresume, uint, S_IRUGO);
 MODULE_PARM_DESC(autoresume, zero, or seconds before remote wakeup);
 
+/* Maximum Autoresume time */
+unsigned max_autoresume;
+module_param(max_autoresume, uint, S_IRUGO);
+MODULE_PARM_DESC(max_autoresume, maximum seconds before remote wakeup);
+
+/* Internal between two remote wakeups */
+unsigned autoresume_interal_ms;
+module_param(autoresume_interal_ms, uint, S_IRUGO);
+MODULE_PARM_DESC(autoresume_interal_ms,
+   milliseconds internal between sending two wakeups);
+
+static unsigned autoresume_step_ms;
 /*-*/
 
 static struct usb_device_descriptor device_desc = {
@@ -183,8 +194,16 @@ static void zero_suspend(struct usb_composite_dev *cdev)
return;
 
if (autoresume) {
-   mod_timer(autoresume_timer, jiffies + (HZ * autoresume));
-   DBG(cdev, suspend, wakeup in %d seconds\n, autoresume);
+   if (max_autoresume 
+   (autoresume_step_ms  max_autoresume * 1000))
+   autoresume_step_ms = autoresume * 1000;
+
+   mod_timer(autoresume_timer, jiffies +
+   msecs_to_jiffies(autoresume_step_ms));
+   DBG(cdev, suspend, wakeup in %d milliseconds\n,
+   autoresume_step_ms);
+
+   autoresume_step_ms += autoresume_interal_ms;
} else
DBG(cdev, %s\n, __func__);
 }
@@ -316,6 +335,7 @@ static int __init zero_bind(struct usb_composite_dev *cdev)
if (autoresume) {
sourcesink_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
loopback_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+   autoresume_step_ms = autoresume * 1000;
}
 
/* support OTG systems */
-- 
1.7.1


--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v14 00/12] Add tested id switch and vbus connect detect support for Chipidea

2013-08-06 Thread Peter Chen
On Fri, Aug 02, 2013 at 04:33:53PM +0800, Peter Chen wrote:
 This patchset adds tested otg id switch function and vbus connect
 and disconnect detection for chipidea driver. And fix kinds of 
 bugs found at chipidea drivers after enabling id and vbus detection.
 
 This patch are fully tested at imx6 sabresd and imx28evk platform by me.
 Besides, marek tested it on two STMP3780-based boards (not yet mainline)
 and two MX28-based boards.
 
 My chipidea repo: https://github.com/hzpeterchen/linux-usb.git
 
 Changes for v14:
 - This patchset is based on below recent chipidea patches and newest
 usb-next, it can decrease rebase effort.
 
 Fabio Estevam (3):
   chipidea: ci_hdrc_imx: Remove unused variable 'res'
   chipidea: core: Move hw_phymode_configure() into probe
   chipidea: Remove previous MODULE_ALIAS
 
 Lothar Wabmann (3):
   usb: chipidea: improve kconfig 2.0
   usb: chipidea: don't clobber return value of ci_role_start()
   usb: chipidea: ci_hdrc_imx: remove an unsolicited module_put() call
 from ci_hdrc_imx_remove()
 
 Peter Chen (1):
   usb: chipidea: fix the build error with randconfig
 
 - [Michael comments]: move vbus operation to core, and squash two vbus
 patches. [1/12], [2/12]
 - [Michael comments]: move out non vbus and non id related patches. [14/14 at 
 v13]

Hi Alex, any comments?

 
 Chagnes for v13:
 - Add Tested-by: Marek Vasut ma...@denx.de
 - [Sascha's comments]: Add return value check for devm_regulator_get. [3/14]
 - [Marc's comments]: Change timeout usage at hw_wait_reg. [11/14]
 - [Alex's comments]: Using platdata flag to indicate dual role but not 
 OTG controller. [7/14]
 
 Changes for v12:
 - Rebased greg's usb-next tree (3.10.0-rc7+)
 - Split more small patches for single function and fix.
 
 Peter Chen (12):
   usb: chipidea: move vbus regulator operation to core
   usb: chipidea: host: add vbus regulator control
   usb: chipidea: udc: otg_set_peripheral is useless for some chipidea
 users
   usb: chipidea: otg: Add otg file used to access otgsc
   usb: chipidea: Add role init and destory APIs
   usb: chipidea: add flag CI_HDRC_DUAL_ROLE_NOT_OTG
   usb: chipidea: disable all interrupts and clear all interrupts status
   usb: chipidea: move otg relate things to otg file
   usb: chipidea: add vbus interrupt handler
   usb: chipidea: add wait vbus lower than OTGSC_BSV before role starts
   usb: chipidea: udc: misuse flag CI_HDRC_REGS_SHARED and
 CI_HDRC_PULLUP_ON_VBUS
   usb: chipidea: udc: .pullup is valid when vbus is on at
 CI_HDRC_PULLUP_ON_VBUS
 
  drivers/usb/chipidea/Makefile  |2 +-
  drivers/usb/chipidea/bits.h|   10 ++
  drivers/usb/chipidea/ci.h  |8 ++
  drivers/usb/chipidea/ci_hdrc_imx.c |   26 +-
  drivers/usb/chipidea/core.c|  184 
 +---
  drivers/usb/chipidea/host.c|   30 ++-
  drivers/usb/chipidea/host.h|6 +
  drivers/usb/chipidea/otg.c |  135 ++
  drivers/usb/chipidea/otg.h |   22 +
  drivers/usb/chipidea/udc.c |   59 +---
  drivers/usb/chipidea/udc.h |6 +
  include/linux/usb/chipidea.h   |6 +
  12 files changed, 401 insertions(+), 93 deletions(-)
  create mode 100644 drivers/usb/chipidea/otg.c
  create mode 100644 drivers/usb/chipidea/otg.h
 

-- 

Best Regards,
Peter Chen

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] USB: global suspend and remote wakeup don't mix

2013-08-06 Thread Peter Chen
On Tue, Aug 06, 2013 at 01:05:40PM -0400, Alan Stern wrote:
 On Wed, 7 Aug 2013, Huang Rui wrote:
 
Could you explain that how can you make sure the root cause is unable
to relay wakup requests from downstream port to upstream port if
downstream port's suspend feature is not set? The OS is unable wakeup
from S3 at that time. We can't fetch dmesg log and serial port is
suspend either at that time. Did you use any other tools to trace this
issue? Could you teach me? Actually, I was encoutered this issue
either.
   
   It was simple.  I ran two tests.  They were exactly the same, except
   that the suspend feature was set in the first test and was not set in
   the second test.  Remote wakeup worked in the first test and not in the
   second.
   
  
  Got it, but I'm still a little confused. For example, one mouse is
  attached at usb2.0 port of roothub, and it supports remote wakeup. But
  the wakeup attribute is disabled for mouse defaultly, am I right? So
 
 Yes.
 
  remote wakeup doesn't work on this mouse, then run system suspend into
  s3 with global suspend(don't send Set Suspend Feature request). In
  this case, remote wakeup and global suspend doesn't mix, am I right?
 
 No.  In this case they do mix okay.
 
  But system still can not wake up normally.
 
 In this case, the system is not supposed to wake up when you press a 
 mouse button, because the mouse is disabled for remote wakeup.  
 Therefore the system behaves correctly.
 
 Instead of a mouse, consider a USB keyboard.  Keyboards _are_ enabled
 for remote wakeup by default.  And suppose the keyboard is plugged into
 an external hub, not the root hub.
 
 Then pressing a key on the keyboard _should_ cause the system to wake 
 up from S3.  But with some hubs, if you use global suspend then 
 pressing a key does not wake up the system.
 

For end user, the keyboard connects to roothub directly and connects
to intermediate hub (then connects to roothub) may not be different,
since the hub may solder at the board directly. What the end user
sees is the standard A USB port.

-- 

Best Regards,
Peter Chen

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 1/1] usb: gadget: zero: Add flexible auto remote wakeup test method

2013-08-06 Thread Peter Chen
In order to increase test coverage, we can change the interval between
two remote wakeups every time, and the interval can be any user defined
value. This change will no affect current behavior if the user does not
use two introduced module paramters.

Signed-off-by: Peter Chen peter.c...@freescale.com
---

Changes for v2:
- Change some typo and description

 drivers/usb/gadget/zero.c |   25 +++--
 1 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c
index 0deb9d6..21da094 100644
--- a/drivers/usb/gadget/zero.c
+++ b/drivers/usb/gadget/zero.c
@@ -95,6 +95,18 @@ unsigned autoresume = DEFAULT_AUTORESUME;
 module_param(autoresume, uint, S_IRUGO);
 MODULE_PARM_DESC(autoresume, zero, or seconds before remote wakeup);
 
+/* Maximum Autoresume time */
+unsigned max_autoresume;
+module_param(max_autoresume, uint, S_IRUGO);
+MODULE_PARM_DESC(max_autoresume, maximum seconds before remote wakeup);
+
+/* Interval between two remote wakeups */
+unsigned autoresume_interval_ms;
+module_param(autoresume_interval_ms, uint, S_IRUGO);
+MODULE_PARM_DESC(autoresume_interval_ms,
+   milliseconds to increase successive wakup delays);
+
+static unsigned autoresume_step_ms;
 /*-*/
 
 static struct usb_device_descriptor device_desc = {
@@ -183,8 +195,16 @@ static void zero_suspend(struct usb_composite_dev *cdev)
return;
 
if (autoresume) {
-   mod_timer(autoresume_timer, jiffies + (HZ * autoresume));
-   DBG(cdev, suspend, wakeup in %d seconds\n, autoresume);
+   if (max_autoresume 
+   (autoresume_step_ms  max_autoresume * 1000))
+   autoresume_step_ms = autoresume * 1000;
+
+   mod_timer(autoresume_timer, jiffies +
+   msecs_to_jiffies(autoresume_step_ms));
+   DBG(cdev, suspend, wakeup in %d milliseconds\n,
+   autoresume_step_ms);
+
+   autoresume_step_ms += autoresume_interval_ms;
} else
DBG(cdev, %s\n, __func__);
 }
@@ -316,6 +336,7 @@ static int __init zero_bind(struct usb_composite_dev *cdev)
if (autoresume) {
sourcesink_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
loopback_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+   autoresume_step_ms = autoresume * 1000;
}
 
/* support OTG systems */
-- 
1.7.1


--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/1] usb: chipidea: imx: include usbmisc_imx.c in ci_hdrc_imx.c

2013-08-07 Thread Peter Chen
At former design, both ci_hdrc_imx and usbmisc_imx are individual
module, ci_hdrc_imx is glue layer for imx usb driver. usbmisc_imx
handles non-core registers which has different register layout
for imx SoC serials, it usually supplies interface for wakeup
setting, PHY setting, etc.

usbmisc_imx uses symbols from ci_hdrc_imx, So, when we combile both
of drivers as loadable module, usbmisc is needed to be unload first.
However at ci_hdrc_imx, it needs to call usbmisc_imx's interface
at its removal function once we enable wakeup/runtime pm function, so
keeping two drivers can't work well at loadable module use case.

To fix loadable module use case, we need to build usbmisc_imx into
ci_hdrc_imx. The usbmisc_imx still handles misc setting for controllers,
and will be included at ci_hdrc_imx.

There is a short discussion for it:
http://marc.info/?l=linux-usbm=136861599423172w=2

Besides, we update dts and binding doc for at this commit

Signed-off-by: Peter Chen peter.c...@freescale.com
---
 .../devicetree/bindings/usb/ci13xxx-imx.txt|   10 +-
 .../devicetree/bindings/usb/usbmisc-imx.txt|   14 --
 arch/arm/boot/dts/imx23.dtsi   |1 +
 arch/arm/boot/dts/imx25.dtsi   |   14 +-
 arch/arm/boot/dts/imx28.dtsi   |2 +
 arch/arm/boot/dts/imx51.dtsi   |   13 +
 arch/arm/boot/dts/imx53.dtsi   |   13 +
 arch/arm/boot/dts/imx6qdl.dtsi |   20 +-
 drivers/usb/chipidea/Makefile  |2 +-
 drivers/usb/chipidea/ci_hdrc_imx.c |  125 ++-
 drivers/usb/chipidea/ci_hdrc_imx.h |   32 ++--
 drivers/usb/chipidea/usbmisc_imx.c |  237 +---
 12 files changed, 192 insertions(+), 291 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/usb/usbmisc-imx.txt

diff --git a/Documentation/devicetree/bindings/usb/ci13xxx-imx.txt 
b/Documentation/devicetree/bindings/usb/ci13xxx-imx.txt
index b4b5b79..13720a2 100644
--- a/Documentation/devicetree/bindings/usb/ci13xxx-imx.txt
+++ b/Documentation/devicetree/bindings/usb/ci13xxx-imx.txt
@@ -13,8 +13,8 @@ Recommended properies:
 
 Optional properties:
 - fsl,usbphy: phandler of usb phy that connects to the only one port
-- fsl,usbmisc: phandler of non-core register device, with one argument
-  that indicate usb controller index
+- ci,noncore: phandler of non-core register device, the user must enable
+syscon driver to use it
 - vbus-supply: regulator for vbus
 - disable-over-current: disable over current detect
 - external-vbus-divider: enables off-chip resistor divider for Vbus
@@ -25,7 +25,11 @@ usb@02184000 { /* USB OTG */
reg = 0x02184000 0x200;
interrupts = 0 43 0x04;
fsl,usbphy = usbphy1;
-   fsl,usbmisc = usbmisc 0;
+   ci,noncore = noncore;
disable-over-current;
external-vbus-divider;
 };
+noncore: usb-non-core@02184800 {
+compatible = fsl,imx-usb-non-core, syscon;
+reg = 0x02184800 0x200;
+};
diff --git a/Documentation/devicetree/bindings/usb/usbmisc-imx.txt 
b/Documentation/devicetree/bindings/usb/usbmisc-imx.txt
deleted file mode 100644
index 97ce94e..000
--- a/Documentation/devicetree/bindings/usb/usbmisc-imx.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-* Freescale i.MX non-core registers
-
-Required properties:
-- #index-cells: Cells used to descibe usb controller index. Should be 1
-- compatible: Should be one of below:
-   fsl,imx6q-usbmisc for imx6q
-- reg: Should contain registers location and length
-
-Examples:
-usbmisc@02184800 {
-   #index-cells = 1;
-   compatible = fsl,imx6q-usbmisc;
-   reg = 0x02184800 0x200;
-};
diff --git a/arch/arm/boot/dts/imx23.dtsi b/arch/arm/boot/dts/imx23.dtsi
index 587ceef..a0d8471 100644
--- a/arch/arm/boot/dts/imx23.dtsi
+++ b/arch/arm/boot/dts/imx23.dtsi
@@ -20,6 +20,7 @@
gpio2 = gpio2;
serial0 = auart0;
serial1 = auart1;
+   usb0 = usb0;
};
 
cpus {
diff --git a/arch/arm/boot/dts/imx25.dtsi b/arch/arm/boot/dts/imx25.dtsi
index 1f72862..7bb94ce 100644
--- a/arch/arm/boot/dts/imx25.dtsi
+++ b/arch/arm/boot/dts/imx25.dtsi
@@ -461,7 +461,7 @@
interrupts = 37;
clocks = clks 9, clks 70, clks 8;
clock-names = ipg, ahb, per;
-   fsl,usbmisc = usbmisc 0;
+   ci,noncore = noncore;
status = disabled;
};
 
@@ -471,17 +471,13 @@
interrupts = 35;
clocks = clks 9, clks 70, clks 8;
clock-names = ipg, ahb, per;
-   fsl,usbmisc = usbmisc 1;
+   ci,noncore = noncore;
status = disabled

Re: [PATCH 1/1] usb: chipidea: imx: include usbmisc_imx.c in ci_hdrc_imx.c

2013-08-07 Thread Peter Chen
On Wed, Aug 07, 2013 at 10:15:22AM +0200, Sascha Hauer wrote:
 On Wed, Aug 07, 2013 at 01:34:37PM +0800, Peter Chen wrote:
  At former design, both ci_hdrc_imx and usbmisc_imx are individual
  module, ci_hdrc_imx is glue layer for imx usb driver. usbmisc_imx
  handles non-core registers which has different register layout
  for imx SoC serials, it usually supplies interface for wakeup
  setting, PHY setting, etc.
  
  usbmisc_imx uses symbols from ci_hdrc_imx, So, when we combile both
  of drivers as loadable module, usbmisc is needed to be unload first.
  However at ci_hdrc_imx, it needs to call usbmisc_imx's interface
  at its removal function once we enable wakeup/runtime pm function, so
  keeping two drivers can't work well at loadable module use case.
  
  To fix loadable module use case, we need to build usbmisc_imx into
  ci_hdrc_imx. The usbmisc_imx still handles misc setting for controllers,
  and will be included at ci_hdrc_imx.
  
  There is a short discussion for it:
  http://marc.info/?l=linux-usbm=136861599423172w=2
  
  Besides, we update dts and binding doc for at this commit
 
 This patch does far too many things at once.
 
 - Convert imx-usb-misc from a driver into something which is called
   directly
 - add aliases
 - change devicetree bindings (which causes pain and it's not explained why
   this is necessary at all)

Yes, I need to split doc from implementation.

 - converts the misc stuff to regmap
 
 Please split this up so that it can be reviewed.

The changes are all related to convert usbmisc_imx from a driver to something
which can be called directly.

- usbmisc has #index-cells to indicate controller number, now, it is not
a driver, we use aliases at controller driver to instead of it.
- When usbmisc_imx is a device, the register maps only one time.
But ci_hdrc_imx will be several devices, the non-core register
will be mapped several times, we have to use syscon to visit one register
region among several devices.


 
   
   #include ci.h
   #include ci_hdrc_imx.h
  +#include usbmisc_imx.c
 
 Don't include C files.
 

Yes, it is not a good practice, but I want to keep ci_hdrc_imx.c
as clean as possible. The SoC related implementation will be more
and more in the future after we add more USB functions.

Do you have any good suggestions how to organize general imx stuff and
SoC specifc? Put all the things at controller driver is another solution.

  -   ret);
  -   memset(usbdev, 0, sizeof(*usbdev));
  +   ret = of_alias_get_id(np, usb);
  +   if (ret  0) {
  +   dev_err(dev, failed to get alias id, errno %d\n, ret);
  return ret;
  }
  -   usbdev-index = args.args[0];
  -   of_node_put(args.np);
   
  if (of_find_property(np, disable-over-current, NULL))
  -   usbdev-disable_oc = 1;
  +   data-disable_oc = 1;
   
  if (of_find_property(np, external-vbus-divider, NULL))
  -   usbdev-evdo = 1;
  +   data-evdo = 1;
  +
  +   /* mx23 and mx28 doesn't have non core registers */
  +   if (data-misc_data  (!strcmp(data-misc_data-name, imx23-usb) ||
  +   !strcmp(data-misc_data-name, imx28-usb)))
  +   return 0;
 
 If a USB node does not have a usbmisc (or noncore) property then don't
 initialize it. No need for string compares.
 

OK, will let the code be simple, I can't add device_id for mxs either.

-- 

Best Regards,
Peter Chen

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/1] usb: chipidea: imx: include usbmisc_imx.c in ci_hdrc_imx.c

2013-08-07 Thread Peter Chen
On Wed, Aug 07, 2013 at 11:08:45AM +0200, Sascha Hauer wrote:
   
   - Convert imx-usb-misc from a driver into something which is called
 directly
   - add aliases
   - change devicetree bindings (which causes pain and it's not explained why
 this is necessary at all)
  
  Yes, I need to split doc from implementation.
 
 No, you don't. You just have to explain *why* the bindings need to be
 chaged.
 

OK, I will

  
   - converts the misc stuff to regmap
   
   Please split this up so that it can be reviewed.
  
  The changes are all related to convert usbmisc_imx from a driver to 
  something
  which can be called directly.
  
  - usbmisc has #index-cells to indicate controller number, now, it is not
  a driver, we use aliases at controller driver to instead of it.
 
 Why?
 

We need to know controller number, like pdev-id in the past.
The registers at non core register is messy, the specific bit
is for specific controller.

  - When usbmisc_imx is a device, the register maps only one time.
  But ci_hdrc_imx will be several devices, the non-core register
  will be mapped several times, we have to use syscon to visit one register
  region among several devices.
 
 Converting the imx-usb misc driver to regmap is fine, but I see no
 reason to not make this a separate patch. This would make this much
 easier to read.

You mean delete reg entry at usbmisc dts, and using noncore phandle
at usbmisc_imx.c as the first patch, then, convert driver as separate
file.

  
  Yes, it is not a good practice, but I want to keep ci_hdrc_imx.c
  as clean as possible. The SoC related implementation will be more
  and more in the future after we add more USB functions.
 
 Just because you want to have the binary code in a single module doesn't
 mean the source code has to be in a single C file.
 

OK, I will do.

-- 

Best Regards,
Peter Chen

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/1] usb: chipidea: imx: include usbmisc_imx.c in ci_hdrc_imx.c

2013-08-07 Thread Peter Chen
On Wed, Aug 07, 2013 at 11:11:10AM +0200, Sascha Hauer wrote:
 On Wed, Aug 07, 2013 at 01:34:37PM +0800, Peter Chen wrote:
  -
  -   reg = usbmisc-base + MX25_USB_PHY_CTRL_OFFSET;
  -
  -   if (usbdev-evdo) {
  -   spin_lock_irqsave(usbmisc-lock, flags);
  -   val = readl(reg);
  -   writel(val | MX25_BM_EXTERNAL_VBUS_DIVIDER, reg);
  -   spin_unlock_irqrestore(usbmisc-lock, flags);
  +   if (data-evdo) {
  +   spin_lock_irqsave(data-lock, flags);
  +   regmap_read(data-non_core_base_addr,
  +   MX25_USB_PHY_CTRL_OFFSET, val);
  +   regmap_write(data-non_core_base_addr,
  +   MX25_USB_PHY_CTRL_OFFSET,
  +   val | MX25_BM_EXTERNAL_VBUS_DIVIDER);
  +   spin_unlock_irqrestore(data-lock, flags);
 
 Have a look at regmap_update_bits. You won't need this spinlock anymore.

Thanks.

-- 

Best Regards,
Peter Chen

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/1] usb: chipidea: imx: include usbmisc_imx.c in ci_hdrc_imx.c

2013-08-07 Thread Peter Chen
On Wed, Aug 07, 2013 at 12:05:07PM +0200, Sascha Hauer wrote:
  
  We need to know controller number, like pdev-id in the past.
  The registers at non core register is messy, the specific bit
  is for specific controller.
 
 The controller number is present in the old binding:
 
 fsl,usbmisc = usbmisc 1;
^^^
 
 Merging the usbmisc stuff into the imx driver shouldn't be a reason to
 change this binding.
 
 Please get used to the fact that dt bindings cannot be changed easily
 just because the newer binding looks nicer. They define an ABI and
 breaking this ABI causes pain.
 

But current situation is the device node of usbmisc will not be needed.
The usbmisc will not be a driver. We only need usbmisc to supply kinds
of SoC specific implementations, as well as filling the content of the data
at struct of_device_id (imx-usb's).

  
- When usbmisc_imx is a device, the register maps only one time.
But ci_hdrc_imx will be several devices, the non-core register
will be mapped several times, we have to use syscon to visit one 
register
region among several devices.
   
   Converting the imx-usb misc driver to regmap is fine, but I see no
   reason to not make this a separate patch. This would make this much
   easier to read.
  
  You mean delete reg entry at usbmisc dts, and using noncore phandle
  at usbmisc_imx.c as the first patch, then, convert driver as separate
  file.
 
 I mean: create a patch which converts the usbmisc driver to regmap and
 base your other stuff on this patch.
 

This is what I mean. We can't request one region twice, so we need to
delete devm_ioremap_resource at probe first.

-- 

Best Regards,
Peter Chen

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/1] usb: chipidea: imx: include usbmisc_imx.c in ci_hdrc_imx.c

2013-08-07 Thread Peter Chen
On Wed, Aug 07, 2013 at 12:06:42PM +0200, Sascha Hauer wrote:
 On Wed, Aug 07, 2013 at 01:34:37PM +0800, Peter Chen wrote:
  diff --git a/Documentation/devicetree/bindings/usb/ci13xxx-imx.txt 
  b/Documentation/devicetree/bindings/usb/ci13xxx-imx.txt
  index b4b5b79..13720a2 100644
  --- a/Documentation/devicetree/bindings/usb/ci13xxx-imx.txt
  +++ b/Documentation/devicetree/bindings/usb/ci13xxx-imx.txt
  @@ -13,8 +13,8 @@ Recommended properies:
   
   Optional properties:
   - fsl,usbphy: phandler of usb phy that connects to the only one port
  -- fsl,usbmisc: phandler of non-core register device, with one argument
  -  that indicate usb controller index
  +- ci,noncore: phandler of non-core register device, the user must enable
  +syscon driver to use it
 
 Don't add Linux specifics to the binding documentation. The bindings are
 supposed to be OS agnostic.
 

OK, I will change it.

-- 

Best Regards,
Peter Chen

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/1] usb: chipidea: imx: include usbmisc_imx.c in ci_hdrc_imx.c

2013-08-07 Thread Peter Chen
On Wed, Aug 07, 2013 at 02:28:20PM +0200, Michael Grzeschik wrote:
 Hi Peter,
 
 On Wed, Aug 07, 2013 at 05:24:45PM +0800, Peter Chen wrote:
  On Wed, Aug 07, 2013 at 12:05:07PM +0200, Sascha Hauer wrote:

We need to know controller number, like pdev-id in the past.
The registers at non core register is messy, the specific bit
is for specific controller.
   
   The controller number is present in the old binding:
   
   fsl,usbmisc = usbmisc 1;
  ^^^
   
   Merging the usbmisc stuff into the imx driver shouldn't be a reason to
   change this binding.
   
   Please get used to the fact that dt bindings cannot be changed easily
   just because the newer binding looks nicer. They define an ABI and
   breaking this ABI causes pain.
   
  
  But current situation is the device node of usbmisc will not be needed.
  The usbmisc will not be a driver. We only need usbmisc to supply kinds
  of SoC specific implementations, as well as filling the content of the data
  at struct of_device_id (imx-usb's).
  

  - When usbmisc_imx is a device, the register maps only one time.
  But ci_hdrc_imx will be several devices, the non-core register
  will be mapped several times, we have to use syscon to visit one 
  register
  region among several devices.
 
 Converting the imx-usb misc driver to regmap is fine, but I see no
 reason to not make this a separate patch. This would make this much
 easier to read.

You mean delete reg entry at usbmisc dts, and using noncore phandle
at usbmisc_imx.c as the first patch, then, convert driver as separate
file.
   
   I mean: create a patch which converts the usbmisc driver to regmap and
   base your other stuff on this patch.
   
  
  This is what I mean. We can't request one region twice, so we need to
  delete devm_ioremap_resource at probe first.
 
 Please try to reply with your answers in direct context to the questions.
 Otherwise this thread will not end and probably produce more confusion than
 answers. What we need is a clearly seperated series of independent changes;
 Just like Sascha already mentioned:
 
 On Wed, Aug 07, 2013 at 10:15:22AM +0200, Sascha Hauer wrote:
  This patch does far too many things at once.
  
  - Convert imx-usb-misc from a driver into something which is called
directly
  - add aliases
  - change devicetree bindings (which causes pain and it's not explained why
this is necessary at all)
  - converts the misc stuff to regmap
  
  Please split this up so that it can be reviewed.
 
 Your work needs the clean seperation before we can discuss the changes more in
 detail. Please try that first!
 

Thanks, Michael. I will do that.
But discussion is needed, it can let us understand the problem deeply.
For you, what the real problem, for me, how to do it properly.

-- 

Best Regards,
Peter Chen

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/1] usb: chipidea: imx: delete the dead code

2013-08-08 Thread Peter Chen
Signed-off-by: Peter Chen peter.c...@freescale.com
---
 drivers/usb/chipidea/ci_hdrc_imx.c |3 ---
 1 files changed, 0 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c 
b/drivers/usb/chipidea/ci_hdrc_imx.c
index b886998..30fdc2f 100644
--- a/drivers/usb/chipidea/ci_hdrc_imx.c
+++ b/drivers/usb/chipidea/ci_hdrc_imx.c
@@ -23,9 +23,6 @@
 #include ci.h
 #include ci_hdrc_imx.h
 
-#define pdev_to_phy(pdev) \
-   ((struct usb_phy *)platform_get_drvdata(pdev))
-
 struct ci_hdrc_imx_data {
struct usb_phy *phy;
struct platform_device *ci_pdev;
-- 
1.7.1


--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 1/5] usb: chipidea: imx: rename the DT doc name

2013-08-08 Thread Peter Chen
To reflect source file name change

Signed-off-by: Peter Chen peter.c...@freescale.com
---
 .../devicetree/bindings/usb/ci13xxx-imx.txt|   31 
 .../devicetree/bindings/usb/ci_hdrc_imx.txt|   31 
 Documentation/devicetree/bindings/usb/mxs-phy.txt  |   13 
 .../devicetree/bindings/usb/phy-mxs-usb.txt|   13 
 4 files changed, 44 insertions(+), 44 deletions(-)

diff --git a/Documentation/devicetree/bindings/usb/ci13xxx-imx.txt 
b/Documentation/devicetree/bindings/usb/ci13xxx-imx.txt
deleted file mode 100644
index b4b5b79..000
--- a/Documentation/devicetree/bindings/usb/ci13xxx-imx.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-* Freescale i.MX ci13xxx usb controllers
-
-Required properties:
-- compatible: Should be fsl,imx27-usb
-- reg: Should contain registers location and length
-- interrupts: Should contain controller interrupt
-
-Recommended properies:
-- phy_type: the type of the phy connected to the core. Should be one
-  of utmi, utmi_wide, ulpi, serial or hsic. Without this
-  property the PORTSC register won't be touched
-- dr_mode: One of host, peripheral or otg. Defaults to otg
-
-Optional properties:
-- fsl,usbphy: phandler of usb phy that connects to the only one port
-- fsl,usbmisc: phandler of non-core register device, with one argument
-  that indicate usb controller index
-- vbus-supply: regulator for vbus
-- disable-over-current: disable over current detect
-- external-vbus-divider: enables off-chip resistor divider for Vbus
-
-Examples:
-usb@02184000 { /* USB OTG */
-   compatible = fsl,imx6q-usb, fsl,imx27-usb;
-   reg = 0x02184000 0x200;
-   interrupts = 0 43 0x04;
-   fsl,usbphy = usbphy1;
-   fsl,usbmisc = usbmisc 0;
-   disable-over-current;
-   external-vbus-divider;
-};
diff --git a/Documentation/devicetree/bindings/usb/ci_hdrc_imx.txt 
b/Documentation/devicetree/bindings/usb/ci_hdrc_imx.txt
new file mode 100644
index 000..b4b5b79
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/ci_hdrc_imx.txt
@@ -0,0 +1,31 @@
+* Freescale i.MX ci13xxx usb controllers
+
+Required properties:
+- compatible: Should be fsl,imx27-usb
+- reg: Should contain registers location and length
+- interrupts: Should contain controller interrupt
+
+Recommended properies:
+- phy_type: the type of the phy connected to the core. Should be one
+  of utmi, utmi_wide, ulpi, serial or hsic. Without this
+  property the PORTSC register won't be touched
+- dr_mode: One of host, peripheral or otg. Defaults to otg
+
+Optional properties:
+- fsl,usbphy: phandler of usb phy that connects to the only one port
+- fsl,usbmisc: phandler of non-core register device, with one argument
+  that indicate usb controller index
+- vbus-supply: regulator for vbus
+- disable-over-current: disable over current detect
+- external-vbus-divider: enables off-chip resistor divider for Vbus
+
+Examples:
+usb@02184000 { /* USB OTG */
+   compatible = fsl,imx6q-usb, fsl,imx27-usb;
+   reg = 0x02184000 0x200;
+   interrupts = 0 43 0x04;
+   fsl,usbphy = usbphy1;
+   fsl,usbmisc = usbmisc 0;
+   disable-over-current;
+   external-vbus-divider;
+};
diff --git a/Documentation/devicetree/bindings/usb/mxs-phy.txt 
b/Documentation/devicetree/bindings/usb/mxs-phy.txt
deleted file mode 100644
index 5835b27..000
--- a/Documentation/devicetree/bindings/usb/mxs-phy.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-* Freescale MXS USB Phy Device
-
-Required properties:
-- compatible: Should be fsl,imx23-usbphy
-- reg: Should contain registers location and length
-- interrupts: Should contain phy interrupt
-
-Example:
-usbphy1: usbphy@020c9000 {
-   compatible = fsl,imx6q-usbphy, fsl,imx23-usbphy;
-   reg = 0x020c9000 0x1000;
-   interrupts = 0 44 0x04;
-};
diff --git a/Documentation/devicetree/bindings/usb/phy-mxs-usb.txt 
b/Documentation/devicetree/bindings/usb/phy-mxs-usb.txt
new file mode 100644
index 000..5835b27
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/phy-mxs-usb.txt
@@ -0,0 +1,13 @@
+* Freescale MXS USB Phy Device
+
+Required properties:
+- compatible: Should be fsl,imx23-usbphy
+- reg: Should contain registers location and length
+- interrupts: Should contain phy interrupt
+
+Example:
+usbphy1: usbphy@020c9000 {
+   compatible = fsl,imx6q-usbphy, fsl,imx23-usbphy;
+   reg = 0x020c9000 0x1000;
+   interrupts = 0 44 0x04;
+};
-- 
1.7.1


--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 2/5] usb: chipidea: usbmisc_imx: Using regmap to access register

2013-08-08 Thread Peter Chen
Signed-off-by: Peter Chen peter.c...@freescale.com
---
 drivers/usb/chipidea/usbmisc_imx.c |   71 +---
 1 files changed, 34 insertions(+), 37 deletions(-)

diff --git a/drivers/usb/chipidea/usbmisc_imx.c 
b/drivers/usb/chipidea/usbmisc_imx.c
index ac5a461..545efbf 100644
--- a/drivers/usb/chipidea/usbmisc_imx.c
+++ b/drivers/usb/chipidea/usbmisc_imx.c
@@ -15,6 +15,7 @@
 #include linux/err.h
 #include linux/io.h
 #include linux/delay.h
+#include linux/regmap.h
 
 #include ci_hdrc_imx.h
 
@@ -34,10 +35,10 @@
 
 struct imx_usbmisc {
void __iomem *base;
-   spinlock_t lock;
struct clk *clk;
struct usbmisc_usb_device usbdev[USB_DEV_MAX];
const struct usbmisc_ops *ops;
+   struct regmap *regmap;
 };
 
 static struct imx_usbmisc *usbmisc;
@@ -66,21 +67,16 @@ static struct usbmisc_usb_device *get_usbdev(struct device 
*dev)
 static int usbmisc_imx25_post(struct device *dev)
 {
struct usbmisc_usb_device *usbdev;
-   void __iomem *reg;
-   unsigned long flags;
-   u32 val;
 
usbdev = get_usbdev(dev);
if (IS_ERR(usbdev))
return PTR_ERR(usbdev);
 
-   reg = usbmisc-base + MX25_USB_PHY_CTRL_OFFSET;
-
if (usbdev-evdo) {
-   spin_lock_irqsave(usbmisc-lock, flags);
-   val = readl(reg);
-   writel(val | MX25_BM_EXTERNAL_VBUS_DIVIDER, reg);
-   spin_unlock_irqrestore(usbmisc-lock, flags);
+   regmap_update_bits(usbmisc-regmap,
+   MX25_USB_PHY_CTRL_OFFSET,
+   MX25_BM_EXTERNAL_VBUS_DIVIDER,
+   MX25_BM_EXTERNAL_VBUS_DIVIDER);
usleep_range(5000, 1); /* needed to stabilize voltage */
}
 
@@ -90,37 +86,33 @@ static int usbmisc_imx25_post(struct device *dev)
 static int usbmisc_imx53_init(struct device *dev)
 {
struct usbmisc_usb_device *usbdev;
-   void __iomem *reg = NULL;
-   unsigned long flags;
-   u32 val = 0;
+   unsigned int reg = 0, val = 0;
 
usbdev = get_usbdev(dev);
if (IS_ERR(usbdev))
return PTR_ERR(usbdev);
 
if (usbdev-disable_oc) {
-   spin_lock_irqsave(usbmisc-lock, flags);
switch (usbdev-index) {
case 0:
-   reg = usbmisc-base + MX53_USB_OTG_PHY_CTRL_0_OFFSET;
-   val = readl(reg) | MX53_BM_OVER_CUR_DIS_OTG;
+   reg = MX53_USB_OTG_PHY_CTRL_0_OFFSET;
+   val = MX53_BM_OVER_CUR_DIS_OTG;
break;
case 1:
-   reg = usbmisc-base + MX53_USB_OTG_PHY_CTRL_0_OFFSET;
-   val = readl(reg) | MX53_BM_OVER_CUR_DIS_H1;
+   reg = MX53_USB_OTG_PHY_CTRL_0_OFFSET;
+   val = MX53_BM_OVER_CUR_DIS_H1;
break;
case 2:
-   reg = usbmisc-base + MX53_USB_UH2_CTRL_OFFSET;
-   val = readl(reg) | MX53_BM_OVER_CUR_DIS_UHx;
+   reg = MX53_USB_UH2_CTRL_OFFSET;
+   val = MX53_BM_OVER_CUR_DIS_UHx;
break;
case 3:
-   reg = usbmisc-base + MX53_USB_UH3_CTRL_OFFSET;
-   val = readl(reg) | MX53_BM_OVER_CUR_DIS_UHx;
+   reg = MX53_USB_UH3_CTRL_OFFSET;
+   val = MX53_BM_OVER_CUR_DIS_UHx;
break;
}
-   if (reg  val)
-   writel(val, reg);
-   spin_unlock_irqrestore(usbmisc-lock, flags);
+   if (usbdev-index = 0  usbdev-index = 3)
+   regmap_update_bits(usbmisc-regmap, reg, val, val);
}
 
return 0;
@@ -128,22 +120,15 @@ static int usbmisc_imx53_init(struct device *dev)
 
 static int usbmisc_imx6q_init(struct device *dev)
 {
-
struct usbmisc_usb_device *usbdev;
-   unsigned long flags;
-   u32 reg;
 
usbdev = get_usbdev(dev);
if (IS_ERR(usbdev))
return PTR_ERR(usbdev);
 
-   if (usbdev-disable_oc) {
-   spin_lock_irqsave(usbmisc-lock, flags);
-   reg = readl(usbmisc-base + usbdev-index * 4);
-   writel(reg | MX6_BM_OVER_CUR_DIS,
-   usbmisc-base + usbdev-index * 4);
-   spin_unlock_irqrestore(usbmisc-lock, flags);
-   }
+   if (usbdev-disable_oc)
+   regmap_update_bits(usbmisc-regmap, usbdev-index * 4,
+   MX6_BM_OVER_CUR_DIS, MX6_BM_OVER_CUR_DIS);
 
return 0;
 }
@@ -177,6 +162,12 @@ static const struct of_device_id usbmisc_imx_dt_ids[] = {
 };
 MODULE_DEVICE_TABLE(of, usbmisc_imx_dt_ids);
 
+static struct regmap_config usbmisc_regmap_config = {
+   .reg_bits = 32,
+   .val_bits = 32,
+   .reg_stride = 4

[PATCH v2 0/5] usb: chipidea: delete usbmisc_imx

2013-08-08 Thread Peter Chen
At former design, both ci13xxx_imx and usbmisc_imx are individual
module, ci13xxx_imx is glue layer for imx usb driver. usbmisc_imx
handles non-core registers which have different register layout
for imx SoC serials, it usually supplies interface for wakeup
setting, PHY setting, etc.

usbmisc_imx uses symbols from ci_hdrc_imx, So, when we combile both
of drivers as loadable module, usbmisc is needed to be unload first.
However at ci_hdrc_imx, it needs to call usbmisc_imx's interface
at its removal function once we enable wakeup/runtime pm function, so
keeping two drivers together will not work at loadable module use case.

To fix loadable module use case, we need to build usbmisc_imx and
ci_hdrc_imx together as one module, the usbmisc_imx still handles
misc setting for controllers.

The first one of this serial has no relateship with this topic, but
it is related to rename file, and the other patches will use the new
file name, so I hope they can be queued together.

Peter Chen (5):
  usb: chipidea: imx: rename the DT doc name
  usb: chipidea: usbmisc_imx: Using regmap to access register
  usb: chipidea: imx: build ci_hdrc_imx.c and usbmisc_imx.c together
  arm: dts: imx: add aliases for usb
  arm: dts: imx: Delete usbmisc_imx

 .../devicetree/bindings/usb/ci13xxx-imx.txt|   31 ---
 .../devicetree/bindings/usb/ci_hdrc_imx.txt|   35 +++
 Documentation/devicetree/bindings/usb/mxs-phy.txt  |   13 --
 .../devicetree/bindings/usb/phy-mxs-usb.txt|   13 ++
 .../devicetree/bindings/usb/usbmisc-imx.txt|   14 --
 arch/arm/boot/dts/imx23.dtsi   |1 +
 arch/arm/boot/dts/imx25.dtsi   |   14 +-
 arch/arm/boot/dts/imx28.dtsi   |2 +
 arch/arm/boot/dts/imx51.dtsi   |   20 +-
 arch/arm/boot/dts/imx53.dtsi   |   20 +-
 arch/arm/boot/dts/imx6qdl.dtsi |   20 +-
 drivers/usb/chipidea/ci_hdrc_imx.c |  113 +--
 drivers/usb/chipidea/ci_hdrc_imx.h |   28 ++--
 drivers/usb/chipidea/usbmisc_imx.c |  217 +++-
 drivers/usb/chipidea/usbmisc_imx.h |   14 ++
 15 files changed, 201 insertions(+), 354 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/usb/ci13xxx-imx.txt
 create mode 100644 Documentation/devicetree/bindings/usb/ci_hdrc_imx.txt
 delete mode 100644 Documentation/devicetree/bindings/usb/mxs-phy.txt
 create mode 100644 Documentation/devicetree/bindings/usb/phy-mxs-usb.txt
 delete mode 100644 Documentation/devicetree/bindings/usb/usbmisc-imx.txt
 create mode 100644 drivers/usb/chipidea/usbmisc_imx.h


--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 3/5] usb: chipidea: imx: build ci_hdrc_imx.c and usbmisc_imx.c together

2013-08-08 Thread Peter Chen
At former design, both ci13xxx_imx and usbmisc_imx are individual
module, ci13xxx_imx is glue layer for imx usb driver. usbmisc_imx
handles non-core registers which have different register layout
for imx SoC serials, it usually supplies interface for wakeup
setting, PHY setting, etc.

usbmisc_imx uses symbols from ci_hdrc_imx, So, when we combile both
of drivers as loadable module, usbmisc is needed to be unload first.
However at ci_hdrc_imx, it needs to call usbmisc_imx's interface
at its removal function once we enable wakeup/runtime pm function, so
keeping two drivers together will not work at loadable module use case.

To fix loadable module use case, we need to build usbmisc_imx and
ci_hdrc_imx together as one module, the usbmisc_imx still handles
misc setting for controllers.

There is a short discussion for it:
http://marc.info/?l=linux-usbm=136861599423172w=2

Signed-off-by: Peter Chen peter.c...@freescale.com
---
 drivers/usb/chipidea/ci_hdrc_imx.c |  113 +++---
 drivers/usb/chipidea/ci_hdrc_imx.h |   28 +++---
 drivers/usb/chipidea/usbmisc_imx.c |  186 +++-
 drivers/usb/chipidea/usbmisc_imx.h |   14 +++
 4 files changed, 98 insertions(+), 243 deletions(-)

diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c 
b/drivers/usb/chipidea/ci_hdrc_imx.c
index 30fdc2f..be7c86f 100644
--- a/drivers/usb/chipidea/ci_hdrc_imx.c
+++ b/drivers/usb/chipidea/ci_hdrc_imx.c
@@ -19,68 +19,68 @@
 #include linux/dma-mapping.h
 #include linux/usb/chipidea.h
 #include linux/clk.h
+#include linux/mfd/syscon.h
 
 #include ci.h
 #include ci_hdrc_imx.h
+#include usbmisc_imx.h
 
-struct ci_hdrc_imx_data {
-   struct usb_phy *phy;
-   struct platform_device *ci_pdev;
-   struct clk *clk;
+static const struct of_device_id ci_hdrc_imx_dt_ids[] = {
+   {
+   .compatible = fsl,imx25-usb,
+   .data = imx25_usbmisc_data,
+   },
+   {
+   .compatible = fsl,imx53-usb,
+   .data = imx53_usbmisc_data,
+   },
+   {
+   .compatible = fsl,imx6q-usb,
+   .data = imx6q_usbmisc_data,
+   },
+   { /* sentinel */ }
 };
+MODULE_DEVICE_TABLE(of, ci_hdrc_imx_dt_ids);
 
-static const struct usbmisc_ops *usbmisc_ops;
-
-/* Common functions shared by usbmisc drivers */
-
-int usbmisc_set_ops(const struct usbmisc_ops *ops)
-{
-   if (usbmisc_ops)
-   return -EBUSY;
-
-   usbmisc_ops = ops;
-
-   return 0;
-}
-EXPORT_SYMBOL_GPL(usbmisc_set_ops);
-
-void usbmisc_unset_ops(const struct usbmisc_ops *ops)
-{
-   usbmisc_ops = NULL;
-}
-EXPORT_SYMBOL_GPL(usbmisc_unset_ops);
-
-int usbmisc_get_init_data(struct device *dev, struct usbmisc_usb_device 
*usbdev)
+static int usbmisc_init(struct device *dev)
 {
struct device_node *np = dev-of_node;
-   struct of_phandle_args args;
+   struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
int ret;
+   const struct of_device_id *of_id =
+   of_match_device(ci_hdrc_imx_dt_ids, dev);
 
-   usbdev-dev = dev;
+   if (of_id-data)
+   data-misc_data = (struct usbmisc_data *)of_id-data;
+   else
+   dev_dbg(dev, no usbmisc data\n);
 
-   ret = of_parse_phandle_with_args(np, fsl,usbmisc, #index-cells,
-   0, args);
-   if (ret) {
-   dev_err(dev, Failed to parse property fsl,usbmisc, errno %d\n,
-   ret);
-   memset(usbdev, 0, sizeof(*usbdev));
+   ret = of_alias_get_id(np, usb);
+   if (ret  0) {
+   dev_err(dev, failed to get alias id, errno %d\n, ret);
return ret;
}
-   usbdev-index = args.args[0];
-   of_node_put(args.np);
 
if (of_find_property(np, disable-over-current, NULL))
-   usbdev-disable_oc = 1;
+   data-disable_oc = 1;
 
if (of_find_property(np, external-vbus-divider, NULL))
-   usbdev-evdo = 1;
+   data-evdo = 1;
+
+   /* Currently, the usbmisc only handles non core register stuffs */
+   if (!data-misc_data)
+   return 0;
+
+   data-regmap = syscon_regmap_lookup_by_phandle
+   (np, ci,noncore);
+   if (IS_ERR(data-regmap)) {
+   dev_err(dev, can't find non-core regmap: %ld\n,
+   PTR_ERR(data-regmap));
+   return PTR_ERR(data-regmap);
+   }
 
return 0;
 }
-EXPORT_SYMBOL_GPL(usbmisc_get_init_data);
-
-/* End of common functions shared by usbmisc drivers*/
-
 static int ci_hdrc_imx_probe(struct platform_device *pdev)
 {
struct ci_hdrc_imx_data *data;
@@ -93,10 +93,6 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
};
int ret;
 
-   if (of_find_property(pdev-dev.of_node, fsl,usbmisc, NULL)
-!usbmisc_ops)
-   return -EPROBE_DEFER;
-
data = devm_kzalloc(pdev-dev, sizeof

[PATCH v2 4/5] arm: dts: imx: add aliases for usb

2013-08-08 Thread Peter Chen
At imx usb driver, it needs to know the controller id to access
register.

Signed-off-by: Peter Chen peter.c...@freescale.com
---
 arch/arm/boot/dts/imx23.dtsi   |1 +
 arch/arm/boot/dts/imx28.dtsi   |2 ++
 arch/arm/boot/dts/imx51.dtsi   |4 
 arch/arm/boot/dts/imx53.dtsi   |4 
 arch/arm/boot/dts/imx6qdl.dtsi |4 
 5 files changed, 15 insertions(+), 0 deletions(-)

diff --git a/arch/arm/boot/dts/imx23.dtsi b/arch/arm/boot/dts/imx23.dtsi
index 587ceef..a0d8471 100644
--- a/arch/arm/boot/dts/imx23.dtsi
+++ b/arch/arm/boot/dts/imx23.dtsi
@@ -20,6 +20,7 @@
gpio2 = gpio2;
serial0 = auart0;
serial1 = auart1;
+   usb0 = usb0;
};
 
cpus {
diff --git a/arch/arm/boot/dts/imx28.dtsi b/arch/arm/boot/dts/imx28.dtsi
index 9524a05..931be9c 100644
--- a/arch/arm/boot/dts/imx28.dtsi
+++ b/arch/arm/boot/dts/imx28.dtsi
@@ -29,6 +29,8 @@
serial4 = auart4;
ethernet0 = mac0;
ethernet1 = mac1;
+   usb0 = usb0;
+   usb1 = usb1;
};
 
cpus {
diff --git a/arch/arm/boot/dts/imx51.dtsi b/arch/arm/boot/dts/imx51.dtsi
index 25764b5..67f114c 100644
--- a/arch/arm/boot/dts/imx51.dtsi
+++ b/arch/arm/boot/dts/imx51.dtsi
@@ -22,6 +22,10 @@
gpio1 = gpio2;
gpio2 = gpio3;
gpio3 = gpio4;
+   usb0 = usbotg;
+   usb1 = usbh1;
+   usb2 = usbh2;
+   usb3 = usbh3;
};
 
tzic: tz-interrupt-controller@e000 {
diff --git a/arch/arm/boot/dts/imx53.dtsi b/arch/arm/boot/dts/imx53.dtsi
index 569aa9f..429a16f 100644
--- a/arch/arm/boot/dts/imx53.dtsi
+++ b/arch/arm/boot/dts/imx53.dtsi
@@ -30,6 +30,10 @@
i2c0 = i2c1;
i2c1 = i2c2;
i2c2 = i2c3;
+   usb0 = usbotg;
+   usb1 = usbh1;
+   usb2 = usbh2;
+   usb3 = usbh3;
};
 
tzic: tz-interrupt-controller@0fffc000 {
diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi
index f21d259..be1811c 100644
--- a/arch/arm/boot/dts/imx6qdl.dtsi
+++ b/arch/arm/boot/dts/imx6qdl.dtsi
@@ -26,6 +26,10 @@
gpio4 = gpio5;
gpio5 = gpio6;
gpio6 = gpio7;
+   usb0 = usbotg;
+   usb1 = usbh1;
+   usb2 = usbh2;
+   usb3 = usbh3;
};
 
intc: interrupt-controller@00a01000 {
-- 
1.7.1


--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 5/5] arm: dts: imx: Delete usbmisc_imx

2013-08-08 Thread Peter Chen
Since ci_hdrc_imx and usbmisc_imx has relationship between each other,
they can't be existed as two modules. We change the code, and make
the usbmisc_imx has no longer a driver.

Due to above reason, we introduce non core register phandle to know
the non core register, and delete the binding doc from usbmisc_imx as well.

Signed-off-by: Peter Chen peter.c...@freescale.com
---
 .../devicetree/bindings/usb/ci_hdrc_imx.txt|   12 
 .../devicetree/bindings/usb/usbmisc-imx.txt|   14 --
 arch/arm/boot/dts/imx25.dtsi   |   14 +-
 arch/arm/boot/dts/imx51.dtsi   |   16 +++-
 arch/arm/boot/dts/imx53.dtsi   |   16 +++-
 arch/arm/boot/dts/imx6qdl.dtsi |   16 +++-
 6 files changed, 34 insertions(+), 54 deletions(-)

diff --git a/Documentation/devicetree/bindings/usb/ci_hdrc_imx.txt 
b/Documentation/devicetree/bindings/usb/ci_hdrc_imx.txt
index b4b5b79..56d94cb 100644
--- a/Documentation/devicetree/bindings/usb/ci_hdrc_imx.txt
+++ b/Documentation/devicetree/bindings/usb/ci_hdrc_imx.txt
@@ -1,4 +1,4 @@
-* Freescale i.MX ci13xxx usb controllers
+* Freescale i.MX chipidea usb controllers
 
 Required properties:
 - compatible: Should be fsl,imx27-usb
@@ -13,8 +13,7 @@ Recommended properies:
 
 Optional properties:
 - fsl,usbphy: phandler of usb phy that connects to the only one port
-- fsl,usbmisc: phandler of non-core register device, with one argument
-  that indicate usb controller index
+- ci,noncore: phandler of non-core register node
 - vbus-supply: regulator for vbus
 - disable-over-current: disable over current detect
 - external-vbus-divider: enables off-chip resistor divider for Vbus
@@ -25,7 +24,12 @@ usb@02184000 { /* USB OTG */
reg = 0x02184000 0x200;
interrupts = 0 43 0x04;
fsl,usbphy = usbphy1;
-   fsl,usbmisc = usbmisc 0;
+   ci,noncore = noncore;
disable-over-current;
external-vbus-divider;
 };
+
+noncore: usb-non-core@02184800 {
+compatible = fsl,imx-usb-non-core, syscon;
+reg = 0x02184800 0x200;
+};
diff --git a/Documentation/devicetree/bindings/usb/usbmisc-imx.txt 
b/Documentation/devicetree/bindings/usb/usbmisc-imx.txt
deleted file mode 100644
index 97ce94e..000
--- a/Documentation/devicetree/bindings/usb/usbmisc-imx.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-* Freescale i.MX non-core registers
-
-Required properties:
-- #index-cells: Cells used to descibe usb controller index. Should be 1
-- compatible: Should be one of below:
-   fsl,imx6q-usbmisc for imx6q
-- reg: Should contain registers location and length
-
-Examples:
-usbmisc@02184800 {
-   #index-cells = 1;
-   compatible = fsl,imx6q-usbmisc;
-   reg = 0x02184800 0x200;
-};
diff --git a/arch/arm/boot/dts/imx25.dtsi b/arch/arm/boot/dts/imx25.dtsi
index 7011539..a09251b 100644
--- a/arch/arm/boot/dts/imx25.dtsi
+++ b/arch/arm/boot/dts/imx25.dtsi
@@ -460,7 +460,7 @@
interrupts = 37;
clocks = clks 9, clks 70, clks 8;
clock-names = ipg, ahb, per;
-   fsl,usbmisc = usbmisc 0;
+   ci,noncore = noncore;
status = disabled;
};
 
@@ -470,17 +470,13 @@
interrupts = 35;
clocks = clks 9, clks 70, clks 8;
clock-names = ipg, ahb, per;
-   fsl,usbmisc = usbmisc 1;
+   ci,noncore = noncore;
status = disabled;
};
 
-   usbmisc: usbmisc@53ff4600 {
-   #index-cells = 1;
-   compatible = fsl,imx25-usbmisc;
-   clocks = clks 9, clks 70, clks 8;
-   clock-names = ipg, ahb, per;
-   reg = 0x53ff4600 0x00f;
-   status = disabled;
+   noncore: usb-non-core@53ff4600 {
+compatible = fsl,imx-usb-non-core, syscon;
+reg = 0x53ff4600 0xf;
};
 
dryice@53ffc000 {
diff --git a/arch/arm/boot/dts/imx51.dtsi b/arch/arm/boot/dts/imx51.dtsi
index 67f114c..8e55499 100644
--- a/arch/arm/boot/dts/imx51.dtsi
+++ b/arch/arm/boot/dts/imx51.dtsi
@@ -191,7 +191,7 @@
reg = 0x73f8 0x0200;
interrupts = 18;
clocks = clks 108;
-   fsl,usbmisc = usbmisc 0;
+   ci,noncore = noncore;
fsl,usbphy = usbphy0;
status = disabled

Re: [PATCH v2 5/5] arm: dts: imx: Delete usbmisc_imx

2013-08-08 Thread Peter Chen
On Thu, Aug 08, 2013 at 12:38:59PM +0200, Sascha Hauer wrote:
 On Thu, Aug 08, 2013 at 03:33:01PM +0800, Peter Chen wrote:
  Since ci_hdrc_imx and usbmisc_imx has relationship between each other,
  they can't be existed as two modules. We change the code, and make
  the usbmisc_imx has no longer a driver.
  
  Due to above reason, we introduce non core register phandle to know
  the non core register, and delete the binding doc from usbmisc_imx as well.
  
  Signed-off-by: Peter Chen peter.c...@freescale.com
  ---
   .../devicetree/bindings/usb/ci_hdrc_imx.txt|   12 
   .../devicetree/bindings/usb/usbmisc-imx.txt|   14 --
   arch/arm/boot/dts/imx25.dtsi   |   14 +-
   arch/arm/boot/dts/imx51.dtsi   |   16 +++-
   arch/arm/boot/dts/imx53.dtsi   |   16 +++-
   arch/arm/boot/dts/imx6qdl.dtsi |   16 +++-
   6 files changed, 34 insertions(+), 54 deletions(-)
  
  diff --git a/Documentation/devicetree/bindings/usb/ci_hdrc_imx.txt 
  b/Documentation/devicetree/bindings/usb/ci_hdrc_imx.txt
  index b4b5b79..56d94cb 100644
  --- a/Documentation/devicetree/bindings/usb/ci_hdrc_imx.txt
  +++ b/Documentation/devicetree/bindings/usb/ci_hdrc_imx.txt
  @@ -1,4 +1,4 @@
  -* Freescale i.MX ci13xxx usb controllers
  +* Freescale i.MX chipidea usb controllers
   
   Required properties:
   - compatible: Should be fsl,imx27-usb
  @@ -13,8 +13,7 @@ Recommended properies:
   
   Optional properties:
   - fsl,usbphy: phandler of usb phy that connects to the only one port
  -- fsl,usbmisc: phandler of non-core register device, with one argument
  -  that indicate usb controller index
  +- ci,noncore: phandler of non-core register node
   - vbus-supply: regulator for vbus
   - disable-over-current: disable over current detect
   - external-vbus-divider: enables off-chip resistor divider for Vbus
  @@ -25,7 +24,12 @@ usb@02184000 { /* USB OTG */
  reg = 0x02184000 0x200;
  interrupts = 0 43 0x04;
  fsl,usbphy = usbphy1;
  -   fsl,usbmisc = usbmisc 0;
  +   ci,noncore = noncore;
  disable-over-current;
  external-vbus-divider;
   };
  +
  +noncore: usb-non-core@02184800 {
  +compatible = fsl,imx-usb-non-core, syscon;
  +reg = 0x02184800 0x200;
  +};
  diff --git a/Documentation/devicetree/bindings/usb/usbmisc-imx.txt 
  b/Documentation/devicetree/bindings/usb/usbmisc-imx.txt
  deleted file mode 100644
  index 97ce94e..000
  --- a/Documentation/devicetree/bindings/usb/usbmisc-imx.txt
  +++ /dev/null
  @@ -1,14 +0,0 @@
  -* Freescale i.MX non-core registers
  -
  -Required properties:
  -- #index-cells: Cells used to descibe usb controller index. Should be 1
  -- compatible: Should be one of below:
  -   fsl,imx6q-usbmisc for imx6q
  -- reg: Should contain registers location and length
  -
  -Examples:
  -usbmisc@02184800 {
  -   #index-cells = 1;
  -   compatible = fsl,imx6q-usbmisc;
  -   reg = 0x02184800 0x200;
  -};
  diff --git a/arch/arm/boot/dts/imx25.dtsi b/arch/arm/boot/dts/imx25.dtsi
  index 7011539..a09251b 100644
  --- a/arch/arm/boot/dts/imx25.dtsi
  +++ b/arch/arm/boot/dts/imx25.dtsi
  @@ -460,7 +460,7 @@
  interrupts = 37;
  clocks = clks 9, clks 70, clks 8;
  clock-names = ipg, ahb, per;
  -   fsl,usbmisc = usbmisc 0;
  +   ci,noncore = noncore;
  status = disabled;
  };
   
  @@ -470,17 +470,13 @@
  interrupts = 35;
  clocks = clks 9, clks 70, clks 8;
  clock-names = ipg, ahb, per;
  -   fsl,usbmisc = usbmisc 1;
  +   ci,noncore = noncore;
  status = disabled;
  };
   
  -   usbmisc: usbmisc@53ff4600 {
  -   #index-cells = 1;
  -   compatible = fsl,imx25-usbmisc;
  -   clocks = clks 9, clks 70, clks 8;
  -   clock-names = ipg, ahb, per;
  -   reg = 0x53ff4600 0x00f;
  -   status = disabled;
  +   noncore: usb-non-core@53ff4600 {
  +compatible = fsl,imx-usb-non-core, syscon;
  +reg = 0x53ff4600 0xf;
  };
 
 This is bullshit for multiple reasons.
 
 It's the usbmisc unit that changes between different SoCs, not the
 chipidea core. So pretending the usbmisc unit is generic by removing the
 SoC specific compatible and instead leaking in the SoC type from the
 chipidea device nodes is just crazy.
 

Please do not call usbmisc as unit, it should not be a driver, it is
a lib, it is usbmisc-lib to implement functions

Re: [PATCH v2 5/5] arm: dts: imx: Delete usbmisc_imx

2013-08-09 Thread Peter Chen
On Fri, Aug 09, 2013 at 08:20:45AM +0200, Sascha Hauer wrote:
 On Thu, Aug 08, 2013 at 06:19:43PM +0800, Peter Chen wrote:
-   compatible = fsl,imx25-usbmisc;
-   clocks = clks 9, clks 70, clks 
8;
-   clock-names = ipg, ahb, per;
-   reg = 0x53ff4600 0x00f;
-   status = disabled;
+   noncore: usb-non-core@53ff4600 {
+compatible = fsl,imx-usb-non-core, 
syscon;
+reg = 0x53ff4600 0xf;
};
   
   This is bullshit for multiple reasons.
   
   It's the usbmisc unit that changes between different SoCs, not the
   chipidea core. So pretending the usbmisc unit is generic by removing the
   SoC specific compatible and instead leaking in the SoC type from the
   chipidea device nodes is just crazy.
   
  
  Please do not call usbmisc as unit, it should not be a driver, it is
  a lib, it is usbmisc-lib to implement functions for controller
  driver.
  
  At current design, there are two drivers (ci_hdrc_imx  usbmisc_imx) to
  control one hardware (one imx usb controller). You will need to control
  the same clocks at two drivers, it is not a good idea.
 
 It's more meaningful to talk about devices instead of drivers. The USB
 core consists of three (on most i.MX) devices, namely three identical
 chipidea cores. The clocks are shared between all these devices and the
 clock framework handles this just fine due to reference counting.
 

Three devices? What do you mean? host, device, and otg at former fsl
usb driver framework?

You know it is better together the resources, something like register
mapping, clocks, etc. The less place we put clock we the less error
we will meet especially when we introduce runtime power management.

  Besides, there
  are dependencies between two drivers, the usbmisc will be unloaded
  first, how usbmisc can supply the functions after it is unloaded?
  Remember, it is one hardware, why one driver can forbid another to use
  controller's function?
  
   What you are doing here is to model the DT after how the Linux driver is
   programmed. This really is a bad idea. Remember that the bindings have
   to be OS agnostic. They can't be changed just because you want to
   resolve your module probe dependencies.
  
  I am a beginner for DT, how DT binding can't be changed if the driver
  has re-designed? If I understand correctly, you say bindings have to
  be OS agnostic, you mean the same DT can be used at all late Linux 
  versions after the binding has finished, is it correct?
 
 And not only Linux, but also *BSD and others. Currently I use the same
 bindings for barebox which means I would have to change the bindings
 there aswell once you change them in the Kernel.
 

Understand, just like other ABIs, such as sys ctrl, ioctl, etc.
So the binding review should be careful and no regression.

  
  Again, binding is for driver, if it is not suitable as a driver, what 
  the meaningful for the existent of binding? 
 
 Maybe I would believe you if you removed the need for a driver, but what
 you do is to replace a 'usbmisc driver' handling a 'usbmisc device' with
 a 'syscon driver' handling a 'syscon device'. The real change here is
 that the implementation of the driver logic is moved from the usbmisc
 driver to the chipidea driver.
 

Yes, since all chipidea devices need to visit the same register mapping.

-- 

Best Regards,
Peter Chen

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/2] USB: chipidea: i.MX: simplify usbmisc

2013-08-09 Thread Peter Chen
On Fri, Aug 09, 2013 at 08:56:56AM +0200, Sascha Hauer wrote:
 The chipidea i.MX driver is split into two drivers. The ci_hdrc_imx driver
 handles the chipidea cores and the usbmisc_imx driver handles the noncore
 registers common to all chipidea cores (but SoC specific). Current flow is:
 
 - usbmisc sets an ops pointer in the ci_hdrc_imx driver during probe
 - ci_hdrc_imx checks if the pointer is valid during probe, if yes calls
   the functions in the ops pointer.
 - usbmisc_imx calls back into the ci_hdrc_imx driver to get additional
   data
 
 This is overly complicated and has problems if the drivers are compiled
 as modules. In this case the usbmisc_imx driver can be unloaded even if
 the ci_hdrc_imx driver still needs usbmisc functionality.
 
 This patch changes this by letting the ci_hdrc_imx driver calling functions
 from the usbmisc_imx driver. This way the symbol resolving during module
 load makes sure the ci_hdrc_imx driver depends on the usbmisc_imx driver.
 
 Also instead of letting the usbmisc_imx driver call back into the ci_hdrc_imx
 driver, pass the needed data in the first place.
 
 Signed-off-by: Sascha Hauer s.ha...@pengutronix.de
 ---
  drivers/usb/chipidea/ci_hdrc_imx.c | 74 +++--
  drivers/usb/chipidea/ci_hdrc_imx.h | 17 ++-
  drivers/usb/chipidea/usbmisc_imx.c | 95 
 +-
  3 files changed, 72 insertions(+), 114 deletions(-)
 
 diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c 
 b/drivers/usb/chipidea/ci_hdrc_imx.c
 index 11ed423..7e722fe 100644
 --- a/drivers/usb/chipidea/ci_hdrc_imx.c
 +++ b/drivers/usb/chipidea/ci_hdrc_imx.c
 @@ -29,57 +29,43 @@ struct ci_hdrc_imx_data {
   struct platform_device *ci_pdev;
   struct clk *clk;
   struct regulator *reg_vbus;
 + struct imx_usbmisc_data *usbmisc_data;
  };
  
 -static const struct usbmisc_ops *usbmisc_ops;
 -
  /* Common functions shared by usbmisc drivers */
  
 -int usbmisc_set_ops(const struct usbmisc_ops *ops)
 -{
 - if (usbmisc_ops)
 - return -EBUSY;
 -
 - usbmisc_ops = ops;
 -
 - return 0;
 -}
 -EXPORT_SYMBOL_GPL(usbmisc_set_ops);
 -
 -void usbmisc_unset_ops(const struct usbmisc_ops *ops)
 -{
 - usbmisc_ops = NULL;
 -}
 -EXPORT_SYMBOL_GPL(usbmisc_unset_ops);
 -
 -int usbmisc_get_init_data(struct device *dev, struct usbmisc_usb_device 
 *usbdev)
 +static struct imx_usbmisc_data *usbmisc_get_init_data(struct device *dev)
  {
   struct device_node *np = dev-of_node;
   struct of_phandle_args args;
 + struct imx_usbmisc_data *data;
   int ret;
  
 - usbdev-dev = dev;
 + if (!of_get_property(np, fsl,usbmisc, NULL))
 + return NULL;
  
   ret = of_parse_phandle_with_args(np, fsl,usbmisc, #index-cells,
   0, args);
   if (ret) {
   dev_err(dev, Failed to parse property fsl,usbmisc, errno %d\n,
   ret);
 - memset(usbdev, 0, sizeof(*usbdev));
 - return ret;
 + return ERR_PTR(ret);
   }
 - usbdev-index = args.args[0];
 - of_node_put(args.np);

Is it a bug fix?

 +
 + data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
 + if (!data)
 + return ERR_PTR(-ENOMEM);
 +
 + data-index = args.args[0];
  
   if (of_find_property(np, disable-over-current, NULL))
 - usbdev-disable_oc = 1;
 + data-disable_oc = 1;
  
   if (of_find_property(np, external-vbus-divider, NULL))
 - usbdev-evdo = 1;
 + data-evdo = 1;
  
 - return 0;
 + return data;
  }
 -EXPORT_SYMBOL_GPL(usbmisc_get_init_data);
  
  /* End of common functions shared by usbmisc drivers*/
  
 @@ -96,10 +82,6 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
   struct resource *res;
   int ret;
  
 - if (of_find_property(pdev-dev.of_node, fsl,usbmisc, NULL)
 -  !usbmisc_ops)
 - return -EPROBE_DEFER;
 -
   data = devm_kzalloc(pdev-dev, sizeof(*data), GFP_KERNEL);
   if (!data) {
   dev_err(pdev-dev, Failed to allocate ci_hdrc-imx data!\n);
 @@ -112,6 +94,10 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
   return -ENOENT;
   }
  
 + data-usbmisc_data = usbmisc_get_init_data(pdev-dev);
 + if (IS_ERR(data-usbmisc_data))
 + return PTR_ERR(data-usbmisc_data);
 +

You need to consider mx23/mx28 case which doesn't have usbmisc.

Your version can fix current loadable module problem, and it is also
easy to add new ops in future. After fixing mx23/mx28 case, we can use
your version.

-- 

Best Regards,
Peter Chen

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v14 06/12] usb: chipidea: add flag CI_HDRC_DUAL_ROLE_NOT_OTG

2013-08-09 Thread Peter Chen
On Fri, Aug 09, 2013 at 03:55:56PM +0300, Alexander Shishkin wrote:
 Peter Chen peter.c...@freescale.com writes:
 
  Since we need otgsc to know vbus's status at some chipidea
  controllers even it is peripheral-only mode. Besides, some
  SoCs (eg, AR9331 SoC) don't have otgsc register even
  the DCCPARAMS_DC and DCCPARAMS_HC are both 1 at CAP_DCCPARAMS.
 
  We inroduce flag CI_HDRC_DUAL_ROLE_NOT_OTG to indicate if the
  controller is dual role, but not supports OTG. If this flag is
  not set, we follow the rule that if DCCPARAMS_DC and DCCPARAMS_HC
  are both 1 at CAP_DCCPARAMS, then this controller is otg capable.
 
  Signed-off-by: Peter Chen peter.c...@freescale.com
  ---
   drivers/usb/chipidea/core.c  |   38 +++---
   include/linux/usb/chipidea.h |5 +
   2 files changed, 36 insertions(+), 7 deletions(-)
 
  diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
  index bfc9aef..2ae18fd 100644
  --- a/drivers/usb/chipidea/core.c
  +++ b/drivers/usb/chipidea/core.c
  @@ -426,6 +426,18 @@ static inline void ci_role_destroy(struct ci_hdrc *ci)
  ci_hdrc_host_destroy(ci);
   }
   
  +static void ci_get_otg_capable(struct ci_hdrc *ci)
  +{
  +   if (ci-platdata-flags  CI_HDRC_DUAL_ROLE_NOT_OTG)
  +   ci-is_otg = false;
  +   else
  +   ci-is_otg = (hw_read(ci, CAP_DCCPARAMS,
  +   DCCPARAMS_DC | DCCPARAMS_HC)
  +   == (DCCPARAMS_DC | DCCPARAMS_HC));
  +   if (ci-is_otg)
  +   dev_dbg(ci-dev, It is OTG capable controller\n);
  +}
  +
   static int ci_hdrc_probe(struct platform_device *pdev)
   {
  struct device   *dev = pdev-dev;
  @@ -482,6 +494,9 @@ static int ci_hdrc_probe(struct platform_device *pdev)
  return -ENODEV;
  }
   
  +   /* To know if controller is OTG capable or not */
  +   ci_get_otg_capable(ci);
 
 The comment is redundant.
 

Will delete

  +   } else {
  +   /*
  +* If the controller is not OTG capable, but support
  +* role switch, the defalt role is gadget, and the
  +* user can switch it through debugfs (proc in future?)
 
 It's not going to be in procfs ever, so that part of the comment can go.
 

I can delete now, but the role switch does not a debug function, we
may not put it at debugfs, do you think so?

  +*/
  +   ci-role = CI_ROLE_GADGET;
 
 I think we might need a config option for this in the future, at least.
 

Yes, we can add CONFIG_CI_DEFAULT_ROLE in the future.

-- 

Best Regards,
Peter Chen

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v14 04/12] usb: chipidea: otg: Add otg file used to access otgsc

2013-08-09 Thread Peter Chen
On Fri, Aug 09, 2013 at 04:00:13PM +0300, Alexander Shishkin wrote:
 Peter Chen peter.c...@freescale.com writes:
 
  This file is mainly used to access otgsc currently, it may
  add otg related things in the future.
 
  Tested-by: Marek Vasut ma...@denx.de
  Signed-off-by: Peter Chen peter.c...@freescale.com
  ---
   drivers/usb/chipidea/Makefile |2 +-
   drivers/usb/chipidea/bits.h   |   10 
   drivers/usb/chipidea/core.c   |3 +-
   drivers/usb/chipidea/otg.c|   50 
  +
   drivers/usb/chipidea/otg.h|   19 +++
   5 files changed, 82 insertions(+), 2 deletions(-)
 
  diff --git a/drivers/usb/chipidea/Makefile b/drivers/usb/chipidea/Makefile
  index 6cf5f68..a99d980 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/bits.h b/drivers/usb/chipidea/bits.h
  index aefa026..dd0cf9e 100644
  --- a/drivers/usb/chipidea/bits.h
  +++ b/drivers/usb/chipidea/bits.h
  @@ -79,11 +79,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/core.c b/drivers/usb/chipidea/core.c
  index 26f6599..a4be8a5 100644
  --- a/drivers/usb/chipidea/core.c
  +++ b/drivers/usb/chipidea/core.c
  @@ -72,6 +72,7 @@
   #include bits.h
   #include host.h
   #include debug.h
  +#include otg.h
   
   /* Controller register map */
   static uintptr_t ci_regs_nolpm[] = {
  @@ -530,7 +531,7 @@ static int ci_hdrc_probe(struct platform_device *pdev)
  goto stop;
   
  if (ci-is_otg)
  -   hw_write(ci, OP_OTGSC, OTGSC_IDIE, OTGSC_IDIE);
  +   ci_hdrc_otg_init(ci);
   
  ret = dbg_create_files(ci);
  if (!ret)
  diff --git a/drivers/usb/chipidea/otg.c b/drivers/usb/chipidea/otg.c
  new file mode 100644
  index 000..abefb4d
  --- /dev/null
  +++ b/drivers/usb/chipidea/otg.c
  @@ -0,0 +1,50 @@
  +/*
  + * otg.c - ChipIdea USB IP core OTG driver
  + *
  + * Copyright (C) 2013 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.
  + */
  +
  +/*
  + * This file mainly handles otgsc register, it may include OTG operation
  + * in the future.
  + */
  +
  +#include linux/usb/otg.h
  +#include linux/usb/gadget.h
  +#include linux/usb/chipidea.h
  +
  +#include ci.h
  +#include bits.h
 
 You don't include otg.h here, which makes sparse think that you wanted
 these functions to be static.
 

Will add

  +
  +void ci_clear_otg_interrupt(struct ci_hdrc *ci, u32 bits)
  +{
  +   /* Only clear request bits */
  +   hw_write(ci, OP_OTGSC, OTGSC_INT_STATUS_BITS, bits);
  +}
  +
  +void ci_enable_otg_interrupt(struct ci_hdrc *ci, u32 bits)
  +{
  +   hw_write(ci, OP_OTGSC, bits, bits);
  +}
  +
  +void ci_disable_otg_interrupt(struct ci_hdrc *ci, u32 bits)
  +{
  +   hw_write(ci, OP_OTGSC, bits, 0);
  +}
 
 These functions look like they would be better off as static inlines in
 otg.h than here.
 

Will do

-- 

Best Regards,
Peter Chen

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v14 11/12] usb: chipidea: udc: misuse flag CI_HDRC_REGS_SHARED and CI_HDRC_PULLUP_ON_VBUS

2013-08-09 Thread Peter Chen
On Fri, Aug 09, 2013 at 04:23:11PM +0300, Alexander Shishkin wrote:
 Peter Chen peter.c...@freescale.com writes:
 
  CI_HDRC_REGS_SHARED stands for the controller registers is shared
  with other USB drivers, if all USB drivers are at chipidea/, it doesn't
  needed to set.
 
 We still have the msm driver that uses REGS_SHARED.
 

Yes, I have considered it. At udc interrupt handler, the REGS_SHARED
is still used. The msm set both CI_HDRC_REGS_SHARED and CI_HDRC_PULLUP_ON_VBUS.

  CI_HDRC_PULLUP_ON_VBUS stands for pullup dp when the vbus is on. This
  flag doesn't need to set if the vbus is always on for gadget
  since dp has always pulled up after the gadget has initialized.
 
 Didn't we agree at some point to get rid of this flag altogether once we
 have proper VBUS detection?

Yes, we can delete it now, the reason why I haven't remove it is:
I met some use cases that the vbus is always on recently,
no connection/disconnection. Eg, the USB audio device connects
to Apple Sound machine, the vbus is the power of the device system.

I checked the code just now again, we can cover such kind of case.

-- 

Best Regards,
Peter Chen

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v14 11/12] usb: chipidea: udc: misuse flag CI_HDRC_REGS_SHARED and CI_HDRC_PULLUP_ON_VBUS

2013-08-09 Thread Peter Chen
On Fri, Aug 09, 2013 at 07:46:00PM +0800, Peter Chen wrote:
 On Fri, Aug 09, 2013 at 04:23:11PM +0300, Alexander Shishkin wrote:
  Peter Chen peter.c...@freescale.com writes:
  
   CI_HDRC_REGS_SHARED stands for the controller registers is shared
   with other USB drivers, if all USB drivers are at chipidea/, it doesn't
   needed to set.
  
  We still have the msm driver that uses REGS_SHARED.
  
 
 Yes, I have considered it. At udc interrupt handler, the REGS_SHARED
 is still used. The msm set both CI_HDRC_REGS_SHARED and 
 CI_HDRC_PULLUP_ON_VBUS.
 
   CI_HDRC_PULLUP_ON_VBUS stands for pullup dp when the vbus is on. This
   flag doesn't need to set if the vbus is always on for gadget
   since dp has always pulled up after the gadget has initialized.
  
  Didn't we agree at some point to get rid of this flag altogether once we
  have proper VBUS detection?
 
 Yes, we can delete it now, the reason why I haven't remove it is:
 I met some use cases that the vbus is always on recently,
 no connection/disconnection. Eg, the USB audio device connects
 to Apple Sound machine, the vbus is the power of the device system.
 
 I checked the code just now again, we can cover such kind of case.

I will have a patch to delete CI_HDRC_PULLUP_ON_VBUS. If we squash
two patches, the change like below:

diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c 
b/drivers/usb/chipidea/ci_hdrc_imx.c
index bd1fe25..ab3e74a 100644
--- a/drivers/usb/chipidea/ci_hdrc_imx.c
+++ b/drivers/usb/chipidea/ci_hdrc_imx.c
@@ -91,7 +91,6 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
.name   = ci_hdrc_imx,
.capoffset  = DEF_CAPOFFSET,
.flags  = CI_HDRC_REQUIRE_TRANSCEIVER |
- CI_HDRC_PULLUP_ON_VBUS |
  CI_HDRC_DISABLE_STREAMING,
};
int ret;
diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c 
b/drivers/usb/chipidea/ci_hdrc_msm.c
index fb657ef..2d51d85 100644
--- a/drivers/usb/chipidea/ci_hdrc_msm.c
+++ b/drivers/usb/chipidea/ci_hdrc_msm.c
@@ -49,7 +49,6 @@ static struct ci_hdrc_platform_data ci_hdrc_msm_platdata = {
.name   = ci_hdrc_msm,
.flags  = CI_HDRC_REGS_SHARED |
  CI_HDRC_REQUIRE_TRANSCEIVER |
- CI_HDRC_PULLUP_ON_VBUS |
  CI_HDRC_DISABLE_STREAMING,
 
.notify_event   = ci_hdrc_msm_notify_event,
diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
index c70ce38..f77c904 100644
--- a/drivers/usb/chipidea/udc.c
+++ b/drivers/usb/chipidea/udc.c
@@ -1635,14 +1635,11 @@ static int ci_udc_start(struct usb_gadget *gadget,
 
ci-driver = driver;
pm_runtime_get_sync(ci-gadget.dev);
-   if (ci-platdata-flags  CI_HDRC_PULLUP_ON_VBUS) {
-   if (ci-vbus_active) {
-   if (ci-platdata-flags  CI_HDRC_REGS_SHARED)
-   hw_device_reset(ci, USBMODE_CM_DC);
-   } else {
-   pm_runtime_put_sync(ci-gadget.dev);
-   goto done;
-   }
+   if (ci-vbus_active) {
+   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);
@@ -1665,8 +1662,7 @@ static int ci_udc_stop(struct usb_gadget *gadget,
 
spin_lock_irqsave(ci-lock, flags);
 
-   if (!(ci-platdata-flags  CI_HDRC_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,
@@ -1801,12 +1797,6 @@ static int udc_start(struct ci_hdrc *ci)
}
}
 
-   if (!(ci-platdata-flags  CI_HDRC_REGS_SHARED)) {
-   retval = hw_device_reset(ci, USBMODE_CM_DC);
-   if (retval)
-   goto put_transceiver;
-   }
-
if (ci-transceiver) {
retval = otg_set_peripheral(ci-transceiver-otg,
ci-gadget);
diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h
index 10a607c..7c4ba37 100644
--- a/include/linux/usb/chipidea.h
+++ b/include/linux/usb/chipidea.h
@@ -18,13 +18,12 @@ struct ci_hdrc_platform_data {
unsigned longflags;
 #define CI_HDRC_REGS_SHAREDBIT(0)
 #define CI_HDRC_REQUIRE_TRANSCEIVERBIT(1)
-#define CI_HDRC_PULLUP_ON_VBUS BIT(2)
-#define CI_HDRC_DISABLE_STREAMING  BIT(3)
+#define CI_HDRC_DISABLE_STREAMING  BIT(2)
/*
 * Only set it when DCCPARAMS.DC==1 and DCCPARAMS.HC==1,
 * but otg is not supported (no register otgsc).
 */
-#define CI_HDRC_DUAL_ROLE_NOT_OTG  BIT(4)
+#define

Re: [PATCH] usb: chipidea: enable to build host support as module

2013-08-11 Thread Peter Chen
On Sun, Aug 11, 2013 at 01:00:49PM +0200, Luka Perkov wrote:
 USB_CHIPIDEA_HOST does not need to depend on USB=y, USB_CHIPIDEA_HOST will 
 work
 just fine even if USB=m is used. The depends line can be safely removed since
 USB_CHIPIDEA already depends on USB.
 
 Tested on Gateworks imx6q Ventana board (gw-5400-a) and imx6dl Wandboard Dual
 (imx6dl-wandboard).
 
 Signed-off-by: Luka Perkov l...@openwrt.org
 ---
  drivers/usb/chipidea/Kconfig | 1 -
  1 file changed, 1 deletion(-)
 
 diff --git a/drivers/usb/chipidea/Kconfig b/drivers/usb/chipidea/Kconfig
 index d1bd8ef..3eb5a31 100644
 --- a/drivers/usb/chipidea/Kconfig
 +++ b/drivers/usb/chipidea/Kconfig
 @@ -19,7 +19,6 @@ config USB_CHIPIDEA_UDC
  
  config USB_CHIPIDEA_HOST
   bool ChipIdea host controller
 - depends on USB=y
   depends on USB_EHCI_HCD=y || (USB_CHIPIDEA=m  USB_EHCI_HCD=m)
   select USB_EHCI_ROOT_HUB_TT
   help

Hi Luka,

Lothar has already posted a solution for it.

http://marc.info/?l=linux-usbm=137533651927159w=2

-- 

Best Regards,
Peter Chen

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v15 02/13] usb: chipidea: host: add vbus regulator control

2013-08-11 Thread Peter Chen
For boards which have board level vbus control (eg, through gpio), we
need to vbus operation according to below rules:
- For host, we need open vbus before start hcd, and close it
after remove hcd.
- For otg, the vbus needs to be on/off when usb role switches.
When the host roles begins, it opens vbus; when the host role
finishes, it closes vbus.

We put vbus operation to host as host is the only vbus user,
When we are at host mode, the vbus is on, when we are not at
host mode, vbus should be off.

Tested-by: Marek Vasut ma...@denx.de
Signed-off-by: Peter Chen peter.c...@freescale.com
---
 drivers/usb/chipidea/host.c |   23 ++-
 1 files changed, 22 insertions(+), 1 deletions(-)

diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c
index 40d0fda..e94e52b 100644
--- a/drivers/usb/chipidea/host.c
+++ b/drivers/usb/chipidea/host.c
@@ -24,6 +24,7 @@
 #include linux/usb.h
 #include linux/usb/hcd.h
 #include linux/usb/chipidea.h
+#include linux/regulator/consumer.h
 
 #include ../host/ehci.h
 
@@ -64,9 +65,19 @@ static int host_start(struct ci_hdrc *ci)
ehci-caps = ci-hw_bank.cap;
ehci-has_hostpc = ci-hw_bank.lpm;
 
+   if (ci-platdata-reg_vbus) {
+   ret = regulator_enable(ci-platdata-reg_vbus);
+   if (ret) {
+   dev_err(ci-dev,
+   Failed to enable vbus regulator, ret=%d\n,
+   ret);
+   goto put_hcd;
+   }
+   }
+
ret = usb_add_hcd(hcd, 0, 0);
if (ret)
-   usb_put_hcd(hcd);
+   goto disable_reg;
else
ci-hcd = hcd;
 
@@ -74,6 +85,14 @@ static int host_start(struct ci_hdrc *ci)
hw_write(ci, OP_USBMODE, USBMODE_CI_SDIS, USBMODE_CI_SDIS);
 
return ret;
+
+disable_reg:
+   regulator_disable(ci-platdata-reg_vbus);
+
+put_hcd:
+   usb_put_hcd(hcd);
+
+   return ret;
 }
 
 static void host_stop(struct ci_hdrc *ci)
@@ -82,6 +101,8 @@ static void host_stop(struct ci_hdrc *ci)
 
usb_remove_hcd(hcd);
usb_put_hcd(hcd);
+   if (ci-platdata-reg_vbus)
+   regulator_disable(ci-platdata-reg_vbus);
 }
 
 int ci_hdrc_host_init(struct ci_hdrc *ci)
-- 
1.7.1


--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v15 01/13] usb: chipidea: move vbus regulator operation to core

2013-08-11 Thread Peter Chen
The vbus regulator is a common element for USB vbus operation,
So, move it from glue layer to core.

Tested-by: Marek Vasut ma...@denx.de
Signed-off-by: Michael Grzeschik m.grzesc...@pengutronix.de
Signed-off-by: Peter Chen peter.c...@freescale.com
---
 drivers/usb/chipidea/ci_hdrc_imx.c |   26 ++
 drivers/usb/chipidea/core.c|   23 +++
 include/linux/usb/chipidea.h   |1 +
 3 files changed, 26 insertions(+), 24 deletions(-)

diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c 
b/drivers/usb/chipidea/ci_hdrc_imx.c
index 35008e3..bd1fe25 100644
--- a/drivers/usb/chipidea/ci_hdrc_imx.c
+++ b/drivers/usb/chipidea/ci_hdrc_imx.c
@@ -19,7 +19,6 @@
 #include linux/dma-mapping.h
 #include linux/usb/chipidea.h
 #include linux/clk.h
-#include linux/regulator/consumer.h
 
 #include ci.h
 #include ci_hdrc_imx.h
@@ -31,7 +30,6 @@ struct ci_hdrc_imx_data {
struct usb_phy *phy;
struct platform_device *ci_pdev;
struct clk *clk;
-   struct regulator *reg_vbus;
 };
 
 static const struct usbmisc_ops *usbmisc_ops;
@@ -134,20 +132,6 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
goto err_clk;
}
 
-   /* we only support host now, so enable vbus here */
-   data-reg_vbus = devm_regulator_get(pdev-dev, vbus);
-   if (!IS_ERR(data-reg_vbus)) {
-   ret = regulator_enable(data-reg_vbus);
-   if (ret) {
-   dev_err(pdev-dev,
-   Failed to enable vbus regulator, err=%d\n,
-   ret);
-   goto err_clk;
-   }
-   } else {
-   data-reg_vbus = NULL;
-   }
-
pdata.phy = data-phy;
 
if (!pdev-dev.dma_mask)
@@ -160,7 +144,7 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
if (ret) {
dev_err(pdev-dev,
usbmisc init failed, ret=%d\n, ret);
-   goto err;
+   goto err_clk;
}
}
 
@@ -172,7 +156,7 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
dev_err(pdev-dev,
Can't register ci_hdrc platform device, err=%d\n,
ret);
-   goto err;
+   goto err_clk;
}
 
if (usbmisc_ops  usbmisc_ops-post) {
@@ -193,9 +177,6 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
 
 disable_device:
ci_hdrc_remove_device(data-ci_pdev);
-err:
-   if (data-reg_vbus)
-   regulator_disable(data-reg_vbus);
 err_clk:
clk_disable_unprepare(data-clk);
return ret;
@@ -208,9 +189,6 @@ static int ci_hdrc_imx_remove(struct platform_device *pdev)
pm_runtime_disable(pdev-dev);
ci_hdrc_remove_device(data-ci_pdev);
 
-   if (data-reg_vbus)
-   regulator_disable(data-reg_vbus);
-
if (data-phy)
usb_phy_shutdown(data-phy);
 
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index 3126c03..26f6599 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -65,6 +65,7 @@
 #include linux/usb/chipidea.h
 #include linux/usb/of.h
 #include linux/phy.h
+#include linux/regulator/consumer.h
 
 #include ci.h
 #include udc.h
@@ -342,6 +343,24 @@ static irqreturn_t ci_irq(int irq, void *data)
return ret;
 }
 
+static int ci_get_platdata(struct device *dev,
+   struct ci_hdrc_platform_data *platdata)
+{
+   /* Get the vbus regulator */
+   platdata-reg_vbus = devm_regulator_get(dev, vbus);
+   if (PTR_ERR(platdata-reg_vbus) == -EPROBE_DEFER) {
+   return -EPROBE_DEFER;
+   } else if (PTR_ERR(platdata-reg_vbus) == -ENODEV) {
+   platdata-reg_vbus = NULL; /* no vbus regualator is needed */
+   } else if (IS_ERR(platdata-reg_vbus)) {
+   dev_err(dev, Getting regulator error: %ld\n,
+   PTR_ERR(platdata-reg_vbus));
+   return PTR_ERR(platdata-reg_vbus);
+   }
+
+   return 0;
+}
+
 static DEFINE_IDA(ci_ida);
 
 struct platform_device *ci_hdrc_add_device(struct device *dev,
@@ -351,6 +370,10 @@ struct platform_device *ci_hdrc_add_device(struct device 
*dev,
struct platform_device *pdev;
int id, ret;
 
+   ret = ci_get_platdata(dev, platdata);
+   if (ret)
+   return ERR_PTR(ret);
+
id = ida_simple_get(ci_ida, 0, 0, GFP_KERNEL);
if (id  0)
return ERR_PTR(id);
diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h
index 2562994..ce4e1aa 100644
--- a/include/linux/usb/chipidea.h
+++ b/include/linux/usb/chipidea.h
@@ -24,6 +24,7 @@ struct ci_hdrc_platform_data {
 #define CI_HDRC_CONTROLLER_RESET_EVENT 0
 #define CI_HDRC_CONTROLLER_STOPPED_EVENT   1
void(*notify_event) (struct ci_hdrc *ci

[PATCH v15 00/13] Add tested id switch and vbus connect detect support for Chipidea

2013-08-11 Thread Peter Chen
This patchset adds tested otg id switch function and vbus connect
and disconnect detection for chipidea driver. And fix kinds of 
bugs found at chipidea drivers after enabling id and vbus detection.

This patch are fully tested at imx6 sabresd and imx28evk platform by me.
Besides, marek tested it on two STMP3780-based boards (not yet mainline)
and two MX28-based boards.

My chipidea repo: https://github.com/hzpeterchen/linux-usb.git

Changes for v15:
- Mark otgsc API as static line, and move them to otg.h [4/13]
- Remove some redundant comments [6/13]
- Fix some typos [8/13]
- Retire flag CI_HDRC_PULLUP_ON_VBUS [12/13] [13/13]

Changes for v14:
- This patchset is based on below recent chipidea patches and newest
usb-next, it can decrease rebase effort.

Fabio Estevam (3):
  chipidea: ci_hdrc_imx: Remove unused variable 'res'
  chipidea: core: Move hw_phymode_configure() into probe
  chipidea: Remove previous MODULE_ALIAS

Lothar Wabmann (3):
  usb: chipidea: improve kconfig 2.0
  usb: chipidea: don't clobber return value of ci_role_start()
  usb: chipidea: ci_hdrc_imx: remove an unsolicited module_put() call
from ci_hdrc_imx_remove()

Peter Chen (1):
  usb: chipidea: fix the build error with randconfig

- [Michael comments]: move vbus operation to core, and squash two vbus
patches. [1/12], [2/12]
- [Michael comments]: move out non vbus and non id related patches. [14/14 at 
v13]

Chagnes for v13:
- Add Tested-by: Marek Vasut ma...@denx.de
- [Sascha's comments]: Add return value check for devm_regulator_get. [3/14]
- [Marc's comments]: Change timeout usage at hw_wait_reg. [11/14]
- [Alex's comments]: Using platdata flag to indicate dual role but not 
OTG controller. [7/14]

Changes for v12:
- Rebased greg's usb-next tree (3.10.0-rc7+)
- Split more small patches for single function and fix.

Peter Chen (12):
  usb: chipidea: move vbus regulator operation to core
  usb: chipidea: host: add vbus regulator control
  usb: chipidea: udc: otg_set_peripheral is useless for some chipidea
users
  usb: chipidea: otg: Add otg file used to access otgsc
  usb: chipidea: Add role init and destory APIs
  usb: chipidea: add flag CI_HDRC_DUAL_ROLE_NOT_OTG
  usb: chipidea: disable all interrupts and clear all interrupts status
  usb: chipidea: move otg relate things to otg file
  usb: chipidea: add vbus interrupt handler
  usb: chipidea: add wait vbus lower than OTGSC_BSV before role starts
  usb: chipidea: udc: misuse flag CI_HDRC_REGS_SHARED and
CI_HDRC_PULLUP_ON_VBUS
  usb: chipidea: udc: .pullup is valid when vbus is on at
CI_HDRC_PULLUP_ON_VBUS

Peter Chen (13):
  usb: chipidea: move vbus regulator operation to core
  usb: chipidea: host: add vbus regulator control
  usb: chipidea: udc: otg_set_peripheral is useless for some chipidea
users
  usb: chipidea: otg: Add otg file used to access otgsc
  usb: chipidea: Add role init and destroy APIs
  usb: chipidea: add flag CI_HDRC_DUAL_ROLE_NOT_OTG
  usb: chipidea: disable all interrupts and clear all interrupts status
  usb: chipidea: move otg related things to otg file
  usb: chipidea: add vbus interrupt handler
  usb: chipidea: add wait vbus lower than OTGSC_BSV before role starts
  usb: chipidea: udc: misuse flag CI_HDRC_REGS_SHARED and
CI_HDRC_PULLUP_ON_VBUS
  usb: chipidea: retire flag CI_HDRC_PULLUP_ON_VBUS
  usb: chipidea: udc: .pullup is valid only when vbus is there

 drivers/usb/chipidea/Makefile  |2 +-
 drivers/usb/chipidea/bits.h|   10 ++
 drivers/usb/chipidea/ci.h  |8 ++
 drivers/usb/chipidea/ci_hdrc_imx.c |   27 +-
 drivers/usb/chipidea/ci_hdrc_msm.c |1 -
 drivers/usb/chipidea/core.c|  183 +---
 drivers/usb/chipidea/host.c|   30 ++-
 drivers/usb/chipidea/host.h|6 +
 drivers/usb/chipidea/otg.c |  120 +++
 drivers/usb/chipidea/otg.h |   35 +++
 drivers/usb/chipidea/udc.c |   78 ++--
 drivers/usb/chipidea/udc.h |6 +
 include/linux/usb/chipidea.h   |7 +-
 13 files changed, 401 insertions(+), 112 deletions(-)
 create mode 100644 drivers/usb/chipidea/otg.c
 create mode 100644 drivers/usb/chipidea/otg.h


--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v15 10/13] usb: chipidea: add wait vbus lower than OTGSC_BSV before role starts

2013-08-11 Thread Peter Chen
When the gadget role starts, we need to make sure the vbus is lower
than OTGSC_BSV, or there will be an vbus interrupt since we use
B_SESSION_VALID as vbus interrupt to indicate connect and disconnect.
When the host role starts, it may not be useful to wait vbus to lower
than OTGSC_BSV, but it can indicate some hardware problems like the
vbus is still higher than OTGSC_BSV after we disconnect to host some
time later (5000 milliseconds currently), which is obvious not correct.

Tested-by: Marek Vasut ma...@denx.de
Signed-off-by: Peter Chen peter.c...@freescale.com
---
 drivers/usb/chipidea/ci.h   |3 +++
 drivers/usb/chipidea/core.c |   32 
 drivers/usb/chipidea/otg.c  |4 
 3 files changed, 39 insertions(+), 0 deletions(-)

diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h
index 3160363..1c94fc5 100644
--- a/drivers/usb/chipidea/ci.h
+++ b/drivers/usb/chipidea/ci.h
@@ -308,4 +308,7 @@ int hw_port_test_set(struct ci_hdrc *ci, u8 mode);
 
 u8 hw_port_test_get(struct ci_hdrc *ci);
 
+int hw_wait_reg(struct ci_hdrc *ci, enum ci_hw_regs reg, u32 mask,
+   u32 value, unsigned int timeout_ms);
+
 #endif /* __DRIVERS_USB_CHIPIDEA_CI_H */
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index ec0bb11..cfeae3c 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -294,6 +294,38 @@ int hw_device_reset(struct ci_hdrc *ci, u32 mode)
return 0;
 }
 
+/**
+ * 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_ms: timeout in millisecond
+ *
+ * This function returns an error code if timeout
+ */
+int hw_wait_reg(struct ci_hdrc *ci, enum ci_hw_regs reg, u32 mask,
+   u32 value, unsigned int timeout_ms)
+{
+   unsigned long elapse = jiffies + msecs_to_jiffies(timeout_ms);
+
+   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;
+}
+
 static irqreturn_t ci_irq(int irq, void *data)
 {
struct ci_hdrc *ci = data;
diff --git a/drivers/usb/chipidea/otg.c b/drivers/usb/chipidea/otg.c
index 7f37484..39bd7ec 100644
--- a/drivers/usb/chipidea/otg.c
+++ b/drivers/usb/chipidea/otg.c
@@ -52,6 +52,7 @@ void ci_handle_vbus_change(struct ci_hdrc *ci)
usb_gadget_vbus_disconnect(ci-gadget);
 }
 
+#define CI_VBUS_STABLE_TIMEOUT_MS 5000
 static void ci_handle_id_switch(struct ci_hdrc *ci)
 {
enum ci_role role = ci_otg_role(ci);
@@ -61,6 +62,9 @@ static void ci_handle_id_switch(struct ci_hdrc *ci)
ci_role(ci)-name, ci-roles[role]-name);
 
ci_role_stop(ci);
+   /* wait vbus lower than OTGSC_BSV */
+   hw_wait_reg(ci, OP_OTGSC, OTGSC_BSV, 0,
+   CI_VBUS_STABLE_TIMEOUT_MS);
ci_role_start(ci, role);
}
 }
-- 
1.7.1


--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v15 11/13] usb: chipidea: udc: misuse flag CI_HDRC_REGS_SHARED and CI_HDRC_PULLUP_ON_VBUS

2013-08-11 Thread Peter Chen
CI_HDRC_REGS_SHARED stands for the controller registers is shared
with other USB drivers, if all USB drivers are at chipidea/, it doesn't
needed to set.
CI_HDRC_PULLUP_ON_VBUS stands for pullup dp when the vbus is on. This
flag doesn't need to set if the vbus is always on for gadget
since dp has always pulled up after the gadget has initialized.

So, the current code seems to misuse this two flags.
- When the gadget initializes, the controller doesn't need to run if
it depends on vbus (CI_HDRC_PULLUP_ON_VBUS), it does not
relate to shared register.
- When the gadget starts (load one gadget module), the controller
can run if vbus is on (CI_HDRC_PULLUP_ON_VBUS), it also does not
relate to shared register.

Tested-by: Marek Vasut ma...@denx.de
Signed-off-by: Peter Chen peter.c...@freescale.com
---
 drivers/usb/chipidea/udc.c |5 ++---
 1 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
index c70ce38..45abf4d 100644
--- a/drivers/usb/chipidea/udc.c
+++ b/drivers/usb/chipidea/udc.c
@@ -1637,8 +1637,7 @@ static int ci_udc_start(struct usb_gadget *gadget,
pm_runtime_get_sync(ci-gadget.dev);
if (ci-platdata-flags  CI_HDRC_PULLUP_ON_VBUS) {
if (ci-vbus_active) {
-   if (ci-platdata-flags  CI_HDRC_REGS_SHARED)
-   hw_device_reset(ci, USBMODE_CM_DC);
+   hw_device_reset(ci, USBMODE_CM_DC);
} else {
pm_runtime_put_sync(ci-gadget.dev);
goto done;
@@ -1801,7 +1800,7 @@ static int udc_start(struct ci_hdrc *ci)
}
}
 
-   if (!(ci-platdata-flags  CI_HDRC_REGS_SHARED)) {
+   if (!(ci-platdata-flags  CI_HDRC_PULLUP_ON_VBUS)) {
retval = hw_device_reset(ci, USBMODE_CM_DC);
if (retval)
goto put_transceiver;
-- 
1.7.1


--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v15 04/13] usb: chipidea: otg: Add otg file used to access otgsc

2013-08-11 Thread Peter Chen
This file is mainly used to access otgsc currently, it may
add otg related things in the future.

Tested-by: Marek Vasut ma...@denx.de
Signed-off-by: Peter Chen peter.c...@freescale.com
---
 drivers/usb/chipidea/Makefile |2 +-
 drivers/usb/chipidea/bits.h   |   10 ++
 drivers/usb/chipidea/core.c   |3 ++-
 drivers/usb/chipidea/otg.c|   35 +++
 drivers/usb/chipidea/otg.h|   32 
 5 files changed, 80 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/chipidea/Makefile b/drivers/usb/chipidea/Makefile
index 6cf5f68..a99d980 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/bits.h b/drivers/usb/chipidea/bits.h
index aefa026..dd0cf9e 100644
--- a/drivers/usb/chipidea/bits.h
+++ b/drivers/usb/chipidea/bits.h
@@ -79,11 +79,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/core.c b/drivers/usb/chipidea/core.c
index 26f6599..a4be8a5 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -72,6 +72,7 @@
 #include bits.h
 #include host.h
 #include debug.h
+#include otg.h
 
 /* Controller register map */
 static uintptr_t ci_regs_nolpm[] = {
@@ -530,7 +531,7 @@ static int ci_hdrc_probe(struct platform_device *pdev)
goto stop;
 
if (ci-is_otg)
-   hw_write(ci, OP_OTGSC, OTGSC_IDIE, OTGSC_IDIE);
+   ci_hdrc_otg_init(ci);
 
ret = dbg_create_files(ci);
if (!ret)
diff --git a/drivers/usb/chipidea/otg.c b/drivers/usb/chipidea/otg.c
new file mode 100644
index 000..999a085
--- /dev/null
+++ b/drivers/usb/chipidea/otg.c
@@ -0,0 +1,35 @@
+/*
+ * otg.c - ChipIdea USB IP core OTG driver
+ *
+ * Copyright (C) 2013 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.
+ */
+
+/*
+ * This file mainly handles otgsc register, it may include OTG operation
+ * in the future.
+ */
+
+#include linux/usb/otg.h
+#include linux/usb/gadget.h
+#include linux/usb/chipidea.h
+
+#include ci.h
+#include bits.h
+#include otg.h
+
+/**
+ * ci_hdrc_otg_init - initialize otgsc bits
+ * ci: the controller
+ */
+int ci_hdrc_otg_init(struct ci_hdrc *ci)
+{
+   ci_enable_otg_interrupt(ci, OTGSC_IDIE);
+
+   return 0;
+}
diff --git a/drivers/usb/chipidea/otg.h b/drivers/usb/chipidea/otg.h
new file mode 100644
index 000..376eaee
--- /dev/null
+++ b/drivers/usb/chipidea/otg.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2013 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.
+ */
+
+#ifndef __DRIVERS_USB_CHIPIDEA_OTG_H
+#define __DRIVERS_USB_CHIPIDEA_OTG_H
+
+static inline void ci_clear_otg_interrupt(struct ci_hdrc *ci, u32 bits)
+{
+   /* Only clear request bits */
+   hw_write(ci, OP_OTGSC, OTGSC_INT_STATUS_BITS, bits);
+}
+
+static inline void ci_enable_otg_interrupt(struct ci_hdrc *ci, u32 bits)
+{
+   hw_write(ci, OP_OTGSC, bits, bits);
+}
+
+static inline void ci_disable_otg_interrupt(struct ci_hdrc *ci, u32 bits)
+{
+   hw_write(ci, OP_OTGSC, bits, 0);
+}
+
+int ci_hdrc_otg_init(struct ci_hdrc *ci);
+
+#endif /* __DRIVERS_USB_CHIPIDEA_OTG_H */
-- 
1.7.1


--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v15 05/13] usb: chipidea: Add role init and destroy APIs

2013-08-11 Thread Peter Chen
- The role's init will be called at probe procedure.
- The role's destroy will be called at fail patch
at probe and driver's removal.
- The role's start/stop will be called when specific
role has started.

Tested-by: Marek Vasut ma...@denx.de
Signed-off-by: Peter Chen peter.c...@freescale.com
---
 drivers/usb/chipidea/core.c |   10 --
 drivers/usb/chipidea/host.c |7 +++
 drivers/usb/chipidea/host.h |6 ++
 drivers/usb/chipidea/udc.c  |   36 +++-
 drivers/usb/chipidea/udc.h  |6 ++
 5 files changed, 54 insertions(+), 11 deletions(-)

diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index a4be8a5..bfc9aef 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -420,6 +420,12 @@ void ci_hdrc_remove_device(struct platform_device *pdev)
 }
 EXPORT_SYMBOL_GPL(ci_hdrc_remove_device);
 
+static inline void ci_role_destroy(struct ci_hdrc *ci)
+{
+   ci_hdrc_gadget_destroy(ci);
+   ci_hdrc_host_destroy(ci);
+}
+
 static int ci_hdrc_probe(struct platform_device *pdev)
 {
struct device   *dev = pdev-dev;
@@ -539,7 +545,7 @@ static int ci_hdrc_probe(struct platform_device *pdev)
 
free_irq(ci-irq, ci);
 stop:
-   ci_role_stop(ci);
+   ci_role_destroy(ci);
 rm_wq:
flush_workqueue(ci-wq);
destroy_workqueue(ci-wq);
@@ -555,7 +561,7 @@ static int ci_hdrc_remove(struct platform_device *pdev)
flush_workqueue(ci-wq);
destroy_workqueue(ci-wq);
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 e94e52b..382be5b 100644
--- a/drivers/usb/chipidea/host.c
+++ b/drivers/usb/chipidea/host.c
@@ -105,6 +105,13 @@ static void host_stop(struct ci_hdrc *ci)
regulator_disable(ci-platdata-reg_vbus);
 }
 
+
+void ci_hdrc_host_destroy(struct ci_hdrc *ci)
+{
+   if (ci-role == CI_ROLE_HOST)
+   host_stop(ci);
+}
+
 int ci_hdrc_host_init(struct ci_hdrc *ci)
 {
struct ci_role_driver *rdrv;
diff --git a/drivers/usb/chipidea/host.h b/drivers/usb/chipidea/host.h
index 058875c..5707bf3 100644
--- a/drivers/usb/chipidea/host.h
+++ b/drivers/usb/chipidea/host.h
@@ -4,6 +4,7 @@
 #ifdef CONFIG_USB_CHIPIDEA_HOST
 
 int ci_hdrc_host_init(struct ci_hdrc *ci);
+void ci_hdrc_host_destroy(struct ci_hdrc *ci);
 
 #else
 
@@ -12,6 +13,11 @@ static inline int ci_hdrc_host_init(struct ci_hdrc *ci)
return -ENXIO;
 }
 
+static inline void ci_hdrc_host_destroy(struct ci_hdrc *ci)
+{
+
+}
+
 #endif
 
 #endif /* __DRIVERS_USB_CHIPIDEA_HOST_H */
diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
index 116c762..24a100d 100644
--- a/drivers/usb/chipidea/udc.c
+++ b/drivers/usb/chipidea/udc.c
@@ -27,6 +27,7 @@
 #include udc.h
 #include bits.h
 #include debug.h
+#include otg.h
 
 /* control endpoint description */
 static const struct usb_endpoint_descriptor
@@ -1844,13 +1845,13 @@ free_qh_pool:
 }
 
 /**
- * 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 ci_hdrc *ci)
+void ci_hdrc_gadget_destroy(struct ci_hdrc *ci)
 {
-   if (ci == NULL)
+   if (!ci-roles[CI_ROLE_GADGET])
return;
 
usb_del_gadget_udc(ci-gadget);
@@ -1865,15 +1866,32 @@ static void udc_stop(struct ci_hdrc *ci)
if (ci-global_phy)
usb_put_phy(ci-transceiver);
}
-   /* my kobject is dynamic, I swear! */
-   memset(ci-gadget, 0, sizeof(ci-gadget));
+}
+
+static int udc_id_switch_for_device(struct ci_hdrc *ci)
+{
+   if (ci-is_otg) {
+   ci_clear_otg_interrupt(ci, OTGSC_BSVIS);
+   ci_enable_otg_interrupt(ci, OTGSC_BSVIE);
+   }
+
+   return 0;
+}
+
+static void udc_id_switch_for_host(struct ci_hdrc *ci)
+{
+   if (ci-is_otg) {
+   /* host doesn't care B_SESSION_VALID event */
+   ci_clear_otg_interrupt(ci, OTGSC_BSVIS);
+   ci_disable_otg_interrupt(ci, OTGSC_BSVIE);
+   }
 }
 
 /**
  * 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 the gadget, if the device is device capable.
  */
 int ci_hdrc_gadget_init(struct ci_hdrc *ci)
 {
@@ -1886,11 +1904,11 @@ int ci_hdrc_gadget_init(struct ci_hdrc *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

[PATCH v15 12/13] usb: chipidea: retire flag CI_HDRC_PULLUP_ON_VBUS

2013-08-11 Thread Peter Chen
Currently, the controller only runs when the ci-vbus_active is true.
So the flag CI_HDRC_PULLUP_ON_VBUS is useless no longer.
If the user doesn't have otgsc, he/she needs to change ci_handle_vbus_change
to update ci-vbus_active.

Signed-off-by: Peter Chen peter.c...@freescale.com
---
 drivers/usb/chipidea/ci_hdrc_imx.c |1 -
 drivers/usb/chipidea/ci_hdrc_msm.c |1 -
 drivers/usb/chipidea/udc.c |   24 ++--
 include/linux/usb/chipidea.h   |1 -
 4 files changed, 6 insertions(+), 21 deletions(-)

diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c 
b/drivers/usb/chipidea/ci_hdrc_imx.c
index bd1fe25..ab3e74a 100644
--- a/drivers/usb/chipidea/ci_hdrc_imx.c
+++ b/drivers/usb/chipidea/ci_hdrc_imx.c
@@ -91,7 +91,6 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
.name   = ci_hdrc_imx,
.capoffset  = DEF_CAPOFFSET,
.flags  = CI_HDRC_REQUIRE_TRANSCEIVER |
- CI_HDRC_PULLUP_ON_VBUS |
  CI_HDRC_DISABLE_STREAMING,
};
int ret;
diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c 
b/drivers/usb/chipidea/ci_hdrc_msm.c
index fb657ef..2d51d85 100644
--- a/drivers/usb/chipidea/ci_hdrc_msm.c
+++ b/drivers/usb/chipidea/ci_hdrc_msm.c
@@ -49,7 +49,6 @@ static struct ci_hdrc_platform_data ci_hdrc_msm_platdata = {
.name   = ci_hdrc_msm,
.flags  = CI_HDRC_REGS_SHARED |
  CI_HDRC_REQUIRE_TRANSCEIVER |
- CI_HDRC_PULLUP_ON_VBUS |
  CI_HDRC_DISABLE_STREAMING,
 
.notify_event   = ci_hdrc_msm_notify_event,
diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
index 45abf4d..90c3572 100644
--- a/drivers/usb/chipidea/udc.c
+++ b/drivers/usb/chipidea/udc.c
@@ -1448,9 +1448,6 @@ static int ci_udc_vbus_session(struct usb_gadget 
*_gadget, int is_active)
unsigned long flags;
int gadget_ready = 0;
 
-   if (!(ci-platdata-flags  CI_HDRC_PULLUP_ON_VBUS))
-   return -EOPNOTSUPP;
-
spin_lock_irqsave(ci-lock, flags);
ci-vbus_active = is_active;
if (ci-driver)
@@ -1635,13 +1632,11 @@ static int ci_udc_start(struct usb_gadget *gadget,
 
ci-driver = driver;
pm_runtime_get_sync(ci-gadget.dev);
-   if (ci-platdata-flags  CI_HDRC_PULLUP_ON_VBUS) {
-   if (ci-vbus_active) {
-   hw_device_reset(ci, USBMODE_CM_DC);
-   } else {
-   pm_runtime_put_sync(ci-gadget.dev);
-   goto done;
-   }
+   if (ci-vbus_active) {
+   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);
@@ -1664,8 +1659,7 @@ static int ci_udc_stop(struct usb_gadget *gadget,
 
spin_lock_irqsave(ci-lock, flags);
 
-   if (!(ci-platdata-flags  CI_HDRC_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,
@@ -1800,12 +1794,6 @@ static int udc_start(struct ci_hdrc *ci)
}
}
 
-   if (!(ci-platdata-flags  CI_HDRC_PULLUP_ON_VBUS)) {
-   retval = hw_device_reset(ci, USBMODE_CM_DC);
-   if (retval)
-   goto put_transceiver;
-   }
-
if (ci-transceiver) {
retval = otg_set_peripheral(ci-transceiver-otg,
ci-gadget);
diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h
index 10a607c..7d39967 100644
--- a/include/linux/usb/chipidea.h
+++ b/include/linux/usb/chipidea.h
@@ -18,7 +18,6 @@ struct ci_hdrc_platform_data {
unsigned longflags;
 #define CI_HDRC_REGS_SHAREDBIT(0)
 #define CI_HDRC_REQUIRE_TRANSCEIVERBIT(1)
-#define CI_HDRC_PULLUP_ON_VBUS BIT(2)
 #define CI_HDRC_DISABLE_STREAMING  BIT(3)
/*
 * Only set it when DCCPARAMS.DC==1 and DCCPARAMS.HC==1,
-- 
1.7.1


--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v15 06/13] usb: chipidea: add flag CI_HDRC_DUAL_ROLE_NOT_OTG

2013-08-11 Thread Peter Chen
Since we need otgsc to know vbus's status at some chipidea
controllers even it is peripheral-only mode. Besides, some
SoCs (eg, AR9331 SoC) don't have otgsc register even
the DCCPARAMS_DC and DCCPARAMS_HC are both 1 at CAP_DCCPARAMS.

We inroduce flag CI_HDRC_DUAL_ROLE_NOT_OTG to indicate if the
controller is dual role, but not supports OTG. If this flag is
not set, we follow the rule that if DCCPARAMS_DC and DCCPARAMS_HC
are both 1 at CAP_DCCPARAMS, then this controller is otg capable.

Signed-off-by: Peter Chen peter.c...@freescale.com
---
 drivers/usb/chipidea/core.c  |   37 ++---
 include/linux/usb/chipidea.h |5 +
 2 files changed, 35 insertions(+), 7 deletions(-)

diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index bfc9aef..56294e0 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -426,6 +426,18 @@ static inline void ci_role_destroy(struct ci_hdrc *ci)
ci_hdrc_host_destroy(ci);
 }
 
+static void ci_get_otg_capable(struct ci_hdrc *ci)
+{
+   if (ci-platdata-flags  CI_HDRC_DUAL_ROLE_NOT_OTG)
+   ci-is_otg = false;
+   else
+   ci-is_otg = (hw_read(ci, CAP_DCCPARAMS,
+   DCCPARAMS_DC | DCCPARAMS_HC)
+   == (DCCPARAMS_DC | DCCPARAMS_HC));
+   if (ci-is_otg)
+   dev_dbg(ci-dev, It is OTG capable controller\n);
+}
+
 static int ci_hdrc_probe(struct platform_device *pdev)
 {
struct device   *dev = pdev-dev;
@@ -482,6 +494,8 @@ static int ci_hdrc_probe(struct platform_device *pdev)
return -ENODEV;
}
 
+   ci_get_otg_capable(ci);
+
if (!ci-platdata-phy_mode)
ci-platdata-phy_mode = of_usb_get_phy_mode(dev-of_node);
 
@@ -514,10 +528,22 @@ static int ci_hdrc_probe(struct platform_device *pdev)
}
 
if (ci-roles[CI_ROLE_HOST]  ci-roles[CI_ROLE_GADGET]) {
-   ci-is_otg = true;
-   /* ID pin needs 1ms debouce time, we delay 2ms for safe */
-   mdelay(2);
-   ci-role = ci_otg_role(ci);
+   if (ci-is_otg) {
+   /*
+* ID pin needs 1ms debouce time,
+* we delay 2ms for safe.
+*/
+   mdelay(2);
+   ci-role = ci_otg_role(ci);
+   ci_hdrc_otg_init(ci);
+   } else {
+   /*
+* If the controller is not OTG capable, but support
+* role switch, the defalt role is gadget, and the
+* user can switch it through debugfs.
+*/
+   ci-role = CI_ROLE_GADGET;
+   }
} else {
ci-role = ci-roles[CI_ROLE_HOST]
? CI_ROLE_HOST
@@ -536,9 +562,6 @@ static int ci_hdrc_probe(struct platform_device *pdev)
if (ret)
goto stop;
 
-   if (ci-is_otg)
-   ci_hdrc_otg_init(ci);
-
ret = dbg_create_files(ci);
if (!ret)
return 0;
diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h
index ce4e1aa..10a607c 100644
--- a/include/linux/usb/chipidea.h
+++ b/include/linux/usb/chipidea.h
@@ -20,6 +20,11 @@ struct ci_hdrc_platform_data {
 #define CI_HDRC_REQUIRE_TRANSCEIVERBIT(1)
 #define CI_HDRC_PULLUP_ON_VBUS BIT(2)
 #define CI_HDRC_DISABLE_STREAMING  BIT(3)
+   /*
+* Only set it when DCCPARAMS.DC==1 and DCCPARAMS.HC==1,
+* but otg is not supported (no register otgsc).
+*/
+#define CI_HDRC_DUAL_ROLE_NOT_OTG  BIT(4)
enum usb_dr_modedr_mode;
 #define CI_HDRC_CONTROLLER_RESET_EVENT 0
 #define CI_HDRC_CONTROLLER_STOPPED_EVENT   1
-- 
1.7.1


--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v15 08/13] usb: chipidea: move otg related things to otg file

2013-08-11 Thread Peter Chen
Move otg related things to otg file.

Tested-by: Marek Vasut ma...@denx.de
Signed-off-by: Peter Chen peter.c...@freescale.com
---
 drivers/usb/chipidea/core.c |   63 +--
 drivers/usb/chipidea/otg.c  |   57 +-
 drivers/usb/chipidea/otg.h  |2 +
 3 files changed, 70 insertions(+), 52 deletions(-)

diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index 8ce0c45..e869269 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -294,40 +294,6 @@ int hw_device_reset(struct ci_hdrc *ci, u32 mode)
return 0;
 }
 
-/**
- * ci_otg_role - pick role based on ID pin state
- * @ci: the controller
- */
-static enum ci_role ci_otg_role(struct ci_hdrc *ci)
-{
-   u32 sts = hw_read(ci, OP_OTGSC, ~0);
-   enum ci_role role = sts  OTGSC_ID
-   ? CI_ROLE_GADGET
-   : CI_ROLE_HOST;
-
-   return role;
-}
-
-/**
- * ci_role_work - perform role changing based on ID pin
- * @work: work struct
- */
-static void ci_role_work(struct work_struct *work)
-{
-   struct ci_hdrc *ci = container_of(work, struct ci_hdrc, 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);
-}
-
 static irqreturn_t ci_irq(int irq, void *data)
 {
struct ci_hdrc *ci = data;
@@ -430,6 +396,8 @@ static inline void ci_role_destroy(struct ci_hdrc *ci)
 {
ci_hdrc_gadget_destroy(ci);
ci_hdrc_host_destroy(ci);
+   if (ci-is_otg)
+   ci_hdrc_otg_destroy(ci);
 }
 
 static void ci_get_otg_capable(struct ci_hdrc *ci)
@@ -496,13 +464,6 @@ static int ci_hdrc_probe(struct platform_device *pdev)
return -ENODEV;
}
 
-   INIT_WORK(ci-work, ci_role_work);
-   ci-wq = create_singlethread_workqueue(ci_otg);
-   if (!ci-wq) {
-   dev_err(dev, can't create workqueue\n);
-   return -ENODEV;
-   }
-
ci_get_otg_capable(ci);
 
if (!ci-platdata-phy_mode)
@@ -532,8 +493,15 @@ static int ci_hdrc_probe(struct platform_device *pdev)
 
if (!ci-roles[CI_ROLE_HOST]  !ci-roles[CI_ROLE_GADGET]) {
dev_err(dev, no supported roles\n);
-   ret = -ENODEV;
-   goto rm_wq;
+   return -ENODEV;
+   }
+
+   if (ci-is_otg) {
+   ret = ci_hdrc_otg_init(ci);
+   if (ret) {
+   dev_err(dev, init otg fails, ret = %d\n, ret);
+   goto stop;
+   }
}
 
if (ci-roles[CI_ROLE_HOST]  ci-roles[CI_ROLE_GADGET]) {
@@ -544,7 +512,7 @@ static int ci_hdrc_probe(struct platform_device *pdev)
 */
mdelay(2);
ci-role = ci_otg_role(ci);
-   ci_hdrc_otg_init(ci);
+   ci_enable_otg_interrupt(ci, OTGSC_IDIE);
} else {
/*
 * If the controller is not OTG capable, but support
@@ -562,7 +530,7 @@ static int ci_hdrc_probe(struct platform_device *pdev)
ret = ci_role_start(ci, ci-role);
if (ret) {
dev_err(dev, can't start %s role\n, ci_role(ci)-name);
-   goto rm_wq;
+   goto stop;
}
 
platform_set_drvdata(pdev, ci);
@@ -578,9 +546,6 @@ static int ci_hdrc_probe(struct platform_device *pdev)
free_irq(ci-irq, ci);
 stop:
ci_role_destroy(ci);
-rm_wq:
-   flush_workqueue(ci-wq);
-   destroy_workqueue(ci-wq);
 
return ret;
 }
@@ -590,8 +555,6 @@ static int ci_hdrc_remove(struct platform_device *pdev)
struct ci_hdrc *ci = platform_get_drvdata(pdev);
 
dbg_remove_files(ci);
-   flush_workqueue(ci-wq);
-   destroy_workqueue(ci-wq);
free_irq(ci-irq, ci);
ci_role_destroy(ci);
 
diff --git a/drivers/usb/chipidea/otg.c b/drivers/usb/chipidea/otg.c
index 999a085..3b66cbe 100644
--- a/drivers/usb/chipidea/otg.c
+++ b/drivers/usb/chipidea/otg.c
@@ -24,12 +24,65 @@
 #include otg.h
 
 /**
- * ci_hdrc_otg_init - initialize otgsc bits
+ * ci_otg_role - pick role based on ID pin state
+ * @ci: the controller
+ */
+enum ci_role ci_otg_role(struct ci_hdrc *ci)
+{
+   u32 sts = hw_read(ci, OP_OTGSC, ~0);
+   enum ci_role role = sts  OTGSC_ID
+   ? CI_ROLE_GADGET
+   : CI_ROLE_HOST;
+
+   return role;
+}
+
+/**
+ * ci_role_work - perform role changing based on ID pin
+ * @work: work struct
+ */
+static void ci_role_work(struct work_struct *work)
+{
+   struct ci_hdrc *ci = container_of(work, struct ci_hdrc, work);
+   enum ci_role role = ci_otg_role(ci);
+
+   if (role != ci-role

[PATCH v15 03/13] usb: chipidea: udc: otg_set_peripheral is useless for some chipidea users

2013-08-11 Thread Peter Chen
It is useless at below cases:
- If we implement both usb host and device at chipidea driver.
- If we don't need phy-otg.

Tested-by: Marek Vasut ma...@denx.de
Signed-off-by: Peter Chen peter.c...@freescale.com
---
 drivers/usb/chipidea/udc.c |7 ++-
 1 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
index e475fcd..116c762 100644
--- a/drivers/usb/chipidea/udc.c
+++ b/drivers/usb/chipidea/udc.c
@@ -1805,7 +1805,12 @@ static int udc_start(struct ci_hdrc *ci)
if (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 put_transceiver;
}
 
-- 
1.7.1


--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v15 09/13] usb: chipidea: add vbus interrupt handler

2013-08-11 Thread Peter Chen
We add vbus interrupt handler at ci_otg_work, it uses OTGSC_BSV(at otgsc)
to know it is connect or disconnet event.
Meanwhile, we introduce two flags id_event and b_sess_valid_event to
indicate it is an id interrupt or a vbus interrupt.

Tested-by: Marek Vasut ma...@denx.de
Signed-off-by: Peter Chen peter.c...@freescale.com
---
 drivers/usb/chipidea/ci.h   |5 +
 drivers/usb/chipidea/core.c |   28 +++-
 drivers/usb/chipidea/otg.c  |   42 +++---
 drivers/usb/chipidea/otg.h  |1 +
 drivers/usb/chipidea/udc.c  |7 +++
 5 files changed, 71 insertions(+), 12 deletions(-)

diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h
index 33cb29f..3160363 100644
--- a/drivers/usb/chipidea/ci.h
+++ b/drivers/usb/chipidea/ci.h
@@ -132,6 +132,9 @@ struct hw_bank {
  * @transceiver: pointer to USB PHY, if any
  * @hcd: pointer to usb_hcd for ehci host driver
  * @debugfs: root dentry for this controller in debugfs
+ * @id_event: indicates there is an id event, and handled at ci_otg_work
+ * @b_sess_valid_event: indicates there is a vbus event, and handled
+ * at ci_otg_work
  */
 struct ci_hdrc {
struct device   *dev;
@@ -168,6 +171,8 @@ struct ci_hdrc {
struct usb_phy  *transceiver;
struct usb_hcd  *hcd;
struct dentry   *debugfs;
+   boolid_event;
+   boolb_sess_valid_event;
 };
 
 static inline struct ci_role_driver *ci_role(struct ci_hdrc *ci)
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index e869269..ec0bb11 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -303,16 +303,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 (ci-is_otg  (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;
 }
 
diff --git a/drivers/usb/chipidea/otg.c b/drivers/usb/chipidea/otg.c
index 3b66cbe..7f37484 100644
--- a/drivers/usb/chipidea/otg.c
+++ b/drivers/usb/chipidea/otg.c
@@ -37,13 +37,23 @@ enum ci_role ci_otg_role(struct ci_hdrc *ci)
return role;
 }
 
-/**
- * ci_role_work - perform role changing based on ID pin
- * @work: work struct
- */
-static void ci_role_work(struct work_struct *work)
+void ci_handle_vbus_change(struct ci_hdrc *ci)
+{
+   u32 otgsc;
+
+   if (!ci-is_otg)
+   return;
+
+   otgsc = hw_read(ci, OP_OTGSC, ~0);
+
+   if (otgsc  OTGSC_BSV)
+   usb_gadget_vbus_connect(ci-gadget);
+   else
+   usb_gadget_vbus_disconnect(ci-gadget);
+}
+
+static void ci_handle_id_switch(struct ci_hdrc *ci)
 {
-   struct ci_hdrc *ci = container_of(work, struct ci_hdrc, work);
enum ci_role role = ci_otg_role(ci);
 
if (role != ci-role) {
@@ -53,17 +63,35 @@ static void ci_role_work(struct work_struct *work)
ci_role_stop(ci);
ci_role_start(ci, role);
}
+}
+/**
+ * ci_otg_work - perform otg (vbus/id) event handle
+ * @work: work struct
+ */
+static void ci_otg_work(struct work_struct *work)
+{
+   struct ci_hdrc *ci = container_of(work, struct ci_hdrc, 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);
 }
 
+
 /**
  * ci_hdrc_otg_init - initialize otg struct
  * ci: the controller
  */
 int ci_hdrc_otg_init(struct ci_hdrc *ci)
 {
-   INIT_WORK(ci-work, ci_role_work);
+   INIT_WORK(ci-work

[PATCH v15 07/13] usb: chipidea: disable all interrupts and clear all interrupts status

2013-08-11 Thread Peter Chen
During the initialization, it needs to disable all interrupts
enable bit as well as clear all interrupts status bits to avoid
exceptional interrupt.

Tested-by: Marek Vasut ma...@denx.de
Signed-off-by: Peter Chen peter.c...@freescale.com
---
 drivers/usb/chipidea/core.c |   11 ++-
 1 files changed, 10 insertions(+), 1 deletions(-)

diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index 56294e0..8ce0c45 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -199,6 +199,12 @@ static int hw_device_init(struct ci_hdrc *ci, void __iomem 
*base)
if (ci-hw_ep_max  ENDPT_MAX)
return -ENODEV;
 
+   /* Disable all interrupts bits */
+   hw_write(ci, OP_USBINTR, 0x, 0);
+
+   /* Clear all interrupts status bits*/
+   hw_write(ci, OP_USBSTS, 0x, 0x);
+
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);
 
@@ -434,8 +440,11 @@ static void ci_get_otg_capable(struct ci_hdrc *ci)
ci-is_otg = (hw_read(ci, CAP_DCCPARAMS,
DCCPARAMS_DC | DCCPARAMS_HC)
== (DCCPARAMS_DC | DCCPARAMS_HC));
-   if (ci-is_otg)
+   if (ci-is_otg) {
dev_dbg(ci-dev, It is OTG capable controller\n);
+   ci_disable_otg_interrupt(ci, OTGSC_INT_EN_BITS);
+   ci_clear_otg_interrupt(ci, OTGSC_INT_STATUS_BITS);
+   }
 }
 
 static int ci_hdrc_probe(struct platform_device *pdev)
-- 
1.7.1


--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/2] USB: chipidea: i.MX: remove unused define

2013-08-12 Thread Peter Chen
On Mon, Aug 12, 2013 at 12:29:41PM +0200, Sascha Hauer wrote:
 Signed-off-by: Sascha Hauer s.ha...@pengutronix.de
 ---
  drivers/usb/chipidea/ci_hdrc_imx.c | 3 ---
  1 file changed, 3 deletions(-)
 
 diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c 
 b/drivers/usb/chipidea/ci_hdrc_imx.c
 index 14362c0..11ed423 100644
 --- a/drivers/usb/chipidea/ci_hdrc_imx.c
 +++ b/drivers/usb/chipidea/ci_hdrc_imx.c
 @@ -24,9 +24,6 @@
  #include ci.h
  #include ci_hdrc_imx.h
  
 -#define pdev_to_phy(pdev) \
 - ((struct usb_phy *)platform_get_drvdata(pdev))
 -

This one has already submitted by me, and queued by alex.

-- 

Best Regards,
Peter Chen

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/2] USB: chipidea: i.MX: simplify usbmisc

2013-08-12 Thread Peter Chen
 + MX53_USB_OTG_PHY_CTRL_0_OFFSET;
   val = readl(reg) | MX53_BM_OVER_CUR_DIS_OTG;
 @@ -126,22 +105,19 @@ static int usbmisc_imx53_init(struct device *dev)
   return 0;
  }
  
 -static int usbmisc_imx6q_init(struct device *dev)
 +static int usbmisc_imx6q_init(struct imx_usbmisc_data *data)
  {
 -
 - struct usbmisc_usb_device *usbdev;
   unsigned long flags;
   u32 reg;
  
 - usbdev = get_usbdev(dev);
 - if (IS_ERR(usbdev))
 - return PTR_ERR(usbdev);
 + if (data-index  3)
 + return -EINVAL;
  
 - if (usbdev-disable_oc) {
 + if (data-disable_oc) {
   spin_lock_irqsave(usbmisc-lock, flags);
 - reg = readl(usbmisc-base + usbdev-index * 4);
 + reg = readl(usbmisc-base + data-index * 4);
   writel(reg | MX6_BM_OVER_CUR_DIS,
 - usbmisc-base + usbdev-index * 4);
 + usbmisc-base + data-index * 4);
   spin_unlock_irqrestore(usbmisc-lock, flags);
   }
  
 @@ -160,6 +136,26 @@ static const struct usbmisc_ops imx6q_usbmisc_ops = {
   .init = usbmisc_imx6q_init,
  };
  
 +int imx_usbmisc_init(struct imx_usbmisc_data *data)
 +{
 + if (!usbmisc)
 + return -EPROBE_DEFER;
 + if (!usbmisc-ops-init)
 + return 0;
 + return usbmisc-ops-init(data);
 +}
 +EXPORT_SYMBOL_GPL(imx_usbmisc_init);
 +
 +int imx_usbmisc_init_post(struct imx_usbmisc_data *data)
 +{
 + if (!usbmisc)
 + return -EPROBE_DEFER;
 + if (!usbmisc-ops-post)
 + return 0;
 + return usbmisc-ops-post(data);
 +}
 +EXPORT_SYMBOL_GPL(imx_usbmisc_init_post);
 +
  static const struct of_device_id usbmisc_imx_dt_ids[] = {
   {
   .compatible = fsl,imx25-usbmisc,
 @@ -216,19 +212,12 @@ static int usbmisc_imx_probe(struct platform_device 
 *pdev)
   of_match_device(usbmisc_imx_dt_ids, pdev-dev);
   data-ops = (const struct usbmisc_ops *)tmp_dev-data;
   usbmisc = data;
 - ret = usbmisc_set_ops(data-ops);
 - if (ret) {
 - usbmisc = NULL;
 - clk_disable_unprepare(data-clk);
 - return ret;
 - }
  
   return 0;
  }
  
  static int usbmisc_imx_remove(struct platform_device *pdev)
  {
 - usbmisc_unset_ops(usbmisc-ops);
   clk_disable_unprepare(usbmisc-clk);
   usbmisc = NULL;
   return 0;
 -- 
 1.8.4.rc1
 

Acked-by: Peter Chen peter.c...@freescale.com

-- 

Best Regards,
Peter Chen

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] dwc3: dwc3-pci: Use SIMPLE_DEV_PM_OPS

2013-08-13 Thread Peter Chen
On Wed, Aug 7, 2013 at 7:51 PM, Fabio Estevam feste...@gmail.com wrote:
 From: Fabio Estevam fabio.este...@freescale.com

 Using SIMPLE_DEV_PM_OPS can make the code simpler and cleaner.

 Signed-off-by: Fabio Estevam fabio.este...@freescale.com
 ---
  drivers/usb/dwc3/dwc3-pci.c | 15 +--
  1 file changed, 5 insertions(+), 10 deletions(-)

 diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c
 index 5d746e5..b922315 100644
 --- a/drivers/usb/dwc3/dwc3-pci.c
 +++ b/drivers/usb/dwc3/dwc3-pci.c
 @@ -191,7 +191,7 @@ static DEFINE_PCI_DEVICE_TABLE(dwc3_pci_id_table) = {
  };
  MODULE_DEVICE_TABLE(pci, dwc3_pci_id_table);

 -#ifdef CONFIG_PM
 +#ifdef CONFIG_PM_SLEEP
  static int dwc3_pci_suspend(struct device *dev)
  {
 struct pci_dev  *pci = to_pci_dev(dev);
 @@ -216,15 +216,10 @@ static int dwc3_pci_resume(struct device *dev)

 return 0;
  }
 +#endif /* CONFIG_PM_SLEEP */

 -static const struct dev_pm_ops dwc3_pci_dev_pm_ops = {
 -   SET_SYSTEM_SLEEP_PM_OPS(dwc3_pci_suspend, dwc3_pci_resume)
 -};
 -
 -#define DEV_PM_OPS (dwc3_pci_dev_pm_ops)
 -#else
 -#define DEV_PM_OPS NULL
 -#endif /* CONFIG_PM */
 +static SIMPLE_DEV_PM_OPS(dwc3_pci_dev_pm_ops, dwc3_pci_suspend,
 +dwc3_pci_resume);

  static struct pci_driver dwc3_pci_driver = {
 .name   = dwc3-pci,
 @@ -232,7 +227,7 @@ static struct pci_driver dwc3_pci_driver = {
 .probe  = dwc3_pci_probe,
 .remove = dwc3_pci_remove,
 .driver = {
 -   .pm = DEV_PM_OPS,
 +   .pm = dwc3_pci_dev_pm_ops,
 },
  };

It seems .pm is not NULL if CONFIG_PM_SLEEP is not defined
which is not the same with former code.

-- 
BR,
Peter Chen
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] dwc3: dwc3-pci: Use SIMPLE_DEV_PM_OPS

2013-08-13 Thread Peter Chen
On Tue, Aug 13, 2013 at 8:59 PM, Fabio Estevam feste...@gmail.com wrote:
 On Tue, Aug 13, 2013 at 3:59 AM, Peter Chen hzpeterc...@gmail.com wrote:

 It seems .pm is not NULL if CONFIG_PM_SLEEP is not defined
 which is not the same with former code.

 With SIMPLE_DEV_PM_OPS macro we don't need to define the NULL function 
 variants.

 Take a look at include/linux/pm.h to get a clear picture.

But what I see is the dwc3_pci_dev_pm_ops is not NULL if CONFIG_PM_SLEEP
is not defined.

static foo(void)
{}
static goo(void)
{}
struct dev_pm_ops {
int a;
int b;
};
#define SET_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn)
#define SIMPLE_DEV_PM_OPS(name, suspend_fn, resume_fn) \
const struct dev_pm_ops name = { \
SET_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \
}

SIMPLE_DEV_PM_OPS(test_name, foo, goo);
void main(void)
{
printf(the pointer of name is %p\n, test_name);
return;
}

-- 
BR,
Peter Chen
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


  1   2   3   4   5   6   7   8   9   10   >