> > On 12/05/2013 01:16 PM, Peter Chen wrote: > >> Personally I think you should include the text of the errata > >> in one of the files. > > > Yes, some may be interested in detail, not only the solution, > > will do it next time. > > > >> I'm not suggesting you change the guts of the patch, but... > >> > >> Having read the errata it isn't 100% clear to me that using SWP > >> is necessary for all register accesses. > > > > Only write USB controller register is needed. > > > >> Since SWP is a locked bus cycle it will have performance penalties, > >> depending on the number of write operations this might be measurable. > >> > >> AFAICT the reason that SWP works is that does a read cycle prior > >> to the write that ensures that logic is all in the correct state > >> (I think the read returns garbage). > >> There is no requirement for a locked bus cycle, or for the cycles > >> to be adjacent (from the cpu's point of view). Just that there > >> can be no other cycles on what I assume is a peripheral bus. > >> > >> So if the code can guarantee no other cycles on the same bus (the > >> ones that are documented in the errata to cause problems) then > >> there is no need to use the SWP instruction. > >> Typically this would be single cpu systems doing a series of > >> accesses (the first could be a read) with interrupts hard disabled. > >> > > > > Thanks for your analysis. > > > > As far as I know, the workaround for this problem is it needs a read > > usb controller register operation before every write, the swp > instruction > > may be the easiest way to implement it, so the design team suggests it, > > this patch just implements that workaround. > > > > We can't guarantee there is no other access on the AHB without disable > > interrupt, would you think below operation will be more efficient than > swp, > > or any better solutions? > > > > local_irq_save(flags); > > readl(addr); > > writel(val, addr); > > local_irq_restore(flags); > > Does this work without modifications on PREEMPT_RT? > What's the relationship between PREEMPT_RT and local_irq_save? local_irq_save will save irq registers and disable arm hardware interrupt (I bit is set), in that case, no other threads will be scheduled at single core system. Peter ��.n��������+%������w��{.n�����{���)��jg��������ݢj����G�������j:+v���w�m������w�������h�����٥