Re: [PATCH] USB: m66592-udc: Add support for SH7722 USBF
Yoshihiro Shimoda <[email protected]>
| Newsgroups | gmane.linux.usb.devel |
|---|---|
| Message-ID | <[email protected]> |
David Brownell wrote:
> On Thursday 08 November 2007, you wrote:
>> David Brownell wrote:
>>> ACK ... though see below.
>>>
>>> And I suspect you're missing clock management for the on-chip code,
>>> and assuming that "someone else" turns on the clocks needed by this
>>> particular functional module. Since this all seems quite new, I'd
>>> expect such patches to show up later.
>> Thank you for your comment.
>>
>> I already sent a patch which turned on clock of USBF to SuperH maintainer.
>> http://lkml.org/lkml/2007/11/2/10
>> sh: Enable USBF on MS7722SE.
>
> That's the wrong model, except when powere management is a
> complete non-issue. The probe() and resume() methods will
> normally turn the clock(s) off. The suspend() and remove()
> methods will normally turn them off. If some non-retention
> mode is supported, there are ways to us that too.
>
> Plus, when there's no VBUS current available, that's another
> signal to put the controller into a low power mode ... which
> usually means "clocks off", including whatever goes to the
> high speed PHY.
I understood it. I do not think that power management is
a non-issue. I made a patch which I added clock management.
But my development environment does not support suspend()
and resume(), so suspend() and resume() methods of this
driver did not implement it.
>>> But the Kconfig BUILT_IN_* option is defined only if this
>>> CPU_SUBTYPE is set. I take it the implication is that
>>> other similar chips are on the way, and only this one
>>> requires that workaround?
>> Perhaps this workaround is necessary for only this CPU.
>> But I can not confirm it whether it is really necessary
>> or not, because I do not yet obtain other similar CPU's.
>
> In which case that nested #ifdef should probably vanish.
I see. I removed it.
Thanks,
Yoshihiro Shimoda
---
drivers/usb/gadget/m66592-udc.c | 29 ++++++++++++++++++++++-------
drivers/usb/gadget/m66592-udc.h | 20 ++++++++++++++++++++
2 files changed, 42 insertions(+), 7 deletions(-)
diff -uprN a/drivers/usb/gadget/m66592-udc.c b/drivers/usb/gadget/m66592-udc.c
--- a/drivers/usb/gadget/m66592-udc.c 2007-10-29 13:23:48.000000000 +0900
+++ b/drivers/usb/gadget/m66592-udc.c 2007-11-09 15:53:18.000000000 +0900
@@ -622,19 +622,16 @@ static void start_ep0(struct m66592_ep *
#if defined(CONFIG_SUPERH_BUILT_IN_M66592)
static void init_controller(struct m66592 *m66592)
{
+ usbf_start_clock();
m66592_bset(m66592, M66592_HSE, M66592_SYSCFG); /* High spd */
m66592_bclr(m66592, M66592_USBE, M66592_SYSCFG);
m66592_bclr(m66592, M66592_DPRPU, M66592_SYSCFG);
m66592_bset(m66592, M66592_USBE, M66592_SYSCFG);
-#if defined(CONFIG_CPU_SUBTYPE_SH7722)
- /*
- * This is a workaound for SH7722 2nd cut
- */
+ /* This is a workaound for SH7722 2nd cut */
m66592_bset(m66592, 0x8000, M66592_DVSTCTR);
m66592_bset(m66592, 0x1000, M66592_TESTMODE);
m66592_bclr(m66592, 0x8000, M66592_DVSTCTR);
-#endif
m66592_bset(m66592, M66592_INTL, M66592_INTENB1);
@@ -673,7 +670,9 @@ static void init_controller(struct m6659
static void disable_controller(struct m66592 *m66592)
{
-#if !defined(CONFIG_SUPERH_BUILT_IN_M66592)
+#if defined(CONFIG_SUPERH_BUILT_IN_M66592)
+ usbf_stop_clock();
+#else
m66592_bclr(m66592, M66592_SCKE, M66592_SYSCFG);
udelay(1);
m66592_bclr(m66592, M66592_PLLC, M66592_SYSCFG);
@@ -686,7 +685,9 @@ static void disable_controller(struct m6
static void m66592_start_xclock(struct m66592 *m66592)
{
-#if !defined(CONFIG_SUPERH_BUILT_IN_M66592)
+#if defined(CONFIG_SUPERH_BUILT_IN_M66592)
+ usbf_start_clock();
+#else
u16 tmp;
tmp = m66592_read(m66592, M66592_SYSCFG);
@@ -1180,6 +1181,19 @@ static irqreturn_t m66592_irq(int irq, v
intsts0 = m66592_read(m66592, M66592_INTSTS0);
intenb0 = m66592_read(m66592, M66592_INTENB0);
+#if defined(CONFIG_SUPERH_BUILT_IN_M66592)
+ if (!intsts0 && !intenb0) {
+ /*
+ * When USB clock stops, it cannot read register. Even if a
+ * clock stops, the interrupt occurs. So this driver turn on
+ * a clock by this timing and do re-reading of register.
+ */
+ m66592_start_xclock(m66592);
+ intsts0 = m66592_read(m66592, M66592_INTSTS0);
+ intenb0 = m66592_read(m66592, M66592_INTENB0);
+ }
+#endif
+
savepipe = m66592_read(m66592, M66592_CFIFOSEL);
mask0 = intsts0 & intenb0;
@@ -1523,6 +1537,7 @@ static int __exit m66592_remove(struct p
iounmap(m66592->reg);
free_irq(platform_get_irq(pdev, 0), m66592);
m66592_free_request(&m66592->ep[0].ep, m66592->ep0_req);
+ usbf_stop_clock();
kfree(m66592);
return 0;
}
diff -uprN a/drivers/usb/gadget/m66592-udc.h b/drivers/usb/gadget/m66592-udc.h
--- a/drivers/usb/gadget/m66592-udc.h 2007-10-29 13:23:48.000000000 +0900
+++ b/drivers/usb/gadget/m66592-udc.h 2007-11-09 14:04:17.000000000 +0900
@@ -604,6 +604,26 @@ static inline void m66592_mdfy(struct m6
#define m66592_bset(m66592, val, offset) \
m66592_mdfy(m66592, val, 0, offset)
+#if defined(CONFIG_SUPERH_BUILT_IN_M66592)
+#include <asm/io.h>
+#define MSTPCR2 0xA4150038 /* for SH7722 */
+#define MSTPCR2_USB 0x00000800
+
+static inline void usbf_start_clock(void)
+{
+ ctrl_outl(ctrl_inl(MSTPCR2) & ~MSTPCR2_USB, MSTPCR2);
+}
+
+static inline void usbf_stop_clock(void)
+{
+ ctrl_outl(ctrl_inl(MSTPCR2) | MSTPCR2_USB, MSTPCR2);
+}
+
+#else
+#define usbf_start_clock(x)
+#define usbf_stop_clock(x)
+#endif /* if defined(CONFIG_SUPERH_BUILT_IN_M66592) */
+
#endif /* ifndef __M66592_UDC_H__ */
-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________
[email protected]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel