| .. | .. | 
|---|
| 23 | 23 |   * @nvec:	The number of vectors used in this entry | 
|---|
| 24 | 24 |   * @affinity:	Optional pointer to an affinity mask array size of @nvec | 
|---|
| 25 | 25 |   * | 
|---|
| 26 |  | - * If @affinity is not NULL then a an affinity array[@nvec] is allocated  | 
|---|
| 27 |  | - * and the affinity masks from @affinity are copied.  | 
|---|
 | 26 | + * If @affinity is not NULL then an affinity array[@nvec] is allocated  | 
|---|
 | 27 | + * and the affinity masks and flags from @affinity are copied.  | 
|---|
| 28 | 28 |   */ | 
|---|
| 29 |  | -struct msi_desc *  | 
|---|
| 30 |  | -alloc_msi_entry(struct device *dev, int nvec, const struct cpumask *affinity)  | 
|---|
 | 29 | +struct msi_desc *alloc_msi_entry(struct device *dev, int nvec,  | 
|---|
 | 30 | +				 const struct irq_affinity_desc *affinity)  | 
|---|
| 31 | 31 |  { | 
|---|
| 32 | 32 |  	struct msi_desc *desc; | 
|---|
| 33 | 33 |   | 
|---|
| .. | .. | 
|---|
| 187 | 187 |  	.deactivate	= msi_domain_deactivate, | 
|---|
| 188 | 188 |  }; | 
|---|
| 189 | 189 |   | 
|---|
| 190 |  | -#ifdef GENERIC_MSI_DOMAIN_OPS  | 
|---|
| 191 | 190 |  static irq_hw_number_t msi_domain_ops_get_hwirq(struct msi_domain_info *info, | 
|---|
| 192 | 191 |  						msi_alloc_info_t *arg) | 
|---|
| 193 | 192 |  { | 
|---|
| .. | .. | 
|---|
| 206 | 205 |  { | 
|---|
| 207 | 206 |  	arg->desc = desc; | 
|---|
| 208 | 207 |  } | 
|---|
| 209 |  | -#else  | 
|---|
| 210 |  | -#define msi_domain_ops_get_hwirq	NULL  | 
|---|
| 211 |  | -#define msi_domain_ops_prepare		NULL  | 
|---|
| 212 |  | -#define msi_domain_ops_set_desc		NULL  | 
|---|
| 213 |  | -#endif /* !GENERIC_MSI_DOMAIN_OPS */  | 
|---|
| 214 | 208 |   | 
|---|
| 215 | 209 |  static int msi_domain_ops_init(struct irq_domain *domain, | 
|---|
| 216 | 210 |  			       struct msi_domain_info *info, | 
|---|
| .. | .. | 
|---|
| 235 | 229 |  } | 
|---|
| 236 | 230 |   | 
|---|
| 237 | 231 |  static struct msi_domain_ops msi_domain_ops_default = { | 
|---|
| 238 |  | -	.get_hwirq	= msi_domain_ops_get_hwirq,  | 
|---|
| 239 |  | -	.msi_init	= msi_domain_ops_init,  | 
|---|
| 240 |  | -	.msi_check	= msi_domain_ops_check,  | 
|---|
| 241 |  | -	.msi_prepare	= msi_domain_ops_prepare,  | 
|---|
| 242 |  | -	.set_desc	= msi_domain_ops_set_desc,  | 
|---|
 | 232 | +	.get_hwirq		= msi_domain_ops_get_hwirq,  | 
|---|
 | 233 | +	.msi_init		= msi_domain_ops_init,  | 
|---|
 | 234 | +	.msi_check		= msi_domain_ops_check,  | 
|---|
 | 235 | +	.msi_prepare		= msi_domain_ops_prepare,  | 
|---|
 | 236 | +	.set_desc		= msi_domain_ops_set_desc,  | 
|---|
 | 237 | +	.domain_alloc_irqs	= __msi_domain_alloc_irqs,  | 
|---|
 | 238 | +	.domain_free_irqs	= __msi_domain_free_irqs,  | 
|---|
| 243 | 239 |  }; | 
|---|
| 244 | 240 |   | 
|---|
| 245 | 241 |  static void msi_domain_update_dom_ops(struct msi_domain_info *info) | 
|---|
| .. | .. | 
|---|
| 250 | 246 |  		info->ops = &msi_domain_ops_default; | 
|---|
| 251 | 247 |  		return; | 
|---|
| 252 | 248 |  	} | 
|---|
 | 249 | +  | 
|---|
 | 250 | +	if (ops->domain_alloc_irqs == NULL)  | 
|---|
 | 251 | +		ops->domain_alloc_irqs = msi_domain_ops_default.domain_alloc_irqs;  | 
|---|
 | 252 | +	if (ops->domain_free_irqs == NULL)  | 
|---|
 | 253 | +		ops->domain_free_irqs = msi_domain_ops_default.domain_free_irqs;  | 
|---|
 | 254 | +  | 
|---|
 | 255 | +	if (!(info->flags & MSI_FLAG_USE_DEF_DOM_OPS))  | 
|---|
 | 256 | +		return;  | 
|---|
| 253 | 257 |   | 
|---|
| 254 | 258 |  	if (ops->get_hwirq == NULL) | 
|---|
| 255 | 259 |  		ops->get_hwirq = msi_domain_ops_default.get_hwirq; | 
|---|
| .. | .. | 
|---|
| 284 | 288 |  { | 
|---|
| 285 | 289 |  	struct irq_domain *domain; | 
|---|
| 286 | 290 |   | 
|---|
| 287 |  | -	if (info->flags & MSI_FLAG_USE_DEF_DOM_OPS)  | 
|---|
| 288 |  | -		msi_domain_update_dom_ops(info);  | 
|---|
 | 291 | +	msi_domain_update_dom_ops(info);  | 
|---|
| 289 | 292 |  	if (info->flags & MSI_FLAG_USE_DEF_CHIP_OPS) | 
|---|
| 290 | 293 |  		msi_domain_update_chip_ops(info); | 
|---|
| 291 | 294 |   | 
|---|
| .. | .. | 
|---|
| 370 | 373 |  { | 
|---|
| 371 | 374 |  	struct msi_desc *desc; | 
|---|
| 372 | 375 |   | 
|---|
| 373 |  | -	if (domain->bus_token != DOMAIN_BUS_PCI_MSI)  | 
|---|
 | 376 | +	switch(domain->bus_token) {  | 
|---|
 | 377 | +	case DOMAIN_BUS_PCI_MSI:  | 
|---|
 | 378 | +	case DOMAIN_BUS_VMD_MSI:  | 
|---|
 | 379 | +		break;  | 
|---|
 | 380 | +	default:  | 
|---|
| 374 | 381 |  		return false; | 
|---|
 | 382 | +	}  | 
|---|
| 375 | 383 |   | 
|---|
| 376 | 384 |  	if (!(info->flags & MSI_FLAG_MUST_REACTIVATE)) | 
|---|
| 377 | 385 |  		return false; | 
|---|
| .. | .. | 
|---|
| 387 | 395 |  	return desc->msi_attrib.is_msix || desc->msi_attrib.maskbit; | 
|---|
| 388 | 396 |  } | 
|---|
| 389 | 397 |   | 
|---|
| 390 |  | -/**  | 
|---|
| 391 |  | - * msi_domain_alloc_irqs - Allocate interrupts from a MSI interrupt domain  | 
|---|
| 392 |  | - * @domain:	The domain to allocate from  | 
|---|
| 393 |  | - * @dev:	Pointer to device struct of the device for which the interrupts  | 
|---|
| 394 |  | - *		are allocated  | 
|---|
| 395 |  | - * @nvec:	The number of interrupts to allocate  | 
|---|
| 396 |  | - *  | 
|---|
| 397 |  | - * Returns 0 on success or an error code.  | 
|---|
| 398 |  | - */  | 
|---|
| 399 |  | -int msi_domain_alloc_irqs(struct irq_domain *domain, struct device *dev,  | 
|---|
| 400 |  | -			  int nvec)  | 
|---|
 | 398 | +int __msi_domain_alloc_irqs(struct irq_domain *domain, struct device *dev,  | 
|---|
 | 399 | +			    int nvec)  | 
|---|
| 401 | 400 |  { | 
|---|
| 402 | 401 |  	struct msi_domain_info *info = domain->host_data; | 
|---|
| 403 | 402 |  	struct msi_domain_ops *ops = info->ops; | 
|---|
| .. | .. | 
|---|
| 457 | 456 |  			irqd_clr_can_reserve(irq_data); | 
|---|
| 458 | 457 |  			if (domain->flags & IRQ_DOMAIN_MSI_NOMASK_QUIRK) | 
|---|
| 459 | 458 |  				irqd_set_msi_nomask_quirk(irq_data); | 
|---|
 | 459 | +			if ((info->flags & MSI_FLAG_ACTIVATE_EARLY) &&  | 
|---|
 | 460 | +				irqd_affinity_is_managed(irq_data) &&  | 
|---|
 | 461 | +				!cpumask_intersects(irq_data_get_affinity_mask(irq_data),  | 
|---|
 | 462 | +						    cpu_online_mask)) {  | 
|---|
 | 463 | +				irqd_set_managed_shutdown(irq_data);  | 
|---|
 | 464 | +				continue;  | 
|---|
 | 465 | +			}  | 
|---|
| 460 | 466 |  		} | 
|---|
| 461 | 467 |  		ret = irq_domain_activate_irq(irq_data, can_reserve); | 
|---|
| 462 | 468 |  		if (ret) | 
|---|
| .. | .. | 
|---|
| 482 | 488 |  } | 
|---|
| 483 | 489 |   | 
|---|
| 484 | 490 |  /** | 
|---|
| 485 |  | - * msi_domain_free_irqs - Free interrupts from a MSI interrupt @domain associated tp @dev  | 
|---|
| 486 |  | - * @domain:	The domain to managing the interrupts  | 
|---|
 | 491 | + * msi_domain_alloc_irqs - Allocate interrupts from a MSI interrupt domain  | 
|---|
 | 492 | + * @domain:	The domain to allocate from  | 
|---|
| 487 | 493 |   * @dev:	Pointer to device struct of the device for which the interrupts | 
|---|
| 488 |  | - *		are free  | 
|---|
 | 494 | + *		are allocated  | 
|---|
 | 495 | + * @nvec:	The number of interrupts to allocate  | 
|---|
 | 496 | + *  | 
|---|
 | 497 | + * Returns 0 on success or an error code.  | 
|---|
| 489 | 498 |   */ | 
|---|
| 490 |  | -void msi_domain_free_irqs(struct irq_domain *domain, struct device *dev)  | 
|---|
 | 499 | +int msi_domain_alloc_irqs(struct irq_domain *domain, struct device *dev,  | 
|---|
 | 500 | +			  int nvec)  | 
|---|
 | 501 | +{  | 
|---|
 | 502 | +	struct msi_domain_info *info = domain->host_data;  | 
|---|
 | 503 | +	struct msi_domain_ops *ops = info->ops;  | 
|---|
 | 504 | +  | 
|---|
 | 505 | +	return ops->domain_alloc_irqs(domain, dev, nvec);  | 
|---|
 | 506 | +}  | 
|---|
 | 507 | +  | 
|---|
 | 508 | +void __msi_domain_free_irqs(struct irq_domain *domain, struct device *dev)  | 
|---|
| 491 | 509 |  { | 
|---|
| 492 | 510 |  	struct irq_data *irq_data; | 
|---|
| 493 | 511 |  	struct msi_desc *desc; | 
|---|
| .. | .. | 
|---|
| 513 | 531 |  } | 
|---|
| 514 | 532 |   | 
|---|
| 515 | 533 |  /** | 
|---|
 | 534 | + * __msi_domain_free_irqs - Free interrupts from a MSI interrupt @domain associated tp @dev  | 
|---|
 | 535 | + * @domain:	The domain to managing the interrupts  | 
|---|
 | 536 | + * @dev:	Pointer to device struct of the device for which the interrupts  | 
|---|
 | 537 | + *		are free  | 
|---|
 | 538 | + */  | 
|---|
 | 539 | +void msi_domain_free_irqs(struct irq_domain *domain, struct device *dev)  | 
|---|
 | 540 | +{  | 
|---|
 | 541 | +	struct msi_domain_info *info = domain->host_data;  | 
|---|
 | 542 | +	struct msi_domain_ops *ops = info->ops;  | 
|---|
 | 543 | +  | 
|---|
 | 544 | +	return ops->domain_free_irqs(domain, dev);  | 
|---|
 | 545 | +}  | 
|---|
 | 546 | +  | 
|---|
 | 547 | +/**  | 
|---|
| 516 | 548 |   * msi_get_domain_info - Get the MSI interrupt domain info for @domain | 
|---|
| 517 | 549 |   * @domain:	The interrupt domain to retrieve data from | 
|---|
| 518 | 550 |   * | 
|---|