Commit 4017040a authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'cxl-fixes-6.15-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/cxl/cxl

Pull cxl fixes from Dave Jiang:
 "The fixes address global persistent flush (GPF) changes and CXL
  Features support changes that went in the 6.15 merge window. And also
  a fix to an issue observed on CXL 1.1 platform during device
  enumeration.

  Summary:

   - Fix using the wrong GPF DVSEC location:
       - Fix caching of dport GPF DVSEC from the first endpoint
       - Ensure that the GPF phase timeout is only updated once by first
         endpoint
       - Drop is_port parameter for cxl_gpf_get_dvsec()

   - Fix the devm_* call host device for CXL fwctl setup

   - Set the out_len in Set Features failure case

   - Fix RCD initialization by skipping unneeded mem_en check"

* tag 'cxl-fixes-6.15-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/cxl/cxl:
  cxl/core/regs.c: Skip Memory Space Enable check for RCD and RCH Ports
  cxl/feature: Update out_len in set feature failure case
  cxl: Fix devm host device for CXL fwctl initialization
  cxl/pci: Drop the parameter is_port of cxl_gpf_get_dvsec()
  cxl/pci: Update Port GPF timeout only when the first EP attaching
  cxl/core: Fix caching dport GPF DVSEC issue
parents c3137514 078d3ee7
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -119,7 +119,7 @@ int cxl_port_get_switch_dport_bandwidth(struct cxl_port *port,

int cxl_ras_init(void);
void cxl_ras_exit(void);
int cxl_gpf_port_setup(struct device *dport_dev, struct cxl_port *port);
int cxl_gpf_port_setup(struct cxl_dport *dport);
int cxl_acpi_get_extended_linear_cache_size(struct resource *backing_res,
					    int nid, resource_size_t *size);

+3 −3
Original line number Diff line number Diff line
@@ -528,13 +528,13 @@ static void *cxlctl_set_feature(struct cxl_features_state *cxlfs,
	rc = cxl_set_feature(cxl_mbox, &feat_in->uuid,
			     feat_in->version, feat_in->feat_data,
			     data_size, flags, offset, &return_code);
	*out_len = sizeof(*rpc_out);
	if (rc) {
		rpc_out->retval = return_code;
		return no_free_ptr(rpc_out);
	}

	rpc_out->retval = CXL_MBOX_CMD_RC_SUCCESS;
	*out_len = sizeof(*rpc_out);

	return no_free_ptr(rpc_out);
}
@@ -677,7 +677,7 @@ static void free_memdev_fwctl(void *_fwctl_dev)
	fwctl_put(fwctl_dev);
}

