diff options
author | Jon Hunter <jonathanh@nvidia.com> | 2016-06-07 11:12:29 -0400 |
---|---|---|
committer | Marc Zyngier <marc.zyngier@arm.com> | 2016-06-13 06:53:51 -0400 |
commit | be45beb2df6909d42a6b3b0052601b3eef878fc0 (patch) | |
tree | ec2e157704e95b7d78cffc5be6026b6f7f022a7d /kernel/irq/chip.c | |
parent | 1e2a7d78499ec8859d2b469051b7b80bad3b08aa (diff) |
genirq: Add runtime power management support for IRQ chips
Some IRQ chips may be located in a power domain outside of the CPU
subsystem and hence will require device specific runtime power
management. In order to support such IRQ chips, add a pointer for a
device structure to the irq_chip structure, and if this pointer is
populated by the IRQ chip driver and CONFIG_PM is selected in the kernel
configuration, then the pm_runtime_get/put APIs for this chip will be
called when an IRQ is requested/freed, respectively.
Reviewed-by: Kevin Hilman <khilman@baylibre.com>
Signed-off-by: Jon Hunter <jonathanh@nvidia.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Diffstat (limited to 'kernel/irq/chip.c')
-rw-r--r-- | kernel/irq/chip.c | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index 2f9f2b0e79f2..ad8131473774 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c | |||
@@ -1093,3 +1093,43 @@ int irq_chip_compose_msi_msg(struct irq_data *data, struct msi_msg *msg) | |||
1093 | 1093 | ||
1094 | return 0; | 1094 | return 0; |
1095 | } | 1095 | } |
1096 | |||
1097 | /** | ||
1098 | * irq_chip_pm_get - Enable power for an IRQ chip | ||
1099 | * @data: Pointer to interrupt specific data | ||
1100 | * | ||
1101 | * Enable the power to the IRQ chip referenced by the interrupt data | ||
1102 | * structure. | ||
1103 | */ | ||
1104 | int irq_chip_pm_get(struct irq_data *data) | ||
1105 | { | ||
1106 | int retval; | ||
1107 | |||
1108 | if (IS_ENABLED(CONFIG_PM) && data->chip->parent_device) { | ||
1109 | retval = pm_runtime_get_sync(data->chip->parent_device); | ||
1110 | if (retval < 0) { | ||
1111 | pm_runtime_put_noidle(data->chip->parent_device); | ||
1112 | return retval; | ||
1113 | } | ||
1114 | } | ||
1115 | |||
1116 | return 0; | ||
1117 | } | ||
1118 | |||
1119 | /** | ||
1120 | * irq_chip_pm_put - Disable power for an IRQ chip | ||
1121 | * @data: Pointer to interrupt specific data | ||
1122 | * | ||
1123 | * Disable the power to the IRQ chip referenced by the interrupt data | ||
1124 | * structure, belongs. Note that power will only be disabled, once this | ||
1125 | * function has been called for all IRQs that have called irq_chip_pm_get(). | ||
1126 | */ | ||
1127 | int irq_chip_pm_put(struct irq_data *data) | ||
1128 | { | ||
1129 | int retval = 0; | ||
1130 | |||
1131 | if (IS_ENABLED(CONFIG_PM) && data->chip->parent_device) | ||
1132 | retval = pm_runtime_put(data->chip->parent_device); | ||
1133 | |||
1134 | return (retval < 0) ? retval : 0; | ||
1135 | } | ||