Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 248774
b: refs/heads/master
c: 2ea6698
h: refs/heads/master
v: v3
  • Loading branch information
Anatolij Gustschin authored and Greg Kroah-Hartman committed May 2, 2011
1 parent 2c92017 commit 2b29873
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 32 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 09ba0def9aefc16c1c8a6d166f024c9d704f0ab0
refs/heads/master: 2ea6698d7b9266da53044dddc5f6743adf097fb5
141 changes: 110 additions & 31 deletions trunk/drivers/usb/gadget/fsl_udc_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
*
* Description:
* Freescale high-speed USB SOC DR module device controller driver.
* This can be found on MPC8349E/MPC8313E cpus.
* This can be found on MPC8349E/MPC8313E/MPC5121E cpus.
* The driver is previously named as mpc_udc. Based on bare board
* code from Dave Liu and Shlomi Gridish.
*
Expand Down Expand Up @@ -45,6 +45,7 @@
#include <asm/system.h>
#include <asm/unaligned.h>
#include <asm/dma.h>
#include <asm/cacheflush.h>

#include "fsl_usb2_udc.h"

Expand Down Expand Up @@ -278,9 +279,12 @@ static int dr_controller_setup(struct fsl_udc *udc)

/* Set the controller as device mode */
tmp = fsl_readl(&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;
fsl_writel(tmp, &dr_regs->usbmode);

/* Clear the setup status */
Expand All @@ -296,20 +300,24 @@ static int dr_controller_setup(struct fsl_udc *udc)

/* Config control enable i/o output, cpu endian register */
#ifndef CONFIG_ARCH_MXC
ctrl = __raw_readl(&usb_sys_regs->control);
ctrl |= USB_CTRL_IOENB;
__raw_writel(ctrl, &usb_sys_regs->control);
if (udc->pdata->have_sysif_regs) {
ctrl = __raw_readl(&usb_sys_regs->control);
ctrl |= USB_CTRL_IOENB;
__raw_writel(ctrl, &usb_sys_regs->control);
}
#endif

#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
/* Turn on cache snooping hardware, since some PowerPC platforms
* wholly rely on hardware to deal with cache coherent. */

/* Setup Snooping for all the 4GB space */
tmp = SNOOP_SIZE_2GB; /* starts from 0x0, size 2G */
__raw_writel(tmp, &usb_sys_regs->snoop1);
tmp |= 0x80000000; /* starts from 0x8000000, size 2G */
__raw_writel(tmp, &usb_sys_regs->snoop2);
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);
tmp |= 0x80000000; /* starts from 0x8000000, size 2G */
__raw_writel(tmp, &usb_sys_regs->snoop2);
}
#endif

return 0;
Expand Down Expand Up @@ -1014,6 +1022,36 @@ static int fsl_ep_set_halt(struct usb_ep *_ep, int value)
return status;
}

static int fsl_ep_fifo_status(struct usb_ep *_ep)
{
struct fsl_ep *ep;
struct fsl_udc *udc;
int size = 0;
u32 bitmask;
struct ep_queue_head *d_qh;

ep = container_of(_ep, struct fsl_ep, ep);
if (!_ep || (!ep->desc && ep_index(ep) != 0))
return -ENODEV;

udc = (struct fsl_udc *)ep->udc;

if (!udc->driver || udc->gadget.speed == USB_SPEED_UNKNOWN)
return -ESHUTDOWN;

d_qh = &ep->udc->ep_qh[ep_index(ep) * 2 + ep_is_in(ep)];

bitmask = (ep_is_in(ep)) ? (1 << (ep_index(ep) + 16)) :
(1 << (ep_index(ep)));

if (fsl_readl(&dr_regs->endptstatus) & bitmask)
size = (d_qh->size_ioc_int_sts & DTD_PACKET_SIZE)
>> DTD_LENGTH_BIT_POS;

pr_debug("%s %u\n", __func__, size);
return size;
}

