Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[PATCH] USB: isp116x-hcd: cleanup

The attached patch makes a cleanup of isp116x-hcd. Most of the volume of
the patch comes from 2 sources: moving the code around to get rid of a
few function prototypes and reworking register dumping functions/macros.
Among other things, switched over from using procfs to debugfs.

Cleanup. The following changes were made:

- Rework register dumping code so it can be used for dumping
to both syslog and debugfs.
- Switch from procfs to debugfs..
- Die gracefully on Unrecoverable Error interrupt.
- Fix memory leak in isp116x_urb_enqueue(), if HC happens to
die in a narrow time window.
- Fix a 'sparce' warning (unnecessary cast).
- Report Devices Removable for root hub ports by default
(was Devices Permanently Attached).
- Move bus suspend/resume functions down in code to get rid of
a few function prototypes.
- A number of one-line cleanups.
- Add an entry to MAINTAINERS.

Signed-off-by: Olav Kongas <ok@artecdesign.ee>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

MAINTAINERS | 6
drivers/usb/host/isp116x-hcd.c | 429 ++++++++++++++++-------------------------
drivers/usb/host/isp116x.h | 83 +++++--
3 files changed, 230 insertions(+), 288 deletions(-)

authored by

Olav Kongas and committed by
Greg Kroah-Hartman
959eea21 535488fc

