On Mon, Oct 06, 2014 at 06:55:03PM +0300, Laurent Pinchart wrote:
> Although the corresponding register is part of the HCD register space,
> processor bus initialization is not specific to the HCD. To prepare for
> device controller support, move bus interface initialization to core
> code.
> 
> Signed-off-by: Laurent Pinchart <[email protected]>

Reviewed-by: Felipe Balbi <[email protected]>

> ---
>  drivers/usb/host/isp1760-core.c | 62 ++++++++++++++++++++++++++++++++++++--
>  drivers/usb/host/isp1760-core.h | 30 ++++++++++++++++++
>  drivers/usb/host/isp1760-hcd.c  | 67 
> ++++++++---------------------------------
>  drivers/usb/host/isp1760-hcd.h  | 20 +-----------
>  4 files changed, 104 insertions(+), 75 deletions(-)
> 
> diff --git a/drivers/usb/host/isp1760-core.c b/drivers/usb/host/isp1760-core.c
> index 718fd6c..cde66d3 100644
> --- a/drivers/usb/host/isp1760-core.c
> +++ b/drivers/usb/host/isp1760-core.c
> @@ -13,6 +13,7 @@
>   * version 2 as published by the Free Software Foundation.
>   */
>  
> +#include <linux/delay.h>
>  #include <linux/gpio.h>
>  #include <linux/io.h>
>  #include <linux/kernel.h>
> @@ -22,6 +23,59 @@
>  
>  #include "isp1760-core.h"
>  #include "isp1760-hcd.h"
> +#include "isp1760-regs.h"
> +
> +static void isp1760_init_core(struct isp1760_device *isp)
> +{
> +     u32 hwmode;
> +
> +     /* Low-level chip reset */
> +     if (gpio_is_valid(isp->rst_gpio)) {
> +             unsigned int rst_lvl;
> +
> +             rst_lvl = (isp->devflags &
> +                        ISP1760_FLAG_RESET_ACTIVE_HIGH) ? 1 : 0;
> +
> +             gpio_set_value(isp->rst_gpio, rst_lvl);
> +             mdelay(50);
> +             gpio_set_value(isp->rst_gpio, !rst_lvl);
> +     }
> +
> +     /*
> +      * Reset the host controller, including the CPU interface
> +      * configuration.
> +      */
> +     isp1760_write32(isp->regs, HC_RESET_REG, SW_RESET_RESET_ALL);
> +     msleep(100);
> +
> +     /* Setup HW Mode Control: This assumes a level active-low interrupt */
> +     hwmode = HW_DATA_BUS_32BIT;
> +
> +     if (isp->devflags & ISP1760_FLAG_BUS_WIDTH_16)
> +             hwmode &= ~HW_DATA_BUS_32BIT;
> +     if (isp->devflags & ISP1760_FLAG_ANALOG_OC)
> +             hwmode |= HW_ANA_DIGI_OC;
> +     if (isp->devflags & ISP1760_FLAG_DACK_POL_HIGH)
> +             hwmode |= HW_DACK_POL_HIGH;
> +     if (isp->devflags & ISP1760_FLAG_DREQ_POL_HIGH)
> +             hwmode |= HW_DREQ_POL_HIGH;
> +     if (isp->devflags & ISP1760_FLAG_INTR_POL_HIGH)
> +             hwmode |= HW_INTR_HIGH_ACT;
> +     if (isp->devflags & ISP1760_FLAG_INTR_EDGE_TRIG)
> +             hwmode |= HW_INTR_EDGE_TRIG;
> +
> +     /*
> +      * We have to set this first in case we're in 16-bit mode.
> +      * Write it twice to ensure correct upper bits if switching
> +      * to 16-bit mode.
> +      */
> +     isp1760_write32(isp->regs, HC_HW_MODE_CTRL, hwmode);
> +     isp1760_write32(isp->regs, HC_HW_MODE_CTRL, hwmode);
> +
> +     dev_info(isp->dev, "bus width: %u, oc: %s\n",
> +              isp->devflags & ISP1760_FLAG_BUS_WIDTH_16 ? 16 : 32,
> +              isp->devflags & ISP1760_FLAG_ANALOG_OC ? "analog" : "digital");
> +}
>  
>  int isp1760_register(struct resource *mem, int irq, unsigned long irqflags,
>                    int rst_gpio, struct device *dev, unsigned int devflags)
> @@ -39,6 +93,9 @@ int isp1760_register(struct resource *mem, int irq, 
> unsigned long irqflags,
>       if (!isp)
>               return -ENOMEM;
>  
> +     isp->dev = dev;
> +     isp->devflags = devflags;
> +
>       if (gpio_is_valid(rst_gpio)) {
>               ret = gpio_request(rst_gpio, dev_name(dev));
>               if (!ret) {
> @@ -62,9 +119,10 @@ int isp1760_register(struct resource *mem, int irq, 
> unsigned long irqflags,
>               goto error;
>       }
>  
> -     isp->hcd.rst_gpio = rst_gpio;
> +     isp1760_init_core(isp);
> +
>       ret = isp1760_hcd_register(&isp->hcd, isp->regs, mem, irq,
> -                                irqflags | IRQF_SHARED, dev, devflags);
> +                                irqflags | IRQF_SHARED, dev);
>       if (ret < 0)
>               goto error;
>  
> diff --git a/drivers/usb/host/isp1760-core.h b/drivers/usb/host/isp1760-core.h
> index 8bd997c..862dff4 100644
> --- a/drivers/usb/host/isp1760-core.h
> +++ b/drivers/usb/host/isp1760-core.h
> @@ -20,11 +20,31 @@
>  
>  #include "isp1760-hcd.h"
>  
> +struct device;
> +
> +/*
> + * Device flags that can vary from board to board.  All of these
> + * indicate the most "atypical" case, so that a devflags of 0 is
> + * a sane default configuration.
> + */
> +#define ISP1760_FLAG_BUS_WIDTH_16    0x00000002 /* 16-bit data bus width */
> +#define ISP1760_FLAG_OTG_EN          0x00000004 /* Port 1 supports OTG */
> +#define ISP1760_FLAG_ANALOG_OC               0x00000008 /* Analog 
> overcurrent */
> +#define ISP1760_FLAG_DACK_POL_HIGH   0x00000010 /* DACK active high */
> +#define ISP1760_FLAG_DREQ_POL_HIGH   0x00000020 /* DREQ active high */
> +#define ISP1760_FLAG_ISP1761         0x00000040 /* Chip is ISP1761 */
> +#define ISP1760_FLAG_INTR_POL_HIGH   0x00000080 /* Interrupt polarity active 
> high */
> +#define ISP1760_FLAG_INTR_EDGE_TRIG  0x00000100 /* Interrupt edge triggered 
> */
> +#define ISP1760_FLAG_RESET_ACTIVE_HIGH       0x80000000 /* RESET GPIO active 
> high */
> +
>  struct isp1760_device {
> +     struct device *dev;
> +
>       resource_size_t mem_start;
>       resource_size_t mem_size;
>  
>       void __iomem *regs;
> +     unsigned int devflags;
>       int rst_gpio;
>  
>       struct isp1760_hcd hcd;
> @@ -34,4 +54,14 @@ int isp1760_register(struct resource *mem, int irq, 
> unsigned long irqflags,
>                    int rst_gpio, struct device *dev, unsigned int devflags);
>  void isp1760_unregister(struct device *dev);
>  
> +static inline u32 isp1760_read32(void __iomem *base, u32 reg)
> +{
> +     return readl(base + reg);
> +}
> +
> +static inline void isp1760_write32(void __iomem *base, u32 reg, u32 val)
> +{
> +     writel(val, base + reg);
> +}
> +
>  #endif
> diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c
> index f903ad9..596a1a9 100644
> --- a/drivers/usb/host/isp1760-hcd.c
> +++ b/drivers/usb/host/isp1760-hcd.c
> @@ -24,8 +24,8 @@
>  #include <linux/timer.h>
>  #include <asm/unaligned.h>
>  #include <asm/cacheflush.h>
> -#include <linux/gpio.h>
>  
> +#include "isp1760-core.h"
>  #include "isp1760-hcd.h"
>  #include "isp1760-regs.h"
>  
> @@ -160,12 +160,12 @@ struct urb_listitem {
>   */
>  static u32 reg_read32(void __iomem *base, u32 reg)
>  {
> -     return readl(base + reg);
> +     return isp1760_read32(base, reg);
>  }
>  
>  static void reg_write32(void __iomem *base, u32 reg, u32 val)
>  {
> -     writel(val, base + reg);
> +     isp1760_write32(base, reg, val);
>  }
>  
>  /*
> @@ -466,42 +466,6 @@ static int isp1760_hc_setup(struct usb_hcd *hcd)
>       int result;
>       u32 scratch, hwmode;
>  
> -     /* low-level chip reset */
> -     if (gpio_is_valid(priv->rst_gpio)) {
> -             unsigned int rst_lvl;
> -
> -             rst_lvl = (priv->devflags &
> -                        ISP1760_FLAG_RESET_ACTIVE_HIGH) ? 1 : 0;
> -
> -             gpio_set_value(priv->rst_gpio, rst_lvl);
> -             mdelay(50);
> -             gpio_set_value(priv->rst_gpio, !rst_lvl);
> -     }
> -
> -     /* Setup HW Mode Control: This assumes a level active-low interrupt */
> -     hwmode = HW_DATA_BUS_32BIT;
> -
> -     if (priv->devflags & ISP1760_FLAG_BUS_WIDTH_16)
> -             hwmode &= ~HW_DATA_BUS_32BIT;
> -     if (priv->devflags & ISP1760_FLAG_ANALOG_OC)
> -             hwmode |= HW_ANA_DIGI_OC;
> -     if (priv->devflags & ISP1760_FLAG_DACK_POL_HIGH)
> -             hwmode |= HW_DACK_POL_HIGH;
> -     if (priv->devflags & ISP1760_FLAG_DREQ_POL_HIGH)
> -             hwmode |= HW_DREQ_POL_HIGH;
> -     if (priv->devflags & ISP1760_FLAG_INTR_POL_HIGH)
> -             hwmode |= HW_INTR_HIGH_ACT;
> -     if (priv->devflags & ISP1760_FLAG_INTR_EDGE_TRIG)
> -             hwmode |= HW_INTR_EDGE_TRIG;
> -
> -     /*
> -      * We have to set this first in case we're in 16-bit mode.
> -      * Write it twice to ensure correct upper bits if switching
> -      * to 16-bit mode.
> -      */
> -     reg_write32(hcd->regs, HC_HW_MODE_CTRL, hwmode);
> -     reg_write32(hcd->regs, HC_HW_MODE_CTRL, hwmode);
> -
>       reg_write32(hcd->regs, HC_SCRATCH_REG, 0xdeadbabe);
>       /* Change bus pattern */
>       scratch = reg_read32(hcd->regs, HC_CHIP_ID_REG);
> @@ -511,31 +475,27 @@ static int isp1760_hc_setup(struct usb_hcd *hcd)
>               return -ENODEV;
>       }
>  
> -     /* pre reset */
> +     /*
> +      * The RESET_HC bit in the SW_RESET register is supposed to reset the
> +      * host controller without touching the CPU interface registers, but at
> +      * least on the ISP1761 it seems to behave as the RESET_ALL bit and
> +      * reset the whole device. We thus can't use it here, so let's reset
> +      * the host controller through the EHCI USB Command register. The device
> +      * has been reset in core code anyway, so this shouldn't matter.
> +      */
>       reg_write32(hcd->regs, HC_BUFFER_STATUS_REG, 0);
>       reg_write32(hcd->regs, HC_ATL_PTD_SKIPMAP_REG, NO_TRANSFER_ACTIVE);
>       reg_write32(hcd->regs, HC_INT_PTD_SKIPMAP_REG, NO_TRANSFER_ACTIVE);
>       reg_write32(hcd->regs, HC_ISO_PTD_SKIPMAP_REG, NO_TRANSFER_ACTIVE);
>  
> -     /* reset */
> -     reg_write32(hcd->regs, HC_RESET_REG, SW_RESET_RESET_ALL);
> -     mdelay(100);
> -
> -     reg_write32(hcd->regs, HC_RESET_REG, SW_RESET_RESET_HC);
> -     mdelay(100);
> -
>       result = ehci_reset(hcd);
>       if (result)
>               return result;
>  
>       /* Step 11 passed */
>  
> -     dev_info(hcd->self.controller, "bus width: %d, oc: %s\n",
> -                        (priv->devflags & ISP1760_FLAG_BUS_WIDTH_16) ?
> -                        16 : 32, (priv->devflags & ISP1760_FLAG_ANALOG_OC) ?
> -                        "analog" : "digital");
> -
>       /* ATL reset */
> +     hwmode = reg_read32(hcd->regs, HC_HW_MODE_CTRL) & ~ALL_ATX_RESET;
>       reg_write32(hcd->regs, HC_HW_MODE_CTRL, hwmode | ALL_ATX_RESET);
>       mdelay(10);
>       reg_write32(hcd->regs, HC_HW_MODE_CTRL, hwmode);
> @@ -2239,7 +2199,7 @@ void isp1760_deinit_kmem_cache(void)
>  
>  int isp1760_hcd_register(struct isp1760_hcd *priv, void __iomem *regs,
>                        struct resource *mem, int irq, unsigned long irqflags,
> -                      struct device *dev, unsigned int devflags)
> +                      struct device *dev)
>  {
>       struct usb_hcd *hcd;
>       int ret;
> @@ -2251,7 +2211,6 @@ int isp1760_hcd_register(struct isp1760_hcd *priv, void 
> __iomem *regs,
>       *(struct isp1760_hcd **)hcd->hcd_priv = priv;
>  
>       priv->hcd = hcd;
> -     priv->devflags = devflags;
>  
>       init_memory(priv);
>  
> diff --git a/drivers/usb/host/isp1760-hcd.h b/drivers/usb/host/isp1760-hcd.h
> index 51996a2..df7ea36 100644
> --- a/drivers/usb/host/isp1760-hcd.h
> +++ b/drivers/usb/host/isp1760-hcd.h
> @@ -26,21 +26,6 @@ struct usb_hcd;
>  #define MAX_PAYLOAD_SIZE BLOCK_3_SIZE
>  #define PAYLOAD_AREA_SIZE 0xf000
>  
> -/*
> - * Device flags that can vary from board to board.  All of these
> - * indicate the most "atypical" case, so that a devflags of 0 is
> - * a sane default configuration.
> - */
> -#define ISP1760_FLAG_BUS_WIDTH_16    0x00000002 /* 16-bit data bus width */
> -#define ISP1760_FLAG_OTG_EN          0x00000004 /* Port 1 supports OTG */
> -#define ISP1760_FLAG_ANALOG_OC               0x00000008 /* Analog 
> overcurrent */
> -#define ISP1760_FLAG_DACK_POL_HIGH   0x00000010 /* DACK active high */
> -#define ISP1760_FLAG_DREQ_POL_HIGH   0x00000020 /* DREQ active high */
> -#define ISP1760_FLAG_ISP1761         0x00000040 /* Chip is ISP1761 */
> -#define ISP1760_FLAG_INTR_POL_HIGH   0x00000080 /* Interrupt polarity active 
> high */
> -#define ISP1760_FLAG_INTR_EDGE_TRIG  0x00000100 /* Interrupt edge triggered 
> */
> -#define ISP1760_FLAG_RESET_ACTIVE_HIGH       0x80000000 /* RESET GPIO active 
> high */
> -
>  struct isp1760_slotinfo {
>       struct isp1760_qh *qh;
>       struct isp1760_qtd *qtd;
> @@ -79,14 +64,11 @@ struct isp1760_hcd {
>       unsigned                i_thresh;
>       unsigned long           reset_done;
>       unsigned long           next_statechange;
> -     unsigned int            devflags;
> -
> -     int                     rst_gpio;
>  };
>  
>  int isp1760_hcd_register(struct isp1760_hcd *priv, void __iomem *regs,
>                        struct resource *mem, int irq, unsigned long irqflags,
> -                      struct device *dev, unsigned int devflags);
> +                      struct device *dev);
>  void isp1760_hcd_unregister(struct isp1760_hcd *priv);
>  
>  int isp1760_init_kmem_once(void);
> -- 
> 2.0.4
> 

-- 
balbi

Attachment: signature.asc
Description: Digital signature

Reply via email to