Merge git://git.kernel.org/pub/scm/linux/kernel/git/brodo/pcmcia
Pull PCMCIA update from Dominik Brodowski:
"A few PCMCIA fixes and cleanups are available in the PCMCIA tree.
Most of them are trivial and self-explanatory. Of particular note are
the last three patches which add an important hardware quirk for
Toshiba ToPIC95 sockets (or BIOS breakage on systems with these
sockets), fix resource leaks in yenta_socket enable/disable call
paths, and fix a regression caused by patch 1c6c9b1d9d
since v4.0.
Alan stated he is OK with me pushing this patch upstream. Once it
works out well in your tree, I will push it to stable for 4.0/4.1 as
well"
* git://git.kernel.org/pub/scm/linux/kernel/git/brodo/pcmcia:
pcmcia: do not break rsrc_nonstatic when handling anonymous cards
pcmcia: Fix resource leaks in yenta_probe() and _close()
Disable write buffering on Toshiba ToPIC95
pcmcia: Convert dev_printk to dev_<level>
pcmcia/vrc4171: Remove typedefs for enums and struct
pcmcia: Remove typedef in structs and emum
pcmcia: Remove typedef tuple_flags
drivers: pcmcia: electra_cf.c fix checkpatch error and warnings
drivers: pcmcia: ds.c fix checkpatch errors
PCMCIA: Remove commented references to dead class_device_create_file()
drivers/pcmcia/electra_cf.c: add missing iounmap and kfree
pcmcia: replace open-coded ARRAY_SIZE with macro
This commit is contained in:
commit
a394c6a0b3
|
@ -532,8 +532,7 @@ static int reader_config(struct pcmcia_device *link, int devno)
|
||||||
|
|
||||||
fail_rc = pcmcia_enable_device(link);
|
fail_rc = pcmcia_enable_device(link);
|
||||||
if (fail_rc != 0) {
|
if (fail_rc != 0) {
|
||||||
dev_printk(KERN_INFO, &link->dev,
|
dev_info(&link->dev, "pcmcia_enable_device failed 0x%x\n",
|
||||||
"pcmcia_enable_device failed 0x%x\n",
|
|
||||||
fail_rc);
|
fail_rc);
|
||||||
goto cs_release;
|
goto cs_release;
|
||||||
}
|
}
|
||||||
|
|
|
@ -94,8 +94,7 @@ static void __iomem *set_cis_map(struct pcmcia_socket *s,
|
||||||
mem->res = pcmcia_find_mem_region(0, s->map_size,
|
mem->res = pcmcia_find_mem_region(0, s->map_size,
|
||||||
s->map_size, 0, s);
|
s->map_size, 0, s);
|
||||||
if (mem->res == NULL) {
|
if (mem->res == NULL) {
|
||||||
dev_printk(KERN_NOTICE, &s->dev,
|
dev_notice(&s->dev, "cs: unable to map card memory!\n");
|
||||||
"cs: unable to map card memory!\n");
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
s->cis_virt = NULL;
|
s->cis_virt = NULL;
|
||||||
|
@ -381,8 +380,7 @@ int verify_cis_cache(struct pcmcia_socket *s)
|
||||||
|
|
||||||
buf = kmalloc(256, GFP_KERNEL);
|
buf = kmalloc(256, GFP_KERNEL);
|
||||||
if (buf == NULL) {
|
if (buf == NULL) {
|
||||||
dev_printk(KERN_WARNING, &s->dev,
|
dev_warn(&s->dev, "no memory for verifying CIS\n");
|
||||||
"no memory for verifying CIS\n");
|
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
mutex_lock(&s->ops_mutex);
|
mutex_lock(&s->ops_mutex);
|
||||||
|
@ -414,14 +412,14 @@ int pcmcia_replace_cis(struct pcmcia_socket *s,
|
||||||
const u8 *data, const size_t len)
|
const u8 *data, const size_t len)
|
||||||
{
|
{
|
||||||
if (len > CISTPL_MAX_CIS_SIZE) {
|
if (len > CISTPL_MAX_CIS_SIZE) {
|
||||||
dev_printk(KERN_WARNING, &s->dev, "replacement CIS too big\n");
|
dev_warn(&s->dev, "replacement CIS too big\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
mutex_lock(&s->ops_mutex);
|
mutex_lock(&s->ops_mutex);
|
||||||
kfree(s->fake_cis);
|
kfree(s->fake_cis);
|
||||||
s->fake_cis = kmalloc(len, GFP_KERNEL);
|
s->fake_cis = kmalloc(len, GFP_KERNEL);
|
||||||
if (s->fake_cis == NULL) {
|
if (s->fake_cis == NULL) {
|
||||||
dev_printk(KERN_WARNING, &s->dev, "no memory to replace CIS\n");
|
dev_warn(&s->dev, "no memory to replace CIS\n");
|
||||||
mutex_unlock(&s->ops_mutex);
|
mutex_unlock(&s->ops_mutex);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
@ -434,17 +432,17 @@ int pcmcia_replace_cis(struct pcmcia_socket *s,
|
||||||
|
|
||||||
/* The high-level CIS tuple services */
|
/* The high-level CIS tuple services */
|
||||||
|
|
||||||
typedef struct tuple_flags {
|
struct tuple_flags {
|
||||||
u_int link_space:4;
|
u_int link_space:4;
|
||||||
u_int has_link:1;
|
u_int has_link:1;
|
||||||
u_int mfc_fn:3;
|
u_int mfc_fn:3;
|
||||||
u_int space:4;
|
u_int space:4;
|
||||||
} tuple_flags;
|
};
|
||||||
|
|
||||||
#define LINK_SPACE(f) (((tuple_flags *)(&(f)))->link_space)
|
#define LINK_SPACE(f) (((struct tuple_flags *)(&(f)))->link_space)
|
||||||
#define HAS_LINK(f) (((tuple_flags *)(&(f)))->has_link)
|
#define HAS_LINK(f) (((struct tuple_flags *)(&(f)))->has_link)
|
||||||
#define MFC_FN(f) (((tuple_flags *)(&(f)))->mfc_fn)
|
#define MFC_FN(f) (((struct tuple_flags *)(&(f)))->mfc_fn)
|
||||||
#define SPACE(f) (((tuple_flags *)(&(f)))->space)
|
#define SPACE(f) (((struct tuple_flags *)(&(f)))->space)
|
||||||
|
|
||||||
int pccard_get_first_tuple(struct pcmcia_socket *s, unsigned int function,
|
int pccard_get_first_tuple(struct pcmcia_socket *s, unsigned int function,
|
||||||
tuple_t *tuple)
|
tuple_t *tuple)
|
||||||
|
@ -1451,26 +1449,16 @@ int pccard_validate_cis(struct pcmcia_socket *s, unsigned int *info)
|
||||||
done:
|
done:
|
||||||
/* invalidate CIS cache on failure */
|
/* invalidate CIS cache on failure */
|
||||||
if (!dev_ok || !ident_ok || !count) {
|
if (!dev_ok || !ident_ok || !count) {
|
||||||
#if defined(CONFIG_MTD_PCMCIA_ANONYMOUS)
|
|
||||||
/* Set up as an anonymous card. If we don't have anonymous
|
|
||||||
memory support then just error the card as there is no
|
|
||||||
point trying to second guess.
|
|
||||||
|
|
||||||
Note: some cards have just a device entry, it may be
|
|
||||||
worth extending support to cover these in future */
|
|
||||||
if (!dev_ok || !ident_ok) {
|
|
||||||
dev_info(&s->dev, "no CIS, assuming an anonymous memory card.\n");
|
|
||||||
pcmcia_replace_cis(s, "\xFF", 1);
|
|
||||||
count = 1;
|
|
||||||
ret = 0;
|
|
||||||
} else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
mutex_lock(&s->ops_mutex);
|
mutex_lock(&s->ops_mutex);
|
||||||
destroy_cis_cache(s);
|
destroy_cis_cache(s);
|
||||||
mutex_unlock(&s->ops_mutex);
|
mutex_unlock(&s->ops_mutex);
|
||||||
|
/* We differentiate between dev_ok, ident_ok and count
|
||||||
|
failures to allow for an override for anonymous cards
|
||||||
|
in ds.c */
|
||||||
|
if (!dev_ok || !ident_ok)
|
||||||
ret = -EIO;
|
ret = -EIO;
|
||||||
}
|
else
|
||||||
|
ret = -EFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info)
|
if (info)
|
||||||
|
|
|
@ -177,7 +177,7 @@ int pcmcia_register_socket(struct pcmcia_socket *socket)
|
||||||
|
|
||||||
wait_for_completion(&socket->thread_done);
|
wait_for_completion(&socket->thread_done);
|
||||||
if (!socket->thread) {
|
if (!socket->thread) {
|
||||||
dev_printk(KERN_WARNING, &socket->dev,
|
dev_warn(&socket->dev,
|
||||||
"PCMCIA: warning: socket thread did not start\n");
|
"PCMCIA: warning: socket thread did not start\n");
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
@ -275,7 +275,7 @@ static int socket_reset(struct pcmcia_socket *skt)
|
||||||
msleep(unreset_check * 10);
|
msleep(unreset_check * 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
dev_printk(KERN_ERR, &skt->dev, "time out after reset.\n");
|
dev_err(&skt->dev, "time out after reset\n");
|
||||||
return -ETIMEDOUT;
|
return -ETIMEDOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -325,7 +325,7 @@ static void socket_shutdown(struct pcmcia_socket *s)
|
||||||
|
|
||||||
s->ops->get_status(s, &status);
|
s->ops->get_status(s, &status);
|
||||||
if (status & SS_POWERON) {
|
if (status & SS_POWERON) {
|
||||||
dev_printk(KERN_ERR, &s->dev,
|
dev_err(&s->dev,
|
||||||
"*** DANGER *** unable to remove socket power\n");
|
"*** DANGER *** unable to remove socket power\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -356,15 +356,13 @@ static int socket_setup(struct pcmcia_socket *skt, int initial_delay)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status & SS_PENDING) {
|
if (status & SS_PENDING) {
|
||||||
dev_printk(KERN_ERR, &skt->dev,
|
dev_err(&skt->dev, "voltage interrogation timed out\n");
|
||||||
"voltage interrogation timed out.\n");
|
|
||||||
return -ETIMEDOUT;
|
return -ETIMEDOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status & SS_CARDBUS) {
|
if (status & SS_CARDBUS) {
|
||||||
if (!(skt->features & SS_CAP_CARDBUS)) {
|
if (!(skt->features & SS_CAP_CARDBUS)) {
|
||||||
dev_printk(KERN_ERR, &skt->dev,
|
dev_err(&skt->dev, "cardbus cards are not supported\n");
|
||||||
"cardbus cards are not supported.\n");
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
skt->state |= SOCKET_CARDBUS;
|
skt->state |= SOCKET_CARDBUS;
|
||||||
|
@ -379,7 +377,7 @@ static int socket_setup(struct pcmcia_socket *skt, int initial_delay)
|
||||||
else if (!(status & SS_XVCARD))
|
else if (!(status & SS_XVCARD))
|
||||||
skt->socket.Vcc = skt->socket.Vpp = 50;
|
skt->socket.Vcc = skt->socket.Vpp = 50;
|
||||||
else {
|
else {
|
||||||
dev_printk(KERN_ERR, &skt->dev, "unsupported voltage key.\n");
|
dev_err(&skt->dev, "unsupported voltage key\n");
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -396,7 +394,7 @@ static int socket_setup(struct pcmcia_socket *skt, int initial_delay)
|
||||||
|
|
||||||
skt->ops->get_status(skt, &status);
|
skt->ops->get_status(skt, &status);
|
||||||
if (!(status & SS_POWERON)) {
|
if (!(status & SS_POWERON)) {
|
||||||
dev_printk(KERN_ERR, &skt->dev, "unable to apply power.\n");
|
dev_err(&skt->dev, "unable to apply power\n");
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -429,8 +427,7 @@ static int socket_insert(struct pcmcia_socket *skt)
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
skt->state |= SOCKET_PRESENT;
|
skt->state |= SOCKET_PRESENT;
|
||||||
|
|
||||||
dev_printk(KERN_NOTICE, &skt->dev,
|
dev_notice(&skt->dev, "pccard: %s card inserted into slot %d\n",
|
||||||
"pccard: %s card inserted into slot %d\n",
|
|
||||||
(skt->state & SOCKET_CARDBUS) ? "CardBus" : "PCMCIA",
|
(skt->state & SOCKET_CARDBUS) ? "CardBus" : "PCMCIA",
|
||||||
skt->sock);
|
skt->sock);
|
||||||
|
|
||||||
|
@ -558,8 +555,7 @@ static int socket_resume(struct pcmcia_socket *skt)
|
||||||
|
|
||||||
static void socket_remove(struct pcmcia_socket *skt)
|
static void socket_remove(struct pcmcia_socket *skt)
|
||||||
{
|
{
|
||||||
dev_printk(KERN_NOTICE, &skt->dev,
|
dev_notice(&skt->dev, "pccard: card ejected from slot %d\n", skt->sock);
|
||||||
"pccard: card ejected from slot %d\n", skt->sock);
|
|
||||||
socket_shutdown(skt);
|
socket_shutdown(skt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -605,8 +601,7 @@ static int pccardd(void *__skt)
|
||||||
/* register with the device core */
|
/* register with the device core */
|
||||||
ret = device_register(&skt->dev);
|
ret = device_register(&skt->dev);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_printk(KERN_WARNING, &skt->dev,
|
dev_warn(&skt->dev, "PCMCIA: unable to register socket\n");
|
||||||
"PCMCIA: unable to register socket\n");
|
|
||||||
skt->thread = NULL;
|
skt->thread = NULL;
|
||||||
complete(&skt->thread_done);
|
complete(&skt->thread_done);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -284,7 +284,7 @@ static int pcmcia_device_probe(struct device *dev)
|
||||||
dev_dbg(dev, "base %x, regs %x", p_dev->config_base,
|
dev_dbg(dev, "base %x, regs %x", p_dev->config_base,
|
||||||
p_dev->config_regs);
|
p_dev->config_regs);
|
||||||
} else {
|
} else {
|
||||||
dev_printk(KERN_INFO, dev,
|
dev_info(dev,
|
||||||
"pcmcia: could not parse base and rmask0 of CIS\n");
|
"pcmcia: could not parse base and rmask0 of CIS\n");
|
||||||
p_dev->config_base = 0;
|
p_dev->config_base = 0;
|
||||||
p_dev->config_regs = 0;
|
p_dev->config_regs = 0;
|
||||||
|
@ -382,13 +382,13 @@ static int pcmcia_device_remove(struct device *dev)
|
||||||
|
|
||||||
/* check for proper unloading */
|
/* check for proper unloading */
|
||||||
if (p_dev->_irq || p_dev->_io || p_dev->_locked)
|
if (p_dev->_irq || p_dev->_io || p_dev->_locked)
|
||||||
dev_printk(KERN_INFO, dev,
|
dev_info(dev,
|
||||||
"pcmcia: driver %s did not release config properly\n",
|
"pcmcia: driver %s did not release config properly\n",
|
||||||
p_drv->name);
|
p_drv->name);
|
||||||
|
|
||||||
for (i = 0; i < MAX_WIN; i++)
|
for (i = 0; i < MAX_WIN; i++)
|
||||||
if (p_dev->_win & CLIENT_WIN_REQ(i))
|
if (p_dev->_win & CLIENT_WIN_REQ(i))
|
||||||
dev_printk(KERN_INFO, dev,
|
dev_info(dev,
|
||||||
"pcmcia: driver %s did not release window properly\n",
|
"pcmcia: driver %s did not release window properly\n",
|
||||||
p_drv->name);
|
p_drv->name);
|
||||||
|
|
||||||
|
@ -566,7 +566,7 @@ static struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s,
|
||||||
c->io[i].name = p_dev->devname;
|
c->io[i].name = p_dev->devname;
|
||||||
c->io[i].flags = IORESOURCE_IO;
|
c->io[i].flags = IORESOURCE_IO;
|
||||||
}
|
}
|
||||||
for (i = 0; i< MAX_WIN; i++) {
|
for (i = 0; i < MAX_WIN; i++) {
|
||||||
c->mem[i].name = p_dev->devname;
|
c->mem[i].name = p_dev->devname;
|
||||||
c->mem[i].flags = IORESOURCE_MEM;
|
c->mem[i].flags = IORESOURCE_MEM;
|
||||||
}
|
}
|
||||||
|
@ -578,8 +578,7 @@ static struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s,
|
||||||
|
|
||||||
mutex_unlock(&s->ops_mutex);
|
mutex_unlock(&s->ops_mutex);
|
||||||
|
|
||||||
dev_printk(KERN_NOTICE, &p_dev->dev,
|
dev_notice(&p_dev->dev, "pcmcia: registering new device %s (IRQ: %d)\n",
|
||||||
"pcmcia: registering new device %s (IRQ: %d)\n",
|
|
||||||
p_dev->devname, p_dev->irq);
|
p_dev->devname, p_dev->irq);
|
||||||
|
|
||||||
pcmcia_device_query(p_dev);
|
pcmcia_device_query(p_dev);
|
||||||
|
@ -634,9 +633,25 @@ static int pcmcia_card_add(struct pcmcia_socket *s)
|
||||||
|
|
||||||
ret = pccard_validate_cis(s, &no_chains);
|
ret = pccard_validate_cis(s, &no_chains);
|
||||||
if (ret || !no_chains) {
|
if (ret || !no_chains) {
|
||||||
|
#if defined(CONFIG_MTD_PCMCIA_ANONYMOUS)
|
||||||
|
/* Set up as an anonymous card. If we don't have anonymous
|
||||||
|
memory support then just error the card as there is no
|
||||||
|
point trying to second guess.
|
||||||
|
|
||||||
|
Note: some cards have just a device entry, it may be
|
||||||
|
worth extending support to cover these in future */
|
||||||
|
if (ret == -EIO) {
|
||||||
|
dev_info(&s->dev, "no CIS, assuming an anonymous memory card.\n");
|
||||||
|
pcmcia_replace_cis(s, "\xFF", 1);
|
||||||
|
no_chains = 1;
|
||||||
|
ret = 0;
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
dev_dbg(&s->dev, "invalid CIS or invalid resources\n");
|
dev_dbg(&s->dev, "invalid CIS or invalid resources\n");
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!pccard_read_tuple(s, BIND_FN_ALL, CISTPL_LONGLINK_MFC, &mfc))
|
if (!pccard_read_tuple(s, BIND_FN_ALL, CISTPL_LONGLINK_MFC, &mfc))
|
||||||
no_funcs = mfc.nfn;
|
no_funcs = mfc.nfn;
|
||||||
|
@ -651,7 +666,7 @@ static int pcmcia_card_add(struct pcmcia_socket *s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int pcmcia_requery_callback(struct device *dev, void * _data)
|
static int pcmcia_requery_callback(struct device *dev, void *_data)
|
||||||
{
|
{
|
||||||
struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
|
struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
|
||||||
if (!p_dev->dev.driver) {
|
if (!p_dev->dev.driver) {
|
||||||
|
@ -729,7 +744,7 @@ static void pcmcia_requery(struct pcmcia_socket *s)
|
||||||
* the one provided by the card is broken. The firmware files reside in
|
* the one provided by the card is broken. The firmware files reside in
|
||||||
* /lib/firmware/ in userspace.
|
* /lib/firmware/ in userspace.
|
||||||
*/
|
*/
|
||||||
static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename)
|
static int pcmcia_load_firmware(struct pcmcia_device *dev, char *filename)
|
||||||
{
|
{
|
||||||
struct pcmcia_socket *s = dev->socket;
|
struct pcmcia_socket *s = dev->socket;
|
||||||
const struct firmware *fw;
|
const struct firmware *fw;
|
||||||
|
@ -745,16 +760,14 @@ static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename)
|
||||||
if (request_firmware(&fw, filename, &dev->dev) == 0) {
|
if (request_firmware(&fw, filename, &dev->dev) == 0) {
|
||||||
if (fw->size >= CISTPL_MAX_CIS_SIZE) {
|
if (fw->size >= CISTPL_MAX_CIS_SIZE) {
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
dev_printk(KERN_ERR, &dev->dev,
|
dev_err(&dev->dev, "pcmcia: CIS override is too big\n");
|
||||||
"pcmcia: CIS override is too big\n");
|
|
||||||
goto release;
|
goto release;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pcmcia_replace_cis(s, fw->data, fw->size))
|
if (!pcmcia_replace_cis(s, fw->data, fw->size))
|
||||||
ret = 0;
|
ret = 0;
|
||||||
else {
|
else {
|
||||||
dev_printk(KERN_ERR, &dev->dev,
|
dev_err(&dev->dev, "pcmcia: CIS override failed\n");
|
||||||
"pcmcia: CIS override failed\n");
|
|
||||||
goto release;
|
goto release;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -781,7 +794,8 @@ static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename)
|
||||||
|
|
||||||
#else /* !CONFIG_PCMCIA_LOAD_CIS */
|
#else /* !CONFIG_PCMCIA_LOAD_CIS */
|
||||||
|
|
||||||
static inline int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename)
|
static inline int pcmcia_load_firmware(struct pcmcia_device *dev,
|
||||||
|
char *filename)
|
||||||
{
|
{
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
@ -1148,9 +1162,8 @@ static int pcmcia_dev_suspend(struct device *dev, pm_message_t state)
|
||||||
if (p_drv->suspend) {
|
if (p_drv->suspend) {
|
||||||
ret = p_drv->suspend(p_dev);
|
ret = p_drv->suspend(p_dev);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_printk(KERN_ERR, dev,
|
dev_err(dev,
|
||||||
"pcmcia: device %s (driver %s) did "
|
"pcmcia: device %s (driver %s) did not want to go to sleep (%d)\n",
|
||||||
"not want to go to sleep (%d)\n",
|
|
||||||
p_dev->devname, p_drv->name, ret);
|
p_dev->devname, p_drv->name, ret);
|
||||||
mutex_lock(&p_dev->socket->ops_mutex);
|
mutex_lock(&p_dev->socket->ops_mutex);
|
||||||
p_dev->suspended = 0;
|
p_dev->suspended = 0;
|
||||||
|
@ -1206,7 +1219,7 @@ static int pcmcia_dev_resume(struct device *dev)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int pcmcia_bus_suspend_callback(struct device *dev, void * _data)
|
static int pcmcia_bus_suspend_callback(struct device *dev, void *_data)
|
||||||
{
|
{
|
||||||
struct pcmcia_socket *skt = _data;
|
struct pcmcia_socket *skt = _data;
|
||||||
struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
|
struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
|
||||||
|
@ -1217,7 +1230,7 @@ static int pcmcia_bus_suspend_callback(struct device *dev, void * _data)
|
||||||
return runtime_suspend(dev);
|
return runtime_suspend(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pcmcia_bus_resume_callback(struct device *dev, void * _data)
|
static int pcmcia_bus_resume_callback(struct device *dev, void *_data)
|
||||||
{
|
{
|
||||||
struct pcmcia_socket *skt = _data;
|
struct pcmcia_socket *skt = _data;
|
||||||
struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
|
struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
|
||||||
|
@ -1342,14 +1355,13 @@ static int pcmcia_bus_add_socket(struct device *dev,
|
||||||
|
|
||||||
socket = pcmcia_get_socket(socket);
|
socket = pcmcia_get_socket(socket);
|
||||||
if (!socket) {
|
if (!socket) {
|
||||||
dev_printk(KERN_ERR, dev,
|
dev_err(dev, "PCMCIA obtaining reference to socket failed\n");
|
||||||
"PCMCIA obtaining reference to socket failed\n");
|
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = sysfs_create_bin_file(&dev->kobj, &pccard_cis_attr);
|
ret = sysfs_create_bin_file(&dev->kobj, &pccard_cis_attr);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_printk(KERN_ERR, dev, "PCMCIA registration failed\n");
|
dev_err(dev, "PCMCIA registration failed\n");
|
||||||
pcmcia_put_socket(socket);
|
pcmcia_put_socket(socket);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -1361,7 +1373,7 @@ static int pcmcia_bus_add_socket(struct device *dev,
|
||||||
|
|
||||||
ret = pccard_register_pcmcia(socket, &pcmcia_bus_callback);
|
ret = pccard_register_pcmcia(socket, &pcmcia_bus_callback);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_printk(KERN_ERR, dev, "PCMCIA registration failed\n");
|
dev_err(dev, "PCMCIA registration failed\n");
|
||||||
pcmcia_put_socket(socket);
|
pcmcia_put_socket(socket);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,14 +48,14 @@ struct electra_cf_socket {
|
||||||
|
|
||||||
struct platform_device *ofdev;
|
struct platform_device *ofdev;
|
||||||
unsigned long mem_phys;
|
unsigned long mem_phys;
|
||||||
void __iomem * mem_base;
|
void __iomem *mem_base;
|
||||||
unsigned long mem_size;
|
unsigned long mem_size;
|
||||||
void __iomem * io_virt;
|
void __iomem *io_virt;
|
||||||
unsigned int io_base;
|
unsigned int io_base;
|
||||||
unsigned int io_size;
|
unsigned int io_size;
|
||||||
u_int irq;
|
u_int irq;
|
||||||
struct resource iomem;
|
struct resource iomem;
|
||||||
void __iomem * gpio_base;
|
void __iomem *gpio_base;
|
||||||
int gpio_detect;
|
int gpio_detect;
|
||||||
int gpio_vsense;
|
int gpio_vsense;
|
||||||
int gpio_3v;
|
int gpio_3v;
|
||||||
|
@ -202,7 +202,7 @@ static int electra_cf_probe(struct platform_device *ofdev)
|
||||||
if (err)
|
if (err)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
cf = kzalloc(sizeof *cf, GFP_KERNEL);
|
cf = kzalloc(sizeof(*cf), GFP_KERNEL);
|
||||||
if (!cf)
|
if (!cf)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
@ -216,8 +216,10 @@ static int electra_cf_probe(struct platform_device *ofdev)
|
||||||
cf->io_size = PAGE_ALIGN(resource_size(&io));
|
cf->io_size = PAGE_ALIGN(resource_size(&io));
|
||||||
|
|
||||||
area = __get_vm_area(cf->io_size, 0, PHB_IO_BASE, PHB_IO_END);
|
area = __get_vm_area(cf->io_size, 0, PHB_IO_BASE, PHB_IO_END);
|
||||||
if (area == NULL)
|
if (area == NULL) {
|
||||||
return -ENOMEM;
|
status = -ENOMEM;
|
||||||
|
goto fail1;
|
||||||
|
}
|
||||||
|
|
||||||
cf->io_virt = (void __iomem *)(area->addr);
|
cf->io_virt = (void __iomem *)(area->addr);
|
||||||
|
|
||||||
|
@ -320,6 +322,7 @@ fail1:
|
||||||
iounmap(cf->mem_base);
|
iounmap(cf->mem_base);
|
||||||
if (cf->gpio_base)
|
if (cf->gpio_base)
|
||||||
iounmap(cf->gpio_base);
|
iounmap(cf->gpio_base);
|
||||||
|
if (area)
|
||||||
device_init_wakeup(&ofdev->dev, 0);
|
device_init_wakeup(&ofdev->dev, 0);
|
||||||
kfree(cf);
|
kfree(cf);
|
||||||
return status;
|
return status;
|
||||||
|
@ -369,5 +372,5 @@ static struct platform_driver electra_cf_driver = {
|
||||||
module_platform_driver(electra_cf_driver);
|
module_platform_driver(electra_cf_driver);
|
||||||
|
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
MODULE_AUTHOR ("Olof Johansson <olof@lixom.net>");
|
MODULE_AUTHOR("Olof Johansson <olof@lixom.net>");
|
||||||
MODULE_DESCRIPTION("PA Semi Electra CF driver");
|
MODULE_DESCRIPTION("PA Semi Electra CF driver");
|
||||||
|
|
|
@ -132,14 +132,14 @@ module_param(recov_time, int, 0444);
|
||||||
|
|
||||||
/*====================================================================*/
|
/*====================================================================*/
|
||||||
|
|
||||||
typedef struct cirrus_state_t {
|
struct cirrus_state {
|
||||||
u_char misc1, misc2;
|
u_char misc1, misc2;
|
||||||
u_char timer[6];
|
u_char timer[6];
|
||||||
} cirrus_state_t;
|
};
|
||||||
|
|
||||||
typedef struct vg46x_state_t {
|
struct vg46x_state {
|
||||||
u_char ctl, ema;
|
u_char ctl, ema;
|
||||||
} vg46x_state_t;
|
};
|
||||||
|
|
||||||
struct i82365_socket {
|
struct i82365_socket {
|
||||||
u_short type, flags;
|
u_short type, flags;
|
||||||
|
@ -149,8 +149,8 @@ struct i82365_socket {
|
||||||
u_short psock;
|
u_short psock;
|
||||||
u_char cs_irq, intr;
|
u_char cs_irq, intr;
|
||||||
union {
|
union {
|
||||||
cirrus_state_t cirrus;
|
struct cirrus_state cirrus;
|
||||||
vg46x_state_t vg46x;
|
struct vg46x_state vg46x;
|
||||||
} state;
|
} state;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -173,11 +173,11 @@ static struct timer_list poll_timer;
|
||||||
/*====================================================================*/
|
/*====================================================================*/
|
||||||
|
|
||||||
/* These definitions must match the pcic table! */
|
/* These definitions must match the pcic table! */
|
||||||
typedef enum pcic_id {
|
enum pcic_id {
|
||||||
IS_I82365A, IS_I82365B, IS_I82365DF,
|
IS_I82365A, IS_I82365B, IS_I82365DF,
|
||||||
IS_IBM, IS_RF5Cx96, IS_VLSI, IS_VG468, IS_VG469,
|
IS_IBM, IS_RF5Cx96, IS_VLSI, IS_VG468, IS_VG469,
|
||||||
IS_PD6710, IS_PD672X, IS_VT83C469,
|
IS_PD6710, IS_PD672X, IS_VT83C469,
|
||||||
} pcic_id;
|
};
|
||||||
|
|
||||||
/* Flags for classifying groups of controllers */
|
/* Flags for classifying groups of controllers */
|
||||||
#define IS_VADEM 0x0001
|
#define IS_VADEM 0x0001
|
||||||
|
@ -189,12 +189,12 @@ typedef enum pcic_id {
|
||||||
#define IS_REGISTERED 0x2000
|
#define IS_REGISTERED 0x2000
|
||||||
#define IS_ALIVE 0x8000
|
#define IS_ALIVE 0x8000
|
||||||
|
|
||||||
typedef struct pcic_t {
|
struct pcic {
|
||||||
char *name;
|
char *name;
|
||||||
u_short flags;
|
u_short flags;
|
||||||
} pcic_t;
|
};
|
||||||
|
|
||||||
static pcic_t pcic[] = {
|
static struct pcic pcic[] = {
|
||||||
{ "Intel i82365sl A step", 0 },
|
{ "Intel i82365sl A step", 0 },
|
||||||
{ "Intel i82365sl B step", 0 },
|
{ "Intel i82365sl B step", 0 },
|
||||||
{ "Intel i82365sl DF", IS_DF_PWR },
|
{ "Intel i82365sl DF", IS_DF_PWR },
|
||||||
|
@ -208,7 +208,7 @@ static pcic_t pcic[] = {
|
||||||
{ "VIA VT83C469", IS_CIRRUS|IS_VIA },
|
{ "VIA VT83C469", IS_CIRRUS|IS_VIA },
|
||||||
};
|
};
|
||||||
|
|
||||||
#define PCIC_COUNT (sizeof(pcic)/sizeof(pcic_t))
|
#define PCIC_COUNT ARRAY_SIZE(pcic)
|
||||||
|
|
||||||
/*====================================================================*/
|
/*====================================================================*/
|
||||||
|
|
||||||
|
@ -294,7 +294,7 @@ static void i365_set_pair(u_short sock, u_short reg, u_short data)
|
||||||
static void cirrus_get_state(u_short s)
|
static void cirrus_get_state(u_short s)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
cirrus_state_t *p = &socket[s].state.cirrus;
|
struct cirrus_state *p = &socket[s].state.cirrus;
|
||||||
p->misc1 = i365_get(s, PD67_MISC_CTL_1);
|
p->misc1 = i365_get(s, PD67_MISC_CTL_1);
|
||||||
p->misc1 &= (PD67_MC1_MEDIA_ENA | PD67_MC1_INPACK_ENA);
|
p->misc1 &= (PD67_MC1_MEDIA_ENA | PD67_MC1_INPACK_ENA);
|
||||||
p->misc2 = i365_get(s, PD67_MISC_CTL_2);
|
p->misc2 = i365_get(s, PD67_MISC_CTL_2);
|
||||||
|
@ -306,7 +306,7 @@ static void cirrus_set_state(u_short s)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
u_char misc;
|
u_char misc;
|
||||||
cirrus_state_t *p = &socket[s].state.cirrus;
|
struct cirrus_state *p = &socket[s].state.cirrus;
|
||||||
|
|
||||||
misc = i365_get(s, PD67_MISC_CTL_2);
|
misc = i365_get(s, PD67_MISC_CTL_2);
|
||||||
i365_set(s, PD67_MISC_CTL_2, p->misc2);
|
i365_set(s, PD67_MISC_CTL_2, p->misc2);
|
||||||
|
@ -321,7 +321,7 @@ static void cirrus_set_state(u_short s)
|
||||||
static u_int __init cirrus_set_opts(u_short s, char *buf)
|
static u_int __init cirrus_set_opts(u_short s, char *buf)
|
||||||
{
|
{
|
||||||
struct i82365_socket *t = &socket[s];
|
struct i82365_socket *t = &socket[s];
|
||||||
cirrus_state_t *p = &socket[s].state.cirrus;
|
struct cirrus_state *p = &socket[s].state.cirrus;
|
||||||
u_int mask = 0xffff;
|
u_int mask = 0xffff;
|
||||||
|
|
||||||
if (has_ring == -1) has_ring = 1;
|
if (has_ring == -1) has_ring = 1;
|
||||||
|
@ -377,7 +377,7 @@ static u_int __init cirrus_set_opts(u_short s, char *buf)
|
||||||
|
|
||||||
static void vg46x_get_state(u_short s)
|
static void vg46x_get_state(u_short s)
|
||||||
{
|
{
|
||||||
vg46x_state_t *p = &socket[s].state.vg46x;
|
struct vg46x_state *p = &socket[s].state.vg46x;
|
||||||
p->ctl = i365_get(s, VG468_CTL);
|
p->ctl = i365_get(s, VG468_CTL);
|
||||||
if (socket[s].type == IS_VG469)
|
if (socket[s].type == IS_VG469)
|
||||||
p->ema = i365_get(s, VG469_EXT_MODE);
|
p->ema = i365_get(s, VG469_EXT_MODE);
|
||||||
|
@ -385,7 +385,7 @@ static void vg46x_get_state(u_short s)
|
||||||
|
|
||||||
static void vg46x_set_state(u_short s)
|
static void vg46x_set_state(u_short s)
|
||||||
{
|
{
|
||||||
vg46x_state_t *p = &socket[s].state.vg46x;
|
struct vg46x_state *p = &socket[s].state.vg46x;
|
||||||
i365_set(s, VG468_CTL, p->ctl);
|
i365_set(s, VG468_CTL, p->ctl);
|
||||||
if (socket[s].type == IS_VG469)
|
if (socket[s].type == IS_VG469)
|
||||||
i365_set(s, VG469_EXT_MODE, p->ema);
|
i365_set(s, VG469_EXT_MODE, p->ema);
|
||||||
|
@ -393,7 +393,7 @@ static void vg46x_set_state(u_short s)
|
||||||
|
|
||||||
static u_int __init vg46x_set_opts(u_short s, char *buf)
|
static u_int __init vg46x_set_opts(u_short s, char *buf)
|
||||||
{
|
{
|
||||||
vg46x_state_t *p = &socket[s].state.vg46x;
|
struct vg46x_state *p = &socket[s].state.vg46x;
|
||||||
|
|
||||||
flip(p->ctl, VG468_CTL_ASYNC, async_clock);
|
flip(p->ctl, VG468_CTL_ASYNC, async_clock);
|
||||||
flip(p->ema, VG469_MODE_CABLE, cable_mode);
|
flip(p->ema, VG469_MODE_CABLE, cable_mode);
|
||||||
|
@ -1285,13 +1285,6 @@ static int __init init_i82365(void)
|
||||||
ret = pcmcia_register_socket(&socket[i].socket);
|
ret = pcmcia_register_socket(&socket[i].socket);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
socket[i].flags |= IS_REGISTERED;
|
socket[i].flags |= IS_REGISTERED;
|
||||||
|
|
||||||
#if 0 /* driver model ordering issue */
|
|
||||||
class_device_create_file(&socket[i].socket.dev,
|
|
||||||
&class_device_attr_info);
|
|
||||||
class_device_create_file(&socket[i].socket.dev,
|
|
||||||
&class_device_attr_exca);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Finally, schedule a polling interrupt */
|
/* Finally, schedule a polling interrupt */
|
||||||
|
|
|
@ -754,13 +754,6 @@ static int __init init_m32r_pcc(void)
|
||||||
ret = pcmcia_register_socket(&socket[i].socket);
|
ret = pcmcia_register_socket(&socket[i].socket);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
socket[i].flags |= IS_REGISTERED;
|
socket[i].flags |= IS_REGISTERED;
|
||||||
|
|
||||||
#if 0 /* driver model ordering issue */
|
|
||||||
class_device_create_file(&socket[i].socket.dev,
|
|
||||||
&class_device_attr_info);
|
|
||||||
class_device_create_file(&socket[i].socket.dev,
|
|
||||||
&class_device_attr_exca);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Finally, schedule a polling interrupt */
|
/* Finally, schedule a polling interrupt */
|
||||||
|
|
|
@ -716,13 +716,6 @@ static int __init init_m32r_pcc(void)
|
||||||
ret = pcmcia_register_socket(&socket[i].socket);
|
ret = pcmcia_register_socket(&socket[i].socket);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
socket[i].flags |= IS_REGISTERED;
|
socket[i].flags |= IS_REGISTERED;
|
||||||
|
|
||||||
#if 0 /* driver model ordering issue */
|
|
||||||
class_device_create_file(&socket[i].socket.dev,
|
|
||||||
&class_device_attr_info);
|
|
||||||
class_device_create_file(&socket[i].socket.dev,
|
|
||||||
&class_device_attr_exca);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Finally, schedule a polling interrupt */
|
/* Finally, schedule a polling interrupt */
|
||||||
|
|
|
@ -44,7 +44,7 @@ int pccard_read_tuple(struct pcmcia_socket *s, unsigned int function,
|
||||||
|
|
||||||
buf = kmalloc(256, GFP_KERNEL);
|
buf = kmalloc(256, GFP_KERNEL);
|
||||||
if (buf == NULL) {
|
if (buf == NULL) {
|
||||||
dev_printk(KERN_WARNING, &s->dev, "no memory to read tuple\n");
|
dev_warn(&s->dev, "no memory to read tuple\n");
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
tuple.DesiredTuple = code;
|
tuple.DesiredTuple = code;
|
||||||
|
@ -94,7 +94,7 @@ int pccard_loop_tuple(struct pcmcia_socket *s, unsigned int function,
|
||||||
|
|
||||||
buf = kzalloc(256, GFP_KERNEL);
|
buf = kzalloc(256, GFP_KERNEL);
|
||||||
if (buf == NULL) {
|
if (buf == NULL) {
|
||||||
dev_printk(KERN_WARNING, &s->dev, "no memory to read tuple\n");
|
dev_warn(&s->dev, "no memory to read tuple\n");
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -508,8 +508,7 @@ int pcmcia_enable_device(struct pcmcia_device *p_dev)
|
||||||
s->socket.Vpp = p_dev->vpp;
|
s->socket.Vpp = p_dev->vpp;
|
||||||
if (s->ops->set_socket(s, &s->socket)) {
|
if (s->ops->set_socket(s, &s->socket)) {
|
||||||
mutex_unlock(&s->ops_mutex);
|
mutex_unlock(&s->ops_mutex);
|
||||||
dev_printk(KERN_WARNING, &p_dev->dev,
|
dev_warn(&p_dev->dev, "Unable to set socket state\n");
|
||||||
"Unable to set socket state\n");
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -736,13 +735,11 @@ __pcmcia_request_exclusive_irq(struct pcmcia_device *p_dev,
|
||||||
ret = request_irq(p_dev->irq, handler, 0, p_dev->devname, p_dev->priv);
|
ret = request_irq(p_dev->irq, handler, 0, p_dev->devname, p_dev->priv);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
ret = pcmcia_request_irq(p_dev, handler);
|
ret = pcmcia_request_irq(p_dev, handler);
|
||||||
dev_printk(KERN_WARNING, &p_dev->dev, "pcmcia: "
|
dev_warn(&p_dev->dev, "pcmcia: request for exclusive IRQ could not be fulfilled\n");
|
||||||
"request for exclusive IRQ could not be fulfilled.\n");
|
dev_warn(&p_dev->dev, "pcmcia: the driver needs updating to supported shared IRQ lines\n");
|
||||||
dev_printk(KERN_WARNING, &p_dev->dev, "pcmcia: the driver "
|
|
||||||
"needs updating to supported shared IRQ lines.\n");
|
|
||||||
}
|
}
|
||||||
if (ret)
|
if (ret)
|
||||||
dev_printk(KERN_INFO, &p_dev->dev, "request_irq() failed\n");
|
dev_info(&p_dev->dev, "request_irq() failed\n");
|
||||||
else
|
else
|
||||||
p_dev->_irq = 1;
|
p_dev->_irq = 1;
|
||||||
|
|
||||||
|
|
|
@ -191,15 +191,13 @@ static void do_io_probe(struct pcmcia_socket *s, unsigned int base,
|
||||||
int any;
|
int any;
|
||||||
u_char *b, hole, most;
|
u_char *b, hole, most;
|
||||||
|
|
||||||
dev_printk(KERN_INFO, &s->dev, "cs: IO port probe %#x-%#x:",
|
dev_info(&s->dev, "cs: IO port probe %#x-%#x:", base, base+num-1);
|
||||||
base, base+num-1);
|
|
||||||
|
|
||||||
/* First, what does a floating port look like? */
|
/* First, what does a floating port look like? */
|
||||||
b = kzalloc(256, GFP_KERNEL);
|
b = kzalloc(256, GFP_KERNEL);
|
||||||
if (!b) {
|
if (!b) {
|
||||||
printk("\n");
|
pr_cont("\n");
|
||||||
dev_printk(KERN_ERR, &s->dev,
|
dev_err(&s->dev, "do_io_probe: unable to kmalloc 256 bytes\n");
|
||||||
"do_io_probe: unable to kmalloc 256 bytes");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (i = base, most = 0; i < base+num; i += 8) {
|
for (i = base, most = 0; i < base+num; i += 8) {
|
||||||
|
@ -223,7 +221,7 @@ static void do_io_probe(struct pcmcia_socket *s, unsigned int base,
|
||||||
res = claim_region(s, i, 8, IORESOURCE_IO, "PCMCIA ioprobe");
|
res = claim_region(s, i, 8, IORESOURCE_IO, "PCMCIA ioprobe");
|
||||||
if (!res) {
|
if (!res) {
|
||||||
if (!any)
|
if (!any)
|
||||||
printk(" excluding");
|
pr_cont(" excluding");
|
||||||
if (!bad)
|
if (!bad)
|
||||||
bad = any = i;
|
bad = any = i;
|
||||||
continue;
|
continue;
|
||||||
|
@ -234,13 +232,13 @@ static void do_io_probe(struct pcmcia_socket *s, unsigned int base,
|
||||||
free_region(res);
|
free_region(res);
|
||||||
if (j < 8) {
|
if (j < 8) {
|
||||||
if (!any)
|
if (!any)
|
||||||
printk(" excluding");
|
pr_cont(" excluding");
|
||||||
if (!bad)
|
if (!bad)
|
||||||
bad = any = i;
|
bad = any = i;
|
||||||
} else {
|
} else {
|
||||||
if (bad) {
|
if (bad) {
|
||||||
sub_interval(&s_data->io_db, bad, i-bad);
|
sub_interval(&s_data->io_db, bad, i-bad);
|
||||||
printk(" %#x-%#x", bad, i-1);
|
pr_cont(" %#x-%#x", bad, i-1);
|
||||||
bad = 0;
|
bad = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -248,15 +246,15 @@ static void do_io_probe(struct pcmcia_socket *s, unsigned int base,
|
||||||
if (bad) {
|
if (bad) {
|
||||||
if ((num > 16) && (bad == base) && (i == base+num)) {
|
if ((num > 16) && (bad == base) && (i == base+num)) {
|
||||||
sub_interval(&s_data->io_db, bad, i-bad);
|
sub_interval(&s_data->io_db, bad, i-bad);
|
||||||
printk(" nothing: probe failed.\n");
|
pr_cont(" nothing: probe failed.\n");
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
sub_interval(&s_data->io_db, bad, i-bad);
|
sub_interval(&s_data->io_db, bad, i-bad);
|
||||||
printk(" %#x-%#x", bad, i-1);
|
pr_cont(" %#x-%#x", bad, i-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
printk(any ? "\n" : " clean.\n");
|
pr_cont("%s\n", !any ? " clean" : "");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -413,7 +411,7 @@ static int do_mem_probe(struct pcmcia_socket *s, u_long base, u_long num,
|
||||||
struct socket_data *s_data = s->resource_data;
|
struct socket_data *s_data = s->resource_data;
|
||||||
u_long i, j, bad, fail, step;
|
u_long i, j, bad, fail, step;
|
||||||
|
|
||||||
dev_printk(KERN_INFO, &s->dev, "cs: memory probe 0x%06lx-0x%06lx:",
|
dev_info(&s->dev, "cs: memory probe 0x%06lx-0x%06lx:",
|
||||||
base, base+num-1);
|
base, base+num-1);
|
||||||
bad = fail = 0;
|
bad = fail = 0;
|
||||||
step = (num < 0x20000) ? 0x2000 : ((num>>4) & ~0x1fff);
|
step = (num < 0x20000) ? 0x2000 : ((num>>4) & ~0x1fff);
|
||||||
|
@ -438,13 +436,13 @@ static int do_mem_probe(struct pcmcia_socket *s, u_long base, u_long num,
|
||||||
}
|
}
|
||||||
if (i != j) {
|
if (i != j) {
|
||||||
if (!bad)
|
if (!bad)
|
||||||
printk(" excluding");
|
pr_cont(" excluding");
|
||||||
printk(" %#05lx-%#05lx", i, j-1);
|
pr_cont(" %#05lx-%#05lx", i, j-1);
|
||||||
sub_interval(&s_data->mem_db, i, j-i);
|
sub_interval(&s_data->mem_db, i, j-i);
|
||||||
bad += j-i;
|
bad += j-i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
printk(bad ? "\n" : " clean.\n");
|
pr_cont("%s\n", !bad ? " clean" : "");
|
||||||
return num - bad;
|
return num - bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -495,7 +493,7 @@ static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
|
||||||
return 0;
|
return 0;
|
||||||
if (s_data->mem_db_valid.next != &s_data->mem_db_valid)
|
if (s_data->mem_db_valid.next != &s_data->mem_db_valid)
|
||||||
return 0;
|
return 0;
|
||||||
dev_printk(KERN_NOTICE, &s->dev,
|
dev_notice(&s->dev,
|
||||||
"cs: warning: no high memory space available!\n");
|
"cs: warning: no high memory space available!\n");
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
@ -975,7 +973,7 @@ static int nonstatic_autoadd_resources(struct pcmcia_socket *s)
|
||||||
if (res == &ioport_resource)
|
if (res == &ioport_resource)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
dev_printk(KERN_INFO, &s->cb_dev->dev,
|
dev_info(&s->cb_dev->dev,
|
||||||
"pcmcia: parent PCI bridge window: %pR\n",
|
"pcmcia: parent PCI bridge window: %pR\n",
|
||||||
res);
|
res);
|
||||||
if (!adjust_io(s, ADD_MANAGED_RESOURCE, res->start, res->end))
|
if (!adjust_io(s, ADD_MANAGED_RESOURCE, res->start, res->end))
|
||||||
|
@ -990,7 +988,7 @@ static int nonstatic_autoadd_resources(struct pcmcia_socket *s)
|
||||||
if (res == &iomem_resource)
|
if (res == &iomem_resource)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
dev_printk(KERN_INFO, &s->cb_dev->dev,
|
dev_info(&s->cb_dev->dev,
|
||||||
"pcmcia: parent PCI bridge window: %pR\n",
|
"pcmcia: parent PCI bridge window: %pR\n",
|
||||||
res);
|
res);
|
||||||
if (!adjust_memory(s, ADD_MANAGED_RESOURCE, res->start, res->end))
|
if (!adjust_memory(s, ADD_MANAGED_RESOURCE, res->start, res->end))
|
||||||
|
|
|
@ -372,8 +372,8 @@ static void ti12xx_irqroute_func0(struct yenta_socket *socket)
|
||||||
|
|
||||||
mfunc = mfunc_old = config_readl(socket, TI122X_MFUNC);
|
mfunc = mfunc_old = config_readl(socket, TI122X_MFUNC);
|
||||||
devctl = config_readb(socket, TI113X_DEVICE_CONTROL);
|
devctl = config_readb(socket, TI113X_DEVICE_CONTROL);
|
||||||
dev_printk(KERN_INFO, &socket->dev->dev,
|
dev_info(&socket->dev->dev, "TI: mfunc 0x%08x, devctl 0x%02x\n",
|
||||||
"TI: mfunc 0x%08x, devctl 0x%02x\n", mfunc, devctl);
|
mfunc, devctl);
|
||||||
|
|
||||||
/* make sure PCI interrupts are enabled before probing */
|
/* make sure PCI interrupts are enabled before probing */
|
||||||
ti_init(socket);
|
ti_init(socket);
|
||||||
|
@ -387,7 +387,7 @@ static void ti12xx_irqroute_func0(struct yenta_socket *socket)
|
||||||
* We're here which means PCI interrupts are _not_ delivered. try to
|
* We're here which means PCI interrupts are _not_ delivered. try to
|
||||||
* find the right setting (all serial or parallel)
|
* find the right setting (all serial or parallel)
|
||||||
*/
|
*/
|
||||||
dev_printk(KERN_INFO, &socket->dev->dev,
|
dev_info(&socket->dev->dev,
|
||||||
"TI: probing PCI interrupt failed, trying to fix\n");
|
"TI: probing PCI interrupt failed, trying to fix\n");
|
||||||
|
|
||||||
/* for serial PCI make sure MFUNC3 is set to IRQSER */
|
/* for serial PCI make sure MFUNC3 is set to IRQSER */
|
||||||
|
@ -412,7 +412,7 @@ static void ti12xx_irqroute_func0(struct yenta_socket *socket)
|
||||||
|
|
||||||
pci_irq_status = yenta_probe_cb_irq(socket);
|
pci_irq_status = yenta_probe_cb_irq(socket);
|
||||||
if (pci_irq_status == 1) {
|
if (pci_irq_status == 1) {
|
||||||
dev_printk(KERN_INFO, &socket->dev->dev,
|
dev_info(&socket->dev->dev,
|
||||||
"TI: all-serial interrupts ok\n");
|
"TI: all-serial interrupts ok\n");
|
||||||
mfunc_old = mfunc;
|
mfunc_old = mfunc;
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -428,7 +428,7 @@ static void ti12xx_irqroute_func0(struct yenta_socket *socket)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* serial PCI interrupts not working fall back to parallel */
|
/* serial PCI interrupts not working fall back to parallel */
|
||||||
dev_printk(KERN_INFO, &socket->dev->dev,
|
dev_info(&socket->dev->dev,
|
||||||
"TI: falling back to parallel PCI interrupts\n");
|
"TI: falling back to parallel PCI interrupts\n");
|
||||||
devctl &= ~TI113X_DCR_IMODE_MASK;
|
devctl &= ~TI113X_DCR_IMODE_MASK;
|
||||||
devctl |= TI113X_DCR_IMODE_SERIAL; /* serial ISA could be right */
|
devctl |= TI113X_DCR_IMODE_SERIAL; /* serial ISA could be right */
|
||||||
|
@ -460,8 +460,7 @@ static void ti12xx_irqroute_func0(struct yenta_socket *socket)
|
||||||
pci_irq_status = yenta_probe_cb_irq(socket);
|
pci_irq_status = yenta_probe_cb_irq(socket);
|
||||||
if (pci_irq_status == 1) {
|
if (pci_irq_status == 1) {
|
||||||
mfunc_old = mfunc;
|
mfunc_old = mfunc;
|
||||||
dev_printk(KERN_INFO, &socket->dev->dev,
|
dev_info(&socket->dev->dev, "TI: parallel PCI interrupts ok\n");
|
||||||
"TI: parallel PCI interrupts ok\n");
|
|
||||||
} else {
|
} else {
|
||||||
/* not working, back to old value */
|
/* not working, back to old value */
|
||||||
mfunc = mfunc_old;
|
mfunc = mfunc_old;
|
||||||
|
@ -473,9 +472,8 @@ static void ti12xx_irqroute_func0(struct yenta_socket *socket)
|
||||||
out:
|
out:
|
||||||
if (pci_irq_status < 1) {
|
if (pci_irq_status < 1) {
|
||||||
socket->cb_irq = 0;
|
socket->cb_irq = 0;
|
||||||
dev_printk(KERN_INFO, &socket->dev->dev,
|
dev_info(&socket->dev->dev,
|
||||||
"Yenta TI: no PCI interrupts. Fish. "
|
"Yenta TI: no PCI interrupts. Fish. Please report.\n");
|
||||||
"Please report.\n");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -547,8 +545,7 @@ static void ti12xx_irqroute_func1(struct yenta_socket *socket)
|
||||||
|
|
||||||
mfunc = mfunc_old = config_readl(socket, TI122X_MFUNC);
|
mfunc = mfunc_old = config_readl(socket, TI122X_MFUNC);
|
||||||
devctl = config_readb(socket, TI113X_DEVICE_CONTROL);
|
devctl = config_readb(socket, TI113X_DEVICE_CONTROL);
|
||||||
dev_printk(KERN_INFO, &socket->dev->dev,
|
dev_info(&socket->dev->dev, "TI: mfunc 0x%08x, devctl 0x%02x\n",
|
||||||
"TI: mfunc 0x%08x, devctl 0x%02x\n",
|
|
||||||
mfunc, devctl);
|
mfunc, devctl);
|
||||||
|
|
||||||
/* if IRQs are configured as tied, align irq of func1 with func0 */
|
/* if IRQs are configured as tied, align irq of func1 with func0 */
|
||||||
|
@ -568,7 +565,7 @@ static void ti12xx_irqroute_func1(struct yenta_socket *socket)
|
||||||
* We're here which means PCI interrupts are _not_ delivered. try to
|
* We're here which means PCI interrupts are _not_ delivered. try to
|
||||||
* find the right setting
|
* find the right setting
|
||||||
*/
|
*/
|
||||||
dev_printk(KERN_INFO, &socket->dev->dev,
|
dev_info(&socket->dev->dev,
|
||||||
"TI: probing PCI interrupt failed, trying to fix\n");
|
"TI: probing PCI interrupt failed, trying to fix\n");
|
||||||
|
|
||||||
/* if all serial: set INTRTIE, probe again */
|
/* if all serial: set INTRTIE, probe again */
|
||||||
|
@ -578,7 +575,7 @@ static void ti12xx_irqroute_func1(struct yenta_socket *socket)
|
||||||
if (ti12xx_tie_interrupts(socket, &old_irq)) {
|
if (ti12xx_tie_interrupts(socket, &old_irq)) {
|
||||||
pci_irq_status = yenta_probe_cb_irq(socket);
|
pci_irq_status = yenta_probe_cb_irq(socket);
|
||||||
if (pci_irq_status == 1) {
|
if (pci_irq_status == 1) {
|
||||||
dev_printk(KERN_INFO, &socket->dev->dev,
|
dev_info(&socket->dev->dev,
|
||||||
"TI: all-serial interrupts, tied ok\n");
|
"TI: all-serial interrupts, tied ok\n");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -616,7 +613,7 @@ static void ti12xx_irqroute_func1(struct yenta_socket *socket)
|
||||||
|
|
||||||
pci_irq_status = yenta_probe_cb_irq(socket);
|
pci_irq_status = yenta_probe_cb_irq(socket);
|
||||||
if (pci_irq_status == 1) {
|
if (pci_irq_status == 1) {
|
||||||
dev_printk(KERN_INFO, &socket->dev->dev,
|
dev_info(&socket->dev->dev,
|
||||||
"TI: parallel PCI interrupts ok\n");
|
"TI: parallel PCI interrupts ok\n");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -632,7 +629,7 @@ static void ti12xx_irqroute_func1(struct yenta_socket *socket)
|
||||||
if (ti12xx_tie_interrupts(socket, &old_irq)) {
|
if (ti12xx_tie_interrupts(socket, &old_irq)) {
|
||||||
pci_irq_status = yenta_probe_cb_irq(socket);
|
pci_irq_status = yenta_probe_cb_irq(socket);
|
||||||
if (pci_irq_status == 1) {
|
if (pci_irq_status == 1) {
|
||||||
dev_printk(KERN_INFO, &socket->dev->dev,
|
dev_info(&socket->dev->dev,
|
||||||
"TI: parallel PCI interrupts, tied ok\n");
|
"TI: parallel PCI interrupts, tied ok\n");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -644,7 +641,7 @@ static void ti12xx_irqroute_func1(struct yenta_socket *socket)
|
||||||
out:
|
out:
|
||||||
if (pci_irq_status < 1) {
|
if (pci_irq_status < 1) {
|
||||||
socket->cb_irq = 0;
|
socket->cb_irq = 0;
|
||||||
dev_printk(KERN_INFO, &socket->dev->dev,
|
dev_info(&socket->dev->dev,
|
||||||
"TI: no PCI interrupts. Fish. Please report.\n");
|
"TI: no PCI interrupts. Fish. Please report.\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -849,12 +846,11 @@ static int ti12xx_override(struct yenta_socket *socket)
|
||||||
/* make sure that memory burst is active */
|
/* make sure that memory burst is active */
|
||||||
val_orig = val = config_readl(socket, TI113X_SYSTEM_CONTROL);
|
val_orig = val = config_readl(socket, TI113X_SYSTEM_CONTROL);
|
||||||
if (disable_clkrun && PCI_FUNC(socket->dev->devfn) == 0) {
|
if (disable_clkrun && PCI_FUNC(socket->dev->devfn) == 0) {
|
||||||
dev_printk(KERN_INFO, &socket->dev->dev,
|
dev_info(&socket->dev->dev, "Disabling CLKRUN feature\n");
|
||||||
"Disabling CLKRUN feature\n");
|
|
||||||
val |= TI113X_SCR_KEEPCLK;
|
val |= TI113X_SCR_KEEPCLK;
|
||||||
}
|
}
|
||||||
if (!(val & TI122X_SCR_MRBURSTUP)) {
|
if (!(val & TI122X_SCR_MRBURSTUP)) {
|
||||||
dev_printk(KERN_INFO, &socket->dev->dev,
|
dev_info(&socket->dev->dev,
|
||||||
"Enabling burst memory read transactions\n");
|
"Enabling burst memory read transactions\n");
|
||||||
val |= TI122X_SCR_MRBURSTUP;
|
val |= TI122X_SCR_MRBURSTUP;
|
||||||
}
|
}
|
||||||
|
@ -866,11 +862,9 @@ static int ti12xx_override(struct yenta_socket *socket)
|
||||||
* CSC interrupts to PCI rather than INTVAL.
|
* CSC interrupts to PCI rather than INTVAL.
|
||||||
*/
|
*/
|
||||||
val = config_readb(socket, TI1250_DIAGNOSTIC);
|
val = config_readb(socket, TI1250_DIAGNOSTIC);
|
||||||
dev_printk(KERN_INFO, &socket->dev->dev,
|
dev_info(&socket->dev->dev, "Using %s to route CSC interrupts to PCI\n",
|
||||||
"Using %s to route CSC interrupts to PCI\n",
|
|
||||||
(val & TI1250_DIAG_PCI_CSC) ? "CSCINT" : "INTVAL");
|
(val & TI1250_DIAG_PCI_CSC) ? "CSCINT" : "INTVAL");
|
||||||
dev_printk(KERN_INFO, &socket->dev->dev,
|
dev_info(&socket->dev->dev, "Routing CardBus interrupts to %s\n",
|
||||||
"Routing CardBus interrupts to %s\n",
|
|
||||||
(val & TI1250_DIAG_PCI_IREQ) ? "PCI" : "ISA");
|
(val & TI1250_DIAG_PCI_IREQ) ? "PCI" : "ISA");
|
||||||
|
|
||||||
/* do irqrouting, depending on function */
|
/* do irqrouting, depending on function */
|
||||||
|
@ -896,7 +890,7 @@ static int ti1250_override(struct yenta_socket *socket)
|
||||||
diag |= TI1250_DIAG_PCI_CSC | TI1250_DIAG_PCI_IREQ;
|
diag |= TI1250_DIAG_PCI_CSC | TI1250_DIAG_PCI_IREQ;
|
||||||
|
|
||||||
if (diag != old) {
|
if (diag != old) {
|
||||||
dev_printk(KERN_INFO, &socket->dev->dev,
|
dev_info(&socket->dev->dev,
|
||||||
"adjusting diagnostic: %02x -> %02x\n",
|
"adjusting diagnostic: %02x -> %02x\n",
|
||||||
old, diag);
|
old, diag);
|
||||||
config_writeb(socket, TI1250_DIAGNOSTIC, diag);
|
config_writeb(socket, TI1250_DIAGNOSTIC, diag);
|
||||||
|
@ -963,8 +957,8 @@ static void ene_tune_bridge(struct pcmcia_socket *sock, struct pci_bus *bus)
|
||||||
/* default to clear TLTEnable bit, old behaviour */
|
/* default to clear TLTEnable bit, old behaviour */
|
||||||
test_c9 &= ~ENE_TEST_C9_TLTENABLE;
|
test_c9 &= ~ENE_TEST_C9_TLTENABLE;
|
||||||
|
|
||||||
dev_printk(KERN_INFO, &socket->dev->dev,
|
dev_info(&socket->dev->dev,
|
||||||
"EnE: chaning testregister 0xC9, %02x -> %02x\n",
|
"EnE: changing testregister 0xC9, %02x -> %02x\n",
|
||||||
old_c9, test_c9);
|
old_c9, test_c9);
|
||||||
config_writeb(socket, ENE_TEST_C9, test_c9);
|
config_writeb(socket, ENE_TEST_C9, test_c9);
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,6 +104,9 @@
|
||||||
#define TOPIC_EXCA_IF_CONTROL 0x3e /* 8 bit */
|
#define TOPIC_EXCA_IF_CONTROL 0x3e /* 8 bit */
|
||||||
#define TOPIC_EXCA_IFC_33V_ENA 0x01
|
#define TOPIC_EXCA_IFC_33V_ENA 0x01
|
||||||
|
|
||||||
|
#define TOPIC_PCI_CFG_PPBCN 0x3e /* 16-bit */
|
||||||
|
#define TOPIC_PCI_CFG_PPBCN_WBEN 0x0400
|
||||||
|
|
||||||
static void topic97_zoom_video(struct pcmcia_socket *sock, int onoff)
|
static void topic97_zoom_video(struct pcmcia_socket *sock, int onoff)
|
||||||
{
|
{
|
||||||
struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
|
struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
|
||||||
|
@ -138,6 +141,7 @@ static int topic97_override(struct yenta_socket *socket)
|
||||||
static int topic95_override(struct yenta_socket *socket)
|
static int topic95_override(struct yenta_socket *socket)
|
||||||
{
|
{
|
||||||
u8 fctrl;
|
u8 fctrl;
|
||||||
|
u16 ppbcn;
|
||||||
|
|
||||||
/* enable 3.3V support for 16bit cards */
|
/* enable 3.3V support for 16bit cards */
|
||||||
fctrl = exca_readb(socket, TOPIC_EXCA_IF_CONTROL);
|
fctrl = exca_readb(socket, TOPIC_EXCA_IF_CONTROL);
|
||||||
|
@ -146,6 +150,18 @@ static int topic95_override(struct yenta_socket *socket)
|
||||||
/* tell yenta to use exca registers to power 16bit cards */
|
/* tell yenta to use exca registers to power 16bit cards */
|
||||||
socket->flags |= YENTA_16BIT_POWER_EXCA | YENTA_16BIT_POWER_DF;
|
socket->flags |= YENTA_16BIT_POWER_EXCA | YENTA_16BIT_POWER_DF;
|
||||||
|
|
||||||
|
/* Disable write buffers to prevent lockups under load with numerous
|
||||||
|
Cardbus cards, observed on Tecra 500CDT and reported elsewhere on the
|
||||||
|
net. This is not a power-on default according to the datasheet
|
||||||
|
but some BIOSes seem to set it. */
|
||||||
|
if (pci_read_config_word(socket->dev, TOPIC_PCI_CFG_PPBCN, &ppbcn) == 0
|
||||||
|
&& socket->dev->revision <= 7
|
||||||
|
&& (ppbcn & TOPIC_PCI_CFG_PPBCN_WBEN)) {
|
||||||
|
ppbcn &= ~TOPIC_PCI_CFG_PPBCN_WBEN;
|
||||||
|
pci_write_config_word(socket->dev, TOPIC_PCI_CFG_PPBCN, ppbcn);
|
||||||
|
dev_info(&socket->dev->dev, "Disabled ToPIC95 Cardbus write buffers.\n");
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -84,32 +84,32 @@ MODULE_LICENSE("GPL");
|
||||||
#define IO_MAX_MAPS 2
|
#define IO_MAX_MAPS 2
|
||||||
#define MEM_MAX_MAPS 5
|
#define MEM_MAX_MAPS 5
|
||||||
|
|
||||||
typedef enum {
|
enum vrc4171_slot {
|
||||||
SLOT_PROBE = 0,
|
SLOT_PROBE = 0,
|
||||||
SLOT_NOPROBE_IO,
|
SLOT_NOPROBE_IO,
|
||||||
SLOT_NOPROBE_MEM,
|
SLOT_NOPROBE_MEM,
|
||||||
SLOT_NOPROBE_ALL,
|
SLOT_NOPROBE_ALL,
|
||||||
SLOT_INITIALIZED,
|
SLOT_INITIALIZED,
|
||||||
} vrc4171_slot_t;
|
};
|
||||||
|
|
||||||
typedef enum {
|
enum vrc4171_slotb {
|
||||||
SLOTB_IS_NONE,
|
SLOTB_IS_NONE,
|
||||||
SLOTB_IS_PCCARD,
|
SLOTB_IS_PCCARD,
|
||||||
SLOTB_IS_CF,
|
SLOTB_IS_CF,
|
||||||
SLOTB_IS_FLASHROM,
|
SLOTB_IS_FLASHROM,
|
||||||
} vrc4171_slotb_t;
|
};
|
||||||
|
|
||||||
typedef struct vrc4171_socket {
|
struct vrc4171_socket {
|
||||||
vrc4171_slot_t slot;
|
enum vrc4171_slot slot;
|
||||||
struct pcmcia_socket pcmcia_socket;
|
struct pcmcia_socket pcmcia_socket;
|
||||||
char name[24];
|
char name[24];
|
||||||
int csc_irq;
|
int csc_irq;
|
||||||
int io_irq;
|
int io_irq;
|
||||||
spinlock_t lock;
|
spinlock_t lock;
|
||||||
} vrc4171_socket_t;
|
};
|
||||||
|
|
||||||
static vrc4171_socket_t vrc4171_sockets[CARD_MAX_SLOTS];
|
static struct vrc4171_socket vrc4171_sockets[CARD_MAX_SLOTS];
|
||||||
static vrc4171_slotb_t vrc4171_slotb = SLOTB_IS_NONE;
|
static enum vrc4171_slotb vrc4171_slotb = SLOTB_IS_NONE;
|
||||||
static char vrc4171_card_name[] = "NEC VRC4171 Card Controller";
|
static char vrc4171_card_name[] = "NEC VRC4171 Card Controller";
|
||||||
static unsigned int vrc4171_irq;
|
static unsigned int vrc4171_irq;
|
||||||
static uint16_t vrc4171_irq_mask = 0xdeb8;
|
static uint16_t vrc4171_irq_mask = 0xdeb8;
|
||||||
|
@ -141,7 +141,7 @@ static inline uint16_t vrc4171_get_irq_status(void)
|
||||||
return inw(INTERRUPT_STATUS);
|
return inw(INTERRUPT_STATUS);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void vrc4171_set_multifunction_pin(vrc4171_slotb_t config)
|
static inline void vrc4171_set_multifunction_pin(enum vrc4171_slotb config)
|
||||||
{
|
{
|
||||||
uint16_t config1;
|
uint16_t config1;
|
||||||
|
|
||||||
|
@ -234,7 +234,7 @@ static inline int search_nonuse_irq(void)
|
||||||
|
|
||||||
static int pccard_init(struct pcmcia_socket *sock)
|
static int pccard_init(struct pcmcia_socket *sock)
|
||||||
{
|
{
|
||||||
vrc4171_socket_t *socket;
|
struct vrc4171_socket *socket;
|
||||||
unsigned int slot;
|
unsigned int slot;
|
||||||
|
|
||||||
sock->features |= SS_CAP_PCCARD | SS_CAP_PAGE_REGS;
|
sock->features |= SS_CAP_PCCARD | SS_CAP_PAGE_REGS;
|
||||||
|
@ -317,7 +317,7 @@ static inline uint8_t set_Vcc_value(u_char Vcc)
|
||||||
|
|
||||||
static int pccard_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
|
static int pccard_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
|
||||||
{
|
{
|
||||||
vrc4171_socket_t *socket;
|
struct vrc4171_socket *socket;
|
||||||
unsigned int slot;
|
unsigned int slot;
|
||||||
uint8_t voltage, power, control, cscint;
|
uint8_t voltage, power, control, cscint;
|
||||||
|
|
||||||
|
@ -517,7 +517,7 @@ static inline unsigned int get_events(int slot)
|
||||||
|
|
||||||
static irqreturn_t pccard_interrupt(int irq, void *dev_id)
|
static irqreturn_t pccard_interrupt(int irq, void *dev_id)
|
||||||
{
|
{
|
||||||
vrc4171_socket_t *socket;
|
struct vrc4171_socket *socket;
|
||||||
unsigned int events;
|
unsigned int events;
|
||||||
irqreturn_t retval = IRQ_NONE;
|
irqreturn_t retval = IRQ_NONE;
|
||||||
uint16_t status;
|
uint16_t status;
|
||||||
|
@ -567,7 +567,7 @@ static inline void reserve_using_irq(int slot)
|
||||||
|
|
||||||
static int vrc4171_add_sockets(void)
|
static int vrc4171_add_sockets(void)
|
||||||
{
|
{
|
||||||
vrc4171_socket_t *socket;
|
struct vrc4171_socket *socket;
|
||||||
int slot, retval;
|
int slot, retval;
|
||||||
|
|
||||||
for (slot = 0; slot < CARD_MAX_SLOTS; slot++) {
|
for (slot = 0; slot < CARD_MAX_SLOTS; slot++) {
|
||||||
|
@ -617,7 +617,7 @@ static int vrc4171_add_sockets(void)
|
||||||
|
|
||||||
static void vrc4171_remove_sockets(void)
|
static void vrc4171_remove_sockets(void)
|
||||||
{
|
{
|
||||||
vrc4171_socket_t *socket;
|
struct vrc4171_socket *socket;
|
||||||
int slot;
|
int slot;
|
||||||
|
|
||||||
for (slot = 0; slot < CARD_MAX_SLOTS; slot++) {
|
for (slot = 0; slot < CARD_MAX_SLOTS; slot++) {
|
||||||
|
|
|
@ -712,9 +712,8 @@ static int yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned type
|
||||||
pcibios_bus_to_resource(dev->bus, res, ®ion);
|
pcibios_bus_to_resource(dev->bus, res, ®ion);
|
||||||
if (pci_claim_resource(dev, PCI_BRIDGE_RESOURCES + nr) == 0)
|
if (pci_claim_resource(dev, PCI_BRIDGE_RESOURCES + nr) == 0)
|
||||||
return 0;
|
return 0;
|
||||||
dev_printk(KERN_INFO, &dev->dev,
|
dev_info(&dev->dev,
|
||||||
"Preassigned resource %d busy or not available, "
|
"Preassigned resource %d busy or not available, reconfiguring...\n",
|
||||||
"reconfiguring...\n",
|
|
||||||
nr);
|
nr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -738,7 +737,7 @@ static int yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned type
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
dev_printk(KERN_INFO, &dev->dev,
|
dev_info(&dev->dev,
|
||||||
"no resource of type %x available, trying to continue...\n",
|
"no resource of type %x available, trying to continue...\n",
|
||||||
type);
|
type);
|
||||||
res->start = res->end = res->flags = 0;
|
res->start = res->end = res->flags = 0;
|
||||||
|
@ -802,13 +801,13 @@ static void yenta_close(struct pci_dev *dev)
|
||||||
else
|
else
|
||||||
del_timer_sync(&sock->poll_timer);
|
del_timer_sync(&sock->poll_timer);
|
||||||
|
|
||||||
if (sock->base)
|
|
||||||
iounmap(sock->base);
|
iounmap(sock->base);
|
||||||
yenta_free_resources(sock);
|
yenta_free_resources(sock);
|
||||||
|
|
||||||
pci_release_regions(dev);
|
pci_release_regions(dev);
|
||||||
pci_disable_device(dev);
|
pci_disable_device(dev);
|
||||||
pci_set_drvdata(dev, NULL);
|
pci_set_drvdata(dev, NULL);
|
||||||
|
kfree(sock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -979,7 +978,7 @@ static int yenta_probe_cb_irq(struct yenta_socket *socket)
|
||||||
socket->probe_status = 0;
|
socket->probe_status = 0;
|
||||||
|
|
||||||
if (request_irq(socket->cb_irq, yenta_probe_handler, IRQF_SHARED, "yenta", socket)) {
|
if (request_irq(socket->cb_irq, yenta_probe_handler, IRQF_SHARED, "yenta", socket)) {
|
||||||
dev_printk(KERN_WARNING, &socket->dev->dev,
|
dev_warn(&socket->dev->dev,
|
||||||
"request_irq() in yenta_probe_cb_irq() failed!\n");
|
"request_irq() in yenta_probe_cb_irq() failed!\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -1019,8 +1018,7 @@ static void yenta_get_socket_capabilities(struct yenta_socket *socket, u32 isa_i
|
||||||
else
|
else
|
||||||
socket->socket.irq_mask = 0;
|
socket->socket.irq_mask = 0;
|
||||||
|
|
||||||
dev_printk(KERN_INFO, &socket->dev->dev,
|
dev_info(&socket->dev->dev, "ISA IRQ mask 0x%04x, PCI irq %d\n",
|
||||||
"ISA IRQ mask 0x%04x, PCI irq %d\n",
|
|
||||||
socket->socket.irq_mask, socket->cb_irq);
|
socket->socket.irq_mask, socket->cb_irq);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1111,9 +1109,9 @@ static void yenta_fixup_parent_bridge(struct pci_bus *cardbus_bridge)
|
||||||
|
|
||||||
/* Show that the wanted subordinate number is not possible: */
|
/* Show that the wanted subordinate number is not possible: */
|
||||||
if (cardbus_bridge->busn_res.end > upper_limit)
|
if (cardbus_bridge->busn_res.end > upper_limit)
|
||||||
dev_printk(KERN_WARNING, &cardbus_bridge->dev,
|
dev_warn(&cardbus_bridge->dev,
|
||||||
"Upper limit for fixing this "
|
"Upper limit for fixing this bridge's parent bridge: #%02x\n",
|
||||||
"bridge's parent bridge: #%02x\n", upper_limit);
|
upper_limit);
|
||||||
|
|
||||||
/* If we have room to increase the bridge's subordinate number, */
|
/* If we have room to increase the bridge's subordinate number, */
|
||||||
if (bridge_to_fix->busn_res.end < upper_limit) {
|
if (bridge_to_fix->busn_res.end < upper_limit) {
|
||||||
|
@ -1122,11 +1120,11 @@ static void yenta_fixup_parent_bridge(struct pci_bus *cardbus_bridge)
|
||||||
unsigned char subordinate_to_assign =
|
unsigned char subordinate_to_assign =
|
||||||
min_t(int, cardbus_bridge->busn_res.end, upper_limit);
|
min_t(int, cardbus_bridge->busn_res.end, upper_limit);
|
||||||
|
|
||||||
dev_printk(KERN_INFO, &bridge_to_fix->dev,
|
dev_info(&bridge_to_fix->dev,
|
||||||
"Raising subordinate bus# of parent "
|
"Raising subordinate bus# of parent bus (#%02x) from #%02x to #%02x\n",
|
||||||
"bus (#%02x) from #%02x to #%02x\n",
|
|
||||||
bridge_to_fix->number,
|
bridge_to_fix->number,
|
||||||
(int)bridge_to_fix->busn_res.end, subordinate_to_assign);
|
(int)bridge_to_fix->busn_res.end,
|
||||||
|
subordinate_to_assign);
|
||||||
|
|
||||||
/* Save the new subordinate in the bus struct of the bridge */
|
/* Save the new subordinate in the bus struct of the bridge */
|
||||||
bridge_to_fix->busn_res.end = subordinate_to_assign;
|
bridge_to_fix->busn_res.end = subordinate_to_assign;
|
||||||
|
@ -1153,8 +1151,7 @@ static int yenta_probe(struct pci_dev *dev, const struct pci_device_id *id)
|
||||||
* Bail out if so.
|
* Bail out if so.
|
||||||
*/
|
*/
|
||||||
if (!dev->subordinate) {
|
if (!dev->subordinate) {
|
||||||
dev_printk(KERN_ERR, &dev->dev, "no bus associated! "
|
dev_err(&dev->dev, "no bus associated! (try 'pci=assign-busses')\n");
|
||||||
"(try 'pci=assign-busses')\n");
|
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1189,7 +1186,7 @@ static int yenta_probe(struct pci_dev *dev, const struct pci_device_id *id)
|
||||||
goto disable;
|
goto disable;
|
||||||
|
|
||||||
if (!pci_resource_start(dev, 0)) {
|
if (!pci_resource_start(dev, 0)) {
|
||||||
dev_printk(KERN_ERR, &dev->dev, "No cardbus resource!\n");
|
dev_err(&dev->dev, "No cardbus resource!\n");
|
||||||
ret = -ENODEV;
|
ret = -ENODEV;
|
||||||
goto release;
|
goto release;
|
||||||
}
|
}
|
||||||
|
@ -1208,7 +1205,7 @@ static int yenta_probe(struct pci_dev *dev, const struct pci_device_id *id)
|
||||||
* report the subsystem vendor and device for help debugging
|
* report the subsystem vendor and device for help debugging
|
||||||
* the irq stuff...
|
* the irq stuff...
|
||||||
*/
|
*/
|
||||||
dev_printk(KERN_INFO, &dev->dev, "CardBus bridge found [%04x:%04x]\n",
|
dev_info(&dev->dev, "CardBus bridge found [%04x:%04x]\n",
|
||||||
dev->subsystem_vendor, dev->subsystem_device);
|
dev->subsystem_vendor, dev->subsystem_device);
|
||||||
|
|
||||||
yenta_config_init(socket);
|
yenta_config_init(socket);
|
||||||
|
@ -1239,12 +1236,10 @@ static int yenta_probe(struct pci_dev *dev, const struct pci_device_id *id)
|
||||||
setup_timer(&socket->poll_timer, yenta_interrupt_wrapper,
|
setup_timer(&socket->poll_timer, yenta_interrupt_wrapper,
|
||||||
(unsigned long)socket);
|
(unsigned long)socket);
|
||||||
mod_timer(&socket->poll_timer, jiffies + HZ);
|
mod_timer(&socket->poll_timer, jiffies + HZ);
|
||||||
dev_printk(KERN_INFO, &dev->dev,
|
dev_info(&dev->dev,
|
||||||
"no PCI IRQ, CardBus support disabled for this "
|
"no PCI IRQ, CardBus support disabled for this socket.\n");
|
||||||
"socket.\n");
|
dev_info(&dev->dev,
|
||||||
dev_printk(KERN_INFO, &dev->dev,
|
"check your BIOS CardBus, BIOS IRQ or ACPI settings.\n");
|
||||||
"check your BIOS CardBus, BIOS IRQ or ACPI "
|
|
||||||
"settings.\n");
|
|
||||||
} else {
|
} else {
|
||||||
socket->socket.features |= SS_CAP_CARDBUS;
|
socket->socket.features |= SS_CAP_CARDBUS;
|
||||||
}
|
}
|
||||||
|
@ -1252,32 +1247,41 @@ static int yenta_probe(struct pci_dev *dev, const struct pci_device_id *id)
|
||||||
/* Figure out what the dang thing can do for the PCMCIA layer... */
|
/* Figure out what the dang thing can do for the PCMCIA layer... */
|
||||||
yenta_interrogate(socket);
|
yenta_interrogate(socket);
|
||||||
yenta_get_socket_capabilities(socket, isa_interrupts);
|
yenta_get_socket_capabilities(socket, isa_interrupts);
|
||||||
dev_printk(KERN_INFO, &dev->dev,
|
dev_info(&dev->dev, "Socket status: %08x\n",
|
||||||
"Socket status: %08x\n", cb_readl(socket, CB_SOCKET_STATE));
|
cb_readl(socket, CB_SOCKET_STATE));
|
||||||
|
|
||||||
yenta_fixup_parent_bridge(dev->subordinate);
|
yenta_fixup_parent_bridge(dev->subordinate);
|
||||||
|
|
||||||
/* Register it with the pcmcia layer.. */
|
/* Register it with the pcmcia layer.. */
|
||||||
ret = pcmcia_register_socket(&socket->socket);
|
ret = pcmcia_register_socket(&socket->socket);
|
||||||
if (ret == 0) {
|
if (ret)
|
||||||
|
goto free_irq;
|
||||||
|
|
||||||
/* Add the yenta register attributes */
|
/* Add the yenta register attributes */
|
||||||
ret = device_create_file(&dev->dev, &dev_attr_yenta_registers);
|
ret = device_create_file(&dev->dev, &dev_attr_yenta_registers);
|
||||||
if (ret == 0)
|
if (ret)
|
||||||
goto out;
|
goto unregister_socket;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
|
||||||
/* error path... */
|
/* error path... */
|
||||||
|
unregister_socket:
|
||||||
pcmcia_unregister_socket(&socket->socket);
|
pcmcia_unregister_socket(&socket->socket);
|
||||||
}
|
free_irq:
|
||||||
|
if (socket->cb_irq)
|
||||||
|
free_irq(socket->cb_irq, socket);
|
||||||
|
else
|
||||||
|
del_timer_sync(&socket->poll_timer);
|
||||||
unmap:
|
unmap:
|
||||||
iounmap(socket->base);
|
iounmap(socket->base);
|
||||||
|
yenta_free_resources(socket);
|
||||||
release:
|
release:
|
||||||
pci_release_regions(dev);
|
pci_release_regions(dev);
|
||||||
disable:
|
disable:
|
||||||
pci_disable_device(dev);
|
pci_disable_device(dev);
|
||||||
free:
|
free:
|
||||||
|
pci_set_drvdata(dev, NULL);
|
||||||
kfree(socket);
|
kfree(socket);
|
||||||
out:
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue