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

Commit 765a6fac authored by Dean Luick's avatar Dean Luick Committed by Doug Ledford
Browse files

IB/hfi1: Change QSFP functions to use resource reservation



Remove the mutex guarding each operation in favor the ASIC
resource acquire/release.  Push the resource acquire/release,
above each operation call to allow exclusive access across
multiple operations.

Reviewed-by: default avatarMitko Haralanov <mitko.haralanov@intel.com>
Reviewed-by: default avatarEaswar Hariharan <easwar.hariharan@intel.com>
Signed-off-by: default avatarDean Luick <dean.luick@intel.com>
Signed-off-by: default avatarJubin John <jubin.john@intel.com>
Signed-off-by: default avatarDoug Ledford <dledford@redhat.com>
parent 576531fd
Loading
Loading
Loading
Loading
+15 −5
Original line number Diff line number Diff line
@@ -6267,7 +6267,7 @@ void handle_8051_request(struct work_struct *work)
					cdr_ctrl_byte &= ~(1 << i);
			}
		}
		qsfp_write(ppd, ppd->dd->hfi1_id, QSFP_CDR_CTRL_BYTE_OFFS,
		one_qsfp_write(ppd, dd->hfi1_id, QSFP_CDR_CTRL_BYTE_OFFS,
			       &cdr_ctrl_byte, 1);
		hreq_response(dd, HREQ_SUCCESS, data);
		refresh_qsfp_cache(ppd, &ppd->qsfp_info);
@@ -9290,7 +9290,7 @@ void qsfp_event(struct work_struct *work)
	if (qd->check_interrupt_flags) {
		u8 qsfp_interrupt_status[16] = {0,};

		if (qsfp_read(ppd, dd->hfi1_id, 6,
		if (one_qsfp_read(ppd, dd->hfi1_id, 6,
				  &qsfp_interrupt_status[0], 16) != 16) {
			dd_dev_info(dd,
				    "%s: Failed to read status of QSFP module\n",
@@ -9845,7 +9845,17 @@ static int goto_offline(struct hfi1_pportdata *ppd, u8 rem_reason)
	if (ppd->port_type == PORT_TYPE_QSFP &&
	    ppd->qsfp_info.limiting_active &&
	    qsfp_mod_present(ppd)) {
		int ret;

		ret = acquire_chip_resource(dd, qsfp_resource(dd), QSFP_WAIT);
		if (ret == 0) {
			set_qsfp_tx(ppd, 0);
			release_chip_resource(dd, qsfp_resource(dd));
		} else {
			/* not fatal, but should warn */
			dd_dev_err(dd,
				   "Unable to acquire lock to turn off QSFP TX\n");
		}
	}

	/*
+3 −0
Original line number Diff line number Diff line
@@ -672,6 +672,9 @@ void finish_chip_resources(struct hfi1_devdata *dd);
/* ms wait time for access to an SBus resoure */
#define SBUS_TIMEOUT 4000 /* long enough for a FW download and SBR */

/* ms wait time for a qsfp (i2c) chain to become available */
#define QSFP_WAIT 20000 /* long enough for FW update to the F4 uc */

void fabric_serdes_reset(struct hfi1_devdata *dd);
int read_8051_data(struct hfi1_devdata *dd, u32 addr, u32 len, u64 *result);

+17 −5
Original line number Diff line number Diff line
@@ -465,16 +465,22 @@ static ssize_t __i2c_debugfs_write(struct file *file, const char __user *buf,
		goto _free;
	}

	ret = acquire_chip_resource(ppd->dd, i2c_target(target), 0);
	if (ret)
		goto _free;

	total_written = i2c_write(ppd, target, i2c_addr, offset, buff, count);
	if (total_written < 0) {
		ret = total_written;
		goto _free;
		goto _release;
	}

	*ppos += total_written;

	ret = total_written;

 _release:
	release_chip_resource(ppd->dd, i2c_target(target));
 _free:
	kfree(buff);
 _return:
@@ -526,10 +532,14 @@ static ssize_t __i2c_debugfs_read(struct file *file, char __user *buf,
		goto _return;
	}

	ret = acquire_chip_resource(ppd->dd, i2c_target(target), 0);
	if (ret)
		goto _free;

	total_read = i2c_read(ppd, target, i2c_addr, offset, buff, count);
	if (total_read < 0) {
		ret = total_read;
		goto _free;
		goto _release;
	}

	*ppos += total_read;
@@ -537,11 +547,13 @@ static ssize_t __i2c_debugfs_read(struct file *file, char __user *buf,
	ret = copy_to_user(buf, buff, total_read);
	if (ret > 0) {
		ret = -EFAULT;
		goto _free;
		goto _release;
	}

	ret = total_read;

 _release:
	release_chip_resource(ppd->dd, i2c_target(target));
 _free:
	kfree(buff);
 _return:
@@ -592,7 +604,7 @@ static ssize_t __qsfp_debugfs_write(struct file *file, const char __user *buf,
		goto _free;
	}

	total_written = qsfp_write(ppd, target, *ppos, buff, count);
	total_written = one_qsfp_write(ppd, target, *ppos, buff, count);
	if (total_written < 0) {
		ret = total_written;
		goto _free;
@@ -646,7 +658,7 @@ static ssize_t __qsfp_debugfs_read(struct file *file, char __user *buf,
		goto _return;
	}

	total_read = qsfp_read(ppd, target, *ppos, buff, count);
	total_read = one_qsfp_read(ppd, target, *ppos, buff, count);
	if (total_read < 0) {
		ret = total_read;
		goto _free;
+12 −2
Original line number Diff line number Diff line
@@ -1048,8 +1048,6 @@ struct hfi1_devdata {

	struct platform_config platform_config;
	struct platform_config_cache pcfg_cache;
	/* control high-level access to qsfp */
	struct mutex qsfp_i2c_mutex;

	struct diag_client *diag_client;
	spinlock_t hfi1_diag_trans_lock; /* protect diag observer ops */
@@ -1938,6 +1936,18 @@ static inline void setextled(struct hfi1_devdata *dd, u32 on)
		write_csr(dd, DCC_CFG_LED_CNTRL, 0x10);
}

/* return the i2c resource given the target */
static inline u32 i2c_target(u32 target)
{
	return target ? CR_I2C2 : CR_I2C1;
}

/* return the i2c chain chip resource that this HFI uses for QSFP */
static inline u32 qsfp_resource(struct hfi1_devdata *dd)
{
	return i2c_target(dd->hfi1_id);
}

int hfi1_tempsense_rd(struct hfi1_devdata *dd, struct hfi1_temp *temp);

#endif                          /* _HFI1_KERNEL_H */
+0 −1
Original line number Diff line number Diff line
@@ -1065,7 +1065,6 @@ struct hfi1_devdata *hfi1_alloc_devdata(struct pci_dev *pdev, size_t extra)
	spin_lock_init(&dd->sc_init_lock);
	spin_lock_init(&dd->dc8051_lock);
	spin_lock_init(&dd->dc8051_memlock);
	mutex_init(&dd->qsfp_i2c_mutex);
	seqlock_init(&dd->sc2vl_lock);
	spin_lock_init(&dd->sde_map_lock);
	spin_lock_init(&dd->pio_map_lock);
Loading