[RK3288] 外接USB设备出现丢数

CPU:RK3288

系统:Android 5.1

主板外接 USB 接口的外设,经常会出现丢数的现象,这种问题在很多 USB 接口的外设上都遇到过,例如:USB读卡器、USB扫描枪等

有一个共同点是外设在系统中作为一个键盘设备,相当于键盘输入。

直接上RK提供的补丁,此补丁优化很大,但是没有根本解决问题,偶尔还会出现丢数

diff --git a/kernel/drivers/irqchip/irq-gic.c b/kernel/drivers/irqchip/irq-gic.c
old mode 100755
new mode 100644
index ce24a7e..458edaa
--- a/kernel/drivers/irqchip/irq-gic.c
+++ b/kernel/drivers/irqchip/irq-gic.c
@@ -266,6 +266,8 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
        bit = gic_cpu_map[cpu] << shift;
        val = readl_relaxed(reg) & ~mask;
        writel_relaxed(val | bit, reg);
+       if((gic_irq(d)!=57) && (gic_irq(d)!=55))
+               writel_relaxed(val | bit, reg);
        raw_spin_unlock(&irq_controller_lock);
 
        return IRQ_SET_MASK_OK;
@@ -399,6 +401,11 @@ static void __init gic_dist_init(struct gic_chip_data *gic)
        for (i = 32; i < gic_irqs; i += 4)
                writel_relaxed(cpumask, base + GIC_DIST_TARGET + i * 4 / 4);
 
+       writel_relaxed(0x01010f01, base + GIC_DIST_TARGET + 0x38);
+       writel_relaxed(0xa0a090a0, base + GIC_DIST_PRI + 0x38);
+       writel_relaxed(0x0f010101, base + GIC_DIST_TARGET + 0x34);
+       writel_relaxed(0x90a0a0a0, base + GIC_DIST_PRI + 0x34);
+
        gic_dist_config(base, gic_irqs, NULL);
 
 #ifdef CONFIG_FIQ_DEBUGGER
diff --git a/kernel/drivers/usb/dwc_otg_310/common_port/dwc_list.h b/kernel/drivers/usb/dwc_otg_310/common_port/dwc_list.h
old mode 100755
new mode 100644
index 46f1da3..7b75033
--- a/kernel/drivers/usb/dwc_otg_310/common_port/dwc_list.h
+++ b/kernel/drivers/usb/dwc_otg_310/common_port/dwc_list.h
@@ -565,6 +565,18 @@ struct {                                                           
        (head)->cqh_last = (elm);                                       
 } while (0)
 
+#define DWC_CIRCLEQ_INSERT_COM(head, listelm, elm, field, com) do {    
+       DWC_CIRCLEQ_FOREACH(listelm, head, field) {             
+               if ((elm)->com < (listelm)->com) {              
+                       DWC_CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field); 
+                       break;                                  
+               } else                                          
+                       continue;                               
+       }                                                       
+       if (DWC_CIRCLEQ_PREV(listelm, field) != elm)            
+               DWC_CIRCLEQ_INSERT_TAIL(head, elm, field);      
+} while (0)
+
 #define DWC_CIRCLEQ_REMOVE(head, elm, field) do {                      
        if ((elm)->field.cqe_next == DWC_CIRCLEQ_END(head))             
                (head)->cqh_last = (elm)->field.cqe_prev;               
diff --git a/kernel/drivers/usb/dwc_otg_310/dwc_otg_hcd_intr.c b/kernel/drivers/usb/dwc_otg_310/dwc_otg_hcd_intr.c
old mode 100755
new mode 100644
index 0e05b13..a1a067f
--- a/kernel/drivers/usb/dwc_otg_310/dwc_otg_hcd_intr.c
+++ b/kernel/drivers/usb/dwc_otg_310/dwc_otg_hcd_intr.c
@@ -833,6 +833,7 @@ static void release_channel(dwc_otg_hcd_t *hcd,
        dwc_otg_transaction_type_e tr_type;
        int free_qtd;
        int continue_trans = 1;
+       dwc_hc_t *hc_tmp = NULL;
 
        DWC_DEBUGPL(DBG_HCDV, "  %s: channel %d, halt_status %d
",
                    __func__, hc->hc_num, halt_status);
@@ -893,7 +894,7 @@ cleanup:
         * there's no need to clear the Channel Halted interrupt separately.
         */
        dwc_otg_hc_cleanup(hcd->core_if, hc);
-       DWC_CIRCLEQ_INSERT_TAIL(&hcd->free_hc_list, hc, hc_list_entry);
+       DWC_CIRCLEQ_INSERT_COM(&hcd->free_hc_list, hc_tmp, hc, hc_list_entry, hc_num);
 
        switch (hc->ep_type) {
        case DWC_OTG_EP_TYPE_CONTROL:
原文地址:https://www.cnblogs.com/lialong1st/p/11661996.html