diff options
Diffstat (limited to 'arch/powerpc/sysdev/mpic.c')
-rw-r--r-- | arch/powerpc/sysdev/mpic.c | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index e88bbd5ec4c8..33ecf89702d4 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c | |||
@@ -389,6 +389,50 @@ static void mpic_shutdown_ht_interrupt(struct mpic *mpic, unsigned int source, | |||
389 | #endif | 389 | #endif |
390 | } | 390 | } |
391 | 391 | ||
392 | #ifdef CONFIG_PCI_MSI | ||
393 | static void __init mpic_scan_ht_msi(struct mpic *mpic, u8 __iomem *devbase, | ||
394 | unsigned int devfn) | ||
395 | { | ||
396 | u8 __iomem *base; | ||
397 | u8 pos, flags; | ||
398 | u64 addr = 0; | ||
399 | |||
400 | for (pos = readb(devbase + PCI_CAPABILITY_LIST); pos != 0; | ||
401 | pos = readb(devbase + pos + PCI_CAP_LIST_NEXT)) { | ||
402 | u8 id = readb(devbase + pos + PCI_CAP_LIST_ID); | ||
403 | if (id == PCI_CAP_ID_HT) { | ||
404 | id = readb(devbase + pos + 3); | ||
405 | if ((id & HT_5BIT_CAP_MASK) == HT_CAPTYPE_MSI_MAPPING) | ||
406 | break; | ||
407 | } | ||
408 | } | ||
409 | |||
410 | if (pos == 0) | ||
411 | return; | ||
412 | |||
413 | base = devbase + pos; | ||
414 | |||
415 | flags = readb(base + HT_MSI_FLAGS); | ||
416 | if (!(flags & HT_MSI_FLAGS_FIXED)) { | ||
417 | addr = readl(base + HT_MSI_ADDR_LO) & HT_MSI_ADDR_LO_MASK; | ||
418 | addr = addr | ((u64)readl(base + HT_MSI_ADDR_HI) << 32); | ||
419 | } | ||
420 | |||
421 | printk(KERN_DEBUG "mpic: - HT:%02x.%x %s MSI mapping found @ 0x%lx\n", | ||
422 | PCI_SLOT(devfn), PCI_FUNC(devfn), | ||
423 | flags & HT_MSI_FLAGS_ENABLE ? "enabled" : "disabled", addr); | ||
424 | |||
425 | if (!(flags & HT_MSI_FLAGS_ENABLE)) | ||
426 | writeb(flags | HT_MSI_FLAGS_ENABLE, base + HT_MSI_FLAGS); | ||
427 | } | ||
428 | #else | ||
429 | static void __init mpic_scan_ht_msi(struct mpic *mpic, u8 __iomem *devbase, | ||
430 | unsigned int devfn) | ||
431 | { | ||
432 | return; | ||
433 | } | ||
434 | #endif | ||
435 | |||
392 | static void __init mpic_scan_ht_pic(struct mpic *mpic, u8 __iomem *devbase, | 436 | static void __init mpic_scan_ht_pic(struct mpic *mpic, u8 __iomem *devbase, |
393 | unsigned int devfn, u32 vdid) | 437 | unsigned int devfn, u32 vdid) |
394 | { | 438 | { |
@@ -480,6 +524,7 @@ static void __init mpic_scan_ht_pics(struct mpic *mpic) | |||
480 | goto next; | 524 | goto next; |
481 | 525 | ||
482 | mpic_scan_ht_pic(mpic, devbase, devfn, l); | 526 | mpic_scan_ht_pic(mpic, devbase, devfn, l); |
527 | mpic_scan_ht_msi(mpic, devbase, devfn); | ||
483 | 528 | ||
484 | next: | 529 | next: |
485 | /* next device, if function 0 */ | 530 | /* next device, if function 0 */ |