staging: most: make interface drivers allocate coherent memory
On arm64/aarch64 architectures the allocation of coherent memory needs a device that has the dma_ops properly set. That's why the core module of the MOST driver is no longer able to allocate this type or memory. This patch moves the allocation process down to the interface drivers where the proper devices exist (e.g. platform device or USB system software). Signed-off-by: Christian Gromm <christian.gromm@microchip.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
7e6e228873
commit
3598cec585
|
@ -111,8 +111,10 @@ static void most_free_mbo_coherent(struct mbo *mbo)
|
|||
struct most_channel *c = mbo->context;
|
||||
u16 const coherent_buf_size = c->cfg.buffer_size + c->cfg.extra_len;
|
||||
|
||||
dma_free_coherent(NULL, coherent_buf_size, mbo->virt_address,
|
||||
mbo->bus_address);
|
||||
if (c->iface->dma_free)
|
||||
c->iface->dma_free(mbo, coherent_buf_size);
|
||||
else
|
||||
kfree(mbo->virt_address);
|
||||
kfree(mbo);
|
||||
if (atomic_sub_and_test(1, &c->mbo_ref))
|
||||
complete(&c->cleanup);
|
||||
|
@ -988,10 +990,13 @@ static int arm_mbo_chain(struct most_channel *c, int dir,
|
|||
mbo->context = c;
|
||||
mbo->ifp = c->iface;
|
||||
mbo->hdm_channel_id = c->channel_id;
|
||||
mbo->virt_address = dma_alloc_coherent(NULL,
|
||||
coherent_buf_size,
|
||||
&mbo->bus_address,
|
||||
GFP_KERNEL);
|
||||
if (c->iface->dma_alloc) {
|
||||
mbo->virt_address =
|
||||
c->iface->dma_alloc(mbo, coherent_buf_size);
|
||||
} else {
|
||||
mbo->virt_address =
|
||||
kzalloc(coherent_buf_size, GFP_KERNEL);
|
||||
}
|
||||
if (!mbo->virt_address)
|
||||
goto release_mbo;
|
||||
|
||||
|
|
|
@ -235,6 +235,8 @@ struct most_interface {
|
|||
const char *description;
|
||||
unsigned int num_channels;
|
||||
struct most_channel_capability *channel_vector;
|
||||
void *(*dma_alloc)(struct mbo *mbo, u32 size);
|
||||
void (*dma_free)(struct mbo *mbo, u32 size);
|
||||
int (*configure)(struct most_interface *iface, int channel_idx,
|
||||
struct most_channel_config *channel_config);
|
||||
int (*enqueue)(struct most_interface *iface, int channel_idx,
|
||||
|
|
|
@ -703,6 +703,16 @@ static int poison_channel(struct most_interface *most_iface, int ch_idx)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void *dma_alloc(struct mbo *mbo, u32 size)
|
||||
{
|
||||
return dma_alloc_coherent(NULL, size, &mbo->bus_address, GFP_KERNEL);
|
||||
}
|
||||
|
||||
static void dma_free(struct mbo *mbo, u32 size)
|
||||
{
|
||||
dma_free_coherent(NULL, size, mbo->virt_address, mbo->bus_address);
|
||||
}
|
||||
|
||||
/*
|
||||
* dim2_probe - dim2 probe handler
|
||||
* @pdev: platform device structure
|
||||
|
@ -800,6 +810,8 @@ static int dim2_probe(struct platform_device *pdev)
|
|||
dev->most_iface.channel_vector = dev->capabilities;
|
||||
dev->most_iface.configure = configure_channel;
|
||||
dev->most_iface.enqueue = enqueue;
|
||||
dev->most_iface.dma_alloc = dma_alloc;
|
||||
dev->most_iface.dma_free = dma_free;
|
||||
dev->most_iface.poison_channel = poison_channel;
|
||||
dev->most_iface.request_netinfo = request_netinfo;
|
||||
dev->dev.init_name = "dim2_state";
|
||||
|
|
|
@ -618,6 +618,22 @@ static int hdm_enqueue(struct most_interface *iface, int channel,
|
|||
return retval;
|
||||
}
|
||||
|
||||
static void *hdm_dma_alloc(struct mbo *mbo, u32 size)
|
||||
{
|
||||
struct most_dev *mdev = to_mdev(mbo->ifp);
|
||||
|
||||
return usb_alloc_coherent(mdev->usb_device, size, GFP_KERNEL,
|
||||
&mbo->bus_address);
|
||||
}
|
||||
|
||||
static void hdm_dma_free(struct mbo *mbo, u32 size)
|
||||
{
|
||||
struct most_dev *mdev = to_mdev(mbo->ifp);
|
||||
|
||||
usb_free_coherent(mdev->usb_device, size, mbo->virt_address,
|
||||
mbo->bus_address);
|
||||
}
|
||||
|
||||
/**
|
||||
* hdm_configure_channel - receive channel configuration from core
|
||||
* @iface: interface
|
||||
|
@ -1032,6 +1048,8 @@ hdm_probe(struct usb_interface *interface, const struct usb_device_id *id)
|
|||
mdev->iface.request_netinfo = hdm_request_netinfo;
|
||||
mdev->iface.enqueue = hdm_enqueue;
|
||||
mdev->iface.poison_channel = hdm_poison_channel;
|
||||
mdev->iface.dma_alloc = hdm_dma_alloc;
|
||||
mdev->iface.dma_free = hdm_dma_free;
|
||||
mdev->iface.description = mdev->description;
|
||||
mdev->iface.num_channels = num_endpoints;
|
||||
|
||||
|
|
Loading…
Reference in New Issue