mirror of
https://github.com/FEX-Emu/linux.git
synced 2024-12-14 21:01:29 +00:00
pcmcia: split up modify_configuration() into two fixup functions
pcmcia_modify_configuration() was only used by two drivers to fix up one issue each: setting the Vpp to a different value, and reducing the IO width to 8 bit. Introduce two explicitly named functions handling these things, and remove one further typedef. CC: netdev@vger.kernel.org CC: linux-mtd@lists.infradead.org Tested-by: Wolfram Sang <w.sang@pengutronix.de> Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
This commit is contained in:
parent
cdb138080b
commit
fb49fa533f
@ -316,15 +316,9 @@ static void pcmciamtd_set_vpp(struct map_info *map, int on)
|
|||||||
{
|
{
|
||||||
struct pcmciamtd_dev *dev = (struct pcmciamtd_dev *)map->map_priv_1;
|
struct pcmciamtd_dev *dev = (struct pcmciamtd_dev *)map->map_priv_1;
|
||||||
struct pcmcia_device *link = dev->p_dev;
|
struct pcmcia_device *link = dev->p_dev;
|
||||||
modconf_t mod;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
mod.Attributes = CONF_VPP1_CHANGE_VALID | CONF_VPP2_CHANGE_VALID;
|
|
||||||
mod.Vcc = 0;
|
|
||||||
mod.Vpp1 = mod.Vpp2 = on ? dev->vpp : 0;
|
|
||||||
|
|
||||||
DEBUG(2, "dev = %p on = %d vpp = %d\n", dev, on, dev->vpp);
|
DEBUG(2, "dev = %p on = %d vpp = %d\n", dev, on, dev->vpp);
|
||||||
ret = pcmcia_modify_configuration(link, &mod);
|
pcmcia_fixup_vpp(link, on ? dev->vpp : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -816,13 +816,10 @@ static int check_sig(struct pcmcia_device *link)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (width) {
|
if (width) {
|
||||||
modconf_t mod = {
|
|
||||||
.Attributes = CONF_IO_CHANGE_WIDTH,
|
|
||||||
};
|
|
||||||
printk(KERN_INFO "smc91c92_cs: using 8-bit IO window.\n");
|
printk(KERN_INFO "smc91c92_cs: using 8-bit IO window.\n");
|
||||||
|
|
||||||
smc91c92_suspend(link);
|
smc91c92_suspend(link);
|
||||||
pcmcia_modify_configuration(link, &mod);
|
pcmcia_fixup_iowidth(link);
|
||||||
smc91c92_resume(link);
|
smc91c92_resume(link);
|
||||||
return check_sig(link);
|
return check_sig(link);
|
||||||
}
|
}
|
||||||
|
@ -226,69 +226,31 @@ int pcmcia_map_mem_page(struct pcmcia_device *p_dev, struct resource *res,
|
|||||||
EXPORT_SYMBOL(pcmcia_map_mem_page);
|
EXPORT_SYMBOL(pcmcia_map_mem_page);
|
||||||
|
|
||||||
|
|
||||||
/** pcmcia_modify_configuration
|
/**
|
||||||
|
* pcmcia_fixup_iowidth() - reduce io width to 8bit
|
||||||
*
|
*
|
||||||
* Modify a locked socket configuration
|
* pcmcia_fixup_iowidth() allows a PCMCIA device driver to reduce the
|
||||||
|
* IO width to 8bit after having called pcmcia_request_configuration()
|
||||||
|
* previously.
|
||||||
*/
|
*/
|
||||||
int pcmcia_modify_configuration(struct pcmcia_device *p_dev,
|
int pcmcia_fixup_iowidth(struct pcmcia_device *p_dev)
|
||||||
modconf_t *mod)
|
|
||||||
{
|
{
|
||||||
struct pcmcia_socket *s;
|
struct pcmcia_socket *s = p_dev->socket;
|
||||||
config_t *c;
|
pccard_io_map io_off = { 0, 0, 0, 0, 1 };
|
||||||
int ret;
|
pccard_io_map io_on;
|
||||||
|
int i, ret = 0;
|
||||||
s = p_dev->socket;
|
|
||||||
|
|
||||||
mutex_lock(&s->ops_mutex);
|
mutex_lock(&s->ops_mutex);
|
||||||
c = p_dev->function_config;
|
|
||||||
|
|
||||||
if (!(s->state & SOCKET_PRESENT)) {
|
dev_dbg(&p_dev->dev, "fixup iowidth to 8bit\n");
|
||||||
dev_dbg(&p_dev->dev, "No card present\n");
|
|
||||||
ret = -ENODEV;
|
if (!(s->state & SOCKET_PRESENT) ||
|
||||||
goto unlock;
|
!(p_dev->function_config->state & CONFIG_LOCKED)) {
|
||||||
}
|
dev_dbg(&p_dev->dev, "No card? Config not locked?\n");
|
||||||
if (!(c->state & CONFIG_LOCKED)) {
|
|
||||||
dev_dbg(&p_dev->dev, "Configuration isnt't locked\n");
|
|
||||||
ret = -EACCES;
|
ret = -EACCES;
|
||||||
goto unlock;
|
goto unlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mod->Attributes & (CONF_IRQ_CHANGE_VALID | CONF_VCC_CHANGE_VALID)) {
|
|
||||||
dev_dbg(&p_dev->dev,
|
|
||||||
"changing Vcc or IRQ is not allowed at this time\n");
|
|
||||||
ret = -EINVAL;
|
|
||||||
goto unlock;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We only allow changing Vpp1 and Vpp2 to the same value */
|
|
||||||
if ((mod->Attributes & CONF_VPP1_CHANGE_VALID) &&
|
|
||||||
(mod->Attributes & CONF_VPP2_CHANGE_VALID)) {
|
|
||||||
if (mod->Vpp1 != mod->Vpp2) {
|
|
||||||
dev_dbg(&p_dev->dev,
|
|
||||||
"Vpp1 and Vpp2 must be the same\n");
|
|
||||||
ret = -EINVAL;
|
|
||||||
goto unlock;
|
|
||||||
}
|
|
||||||
s->socket.Vpp = mod->Vpp1;
|
|
||||||
if (s->ops->set_socket(s, &s->socket)) {
|
|
||||||
dev_printk(KERN_WARNING, &p_dev->dev,
|
|
||||||
"Unable to set VPP\n");
|
|
||||||
ret = -EIO;
|
|
||||||
goto unlock;
|
|
||||||
}
|
|
||||||
} else if ((mod->Attributes & CONF_VPP1_CHANGE_VALID) ||
|
|
||||||
(mod->Attributes & CONF_VPP2_CHANGE_VALID)) {
|
|
||||||
dev_dbg(&p_dev->dev,
|
|
||||||
"changing Vcc is not allowed at this time\n");
|
|
||||||
ret = -EINVAL;
|
|
||||||
goto unlock;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mod->Attributes & CONF_IO_CHANGE_WIDTH) {
|
|
||||||
pccard_io_map io_off = { 0, 0, 0, 0, 1 };
|
|
||||||
pccard_io_map io_on;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
io_on.speed = io_speed;
|
io_on.speed = io_speed;
|
||||||
for (i = 0; i < MAX_IO_WIN; i++) {
|
for (i = 0; i < MAX_IO_WIN; i++) {
|
||||||
if (!s->io[i].res)
|
if (!s->io[i].res)
|
||||||
@ -304,14 +266,50 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev,
|
|||||||
mdelay(40);
|
mdelay(40);
|
||||||
s->ops->set_io_map(s, &io_on);
|
s->ops->set_io_map(s, &io_on);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
ret = 0;
|
|
||||||
unlock:
|
unlock:
|
||||||
mutex_unlock(&s->ops_mutex);
|
mutex_unlock(&s->ops_mutex);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
} /* modify_configuration */
|
}
|
||||||
EXPORT_SYMBOL(pcmcia_modify_configuration);
|
EXPORT_SYMBOL(pcmcia_fixup_iowidth);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* pcmcia_fixup_vpp() - set Vpp to a new voltage level
|
||||||
|
*
|
||||||
|
* pcmcia_fixup_vpp() allows a PCMCIA device driver to set Vpp to
|
||||||
|
* a new voltage level between calls to pcmcia_request_configuration()
|
||||||
|
* and pcmcia_disable_device().
|
||||||
|
*/
|
||||||
|
int pcmcia_fixup_vpp(struct pcmcia_device *p_dev, unsigned char new_vpp)
|
||||||
|
{
|
||||||
|
struct pcmcia_socket *s = p_dev->socket;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
mutex_lock(&s->ops_mutex);
|
||||||
|
|
||||||
|
dev_dbg(&p_dev->dev, "fixup Vpp to %d\n", new_vpp);
|
||||||
|
|
||||||
|
if (!(s->state & SOCKET_PRESENT) ||
|
||||||
|
!(p_dev->function_config->state & CONFIG_LOCKED)) {
|
||||||
|
dev_dbg(&p_dev->dev, "No card? Config not locked?\n");
|
||||||
|
ret = -EACCES;
|
||||||
|
goto unlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
s->socket.Vpp = new_vpp;
|
||||||
|
if (s->ops->set_socket(s, &s->socket)) {
|
||||||
|
dev_warn(&p_dev->dev, "Unable to set VPP\n");
|
||||||
|
ret = -EIO;
|
||||||
|
goto unlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
unlock:
|
||||||
|
mutex_unlock(&s->ops_mutex);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(pcmcia_fixup_vpp);
|
||||||
|
|
||||||
|
|
||||||
int pcmcia_release_configuration(struct pcmcia_device *p_dev)
|
int pcmcia_release_configuration(struct pcmcia_device *p_dev)
|
||||||
|
@ -19,19 +19,6 @@
|
|||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* ModifyConfiguration */
|
|
||||||
typedef struct modconf_t {
|
|
||||||
u_int Attributes;
|
|
||||||
u_int Vcc, Vpp1, Vpp2;
|
|
||||||
} modconf_t;
|
|
||||||
|
|
||||||
/* Attributes for ModifyConfiguration */
|
|
||||||
#define CONF_IRQ_CHANGE_VALID 0x0100
|
|
||||||
#define CONF_VCC_CHANGE_VALID 0x0200
|
|
||||||
#define CONF_VPP1_CHANGE_VALID 0x0400
|
|
||||||
#define CONF_VPP2_CHANGE_VALID 0x0800
|
|
||||||
#define CONF_IO_CHANGE_WIDTH 0x1000
|
|
||||||
|
|
||||||
/* For RequestConfiguration */
|
/* For RequestConfiguration */
|
||||||
typedef struct config_req_t {
|
typedef struct config_req_t {
|
||||||
u_int Attributes;
|
u_int Attributes;
|
||||||
|
@ -212,7 +212,9 @@ int pcmcia_release_window(struct pcmcia_device *p_dev, struct resource *res);
|
|||||||
int pcmcia_map_mem_page(struct pcmcia_device *p_dev, struct resource *res,
|
int pcmcia_map_mem_page(struct pcmcia_device *p_dev, struct resource *res,
|
||||||
unsigned int offset);
|
unsigned int offset);
|
||||||
|
|
||||||
int pcmcia_modify_configuration(struct pcmcia_device *p_dev, modconf_t *mod);
|
int pcmcia_fixup_vpp(struct pcmcia_device *p_dev, unsigned char new_vpp);
|
||||||
|
int pcmcia_fixup_iowidth(struct pcmcia_device *p_dev);
|
||||||
|
|
||||||
void pcmcia_disable_device(struct pcmcia_device *p_dev);
|
void pcmcia_disable_device(struct pcmcia_device *p_dev);
|
||||||
|
|
||||||
/* IO ports */
|
/* IO ports */
|
||||||
|
Loading…
Reference in New Issue
Block a user