aboutsummaryrefslogtreecommitdiff
path: root/drivers/misc/xilinx_sdfec.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2020-06-07 10:59:32 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2020-06-07 10:59:32 -0700
commit9aa900c8094dba7a60dc805ecec1e9f720744ba1 (patch)
tree3cc09a579f8ea6d3a182076ba722f7c1648e682d /drivers/misc/xilinx_sdfec.c
parentf558b8364e19f9222e7976c64e9367f66bab02cc (diff)
parent05c8a4fc44a916dd897769ca69b42381f9177ec4 (diff)
downloadlinux-9aa900c8094dba7a60dc805ecec1e9f720744ba1.tar.gz
linux-9aa900c8094dba7a60dc805ecec1e9f720744ba1.tar.bz2
linux-9aa900c8094dba7a60dc805ecec1e9f720744ba1.zip
Merge tag 'char-misc-5.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc
Pull char/misc driver updates from Greg KH: "Here is the large set of char/misc driver patches for 5.8-rc1 Included in here are: - habanalabs driver updates, loads - mhi bus driver updates - extcon driver updates - clk driver updates (approved by the clock maintainer) - firmware driver updates - fpga driver updates - gnss driver updates - coresight driver updates - interconnect driver updates - parport driver updates (it's still alive!) - nvmem driver updates - soundwire driver updates - visorbus driver updates - w1 driver updates - various misc driver updates In short, loads of different driver subsystem updates along with the drivers as well. All have been in linux-next for a while with no reported issues" * tag 'char-misc-5.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (233 commits) habanalabs: correctly cast u64 to void* habanalabs: initialize variable to default value extcon: arizona: Fix runtime PM imbalance on error extcon: max14577: Add proper dt-compatible strings extcon: adc-jack: Fix an error handling path in 'adc_jack_probe()' extcon: remove redundant assignment to variable idx w1: omap-hdq: print dev_err if irq flags are not cleared w1: omap-hdq: fix interrupt handling which did show spurious timeouts w1: omap-hdq: fix return value to be -1 if there is a timeout w1: omap-hdq: cleanup to add missing newline for some dev_dbg /dev/mem: Revoke mappings when a driver claims the region misc: xilinx-sdfec: convert get_user_pages() --> pin_user_pages() misc: xilinx-sdfec: cleanup return value in xsdfec_table_write() misc: xilinx-sdfec: improve get_user_pages_fast() error handling nvmem: qfprom: remove incorrect write support habanalabs: handle MMU cache invalidation timeout habanalabs: don't allow hard reset with open processes habanalabs: GAUDI does not support soft-reset habanalabs: add print for soft reset due to event habanalabs: improve MMU cache invalidation code ...
Diffstat (limited to 'drivers/misc/xilinx_sdfec.c')
-rw-r--r--drivers/misc/xilinx_sdfec.c61
1 files changed, 21 insertions, 40 deletions
diff --git a/drivers/misc/xilinx_sdfec.c b/drivers/misc/xilinx_sdfec.c
index 71bbaa56bdb5..92291292756a 100644
--- a/drivers/misc/xilinx_sdfec.c
+++ b/drivers/misc/xilinx_sdfec.c
@@ -602,10 +602,10 @@ static int xsdfec_table_write(struct xsdfec_dev *xsdfec, u32 offset,
const u32 depth)
{
u32 reg = 0;
- u32 res;
- u32 n, i;
+ int res, i, nr_pages;
+ u32 n;
u32 *addr = NULL;
- struct page *page[MAX_NUM_PAGES];
+ struct page *pages[MAX_NUM_PAGES];
/*
* Writes that go beyond the length of
@@ -622,15 +622,21 @@ static int xsdfec_table_write(struct xsdfec_dev *xsdfec, u32 offset,
if ((len * XSDFEC_REG_WIDTH_JUMP) % PAGE_SIZE)
n += 1;
- res = get_user_pages_fast((unsigned long)src_ptr, n, 0, page);
- if (res < n) {
- for (i = 0; i < res; i++)
- put_page(page[i]);
+ if (WARN_ON_ONCE(n > INT_MAX))
+ return -EINVAL;
+
+ nr_pages = n;
+
+ res = pin_user_pages_fast((unsigned long)src_ptr, nr_pages, 0, pages);
+ if (res < nr_pages) {
+ if (res > 0)
+ unpin_user_pages(pages, res);
+
return -EINVAL;
}
- for (i = 0; i < n; i++) {
- addr = kmap(page[i]);
+ for (i = 0; i < nr_pages; i++) {
+ addr = kmap(pages[i]);
do {
xsdfec_regwrite(xsdfec,
base_addr + ((offset + reg) *
@@ -639,9 +645,9 @@ static int xsdfec_table_write(struct xsdfec_dev *xsdfec, u32 offset,
reg++;
} while ((reg < len) &&
((reg * XSDFEC_REG_WIDTH_JUMP) % PAGE_SIZE));
- put_page(page[i]);
+ unpin_user_page(pages[i]);
}
- return reg;
+ return 0;
}
static int xsdfec_add_ldpc(struct xsdfec_dev *xsdfec, void __user *arg)
@@ -649,14 +655,9 @@ static int xsdfec_add_ldpc(struct xsdfec_dev *xsdfec, void __user *arg)
struct xsdfec_ldpc_params *ldpc;
int ret, n;
- ldpc = kzalloc(sizeof(*ldpc), GFP_KERNEL);
- if (!ldpc)
- return -ENOMEM;
-
- if (copy_from_user(ldpc, arg, sizeof(*ldpc))) {
- ret = -EFAULT;
- goto err_out;
- }
+ ldpc = memdup_user(arg, sizeof(*ldpc));
+ if (IS_ERR(ldpc))
+ return PTR_ERR(ldpc);
if (xsdfec->config.code == XSDFEC_TURBO_CODE) {
ret = -EIO;
@@ -720,8 +721,6 @@ static int xsdfec_add_ldpc(struct xsdfec_dev *xsdfec, void __user *arg)
ret = xsdfec_table_write(xsdfec, 4 * ldpc->qc_off, ldpc->qc_table,
ldpc->nqc, XSDFEC_LDPC_QC_TABLE_ADDR_BASE,
XSDFEC_QC_TABLE_DEPTH);
- if (ret > 0)
- ret = 0;
err_out:
kfree(ldpc);
return ret;
@@ -1484,25 +1483,7 @@ static struct platform_driver xsdfec_driver = {
.remove = xsdfec_remove,
};
-static int __init xsdfec_init(void)
-{
- int err;
-
- err = platform_driver_register(&xsdfec_driver);
- if (err < 0) {
- pr_err("%s Unabled to register SDFEC driver", __func__);
- return err;
- }
- return 0;
-}
-
-static void __exit xsdfec_exit(void)
-{
- platform_driver_unregister(&xsdfec_driver);
-}
-
-module_init(xsdfec_init);
-module_exit(xsdfec_exit);
+module_platform_driver(xsdfec_driver);
MODULE_AUTHOR("Xilinx, Inc");
MODULE_DESCRIPTION("Xilinx SD-FEC16 Driver");