aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/misc/tifm_7xx1.c3
-rw-r--r--drivers/misc/tifm_core.c11
-rw-r--r--drivers/mmc/tifm_sd.c205
-rw-r--r--include/linux/tifm.h5
4 files changed, 116 insertions, 108 deletions
diff --git a/drivers/misc/tifm_7xx1.c b/drivers/misc/tifm_7xx1.c
index 2ab7add78f94..50c4cdabb654 100644
--- a/drivers/misc/tifm_7xx1.c
+++ b/drivers/misc/tifm_7xx1.c
@@ -201,11 +201,12 @@ static void tifm_7xx1_insert_media(struct work_struct *work)
201 fm->max_sockets == 2); 201 fm->max_sockets == 2);
202 if (media_id) { 202 if (media_id) {
203 ok_to_register = 0; 203 ok_to_register = 0;
204 new_sock = tifm_alloc_device(fm, cnt); 204 new_sock = tifm_alloc_device(fm);
205 if (new_sock) { 205 if (new_sock) {
206 new_sock->addr = tifm_7xx1_sock_addr(fm->addr, 206 new_sock->addr = tifm_7xx1_sock_addr(fm->addr,
207 cnt); 207 cnt);
208 new_sock->media_id = media_id; 208 new_sock->media_id = media_id;
209 new_sock->socket_id = cnt;
209 switch (media_id) { 210 switch (media_id) {
210 case 1: 211 case 1:
211 card_name = "xd"; 212 card_name = "xd";
diff --git a/drivers/misc/tifm_core.c b/drivers/misc/tifm_core.c
index d61df5c3ac36..21eb0ab7c329 100644
--- a/drivers/misc/tifm_core.c
+++ b/drivers/misc/tifm_core.c
@@ -141,24 +141,17 @@ EXPORT_SYMBOL(tifm_remove_adapter);
141void tifm_free_device(struct device *dev) 141void tifm_free_device(struct device *dev)
142{ 142{
143 struct tifm_dev *fm_dev = container_of(dev, struct tifm_dev, dev); 143 struct tifm_dev *fm_dev = container_of(dev, struct tifm_dev, dev);
144 if (fm_dev->wq)
145 destroy_workqueue(fm_dev->wq);
146 kfree(fm_dev); 144 kfree(fm_dev);
147} 145}
148EXPORT_SYMBOL(tifm_free_device); 146EXPORT_SYMBOL(tifm_free_device);
149 147
150struct tifm_dev *tifm_alloc_device(struct tifm_adapter *fm, unsigned int id) 148struct tifm_dev *tifm_alloc_device(struct tifm_adapter *fm)
151{ 149{
152 struct tifm_dev *dev = kzalloc(sizeof(struct tifm_dev), GFP_KERNEL); 150 struct tifm_dev *dev = kzalloc(sizeof(struct tifm_dev), GFP_KERNEL);
153 151
154 if (dev) { 152 if (dev) {
155 spin_lock_init(&dev->lock); 153 spin_lock_init(&dev->lock);
156 snprintf(dev->wq_name, KOBJ_NAME_LEN, "tifm%u:%u", fm->id, id); 154
157 dev->wq = create_singlethread_workqueue(dev->wq_name);
158 if (!dev->wq) {
159 kfree(dev);
160 return NULL;
161 }
162 dev->dev.parent = fm->dev; 155 dev->dev.parent = fm->dev;
163 dev->dev.bus = &tifm_bus_type; 156 dev->dev.bus = &tifm_bus_type;
164 dev->dev.release = tifm_free_device; 157 dev->dev.release = tifm_free_device;
diff --git a/drivers/mmc/tifm_sd.c b/drivers/mmc/tifm_sd.c
index 5817a138a1e4..85a5974318b4 100644
--- a/drivers/mmc/tifm_sd.c
+++ b/drivers/mmc/tifm_sd.c
@@ -79,7 +79,6 @@ typedef enum {
79 79
80enum { 80enum {
81 FIFO_RDY = 0x0001, /* hardware dependent value */ 81 FIFO_RDY = 0x0001, /* hardware dependent value */
82 HOST_REG = 0x0002,
83 EJECT = 0x0004, 82 EJECT = 0x0004,
84 EJECT_DONE = 0x0008, 83 EJECT_DONE = 0x0008,
85 CARD_BUSY = 0x0010, 84 CARD_BUSY = 0x0010,
@@ -97,10 +96,10 @@ struct tifm_sd {
97 unsigned int clk_div; 96 unsigned int clk_div;
98 unsigned long timeout_jiffies; 97 unsigned long timeout_jiffies;
99 98
99 struct tasklet_struct finish_tasklet;
100 struct timer_list timer; 100 struct timer_list timer;
101 struct mmc_request *req; 101 struct mmc_request *req;
102 struct work_struct cmd_handler; 102 wait_queue_head_t notify;
103 wait_queue_head_t can_eject;
104 103
105 size_t written_blocks; 104 size_t written_blocks;
106 size_t buffer_size; 105 size_t buffer_size;
@@ -317,7 +316,7 @@ change_state:
317 } 316 }
318 break; 317 break;
319 case READY: 318 case READY:
320 queue_work(sock->wq, &host->cmd_handler); 319 tasklet_schedule(&host->finish_tasklet);
321 return; 320 return;
322 } 321 }
323 322
@@ -345,8 +344,6 @@ static unsigned int tifm_sd_signal_irq(struct tifm_dev *sock,
345 host_status = readl(sock->addr + SOCK_MMCSD_STATUS); 344 host_status = readl(sock->addr + SOCK_MMCSD_STATUS);
346 writel(host_status, sock->addr + SOCK_MMCSD_STATUS); 345 writel(host_status, sock->addr + SOCK_MMCSD_STATUS);
347 346
348 if (!(host->flags & HOST_REG))
349 queue_work(sock->wq, &host->cmd_handler);
350 if (!host->req) 347 if (!host->req)
351 goto done; 348 goto done;
352 349
@@ -517,9 +514,9 @@ err_out:
517 mmc_request_done(mmc, mrq); 514 mmc_request_done(mmc, mrq);
518} 515}
519 516
520static void tifm_sd_end_cmd(struct work_struct *work) 517static void tifm_sd_end_cmd(unsigned long data)
521{ 518{
522 struct tifm_sd *host = container_of(work, struct tifm_sd, cmd_handler); 519 struct tifm_sd *host = (struct tifm_sd*)data;
523 struct tifm_dev *sock = host->dev; 520 struct tifm_dev *sock = host->dev;
524 struct mmc_host *mmc = tifm_get_drvdata(sock); 521 struct mmc_host *mmc = tifm_get_drvdata(sock);
525 struct mmc_request *mrq; 522 struct mmc_request *mrq;
@@ -616,9 +613,9 @@ err_out:
616 mmc_request_done(mmc, mrq); 613 mmc_request_done(mmc, mrq);
617} 614}
618 615
619static void tifm_sd_end_cmd_nodma(struct work_struct *work) 616static void tifm_sd_end_cmd_nodma(unsigned long data)
620{ 617{
621 struct tifm_sd *host = container_of(work, struct tifm_sd, cmd_handler); 618 struct tifm_sd *host = (struct tifm_sd*)data;
622 struct tifm_dev *sock = host->dev; 619 struct tifm_dev *sock = host->dev;
623 struct mmc_host *mmc = tifm_get_drvdata(sock); 620 struct mmc_host *mmc = tifm_get_drvdata(sock);
624 struct mmc_request *mrq; 621 struct mmc_request *mrq;
@@ -666,11 +663,33 @@ static void tifm_sd_end_cmd_nodma(struct work_struct *work)
666 mmc_request_done(mmc, mrq); 663 mmc_request_done(mmc, mrq);
667} 664}
668 665
666static void tifm_sd_terminate(struct tifm_sd *host)
667{
668 struct tifm_dev *sock = host->dev;
669 unsigned long flags;
670
671 writel(0, sock->addr + SOCK_MMCSD_INT_ENABLE);
672 mmiowb();
673 spin_lock_irqsave(&sock->lock, flags);
674 host->flags |= EJECT;
675 if (host->req) {
676 writel(TIFM_FIFO_INT_SETALL,
677 sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR);
678 writel(0, sock->addr + SOCK_DMA_FIFO_INT_ENABLE_SET);
679 tasklet_schedule(&host->finish_tasklet);
680 }
681 spin_unlock_irqrestore(&sock->lock, flags);
682}
683
669static void tifm_sd_abort(unsigned long data) 684static void tifm_sd_abort(unsigned long data)
670{ 685{
686 struct tifm_sd *host = (struct tifm_sd*)data;
687
671 printk(KERN_ERR DRIVER_NAME 688 printk(KERN_ERR DRIVER_NAME
672 ": card failed to respond for a long period of time"); 689 ": card failed to respond for a long period of time");
673 tifm_eject(((struct tifm_sd*)data)->dev); 690
691 tifm_sd_terminate(host);
692 tifm_eject(host->dev);
674} 693}
675 694
676static void tifm_sd_ios(struct mmc_host *mmc, struct mmc_ios *ios) 695static void tifm_sd_ios(struct mmc_host *mmc, struct mmc_ios *ios)
@@ -739,7 +758,7 @@ static void tifm_sd_ios(struct mmc_host *mmc, struct mmc_ios *ios)
739 // allow removal. 758 // allow removal.
740 if ((host->flags & EJECT) && ios->power_mode == MMC_POWER_OFF) { 759 if ((host->flags & EJECT) && ios->power_mode == MMC_POWER_OFF) {
741 host->flags |= EJECT_DONE; 760 host->flags |= EJECT_DONE;
742 wake_up_all(&host->can_eject); 761 wake_up_all(&host->notify);
743 } 762 }
744 763
745 spin_unlock_irqrestore(&sock->lock, flags); 764 spin_unlock_irqrestore(&sock->lock, flags);
@@ -767,21 +786,67 @@ static struct mmc_host_ops tifm_sd_ops = {
767 .get_ro = tifm_sd_ro 786 .get_ro = tifm_sd_ro
768}; 787};
769 788
770static void tifm_sd_register_host(struct work_struct *work) 789static int tifm_sd_initialize_host(struct tifm_sd *host)
771{ 790{
772 struct tifm_sd *host = container_of(work, struct tifm_sd, cmd_handler); 791 int rc;
792 unsigned int host_status = 0;
773 struct tifm_dev *sock = host->dev; 793 struct tifm_dev *sock = host->dev;
774 struct mmc_host *mmc = tifm_get_drvdata(sock);
775 unsigned long flags;
776 794
777 spin_lock_irqsave(&sock->lock, flags); 795 writel(0, sock->addr + SOCK_MMCSD_INT_ENABLE);
778 del_timer(&host->timer); 796 mmiowb();
779 host->flags |= HOST_REG; 797 host->clk_div = 61;
780 PREPARE_WORK(&host->cmd_handler, 798 host->clk_freq = 20000000;
781 no_dma ? tifm_sd_end_cmd_nodma : tifm_sd_end_cmd); 799 writel(TIFM_MMCSD_RESET, sock->addr + SOCK_MMCSD_SYSTEM_CONTROL);
782 spin_unlock_irqrestore(&sock->lock, flags); 800 writel(host->clk_div | TIFM_MMCSD_POWER,
783 dev_dbg(&sock->dev, "adding host\n"); 801 sock->addr + SOCK_MMCSD_CONFIG);
784 mmc_add_host(mmc); 802
803 /* wait up to 0.51 sec for reset */
804 for (rc = 2; rc <= 256; rc <<= 1) {
805 if (1 & readl(sock->addr + SOCK_MMCSD_SYSTEM_STATUS)) {
806 rc = 0;
807 break;
808 }
809 msleep(rc);
810 }
811
812 if (rc) {
813 printk(KERN_ERR DRIVER_NAME
814 ": controller failed to reset\n");
815 return -ENODEV;
816 }
817
818 writel(0, sock->addr + SOCK_MMCSD_NUM_BLOCKS);
819 writel(host->clk_div | TIFM_MMCSD_POWER,
820 sock->addr + SOCK_MMCSD_CONFIG);
821 writel(TIFM_MMCSD_RXDE, sock->addr + SOCK_MMCSD_BUFFER_CONFIG);
822
823 // command timeout fixed to 64 clocks for now
824 writel(64, sock->addr + SOCK_MMCSD_COMMAND_TO);
825 writel(TIFM_MMCSD_INAB, sock->addr + SOCK_MMCSD_COMMAND);
826
827 /* INAB should take much less than reset */
828 for (rc = 1; rc <= 16; rc <<= 1) {
829 host_status = readl(sock->addr + SOCK_MMCSD_STATUS);
830 writel(host_status, sock->addr + SOCK_MMCSD_STATUS);
831 if (!(host_status & TIFM_MMCSD_ERRMASK)
832 && (host_status & TIFM_MMCSD_EOC)) {
833 rc = 0;
834 break;
835 }
836 msleep(rc);
837 }
838
839 if (rc) {
840 printk(KERN_ERR DRIVER_NAME
841 ": card not ready - probe failed on initialization\n");
842 return -ENODEV;
843 }
844
845 writel(TIFM_MMCSD_DATAMASK | TIFM_MMCSD_ERRMASK,
846 sock->addr + SOCK_MMCSD_INT_ENABLE);
847 mmiowb();
848
849 return 0;
785} 850}
786 851
787static int tifm_sd_probe(struct tifm_dev *sock) 852static int tifm_sd_probe(struct tifm_dev *sock)
@@ -801,77 +866,37 @@ static int tifm_sd_probe(struct tifm_dev *sock)
801 return -ENOMEM; 866 return -ENOMEM;
802 867
803 host = mmc_priv(mmc); 868 host = mmc_priv(mmc);
804 host->dev = sock;
805 host->clk_div = 61;
806 init_waitqueue_head(&host->can_eject);
807 INIT_WORK(&host->cmd_handler, tifm_sd_register_host);
808 setup_timer(&host->timer, tifm_sd_abort, (unsigned long)host);
809
810 tifm_set_drvdata(sock, mmc); 869 tifm_set_drvdata(sock, mmc);
811 sock->signal_irq = tifm_sd_signal_irq; 870 host->dev = sock;
812
813 host->clk_freq = 20000000;
814 host->timeout_jiffies = msecs_to_jiffies(1000); 871 host->timeout_jiffies = msecs_to_jiffies(1000);
815 872
873 init_waitqueue_head(&host->notify);
874 tasklet_init(&host->finish_tasklet,
875 no_dma ? tifm_sd_end_cmd_nodma : tifm_sd_end_cmd,
876 (unsigned long)host);
877 setup_timer(&host->timer, tifm_sd_abort, (unsigned long)host);
878
816 tifm_sd_ops.request = no_dma ? tifm_sd_request_nodma : tifm_sd_request; 879 tifm_sd_ops.request = no_dma ? tifm_sd_request_nodma : tifm_sd_request;
817 mmc->ops = &tifm_sd_ops; 880 mmc->ops = &tifm_sd_ops;
818 mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; 881 mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
819 mmc->caps = MMC_CAP_4_BIT_DATA; 882 mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_MULTIWRITE;
820 mmc->f_min = 20000000 / 60; 883 mmc->f_min = 20000000 / 60;
821 mmc->f_max = 24000000; 884 mmc->f_max = 24000000;
822 mmc->max_hw_segs = 1; 885 mmc->max_hw_segs = 1;
823 mmc->max_phys_segs = 1; 886 mmc->max_phys_segs = 1;
824 mmc->max_sectors = 127; 887 mmc->max_sectors = 127;
825 mmc->max_seg_size = mmc->max_sectors << 11; //2k maximum hw block length 888 mmc->max_seg_size = mmc->max_sectors << 11; //2k maximum hw block length
889 sock->signal_irq = tifm_sd_signal_irq;
890 rc = tifm_sd_initialize_host(host);
826 891
827 writel(0, sock->addr + SOCK_MMCSD_INT_ENABLE); 892 if (!rc)
828 writel(TIFM_MMCSD_RESET, sock->addr + SOCK_MMCSD_SYSTEM_CONTROL); 893 rc = mmc_add_host(mmc);
829 writel(host->clk_div | TIFM_MMCSD_POWER, 894 if (rc)
830 sock->addr + SOCK_MMCSD_CONFIG); 895 goto out_free_mmc;
831
832 for (rc = 0; rc < 50; rc++) {
833 /* Wait for reset ack */
834 if (1 & readl(sock->addr + SOCK_MMCSD_SYSTEM_STATUS)) {
835 rc = 0;
836 break;
837 }
838 msleep(10);
839 }
840
841 if (rc) {
842 printk(KERN_ERR DRIVER_NAME
843 ": card not ready - probe failed\n");
844 mmc_free_host(mmc);
845 return -ENODEV;
846 }
847
848 writel(0, sock->addr + SOCK_MMCSD_NUM_BLOCKS);
849 writel(host->clk_div | TIFM_MMCSD_POWER,
850 sock->addr + SOCK_MMCSD_CONFIG);
851 writel(TIFM_MMCSD_RXDE, sock->addr + SOCK_MMCSD_BUFFER_CONFIG);
852 writel(TIFM_MMCSD_DATAMASK | TIFM_MMCSD_ERRMASK,
853 sock->addr + SOCK_MMCSD_INT_ENABLE);
854
855 writel(64, sock->addr + SOCK_MMCSD_COMMAND_TO); // command timeout 64 clocks for now
856 writel(TIFM_MMCSD_INAB, sock->addr + SOCK_MMCSD_COMMAND);
857 writel(host->clk_div | TIFM_MMCSD_POWER,
858 sock->addr + SOCK_MMCSD_CONFIG);
859
860 mod_timer(&host->timer, jiffies + host->timeout_jiffies);
861 896
862 return 0; 897 return 0;
863} 898out_free_mmc:
864 899 mmc_free_host(mmc);
865static int tifm_sd_host_is_down(struct tifm_dev *sock)
866{
867 struct mmc_host *mmc = tifm_get_drvdata(sock);
868 struct tifm_sd *host = mmc_priv(mmc);
869 unsigned long flags;
870 int rc = 0;
871
872 spin_lock_irqsave(&sock->lock, flags);
873 rc = (host->flags & EJECT_DONE);
874 spin_unlock_irqrestore(&sock->lock, flags);
875 return rc; 900 return rc;
876} 901}
877 902
@@ -879,27 +904,17 @@ static void tifm_sd_remove(struct tifm_dev *sock)
879{ 904{
880 struct mmc_host *mmc = tifm_get_drvdata(sock); 905 struct mmc_host *mmc = tifm_get_drvdata(sock);
881 struct tifm_sd *host = mmc_priv(mmc); 906 struct tifm_sd *host = mmc_priv(mmc);
882 unsigned long flags;
883 907
884 del_timer_sync(&host->timer); 908 del_timer_sync(&host->timer);
885 spin_lock_irqsave(&sock->lock, flags); 909 tifm_sd_terminate(host);
886 host->flags |= EJECT; 910 wait_event_timeout(host->notify, host->flags & EJECT_DONE,
887 if (host->req) 911 host->timeout_jiffies);
888 queue_work(sock->wq, &host->cmd_handler); 912 tasklet_kill(&host->finish_tasklet);
889 spin_unlock_irqrestore(&sock->lock, flags); 913 mmc_remove_host(mmc);
890 wait_event_timeout(host->can_eject, tifm_sd_host_is_down(sock),
891 host->timeout_jiffies);
892
893 if (host->flags & HOST_REG)
894 mmc_remove_host(mmc);
895 914
896 /* The meaning of the bit majority in this constant is unknown. */ 915 /* The meaning of the bit majority in this constant is unknown. */
897 writel(0xfff8 & readl(sock->addr + SOCK_CONTROL), 916 writel(0xfff8 & readl(sock->addr + SOCK_CONTROL),
898 sock->addr + SOCK_CONTROL); 917 sock->addr + SOCK_CONTROL);
899 writel(0, sock->addr + SOCK_MMCSD_INT_ENABLE);
900 writel(TIFM_FIFO_INT_SETALL,
901 sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR);
902 writel(0, sock->addr + SOCK_DMA_FIFO_INT_ENABLE_SET);
903 918
904 tifm_set_drvdata(sock, NULL); 919 tifm_set_drvdata(sock, NULL);
905 mmc_free_host(mmc); 920 mmc_free_host(mmc);
diff --git a/include/linux/tifm.h b/include/linux/tifm.h
index dfb8052eee5e..9caa28e2a63c 100644
--- a/include/linux/tifm.h
+++ b/include/linux/tifm.h
@@ -89,8 +89,7 @@ struct tifm_dev {
89 char __iomem *addr; 89 char __iomem *addr;
90 spinlock_t lock; 90 spinlock_t lock;
91 tifm_media_id media_id; 91 tifm_media_id media_id;
92 char wq_name[KOBJ_NAME_LEN]; 92 unsigned int socket_id;
93 struct workqueue_struct *wq;
94 93
95 unsigned int (*signal_irq)(struct tifm_dev *sock, 94 unsigned int (*signal_irq)(struct tifm_dev *sock,
96 unsigned int sock_irq_status); 95 unsigned int sock_irq_status);
@@ -132,7 +131,7 @@ void tifm_free_device(struct device *dev);
132void tifm_free_adapter(struct tifm_adapter *fm); 131void tifm_free_adapter(struct tifm_adapter *fm);
133int tifm_add_adapter(struct tifm_adapter *fm); 132int tifm_add_adapter(struct tifm_adapter *fm);
134void tifm_remove_adapter(struct tifm_adapter *fm); 133void tifm_remove_adapter(struct tifm_adapter *fm);
135struct tifm_dev *tifm_alloc_device(struct tifm_adapter *fm, unsigned int id); 134struct tifm_dev *tifm_alloc_device(struct tifm_adapter *fm);
136int tifm_register_driver(struct tifm_driver *drv); 135int tifm_register_driver(struct tifm_driver *drv);
137void tifm_unregister_driver(struct tifm_driver *drv); 136void tifm_unregister_driver(struct tifm_driver *drv);
138void tifm_eject(struct tifm_dev *sock); 137void tifm_eject(struct tifm_dev *sock);