Commit 23c5947ac3f7a610bb4cb9e433802b36edc80fdf

Authored by Takashi Iwai
Committed by Linus Torvalds
1 parent 0193383a58

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;