On Wed, 2010-12-08 at 11:18 +0100, Guillaume Dargaud wrote: > Thanks again for your detailed answer, > I'm learning, but not as fast as my colleagues with a deadline want me to !
:) > > The platform code does that. That function create devices on the > > platform bus by examining the device tree. It looks for nodes that are > > compatible with the compatible strings you give it, and treats them as > > busses, ie. creates devices for all child nodes of those nodes. > > Is there a way to enable some debug output from it, to see what's going on ? Not really, but there probably should be. > > > ...hmm I had to "git pull" in order for this to compile your snippet. > > > That's really recent! Unfortunately i need to reflash my device with the > > > new kernel before i can begin testing my module. > > > > It shouldn't be that recent, what kernel version were you using? > > I had to go from 2.6.34 to 2.6.35, xilinx git tree. Ah that is the problem I think. Sorry I assumed you were working on mainline. In 2.6.35 you still need to use an of_platform_driver, I'll describe below. > > platform_device_register() tends to be for cases where you can't > > discover or probe a device, but you "know" that it exists. > > When you see something in /sys/devices/plb.0/, it means that you don't need > platform_device_register, right ? That's right. > > Yes, "make tags", then use vim :) > > Great, that works. Cool. > OK, here's the relevant part of my code, ripped directly from your sample, > with a few additions and different variable names. Why do you think > xad_driver_probe() is not being called ? As I said above in 2.6.35 platform drivers and of_platform drivers were still separate. So your device is on the of_platform_bus (ie. was discovered using the device tree), but your driver is on the platform_bus. Yes this is very confusing. So basically you need to change all occurrences of platform_driver to of_platform_driver. > #include <linux/kernel.h> > #include <linux/init.h> > #include <asm/device.h> > #include <linux/platform_device.h> > #include <linux/cdev.h> // char device > #include <linux/fs.h> > #include <linux/of.h> > #include <linux/interrupt.h> > > #define DEVNAME "xps-acqui-data" > #define NAME "xad" // This is only used for printk > > #define SD "{%s %d} " > #define FL , __func__, __LINE__ > > static dev_t first; > static unsigned int count = 1; > static int my_major = 241, my_minor = 0; > // You must run "mknod /dev/xad c 241 0" in a shell at least once > > struct cdev *my_cdev=NULL; > struct platform_device *pdev=NULL; > > typedef struct XadDevice { > struct resource *hw_region; > struct device *dev; > int irq; > } tXadDevice; > tXadDevice Xad; > > // There should be something in: > // ll /sys/devices/plb.0/c9800000.xps-acqui-data > static const struct of_device_id xad_device_id[] = { > { .compatible = "xlnx,xps-acqui-data-3.00.a" }, // Must match > the DTS > {} > }; > > > static irqreturn_t XadIsr(int irq, void *dev_id) { > printk(KERN_INFO SD "IRQ:%d\n" FL, irq); > return IRQ_HANDLED; > } > > /////////////////////////////////////////////////////////////////////////////// > // Platform Bus Support > /////////////////////////////////////////////////////////////////////////////// > > static int xad_driver_probe(struct platform_device *device /*, > const struct of_device_id *device_id*/ ) { So you need to switch the prototype here to: static int xad_driver_probe(struct of_platform_device *ofdev, const struct of_device_id *device_id) { > struct device_node *dn = device->dev.of_node; > int rc; > > pr_devel("Probing %s\n", dn->full_name); > > Xad.irq = irq_of_parse_and_map(dn, 0); > rc=request_irq(Xad.irq, XadIsr, IRQF_TRIGGER_RISING | IRQF_DISABLED, > "XadIsr", &Xad); > if (rc) printk(KERN_INFO SD "Failled IRQ request: %d\n" FL, rc); > > return 0; > } > > static int __devexit xad_driver_remove(struct platform_device *device) { > printk(KERN_INFO SD "Removing...\n" FL); > return 0; > } > > static struct platform_driver xad_driver = { Becomes of_platform_driver > .probe = xad_driver_probe, > .remove = xad_driver_remove, > .driver = { > .owner = THIS_MODULE, > .name = "xad-driver", > .of_match_table = xad_device_id, > }, > }; > > > /////////////////////////////////////////////////////////////////////////////// > // This section deals with the /dev/xad device > /////////////////////////////////////////////////////////////////////////////// > static int xad_open(struct inode *node, struct file *filep) { > printk (KERN_INFO SD "OPENING device: %s\n" FL, NAME); > return 0; > } > > static int xad_release(struct inode *node, struct file *filep) { > printk (KERN_INFO SD "RELEASING device: %s\n" FL, NAME); > return 0; > } > > static int xad_ioctl(struct inode *node, struct file *filep, unsigned int > cmd, > unsigned long arg) { > printk (KERN_INFO SD "IOCTL on device: %s, cmd:%d, arg:%lu\n" FL, NAME, > cmd, > arg); > return 0; > } > > static struct file_operations fops = { > .owner = THIS_MODULE, > .open = xad_open, > .release = xad_release, > .ioctl = xad_ioctl, > }; > > > /////////////////////////////////////////////////////////////////////////////// > // Called on insmod > static int __init xad_init(void) { > int rc=0; > printk(KERN_INFO SD "Module %s: loading...\n" FL, NAME); > > // Deal with the device > first = MKDEV (my_major, my_minor); > register_chrdev_region(first, count, DEVNAME); > my_cdev = cdev_alloc (); > if (NULL==my_cdev) goto Err; > > cdev_init(my_cdev, &fops); > cdev_add (my_cdev, first, count); > > printk(KERN_INFO SD "Module %s: Major=%d, Minor=%d, Count=%d\n" FL, NAME, > my_major, my_minor, count); > > // Driver > rc = platform_driver_register(&xad_driver); Should be of_register_platform_driver() > // rc = platform_driver_probe(&xad_driver, xad_driver_probe); > if (rc) goto err_plat; > > // Device > pdev=platform_device_register_simple("xps-acqui-data", -1, NULL, 0); > if (IS_ERR(pdev)) { > rc = PTR_ERR(pdev); > platform_driver_unregister(&xad_driver); > goto err_plat; > } > > > return 0; > > err_plat: > unregister_chrdev_region(first, count); > Err: > printk(KERN_ERR SD "Module %s: Failed loading rc=%d\n" FL, NAME, rc); > return rc; > } > > /////////////////////////////////////////////////////////////////////////////// > // Called on rmmod > static void xad_exit(void) { > platform_device_unregister(pdev); pdev=NULL; > platform_driver_unregister(&xad_driver); > > cdev_del (my_cdev); my_cdev=NULL; > unregister_chrdev_region (first, count); > printk(KERN_INFO SD "Module %s unloaded\n" FL, NAME); > } > > module_init(xad_init); > module_exit(xad_exit); > > MODULE_AUTHOR("Guillaume Dargaud"); > MODULE_LICENSE("GPL"); > > cheers
signature.asc
Description: This is a digitally signed message part
_______________________________________________ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev