| .. | .. | 
|---|
| 282 | 282 |  		} | 
|---|
| 283 | 283 |  	} | 
|---|
| 284 | 284 |  	if (resend) | 
|---|
| 285 |  | -		check_irq_resend(desc);  | 
|---|
 | 285 | +		check_irq_resend(desc, false);  | 
|---|
| 286 | 286 |   | 
|---|
| 287 | 287 |  	return ret; | 
|---|
| 288 | 288 |  } | 
|---|
| .. | .. | 
|---|
| 674 | 674 |  } | 
|---|
| 675 | 675 |  EXPORT_SYMBOL_GPL(handle_level_irq); | 
|---|
| 676 | 676 |   | 
|---|
| 677 |  | -#ifdef CONFIG_IRQ_PREFLOW_FASTEOI  | 
|---|
| 678 |  | -static inline void preflow_handler(struct irq_desc *desc)  | 
|---|
| 679 |  | -{  | 
|---|
| 680 |  | -	if (desc->preflow_handler)  | 
|---|
| 681 |  | -		desc->preflow_handler(&desc->irq_data);  | 
|---|
| 682 |  | -}  | 
|---|
| 683 |  | -#else  | 
|---|
| 684 |  | -static inline void preflow_handler(struct irq_desc *desc) { }  | 
|---|
| 685 |  | -#endif  | 
|---|
| 686 |  | -  | 
|---|
| 687 | 677 |  static void cond_unmask_eoi_irq(struct irq_desc *desc, struct irq_chip *chip) | 
|---|
| 688 | 678 |  { | 
|---|
| 689 | 679 |  	if (!(desc->istate & IRQS_ONESHOT)) { | 
|---|
| .. | .. | 
|---|
| 739 | 729 |  	if (desc->istate & IRQS_ONESHOT) | 
|---|
| 740 | 730 |  		mask_irq(desc); | 
|---|
| 741 | 731 |   | 
|---|
| 742 |  | -	preflow_handler(desc);  | 
|---|
| 743 | 732 |  	handle_irq_event(desc); | 
|---|
| 744 | 733 |   | 
|---|
| 745 | 734 |  	cond_unmask_eoi_irq(desc, chip); | 
|---|
| .. | .. | 
|---|
| 752 | 741 |  	raw_spin_unlock(&desc->lock); | 
|---|
| 753 | 742 |  } | 
|---|
| 754 | 743 |  EXPORT_SYMBOL_GPL(handle_fasteoi_irq); | 
|---|
 | 744 | +  | 
|---|
 | 745 | +/**  | 
|---|
 | 746 | + *	handle_fasteoi_nmi - irq handler for NMI interrupt lines  | 
|---|
 | 747 | + *	@desc:	the interrupt description structure for this irq  | 
|---|
 | 748 | + *  | 
|---|
 | 749 | + *	A simple NMI-safe handler, considering the restrictions  | 
|---|
 | 750 | + *	from request_nmi.  | 
|---|
 | 751 | + *  | 
|---|
 | 752 | + *	Only a single callback will be issued to the chip: an ->eoi()  | 
|---|
 | 753 | + *	call when the interrupt has been serviced. This enables support  | 
|---|
 | 754 | + *	for modern forms of interrupt handlers, which handle the flow  | 
|---|
 | 755 | + *	details in hardware, transparently.  | 
|---|
 | 756 | + */  | 
|---|
 | 757 | +void handle_fasteoi_nmi(struct irq_desc *desc)  | 
|---|
 | 758 | +{  | 
|---|
 | 759 | +	struct irq_chip *chip = irq_desc_get_chip(desc);  | 
|---|
 | 760 | +	struct irqaction *action = desc->action;  | 
|---|
 | 761 | +	unsigned int irq = irq_desc_get_irq(desc);  | 
|---|
 | 762 | +	irqreturn_t res;  | 
|---|
 | 763 | +  | 
|---|
 | 764 | +	__kstat_incr_irqs_this_cpu(desc);  | 
|---|
 | 765 | +  | 
|---|
 | 766 | +	trace_irq_handler_entry(irq, action);  | 
|---|
 | 767 | +	/*  | 
|---|
 | 768 | +	 * NMIs cannot be shared, there is only one action.  | 
|---|
 | 769 | +	 */  | 
|---|
 | 770 | +	res = action->handler(irq, action->dev_id);  | 
|---|
 | 771 | +	trace_irq_handler_exit(irq, action, res);  | 
|---|
 | 772 | +  | 
|---|
 | 773 | +	if (chip->irq_eoi)  | 
|---|
 | 774 | +		chip->irq_eoi(&desc->irq_data);  | 
|---|
 | 775 | +}  | 
|---|
 | 776 | +EXPORT_SYMBOL_GPL(handle_fasteoi_nmi);  | 
|---|
| 755 | 777 |   | 
|---|
| 756 | 778 |  /** | 
|---|
| 757 | 779 |   *	handle_edge_irq - edge type IRQ handler | 
|---|
| .. | .. | 
|---|
| 940 | 962 |  		chip->irq_eoi(&desc->irq_data); | 
|---|
| 941 | 963 |  } | 
|---|
| 942 | 964 |   | 
|---|
 | 965 | +/**  | 
|---|
 | 966 | + * handle_percpu_devid_fasteoi_ipi - Per CPU local IPI handler with per cpu  | 
|---|
 | 967 | + *				     dev ids  | 
|---|
 | 968 | + * @desc:	the interrupt description structure for this irq  | 
|---|
 | 969 | + *  | 
|---|
 | 970 | + * The biggest difference with the IRQ version is that the interrupt is  | 
|---|
 | 971 | + * EOIed early, as the IPI could result in a context switch, and we need to  | 
|---|
 | 972 | + * make sure the IPI can fire again. We also assume that the arch code has  | 
|---|
 | 973 | + * registered an action. If not, we are positively doomed.  | 
|---|
 | 974 | + */  | 
|---|
 | 975 | +void handle_percpu_devid_fasteoi_ipi(struct irq_desc *desc)  | 
|---|
 | 976 | +{  | 
|---|
 | 977 | +	struct irq_chip *chip = irq_desc_get_chip(desc);  | 
|---|
 | 978 | +	struct irqaction *action = desc->action;  | 
|---|
 | 979 | +	unsigned int irq = irq_desc_get_irq(desc);  | 
|---|
 | 980 | +	irqreturn_t res;  | 
|---|
 | 981 | +  | 
|---|
 | 982 | +	__kstat_incr_irqs_this_cpu(desc);  | 
|---|
 | 983 | +  | 
|---|
 | 984 | +	if (chip->irq_eoi)  | 
|---|
 | 985 | +		chip->irq_eoi(&desc->irq_data);  | 
|---|
 | 986 | +  | 
|---|
 | 987 | +	trace_irq_handler_entry(irq, action);  | 
|---|
 | 988 | +	res = action->handler(irq, raw_cpu_ptr(action->percpu_dev_id));  | 
|---|
 | 989 | +	trace_irq_handler_exit(irq, action, res);  | 
|---|
 | 990 | +}  | 
|---|
 | 991 | +  | 
|---|
 | 992 | +/**  | 
|---|
 | 993 | + * handle_percpu_devid_fasteoi_nmi - Per CPU local NMI handler with per cpu  | 
|---|
 | 994 | + *				     dev ids  | 
|---|
 | 995 | + * @desc:	the interrupt description structure for this irq  | 
|---|
 | 996 | + *  | 
|---|
 | 997 | + * Similar to handle_fasteoi_nmi, but handling the dev_id cookie  | 
|---|
 | 998 | + * as a percpu pointer.  | 
|---|
 | 999 | + */  | 
|---|
 | 1000 | +void handle_percpu_devid_fasteoi_nmi(struct irq_desc *desc)  | 
|---|
 | 1001 | +{  | 
|---|
 | 1002 | +	struct irq_chip *chip = irq_desc_get_chip(desc);  | 
|---|
 | 1003 | +	struct irqaction *action = desc->action;  | 
|---|
 | 1004 | +	unsigned int irq = irq_desc_get_irq(desc);  | 
|---|
 | 1005 | +	irqreturn_t res;  | 
|---|
 | 1006 | +  | 
|---|
 | 1007 | +	__kstat_incr_irqs_this_cpu(desc);  | 
|---|
 | 1008 | +  | 
|---|
 | 1009 | +	trace_irq_handler_entry(irq, action);  | 
|---|
 | 1010 | +	res = action->handler(irq, raw_cpu_ptr(action->percpu_dev_id));  | 
|---|
 | 1011 | +	trace_irq_handler_exit(irq, action, res);  | 
|---|
 | 1012 | +  | 
|---|
 | 1013 | +	if (chip->irq_eoi)  | 
|---|
 | 1014 | +		chip->irq_eoi(&desc->irq_data);  | 
|---|
 | 1015 | +}  | 
|---|
 | 1016 | +  | 
|---|
| 943 | 1017 |  static void | 
|---|
| 944 | 1018 |  __irq_do_set_handler(struct irq_desc *desc, irq_flow_handler_t handle, | 
|---|
| 945 | 1019 |  		     int is_chained, const char *name) | 
|---|
| .. | .. | 
|---|
| 961 | 1035 |  				break; | 
|---|
| 962 | 1036 |  			/* | 
|---|
| 963 | 1037 |  			 * Bail out if the outer chip is not set up | 
|---|
| 964 |  | -			 * and the interrrupt supposed to be started  | 
|---|
 | 1038 | +			 * and the interrupt supposed to be started  | 
|---|
| 965 | 1039 |  			 * right away. | 
|---|
| 966 | 1040 |  			 */ | 
|---|
| 967 | 1041 |  			if (WARN_ON(is_chained)) | 
|---|
| .. | .. | 
|---|
| 1051 | 1125 |  } | 
|---|
| 1052 | 1126 |  EXPORT_SYMBOL_GPL(irq_set_chip_and_handler_name); | 
|---|
| 1053 | 1127 |   | 
|---|
| 1054 |  | -void irq_modify_status(unsigned int irq, unsigned long clr, unsigned long set)  | 
|---|
 | 1128 | +void __irq_modify_status(unsigned int irq, unsigned long clr,  | 
|---|
 | 1129 | +			 unsigned long set, unsigned long mask)  | 
