Mailing List Archive

[PATCH 00/03][RFC] Reusable UIO Platform Driver
These patches implement a reusable UIO platform driver. This driver
can be used to export hardware to user space, as long as the device
is a) memory mapped and b) equipped with an unique IRQ.

The uio_platform driver gets all information through platform data,
including address window information and IRQ number. The driver also
supports assigning a contiguous piece of memory to each instance.
This may be useful when the exported hardware blocks can bus master
but requires physically contiguous memory.

There are not many surprises in the code if you are familiar with UIO,
except for the interrupt handling. All UIO kernel drivers that I've
seen so far have hardware specific interrupt acknowledge code in the
interrupt handler. The uio_platform driver is different.

The interrupt handling code in uio_platform assumes the device is the
only user of the assigned interrupt. This may be rare in the PC world
but for SuperH almost all interrupt sources are unique. Having an
unique interrupt for the device allows the code to use disable_irq()
and enable_irq() in kernel space and leave actual interrupt acknowledge
to user space. That way we have no hardware specific code in the kernel.

Interrupts are of course serviced in kernel space by the uio_platform
driver, but the uio_platform interrupt handler will simply disable the
IRQ until next read() or poll() syscall. The uio_platform kernel driver
assumes that the user space driver has taken care of acknowledging
the interrupt before doing read() and waiting for events again. If no
acknowledge has happened then an interrupt will occur again (since it's
still pending) and the kernel interrupt handler will disable the IRQ
again and unblock the user space process.

The last patch contains SuperH specific code that exports various
multimedia acceleration blocks to userspace. The following processors
and hardware blocks are exported for now:

sh7343: VPU
sh7722: VPU, VEU
sh7723: VPU, VEU, VEU

If anyone is interested then I have a proof of concept vidix driver
for mplayer that is interfacing using UIO to the VEU on a sh7722 to
provide accelerated color space conversion and stretching.

[PATCH 01/03] uio: Add enable_irq() callback
[PATCH 02/03] uio: Add uio_platform driver
[PATCH 03/03] sh: Export sh7343/sh7722/sh7723 VPU/VEU blocks

Signed-off-by: Magnus Damm <damm@igel.co.jp>
---

arch/sh/kernel/cpu/sh4a/setup-sh7343.c | 32 ++++++
arch/sh/kernel/cpu/sh4a/setup-sh7722.c | 63 ++++++++++++
arch/sh/kernel/cpu/sh4a/setup-sh7723.c | 94 ++++++++++++++++++
drivers/uio/Kconfig | 10 +
drivers/uio/Makefile | 1
drivers/uio/uio.c | 6 +
drivers/uio/uio_platform.c | 161 ++++++++++++++++++++++++++++++++
include/linux/uio_driver.h | 1
include/linux/uio_platform.h | 10 +
9 files changed, 378 insertions(+)
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 00/03][RFC] Reusable UIO Platform Driver [ In reply to ]
On Tue, May 20, 2008 at 07:51:32PM +0900, Magnus Damm wrote:

Hi Magnus,

> These patches implement a reusable UIO platform driver.

Uwe Kleine-Koenig already submitted such a framework:

http://lkml.org/lkml/2008/5/20/94

It's his third version, and it looks good. I presume you didn't know
about his work. The main difference is that he leaves interrupt handling
to platform code. That might look strange (it did to me first), but it
has the advantage that you can put hardware dependent stuff in your
board support (which depends on hardware anyway).

Could you have a look at his patch and tell me if that does what you
need?

> This driver
> can be used to export hardware to user space, as long as the device
> is a) memory mapped and b) equipped with an unique IRQ.
>
> The uio_platform driver gets all information through platform data,
> including address window information and IRQ number. The driver also
> supports assigning a contiguous piece of memory to each instance.
> This may be useful when the exported hardware blocks can bus master
> but requires physically contiguous memory.
>
> There are not many surprises in the code if you are familiar with UIO,
> except for the interrupt handling. All UIO kernel drivers that I've
> seen so far have hardware specific interrupt acknowledge code in the
> interrupt handler. The uio_platform driver is different.
>
> The interrupt handling code in uio_platform assumes the device is the
> only user of the assigned interrupt.

Uwe's approach doesn't have this limitation.

