Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dd0a9ded authored by Tony Truong's avatar Tony Truong Committed by Gerrit - the friendly Code Review server
Browse files

msm: pcie: remove unnecessary global PCI device table



Having a global PCI device table share between all PCIe ports
is not necessary. There is potential race conditions if required
locks are present. remove the global PCI device table completely
and utilize the bus list for each PCIe port instead.

Change-Id: I48ebc086fcf56e4b9a9496615e4185c3893ae278
Signed-off-by: default avatarTony Truong <truong@codeaurora.org>
parent 98ed1806
Loading
Loading
Loading
Loading
+46 −115
Original line number Diff line number Diff line
@@ -874,10 +874,6 @@ static u32 corr_counter_limit = 5;
/* CRC8 table for BDF to SID translation */
static u8 msm_pcie_crc8_table[CRC8_TABLE_SIZE];

/* Table to track info of PCIe devices */
static struct msm_pcie_device_info
	msm_pcie_dev_tbl[MAX_RC_NUM * MAX_DEVICE_NUM];

/* PCIe driver state */
static struct pcie_drv_sta {
	u32 rc_num;
@@ -2933,20 +2929,13 @@ static void msm_pcie_save_shadow(struct msm_pcie_dev_t *dev,
					u32 word_offset, u32 wr_val,
					u32 bdf, bool rc)
{
	int i, j;
	u32 max_dev = MAX_RC_NUM * MAX_DEVICE_NUM;
	int i;

	if (rc) {
		dev->rc_shadow[word_offset / 4] = wr_val;
	} else {
		for (i = 0; i < MAX_DEVICE_NUM; i++) {
			if (!dev->pcidev_table[i].bdf) {
				for (j = 0; j < max_dev; j++) {
					if (!msm_pcie_dev_tbl[j].bdf) {
						msm_pcie_dev_tbl[j].bdf = bdf;
						break;
					}
				}
				dev->pcidev_table[i].bdf = bdf;
				if ((!dev->bridge_found) && (i > 0))
					dev->bridge_found = true;
@@ -4617,27 +4606,18 @@ static void msm_pcie_config_ep_aer(struct msm_pcie_dev_t *dev,
		readl_relaxed(ep_base + ep_dev_info->dev_ctrlstts_offset));
}

static int msm_pcie_config_device_table(struct device *dev, void *pdev)
static int msm_pcie_config_device_table(struct pci_dev *pcidev, void *pdev)
{
	struct pci_dev *pcidev = to_pci_dev(dev);
	struct msm_pcie_dev_t *pcie_dev = (struct msm_pcie_dev_t *) pdev;
	struct msm_pcie_device_info *dev_table_t = pcie_dev->pcidev_table;
	struct resource *axi_conf = pcie_dev->res[MSM_PCIE_RES_CONF].resource;
	int ret = 0;
	u32 rc_idx = pcie_dev->rc_idx;
	u32 i, index;
	u32 i;
	u32 bdf = 0;
	u8 type;
	u32 h_type;
	u32 bme;

	if (!pcidev) {
		PCIE_ERR(pcie_dev,
			"PCIe: Did not find PCI device in list for RC%d.\n",
			pcie_dev->rc_idx);
		return -ENODEV;
	}

	PCIE_DBG(pcie_dev,
		"PCI device found: vendor-id:0x%x device-id:0x%x\n",
		pcidev->vendor, pcidev->device);
@@ -4649,81 +4629,51 @@ static int msm_pcie_config_device_table(struct device *dev, void *pdev)
	type = pcidev->bus->number == 1 ?
		PCIE20_CTRL1_TYPE_CFG0 : PCIE20_CTRL1_TYPE_CFG1;

	for (i = 0; i < (MAX_RC_NUM * MAX_DEVICE_NUM); i++) {
		if (msm_pcie_dev_tbl[i].bdf == bdf &&
			!msm_pcie_dev_tbl[i].dev) {
			for (index = 0; index < MAX_DEVICE_NUM; index++) {
				if (dev_table_t[index].bdf == bdf) {
					msm_pcie_dev_tbl[i].dev = pcidev;
					msm_pcie_dev_tbl[i].domain = rc_idx;
					msm_pcie_dev_tbl[i].conf_base =
						pcie_dev->conf + index * SZ_4K;
					msm_pcie_dev_tbl[i].phy_address =
						axi_conf->start + index * SZ_4K;

					dev_table_t[index].dev = pcidev;
					dev_table_t[index].domain = rc_idx;
					dev_table_t[index].conf_base =
						pcie_dev->conf + index * SZ_4K;
					dev_table_t[index].phy_address =
						axi_conf->start + index * SZ_4K;

					msm_pcie_iatu_config(pcie_dev, index,
						type,
						dev_table_t[index].phy_address,
						dev_table_t[index].phy_address
						+ SZ_4K - 1,
						bdf);
	for (i = 0; i < MAX_DEVICE_NUM; i++) {
		struct msm_pcie_device_info *dev_table_t =
						&pcie_dev->pcidev_table[i];

					h_type = readl_relaxed(
						dev_table_t[index].conf_base +
		if (dev_table_t->bdf != bdf)
			continue;

		dev_table_t->dev = pcidev;
		dev_table_t->domain = rc_idx;
		dev_table_t->conf_base = pcie_dev->conf + i * SZ_4K;
		dev_table_t->phy_address = axi_conf->start + i * SZ_4K;

		msm_pcie_iatu_config(pcie_dev, i, type,
				     dev_table_t->phy_address,
				     dev_table_t->phy_address + SZ_4K - 1, bdf);

		h_type = readl_relaxed(dev_table_t->conf_base +
				       PCIE20_HEADER_TYPE);

					bme = readl_relaxed(
						dev_table_t[index].conf_base +
		bme = readl_relaxed(dev_table_t->conf_base +
				    PCIE20_COMMAND_STATUS);

		if (h_type & (1 << 16)) {
						pci_write_config_dword(pcidev,
							PCIE20_COMMAND_STATUS,
			pci_write_config_dword(pcidev, PCIE20_COMMAND_STATUS,
					       bme | 0x06);
		} else {
			pcie_dev->num_ep++;
						dev_table_t[index].registered =
							false;
			dev_table_t->registered = false;
		}

		if (pcie_dev->num_ep > 1)
			pcie_dev->pending_ep_reg = true;

		if (pcie_dev->aer_enable)
						msm_pcie_config_ep_aer(pcie_dev,
							&dev_table_t[index]);
			msm_pcie_config_ep_aer(pcie_dev, dev_table_t);

		break;
	}
			}
			if (index == MAX_DEVICE_NUM) {
				PCIE_ERR(pcie_dev,
					"RC%d PCI device table is full.\n",
					rc_idx);
				ret = index;
			} else {
				break;
			}
		} else if (msm_pcie_dev_tbl[i].bdf == bdf &&
			pcidev == msm_pcie_dev_tbl[i].dev) {
			break;
		}
	}
	if (i == MAX_RC_NUM * MAX_DEVICE_NUM) {
		PCIE_ERR(pcie_dev,
			"Global PCI device table is full: %d elements.\n",
			i);

	if (i == MAX_DEVICE_NUM) {
		PCIE_ERR(pcie_dev,
			"Bus number is 0x%x\nDevice number is 0x%x\n",
			pcidev->bus->number, pcidev->devfn);
		ret = i;
			 "PCIe: RC%d: could not find device in the table: %02x:%02x:%01x\n",
			 pcie_dev->rc_idx, pcidev->bus->number,
			 PCI_SLOT(pcidev->devfn), PCI_FUNC(pcidev->devfn));
		ret = -ENODEV;
	}
	return ret;
}
@@ -4803,7 +4753,7 @@ static void msm_pcie_config_sid(struct msm_pcie_dev_t *dev)

int msm_pcie_enumerate(u32 rc_idx)
{
	int ret = 0, bus_ret = 0;
	int ret = 0;
	struct msm_pcie_dev_t *dev = &msm_pcie_dev[rc_idx];
	struct pci_dev *pcidev = NULL;
	struct pci_host_bridge *bridge;
@@ -4925,14 +4875,7 @@ int msm_pcie_enumerate(u32 rc_idx)
		goto out;
	}

	bus_ret = bus_for_each_dev(&pci_bus_type, NULL, dev,
			&msm_pcie_config_device_table);
	if (bus_ret) {
		PCIE_ERR(dev, "PCIe: RC%d: Failed to set up device table\n",
			dev->rc_idx);
		ret = -ENODEV;
		goto out;
	}
	pci_walk_bus(dev->dev->bus, msm_pcie_config_device_table, dev);

	msm_pcie_check_l1ss_support_all(dev);
	msm_pcie_config_link_pm(dev, true);
@@ -7010,18 +6953,6 @@ static int __init pcie_init(void)
		INIT_WORK(&msm_pcie_dev[i].drv_enable_pc_work,
				msm_pcie_drv_enable_pc);
	}
	for (i = 0; i < MAX_RC_NUM * MAX_DEVICE_NUM; i++) {
		msm_pcie_dev_tbl[i].bdf = 0;
		msm_pcie_dev_tbl[i].dev = NULL;
		msm_pcie_dev_tbl[i].short_bdf = 0;
		msm_pcie_dev_tbl[i].sid = 0;
		msm_pcie_dev_tbl[i].domain = -1;
		msm_pcie_dev_tbl[i].conf_base = NULL;
		msm_pcie_dev_tbl[i].phy_address = 0;
		msm_pcie_dev_tbl[i].dev_ctrlstts_offset = 0;
		msm_pcie_dev_tbl[i].event_reg = NULL;
		msm_pcie_dev_tbl[i].registered = true;
	}

	crc8_populate_msb(msm_pcie_crc8_table, MSM_PCIE_CRC8_POLYNOMIAL);