aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/ufs/ufshcd-pltfrm.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-09-03 15:48:06 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2013-09-03 15:48:06 -0700
commitf66c83d059d1ed90968caa81d401f160912b063a (patch)
tree8558803eadc5c29038de16d88b02b4f6176850ac /drivers/scsi/ufs/ufshcd-pltfrm.c
parentlockref: Relax in cmpxchg loop (diff)
parent[SCSI] sg: push file descriptor list locking down to per-device locking (diff)
downloadlinux-dev-f66c83d059d1ed90968caa81d401f160912b063a.tar.xz
linux-dev-f66c83d059d1ed90968caa81d401f160912b063a.zip
Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
Pull first round of SCSI updates from James Bottomley: "This patch set is a set of driver updates (ufs, zfcp, lpfc, mpt2/3sas, qla4xxx, qla2xxx [adding support for ISP8044 + other things]). We also have a new driver: esas2r which has a number of static checker problems, but which I expect to resolve over the -rc course of 3.12 under the new driver exception. We also have the error return that were discussed at LSF" * tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (118 commits) [SCSI] sg: push file descriptor list locking down to per-device locking [SCSI] sg: checking sdp->detached isn't protected when open [SCSI] sg: no need sg_open_exclusive_lock [SCSI] sg: use rwsem to solve race during exclusive open [SCSI] scsi_debug: fix logical block provisioning support when unmap_alignment != 0 [SCSI] scsi_debug: fix endianness bug in sdebug_build_parts() [SCSI] qla2xxx: Update the driver version to 8.06.00.08-k. [SCSI] qla2xxx: print MAC via %pMR. [SCSI] qla2xxx: Correction to message ids. [SCSI] qla2xxx: Correctly print out/in mailbox registers. [SCSI] qla2xxx: Add a new interface to update versions. [SCSI] qla2xxx: Move queue depth ramp down message to i/o debug level. [SCSI] qla2xxx: Select link initialization option bits from current operating mode. [SCSI] qla2xxx: Add loopback IDC-TIME-EXTEND aen handling support. [SCSI] qla2xxx: Set default critical temperature value in cases when ISPFX00 firmware doesn't provide it [SCSI] qla2xxx: QLAFX00 make over temperature AEN handling informational, add log for normal temperature AEN [SCSI] qla2xxx: Correct Interrupt Register offset for ISPFX00 [SCSI] qla2xxx: Remove handling of Shutdown Requested AEN from qlafx00_process_aen(). [SCSI] qla2xxx: Send all AENs for ISPFx00 to above layers. [SCSI] qla2xxx: Add changes in initialization for ISPFX00 cards with BIOS ...
Diffstat (limited to 'drivers/scsi/ufs/ufshcd-pltfrm.c')
-rw-r--r--drivers/scsi/ufs/ufshcd-pltfrm.c57
1 files changed, 48 insertions, 9 deletions
diff --git a/drivers/scsi/ufs/ufshcd-pltfrm.c b/drivers/scsi/ufs/ufshcd-pltfrm.c
index c42db40d4e51..5e4623225422 100644
--- a/drivers/scsi/ufs/ufshcd-pltfrm.c
+++ b/drivers/scsi/ufs/ufshcd-pltfrm.c
@@ -34,6 +34,7 @@
*/
#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
#include "ufshcd.h"
@@ -87,6 +88,40 @@ static int ufshcd_pltfrm_resume(struct device *dev)
#define ufshcd_pltfrm_resume NULL
#endif
+#ifdef CONFIG_PM_RUNTIME
+static int ufshcd_pltfrm_runtime_suspend(struct device *dev)
+{
+ struct ufs_hba *hba = dev_get_drvdata(dev);
+
+ if (!hba)
+ return 0;
+
+ return ufshcd_runtime_suspend(hba);
+}
+static int ufshcd_pltfrm_runtime_resume(struct device *dev)
+{
+ struct ufs_hba *hba = dev_get_drvdata(dev);
+
+ if (!hba)
+ return 0;
+
+ return ufshcd_runtime_resume(hba);
+}
+static int ufshcd_pltfrm_runtime_idle(struct device *dev)
+{
+ struct ufs_hba *hba = dev_get_drvdata(dev);
+
+ if (!hba)
+ return 0;
+
+ return ufshcd_runtime_idle(hba);
+}
+#else /* !CONFIG_PM_RUNTIME */
+#define ufshcd_pltfrm_runtime_suspend NULL
+#define ufshcd_pltfrm_runtime_resume NULL
+#define ufshcd_pltfrm_runtime_idle NULL
+#endif /* CONFIG_PM_RUNTIME */
+
/**
* ufshcd_pltfrm_probe - probe routine of the driver
* @pdev: pointer to Platform device handle
@@ -102,15 +137,8 @@ static int ufshcd_pltfrm_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!mem_res) {
- dev_err(dev, "Memory resource not available\n");
- err = -ENODEV;
- goto out;
- }
-
mmio_base = devm_ioremap_resource(dev, mem_res);
if (IS_ERR(mmio_base)) {
- dev_err(dev, "memory map failed\n");
err = PTR_ERR(mmio_base);
goto out;
}
@@ -122,14 +150,22 @@ static int ufshcd_pltfrm_probe(struct platform_device *pdev)
goto out;
}
+ pm_runtime_set_active(&pdev->dev);
+ pm_runtime_enable(&pdev->dev);
+
err = ufshcd_init(dev, &hba, mmio_base, irq);
if (err) {
dev_err(dev, "Intialization failed\n");
- goto out;
+ goto out_disable_rpm;
}
platform_set_drvdata(pdev, hba);
+ return 0;
+
+out_disable_rpm:
+ pm_runtime_disable(&pdev->dev);
+ pm_runtime_set_suspended(&pdev->dev);
out:
return err;
}
@@ -144,7 +180,7 @@ static int ufshcd_pltfrm_remove(struct platform_device *pdev)
{
struct ufs_hba *hba = platform_get_drvdata(pdev);
- disable_irq(hba->irq);
+ pm_runtime_get_sync(&(pdev)->dev);
ufshcd_remove(hba);
return 0;
}
@@ -157,6 +193,9 @@ static const struct of_device_id ufs_of_match[] = {
static const struct dev_pm_ops ufshcd_dev_pm_ops = {
.suspend = ufshcd_pltfrm_suspend,
.resume = ufshcd_pltfrm_resume,
+ .runtime_suspend = ufshcd_pltfrm_runtime_suspend,
+ .runtime_resume = ufshcd_pltfrm_runtime_resume,
+ .runtime_idle = ufshcd_pltfrm_runtime_idle,
};
static struct platform_driver ufshcd_pltfrm_driver = {