Hi, On Fri, Feb 10, 2012 at 10:12:24AM +0100, Lukasz Majewski wrote: > The s3c_hsotg_core_init function has been added to exclude > code responsible for Samsung's SoCs USB core initialization. > > Signed-off-by: Lukasz Majewski <l.majewski@xxxxxxxxxxx> > Signed-off-by: Kyungmin Park <kyungmin.park@xxxxxxxxxxx> > --- > drivers/usb/gadget/s3c-hsotg.c | 329 ++++++++++++++++++++-------------------- > 1 files changed, 168 insertions(+), 161 deletions(-) > > diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c > index 7664932..6543bb5 100644 > --- a/drivers/usb/gadget/s3c-hsotg.c > +++ b/drivers/usb/gadget/s3c-hsotg.c > @@ -2158,6 +2158,173 @@ static struct s3c_hsotg *our_hsotg; > S3C_GINTSTS_RxFLvl) > > /** > + * s3c_hsotg_corereset - issue softreset to the core > + * @hsotg: The device state > + * > + * Issue a soft reset to the core, and await the core finishing it. > +*/ > +static int s3c_hsotg_corereset(struct s3c_hsotg *hsotg) > +{ > + int timeout; > + u32 grstctl; > + > + dev_dbg(hsotg->dev, "resetting core\n"); > + > + /* issue soft reset */ > + writel(S3C_GRSTCTL_CSftRst, hsotg->regs + S3C_GRSTCTL); > + > + timeout = 1000; > + do { > + grstctl = readl(hsotg->regs + S3C_GRSTCTL); > + } while ((grstctl & S3C_GRSTCTL_CSftRst) && timeout-- > 0); > + > + if (grstctl & S3C_GRSTCTL_CSftRst) { > + dev_err(hsotg->dev, "Failed to get CSftRst asserted\n"); > + return -EINVAL; > + } > + > + timeout = 1000; > + > + while (1) { > + u32 grstctl = readl(hsotg->regs + S3C_GRSTCTL); > + > + if (timeout-- < 0) { > + dev_info(hsotg->dev, > + "%s: reset failed, GRSTCTL=%08x\n", > + __func__, grstctl); > + return -ETIMEDOUT; > + } > + > + if (!(grstctl & S3C_GRSTCTL_AHBIdle)) > + continue; is this a synopsys core ? Is this the DWC USB2 core ? If it is, how come this was written as a samsung-only driver ? There's another company which has been trying to merge a more generic DWC USB2 driver for almost 2 years, when you guys could have joined the efforts and cleanup this driver to allow more people to re-use it. Keep in mind that we want to avoid code duplication as much as possible, so please start helping the other folks and myself when writing drivers ;-) If the other company happens to try again, I will point them to this driver, provided you confirm this is, indeed, a synopsys dwc usb2 core. > + > + break; /* reset done */ > + } > + > + dev_dbg(hsotg->dev, "reset successful\n"); I would make this dev_vdbg(), but it's your call ;-) > + return 0; > +} > + > + > +static void s3c_hsotg_core_init(struct s3c_hsotg *hsotg) > +{ > + s3c_hsotg_corereset(hsotg); > + > + /* we must now enable ep0 ready for host detection and then > + * set configuration. */ > + > + /* set the PLL on, remove the HNP/SRP and set the PHY */ > + writel(S3C_GUSBCFG_PHYIf16 | S3C_GUSBCFG_TOutCal(7) | > + (0x5 << 10), hsotg->regs + S3C_GUSBCFG); > + > + /* looks like soft-reset changes state of FIFOs */ > + s3c_hsotg_init_fifo(hsotg); > + > + __orr32(hsotg->regs + S3C_DCTL, S3C_DCTL_SftDiscon); > + > + writel(1 << 18 | S3C_DCFG_DevSpd_HS, hsotg->regs + S3C_DCFG); > + > + /* Clear any pending OTG interrupts */ > + writel(0xffffffff, hsotg->regs + S3C_GOTGINT); > + > + /* Clear any pending interrupts */ > + writel(0xffffffff, hsotg->regs + S3C_GINTSTS); > + > + writel(S3C_GINTSTS_DisconnInt | S3C_GINTSTS_SessReqInt | > + S3C_GINTSTS_ConIDStsChng | S3C_GINTSTS_USBRst | > + S3C_GINTSTS_EnumDone | S3C_GINTSTS_OTGInt | > + S3C_GINTSTS_USBSusp | S3C_GINTSTS_WkUpInt | > + S3C_GINTSTS_GOUTNakEff | S3C_GINTSTS_GINNakEff | > + S3C_GINTSTS_ErlySusp, > + hsotg->regs + S3C_GINTMSK); > + > + if (using_dma(hsotg)) > + writel(S3C_GAHBCFG_GlblIntrEn | S3C_GAHBCFG_DMAEn | > + S3C_GAHBCFG_HBstLen_Incr4, > + hsotg->regs + S3C_GAHBCFG); > + else > + writel(S3C_GAHBCFG_GlblIntrEn, hsotg->regs + S3C_GAHBCFG); > + > + /* Enabling INTknTXFEmpMsk here seems to be a big mistake, we end > + * up being flooded with interrupts if the host is polling the > + * endpoint to try and read data. */ multiline comment style. > + writel(S3C_DIEPMSK_TimeOUTMsk | S3C_DIEPMSK_AHBErrMsk | > + S3C_DIEPMSK_INTknEPMisMsk | > + S3C_DIEPMSK_EPDisbldMsk | S3C_DIEPMSK_XferComplMsk | > + ((hsotg->dedicated_fifos) ? S3C_DIEPMSK_TxFIFOEmpty : 0), > + hsotg->regs + S3C_DIEPMSK); > + > + /* don't need XferCompl, we get that from RXFIFO in slave mode. In > + * DMA mode we may need this. */ multiline comment style > + writel(S3C_DOEPMSK_SetupMsk | S3C_DOEPMSK_AHBErrMsk | > + S3C_DOEPMSK_EPDisbldMsk | > + (using_dma(hsotg) ? (S3C_DIEPMSK_XferComplMsk | > + S3C_DIEPMSK_TimeOUTMsk) : 0), > + hsotg->regs + S3C_DOEPMSK); > + > + writel(0, hsotg->regs + S3C_DAINTMSK); > + > + dev_dbg(hsotg->dev, "EP0: DIEPCTL0=0x%08x, DOEPCTL0=0x%08x\n", > + readl(hsotg->regs + S3C_DIEPCTL0), > + readl(hsotg->regs + S3C_DOEPCTL0)); > + > + /* enable in and out endpoint interrupts */ > + s3c_hsotg_en_gsint(hsotg, S3C_GINTSTS_OEPInt | S3C_GINTSTS_IEPInt); > + > + /* Enable the RXFIFO when in slave mode, as this is how we collect > + * the data. In DMA mode, we get events from the FIFO but also > + * things we cannot process, so do not use it. */ multiline comment style > + if (!using_dma(hsotg)) > + s3c_hsotg_en_gsint(hsotg, S3C_GINTSTS_RxFLvl); > + > + /* Enable interrupts for EP0 in and out */ > + s3c_hsotg_ctrl_epint(hsotg, 0, 0, 1); > + s3c_hsotg_ctrl_epint(hsotg, 0, 1, 1); > + > + __orr32(hsotg->regs + S3C_DCTL, S3C_DCTL_PWROnPrgDone); > + udelay(10); /* see openiboot */ > + __bic32(hsotg->regs + S3C_DCTL, S3C_DCTL_PWROnPrgDone); > + > + dev_dbg(hsotg->dev, "DCTL=0x%08x\n", readl(hsotg->regs + S3C_DCTL)); > + > + /* S3C_DxEPCTL_USBActEp says RO in manual, but seems to be set by > + writing to the EPCTL register.. */ multiline comment style > + > + /* set to read 1 8byte packet */ > + writel(S3C_DxEPTSIZ_MC(1) | S3C_DxEPTSIZ_PktCnt(1) | > + S3C_DxEPTSIZ_XferSize(8), hsotg->regs + DOEPTSIZ0); > + > + writel(s3c_hsotg_ep0_mps(hsotg->eps[0].ep.maxpacket) | > + S3C_DxEPCTL_CNAK | S3C_DxEPCTL_EPEna | > + S3C_DxEPCTL_USBActEp, > + hsotg->regs + S3C_DOEPCTL0); > + > + /* enable, but don't activate EP0in */ > + writel(s3c_hsotg_ep0_mps(hsotg->eps[0].ep.maxpacket) | > + S3C_DxEPCTL_USBActEp, hsotg->regs + S3C_DIEPCTL0); > + > + s3c_hsotg_enqueue_setup(hsotg); > + > + dev_dbg(hsotg->dev, "EP0: DIEPCTL0=0x%08x, DOEPCTL0=0x%08x\n", > + readl(hsotg->regs + S3C_DIEPCTL0), > + readl(hsotg->regs + S3C_DOEPCTL0)); > + > + /* clear global NAKs */ > + writel(S3C_DCTL_CGOUTNak | S3C_DCTL_CGNPInNAK, > + hsotg->regs + S3C_DCTL); > + > + /* must be at-least 3ms to allow bus to see disconnect */ > + mdelay(3); > + > + /* remove the soft-disconnect and let's go */ > + __bic32(hsotg->regs + S3C_DCTL, S3C_DCTL_SftDiscon); > + > + /* printk(KERN_ERR "%s: HSOTG\n", __func__); */ remove this commented code. There's no need for it whatsoever. -- balbi
Attachment:
signature.asc
Description: Digital signature