aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/irq/chip.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/irq/chip.c')
-rw-r--r--kernel/irq/chip.c109
1 files changed, 109 insertions, 0 deletions
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index a3cc37c0c85e..23958980189d 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -1092,6 +1092,112 @@ void irq_cpu_offline(void)
1092} 1092}
1093 1093
1094#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY 1094#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
1095
1096#ifdef CONFIG_IRQ_FASTEOI_HIERARCHY_HANDLERS
1097/**
1098 * handle_fasteoi_ack_irq - irq handler for edge hierarchy
1099 * stacked on transparent controllers
1100 *
1101 * @desc: the interrupt description structure for this irq
1102 *
1103 * Like handle_fasteoi_irq(), but for use with hierarchy where
1104 * the irq_chip also needs to have its ->irq_ack() function
1105 * called.
1106 */
1107void handle_fasteoi_ack_irq(struct irq_desc *desc)
1108{
1109 struct irq_chip *chip = desc->irq_data.chip;
1110
1111 raw_spin_lock(&desc->lock);
1112
1113 if (!irq_may_run(desc))
1114 goto out;
1115
1116 desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING);
1117
1118 /*
1119 * If its disabled or no action available
1120 * then mask it and get out of here:
1121 */
1122 if (unlikely(!desc->action || irqd_irq_disabled(&desc->irq_data))) {
1123 desc->istate |= IRQS_PENDING;
1124 mask_irq(desc);
1125 goto out;
1126 }
1127
1128 kstat_incr_irqs_this_cpu(desc);
1129 if (desc->istate & IRQS_ONESHOT)
1130 mask_irq(desc);
1131
1132 /* Start handling the irq */
1133 desc->irq_data.chip->irq_ack(&desc->irq_data);
1134
1135 preflow_handler(desc);
1136 handle_irq_event(desc);
1137
1138 cond_unmask_eoi_irq(desc, chip);
1139
1140 raw_spin_unlock(&desc->lock);
1141 return;
1142out:
1143 if (!(chip->flags & IRQCHIP_EOI_IF_HANDLED))
1144 chip->irq_eoi(&desc->irq_data);
1145 raw_spin_unlock(&desc->lock);
1146}
1147EXPORT_SYMBOL_GPL(handle_fasteoi_ack_irq);
1148
1149/**
1150 * handle_fasteoi_mask_irq - irq handler for level hierarchy
1151 * stacked on transparent controllers
1152 *
1153 * @desc: the interrupt description structure for this irq
1154 *
1155 * Like handle_fasteoi_irq(), but for use with hierarchy where
1156 * the irq_chip also needs to have its ->irq_mask_ack() function
1157 * called.
1158 */
1159void handle_fasteoi_mask_irq(struct irq_desc *desc)
1160{
1161 struct irq_chip *chip = desc->irq_data.chip;
1162
1163 raw_spin_lock(&desc->lock);
1164 mask_ack_irq(desc);
1165
1166 if (!irq_may_run(desc))
1167 goto out;
1168
1169 desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING);
1170
1171 /*
1172 * If its disabled or no action available
1173 * then mask it and get out of here:
1174 */
1175 if (unlikely(!desc->action || irqd_irq_disabled(&desc->irq_data))) {
1176 desc->istate |= IRQS_PENDING;
1177 mask_irq(desc);
1178 goto out;
1179 }
1180
1181 kstat_incr_irqs_this_cpu(desc);
1182 if (desc->istate & IRQS_ONESHOT)
1183 mask_irq(desc);
1184
1185 preflow_handler(desc);
1186 handle_irq_event(desc);
1187
1188 cond_unmask_eoi_irq(desc, chip);
1189
1190 raw_spin_unlock(&desc->lock);
1191 return;
1192out:
1193 if (!(chip->flags & IRQCHIP_EOI_IF_HANDLED))
1194 chip->irq_eoi(&desc->irq_data);
1195 raw_spin_unlock(&desc->lock);
1196}
1197EXPORT_SYMBOL_GPL(handle_fasteoi_mask_irq);
1198
1199#endif /* CONFIG_IRQ_FASTEOI_HIERARCHY_HANDLERS */
1200
1095/** 1201/**
1096 * irq_chip_enable_parent - Enable the parent interrupt (defaults to unmask if 1202 * irq_chip_enable_parent - Enable the parent interrupt (defaults to unmask if
1097 * NULL) 1203 * NULL)
@@ -1105,6 +1211,7 @@ void irq_chip_enable_parent(struct irq_data *data)
1105 else 1211 else
1106 data->chip->irq_unmask(data); 1212 data->chip->irq_unmask(data);
1107} 1213}
1214EXPORT_SYMBOL_GPL(irq_chip_enable_parent);
1108 1215
1109/** 1216/**
1110 * irq_chip_disable_parent - Disable the parent interrupt (defaults to mask if 1217 * irq_chip_disable_parent - Disable the parent interrupt (defaults to mask if
@@ -1119,6 +1226,7 @@ void irq_chip_disable_parent(struct irq_data *data)
1119 else 1226 else
1120 data->chip->irq_mask(data); 1227 data->chip->irq_mask(data);
1121} 1228}
1229EXPORT_SYMBOL_GPL(irq_chip_disable_parent);
1122 1230
1123/** 1231/**
1124 * irq_chip_ack_parent - Acknowledge the parent interrupt 1232 * irq_chip_ack_parent - Acknowledge the parent interrupt
@@ -1181,6 +1289,7 @@ int irq_chip_set_affinity_parent(struct irq_data *data,
1181 1289
1182 return -ENOSYS; 1290 return -ENOSYS;
1183} 1291}
1292EXPORT_SYMBOL_GPL(irq_chip_set_affinity_parent);
1184 1293
1185/** 1294/**
1186 * irq_chip_set_type_parent - Set IRQ type on the parent interrupt 1295 * irq_chip_set_type_parent - Set IRQ type on the parent interrupt