aboutsummaryrefslogtreecommitdiff
path: root/drivers/usb/c67x00
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/c67x00')
-rw-r--r--drivers/usb/c67x00/Makefile2
-rw-r--r--drivers/usb/c67x00/c67x00-drv.c28
-rw-r--r--drivers/usb/c67x00/c67x00-hcd.c3
-rw-r--r--drivers/usb/c67x00/c67x00-hcd.h4
-rw-r--r--drivers/usb/c67x00/c67x00-ll-hpi.c16
-rw-r--r--drivers/usb/c67x00/c67x00-sched.c41
6 files changed, 42 insertions, 52 deletions
diff --git a/drivers/usb/c67x00/Makefile b/drivers/usb/c67x00/Makefile
index b1218683c8e..da5f314a5de 100644
--- a/drivers/usb/c67x00/Makefile
+++ b/drivers/usb/c67x00/Makefile
@@ -2,8 +2,6 @@
# Makefile for Cypress C67X00 USB Controller
#
-ccflags-$(CONFIG_USB_DEBUG) := -DDEBUG
-
obj-$(CONFIG_USB_C67X00_HCD) += c67x00.o
c67x00-y := c67x00-drv.o c67x00-ll-hpi.o c67x00-hcd.o c67x00-sched.o
diff --git a/drivers/usb/c67x00/c67x00-drv.c b/drivers/usb/c67x00/c67x00-drv.c
index b6d49234e52..8db3380c332 100644
--- a/drivers/usb/c67x00/c67x00-drv.c
+++ b/drivers/usb/c67x00/c67x00-drv.c
@@ -27,7 +27,7 @@
* the link between the common hardware parts and the subdrivers (e.g.
* interrupt handling).
*
- * The c67x00 has 2 SIE's (serial interface engine) wich can be configured
+ * The c67x00 has 2 SIE's (serial interface engine) which can be configured
* to be host, device or OTG (with some limitations, E.G. only SIE1 can be OTG).
*
* Depending on the platform configuration, the SIE's are created and
@@ -38,6 +38,7 @@
#include <linux/io.h>
#include <linux/list.h>
#include <linux/slab.h>
+#include <linux/module.h>
#include <linux/usb.h>
#include <linux/usb/c67x00.h>
@@ -115,7 +116,7 @@ static irqreturn_t c67x00_irq(int irq, void *__dev)
/* ------------------------------------------------------------------------- */
-static int __devinit c67x00_drv_probe(struct platform_device *pdev)
+static int c67x00_drv_probe(struct platform_device *pdev)
{
struct c67x00_device *c67x00;
struct c67x00_platform_data *pdata;
@@ -130,7 +131,7 @@ static int __devinit c67x00_drv_probe(struct platform_device *pdev)
if (!res2)
return -ENODEV;
- pdata = pdev->dev.platform_data;
+ pdata = dev_get_platdata(&pdev->dev);
if (!pdata)
return -ENODEV;
@@ -153,7 +154,7 @@ static int __devinit c67x00_drv_probe(struct platform_device *pdev)
spin_lock_init(&c67x00->hpi.lock);
c67x00->hpi.regstep = pdata->hpi_regstep;
- c67x00->pdata = pdev->dev.platform_data;
+ c67x00->pdata = dev_get_platdata(&pdev->dev);
c67x00->pdev = pdev;
c67x00_ll_init(c67x00);
@@ -190,7 +191,7 @@ static int __devinit c67x00_drv_probe(struct platform_device *pdev)
return ret;
}
-static int __devexit c67x00_drv_remove(struct platform_device *pdev)
+static int c67x00_drv_remove(struct platform_device *pdev)
{
struct c67x00_device *c67x00 = platform_get_drvdata(pdev);
struct resource *res;
@@ -218,27 +219,16 @@ static int __devexit c67x00_drv_remove(struct platform_device *pdev)
static struct platform_driver c67x00_driver = {
.probe = c67x00_drv_probe,
- .remove = __devexit_p(c67x00_drv_remove),
+ .remove = c67x00_drv_remove,
.driver = {
.owner = THIS_MODULE,
.name = "c67x00",
},
};
-MODULE_ALIAS("platform:c67x00");
-
-static int __init c67x00_init(void)
-{
- return platform_driver_register(&c67x00_driver);
-}
-static void __exit c67x00_exit(void)
-{
- platform_driver_unregister(&c67x00_driver);
-}
-
-module_init(c67x00_init);
-module_exit(c67x00_exit);
+module_platform_driver(c67x00_driver);
MODULE_AUTHOR("Peter Korsgaard, Jan Veldeman, Grant Likely");
MODULE_DESCRIPTION("Cypress C67X00 USB Controller Driver");
MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:c67x00");
diff --git a/drivers/usb/c67x00/c67x00-hcd.c b/drivers/usb/c67x00/c67x00-hcd.c
index d3e1356d091..20ec4eee1ac 100644
--- a/drivers/usb/c67x00/c67x00-hcd.c
+++ b/drivers/usb/c67x00/c67x00-hcd.c
@@ -271,7 +271,6 @@ static void c67x00_hcd_irq(struct c67x00_sie *sie, u16 int_status, u16 msg)
if (int_status & SOFEOP_FLG(sie->sie_num)) {
c67x00_ll_usb_clear_status(sie, SOF_EOP_IRQ_FLG);
c67x00_sched_kick(c67x00);
- set_bit(HCD_FLAG_SAW_IRQ, &hcd->flags);
}
}
@@ -385,6 +384,8 @@ int c67x00_hcd_probe(struct c67x00_sie *sie)
goto err2;
}
+ device_wakeup_enable(hcd->self.controller);
+
spin_lock_irqsave(&sie->lock, flags);
sie->private_data = c67x00;
sie->irq = c67x00_hcd_irq;
diff --git a/drivers/usb/c67x00/c67x00-hcd.h b/drivers/usb/c67x00/c67x00-hcd.h
index 74e44621e31..cf8a455a640 100644
--- a/drivers/usb/c67x00/c67x00-hcd.h
+++ b/drivers/usb/c67x00/c67x00-hcd.h
@@ -34,7 +34,7 @@
/*
* The following parameters depend on the CPU speed, bus speed, ...
* These can be tuned for specific use cases, e.g. if isochronous transfers
- * are very important, bandwith can be sacrificed to guarantee that the
+ * are very important, bandwidth can be sacrificed to guarantee that the
* 1ms deadline will be met.
* If bulk transfers are important, the MAX_FRAME_BW can be increased,
* but some (or many) isochronous deadlines might not be met.
@@ -45,7 +45,7 @@
/*
* The current implementation switches between _STD (default) and _ISO (when
* isochronous transfers are scheduled), in order to optimize the throughput
- * in normal cicrumstances, but also provide good isochronous behaviour.
+ * in normal circumstances, but also provide good isochronous behaviour.
*
* Bandwidth is described in bit time so with a 12MHz USB clock and 1ms
* frames; there are 12000 bit times per frame.
diff --git a/drivers/usb/c67x00/c67x00-ll-hpi.c b/drivers/usb/c67x00/c67x00-ll-hpi.c
index a9636f43bca..b58151841e1 100644
--- a/drivers/usb/c67x00/c67x00-ll-hpi.c
+++ b/drivers/usb/c67x00/c67x00-ll-hpi.c
@@ -22,6 +22,7 @@
*/
#include <asm/byteorder.h>
+#include <linux/delay.h>
#include <linux/io.h>
#include <linux/jiffies.h>
#include <linux/usb/c67x00.h>
@@ -62,8 +63,8 @@ struct c67x00_lcp_int_data {
* HPI implementation
*
* The c67x00 chip also support control via SPI or HSS serial
- * interfaces. However, this driver assumes that register access can
- * be performed from IRQ context. While this is a safe assuption with
+ * interfaces. However, this driver assumes that register access can
+ * be performed from IRQ context. While this is a safe assumption with
* the HPI interface, it is not true for the serial interfaces.
*/
@@ -73,13 +74,22 @@ struct c67x00_lcp_int_data {
#define HPI_ADDR 2
#define HPI_STATUS 3
+/*
+ * According to CY7C67300 specification (tables 140 and 141) HPI read and
+ * write cycle duration Tcyc must be at least 6T long, where T is 1/48MHz,
+ * which is 125ns.
+ */
+#define HPI_T_CYC_NS 125
+
static inline u16 hpi_read_reg(struct c67x00_device *dev, int reg)
{
+ ndelay(HPI_T_CYC_NS);
return __raw_readw(dev->hpi.base + reg * dev->hpi.regstep);
}
static inline void hpi_write_reg(struct c67x00_device *dev, int reg, u16 value)
{
+ ndelay(HPI_T_CYC_NS);
__raw_writew(value, dev->hpi.base + reg * dev->hpi.regstep);
}
@@ -237,7 +247,7 @@ void c67x00_ll_hpi_disable_sofeop(struct c67x00_sie *sie)
/* -------------------------------------------------------------------------- */
/* Transactions */
-static inline u16 ll_recv_msg(struct c67x00_device *dev)
+static inline int ll_recv_msg(struct c67x00_device *dev)
{
u16 res;
diff --git a/drivers/usb/c67x00/c67x00-sched.c b/drivers/usb/c67x00/c67x00-sched.c
index f6b3c253f3f..7311ed61e99 100644
--- a/drivers/usb/c67x00/c67x00-sched.c
+++ b/drivers/usb/c67x00/c67x00-sched.c
@@ -100,7 +100,7 @@ struct c67x00_urb_priv {
#define TD_PIDEP_OFFSET 0x04
#define TD_PIDEPMASK_PID 0xF0
#define TD_PIDEPMASK_EP 0x0F
-#define TD_PORTLENMASK_DL 0x02FF
+#define TD_PORTLENMASK_DL 0x03FF
#define TD_PORTLENMASK_PN 0xC000
#define TD_STATUS_OFFSET 0x07
@@ -144,8 +144,6 @@ struct c67x00_urb_priv {
/* -------------------------------------------------------------------------- */
-#ifdef DEBUG
-
/**
* dbg_td - Dump the contents of the TD
*/
@@ -166,16 +164,8 @@ static void dbg_td(struct c67x00_hcd *c67x00, struct c67x00_td *td, char *msg)
dev_dbg(dev, "retry_cnt: 0x%02x\n", td->retry_cnt);
dev_dbg(dev, "residue: 0x%02x\n", td->residue);
dev_dbg(dev, "next_td_addr: 0x%04x\n", td_next_td_addr(td));
- dev_dbg(dev, "data:");
- print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 16, 1,
- td->data, td_length(td), 1);
+ dev_dbg(dev, "data: %*ph\n", td_length(td), td->data);
}
-#else /* DEBUG */
-
-static inline void
-dbg_td(struct c67x00_hcd *c67x00, struct c67x00_td *td, char *msg) { }
-
-#endif /* DEBUG */
/* -------------------------------------------------------------------------- */
/* Helper functions */
@@ -344,7 +334,7 @@ void c67x00_endpoint_disable(struct usb_hcd *hcd, struct usb_host_endpoint *ep)
/* it could happen that we reinitialize this completion, while
* somebody was waiting for that completion. The timeout and
* while loop handle such cases, but this might be improved */
- INIT_COMPLETION(c67x00->endpoint_disable);
+ reinit_completion(&c67x00->endpoint_disable);
c67x00_sched_kick(c67x00);
wait_for_completion_timeout(&c67x00->endpoint_disable, 1 * HZ);
@@ -372,6 +362,13 @@ int c67x00_urb_enqueue(struct usb_hcd *hcd,
struct c67x00_hcd *c67x00 = hcd_to_c67x00_hcd(hcd);
int port = get_root_port(urb->dev)-1;
+ /* Allocate and initialize urb private data */
+ urbp = kzalloc(sizeof(*urbp), mem_flags);
+ if (!urbp) {
+ ret = -ENOMEM;
+ goto err_urbp;
+ }
+
spin_lock_irqsave(&c67x00->lock, flags);
/* Make sure host controller is running */
@@ -384,13 +381,6 @@ int c67x00_urb_enqueue(struct usb_hcd *hcd,
if (ret)
goto err_not_linked;
- /* Allocate and initialize urb private data */
- urbp = kzalloc(sizeof(*urbp), mem_flags);
- if (!urbp) {
- ret = -ENOMEM;
- goto err_urbp;
- }
-
INIT_LIST_HEAD(&urbp->hep_node);
urbp->urb = urb;
urbp->port = port;
@@ -453,11 +443,11 @@ int c67x00_urb_enqueue(struct usb_hcd *hcd,
return 0;
err_epdata:
- kfree(urbp);
-err_urbp:
usb_hcd_unlink_urb_from_ep(hcd, urb);
err_not_linked:
spin_unlock_irqrestore(&c67x00->lock, flags);
+ kfree(urbp);
+err_urbp:
return ret;
}
@@ -590,7 +580,7 @@ static int c67x00_create_td(struct c67x00_hcd *c67x00, struct urb *urb,
{
struct c67x00_td *td;
struct c67x00_urb_priv *urbp = urb->hcpriv;
- const __u8 active_flag = 1, retry_cnt = 1;
+ const __u8 active_flag = 1, retry_cnt = 3;
__u8 cmd = 0;
int tt = 0;
@@ -780,7 +770,8 @@ static int c67x00_add_iso_urb(struct c67x00_hcd *c67x00, struct urb *urb)
ret = c67x00_create_td(c67x00, urb, td_buf, len, pid, 0,
urbp->cnt);
if (ret) {
- printk(KERN_DEBUG "create failed: %d\n", ret);
+ dev_dbg(c67x00_hcd_dev(c67x00), "create failed: %d\n",
+ ret);
urb->iso_frame_desc[urbp->cnt].actual_length = 0;
urb->iso_frame_desc[urbp->cnt].status = ret;
if (urbp->cnt + 1 == urb->number_of_packets)
@@ -907,7 +898,7 @@ static inline int c67x00_end_of_data(struct c67x00_td *td)
/* Remove all td's from the list which come
* after last_td and are meant for the same pipe.
- * This is used when a short packet has occured */
+ * This is used when a short packet has occurred */
static inline void c67x00_clear_pipe(struct c67x00_hcd *c67x00,
struct c67x00_td *last_td)
{