|---|
| 1055 | 1130 |  { | 
|---|
| 1056 | 1131 |  	unsigned long flags, trigger, tmp; | 
|---|
| 1057 | 1132 |  	struct irq_desc *desc = irq_get_desc_lock(irq, &flags, 0); | 
|---|
| .. | .. | 
|---|
| 1065 | 1140 |  	 */ | 
|---|
| 1066 | 1141 |  	WARN_ON_ONCE(!desc->depth && (set & _IRQ_NOAUTOEN)); | 
|---|
| 1067 | 1142 |   | 
|---|
| 1068 |  | -	irq_settings_clr_and_set(desc, clr, set);  | 
|---|
 | 1143 | +	/* Warn when trying to clear or set a bit disallowed by the mask */  | 
|---|
 | 1144 | +	WARN_ON((clr | set) & ~mask);  | 
|---|
 | 1145 | +	__irq_settings_clr_and_set(desc, clr, set, mask);  | 
|---|
| 1069 | 1146 |   | 
|---|
| 1070 | 1147 |  	trigger = irqd_get_trigger_type(&desc->irq_data); | 
|---|
| 1071 | 1148 |   | 
|---|
| .. | .. | 
|---|
| 1087 | 1164 |  	irqd_set(&desc->irq_data, trigger); | 
|---|
| 1088 | 1165 |   | 
|---|
| 1089 | 1166 |  	irq_put_desc_unlock(desc, flags); | 
|---|
 | 1167 | +}  | 
|---|
 | 1168 | +  | 
|---|
 | 1169 | +void irq_modify_status(unsigned int irq, unsigned long clr, unsigned long set)  | 
|---|
 | 1170 | +{  | 
|---|
 | 1171 | +	__irq_modify_status(irq, clr, set, _IRQF_MODIFY_MASK);  | 
|---|
| 1090 | 1172 |  } | 
|---|
| 1091 | 1173 |  EXPORT_SYMBOL_GPL(irq_modify_status); | 
|---|
| 1092 | 1174 |   | 
|---|
| .. | .. | 
|---|
| 1191 | 1273 |  	/* Start handling the irq */ | 
|---|
| 1192 | 1274 |  	desc->irq_data.chip->irq_ack(&desc->irq_data); | 
|---|
| 1193 | 1275 |   | 
|---|
| 1194 |  | -	preflow_handler(desc);  | 
|---|
| 1195 | 1276 |  	handle_irq_event(desc); | 
|---|
| 1196 | 1277 |   | 
|---|
| 1197 | 1278 |  	cond_unmask_eoi_irq(desc, chip); | 
|---|
| .. | .. | 
|---|
| 1241 | 1322 |  	if (desc->istate & IRQS_ONESHOT) | 
|---|
| 1242 | 1323 |  		mask_irq(desc); | 
|---|
| 1243 | 1324 |   | 
|---|
| 1244 |  | -	preflow_handler(desc);  | 
|---|
| 1245 | 1325 |  	handle_irq_event(desc); | 
|---|
| 1246 | 1326 |   | 
|---|
| 1247 | 1327 |  	cond_unmask_eoi_irq(desc, chip); | 
|---|
| .. | .. | 
|---|
| 1258 | 1338 |  #endif /* CONFIG_IRQ_FASTEOI_HIERARCHY_HANDLERS */ | 
|---|
| 1259 | 1339 |   | 
|---|
| 1260 | 1340 |  /** | 
|---|
| 1261 |  | - *	irq_chip_set_parent_state - set the state of a parent interrupt.  | 
|---|
| 1262 |  | - *	@data: Pointer to interrupt specific data  | 
|---|
| 1263 |  | - *	@which: State to be restored (one of IRQCHIP_STATE_*)  | 
|---|
| 1264 |  | - *	@val: Value corresponding to @which  | 
|---|
 | 1341 | + * irq_chip_set_parent_state - set the state of a parent interrupt.  | 
|---|
| 1265 | 1342 |   * | 
|---|
 | 1343 | + * @data: Pointer to interrupt specific data  | 
|---|
 | 1344 | + * @which: State to be restored (one of IRQCHIP_STATE_*)  | 
|---|
 | 1345 | + * @val: Value corresponding to @which  | 
|---|
 | 1346 | + *  | 
|---|
 | 1347 | + * Conditional success, if the underlying irqchip does not implement it.  | 
|---|
| 1266 | 1348 |   */ | 
|---|
| 1267 | 1349 |  int irq_chip_set_parent_state(struct irq_data *data, | 
|---|
| 1268 | 1350 |  			      enum irqchip_irq_state which, | 
|---|
| 1269 | 1351 |  			      bool val) | 
|---|
| 1270 | 1352 |  { | 
|---|
| 1271 | 1353 |  	data = data->parent_data; | 
|---|
| 1272 |  | -	if (!data)  | 
|---|
 | 1354 | +  | 
|---|
 | 1355 | +	if (!data || !data->chip->irq_set_irqchip_state)  | 
|---|
| 1273 | 1356 |  		return 0; | 
|---|
| 1274 | 1357 |   | 
|---|
| 1275 |  | -	if (data->chip->irq_set_irqchip_state)  | 
|---|
| 1276 |  | -		return data->chip->irq_set_irqchip_state(data, which, val);  | 
|---|
| 1277 |  | -  | 
|---|
| 1278 |  | -	return 0;  | 
|---|
 | 1358 | +	return data->chip->irq_set_irqchip_state(data, which, val);  | 
|---|
| 1279 | 1359 |  } | 
|---|
| 1280 |  | -EXPORT_SYMBOL(irq_chip_set_parent_state);  | 
|---|
 | 1360 | +EXPORT_SYMBOL_GPL(irq_chip_set_parent_state);  | 
|---|
| 1281 | 1361 |   | 
|---|
| 1282 | 1362 |  /** | 
|---|
| 1283 |  | - *	irq_chip_get_parent_state - get the state of a parent interrupt.  | 
|---|
| 1284 |  | - *	@data: Pointer to interrupt specific data  | 
|---|
| 1285 |  | - *	@which: one of IRQCHIP_STATE_* the caller wants to know  | 
|---|
| 1286 |  | - *	@state: a pointer to a boolean where the state is to be stored  | 
|---|
 | 1363 | + * irq_chip_get_parent_state - get the state of a parent interrupt.  | 
|---|
| 1287 | 1364 |   * | 
|---|
 | 1365 | + * @data: Pointer to interrupt specific data  | 
|---|
 | 1366 | + * @which: one of IRQCHIP_STATE_* the caller wants to know  | 
|---|
 | 1367 | + * @state: a pointer to a boolean where the state is to be stored  | 
|---|
 | 1368 | + *  | 
|---|
 | 1369 | + * Conditional success, if the underlying irqchip does not implement it.  | 
|---|
| 1288 | 1370 |   */ | 
|---|
| 1289 | 1371 |  int irq_chip_get_parent_state(struct irq_data *data, | 
|---|
| 1290 | 1372 |  			      enum irqchip_irq_state which, | 
|---|
| 1291 | 1373 |  			      bool *state) | 
|---|
| 1292 | 1374 |  { | 
|---|
| 1293 | 1375 |  	data = data->parent_data; | 
|---|
| 1294 |  | -	if (!data)  | 
|---|
 | 1376 | +  | 
|---|
 | 1377 | +	if (!data || !data->chip->irq_get_irqchip_state)  | 
|---|
| 1295 | 1378 |  		return 0; | 
|---|
| 1296 | 1379 |   | 
|---|
| 1297 |  | -	if (data->chip->irq_get_irqchip_state)  | 
|---|
| 1298 |  | -		return data->chip->irq_get_irqchip_state(data, which, state);  | 
|---|
| 1299 |  | -  | 
|---|
| 1300 |  | -	return 0;  | 
|---|
 | 1380 | +	return data->chip->irq_get_irqchip_state(data, which, state);  | 
|---|
| 1301 | 1381 |  } | 
|---|
| 1302 |  | -EXPORT_SYMBOL(irq_chip_get_parent_state);  | 
|---|
 | 1382 | +EXPORT_SYMBOL_GPL(irq_chip_get_parent_state);  | 
