[PATCH 02/10] staging: dwc2: do not handle PRTINT in dwc2_handle_common_intr

2013-04-15 Thread Matthijs Kooijman
For host mode, this interrupt is already handled by the hcd interrupt
handler. The common interrupt handler additionally did a noop handling
(it only cleared the flag and nothing else) when in device mode.

Since the driver currently supports only host mode, this shouldn't
result in any behaviour change in the driver. When device mode is
implemented later on, this interrupt should be properly handled by the
device interupt handler, if needed.

This change allows to make a clean cut between common interrupts and
host interrupts, since there are no longer any interrupts handled by
both.

Signed-off-by: Matthijs Kooijman 
---
 drivers/staging/dwc2/core_intr.c | 19 ++-
 1 file changed, 2 insertions(+), 17 deletions(-)

diff --git a/drivers/staging/dwc2/core_intr.c b/drivers/staging/dwc2/core_intr.c
index 44c0166..73d48a5 100644
--- a/drivers/staging/dwc2/core_intr.c
+++ b/drivers/staging/dwc2/core_intr.c
@@ -403,8 +403,7 @@ static void dwc2_handle_usb_suspend_intr(struct dwc2_hsotg 
*hsotg)
 #define GINTMSK_COMMON (GINTSTS_WKUPINT | GINTSTS_SESSREQINT | \
 GINTSTS_CONIDSTSCHNG | GINTSTS_OTGINT |\
 GINTSTS_MODEMIS | GINTSTS_DISCONNINT | \
-GINTSTS_USBSUSP | GINTSTS_RESTOREDONE |\
-GINTSTS_PRTINT)
+GINTSTS_USBSUSP | GINTSTS_RESTOREDONE)
 
 /*
  * This function returns the Core Interrupt register
@@ -460,7 +459,7 @@ irqreturn_t dwc2_handle_common_intr(int irq, void *dev)
spin_lock(&hsotg->lock);
 
gintsts = dwc2_read_common_intr(hsotg);
-   if (gintsts & ~GINTSTS_PRTINT)
+   if (gintsts)
retval = 1;
 
if (gintsts & GINTSTS_MODEMIS)
@@ -484,20 +483,6 @@ irqreturn_t dwc2_handle_common_intr(int irq, void *dev)
dev_dbg(hsotg->dev, " --Restore done interrupt received--\n");
}
 
-   if (gintsts & GINTSTS_PRTINT) {
-   /*
-* The port interrupt occurs while in device mode with HPRT0
-* Port Enable/Disable
-*/
-   if (dwc2_is_device_mode(hsotg)) {
-   dev_dbg(hsotg->dev,
-   " --Port interrupt received in Device 
mode--\n");
-   gintsts = GINTSTS_PRTINT;
-   writel(gintsts, hsotg->regs + GINTSTS);
-   retval = 1;
-   }
-   }
-
spin_unlock(&hsotg->lock);
 out:
return IRQ_RETVAL(retval);
-- 
1.8.0

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RE: [PATCH 02/10] staging: dwc2: do not handle PRTINT in dwc2_handle_common_intr

2013-04-15 Thread Paul Zimmerman
Resending as plain text.

> From: Matthijs Kooijman [mailto:matth...@stdin.nl]
> Sent: Monday, April 15, 2013 7:14 AM
> 
> For host mode, this interrupt is already handled by the hcd interrupt
> handler. The common interrupt handler additionally did a noop handling
> (it only cleared the flag and nothing else) when in device mode.
> 
> Since the driver currently supports only host mode, this shouldn't
> result in any behaviour change in the driver. When device mode is
> implemented later on, this interrupt should be properly handled by the
> device interupt handler, if needed.
> 
> This change allows to make a clean cut between common interrupts and
> host interrupts, since there are no longer any interrupts handled by
> both.

Hi Matthijs,

I'd rather keep this code as-is. The reason is, even though the driver
is currently host-only, the core that it is operating may not be. In
that case, when the USB cable is unplugged, the core will switch to
device mode. In that case the interrupt handler for host mode will exit
without clearing the interrupt.

