diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/usb/gadget/udc/pxa25x_udc.c | 61 | ||||
-rw-r--r-- | drivers/usb/gadget/udc/pxa25x_udc.h | 1 |
2 files changed, 40 insertions, 22 deletions
diff --git a/drivers/usb/gadget/udc/pxa25x_udc.c b/drivers/usb/gadget/udc/pxa25x_udc.c index 5db429f3cfb2..6d3acbf3b311 100644 --- a/drivers/usb/gadget/udc/pxa25x_udc.c +++ b/drivers/usb/gadget/udc/pxa25x_udc.c @@ -52,9 +52,6 @@ #include <mach/lubbock.h> #endif -static void __iomem *pxa25x_udc_reg_base; -#define __UDC_REG(x) (*((volatile u32 *)(pxa25x_udc_reg_base + (x)))) - #define UDCCR 0x0000 /* UDC Control Register */ #define UDC_RES1 0x0004 /* UDC Undocumented - Reserved1 */ #define UDC_RES2 0x0008 /* UDC Undocumented - Reserved2 */ @@ -292,16 +289,36 @@ static void pullup_on(void) mach->udc_command(PXA2XX_UDC_CMD_CONNECT); } -static inline void udc_set_reg(struct pxa25x_udc *dev, u32 reg, u32 uicr) +#if defined(CONFIG_ARCH_IXP4XX) && defined(CONFIG_CPU_BIG_ENDIAN) +/* + * not sure if this is the correct behavior on ixp4xx in both + * bit-endian and little-endian modes, but it's what the driver + * has always done using direct pointer dereferences: + * We assume that there is a byteswap done in hardware at the + * MMIO register that matches what the CPU setting is, so we + * never swap in software. + */ +static inline void udc_set_reg(struct pxa25x_udc *dev, u32 reg, u32 val) { - __UDC_REG(reg) = uicr; + iowrite32be(val, dev->regs + reg); } static inline u32 udc_get_reg(struct pxa25x_udc *dev, u32 reg) { - return __UDC_REG(reg); + return ioread32be(dev->regs + reg); +} +#else +static inline void udc_set_reg(struct pxa25x_udc *dev, u32 reg, u32 val) +{ + writel(val, dev->regs + reg); } +static inline u32 udc_get_reg(struct pxa25x_udc *dev, u32 reg) +{ + return readl(dev->regs + reg); +} +#endif + static void pio_irq_enable(struct pxa25x_ep *ep) { u32 bEndpointAddress = ep->bEndpointAddress & 0xf; @@ -337,59 +354,59 @@ static void pio_irq_disable(struct pxa25x_ep *ep) static inline void udc_set_mask_UDCCR(struct pxa25x_udc *dev, int mask) { - u32 udccr = __UDC_REG(UDCCR); + u32 udccr = udc_get_reg(dev, UDCCR); - __UDC_REG(UDCCR) = (udccr & UDCCR_MASK_BITS) | (mask & UDCCR_MASK_BITS); + udc_set_reg(dev, (udccr & UDCCR_MASK_BITS) | (mask & UDCCR_MASK_BITS), UDCCR); } static inline void udc_clear_mask_UDCCR(struct pxa25x_udc *dev, int mask) { - u32 udccr = __UDC_REG(UDCCR); + u32 udccr = udc_get_reg(dev, UDCCR); - __UDC_REG(UDCCR) = (udccr & UDCCR_MASK_BITS) & ~(mask & UDCCR_MASK_BITS); + udc_set_reg(dev, (udccr & UDCCR_MASK_BITS) & ~(mask & UDCCR_MASK_BITS), UDCCR); } static inline void udc_ack_int_UDCCR(struct pxa25x_udc *dev, int mask) { /* udccr contains the bits we dont want to change */ - u32 udccr = __UDC_REG(UDCCR) & UDCCR_MASK_BITS; + u32 udccr = udc_get_reg(dev, UDCCR) & UDCCR_MASK_BITS; - __UDC_REG(UDCCR) = udccr | (mask & ~UDCCR_MASK_BITS); + udc_set_reg(dev, udccr | (mask & ~UDCCR_MASK_BITS), UDCCR); } static inline u32 udc_ep_get_UDCCS(struct pxa25x_ep *ep) { - return __UDC_REG(ep->regoff_udccs); + return udc_get_reg(ep->dev, ep->regoff_udccs); } static inline void udc_ep_set_UDCCS(struct pxa25x_ep *ep, u32 data) { - __UDC_REG(ep->regoff_udccs) = data; + udc_set_reg(ep->dev, data, ep->regoff_udccs); } static inline u32 udc_ep0_get_UDCCS(struct pxa25x_udc *dev) { - return __UDC_REG(UDCCS0); + return udc_get_reg(dev, UDCCS0); } static inline void udc_ep0_set_UDCCS(struct pxa25x_udc *dev, u32 data) { - __UDC_REG(UDCCS0) = data; + udc_set_reg(dev, data, UDCCS0); } static inline u32 udc_ep_get_UDDR(struct pxa25x_ep *ep) { - return __UDC_REG(ep->regoff_uddr); + return udc_get_reg(ep->dev, ep->regoff_uddr); } static inline void udc_ep_set_UDDR(struct pxa25x_ep *ep, u32 data) { - __UDC_REG(ep->regoff_uddr) = data; + udc_set_reg(ep->dev, data, ep->regoff_uddr); } static inline u32 udc_ep_get_UBCR(struct pxa25x_ep *ep) { - return __UDC_REG(ep->regoff_ubcr); + return udc_get_reg(ep->dev, ep->regoff_ubcr); } /* @@ -2369,9 +2386,9 @@ static int pxa25x_udc_probe(struct platform_device *pdev) return -ENODEV; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - pxa25x_udc_reg_base = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(pxa25x_udc_reg_base)) - return PTR_ERR(pxa25x_udc_reg_base); + dev->regs = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(dev->regs)) + return PTR_ERR(dev->regs); dev->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(dev->clk)) diff --git a/drivers/usb/gadget/udc/pxa25x_udc.h b/drivers/usb/gadget/udc/pxa25x_udc.h index f884513f7390..4b8b72d7ab37 100644 --- a/drivers/usb/gadget/udc/pxa25x_udc.h +++ b/drivers/usb/gadget/udc/pxa25x_udc.h @@ -125,6 +125,7 @@ struct pxa25x_udc { #ifdef CONFIG_USB_GADGET_DEBUG_FS struct dentry *debugfs_udc; #endif + void __iomem *regs; }; #define to_pxa25x(g) (container_of((g), struct pxa25x_udc, gadget)) |