summaryrefslogtreecommitdiffstats
path: root/drivers/char/pcmcia/synclink_cs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/pcmcia/synclink_cs.c')
-rw-r--r--drivers/char/pcmcia/synclink_cs.c116
1 files changed, 41 insertions, 75 deletions
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
index e6b714b..0721345 100644
--- a/drivers/char/pcmcia/synclink_cs.c
+++ b/drivers/char/pcmcia/synclink_cs.c
@@ -228,7 +228,7 @@ typedef struct _mgslpc_info {
struct _input_signal_events input_signal_events;
/* PCMCIA support */
- dev_link_t link;
+ struct pcmcia_device *p_dev;
dev_node_t node;
int stop;
@@ -484,7 +484,7 @@ static void mgslpc_wait_until_sent(struct tty_struct *tty, int timeout);
/* PCMCIA prototypes */
-static void mgslpc_config(dev_link_t *link);
+static int mgslpc_config(struct pcmcia_device *link);
static void mgslpc_release(u_long arg);
static void mgslpc_detach(struct pcmcia_device *p_dev);
@@ -533,14 +533,14 @@ static void ldisc_receive_buf(struct tty_struct *tty,
}
}
-static int mgslpc_attach(struct pcmcia_device *p_dev)
+static int mgslpc_probe(struct pcmcia_device *link)
{
MGSLPC_INFO *info;
- dev_link_t *link;
-
+ int ret;
+
if (debug_level >= DEBUG_LEVEL_INFO)
printk("mgslpc_attach\n");
-
+
info = (MGSLPC_INFO *)kmalloc(sizeof(MGSLPC_INFO), GFP_KERNEL);
if (!info) {
printk("Error can't allocate device instance data\n");
@@ -565,25 +565,22 @@ static int mgslpc_attach(struct pcmcia_device *p_dev)
info->imrb_value = 0xffff;
info->pim_value = 0xff;
- link = &info->link;
+ info->p_dev = link;
link->priv = info;
-
- /* Initialize the dev_link_t structure */
+
+ /* Initialize the struct pcmcia_device structure */
/* Interrupt setup */
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
link->irq.Handler = NULL;
-
+
link->conf.Attributes = 0;
- link->conf.Vcc = 50;
link->conf.IntType = INT_MEMORY_AND_IO;
- link->handle = p_dev;
- p_dev->instance = link;
-
- link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
- mgslpc_config(link);
+ ret = mgslpc_config(link);
+ if (ret)
+ return ret;
mgslpc_add_device(info);
@@ -596,15 +593,13 @@ static int mgslpc_attach(struct pcmcia_device *p_dev)
#define CS_CHECK(fn, ret) \
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-static void mgslpc_config(dev_link_t *link)
+static int mgslpc_config(struct pcmcia_device *link)
{
- client_handle_t handle = link->handle;
MGSLPC_INFO *info = link->priv;
tuple_t tuple;
cisparse_t parse;
int last_fn, last_ret;
u_char buf[64];
- config_info_t conf;
cistpl_cftable_entry_t dflt = { 0 };
cistpl_cftable_entry_t *cfg;
@@ -617,27 +612,20 @@ static void mgslpc_config(dev_link_t *link)
tuple.TupleData = buf;
tuple.TupleDataMax = sizeof(buf);
tuple.TupleOffset = 0;
- CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
- CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
- CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
+ CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
+ CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
+ CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse));
link->conf.ConfigBase = parse.config.base;
link->conf.Present = parse.config.rmask[0];
-
- /* Configure card */
- link->state |= DEV_CONFIG;
-
- /* Look up the current Vcc */
- CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(handle, &conf));
- link->conf.Vcc = conf.Vcc;
/* get CIS configuration entry */
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
- CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
+ CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
cfg = &(parse.cftable_entry);
- CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
- CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
+ CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
+ CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse));
if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg;
if (cfg->index == 0)
@@ -658,11 +646,10 @@ static void mgslpc_config(dev_link_t *link)
link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
link->io.BasePort1 = io->win[0].base;
link->io.NumPorts1 = io->win[0].len;
- CS_CHECK(RequestIO, pcmcia_request_io(link->handle, &link->io));
+ CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io));
}
link->conf.Attributes = CONF_ENABLE_IRQ;
- link->conf.Vcc = 50;
link->conf.IntType = INT_MEMORY_AND_IO;
link->conf.ConfigIndex = 8;
link->conf.Present = PRESENT_OPTION;
@@ -670,9 +657,9 @@ static void mgslpc_config(dev_link_t *link)
link->irq.Attributes |= IRQ_HANDLE_PRESENT;
link->irq.Handler = mgslpc_isr;
link->irq.Instance = info;
- CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq));
+ CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
- CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf));
+ CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
info->io_base = link->io.BasePort1;
info->irq_level = link->irq.AssignedIRQ;
@@ -680,7 +667,7 @@ static void mgslpc_config(dev_link_t *link)
/* add to linked list of devices */
sprintf(info->node.dev_name, "mgslpc0");
info->node.major = info->node.minor = 0;
- link->dev = &info->node;
+ link->dev_node = &info->node;
printk(KERN_INFO "%s: index 0x%02x:",
info->node.dev_name, link->conf.ConfigIndex);
@@ -690,13 +677,12 @@ static void mgslpc_config(dev_link_t *link)
printk(", io 0x%04x-0x%04x", link->io.BasePort1,
link->io.BasePort1+link->io.NumPorts1-1);
printk("\n");
-
- link->state &= ~DEV_CONFIG_PENDING;
- return;
+ return 0;
cs_failed:
- cs_error(link->handle, last_fn, last_ret);
+ cs_error(link, last_fn, last_ret);
mgslpc_release((u_long)link);
+ return -ENODEV;
}
/* Card has been removed.
@@ -705,58 +691,38 @@ cs_failed:
*/
static void mgslpc_release(u_long arg)
{
- dev_link_t *link = (dev_link_t *)arg;
+ struct pcmcia_device *link = (struct pcmcia_device *)arg;
- if (debug_level >= DEBUG_LEVEL_INFO)
- printk("mgslpc_release(0x%p)\n", link);
-
- /* Unlink the device chain */
- link->dev = NULL;
- link->state &= ~DEV_CONFIG;
+ if (debug_level >= DEBUG_LEVEL_INFO)
+ printk("mgslpc_release(0x%p)\n", link);
- pcmcia_release_configuration(link->handle);
- if (link->io.NumPorts1)
- pcmcia_release_io(link->handle, &link->io);
- if (link->irq.AssignedIRQ)
- pcmcia_release_irq(link->handle, &link->irq);
+ pcmcia_disable_device(link);
}
-static void mgslpc_detach(struct pcmcia_device *p_dev)
+static void mgslpc_detach(struct pcmcia_device *link)
{
- dev_link_t *link = dev_to_instance(p_dev);
-
- if (debug_level >= DEBUG_LEVEL_INFO)
- printk("mgslpc_detach(0x%p)\n", link);
+ if (debug_level >= DEBUG_LEVEL_INFO)
+ printk("mgslpc_detach(0x%p)\n", link);
- if (link->state & DEV_CONFIG) {
- ((MGSLPC_INFO *)link->priv)->stop = 1;
- mgslpc_release((u_long)link);
- }
+ ((MGSLPC_INFO *)link->priv)->stop = 1;
+ mgslpc_release((u_long)link);
- mgslpc_remove_device((MGSLPC_INFO *)link->priv);
+ mgslpc_remove_device((MGSLPC_INFO *)link->priv);
}
-static int mgslpc_suspend(struct pcmcia_device *dev)
+static int mgslpc_suspend(struct pcmcia_device *link)
{
- dev_link_t *link = dev_to_instance(dev);
MGSLPC_INFO *info = link->priv;
- link->state |= DEV_SUSPEND;
info->stop = 1;
- if (link->state & DEV_CONFIG)
- pcmcia_release_configuration(link->handle);
return 0;
}
-static int mgslpc_resume(struct pcmcia_device *dev)
+static int mgslpc_resume(struct pcmcia_device *link)
{
- dev_link_t *link = dev_to_instance(dev);
MGSLPC_INFO *info = link->priv;
- link->state &= ~DEV_SUSPEND;
- if (link->state & DEV_CONFIG)
- pcmcia_request_configuration(link->handle, &link->conf);
info->stop = 0;
return 0;
@@ -1280,7 +1246,7 @@ static irqreturn_t mgslpc_isr(int irq, void *dev_id, struct pt_regs * regs)
if (!info)
return IRQ_NONE;
- if (!(info->link.state & DEV_CONFIG))
+ if (!(info->p_dev->_locked))
return IRQ_HANDLED;
spin_lock(&info->lock);
@@ -3033,7 +2999,7 @@ static struct pcmcia_driver mgslpc_driver = {
.drv = {
.name = "synclink_cs",
},
- .probe = mgslpc_attach,
+ .probe = mgslpc_probe,
.remove = mgslpc_detach,
.id_table = mgslpc_ids,
.suspend = mgslpc_suspend,
OpenPOWER on IntegriCloud