aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLucas Stach <l.stach@pengutronix.de>2014-09-30 12:36:27 -0400
committerBjorn Helgaas <bhelgaas@google.com>2014-10-01 14:40:21 -0400
commitc8df6ac9452e8f47a6f660993c526d13e858a6f3 (patch)
tree283404af3b0be1e0337bbbf8266c4c249b7aa1d4
parent91f8ae823f2be0ea3863360dc9327ab573a8f183 (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.c51
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
199static 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
223static void dw_pcie_msi_clear_irq(struct pcie_port *pp, int irq) 199static 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
250static void dw_pcie_msi_set_irq(struct pcie_port *pp, int irq) 227static 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
261static int assign_irq(int no_irqs, struct msi_desc *desc, int *pos) 238static 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);