diff options
author | Tarun Kanti DebBarma <tarun.kanti@ti.com> | 2011-09-28 21:53:22 -0400 |
---|---|---|
committer | Tarun Kanti DebBarma <tarun.kanti@ti.com> | 2012-02-06 03:43:44 -0500 |
commit | 55b93c32520dc7ff0097db81db9b1e6b735951a9 (patch) | |
tree | 49b2c64c5a0d32382e1980245b601d47ff500c30 /drivers/gpio/gpio-omap.c | |
parent | ec9af5d9f9399ceb340ee26afcc7d23e9d2a94c2 (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/gpio/gpio-omap.c')
-rw-r--r-- | drivers/gpio/gpio-omap.c | 68 |
1 files changed, 44 insertions, 24 deletions
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 951d78435812..7e1e50c23f93 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) | |||
625 | exit: | 640 | exit: |
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 | ||
630 | static void gpio_irq_shutdown(struct irq_data *d) | 646 | static 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 | ||
1059 | static int omap_gpio_suspend(void) | 1078 | #ifdef CONFIG_ARCH_OMAP2PLUS |
1079 | |||
1080 | #if defined(CONFIG_PM_SLEEP) | ||
1081 | static 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 | ||
1083 | static void omap_gpio_resume(void) | 1105 | static 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 | |||
1101 | static 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 | ||
1108 | static void omap_gpio_save_context(struct gpio_bank *bank); | 1126 | static void omap_gpio_save_context(struct gpio_bank *bank); |
1109 | static void omap_gpio_restore_context(struct gpio_bank *bank); | 1127 | static 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 | ||
1147 | save_gpio_context: | 1165 | save_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 | ||
1307 | static const struct dev_pm_ops gpio_pm_ops = { | ||
1308 | SET_SYSTEM_SLEEP_PM_OPS(omap_gpio_suspend, omap_gpio_resume) | ||
1309 | }; | ||
1310 | |||
1279 | static struct platform_driver omap_gpio_driver = { | 1311 | static 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 | } |
1295 | postcore_initcall(omap_gpio_drv_reg); | 1328 | postcore_initcall(omap_gpio_drv_reg); |
1296 | |||
1297 | static 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 | |||
1308 | arch_initcall(omap_gpio_sysinit); | ||