static void fsl_ep_fifo_flush(struct usb_ep *_ep)
{
struct fsl_ep *ep;
Expand Down Expand Up @@ -1066,6 +1104,7 @@ static struct usb_ep_ops fsl_ep_ops = {
.dequeue = fsl_ep_dequeue,

.set_halt = fsl_ep_set_halt,
.fifo_status = fsl_ep_fifo_status,
.fifo_flush = fsl_ep_fifo_flush, /* flush fifo */
};

Expand Down Expand Up @@ -1280,6 +1319,10 @@ static void ch9getstatus(struct fsl_udc *udc, u8 request_type, u16 value,
req = udc->status_req;
/* Fill in the reqest structure */
*((u16 *) req->req.buf) = cpu_to_le16(tmp);

/* flush cache for the req buffer */
flush_dcache_range((u32)req->req.buf, (u32)req->req.buf + 8);

req->ep = ep;
req->req.length = 2;
req->req.status = -EINPROGRESS;
Expand Down Expand Up @@ -1332,6 +1375,7 @@ static void setup_received_irq(struct fsl_udc *udc,
/* Status phase from udc */
{
int rc = -EOPNOTSUPP;
u16 ptc = 0;

if ((setup->bRequestType & (USB_RECIP_MASK | USB_TYPE_MASK))
== (USB_RECIP_ENDPOINT | USB_TYPE_STANDARD)) {
Expand All @@ -1353,17 +1397,19 @@ static void setup_received_irq(struct fsl_udc *udc,
| USB_TYPE_STANDARD)) {
/* Note: The driver has not include OTG support yet.
* This will be set when OTG support is added */
if (!gadget_is_otg(&udc->gadget))
break;
else if (setup->bRequest == USB_DEVICE_B_HNP_ENABLE)
udc->gadget.b_hnp_enable = 1;
else if (setup->bRequest == USB_DEVICE_A_HNP_SUPPORT)
udc->gadget.a_hnp_support = 1;
else if (setup->bRequest ==
USB_DEVICE_A_ALT_HNP_SUPPORT)
udc->gadget.a_alt_hnp_support = 1;
else
break;
if (wValue == USB_DEVICE_TEST_MODE)
ptc = wIndex >> 8;
else if (gadget_is_otg(&udc->gadget)) {
if (setup->bRequest ==
USB_DEVICE_B_HNP_ENABLE)
udc->gadget.b_hnp_enable = 1;
else if (setup->bRequest ==
USB_DEVICE_A_HNP_SUPPORT)
udc->gadget.a_hnp_support = 1;
else if (setup->bRequest ==
USB_DEVICE_A_ALT_HNP_SUPPORT)
udc->gadget.a_alt_hnp_support = 1;
}
rc = 0;
} else
break;
Expand All @@ -1372,6 +1418,15 @@ static void setup_received_irq(struct fsl_udc *udc,
if (ep0_prime_status(udc, EP_DIR_IN))
ep0stall(udc);
}
if (ptc) {
u32 tmp;

mdelay(10);
tmp = fsl_readl(&dr_regs->portsc1) | (ptc << 16);
fsl_writel(tmp, &dr_regs->portsc1);
printk(KERN_INFO "udc: switch to test mode %d.\n", ptc);
}

return;
}

Expand Down Expand Up @@ -2106,16 +2161,18 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count,
next += t;

#ifndef CONFIG_ARCH_MXC
tmp_reg = usb_sys_regs->snoop1;
t = scnprintf(next, size, "Snoop1 Reg : = [0x%x]\n\n", tmp_reg);
size -= t;
next += t;
if (udc->pdata->have_sysif_regs) {
tmp_reg = 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;
t = scnprintf(next, size, "General Control Reg : = [0x%x]\n\n",
tmp_reg);
size -= t;
next += t;
tmp_reg = usb_sys_regs->control;
t = scnprintf(next, size, "General Control Reg : = [0x%x]\n\n",
tmp_reg);
size -= t;
next += t;
}
#endif

/* ------fsl_udc, fsl_ep, fsl_request structure information ----- */
Expand Down Expand Up @@ -2336,6 +2393,17 @@ static int __init fsl_udc_probe(struct platform_device *pdev)
goto err_release_mem_region;
}

pdata->regs = (void *)dr_regs;

/*
* do platform specific init: check the clock, grab/config pins, etc.
*/
if (pdata->init && pdata->init(pdev)) {
ret = -ENODEV;
goto err_iounmap_noclk;
}

/* Set accessors only after pdata->init() ! */
if (pdata->big_endian_mmio) {
_fsl_readl = _fsl_readl_be;
_fsl_writel = _fsl_writel_be;
Expand All @@ -2345,8 +2413,9 @@ static int __init fsl_udc_probe(struct platform_device *pdev)
}

#ifndef CONFIG_ARCH_MXC
usb_sys_regs = (struct usb_sys_interface *)
((u32)dr_regs + USB_DR_SYS_OFFSET);
if (pdata->have_sysif_regs)
usb_sys_regs = (struct usb_sys_interface *)
((u32)dr_regs + USB_DR_SYS_OFFSET);
#endif

/* Initialize USB clocks */
Expand Down Expand Up @@ -2446,6 +2515,8 @@ static int __init fsl_udc_probe(struct platform_device *pdev)
err_free_irq:
free_irq(udc_controller->irq, udc_controller);
err_iounmap:
if (pdata->exit)
pdata->exit(pdev);
fsl_udc_clk_release();
err_iounmap_noclk:
iounmap(dr_regs);
Expand All @@ -2463,6 +2534,7 @@ static int __init fsl_udc_probe(struct platform_device *pdev)
static int __exit fsl_udc_remove(struct platform_device *pdev)
{
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data;

DECLARE_COMPLETION(done);

Expand All @@ -2489,6 +2561,13 @@ static int __exit fsl_udc_remove(struct platform_device *pdev)
/* free udc --wait for the release() finished */
wait_for_completion(&done);

/*
* do platform specific un-initialization:
* release iomux pins, etc.
*/
if (pdata->exit)
pdata->exit(pdev);

return 0;
}

Expand Down
2 changes: 2 additions & 0 deletions trunk/drivers/usb/gadget/fsl_usb2_udc.h
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,9 @@ struct usb_sys_interface {
#define USB_MODE_CTRL_MODE_IDLE 0x00000000
#define USB_MODE_CTRL_MODE_DEVICE 0x00000002
#define USB_MODE_CTRL_MODE_HOST 0x00000003
#define USB_MODE_CTRL_MODE_MASK 0x00000003
#define USB_MODE_CTRL_MODE_RSV 0x00000001
#define USB_MODE_ES 0x00000004 /* Endian Select */
#define USB_MODE_SETUP_LOCK_OFF 0x00000008
#define USB_MODE_STREAM_DISABLE 0x00000010
/* Endpoint Flush Register */
Expand Down

0 comments on commit 2b29873

Please sign in to comment.