Commit 23c5947ac3f7a610bb4cb9e433802b36edc80fdf
Committed by
Linus Torvalds
1 parent
0193383a58
Exists in
master
and in
4 other branches
memstick: fix setup for JMicron 38x controllers
This patch corrects the definition of clock values for JMicron 38x controllers and sets the value properly per interface type. Also, it adds a check for TPC errors in the interrupt handler. Signed-off-by: Aries Lee <arieslee@jmicron.com> Signed-off-by: Takashi Iwai <tiwai@suse.de> Cc: Alex Dubov <oakad@yahoo.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Showing 1 changed file with 36 additions and 30 deletions Side-by-side Diff
drivers/memstick/host/jmb38x_ms.c
... | ... | @@ -61,6 +61,7 @@ |
61 | 61 | struct memstick_request *req; |
62 | 62 | unsigned char cmd_flags; |
63 | 63 | unsigned char io_pos; |
64 | + unsigned char ifmode; | |
64 | 65 | unsigned int io_word[2]; |
65 | 66 | }; |
66 | 67 | |
67 | 68 | |
68 | 69 | |
... | ... | @@ -136,15 +137,14 @@ |
136 | 137 | #define PAD_PU_PD_ON_MS_SOCK0 0x5f8f0000 |
137 | 138 | #define PAD_PU_PD_ON_MS_SOCK1 0x0f0f0000 |
138 | 139 | |
140 | +#define CLOCK_CONTROL_BY_MMIO 0x00000008 | |
139 | 141 | #define CLOCK_CONTROL_40MHZ 0x00000001 |
140 | -#define CLOCK_CONTROL_50MHZ 0x0000000a | |
141 | -#define CLOCK_CONTROL_60MHZ 0x00000008 | |
142 | -#define CLOCK_CONTROL_62_5MHZ 0x0000000c | |
142 | +#define CLOCK_CONTROL_50MHZ 0x00000002 | |
143 | +#define CLOCK_CONTROL_60MHZ 0x00000010 | |
144 | +#define CLOCK_CONTROL_62_5MHZ 0x00000004 | |
143 | 145 | #define CLOCK_CONTROL_OFF 0x00000000 |
144 | 146 | |
145 | 147 | #define PCI_CTL_CLOCK_DLY_ADDR 0x000000b0 |
146 | -#define PCI_CTL_CLOCK_DLY_MASK_A 0x00000f00 | |
147 | -#define PCI_CTL_CLOCK_DLY_MASK_B 0x0000f000 | |
148 | 148 | |
149 | 149 | enum { |
150 | 150 | CMD_READY = 0x01, |
151 | 151 | |
... | ... | @@ -390,9 +390,14 @@ |
390 | 390 | |
391 | 391 | if (host->req->data_dir == READ) |
392 | 392 | cmd |= TPC_DIR; |
393 | - if (host->req->need_card_int) | |
394 | - cmd |= TPC_WAIT_INT; | |
395 | 393 | |
394 | + if (host->req->need_card_int) { | |
395 | + if (host->ifmode == MEMSTICK_SERIAL) | |
396 | + cmd |= TPC_GET_INT; | |
397 | + else | |
398 | + cmd |= TPC_WAIT_INT; | |
399 | + } | |
400 | + | |
396 | 401 | data = host->req->data; |
397 | 402 | |
398 | 403 | if (!no_dma) |
... | ... | @@ -529,7 +534,10 @@ |
529 | 534 | if (irq_status & INT_STATUS_ANY_ERR) { |
530 | 535 | if (irq_status & INT_STATUS_CRC_ERR) |
531 | 536 | host->req->error = -EILSEQ; |
532 | - else | |
537 | + else if (irq_status & INT_STATUS_TPC_ERR) { | |
538 | + dev_dbg(&host->chip->pdev->dev, "TPC_ERR\n"); | |
539 | + jmb38x_ms_complete_cmd(msh, 0); | |
540 | + } else | |
533 | 541 | host->req->error = -ETIME; |
534 | 542 | } else { |
535 | 543 | if (host->cmd_flags & DMA_DATA) { |
... | ... | @@ -644,7 +652,6 @@ |
644 | 652 | ndelay(20); |
645 | 653 | } |
646 | 654 | dev_dbg(&host->chip->pdev->dev, "reset_req timeout\n"); |
647 | - /* return -EIO; */ | |
648 | 655 | |
649 | 656 | reset_next: |
650 | 657 | writel(HOST_CONTROL_RESET | HOST_CONTROL_CLOCK_EN |
... | ... | @@ -675,7 +682,7 @@ |
675 | 682 | { |
676 | 683 | struct jmb38x_ms_host *host = memstick_priv(msh); |
677 | 684 | unsigned int host_ctl = readl(host->addr + HOST_CONTROL); |
678 | - unsigned int clock_ctl = CLOCK_CONTROL_40MHZ, clock_delay = 0; | |
685 | + unsigned int clock_ctl = CLOCK_CONTROL_BY_MMIO, clock_delay = 0; | |
679 | 686 | int rc = 0; |
680 | 687 | |
681 | 688 | switch (param) { |
... | ... | @@ -687,9 +694,7 @@ |
687 | 694 | |
688 | 695 | host_ctl = 7; |
689 | 696 | host_ctl |= HOST_CONTROL_POWER_EN |
690 | - | HOST_CONTROL_CLOCK_EN | |
691 | - | HOST_CONTROL_HW_OC_P | |
692 | - | HOST_CONTROL_TDELAY_EN; | |
697 | + | HOST_CONTROL_CLOCK_EN; | |
693 | 698 | writel(host_ctl, host->addr + HOST_CONTROL); |
694 | 699 | |
695 | 700 | writel(host->id ? PAD_PU_PD_ON_MS_SOCK1 |
696 | 701 | |
697 | 702 | |
698 | 703 | |
699 | 704 | |
700 | 705 | |
701 | 706 | |
702 | 707 | |
703 | 708 | |
... | ... | @@ -712,41 +717,42 @@ |
712 | 717 | return -EINVAL; |
713 | 718 | break; |
714 | 719 | case MEMSTICK_INTERFACE: |
720 | + dev_dbg(&host->chip->pdev->dev, | |
721 | + "Set Host Interface Mode to %d\n", value); | |
722 | + host_ctl &= ~(HOST_CONTROL_FAST_CLK | HOST_CONTROL_REI | | |
723 | + HOST_CONTROL_REO); | |
724 | + host_ctl |= HOST_CONTROL_TDELAY_EN | HOST_CONTROL_HW_OC_P; | |
715 | 725 | host_ctl &= ~(3 << HOST_CONTROL_IF_SHIFT); |
716 | - pci_read_config_dword(host->chip->pdev, | |
717 | - PCI_CTL_CLOCK_DLY_ADDR, | |
718 | - &clock_delay); | |
719 | - clock_delay &= host->id ? ~PCI_CTL_CLOCK_DLY_MASK_B | |
720 | - : ~PCI_CTL_CLOCK_DLY_MASK_A; | |
721 | 726 | |
722 | 727 | if (value == MEMSTICK_SERIAL) { |
723 | - host_ctl &= ~HOST_CONTROL_FAST_CLK; | |
724 | - host_ctl &= ~HOST_CONTROL_REO; | |
725 | 728 | host_ctl |= HOST_CONTROL_IF_SERIAL |
726 | 729 | << HOST_CONTROL_IF_SHIFT; |
727 | 730 | host_ctl |= HOST_CONTROL_REI; |
728 | - clock_ctl = CLOCK_CONTROL_40MHZ; | |
731 | + clock_ctl |= CLOCK_CONTROL_40MHZ; | |
732 | + clock_delay = 0; | |
729 | 733 | } else if (value == MEMSTICK_PAR4) { |
730 | - host_ctl |= HOST_CONTROL_FAST_CLK | HOST_CONTROL_REO; | |
734 | + host_ctl |= HOST_CONTROL_FAST_CLK; | |
731 | 735 | host_ctl |= HOST_CONTROL_IF_PAR4 |
732 | 736 | << HOST_CONTROL_IF_SHIFT; |
733 | - host_ctl &= ~HOST_CONTROL_REI; | |
734 | - clock_ctl = CLOCK_CONTROL_40MHZ; | |
735 | - clock_delay |= host->id ? (4 << 12) : (4 << 8); | |
737 | + host_ctl |= HOST_CONTROL_REO; | |
738 | + clock_ctl |= CLOCK_CONTROL_40MHZ; | |
739 | + clock_delay = 4; | |
736 | 740 | } else if (value == MEMSTICK_PAR8) { |
737 | 741 | host_ctl |= HOST_CONTROL_FAST_CLK; |
738 | 742 | host_ctl |= HOST_CONTROL_IF_PAR8 |
739 | 743 | << HOST_CONTROL_IF_SHIFT; |
740 | - host_ctl &= ~(HOST_CONTROL_REI | HOST_CONTROL_REO); | |
741 | - clock_ctl = CLOCK_CONTROL_50MHZ; | |
744 | + clock_ctl |= CLOCK_CONTROL_50MHZ; | |
745 | + clock_delay = 0; | |
742 | 746 | } else |
743 | 747 | return -EINVAL; |
744 | 748 | |
745 | 749 | writel(host_ctl, host->addr + HOST_CONTROL); |
750 | + writel(CLOCK_CONTROL_OFF, host->addr + CLOCK_CONTROL); | |
746 | 751 | writel(clock_ctl, host->addr + CLOCK_CONTROL); |
747 | - pci_write_config_dword(host->chip->pdev, | |
748 | - PCI_CTL_CLOCK_DLY_ADDR, | |
749 | - clock_delay); | |
752 | + pci_write_config_byte(host->chip->pdev, | |
753 | + PCI_CTL_CLOCK_DLY_ADDR + 1, | |
754 | + clock_delay); | |
755 | + host->ifmode = value; | |
750 | 756 | break; |
751 | 757 | }; |
752 | 758 | return 0; |