/** * mu3d_hal_stop_qmu - stop qmu function (after qmu stop, fifo should be flushed) * @args - arg1: ep number, arg2: dir */ void mu3d_hal_stop_qmu(DEV_INT32 q_num, USB_DIR dir) { if (dir == USB_TX) { if(!(os_readl(USB_QMU_TQCSR(q_num)) & (QMU_Q_ACTIVE))){ qmu_printk(K_CRIT, "Tx%d inActive Now!\n", q_num); return; } os_writel(USB_QMU_TQCSR(q_num), QMU_Q_STOP); mb(); if(wait_for_value(USB_QMU_TQCSR(q_num), QMU_Q_ACTIVE, 0, 10, 100) == RET_SUCCESS) qmu_printk(K_CRIT, "Tx%d stop Now! CSR=0x%x\n", q_num, os_readl(USB_QMU_TQCSR(q_num))); else { qmu_printk(K_CRIT, "Tx%d UNSTOPABLE!! CSR=0x%x\n", q_num, os_readl(USB_QMU_TQCSR(q_num))); WARN_ON(1); } } else if(dir == USB_RX) { if(!(os_readl(USB_QMU_RQCSR(q_num)) & QMU_Q_ACTIVE)){ qmu_printk(K_CRIT, "Rx%d inActive Now!\n", q_num); return; } os_writel(USB_QMU_RQCSR(q_num), QMU_Q_STOP); mb(); if(wait_for_value(USB_QMU_RQCSR(q_num), QMU_Q_ACTIVE, 0, 10, 100) == RET_SUCCESS) qmu_printk(K_CRIT, "Rx%d stop Now! CSR=0x%x\n", q_num, os_readl(USB_QMU_RQCSR(q_num))); else { qmu_printk(K_CRIT, "Rx%d UNSTOPABLE!! CSR=0x%x\n", q_num, os_readl(USB_QMU_RQCSR(q_num))); WARN_ON(1); } } }
void __gxio_dma_queue_update_credits(__gxio_dma_queue_t *dma_queue) { __gxio_ring_t val; uint64_t count; uint64_t delta; uint64_t new_count; /* * Read the 64-bit completion count without touching the cache, so * we later avoid having to evict any sharers of this cache line * when we update it below. */ uint64_t orig_hw_complete_count = cmpxchg(&dma_queue->hw_complete_count, -1, -1); /* Make sure the load completes before we access the hardware. */ wait_for_value(orig_hw_complete_count); /* Read the 16-bit count of how many packets it has completed. */ val.word = __gxio_mmio_read(dma_queue->post_region_addr); count = val.count; /* * Calculate the number of completions since we last updated the * 64-bit counter. It's safe to ignore the high bits because the * maximum credit value is 65535. */ delta = (count - orig_hw_complete_count) & 0xffff; if (delta == 0) return; /* * Try to write back the count, advanced by delta. If we race with * another thread, this might fail, in which case we return * immediately on the assumption that some credits are (or at least * were) available. */ new_count = orig_hw_complete_count + delta; if (cmpxchg(&dma_queue->hw_complete_count, orig_hw_complete_count, new_count) != orig_hw_complete_count) return; /* * We succeeded in advancing the completion count; add back the * corresponding number of egress credits. */ __insn_fetchadd(&dma_queue->credits_and_next_index, (delta << DMA_QUEUE_CREDIT_SHIFT)); }