#include <asm/io.h>
#include <asm/system.h>
-#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
#include <pcmcia/ciscode.h>
#include <pcmcia/ds.h>
static int quirk_post_ibm(struct pcmcia_device *link)
{
- conf_reg_t reg = { 0, CS_READ, 0x800, 0 };
+ u8 val;
int ret;
- ret = pcmcia_access_configuration_register(link, ®);
+ ret = pcmcia_read_config_byte(link, 0x800, &val);
if (ret)
goto failed;
- reg.Action = CS_WRITE;
- reg.Value = reg.Value | 1;
- ret = pcmcia_access_configuration_register(link, ®);
+ ret = pcmcia_write_config_byte(link, 0x800, val | 1);
if (ret)
goto failed;
return 0;
{
struct serial_info *info = link->priv;
- if (info->multi) {
- link->conf.Present |= PRESENT_EXT_STATUS;
- link->conf.ExtStatus = ESR_REQ_ATTN_ENA;
- }
+ if (info->multi)
+ link->config_flags |= CONF_ENABLE_ESR;
}
static const struct serial_quirk quirks[] = {
info->p_dev = link;
link->priv = info;
- link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
- link->io.NumPorts1 = 8;
- link->conf.Attributes = CONF_ENABLE_IRQ;
- if (do_sound) {
- link->conf.Attributes |= CONF_ENABLE_SPKR;
- link->conf.Status = CCSR_AUDIO_ENA;
- }
- link->conf.IntType = INT_MEMORY_AND_IO;
+ link->config_flags |= CONF_ENABLE_IRQ;
+ if (do_sound)
+ link->config_flags |= CONF_ENABLE_SPKR;
return serial_config(link);
}
/*====================================================================*/
+static int pfc_config(struct pcmcia_device *p_dev)
+{
+ unsigned int port = 0;
+ struct serial_info *info = p_dev->priv;
+
+ if ((p_dev->resource[1]->end != 0) &&
+ (resource_size(p_dev->resource[1]) == 8)) {
+ port = p_dev->resource[1]->start;
+ info->slave = 1;
+ } else if ((info->manfid == MANFID_OSITECH) &&
+ (resource_size(p_dev->resource[0]) == 0x40)) {
+ port = p_dev->resource[0]->start + 0x28;
+ info->slave = 1;
+ }
+ if (info->slave)
+ return setup_serial(p_dev, info, port, p_dev->irq);
+
+ dev_warn(&p_dev->dev, "no usable port range found, giving up\n");
+ return -ENODEV;
+}
+
static int simple_config_check(struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cf,
cistpl_cftable_entry_t *dflt,
int *try = priv_data;
if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM))
- p_dev->conf.Vpp =
+ p_dev->vpp =
cf->vpp1.param[CISTPL_POWER_VNOM] / 10000;
+ p_dev->io_lines = ((*try & 0x1) == 0) ?
+ 16 : cf->io.flags & CISTPL_IO_LINES_MASK;
+
if ((cf->io.nwin > 0) && (cf->io.win[0].len == size_table[(*try >> 1)])
&& (cf->io.win[0].base != 0)) {
- p_dev->io.BasePort1 = cf->io.win[0].base;
- p_dev->io.IOAddrLines = ((*try & 0x1) == 0) ?
- 16 : cf->io.flags & CISTPL_IO_LINES_MASK;
- if (!pcmcia_request_io(p_dev, &p_dev->io))
+ p_dev->resource[0]->start = cf->io.win[0].base;
+ if (!pcmcia_request_io(p_dev))
return 0;
}
return -EINVAL;
if ((cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) {
for (j = 0; j < 5; j++) {
- p_dev->io.BasePort1 = base[j];
- p_dev->io.IOAddrLines = base[j] ? 16 : 3;
- if (!pcmcia_request_io(p_dev, &p_dev->io))
+ p_dev->resource[0]->start = base[j];
+ p_dev->io_lines = base[j] ? 16 : 3;
+ if (!pcmcia_request_io(p_dev))
return 0;
}
}
struct serial_info *info = link->priv;
int i = -ENODEV, try;
- /* If the card is already configured, look up the port and irq */
- if (link->function_config) {
- unsigned int port = 0;
- if ((link->io.BasePort2 != 0) &&
- (link->io.NumPorts2 == 8)) {
- port = link->io.BasePort2;
- info->slave = 1;
- } else if ((info->manfid == MANFID_OSITECH) &&
- (link->io.NumPorts1 == 0x40)) {
- port = link->io.BasePort1 + 0x28;
- info->slave = 1;
- }
- if (info->slave) {
- return setup_serial(link, info, port,
- link->irq);
- }
- }
+ link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
+ link->resource[0]->end = 8;
/* First pass: look for a config entry that looks normal.
* Two tries: without IO aliases, then with aliases */
if (!pcmcia_loop_config(link, simple_config_check_notpicky, NULL))
goto found_port;
- printk(KERN_NOTICE
- "serial_cs: no usable port range found, giving up\n");
+ dev_warn(&link->dev, "no usable port range found, giving up\n");
return -1;
found_port:
if (info->multi && (info->manfid == MANFID_3COM))
- link->conf.ConfigIndex &= ~(0x08);
+ link->config_index &= ~(0x08);
/*
* Apply any configuration quirks.
if (info->quirk && info->quirk->config)
info->quirk->config(link);
- i = pcmcia_request_configuration(link, &link->conf);
+ i = pcmcia_enable_device(link);
if (i != 0)
return -1;
- return setup_serial(link, info, link->io.BasePort1, link->irq);
+ return setup_serial(link, info, link->resource[0]->start, link->irq);
}
static int multi_config_check(struct pcmcia_device *p_dev,
/* The quad port cards have bad CIS's, so just look for a
window larger than 8 ports and assume it will be right */
if ((cf->io.nwin == 1) && (cf->io.win[0].len > 8)) {
- p_dev->io.BasePort1 = cf->io.win[0].base;
- p_dev->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK;
- if (!pcmcia_request_io(p_dev, &p_dev->io)) {
- *base2 = p_dev->io.BasePort1 + 8;
+ p_dev->resource[0]->start = cf->io.win[0].base;
+ p_dev->io_lines = cf->io.flags & CISTPL_IO_LINES_MASK;
+ if (!pcmcia_request_io(p_dev)) {
+ *base2 = p_dev->resource[0]->start + 8;
return 0;
}
}
int *base2 = priv_data;
if (cf->io.nwin == 2) {
- p_dev->io.BasePort1 = cf->io.win[0].base;
- p_dev->io.BasePort2 = cf->io.win[1].base;
- p_dev->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK;
- if (!pcmcia_request_io(p_dev, &p_dev->io)) {
- *base2 = p_dev->io.BasePort2;
+ p_dev->resource[0]->start = cf->io.win[0].base;
+ p_dev->resource[1]->start = cf->io.win[1].base;
+ p_dev->io_lines = cf->io.flags & CISTPL_IO_LINES_MASK;
+ if (!pcmcia_request_io(p_dev)) {
+ *base2 = p_dev->resource[1]->start;
return 0;
}
}
int i, base2 = 0;
/* First, look for a generic full-sized window */
- link->io.NumPorts1 = info->multi * 8;
+ link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
+ link->resource[0]->end = info->multi * 8;
if (pcmcia_loop_config(link, multi_config_check, &base2)) {
/* If that didn't work, look for two windows */
- link->io.NumPorts1 = link->io.NumPorts2 = 8;
+ link->resource[0]->end = link->resource[1]->end = 8;
info->multi = 2;
if (pcmcia_loop_config(link, multi_config_check_notpicky,
&base2)) {
- printk(KERN_NOTICE "serial_cs: no usable port range"
+ dev_warn(&link->dev, "no usable port range "
"found, giving up\n");
return -ENODEV;
}
}
if (!link->irq)
- dev_warn(&link->dev,
- "serial_cs: no usable IRQ found, continuing...\n");
+ dev_warn(&link->dev, "no usable IRQ found, continuing...\n");
/*
* Apply any configuration quirks.
if (info->quirk && info->quirk->config)
info->quirk->config(link);
- i = pcmcia_request_configuration(link, &link->conf);
+ i = pcmcia_enable_device(link);
if (i != 0)
return -ENODEV;
info->prodid == PRODID_POSSIO_GCC)) {
int err;
- if (link->conf.ConfigIndex == 1 ||
- link->conf.ConfigIndex == 3) {
+ if (link->config_index == 1 ||
+ link->config_index == 3) {
err = setup_serial(link, info, base2,
link->irq);
- base2 = link->io.BasePort1;
+ base2 = link->resource[0]->start;;
} else {
- err = setup_serial(link, info, link->io.BasePort1,
+ err = setup_serial(link, info, link->resource[0]->start,
link->irq);
}
info->c950ctrl = base2;
return 0;
}
- setup_serial(link, info, link->io.BasePort1, link->irq);
+ setup_serial(link, info, link->resource[0]->start, link->irq);
for (i = 0; i < info->multi - 1; i++)
setup_serial(link, info, base2 + (8 * i),
link->irq);
multifunction cards that ask for appropriate IO port ranges */
if ((info->multi == 0) &&
(link->has_func_id) &&
+ (link->socket->pcmcia_pfc == 0) &&
((link->func_id == CISTPL_FUNCID_MULTI) ||
(link->func_id == CISTPL_FUNCID_SERIAL)))
pcmcia_loop_config(link, serial_check_for_multi, info);
if (info->quirk && info->quirk->multi != -1)
info->multi = info->quirk->multi;
- if (info->multi > 1)
+ dev_info(&link->dev,
+ "trying to set up [0x%04x:0x%04x] (pfc: %d, multi: %d, quirk: %p)\n",
+ link->manf_id, link->card_id,
+ link->socket->pcmcia_pfc, info->multi, info->quirk);
+ if (link->socket->pcmcia_pfc)
+ i = pfc_config(link);
+ else if (info->multi > 1)
i = multi_config(link);
else
i = simple_config(link);
return 0;
failed:
- dev_warn(&link->dev, "serial_cs: failed to initialize\n");
+ dev_warn(&link->dev, "failed to initialize\n");
serial_remove(link);
return -ENODEV;
}