Getting the IRQ number (Was: Basic driver devel questions ?)

Michael Ellerman michael at ellerman.id.au
Mon Dec 6 23:07:08 EST 2010


On Mon, 2010-12-06 at 10:58 +0100, Guillaume Dargaud wrote:
> Thank you for the detailed answer. I'm trying to digest it...
> 
> > > What's a good source, besides grepping the kernel to no end ?
> > 
> > Nothing really I'm afraid.
> 8-|
> 
> > So you have a device, it appears in your device tree, and you want to
> > write a driver for it.

> That's the idea. Communication between usermode and the driver is limited to 
> simple ioctl calls and the driver receives an interrupt when certain data has 
> been placed in memory blocks by the hardware (like a DMA). Then the user prog 
> figures out where that latest data buffer is (mmap) and saves it. 

OK, that should be all pretty straight forward, and covered by the
material in LDD and similar references. You just need to get your device
probed.

> > The first issue is that someone needs to create a device for your node,
> > it doesn't necessarily happen by default. For many platforms this will
> > all happen "automagically" as long as the device node that describes
> > your device appears in the right place, but I'll describe it in full
> > anyway.
> 
> I'm on a minimalist embedded system (buildroot+busybox+uclibc), so I'm pretty 
> sure I have to do the whole thing. No udev/HAL here.

That's another problem. The device I'm talking about here is just the
minimal struct in the kernel that you need in order for your driver to
probe against it. Once your driver has matched against a device then you
(might) need to worry about exposing a device to userspace in /dev.

> > In most cases your device will appear below a node that represents a
> > bus, eg:
> > 
> > 	foobus at xyz {
> > 		compatible = "vendor,foobus-v1.m.n", "simple-bus";
> > 		...
> > 		yournode at abc {
> > 			...
> > 		}
> > 	}
> > 
> > If that isn't the case you need to arrange for it somehow [1].
> 
> Commenting on your [1] here. So should I just add "simple-bus" or does the 
> VHDL needs to be modified so as to generate this additional bus info ?

Doesn't look like it:

> I indeed have:
> 
> /dts-v1/;
> / {
> 	#address-cells = <1>;
> 	#size-cells = <1>;
> 	compatible = "xlnx,virtex405", "xlnx,virtex";
> 	model = "testing";
> 	...
> 	plb: plb at 0 {
> 		#address-cells = <1>;
> 		#size-cells = <1>;
> 		compatible = "xlnx,plb-v46-1.05.a", "xlnx,plb-v46-1.00.a", "simple-bus";
> 		ranges ;
> 		...
> 		xps_acqui_data_0: xps-acqui-data at c9800000 {
> 			compatible = "xlnx,xps-acqui-data-3.00.a";
> 			...
> 		}
> 		...
> 	}
> 	...
> }

That looks good.

> > Somewhere there needs to be code to probe that bus and create devices on
> > it. That is usually done in platform code with of_platform_bus_probe().
> 
> Isn't the of_* code outdated (just been told that on a previous message) ?
> Or was it just for of_register_platform_driver ?

No it's just that platform_drivers are now able to do all the things an
of_platform_driver can do, so new code should just use platform_driver.

I'm not sure if of_platform_bus_probe() will go away eventually, but for
now it is the only way to achieve what you need.

> > If you don't know what platform you're on, you can look at a boot log
> > for a line saying "Using <blah> machine description", it will be very
> > early in the log. "blah" is then the name of the platform you're on, and
> > you should be able to grep for it in arch/powerpc/platforms.
> 
> "Using Xilinx Virtex machine description"

Cool.

> > Once you've found the .c file for your platform, there should be a call
> > somewhere to of_platform_bus_probe(), with a list of ids, and one of
> > those ids should match the compatible property of your bus node. In a
> > lot of cases that is just "simple-bus".
> 
> That'd be:
> arch/powerpc/platforms/40x/virtex.c:51: .name = "Xilinx Virtex",
> and
> arch/powerpc/platforms/40x/virtex.c:21: { .compatible = "simple-bus", },

Perfect.

> No match for simple-bus of acqui-data in dmesg.

That's normal, if the kernel printed out every device it found you'd
drown in messages. If you want to you can put a printk in
of_platform_device_create() and you should see it.

> > To check a device is being created for your device node, you can look
> > in /sys/devices. The device names don't match 100% with what's in the
> > device tree, but the name should be there, so in your case:
> > 
> > # find /sys/devices -name '*xps-acqui-data*'
> 
> Indeed: 
> # ll /sys/devices/plb.0/c9800000.xps-acqui-data
> -r--r--r--    1 root     root        4.0K Dec  6 09:47 devspec
> -r--r--r--    1 root     root        4.0K Dec  6 09:47 modalias
> -r--r--r--    1 root     root        4.0K Dec  6 09:47 name
> lrwxrwxrwx    1 root     root           0 Dec  6 09:47 subsystem -> ../../../bus/of_platform/
> -rw-r--r--    1 root     root        4.0K Dec  6 09:47 uevent
> 
> So that's created on boot, right ?

Yep, so that is all working fine. You just need to write a driver that
will match against that device.

> > [...code snipped...]
> 
> I still need a platform_device_register() after your sample init, right ?

I had one in there already, in foo_driver_init(), didn't I?

> I'll get on to adapting your sample code now. Thanks a lot.

No worries.

cheers

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: This is a digitally signed message part
URL: <http://lists.ozlabs.org/pipermail/linuxppc-dev/attachments/20101206/e78acc4b/attachment.pgp>


More information about the Linuxppc-dev mailing list