So NAK on this patch, unless you have another reason why it is required.

-- 
Paul

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 02/10] staging: dwc2: do not handle PRTINT in dwc2_handle_common_intr

2013-04-16 Thread Matthijs Kooijman
Hi Paul,

On Mon, Apr 15, 2013 at 10:22:12PM +, Paul Zimmerman wrote:
> Resending as plain text.
> 
> > From: Matthijs Kooijman [mailto:matth...@stdin.nl]
> > Sent: Monday, April 15, 2013 7:14 AM
> > 
> > For host mode, this interrupt is already handled by the hcd interrupt
> > handler. The common interrupt handler additionally did a noop handling
> > (it only cleared the flag and nothing else) when in device mode.
> > 
> > Since the driver currently supports only host mode, this shouldn't
> > result in any behaviour change in the driver. When device mode is
> > implemented later on, this interrupt should be properly handled by the
> > device interupt handler, if needed.
> > 
> > This change allows to make a clean cut between common interrupts and
> > host interrupts, since there are no longer any interrupts handled by
> > both.
> 
> Hi Matthijs,
> 
> I'd rather keep this code as-is. The reason is, even though the driver
> is currently host-only, the core that it is operating may not be. In
> that case, when the USB cable is unplugged, the core will switch to
> device mode. In that case the interrupt handler for host mode will exit
> without clearing the interrupt.
Ok, so if I understand this correctly this interrupt is really not a
common interrupt, but it is a host interrupt as well as a device
interrupt? And the code in dwc2_handle_common_intr would be moved to the
device-mode interrupt handler once it gets added? If so, I could replace
this patch with a comment stating that.

However, the fact that an interrupt can be both a host and a device
interrupt, might complicate things. I'll think a bit about this (also
considering your other comments that I haven't answered yet) and see
what this means for the separation I have been trying to achieve :-)

Gr.

Matthijs
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RE: [PATCH 02/10] staging: dwc2: do not handle PRTINT in dwc2_handle_common_intr

2013-04-16 Thread Paul Zimmerman
> From: Matthijs Kooijman [mailto:matth...@stdin.nl]
> Sent: Tuesday, April 16, 2013 9:53 AM
> 
> On Mon, Apr 15, 2013 at 10:22:12PM +, Paul Zimmerman wrote:
> >
> > > From: Matthijs Kooijman [mailto:matth...@stdin.nl]
> > > Sent: Monday, April 15, 2013 7:14 AM
> > >
> > > For host mode, this interrupt is already handled by the hcd interrupt
> > > handler. The common interrupt handler additionally did a noop handling
> > > (it only cleared the flag and nothing else) when in device mode.
> > >
> > > Since the driver currently supports only host mode, this shouldn't
> > > result in any behaviour change in the driver. When device mode is
> > > implemented later on, this interrupt should be properly handled by the
> > > device interupt handler, if needed.
> > >
> > > This change allows to make a clean cut between common interrupts and
> > > host interrupts, since there are no longer any interrupts handled by
> > > both.
> >
> > Hi Matthijs,
> >
> > I'd rather keep this code as-is. The reason is, even though the driver
> > is currently host-only, the core that it is operating may not be. In
> > that case, when the USB cable is unplugged, the core will switch to
> > device mode. In that case the interrupt handler for host mode will exit
> > without clearing the interrupt.
> Ok, so if I understand this correctly this interrupt is really not a
> common interrupt, but it is a host interrupt as well as a device
> interrupt?

No, the interrupt is strictly a host interrupt. But due to the
design of the hardware, there's a race condition: Say the user
unplugs the A connector from the host. The disconnect interrupt gets
triggered, and the driver starts to process it. But unplugging the
A connector also causes the core to switch to device mode, on its
own, without any input from the driver. So by the time the CPU
gets to the point in dwc2_hcd_intr() where it checks to see what
mode the core is in, it could now be in device mode, even though
the interrupt was triggered while in host mode.

So there is an inherent race condition due to the way the hardware
works.

