Linux 自定义总线类型

#include <linux/module.h>
#include <linux/init.h>
#include <linux/device.h>

// 按照 platform_device 格式定义
struct test_dev {
  char *name;
  // 必须要有父类,注册时会将父类注册到链表
  struct device dev;
  // 其他成员自定义
};

// 按照 platform_driver 格式定义
struct test_drv {
  // 必须要有父类,注册时会将父类注册到链表
  struct device_driver driver;
  // 其他成员自定义
};

void mydev_release(struct device *dev)
{
  // 防止 rmmod 时报错
}

// 匹配函数
int my_bus_match(struct device *dev, struct device_driver *drv)
{
  struct test_dev *testdev;

  // 优先使用 drv 父类中的 name 和 dev 中的 name 比较匹配
  testdev = container_of(dev, struct test_dev, dev);

  if (strcmp(drv->name, testdev->name) == 0)
  {
    printk("match ok!
");
    return 1;
  }

  // 如果 drv 父类中的 name 没有定义,再使用 drv 中的 name 比较匹配
  // 代码忽略
  return 0;
}

// 匹配成功后执行的函数
int my_bus_probe(struct device *dev)
{
  printk("-----%s-----
", __FUNCTION__);

  return 0;
}

// 初始化自定义总线
struct bus_type my_bus= {
  .name = "my_bus",
  .match = my_bus_match,
};

struct test_dev mydev = {
  .name = "dev_drv",
  .dev = {
    .init_name = "test_bus",
    .bus = &my_bus,
    .release = mydev_release,
  },
};

struct test_drv mydrv= {
  .driver = {
    .name = "dev_drv",
    .bus = &my_bus,
    .probe = my_bus_probe,
  },
};

static int __init my_bus_init(void)
{
  // 注册总线
  bus_register(&my_bus);

  // 注册设备,注意是父类
  device_register(&mydev.dev);

  // 注册驱动,注意是父类
  driver_register(&mydrv.driver);

  return 0;
}

static void __exit my_bus_exit(void)
{
  // 注销
  device_unregister(&mydev.dev);
  driver_unregister(&mydrv.driver);
  bus_unregister(&my_bus);
}

module_init(my_bus_init);
module_exit(my_bus_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Aaron Lee");

注册和注销时一定要选用 device 和 driver 父类:

device_register(&mydev.dev);

driver_register(&mydrv.driver);

device_unregister(&mydev.dev);

driver_unregister(&mydrv.driver);

ps:原因与平台总线相同,请参照下面文章中的“分离”。

http://www.cnblogs.com/lialong1st/p/7756669.html

自定义的总线在 /sys/bus 目录下

struct test_dev 中的 init_name 在 /sys/bus/my_bus/device 目录下

原文地址:https://www.cnblogs.com/lialong1st/p/7762571.html