aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/memstick/host
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2011-01-12 20:01:01 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2011-01-13 11:03:21 -0500
commit23c5947ac3f7a610bb4cb9e433802b36edc80fdf (patch)
tree6207b2375c61d2bd7e661cac5d1f0b60fb2b23e8 /drivers/memstick/host
parent0193383a5833c1f082c738eaca868e4093a8df39 (diff)
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>
Diffstat (limited to 'drivers/memstick/host')
-rw-r--r--drivers/memstick/host/jmb38x_ms.c66
1 files changed, 36 insertions, 30 deletions
diff --git a/drivers/memstick/host/jmb38x_ms.c b/drivers/memstick/host/jmb38x_ms.c
index f2b894cd8b02..c90ba5082252 100644
--- a/drivers/memstick/host/jmb38x_ms.c
+++ b/drivers/memstick/host/jmb38x_ms.c
@@ -61,6 +61,7 @@ struct jmb38x_ms_host {
61 struct memstick_request *req; 61 struct memstick_request *req;
62 unsigned char cmd_flags; 62 unsigned char cmd_flags;
63 unsigned char io_pos; 63 unsigned char io_pos;
64 unsigned char ifmode;
64 unsigned int io_word[2]; 65 unsigned int io_word[2];
65}; 66};
66 67
@@ -136,15 +137,14 @@ struct jmb38x_ms {
136#define PAD_PU_PD_ON_MS_SOCK0 0x5f8f0000 137#define PAD_PU_PD_ON_MS_SOCK0 0x5f8f0000
137#define PAD_PU_PD_ON_MS_SOCK1 0x0f0f0000 138#define PAD_PU_PD_ON_MS_SOCK1 0x0f0f0000
138 139
140#define CLOCK_CONTROL_BY_MMIO 0x00000008
139#define CLOCK_CONTROL_40MHZ 0x00000001 141#define CLOCK_CONTROL_40MHZ 0x00000001
140#define CLOCK_CONTROL_50MHZ 0x0000000a 142#define CLOCK_CONTROL_50MHZ 0x00000002
141#define CLOCK_CONTROL_60MHZ 0x00000008 143#define CLOCK_CONTROL_60MHZ 0x00000010
142#define CLOCK_CONTROL_62_5MHZ 0x0000000c 144#define CLOCK_CONTROL_62_5MHZ 0x00000004
143#define CLOCK_CONTROL_OFF 0x00000000 145#define CLOCK_CONTROL_OFF 0x00000000
144 146
145#define PCI_CTL_CLOCK_DLY_ADDR 0x000000b0 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
149enum { 149enum {
150 CMD_READY = 0x01, 150 CMD_READY = 0x01,
@@ -390,8 +390,13 @@ static int jmb38x_ms_issue_cmd(struct memstick_host *msh)
390 390
391 if (host->req->data_dir == READ) 391 if (host->req->data_dir == READ)
392 cmd |= TPC_DIR; 392 cmd |= TPC_DIR;
393 if (host->req->need_card_int) 393
394 cmd |= TPC_WAIT_INT; 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 }
395 400
396 data = host->req->data; 401 data = host->req->data;
397 402
@@ -529,7 +534,10 @@ static irqreturn_t jmb38x_ms_isr(int irq, void *dev_id)
529 if (irq_status & INT_STATUS_ANY_ERR) { 534 if (irq_status & INT_STATUS_ANY_ERR) {
530 if (irq_status & INT_STATUS_CRC_ERR) 535 if (irq_status & INT_STATUS_CRC_ERR)
531 host->req->error = -EILSEQ; 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 host->req->error = -ETIME; 541 host->req->error = -ETIME;
534 } else { 542 } else {
535 if (host->cmd_flags & DMA_DATA) { 543 if (host->cmd_flags & DMA_DATA) {
@@ -644,7 +652,6 @@ static int jmb38x_ms_reset(struct jmb38x_ms_host *host)
644 ndelay(20); 652 ndelay(20);
645 } 653 }
646 dev_dbg(&host->chip->pdev->dev, "reset_req timeout\n"); 654 dev_dbg(&host->chip->pdev->dev, "reset_req timeout\n");
647 /* return -EIO; */
648 655
649reset_next: 656reset_next:
650 writel(HOST_CONTROL_RESET | HOST_CONTROL_CLOCK_EN 657 writel(HOST_CONTROL_RESET | HOST_CONTROL_CLOCK_EN
@@ -675,7 +682,7 @@ static int jmb38x_ms_set_param(struct memstick_host *msh,
675{ 682{
676 struct jmb38x_ms_host *host = memstick_priv(msh); 683 struct jmb38x_ms_host *host = memstick_priv(msh);
677 unsigned int host_ctl = readl(host->addr + HOST_CONTROL); 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 int rc = 0; 686 int rc = 0;
680 687
681 switch (param) { 688 switch (param) {
@@ -687,9 +694,7 @@ static int jmb38x_ms_set_param(struct memstick_host *msh,
687 694
688 host_ctl = 7; 695 host_ctl = 7;
689 host_ctl |= HOST_CONTROL_POWER_EN 696 host_ctl |= HOST_CONTROL_POWER_EN
690 | HOST_CONTROL_CLOCK_EN 697 | HOST_CONTROL_CLOCK_EN;
691 | HOST_CONTROL_HW_OC_P
692 | HOST_CONTROL_TDELAY_EN;
693 writel(host_ctl, host->addr + HOST_CONTROL); 698 writel(host_ctl, host->addr + HOST_CONTROL);
694 699
695 writel(host->id ? PAD_PU_PD_ON_MS_SOCK1 700 writel(host->id ? PAD_PU_PD_ON_MS_SOCK1
@@ -712,41 +717,42 @@ static int jmb38x_ms_set_param(struct memstick_host *msh,
712 return -EINVAL; 717 return -EINVAL;
713 break; 718 break;
714 case MEMSTICK_INTERFACE: 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 host_ctl &= ~(3 << HOST_CONTROL_IF_SHIFT); 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 if (value == MEMSTICK_SERIAL) { 727 if (value == MEMSTICK_SERIAL) {
723 host_ctl &= ~HOST_CONTROL_FAST_CLK;
724 host_ctl &= ~HOST_CONTROL_REO;
725 host_ctl |= HOST_CONTROL_IF_SERIAL 728 host_ctl |= HOST_CONTROL_IF_SERIAL
726 << HOST_CONTROL_IF_SHIFT; 729 << HOST_CONTROL_IF_SHIFT;
727 host_ctl |= HOST_CONTROL_REI; 730 host_ctl |= HOST_CONTROL_REI;
728 clock_ctl = CLOCK_CONTROL_40MHZ; 731 clock_ctl |= CLOCK_CONTROL_40MHZ;
732 clock_delay = 0;
729 } else if (value == MEMSTICK_PAR4) { 733 } else if (value == MEMSTICK_PAR4) {
730 host_ctl |= HOST_CONTROL_FAST_CLK | HOST_CONTROL_REO; 734 host_ctl |= HOST_CONTROL_FAST_CLK;
731 host_ctl |= HOST_CONTROL_IF_PAR4 735 host_ctl |= HOST_CONTROL_IF_PAR4
732 << HOST_CONTROL_IF_SHIFT; 736 << HOST_CONTROL_IF_SHIFT;
733 host_ctl &= ~HOST_CONTROL_REI; 737 host_ctl |= HOST_CONTROL_REO;
734 clock_ctl = CLOCK_CONTROL_40MHZ; 738 clock_ctl |= CLOCK_CONTROL_40MHZ;
735 clock_delay |= host->id ? (4 << 12) : (4 << 8); 739 clock_delay = 4;
736 } else if (value == MEMSTICK_PAR8) { 740 } else if (value == MEMSTICK_PAR8) {
737 host_ctl |= HOST_CONTROL_FAST_CLK; 741 host_ctl |= HOST_CONTROL_FAST_CLK;
738 host_ctl |= HOST_CONTROL_IF_PAR8 742 host_ctl |= HOST_CONTROL_IF_PAR8
739 << HOST_CONTROL_IF_SHIFT; 743 << HOST_CONTROL_IF_SHIFT;
740 host_ctl &= ~(HOST_CONTROL_REI | HOST_CONTROL_REO); 744 clock_ctl |= CLOCK_CONTROL_50MHZ;
741 clock_ctl = CLOCK_CONTROL_50MHZ; 745 clock_delay = 0;
742 } else 746 } else
743 return -EINVAL; 747 return -EINVAL;
744 748
745 writel(host_ctl, host->addr + HOST_CONTROL); 749 writel(host_ctl, host->addr + HOST_CONTROL);
750 writel(CLOCK_CONTROL_OFF, host->addr + CLOCK_CONTROL);
746 writel(clock_ctl, host->addr + CLOCK_CONTROL); 751 writel(clock_ctl, host->addr + CLOCK_CONTROL);
747 pci_write_config_dword(host->chip->pdev, 752 pci_write_config_byte(host->chip->pdev,
748 PCI_CTL_CLOCK_DLY_ADDR, 753 PCI_CTL_CLOCK_DLY_ADDR + 1,
749 clock_delay); 754 clock_delay);
755 host->ifmode = value;
750 break; 756 break;
751 }; 757 };
752 return 0; 758 return 0;