[PATCH] pcmcia: merge suspend into device model
Merge the suspend and resume methods for 16-bit PCMCIA cards into the device model -- for both runtime power management and suspend to ram/disk. Bugfix in ds.c by Richard Purdie Signed-Off-By: Richard Purdie <rpurdie@rpsys.net> Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
This commit is contained in:
parent
98e4c28b7e
commit
8e9e793d68
|
@ -62,6 +62,7 @@ int dpm_runtime_suspend(struct device * dev, pm_message_t state)
|
||||||
up(&dpm_sem);
|
up(&dpm_sem);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(dpm_runtime_suspend);
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
|
|
@ -780,8 +780,13 @@ int pccard_reset_card(struct pcmcia_socket *skt)
|
||||||
ret = send_event(skt, CS_EVENT_RESET_REQUEST, CS_EVENT_PRI_LOW);
|
ret = send_event(skt, CS_EVENT_RESET_REQUEST, CS_EVENT_PRI_LOW);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
send_event(skt, CS_EVENT_RESET_PHYSICAL, CS_EVENT_PRI_LOW);
|
send_event(skt, CS_EVENT_RESET_PHYSICAL, CS_EVENT_PRI_LOW);
|
||||||
if (socket_reset(skt) == CS_SUCCESS)
|
if (skt->callback)
|
||||||
|
skt->callback->suspend(skt);
|
||||||
|
if (socket_reset(skt) == CS_SUCCESS) {
|
||||||
send_event(skt, CS_EVENT_CARD_RESET, CS_EVENT_PRI_LOW);
|
send_event(skt, CS_EVENT_CARD_RESET, CS_EVENT_PRI_LOW);
|
||||||
|
if (skt->callback)
|
||||||
|
skt->callback->resume(skt);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = CS_SUCCESS;
|
ret = CS_SUCCESS;
|
||||||
|
@ -812,6 +817,11 @@ int pcmcia_suspend_card(struct pcmcia_socket *skt)
|
||||||
ret = CS_UNSUPPORTED_FUNCTION;
|
ret = CS_UNSUPPORTED_FUNCTION;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (skt->callback) {
|
||||||
|
ret = skt->callback->suspend(skt);
|
||||||
|
if (ret)
|
||||||
|
break;
|
||||||
|
}
|
||||||
ret = socket_suspend(skt);
|
ret = socket_suspend(skt);
|
||||||
} while (0);
|
} while (0);
|
||||||
up(&skt->skt_sem);
|
up(&skt->skt_sem);
|
||||||
|
@ -838,6 +848,8 @@ int pcmcia_resume_card(struct pcmcia_socket *skt)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ret = socket_resume(skt);
|
ret = socket_resume(skt);
|
||||||
|
if (!ret && skt->callback)
|
||||||
|
skt->callback->resume(skt);
|
||||||
} while (0);
|
} while (0);
|
||||||
up(&skt->skt_sem);
|
up(&skt->skt_sem);
|
||||||
|
|
||||||
|
|
|
@ -143,6 +143,8 @@ struct pcmcia_callback{
|
||||||
struct module *owner;
|
struct module *owner;
|
||||||
int (*event) (struct pcmcia_socket *s, event_t event, int priority);
|
int (*event) (struct pcmcia_socket *s, event_t event, int priority);
|
||||||
void (*requery) (struct pcmcia_socket *s);
|
void (*requery) (struct pcmcia_socket *s);
|
||||||
|
int (*suspend) (struct pcmcia_socket *s);
|
||||||
|
int (*resume) (struct pcmcia_socket *s);
|
||||||
};
|
};
|
||||||
|
|
||||||
int pccard_register_pcmcia(struct pcmcia_socket *s, struct pcmcia_callback *c);
|
int pccard_register_pcmcia(struct pcmcia_socket *s, struct pcmcia_callback *c);
|
||||||
|
|
|
@ -920,6 +920,78 @@ static struct device_attribute pcmcia_dev_attrs[] = {
|
||||||
__ATTR_NULL,
|
__ATTR_NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* PM support, also needed for reset */
|
||||||
|
|
||||||
|
static int pcmcia_dev_suspend(struct device * dev, pm_message_t state)
|
||||||
|
{
|
||||||
|
struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
|
||||||
|
struct pcmcia_driver *p_drv = NULL;
|
||||||
|
|
||||||
|
if (dev->driver)
|
||||||
|
p_drv = to_pcmcia_drv(dev->driver);
|
||||||
|
|
||||||
|
if (p_drv && p_drv->suspend)
|
||||||
|
return p_drv->suspend(p_dev);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int pcmcia_dev_resume(struct device * dev)
|
||||||
|
{
|
||||||
|
struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
|
||||||
|
struct pcmcia_driver *p_drv = NULL;
|
||||||
|
|
||||||
|
if (dev->driver)
|
||||||
|
p_drv = to_pcmcia_drv(dev->driver);
|
||||||
|
|
||||||
|
if (p_drv && p_drv->resume)
|
||||||
|
return p_drv->resume(p_dev);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int pcmcia_bus_suspend_callback(struct device *dev, void * _data)
|
||||||
|
{
|
||||||
|
struct pcmcia_socket *skt = _data;
|
||||||
|
struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
|
||||||
|
|
||||||
|
if (p_dev->socket != skt)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return dpm_runtime_suspend(dev, PMSG_SUSPEND);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int pcmcia_bus_resume_callback(struct device *dev, void * _data)
|
||||||
|
{
|
||||||
|
struct pcmcia_socket *skt = _data;
|
||||||
|
struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
|
||||||
|
|
||||||
|
if (p_dev->socket != skt)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
dpm_runtime_resume(dev);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int pcmcia_bus_resume(struct pcmcia_socket *skt)
|
||||||
|
{
|
||||||
|
bus_for_each_dev(&pcmcia_bus_type, NULL, skt, pcmcia_bus_resume_callback);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int pcmcia_bus_suspend(struct pcmcia_socket *skt)
|
||||||
|
{
|
||||||
|
if (bus_for_each_dev(&pcmcia_bus_type, NULL, skt,
|
||||||
|
pcmcia_bus_suspend_callback)) {
|
||||||
|
pcmcia_bus_resume(skt);
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*======================================================================
|
/*======================================================================
|
||||||
|
|
||||||
|
@ -951,16 +1023,6 @@ static int send_event_callback(struct device *dev, void * _data)
|
||||||
if (p_dev->state & (CLIENT_UNBOUND|CLIENT_STALE))
|
if (p_dev->state & (CLIENT_UNBOUND|CLIENT_STALE))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if ((data->event == CS_EVENT_PM_SUSPEND) ||
|
|
||||||
(data->event == CS_EVENT_RESET_PHYSICAL)) {
|
|
||||||
if (p_drv->suspend)
|
|
||||||
return p_drv->suspend(p_dev);
|
|
||||||
} else if ((data->event == CS_EVENT_PM_RESUME) ||
|
|
||||||
(data->event == CS_EVENT_CARD_RESET)) {
|
|
||||||
if (p_drv->resume)
|
|
||||||
return p_drv->resume(p_dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (p_drv->event)
|
if (p_drv->event)
|
||||||
return p_drv->event(data->event, data->priority,
|
return p_drv->event(data->event, data->priority,
|
||||||
&p_dev->event_callback_args);
|
&p_dev->event_callback_args);
|
||||||
|
@ -1012,6 +1074,13 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority)
|
||||||
ret = send_event(skt, event, priority);
|
ret = send_event(skt, event, priority);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case CS_EVENT_PM_SUSPEND:
|
||||||
|
case CS_EVENT_PM_RESUME:
|
||||||
|
case CS_EVENT_RESET_PHYSICAL:
|
||||||
|
case CS_EVENT_CARD_RESET:
|
||||||
|
handle_event(skt, event);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
handle_event(skt, event);
|
handle_event(skt, event);
|
||||||
send_event(skt, event, priority);
|
send_event(skt, event, priority);
|
||||||
|
@ -1166,10 +1235,13 @@ int pcmcia_deregister_client(struct pcmcia_device *p_dev)
|
||||||
} /* deregister_client */
|
} /* deregister_client */
|
||||||
EXPORT_SYMBOL(pcmcia_deregister_client);
|
EXPORT_SYMBOL(pcmcia_deregister_client);
|
||||||
|
|
||||||
|
|
||||||
static struct pcmcia_callback pcmcia_bus_callback = {
|
static struct pcmcia_callback pcmcia_bus_callback = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.event = ds_event,
|
.event = ds_event,
|
||||||
.requery = pcmcia_bus_rescan,
|
.requery = pcmcia_bus_rescan,
|
||||||
|
.suspend = pcmcia_bus_suspend,
|
||||||
|
.resume = pcmcia_bus_resume,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __devinit pcmcia_bus_add_socket(struct class_device *class_dev,
|
static int __devinit pcmcia_bus_add_socket(struct class_device *class_dev,
|
||||||
|
@ -1238,6 +1310,8 @@ struct bus_type pcmcia_bus_type = {
|
||||||
.uevent = pcmcia_bus_uevent,
|
.uevent = pcmcia_bus_uevent,
|
||||||
.match = pcmcia_bus_match,
|
.match = pcmcia_bus_match,
|
||||||
.dev_attrs = pcmcia_dev_attrs,
|
.dev_attrs = pcmcia_dev_attrs,
|
||||||
|
.suspend = pcmcia_dev_suspend,
|
||||||
|
.resume = pcmcia_dev_resume,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue