|
@@ -182,3 +182,56 @@ static void samsung_gpio_pm_2bit_resume(struct samsung_gpio_chip *chip)
|
|
|
|
|
|
__raw_writel(gps_gpdat, base + OFFS_DAT);
|
|
|
__raw_writel(gps_gpcon, base + OFFS_CON);
|
|
|
+
|
|
|
+ S3C_PMDBG("%s: CON %08x => %08x, DAT %08x => %08x\n",
|
|
|
+ chip->chip.label, old_gpcon, gps_gpcon, old_gpdat, gps_gpdat);
|
|
|
+}
|
|
|
+
|
|
|
+struct samsung_gpio_pm samsung_gpio_pm_2bit = {
|
|
|
+ .save = samsung_gpio_pm_2bit_save,
|
|
|
+ .resume = samsung_gpio_pm_2bit_resume,
|
|
|
+};
|
|
|
+
|
|
|
+#if defined(CONFIG_ARCH_S3C64XX) || defined(CONFIG_PLAT_S5P)
|
|
|
+static void samsung_gpio_pm_4bit_save(struct samsung_gpio_chip *chip)
|
|
|
+{
|
|
|
+ chip->pm_save[1] = __raw_readl(chip->base + OFFS_CON);
|
|
|
+ chip->pm_save[2] = __raw_readl(chip->base + OFFS_DAT);
|
|
|
+ chip->pm_save[3] = __raw_readl(chip->base + OFFS_UP);
|
|
|
+
|
|
|
+ if (chip->chip.ngpio > 8)
|
|
|
+ chip->pm_save[0] = __raw_readl(chip->base - 4);
|
|
|
+}
|
|
|
+
|
|
|
+static u32 samsung_gpio_pm_4bit_mask(u32 old_gpcon, u32 gps_gpcon)
|
|
|
+{
|
|
|
+ u32 old, new, mask;
|
|
|
+ u32 change_mask = 0x0;
|
|
|
+ int nr;
|
|
|
+
|
|
|
+ for (nr = 0, mask = 0x0f; nr < 16; nr += 4, mask <<= 4) {
|
|
|
+ old = (old_gpcon & mask) >> nr;
|
|
|
+ new = (gps_gpcon & mask) >> nr;
|
|
|
+
|
|
|
+ /* If there is no change, then skip */
|
|
|
+
|
|
|
+ if (old == new)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ /* If both are special function, then skip */
|
|
|
+
|
|
|
+ if (is_sfn(old) && is_sfn(new))
|
|
|
+ continue;
|
|
|
+
|
|
|
+ /* Change is IN => OUT, do not change now */
|
|
|
+
|
|
|
+ if (is_in(old) && is_out(new))
|
|
|
+ continue;
|
|
|
+
|
|
|
+ /* Change is SFN => OUT, do not change now */
|
|
|
+
|
|
|
+ if (is_sfn(old) && is_out(new))
|
|
|
+ continue;
|
|
|
+
|
|
|
+ /* We should now be at the case of IN=>SFN,
|
|
|
+ * OUT=>SFN, OUT=>IN, SFN=>IN. */
|