From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.2 required=3.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH, MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_PASS,URIBL_BLOCKED,USER_AGENT_MUTT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id AFC6AC43387 for ; Wed, 9 Jan 2019 14:02:02 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 6987620859 for ; Wed, 9 Jan 2019 14:02:02 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b="mFO3yvmM" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730970AbfAIOCB (ORCPT ); Wed, 9 Jan 2019 09:02:01 -0500 Received: from fllv0016.ext.ti.com ([198.47.19.142]:33280 "EHLO fllv0016.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730413AbfAIOCB (ORCPT ); Wed, 9 Jan 2019 09:02:01 -0500 Received: from lelv0265.itg.ti.com ([10.180.67.224]) by fllv0016.ext.ti.com (8.15.2/8.15.2) with ESMTP id x09E1jt4074972; Wed, 9 Jan 2019 08:01:45 -0600 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1547042505; bh=kNWJm0hE9mBYzeNeFj1CD0GYB6k0bEM5j9ZvLuhaUEs=; h=Date:From:To:CC:Subject:References:In-Reply-To; b=mFO3yvmM09Y6FRNElLAz77t5VmcmxtPmdO5AQTWfPUSPFtZZPZpSnow6xsN2H1JGD //wRnKvuYIKiPLvFUsG+6CUoL2tpoGPkAYWFJWWb5PJWFi7fMjKicIh12funzsH4e8 K4Wq6XTUHHY4G/jMVoXD5iD21MXoLCLbrjowKyNw= Received: from DFLE100.ent.ti.com (dfle100.ent.ti.com [10.64.6.21]) by lelv0265.itg.ti.com (8.15.2/8.15.2) with ESMTPS id x09E1juH040143 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Wed, 9 Jan 2019 08:01:45 -0600 Received: from DFLE101.ent.ti.com (10.64.6.22) by DFLE100.ent.ti.com (10.64.6.21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1591.10; Wed, 9 Jan 2019 08:01:45 -0600 Received: from dflp32.itg.ti.com (10.64.6.15) by DFLE101.ent.ti.com (10.64.6.22) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_RSA_WITH_AES_256_CBC_SHA) id 15.1.1591.10 via Frontend Transport; Wed, 9 Jan 2019 08:01:45 -0600 Received: from localhost (ileax41-snat.itg.ti.com [10.172.224.153]) by dflp32.itg.ti.com (8.14.3/8.13.8) with ESMTP id x09E1jOO025727; Wed, 9 Jan 2019 08:01:45 -0600 Date: Wed, 9 Jan 2019 08:01:44 -0600 From: Bin Liu To: Min Guo CC: Rob Herring , Greg Kroah-Hartman , Mark Rutland , Matthias Brugger , Alan Stern , , , , , , , Yonglong Wu Subject: Re: [PATCH 4/4] usb: musb: Add support for MediaTek musb controller Message-ID: <20190109140144.GI25910@uda0271908> Mail-Followup-To: Bin Liu , Min Guo , Rob Herring , Greg Kroah-Hartman , Mark Rutland , Matthias Brugger , Alan Stern , chunfeng.yun@mediatek.com, linux-usb@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org, Yonglong Wu References: <1545896066-897-1-git-send-email-min.guo@mediatek.com> <1545896066-897-5-git-send-email-min.guo@mediatek.com> <20190108154441.GG25910@uda0271908> <1547037068.4433.122.camel@mhfsdcap03> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Disposition: inline In-Reply-To: <1547037068.4433.122.camel@mhfsdcap03> User-Agent: Mutt/1.5.21 (2010-09-15) X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi Min, On Wed, Jan 09, 2019 at 08:31:08PM +0800, Min Guo wrote: > Hi Bin, > On Tue, 2019-01-08 at 09:44 -0600, Bin Liu wrote: > > Hi, > > > > On Thu, Dec 27, 2018 at 03:34:26PM +0800, min.guo@mediatek.com wrote: > > > From: Min Guo > > > > > > This adds support for MediaTek musb controller in > > > host, peripheral and otg mode > > > > > > Signed-off-by: Min Guo > > > Signed-off-by: Yonglong Wu > > > --- > > > drivers/usb/musb/Kconfig | 8 +- > > > drivers/usb/musb/Makefile | 1 + > > > drivers/usb/musb/mediatek.c | 562 +++++++++++++++++++++++++++++++++++++++++++ > > > drivers/usb/musb/musb_core.c | 10 + > > > drivers/usb/musb/musb_core.h | 1 + > > > drivers/usb/musb/musb_dma.h | 1 + > > > drivers/usb/musb/musb_host.c | 79 ++++-- > > > drivers/usb/musb/musb_regs.h | 6 + > > > drivers/usb/musb/musbhsdma.c | 34 ++- > > > 9 files changed, 671 insertions(+), 31 deletions(-) > > > create mode 100644 drivers/usb/musb/mediatek.c > > > > > > diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig > > > index ad08895..540fc9f 100644 > > > --- a/drivers/usb/musb/Kconfig > > > +++ b/drivers/usb/musb/Kconfig > > > @@ -115,6 +115,12 @@ config USB_MUSB_JZ4740 > > > depends on USB_MUSB_GADGET > > > depends on USB_OTG_BLACKLIST_HUB > > > > > > +config USB_MUSB_MEDIATEK > > > + tristate "MediaTek platforms" > > > + depends on ARCH_MEDIATEK > > > > Please also add '|| COMPILE_TEST' to make testing easier. > > Ok > > > > + depends on NOP_USB_XCEIV > > > + depends on GENERIC_PHY > > > + > > > config USB_MUSB_AM335X_CHILD > > > tristate > > > > > > @@ -141,7 +147,7 @@ config USB_UX500_DMA > > > > > > config USB_INVENTRA_DMA > > > bool 'Inventra' > > > - depends on USB_MUSB_OMAP2PLUS > > > + depends on USB_MUSB_OMAP2PLUS || USB_MUSB_MEDIATEK > > > help > > > Enable DMA transfers using Mentor's engine. > > > > > > diff --git a/drivers/usb/musb/Makefile b/drivers/usb/musb/Makefile > > > index 3a88c79..63d82d0 100644 > > > --- a/drivers/usb/musb/Makefile > > > +++ b/drivers/usb/musb/Makefile > > > @@ -24,6 +24,7 @@ obj-$(CONFIG_USB_MUSB_DA8XX) += da8xx.o > > > obj-$(CONFIG_USB_MUSB_UX500) += ux500.o > > > obj-$(CONFIG_USB_MUSB_JZ4740) += jz4740.o > > > obj-$(CONFIG_USB_MUSB_SUNXI) += sunxi.o > > > +obj-$(CONFIG_USB_MUSB_MEDIATEK) += mediatek.o > > > > > > > > > obj-$(CONFIG_USB_MUSB_AM335X_CHILD) += musb_am335x.o > > > diff --git a/drivers/usb/musb/mediatek.c b/drivers/usb/musb/mediatek.c > > > new file mode 100644 > > > index 0000000..15a6460 > > > --- /dev/null > > > +++ b/drivers/usb/musb/mediatek.c > > > > [snip] > > I will review this section later after we sorted out other things. > > > > > diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c > > > index b7d5627..d60f76f 100644 > > > --- a/drivers/usb/musb/musb_core.c > > > +++ b/drivers/usb/musb/musb_core.c > > > @@ -1028,6 +1028,16 @@ static void musb_disable_interrupts(struct musb *musb) > > > temp = musb_readb(mbase, MUSB_INTRUSB); > > > temp = musb_readw(mbase, MUSB_INTRTX); > > > temp = musb_readw(mbase, MUSB_INTRRX); > > > + > > > + /* MediaTek controller interrupt status is W1C */ > > > > This W1C doesn't match to the MUSB Programming Guide that I have. Those > > registers are read-only. > > Is the difference due to the IP intergration in the mtk platforms? or is > > it a new version of the MUSB controller? If latter, what is the version? > > This is difference due to the IP intergration in mtk platforms. W1C is > easy for CpdeViser debug. > > > > + if (musb->ops->quirks & MUSB_MTK_QUIRKS) { > > > > Basically we don't want to use this type of platform specific quirks if > > possible, so let's try to not use it. > > I will try my best to avoid using it. Thanks. > > > > + musb_writeb(mbase, MUSB_INTRUSB, > > > + musb_readb(mbase, MUSB_INTRUSB)); > > > > For this clearing register bit operation, please create platform hooks > > musb_clearb() and musb_clearw() in struct musb_platform_ops instead, > > then follow how musb_readb() pointer is assigned in > > musb_init_controller() to use the W1C version for mtk platform. > > I have tried implementing musb_readb(), musb_readw() interface with > interrupt status W1C function in struct musb_platform_ops. But this > interface will require a global variable to hold MAC basic address for > judgment, and then special handling of the interrupt state. A global > variable will make the driver work with only a single instance, so it > can't work on some MTK platforms which have two instances. I didn't mean to modify musb_read*(), but > How about creating musb_clearb/w() as following: > void (*clearb)(void __iomem *addr, unsigned offset, u8 data); > void (*clearw)(void __iomem *addr, unsigned offset, u16 data); this is what I was asking for, similar to what musb_readb/w() is implemented. > > > > > + musb_writew(mbase, MUSB_INTRRX, > > > + musb_readw(mbase, MUSB_INTRRX)); > > > + musb_writew(mbase, MUSB_INTRTX, > > > + musb_readw(mbase, MUSB_INTRTX)); > > > + } > > > } > > > > > > static void musb_enable_interrupts(struct musb *musb) > > > diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h > > > index 04203b7..1bf4e9a 100644 > > > --- a/drivers/usb/musb/musb_core.h > > > +++ b/drivers/usb/musb/musb_core.h > > > @@ -138,6 +138,7 @@ enum musb_g_ep0_state { > > > */ > > > struct musb_platform_ops { > > > > > > +#define MUSB_MTK_QUIRKS BIT(10) > > > #define MUSB_G_NO_SKB_RESERVE BIT(9) > > > #define MUSB_DA8XX BIT(8) > > > #define MUSB_PRESERVE_SESSION BIT(7) > > > diff --git a/drivers/usb/musb/musb_dma.h b/drivers/usb/musb/musb_dma.h > > > index 281e75d3..b218210 100644 > > > --- a/drivers/usb/musb/musb_dma.h > > > +++ b/drivers/usb/musb/musb_dma.h > > > @@ -197,6 +197,7 @@ static inline void musb_dma_controller_destroy(struct dma_controller *d) { } > > > extern struct dma_controller * > > > musbhs_dma_controller_create(struct musb *musb, void __iomem *base); > > > extern void musbhs_dma_controller_destroy(struct dma_controller *c); > > > +extern irqreturn_t dma_controller_irq(int irq, void *private_data); > > > > > > extern struct dma_controller * > > > tusb_dma_controller_create(struct musb *musb, void __iomem *base); > > > diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c > > > index b59ce9a..b1b0216 100644 > > > --- a/drivers/usb/musb/musb_host.c > > > +++ b/drivers/usb/musb/musb_host.c > > > @@ -292,20 +292,73 @@ static inline void musb_save_toggle(struct musb_qh *qh, int is_in, > > > { > > > void __iomem *epio = qh->hw_ep->regs; > > > u16 csr; > > > + struct musb *musb = qh->hw_ep->musb; > > > > > > /* > > > * FIXME: the current Mentor DMA code seems to have > > > * problems getting toggle correct. > > > */ > > > > > > - if (is_in) > > > - csr = musb_readw(epio, MUSB_RXCSR) & MUSB_RXCSR_H_DATATOGGLE; > > > - else > > > - csr = musb_readw(epio, MUSB_TXCSR) & MUSB_TXCSR_H_DATATOGGLE; > > > + /* MediaTek controller has private toggle register */ > > > > only one toggle register for all endpoints? how does it handle > > difference toggle values for different endpoints? > > MediaTek controller has separate registers to describe TX/RX toggle. Is it one register per endpoint? > > > > + if (musb->ops->quirks & MUSB_MTK_QUIRKS) { > > > + u16 toggle; > > > + u8 epnum = qh->hw_ep->epnum; > > > + > > > + if (is_in) > > > + toggle = musb_readl(musb->mregs, MUSB_RXTOG); this line seems telling there is just *one* register for all endpoints. > > > > should use musb_readw() instead? MUSB_RXTOG seems to be 16bit. > > Ok > > > > + else > > > + toggle = musb_readl(musb->mregs, MUSB_TXTOG); > > > + > > > + csr = toggle & (1 << epnum); > > > + } else { > > > + if (is_in) > > > + csr = musb_readw(epio, MUSB_RXCSR) > > > + & MUSB_RXCSR_H_DATATOGGLE; > > > + else > > > + csr = musb_readw(epio, MUSB_TXCSR) > > > + & MUSB_TXCSR_H_DATATOGGLE; > > > > Does this logic still work for the mtk platform even if it has its own > > private toggle register? If so, we don't need to change here. > > Sorry, this logic can not work on mtk platform, bit > MUSB_RXCSR_H_DATATOGGLE and MUSB_TXCSR_H_DATATOGGLE are used for other > function. Is there a different controller RTL version we can use to differentiate? > > > If not, let's try to not use this quirk flag. Please create a hook > > musb_platform_get_toggle() in struct musb_platform_ops. > > Does the method of implement musb_platform_get_toggle() is prepare > musb_default_get_toggle with common function, then follow how > musb_readb() pointer is assigned in musb_init_controller()? Yes, similar to musb_readb() implementation. > How about creating musb_platform_get_toggle() as following: > u16 (*get_toggle)(struct musb* musb, struct musb_qh *qh, int is_in); yes, it is part of the implementation, then add it in struct musb_io. > > > > + } > > > > > > usb_settoggle(urb->dev, qh->epnum, !is_in, csr ? 1 : 0); > > > } > > > > > > +static inline u16 musb_set_toggle(struct musb_qh *qh, int is_in, > > > + struct urb *urb) > > > +{ > > > + u16 csr = 0; > > > + u16 toggle = 0; > > > + struct musb *musb = qh->hw_ep->musb; > > > + u8 epnum = qh->hw_ep->epnum; > > > + > > > + toggle = usb_gettoggle(urb->dev, qh->epnum, !is_in); > > > + > > > + /* MediaTek controller has private toggle register */ > > > + if (musb->ops->quirks & MUSB_MTK_QUIRKS) { > > > + if (is_in) { > > > + musb_writel(musb->mregs, MUSB_RXTOGEN, (1 << epnum)); > > > + musb_writel(musb->mregs, MUSB_RXTOG, (toggle << epnum)); > > > + } else { > > > + musb_writel(musb->mregs, MUSB_TXTOGEN, (1 << epnum)); > > > + musb_writel(musb->mregs, MUSB_TXTOG, (toggle << epnum)); > > > + } > > > + } else { > > > + if (is_in) { > > > + if (toggle) > > > + csr = MUSB_RXCSR_H_WR_DATATOGGLE > > > + | MUSB_RXCSR_H_DATATOGGLE; > > > + else > > > + csr = 0; > > > + } else { > > > + if (toggle) > > > + csr |= MUSB_TXCSR_H_WR_DATATOGGLE > > > + | MUSB_TXCSR_H_DATATOGGLE; > > > + else > > > + csr |= MUSB_TXCSR_CLRDATATOG; '? :' operation probably is better than 'if else' here. > > > + } > > > + } > > > + return csr; > > > > Please create a seperate patch for this musb_set_toggle() without adding > > the mtk logic. It is a nice cleanup. > > Does this like get toggle implementation, create a hook > musb_platform_set_toggle() in struct musb_platform_ops? You did the code cleanup by creating musb_set_toggle(), please make it in a separate patch, like static u16 musb_set_toggle(struct musb_qh *qh, int is_in, struct urb *urb) { toggle = usb_gettoggle(urb->dev, qh->epnum, !is_in); if (is_in) csr = toggle ? (MUSB_RXCSR_H_WR_DATATOGGLE | MUSB_RXCSR_H_DATATOGGLE) : 0; else csr = toggle ? MUSB_TXCSR_H_WR_DATATOGGLE | MUSB_TXCSR_H_DATATOGGLE : MUSB_TXCSR_CLRDATATOG; return csr; } /* use musb_set_toggle() in the two instances */ then in this patch you add the mtk implementation similar as *get_toggle() discussed above. > > > > +} > > > + > > > /* > > > * Advance this hardware endpoint's queue, completing the specified URB and > > > * advancing to either the next URB queued to that qh, or else invalidating > > > @@ -772,13 +825,8 @@ static void musb_ep_program(struct musb *musb, u8 epnum, > > > ); > > > csr |= MUSB_TXCSR_MODE; > > > > > > - if (!hw_ep->tx_double_buffered) { > > > - if (usb_gettoggle(urb->dev, qh->epnum, 1)) > > > - csr |= MUSB_TXCSR_H_WR_DATATOGGLE > > > - | MUSB_TXCSR_H_DATATOGGLE; > > > - else > > > - csr |= MUSB_TXCSR_CLRDATATOG; > > > - } > > > + if (!hw_ep->tx_double_buffered) > > > + csr |= musb_set_toggle(qh, !is_out, urb); > > > > > > musb_writew(epio, MUSB_TXCSR, csr); > > > /* REVISIT may need to clear FLUSHFIFO ... */ > > > @@ -860,17 +908,12 @@ static void musb_ep_program(struct musb *musb, u8 epnum, > > > > > > /* IN/receive */ > > > } else { > > > - u16 csr; > > > + u16 csr = 0; > > > > > > if (hw_ep->rx_reinit) { > > > musb_rx_reinit(musb, qh, epnum); > > > + csr |= musb_set_toggle(qh, !is_out, urb); > > > > > > - /* init new state: toggle and NYET, maybe DMA later */ > > > - if (usb_gettoggle(urb->dev, qh->epnum, 0)) > > > - csr = MUSB_RXCSR_H_WR_DATATOGGLE > > > - | MUSB_RXCSR_H_DATATOGGLE; > > > - else > > > - csr = 0; > > > if (qh->type == USB_ENDPOINT_XFER_INT) > > > csr |= MUSB_RXCSR_DISNYET; > > > > > > diff --git a/drivers/usb/musb/musb_regs.h b/drivers/usb/musb/musb_regs.h > > > index 5cd7264..ffbe267 100644 > > > --- a/drivers/usb/musb/musb_regs.h > > > +++ b/drivers/usb/musb/musb_regs.h > > > @@ -273,6 +273,12 @@ > > > #define MUSB_RXHUBADDR 0x06 > > > #define MUSB_RXHUBPORT 0x07 > > > > > > +/* MediaTek controller toggle enable and status reg */ > > > +#define MUSB_RXTOG 0x80 > > > +#define MUSB_RXTOGEN 0x82 > > > +#define MUSB_TXTOG 0x84 > > > +#define MUSB_TXTOGEN 0x86 > > > > Again, these offsets are for different registers in the MUSB version I > > have, please let me know if you have different version of the MUSB IP. > > Sorry, these are MediaTek controller private registers used for control > toggle. Okay. Once the platform get/set_toggle() are implemented, those registers can be defined in the mtk glue driver instead of here. Regards, -Bin. From mboxrd@z Thu Jan 1 00:00:00 1970 From: Bin Liu Subject: Re: [PATCH 4/4] usb: musb: Add support for MediaTek musb controller Date: Wed, 9 Jan 2019 08:01:44 -0600 Message-ID: <20190109140144.GI25910@uda0271908> References: <1545896066-897-1-git-send-email-min.guo@mediatek.com> <1545896066-897-5-git-send-email-min.guo@mediatek.com> <20190108154441.GG25910@uda0271908> <1547037068.4433.122.camel@mhfsdcap03> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: Content-Disposition: inline In-Reply-To: <1547037068.4433.122.camel@mhfsdcap03> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=m.gmane.org@lists.infradead.org To: Min Guo Cc: Mark Rutland , devicetree@vger.kernel.org, Yonglong Wu , Greg Kroah-Hartman , linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, Matthias Brugger , Rob Herring , Alan Stern , chunfeng.yun@mediatek.com, linux-mediatek@lists.infradead.org, linux-arm-kernel@lists.infradead.org List-Id: devicetree@vger.kernel.org Hi Min, On Wed, Jan 09, 2019 at 08:31:08PM +0800, Min Guo wrote: > Hi Bin, > On Tue, 2019-01-08 at 09:44 -0600, Bin Liu wrote: > > Hi, > > > > On Thu, Dec 27, 2018 at 03:34:26PM +0800, min.guo@mediatek.com wrote: > > > From: Min Guo > > > > > > This adds support for MediaTek musb controller in > > > host, peripheral and otg mode > > > > > > Signed-off-by: Min Guo > > > Signed-off-by: Yonglong Wu > > > --- > > > drivers/usb/musb/Kconfig | 8 +- > > > drivers/usb/musb/Makefile | 1 + > > > drivers/usb/musb/mediatek.c | 562 +++++++++++++++++++++++++++++++++++++++++++ > > > drivers/usb/musb/musb_core.c | 10 + > > > drivers/usb/musb/musb_core.h | 1 + > > > drivers/usb/musb/musb_dma.h | 1 + > > > drivers/usb/musb/musb_host.c | 79 ++++-- > > > drivers/usb/musb/musb_regs.h | 6 + > > > drivers/usb/musb/musbhsdma.c | 34 ++- > > > 9 files changed, 671 insertions(+), 31 deletions(-) > > > create mode 100644 drivers/usb/musb/mediatek.c > > > > > > diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig > > > index ad08895..540fc9f 100644 > > > --- a/drivers/usb/musb/Kconfig > > > +++ b/drivers/usb/musb/Kconfig > > > @@ -115,6 +115,12 @@ config USB_MUSB_JZ4740 > > > depends on USB_MUSB_GADGET > > > depends on USB_OTG_BLACKLIST_HUB > > > > > > +config USB_MUSB_MEDIATEK > > > + tristate "MediaTek platforms" > > > + depends on ARCH_MEDIATEK > > > > Please also add '|| COMPILE_TEST' to make testing easier. > > Ok > > > > + depends on NOP_USB_XCEIV > > > + depends on GENERIC_PHY > > > + > > > config USB_MUSB_AM335X_CHILD > > > tristate > > > > > > @@ -141,7 +147,7 @@ config USB_UX500_DMA > > > > > > config USB_INVENTRA_DMA > > > bool 'Inventra' > > > - depends on USB_MUSB_OMAP2PLUS > > > + depends on USB_MUSB_OMAP2PLUS || USB_MUSB_MEDIATEK > > > help > > > Enable DMA transfers using Mentor's engine. > > > > > > diff --git a/drivers/usb/musb/Makefile b/drivers/usb/musb/Makefile > > > index 3a88c79..63d82d0 100644 > > > --- a/drivers/usb/musb/Makefile > > > +++ b/drivers/usb/musb/Makefile > > > @@ -24,6 +24,7 @@ obj-$(CONFIG_USB_MUSB_DA8XX) += da8xx.o > > > obj-$(CONFIG_USB_MUSB_UX500) += ux500.o > > > obj-$(CONFIG_USB_MUSB_JZ4740) += jz4740.o > > > obj-$(CONFIG_USB_MUSB_SUNXI) += sunxi.o > > > +obj-$(CONFIG_USB_MUSB_MEDIATEK) += mediatek.o > > > > > > > > > obj-$(CONFIG_USB_MUSB_AM335X_CHILD) += musb_am335x.o > > > diff --git a/drivers/usb/musb/mediatek.c b/drivers/usb/musb/mediatek.c > > > new file mode 100644 > > > index 0000000..15a6460 > > > --- /dev/null > > > +++ b/drivers/usb/musb/mediatek.c > > > > [snip] > > I will review this section later after we sorted out other things. > > > > > diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c > > > index b7d5627..d60f76f 100644 > > > --- a/drivers/usb/musb/musb_core.c > > > +++ b/drivers/usb/musb/musb_core.c > > > @@ -1028,6 +1028,16 @@ static void musb_disable_interrupts(struct musb *musb) > > > temp = musb_readb(mbase, MUSB_INTRUSB); > > > temp = musb_readw(mbase, MUSB_INTRTX); > > > temp = musb_readw(mbase, MUSB_INTRRX); > > > + > > > + /* MediaTek controller interrupt status is W1C */ > > > > This W1C doesn't match to the MUSB Programming Guide that I have. Those > > registers are read-only. > > Is the difference due to the IP intergration in the mtk platforms? or is > > it a new version of the MUSB controller? If latter, what is the version? > > This is difference due to the IP intergration in mtk platforms. W1C is > easy for CpdeViser debug. > > > > + if (musb->ops->quirks & MUSB_MTK_QUIRKS) { > > > > Basically we don't want to use this type of platform specific quirks if > > possible, so let's try to not use it. > > I will try my best to avoid using it. Thanks. > > > > + musb_writeb(mbase, MUSB_INTRUSB, > > > + musb_readb(mbase, MUSB_INTRUSB)); > > > > For this clearing register bit operation, please create platform hooks > > musb_clearb() and musb_clearw() in struct musb_platform_ops instead, > > then follow how musb_readb() pointer is assigned in > > musb_init_controller() to use the W1C version for mtk platform. > > I have tried implementing musb_readb(), musb_readw() interface with > interrupt status W1C function in struct musb_platform_ops. But this > interface will require a global variable to hold MAC basic address for > judgment, and then special handling of the interrupt state. A global > variable will make the driver work with only a single instance, so it > can't work on some MTK platforms which have two instances. I didn't mean to modify musb_read*(), but > How about creating musb_clearb/w() as following: > void (*clearb)(void __iomem *addr, unsigned offset, u8 data); > void (*clearw)(void __iomem *addr, unsigned offset, u16 data); this is what I was asking for, similar to what musb_readb/w() is implemented. > > > > > + musb_writew(mbase, MUSB_INTRRX, > > > + musb_readw(mbase, MUSB_INTRRX)); > > > + musb_writew(mbase, MUSB_INTRTX, > > > + musb_readw(mbase, MUSB_INTRTX)); > > > + } > > > } > > > > > > static void musb_enable_interrupts(struct musb *musb) > > > diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h > > > index 04203b7..1bf4e9a 100644 > > > --- a/drivers/usb/musb/musb_core.h > > > +++ b/drivers/usb/musb/musb_core.h > > > @@ -138,6 +138,7 @@ enum musb_g_ep0_state { > > > */ > > > struct musb_platform_ops { > > > > > > +#define MUSB_MTK_QUIRKS BIT(10) > > > #define MUSB_G_NO_SKB_RESERVE BIT(9) > > > #define MUSB_DA8XX BIT(8) > > > #define MUSB_PRESERVE_SESSION BIT(7) > > > diff --git a/drivers/usb/musb/musb_dma.h b/drivers/usb/musb/musb_dma.h > > > index 281e75d3..b218210 100644 > > > --- a/drivers/usb/musb/musb_dma.h > > > +++ b/drivers/usb/musb/musb_dma.h > > > @@ -197,6 +197,7 @@ static inline void musb_dma_controller_destroy(struct dma_controller *d) { } > > > extern struct dma_controller * > > > musbhs_dma_controller_create(struct musb *musb, void __iomem *base); > > > extern void musbhs_dma_controller_destroy(struct dma_controller *c); > > > +extern irqreturn_t dma_controller_irq(int irq, void *private_data); > > > > > > extern struct dma_controller * > > > tusb_dma_controller_create(struct musb *musb, void __iomem *base); > > > diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c > > > index b59ce9a..b1b0216 100644 > > > --- a/drivers/usb/musb/musb_host.c > > > +++ b/drivers/usb/musb/musb_host.c > > > @@ -292,20 +292,73 @@ static inline void musb_save_toggle(struct musb_qh *qh, int is_in, > > > { > > > void __iomem *epio = qh->hw_ep->regs; > > > u16 csr; > > > + struct musb *musb = qh->hw_ep->musb; > > > > > > /* > > > * FIXME: the current Mentor DMA code seems to have > > > * problems getting toggle correct. > > > */ > > > > > > - if (is_in) > > > - csr = musb_readw(epio, MUSB_RXCSR) & MUSB_RXCSR_H_DATATOGGLE; > > > - else > > > - csr = musb_readw(epio, MUSB_TXCSR) & MUSB_TXCSR_H_DATATOGGLE; > > > + /* MediaTek controller has private toggle register */ > > > > only one toggle register for all endpoints? how does it handle > > difference toggle values for different endpoints? > > MediaTek controller has separate registers to describe TX/RX toggle. Is it one register per endpoint? > > > > + if (musb->ops->quirks & MUSB_MTK_QUIRKS) { > > > + u16 toggle; > > > + u8 epnum = qh->hw_ep->epnum; > > > + > > > + if (is_in) > > > + toggle = musb_readl(musb->mregs, MUSB_RXTOG); this line seems telling there is just *one* register for all endpoints. > > > > should use musb_readw() instead? MUSB_RXTOG seems to be 16bit. > > Ok > > > > + else > > > + toggle = musb_readl(musb->mregs, MUSB_TXTOG); > > > + > > > + csr = toggle & (1 << epnum); > > > + } else { > > > + if (is_in) > > > + csr = musb_readw(epio, MUSB_RXCSR) > > > + & MUSB_RXCSR_H_DATATOGGLE; > > > + else > > > + csr = musb_readw(epio, MUSB_TXCSR) > > > + & MUSB_TXCSR_H_DATATOGGLE; > > > > Does this logic still work for the mtk platform even if it has its own > > private toggle register? If so, we don't need to change here. > > Sorry, this logic can not work on mtk platform, bit > MUSB_RXCSR_H_DATATOGGLE and MUSB_TXCSR_H_DATATOGGLE are used for other > function. Is there a different controller RTL version we can use to differentiate? > > > If not, let's try to not use this quirk flag. Please create a hook > > musb_platform_get_toggle() in struct musb_platform_ops. > > Does the method of implement musb_platform_get_toggle() is prepare > musb_default_get_toggle with common function, then follow how > musb_readb() pointer is assigned in musb_init_controller()? Yes, similar to musb_readb() implementation. > How about creating musb_platform_get_toggle() as following: > u16 (*get_toggle)(struct musb* musb, struct musb_qh *qh, int is_in); yes, it is part of the implementation, then add it in struct musb_io. > > > > + } > > > > > > usb_settoggle(urb->dev, qh->epnum, !is_in, csr ? 1 : 0); > > > } > > > > > > +static inline u16 musb_set_toggle(struct musb_qh *qh, int is_in, > > > + struct urb *urb) > > > +{ > > > + u16 csr = 0; > > > + u16 toggle = 0; > > > + struct musb *musb = qh->hw_ep->musb; > > > + u8 epnum = qh->hw_ep->epnum; > > > + > > > + toggle = usb_gettoggle(urb->dev, qh->epnum, !is_in); > > > + > > > + /* MediaTek controller has private toggle register */ > > > + if (musb->ops->quirks & MUSB_MTK_QUIRKS) { > > > + if (is_in) { > > > + musb_writel(musb->mregs, MUSB_RXTOGEN, (1 << epnum)); > > > + musb_writel(musb->mregs, MUSB_RXTOG, (toggle << epnum)); > > > + } else { > > > + musb_writel(musb->mregs, MUSB_TXTOGEN, (1 << epnum)); > > > + musb_writel(musb->mregs, MUSB_TXTOG, (toggle << epnum)); > > > + } > > > + } else { > > > + if (is_in) { > > > + if (toggle) > > > + csr = MUSB_RXCSR_H_WR_DATATOGGLE > > > + | MUSB_RXCSR_H_DATATOGGLE; > > > + else > > > + csr = 0; > > > + } else { > > > + if (toggle) > > > + csr |= MUSB_TXCSR_H_WR_DATATOGGLE > > > + | MUSB_TXCSR_H_DATATOGGLE; > > > + else > > > + csr |= MUSB_TXCSR_CLRDATATOG; '? :' operation probably is better than 'if else' here. > > > + } > > > + } > > > + return csr; > > > > Please create a seperate patch for this musb_set_toggle() without adding > > the mtk logic. It is a nice cleanup. > > Does this like get toggle implementation, create a hook > musb_platform_set_toggle() in struct musb_platform_ops? You did the code cleanup by creating musb_set_toggle(), please make it in a separate patch, like static u16 musb_set_toggle(struct musb_qh *qh, int is_in, struct urb *urb) { toggle = usb_gettoggle(urb->dev, qh->epnum, !is_in); if (is_in) csr = toggle ? (MUSB_RXCSR_H_WR_DATATOGGLE | MUSB_RXCSR_H_DATATOGGLE) : 0; else csr = toggle ? MUSB_TXCSR_H_WR_DATATOGGLE | MUSB_TXCSR_H_DATATOGGLE : MUSB_TXCSR_CLRDATATOG; return csr; } /* use musb_set_toggle() in the two instances */ then in this patch you add the mtk implementation similar as *get_toggle() discussed above. > > > > +} > > > + > > > /* > > > * Advance this hardware endpoint's queue, completing the specified URB and > > > * advancing to either the next URB queued to that qh, or else invalidating > > > @@ -772,13 +825,8 @@ static void musb_ep_program(struct musb *musb, u8 epnum, > > > ); > > > csr |= MUSB_TXCSR_MODE; > > > > > > - if (!hw_ep->tx_double_buffered) { > > > - if (usb_gettoggle(urb->dev, qh->epnum, 1)) > > > - csr |= MUSB_TXCSR_H_WR_DATATOGGLE > > > - | MUSB_TXCSR_H_DATATOGGLE; > > > - else > > > - csr |= MUSB_TXCSR_CLRDATATOG; > > > - } > > > + if (!hw_ep->tx_double_buffered) > > > + csr |= musb_set_toggle(qh, !is_out, urb); > > > > > > musb_writew(epio, MUSB_TXCSR, csr); > > > /* REVISIT may need to clear FLUSHFIFO ... */ > > > @@ -860,17 +908,12 @@ static void musb_ep_program(struct musb *musb, u8 epnum, > > > > > > /* IN/receive */ > > > } else { > > > - u16 csr; > > > + u16 csr = 0; > > > > > > if (hw_ep->rx_reinit) { > > > musb_rx_reinit(musb, qh, epnum); > > > + csr |= musb_set_toggle(qh, !is_out, urb); > > > > > > - /* init new state: toggle and NYET, maybe DMA later */ > > > - if (usb_gettoggle(urb->dev, qh->epnum, 0)) > > > - csr = MUSB_RXCSR_H_WR_DATATOGGLE > > > - | MUSB_RXCSR_H_DATATOGGLE; > > > - else > > > - csr = 0; > > > if (qh->type == USB_ENDPOINT_XFER_INT) > > > csr |= MUSB_RXCSR_DISNYET; > > > > > > diff --git a/drivers/usb/musb/musb_regs.h b/drivers/usb/musb/musb_regs.h > > > index 5cd7264..ffbe267 100644 > > > --- a/drivers/usb/musb/musb_regs.h > > > +++ b/drivers/usb/musb/musb_regs.h > > > @@ -273,6 +273,12 @@ > > > #define MUSB_RXHUBADDR 0x06 > > > #define MUSB_RXHUBPORT 0x07 > > > > > > +/* MediaTek controller toggle enable and status reg */ > > > +#define MUSB_RXTOG 0x80 > > > +#define MUSB_RXTOGEN 0x82 > > > +#define MUSB_TXTOG 0x84 > > > +#define MUSB_TXTOGEN 0x86 > > > > Again, these offsets are for different registers in the MUSB version I > > have, please let me know if you have different version of the MUSB IP. > > Sorry, these are MediaTek controller private registers used for control > toggle. Okay. Once the platform get/set_toggle() are implemented, those registers can be defined in the mtk glue driver instead of here. Regards, -Bin. From mboxrd@z Thu Jan 1 00:00:00 1970 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: base64 Subject: [4/4] usb: musb: Add support for MediaTek musb controller From: Bin Liu Message-Id: <20190109140144.GI25910@uda0271908> Date: Wed, 9 Jan 2019 08:01:44 -0600 To: Min Guo Cc: Rob Herring , Greg Kroah-Hartman , Mark Rutland , Matthias Brugger , Alan Stern , chunfeng.yun@mediatek.com, linux-usb@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org, Yonglong Wu List-ID: SGkgTWluLAoKT24gV2VkLCBKYW4gMDksIDIwMTkgYXQgMDg6MzE6MDhQTSArMDgwMCwgTWluIEd1 byB3cm90ZToKPiBIaSBCaW4sCj4gT24gVHVlLCAyMDE5LTAxLTA4IGF0IDA5OjQ0IC0wNjAwLCBC aW4gTGl1IHdyb3RlOgo+ID4gSGksCj4gPiAKPiA+IE9uIFRodSwgRGVjIDI3LCAyMDE4IGF0IDAz OjM0OjI2UE0gKzA4MDAsIG1pbi5ndW9AbWVkaWF0ZWsuY29tIHdyb3RlOgo+ID4gPiBGcm9tOiBN aW4gR3VvIDxtaW4uZ3VvQG1lZGlhdGVrLmNvbT4KPiA+ID4gCj4gPiA+IFRoaXMgYWRkcyBzdXBw b3J0IGZvciBNZWRpYVRlayBtdXNiIGNvbnRyb2xsZXIgaW4KPiA+ID4gaG9zdCwgcGVyaXBoZXJh bCBhbmQgb3RnIG1vZGUKPiA+ID4gCj4gPiA+IFNpZ25lZC1vZmYtYnk6IE1pbiBHdW8gPG1pbi5n dW9AbWVkaWF0ZWsuY29tPgo+ID4gPiBTaWduZWQtb2ZmLWJ5OiBZb25nbG9uZyBXdSA8eW9uZ2xv bmcud3VAbWVkaWF0ZWsuY29tPgo+ID4gPiAtLS0KPiA+ID4gIGRyaXZlcnMvdXNiL211c2IvS2Nv bmZpZyAgICAgfCAgIDggKy0KPiA+ID4gIGRyaXZlcnMvdXNiL211c2IvTWFrZWZpbGUgICAgfCAg IDEgKwo+ID4gPiAgZHJpdmVycy91c2IvbXVzYi9tZWRpYXRlay5jICB8IDU2MiArKysrKysrKysr KysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrCj4gPiA+ICBkcml2ZXJzL3VzYi9tdXNi L211c2JfY29yZS5jIHwgIDEwICsKPiA+ID4gIGRyaXZlcnMvdXNiL211c2IvbXVzYl9jb3JlLmgg fCAgIDEgKwo+ID4gPiAgZHJpdmVycy91c2IvbXVzYi9tdXNiX2RtYS5oICB8ICAgMSArCj4gPiA+ ICBkcml2ZXJzL3VzYi9tdXNiL211c2JfaG9zdC5jIHwgIDc5ICsrKystLQo+ID4gPiAgZHJpdmVy cy91c2IvbXVzYi9tdXNiX3JlZ3MuaCB8ICAgNiArCj4gPiA+ICBkcml2ZXJzL3VzYi9tdXNiL211 c2Joc2RtYS5jIHwgIDM0ICsrLQo+ID4gPiAgOSBmaWxlcyBjaGFuZ2VkLCA2NzEgaW5zZXJ0aW9u cygrKSwgMzEgZGVsZXRpb25zKC0pCj4gPiA+ICBjcmVhdGUgbW9kZSAxMDA2NDQgZHJpdmVycy91 c2IvbXVzYi9tZWRpYXRlay5jCj4gPiA+IAo+ID4gPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy91c2Iv bXVzYi9LY29uZmlnIGIvZHJpdmVycy91c2IvbXVzYi9LY29uZmlnCj4gPiA+IGluZGV4IGFkMDg4 OTUuLjU0MGZjOWYgMTAwNjQ0Cj4gPiA+IC0tLSBhL2RyaXZlcnMvdXNiL211c2IvS2NvbmZpZwo+ ID4gPiArKysgYi9kcml2ZXJzL3VzYi9tdXNiL0tjb25maWcKPiA+ID4gQEAgLTExNSw2ICsxMTUs MTIgQEAgY29uZmlnIFVTQl9NVVNCX0paNDc0MAo+ID4gPiAgCWRlcGVuZHMgb24gVVNCX01VU0Jf R0FER0VUCj4gPiA+ICAJZGVwZW5kcyBvbiBVU0JfT1RHX0JMQUNLTElTVF9IVUIKPiA+ID4gIAo+ ID4gPiArY29uZmlnIFVTQl9NVVNCX01FRElBVEVLCj4gPiA+ICsJdHJpc3RhdGUgIk1lZGlhVGVr IHBsYXRmb3JtcyIKPiA+ID4gKwlkZXBlbmRzIG9uIEFSQ0hfTUVESUFURUsKPiA+IAo+ID4gUGxl YXNlIGFsc28gYWRkICd8fCBDT01QSUxFX1RFU1QnIHRvIG1ha2UgdGVzdGluZyBlYXNpZXIuCj4g Cj4gT2sKPiAKPiA+ID4gKwlkZXBlbmRzIG9uIE5PUF9VU0JfWENFSVYKPiA+ID4gKwlkZXBlbmRz IG9uIEdFTkVSSUNfUEhZCj4gPiA+ICsKPiA+ID4gIGNvbmZpZyBVU0JfTVVTQl9BTTMzNVhfQ0hJ TEQKPiA+ID4gIAl0cmlzdGF0ZQo+ID4gPiAgCj4gPiA+IEBAIC0xNDEsNyArMTQ3LDcgQEAgY29u ZmlnIFVTQl9VWDUwMF9ETUEKPiA+ID4gIAo+ID4gPiAgY29uZmlnIFVTQl9JTlZFTlRSQV9ETUEK PiA+ID4gIAlib29sICdJbnZlbnRyYScKPiA+ID4gLQlkZXBlbmRzIG9uIFVTQl9NVVNCX09NQVAy UExVUwo+ID4gPiArCWRlcGVuZHMgb24gVVNCX01VU0JfT01BUDJQTFVTIHx8IFVTQl9NVVNCX01F RElBVEVLCj4gPiA+ICAJaGVscAo+ID4gPiAgCSAgRW5hYmxlIERNQSB0cmFuc2ZlcnMgdXNpbmcg TWVudG9yJ3MgZW5naW5lLgo+ID4gPiAgCj4gPiA+IGRpZmYgLS1naXQgYS9kcml2ZXJzL3VzYi9t dXNiL01ha2VmaWxlIGIvZHJpdmVycy91c2IvbXVzYi9NYWtlZmlsZQo+ID4gPiBpbmRleCAzYTg4 Yzc5Li42M2Q4MmQwIDEwMDY0NAo+ID4gPiAtLS0gYS9kcml2ZXJzL3VzYi9tdXNiL01ha2VmaWxl Cj4gPiA+ICsrKyBiL2RyaXZlcnMvdXNiL211c2IvTWFrZWZpbGUKPiA+ID4gQEAgLTI0LDYgKzI0 LDcgQEAgb2JqLSQoQ09ORklHX1VTQl9NVVNCX0RBOFhYKQkJCSs9IGRhOHh4Lm8KPiA+ID4gIG9i ai0kKENPTkZJR19VU0JfTVVTQl9VWDUwMCkJCQkrPSB1eDUwMC5vCj4gPiA+ICBvYmotJChDT05G SUdfVVNCX01VU0JfSlo0NzQwKQkJCSs9IGp6NDc0MC5vCj4gPiA+ICBvYmotJChDT05GSUdfVVNC X01VU0JfU1VOWEkpCQkJKz0gc3VueGkubwo+ID4gPiArb2JqLSQoQ09ORklHX1VTQl9NVVNCX01F RElBVEVLKSAgICAgIAkJKz0gbWVkaWF0ZWsubwo+ID4gPiAgCj4gPiA+ICAKPiA+ID4gIG9iai0k KENPTkZJR19VU0JfTVVTQl9BTTMzNVhfQ0hJTEQpCQkrPSBtdXNiX2FtMzM1eC5vCj4gPiA+IGRp ZmYgLS1naXQgYS9kcml2ZXJzL3VzYi9tdXNiL21lZGlhdGVrLmMgYi9kcml2ZXJzL3VzYi9tdXNi L21lZGlhdGVrLmMKPiA+ID4gbmV3IGZpbGUgbW9kZSAxMDA2NDQKPiA+ID4gaW5kZXggMDAwMDAw MC4uMTVhNjQ2MAo+ID4gPiAtLS0gL2Rldi9udWxsCj4gPiA+ICsrKyBiL2RyaXZlcnMvdXNiL211 c2IvbWVkaWF0ZWsuYwo+ID4gCj4gPiBbc25pcF0KPiA+IEkgd2lsbCByZXZpZXcgdGhpcyBzZWN0 aW9uIGxhdGVyIGFmdGVyIHdlIHNvcnRlZCBvdXQgb3RoZXIgdGhpbmdzLgo+ID4gCj4gPiA+IGRp ZmYgLS1naXQgYS9kcml2ZXJzL3VzYi9tdXNiL211c2JfY29yZS5jIGIvZHJpdmVycy91c2IvbXVz Yi9tdXNiX2NvcmUuYwo+ID4gPiBpbmRleCBiN2Q1NjI3Li5kNjBmNzZmIDEwMDY0NAo+ID4gPiAt LS0gYS9kcml2ZXJzL3VzYi9tdXNiL211c2JfY29yZS5jCj4gPiA+ICsrKyBiL2RyaXZlcnMvdXNi L211c2IvbXVzYl9jb3JlLmMKPiA+ID4gQEAgLTEwMjgsNiArMTAyOCwxNiBAQCBzdGF0aWMgdm9p ZCBtdXNiX2Rpc2FibGVfaW50ZXJydXB0cyhzdHJ1Y3QgbXVzYiAqbXVzYikKPiA+ID4gIAl0ZW1w ID0gbXVzYl9yZWFkYihtYmFzZSwgTVVTQl9JTlRSVVNCKTsKPiA+ID4gIAl0ZW1wID0gbXVzYl9y ZWFkdyhtYmFzZSwgTVVTQl9JTlRSVFgpOwo+ID4gPiAgCXRlbXAgPSBtdXNiX3JlYWR3KG1iYXNl LCBNVVNCX0lOVFJSWCk7Cj4gPiA+ICsKPiA+ID4gKwkvKiAgTWVkaWFUZWsgY29udHJvbGxlciBp bnRlcnJ1cHQgc3RhdHVzIGlzIFcxQyAqLwo+ID4gCj4gPiBUaGlzIFcxQyBkb2Vzbid0IG1hdGNo IHRvIHRoZSBNVVNCIFByb2dyYW1taW5nIEd1aWRlIHRoYXQgSSBoYXZlLiBUaG9zZQo+ID4gcmVn aXN0ZXJzIGFyZSByZWFkLW9ubHkuCj4gPiBJcyB0aGUgZGlmZmVyZW5jZSBkdWUgdG8gdGhlIElQ IGludGVyZ3JhdGlvbiBpbiB0aGUgbXRrIHBsYXRmb3Jtcz8gb3IgaXMKPiA+IGl0IGEgbmV3IHZl cnNpb24gb2YgdGhlIE1VU0IgY29udHJvbGxlcj8gSWYgbGF0dGVyLCB3aGF0IGlzIHRoZSB2ZXJz aW9uPwo+IAo+IFRoaXMgaXMgZGlmZmVyZW5jZSBkdWUgdG8gdGhlIElQIGludGVyZ3JhdGlvbiBp biBtdGsgcGxhdGZvcm1zLiBXMUMgaXMKPiBlYXN5IGZvciBDcGRlVmlzZXIgZGVidWcuCj4gCj4g PiA+ICsJaWYgKG11c2ItPm9wcy0+cXVpcmtzICYgTVVTQl9NVEtfUVVJUktTKSB7Cj4gPiAKPiA+ IEJhc2ljYWxseSB3ZSBkb24ndCB3YW50IHRvIHVzZSB0aGlzIHR5cGUgb2YgcGxhdGZvcm0gc3Bl Y2lmaWMgcXVpcmtzIGlmCj4gPiBwb3NzaWJsZSwgc28gbGV0J3MgdHJ5IHRvIG5vdCB1c2UgaXQu Cj4gCj4gSSB3aWxsIHRyeSBteSBiZXN0IHRvIGF2b2lkIHVzaW5nIGl0LgoKVGhhbmtzLgoKPiAK PiA+ID4gKwkJbXVzYl93cml0ZWIobWJhc2UsIE1VU0JfSU5UUlVTQiwKPiA+ID4gKwkJCW11c2Jf cmVhZGIobWJhc2UsIE1VU0JfSU5UUlVTQikpOwo+ID4gCj4gPiBGb3IgdGhpcyBjbGVhcmluZyBy ZWdpc3RlciBiaXQgb3BlcmF0aW9uLCBwbGVhc2UgY3JlYXRlIHBsYXRmb3JtIGhvb2tzCj4gPiBt dXNiX2NsZWFyYigpIGFuZCBtdXNiX2NsZWFydygpIGluIHN0cnVjdCBtdXNiX3BsYXRmb3JtX29w cyBpbnN0ZWFkLAo+ID4gdGhlbiBmb2xsb3cgaG93IG11c2JfcmVhZGIoKSBwb2ludGVyIGlzIGFz c2lnbmVkIGluCj4gPiBtdXNiX2luaXRfY29udHJvbGxlcigpIHRvIHVzZSB0aGUgVzFDIHZlcnNp b24gZm9yIG10ayBwbGF0Zm9ybS4KPiAKPiBJIGhhdmUgdHJpZWQgaW1wbGVtZW50aW5nIG11c2Jf cmVhZGIoKSwgbXVzYl9yZWFkdygpIGludGVyZmFjZSB3aXRoCj4gaW50ZXJydXB0IHN0YXR1cyBX MUMgZnVuY3Rpb24gaW4gc3RydWN0IG11c2JfcGxhdGZvcm1fb3BzLiBCdXQgdGhpcwo+IGludGVy ZmFjZSB3aWxsIHJlcXVpcmUgYSBnbG9iYWwgdmFyaWFibGUgdG8gaG9sZCBNQUMgYmFzaWMgYWRk cmVzcyBmb3IKPiBqdWRnbWVudCwgYW5kIHRoZW4gc3BlY2lhbCBoYW5kbGluZyBvZiB0aGUgaW50 ZXJydXB0IHN0YXRlLiBBIGdsb2JhbAo+IHZhcmlhYmxlIHdpbGwgbWFrZSB0aGUgZHJpdmVyIHdv cmsgd2l0aCBvbmx5IGEgc2luZ2xlIGluc3RhbmNlLCBzbyBpdAo+IGNhbid0IHdvcmsgb24gc29t ZSBNVEsgcGxhdGZvcm1zIHdoaWNoIGhhdmUgdHdvIGluc3RhbmNlcy4KCkkgZGlkbid0IG1lYW4g dG8gbW9kaWZ5IG11c2JfcmVhZCooKSwgYnV0Cgo+IEhvdyBhYm91dCBjcmVhdGluZyBtdXNiX2Ns ZWFyYi93KCkgYXMgZm9sbG93aW5nOgo+IHZvaWQgKCpjbGVhcmIpKHZvaWQgX19pb21lbSAqYWRk ciwgdW5zaWduZWQgb2Zmc2V0LCB1OCBkYXRhKTsKPiB2b2lkICgqY2xlYXJ3KSh2b2lkIF9faW9t ZW0gKmFkZHIsIHVuc2lnbmVkIG9mZnNldCwgdTE2IGRhdGEpOwoKdGhpcyBpcyB3aGF0IEkgd2Fz IGFza2luZyBmb3IsIHNpbWlsYXIgdG8gd2hhdCBtdXNiX3JlYWRiL3coKSBpcwppbXBsZW1lbnRl ZC4KCj4gCj4gCj4gPiA+ICsJCW11c2Jfd3JpdGV3KG1iYXNlLCBNVVNCX0lOVFJSWCwKPiA+ID4g KwkJCW11c2JfcmVhZHcobWJhc2UsIE1VU0JfSU5UUlJYKSk7Cj4gPiA+ICsJCW11c2Jfd3JpdGV3 KG1iYXNlLCBNVVNCX0lOVFJUWCwKPiA+ID4gKwkJCW11c2JfcmVhZHcobWJhc2UsIE1VU0JfSU5U UlRYKSk7Cj4gPiA+ICsJfQo+ID4gPiAgfQo+ID4gPiAgCj4gPiA+ICBzdGF0aWMgdm9pZCBtdXNi X2VuYWJsZV9pbnRlcnJ1cHRzKHN0cnVjdCBtdXNiICptdXNiKQo+ID4gPiBkaWZmIC0tZ2l0IGEv ZHJpdmVycy91c2IvbXVzYi9tdXNiX2NvcmUuaCBiL2RyaXZlcnMvdXNiL211c2IvbXVzYl9jb3Jl LmgKPiA+ID4gaW5kZXggMDQyMDNiNy4uMWJmNGU5YSAxMDA2NDQKPiA+ID4gLS0tIGEvZHJpdmVy cy91c2IvbXVzYi9tdXNiX2NvcmUuaAo+ID4gPiArKysgYi9kcml2ZXJzL3VzYi9tdXNiL211c2Jf Y29yZS5oCj4gPiA+IEBAIC0xMzgsNiArMTM4LDcgQEAgZW51bSBtdXNiX2dfZXAwX3N0YXRlIHsK PiA+ID4gICAqLwo+ID4gPiAgc3RydWN0IG11c2JfcGxhdGZvcm1fb3BzIHsKPiA+ID4gIAo+ID4g PiArI2RlZmluZSBNVVNCX01US19RVUlSS1MJQklUKDEwKQo+ID4gPiAgI2RlZmluZSBNVVNCX0df Tk9fU0tCX1JFU0VSVkUJQklUKDkpCj4gPiA+ICAjZGVmaW5lIE1VU0JfREE4WFgJCUJJVCg4KQo+ ID4gPiAgI2RlZmluZSBNVVNCX1BSRVNFUlZFX1NFU1NJT04JQklUKDcpCj4gPiA+IGRpZmYgLS1n aXQgYS9kcml2ZXJzL3VzYi9tdXNiL211c2JfZG1hLmggYi9kcml2ZXJzL3VzYi9tdXNiL211c2Jf ZG1hLmgKPiA+ID4gaW5kZXggMjgxZTc1ZDMuLmIyMTgyMTAgMTAwNjQ0Cj4gPiA+IC0tLSBhL2Ry aXZlcnMvdXNiL211c2IvbXVzYl9kbWEuaAo+ID4gPiArKysgYi9kcml2ZXJzL3VzYi9tdXNiL211 c2JfZG1hLmgKPiA+ID4gQEAgLTE5Nyw2ICsxOTcsNyBAQCBzdGF0aWMgaW5saW5lIHZvaWQgbXVz Yl9kbWFfY29udHJvbGxlcl9kZXN0cm95KHN0cnVjdCBkbWFfY29udHJvbGxlciAqZCkgeyB9Cj4g PiA+ICBleHRlcm4gc3RydWN0IGRtYV9jb250cm9sbGVyICoKPiA+ID4gIG11c2Joc19kbWFfY29u dHJvbGxlcl9jcmVhdGUoc3RydWN0IG11c2IgKm11c2IsIHZvaWQgX19pb21lbSAqYmFzZSk7Cj4g PiA+ICBleHRlcm4gdm9pZCBtdXNiaHNfZG1hX2NvbnRyb2xsZXJfZGVzdHJveShzdHJ1Y3QgZG1h X2NvbnRyb2xsZXIgKmMpOwo+ID4gPiArZXh0ZXJuIGlycXJldHVybl90IGRtYV9jb250cm9sbGVy X2lycShpbnQgaXJxLCB2b2lkICpwcml2YXRlX2RhdGEpOwo+ID4gPiAgCj4gPiA+ICBleHRlcm4g c3RydWN0IGRtYV9jb250cm9sbGVyICoKPiA+ID4gIHR1c2JfZG1hX2NvbnRyb2xsZXJfY3JlYXRl KHN0cnVjdCBtdXNiICptdXNiLCB2b2lkIF9faW9tZW0gKmJhc2UpOwo+ID4gPiBkaWZmIC0tZ2l0 IGEvZHJpdmVycy91c2IvbXVzYi9tdXNiX2hvc3QuYyBiL2RyaXZlcnMvdXNiL211c2IvbXVzYl9o b3N0LmMKPiA+ID4gaW5kZXggYjU5Y2U5YS4uYjFiMDIxNiAxMDA2NDQKPiA+ID4gLS0tIGEvZHJp dmVycy91c2IvbXVzYi9tdXNiX2hvc3QuYwo+ID4gPiArKysgYi9kcml2ZXJzL3VzYi9tdXNiL211 c2JfaG9zdC5jCj4gPiA+IEBAIC0yOTIsMjAgKzI5Miw3MyBAQCBzdGF0aWMgaW5saW5lIHZvaWQg bXVzYl9zYXZlX3RvZ2dsZShzdHJ1Y3QgbXVzYl9xaCAqcWgsIGludCBpc19pbiwKPiA+ID4gIHsK PiA+ID4gIAl2b2lkIF9faW9tZW0JCSplcGlvID0gcWgtPmh3X2VwLT5yZWdzOwo+ID4gPiAgCXUx NgkJCWNzcjsKPiA+ID4gKwlzdHJ1Y3QgbXVzYiAqbXVzYiA9IHFoLT5od19lcC0+bXVzYjsKPiA+ ID4gIAo+ID4gPiAgCS8qCj4gPiA+ICAJICogRklYTUU6IHRoZSBjdXJyZW50IE1lbnRvciBETUEg Y29kZSBzZWVtcyB0byBoYXZlCj4gPiA+ICAJICogcHJvYmxlbXMgZ2V0dGluZyB0b2dnbGUgY29y cmVjdC4KPiA+ID4gIAkgKi8KPiA+ID4gIAo+ID4gPiAtCWlmIChpc19pbikKPiA+ID4gLQkJY3Ny ID0gbXVzYl9yZWFkdyhlcGlvLCBNVVNCX1JYQ1NSKSAmIE1VU0JfUlhDU1JfSF9EQVRBVE9HR0xF Owo+ID4gPiAtCWVsc2UKPiA+ID4gLQkJY3NyID0gbXVzYl9yZWFkdyhlcGlvLCBNVVNCX1RYQ1NS KSAmIE1VU0JfVFhDU1JfSF9EQVRBVE9HR0xFOwo+ID4gPiArCS8qIE1lZGlhVGVrIGNvbnRyb2xs ZXIgaGFzIHByaXZhdGUgdG9nZ2xlIHJlZ2lzdGVyICovCj4gPiAKPiA+IG9ubHkgb25lIHRvZ2ds ZSByZWdpc3RlciBmb3IgYWxsIGVuZHBvaW50cz8gaG93IGRvZXMgaXQgaGFuZGxlCj4gPiBkaWZm ZXJlbmNlIHRvZ2dsZSB2YWx1ZXMgZm9yIGRpZmZlcmVudCBlbmRwb2ludHM/Cj4gCj4gTWVkaWFU ZWsgY29udHJvbGxlciBoYXMgc2VwYXJhdGUgcmVnaXN0ZXJzIHRvIGRlc2NyaWJlIFRYL1JYIHRv Z2dsZS4KCklzIGl0IG9uZSByZWdpc3RlciBwZXIgZW5kcG9pbnQ/Cgo+IAo+ID4gPiArCWlmICht dXNiLT5vcHMtPnF1aXJrcyAmIE1VU0JfTVRLX1FVSVJLUykgewo+ID4gPiArCQl1MTYgdG9nZ2xl Owo+ID4gPiArCQl1OCBlcG51bSA9IHFoLT5od19lcC0+ZXBudW07Cj4gPiA+ICsKPiA+ID4gKwkJ aWYgKGlzX2luKQo+ID4gPiArCQkJdG9nZ2xlID0gbXVzYl9yZWFkbChtdXNiLT5tcmVncywgTVVT Ql9SWFRPRyk7Cgp0aGlzIGxpbmUgc2VlbXMgdGVsbGluZyB0aGVyZSBpcyBqdXN0ICpvbmUqIHJl Z2lzdGVyIGZvciBhbGwgZW5kcG9pbnRzLgoKPiA+IAo+ID4gc2hvdWxkIHVzZSBtdXNiX3JlYWR3 KCkgaW5zdGVhZD8gTVVTQl9SWFRPRyBzZWVtcyB0byBiZSAxNmJpdC4KPiAKPiBPawo+IAo+ID4g PiArCQllbHNlCj4gPiA+ICsJCQl0b2dnbGUgPSBtdXNiX3JlYWRsKG11c2ItPm1yZWdzLCBNVVNC X1RYVE9HKTsKPiA+ID4gKwo+ID4gPiArCQljc3IgPSB0b2dnbGUgJiAoMSA8PCBlcG51bSk7Cj4g PiA+ICsJfSBlbHNlIHsKPiA+ID4gKwkJaWYgKGlzX2luKQo+ID4gPiArCQkJY3NyID0gbXVzYl9y ZWFkdyhlcGlvLCBNVVNCX1JYQ1NSKQo+ID4gPiArCQkJCSYgTVVTQl9SWENTUl9IX0RBVEFUT0dH TEU7Cj4gPiA+ICsJCWVsc2UKPiA+ID4gKwkJCWNzciA9IG11c2JfcmVhZHcoZXBpbywgTVVTQl9U WENTUikKPiA+ID4gKwkJCQkmIE1VU0JfVFhDU1JfSF9EQVRBVE9HR0xFOwo+ID4gCj4gPiBEb2Vz IHRoaXMgbG9naWMgc3RpbGwgd29yayBmb3IgdGhlIG10ayBwbGF0Zm9ybSBldmVuIGlmIGl0IGhh cyBpdHMgb3duCj4gPiBwcml2YXRlIHRvZ2dsZSByZWdpc3Rlcj8gSWYgc28sIHdlIGRvbid0IG5l ZWQgdG8gY2hhbmdlIGhlcmUuCj4gCj4gU29ycnksIHRoaXMgbG9naWMgY2FuIG5vdCB3b3JrIG9u IG10ayBwbGF0Zm9ybSwgYml0Cj4gTVVTQl9SWENTUl9IX0RBVEFUT0dHTEUgYW5kIE1VU0JfVFhD U1JfSF9EQVRBVE9HR0xFIGFyZSB1c2VkIGZvciBvdGhlcgo+IGZ1bmN0aW9uLgoKSXMgdGhlcmUg YSBkaWZmZXJlbnQgY29udHJvbGxlciBSVEwgdmVyc2lvbiB3ZSBjYW4gdXNlIHRvCmRpZmZlcmVu dGlhdGU/Cgo+IAo+ID4gSWYgbm90LCBsZXQncyB0cnkgdG8gbm90IHVzZSB0aGlzIHF1aXJrIGZs YWcuIFBsZWFzZSBjcmVhdGUgYSBob29rCj4gPiBtdXNiX3BsYXRmb3JtX2dldF90b2dnbGUoKSBp biBzdHJ1Y3QgbXVzYl9wbGF0Zm9ybV9vcHMuCj4gCj4gRG9lcyB0aGUgbWV0aG9kIG9mIGltcGxl bWVudCBtdXNiX3BsYXRmb3JtX2dldF90b2dnbGUoKSBpcyBwcmVwYXJlCj4gbXVzYl9kZWZhdWx0 X2dldF90b2dnbGUgd2l0aCBjb21tb24gZnVuY3Rpb24sIHRoZW4gZm9sbG93IGhvdwo+IG11c2Jf cmVhZGIoKSBwb2ludGVyIGlzIGFzc2lnbmVkIGluIG11c2JfaW5pdF9jb250cm9sbGVyKCk/CgpZ ZXMsIHNpbWlsYXIgdG8gbXVzYl9yZWFkYigpIGltcGxlbWVudGF0aW9uLgoKPiBIb3cgYWJvdXQg Y3JlYXRpbmcgbXVzYl9wbGF0Zm9ybV9nZXRfdG9nZ2xlKCkgYXMgZm9sbG93aW5nOgo+IHUxNiAo KmdldF90b2dnbGUpKHN0cnVjdCBtdXNiKiBtdXNiLCBzdHJ1Y3QgbXVzYl9xaCAqcWgsIGludCBp c19pbik7Cgp5ZXMsIGl0IGlzIHBhcnQgb2YgdGhlIGltcGxlbWVudGF0aW9uLCB0aGVuIGFkZCBp dCBpbiBzdHJ1Y3QgbXVzYl9pby4KCj4gCj4gPiA+ICsJfQo+ID4gPiAgCj4gPiA+ICAJdXNiX3Nl dHRvZ2dsZSh1cmItPmRldiwgcWgtPmVwbnVtLCAhaXNfaW4sIGNzciA/IDEgOiAwKTsKPiA+ID4g IH0KPiA+ID4gIAo+ID4gPiArc3RhdGljIGlubGluZSB1MTYgbXVzYl9zZXRfdG9nZ2xlKHN0cnVj dCBtdXNiX3FoICpxaCwgaW50IGlzX2luLAo+ID4gPiArCQkJCQlzdHJ1Y3QgdXJiICp1cmIpCj4g PiA+ICt7Cj4gPiA+ICsJdTE2IGNzciA9IDA7Cj4gPiA+ICsJdTE2IHRvZ2dsZSA9IDA7Cj4gPiA+ ICsJc3RydWN0IG11c2IgKm11c2IgPSBxaC0+aHdfZXAtPm11c2I7Cj4gPiA+ICsJdTggZXBudW0g PSBxaC0+aHdfZXAtPmVwbnVtOwo+ID4gPiArCj4gPiA+ICsJdG9nZ2xlID0gdXNiX2dldHRvZ2ds ZSh1cmItPmRldiwgcWgtPmVwbnVtLCAhaXNfaW4pOwo+ID4gPiArCj4gPiA+ICsJLyogTWVkaWFU ZWsgY29udHJvbGxlciBoYXMgcHJpdmF0ZSB0b2dnbGUgcmVnaXN0ZXIgKi8KPiA+ID4gKwlpZiAo bXVzYi0+b3BzLT5xdWlya3MgJiBNVVNCX01US19RVUlSS1MpIHsKPiA+ID4gKwkJaWYgKGlzX2lu KSB7Cj4gPiA+ICsJCQltdXNiX3dyaXRlbChtdXNiLT5tcmVncywgTVVTQl9SWFRPR0VOLCAoMSA8 PCBlcG51bSkpOwo+ID4gPiArCQkJbXVzYl93cml0ZWwobXVzYi0+bXJlZ3MsIE1VU0JfUlhUT0cs ICh0b2dnbGUgPDwgZXBudW0pKTsKPiA+ID4gKwkJfSBlbHNlIHsKPiA+ID4gKwkJCW11c2Jfd3Jp dGVsKG11c2ItPm1yZWdzLCBNVVNCX1RYVE9HRU4sICgxIDw8IGVwbnVtKSk7Cj4gPiA+ICsJCQlt dXNiX3dyaXRlbChtdXNiLT5tcmVncywgTVVTQl9UWFRPRywgKHRvZ2dsZSA8PCBlcG51bSkpOwo+ ID4gPiArCQl9Cj4gPiA+ICsJfSBlbHNlIHsKPiA+ID4gKwkJaWYgKGlzX2luKSB7Cj4gPiA+ICsJ CQlpZiAodG9nZ2xlKQo+ID4gPiArCQkJCWNzciA9IE1VU0JfUlhDU1JfSF9XUl9EQVRBVE9HR0xF Cj4gPiA+ICsJCQkJCQl8IE1VU0JfUlhDU1JfSF9EQVRBVE9HR0xFOwo+ID4gPiArCQkJZWxzZQo+ ID4gPiArCQkJCWNzciA9IDA7Cj4gPiA+ICsJCX0gZWxzZSB7Cj4gPiA+ICsJCQlpZiAodG9nZ2xl KQo+ID4gPiArCQkJCWNzciB8PSBNVVNCX1RYQ1NSX0hfV1JfREFUQVRPR0dMRQo+ID4gPiArCQkJ CQkJfCBNVVNCX1RYQ1NSX0hfREFUQVRPR0dMRTsKPiA+ID4gKwkJCWVsc2UKPiA+ID4gKwkJCQlj c3IgfD0gTVVTQl9UWENTUl9DTFJEQVRBVE9HOwoKJz8gOicgb3BlcmF0aW9uIHByb2JhYmx5IGlz IGJldHRlciB0aGFuICdpZiBlbHNlJyBoZXJlLgoKPiA+ID4gKwkJfQo+ID4gPiArCX0KPiA+ID4g KwlyZXR1cm4gY3NyOwo+ID4gCj4gPiBQbGVhc2UgY3JlYXRlIGEgc2VwZXJhdGUgcGF0Y2ggZm9y IHRoaXMgbXVzYl9zZXRfdG9nZ2xlKCkgd2l0aG91dCBhZGRpbmcKPiA+IHRoZSBtdGsgbG9naWMu IEl0IGlzIGEgbmljZSBjbGVhbnVwLgo+IAo+IERvZXMgdGhpcyBsaWtlIGdldCB0b2dnbGUgaW1w bGVtZW50YXRpb24sIGNyZWF0ZSBhIGhvb2sKPiBtdXNiX3BsYXRmb3JtX3NldF90b2dnbGUoKSBp biBzdHJ1Y3QgbXVzYl9wbGF0Zm9ybV9vcHM/CgpZb3UgZGlkIHRoZSBjb2RlIGNsZWFudXAgYnkg Y3JlYXRpbmcgbXVzYl9zZXRfdG9nZ2xlKCksIHBsZWFzZSBtYWtlIGl0CmluIGEgc2VwYXJhdGUg cGF0Y2gsIGxpa2UKCnN0YXRpYyB1MTYgbXVzYl9zZXRfdG9nZ2xlKHN0cnVjdCBtdXNiX3FoICpx aCwgaW50IGlzX2luLCBzdHJ1Y3QgdXJiICp1cmIpCnsKCXRvZ2dsZSA9IHVzYl9nZXR0b2dnbGUo dXJiLT5kZXYsIHFoLT5lcG51bSwgIWlzX2luKTsKCWlmIChpc19pbikKCQljc3IgPSB0b2dnbGUg PyAKCQkJKE1VU0JfUlhDU1JfSF9XUl9EQVRBVE9HR0xFIHwgTVVTQl9SWENTUl9IX0RBVEFUT0dH TEUpIDoKCQkJMDsKCWVsc2UKCQljc3IgPSB0b2dnbGUgPwoJCQlNVVNCX1RYQ1NSX0hfV1JfREFU QVRPR0dMRSB8IE1VU0JfVFhDU1JfSF9EQVRBVE9HR0xFIDoKCQkJTVVTQl9UWENTUl9DTFJEQVRB VE9HOwoJcmV0dXJuIGNzcjsKfQoKLyogdXNlIG11c2Jfc2V0X3RvZ2dsZSgpIGluIHRoZSB0d28g aW5zdGFuY2VzICovCgp0aGVuIGluIHRoaXMgcGF0Y2ggeW91IGFkZCB0aGUgbXRrIGltcGxlbWVu dGF0aW9uIHNpbWlsYXIgYXMKKmdldF90b2dnbGUoKSBkaXNjdXNzZWQgYWJvdmUuCgo+IAo+ID4g PiArfQo+ID4gPiArCj4gPiA+ICAvKgo+ID4gPiAgICogQWR2YW5jZSB0aGlzIGhhcmR3YXJlIGVu ZHBvaW50J3MgcXVldWUsIGNvbXBsZXRpbmcgdGhlIHNwZWNpZmllZCBVUkIgYW5kCj4gPiA+ICAg KiBhZHZhbmNpbmcgdG8gZWl0aGVyIHRoZSBuZXh0IFVSQiBxdWV1ZWQgdG8gdGhhdCBxaCwgb3Ig ZWxzZSBpbnZhbGlkYXRpbmcKPiA+ID4gQEAgLTc3MiwxMyArODI1LDggQEAgc3RhdGljIHZvaWQg bXVzYl9lcF9wcm9ncmFtKHN0cnVjdCBtdXNiICptdXNiLCB1OCBlcG51bSwKPiA+ID4gIAkJCQkJ KTsKPiA+ID4gIAkJCWNzciB8PSBNVVNCX1RYQ1NSX01PREU7Cj4gPiA+ICAKPiA+ID4gLQkJCWlm ICghaHdfZXAtPnR4X2RvdWJsZV9idWZmZXJlZCkgewo+ID4gPiAtCQkJCWlmICh1c2JfZ2V0dG9n Z2xlKHVyYi0+ZGV2LCBxaC0+ZXBudW0sIDEpKQo+ID4gPiAtCQkJCQljc3IgfD0gTVVTQl9UWENT Ul9IX1dSX0RBVEFUT0dHTEUKPiA+ID4gLQkJCQkJCXwgTVVTQl9UWENTUl9IX0RBVEFUT0dHTEU7 Cj4gPiA+IC0JCQkJZWxzZQo+ID4gPiAtCQkJCQljc3IgfD0gTVVTQl9UWENTUl9DTFJEQVRBVE9H Owo+ID4gPiAtCQkJfQo+ID4gPiArCQkJaWYgKCFod19lcC0+dHhfZG91YmxlX2J1ZmZlcmVkKQo+ ID4gPiArCQkJCWNzciB8PSBtdXNiX3NldF90b2dnbGUocWgsICFpc19vdXQsIHVyYik7Cj4gPiA+ ICAKPiA+ID4gIAkJCW11c2Jfd3JpdGV3KGVwaW8sIE1VU0JfVFhDU1IsIGNzcik7Cj4gPiA+ICAJ CQkvKiBSRVZJU0lUIG1heSBuZWVkIHRvIGNsZWFyIEZMVVNIRklGTyAuLi4gKi8KPiA+ID4gQEAg LTg2MCwxNyArOTA4LDEyIEBAIHN0YXRpYyB2b2lkIG11c2JfZXBfcHJvZ3JhbShzdHJ1Y3QgbXVz YiAqbXVzYiwgdTggZXBudW0sCj4gPiA+ICAKPiA+ID4gIAkvKiBJTi9yZWNlaXZlICovCj4gPiA+ ICAJfSBlbHNlIHsKPiA+ID4gLQkJdTE2CWNzcjsKPiA+ID4gKwkJdTE2CWNzciA9IDA7Cj4gPiA+ ICAKPiA+ID4gIAkJaWYgKGh3X2VwLT5yeF9yZWluaXQpIHsKPiA+ID4gIAkJCW11c2JfcnhfcmVp bml0KG11c2IsIHFoLCBlcG51bSk7Cj4gPiA+ICsJCQljc3IgfD0gbXVzYl9zZXRfdG9nZ2xlKHFo LCAhaXNfb3V0LCB1cmIpOwo+ID4gPiAgCj4gPiA+IC0JCQkvKiBpbml0IG5ldyBzdGF0ZTogdG9n Z2xlIGFuZCBOWUVULCBtYXliZSBETUEgbGF0ZXIgKi8KPiA+ID4gLQkJCWlmICh1c2JfZ2V0dG9n Z2xlKHVyYi0+ZGV2LCBxaC0+ZXBudW0sIDApKQo+ID4gPiAtCQkJCWNzciA9IE1VU0JfUlhDU1Jf SF9XUl9EQVRBVE9HR0xFCj4gPiA+IC0JCQkJCXwgTVVTQl9SWENTUl9IX0RBVEFUT0dHTEU7Cj4g PiA+IC0JCQllbHNlCj4gPiA+IC0JCQkJY3NyID0gMDsKPiA+ID4gIAkJCWlmIChxaC0+dHlwZSA9 PSBVU0JfRU5EUE9JTlRfWEZFUl9JTlQpCj4gPiA+ICAJCQkJY3NyIHw9IE1VU0JfUlhDU1JfRElT TllFVDsKPiA+ID4gIAo+ID4gPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy91c2IvbXVzYi9tdXNiX3Jl Z3MuaCBiL2RyaXZlcnMvdXNiL211c2IvbXVzYl9yZWdzLmgKPiA+ID4gaW5kZXggNWNkNzI2NC4u ZmZiZTI2NyAxMDA2NDQKPiA+ID4gLS0tIGEvZHJpdmVycy91c2IvbXVzYi9tdXNiX3JlZ3MuaAo+ ID4gPiArKysgYi9kcml2ZXJzL3VzYi9tdXNiL211c2JfcmVncy5oCj4gPiA+IEBAIC0yNzMsNiAr MjczLDEyIEBACj4gPiA+ICAjZGVmaW5lIE1VU0JfUlhIVUJBRERSCQkweDA2Cj4gPiA+ICAjZGVm aW5lIE1VU0JfUlhIVUJQT1JUCQkweDA3Cj4gPiA+ICAKPiA+ID4gKy8qIE1lZGlhVGVrIGNvbnRy b2xsZXIgdG9nZ2xlIGVuYWJsZSBhbmQgc3RhdHVzIHJlZyAqLwo+ID4gPiArI2RlZmluZSBNVVNC X1JYVE9HCQkweDgwCj4gPiA+ICsjZGVmaW5lIE1VU0JfUlhUT0dFTgkJMHg4Mgo+ID4gPiArI2Rl ZmluZSBNVVNCX1RYVE9HCQkweDg0Cj4gPiA+ICsjZGVmaW5lIE1VU0JfVFhUT0dFTgkJMHg4Ngo+ ID4gCj4gPiBBZ2FpbiwgdGhlc2Ugb2Zmc2V0cyBhcmUgZm9yIGRpZmZlcmVudCByZWdpc3RlcnMg aW4gdGhlIE1VU0IgdmVyc2lvbiBJCj4gPiBoYXZlLCBwbGVhc2UgbGV0IG1lIGtub3cgaWYgeW91 IGhhdmUgZGlmZmVyZW50IHZlcnNpb24gb2YgdGhlIE1VU0IgSVAuCj4gCj4gU29ycnksIHRoZXNl IGFyZSBNZWRpYVRlayBjb250cm9sbGVyIHByaXZhdGUgcmVnaXN0ZXJzIHVzZWQgZm9yIGNvbnRy b2wKPiB0b2dnbGUuCgpPa2F5LiBPbmNlIHRoZSBwbGF0Zm9ybSBnZXQvc2V0X3RvZ2dsZSgpIGFy ZSBpbXBsZW1lbnRlZCwgdGhvc2UKcmVnaXN0ZXJzIGNhbiBiZSBkZWZpbmVkIGluIHRoZSBtdGsg Z2x1ZSBkcml2ZXIgaW5zdGVhZCBvZiBoZXJlLgoKUmVnYXJkcywKLUJpbi4K From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.1 required=3.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_PASS,URIBL_BLOCKED,USER_AGENT_MUTT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 78E67C43444 for ; Wed, 9 Jan 2019 14:02:05 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 36B31206B7 for ; Wed, 9 Jan 2019 14:02:05 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="Pq3vrNVy"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=ti.com header.i=@ti.com header.b="mFO3yvmM" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 36B31206B7 Authentication-Results: mail.kernel.org; dmarc=fail (p=quarantine dis=none) header.from=ti.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+infradead-linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:In-Reply-To:MIME-Version:References: Message-ID:Subject:To:From:Date:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=RoVFHSo8+xiTIliNYI8g6BmEJE4eKLo3Gl1CNjNRFEo=; b=Pq3vrNVyzdD3pK hHuF/hEKFBrStlIe0WvVX0ypQdkhPamfw/h9M8CgN9p/hkswT1rzs9t7pEXjF8m/dG9t9k0beno9y Um8ozCXCv8e//FFU3ckwnVzo3O1giwhUd7ENX0uQBO+RSGdmkBI+4E7q8s/km5eTHTIeYfDq04BOq wixni8xExR/hz1H3OLTPs5ObszQf/7MQ9248bWTdVa9a5Y/zqPbC41ECfeiAwmTW2Y86w3mFasXu0 rNPys2YgY6QEDvewc9oY4Y+A2q9aHnpPZmasJvkMa4q+M2JFN4zHAejZ711POAmHXf/i4WaqTfz0p HPNqQOkPGYFZG3z2Rkig==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1ghEQe-00018J-Q9; Wed, 09 Jan 2019 14:01:56 +0000 Received: from fllv0016.ext.ti.com ([198.47.19.142]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1ghEQa-00017S-LM; Wed, 09 Jan 2019 14:01:55 +0000 Received: from lelv0265.itg.ti.com ([10.180.67.224]) by fllv0016.ext.ti.com (8.15.2/8.15.2) with ESMTP id x09E1jt4074972; Wed, 9 Jan 2019 08:01:45 -0600 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1547042505; bh=kNWJm0hE9mBYzeNeFj1CD0GYB6k0bEM5j9ZvLuhaUEs=; h=Date:From:To:CC:Subject:References:In-Reply-To; b=mFO3yvmM09Y6FRNElLAz77t5VmcmxtPmdO5AQTWfPUSPFtZZPZpSnow6xsN2H1JGD //wRnKvuYIKiPLvFUsG+6CUoL2tpoGPkAYWFJWWb5PJWFi7fMjKicIh12funzsH4e8 K4Wq6XTUHHY4G/jMVoXD5iD21MXoLCLbrjowKyNw= Received: from DFLE100.ent.ti.com (dfle100.ent.ti.com [10.64.6.21]) by lelv0265.itg.ti.com (8.15.2/8.15.2) with ESMTPS id x09E1juH040143 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Wed, 9 Jan 2019 08:01:45 -0600 Received: from DFLE101.ent.ti.com (10.64.6.22) by DFLE100.ent.ti.com (10.64.6.21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1591.10; Wed, 9 Jan 2019 08:01:45 -0600 Received: from dflp32.itg.ti.com (10.64.6.15) by DFLE101.ent.ti.com (10.64.6.22) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_RSA_WITH_AES_256_CBC_SHA) id 15.1.1591.10 via Frontend Transport; Wed, 9 Jan 2019 08:01:45 -0600 Received: from localhost (ileax41-snat.itg.ti.com [10.172.224.153]) by dflp32.itg.ti.com (8.14.3/8.13.8) with ESMTP id x09E1jOO025727; Wed, 9 Jan 2019 08:01:45 -0600 Date: Wed, 9 Jan 2019 08:01:44 -0600 From: Bin Liu To: Min Guo Subject: Re: [PATCH 4/4] usb: musb: Add support for MediaTek musb controller Message-ID: <20190109140144.GI25910@uda0271908> Mail-Followup-To: Bin Liu , Min Guo , Rob Herring , Greg Kroah-Hartman , Mark Rutland , Matthias Brugger , Alan Stern , chunfeng.yun@mediatek.com, linux-usb@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org, Yonglong Wu References: <1545896066-897-1-git-send-email-min.guo@mediatek.com> <1545896066-897-5-git-send-email-min.guo@mediatek.com> <20190108154441.GG25910@uda0271908> <1547037068.4433.122.camel@mhfsdcap03> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <1547037068.4433.122.camel@mhfsdcap03> User-Agent: Mutt/1.5.21 (2010-09-15) X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190109_060152_836278_D2C35948 X-CRM114-Status: GOOD ( 49.71 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Mark Rutland , devicetree@vger.kernel.org, Yonglong Wu , Greg Kroah-Hartman , linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, Matthias Brugger , Rob Herring , Alan Stern , chunfeng.yun@mediatek.com, linux-mediatek@lists.infradead.org, linux-arm-kernel@lists.infradead.org Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+infradead-linux-arm-kernel=archiver.kernel.org@lists.infradead.org Hi Min, On Wed, Jan 09, 2019 at 08:31:08PM +0800, Min Guo wrote: > Hi Bin, > On Tue, 2019-01-08 at 09:44 -0600, Bin Liu wrote: > > Hi, > > > > On Thu, Dec 27, 2018 at 03:34:26PM +0800, min.guo@mediatek.com wrote: > > > From: Min Guo > > > > > > This adds support for MediaTek musb controller in > > > host, peripheral and otg mode > > > > > > Signed-off-by: Min Guo > > > Signed-off-by: Yonglong Wu > > > --- > > > drivers/usb/musb/Kconfig | 8 +- > > > drivers/usb/musb/Makefile | 1 + > > > drivers/usb/musb/mediatek.c | 562 +++++++++++++++++++++++++++++++++++++++++++ > > > drivers/usb/musb/musb_core.c | 10 + > > > drivers/usb/musb/musb_core.h | 1 + > > > drivers/usb/musb/musb_dma.h | 1 + > > > drivers/usb/musb/musb_host.c | 79 ++++-- > > > drivers/usb/musb/musb_regs.h | 6 + > > > drivers/usb/musb/musbhsdma.c | 34 ++- > > > 9 files changed, 671 insertions(+), 31 deletions(-) > > > create mode 100644 drivers/usb/musb/mediatek.c > > > > > > diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig > > > index ad08895..540fc9f 100644 > > > --- a/drivers/usb/musb/Kconfig > > > +++ b/drivers/usb/musb/Kconfig > > > @@ -115,6 +115,12 @@ config USB_MUSB_JZ4740 > > > depends on USB_MUSB_GADGET > > > depends on USB_OTG_BLACKLIST_HUB > > > > > > +config USB_MUSB_MEDIATEK > > > + tristate "MediaTek platforms" > > > + depends on ARCH_MEDIATEK > > > > Please also add '|| COMPILE_TEST' to make testing easier. > > Ok > > > > + depends on NOP_USB_XCEIV > > > + depends on GENERIC_PHY > > > + > > > config USB_MUSB_AM335X_CHILD > > > tristate > > > > > > @@ -141,7 +147,7 @@ config USB_UX500_DMA > > > > > > config USB_INVENTRA_DMA > > > bool 'Inventra' > > > - depends on USB_MUSB_OMAP2PLUS > > > + depends on USB_MUSB_OMAP2PLUS || USB_MUSB_MEDIATEK > > > help > > > Enable DMA transfers using Mentor's engine. > > > > > > diff --git a/drivers/usb/musb/Makefile b/drivers/usb/musb/Makefile > > > index 3a88c79..63d82d0 100644 > > > --- a/drivers/usb/musb/Makefile > > > +++ b/drivers/usb/musb/Makefile > > > @@ -24,6 +24,7 @@ obj-$(CONFIG_USB_MUSB_DA8XX) += da8xx.o > > > obj-$(CONFIG_USB_MUSB_UX500) += ux500.o > > > obj-$(CONFIG_USB_MUSB_JZ4740) += jz4740.o > > > obj-$(CONFIG_USB_MUSB_SUNXI) += sunxi.o > > > +obj-$(CONFIG_USB_MUSB_MEDIATEK) += mediatek.o > > > > > > > > > obj-$(CONFIG_USB_MUSB_AM335X_CHILD) += musb_am335x.o > > > diff --git a/drivers/usb/musb/mediatek.c b/drivers/usb/musb/mediatek.c > > > new file mode 100644 > > > index 0000000..15a6460 > > > --- /dev/null > > > +++ b/drivers/usb/musb/mediatek.c > > > > [snip] > > I will review this section later after we sorted out other things. > > > > > diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c > > > index b7d5627..d60f76f 100644 > > > --- a/drivers/usb/musb/musb_core.c > > > +++ b/drivers/usb/musb/musb_core.c > > > @@ -1028,6 +1028,16 @@ static void musb_disable_interrupts(struct musb *musb) > > > temp = musb_readb(mbase, MUSB_INTRUSB); > > > temp = musb_readw(mbase, MUSB_INTRTX); > > > temp = musb_readw(mbase, MUSB_INTRRX); > > > + > > > + /* MediaTek controller interrupt status is W1C */ > > > > This W1C doesn't match to the MUSB Programming Guide that I have. Those > > registers are read-only. > > Is the difference due to the IP intergration in the mtk platforms? or is > > it a new version of the MUSB controller? If latter, what is the version? > > This is difference due to the IP intergration in mtk platforms. W1C is > easy for CpdeViser debug. > > > > + if (musb->ops->quirks & MUSB_MTK_QUIRKS) { > > > > Basically we don't want to use this type of platform specific quirks if > > possible, so let's try to not use it. > > I will try my best to avoid using it. Thanks. > > > > + musb_writeb(mbase, MUSB_INTRUSB, > > > + musb_readb(mbase, MUSB_INTRUSB)); > > > > For this clearing register bit operation, please create platform hooks > > musb_clearb() and musb_clearw() in struct musb_platform_ops instead, > > then follow how musb_readb() pointer is assigned in > > musb_init_controller() to use the W1C version for mtk platform. > > I have tried implementing musb_readb(), musb_readw() interface with > interrupt status W1C function in struct musb_platform_ops. But this > interface will require a global variable to hold MAC basic address for > judgment, and then special handling of the interrupt state. A global > variable will make the driver work with only a single instance, so it > can't work on some MTK platforms which have two instances. I didn't mean to modify musb_read*(), but > How about creating musb_clearb/w() as following: > void (*clearb)(void __iomem *addr, unsigned offset, u8 data); > void (*clearw)(void __iomem *addr, unsigned offset, u16 data); this is what I was asking for, similar to what musb_readb/w() is implemented. > > > > > + musb_writew(mbase, MUSB_INTRRX, > > > + musb_readw(mbase, MUSB_INTRRX)); > > > + musb_writew(mbase, MUSB_INTRTX, > > > + musb_readw(mbase, MUSB_INTRTX)); > > > + } > > > } > > > > > > static void musb_enable_interrupts(struct musb *musb) > > > diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h > > > index 04203b7..1bf4e9a 100644 > > > --- a/drivers/usb/musb/musb_core.h > > > +++ b/drivers/usb/musb/musb_core.h > > > @@ -138,6 +138,7 @@ enum musb_g_ep0_state { > > > */ > > > struct musb_platform_ops { > > > > > > +#define MUSB_MTK_QUIRKS BIT(10) > > > #define MUSB_G_NO_SKB_RESERVE BIT(9) > > > #define MUSB_DA8XX BIT(8) > > > #define MUSB_PRESERVE_SESSION BIT(7) > > > diff --git a/drivers/usb/musb/musb_dma.h b/drivers/usb/musb/musb_dma.h > > > index 281e75d3..b218210 100644 > > > --- a/drivers/usb/musb/musb_dma.h > > > +++ b/drivers/usb/musb/musb_dma.h > > > @@ -197,6 +197,7 @@ static inline void musb_dma_controller_destroy(struct dma_controller *d) { } > > > extern struct dma_controller * > > > musbhs_dma_controller_create(struct musb *musb, void __iomem *base); > > > extern void musbhs_dma_controller_destroy(struct dma_controller *c); > > > +extern irqreturn_t dma_controller_irq(int irq, void *private_data); > > > > > > extern struct dma_controller * > > > tusb_dma_controller_create(struct musb *musb, void __iomem *base); > > > diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c > > > index b59ce9a..b1b0216 100644 > > > --- a/drivers/usb/musb/musb_host.c > > > +++ b/drivers/usb/musb/musb_host.c > > > @@ -292,20 +292,73 @@ static inline void musb_save_toggle(struct musb_qh *qh, int is_in, > > > { > > > void __iomem *epio = qh->hw_ep->regs; > > > u16 csr; > > > + struct musb *musb = qh->hw_ep->musb; > > > > > > /* > > > * FIXME: the current Mentor DMA code seems to have > > > * problems getting toggle correct. > > > */ > > > > > > - if (is_in) > > > - csr = musb_readw(epio, MUSB_RXCSR) & MUSB_RXCSR_H_DATATOGGLE; > > > - else > > > - csr = musb_readw(epio, MUSB_TXCSR) & MUSB_TXCSR_H_DATATOGGLE; > > > + /* MediaTek controller has private toggle register */ > > > > only one toggle register for all endpoints? how does it handle > > difference toggle values for different endpoints? > > MediaTek controller has separate registers to describe TX/RX toggle. Is it one register per endpoint? > > > > + if (musb->ops->quirks & MUSB_MTK_QUIRKS) { > > > + u16 toggle; > > > + u8 epnum = qh->hw_ep->epnum; > > > + > > > + if (is_in) > > > + toggle = musb_readl(musb->mregs, MUSB_RXTOG); this line seems telling there is just *one* register for all endpoints. > > > > should use musb_readw() instead? MUSB_RXTOG seems to be 16bit. > > Ok > > > > + else > > > + toggle = musb_readl(musb->mregs, MUSB_TXTOG); > > > + > > > + csr = toggle & (1 << epnum); > > > + } else { > > > + if (is_in) > > > + csr = musb_readw(epio, MUSB_RXCSR) > > > + & MUSB_RXCSR_H_DATATOGGLE; > > > + else > > > + csr = musb_readw(epio, MUSB_TXCSR) > > > + & MUSB_TXCSR_H_DATATOGGLE; > > > > Does this logic still work for the mtk platform even if it has its own > > private toggle register? If so, we don't need to change here. > > Sorry, this logic can not work on mtk platform, bit > MUSB_RXCSR_H_DATATOGGLE and MUSB_TXCSR_H_DATATOGGLE are used for other > function. Is there a different controller RTL version we can use to differentiate? > > > If not, let's try to not use this quirk flag. Please create a hook > > musb_platform_get_toggle() in struct musb_platform_ops. > > Does the method of implement musb_platform_get_toggle() is prepare > musb_default_get_toggle with common function, then follow how > musb_readb() pointer is assigned in musb_init_controller()? Yes, similar to musb_readb() implementation. > How about creating musb_platform_get_toggle() as following: > u16 (*get_toggle)(struct musb* musb, struct musb_qh *qh, int is_in); yes, it is part of the implementation, then add it in struct musb_io. > > > > + } > > > > > > usb_settoggle(urb->dev, qh->epnum, !is_in, csr ? 1 : 0); > > > } > > > > > > +static inline u16 musb_set_toggle(struct musb_qh *qh, int is_in, > > > + struct urb *urb) > > > +{ > > > + u16 csr = 0; > > > + u16 toggle = 0; > > > + struct musb *musb = qh->hw_ep->musb; > > > + u8 epnum = qh->hw_ep->epnum; > > > + > > > + toggle = usb_gettoggle(urb->dev, qh->epnum, !is_in); > > > + > > > + /* MediaTek controller has private toggle register */ > > > + if (musb->ops->quirks & MUSB_MTK_QUIRKS) { > > > + if (is_in) { > > > + musb_writel(musb->mregs, MUSB_RXTOGEN, (1 << epnum)); > > > + musb_writel(musb->mregs, MUSB_RXTOG, (toggle << epnum)); > > > + } else { > > > + musb_writel(musb->mregs, MUSB_TXTOGEN, (1 << epnum)); > > > + musb_writel(musb->mregs, MUSB_TXTOG, (toggle << epnum)); > > > + } > > > + } else { > > > + if (is_in) { > > > + if (toggle) > > > + csr = MUSB_RXCSR_H_WR_DATATOGGLE > > > + | MUSB_RXCSR_H_DATATOGGLE; > > > + else > > > + csr = 0; > > > + } else { > > > + if (toggle) > > > + csr |= MUSB_TXCSR_H_WR_DATATOGGLE > > > + | MUSB_TXCSR_H_DATATOGGLE; > > > + else > > > + csr |= MUSB_TXCSR_CLRDATATOG; '? :' operation probably is better than 'if else' here. > > > + } > > > + } > > > + return csr; > > > > Please create a seperate patch for this musb_set_toggle() without adding > > the mtk logic. It is a nice cleanup. > > Does this like get toggle implementation, create a hook > musb_platform_set_toggle() in struct musb_platform_ops? You did the code cleanup by creating musb_set_toggle(), please make it in a separate patch, like static u16 musb_set_toggle(struct musb_qh *qh, int is_in, struct urb *urb) { toggle = usb_gettoggle(urb->dev, qh->epnum, !is_in); if (is_in) csr = toggle ? (MUSB_RXCSR_H_WR_DATATOGGLE | MUSB_RXCSR_H_DATATOGGLE) : 0; else csr = toggle ? MUSB_TXCSR_H_WR_DATATOGGLE | MUSB_TXCSR_H_DATATOGGLE : MUSB_TXCSR_CLRDATATOG; return csr; } /* use musb_set_toggle() in the two instances */ then in this patch you add the mtk implementation similar as *get_toggle() discussed above. > > > > +} > > > + > > > /* > > > * Advance this hardware endpoint's queue, completing the specified URB and > > > * advancing to either the next URB queued to that qh, or else invalidating > > > @@ -772,13 +825,8 @@ static void musb_ep_program(struct musb *musb, u8 epnum, > > > ); > > > csr |= MUSB_TXCSR_MODE; > > > > > > - if (!hw_ep->tx_double_buffered) { > > > - if (usb_gettoggle(urb->dev, qh->epnum, 1)) > > > - csr |= MUSB_TXCSR_H_WR_DATATOGGLE > > > - | MUSB_TXCSR_H_DATATOGGLE; > > > - else > > > - csr |= MUSB_TXCSR_CLRDATATOG; > > > - } > > > + if (!hw_ep->tx_double_buffered) > > > + csr |= musb_set_toggle(qh, !is_out, urb); > > > > > > musb_writew(epio, MUSB_TXCSR, csr); > > > /* REVISIT may need to clear FLUSHFIFO ... */ > > > @@ -860,17 +908,12 @@ static void musb_ep_program(struct musb *musb, u8 epnum, > > > > > > /* IN/receive */ > > > } else { > > > - u16 csr; > > > + u16 csr = 0; > > > > > > if (hw_ep->rx_reinit) { > > > musb_rx_reinit(musb, qh, epnum); > > > + csr |= musb_set_toggle(qh, !is_out, urb); > > > > > > - /* init new state: toggle and NYET, maybe DMA later */ > > > - if (usb_gettoggle(urb->dev, qh->epnum, 0)) > > > - csr = MUSB_RXCSR_H_WR_DATATOGGLE > > > - | MUSB_RXCSR_H_DATATOGGLE; > > > - else > > > - csr = 0; > > > if (qh->type == USB_ENDPOINT_XFER_INT) > > > csr |= MUSB_RXCSR_DISNYET; > > > > > > diff --git a/drivers/usb/musb/musb_regs.h b/drivers/usb/musb/musb_regs.h > > > index 5cd7264..ffbe267 100644 > > > --- a/drivers/usb/musb/musb_regs.h > > > +++ b/drivers/usb/musb/musb_regs.h > > > @@ -273,6 +273,12 @@ > > > #define MUSB_RXHUBADDR 0x06 > > > #define MUSB_RXHUBPORT 0x07 > > > > > > +/* MediaTek controller toggle enable and status reg */ > > > +#define MUSB_RXTOG 0x80 > > > +#define MUSB_RXTOGEN 0x82 > > > +#define MUSB_TXTOG 0x84 > > > +#define MUSB_TXTOGEN 0x86 > > > > Again, these offsets are for different registers in the MUSB version I > > have, please let me know if you have different version of the MUSB IP. > > Sorry, these are MediaTek controller private registers used for control > toggle. Okay. Once the platform get/set_toggle() are implemented, those registers can be defined in the mtk glue driver instead of here. Regards, -Bin. _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel