字符驱动移植--bus(平台总线), device, driver

bus


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

char bus_version[128] = "bus version v1";

// 如果匹配成功,返回1, 失败返回0
int mybus_match(struct device *dev, struct device_driver *drv)
{

    //  匹配的基本规则就是匹配名字(注意:dev是父类的名字 )
    if(!strncmp(drv->name, dev->kobj.name, strlen(drv->name))){
        printk("match ok\n");
        return 1;

    }else{
        printk("match failed\n");
        return 0;

    }

}


struct bus_type  mybus = {
    .name = "my_bus",
    .match = mybus_match,

};

//当用cat 调用此函数
ssize_t bus_version_show(struct bus_type *bus, char *buf)
{
    printk("-------^_^   %s-----------\n", __FUNCTION__);

    return snprintf(buf,128, "%s", bus_version);
}
//当用ech xxxx > ultoa, 会调用此函数
ssize_t bus_version_store(struct bus_type *bus, const char *buf, size_t count)
{
    printk("-------^_^   %s-----------\n", __FUNCTION__);

    return snprintf(bus_version,count,"%s", buf);
}

//定义一个新文件--属性文件 struct bus_attribute,用 一个宏来初始化

//  变量名== bus_attr_bus_version
//BUS_ATTR(bus_version,0666,bus_version_show, bus_version_store);

//  BUS_ATTR==>等同于下面
struct bus_attribute   bus_file_attr = {
    .attr = {
        .name = "bus_version",  //   /sys/bus/my_bus/bus_version
        .mode = 0666,
    },
    .show = bus_version_show,
    .store = bus_version_store,
};


EXPORT_SYMBOL(mybus);  //导出,否则mydev中拿不到该变量

static int __init mybus_init(void)
{
    printk("-------^_^   %s-----------\n", __FUNCTION__);
    int ret;
    //注册一个总线
    ret = bus_register(&mybus);
    if(ret != 0)
    {
        printk("bus_register");
        return ret;
    }

    //  /sys/bus/my_bus/bus_version
    //变量名== bus_attr_bus_version
    //bus_create_file(&mybus, &bus_attr_bus_version);

    bus_create_file(&mybus, &bus_file_attr);

    return 0;

}


static void __exit mybus_exit(void)
{
    printk("-------^_^   %s-----------\n", __FUNCTION__);
    //变量名== bus_attr_bus_version
    //bus_remove_file(&mybus, &bus_attr_bus_version);
    bus_remove_file(&mybus,&bus_file_attr);
    bus_unregister(&mybus);

}
module_init(mybus_init);
module_exit(mybus_exit);
MODULE_LICENSE("GPL");

——————————————

device


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



struct mydev_info  info = {
    .name = "s5pv210_mydev",
    .addr = 0xE0000060,
    .irqno = 456,
    .gpionum = 123,
};


extern struct bus_type  mybus; //为了编译

void    mydev_release(struct device *dev)
{

}


struct device mydev = {
    .init_name = "s5pv210_devdrv", // /sys/bus/my_bus/devices/my_dev
                            // /sys/devices/my_dev
    .bus = &mybus,
    .release = mydev_release,
    .platform_data = &info,
};

static int __init mydev_init(void)
{
    printk("-------^_^   %s-----------\n", __FUNCTION__);
    int ret;
    //注册一个device到总线上
    ret = device_register(&mydev);
    if(ret < 0)
    {
        printk("device_register error");
        return ret;
    }

    return 0;

}


static void __exit mydev_exit(void)
{
    printk("-------^_^   %s-----------\n", __FUNCTION__);
    device_unregister(&mydev);

}
module_init(mydev_init);
module_exit(mydev_exit);
MODULE_LICENSE("GPL");

——————————————

driver


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


extern struct bus_type  mybus; //为了编译

int mydrv_probe (struct device *dev)
{
    printk("-------^_^   %s-----------\n", __FUNCTION__);
    //获取到device中的数据
    struct mydev_info *p = dev->platform_data;

    printk("name = %s\n", p->name);
    printk("addr = 0x%x\n", p->addr);
    printk("gpio = %d\n", p->gpionum);
    printk("irq = %d\n", p->irqno);

    return 0;
}
int mydrv_remove (struct device *dev)
{
    printk("-------^_^   %s-----------\n", __FUNCTION__);
    return 0;

}



struct device_driver mydrv = {
    .name = "s5pv210_devdrv", //  /sys/bus/my_bus/drivers/my_drv
    .bus = &mybus,
    .probe = mydrv_probe,
    .remove = mydrv_remove,
};

static int __init mydrv_init(void)
{
    printk("-------^_^   %s-----------\n", __FUNCTION__);
    int ret;
    //注册一个driver到总线上

    ret = driver_register(&mydrv);
    if(ret < 0)
    {
        printk("device_register error");
        return ret;
    }



    return 0;

}


static void __exit mydrv_exit(void)
{
    printk("-------^_^   %s-----------\n", __FUNCTION__);
    driver_unregister(&mydrv);

}
module_init(mydrv_init);
module_exit(mydrv_exit);
MODULE_LICENSE("GPL");
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值