forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-01-31 f70575805708cabdedea7498aaa3f710fde4d920
kernel/drivers/rapidio/devices/rio_mport_cdev.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * RapidIO mport character device
34 *
....@@ -8,11 +9,6 @@
89 * Jerry Jacobs <jerry.jacobs@prodrive-technologies.com>
910 * Copyright (C) 2014 Texas Instruments Incorporated
1011 * Aurelien Jacquiot <a-jacquiot@ti.com>
11
- *
12
- * This program is free software; you can redistribute it and/or modify it
13
- * under the terms of the GNU General Public License as published by the
14
- * Free Software Foundation; either version 2 of the License, or (at your
15
- * option) any later version.
1612 */
1713 #include <linux/module.h>
1814 #include <linux/kernel.h>
....@@ -576,14 +572,12 @@
576572 struct mport_dma_req *req = container_of(ref, struct mport_dma_req,
577573 refcount);
578574 struct mport_cdev_priv *priv = req->priv;
579
- unsigned int i;
580575
581576 dma_unmap_sg(req->dmach->device->dev,
582577 req->sgt.sgl, req->sgt.nents, req->dir);
583578 sg_free_table(&req->sgt);
584579 if (req->page_list) {
585
- for (i = 0; i < req->nr_pages; i++)
586
- put_page(req->page_list[i]);
580
+ unpin_user_pages(req->page_list, req->nr_pages);
587581 kfree(req->page_list);
588582 }
589583
....@@ -819,7 +813,7 @@
819813 struct mport_dma_req *req;
820814 struct mport_dev *md = priv->md;
821815 struct dma_chan *chan;
822
- int i, ret;
816
+ int ret;
823817 int nents;
824818
825819 if (xfer->length == 0)
....@@ -866,13 +860,15 @@
866860 goto err_req;
867861 }
868862
869
- pinned = get_user_pages_fast(
863
+ pinned = pin_user_pages_fast(
870864 (unsigned long)xfer->loc_addr & PAGE_MASK,
871
- nr_pages, dir == DMA_FROM_DEVICE, page_list);
865
+ nr_pages,
866
+ dir == DMA_FROM_DEVICE ? FOLL_WRITE : 0,
867
+ page_list);
872868
873869 if (pinned != nr_pages) {
874870 if (pinned < 0) {
875
- rmcd_error("get_user_pages_unlocked err=%ld",
871
+ rmcd_error("pin_user_pages_fast err=%ld",
876872 pinned);
877873 nr_pages = 0;
878874 } else {
....@@ -954,8 +950,7 @@
954950
955951 err_pg:
956952 if (!req->page_list) {
957
- for (i = 0; i < nr_pages; i++)
958
- put_page(page_list[i]);
953
+ unpin_user_pages(page_list, nr_pages);
959954 kfree(page_list);
960955 }
961956 err_req:
....@@ -987,7 +982,7 @@
987982
988983 if (unlikely(copy_from_user(transfer,
989984 (void __user *)(uintptr_t)transaction.block,
990
- transaction.count * sizeof(*transfer)))) {
985
+ array_size(sizeof(*transfer), transaction.count)))) {
991986 ret = -EFAULT;
992987 goto out_free;
993988 }
....@@ -1000,7 +995,7 @@
1000995
1001996 if (unlikely(copy_to_user((void __user *)(uintptr_t)transaction.block,
1002997 transfer,
1003
- transaction.count * sizeof(*transfer))))
998
+ array_size(sizeof(*transfer), transaction.count))))
1004999 ret = -EFAULT;
10051000
10061001 out_free:
....@@ -1719,8 +1714,7 @@
17191714 if (rval & RIO_PEF_SWITCH) {
17201715 rio_mport_read_config_32(mport, destid, hopcount,
17211716 RIO_SWP_INFO_CAR, &swpinfo);
1722
- size += (RIO_GET_TOTAL_PORTS(swpinfo) *
1723
- sizeof(rswitch->nextdev[0])) + sizeof(*rswitch);
1717
+ size += struct_size(rswitch, nextdev, RIO_GET_TOTAL_PORTS(swpinfo));
17241718 }
17251719
17261720 rdev = kzalloc(size, GFP_KERNEL);
....@@ -1809,8 +1803,11 @@
18091803 rio_init_dbell_res(&rdev->riores[RIO_DOORBELL_RESOURCE],
18101804 0, 0xffff);
18111805 err = rio_add_device(rdev);
1812
- if (err)
1813
- goto cleanup;
1806
+ if (err) {
1807
+ put_device(&rdev->dev);
1808
+ return err;
1809
+ }
1810
+
18141811 rio_dev_get(rdev);
18151812
18161813 return 0;
....@@ -1906,10 +1903,6 @@
19061903
19071904 priv->md = chdev;
19081905
1909
- mutex_lock(&chdev->file_mutex);
1910
- list_add_tail(&priv->list, &chdev->file_list);
1911
- mutex_unlock(&chdev->file_mutex);
1912
-
19131906 INIT_LIST_HEAD(&priv->db_filters);
19141907 INIT_LIST_HEAD(&priv->pw_filters);
19151908 spin_lock_init(&priv->fifo_lock);
....@@ -1918,6 +1911,7 @@
19181911 sizeof(struct rio_event) * MPORT_EVENT_DEPTH,
19191912 GFP_KERNEL);
19201913 if (ret < 0) {
1914
+ put_device(&chdev->dev);
19211915 dev_err(&chdev->dev, DRV_NAME ": kfifo_alloc failed\n");
19221916 ret = -ENOMEM;
19231917 goto err_fifo;
....@@ -1928,6 +1922,9 @@
19281922 spin_lock_init(&priv->req_lock);
19291923 mutex_init(&priv->dma_lock);
19301924 #endif
1925
+ mutex_lock(&chdev->file_mutex);
1926
+ list_add_tail(&priv->list, &chdev->file_list);
1927
+ mutex_unlock(&chdev->file_mutex);
19311928
19321929 filp->private_data = priv;
19331930 goto out;
....@@ -2160,6 +2157,7 @@
21602157 switch (map->dir) {
21612158 case MAP_INBOUND:
21622159 rio_unmap_inb_region(mport, map->phys_addr);
2160
+ fallthrough;
21632161 case MAP_DMA:
21642162 dma_free_coherent(mport->dev.parent, map->size,
21652163 map->virt_addr, map->phys_addr);