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>
diff --git a/drivers/staging/gasket/gasket_core.c b/drivers/staging/gasket/gasket_core.c
index 65b3ab2..ae3f9c7 100644
--- a/drivers/staging/gasket/gasket_core.c
+++ b/drivers/staging/gasket/gasket_core.c
@@ -215,6 +215,7 @@
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 @@
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 @@
}
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.
diff --git a/drivers/staging/gasket/gasket_core.h b/drivers/staging/gasket/gasket_core.h
index 75ad11b..7301166 100644
--- a/drivers/staging/gasket/gasket_core.h
+++ b/drivers/staging/gasket/gasket_core.h
@@ -266,6 +266,9 @@
/* 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 @@
/* 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);