> This may be rare in the PC world
> but for SuperH almost all interrupt sources are unique. Having an
> unique interrupt for the device allows the code to use disable_irq()
> and enable_irq() in kernel space and leave actual interrupt acknowledge
> to user space. That way we have no hardware specific code in the kernel.
>
> Interrupts are of course serviced in kernel space by the uio_platform
> driver, but the uio_platform interrupt handler will simply disable the
> IRQ until next read() or poll() syscall. The uio_platform kernel driver
> assumes that the user space driver has taken care of acknowledging
> the interrupt before doing read() and waiting for events again. If no
> acknowledge has happened then an interrupt will occur again (since it's
> still pending) and the kernel interrupt handler will disable the IRQ
> again and unblock the user space process.
>
> The last patch contains SuperH specific code that exports various
> multimedia acceleration blocks to userspace. The following processors
> and hardware blocks are exported for now:
>
> sh7343: VPU
> sh7722: VPU, VEU
> sh7723: VPU, VEU, VEU
>
> If anyone is interested then I have a proof of concept vidix driver
> for mplayer that is interfacing using UIO to the VEU on a sh7722 to
> provide accelerated color space conversion and stretching.

This sounds quite interesting. Unfortunately, I'm not familiar with the
SuperH architecture. Could you also do this with Uwe's approach?

I'm about to sign-off Uwe's patch, and we'll possibly have that in
mainline soon. I don't mind having a second "generic platform" driver,
but you'll need to have good technical arguments.

Thanks,
Hans

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 00/03][RFC] Reusable UIO Platform Driver [ In reply to ]
Hi Hans!

On Wed, May 21, 2008 at 6:07 AM, Hans J. Koch <hjk@linutronix.de> wrote:
> On Tue, May 20, 2008 at 07:51:32PM +0900, Magnus Damm wrote:
>> These patches implement a reusable UIO platform driver.
>
> Uwe Kleine-Koenig already submitted such a framework:
>
> http://lkml.org/lkml/2008/5/20/94
>
> It's his third version, and it looks good. I presume you didn't know
> about his work. The main difference is that he leaves interrupt handling
> to platform code. That might look strange (it did to me first), but it
> has the advantage that you can put hardware dependent stuff in your
> board support (which depends on hardware anyway).

I was not aware of this driver, thanks for the pointer!

> Could you have a look at his patch and tell me if that does what you
> need?

The uio_pdrv driver doesn't do what I need at this point, though I may
be able to extend it with the following:
- Interrupt enable/disable code
- Physically contiguous memory support

The interrupt code may be placed in the board/cpu code, but I need to
share that code between multiple UIO driver instances. We want to use
the same UIO driver for many different processor models and hardware
blocks. Extending uio_pdrv driver with a chunk of physically
contiguous memory isn't a big deal though.

To be frank, I have my doubts in adding an extra forwarding-only
platform layer on top of UIO compared to using uio_register_device()
directly from the board code. I like that the platform layer is using
struct resource and handles resource ranges for us automatically, but
wouldn't it make more sense to extend the UIO core to always use
struct resource instead of struct uio_mem? I'd be happy to help out -
just point me in the right direction.

>> The interrupt handling code in uio_platform assumes the device is the
>> only user of the assigned interrupt.
>
> Uwe's approach doesn't have this limitation.

True, but the uio_pdrv driver is choosing to not deal with interrupts
at all. I'd like to have shared interrupt handling code. With my
driver, you just feed it io memory window parameters and an interrupt
number and off you go. No need for any callbacks.

>> If anyone is interested then I have a proof of concept vidix driver
>> for mplayer that is interfacing using UIO to the VEU on a sh7722 to
>> provide accelerated color space conversion and stretching.
>
> This sounds quite interesting. Unfortunately, I'm not familiar with the
> SuperH architecture. Could you also do this with Uwe's approach?

I could handle things by extending Uwe's uio_pdrv driver, but I still
need the enable_irq() callback. I wonder if it makes sense to let the
two drivers coexist side by side, since they are solving different
problems. I can rename my driver to uio_pdrv_unique_irq or something,
or maybe uio_superh.c. I dislike the latter since my driver doesn't do
anything SuperH specific and that I suspect it can be useful for other
architectures as well.

> I'm about to sign-off Uwe's patch, and we'll possibly have that in
> mainline soon. I don't mind having a second "generic platform" driver,
> but you'll need to have good technical arguments.

I'd like to have this driver upstream as well, and sharing the code
with the uio_pdrv driver is one way, but I suspect that adding another
reusable layer on top of that driver will just complicate things. The
uio-specific part of my patches is less than 200 lines of code. From
the top of my head I can think of at least 10 different SuperH
hardware devices that can reuse this driver.

Please let me know what you prefer and I'll update the code and repost.

