![Linus Torvalds](/assets/img/avatar_default.png)
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJad5lgAAoJEFmIoMA60/r8s2kQAI3PztawDpaCP9Z12pkbBHSt Ho0xTyk9rCZi9kQJbNjc+a+QrlA3QmTHXIXerB3LSWoh7M+XhsECjem92eHpgLNS JvYPhTfOrCr0vdiAmOz6hD0AqN/psrbfzgiJhSwomsGEFS77k7kERSJckRv81sxb Aj5F/WjucAgLorwm4auveAJEQ7atE7/6pkXzoqYm4G6NLOb46jUcRGndrnvXZBlz fws8fBM4BHyi7i25CYQl24tFq1CGax1rIPgLg+4KnH76bQk/N6Ju0sGVSzfh+hG8 SIerK9bJbzGRAuNKoxB3aO1dyzsK3x9WztE2mG98w5trOISPIR1FqnvC/225FWAU d6eIXiC7wKnEx+DElNTzCjzfHc7SAJoupO32H7CoiTe5zPUlWlxJ1zLYkK1gt50q m8PRBiYTglxyznzrO0drtcdjEzvbdZNRrsYnul4wi1vSHzjk6F6XLtzT10XWM1M1 1pXLB8384FTj0Hu4bq6Y3Aivkmz0Sf+eQM2NaOwe+Zj7/1VV0d3lvi4LUXkqzLCA FoXPJSMxG2Qu+iflCeYRQBJjExaZH3eNLZ3dT6QpcJrjaFVedd9u5DeeFqNL27zV bhr8TdqrR4p4rc8EBAGoCapw96IxLZROKB3gxbrZVOpfIZpzthwHbElHX6aqUgF4 w/EV1JWs36WXWaxFk8wd =ttq9 -----END PGP SIGNATURE----- Merge tag 'pci-v4.16-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci Pull PCI updates from Bjorn Helgaas: - skip AER driver error recovery callbacks for correctable errors reported via ACPI APEI, as we already do for errors reported via the native path (Tyler Baicar) - fix DPC shared interrupt handling (Alex Williamson) - print full DPC interrupt number (Keith Busch) - enable DPC only if AER is available (Keith Busch) - simplify DPC code (Bjorn Helgaas) - calculate ASPM L1 substate parameter instead of hardcoding it (Bjorn Helgaas) - enable Latency Tolerance Reporting for ASPM L1 substates (Bjorn Helgaas) - move ASPM internal interfaces out of public header (Bjorn Helgaas) - allow hot-removal of VGA devices (Mika Westerberg) - speed up unplug and shutdown by assuming Thunderbolt controllers don't support Command Completed events (Lukas Wunner) - add AtomicOps support for GPU and Infiniband drivers (Felix Kuehling, Jay Cornwall) - expose "ari_enabled" in sysfs to help NIC naming (Stuart Hayes) - clean up PCI DMA interface usage (Christoph Hellwig) - remove PCI pool API (replaced with DMA pool) (Romain Perier) - deprecate pci_get_bus_and_slot(), which assumed PCI domain 0 (Sinan Kaya) - move DT PCI code from drivers/of/ to drivers/pci/ (Rob Herring) - add PCI-specific wrappers for dev_info(), etc (Frederick Lawler) - remove warnings on sysfs mmap failure (Bjorn Helgaas) - quiet ROM validation messages (Alex Deucher) - remove redundant memory alloc failure messages (Markus Elfring) - fill in types for compile-time VGA and other I/O port resources (Bjorn Helgaas) - make "pci=pcie_scan_all" work for Root Ports as well as Downstream Ports to help AmigaOne X1000 (Bjorn Helgaas) - add SPDX tags to all PCI files (Bjorn Helgaas) - quirk Marvell 9128 DMA aliases (Alex Williamson) - quirk broken INTx disable on Ceton InfiniTV4 (Bjorn Helgaas) - fix CONFIG_PCI=n build by adding dummy pci_irqd_intx_xlate() (Niklas Cassel) - use DMA API to get MSI address for DesignWare IP (Niklas Cassel) - fix endpoint-mode DMA mask configuration (Kishon Vijay Abraham I) - fix ARTPEC-6 incorrect IS_ERR() usage (Wei Yongjun) - add support for ARTPEC-7 SoC (Niklas Cassel) - add endpoint-mode support for ARTPEC (Niklas Cassel) - add Cadence PCIe host and endpoint controller driver (Cyrille Pitchen) - handle multiple INTx status bits being set in dra7xx (Vignesh R) - translate dra7xx hwirq range to fix INTD handling (Vignesh R) - remove deprecated Exynos PHY initialization code (Jaehoon Chung) - fix MSI erratum workaround for HiSilicon Hip06/Hip07 (Dongdong Liu) - fix NULL pointer dereference in iProc BCMA driver (Ray Jui) - fix Keystone interrupt-controller-node lookup (Johan Hovold) - constify qcom driver structures (Julia Lawall) - rework Tegra config space mapping to increase space available for endpoints (Vidya Sagar) - simplify Tegra driver by using bus->sysdata (Manikanta Maddireddy) - remove PCI_REASSIGN_ALL_BUS usage on Tegra (Manikanta Maddireddy) - add support for Global Fabric Manager Server (GFMS) event to Microsemi Switchtec switch driver (Logan Gunthorpe) - add IDs for Switchtec PSX 24xG3 and PSX 48xG3 (Kelvin Cao) * tag 'pci-v4.16-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci: (140 commits) PCI: cadence: Add EndPoint Controller driver for Cadence PCIe controller dt-bindings: PCI: cadence: Add DT bindings for Cadence PCIe endpoint controller PCI: endpoint: Fix EPF device name to support multi-function devices PCI: endpoint: Add the function number as argument to EPC ops PCI: cadence: Add host driver for Cadence PCIe controller dt-bindings: PCI: cadence: Add DT bindings for Cadence PCIe host controller PCI: Add vendor ID for Cadence PCI: Add generic function to probe PCI host controllers PCI: generic: fix missing call of pci_free_resource_list() PCI: OF: Add generic function to parse and allocate PCI resources PCI: Regroup all PCI related entries into drivers/pci/Makefile PCI/DPC: Reformat DPC register definitions PCI/DPC: Add and use DPC Status register field definitions PCI/DPC: Squash dpc_rp_pio_get_info() into dpc_process_rp_pio_error() PCI/DPC: Remove unnecessary RP PIO register structs PCI/DPC: Push dpc->rp_pio_status assignment into dpc_rp_pio_get_info() PCI/DPC: Squash dpc_rp_pio_print_error() into dpc_rp_pio_get_info() PCI/DPC: Make RP PIO log size check more generic PCI/DPC: Rename local "status" to "dpc_status" PCI/DPC: Squash dpc_rp_pio_print_tlp_header() into dpc_rp_pio_print_error() ...
172 lines
4.2 KiB
C
172 lines
4.2 KiB
C
/*
|
|
* PCI bus setup for Marvell mv64360/mv64460 host bridges (Discovery)
|
|
*
|
|
* Author: Dale Farnsworth <dale@farnsworth.org>
|
|
*
|
|
* 2007 (c) MontaVista, Software, Inc. This file is licensed under
|
|
* the terms of the GNU General Public License version 2. This program
|
|
* is licensed "as is" without any warranty of any kind, whether express
|
|
* or implied.
|
|
*/
|
|
|
|
#include <linux/stddef.h>
|
|
#include <linux/kernel.h>
|
|
#include <linux/init.h>
|
|
#include <linux/stat.h>
|
|
#include <linux/pci.h>
|
|
|
|
#include <asm/prom.h>
|
|
#include <asm/pci-bridge.h>
|
|
|
|
#define PCI_HEADER_TYPE_INVALID 0x7f /* Invalid PCI header type */
|
|
|
|
#ifdef CONFIG_SYSFS
|
|
/* 32-bit hex or dec stringified number + '\n' */
|
|
#define MV64X60_VAL_LEN_MAX 11
|
|
#define MV64X60_PCICFG_CPCI_HOTSWAP 0x68
|
|
|
|
static ssize_t mv64x60_hs_reg_read(struct file *filp, struct kobject *kobj,
|
|
struct bin_attribute *attr, char *buf,
|
|
loff_t off, size_t count)
|
|
{
|
|
struct pci_dev *phb;
|
|
u32 v;
|
|
|
|
if (off > 0)
|
|
return 0;
|
|
if (count < MV64X60_VAL_LEN_MAX)
|
|
return -EINVAL;
|
|
|
|
phb = pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(0, 0));
|
|
if (!phb)
|
|
return -ENODEV;
|
|
pci_read_config_dword(phb, MV64X60_PCICFG_CPCI_HOTSWAP, &v);
|
|
pci_dev_put(phb);
|
|
|
|
return sprintf(buf, "0x%08x\n", v);
|
|
}
|
|
|
|
static ssize_t mv64x60_hs_reg_write(struct file *filp, struct kobject *kobj,
|
|
struct bin_attribute *attr, char *buf,
|
|
loff_t off, size_t count)
|
|
{
|
|
struct pci_dev *phb;
|
|
u32 v;
|
|
|
|
if (off > 0)
|
|
return 0;
|
|
if (count <= 0)
|
|
return -EINVAL;
|
|
|
|
if (sscanf(buf, "%i", &v) != 1)
|
|
return -EINVAL;
|
|
|
|
phb = pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(0, 0));
|
|
if (!phb)
|
|
return -ENODEV;
|
|
pci_write_config_dword(phb, MV64X60_PCICFG_CPCI_HOTSWAP, v);
|
|
pci_dev_put(phb);
|
|
|
|
return count;
|
|
}
|
|
|
|
static const struct bin_attribute mv64x60_hs_reg_attr = { /* Hotswap register */
|
|
.attr = {
|
|
.name = "hs_reg",
|
|
.mode = 0644,
|
|
},
|
|
.size = MV64X60_VAL_LEN_MAX,
|
|
.read = mv64x60_hs_reg_read,
|
|
.write = mv64x60_hs_reg_write,
|
|
};
|
|
|
|
static int __init mv64x60_sysfs_init(void)
|
|
{
|
|
struct device_node *np;
|
|
struct platform_device *pdev;
|
|
const unsigned int *prop;
|
|
|
|
np = of_find_compatible_node(NULL, NULL, "marvell,mv64360");
|
|
if (!np)
|
|
return 0;
|
|
|
|
prop = of_get_property(np, "hs_reg_valid", NULL);
|
|
of_node_put(np);
|
|
|
|
pdev = platform_device_register_simple("marvell,mv64360", 0, NULL, 0);
|
|
if (IS_ERR(pdev))
|
|
return PTR_ERR(pdev);
|
|
|
|
return sysfs_create_bin_file(&pdev->dev.kobj, &mv64x60_hs_reg_attr);
|
|
}
|
|
|
|
subsys_initcall(mv64x60_sysfs_init);
|
|
|
|
#endif /* CONFIG_SYSFS */
|
|
|
|
static void mv64x60_pci_fixup_early(struct pci_dev *dev)
|
|
{
|
|
/*
|
|
* Set the host bridge hdr_type to an invalid value so that
|
|
* pci_setup_device() will ignore the host bridge.
|
|
*/
|
|
dev->hdr_type = PCI_HEADER_TYPE_INVALID;
|
|
}
|
|
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_MARVELL, PCI_DEVICE_ID_MARVELL_MV64360,
|
|
mv64x60_pci_fixup_early);
|
|
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_MARVELL, PCI_DEVICE_ID_MARVELL_MV64460,
|
|
mv64x60_pci_fixup_early);
|
|
|
|
static int __init mv64x60_add_bridge(struct device_node *dev)
|
|
{
|
|
int len;
|
|
struct pci_controller *hose;
|
|
struct resource rsrc;
|
|
const int *bus_range;
|
|
int primary;
|
|
|
|
memset(&rsrc, 0, sizeof(rsrc));
|
|
|
|
/* Fetch host bridge registers address */
|
|
if (of_address_to_resource(dev, 0, &rsrc)) {
|
|
printk(KERN_ERR "No PCI reg property in device tree\n");
|
|
return -ENODEV;
|
|
}
|
|
|
|
/* Get bus range if any */
|
|
bus_range = of_get_property(dev, "bus-range", &len);
|
|
if (bus_range == NULL || len < 2 * sizeof(int))
|
|
printk(KERN_WARNING "Can't get bus-range for %pOF, assume"
|
|
" bus 0\n", dev);
|
|
|
|
hose = pcibios_alloc_controller(dev);
|
|
if (!hose)
|
|
return -ENOMEM;
|
|
|
|
hose->first_busno = bus_range ? bus_range[0] : 0;
|
|
hose->last_busno = bus_range ? bus_range[1] : 0xff;
|
|
|
|
setup_indirect_pci(hose, rsrc.start, rsrc.start + 4, 0);
|
|
hose->self_busno = hose->first_busno;
|
|
|
|
printk(KERN_INFO "Found MV64x60 PCI host bridge at 0x%016llx. "
|
|
"Firmware bus number: %d->%d\n",
|
|
(unsigned long long)rsrc.start, hose->first_busno,
|
|
hose->last_busno);
|
|
|
|
/* Interpret the "ranges" property */
|
|
/* This also maps the I/O region and sets isa_io/mem_base */
|
|
primary = (hose->first_busno == 0);
|
|
pci_process_bridge_OF_ranges(hose, dev, primary);
|
|
|
|
return 0;
|
|
}
|
|
|
|
void __init mv64x60_pci_init(void)
|
|
{
|
|
struct device_node *np;
|
|
|
|
for_each_compatible_node(np, "pci", "marvell,mv64360-pci")
|
|
mv64x60_add_bridge(np);
|
|
}
|