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);