Thanks for your help!

/ magnus
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 00/03][RFC] Reusable UIO Platform Driver [ In reply to ]
Hello Magnus,

Magnus Damm wrote:
> Hi Hans!
>
> On Wed, May 21, 2008 at 6:07 AM, Hans J. Koch <hjk@linutronix.de> wrote:
> > On Tue, May 20, 2008 at 07:51:32PM +0900, Magnus Damm wrote:
> >> These patches implement a reusable UIO platform driver.
> >
> > Uwe Kleine-Koenig already submitted such a framework:
> >
> > http://lkml.org/lkml/2008/5/20/94
> >
> > It's his third version, and it looks good. I presume you didn't know
> > about his work. The main difference is that he leaves interrupt handling
> > to platform code. That might look strange (it did to me first), but it
> > has the advantage that you can put hardware dependent stuff in your
> > board support (which depends on hardware anyway).
>
> I was not aware of this driver, thanks for the pointer!
>
> > Could you have a look at his patch and tell me if that does what you
> > need?
>
> The uio_pdrv driver doesn't do what I need at this point, though I may
> be able to extend it with the following:
> - Interrupt enable/disable code
> - Physically contiguous memory support
>
> The interrupt code may be placed in the board/cpu code, but I need to
> share that code between multiple UIO driver instances. We want to use
> the same UIO driver for many different processor models and hardware
> blocks.
What about adding uio_platform_handler (with a different name) to
uio_pdrv.c?
OTOH I don't see why you want to disable the irq. Can you describe the
reason?

> Extending uio_pdrv driver with a chunk of physically
> contiguous memory isn't a big deal though.
I wonder how you use that memory. Isn't it just some kind of shared
memory? If so, why not use normal shared memory? Do you really need
that?

> To be frank, I have my doubts in adding an extra forwarding-only
> platform layer on top of UIO compared to using uio_register_device()
> directly from the board code. I like that the platform layer is using
> struct resource and handles resource ranges for us automatically, but
> wouldn't it make more sense to extend the UIO core to always use
> struct resource instead of struct uio_mem? I'd be happy to help out -
> just point me in the right direction.
That alone doesn't help. You need a struct device to register a uio
device. So a platform device is the straight forward approach.

> >> The interrupt handling code in uio_platform assumes the device is the
> >> only user of the assigned interrupt.
> >
> > Uwe's approach doesn't have this limitation.
>
> True, but the uio_pdrv driver is choosing to not deal with interrupts
> at all. I'd like to have shared interrupt handling code. With my
> driver, you just feed it io memory window parameters and an interrupt
> number and off you go. No need for any callbacks.
In my eyes this isn't completly correct. Just the way you specify your
handler is a bit different. You can pass a handler via platform data
with my driver, too.

BTW, you don't need "depends on UIO" (because it's in a if UIO/endif
block) and "default n" (as this is the default anyhow). See also
http://thread.gmane.org/gmane.linux.kernel/663884/focus=683097

Best regards
Uwe

--
Uwe Kleine-König, Software Engineer
Digi International GmbH Branch Breisach, Küferstrasse 8, 79206 Breisach, Germany
Tax: 315/5781/0242 / VAT: DE153662976 / Reg. Amtsgericht Dortmund HRB 13962
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 00/03][RFC] Reusable UIO Platform Driver [ In reply to ]
On Wed, May 21, 2008 at 08:49:38AM +0200, Uwe Kleine-K?nig wrote:
> Magnus Damm wrote:
> > Extending uio_pdrv driver with a chunk of physically
> > contiguous memory isn't a big deal though.
> I wonder how you use that memory. Isn't it just some kind of shared
> memory? If so, why not use normal shared memory? Do you really need
> that?
>
Physically contiguous memory is a real requirement, especially for DMA.
I'm not sure what's confusing about that?
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 00/03][RFC] Reusable UIO Platform Driver [ In reply to ]
Paul Mundt wrote:
> On Wed, May 21, 2008 at 08:49:38AM +0200, Uwe Kleine-K?nig wrote:
> > Magnus Damm wrote:
> > > Extending uio_pdrv driver with a chunk of physically
> > > contiguous memory isn't a big deal though.
> > I wonder how you use that memory. Isn't it just some kind of shared
> > memory? If so, why not use normal shared memory? Do you really need
> > that?
> >
> Physically contiguous memory is a real requirement, especially for DMA.
> I'm not sure what's confusing about that?
I got that, yes. The problem is I don't see how you can use it for DMA.
The physical address is stored in info->mem[$last].internal_addr and if
there is a way to access that variable from user space, I don't see it
and would appretiate a hint. Sorry for not expressing my concern more
clear at the first go. I hope it's understandable now.

