aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/telephony/ixj_pcmcia.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/telephony/ixj_pcmcia.c')
-rw-r--r--drivers/telephony/ixj_pcmcia.c112
1 files changed, 40 insertions, 72 deletions
diff --git a/drivers/telephony/ixj_pcmcia.c b/drivers/telephony/ixj_pcmcia.c
index 57c0c6e3fbed..d3a7b0c3d38b 100644
--- a/drivers/telephony/ixj_pcmcia.c
+++ b/drivers/telephony/ixj_pcmcia.c
@@ -34,24 +34,19 @@ typedef struct ixj_info_t {
34 struct ixj *port; 34 struct ixj *port;
35} ixj_info_t; 35} ixj_info_t;
36 36
37static dev_link_t *ixj_attach(void); 37static void ixj_detach(struct pcmcia_device *p_dev);
38static void ixj_detach(dev_link_t *);
39static void ixj_config(dev_link_t * link); 38static void ixj_config(dev_link_t * link);
40static void ixj_cs_release(dev_link_t * link); 39static void ixj_cs_release(dev_link_t * link);
41static int ixj_event(event_t event, int priority, event_callback_args_t * args);
42static dev_info_t dev_info = "ixj_cs";
43static dev_link_t *dev_list = NULL;
44 40
45static dev_link_t *ixj_attach(void) 41static int ixj_attach(struct pcmcia_device *p_dev)
46{ 42{
47 client_reg_t client_reg;
48 dev_link_t *link; 43 dev_link_t *link;
49 int ret; 44
50 DEBUG(0, "ixj_attach()\n"); 45 DEBUG(0, "ixj_attach()\n");
51 /* Create new ixj device */ 46 /* Create new ixj device */
52 link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL); 47 link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
53 if (!link) 48 if (!link)
54 return NULL; 49 return -ENOMEM;
55 memset(link, 0, sizeof(struct dev_link_t)); 50 memset(link, 0, sizeof(struct dev_link_t));
56 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; 51 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
57 link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; 52 link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
@@ -61,44 +56,29 @@ static dev_link_t *ixj_attach(void)
61 link->priv = kmalloc(sizeof(struct ixj_info_t), GFP_KERNEL); 56 link->priv = kmalloc(sizeof(struct ixj_info_t), GFP_KERNEL);
62 if (!link->priv) { 57 if (!link->priv) {
63 kfree(link); 58 kfree(link);
64 return NULL; 59 return -ENOMEM;
65 } 60 }
66 memset(link->priv, 0, sizeof(struct ixj_info_t)); 61 memset(link->priv, 0, sizeof(struct ixj_info_t));
67 /* Register with Card Services */ 62
68 link->next = dev_list; 63 link->handle = p_dev;
69 dev_list = link; 64 p_dev->instance = link;
70 client_reg.dev_info = &dev_info; 65
71 client_reg.Version = 0x0210; 66 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
72 client_reg.event_callback_args.client_data = link; 67 ixj_config(link);
73 ret = pcmcia_register_client(&link->handle, &client_reg); 68
74 if (ret != CS_SUCCESS) { 69 return 0;
75 cs_error(link->handle, RegisterClient, ret);
76 ixj_detach(link);
77 return NULL;
78 }
79 return link;
80} 70}
81 71
82static void ixj_detach(dev_link_t * link) 72static void ixj_detach(struct pcmcia_device *p_dev)
83{ 73{
84 dev_link_t **linkp; 74 dev_link_t *link = dev_to_instance(p_dev);
85 int ret; 75
86 DEBUG(0, "ixj_detach(0x%p)\n", link); 76 DEBUG(0, "ixj_detach(0x%p)\n", link);
87 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) 77
88 if (*linkp == link)
89 break;
90 if (*linkp == NULL)
91 return;
92 link->state &= ~DEV_RELEASE_PENDING; 78 link->state &= ~DEV_RELEASE_PENDING;
93 if (link->state & DEV_CONFIG) 79 if (link->state & DEV_CONFIG)
94 ixj_cs_release(link); 80 ixj_cs_release(link);
95 if (link->handle) { 81
96 ret = pcmcia_deregister_client(link->handle);
97 if (ret != CS_SUCCESS)
98 cs_error(link->handle, DeregisterClient, ret);
99 }
100 /* Unlink device structure, free bits */
101 *linkp = link->next;
102 kfree(link->priv); 82 kfree(link->priv);
103 kfree(link); 83 kfree(link);
104} 84}
@@ -255,37 +235,25 @@ static void ixj_cs_release(dev_link_t *link)
255 link->state &= ~DEV_CONFIG; 235 link->state &= ~DEV_CONFIG;
256} 236}
257 237
258static int ixj_event(event_t event, int priority, event_callback_args_t * args) 238static int ixj_suspend(struct pcmcia_device *dev)
259{ 239{
260 dev_link_t *link = args->client_data; 240 dev_link_t *link = dev_to_instance(dev);
261 DEBUG(1, "ixj_event(0x%06x)\n", event); 241
262 switch (event) { 242 link->state |= DEV_SUSPEND;
263 case CS_EVENT_CARD_REMOVAL: 243 if (link->state & DEV_CONFIG)
264 link->state &= ~DEV_PRESENT; 244 pcmcia_release_configuration(link->handle);
265 if (link->state & DEV_CONFIG) { 245
266 link->state |= DEV_RELEASE_PENDING; 246 return 0;
267 ixj_cs_release(link); 247}
268 } 248
269 break; 249static int ixj_resume(struct pcmcia_device *dev)
270 case CS_EVENT_CARD_INSERTION: 250{
271 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 251 dev_link_t *link = dev_to_instance(dev);
272 ixj_config(link); 252
273 break; 253 link->state &= ~DEV_SUSPEND;
274 case CS_EVENT_PM_SUSPEND: 254 if (DEV_OK(link))
275 link->state |= DEV_SUSPEND; 255 pcmcia_request_configuration(link->handle, &link->conf);
276 /* Fall through... */ 256
277 case CS_EVENT_RESET_PHYSICAL:
278 if (link->state & DEV_CONFIG)
279 pcmcia_release_configuration(link->handle);
280 break;
281 case CS_EVENT_PM_RESUME:
282 link->state &= ~DEV_SUSPEND;
283 /* Fall through... */
284 case CS_EVENT_CARD_RESET:
285 if (DEV_OK(link))
286 pcmcia_request_configuration(link->handle, &link->conf);
287 break;
288 }
289 return 0; 257 return 0;
290} 258}
291 259
@@ -300,10 +268,11 @@ static struct pcmcia_driver ixj_driver = {
300 .drv = { 268 .drv = {
301 .name = "ixj_cs", 269 .name = "ixj_cs",
302 }, 270 },
303 .attach = ixj_attach, 271 .probe = ixj_attach,
304 .event = ixj_event, 272 .remove = ixj_detach,
305 .detach = ixj_detach,
306 .id_table = ixj_ids, 273 .id_table = ixj_ids,
274 .suspend = ixj_suspend,
275 .resume = ixj_resume,
307}; 276};
308 277
309static int __init ixj_pcmcia_init(void) 278static int __init ixj_pcmcia_init(void)
@@ -314,7 +283,6 @@ static int __init ixj_pcmcia_init(void)
314static void ixj_pcmcia_exit(void) 283static void ixj_pcmcia_exit(void)
315{ 284{
316 pcmcia_unregister_driver(&ixj_driver); 285 pcmcia_unregister_driver(&ixj_driver);
317 BUG_ON(dev_list != NULL);
318} 286}
319 287
320module_init(ixj_pcmcia_init); 288module_init(ixj_pcmcia_init);