您的位置:首页 > 运维架构 > Linux

ARM linux PLATFORM 设备注册

2010-04-13 00:21 302 查看
ARM linux PLATFORM 设备注册

static struct platform_driver power_driver = {
.driver.name = "power",
.suspend_late = power_suspend_late,
};
static struct platform_device power_device = {
.name = "power",
};

static int __init wakelocks_init(void)
{

ret = platform_device_register(&power_device);
if (ret) {
pr_err("wakelocks_init: platform_device_register failed/n");
goto err_platform_device_register;
}
ret = platform_driver_register(&power_driver);




}

设备注册到总线

struct platform_device pxa_device_fb = {
.name = "pxa2xx-fb",
.id = -1,
.dev = {
.dma_mask = &fb_dma_mask,
.coherent_dma_mask = 0xffffffff,
},
.num_resources = ARRAY_SIZE(pxafb_resources),
.resource = pxafb_resources,
};

void __init set_pxa_fb_info(struct pxafb_mach_info *info)
{
pxa_register_device(&pxa_device_fb, info);
}

void __init pxa_register_device(struct platform_device *dev, void *data)
{
int ret;

dev->dev.platform_data = data;

ret = platform_device_register(dev);
if (ret)
dev_err(&dev->dev, "unable to register device: %d/n", ret);
}

int platform_device_register(struct platform_device *pdev)
{
device_initialize(&pdev->dev);
return platform_device_add(pdev);
}

int platform_device_add(struct platform_device *pdev)

int platform_device_add(struct platform_device *pdev)
{
int i, ret = 0;

if (!pdev)
return -EINVAL;

if (!pdev->dev.parent)
pdev->dev.parent = &platform_bus;

pdev->dev.bus = &platform_bus_type;

if (pdev->id != -1)
dev_set_name(&pdev->dev, "%s.%d", pdev->name, pdev->id);
else
dev_set_name(&pdev->dev, pdev->name);

for (i = 0; i < pdev->num_resources; i++) {
struct resource *p, *r = &pdev->resource[i];

if (r->name == NULL)
r->name = dev_name(&pdev->dev);

p = r->parent;
if (!p) {
if (resource_type(r) == IORESOURCE_MEM)
p = &iomem_resource;
else if (resource_type(r) == IORESOURCE_IO)
p = &ioport_resource;
}

if (p && insert_resource(p, r)) {
printk(KERN_ERR
"%s: failed to claim resource %d/n",
dev_name(&pdev->dev), i);
ret = -EBUSY;
goto failed;
}
}

pr_debug("Registering platform device '%s'. Parent at %s/n",
dev_name(&pdev->dev), dev_name(pdev->dev.parent));

ret = device_add(&pdev->dev);
if (ret == 0)
return ret;

failed:
while (--i >= 0) {
struct resource *r = &pdev->resource[i];
unsigned long type = resource_type(r);

if (type == IORESOURCE_MEM || type == IORESOURCE_IO)
release_resource(r);
}

return ret;
}

驱动注册到总线

