Commit 77dd39d9 authored by Dragan Cvetic's avatar Dragan Cvetic Committed by Greg Kroah-Hartman
Browse files

misc: xilinx_sdfec: Add ability to get/set config



- Add capability to get SD-FEC config data using ioctl
XSDFEC_GET_CONFIG.

- Add capability to set SD-FEC data order using ioctl
SDFEC_SET_ORDER.

- Add capability to set SD-FEC bypass option using ioctl
XSDFEC_SET_BYPASS.

- Add capability to set SD-FEC active state using ioctl
XSDFEC_IS_ACTIVE.

Tested-by: default avatarDragan Cvetic <dragan.cvetic@xilinx.com>
Signed-off-by: default avatarDerek Kiernan <derek.kiernan@xilinx.com>
Signed-off-by: default avatarDragan Cvetic <dragan.cvetic@xilinx.com>
Link: https://lore.kernel.org/r/1564216438-322406-5-git-send-email-dragan.cvetic@xilinx.com


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 20ec628e
Loading
Loading
Loading
Loading
+88 −0
Original line number Diff line number Diff line
@@ -273,6 +273,17 @@ static void update_config_from_hw(struct xsdfec_dev *xsdfec)
		xsdfec->state = XSDFEC_STOPPED;
}

static int xsdfec_get_config(struct xsdfec_dev *xsdfec, void __user *arg)
{
	int err;

	err = copy_to_user(arg, &xsdfec->config, sizeof(xsdfec->config));
	if (err)
		err = -EFAULT;

	return err;
}

static int xsdfec_set_turbo(struct xsdfec_dev *xsdfec, void __user *arg)
{
	struct xsdfec_turbo turbo;
@@ -591,6 +602,71 @@ err_out:
	return ret;
}

static int xsdfec_set_order(struct xsdfec_dev *xsdfec, void __user *arg)
{
	bool order_invalid;
	enum xsdfec_order order;
	int err;

	err = get_user(order, (enum xsdfec_order *)arg);
	if (err)
		return -EFAULT;

	order_invalid = (order != XSDFEC_MAINTAIN_ORDER) &&
			(order != XSDFEC_OUT_OF_ORDER);
	if (order_invalid)
		return -EINVAL;

	/* Verify Device has not started */
	if (xsdfec->state == XSDFEC_STARTED)
		return -EIO;

	xsdfec_regwrite(xsdfec, XSDFEC_ORDER_ADDR, order);

	xsdfec->config.order = order;

	return 0;
}

static int xsdfec_set_bypass(struct xsdfec_dev *xsdfec, bool __user *arg)
{
	bool bypass;
	int err;

	err = get_user(bypass, arg);
	if (err)
		return -EFAULT;

	/* Verify Device has not started */
	if (xsdfec->state == XSDFEC_STARTED)
		return -EIO;

	if (bypass)
		xsdfec_regwrite(xsdfec, XSDFEC_BYPASS_ADDR, 1);
	else
		xsdfec_regwrite(xsdfec, XSDFEC_BYPASS_ADDR, 0);

	xsdfec->config.bypass = bypass;

	return 0;
}

static int xsdfec_is_active(struct xsdfec_dev *xsdfec, bool __user *arg)
{
	u32 reg_value;
	bool is_active;
	int err;

	reg_value = xsdfec_regread(xsdfec, XSDFEC_ACTIVE_ADDR);
	/* using a double ! operator instead of casting */
	is_active = !!(reg_value & XSDFEC_IS_ACTIVITY_SET);
	err = put_user(is_active, arg);
	if (err)
		return -EFAULT;

	return err;
}

static u32
xsdfec_translate_axis_width_cfg_val(enum xsdfec_axis_width axis_width_cfg)
{
@@ -681,6 +757,9 @@ static long xsdfec_dev_ioctl(struct file *fptr, unsigned int cmd,
	}

	switch (cmd) {
	case XSDFEC_GET_CONFIG:
		rval = xsdfec_get_config(xsdfec, arg);
		break;
	case XSDFEC_SET_TURBO:
		rval = xsdfec_set_turbo(xsdfec, arg);
		break;
@@ -690,6 +769,15 @@ static long xsdfec_dev_ioctl(struct file *fptr, unsigned int cmd,
	case XSDFEC_ADD_LDPC_CODE_PARAMS:
		rval = xsdfec_add_ldpc(xsdfec, arg);
		break;
	case XSDFEC_SET_ORDER:
		rval = xsdfec_set_order(xsdfec, arg);
		break;
	case XSDFEC_SET_BYPASS:
		rval = xsdfec_set_bypass(xsdfec, arg);
		break;
	case XSDFEC_IS_ACTIVE:
		rval = xsdfec_is_active(xsdfec, (bool __user *)arg);
		break;
	default:
		/* Should not get here */
		break;
+57 −0
Original line number Diff line number Diff line
@@ -287,6 +287,19 @@ struct xsdfec_ldpc_param_table_sizes {
 */
#define XSDFEC_ADD_LDPC_CODE_PARAMS                                            \
	_IOW(XSDFEC_MAGIC, 5, struct xsdfec_ldpc_params)
/**
 * DOC: XSDFEC_GET_CONFIG
 * @Parameters
 *
 * @struct xsdfec_config *
 *	Pointer to the &struct xsdfec_config that contains the current
 *	configuration settings of the SD-FEC Block
 *
 * @Description
 *
 * ioctl that returns SD-FEC core configuration
 */
#define XSDFEC_GET_CONFIG _IOR(XSDFEC_MAGIC, 6, struct xsdfec_config)
/**
 * DOC: XSDFEC_GET_TURBO
 * @Parameters
@@ -300,4 +313,48 @@ struct xsdfec_ldpc_param_table_sizes {
 * ioctl that returns SD-FEC turbo param values
 */
#define XSDFEC_GET_TURBO _IOR(XSDFEC_MAGIC, 7, struct xsdfec_turbo)
/**
 * DOC: XSDFEC_SET_ORDER
 * @Parameters
 *
 * @struct unsigned long *
 *	Pointer to the unsigned long that contains a value from the
 *	@enum xsdfec_order
 *
 * @Description
 *
 * ioctl that sets order, if order of blocks can change from input to output
 *
 * This can only be used when the driver is in the XSDFEC_STOPPED state
 */
#define XSDFEC_SET_ORDER _IOW(XSDFEC_MAGIC, 8, unsigned long)
/**
 * DOC: XSDFEC_SET_BYPASS
 * @Parameters
 *
 * @struct bool *
 *	Pointer to bool that sets the bypass value, where false results in
 *	normal operation and false results in the SD-FEC performing the
 *	configured operations (same number of cycles) but output data matches
 *	the input data
 *
 * @Description
 *
 * ioctl that sets bypass.
 *
 * This can only be used when the driver is in the XSDFEC_STOPPED state
 */
#define XSDFEC_SET_BYPASS _IOW(XSDFEC_MAGIC, 9, bool)
/**
 * DOC: XSDFEC_IS_ACTIVE
 * @Parameters
 *
 * @struct bool *
 *	Pointer to bool that returns true if the SD-FEC is processing data
 *
 * @Description
 *
 * ioctl that determines if SD-FEC is processing data
 */
#define XSDFEC_IS_ACTIVE _IOR(XSDFEC_MAGIC, 10, bool)
#endif /* __XILINX_SDFEC_H__ */