/**
 * 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));
}