aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/misc/tifm_7xx1.c10
-rw-r--r--drivers/misc/tifm_core.c24
-rw-r--r--drivers/mmc/tifm_sd.c49
-rw-r--r--include/linux/tifm.h69
4 files changed, 80 insertions, 72 deletions
diff --git a/drivers/misc/tifm_7xx1.c b/drivers/misc/tifm_7xx1.c
index eafa5575f312..9dcff14e752c 100644
--- a/drivers/misc/tifm_7xx1.c
+++ b/drivers/misc/tifm_7xx1.c
@@ -10,8 +10,6 @@
10 */ 10 */
11 11
12#include <linux/tifm.h> 12#include <linux/tifm.h>
13#include <linux/dma-mapping.h>
14#include <linux/freezer.h>
15 13
16#define DRIVER_NAME "tifm_7xx1" 14#define DRIVER_NAME "tifm_7xx1"
17#define DRIVER_VERSION "0.8" 15#define DRIVER_VERSION "0.8"
@@ -41,8 +39,7 @@ static irqreturn_t tifm_7xx1_isr(int irq, void *dev_id)
41{ 39{
42 struct tifm_adapter *fm = dev_id; 40 struct tifm_adapter *fm = dev_id;
43 struct tifm_dev *sock; 41 struct tifm_dev *sock;
44 unsigned int irq_status; 42 unsigned int irq_status, cnt;
45 unsigned int cnt;
46 43
47 spin_lock(&fm->lock); 44 spin_lock(&fm->lock);
48 irq_status = readl(fm->addr + FM_INTERRUPT_STATUS); 45 irq_status = readl(fm->addr + FM_INTERRUPT_STATUS);
@@ -134,11 +131,10 @@ static void tifm_7xx1_switch_media(struct work_struct *work)
134{ 131{
135 struct tifm_adapter *fm = container_of(work, struct tifm_adapter, 132 struct tifm_adapter *fm = container_of(work, struct tifm_adapter,
136 media_switcher); 133 media_switcher);
134 struct tifm_dev *sock;
137 unsigned long flags; 135 unsigned long flags;
138 unsigned char media_id; 136 unsigned char media_id;
139 int cnt; 137 unsigned int socket_change_set, cnt;
140 struct tifm_dev *sock;
141 unsigned int socket_change_set;
142 138
143 spin_lock_irqsave(&fm->lock, flags); 139 spin_lock_irqsave(&fm->lock, flags);
144 socket_change_set = fm->socket_change_set; 140 socket_change_set = fm->socket_change_set;
diff --git a/drivers/misc/tifm_core.c b/drivers/misc/tifm_core.c
index 70220beb3e04..d195fb088f4a 100644
--- a/drivers/misc/tifm_core.c
+++ b/drivers/misc/tifm_core.c
@@ -115,23 +115,23 @@ static int tifm_device_remove(struct device *dev)
115 115
116static int tifm_device_suspend(struct device *dev, pm_message_t state) 116static int tifm_device_suspend(struct device *dev, pm_message_t state)
117{ 117{
118 struct tifm_dev *fm_dev = container_of(dev, struct tifm_dev, dev); 118 struct tifm_dev *sock = container_of(dev, struct tifm_dev, dev);
119 struct tifm_driver *drv = container_of(dev->driver, struct tifm_driver, 119 struct tifm_driver *drv = container_of(dev->driver, struct tifm_driver,
120 driver); 120 driver);
121 121
122 if (dev->driver && drv->suspend) 122 if (dev->driver && drv->suspend)
123 return drv->suspend(fm_dev, state); 123 return drv->suspend(sock, state);
124 return 0; 124 return 0;
125} 125}
126 126
127static int tifm_device_resume(struct device *dev) 127static int tifm_device_resume(struct device *dev)
128{ 128{
129 struct tifm_dev *fm_dev = container_of(dev, struct tifm_dev, dev); 129 struct tifm_dev *sock = container_of(dev, struct tifm_dev, dev);
130 struct tifm_driver *drv = container_of(dev->driver, struct tifm_driver, 130 struct tifm_driver *drv = container_of(dev->driver, struct tifm_driver,
131 driver); 131 driver);
132 132
133 if (dev->driver && drv->resume) 133 if (dev->driver && drv->resume)
134 return drv->resume(fm_dev); 134 return drv->resume(sock);
135 return 0; 135 return 0;
136} 136}
137 137
@@ -155,14 +155,14 @@ static struct device_attribute tifm_dev_attrs[] = {
155}; 155};
156 156
157static struct bus_type tifm_bus_type = { 157static struct bus_type tifm_bus_type = {
158 .name = "tifm", 158 .name = "tifm",
159 .dev_attrs = tifm_dev_attrs, 159 .dev_attrs = tifm_dev_attrs,
160 .match = tifm_bus_match, 160 .match = tifm_bus_match,
161 .uevent = tifm_uevent, 161 .uevent = tifm_uevent,
162 .probe = tifm_device_probe, 162 .probe = tifm_device_probe,
163 .remove = tifm_device_remove, 163 .remove = tifm_device_remove,
164 .suspend = tifm_device_suspend, 164 .suspend = tifm_device_suspend,
165 .resume = tifm_device_resume 165 .resume = tifm_device_resume
166}; 166};
167 167
168static void tifm_free(struct class_device *cdev) 168static void tifm_free(struct class_device *cdev)
diff --git a/drivers/mmc/tifm_sd.c b/drivers/mmc/tifm_sd.c
index 8e69514e415d..f692a2ec09c5 100644
--- a/drivers/mmc/tifm_sd.c
+++ b/drivers/mmc/tifm_sd.c
@@ -7,6 +7,8 @@
7 * it under the terms of the GNU General Public License version 2 as 7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation. 8 * published by the Free Software Foundation.
9 * 9 *
10 * Special thanks to Brad Campbell for extensive testing of this driver.
11 *
10 */ 12 */
11 13
12 14
@@ -39,6 +41,7 @@ module_param(fixed_timeout, bool, 0644);
39 41
40#define TIFM_MMCSD_ERRMASK 0x01e0 /* set bits: CCRC, CTO, DCRC, DTO */ 42#define TIFM_MMCSD_ERRMASK 0x01e0 /* set bits: CCRC, CTO, DCRC, DTO */
41#define TIFM_MMCSD_EOC 0x0001 /* end of command phase */ 43#define TIFM_MMCSD_EOC 0x0001 /* end of command phase */
44#define TIFM_MMCSD_CD 0x0002 /* card detect */
42#define TIFM_MMCSD_CB 0x0004 /* card enter busy state */ 45#define TIFM_MMCSD_CB 0x0004 /* card enter busy state */
43#define TIFM_MMCSD_BRS 0x0008 /* block received/sent */ 46#define TIFM_MMCSD_BRS 0x0008 /* block received/sent */
44#define TIFM_MMCSD_EOFB 0x0010 /* card exit busy state */ 47#define TIFM_MMCSD_EOFB 0x0010 /* card exit busy state */
@@ -48,6 +51,8 @@ module_param(fixed_timeout, bool, 0644);
48#define TIFM_MMCSD_CCRC 0x0100 /* command crc error */ 51#define TIFM_MMCSD_CCRC 0x0100 /* command crc error */
49#define TIFM_MMCSD_AF 0x0400 /* fifo almost full */ 52#define TIFM_MMCSD_AF 0x0400 /* fifo almost full */
50#define TIFM_MMCSD_AE 0x0800 /* fifo almost empty */ 53#define TIFM_MMCSD_AE 0x0800 /* fifo almost empty */
54#define TIFM_MMCSD_OCRB 0x1000 /* OCR busy */
55#define TIFM_MMCSD_CIRQ 0x2000 /* card irq (cmd40/sdio) */
51#define TIFM_MMCSD_CERR 0x4000 /* card status error */ 56#define TIFM_MMCSD_CERR 0x4000 /* card status error */
52 57
53#define TIFM_MMCSD_ODTO 0x0040 /* open drain / extended timeout */ 58#define TIFM_MMCSD_ODTO 0x0040 /* open drain / extended timeout */
@@ -83,16 +88,16 @@ enum {
83}; 88};
84 89
85struct tifm_sd { 90struct tifm_sd {
86 struct tifm_dev *dev; 91 struct tifm_dev *dev;
87 92
88 unsigned short eject:1, 93 unsigned short eject:1,
89 open_drain:1, 94 open_drain:1,
90 no_dma:1; 95 no_dma:1;
91 unsigned short cmd_flags; 96 unsigned short cmd_flags;
92 97
93 unsigned int clk_freq; 98 unsigned int clk_freq;
94 unsigned int clk_div; 99 unsigned int clk_div;
95 unsigned long timeout_jiffies; 100 unsigned long timeout_jiffies;
96 101
97 struct tasklet_struct finish_tasklet; 102 struct tasklet_struct finish_tasklet;
98 struct timer_list timer; 103 struct timer_list timer;
@@ -627,7 +632,8 @@ static void tifm_sd_request(struct mmc_host *mmc, struct mmc_request *mrq)
627 } 632 }
628 633
629 if (host->req) { 634 if (host->req) {
630 printk(KERN_ERR DRIVER_NAME ": unfinished request detected\n"); 635 printk(KERN_ERR "%s : unfinished request detected\n",
636 sock->dev.bus_id);
631 spin_unlock_irqrestore(&sock->lock, flags); 637 spin_unlock_irqrestore(&sock->lock, flags);
632 goto err_out; 638 goto err_out;
633 } 639 }
@@ -737,7 +743,8 @@ static void tifm_sd_end_cmd(unsigned long data)
737 host->req = NULL; 743 host->req = NULL;
738 744
739 if (!mrq) { 745 if (!mrq) {
740 printk(KERN_ERR DRIVER_NAME ": no request to complete?\n"); 746 printk(KERN_ERR " %s : no request to complete?\n",
747 sock->dev.bus_id);
741 spin_unlock_irqrestore(&sock->lock, flags); 748 spin_unlock_irqrestore(&sock->lock, flags);
742 return; 749 return;
743 } 750 }
@@ -775,8 +782,10 @@ static void tifm_sd_abort(unsigned long data)
775{ 782{
776 struct tifm_sd *host = (struct tifm_sd*)data; 783 struct tifm_sd *host = (struct tifm_sd*)data;
777 784
778 printk(KERN_ERR DRIVER_NAME 785 printk(KERN_ERR
779 ": card failed to respond for a long period of time\n"); 786 "%s : card failed to respond for a long period of time "
787 "(%x, %x)\n",
788 host->dev->dev.bus_id, host->req->cmd->opcode, host->cmd_flags);
780 789
781 tifm_eject(host->dev); 790 tifm_eject(host->dev);
782} 791}
@@ -790,8 +799,11 @@ static void tifm_sd_ios(struct mmc_host *mmc, struct mmc_ios *ios)
790 799
791 spin_lock_irqsave(&sock->lock, flags); 800 spin_lock_irqsave(&sock->lock, flags);
792 801
793 dev_dbg(&sock->dev, "Setting bus width %d, power %d\n", ios->bus_width, 802 dev_dbg(&sock->dev, "ios: clock = %u, vdd = %x, bus_mode = %x, "
794 ios->power_mode); 803 "chip_select = %x, power_mode = %x, bus_width = %x\n",
804 ios->clock, ios->vdd, ios->bus_mode, ios->chip_select,
805 ios->power_mode, ios->bus_width);
806
795 if (ios->bus_width == MMC_BUS_WIDTH_4) { 807 if (ios->bus_width == MMC_BUS_WIDTH_4) {
796 writel(TIFM_MMCSD_4BBUS | readl(sock->addr + SOCK_MMCSD_CONFIG), 808 writel(TIFM_MMCSD_4BBUS | readl(sock->addr + SOCK_MMCSD_CONFIG),
797 sock->addr + SOCK_MMCSD_CONFIG); 809 sock->addr + SOCK_MMCSD_CONFIG);
@@ -937,7 +949,8 @@ static int tifm_sd_probe(struct tifm_dev *sock)
937 949
938 if (!(TIFM_SOCK_STATE_OCCUPIED 950 if (!(TIFM_SOCK_STATE_OCCUPIED
939 & readl(sock->addr + SOCK_PRESENT_STATE))) { 951 & readl(sock->addr + SOCK_PRESENT_STATE))) {
940 printk(KERN_WARNING DRIVER_NAME ": card gone, unexpectedly\n"); 952 printk(KERN_WARNING "%s : card gone, unexpectedly\n",
953 sock->dev.bus_id);
941 return rc; 954 return rc;
942 } 955 }
943 956
@@ -974,11 +987,9 @@ static int tifm_sd_probe(struct tifm_dev *sock)
974 987
975 if (!rc) 988 if (!rc)
976 rc = mmc_add_host(mmc); 989 rc = mmc_add_host(mmc);
977 if (rc) 990 if (!rc)
978 goto out_free_mmc; 991 return 0;
979 992
980 return 0;
981out_free_mmc:
982 mmc_free_host(mmc); 993 mmc_free_host(mmc);
983 return rc; 994 return rc;
984} 995}
diff --git a/include/linux/tifm.h b/include/linux/tifm.h
index 7ccad0795466..2a196982601f 100644
--- a/include/linux/tifm.h
+++ b/include/linux/tifm.h
@@ -14,16 +14,16 @@
14 14
15#include <linux/spinlock.h> 15#include <linux/spinlock.h>
16#include <linux/interrupt.h> 16#include <linux/interrupt.h>
17#include <linux/wait.h>
18#include <linux/delay.h> 17#include <linux/delay.h>
19#include <linux/pci.h> 18#include <linux/pci.h>
20#include <linux/kthread.h> 19#include <linux/workqueue.h>
21 20
22/* Host registers (relative to pci base address): */ 21/* Host registers (relative to pci base address): */
23enum { 22enum {
24 FM_SET_INTERRUPT_ENABLE = 0x008, 23 FM_SET_INTERRUPT_ENABLE = 0x008,
25 FM_CLEAR_INTERRUPT_ENABLE = 0x00c, 24 FM_CLEAR_INTERRUPT_ENABLE = 0x00c,
26 FM_INTERRUPT_STATUS = 0x014 }; 25 FM_INTERRUPT_STATUS = 0x014
26};
27 27
28/* Socket registers (relative to socket base address): */ 28/* Socket registers (relative to socket base address): */
29enum { 29enum {
@@ -58,7 +58,8 @@ enum {
58 SOCK_MS_DATA = 0x188, 58 SOCK_MS_DATA = 0x188,
59 SOCK_MS_STATUS = 0x18c, 59 SOCK_MS_STATUS = 0x18c,
60 SOCK_MS_SYSTEM = 0x190, 60 SOCK_MS_SYSTEM = 0x190,
61 SOCK_FIFO_ACCESS = 0x200 }; 61 SOCK_FIFO_ACCESS = 0x200
62};
62 63
63#define TIFM_CTRL_LED 0x00000040 64#define TIFM_CTRL_LED 0x00000040
64#define TIFM_CTRL_FAST_CLK 0x00000100 65#define TIFM_CTRL_FAST_CLK 0x00000100
@@ -66,14 +67,14 @@ enum {
66#define TIFM_SOCK_STATE_OCCUPIED 0x00000008 67#define TIFM_SOCK_STATE_OCCUPIED 0x00000008
67#define TIFM_SOCK_STATE_POWERED 0x00000080 68#define TIFM_SOCK_STATE_POWERED 0x00000080
68 69
69#define TIFM_FIFO_ENABLE 0x00000001 /* Meaning of this constant is unverified */ 70#define TIFM_FIFO_ENABLE 0x00000001
70#define TIFM_FIFO_READY 0x00000001 /* Meaning of this constant is unverified */ 71#define TIFM_FIFO_READY 0x00000001
71#define TIFM_FIFO_INT_SETALL 0x0000ffff 72#define TIFM_FIFO_INT_SETALL 0x0000ffff
72#define TIFM_FIFO_INTMASK 0x00000005 /* Meaning of this constant is unverified */ 73#define TIFM_FIFO_INTMASK 0x00000005
73 74
74#define TIFM_DMA_RESET 0x00000002 /* Meaning of this constant is unverified */ 75#define TIFM_DMA_RESET 0x00000002
75#define TIFM_DMA_TX 0x00008000 /* Meaning of this constant is unverified */ 76#define TIFM_DMA_TX 0x00008000
76#define TIFM_DMA_EN 0x00000001 /* Meaning of this constant is unverified */ 77#define TIFM_DMA_EN 0x00000001
77#define TIFM_DMA_TSIZE 0x0000007f 78#define TIFM_DMA_TSIZE 0x0000007f
78 79
79#define TIFM_TYPE_XD 1 80#define TIFM_TYPE_XD 1
@@ -86,44 +87,44 @@ struct tifm_device_id {
86 87
87struct tifm_driver; 88struct tifm_driver;
88struct tifm_dev { 89struct tifm_dev {
89 char __iomem *addr; 90 char __iomem *addr;
90 spinlock_t lock; 91 spinlock_t lock;
91 unsigned char type; 92 unsigned char type;
92 unsigned int socket_id; 93 unsigned int socket_id;
93 94
94 void (*card_event)(struct tifm_dev *sock); 95 void (*card_event)(struct tifm_dev *sock);
95 void (*data_event)(struct tifm_dev *sock); 96 void (*data_event)(struct tifm_dev *sock);
96 97
97 struct device dev; 98 struct device dev;
98}; 99};
99 100
100struct tifm_driver { 101struct tifm_driver {
101 struct tifm_device_id *id_table; 102 struct tifm_device_id *id_table;
102 int (*probe)(struct tifm_dev *dev); 103 int (*probe)(struct tifm_dev *dev);
103 void (*remove)(struct tifm_dev *dev); 104 void (*remove)(struct tifm_dev *dev);
104 int (*suspend)(struct tifm_dev *dev, 105 int (*suspend)(struct tifm_dev *dev,
105 pm_message_t state); 106 pm_message_t state);
106 int (*resume)(struct tifm_dev *dev); 107 int (*resume)(struct tifm_dev *dev);
107 108
108 struct device_driver driver; 109 struct device_driver driver;
109}; 110};
110 111
111struct tifm_adapter { 112struct tifm_adapter {
112 char __iomem *addr; 113 char __iomem *addr;
113 spinlock_t lock; 114 spinlock_t lock;
114 unsigned int irq_status; 115 unsigned int irq_status;
115 unsigned int socket_change_set; 116 unsigned int socket_change_set;
116 unsigned int id; 117 unsigned int id;
117 unsigned int num_sockets; 118 unsigned int num_sockets;
118 struct completion *finish_me; 119 struct completion *finish_me;
119 120
120 struct work_struct media_switcher; 121 struct work_struct media_switcher;
121 struct class_device cdev; 122 struct class_device cdev;
122 123
123 void (*eject)(struct tifm_adapter *fm, 124 void (*eject)(struct tifm_adapter *fm,
124 struct tifm_dev *sock); 125 struct tifm_dev *sock);
125 126
126 struct tifm_dev *sockets[0]; 127 struct tifm_dev *sockets[0];
127}; 128};
128 129
129struct tifm_adapter *tifm_alloc_adapter(unsigned int num_sockets, 130struct tifm_adapter *tifm_alloc_adapter(unsigned int num_sockets,
@@ -147,7 +148,7 @@ void tifm_queue_work(struct work_struct *work);
147 148
148static inline void *tifm_get_drvdata(struct tifm_dev *dev) 149static inline void *tifm_get_drvdata(struct tifm_dev *dev)
149{ 150{
150 return dev_get_drvdata(&dev->dev); 151 return dev_get_drvdata(&dev->dev);
151} 152}
152 153
153static inline void tifm_set_drvdata(struct tifm_dev *dev, void *data) 154static inline void tifm_set_drvdata(struct tifm_dev *dev, void *data)