From patchwork Mon Aug 8 08:32:38 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Per Forlin X-Patchwork-Id: 3294 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id A9DB52406F for ; Mon, 8 Aug 2011 08:33:22 +0000 (UTC) Received: from mail-qy0-f173.google.com (mail-qy0-f173.google.com [209.85.216.173]) by fiordland.canonical.com (Postfix) with ESMTP id 39FA6A18064 for ; Mon, 8 Aug 2011 08:33:22 +0000 (UTC) Received: by qyk31 with SMTP id 31so1622651qyk.11 for ; Mon, 08 Aug 2011 01:33:21 -0700 (PDT) Received: by 10.229.159.194 with SMTP id k2mr627545qcx.83.1312792401671; Mon, 08 Aug 2011 01:33:21 -0700 (PDT) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.229.190.71 with SMTP id dh7cs6706qcb; Mon, 8 Aug 2011 01:33:21 -0700 (PDT) Received: from mr.google.com ([10.223.145.2]) by 10.223.145.2 with SMTP id b2mr5316840fav.99.1312792401217 (num_hops = 1); Mon, 08 Aug 2011 01:33:21 -0700 (PDT) Received: by 10.223.145.2 with SMTP id b2mr4301963fav.99.1312792400435; Mon, 08 Aug 2011 01:33:20 -0700 (PDT) Received: from mail-fx0-f50.google.com (mail-fx0-f50.google.com [209.85.161.50]) by mx.google.com with ESMTPS id f13si6300551fai.54.2011.08.08.01.33.19 (version=TLSv1/SSLv3 cipher=OTHER); Mon, 08 Aug 2011 01:33:20 -0700 (PDT) Received-SPF: neutral (google.com: 209.85.161.50 is neither permitted nor denied by best guess record for domain of per.forlin@linaro.org) client-ip=209.85.161.50; Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.161.50 is neither permitted nor denied by best guess record for domain of per.forlin@linaro.org) smtp.mail=per.forlin@linaro.org Received: by fxh2 with SMTP id 2so5687076fxh.37 for ; Mon, 08 Aug 2011 01:33:19 -0700 (PDT) Received: by 10.204.2.78 with SMTP id 14mr1441485bki.71.1312792399223; Mon, 08 Aug 2011 01:33:19 -0700 (PDT) Received: from localhost.localdomain (c-c37f71d5.029-82-6c756e10.cust.bredbandsbolaget.se [213.113.127.195]) by mx.google.com with ESMTPS id f12sm1556885bkt.36.2011.08.08.01.33.16 (version=TLSv1/SSLv3 cipher=OTHER); Mon, 08 Aug 2011 01:33:18 -0700 (PDT) From: Per Forlin To: Felipe Balbi , Greg Kroah-Hartman , linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, linaro-dev@lists.linaro.org, Mian Yousaf KAUKAB Cc: Per Forlin Subject: [PATCH] usb: musb: ux500: optimize DMA callback routine Date: Mon, 8 Aug 2011 10:32:38 +0200 Message-Id: <1312792358-2445-1-git-send-email-per.forlin@linaro.org> X-Mailer: git-send-email 1.7.4.1 Skip the use of work queue and call musb_dma_completion() directly from DMA callback context. Here follows measurements on a Snowball board with ondemand governor active. Performance using work queue: (105 MB) copied, 6.23758 s, 16.8 MB/s (105 MB) copied, 5.7151 s, 18.3 MB/s (105 MB) copied, 5.83583 s, 18.0 MB/s (105 MB) copied, 5.93611 s, 17.7 MB/s Performance without work queue (105 MB) copied, 5.62173 s, 18.7 MB/s (105 MB) copied, 5.61811 s, 18.7 MB/s (105 MB) copied, 5.57817 s, 18.8 MB/s (105 MB) copied, 5.58549 s, 18.8 MB/s Signed-off-by: Per Forlin Acked-by: Mian Yousaf Kaukab --- drivers/usb/musb/ux500_dma.c | 43 ++--------------------------------------- 1 files changed, 3 insertions(+), 40 deletions(-) diff --git a/drivers/usb/musb/ux500_dma.c b/drivers/usb/musb/ux500_dma.c index ef4333f..46ba08f 100644 --- a/drivers/usb/musb/ux500_dma.c +++ b/drivers/usb/musb/ux500_dma.c @@ -37,7 +37,6 @@ struct ux500_dma_channel { struct dma_channel channel; struct ux500_dma_controller *controller; struct musb_hw_ep *hw_ep; - struct work_struct channel_work; struct dma_chan *dma_chan; unsigned int cur_len; dma_cookie_t cookie; @@ -56,52 +55,21 @@ struct ux500_dma_controller { dma_addr_t phy_base; }; -/* Work function invoked from DMA callback to handle tx transfers. */ -static void ux500_tx_work(struct work_struct *data) -{ - struct ux500_dma_channel *ux500_channel = container_of(data, - struct ux500_dma_channel, channel_work); - struct musb_hw_ep *hw_ep = ux500_channel->hw_ep; - struct musb *musb = hw_ep->musb; - unsigned long flags; - - dev_dbg(musb->controller, "DMA tx transfer done on hw_ep=%d\n", - hw_ep->epnum); - - spin_lock_irqsave(&musb->lock, flags); - ux500_channel->channel.actual_len = ux500_channel->cur_len; - ux500_channel->channel.status = MUSB_DMA_STATUS_FREE; - musb_dma_completion(musb, hw_ep->epnum, - ux500_channel->is_tx); - spin_unlock_irqrestore(&musb->lock, flags); -} - -/* Work function invoked from DMA callback to handle rx transfers. */ -static void ux500_rx_work(struct work_struct *data) +void ux500_dma_callback(void *private_data) { - struct ux500_dma_channel *ux500_channel = container_of(data, - struct ux500_dma_channel, channel_work); + struct dma_channel *channel = (struct dma_channel *)private_data; + struct ux500_dma_channel *ux500_channel = channel->private_data; struct musb_hw_ep *hw_ep = ux500_channel->hw_ep; struct musb *musb = hw_ep->musb; unsigned long flags; - dev_dbg(musb->controller, "DMA rx transfer done on hw_ep=%d\n", - hw_ep->epnum); - spin_lock_irqsave(&musb->lock, flags); ux500_channel->channel.actual_len = ux500_channel->cur_len; ux500_channel->channel.status = MUSB_DMA_STATUS_FREE; musb_dma_completion(musb, hw_ep->epnum, ux500_channel->is_tx); spin_unlock_irqrestore(&musb->lock, flags); -} - -void ux500_dma_callback(void *private_data) -{ - struct dma_channel *channel = (struct dma_channel *)private_data; - struct ux500_dma_channel *ux500_channel = channel->private_data; - schedule_work(&ux500_channel->channel_work); } static bool ux500_configure_channel(struct dma_channel *channel, @@ -330,7 +298,6 @@ static int ux500_dma_controller_start(struct dma_controller *c) void **param_array; struct ux500_dma_channel *channel_array; u32 ch_count; - void (*musb_channel_work)(struct work_struct *); dma_cap_mask_t mask; if ((data->num_rx_channels > UX500_MUSB_DMA_NUM_RX_CHANNELS) || @@ -347,7 +314,6 @@ static int ux500_dma_controller_start(struct dma_controller *c) channel_array = controller->rx_channel; ch_count = data->num_rx_channels; param_array = data->dma_rx_param_array; - musb_channel_work = ux500_rx_work; for (dir = 0; dir < 2; dir++) { for (ch_num = 0; ch_num < ch_count; ch_num++) { @@ -374,15 +340,12 @@ static int ux500_dma_controller_start(struct dma_controller *c) return -EBUSY; } - INIT_WORK(&ux500_channel->channel_work, - musb_channel_work); } /* Prepare the loop for TX channels */ channel_array = controller->tx_channel; ch_count = data->num_tx_channels; param_array = data->dma_tx_param_array; - musb_channel_work = ux500_tx_work; is_tx = 1; }