分类: LINUX
2015-03-17 16:25:30
Driver added
static struct platform_driver ls1f_gmac_driver = {
.probe = init_one_platform,
.remove = remove_one_platform,
.driver = {
.name = "sb2f-gmac",
.owner = THIS_MODULE,
},
};
->static int __init ls1f_gmac_init(void)(drivers/net/sb2f_gmac/synopGMAC_platform_interface.c)
//fill the platform_driver struct
->platform_driver_register(&ls1f_gmac_driver);(driver/base/platform.c)
-> drv->driver.bus = &platform_bus_type;
//fill the drv->driver struct
->driver_register(&drv->driver);(drivers/base/driver.c)
->bus_add_driver(drv);(drivers/base/bus.c)
//creat a kobject and add to the list of drivers
->kobject_register(&drv->kobj)(kobject.c)
//Walk the list of devices that the bus has on it and try to match the driver with each one.
-> driver_attach(drv);(drivers/base/dd.c)
->bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);
->__driver_attach
->driver_probe_device(drv, dev);
//match the driver and device with their names
->if (drv->bus->match && !drv->bus->match(dev, drv))
->really_probe(data)
->driver_sysfs_add(dev)
//probe
->drv->probe(dev);or dev->bus->probe
Device added
static struct platform_device *sb2f_platform_devices[] __initdata = {
&ls1g_nand_device,
&uart8250_device,
&sb2f_gmac1_device,}
->arch_initcall(sb2f_platform_init);(arch/mips/looson/sb2f-board/platform.c
->platform_add_devices(sb2f_platform_devices,)
->for (i=0;i < num; i++) {ret = platform_device_register(devs[i]);(driver/base/platform.c)
->device_initialize(struct device *dev)(drivers/base/core.c)
//fill the platform_device
->platform_device_add(pdev);(driver/base/platform.c)
// Inserts a resource in the resource tree
->insert_resource(p, r)
// * This adds it to the kobject hierarchy via kobject_add(), adds it
* to the global and sibling lists for the device, then
* adds it to the other relevant subsystems of the driver model.
->device_add(&pdev->dev);
-> pdev->dev.parent = &platform_bus;
-> pdev->dev.bus = &platform_bus_type;
->kobject_add(&dev->kobj);
-> bus_add_device(dev) (drivers/base/core.c)
-> bus_attach_device(dev)(drivers/base/bus.c)
->device_attach(dev);(drivers/base/dd.c)
->device_bind_driver(dev); or
bus_for_each_drv(dev->bus, NULL, dev, __device_attach)
->__device_attach
->driver_probe_device(drv, dev)
->drv->bus->match && !drv->bus->match(dev, drv)
->really_probe(data)
->drv->probe(dev);or dev->bus->probe
Platform device added
//include/linux/device.h
struct device platform_bus = {
.bus_id = "platform",
};
//include/linux/device.h
struct bus_type platform_bus_type = {
.name = "platform",
.dev_attrs = platform_dev_attrs,
.match = platform_match,
.uevent = platform_uevent,
.suspend = platform_suspend,
.suspend_late = platform_suspend_late,
.resume_early = platform_resume_early,
.resume = platform_resume,
};
->int __init platform_bus_init(void) (drivers/base/platform.c)
->device_register(&platform_bus);(drivers/base/core.c)
-> device_initialize(dev);
-> device_add(dev);
-> kobject_add(&dev->kobj);
//notify platform of device entry
->if (platform_notify) platform_notify(dev);
Look document/kobject.txt
//about filesystem
->bus_register(&platform_bus_type);
//create node below sys/platform
->kobject_set_name(&bus->subsys.kset.kobj, "%s", bus->name);
->subsys_set_kset(bus, bus_subsys);
->subsystem_register(&bus->subsys);
//create node below sys/platform/device
->kobject_set_name(&bus->devices.kobj, "devices");
->bus->devices.subsys = &bus->subsys;
->kset_register(&bus->devices);
//create node below sys/platform/driver
->kobject_set_name(&bus->drivers.kobj, "drivers");
->bus->drivers.subsys = &bus->subsys;
->bus->drivers.ktype = &ktype_driver;
-> kset_register(&bus->drivers);