drivers/pci/controller/pcie-brcmstb.c

Source file repositories/reference/linux-study-clean/drivers/pci/controller/pcie-brcmstb.c

File Facts

System
Linux kernel
Corpus path
drivers/pci/controller/pcie-brcmstb.c
Extension
.c
Size
65391 bytes
Lines
2215
Domain
Representative Device Path
Bucket
PCIe NVMe Storage Path
Inferred role
Representative Device Path: implementation source
Status
source implementation candidate

Why This File Exists

Part of the selected hardware vertical slice: PCI discovery, driver binding, NVMe queues, block requests, DMA, interrupts, and completion.

Dependency Surface

Detected Declarations

Annotated Snippet

struct inbound_win {
	u64 size;
	u64 pci_offset;
	u64 cpu_addr;
};

/*
 * The RESCAL block is tied to PCIe controller #1, regardless of the number of
 * controllers, and turning off PCIe controller #1 prevents access to the RESCAL
 * register blocks, therefore no other controller can access this register
 * space, and depending upon the bus fabric we may get a timeout (UBUS/GISB),
 * or a hang (AXI).
 */
#define CFG_QUIRK_AVOID_BRIDGE_SHUTDOWN		BIT(0)

struct pcie_cfg_data {
	const int *offsets;
	const enum pcie_soc_base soc_base;
	const bool has_phy;
	const u32 quirks;
	u8 num_inbound_wins;
	int (*perst_set)(struct brcm_pcie *pcie, u32 val);
	int (*bridge_sw_init_set)(struct brcm_pcie *pcie, u32 val);
	int (*post_setup)(struct brcm_pcie *pcie);
	bool has_err_report;
};

struct subdev_regulators {
	unsigned int num_supplies;
	struct regulator_bulk_data supplies[];
};

struct brcm_msi {
	struct device		*dev;
	void __iomem		*base;
	struct device_node	*np;
	struct irq_domain	*inner_domain;
	struct mutex		lock; /* guards the alloc/free operations */
	u64			target_addr;
	int			irq;
	DECLARE_BITMAP(used, BRCM_INT_PCI_MSI_NR);
	bool			legacy;
	/* Some chips have MSIs in bits [31..24] of a shared register. */
	int			legacy_shift;
	int			nr; /* No. of MSI available, depends on chip */
	/* This is the base pointer for interrupt status/set/clr regs */
	void __iomem		*intr_base;
};

/* Internal PCIe Host Controller Information.*/
struct brcm_pcie {
	struct device		*dev;
	void __iomem		*base;
	struct clk		*clk;
	struct device_node	*np;
	bool			ssc;
	int			gen;
	u64			msi_target_addr;
	struct brcm_msi		*msi;
	struct reset_control	*rescal;
	struct reset_control	*perst_reset;
	struct reset_control	*bridge_reset;
	struct reset_control	*swinit_reset;
	int			num_memc;
	u64			memc_size[PCIE_BRCM_MAX_MEMC];
	u32			hw_rev;
	struct subdev_regulators *sr;
	bool			ep_wakeup_capable;
	const struct pcie_cfg_data	*cfg;
	bool			bridge_in_reset;
	struct notifier_block	die_notifier;
	struct notifier_block	panic_notifier;
	spinlock_t		bridge_lock;
};

static inline bool is_bmips(const struct brcm_pcie *pcie)
{
	return pcie->cfg->soc_base == BCM7435 || pcie->cfg->soc_base == BCM7425;
}

static int brcm_pcie_bridge_sw_init_set(struct brcm_pcie *pcie, u32 val)
{
	unsigned long flags;
	int ret;

	if (pcie->cfg->has_err_report)
		spin_lock_irqsave(&pcie->bridge_lock, flags);

	ret = pcie->cfg->bridge_sw_init_set(pcie, val);
	/* If we fail, assume the bridge is in reset (off) */

Annotation

Implementation Notes