diff options
author | Dragan Cvetic <dragan.cvetic@xilinx.com> | 2019-07-27 11:33:54 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2019-08-15 18:54:38 +0300 |
commit | 77dd39d924e650cd20696d790f861dfe26e0cb64 (patch) | |
tree | 1706c2235448b83bc5dcad9032f981d9ddfbbe27 /drivers/misc/xilinx_sdfec.c | |
parent | 20ec628e8007ec75c2f884e00004f39eab6289b5 (diff) | |
download | linux-77dd39d924e650cd20696d790f861dfe26e0cb64.tar.xz |
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: Dragan Cvetic <dragan.cvetic@xilinx.com>
Signed-off-by: Derek Kiernan <derek.kiernan@xilinx.com>
Signed-off-by: Dragan Cvetic <dragan.cvetic@xilinx.com>
Link: https://lore.kernel.org/r/1564216438-322406-5-git-send-email-dragan.cvetic@xilinx.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/misc/xilinx_sdfec.c')
-rw-r--r-- | drivers/misc/xilinx_sdfec.c | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/drivers/misc/xilinx_sdfec.c b/drivers/misc/xilinx_sdfec.c index 9be4de07eee2..579f23617dd7 100644 --- a/drivers/misc/xilinx_sdfec.c +++ b/drivers/misc/xilinx_sdfec.c @@ -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; |