diff options
author | Tomas Winkler <tomas.winkler@intel.com> | 2018-11-22 06:11:36 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2018-11-26 10:59:48 -0500 |
commit | ce0925e8c2f85f6bbf5d24b56621336cceaf743d (patch) | |
tree | 0e97e539e9fb5ebde9f49ae32ffbd3e8ec7055c2 | |
parent | 986fb2e0532b1b0fa1e8312fbc38b9e7ed826547 (diff) |
mei: dma ring buffers allocation
Allocate DMA ring buffers from managed coherent memory.
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/misc/mei/Makefile | 1 | ||||
-rw-r--r-- | drivers/misc/mei/dma-ring.c | 99 | ||||
-rw-r--r-- | drivers/misc/mei/hw-me.c | 6 | ||||
-rw-r--r-- | drivers/misc/mei/mei_dev.h | 20 |
4 files changed, 126 insertions, 0 deletions
diff --git a/drivers/misc/mei/Makefile b/drivers/misc/mei/Makefile index cd6825afa8e1..d9215fc4e499 100644 --- a/drivers/misc/mei/Makefile +++ b/drivers/misc/mei/Makefile | |||
@@ -9,6 +9,7 @@ mei-objs += hbm.o | |||
9 | mei-objs += interrupt.o | 9 | mei-objs += interrupt.o |
10 | mei-objs += client.o | 10 | mei-objs += client.o |
11 | mei-objs += main.o | 11 | mei-objs += main.o |
12 | mei-objs += dma-ring.o | ||
12 | mei-objs += bus.o | 13 | mei-objs += bus.o |
13 | mei-objs += bus-fixup.o | 14 | mei-objs += bus-fixup.o |
14 | mei-$(CONFIG_DEBUG_FS) += debugfs.o | 15 | mei-$(CONFIG_DEBUG_FS) += debugfs.o |
diff --git a/drivers/misc/mei/dma-ring.c b/drivers/misc/mei/dma-ring.c new file mode 100644 index 000000000000..56f4c0882a20 --- /dev/null +++ b/drivers/misc/mei/dma-ring.c | |||
@@ -0,0 +1,99 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * Copyright(c) 2016 - 2018 Intel Corporation. All rights reserved. | ||
4 | */ | ||
5 | #include <linux/dma-mapping.h> | ||
6 | #include <linux/mei.h> | ||
7 | |||
8 | #include "mei_dev.h" | ||
9 | |||
10 | /** | ||
11 | * mei_dmam_dscr_alloc() - allocate a managed coherent buffer | ||
12 | * for the dma descriptor | ||
13 | * @dev: mei_device | ||
14 | * @dscr: dma descriptor | ||
15 | * | ||
16 | * Return: | ||
17 | * * 0 - on success or zero allocation request | ||
18 | * * -EINVAL - if size is not power of 2 | ||
19 | * * -ENOMEM - of allocation has failed | ||
20 | */ | ||
21 | static int mei_dmam_dscr_alloc(struct mei_device *dev, | ||
22 | struct mei_dma_dscr *dscr) | ||
23 | { | ||
24 | if (!dscr->size) | ||
25 | return 0; | ||
26 | |||
27 | if (WARN_ON(!is_power_of_2(dscr->size))) | ||
28 | return -EINVAL; | ||
29 | |||
30 | if (dscr->vaddr) | ||
31 | return 0; | ||
32 | |||
33 | dscr->vaddr = dmam_alloc_coherent(dev->dev, dscr->size, &dscr->daddr, | ||
34 | GFP_KERNEL); | ||
35 | if (!dscr->vaddr) | ||
36 | return -ENOMEM; | ||
37 | |||
38 | return 0; | ||
39 | } | ||
40 | |||
41 | /** | ||
42 | * mei_dmam_dscr_free() - free a managed coherent buffer | ||
43 | * from the dma descriptor | ||
44 | * @dev: mei_device | ||
45 | * @dscr: dma descriptor | ||
46 | */ | ||
47 | static void mei_dmam_dscr_free(struct mei_device *dev, | ||
48 | struct mei_dma_dscr *dscr) | ||
49 | { | ||
50 | if (!dscr->vaddr) | ||
51 | return; | ||
52 | |||
53 | dmam_free_coherent(dev->dev, dscr->size, dscr->vaddr, dscr->daddr); | ||
54 | dscr->vaddr = NULL; | ||
55 | } | ||
56 | |||
57 | /** | ||
58 | * mei_dmam_ring_free() - free dma ring buffers | ||
59 | * @dev: mei device | ||
60 | */ | ||
61 | void mei_dmam_ring_free(struct mei_device *dev) | ||
62 | { | ||
63 | int i; | ||
64 | |||
65 | for (i = 0; i < DMA_DSCR_NUM; i++) | ||
66 | mei_dmam_dscr_free(dev, &dev->dr_dscr[i]); | ||
67 | } | ||
68 | |||
69 | /** | ||
70 | * mei_dmam_ring_alloc() - allocate dma ring buffers | ||
71 | * @dev: mei device | ||
72 | * | ||
73 | * Return: -ENOMEM on allocation failure 0 otherwise | ||
74 | */ | ||
75 | int mei_dmam_ring_alloc(struct mei_device *dev) | ||
76 | { | ||
77 | int i; | ||
78 | |||
79 | for (i = 0; i < DMA_DSCR_NUM; i++) | ||
80 | if (mei_dmam_dscr_alloc(dev, &dev->dr_dscr[i])) | ||
81 | goto err; | ||
82 | |||
83 | return 0; | ||
84 | |||
85 | err: | ||
86 | mei_dmam_ring_free(dev); | ||
87 | return -ENOMEM; | ||
88 | } | ||
89 | |||
90 | /** | ||
91 | * mei_dma_ring_is_allocated() - check if dma ring is allocated | ||
92 | * @dev: mei device | ||
93 | * | ||
94 | * Return: true if dma ring is allocated | ||
95 | */ | ||
96 | bool mei_dma_ring_is_allocated(struct mei_device *dev) | ||
97 | { | ||
98 | return !!dev->dr_dscr[DMA_DSCR_HOST].vaddr; | ||
99 | } | ||
diff --git a/drivers/misc/mei/hw-me.c b/drivers/misc/mei/hw-me.c index 0759c3a668de..3fbbadfa2ae1 100644 --- a/drivers/misc/mei/hw-me.c +++ b/drivers/misc/mei/hw-me.c | |||
@@ -1471,15 +1471,21 @@ struct mei_device *mei_me_dev_init(struct pci_dev *pdev, | |||
1471 | { | 1471 | { |
1472 | struct mei_device *dev; | 1472 | struct mei_device *dev; |
1473 | struct mei_me_hw *hw; | 1473 | struct mei_me_hw *hw; |
1474 | int i; | ||
1474 | 1475 | ||
1475 | dev = devm_kzalloc(&pdev->dev, sizeof(struct mei_device) + | 1476 | dev = devm_kzalloc(&pdev->dev, sizeof(struct mei_device) + |
1476 | sizeof(struct mei_me_hw), GFP_KERNEL); | 1477 | sizeof(struct mei_me_hw), GFP_KERNEL); |
1477 | if (!dev) | 1478 | if (!dev) |
1478 | return NULL; | 1479 | return NULL; |
1480 | |||
1479 | hw = to_me_hw(dev); | 1481 | hw = to_me_hw(dev); |
1480 | 1482 | ||
1483 | for (i = 0; i < DMA_DSCR_NUM; i++) | ||
1484 | dev->dr_dscr[i].size = cfg->dma_size[i]; | ||
1485 | |||
1481 | mei_device_init(dev, &pdev->dev, &mei_me_hw_ops); | 1486 | mei_device_init(dev, &pdev->dev, &mei_me_hw_ops); |
1482 | hw->cfg = cfg; | 1487 | hw->cfg = cfg; |
1488 | |||
1483 | return dev; | 1489 | return dev; |
1484 | } | 1490 | } |
1485 | 1491 | ||
diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index 377397e1b5a5..a6796e3f712b 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h | |||
@@ -122,6 +122,19 @@ struct mei_msg_data { | |||
122 | unsigned char *data; | 122 | unsigned char *data; |
123 | }; | 123 | }; |
124 | 124 | ||
125 | /** | ||
126 | * struct mei_dma_dscr - dma address descriptor | ||
127 | * | ||
128 | * @vaddr: dma buffer virtual address | ||
129 | * @daddr: dma buffer physical address | ||
130 | * @size : dma buffer size | ||
131 | */ | ||
132 | struct mei_dma_dscr { | ||
133 | void *vaddr; | ||
134 | dma_addr_t daddr; | ||
135 | size_t size; | ||
136 | }; | ||
137 | |||
125 | /* Maximum number of processed FW status registers */ | 138 | /* Maximum number of processed FW status registers */ |
126 | #define MEI_FW_STATUS_MAX 6 | 139 | #define MEI_FW_STATUS_MAX 6 |
127 | /* Minimal buffer for FW status string (8 bytes in dw + space or '\0') */ | 140 | /* Minimal buffer for FW status string (8 bytes in dw + space or '\0') */ |
@@ -409,6 +422,7 @@ struct mei_fw_version { | |||
409 | * @rd_msg_hdr : read message header storage | 422 | * @rd_msg_hdr : read message header storage |
410 | * | 423 | * |
411 | * @hbuf_is_ready : query if the host host/write buffer is ready | 424 | * @hbuf_is_ready : query if the host host/write buffer is ready |
425 | * @dr_dscr: DMA ring descriptors: TX, RX, and CTRL | ||
412 | * | 426 | * |
413 | * @version : HBM protocol version in use | 427 | * @version : HBM protocol version in use |
414 | * @hbm_f_pg_supported : hbm feature pgi protocol | 428 | * @hbm_f_pg_supported : hbm feature pgi protocol |
@@ -488,6 +502,8 @@ struct mei_device { | |||
488 | /* write buffer */ | 502 | /* write buffer */ |
489 | bool hbuf_is_ready; | 503 | bool hbuf_is_ready; |
490 | 504 | ||
505 | struct mei_dma_dscr dr_dscr[DMA_DSCR_NUM]; | ||
506 | |||
491 | struct hbm_version version; | 507 | struct hbm_version version; |
492 | unsigned int hbm_f_pg_supported:1; | 508 | unsigned int hbm_f_pg_supported:1; |
493 | unsigned int hbm_f_dc_supported:1; | 509 | unsigned int hbm_f_dc_supported:1; |
@@ -578,6 +594,10 @@ int mei_restart(struct mei_device *dev); | |||
578 | void mei_stop(struct mei_device *dev); | 594 | void mei_stop(struct mei_device *dev); |
579 | void mei_cancel_work(struct mei_device *dev); | 595 | void mei_cancel_work(struct mei_device *dev); |
580 | 596 | ||
597 | int mei_dmam_ring_alloc(struct mei_device *dev); | ||
598 | void mei_dmam_ring_free(struct mei_device *dev); | ||
599 | bool mei_dma_ring_is_allocated(struct mei_device *dev); | ||
600 | |||
581 | /* | 601 | /* |
582 | * MEI interrupt functions prototype | 602 | * MEI interrupt functions prototype |
583 | */ | 603 | */ |