Provide domain info flags which tell the core to allocate simple descriptors or to free descriptors when the interrupts are freed and implement the required functionality.
Showing the changes to kernel (1 of 2 files). Show all
Unified · Split
| @@ -119,6 +119,32 @@ fail: · 118 unmodified lines | |||
| 119 | return -ENOMEM; | 119 | return -ENOMEM; |
| 120 | } | 120 | } |
| 121 | 121 | ||
| 122 | /** | ||
| 123 | * msi_free_msi_descs_range - Free MSI descriptors of a device | ||
| 124 | * @dev: Device to free the descriptors | ||
| 125 | * @filter: Descriptor state filter | ||
| 126 | * @first_index: Index to start freeing from | ||
| 127 | * @last_index: Last index to be freed | ||
| 128 | */ | ||
| 129 | void msi_free_msi_descs_range(struct device *dev, enum msi_desc_filter filter, | ||
| 130 | unsigned int first_index, unsigned int last_index) | ||
| 131 | { | ||
| 132 | struct msi_desc *desc; | ||
| 133 | |||
| 134 | lockdep_assert_held(&dev->msi.data->mutex); | ||
| 135 | |||
| 136 | msi_for_each_desc(desc, dev, filter) { | ||
| 137 | /* | ||
| 138 | * Stupid for now to handle MSI device domain until the | ||
| 139 | * storage is switched over to an xarray. | ||
| 140 | */ | ||
| 141 | if (desc->msi_index < first_index || desc->msi_index > last_index) | ||
| 142 | continue; | ||
| 143 | list_del(&desc->list); | ||
| 144 | free_msi_entry(desc); | ||
| 145 | } | ||
| 146 | } | ||
| 147 | |||
| 122 | void __get_cached_msi_msg(struct msi_desc *entry, struct msi_msg *msg) | 148 | void __get_cached_msi_msg(struct msi_desc *entry, struct msi_msg *msg) |
| 123 | { | 149 | { |
| 124 | *msg = entry->msg; | 150 | *msg = entry->msg; |
| @@ -879,6 +905,16 @@ skip_activate: · 754 unmodified lines | |||
| 879 | return 0; | 905 | return 0; |
| 880 | } | 906 | } |
| 881 | 907 | ||
| 908 | static int msi_domain_add_simple_msi_descs(struct msi_domain_info *info, | ||
| 909 | struct device *dev, | ||
| 910 | unsigned int num_descs) | ||
| 911 | { | ||
| 912 | if (!(info->flags & MSI_FLAG_ALLOC_SIMPLE_MSI_DESCS)) | ||
| 913 | return 0; | ||
| 914 | |||
| 915 | return msi_add_simple_msi_descs(dev, 0, num_descs); | ||
| 916 | } | ||
| 917 | |||
| 882 | /** | 918 | /** |
| 883 | * msi_domain_alloc_irqs_descs_locked - Allocate interrupts from a MSI interrupt domain | 919 | * msi_domain_alloc_irqs_descs_locked - Allocate interrupts from a MSI interrupt domain |
| 884 | * @domain: The domain to allocate from | 920 | * @domain: The domain to allocate from |
| @@ -901,6 +937,10 @@ int msi_domain_alloc_irqs_descs_locked(struct irq_domain *domain, struct device · 16 unmodified lines | |||
| 901 | 937 | ||
| 902 | lockdep_assert_held(&dev->msi.data->mutex); | 938 | lockdep_assert_held(&dev->msi.data->mutex); |
| 903 | 939 | ||
| 940 | ret = msi_domain_add_simple_msi_descs(info, dev, nvec); | ||
| 941 | if (ret) | ||
| 942 | return ret; | ||
| 943 | |||
| 904 | ret = ops->domain_alloc_irqs(domain, dev, nvec); | 944 | ret = ops->domain_alloc_irqs(domain, dev, nvec); |
| 905 | if (ret) | 945 | if (ret) |
| 906 | goto cleanup; | 946 | goto cleanup; |
| @@ -962,6 +1002,13 @@ void __msi_domain_free_irqs(struct irq_domain *domain, struct device *dev) · 55 unmodified lines | |||
| 962 | } | 1002 | } |
| 963 | } | 1003 | } |
| 964 | 1004 | ||
| 1005 | static void msi_domain_free_msi_descs(struct msi_domain_info *info, | ||
| 1006 | struct device *dev) | ||
| 1007 | { | ||
| 1008 | if (info->flags & MSI_FLAG_FREE_MSI_DESCS) | ||
| 1009 | msi_free_msi_descs(dev); | ||
| 1010 | } | ||
| 1011 | |||
| 965 | /** | 1012 | /** |
| 966 | * msi_domain_free_irqs_descs_locked - Free interrupts from a MSI interrupt @domain associated to @dev | 1013 | * msi_domain_free_irqs_descs_locked - Free interrupts from a MSI interrupt @domain associated to @dev |
| 967 | * @domain: The domain to managing the interrupts | 1014 | * @domain: The domain to managing the interrupts |
| @@ -982,6 +1029,7 @@ void msi_domain_free_irqs_descs_locked(struct irq_domain *domain, struct device · 14 unmodified lines | |||
| 982 | if (info->flags & MSI_FLAG_DEV_SYSFS) | 1029 | if (info->flags & MSI_FLAG_DEV_SYSFS) |
| 983 | msi_device_destroy_sysfs(dev); | 1030 | msi_device_destroy_sysfs(dev); |
| 984 | ops->domain_free_irqs(domain, dev); | 1031 | ops->domain_free_irqs(domain, dev); |
| 1032 | msi_domain_free_msi_descs(info, dev); | ||
| 985 | } | 1033 | } |
| 986 | 1034 | ||
| 987 | /** | 1035 | /** |