Skip to content

Commit

Permalink
ARM: sa1111: fix pcmcia suspend/resume
Browse files Browse the repository at this point in the history
BugLink: http://bugs.launchpad.net/bugs/1631468

commit 06dfe5c upstream.

SA1111 PCMCIA was broken when PCMCIA switched to using dev_pm_ops for
the PCMCIA socket class.  PCMCIA used to handle suspend/resume via the
socket hosting device, which happened at normal device suspend/resume
time.

However, the referenced commit changed this: much of the resume now
happens much earlier, in the noirq resume handler of dev_pm_ops.

However, on SA1111, the PCMCIA device is not accessible as the SA1111
has not been resumed at _noirq time.  It's slightly worse than that,
because the SA1111 has already been put to sleep at _noirq time, so
suspend doesn't work properly.

Fix this by converting the core SA1111 code to use dev_pm_ops as well,
and performing its own suspend/resume at noirq time.

This fixes these errors in the kernel log:

pcmcia_socket pcmcia_socket0: time out after reset
pcmcia_socket pcmcia_socket1: time out after reset

and the resulting lack of PCMCIA cards after a S2RAM cycle.

Fixes: d7646f7 ("pcmcia: use dev_pm_ops for class pcmcia_socket_class")
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

Signed-off-by: Tim Gardner <tim.gardner@canonical.com>
  • Loading branch information
Russell King authored and Seth Forshee committed Oct 20, 2016
1 parent 18ad588 commit 1f4c882
Showing 1 changed file with 13 additions and 9 deletions.
22 changes: 13 additions & 9 deletions arch/arm/common/sa1111.c
Original file line number Diff line number Diff line change
Expand Up @@ -869,9 +869,9 @@ struct sa1111_save_data {

#ifdef CONFIG_PM

static int sa1111_suspend(struct platform_device *dev, pm_message_t state)
static int sa1111_suspend_noirq(struct device *dev)
{
struct sa1111 *sachip = platform_get_drvdata(dev);
struct sa1111 *sachip = dev_get_drvdata(dev);
struct sa1111_save_data *save;
unsigned long flags;
unsigned int val;
Expand Down Expand Up @@ -934,9 +934,9 @@ static int sa1111_suspend(struct platform_device *dev, pm_message_t state)
* restored by their respective drivers, and must be called
* via LDM after this function.
*/
static int sa1111_resume(struct platform_device *dev)
static int sa1111_resume_noirq(struct device *dev)
{
struct sa1111 *sachip = platform_get_drvdata(dev);
struct sa1111 *sachip = dev_get_drvdata(dev);
struct sa1111_save_data *save;
unsigned long flags, id;
void __iomem *base;
Expand All @@ -952,7 +952,7 @@ static int sa1111_resume(struct platform_device *dev)
id = sa1111_readl(sachip->base + SA1111_SKID);
if ((id & SKID_ID_MASK) != SKID_SA1111_ID) {
__sa1111_remove(sachip);
platform_set_drvdata(dev, NULL);
dev_set_drvdata(dev, NULL);
kfree(save);
return 0;
}
Expand Down Expand Up @@ -1003,8 +1003,8 @@ static int sa1111_resume(struct platform_device *dev)
}

#else
#define sa1111_suspend NULL
#define sa1111_resume NULL
#define sa1111_suspend_noirq NULL
#define sa1111_resume_noirq NULL
#endif

static int sa1111_probe(struct platform_device *pdev)
Expand Down Expand Up @@ -1038,6 +1038,11 @@ static int sa1111_remove(struct platform_device *pdev)
return 0;
}

static struct dev_pm_ops sa1111_pm_ops = {
.suspend_noirq = sa1111_suspend_noirq,
.resume_noirq = sa1111_resume_noirq,
};

/*
* Not sure if this should be on the system bus or not yet.
* We really want some way to register a system device at
Expand All @@ -1050,10 +1055,9 @@ static int sa1111_remove(struct platform_device *pdev)
static struct platform_driver sa1111_device_driver = {
.probe = sa1111_probe,
.remove = sa1111_remove,
.suspend = sa1111_suspend,
.resume = sa1111_resume,
.driver = {
.name = "sa1111",
.pm = &sa1111_pm_ops,
},
};

Expand Down

0 comments on commit 1f4c882

Please sign in to comment.