Re: [PATCH 5/7] usb: gadget: fsl_udc: postpone freeing current dTD

2012-10-20 Thread Christoph Fritz
On Fri, 2012-10-19 at 13:44 +0300, Felipe Balbi wrote:
  I thought about this too but wasn't able to use chipidea with
  MXC_EHCI_INTERNAL_PHY as it's called in fsl_udc.
 
 that's a matter of writing the PHY driver, right ;-) It has nothing to
 do with chipidea, actually :-)

Okay, I'll do. But then we should purge the old buggy fsl_udc.

 Thanks
   -- Christoph




___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 0/7] update USB gadget driver fsl-usb2-udc

2012-10-19 Thread Christoph Fritz
This series updates USB gadget driver fsl-usb2-udc.

Christoph Fritz (7):
  usb: gadget: fsl_udc: simplify driver init
  usb: gadget: fsl_udc: protect fsl_pullup() with spin_lock
  usb: gadget: fsl_udc: convert to new ulc style
  usb: gadget: fsl_udc: drop ARCH dependency
  usb: gadget: fsl_udc: postpone freeing current dTD
  usb: gadget: fsl_udc: purge global pointer usb_sys_regs
  usb: gadget: fsl_udc: purge global pointer dr_regs

 drivers/usb/gadget/fsl_udc_core.c |  755 -
 drivers/usb/gadget/fsl_usb2_udc.h |4 +
 2 files changed, 322 insertions(+), 437 deletions(-)

-- 
1.7.2.5

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 1/7] usb: gadget: fsl_udc: simplify driver init

2012-10-19 Thread Christoph Fritz
To initialize this driver use 'module_platform_driver' instead
of '__init' and '__exit'.

Signed-off-by: Christoph Fritz chf.fr...@googlemail.com
---
 drivers/usb/gadget/fsl_udc_core.c |   37 +++--
 1 files changed, 11 insertions(+), 26 deletions(-)

diff --git a/drivers/usb/gadget/fsl_udc_core.c 
b/drivers/usb/gadget/fsl_udc_core.c
index 6ae70cb..340451d 100644
--- a/drivers/usb/gadget/fsl_udc_core.c
+++ b/drivers/usb/gadget/fsl_udc_core.c
@@ -49,13 +49,14 @@
 
 #include fsl_usb2_udc.h
 
+#defineDRIVER_NAME fsl-usb2-udc
 #defineDRIVER_DESC Freescale High-Speed USB SOC Device Controller 
driver
 #defineDRIVER_AUTHOR   Li Yang/Jiang Bo
 #defineDRIVER_VERSION  Apr 20, 2007
 
 #defineDMA_ADDR_INVALID(~(dma_addr_t)0)
 
-static const char driver_name[] = fsl-usb2-udc;
+static const char driver_name[] = DRIVER_NAME;
 static const char driver_desc[] = DRIVER_DESC;
 
 static struct usb_dr_device *dr_regs;
@@ -2761,35 +2762,19 @@ static int fsl_udc_otg_resume(struct device *dev)
Register entry point for the peripheral controller driver
 --*/
 