|---|
| 1303 | 1383 |   | 
|---|
| 1304 | 1384 |  /** | 
|---|
| 1305 | 1385 |   * irq_chip_enable_parent - Enable the parent interrupt (defaults to unmask if | 
|---|
| .. | .. | 
|---|
| 1352 | 1432 |  	data->chip->irq_mask(data); | 
|---|
| 1353 | 1433 |  } | 
|---|
| 1354 | 1434 |  EXPORT_SYMBOL_GPL(irq_chip_mask_parent); | 
|---|
 | 1435 | +  | 
|---|
 | 1436 | +/**  | 
|---|
 | 1437 | + * irq_chip_mask_ack_parent - Mask and acknowledge the parent interrupt  | 
|---|
 | 1438 | + * @data:	Pointer to interrupt specific data  | 
|---|
 | 1439 | + */  | 
|---|
 | 1440 | +void irq_chip_mask_ack_parent(struct irq_data *data)  | 
|---|
 | 1441 | +{  | 
|---|
 | 1442 | +	data = data->parent_data;  | 
|---|
 | 1443 | +	data->chip->irq_mask_ack(data);  | 
|---|
 | 1444 | +}  | 
|---|
 | 1445 | +EXPORT_SYMBOL_GPL(irq_chip_mask_ack_parent);  | 
