forked from Minki/linux
PCI changes for the v3.20 merge window:
Enumeration - Move domain assignment from arm64 to generic code (Lorenzo Pieralisi) - ARM: Remove artificial dependency on pci_sys_data domain (Lorenzo Pieralisi) - ARM: Move to generic PCI domains (Lorenzo Pieralisi) - Generate uppercase hex for modalias var in uevent (Ricardo Ribalda Delgado) - Add and use generic config accessors on ARM, PowerPC (Rob Herring) Resource management - Free resources on failure in of_pci_get_host_bridge_resources() (Lorenzo Pieralisi) - Fix infinite loop with ROM image of size 0 (Michel Dänzer) PCI device hotplug - Handle surprise add even if surprise removal isn't supported (Bjorn Helgaas) Virtualization - Mark AMD/ATI VGA devices that don't reset on D3hot->D0 transition (Alex Williamson) - Add DMA alias quirk for Adaptec 3405 (Alex Williamson) - Add Wellsburg (X99) to Intel PCH root port ACS quirk (Alex Williamson) - Add ACS quirk for Emulex NICs (Vasundhara Volam) MSI - Fail MSI-X mappings if there's no space assigned to MSI-X BAR (Yijing Wang) Freescale Layerscape host bridge driver - Fix platform_no_drv_owner.cocci warnings (Julia Lawall) NVIDIA Tegra host bridge driver - Remove unnecessary tegra_pcie_fixup_bridge() (Lucas Stach) Renesas R-Car host bridge driver - Fix error handling of irq_of_parse_and_map() (Dmitry Torokhov) TI Keystone host bridge driver - Fix error handling of irq_of_parse_and_map() (Dmitry Torokhov) - Fix misspelling of current function in debug output (Julia Lawall) Xilinx AXI host bridge driver - Fix harmless format string warning (Arnd Bergmann) Miscellaneous - Use standard parsing functions for ASPM sysfs setters (Chris J Arges) - Add pci_device_to_OF_node() stub for !CONFIG_OF (Kevin Hao) - Delete unnecessary NULL pointer checks (Markus Elfring) - Add and use defines for PCIe Max_Read_Request_Size (Rafał Miłecki) - Include clk.h instead of clk-private.h (Stephen Boyd) -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJU1idjAAoJEFmIoMA60/r8C+gP/3p1Ya/cW+liX7e0Pz6wsrkB pAk9Af9Iz7RHYb0ODAs1XnlvuJJtJ6nXb9iXTFefhWKfVK0dF1i0w2VqsLUa+iLS V65XzkdtrEa+uJj5plvzehrHQhOPh5U2WtZvsAgeC6yu9F/LhnJywOIZjaYdCYwE /lXBgLPJiqXfDyEpKT6TqObwPpY7Ly+7+yNZ4LcO84AuBwb6lBq88Eyl7Ft+K57m dIJVh8ZTQMzVy5EcGbLoIYF4Mg8zdQbxju73bfeBNerxwd7QD7l0mfiQ3yIexRrQ FvzgIerDYdabKgYcbC3cQzMR4V0TEcWs0E7VqiokU4onor4VnK4A0PtbMEWcK8YN OZnQ8d4imHhJN4HdJeMhiKIIk+Cr52A1fC/AKmL0Ddw8yKusgjPz2Ux0pHpXMR1a NodymVV4XWcDBKWPX0DLESe8wJC4fN+v8bwMVWg20BC709BaK61yA7lGqJ70HmJ+ u5mWokjgiycTQmJBiJmkEM9b5YVHLjrQ0PwDiYEtkxhMmd/ti+o12fhyNU8Epkr7 fgDEI/OTURbhbrX0qiQ8RZiSSt5WXuy+ZWbw76rfo3SUH3Lt1WrcdbZrUd9em2hy dqOA1vV97JUtQMD/Dsg9apTObR9XJk2B/lyZs1YyCcb77KGSEsSw2x+xz3RRVHM4 uQDwVupB/QsRVAu4tubr =N6mH -----END PGP SIGNATURE----- Merge tag 'pci-v3.20-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci Pull PCI changes from Bjorn Helgaas: "Enumeration - Move domain assignment from arm64 to generic code (Lorenzo Pieralisi) - ARM: Remove artificial dependency on pci_sys_data domain (Lorenzo Pieralisi) - ARM: Move to generic PCI domains (Lorenzo Pieralisi) - Generate uppercase hex for modalias var in uevent (Ricardo Ribalda Delgado) - Add and use generic config accessors on ARM, PowerPC (Rob Herring) Resource management - Free resources on failure in of_pci_get_host_bridge_resources() (Lorenzo Pieralisi) - Fix infinite loop with ROM image of size 0 (Michel Dänzer) PCI device hotplug - Handle surprise add even if surprise removal isn't supported (Bjorn Helgaas) Virtualization - Mark AMD/ATI VGA devices that don't reset on D3hot->D0 transition (Alex Williamson) - Add DMA alias quirk for Adaptec 3405 (Alex Williamson) - Add Wellsburg (X99) to Intel PCH root port ACS quirk (Alex Williamson) - Add ACS quirk for Emulex NICs (Vasundhara Volam) MSI - Fail MSI-X mappings if there's no space assigned to MSI-X BAR (Yijing Wang) Freescale Layerscape host bridge driver - Fix platform_no_drv_owner.cocci warnings (Julia Lawall) NVIDIA Tegra host bridge driver - Remove unnecessary tegra_pcie_fixup_bridge() (Lucas Stach) Renesas R-Car host bridge driver - Fix error handling of irq_of_parse_and_map() (Dmitry Torokhov) TI Keystone host bridge driver - Fix error handling of irq_of_parse_and_map() (Dmitry Torokhov) - Fix misspelling of current function in debug output (Julia Lawall) Xilinx AXI host bridge driver - Fix harmless format string warning (Arnd Bergmann) Miscellaneous - Use standard parsing functions for ASPM sysfs setters (Chris J Arges) - Add pci_device_to_OF_node() stub for !CONFIG_OF (Kevin Hao) - Delete unnecessary NULL pointer checks (Markus Elfring) - Add and use defines for PCIe Max_Read_Request_Size (Rafał Miłecki) - Include clk.h instead of clk-private.h (Stephen Boyd)" * tag 'pci-v3.20-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci: (48 commits) PCI: Add pci_device_to_OF_node() stub for !CONFIG_OF PCI: xilinx: Convert to use generic config accessors PCI: xgene: Convert to use generic config accessors PCI: tegra: Convert to use generic config accessors PCI: rcar: Convert to use generic config accessors PCI: generic: Convert to use generic config accessors powerpc/powermac: Convert PCI to use generic config accessors powerpc/fsl_pci: Convert PCI to use generic config accessors ARM: ks8695: Convert PCI to use generic config accessors ARM: sa1100: Convert PCI to use generic config accessors ARM: integrator: Convert PCI to use generic config accessors PCI: versatile: Add DT-based ARM Versatile PB PCIe host driver ARM: dts: versatile: add PCI controller binding of/pci: Free resources on failure in of_pci_get_host_bridge_resources() PCI: versatile: Add DT docs for ARM Versatile PB PCIe driver PCI: Fail MSI-X mappings if there's no space assigned to MSI-X BAR r8169: use PCI define for Max_Read_Request_Size [SCSI] esas2r: use PCI define for Max_Read_Request_Size tile: use PCI define for Max_Read_Request_Size rapidio/tsi721: use PCI define for Max_Read_Request_Size ...
This commit is contained in:
commit
c08f846793
59
Documentation/devicetree/bindings/pci/versatile.txt
Normal file
59
Documentation/devicetree/bindings/pci/versatile.txt
Normal file
@ -0,0 +1,59 @@
|
||||
* ARM Versatile Platform Baseboard PCI interface
|
||||
|
||||
PCI host controller found on the ARM Versatile PB board's FPGA.
|
||||
|
||||
Required properties:
|
||||
- compatible: should contain "arm,versatile-pci" to identify the Versatile PCI
|
||||
controller.
|
||||
- reg: base addresses and lengths of the pci controller. There must be 3
|
||||
entries:
|
||||
- Versatile-specific registers
|
||||
- Self Config space
|
||||
- Config space
|
||||
- #address-cells: set to <3>
|
||||
- #size-cells: set to <2>
|
||||
- device_type: set to "pci"
|
||||
- bus-range: set to <0 0xff>
|
||||
- ranges: ranges for the PCI memory and I/O regions
|
||||
- #interrupt-cells: set to <1>
|
||||
- interrupt-map-mask and interrupt-map: standard PCI properties to define
|
||||
the mapping of the PCI interface to interrupt numbers.
|
||||
|
||||
Example:
|
||||
|
||||
pci-controller@10001000 {
|
||||
compatible = "arm,versatile-pci";
|
||||
device_type = "pci";
|
||||
reg = <0x10001000 0x1000
|
||||
0x41000000 0x10000
|
||||
0x42000000 0x100000>;
|
||||
bus-range = <0 0xff>;
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
#interrupt-cells = <1>;
|
||||
|
||||
ranges = <0x01000000 0 0x00000000 0x43000000 0 0x00010000 /* downstream I/O */
|
||||
0x02000000 0 0x50000000 0x50000000 0 0x10000000 /* non-prefetchable memory */
|
||||
0x42000000 0 0x60000000 0x60000000 0 0x10000000>; /* prefetchable memory */
|
||||
|
||||
interrupt-map-mask = <0x1800 0 0 7>;
|
||||
interrupt-map = <0x1800 0 0 1 &sic 28
|
||||
0x1800 0 0 2 &sic 29
|
||||
0x1800 0 0 3 &sic 30
|
||||
0x1800 0 0 4 &sic 27
|
||||
|
||||
0x1000 0 0 1 &sic 27
|
||||
0x1000 0 0 2 &sic 28
|
||||
0x1000 0 0 3 &sic 29
|
||||
0x1000 0 0 4 &sic 30
|
||||
|
||||
0x0800 0 0 1 &sic 30
|
||||
0x0800 0 0 2 &sic 27
|
||||
0x0800 0 0 3 &sic 28
|
||||
0x0800 0 0 4 &sic 29
|
||||
|
||||
0x0000 0 0 1 &sic 29
|
||||
0x0000 0 0 2 &sic 30
|
||||
0x0000 0 0 3 &sic 27
|
||||
0x0000 0 0 4 &sic 28>;
|
||||
};
|
@ -7277,6 +7277,14 @@ F: include/linux/pci*
|
||||
F: arch/x86/pci/
|
||||
F: arch/x86/kernel/quirks.c
|
||||
|
||||
PCI DRIVER FOR ARM VERSATILE PLATFORM
|
||||
M: Rob Herring <robh@kernel.org>
|
||||
L: linux-pci@vger.kernel.org
|
||||
L: linux-arm-kernel@lists.infradead.org
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/pci/versatile.txt
|
||||
F: drivers/pci/host/pci-versatile.c
|
||||
|
||||
PCI DRIVER FOR APPLIEDMICRO XGENE
|
||||
M: Tanmay Inamdar <tinamdar@apm.com>
|
||||
L: linux-pci@vger.kernel.org
|
||||
|
@ -1279,6 +1279,9 @@ config PCI_DOMAINS
|
||||
bool
|
||||
depends on PCI
|
||||
|
||||
config PCI_DOMAINS_GENERIC
|
||||
def_bool PCI_DOMAINS
|
||||
|
||||
config PCI_NANOENGINE
|
||||
bool "BSE nanoEngine PCI support"
|
||||
depends on SA1100_NANOENGINE
|
||||
|
@ -29,6 +29,43 @@
|
||||
clock-names = "apb_pclk";
|
||||
};
|
||||
|
||||
pci-controller@10001000 {
|
||||
compatible = "arm,versatile-pci";
|
||||
device_type = "pci";
|
||||
reg = <0x10001000 0x1000
|
||||
0x41000000 0x10000
|
||||
0x42000000 0x100000>;
|
||||
bus-range = <0 0xff>;
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
#interrupt-cells = <1>;
|
||||
|
||||
ranges = <0x01000000 0 0x00000000 0x43000000 0 0x00010000 /* downstream I/O */
|
||||
0x02000000 0 0x50000000 0x50000000 0 0x10000000 /* non-prefetchable memory */
|
||||
0x42000000 0 0x60000000 0x60000000 0 0x10000000>; /* prefetchable memory */
|
||||
|
||||
interrupt-map-mask = <0x1800 0 0 7>;
|
||||
interrupt-map = <0x1800 0 0 1 &sic 28
|
||||
0x1800 0 0 2 &sic 29
|
||||
0x1800 0 0 3 &sic 30
|
||||
0x1800 0 0 4 &sic 27
|
||||
|
||||
0x1000 0 0 1 &sic 27
|
||||
0x1000 0 0 2 &sic 28
|
||||
0x1000 0 0 3 &sic 29
|
||||
0x1000 0 0 4 &sic 30
|
||||
|
||||
0x0800 0 0 1 &sic 30
|
||||
0x0800 0 0 2 &sic 27
|
||||
0x0800 0 0 3 &sic 28
|
||||
0x0800 0 0 4 &sic 29
|
||||
|
||||
0x0000 0 0 1 &sic 29
|
||||
0x0000 0 0 2 &sic 30
|
||||
0x0000 0 0 3 &sic 27
|
||||
0x0000 0 0 4 &sic 28>;
|
||||
};
|
||||
|
||||
fpga {
|
||||
uart@9000 {
|
||||
compatible = "arm,pl011", "arm,primecell";
|
||||
|
@ -19,9 +19,6 @@ struct pci_bus;
|
||||
struct device;
|
||||
|
||||
struct hw_pci {
|
||||
#ifdef CONFIG_PCI_DOMAINS
|
||||
int domain;
|
||||
#endif
|
||||
#ifdef CONFIG_PCI_MSI
|
||||
struct msi_controller *msi_ctrl;
|
||||
#endif
|
||||
@ -45,9 +42,6 @@ struct hw_pci {
|
||||
* Per-controller structure
|
||||
*/
|
||||
struct pci_sys_data {
|
||||
#ifdef CONFIG_PCI_DOMAINS
|
||||
int domain;
|
||||
#endif
|
||||
#ifdef CONFIG_PCI_MSI
|
||||
struct msi_controller *msi_ctrl;
|
||||
#endif
|
||||
|
@ -18,13 +18,6 @@ static inline int pcibios_assign_all_busses(void)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PCI_DOMAINS
|
||||
static inline int pci_domain_nr(struct pci_bus *bus)
|
||||
{
|
||||
struct pci_sys_data *root = bus->sysdata;
|
||||
|
||||
return root->domain;
|
||||
}
|
||||
|
||||
static inline int pci_proc_domain(struct pci_bus *bus)
|
||||
{
|
||||
return pci_domain_nr(bus);
|
||||
|
@ -463,9 +463,6 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw,
|
||||
if (!sys)
|
||||
panic("PCI: unable to allocate sys data!");
|
||||
|
||||
#ifdef CONFIG_PCI_DOMAINS
|
||||
sys->domain = hw->domain;
|
||||
#endif
|
||||
#ifdef CONFIG_PCI_MSI
|
||||
sys->msi_ctrl = hw->msi_ctrl;
|
||||
#endif
|
||||
|
@ -30,18 +30,15 @@ struct cns3xxx_pcie {
|
||||
unsigned int irqs[2];
|
||||
struct resource res_io;
|
||||
struct resource res_mem;
|
||||
struct hw_pci hw_pci;
|
||||
|
||||
int port;
|
||||
bool linked;
|
||||
};
|
||||
|
||||
static struct cns3xxx_pcie cns3xxx_pcie[]; /* forward decl. */
|
||||
|
||||
static struct cns3xxx_pcie *sysdata_to_cnspci(void *sysdata)
|
||||
{
|
||||
struct pci_sys_data *root = sysdata;
|
||||
|
||||
return &cns3xxx_pcie[root->domain];
|
||||
return root->private_data;
|
||||
}
|
||||
|
||||
static struct cns3xxx_pcie *pdev_to_cnspci(const struct pci_dev *dev)
|
||||
@ -54,8 +51,8 @@ static struct cns3xxx_pcie *pbus_to_cnspci(struct pci_bus *bus)
|
||||
return sysdata_to_cnspci(bus->sysdata);
|
||||
}
|
||||
|
||||
static void __iomem *cns3xxx_pci_cfg_base(struct pci_bus *bus,
|
||||
unsigned int devfn, int where)
|
||||
static void __iomem *cns3xxx_pci_map_bus(struct pci_bus *bus,
|
||||
unsigned int devfn, int where)
|
||||
{
|
||||
struct cns3xxx_pcie *cnspci = pbus_to_cnspci(bus);
|
||||
int busno = bus->number;
|
||||
@ -91,55 +88,22 @@ static void __iomem *cns3xxx_pci_cfg_base(struct pci_bus *bus,
|
||||
static int cns3xxx_pci_read_config(struct pci_bus *bus, unsigned int devfn,
|
||||
int where, int size, u32 *val)
|
||||
{
|
||||
u32 v;
|
||||
void __iomem *base;
|
||||
int ret;
|
||||
u32 mask = (0x1ull << (size * 8)) - 1;
|
||||
int shift = (where % 4) * 8;
|
||||
|
||||
base = cns3xxx_pci_cfg_base(bus, devfn, where);
|
||||
if (!base) {
|
||||
*val = 0xffffffff;
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
ret = pci_generic_config_read32(bus, devfn, where, size, val);
|
||||
|
||||
v = __raw_readl(base);
|
||||
|
||||
if (bus->number == 0 && devfn == 0 &&
|
||||
(where & 0xffc) == PCI_CLASS_REVISION) {
|
||||
if (ret == PCIBIOS_SUCCESSFUL && !bus->number && !devfn &&
|
||||
(where & 0xffc) == PCI_CLASS_REVISION)
|
||||
/*
|
||||
* RC's class is 0xb, but Linux PCI driver needs 0x604
|
||||
* for a PCIe bridge. So we must fixup the class code
|
||||
* to 0x604 here.
|
||||
*/
|
||||
v &= 0xff;
|
||||
v |= 0x604 << 16;
|
||||
}
|
||||
*val = ((((*val << shift) & 0xff) | (0x604 << 16)) >> shift) & mask;
|
||||
|
||||
*val = (v >> shift) & mask;
|
||||
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
static int cns3xxx_pci_write_config(struct pci_bus *bus, unsigned int devfn,
|
||||
int where, int size, u32 val)
|
||||
{
|
||||
u32 v;
|
||||
void __iomem *base;
|
||||
u32 mask = (0x1ull << (size * 8)) - 1;
|
||||
int shift = (where % 4) * 8;
|
||||
|
||||
base = cns3xxx_pci_cfg_base(bus, devfn, where);
|
||||
if (!base)
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
|
||||
v = __raw_readl(base);
|
||||
|
||||
v &= ~(mask << shift);
|
||||
v |= (val & mask) << shift;
|
||||
|
||||
__raw_writel(v, base);
|
||||
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int cns3xxx_pci_setup(int nr, struct pci_sys_data *sys)
|
||||
@ -158,8 +122,9 @@ static int cns3xxx_pci_setup(int nr, struct pci_sys_data *sys)
|
||||
}
|
||||
|
||||
static struct pci_ops cns3xxx_pcie_ops = {
|
||||
.map_bus = cns3xxx_pci_map_bus,
|
||||
.read = cns3xxx_pci_read_config,
|
||||
.write = cns3xxx_pci_write_config,
|
||||
.write = pci_generic_config_write,
|
||||
};
|
||||
|
||||
static int cns3xxx_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
|
||||
@ -192,13 +157,7 @@ static struct cns3xxx_pcie cns3xxx_pcie[] = {
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
.irqs = { IRQ_CNS3XXX_PCIE0_RC, IRQ_CNS3XXX_PCIE0_DEVICE, },
|
||||
.hw_pci = {
|
||||
.domain = 0,
|
||||
.nr_controllers = 1,
|
||||
.ops = &cns3xxx_pcie_ops,
|
||||
.setup = cns3xxx_pci_setup,
|
||||
.map_irq = cns3xxx_pcie_map_irq,
|
||||
},
|
||||
.port = 0,
|
||||
},
|
||||
[1] = {
|
||||
.host_regs = (void __iomem *)CNS3XXX_PCIE1_HOST_BASE_VIRT,
|
||||
@ -217,19 +176,13 @@ static struct cns3xxx_pcie cns3xxx_pcie[] = {
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
.irqs = { IRQ_CNS3XXX_PCIE1_RC, IRQ_CNS3XXX_PCIE1_DEVICE, },
|
||||
.hw_pci = {
|
||||
.domain = 1,
|
||||
.nr_controllers = 1,
|
||||
.ops = &cns3xxx_pcie_ops,
|
||||
.setup = cns3xxx_pci_setup,
|
||||
.map_irq = cns3xxx_pcie_map_irq,
|
||||
},
|
||||
.port = 1,
|
||||
},
|
||||
};
|
||||
|
||||
static void __init cns3xxx_pcie_check_link(struct cns3xxx_pcie *cnspci)
|
||||
{
|
||||
int port = cnspci->hw_pci.domain;
|
||||
int port = cnspci->port;
|
||||
u32 reg;
|
||||
unsigned long time;
|
||||
|
||||
@ -260,9 +213,9 @@ static void __init cns3xxx_pcie_check_link(struct cns3xxx_pcie *cnspci)
|
||||
|
||||
static void __init cns3xxx_pcie_hw_init(struct cns3xxx_pcie *cnspci)
|
||||
{
|
||||
int port = cnspci->hw_pci.domain;
|
||||
int port = cnspci->port;
|
||||
struct pci_sys_data sd = {
|
||||
.domain = port,
|
||||
.private_data = cnspci,
|
||||
};
|
||||
struct pci_bus bus = {
|
||||
.number = 0,
|
||||
@ -323,6 +276,14 @@ static int cns3xxx_pcie_abort_handler(unsigned long addr, unsigned int fsr,
|
||||
void __init cns3xxx_pcie_init_late(void)
|
||||
{
|
||||
int i;
|
||||
void *private_data;
|
||||
struct hw_pci hw_pci = {
|
||||
.nr_controllers = 1,
|
||||
.ops = &cns3xxx_pcie_ops,
|
||||
.setup = cns3xxx_pci_setup,
|
||||
.map_irq = cns3xxx_pcie_map_irq,
|
||||
.private_data = &private_data,
|
||||
};
|
||||
|
||||
pcibios_min_io = 0;
|
||||
pcibios_min_mem = 0;
|
||||
@ -335,7 +296,8 @@ void __init cns3xxx_pcie_init_late(void)
|
||||
cns3xxx_pwr_soft_rst(0x1 << PM_SOFT_RST_REG_OFFST_PCIE(i));
|
||||
cns3xxx_pcie_check_link(&cns3xxx_pcie[i]);
|
||||
cns3xxx_pcie_hw_init(&cns3xxx_pcie[i]);
|
||||
pci_common_init(&cns3xxx_pcie[i].hw_pci);
|
||||
private_data = &cns3xxx_pcie[i];
|
||||
pci_common_init(&hw_pci);
|
||||
}
|
||||
|
||||
pci_assign_unassigned_resources();
|
||||
|
@ -356,7 +356,6 @@ static u64 pre_mem_pci_sz;
|
||||
* 7:2 register number
|
||||
*
|
||||
*/
|
||||
static DEFINE_RAW_SPINLOCK(v3_lock);
|
||||
|
||||
#undef V3_LB_BASE_PREFETCH
|
||||
#define V3_LB_BASE_PREFETCH 0
|
||||
@ -457,67 +456,21 @@ static void v3_close_config_window(void)
|
||||
static int v3_read_config(struct pci_bus *bus, unsigned int devfn, int where,
|
||||
int size, u32 *val)
|
||||
{
|
||||
void __iomem *addr;
|
||||
unsigned long flags;
|
||||
u32 v;
|
||||
|
||||
raw_spin_lock_irqsave(&v3_lock, flags);
|
||||
addr = v3_open_config_window(bus, devfn, where);
|
||||
|
||||
switch (size) {
|
||||
case 1:
|
||||
v = __raw_readb(addr);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
v = __raw_readw(addr);
|
||||
break;
|
||||
|
||||
default:
|
||||
v = __raw_readl(addr);
|
||||
break;
|
||||
}
|
||||
|
||||
int ret = pci_generic_config_read(bus, devfn, where, size, val);
|
||||
v3_close_config_window();
|
||||
raw_spin_unlock_irqrestore(&v3_lock, flags);
|
||||
|
||||
*val = v;
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int v3_write_config(struct pci_bus *bus, unsigned int devfn, int where,
|
||||
int size, u32 val)
|
||||
{
|
||||
void __iomem *addr;
|
||||
unsigned long flags;
|
||||
|
||||
raw_spin_lock_irqsave(&v3_lock, flags);
|
||||
addr = v3_open_config_window(bus, devfn, where);
|
||||
|
||||
switch (size) {
|
||||
case 1:
|
||||
__raw_writeb((u8)val, addr);
|
||||
__raw_readb(addr);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
__raw_writew((u16)val, addr);
|
||||
__raw_readw(addr);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
__raw_writel(val, addr);
|
||||
__raw_readl(addr);
|
||||
break;
|
||||
}
|
||||
|
||||
int ret = pci_generic_config_write(bus, devfn, where, size, val);
|
||||
v3_close_config_window();
|
||||
raw_spin_unlock_irqrestore(&v3_lock, flags);
|
||||
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct pci_ops pci_v3_ops = {
|
||||
.map_bus = v3_open_config_window,
|
||||
.read = v3_read_config,
|
||||
.write = v3_write_config,
|
||||
};
|
||||
@ -658,7 +611,6 @@ static int __init pci_v3_setup(int nr, struct pci_sys_data *sys)
|
||||
*/
|
||||
static void __init pci_v3_preinit(void)
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned int temp;
|
||||
phys_addr_t io_address = pci_pio_to_address(io_mem.start);
|
||||
|
||||
@ -672,8 +624,6 @@ static void __init pci_v3_preinit(void)
|
||||
hook_fault_code(8, v3_pci_fault, SIGBUS, 0, "external abort on non-linefetch");
|
||||
hook_fault_code(10, v3_pci_fault, SIGBUS, 0, "external abort on non-linefetch");
|
||||
|
||||
raw_spin_lock_irqsave(&v3_lock, flags);
|
||||
|
||||
/*
|
||||
* Unlock V3 registers, but only if they were previously locked.
|
||||
*/
|
||||
@ -736,8 +686,6 @@ static void __init pci_v3_preinit(void)
|
||||
v3_writew(V3_LB_CFG, v3_readw(V3_LB_CFG) | (1 << 10));
|
||||
v3_writeb(V3_LB_IMASK, 0x28);
|
||||
__raw_writel(3, ap_syscon_base + INTEGRATOR_SC_PCIENABLE_OFFSET);
|
||||
|
||||
raw_spin_unlock_irqrestore(&v3_lock, flags);
|
||||
}
|
||||
|
||||
static void __init pci_v3_postinit(void)
|
||||
|
@ -38,8 +38,6 @@
|
||||
|
||||
|
||||
static int pci_dbg;
|
||||
static int pci_cfg_dbg;
|
||||
|
||||
|
||||
static void ks8695_pci_setupconfig(unsigned int bus_nr, unsigned int devfn, unsigned int where)
|
||||
{
|
||||
@ -59,75 +57,11 @@ static void ks8695_pci_setupconfig(unsigned int bus_nr, unsigned int devfn, unsi
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The KS8695 datasheet prohibits anything other than 32bit accesses
|
||||
* to the IO registers, so all our configuration must be done with
|
||||
* 32bit operations, and the correct bit masking and shifting.
|
||||
*/
|
||||
|
||||
static int ks8695_pci_readconfig(struct pci_bus *bus,
|
||||
unsigned int devfn, int where, int size, u32 *value)
|
||||
static void __iomem *ks8695_pci_map_bus(struct pci_bus *bus, unsigned int devfn,
|
||||
int where)
|
||||
{
|
||||
ks8695_pci_setupconfig(bus->number, devfn, where);
|
||||
|
||||
*value = __raw_readl(KS8695_PCI_VA + KS8695_PBCD);
|
||||
|
||||
switch (size) {
|
||||
case 4:
|
||||
break;
|
||||
case 2:
|
||||
*value = *value >> ((where & 2) * 8);
|
||||
*value &= 0xffff;
|
||||
break;
|
||||
case 1:
|
||||
*value = *value >> ((where & 3) * 8);
|
||||
*value &= 0xff;
|
||||
break;
|
||||
}
|
||||
|
||||
if (pci_cfg_dbg) {
|
||||
printk("read: %d,%08x,%02x,%d: %08x (%08x)\n",
|
||||
bus->number, devfn, where, size, *value,
|
||||
__raw_readl(KS8695_PCI_VA + KS8695_PBCD));
|
||||
}
|
||||
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
static int ks8695_pci_writeconfig(struct pci_bus *bus,
|
||||
unsigned int devfn, int where, int size, u32 value)
|
||||
{
|
||||
unsigned long tmp;
|
||||
|
||||
if (pci_cfg_dbg) {
|
||||
printk("write: %d,%08x,%02x,%d: %08x\n",
|
||||
bus->number, devfn, where, size, value);
|
||||
}
|
||||
|
||||
ks8695_pci_setupconfig(bus->number, devfn, where);
|
||||
|
||||
switch (size) {
|
||||
case 4:
|
||||
__raw_writel(value, KS8695_PCI_VA + KS8695_PBCD);
|
||||
break;
|
||||
case 2:
|
||||
tmp = __raw_readl(KS8695_PCI_VA + KS8695_PBCD);
|
||||
tmp &= ~(0xffff << ((where & 2) * 8));
|
||||
tmp |= value << ((where & 2) * 8);
|
||||
|
||||
__raw_writel(tmp, KS8695_PCI_VA + KS8695_PBCD);
|
||||
break;
|
||||
case 1:
|
||||
tmp = __raw_readl(KS8695_PCI_VA + KS8695_PBCD);
|
||||
tmp &= ~(0xff << ((where & 3) * 8));
|
||||
tmp |= value << ((where & 3) * 8);
|
||||
|
||||
__raw_writel(tmp, KS8695_PCI_VA + KS8695_PBCD);
|
||||
break;
|
||||
}
|
||||
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
return KS8695_PCI_VA + KS8695_PBCD;
|
||||
}
|
||||
|
||||
static void ks8695_local_writeconfig(int where, u32 value)
|
||||
@ -137,8 +71,9 @@ static void ks8695_local_writeconfig(int where, u32 value)
|
||||
}
|
||||
|
||||
static struct pci_ops ks8695_pci_ops = {
|
||||
.read = ks8695_pci_readconfig,
|
||||
.write = ks8695_pci_writeconfig,
|
||||
.map_bus = ks8695_pci_map_bus,
|
||||
.read = pci_generic_config_read32,
|
||||
.write = pci_generic_config_write32,
|
||||
};
|
||||
|
||||
static struct resource pci_mem = {
|
||||
|
@ -22,7 +22,6 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/spinlock.h>
|
||||
|
||||
#include <asm/mach/pci.h>
|
||||
#include <asm/mach-types.h>
|
||||
@ -30,97 +29,20 @@
|
||||
#include <mach/nanoengine.h>
|
||||
#include <mach/hardware.h>
|
||||
|
||||
static DEFINE_SPINLOCK(nano_lock);
|
||||
|
||||
static int nanoengine_get_pci_address(struct pci_bus *bus,
|
||||
unsigned int devfn, int where, void __iomem **address)
|
||||
static void __iomem *nanoengine_pci_map_bus(struct pci_bus *bus,
|
||||
unsigned int devfn, int where)
|
||||
{
|
||||
int ret = PCIBIOS_DEVICE_NOT_FOUND;
|
||||
unsigned int busnr = bus->number;
|
||||
if (bus->number != 0 || (devfn >> 3) != 0)
|
||||
return NULL;
|
||||
|
||||
*address = (void __iomem *)NANO_PCI_CONFIG_SPACE_VIRT +
|
||||
return (void __iomem *)NANO_PCI_CONFIG_SPACE_VIRT +
|
||||
((bus->number << 16) | (devfn << 8) | (where & ~3));
|
||||
|
||||
ret = (busnr > 255 || devfn > 255 || where > 255) ?
|
||||
PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int nanoengine_read_config(struct pci_bus *bus, unsigned int devfn, int where,
|
||||
int size, u32 *val)
|
||||
{
|
||||
int ret;
|
||||
void __iomem *address;
|
||||
unsigned long flags;
|
||||
u32 v;
|
||||
|
||||
/* nanoEngine PCI bridge does not return -1 for a non-existing
|
||||
* device. We must fake the answer. We know that the only valid
|
||||
* device is device zero at bus 0, which is the network chip. */
|
||||
if (bus->number != 0 || (devfn >> 3) != 0) {
|
||||
v = -1;
|
||||
nanoengine_get_pci_address(bus, devfn, where, &address);
|
||||
goto exit_function;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&nano_lock, flags);
|
||||
|
||||
ret = nanoengine_get_pci_address(bus, devfn, where, &address);
|
||||
if (ret != PCIBIOS_SUCCESSFUL)
|
||||
return ret;
|
||||
v = __raw_readl(address);
|
||||
|
||||
spin_unlock_irqrestore(&nano_lock, flags);
|
||||
|
||||
v >>= ((where & 3) * 8);
|
||||
v &= (unsigned long)(-1) >> ((4 - size) * 8);
|
||||
|
||||
exit_function:
|
||||
*val = v;
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
static int nanoengine_write_config(struct pci_bus *bus, unsigned int devfn, int where,
|
||||
int size, u32 val)
|
||||
{
|
||||
int ret;
|
||||
void __iomem *address;
|
||||
unsigned long flags;
|
||||
unsigned shift;
|
||||
u32 v;
|
||||
|
||||
shift = (where & 3) * 8;
|
||||
|
||||
spin_lock_irqsave(&nano_lock, flags);
|
||||
|
||||
ret = nanoengine_get_pci_address(bus, devfn, where, &address);
|
||||
if (ret != PCIBIOS_SUCCESSFUL)
|
||||
return ret;
|
||||
v = __raw_readl(address);
|
||||
switch (size) {
|
||||
case 1:
|
||||
v &= ~(0xFF << shift);
|
||||
v |= val << shift;
|
||||
break;
|
||||
case 2:
|
||||
v &= ~(0xFFFF << shift);
|
||||
v |= val << shift;
|
||||
break;
|
||||
case 4:
|
||||
v = val;
|
||||
break;
|
||||
}
|
||||
__raw_writel(v, address);
|
||||
|
||||
spin_unlock_irqrestore(&nano_lock, flags);
|
||||
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
static struct pci_ops pci_nano_ops = {
|
||||
.read = nanoengine_read_config,
|
||||
.write = nanoengine_write_config,
|
||||
.map_bus = nanoengine_pci_map_bus,
|
||||
.read = pci_generic_config_read32,
|
||||
.write = pci_generic_config_write32,
|
||||
};
|
||||
|
||||
static int __init pci_nanoengine_map_irq(const struct pci_dev *dev, u8 slot,
|
||||
|
@ -46,25 +46,3 @@ int pcibios_add_device(struct pci_dev *dev)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_PCI_DOMAINS_GENERIC
|
||||
static bool dt_domain_found = false;
|
||||
|
||||
void pci_bus_assign_domain_nr(struct pci_bus *bus, struct device *parent)
|
||||
{
|
||||
int domain = of_get_pci_domain_nr(parent->of_node);
|
||||
|
||||
if (domain >= 0) {
|
||||
dt_domain_found = true;
|
||||
} else if (dt_domain_found == true) {
|
||||
dev_err(parent, "Node %s is missing \"linux,pci-domain\" property in DT\n",
|
||||
parent->of_node->full_name);
|
||||
return;
|
||||
} else {
|
||||
domain = pci_get_new_domain_nr();
|
||||
}
|
||||
|
||||
bus->domain_nr = domain;
|
||||
}
|
||||
#endif
|
||||
|
@ -168,8 +168,8 @@ static int pci_frv_write_config(struct pci_bus *bus, unsigned int devfn, int whe
|
||||
}
|
||||
|
||||
static struct pci_ops pci_direct_frv = {
|
||||
pci_frv_read_config,
|
||||
pci_frv_write_config,
|
||||
.read = pci_frv_read_config,
|
||||
.write = pci_frv_write_config,
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -173,8 +173,8 @@ static int bcm1480_pcibios_write(struct pci_bus *bus, unsigned int devfn,
|
||||
}
|
||||
|
||||
struct pci_ops bcm1480_pci_ops = {
|
||||
bcm1480_pcibios_read,
|
||||
bcm1480_pcibios_write,
|
||||
.read = bcm1480_pcibios_read,
|
||||
.write = bcm1480_pcibios_write,
|
||||
};
|
||||
|
||||
static struct resource bcm1480_mem_resource = {
|
||||
|
@ -327,8 +327,8 @@ static int octeon_write_config(struct pci_bus *bus, unsigned int devfn,
|
||||
|
||||
|
||||
static struct pci_ops octeon_pci_ops = {
|
||||
octeon_read_config,
|
||||
octeon_write_config,
|
||||
.read = octeon_read_config,
|
||||
.write = octeon_write_config,
|
||||
};
|
||||
|
||||
static struct resource octeon_pci_mem_resource = {
|
||||
|
@ -1792,8 +1792,8 @@ static int octeon_dummy_write_config(struct pci_bus *bus, unsigned int devfn,
|
||||
}
|
||||
|
||||
static struct pci_ops octeon_pcie0_ops = {
|
||||
octeon_pcie0_read_config,
|
||||
octeon_pcie0_write_config,
|
||||
.read = octeon_pcie0_read_config,
|
||||
.write = octeon_pcie0_write_config,
|
||||
};
|
||||
|
||||
static struct resource octeon_pcie0_mem_resource = {
|
||||
@ -1813,8 +1813,8 @@ static struct pci_controller octeon_pcie0_controller = {
|
||||
};
|
||||
|
||||
static struct pci_ops octeon_pcie1_ops = {
|
||||
octeon_pcie1_read_config,
|
||||
octeon_pcie1_write_config,
|
||||
.read = octeon_pcie1_read_config,
|
||||
.write = octeon_pcie1_write_config,
|
||||
};
|
||||
|
||||
static struct resource octeon_pcie1_mem_resource = {
|
||||
@ -1834,8 +1834,8 @@ static struct pci_controller octeon_pcie1_controller = {
|
||||
};
|
||||
|
||||
static struct pci_ops octeon_dummy_ops = {
|
||||
octeon_dummy_read_config,
|
||||
octeon_dummy_write_config,
|
||||
.read = octeon_dummy_read_config,
|
||||
.write = octeon_dummy_write_config,
|
||||
};
|
||||
|
||||
static struct resource octeon_dummy_mem_resource = {
|
||||
|
@ -228,8 +228,8 @@ static int pci_ampci_write_config(struct pci_bus *bus, unsigned int devfn,
|
||||
}
|
||||
|
||||
static struct pci_ops pci_direct_ampci = {
|
||||
pci_ampci_read_config,
|
||||
pci_ampci_write_config,
|
||||
.read = pci_ampci_read_config,
|
||||
.write = pci_ampci_write_config,
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -399,8 +399,8 @@ static int scc_pciex_write_config(struct pci_bus *bus, unsigned int devfn,
|
||||
}
|
||||
|
||||
static struct pci_ops scc_pciex_pci_ops = {
|
||||
scc_pciex_read_config,
|
||||
scc_pciex_write_config,
|
||||
.read = scc_pciex_read_config,
|
||||
.write = scc_pciex_write_config,
|
||||
};
|
||||
|
||||
static void pciex_clear_intr_all(unsigned int __iomem *base)
|
||||
|
@ -133,17 +133,23 @@ static void __init fixup_bus_range(struct device_node *bridge)
|
||||
|(((unsigned int)(off)) & 0xFCUL) \
|
||||
|1UL)
|
||||
|
||||
static volatile void __iomem *macrisc_cfg_access(struct pci_controller* hose,
|
||||
u8 bus, u8 dev_fn, u8 offset)
|
||||
static void __iomem *macrisc_cfg_map_bus(struct pci_bus *bus,
|
||||
unsigned int dev_fn,
|
||||
int offset)
|
||||
{
|
||||
unsigned int caddr;
|
||||
struct pci_controller *hose;
|
||||
|
||||
if (bus == hose->first_busno) {
|
||||
hose = pci_bus_to_host(bus);
|
||||
if (hose == NULL)
|
||||
return NULL;
|
||||
|
||||
if (bus->number == hose->first_busno) {
|
||||
if (dev_fn < (11 << 3))
|
||||
return NULL;
|
||||
caddr = MACRISC_CFA0(dev_fn, offset);
|
||||
} else
|
||||
caddr = MACRISC_CFA1(bus, dev_fn, offset);
|
||||
caddr = MACRISC_CFA1(bus->number, dev_fn, offset);
|
||||
|
||||
/* Uninorth will return garbage if we don't read back the value ! */
|
||||
do {
|
||||
@ -154,129 +160,46 @@ static volatile void __iomem *macrisc_cfg_access(struct pci_controller* hose,
|
||||
return hose->cfg_data + offset;
|
||||
}
|
||||
|
||||
static int macrisc_read_config(struct pci_bus *bus, unsigned int devfn,
|
||||
int offset, int len, u32 *val)
|
||||
{
|
||||
struct pci_controller *hose;
|
||||
volatile void __iomem *addr;
|
||||
|
||||
hose = pci_bus_to_host(bus);
|
||||
if (hose == NULL)
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
if (offset >= 0x100)
|
||||
return PCIBIOS_BAD_REGISTER_NUMBER;
|
||||
addr = macrisc_cfg_access(hose, bus->number, devfn, offset);
|
||||
if (!addr)
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
/*
|
||||
* Note: the caller has already checked that offset is
|
||||
* suitably aligned and that len is 1, 2 or 4.
|
||||
*/
|
||||
switch (len) {
|
||||
case 1:
|
||||
*val = in_8(addr);
|
||||
break;
|
||||
case 2:
|
||||
*val = in_le16(addr);
|
||||
break;
|
||||
default:
|
||||
*val = in_le32(addr);
|
||||
break;
|
||||
}
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
static int macrisc_write_config(struct pci_bus *bus, unsigned int devfn,
|
||||
int offset, int len, u32 val)
|
||||
{
|
||||
struct pci_controller *hose;
|
||||
volatile void __iomem *addr;
|
||||
|
||||
hose = pci_bus_to_host(bus);
|
||||
if (hose == NULL)
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
if (offset >= 0x100)
|
||||
return PCIBIOS_BAD_REGISTER_NUMBER;
|
||||
addr = macrisc_cfg_access(hose, bus->number, devfn, offset);
|
||||
if (!addr)
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
/*
|
||||
* Note: the caller has already checked that offset is
|
||||
* suitably aligned and that len is 1, 2 or 4.
|
||||
*/
|
||||
switch (len) {
|
||||
case 1:
|
||||
out_8(addr, val);
|
||||
break;
|
||||
case 2:
|
||||
out_le16(addr, val);
|
||||
break;
|
||||
default:
|
||||
out_le32(addr, val);
|
||||
break;
|
||||
}
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
static struct pci_ops macrisc_pci_ops =
|
||||
{
|
||||
.read = macrisc_read_config,
|
||||
.write = macrisc_write_config,
|
||||
.map_bus = macrisc_cfg_map_bus,
|
||||
.read = pci_generic_config_read,
|
||||
.write = pci_generic_config_write,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_PPC32
|
||||
/*
|
||||
* Verify that a specific (bus, dev_fn) exists on chaos
|
||||
*/
|
||||
static int chaos_validate_dev(struct pci_bus *bus, int devfn, int offset)
|
||||
static void __iomem *chaos_map_bus(struct pci_bus *bus, unsigned int devfn,
|
||||
int offset)
|
||||
{
|
||||
struct device_node *np;
|
||||
const u32 *vendor, *device;
|
||||
|
||||
if (offset >= 0x100)
|
||||
return PCIBIOS_BAD_REGISTER_NUMBER;
|
||||
return NULL;
|
||||
np = of_pci_find_child_device(bus->dev.of_node, devfn);
|
||||
if (np == NULL)
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
return NULL;
|
||||
|
||||
vendor = of_get_property(np, "vendor-id", NULL);
|
||||
device = of_get_property(np, "device-id", NULL);
|
||||
if (vendor == NULL || device == NULL)
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
return NULL;
|
||||
|
||||
if ((*vendor == 0x106b) && (*device == 3) && (offset >= 0x10)
|
||||
&& (offset != 0x14) && (offset != 0x18) && (offset <= 0x24))
|
||||
return PCIBIOS_BAD_REGISTER_NUMBER;
|
||||
return NULL;
|
||||
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
static int
|
||||
chaos_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
|
||||
int len, u32 *val)
|
||||
{
|
||||
int result = chaos_validate_dev(bus, devfn, offset);
|
||||
if (result == PCIBIOS_BAD_REGISTER_NUMBER)
|
||||
*val = ~0U;
|
||||
if (result != PCIBIOS_SUCCESSFUL)
|
||||
return result;
|
||||
return macrisc_read_config(bus, devfn, offset, len, val);
|
||||
}
|
||||
|
||||
static int
|
||||
chaos_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
|
||||
int len, u32 val)
|
||||
{
|
||||
int result = chaos_validate_dev(bus, devfn, offset);
|
||||
if (result != PCIBIOS_SUCCESSFUL)
|
||||
return result;
|
||||
return macrisc_write_config(bus, devfn, offset, len, val);
|
||||
return macrisc_cfg_map_bus(bus, devfn, offset);
|
||||
}
|
||||
|
||||
static struct pci_ops chaos_pci_ops =
|
||||
{
|
||||
.read = chaos_read_config,
|
||||
.write = chaos_write_config,
|
||||
.map_bus = chaos_map_bus,
|
||||
.read = pci_generic_config_read,
|
||||
.write = pci_generic_config_write,
|
||||
};
|
||||
|
||||
static void __init setup_chaos(struct pci_controller *hose,
|
||||
@ -471,15 +394,24 @@ static struct pci_ops u3_ht_pci_ops =
|
||||
|(((unsigned int)(off)) & 0xfcU) \
|
||||
|1UL)
|
||||
|
||||
static volatile void __iomem *u4_pcie_cfg_access(struct pci_controller* hose,
|
||||
u8 bus, u8 dev_fn, int offset)
|
||||
static void __iomem *u4_pcie_cfg_map_bus(struct pci_bus *bus,
|
||||
unsigned int dev_fn,
|
||||
int offset)
|
||||
{
|
||||
struct pci_controller *hose;
|
||||
unsigned int caddr;
|
||||
|
||||
if (bus == hose->first_busno) {
|
||||
if (offset >= 0x1000)
|
||||
return NULL;
|
||||
|
||||
hose = pci_bus_to_host(bus);
|
||||
if (!hose)
|
||||
return NULL;
|
||||
|
||||
if (bus->number == hose->first_busno) {
|
||||
caddr = U4_PCIE_CFA0(dev_fn, offset);
|
||||
} else
|
||||
caddr = U4_PCIE_CFA1(bus, dev_fn, offset);
|
||||
caddr = U4_PCIE_CFA1(bus->number, dev_fn, offset);
|
||||
|
||||
/* Uninorth will return garbage if we don't read back the value ! */
|
||||
do {
|
||||
@ -490,74 +422,11 @@ static volatile void __iomem *u4_pcie_cfg_access(struct pci_controller* hose,
|
||||
return hose->cfg_data + offset;
|
||||
}
|
||||
|
||||
static int u4_pcie_read_config(struct pci_bus *bus, unsigned int devfn,
|
||||
int offset, int len, u32 *val)
|
||||
{
|
||||
struct pci_controller *hose;
|
||||
volatile void __iomem *addr;
|
||||
|
||||
hose = pci_bus_to_host(bus);
|
||||
if (hose == NULL)
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
if (offset >= 0x1000)
|
||||
return PCIBIOS_BAD_REGISTER_NUMBER;
|
||||
addr = u4_pcie_cfg_access(hose, bus->number, devfn, offset);
|
||||
if (!addr)
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
/*
|
||||
* Note: the caller has already checked that offset is
|
||||
* suitably aligned and that len is 1, 2 or 4.
|
||||
*/
|
||||
switch (len) {
|
||||
case 1:
|
||||
*val = in_8(addr);
|
||||
break;
|
||||
case 2:
|
||||
*val = in_le16(addr);
|
||||
break;
|
||||
default:
|
||||
*val = in_le32(addr);
|
||||
break;
|
||||
}
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
static int u4_pcie_write_config(struct pci_bus *bus, unsigned int devfn,
|
||||
int offset, int len, u32 val)
|
||||
{
|
||||
struct pci_controller *hose;
|
||||
volatile void __iomem *addr;
|
||||
|
||||
hose = pci_bus_to_host(bus);
|
||||
if (hose == NULL)
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
if (offset >= 0x1000)
|
||||
return PCIBIOS_BAD_REGISTER_NUMBER;
|
||||
addr = u4_pcie_cfg_access(hose, bus->number, devfn, offset);
|
||||
if (!addr)
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
/*
|
||||
* Note: the caller has already checked that offset is
|
||||
* suitably aligned and that len is 1, 2 or 4.
|
||||
*/
|
||||
switch (len) {
|
||||
case 1:
|
||||
out_8(addr, val);
|
||||
break;
|
||||
case 2:
|
||||
out_le16(addr, val);
|
||||
break;
|
||||
default:
|
||||
out_le32(addr, val);
|
||||
break;
|
||||
}
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
static struct pci_ops u4_pcie_pci_ops =
|
||||
{
|
||||
.read = u4_pcie_read_config,
|
||||
.write = u4_pcie_write_config,
|
||||
.map_bus = u4_pcie_cfg_map_bus,
|
||||
.read = pci_generic_config_read,
|
||||
.write = pci_generic_config_write,
|
||||
};
|
||||
|
||||
static void pmac_pci_fixup_u4_of_node(struct pci_dev *dev)
|
||||
|
@ -645,61 +645,21 @@ mapped:
|
||||
return pcie->cfg_type1 + offset;
|
||||
}
|
||||
|
||||
static int mpc83xx_pcie_read_config(struct pci_bus *bus, unsigned int devfn,
|
||||
int offset, int len, u32 *val)
|
||||
{
|
||||
void __iomem *cfg_addr;
|
||||
|
||||
cfg_addr = mpc83xx_pcie_remap_cfg(bus, devfn, offset);
|
||||
if (!cfg_addr)
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
|
||||
switch (len) {
|
||||
case 1:
|
||||
*val = in_8(cfg_addr);
|
||||
break;
|
||||
case 2:
|
||||
*val = in_le16(cfg_addr);
|
||||
break;
|
||||
default:
|
||||
*val = in_le32(cfg_addr);
|
||||
break;
|
||||
}
|
||||
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
static int mpc83xx_pcie_write_config(struct pci_bus *bus, unsigned int devfn,
|
||||
int offset, int len, u32 val)
|
||||
{
|
||||
struct pci_controller *hose = pci_bus_to_host(bus);
|
||||
void __iomem *cfg_addr;
|
||||
|
||||
cfg_addr = mpc83xx_pcie_remap_cfg(bus, devfn, offset);
|
||||
if (!cfg_addr)
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
|
||||
/* PPC_INDIRECT_TYPE_SURPRESS_PRIMARY_BUS */
|
||||
if (offset == PCI_PRIMARY_BUS && bus->number == hose->first_busno)
|
||||
val &= 0xffffff00;
|
||||
|
||||
switch (len) {
|
||||
case 1:
|
||||
out_8(cfg_addr, val);
|
||||
break;
|
||||
case 2:
|
||||
out_le16(cfg_addr, val);
|
||||
break;
|
||||
default:
|
||||
out_le32(cfg_addr, val);
|
||||
break;
|
||||
}
|
||||
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
return pci_generic_config_write(bus, devfn, offset, len, val);
|
||||
}
|
||||
|
||||
static struct pci_ops mpc83xx_pcie_ops = {
|
||||
.read = mpc83xx_pcie_read_config,
|
||||
.map_bus = mpc83xx_pcie_remap_cfg,
|
||||
.read = pci_generic_config_read,
|
||||
.write = mpc83xx_pcie_write_config,
|
||||
};
|
||||
|
||||
|
@ -245,7 +245,7 @@ static void fixup_read_and_payload_sizes(void)
|
||||
{
|
||||
struct pci_dev *dev = NULL;
|
||||
int smallest_max_payload = 0x1; /* Tile maxes out at 256 bytes. */
|
||||
int max_read_size = 0x2; /* Limit to 512 byte reads. */
|
||||
int max_read_size = PCI_EXP_DEVCTL_READRQ_512B;
|
||||
u16 new_values;
|
||||
|
||||
/* Scan for the smallest maximum payload size. */
|
||||
@ -258,7 +258,7 @@ static void fixup_read_and_payload_sizes(void)
|
||||
}
|
||||
|
||||
/* Now, set the max_payload_size for all devices to that value. */
|
||||
new_values = (max_read_size << 12) | (smallest_max_payload << 5);
|
||||
new_values = max_read_size | (smallest_max_payload << 5);
|
||||
for_each_pci_dev(dev)
|
||||
pcie_capability_clear_and_set_word(dev, PCI_EXP_DEVCTL,
|
||||
PCI_EXP_DEVCTL_PAYLOAD | PCI_EXP_DEVCTL_READRQ,
|
||||
|
@ -298,12 +298,16 @@ static int xen_initdom_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
|
||||
map_irq.entry_nr = nvec;
|
||||
} else if (type == PCI_CAP_ID_MSIX) {
|
||||
int pos;
|
||||
unsigned long flags;
|
||||
u32 table_offset, bir;
|
||||
|
||||
pos = dev->msix_cap;
|
||||
pci_read_config_dword(dev, pos + PCI_MSIX_TABLE,
|
||||
&table_offset);
|
||||
bir = (u8)(table_offset & PCI_MSIX_TABLE_BIR);
|
||||
flags = pci_resource_flags(dev, bir);
|
||||
if (!flags || (flags & IORESOURCE_UNSET))
|
||||
return -EINVAL;
|
||||
|
||||
map_irq.table_base = pci_resource_start(dev, bir);
|
||||
map_irq.entry_nr = msidesc->msi_attrib.entry_nr;
|
||||
|
@ -4915,7 +4915,7 @@ static void r8168c_hw_jumbo_enable(struct rtl8169_private *tp)
|
||||
|
||||
RTL_W8(Config3, RTL_R8(Config3) | Jumbo_En0);
|
||||
RTL_W8(Config4, RTL_R8(Config4) | Jumbo_En1);
|
||||
rtl_tx_performance_tweak(tp->pci_dev, 0x2 << MAX_READ_REQUEST_SHIFT);
|
||||
rtl_tx_performance_tweak(tp->pci_dev, PCI_EXP_DEVCTL_READRQ_512B);
|
||||
}
|
||||
|
||||
static void r8168c_hw_jumbo_disable(struct rtl8169_private *tp)
|
||||
@ -4948,7 +4948,7 @@ static void r8168e_hw_jumbo_enable(struct rtl8169_private *tp)
|
||||
RTL_W8(MaxTxPacketSize, 0x3f);
|
||||
RTL_W8(Config3, RTL_R8(Config3) | Jumbo_En0);
|
||||
RTL_W8(Config4, RTL_R8(Config4) | 0x01);
|
||||
rtl_tx_performance_tweak(tp->pci_dev, 0x2 << MAX_READ_REQUEST_SHIFT);
|
||||
rtl_tx_performance_tweak(tp->pci_dev, PCI_EXP_DEVCTL_READRQ_512B);
|
||||
}
|
||||
|
||||
static void r8168e_hw_jumbo_disable(struct rtl8169_private *tp)
|
||||
@ -4964,7 +4964,7 @@ static void r8168e_hw_jumbo_disable(struct rtl8169_private *tp)
|
||||
static void r8168b_0_hw_jumbo_enable(struct rtl8169_private *tp)
|
||||
{
|
||||
rtl_tx_performance_tweak(tp->pci_dev,
|
||||
(0x2 << MAX_READ_REQUEST_SHIFT) | PCI_EXP_DEVCTL_NOSNOOP_EN);
|
||||
PCI_EXP_DEVCTL_READRQ_512B | PCI_EXP_DEVCTL_NOSNOOP_EN);
|
||||
}
|
||||
|
||||
static void r8168b_0_hw_jumbo_disable(struct rtl8169_private *tp)
|
||||
|
@ -140,6 +140,7 @@ int of_pci_get_host_bridge_resources(struct device_node *dev,
|
||||
unsigned char busno, unsigned char bus_max,
|
||||
struct list_head *resources, resource_size_t *io_base)
|
||||
{
|
||||
struct pci_host_bridge_window *window;
|
||||
struct resource *res;
|
||||
struct resource *bus_range;
|
||||
struct of_pci_range range;
|
||||
@ -225,7 +226,10 @@ int of_pci_get_host_bridge_resources(struct device_node *dev,
|
||||
conversion_failed:
|
||||
kfree(res);
|
||||
parse_failed:
|
||||
list_for_each_entry(window, resources, list)
|
||||
kfree(window->res);
|
||||
pci_free_resource_list(resources);
|
||||
kfree(bus_range);
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(of_pci_get_host_bridge_resources);
|
||||
|
@ -67,6 +67,93 @@ EXPORT_SYMBOL(pci_bus_write_config_byte);
|
||||
EXPORT_SYMBOL(pci_bus_write_config_word);
|
||||
EXPORT_SYMBOL(pci_bus_write_config_dword);
|
||||
|
||||
int pci_generic_config_read(struct pci_bus *bus, unsigned int devfn,
|
||||
int where, int size, u32 *val)
|
||||
{
|
||||
void __iomem *addr;
|
||||
|
||||
addr = bus->ops->map_bus(bus, devfn, where);
|
||||
if (!addr) {
|
||||
*val = ~0;
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
}
|
||||
|
||||
if (size == 1)
|
||||
*val = readb(addr);
|
||||
else if (size == 2)
|
||||
*val = readw(addr);
|
||||
else
|
||||
*val = readl(addr);
|
||||
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pci_generic_config_read);
|
||||
|
||||
int pci_generic_config_write(struct pci_bus *bus, unsigned int devfn,
|
||||
int where, int size, u32 val)
|
||||
{
|
||||
void __iomem *addr;
|
||||
|
||||
addr = bus->ops->map_bus(bus, devfn, where);
|
||||
if (!addr)
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
|
||||
if (size == 1)
|
||||
writeb(val, addr);
|
||||
else if (size == 2)
|
||||
writew(val, addr);
|
||||
else
|
||||
writel(val, addr);
|
||||
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pci_generic_config_write);
|
||||
|
||||
int pci_generic_config_read32(struct pci_bus *bus, unsigned int devfn,
|
||||
int where, int size, u32 *val)
|
||||
{
|
||||
void __iomem *addr;
|
||||
|
||||
addr = bus->ops->map_bus(bus, devfn, where & ~0x3);
|
||||
if (!addr) {
|
||||
*val = ~0;
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
}
|
||||
|
||||
*val = readl(addr);
|
||||
|
||||
if (size <= 2)
|
||||
*val = (*val >> (8 * (where & 3))) & ((1 << (size * 8)) - 1);
|
||||
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pci_generic_config_read32);
|
||||
|
||||
int pci_generic_config_write32(struct pci_bus *bus, unsigned int devfn,
|
||||
int where, int size, u32 val)
|
||||
{
|
||||
void __iomem *addr;
|
||||
u32 mask, tmp;
|
||||
|
||||
addr = bus->ops->map_bus(bus, devfn, where & ~0x3);
|
||||
if (!addr)
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
|
||||
if (size == 4) {
|
||||
writel(val, addr);
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
} else {
|
||||
mask = ~(((1 << (size * 8)) - 1) << ((where & 0x3) * 8));
|
||||
}
|
||||
|
||||
tmp = readl(addr) & mask;
|
||||
tmp |= val << ((where & 0x3) * 8);
|
||||
writel(tmp, addr);
|
||||
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pci_generic_config_write32);
|
||||
|
||||
/**
|
||||
* pci_bus_set_ops - Set raw operations of pci bus
|
||||
* @bus: pci bus struct
|
||||
|
@ -102,4 +102,8 @@ config PCI_LAYERSCAPE
|
||||
help
|
||||
Say Y here if you want PCIe controller support on Layerscape SoCs.
|
||||
|
||||
config PCI_VERSATILE
|
||||
bool "ARM Versatile PB PCI controller"
|
||||
depends on ARCH_VERSATILE
|
||||
|
||||
endmenu
|
||||
|
@ -12,3 +12,4 @@ obj-$(CONFIG_PCI_KEYSTONE) += pci-keystone-dw.o pci-keystone.o
|
||||
obj-$(CONFIG_PCIE_XILINX) += pcie-xilinx.o
|
||||
obj-$(CONFIG_PCI_XGENE) += pci-xgene.o
|
||||
obj-$(CONFIG_PCI_LAYERSCAPE) += pci-layerscape.o
|
||||
obj-$(CONFIG_PCI_VERSATILE) += pci-versatile.o
|
||||
|
@ -76,55 +76,9 @@ static struct gen_pci_cfg_bus_ops gen_pci_cfg_ecam_bus_ops = {
|
||||
.map_bus = gen_pci_map_cfg_bus_ecam,
|
||||
};
|
||||
|
||||
static int gen_pci_config_read(struct pci_bus *bus, unsigned int devfn,
|
||||
int where, int size, u32 *val)
|
||||
{
|
||||
void __iomem *addr;
|
||||
struct pci_sys_data *sys = bus->sysdata;
|
||||
struct gen_pci *pci = sys->private_data;
|
||||
|
||||
addr = pci->cfg.ops->map_bus(bus, devfn, where);
|
||||
|
||||
switch (size) {
|
||||
case 1:
|
||||
*val = readb(addr);
|
||||
break;
|
||||
case 2:
|
||||
*val = readw(addr);
|
||||
break;
|
||||
default:
|
||||
*val = readl(addr);
|
||||
}
|
||||
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
static int gen_pci_config_write(struct pci_bus *bus, unsigned int devfn,
|
||||
int where, int size, u32 val)
|
||||
{
|
||||
void __iomem *addr;
|
||||
struct pci_sys_data *sys = bus->sysdata;
|
||||
struct gen_pci *pci = sys->private_data;
|
||||
|
||||
addr = pci->cfg.ops->map_bus(bus, devfn, where);
|
||||
|
||||
switch (size) {
|
||||
case 1:
|
||||
writeb(val, addr);
|
||||
break;
|
||||
case 2:
|
||||
writew(val, addr);
|
||||
break;
|
||||
default:
|
||||
writel(val, addr);
|
||||
}
|
||||
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
static struct pci_ops gen_pci_ops = {
|
||||
.read = gen_pci_config_read,
|
||||
.write = gen_pci_config_write,
|
||||
.read = pci_generic_config_read,
|
||||
.write = pci_generic_config_write,
|
||||
};
|
||||
|
||||
static const struct of_device_id gen_pci_of_match[] = {
|
||||
@ -287,6 +241,7 @@ static int gen_pci_probe(struct platform_device *pdev)
|
||||
|
||||
of_id = of_match_node(gen_pci_of_match, np);
|
||||
pci->cfg.ops = of_id->data;
|
||||
gen_pci_ops.map_bus = pci->cfg.ops->map_bus;
|
||||
pci->host.dev.parent = dev;
|
||||
INIT_LIST_HEAD(&pci->host.windows);
|
||||
INIT_LIST_HEAD(&pci->resources);
|
||||
|
@ -119,7 +119,7 @@ static void ks_pcie_msi_irq_handler(unsigned int irq, struct irq_desc *desc)
|
||||
struct pcie_port *pp = &ks_pcie->pp;
|
||||
struct irq_chip *chip = irq_desc_get_chip(desc);
|
||||
|
||||
dev_dbg(pp->dev, "ks_pci_msi_irq_handler, irq %d\n", irq);
|
||||
dev_dbg(pp->dev, "%s, irq %d\n", __func__, irq);
|
||||
|
||||
/*
|
||||
* The chained irq handler installation would have replaced normal
|
||||
@ -197,7 +197,7 @@ static int ks_pcie_get_irq_controller_info(struct keystone_pcie *ks_pcie,
|
||||
*/
|
||||
for (temp = 0; temp < max_host_irqs; temp++) {
|
||||
host_irqs[temp] = irq_of_parse_and_map(*np_temp, temp);
|
||||
if (host_irqs[temp] < 0)
|
||||
if (!host_irqs[temp])
|
||||
break;
|
||||
}
|
||||
if (temp) {
|
||||
|
@ -167,7 +167,6 @@ MODULE_DEVICE_TABLE(of, ls_pcie_of_match);
|
||||
static struct platform_driver ls_pcie_driver = {
|
||||
.driver = {
|
||||
.name = "layerscape-pcie",
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = ls_pcie_of_match,
|
||||
},
|
||||
};
|
||||
|
@ -101,9 +101,7 @@ struct mvebu_pcie {
|
||||
struct mvebu_pcie_port *ports;
|
||||
struct msi_controller *msi;
|
||||
struct resource io;
|
||||
char io_name[30];
|
||||
struct resource realio;
|
||||
char mem_name[30];
|
||||
struct resource mem;
|
||||
struct resource busn;
|
||||
int nports;
|
||||
@ -723,18 +721,9 @@ static int mvebu_pcie_setup(int nr, struct pci_sys_data *sys)
|
||||
{
|
||||
struct mvebu_pcie *pcie = sys_to_pcie(sys);
|
||||
int i;
|
||||
int domain = 0;
|
||||
|
||||
#ifdef CONFIG_PCI_DOMAINS
|
||||
domain = sys->domain;
|
||||
#endif
|
||||
|
||||
snprintf(pcie->mem_name, sizeof(pcie->mem_name), "PCI MEM %04x",
|
||||
domain);
|
||||
pcie->mem.name = pcie->mem_name;
|
||||
|
||||
snprintf(pcie->io_name, sizeof(pcie->io_name), "PCI I/O %04x", domain);
|
||||
pcie->realio.name = pcie->io_name;
|
||||
pcie->mem.name = "PCI MEM";
|
||||
pcie->realio.name = "PCI I/O";
|
||||
|
||||
if (request_resource(&iomem_resource, &pcie->mem))
|
||||
return 0;
|
||||
|
@ -131,52 +131,6 @@ static void __iomem *rcar_pci_cfg_base(struct pci_bus *bus, unsigned int devfn,
|
||||
return priv->reg + (slot >> 1) * 0x100 + where;
|
||||
}
|
||||
|
||||
static int rcar_pci_read_config(struct pci_bus *bus, unsigned int devfn,
|
||||
int where, int size, u32 *val)
|
||||
{
|
||||
void __iomem *reg = rcar_pci_cfg_base(bus, devfn, where);
|
||||
|
||||
if (!reg)
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
|
||||
switch (size) {
|
||||
case 1:
|
||||
*val = ioread8(reg);
|
||||
break;
|
||||
case 2:
|
||||
*val = ioread16(reg);
|
||||
break;
|
||||
default:
|
||||
*val = ioread32(reg);
|
||||
break;
|
||||
}
|
||||
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
static int rcar_pci_write_config(struct pci_bus *bus, unsigned int devfn,
|
||||
int where, int size, u32 val)
|
||||
{
|
||||
void __iomem *reg = rcar_pci_cfg_base(bus, devfn, where);
|
||||
|
||||
if (!reg)
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
|
||||
switch (size) {
|
||||
case 1:
|
||||
iowrite8(val, reg);
|
||||
break;
|
||||
case 2:
|
||||
iowrite16(val, reg);
|
||||
break;
|
||||
default:
|
||||
iowrite32(val, reg);
|
||||
break;
|
||||
}
|
||||
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
/* PCI interrupt mapping */
|
||||
static int rcar_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
|
||||
{
|
||||
@ -325,8 +279,9 @@ static int rcar_pci_setup(int nr, struct pci_sys_data *sys)
|
||||
}
|
||||
|
||||
static struct pci_ops rcar_pci_ops = {
|
||||
.read = rcar_pci_read_config,
|
||||
.write = rcar_pci_write_config,
|
||||
.map_bus = rcar_pci_cfg_base,
|
||||
.read = pci_generic_config_read,
|
||||
.write = pci_generic_config_write,
|
||||
};
|
||||
|
||||
static int rcar_pci_probe(struct platform_device *pdev)
|
||||
|
@ -480,59 +480,10 @@ static void __iomem *tegra_pcie_conf_address(struct pci_bus *bus,
|
||||
return addr;
|
||||
}
|
||||
|
||||
static int tegra_pcie_read_conf(struct pci_bus *bus, unsigned int devfn,
|
||||
int where, int size, u32 *value)
|
||||
{
|
||||
void __iomem *addr;
|
||||
|
||||
addr = tegra_pcie_conf_address(bus, devfn, where);
|
||||
if (!addr) {
|
||||
*value = 0xffffffff;
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
}
|
||||
|
||||
*value = readl(addr);
|
||||
|
||||
if (size == 1)
|
||||
*value = (*value >> (8 * (where & 3))) & 0xff;
|
||||
else if (size == 2)
|
||||
*value = (*value >> (8 * (where & 3))) & 0xffff;
|
||||
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
static int tegra_pcie_write_conf(struct pci_bus *bus, unsigned int devfn,
|
||||
int where, int size, u32 value)
|
||||
{
|
||||
void __iomem *addr;
|
||||
u32 mask, tmp;
|
||||
|
||||
addr = tegra_pcie_conf_address(bus, devfn, where);
|
||||
if (!addr)
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
|
||||
if (size == 4) {
|
||||
writel(value, addr);
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
if (size == 2)
|
||||
mask = ~(0xffff << ((where & 0x3) * 8));
|
||||
else if (size == 1)
|
||||
mask = ~(0xff << ((where & 0x3) * 8));
|
||||
else
|
||||
return PCIBIOS_BAD_REGISTER_NUMBER;
|
||||
|
||||
tmp = readl(addr) & mask;
|
||||
tmp |= value << ((where & 0x3) * 8);
|
||||
writel(tmp, addr);
|
||||
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
static struct pci_ops tegra_pcie_ops = {
|
||||
.read = tegra_pcie_read_conf,
|
||||
.write = tegra_pcie_write_conf,
|
||||
.map_bus = tegra_pcie_conf_address,
|
||||
.read = pci_generic_config_read32,
|
||||
.write = pci_generic_config_write32,
|
||||
};
|
||||
|
||||
static unsigned long tegra_pcie_port_get_pex_ctrl(struct tegra_pcie_port *port)
|
||||
@ -625,19 +576,6 @@ static void tegra_pcie_port_free(struct tegra_pcie_port *port)
|
||||
devm_kfree(pcie->dev, port);
|
||||
}
|
||||
|
||||
static void tegra_pcie_fixup_bridge(struct pci_dev *dev)
|
||||
{
|
||||
u16 reg;
|
||||
|
||||
if ((dev->class >> 16) == PCI_BASE_CLASS_BRIDGE) {
|
||||
pci_read_config_word(dev, PCI_COMMAND, ®);
|
||||
reg |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
|
||||
PCI_COMMAND_MASTER | PCI_COMMAND_SERR);
|
||||
pci_write_config_word(dev, PCI_COMMAND, reg);
|
||||
}
|
||||
}
|
||||
DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, tegra_pcie_fixup_bridge);
|
||||
|
||||
/* Tegra PCIE root complex wrongly reports device class */
|
||||
static void tegra_pcie_fixup_class(struct pci_dev *dev)
|
||||
{
|
||||
|
237
drivers/pci/host/pci-versatile.c
Normal file
237
drivers/pci/host/pci-versatile.c
Normal file
@ -0,0 +1,237 @@
|
||||
/*
|
||||
* Copyright 2004 Koninklijke Philips Electronics NV
|
||||
*
|
||||
* Conversion to platform driver and DT:
|
||||
* Copyright 2014 Linaro Ltd.
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 14/04/2005 Initial version, colin.king@philips.com
|
||||
*/
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_pci.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
static void __iomem *versatile_pci_base;
|
||||
static void __iomem *versatile_cfg_base[2];
|
||||
|
||||
#define PCI_IMAP(m) (versatile_pci_base + ((m) * 4))
|
||||
#define PCI_SMAP(m) (versatile_pci_base + 0x14 + ((m) * 4))
|
||||
#define PCI_SELFID (versatile_pci_base + 0xc)
|
||||
|
||||
#define VP_PCI_DEVICE_ID 0x030010ee
|
||||
#define VP_PCI_CLASS_ID 0x0b400000
|
||||
|
||||
static u32 pci_slot_ignore;
|
||||
|
||||
static int __init versatile_pci_slot_ignore(char *str)
|
||||
{
|
||||
int retval;
|
||||
int slot;
|
||||
|
||||
while ((retval = get_option(&str, &slot))) {
|
||||
if ((slot < 0) || (slot > 31))
|
||||
pr_err("Illegal slot value: %d\n", slot);
|
||||
else
|
||||
pci_slot_ignore |= (1 << slot);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
__setup("pci_slot_ignore=", versatile_pci_slot_ignore);
|
||||
|
||||
|
||||
static void __iomem *versatile_map_bus(struct pci_bus *bus,
|
||||
unsigned int devfn, int offset)
|
||||
{
|
||||
unsigned int busnr = bus->number;
|
||||
|
||||
if (pci_slot_ignore & (1 << PCI_SLOT(devfn)))
|
||||
return NULL;
|
||||
|
||||
return versatile_cfg_base[1] + ((busnr << 16) | (devfn << 8) | offset);
|
||||
}
|
||||
|
||||
static struct pci_ops pci_versatile_ops = {
|
||||
.map_bus = versatile_map_bus,
|
||||
.read = pci_generic_config_read32,
|
||||
.write = pci_generic_config_write,
|
||||
};
|
||||
|
||||
static int versatile_pci_parse_request_of_pci_ranges(struct device *dev,
|
||||
struct list_head *res)
|
||||
{
|
||||
int err, mem = 1, res_valid = 0;
|
||||
struct device_node *np = dev->of_node;
|
||||
resource_size_t iobase;
|
||||
struct pci_host_bridge_window *win;
|
||||
|
||||
err = of_pci_get_host_bridge_resources(np, 0, 0xff, res, &iobase);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
list_for_each_entry(win, res, list) {
|
||||
struct resource *parent, *res = win->res;
|
||||
|
||||
switch (resource_type(res)) {
|
||||
case IORESOURCE_IO:
|
||||
parent = &ioport_resource;
|
||||
err = pci_remap_iospace(res, iobase);
|
||||
if (err) {
|
||||
dev_warn(dev, "error %d: failed to map resource %pR\n",
|
||||
err, res);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case IORESOURCE_MEM:
|
||||
parent = &iomem_resource;
|
||||
res_valid |= !(res->flags & IORESOURCE_PREFETCH);
|
||||
|
||||
writel(res->start >> 28, PCI_IMAP(mem));
|
||||
writel(PHYS_OFFSET >> 28, PCI_SMAP(mem));
|
||||
mem++;
|
||||
|
||||
break;
|
||||
case IORESOURCE_BUS:
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
|
||||
err = devm_request_resource(dev, parent, res);
|
||||
if (err)
|
||||
goto out_release_res;
|
||||
}
|
||||
|
||||
if (!res_valid) {
|
||||
dev_err(dev, "non-prefetchable memory resource required\n");
|
||||
err = -EINVAL;
|
||||
goto out_release_res;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
out_release_res:
|
||||
pci_free_resource_list(res);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Unused, temporary to satisfy ARM arch code */
|
||||
struct pci_sys_data sys;
|
||||
|
||||
static int versatile_pci_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct resource *res;
|
||||
int ret, i, myslot = -1;
|
||||
u32 val;
|
||||
void __iomem *local_pci_cfg_base;
|
||||
struct pci_bus *bus;
|
||||
LIST_HEAD(pci_res);
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!res)
|
||||
return -ENODEV;
|
||||
versatile_pci_base = devm_ioremap_resource(&pdev->dev, res);
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
|
||||
if (!res)
|
||||
return -ENODEV;
|
||||
versatile_cfg_base[0] = devm_ioremap_resource(&pdev->dev, res);
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
|
||||
if (!res)
|
||||
return -ENODEV;
|
||||
versatile_cfg_base[1] = devm_ioremap_resource(&pdev->dev, res);
|
||||
|
||||
ret = versatile_pci_parse_request_of_pci_ranges(&pdev->dev, &pci_res);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* We need to discover the PCI core first to configure itself
|
||||
* before the main PCI probing is performed
|
||||
*/
|
||||
for (i = 0; i < 32; i++) {
|
||||
if ((readl(versatile_cfg_base[0] + (i << 11) + PCI_VENDOR_ID) == VP_PCI_DEVICE_ID) &&
|
||||
(readl(versatile_cfg_base[0] + (i << 11) + PCI_CLASS_REVISION) == VP_PCI_CLASS_ID)) {
|
||||
myslot = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (myslot == -1) {
|
||||
dev_err(&pdev->dev, "Cannot find PCI core!\n");
|
||||
return -EIO;
|
||||
}
|
||||
/*
|
||||
* Do not to map Versatile FPGA PCI device into memory space
|
||||
*/
|
||||
pci_slot_ignore |= (1 << myslot);
|
||||
|
||||
dev_info(&pdev->dev, "PCI core found (slot %d)\n", myslot);
|
||||
|
||||
writel(myslot, PCI_SELFID);
|
||||
local_pci_cfg_base = versatile_cfg_base[1] + (myslot << 11);
|
||||
|
||||
val = readl(local_pci_cfg_base + PCI_COMMAND);
|
||||
val |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE;
|
||||
writel(val, local_pci_cfg_base + PCI_COMMAND);
|
||||
|
||||
/*
|
||||
* Configure the PCI inbound memory windows to be 1:1 mapped to SDRAM
|
||||
*/
|
||||
writel(PHYS_OFFSET, local_pci_cfg_base + PCI_BASE_ADDRESS_0);
|
||||
writel(PHYS_OFFSET, local_pci_cfg_base + PCI_BASE_ADDRESS_1);
|
||||
writel(PHYS_OFFSET, local_pci_cfg_base + PCI_BASE_ADDRESS_2);
|
||||
|
||||
/*
|
||||
* For many years the kernel and QEMU were symbiotically buggy
|
||||
* in that they both assumed the same broken IRQ mapping.
|
||||
* QEMU therefore attempts to auto-detect old broken kernels
|
||||
* so that they still work on newer QEMU as they did on old
|
||||
* QEMU. Since we now use the correct (ie matching-hardware)
|
||||
* IRQ mapping we write a definitely different value to a
|
||||
* PCI_INTERRUPT_LINE register to tell QEMU that we expect
|
||||
* real hardware behaviour and it need not be backwards
|
||||
* compatible for us. This write is harmless on real hardware.
|
||||
*/
|
||||
writel(0, versatile_cfg_base[0] + PCI_INTERRUPT_LINE);
|
||||
|
||||
pci_add_flags(PCI_ENABLE_PROC_DOMAINS);
|
||||
pci_add_flags(PCI_REASSIGN_ALL_BUS | PCI_REASSIGN_ALL_RSRC);
|
||||
|
||||
bus = pci_scan_root_bus(&pdev->dev, 0, &pci_versatile_ops, &sys, &pci_res);
|
||||
if (!bus)
|
||||
return -ENOMEM;
|
||||
|
||||
pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
|
||||
pci_assign_unassigned_bus_resources(bus);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id versatile_pci_of_match[] = {
|
||||
{ .compatible = "arm,versatile-pci", },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, versatile_pci_of_match);
|
||||
|
||||
static struct platform_driver versatile_pci_driver = {
|
||||
.driver = {
|
||||
.name = "versatile-pci",
|
||||
.of_match_table = versatile_pci_of_match,
|
||||
},
|
||||
.probe = versatile_pci_probe,
|
||||
};
|
||||
module_platform_driver(versatile_pci_driver);
|
||||
|
||||
MODULE_DESCRIPTION("Versatile PCI driver");
|
||||
MODULE_LICENSE("GPL v2");
|
@ -16,7 +16,7 @@
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
#include <linux/clk-private.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/jiffies.h>
|
||||
@ -74,92 +74,6 @@ static inline u32 pcie_bar_low_val(u32 addr, u32 flags)
|
||||
return (addr & PCI_BASE_ADDRESS_MEM_MASK) | flags;
|
||||
}
|
||||
|
||||
/* PCIe Configuration Out/In */
|
||||
static inline void xgene_pcie_cfg_out32(void __iomem *addr, int offset, u32 val)
|
||||
{
|
||||
writel(val, addr + offset);
|
||||
}
|
||||
|
||||
static inline void xgene_pcie_cfg_out16(void __iomem *addr, int offset, u16 val)
|
||||
{
|
||||
u32 val32 = readl(addr + (offset & ~0x3));
|
||||
|
||||
switch (offset & 0x3) {
|
||||
case 2:
|
||||
val32 &= ~0xFFFF0000;
|
||||
val32 |= (u32)val << 16;
|
||||
break;
|
||||
case 0:
|
||||
default:
|
||||
val32 &= ~0xFFFF;
|
||||
val32 |= val;
|
||||
break;
|
||||
}
|
||||
writel(val32, addr + (offset & ~0x3));
|
||||
}
|
||||
|
||||
static inline void xgene_pcie_cfg_out8(void __iomem *addr, int offset, u8 val)
|
||||
{
|
||||
u32 val32 = readl(addr + (offset & ~0x3));
|
||||
|
||||
switch (offset & 0x3) {
|
||||
case 0:
|
||||
val32 &= ~0xFF;
|
||||
val32 |= val;
|
||||
break;
|
||||
case 1:
|
||||
val32 &= ~0xFF00;
|
||||
val32 |= (u32)val << 8;
|
||||
break;
|
||||
case 2:
|
||||
val32 &= ~0xFF0000;
|
||||
val32 |= (u32)val << 16;
|
||||
break;
|
||||
case 3:
|
||||
default:
|
||||
val32 &= ~0xFF000000;
|
||||
val32 |= (u32)val << 24;
|
||||
break;
|
||||
}
|
||||
writel(val32, addr + (offset & ~0x3));
|
||||
}
|
||||
|
||||
static inline void xgene_pcie_cfg_in32(void __iomem *addr, int offset, u32 *val)
|
||||
{
|
||||
*val = readl(addr + offset);
|
||||
}
|
||||
|
||||
static inline void xgene_pcie_cfg_in16(void __iomem *addr, int offset, u32 *val)
|
||||
{
|
||||
*val = readl(addr + (offset & ~0x3));
|
||||
|
||||
switch (offset & 0x3) {
|
||||
case 2:
|
||||
*val >>= 16;
|
||||
break;
|
||||
}
|
||||
|
||||
*val &= 0xFFFF;
|
||||
}
|
||||
|
||||
static inline void xgene_pcie_cfg_in8(void __iomem *addr, int offset, u32 *val)
|
||||
{
|
||||
*val = readl(addr + (offset & ~0x3));
|
||||
|
||||
switch (offset & 0x3) {
|
||||
case 3:
|
||||
*val = *val >> 24;
|
||||
break;
|
||||
case 2:
|
||||
*val = *val >> 16;
|
||||
break;
|
||||
case 1:
|
||||
*val = *val >> 8;
|
||||
break;
|
||||
}
|
||||
*val &= 0xFF;
|
||||
}
|
||||
|
||||
/*
|
||||
* When the address bit [17:16] is 2'b01, the Configuration access will be
|
||||
* treated as Type 1 and it will be forwarded to external PCIe device.
|
||||
@ -213,69 +127,23 @@ static bool xgene_pcie_hide_rc_bars(struct pci_bus *bus, int offset)
|
||||
return false;
|
||||
}
|
||||
|
||||
static int xgene_pcie_read_config(struct pci_bus *bus, unsigned int devfn,
|
||||
int offset, int len, u32 *val)
|
||||
static int xgene_pcie_map_bus(struct pci_bus *bus, unsigned int devfn,
|
||||
int offset)
|
||||
{
|
||||
struct xgene_pcie_port *port = bus->sysdata;
|
||||
void __iomem *addr;
|
||||
|
||||
if ((pci_is_root_bus(bus) && devfn != 0) || !port->link_up)
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
|
||||
if (xgene_pcie_hide_rc_bars(bus, offset)) {
|
||||
*val = 0;
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
if ((pci_is_root_bus(bus) && devfn != 0) || !port->link_up ||
|
||||
xgene_pcie_hide_rc_bars(bus, offset))
|
||||
return NULL;
|
||||
|
||||
xgene_pcie_set_rtdid_reg(bus, devfn);
|
||||
addr = xgene_pcie_get_cfg_base(bus);
|
||||
switch (len) {
|
||||
case 1:
|
||||
xgene_pcie_cfg_in8(addr, offset, val);
|
||||
break;
|
||||
case 2:
|
||||
xgene_pcie_cfg_in16(addr, offset, val);
|
||||
break;
|
||||
default:
|
||||
xgene_pcie_cfg_in32(addr, offset, val);
|
||||
break;
|
||||
}
|
||||
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
static int xgene_pcie_write_config(struct pci_bus *bus, unsigned int devfn,
|
||||
int offset, int len, u32 val)
|
||||
{
|
||||
struct xgene_pcie_port *port = bus->sysdata;
|
||||
void __iomem *addr;
|
||||
|
||||
if ((pci_is_root_bus(bus) && devfn != 0) || !port->link_up)
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
|
||||
if (xgene_pcie_hide_rc_bars(bus, offset))
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
|
||||
xgene_pcie_set_rtdid_reg(bus, devfn);
|
||||
addr = xgene_pcie_get_cfg_base(bus);
|
||||
switch (len) {
|
||||
case 1:
|
||||
xgene_pcie_cfg_out8(addr, offset, (u8)val);
|
||||
break;
|
||||
case 2:
|
||||
xgene_pcie_cfg_out16(addr, offset, (u16)val);
|
||||
break;
|
||||
default:
|
||||
xgene_pcie_cfg_out32(addr, offset, val);
|
||||
break;
|
||||
}
|
||||
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
return xgene_pcie_get_cfg_base(bus);
|
||||
}
|
||||
|
||||
static struct pci_ops xgene_pcie_ops = {
|
||||
.read = xgene_pcie_read_config,
|
||||
.write = xgene_pcie_write_config
|
||||
.map_bus = xgene_pcie_map_bus,
|
||||
.read = pci_generic_config_read32,
|
||||
.write = pci_generic_config_write32,
|
||||
};
|
||||
|
||||
static u64 xgene_pcie_set_ib_mask(void __iomem *csr_base, u32 addr,
|
||||
|
@ -511,9 +511,6 @@ int __init dw_pcie_host_init(struct pcie_port *pp)
|
||||
dw_pci.private_data = (void **)&pp;
|
||||
|
||||
pci_common_init_dev(pp->dev, &dw_pci);
|
||||
#ifdef CONFIG_PCI_DOMAINS
|
||||
dw_pci.domain++;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -397,9 +397,6 @@ static void rcar_pcie_enable(struct rcar_pcie *pcie)
|
||||
#endif
|
||||
|
||||
pci_common_init_dev(&pdev->dev, &rcar_pci);
|
||||
#ifdef CONFIG_PCI_DOMAINS
|
||||
rcar_pci.domain++;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int phy_wait_for_ack(struct rcar_pcie *pcie)
|
||||
@ -757,7 +754,7 @@ static int rcar_pcie_get_resources(struct platform_device *pdev,
|
||||
goto err_map_reg;
|
||||
|
||||
i = irq_of_parse_and_map(pdev->dev.of_node, 0);
|
||||
if (i < 0) {
|
||||
if (!i) {
|
||||
dev_err(pcie->dev, "cannot get platform resources for msi interrupt\n");
|
||||
err = -ENOENT;
|
||||
goto err_map_reg;
|
||||
@ -765,7 +762,7 @@ static int rcar_pcie_get_resources(struct platform_device *pdev,
|
||||
pcie->msi.irq1 = i;
|
||||
|
||||
i = irq_of_parse_and_map(pdev->dev.of_node, 1);
|
||||
if (i < 0) {
|
||||
if (!i) {
|
||||
dev_err(pcie->dev, "cannot get platform resources for msi interrupt\n");
|
||||
err = -ENOENT;
|
||||
goto err_map_reg;
|
||||
|
@ -148,10 +148,10 @@ static inline bool xilinx_pcie_link_is_up(struct xilinx_pcie_port *port)
|
||||
*/
|
||||
static void xilinx_pcie_clear_err_interrupts(struct xilinx_pcie_port *port)
|
||||
{
|
||||
u32 val = pcie_read(port, XILINX_PCIE_REG_RPEFR);
|
||||
unsigned long val = pcie_read(port, XILINX_PCIE_REG_RPEFR);
|
||||
|
||||
if (val & XILINX_PCIE_RPEFR_ERR_VALID) {
|
||||
dev_dbg(port->dev, "Requester ID %d\n",
|
||||
dev_dbg(port->dev, "Requester ID %lu\n",
|
||||
val & XILINX_PCIE_RPEFR_REQ_ID);
|
||||
pcie_write(port, XILINX_PCIE_RPEFR_ALL_MASK,
|
||||
XILINX_PCIE_REG_RPEFR);
|
||||
@ -189,7 +189,7 @@ static bool xilinx_pcie_valid_device(struct pci_bus *bus, unsigned int devfn)
|
||||
}
|
||||
|
||||
/**
|
||||
* xilinx_pcie_config_base - Get configuration base
|
||||
* xilinx_pcie_map_bus - Get configuration base
|
||||
* @bus: PCI Bus structure
|
||||
* @devfn: Device/function
|
||||
* @where: Offset from base
|
||||
@ -197,96 +197,26 @@ static bool xilinx_pcie_valid_device(struct pci_bus *bus, unsigned int devfn)
|
||||
* Return: Base address of the configuration space needed to be
|
||||
* accessed.
|
||||
*/
|
||||
static void __iomem *xilinx_pcie_config_base(struct pci_bus *bus,
|
||||
unsigned int devfn, int where)
|
||||
static void __iomem *xilinx_pcie_map_bus(struct pci_bus *bus,
|
||||
unsigned int devfn, int where)
|
||||
{
|
||||
struct xilinx_pcie_port *port = sys_to_pcie(bus->sysdata);
|
||||
int relbus;
|
||||
|
||||
if (!xilinx_pcie_valid_device(bus, devfn))
|
||||
return NULL;
|
||||
|
||||
relbus = (bus->number << ECAM_BUS_NUM_SHIFT) |
|
||||
(devfn << ECAM_DEV_NUM_SHIFT);
|
||||
|
||||
return port->reg_base + relbus + where;
|
||||
}
|
||||
|
||||
/**
|
||||
* xilinx_pcie_read_config - Read configuration space
|
||||
* @bus: PCI Bus structure
|
||||
* @devfn: Device/function
|
||||
* @where: Offset from base
|
||||
* @size: Byte/word/dword
|
||||
* @val: Value to be read
|
||||
*
|
||||
* Return: PCIBIOS_SUCCESSFUL on success
|
||||
* PCIBIOS_DEVICE_NOT_FOUND on failure
|
||||
*/
|
||||
static int xilinx_pcie_read_config(struct pci_bus *bus, unsigned int devfn,
|
||||
int where, int size, u32 *val)
|
||||
{
|
||||
void __iomem *addr;
|
||||
|
||||
if (!xilinx_pcie_valid_device(bus, devfn)) {
|
||||
*val = 0xFFFFFFFF;
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
}
|
||||
|
||||
addr = xilinx_pcie_config_base(bus, devfn, where);
|
||||
|
||||
switch (size) {
|
||||
case 1:
|
||||
*val = readb(addr);
|
||||
break;
|
||||
case 2:
|
||||
*val = readw(addr);
|
||||
break;
|
||||
default:
|
||||
*val = readl(addr);
|
||||
break;
|
||||
}
|
||||
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
/**
|
||||
* xilinx_pcie_write_config - Write configuration space
|
||||
* @bus: PCI Bus structure
|
||||
* @devfn: Device/function
|
||||
* @where: Offset from base
|
||||
* @size: Byte/word/dword
|
||||
* @val: Value to be written to device
|
||||
*
|
||||
* Return: PCIBIOS_SUCCESSFUL on success
|
||||
* PCIBIOS_DEVICE_NOT_FOUND on failure
|
||||
*/
|
||||
static int xilinx_pcie_write_config(struct pci_bus *bus, unsigned int devfn,
|
||||
int where, int size, u32 val)
|
||||
{
|
||||
void __iomem *addr;
|
||||
|
||||
if (!xilinx_pcie_valid_device(bus, devfn))
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
|
||||
addr = xilinx_pcie_config_base(bus, devfn, where);
|
||||
|
||||
switch (size) {
|
||||
case 1:
|
||||
writeb(val, addr);
|
||||
break;
|
||||
case 2:
|
||||
writew(val, addr);
|
||||
break;
|
||||
default:
|
||||
writel(val, addr);
|
||||
break;
|
||||
}
|
||||
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
/* PCIe operations */
|
||||
static struct pci_ops xilinx_pcie_ops = {
|
||||
.read = xilinx_pcie_read_config,
|
||||
.write = xilinx_pcie_write_config,
|
||||
.map_bus = xilinx_pcie_map_bus,
|
||||
.read = pci_generic_config_read,
|
||||
.write = pci_generic_config_write,
|
||||
};
|
||||
|
||||
/* MSI functions */
|
||||
|
@ -214,8 +214,7 @@ static void release_slot(struct hotplug_slot *hotplug_slot)
|
||||
|
||||
kfree(slot->hotplug_slot->info);
|
||||
kfree(slot->hotplug_slot);
|
||||
if (slot->dev)
|
||||
pci_dev_put(slot->dev);
|
||||
pci_dev_put(slot->dev);
|
||||
kfree(slot);
|
||||
}
|
||||
|
||||
|
@ -532,8 +532,6 @@ static void interrupt_event_handler(struct work_struct *work)
|
||||
pciehp_green_led_off(p_slot);
|
||||
break;
|
||||
case INT_PRESENCE_ON:
|
||||
if (!HP_SUPR_RM(ctrl))
|
||||
break;
|
||||
ctrl_dbg(ctrl, "Surprise Insertion\n");
|
||||
handle_surprise_event(p_slot);
|
||||
break;
|
||||
|
@ -694,11 +694,16 @@ static void __iomem *msix_map_region(struct pci_dev *dev, unsigned nr_entries)
|
||||
{
|
||||
resource_size_t phys_addr;
|
||||
u32 table_offset;
|
||||
unsigned long flags;
|
||||
u8 bir;
|
||||
|
||||
pci_read_config_dword(dev, dev->msix_cap + PCI_MSIX_TABLE,
|
||||
&table_offset);
|
||||
bir = (u8)(table_offset & PCI_MSIX_TABLE_BIR);
|
||||
flags = pci_resource_flags(dev, bir);
|
||||
if (!flags || (flags & IORESOURCE_UNSET))
|
||||
return NULL;
|
||||
|
||||
table_offset &= PCI_MSIX_TABLE_OFFSET;
|
||||
phys_addr = pci_resource_start(dev, bir) + table_offset;
|
||||
|
||||
|
@ -1383,7 +1383,7 @@ static int pci_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||
if (add_uevent_var(env, "PCI_SLOT_NAME=%s", pci_name(pdev)))
|
||||
return -ENOMEM;
|
||||
|
||||
if (add_uevent_var(env, "MODALIAS=pci:v%08Xd%08Xsv%08Xsd%08Xbc%02Xsc%02Xi%02x",
|
||||
if (add_uevent_var(env, "MODALIAS=pci:v%08Xd%08Xsv%08Xsd%08Xbc%02Xsc%02Xi%02X",
|
||||
pdev->vendor, pdev->device,
|
||||
pdev->subsystem_vendor, pdev->subsystem_device,
|
||||
(u8)(pdev->class >> 16), (u8)(pdev->class >> 8),
|
||||
|
@ -10,6 +10,8 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_pci.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/slab.h>
|
||||
@ -3197,7 +3199,7 @@ static int pci_pm_reset(struct pci_dev *dev, int probe)
|
||||
{
|
||||
u16 csr;
|
||||
|
||||
if (!dev->pm_cap)
|
||||
if (!dev->pm_cap || dev->dev_flags & PCI_DEV_FLAGS_NO_PM_RESET)
|
||||
return -ENOTTY;
|
||||
|
||||
pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &csr);
|
||||
@ -4471,6 +4473,53 @@ int pci_get_new_domain_nr(void)
|
||||
{
|
||||
return atomic_inc_return(&__domain_nr);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PCI_DOMAINS_GENERIC
|
||||
void pci_bus_assign_domain_nr(struct pci_bus *bus, struct device *parent)
|
||||
{
|
||||
static int use_dt_domains = -1;
|
||||
int domain = of_get_pci_domain_nr(parent->of_node);
|
||||
|
||||
/*
|
||||
* Check DT domain and use_dt_domains values.
|
||||
*
|
||||
* If DT domain property is valid (domain >= 0) and
|
||||
* use_dt_domains != 0, the DT assignment is valid since this means
|
||||
* we have not previously allocated a domain number by using
|
||||
* pci_get_new_domain_nr(); we should also update use_dt_domains to
|
||||
* 1, to indicate that we have just assigned a domain number from
|
||||
* DT.
|
||||
*
|
||||
* If DT domain property value is not valid (ie domain < 0), and we
|
||||
* have not previously assigned a domain number from DT
|
||||
* (use_dt_domains != 1) we should assign a domain number by
|
||||
* using the:
|
||||
*
|
||||
* pci_get_new_domain_nr()
|
||||
*
|
||||
* API and update the use_dt_domains value to keep track of method we
|
||||
* are using to assign domain numbers (use_dt_domains = 0).
|
||||
*
|
||||
* All other combinations imply we have a platform that is trying
|
||||
* to mix domain numbers obtained from DT and pci_get_new_domain_nr(),
|
||||
* which is a recipe for domain mishandling and it is prevented by
|
||||
* invalidating the domain value (domain = -1) and printing a
|
||||
* corresponding error.
|
||||
*/
|
||||
if (domain >= 0 && use_dt_domains) {
|
||||
use_dt_domains = 1;
|
||||
} else if (domain < 0 && use_dt_domains != 1) {
|
||||
use_dt_domains = 0;
|
||||
domain = pci_get_new_domain_nr();
|
||||
} else {
|
||||
dev_err(parent, "Node %s has inconsistent \"linux,pci-domain\" property in DT\n",
|
||||
parent->of_node->full_name);
|
||||
domain = -1;
|
||||
}
|
||||
|
||||
bus->domain_nr = domain;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
@ -859,7 +859,10 @@ static ssize_t link_state_store(struct device *dev,
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(dev);
|
||||
struct pcie_link_state *link, *root = pdev->link_state->root;
|
||||
u32 val = buf[0] - '0', state = 0;
|
||||
u32 val, state = 0;
|
||||
|
||||
if (kstrtouint(buf, 10, &val))
|
||||
return -EINVAL;
|
||||
|
||||
if (aspm_disabled)
|
||||
return -EPERM;
|
||||
@ -900,15 +903,14 @@ static ssize_t clk_ctl_store(struct device *dev,
|
||||
size_t n)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(dev);
|
||||
int state;
|
||||
bool state;
|
||||
|
||||
if (n < 1)
|
||||
if (strtobool(buf, &state))
|
||||
return -EINVAL;
|
||||
state = buf[0]-'0';
|
||||
|
||||
down_read(&pci_bus_sem);
|
||||
mutex_lock(&aspm_lock);
|
||||
pcie_set_clkpm_nocheck(pdev->link_state, !!state);
|
||||
pcie_set_clkpm_nocheck(pdev->link_state, state);
|
||||
mutex_unlock(&aspm_lock);
|
||||
up_read(&pci_bus_sem);
|
||||
|
||||
|
@ -3076,6 +3076,27 @@ static void quirk_no_bus_reset(struct pci_dev *dev)
|
||||
*/
|
||||
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x0030, quirk_no_bus_reset);
|
||||
|
||||
static void quirk_no_pm_reset(struct pci_dev *dev)
|
||||
{
|
||||
/*
|
||||
* We can't do a bus reset on root bus devices, but an ineffective
|
||||
* PM reset may be better than nothing.
|
||||
*/
|
||||
if (!pci_is_root_bus(dev->bus))
|
||||
dev->dev_flags |= PCI_DEV_FLAGS_NO_PM_RESET;
|
||||
}
|
||||
|
||||
/*
|
||||
* Some AMD/ATI GPUS (HD8570 - Oland) report that a D3hot->D0 transition
|
||||
* causes a reset (i.e., they advertise NoSoftRst-). This transition seems
|
||||
* to have no effect on the device: it retains the framebuffer contents and
|
||||
* monitor sync. Advertising this support makes other layers, like VFIO,
|
||||
* assume pci_reset_function() is viable for this device. Mark it as
|
||||
* unavailable to skip it when testing reset methods.
|
||||
*/
|
||||
DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_VENDOR_ID_ATI, PCI_ANY_ID,
|
||||
PCI_CLASS_DISPLAY_VGA, 8, quirk_no_pm_reset);
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
/*
|
||||
* Apple: Shutdown Cactus Ridge Thunderbolt controller.
|
||||
@ -3575,6 +3596,44 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_JMICRON,
|
||||
PCI_DEVICE_ID_JMICRON_JMB388_ESD,
|
||||
quirk_dma_func1_alias);
|
||||
|
||||
/*
|
||||
* Some devices DMA with the wrong devfn, not just the wrong function.
|
||||
* quirk_fixed_dma_alias() uses this table to create fixed aliases, where
|
||||
* the alias is "fixed" and independent of the device devfn.
|
||||
*
|
||||
* For example, the Adaptec 3405 is a PCIe card with an Intel 80333 I/O
|
||||
* processor. To software, this appears as a PCIe-to-PCI/X bridge with a
|
||||
* single device on the secondary bus. In reality, the single exposed
|
||||
* device at 0e.0 is the Address Translation Unit (ATU) of the controller
|
||||
* that provides a bridge to the internal bus of the I/O processor. The
|
||||
* controller supports private devices, which can be hidden from PCI config
|
||||
* space. In the case of the Adaptec 3405, a private device at 01.0
|
||||
* appears to be the DMA engine, which therefore needs to become a DMA
|
||||
* alias for the device.
|
||||
*/
|
||||
static const struct pci_device_id fixed_dma_alias_tbl[] = {
|
||||
{ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x0285,
|
||||
PCI_VENDOR_ID_ADAPTEC2, 0x02bb), /* Adaptec 3405 */
|
||||
.driver_data = PCI_DEVFN(1, 0) },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static void quirk_fixed_dma_alias(struct pci_dev *dev)
|
||||
{
|
||||
const struct pci_device_id *id;
|
||||
|
||||
id = pci_match_id(fixed_dma_alias_tbl, dev);
|
||||
if (id) {
|
||||
dev->dma_alias_devfn = id->driver_data;
|
||||
dev->dev_flags |= PCI_DEV_FLAGS_DMA_ALIAS_DEVFN;
|
||||
dev_info(&dev->dev, "Enabling fixed DMA alias to %02x.%d\n",
|
||||
PCI_SLOT(dev->dma_alias_devfn),
|
||||
PCI_FUNC(dev->dma_alias_devfn));
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ADAPTEC2, 0x0285, quirk_fixed_dma_alias);
|
||||
|
||||
/*
|
||||
* A few PCIe-to-PCI bridges fail to expose a PCIe capability, resulting in
|
||||
* using the wrong DMA alias for the device. Some of these devices can be
|
||||
@ -3678,6 +3737,9 @@ static const u16 pci_quirk_intel_pch_acs_ids[] = {
|
||||
0x9c98, 0x9c99, 0x9c9a, 0x9c9b,
|
||||
/* Patsburg (X79) PCH */
|
||||
0x1d10, 0x1d12, 0x1d14, 0x1d16, 0x1d18, 0x1d1a, 0x1d1c, 0x1d1e,
|
||||
/* Wellsburg (X99) PCH */
|
||||
0x8d10, 0x8d11, 0x8d12, 0x8d13, 0x8d14, 0x8d15, 0x8d16, 0x8d17,
|
||||
0x8d18, 0x8d19, 0x8d1a, 0x8d1b, 0x8d1c, 0x8d1d, 0x8d1e,
|
||||
};
|
||||
|
||||
static bool pci_quirk_intel_pch_acs_match(struct pci_dev *dev)
|
||||
@ -3761,6 +3823,8 @@ static const struct pci_dev_acs_enabled {
|
||||
{ PCI_VENDOR_ID_INTEL, 0x1551, pci_quirk_mf_endpoint_acs },
|
||||
{ PCI_VENDOR_ID_INTEL, 0x1558, pci_quirk_mf_endpoint_acs },
|
||||
{ PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_quirk_intel_pch_acs },
|
||||
{ 0x19a2, 0x710, pci_quirk_mf_endpoint_acs }, /* Emulex BE3-R */
|
||||
{ 0x10df, 0x720, pci_quirk_mf_endpoint_acs }, /* Emulex Skyhawk-R */
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
|
@ -71,6 +71,7 @@ size_t pci_get_rom_size(struct pci_dev *pdev, void __iomem *rom, size_t size)
|
||||
{
|
||||
void __iomem *image;
|
||||
int last_image;
|
||||
unsigned length;
|
||||
|
||||
image = rom;
|
||||
do {
|
||||
@ -93,9 +94,9 @@ size_t pci_get_rom_size(struct pci_dev *pdev, void __iomem *rom, size_t size)
|
||||
if (readb(pds + 3) != 'R')
|
||||
break;
|
||||
last_image = readb(pds + 21) & 0x80;
|
||||
/* this length is reliable */
|
||||
image += readw(pds + 16) * 512;
|
||||
} while (!last_image);
|
||||
length = readw(pds + 16);
|
||||
image += length * 512;
|
||||
} while (length && !last_image);
|
||||
|
||||
/* never return a size larger than the PCI resource window */
|
||||
/* there are known ROMs that get the size wrong */
|
||||
|
@ -2430,7 +2430,7 @@ static int tsi721_probe(struct pci_dev *pdev,
|
||||
pcie_capability_clear_and_set_word(pdev, PCI_EXP_DEVCTL,
|
||||
PCI_EXP_DEVCTL_READRQ | PCI_EXP_DEVCTL_RELAX_EN |
|
||||
PCI_EXP_DEVCTL_NOSNOOP_EN,
|
||||
0x2 << MAX_READ_REQUEST_SZ_SHIFT);
|
||||
PCI_EXP_DEVCTL_READRQ_512B);
|
||||
|
||||
/* Adjust PCIe completion timeout. */
|
||||
pcie_capability_clear_and_set_word(pdev, PCI_EXP_DEVCTL2, 0xf, 0x2);
|
||||
|
@ -72,8 +72,6 @@
|
||||
#define TSI721_MSIXPBA_OFFSET 0x2a000
|
||||
#define TSI721_PCIECFG_EPCTL 0x400
|
||||
|
||||
#define MAX_READ_REQUEST_SZ_SHIFT 12
|
||||
|
||||
/*
|
||||
* Event Management Registers
|
||||
*/
|
||||
|
@ -813,12 +813,13 @@ static void esas2r_init_pci_cfg_space(struct esas2r_adapter *a)
|
||||
pci_read_config_word(a->pcid, pcie_cap_reg + PCI_EXP_DEVCTL,
|
||||
&devcontrol);
|
||||
|
||||
if ((devcontrol & PCI_EXP_DEVCTL_READRQ) > 0x2000) {
|
||||
if ((devcontrol & PCI_EXP_DEVCTL_READRQ) >
|
||||
PCI_EXP_DEVCTL_READRQ_512B) {
|
||||
esas2r_log(ESAS2R_LOG_INFO,
|
||||
"max read request size > 512B");
|
||||
|
||||
devcontrol &= ~PCI_EXP_DEVCTL_READRQ;
|
||||
devcontrol |= 0x2000;
|
||||
devcontrol |= PCI_EXP_DEVCTL_READRQ_512B;
|
||||
pci_write_config_word(a->pcid,
|
||||
pcie_cap_reg + PCI_EXP_DEVCTL,
|
||||
devcontrol);
|
||||
|
@ -177,6 +177,8 @@ enum pci_dev_flags {
|
||||
PCI_DEV_FLAG_PCIE_BRIDGE_ALIAS = (__force pci_dev_flags_t) (1 << 5),
|
||||
/* Do not use bus resets for device */
|
||||
PCI_DEV_FLAGS_NO_BUS_RESET = (__force pci_dev_flags_t) (1 << 6),
|
||||
/* Do not use PM reset even if device advertises NoSoftRst- */
|
||||
PCI_DEV_FLAGS_NO_PM_RESET = (__force pci_dev_flags_t) (1 << 7),
|
||||
};
|
||||
|
||||
enum pci_irq_reroute_variant {
|
||||
@ -562,6 +564,7 @@ static inline int pcibios_err_to_errno(int err)
|
||||
/* Low-level architecture-dependent routines */
|
||||
|
||||
struct pci_ops {
|
||||
void __iomem *(*map_bus)(struct pci_bus *bus, unsigned int devfn, int where);
|
||||
int (*read)(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *val);
|
||||
int (*write)(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val);
|
||||
};
|
||||
@ -859,6 +862,16 @@ int pci_bus_write_config_word(struct pci_bus *bus, unsigned int devfn,
|
||||
int where, u16 val);
|
||||
int pci_bus_write_config_dword(struct pci_bus *bus, unsigned int devfn,
|
||||
int where, u32 val);
|
||||
|
||||
int pci_generic_config_read(struct pci_bus *bus, unsigned int devfn,
|
||||
int where, int size, u32 *val);
|
||||
int pci_generic_config_write(struct pci_bus *bus, unsigned int devfn,
|
||||
int where, int size, u32 val);
|
||||
int pci_generic_config_read32(struct pci_bus *bus, unsigned int devfn,
|
||||
int where, int size, u32 *val);
|
||||
int pci_generic_config_write32(struct pci_bus *bus, unsigned int devfn,
|
||||
int where, int size, u32 val);
|
||||
|
||||
struct pci_ops *pci_bus_set_ops(struct pci_bus *bus, struct pci_ops *ops);
|
||||
|
||||
static inline int pci_read_config_byte(const struct pci_dev *dev, int where, u8 *val)
|
||||
@ -1850,6 +1863,8 @@ static inline void pci_set_of_node(struct pci_dev *dev) { }
|
||||
static inline void pci_release_of_node(struct pci_dev *dev) { }
|
||||
static inline void pci_set_bus_of_node(struct pci_bus *bus) { }
|
||||
static inline void pci_release_bus_of_node(struct pci_bus *bus) { }
|
||||
static inline struct device_node *
|
||||
pci_device_to_OF_node(const struct pci_dev *pdev) { return NULL; }
|
||||
#endif /* CONFIG_OF */
|
||||
|
||||
#ifdef CONFIG_EEH
|
||||
|
@ -451,6 +451,10 @@
|
||||
#define PCI_EXP_DEVCTL_AUX_PME 0x0400 /* Auxiliary Power PM Enable */
|
||||
#define PCI_EXP_DEVCTL_NOSNOOP_EN 0x0800 /* Enable No Snoop */
|
||||
#define PCI_EXP_DEVCTL_READRQ 0x7000 /* Max_Read_Request_Size */
|
||||
#define PCI_EXP_DEVCTL_READRQ_128B 0x0000 /* 128 Bytes */
|
||||
#define PCI_EXP_DEVCTL_READRQ_256B 0x1000 /* 256 Bytes */
|
||||
#define PCI_EXP_DEVCTL_READRQ_512B 0x2000 /* 512 Bytes */
|
||||
#define PCI_EXP_DEVCTL_READRQ_1024B 0x3000 /* 1024 Bytes */
|
||||
#define PCI_EXP_DEVCTL_BCR_FLR 0x8000 /* Bridge Configuration Retry / FLR */
|
||||
#define PCI_EXP_DEVSTA 10 /* Device Status */
|
||||
#define PCI_EXP_DEVSTA_CED 0x0001 /* Correctable Error Detected */
|
||||
|
Loading…
Reference in New Issue
Block a user