Re: UIO not working on ppc405 onchip registers

2008-09-04 Thread Markus Brunner
On Tuesday 22 July 2008, Ben Nizette wrote:

> But I'll let you get back to solving the UIO problem at hand :-D

I already surrendered and created (hacked) a read/write driver, which let me 
use the old userspace drivers I'm trying to port (with some changes of 
course). This was way faster than understanding all the involved APIs and 
creating glue code between them. And the amount of time it needs was easy to 
estimate.

However accidently I ran over the "old school" userland mmap code 
with /dev/mem. I already knew mapping with /dev/mem is possible but I haven't 
thought this could make a difference.

http://ozlabs.org/pipermail/linuxppc-embedded/2006-August/023811.html

Also I was wrong with my assumption that uio worked well on the peripherals. 
It worked (very) well on the leds, just to fool me!!! But it returned crap on 
some version registers.

With a working and a non working version of mmap it should be rather easy to 
trace this bug. Unfortunately I was already short of time before running into 
this (and other) problems and it didn't get any better. 
So I would need some help from someone with more experience to fix this. 
Any instructions?

Markus
___
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev


Re: UIO not working on ppc405 onchip registers

2008-07-22 Thread super . firetwister
On Tuesday 22 July 2008, [EMAIL PROTECTED] wrote:
> Hello Uwe,
>
> On Tuesday 22 July 2008, Uwe Kleine-König wrote:
> > I don't know powerpc in general nor ppc405ep in detail but IIRC arm has
> > problems if some memory is mapped twice.  Might this be the problem
> > here?
>
> Maybee, the emac0 (0xef600800) and emac1 (0xef600900) get mapped as well,
> because AFAIK I have to map a whole pagesize (0x1000).

Same problem without emac module loaded.

Did anybody tried to reproduce the problem?

Regards

Markus


___
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev


Re: UIO not working on ppc405 onchip registers

2008-07-22 Thread Ben Nizette

On Tue, 2008-07-22 at 09:48 +0200, [EMAIL PROTECTED]
wrote:
> On Tuesday 22 July 2008, Ben Nizette wrote:
> 
> > As an aside, you sure you want to do this anyway?  
> 
> No ;)
> 
> 
> > I'd suggest that you 
> > just do a gpio chip driver for this, tie it in to gpiolib and use the
> > gpiolib user interface (which IIRC has only made it as far as -mm but is
> > on the way up).  This gives kernel internals nice access to the pins as
> > well through the standard gpio framework.
> 
> This was just an example to make it others easier to reproduce my problem. My 
> goal is to have a soft spi driver in userspace, which would probably be 
> slower if it uses gpiolib. This driver is integrated in the application I 
> want to port to Linux. 

Ah right, cool.  I donno what the speed would be like, but both David
Brownell and Michael Buesch both have spi-over-gpio patches floating
around (eg [1]).  That, plus the spidev interface, might at least be
worth a try..?

But I'll let you get back to solving the UIO problem at hand :-D

--Ben.

[1] http://lwn.net/Articles/290066/


___
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev


Re: UIO not working on ppc405 onchip registers

2008-07-22 Thread Uwe Kleine-König
Hello Markus,

Markus Brunner wrote:
> I'm unable to get UIO working on the ppc405ep onchip registers (e.g. gpio/iic)
> however it's working fine on peripherals.
I don't know powerpc in general nor ppc405ep in detail but IIRC arm has
problems if some memory is mapped twice.  Might this be the problem
here?

> It seems to me to be a problem with UIO on powerpc, because if I change the
> address (and nothing more) to point to a external FPGA it's working fine.
> I also tried the generic uio_pdrv which had the same problems.
> Sometimes I get a "bus error" sometimes it only produces wrong results.
> The "bus error" occurred when not a full 32 bit register was read (e.g. only a
> byte of it), but I'm not sure if it doesn't occur for other reasons as well.
Well, if this is a 32bit memory mapped device and you do a non-32 bit
access strage things can happen.