> And the code in dwc2_handle_common_intr would be moved to the
> device-mode interrupt handler once it gets added? If so, I could replace
> this patch with a comment stating that.

No, PRTINT has no meaning in device mode.

> However, the fact that an interrupt can be both a host and a device
> interrupt, might complicate things. I'll think a bit about this (also
> considering your other comments that I haven't answered yet) and see
> what this means for the separation I have been trying to achieve :-)

-- 
Paul

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 02/10] staging: dwc2: do not handle PRTINT in dwc2_handle_common_intr

2013-04-16 Thread Matthijs Kooijman
Hi Paul,

> No, the interrupt is strictly a host interrupt. But due to the
> design of the hardware, there's a race condition: Say the user
> unplugs the A connector from the host. The disconnect interrupt gets
> triggered, and the driver starts to process it. But unplugging the
> A connector also causes the core to switch to device mode, on its
> own, without any input from the driver. So by the time the CPU
> gets to the point in dwc2_hcd_intr() where it checks to see what
> mode the core is in, it could now be in device mode, even though
> the interrupt was triggered while in host mode.
Ah, right. This sounds like its the same as for the DISCONNINT. Perhaps
the handling for PRTINT can be the same as you proposed for DISCONNINT:
handle it in dwc_hcd_intr, but before the check for host mode?

Gr.

Matthijs
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RE: [PATCH 02/10] staging: dwc2: do not handle PRTINT in dwc2_handle_common_intr

2013-04-16 Thread Paul Zimmerman
> From: Matthijs Kooijman [mailto:matth...@stdin.nl]
> Sent: Tuesday, April 16, 2013 12:03 PM
> 
> > No, the interrupt is strictly a host interrupt. But due to the
> > design of the hardware, there's a race condition: Say the user
> > unplugs the A connector from the host. The disconnect interrupt gets
> > triggered, and the driver starts to process it. But unplugging the
> > A connector also causes the core to switch to device mode, on its
> > own, without any input from the driver. So by the time the CPU
> > gets to the point in dwc2_hcd_intr() where it checks to see what
> > mode the core is in, it could now be in device mode, even though
> > the interrupt was triggered while in host mode.
> 
> Ah, right. This sounds like its the same as for the DISCONNINT. Perhaps
> the handling for PRTINT can be the same as you proposed for DISCONNINT:
> handle it in dwc_hcd_intr, but before the check for host mode?

Yes. Actually, it would probably be best to check the core's mode at
the start of the host interrupt handler, and if it's in device mode,
just clear ALL asserted host-only interrupts and return without doing
anything further.

According to the databook, the host-only interrupts are DisconnInt,
PTxFEmp, HChInt, and PrtInt. DisconnInt is cleared via the GINTSTS
register, HChInt is cleared via the HCINTn register, and PrtInt is
cleared via the HPRT register. PTxFEmp can't be cleared without
writing data to the FIFO, so I guess that one should just be disabled
in GINTMSK.

Want to take a crack at that?

-- 
Paul

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 02/10] staging: dwc2: do not handle PRTINT in dwc2_handle_common_intr

2013-04-17 Thread Matthijs Kooijman
Hey Paul,

On Tue, Apr 16, 2013 at 07:39:22PM +, Paul Zimmerman wrote:
> > From: Matthijs Kooijman [mailto:matth...@stdin.nl]
> > Sent: Tuesday, April 16, 2013 12:03 PM
> > 
> > > No, the interrupt is strictly a host interrupt. But due to the
> > > design of the hardware, there's a race condition: Say the user
> > > unplugs the A connector from the host. The disconnect interrupt gets
> > > triggered, and the driver starts to process it. But unplugging the
> > > A connector also causes the core to switch to device mode, on its
> > > own, without any input from the driver. So by the time the CPU
> > > gets to the point in dwc2_hcd_intr() where it checks to see what
> > > mode the core is in, it could now be in device mode, even though
> > > the interrupt was triggered while in host mode.
> > 
> > Ah, right. This sounds like its the same as for the DISCONNINT. Perhaps
> > the handling for PRTINT can be the same as you proposed for DISCONNINT:
> > handle it in dwc_hcd_intr, but before the check for host mode?
> 
> Yes. Actually, it would probably be best to check the core's mode at
> the start of the host interrupt handler, and if it's in device mode,
> just clear ALL asserted host-only interrupts and return without doing
> anything further.
Yeah, that thought crossed my mind at some point as well. However, the
handler for DISCONNINT doesn't just clear the interrupt, it also does:

/* Change to L3 (OFF) state */
hsotg->lx_state = DWC2_L3;

Is this one no longer relevant when the hardware switched to device
mode, or should the above be moved into the host interrupt handler as
well?

> According to the databook, the host-only interrupts are DisconnInt,
> PTxFEmp, HChInt, and PrtInt.
In the current code / my patches I also have SOF, NPTxFEmp and RxFLvl
marked (and handled) as a host interrupt, but I suspect that these three
are used for device mode as well? However, since we don't have
device handlers for them already, shouldn't they be cleared by
dwc2_hcd_intr() as well if it detects device mode?

I suspect not clearing them might currently be a race condition, but
it's just not so likely that one of the fifo's is empty at the same
moment a cable is unplugged. The SOF interrupt is more likely, but that
is cleared directly in the GINTSTS_CONIDSTSCHNG handler (at first glance
there still seems to be a race condition here, but assuming that
GINTSTS_CONIDSTSCHNG is triggered before switching to device mode, SOF
will eventually be masked out).

Perhaps it makes sense to actually disable host (and later device)
interrupts from GINTSTS_CONIDSTSCHNG? The interrupts for host mode are
actually enabled in response to this interrupt already
(dwc2_handle_conn_id_status_change_intr -> dwc2_conn_id_status_change ->
dwc2_hcd_start -> dwc2_hcd_start_func -> dwc2_host_start ->
_dwc2_hcd_start -> dwc2_hcd_reinit -> dwc2_core_host_init ->
dwc2_enable_host_interrupts).

If we go this route, my concerns for interrupts that are used in both
device and host mode are also lifted: These "shared" interrupts can then
disabled in disable_(host|device)_interrupts, since we can be sure that
one is called before the matching enable_(device|host)_interrupts.
Having all interrupts disabled while the core and kernel is switching
seems like a good idea to me as well.

> DisconnInt is cleared via the GINTSTS register, HChInt is cleared via
> the HCINTn register, and PrtInt is cleared via the HPRT register.
> PTxFEmp can't be cleared without writing data to the FIFO, so I guess
> that one should just be disabled in GINTMSK.
Before writing the above, I wrote: if we need to mess with GINTMSK for
PTXFEMP, wouldn't it make sense to just disable all (host-only)
interrupts when a host-only interrupt is detected when the core is in
device mode (instead of clearing all the interrupts)? But it seems to me
that doing this in GINTSTS_CONIDSTSCHNG is a better idea if we want to
do it like this.

Gr.

Matthijs
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RE: [PATCH 02/10] staging: dwc2: do not handle PRTINT in dwc2_handle_common_intr

2013-04-17 Thread Paul Zimmerman
> From: Matthijs Kooijman [mailto:matth...@stdin.nl]
> Sent: Wednesday, April 17, 2013 10:06 AM
> 
> On Tue, Apr 16, 2013 at 07:39:22PM +, Paul Zimmerman wrote:
> >
> > Yes. Actually, it would probably be best to check the core's mode at
> > the start of the host interrupt handler, and if it's in device mode,
> > just clear ALL asserted host-only interrupts and return without doing
> > anything further.
> Yeah, that thought crossed my mind at some point as well. However, the
> handler for DISCONNINT doesn't just clear the interrupt, it also does:
> 
> /* Change to L3 (OFF) state */
>   hsotg->lx_state = DWC2_L3;
> 
> Is this one no longer relevant when the hardware switched to device
> mode, or should the above be moved into the host interrupt handler as
> well?

Ah yes, good point.

I guess code like this which changes the driver state should still
be executed. What should _not_ be executed is any code that touches
host-mode registers, because the host-mode registers disappear once
the core has switched itself to device mode.

