Branch data Line data Source code
1 : : /*
2 : : * linux/drivers/mmc/core/sdio_io.c
3 : : *
4 : : * Copyright 2007-2008 Pierre Ossman
5 : : *
6 : : * This program is free software; you can redistribute it and/or modify
7 : : * it under the terms of the GNU General Public License as published by
8 : : * the Free Software Foundation; either version 2 of the License, or (at
9 : : * your option) any later version.
10 : : */
11 : :
12 : : #include <linux/export.h>
13 : : #include <linux/mmc/host.h>
14 : : #include <linux/mmc/card.h>
15 : : #include <linux/mmc/sdio.h>
16 : : #include <linux/mmc/sdio_func.h>
17 : :
18 : : #include "sdio_ops.h"
19 : :
20 : : /**
21 : : * sdio_claim_host - exclusively claim a bus for a certain SDIO function
22 : : * @func: SDIO function that will be accessed
23 : : *
24 : : * Claim a bus for a set of operations. The SDIO function given
25 : : * is used to figure out which bus is relevant.
26 : : */
27 : 0 : void sdio_claim_host(struct sdio_func *func)
28 : : {
29 [ # # ]: 0 : BUG_ON(!func);
30 [ # # ]: 0 : BUG_ON(!func->card);
31 : :
32 : 0 : mmc_claim_host(func->card->host);
33 : 0 : }
34 : : EXPORT_SYMBOL_GPL(sdio_claim_host);
35 : :
36 : : /**
37 : : * sdio_release_host - release a bus for a certain SDIO function
38 : : * @func: SDIO function that was accessed
39 : : *
40 : : * Release a bus, allowing others to claim the bus for their
41 : : * operations.
42 : : */
43 : 0 : void sdio_release_host(struct sdio_func *func)
44 : : {
45 [ # # ]: 0 : BUG_ON(!func);
46 [ # # ]: 0 : BUG_ON(!func->card);
47 : :
48 : 0 : mmc_release_host(func->card->host);
49 : 0 : }
50 : : EXPORT_SYMBOL_GPL(sdio_release_host);
51 : :
52 : : /**
53 : : * sdio_enable_func - enables a SDIO function for usage
54 : : * @func: SDIO function to enable
55 : : *
56 : : * Powers up and activates a SDIO function so that register
57 : : * access is possible.
58 : : */
59 : 0 : int sdio_enable_func(struct sdio_func *func)
60 : : {
61 : : int ret;
62 : : unsigned char reg;
63 : : unsigned long timeout;
64 : :
65 [ # # ]: 0 : BUG_ON(!func);
66 [ # # ]: 0 : BUG_ON(!func->card);
67 : :
68 : : pr_debug("SDIO: Enabling device %s...\n", sdio_func_id(func));
69 : :
70 : 0 : ret = mmc_io_rw_direct(func->card, 0, 0, SDIO_CCCR_IOEx, 0, ®);
71 [ # # ]: 0 : if (ret)
72 : : goto err;
73 : :
74 : 0 : reg |= 1 << func->num;
75 : :
76 : 0 : ret = mmc_io_rw_direct(func->card, 1, 0, SDIO_CCCR_IOEx, reg, NULL);
77 [ # # ]: 0 : if (ret)
78 : : goto err;
79 : :
80 : 0 : timeout = jiffies + msecs_to_jiffies(func->enable_timeout);
81 : :
82 : : while (1) {
83 : 0 : ret = mmc_io_rw_direct(func->card, 0, 0, SDIO_CCCR_IORx, 0, ®);
84 [ # # ]: 0 : if (ret)
85 : : goto err;
86 [ # # ]: 0 : if (reg & (1 << func->num))
87 : : break;
88 : : ret = -ETIME;
89 [ # # ]: 0 : if (time_after(jiffies, timeout))
90 : : goto err;
91 : : }
92 : :
93 : : pr_debug("SDIO: Enabled device %s\n", sdio_func_id(func));
94 : :
95 : : return 0;
96 : :
97 : : err:
98 : : pr_debug("SDIO: Failed to enable device %s\n", sdio_func_id(func));
99 : 0 : return ret;
100 : : }
101 : : EXPORT_SYMBOL_GPL(sdio_enable_func);
102 : :
103 : : /**
104 : : * sdio_disable_func - disable a SDIO function
105 : : * @func: SDIO function to disable
106 : : *
107 : : * Powers down and deactivates a SDIO function. Register access
108 : : * to this function will fail until the function is reenabled.
109 : : */
110 : 0 : int sdio_disable_func(struct sdio_func *func)
111 : : {
112 : : int ret;
113 : : unsigned char reg;
114 : :
115 [ # # ]: 0 : BUG_ON(!func);
116 [ # # ]: 0 : BUG_ON(!func->card);
117 : :
118 : : pr_debug("SDIO: Disabling device %s...\n", sdio_func_id(func));
119 : :
120 : 0 : ret = mmc_io_rw_direct(func->card, 0, 0, SDIO_CCCR_IOEx, 0, ®);
121 [ # # ]: 0 : if (ret)
122 : : goto err;
123 : :
124 : 0 : reg &= ~(1 << func->num);
125 : :
126 : 0 : ret = mmc_io_rw_direct(func->card, 1, 0, SDIO_CCCR_IOEx, reg, NULL);
127 [ # # ]: 0 : if (ret)
128 : : goto err;
129 : :
130 : : pr_debug("SDIO: Disabled device %s\n", sdio_func_id(func));
131 : :
132 : : return 0;
133 : :
134 : : err:
135 : : pr_debug("SDIO: Failed to disable device %s\n", sdio_func_id(func));
136 : : return -EIO;
137 : : }
138 : : EXPORT_SYMBOL_GPL(sdio_disable_func);
139 : :
140 : : /**
141 : : * sdio_set_block_size - set the block size of an SDIO function
142 : : * @func: SDIO function to change
143 : : * @blksz: new block size or 0 to use the default.
144 : : *
145 : : * The default block size is the largest supported by both the function
146 : : * and the host, with a maximum of 512 to ensure that arbitrarily sized
147 : : * data transfer use the optimal (least) number of commands.
148 : : *
149 : : * A driver may call this to override the default block size set by the
150 : : * core. This can be used to set a block size greater than the maximum
151 : : * that reported by the card; it is the driver's responsibility to ensure
152 : : * it uses a value that the card supports.
153 : : *
154 : : * Returns 0 on success, -EINVAL if the host does not support the
155 : : * requested block size, or -EIO (etc.) if one of the resultant FBR block
156 : : * size register writes failed.
157 : : *
158 : : */
159 : 0 : int sdio_set_block_size(struct sdio_func *func, unsigned blksz)
160 : : {
161 : : int ret;
162 : :
163 [ # # ]: 0 : if (blksz > func->card->host->max_blk_size)
164 : : return -EINVAL;
165 : :
166 [ # # ]: 0 : if (blksz == 0) {
167 : 0 : blksz = min(func->max_blksize, func->card->host->max_blk_size);
168 : 0 : blksz = min(blksz, 512u);
169 : : }
170 : :
171 : 0 : ret = mmc_io_rw_direct(func->card, 1, 0,
172 : 0 : SDIO_FBR_BASE(func->num) + SDIO_FBR_BLKSIZE,
173 : : blksz & 0xff, NULL);
174 [ # # ]: 0 : if (ret)
175 : : return ret;
176 : 0 : ret = mmc_io_rw_direct(func->card, 1, 0,
177 : 0 : SDIO_FBR_BASE(func->num) + SDIO_FBR_BLKSIZE + 1,
178 : 0 : (blksz >> 8) & 0xff, NULL);
179 [ # # ]: 0 : if (ret)
180 : : return ret;
181 : 0 : func->cur_blksize = blksz;
182 : 0 : return 0;
183 : : }
184 : : EXPORT_SYMBOL_GPL(sdio_set_block_size);
185 : :
186 : : /*
187 : : * Calculate the maximum byte mode transfer size
188 : : */
189 : : static inline unsigned int sdio_max_byte_size(struct sdio_func *func)
190 : : {
191 : 0 : unsigned mval = func->card->host->max_blk_size;
192 : :
193 [ # # ][ # # : 0 : if (mmc_blksz_for_byte_mode(func->card))
# # # # ]
[ # # # # ]
194 : 0 : mval = min(mval, func->cur_blksize);
195 : : else
196 : 0 : mval = min(mval, func->max_blksize);
197 : :
198 [ # # ][ # # ]: 0 : if (mmc_card_broken_byte_mode_512(func->card))
[ # # ][ # # ]
[ # # ][ # # ]
199 : 0 : return min(mval, 511u);
200 : :
201 : 0 : return min(mval, 512u); /* maximum size for byte mode */
202 : : }
203 : :
204 : : /**
205 : : * sdio_align_size - pads a transfer size to a more optimal value
206 : : * @func: SDIO function
207 : : * @sz: original transfer size
208 : : *
209 : : * Pads the original data size with a number of extra bytes in
210 : : * order to avoid controller bugs and/or performance hits
211 : : * (e.g. some controllers revert to PIO for certain sizes).
212 : : *
213 : : * If possible, it will also adjust the size so that it can be
214 : : * handled in just a single request.
215 : : *
216 : : * Returns the improved size, which might be unmodified.
217 : : */
218 : 0 : unsigned int sdio_align_size(struct sdio_func *func, unsigned int sz)
219 : : {
220 : : unsigned int orig_sz;
221 : : unsigned int blk_sz, byte_sz;
222 : : unsigned chunk_sz;
223 : :
224 : : orig_sz = sz;
225 : :
226 : : /*
227 : : * Do a first check with the controller, in case it
228 : : * wants to increase the size up to a point where it
229 : : * might need more than one block.
230 : : */
231 : 0 : sz = mmc_align_data_size(func->card, sz);
232 : :
233 : : /*
234 : : * If we can still do this with just a byte transfer, then
235 : : * we're done.
236 : : */
237 [ # # ]: 0 : if (sz <= sdio_max_byte_size(func))
238 : : return sz;
239 : :
240 [ # # ]: 0 : if (func->card->cccr.multi_block) {
241 : : /*
242 : : * Check if the transfer is already block aligned
243 : : */
244 [ # # ]: 0 : if ((sz % func->cur_blksize) == 0)
245 : : return sz;
246 : :
247 : : /*
248 : : * Realign it so that it can be done with one request,
249 : : * and recheck if the controller still likes it.
250 : : */
251 : 0 : blk_sz = ((sz + func->cur_blksize - 1) /
252 : : func->cur_blksize) * func->cur_blksize;
253 : 0 : blk_sz = mmc_align_data_size(func->card, blk_sz);
254 : :
255 : : /*
256 : : * This value is only good if it is still just
257 : : * one request.
258 : : */
259 [ # # ]: 0 : if ((blk_sz % func->cur_blksize) == 0)
260 : : return blk_sz;
261 : :
262 : : /*
263 : : * We failed to do one request, but at least try to
264 : : * pad the remainder properly.
265 : : */
266 : 0 : byte_sz = mmc_align_data_size(func->card,
267 : : sz % func->cur_blksize);
268 [ # # ]: 0 : if (byte_sz <= sdio_max_byte_size(func)) {
269 : 0 : blk_sz = sz / func->cur_blksize;
270 : 0 : return blk_sz * func->cur_blksize + byte_sz;
271 : : }
272 : : } else {
273 : : /*
274 : : * We need multiple requests, so first check that the
275 : : * controller can handle the chunk size;
276 : : */
277 : 0 : chunk_sz = mmc_align_data_size(func->card,
278 : : sdio_max_byte_size(func));
279 [ # # ]: 0 : if (chunk_sz == sdio_max_byte_size(func)) {
280 : : /*
281 : : * Fix up the size of the remainder (if any)
282 : : */
283 : 0 : byte_sz = orig_sz % chunk_sz;
284 [ # # ]: 0 : if (byte_sz) {
285 : 0 : byte_sz = mmc_align_data_size(func->card,
286 : : byte_sz);
287 : : }
288 : :
289 : 0 : return (orig_sz / chunk_sz) * chunk_sz + byte_sz;
290 : : }
291 : : }
292 : :
293 : : /*
294 : : * The controller is simply incapable of transferring the size
295 : : * we want in decent manner, so just return the original size.
296 : : */
297 : 0 : return orig_sz;
298 : : }
299 : : EXPORT_SYMBOL_GPL(sdio_align_size);
300 : :
301 : : /* Split an arbitrarily sized data transfer into several
302 : : * IO_RW_EXTENDED commands. */
303 : 0 : static int sdio_io_rw_ext_helper(struct sdio_func *func, int write,
304 : : unsigned addr, int incr_addr, u8 *buf, unsigned size)
305 : : {
306 : : unsigned remainder = size;
307 : : unsigned max_blocks;
308 : : int ret;
309 : :
310 : : /* Do the bulk of the transfer using block mode (if supported). */
311 [ # # ][ # # ]: 0 : if (func->card->cccr.multi_block && (size > sdio_max_byte_size(func))) {
312 : : /* Blocks per command is limited by host count, host transfer
313 : : * size and the maximum for IO_RW_EXTENDED of 511 blocks. */
314 : 0 : max_blocks = min(func->card->host->max_blk_count, 511u);
315 : :
316 [ # # ]: 0 : while (remainder >= func->cur_blksize) {
317 : : unsigned blocks;
318 : :
319 : 0 : blocks = remainder / func->cur_blksize;
320 [ # # ]: 0 : if (blocks > max_blocks)
321 : : blocks = max_blocks;
322 : 0 : size = blocks * func->cur_blksize;
323 : :
324 : 0 : ret = mmc_io_rw_extended(func->card, write,
325 : : func->num, addr, incr_addr, buf,
326 : : blocks, func->cur_blksize);
327 [ # # ]: 0 : if (ret)
328 : : return ret;
329 : :
330 : 0 : remainder -= size;
331 : 0 : buf += size;
332 [ # # ]: 0 : if (incr_addr)
333 : 0 : addr += size;
334 : : }
335 : : }
336 : :
337 : : /* Write the remainder using byte mode. */
338 [ # # ]: 0 : while (remainder > 0) {
339 : 0 : size = min(remainder, sdio_max_byte_size(func));
340 : :
341 : : /* Indicate byte mode by setting "blocks" = 0 */
342 : 0 : ret = mmc_io_rw_extended(func->card, write, func->num, addr,
343 : : incr_addr, buf, 0, size);
344 [ # # ]: 0 : if (ret)
345 : : return ret;
346 : :
347 : 0 : remainder -= size;
348 : 0 : buf += size;
349 [ # # ]: 0 : if (incr_addr)
350 : 0 : addr += size;
351 : : }
352 : : return 0;
353 : : }
354 : :
355 : : /**
356 : : * sdio_readb - read a single byte from a SDIO function
357 : : * @func: SDIO function to access
358 : : * @addr: address to read
359 : : * @err_ret: optional status value from transfer
360 : : *
361 : : * Reads a single byte from the address space of a given SDIO
362 : : * function. If there is a problem reading the address, 0xff
363 : : * is returned and @err_ret will contain the error code.
364 : : */
365 : 0 : u8 sdio_readb(struct sdio_func *func, unsigned int addr, int *err_ret)
366 : : {
367 : : int ret;
368 : : u8 val;
369 : :
370 [ # # ]: 0 : BUG_ON(!func);
371 : :
372 [ # # ]: 0 : if (err_ret)
373 : 0 : *err_ret = 0;
374 : :
375 : 0 : ret = mmc_io_rw_direct(func->card, 0, func->num, addr, 0, &val);
376 [ # # ]: 0 : if (ret) {
377 [ # # ]: 0 : if (err_ret)
378 : 0 : *err_ret = ret;
379 : : return 0xFF;
380 : : }
381 : :
382 : 0 : return val;
383 : : }
384 : : EXPORT_SYMBOL_GPL(sdio_readb);
385 : :
386 : : /**
387 : : * sdio_readb_ext - read a single byte from a SDIO function
388 : : * @func: SDIO function to access
389 : : * @addr: address to read
390 : : * @err_ret: optional status value from transfer
391 : : * @in: value to add to argument
392 : : *
393 : : * Reads a single byte from the address space of a given SDIO
394 : : * function. If there is a problem reading the address, 0xff
395 : : * is returned and @err_ret will contain the error code.
396 : : */
397 : 0 : unsigned char sdio_readb_ext(struct sdio_func *func, unsigned int addr,
398 : : int *err_ret, unsigned in)
399 : : {
400 : : int ret;
401 : : unsigned char val;
402 : :
403 [ # # ]: 0 : BUG_ON(!func);
404 : :
405 [ # # ]: 0 : if (err_ret)
406 : 0 : *err_ret = 0;
407 : :
408 : 0 : ret = mmc_io_rw_direct(func->card, 0, func->num, addr, (u8)in, &val);
409 [ # # ]: 0 : if (ret) {
410 [ # # ]: 0 : if (err_ret)
411 : 0 : *err_ret = ret;
412 : : return 0xFF;
413 : : }
414 : :
415 : 0 : return val;
416 : : }
417 : : EXPORT_SYMBOL_GPL(sdio_readb_ext);
418 : :
419 : : /**
420 : : * sdio_writeb - write a single byte to a SDIO function
421 : : * @func: SDIO function to access
422 : : * @b: byte to write
423 : : * @addr: address to write to
424 : : * @err_ret: optional status value from transfer
425 : : *
426 : : * Writes a single byte to the address space of a given SDIO
427 : : * function. @err_ret will contain the status of the actual
428 : : * transfer.
429 : : */
430 : 0 : void sdio_writeb(struct sdio_func *func, u8 b, unsigned int addr, int *err_ret)
431 : : {
432 : : int ret;
433 : :
434 [ # # ]: 0 : BUG_ON(!func);
435 : :
436 : 0 : ret = mmc_io_rw_direct(func->card, 1, func->num, addr, b, NULL);
437 [ # # ]: 0 : if (err_ret)
438 : 0 : *err_ret = ret;
439 : 0 : }
440 : : EXPORT_SYMBOL_GPL(sdio_writeb);
441 : :
442 : : /**
443 : : * sdio_writeb_readb - write and read a byte from SDIO function
444 : : * @func: SDIO function to access
445 : : * @write_byte: byte to write
446 : : * @addr: address to write to
447 : : * @err_ret: optional status value from transfer
448 : : *
449 : : * Performs a RAW (Read after Write) operation as defined by SDIO spec -
450 : : * single byte is written to address space of a given SDIO function and
451 : : * response is read back from the same address, both using single request.
452 : : * If there is a problem with the operation, 0xff is returned and
453 : : * @err_ret will contain the error code.
454 : : */
455 : 0 : u8 sdio_writeb_readb(struct sdio_func *func, u8 write_byte,
456 : : unsigned int addr, int *err_ret)
457 : : {
458 : : int ret;
459 : : u8 val;
460 : :
461 : 0 : ret = mmc_io_rw_direct(func->card, 1, func->num, addr,
462 : : write_byte, &val);
463 [ # # ]: 0 : if (err_ret)
464 : 0 : *err_ret = ret;
465 [ # # ]: 0 : if (ret)
466 : 0 : val = 0xff;
467 : :
468 : 0 : return val;
469 : : }
470 : : EXPORT_SYMBOL_GPL(sdio_writeb_readb);
471 : :
472 : : /**
473 : : * sdio_memcpy_fromio - read a chunk of memory from a SDIO function
474 : : * @func: SDIO function to access
475 : : * @dst: buffer to store the data
476 : : * @addr: address to begin reading from
477 : : * @count: number of bytes to read
478 : : *
479 : : * Reads from the address space of a given SDIO function. Return
480 : : * value indicates if the transfer succeeded or not.
481 : : */
482 : 0 : int sdio_memcpy_fromio(struct sdio_func *func, void *dst,
483 : : unsigned int addr, int count)
484 : : {
485 : 0 : return sdio_io_rw_ext_helper(func, 0, addr, 1, dst, count);
486 : : }
487 : : EXPORT_SYMBOL_GPL(sdio_memcpy_fromio);
488 : :
489 : : /**
490 : : * sdio_memcpy_toio - write a chunk of memory to a SDIO function
491 : : * @func: SDIO function to access
492 : : * @addr: address to start writing to
493 : : * @src: buffer that contains the data to write
494 : : * @count: number of bytes to write
495 : : *
496 : : * Writes to the address space of a given SDIO function. Return
497 : : * value indicates if the transfer succeeded or not.
498 : : */
499 : 0 : int sdio_memcpy_toio(struct sdio_func *func, unsigned int addr,
500 : : void *src, int count)
501 : : {
502 : 0 : return sdio_io_rw_ext_helper(func, 1, addr, 1, src, count);
503 : : }
504 : : EXPORT_SYMBOL_GPL(sdio_memcpy_toio);
505 : :
506 : : /**
507 : : * sdio_readsb - read from a FIFO on a SDIO function
508 : : * @func: SDIO function to access
509 : : * @dst: buffer to store the data
510 : : * @addr: address of (single byte) FIFO
511 : : * @count: number of bytes to read
512 : : *
513 : : * Reads from the specified FIFO of a given SDIO function. Return
514 : : * value indicates if the transfer succeeded or not.
515 : : */
516 : 0 : int sdio_readsb(struct sdio_func *func, void *dst, unsigned int addr,
517 : : int count)
518 : : {
519 : 0 : return sdio_io_rw_ext_helper(func, 0, addr, 0, dst, count);
520 : : }
521 : : EXPORT_SYMBOL_GPL(sdio_readsb);
522 : :
523 : : /**
524 : : * sdio_writesb - write to a FIFO of a SDIO function
525 : : * @func: SDIO function to access
526 : : * @addr: address of (single byte) FIFO
527 : : * @src: buffer that contains the data to write
528 : : * @count: number of bytes to write
529 : : *
530 : : * Writes to the specified FIFO of a given SDIO function. Return
531 : : * value indicates if the transfer succeeded or not.
532 : : */
533 : 0 : int sdio_writesb(struct sdio_func *func, unsigned int addr, void *src,
534 : : int count)
535 : : {
536 : 0 : return sdio_io_rw_ext_helper(func, 1, addr, 0, src, count);
537 : : }
538 : : EXPORT_SYMBOL_GPL(sdio_writesb);
539 : :
540 : : /**
541 : : * sdio_readw - read a 16 bit integer from a SDIO function
542 : : * @func: SDIO function to access
543 : : * @addr: address to read
544 : : * @err_ret: optional status value from transfer
545 : : *
546 : : * Reads a 16 bit integer from the address space of a given SDIO
547 : : * function. If there is a problem reading the address, 0xffff
548 : : * is returned and @err_ret will contain the error code.
549 : : */
550 : 0 : u16 sdio_readw(struct sdio_func *func, unsigned int addr, int *err_ret)
551 : : {
552 : : int ret;
553 : :
554 [ # # ]: 0 : if (err_ret)
555 : 0 : *err_ret = 0;
556 : :
557 : 0 : ret = sdio_memcpy_fromio(func, func->tmpbuf, addr, 2);
558 [ # # ]: 0 : if (ret) {
559 [ # # ]: 0 : if (err_ret)
560 : 0 : *err_ret = ret;
561 : : return 0xFFFF;
562 : : }
563 : :
564 : 0 : return le16_to_cpup((__le16 *)func->tmpbuf);
565 : : }
566 : : EXPORT_SYMBOL_GPL(sdio_readw);
567 : :
568 : : /**
569 : : * sdio_writew - write a 16 bit integer to a SDIO function
570 : : * @func: SDIO function to access
571 : : * @b: integer to write
572 : : * @addr: address to write to
573 : : * @err_ret: optional status value from transfer
574 : : *
575 : : * Writes a 16 bit integer to the address space of a given SDIO
576 : : * function. @err_ret will contain the status of the actual
577 : : * transfer.
578 : : */
579 : 0 : void sdio_writew(struct sdio_func *func, u16 b, unsigned int addr, int *err_ret)
580 : : {
581 : : int ret;
582 : :
583 : 0 : *(__le16 *)func->tmpbuf = cpu_to_le16(b);
584 : :
585 : 0 : ret = sdio_memcpy_toio(func, addr, func->tmpbuf, 2);
586 [ # # ]: 0 : if (err_ret)
587 : 0 : *err_ret = ret;
588 : 0 : }
589 : : EXPORT_SYMBOL_GPL(sdio_writew);
590 : :
591 : : /**
592 : : * sdio_readl - read a 32 bit integer from a SDIO function
593 : : * @func: SDIO function to access
594 : : * @addr: address to read
595 : : * @err_ret: optional status value from transfer
596 : : *
597 : : * Reads a 32 bit integer from the address space of a given SDIO
598 : : * function. If there is a problem reading the address,
599 : : * 0xffffffff is returned and @err_ret will contain the error
600 : : * code.
601 : : */
602 : 0 : u32 sdio_readl(struct sdio_func *func, unsigned int addr, int *err_ret)
603 : : {
604 : : int ret;
605 : :
606 [ # # ]: 0 : if (err_ret)
607 : 0 : *err_ret = 0;
608 : :
609 : 0 : ret = sdio_memcpy_fromio(func, func->tmpbuf, addr, 4);
610 [ # # ]: 0 : if (ret) {
611 [ # # ]: 0 : if (err_ret)
612 : 0 : *err_ret = ret;
613 : : return 0xFFFFFFFF;
614 : : }
615 : :
616 : 0 : return le32_to_cpup((__le32 *)func->tmpbuf);
617 : : }
618 : : EXPORT_SYMBOL_GPL(sdio_readl);
619 : :
620 : : /**
621 : : * sdio_writel - write a 32 bit integer to a SDIO function
622 : : * @func: SDIO function to access
623 : : * @b: integer to write
624 : : * @addr: address to write to
625 : : * @err_ret: optional status value from transfer
626 : : *
627 : : * Writes a 32 bit integer to the address space of a given SDIO
628 : : * function. @err_ret will contain the status of the actual
629 : : * transfer.
630 : : */
631 : 0 : void sdio_writel(struct sdio_func *func, u32 b, unsigned int addr, int *err_ret)
632 : : {
633 : : int ret;
634 : :
635 : 0 : *(__le32 *)func->tmpbuf = cpu_to_le32(b);
636 : :
637 : 0 : ret = sdio_memcpy_toio(func, addr, func->tmpbuf, 4);
638 [ # # ]: 0 : if (err_ret)
639 : 0 : *err_ret = ret;
640 : 0 : }
641 : : EXPORT_SYMBOL_GPL(sdio_writel);
642 : :
643 : : /**
644 : : * sdio_f0_readb - read a single byte from SDIO function 0
645 : : * @func: an SDIO function of the card
646 : : * @addr: address to read
647 : : * @err_ret: optional status value from transfer
648 : : *
649 : : * Reads a single byte from the address space of SDIO function 0.
650 : : * If there is a problem reading the address, 0xff is returned
651 : : * and @err_ret will contain the error code.
652 : : */
653 : 0 : unsigned char sdio_f0_readb(struct sdio_func *func, unsigned int addr,
654 : : int *err_ret)
655 : : {
656 : : int ret;
657 : : unsigned char val;
658 : :
659 [ # # ]: 0 : BUG_ON(!func);
660 : :
661 [ # # ]: 0 : if (err_ret)
662 : 0 : *err_ret = 0;
663 : :
664 : 0 : ret = mmc_io_rw_direct(func->card, 0, 0, addr, 0, &val);
665 [ # # ]: 0 : if (ret) {
666 [ # # ]: 0 : if (err_ret)
667 : 0 : *err_ret = ret;
668 : : return 0xFF;
669 : : }
670 : :
671 : 0 : return val;
672 : : }
673 : : EXPORT_SYMBOL_GPL(sdio_f0_readb);
674 : :
675 : : /**
676 : : * sdio_f0_writeb - write a single byte to SDIO function 0
677 : : * @func: an SDIO function of the card
678 : : * @b: byte to write
679 : : * @addr: address to write to
680 : : * @err_ret: optional status value from transfer
681 : : *
682 : : * Writes a single byte to the address space of SDIO function 0.
683 : : * @err_ret will contain the status of the actual transfer.
684 : : *
685 : : * Only writes to the vendor specific CCCR registers (0xF0 -
686 : : * 0xFF) are permiited; @err_ret will be set to -EINVAL for *
687 : : * writes outside this range.
688 : : */
689 : 0 : void sdio_f0_writeb(struct sdio_func *func, unsigned char b, unsigned int addr,
690 : : int *err_ret)
691 : : {
692 : : int ret;
693 : :
694 [ # # ]: 0 : BUG_ON(!func);
695 : :
696 [ # # ][ # # ]: 0 : if ((addr < 0xF0 || addr > 0xFF) && (!mmc_card_lenient_fn0(func->card))) {
697 [ # # ]: 0 : if (err_ret)
698 : 0 : *err_ret = -EINVAL;
699 : 0 : return;
700 : : }
701 : :
702 : 0 : ret = mmc_io_rw_direct(func->card, 1, 0, addr, b, NULL);
703 [ # # ]: 0 : if (err_ret)
704 : 0 : *err_ret = ret;
705 : : }
706 : : EXPORT_SYMBOL_GPL(sdio_f0_writeb);
707 : :
708 : : /**
709 : : * sdio_get_host_pm_caps - get host power management capabilities
710 : : * @func: SDIO function attached to host
711 : : *
712 : : * Returns a capability bitmask corresponding to power management
713 : : * features supported by the host controller that the card function
714 : : * might rely upon during a system suspend. The host doesn't need
715 : : * to be claimed, nor the function active, for this information to be
716 : : * obtained.
717 : : */
718 : 0 : mmc_pm_flag_t sdio_get_host_pm_caps(struct sdio_func *func)
719 : : {
720 [ # # ]: 0 : BUG_ON(!func);
721 [ # # ]: 0 : BUG_ON(!func->card);
722 : :
723 : 0 : return func->card->host->pm_caps;
724 : : }
725 : : EXPORT_SYMBOL_GPL(sdio_get_host_pm_caps);
726 : :
727 : : /**
728 : : * sdio_set_host_pm_flags - set wanted host power management capabilities
729 : : * @func: SDIO function attached to host
730 : : *
731 : : * Set a capability bitmask corresponding to wanted host controller
732 : : * power management features for the upcoming suspend state.
733 : : * This must be called, if needed, each time the suspend method of
734 : : * the function driver is called, and must contain only bits that
735 : : * were returned by sdio_get_host_pm_caps().
736 : : * The host doesn't need to be claimed, nor the function active,
737 : : * for this information to be set.
738 : : */
739 : 0 : int sdio_set_host_pm_flags(struct sdio_func *func, mmc_pm_flag_t flags)
740 : : {
741 : : struct mmc_host *host;
742 : :
743 [ # # ]: 0 : BUG_ON(!func);
744 [ # # ]: 0 : BUG_ON(!func->card);
745 : :
746 : 0 : host = func->card->host;
747 : :
748 [ # # ]: 0 : if (flags & ~host->pm_caps)
749 : : return -EINVAL;
750 : :
751 : : /* function suspend methods are serialized, hence no lock needed */
752 : 0 : host->pm_flags |= flags;
753 : 0 : return 0;
754 : : }
755 : : EXPORT_SYMBOL_GPL(sdio_set_host_pm_flags);
|