-------------------02model$ cat dev1.c
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
#include "bus.h"
static struct specdev dev1 = {
.regcon = 0x95273856,
.regdat = 0x77889911,
.irq = 442,
.product_id = 0x00001956,
.vendor_id = 0x00001978,
.name = "plat_dev0"
};
static int __init test_init(void)
{
return specdev_register(&dev1); //在bus.c中封装,调用标准设备注册.
}
static void __exit test_exit(void)
{
specdev_unregister(&dev1);
}
module_init(test_init);
module_exit(test_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("MR. Millet");
MODULE_VERSION("version 6.0");
MODULE_DESCR
----------------------------------------------------------------------------------------------------------------------dev1.c
02model$ cat drv1.c
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
#include "bus.h"
static int myprobe (struct specdev *dev)
{
printk("REGCON: %#x\n", dev->regcon);
printk("REGDAT: %#x\n", dev->regdat);
printk("REGIRQ: %d\n", dev->irq);
return 0;
}
static int myremove (struct specdev*dev)
{
printk("driver %s is removed!\n", dev->name);
return 0;
}
static struct specdrv drv1 = {
.myprobe = myprobe,
.myremove = myremove,
.product_id = 0x1956,
.vendor_id = 0x1978,
.name = "plat_drv0",
};
static int __init test_init(void)
{
return specdrv_register(&drv1);//在bus.c中实现
}
static void __exit test_exit(void)
{
specdrv_unregister(&drv1);
}
module_init(test_init);
module_exit(test_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("MR. Millet");
MODULE_VERSION("version 6.0");
MODULE_DESCRIPTION("A simple example for driver module");
02model$
--------------------------------------------------------------------------------------------------------------------drv..
02model$ cat bus.c
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
#include "plat.h"
//总线的匹配规则,匹配往总线上注册的设备和驱动。匹配成功返回1, 否则返回0;
static int p_match(struct device *dev, struct device_driver *drv)
{
struct specdev *pdev = container_of(dev, struct specdev, dev);
struct specdrv *pdrv = container_of(drv, struct specdrv, drv);
return (pdev->vendor_id == pdrv->vendor_id && pdev->product_id == pdrv->product_id);//match by id
}
static struct bus_type platform_= {//平台总线
.name = "platform_",
.match = p_match,
};
--------------------------------------------------------------------------------------------------------------------dev/release ...
/*注册标准设备对象时需要实现的release, 移除设备时自动会被调用*/
static void pubrelease(struct device *dev) //dev 需要实现
{
struct specdev *p = container_of(dev, struct specdev, dev);
printk("Vendor: %d, Product: %d device is removed.\n", \
p->vendor_id, p->product_id);
}
----------------------------------------------------------------------------------------------------------------------
/*通用的用于注册用户自己的设备函数接口,内部最终调用了标准的设备注册方法*/
static int specdev_register(struct specdev *pdev)
{
pdev->dev.init_name = pdev->name;
pdev->dev.bus = &platform_;
pdev->dev.release = pubrelease;
return device_register(&pdev->dev); //标准注册设备到总线
}
EXPORT_SYMBOL_GPL(specdev_register);
/*通用的用于从指定总线上移除已经注册的封装设备*/
static void specdev_unregister(struct specdev *pdev)
{
return device_unregister(&pdev->dev);
}
EXPORT_SYMBOL_GPL(specdev_unregister);
-----------------------------------------------------------------------------------------------------------------实现probe/remove---drv
/*总线匹配设备和驱动成功后调用标准的驱动结构体内部的探测函数*/
static int pubprobe (struct device *dev)
{
struct specdev *pdev = container_of(dev, struct specdev, dev);
struct specdrv *pdrv = container_of(dev->driver, struct specdrv, drv);
return pdrv->myprobe(pdev); //调用具体用户实现的对具体封装设备操作的函数
}
/*总线上注册的驱动被移除时会调用此标准的移除函数, 一般做和probe相反的工作*/
static int pubremove (struct device *dev)
{
struct specdev *pdev = container_of(dev, struct specdev, dev);
struct specdrv *pdrv = container_of(dev->driver, struct specdrv, drv);
return pdrv->myremove(pdev); //调用具体用户实现的移除驱动时所做工作的函数
}
----------------------------------------------------------------------------------------------------------------------drv
/*往我们指定的总线上注册驱动的通用方法*/
static int specdrv_register(struct specdrv *pdrv)
{
pdrv->drv.name = pdrv->name;
pdrv->drv.bus = &platform_;
pdrv->drv.probe = pubprobe;
pdrv->drv.remove = pubremove;
return driver_register(&pdrv->drv);
}
EXPORT_SYMBOL_GPL(specdrv_register);
/*从注册的总线上把注册的驱动移除,通用方法*/
static void specdrv_unregister(struct specdrv *pdrv)
{
return driver_unregister(&pdrv->drv); //标准方法
}
EXPORT_SYMBOL_GPL(specdrv_unregister);
---------------------------------------------------------------------------------------------------------------------------
static int __init test_init(void)
{
return bus_register(&platform_);
}
static void __exit test_exit(void)
{
bus_unregister(&platform_);
}
module_init(test_init);
module_exit(test_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("MR. Millet");
MODULE_VERSION("version 6.0");
MODULE_DESCRIPTION("A simple example for driver module");
02model$ vim bus.c
02model$ cat bus.c
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
#include "plat.h"
//总线的匹配规则,匹配往总线上注册的设备和驱动。匹配成功返回1, 否则返回0;
static int p_match(struct device *dev, struct device_driver *drv)
{
struct specdev *pdev = container_of(dev, struct specdev, dev);
struct specdrv *pdrv = container_of(drv, struct specdrv, drv);
return (pdev->vendor_id == pdrv->vendor_id && pdev->product_id == pdrv->product_id);
}
static struct bus_type platform_= {
.name = "platform_",
.match = p_match,
};
/*注册标准设备对象时需要实现的release, 移除设备时自动会被调用*/
static void pubrelease(struct device *dev)
{
struct specdev *p = container_of(dev, struct specdev, dev);
printk("Vendor: %d, Product: %d device is removed.\n", \
p->vendor_id, p->product_id);
}
/*通用的用于注册用户自己的设备函数接口,内部最终调用了标准的设备注册方法*/
static int specdev_register(struct specdev *pdev)
{
pdev->dev.init_name = pdev->name;
pdev->dev.bus = &platform_;
pdev->dev.release = pubrelease;
return device_register(&pdev->dev); //标准注册设备到总线
}
EXPORT_SYMBOL_GPL(specdev_register);
/*通用的用于从指定总线上移除已经注册的封装设备*/
static void specdev_unregister(struct specdev *pdev)
{
return device_unregister(&pdev->dev);
}
EXPORT_SYMBOL_GPL(specdev_unregister);
/*总线匹配设备和驱动成功后调用标准的驱动结构体内部的探测函数*/
static int pubprobe (struct device *dev)
{
struct specdev *pdev = container_of(dev, struct specdev, dev);
struct specdrv *pdrv = container_of(dev->driver, struct specdrv, drv);
return pdrv->myprobe(pdev); //调用具体用户实现的对具体封装设备操作的函数
}
/*总线上注册的驱动被移除时会调用此标准的移除函数, 一般做和probe相反的工作*/
static int pubremove (struct device *dev)
{
struct specdev *pdev = container_of(dev, struct specdev, dev);
struct specdrv *pdrv = container_of(dev->driver, struct specdrv, drv);
return pdrv->myremove(pdev); //调用具体用户实现的移除驱动时所做工作的函数
}
/*往我们指定的总线上注册驱动的通用方法*/
static int specdrv_register(struct specdrv *pdrv)
{
pdrv->drv.name = pdrv->name;
pdrv->drv.bus = &platform_;
pdrv->drv.probe = pubprobe;
pdrv->drv.remove = pubremove;
return driver_register(&pdrv->drv);
}
EXPORT_SYMBOL_GPL(specdrv_register);
/*从注册的总线上把注册的驱动移除,通用方法*/
static void specdrv_unregister(struct specdrv *pdrv)
{
return driver_unregister(&pdrv->drv); //标准方法
}
EXPORT_SYMBOL_GPL(specdrv_unregister);
static int __init test_init(void)
{
return bus_register(&platform_);
}
static void __exit test_exit(void)
{
bus_unregister(&platform_);
}
module_init(test_init);
module_exit(test_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("MR. Millet");
MODULE_VERSION("version 6.0");
MODULE_DES
转载于:https://my.oschina.net/tplinuxhyh/blog/525070