char: oscar: gasket: add interface to set a separate DMA device

In at least the case of an mfd_cell multi-function device child, the
child platform device does not inherit the DMA / IOMMU configuration
of the parent.  Copying that configuration is non-straightforward or
even likely impossible when the parent device is PCI and holds
pointers to IOMMU-related state only made available for PCI devices.

Add a gasket call to allow platform chip drivers to register their
PCI parent as the device to use for DMA API calls, such that the
chip drivers can workaround this.

Change-Id: I4a4b6de67f5d10197f8ea02d06522090b150d659
Signed-off-by: Todd Poynor <toddpoynor@google.com>
This commit is contained in:
Leonid Lobachev
2019-09-23 14:25:08 -07:00
parent 975c81ef1d
commit e2505d92c7
2 changed files with 17 additions and 0 deletions

View File

@@ -215,6 +215,7 @@ static int gasket_alloc_dev(struct gasket_internal_desc *internal_desc,
gasket_dev->dev_idx = dev_idx;
snprintf(gasket_dev->kobj_name, GASKET_NAME_MAX, "%s", parent_name);
gasket_dev->dev = get_device(parent);
gasket_dev->dma_dev = get_device(parent);
/* gasket_bar_data is uninitialized. */
gasket_dev->num_page_tables = driver_desc->num_page_tables;
/* max_page_table_size and *page table are uninit'ed */
@@ -247,6 +248,7 @@ static void gasket_free_dev(struct gasket_dev *gasket_dev)
internal_desc->devs[gasket_dev->dev_idx] = NULL;
mutex_unlock(&internal_desc->mutex);
put_device(gasket_dev->dev);
put_device(gasket_dev->dma_dev);
kfree(gasket_dev);
}
@@ -1643,6 +1645,14 @@ void gasket_platform_remove_device(struct platform_device *pdev)
}
EXPORT_SYMBOL(gasket_platform_remove_device);
void gasket_set_dma_device(struct gasket_dev *gasket_dev,
struct device *dma_dev)
{
put_device(gasket_dev->dma_dev);
gasket_dev->dma_dev = get_device(dma_dev);
}
EXPORT_SYMBOL(gasket_set_dma_device);
/**
* Lookup a name by number in a num_name table.
* @num: Number to lookup.

View File

@@ -266,6 +266,9 @@ struct gasket_dev {
/* Device info */
struct device *dev;
/* DMA device to use, may be same as above or a parent */
struct device *dma_dev;
/* PCI device pointer for PCI devices */
struct pci_dev *pci_dev;
@@ -550,6 +553,10 @@ int gasket_platform_add_device(struct platform_device *pdev,
/* Remove a platform gasket device. */
void gasket_platform_remove_device(struct platform_device *pdev);
/* Set DMA device to use (if different from PCI/platform device) */
void gasket_set_dma_device(struct gasket_dev *gasket_dev,
struct device *dma_dev);
/* Enable a Gasket device. */
int gasket_enable_device(struct gasket_dev *gasket_dev);