aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMagnus Damm <damm@igel.co.jp>2009-07-22 10:41:35 -0400
committerPaul Mundt <lethal@linux-sh.org>2009-07-23 00:04:15 -0400
commit2c59b0b70b9d5d61c726f179724660c4c2423f31 (patch)
treedc7629d1ed0627f3651669d8b483f88a8cd4955e
parentcf4f1e76c49dacfde0680b170b9a9b6a42f296bb (diff)
usb: m66592-udc platform data on_chip support
Convert the m66592-udc driver to use the on_chip flag from platform data to enable on chip behaviour instead of relying on CONFIG_SUPERH_BUILT_IN_M66592 ugliness. This makes the code cleaner and also allows us to support both external and internal m66592 with the same kernel. It also makes the Kconfig part more future proof since we with this patch can add support for new processors with on-chip m66592 without modifying the Kconfig. The patch adds a m66592 header file for platform data and ties in platform data to the existing m66592 devices. Signed-off-by: Magnus Damm <damm@igel.co.jp> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
-rw-r--r--arch/sh/boards/mach-highlander/setup.c7
-rw-r--r--arch/sh/boards/mach-x3proto/setup.c7
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7722.c8
-rw-r--r--drivers/usb/gadget/Kconfig10
-rw-r--r--drivers/usb/gadget/m66592-udc.c252
-rw-r--r--drivers/usb/gadget/m66592-udc.h89
-rw-r--r--include/linux/usb/m66592.h44
7 files changed, 257 insertions, 160 deletions
diff --git a/arch/sh/boards/mach-highlander/setup.c b/arch/sh/boards/mach-highlander/setup.c
index 1639f8915000..566e69d8d729 100644
--- a/arch/sh/boards/mach-highlander/setup.c
+++ b/arch/sh/boards/mach-highlander/setup.c
@@ -22,6 +22,7 @@
22#include <linux/irq.h> 22#include <linux/irq.h>
23#include <linux/interrupt.h> 23#include <linux/interrupt.h>
24#include <linux/usb/r8a66597.h> 24#include <linux/usb/r8a66597.h>
25#include <linux/usb/m66592.h>
25#include <net/ax88796.h> 26#include <net/ax88796.h>
26#include <asm/machvec.h> 27#include <asm/machvec.h>
27#include <mach/highlander.h> 28#include <mach/highlander.h>
@@ -60,6 +61,11 @@ static struct platform_device r8a66597_usb_host_device = {
60 .resource = r8a66597_usb_host_resources, 61 .resource = r8a66597_usb_host_resources,
61}; 62};
62 63
64static struct m66592_platdata usbf_platdata = {
65 .xtal = M66592_PLATDATA_XTAL_24MHZ,
66 .vif = 1,
67};
68
63static struct resource m66592_usb_peripheral_resources[] = { 69static struct resource m66592_usb_peripheral_resources[] = {
64 [0] = { 70 [0] = {
65 .name = "m66592_udc", 71 .name = "m66592_udc",
@@ -81,6 +87,7 @@ static struct platform_device m66592_usb_peripheral_device = {
81 .dev = { 87 .dev = {
82 .dma_mask = NULL, /* don't use dma */ 88 .dma_mask = NULL, /* don't use dma */
83 .coherent_dma_mask = 0xffffffff, 89 .coherent_dma_mask = 0xffffffff,
90 .platform_data = &usbf_platdata,
84 }, 91 },
85 .num_resources = ARRAY_SIZE(m66592_usb_peripheral_resources), 92 .num_resources = ARRAY_SIZE(m66592_usb_peripheral_resources),
86 .resource = m66592_usb_peripheral_resources, 93 .resource = m66592_usb_peripheral_resources,
diff --git a/arch/sh/boards/mach-x3proto/setup.c b/arch/sh/boards/mach-x3proto/setup.c
index 8913ae39a802..efe4cb9f8a77 100644
--- a/arch/sh/boards/mach-x3proto/setup.c
+++ b/arch/sh/boards/mach-x3proto/setup.c
@@ -17,6 +17,7 @@
17#include <linux/irq.h> 17#include <linux/irq.h>
18#include <linux/interrupt.h> 18#include <linux/interrupt.h>
19#include <linux/usb/r8a66597.h> 19#include <linux/usb/r8a66597.h>
20#include <linux/usb/m66592.h>
20#include <asm/ilsel.h> 21#include <asm/ilsel.h>
21 22
22static struct resource heartbeat_resources[] = { 23static struct resource heartbeat_resources[] = {
@@ -89,6 +90,11 @@ static struct platform_device r8a66597_usb_host_device = {
89 .resource = r8a66597_usb_host_resources, 90 .resource = r8a66597_usb_host_resources,
90}; 91};
91 92
93static struct m66592_platdata usbf_platdata = {
94 .xtal = M66592_PLATDATA_XTAL_24MHZ,
95 .vif = 1,
96};
97
92static struct resource m66592_usb_peripheral_resources[] = { 98static struct resource m66592_usb_peripheral_resources[] = {
93 [0] = { 99 [0] = {
94 .name = "m66592_udc", 100 .name = "m66592_udc",
@@ -109,6 +115,7 @@ static struct platform_device m66592_usb_peripheral_device = {
109 .dev = { 115 .dev = {
110 .dma_mask = NULL, /* don't use dma */ 116 .dma_mask = NULL, /* don't use dma */
111 .coherent_dma_mask = 0xffffffff, 117 .coherent_dma_mask = 0xffffffff,
118 .platform_data = &usbf_platdata,
112 }, 119 },
113 .num_resources = ARRAY_SIZE(m66592_usb_peripheral_resources), 120 .num_resources = ARRAY_SIZE(m66592_usb_peripheral_resources),
114 .resource = m66592_usb_peripheral_resources, 121 .resource = m66592_usb_peripheral_resources,
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
index ea524a2da3e4..0bad14a44238 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
@@ -13,6 +13,7 @@
13#include <linux/serial_sci.h> 13#include <linux/serial_sci.h>
14#include <linux/mm.h> 14#include <linux/mm.h>
15#include <linux/uio_driver.h> 15#include <linux/uio_driver.h>
16#include <linux/usb/m66592.h>
16#include <linux/sh_timer.h> 17#include <linux/sh_timer.h>
17#include <asm/clock.h> 18#include <asm/clock.h>
18#include <asm/mmzone.h> 19#include <asm/mmzone.h>
@@ -47,9 +48,13 @@ static struct platform_device rtc_device = {
47 .resource = rtc_resources, 48 .resource = rtc_resources,
48}; 49};
49 50
51static struct m66592_platdata usbf_platdata = {
52 .on_chip = 1,
53};
54
50static struct resource usbf_resources[] = { 55static struct resource usbf_resources[] = {
51 [0] = { 56 [0] = {
52 .name = "m66592_udc", 57 .name = "USBF",
53 .start = 0x04480000, 58 .start = 0x04480000,
54 .end = 0x044800FF, 59 .end = 0x044800FF,
55 .flags = IORESOURCE_MEM, 60 .flags = IORESOURCE_MEM,
@@ -67,6 +72,7 @@ static struct platform_device usbf_device = {
67 .dev = { 72 .dev = {
68 .dma_mask = NULL, 73 .dma_mask = NULL,
69 .coherent_dma_mask = 0xffffffff, 74 .coherent_dma_mask = 0xffffffff,
75 .platform_data = &usbf_platdata,
70 }, 76 },
71 .num_resources = ARRAY_SIZE(usbf_resources), 77 .num_resources = ARRAY_SIZE(usbf_resources),
72 .resource = usbf_resources, 78 .resource = usbf_resources,
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index 7f8e83a954ac..b7f10bc25c2c 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -360,16 +360,6 @@ config USB_M66592
360 default USB_GADGET 360 default USB_GADGET
361 select USB_GADGET_SELECTED 361 select USB_GADGET_SELECTED
362 362
363config SUPERH_BUILT_IN_M66592
364 boolean "Enable SuperH built-in USB like the M66592"
365 depends on USB_GADGET_M66592 && CPU_SUBTYPE_SH7722
366 help
367 SH7722 has USB like the M66592.
368
369 The transfer rate is very slow when use "Ethernet Gadget".
370 However, this problem is improved if change a value of
371 NET_IP_ALIGN to 4.
372
373# 363#
374# Controllers available only in discrete form (and all PCI controllers) 364# Controllers available only in discrete form (and all PCI controllers)
375# 365#
diff --git a/drivers/usb/gadget/m66592-udc.c b/drivers/usb/gadget/m66592-udc.c
index 0dddd2f8ff35..a61c70caff12 100644
--- a/drivers/usb/gadget/m66592-udc.c
+++ b/drivers/usb/gadget/m66592-udc.c
@@ -31,38 +31,12 @@
31 31
32#include "m66592-udc.h" 32#include "m66592-udc.h"
33 33
34
35MODULE_DESCRIPTION("M66592 USB gadget driver"); 34MODULE_DESCRIPTION("M66592 USB gadget driver");
36MODULE_LICENSE("GPL"); 35MODULE_LICENSE("GPL");
37MODULE_AUTHOR("Yoshihiro Shimoda"); 36MODULE_AUTHOR("Yoshihiro Shimoda");
38MODULE_ALIAS("platform:m66592_udc"); 37MODULE_ALIAS("platform:m66592_udc");
39 38
40#define DRIVER_VERSION "26 Jun 2009" 39#define DRIVER_VERSION "21 July 2009"
41
42/* module parameters */
43#if defined(CONFIG_SUPERH_BUILT_IN_M66592)
44static unsigned short endian = M66592_LITTLE;
45module_param(endian, ushort, 0644);
46MODULE_PARM_DESC(endian, "data endian: big=0, little=0 (default=0)");
47#else
48static unsigned short clock = M66592_XTAL24;
49module_param(clock, ushort, 0644);
50MODULE_PARM_DESC(clock, "input clock: 48MHz=32768, 24MHz=16384, 12MHz=0 "
51 "(default=16384)");
52
53static unsigned short vif = M66592_LDRV;
54module_param(vif, ushort, 0644);
55MODULE_PARM_DESC(vif, "input VIF: 3.3V=32768, 1.5V=0 (default=32768)");
56
57static unsigned short endian;
58module_param(endian, ushort, 0644);
59MODULE_PARM_DESC(endian, "data endian: big=256, little=0 (default=0)");
60
61static unsigned short irq_sense = M66592_INTL;
62module_param(irq_sense, ushort, 0644);
63MODULE_PARM_DESC(irq_sense, "IRQ sense: low level=2, falling edge=0 "
64 "(default=2)");
65#endif
66 40
67static const char udc_name[] = "m66592_udc"; 41static const char udc_name[] = "m66592_udc";
68static const char *m66592_ep_name[] = { 42static const char *m66592_ep_name[] = {
@@ -244,6 +218,7 @@ static inline int get_buffer_size(struct m66592 *m66592, u16 pipenum)
244static inline void pipe_change(struct m66592 *m66592, u16 pipenum) 218static inline void pipe_change(struct m66592 *m66592, u16 pipenum)
245{ 219{
246 struct m66592_ep *ep = m66592->pipenum2ep[pipenum]; 220 struct m66592_ep *ep = m66592->pipenum2ep[pipenum];
221 unsigned short mbw;
247 222
248 if (ep->use_dma) 223 if (ep->use_dma)
249 return; 224 return;
@@ -252,7 +227,12 @@ static inline void pipe_change(struct m66592 *m66592, u16 pipenum)
252 227
253 ndelay(450); 228 ndelay(450);
254 229
255 m66592_bset(m66592, M66592_MBW, ep->fifosel); 230 if (m66592->pdata->on_chip)
231 mbw = M66592_MBW_32;
232 else
233 mbw = M66592_MBW_16;
234
235 m66592_bset(m66592, mbw, ep->fifosel);
256} 236}
257 237
258static int pipe_buffer_setting(struct m66592 *m66592, 238static int pipe_buffer_setting(struct m66592 *m66592,
@@ -332,6 +312,7 @@ static void pipe_buffer_release(struct m66592 *m66592,
332static void pipe_initialize(struct m66592_ep *ep) 312static void pipe_initialize(struct m66592_ep *ep)
333{ 313{
334 struct m66592 *m66592 = ep->m66592; 314 struct m66592 *m66592 = ep->m66592;
315 unsigned short mbw;
335 316
336 m66592_mdfy(m66592, 0, M66592_CURPIPE, ep->fifosel); 317 m66592_mdfy(m66592, 0, M66592_CURPIPE, ep->fifosel);
337 318
@@ -343,7 +324,12 @@ static void pipe_initialize(struct m66592_ep *ep)
343 324
344 ndelay(450); 325 ndelay(450);
345 326
346 m66592_bset(m66592, M66592_MBW, ep->fifosel); 327 if (m66592->pdata->on_chip)
328 mbw = M66592_MBW_32;
329 else
330 mbw = M66592_MBW_16;
331
332 m66592_bset(m66592, mbw, ep->fifosel);
347 } 333 }
348} 334}
349 335
@@ -359,15 +345,13 @@ static void m66592_ep_setting(struct m66592 *m66592, struct m66592_ep *ep,
359 ep->fifosel = M66592_D0FIFOSEL; 345 ep->fifosel = M66592_D0FIFOSEL;
360 ep->fifoctr = M66592_D0FIFOCTR; 346 ep->fifoctr = M66592_D0FIFOCTR;
361 ep->fifotrn = M66592_D0FIFOTRN; 347 ep->fifotrn = M66592_D0FIFOTRN;
362#if !defined(CONFIG_SUPERH_BUILT_IN_M66592) 348 } else if (!m66592->pdata->on_chip && m66592->num_dma == 1) {
363 } else if (m66592->num_dma == 1) {
364 m66592->num_dma++; 349 m66592->num_dma++;
365 ep->use_dma = 1; 350 ep->use_dma = 1;
366 ep->fifoaddr = M66592_D1FIFO; 351 ep->fifoaddr = M66592_D1FIFO;
367 ep->fifosel = M66592_D1FIFOSEL; 352 ep->fifosel = M66592_D1FIFOSEL;
368 ep->fifoctr = M66592_D1FIFOCTR; 353 ep->fifoctr = M66592_D1FIFOCTR;
369 ep->fifotrn = M66592_D1FIFOTRN; 354 ep->fifotrn = M66592_D1FIFOTRN;
370#endif
371 } else { 355 } else {
372 ep->use_dma = 0; 356 ep->use_dma = 0;
373 ep->fifoaddr = M66592_CFIFO; 357 ep->fifoaddr = M66592_CFIFO;
@@ -612,76 +596,120 @@ static void start_ep0(struct m66592_ep *ep, struct m66592_request *req)
612 } 596 }
613} 597}
614 598
615#if defined(CONFIG_SUPERH_BUILT_IN_M66592)
616static void init_controller(struct m66592 *m66592) 599static void init_controller(struct m66592 *m66592)
617{ 600{
618 m66592_bset(m66592, M66592_HSE, M66592_SYSCFG); /* High spd */ 601 unsigned int endian;
619 m66592_bclr(m66592, M66592_USBE, M66592_SYSCFG);
620 m66592_bclr(m66592, M66592_DPRPU, M66592_SYSCFG);
621 m66592_bset(m66592, M66592_USBE, M66592_SYSCFG);
622 602
623 /* This is a workaound for SH7722 2nd cut */ 603 if (m66592->pdata->on_chip) {
624 m66592_bset(m66592, 0x8000, M66592_DVSTCTR); 604 if (m66592->pdata->endian)
625 m66592_bset(m66592, 0x1000, M66592_TESTMODE); 605 endian = 0; /* big endian */
626 m66592_bclr(m66592, 0x8000, M66592_DVSTCTR); 606 else
607 endian = M66592_LITTLE; /* little endian */
627 608
628 m66592_bset(m66592, M66592_INTL, M66592_INTENB1); 609 m66592_bset(m66592, M66592_HSE, M66592_SYSCFG); /* High spd */
610 m66592_bclr(m66592, M66592_USBE, M66592_SYSCFG);
611 m66592_bclr(m66592, M66592_DPRPU, M66592_SYSCFG);
612 m66592_bset(m66592, M66592_USBE, M66592_SYSCFG);
629 613
630 m66592_write(m66592, 0, M66592_CFBCFG); 614 /* This is a workaound for SH7722 2nd cut */
631 m66592_write(m66592, 0, M66592_D0FBCFG); 615 m66592_bset(m66592, 0x8000, M66592_DVSTCTR);
632 m66592_bset(m66592, endian, M66592_CFBCFG); 616 m66592_bset(m66592, 0x1000, M66592_TESTMODE);
633 m66592_bset(m66592, endian, M66592_D0FBCFG); 617 m66592_bclr(m66592, 0x8000, M66592_DVSTCTR);
634}
635#else /* #if defined(CONFIG_SUPERH_BUILT_IN_M66592) */
636static void init_controller(struct m66592 *m66592)
637{
638 m66592_bset(m66592, (vif & M66592_LDRV) | (endian & M66592_BIGEND),
639 M66592_PINCFG);
640 m66592_bset(m66592, M66592_HSE, M66592_SYSCFG); /* High spd */
641 m66592_mdfy(m66592, clock & M66592_XTAL, M66592_XTAL, M66592_SYSCFG);
642 618
643 m66592_bclr(m66592, M66592_USBE, M66592_SYSCFG); 619 m66592_bset(m66592, M66592_INTL, M66592_INTENB1);
644 m66592_bclr(m66592, M66592_DPRPU, M66592_SYSCFG); 620
645 m66592_bset(m66592, M66592_USBE, M66592_SYSCFG); 621 m66592_write(m66592, 0, M66592_CFBCFG);
622 m66592_write(m66592, 0, M66592_D0FBCFG);
623 m66592_bset(m66592, endian, M66592_CFBCFG);
624 m66592_bset(m66592, endian, M66592_D0FBCFG);
625 } else {
626 unsigned int clock, vif, irq_sense;
627
628 if (m66592->pdata->endian)
629 endian = M66592_BIGEND; /* big endian */
630 else
631 endian = 0; /* little endian */
632
633 if (m66592->pdata->vif)
634 vif = M66592_LDRV; /* 3.3v */
635 else
636 vif = 0; /* 1.5v */
637
638 switch (m66592->pdata->xtal) {
639 case M66592_PLATDATA_XTAL_12MHZ:
640 clock = M66592_XTAL12;
641 break;
642 case M66592_PLATDATA_XTAL_24MHZ:
643 clock = M66592_XTAL24;
644 break;
645 case M66592_PLATDATA_XTAL_48MHZ:
646 clock = M66592_XTAL48;
647 break;
648 default:
649 pr_warning("m66592-udc: xtal configuration error\n");
650 clock = 0;
651 }
646 652
647 m66592_bset(m66592, M66592_XCKE, M66592_SYSCFG); 653 switch (m66592->irq_trigger) {
654 case IRQF_TRIGGER_LOW:
655 irq_sense = M66592_INTL;
656 break;
657 case IRQF_TRIGGER_FALLING:
658 irq_sense = 0;
659 break;
660 default:
661 pr_warning("m66592-udc: irq trigger config error\n");
662 irq_sense = 0;
663 }
648 664
649 msleep(3); 665 m66592_bset(m66592,
666 (vif & M66592_LDRV) | (endian & M66592_BIGEND),
667 M66592_PINCFG);
668 m66592_bset(m66592, M66592_HSE, M66592_SYSCFG); /* High spd */
669 m66592_mdfy(m66592, clock & M66592_XTAL, M66592_XTAL,
670 M66592_SYSCFG);
671 m66592_bclr(m66592, M66592_USBE, M66592_SYSCFG);
672 m66592_bclr(m66592, M66592_DPRPU, M66592_SYSCFG);
673 m66592_bset(m66592, M66592_USBE, M66592_SYSCFG);
650 674
651 m66592_bset(m66592, M66592_RCKE | M66592_PLLC, M66592_SYSCFG); 675 m66592_bset(m66592, M66592_XCKE, M66592_SYSCFG);
676
677 msleep(3);
652 678
653 msleep(1); 679 m66592_bset(m66592, M66592_RCKE | M66592_PLLC, M66592_SYSCFG);
654 680
655 m66592_bset(m66592, M66592_SCKE, M66592_SYSCFG); 681 msleep(1);
656 682
657 m66592_bset(m66592, irq_sense & M66592_INTL, M66592_INTENB1); 683 m66592_bset(m66592, M66592_SCKE, M66592_SYSCFG);
658 m66592_write(m66592, M66592_BURST | M66592_CPU_ADR_RD_WR, 684
659 M66592_DMA0CFG); 685 m66592_bset(m66592, irq_sense & M66592_INTL, M66592_INTENB1);
686 m66592_write(m66592, M66592_BURST | M66592_CPU_ADR_RD_WR,
687 M66592_DMA0CFG);
688 }
660} 689}
661#endif /* #if defined(CONFIG_SUPERH_BUILT_IN_M66592) */
662 690
663static void disable_controller(struct m66592 *m66592) 691static void disable_controller(struct m66592 *m66592)
664{ 692{
665#if !defined(CONFIG_SUPERH_BUILT_IN_M66592) 693 if (!m66592->pdata->on_chip) {
666 m66592_bclr(m66592, M66592_SCKE, M66592_SYSCFG); 694 m66592_bclr(m66592, M66592_SCKE, M66592_SYSCFG);
667 udelay(1); 695 udelay(1);
668 m66592_bclr(m66592, M66592_PLLC, M66592_SYSCFG); 696 m66592_bclr(m66592, M66592_PLLC, M66592_SYSCFG);
669 udelay(1); 697 udelay(1);
670 m66592_bclr(m66592, M66592_RCKE, M66592_SYSCFG); 698 m66592_bclr(m66592, M66592_RCKE, M66592_SYSCFG);
671 udelay(1); 699 udelay(1);
672 m66592_bclr(m66592, M66592_XCKE, M66592_SYSCFG); 700 m66592_bclr(m66592, M66592_XCKE, M66592_SYSCFG);
673#endif 701 }
674} 702}
675 703
676static void m66592_start_xclock(struct m66592 *m66592) 704static void m66592_start_xclock(struct m66592 *m66592)
677{ 705{
678#if !defined(CONFIG_SUPERH_BUILT_IN_M66592)
679 u16 tmp; 706 u16 tmp;
680 707
681 tmp = m66592_read(m66592, M66592_SYSCFG); 708 if (!m66592->pdata->on_chip) {
682 if (!(tmp & M66592_XCKE)) 709 tmp = m66592_read(m66592, M66592_SYSCFG);
683 m66592_bset(m66592, M66592_XCKE, M66592_SYSCFG); 710 if (!(tmp & M66592_XCKE))
684#endif 711 m66592_bset(m66592, M66592_XCKE, M66592_SYSCFG);
712 }
685} 713}
686 714
687/*-------------------------------------------------------------------------*/ 715/*-------------------------------------------------------------------------*/
@@ -1169,8 +1197,7 @@ static irqreturn_t m66592_irq(int irq, void *_m66592)
1169 intsts0 = m66592_read(m66592, M66592_INTSTS0); 1197 intsts0 = m66592_read(m66592, M66592_INTSTS0);
1170 intenb0 = m66592_read(m66592, M66592_INTENB0); 1198 intenb0 = m66592_read(m66592, M66592_INTENB0);
1171 1199
1172#if defined(CONFIG_SUPERH_BUILT_IN_M66592) 1200 if (m66592->pdata->on_chip && !intsts0 && !intenb0) {
1173 if (!intsts0 && !intenb0) {
1174 /* 1201 /*
1175 * When USB clock stops, it cannot read register. Even if a 1202 * When USB clock stops, it cannot read register. Even if a
1176 * clock stops, the interrupt occurs. So this driver turn on 1203 * clock stops, the interrupt occurs. So this driver turn on
@@ -1180,7 +1207,6 @@ static irqreturn_t m66592_irq(int irq, void *_m66592)
1180 intsts0 = m66592_read(m66592, M66592_INTSTS0); 1207 intsts0 = m66592_read(m66592, M66592_INTSTS0);
1181 intenb0 = m66592_read(m66592, M66592_INTENB0); 1208 intenb0 = m66592_read(m66592, M66592_INTENB0);
1182 } 1209 }
1183#endif
1184 1210
1185 savepipe = m66592_read(m66592, M66592_CFIFOSEL); 1211 savepipe = m66592_read(m66592, M66592_CFIFOSEL);
1186 1212
@@ -1526,9 +1552,11 @@ static int __exit m66592_remove(struct platform_device *pdev)
1526 iounmap(m66592->reg); 1552 iounmap(m66592->reg);
1527 free_irq(platform_get_irq(pdev, 0), m66592); 1553 free_irq(platform_get_irq(pdev, 0), m66592);
1528 m66592_free_request(&m66592->ep[0].ep, m66592->ep0_req); 1554 m66592_free_request(&m66592->ep[0].ep, m66592->ep0_req);
1529#if defined(CONFIG_SUPERH_BUILT_IN_M66592) && defined(CONFIG_HAVE_CLK) 1555#ifdef CONFIG_HAVE_CLK
1530 clk_disable(m66592->clk); 1556 if (m66592->pdata->on_chip) {
1531 clk_put(m66592->clk); 1557 clk_disable(m66592->clk);
1558 clk_put(m66592->clk);
1559 }
1532#endif 1560#endif
1533 kfree(m66592); 1561 kfree(m66592);
1534 return 0; 1562 return 0;
@@ -1540,11 +1568,10 @@ static void nop_completion(struct usb_ep *ep, struct usb_request *r)
1540 1568
1541static int __init m66592_probe(struct platform_device *pdev) 1569static int __init m66592_probe(struct platform_device *pdev)
1542{ 1570{
1543 struct resource *res; 1571 struct resource *res, *ires;
1544 int irq;
1545 void __iomem *reg = NULL; 1572 void __iomem *reg = NULL;
1546 struct m66592 *m66592 = NULL; 1573 struct m66592 *m66592 = NULL;
1547#if defined(CONFIG_SUPERH_BUILT_IN_M66592) && defined(CONFIG_HAVE_CLK) 1574#ifdef CONFIG_HAVE_CLK
1548 char clk_name[8]; 1575 char clk_name[8];
1549#endif 1576#endif
1550 int ret = 0; 1577 int ret = 0;
@@ -1557,10 +1584,11 @@ static int __init m66592_probe(struct platform_device *pdev)
1557 goto clean_up; 1584 goto clean_up;
1558 } 1585 }
1559 1586
1560 irq = platform_get_irq(pdev, 0); 1587 ires = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
1561 if (irq < 0) { 1588 if (!ires) {
1562 ret = -ENODEV; 1589 ret = -ENODEV;
1563 pr_err("platform_get_irq error.\n"); 1590 dev_err(&pdev->dev,
1591 "platform_get_resource IORESOURCE_IRQ error.\n");
1564 goto clean_up; 1592 goto clean_up;
1565 } 1593 }
1566 1594
@@ -1571,6 +1599,12 @@ static int __init m66592_probe(struct platform_device *pdev)
1571 goto clean_up; 1599 goto clean_up;
1572 } 1600 }
1573 1601
1602 if (pdev->dev.platform_data == NULL) {
1603 dev_err(&pdev->dev, "no platform data\n");
1604 ret = -ENODEV;
1605 goto clean_up;
1606 }
1607
1574 /* initialize ucd */ 1608 /* initialize ucd */
1575 m66592 = kzalloc(sizeof(struct m66592), GFP_KERNEL); 1609 m66592 = kzalloc(sizeof(struct m66592), GFP_KERNEL);
1576 if (m66592 == NULL) { 1610 if (m66592 == NULL) {
@@ -1578,6 +1612,9 @@ static int __init m66592_probe(struct platform_device *pdev)
1578 goto clean_up; 1612 goto clean_up;
1579 } 1613 }
1580 1614
1615 m66592->pdata = pdev->dev.platform_data;
1616 m66592->irq_trigger = ires->flags & IRQF_TRIGGER_MASK;
1617
1581 spin_lock_init(&m66592->lock); 1618 spin_lock_init(&m66592->lock);
1582 dev_set_drvdata(&pdev->dev, m66592); 1619 dev_set_drvdata(&pdev->dev, m66592);
1583 1620
@@ -1595,22 +1632,25 @@ static int __init m66592_probe(struct platform_device *pdev)
1595 m66592->timer.data = (unsigned long)m66592; 1632 m66592->timer.data = (unsigned long)m66592;
1596 m66592->reg = reg; 1633 m66592->reg = reg;
1597 1634
1598 ret = request_irq(irq, m66592_irq, IRQF_DISABLED | IRQF_SHARED, 1635 ret = request_irq(ires->start, m66592_irq, IRQF_DISABLED | IRQF_SHARED,
1599 udc_name, m66592); 1636 udc_name, m66592);
1600 if (ret < 0) { 1637 if (ret < 0) {
1601 pr_err("request_irq error (%d)\n", ret); 1638 pr_err("request_irq error (%d)\n", ret);
1602 goto clean_up; 1639 goto clean_up;
1603 } 1640 }
1604 1641
1605#if defined(CONFIG_SUPERH_BUILT_IN_M66592) && defined(CONFIG_HAVE_CLK) 1642#ifdef CONFIG_HAVE_CLK
1606 snprintf(clk_name, sizeof(clk_name), "usbf%d", pdev->id); 1643 if (m66592->pdata->on_chip) {
1607 m66592->clk = clk_get(&pdev->dev, clk_name); 1644 snprintf(clk_name, sizeof(clk_name), "usbf%d", pdev->id);
1608 if (IS_ERR(m66592->clk)) { 1645 m66592->clk = clk_get(&pdev->dev, clk_name);
1609 dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name); 1646 if (IS_ERR(m66592->clk)) {
1610 ret = PTR_ERR(m66592->clk); 1647 dev_err(&pdev->dev, "cannot get clock \"%s\"\n",
1611 goto clean_up2; 1648 clk_name);
1649 ret = PTR_ERR(m66592->clk);
1650 goto clean_up2;
1651 }
1652 clk_enable(m66592->clk);
1612 } 1653 }
1613 clk_enable(m66592->clk);
1614#endif 1654#endif
1615 INIT_LIST_HEAD(&m66592->gadget.ep_list); 1655 INIT_LIST_HEAD(&m66592->gadget.ep_list);
1616 m66592->gadget.ep0 = &m66592->ep[0].ep; 1656 m66592->gadget.ep0 = &m66592->ep[0].ep;
@@ -1652,12 +1692,14 @@ static int __init m66592_probe(struct platform_device *pdev)
1652 return 0; 1692 return 0;
1653 1693
1654clean_up3: 1694clean_up3:
1655#if defined(CONFIG_SUPERH_BUILT_IN_M66592) && defined(CONFIG_HAVE_CLK) 1695#ifdef CONFIG_HAVE_CLK
1656 clk_disable(m66592->clk); 1696 if (m66592->pdata->on_chip) {
1657 clk_put(m66592->clk); 1697 clk_disable(m66592->clk);
1698 clk_put(m66592->clk);
1699 }
1658clean_up2: 1700clean_up2:
1659#endif 1701#endif
1660 free_irq(irq, m66592); 1702 free_irq(ires->start, m66592);
1661clean_up: 1703clean_up:
1662 if (m66592) { 1704 if (m66592) {
1663 if (m66592->ep0_req) 1705 if (m66592->ep0_req)
diff --git a/drivers/usb/gadget/m66592-udc.h b/drivers/usb/gadget/m66592-udc.h
index 9a9c2bf9fbd5..8b960deed680 100644
--- a/drivers/usb/gadget/m66592-udc.h
+++ b/drivers/usb/gadget/m66592-udc.h
@@ -23,10 +23,12 @@
23#ifndef __M66592_UDC_H__ 23#ifndef __M66592_UDC_H__
24#define __M66592_UDC_H__ 24#define __M66592_UDC_H__
25 25
26#if defined(CONFIG_SUPERH_BUILT_IN_M66592) && defined(CONFIG_HAVE_CLK) 26#ifdef CONFIG_HAVE_CLK
27#include <linux/clk.h> 27#include <linux/clk.h>
28#endif 28#endif
29 29
30#include <linux/usb/m66592.h>
31
30#define M66592_SYSCFG 0x00 32#define M66592_SYSCFG 0x00
31#define M66592_XTAL 0xC000 /* b15-14: Crystal selection */ 33#define M66592_XTAL 0xC000 /* b15-14: Crystal selection */
32#define M66592_XTAL48 0x8000 /* 48MHz */ 34#define M66592_XTAL48 0x8000 /* 48MHz */
@@ -76,11 +78,11 @@
76#define M66592_P_TST_J 0x0001 /* PERI TEST J */ 78#define M66592_P_TST_J 0x0001 /* PERI TEST J */
77#define M66592_P_TST_NORMAL 0x0000 /* PERI Normal Mode */ 79#define M66592_P_TST_NORMAL 0x0000 /* PERI Normal Mode */
78 80
79#if defined(CONFIG_SUPERH_BUILT_IN_M66592) 81/* built-in registers */
80#define M66592_CFBCFG 0x0A 82#define M66592_CFBCFG 0x0A
81#define M66592_D0FBCFG 0x0C 83#define M66592_D0FBCFG 0x0C
82#define M66592_LITTLE 0x0100 /* b8: Little endian mode */ 84#define M66592_LITTLE 0x0100 /* b8: Little endian mode */
83#else 85/* external chip case */
84#define M66592_PINCFG 0x0A 86#define M66592_PINCFG 0x0A
85#define M66592_LDRV 0x8000 /* b15: Drive Current Adjust */ 87#define M66592_LDRV 0x8000 /* b15: Drive Current Adjust */
86#define M66592_BIGEND 0x0100 /* b8: Big endian mode */ 88#define M66592_BIGEND 0x0100 /* b8: Big endian mode */
@@ -100,8 +102,8 @@
100#define M66592_PKTM 0x0020 /* b5: Packet mode */ 102#define M66592_PKTM 0x0020 /* b5: Packet mode */
101#define M66592_DENDE 0x0010 /* b4: Dend enable */ 103#define M66592_DENDE 0x0010 /* b4: Dend enable */
102#define M66592_OBUS 0x0004 /* b2: OUTbus mode */ 104#define M66592_OBUS 0x0004 /* b2: OUTbus mode */
103#endif /* #if defined(CONFIG_SUPERH_BUILT_IN_M66592) */
104 105
106/* common case */
105#define M66592_CFIFO 0x10 107#define M66592_CFIFO 0x10
106#define M66592_D0FIFO 0x14 108#define M66592_D0FIFO 0x14
107#define M66592_D1FIFO 0x18 109#define M66592_D1FIFO 0x18
@@ -113,13 +115,9 @@
113#define M66592_REW 0x4000 /* b14: Buffer rewind */ 115#define M66592_REW 0x4000 /* b14: Buffer rewind */
114#define M66592_DCLRM 0x2000 /* b13: DMA buffer clear mode */ 116#define M66592_DCLRM 0x2000 /* b13: DMA buffer clear mode */
115#define M66592_DREQE 0x1000 /* b12: DREQ output enable */ 117#define M66592_DREQE 0x1000 /* b12: DREQ output enable */
116#if defined(CONFIG_SUPERH_BUILT_IN_M66592) 118#define M66592_MBW_8 0x0000 /* 8bit */
117#define M66592_MBW 0x0800 /* b11: Maximum bit width for FIFO */ 119#define M66592_MBW_16 0x0400 /* 16bit */
118#else 120#define M66592_MBW_32 0x0800 /* 32bit */
119#define M66592_MBW 0x0400 /* b10: Maximum bit width for FIFO */
120#define M66592_MBW_8 0x0000 /* 8bit */
121#define M66592_MBW_16 0x0400 /* 16bit */
122#endif /* #if defined(CONFIG_SUPERH_BUILT_IN_M66592) */
123#define M66592_TRENB 0x0200 /* b9: Transaction counter enable */ 121#define M66592_TRENB 0x0200 /* b9: Transaction counter enable */
124#define M66592_TRCLR 0x0100 /* b8: Transaction counter clear */ 122#define M66592_TRCLR 0x0100 /* b8: Transaction counter clear */
125#define M66592_DEZPM 0x0080 /* b7: Zero-length packet mode */ 123#define M66592_DEZPM 0x0080 /* b7: Zero-length packet mode */
@@ -480,9 +478,11 @@ struct m66592_ep {
480struct m66592 { 478struct m66592 {
481 spinlock_t lock; 479 spinlock_t lock;
482 void __iomem *reg; 480 void __iomem *reg;
483#if defined(CONFIG_SUPERH_BUILT_IN_M66592) && defined(CONFIG_HAVE_CLK) 481#ifdef CONFIG_HAVE_CLK
484 struct clk *clk; 482 struct clk *clk;
485#endif 483#endif
484 struct m66592_platdata *pdata;
485 unsigned long irq_trigger;
486 486
487 struct usb_gadget gadget; 487 struct usb_gadget gadget;
488 struct usb_gadget_driver *driver; 488 struct usb_gadget_driver *driver;
@@ -546,13 +546,13 @@ static inline void m66592_read_fifo(struct m66592 *m66592,
546{ 546{
547 unsigned long fifoaddr = (unsigned long)m66592->reg + offset; 547 unsigned long fifoaddr = (unsigned long)m66592->reg + offset;
548 548
549#if defined(CONFIG_SUPERH_BUILT_IN_M66592) 549 if (m66592->pdata->on_chip) {
550 len = (len + 3) / 4; 550 len = (len + 3) / 4;
551 insl(fifoaddr, buf, len); 551 insl(fifoaddr, buf, len);
552#else 552 } else {
553 len = (len + 1) / 2; 553 len = (len + 1) / 2;
554 insw(fifoaddr, buf, len); 554 insw(fifoaddr, buf, len);
555#endif 555 }
556} 556}
557 557
558static inline void m66592_write(struct m66592 *m66592, u16 val, 558static inline void m66592_write(struct m66592 *m66592, u16 val,
@@ -566,33 +566,34 @@ static inline void m66592_write_fifo(struct m66592 *m66592,
566 void *buf, unsigned long len) 566 void *buf, unsigned long len)
567{ 567{
568 unsigned long fifoaddr = (unsigned long)m66592->reg + offset; 568 unsigned long fifoaddr = (unsigned long)m66592->reg + offset;
569#if defined(CONFIG_SUPERH_BUILT_IN_M66592) 569
570 unsigned long count; 570 if (m66592->pdata->on_chip) {
571 unsigned char *pb; 571 unsigned long count;
572 int i; 572 unsigned char *pb;
573 573 int i;
574 count = len / 4; 574
575 outsl(fifoaddr, buf, count); 575 count = len / 4;
576 576 outsl(fifoaddr, buf, count);
577 if (len & 0x00000003) { 577
578 pb = buf + count * 4; 578 if (len & 0x00000003) {
579 for (i = 0; i < (len & 0x00000003); i++) { 579 pb = buf + count * 4;
580 if (m66592_read(m66592, M66592_CFBCFG)) /* little */ 580 for (i = 0; i < (len & 0x00000003); i++) {
581 outb(pb[i], fifoaddr + (3 - i)); 581 if (m66592_read(m66592, M66592_CFBCFG)) /* le */
582 else 582 outb(pb[i], fifoaddr + (3 - i));
583 outb(pb[i], fifoaddr + i); 583 else
584 outb(pb[i], fifoaddr + i);
585 }
586 }
587 } else {
588 unsigned long odd = len & 0x0001;
589
590 len = len / 2;
591 outsw(fifoaddr, buf, len);
592 if (odd) {
593 unsigned char *p = buf + len*2;
594 outb(*p, fifoaddr);
584 } 595 }
585 } 596 }
586#else
587 unsigned long odd = len & 0x0001;
588
589 len = len / 2;
590 outsw(fifoaddr, buf, len);
591 if (odd) {
592 unsigned char *p = buf + len*2;
593 outb(*p, fifoaddr);
594 }
595#endif /* #if defined(CONFIG_SUPERH_BUILT_IN_M66592) */
596} 597}
597 598
598static inline void m66592_mdfy(struct m66592 *m66592, u16 val, u16 pat, 599static inline void m66592_mdfy(struct m66592 *m66592, u16 val, u16 pat,
diff --git a/include/linux/usb/m66592.h b/include/linux/usb/m66592.h
new file mode 100644
index 000000000000..cda9625e7df0
--- /dev/null
+++ b/include/linux/usb/m66592.h
@@ -0,0 +1,44 @@
1/*
2 * M66592 driver platform data
3 *
4 * Copyright (C) 2009 Renesas Solutions Corp.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 *
19 */
20
21#ifndef __LINUX_USB_M66592_H
22#define __LINUX_USB_M66592_H
23
24#define M66592_PLATDATA_XTAL_12MHZ 0x01
25#define M66592_PLATDATA_XTAL_24MHZ 0x02
26#define M66592_PLATDATA_XTAL_48MHZ 0x03
27
28struct m66592_platdata {
29 /* one = on chip controller, zero = external controller */
30 unsigned on_chip:1;
31
32 /* one = big endian, zero = little endian */
33 unsigned endian:1;
34
35 /* (external controller only) M66592_PLATDATA_XTAL_nnMHZ */
36 unsigned xtal:2;
37
38 /* (external controller only) one = 3.3V, zero = 1.5V */
39 unsigned vif:1;
40
41};
42
43#endif /* __LINUX_USB_M66592_H */
44