@Magnus: Maybe you can provide the userspace part of the driver?
How is that mapping used there?

Best regards
Uwe

--
Uwe Kleine-König, Software Engineer
Digi International GmbH Branch Breisach, Küferstrasse 8, 79206 Breisach, Germany
Tax: 315/5781/0242 / VAT: DE153662976 / Reg. Amtsgericht Dortmund HRB 13962
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 00/03][RFC] Reusable UIO Platform Driver [ In reply to ]
Hi Uwe!

Thanks for your email.

On Wed, May 21, 2008 at 3:49 PM, Uwe Kleine-König
<Uwe.Kleine-Koenig@digi.com> wrote:
> Magnus Damm wrote:
>> The uio_pdrv driver doesn't do what I need at this point, though I may
>> be able to extend it with the following:
>> - Interrupt enable/disable code
>> - Physically contiguous memory support
>>
>> The interrupt code may be placed in the board/cpu code, but I need to
>> share that code between multiple UIO driver instances. We want to use
>> the same UIO driver for many different processor models and hardware
>> blocks.
> What about adding uio_platform_handler (with a different name) to
> uio_pdrv.c?

I'm not sure if it will help. What would such function do? Please explain.

> OTOH I don't see why you want to disable the irq. Can you describe the
> reason?

Most UIO kernel drivers today contain hardware device specific code to
acknowledge interrupts. In other words, most UIO interrupt handlers
touches some device specific bits so the interrupt gets deasserted.

My uio_platform driver handles interrupts in a different way. The
kernel UIO driver is not aware of the hardware device specific method
to acknowledge the interrupt, instead it simply disables the interrupt
and notifies user space which instead will acknowledge the interrupt.
Next time a read() or poll() call gets made, the interrupt is enabled
again.

This allows us to export a hardware device to user space and allow
user space to handle interrupts without knowing in kernel space how to
acknowledge interrupts.

>> Extending uio_pdrv driver with a chunk of physically
>> contiguous memory isn't a big deal though.
> I wonder how you use that memory. Isn't it just some kind of shared
> memory? If so, why not use normal shared memory? Do you really need
> that?

Yes, I need that to give the exported hardware device some physically
contiguous memory for DMA. At this point our hardware is missing IOMMU
so physically contiguous memory is needed.

>> To be frank, I have my doubts in adding an extra forwarding-only
>> platform layer on top of UIO compared to using uio_register_device()
>> directly from the board code. I like that the platform layer is using
>> struct resource and handles resource ranges for us automatically, but
>> wouldn't it make more sense to extend the UIO core to always use
>> struct resource instead of struct uio_mem? I'd be happy to help out -
>> just point me in the right direction.
> That alone doesn't help. You need a struct device to register a uio
> device. So a platform device is the straight forward approach.

I don't mind that you are using platform devices. Actually, I think
platform devices are great. We use them for all sorts of things on the
SuperH architecture. I'm trying to suggest that maybe it's a good idea
to change the UIO core code to use struct resource instead of struct
uio_mem. Or maybe that's not a good idea, I'm not sure.

>> >> The interrupt handling code in uio_platform assumes the device is the
>> >> only user of the assigned interrupt.
>> >
>> > Uwe's approach doesn't have this limitation.
>>
>> True, but the uio_pdrv driver is choosing to not deal with interrupts
>> at all. I'd like to have shared interrupt handling code. With my
>> driver, you just feed it io memory window parameters and an interrupt
>> number and off you go. No need for any callbacks.
> In my eyes this isn't completly correct. Just the way you specify your
> handler is a bit different. You can pass a handler via platform data
> with my driver, too.

I don't want to pass any handler. All devices share the same interrupt
handler, the only thing that differs between multiple uio_platform
devices on one system is memory window information and irq number.

> BTW, you don't need "depends on UIO" (because it's in a if UIO/endif
> block) and "default n" (as this is the default anyhow). See also
> http://thread.gmane.org/gmane.linux.kernel/663884/focus=683097

Ah, thanks for pointing that out!

Thank you for your feedback!

/ magnus
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 00/03][RFC] Reusable UIO Platform Driver [ In reply to ]
On Wed, May 21, 2008 at 5:05 PM, Uwe Kleine-König
<Uwe.Kleine-Koenig@digi.com> wrote:
> @Magnus: Maybe you can provide the userspace part of the driver?
> How is that mapping used there?

[Added Matsubara-san as CC]

Sure, here is a little test program. Have a look at "uio_mem". The
"address" member contains the physical address that can be used for
bus mastering DMA. Compare that to "iomem" which is the pointer to the
virtual memory area in user space.

Hope this helps!

/ magnus
Re: [PATCH 00/03][RFC] Reusable UIO Platform Driver [ In reply to ]
Hello,

Magnus Damm wrote:
> On Wed, May 21, 2008 at 5:05 PM, Uwe Kleine-König
> <Uwe.Kleine-Koenig@digi.com> wrote:
> > @Magnus: Maybe you can provide the userspace part of the driver?
> > How is that mapping used there?
>
> [Added Matsubara-san as CC]
>
> Sure, here is a little test program. Have a look at "uio_mem". The
> "address" member contains the physical address that can be used for
> bus mastering DMA. Compare that to "iomem" which is the pointer to the
> virtual memory area in user space.
>
> Hope this helps!
Yes it does. I thought the physical address is stored in internal_addr
and the virtual in addr, but it's the other way round. Thanks.

Best regards
Uwe

--
Uwe Kleine-König, Software Engineer
Digi International GmbH Branch Breisach, Küferstrasse 8, 79206 Breisach, Germany
Tax: 315/5781/0242 / VAT: DE153662976 / Reg. Amtsgericht Dortmund HRB 13962
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 00/03][RFC] Reusable UIO Platform Driver [ In reply to ]
Magnus Damm wrote:
> Hi Uwe!
>
> Thanks for your email.
>
> On Wed, May 21, 2008 at 3:49 PM, Uwe Kleine-König
> <Uwe.Kleine-Koenig@digi.com> wrote:
> > Magnus Damm wrote:
> >> The uio_pdrv driver doesn't do what I need at this point, though I may
> >> be able to extend it with the following:
> >> - Interrupt enable/disable code
> >> - Physically contiguous memory support
> >>
> >> The interrupt code may be placed in the board/cpu code, but I need to
> >> share that code between multiple UIO driver instances. We want to use
> >> the same UIO driver for many different processor models and hardware
> >> blocks.
> > What about adding uio_platform_handler (with a different name) to
> > uio_pdrv.c?
>
> I'm not sure if it will help. What would such function do? Please explain.
Just add irq_disabled to struct uio_platdata and define

irqreturn_t uio_pdrv_disirq(int irq, struct uio_info *dev_info)
{
struct uio_platdata *pdata = container_of(dev_info, struct uio_platdata, uio_info);

disable_irq(irq);
pdata->irq_disabled = 1;
return IRQ_HANDLED;
}
EXPORT_SYMBOL(uio_pdrv_disirq);

void uio_pdrv_enirq(struct uio_info *dev_info)
{
...
}
EXPORT_SYMBOL(uio_pdrv_enirq);

and then you can do

info->handler = uio_pdrv_disirq;
info->enable_irq = uio_pdrv_enirq;

in the arch specific code. I just realize that you need to compile UIO
statically then :-(

IMHO something like prep_read_poll is a better name than enable_irq for
the new member of uio_info.

> > OTOH I don't see why you want to disable the irq. Can you describe the
> > reason?
>
> Most UIO kernel drivers today contain hardware device specific code to
> acknowledge interrupts. In other words, most UIO interrupt handlers
> touches some device specific bits so the interrupt gets deasserted.
>
> My uio_platform driver handles interrupts in a different way. The
> kernel UIO driver is not aware of the hardware device specific method
> to acknowledge the interrupt, instead it simply disables the interrupt
> and notifies user space which instead will acknowledge the interrupt.
> Next time a read() or poll() call gets made, the interrupt is enabled
> again.
>
> This allows us to export a hardware device to user space and allow
> user space to handle interrupts without knowing in kernel space how to
> acknowledge interrupts.
OK, got it. The down-side is that you can only get a single interrupt
between two calls to read() (or poll()). So you might or might not
loose information. And you might run into problems if your device or
your interrupt goes berserk as your handler always returns IRQ_HANDLED.
With a functional handler you can rely on existing mechanisms in the
kernel.

> >> To be frank, I have my doubts in adding an extra forwarding-only
> >> platform layer on top of UIO compared to using uio_register_device()
> >> directly from the board code. I like that the platform layer is using
> >> struct resource and handles resource ranges for us automatically, but
> >> wouldn't it make more sense to extend the UIO core to always use
> >> struct resource instead of struct uio_mem? I'd be happy to help out -
> >> just point me in the right direction.
> > That alone doesn't help. You need a struct device to register a uio
> > device. So a platform device is the straight forward approach.
>
> I don't mind that you are using platform devices. Actually, I think
> platform devices are great. We use them for all sorts of things on the
> SuperH architecture. I'm trying to suggest that maybe it's a good idea
> to change the UIO core code to use struct resource instead of struct
> uio_mem. Or maybe that's not a good idea, I'm not sure.
struct resource alone doesn't provide enough information. At least
memtype is needed. And you don't need the pointers *parent, *sibling,
*child, so in my eyes it's fine to have a dedicated structure for uio.

> >> >> The interrupt handling code in uio_platform assumes the device is the
> >> >> only user of the assigned interrupt.
> >> >
> >> > Uwe's approach doesn't have this limitation.
> >>
> >> True, but the uio_pdrv driver is choosing to not deal with interrupts
> >> at all. I'd like to have shared interrupt handling code. With my
> >> driver, you just feed it io memory window parameters and an interrupt
> >> number and off you go. No need for any callbacks.
> > In my eyes this isn't completly correct. Just the way you specify your
> > handler is a bit different. You can pass a handler via platform data
> > with my driver, too.
>
> I don't want to pass any handler. All devices share the same interrupt
> handler, the only thing that differs between multiple uio_platform
> devices on one system is memory window information and irq number.
See above. That would be the cost to share code with "my" driver.

All in all I'm not conviced that it's a good idea to use the irq_disable
trick to save acking in kernel space. This doesn't need to stop you
doing it that way of course.

Best regards
Uwe

--
Uwe Kleine-König, Software Engineer
Digi International GmbH Branch Breisach, Küferstrasse 8, 79206 Breisach, Germany
Tax: 315/5781/0242 / VAT: DE153662976 / Reg. Amtsgericht Dortmund HRB 13962
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 00/03][RFC] Reusable UIO Platform Driver [ In reply to ]
On Wed, May 21, 2008 at 6:25 PM, Uwe Kleine-König
<Uwe.Kleine-Koenig@digi.com> wrote:
> Magnus Damm wrote:
>> On Wed, May 21, 2008 at 3:49 PM, Uwe Kleine-König
>> > What about adding uio_platform_handler (with a different name) to
>> > uio_pdrv.c?
>>
>> I'm not sure if it will help. What would such function do? Please explain.
> Just add irq_disabled to struct uio_platdata and define
>
> irqreturn_t uio_pdrv_disirq(int irq, struct uio_info *dev_info)
> {
> struct uio_platdata *pdata = container_of(dev_info, struct uio_platdata, uio_info);
>
> disable_irq(irq);
> pdata->irq_disabled = 1;
> return IRQ_HANDLED;
> }
> EXPORT_SYMBOL(uio_pdrv_disirq);
>
> void uio_pdrv_enirq(struct uio_info *dev_info)
> {
> ...
> }
> EXPORT_SYMBOL(uio_pdrv_enirq);
>
> and then you can do
>
> info->handler = uio_pdrv_disirq;
> info->enable_irq = uio_pdrv_enirq;
>
> in the arch specific code. I just realize that you need to compile UIO
> statically then :-(

I understand now. Thanks for the clear description.

What about letting the uio_pdrv code override info->handler and
info->enable_irq with the above functions if info->handler is NULL?
That would be one step closer to a shared driver in my opinion. And it
would remove the need for symbol exports and solve the
static-compile-only issue.

The physically contiguous memory issue still needs to be solved
somehow though. What about using struct resouce flagged as
IORESOURCE_DMA to pass the amount of memory that should be allocated?

> IMHO something like prep_read_poll is a better name than enable_irq for
> the new member of uio_info.

That's fine.

>> > OTOH I don't see why you want to disable the irq. Can you describe the
>> > reason?
>>
>> Most UIO kernel drivers today contain hardware device specific code to
>> acknowledge interrupts. In other words, most UIO interrupt handlers
>> touches some device specific bits so the interrupt gets deasserted.
>>
>> My uio_platform driver handles interrupts in a different way. The
>> kernel UIO driver is not aware of the hardware device specific method
>> to acknowledge the interrupt, instead it simply disables the interrupt
>> and notifies user space which instead will acknowledge the interrupt.
>> Next time a read() or poll() call gets made, the interrupt is enabled
>> again.
>>
>> This allows us to export a hardware device to user space and allow
>> user space to handle interrupts without knowing in kernel space how to
>> acknowledge interrupts.
> OK, got it. The down-side is that you can only get a single interrupt
> between two calls to read() (or poll()). So you might or might not
> loose information. And you might run into problems if your device or
> your interrupt goes berserk as your handler always returns IRQ_HANDLED.
> With a functional handler you can rely on existing mechanisms in the
> kernel.

I agree that I only get a single interrupt, but I'm not agreeing
regarding the problems. =)

In my mind, disabling interrupts and acking them from user space only
leads to increased interrupt latencies. People may dislike increased
interrupt latencies, but if so they shouldn't have their driver in
user space. And you may of course choose to ack interrupts in kernel
space and queue information there which user space later reads out.
But that sounds more like a specialized kernel driver. And that is not
what i'm trying to do.

Regarding loosing information, if your hardware device can't cope with
long latencies and drops things on the floor then improve your
latency, increase buffer size or design better hardware. Also, I don't
think the interrupt can go berserk since it will be disabled directly
by the interrupt handler.

>> >> To be frank, I have my doubts in adding an extra forwarding-only
>> >> platform layer on top of UIO compared to using uio_register_device()
>> >> directly from the board code. I like that the platform layer is using
>> >> struct resource and handles resource ranges for us automatically, but
>> >> wouldn't it make more sense to extend the UIO core to always use
>> >> struct resource instead of struct uio_mem? I'd be happy to help out -
>> >> just point me in the right direction.
>> > That alone doesn't help. You need a struct device to register a uio
>> > device. So a platform device is the straight forward approach.
>>
>> I don't mind that you are using platform devices. Actually, I think
>> platform devices are great. We use them for all sorts of things on the
>> SuperH architecture. I'm trying to suggest that maybe it's a good idea
>> to change the UIO core code to use struct resource instead of struct
>> uio_mem. Or maybe that's not a good idea, I'm not sure.
> struct resource alone doesn't provide enough information. At least
> memtype is needed. And you don't need the pointers *parent, *sibling,
> *child, so in my eyes it's fine to have a dedicated structure for uio.

Maybe the flags member of struct resource together with IORESOURCE_xxx
can be used instead of memtype. But there is no point in changing
things just for the sake of it, so it is fine as-is in my opinion.

Thank you!

/ magnus
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 00/03][RFC] Reusable UIO Platform Driver [ In reply to ]
Magnus Damm wrote:
> On Wed, May 21, 2008 at 6:25 PM, Uwe Kleine-König
> <Uwe.Kleine-Koenig@digi.com> wrote:
> > Magnus Damm wrote:
> >> On Wed, May 21, 2008 at 3:49 PM, Uwe Kleine-König
> >> > What about adding uio_platform_handler (with a different name) to
> >> > uio_pdrv.c?
> >>
> >> I'm not sure if it will help. What would such function do? Please explain.
> > Just add irq_disabled to struct uio_platdata and define
> >
> > irqreturn_t uio_pdrv_disirq(int irq, struct uio_info *dev_info)
> > {
> > struct uio_platdata *pdata = container_of(dev_info, struct uio_platdata, uio_info);
> >
> > disable_irq(irq);
> > pdata->irq_disabled = 1;
> > return IRQ_HANDLED;
> > }
> > EXPORT_SYMBOL(uio_pdrv_disirq);
> >
> > void uio_pdrv_enirq(struct uio_info *dev_info)
> > {
> > ...
> > }
> > EXPORT_SYMBOL(uio_pdrv_enirq);
> >
> > and then you can do
> >
> > info->handler = uio_pdrv_disirq;
> > info->enable_irq = uio_pdrv_enirq;
> >
> > in the arch specific code. I just realize that you need to compile UIO
> > statically then :-(
>
> I understand now. Thanks for the clear description.
>
> What about letting the uio_pdrv code override info->handler and
> info->enable_irq with the above functions if info->handler is NULL?
... if both info->handler and info->prep_read_poll are NULL and
info->irq >= 0.

> That would be one step closer to a shared driver in my opinion. And it
> would remove the need for symbol exports and solve the
> static-compile-only issue.
>
> The physically contiguous memory issue still needs to be solved
> somehow though. What about using struct resouce flagged as
> IORESOURCE_DMA to pass the amount of memory that should be allocated?
I'm not sure that solving that problem in uio_pdrv is the right
approach. Other uio drivers might have the same problem, so better
allow the userspace driver to allocate some memory in a more generic
way?

> >> My uio_platform driver handles interrupts in a different way. The
> >> kernel UIO driver is not aware of the hardware device specific method
> >> to acknowledge the interrupt, instead it simply disables the interrupt
> >> and notifies user space which instead will acknowledge the interrupt.
> >> Next time a read() or poll() call gets made, the interrupt is enabled
> >> again.
> >>
> >> This allows us to export a hardware device to user space and allow
> >> user space to handle interrupts without knowing in kernel space how to
> >> acknowledge interrupts.
> > OK, got it. The down-side is that you can only get a single interrupt
> > between two calls to read() (or poll()). So you might or might not
> > loose information. And you might run into problems if your device or
> > your interrupt goes berserk as your handler always returns IRQ_HANDLED.
> > With a functional handler you can rely on existing mechanisms in the
> > kernel.
>
> I agree that I only get a single interrupt, but I'm not agreeing
> regarding the problems. =)
>
> In my mind, disabling interrupts and acking them from user space only
> leads to increased interrupt latencies. People may dislike increased
> interrupt latencies, but if so they shouldn't have their driver in
> user space. And you may of course choose to ack interrupts in kernel
> space and queue information there which user space later reads out.
> But that sounds more like a specialized kernel driver. And that is not
> what i'm trying to do.
>
> Regarding loosing information, if your hardware device can't cope with
> long latencies and drops things on the floor then improve your
> latency, increase buffer size or design better hardware. Also, I don't
> think the interrupt can go berserk since it will be disabled directly
> by the interrupt handler.
Assume your irq is stuck at its active level. Normally the irq is
then disabled after some time. You can handle that in your userspace
driver, but with acking in kernel space and returning IRQ_NONE or
IRQ_HANDLED you get it for free. Nevertheless, go on.

