.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* |
---|
2 | 3 | * RapidIO mport character device |
---|
3 | 4 | * |
---|
.. | .. |
---|
8 | 9 | * Jerry Jacobs <jerry.jacobs@prodrive-technologies.com> |
---|
9 | 10 | * Copyright (C) 2014 Texas Instruments Incorporated |
---|
10 | 11 | * 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. |
---|
16 | 12 | */ |
---|
17 | 13 | #include <linux/module.h> |
---|
18 | 14 | #include <linux/kernel.h> |
---|
.. | .. |
---|
576 | 572 | struct mport_dma_req *req = container_of(ref, struct mport_dma_req, |
---|
577 | 573 | refcount); |
---|
578 | 574 | struct mport_cdev_priv *priv = req->priv; |
---|
579 | | - unsigned int i; |
---|
580 | 575 | |
---|
581 | 576 | dma_unmap_sg(req->dmach->device->dev, |
---|
582 | 577 | req->sgt.sgl, req->sgt.nents, req->dir); |
---|
583 | 578 | sg_free_table(&req->sgt); |
---|
584 | 579 | 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); |
---|
587 | 581 | kfree(req->page_list); |
---|
588 | 582 | } |
---|
589 | 583 | |
---|
.. | .. |
---|
819 | 813 | struct mport_dma_req *req; |
---|
820 | 814 | struct mport_dev *md = priv->md; |
---|
821 | 815 | struct dma_chan *chan; |
---|
822 | | - int i, ret; |
---|
| 816 | + int ret; |
---|
823 | 817 | int nents; |
---|
824 | 818 | |
---|
825 | 819 | if (xfer->length == 0) |
---|
.. | .. |
---|
866 | 860 | goto err_req; |
---|
867 | 861 | } |
---|
868 | 862 | |
---|
869 | | - pinned = get_user_pages_fast( |
---|
| 863 | + pinned = pin_user_pages_fast( |
---|
870 | 864 | (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); |
---|
872 | 868 | |
---|
873 | 869 | if (pinned != nr_pages) { |
---|
874 | 870 | if (pinned < 0) { |
---|
875 | | - rmcd_error("get_user_pages_unlocked err=%ld", |
---|
| 871 | + rmcd_error("pin_user_pages_fast err=%ld", |
---|
876 | 872 | pinned); |
---|
877 | 873 | nr_pages = 0; |
---|
878 | 874 | } else { |
---|
.. | .. |
---|
954 | 950 | |
---|
955 | 951 | err_pg: |
---|
956 | 952 | 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); |
---|
959 | 954 | kfree(page_list); |
---|
960 | 955 | } |
---|
961 | 956 | err_req: |
---|
.. | .. |
---|
987 | 982 | |
---|
988 | 983 | if (unlikely(copy_from_user(transfer, |
---|
989 | 984 | (void __user *)(uintptr_t)transaction.block, |
---|
990 | | - transaction.count * sizeof(*transfer)))) { |
---|
| 985 | + array_size(sizeof(*transfer), transaction.count)))) { |
---|
991 | 986 | ret = -EFAULT; |
---|
992 | 987 | goto out_free; |
---|
993 | 988 | } |
---|
.. | .. |
---|
1000 | 995 | |
---|
1001 | 996 | if (unlikely(copy_to_user((void __user *)(uintptr_t)transaction.block, |
---|
1002 | 997 | transfer, |
---|
1003 | | - transaction.count * sizeof(*transfer)))) |
---|
| 998 | + array_size(sizeof(*transfer), transaction.count)))) |
---|
1004 | 999 | ret = -EFAULT; |
---|
1005 | 1000 | |
---|
1006 | 1001 | out_free: |
---|
.. | .. |
---|
1719 | 1714 | if (rval & RIO_PEF_SWITCH) { |
---|
1720 | 1715 | rio_mport_read_config_32(mport, destid, hopcount, |
---|
1721 | 1716 | 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)); |
---|
1724 | 1718 | } |
---|
1725 | 1719 | |
---|
1726 | 1720 | rdev = kzalloc(size, GFP_KERNEL); |
---|
.. | .. |
---|
2160 | 2154 | switch (map->dir) { |
---|
2161 | 2155 | case MAP_INBOUND: |
---|
2162 | 2156 | rio_unmap_inb_region(mport, map->phys_addr); |
---|
| 2157 | + fallthrough; |
---|
2163 | 2158 | case MAP_DMA: |
---|
2164 | 2159 | dma_free_coherent(mport->dev.parent, map->size, |
---|
2165 | 2160 | map->virt_addr, map->phys_addr); |
---|