|---|
| 1355 | 1446 |   | 
|---|
| 1356 | 1447 |  /** | 
|---|
| 1357 | 1448 |   * irq_chip_unmask_parent - Unmask the parent interrupt | 
|---|
| .. | .. | 
|---|
| 1443 | 1534 |  	return -ENOSYS; | 
|---|
| 1444 | 1535 |  } | 
|---|
| 1445 | 1536 |  EXPORT_SYMBOL_GPL(irq_chip_set_vcpu_affinity_parent); | 
|---|
| 1446 |  | -  | 
|---|
| 1447 | 1537 |  /** | 
|---|
| 1448 | 1538 |   * irq_chip_set_wake_parent - Set/reset wake-up on the parent interrupt | 
|---|
| 1449 | 1539 |   * @data:	Pointer to interrupt specific data | 
|---|
| .. | .. | 
|---|
| 1464 | 1554 |  	return -ENOSYS; | 
|---|
| 1465 | 1555 |  } | 
|---|
| 1466 | 1556 |  EXPORT_SYMBOL_GPL(irq_chip_set_wake_parent); | 
|---|
 | 1557 | +  | 
|---|
 | 1558 | +/**  | 
|---|
 | 1559 | + * irq_chip_request_resources_parent - Request resources on the parent interrupt  | 
|---|
 | 1560 | + * @data:	Pointer to interrupt specific data  | 
|---|
 | 1561 | + */  | 
|---|
 | 1562 | +int irq_chip_request_resources_parent(struct irq_data *data)  | 
|---|
 | 1563 | +{  | 
|---|
 | 1564 | +	data = data->parent_data;  | 
|---|
 | 1565 | +  | 
|---|
 | 1566 | +	if (data->chip->irq_request_resources)  | 
|---|
 | 1567 | +		return data->chip->irq_request_resources(data);  | 
|---|
 | 1568 | +  | 
|---|
 | 1569 | +	/* no error on missing optional irq_chip::irq_request_resources */  | 
|---|
 | 1570 | +	return 0;  | 
|---|
 | 1571 | +}  | 
|---|
 | 1572 | +EXPORT_SYMBOL_GPL(irq_chip_request_resources_parent);  | 
|---|
 | 1573 | +  | 
|---|
 | 1574 | +/**  | 
|---|
 | 1575 | + * irq_chip_release_resources_parent - Release resources on the parent interrupt  | 
|---|
 | 1576 | + * @data:	Pointer to interrupt specific data  | 
|---|
 | 1577 | + */  | 
|---|
 | 1578 | +void irq_chip_release_resources_parent(struct irq_data *data)  | 
|---|
 | 1579 | +{  | 
|---|
 | 1580 | +	data = data->parent_data;  | 
|---|
 | 1581 | +	if (data->chip->irq_release_resources)  | 
|---|
 | 1582 | +		data->chip->irq_release_resources(data);  | 
|---|
 | 1583 | +}  | 
|---|
 | 1584 | +EXPORT_SYMBOL_GPL(irq_chip_release_resources_parent);  | 
|---|
| 1467 | 1585 |  #endif | 
|---|
| 1468 | 1586 |   | 
|---|
| 1469 | 1587 |  /** | 
|---|
| .. | .. | 
|---|
| 1477 | 1595 |   */ | 
|---|
| 1478 | 1596 |  int irq_chip_compose_msi_msg(struct irq_data *data, struct msi_msg *msg) | 
|---|
| 1479 | 1597 |  { | 
|---|
| 1480 |  | -	struct irq_data *pos = NULL;  | 
|---|
 | 1598 | +	struct irq_data *pos;  | 
|---|
| 1481 | 1599 |   | 
|---|
| 1482 |  | -#ifdef	CONFIG_IRQ_DOMAIN_HIERARCHY  | 
|---|
| 1483 |  | -	for (; data; data = data->parent_data)  | 
|---|
| 1484 |  | -#endif  | 
|---|
 | 1600 | +	for (pos = NULL; !pos && data; data = irqd_get_parent_data(data)) {  | 
|---|
| 1485 | 1601 |  		if (data->chip && data->chip->irq_compose_msi_msg) | 
|---|
| 1486 | 1602 |  			pos = data; | 
|---|
 | 1603 | +	}  | 
|---|
 | 1604 | +  | 
|---|
| 1487 | 1605 |  	if (!pos) | 
|---|
| 1488 | 1606 |  		return -ENOSYS; | 
|---|
| 1489 | 1607 |   | 
|---|
| 1490 | 1608 |  	pos->chip->irq_compose_msi_msg(pos, msg); | 
|---|
| 1491 |  | -  | 
|---|
| 1492 | 1609 |  	return 0; | 
|---|
| 1493 | 1610 |  } | 
|---|
| 1494 | 1611 |   | 
|---|