aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/misc/tifm_7xx1.c94
-rw-r--r--drivers/misc/tifm_core.c39
-rw-r--r--include/linux/tifm.h4
3 files changed, 65 insertions, 72 deletions
diff --git a/drivers/misc/tifm_7xx1.c b/drivers/misc/tifm_7xx1.c
index e051f9da9c5c..356386904a5d 100644
--- a/drivers/misc/tifm_7xx1.c
+++ b/drivers/misc/tifm_7xx1.c
@@ -136,7 +136,6 @@ static void tifm_7xx1_switch_media(struct work_struct *work)
136 media_switcher); 136 media_switcher);
137 unsigned long flags; 137 unsigned long flags;
138 unsigned char media_id; 138 unsigned char media_id;
139 char *card_name = "xx";
140 int cnt; 139 int cnt;
141 struct tifm_dev *sock; 140 struct tifm_dev *sock;
142 unsigned int socket_change_set; 141 unsigned int socket_change_set;
@@ -153,68 +152,45 @@ static void tifm_7xx1_switch_media(struct work_struct *work)
153 return; 152 return;
154 } 153 }
155 154
156 for (cnt = 0; cnt < fm->num_sockets; cnt++) { 155 for (cnt = 0; cnt < fm->num_sockets; cnt++) {
157 if (!(socket_change_set & (1 << cnt))) 156 if (!(socket_change_set & (1 << cnt)))
158 continue; 157 continue;
159 sock = fm->sockets[cnt]; 158 sock = fm->sockets[cnt];
160 if (sock) { 159 if (sock) {
161 printk(KERN_INFO DRIVER_NAME 160 printk(KERN_INFO
162 ": demand removing card from socket %d\n", 161 "%s : demand removing card from socket %u:%u\n",
163 cnt); 162 fm->cdev.class_id, fm->id, cnt);
164 fm->sockets[cnt] = NULL; 163 fm->sockets[cnt] = NULL;
165 spin_unlock_irqrestore(&fm->lock, flags);
166 device_unregister(&sock->dev);
167 spin_lock_irqsave(&fm->lock, flags);
168 writel(0x0e00,
169 tifm_7xx1_sock_addr(fm->addr, cnt)
170 + SOCK_CONTROL);
171 }
172
173 spin_unlock_irqrestore(&fm->lock, flags); 164 spin_unlock_irqrestore(&fm->lock, flags);
174 media_id = tifm_7xx1_toggle_sock_power( 165 device_unregister(&sock->dev);
175 tifm_7xx1_sock_addr(fm->addr, cnt)); 166 spin_lock_irqsave(&fm->lock, flags);
176 if (media_id) { 167 writel(0x0e00, tifm_7xx1_sock_addr(fm->addr, cnt)
177 sock = tifm_alloc_device(fm); 168 + SOCK_CONTROL);
178 if (sock) { 169 }
179 sock->addr = tifm_7xx1_sock_addr(fm->addr, 170
180 cnt); 171 spin_unlock_irqrestore(&fm->lock, flags);
181 sock->type = media_id; 172
182 sock->socket_id = cnt; 173 media_id = tifm_7xx1_toggle_sock_power(
183 switch (media_id) { 174 tifm_7xx1_sock_addr(fm->addr, cnt));
184 case 1: 175
185 card_name = "xd"; 176 // tifm_alloc_device will check if media_id is valid
186 break; 177 sock = tifm_alloc_device(fm, cnt, media_id);
187 case 2: 178 if (sock) {
188 card_name = "ms"; 179 sock->addr = tifm_7xx1_sock_addr(fm->addr, cnt);
189 break; 180
190 case 3: 181 if (!device_register(&sock->dev)) {
191 card_name = "sd";
192 break;
193 default:
194 tifm_free_device(&sock->dev);
195 spin_lock_irqsave(&fm->lock, flags);
196 continue;
197 }
198 snprintf(sock->dev.bus_id, BUS_ID_SIZE,
199 "tifm_%s%u:%u", card_name,
200 fm->id, cnt);
201 printk(KERN_INFO DRIVER_NAME
202 ": %s card detected in socket %d\n",
203 card_name, cnt);
204 if (!device_register(&sock->dev)) {
205 spin_lock_irqsave(&fm->lock, flags);
206 if (!fm->sockets[cnt]) {
207 fm->sockets[cnt] = sock;
208 sock = NULL;
209 }
210 spin_unlock_irqrestore(&fm->lock, flags);
211 }
212 if (sock)
213 tifm_free_device(&sock->dev);
214 }
215 spin_lock_irqsave(&fm->lock, flags); 182 spin_lock_irqsave(&fm->lock, flags);
183 if (!fm->sockets[cnt]) {
184 fm->sockets[cnt] = sock;
185 sock = NULL;
186 }
187 spin_unlock_irqrestore(&fm->lock, flags);
216 } 188 }
189 if (sock)
190 tifm_free_device(&sock->dev);
217 } 191 }
192 spin_lock_irqsave(&fm->lock, flags);
193 }
218 194
219 writel(TIFM_IRQ_FIFOMASK(socket_change_set) 195 writel(TIFM_IRQ_FIFOMASK(socket_change_set)
220 | TIFM_IRQ_CARDMASK(socket_change_set), 196 | TIFM_IRQ_CARDMASK(socket_change_set),
diff --git a/drivers/misc/tifm_core.c b/drivers/misc/tifm_core.c
index f0cce2a642df..1e591989835d 100644
--- a/drivers/misc/tifm_core.c
+++ b/drivers/misc/tifm_core.c
@@ -232,25 +232,40 @@ EXPORT_SYMBOL(tifm_free_adapter);
232 232
233void tifm_free_device(struct device *dev) 233void tifm_free_device(struct device *dev)
234{ 234{
235 struct tifm_dev *fm_dev = container_of(dev, struct tifm_dev, dev); 235 struct tifm_dev *sock = container_of(dev, struct tifm_dev, dev);
236 kfree(fm_dev); 236 kfree(sock);
237} 237}
238EXPORT_SYMBOL(tifm_free_device); 238EXPORT_SYMBOL(tifm_free_device);
239 239
240struct tifm_dev *tifm_alloc_device(struct tifm_adapter *fm) 240struct tifm_dev *tifm_alloc_device(struct tifm_adapter *fm, unsigned int id,
241 unsigned char type)
241{ 242{
242 struct tifm_dev *dev = kzalloc(sizeof(struct tifm_dev), GFP_KERNEL); 243 struct tifm_dev *sock = NULL;
244
245 if (!tifm_media_type_name(type, 0))
246 return sock;
243 247
244 if (dev) { 248 sock = kzalloc(sizeof(struct tifm_dev), GFP_KERNEL);
245 spin_lock_init(&dev->lock); 249 if (sock) {
250 spin_lock_init(&sock->lock);
251 sock->type = type;
252 sock->socket_id = id;
253 sock->card_event = tifm_dummy_event;
254 sock->data_event = tifm_dummy_event;
246 255
247 dev->dev.parent = fm->cdev.dev; 256 sock->dev.parent = fm->cdev.dev;
248 dev->dev.bus = &tifm_bus_type; 257 sock->dev.bus = &tifm_bus_type;
249 dev->dev.release = tifm_free_device; 258 sock->dev.dma_mask = fm->cdev.dev->dma_mask;
250 dev->card_event = tifm_dummy_event; 259 sock->dev.release = tifm_free_device;
251 dev->data_event = tifm_dummy_event; 260
261 snprintf(sock->dev.bus_id, BUS_ID_SIZE,
262 "tifm_%s%u:%u", tifm_media_type_name(type, 2),
263 fm->id, id);
264 printk(KERN_INFO DRIVER_NAME
265 ": %s card detected in socket %u:%u\n",
266 tifm_media_type_name(type, 0), fm->id, id);
252 } 267 }
253 return dev; 268 return sock;
254} 269}
255EXPORT_SYMBOL(tifm_alloc_device); 270EXPORT_SYMBOL(tifm_alloc_device);
256 271
diff --git a/include/linux/tifm.h b/include/linux/tifm.h
index a7bd654e2ee5..82da028d8c07 100644
--- a/include/linux/tifm.h
+++ b/include/linux/tifm.h
@@ -131,7 +131,9 @@ void tifm_remove_adapter(struct tifm_adapter *fm);
131void tifm_free_adapter(struct tifm_adapter *fm); 131void tifm_free_adapter(struct tifm_adapter *fm);
132 132
133void tifm_free_device(struct device *dev); 133void tifm_free_device(struct device *dev);
134struct tifm_dev *tifm_alloc_device(struct tifm_adapter *fm); 134struct tifm_dev *tifm_alloc_device(struct tifm_adapter *fm, unsigned int id,
135 unsigned char type);
136
135int tifm_register_driver(struct tifm_driver *drv); 137int tifm_register_driver(struct tifm_driver *drv);
136void tifm_unregister_driver(struct tifm_driver *drv); 138void tifm_unregister_driver(struct tifm_driver *drv);
137void tifm_eject(struct tifm_dev *sock); 139void tifm_eject(struct tifm_dev *sock);