From patchwork Fri Jul 25 09:55:59 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mika Westerberg X-Patchwork-Id: 4622131 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 586E49F36A for ; Fri, 25 Jul 2014 10:01:00 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 4EE3E201F2 for ; Fri, 25 Jul 2014 10:00:59 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 47939201CD for ; Fri, 25 Jul 2014 10:00:58 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1XAcGg-0001hS-ET; Fri, 25 Jul 2014 09:58:26 +0000 Received: from mga02.intel.com ([134.134.136.20]) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1XAcGe-0001gX-RU for linux-arm-kernel@lists.infradead.org; Fri, 25 Jul 2014 09:58:25 +0000 Received: from orsmga002.jf.intel.com ([10.7.209.21]) by orsmga101.jf.intel.com with ESMTP; 25 Jul 2014 02:57:52 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.01,730,1400050800"; d="scan'208";a="578837030" Received: from lahna.fi.intel.com (HELO lahna) ([10.237.72.95]) by orsmga002.jf.intel.com with SMTP; 25 Jul 2014 02:56:01 -0700 Received: by lahna (sSMTP sendmail emulation); Fri, 25 Jul 2014 12:55:59 +0300 Date: Fri, 25 Jul 2014 12:55:59 +0300 From: Mika Westerberg To: Arnd Bergmann Subject: Re: [PATCH] spi/pxa2xx-pci: Enable DMA binding through device name Message-ID: <20140725095559.GA1857@lahna.fi.intel.com> References: <1406196111-22861-1-git-send-email-hock.leong.kweh@intel.com> <5574058.fMy2hcvT92@wuerfel> <20140725082249.GX1857@lahna.fi.intel.com> <7309109.iKHmHOxjzD@wuerfel> <20140725090714.GY1857@lahna.fi.intel.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20140725090714.GY1857@lahna.fi.intel.com> Organization: Intel Finland Oy - BIC 0357606-4 - Westendinkatu 7, 02160 Espoo User-Agent: Mutt/1.5.23 (2014-03-12) X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20140725_025824_938551_622CF399 X-CRM114-Status: GOOD ( 25.89 ) X-Spam-Score: -5.0 (-----) Cc: Kweh Hock Leong , Eric Miao , Chew Chiau Ee , Darren Hart , chiauee85@gmail.com, linux-kernel@vger.kernel.org, Haojian Zhuang , linux-spi@vger.kernel.org, Mark Brown , Russell King , Andy Shevchenko , linux-arm-kernel@lists.infradead.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP On Fri, Jul 25, 2014 at 12:07:14PM +0300, Mika Westerberg wrote: > On Fri, Jul 25, 2014 at 10:38:36AM +0200, Arnd Bergmann wrote: > > On Friday 25 July 2014 11:22:49 Mika Westerberg wrote: > > > > All you need to do is change your filter function to take the > > > > slave id from pxa_spi_info and stick it in there, e.g. > > > > > > > > static bool pxa2xx_spi_dw_dma_filter(struct dma_chan *chan, void *param) > > > > { > > > > const struct pxa2xx_spi_master *pdata = param; > > > > struct dw_dma_chan *dwc = to_dw_dma_chan(chan); > > > > > > > > dwc->request_line = fargs->req; > > > > dwc->src_master = 0; > > > > dwc->dst_master = 0; > > > > > > > > return 1; > > > > } > > > > > > Oh man. That makes pxa2xx_spi dependent on a certain specific DMA engine > > > driver. > > > > I think you can improve this by putting the filter function (and a pointer > > to it) into the pxa2xx_spi_master data provided by the PCI driver. > > Indeed, that looks better. It still makes the PCI part of the driver > dependent on a particular DMA engine driver but is certainly better than > the core pxa2xx_spi driver. Something like this? Hock Leong / Chiaue Ee, are you able to check if this works on your BYT machines? diff --git a/drivers/spi/spi-pxa2xx-dma.c b/drivers/spi/spi-pxa2xx-dma.c index c41ff148a2b4..5d46972ffc40 100644 --- a/drivers/spi/spi-pxa2xx-dma.c +++ b/drivers/spi/spi-pxa2xx-dma.c @@ -157,7 +157,6 @@ static struct dma_async_tx_descriptor * pxa2xx_spi_dma_prepare_one(struct driver_data *drv_data, enum dma_transfer_direction dir) { - struct pxa2xx_spi_master *pdata = drv_data->master_info; struct chip_data *chip = drv_data->cur_chip; enum dma_slave_buswidth width; struct dma_slave_config cfg; @@ -184,7 +183,6 @@ pxa2xx_spi_dma_prepare_one(struct driver_data *drv_data, cfg.dst_addr = drv_data->ssdr_physical; cfg.dst_addr_width = width; cfg.dst_maxburst = chip->dma_burst_size; - cfg.slave_id = pdata->tx_slave_id; sgt = &drv_data->tx_sgt; nents = drv_data->tx_nents; @@ -193,7 +191,6 @@ pxa2xx_spi_dma_prepare_one(struct driver_data *drv_data, cfg.src_addr = drv_data->ssdr_physical; cfg.src_addr_width = width; cfg.src_maxburst = chip->dma_burst_size; - cfg.slave_id = pdata->rx_slave_id; sgt = &drv_data->rx_sgt; nents = drv_data->rx_nents; @@ -210,14 +207,6 @@ pxa2xx_spi_dma_prepare_one(struct driver_data *drv_data, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); } -static bool pxa2xx_spi_dma_filter(struct dma_chan *chan, void *param) -{ - const struct pxa2xx_spi_master *pdata = param; - - return chan->chan_id == pdata->tx_chan_id || - chan->chan_id == pdata->rx_chan_id; -} - bool pxa2xx_spi_dma_is_possible(size_t len) { return len <= MAX_DMA_LEN; @@ -321,12 +310,14 @@ int pxa2xx_spi_dma_setup(struct driver_data *drv_data) return -ENOMEM; drv_data->tx_chan = dma_request_slave_channel_compat(mask, - pxa2xx_spi_dma_filter, pdata, dev, "tx"); + pdata->dma_filter, pdata->dma_filter_param, + dev, "tx"); if (!drv_data->tx_chan) return -ENODEV; drv_data->rx_chan = dma_request_slave_channel_compat(mask, - pxa2xx_spi_dma_filter, pdata, dev, "rx"); + pdata->dma_filter, pdata->dma_filter_param, + dev, "rx"); if (!drv_data->rx_chan) { dma_release_channel(drv_data->tx_chan); drv_data->tx_chan = NULL; diff --git a/drivers/spi/spi-pxa2xx-pci.c b/drivers/spi/spi-pxa2xx-pci.c index c1865c92ccb9..aee3aa9365cf 100644 --- a/drivers/spi/spi-pxa2xx-pci.c +++ b/drivers/spi/spi-pxa2xx-pci.c @@ -8,6 +8,9 @@ #include #include +#include +#include "../../drivers/dma/dw/regs.h" + enum { PORT_CE4100, PORT_BYT, @@ -23,6 +26,24 @@ struct pxa_spi_info { int rx_chan_id; }; +static bool pxa2xx_spi_pci_dma_filter(struct dma_chan *chan, void *param) +{ + struct dw_dma_chan *dwc = to_dw_dma_chan(chan); + const struct pxa_spi_info *info = param; + + if (chan->chan_id == info->tx_chan_id) + dwc->request_line = info->tx_slave_id; + else if (chan->chan_id == info->rx_chan_id) + dwc->request_line = info->rx_slave_id; + else + return false; + + dwc->src_master = 0; + dwc->dst_master = 0; + + return true; +} + static struct pxa_spi_info spi_info_configs[] = { [PORT_CE4100] = { .type = PXA25x_SSP, @@ -67,10 +88,9 @@ static int pxa2xx_spi_pci_probe(struct pci_dev *dev, memset(&spi_pdata, 0, sizeof(spi_pdata)); spi_pdata.num_chipselect = (c->num_chipselect > 0) ? c->num_chipselect : dev->devfn; - spi_pdata.tx_slave_id = c->tx_slave_id; - spi_pdata.tx_chan_id = c->tx_chan_id; - spi_pdata.rx_slave_id = c->rx_slave_id; - spi_pdata.rx_chan_id = c->rx_chan_id; + + spi_pdata.dma_filter = pxa2xx_spi_pci_dma_filter; + spi_pdata.dma_filter_param = c; spi_pdata.enable_dma = c->rx_slave_id >= 0 && c->tx_slave_id >= 0; ssp = &spi_pdata.ssp; diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c index fe792106bdc5..256c0abbddd2 100644 --- a/drivers/spi/spi-pxa2xx.c +++ b/drivers/spi/spi-pxa2xx.c @@ -1062,8 +1062,6 @@ pxa2xx_spi_acpi_get_pdata(struct platform_device *pdev) pdata->num_chipselect = 1; pdata->enable_dma = true; - pdata->tx_chan_id = -1; - pdata->rx_chan_id = -1; return pdata; } diff --git a/include/linux/spi/pxa2xx_spi.h b/include/linux/spi/pxa2xx_spi.h index 82d5111cd0c2..2eb00920c169 100644 --- a/include/linux/spi/pxa2xx_spi.h +++ b/include/linux/spi/pxa2xx_spi.h @@ -23,6 +23,8 @@ #define PXA2XX_CS_ASSERT (0x01) #define PXA2XX_CS_DEASSERT (0x02) +struct dma_chan; + /* device.platform_data for SSP controller devices */ struct pxa2xx_spi_master { u32 clock_enable; @@ -30,10 +32,8 @@ struct pxa2xx_spi_master { u8 enable_dma; /* DMA engine specific config */ - int rx_chan_id; - int tx_chan_id; - int rx_slave_id; - int tx_slave_id; + bool (*dma_filter)(struct dma_chan *chan, void *param); + void *dma_filter_param; /* For non-PXA arches */ struct ssp_device ssp;