aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2016-01-28 11:17:04 -0500
committerFelipe Balbi <balbi@kernel.org>2016-03-04 08:14:29 -0500
commit65bc0fba4ed6e2ea7d89539985feb576ae2f84b9 (patch)
treef4caaf1f5f2db5b99a1d085ce70d31e4e9eeeac9 /drivers
parenta77af20e9e67caf79bd961c3d12938051b2c560e (diff)
usb: gadget: pxa25x_udc: use readl/writel for mmio
This converts the pxa25x udc driver to use readl/writel as normal driver should do, rather than dereferencing __iomem pointers themselves. Based on the earlier preparation work, we can now also pass the register start in the device pointer so we no longer need the global variable. The unclear part here is for IXP4xx, which supports both big-endian and little-endian configurations. So far, the driver has done no byteswap in either case. I suspect that is wrong and it would actually need to swap in one or the other case, but I don't know which. It's also possible that there is some magic setting in the chip that makes the endianess of the MMIO register match the CPU, and in that case, the code actually does the right thing for all configurations, both before and after this patch. Acked-by: Robert Jarzmik <robert.jarzmik@free.fr> Signed-off-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Felipe Balbi <balbi@kernel.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/usb/gadget/udc/pxa25x_udc.c61
-rw-r--r--drivers/usb/gadget/udc/pxa25x_udc.h1
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 @@
52#include <mach/lubbock.h> 52#include <mach/lubbock.h>
53#endif 53#endif
54 54
55static void __iomem *pxa25x_udc_reg_base;
56#define __UDC_REG(x) (*((volatile u32 *)(pxa25x_udc_reg_base + (x))))
57
58#define UDCCR 0x0000 /* UDC Control Register */ 55#define UDCCR 0x0000 /* UDC Control Register */
59#define UDC_RES1 0x0004 /* UDC Undocumented - Reserved1 */ 56#define UDC_RES1 0x0004 /* UDC Undocumented - Reserved1 */
60#define UDC_RES2 0x0008 /* UDC Undocumented - Reserved2 */ 57#define UDC_RES2 0x0008 /* UDC Undocumented - Reserved2 */
@@ -292,16 +289,36 @@ static void pullup_on(void)
292 mach->udc_command(PXA2XX_UDC_CMD_CONNECT); 289 mach->udc_command(PXA2XX_UDC_CMD_CONNECT);
293} 290}
294 291
295static inline void udc_set_reg(struct pxa25x_udc *dev, u32 reg, u32 uicr) 292#if defined(CONFIG_ARCH_IXP4XX) && defined(CONFIG_CPU_BIG_ENDIAN)
293/*
294 * not sure if this is the correct behavior on ixp4xx in both
295 * bit-endian and little-endian modes, but it's what the driver
296 * has always done using direct pointer dereferences:
297 * We assume that there is a byteswap done in hardware at the
298 * MMIO register that matches what the CPU setting is, so we
299 * never swap in software.
300 */
301static inline void udc_set_reg(struct pxa25x_udc *dev, u32 reg, u32 val)
296{ 302{
297 __UDC_REG(reg) = uicr; 303 iowrite32be(val, dev->regs + reg);
298} 304}
299 305
300static inline u32 udc_get_reg(struct pxa25x_udc *dev, u32 reg) 306static inline u32 udc_get_reg(struct pxa25x_udc *dev, u32 reg)
301{ 307{
302 return __UDC_REG(reg); 308 return ioread32be(dev->regs + reg);
309}
310#else
311static inline void udc_set_reg(struct pxa25x_udc *dev, u32 reg, u32 val)
312{
313 writel(val, dev->regs + reg);
303} 314}
304 315
316static inline u32 udc_get_reg(struct pxa25x_udc *dev, u32 reg)
317{
318 return readl(dev->regs + reg);
319}
320#endif
321
305static void pio_irq_enable(struct pxa25x_ep *ep) 322static void pio_irq_enable(struct pxa25x_ep *ep)
306{ 323{
307 u32 bEndpointAddress = ep->bEndpointAddress & 0xf; 324 u32 bEndpointAddress = ep->bEndpointAddress & 0xf;
@@ -337,59 +354,59 @@ static void pio_irq_disable(struct pxa25x_ep *ep)
337 354
338static inline void udc_set_mask_UDCCR(struct pxa25x_udc *dev, int mask) 355static inline void udc_set_mask_UDCCR(struct pxa25x_udc *dev, int mask)
339{ 356{
340 u32 udccr = __UDC_REG(UDCCR); 357 u32 udccr = udc_get_reg(dev, UDCCR);
341 358
342 __UDC_REG(UDCCR) = (udccr & UDCCR_MASK_BITS) | (mask & UDCCR_MASK_BITS); 359 udc_set_reg(dev, (udccr & UDCCR_MASK_BITS) | (mask & UDCCR_MASK_BITS), UDCCR);
343} 360}
344 361
345static inline void udc_clear_mask_UDCCR(struct pxa25x_udc *dev, int mask) 362static inline void udc_clear_mask_UDCCR(struct pxa25x_udc *dev, int mask)
346{ 363{
347 u32 udccr = __UDC_REG(UDCCR); 364 u32 udccr = udc_get_reg(dev, UDCCR);
348 365
349 __UDC_REG(UDCCR) = (udccr & UDCCR_MASK_BITS) & ~(mask & UDCCR_MASK_BITS); 366 udc_set_reg(dev, (udccr & UDCCR_MASK_BITS) & ~(mask & UDCCR_MASK_BITS), UDCCR);
350} 367}
351 368
352static inline void udc_ack_int_UDCCR(struct pxa25x_udc *dev, int mask) 369static inline void udc_ack_int_UDCCR(struct pxa25x_udc *dev, int mask)
353{ 370{
354 /* udccr contains the bits we dont want to change */ 371 /* udccr contains the bits we dont want to change */
355 u32 udccr = __UDC_REG(UDCCR) & UDCCR_MASK_BITS; 372 u32 udccr = udc_get_reg(dev, UDCCR) & UDCCR_MASK_BITS;
356 373
357 __UDC_REG(UDCCR) = udccr | (mask & ~UDCCR_MASK_BITS); 374 udc_set_reg(dev, udccr | (mask & ~UDCCR_MASK_BITS), UDCCR);
358} 375}
359 376
360static inline u32 udc_ep_get_UDCCS(struct pxa25x_ep *ep) 377static inline u32 udc_ep_get_UDCCS(struct pxa25x_ep *ep)
361{ 378{
362 return __UDC_REG(ep->regoff_udccs); 379 return udc_get_reg(ep->dev, ep->regoff_udccs);
363} 380}
364 381
365static inline void udc_ep_set_UDCCS(struct pxa25x_ep *ep, u32 data) 382static inline void udc_ep_set_UDCCS(struct pxa25x_ep *ep, u32 data)
366{ 383{
367 __UDC_REG(ep->regoff_udccs) = data; 384 udc_set_reg(ep->dev, data, ep->regoff_udccs);
368} 385}
369 386
370static inline u32 udc_ep0_get_UDCCS(struct pxa25x_udc *dev) 387static inline u32 udc_ep0_get_UDCCS(struct pxa25x_udc *dev)
371{ 388{
372 return __UDC_REG(UDCCS0); 389 return udc_get_reg(dev, UDCCS0);
373} 390}
374 391
375static inline void udc_ep0_set_UDCCS(struct pxa25x_udc *dev, u32 data) 392static inline void udc_ep0_set_UDCCS(struct pxa25x_udc *dev, u32 data)
376{ 393{
377 __UDC_REG(UDCCS0) = data; 394 udc_set_reg(dev, data, UDCCS0);
378} 395}
379 396
380static inline u32 udc_ep_get_UDDR(struct pxa25x_ep *ep) 397static inline u32 udc_ep_get_UDDR(struct pxa25x_ep *ep)
381{ 398{
382 return __UDC_REG(ep->regoff_uddr); 399 return udc_get_reg(ep->dev, ep->regoff_uddr);
383} 400}
384 401
385static inline void udc_ep_set_UDDR(struct pxa25x_ep *ep, u32 data) 402static inline void udc_ep_set_UDDR(struct pxa25x_ep *ep, u32 data)
386{ 403{
387 __UDC_REG(ep->regoff_uddr) = data; 404 udc_set_reg(ep->dev, data, ep->regoff_uddr);
388} 405}
389 406
390static inline u32 udc_ep_get_UBCR(struct pxa25x_ep *ep) 407static inline u32 udc_ep_get_UBCR(struct pxa25x_ep *ep)
391{ 408{
392 return __UDC_REG(ep->regoff_ubcr); 409 return udc_get_reg(ep->dev, ep->regoff_ubcr);
393} 410}
394 411
395/* 412/*
@@ -2369,9 +2386,9 @@ static int pxa25x_udc_probe(struct platform_device *pdev)
2369 return -ENODEV; 2386 return -ENODEV;
2370 2387
2371 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 2388 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2372 pxa25x_udc_reg_base = devm_ioremap_resource(&pdev->dev, res); 2389 dev->regs = devm_ioremap_resource(&pdev->dev, res);
2373 if (IS_ERR(pxa25x_udc_reg_base)) 2390 if (IS_ERR(dev->regs))
2374 return PTR_ERR(pxa25x_udc_reg_base); 2391 return PTR_ERR(dev->regs);
2375 2392
2376 dev->clk = devm_clk_get(&pdev->dev, NULL); 2393 dev->clk = devm_clk_get(&pdev->dev, NULL);
2377 if (IS_ERR(dev->clk)) 2394 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 {
125#ifdef CONFIG_USB_GADGET_DEBUG_FS 125#ifdef CONFIG_USB_GADGET_DEBUG_FS
126 struct dentry *debugfs_udc; 126 struct dentry *debugfs_udc;
127#endif 127#endif
128 void __iomem *regs;
128}; 129};
129#define to_pxa25x(g) (container_of((g), struct pxa25x_udc, gadget)) 130#define to_pxa25x(g) (container_of((g), struct pxa25x_udc, gadget))
130 131