Commit 59c3368b authored by Dave Jiang's avatar Dave Jiang Committed by Dan Williams
Browse files

cxl/port: Export cxl_dvsec_rr_decode() to cxl_port



Call cxl_dvsec_rr_decode() in the beginning of cxl_port_probe() and
preserve the decoded information in a local
'struct cxl_endpoint_dvsec_info'. This info can be passed to various
functions later on in order to support the HDM decoder emulation.
The invocation of cxl_dvsec_rr_decode() in cxl_hdm_decode_init() is
removed and a pointer to the 'struct cxl_endpoint_dvsec_info' is passed
in.

Reviewed-by: default avatarJonathan Cameron <Jonathan.Cameron@huawei.com>
Signed-off-by: default avatarDave Jiang <dave.jiang@intel.com>
Link: https://lore.kernel.org/r/167640367377.935665.2848747799651019676.stgit@dwillia2-xfh.jf.intel.com


Signed-off-by: default avatarDan Williams <dan.j.williams@intel.com>
parent 1acba6e9
Loading
Loading
Loading
Loading
+7 −11
Original line number Diff line number Diff line
@@ -333,7 +333,7 @@ static bool __cxl_hdm_decode_init(struct cxl_dev_state *cxlds,
	return true;
}

static int cxl_dvsec_rr_decode(struct device *dev, int d,
int cxl_dvsec_rr_decode(struct device *dev, int d,
			struct cxl_endpoint_dvsec_info *info)
{
	struct pci_dev *pdev = to_pci_dev(dev);
@@ -434,30 +434,26 @@ static int cxl_dvsec_rr_decode(struct device *dev, int d,

	return 0;
}
EXPORT_SYMBOL_NS_GPL(cxl_dvsec_rr_decode, CXL);

/**
 * cxl_hdm_decode_init() - Setup HDM decoding for the endpoint
 * @cxlds: Device state
 * @cxlhdm: Mapped HDM decoder Capability
 * @info: Cached DVSEC range registers info
 *
 * Try to enable the endpoint's HDM Decoder Capability
 */
int cxl_hdm_decode_init(struct cxl_dev_state *cxlds, struct cxl_hdm *cxlhdm)
int cxl_hdm_decode_init(struct cxl_dev_state *cxlds, struct cxl_hdm *cxlhdm,
			struct cxl_endpoint_dvsec_info *info)
{
	struct cxl_endpoint_dvsec_info info = { 0 };
	struct device *dev = cxlds->dev;
	int d = cxlds->cxl_dvsec;
	int rc;

	rc = cxl_dvsec_rr_decode(dev, d, &info);
	if (rc < 0)
		return rc;

	/*
	 * If DVSEC ranges are being used instead of HDM decoder registers there
	 * is no use in trying to manage those.
	 */
	if (!__cxl_hdm_decode_init(cxlds, cxlhdm, &info)) {
	if (!__cxl_hdm_decode_init(cxlds, cxlhdm, info)) {
		dev_err(dev,
			"Legacy range registers configuration prevents HDM operation.\n");
		return -EBUSY;
+14 −0
Original line number Diff line number Diff line
@@ -630,10 +630,24 @@ int cxl_decoder_add_locked(struct cxl_decoder *cxld, int *target_map);
int cxl_decoder_autoremove(struct device *host, struct cxl_decoder *cxld);
int cxl_endpoint_autoremove(struct cxl_memdev *cxlmd, struct cxl_port *endpoint);

/**
 * struct cxl_endpoint_dvsec_info - Cached DVSEC info
 * @mem_enabled: cached value of mem_enabled in the DVSEC, PCIE_DEVICE
 * @ranges: Number of active HDM ranges this device uses.
 * @dvsec_range: cached attributes of the ranges in the DVSEC, PCIE_DEVICE
 */
struct cxl_endpoint_dvsec_info {
	bool mem_enabled;
	int ranges;
	struct range dvsec_range[2];
};

struct cxl_hdm;
struct cxl_hdm *devm_cxl_setup_hdm(struct cxl_port *port);
int devm_cxl_enumerate_decoders(struct cxl_hdm *cxlhdm);
int devm_cxl_add_passthrough_decoder(struct cxl_port *port);
int cxl_dvsec_rr_decode(struct device *dev, int dvsec,
			struct cxl_endpoint_dvsec_info *info);

bool is_cxl_region(struct device *dev);

+0 −12
Original line number Diff line number Diff line
@@ -181,18 +181,6 @@ static inline int cxl_mbox_cmd_rc2errno(struct cxl_mbox_cmd *mbox_cmd)
 */
#define CXL_CAPACITY_MULTIPLIER SZ_256M

/**
 * struct cxl_endpoint_dvsec_info - Cached DVSEC info
 * @mem_enabled: cached value of mem_enabled in the DVSEC, PCIE_DEVICE
 * @ranges: Number of active HDM ranges this device uses.
 * @dvsec_range: cached attributes of the ranges in the DVSEC, PCIE_DEVICE
 */
struct cxl_endpoint_dvsec_info {
	bool mem_enabled;
	int ranges;
	struct range dvsec_range[2];
};

/**
 * struct cxl_dev_state - The driver device state
 *
+2 −1
Original line number Diff line number Diff line
@@ -64,6 +64,7 @@ enum cxl_regloc_type {

int devm_cxl_port_enumerate_dports(struct cxl_port *port);
struct cxl_dev_state;
int cxl_hdm_decode_init(struct cxl_dev_state *cxlds, struct cxl_hdm *cxlhdm);
int cxl_hdm_decode_init(struct cxl_dev_state *cxlds, struct cxl_hdm *cxlhdm,
			struct cxl_endpoint_dvsec_info *info);
void read_cdat_data(struct cxl_port *port);
#endif /* __CXL_PCI_H__ */
+13 −7
Original line number Diff line number Diff line
@@ -32,12 +32,21 @@ static void schedule_detach(void *cxlmd)

static int cxl_port_probe(struct device *dev)
{
	struct cxl_endpoint_dvsec_info info = { 0 };
	struct cxl_port *port = to_cxl_port(dev);
	bool is_ep = is_cxl_endpoint(port);
	struct cxl_dev_state *cxlds;
	struct cxl_memdev *cxlmd;
	struct cxl_hdm *cxlhdm;
	int rc;


	if (!is_cxl_endpoint(port)) {
	if (is_ep) {
		cxlmd = to_cxl_memdev(port->uport);
		cxlds = cxlmd->cxlds;
		rc = cxl_dvsec_rr_decode(cxlds->dev, cxlds->cxl_dvsec, &info);
		if (rc < 0)
			return rc;
	} else {
		rc = devm_cxl_port_enumerate_dports(port);
		if (rc < 0)
			return rc;
@@ -49,10 +58,7 @@ static int cxl_port_probe(struct device *dev)
	if (IS_ERR(cxlhdm))
		return PTR_ERR(cxlhdm);

	if (is_cxl_endpoint(port)) {
		struct cxl_memdev *cxlmd = to_cxl_memdev(port->uport);
		struct cxl_dev_state *cxlds = cxlmd->cxlds;

	if (is_ep) {
		/* Cache the data early to ensure is_visible() works */
		read_cdat_data(port);

@@ -61,7 +67,7 @@ static int cxl_port_probe(struct device *dev)
		if (rc)
			return rc;

		rc = cxl_hdm_decode_init(cxlds, cxlhdm);
		rc = cxl_hdm_decode_init(cxlds, cxlhdm, &info);
		if (rc)
			return rc;

Loading