int devm_cxl_setup_fwctl(struct cxl_memdev *cxlmd)
int devm_cxl_setup_fwctl(struct device *host, struct cxl_memdev *cxlmd)
{
	struct cxl_dev_state *cxlds = cxlmd->cxlds;
	struct cxl_features_state *cxlfs;
@@ -700,7 +700,7 @@ int devm_cxl_setup_fwctl(struct cxl_memdev *cxlmd)
	if (rc)
		return rc;

	return devm_add_action_or_reset(&cxlmd->dev, free_memdev_fwctl,
	return devm_add_action_or_reset(host, free_memdev_fwctl,
					no_free_ptr(fwctl_dev));
}
EXPORT_SYMBOL_NS_GPL(devm_cxl_setup_fwctl, "CXL");
+17 −13
Original line number Diff line number Diff line
@@ -1072,14 +1072,20 @@ int cxl_pci_get_bandwidth(struct pci_dev *pdev, struct access_coordinate *c)
#define GPF_TIMEOUT_BASE_MAX 2
#define GPF_TIMEOUT_SCALE_MAX 7 /* 10 seconds */

u16 cxl_gpf_get_dvsec(struct device *dev, bool is_port)
u16 cxl_gpf_get_dvsec(struct device *dev)
{
	struct pci_dev *pdev;
	bool is_port = true;
	u16 dvsec;

	if (!dev_is_pci(dev))
		return 0;

	dvsec = pci_find_dvsec_capability(to_pci_dev(dev), PCI_VENDOR_ID_CXL,
	pdev = to_pci_dev(dev);
	if (pci_pcie_type(pdev) == PCI_EXP_TYPE_ENDPOINT)
		is_port = false;

	dvsec = pci_find_dvsec_capability(pdev, PCI_VENDOR_ID_CXL,
			is_port ? CXL_DVSEC_PORT_GPF : CXL_DVSEC_DEVICE_GPF);
	if (!dvsec)
		dev_warn(dev, "%s GPF DVSEC not present\n",
@@ -1128,26 +1134,24 @@ static int update_gpf_port_dvsec(struct pci_dev *pdev, int dvsec, int phase)
	return rc;
}

int cxl_gpf_port_setup(struct device *dport_dev, struct cxl_port *port)
int cxl_gpf_port_setup(struct cxl_dport *dport)
{
	struct pci_dev *pdev;

	if (!port)
	if (!dport)
		return -EINVAL;

	if (!port->gpf_dvsec) {
	if (!dport->gpf_dvsec) {
		struct pci_dev *pdev;
		int dvsec;

		dvsec = cxl_gpf_get_dvsec(dport_dev, true);
		dvsec = cxl_gpf_get_dvsec(dport->dport_dev);
		if (!dvsec)
			return -EINVAL;

		port->gpf_dvsec = dvsec;
		dport->gpf_dvsec = dvsec;
		pdev = to_pci_dev(dport->dport_dev);
		update_gpf_port_dvsec(pdev, dport->gpf_dvsec, 1);
		update_gpf_port_dvsec(pdev, dport->gpf_dvsec, 2);
	}

	pdev = to_pci_dev(dport_dev);
	update_gpf_port_dvsec(pdev, port->gpf_dvsec, 1);
	update_gpf_port_dvsec(pdev, port->gpf_dvsec, 2);

	return 0;
}
+1 −1
Original line number Diff line number Diff line
@@ -1678,7 +1678,7 @@ int devm_cxl_enumerate_ports(struct cxl_memdev *cxlmd)
			if (rc && rc != -EBUSY)
				return rc;

			cxl_gpf_port_setup(dport_dev, port);
			cxl_gpf_port_setup(dport);

			/* Any more ports to add between this one and the root? */
			if (!dev_is_cxl_root_child(&port->dev))
+0 −4
Original line number Diff line number Diff line
@@ -581,7 +581,6 @@ resource_size_t __rcrb_to_component(struct device *dev, struct cxl_rcrb_info *ri
	resource_size_t rcrb = ri->base;
	void __iomem *addr;
	u32 bar0, bar1;
	u16 cmd;
	u32 id;

	if (which == CXL_RCRB_UPSTREAM)
@@ -603,7 +602,6 @@ resource_size_t __rcrb_to_component(struct device *dev, struct cxl_rcrb_info *ri
	}

	id = readl(addr + PCI_VENDOR_ID);
	cmd = readw(addr + PCI_COMMAND);
	bar0 = readl(addr + PCI_BASE_ADDRESS_0);
	bar1 = readl(addr + PCI_BASE_ADDRESS_1);
	iounmap(addr);
@@ -618,8 +616,6 @@ resource_size_t __rcrb_to_component(struct device *dev, struct cxl_rcrb_info *ri
			dev_err(dev, "Failed to access Downstream Port RCRB\n");
		return CXL_RESOURCE_NONE;
	}
	if (!(cmd & PCI_COMMAND_MEMORY))
		return CXL_RESOURCE_NONE;
	/* The RCRB is a Memory Window, and the MEM_TYPE_1M bit is obsolete */
	if (bar0 & (PCI_BASE_ADDRESS_MEM_TYPE_1M | PCI_BASE_ADDRESS_SPACE_IO))
		return CXL_RESOURCE_NONE;
Loading