-static struct platform_driver udc_driver = {
-   .remove  = __exit_p(fsl_udc_remove),
-   /* these suspend and resume are not usb suspend and resume */
-   .suspend = fsl_udc_suspend,
-   .resume  = fsl_udc_resume,
-   .driver  = {
-   .name = (char *)driver_name,
-   .owner = THIS_MODULE,
-   /* udc suspend/resume called from OTG driver */
+static struct platform_driver fsl_udc_driver = {
+   .probe  = fsl_udc_probe,
+   .remove = __devexit_p(fsl_udc_remove),
+   .suspend= fsl_udc_suspend,
+   .resume = fsl_udc_resume,
+   .driver = {
+   .name   = DRIVER_NAME,
+   .owner  = THIS_MODULE,
.suspend = fsl_udc_otg_suspend,
.resume  = fsl_udc_otg_resume,
},
 };
-
-static int __init udc_init(void)
-{
-   printk(KERN_INFO %s (%s)\n, driver_desc, DRIVER_VERSION);
-   return platform_driver_probe(udc_driver, fsl_udc_probe);
-}
-
-module_init(udc_init);
-
-static void __exit udc_exit(void)
-{
-   platform_driver_unregister(udc_driver);
-   printk(KERN_WARNING %s unregistered\n, driver_desc);
-}
-
-module_exit(udc_exit);
+module_platform_driver(fsl_udc_driver);
 
 MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_AUTHOR(DRIVER_AUTHOR);
-- 
1.7.2.5

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 2/7] usb: gadget: fsl_udc: protect fsl_pullup() with spin_lock

2012-10-19 Thread Christoph Fritz
This patch reworks fsl_pullup() against the background of switching over
to udc_start()/udc_stop() style:

Protect function fsl_pullup() with a spin_lock. Also set vbus_active as
default to true. This prevents disabling USB controller if there is no
driver support for an external transceiver (or GPIO) that detects a VBUS
power session starting.

Signed-off-by: Christoph Fritz chf.fr...@googlemail.com
---
 drivers/usb/gadget/fsl_udc_core.c |4 
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/drivers/usb/gadget/fsl_udc_core.c 
b/drivers/usb/gadget/fsl_udc_core.c
index 340451d..0a0d6a6 100644
--- a/drivers/usb/gadget/fsl_udc_core.c
+++ b/drivers/usb/gadget/fsl_udc_core.c
@@ -1242,8 +1242,10 @@ static int fsl_vbus_draw(struct usb_gadget *gadget, 
unsigned mA)
 static int fsl_pullup(struct usb_gadget *gadget, int is_on)
 {
struct fsl_udc *udc;
+   unsigned long flags;
 
udc = container_of(gadget, struct fsl_udc, gadget);
+   spin_lock_irqsave(udc-lock, flags);
udc-softconnect = (is_on != 0);
if (can_pullup(udc))
fsl_writel((fsl_readl(dr_regs-usbcmd) | USB_CMD_RUN_STOP),
@@ -1251,6 +1253,7 @@ static int fsl_pullup(struct usb_gadget *gadget, int 
is_on)
else
fsl_writel((fsl_readl(dr_regs-usbcmd)  ~USB_CMD_RUN_STOP),
dr_regs-usbcmd);
+   spin_unlock_irqrestore(udc-lock, flags);
 
return 0;
 }
@@ -2557,6 +2560,7 @@ static int __init fsl_udc_probe(struct platform_device 
*pdev)
INIT_LIST_HEAD(udc_controller-gadget.ep_list);
udc_controller-gadget.speed = USB_SPEED_UNKNOWN;
udc_controller-gadget.name = driver_name;
+   udc-vbus_active = true;
 
/* Setup gadget.dev and register with kernel */
dev_set_name(udc_controller-gadget.dev, gadget);
-- 
1.7.2.5

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 3/7] usb: gadget: fsl_udc: convert to new ulc style

2012-10-19 Thread Christoph Fritz
Convert to new UDC style registration and remove
global 'udc_controller' pointer.

Signed-off-by: Christoph Fritz chf.fr...@googlemail.com
---
 drivers/usb/gadget/fsl_udc_core.c |  289 +
 1 files changed, 131 insertions(+), 158 deletions(-)

diff --git a/drivers/usb/gadget/fsl_udc_core.c 
b/drivers/usb/gadget/fsl_udc_core.c
index 0a0d6a6..d113f39 100644
--- a/drivers/usb/gadget/fsl_udc_core.c
+++ b/drivers/usb/gadget/fsl_udc_core.c
@@ -63,9 +63,6 @@ static struct usb_dr_device *dr_regs;
 
 static struct usb_sys_interface *usb_sys_regs;
 
-/* it is initialized in probe()  */
-static struct fsl_udc *udc_controller = NULL;
-
 static const struct usb_endpoint_descriptor
 fsl_ep0_desc = {
.bLength =  USB_DT_ENDPOINT_SIZE,
@@ -783,12 +780,14 @@ static void fsl_queue_td(struct fsl_ep *ep, struct 
fsl_req *req)
 }
 
 /* Fill in the dTD structure
+ * @udc: driver private data
  * @req: request that the transfer belongs to
  * @length: return actually data length of the dTD
  * @dma: return dma address of the dTD
  * @is_last: return flag if it is the last dTD of the request
  * return: pointer to the built dTD */
-static struct ep_td_struct *fsl_build_dtd(struct fsl_req *req, unsigned 
*length,
+static struct ep_td_struct *fsl_build_dtd(struct fsl_udc *udc,
+   struct fsl_req *req, unsigned *length,
dma_addr_t *dma, int *is_last, gfp_t gfp_flags)
 {
u32 swap_temp;
@@ -798,7 +797,7 @@ static struct ep_td_struct *fsl_build_dtd(struct fsl_req 
*req, unsigned *length,
*length = min(req-req.length - req-req.actual,
(unsigned)EP_MAX_LENGTH_TRANSFER);
 
-   dtd = dma_pool_alloc(udc_controller-td_pool, gfp_flags, dma);
+   dtd = dma_pool_alloc(udc-td_pool, gfp_flags, dma);
if (dtd == NULL)
return dtd;
 
@@ -848,7 +847,8 @@ static struct ep_td_struct *fsl_build_dtd(struct fsl_req 
*req, unsigned *length,
 }
 
 /* Generate dtd chain for a request */
-static int fsl_req_to_dtd(struct fsl_req *req, gfp_t gfp_flags)
+static int fsl_req_to_dtd(struct fsl_udc *udc, struct fsl_req *req,
+   gfp_t gfp_flags)
 {
unsignedcount;
int is_last;
@@ -857,7 +857,8 @@ static int fsl_req_to_dtd(struct fsl_req *req, gfp_t 
gfp_flags)
dma_addr_t dma;
 
do {
-   dtd = fsl_build_dtd(req, count, dma, is_last, gfp_flags);
+   dtd = fsl_build_dtd(udc, req, count, dma, is_last,
+   gfp_flags);
if (dtd == NULL)
return -ENOMEM;
 
@@ -932,7 +933,7 @@ fsl_ep_queue(struct usb_ep *_ep, struct usb_request *_req, 
gfp_t gfp_flags)
req-dtd_count = 0;
 
/* build dtds and push them to device queue */
-   if (!fsl_req_to_dtd(req, gfp_flags)) {
+   if (!fsl_req_to_dtd(udc, req, gfp_flags)) {
spin_lock_irqsave(udc-lock, flags);
fsl_queue_td(ep, req);
} else {
@@ -1258,9 +1259,10 @@ static int fsl_pullup(struct usb_gadget *gadget, int 
is_on)
return 0;
 }
 
-static int fsl_start(struct usb_gadget_driver *driver,
-   int (*bind)(struct usb_gadget *, struct usb_gadget_driver *));
-static int fsl_stop(struct usb_gadget_driver *driver);
+static int fsl_udc_start(struct usb_gadget *gadget,
+   struct usb_gadget_driver *driver);
+static int fsl_udc_stop(struct usb_gadget *gadget,
+   struct usb_gadget_driver *driver);
 /* defined in gadget.h */
 static struct usb_gadget_ops fsl_gadget_ops = {
.get_frame = fsl_get_frame,
@@ -1269,8 +1271,8 @@ static struct usb_gadget_ops fsl_gadget_ops = {
.vbus_session = fsl_vbus_session,
.vbus_draw = fsl_vbus_draw,
.pullup = fsl_pullup,
-   .start = fsl_start,
-   .stop = fsl_stop,
+   .udc_start = fsl_udc_start,
+   .udc_stop = fsl_udc_stop,
 };
 
 /* Set protocol stall on ep0, protocol stall will automatically be cleared
@@ -1314,7 +1316,7 @@ static int ep0_prime_status(struct fsl_udc *udc, int 
direction)
ep_is_in(ep) ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
req-mapped = 1;
 
-   if (fsl_req_to_dtd(req, GFP_ATOMIC) == 0)
+   if (fsl_req_to_dtd(udc, req, GFP_ATOMIC) == 0)
fsl_queue_td(ep, req);
else
return -ENOMEM;
@@ -1398,7 +1400,7 @@ static void ch9getstatus(struct fsl_udc *udc, u8 
request_type, u16 value,
req-mapped = 1;
 
/* prime the data phase */
-   if ((fsl_req_to_dtd(req, GFP_ATOMIC) == 0))
+   if ((fsl_req_to_dtd(udc, req, GFP_ATOMIC) == 0))
fsl_queue_td(ep, req);
else/* no mem */
goto stall;
@@ -1422,7 +1424,7 @@ static void setup_received_irq(struct fsl_udc *udc,
 
udc_reset_ep_queue(udc, 0);
 
-   /* We process some stardard setup requests here */
+   /* We process some standard setup

[PATCH 4/7] usb: gadget: fsl_udc: drop ARCH dependency

2012-10-19 Thread Christoph Fritz
Drop the big-/little-endian helpers and make use of generic
writel()/readl() routines.

Signed-off-by: Christoph Fritz chf.fr...@googlemail.com
---
 drivers/usb/gadget/fsl_udc_core.c |  331 +
 1 files changed, 118 insertions(+), 213 deletions(-)

diff --git a/drivers/usb/gadget/fsl_udc_core.c 
b/drivers/usb/gadget/fsl_udc_core.c
index d113f39..53df9c0 100644
--- a/drivers/usb/gadget/fsl_udc_core.c
+++ b/drivers/usb/gadget/fsl_udc_core.c
@@ -20,32 +20,14 @@
 #undef VERBOSE
 
 #include linux/module.h
-#include linux/kernel.h
-#include linux/ioport.h
-#include linux/types.h
-#include linux/errno.h
-#include linux/err.h
-#include linux/slab.h
-#include linux/init.h
-#include linux/list.h
 #include linux/interrupt.h
 #include linux/proc_fs.h
-#include linux/mm.h
-#include linux/moduleparam.h
-#include linux/device.h
-#include linux/usb/ch9.h
 #include linux/usb/gadget.h
 #include linux/usb/otg.h
 #include linux/dma-mapping.h
 #include linux/platform_device.h
 #include linux/fsl_devices.h
 #include linux/dmapool.h
-#include linux/delay.h
-
-#include asm/byteorder.h
-#include asm/io.h
-#include asm/unaligned.h
-#include asm/dma.h
 
 #include fsl_usb2_udc.h
 
@@ -74,78 +56,6 @@ fsl_ep0_desc = {
 
 static void fsl_ep_fifo_flush(struct usb_ep *_ep);
 
-#ifdef CONFIG_PPC32
-/*
- * On some SoCs, the USB controller registers can be big or little endian,
- * depending on the version of the chip. In order to be able to run the
- * same kernel binary on 2 different versions of an SoC, the BE/LE decision
- * must be made at run time. _fsl_readl and fsl_writel are pointers to the
- * BE or LE readl() and writel() functions, and fsl_readl() and fsl_writel()
- * call through those pointers. Platform code for SoCs that have BE USB
- * registers should set pdata-big_endian_mmio flag.
- *
- * This also applies to controller-to-cpu accessors for the USB descriptors,
- * since their endianness is also SoC dependant. Platform code for SoCs that
- * have BE USB descriptors should set pdata-big_endian_desc flag.
- */
-static u32 _fsl_readl_be(const unsigned __iomem *p)
-{
-   return in_be32(p);
-}
-
-static u32 _fsl_readl_le(const unsigned __iomem *p)
-{
-   return in_le32(p);
-}
-
-static void _fsl_writel_be(u32 v, unsigned __iomem *p)
-{
-   out_be32(p, v);
-}
-
-static void _fsl_writel_le(u32 v, unsigned __iomem *p)
-{
-   out_le32(p, v);
-}
-
-static u32 (*_fsl_readl)(const unsigned __iomem *p);
-static void (*_fsl_writel)(u32 v, unsigned __iomem *p);
-
-#define fsl_readl(p)   (*_fsl_readl)((p))
-#define fsl_writel(v, p)   (*_fsl_writel)((v), (p))
-
-static inline void fsl_set_accessors(struct fsl_usb2_platform_data *pdata)
-{
-   if (pdata-big_endian_mmio) {
-   _fsl_readl = _fsl_readl_be;
-   _fsl_writel = _fsl_writel_be;
-   } else {
-   _fsl_readl = _fsl_readl_le;
-   _fsl_writel = _fsl_writel_le;
-   }
-}
-
-static inline u32 cpu_to_hc32(const u32 x)
-{
-   return udc_controller-pdata-big_endian_desc
-   ? (__force u32)cpu_to_be32(x)
-   : (__force u32)cpu_to_le32(x);
-}
-
-static inline u32 hc32_to_cpu(const u32 x)
-{
-   return udc_controller-pdata-big_endian_desc
-   ? be32_to_cpu((__force __be32)x)
-   : le32_to_cpu((__force __le32)x);
-}
-#else /* !CONFIG_PPC32 */
-static inline void fsl_set_accessors(struct fsl_usb2_platform_data *pdata) {}
-
-#define fsl_readl(addr)readl(addr)
-#define fsl_writel(val32, addr) writel(val32, addr)
-#define cpu_to_hc32(x) cpu_to_le32(x)
-#define hc32_to_cpu(x) le32_to_cpu(x)
-#endif /* CONFIG_PPC32 */
 
 /
  * Internal Used Function
@@ -248,7 +158,7 @@ static int dr_controller_setup(struct fsl_udc *udc)
 #define FSL_UDC_RESET_TIMEOUT 1000
 
/* Config PHY interface */
-   portctrl = fsl_readl(dr_regs-portsc1);
+   portctrl = readl(dr_regs-portsc1);
portctrl = ~(PORTSCX_PHY_TYPE_SEL | PORTSCX_PORT_WIDTH);
switch (udc-phy_mode) {
case FSL_USB2_PHY_ULPI:
@@ -286,20 +196,20 @@ static int dr_controller_setup(struct fsl_udc *udc)
default:
return -EINVAL;
}
-   fsl_writel(portctrl, dr_regs-portsc1);
+   writel(portctrl, dr_regs-portsc1);
 
/* Stop and reset the usb controller */
-   tmp = fsl_readl(dr_regs-usbcmd);
+   tmp = readl(dr_regs-usbcmd);
tmp = ~USB_CMD_RUN_STOP;
-   fsl_writel(tmp, dr_regs-usbcmd);
+   writel(tmp, dr_regs-usbcmd);
 
-   tmp = fsl_readl(dr_regs-usbcmd);
+   tmp = readl(dr_regs-usbcmd);
tmp |= USB_CMD_CTRL_RESET;
-   fsl_writel(tmp, dr_regs-usbcmd);
+   writel(tmp, dr_regs-usbcmd);
 
/* Wait for reset to complete */
timeout = jiffies + FSL_UDC_RESET_TIMEOUT;
-   while (fsl_readl(dr_regs-usbcmd)  USB_CMD_CTRL_RESET) {
+   while (readl

[PATCH 5/7] usb: gadget: fsl_udc: postpone freeing current dTD

2012-10-19 Thread Christoph Fritz
USB controller may access a wrong address for the dTD (endpoint transfer
descriptor) and then hang. This happens a lot when doing tests with
g_ether module and iperf, a tool for measuring maximum TCP and UDP
bandwidth.

This hardware bug is explained in detail by errata number 2858 for i.MX23:
http://cache.freescale.com/files/dsp/doc/errata/IMX23CE.pdf

All (?) SOCs with an IP from chipidea suffer from this problem.
mv_udc_core fixes this bug by commit daec765.  There still may be
unfixed drivers.

Signed-off-by: Christoph Fritz chf.fr...@googlemail.com
Signed-off-by: Christian Hemp c.h...@phytec.de
Reviewed-by: Peter Chen peter.c...@freescale.com
---
 drivers/usb/gadget/fsl_udc_core.c |   12 +++-
 drivers/usb/gadget/fsl_usb2_udc.h |2 ++
 2 files changed, 13 insertions(+), 1 deletions(-)

diff --git a/drivers/usb/gadget/fsl_udc_core.c 
b/drivers/usb/gadget/fsl_udc_core.c
index 53df9c0..deaab62 100644
--- a/drivers/usb/gadget/fsl_udc_core.c
+++ b/drivers/usb/gadget/fsl_udc_core.c
@@ -88,8 +88,13 @@ static void done(struct fsl_ep *ep, struct fsl_req *req, int 
status)
curr_td = next_td;
if (j != req-dtd_count - 1) {
next_td = curr_td-next_td_virt;
+   dma_pool_free(udc-td_pool, curr_td, curr_td-td_dma);
+   } else {
+   if (udc-last_free_td != NULL)
+   dma_pool_free(udc-td_pool, udc-last_free_td,
+   udc-last_free_td-td_dma);
+   udc-last_free_td = curr_td;
}
-   dma_pool_free(udc-td_pool, curr_td, curr_td-td_dma);
}
 
if (req-mapped) {
@@ -2439,6 +2444,7 @@ static int __init fsl_udc_probe(struct platform_device 
*pdev)
udc-gadget.speed = USB_SPEED_UNKNOWN;
udc-gadget.name = driver_name;
udc-vbus_active = true;
+   udc-last_free_td = NULL;
 
/* Setup gadget.dev and register with kernel */
dev_set_name(udc-gadget.dev, gadget);
@@ -2533,6 +2539,10 @@ static int __exit fsl_udc_remove(struct platform_device 
*pdev)
kfree(udc-status_req);
kfree(udc-eps);
 
+   if (udc-last_free_td != NULL)
+   dma_pool_free(udc-td_pool, udc-last_free_td,
+   udc-last_free_td-td_dma);
+
dma_pool_destroy(udc-td_pool);
free_irq(udc-irq, udc);
iounmap(dr_regs);
diff --git a/drivers/usb/gadget/fsl_usb2_udc.h 
b/drivers/usb/gadget/fsl_usb2_udc.h
index f61a967..a0123ae 100644
--- a/drivers/usb/gadget/fsl_usb2_udc.h
+++ b/drivers/usb/gadget/fsl_usb2_udc.h
@@ -497,6 +497,8 @@ struct fsl_udc {
size_t ep_qh_size;  /* size after alignment adjustment*/
dma_addr_t ep_qh_dma;   /* dma address of QH */
 
+   struct ep_td_struct *last_free_td;
+
u32 max_pipes;  /* Device max pipes */
u32 bus_reset;  /* Device is bus resetting */
u32 resume_state;   /* USB state to resume */
-- 
1.7.2.5

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 6/7] usb: gadget: fsl_udc: purge global pointer usb_sys_regs

2012-10-19 Thread Christoph Fritz
Move global driver pointer usb_sys_regs to private struct fsl_udc.

Signed-off-by: Christoph Fritz chf.fr...@googlemail.com
Reviewed-by: Teresa Gamez t.ga...@phytec.de
---
 drivers/usb/gadget/fsl_udc_core.c |   26 --
 drivers/usb/gadget/fsl_usb2_udc.h |1 +
 2 files changed, 13 insertions(+), 14 deletions(-)

diff --git a/drivers/usb/gadget/fsl_udc_core.c 
b/drivers/usb/gadget/fsl_udc_core.c
index deaab62..35ebcd4 100644
--- a/drivers/usb/gadget/fsl_udc_core.c
+++ b/drivers/usb/gadget/fsl_udc_core.c
@@ -43,8 +43,6 @@ static const char driver_desc[] = DRIVER_DESC;
 
 static struct usb_dr_device *dr_regs;
 
-static struct usb_sys_interface *usb_sys_regs;
-
 static const struct usb_endpoint_descriptor
 fsl_ep0_desc = {
.bLength =  USB_DT_ENDPOINT_SIZE,
@@ -170,10 +168,10 @@ static int dr_controller_setup(struct fsl_udc *udc)
if (udc-pdata-have_sysif_regs) {
if (udc-pdata-controller_ver) {
/* controller version 1.6 or above */
-   ctrl = __raw_readl(usb_sys_regs-control);
+   ctrl = readl(udc-usb_sys_regs-control);
ctrl = ~USB_CTRL_UTMI_PHY_EN;
ctrl |= USB_CTRL_USB_EN;
-   __raw_writel(ctrl, usb_sys_regs-control);
+   writel(ctrl, udc-usb_sys_regs-control);
}
}
portctrl |= PORTSCX_PTS_ULPI;
@@ -185,10 +183,10 @@ static int dr_controller_setup(struct fsl_udc *udc)
if (udc-pdata-have_sysif_regs) {
if (udc-pdata-controller_ver) {
/* controller version 1.6 or above */
-   ctrl = __raw_readl(usb_sys_regs-control);
+   ctrl = readl(udc-usb_sys_regs-control);
ctrl |= (USB_CTRL_UTMI_PHY_EN |
USB_CTRL_USB_EN);
-   __raw_writel(ctrl, usb_sys_regs-control);
+   writel(ctrl, udc-usb_sys_regs-control);
mdelay(FSL_UTMI_PHY_DLY); /* Delay for UTMI
PHY CLK to become stable - 10ms*/
}
@@ -254,9 +252,9 @@ static int dr_controller_setup(struct fsl_udc *udc)
/* Config control enable i/o output, cpu endian register */
 #ifndef CONFIG_ARCH_MXC
if (udc-pdata-have_sysif_regs) {
-   ctrl = __raw_readl(usb_sys_regs-control);
+   ctrl = readl(udc-usb_sys_regs-control);
ctrl |= USB_CTRL_IOENB;
-   __raw_writel(ctrl, usb_sys_regs-control);
+   writel(ctrl, udc-usb_sys_regs-control);
}
 #endif
 
@@ -267,9 +265,9 @@ static int dr_controller_setup(struct fsl_udc *udc)
if (udc-pdata-have_sysif_regs) {
/* Setup Snooping for all the 4GB space */
tmp = SNOOP_SIZE_2GB;   /* starts from 0x0, size 2G */
-   __raw_writel(tmp, usb_sys_regs-snoop1);
+   writel(tmp, udc-usb_sys_regs-snoop1);
tmp |= 0x8000;  /* starts from 0x800, size 2G */
-   __raw_writel(tmp, usb_sys_regs-snoop2);
+   writel(tmp, udc-usb_sys_regs-snoop2);
}
 #endif
 
@@ -326,7 +324,7 @@ static void dr_controller_stop(struct fsl_udc *udc)
udc-stopped = 1;
 
/* disable IO output */
-/* usb_sys_regs-control = 0; */
+/* udc-usb_sys_regs-control = 0; */
 
/* set controller to Stop */
tmp = readl(dr_regs-usbcmd);
@@ -2130,12 +2128,12 @@ static int fsl_proc_read(char *page, char **start, 
off_t off, int count,
 
 #ifndef CONFIG_ARCH_MXC
if (udc-pdata-have_sysif_regs) {
-   tmp_reg = usb_sys_regs-snoop1;
+   tmp_reg = udc-usb_sys_regs-snoop1;
t = scnprintf(next, size, Snoop1 Reg : = [0x%x]\n\n, tmp_reg);
size -= t;
next += t;
 
-   tmp_reg = usb_sys_regs-control;
+   tmp_reg = udc-usb_sys_regs-control;
t = scnprintf(next, size, General Control Reg : = [0x%x]\n\n,
tmp_reg);
size -= t;
@@ -2388,7 +2386,7 @@ static int __init fsl_udc_probe(struct platform_device 
*pdev)
 
 #ifndef CONFIG_ARCH_MXC
if (pdata-have_sysif_regs)
-   usb_sys_regs = (void *)dr_regs + USB_DR_SYS_OFFSET;
+   udc-usb_sys_regs = (void *)dr_regs + USB_DR_SYS_OFFSET;
 #endif
 
/* Initialize USB clocks */
diff --git a/drivers/usb/gadget/fsl_usb2_udc.h 
b/drivers/usb/gadget/fsl_usb2_udc.h
index a0123ae..0d888f4 100644
--- a/drivers/usb/gadget/fsl_usb2_udc.h
+++ b/drivers/usb/gadget/fsl_usb2_udc.h
@@ -498,6 +498,7 @@ struct fsl_udc {
dma_addr_t ep_qh_dma;   /* dma

[PATCH 7/7] usb: gadget: fsl_udc: purge global pointer dr_regs

2012-10-19 Thread Christoph Fritz
Move global driver pointer dr_regs to private struct fsl_udc.

Signed-off-by: Christoph Fritz chf.fr...@googlemail.com
---
 drivers/usb/gadget/fsl_udc_core.c |  252 +++--
 drivers/usb/gadget/fsl_usb2_udc.h |1 +
 2 files changed, 130 insertions(+), 123 deletions(-)

diff --git a/drivers/usb/gadget/fsl_udc_core.c 
b/drivers/usb/gadget/fsl_udc_core.c
index 35ebcd4..f9c4eb9 100644
--- a/drivers/usb/gadget/fsl_udc_core.c
+++ b/drivers/usb/gadget/fsl_udc_core.c
@@ -41,8 +41,6 @@
 static const char driver_name[] = DRIVER_NAME;
 static const char driver_desc[] = DRIVER_DESC;
 
-static struct usb_dr_device *dr_regs;
-
 static const struct usb_endpoint_descriptor
 fsl_ep0_desc = {
.bLength =  USB_DT_ENDPOINT_SIZE,
@@ -161,7 +159,7 @@ static int dr_controller_setup(struct fsl_udc *udc)
 #define FSL_UDC_RESET_TIMEOUT 1000
 
/* Config PHY interface */
-   portctrl = readl(dr_regs-portsc1);
+   portctrl = readl(udc-dr_regs-portsc1);
portctrl = ~(PORTSCX_PHY_TYPE_SEL | PORTSCX_PORT_WIDTH);
switch (udc-phy_mode) {
case FSL_USB2_PHY_ULPI:
@@ -199,20 +197,20 @@ static int dr_controller_setup(struct fsl_udc *udc)
default:
return -EINVAL;
}
-   writel(portctrl, dr_regs-portsc1);
+   writel(portctrl, udc-dr_regs-portsc1);
 
/* Stop and reset the usb controller */
-   tmp = readl(dr_regs-usbcmd);
+   tmp = readl(udc-dr_regs-usbcmd);
tmp = ~USB_CMD_RUN_STOP;
-   writel(tmp, dr_regs-usbcmd);
+   writel(tmp, udc-dr_regs-usbcmd);
 
-   tmp = readl(dr_regs-usbcmd);
+   tmp = readl(udc-dr_regs-usbcmd);
tmp |= USB_CMD_CTRL_RESET;
-   writel(tmp, dr_regs-usbcmd);
+   writel(tmp, udc-dr_regs-usbcmd);
 
/* Wait for reset to complete */
timeout = jiffies + FSL_UDC_RESET_TIMEOUT;
-   while (readl(dr_regs-usbcmd)  USB_CMD_CTRL_RESET) {
+   while (readl(udc-dr_regs-usbcmd)  USB_CMD_CTRL_RESET) {
if (time_after(jiffies, timeout)) {
ERR(udc reset timeout!\n);
return -ETIMEDOUT;
@@ -221,33 +219,33 @@ static int dr_controller_setup(struct fsl_udc *udc)
}
 
/* Set the controller as device mode */
-   tmp = readl(dr_regs-usbmode);
+   tmp = readl(udc-dr_regs-usbmode);
tmp = ~USB_MODE_CTRL_MODE_MASK;/* clear mode bits */
tmp |= USB_MODE_CTRL_MODE_DEVICE;
/* Disable Setup Lockout */
tmp |= USB_MODE_SETUP_LOCK_OFF;
if (udc-pdata-es)
tmp |= USB_MODE_ES;
-   writel(tmp, dr_regs-usbmode);
+   writel(tmp, udc-dr_regs-usbmode);
 
/* Clear the setup status */
-   writel(0, dr_regs-usbsts);
+   writel(0, udc-dr_regs-usbsts);
 
tmp = udc-ep_qh_dma;
tmp = USB_EP_LIST_ADDRESS_MASK;
-   writel(tmp, dr_regs-endpointlistaddr);
+   writel(tmp, udc-dr_regs-endpointlistaddr);
 
VDBG(vir[qh_base] is %p phy[qh_base] is 0x%8x reg is 0x%8x,
udc-ep_qh, (int)tmp,
-   readl(dr_regs-endpointlistaddr));
+   readl(udc-dr_regs-endpointlistaddr));
 
-   max_no_of_ep = (0x001F  readl(dr_regs-dccparams));
+   max_no_of_ep = (0x001F  readl(udc-dr_regs-dccparams));
for (ep_num = 1; ep_num  max_no_of_ep; ep_num++) {
-   tmp = readl(dr_regs-endptctrl[ep_num]);
+   tmp = readl(udc-dr_regs-endptctrl[ep_num]);
tmp = ~(EPCTRL_TX_TYPE | EPCTRL_RX_TYPE);
tmp |= (EPCTRL_EP_TYPE_BULK  EPCTRL_TX_EP_TYPE_SHIFT)
| (EPCTRL_EP_TYPE_BULK  EPCTRL_RX_EP_TYPE_SHIFT);
-   writel(tmp, dr_regs-endptctrl[ep_num]);
+   writel(tmp, udc-dr_regs-endptctrl[ep_num]);
}
/* Config control enable i/o output, cpu endian register */
 #ifndef CONFIG_ARCH_MXC
@@ -284,20 +282,20 @@ static void dr_controller_run(struct fsl_udc *udc)
| USB_INTR_PTC_DETECT_EN | USB_INTR_RESET_EN
| USB_INTR_DEVICE_SUSPEND | USB_INTR_SYS_ERR_EN;
 
-   writel(temp, dr_regs-usbintr);
+   writel(temp, udc-dr_regs-usbintr);
 
/* Clear stopped bit */
udc-stopped = 0;
 
/* Set the controller as device mode */
-   temp = readl(dr_regs-usbmode);
+   temp = readl(udc-dr_regs-usbmode);
temp |= USB_MODE_CTRL_MODE_DEVICE;
-   writel(temp, dr_regs-usbmode);
+   writel(temp, udc-dr_regs-usbmode);
 
/* Set controller to Run */
-   temp = readl(dr_regs-usbcmd);
+   temp = readl(udc-dr_regs-usbcmd);
temp |= USB_CMD_RUN_STOP;
-   writel(temp, dr_regs-usbcmd);
+   writel(temp, udc-dr_regs-usbcmd);
 }
 
 static void dr_controller_stop(struct fsl_udc *udc)
@@ -311,14 +309,14 @@ static void dr_controller_stop(struct fsl_udc *udc)
 * ehci driver
 */
if (udc-gadget.is_otg) {
-   if (!(readl(dr_regs-otgsc

Re: [PATCH 5/7] usb: gadget: fsl_udc: postpone freeing current dTD

2012-10-19 Thread Christoph Fritz
On Fri, 2012-10-19 at 13:30 +0300, Felipe Balbi wrote:
 On Fri, Oct 19, 2012 at 12:24:43PM +0200, Christoph Fritz wrote:
  USB controller may access a wrong address for the dTD (endpoint transfer
  descriptor) and then hang. This happens a lot when doing tests with
  g_ether module and iperf, a tool for measuring maximum TCP and UDP
  bandwidth.
  
  This hardware bug is explained in detail by errata number 2858 for i.MX23:
  http://cache.freescale.com/files/dsp/doc/errata/IMX23CE.pdf
  
  All (?) SOCs with an IP from chipidea suffer from this problem.
  mv_udc_core fixes this bug by commit daec765.  There still may be
  unfixed drivers.
 
 why aren't you using that driver instead ? Is it really necessary to
 keep this driver around ? I would really like to see uniformization
 towards that, if you use the same IP, then the same driver ought to
 suffice.
 
 What's the reason for not using drivers/usb/chipidea ?
 

I thought about this too but wasn't able to use chipidea with
MXC_EHCI_INTERNAL_PHY as it's called in fsl_udc.

Sascha, do you know if i.mx35 works with usb/chipidea?

Thanks
 -- Christoph

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH v2] usb: fsl_udc: errata - postpone freeing current dTD

2012-06-12 Thread Christoph Fritz
Hi Fabio

On Sun, 2012-06-10 at 15:41 -0300, Fabio Estevam wrote:
 Hi Christoph,
 
 On Mon, Jun 4, 2012 at 8:37 AM, Christoph Fritz
 chf.fr...@googlemail.com wrote:
 
  After that, I stumbled upon this dmesg:
 
  Freescale High-Speed USB SOC Device Controller driver (Apr 20, 2007)
  fsl-usb2-udc fsl-usb2-udc: clk_get(usb) failed
  fsl-usb2-udc: probe of fsl-usb2-udc failed with error -2
 
  Sascha, could you give me a hint?
 
 Does the patch below fix your problem?

Thanks for your patch. It does indeed load
Freescale High-Speed USB SOC Device Controller driver (Apr 20, 2007)
fine - but now when I want to use it:

modprobe g_ether
[   17.099363] g_ether gadget: using random self ethernet address
[   17.105316] g_ether gadget: using random host ethernet address
[   17.111974] usb0: MAC 1a:c7:9e:76:cc:45
[   17.115866] usb0: HOST MAC 66:a2:4a:0a:46:17
[   17.120199] g_ether gadget: Ethernet Gadget, version: Memorial Day 2008
[   17.126861] g_ether gadget: g_ether ready

these are the last words: System hangs completely. Same behavior with
g_serial (these two I've tested).

Currently I can't investigate this further, not because of a bug - but a
flu.


Thanks,
 -- Christoph

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH v2] usb: fsl_udc: errata - postpone freeing current dTD

2012-06-04 Thread Christoph Fritz
Hi,

On Mon, 2012-05-21 at 22:04 +0300, Felipe Balbi wrote:
 On Mon, May 21, 2012 at 08:57:22AM +0200, Christoph Fritz wrote:
  USB controller may access a wrong address for the dTD (endpoint transfer
  descriptor) and then hang. This happens a lot when doing tests with
  g_ether module and iperf, a tool for measuring maximum TCP and UDP
  bandwidth.
  
  This hardware bug is explained in detail by errata number 2858 for i.MX23:
  http://cache.freescale.com/files/dsp/doc/errata/IMX23CE.pdf
  
  All (?) SOCs with an IP from chipidea suffer from this problem.
  mv_udc_core fixes this bug by commit daec765.  There still may be
  unfixed drivers.
  
  Signed-off-by: Christoph Fritz chf.fr...@googlemail.com
  Signed-off-by: Christian Hemp c.h...@phytec.de
  ---
   drivers/usb/gadget/fsl_udc_core.c |   15 ++-
   1 files changed, 14 insertions(+), 1 deletions(-)
  
  diff --git a/drivers/usb/gadget/fsl_udc_core.c 
  b/drivers/usb/gadget/fsl_udc_core.c
  index 55abfb6..72f2139 100644
  --- a/drivers/usb/gadget/fsl_udc_core.c
  +++ b/drivers/usb/gadget/fsl_udc_core.c
  @@ -65,6 +65,8 @@ static struct usb_sys_interface *usb_sys_regs;
   /* it is initialized in probe()  */
   static struct fsl_udc *udc_controller = NULL;
   
  +static struct ep_td_struct *last_free_td;
 
 I don't want to see global variables anymore. In fact, please convert
 this to the new udc_start()/udc_stop() calls and use the generic
 map/unmap routines.
 
 That'll help you get rid of a bunch of useless code on the driver. After
 that you should remove all asm/* header includes and drop the ARCH
 dependency.
 
 You can also drop the big-/little-endian helpers as you can make use of
 generic writel()/readl() routines.
 
 Please make sure these series comes in with enough time to reach v3.6
 merge window in about 3 months.
 
 You can put this fix together on that series after you drop the global.

Before I came to do the proposed changes, I stumbled upon this:

In file included from drivers/usb/gadget/fsl_udc_core.c:49:
drivers/usb/gadget/fsl_usb2_udc.h: In function ‘get_qh_by_ep’:
drivers/usb/gadget/fsl_usb2_udc.h:585: error: ‘struct fsl_ep’ has no member 
named ‘desc’
drivers/usb/gadget/fsl_udc_core.c: In function ‘done’:
drivers/usb/gadget/fsl_udc_core.c:187: error: ‘struct fsl_ep’ has no member 
named ‘desc’
drivers/usb/gadget/fsl_udc_core.c:187: error: ‘struct fsl_ep’ has no member 
named ‘desc’
snip

my proposed regression patch:
---
From: Christoph Fritz chf.fr...@googlemail.com
Date: Mon, 4 Jun 2012 12:58:21 +0200
Subject: [PATCH] usb: gadget: regression fix - useage of usb_ep

This patch removes redundant pointer to struct usb_endpoint_descriptor which
were missed in commit 79149b8:

 usb: gadget: Update fsl_udc_core to use usb_endpoint_descriptor inside the
 struct usb_ep

Signed-off-by: Christoph Fritz chf.fr...@googlemail.com
---
 drivers/usb/gadget/fsl_udc_core.c |2 +-
 drivers/usb/gadget/fsl_usb2_udc.h |4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/gadget/fsl_udc_core.c 
b/drivers/usb/gadget/fsl_udc_core.c
index 2831685..678ec4d 100644
--- a/drivers/usb/gadget/fsl_udc_core.c
+++ b/drivers/usb/gadget/fsl_udc_core.c
@@ -2575,7 +2575,7 @@ static int __init fsl_udc_probe(struct platform_device 
*pdev)
/* for ep0: the desc defined here;
 * for other eps, gadget layer called ep_enable with defined desc
 */
-   udc_controller-eps[0].desc = fsl_ep0_desc;
+   udc_controller-eps[0].ep.desc = fsl_ep0_desc;
udc_controller-eps[0].ep.maxpacket = USB_MAX_CTRL_PAYLOAD;
 
/* setup the udc-eps[] for non-control endpoints and link
diff --git a/drivers/usb/gadget/fsl_usb2_udc.h 
b/drivers/usb/gadget/fsl_usb2_udc.h
index 5cd7b7e..f61a967 100644
--- a/drivers/usb/gadget/fsl_usb2_udc.h
+++ b/drivers/usb/gadget/fsl_usb2_udc.h
@@ -568,10 +568,10 @@ static void dump_msg(const char *label, const u8 * buf, 
unsigned int length)
 /*
  * ### internal used help routines.
  */
-#define ep_index(EP)   ((EP)-desc-bEndpointAddress0xF)
+#define ep_index(EP)   ((EP)-ep.desc-bEndpointAddress0xF)
 #define ep_maxpacket(EP)   ((EP)-ep.maxpacket)
 #define ep_is_in(EP)   ( (ep_index(EP) == 0) ? (EP-udc-ep0_dir == \
-   USB_DIR_IN ):((EP)-desc-bEndpointAddress \
+   USB_DIR_IN) : ((EP)-ep.desc-bEndpointAddress \
 USB_DIR_IN)==USB_DIR_IN)
 #define get_ep_by_pipe(udc, pipe)  ((pipe == 1)? udc-eps[0]: \
udc-eps[pipe])
-- 
1.7.2.5





___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [PATCH v2] usb: fsl_udc: errata - postpone freeing current dTD

2012-06-04 Thread Christoph Fritz
On Mon, 2012-06-04 at 13:30 +0200, Christoph Fritz wrote:
 Hi,
 
 On Mon, 2012-05-21 at 22:04 +0300, Felipe Balbi wrote:
  On Mon, May 21, 2012 at 08:57:22AM +0200, Christoph Fritz wrote:
   USB controller may access a wrong address for the dTD (endpoint transfer
   descriptor) and then hang. This happens a lot when doing tests with
   g_ether module and iperf, a tool for measuring maximum TCP and UDP
   bandwidth.
   
   This hardware bug is explained in detail by errata number 2858 for i.MX23:
   http://cache.freescale.com/files/dsp/doc/errata/IMX23CE.pdf
   
   All (?) SOCs with an IP from chipidea suffer from this problem.
   mv_udc_core fixes this bug by commit daec765.  There still may be
   unfixed drivers.
   
   Signed-off-by: Christoph Fritz chf.fr...@googlemail.com
   Signed-off-by: Christian Hemp c.h...@phytec.de
   ---
drivers/usb/gadget/fsl_udc_core.c |   15 ++-
1 files changed, 14 insertions(+), 1 deletions(-)
   
   diff --git a/drivers/usb/gadget/fsl_udc_core.c 
   b/drivers/usb/gadget/fsl_udc_core.c
   index 55abfb6..72f2139 100644
   --- a/drivers/usb/gadget/fsl_udc_core.c
   +++ b/drivers/usb/gadget/fsl_udc_core.c
   @@ -65,6 +65,8 @@ static struct usb_sys_interface *usb_sys_regs;
/* it is initialized in probe()  */
static struct fsl_udc *udc_controller = NULL;

   +static struct ep_td_struct *last_free_td;
  
  I don't want to see global variables anymore. In fact, please convert
  this to the new udc_start()/udc_stop() calls and use the generic
  map/unmap routines.
  
  That'll help you get rid of a bunch of useless code on the driver. After
  that you should remove all asm/* header includes and drop the ARCH
  dependency.
  
  You can also drop the big-/little-endian helpers as you can make use of
  generic writel()/readl() routines.
  
  Please make sure these series comes in with enough time to reach v3.6
  merge window in about 3 months.
  
  You can put this fix together on that series after you drop the global.
 
 Before I came to do the proposed changes, I stumbled upon this:
 
 In file included from drivers/usb/gadget/fsl_udc_core.c:49:
 drivers/usb/gadget/fsl_usb2_udc.h: In function ‘get_qh_by_ep’:
 drivers/usb/gadget/fsl_usb2_udc.h:585: error: ‘struct fsl_ep’ has no member 
 named ‘desc’
 drivers/usb/gadget/fsl_udc_core.c: In function ‘done’:
 drivers/usb/gadget/fsl_udc_core.c:187: error: ‘struct fsl_ep’ has no member 
 named ‘desc’
 drivers/usb/gadget/fsl_udc_core.c:187: error: ‘struct fsl_ep’ has no member 
 named ‘desc’
 snip
 
 my proposed regression patch:
 ---
 From: Christoph Fritz chf.fr...@googlemail.com
 Date: Mon, 4 Jun 2012 12:58:21 +0200
 Subject: [PATCH] usb: gadget: regression fix - useage of usb_ep
snip

After that, I stumbled upon this dmesg:

Freescale High-Speed USB SOC Device Controller driver (Apr 20, 2007)
fsl-usb2-udc fsl-usb2-udc: clk_get(usb) failed
fsl-usb2-udc: probe of fsl-usb2-udc failed with error -2

Sascha, could you give me a hint?

 Thanks,
  -- Christoph


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH] usb: gadget: regression fix - useage of usb_ep

2012-06-04 Thread Christoph Fritz
This patch removes redundant pointer to struct usb_endpoint_descriptor which
were missed in commit 79149b8:

 usb: gadget: Update fsl_udc_core to use usb_endpoint_descriptor inside the
 struct usb_ep

Due to clock framework regressions, this patch is only compile tested!

Signed-off-by: Christoph Fritz chf.fr...@googlemail.com
---
 drivers/usb/gadget/fsl_udc_core.c |2 +-
 drivers/usb/gadget/fsl_usb2_udc.h |4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/gadget/fsl_udc_core.c 
b/drivers/usb/gadget/fsl_udc_core.c
index 2831685..678ec4d 100644
--- a/drivers/usb/gadget/fsl_udc_core.c
+++ b/drivers/usb/gadget/fsl_udc_core.c
@@ -2575,7 +2575,7 @@ static int __init fsl_udc_probe(struct platform_device 
*pdev)
/* for ep0: the desc defined here;
 * for other eps, gadget layer called ep_enable with defined desc
 */
-   udc_controller-eps[0].desc = fsl_ep0_desc;
+   udc_controller-eps[0].ep.desc = fsl_ep0_desc;
udc_controller-eps[0].ep.maxpacket = USB_MAX_CTRL_PAYLOAD;
 
/* setup the udc-eps[] for non-control endpoints and link
diff --git a/drivers/usb/gadget/fsl_usb2_udc.h 
b/drivers/usb/gadget/fsl_usb2_udc.h
index 5cd7b7e..f61a967 100644
--- a/drivers/usb/gadget/fsl_usb2_udc.h
+++ b/drivers/usb/gadget/fsl_usb2_udc.h
@@ -568,10 +568,10 @@ static void dump_msg(const char *label, const u8 * buf, 
unsigned int length)
 /*
  * ### internal used help routines.
  */
-#define ep_index(EP)   ((EP)-desc-bEndpointAddress0xF)
+#define ep_index(EP)   ((EP)-ep.desc-bEndpointAddress0xF)
 #define ep_maxpacket(EP)   ((EP)-ep.maxpacket)
 #define ep_is_in(EP)   ( (ep_index(EP) == 0) ? (EP-udc-ep0_dir == \
-   USB_DIR_IN ):((EP)-desc-bEndpointAddress \
+   USB_DIR_IN) : ((EP)-ep.desc-bEndpointAddress \
 USB_DIR_IN)==USB_DIR_IN)
 #define get_ep_by_pipe(udc, pipe)  ((pipe == 1)? udc-eps[0]: \
udc-eps[pipe])
-- 
1.7.2.5



___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


RE: [PATCH] usb: fsl_udc: errata - postpone freeing current dTD

2012-05-21 Thread Christoph Fritz
Hi Chen,

On Mon, 2012-05-21 at 01:05 +, Chen Peter-B29397 wrote:
 
  
  
  USB controller may access a wrong address for the dTD (endpoint transfer
  descriptor) and then hang. This happens a lot when doing tests with
  g_ether module and iperf, a tool for measuring maximum TCP and UDP
  bandwidth.
  
  This hardware bug is explained in detail by errata number 2858 for i.MX23:
  http://cache.freescale.com/files/dsp/doc/errata/IMX23CE.pdf
  
 
 Does this patch fix your problem?

yes, it does! :-)

  +#if defined CONFIG_ARCH_MX51 || defined CONFIG_SOC_IMX35
  +#define POSTPONE_FREE_LAST_DTD
  +#else
  +#undef POSTPONE_FREE_LAST_DTD
  +#endif
  +
 All i.mx SoC has this problem, if PowerPC also has this problem, you can 
 delete #if defined. Else, you can define it for all i.mx SoC 
 (CONFIG_ARCH_MXC | CONFIG_ARCH_MXS)

I was unsure about this too. I can only test imx35. And mx51 was defined
in your tree. So these two should be defined anyway.

Marvell doesn't use any defines in mv_udc_core for their fix, so I would
be fine without ifdefs too. Any objections? Please see next mail with
patch v2.


Thanks,
 -- Christoph

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH v2] usb: fsl_udc: errata - postpone freeing current dTD

2012-05-21 Thread Christoph Fritz
USB controller may access a wrong address for the dTD (endpoint transfer
descriptor) and then hang. This happens a lot when doing tests with
g_ether module and iperf, a tool for measuring maximum TCP and UDP
bandwidth.

This hardware bug is explained in detail by errata number 2858 for i.MX23:
http://cache.freescale.com/files/dsp/doc/errata/IMX23CE.pdf

All (?) SOCs with an IP from chipidea suffer from this problem.
mv_udc_core fixes this bug by commit daec765.  There still may be
unfixed drivers.

Signed-off-by: Christoph Fritz chf.fr...@googlemail.com
Signed-off-by: Christian Hemp c.h...@phytec.de
---
 drivers/usb/gadget/fsl_udc_core.c |   15 ++-
 1 files changed, 14 insertions(+), 1 deletions(-)

diff --git a/drivers/usb/gadget/fsl_udc_core.c 
b/drivers/usb/gadget/fsl_udc_core.c
index 55abfb6..72f2139 100644
--- a/drivers/usb/gadget/fsl_udc_core.c
+++ b/drivers/usb/gadget/fsl_udc_core.c
@@ -65,6 +65,8 @@ static struct usb_sys_interface *usb_sys_regs;
 /* it is initialized in probe()  */
 static struct fsl_udc *udc_controller = NULL;
 
+static struct ep_td_struct *last_free_td;
+
 static const struct usb_endpoint_descriptor
 fsl_ep0_desc = {
.bLength =  USB_DT_ENDPOINT_SIZE,
@@ -180,8 +182,13 @@ static void done(struct fsl_ep *ep, struct fsl_req *req, 
int status)
curr_td = next_td;
if (j != req-dtd_count - 1) {
next_td = curr_td-next_td_virt;
+   dma_pool_free(udc-td_pool, curr_td, curr_td-td_dma);
+   } else {
+   if (last_free_td != NULL)
+   dma_pool_free(udc-td_pool, last_free_td,
+   last_free_td-td_dma);
+   last_free_td = curr_td;
}
-   dma_pool_free(udc-td_pool, curr_td, curr_td-td_dma);
}
 
if (req-mapped) {
@@ -2579,6 +2586,8 @@ static int __init fsl_udc_probe(struct platform_device 
*pdev)
goto err_unregister;
}
 
+   last_free_td = NULL;
+
ret = usb_add_gadget_udc(pdev-dev, udc_controller-gadget);
if (ret)
goto err_del_udc;
@@ -2633,6 +2642,10 @@ static int __exit fsl_udc_remove(struct platform_device 
*pdev)
kfree(udc_controller-status_req);
kfree(udc_controller-eps);
 
+   if (last_free_td != NULL)
+   dma_pool_free(udc_controller-td_pool, last_free_td,
+   last_free_td-td_dma);
+
dma_pool_destroy(udc_controller-td_pool);
free_irq(udc_controller-irq, udc_controller);
iounmap(dr_regs);
-- 
1.7.2.5


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH] usb: fsl_udc: errata - postpone freeing current dTD

2012-05-20 Thread Christoph Fritz
USB controller may access a wrong address for the dTD (endpoint transfer
descriptor) and then hang. This happens a lot when doing tests with
g_ether module and iperf, a tool for measuring maximum TCP and UDP
bandwidth.

This hardware bug is explained in detail by errata number 2858 for i.MX23:
http://cache.freescale.com/files/dsp/doc/errata/IMX23CE.pdf

mv_udc_core fixes this bug by commit daec765. There still may be unfixed
drivers.

Signed-off-by: Christoph Fritz chf.fr...@googlemail.com
Signed-off-by: Christian Hemp c.h...@phytec.de
---
 drivers/usb/gadget/fsl_udc_core.c |   22 ++
 drivers/usb/gadget/fsl_usb2_udc.h |6 ++
 2 files changed, 28 insertions(+), 0 deletions(-)

diff --git a/drivers/usb/gadget/fsl_udc_core.c 
b/drivers/usb/gadget/fsl_udc_core.c
index 55abfb6..f9bfafd 100644
--- a/drivers/usb/gadget/fsl_udc_core.c
+++ b/drivers/usb/gadget/fsl_udc_core.c
@@ -65,6 +65,9 @@ static struct usb_sys_interface *usb_sys_regs;
 /* it is initialized in probe()  */
 static struct fsl_udc *udc_controller = NULL;
 
+#ifdef POSTPONE_FREE_LAST_DTD
+static struct ep_td_struct *last_free_td;
+#endif
 static const struct usb_endpoint_descriptor
 fsl_ep0_desc = {
.bLength =  USB_DT_ENDPOINT_SIZE,
@@ -180,8 +183,18 @@ static void done(struct fsl_ep *ep, struct fsl_req *req, 
int status)
curr_td = next_td;
if (j != req-dtd_count - 1) {
next_td = curr_td-next_td_virt;
+#ifdef POSTPONE_FREE_LAST_DTD
+   dma_pool_free(udc-td_pool, curr_td, curr_td-td_dma);
+   } else {
+   if (last_free_td != NULL)
+   dma_pool_free(udc-td_pool, last_free_td,
+   last_free_td-td_dma);
+   last_free_td = curr_td;
+   }
+#else
}
dma_pool_free(udc-td_pool, curr_td, curr_td-td_dma);
+#endif
}
 
if (req-mapped) {
@@ -2579,6 +2592,10 @@ static int __init fsl_udc_probe(struct platform_device 
*pdev)
goto err_unregister;
}
 
+#ifdef POSTPONE_FREE_LAST_DTD
+   last_free_td = NULL;
+#endif
+
ret = usb_add_gadget_udc(pdev-dev, udc_controller-gadget);
if (ret)
goto err_del_udc;
@@ -2633,6 +2650,11 @@ static int __exit fsl_udc_remove(struct platform_device 
*pdev)
kfree(udc_controller-status_req);
kfree(udc_controller-eps);
 
+#ifdef POSTPONE_FREE_LAST_DTD
+   if (last_free_td != NULL)
+   dma_pool_free(udc_controller-td_pool, last_free_td,
+   last_free_td-td_dma);
+#endif
dma_pool_destroy(udc_controller-td_pool);
free_irq(udc_controller-irq, udc_controller);
iounmap(dr_regs);
diff --git a/drivers/usb/gadget/fsl_usb2_udc.h 
b/drivers/usb/gadget/fsl_usb2_udc.h
index e651469..03ae07f 100644
--- a/drivers/usb/gadget/fsl_usb2_udc.h
+++ b/drivers/usb/gadget/fsl_usb2_udc.h
@@ -4,6 +4,12 @@
 #ifndef __FSL_USB2_UDC_H
 #define __FSL_USB2_UDC_H
 
+#if defined CONFIG_ARCH_MX51 || defined CONFIG_SOC_IMX35
+#define POSTPONE_FREE_LAST_DTD
+#else
+#undef POSTPONE_FREE_LAST_DTD
+#endif
+
 /* ### define USB registers here
  */
 #define USB_MAX_CTRL_PAYLOAD   64
-- 
1.7.2.5


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [RFC] [PATCH] usb: gadget: fix dtd dma confusion

2012-05-13 Thread Christoph Fritz
On Wed, May 09, 2012 at 02:02:22AM +0200, Christoph Fritz wrote:
 
 Hi to All,
 
 after a while of testing and searching I can come up with a patch
 that fixes g_ether - iperf for fsl_udc on ARM i.MX35.
 
 The sad part is that this kind of fix is already implemented for
 marvell mv_udc driver since last year but still _not_ in the ~15
 other *udc.c drivers.
 
 See here:
 daec765da767e4a6a30e1298862b28f2cae9a73f
 usb: gadget: mv_udc: fix dtd dma confusion
 
 So hereby I'm CC-ing all *udc.c maintainers to point out that this
 issue maybe affects you too.
 
 
 ---
 Subject: [PATCH] usb: gadget: fsl_udc: fix dtd dma confusion
 
 The controller will hang when doing testings with g_ether and iperf
 (tool for measuring maximum TCP and UDP bandwidth).  This patch adds a
 delay to wait for controller to release dtd dma before freeing it.
 
 Signed-off-by: Christoph Fritz chf.fr...@googlemail.com
 ---
  drivers/usb/gadget/fsl_udc_core.c |9 +
  1 files changed, 9 insertions(+), 0 deletions(-)
 
 diff --git a/drivers/usb/gadget/fsl_udc_core.c 
 b/drivers/usb/gadget/fsl_udc_core.c
 index 55abfb6..fc86108 100644
 --- a/drivers/usb/gadget/fsl_udc_core.c
 +++ b/drivers/usb/gadget/fsl_udc_core.c
 @@ -1638,6 +1638,15 @@ static int process_ep_req(struct fsl_udc *udc, int 
 pipe,
   status = REQ_UNCOMPLETE;
   return status;
   } else if (remaining_length) {
 + /* wait controller release dtd dma */
 + while ((curr_qh-curr_dtd_ptr == curr_td-td_dma)) {
 + if (curr_td-next_td_ptr ==
 + EP_QUEUE_HEAD_NEXT_TERMINATE) {
 + udelay(100);
 + break;
 + }
 + udelay(1);
 + }
   if (direction) {
   VDBG(Transmit dTD remaining length not zero);
   status = -EPROTO;
 -- 
 1.7.2.5

 ping  -  what about this patch? Will it be applied?

Thanks,
 -- Christoph
 
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [RFC] [PATCH] usb: gadget: fix dtd dma confusion

2012-05-09 Thread Christoph Fritz
Hi Neil,

 thanks for you help.

  
  What about the fix for mv_udc, shouldn't they have a similar
  limitation? How do you explain?
  Or maybe someone from Marvell has an answer?
  
 
 Yes, we encountered the same issue, and I have answered your question several 
 hours ago.
 Please have a look.

Thanks for that.
Relating to the other *udc.c driver, do you think they should implement
a similar workaround there too or at least check their errataS?

Thanks,
 -- Christoph
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[RFC] [PATCH] usb: gadget: fix dtd dma confusion

2012-05-08 Thread Christoph Fritz
On Wed, Apr 11, 2012 at 10:15:49AM -0300, Fabio Estevam wrote:
 On Wed, Apr 11, 2012 at 4:39 AM, Christoph Fritz
 chf.fr...@googlemail.com wrote:
 
  Can you approve this behaviour of g_ether/usbnet when using iperf?
 
 I am not very familiar with iperf, so I will let others comment.

Hi to All,

after a while of testing and searching I can come up with a patch
that fixes g_ether - iperf for fsl_udc on ARM i.MX35.

The sad part is that this kind of fix is already implemented for
marvell mv_udc driver since last year but still _not_ in the ~15
other *udc.c drivers.

See here:
daec765da767e4a6a30e1298862b28f2cae9a73f
usb: gadget: mv_udc: fix dtd dma confusion

So hereby I'm CC-ing all *udc.c maintainers to point out that this
issue maybe affects you too.

And maybe someone can explain if this: 
+   if (curr_td-next_td_ptr == 
EP_QUEUE_HEAD_NEXT_TERMINATE) {
is necessary and why (please see below).


Thanks,
 -- Christoph

---
Subject: [PATCH] usb: gadget: fsl_udc: fix dtd dma confusion

The controller will hang when doing testings with g_ether and iperf
(tool for measuring maximum TCP and UDP bandwidth).  This patch adds a
delay to wait for controller to release dtd dma before freeing it.

Signed-off-by: Christoph Fritz chf.fr...@googlemail.com
---
 drivers/usb/gadget/fsl_udc_core.c |9 +
 1 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/drivers/usb/gadget/fsl_udc_core.c 
b/drivers/usb/gadget/fsl_udc_core.c
index 55abfb6..fc86108 100644
--- a/drivers/usb/gadget/fsl_udc_core.c
+++ b/drivers/usb/gadget/fsl_udc_core.c
@@ -1638,6 +1638,15 @@ static int process_ep_req(struct fsl_udc *udc, int pipe,
status = REQ_UNCOMPLETE;
return status;
} else if (remaining_length) {
+   /* wait controller release dtd dma */
+   while ((curr_qh-curr_dtd_ptr == curr_td-td_dma)) {
+   if (curr_td-next_td_ptr ==
+   EP_QUEUE_HEAD_NEXT_TERMINATE) {
+   udelay(100);
+   break;
+   }
+   udelay(1);
+   }
if (direction) {
VDBG(Transmit dTD remaining length not zero);
status = -EPROTO;
-- 
1.7.2.5


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [RFC] [PATCH] usb: gadget: fix dtd dma confusion

2012-05-08 Thread Christoph Fritz
Hi Peter,

 thanks you for your help.

On Wed, May 09, 2012 at 02:11:56AM +, Chen Peter-B29397 wrote:
 
  
  
   after a while of testing and searching I can come up with a patch
   that fixes g_ether - iperf for fsl_udc on ARM i.MX35.
  
   The sad part is that this kind of fix is already implemented for
   marvell mv_udc driver since last year but still _not_ in the ~15
   other *udc.c drivers.
  
  
 It is a controller limitation (bug?) for chipidea controller when using
 dtd list to handle multi-dtds situation. The controller will read dtd's
 next pointer after this dtd's active bit has already been cleared.
 
 Freescale has an errata for this problem's description and solution.
 http://cache.freescale.com/files/dsp/doc/errata/IMX23CE.pdf
 See 2858

I'm hacking here an i.MX35 not an i.MX23. So I already had a look at its
errata sheet http://cache.freescale.com/files/dsp/doc/errata/IMX35CE.pdf
but didn't find a similar limitation as you now pointed out by errata
number 2858 for i.MX23.

What about the fix for mv_udc, shouldn't they have a similar
limitation? How do you explain?
Or maybe someone from Marvell has an answer?


Thanks,
 -- Christoph
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [RFC] [PATCH] usb: gadget: fix dtd dma confusion

2012-05-08 Thread Christoph Fritz
On Wed, May 09, 2012 at 05:43:11AM +, Chen Peter-B29397 wrote:
  
  
  I'm hacking here an i.MX35 not an i.MX23. So I already had a look at its
  errata sheet http://cache.freescale.com/files/dsp/doc/errata/IMX35CE.pdf
  but didn't find a similar limitation as you now pointed out by errata
  number 2858 for i.MX23.
 
 
 i.mx35 and i.mx23 uses the same controller.

A link or short note in i.MX35 its errata sheet to the i.MX23 one
would be nice.

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev