aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorTarun Kanti DebBarma <tarun.kanti@ti.com>2011-09-28 21:53:22 -0400
committerTarun Kanti DebBarma <tarun.kanti@ti.com>2012-02-06 03:43:44 -0500
commit55b93c32520dc7ff0097db81db9b1e6b735951a9 (patch)
tree49b2c64c5a0d32382e1980245b601d47ff500c30 /drivers
parentec9af5d9f9399ceb340ee26afcc7d23e9d2a94c2 (diff)
gpio/omap: use pm-runtime framework
Call runtime pm APIs pm_runtime_get_sync() and pm_runtime_put() for enabling/disabling clocks appropriately. Remove syscore_ops and instead use SET_RUNTIME_PM_OPS macro. There is no more need to call omap_device_disable_idle_on_suspend since driver is PM runtime adapted now. Signed-off-by: Charulatha V <charu@ti.com> Signed-off-by: Tarun Kanti DebBarma <tarun.kanti@ti.com> Reviewed-by: Santosh Shilimkar <santosh.shilimkar@ti.com> Reviewed-by: Kevin Hilman <khilman@ti.com> Signed-off-by: Kevin Hilman <khilman@ti.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpio/gpio-omap.c68
1 files changed, 44 insertions, 24 deletions
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
index 951d7843581..7e1e50c23f9 100644
--- a/drivers/gpio/gpio-omap.c
+++ b/drivers/gpio/gpio-omap.c
@@ -21,6 +21,7 @@
21#include <linux/io.h> 21#include <linux/io.h>
22#include <linux/slab.h> 22#include <linux/slab.h>
23#include <linux/pm_runtime.h> 23#include <linux/pm_runtime.h>
24#include <linux/pm.h>
24 25
25#include <mach/hardware.h> 26#include <mach/hardware.h>
26#include <asm/irq.h> 27#include <asm/irq.h>
@@ -483,8 +484,14 @@ static int omap_gpio_request(struct gpio_chip *chip, unsigned offset)
483 struct gpio_bank *bank = container_of(chip, struct gpio_bank, chip); 484 struct gpio_bank *bank = container_of(chip, struct gpio_bank, chip);
484 unsigned long flags; 485 unsigned long flags;
485 486
486 spin_lock_irqsave(&bank->lock, flags); 487 /*
488 * If this is the first gpio_request for the bank,
489 * enable the bank module.
490 */
491 if (!bank->mod_usage)
492 pm_runtime_get_sync(bank->dev);
487 493
494 spin_lock_irqsave(&bank->lock, flags);
488 /* Set trigger to none. You need to enable the desired trigger with 495 /* Set trigger to none. You need to enable the desired trigger with
489 * request_irq() or set_irq_type(). 496 * request_irq() or set_irq_type().
490 */ 497 */
@@ -540,6 +547,13 @@ static void omap_gpio_free(struct gpio_chip *chip, unsigned offset)
540 547
541 _reset_gpio(bank, bank->chip.base + offset); 548 _reset_gpio(bank, bank->chip.base + offset);
542 spin_unlock_irqrestore(&bank->lock, flags); 549 spin_unlock_irqrestore(&bank->lock, flags);
550
551 /*
552 * If this is the last gpio to be freed in the bank,
553 * disable the bank module.
554 */
555 if (!bank->mod_usage)
556 pm_runtime_put(bank->dev);
543} 557}
544 558
545/* 559/*
@@ -565,6 +579,7 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
565 579
566 bank = irq_get_handler_data(irq); 580 bank = irq_get_handler_data(irq);
567 isr_reg = bank->base + bank->regs->irqstatus; 581 isr_reg = bank->base + bank->regs->irqstatus;
582 pm_runtime_get_sync(bank->dev);
568 583
569 if (WARN_ON(!isr_reg)) 584 if (WARN_ON(!isr_reg))
570 goto exit; 585 goto exit;
@@ -625,6 +640,7 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
625exit: 640exit:
626 if (!unmasked) 641 if (!unmasked)
627 chained_irq_exit(chip, desc); 642 chained_irq_exit(chip, desc);
643 pm_runtime_put(bank->dev);
628} 644}
629 645
630static void gpio_irq_shutdown(struct irq_data *d) 646static void gpio_irq_shutdown(struct irq_data *d)
@@ -1037,6 +1053,7 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev)
1037 } 1053 }
1038 1054
1039 pm_runtime_enable(bank->dev); 1055 pm_runtime_enable(bank->dev);
1056 pm_runtime_irq_safe(bank->dev);
1040 pm_runtime_get_sync(bank->dev); 1057 pm_runtime_get_sync(bank->dev);
1041 1058
1042 if (bank->is_mpuio) 1059 if (bank->is_mpuio)
@@ -1046,6 +1063,8 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev)
1046 omap_gpio_chip_init(bank); 1063 omap_gpio_chip_init(bank);
1047 omap_gpio_show_rev(bank); 1064 omap_gpio_show_rev(bank);
1048 1065
1066 pm_runtime_put(bank->dev);
1067
1049 list_add_tail(&bank->node, &omap_gpio_list); 1068 list_add_tail(&bank->node, &omap_gpio_list);
1050 1069
1051 return ret; 1070 return ret;
@@ -1056,7 +1075,10 @@ err_exit:
1056 return ret; 1075 return ret;
1057} 1076}
1058 1077
1059static int omap_gpio_suspend(void) 1078#ifdef CONFIG_ARCH_OMAP2PLUS
1079
1080#if defined(CONFIG_PM_SLEEP)
1081static int omap_gpio_suspend(struct device *dev)
1060{ 1082{
1061 struct gpio_bank *bank; 1083 struct gpio_bank *bank;
1062 1084
@@ -1080,7 +1102,7 @@ static int omap_gpio_suspend(void)
1080 return 0; 1102 return 0;
1081} 1103}
1082 1104
1083static void omap_gpio_resume(void) 1105static int omap_gpio_resume(struct device *dev)
1084{ 1106{
1085 struct gpio_bank *bank; 1107 struct gpio_bank *bank;
1086 1108
@@ -1089,21 +1111,17 @@ static void omap_gpio_resume(void)
1089 unsigned long flags; 1111 unsigned long flags;
1090 1112
1091 if (!bank->regs->wkup_en) 1113 if (!bank->regs->wkup_en)
1092 return; 1114 return 0;
1093 1115
1094 spin_lock_irqsave(&bank->lock, flags); 1116 spin_lock_irqsave(&bank->lock, flags);
1095 _gpio_rmw(base, bank->regs->wkup_en, 0xffffffff, 0); 1117 _gpio_rmw(base, bank->regs->wkup_en, 0xffffffff, 0);
1096 _gpio_rmw(base, bank->regs->wkup_en, bank->saved_wakeup, 1); 1118 _gpio_rmw(base, bank->regs->wkup_en, bank->saved_wakeup, 1);
1097 spin_unlock_irqrestore(&bank->lock, flags); 1119 spin_unlock_irqrestore(&bank->lock, flags);
1098 } 1120 }
1099}
1100
1101static struct syscore_ops omap_gpio_syscore_ops = {
1102 .suspend = omap_gpio_suspend,
1103 .resume = omap_gpio_resume,
1104};
1105 1121
1106#ifdef CONFIG_ARCH_OMAP2PLUS 1122 return 0;
1123}
1124#endif /* CONFIG_PM_SLEEP */
1107 1125
1108static void omap_gpio_save_context(struct gpio_bank *bank); 1126static void omap_gpio_save_context(struct gpio_bank *bank);
1109static void omap_gpio_restore_context(struct gpio_bank *bank); 1127static void omap_gpio_restore_context(struct gpio_bank *bank);
@@ -1145,11 +1163,15 @@ void omap2_gpio_prepare_for_idle(int off_mode)
1145 __raw_writel(l2, bank->base + bank->regs->risingdetect); 1163 __raw_writel(l2, bank->base + bank->regs->risingdetect);
1146 1164
1147save_gpio_context: 1165save_gpio_context:
1166
1148 if (bank->get_context_loss_count) 1167 if (bank->get_context_loss_count)
1149 bank->context_loss_count = 1168 bank->context_loss_count =
1150 bank->get_context_loss_count(bank->dev); 1169 bank->get_context_loss_count(bank->dev);
1151 1170
1152 omap_gpio_save_context(bank); 1171 omap_gpio_save_context(bank);
1172
1173 if (!pm_runtime_suspended(bank->dev))
1174 pm_runtime_put(bank->dev);
1153 } 1175 }
1154} 1176}
1155 1177
@@ -1168,6 +1190,9 @@ void omap2_gpio_resume_after_idle(void)
1168 for (j = 0; j < hweight_long(bank->dbck_enable_mask); j++) 1190 for (j = 0; j < hweight_long(bank->dbck_enable_mask); j++)
1169 clk_enable(bank->dbck); 1191 clk_enable(bank->dbck);
1170 1192
1193 if (pm_runtime_suspended(bank->dev))
1194 pm_runtime_get_sync(bank->dev);
1195
1171 if (bank->get_context_loss_count) { 1196 if (bank->get_context_loss_count) {
1172 context_lost_cnt_after = 1197 context_lost_cnt_after =
1173 bank->get_context_loss_count(bank->dev); 1198 bank->get_context_loss_count(bank->dev);
@@ -1274,12 +1299,20 @@ static void omap_gpio_restore_context(struct gpio_bank *bank)
1274 bank->base + bank->regs->fallingdetect); 1299 bank->base + bank->regs->fallingdetect);
1275 __raw_writel(bank->context.dataout, bank->base + bank->regs->dataout); 1300 __raw_writel(bank->context.dataout, bank->base + bank->regs->dataout);
1276} 1301}
1302#else
1303#define omap_gpio_suspend NULL
1304#define omap_gpio_resume NULL
1277#endif 1305#endif
1278 1306
1307static const struct dev_pm_ops gpio_pm_ops = {
1308 SET_SYSTEM_SLEEP_PM_OPS(omap_gpio_suspend, omap_gpio_resume)
1309};
1310
1279static struct platform_driver omap_gpio_driver = { 1311static struct platform_driver omap_gpio_driver = {
1280 .probe = omap_gpio_probe, 1312 .probe = omap_gpio_probe,
1281 .driver = { 1313 .driver = {
1282 .name = "omap_gpio", 1314 .name = "omap_gpio",
1315 .pm = &gpio_pm_ops,
1283 }, 1316 },
1284}; 1317};
1285 1318
@@ -1293,16 +1326,3 @@ static int __init omap_gpio_drv_reg(void)
1293 return platform_driver_register(&omap_gpio_driver); 1326 return platform_driver_register(&omap_gpio_driver);
1294} 1327}
1295postcore_initcall(omap_gpio_drv_reg); 1328postcore_initcall(omap_gpio_drv_reg);
1296
1297static int __init omap_gpio_sysinit(void)
1298{
1299
1300#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2PLUS)
1301 if (cpu_is_omap16xx() || cpu_class_is_omap2())
1302 register_syscore_ops(&omap_gpio_syscore_ops);
1303#endif
1304
1305 return 0;
1306}
1307
1308arch_initcall(omap_gpio_sysinit);