aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/sl811_cs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host/sl811_cs.c')
-rw-r--r--drivers/usb/host/sl811_cs.c115
1 files changed, 35 insertions, 80 deletions
diff --git a/drivers/usb/host/sl811_cs.c b/drivers/usb/host/sl811_cs.c
index e73faf831b24..466384d7c79f 100644
--- a/drivers/usb/host/sl811_cs.c
+++ b/drivers/usb/host/sl811_cs.c
@@ -38,7 +38,7 @@ MODULE_LICENSE("GPL");
38/* MACROS */ 38/* MACROS */
39/*====================================================================*/ 39/*====================================================================*/
40 40
41#if defined(DEBUG) || defined(CONFIG_USB_DEBUG) || defined(PCMCIA_DEBUG) 41#if defined(DEBUG) || defined(PCMCIA_DEBUG)
42 42
43static int pc_debug = 0; 43static int pc_debug = 0;
44module_param(pc_debug, int, 0644); 44module_param(pc_debug, int, 0644);
@@ -66,13 +66,13 @@ module_param(pc_debug, int, 0644);
66 66
67static const char driver_name[DEV_NAME_LEN] = "sl811_cs"; 67static const char driver_name[DEV_NAME_LEN] = "sl811_cs";
68 68
69static dev_link_t *dev_list = NULL;
70
71typedef struct local_info_t { 69typedef struct local_info_t {
72 dev_link_t link; 70 dev_link_t link;
73 dev_node_t node; 71 dev_node_t node;
74} local_info_t; 72} local_info_t;
75 73
74static void sl811_cs_release(dev_link_t * link);
75
76/*====================================================================*/ 76/*====================================================================*/
77 77
78static void release_platform_dev(struct device * dev) 78static void release_platform_dev(struct device * dev)
@@ -129,7 +129,8 @@ static int sl811_hc_init(struct device *parent, ioaddr_t base_addr, int irq)
129 resources[2].end = base_addr + 1; 129 resources[2].end = base_addr + 1;
130 130
131 /* The driver core will probe for us. We know sl811-hcd has been 131 /* The driver core will probe for us. We know sl811-hcd has been
132 * initialized already because of the link order dependency. 132 * initialized already because of the link order dependency created
133 * by referencing "sl811h_driver".
133 */ 134 */
134 platform_dev.name = sl811h_driver.name; 135 platform_dev.name = sl811h_driver.name;
135 return platform_device_register(&platform_dev); 136 return platform_device_register(&platform_dev);
@@ -137,26 +138,16 @@ static int sl811_hc_init(struct device *parent, ioaddr_t base_addr, int irq)
137 138
138/*====================================================================*/ 139/*====================================================================*/
139 140
140static void sl811_cs_detach(dev_link_t *link) 141static void sl811_cs_detach(struct pcmcia_device *p_dev)
141{ 142{
142 dev_link_t **linkp; 143 dev_link_t *link = dev_to_instance(p_dev);
143 144
144 DBG(0, "sl811_cs_detach(0x%p)\n", link); 145 DBG(0, "sl811_cs_detach(0x%p)\n", link);
145 146
146 /* Locate device structure */ 147 link->state &= ~DEV_PRESENT;
147 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) { 148 if (link->state & DEV_CONFIG)
148 if (*linkp == link) 149 sl811_cs_release(link);
149 break;
150 }
151 if (*linkp == NULL)
152 return;
153
154 /* Break the link with Card Services */
155 if (link->handle)
156 pcmcia_deregister_client(link->handle);
157 150
158 /* Unlink device structure, and free it */
159 *linkp = link->next;
160 /* This points to the parent local_info_t struct */ 151 /* This points to the parent local_info_t struct */
161 kfree(link->priv); 152 kfree(link->priv);
162} 153}
@@ -166,13 +157,6 @@ static void sl811_cs_release(dev_link_t * link)
166 157
167 DBG(0, "sl811_cs_release(0x%p)\n", link); 158 DBG(0, "sl811_cs_release(0x%p)\n", link);
168 159
169 if (link->open) {
170 DBG(1, "sl811_cs: release postponed, '%s' still open\n",
171 link->dev->dev_name);
172 link->state |= DEV_STALE_CONFIG;
173 return;
174 }
175
176 /* Unlink the device chain */ 160 /* Unlink the device chain */
177 link->dev = NULL; 161 link->dev = NULL;
178 162
@@ -183,9 +167,6 @@ static void sl811_cs_release(dev_link_t * link)
183 if (link->irq.AssignedIRQ) 167 if (link->irq.AssignedIRQ)
184 pcmcia_release_irq(link->handle, &link->irq); 168 pcmcia_release_irq(link->handle, &link->irq);
185 link->state &= ~DEV_CONFIG; 169 link->state &= ~DEV_CONFIG;
186
187 if (link->state & DEV_STALE_LINK)
188 sl811_cs_detach(link);
189} 170}
190 171
191static void sl811_cs_config(dev_link_t *link) 172static void sl811_cs_config(dev_link_t *link)
@@ -322,55 +303,36 @@ cs_failed:
322 } 303 }
323} 304}
324 305
325static int 306static int sl811_suspend(struct pcmcia_device *dev)
326sl811_cs_event(event_t event, int priority, event_callback_args_t *args)
327{ 307{
328 dev_link_t *link = args->client_data; 308 dev_link_t *link = dev_to_instance(dev);
329 309
330 DBG(1, "sl811_cs_event(0x%06x)\n", event); 310 link->state |= DEV_SUSPEND;
311 if (link->state & DEV_CONFIG)
312 pcmcia_release_configuration(link->handle);
331 313
332 switch (event) { 314 return 0;
333 case CS_EVENT_CARD_REMOVAL: 315}
334 link->state &= ~DEV_PRESENT;
335 if (link->state & DEV_CONFIG)
336 sl811_cs_release(link);
337 break;
338 316
339 case CS_EVENT_CARD_INSERTION: 317static int sl811_resume(struct pcmcia_device *dev)
340 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 318{
341 sl811_cs_config(link); 319 dev_link_t *link = dev_to_instance(dev);
342 break;
343 320
344 case CS_EVENT_PM_SUSPEND: 321 link->state &= ~DEV_SUSPEND;
345 link->state |= DEV_SUSPEND; 322 if (link->state & DEV_CONFIG)
346 /* Fall through... */ 323 pcmcia_request_configuration(link->handle, &link->conf);
347 case CS_EVENT_RESET_PHYSICAL:
348 if (link->state & DEV_CONFIG)
349 pcmcia_release_configuration(link->handle);
350 break;
351 324
352 case CS_EVENT_PM_RESUME:
353 link->state &= ~DEV_SUSPEND;
354 /* Fall through... */
355 case CS_EVENT_CARD_RESET:
356 if (link->state & DEV_CONFIG)
357 pcmcia_request_configuration(link->handle, &link->conf);
358 DBG(0, "reset sl811-hcd here?\n");
359 break;
360 }
361 return 0; 325 return 0;
362} 326}
363 327
364static dev_link_t *sl811_cs_attach(void) 328static int sl811_cs_attach(struct pcmcia_device *p_dev)
365{ 329{
366 local_info_t *local; 330 local_info_t *local;
367 dev_link_t *link; 331 dev_link_t *link;
368 client_reg_t client_reg;
369 int ret;
370 332
371 local = kmalloc(sizeof(local_info_t), GFP_KERNEL); 333 local = kmalloc(sizeof(local_info_t), GFP_KERNEL);
372 if (!local) 334 if (!local)
373 return NULL; 335 return -ENOMEM;
374 memset(local, 0, sizeof(local_info_t)); 336 memset(local, 0, sizeof(local_info_t));
375 link = &local->link; 337 link = &local->link;
376 link->priv = local; 338 link->priv = local;
@@ -384,21 +346,13 @@ static dev_link_t *sl811_cs_attach(void)
384 link->conf.Vcc = 33; 346 link->conf.Vcc = 33;
385 link->conf.IntType = INT_MEMORY_AND_IO; 347 link->conf.IntType = INT_MEMORY_AND_IO;
386 348
387 /* Register with Card Services */ 349 link->handle = p_dev;
388 link->next = dev_list; 350 p_dev->instance = link;
389 dev_list = link;
390 client_reg.dev_info = (dev_info_t *) &driver_name;
391 client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
392 client_reg.Version = 0x0210;
393 client_reg.event_callback_args.client_data = link;
394 ret = pcmcia_register_client(&link->handle, &client_reg);
395 if (ret != CS_SUCCESS) {
396 cs_error(link->handle, RegisterClient, ret);
397 sl811_cs_detach(link);
398 return NULL;
399 }
400 351
401 return link; 352 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
353 sl811_cs_config(link);
354
355 return 0;
402} 356}
403 357
404static struct pcmcia_device_id sl811_ids[] = { 358static struct pcmcia_device_id sl811_ids[] = {
@@ -412,10 +366,11 @@ static struct pcmcia_driver sl811_cs_driver = {
412 .drv = { 366 .drv = {
413 .name = (char *)driver_name, 367 .name = (char *)driver_name,
414 }, 368 },
415 .attach = sl811_cs_attach, 369 .probe = sl811_cs_attach,
416 .event = sl811_cs_event, 370 .remove = sl811_cs_detach,
417 .detach = sl811_cs_detach,
418 .id_table = sl811_ids, 371 .id_table = sl811_ids,
372 .suspend = sl811_suspend,
373 .resume = sl811_resume,
419}; 374};
420 375
421/*====================================================================*/ 376/*====================================================================*/