> > According to the databook, the host-only interrupts are DisconnInt,
> > PTxFEmp, HChInt, and PrtInt.
> In the current code / my patches I also have SOF, NPTxFEmp and RxFLvl
> marked (and handled) as a host interrupt, but I suspect that these three
> are used for device mode as well? However, since we don't have
> device handlers for them already, shouldn't they be cleared by
> dwc2_hcd_intr() as well if it detects device mode?

Yes, these are relevant in both modes.

I wonder if it would make sense to have a stub device-mode interrupt
handler for now, which would be responsible for clearing these. Once
device mode is implemented, it would be replaced with a real device-
mode interrupt handler.

> I suspect not clearing them might currently be a race condition, but
> it's just not so likely that one of the fifo's is empty at the same
> moment a cable is unplugged. The SOF interrupt is more likely, but that
> is cleared directly in the GINTSTS_CONIDSTSCHNG handler (at first glance
> there still seems to be a race condition here, but assuming that
> GINTSTS_CONIDSTSCHNG is triggered before switching to device mode, SOF
> will eventually be masked out).
> 
> Perhaps it makes sense to actually disable host (and later device)
> interrupts from GINTSTS_CONIDSTSCHNG? The interrupts for host mode are
> actually enabled in response to this interrupt already
> (dwc2_handle_conn_id_status_change_intr -> dwc2_conn_id_status_change ->
> dwc2_hcd_start -> dwc2_hcd_start_func -> dwc2_host_start ->
> _dwc2_hcd_start -> dwc2_hcd_reinit -> dwc2_core_host_init ->
> dwc2_enable_host_interrupts).
> 
> If we go this route, my concerns for interrupts that are used in both
> device and host mode are also lifted: These "shared" interrupts can then
> disabled in disable_(host|device)_interrupts, since we can be sure that
> one is called before the matching enable_(device|host)_interrupts.
> Having all interrupts disabled while the core and kernel is switching
> seems like a good idea to me as well.

It turns out that dwc2_handle_conn_id_status_change_intr() already
disables all interrupts. It calls dwc2_core_init(), which calls
dwc2_core_reset(), which does a soft reset of the core. According
to the databook, that resets most of the core's state, and clears
most of the registers, including GINTMSK.

So should not be necessary to explicitly disable interrupts.

-- 
Paul

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RE: [PATCH 02/10] staging: dwc2: do not handle PRTINT in dwc2_handle_common_intr

2013-04-17 Thread Paul Zimmerman
> From: Matthijs Kooijman [mailto:matth...@stdin.nl]
> Sent: Wednesday, April 17, 2013 10:06 AM
> 
> On Tue, Apr 16, 2013 at 07:39:22PM +, Paul Zimmerman wrote:

...

>> DisconnInt is cleared via the GINTSTS register, HChInt is cleared via
>> the HCINTn register, and PrtInt is cleared via the HPRT register.
>> PTxFEmp can't be cleared without writing data to the FIFO, so I guess
>> that one should just be disabled in GINTMSK.

By the way, when I wrote this, I was thinking that the host interrupts
should be cleared and then disabled. But, as I mentioned in another
email, the host-mode registers actually disappear when the core
switches to device mode. So it is impossible to clear HChInt or PrtInt.
Only DisconnInt can be cleared, the rest should just be disabled in
GINTMSK.

-- 
Paul

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 02/10] staging: dwc2: do not handle PRTINT in dwc2_handle_common_intr

2013-04-25 Thread Matthijs Kooijman
Hey Paul,

> > In the current code / my patches I also have SOF, NPTxFEmp and RxFLvl
> > marked (and handled) as a host interrupt, but I suspect that these three
> > are used for device mode as well? However, since we don't have
> > device handlers for them already, shouldn't they be cleared by
> > dwc2_hcd_intr() as well if it detects device mode?
> 
> Yes, these are relevant in both modes.
> 
> I wonder if it would make sense to have a stub device-mode interrupt
> handler for now, which would be responsible for clearing these. Once
> device mode is implemented, it would be replaced with a real device-
> mode interrupt handler.
If we make sure that these interrupts are only enabled when the device
is in host-mode, then this shouldn't be needed, right? (As long as we
don't have code for device-mode, no interrupts will be enabled for
device mode either.