Best regards
Uwe

--
Uwe Kleine-König, Software Engineer
Digi International GmbH Branch Breisach, Küferstrasse 8, 79206 Breisach, Germany
Tax: 315/5781/0242 / VAT: DE153662976 / Reg. Amtsgericht Dortmund HRB 13962
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 00/03][RFC] Reusable UIO Platform Driver [ In reply to ]
On Wed, May 21, 2008 at 8:04 PM, Uwe Kleine-König
<Uwe.Kleine-Koenig@digi.com> wrote:
> Magnus Damm wrote:
>> What about letting the uio_pdrv code override info->handler and
>> info->enable_irq with the above functions if info->handler is NULL?
> ... if both info->handler and info->prep_read_poll are NULL and
> info->irq >= 0.

Even better! =)

>> The physically contiguous memory issue still needs to be solved
>> somehow though. What about using struct resouce flagged as
>> IORESOURCE_DMA to pass the amount of memory that should be allocated?
> I'm not sure that solving that problem in uio_pdrv is the right
> approach. Other uio drivers might have the same problem, so better
> allow the userspace driver to allocate some memory in a more generic
> way?

I don't think there is any generic way for a user space driver to
allocate physically contiguous memory. If such way exists then we
should use that instead of course. Recommendations anyone?

>> Regarding loosing information, if your hardware device can't cope with
>> long latencies and drops things on the floor then improve your
>> latency, increase buffer size or design better hardware. Also, I don't
>> think the interrupt can go berserk since it will be disabled directly
>> by the interrupt handler.
> Assume your irq is stuck at its active level. Normally the irq is
> then disabled after some time. You can handle that in your userspace
> driver, but with acking in kernel space and returning IRQ_NONE or
> IRQ_HANDLED you get it for free. Nevertheless, go on.

Ok, so normally if the irq is stuck as asserted then it gets disabled
after some time. In my case it gets disabled directly so see it as a
feature. =)

Would you like to fold in the irq_handler and irq_enable function in
your patch, or would you like me to make a patch that fits on top of
your latest version?

Thanks for your help!

/ magnus
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 00/03][RFC] Reusable UIO Platform Driver [ In reply to ]
Magnus Damm wrote:
> Would you like to fold in the irq_handler and irq_enable function in
> your patch, or would you like me to make a patch that fits on top of
> your latest version?
I would prefer the latter, because my patch already has acks and is
complete as such. Moreover your suggestion needs the irq_enable patch.

Best regards
Uwe

--
Uwe Kleine-König, Software Engineer
Digi International GmbH Branch Breisach, Küferstrasse 8, 79206 Breisach, Germany
Tax: 315/5781/0242 / VAT: DE153662976 / Reg. Amtsgericht Dortmund HRB 13962
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/