+230 -288
+6
MAINTAINERS
··· 2640 2640 L: linux-usb-devel@lists.sourceforge.net 2641 2641 S: Maintained 2642 2642 2643 + USB ISP116X DRIVER 2644 + P: Olav Kongas 2645 + M: ok@artecdesign.ee 2646 + L: linux-usb-devel@lists.sourceforge.net 2647 + S: Maintained 2648 + 2643 2649 USB KAWASAKI LSI DRIVER 2644 2650 P: Oliver Neukum 2645 2651 M: oliver@neukum.name
+170 -259
drivers/usb/host/isp116x-hcd.c
··· 55 55 /* enqueuing/finishing log of urbs */ 56 56 //#define URB_TRACE 57 57 58 - #include <linux/config.h> 59 58 #include <linux/module.h> 60 - #include <linux/moduleparam.h> 61 - #include <linux/kernel.h> 62 59 #include <linux/delay.h> 63 - #include <linux/ioport.h> 64 - #include <linux/sched.h> 65 - #include <linux/slab.h> 66 - #include <linux/smp_lock.h> 60 + #include <linux/debugfs.h> 61 + #include <linux/seq_file.h> 67 62 #include <linux/errno.h> 68 63 #include <linux/init.h> 69 64 #include <linux/list.h> 70 - #include <linux/interrupt.h> 71 65 #include <linux/usb.h> 72 66 #include <linux/usb_isp116x.h> 73 67 #include <linux/platform_device.h> ··· 71 77 #include <asm/system.h> 72 78 #include <asm/byteorder.h> 73 79 74 - #ifndef DEBUG 75 - # define STUB_DEBUG_FILE 76 - #endif 77 - 78 80 #include "../core/hcd.h" 79 81 #include "isp116x.h" 80 82 81 - #define DRIVER_VERSION "05 Aug 2005" 83 + #define DRIVER_VERSION "03 Nov 2005" 82 84 #define DRIVER_DESC "ISP116x USB Host Controller Driver" 83 85 84 86 MODULE_DESCRIPTION(DRIVER_DESC); ··· 295 305 udev = urb->dev; 296 306 ptd = &ep->ptd; 297 307 cc = PTD_GET_CC(ptd); 298 - 299 - spin_lock(&urb->lock); 300 308 short_not_ok = 1; 309 + spin_lock(&urb->lock); 301 310 302 311 /* Data underrun is special. For allowed underrun 303 312 we clear the error and continue as normal. For ··· 409 420 ep->nextpid = 0; 410 421 break; 411 422 default: 412 - BUG_ON(1); 423 + BUG(); 413 424 } 414 425 spin_unlock(&urb->lock); 415 426 } ··· 617 628 u32 intstat = isp116x_read_reg32(isp116x, HCINTSTAT); 618 629 isp116x_write_reg32(isp116x, HCINTSTAT, intstat); 619 630 if (intstat & HCINT_UE) { 620 - ERR("Unrecoverable error\n"); 621 - /* What should we do here? Reset? */ 631 + ERR("Unrecoverable error, HC is dead!\n"); 632 + /* IRQ's are off, we do no DMA, 633 + perfectly ready to die ... */ 634 + hcd->state = HC_STATE_HALT; 635 + ret = IRQ_HANDLED; 636 + goto done; 622 637 } 623 638 if (intstat & HCINT_RHSC) 624 639 /* When root hub or any of its ports is going ··· 633 640 if (intstat & HCINT_RD) { 634 641 DBG("---- remote wakeup\n"); 635 642 usb_hcd_resume_root_hub(hcd); 636 - ret = IRQ_HANDLED; 637 643 } 638 644 irqstat &= ~HCuPINT_OPR; 639 645 ret = IRQ_HANDLED; ··· 643 651 } 644 652 645 653 isp116x_write_reg16(isp116x, HCuPINTENB, isp116x->irqenb); 654 + done: 646 655 spin_unlock(&isp116x->lock); 647 656 return ret; 648 657 } ··· 717 724 718 725 spin_lock_irqsave(&isp116x->lock, flags); 719 726 if (!HC_IS_RUNNING(hcd->state)) { 727 + kfree(ep); 720 728 ret = -ENODEV; 721 729 goto fail; 722 730 } ··· 882 888 struct usb_host_endpoint *hep) 883 889 { 884 890 int i; 885 - struct isp116x_ep *ep = hep->hcpriv;; 891 + struct isp116x_ep *ep = hep->hcpriv; 886 892 887 893 if (!ep) 888 894 return; ··· 909 915 spin_unlock_irqrestore(&isp116x->lock, flags); 910 916 return (int)fmnum; 911 917 } 912 - 913 - /*----------------------------------------------------------------*/ 914 918 915 919 /* 916 920 Adapted from ohci-hub.c. Currently we don't support autosuspend. ··· 960 968 desc->bHubContrCurrent = 0; 961 969 desc->bNbrPorts = (u8) (reg & 0x3); 962 970 /* Power switching, device type, overcurrent. */ 963 - desc->wHubCharacteristics = 964 - (__force __u16) cpu_to_le16((u16) ((reg >> 8) & 0x1f)); 971 + desc->wHubCharacteristics = cpu_to_le16((u16) ((reg >> 8) & 0x1f)); 965 972 desc->bPwrOn2PwrGood = (u8) ((reg >> 24) & 0xff); 966 973 /* two bitmaps: ports removable, and legacy PortPwrCtrlMask */ 967 - desc->bitmap[0] = desc->bNbrPorts == 1 ? 1 << 1 : 3 << 1; 974 + desc->bitmap[0] = 0; 968 975 desc->bitmap[1] = ~0; 969 976 } 970 977 ··· 1150 1159 return ret; 1151 1160 } 1152 1161 1153 - #ifdef CONFIG_PM 1154 - 1155 - static int isp116x_bus_suspend(struct usb_hcd *hcd) 1156 - { 1157 - struct isp116x *isp116x = hcd_to_isp116x(hcd); 1158 - unsigned long flags; 1159 - u32 val; 1160 - int ret = 0; 1161 - 1162 - spin_lock_irqsave(&isp116x->lock, flags); 1163 - 1164 - val = isp116x_read_reg32(isp116x, HCCONTROL); 1165 - switch (val & HCCONTROL_HCFS) { 1166 - case HCCONTROL_USB_OPER: 1167 - hcd->state = HC_STATE_QUIESCING; 1168 - val &= (~HCCONTROL_HCFS & ~HCCONTROL_RWE); 1169 - val |= HCCONTROL_USB_SUSPEND; 1170 - if (hcd->remote_wakeup) 1171 - val |= HCCONTROL_RWE; 1172 - /* Wait for usb transfers to finish */ 1173 - mdelay(2); 1174 - isp116x_write_reg32(isp116x, HCCONTROL, val); 1175 - hcd->state = HC_STATE_SUSPENDED; 1176 - /* Wait for devices to suspend */ 1177 - mdelay(5); 1178 - case HCCONTROL_USB_SUSPEND: 1179 - break; 1180 - case HCCONTROL_USB_RESUME: 1181 - isp116x_write_reg32(isp116x, HCCONTROL, 1182 - (val & ~HCCONTROL_HCFS) | 1183 - HCCONTROL_USB_RESET); 1184 - case HCCONTROL_USB_RESET: 1185 - ret = -EBUSY; 1186 - break; 1187 - default: 1188 - ret = -EINVAL; 1189 - } 1190 - 1191 - spin_unlock_irqrestore(&isp116x->lock, flags); 1192 - return ret; 1193 - } 1194 - 1195 - /* Get rid of these declarations later in cleanup */ 1196 - static int isp116x_reset(struct usb_hcd *hcd); 1197 - static int isp116x_start(struct usb_hcd *hcd); 1198 - 1199 - static int isp116x_bus_resume(struct usb_hcd *hcd) 1200 - { 1201 - struct isp116x *isp116x = hcd_to_isp116x(hcd); 1202 - u32 val; 1203 - 1204 - msleep(5); 1205 - spin_lock_irq(&isp116x->lock); 1206 - 1207 - val = isp116x_read_reg32(isp116x, HCCONTROL); 1208 - switch (val & HCCONTROL_HCFS) { 1209 - case HCCONTROL_USB_SUSPEND: 1210 - val &= ~HCCONTROL_HCFS; 1211 - val |= HCCONTROL_USB_RESUME; 1212 - isp116x_write_reg32(isp116x, HCCONTROL, val); 1213 - case HCCONTROL_USB_RESUME: 1214 - break; 1215 - case HCCONTROL_USB_OPER: 1216 - spin_unlock_irq(&isp116x->lock); 1217 - /* Without setting power_state here the 1218 - SUSPENDED state won't be removed from 1219 - sysfs/usbN/power.state as a response to remote 1220 - wakeup. Maybe in the future. */ 1221 - hcd->self.root_hub->dev.power.power_state = PMSG_ON; 1222 - return 0; 1223 - default: 1224 - /* HCCONTROL_USB_RESET: this may happen, when during 1225 - suspension the HC lost power. Reinitialize completely */ 1226 - spin_unlock_irq(&isp116x->lock); 1227 - DBG("Chip has been reset while suspended. Reinit from scratch.\n"); 1228 - isp116x_reset(hcd); 1229 - isp116x_start(hcd); 1230 - isp116x_hub_control(hcd, SetPortFeature, 1231 - USB_PORT_FEAT_POWER, 1, NULL, 0); 1232 - if ((isp116x->rhdesca & RH_A_NDP) == 2) 1233 - isp116x_hub_control(hcd, SetPortFeature, 1234 - USB_PORT_FEAT_POWER, 2, NULL, 0); 1235 - hcd->self.root_hub->dev.power.power_state = PMSG_ON; 1236 - return 0; 1237 - } 1238 - 1239 - val = isp116x->rhdesca & RH_A_NDP; 1240 - while (val--) { 1241 - u32 stat = 1242 - isp116x_read_reg32(isp116x, val ? HCRHPORT2 : HCRHPORT1); 1243 - /* force global, not selective, resume */ 1244 - if (!(stat & RH_PS_PSS)) 1245 - continue; 1246 - DBG("%s: Resuming port %d\n", __func__, val); 1247 - isp116x_write_reg32(isp116x, RH_PS_POCI, val 1248 - ? HCRHPORT2 : HCRHPORT1); 1249 - } 1250 - spin_unlock_irq(&isp116x->lock); 1251 - 1252 - hcd->state = HC_STATE_RESUMING; 1253 - mdelay(20); 1254 - 1255 - /* Go operational */ 1256 - spin_lock_irq(&isp116x->lock); 1257 - val = isp116x_read_reg32(isp116x, HCCONTROL); 1258 - isp116x_write_reg32(isp116x, HCCONTROL, 1259 - (val & ~HCCONTROL_HCFS) | HCCONTROL_USB_OPER); 1260 - spin_unlock_irq(&isp116x->lock); 1261 - /* see analogous comment above */ 1262 - hcd->self.root_hub->dev.power.power_state = PMSG_ON; 1263 - hcd->state = HC_STATE_RUNNING; 1264 - 1265 - return 0; 1266 - } 1267 - 1268 - 1269 - #else 1270 - 1271 - #define isp116x_bus_suspend NULL 1272 - #define isp116x_bus_resume NULL 1273 - 1274 - #endif 1275 - 1276 1162 /*-----------------------------------------------------------------*/ 1277 1163 1278 - #ifdef STUB_DEBUG_FILE 1279 - 1280 - static inline void create_debug_file(struct isp116x *isp116x) 1281 - { 1282 - } 1283 - 1284 - static inline void remove_debug_file(struct isp116x *isp116x) 1285 - { 1286 - } 1287 - 1288 - #else 1289 - 1290 - #include <linux/proc_fs.h> 1291 - #include <linux/seq_file.h> 1164 + #ifdef CONFIG_DEBUG_FS 1292 1165 1293 1166 static void dump_irq(struct seq_file *s, char *label, u16 mask) 1294 1167 { ··· 1176 1321 mask & HCINT_SF ? " sof" : "", mask & HCINT_SO ? " so" : ""); 1177 1322 } 1178 1323 1179 - static int proc_isp116x_show(struct seq_file *s, void *unused) 1324 + static int isp116x_show_dbg(struct seq_file *s, void *unused) 1180 1325 { 1181 1326 struct isp116x *isp116x = s->private; 1182 - struct isp116x_ep *ep; 1183 - struct urb *urb; 1184 - unsigned i; 1185 - char *str; 1186 1327 1187 1328 seq_printf(s, "%s\n%s version %s\n", 1188 1329 isp116x_to_hcd(isp116x)->product_desc, hcd_name, ··· 1194 1343 } 1195 1344 1196 1345 spin_lock_irq(&isp116x->lock); 1197 - 1198 1346 dump_irq(s, "hc_irq_enable", isp116x_read_reg16(isp116x, HCuPINTENB)); 1199 1347 dump_irq(s, "hc_irq_status", isp116x_read_reg16(isp116x, HCuPINT)); 1200 1348 dump_int(s, "hc_int_enable", isp116x_read_reg32(isp116x, HCINTENB)); 1201 1349 dump_int(s, "hc_int_status", isp116x_read_reg32(isp116x, HCINTSTAT)); 1202 - 1203 - list_for_each_entry(ep, &isp116x->async, schedule) { 1204 - 1205 - switch (ep->nextpid) { 1206 - case USB_PID_IN: 1207 - str = "in"; 1208 - break; 1209 - case USB_PID_OUT: 1210 - str = "out"; 1211 - break; 1212 - case USB_PID_SETUP: 1213 - str = "setup"; 1214 - break; 1215 - case USB_PID_ACK: 1216 - str = "status"; 1217 - break; 1218 - default: 1219 - str = "?"; 1220 - break; 1221 - }; 1222 - seq_printf(s, "%p, ep%d%s, maxpacket %d:\n", ep, 1223 - ep->epnum, str, ep->maxpacket); 1224 - list_for_each_entry(urb, &ep->hep->urb_list, urb_list) { 1225 - seq_printf(s, " urb%p, %d/%d\n", urb, 1226 - urb->actual_length, 1227 - urb->transfer_buffer_length); 1228 - } 1229 - } 1230 - if (!list_empty(&isp116x->async)) 1231 - seq_printf(s, "\n"); 1232 - 1233 - seq_printf(s, "periodic size= %d\n", PERIODIC_SIZE); 1234 - 1235 - for (i = 0; i < PERIODIC_SIZE; i++) { 1236 - ep = isp116x->periodic[i]; 1237 - if (!ep) 1238 - continue; 1239 - seq_printf(s, "%2d [%3d]:\n", i, isp116x->load[i]); 1240 - 1241 - /* DUMB: prints shared entries multiple times */ 1242 - do { 1243 - seq_printf(s, " %d/%p (%sdev%d ep%d%s max %d)\n", 1244 - ep->period, ep, 1245 - (ep->udev->speed == 1246 - USB_SPEED_FULL) ? "" : "ls ", 1247 - ep->udev->devnum, ep->epnum, 1248 - (ep->epnum == 1249 - 0) ? "" : ((ep->nextpid == 1250 - USB_PID_IN) ? "in" : "out"), 1251 - ep->maxpacket); 1252 - ep = ep->next; 1253 - } while (ep); 1254 - } 1350 + isp116x_show_regs_seq(isp116x, s); 1255 1351 spin_unlock_irq(&isp116x->lock); 1256 1352 seq_printf(s, "\n"); 1257 1353 1258 1354 return 0; 1259 1355 } 1260 1356 1261 - static int proc_isp116x_open(struct inode *inode, struct file *file) 1357 + static int isp116x_open_seq(struct inode *inode, struct file *file) 1262 1358 { 1263 - return single_open(file, proc_isp116x_show, PDE(inode)->data); 1359 + return single_open(file, isp116x_show_dbg, inode->u.generic_ip); 1264 1360 } 1265 1361 1266 - static struct file_operations proc_ops = { 1267 - .open = proc_isp116x_open, 1362 + static struct file_operations isp116x_debug_fops = { 1363 + .open = isp116x_open_seq, 1268 1364 .read = seq_read, 1269 1365 .llseek = seq_lseek, 1270 1366 .release = single_release, 1271 1367 }; 1272 1368 1273 - /* expect just one isp116x per system */ 1274 - static const char proc_filename[] = "driver/isp116x"; 1275 - 1276 - static void create_debug_file(struct isp116x *isp116x) 1369 + static int create_debug_file(struct isp116x *isp116x) 1277 1370 { 1278 - struct proc_dir_entry *pde; 1279 - 1280 - pde = create_proc_entry(proc_filename, 0, NULL); 1281 - if (pde == NULL) 1282 - return; 1283 - 1284 - pde->proc_fops = &proc_ops; 1285 - pde->data = isp116x; 1286 - isp116x->pde = pde; 1371 + isp116x->dentry = debugfs_create_file(hcd_name, 1372 + S_IRUGO, NULL, isp116x, 1373 + &isp116x_debug_fops); 1374 + if (!isp116x->dentry) 1375 + return -ENOMEM; 1376 + return 0; 1287 1377 } 1288 1378 1289 1379 static void remove_debug_file(struct isp116x *isp116x) 1290 1380 { 1291 - if (isp116x->pde) 1292 - remove_proc_entry(proc_filename, NULL); 1381 + debugfs_remove(isp116x->dentry); 1293 1382 } 1294 1383 1295 - #endif 1384 + #else 1385 + 1386 + #define create_debug_file(d) 0 1387 + #define remove_debug_file(d) do{}while(0) 1388 + 1389 + #endif /* CONFIG_DEBUG_FS */ 1296 1390 1297 1391 /*-----------------------------------------------------------------*/ 1298 1392 ··· 1272 1476 struct isp116x *isp116x = hcd_to_isp116x(hcd); 1273 1477 unsigned long t; 1274 1478 u16 clkrdy = 0; 1275 - int ret = 0, timeout = 15 /* ms */ ; 1479 + int ret, timeout = 15 /* ms */ ; 1276 1480 1277 1481 ret = isp116x_sw_reset(isp116x); 1278 1482 if (ret) ··· 1288 1492 break; 1289 1493 } 1290 1494 if (!clkrdy) { 1291 - ERR("Clock not ready after 20ms\n"); 1495 + ERR("Clock not ready after %dms\n", timeout); 1292 1496 /* After sw_reset the clock won't report to be ready, if 1293 1497 H_WAKEUP pin is high. */ 1294 1498 ERR("Please make sure that the H_WAKEUP pin is pulled low!\n"); ··· 1406 1610 isp116x_write_reg32(isp116x, HCRHPORT1, RH_PS_CCS); 1407 1611 isp116x_write_reg32(isp116x, HCRHPORT2, RH_PS_CCS); 1408 1612 1409 - isp116x_show_regs(isp116x); 1613 + isp116x_show_regs_log(isp116x); 1410 1614 spin_unlock_irqrestore(&isp116x->lock, flags); 1411 1615 return 0; 1412 1616 } 1413 1617 1414 - /*-----------------------------------------------------------------*/ 1618 + #ifdef CONFIG_PM 1619 + 1620 + static int isp116x_bus_suspend(struct usb_hcd *hcd) 1621 + { 1622 + struct isp116x *isp116x = hcd_to_isp116x(hcd); 1623 + unsigned long flags; 1624 + u32 val; 1625 + int ret = 0; 1626 + 1627 + spin_lock_irqsave(&isp116x->lock, flags); 1628 + 1629 + val = isp116x_read_reg32(isp116x, HCCONTROL); 1630 + switch (val & HCCONTROL_HCFS) { 1631 + case HCCONTROL_USB_OPER: 1632 + hcd->state = HC_STATE_QUIESCING; 1633 + val &= (~HCCONTROL_HCFS & ~HCCONTROL_RWE); 1634 + val |= HCCONTROL_USB_SUSPEND; 1635 + if (hcd->remote_wakeup) 1636 + val |= HCCONTROL_RWE; 1637 + /* Wait for usb transfers to finish */ 1638 + mdelay(2); 1639 + isp116x_write_reg32(isp116x, HCCONTROL, val); 1640 + hcd->state = HC_STATE_SUSPENDED; 1641 + /* Wait for devices to suspend */ 1642 + mdelay(5); 1643 + case HCCONTROL_USB_SUSPEND: 1644 + break; 1645 + case HCCONTROL_USB_RESUME: 1646 + isp116x_write_reg32(isp116x, HCCONTROL, 1647 + (val & ~HCCONTROL_HCFS) | 1648 + HCCONTROL_USB_RESET); 1649 + case HCCONTROL_USB_RESET: 1650 + ret = -EBUSY; 1651 + break; 1652 + default: 1653 + ret = -EINVAL; 1654 + } 1655 + 1656 + spin_unlock_irqrestore(&isp116x->lock, flags); 1657 + return ret; 1658 + } 1659 + 1660 + static int isp116x_bus_resume(struct usb_hcd *hcd) 1661 + { 1662 + struct isp116x *isp116x = hcd_to_isp116x(hcd); 1663 + u32 val; 1664 + 1665 + msleep(5); 1666 + spin_lock_irq(&isp116x->lock); 1667 + 1668 + val = isp116x_read_reg32(isp116x, HCCONTROL); 1669 + switch (val & HCCONTROL_HCFS) { 1670 + case HCCONTROL_USB_SUSPEND: 1671 + val &= ~HCCONTROL_HCFS; 1672 + val |= HCCONTROL_USB_RESUME; 1673 + isp116x_write_reg32(isp116x, HCCONTROL, val); 1674 + case HCCONTROL_USB_RESUME: 1675 + break; 1676 + case HCCONTROL_USB_OPER: 1677 + spin_unlock_irq(&isp116x->lock); 1678 + /* Without setting power_state here the 1679 + SUSPENDED state won't be removed from 1680 + sysfs/usbN/power.state as a response to remote 1681 + wakeup. Maybe in the future. */ 1682 + hcd->self.root_hub->dev.power.power_state = PMSG_ON; 1683 + return 0; 1684 + default: 1685 + /* HCCONTROL_USB_RESET: this may happen, when during 1686 + suspension the HC lost power. Reinitialize completely */ 1687 + spin_unlock_irq(&isp116x->lock); 1688 + DBG("Chip has been reset while suspended. Reinit from scratch.\n"); 1689 + isp116x_reset(hcd); 1690 + isp116x_start(hcd); 1691 + isp116x_hub_control(hcd, SetPortFeature, 1692 + USB_PORT_FEAT_POWER, 1, NULL, 0); 1693 + if ((isp116x->rhdesca & RH_A_NDP) == 2) 1694 + isp116x_hub_control(hcd, SetPortFeature, 1695 + USB_PORT_FEAT_POWER, 2, NULL, 0); 1696 + hcd->self.root_hub->dev.power.power_state = PMSG_ON; 1697 + return 0; 1698 + } 1699 + 1700 + val = isp116x->rhdesca & RH_A_NDP; 1701 + while (val--) { 1702 + u32 stat = 1703 + isp116x_read_reg32(isp116x, val ? HCRHPORT2 : HCRHPORT1); 1704 + /* force global, not selective, resume */ 1705 + if (!(stat & RH_PS_PSS)) 1706 + continue; 1707 + DBG("%s: Resuming port %d\n", __func__, val); 1708 + isp116x_write_reg32(isp116x, RH_PS_POCI, val 1709 + ? HCRHPORT2 : HCRHPORT1); 1710 + } 1711 + spin_unlock_irq(&isp116x->lock); 1712 + 1713 + hcd->state = HC_STATE_RESUMING; 1714 + msleep(20); 1715 + 1716 + /* Go operational */ 1717 + spin_lock_irq(&isp116x->lock); 1718 + val = isp116x_read_reg32(isp116x, HCCONTROL); 1719 + isp116x_write_reg32(isp116x, HCCONTROL, 1720 + (val & ~HCCONTROL_HCFS) | HCCONTROL_USB_OPER); 1721 + spin_unlock_irq(&isp116x->lock); 1722 + /* see analogous comment above */ 1723 + hcd->self.root_hub->dev.power.power_state = PMSG_ON; 1724 + hcd->state = HC_STATE_RUNNING; 1725 + 1726 + return 0; 1727 + } 1728 + 1729 + #else 1730 + 1731 + #define isp116x_bus_suspend NULL 1732 + #define isp116x_bus_resume NULL 1733 + 1734 + #endif 1415 1735 1416 1736 static struct hc_driver isp116x_hc_driver = { 1417 1737 .description = hcd_name, ··· 1657 1745 } 1658 1746 1659 1747 ret = usb_add_hcd(hcd, irq, SA_INTERRUPT); 1660 - if (ret != 0) 1748 + if (ret) 1661 1749 goto err6; 1662 1750 1663 - create_debug_file(isp116x); 1751 + ret = create_debug_file(isp116x); 1752 + if (ret) { 1753 + ERR("Couldn't create debugfs entry\n"); 1754 + goto err7; 1755 + } 1756 + 1664 1757 return 0; 1665 1758 1759 + err7: 1760 + usb_remove_hcd(hcd); 1666 1761 err6: 1667 1762 usb_put_hcd(hcd); 1668 1763 err5: ··· 1691 1772 */ 1692 1773 static int isp116x_suspend(struct platform_device *dev, pm_message_t state) 1693 1774 { 1694 - int ret = 0; 1695 - 1696 - VDBG("%s: state %x\n", __func__, state); 1697 - 1775 + VDBG("%s: state %x\n", __func__, state.event); 1698 1776 dev->dev.power.power_state = state; 1699 - 1700 - return ret; 1777 + return 0; 1701 1778 } 1702 1779 1703 1780 /* ··· 1701 1786 */ 1702 1787 static int isp116x_resume(struct platform_device *dev) 1703 1788 { 1704 - int ret = 0; 1705 - 1706 - VDBG("%s: state %x\n", __func__, dev->dev.power.power_state); 1707 - 1789 + VDBG("%s: state %x\n", __func__, dev->power.power_state.event); 1708 1790 dev->dev.power.power_state = PMSG_ON; 1709 - 1710 - return ret; 1791 + return 0; 1711 1792 } 1712 1793 1713 1794 #else
+54 -29
drivers/usb/host/isp116x.h
··· 259 259 260 260 struct isp116x_platform_data *board; 261 261 262 - struct proc_dir_entry *pde; 262 + struct dentry *dentry; 263 263 unsigned long stat1, stat2, stat4, stat8, stat16; 264 264 265 265 /* HC registers */ ··· 450 450 isp116x_write_data32(isp116x, (u32) val); 451 451 } 452 452 453 - #define isp116x_show_reg(d,r) { \ 453 + #define isp116x_show_reg_log(d,r,s) { \ 454 454 if ((r) < 0x20) { \ 455 455 DBG("%-12s[%02x]: %08x\n", #r, \ 456 456 r, isp116x_read_reg32(d, r)); \ ··· 459 459 r, isp116x_read_reg16(d, r)); \ 460 460 } \ 461 461 } 462 + #define isp116x_show_reg_seq(d,r,s) { \ 463 + if ((r) < 0x20) { \ 464 + seq_printf(s, "%-12s[%02x]: %08x\n", #r, \ 465 + r, isp116x_read_reg32(d, r)); \ 466 + } else { \ 467 + seq_printf(s, "%-12s[%02x]: %04x\n", #r, \ 468 + r, isp116x_read_reg16(d, r)); \ 469 + } \ 470 + } 462 471 463 - static inline void isp116x_show_regs(struct isp116x *isp116x) 472 + #define isp116x_show_regs(d,type,s) { \ 473 + isp116x_show_reg_##type(d, HCREVISION, s); \ 474 + isp116x_show_reg_##type(d, HCCONTROL, s); \ 475 + isp116x_show_reg_##type(d, HCCMDSTAT, s); \ 476 + isp116x_show_reg_##type(d, HCINTSTAT, s); \ 477 + isp116x_show_reg_##type(d, HCINTENB, s); \ 478 + isp116x_show_reg_##type(d, HCFMINTVL, s); \ 479 + isp116x_show_reg_##type(d, HCFMREM, s); \ 480 + isp116x_show_reg_##type(d, HCFMNUM, s); \ 481 + isp116x_show_reg_##type(d, HCLSTHRESH, s); \ 482 + isp116x_show_reg_##type(d, HCRHDESCA, s); \ 483 + isp116x_show_reg_##type(d, HCRHDESCB, s); \ 484 + isp116x_show_reg_##type(d, HCRHSTATUS, s); \ 485 + isp116x_show_reg_##type(d, HCRHPORT1, s); \ 486 + isp116x_show_reg_##type(d, HCRHPORT2, s); \ 487 + isp116x_show_reg_##type(d, HCHWCFG, s); \ 488 + isp116x_show_reg_##type(d, HCDMACFG, s); \ 489 + isp116x_show_reg_##type(d, HCXFERCTR, s); \ 490 + isp116x_show_reg_##type(d, HCuPINT, s); \ 491 + isp116x_show_reg_##type(d, HCuPINTENB, s); \ 492 + isp116x_show_reg_##type(d, HCCHIPID, s); \ 493 + isp116x_show_reg_##type(d, HCSCRATCH, s); \ 494 + isp116x_show_reg_##type(d, HCITLBUFLEN, s); \ 495 + isp116x_show_reg_##type(d, HCATLBUFLEN, s); \ 496 + isp116x_show_reg_##type(d, HCBUFSTAT, s); \ 497 + isp116x_show_reg_##type(d, HCRDITL0LEN, s); \ 498 + isp116x_show_reg_##type(d, HCRDITL1LEN, s); \ 499 + } 500 + 501 + /* 502 + Dump registers for debugfs. 503 + */ 504 + static inline void isp116x_show_regs_seq(struct isp116x *isp116x, 505 + struct seq_file *s) 464 506 { 465 - isp116x_show_reg(isp116x, HCREVISION); 466 - isp116x_show_reg(isp116x, HCCONTROL); 467 - isp116x_show_reg(isp116x, HCCMDSTAT); 468 - isp116x_show_reg(isp116x, HCINTSTAT); 469 - isp116x_show_reg(isp116x, HCINTENB); 470 - isp116x_show_reg(isp116x, HCFMINTVL); 471 - isp116x_show_reg(isp116x, HCFMREM); 472 - isp116x_show_reg(isp116x, HCFMNUM); 473 - isp116x_show_reg(isp116x, HCLSTHRESH); 474 - isp116x_show_reg(isp116x, HCRHDESCA); 475 - isp116x_show_reg(isp116x, HCRHDESCB); 476 - isp116x_show_reg(isp116x, HCRHSTATUS); 477 - isp116x_show_reg(isp116x, HCRHPORT1); 478 - isp116x_show_reg(isp116x, HCRHPORT2); 479 - isp116x_show_reg(isp116x, HCHWCFG); 480 - isp116x_show_reg(isp116x, HCDMACFG); 481 - isp116x_show_reg(isp116x, HCXFERCTR); 482 - isp116x_show_reg(isp116x, HCuPINT); 483 - isp116x_show_reg(isp116x, HCuPINTENB); 484 - isp116x_show_reg(isp116x, HCCHIPID); 485 - isp116x_show_reg(isp116x, HCSCRATCH); 486 - isp116x_show_reg(isp116x, HCITLBUFLEN); 487 - isp116x_show_reg(isp116x, HCATLBUFLEN); 488 - isp116x_show_reg(isp116x, HCBUFSTAT); 489 - isp116x_show_reg(isp116x, HCRDITL0LEN); 490 - isp116x_show_reg(isp116x, HCRDITL1LEN); 507 + isp116x_show_regs(isp116x, seq, s); 508 + } 509 + 510 + /* 511 + Dump registers to syslog. 512 + */ 513 + static inline void isp116x_show_regs_log(struct isp116x *isp116x) 514 + { 515 + isp116x_show_regs(isp116x, log, NULL); 491 516 } 492 517 493 518 #if defined(URB_TRACE)