dev.c drv.c bus.c

-------------------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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值