diff options
Diffstat (limited to 'drivers/usb/c67x00')
| -rw-r--r-- | drivers/usb/c67x00/Makefile | 2 | ||||
| -rw-r--r-- | drivers/usb/c67x00/c67x00-drv.c | 28 | ||||
| -rw-r--r-- | drivers/usb/c67x00/c67x00-hcd.c | 3 | ||||
| -rw-r--r-- | drivers/usb/c67x00/c67x00-hcd.h | 4 | ||||
| -rw-r--r-- | drivers/usb/c67x00/c67x00-ll-hpi.c | 16 | ||||
| -rw-r--r-- | drivers/usb/c67x00/c67x00-sched.c | 41 |
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) { |
