平台总线第一天①

驱动层

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

int led_pdrv_probe(struct platform_device *pdev)//匹配成功之后调用这个函数,默认传参匹配成功之后的pdev
{
	struct resource * addr_res1, *addr_res2;
	struct resource * irq_res;
	int irqno;
 	printk("---------------%s------------------\n",__FUNCTION__);

    //获取平台资源
    //参数1:pdev对象
    //参数2:资源的类型
    //参数3:资源的编号,同一种类型,从0开始编号
	addr_res1 = platform_get_resource(pdev,IORESOURCE_MEM,0);
	printk("addr_res1: start = 0x%x\n",addr_res1->start);

	addr_res2 = platform_get_resource(pdev,IORESOURCE_MEM,1);
	printk("addr_res2: start = 0x%x\n",addr_res2->start);

    //方法一
	irq_res = platform_get_resource(pdev,IORESOURCE_IRQ,0);
	printk("irq_res: start = %d\n",irq_res->start);
	printk("irq_res: end = %d\n",irq_res->end);
	//方法二
	irqno = platform_get_irq(pdev,0);
	printk("irqno = %d\n",irqno);	//获取的是中段资源的编号
	return 0;
}

int led_pdrv_remove(struct platform_device *pdev)
{
	printk("---------------%s------------------\n",__FUNCTION__);
	return 0;
}

const struct platform_device_id led_id_table[] = {
	{"s5pv210_led", 0x1122},
	{"s3c2410_led", 0x1234},
	{"s3c6410_led", 0x2233},
};

struct platform_driver led_pdrv = {
 	.probe = led_pdrv_probe,
	.remove = led_pdrv_remove,
	.driver = {
		.name = "samsung led_drv",//自定义,但是一定要有,没有id_table则用这个名字和pdev匹配,--- ls /sys/bus/platform/drivers/下创建同名目录
	},
	.id_table = led_id_table,
};


static int __init led_pdrv_init(void)
{
	printk("--------------%s--------------\n",__FUNCTION__);
	return platform_driver_register(&led_pdrv);
}

static void __exit led_pdrv_exit(void)
{
	printk("--------------%s--------------\n",__FUNCTION__);
	platform_driver_unregister(&led_pdrv);

}
module_init(led_pdrv_init);
module_exit(led_pdrv_exit);
MODULE_LICENSE("GPL");


设备层

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

#define LED_GPC0_CONF 0xe0200060
#define LED_GPC0_SIZE 8

struct resource led_resource[] = {
	[0] = {
		.start = LED_GPC0_CONF,
		.end = LED_GPC0_CONF + LED_GPC0_SIZE - 1,
		.flags = IORESOURCE_MEM,
	},
	//以下是演示代码
	[1] = {
		.start = 0x1122,
		.end = 0x1122,
		.flags = IORESOURCE_IRQ,
	},
	[2] = {
		.start = 0xe0200160,
		.end = 0xe0200160 + 8 - 1,
		.flags = IORESOURCE_MEM,
	},
};

//可以不用实现5,但是一定要有,因为卸载的时候会调用
void led_pdev_release(struct device *dev)
{
	printk("--------------%s--------------\n",__FUNCTION__);
}


struct platform_device led_pdev = {
	.name = "s5pv210_led",
	.id = -1,
	.dev = {
		.release = led_pdev_release,
	},
	.num_resources = ARRAY_SIZE(led_resource),
	.resource = led_resource,

};

static int __init led_pdev_init(void)
{
	printk("--------------%s--------------\n",__FUNCTION__);
	return platform_device_register(&led_pdev);
}

static void __exit led_pdev_exit(void)
{
	printk("--------------%s--------------\n",__FUNCTION__);
	platform_device_unregister(&led_pdev);

}
module_init(led_pdev_init);
module_exit(led_pdev_exit);
MODULE_LICENSE("GPL");

驱动装载顺序无要求,都会先执行init函数,第二个驱动装载完成后,两者会进行匹配,匹配成功后执行probe方法。

装载过程如下:

[root@farsight /drv_module]# insmod plat_led_dev.ko
--------------led_pdev_init--------------
[root@farsight /drv_module]# insmod plat_led_drv.ko
--------------led_pdrv_init--------------
---------------led_pdrv_probe------------------
addr_res1: start = 0xe0200060
addr_res2: start = 0xe0200160
irq_res: start = 4386
irq_res: end = 4386
irqno = 4386

[root@farsight /drv_module]# insmod plat_led_drv.ko
--------------led_pdrv_init--------------
[root@farsight /drv_module]# insmod plat_led_dev.ko
--------------led_pdev_init--------------
---------------led_pdrv_probe------------------
addr_res1: start = 0xe0200060
addr_res2: start = 0xe0200160
irq_res: start = 4386
irq_res: end = 4386
irqno = 4386

卸载过程要按照顺序

[root@farsight /drv_module]# rmmod plat_led_dev
--------------led_pdev_exit--------------
---------------led_pdrv_remove------------------
--------------led_pdev_release--------------
[root@farsight /drv_module]# rmmod plat_led_drv
--------------led_pdrv_exit--------------

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值