平台总线专题3 -作业

总线实现匹配实验

device设备代码 exynos4412_led_dev.c

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

#define GPIO_BASE_ADDRESS 0x11400000
#define GPX1_CON 0x0C20
#define GPX1_SIZE 24
#define GPX2_CON 0x0C40
#define GPX2_SIZE 24
#define GPF3_CON 0x01E0
#define GPX3_SIZE 24

struct resource	led_resource[] = {
	[0] = {
		.start = GPIO_BASE_ADDRESS + GPX2_CON,
		.end = GPIO_BASE_ADDRESS + GPX2_CON + GPX2_SIZE - 1,
		.name = "exynos4412_dev_led2",
		.flags = IORESOURCE_MEM,
	},

	[1] = {
		.start = GPIO_BASE_ADDRESS + GPX1_CON,
		.end = GPIO_BASE_ADDRESS + GPX1_CON + GPX1_SIZE - 1,
		.name = "exynos4412_dev_led3",
		.flags = IORESOURCE_MEM,
	},

	//中断资源描述,这里只是举例,在实际led驱动中并没有使用到该中断
	[2] = {
		.start = 73,	//irq中断号 
		.end = 73,
		.name = "exynos4412_dev_irq0",
		.flags = IORESOURCE_IRQ,
	},

};


struct platform_device dev_led = {
	.name = "exynos4412_dev_led",
	.id = -1,
	.num_resources = ARRAY_SIZE(led_resource),
	.resource = led_resource,
};

static int __init led_dev_init(void)
{

	return platform_device_register(&dev_led);
		
}

static void __exit led_dev_exit(void)
{
	platform_device_unregister(&dev_led);
}


module_init(led_dev_init);
module_exit(led_dev_exit);
MODULE_LICENSE("GPL");

driver驱动代码 exynos4412_led_drv.c

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


int exynos4412_led_drv_probe(struct platform_device *pdev) //匹配成功之后被调用的函数
{
	printk("--------%s----------\n",__FUNCTION__);

	return 0;
}
int exynos4412_led_drv_remove(struct platform_device *pdev)//device移除的时候调用的函数
{
	printk("--------%s----------\n",__FUNCTION__);
	
	return 0;
}

struct platform_device_id id_table[] = {	//id列表 将驱动支持的设备都列出来
	[0] = {
		.name = "exynos4412_dev_led",	//用于匹配dev的名字
		.driver_data = 0x1111,
	},
	
	[1] = {
		.name = "exynos2410_dev_led",
		.driver_data = 0x2222,
	},
	
	[2] = {
		.name = "exynos6410_dev_led",
		.driver_data = 0x3333,
	},
	
	[3] = {
		.name = "exynos6412_dev_led",
		.driver_data = 0x4444,
	},
};

struct platform_driver pdrv = {
	.probe = exynos4412_led_drv_probe,
	.remove = exynos4412_led_drv_remove,
	.driver = {
			.name = "SAMSUNG_drv_led", 	//这个名字是在sys/bus/platform/drivers下显示的驱动名 
										//也可用于匹配dev 但是优先级低于下面的id_table
		},
	.id_table = id_table,	
};

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

void __exit exynos4412_led_drv_exit(void)
{
	printk("--------%s----------\n",__FUNCTION__);
	
	platform_driver_unregister(&pdrv);
}



module_init(exynos4412_led_drv_init);
module_exit(exynos4412_led_drv_exit);
MODULE_LICENSE("GPL");

makefile代码

ROOTFS_DIR = /home/linux/Level11

#APP_NAME = key_test

CROSS_COMPILE = arm-none-linux-gnueabi-
CC = $(CROSS_COMPILE)gcc

ifeq ($(KERNELRELEASE), )

KERNEL_DIR = /home/linux/Level10/day6/linux-5.4.79
CUR_DIR = $(shell pwd)

all :
		make -C  $(KERNEL_DIR) M=$(CUR_DIR) modules -j6 ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi-
		#$(CC) $(APP_NAME).c -o $(APP_NAME)

clean :
		make -C  $(KERNEL_DIR) M=$(CUR_DIR) clean
		#rm $(APP_NAME) ./1/$(APP_NAME)
		clear

install:
		#cp -raf  *.ko  $(APP_NAME)   ./1/
		cp -raf  *.ko  ./1/
		
else
obj-m += exynos4412_led_dev.o
obj-m += exynos4412_led_drv.o
#obj-m += mydrv.o
endif

效果展示

[root@farsight ]# insmod exynos4412_led_dev.ko
[   35.847814] exynos4412_led_dev: loading out-of-tree module taints kernel.
[root@farsight ]# insmod exynos4412_led_drv.ko
[   42.539908] --------exynos4412_led_drv_init----------
[   42.543801] --------exynos4412_led_drv_probe----------
[root@farsight ]# cd sys/
[root@farsight sys]# ls
block     class     devices   fs        module
bus       dev       firmware  kernel    power
[root@farsight sys]# cd bus/
[root@farsight drivers]# cd SAMSUNG_drv_led/
[root@farsight SAMSUNG_drv_led]# ls
bind                module              unbind
exynos4412_dev_led  uevent