这是平台设备:
1 #include <linux/fs.h>
2 #include <linux/init.h>
3 #include <linux/delay.h>
4 #include <linux/irq.h>
5 #include <asm/irq.h>
6 #include <asm/io.h>
7 #include <linux/cdev.h>
8 #include <linux/device.h>
9 #include <linux/interrupt.h>
10 #include <linux/input.h>
11 #include <linux/bitmap.h>
12 #include <asm/gpio.h>
13 #include <linux/platform_device.h>
14
15 static struct resource led_data[] = {
16 [0] = {
17 .start = 0x56000050,
18 .end = 0x56000050 + 8 -1,
19 .flags = IORESOURCE_MEM,
20 },
21 [1] = {
22 .start = 4,
23 .end = 6,
24 .flags = IORESOURCE_IO,
25 },
26 [2] = {
27 .start = IRQ_EINT0,
28 .end = IRQ_EINT0,
29 .name = "IRQ_EINT0",
30 .flags = IORESOURCE_IRQ,
31 },
32 [3] = {
33 .start = IRQ_EINT2,
34 .end = IRQ_EINT2,
35 .name = "IRQ_EINT2",
36 .flags = IORESOURCE_IRQ,
37 },
38 [4] = {
39 .start = IRQ_EINT11,
40 .end = IRQ_EINT11,
41 .name = "IRQ_EINT11",
42 .flags = IORESOURCE_IRQ,
43 }
44 };
45
46 static struct platform_device led_device = {
47 .name = "jz2440_led",
48 .num_resources = ARRAY_SIZE(led_data),
49 .resource = led_data,
50 };
51
52 int led_dev_init(void)
53 {
54 platform_device_register(&led_device);
55 return 0;
56 }
57
58 void led_dev_exit(void)
59 {
60 platform_device_unregister(&led_device);
61 }
62
63 module_init(led_dev_init);
64 module_exit(led_dev_exit);
65
66 MODULE_LICENSE("GPL");
这是平台驱动:
1 #include <linux/module.h>
2 #include <linux/kernel.h>
3 #include <linux/fs.h>
4 #include <linux/init.h>
5 #include <linux/delay.h>
6 #include <linux/irq.h>
7 #include <asm/irq.h>
8 #include <asm/io.h>
9 #include <linux/cdev.h>
10 #include <linux/device.h>
11 #include <linux/interrupt.h>
12 #include <linux/input.h>
13 #include <linux/bitmap.h>
14 #include <asm/gpio.h>
15 #include <linux/platform_device.h>
16 #include <linux/slab.h>
17 #include <linux/sched.h>
18
19 static volatile unsigned long *ledcon;
20 static volatile unsigned long *leddat;
21
22 static int pin_nums;
23 static int pin_start,pin_end;
24
25 static struct resource *pRes;
26 static unsigned long *pname;
27 static struct resource *irq;
28
29 static struct class *led_class;
30 static struct timer_list led_timer;
31
32 static int led_open(struct inode *inode, struct file *file)
33 {
34 int i;
35 for(i = 0; i < pin_nums; i++){
36 *ledcon &= ~(3 << (pin_start + i) * 2);
37 *leddat &= ~(1 << (pin_start + i));
38 *ledcon |= (1 << (pin_start + i) * 2);
39 }
40
41 return 0;
42 }
43
44 static struct file_operations led_fops = {
45 .owner = THIS_MODULE,
46 .open = led_open,
47
48 };
49
50 static irqreturn_t led_irq(int dat, void *pvoid)
51 {
52 pRes = (struct resource *)pvoid;
53 mod_timer(&led_timer, jiffies + HZ/100);
54
55 return IRQ_HANDLED;
56 }
57
58 static int STRCMP(const char *str1,const char *str2)
59 {
60 while((*str1++) == (*str2++)){
61 if(*str1 == '\0' && *str2 == '\0')
62 return 0;
63 else if(*str1 == '\0' || *str2 == '\0')
64 break;
65 }
66 return -1;
67 }
68
69 static int GetPinNum(struct resource *pres)
70 {
71 int i;
72 for(i = 0; i < pin_nums; i++){
73 if(0 == STRCMP(pres->name,(char *)*(pname + i))){
74 return i;
75 }
76 }
77 return -1;
78 }
79
80 static void led_time_function(unsigned long dat)
81 {
82
83 int ls = GetPinNum(pRes);
84 if(ls >= 0)
85 *leddat ^= (1 << (pin_start + ls));
86 }
87
88
89 static int major;
90 static int led_probe(struct platform_device *led_dev)
91 {
92 int i;
93 struct resource *reg;
94 struct resource *led_pins;
95
96 major = register_chrdev(0,"led",&led_fops);
97 led_class = class_create(THIS_MODULE, "led");
98 device_create(led_class,NULL,MKDEV(major,0),NULL,"led0");
99 reg = platform_get_resource(led_dev,IORESOURCE_MEM,0);
100 led_pins = platform_get_resource(led_dev,IORESOURCE_IO,0);
101 ledcon = ioremap(reg->start,reg->end - reg->start + 1);
102 leddat = ledcon + 1;
103 pin_start = led_pins->start;
104 pin_end = led_pins->end;
105 pin_nums = led_pins->end - led_pins->start + 1;
106 pname = (unsigned long *)kmalloc(pin_nums * sizeof(unsigned long), GFP_KERNEL); //pin_nums个指针
107 for(i = 0; i < pin_nums; i++){
108 irq = platform_get_resource(led_dev,IORESOURCE_IRQ,i);
109 request_irq(irq->start, led_irq, IRQ_TYPE_EDGE_BOTH, irq->name, irq);
110 *(pname + i)= (unsigned long)irq->name;
111 }
112
113 init_timer(&led_timer);
114 led_timer.function = led_time_function;
115 add_timer(&led_timer);
116
117 return 0;
118 }
119
120 static int led_remove(struct platform_device *led_dev)
121 {
122 int i;
123 del_timer(&led_timer);
124 for(i = 0; i < pin_nums; i++){
125 irq = platform_get_resource(led_dev,IORESOURCE_IRQ,i);
126 free_irq(irq->start,irq);
127 }
128 kfree(pname);
129 iounmap(ledcon);
130 device_destroy(led_class, MKDEV(major,0));
131 class_destroy(led_class);
132 unregister_chrdev(major, "led");
133
134 return 0;
135 }
136
137 static struct platform_driver led_drv = {
138 .driver = {
139 .name = "jz2440_led",
140 .owner = THIS_MODULE,
141 },
142 .probe = led_probe,
143 .remove = __devexit_p(led_remove),
144 };
145
146 static int led_init(void)
147 {
148 platform_driver_register(&led_drv);
149 return 0;
150 }
151
152 static void led_exit(void)
153 {
154 platform_driver_unregister(&led_drv);
155 }
156
157 module_init(led_init);
158 module_exit(led_exit);
159
160 MODULE_LICENSE("GPL");
这是应用程序:
1 #include <sys/types.h>
2 #include <sys/stat.h>
3 #include <fcntl.h>
4
5 int main(int argc,char **argv)
6 {
7 int fd = open("/dev/led0",O_RDWR);
8 if(fd < 0){
9 return -1;
10 }
11
12 while(1);
13 return 0;
14 }