Allow SRCREV handling through poky-agl.conf
[AGL/meta-agl-demo.git] / recipes-kernel / most / files / 0001-let-HDMs-do-the-coherent-memory-allocation.patch
1 From b4fe384dde3e230d8c252525fcd5297015b147d1 Mon Sep 17 00:00:00 2001
2 From: Christian Gromm <christian.gromm@microchip.com>
3 Date: Wed, 2 Aug 2017 14:51:20 +0200
4 Subject: [PATCH 1/5] let HDMs do the coherent memory allocation
5
6 On arm64/aarch64 architectures the allocation of coherent memory
7 needs a device that has the dma_ops proberly set. That's why the
8 core module of the MOST driver is no longer able to allocate this
9 kind of memory. This patch moves the allocation process down to
10 the HDM layer where the proper devices exist in either the USB
11 host controller or the platform device.
12
13 Signed-off-by: Christian Gromm <christian.gromm@microchip.com>
14
15
16 Signed-off-by: Christian Gromm <christian.gromm@microchip.com>
17 ---
18  driver/hdm-dim2/dim2_hdm.c | 12 ++++++++++++
19  driver/hdm-usb/hdm_usb.c   | 18 ++++++++++++++++++
20  driver/include/mostcore.h  |  2 ++
21  driver/mostcore/core.c     | 17 +++++++++++------
22  4 files changed, 43 insertions(+), 6 deletions(-)
23
24 diff --git a/hdm-dim2/dim2_hdm.c b/hdm-dim2/dim2_hdm.c
25 index 35aee9f..1b164cf 100644
26 --- a/hdm-dim2/dim2_hdm.c
27 +++ b/hdm-dim2/dim2_hdm.c
28 @@ -722,6 +722,16 @@ static int poison_channel(struct most_interface *most_iface, int ch_idx)
29         return ret;
30  }
31  
32 +static void *dma_alloc(struct mbo *mbo, u32 size)
33 +{
34 +       return dma_alloc_coherent(NULL, size, &mbo->bus_address, GFP_KERNEL);
35 +}
36 +
37 +static void dma_free(struct mbo *mbo, u32 size)
38 +{
39 +       dma_free_coherent(NULL, size, mbo->virt_address, mbo->bus_address);
40 +}
41 +
42  /*
43   * dim2_probe - dim2 probe handler
44   * @pdev: platform device structure
45 @@ -820,6 +830,8 @@ static int dim2_probe(struct platform_device *pdev)
46         dev->most_iface.channel_vector = dev->capabilities;
47         dev->most_iface.configure = configure_channel;
48         dev->most_iface.enqueue = enqueue;
49 +       dev->most_iface.dma_alloc = dma_alloc;
50 +       dev->most_iface.dma_free = dma_free;
51         dev->most_iface.poison_channel = poison_channel;
52         dev->most_iface.request_netinfo = request_netinfo;
53  
54 diff --git a/hdm-usb/hdm_usb.c b/hdm-usb/hdm_usb.c
55 index 3433646..0b689b5 100644
56 --- a/hdm-usb/hdm_usb.c
57 +++ b/hdm-usb/hdm_usb.c
58 @@ -629,6 +629,22 @@ _error:
59         return retval;
60  }
61  
62 +static void *hdm_dma_alloc(struct mbo *mbo, u32 size)
63 +{
64 +       struct most_dev *mdev = to_mdev(mbo->ifp);
65 +
66 +       return usb_alloc_coherent(mdev->usb_device, size, GFP_KERNEL,
67 +                                 &mbo->bus_address);
68 +}
69 +
70 +static void hdm_dma_free(struct mbo *mbo, u32 size)
71 +{
72 +       struct most_dev *mdev = to_mdev(mbo->ifp);
73 +
74 +       usb_free_coherent(mdev->usb_device, size, mbo->virt_address,
75 +                         mbo->bus_address);
76 +}
77 +
78  /**
79   * hdm_configure_channel - receive channel configuration from core
80   * @iface: interface
81 @@ -1140,6 +1156,8 @@ hdm_probe(struct usb_interface *interface, const struct usb_device_id *id)
82         mdev->iface.request_netinfo = hdm_request_netinfo;
83         mdev->iface.enqueue = hdm_enqueue;
84         mdev->iface.poison_channel = hdm_poison_channel;
85 +       mdev->iface.dma_alloc = hdm_dma_alloc;
86 +       mdev->iface.dma_free = hdm_dma_free;
87         mdev->iface.description = mdev->description;
88         mdev->iface.num_channels = num_endpoints;
89  
90 diff --git a/include/mostcore.h b/include/mostcore.h
91 index 5f8339b..deefe25 100644
92 --- a/include/mostcore.h
93 +++ b/include/mostcore.h
94 @@ -241,6 +241,8 @@ struct most_interface {
95         const char *description;
96         int num_channels;
97         struct most_channel_capability *channel_vector;
98 +       void *(*dma_alloc)(struct mbo *mbo, u32 size);
99 +       void (*dma_free)(struct mbo *mbo, u32 size);
100         int (*configure)(struct most_interface *iface, int channel_idx,
101                          struct most_channel_config *channel_config);
102         int (*enqueue)(struct most_interface *iface, int channel_idx,
103 diff --git a/mostcore/core.c b/mostcore/core.c
104 index 4c580d1..931efb9 100644
105 --- a/mostcore/core.c
106 +++ b/mostcore/core.c
107 @@ -184,8 +184,10 @@ static void most_free_mbo_coherent(struct mbo *mbo)
108         struct most_c_obj *c = mbo->context;
109         u16 const coherent_buf_size = c->cfg.buffer_size + c->cfg.extra_len;
110  
111 -       dma_free_coherent(NULL, coherent_buf_size, mbo->virt_address,
112 -                         mbo->bus_address);
113 +       if (c->iface->dma_free)
114 +               c->iface->dma_free(mbo, coherent_buf_size);
115 +       else
116 +               kfree(mbo->virt_address);
117         kfree(mbo);
118         if (atomic_sub_and_test(1, &c->mbo_ref))
119                 complete(&c->cleanup);
120 @@ -1289,10 +1291,13 @@ static int arm_mbo_chain(struct most_c_obj *c, int dir,
121                 mbo->context = c;
122                 mbo->ifp = c->iface;
123                 mbo->hdm_channel_id = c->channel_id;
124 -               mbo->virt_address = dma_alloc_coherent(NULL,
125 -                                                      coherent_buf_size,
126 -                                                      &mbo->bus_address,
127 -                                                      GFP_KERNEL);
128 +               if (c->iface->dma_alloc) {
129 +                       mbo->virt_address =
130 +                               c->iface->dma_alloc(mbo, coherent_buf_size);
131 +               } else {
132 +                       mbo->virt_address =
133 +                               kzalloc(coherent_buf_size, GFP_KERNEL);
134 +               }
135                 if (!mbo->virt_address) {
136                         pr_info("WARN: No DMA coherent buffer.\n");
137                         retval = i;
138 -- 
139 2.7.4
140