2
votes

I need a device driver that I'm writing/modifying to be able to access another device in the system. I know some information about the driver, like the name and/or address, in order to look it up, but I can't find how to actually do the look up. In this particular case, I need to get a GPIO device (there will be 5 loaded, and there are 2 different types of them), but I do need to know in general also, as I have a different task where several drivers share a common one that they will have to look up, I presume in a similar manner. I've found how to look up a device from userspace, but nothing about how to do it from another kernel driver. Also, there are no modules in the system, all devices are loaded from the devicetree info.

Part of what's confusing me is that I don't see how the particular gpio init functions register the device anywhere. I'm using the Xilinx-specific AXI GPIO device, which uses the code in drivers/gpio/gpio-xilinx.c and I can see how it gets all the info from the devicetree, but I don't see anything getting passed back to any kernel lists for it to be used later.

If it helps, this is running on a Xilinx Zynq chip.

2

2 Answers

1
votes

Use driver_find() API to find the driver if you know the name and the bus_type to which the driver belongs to. You can also use the find_module() API to get the module provided you know the module name. Example...

int __init initialization_routine(void)
{
        struct module *mod;
        struct device_driver *drv;

        mod = find_module("e1000"); // e1000 is Intel ethernet module
        if (mod == NULL) { 
                printk("Module e1000 not found\n");
                return 1;
        }

        printk("Module name : %s\n", mod->name);

        /*
         * Module e1000 belongs to pci_bus_type
         */
        drv = driver_find("e1000", &pci_bus_type);
        if (drv == NULL) {
                printk("Cannot find driver for module e1000\n");
                return 1;
        }

        return 0;
}

There are various buses registered on the system. You can find them be listing all the directories under /sys/bus . Each directory is a bus type. The bus type structure name can be found out by searching in the kernel for bus_type structure definitions.

1
votes

The final solution I used was this:

static int custom_match_dev(struct device *dev, void *data)
{
// this function implements the comaparison logic. Return not zero if found.
    const char *name = data;

    return sysfs_streq(name, dev->of_node->name);
}

static struct device *find_dev( const char * name )
{
    struct device *dev = bus_find_device( &platform_bus_type, NULL, name, custom_match_dev );

    return dev;
}

The only thing to remember is that the name of the device in the device tree must be unique.