diff options
author | Lucas Stach <l.stach@pengutronix.de> | 2014-09-30 12:36:27 -0400 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2014-10-01 14:40:21 -0400 |
commit | c8df6ac9452e8f47a6f660993c526d13e858a6f3 (patch) | |
tree | 283404af3b0be1e0337bbbf8266c4c249b7aa1d4 | |
parent | 91f8ae823f2be0ea3863360dc9327ab573a8f183 (diff) |
PCI: designware: Remove open-coded bitmap operations
Replace them by using the standard kernel bitmap ops. No functional
change, but makes the code a lot cleaner.
Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Pratyush Anand <pratyush.anand@st.com>
Acked-by: Jingoo Han <jg1.han@samsung.com>
-rw-r--r-- | drivers/pci/host/pcie-designware.c | 51 |
1 files changed, 7 insertions, 44 deletions
diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c index 339296cbc823..dfed00aa3ac0 100644 --- a/drivers/pci/host/pcie-designware.c +++ b/drivers/pci/host/pcie-designware.c | |||
@@ -196,30 +196,6 @@ void dw_pcie_msi_init(struct pcie_port *pp) | |||
196 | dw_pcie_wr_own_conf(pp, PCIE_MSI_ADDR_HI, 4, 0); | 196 | dw_pcie_wr_own_conf(pp, PCIE_MSI_ADDR_HI, 4, 0); |
197 | } | 197 | } |
198 | 198 | ||
199 | static int find_valid_pos0(struct pcie_port *pp, int msgvec, int pos, int *pos0) | ||
200 | { | ||
201 | int flag = 1; | ||
202 | |||
203 | do { | ||
204 | pos = find_next_zero_bit(pp->msi_irq_in_use, | ||
205 | MAX_MSI_IRQS, pos); | ||
206 | /*if you have reached to the end then get out from here.*/ | ||
207 | if (pos == MAX_MSI_IRQS) | ||
208 | return -ENOSPC; | ||
209 | /* | ||
210 | * Check if this position is at correct offset.nvec is always a | ||
211 | * power of two. pos0 must be nvec bit aligned. | ||
212 | */ | ||
213 | if (pos % msgvec) | ||
214 | pos += msgvec - (pos % msgvec); | ||
215 | else | ||
216 | flag = 0; | ||
217 | } while (flag); | ||
218 | |||
219 | *pos0 = pos; | ||
220 | return 0; | ||
221 | } | ||
222 | |||
223 | static void dw_pcie_msi_clear_irq(struct pcie_port *pp, int irq) | 199 | static void dw_pcie_msi_clear_irq(struct pcie_port *pp, int irq) |
224 | { | 200 | { |
225 | unsigned int res, bit, val; | 201 | unsigned int res, bit, val; |
@@ -238,13 +214,14 @@ static void clear_irq_range(struct pcie_port *pp, unsigned int irq_base, | |||
238 | 214 | ||
239 | for (i = 0; i < nvec; i++) { | 215 | for (i = 0; i < nvec; i++) { |
240 | irq_set_msi_desc_off(irq_base, i, NULL); | 216 | irq_set_msi_desc_off(irq_base, i, NULL); |
241 | clear_bit(pos + i, pp->msi_irq_in_use); | ||
242 | /* Disable corresponding interrupt on MSI controller */ | 217 | /* Disable corresponding interrupt on MSI controller */ |
243 | if (pp->ops->msi_clear_irq) | 218 | if (pp->ops->msi_clear_irq) |
244 | pp->ops->msi_clear_irq(pp, pos + i); | 219 | pp->ops->msi_clear_irq(pp, pos + i); |
245 | else | 220 | else |
246 | dw_pcie_msi_clear_irq(pp, pos + i); | 221 | dw_pcie_msi_clear_irq(pp, pos + i); |
247 | } | 222 | } |
223 | |||
224 | bitmap_release_region(pp->msi_irq_in_use, pos, order_base_2(nvec)); | ||
248 | } | 225 | } |
249 | 226 | ||
250 | static void dw_pcie_msi_set_irq(struct pcie_port *pp, int irq) | 227 | static void dw_pcie_msi_set_irq(struct pcie_port *pp, int irq) |
@@ -260,26 +237,13 @@ static void dw_pcie_msi_set_irq(struct pcie_port *pp, int irq) | |||
260 | 237 | ||
261 | static int assign_irq(int no_irqs, struct msi_desc *desc, int *pos) | 238 | static int assign_irq(int no_irqs, struct msi_desc *desc, int *pos) |
262 | { | 239 | { |
263 | int irq, pos0, pos1, i; | 240 | int irq, pos0, i; |
264 | struct pcie_port *pp = sys_to_pcie(desc->dev->bus->sysdata); | 241 | struct pcie_port *pp = sys_to_pcie(desc->dev->bus->sysdata); |
265 | 242 | ||
266 | pos0 = find_first_zero_bit(pp->msi_irq_in_use, | 243 | pos0 = bitmap_find_free_region(pp->msi_irq_in_use, MAX_MSI_IRQS, |
267 | MAX_MSI_IRQS); | 244 | order_base_2(no_irqs)); |
268 | if (pos0 % no_irqs) { | 245 | if (pos0 < 0) |
269 | if (find_valid_pos0(pp, no_irqs, pos0, &pos0)) | 246 | goto no_valid_irq; |
270 | goto no_valid_irq; | ||
271 | } | ||
272 | if (no_irqs > 1) { | ||
273 | pos1 = find_next_bit(pp->msi_irq_in_use, | ||
274 | MAX_MSI_IRQS, pos0); | ||
275 | /* there must be nvec number of consecutive free bits */ | ||
276 | while ((pos1 - pos0) < no_irqs) { | ||
277 | if (find_valid_pos0(pp, no_irqs, pos1, &pos0)) | ||
278 | goto no_valid_irq; | ||
279 | pos1 = find_next_bit(pp->msi_irq_in_use, | ||
280 | MAX_MSI_IRQS, pos0); | ||
281 | } | ||
282 | } | ||
283 | 247 | ||
284 | irq = irq_find_mapping(pp->irq_domain, pos0); | 248 | irq = irq_find_mapping(pp->irq_domain, pos0); |
285 | if (!irq) | 249 | if (!irq) |
@@ -297,7 +261,6 @@ static int assign_irq(int no_irqs, struct msi_desc *desc, int *pos) | |||
297 | clear_irq_range(pp, irq, i, pos0); | 261 | clear_irq_range(pp, irq, i, pos0); |
298 | goto no_valid_irq; | 262 | goto no_valid_irq; |
299 | } | 263 | } |
300 | set_bit(pos0 + i, pp->msi_irq_in_use); | ||
301 | /*Enable corresponding interrupt in MSI interrupt controller */ | 264 | /*Enable corresponding interrupt in MSI interrupt controller */ |
302 | if (pp->ops->msi_set_irq) | 265 | if (pp->ops->msi_set_irq) |
303 | pp->ops->msi_set_irq(pp, pos0 + i); | 266 | pp->ops->msi_set_irq(pp, pos0 + i); |