|
@@ -26,6 +26,8 @@ struct scoop_pcmcia_dev *scoop_devs;
|
|
|
struct scoop_dev {
|
|
|
void *base;
|
|
|
spinlock_t scoop_lock;
|
|
|
+ unsigned short suspend_clr;
|
|
|
+ unsigned short suspend_set;
|
|
|
u32 scoop_gpwr;
|
|
|
};
|
|
|
|
|
@@ -90,14 +92,24 @@ EXPORT_SYMBOL(reset_scoop);
|
|
|
EXPORT_SYMBOL(read_scoop_reg);
|
|
|
EXPORT_SYMBOL(write_scoop_reg);
|
|
|
|
|
|
+static void check_scoop_reg(struct scoop_dev *sdev)
|
|
|
+{
|
|
|
+ unsigned short mcr;
|
|
|
+
|
|
|
+ mcr = SCOOP_REG(sdev->base, SCOOP_MCR);
|
|
|
+ if ((mcr & 0x100) == 0)
|
|
|
+ SCOOP_REG(sdev->base, SCOOP_MCR) = 0x0101;
|
|
|
+}
|
|
|
+
|
|
|
#ifdef CONFIG_PM
|
|
|
static int scoop_suspend(struct device *dev, pm_message_t state, uint32_t level)
|
|
|
{
|
|
|
if (level == SUSPEND_POWER_DOWN) {
|
|
|
struct scoop_dev *sdev = dev_get_drvdata(dev);
|
|
|
|
|
|
- sdev->scoop_gpwr = SCOOP_REG(sdev->base,SCOOP_GPWR);
|
|
|
- SCOOP_REG(sdev->base,SCOOP_GPWR) = 0;
|
|
|
+ check_scoop_reg(sdev);
|
|
|
+ sdev->scoop_gpwr = SCOOP_REG(sdev->base, SCOOP_GPWR);
|
|
|
+ SCOOP_REG(sdev->base, SCOOP_GPWR) = (sdev->scoop_gpwr & ~sdev->suspend_clr) | sdev->suspend_set;
|
|
|
}
|
|
|
return 0;
|
|
|
}
|
|
@@ -107,6 +119,7 @@ static int scoop_resume(struct device *dev, uint32_t level)
|
|
|
if (level == RESUME_POWER_ON) {
|
|
|
struct scoop_dev *sdev = dev_get_drvdata(dev);
|
|
|
|
|
|
+ check_scoop_reg(sdev);
|
|
|
SCOOP_REG(sdev->base,SCOOP_GPWR) = sdev->scoop_gpwr;
|
|
|
}
|
|
|
return 0;
|
|
@@ -151,6 +164,9 @@ int __init scoop_probe(struct device *dev)
|
|
|
SCOOP_REG(devptr->base, SCOOP_GPCR) = inf->io_dir & 0xffff;
|
|
|
SCOOP_REG(devptr->base, SCOOP_GPWR) = inf->io_out & 0xffff;
|
|
|
|
|
|
+ devptr->suspend_clr = inf->suspend_clr;
|
|
|
+ devptr->suspend_set = inf->suspend_set;
|
|
|
+
|
|
|
return 0;
|
|
|
}
|
|
|
|