diff options
Diffstat (limited to 'arch/powerpc/sysdev/fsl_msi.c')
-rw-r--r-- | arch/powerpc/sysdev/fsl_msi.c | 28 |
1 files changed, 19 insertions, 9 deletions
diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c index 419a77239bd7..e5c344d336ea 100644 --- a/arch/powerpc/sysdev/fsl_msi.c +++ b/arch/powerpc/sysdev/fsl_msi.c | |||
@@ -30,7 +30,7 @@ LIST_HEAD(msi_head); | |||
30 | 30 | ||
31 | struct fsl_msi_feature { | 31 | struct fsl_msi_feature { |
32 | u32 fsl_pic_ip; | 32 | u32 fsl_pic_ip; |
33 | u32 msiir_offset; | 33 | u32 msiir_offset; /* Offset of MSIIR, relative to start of MSIR bank */ |
34 | }; | 34 | }; |
35 | 35 | ||
36 | struct fsl_msi_cascade_data { | 36 | struct fsl_msi_cascade_data { |
@@ -126,10 +126,19 @@ static void fsl_compose_msi_msg(struct pci_dev *pdev, int hwirq, | |||
126 | { | 126 | { |
127 | struct fsl_msi *msi_data = fsl_msi_data; | 127 | struct fsl_msi *msi_data = fsl_msi_data; |
128 | struct pci_controller *hose = pci_bus_to_host(pdev->bus); | 128 | struct pci_controller *hose = pci_bus_to_host(pdev->bus); |
129 | u64 base = fsl_pci_immrbar_base(hose); | 129 | u64 address; /* Physical address of the MSIIR */ |
130 | int len; | ||
131 | const u64 *reg; | ||
132 | |||
133 | /* If the msi-address-64 property exists, then use it */ | ||
134 | reg = of_get_property(hose->dn, "msi-address-64", &len); | ||
135 | if (reg && (len == sizeof(u64))) | ||
136 | address = be64_to_cpup(reg); | ||
137 | else | ||
138 | address = fsl_pci_immrbar_base(hose) + msi_data->msiir_offset; | ||
130 | 139 | ||
131 | msg->address_lo = msi_data->msi_addr_lo + lower_32_bits(base); | 140 | msg->address_lo = lower_32_bits(address); |
132 | msg->address_hi = msi_data->msi_addr_hi + upper_32_bits(base); | 141 | msg->address_hi = upper_32_bits(address); |
133 | 142 | ||
134 | msg->data = hwirq; | 143 | msg->data = hwirq; |
135 | 144 | ||
@@ -296,7 +305,7 @@ static int __devinit fsl_msi_setup_hwirq(struct fsl_msi *msi, | |||
296 | } | 305 | } |
297 | 306 | ||
298 | msi->msi_virqs[irq_index] = virt_msir; | 307 | msi->msi_virqs[irq_index] = virt_msir; |
299 | cascade_data->index = offset + irq_index; | 308 | cascade_data->index = offset; |
300 | cascade_data->msi_data = msi; | 309 | cascade_data->msi_data = msi; |
301 | irq_set_handler_data(virt_msir, cascade_data); | 310 | irq_set_handler_data(virt_msir, cascade_data); |
302 | irq_set_chained_handler(virt_msir, fsl_msi_cascade); | 311 | irq_set_chained_handler(virt_msir, fsl_msi_cascade); |
@@ -359,8 +368,7 @@ static int __devinit fsl_of_msi_probe(struct platform_device *dev) | |||
359 | 368 | ||
360 | msi->irqhost->host_data = msi; | 369 | msi->irqhost->host_data = msi; |
361 | 370 | ||
362 | msi->msi_addr_hi = 0x0; | 371 | msi->msiir_offset = features->msiir_offset + (res.start & 0xfffff); |
363 | msi->msi_addr_lo = features->msiir_offset + (res.start & 0xfffff); | ||
364 | 372 | ||
365 | rc = fsl_msi_init_allocator(msi); | 373 | rc = fsl_msi_init_allocator(msi); |
366 | if (rc) { | 374 | if (rc) { |
@@ -376,8 +384,10 @@ static int __devinit fsl_of_msi_probe(struct platform_device *dev) | |||
376 | goto error_out; | 384 | goto error_out; |
377 | } | 385 | } |
378 | 386 | ||
379 | if (!p) | 387 | if (!p) { |
380 | p = all_avail; | 388 | p = all_avail; |
389 | len = sizeof(all_avail); | ||
390 | } | ||
381 | 391 | ||
382 | for (irq_index = 0, i = 0; i < len / (2 * sizeof(u32)); i++) { | 392 | for (irq_index = 0, i = 0; i < len / (2 * sizeof(u32)); i++) { |
383 | if (p[i * 2] % IRQS_PER_MSI_REG || | 393 | if (p[i * 2] % IRQS_PER_MSI_REG || |
@@ -393,7 +403,7 @@ static int __devinit fsl_of_msi_probe(struct platform_device *dev) | |||
393 | count = p[i * 2 + 1] / IRQS_PER_MSI_REG; | 403 | count = p[i * 2 + 1] / IRQS_PER_MSI_REG; |
394 | 404 | ||
395 | for (j = 0; j < count; j++, irq_index++) { | 405 | for (j = 0; j < count; j++, irq_index++) { |
396 | err = fsl_msi_setup_hwirq(msi, dev, offset, irq_index); | 406 | err = fsl_msi_setup_hwirq(msi, dev, offset + j, irq_index); |
397 | if (err) | 407 | if (err) |
398 | goto error_out; | 408 | goto error_out; |
399 | } | 409 | } |