> > Perhaps it makes sense to actually disable host (and later device)
> > interrupts from GINTSTS_CONIDSTSCHNG? The interrupts for host mode are
> > actually enabled in response to this interrupt already
> > (dwc2_handle_conn_id_status_change_intr -> dwc2_conn_id_status_change ->
> > dwc2_hcd_start -> dwc2_hcd_start_func -> dwc2_host_start ->
> > _dwc2_hcd_start -> dwc2_hcd_reinit -> dwc2_core_host_init ->
> > dwc2_enable_host_interrupts).
> 
> It turns out that dwc2_handle_conn_id_status_change_intr() already
> disables all interrupts. It calls dwc2_core_init(), which calls
> dwc2_core_reset(), which does a soft reset of the core. According
> to the databook, that resets most of the core's state, and clears
> most of the registers, including GINTMSK.

This is true, but the step from dwc2_handle_conn_id_status_change_intr
to dwc2_conn_id_status_change (which then calls dwc2_core_init) happens
through a work queue, not as a direct call. I think this is the reason
there is the reason DISCONN needs to be handled by the common handler
right now, or outside of the "is in host mode" check in the hcd handler
as we discussed before. If the DISCONN interrupt was handled in the hcd
handler, and only if the device is in host mode, the following can
happen:
 - The CONIDSTSCHNG interrupt fires, the hardware starts changing to
   device mode.
 - The DISCONN interrupt fires, potentially at the same time or later as
   the CONIDSTSCHNG interrupt.
 - By the time the host irq handler is run, the hardware is in device
   mode, so the hcd irq handler doesn't do anything (in particular, the
   DISCONN interrupt is not cleared).
 - In the time between the interrupt and the scheduling of the queued
   work, the DISCONN interrupt triggers again, and keeps triggering
   until the queued work is finally scheduled and resets the core.

I would propose to clear the host (and later device) interrupts directly
in the dwc2_handle_conn_id_status_change_intr function, so the following
happens:
 - The CONIDSTSCHNG interrupt fires, the hardware starts changing to
   device mode.
 - dwc2_handle_conn_id_status_change_intr disables all host interrupts,
   so they don't get handled anymore and don't get triggered.

This should remove the race condition, while allowing the DISCONN
interrupt to be handled by the host interrupt handler where it would
make the most sense.

Furthermore, I think this will also close another race condition: If the
hardware switches to device mode after the host interupt handler checks
for host mode, but before the end of the handler, it could potentially
access non-existent registers. With this change, the host mode interrupt
handler (effectively) becomes a noop (since it only handles enabled
interrupts) as soon as the hardware starts changing to device mode,
closeing this gap.

Possibly some similar analysis needs to be applied to other places where
the hardware or driver can initiate device <-> host mode switches, but
perhaps this is only here as long as device mode and the otg protocols
are not implemented?

Gr.

Matthijs
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RE: [PATCH 02/10] staging: dwc2: do not handle PRTINT in dwc2_handle_common_intr

2013-04-25 Thread Paul Zimmerman
> From: Matthijs Kooijman [mailto:matth...@stdin.nl]
> Sent: Thursday, April 25, 2013 2:22 AM
> 
> Hey Paul,

Hi Matthijs,

What say we just defer this change for now? Once we go to add the
device-mode handling, we will probably find out that further changes
will be required anyway.

For example, handling everything in the GINTSTS_CONIDSTSCHNG handler
probably won't work when OTG is enabled, because then you can get
host <-> device switching without the cable being unplugged.

-- 
Paul

