* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
-
+#undef DEBUG
#include <common.h>
#include <asm/errno.h>
#include <linux/list.h>
#include <linux/usb/gadget.h>
#include <asm/byteorder.h>
+#include <asm/unaligned.h>
#include <asm/io.h>
#include <asm/mach-types.h>
#include <asm/arch/gpio.h>
#include "regs-otg.h"
-#include <usb/s3c_udc.h>
#include <usb/lin_gadget_compat.h>
/***********************************************************/
#define OTG_DMA_MODE 1
-#undef DEBUG_S3C_UDC_SETUP
-#undef DEBUG_S3C_UDC_EP0
-#undef DEBUG_S3C_UDC_ISR
-#undef DEBUG_S3C_UDC_OUT_EP
-#undef DEBUG_S3C_UDC_IN_EP
-#undef DEBUG_S3C_UDC
-
-/* #define DEBUG_S3C_UDC_SETUP */
-/* #define DEBUG_S3C_UDC_EP0 */
-/* #define DEBUG_S3C_UDC_ISR */
-/* #define DEBUG_S3C_UDC_OUT_EP */
-/* #define DEBUG_S3C_UDC_IN_EP */
-/* #define DEBUG_S3C_UDC */
+#define DEBUG_SETUP 0
+#define DEBUG_EP0 0
+#define DEBUG_ISR 0
+#define DEBUG_OUT_EP 0
+#define DEBUG_IN_EP 0
#include <usb/s3c_udc.h>
#define EP0_CON 0
#define EP_MASK 0xF
-#if defined(DEBUG_S3C_UDC_SETUP) || defined(DEBUG_S3C_UDC_ISR) \
- || defined(DEBUG_S3C_UDC_OUT_EP)
static char *state_names[] = {
"WAIT_FOR_SETUP",
"DATA_STATE_XMIT",
"WAIT_FOR_IN_COMPLETE",
"WAIT_FOR_NULL_COMPLETE",
};
-#endif
#define DRIVER_DESC "S3C HS USB OTG Device Driver, (c) Samsung Electronics"
#define DRIVER_VERSION "15 March 2009"
static int s3c_udc_set_halt(struct usb_ep *_ep, int value);
static void s3c_udc_set_nak(struct s3c_ep *ep);
+void set_udc_gadget_private_data(void *p)
+{
+ debug_cond(DEBUG_SETUP != 0,
+ "%s: the_controller: 0x%p, p: 0x%p\n", __func__,
+ the_controller, p);
+ the_controller->gadget.dev.device_data = p;
+}
+
+void *get_udc_gadget_private_data(struct usb_gadget *gadget)
+{
+ return gadget->dev.device_data;
+}
+
static struct usb_ep_ops s3c_ep_ops = {
.enable = s3c_ep_enable,
.disable = s3c_ep_disable,
*/
static void udc_disable(struct s3c_udc *dev)
{
- DEBUG_SETUP("%s: %p\n", __func__, dev);
+ debug_cond(DEBUG_SETUP != 0, "%s: %p\n", __func__, dev);
udc_set_address(dev, 0);
{
unsigned int i;
- DEBUG_SETUP("%s: %p\n", __func__, dev);
+ debug_cond(DEBUG_SETUP != 0, "%s: %p\n", __func__, dev);
/* device/ep0 records init */
INIT_LIST_HEAD(&dev->gadget.ep_list);
*/
static int udc_enable(struct s3c_udc *dev)
{
- DEBUG_SETUP("%s: %p\n", __func__, dev);
+ debug_cond(DEBUG_SETUP != 0, "%s: %p\n", __func__, dev);
otg_phy_init(dev);
reconfig_usbd();
- DEBUG_SETUP("S3C USB 2.0 OTG Controller Core Initialized : 0x%x\n",
+ debug_cond(DEBUG_SETUP != 0,
+ "S3C USB 2.0 OTG Controller Core Initialized : 0x%x\n",
readl(®->gintmsk));
dev->gadget.speed = USB_SPEED_UNKNOWN;
int retval = 0;
unsigned long flags;
- DEBUG_SETUP("%s: %s\n", __func__, "no name");
+ debug_cond(DEBUG_SETUP != 0, "%s: %s\n", __func__, "no name");
if (!driver
|| (driver->speed != USB_SPEED_FULL
retval = driver->bind(&dev->gadget);
if (retval) {
- DEBUG_SETUP("%s: bind to driver --> error %d\n",
+ debug_cond(DEBUG_SETUP != 0,
+ "%s: bind to driver --> error %d\n",
dev->gadget.name, retval);
dev->driver = 0;
return retval;
enable_irq(IRQ_OTG);
- DEBUG_SETUP("Registered gadget driver %s\n", dev->gadget.name);
+ debug_cond(DEBUG_SETUP != 0,
+ "Registered gadget driver %s\n", dev->gadget.name);
udc_enable(dev);
return 0;
{
unsigned int stopped = ep->stopped;
- DEBUG("%s: %s %p, req = %p, stopped = %d\n",
+ debug("%s: %s %p, req = %p, stopped = %d\n",
__func__, ep->ep.name, ep, &req->req, stopped);
list_del_init(&req->queue);
status = req->req.status;
if (status && status != -ESHUTDOWN) {
- DEBUG("complete %s req %p stat %d len %u/%u\n",
+ debug("complete %s req %p stat %d len %u/%u\n",
ep->ep.name, &req->req, status,
req->req.actual, req->req.length);
}
/* don't modify queue heads during completion callback */
ep->stopped = 1;
-#ifdef DEBUG_S3C_UDC
+#ifdef DEBUG
printf("calling complete callback\n");
{
int i, len = req->req.length;
req->req.complete(&ep->ep, &req->req);
spin_lock(&ep->dev->lock);
- DEBUG("callback completed\n");
+ debug("callback completed\n");
ep->stopped = stopped;
}
{
struct s3c_request *req;
- DEBUG("%s: %s %p\n", __func__, ep->ep.name, ep);
+ debug("%s: %s %p\n", __func__, ep->ep.name, ep);
/* called with irqs blocked */
while (!list_empty(&ep->queue)) {
int i;
unsigned int uTemp = writel(CORE_SOFT_RESET, ®->grstctl);
- DEBUG(2, "Reseting OTG controller\n");
+ debug("Reseting OTG controller\n");
writel(0<<15 /* PHY Low Power Clock sel*/
|1<<14 /* Non-Periodic TxFIFO Rewind Enable*/
/* Flush the RX FIFO */
writel(RX_FIFO_FLUSH, ®->grstctl);
while (readl(®->grstctl) & RX_FIFO_FLUSH)
- DEBUG("%s: waiting for S3C_UDC_OTG_GRSTCTL\n", __func__);
+ debug("%s: waiting for S3C_UDC_OTG_GRSTCTL\n", __func__);
/* Flush all the Tx FIFO's */
writel(TX_FIFO_FLUSH_ALL, ®->grstctl);
writel(TX_FIFO_FLUSH_ALL | TX_FIFO_FLUSH, ®->grstctl);
while (readl(®->grstctl) & TX_FIFO_FLUSH)
- DEBUG("%s: waiting for S3C_UDC_OTG_GRSTCTL\n", __func__);
+ debug("%s: waiting for S3C_UDC_OTG_GRSTCTL\n", __func__);
/* 13. Clear NAK bit of EP0, EP1, EP2*/
/* For Slave mode*/
struct s3c_udc *dev;
unsigned long flags;
- DEBUG("%s: %p\n", __func__, _ep);
+ debug("%s: %p\n", __func__, _ep);
ep = container_of(_ep, struct s3c_ep, ep);
if (!_ep || !desc || ep->desc || _ep->name == ep0name
|| desc->bDescriptorType != USB_DT_ENDPOINT
|| ep->bEndpointAddress != desc->bEndpointAddress
- || ep_maxpacket(ep) < le16_to_cpu(desc->wMaxPacketSize)) {
+ || ep_maxpacket(ep) <
+ le16_to_cpu(get_unaligned(&desc->wMaxPacketSize))) {
- DEBUG("%s: bad ep or descriptor\n", __func__);
+ debug("%s: bad ep or descriptor\n", __func__);
return -EINVAL;
}
&& ep->bmAttributes != USB_ENDPOINT_XFER_BULK
&& desc->bmAttributes != USB_ENDPOINT_XFER_INT) {
- DEBUG("%s: %s type mismatch\n", __func__, _ep->name);
+ debug("%s: %s type mismatch\n", __func__, _ep->name);
return -EINVAL;
}
/* hardware _could_ do smaller, but driver doesn't */
if ((desc->bmAttributes == USB_ENDPOINT_XFER_BULK
- && le16_to_cpu(desc->wMaxPacketSize) != ep_maxpacket(ep))
- || !desc->wMaxPacketSize) {
+ && le16_to_cpu(get_unaligned(&desc->wMaxPacketSize)) !=
+ ep_maxpacket(ep)) || !get_unaligned(&desc->wMaxPacketSize)) {
- DEBUG("%s: bad %s maxpacket\n", __func__, _ep->name);
+ debug("%s: bad %s maxpacket\n", __func__, _ep->name);
return -ERANGE;
}
dev = ep->dev;
if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) {
- DEBUG("%s: bogus device state\n", __func__);
+ debug("%s: bogus device state\n", __func__);
return -ESHUTDOWN;
}
ep->stopped = 0;
ep->desc = desc;
ep->pio_irqs = 0;
- ep->ep.maxpacket = le16_to_cpu(desc->wMaxPacketSize);
+ ep->ep.maxpacket = le16_to_cpu(get_unaligned(&desc->wMaxPacketSize));
/* Reset halt state */
s3c_udc_set_nak(ep);
s3c_udc_ep_activate(ep);
spin_unlock_irqrestore(&ep->dev->lock, flags);
- DEBUG("%s: enabled %s, stopped = %d, maxpacket = %d\n",
+ debug("%s: enabled %s, stopped = %d, maxpacket = %d\n",
__func__, _ep->name, ep->stopped, ep->ep.maxpacket);
return 0;
}
struct s3c_ep *ep;
unsigned long flags;
- DEBUG("%s: %p\n", __func__, _ep);
+ debug("%s: %p\n", __func__, _ep);
ep = container_of(_ep, struct s3c_ep, ep);
if (!_ep || !ep->desc) {
- DEBUG("%s: %s not enabled\n", __func__,
+ debug("%s: %s not enabled\n", __func__,
_ep ? ep->ep.name : NULL);
return -EINVAL;
}
spin_unlock_irqrestore(&ep->dev->lock, flags);
- DEBUG("%s: disabled %s\n", __func__, _ep->name);
+ debug("%s: disabled %s\n", __func__, _ep->name);
return 0;
}
{
struct s3c_request *req;
- DEBUG("%s: %s %p\n", __func__, ep->name, ep);
+ debug("%s: %s %p\n", __func__, ep->name, ep);
- req = kmalloc(sizeof *req, gfp_flags);
+ req = memalign(CONFIG_SYS_CACHELINE_SIZE, sizeof(*req));
if (!req)
return 0;
{
struct s3c_request *req;
- DEBUG("%s: %p\n", __func__, ep);
+ debug("%s: %p\n", __func__, ep);
req = container_of(_req, struct s3c_request, req);
WARN_ON(!list_empty(&req->queue));
struct s3c_request *req;
unsigned long flags;
- DEBUG("%s: %p\n", __func__, _ep);
+ debug("%s: %p\n", __func__, _ep);
ep = container_of(_ep, struct s3c_ep, ep);
if (!_ep || ep->ep.name == ep0name)
ep = container_of(_ep, struct s3c_ep, ep);
if (!_ep) {
- DEBUG("%s: bad ep\n", __func__);
+ debug("%s: bad ep\n", __func__);
return -ENODEV;
}
- DEBUG("%s: %d\n", __func__, ep_index(ep));
+ debug("%s: %d\n", __func__, ep_index(ep));
/* LPD can't report unclaimed bytes from IN fifos */
if (ep_is_in(ep))
ep = container_of(_ep, struct s3c_ep, ep);
if (unlikely(!_ep || (!ep->desc && ep->ep.name != ep0name))) {
- DEBUG("%s: bad ep\n", __func__);
+ debug("%s: bad ep\n", __func__);
return;
}
- DEBUG("%s: %d\n", __func__, ep_index(ep));
+ debug("%s: %d\n", __func__, ep_index(ep));
}
static const struct usb_gadget_ops s3c_udc_ops = {
struct s3c_udc *dev = &memory;
int retval = 0, i;
- DEBUG("%s: %p\n", __func__, pdata);
+ debug("%s: %p\n", __func__, pdata);
dev->pdata = pdata;
the_controller = dev;
for (i = 0; i < S3C_MAX_ENDPOINTS+1; i++) {
- dev->dma_buf[i] = kmalloc(DMA_BUFFER_SIZE, GFP_KERNEL);
+ dev->dma_buf[i] = memalign(CONFIG_SYS_CACHELINE_SIZE,
+ DMA_BUFFER_SIZE);
dev->dma_addr[i] = (dma_addr_t) dev->dma_buf[i];
invalidate_dcache_range((unsigned long) dev->dma_buf[i],
(unsigned long) (dev->dma_buf[i]