diff options
Diffstat (limited to 'drivers/usb/host/isp1362-hcd.c')
-rw-r--r-- | drivers/usb/host/isp1362-hcd.c | 66 |
1 files changed, 23 insertions, 43 deletions
diff --git a/drivers/usb/host/isp1362-hcd.c b/drivers/usb/host/isp1362-hcd.c index 5c774ab98252..217fb5170200 100644 --- a/drivers/usb/host/isp1362-hcd.c +++ b/drivers/usb/host/isp1362-hcd.c | |||
@@ -80,7 +80,7 @@ | |||
80 | #include <linux/platform_device.h> | 80 | #include <linux/platform_device.h> |
81 | #include <linux/pm.h> | 81 | #include <linux/pm.h> |
82 | #include <linux/io.h> | 82 | #include <linux/io.h> |
83 | #include <linux/bitops.h> | 83 | #include <linux/bitmap.h> |
84 | 84 | ||
85 | #include <asm/irq.h> | 85 | #include <asm/irq.h> |
86 | #include <asm/system.h> | 86 | #include <asm/system.h> |
@@ -190,10 +190,8 @@ static int claim_ptd_buffers(struct isp1362_ep_queue *epq, | |||
190 | struct isp1362_ep *ep, u16 len) | 190 | struct isp1362_ep *ep, u16 len) |
191 | { | 191 | { |
192 | int ptd_offset = -EINVAL; | 192 | int ptd_offset = -EINVAL; |
193 | int index; | ||
194 | int num_ptds = ((len + PTD_HEADER_SIZE - 1) / epq->blk_size) + 1; | 193 | int num_ptds = ((len + PTD_HEADER_SIZE - 1) / epq->blk_size) + 1; |
195 | int found = -1; | 194 | int found; |
196 | int last = -1; | ||
197 | 195 | ||
198 | BUG_ON(len > epq->buf_size); | 196 | BUG_ON(len > epq->buf_size); |
199 | 197 | ||
@@ -205,20 +203,9 @@ static int claim_ptd_buffers(struct isp1362_ep_queue *epq, | |||
205 | epq->name, len, epq->blk_size, num_ptds, epq->buf_map, epq->skip_map); | 203 | epq->name, len, epq->blk_size, num_ptds, epq->buf_map, epq->skip_map); |
206 | BUG_ON(ep->num_ptds != 0); | 204 | BUG_ON(ep->num_ptds != 0); |
207 | 205 | ||
208 | for (index = 0; index <= epq->buf_count - num_ptds; index++) { | 206 | found = bitmap_find_next_zero_area(&epq->buf_map, epq->buf_count, 0, |
209 | if (test_bit(index, &epq->buf_map)) | 207 | num_ptds, 0); |
210 | continue; | 208 | if (found >= epq->buf_count) |
211 | found = index; | ||
212 | for (last = index + 1; last < index + num_ptds; last++) { | ||
213 | if (test_bit(last, &epq->buf_map)) { | ||
214 | found = -1; | ||
215 | break; | ||
216 | } | ||
217 | } | ||
218 | if (found >= 0) | ||
219 | break; | ||
220 | } | ||
221 | if (found < 0) | ||
222 | return -EOVERFLOW; | 209 | return -EOVERFLOW; |
223 | 210 | ||
224 | DBG(1, "%s: Found %d PTDs[%d] for %d/%d byte\n", __func__, | 211 | DBG(1, "%s: Found %d PTDs[%d] for %d/%d byte\n", __func__, |
@@ -230,8 +217,7 @@ static int claim_ptd_buffers(struct isp1362_ep_queue *epq, | |||
230 | epq->buf_avail -= num_ptds; | 217 | epq->buf_avail -= num_ptds; |
231 | BUG_ON(epq->buf_avail > epq->buf_count); | 218 | BUG_ON(epq->buf_avail > epq->buf_count); |
232 | ep->ptd_index = found; | 219 | ep->ptd_index = found; |
233 | for (index = found; index < last; index++) | 220 | bitmap_set(&epq->buf_map, found, num_ptds); |
234 | __set_bit(index, &epq->buf_map); | ||
235 | DBG(1, "%s: Done %s PTD[%d] $%04x, avail %d count %d claimed %d %08lx:%08lx\n", | 221 | DBG(1, "%s: Done %s PTD[%d] $%04x, avail %d count %d claimed %d %08lx:%08lx\n", |
236 | __func__, epq->name, ep->ptd_index, ep->ptd_offset, | 222 | __func__, epq->name, ep->ptd_index, ep->ptd_offset, |
237 | epq->buf_avail, epq->buf_count, num_ptds, epq->buf_map, epq->skip_map); | 223 | epq->buf_avail, epq->buf_count, num_ptds, epq->buf_map, epq->skip_map); |
@@ -1271,7 +1257,7 @@ static int isp1362_urb_enqueue(struct usb_hcd *hcd, | |||
1271 | 1257 | ||
1272 | /* avoid all allocations within spinlocks: request or endpoint */ | 1258 | /* avoid all allocations within spinlocks: request or endpoint */ |
1273 | if (!hep->hcpriv) { | 1259 | if (!hep->hcpriv) { |
1274 | ep = kcalloc(1, sizeof *ep, mem_flags); | 1260 | ep = kzalloc(sizeof *ep, mem_flags); |
1275 | if (!ep) | 1261 | if (!ep) |
1276 | return -ENOMEM; | 1262 | return -ENOMEM; |
1277 | } | 1263 | } |
@@ -2284,10 +2270,10 @@ static int isp1362_mem_config(struct usb_hcd *hcd) | |||
2284 | dev_info(hcd->self.controller, "ISP1362 Memory usage:\n"); | 2270 | dev_info(hcd->self.controller, "ISP1362 Memory usage:\n"); |
2285 | dev_info(hcd->self.controller, " ISTL: 2 * %4d: %4d @ $%04x:$%04x\n", | 2271 | dev_info(hcd->self.controller, " ISTL: 2 * %4d: %4d @ $%04x:$%04x\n", |
2286 | istl_size / 2, istl_size, 0, istl_size / 2); | 2272 | istl_size / 2, istl_size, 0, istl_size / 2); |
2287 | dev_info(hcd->self.controller, " INTL: %4d * (%3lu+8): %4d @ $%04x\n", | 2273 | dev_info(hcd->self.controller, " INTL: %4d * (%3zu+8): %4d @ $%04x\n", |
2288 | ISP1362_INTL_BUFFERS, intl_blksize - PTD_HEADER_SIZE, | 2274 | ISP1362_INTL_BUFFERS, intl_blksize - PTD_HEADER_SIZE, |
2289 | intl_size, istl_size); | 2275 | intl_size, istl_size); |
2290 | dev_info(hcd->self.controller, " ATL : %4d * (%3lu+8): %4d @ $%04x\n", | 2276 | dev_info(hcd->self.controller, " ATL : %4d * (%3zu+8): %4d @ $%04x\n", |
2291 | atl_buffers, atl_blksize - PTD_HEADER_SIZE, | 2277 | atl_buffers, atl_blksize - PTD_HEADER_SIZE, |
2292 | atl_size, istl_size + intl_size); | 2278 | atl_size, istl_size + intl_size); |
2293 | dev_info(hcd->self.controller, " USED/FREE: %4d %4d\n", total, | 2279 | dev_info(hcd->self.controller, " USED/FREE: %4d %4d\n", total, |
@@ -2711,6 +2697,8 @@ static int __init isp1362_probe(struct platform_device *pdev) | |||
2711 | void __iomem *data_reg; | 2697 | void __iomem *data_reg; |
2712 | int irq; | 2698 | int irq; |
2713 | int retval = 0; | 2699 | int retval = 0; |
2700 | struct resource *irq_res; | ||
2701 | unsigned int irq_flags = 0; | ||
2714 | 2702 | ||
2715 | /* basic sanity checks first. board-specific init logic should | 2703 | /* basic sanity checks first. board-specific init logic should |
2716 | * have initialized this the three resources and probably board | 2704 | * have initialized this the three resources and probably board |
@@ -2724,30 +2712,18 @@ static int __init isp1362_probe(struct platform_device *pdev) | |||
2724 | 2712 | ||
2725 | data = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 2713 | data = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
2726 | addr = platform_get_resource(pdev, IORESOURCE_MEM, 1); | 2714 | addr = platform_get_resource(pdev, IORESOURCE_MEM, 1); |
2727 | irq = platform_get_irq(pdev, 0); | 2715 | irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); |
2728 | if (!addr || !data || irq < 0) { | 2716 | if (!addr || !data || !irq_res) { |
2729 | retval = -ENODEV; | 2717 | retval = -ENODEV; |
2730 | goto err1; | 2718 | goto err1; |
2731 | } | 2719 | } |
2720 | irq = irq_res->start; | ||
2732 | 2721 | ||
2733 | #ifdef CONFIG_USB_HCD_DMA | ||
2734 | if (pdev->dev.dma_mask) { | ||
2735 | struct resource *dma_res = platform_get_resource(pdev, IORESOURCE_MEM, 2); | ||
2736 | |||
2737 | if (!dma_res) { | ||
2738 | retval = -ENODEV; | ||
2739 | goto err1; | ||
2740 | } | ||
2741 | isp1362_hcd->data_dma = dma_res->start; | ||
2742 | isp1362_hcd->max_dma_size = resource_len(dma_res); | ||
2743 | } | ||
2744 | #else | ||
2745 | if (pdev->dev.dma_mask) { | 2722 | if (pdev->dev.dma_mask) { |
2746 | DBG(1, "won't do DMA"); | 2723 | DBG(1, "won't do DMA"); |
2747 | retval = -ENODEV; | 2724 | retval = -ENODEV; |
2748 | goto err1; | 2725 | goto err1; |
2749 | } | 2726 | } |
2750 | #endif | ||
2751 | 2727 | ||
2752 | if (!request_mem_region(addr->start, resource_len(addr), hcd_name)) { | 2728 | if (!request_mem_region(addr->start, resource_len(addr), hcd_name)) { |
2753 | retval = -EBUSY; | 2729 | retval = -EBUSY; |
@@ -2795,12 +2771,16 @@ static int __init isp1362_probe(struct platform_device *pdev) | |||
2795 | } | 2771 | } |
2796 | #endif | 2772 | #endif |
2797 | 2773 | ||
2798 | #ifdef CONFIG_ARM | 2774 | if (irq_res->flags & IORESOURCE_IRQ_HIGHEDGE) |
2799 | if (isp1362_hcd->board) | 2775 | irq_flags |= IRQF_TRIGGER_RISING; |
2800 | set_irq_type(irq, isp1362_hcd->board->int_act_high ? IRQT_RISING : IRQT_FALLING); | 2776 | if (irq_res->flags & IORESOURCE_IRQ_LOWEDGE) |
2801 | #endif | 2777 | irq_flags |= IRQF_TRIGGER_FALLING; |
2778 | if (irq_res->flags & IORESOURCE_IRQ_HIGHLEVEL) | ||
2779 | irq_flags |= IRQF_TRIGGER_HIGH; | ||
2780 | if (irq_res->flags & IORESOURCE_IRQ_LOWLEVEL) | ||
2781 | irq_flags |= IRQF_TRIGGER_LOW; | ||
2802 | 2782 | ||
2803 | retval = usb_add_hcd(hcd, irq, IRQF_TRIGGER_LOW | IRQF_DISABLED | IRQF_SHARED); | 2783 | retval = usb_add_hcd(hcd, irq, irq_flags | IRQF_DISABLED | IRQF_SHARED); |
2804 | if (retval != 0) | 2784 | if (retval != 0) |
2805 | goto err6; | 2785 | goto err6; |
2806 | pr_info("%s, irq %d\n", hcd->product_desc, irq); | 2786 | pr_info("%s, irq %d\n", hcd->product_desc, irq); |