> > > In the current code / my patches I also have SOF, NPTxFEmp and RxFLvl
> > > marked (and handled) as a host interrupt, but I suspect that these three
> > > are used for device mode as well? However, since we don't have
> > > device handlers for them already, shouldn't they be cleared by
> > > dwc2_hcd_intr() as well if it detects device mode?
> >
> > Yes, these are relevant in both modes.
> >
> > I wonder if it would make sense to have a stub device-mode interrupt
> > handler for now, which would be responsible for clearing these. Once
> > device mode is implemented, it would be replaced with a real device-
> > mode interrupt handler.
> If we make sure that these interrupts are only enabled when the device
> is in host-mode, then this shouldn't be needed, right? (As long as we
> don't have code for device-mode, no interrupts will be enabled for
> device mode either.
> 
> > > Perhaps it makes sense to actually disable host (and later device)
> > > interrupts from GINTSTS_CONIDSTSCHNG? The interrupts for host mode are
> > > actually enabled in response to this interrupt already
> > > (dwc2_handle_conn_id_status_change_intr -> dwc2_conn_id_status_change ->
> > > dwc2_hcd_start -> dwc2_hcd_start_func -> dwc2_host_start ->
> > > _dwc2_hcd_start -> dwc2_hcd_reinit -> dwc2_core_host_init ->
> > > dwc2_enable_host_interrupts).
> >
> > It turns out that dwc2_handle_conn_id_status_change_intr() already
> > disables all interrupts. It calls dwc2_core_init(), which calls
> > dwc2_core_reset(), which does a soft reset of the core. According
> > to the databook, that resets most of the core's state, and clears
> > most of the registers, including GINTMSK.
> 
> This is true, but the step from dwc2_handle_conn_id_status_change_intr
> to dwc2_conn_id_status_change (which then calls dwc2_core_init) happens
> through a work queue, not as a direct call. I think this is the reason
> there is the reason DISCONN needs to be handled by the common handler
> right now, or outside of the "is in host mode" check in the hcd handler
> as we discussed before. If the DISCONN interrupt was handled in the hcd
> handler, and only if the device is in host mode, the following can
> happen:
>  - The CONIDSTSCHNG interrupt fires, the hardware starts changing to
>device mode.
>  - The DISCONN interrupt fires, potentially at the same time or later as
>the CONIDSTSCHNG interrupt.
>  - By the time the host irq handler is run, the hardware is in device
>mode, so the hcd irq handler doesn't do anything (in particular, the
>DISCONN interrupt is not cleared).
>  - In the time between the interrupt and the scheduling of the queued
>work, the DISCONN interrupt triggers again, and keeps triggering
>until the queued work is finally scheduled and resets the core.
> 
> I would propose to clear the host (and later device) interrupts directly
> in the dwc2_handle_conn_id_status_change_intr function, so the following
> happens:
>  - The CONIDSTSCHNG interrupt fires, the hardware starts changing to
>device mode.
>  - dwc2_handle_conn_id_status_change_intr disables all host interrupts,
>so they don't get handled anymore and don't get triggered.
> 
> This should remove the race condition, while allowing the DISCONN
> interrupt to be handled by the host interrupt handler where it would
> make the most sense.
> 
> Furthermore, I think this will also close another race condition: If the
> hardware switches to device mode after the host interupt handler checks
> for host mode, but before the end of the handler, it could potentially
> access non-existent registers. With this change, the host mode interrupt
> handler (effectively) becomes a noop (since it only handles enabled
> interrupts) as soon as the hardware starts changing to device mode,
> closeing this gap.
> 
> Possibly some similar analysis needs to be applied to other places where
> the hardware or driver can initiate device <-> host mode switches, but
> perhaps this is only here as long as device mode and the otg protocols
> are not implemented?
> 
> Gr.
> 
> Matthijs
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 02/10] staging: dwc2: do not handle PRTINT in dwc2_handle_common_intr

2013-04-25 Thread Matthijs Kooijman
Hey Paul,

> What say we just defer this change for now? Once we go to add the
> device-mode handling, we will probably find out that further changes
> will be required anyway.
Possibly, yeah.

In any case, I'm about to send a new patch series which has the easy
fixes up front and then tries to make things a bit better separated
with less invasive changes. Just see if you think any of those are ok,
if not we'll drop them for now and I'll continue with the next batch of
cleanup patches I have :-)

Gr.

Matthijs
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html