diff options
| author | Gavin Shan <shangw@linux.vnet.ibm.com> | 2012-09-11 18:59:45 -0400 |
|---|---|---|
| committer | Bjorn Helgaas <bhelgaas@google.com> | 2012-09-11 18:59:45 -0400 |
| commit | ac5ad93e92c3ffca4c7ba386aaa34244e27b7759 (patch) | |
| tree | 53709126d79c3718c85fbca2ec5542aec88d4bd1 | |
| parent | 479e0d485eaab452cf248cd1a9520015023b35b2 (diff) | |
PCI: Add weak pcibios_window_alignment() interface
This patch implements a weak function to return the default I/O or memory
window alignment for a P2P bridge. By default, I/O windows are aligned to
4KiB or 1KiB and memory windows are aligned to 4MiB. Some platforms, e.g.,
powernv, have special alignment requirements and can override
pcibios_window_alignment().
[bhelgaas: changelog]
Signed-off-by: Gavin Shan <shangw@linux.vnet.ibm.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
| -rw-r--r-- | drivers/pci/setup-bus.c | 32 | ||||
| -rw-r--r-- | include/linux/pci.h | 2 |
2 files changed, 34 insertions, 0 deletions
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index fb506137aaee..896f06e3e793 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c | |||
| @@ -697,6 +697,38 @@ static resource_size_t calculate_memsize(resource_size_t size, | |||
| 697 | return size; | 697 | return size; |
| 698 | } | 698 | } |
| 699 | 699 | ||
| 700 | resource_size_t __weak pcibios_window_alignment(struct pci_bus *bus, | ||
| 701 | unsigned long type) | ||
| 702 | { | ||
| 703 | return 1; | ||
| 704 | } | ||
| 705 | |||
| 706 | #define PCI_P2P_DEFAULT_MEM_ALIGN 0x100000 /* 1MiB */ | ||
| 707 | #define PCI_P2P_DEFAULT_IO_ALIGN 0x1000 /* 4KiB */ | ||
| 708 | #define PCI_P2P_DEFAULT_IO_ALIGN_1K 0x400 /* 1KiB */ | ||
| 709 | |||
| 710 | static resource_size_t window_alignment(struct pci_bus *bus, | ||
| 711 | unsigned long type) | ||
| 712 | { | ||
| 713 | resource_size_t align = 1, arch_align; | ||
| 714 | |||
| 715 | if (type & IORESOURCE_MEM) | ||
| 716 | align = PCI_P2P_DEFAULT_MEM_ALIGN; | ||
| 717 | else if (type & IORESOURCE_IO) { | ||
| 718 | /* | ||
| 719 | * Per spec, I/O windows are 4K-aligned, but some | ||
| 720 | * bridges have an extension to support 1K alignment. | ||
| 721 | */ | ||
| 722 | if (bus->self->io_window_1k) | ||
| 723 | align = PCI_P2P_DEFAULT_IO_ALIGN_1K; | ||
| 724 | else | ||
| 725 | align = PCI_P2P_DEFAULT_IO_ALIGN; | ||
| 726 | } | ||
| 727 | |||
| 728 | arch_align = pcibios_window_alignment(bus, type); | ||
| 729 | return max(align, arch_align); | ||
| 730 | } | ||
| 731 | |||
| 700 | /** | 732 | /** |
| 701 | * pbus_size_io() - size the io window of a given bus | 733 | * pbus_size_io() - size the io window of a given bus |
| 702 | * | 734 | * |
diff --git a/include/linux/pci.h b/include/linux/pci.h index b8667e0548e0..2c755243eef2 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
| @@ -1064,6 +1064,8 @@ int pci_cfg_space_size_ext(struct pci_dev *dev); | |||
| 1064 | int pci_cfg_space_size(struct pci_dev *dev); | 1064 | int pci_cfg_space_size(struct pci_dev *dev); |
| 1065 | unsigned char pci_bus_max_busnr(struct pci_bus *bus); | 1065 | unsigned char pci_bus_max_busnr(struct pci_bus *bus); |
| 1066 | void pci_setup_bridge(struct pci_bus *bus); | 1066 | void pci_setup_bridge(struct pci_bus *bus); |
| 1067 | resource_size_t pcibios_window_alignment(struct pci_bus *bus, | ||
| 1068 | unsigned long type); | ||
| 1067 | 1069 | ||
| 1068 | #define PCI_VGA_STATE_CHANGE_BRIDGE (1 << 0) | 1070 | #define PCI_VGA_STATE_CHANGE_BRIDGE (1 << 0) |
| 1069 | #define PCI_VGA_STATE_CHANGE_DECODES (1 << 1) | 1071 | #define PCI_VGA_STATE_CHANGE_DECODES (1 << 1) |
