OLD | NEW |
1 //------------------------------------------------------------------------------ | 1 //------------------------------------------------------------------------------ |
2 // <copyright file="hif.c" company="Atheros"> | 2 // <copyright file="hif.c" company="Atheros"> |
3 // Copyright (c) 2004-2008 Atheros Corporation. All rights reserved. | 3 // Copyright (c) 2004-2010 Atheros Corporation. All rights reserved. |
4 // | 4 // |
5 // This program is free software; you can redistribute it and/or modify | |
6 // it under the terms of the GNU General Public License version 2 as | |
7 // published by the Free Software Foundation; | |
8 // | 5 // |
9 // Software distributed under the License is distributed on an "AS | 6 // Permission to use, copy, modify, and/or distribute this software for any |
10 // IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or | 7 // purpose with or without fee is hereby granted, provided that the above |
11 // implied. See the License for the specific language governing | 8 // copyright notice and this permission notice appear in all copies. |
12 // rights and limitations under the License. | 9 // |
| 10 // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
| 11 // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
| 12 // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
| 13 // ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
| 14 // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
| 15 // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
| 16 // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
13 // | 17 // |
14 // | 18 // |
15 //------------------------------------------------------------------------------ | 19 //------------------------------------------------------------------------------ |
16 //============================================================================== | 20 //============================================================================== |
17 // HIF layer reference implementation for Linux Native MMC stack | 21 // HIF layer reference implementation for Linux Native MMC stack |
18 // | 22 // |
19 // Author(s): ="Atheros" | 23 // Author(s): ="Atheros" |
20 //============================================================================== | 24 //============================================================================== |
21 #include <linux/mmc/card.h> | 25 #include <linux/mmc/card.h> |
22 #include <linux/mmc/mmc.h> | 26 #include <linux/mmc/mmc.h> |
23 #include <linux/mmc/host.h> | 27 #include <linux/mmc/host.h> |
24 #include <linux/mmc/sdio_func.h> | 28 #include <linux/mmc/sdio_func.h> |
25 #include <linux/mmc/sdio_ids.h> | 29 #include <linux/mmc/sdio_ids.h> |
26 #include <linux/mmc/sdio.h> | 30 #include <linux/mmc/sdio.h> |
| 31 #include <linux/mmc/sd.h> |
27 #include <linux/kthread.h> | 32 #include <linux/kthread.h> |
28 | 33 |
29 /* by default setup a bounce buffer for the data packets, if the underlying host
controller driver | 34 /* by default setup a bounce buffer for the data packets, if the underlying host
controller driver |
30 does not use DMA you may be able to skip this step and save the memory alloca
tion and transfer time */ | 35 does not use DMA you may be able to skip this step and save the memory alloca
tion and transfer time */ |
31 #define HIF_USE_DMA_BOUNCE_BUFFER 1 | 36 #define HIF_USE_DMA_BOUNCE_BUFFER 1 |
32 #include "hif_internal.h" | 37 #include "hif_internal.h" |
33 #define ATH_MODULE_NAME hif | 38 #define ATH_MODULE_NAME hif |
34 #include "a_debug.h" | 39 #include "a_debug.h" |
35 #include "AR6002/hw2.0/hw/mbox_host_reg.h" | 40 #include "AR6002/hw2.0/hw/mbox_host_reg.h" |
36 | 41 |
37 #if HIF_USE_DMA_BOUNCE_BUFFER | 42 #if HIF_USE_DMA_BOUNCE_BUFFER |
38 /* macro to check if DMA buffer is WORD-aligned and DMA-able. Most host control
lers assume the | 43 /* macro to check if DMA buffer is WORD-aligned and DMA-able. Most host control
lers assume the |
39 * buffer is DMA'able and will bug-check otherwise (i.e. buffers on the stack).
| 44 * buffer is DMA'able and will bug-check otherwise (i.e. buffers on the stack).
|
40 * virt_addr_valid check fails on stack memory. | 45 * virt_addr_valid check fails on stack memory. |
41 */ | 46 */ |
42 #define BUFFER_NEEDS_BOUNCE(buffer) (((A_UINT32)(buffer) & 0x3) || !virt_addr_v
alid((buffer))) | 47 #define BUFFER_NEEDS_BOUNCE(buffer) (((unsigned long)(buffer) & 0x3) || !virt_a
ddr_valid((buffer))) |
43 #else | 48 #else |
44 #define BUFFER_NEEDS_BOUNCE(buffer) (FALSE) | 49 #define BUFFER_NEEDS_BOUNCE(buffer) (FALSE) |
45 #endif | 50 #endif |
46 | 51 |
47 /* ATHENV */ | 52 /* ATHENV */ |
48 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) && defined(CONFIG_PM) | 53 #if defined(CONFIG_PM) |
49 #define dev_to_sdio_func(d) container_of(d, struct sdio_func, dev) | 54 #define dev_to_sdio_func(d) container_of(d, struct sdio_func, dev) |
50 #define to_sdio_driver(d) container_of(d, struct sdio_driver, drv) | 55 #define to_sdio_driver(d) container_of(d, struct sdio_driver, drv) |
51 static int hifDeviceSuspend(struct device *dev); | 56 static int hifDeviceSuspend(struct device *dev); |
52 static int hifDeviceResume(struct device *dev); | 57 static int hifDeviceResume(struct device *dev); |
53 #endif /* CONFIG_PM */ | 58 #endif /* CONFIG_PM */ |
54 static int hifDeviceInserted(struct sdio_func *func, const struct sdio_device_id
*id); | 59 static int hifDeviceInserted(struct sdio_func *func, const struct sdio_device_id
*id); |
55 static void hifDeviceRemoved(struct sdio_func *func); | 60 static void hifDeviceRemoved(struct sdio_func *func); |
56 static HIF_DEVICE *addHifDevice(struct sdio_func *func); | 61 static HIF_DEVICE *addHifDevice(struct sdio_func *func); |
57 static HIF_DEVICE *getHifDevice(struct sdio_func *func); | 62 static HIF_DEVICE *getHifDevice(struct sdio_func *func); |
58 static void delHifDevice(HIF_DEVICE * device); | 63 static void delHifDevice(HIF_DEVICE * device); |
59 static int Func0_CMD52WriteByte(struct mmc_card *card, unsigned int address, uns
igned char byte); | 64 static int Func0_CMD52WriteByte(struct mmc_card *card, unsigned int address, uns
igned char byte); |
| 65 static int Func0_CMD52ReadByte(struct mmc_card *card, unsigned int address, unsi
gned char *byte); |
60 | 66 |
61 int reset_sdio_on_unload = 0; | 67 int reset_sdio_on_unload = 0; |
62 module_param(reset_sdio_on_unload, int, 0644); | 68 module_param(reset_sdio_on_unload, int, 0644); |
63 | 69 |
64 extern A_UINT32 nohifscattersupport; | 70 extern A_UINT32 nohifscattersupport; |
65 | 71 |
66 | 72 |
67 /* ------ Static Variables ------ */ | 73 /* ------ Static Variables ------ */ |
68 static const struct sdio_device_id ar6k_id_table[] = { | 74 static const struct sdio_device_id ar6k_id_table[] = { |
69 { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6002_BASE | 0x0)) }, | 75 { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6002_BASE | 0x0)) }, |
70 { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6002_BASE | 0x1)) }, | 76 { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6002_BASE | 0x1)) }, |
71 { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6003_BASE | 0x0)) }, | 77 { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6003_BASE | 0x0)) }, |
72 { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6003_BASE | 0x1)) }, | 78 { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6003_BASE | 0x1)) }, |
73 { /* null */ }, | 79 { /* null */ }, |
74 }; | 80 }; |
75 MODULE_DEVICE_TABLE(sdio, ar6k_id_table); | 81 MODULE_DEVICE_TABLE(sdio, ar6k_id_table); |
76 | 82 |
77 static struct sdio_driver ar6k_driver = { | 83 static struct sdio_driver ar6k_driver = { |
78 .name = "ar6k_wlan", | 84 .name = "ar6k_wlan", |
79 .id_table = ar6k_id_table, | 85 .id_table = ar6k_id_table, |
80 .probe = hifDeviceInserted, | 86 .probe = hifDeviceInserted, |
81 .remove = hifDeviceRemoved, | 87 .remove = hifDeviceRemoved, |
82 }; | 88 }; |
83 | 89 |
84 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) && defined(CONFIG_PM) | 90 #if defined(CONFIG_PM) |
85 /* New suspend/resume based on linux-2.6.32 | 91 /* New suspend/resume based on linux-2.6.32 |
86 * Need to patch linux-2.6.32 with mmc2.6.32_suspend.patch | 92 * Need to patch linux-2.6.32 with mmc2.6.32_suspend.patch |
87 * Need to patch with msmsdcc2.6.29_suspend.patch for msm_sdcc host | 93 * Need to patch with msmsdcc2.6.29_suspend.patch for msm_sdcc host |
88 */ | 94 */ |
89 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29) | |
90 static struct dev_pm_ops ar6k_device_pm_ops = { | 95 static struct dev_pm_ops ar6k_device_pm_ops = { |
91 #else | |
92 static struct pm_ops ar6k_device_pm_ops = { | |
93 #endif | |
94 .suspend = hifDeviceSuspend, | 96 .suspend = hifDeviceSuspend, |
95 .resume = hifDeviceResume, | 97 .resume = hifDeviceResume, |
96 }; | 98 }; |
97 #endif /* CONFIG_PM */ | 99 #endif /* CONFIG_PM */ |
98 | 100 |
99 /* make sure we only unregister when registered. */ | 101 /* make sure we only unregister when registered. */ |
100 static int registered = 0; | 102 static int registered = 0; |
101 | 103 |
102 OSDRV_CALLBACKS osdrvCallbacks; | 104 OSDRV_CALLBACKS osdrvCallbacks; |
103 extern A_UINT32 onebitmode; | 105 extern A_UINT32 onebitmode; |
104 extern A_UINT32 busspeedlow; | 106 extern A_UINT32 busspeedlow; |
105 extern A_UINT32 debughif; | 107 extern A_UINT32 debughif; |
106 | 108 |
107 static void ResetAllCards(void); | 109 static void ResetAllCards(void); |
| 110 static A_STATUS hifDisableFunc(HIF_DEVICE *device, struct sdio_func *func); |
| 111 static A_STATUS hifEnableFunc(HIF_DEVICE *device, struct sdio_func *func); |
108 | 112 |
109 #ifdef DEBUG | 113 #ifdef DEBUG |
110 | 114 |
111 ATH_DEBUG_INSTANTIATE_MODULE_VAR(hif, | 115 ATH_DEBUG_INSTANTIATE_MODULE_VAR(hif, |
112 "hif", | 116 "hif", |
113 "(Linux MMC) Host Interconnect Framework", | 117 "(Linux MMC) Host Interconnect Framework", |
114 ATH_DEBUG_MASK_DEFAULTS, | 118 ATH_DEBUG_MASK_DEFAULTS, |
115 0, | 119 0, |
116 NULL); | 120 NULL); |
117 | 121 |
118 #endif | 122 #endif |
119 | 123 |
120 | 124 |
121 /* ------ Functions ------ */ | 125 /* ------ Functions ------ */ |
122 A_STATUS HIFInit(OSDRV_CALLBACKS *callbacks) | 126 A_STATUS HIFInit(OSDRV_CALLBACKS *callbacks) |
123 { | 127 { |
124 int status; | 128 int status; |
125 AR_DEBUG_ASSERT(callbacks != NULL); | 129 AR_DEBUG_ASSERT(callbacks != NULL); |
126 | 130 |
127 A_REGISTER_MODULE_DEBUG_INFO(hif); | 131 A_REGISTER_MODULE_DEBUG_INFO(hif); |
128 | 132 |
129 /* store the callback handlers */ | 133 /* store the callback handlers */ |
130 osdrvCallbacks = *callbacks; | 134 osdrvCallbacks = *callbacks; |
131 | 135 |
132 /* Register with bus driver core */ | 136 /* Register with bus driver core */ |
133 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: HIFInit registering\n")); | 137 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: HIFInit registering\n")); |
134 registered = 1; | 138 registered = 1; |
135 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) && defined(CONFIG_PM) | 139 #if defined(CONFIG_PM) |
136 if (callbacks->deviceSuspendHandler && callbacks->deviceResumeHandler) { | 140 if (callbacks->deviceSuspendHandler && callbacks->deviceResumeHandler) { |
137 ar6k_driver.drv.pm = &ar6k_device_pm_ops; | 141 ar6k_driver.drv.pm = &ar6k_device_pm_ops; |
138 } | 142 } |
139 #endif /* CONFIG_PM */ | 143 #endif /* CONFIG_PM */ |
140 status = sdio_register_driver(&ar6k_driver); | 144 status = sdio_register_driver(&ar6k_driver); |
141 AR_DEBUG_ASSERT(status==0); | 145 AR_DEBUG_ASSERT(status==0); |
142 | 146 |
143 if (status != 0) { | 147 if (status != 0) { |
144 return A_ERROR; | 148 return A_ERROR; |
145 } | 149 } |
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
356 } | 360 } |
357 busrequest->address = address; | 361 busrequest->address = address; |
358 busrequest->buffer = buffer; | 362 busrequest->buffer = buffer; |
359 busrequest->length = length; | 363 busrequest->length = length; |
360 busrequest->request = request; | 364 busrequest->request = request; |
361 busrequest->context = context; | 365 busrequest->context = context; |
362 | 366 |
363 AddToAsyncList(device, busrequest); | 367 AddToAsyncList(device, busrequest); |
364 | 368 |
365 if (request & HIF_SYNCHRONOUS) { | 369 if (request & HIF_SYNCHRONOUS) { |
366 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: queued sync req: 0x%X
\n", (unsigned int)busrequest)); | 370 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: queued sync req: 0x%l
X\n", (unsigned long)busrequest)); |
367 | 371 |
368 /* wait for completion */ | 372 /* wait for completion */ |
369 up(&device->sem_async); | 373 up(&device->sem_async); |
370 if (down_interruptible(&busrequest->sem_req) != 0) { | 374 if (down_interruptible(&busrequest->sem_req) != 0) { |
371 /* interrupted, exit */ | 375 /* interrupted, exit */ |
372 return A_ERROR; | 376 return A_ERROR; |
373 } else { | 377 } else { |
374 A_STATUS status = busrequest->status; | 378 A_STATUS status = busrequest->status; |
375 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: sync return freei
ng 0x%X: 0x%X\n", | 379 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: sync return freei
ng 0x%lX: 0x%X\n", |
376 » » » » » » (unsigned int)busrequest,
busrequest->status)); | 380 » » » » » » (unsigned long)busrequest,
busrequest->status)); |
377 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: freeing req: 0x%X
\n", (unsigned int)request)); | 381 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: freeing req: 0x%X
\n", (unsigned int)request)); |
378 hifFreeBusRequest(device, busrequest); | 382 hifFreeBusRequest(device, busrequest); |
379 return status; | 383 return status; |
380 } | 384 } |
381 } else { | 385 } else { |
382 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: queued async req: 0x%
X\n", (unsigned int)busrequest)); | 386 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: queued async req: 0x%
lX\n", (unsigned long)busrequest)); |
383 up(&device->sem_async); | 387 up(&device->sem_async); |
384 return A_PENDING; | 388 return A_PENDING; |
385 } | 389 } |
386 } else { | 390 } else { |
387 AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, | 391 AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, |
388 ("AR6000: Invalid execution mode: 0x%08x\n", (unsign
ed int)request)); | 392 ("AR6000: Invalid execution mode: 0x%08x\n", (unsign
ed int)request)); |
389 status = A_EINVAL; | 393 status = A_EINVAL; |
390 break; | 394 break; |
391 } | 395 } |
392 } while(0); | 396 } while(0); |
(...skipping 27 matching lines...) Expand all Loading... |
420 spin_lock_irqsave(&device->asynclock, flags); | 424 spin_lock_irqsave(&device->asynclock, flags); |
421 /* pull the request to work on */ | 425 /* pull the request to work on */ |
422 while (device->asyncreq != NULL) { | 426 while (device->asyncreq != NULL) { |
423 request = device->asyncreq; | 427 request = device->asyncreq; |
424 if (request->inusenext != NULL) { | 428 if (request->inusenext != NULL) { |
425 device->asyncreq = request->inusenext; | 429 device->asyncreq = request->inusenext; |
426 } else { | 430 } else { |
427 device->asyncreq = NULL; | 431 device->asyncreq = NULL; |
428 } | 432 } |
429 spin_unlock_irqrestore(&device->asynclock, flags); | 433 spin_unlock_irqrestore(&device->asynclock, flags); |
430 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async_task processing req
: 0x%X\n", (unsigned int)request)); | 434 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async_task processing req
: 0x%lX\n", (unsigned long)request)); |
431 | 435 |
432 if (request->pScatterReq != NULL) { | 436 if (request->pScatterReq != NULL) { |
433 A_ASSERT(device->scatter_enabled); | 437 A_ASSERT(device->scatter_enabled); |
434 /* this is a queued scatter request, pass the request to sca
tter routine which | 438 /* this is a queued scatter request, pass the request to sca
tter routine which |
435 * executes it synchronously, note, no need to free the requ
est since scatter requests | 439 * executes it synchronously, note, no need to free the requ
est since scatter requests |
436 * are maintained on a separate list */ | 440 * are maintained on a separate list */ |
437 status = DoHifReadWriteScatter(device,request); | 441 status = DoHifReadWriteScatter(device,request); |
438 } else { | 442 } else { |
439 /* call HIFReadWrite in sync mode to do the work */ | 443 /* call HIFReadWrite in sync mode to do the work */ |
440 status = __HIFReadWrite(device, request->address, request->buffe
r, | 444 status = __HIFReadWrite(device, request->address, request->buffe
r, |
441 request->length, request->request & ~HIF_S
YNCHRONOUS, NULL); | 445 request->length, request->request & ~HIF_S
YNCHRONOUS, NULL); |
442 if (request->request & HIF_ASYNCHRONOUS) { | 446 if (request->request & HIF_ASYNCHRONOUS) { |
443 void *context = request->context; | 447 void *context = request->context; |
444 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async_task freein
g req: 0x%X\n", (unsigned int)request)); | 448 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async_task freein
g req: 0x%lX\n", (unsigned long)request)); |
445 hifFreeBusRequest(device, request); | 449 hifFreeBusRequest(device, request); |
446 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async_task comple
tion routine req: 0x%X\n", (unsigned int)request)); | 450 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async_task comple
tion routine req: 0x%lX\n", (unsigned long)request)); |
447 device->htcCallbacks.rwCompletionHandler(context, status); | 451 device->htcCallbacks.rwCompletionHandler(context, status); |
448 } else { | 452 } else { |
449 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async_task upping
req: 0x%X\n", (unsigned int)request)); | 453 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async_task upping
req: 0x%lX\n", (unsigned long)request)); |
450 request->status = status; | 454 request->status = status; |
451 up(&request->sem_req); | 455 up(&request->sem_req); |
452 } | 456 } |
453 } | 457 } |
454 spin_lock_irqsave(&device->asynclock, flags); | 458 spin_lock_irqsave(&device->asynclock, flags); |
455 } | 459 } |
456 spin_unlock_irqrestore(&device->asynclock, flags); | 460 spin_unlock_irqrestore(&device->asynclock, flags); |
457 sdio_release_host(device->func); | 461 sdio_release_host(device->func); |
458 } | 462 } |
459 | 463 |
460 complete_and_exit(&device->async_completion, 0); | 464 complete_and_exit(&device->async_completion, 0); |
461 return 0; | 465 return 0; |
462 } | 466 } |
| 467 |
| 468 static A_INT32 IssueSDCommand(HIF_DEVICE *device, A_UINT32 opcode, A_UINT32 arg,
A_UINT32 flags, A_UINT32 *resp) |
| 469 { |
| 470 struct mmc_command cmd; |
| 471 A_INT32 err; |
| 472 struct mmc_host *host; |
| 473 struct sdio_func *func; |
| 474 |
| 475 func = device->func; |
| 476 host = func->card->host; |
| 477 |
| 478 memset(&cmd, 0, sizeof(struct mmc_command)); |
| 479 cmd.opcode = opcode; |
| 480 cmd.arg = arg; |
| 481 cmd.flags = flags; |
| 482 err = mmc_wait_for_cmd(host, &cmd, 3); |
| 483 |
| 484 if ((!err) && (resp)) { |
| 485 *resp = cmd.resp[0]; |
| 486 } |
| 487 |
| 488 return err; |
| 489 } |
| 490 |
| 491 A_STATUS ReinitSDIO(HIF_DEVICE *device) |
| 492 { |
| 493 A_INT32 err; |
| 494 struct mmc_host *host; |
| 495 struct mmc_card *card; |
| 496 » struct sdio_func *func; |
| 497 A_UINT8 cmd52_resp; |
| 498 A_UINT32 clock; |
| 499 |
| 500 func = device->func; |
| 501 card = func->card; |
| 502 host = card->host; |
| 503 |
| 504 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +ReinitSDIO \n")); |
| 505 sdio_claim_host(func); |
| 506 |
| 507 do { |
| 508 if (!device->is_suspend) { |
| 509 A_UINT32 resp; |
| 510 A_UINT16 rca; |
| 511 A_UINT32 i; |
| 512 int bit = fls(host->ocr_avail) - 1; |
| 513 /* emulate the mmc_power_up(...) */ |
| 514 host->ios.vdd = bit; |
| 515 host->ios.chip_select = MMC_CS_DONTCARE; |
| 516 host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN; |
| 517 host->ios.power_mode = MMC_POWER_UP; |
| 518 host->ios.bus_width = MMC_BUS_WIDTH_1; |
| 519 host->ios.timing = MMC_TIMING_LEGACY; |
| 520 host->ops->set_ios(host, &host->ios); |
| 521 /* |
| 522 * This delay should be sufficient to allow the power supply |
| 523 * to reach the minimum voltage. |
| 524 */ |
| 525 msleep(2); |
| 526 |
| 527 host->ios.clock = host->f_min; |
| 528 host->ios.power_mode = MMC_POWER_ON; |
| 529 host->ops->set_ios(host, &host->ios); |
| 530 |
| 531 /* |
| 532 * This delay must be at least 74 clock sizes, or 1 ms, or the |
| 533 * time required to reach a stable voltage. |
| 534 */ |
| 535 msleep(2); |
| 536 |
| 537 /* Issue CMD0. Goto idle state */ |
| 538 » host->ios.chip_select = MMC_CS_HIGH; |
| 539 host->ops->set_ios(host, &host->ios); |
| 540 » msleep(1); |
| 541 err = IssueSDCommand(device, MMC_GO_IDLE_STATE, 0, (MMC_RSP_NONE | M
MC_CMD_BC), NULL); |
| 542 host->ios.chip_select = MMC_CS_DONTCARE; |
| 543 host->ops->set_ios(host, &host->ios); |
| 544 » msleep(1); |
| 545 host->use_spi_crc = 0; |
| 546 |
| 547 if (err) { |
| 548 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD0 failed : %d \n
",err)); |
| 549 break; |
| 550 } |
| 551 |
| 552 if (!host->ocr) { |
| 553 /* Issue CMD5, arg = 0 */ |
| 554 err = IssueSDCommand(device, SD_IO_SEND_OP_COND, 0, (MMC_RSP_R4
| MMC_CMD_BCR), &resp); |
| 555 if (err) { |
| 556 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD5 failed : %
d \n",err)); |
| 557 break; |
| 558 } |
| 559 host->ocr = resp; |
| 560 } |
| 561 |
| 562 /* Issue CMD5, arg = ocr. Wait till card is ready */ |
| 563 for (i=0;i<100;i++) { |
| 564 err = IssueSDCommand(device, SD_IO_SEND_OP_COND, host->ocr, (MMC
_RSP_R4 | MMC_CMD_BCR), &resp); |
| 565 if (err) { |
| 566 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD5 failed : %
d \n",err)); |
| 567 break; |
| 568 } |
| 569 if (resp & MMC_CARD_BUSY) { |
| 570 break; |
| 571 } |
| 572 msleep(10); |
| 573 } |
| 574 |
| 575 if ((i == 100) || (err)) { |
| 576 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: card in not ready :
%d %d \n",i,err)); |
| 577 break; |
| 578 } |
| 579 |
| 580 /* Issue CMD3, get RCA */ |
| 581 err = IssueSDCommand(device, SD_SEND_RELATIVE_ADDR, 0, MMC_RSP_R6 |
MMC_CMD_BCR, &resp); |
| 582 if (err) { |
| 583 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD3 failed : %d \n
",err)); |
| 584 break; |
| 585 } |
| 586 rca = resp >> 16; |
| 587 host->ios.bus_mode = MMC_BUSMODE_PUSHPULL; |
| 588 host->ops->set_ios(host, &host->ios); |
| 589 |
| 590 /* Issue CMD7, select card */ |
| 591 err = IssueSDCommand(device, MMC_SELECT_CARD, (rca << 16), MMC_RSP_R
1 | MMC_CMD_AC, NULL); |
| 592 if (err) { |
| 593 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD7 failed : %d \n
",err)); |
| 594 break; |
| 595 } |
| 596 } |
| 597 |
| 598 /* Enable high speed */ |
| 599 if (card->host->caps & MMC_CAP_SD_HIGHSPEED) { |
| 600 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("ReinitSDIO: Set high speed mode\n
")); |
| 601 err = Func0_CMD52ReadByte(card, SDIO_CCCR_SPEED, &cmd52_resp); |
| 602 if (err) { |
| 603 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD52 read to CCCR
speed register failed : %d \n",err)); |
| 604 card->state &= ~MMC_STATE_HIGHSPEED; |
| 605 /* no need to break */ |
| 606 } else { |
| 607 err = Func0_CMD52WriteByte(card, SDIO_CCCR_SPEED, (cmd52_resp |
SDIO_SPEED_EHS)); |
| 608 if (err) { |
| 609 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD52 write to
CCCR speed register failed : %d \n",err)); |
| 610 break; |
| 611 } |
| 612 mmc_card_set_highspeed(card); |
| 613 host->ios.timing = MMC_TIMING_SD_HS; |
| 614 host->ops->set_ios(host, &host->ios); |
| 615 } |
| 616 } |
| 617 |
| 618 /* Set clock */ |
| 619 if (mmc_card_highspeed(card)) { |
| 620 clock = 50000000; |
| 621 } else { |
| 622 clock = card->cis.max_dtr; |
| 623 } |
| 624 |
| 625 if (clock > host->f_max) { |
| 626 clock = host->f_max; |
| 627 } |
| 628 host->ios.clock = clock; |
| 629 host->ops->set_ios(host, &host->ios); |
| 630 |
| 631 |
| 632 if (card->host->caps & MMC_CAP_4_BIT_DATA) { |
| 633 /* CMD52: Set bus width & disable card detect resistor */ |
| 634 err = Func0_CMD52WriteByte(card, SDIO_CCCR_IF, SDIO_BUS_CD_DISABLE |
SDIO_BUS_WIDTH_4BIT); |
| 635 if (err) { |
| 636 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD52 to set bus mo
de failed : %d \n",err)); |
| 637 break; |
| 638 } |
| 639 host->ios.bus_width = MMC_BUS_WIDTH_4; |
| 640 host->ops->set_ios(host, &host->ios); |
| 641 } |
| 642 } while (0); |
| 643 |
| 644 sdio_release_host(func); |
| 645 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -ReinitSDIO \n")); |
| 646 |
| 647 return (err) ? A_ERROR : A_OK; |
| 648 } |
| 649 |
| 650 A_STATUS |
| 651 PowerStateChangeNotify(HIF_DEVICE *device, HIF_DEVICE_POWER_CHANGE_TYPE config) |
| 652 { |
| 653 A_STATUS status = A_OK; |
| 654 #if defined(CONFIG_PM) |
| 655 » struct sdio_func *func = device->func; |
| 656 int old_reset_val; |
| 657 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +PowerStateChangeNotify %d\n", co
nfig)); |
| 658 switch (config) { |
| 659 case HIF_DEVICE_POWER_DOWN: |
| 660 case HIF_DEVICE_POWER_CUT: |
| 661 old_reset_val = reset_sdio_on_unload; |
| 662 reset_sdio_on_unload = 1; |
| 663 status = hifDisableFunc(device, func); |
| 664 reset_sdio_on_unload = old_reset_val; |
| 665 if (!device->is_suspend) { |
| 666 struct mmc_host *host = func->card->host; |
| 667 » host->ios.clock = 0; |
| 668 » host->ios.vdd = 0; |
| 669 host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN; |
| 670 host->ios.chip_select = MMC_CS_DONTCARE; |
| 671 host->ios.power_mode = MMC_POWER_OFF; |
| 672 host->ios.bus_width = MMC_BUS_WIDTH_1; |
| 673 host->ios.timing = MMC_TIMING_LEGACY; |
| 674 host->ops->set_ios(host, &host->ios); |
| 675 } |
| 676 break; |
| 677 case HIF_DEVICE_POWER_UP: |
| 678 if (device->powerConfig == HIF_DEVICE_POWER_CUT) { |
| 679 status = ReinitSDIO(device); |
| 680 } |
| 681 if (status == A_OK) { |
| 682 status = hifEnableFunc(device, func); |
| 683 } |
| 684 break; |
| 685 } |
| 686 device->powerConfig = config; |
| 687 |
| 688 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -PowerStateChangeNotify\n")); |
| 689 #endif |
| 690 return status; |
| 691 } |
463 | 692 |
464 A_STATUS | 693 A_STATUS |
465 HIFConfigureDevice(HIF_DEVICE *device, HIF_DEVICE_CONFIG_OPCODE opcode, | 694 HIFConfigureDevice(HIF_DEVICE *device, HIF_DEVICE_CONFIG_OPCODE opcode, |
466 void *config, A_UINT32 configLen) | 695 void *config, A_UINT32 configLen) |
467 { | 696 { |
468 A_UINT32 count; | 697 A_UINT32 count; |
469 A_STATUS status; | 698 A_STATUS status = A_OK; |
470 | 699 |
471 switch(opcode) { | 700 switch(opcode) { |
472 case HIF_DEVICE_GET_MBOX_BLOCK_SIZE: | 701 case HIF_DEVICE_GET_MBOX_BLOCK_SIZE: |
473 ((A_UINT32 *)config)[0] = HIF_MBOX0_BLOCK_SIZE; | 702 ((A_UINT32 *)config)[0] = HIF_MBOX0_BLOCK_SIZE; |
474 ((A_UINT32 *)config)[1] = HIF_MBOX1_BLOCK_SIZE; | 703 ((A_UINT32 *)config)[1] = HIF_MBOX1_BLOCK_SIZE; |
475 ((A_UINT32 *)config)[2] = HIF_MBOX2_BLOCK_SIZE; | 704 ((A_UINT32 *)config)[2] = HIF_MBOX2_BLOCK_SIZE; |
476 ((A_UINT32 *)config)[3] = HIF_MBOX3_BLOCK_SIZE; | 705 ((A_UINT32 *)config)[3] = HIF_MBOX3_BLOCK_SIZE; |
477 break; | 706 break; |
478 | 707 |
479 case HIF_DEVICE_GET_MBOX_ADDR: | 708 case HIF_DEVICE_GET_MBOX_ADDR: |
(...skipping 11 matching lines...) Expand all Loading... |
491 *((HIF_DEVICE_IRQ_PROCESSING_MODE *)config) = HIF_DEVICE_IRQ_SYNC_ON
LY; | 720 *((HIF_DEVICE_IRQ_PROCESSING_MODE *)config) = HIF_DEVICE_IRQ_SYNC_ON
LY; |
492 break; | 721 break; |
493 case HIF_CONFIGURE_QUERY_SCATTER_REQUEST_SUPPORT: | 722 case HIF_CONFIGURE_QUERY_SCATTER_REQUEST_SUPPORT: |
494 if (!device->scatter_enabled) { | 723 if (!device->scatter_enabled) { |
495 return A_ENOTSUP; | 724 return A_ENOTSUP; |
496 } | 725 } |
497 status = SetupHIFScatterSupport(device, (HIF_DEVICE_SCATTER_SUPPORT_
INFO *)config); | 726 status = SetupHIFScatterSupport(device, (HIF_DEVICE_SCATTER_SUPPORT_
INFO *)config); |
498 if (A_FAILED(status)) { | 727 if (A_FAILED(status)) { |
499 device->scatter_enabled = FALSE; | 728 device->scatter_enabled = FALSE; |
500 } | 729 } |
501 return status; | 730 break; |
502 case HIF_DEVICE_GET_OS_DEVICE: | 731 case HIF_DEVICE_GET_OS_DEVICE: |
503 /* pass back a pointer to the SDIO function's "dev" struct */ | 732 /* pass back a pointer to the SDIO function's "dev" struct */ |
504 ((HIF_DEVICE_OS_DEVICE_INFO *)config)->pOSDevice = &device->func->de
v; | 733 ((HIF_DEVICE_OS_DEVICE_INFO *)config)->pOSDevice = &device->func->de
v; |
505 break; | 734 break; |
| 735 case HIF_DEVICE_POWER_STATE_CHANGE: |
| 736 status = PowerStateChangeNotify(device, *(HIF_DEVICE_POWER_CHANGE_TY
PE *)config); |
| 737 break; |
506 default: | 738 default: |
507 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, | 739 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, |
508 ("AR6000: Unsupported configuration opcode: %d\n", o
pcode)); | 740 ("AR6000: Unsupported configuration opcode: %d\n", o
pcode)); |
509 return A_ERROR; | 741 status = A_ERROR; |
510 } | 742 } |
511 | 743 |
512 return A_OK; | 744 return status; |
513 } | 745 } |
514 | 746 |
515 void | 747 void |
516 HIFShutDownDevice(HIF_DEVICE *device) | 748 HIFShutDownDevice(HIF_DEVICE *device) |
517 { | 749 { |
518 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +HIFShutDownDevice\n")); | 750 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +HIFShutDownDevice\n")); |
519 if (device != NULL) { | 751 if (device != NULL) { |
520 AR_DEBUG_ASSERT(device->func != NULL); | 752 AR_DEBUG_ASSERT(device->func != NULL); |
521 } else { | 753 } else { |
522 /* since we are unloading the driver anyways, reset all cards in cas
e the SDIO card | 754 /* since we are unloading the driver anyways, reset all cards in cas
e the SDIO card |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
564 | 796 |
565 device = (HIF_DEVICE *)param; | 797 device = (HIF_DEVICE *)param; |
566 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: call HTC from startup_task\n")); | 798 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: call HTC from startup_task\n")); |
567 /* start up inform DRV layer */ | 799 /* start up inform DRV layer */ |
568 if ((osdrvCallbacks.deviceInsertedHandler(osdrvCallbacks.context,device)) !=
A_OK) { | 800 if ((osdrvCallbacks.deviceInsertedHandler(osdrvCallbacks.context,device)) !=
A_OK) { |
569 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Device rejected\n")); | 801 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Device rejected\n")); |
570 } | 802 } |
571 return 0; | 803 return 0; |
572 } | 804 } |
573 | 805 |
574 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) && defined(CONFIG_PM) | 806 #if defined(CONFIG_PM) |
575 /* handle HTC startup via thread*/ | 807 static int enable_task(void *param) |
576 static int resume_task(void *param) | |
577 { | 808 { |
578 HIF_DEVICE *device; | 809 HIF_DEVICE *device; |
579 device = (HIF_DEVICE *)param; | 810 device = (HIF_DEVICE *)param; |
580 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: call HTC from resume_task\n")); | 811 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: call from resume_task\n")); |
| 812 |
581 /* start up inform DRV layer */ | 813 /* start up inform DRV layer */ |
582 if (device && device->claimedContext && osdrvCallbacks.deviceResumeHandler &
& | 814 if (device && |
583 osdrvCallbacks.deviceResumeHandler(device->claimedContext) != A_OK) { | 815 device->claimedContext && |
| 816 osdrvCallbacks.devicePowerChangeHandler && |
| 817 osdrvCallbacks.devicePowerChangeHandler(device->claimedContext, HIF_DEVI
CE_POWER_UP) != A_OK) |
| 818 { |
584 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Device rejected\n")); | 819 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Device rejected\n")); |
585 } | 820 } |
| 821 |
586 return 0; | 822 return 0; |
587 } | 823 } |
588 #endif /* CONFIG_PM */ | 824 #endif |
589 | 825 |
590 static int hifDeviceInserted(struct sdio_func *func, const struct sdio_device_id
*id) | 826 static int hifDeviceInserted(struct sdio_func *func, const struct sdio_device_id
*id) |
591 { | 827 { |
592 int ret; | 828 int ret; |
593 HIF_DEVICE * device; | 829 HIF_DEVICE * device; |
594 int count; | 830 int count; |
595 struct task_struct* startup_task_struct; | |
596 | 831 |
597 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, | 832 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, |
598 ("AR6000: hifDeviceInserted, Function: 0x%X, Vendor ID: 0x%X
, Device ID: 0x%X, block size: 0x%X/0x%X\n", | 833 ("AR6000: hifDeviceInserted, Function: 0x%X, Vendor ID: 0x%X
, Device ID: 0x%X, block size: 0x%X/0x%X\n", |
599 func->num, func->vendor, func->device, func->max_blksize, f
unc->cur_blksize)); | 834 func->num, func->vendor, func->device, func->max_blksize, f
unc->cur_blksize)); |
600 | 835 |
601 addHifDevice(func); | 836 addHifDevice(func); |
602 device = getHifDevice(func); | 837 device = getHifDevice(func); |
603 | 838 |
| 839 device->id = id; |
| 840 device->is_disabled = TRUE; |
| 841 |
604 spin_lock_init(&device->lock); | 842 spin_lock_init(&device->lock); |
605 | 843 |
606 spin_lock_init(&device->asynclock); | 844 spin_lock_init(&device->asynclock); |
607 | 845 |
608 DL_LIST_INIT(&device->ScatterReqHead); | 846 DL_LIST_INIT(&device->ScatterReqHead); |
609 | 847 |
610 if (!nohifscattersupport) { | 848 if (!nohifscattersupport) { |
611 /* try to allow scatter operation on all instances, | 849 /* try to allow scatter operation on all instances, |
612 * unless globally overridden */ | 850 * unless globally overridden */ |
613 device->scatter_enabled = TRUE; | 851 device->scatter_enabled = TRUE; |
614 } | 852 } |
615 | |
616 /* enable the SDIO function */ | |
617 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: claim\n")); | |
618 sdio_claim_host(func); | |
619 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: enable\n")); | |
620 | 853 |
621 if ((id->device & MANUFACTURER_ID_AR6K_BASE_MASK) >= MANUFACTURER_ID_AR6003_
BASE) { | |
622 /* enable 4-bit ASYNC interrupt on AR6003 or later devices */ | |
623 ret = Func0_CMD52WriteByte(func->card, CCCR_SDIO_IRQ_MODE_REG, SDIO_IRQ_
MODE_ASYNC_4BIT_IRQ); | |
624 if (ret) { | |
625 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("AR6000: failed to enable 4-bit ASYN
C IRQ mode %d \n",ret)); | |
626 sdio_release_host(func); | |
627 return ret; | |
628 } | |
629 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: 4-bit ASYNC IRQ mode enabled\
n")); | |
630 } | |
631 | |
632 | |
633 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) | |
634 /* give us some time to enable, in ms */ | |
635 func->enable_timeout = 100; | |
636 #endif | |
637 ret = sdio_enable_func(func); | |
638 if (ret) { | |
639 AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), Unable to enable AR6K:
0x%X\n", | |
640 __FUNCTION__, ret)); | |
641 sdio_release_host(func); | |
642 return ret; | |
643 } | |
644 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: set block size 0x%X\n", HIF_MBOX_
BLOCK_SIZE)); | |
645 ret = sdio_set_block_size(func, HIF_MBOX_BLOCK_SIZE); | |
646 sdio_release_host(func); | |
647 if (ret) { | |
648 AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), Unable to set block siz
e 0x%x AR6K: 0x%X\n", | |
649 __FUNCTION__, HIF_MBOX_BLOCK_SIZE, ret
)); | |
650 return ret; | |
651 } | |
652 /* Initialize the bus requests to be used later */ | 854 /* Initialize the bus requests to be used later */ |
653 A_MEMZERO(device->busRequest, sizeof(device->busRequest)); | 855 A_MEMZERO(device->busRequest, sizeof(device->busRequest)); |
654 for (count = 0; count < BUS_REQUEST_MAX_NUM; count ++) { | 856 for (count = 0; count < BUS_REQUEST_MAX_NUM; count ++) { |
655 sema_init(&device->busRequest[count].sem_req, 0); | 857 sema_init(&device->busRequest[count].sem_req, 0); |
656 hifFreeBusRequest(device, &device->busRequest[count]); | 858 hifFreeBusRequest(device, &device->busRequest[count]); |
657 } | 859 } |
| 860 sema_init(&device->sem_async, 0); |
| 861 |
| 862 ret = hifEnableFunc(device, func); |
658 | 863 |
659 /* create async I/O thread */ | |
660 device->async_shutdown = 0; | |
661 device->async_task = kthread_create(async_task, | |
662 (void *)device, | |
663 "AR6K Async"); | |
664 if (IS_ERR(device->async_task)) { | |
665 AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), to create async task\n"
, __FUNCTION__)); | |
666 return A_ERROR; | |
667 } | |
668 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: start async task\n")); | |
669 sema_init(&device->sem_async, 0); | |
670 wake_up_process(device->async_task ); | |
671 | |
672 /* create startup thread */ | |
673 startup_task_struct = kthread_create(startup_task, | |
674 (void *)device, | |
675 "AR6K startup"); | |
676 if (IS_ERR(startup_task_struct)) { | |
677 AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), to create startup task\
n", __FUNCTION__)); | |
678 return A_ERROR; | |
679 } | |
680 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: start startup task\n")); | |
681 wake_up_process(startup_task_struct); | |
682 | |
683 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: return %d\n", ret)); | |
684 return ret; | 864 return ret; |
685 } | 865 } |
686 | 866 |
687 | 867 |
688 void | 868 void |
689 HIFAckInterrupt(HIF_DEVICE *device) | 869 HIFAckInterrupt(HIF_DEVICE *device) |
690 { | 870 { |
691 AR_DEBUG_ASSERT(device != NULL); | 871 AR_DEBUG_ASSERT(device != NULL); |
692 | 872 |
693 /* Acknowledge our function IRQ */ | 873 /* Acknowledge our function IRQ */ |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
736 unsigned long flag; | 916 unsigned long flag; |
737 | 917 |
738 /* Acquire lock */ | 918 /* Acquire lock */ |
739 spin_lock_irqsave(&device->lock, flag); | 919 spin_lock_irqsave(&device->lock, flag); |
740 | 920 |
741 /* Remove first in list */ | 921 /* Remove first in list */ |
742 if((busrequest = device->s_busRequestFreeQueue) != NULL) | 922 if((busrequest = device->s_busRequestFreeQueue) != NULL) |
743 { | 923 { |
744 device->s_busRequestFreeQueue = busrequest->next; | 924 device->s_busRequestFreeQueue = busrequest->next; |
745 } | 925 } |
746 | |
747 /* Release lock */ | 926 /* Release lock */ |
748 spin_unlock_irqrestore(&device->lock, flag); | 927 spin_unlock_irqrestore(&device->lock, flag); |
749 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: hifAllocateBusRequest: 0x%p\n", b
usrequest)); | 928 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: hifAllocateBusRequest: 0x%p\n", b
usrequest)); |
750 return busrequest; | 929 return busrequest; |
751 } | 930 } |
752 | 931 |
753 void | 932 void |
754 hifFreeBusRequest(HIF_DEVICE *device, BUS_REQUEST *busrequest) | 933 hifFreeBusRequest(HIF_DEVICE *device, BUS_REQUEST *busrequest) |
755 { | 934 { |
756 unsigned long flag; | 935 unsigned long flag; |
757 | 936 |
758 AR_DEBUG_ASSERT(busrequest != NULL); | 937 AR_DEBUG_ASSERT(busrequest != NULL); |
759 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: hifFreeBusRequest: 0x%p\n", busre
quest)); | 938 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: hifFreeBusRequest: 0x%p\n", busre
quest)); |
760 /* Acquire lock */ | 939 /* Acquire lock */ |
761 spin_lock_irqsave(&device->lock, flag); | 940 spin_lock_irqsave(&device->lock, flag); |
762 | 941 |
763 | 942 |
764 /* Insert first in list */ | 943 /* Insert first in list */ |
765 busrequest->next = device->s_busRequestFreeQueue; | 944 busrequest->next = device->s_busRequestFreeQueue; |
766 busrequest->inusenext = NULL; | 945 busrequest->inusenext = NULL; |
767 device->s_busRequestFreeQueue = busrequest; | 946 device->s_busRequestFreeQueue = busrequest; |
768 | 947 |
769 /* Release lock */ | 948 /* Release lock */ |
770 spin_unlock_irqrestore(&device->lock, flag); | 949 spin_unlock_irqrestore(&device->lock, flag); |
771 } | 950 } |
772 | 951 |
773 static int hifDisableFunc(HIF_DEVICE *device, struct sdio_func *func) | 952 static A_STATUS hifDisableFunc(HIF_DEVICE *device, struct sdio_func *func) |
774 { | 953 { |
775 int ret = 0; | 954 int ret; |
| 955 A_STATUS status = A_OK; |
776 | 956 |
777 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifDeviceRemoved\n")); | 957 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifDisableFunc\n")); |
778 device = getHifDevice(func); | 958 device = getHifDevice(func); |
779 if (!IS_ERR(device->async_task)) { | 959 if (!IS_ERR(device->async_task)) { |
780 init_completion(&device->async_completion); | 960 init_completion(&device->async_completion); |
781 device->async_shutdown = 1; | 961 device->async_shutdown = 1; |
782 up(&device->sem_async); | 962 up(&device->sem_async); |
783 wait_for_completion(&device->async_completion); | 963 wait_for_completion(&device->async_completion); |
784 device->async_task = NULL; | 964 device->async_task = NULL; |
785 } | 965 } |
786 /* Disable the card */ | 966 /* Disable the card */ |
787 sdio_claim_host(device->func); | 967 sdio_claim_host(device->func); |
788 ret = sdio_disable_func(device->func); | 968 ret = sdio_disable_func(device->func); |
| 969 if (ret) { |
| 970 status = A_ERROR; |
| 971 } |
789 | 972 |
790 if (reset_sdio_on_unload) { | 973 if (reset_sdio_on_unload) { |
791 /* reset the SDIO interface. This is useful in automated testing where
the card | 974 /* reset the SDIO interface. This is useful in automated testing where
the card |
792 * does not need to be removed at the end of the test. It is expected t
hat the user will | 975 * does not need to be removed at the end of the test. It is expected t
hat the user will |
793 * also unload/reload the host controller driver to force the bus driver
to re-enumerate the slot */ | 976 * also unload/reload the host controller driver to force the bus driver
to re-enumerate the slot */ |
794 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("AR6000: reseting SDIO card back to uni
nitialized state \n")); | 977 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("AR6000: reseting SDIO card back to uni
nitialized state \n")); |
795 | 978 |
796 /* NOTE : sdio_f0_writeb() cannot be used here, that API only allows acc
ess | 979 /* NOTE : sdio_f0_writeb() cannot be used here, that API only allows acc
ess |
797 * to undefined registers in the range of: 0xF0-0xFF */ | 980 * to undefined registers in the range of: 0xF0-0xFF */ |
798 | 981 |
799 ret = Func0_CMD52WriteByte(device->func->card, SDIO_CCCR_ABORT, (1 << 3)
); | 982 ret = Func0_CMD52WriteByte(device->func->card, SDIO_CCCR_ABORT, (1 << 3)
); |
800 if (ret) { | 983 if (ret) { |
801 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("AR6000: reset failed : %d \n",ret)
); | 984 status = A_ERROR; |
| 985 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("AR6000: reset failed : %d \n",ret))
; |
802 } | 986 } |
803 } | 987 } |
804 | 988 |
805 sdio_release_host(device->func); | 989 sdio_release_host(device->func); |
806 return ret; | 990 |
| 991 if (status == A_OK) { |
| 992 device->is_disabled = TRUE; |
| 993 } |
| 994 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -hifDisableFunc\n")); |
| 995 |
| 996 return status; |
807 } | 997 } |
808 | 998 |
809 static void hifDeviceRemoved(struct sdio_func *func) | 999 static int hifEnableFunc(HIF_DEVICE *device, struct sdio_func *func) |
810 { | |
811 A_STATUS status = A_OK; | |
812 HIF_DEVICE *device; | |
813 AR_DEBUG_ASSERT(func != NULL); | |
814 | |
815 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifDeviceRemoved\n")); | |
816 device = getHifDevice(func); | |
817 if (device->claimedContext != NULL) { | |
818 status = osdrvCallbacks.deviceRemovedHandler(device->claimedContext, dev
ice); | |
819 } | |
820 | |
821 if (device->is_suspend) { | |
822 device->is_suspend = FALSE; | |
823 } else { | |
824 if (hifDisableFunc(device, func)!=0) { | |
825 status = A_ERROR; | |
826 } | |
827 } | |
828 CleanupHIFScatterResources(device); | |
829 | |
830 delHifDevice(device); | |
831 AR_DEBUG_ASSERT(status == A_OK); | |
832 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -hifDeviceRemoved\n")); | |
833 } | |
834 | |
835 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) && defined(CONFIG_PM) | |
836 static int hifDeviceSuspend(struct device *dev) | |
837 { | |
838 » struct sdio_func *func = dev_to_sdio_func(dev); | |
839 A_STATUS status = A_OK; | |
840 HIF_DEVICE *device; | |
841 device = getHifDevice(func); | |
842 if (device && device->claimedContext && osdrvCallbacks.deviceSuspendHandler)
{ | |
843 status = osdrvCallbacks.deviceSuspendHandler(device->claimedContext); | |
844 } | |
845 if (status == A_OK) { | |
846 int oldresetvalue = reset_sdio_on_unload; | |
847 reset_sdio_on_unload = 1; | |
848 hifDisableFunc(device, func); | |
849 reset_sdio_on_unload = oldresetvalue; | |
850 device->is_suspend = TRUE; | |
851 } else if (status == A_EBUSY) { | |
852 A_INT32 cnt = 10; | |
853 A_UINT8 host_int_status; | |
854 » do { » » | |
855 » » while (atomic_read(&device->irqHandling)) { | |
856 » » » /* wait until irq handler finished all the jobs */ | |
857 » » » schedule_timeout(HZ/10); | |
858 » » } | |
859 » » /* check if there is any pending irq due to force done */ | |
860 » » host_int_status = 0; | |
861 » » status = HIFReadWrite(device, HOST_INT_STATUS_ADDRESS, | |
862 » » » » (A_UINT8 *)&host_int_status, sizeof(host_int
_status), | |
863 » » » » HIF_RD_SYNC_BYTE_INC, NULL); | |
864 » » host_int_status = A_SUCCESS(status) ? (host_int_status & (1
<< 0)) : 0; | |
865 » » if (host_int_status) { | |
866 » » » schedule(); /* schedule for next dsrHandler */ | |
867 » » } | |
868 » } while (host_int_status && --cnt > 0); | |
869 | |
870 if (host_int_status && cnt == 0) { | |
871 AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, | |
872 ("AR6000: %s(), Unable clear up pending IRQ before t
he system suspended\n", | |
873 » » » » » __FUNCTION__)); | |
874 } | |
875 #if 1 | |
876 status = A_OK; /* assume that sdio host controller will take care the po
wer of wifi chip */ | |
877 #else | |
878 return -EBUSY; /* Return -EBUSY if customer use all android patch of mmc
stack provided by us */ | |
879 #endif | |
880 } | |
881 return A_SUCCESS(status) ? 0 : status; | |
882 } | |
883 | |
884 static int hifDeviceResume(struct device *dev) | |
885 { | 1000 { |
886 struct task_struct* pTask; | 1001 struct task_struct* pTask; |
887 const char *taskName; | 1002 const char *taskName = NULL; |
888 int (*taskFunc)(void *); | 1003 int (*taskFunc)(void *) = NULL; |
889 » struct sdio_func *func = dev_to_sdio_func(dev); | 1004 int ret = A_OK; |
890 A_STATUS ret = A_OK; | 1005 |
891 HIF_DEVICE *device; | 1006 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifEnableFunc\n")); |
892 device = getHifDevice(func); | 1007 device = getHifDevice(func); |
893 | 1008 |
894 if (device->is_suspend) { | 1009 if (device->is_disabled) { |
895 /* enable the SDIO function */ | 1010 /* enable the SDIO function */ |
896 sdio_claim_host(func); | 1011 sdio_claim_host(func); |
897 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) | 1012 |
| 1013 if ((device->id->device & MANUFACTURER_ID_AR6K_BASE_MASK) >= MANUFACTURE
R_ID_AR6003_BASE) { |
| 1014 /* enable 4-bit ASYNC interrupt on AR6003 or later devices */ |
| 1015 ret = Func0_CMD52WriteByte(func->card, CCCR_SDIO_IRQ_MODE_REG, SDIO_
IRQ_MODE_ASYNC_4BIT_IRQ); |
| 1016 if (ret) { |
| 1017 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("AR6000: failed to enable 4-bit
ASYNC IRQ mode %d \n",ret)); |
| 1018 sdio_release_host(func); |
| 1019 return A_ERROR; |
| 1020 } |
| 1021 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: 4-bit ASYNC IRQ mode enab
led\n")); |
| 1022 } |
898 /* give us some time to enable, in ms */ | 1023 /* give us some time to enable, in ms */ |
899 func->enable_timeout = 100; | 1024 func->enable_timeout = 100; |
900 #endif | |
901 ret = sdio_enable_func(func); | 1025 ret = sdio_enable_func(func); |
902 if (ret) { | 1026 if (ret) { |
903 AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), Unable to enable AR
6K: 0x%X\n", | 1027 AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), Unable to enable AR
6K: 0x%X\n", |
904 __FUNCTION__, ret)); | 1028 __FUNCTION__, ret)); |
905 sdio_release_host(func); | 1029 sdio_release_host(func); |
906 return ret; | 1030 return A_ERROR; |
907 } | 1031 } |
908 ret = sdio_set_block_size(func, HIF_MBOX_BLOCK_SIZE); | 1032 ret = sdio_set_block_size(func, HIF_MBOX_BLOCK_SIZE); |
909 sdio_release_host(func); | 1033 sdio_release_host(func); |
910 if (ret) { | 1034 if (ret) { |
911 AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), Unable to set block
size 0x%x AR6K: 0x%X\n", | 1035 AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), Unable to set block
size 0x%x AR6K: 0x%X\n", |
912 __FUNCTION__, HIF_MBOX_BLOCK_SIZE, ret
)); | 1036 __FUNCTION__, HIF_MBOX_BLOCK_SIZE, ret
)); |
913 return ret; | 1037 return A_ERROR; |
914 } | 1038 } |
915 device->is_suspend = FALSE; | 1039 device->is_disabled = FALSE; |
916 /* create async I/O thread */ | 1040 /* create async I/O thread */ |
917 if (!device->async_task) { | 1041 if (!device->async_task) { |
918 device->async_shutdown = 0; | 1042 device->async_shutdown = 0; |
919 device->async_task = kthread_create(async_task, | 1043 device->async_task = kthread_create(async_task, |
920 (void *)device, | 1044 (void *)device, |
921 "AR6K Async"); | 1045 "AR6K Async"); |
922 if (IS_ERR(device->async_task)) { | 1046 if (IS_ERR(device->async_task)) { |
923 AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), to create async
task\n", __FUNCTION__)); | 1047 AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), to create async
task\n", __FUNCTION__)); |
924 return A_ERROR; | 1048 return A_ERROR; |
925 } | 1049 } |
926 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: start async task\n")); | 1050 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: start async task\n")); |
927 wake_up_process(device->async_task ); | 1051 wake_up_process(device->async_task ); |
928 } | 1052 } |
929 } | 1053 } |
930 | 1054 |
931 if (!device->claimedContext) { | 1055 if (!device->claimedContext) { |
932 printk("WARNING!!! No claimedContext during resume wlan\n"); | |
933 taskFunc = startup_task; | 1056 taskFunc = startup_task; |
934 taskName = "AR6K startup"; | 1057 taskName = "AR6K startup"; |
| 1058 ret = A_OK; |
| 1059 #if defined(CONFIG_PM) |
935 } else { | 1060 } else { |
936 taskFunc = resume_task; | 1061 taskFunc = enable_task; |
937 taskName = "AR6K resume"; | 1062 taskName = "AR6K enable"; |
| 1063 ret = A_PENDING; |
| 1064 #endif /* CONFIG_PM */ |
938 } | 1065 } |
939 /* create resume thread */ | 1066 /* create resume thread */ |
940 pTask = kthread_create(taskFunc, (void *)device, taskName); | 1067 pTask = kthread_create(taskFunc, (void *)device, taskName); |
941 if (IS_ERR(pTask)) { | 1068 if (IS_ERR(pTask)) { |
942 AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), to create resume task\n
", __FUNCTION__)); | 1069 AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), to create enabel task\n
", __FUNCTION__)); |
943 return A_ERROR; | 1070 return A_ERROR; |
944 } | 1071 } |
945 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: start resume task\n")); | |
946 wake_up_process(pTask); | 1072 wake_up_process(pTask); |
947 return A_SUCCESS(ret) ? 0 : ret; | 1073 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -hifEnableFunc\n")); |
| 1074 |
| 1075 /* task will call the enable func, indicate pending */ |
| 1076 return ret; |
| 1077 } |
| 1078 |
| 1079 #if defined(CONFIG_PM) |
| 1080 static int hifDeviceSuspend(struct device *dev) |
| 1081 { |
| 1082 struct sdio_func *func=dev_to_sdio_func(dev); |
| 1083 A_STATUS status = A_OK; |
| 1084 HIF_DEVICE *device; |
| 1085 |
| 1086 device = getHifDevice(func); |
| 1087 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifDeviceSuspend\n")); |
| 1088 if (device && device->claimedContext && osdrvCallbacks.deviceSuspendHandler)
{ |
| 1089 device->is_suspend = TRUE; /* set true first for PowerStateChangeNotify(
..) */ |
| 1090 status = osdrvCallbacks.deviceSuspendHandler(device->claimedContext); |
| 1091 if (status != A_OK) { |
| 1092 device->is_suspend = FALSE; |
| 1093 } |
| 1094 } |
| 1095 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -hifDeviceSuspend\n")); |
| 1096 |
| 1097 switch (status) { |
| 1098 case A_OK: |
| 1099 return 0; |
| 1100 case A_EBUSY: |
| 1101 return -EBUSY; /* Hack for kernel in order to support deep sleep and wow
*/ |
| 1102 default: |
| 1103 return -1; |
| 1104 } |
| 1105 } |
| 1106 |
| 1107 static int hifDeviceResume(struct device *dev) |
| 1108 { |
| 1109 struct sdio_func *func=dev_to_sdio_func(dev); |
| 1110 A_STATUS status = A_OK; |
| 1111 HIF_DEVICE *device; |
| 1112 |
| 1113 device = getHifDevice(func); |
| 1114 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifDeviceResume\n")); |
| 1115 if (device && device->claimedContext && osdrvCallbacks.deviceSuspendHandler)
{ |
| 1116 status = osdrvCallbacks.deviceResumeHandler(device->claimedContext); |
| 1117 if (status == A_OK) { |
| 1118 device->is_suspend = FALSE; |
| 1119 } |
| 1120 } |
| 1121 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -hifDeviceResume\n")); |
| 1122 |
| 1123 return A_SUCCESS(status) ? 0 : status; |
948 } | 1124 } |
949 #endif /* CONFIG_PM */ | 1125 #endif /* CONFIG_PM */ |
950 | 1126 |
| 1127 static void hifDeviceRemoved(struct sdio_func *func) |
| 1128 { |
| 1129 A_STATUS status = A_OK; |
| 1130 HIF_DEVICE *device; |
| 1131 AR_DEBUG_ASSERT(func != NULL); |
| 1132 |
| 1133 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifDeviceRemoved\n")); |
| 1134 device = getHifDevice(func); |
| 1135 if (device->claimedContext != NULL) { |
| 1136 status = osdrvCallbacks.deviceRemovedHandler(device->claimedContext, dev
ice); |
| 1137 } |
| 1138 |
| 1139 if (device->is_disabled) { |
| 1140 device->is_disabled = FALSE; |
| 1141 } else { |
| 1142 status = hifDisableFunc(device, func); |
| 1143 } |
| 1144 CleanupHIFScatterResources(device); |
| 1145 |
| 1146 delHifDevice(device); |
| 1147 AR_DEBUG_ASSERT(status == A_OK); |
| 1148 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -hifDeviceRemoved\n")); |
| 1149 } |
| 1150 |
| 1151 /* |
| 1152 * This should be moved to AR6K HTC layer. |
| 1153 */ |
| 1154 A_STATUS hifWaitForPendingRecv(HIF_DEVICE *device) |
| 1155 { |
| 1156 A_INT32 cnt = 10; |
| 1157 A_UINT8 host_int_status; |
| 1158 A_STATUS status = A_OK; |
| 1159 |
| 1160 do { |
| 1161 while (atomic_read(&device->irqHandling)) { |
| 1162 /* wait until irq handler finished all the jobs */ |
| 1163 schedule_timeout(HZ/10); |
| 1164 } |
| 1165 /* check if there is any pending irq due to force done */ |
| 1166 host_int_status = 0; |
| 1167 status = HIFReadWrite(device, HOST_INT_STATUS_ADDRESS, |
| 1168 (A_UINT8 *)&host_int_status, sizeof(host_int
_status), |
| 1169 HIF_RD_SYNC_BYTE_INC, NULL); |
| 1170 host_int_status = A_SUCCESS(status) ? (host_int_status & (1 << 0)) :
0; |
| 1171 if (host_int_status) { |
| 1172 schedule(); /* schedule for next dsrHandler */ |
| 1173 } |
| 1174 } while (host_int_status && --cnt > 0); |
| 1175 |
| 1176 if (host_int_status && cnt == 0) { |
| 1177 AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, |
| 1178 ("AR6000: %s(), Unable clear up pending IRQ before t
he system suspended\n", __FUNCTION__)); |
| 1179 } |
| 1180 |
| 1181 return A_OK; |
| 1182 } |
| 1183 |
| 1184 |
951 static HIF_DEVICE * | 1185 static HIF_DEVICE * |
952 addHifDevice(struct sdio_func *func) | 1186 addHifDevice(struct sdio_func *func) |
953 { | 1187 { |
954 HIF_DEVICE *hifdevice; | 1188 HIF_DEVICE *hifdevice; |
955 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: addHifDevice\n")); | 1189 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: addHifDevice\n")); |
956 AR_DEBUG_ASSERT(func != NULL); | 1190 AR_DEBUG_ASSERT(func != NULL); |
957 hifdevice = (HIF_DEVICE *)kzalloc(sizeof(HIF_DEVICE), GFP_KERNEL); | 1191 hifdevice = (HIF_DEVICE *)kzalloc(sizeof(HIF_DEVICE), GFP_KERNEL); |
958 AR_DEBUG_ASSERT(hifdevice != NULL); | 1192 AR_DEBUG_ASSERT(hifdevice != NULL); |
959 #if HIF_USE_DMA_BOUNCE_BUFFER | 1193 #if HIF_USE_DMA_BOUNCE_BUFFER |
960 hifdevice->dma_buffer = kmalloc(HIF_DMA_BUFFER_SIZE, GFP_KERNEL); | 1194 hifdevice->dma_buffer = kmalloc(HIF_DMA_BUFFER_SIZE, GFP_KERNEL); |
961 AR_DEBUG_ASSERT(hifdevice->dma_buffer != NULL); | 1195 AR_DEBUG_ASSERT(hifdevice->dma_buffer != NULL); |
962 #endif | 1196 #endif |
963 hifdevice->func = func; | 1197 hifdevice->func = func; |
| 1198 hifdevice->powerConfig = HIF_DEVICE_POWER_UP; |
964 sdio_set_drvdata(func, hifdevice); | 1199 sdio_set_drvdata(func, hifdevice); |
965 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: addHifDevice; 0x%p\n", hifdevice)
); | 1200 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: addHifDevice; 0x%p\n", hifdevice)
); |
966 return hifdevice; | 1201 return hifdevice; |
967 } | 1202 } |
968 | 1203 |
969 static HIF_DEVICE * | 1204 static HIF_DEVICE * |
970 getHifDevice(struct sdio_func *func) | 1205 getHifDevice(struct sdio_func *func) |
971 { | 1206 { |
972 AR_DEBUG_ASSERT(func != NULL); | 1207 AR_DEBUG_ASSERT(func != NULL); |
973 return (HIF_DEVICE *)sdio_get_drvdata(func); | 1208 return (HIF_DEVICE *)sdio_get_drvdata(func); |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1034 | 1269 |
1035 memset(&ioCmd,0,sizeof(ioCmd)); | 1270 memset(&ioCmd,0,sizeof(ioCmd)); |
1036 SDIO_SET_CMD52_WRITE_ARG(arg,0,address,byte); | 1271 SDIO_SET_CMD52_WRITE_ARG(arg,0,address,byte); |
1037 ioCmd.opcode = SD_IO_RW_DIRECT; | 1272 ioCmd.opcode = SD_IO_RW_DIRECT; |
1038 ioCmd.arg = arg; | 1273 ioCmd.arg = arg; |
1039 ioCmd.flags = MMC_RSP_R5 | MMC_CMD_AC; | 1274 ioCmd.flags = MMC_RSP_R5 | MMC_CMD_AC; |
1040 | 1275 |
1041 return mmc_wait_for_cmd(card->host, &ioCmd, 0); | 1276 return mmc_wait_for_cmd(card->host, &ioCmd, 0); |
1042 } | 1277 } |
1043 | 1278 |
| 1279 static int Func0_CMD52ReadByte(struct mmc_card *card, unsigned int address, unsi
gned char *byte) |
| 1280 { |
| 1281 struct mmc_command ioCmd; |
| 1282 unsigned long arg; |
| 1283 A_INT32 err; |
| 1284 |
| 1285 memset(&ioCmd,0,sizeof(ioCmd)); |
| 1286 SDIO_SET_CMD52_READ_ARG(arg,0,address); |
| 1287 ioCmd.opcode = SD_IO_RW_DIRECT; |
| 1288 ioCmd.arg = arg; |
| 1289 ioCmd.flags = MMC_RSP_R5 | MMC_CMD_AC; |
1044 | 1290 |
| 1291 err = mmc_wait_for_cmd(card->host, &ioCmd, 0); |
1045 | 1292 |
| 1293 if ((!err) && (byte)) { |
| 1294 *byte = ioCmd.resp[0] & 0xFF; |
| 1295 } |
1046 | 1296 |
| 1297 return err; |
| 1298 } |
OLD | NEW |