static int __devinit pxafb_init(void)--------> Pxafb.c (kernel/drivers/video
int platform_driver_register(struct platform_driver *drv)--->Platform.c (kernel/drivers/base)
int driver_register(struct device_driver *drv)------->driver.c (kernel/drivers/base)
struct device_driver *driver_find(const char *name, struct bus_type *bus)-------->driver.c (kernel/drivers/base)
int bus_add_driver(struct device_driver *drv)----->bus.c (kernel/drivers/base)
static int driver_add_groups(struct device_driver *drv, struct attribute_group **groups)--->driver.c (kernel/drivers/base)
int driver_attach(struct device_driver *drv)----->Dd.c (kernel、drivers/base)
static int __driver_attach(struct device *dev, void *data)------>Dd.c (kernel/drivers/base)

drv->bus->match(dev, drv) ( 不同的总线这个match指向的函数不一样在各个bus定义,例如I2c为i2c_device_match )

int driver_probe_device(struct device_driver *drv, struct device *dev)--->Dd.c (kernel/drivers/base)
static int really_probe(struct device *dev, struct device_driver *drv)----->Dd.c (kernel/drivers/base)

static int really_probe(struct device *dev, struct device_driver *drv)

if (dev->bus->probe) {
ret = dev->bus->probe(dev);
if (ret)
goto probe_failed;
} else if (drv->probe) {
ret = drv->probe(dev);
if (ret)
goto probe_failed;
}

static int __init pxafb_probe(struct platform_device *dev)---->Pxafb.c (kernel/drivers/video
platform_device_register 将设备的名字注册到设备链表

platform_driver_register将设备和驱动的名字对比,调用probe函数初始化

struct bus_type i2c_bus_type = {
.name = "i2c",
.dev_attrs = i2c_dev_attrs,
.match = i2c_device_match,
.uevent = i2c_device_uevent,
.probe = i2c_device_probe,
.remove = i2c_device_remove,
.shutdown = i2c_device_shutdown,
.suspend = i2c_device_suspend,
.resume = i2c_device_resume,
};
EXPORT_SYMBOL_GPL(i2c_bus_type);

struct bus_type platform_bus_type = {
.name = "platform",
.dev_attrs = platform_dev_attrs,
.match = platform_match,
.uevent = platform_uevent,
.pm = PLATFORM_PM_OPS_PTR,
};
EXPORT_SYMBOL_GPL(platform_bus_type);

struct bus_type usb_bus_type = {
.name = "usb",
.match = usb_device_match,
.uevent = usb_uevent,
};

struct bus_type ac97_bus_type = {
.name = "ac97",
.match = ac97_bus_match,
#ifdef CONFIG_PM
.suspend = ac97_bus_suspend,
.resume = ac97_bus_resume,
#endif /* CONFIG_PM */
};

static int __init ac97_bus_init(void)
{
return bus_register(&ac97_bus_type);
}

static struct bus_type sdio_bus_type = {
.name = "sdio",
.dev_attrs = sdio_dev_attrs,
.match = sdio_bus_match,
.uevent = sdio_bus_uevent,
.probe = sdio_bus_probe,
.remove = sdio_bus_remove,
.suspend = sdio_bus_suspend,
.resume = sdio_bus_resume,
};

int sdio_register_bus(void)
{
return bus_register(&sdio_bus_type);
}

static struct bus_type serio_bus = {
.name = "serio",
.dev_attrs = serio_device_attrs,
.drv_attrs = serio_driver_attrs,
.match = serio_bus_match,
.uevent = serio_uevent,
.probe = serio_driver_probe,
.remove = serio_driver_remove,
.shutdown = serio_shutdown,
#ifdef CONFIG_PM
.suspend = serio_suspend,
.resume = serio_resume,
#endif
};

static int __init serio_init(void)
{
int error;

error = bus_register(&serio_bus);
if (error) {
printk(KERN_ERR "serio: failed to register serio bus, error: %d/n", error);
return error;
}

serio_task = kthread_run(serio_thread, NULL, "kseriod");
if (IS_ERR(serio_task)) {
bus_unregister(&serio_bus);
error = PTR_ERR(serio_task);
printk(KERN_ERR "serio: Failed to start kseriod, error: %d/n", error);
return error;
}

return 0;
}

struct bus_type scsi_bus_type = {
.name = "scsi",
.match = scsi_bus_match,
.uevent = scsi_bus_uevent,
.suspend = scsi_bus_suspend,
.resume = scsi_bus_resume,
.remove = scsi_bus_remove,
};
EXPORT_SYMBOL_GPL(scsi_bus_type);

int scsi_sysfs_register(void)
{
int error;

error = bus_register(&scsi_bus_type);
if (!error) {
error = class_register(&sdev_class);
if (error)
bus_unregister(&scsi_bus_type);
}

return error;
}

struct bus_type pci_bus_type = {
.name = "pci",
.match = pci_bus_match,
.uevent = pci_uevent,
.probe = pci_device_probe,
.remove = pci_device_remove,
.shutdown = pci_device_shutdown,
.dev_attrs = pci_dev_attrs,
.pm = PCI_PM_OPS_PTR,
};

static int __init pci_driver_init(void)
{
return bus_register(&pci_bus_type);
}

static struct bus_type w1_bus_type = {
.name = "w1",
.match = w1_master_match,
.uevent = w1_uevent,
};

static const struct i2c_device_id *i2c_match_id(const struct i2c_device_id *id,
const struct i2c_client *client)
{
while (id->name[0]) {
if (strcmp(client->name, id->name) == 0)
return id;
id++;
}
return NULL;
}

static int i2c_device_match(struct device *dev, struct device_driver *drv)
{
struct i2c_client *client = to_i2c_client(dev);
struct i2c_driver *driver = to_i2c_driver(drv);

/* make legacy i2c drivers bypass driver model probing entirely;
* such drivers scan each i2c adapter/bus themselves.
*/
if (!is_newstyle_driver(driver))
return 0;

/* match on an id table if there is one */
if (driver->id_table)
return i2c_match_id(driver->id_table, client) != NULL;

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: