H A D | isp116x-hcd.c | 41 include/linux/usb-isp116x.h for more info. Some broken 66 #include <linux/usb/isp116x.h> 74 #include "isp116x.h" 82 static const char hcd_name[] = "isp116x-hcd"; 89 static void write_ptddata_to_fifo(struct isp116x *isp116x, void *buf, int len) write_ptddata_to_fifo() argument 105 isp116x_raw_write_data16(isp116x, w); write_ptddata_to_fifo() 108 isp116x_write_data16(isp116x, (u16) * dp); write_ptddata_to_fifo() 113 isp116x_raw_write_data16(isp116x, cpu_to_le16(*dp2++)); write_ptddata_to_fifo() 117 isp116x_write_data16(isp116x, 0xff & *((u8 *) dp2)); write_ptddata_to_fifo() 120 isp116x_raw_write_data16(isp116x, 0); write_ptddata_to_fifo() 126 static void read_ptddata_from_fifo(struct isp116x *isp116x, void *buf, int len) read_ptddata_from_fifo() argument 140 w = isp116x_raw_read_data16(isp116x); read_ptddata_from_fifo() 146 *dp = 0xff & isp116x_read_data16(isp116x); read_ptddata_from_fifo() 151 *dp2++ = le16_to_cpu(isp116x_raw_read_data16(isp116x)); read_ptddata_from_fifo() 155 *(u8 *) dp2 = 0xff & isp116x_read_data16(isp116x); read_ptddata_from_fifo() 158 isp116x_raw_read_data16(isp116x); read_ptddata_from_fifo() 165 static void pack_fifo(struct isp116x *isp116x) pack_fifo() argument 169 int buflen = isp116x->atl_last_dir == PTD_DIR_IN pack_fifo() 170 ? isp116x->atl_bufshrt : isp116x->atl_buflen; pack_fifo() 172 isp116x_write_reg16(isp116x, HCuPINT, HCuPINT_AIIEOT); pack_fifo() 173 isp116x_write_reg16(isp116x, HCXFERCTR, buflen); pack_fifo() 174 isp116x_write_addr(isp116x, HCATLPORT | ISP116x_WRITE_OFFSET); pack_fifo() 175 for (ep = isp116x->atl_active; ep; ep = ep->active) { pack_fifo() 179 isp116x_write_data16(isp116x, ptd->count); pack_fifo() 180 isp116x_write_data16(isp116x, ptd->mps); pack_fifo() 181 isp116x_write_data16(isp116x, ptd->len); pack_fifo() 182 isp116x_write_data16(isp116x, ptd->faddr); pack_fifo() 185 if (ep->active || (isp116x->atl_last_dir != PTD_DIR_IN)) { pack_fifo() 186 write_ptddata_to_fifo(isp116x, ep->data, ep->length); pack_fifo() 197 static void unpack_fifo(struct isp116x *isp116x) unpack_fifo() argument 201 int buflen = isp116x->atl_last_dir == PTD_DIR_IN unpack_fifo() 202 ? isp116x->atl_buflen : isp116x->atl_bufshrt; unpack_fifo() 204 isp116x_write_reg16(isp116x, HCuPINT, HCuPINT_AIIEOT); unpack_fifo() 205 isp116x_write_reg16(isp116x, HCXFERCTR, buflen); unpack_fifo() 206 isp116x_write_addr(isp116x, HCATLPORT); unpack_fifo() 207 for (ep = isp116x->atl_active; ep; ep = ep->active) { unpack_fifo() 209 ptd->count = isp116x_read_data16(isp116x); unpack_fifo() 210 ptd->mps = isp116x_read_data16(isp116x); unpack_fifo() 211 ptd->len = isp116x_read_data16(isp116x); unpack_fifo() 212 ptd->faddr = isp116x_read_data16(isp116x); unpack_fifo() 215 if (ep->active || (isp116x->atl_last_dir == PTD_DIR_IN)) { unpack_fifo() 216 read_ptddata_from_fifo(isp116x, ep->data, ep->length); unpack_fifo() 230 static void preproc_atl_queue(struct isp116x *isp116x) preproc_atl_queue() argument 237 for (ep = isp116x->atl_active; ep; ep = ep->active) { preproc_atl_queue() 282 isp116x->atl_last_dir = dir; preproc_atl_queue() 284 isp116x->atl_bufshrt = sizeof(struct ptd) + isp116x->atl_buflen; preproc_atl_queue() 285 isp116x->atl_buflen = isp116x->atl_bufshrt + ALIGN(len, 4); preproc_atl_queue() 293 static void finish_request(struct isp116x *isp116x, struct isp116x_ep *ep, 295 __releases(isp116x->lock) __acquires(isp116x->lock) 306 usb_hcd_unlink_urb_from_ep(isp116x_to_hcd(isp116x), urb); 307 spin_unlock(&isp116x->lock); 308 usb_hcd_giveback_urb(isp116x_to_hcd(isp116x), urb, status); 309 spin_lock(&isp116x->lock); 325 struct isp116x_ep **prev = &isp116x->periodic[i]; 331 isp116x->load[i] -= ep->load; 334 isp116x_to_hcd(isp116x)->self.bandwidth_allocated -= 338 if (!--isp116x->periodic_count) { 339 isp116x->irqenb &= ~HCuPINT_SOF; 340 isp116x->irqenb |= HCuPINT_ATL; 347 static void postproc_atl_queue(struct isp116x *isp116x) postproc_atl_queue() argument 357 for (ep = isp116x->atl_active; ep; ep = ep->active) { postproc_atl_queue() 411 /* Take into account idiosyncracies of the isp116x chip postproc_atl_queue() 471 finish_request(isp116x, ep, urb, status); postproc_atl_queue() 479 static void start_atl_transfers(struct isp116x *isp116x) start_atl_transfers() argument 486 if (atomic_read(&isp116x->atl_finishing)) start_atl_transfers() 489 if (!HC_IS_RUNNING(isp116x_to_hcd(isp116x)->state)) start_atl_transfers() 493 if (isp116x_read_reg16(isp116x, HCBUFSTAT) & HCBUFSTAT_ATL_FULL) start_atl_transfers() 496 isp116x->atl_active = NULL; start_atl_transfers() 497 isp116x->atl_buflen = isp116x->atl_bufshrt = 0; start_atl_transfers() 500 if (isp116x->periodic_count) { start_atl_transfers() 501 isp116x->fmindex = index = start_atl_transfers() 502 (isp116x->fmindex + 1) & (PERIODIC_SIZE - 1); start_atl_transfers() 503 if ((load = isp116x->load[index])) { start_atl_transfers() 506 isp116x->atl_active = last_ep = start_atl_transfers() 507 isp116x->periodic[index]; start_atl_transfers() 515 list_for_each_entry(ep, &isp116x->async, schedule) { start_atl_transfers() 558 isp116x->atl_active = ep; start_atl_transfers() 563 if ((&isp116x->async)->next != (&isp116x->async)->prev) start_atl_transfers() 564 list_move(&isp116x->async, (&isp116x->async)->next); start_atl_transfers() 566 if (isp116x->atl_active) { start_atl_transfers() 567 preproc_atl_queue(isp116x); start_atl_transfers() 568 pack_fifo(isp116x); start_atl_transfers() 575 static void finish_atl_transfers(struct isp116x *isp116x) finish_atl_transfers() argument 577 if (!isp116x->atl_active) finish_atl_transfers() 580 if (!(isp116x_read_reg16(isp116x, HCBUFSTAT) & HCBUFSTAT_ATL_DONE)) finish_atl_transfers() 583 atomic_inc(&isp116x->atl_finishing); finish_atl_transfers() 584 unpack_fifo(isp116x); finish_atl_transfers() 585 postproc_atl_queue(isp116x); finish_atl_transfers() 586 atomic_dec(&isp116x->atl_finishing); finish_atl_transfers() 591 struct isp116x *isp116x = hcd_to_isp116x(hcd); isp116x_irq() local 595 spin_lock(&isp116x->lock); isp116x_irq() 596 isp116x_write_reg16(isp116x, HCuPINTENB, 0); isp116x_irq() 597 irqstat = isp116x_read_reg16(isp116x, HCuPINT); isp116x_irq() 598 isp116x_write_reg16(isp116x, HCuPINT, irqstat); isp116x_irq() 602 finish_atl_transfers(isp116x); isp116x_irq() 606 u32 intstat = isp116x_read_reg32(isp116x, HCINTSTAT); isp116x_irq() 607 isp116x_write_reg32(isp116x, HCINTSTAT, intstat); isp116x_irq() 632 start_atl_transfers(isp116x); isp116x_irq() 635 isp116x_write_reg16(isp116x, HCuPINTENB, isp116x->irqenb); isp116x_irq() 637 spin_unlock(&isp116x->lock); isp116x_irq() 650 static int balance(struct isp116x *isp116x, u16 period, u16 load) balance() argument 657 if (branch < 0 || isp116x->load[branch] > isp116x->load[i]) { balance() 661 if ((isp116x->load[j] + load) balance() 673 /* NB! ALL the code above this point runs with isp116x->lock 683 struct isp116x *isp116x = hcd_to_isp116x(hcd); isp116x_urb_enqueue() local 709 spin_lock_irqsave(&isp116x->lock, flags); isp116x_urb_enqueue() 771 list_add_tail(&ep->schedule, &isp116x->async); isp116x_urb_enqueue() 782 ep->branch = ret = balance(isp116x, ep->period, ep->load); isp116x_urb_enqueue() 787 urb->start_frame = (isp116x->fmindex & (PERIODIC_SIZE - 1)) isp116x_urb_enqueue() 795 struct isp116x_ep **prev = &isp116x->periodic[i]; isp116x_urb_enqueue() 808 isp116x->load[i] += ep->load; isp116x_urb_enqueue() 813 if (!isp116x->periodic_count++) { isp116x_urb_enqueue() 814 isp116x->irqenb &= ~HCuPINT_ATL; isp116x_urb_enqueue() 815 isp116x->irqenb |= HCuPINT_SOF; isp116x_urb_enqueue() 816 isp116x_write_reg16(isp116x, HCuPINTENB, isp116x_urb_enqueue() 817 isp116x->irqenb); isp116x_urb_enqueue() 822 start_atl_transfers(isp116x); isp116x_urb_enqueue() 828 spin_unlock_irqrestore(&isp116x->lock, flags); isp116x_urb_enqueue() 838 struct isp116x *isp116x = hcd_to_isp116x(hcd); isp116x_urb_dequeue() local 844 spin_lock_irqsave(&isp116x->lock, flags); isp116x_urb_dequeue() 856 for (ep_act = isp116x->atl_active; ep_act; isp116x_urb_dequeue() 866 finish_request(isp116x, ep, urb, status); isp116x_urb_dequeue() 868 spin_unlock_irqrestore(&isp116x->lock, flags); isp116x_urb_dequeue() 893 struct isp116x *isp116x = hcd_to_isp116x(hcd); isp116x_get_frame() local 897 spin_lock_irqsave(&isp116x->lock, flags); isp116x_get_frame() 898 fmnum = isp116x_read_reg32(isp116x, HCFMNUM); isp116x_get_frame() 899 spin_unlock_irqrestore(&isp116x->lock, flags); isp116x_get_frame() 908 struct isp116x *isp116x = hcd_to_isp116x(hcd); isp116x_hub_status_data() local 920 ports = isp116x->rhdesca & RH_A_NDP; isp116x_hub_status_data() 921 spin_lock_irqsave(&isp116x->lock, flags); isp116x_hub_status_data() 922 isp116x->rhstatus = isp116x_read_reg32(isp116x, HCRHSTATUS); isp116x_hub_status_data() 923 if (isp116x->rhstatus & (RH_HS_LPSC | RH_HS_OCIC)) isp116x_hub_status_data() 929 u32 status = isp116x_read_reg32(isp116x, i ? HCRHPORT2 : HCRHPORT1); isp116x_hub_status_data() 937 spin_unlock_irqrestore(&isp116x->lock, flags); isp116x_hub_status_data() 941 static void isp116x_hub_descriptor(struct isp116x *isp116x, isp116x_hub_descriptor() argument 944 u32 reg = isp116x->rhdesca; isp116x_hub_descriptor() 968 static inline void root_port_reset(struct isp116x *isp116x, unsigned port) root_port_reset() argument 978 spin_lock_irqsave(&isp116x->lock, flags); root_port_reset() 981 tmp = isp116x_read_reg32(isp116x, port ? root_port_reset() 989 spin_unlock_irqrestore(&isp116x->lock, flags); root_port_reset() 993 isp116x_write_reg32(isp116x, port ? HCRHPORT2 : root_port_reset() 995 spin_unlock_irqrestore(&isp116x->lock, flags); root_port_reset() 1005 struct isp116x *isp116x = hcd_to_isp116x(hcd); isp116x_hub_control() local 1008 int ports = isp116x->rhdesca & RH_A_NDP; isp116x_hub_control() 1017 spin_lock_irqsave(&isp116x->lock, flags); isp116x_hub_control() 1018 isp116x_write_reg32(isp116x, HCRHSTATUS, RH_HS_OCIC); isp116x_hub_control() 1019 spin_unlock_irqrestore(&isp116x->lock, flags); isp116x_hub_control() 1040 isp116x_hub_descriptor(isp116x, isp116x_hub_control() 1051 spin_lock_irqsave(&isp116x->lock, flags); isp116x_hub_control() 1052 tmp = isp116x_read_reg32(isp116x, (--wIndex) ? HCRHPORT2 : HCRHPORT1); isp116x_hub_control() 1053 spin_unlock_irqrestore(&isp116x->lock, flags); isp116x_hub_control() 1099 spin_lock_irqsave(&isp116x->lock, flags); isp116x_hub_control() 1100 isp116x_write_reg32(isp116x, wIndex isp116x_hub_control() 1102 spin_unlock_irqrestore(&isp116x->lock, flags); isp116x_hub_control() 1112 spin_lock_irqsave(&isp116x->lock, flags); isp116x_hub_control() 1113 isp116x_write_reg32(isp116x, wIndex isp116x_hub_control() 1115 spin_unlock_irqrestore(&isp116x->lock, flags); isp116x_hub_control() 1119 spin_lock_irqsave(&isp116x->lock, flags); isp116x_hub_control() 1120 isp116x_write_reg32(isp116x, wIndex isp116x_hub_control() 1122 spin_unlock_irqrestore(&isp116x->lock, flags); isp116x_hub_control() 1126 root_port_reset(isp116x, wIndex); isp116x_hub_control() 1170 struct isp116x *isp116x = s->private; isp116x_show_dbg() local 1173 isp116x_to_hcd(isp116x)->product_desc, hcd_name, isp116x_show_dbg() 1176 if (HC_IS_SUSPENDED(isp116x_to_hcd(isp116x)->state)) { isp116x_show_dbg() 1180 if (!HC_IS_RUNNING(isp116x_to_hcd(isp116x)->state)) { isp116x_show_dbg() 1185 spin_lock_irq(&isp116x->lock); isp116x_show_dbg() 1186 dump_irq(s, "hc_irq_enable", isp116x_read_reg16(isp116x, HCuPINTENB)); isp116x_show_dbg() 1187 dump_irq(s, "hc_irq_status", isp116x_read_reg16(isp116x, HCuPINT)); isp116x_show_dbg() 1188 dump_int(s, "hc_int_enable", isp116x_read_reg32(isp116x, HCINTENB)); isp116x_show_dbg() 1189 dump_int(s, "hc_int_status", isp116x_read_reg32(isp116x, HCINTSTAT)); isp116x_show_dbg() 1190 isp116x_show_regs_seq(isp116x, s); isp116x_show_dbg() 1191 spin_unlock_irq(&isp116x->lock); isp116x_show_dbg() 1209 static int create_debug_file(struct isp116x *isp116x) create_debug_file() argument 1211 isp116x->dentry = debugfs_create_file(hcd_name, create_debug_file() 1212 S_IRUGO, NULL, isp116x, create_debug_file() 1214 if (!isp116x->dentry) create_debug_file() 1219 static void remove_debug_file(struct isp116x *isp116x) remove_debug_file() argument 1221 debugfs_remove(isp116x->dentry); remove_debug_file() 1236 static int isp116x_sw_reset(struct isp116x *isp116x) isp116x_sw_reset() argument 1242 spin_lock_irqsave(&isp116x->lock, flags); isp116x_sw_reset() 1243 isp116x_write_reg16(isp116x, HCSWRES, HCSWRES_MAGIC); isp116x_sw_reset() 1244 isp116x_write_reg32(isp116x, HCCMDSTAT, HCCMDSTAT_HCR); isp116x_sw_reset() 1248 if (!(isp116x_read_reg32(isp116x, HCCMDSTAT) & HCCMDSTAT_HCR)) isp116x_sw_reset() 1255 spin_unlock_irqrestore(&isp116x->lock, flags); isp116x_sw_reset() 1261 struct isp116x *isp116x = hcd_to_isp116x(hcd); isp116x_reset() local 1266 ret = isp116x_sw_reset(isp116x); isp116x_reset() 1273 spin_lock_irq(&isp116x->lock); isp116x_reset() 1274 clkrdy = isp116x_read_reg16(isp116x, HCuPINT) & HCuPINT_CLKRDY; isp116x_reset() 1275 spin_unlock_irq(&isp116x->lock); isp116x_reset() 1291 struct isp116x *isp116x = hcd_to_isp116x(hcd); isp116x_stop() local 1295 spin_lock_irqsave(&isp116x->lock, flags); isp116x_stop() 1296 isp116x_write_reg16(isp116x, HCuPINTENB, 0); isp116x_stop() 1300 val = isp116x_read_reg32(isp116x, HCRHDESCA); isp116x_stop() 1302 isp116x_write_reg32(isp116x, HCRHDESCA, val); isp116x_stop() 1303 isp116x_write_reg32(isp116x, HCRHSTATUS, RH_HS_LPS); isp116x_stop() 1304 spin_unlock_irqrestore(&isp116x->lock, flags); isp116x_stop() 1306 isp116x_sw_reset(isp116x); isp116x_stop() 1314 struct isp116x *isp116x = hcd_to_isp116x(hcd); isp116x_start() local 1315 struct isp116x_platform_data *board = isp116x->board; isp116x_start() 1319 spin_lock_irqsave(&isp116x->lock, flags); isp116x_start() 1322 isp116x_write_reg16(isp116x, HCuPINT, 0xff); isp116x_start() 1323 isp116x_write_reg16(isp116x, HCuPINTENB, 0); isp116x_start() 1325 val = isp116x_read_reg16(isp116x, HCCHIPID); isp116x_start() 1328 spin_unlock_irqrestore(&isp116x->lock, flags); isp116x_start() 1335 isp116x_write_reg16(isp116x, HCITLBUFLEN, ISP116x_ITL_BUFSIZE); isp116x_start() 1336 isp116x_write_reg16(isp116x, HCATLBUFLEN, ISP116x_ATL_BUFSIZE); isp116x_start() 1351 isp116x_write_reg16(isp116x, HCHWCFG, val); isp116x_start() 1361 isp116x_write_reg32(isp116x, HCRHDESCA, val); isp116x_start() 1362 isp116x->rhdesca = isp116x_read_reg32(isp116x, HCRHDESCA); isp116x_start() 1365 isp116x_write_reg32(isp116x, HCRHDESCB, val); isp116x_start() 1366 isp116x->rhdescb = isp116x_read_reg32(isp116x, HCRHDESCB); isp116x_start() 1374 isp116x_write_reg32(isp116x, HCRHSTATUS, val); isp116x_start() 1375 isp116x->rhstatus = isp116x_read_reg32(isp116x, HCRHSTATUS); isp116x_start() 1377 isp116x_write_reg32(isp116x, HCFMINTVL, 0x27782edf); isp116x_start() 1382 isp116x->intenb = HCINT_MIE | HCINT_RHSC | HCINT_UE; isp116x_start() 1384 isp116x->intenb |= HCINT_RD; isp116x_start() 1385 isp116x->irqenb = HCuPINT_ATL | HCuPINT_OPR; /* | HCuPINT_SUSP; */ isp116x_start() 1386 isp116x_write_reg32(isp116x, HCINTENB, isp116x->intenb); isp116x_start() 1387 isp116x_write_reg16(isp116x, HCuPINTENB, isp116x->irqenb); isp116x_start() 1393 isp116x_write_reg32(isp116x, HCCONTROL, val); isp116x_start() 1396 isp116x_write_reg32(isp116x, HCRHPORT1, RH_PS_CCS); isp116x_start() 1397 isp116x_write_reg32(isp116x, HCRHPORT2, RH_PS_CCS); isp116x_start() 1399 isp116x_show_regs_log(isp116x); isp116x_start() 1400 spin_unlock_irqrestore(&isp116x->lock, flags); isp116x_start() 1408 struct isp116x *isp116x = hcd_to_isp116x(hcd); isp116x_bus_suspend() local 1413 spin_lock_irqsave(&isp116x->lock, flags); isp116x_bus_suspend() 1414 val = isp116x_read_reg32(isp116x, HCCONTROL); isp116x_bus_suspend() 1418 spin_unlock_irqrestore(&isp116x->lock, flags); isp116x_bus_suspend() 1425 spin_lock_irqsave(&isp116x->lock, flags); isp116x_bus_suspend() 1426 isp116x_write_reg32(isp116x, HCCONTROL, val); isp116x_bus_suspend() 1427 spin_unlock_irqrestore(&isp116x->lock, flags); isp116x_bus_suspend() 1432 isp116x_write_reg32(isp116x, HCCONTROL, isp116x_bus_suspend() 1438 spin_unlock_irqrestore(&isp116x->lock, flags); isp116x_bus_suspend() 1447 struct isp116x *isp116x = hcd_to_isp116x(hcd); isp116x_bus_resume() local 1451 spin_lock_irq(&isp116x->lock); isp116x_bus_resume() 1453 val = isp116x_read_reg32(isp116x, HCCONTROL); isp116x_bus_resume() 1458 isp116x_write_reg32(isp116x, HCCONTROL, val); isp116x_bus_resume() 1462 spin_unlock_irq(&isp116x->lock); isp116x_bus_resume() 1467 spin_unlock_irq(&isp116x->lock); isp116x_bus_resume() 1473 if ((isp116x->rhdesca & RH_A_NDP) == 2) isp116x_bus_resume() 1479 val = isp116x->rhdesca & RH_A_NDP; isp116x_bus_resume() 1482 isp116x_read_reg32(isp116x, val ? HCRHPORT2 : HCRHPORT1); isp116x_bus_resume() 1487 isp116x_write_reg32(isp116x, RH_PS_POCI, val isp116x_bus_resume() 1490 spin_unlock_irq(&isp116x->lock); isp116x_bus_resume() 1496 spin_lock_irq(&isp116x->lock); isp116x_bus_resume() 1497 val = isp116x_read_reg32(isp116x, HCCONTROL); isp116x_bus_resume() 1498 isp116x_write_reg32(isp116x, HCCONTROL, isp116x_bus_resume() 1500 spin_unlock_irq(&isp116x->lock); isp116x_bus_resume() 1516 .hcd_priv_size = sizeof(struct isp116x), 1542 struct isp116x *isp116x; isp116x_remove() local 1547 isp116x = hcd_to_isp116x(hcd); isp116x_remove() 1548 remove_debug_file(isp116x); isp116x_remove() 1551 iounmap(isp116x->data_reg); isp116x_remove() 1554 iounmap(isp116x->addr_reg); isp116x_remove() 1565 struct isp116x *isp116x; isp116x_probe() local 1626 isp116x = hcd_to_isp116x(hcd); isp116x_probe() 1627 isp116x->data_reg = data_reg; isp116x_probe() 1628 isp116x->addr_reg = addr_reg; isp116x_probe() 1629 spin_lock_init(&isp116x->lock); isp116x_probe() 1630 INIT_LIST_HEAD(&isp116x->async); isp116x_probe() 1631 isp116x->board = dev_get_platdata(&pdev->dev); isp116x_probe() 1633 if (!isp116x->board) { isp116x_probe() 1638 if (isp116x_check_platform_delay(isp116x)) { isp116x_probe() 1641 ERR("See comments in drivers/usb/host/isp116x-hcd.c\n"); isp116x_probe() 1652 ret = create_debug_file(isp116x); isp116x_probe() 1704 MODULE_ALIAS("platform:isp116x-hcd");
|