diff options
-rw-r--r-- | drivers/misc/tifm_7xx1.c | 94 | ||||
-rw-r--r-- | drivers/misc/tifm_core.c | 39 | ||||
-rw-r--r-- | include/linux/tifm.h | 4 |
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 | ||
233 | void tifm_free_device(struct device *dev) | 233 | void 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 | } |
238 | EXPORT_SYMBOL(tifm_free_device); | 238 | EXPORT_SYMBOL(tifm_free_device); |
239 | 239 | ||
240 | struct tifm_dev *tifm_alloc_device(struct tifm_adapter *fm) | 240 | struct 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 | } |
255 | EXPORT_SYMBOL(tifm_alloc_device); | 270 | EXPORT_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); | |||
131 | void tifm_free_adapter(struct tifm_adapter *fm); | 131 | void tifm_free_adapter(struct tifm_adapter *fm); |
132 | 132 | ||
133 | void tifm_free_device(struct device *dev); | 133 | void tifm_free_device(struct device *dev); |
134 | struct tifm_dev *tifm_alloc_device(struct tifm_adapter *fm); | 134 | struct tifm_dev *tifm_alloc_device(struct tifm_adapter *fm, unsigned int id, |
135 | unsigned char type); | ||
136 | |||
135 | int tifm_register_driver(struct tifm_driver *drv); | 137 | int tifm_register_driver(struct tifm_driver *drv); |
136 | void tifm_unregister_driver(struct tifm_driver *drv); | 138 | void tifm_unregister_driver(struct tifm_driver *drv); |
137 | void tifm_eject(struct tifm_dev *sock); | 139 | void tifm_eject(struct tifm_dev *sock); |