Re: ioremap definition in generic io.h

Arnd Bergmann
2010-09-30T12:05:05Z

On Thursday 30 September 2010, Jonas Bonn wrote:
> On Thu, 2010-09-30 at 13:45 +0200, Arnd Bergmann wrote:
> > On Wednesday 29 September 2010, Jonas Bonn wrote:
> > > On another note, looking at the definitions of ioread32/iowrite32, they
> > > imply a little-endian bus. Some architectures (e.g. Microblaze) define
> > > these to use host-native byte ordering instead. Is there a correct
> > > way these functions should be defined?
> >
> > ioread32/iowrite32 are accessor functions for PCI byte order which is
> > little endian. If microblaze does this differently, that is a microblaze
> > bug. Any code that needs big-endian I/O should use ioread32be/iowrite32be.
> >
>
> So what's the correct way to do host-native access? For example, big
> endian access on a big endian processor. I think I'm missing something
> fundamental here...

The I/O accessors in Linux are written under the assumption that the I/O
device is fixed endian and may be used on both kinds of CPUs.

I assume that microblaze is a special case here because you synthesize
the I/O devices together with the CPU core and choose a common endianess
for both, right?

We have the __raw_readl()/__raw_writel() functions which are defined as
host-endian, but I would not recommend using them in general because they
also mean slightly different things depending on the architecture.

It's probably best to define your own functions for microblaze. Obviously
the drivers are not portable to other architectures anyway because those
might be cross-endian.

It's probably best to name the accessors by the bus that the devices
are attached to, and then define them in a a per-bus header file, like

#ifdef CONFIG_PLB_BIG_ENDIAN
#define plb_ioread32(p) ioread32be(p)
#define plb_iowrite32(p) iowrite32be(p)
#else
#define plb_ioread32(p) ioread32(p)
#define plb_iowrite32(p) iowrite32(p)
#endif

Arnd