|
@@ -253,3 +253,132 @@ static void samsung_gpio_pm_4bit_con(struct samsung_gpio_chip *chip, int index)
|
|
|
|
|
|
gpcon = old_gpcon & ~mask;
|
|
|
gpcon |= gps_gpcon & mask;
|
|
|
+
|
|
|
+ __raw_writel(gpcon, con);
|
|
|
+}
|
|
|
+
|
|
|
+static void samsung_gpio_pm_4bit_resume(struct samsung_gpio_chip *chip)
|
|
|
+{
|
|
|
+ void __iomem *base = chip->base;
|
|
|
+ u32 old_gpcon[2];
|
|
|
+ u32 old_gpdat = __raw_readl(base + OFFS_DAT);
|
|
|
+ u32 gps_gpdat = chip->pm_save[2];
|
|
|
+
|
|
|
+ /* First, modify the CON settings */
|
|
|
+
|
|
|
+ old_gpcon[0] = 0;
|
|
|
+ old_gpcon[1] = __raw_readl(base + OFFS_CON);
|
|
|
+
|
|
|
+ samsung_gpio_pm_4bit_con(chip, 0);
|
|
|
+ if (chip->chip.ngpio > 8) {
|
|
|
+ old_gpcon[0] = __raw_readl(base - 4);
|
|
|
+ samsung_gpio_pm_4bit_con(chip, -1);
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Now change the configurations that require DAT,CON */
|
|
|
+
|
|
|
+ __raw_writel(chip->pm_save[2], base + OFFS_DAT);
|
|
|
+ __raw_writel(chip->pm_save[1], base + OFFS_CON);
|
|
|
+ if (chip->chip.ngpio > 8)
|
|
|
+ __raw_writel(chip->pm_save[0], base - 4);
|
|
|
+
|
|
|
+ __raw_writel(chip->pm_save[2], base + OFFS_DAT);
|
|
|
+ __raw_writel(chip->pm_save[3], base + OFFS_UP);
|
|
|
+
|
|
|
+ if (chip->chip.ngpio > 8) {
|
|
|
+ S3C_PMDBG("%s: CON4 %08x,%08x => %08x,%08x, DAT %08x => %08x\n",
|
|
|
+ chip->chip.label, old_gpcon[0], old_gpcon[1],
|
|
|
+ __raw_readl(base - 4),
|
|
|
+ __raw_readl(base + OFFS_CON),
|
|
|
+ old_gpdat, gps_gpdat);
|
|
|
+ } else
|
|
|
+ S3C_PMDBG("%s: CON4 %08x => %08x, DAT %08x => %08x\n",
|
|
|
+ chip->chip.label, old_gpcon[1],
|
|
|
+ __raw_readl(base + OFFS_CON),
|
|
|
+ old_gpdat, gps_gpdat);
|
|
|
+}
|
|
|
+
|
|
|
+struct samsung_gpio_pm samsung_gpio_pm_4bit = {
|
|
|
+ .save = samsung_gpio_pm_4bit_save,
|
|
|
+ .resume = samsung_gpio_pm_4bit_resume,
|
|
|
+};
|
|
|
+#endif /* CONFIG_ARCH_S3C64XX || CONFIG_PLAT_S5P */
|
|
|
+
|
|
|
+/**
|
|
|
+ * samsung_pm_save_gpio() - save gpio chip data for suspend
|
|
|
+ * @ourchip: The chip for suspend.
|
|
|
+ */
|
|
|
+static void samsung_pm_save_gpio(struct samsung_gpio_chip *ourchip)
|
|
|
+{
|
|
|
+ struct samsung_gpio_pm *pm = ourchip->pm;
|
|
|
+
|
|
|
+ if (pm == NULL || pm->save == NULL)
|
|
|
+ S3C_PMDBG("%s: no pm for %s\n", __func__, ourchip->chip.label);
|
|
|
+ else
|
|
|
+ pm->save(ourchip);
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * samsung_pm_save_gpios() - Save the state of the GPIO banks.
|
|
|
+ *
|
|
|
+ * For all the GPIO banks, save the state of each one ready for going
|
|
|
+ * into a suspend mode.
|
|
|
+ */
|
|
|
+void samsung_pm_save_gpios(void)
|
|
|
+{
|
|
|
+ struct samsung_gpio_chip *ourchip;
|
|
|
+ unsigned int gpio_nr;
|
|
|
+
|
|
|
+ for (gpio_nr = 0; gpio_nr < S3C_GPIO_END;) {
|
|
|
+ ourchip = samsung_gpiolib_getchip(gpio_nr);
|
|
|
+ if (!ourchip) {
|
|
|
+ gpio_nr++;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ samsung_pm_save_gpio(ourchip);
|
|
|
+
|
|
|
+ S3C_PMDBG("%s: save %08x,%08x,%08x,%08x\n",
|
|
|
+ ourchip->chip.label,
|
|
|
+ ourchip->pm_save[0],
|
|
|
+ ourchip->pm_save[1],
|
|
|
+ ourchip->pm_save[2],
|
|
|
+ ourchip->pm_save[3]);
|
|
|
+
|
|
|
+ gpio_nr += ourchip->chip.ngpio;
|
|
|
+ gpio_nr += CONFIG_S3C_GPIO_SPACE;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * samsung_pm_resume_gpio() - restore gpio chip data after suspend
|
|
|
+ * @ourchip: The suspended chip.
|
|
|
+ */
|
|
|
+static void samsung_pm_resume_gpio(struct samsung_gpio_chip *ourchip)
|
|
|
+{
|
|
|
+ struct samsung_gpio_pm *pm = ourchip->pm;
|
|
|
+
|
|
|
+ if (pm == NULL || pm->resume == NULL)
|
|
|
+ S3C_PMDBG("%s: no pm for %s\n", __func__, ourchip->chip.label);
|
|
|
+ else
|
|
|
+ pm->resume(ourchip);
|
|
|
+}
|
|
|
+
|
|
|
+void samsung_pm_restore_gpios(void)
|
|
|
+{
|
|
|
+ struct samsung_gpio_chip *ourchip;
|
|
|
+ unsigned int gpio_nr;
|
|
|
+
|
|
|
+ for (gpio_nr = 0; gpio_nr < S3C_GPIO_END;) {
|
|
|
+ ourchip = samsung_gpiolib_getchip(gpio_nr);
|
|
|
+ if (!ourchip) {
|
|
|
+ gpio_nr++;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ samsung_pm_resume_gpio(ourchip);
|
|
|
+
|
|
|
+ gpio_nr += ourchip->chip.ngpio;
|
|
|
+ gpio_nr += CONFIG_S3C_GPIO_SPACE;
|
|
|
+ }
|
|
|
+}
|