--- /dev/null
+CONFIG_64BIT=y
+CONFIG_64BIT_TIME=y
+# CONFIG_ADIN_PHY is not set
+# CONFIG_AL_FIC is not set
+CONFIG_ARCH_DMA_ADDR_T_64BIT=y
+CONFIG_ARCH_HAS_BINFMT_FLAT=y
+CONFIG_ARCH_HAS_ELF_RANDOMIZE=y
+CONFIG_ARCH_HAS_GIGANTIC_PAGE=y
+CONFIG_ARCH_HAS_MMIOWB=y
+CONFIG_ARCH_HAS_PTE_SPECIAL=y
+CONFIG_ARCH_MMAP_RND_BITS=18
+CONFIG_ARCH_MMAP_RND_BITS_MAX=24
+CONFIG_ARCH_MMAP_RND_BITS_MIN=18
+# CONFIG_ARCH_RV32I is not set
+CONFIG_ARCH_RV64I=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_SUPPORTS_INT128=y
+CONFIG_ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT=y
+CONFIG_ARCH_WANT_FRAME_POINTERS=y
+CONFIG_ARCH_WANT_GENERAL_HUGETLB=y
+CONFIG_ARCH_WANT_HUGE_PMD_SHARE=y
+CONFIG_ASN1=y
+CONFIG_ASSOCIATIVE_ARRAY=y
+CONFIG_ASYMMETRIC_KEY_TYPE=y
+CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=y
+CONFIG_ATA=y
+CONFIG_ATA_VERBOSE_ERROR=y
+# CONFIG_BACKLIGHT_CLASS_DEVICE is not set
+CONFIG_BLK_DEV_SD=y
+CONFIG_BLK_MQ_PCI=y
+CONFIG_BLK_MQ_VIRTIO=y
+CONFIG_BLK_SCSI_REQUEST=y
+CONFIG_CAVIUM_PTP=y
+CONFIG_CC_CAN_LINK=y
+CONFIG_CC_HAS_ASM_INLINE=y
+CONFIG_CC_HAS_KASAN_GENERIC=y
+CONFIG_CC_HAS_WARN_MAYBE_UNINITIALIZED=y
+CONFIG_CLKDEV_LOOKUP=y
+CONFIG_CLK_ANALOGBITS_WRPLL_CLN28HPC=y
+CONFIG_CLK_GEMGXL_MGMT=y
+CONFIG_CLK_SIFIVE=y
+CONFIG_CLK_SIFIVE_FU540_PRCI=y
+CONFIG_CLK_U54_PRCI=y
+CONFIG_CLONE_BACKWARDS=y
+CONFIG_CLZ_TAB=y
+CONFIG_CMDLINE="earlyprintk root=/dev/mmcblk0p2 rootwait console=ttySI0"
+CONFIG_CMDLINE_FALLBACK=y
+CONFIG_CMODEL_MEDANY=y
+# CONFIG_CMODEL_MEDLOW is not set
+CONFIG_COMMON_CLK=y
+# CONFIG_COMMON_CLK_FIXED_MMIO is not set
+# CONFIG_COMMON_CLK_SI5341 is not set
+CONFIG_COMPAT_BRK=y
+CONFIG_COREDUMP=y
+CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
+# CONFIG_COUNTER is not set
+CONFIG_CPU_ISOLATION=y
+CONFIG_CPU_RMAP=y
+CONFIG_CRC16=y
+# CONFIG_CRC32_SARWATE is not set
+CONFIG_CRC32_SLICEBY8=y
+CONFIG_CRC7=y
+CONFIG_CRC_ITU_T=y
+CONFIG_CRYPTO_ACOMP2=y
+# CONFIG_CRYPTO_ADIANTUM is not set
+CONFIG_CRYPTO_AEAD=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_AKCIPHER=y
+CONFIG_CRYPTO_AKCIPHER2=y
+CONFIG_CRYPTO_CRC32C=y
+CONFIG_CRYPTO_DRBG=y
+CONFIG_CRYPTO_DRBG_HMAC=y
+CONFIG_CRYPTO_DRBG_MENU=y
+CONFIG_CRYPTO_ECHAINIV=y
+# CONFIG_CRYPTO_ECRDSA is not set
+# CONFIG_CRYPTO_ESSIV is not set
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_HASH_INFO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_JITTERENTROPY=y
+CONFIG_CRYPTO_KPP2=y
+CONFIG_CRYPTO_LIB_AES=y
+CONFIG_CRYPTO_LIB_SHA256=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+CONFIG_CRYPTO_NULL=y
+CONFIG_CRYPTO_NULL2=y
+# CONFIG_CRYPTO_OFB is not set
+CONFIG_CRYPTO_RNG=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_RNG_DEFAULT=y
+CONFIG_CRYPTO_RSA=y
+CONFIG_CRYPTO_SHA256=y
+# CONFIG_CRYPTO_STREEBOG is not set
+# CONFIG_CRYPTO_XXHASH is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_FS is not set
+CONFIG_DEBUG_MISC=y
+# CONFIG_DEBUG_PLIST is not set
+CONFIG_DEBUG_SECTION_MISMATCH=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DEVMEM=y
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_DMA_DECLARE_COHERENT=y
+CONFIG_DNOTIFY=y
+CONFIG_DTC=y
+CONFIG_E1000E=y
+CONFIG_EDAC_SUPPORT=y
+# CONFIG_EEPROM_EE1004 is not set
+CONFIG_ELF_CORE=y
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_EXFAT_FS is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+CONFIG_EXT4_FS=y
+CONFIG_FAILOVER=y
+CONFIG_FHANDLE=y
+# CONFIG_FIELDBUS_DEV is not set
+CONFIG_FIXED_PHY=y
+CONFIG_FIX_EARLYCON_MEM=y
+CONFIG_FPU=y
+CONFIG_FRAME_POINTER=y
+CONFIG_FRAME_WARN=2048
+CONFIG_FS_IOMAP=y
+CONFIG_FS_MBCACHE=y
+# CONFIG_FS_VERITY is not set
+# CONFIG_FW_LOADER_COMPRESS is not set
+CONFIG_FW_LOADER_PAGED_BUF=y
+CONFIG_GENERIC_ALLOCATOR=y
+CONFIG_GENERIC_ARCH_TOPOLOGY=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CPU_DEVICES=y
+CONFIG_GENERIC_CSUM=y
+CONFIG_GENERIC_IRQ_MULTI_HANDLER=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_GENERIC_MSI_IRQ=y
+CONFIG_GENERIC_MSI_IRQ_DOMAIN=y
+CONFIG_GENERIC_PCI_IOMAP=y
+CONFIG_GENERIC_SCHED_CLOCK=y
+CONFIG_GENERIC_SMP_IDLE_THREAD=y
+CONFIG_GENERIC_STRNCPY_FROM_USER=y
+CONFIG_GENERIC_STRNLEN_USER=y
+CONFIG_GLOB=y
+CONFIG_GPIOLIB=y
+# CONFIG_GPIO_AMD_FCH is not set
+# CONFIG_GPIO_CADENCE is not set
+# CONFIG_GPIO_GW_PLD is not set
+# CONFIG_GVE is not set
+# CONFIG_HABANA_AI is not set
+CONFIG_HAS_DMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT_MAP=y
+CONFIG_HAVE_ARCH_AUDITSYSCALL=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_ASM_MODVERSIONS=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_CLK_PREPARE=y
+CONFIG_HAVE_COPY_THREAD_TLS=y
+CONFIG_HAVE_DMA_CONTIGUOUS=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS=y
+CONFIG_HAVE_EBPF_JIT=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUTEX_CMPXCHG=y
+CONFIG_HAVE_MEMBLOCK_NODE_MAP=y
+CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
+CONFIG_HAVE_NET_DSA=y
+CONFIG_HAVE_PCI=y
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_HAVE_PERF_REGS=y
+CONFIG_HAVE_PERF_USER_STACK_DUMP=y
+CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
+CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y
+# CONFIG_HEADERS_INSTALL is not set
+# CONFIG_HEADER_TEST is not set
+CONFIG_HID=y
+# CONFIG_HID_CREATIVE_SB0540 is not set
+CONFIG_HID_GENERIC=y
+# CONFIG_HID_MACALLY is not set
+# CONFIG_HID_MALTRON is not set
+# CONFIG_HID_VIEWSONIC is not set
+# CONFIG_HUGETLBFS is not set
+CONFIG_HVC_DRIVER=y
+# CONFIG_HVC_RISCV_SBI is not set
+CONFIG_HZ_PERIODIC=y
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
+CONFIG_I2C_HELPER_AUTO=y
+# CONFIG_I2C_NVIDIA_GPU is not set
+CONFIG_I2C_OCORES=y
+# CONFIG_I3C is not set
+# CONFIG_IGC is not set
+# CONFIG_IKHEADERS is not set
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_INIT_ON_ALLOC_DEFAULT_ON is not set
+# CONFIG_INIT_ON_FREE_DEFAULT_ON is not set
+CONFIG_INIT_STACK_NONE=y
+CONFIG_INPUT=y
+# CONFIG_INPUT_GPIO_VIBRA is not set
+# CONFIG_INPUT_MSM_VIBRATOR is not set
+# CONFIG_INTERCONNECT is not set
+# CONFIG_IONIC is not set
+CONFIG_IO_URING=y
+CONFIG_IRQCHIP=y
+CONFIG_IRQ_DOMAIN=y
+CONFIG_IRQ_DOMAIN_HIERARCHY=y
+CONFIG_IRQ_WORK=y
+CONFIG_JBD2=y
+CONFIG_KALLSYMS=y
+CONFIG_KASAN_STACK=1
+CONFIG_KEYS=y
+# CONFIG_KEYS_REQUEST_CACHE is not set
+# CONFIG_LCD_CLASS_DEVICE is not set
+# CONFIG_LEDS_AN30259A is not set
+# CONFIG_LEDS_LM3532 is not set
+# CONFIG_LEDS_TRIGGER_AUDIO is not set
+# CONFIG_LEDS_TRIGGER_PATTERN is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+CONFIG_LIBFDT=y
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_LSM="lockdown,yama,loadpin,safesetid,integrity"
+CONFIG_MACB=y
+# CONFIG_MACB_PCI is not set
+CONFIG_MACB_USE_HWSTAMP=y
+CONFIG_MANDATORY_FILE_LOCKING=y
+CONFIG_MAXPHYSMEM_128GB=y
+# CONFIG_MAXPHYSMEM_2GB is not set
+CONFIG_MDIO_BUS=y
+# CONFIG_MDIO_BUS_MUX_MULTIPLEXER is not set
+CONFIG_MDIO_DEVICE=y
+CONFIG_MEMFD_CREATE=y
+# CONFIG_MFD_LOCHNAGAR is not set
+# CONFIG_MFD_MAX77650 is not set
+# CONFIG_MFD_ROHM_BD70528 is not set
+# CONFIG_MFD_STMFX is not set
+# CONFIG_MFD_STPMIC1 is not set
+# CONFIG_MFD_TQMX86 is not set
+CONFIG_MICROSEMI_PHY=y
+CONFIG_MIGRATION=y
+# CONFIG_MISC_ALCOR_PCI is not set
+CONFIG_MMC=y
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_SPI=y
+# CONFIG_MMC_TIFM_SD is not set
+CONFIG_MMIOWB=y
+CONFIG_MODULES_USE_ELF_RELA=y
+# CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS is not set
+CONFIG_MODULE_SECTIONS=y
+CONFIG_MPILIB=y
+CONFIG_MQ_IOSCHED_DEADLINE=y
+CONFIG_MQ_IOSCHED_KYBER=y
+# CONFIG_MTD_HYPERBUS is not set
+# CONFIG_MTD_RAW_NAND is not set
+CONFIG_MTD_SPI_NOR=y
+CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y
+CONFIG_NAMESPACES=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_NET_FAILOVER=y
+CONFIG_NET_FLOW_LIMIT=y
+CONFIG_NET_NS=y
+CONFIG_NET_PTP_CLASSIFY=y
+# CONFIG_NET_SCH_TAPRIO is not set
+CONFIG_NET_VENDOR_GOOGLE=y
+CONFIG_NET_VENDOR_PENSANDO=y
+# CONFIG_NI_XGE_MANAGEMENT_ENET is not set
+CONFIG_NLS=y
+CONFIG_NR_CPUS=8
+# CONFIG_NULL_TTY is not set
+CONFIG_NVMEM=y
+CONFIG_NVMEM_SYSFS=y
+CONFIG_OF=y
+CONFIG_OF_ADDRESS=y
+CONFIG_OF_EARLY_FLATTREE=y
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_GPIO=y
+CONFIG_OF_IRQ=y
+CONFIG_OF_KOBJ=y
+CONFIG_OF_MDIO=y
+CONFIG_OF_NET=y
+CONFIG_OF_RESERVED_MEM=y
+CONFIG_OID_REGISTRY=y
+# CONFIG_PACKING is not set
+CONFIG_PADATA=y
+CONFIG_PAGE_OFFSET=0xffffffe000000000
+CONFIG_PANIC_TIMEOUT=0
+CONFIG_PA_BITS=56
+CONFIG_PCI=y
+CONFIG_PCIE_MICROSEMI=y
+CONFIG_PCI_DEBUG=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_DOMAINS_GENERIC=y
+# CONFIG_PCI_MESON is not set
+CONFIG_PCI_MSI=y
+CONFIG_PCI_MSI_IRQ_DOMAIN=y
+CONFIG_PGTABLE_LEVELS=3
+CONFIG_PHYLIB=y
+CONFIG_PHYS_ADDR_T_64BIT=y
+# CONFIG_PHY_CADENCE_DP is not set
+# CONFIG_PHY_CADENCE_DPHY is not set
+# CONFIG_PHY_FSL_IMX8MQ_USB is not set
+# CONFIG_PHY_MIXEL_MIPI_DPHY is not set
+CONFIG_PID_NS=y
+CONFIG_PKCS7_MESSAGE_PARSER=y
+# CONFIG_PKCS8_PRIVATE_KEY_PARSER is not set
+CONFIG_PPS=y
+# CONFIG_PRINTK_CALLER is not set
+CONFIG_PRINTK_TIME=y
+# CONFIG_PSI is not set
+CONFIG_PTP_1588_CLOCK=y
+# CONFIG_PVPANIC is not set
+CONFIG_PWM=y
+# CONFIG_PWM_SIFIVE is not set
+CONFIG_PWM_SYSFS=y
+CONFIG_R8169=y
+# CONFIG_RANDOM_TRUST_BOOTLOADER is not set
+CONFIG_RATIONAL=y
+CONFIG_RCU_NEED_SEGCBLIST=y
+CONFIG_RCU_STALL_COMMON=y
+CONFIG_RCU_TRACE=y
+CONFIG_RD_GZIP=y
+CONFIG_REALTEK_PHY=y
+# CONFIG_REED_SOLOMON_TEST is not set
+CONFIG_REGMAP=y
+CONFIG_REGMAP_I2C=y
+CONFIG_REGMAP_SPI=y
+CONFIG_RFS_ACCEL=y
+CONFIG_RISCV=y
+CONFIG_RISCV_ISA_C=y
+CONFIG_RISCV_TIMER=y
+CONFIG_RPS=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_I2C_AND_SPI=y
+CONFIG_SATA_AHCI=y
+CONFIG_SATA_PMP=y
+CONFIG_SATA_SIL24=y
+CONFIG_SCHED_DEBUG=y
+CONFIG_SCSI=y
+# CONFIG_SCSI_MYRS is not set
+CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+# CONFIG_SERIAL_EARLYCON_RISCV_SBI is not set
+# CONFIG_SERIAL_FSL_LINFLEXUART is not set
+CONFIG_SERIAL_MCTRL_GPIO=y
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_SERIAL_SIFIVE=y
+CONFIG_SERIAL_SIFIVE_CONSOLE=y
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+CONFIG_SGL_ALLOC=y
+CONFIG_SG_POOL=y
+# CONFIG_SHUFFLE_PAGE_ALLOCATOR is not set
+CONFIG_SIFIVE_PLIC=y
+CONFIG_SLUB_DEBUG=y
+CONFIG_SMP=y
+CONFIG_SOC_SIFIVE=y
+CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
+CONFIG_SPARSE_IRQ=y
+CONFIG_SPI=y
+CONFIG_SPI_BITBANG=y
+CONFIG_SPI_MASTER=y
+CONFIG_SPI_MEM=y
+# CONFIG_SPI_MTK_QUADSPI is not set
+CONFIG_SPI_SIFIVE=y
+CONFIG_SRCU=y
+CONFIG_STACKTRACE=y
+CONFIG_SWIOTLB=y
+CONFIG_SWPHY=y
+CONFIG_SYSCTL_EXCEPTION_TRACE=y
+CONFIG_SYSFS_SYSCALL=y
+CONFIG_SYS_SUPPORTS_HUGETLBFS=y
+# CONFIG_TEST_BLACKHOLE_DEV is not set
+# CONFIG_TEST_MEMCAT_P is not set
+# CONFIG_TEST_MEMINIT is not set
+# CONFIG_TEST_STACKINIT is not set
+# CONFIG_TEST_STRSCPY is not set
+# CONFIG_TEST_VMALLOC is not set
+# CONFIG_TEST_XARRAY is not set
+CONFIG_THREAD_INFO_IN_TASK=y
+CONFIG_TICK_CPU_ACCOUNTING=y
+CONFIG_TIMER_OF=y
+CONFIG_TIMER_PROBE=y
+# CONFIG_TI_CPSW_PHY_SEL is not set
+CONFIG_TRACE_CLOCK=y
+CONFIG_TREE_RCU=y
+CONFIG_TREE_SRCU=y
+CONFIG_TUNE_GENERIC=y
+CONFIG_UBSAN_ALIGNMENT=y
+CONFIG_UEVENT_HELPER_PATH=""
+# CONFIG_UNICODE is not set
+CONFIG_UNIX_SCM=y
+CONFIG_USB=y
+CONFIG_USB_COMMON=y
+# CONFIG_USB_CONN_GPIO is not set
+# CONFIG_USB_EHCI_FSL is not set
+CONFIG_USB_EHCI_HCD=y
+# CONFIG_USB_EHCI_HCD_PLATFORM is not set
+CONFIG_USB_EHCI_PCI=y
+CONFIG_USB_HID=y
+CONFIG_USB_NET_DRIVERS=y
+CONFIG_USB_PCI=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_SUPPORT=y
+# CONFIG_USB_UHCI_HCD is not set
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_XHCI_PCI=y
+# CONFIG_USB_XHCI_PLATFORM is not set
+# CONFIG_USERIO is not set
+# CONFIG_USER_NS is not set
+CONFIG_UTS_NS=y
+# CONFIG_VALIDATE_FS_PARSER is not set
+CONFIG_VA_BITS=39
+CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
+CONFIG_VIRTIO=y
+CONFIG_VIRTIO_BLK=y
+CONFIG_VIRTIO_CONSOLE=y
+CONFIG_VIRTIO_MMIO=y
+# CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES is not set
+CONFIG_VIRTIO_NET=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_WATCHDOG_OPEN_TIMEOUT=0
+CONFIG_X509_CERTIFICATE_PARSER=y
+# CONFIG_XILINX_SDFEC is not set
+CONFIG_XPS=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZONE_DMA32=y
--- /dev/null
+From 1fd6c8fbc07bec3c18771738ce4b2aad3ed228f2 Mon Sep 17 00:00:00 2001
+Date: Wed, 25 Apr 2018 12:10:15 -0700
+Subject: [PATCH 10/11] pcie-microsemi: added support for the Vera-board root
+ complex
+
+---
+ drivers/pci/controller/Kconfig | 6 +
+ drivers/pci/controller/Makefile | 1 +
+ drivers/pci/controller/pcie-microsemi.c | 754 ++++++++++++++++++++++++++++++++
+ 3 files changed, 761 insertions(+)
+ create mode 100644 drivers/pci/controller/pcie-microsemi.c
+
+diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig
+index 028b2874..4458c119 100644
+--- a/drivers/pci/controller/Kconfig
++++ b/drivers/pci/controller/Kconfig
+@@ -278,5 +278,11 @@ config VMD
+ To compile this driver as a module, choose M here: the
+ module will be called vmd.
+
++config PCIE_MICROSEMI
++ bool "Microsemi AXI PCIe host bridge support"
++ depends on OF || COMPILE_TEST
++ help
++ Say 'Y' here if you want kernel to support the Microsemi AXI PCIe
++ Host Bridge driver.
+ source "drivers/pci/controller/dwc/Kconfig"
+ endmenu
+diff --git a/drivers/pci/controller/Makefile b/drivers/pci/controller/Makefile
+index d56a5074..c3b76ff2 100644
+--- a/drivers/pci/controller/Makefile
++++ b/drivers/pci/controller/Makefile
+@@ -28,6 +28,7 @@ obj-$(CONFIG_PCIE_ROCKCHIP_HOST) += pcie-rockchip-host.o
+ obj-$(CONFIG_PCIE_MEDIATEK) += pcie-mediatek.o
+ obj-$(CONFIG_PCIE_MOBIVEIL) += pcie-mobiveil.o
+ obj-$(CONFIG_PCIE_TANGO_SMP8759) += pcie-tango.o
++obj-$(CONFIG_PCIE_MICROSEMI) += pcie-microsemi.o
+ obj-$(CONFIG_VMD) += vmd.o
+ # pcie-hisi.o quirks are needed even without CONFIG_PCIE_DW
+ obj-y += dwc/
+diff --git a/drivers/pci/controller/pcie-microsemi.c b/drivers/pci/controller/pcie-microsemi.c
+new file mode 100644
+index 00000000..9e2abca2
+--- /dev/null
++++ b/drivers/pci/controller/pcie-microsemi.c
+@@ -0,0 +1,754 @@
++/*
++ * PCIe host controller driver for Microsemi AXI PCIe Bridge
++ *
++ * Copyright (c) 2018 - Microsemi.
++ *
++ * Based on the Xilinx, Altera PCIe driver
++ *
++ *
++ * This program is free software: you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation, either version 2 of the License, or
++ * (at your option) any later version.
++ */
++
++#include <linux/interrupt.h>
++#include <linux/irq.h>
++#include <linux/irqdomain.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/msi.h>
++#include <linux/of_address.h>
++#include <linux/of_pci.h>
++#include <linux/of_platform.h>
++#include <linux/of_irq.h>
++#include <linux/pci.h>
++#include <linux/platform_device.h>
++#include "../pci.h"
++
++/* ECAM definitions */
++#define ECAM_BUS_NUM_SHIFT 20
++#define ECAM_DEV_NUM_SHIFT 12
++
++/* Number of MSI IRQs */
++#define MICROSEMI_NUM_MSI_IRQS 32
++
++/* PCIe Bridge Phy and Controller Phy offsets */
++#define PCIE0_BRIDGE_PHY_ADDR_OFFSET 0x03004000u
++#define PCIE0_CRTL_PHY_ADDR_OFFSET 0x03006000u
++
++#define PCIE0_BRIDGE_ADDR 0x03004000u
++#define PCIE0_CRTL_ADDR 0x03006000u
++
++#define PCIE1_BRIDGE_ADDR 0x00008000u
++#define PCIE1_CRTL_ADDR 0x0000A000u
++
++/* PCIe LTSSM State reg */
++#define LTSSM_STATE 0x5c
++
++/* PCIe LTSSM L0 state */
++#define LTSSM_L0_STATE 0x10
++
++/* PCIe Controller Phy Regs */
++#define SEC_ERROR_INT 0x28
++#define SEC_ERROR_INT_MASK 0x2c
++#define DED_ERROR_INT 0x30
++#define DED_ERROR_INT_MASK 0x34
++#define ECC_CONTROL 0x38
++#define PCIE_EVENT_INT 0x14c
++
++/* PCIe Bridge Phy Regs */
++#define IMASK_LOCAL 0x180
++#define ISTATUS_LOCAL 0x184
++#define IMASK_HOST 0x188
++#define ISTATUS_HOST 0x18c
++#define ISTATUS_MSI 0x194
++#define PCIE_PCI_IDS_DW1 0x9c
++
++/* PCIe AXI slave table init defines */
++#define ATR0_AXI4_SLV0_SRCADDR_PARAM 0x800u
++#define ATR0_AXI4_SLV0_SRC_ADDR 0x804u
++#define ATR0_AXI4_SLV0_TRSL_ADDR_LSB 0x808u
++#define ATR0_AXI4_SLV0_TRSL_ADDR_UDW 0x80cu
++#define ATR0_AXI4_SLV0_TRSL_PARAM 0x810u
++
++#define ATR1_AXI4_SLV0_SRCADDR_PARAM 0x820u
++#define ATR1_AXI4_SLV0_SRC_ADDR 0x824u
++#define ATR1_AXI4_SLV0_TRSL_ADDR_LSB 0x828u
++#define ATR1_AXI4_SLV0_TRSL_ADDR_UDW 0x82cu
++#define ATR1_AXI4_SLV0_TRSL_PARAM 0x830u
++
++/* PCIe Master table init defines */
++#define ATR0_PCIE_WIN0_SRCADDR_PARAM 0x600u
++
++/* Translated ID */
++#define PCIE_TX_RX_INTERFACE 0x00000000u
++#define PCIE_CONFIG_INTERFACE 0x00000001u
++
++/* PCIe Config space MSI capability structure */
++#define PCIE_ENABLE_MSI 0x10000000u
++
++/* MSI definitions */
++#define MSI_MSG_ADDR 0x190u
++#define MSI_ENABLE (0x01u << 16)
++#define MSI_ENABLE_MULTI (MICROSEMI_NUM_MSI_IRQS << 20)
++
++/* MSI Capability Structure */
++#define MSI_CAP_CTRL 0xE0u
++#define MSI_MSG_ADDR_OFFSET 0xE4u
++#define MSI_MSG_UPPER_ADDR_OFFEST 0xE8u
++#define MSI_MSG_DATA 0xF0u
++
++
++
++/******************************************************************************/
++/*Enable PCIe local*/
++#define PCIE_LOCAL_INT_ENABLE 0xF000000u
++
++/******************************************************************************/
++/* Clear PCIe interrupt events */
++#define PCIE_EVENT_INT_DATA 0x00070007u
++#define PCIE_ECC_DISABLE 0x0F000000u
++#define PCIE_SEC_ERROR_INT_CLEAR 0x0000FFFFu
++#define PCIE_DED_ERROR_INT_CLEAR 0x0000FFFFu
++#define PCIE_ISTATUS_CLEAR 0xFFFFFFFFu
++#define PCIE_CLEAR 0x00000000u
++#define PCIE_SET 0x00000001u
++
++#define ROOT_PORT_ENABLE 0x00000001u
++
++#define NULL_POINTER 0x00000000u
++
++/*****************************************************************************/
++/* PCIe Controller 0 */
++#define PF_PCIE_CTRL_0 0u
++/* PCIe Controller 1 */
++#define PF_PCIE_CTRL_1 1u
++
++/* It indicates that the ATR table is enabled */
++#define PF_PCIE_ATR_TABLE_ENABLE 1u
++/* It indicates that the the ATR table is disabled */
++#define PF_PCIE_ATR_TABLE_DISABLE 0u
++
++
++/**
++ * struct microsemi_pcie_port - PCIe port information
++ * @reg_base: IO Mapped Register Base
++ * @irq: Interrupt number
++ * @root_busno: Root Bus number
++ * @dev: Device pointer
++ * @msi_domain: MSI IRQ domain pointer
++ * @leg_domain: Legacy IRQ domain pointer
++ * @resources: Bus Resources
++ */
++struct microsemi_pcie_port {
++ struct platform_device *pdev;
++ void __iomem *reg_base;
++ void __iomem *reg_base_apb;
++ void __iomem *reg_bridge_apb;
++ void __iomem *reg_ctrl_apb;
++ u32 irq;
++ u8 root_busno;
++ struct device *dev;
++ struct irq_domain *msi_domain;
++ struct irq_domain *leg_domain;
++ struct list_head resources;
++};
++
++static DECLARE_BITMAP(msi_irq_in_use, MICROSEMI_NUM_MSI_IRQS);
++
++static inline u32 pcie_read(struct microsemi_pcie_port *port, u32 reg)
++{
++ return readl(port->reg_base + reg);
++}
++
++static inline void pcie_write(struct microsemi_pcie_port *port,
++ u32 val, u32 reg)
++{
++ writel(val, port->reg_base + reg);
++}
++
++static inline bool microsemi_pcie_link_up(struct microsemi_pcie_port *port)
++{
++ return (readl(port->reg_ctrl_apb + LTSSM_STATE)
++ & LTSSM_L0_STATE) ? 1 : 0;
++}
++
++/**
++ * microsemi_pcie_valid_device - Check if a valid device is present on bus
++ * @bus: PCI Bus structure
++ * @devfn: device/function
++ *
++ * Return: 'true' on success and 'false' if invalid device is found
++ */
++static bool microsemi_pcie_valid_device(struct pci_bus *bus, unsigned int devfn)
++{
++ struct microsemi_pcie_port *port = bus->sysdata;
++
++ /* Check if link is up when trying to access downstream ports */
++ if (bus->number != port->root_busno)
++ if (!microsemi_pcie_link_up(port))
++ return false;
++
++ /* Only one device down on each root port */
++ if (bus->number == port->root_busno && devfn > 0)
++ return false;
++
++ return true;
++}
++
++/**
++ * microsemi_pcie_map_bus - Get configuration base
++ * @bus: PCI Bus structure
++ * @devfn: Device/function
++ * @where: Offset from base
++ *
++ * Return: Base address of the configuration space needed to be
++ * accessed.
++ */
++static void __iomem *microsemi_pcie_map_bus(struct pci_bus *bus,
++ unsigned int devfn, int where)
++{
++ struct microsemi_pcie_port *port = bus->sysdata;
++ int relbus;
++
++
++ if (!microsemi_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;
++}
++
++/* PCIe operations */
++static struct pci_ops microsemi_pcie_ops = {
++ .map_bus = microsemi_pcie_map_bus,
++ .read = pci_generic_config_read,
++ .write = pci_generic_config_write,
++};
++
++/* MSI functions */
++
++/**
++ * microsemi_pcie_destroy_msi - Free MSI number
++ * @irq: IRQ to be freed
++ */
++static void microsemi_pcie_destroy_msi(unsigned int irq)
++{
++ struct msi_desc *msi;
++ struct microsemi_pcie_port *port;
++ struct irq_data *d = irq_get_irq_data(irq);
++ irq_hw_number_t hwirq = irqd_to_hwirq(d);
++
++ if (!test_bit(hwirq, msi_irq_in_use)) {
++ msi = irq_get_msi_desc(irq);
++ port = msi_desc_to_pci_sysdata(msi);
++ dev_err(port->dev, "Trying to free unused MSI#%d\n", irq);
++ } else {
++ clear_bit(hwirq, msi_irq_in_use);
++ }
++}
++
++/**
++ * microsemi_pcie_assign_msi - Allocate MSI number
++ *
++ * Return: A valid IRQ on success and error value on failure.
++ */
++static int microsemi_pcie_assign_msi(void)
++{
++ int pos;
++
++ pos = find_first_zero_bit(msi_irq_in_use, MICROSEMI_NUM_MSI_IRQS);
++ if (pos < MICROSEMI_NUM_MSI_IRQS)
++ set_bit(pos, msi_irq_in_use);
++ else
++ return -ENOSPC;
++
++ return pos;
++}
++
++/**
++ * microsemi_msi_teardown_irq - Destroy the MSI
++ * @chip: MSI Chip descriptor
++ * @irq: MSI IRQ to destroy
++ */
++static void microsemi_msi_teardown_irq(struct msi_controller *chip,
++ unsigned int irq)
++{
++ microsemi_pcie_destroy_msi(irq);
++ irq_dispose_mapping(irq);
++}
++
++/**
++ * microsemi_pcie_msi_setup_irq - Setup MSI request
++ * @chip: MSI chip pointer
++ * @pdev: PCIe device pointer
++ * @desc: MSI descriptor pointer
++ *
++ * Return: '0' on success and error value on failure
++ */
++static int microsemi_pcie_msi_setup_irq(struct msi_controller *chip,
++ struct pci_dev *pdev,
++ struct msi_desc *desc)
++{
++ struct microsemi_pcie_port *port = pdev->bus->sysdata;
++ unsigned int irq;
++ int hwirq;
++ struct msi_msg msg;
++
++ hwirq = microsemi_pcie_assign_msi();
++ if (hwirq < 0)
++ return hwirq;
++
++ irq = irq_create_mapping(port->msi_domain, hwirq);
++ if (!irq)
++ return -EINVAL;
++
++ irq_set_msi_desc(irq, desc);
++
++ msg.address_hi = 0;
++ msg.address_lo = MSI_MSG_ADDR;
++ msg.data = hwirq;
++
++ pci_write_msi_msg(irq, &msg);
++
++ return 0;
++}
++
++/* MSI Chip Descriptor */
++static struct msi_controller microsemi_pcie_msi_chip = {
++ .setup_irq = microsemi_pcie_msi_setup_irq,
++ .teardown_irq = microsemi_msi_teardown_irq,
++};
++
++/* HW Interrupt Chip Descriptor */
++static struct irq_chip microsemi_msi_irq_chip = {
++ .name = "Microsemi PCIe MSI",
++ .irq_enable = pci_msi_unmask_irq,
++ .irq_disable = pci_msi_mask_irq,
++ .irq_mask = pci_msi_mask_irq,
++ .irq_unmask = pci_msi_unmask_irq,
++};
++
++/**
++ * microsemi_pcie_msi_map - Set the handler for the MSI and mark IRQ as valid
++ * @domain: IRQ domain
++ * @irq: Virtual IRQ number
++ * @hwirq: HW interrupt number
++ *
++ * Return: Always returns 0.
++ */
++static int microsemi_pcie_msi_map(struct irq_domain *domain, unsigned int irq,
++ irq_hw_number_t hwirq)
++{
++ irq_set_chip_and_handler(irq,
++ µsemi_msi_irq_chip, handle_simple_irq);
++ irq_set_chip_data(irq, domain->host_data);
++
++ return 0;
++}
++
++/* IRQ Domain operations */
++static const struct irq_domain_ops msi_domain_ops = {
++ .map = microsemi_pcie_msi_map,
++};
++
++/**
++ * microsemi_pcie_enable_msi - Enable MSI support
++ * @port: PCIe port information
++ */
++static void microsemi_pcie_enable_msi(struct microsemi_pcie_port *port)
++{
++ u32 cap_ctrl;
++
++ cap_ctrl = pcie_read(port, MSI_CAP_CTRL);
++
++ pcie_write(port, cap_ctrl | MSI_ENABLE_MULTI | MSI_ENABLE, MSI_CAP_CTRL);
++ pcie_write(port, MSI_MSG_ADDR, MSI_MSG_ADDR_OFFSET);
++}
++
++/* INTx Functions */
++
++/**
++ * microsemi_pcie_intx_map - Set the handler for the INTx and mark IRQ as valid
++ * @domain: IRQ domain
++ * @irq: Virtual IRQ number
++ * @hwirq: HW interrupt number
++ *
++ * Return: Always returns 0.
++ */
++static int microsemi_pcie_intx_map(struct irq_domain *domain, unsigned int irq,
++ irq_hw_number_t hwirq)
++{
++ irq_set_chip_and_handler(irq, &dummy_irq_chip, handle_simple_irq);
++ irq_set_chip_data(irq, domain->host_data);
++
++ return 0;
++}
++
++/* INTx IRQ Domain operations */
++static const struct irq_domain_ops intx_domain_ops = {
++ .map = microsemi_pcie_intx_map,
++ .xlate = pci_irqd_intx_xlate,
++};
++
++/* PCIe HW Functions */
++
++/**
++ * microsemi_pcie_intr_handler - Interrupt Service Handler
++ * @irq: IRQ number
++ * @data: PCIe port information
++ *
++ * Return: IRQ_HANDLED on success and IRQ_NONE on failure
++ */
++static irqreturn_t microsemi_pcie_intr_handler(int irq, void *data)
++{
++ struct microsemi_pcie_port *port = (struct microsemi_pcie_port *)data;
++ struct device *dev = port->dev;
++ unsigned long status;
++ unsigned long msi;
++ u32 bit;
++ u32 virq;
++
++
++ status = readl(port->reg_bridge_apb + ISTATUS_LOCAL);
++
++ status = (status >> 24) & 0x0f;
++ for_each_set_bit(bit, &status, PCI_NUM_INTX) {
++ /* clear interrupts */
++ writel(1 << (bit+24),
++ port->reg_bridge_apb + ISTATUS_LOCAL);
++
++ virq = irq_find_mapping(port->leg_domain, bit);
++
++ if (virq)
++ generic_handle_irq(virq);
++ else
++ dev_err(dev, "unexpected IRQ, INT%d\n", bit);
++ }
++
++ status = readl(port->reg_bridge_apb + ISTATUS_LOCAL);
++ if ((status & 0x10000000) == 0x10000000) {
++ writel((1 << 28), port->reg_bridge_apb + ISTATUS_LOCAL);
++ msi = readl(port->reg_bridge_apb + ISTATUS_MSI);
++ for_each_set_bit(bit, &msi, MICROSEMI_NUM_MSI_IRQS) {
++ /* clear interrupts */
++ writel((1 << bit),
++ port->reg_bridge_apb + ISTATUS_MSI);
++ virq = irq_find_mapping(port->msi_domain, bit);
++ if (virq)
++ generic_handle_irq(virq);
++ else
++ dev_err(dev, "unexpected IRQ, INT%d\n", bit);
++ }
++ }
++
++ return IRQ_HANDLED;
++}
++
++/**
++ * microsemi_pcie_init_irq_domain - Initialize IRQ domain
++ * @port: PCIe port information
++ *
++ * Return: '0' on success and error value on failure
++ */
++static int microsemi_pcie_init_irq_domain(struct microsemi_pcie_port *port)
++{
++ struct device *dev = port->dev;
++ struct device_node *node = dev->of_node;
++ struct device_node *pcie_intc_node;
++
++ /* Setup INTx */
++ pcie_intc_node = of_get_next_child(node, NULL);
++ if (!pcie_intc_node) {
++ dev_err(dev, "No PCIe Intc node found\n");
++ return -ENODEV;
++ }
++ dev_info(dev, "Intc node foundi %s\n", pcie_intc_node->name);
++
++ port->leg_domain = irq_domain_add_linear(pcie_intc_node, PCI_NUM_INTX,
++ &intx_domain_ops,
++ port);
++ if (!port->leg_domain) {
++ dev_err(dev, "Failed to get a INTx IRQ domain\n");
++ return -ENODEV;
++ }
++
++ /* Setup MSI */
++ if (IS_ENABLED(CONFIG_PCI_MSI)) {
++ port->msi_domain = irq_domain_add_linear(node,
++ MICROSEMI_NUM_MSI_IRQS,
++ &msi_domain_ops,
++ µsemi_pcie_msi_chip);
++ if (!port->msi_domain) {
++ dev_err(dev, "Failed to get a MSI IRQ domain\n");
++ return -ENODEV;
++ }
++ microsemi_pcie_enable_msi(port);
++ }
++ return 0;
++}
++
++/**
++ * microsemi_pcie_init_port - Parse Device tree, Initialize hardware
++ * @port: PCIe port information
++ *
++ * Return: '0' on success and error value on failure
++ */
++static int microsemi_pcie_init_port(struct microsemi_pcie_port *port)
++{
++ struct device *dev = port->dev;
++ struct device_node *node = dev->of_node;
++ struct of_pci_range_parser parser;
++ struct of_pci_range range;
++ struct resource regs;
++ struct resource regs1;
++ resource_size_t size;
++ u32 bit, pf_bridge_id = 1;
++ const char *type;
++ int err;
++
++ type = of_get_property(node, "device_type", NULL);
++ if (!type || strcmp(type, "pci")) {
++ dev_err(dev, "invalid \"device_type\" %s\n", type);
++ return -EINVAL;
++ }
++
++ err = of_address_to_resource(node, 0, ®s);
++ if (err) {
++ dev_err(dev, "missing \"reg\" property\n");
++ return err;
++ }
++
++ port->reg_base = devm_pci_remap_cfg_resource(dev, ®s);
++ if (IS_ERR(port->reg_base))
++ return PTR_ERR(port->reg_base);
++
++
++ err = of_address_to_resource(node, 1, ®s1);
++ if (err) {
++ dev_err(dev, "missing \"reg\" property\n");
++ return err;
++ }
++
++
++ port->reg_base_apb = devm_ioremap_resource(dev, ®s1);
++ if (IS_ERR(port->reg_base_apb))
++ return PTR_ERR(port->reg_base_apb);
++
++ if (pf_bridge_id == 0) {
++ port->reg_bridge_apb = port->reg_base_apb + PCIE0_BRIDGE_ADDR;
++ port->reg_ctrl_apb = port->reg_base_apb + PCIE0_CRTL_ADDR;
++ } else {
++ port->reg_bridge_apb = port->reg_base_apb + PCIE1_BRIDGE_ADDR;
++ port->reg_ctrl_apb = port->reg_base_apb + PCIE1_CRTL_ADDR;
++ }
++
++ port->irq = irq_of_parse_and_map(node, 0);
++
++ err = devm_request_irq(dev, port->irq, microsemi_pcie_intr_handler,
++ IRQF_SHARED | IRQF_NO_THREAD,
++ "microsemi-pcie", port);
++ if (err) {
++ dev_err(dev, "unable to request irq %d\n", port->irq);
++ return err;
++ }
++
++
++ /* Clear and Disable interrupts */
++
++ writel(0x0f000000, port->reg_ctrl_apb + ECC_CONTROL);
++ writel(0x00070007, port->reg_ctrl_apb + PCIE_EVENT_INT);
++ writel(0x0000ffff, port->reg_ctrl_apb + SEC_ERROR_INT);
++ writel(0x0000ffff, port->reg_ctrl_apb + SEC_ERROR_INT_MASK);
++ writel(0x0000ffff, port->reg_ctrl_apb + DED_ERROR_INT);
++ writel(0x0000ffff, port->reg_ctrl_apb + DED_ERROR_INT_MASK);
++
++ writel(0x00000000, port->reg_bridge_apb + IMASK_LOCAL);
++ writel(0xffffffff, port->reg_bridge_apb + ISTATUS_LOCAL);
++ writel(0x00000000, port->reg_bridge_apb + IMASK_HOST);
++ writel(0xffffffff, port->reg_bridge_apb + ISTATUS_HOST);
++
++ dev_info(dev, "interrupt disabled\n");
++
++ /* Configure Address Translation Table 0 for pcie config space */
++
++ writel(PCIE_CONFIG_INTERFACE,
++ port->reg_bridge_apb + ATR0_AXI4_SLV0_TRSL_PARAM);
++
++ size = resource_size(®s);
++
++ bit = find_first_bit((const unsigned long *)&size, 64) - 1;
++
++ writel((u32)regs.start | bit << 1 | 0x01,
++ port->reg_bridge_apb + ATR0_AXI4_SLV0_SRCADDR_PARAM);
++
++// writel((u32)(regs.start >> 32),
++// port->reg_bridge_apb + ATR0_AXI4_SLV0_SRC_ADDR);
++
++ writel((u32)regs.start,
++ port->reg_bridge_apb + ATR0_AXI4_SLV0_TRSL_ADDR_LSB);
++
++// writel((u32)(regs.start >> 32),
++// port->reg_bridge_apb + ATR0_AXI4_SLV0_TRSL_ADDR_UDW);
++
++
++ if (of_pci_range_parser_init(&parser, node)) {
++ dev_err(dev, "missing \"ranges\" property\n");
++ return -EINVAL;
++ }
++
++
++ for_each_of_pci_range(&parser, &range) {
++ switch (range.flags & IORESOURCE_TYPE_BITS) {
++ case IORESOURCE_MEM:
++
++ size = range.size;
++ bit = find_first_bit((const unsigned long *)&size, 64) - 1;
++
++ /* Configure Address Translation Table 1 for pcie mem space */
++
++ writel(PCIE_TX_RX_INTERFACE,
++ port->reg_bridge_apb + ATR1_AXI4_SLV0_TRSL_PARAM);
++
++ writel((u32)range.cpu_addr | bit << 1 | 0x01,
++ port->reg_bridge_apb + ATR1_AXI4_SLV0_SRCADDR_PARAM);
++
++// writel((u32)(range.cpu_addr >> 32),
++// port->reg_bridge_apb + ATR1_AXI4_SLV0_SRC_ADDR);
++
++ writel((u32)range.pci_addr,
++ port->reg_bridge_apb + ATR1_AXI4_SLV0_TRSL_ADDR_LSB);
++
++// writel((u32)(range.pci_addr >> 32),
++// port->reg_bridge_apb + ATR1_AXI4_SLV0_TRSL_ADDR_UDW);
++
++ break;
++ }
++
++ }
++
++
++ writel(readl(port->reg_bridge_apb + ATR0_PCIE_WIN0_SRCADDR_PARAM)
++ | 0x3E,
++ port->reg_bridge_apb + ATR0_PCIE_WIN0_SRCADDR_PARAM);
++
++ writel(0, port->reg_bridge_apb + 0x604);
++
++ writel((readl(port->reg_bridge_apb + PCIE_PCI_IDS_DW1) & 0xffff)
++ | (PCI_CLASS_BRIDGE_PCI << 16),
++ port->reg_bridge_apb + PCIE_PCI_IDS_DW1);
++
++ pcie_write(port, 0x00ff0100, 0x18);
++
++ /* Enable interrupts */
++ writel(PCIE_ENABLE_MSI | PCIE_LOCAL_INT_ENABLE,
++ port->reg_bridge_apb + IMASK_LOCAL);
++
++
++ return 0;
++}
++
++/**
++ * microsemi_pcie_probe - Probe function
++ * @pdev: Platform device pointer
++ *
++ * Return: '0' on success and error value on failure
++ */
++static int microsemi_pcie_probe(struct platform_device *pdev)
++{
++ struct device *dev = &pdev->dev;
++ struct microsemi_pcie_port *port;
++ struct pci_bus *bus, *child;
++ struct pci_host_bridge *bridge;
++ int err;
++ resource_size_t iobase = 0;
++ LIST_HEAD(res);
++
++ pr_err("%s In \n", __func__);
++ if (!dev->of_node)
++ return -ENODEV;
++
++ bridge = devm_pci_alloc_host_bridge(dev, sizeof(*port));
++ if (!bridge)
++ return -ENODEV;
++
++ port = pci_host_bridge_priv(bridge);
++
++ port->dev = dev;
++ port->pdev = pdev;
++
++ err = microsemi_pcie_init_port(port);
++ if (err) {
++ dev_err(dev, "Pcie port initialization failed\n");
++ return err;
++ }
++
++
++ err = microsemi_pcie_init_irq_domain(port);
++ if (err) {
++ dev_err(dev, "Failed creating IRQ Domain\n");
++ return err;
++ }
++
++ err = devm_of_pci_get_host_bridge_resources(dev, 0, 0xff, &res,
++ &iobase);
++ if (err) {
++ dev_err(dev, "Getting bridge resources failed\n");
++ return err;
++ }
++
++ err = devm_request_pci_bus_resources(dev, &res);
++ if (err)
++ goto error;
++
++
++ list_splice_init(&res, &bridge->windows);
++ bridge->dev.parent = dev;
++ bridge->sysdata = port;
++ bridge->busnr = 0;
++ bridge->ops = µsemi_pcie_ops;
++ bridge->map_irq = of_irq_parse_and_map_pci;
++ bridge->swizzle_irq = pci_common_swizzle;
++
++#ifdef CONFIG_PCI_MSI
++ microsemi_pcie_msi_chip.dev = dev;
++ bridge->msi = µsemi_pcie_msi_chip;
++#endif
++ err = pci_scan_root_bus_bridge(bridge);
++ dev_info(dev, "pci_scan_root_bus_bridge done\n");
++ if (err < 0)
++ goto error;
++
++ bus = bridge->bus;
++
++ pci_assign_unassigned_bus_resources(bus);
++ list_for_each_entry(child, &bus->children, node)
++ pcie_bus_configure_settings(child);
++ pci_bus_add_devices(bus);
++
++ return 0;
++
++error:
++ pci_free_resource_list(&res);
++ return err;
++}
++
++static const struct of_device_id microsemi_pcie_of_match[] = {
++ { .compatible = "ms-pf,axi-pcie-host", },
++ {}
++};
++
++static struct platform_driver microsemi_pcie_driver = {
++ .driver = {
++ .name = "microsemi-pcie",
++ .of_match_table = microsemi_pcie_of_match,
++ .suppress_bind_attrs = true,
++ },
++ .probe = microsemi_pcie_probe,
++};
++builtin_platform_driver(microsemi_pcie_driver);
+--
+2.7.4
+