7fdb15afbba8699b9a47a8b4392db8bd948bb29c
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / esp8089 / esp_driver / esp_io.c
1 #include <linux/mmc/sdio_func.h>
2 #include "esp_sif.h"
3 #include "slc_host_register.h"
4 #include "esp_debug.h"
5
6 #ifdef SIF_DEBUG_DSR_DUMP_REG
7 static void dump_slc_regs(struct slc_host_regs *regs);
8 #endif /* SIF_DEBUG_DSR_DUMP_REG */
9
10 int esp_common_read(struct esp_pub *epub, u8 *buf, u32 len, int sync, bool noround)
11 {
12         if (sync) {
13 #ifdef ESP_USE_SDIO
14                 return sif_lldesc_read_sync(epub, buf, len);
15 #endif
16 #ifdef ESP_USE_SPI
17                 //return sif_spi_read_sync(epub, buf, len, NOT_CHECK_IDLE);
18                 return sif_spi_read_sync(epub, buf, len, NOT_DUMMYMODE,0);
19 #endif
20         } else {
21 #ifdef ESP_USE_SDIO
22                 return sif_lldesc_read_raw(epub, buf, len, noround);
23 #endif
24 #ifdef ESP_USE_SPI
25                 //return sif_spi_read_nosync(epub, buf, len, NOT_CHECK_IDLE, noround);
26                 return sif_spi_read_nosync(epub, buf, len, NOT_DUMMYMODE, noround,0);
27 #endif
28         }
29 }
30
31
32 int esp_common_write(struct esp_pub *epub, u8 *buf, u32 len, int sync)
33 {
34         if (sync) {
35 #ifdef ESP_USE_SDIO
36                 return sif_lldesc_write_sync(epub, buf, len);
37 #endif
38 #ifdef ESP_USE_SPI
39                 //return sif_spi_write_sync(epub, buf, len, NOT_CHECK_IDLE);
40                 return sif_spi_write_sync(epub, buf, len, NOT_DUMMYMODE,0);
41 #endif
42         } else {
43 #ifdef ESP_USE_SDIO
44                 return sif_lldesc_write_raw(epub, buf, len);
45 #endif
46 #ifdef ESP_USE_SPI
47                 //return sif_spi_write_nosync(epub, buf, len, NOT_CHECK_IDLE);
48                 return sif_spi_write_nosync(epub, buf, len, NOT_DUMMYMODE,0);
49 #endif
50         }
51 }
52
53
54 int esp_common_read_with_addr(struct esp_pub *epub, u32 addr, u8 *buf, u32 len, int sync)
55 {
56         if (sync) {
57 #ifdef ESP_USE_SDIO
58                 return sif_io_sync(epub, addr, buf, len, SIF_FROM_DEVICE | SIF_SYNC | SIF_BYTE_BASIS | SIF_INC_ADDR);
59 #endif
60 #ifdef ESP_USE_SPI
61                 return sif_spi_epub_read_mix_sync(epub, addr, buf, len, NOT_DUMMYMODE,0);
62 #endif
63         } else {
64 #ifdef ESP_USE_SDIO
65                 return sif_io_raw(epub, addr, buf, len, SIF_FROM_DEVICE | SIF_BYTE_BASIS | SIF_INC_ADDR);
66 #endif
67 #ifdef ESP_USE_SPI
68                 return sif_spi_epub_read_mix_nosync(epub, addr, buf, len, NOT_DUMMYMODE,0);
69 #endif
70         }
71
72 }
73
74
75 int esp_common_write_with_addr(struct esp_pub *epub, u32 addr, u8 *buf, u32 len, int sync)
76 {
77         if (sync) {
78 #ifdef ESP_USE_SDIO
79                 return sif_io_sync(epub, addr, buf, len, SIF_TO_DEVICE | SIF_SYNC | SIF_BYTE_BASIS | SIF_INC_ADDR);
80 #endif
81 #ifdef ESP_USE_SPI
82                 return sif_spi_epub_write_mix_sync(epub, addr, buf, len, NOT_DUMMYMODE,0);
83 #endif
84         } else {
85 #ifdef ESP_USE_SDIO
86                 return sif_io_raw(epub, addr, buf, len, SIF_TO_DEVICE | SIF_BYTE_BASIS | SIF_INC_ADDR);
87 #endif
88 #ifdef ESP_USE_SPI
89                 return sif_spi_epub_write_mix_nosync(epub, addr, buf, len, NOT_DUMMYMODE,0);
90 #endif
91         }
92 }
93
94 int esp_common_readbyte_with_addr(struct esp_pub *epub, u32 addr, u8 *buf, int sync)
95 {
96         if(sync){
97 #ifdef ESP_USE_SDIO
98         int res;
99         sif_lock_bus(epub);
100         *buf = sdio_io_readb(epub, addr, &res);
101         sif_unlock_bus(epub);
102         return res;
103 #endif
104 #ifdef ESP_USE_SPI
105         return sif_spi_epub_read_mix_sync(epub, addr, buf, 1, NOT_DUMMYMODE,0);
106 #endif
107         } else {
108 #ifdef ESP_USE_SDIO
109         int res;
110         *buf = sdio_io_readb(epub, addr, &res);
111         return res;
112 #endif
113 #ifdef ESP_USE_SPI
114         return sif_spi_epub_read_mix_nosync(epub, addr, buf, 1, NOT_DUMMYMODE,0);
115 #endif
116         }
117
118 }
119
120
121
122 int esp_common_writebyte_with_addr(struct esp_pub *epub, u32 addr, u8 buf, int sync)
123 {
124         if(sync){
125 #ifdef ESP_USE_SDIO
126                 int res;
127                 sif_lock_bus(epub);
128                 sdio_io_writeb(epub, buf, addr, &res);
129                 sif_unlock_bus(epub);
130                 return res;
131 #endif
132 #ifdef ESP_USE_SPI
133                 return sif_spi_epub_write_mix_sync(epub, addr, &buf, 1, NOT_DUMMYMODE,0 );
134 #endif
135         } else {
136 #ifdef ESP_USE_SDIO
137                 int res;
138                 sdio_io_writeb(epub, buf, addr, &res);
139                 return res;
140 #endif
141 #ifdef ESP_USE_SPI
142                 return sif_spi_epub_write_mix_nosync(epub, addr, &buf, 1, NOT_DUMMYMODE,0);
143 #endif
144         }
145 }
146
147 typedef enum _SDIO_INTR_MODE {
148         SDIO_INTR_IB = 0,
149         SDIO_INTR_OOB_TOGGLE,
150         SDIO_INTR_OOB_HIGH_LEVEL,
151         SDIO_INTR_OOB_LOW_LEVEL,
152 } SDIO_INTR_MODE;
153
154 #define GEN_GPIO_SEL(_gpio_num, _sel_func, _intr_mode, _offset) (((_offset)<< 9 ) |((_intr_mode) << 7)|((_sel_func) << 4)|(_gpio_num))
155 //bit[3:0] = gpio num, 2
156 //bit[6:4] = gpio sel func, 0
157 //bit[8:7] = gpio intr mode, SDIO_INTR_OOB_TOGGLE
158 //bit[15:9] = register offset, 0x38
159
160 u16 gpio_sel_sets[17] = {
161         GEN_GPIO_SEL(0, 0, SDIO_INTR_OOB_TOGGLE, 0x34),//GPIO0
162         GEN_GPIO_SEL(1, 3, SDIO_INTR_OOB_TOGGLE, 0x18),//U0TXD
163         GEN_GPIO_SEL(2, 0, SDIO_INTR_OOB_TOGGLE, 0x38),//GPIO2
164         GEN_GPIO_SEL(3, 3, SDIO_INTR_OOB_TOGGLE, 0x14),//U0RXD
165         GEN_GPIO_SEL(4, 0, SDIO_INTR_OOB_TOGGLE, 0x3C),//GPIO4
166         GEN_GPIO_SEL(5, 0, SDIO_INTR_OOB_TOGGLE, 0x40),//GPIO5
167         GEN_GPIO_SEL(6, 3, SDIO_INTR_OOB_TOGGLE, 0x1C),//SD_CLK
168         GEN_GPIO_SEL(7, 3, SDIO_INTR_OOB_TOGGLE, 0x20),//SD_DATA0
169         GEN_GPIO_SEL(8, 3, SDIO_INTR_OOB_TOGGLE, 0x24),//SD_DATA1
170         GEN_GPIO_SEL(9, 3, SDIO_INTR_OOB_TOGGLE, 0x28),//SD_DATA2
171         GEN_GPIO_SEL(10, 3, SDIO_INTR_OOB_TOGGLE, 0x2C),//SD_DATA3
172         GEN_GPIO_SEL(11, 3, SDIO_INTR_OOB_TOGGLE, 0x30),//SD_CMD
173         GEN_GPIO_SEL(12, 3, SDIO_INTR_OOB_TOGGLE, 0x04),//MTDI
174         GEN_GPIO_SEL(13, 3, SDIO_INTR_OOB_TOGGLE, 0x08),//MTCK
175         GEN_GPIO_SEL(14, 3, SDIO_INTR_OOB_TOGGLE, 0x0C),//MTMS
176         GEN_GPIO_SEL(15, 3, SDIO_INTR_OOB_TOGGLE, 0x10),//MTDO
177         //pls do not change sel before, if you want to change intr mode,change the one blow
178         //GEN_GPIO_SEL(2, 0, SDIO_INTR_OOB_TOGGLE, 0x38)
179         GEN_GPIO_SEL(2, 0, SDIO_INTR_OOB_LOW_LEVEL, 0x38)
180 };
181 #if defined(USE_EXT_GPIO)
182 u16 gpio_forbidden = 0;
183 #endif
184
185 int sif_interrupt_target(struct esp_pub *epub, u8 index)
186 {
187         u8 low_byte = BIT(index);
188         return esp_common_writebyte_with_addr(epub, SLC_HOST_CONF_W4 + 2, low_byte, ESP_SIF_NOSYNC);
189         
190 }
191
192 #ifdef USE_EXT_GPIO
193 int sif_config_gpio_mode(struct esp_pub *epub, u8 gpio_num, u8 gpio_mode)
194 {
195         u32 *p_tbuf = NULL;
196         int err;
197     
198         if((BIT(gpio_num) & gpio_forbidden) || gpio_num > 15)
199                 return -EINVAL;    
200
201         p_tbuf = kzalloc(sizeof(u32), GFP_KERNEL);
202         if(p_tbuf == NULL)
203                 return -ENOMEM;
204         *p_tbuf = (gpio_mode << 16) | gpio_sel_sets[gpio_num];
205         err = esp_common_write_with_addr(epub, SLC_HOST_CONF_W1, (u8*)p_tbuf, sizeof(u32), ESP_SIF_NOSYNC);
206         kfree(p_tbuf);
207         if (err)
208                 return err;
209         
210         return sif_interrupt_target(epub, 4);
211 }
212
213 int sif_set_gpio_output(struct esp_pub *epub, u16 mask, u16 value)
214 {
215         u32 *p_tbuf = NULL;
216         int err;
217         
218         mask &= ~gpio_forbidden;
219         p_tbuf = kzalloc(sizeof(u32), GFP_KERNEL);
220         if(p_tbuf == NULL)
221                 return -ENOMEM;
222         *p_tbuf = (mask << 16) | value;
223         err = esp_common_write_with_addr(epub, SLC_HOST_CONF_W2, (u8*)p_tbuf, sizeof(u32), ESP_SIF_NOSYNC);
224         kfree(p_tbuf);
225         if (err)
226                 return err;
227         
228         return sif_interrupt_target(epub, 5);
229 }
230
231 int sif_get_gpio_intr(struct esp_pub *epub, u16 intr_mask, u16 *value)
232 {
233         u32 *p_tbuf = NULL;
234         int err;
235         
236         p_tbuf = kzalloc(sizeof(u32), GFP_KERNEL);
237         if(p_tbuf == NULL)
238                 return -ENOMEM;
239         *p_tbuf = 0;
240         err = esp_common_read_with_addr(epub, SLC_HOST_CONF_W3, (u8*)p_tbuf, sizeof(u32), ESP_SIF_NOSYNC);
241         if (err){
242                 kfree(p_tbuf);
243                 return err;
244         }
245
246         *value = *p_tbuf & intr_mask;
247         kfree(p_tbuf);
248         if(*value == 0)
249                 return 0;
250         return sif_interrupt_target(epub, 6);
251 }
252
253 int sif_get_gpio_input(struct esp_pub *epub, u16 *mask, u16 *value)
254 {
255         u32 *p_tbuf = NULL;
256         int err;
257         
258         err = sif_interrupt_target(epub, 3);
259         if (err)
260                 return err;
261
262         udelay(20);
263         p_tbuf = kzalloc(sizeof(u32), GFP_KERNEL);
264         if(p_tbuf == NULL)
265                 return -ENOMEM;
266         *p_tbuf = 0;
267         err = esp_common_read_with_addr(epub, SLC_HOST_CONF_W3, (u8*)p_tbuf, sizeof(u32), ESP_SIF_NOSYNC);
268         if (err){
269                 kfree(p_tbuf);
270                 return err;
271         }
272
273         *mask = *p_tbuf >> 16;
274         *value = *p_tbuf & *mask;
275         kfree(p_tbuf);
276         
277         return 0;
278 }
279 #endif
280
281 void sif_raw_dummy_read(struct esp_pub *epub ,int ext_gpio)
282 {
283 #if 0 
284         int retry = 0;
285         u32 *p_tbuf = NULL;
286         static u32 read_err_cnt = 0;
287         static u32 write_err_cnt = 0;
288         static u32 unknow_err_cnt = 0;
289         static u32 check_cnt = 0;
290         int ext_cnt = 0;  
291         int dummy_time = 0;
292 #ifdef ESP_USE_SPI    
293     int read_err = 0;
294     int write_err = 0;
295     int sleep_time = 0;
296 #endif
297  
298     return ;
299         if (atomic_read(&epub->ps.state) == ESP_PM_ON ||ext_gpio == 1 ) {
300
301
302 //      if (atomic_read(&epub->ps.state) == ESP_PM_ON ) {
303     atomic_set(&epub->ps.state, ESP_PM_OFF);
304         } else {
305                 return ;
306         }
307
308         p_tbuf = kzalloc(sizeof(u32), GFP_KERNEL);
309         ESSERT(p_tbuf != NULL);
310         //*p_tbuf = 0;
311                 
312     //  *p_tbuf = 0x010001ff;
313
314     *p_tbuf = 0x01;
315
316
317 #ifdef ESP_USE_SPI
318     write_err = sif_spi_epub_write_mix_nosync(epub, SLC_HOST_CONF_W4+3, (u8 *)p_tbuf, 1, DUMMYMODE,0);
319     if(write_err == -4)
320     {
321         sleep_time ++;
322     }
323 #else
324     esp_common_write_with_addr(epub, SLC_HOST_CONF_W4+3, (u8 *)p_tbuf, 1, ESP_SIF_NOSYNC);
325 #endif
326         do {
327         dummy_time++;
328                 *p_tbuf = 0xffffffff;
329                 udelay(20);
330 #ifdef ESP_USE_SPI
331         read_err = sif_spi_epub_read_mix_nosync(epub, SLC_HOST_CONF_W4, (u8 *)p_tbuf, sizeof(u32), DUMMYMODE,0);
332         if(read_err == -4 || read_err == -5)
333         {
334             sleep_time ++;
335         }
336 #else
337                 esp_common_read_with_addr(epub, SLC_HOST_CONF_W4, (u8 *)p_tbuf, sizeof(u32), ESP_SIF_NOSYNC);
338 #endif
339         if(dummy_time > 10)
340             esp_dbg(ESP_DBG_ERROR, "w4 = %x,dummy time = %d\n",p_tbuf[0],dummy_time);
341
342                 if(*p_tbuf == 0x020001ff){
343 #ifdef ESP_USE_SPI
344 #if 0
345                         if(--ext_cnt >= 0){
346                                 mdelay(2);
347                                 esp_common_write_with_addr(epub, SLC_HOST_CONF_W4, (u8 *)p_tbuf, sizeof(u32), ESP_SIF_NOSYNC);
348                                 retry = -1;
349                                 continue;
350                         }
351 #endif
352 #endif
353                         break;
354                 }
355                 
356                 if(*p_tbuf == 0x010001ff){
357                         if(retry < 5)
358                                 continue;
359                 }else if(*p_tbuf == 0x000001ff){
360                         write_err_cnt++;
361                         ext_cnt = 5;
362                 }else if(*p_tbuf == 0xffffffff){
363                         read_err_cnt++;
364                 //      write_err_cnt++;
365                         ext_cnt = 5;
366                 }else {
367                         unknow_err_cnt++;
368                         ext_cnt = 5;
369                 }
370
371         //      *p_tbuf = 0x010001ff;
372         *p_tbuf = 0x01;
373                 udelay(20);
374 #ifdef ESP_USE_SPI
375         write_err = sif_spi_epub_write_mix_nosync(epub, SLC_HOST_CONF_W4+3, (u8 *)p_tbuf, 1, DUMMYMODE,0);
376         if(write_err == -4)
377         {
378             sleep_time ++;
379         }
380 #else
381         esp_common_write_with_addr(epub, SLC_HOST_CONF_W4+3, (u8 *)p_tbuf, 1, ESP_SIF_NOSYNC);
382 #endif
383         } while (retry++ < 1000);
384         
385         kfree(p_tbuf);
386
387         if(read_err_cnt || write_err_cnt || unknow_err_cnt){
388                 if((check_cnt & 0xf) == 0)
389                         //esp_dbg(ESP_DBG_ERROR, "==============sdio err===============\n,read:%u, write:%u, unknow:%u\n", read_err_cnt,write_err_cnt,unknow_err_cnt);
390                         esp_dbg(ESP_DBG_ERROR, "r%u,w%u,u%u\n", read_err_cnt,write_err_cnt,unknow_err_cnt);
391                 check_cnt++;
392         }
393 #ifdef ESP_USE_SPI
394     if(sleep_time >2)
395     {
396         esp_dbg(ESP_DBG_ERROR, "spierr sleep_time = %d,read_err = %d,write_err = %d\n", sleep_time,read_err,write_err);
397     }
398 #endif
399
400    //     if (retry > 1) {
401  //               esp_dbg(ESP_DBG_ERROR, "=========%s tried %d times===========\n", __func__, retry - 1);
402                 //if (retry>=100)
403                 //        ESSERT(0);
404      //   }
405 #else
406         return;
407 #endif /* disable dummy read func */
408 }
409
410 void check_target_id(struct esp_pub *epub)
411 {
412         u32 date;
413         int err = 0;
414         int i;
415
416         EPUB_CTRL_CHECK(epub, _err);
417
418         sif_lock_bus(epub);
419
420         for(i = 0; i < 4; i++) {
421                 err = esp_common_readbyte_with_addr(epub, SLC_HOST_DATE + i, (u8 *)&date + i, ESP_SIF_NOSYNC);
422                 err = esp_common_readbyte_with_addr(epub, SLC_HOST_ID + i, (u8 *)&EPUB_TO_CTRL(epub)->target_id + i, ESP_SIF_NOSYNC);
423         }
424
425         sif_unlock_bus(epub);
426
427         esp_dbg(ESP_DBG_LOG, "\n\n \t\t SLC data 0x%08x, ID 0x%08x\n\n", date, EPUB_TO_CTRL(epub)->target_id);
428
429         switch(EPUB_TO_CTRL(epub)->target_id) {
430         case 0x100:
431                 EPUB_TO_CTRL(epub)->slc_window_end_addr = 0x20000;
432                 break;
433         case 0x600:
434                 EPUB_TO_CTRL(epub)->slc_window_end_addr = 0x20000 - 0x800;
435
436                 do{
437                         u16 gpio_sel;
438                         u8 low_byte = 0;
439                         u8 high_byte = 0;
440                         u8 byte2 = 0;
441                         u8 byte3 = 0;
442 #ifdef USE_OOB_INTR 
443                         gpio_sel = gpio_sel_sets[16];
444                         low_byte = gpio_sel;
445                         high_byte = gpio_sel >> 8;
446 #ifdef USE_EXT_GPIO
447                         gpio_forbidden |= BIT(gpio_sel & 0xf);
448 #endif /* USE_EXT_GPIO */
449 #endif /* USE_OOB_INTR */
450
451                         if(sif_get_bt_config() == 1 && sif_get_rst_config() != 1){
452                                 u8 gpio_num = sif_get_wakeup_gpio_config();
453                                 gpio_sel = gpio_sel_sets[gpio_num];
454                                 byte2 = gpio_sel;
455                                 byte3 = gpio_sel >> 8;
456 #ifdef USE_EXT_GPIO
457                                 gpio_forbidden |= BIT(gpio_num);
458 #endif
459                         }
460                         sif_lock_bus(epub);
461                         err = esp_common_writebyte_with_addr(epub, SLC_HOST_CONF_W1, low_byte, ESP_SIF_NOSYNC);
462                         err = esp_common_writebyte_with_addr(epub, SLC_HOST_CONF_W1 + 1, high_byte, ESP_SIF_NOSYNC);
463                         err = esp_common_writebyte_with_addr(epub, SLC_HOST_CONF_W1 + 2, byte2, ESP_SIF_NOSYNC);
464                         err = esp_common_writebyte_with_addr(epub, SLC_HOST_CONF_W1 + 3, byte3, ESP_SIF_NOSYNC);
465                         sif_unlock_bus(epub);
466                 }while(0);
467                 break;
468         default:
469                 EPUB_TO_CTRL(epub)->slc_window_end_addr = 0x20000;
470                 break;
471         }
472 _err:
473         return;
474 }
475
476 u32 sif_get_blksz(struct esp_pub *epub)
477 {
478         EPUB_CTRL_CHECK(epub, _err);
479
480         return EPUB_TO_CTRL(epub)->slc_blk_sz;
481 _err:
482         return 512;
483 }
484
485 u32 sif_get_target_id(struct esp_pub *epub)
486 {
487         EPUB_CTRL_CHECK(epub, _err);
488
489         return EPUB_TO_CTRL(epub)->target_id;
490 _err:
491         return 0x600;
492 }
493
494
495 #ifdef SIF_CHECK_FIRST_INTR
496 static bool first_intr_checked = false;
497 #endif //SIF_CHECK_FIRST_INTR
498
499 #ifdef ESP_USE_SDIO
500 void sif_dsr(struct sdio_func *func)
501 {
502         struct esp_sdio_ctrl *sctrl = sdio_get_drvdata(func);
503 #else
504 void sif_dsr(struct spi_device *spi)
505 {
506         struct esp_spi_ctrl *sctrl = spi_get_drvdata(spi);
507         char buf[4];
508 #endif
509 #ifdef SIF_DSR_WAR
510         static int dsr_cnt = 0, real_intr_cnt = 0, bogus_intr_cnt = 0;
511         struct slc_host_regs *regs = &(sctrl->slc_regs);
512        esp_dbg(ESP_DBG_TRACE, " %s enter %d \n", __func__, dsr_cnt++);
513 #endif /* SIF_DSR_WAR */
514
515 #ifdef ESP_USE_SPI
516
517        if(sctrl->epub->wait_reset == 1)
518        {
519            mdelay(50);
520            return;
521        }
522
523        if(sctrl->epub->enable_int  == 1)
524        {
525            sif_spi_epub_read_mix_sync(sctrl->epub, 0x3, buf, 512, NOT_DUMMYMODE,1);
526            buf[0]=buf[0]|(1<<2);
527            buf[2]=buf[2]& 0xfd;
528            sif_spi_epub_write_mix_sync(sctrl->epub, 0x3, buf, 512, NOT_DUMMYMODE,1);
529
530            sctrl->epub->enable_int = 0;
531         }
532 #endif
533         atomic_set(&sctrl->irq_handling, 1);
534
535 #ifdef ESP_USE_SDIO
536         sdio_release_host(sctrl->func);
537 #endif
538
539
540         sif_lock_bus(sctrl->epub);
541
542
543 #ifdef SIF_DSR_WAR
544         do {
545                 int ret =0;
546 #ifdef SIF_CHECK_FIRST_INTR 
547                 if (likely(first_intr_checked)) {
548                         esp_dsr(sctrl->epub);
549                         break;
550                 } 
551 #endif //SIF_CHECK_FIRST_INTR
552           
553                 memset(regs, 0x0, sizeof(struct slc_host_regs));
554               
555              ret = esp_common_read_with_addr(sctrl->epub, REG_SLC_HOST_BASE + 8, (u8 *)regs, sizeof(struct slc_host_regs), ESP_SIF_NOSYNC);
556                 if ( (regs->intr_status & SLC_HOST_RX_ST) && (regs->intr_raw & SLC_HOST_RX_ST) && (ret == 0) ) {
557 #ifdef SIF_CHECK_FIRST_INTR 
558                         first_intr_checked = true;
559 #endif //SIF_CHECK_FIRST_INTR
560                         esp_dbg(ESP_DBG_TRACE, "%s eal intr cnt: %d", __func__, ++real_intr_cnt);
561                 
562                         esp_dsr(sctrl->epub);
563
564                 } else {
565 #ifdef ESP_ACK_INTERRUPT
566                         sif_platform_ack_interrupt(sctrl->epub);
567 #endif //ESP_ACK_INTERRUPT
568                         sif_unlock_bus(sctrl->epub);
569
570                         esp_dbg(ESP_DBG_TRACE, "%s bogus_intr_cnt %d\n", __func__, ++bogus_intr_cnt);
571                 }
572
573 #ifdef SIF_DEBUG_DSR_DUMP_REG
574                 dump_slc_regs(regs);
575 #endif /* SIF_DEBUG_DUMP_DSR */
576
577         } while (0);
578
579 #else
580         esp_dsr(sctrl->epub);
581 #endif /* SIF_DSR_WAR */
582
583 #ifdef ESP_USE_SDIO
584         sdio_claim_host(func);
585 #endif
586
587         atomic_set(&sctrl->irq_handling, 0);
588 }
589
590
591 struct slc_host_regs * sif_get_regs(struct esp_pub *epub) 
592 {
593         EPUB_CTRL_CHECK(epub, _err);
594
595         return &EPUB_TO_CTRL(epub)->slc_regs;
596 _err:
597         return NULL;
598 }
599
600 void sif_disable_target_interrupt(struct esp_pub *epub)
601 {
602         EPUB_FUNC_CHECK(epub, _exit);
603         sif_lock_bus(epub);
604 #ifdef HOST_RESET_BUG
605         mdelay(10);
606 #endif
607         sif_raw_dummy_read(epub,0);
608         memset(EPUB_TO_CTRL(epub)->dma_buffer, 0x00, sizeof(u32));
609         esp_common_write_with_addr(epub, SLC_HOST_INT_ENA, EPUB_TO_CTRL(epub)->dma_buffer, sizeof(u32), ESP_SIF_NOSYNC);
610 #ifdef HOST_RESET_BUG
611         mdelay(10);
612 #endif
613
614         sif_unlock_bus(epub);
615
616         mdelay(1);      
617
618         sif_lock_bus(epub);
619         sif_raw_dummy_read(epub,0);
620         sif_interrupt_target(epub, 7);
621         sif_unlock_bus(epub);
622 _exit:
623         return;
624 }
625
626 #ifdef SIF_DEBUG_DSR_DUMP_REG
627 static void dump_slc_regs(struct slc_host_regs *regs) 
628 {
629         esp_dbg(ESP_DBG_TRACE, "\n\n ------- %s --------------\n", __func__);
630
631         esp_dbg(ESP_DBG_TRACE, " \
632                         intr_raw 0x%08X \t \n  \
633                         state_w0 0x%08X \t state_w1 0x%08X \n  \
634                         config_w0 0x%08X \t config_w1 0x%08X \n \
635                         intr_status 0x%08X \t config_w2 0x%08X \n \
636                         config_w3 0x%08X \t config_w4 0x%08X \n \
637                         token_wdata 0x%08X \t intr_clear 0x%08X \n \
638                         intr_enable 0x%08X \n\n", regs->intr_raw, \
639                         regs->state_w0, regs->state_w1, regs->config_w0, regs->config_w1, \
640                         regs->intr_status, \
641                         regs->config_w2, regs->config_w3, regs->config_w4, regs->token_wdata, \
642                         regs->intr_clear, regs->intr_enable);
643 }
644 #endif /* SIF_DEBUG_DSR_DUMP_REG */
645
646 static int bt_config = 0;
647 void sif_record_bt_config(int value)
648 {
649         bt_config = value;
650 }
651
652 int sif_get_bt_config(void)
653 {
654         return bt_config;
655 }
656
657 static int rst_config = 0;
658 void sif_record_rst_config(int value)
659 {
660         rst_config = value;
661 }
662
663 int sif_get_rst_config(void)
664 {
665         return rst_config;
666 }
667
668 static int ate_test = 0;
669 void sif_record_ate_config(int value)
670 {
671     ate_test =value;
672 }
673
674 int sif_get_ate_config(void)
675 {
676     return ate_test;
677 }
678
679 static int retry_reset = 0;
680 void sif_record_retry_config(void)
681 {
682         retry_reset = 1;
683 }
684
685 int sif_get_retry_config(void)
686 {
687         return retry_reset;
688 }
689
690 static int wakeup_gpio = 12;
691 void sif_record_wakeup_gpio_config(int value)
692 {
693         wakeup_gpio = value;
694 }
695
696 int sif_get_wakeup_gpio_config(void)
697 {
698         return wakeup_gpio;
699 }
700
701