From e2505d92c7677ff188fec9c6d26f92d53668d42d Mon Sep 17 00:00:00 2001 From: Leonid Lobachev Date: Mon, 23 Sep 2019 14:25:08 -0700 Subject: [PATCH] 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 --- gasket_core.c | 10 ++++++++++ gasket_core.h | 7 +++++++ 2 files changed, 17 insertions(+) diff --git a/gasket_core.c b/gasket_core.c index 65b3ab2..ae3f9c7 100644 --- a/gasket_core.c +++ b/gasket_core.c @@ -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. diff --git a/gasket_core.h b/gasket_core.h index 75ad11b..7301166 100644 --- a/gasket_core.h +++ b/gasket_core.h @@ -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);