diff options
Diffstat (limited to 'drivers/crypto/ccp/ccp-dmaengine.c')
-rw-r--r-- | drivers/crypto/ccp/ccp-dmaengine.c | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/drivers/crypto/ccp/ccp-dmaengine.c b/drivers/crypto/ccp/ccp-dmaengine.c index 8d0eeb46d4a2..e00be01fbf5a 100644 --- a/drivers/crypto/ccp/ccp-dmaengine.c +++ b/drivers/crypto/ccp/ccp-dmaengine.c | |||
@@ -10,6 +10,7 @@ | |||
10 | * published by the Free Software Foundation. | 10 | * published by the Free Software Foundation. |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/module.h> | ||
13 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
14 | #include <linux/dmaengine.h> | 15 | #include <linux/dmaengine.h> |
15 | #include <linux/spinlock.h> | 16 | #include <linux/spinlock.h> |
@@ -25,6 +26,37 @@ | |||
25 | (mask == 0) ? 64 : fls64(mask); \ | 26 | (mask == 0) ? 64 : fls64(mask); \ |
26 | }) | 27 | }) |
27 | 28 | ||
29 | /* The CCP as a DMA provider can be configured for public or private | ||
30 | * channels. Default is specified in the vdata for the device (PCI ID). | ||
31 | * This module parameter will override for all channels on all devices: | ||
32 | * dma_chan_attr = 0x2 to force all channels public | ||
33 | * = 0x1 to force all channels private | ||
34 | * = 0x0 to defer to the vdata setting | ||
35 | * = any other value: warning, revert to 0x0 | ||
36 | */ | ||
37 | static unsigned int dma_chan_attr = CCP_DMA_DFLT; | ||
38 | module_param(dma_chan_attr, uint, 0444); | ||
39 | MODULE_PARM_DESC(dma_chan_attr, "Set DMA channel visibility: 0 (default) = device defaults, 1 = make private, 2 = make public"); | ||
40 | |||
41 | unsigned int ccp_get_dma_chan_attr(struct ccp_device *ccp) | ||
42 | { | ||
43 | switch (dma_chan_attr) { | ||
44 | case CCP_DMA_DFLT: | ||
45 | return ccp->vdata->dma_chan_attr; | ||
46 | |||
47 | case CCP_DMA_PRIV: | ||
48 | return DMA_PRIVATE; | ||
49 | |||
50 | case CCP_DMA_PUB: | ||
51 | return 0; | ||
52 | |||
53 | default: | ||
54 | dev_info_once(ccp->dev, "Invalid value for dma_chan_attr: %d\n", | ||
55 | dma_chan_attr); | ||
56 | return ccp->vdata->dma_chan_attr; | ||
57 | } | ||
58 | } | ||
59 | |||
28 | static void ccp_free_cmd_resources(struct ccp_device *ccp, | 60 | static void ccp_free_cmd_resources(struct ccp_device *ccp, |
29 | struct list_head *list) | 61 | struct list_head *list) |
30 | { | 62 | { |
@@ -675,6 +707,15 @@ int ccp_dmaengine_register(struct ccp_device *ccp) | |||
675 | dma_cap_set(DMA_SG, dma_dev->cap_mask); | 707 | dma_cap_set(DMA_SG, dma_dev->cap_mask); |
676 | dma_cap_set(DMA_INTERRUPT, dma_dev->cap_mask); | 708 | dma_cap_set(DMA_INTERRUPT, dma_dev->cap_mask); |
677 | 709 | ||
710 | /* The DMA channels for this device can be set to public or private, | ||
711 | * and overridden by the module parameter dma_chan_attr. | ||
712 | * Default: according to the value in vdata (dma_chan_attr=0) | ||
713 | * dma_chan_attr=0x1: all channels private (override vdata) | ||
714 | * dma_chan_attr=0x2: all channels public (override vdata) | ||
715 | */ | ||
716 | if (ccp_get_dma_chan_attr(ccp) == DMA_PRIVATE) | ||
717 | dma_cap_set(DMA_PRIVATE, dma_dev->cap_mask); | ||
718 | |||
678 | INIT_LIST_HEAD(&dma_dev->channels); | 719 | INIT_LIST_HEAD(&dma_dev->channels); |
679 | for (i = 0; i < ccp->cmd_q_count; i++) { | 720 | for (i = 0; i < ccp->cmd_q_count; i++) { |
680 | chan = ccp->ccp_dma_chan + i; | 721 | chan = ccp->ccp_dma_chan + i; |