UPSTREAM: ARM: 8478/2: arm/arm64: add arm-smccc
[firefly-linux-kernel-4.4.55.git] / drivers / mfd / intel-lpss.c
index 68aa31ae553a64c2aff19668d7a6e3b8e34c53c4..88e80ec772f6eebb0045cbea0a1ddff84eeb44fc 100644 (file)
@@ -33,6 +33,7 @@
 #define LPSS_DEV_SIZE          0x200
 #define LPSS_PRIV_OFFSET       0x200
 #define LPSS_PRIV_SIZE         0x100
+#define LPSS_PRIV_REG_COUNT    (LPSS_PRIV_SIZE / 4)
 #define LPSS_IDMA64_OFFSET     0x800
 #define LPSS_IDMA64_SIZE       0x800
 
@@ -75,6 +76,7 @@ struct intel_lpss {
        const struct mfd_cell *cell;
        struct device *dev;
        void __iomem *priv;
+       u32 priv_ctx[LPSS_PRIV_REG_COUNT];
        int devid;
        u32 caps;
        u32 active_ltr;
@@ -485,6 +487,16 @@ EXPORT_SYMBOL_GPL(intel_lpss_prepare);
 
 int intel_lpss_suspend(struct device *dev)
 {
+       struct intel_lpss *lpss = dev_get_drvdata(dev);
+       unsigned int i;
+
+       /* Save device context */
+       for (i = 0; i < LPSS_PRIV_REG_COUNT; i++)
+               lpss->priv_ctx[i] = readl(lpss->priv + i * 4);
+
+       /* Put the device into reset state */
+       writel(0, lpss->priv + LPSS_PRIV_RESETS);
+
        return 0;
 }
 EXPORT_SYMBOL_GPL(intel_lpss_suspend);
@@ -492,8 +504,13 @@ EXPORT_SYMBOL_GPL(intel_lpss_suspend);
 int intel_lpss_resume(struct device *dev)
 {
        struct intel_lpss *lpss = dev_get_drvdata(dev);
+       unsigned int i;
 
-       intel_lpss_init_dev(lpss);
+       intel_lpss_deassert_reset(lpss);
+
+       /* Restore device context */
+       for (i = 0; i < LPSS_PRIV_REG_COUNT; i++)
+               writel(lpss->priv_ctx[i], lpss->priv + i * 4);
 
        return 0;
 }