162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0+ 262306a36Sopenharmony_ci// 362306a36Sopenharmony_ci// Copyright 2008 Openmoko, Inc. 462306a36Sopenharmony_ci// Copyright 2008 Simtec Electronics 562306a36Sopenharmony_ci// Ben Dooks <ben@simtec.co.uk> 662306a36Sopenharmony_ci// http://armlinux.simtec.co.uk/ 762306a36Sopenharmony_ci// 862306a36Sopenharmony_ci// S3C series GPIO PM code 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#include <linux/kernel.h> 1162306a36Sopenharmony_ci#include <linux/device.h> 1262306a36Sopenharmony_ci#include <linux/init.h> 1362306a36Sopenharmony_ci#include <linux/io.h> 1462306a36Sopenharmony_ci#include <linux/gpio.h> 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ci#include "gpio-samsung.h" 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci#include "gpio-core.h" 1962306a36Sopenharmony_ci#include "pm.h" 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci/* PM GPIO helpers */ 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_ci#define OFFS_CON (0x00) 2462306a36Sopenharmony_ci#define OFFS_DAT (0x04) 2562306a36Sopenharmony_ci#define OFFS_UP (0x08) 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_cistatic void samsung_gpio_pm_1bit_save(struct samsung_gpio_chip *chip) 2862306a36Sopenharmony_ci{ 2962306a36Sopenharmony_ci chip->pm_save[0] = __raw_readl(chip->base + OFFS_CON); 3062306a36Sopenharmony_ci chip->pm_save[1] = __raw_readl(chip->base + OFFS_DAT); 3162306a36Sopenharmony_ci} 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_cistatic void samsung_gpio_pm_1bit_resume(struct samsung_gpio_chip *chip) 3462306a36Sopenharmony_ci{ 3562306a36Sopenharmony_ci void __iomem *base = chip->base; 3662306a36Sopenharmony_ci u32 old_gpcon = __raw_readl(base + OFFS_CON); 3762306a36Sopenharmony_ci u32 old_gpdat = __raw_readl(base + OFFS_DAT); 3862306a36Sopenharmony_ci u32 gps_gpcon = chip->pm_save[0]; 3962306a36Sopenharmony_ci u32 gps_gpdat = chip->pm_save[1]; 4062306a36Sopenharmony_ci u32 gpcon; 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ci /* GPACON only has one bit per control / data and no PULLUPs. 4362306a36Sopenharmony_ci * GPACON[x] = 0 => Output, 1 => SFN */ 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_ci /* first set all SFN bits to SFN */ 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_ci gpcon = old_gpcon | gps_gpcon; 4862306a36Sopenharmony_ci __raw_writel(gpcon, base + OFFS_CON); 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_ci /* now set all the other bits */ 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci __raw_writel(gps_gpdat, base + OFFS_DAT); 5362306a36Sopenharmony_ci __raw_writel(gps_gpcon, base + OFFS_CON); 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_ci S3C_PMDBG("%s: CON %08x => %08x, DAT %08x => %08x\n", 5662306a36Sopenharmony_ci chip->chip.label, old_gpcon, gps_gpcon, old_gpdat, gps_gpdat); 5762306a36Sopenharmony_ci} 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_cistruct samsung_gpio_pm samsung_gpio_pm_1bit = { 6062306a36Sopenharmony_ci .save = samsung_gpio_pm_1bit_save, 6162306a36Sopenharmony_ci .resume = samsung_gpio_pm_1bit_resume, 6262306a36Sopenharmony_ci}; 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_cistatic void samsung_gpio_pm_2bit_save(struct samsung_gpio_chip *chip) 6562306a36Sopenharmony_ci{ 6662306a36Sopenharmony_ci chip->pm_save[0] = __raw_readl(chip->base + OFFS_CON); 6762306a36Sopenharmony_ci chip->pm_save[1] = __raw_readl(chip->base + OFFS_DAT); 6862306a36Sopenharmony_ci chip->pm_save[2] = __raw_readl(chip->base + OFFS_UP); 6962306a36Sopenharmony_ci} 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_ci/* Test whether the given masked+shifted bits of an GPIO configuration 7262306a36Sopenharmony_ci * are one of the SFN (special function) modes. */ 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_cistatic inline int is_sfn(unsigned long con) 7562306a36Sopenharmony_ci{ 7662306a36Sopenharmony_ci return con >= 2; 7762306a36Sopenharmony_ci} 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ci/* Test if the given masked+shifted GPIO configuration is an input */ 8062306a36Sopenharmony_ci 8162306a36Sopenharmony_cistatic inline int is_in(unsigned long con) 8262306a36Sopenharmony_ci{ 8362306a36Sopenharmony_ci return con == 0; 8462306a36Sopenharmony_ci} 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ci/* Test if the given masked+shifted GPIO configuration is an output */ 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_cistatic inline int is_out(unsigned long con) 8962306a36Sopenharmony_ci{ 9062306a36Sopenharmony_ci return con == 1; 9162306a36Sopenharmony_ci} 9262306a36Sopenharmony_ci 9362306a36Sopenharmony_ci/** 9462306a36Sopenharmony_ci * samsung_gpio_pm_2bit_resume() - restore the given GPIO bank 9562306a36Sopenharmony_ci * @chip: The chip information to resume. 9662306a36Sopenharmony_ci * 9762306a36Sopenharmony_ci * Restore one of the GPIO banks that was saved during suspend. This is 9862306a36Sopenharmony_ci * not as simple as once thought, due to the possibility of glitches 9962306a36Sopenharmony_ci * from the order that the CON and DAT registers are set in. 10062306a36Sopenharmony_ci * 10162306a36Sopenharmony_ci * The three states the pin can be are {IN,OUT,SFN} which gives us 9 10262306a36Sopenharmony_ci * combinations of changes to check. Three of these, if the pin stays 10362306a36Sopenharmony_ci * in the same configuration can be discounted. This leaves us with 10462306a36Sopenharmony_ci * the following: 10562306a36Sopenharmony_ci * 10662306a36Sopenharmony_ci * { IN => OUT } Change DAT first 10762306a36Sopenharmony_ci * { IN => SFN } Change CON first 10862306a36Sopenharmony_ci * { OUT => SFN } Change CON first, so new data will not glitch 10962306a36Sopenharmony_ci * { OUT => IN } Change CON first, so new data will not glitch 11062306a36Sopenharmony_ci * { SFN => IN } Change CON first 11162306a36Sopenharmony_ci * { SFN => OUT } Change DAT first, so new data will not glitch [1] 11262306a36Sopenharmony_ci * 11362306a36Sopenharmony_ci * We do not currently deal with the UP registers as these control 11462306a36Sopenharmony_ci * weak resistors, so a small delay in change should not need to bring 11562306a36Sopenharmony_ci * these into the calculations. 11662306a36Sopenharmony_ci * 11762306a36Sopenharmony_ci * [1] this assumes that writing to a pin DAT whilst in SFN will set the 11862306a36Sopenharmony_ci * state for when it is next output. 11962306a36Sopenharmony_ci */ 12062306a36Sopenharmony_cistatic void samsung_gpio_pm_2bit_resume(struct samsung_gpio_chip *chip) 12162306a36Sopenharmony_ci{ 12262306a36Sopenharmony_ci void __iomem *base = chip->base; 12362306a36Sopenharmony_ci u32 old_gpcon = __raw_readl(base + OFFS_CON); 12462306a36Sopenharmony_ci u32 old_gpdat = __raw_readl(base + OFFS_DAT); 12562306a36Sopenharmony_ci u32 gps_gpcon = chip->pm_save[0]; 12662306a36Sopenharmony_ci u32 gps_gpdat = chip->pm_save[1]; 12762306a36Sopenharmony_ci u32 gpcon, old, new, mask; 12862306a36Sopenharmony_ci u32 change_mask = 0x0; 12962306a36Sopenharmony_ci int nr; 13062306a36Sopenharmony_ci 13162306a36Sopenharmony_ci /* restore GPIO pull-up settings */ 13262306a36Sopenharmony_ci __raw_writel(chip->pm_save[2], base + OFFS_UP); 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_ci /* Create a change_mask of all the items that need to have 13562306a36Sopenharmony_ci * their CON value changed before their DAT value, so that 13662306a36Sopenharmony_ci * we minimise the work between the two settings. 13762306a36Sopenharmony_ci */ 13862306a36Sopenharmony_ci 13962306a36Sopenharmony_ci for (nr = 0, mask = 0x03; nr < 32; nr += 2, mask <<= 2) { 14062306a36Sopenharmony_ci old = (old_gpcon & mask) >> nr; 14162306a36Sopenharmony_ci new = (gps_gpcon & mask) >> nr; 14262306a36Sopenharmony_ci 14362306a36Sopenharmony_ci /* If there is no change, then skip */ 14462306a36Sopenharmony_ci 14562306a36Sopenharmony_ci if (old == new) 14662306a36Sopenharmony_ci continue; 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_ci /* If both are special function, then skip */ 14962306a36Sopenharmony_ci 15062306a36Sopenharmony_ci if (is_sfn(old) && is_sfn(new)) 15162306a36Sopenharmony_ci continue; 15262306a36Sopenharmony_ci 15362306a36Sopenharmony_ci /* Change is IN => OUT, do not change now */ 15462306a36Sopenharmony_ci 15562306a36Sopenharmony_ci if (is_in(old) && is_out(new)) 15662306a36Sopenharmony_ci continue; 15762306a36Sopenharmony_ci 15862306a36Sopenharmony_ci /* Change is SFN => OUT, do not change now */ 15962306a36Sopenharmony_ci 16062306a36Sopenharmony_ci if (is_sfn(old) && is_out(new)) 16162306a36Sopenharmony_ci continue; 16262306a36Sopenharmony_ci 16362306a36Sopenharmony_ci /* We should now be at the case of IN=>SFN, 16462306a36Sopenharmony_ci * OUT=>SFN, OUT=>IN, SFN=>IN. */ 16562306a36Sopenharmony_ci 16662306a36Sopenharmony_ci change_mask |= mask; 16762306a36Sopenharmony_ci } 16862306a36Sopenharmony_ci 16962306a36Sopenharmony_ci 17062306a36Sopenharmony_ci /* Write the new CON settings */ 17162306a36Sopenharmony_ci 17262306a36Sopenharmony_ci gpcon = old_gpcon & ~change_mask; 17362306a36Sopenharmony_ci gpcon |= gps_gpcon & change_mask; 17462306a36Sopenharmony_ci 17562306a36Sopenharmony_ci __raw_writel(gpcon, base + OFFS_CON); 17662306a36Sopenharmony_ci 17762306a36Sopenharmony_ci /* Now change any items that require DAT,CON */ 17862306a36Sopenharmony_ci 17962306a36Sopenharmony_ci __raw_writel(gps_gpdat, base + OFFS_DAT); 18062306a36Sopenharmony_ci __raw_writel(gps_gpcon, base + OFFS_CON); 18162306a36Sopenharmony_ci 18262306a36Sopenharmony_ci S3C_PMDBG("%s: CON %08x => %08x, DAT %08x => %08x\n", 18362306a36Sopenharmony_ci chip->chip.label, old_gpcon, gps_gpcon, old_gpdat, gps_gpdat); 18462306a36Sopenharmony_ci} 18562306a36Sopenharmony_ci 18662306a36Sopenharmony_cistruct samsung_gpio_pm samsung_gpio_pm_2bit = { 18762306a36Sopenharmony_ci .save = samsung_gpio_pm_2bit_save, 18862306a36Sopenharmony_ci .resume = samsung_gpio_pm_2bit_resume, 18962306a36Sopenharmony_ci}; 19062306a36Sopenharmony_ci 19162306a36Sopenharmony_ci#if defined(CONFIG_ARCH_S3C64XX) 19262306a36Sopenharmony_cistatic void samsung_gpio_pm_4bit_save(struct samsung_gpio_chip *chip) 19362306a36Sopenharmony_ci{ 19462306a36Sopenharmony_ci chip->pm_save[1] = __raw_readl(chip->base + OFFS_CON); 19562306a36Sopenharmony_ci chip->pm_save[2] = __raw_readl(chip->base + OFFS_DAT); 19662306a36Sopenharmony_ci chip->pm_save[3] = __raw_readl(chip->base + OFFS_UP); 19762306a36Sopenharmony_ci 19862306a36Sopenharmony_ci if (chip->chip.ngpio > 8) 19962306a36Sopenharmony_ci chip->pm_save[0] = __raw_readl(chip->base - 4); 20062306a36Sopenharmony_ci} 20162306a36Sopenharmony_ci 20262306a36Sopenharmony_cistatic u32 samsung_gpio_pm_4bit_mask(u32 old_gpcon, u32 gps_gpcon) 20362306a36Sopenharmony_ci{ 20462306a36Sopenharmony_ci u32 old, new, mask; 20562306a36Sopenharmony_ci u32 change_mask = 0x0; 20662306a36Sopenharmony_ci int nr; 20762306a36Sopenharmony_ci 20862306a36Sopenharmony_ci for (nr = 0, mask = 0x0f; nr < 16; nr += 4, mask <<= 4) { 20962306a36Sopenharmony_ci old = (old_gpcon & mask) >> nr; 21062306a36Sopenharmony_ci new = (gps_gpcon & mask) >> nr; 21162306a36Sopenharmony_ci 21262306a36Sopenharmony_ci /* If there is no change, then skip */ 21362306a36Sopenharmony_ci 21462306a36Sopenharmony_ci if (old == new) 21562306a36Sopenharmony_ci continue; 21662306a36Sopenharmony_ci 21762306a36Sopenharmony_ci /* If both are special function, then skip */ 21862306a36Sopenharmony_ci 21962306a36Sopenharmony_ci if (is_sfn(old) && is_sfn(new)) 22062306a36Sopenharmony_ci continue; 22162306a36Sopenharmony_ci 22262306a36Sopenharmony_ci /* Change is IN => OUT, do not change now */ 22362306a36Sopenharmony_ci 22462306a36Sopenharmony_ci if (is_in(old) && is_out(new)) 22562306a36Sopenharmony_ci continue; 22662306a36Sopenharmony_ci 22762306a36Sopenharmony_ci /* Change is SFN => OUT, do not change now */ 22862306a36Sopenharmony_ci 22962306a36Sopenharmony_ci if (is_sfn(old) && is_out(new)) 23062306a36Sopenharmony_ci continue; 23162306a36Sopenharmony_ci 23262306a36Sopenharmony_ci /* We should now be at the case of IN=>SFN, 23362306a36Sopenharmony_ci * OUT=>SFN, OUT=>IN, SFN=>IN. */ 23462306a36Sopenharmony_ci 23562306a36Sopenharmony_ci change_mask |= mask; 23662306a36Sopenharmony_ci } 23762306a36Sopenharmony_ci 23862306a36Sopenharmony_ci return change_mask; 23962306a36Sopenharmony_ci} 24062306a36Sopenharmony_ci 24162306a36Sopenharmony_cistatic void samsung_gpio_pm_4bit_con(struct samsung_gpio_chip *chip, int index) 24262306a36Sopenharmony_ci{ 24362306a36Sopenharmony_ci void __iomem *con = chip->base + (index * 4); 24462306a36Sopenharmony_ci u32 old_gpcon = __raw_readl(con); 24562306a36Sopenharmony_ci u32 gps_gpcon = chip->pm_save[index + 1]; 24662306a36Sopenharmony_ci u32 gpcon, mask; 24762306a36Sopenharmony_ci 24862306a36Sopenharmony_ci mask = samsung_gpio_pm_4bit_mask(old_gpcon, gps_gpcon); 24962306a36Sopenharmony_ci 25062306a36Sopenharmony_ci gpcon = old_gpcon & ~mask; 25162306a36Sopenharmony_ci gpcon |= gps_gpcon & mask; 25262306a36Sopenharmony_ci 25362306a36Sopenharmony_ci __raw_writel(gpcon, con); 25462306a36Sopenharmony_ci} 25562306a36Sopenharmony_ci 25662306a36Sopenharmony_cistatic void samsung_gpio_pm_4bit_resume(struct samsung_gpio_chip *chip) 25762306a36Sopenharmony_ci{ 25862306a36Sopenharmony_ci void __iomem *base = chip->base; 25962306a36Sopenharmony_ci u32 old_gpcon[2]; 26062306a36Sopenharmony_ci u32 old_gpdat = __raw_readl(base + OFFS_DAT); 26162306a36Sopenharmony_ci u32 gps_gpdat = chip->pm_save[2]; 26262306a36Sopenharmony_ci 26362306a36Sopenharmony_ci /* First, modify the CON settings */ 26462306a36Sopenharmony_ci 26562306a36Sopenharmony_ci old_gpcon[0] = 0; 26662306a36Sopenharmony_ci old_gpcon[1] = __raw_readl(base + OFFS_CON); 26762306a36Sopenharmony_ci 26862306a36Sopenharmony_ci samsung_gpio_pm_4bit_con(chip, 0); 26962306a36Sopenharmony_ci if (chip->chip.ngpio > 8) { 27062306a36Sopenharmony_ci old_gpcon[0] = __raw_readl(base - 4); 27162306a36Sopenharmony_ci samsung_gpio_pm_4bit_con(chip, -1); 27262306a36Sopenharmony_ci } 27362306a36Sopenharmony_ci 27462306a36Sopenharmony_ci /* Now change the configurations that require DAT,CON */ 27562306a36Sopenharmony_ci 27662306a36Sopenharmony_ci __raw_writel(chip->pm_save[2], base + OFFS_DAT); 27762306a36Sopenharmony_ci __raw_writel(chip->pm_save[1], base + OFFS_CON); 27862306a36Sopenharmony_ci if (chip->chip.ngpio > 8) 27962306a36Sopenharmony_ci __raw_writel(chip->pm_save[0], base - 4); 28062306a36Sopenharmony_ci 28162306a36Sopenharmony_ci __raw_writel(chip->pm_save[2], base + OFFS_DAT); 28262306a36Sopenharmony_ci __raw_writel(chip->pm_save[3], base + OFFS_UP); 28362306a36Sopenharmony_ci 28462306a36Sopenharmony_ci if (chip->chip.ngpio > 8) { 28562306a36Sopenharmony_ci S3C_PMDBG("%s: CON4 %08x,%08x => %08x,%08x, DAT %08x => %08x\n", 28662306a36Sopenharmony_ci chip->chip.label, old_gpcon[0], old_gpcon[1], 28762306a36Sopenharmony_ci __raw_readl(base - 4), 28862306a36Sopenharmony_ci __raw_readl(base + OFFS_CON), 28962306a36Sopenharmony_ci old_gpdat, gps_gpdat); 29062306a36Sopenharmony_ci } else 29162306a36Sopenharmony_ci S3C_PMDBG("%s: CON4 %08x => %08x, DAT %08x => %08x\n", 29262306a36Sopenharmony_ci chip->chip.label, old_gpcon[1], 29362306a36Sopenharmony_ci __raw_readl(base + OFFS_CON), 29462306a36Sopenharmony_ci old_gpdat, gps_gpdat); 29562306a36Sopenharmony_ci} 29662306a36Sopenharmony_ci 29762306a36Sopenharmony_cistruct samsung_gpio_pm samsung_gpio_pm_4bit = { 29862306a36Sopenharmony_ci .save = samsung_gpio_pm_4bit_save, 29962306a36Sopenharmony_ci .resume = samsung_gpio_pm_4bit_resume, 30062306a36Sopenharmony_ci}; 30162306a36Sopenharmony_ci#endif /* CONFIG_ARCH_S3C64XX */ 30262306a36Sopenharmony_ci 30362306a36Sopenharmony_ci/** 30462306a36Sopenharmony_ci * samsung_pm_save_gpio() - save gpio chip data for suspend 30562306a36Sopenharmony_ci * @ourchip: The chip for suspend. 30662306a36Sopenharmony_ci */ 30762306a36Sopenharmony_cistatic void samsung_pm_save_gpio(struct samsung_gpio_chip *ourchip) 30862306a36Sopenharmony_ci{ 30962306a36Sopenharmony_ci struct samsung_gpio_pm *pm = ourchip->pm; 31062306a36Sopenharmony_ci 31162306a36Sopenharmony_ci if (pm == NULL || pm->save == NULL) 31262306a36Sopenharmony_ci S3C_PMDBG("%s: no pm for %s\n", __func__, ourchip->chip.label); 31362306a36Sopenharmony_ci else 31462306a36Sopenharmony_ci pm->save(ourchip); 31562306a36Sopenharmony_ci} 31662306a36Sopenharmony_ci 31762306a36Sopenharmony_ci/** 31862306a36Sopenharmony_ci * samsung_pm_save_gpios() - Save the state of the GPIO banks. 31962306a36Sopenharmony_ci * 32062306a36Sopenharmony_ci * For all the GPIO banks, save the state of each one ready for going 32162306a36Sopenharmony_ci * into a suspend mode. 32262306a36Sopenharmony_ci */ 32362306a36Sopenharmony_civoid samsung_pm_save_gpios(void) 32462306a36Sopenharmony_ci{ 32562306a36Sopenharmony_ci struct samsung_gpio_chip *ourchip; 32662306a36Sopenharmony_ci unsigned int gpio_nr; 32762306a36Sopenharmony_ci 32862306a36Sopenharmony_ci for (gpio_nr = 0; gpio_nr < S3C_GPIO_END;) { 32962306a36Sopenharmony_ci ourchip = samsung_gpiolib_getchip(gpio_nr); 33062306a36Sopenharmony_ci if (!ourchip) { 33162306a36Sopenharmony_ci gpio_nr++; 33262306a36Sopenharmony_ci continue; 33362306a36Sopenharmony_ci } 33462306a36Sopenharmony_ci 33562306a36Sopenharmony_ci samsung_pm_save_gpio(ourchip); 33662306a36Sopenharmony_ci 33762306a36Sopenharmony_ci S3C_PMDBG("%s: save %08x,%08x,%08x,%08x\n", 33862306a36Sopenharmony_ci ourchip->chip.label, 33962306a36Sopenharmony_ci ourchip->pm_save[0], 34062306a36Sopenharmony_ci ourchip->pm_save[1], 34162306a36Sopenharmony_ci ourchip->pm_save[2], 34262306a36Sopenharmony_ci ourchip->pm_save[3]); 34362306a36Sopenharmony_ci 34462306a36Sopenharmony_ci gpio_nr += ourchip->chip.ngpio; 34562306a36Sopenharmony_ci gpio_nr += CONFIG_S3C_GPIO_SPACE; 34662306a36Sopenharmony_ci } 34762306a36Sopenharmony_ci} 34862306a36Sopenharmony_ci 34962306a36Sopenharmony_ci/** 35062306a36Sopenharmony_ci * samsung_pm_resume_gpio() - restore gpio chip data after suspend 35162306a36Sopenharmony_ci * @ourchip: The suspended chip. 35262306a36Sopenharmony_ci */ 35362306a36Sopenharmony_cistatic void samsung_pm_resume_gpio(struct samsung_gpio_chip *ourchip) 35462306a36Sopenharmony_ci{ 35562306a36Sopenharmony_ci struct samsung_gpio_pm *pm = ourchip->pm; 35662306a36Sopenharmony_ci 35762306a36Sopenharmony_ci if (pm == NULL || pm->resume == NULL) 35862306a36Sopenharmony_ci S3C_PMDBG("%s: no pm for %s\n", __func__, ourchip->chip.label); 35962306a36Sopenharmony_ci else 36062306a36Sopenharmony_ci pm->resume(ourchip); 36162306a36Sopenharmony_ci} 36262306a36Sopenharmony_ci 36362306a36Sopenharmony_civoid samsung_pm_restore_gpios(void) 36462306a36Sopenharmony_ci{ 36562306a36Sopenharmony_ci struct samsung_gpio_chip *ourchip; 36662306a36Sopenharmony_ci unsigned int gpio_nr; 36762306a36Sopenharmony_ci 36862306a36Sopenharmony_ci for (gpio_nr = 0; gpio_nr < S3C_GPIO_END;) { 36962306a36Sopenharmony_ci ourchip = samsung_gpiolib_getchip(gpio_nr); 37062306a36Sopenharmony_ci if (!ourchip) { 37162306a36Sopenharmony_ci gpio_nr++; 37262306a36Sopenharmony_ci continue; 37362306a36Sopenharmony_ci } 37462306a36Sopenharmony_ci 37562306a36Sopenharmony_ci samsung_pm_resume_gpio(ourchip); 37662306a36Sopenharmony_ci 37762306a36Sopenharmony_ci gpio_nr += ourchip->chip.ngpio; 37862306a36Sopenharmony_ci gpio_nr += CONFIG_S3C_GPIO_SPACE; 37962306a36Sopenharmony_ci } 38062306a36Sopenharmony_ci} 381