> 
> diff -upNr linux-2.6.26/drivers/uio-orig/Kconfig 
> linux-2.6.26/drivers/uio/Kconfig
> --- linux-2.6.26/drivers/uio-orig/Kconfig   2008-07-18 09:15:51.0 
> +0200
> +++ linux-2.6.26/drivers/uio/Kconfig2008-07-18 09:16:18.0 +0200
> @@ -39,4 +39,12 @@ config UIO_SMX
> 
>   If you compile this as a module, it will be called uio_smx.
> 
> +config UIO_GPIO
> +   tristate "Driver for PPC_4xx GPIO"
> +   depends on UIO
> +   default n
> +   help
> + Driver for PPC_4xx GPIO Registers
> +
>  endif
This endif matches an "if UIO", so there is no need to depend on UIO
explicitly.

> diff -upNr linux-2.6.26/drivers/uio-orig/Makefile 
> linux-2.6.26/drivers/uio/Makefile
> --- linux-2.6.26/drivers/uio-orig/Makefile  2008-07-18 09:27:18.0 
> +0200
> +++ linux-2.6.26/drivers/uio/Makefile   2008-07-18 09:16:50.0 +0200
> @@ -1,3 +1,4 @@
>  obj-$(CONFIG_UIO)  += uio.o
>  obj-$(CONFIG_UIO_CIF)  += uio_cif.o
>  obj-$(CONFIG_UIO_SMX)  += uio_smx.o
> +obj-$(CONFIG_UIO_GPIO) += uio_ppc_4xx-gpio.o
> diff -upNr linux-2.6.26/drivers/uio-orig/uio-gpio.c 
> linux-2.6.26/drivers/uio/uio-gpio.c
> --- linux-2.6.26/drivers/uio-orig/uio-gpio.c1970-01-01 01:00:00.0 
> +0100
> +++ linux-2.6.26/drivers/uio/uio-gpio.c 2008-07-18 09:18:56.0 +0200
> @@ -0,0 +1,59 @@
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +const unsigned long pin_mask( unsigned int pin) { return (0x8000 >> 
> (pin));}
> +
> +const char UIO_DEV[]  = "/dev/uio0";
> +const unsigned int UIO_SIZE =   0x1000;
> +const unsigned int UIO_ADDR = 0xef600700;
> +
> +const int  or = 0;
> +const int tcr = 1;
> +
> +const unsigned int gpio_pin = 0;/* What gpio pin do you want to 
> toggle? */
> +
> +volatile unsigned long *gpio_regs;
> +
> +int main(int argc, char *argv[])
> +{
> +   int uiofd = open(UIO_DEV,O_RDWR);
For debugging this is OK, in the final application you should add some
tests.  Check the UIO documentation for the details.

> +   if (uiofd < 0)
> +   return uiofd;
> +
> +   unsigned long* map_addr = mmap(NULL,
> +  UIO_SIZE,
> +  PROT_READ | PROT_WRITE,
> +  MAP_SHARED,
> +  uiofd,
> +  0);
> +   if (map_addr == ((unsigned long*) -1))
> +   return -1;
> [...]
> diff -upNr linux-2.6.26/drivers/uio-orig/uio_ppc_4xx-gpio.c 
> linux-2.6.26/drivers/uio/uio_ppc_4xx-gpio.c
> --- linux-2.6.26/drivers/uio-orig/uio_ppc_4xx-gpio.c1970-01-01 
> 01:00:00.0 +0100
> +++ linux-2.6.26/drivers/uio/uio_ppc_4xx-gpio.c 2008-07-18 09:23:32.0 
> +0200
> @@ -0,0 +1,74 @@
> +/*
> + * simple UIO GPIO driver.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include 
> +
> +static struct uio_info info = {
> +   .name = "uio_gpio",
> +   .version = "0.0.0",
> +   .irq = UIO_IRQ_NONE,
> +   .irq_flags = 0,
> +.mem[0].addr = 0xef600700,
> +.mem[0].size = 0x1000,
> +   .mem[0].memtype = UIO_MEM_PHYS,
> +};
IIRC you should initialise the other mem members.

> +static int __devinit uio_gpio_probe(struct device *dev)
> +{
> +   if (uio_register_device(dev, &info)){
> +   printk(KERN_ERR "uio_gpio: uio_register_device failed\n");
> +   return -ENODEV;
> +   }
> +   return 0;
> +}
> +
> +static int uio_gpio_remove(struct device *dev)
> +{
> +   uio_unregister_device(&info);
> +   info.mem[0].addr = 0;
> +   info.mem[0].size = 0;
> +   return 0;
> +}
Are you sure that overwriting info.mem[0].addr is a good idea?  Then
unbinding the platform device and rebinding it fails to do the right
thing for sure.

> +static struct platform_device *u

Re: UIO not working on ppc405 onchip registers

2008-07-22 Thread Ben Nizette

Hey Markus,

> > 
> > +config UIO_GPIO
> > +   tristate "Driver for PPC_4xx GPIO"

As an aside, you sure you want to do this anyway?  I'd suggest that you
just do a gpio chip driver for this, tie it in to gpiolib and use the
gpiolib user interface (which IIRC has only made it as far as -mm but is
on the way up).  This gives kernel internals nice access to the pins as
well through the standard gpio framework.

Thanks :-)
--Ben.


___
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev


Re: UIO not working on ppc405 onchip registers

2008-07-22 Thread super . firetwister
On Tuesday 22 July 2008, Ben Nizette wrote:

> As an aside, you sure you want to do this anyway?  

No ;)


> I'd suggest that you 
> just do a gpio chip driver for this, tie it in to gpiolib and use the
> gpiolib user interface (which IIRC has only made it as far as -mm but is
> on the way up).  This gives kernel internals nice access to the pins as
> well through the standard gpio framework.

This was just an example to make it others easier to reproduce my problem. My 
goal is to have a soft spi driver in userspace, which would probably be 
slower if it uses gpiolib. This driver is integrated in the application I 
want to port to Linux. 

Thanks

Markus
___
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev


Re: UIO not working on ppc405 onchip registers

2008-07-22 Thread super . firetwister
Hello Uwe,

On Tuesday 22 July 2008, Uwe Kleine-König wrote:

> I don't know powerpc in general nor ppc405ep in detail but IIRC arm has
> problems if some memory is mapped twice.  Might this be the problem
> here?

Maybee, the emac0 (0xef600800) and emac1 (0xef600900) get mapped as well, 
because AFAIK I have to map a whole pagesize (0x1000).

> > +   int uiofd = open(UIO_DEV,O_RDWR);
>
> For debugging this is OK, in the final application you should add some
> tests.  Check the UIO documentation for the details.

The whole example was meant to be short.


> > +static int uio_gpio_remove(struct device *dev)
> > +{
> > +   uio_unregister_device(&info);
> > +   info.mem[0].addr = 0;
> > +   info.mem[0].size = 0;
> > +   return 0;
> > +}
>
> Are you sure that overwriting info.mem[0].addr is a good idea?  Then
> unbinding the platform device and rebinding it fails to do the right
> thing for sure.

This was stolen from uio_dummy. So this might become a common error :(


Thanks a lot for your comments, I will try to get an exclusive memory region 
mapped.

Markus
___
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev


UIO not working on ppc405 onchip registers

2008-07-21 Thread Markus Brunner
Hi,

I'm unable to get UIO working on the ppc405ep onchip registers (e.g. gpio/iic) 
however it's working fine on peripherals.
It seems to me to be a problem with UIO on powerpc, because if I change the 
address (and nothing more) to point to a external FPGA it's working fine.
I also tried the generic uio_pdrv which had the same problems.
Sometimes I get a "bus error" sometimes it only produces wrong results. 
The "bus error" occurred when not a full 32 bit register was read (e.g. only a 
byte of it), but I'm not sure if it doesn't occur for other reasons as well.

Here is a simple example against 2.6.26. It should toggle the GPIO pin 0 on 
ppc405ep, but can be changed easily to work on other ppc variants.

Can anyone reproduce this problem, did anyone already succeed in writing a UIO 
driver for the onchip registers? How can I fix this?

Might this be something like commit c9698d6b1a90929e427a165bd8283f803f57d9bd 
which
added pgprot_noncached() to UIO mmap code to get it work on ppc?

Regards

Markus


diff -upNr linux-2.6.26/drivers/uio-orig/Kconfig 
linux-2.6.26/drivers/uio/Kconfig
--- linux-2.6.26/drivers/uio-orig/Kconfig   2008-07-18 09:15:51.0 
+0200
+++ linux-2.6.26/drivers/uio/Kconfig2008-07-18 09:16:18.0 +0200
@@ -39,4 +39,12 @@ config UIO_SMX
 
  If you compile this as a module, it will be called uio_smx.
 
+config UIO_GPIO
+   tristate "Driver for PPC_4xx GPIO"
+   depends on UIO
+   default n
+   help
+ Driver for PPC_4xx GPIO Registers
+
 endif
+
diff -upNr linux-2.6.26/drivers/uio-orig/Makefile 
linux-2.6.26/drivers/uio/Makefile
--- linux-2.6.26/drivers/uio-orig/Makefile  2008-07-18 09:27:18.0 
+0200
+++ linux-2.6.26/drivers/uio/Makefile   2008-07-18 09:16:50.0 +0200
@@ -1,3 +1,4 @@
 obj-$(CONFIG_UIO)  += uio.o
 obj-$(CONFIG_UIO_CIF)  += uio_cif.o
 obj-$(CONFIG_UIO_SMX)  += uio_smx.o
+obj-$(CONFIG_UIO_GPIO) += uio_ppc_4xx-gpio.o
diff -upNr linux-2.6.26/drivers/uio-orig/uio-gpio.c 
linux-2.6.26/drivers/uio/uio-gpio.c
--- linux-2.6.26/drivers/uio-orig/uio-gpio.c1970-01-01 01:00:00.0 
+0100
+++ linux-2.6.26/drivers/uio/uio-gpio.c 2008-07-18 09:18:56.0 +0200
@@ -0,0 +1,59 @@
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+const unsigned long pin_mask( unsigned int pin) { return (0x8000 >> 
(pin));}
+
+const char UIO_DEV[]  = "/dev/uio0";
+const unsigned int UIO_SIZE =   0x1000;
+const unsigned int UIO_ADDR = 0xef600700;
+
+const int  or = 0;
+const int tcr = 1;
+
+const unsigned int gpio_pin = 0;/* What gpio pin do you want to 
toggle? */
+
+volatile unsigned long *gpio_regs;
+
+int main(int argc, char *argv[])
+{
+   int uiofd = open(UIO_DEV,O_RDWR);
+   if (uiofd < 0)
+   return uiofd;
+
+   unsigned long* map_addr = mmap(NULL,
+  UIO_SIZE,
+  PROT_READ | PROT_WRITE,
+  MAP_SHARED,
+  uiofd,
+  0);
+   if (map_addr == ((unsigned long*) -1))
+   return -1;
+gpio_regs = (volatile unsigned long*) map_addr;
+   printf("Mapped %0lx bytes from %08lx to %08lx\n", UIO_SIZE, UIO_ADDR, 
(unsigned long)map_addr);
+
+printf("TCR = %08lx\n", gpio_regs[tcr]);
+printf("TCR = %08lx\n", gpio_regs[tcr]);
+printf("setting TCR\n");
+gpio_regs[tcr] = gpio_regs[tcr] | pin_mask( gpio_pin ); // set tcr 
for pin to 1
+printf("TCR = %08lx\n", gpio_regs[tcr]);
+printf("TCR = %08lx\n", gpio_regs[tcr]);
+
+printf("OR = %08lx\n", gpio_regs[or]);
+printf("OR = %08lx\n", gpio_regs[or]);
+printf("setting OR\n");
+gpio_regs[or] = gpio_regs[or] | pin_mask( gpio_pin );   // set tcr 
for pin to 1
+printf("OR = %08lx\n", gpio_regs[or]);
+printf("OR = %08lx\n", gpio_regs[or]);
+sleep( 3 );
+printf("setting OR\n");
+gpio_regs[or] = gpio_regs[or] & ~pin_mask( gpio_pin );  // set tcr 
for pin to 0
+printf("OR = %08lx\n", gpio_regs[or]);
+printf("OR = %08lx\n", gpio_regs[or]);
+
+}
diff -upNr linux-2.6.26/drivers/uio-orig/uio_ppc_4xx-gpio.c 
linux-2.6.26/drivers/uio/uio_ppc_4xx-gpio.c
--- linux-2.6.26/drivers/uio-orig/uio_ppc_4xx-gpio.c1970-01-01 
01:00:00.0 +0100
+++ linux-2.6.26/drivers/uio/uio_ppc_4xx-gpio.c 2008-07-18 09:23:32.0 
+0200
@@ -0,0 +1,74 @@
+/*
+ * simple UIO GPIO driver.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+static struct uio_info info = {
+   .name = "uio_gpio",
+   .version = "0.0.0",
+   .irq = UIO_IRQ_NONE,
+   .irq_flags = 0,
+