.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * cb710/mmc.c |
---|
3 | 4 | * |
---|
4 | 5 | * Copyright by Michał Mirosław, 2008-2009 |
---|
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 version 2 as |
---|
8 | | - * published by the Free Software Foundation. |
---|
9 | 6 | */ |
---|
10 | 7 | #include <linux/kernel.h> |
---|
11 | 8 | #include <linux/module.h> |
---|
12 | 9 | #include <linux/pci.h> |
---|
13 | 10 | #include <linux/delay.h> |
---|
14 | 11 | #include "cb710-mmc.h" |
---|
| 12 | + |
---|
| 13 | +#define CB710_MMC_REQ_TIMEOUT_MS 2000 |
---|
15 | 14 | |
---|
16 | 15 | static const u8 cb710_clock_divider_log2[8] = { |
---|
17 | 16 | /* 1, 2, 4, 8, 16, 32, 128, 512 */ |
---|
.. | .. |
---|
566 | 565 | |
---|
567 | 566 | cb710_mmc_select_clock_divider(mmc, ios->clock); |
---|
568 | 567 | |
---|
569 | | - if (ios->power_mode != reader->last_power_mode) |
---|
570 | | - switch (ios->power_mode) { |
---|
571 | | - case MMC_POWER_ON: |
---|
572 | | - err = cb710_mmc_powerup(slot); |
---|
573 | | - if (err) { |
---|
574 | | - dev_warn(cb710_slot_dev(slot), |
---|
575 | | - "powerup failed (%d)- retrying\n", err); |
---|
576 | | - cb710_mmc_powerdown(slot); |
---|
577 | | - udelay(1); |
---|
| 568 | + if (ios->power_mode != reader->last_power_mode) { |
---|
| 569 | + switch (ios->power_mode) { |
---|
| 570 | + case MMC_POWER_ON: |
---|
578 | 571 | err = cb710_mmc_powerup(slot); |
---|
579 | | - if (err) |
---|
| 572 | + if (err) { |
---|
580 | 573 | dev_warn(cb710_slot_dev(slot), |
---|
581 | | - "powerup retry failed (%d) - expect errors\n", |
---|
| 574 | + "powerup failed (%d)- retrying\n", err); |
---|
| 575 | + cb710_mmc_powerdown(slot); |
---|
| 576 | + udelay(1); |
---|
| 577 | + err = cb710_mmc_powerup(slot); |
---|
| 578 | + if (err) |
---|
| 579 | + dev_warn(cb710_slot_dev(slot), |
---|
| 580 | + "powerup retry failed (%d) - expect errors\n", |
---|
582 | 581 | err); |
---|
| 582 | + } |
---|
| 583 | + reader->last_power_mode = MMC_POWER_ON; |
---|
| 584 | + break; |
---|
| 585 | + case MMC_POWER_OFF: |
---|
| 586 | + cb710_mmc_powerdown(slot); |
---|
| 587 | + reader->last_power_mode = MMC_POWER_OFF; |
---|
| 588 | + break; |
---|
| 589 | + case MMC_POWER_UP: |
---|
| 590 | + default: |
---|
| 591 | + /* ignore */ |
---|
| 592 | + break; |
---|
583 | 593 | } |
---|
584 | | - reader->last_power_mode = MMC_POWER_ON; |
---|
585 | | - break; |
---|
586 | | - case MMC_POWER_OFF: |
---|
587 | | - cb710_mmc_powerdown(slot); |
---|
588 | | - reader->last_power_mode = MMC_POWER_OFF; |
---|
589 | | - break; |
---|
590 | | - case MMC_POWER_UP: |
---|
591 | | - default: |
---|
592 | | - /* ignore */; |
---|
593 | 594 | } |
---|
594 | 595 | |
---|
595 | 596 | cb710_mmc_enable_4bit_data(slot, ios->bus_width != MMC_BUS_WIDTH_1); |
---|
.. | .. |
---|
708 | 709 | mmc->f_min = val >> cb710_clock_divider_log2[CB710_MAX_DIVIDER_IDX]; |
---|
709 | 710 | mmc->ocr_avail = MMC_VDD_32_33|MMC_VDD_33_34; |
---|
710 | 711 | mmc->caps = MMC_CAP_4_BIT_DATA; |
---|
| 712 | + /* |
---|
| 713 | + * In cb710_wait_for_event() we use a fixed timeout of ~2s, hence let's |
---|
| 714 | + * inform the core about it. A future improvement should instead make |
---|
| 715 | + * use of the cmd->busy_timeout. |
---|
| 716 | + */ |
---|
| 717 | + mmc->max_busy_timeout = CB710_MMC_REQ_TIMEOUT_MS; |
---|
711 | 718 | |
---|
712 | 719 | reader = mmc_priv(mmc); |
---|
713 | 720 | |
---|