diff options
Diffstat (limited to 'drivers/pcmcia')
31 files changed, 329 insertions, 464 deletions
diff --git a/drivers/pcmcia/at91_cf.c b/drivers/pcmcia/at91_cf.c index 5d228071ec6..fb33fa42d24 100644 --- a/drivers/pcmcia/at91_cf.c +++ b/drivers/pcmcia/at91_cf.c @@ -15,6 +15,7 @@  #include <linux/errno.h>  #include <linux/init.h>  #include <linux/interrupt.h> +#include <linux/slab.h>  #include <pcmcia/ss.h> @@ -361,7 +362,6 @@ static int at91_cf_suspend(struct platform_device *pdev, pm_message_t mesg)  	struct at91_cf_socket	*cf = platform_get_drvdata(pdev);  	struct at91_cf_data	*board = cf->board; -	pcmcia_socket_dev_suspend(&pdev->dev);  	if (device_may_wakeup(&pdev->dev)) {  		enable_irq_wake(board->det_pin);  		if (board->irq_pin) @@ -381,7 +381,6 @@ static int at91_cf_resume(struct platform_device *pdev)  			disable_irq_wake(board->irq_pin);  	} -	pcmcia_socket_dev_resume(&pdev->dev);  	return 0;  } diff --git a/drivers/pcmcia/au1000_generic.c b/drivers/pcmcia/au1000_generic.c index 171c8a65488..88c4c409878 100644 --- a/drivers/pcmcia/au1000_generic.c +++ b/drivers/pcmcia/au1000_generic.c @@ -43,6 +43,7 @@  #include <linux/spinlock.h>  #include <linux/mutex.h>  #include <linux/platform_device.h> +#include <linux/slab.h>  #include <asm/io.h>  #include <asm/irq.h> @@ -510,17 +511,6 @@ static int au1x00_drv_pcmcia_probe(struct platform_device *dev)  	return ret;  } -static int au1x00_drv_pcmcia_suspend(struct platform_device *dev, -				     pm_message_t state) -{ -	return pcmcia_socket_dev_suspend(&dev->dev); -} - -static int au1x00_drv_pcmcia_resume(struct platform_device *dev) -{ -	return pcmcia_socket_dev_resume(&dev->dev); -} -  static struct platform_driver au1x00_pcmcia_driver = {  	.driver = {  		.name		= "au1x00-pcmcia", @@ -528,8 +518,6 @@ static struct platform_driver au1x00_pcmcia_driver = {  	},  	.probe		= au1x00_drv_pcmcia_probe,  	.remove		= au1x00_drv_pcmcia_remove, -	.suspend 	= au1x00_drv_pcmcia_suspend, -	.resume 	= au1x00_drv_pcmcia_resume,  }; diff --git a/drivers/pcmcia/bcm63xx_pcmcia.c b/drivers/pcmcia/bcm63xx_pcmcia.c index bc88a3b19bb..693577e0fef 100644 --- a/drivers/pcmcia/bcm63xx_pcmcia.c +++ b/drivers/pcmcia/bcm63xx_pcmcia.c @@ -11,6 +11,7 @@  #include <linux/ioport.h>  #include <linux/timer.h>  #include <linux/platform_device.h> +#include <linux/slab.h>  #include <linux/delay.h>  #include <linux/pci.h>  #include <linux/gpio.h> diff --git a/drivers/pcmcia/bfin_cf_pcmcia.c b/drivers/pcmcia/bfin_cf_pcmcia.c index 2482ce7ac6d..9e84d039de4 100644 --- a/drivers/pcmcia/bfin_cf_pcmcia.c +++ b/drivers/pcmcia/bfin_cf_pcmcia.c @@ -31,6 +31,7 @@  #include <linux/platform_device.h>  #include <linux/errno.h>  #include <linux/init.h> +#include <linux/slab.h>  #include <linux/delay.h>  #include <linux/interrupt.h>  #include <linux/irq.h> @@ -300,16 +301,6 @@ static int __devexit bfin_cf_remove(struct platform_device *pdev)  	return 0;  } -static int bfin_cf_suspend(struct platform_device *pdev, pm_message_t mesg) -{ -	return pcmcia_socket_dev_suspend(&pdev->dev); -} - -static int bfin_cf_resume(struct platform_device *pdev) -{ -	return pcmcia_socket_dev_resume(&pdev->dev); -} -  static struct platform_driver bfin_cf_driver = {  	.driver = {  		   .name = (char *)driver_name, @@ -317,8 +308,6 @@ static struct platform_driver bfin_cf_driver = {  		   },  	.probe = bfin_cf_probe,  	.remove = __devexit_p(bfin_cf_remove), -	.suspend = bfin_cf_suspend, -	.resume = bfin_cf_resume,  };  static int __init bfin_cf_init(void) diff --git a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c index f230f6543bf..854959cada3 100644 --- a/drivers/pcmcia/cistpl.c +++ b/drivers/pcmcia/cistpl.c @@ -1484,6 +1484,11 @@ int pccard_validate_cis(struct pcmcia_socket *s, unsigned int *info)  	if (!s)  		return -EINVAL; +	if (s->functions) { +		WARN_ON(1); +		return -EINVAL; +	} +  	/* We do not want to validate the CIS cache... */  	mutex_lock(&s->ops_mutex);  	destroy_cis_cache(s); @@ -1639,7 +1644,7 @@ static ssize_t pccard_show_cis(struct kobject *kobj,  		count = 0;  	else {  		struct pcmcia_socket *s; -		unsigned int chains; +		unsigned int chains = 1;  		if (off + count > size)  			count = size - off; @@ -1648,7 +1653,7 @@ static ssize_t pccard_show_cis(struct kobject *kobj,  		if (!(s->state & SOCKET_PRESENT))  			return -ENODEV; -		if (pccard_validate_cis(s, &chains)) +		if (!s->functions && pccard_validate_cis(s, &chains))  			return -EIO;  		if (!chains)  			return -ENODATA; diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c index e679e708db6..c3383750e33 100644 --- a/drivers/pcmcia/cs.c +++ b/drivers/pcmcia/cs.c @@ -76,65 +76,6 @@ DECLARE_RWSEM(pcmcia_socket_list_rwsem);  EXPORT_SYMBOL(pcmcia_socket_list_rwsem); -/* - * Low-level PCMCIA socket drivers need to register with the PCCard - * core using pcmcia_register_socket. - * - * socket drivers are expected to use the following callbacks in their - * .drv struct: - *  - pcmcia_socket_dev_suspend - *  - pcmcia_socket_dev_resume - * These functions check for the appropriate struct pcmcia_soket arrays, - * and pass them to the low-level functions pcmcia_{suspend,resume}_socket - */ -static int socket_early_resume(struct pcmcia_socket *skt); -static int socket_late_resume(struct pcmcia_socket *skt); -static int socket_resume(struct pcmcia_socket *skt); -static int socket_suspend(struct pcmcia_socket *skt); - -static void pcmcia_socket_dev_run(struct device *dev, -				  int (*cb)(struct pcmcia_socket *)) -{ -	struct pcmcia_socket *socket; - -	down_read(&pcmcia_socket_list_rwsem); -	list_for_each_entry(socket, &pcmcia_socket_list, socket_list) { -		if (socket->dev.parent != dev) -			continue; -		mutex_lock(&socket->skt_mutex); -		cb(socket); -		mutex_unlock(&socket->skt_mutex); -	} -	up_read(&pcmcia_socket_list_rwsem); -} - -int pcmcia_socket_dev_suspend(struct device *dev) -{ -	pcmcia_socket_dev_run(dev, socket_suspend); -	return 0; -} -EXPORT_SYMBOL(pcmcia_socket_dev_suspend); - -void pcmcia_socket_dev_early_resume(struct device *dev) -{ -	pcmcia_socket_dev_run(dev, socket_early_resume); -} -EXPORT_SYMBOL(pcmcia_socket_dev_early_resume); - -void pcmcia_socket_dev_late_resume(struct device *dev) -{ -	pcmcia_socket_dev_run(dev, socket_late_resume); -} -EXPORT_SYMBOL(pcmcia_socket_dev_late_resume); - -int pcmcia_socket_dev_resume(struct device *dev) -{ -	pcmcia_socket_dev_run(dev, socket_resume); -	return 0; -} -EXPORT_SYMBOL(pcmcia_socket_dev_resume); - -  struct pcmcia_socket *pcmcia_get_socket(struct pcmcia_socket *skt)  {  	struct device *dev = get_device(&skt->dev); @@ -578,12 +519,18 @@ static int socket_early_resume(struct pcmcia_socket *skt)  static int socket_late_resume(struct pcmcia_socket *skt)  { +	int ret; +  	mutex_lock(&skt->ops_mutex);  	skt->state &= ~SOCKET_SUSPEND;  	mutex_unlock(&skt->ops_mutex); -	if (!(skt->state & SOCKET_PRESENT)) -		return socket_insert(skt); +	if (!(skt->state & SOCKET_PRESENT)) { +		ret = socket_insert(skt); +		if (ret == -ENODEV) +			ret = 0; +		return ret; +	}  	if (skt->resume_status) {  		socket_shutdown(skt); @@ -724,20 +671,22 @@ static int pccardd(void *__skt)  				socket_remove(skt);  			if (sysfs_events & PCMCIA_UEVENT_INSERT)  				socket_insert(skt); -			if ((sysfs_events & PCMCIA_UEVENT_RESUME) && -				!(skt->state & SOCKET_CARDBUS)) { -				ret = socket_resume(skt); -				if (!ret && skt->callback) -					skt->callback->resume(skt); -			}  			if ((sysfs_events & PCMCIA_UEVENT_SUSPEND) &&  				!(skt->state & SOCKET_CARDBUS)) {  				if (skt->callback)  					ret = skt->callback->suspend(skt);  				else  					ret = 0; -				if (!ret) +				if (!ret) {  					socket_suspend(skt); +					msleep(100); +				} +			} +			if ((sysfs_events & PCMCIA_UEVENT_RESUME) && +				!(skt->state & SOCKET_CARDBUS)) { +				ret = socket_resume(skt); +				if (!ret && skt->callback) +					skt->callback->resume(skt);  			}  			if ((sysfs_events & PCMCIA_UEVENT_REQUERY) &&  				!(skt->state & SOCKET_CARDBUS)) { @@ -919,11 +868,66 @@ static void pcmcia_release_socket_class(struct class *data)  } +#ifdef CONFIG_PM + +static int __pcmcia_pm_op(struct device *dev, +			  int (*callback) (struct pcmcia_socket *skt)) +{ +	struct pcmcia_socket *s = container_of(dev, struct pcmcia_socket, dev); +	int ret; + +	mutex_lock(&s->skt_mutex); +	ret = callback(s); +	mutex_unlock(&s->skt_mutex); + +	return ret; +} + +static int pcmcia_socket_dev_suspend_noirq(struct device *dev) +{ +	return __pcmcia_pm_op(dev, socket_suspend); +} + +static int pcmcia_socket_dev_resume_noirq(struct device *dev) +{ +	return __pcmcia_pm_op(dev, socket_early_resume); +} + +static int pcmcia_socket_dev_resume(struct device *dev) +{ +	return __pcmcia_pm_op(dev, socket_late_resume); +} + +static const struct dev_pm_ops pcmcia_socket_pm_ops = { +	/* dev_resume may be called with IRQs enabled */ +	SET_SYSTEM_SLEEP_PM_OPS(NULL, +				pcmcia_socket_dev_resume) + +	/* late suspend must be called with IRQs disabled */ +	.suspend_noirq = pcmcia_socket_dev_suspend_noirq, +	.freeze_noirq = pcmcia_socket_dev_suspend_noirq, +	.poweroff_noirq = pcmcia_socket_dev_suspend_noirq, + +	/* early resume must be called with IRQs disabled */ +	.resume_noirq = pcmcia_socket_dev_resume_noirq, +	.thaw_noirq = pcmcia_socket_dev_resume_noirq, +	.restore_noirq = pcmcia_socket_dev_resume_noirq, +}; + +#define PCMCIA_SOCKET_CLASS_PM_OPS (&pcmcia_socket_pm_ops) + +#else /* CONFIG_PM */ + +#define PCMCIA_SOCKET_CLASS_PM_OPS NULL + +#endif /* CONFIG_PM */ +  struct class pcmcia_socket_class = {  	.name = "pcmcia_socket",  	.dev_uevent = pcmcia_socket_uevent,  	.dev_release = pcmcia_release_socket,  	.class_release = pcmcia_release_socket_class, +	.pm = PCMCIA_SOCKET_CLASS_PM_OPS,  };  EXPORT_SYMBOL(pcmcia_socket_class); diff --git a/drivers/pcmcia/db1xxx_ss.c b/drivers/pcmcia/db1xxx_ss.c index 9254ab0b29b..0f4cc3f0002 100644 --- a/drivers/pcmcia/db1xxx_ss.c +++ b/drivers/pcmcia/db1xxx_ss.c @@ -26,6 +26,7 @@  #include <linux/pm.h>  #include <linux/platform_device.h>  #include <linux/resource.h> +#include <linux/slab.h>  #include <linux/spinlock.h>  #include <pcmcia/cs_types.h> @@ -145,7 +146,6 @@ static irqreturn_t db1200_pcmcia_cdirq(int irq, void *data)  static int db1x_pcmcia_setup_irqs(struct db1x_pcmcia_sock *sock)  {  	int ret; -	unsigned long flags;  	if (sock->stschg_irq != -1) {  		ret = request_irq(sock->stschg_irq, db1000_pcmcia_stschgirq, @@ -161,8 +161,6 @@ static int db1x_pcmcia_setup_irqs(struct db1x_pcmcia_sock *sock)  	 * active one disabled.  	 */  	if (sock->board_type == BOARD_TYPE_DB1200) { -		local_irq_save(flags); -  		ret = request_irq(sock->insert_irq, db1200_pcmcia_cdirq,  				  IRQF_DISABLED, "pcmcia_insert", sock);  		if (ret) @@ -172,17 +170,14 @@ static int db1x_pcmcia_setup_irqs(struct db1x_pcmcia_sock *sock)  				  IRQF_DISABLED, "pcmcia_eject", sock);  		if (ret) {  			free_irq(sock->insert_irq, sock); -			local_irq_restore(flags);  			goto out1;  		} -		/* disable the currently active one */ +		/* enable the currently silent one */  		if (db1200_card_inserted(sock)) -			disable_irq_nosync(sock->insert_irq); +			enable_irq(sock->eject_irq);  		else -			disable_irq_nosync(sock->eject_irq); - -		local_irq_restore(flags); +			enable_irq(sock->insert_irq);  	} else {  		/* all other (older) Db1x00 boards use a GPIO to show  		 * card detection status:  use both-edge triggers. @@ -558,37 +553,10 @@ static int __devexit db1x_pcmcia_socket_remove(struct platform_device *pdev)  	return 0;  } -#ifdef CONFIG_PM -static int db1x_pcmcia_suspend(struct device *dev) -{ -	return pcmcia_socket_dev_suspend(dev); -} - -static int db1x_pcmcia_resume(struct device *dev) -{ -	return pcmcia_socket_dev_resume(dev); -} - -static struct dev_pm_ops db1x_pcmcia_pmops = { -	.resume		= db1x_pcmcia_resume, -	.suspend	= db1x_pcmcia_suspend, -	.thaw		= db1x_pcmcia_resume, -	.freeze		= db1x_pcmcia_suspend, -}; - -#define DB1XXX_SS_PMOPS &db1x_pcmcia_pmops - -#else - -#define DB1XXX_SS_PMOPS NULL - -#endif -  static struct platform_driver db1x_pcmcia_socket_driver = {  	.driver	= {  		.name	= "db1xxx_pcmcia",  		.owner	= THIS_MODULE, -		.pm	= DB1XXX_SS_PMOPS  	},  	.probe		= db1x_pcmcia_socket_probe,  	.remove		= __devexit_p(db1x_pcmcia_socket_remove), diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index ad93ebd7b2a..041eee43fd8 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c @@ -24,6 +24,7 @@  #include <linux/firmware.h>  #include <linux/kref.h>  #include <linux/dma-mapping.h> +#include <linux/slab.h>  #include <pcmcia/cs_types.h>  #include <pcmcia/cs.h> @@ -334,7 +335,6 @@ static void pcmcia_card_remove(struct pcmcia_socket *s, struct pcmcia_device *le  		mutex_lock(&s->ops_mutex);  		list_del(&p_dev->socket_device_list); -		p_dev->_removed = 1;  		mutex_unlock(&s->ops_mutex);  		dev_dbg(&p_dev->dev, "unregistering device\n"); @@ -509,8 +509,12 @@ struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, unsigned int fu  	p_dev->device_no = (s->device_count++);  	mutex_unlock(&s->ops_mutex); -	/* max of 2 devices per card */ -	if (p_dev->device_no >= 2) +	/* max of 2 PFC devices */ +	if ((p_dev->device_no >= 2) && (function == 0)) +		goto err_free; + +	/* max of 4 devices overall */ +	if (p_dev->device_no >= 4)  		goto err_free;  	p_dev->socket = s; @@ -649,14 +653,7 @@ static int pcmcia_requery_callback(struct device *dev, void * _data)  static void pcmcia_requery(struct pcmcia_socket *s)  { -	int present, has_pfc; - -	mutex_lock(&s->ops_mutex); -	present = s->pcmcia_state.present; -	mutex_unlock(&s->ops_mutex); - -	if (!present) -		return; +	int has_pfc;  	if (s->functions == 0) {  		pcmcia_card_add(s); @@ -682,12 +679,10 @@ static void pcmcia_requery(struct pcmcia_socket *s)  			new_funcs = mfc.nfn;  		else  			new_funcs = 1; -		if (old_funcs > new_funcs) { +		if (old_funcs != new_funcs) { +			/* we need to re-start */  			pcmcia_card_remove(s, NULL);  			pcmcia_card_add(s); -		} else if (new_funcs > old_funcs) { -			s->functions = new_funcs; -			pcmcia_device_add(s, 1);  		}  	} @@ -723,6 +718,8 @@ static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename)  	struct pcmcia_socket *s = dev->socket;  	const struct firmware *fw;  	int ret = -ENOMEM; +	cistpl_longlink_mfc_t mfc; +	int old_funcs, new_funcs = 1;  	if (!filename)  		return -EINVAL; @@ -745,6 +742,14 @@ static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename)  			goto release;  		} +		/* we need to re-start if the number of functions changed */ +		old_funcs = s->functions; +		if (!pccard_read_tuple(s, BIND_FN_ALL, CISTPL_LONGLINK_MFC, +					&mfc)) +			new_funcs = mfc.nfn; + +		if (old_funcs != new_funcs) +			ret = -EBUSY;  		/* update information */  		pcmcia_device_query(dev); @@ -815,11 +820,12 @@ static inline int pcmcia_devmatch(struct pcmcia_device *dev,  	}  	if (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) { -		if (dev->device_no != did->device_no) -			return 0; +		dev_dbg(&dev->dev, "this is a pseudo-multi-function device\n");  		mutex_lock(&dev->socket->ops_mutex);  		dev->socket->pcmcia_state.has_pfc = 1;  		mutex_unlock(&dev->socket->ops_mutex); +		if (dev->device_no != did->device_no) +			return 0;  	}  	if (did->match_flags & PCMCIA_DEV_ID_MATCH_FUNC_ID) { @@ -830,7 +836,7 @@ static inline int pcmcia_devmatch(struct pcmcia_device *dev,  		/* if this is a pseudo-multi-function device,  		 * we need explicit matches */ -		if (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) +		if (dev->socket->pcmcia_state.has_pfc)  			return 0;  		if (dev->device_no)  			return 0; @@ -853,10 +859,8 @@ static inline int pcmcia_devmatch(struct pcmcia_device *dev,  	if (did->match_flags & PCMCIA_DEV_ID_MATCH_FAKE_CIS) {  		dev_dbg(&dev->dev, "device needs a fake CIS\n");  		if (!dev->socket->fake_cis) -			pcmcia_load_firmware(dev, did->cisfile); - -		if (!dev->socket->fake_cis) -			return 0; +			if (pcmcia_load_firmware(dev, did->cisfile)) +				return 0;  	}  	if (did->match_flags & PCMCIA_DEV_ID_MATCH_ANONYMOUS) { @@ -1249,9 +1253,7 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority)  	switch (event) {  	case CS_EVENT_CARD_REMOVAL: -		mutex_lock(&s->ops_mutex); -		s->pcmcia_state.present = 0; -		mutex_unlock(&s->ops_mutex); +		atomic_set(&skt->present, 0);  		pcmcia_card_remove(skt, NULL);  		handle_event(skt, event);  		mutex_lock(&s->ops_mutex); @@ -1260,9 +1262,9 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority)  		break;  	case CS_EVENT_CARD_INSERTION: +		atomic_set(&skt->present, 1);  		mutex_lock(&s->ops_mutex);  		s->pcmcia_state.has_pfc = 0; -		s->pcmcia_state.present = 1;  		destroy_cis_cache(s); /* to be on the safe side... */  		mutex_unlock(&s->ops_mutex);  		pcmcia_card_add(skt); @@ -1281,6 +1283,7 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority)  			destroy_cis_cache(skt);  			kfree(skt->fake_cis);  			skt->fake_cis = NULL; +			s->functions = 0;  			mutex_unlock(&s->ops_mutex);  			/* now, add the new card */  			ds_event(skt, CS_EVENT_CARD_INSERTION, @@ -1302,7 +1305,13 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority)      return 0;  } /* ds_event */ - +/* + * NOTE: This is racy. There's no guarantee the card will still be + * physically present, even if the call to this function returns + * non-NULL. Furthermore, the device driver most likely is unbound + * almost immediately, so the timeframe where pcmcia_dev_present + * returns NULL is probably really really small. + */  struct pcmcia_device *pcmcia_dev_present(struct pcmcia_device *_p_dev)  {  	struct pcmcia_device *p_dev; @@ -1312,22 +1321,9 @@ struct pcmcia_device *pcmcia_dev_present(struct pcmcia_device *_p_dev)  	if (!p_dev)  		return NULL; -	mutex_lock(&p_dev->socket->ops_mutex); -	if (!p_dev->socket->pcmcia_state.present) -		goto out; - -	if (p_dev->socket->pcmcia_state.dead) -		goto out; +	if (atomic_read(&p_dev->socket->present) != 0) +		ret = p_dev; -	if (p_dev->_removed) -		goto out; - -	if (p_dev->suspended) -		goto out; - -	ret = p_dev; - out: -	mutex_unlock(&p_dev->socket->ops_mutex);  	pcmcia_put_dev(p_dev);  	return ret;  } @@ -1377,6 +1373,8 @@ static int __devinit pcmcia_bus_add_socket(struct device *dev,  		return ret;  	} +	atomic_set(&socket->present, 0); +  	return 0;  } @@ -1388,10 +1386,6 @@ static void pcmcia_bus_remove_socket(struct device *dev,  	if (!socket)  		return; -	mutex_lock(&socket->ops_mutex); -	socket->pcmcia_state.dead = 1; -	mutex_unlock(&socket->ops_mutex); -  	pccard_register_pcmcia(socket, NULL);  	/* unregister any unbound devices */ diff --git a/drivers/pcmcia/electra_cf.c b/drivers/pcmcia/electra_cf.c index 89cfddca089..2e59fe947d2 100644 --- a/drivers/pcmcia/electra_cf.c +++ b/drivers/pcmcia/electra_cf.c @@ -31,6 +31,7 @@  #include <linux/mm.h>  #include <linux/vmalloc.h>  #include <linux/of_platform.h> +#include <linux/slab.h>  #include <pcmcia/ss.h> diff --git a/drivers/pcmcia/i82092.c b/drivers/pcmcia/i82092.c index a04f21c8170..3003bb3dfcc 100644 --- a/drivers/pcmcia/i82092.c +++ b/drivers/pcmcia/i82092.c @@ -39,27 +39,11 @@ static struct pci_device_id i82092aa_pci_ids[] = {  };  MODULE_DEVICE_TABLE(pci, i82092aa_pci_ids); -#ifdef CONFIG_PM -static int i82092aa_socket_suspend (struct pci_dev *dev, pm_message_t state) -{ -	return pcmcia_socket_dev_suspend(&dev->dev); -} - -static int i82092aa_socket_resume (struct pci_dev *dev) -{ -	return pcmcia_socket_dev_resume(&dev->dev); -} -#endif -  static struct pci_driver i82092aa_pci_driver = {  	.name           = "i82092aa",  	.id_table       = i82092aa_pci_ids,  	.probe          = i82092aa_pci_probe,  	.remove         = __devexit_p(i82092aa_pci_remove), -#ifdef CONFIG_PM -	.suspend        = i82092aa_socket_suspend, -	.resume         = i82092aa_socket_resume, -#endif  }; @@ -133,6 +117,7 @@ static int __devinit i82092aa_pci_probe(struct pci_dev *dev, const struct pci_de  		sockets[i].socket.map_size = 0x1000;  		sockets[i].socket.irq_mask = 0;  		sockets[i].socket.pci_irq  = dev->irq; +		sockets[i].socket.cb_dev  = dev;  		sockets[i].socket.owner = THIS_MODULE;  		sockets[i].number = i; diff --git a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c index c13fd936051..9e2a15628de 100644 --- a/drivers/pcmcia/i82365.c +++ b/drivers/pcmcia/i82365.c @@ -40,7 +40,6 @@  #include <linux/kernel.h>  #include <linux/errno.h>  #include <linux/timer.h> -#include <linux/slab.h>  #include <linux/ioport.h>  #include <linux/delay.h>  #include <linux/workqueue.h> @@ -1223,16 +1222,7 @@ static int pcic_init(struct pcmcia_socket *s)  	return 0;  } -static int i82365_drv_pcmcia_suspend(struct platform_device *dev, -				     pm_message_t state) -{ -	return pcmcia_socket_dev_suspend(&dev->dev); -} -static int i82365_drv_pcmcia_resume(struct platform_device *dev) -{ -	return pcmcia_socket_dev_resume(&dev->dev); -}  static struct pccard_operations pcic_operations = {  	.init			= pcic_init,  	.get_status		= pcic_get_status, @@ -1248,8 +1238,6 @@ static struct platform_driver i82365_driver = {  		.name = "i82365",  		.owner		= THIS_MODULE,  	}, -	.suspend 	= i82365_drv_pcmcia_suspend, -	.resume 	= i82365_drv_pcmcia_resume,  };  static struct platform_device *i82365_device; diff --git a/drivers/pcmcia/i82365.h b/drivers/pcmcia/i82365.h index 849ef1b5d68..3f84d7a2dc8 100644 --- a/drivers/pcmcia/i82365.h +++ b/drivers/pcmcia/i82365.h @@ -95,6 +95,7 @@  #define I365_CSC_DETECT	0x08  #define I365_CSC_ANY	0x0F  #define I365_CSC_GPI	0x10 +#define I365_CSC_IRQ_MASK	0xF0  /* Flags for I365_ADDRWIN */  #define I365_ENA_IO(map)	(0x40 << (map)) diff --git a/drivers/pcmcia/m32r_cfc.c b/drivers/pcmcia/m32r_cfc.c index 0ece2cd4a85..7e16ed8eb0a 100644 --- a/drivers/pcmcia/m32r_cfc.c +++ b/drivers/pcmcia/m32r_cfc.c @@ -16,7 +16,6 @@  #include <linux/kernel.h>  #include <linux/errno.h>  #include <linux/timer.h> -#include <linux/slab.h>  #include <linux/ioport.h>  #include <linux/delay.h>  #include <linux/workqueue.h> @@ -685,16 +684,7 @@ static struct pccard_operations pcc_operations = {  	.set_mem_map		= pcc_set_mem_map,  }; -static int cfc_drv_pcmcia_suspend(struct platform_device *dev, -				     pm_message_t state) -{ -	return pcmcia_socket_dev_suspend(&dev->dev); -} -static int cfc_drv_pcmcia_resume(struct platform_device *dev) -{ -	return pcmcia_socket_dev_resume(&dev->dev); -}  /*====================================================================*/  static struct platform_driver pcc_driver = { @@ -702,8 +692,6 @@ static struct platform_driver pcc_driver = {  		.name		= "cfc",  		.owner		= THIS_MODULE,  	}, -	.suspend 	= cfc_drv_pcmcia_suspend, -	.resume 	= cfc_drv_pcmcia_resume,  };  static struct platform_device pcc_device = { diff --git a/drivers/pcmcia/m32r_pcc.c b/drivers/pcmcia/m32r_pcc.c index 72844c5a6d0..6c5c3f910d7 100644 --- a/drivers/pcmcia/m32r_pcc.c +++ b/drivers/pcmcia/m32r_pcc.c @@ -16,7 +16,6 @@  #include <linux/kernel.h>  #include <linux/errno.h>  #include <linux/timer.h> -#include <linux/slab.h>  #include <linux/ioport.h>  #include <linux/delay.h>  #include <linux/workqueue.h> @@ -663,16 +662,6 @@ static struct pccard_operations pcc_operations = {  	.set_mem_map		= pcc_set_mem_map,  }; -static int pcc_drv_pcmcia_suspend(struct platform_device *dev, -				     pm_message_t state) -{ -	return pcmcia_socket_dev_suspend(&dev->dev); -} - -static int pcc_drv_pcmcia_resume(struct platform_device *dev) -{ -	return pcmcia_socket_dev_resume(&dev->dev); -}  /*====================================================================*/  static struct platform_driver pcc_driver = { @@ -680,8 +669,6 @@ static struct platform_driver pcc_driver = {  		.name		= "pcc",  		.owner		= THIS_MODULE,  	}, -	.suspend 	= pcc_drv_pcmcia_suspend, -	.resume 	= pcc_drv_pcmcia_resume,  };  static struct platform_device pcc_device = { diff --git a/drivers/pcmcia/m8xx_pcmcia.c b/drivers/pcmcia/m8xx_pcmcia.c index 61c21591812..41cc954a5ff 100644 --- a/drivers/pcmcia/m8xx_pcmcia.c +++ b/drivers/pcmcia/m8xx_pcmcia.c @@ -42,7 +42,6 @@  #include <linux/kernel.h>  #include <linux/errno.h> -#include <linux/slab.h>  #include <linux/timer.h>  #include <linux/ioport.h>  #include <linux/delay.h> @@ -1288,21 +1287,6 @@ static int m8xx_remove(struct of_device *ofdev)  	return 0;  } -#ifdef CONFIG_PM -static int m8xx_suspend(struct platform_device *pdev, pm_message_t state) -{ -	return pcmcia_socket_dev_suspend(&pdev->dev); -} - -static int m8xx_resume(struct platform_device *pdev) -{ -	return pcmcia_socket_dev_resume(&pdev->dev); -} -#else -#define m8xx_suspend NULL -#define m8xx_resume NULL -#endif -  static const struct of_device_id m8xx_pcmcia_match[] = {  	{  	 .type = "pcmcia", @@ -1318,8 +1302,6 @@ static struct of_platform_driver m8xx_pcmcia_driver = {  	.match_table = m8xx_pcmcia_match,  	.probe = m8xx_probe,  	.remove = m8xx_remove, -	.suspend = m8xx_suspend, -	.resume = m8xx_resume,  };  static int __init m8xx_init(void) diff --git a/drivers/pcmcia/omap_cf.c b/drivers/pcmcia/omap_cf.c index 3ef99155239..a7cfc7964c7 100644 --- a/drivers/pcmcia/omap_cf.c +++ b/drivers/pcmcia/omap_cf.c @@ -16,6 +16,7 @@  #include <linux/init.h>  #include <linux/delay.h>  #include <linux/interrupt.h> +#include <linux/slab.h>  #include <pcmcia/ss.h> @@ -330,24 +331,12 @@ static int __exit omap_cf_remove(struct platform_device *pdev)  	return 0;  } -static int omap_cf_suspend(struct platform_device *pdev, pm_message_t mesg) -{ -	return pcmcia_socket_dev_suspend(&pdev->dev); -} - -static int omap_cf_resume(struct platform_device *pdev) -{ -	return pcmcia_socket_dev_resume(&pdev->dev); -} -  static struct platform_driver omap_cf_driver = {  	.driver = {  		.name	= (char *) driver_name,  		.owner	= THIS_MODULE,  	},  	.remove		= __exit_p(omap_cf_remove), -	.suspend	= omap_cf_suspend, -	.resume		= omap_cf_resume,  };  static int __init omap_cf_init(void) diff --git a/drivers/pcmcia/pcmcia_ioctl.c b/drivers/pcmcia/pcmcia_ioctl.c index 13a7132cf68..7631faa0cad 100644 --- a/drivers/pcmcia/pcmcia_ioctl.c +++ b/drivers/pcmcia/pcmcia_ioctl.c @@ -27,6 +27,7 @@  #include <linux/proc_fs.h>  #include <linux/poll.h>  #include <linux/pci.h> +#include <linux/slab.h>  #include <linux/seq_file.h>  #include <linux/smp_lock.h>  #include <linux/workqueue.h> @@ -710,7 +711,7 @@ static int ds_open(struct inode *inode, struct file *file)  	    warning_printed = 1;      } -    if (s->pcmcia_state.present) +    if (atomic_read(&s->present))  	queue_event(user, CS_EVENT_CARD_INSERTION);  out:      unlock_kernel(); @@ -769,9 +770,6 @@ static ssize_t ds_read(struct file *file, char __user *buf,  	return -EIO;      s = user->socket; -    if (s->pcmcia_state.dead) -	return -EIO; -      ret = wait_event_interruptible(s->queue, !queue_empty(user));      if (ret == 0)  	ret = put_user(get_queued_event(user), (int __user *)buf) ? -EFAULT : 4; @@ -837,8 +835,6 @@ static int ds_ioctl(struct inode *inode, struct file *file,  	return -EIO;      s = user->socket; -    if (s->pcmcia_state.dead) -	return -EIO;      size = (cmd & IOCSIZE_MASK) >> IOCSIZE_SHIFT;      if (size > sizeof(ds_ioctl_arg_t)) diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c index b2df04199a2..7c3d03bb4f3 100644 --- a/drivers/pcmcia/pcmcia_resource.c +++ b/drivers/pcmcia/pcmcia_resource.c @@ -21,6 +21,7 @@  #include <linux/pci.h>  #include <linux/device.h>  #include <linux/netdevice.h> +#include <linux/slab.h>  #include <pcmcia/cs_types.h>  #include <pcmcia/ss.h> @@ -256,6 +257,7 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev,  {  	struct pcmcia_socket *s;  	config_t *c; +	int ret;  	s = p_dev->socket; @@ -264,13 +266,13 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev,  	if (!(s->state & SOCKET_PRESENT)) {  		dev_dbg(&s->dev, "No card present\n"); -		mutex_unlock(&s->ops_mutex); -		return -ENODEV; +		ret = -ENODEV; +		goto unlock;  	}  	if (!(c->state & CONFIG_LOCKED)) {  		dev_dbg(&s->dev, "Configuration isnt't locked\n"); -		mutex_unlock(&s->ops_mutex); -		return -EACCES; +		ret = -EACCES; +		goto unlock;  	}  	if (mod->Attributes & CONF_IRQ_CHANGE_VALID) { @@ -286,7 +288,8 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev,  	if (mod->Attributes & CONF_VCC_CHANGE_VALID) {  		dev_dbg(&s->dev, "changing Vcc is not allowed at this time\n"); -		return -EINVAL; +		ret = -EINVAL; +		goto unlock;  	}  	/* We only allow changing Vpp1 and Vpp2 to the same value */ @@ -294,21 +297,21 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev,  	    (mod->Attributes & CONF_VPP2_CHANGE_VALID)) {  		if (mod->Vpp1 != mod->Vpp2) {  			dev_dbg(&s->dev, "Vpp1 and Vpp2 must be the same\n"); -			mutex_unlock(&s->ops_mutex); -			return -EINVAL; +			ret = -EINVAL; +			goto unlock;  		}  		s->socket.Vpp = mod->Vpp1;  		if (s->ops->set_socket(s, &s->socket)) { -			mutex_unlock(&s->ops_mutex);  			dev_printk(KERN_WARNING, &s->dev,  				   "Unable to set VPP\n"); -			return -EIO; +			ret = -EIO; +			goto unlock;  		}  	} else if ((mod->Attributes & CONF_VPP1_CHANGE_VALID) ||  		   (mod->Attributes & CONF_VPP2_CHANGE_VALID)) {  		dev_dbg(&s->dev, "changing Vcc is not allowed at this time\n"); -		mutex_unlock(&s->ops_mutex); -		return -EINVAL; +		ret = -EINVAL; +		goto unlock;  	}  	if (mod->Attributes & CONF_IO_CHANGE_WIDTH) { @@ -332,9 +335,11 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev,  			s->ops->set_io_map(s, &io_on);  		}  	} +	ret = 0; +unlock:  	mutex_unlock(&s->ops_mutex); -	return 0; +	return ret;  } /* modify_configuration */  EXPORT_SYMBOL(pcmcia_modify_configuration); @@ -750,20 +755,12 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req)  	else  		printk(KERN_WARNING "pcmcia: Driver needs updating to support IRQ sharing.\n"); -#ifdef CONFIG_PCMCIA_PROBE - -#ifdef IRQ_NOAUTOEN -	/* if the underlying IRQ infrastructure allows for it, only allocate -	 * the IRQ, but do not enable it -	 */ -	if (!(req->Handler)) -		type |= IRQ_NOAUTOEN; -#endif /* IRQ_NOAUTOEN */ - -	if (s->irq.AssignedIRQ != 0) { -		/* If the interrupt is already assigned, it must be the same */ +	/* If the interrupt is already assigned, it must be the same */ +	if (s->irq.AssignedIRQ != 0)  		irq = s->irq.AssignedIRQ; -	} else { + +#ifdef CONFIG_PCMCIA_PROBE +	if (!irq) {  		int try;  		u32 mask = s->irq_mask;  		void *data = p_dev; /* something unique to this device */ diff --git a/drivers/pcmcia/pd6729.c b/drivers/pcmcia/pd6729.c index 7c204910a77..b61a13663a0 100644 --- a/drivers/pcmcia/pd6729.c +++ b/drivers/pcmcia/pd6729.c @@ -9,18 +9,19 @@  #include <linux/kernel.h>  #include <linux/module.h> +#include <linux/slab.h>  #include <linux/pci.h>  #include <linux/init.h>  #include <linux/workqueue.h>  #include <linux/interrupt.h>  #include <linux/device.h> +#include <linux/io.h>  #include <pcmcia/cs_types.h>  #include <pcmcia/ss.h>  #include <pcmcia/cs.h>  #include <asm/system.h> -#include <asm/io.h>  #include "pd6729.h"  #include "i82365.h" @@ -222,9 +223,9 @@ static irqreturn_t pd6729_interrupt(int irq, void *dev)  						? SS_READY : 0;  			} -			if (events) { +			if (events)  				pcmcia_parse_events(&socket[i].socket, events); -			} +  			active |= events;  		} @@ -256,9 +257,8 @@ static int pd6729_get_status(struct pcmcia_socket *sock, u_int *value)  	status = indirect_read(socket, I365_STATUS);  	*value = 0; -	if ((status & I365_CS_DETECT) == I365_CS_DETECT) { +	if ((status & I365_CS_DETECT) == I365_CS_DETECT)  		*value |= SS_DETECT; -	}  	/*  	 * IO cards have a different meaning of bits 0,1 @@ -308,7 +308,7 @@ static int pd6729_set_socket(struct pcmcia_socket *sock, socket_state_t *state)  	socket->card_irq = state->io_irq;  	reg = 0; - 	/* The reset bit has "inverse" logic */ +	/* The reset bit has "inverse" logic */  	if (!(state->flags & SS_RESET))  		reg |= I365_PC_RESET;  	if (state->flags & SS_IOCARD) @@ -380,7 +380,7 @@ static int pd6729_set_socket(struct pcmcia_socket *sock, socket_state_t *state)  		indirect_write(socket, I365_POWER, reg);  	if (irq_mode == 1) { -		 /* all interrupts are to be done as PCI interrupts */ +		/* all interrupts are to be done as PCI interrupts */  		data = PD67_EC1_INV_MGMT_IRQ | PD67_EC1_INV_CARD_IRQ;  	} else  		data = 0; @@ -391,9 +391,9 @@ static int pd6729_set_socket(struct pcmcia_socket *sock, socket_state_t *state)  	/* Enable specific interrupt events */  	reg = 0x00; -	if (state->csc_mask & SS_DETECT) { +	if (state->csc_mask & SS_DETECT)  		reg |= I365_CSC_DETECT; -	} +  	if (state->flags & SS_IOCARD) {  		if (state->csc_mask & SS_STSCHG)  			reg |= I365_CSC_STSCHG; @@ -450,9 +450,12 @@ static int pd6729_set_io_map(struct pcmcia_socket *sock,  	ioctl = indirect_read(socket, I365_IOCTL) & ~I365_IOCTL_MASK(map); -	if (io->flags & MAP_0WS) ioctl |= I365_IOCTL_0WS(map); -	if (io->flags & MAP_16BIT) ioctl |= I365_IOCTL_16BIT(map); -	if (io->flags & MAP_AUTOSZ) ioctl |= I365_IOCTL_IOCS16(map); +	if (io->flags & MAP_0WS) +		ioctl |= I365_IOCTL_0WS(map); +	if (io->flags & MAP_16BIT) +		ioctl |= I365_IOCTL_16BIT(map); +	if (io->flags & MAP_AUTOSZ) +		ioctl |= I365_IOCTL_IOCS16(map);  	indirect_write(socket, I365_IOCTL, ioctl); @@ -497,7 +500,7 @@ static int pd6729_set_mem_map(struct pcmcia_socket *sock,  	/* write the stop address */ -	i= (mem->res->end >> 12) & 0x0fff; +	i = (mem->res->end >> 12) & 0x0fff;  	switch (to_cycles(mem->speed)) {  	case 0:  		break; @@ -563,7 +566,7 @@ static int pd6729_init(struct pcmcia_socket *sock)  /* the pccard structure and its functions */  static struct pccard_operations pd6729_operations = { -	.init 			= pd6729_init, +	.init			= pd6729_init,  	.get_status		= pd6729_get_status,  	.set_socket		= pd6729_set_socket,  	.set_io_map		= pd6729_set_io_map, @@ -578,8 +581,13 @@ static irqreturn_t pd6729_test(int irq, void *dev)  static int pd6729_check_irq(int irq)  { -	if (request_irq(irq, pd6729_test, IRQF_PROBE_SHARED, "x", pd6729_test) -		!= 0) return -1; +	int ret; + +	ret = request_irq(irq, pd6729_test, IRQF_PROBE_SHARED, "x", +			  pd6729_test); +	if (ret) +		return -1; +  	free_irq(irq, pd6729_test);  	return 0;  } @@ -591,7 +599,7 @@ static u_int __devinit pd6729_isa_scan(void)  	if (irq_mode == 1) {  		printk(KERN_INFO "pd6729: PCI card interrupts, " -						"PCI status changes\n"); +		       "PCI status changes\n");  		return 0;  	} @@ -607,9 +615,10 @@ static u_int __devinit pd6729_isa_scan(void)  		if (mask & (1<<i))  			printk("%s%d", ((mask & ((1<<i)-1)) ? "," : ""), i); -	if (mask == 0) printk("none!"); - -	printk("  polling status changes.\n"); +	if (mask == 0) +		printk("none!"); +	else +		printk("  polling status changes.\n");  	return mask;  } @@ -624,11 +633,16 @@ static int __devinit pd6729_pci_probe(struct pci_dev *dev,  	socket = kzalloc(sizeof(struct pd6729_socket) * MAX_SOCKETS,  			 GFP_KERNEL); -	if (!socket) +	if (!socket) { +		dev_warn(&dev->dev, "failed to kzalloc socket.\n");  		return -ENOMEM; +	} -	if ((ret = pci_enable_device(dev))) +	ret = pci_enable_device(dev); +	if (ret) { +		dev_warn(&dev->dev, "failed to enable pci_device.\n");  		goto err_out_free_mem; +	}  	if (!pci_resource_start(dev, 0)) {  		dev_warn(&dev->dev, "refusing to load the driver as the " @@ -639,7 +653,7 @@ static int __devinit pd6729_pci_probe(struct pci_dev *dev,  	dev_info(&dev->dev, "Cirrus PD6729 PCI to PCMCIA Bridge at 0x%llx "  		"on irq %d\n",  		(unsigned long long)pci_resource_start(dev, 0), dev->irq); - 	/* +	/*  	 * Since we have no memory BARs some firmware may not  	 * have had PCI_COMMAND_MEMORY enabled, yet the device needs it.  	 */ @@ -671,6 +685,7 @@ static int __devinit pd6729_pci_probe(struct pci_dev *dev,  		socket[i].socket.map_size = 0x1000;  		socket[i].socket.irq_mask = mask;  		socket[i].socket.pci_irq  = dev->irq; +		socket[i].socket.cb_dev = dev;  		socket[i].socket.owner = THIS_MODULE;  		socket[i].number = i; @@ -684,8 +699,9 @@ static int __devinit pd6729_pci_probe(struct pci_dev *dev,  	pci_set_drvdata(dev, socket);  	if (irq_mode == 1) {  		/* Register the interrupt handler */ -		if ((ret = request_irq(dev->irq, pd6729_interrupt, IRQF_SHARED, -							"pd6729", socket))) { +		ret = request_irq(dev->irq, pd6729_interrupt, IRQF_SHARED, +				  "pd6729", socket); +		if (ret) {  			dev_err(&dev->dev, "Failed to register irq %d\n",  				dev->irq);  			goto err_out_free_res; @@ -749,18 +765,6 @@ static void __devexit pd6729_pci_remove(struct pci_dev *dev)  	kfree(socket);  } -#ifdef CONFIG_PM -static int pd6729_socket_suspend(struct pci_dev *dev, pm_message_t state) -{ -	return pcmcia_socket_dev_suspend(&dev->dev); -} - -static int pd6729_socket_resume(struct pci_dev *dev) -{ -	return pcmcia_socket_dev_resume(&dev->dev); -} -#endif -  static struct pci_device_id pd6729_pci_ids[] = {  	{  		.vendor		= PCI_VENDOR_ID_CIRRUS, @@ -777,10 +781,6 @@ static struct pci_driver pd6729_pci_driver = {  	.id_table	= pd6729_pci_ids,  	.probe		= pd6729_pci_probe,  	.remove		= __devexit_p(pd6729_pci_remove), -#ifdef CONFIG_PM -	.suspend	= pd6729_socket_suspend, -	.resume		= pd6729_socket_resume, -#endif  };  static int pd6729_module_init(void) diff --git a/drivers/pcmcia/pxa2xx_base.c b/drivers/pcmcia/pxa2xx_base.c index 76e640bccde..df4532e91b1 100644 --- a/drivers/pcmcia/pxa2xx_base.c +++ b/drivers/pcmcia/pxa2xx_base.c @@ -17,6 +17,7 @@    ======================================================================*/  #include <linux/module.h> +#include <linux/slab.h>  #include <linux/init.h>  #include <linux/cpufreq.h>  #include <linux/ioport.h> @@ -325,19 +326,13 @@ static int pxa2xx_drv_pcmcia_remove(struct platform_device *dev)  	return 0;  } -static int pxa2xx_drv_pcmcia_suspend(struct device *dev) -{ -	return pcmcia_socket_dev_suspend(dev); -} -  static int pxa2xx_drv_pcmcia_resume(struct device *dev)  {  	pxa2xx_configure_sockets(dev); -	return pcmcia_socket_dev_resume(dev); +	return 0;  }  static const struct dev_pm_ops pxa2xx_drv_pcmcia_pm_ops = { -	.suspend	= pxa2xx_drv_pcmcia_suspend,  	.resume		= pxa2xx_drv_pcmcia_resume,  }; diff --git a/drivers/pcmcia/rsrc_mgr.c b/drivers/pcmcia/rsrc_mgr.c index 452c83b512c..ffa5f3cae57 100644 --- a/drivers/pcmcia/rsrc_mgr.c +++ b/drivers/pcmcia/rsrc_mgr.c @@ -12,6 +12,7 @@   * (C) 1999		David A. Hinds   */ +#include <linux/slab.h>  #include <linux/module.h>  #include <linux/kernel.h> diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c index 4663b3fa9f9..a6eb7b59ba9 100644 --- a/drivers/pcmcia/rsrc_nonstatic.c +++ b/drivers/pcmcia/rsrc_nonstatic.c @@ -214,7 +214,7 @@ static void do_io_probe(struct pcmcia_socket *s, unsigned int base,  		return;  	}  	for (i = base, most = 0; i < base+num; i += 8) { -		res = claim_region(NULL, i, 8, IORESOURCE_IO, "PCMCIA ioprobe"); +		res = claim_region(s, i, 8, IORESOURCE_IO, "PCMCIA ioprobe");  		if (!res)  			continue;  		hole = inb(i); @@ -231,9 +231,14 @@ static void do_io_probe(struct pcmcia_socket *s, unsigned int base,  	bad = any = 0;  	for (i = base; i < base+num; i += 8) { -		res = claim_region(NULL, i, 8, IORESOURCE_IO, "PCMCIA ioprobe"); -		if (!res) +		res = claim_region(s, i, 8, IORESOURCE_IO, "PCMCIA ioprobe"); +		if (!res) { +			if (!any) +				printk(" excluding"); +			if (!bad) +				bad = any = i;  			continue; +		}  		for (j = 0; j < 8; j++)  			if (inb(i+j) != most)  				break; @@ -253,6 +258,7 @@ static void do_io_probe(struct pcmcia_socket *s, unsigned int base,  	}  	if (bad) {  		if ((num > 16) && (bad == base) && (i == base+num)) { +			sub_interval(&s_data->io_db, bad, i-bad);  			printk(" nothing: probe failed.\n");  			return;  		} else { @@ -596,19 +602,17 @@ struct pcmcia_align_data {  	struct resource_map	*map;  }; -static resource_size_t -pcmcia_common_align(void *align_data, const struct resource *res, -			resource_size_t size, resource_size_t align) +static resource_size_t pcmcia_common_align(struct pcmcia_align_data *align_data, +					resource_size_t start)  { -	struct pcmcia_align_data *data = align_data; -	resource_size_t start; +	resource_size_t ret;  	/*  	 * Ensure that we have the correct start address  	 */ -	start = (res->start & ~data->mask) + data->offset; -	if (start < res->start) -		start += data->mask + 1; -	return start; +	ret = (start & ~align_data->mask) + align_data->offset; +	if (ret < start) +		ret += align_data->mask + 1; +	return ret;  }  static resource_size_t @@ -619,29 +623,28 @@ pcmcia_align(void *align_data, const struct resource *res,  	struct resource_map *m;  	resource_size_t start; -	start = pcmcia_common_align(data, res, size, align); +	start = pcmcia_common_align(data, res->start);  	for (m = data->map->next; m != data->map; m = m->next) { -		unsigned long start = m->base; -		unsigned long end = m->base + m->num - 1; +		unsigned long map_start = m->base; +		unsigned long map_end = m->base + m->num - 1;  		/*  		 * If the lower resources are not available, try aligning  		 * to this entry of the resource database to see if it'll  		 * fit here.  		 */ -		if (res->start < start) { -			start = pcmcia_common_align(data, res, size, align); -		} +		if (start < map_start) +			start = pcmcia_common_align(data, map_start);  		/*  		 * If we're above the area which was passed in, there's  		 * no point proceeding.  		 */ -		if (res->start >= res->end) +		if (start >= res->end)  			break; -		if ((res->start + size - 1) <= end) +		if ((start + size - 1) <= map_end)  			break;  	} @@ -807,9 +810,18 @@ static int adjust_memory(struct pcmcia_socket *s, unsigned int action, unsigned  static int adjust_io(struct pcmcia_socket *s, unsigned int action, unsigned long start, unsigned long end)  {  	struct socket_data *data = s->resource_data; -	unsigned long size = end - start + 1; +	unsigned long size;  	int ret = 0; +#if defined(CONFIG_X86) +	/* on x86, avoid anything < 0x100 for it is often used for +	 * legacy platform devices */ +	if (start < 0x100) +		start = 0x100; +#endif + +	size = end - start + 1; +  	if (end < start)  		return -EINVAL; @@ -867,10 +879,8 @@ static int nonstatic_autoadd_resources(struct pcmcia_socket *s)  			if (res == &ioport_resource)  				continue;  			dev_printk(KERN_INFO, &s->cb_dev->dev, -				   "pcmcia: parent PCI bridge I/O " -				   "window: 0x%llx - 0x%llx\n", -				   (unsigned long long)res->start, -				   (unsigned long long)res->end); +				   "pcmcia: parent PCI bridge window: %pR\n", +				   res);  			if (!adjust_io(s, ADD_MANAGED_RESOURCE, res->start, res->end))  				done |= IORESOURCE_IO; @@ -880,10 +890,8 @@ static int nonstatic_autoadd_resources(struct pcmcia_socket *s)  			if (res == &iomem_resource)  				continue;  			dev_printk(KERN_INFO, &s->cb_dev->dev, -				   "pcmcia: parent PCI bridge Memory " -				   "window: 0x%llx - 0x%llx\n", -				   (unsigned long long)res->start, -				   (unsigned long long)res->end); +				   "pcmcia: parent PCI bridge window: %pR\n", +				   res);  			if (!adjust_memory(s, ADD_MANAGED_RESOURCE, res->start, res->end))  				done |= IORESOURCE_MEM;  		} diff --git a/drivers/pcmcia/sa1100_generic.c b/drivers/pcmcia/sa1100_generic.c index 8db86b90c20..edbd8c47262 100644 --- a/drivers/pcmcia/sa1100_generic.c +++ b/drivers/pcmcia/sa1100_generic.c @@ -32,6 +32,7 @@  #include <linux/module.h>  #include <linux/init.h> +#include <linux/slab.h>  #include <linux/platform_device.h>  #include <pcmcia/cs_types.h> @@ -95,17 +96,6 @@ static int sa11x0_drv_pcmcia_remove(struct platform_device *dev)  	return 0;  } -static int sa11x0_drv_pcmcia_suspend(struct platform_device *dev, -				     pm_message_t state) -{ -	return pcmcia_socket_dev_suspend(&dev->dev); -} - -static int sa11x0_drv_pcmcia_resume(struct platform_device *dev) -{ -	return pcmcia_socket_dev_resume(&dev->dev); -} -  static struct platform_driver sa11x0_pcmcia_driver = {  	.driver = {  		.name		= "sa11x0-pcmcia", @@ -113,8 +103,6 @@ static struct platform_driver sa11x0_pcmcia_driver = {  	},  	.probe		= sa11x0_drv_pcmcia_probe,  	.remove		= sa11x0_drv_pcmcia_remove, -	.suspend 	= sa11x0_drv_pcmcia_suspend, -	.resume 	= sa11x0_drv_pcmcia_resume,  };  /* sa11x0_pcmcia_init() diff --git a/drivers/pcmcia/sa1111_generic.c b/drivers/pcmcia/sa1111_generic.c index de6bc333d29..59866905ea3 100644 --- a/drivers/pcmcia/sa1111_generic.c +++ b/drivers/pcmcia/sa1111_generic.c @@ -12,6 +12,7 @@  #include <linux/interrupt.h>  #include <linux/init.h>  #include <linux/io.h> +#include <linux/slab.h>  #include <pcmcia/ss.h> @@ -21,11 +22,18 @@  #include "sa1111_generic.h" +#define IDX_IRQ_S0_READY_NINT	(0) +#define IDX_IRQ_S0_CD_VALID	(1) +#define IDX_IRQ_S0_BVD1_STSCHG	(2) +#define IDX_IRQ_S1_READY_NINT	(3) +#define IDX_IRQ_S1_CD_VALID	(4) +#define IDX_IRQ_S1_BVD1_STSCHG	(5) +  static struct pcmcia_irqs irqs[] = { -	{ 0, IRQ_S0_CD_VALID,    "SA1111 PCMCIA card detect" }, -	{ 0, IRQ_S0_BVD1_STSCHG, "SA1111 PCMCIA BVD1"        }, -	{ 1, IRQ_S1_CD_VALID,    "SA1111 CF card detect"     }, -	{ 1, IRQ_S1_BVD1_STSCHG, "SA1111 CF BVD1"            }, +	{ 0, NO_IRQ, "SA1111 PCMCIA card detect" }, +	{ 0, NO_IRQ, "SA1111 PCMCIA BVD1"        }, +	{ 1, NO_IRQ, "SA1111 CF card detect"     }, +	{ 1, NO_IRQ, "SA1111 CF BVD1"            },  };  static int sa1111_pcmcia_hw_init(struct soc_pcmcia_socket *skt) @@ -136,7 +144,9 @@ int sa1111_pcmcia_add(struct sa1111_dev *dev, struct pcmcia_low_level *ops,  		s->soc.ops = ops;  		s->soc.socket.owner = ops->owner;  		s->soc.socket.dev.parent = &dev->dev; -		s->soc.socket.pci_irq = s->soc.nr ? IRQ_S1_READY_NINT : IRQ_S0_READY_NINT; +		s->soc.socket.pci_irq = s->soc.nr ? +				dev->irq[IDX_IRQ_S0_READY_NINT] : +				dev->irq[IDX_IRQ_S1_READY_NINT];  		s->dev = dev;  		ret = add(&s->soc); @@ -162,6 +172,12 @@ static int pcmcia_probe(struct sa1111_dev *dev)  	base = dev->mapbase; +	/* Initialize PCMCIA IRQs */ +	irqs[0].irq = dev->irq[IDX_IRQ_S0_CD_VALID]; +	irqs[1].irq = dev->irq[IDX_IRQ_S0_BVD1_STSCHG]; +	irqs[2].irq = dev->irq[IDX_IRQ_S1_CD_VALID]; +	irqs[3].irq = dev->irq[IDX_IRQ_S1_BVD1_STSCHG]; +  	/*  	 * Initialise the suspend state.  	 */ @@ -198,16 +214,6 @@ static int __devexit pcmcia_remove(struct sa1111_dev *dev)  	return 0;  } -static int pcmcia_suspend(struct sa1111_dev *dev, pm_message_t state) -{ -	return pcmcia_socket_dev_suspend(&dev->dev); -} - -static int pcmcia_resume(struct sa1111_dev *dev) -{ -	return pcmcia_socket_dev_resume(&dev->dev); -} -  static struct sa1111_driver pcmcia_driver = {  	.drv = {  		.name	= "sa1111-pcmcia", @@ -215,8 +221,6 @@ static struct sa1111_driver pcmcia_driver = {  	.devid		= SA1111_DEVID_PCMCIA,  	.probe		= pcmcia_probe,  	.remove		= __devexit_p(pcmcia_remove), -	.suspend	= pcmcia_suspend, -	.resume		= pcmcia_resume,  };  static int __init sa1111_drv_pcmcia_init(void) diff --git a/drivers/pcmcia/sa11xx_base.c b/drivers/pcmcia/sa11xx_base.c index fc9a6527019..fa28d8911b0 100644 --- a/drivers/pcmcia/sa11xx_base.c +++ b/drivers/pcmcia/sa11xx_base.c @@ -37,6 +37,7 @@  #include <linux/kernel.h>  #include <linux/spinlock.h>  #include <linux/io.h> +#include <linux/slab.h>  #include <mach/hardware.h>  #include <asm/irq.h> diff --git a/drivers/pcmcia/socket_sysfs.c b/drivers/pcmcia/socket_sysfs.c index 08278016e58..80e36bc407d 100644 --- a/drivers/pcmcia/socket_sysfs.c +++ b/drivers/pcmcia/socket_sysfs.c @@ -15,7 +15,6 @@  #include <linux/string.h>  #include <linux/major.h>  #include <linux/errno.h> -#include <linux/slab.h>  #include <linux/mm.h>  #include <linux/interrupt.h>  #include <linux/timer.h> diff --git a/drivers/pcmcia/tcic.c b/drivers/pcmcia/tcic.c index 12c49ee135e..56004a1b5bb 100644 --- a/drivers/pcmcia/tcic.c +++ b/drivers/pcmcia/tcic.c @@ -39,7 +39,6 @@  #include <linux/string.h>  #include <linux/errno.h>  #include <linux/interrupt.h> -#include <linux/slab.h>  #include <linux/timer.h>  #include <linux/ioport.h>  #include <linux/delay.h> @@ -348,16 +347,6 @@ static int __init get_tcic_id(void)      return id;  } -static int tcic_drv_pcmcia_suspend(struct platform_device *dev, -				     pm_message_t state) -{ -	return pcmcia_socket_dev_suspend(&dev->dev); -} - -static int tcic_drv_pcmcia_resume(struct platform_device *dev) -{ -	return pcmcia_socket_dev_resume(&dev->dev); -}  /*====================================================================*/  static struct platform_driver tcic_driver = { @@ -365,8 +354,6 @@ static struct platform_driver tcic_driver = {  		.name = "tcic-pcmcia",  		.owner		= THIS_MODULE,  	}, -	.suspend 	= tcic_drv_pcmcia_suspend, -	.resume 	= tcic_drv_pcmcia_resume,  };  static struct platform_device tcic_device = { diff --git a/drivers/pcmcia/ti113x.h b/drivers/pcmcia/ti113x.h index aaa70227bfb..9ffa97d0b16 100644 --- a/drivers/pcmcia/ti113x.h +++ b/drivers/pcmcia/ti113x.h @@ -296,7 +296,7 @@ static int ti_init(struct yenta_socket *socket)  	u8 new, reg = exca_readb(socket, I365_INTCTL);  	new = reg & ~I365_INTR_ENA; -	if (socket->cb_irq) +	if (socket->dev->irq)  		new |= I365_INTR_ENA;  	if (new != reg)  		exca_writeb(socket, I365_INTCTL, new); @@ -316,14 +316,47 @@ static int ti_override(struct yenta_socket *socket)  	return 0;  } +static void ti113x_use_isa_irq(struct yenta_socket *socket) +{ +	int isa_irq = -1; +	u8 intctl; +	u32 isa_irq_mask = 0; + +	if (!isa_probe) +		return; + +	/* get a free isa int */ +	isa_irq_mask = yenta_probe_irq(socket, isa_interrupts); +	if (!isa_irq_mask) +		return; /* no useable isa irq found */ + +	/* choose highest available */ +	for (; isa_irq_mask; isa_irq++) +		isa_irq_mask >>= 1; +	socket->cb_irq = isa_irq; + +	exca_writeb(socket, I365_CSCINT, (isa_irq << 4)); + +	intctl = exca_readb(socket, I365_INTCTL); +	intctl &= ~(I365_INTR_ENA | I365_IRQ_MASK);     /* CSC Enable */ +	exca_writeb(socket, I365_INTCTL, intctl); + +	dev_info(&socket->dev->dev, +		"Yenta TI113x: using isa irq %d for CardBus\n", isa_irq); +} + +  static int ti113x_override(struct yenta_socket *socket)  {  	u8 cardctl;  	cardctl = config_readb(socket, TI113X_CARD_CONTROL);  	cardctl &= ~(TI113X_CCR_PCI_IRQ_ENA | TI113X_CCR_PCI_IREQ | TI113X_CCR_PCI_CSC); -	if (socket->cb_irq) +	if (socket->dev->irq)  		cardctl |= TI113X_CCR_PCI_IRQ_ENA | TI113X_CCR_PCI_CSC | TI113X_CCR_PCI_IREQ; +	else +		ti113x_use_isa_irq(socket); +  	config_writeb(socket, TI113X_CARD_CONTROL, cardctl);  	return ti_override(socket); diff --git a/drivers/pcmcia/vrc4171_card.c b/drivers/pcmcia/vrc4171_card.c index c9fcbdc164e..86e4a1a3c64 100644 --- a/drivers/pcmcia/vrc4171_card.c +++ b/drivers/pcmcia/vrc4171_card.c @@ -105,6 +105,7 @@ typedef struct vrc4171_socket {  	char name[24];  	int csc_irq;  	int io_irq; +	spinlock_t lock;  } vrc4171_socket_t;  static vrc4171_socket_t vrc4171_sockets[CARD_MAX_SLOTS]; @@ -327,7 +328,7 @@ static int pccard_set_socket(struct pcmcia_socket *sock, socket_state_t *state)  	slot = sock->sock;  	socket = &vrc4171_sockets[slot]; -	spin_lock_irq(&sock->lock); +	spin_lock_irq(&socket->lock);  	voltage = set_Vcc_value(state->Vcc);  	exca_write_byte(slot, CARD_VOLTAGE_SELECT, voltage); @@ -370,7 +371,7 @@ static int pccard_set_socket(struct pcmcia_socket *sock, socket_state_t *state)  		cscint |= I365_CSC_DETECT;          exca_write_byte(slot, I365_CSCINT, cscint); -	spin_unlock_irq(&sock->lock); +	spin_unlock_irq(&socket->lock);  	return 0;  } @@ -704,24 +705,11 @@ static int __devinit vrc4171_card_setup(char *options)  __setup("vrc4171_card=", vrc4171_card_setup); -static int vrc4171_card_suspend(struct platform_device *dev, -				     pm_message_t state) -{ -	return pcmcia_socket_dev_suspend(&dev->dev); -} - -static int vrc4171_card_resume(struct platform_device *dev) -{ -	return pcmcia_socket_dev_resume(&dev->dev); -} -  static struct platform_driver vrc4171_card_driver = {  	.driver = {  		.name		= vrc4171_card_name,  		.owner		= THIS_MODULE,  	}, -	.suspend	= vrc4171_card_suspend, -	.resume		= vrc4171_card_resume,  };  static int __devinit vrc4171_card_init(void) diff --git a/drivers/pcmcia/xxs1500_ss.c b/drivers/pcmcia/xxs1500_ss.c index f9009d34254..201ccfa1e97 100644 --- a/drivers/pcmcia/xxs1500_ss.c +++ b/drivers/pcmcia/xxs1500_ss.c @@ -14,6 +14,7 @@  #include <linux/platform_device.h>  #include <linux/pm.h>  #include <linux/resource.h> +#include <linux/slab.h>  #include <linux/spinlock.h>  #include <pcmcia/cs_types.h> diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c index 967c766f53b..83ace277426 100644 --- a/drivers/pcmcia/yenta_socket.c +++ b/drivers/pcmcia/yenta_socket.c @@ -17,6 +17,7 @@  #include <linux/delay.h>  #include <linux/module.h>  #include <linux/io.h> +#include <linux/slab.h>  #include <pcmcia/cs_types.h>  #include <pcmcia/ss.h> @@ -42,6 +43,18 @@ module_param_string(o2_speedup, o2_speedup, sizeof(o2_speedup), 0444);  MODULE_PARM_DESC(o2_speedup, "Use prefetch/burst for O2-bridges: 'on', 'off' "  	"or 'default' (uses recommended behaviour for the detected bridge)"); +/* + * Only probe "regular" interrupts, don't + * touch dangerous spots like the mouse irq, + * because there are mice that apparently + * get really confused if they get fondled + * too intimately. + * + * Default to 11, 10, 9, 7, 6, 5, 4, 3. + */ +static u32 isa_interrupts = 0x0ef8; + +  #define debug(x, s, args...) dev_dbg(&s->dev->dev, x, ##args)  /* Don't ask.. */ @@ -54,6 +67,8 @@ MODULE_PARM_DESC(o2_speedup, "Use prefetch/burst for O2-bridges: 'on', 'off' "   */  #ifdef CONFIG_YENTA_TI  static int yenta_probe_cb_irq(struct yenta_socket *socket); +static unsigned int yenta_probe_irq(struct yenta_socket *socket, +				u32 isa_irq_mask);  #endif @@ -329,8 +344,8 @@ static int yenta_set_socket(struct pcmcia_socket *sock, socket_state_t *state)  		/* ISA interrupt control? */  		intr = exca_readb(socket, I365_INTCTL);  		intr = (intr & ~0xf); -		if (!socket->cb_irq) { -			intr |= state->io_irq; +		if (!socket->dev->irq) { +			intr |= socket->cb_irq ? socket->cb_irq : state->io_irq;  			bridge |= CB_BRIDGE_INTR;  		}  		exca_writeb(socket, I365_INTCTL, intr); @@ -340,7 +355,7 @@ static int yenta_set_socket(struct pcmcia_socket *sock, socket_state_t *state)  		reg = exca_readb(socket, I365_INTCTL) & (I365_RING_ENA | I365_INTR_ENA);  		reg |= (state->flags & SS_RESET) ? 0 : I365_PC_RESET;  		reg |= (state->flags & SS_IOCARD) ? I365_PC_IOCARD : 0; -		if (state->io_irq != socket->cb_irq) { +		if (state->io_irq != socket->dev->irq) {  			reg |= state->io_irq;  			bridge |= CB_BRIDGE_INTR;  		} @@ -356,7 +371,9 @@ static int yenta_set_socket(struct pcmcia_socket *sock, socket_state_t *state)  			exca_writeb(socket, I365_POWER, reg);  		/* CSC interrupt: no ISA irq for CSC */ -		reg = I365_CSC_DETECT; +		reg = exca_readb(socket, I365_CSCINT); +		reg &= I365_CSC_IRQ_MASK; +		reg |= I365_CSC_DETECT;  		if (state->flags & SS_IOCARD) {  			if (state->csc_mask & SS_STSCHG)  				reg |= I365_CSC_STSCHG; @@ -896,22 +913,12 @@ static struct cardbus_type cardbus_type[] = {  }; -/* - * Only probe "regular" interrupts, don't - * touch dangerous spots like the mouse irq, - * because there are mice that apparently - * get really confused if they get fondled - * too intimately. - * - * Default to 11, 10, 9, 7, 6, 5, 4, 3. - */ -static u32 isa_interrupts = 0x0ef8; -  static unsigned int yenta_probe_irq(struct yenta_socket *socket, u32 isa_irq_mask)  {  	int i;  	unsigned long val;  	u32 mask; +	u8 reg;  	/*  	 * Probe for usable interrupts using the force @@ -919,6 +926,7 @@ static unsigned int yenta_probe_irq(struct yenta_socket *socket, u32 isa_irq_mas  	 */  	cb_writel(socket, CB_SOCKET_EVENT, -1);  	cb_writel(socket, CB_SOCKET_MASK, CB_CSTSMASK); +	reg = exca_readb(socket, I365_CSCINT);  	exca_writeb(socket, I365_CSCINT, 0);  	val = probe_irq_on() & isa_irq_mask;  	for (i = 1; i < 16; i++) { @@ -930,7 +938,7 @@ static unsigned int yenta_probe_irq(struct yenta_socket *socket, u32 isa_irq_mas  		cb_writel(socket, CB_SOCKET_EVENT, -1);  	}  	cb_writel(socket, CB_SOCKET_MASK, 0); -	exca_writeb(socket, I365_CSCINT, 0); +	exca_writeb(socket, I365_CSCINT, reg);  	mask = probe_irq_mask(val) & 0xffff; @@ -967,6 +975,8 @@ static irqreturn_t yenta_probe_handler(int irq, void *dev_id)  /* probes the PCI interrupt, use only on override functions */  static int yenta_probe_cb_irq(struct yenta_socket *socket)  { +	u8 reg; +  	if (!socket->cb_irq)  		return -1; @@ -979,7 +989,8 @@ static int yenta_probe_cb_irq(struct yenta_socket *socket)  	}  	/* generate interrupt, wait */ -	exca_writeb(socket, I365_CSCINT, I365_CSC_STSCHG); +	reg = exca_readb(socket, I365_CSCINT); +	exca_writeb(socket, I365_CSCINT, reg | I365_CSC_STSCHG);  	cb_writel(socket, CB_SOCKET_EVENT, -1);  	cb_writel(socket, CB_SOCKET_MASK, CB_CSTSMASK);  	cb_writel(socket, CB_SOCKET_FORCE, CB_FCARDSTS); @@ -988,7 +999,7 @@ static int yenta_probe_cb_irq(struct yenta_socket *socket)  	/* disable interrupts */  	cb_writel(socket, CB_SOCKET_MASK, 0); -	exca_writeb(socket, I365_CSCINT, 0); +	exca_writeb(socket, I365_CSCINT, reg);  	cb_writel(socket, CB_SOCKET_EVENT, -1);  	exca_readb(socket, I365_CSC); @@ -1280,12 +1291,9 @@ static int yenta_dev_suspend_noirq(struct device *dev)  {  	struct pci_dev *pdev = to_pci_dev(dev);  	struct yenta_socket *socket = pci_get_drvdata(pdev); -	int ret; - -	ret = pcmcia_socket_dev_suspend(dev);  	if (!socket) -		return ret; +		return 0;  	if (socket->type && socket->type->save_state)  		socket->type->save_state(socket); @@ -1302,7 +1310,7 @@ static int yenta_dev_suspend_noirq(struct device *dev)  	 */  	/* pci_set_power_state(dev, 3); */ -	return ret; +	return 0;  }  static int yenta_dev_resume_noirq(struct device *dev) @@ -1326,26 +1334,16 @@ static int yenta_dev_resume_noirq(struct device *dev)  	if (socket->type && socket->type->restore_state)  		socket->type->restore_state(socket); -	pcmcia_socket_dev_early_resume(dev); -	return 0; -} - -static int yenta_dev_resume(struct device *dev) -{ -	pcmcia_socket_dev_late_resume(dev);  	return 0;  }  static const struct dev_pm_ops yenta_pm_ops = {  	.suspend_noirq = yenta_dev_suspend_noirq,  	.resume_noirq = yenta_dev_resume_noirq, -	.resume = yenta_dev_resume,  	.freeze_noirq = yenta_dev_suspend_noirq,  	.thaw_noirq = yenta_dev_resume_noirq, -	.thaw = yenta_dev_resume,  	.poweroff_noirq = yenta_dev_suspend_noirq,  	.restore_noirq = yenta_dev_resume_noirq, -	.restore = yenta_dev_resume,  };  #define YENTA_PM_OPS	(¥ta_pm_ops)  |