···1818 * published by the Free Software Foundation.1919 */20202121+#include <linux/cpu_pm.h>2122#include <linux/suspend.h>2223#include <linux/sched.h>2324#include <linux/proc_fs.h>···3029#include <linux/clk-provider.h>3130#include <linux/irq.h>3231#include <linux/time.h>3333-#include <linux/gpio.h>3434-#include <linux/platform_data/gpio-omap.h>35323633#include <asm/fncpy.h>3734···8687 l = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0) | OMAP24XX_USBSTANDBYCTRL;8788 omap_ctrl_writel(l, OMAP2_CONTROL_DEVCONF0);88898989- omap2_gpio_prepare_for_idle(0);9090+ cpu_cluster_pm_enter();90919192 /* One last check for pending IRQs to avoid extra latency due9293 * to sleeping unnecessarily. */···99100 OMAP_SDRC_REGADDR(SDRC_POWER));100101101102no_sleep:102102- omap2_gpio_resume_after_idle();103103+ cpu_cluster_pm_exit();103104104105 clk_enable(osc_ck);105106
+5-9
arch/arm/mach-omap2/pm34xx.c
···1818 * published by the Free Software Foundation.1919 */20202121+#include <linux/cpu_pm.h>2122#include <linux/pm.h>2223#include <linux/suspend.h>2324#include <linux/interrupt.h>2425#include <linux/module.h>2526#include <linux/list.h>2627#include <linux/err.h>2727-#include <linux/gpio.h>2828#include <linux/clk.h>2929#include <linux/delay.h>3030#include <linux/slab.h>3131#include <linux/omap-dma.h>3232#include <linux/omap-gpmc.h>3333-#include <linux/platform_data/gpio-omap.h>34333534#include <trace/events/power.h>3635···196197 int mpu_next_state = PWRDM_POWER_ON;197198 int per_next_state = PWRDM_POWER_ON;198199 int core_next_state = PWRDM_POWER_ON;199199- int per_going_off;200200 u32 sdrc_pwr = 0;201201202202 mpu_next_state = pwrdm_read_next_pwrst(mpu_pwrdm);···225227 pwrdm_pre_transition(NULL);226228227229 /* PER */228228- if (per_next_state < PWRDM_POWER_ON) {229229- per_going_off = (per_next_state == PWRDM_POWER_OFF) ? 1 : 0;230230- omap2_gpio_prepare_for_idle(per_going_off);231231- }230230+ if (per_next_state == PWRDM_POWER_OFF)231231+ cpu_cluster_pm_enter();232232233233 /* CORE */234234 if (core_next_state < PWRDM_POWER_ON) {···291295 pwrdm_post_transition(NULL);292296293297 /* PER */294294- if (per_next_state < PWRDM_POWER_ON)295295- omap2_gpio_resume_after_idle();298298+ if (per_next_state == PWRDM_POWER_OFF)299299+ cpu_cluster_pm_exit();296300}297301298302static void omap3_pm_idle(void)
+227-104
drivers/gpio/gpio-omap.c
···1919#include <linux/err.h>2020#include <linux/clk.h>2121#include <linux/io.h>2222+#include <linux/cpu_pm.h>2223#include <linux/device.h>2324#include <linux/pm_runtime.h>2425#include <linux/pm.h>···2928#include <linux/bitops.h>3029#include <linux/platform_data/gpio-omap.h>31303232-#define OFF_MODE 13331#define OMAP4_GPIO_DEBOUNCINGTIME_MASK 0xFF3232+3333+#define OMAP_GPIO_QUIRK_IDLE_REMOVE_TRIGGER BIT(2)3434+#define OMAP_GPIO_QUIRK_DEFERRED_WKUP_EN BIT(1)34353536static LIST_HEAD(omap_gpio_list);3637···5148 u32 debounce_en;5249};53505151+struct gpio_bank;5252+5353+struct gpio_omap_funcs {5454+ void (*idle_enable_level_quirk)(struct gpio_bank *bank);5555+ void (*idle_disable_level_quirk)(struct gpio_bank *bank);5656+};5757+5458struct gpio_bank {5559 struct list_head node;5660 void __iomem *base;···6555 u32 non_wakeup_gpios;6656 u32 enabled_non_wakeup_gpios;6757 struct gpio_regs context;5858+ struct gpio_omap_funcs funcs;6859 u32 saved_datain;6960 u32 level_mask;7061 u32 toggle_mask;···7362 raw_spinlock_t wa_lock;7463 struct gpio_chip chip;7564 struct clk *dbck;6565+ struct notifier_block nb;6666+ unsigned int is_suspended:1;7667 u32 mod_usage;7768 u32 irq_usage;7869 u32 dbck_enable_mask;···8673 int stride;8774 u32 width;8875 int context_loss_count;8989- int power_mode;9076 bool workaround_enabled;7777+ u32 quirks;91789279 void (*set_dataout)(struct gpio_bank *bank, unsigned gpio, int enable);9380 void (*set_dataout_multiple)(struct gpio_bank *bank,···381368 readl_relaxed(bank->base + bank->regs->fallingdetect);382369383370 if (likely(!(bank->non_wakeup_gpios & gpio_bit))) {384384- omap_gpio_rmw(base, bank->regs->wkup_en, gpio_bit, trigger != 0);385385- bank->context.wake_en =386386- readl_relaxed(bank->base + bank->regs->wkup_en);371371+ /* Defer wkup_en register update until we idle? */372372+ if (bank->quirks & OMAP_GPIO_QUIRK_DEFERRED_WKUP_EN) {373373+ if (trigger)374374+ bank->context.wake_en |= gpio_bit;375375+ else376376+ bank->context.wake_en &= ~gpio_bit;377377+ } else {378378+ omap_gpio_rmw(base, bank->regs->wkup_en, gpio_bit,379379+ trigger != 0);380380+ bank->context.wake_en =381381+ readl_relaxed(bank->base + bank->regs->wkup_en);382382+ }387383 }388384389385 /* This part needs to be executed always for OMAP{34xx, 44xx} */···763741 if (WARN_ON(!isr_reg))764742 goto exit;765743766766- pm_runtime_get_sync(bank->chip.parent);744744+ if (WARN_ONCE(!pm_runtime_active(bank->chip.parent),745745+ "gpio irq%i while runtime suspended?\n", irq))746746+ return IRQ_NONE;767747768748 while (1) {769749 raw_spin_lock_irqsave(&bank->lock, lock_flags);···816792 }817793 }818794exit:819819- pm_runtime_put(bank->chip.parent);820795 return IRQ_HANDLED;821796}822797···920897921898 omap_set_gpio_irqenable(bank, offset, 1);922899 raw_spin_unlock_irqrestore(&bank->lock, flags);900900+}901901+902902+/*903903+ * Only edges can generate a wakeup event to the PRCM.904904+ *905905+ * Therefore, ensure any wake-up capable GPIOs have906906+ * edge-detection enabled before going idle to ensure a wakeup907907+ * to the PRCM is generated on a GPIO transition. (c.f. 34xx908908+ * NDA TRM 25.5.3.1)909909+ *910910+ * The normal values will be restored upon ->runtime_resume()911911+ * by writing back the values saved in bank->context.912912+ */913913+static void __maybe_unused914914+omap2_gpio_enable_level_quirk(struct gpio_bank *bank)915915+{916916+ u32 wake_low, wake_hi;917917+918918+ /* Enable additional edge detection for level gpios for idle */919919+ wake_low = bank->context.leveldetect0 & bank->context.wake_en;920920+ if (wake_low)921921+ writel_relaxed(wake_low | bank->context.fallingdetect,922922+ bank->base + bank->regs->fallingdetect);923923+924924+ wake_hi = bank->context.leveldetect1 & bank->context.wake_en;925925+ if (wake_hi)926926+ writel_relaxed(wake_hi | bank->context.risingdetect,927927+ bank->base + bank->regs->risingdetect);928928+}929929+930930+static void __maybe_unused931931+omap2_gpio_disable_level_quirk(struct gpio_bank *bank)932932+{933933+ /* Disable edge detection for level gpios after idle */934934+ writel_relaxed(bank->context.fallingdetect,935935+ bank->base + bank->regs->fallingdetect);936936+ writel_relaxed(bank->context.risingdetect,937937+ bank->base + bank->regs->risingdetect);938938+}939939+940940+/*941941+ * On omap4 and later SoC variants a level interrupt with wkup_en942942+ * enabled blocks the GPIO functional clock from idling until the GPIO943943+ * instance has been reset. To avoid that, we must set wkup_en only for944944+ * idle for level interrupts, and clear level registers for the duration945945+ * of idle. The level interrupts will be still there on wakeup by their946946+ * nature.947947+ */948948+static void __maybe_unused949949+omap4_gpio_enable_level_quirk(struct gpio_bank *bank)950950+{951951+ /* Update wake register for idle, edge bits might be already set */952952+ writel_relaxed(bank->context.wake_en,953953+ bank->base + bank->regs->wkup_en);954954+955955+ /* Clear level registers for idle */956956+ writel_relaxed(0, bank->base + bank->regs->leveldetect0);957957+ writel_relaxed(0, bank->base + bank->regs->leveldetect1);958958+}959959+960960+static void __maybe_unused961961+omap4_gpio_disable_level_quirk(struct gpio_bank *bank)962962+{963963+ /* Restore level registers after idle */964964+ writel_relaxed(bank->context.leveldetect0,965965+ bank->base + bank->regs->leveldetect0);966966+ writel_relaxed(bank->context.leveldetect1,967967+ bank->base + bank->regs->leveldetect1);968968+969969+ /* Clear saved wkup_en for level, it will be set for next idle again */970970+ bank->context.wake_en &= ~(bank->context.leveldetect0 |971971+ bank->context.leveldetect1);972972+973973+ /* Update wake with only edge configuration */974974+ writel_relaxed(bank->context.wake_en,975975+ bank->base + bank->regs->wkup_en);923976}924977925978/*---------------------------------------------------------------------*/···13171218 return ret;13181219}1319122012211221+static void omap_gpio_idle(struct gpio_bank *bank, bool may_lose_context);12221222+static void omap_gpio_unidle(struct gpio_bank *bank);12231223+12241224+static int gpio_omap_cpu_notifier(struct notifier_block *nb,12251225+ unsigned long cmd, void *v)12261226+{12271227+ struct gpio_bank *bank;12281228+ struct device *dev;12291229+ unsigned long flags;12301230+12311231+ bank = container_of(nb, struct gpio_bank, nb);12321232+ dev = bank->chip.parent;12331233+12341234+ raw_spin_lock_irqsave(&bank->lock, flags);12351235+ switch (cmd) {12361236+ case CPU_CLUSTER_PM_ENTER:12371237+ if (bank->is_suspended)12381238+ break;12391239+ omap_gpio_idle(bank, true);12401240+ break;12411241+ case CPU_CLUSTER_PM_ENTER_FAILED:12421242+ case CPU_CLUSTER_PM_EXIT:12431243+ if (bank->is_suspended)12441244+ break;12451245+ omap_gpio_unidle(bank);12461246+ break;12471247+ }12481248+ raw_spin_unlock_irqrestore(&bank->lock, flags);12491249+12501250+ return NOTIFY_OK;12511251+}12521252+13201253static const struct of_device_id omap_gpio_match[];1321125413221255static int omap_gpio_probe(struct platform_device *pdev)···14011270 bank->chip.parent = dev;14021271 bank->chip.owner = THIS_MODULE;14031272 bank->dbck_flag = pdata->dbck_flag;12731273+ bank->quirks = pdata->quirks;14041274 bank->stride = pdata->bank_stride;14051275 bank->width = pdata->bank_width;14061276 bank->is_mpuio = pdata->is_mpuio;···14101278#ifdef CONFIG_OF_GPIO14111279 bank->chip.of_node = of_node_get(node);14121280#endif12811281+14131282 if (node) {14141283 if (!of_property_read_bool(node, "ti,gpio-always-on"))14151284 bank->loses_context = true;···14291296 bank->set_dataout = omap_set_gpio_dataout_mask;14301297 bank->set_dataout_multiple =14311298 omap_set_gpio_dataout_mask_multiple;12991299+ }13001300+13011301+ if (bank->quirks & OMAP_GPIO_QUIRK_DEFERRED_WKUP_EN) {13021302+ bank->funcs.idle_enable_level_quirk =13031303+ omap4_gpio_enable_level_quirk;13041304+ bank->funcs.idle_disable_level_quirk =13051305+ omap4_gpio_disable_level_quirk;13061306+ } else if (bank->quirks & OMAP_GPIO_QUIRK_IDLE_REMOVE_TRIGGER) {13071307+ bank->funcs.idle_enable_level_quirk =13081308+ omap2_gpio_enable_level_quirk;13091309+ bank->funcs.idle_disable_level_quirk =13101310+ omap2_gpio_disable_level_quirk;14321311 }1433131214341313 raw_spin_lock_init(&bank->lock);···14671322 platform_set_drvdata(pdev, bank);1468132314691324 pm_runtime_enable(dev);14701470- pm_runtime_irq_safe(dev);14711325 pm_runtime_get_sync(dev);1472132614731327 if (bank->is_mpuio)···1485134114861342 omap_gpio_show_rev(bank);1487134313441344+ if (bank->funcs.idle_enable_level_quirk &&13451345+ bank->funcs.idle_disable_level_quirk) {13461346+ bank->nb.notifier_call = gpio_omap_cpu_notifier;13471347+ cpu_pm_register_notifier(&bank->nb);13481348+ }13491349+14881350 pm_runtime_put(dev);1489135114901352 list_add_tail(&bank->node, &omap_gpio_list);···15021352{15031353 struct gpio_bank *bank = platform_get_drvdata(pdev);1504135413551355+ if (bank->nb.notifier_call)13561356+ cpu_pm_unregister_notifier(&bank->nb);15051357 list_del(&bank->node);15061358 gpiochip_remove(&bank->chip);15071359 pm_runtime_disable(&pdev->dev);···15131361 return 0;15141362}1515136315161516-#ifdef CONFIG_ARCH_OMAP2PLUS15171517-15181518-#if defined(CONFIG_PM)15191364static void omap_gpio_restore_context(struct gpio_bank *bank);1520136515211521-static int omap_gpio_runtime_suspend(struct device *dev)13661366+static void omap_gpio_idle(struct gpio_bank *bank, bool may_lose_context)15221367{15231523- struct platform_device *pdev = to_platform_device(dev);15241524- struct gpio_bank *bank = platform_get_drvdata(pdev);13681368+ struct device *dev = bank->chip.parent;15251369 u32 l1 = 0, l2 = 0;15261526- unsigned long flags;15271527- u32 wake_low, wake_hi;1528137015291529- raw_spin_lock_irqsave(&bank->lock, flags);15301530-15311531- /*15321532- * Only edges can generate a wakeup event to the PRCM.15331533- *15341534- * Therefore, ensure any wake-up capable GPIOs have15351535- * edge-detection enabled before going idle to ensure a wakeup15361536- * to the PRCM is generated on a GPIO transition. (c.f. 34xx15371537- * NDA TRM 25.5.3.1)15381538- *15391539- * The normal values will be restored upon ->runtime_resume()15401540- * by writing back the values saved in bank->context.15411541- */15421542- wake_low = bank->context.leveldetect0 & bank->context.wake_en;15431543- if (wake_low)15441544- writel_relaxed(wake_low | bank->context.fallingdetect,15451545- bank->base + bank->regs->fallingdetect);15461546- wake_hi = bank->context.leveldetect1 & bank->context.wake_en;15471547- if (wake_hi)15481548- writel_relaxed(wake_hi | bank->context.risingdetect,15491549- bank->base + bank->regs->risingdetect);13711371+ if (bank->funcs.idle_enable_level_quirk)13721372+ bank->funcs.idle_enable_level_quirk(bank);1550137315511374 if (!bank->enabled_non_wakeup_gpios)15521375 goto update_gpio_context_count;1553137615541554- if (bank->power_mode != OFF_MODE) {15551555- bank->power_mode = 0;13771377+ if (!may_lose_context)15561378 goto update_gpio_context_count;15571557- }13791379+15581380 /*15591381 * If going to OFF, remove triggering for all15601382 * non-wakeup GPIOs. Otherwise spurious IRQs will be···15531427 bank->get_context_loss_count(dev);1554142815551429 omap_gpio_dbck_disable(bank);15561556- raw_spin_unlock_irqrestore(&bank->lock, flags);15571557-15581558- return 0;15591430}1560143115611432static void omap_gpio_init_context(struct gpio_bank *p);1562143315631563-static int omap_gpio_runtime_resume(struct device *dev)14341434+static void omap_gpio_unidle(struct gpio_bank *bank)15641435{15651565- struct platform_device *pdev = to_platform_device(dev);15661566- struct gpio_bank *bank = platform_get_drvdata(pdev);14361436+ struct device *dev = bank->chip.parent;15671437 u32 l = 0, gen, gen0, gen1;15681568- unsigned long flags;15691438 int c;15701570-15711571- raw_spin_lock_irqsave(&bank->lock, flags);1572143915731440 /*15741441 * On the first resume during the probe, the context has not···1578145915791460 omap_gpio_dbck_enable(bank);1580146115811581- /*15821582- * In ->runtime_suspend(), level-triggered, wakeup-enabled15831583- * GPIOs were set to edge trigger also in order to be able to15841584- * generate a PRCM wakeup. Here we restore the15851585- * pre-runtime_suspend() values for edge triggering.15861586- */15871587- writel_relaxed(bank->context.fallingdetect,15881588- bank->base + bank->regs->fallingdetect);15891589- writel_relaxed(bank->context.risingdetect,15901590- bank->base + bank->regs->risingdetect);14621462+ if (bank->funcs.idle_disable_level_quirk)14631463+ bank->funcs.idle_disable_level_quirk(bank);1591146415921465 if (bank->loses_context) {15931466 if (!bank->get_context_loss_count) {···15891478 if (c != bank->context_loss_count) {15901479 omap_gpio_restore_context(bank);15911480 } else {15921592- raw_spin_unlock_irqrestore(&bank->lock, flags);15931593- return 0;14811481+ return;15941482 }15951483 }15961484 }1597148515981598- if (!bank->workaround_enabled) {15991599- raw_spin_unlock_irqrestore(&bank->lock, flags);16001600- return 0;16011601- }14861486+ if (!bank->workaround_enabled)14871487+ return;1602148816031489 l = readl_relaxed(bank->base + bank->regs->datain);16041490···16481540 }1649154116501542 bank->workaround_enabled = false;16511651- raw_spin_unlock_irqrestore(&bank->lock, flags);16521652-16531653- return 0;16541654-}16551655-#endif /* CONFIG_PM */16561656-16571657-#if IS_BUILTIN(CONFIG_GPIO_OMAP)16581658-void omap2_gpio_prepare_for_idle(int pwr_mode)16591659-{16601660- struct gpio_bank *bank;16611661-16621662- list_for_each_entry(bank, &omap_gpio_list, node) {16631663- if (!BANK_USED(bank) || !bank->loses_context)16641664- continue;16651665-16661666- bank->power_mode = pwr_mode;16671667-16681668- pm_runtime_put_sync_suspend(bank->chip.parent);16691669- }16701543}1671154416721672-void omap2_gpio_resume_after_idle(void)16731673-{16741674- struct gpio_bank *bank;16751675-16761676- list_for_each_entry(bank, &omap_gpio_list, node) {16771677- if (!BANK_USED(bank) || !bank->loses_context)16781678- continue;16791679-16801680- pm_runtime_get_sync(bank->chip.parent);16811681- }16821682-}16831683-#endif16841684-16851685-#if defined(CONFIG_PM)16861545static void omap_gpio_init_context(struct gpio_bank *p)16871546{16881547 struct omap_gpio_reg_offs *regs = p->regs;···17061631 writel_relaxed(bank->context.irqenable2,17071632 bank->base + bank->regs->irqenable2);17081633}17091709-#endif /* CONFIG_PM */17101710-#else17111711-#define omap_gpio_runtime_suspend NULL17121712-#define omap_gpio_runtime_resume NULL17131713-static inline void omap_gpio_init_context(struct gpio_bank *p) {}17141714-#endif1715163416351635+static int __maybe_unused omap_gpio_runtime_suspend(struct device *dev)16361636+{16371637+ struct platform_device *pdev = to_platform_device(dev);16381638+ struct gpio_bank *bank = platform_get_drvdata(pdev);16391639+ unsigned long flags;16401640+ int error = 0;16411641+16421642+ raw_spin_lock_irqsave(&bank->lock, flags);16431643+ /* Must be idled only by CPU_CLUSTER_PM_ENTER? */16441644+ if (bank->irq_usage) {16451645+ error = -EBUSY;16461646+ goto unlock;16471647+ }16481648+ omap_gpio_idle(bank, true);16491649+ bank->is_suspended = true;16501650+unlock:16511651+ raw_spin_unlock_irqrestore(&bank->lock, flags);16521652+16531653+ return error;16541654+}16551655+16561656+static int __maybe_unused omap_gpio_runtime_resume(struct device *dev)16571657+{16581658+ struct platform_device *pdev = to_platform_device(dev);16591659+ struct gpio_bank *bank = platform_get_drvdata(pdev);16601660+ unsigned long flags;16611661+ int error = 0;16621662+16631663+ raw_spin_lock_irqsave(&bank->lock, flags);16641664+ /* Must be unidled only by CPU_CLUSTER_PM_ENTER? */16651665+ if (bank->irq_usage) {16661666+ error = -EBUSY;16671667+ goto unlock;16681668+ }16691669+ omap_gpio_unidle(bank);16701670+ bank->is_suspended = false;16711671+unlock:16721672+ raw_spin_unlock_irqrestore(&bank->lock, flags);16731673+16741674+ return error;16751675+}16761676+16771677+#ifdef CONFIG_ARCH_OMAP2PLUS17161678static const struct dev_pm_ops gpio_pm_ops = {17171679 SET_RUNTIME_PM_OPS(omap_gpio_runtime_suspend, omap_gpio_runtime_resume,17181680 NULL)17191681};16821682+#else16831683+static const struct dev_pm_ops gpio_pm_ops;16841684+#endif /* CONFIG_ARCH_OMAP2PLUS */1720168517211686#if defined(CONFIG_OF)17221687static struct omap_gpio_reg_offs omap2_gpio_regs = {···18051690 .fallingdetect = OMAP4_GPIO_FALLINGDETECT,18061691};1807169216931693+/*16941694+ * Note that omap2 does not currently support idle modes with context loss so16951695+ * no need to add OMAP_GPIO_QUIRK_IDLE_REMOVE_TRIGGER quirk flag to save16961696+ * and restore context.16971697+ */18081698static const struct omap_gpio_platform_data omap2_pdata = {18091699 .regs = &omap2_gpio_regs,18101700 .bank_width = 32,···18201700 .regs = &omap2_gpio_regs,18211701 .bank_width = 32,18221702 .dbck_flag = true,17031703+ .quirks = OMAP_GPIO_QUIRK_IDLE_REMOVE_TRIGGER,18231704};1824170518251706static const struct omap_gpio_platform_data omap4_pdata = {18261707 .regs = &omap4_gpio_regs,18271708 .bank_width = 32,18281709 .dbck_flag = true,17101710+ .quirks = OMAP_GPIO_QUIRK_IDLE_REMOVE_TRIGGER |17111711+ OMAP_GPIO_QUIRK_DEFERRED_WKUP_EN,18291712};1830171318311714static const struct of_device_id omap_gpio_match[] = {
+2-13
include/linux/platform_data/gpio-omap.h
···197197 bool is_mpuio; /* whether the bank is of type MPUIO */198198 u32 non_wakeup_gpios;199199200200+ u32 quirks; /* Version specific quirks mask */201201+200202 struct omap_gpio_reg_offs *regs;201203202204 /* Return context loss count due to PM states changing */203205 int (*get_context_loss_count)(struct device *dev);204206};205205-206206-#if IS_BUILTIN(CONFIG_GPIO_OMAP)207207-extern void omap2_gpio_prepare_for_idle(int off_mode);208208-extern void omap2_gpio_resume_after_idle(void);209209-#else210210-static inline void omap2_gpio_prepare_for_idle(int off_mode)211211-{212212-}213213-214214-static inline void omap2_gpio_resume_after_idle(void)215215-{216216-}217217-#endif218207219208#endif