platform设备的静态注册

在上一篇博文中,设备和驱动都是通过手动加载的(调试的时候采用这种方式),但有些情况下,内核已经为设备注册到platform总线上,只需要我们注册驱动就可以了。接下来介绍一下设备的静态注册。

先看一下内核是从哪里获取静态注册的platform_device

内核是从../linux-2.6.36/arch/arm/mach-s3c64xx/mach-mini6410.c文件中获取到platform_device的信息:

362 static struct platform_device *mini6410_devices[] __initdata = {
363     &globalfifo_device,
364     &s3c_device_led,                                                       //add by wenhui
365 #ifdef CONFIG_MINI6410_SD_CH0
366     &s3c_device_hsmmc0,
367 #endif
368 #ifdef CONFIG_MINI6410_SD_CH1
369     &s3c_device_hsmmc1,
370 #endif
371     &s3c_device_i2c0,
372 #ifdef CONFIG_S3C_DEV_I2C1
373     &s3c_device_i2c1,
374 #endif
375     &s3c_device_nand,
376     &s3c_device_fb,

...
}

可以看到,这个数组存放着所有静态注册的 platform_device信息,我按照它们的格式,也添加了一个 s3c_device_led结构体指针在这个数组中。接下来就要看看是在哪里定义了。结果发现在../linux-2.6.36/arch/arm/plat-samsung 中发现



每个设备的资源都是以一个单独的文件来包含的 所以我就可以照样画葫芦新建一个dev-led.c

1> cp dev-wdt.c dev-led.c ; vim dev-led.c 经修改后

  1 /* linux/arch/arm/plat-samsung/dev-led.c
  2  *
  3  * Copyright (c) 2004 Simtec Electronics
  4  *  Ben Dooks <[email protected]>
  5  *
  6  * S3C series device definition for the watchdog timer
  7  *
  8  * This program is free software; you can redistribute it and/or modify
  9  * it under the terms of the GNU General Public License version 2 as
 10  * published by the Free Software Foundation.
 11 */
 12 
 13 #include <linux/kernel.h>
 14 #include <linux/platform_device.h>
 15 
 16 #include <mach/irqs.h>
 17 #include <mach/map.h>
 18 
 19 #include <plat/devs.h>
 20 
 21 static struct resource s3c_led_resource[1] = {
 22     [0] = {
 23         .start  = 0x7F008800,
 24         .end    = 0X7F00880C,
 25         .flags  = IORESOURCE_MEM,
 26     },
 27 };
 28 
 29 struct platform_device s3c_device_led = {
 30         .name   = "plat-led",
 31         .id     = -1,
 32         .num_resources  = 1,
 33         .resource = s3c_led_resource,
 34 };
 35 EXPORT_SYMBOL(s3c_device_led);

2>在Makefile 中 添加编译选项 50行

 45 obj-$(CONFIG_S3C_DEV_USB_HOST)  += dev-usb.o
 46 obj-$(CONFIG_S3C_DEV_USB_HSOTG) += dev-usb-hsotg.o
 47 obj-$(CONFIG_S3C_DEV_WDT)   += dev-wdt.o
 48 
 49 #add by wenhui for platform led 
 50 obj-y += dev-led.o
 51 
 52 obj-$(CONFIG_S3C_DEV_NAND)  += dev-nand.o

3>在../linux-2.6.36/arch/arm/plat-samsung/include/plat/devs.h中增加

platform_match函数是通过包含该文件后读取里面的platform_device信息来跟platform_driver匹配。

    所以,必须在这里加上一行代码:)

 42 extern struct platform_device s3c_device_fb;
 43 extern struct platform_device s3c_device_ohci;
 44 extern struct platform_device s3c_device_lcd;
 45 extern struct platform_device s3c_device_wdt;
 46 
 47 extern struct platform_device s3c_device_led; //add by wenhui
 48 
 49 extern struct platform_device s3c_device_i2c0;

修改完上面的几个文件后,重新编译内核后就实现了静态注册 platform设备,在内核启动时会自动注册 s3c_device_led。所以,我们只需要注册 platform驱动就可以了

以下是驱动的代码:

  //driver.c
  1 #include<linux/module.h>
  2 #include<linux/init.h>
  3 
  4 #include<linux/platform_device.h>
  5 #include<asm/io.h>
  6 #include<asm/sizes.h>
  7 
  8 struct plat_led{
  9     unsigned long phys, virt;
 10     unsigned long gpkcon1, gpkdat, gpkup;
 11     unsigned long reg;
 12 };
 13 
 14 struct plat_led pled;
 15 
 16 int led_driver_probe(struct platform_device *pdev)
 17 {
 18     printk("led_driver_probe\n");
 19     pled.phys = pdev->resource[0].start; /*0x7F008800*/
 20 
 21 /*不加强制性转换 会报 warning: assignment makes integer from pointer without a cast*/
 22     pled.virt = (unsigned long)ioremap(pled.phys, SZ_4K);
 23 
 24     pled.gpkcon1 = pled.virt + 0x4;
 25     pled.gpkdat = pled.virt + 0x8;
 26     pled.gpkup  = pled.virt + 0xc;
 27 
 28     //config
 29     pled.reg = ioread32(pled.gpkcon1); /*GPK4 LED1*/
 30     pled.reg &= ~(0xe<<0);           /*0001 output*/
 31     pled.reg |= (0x1<<0);
 32     iowrite32(pled.reg, pled.gpkcon1);
 33 
 34     //up
 35     pled.reg = ioread32(pled.gpkup);
 36     pled.reg &= ~(0x3<<8);           /*disable pull-up/down*/
 37     iowrite32(pled.reg, pled.gpkup);
 38 
 39     //dat
 40     pled.reg = ioread32(pled.gpkdat);
 41     pled.reg &= ~(0x1<<8);            /*low */
 42     iowrite32(pled.reg, pled.gpkdat);
 43 
 44     printk("led on\n");
 45     return 0;
 46 }
 47 
 48 int led_driver_remove(struct platform_device *pdev)
 49 {
 50     printk("led_driver_remove\n");
 51     pled.reg = ioread32(pled.gpkdat);
 52     pled.reg |= (0x1<<8);
 53     iowrite32(pled.reg, pled.gpkdat);
 54 
 55     printk("led off\n");
 56     return 0;
 57 }
 58 
 59 struct platform_driver s3c_led_drv = {
 60     .probe = led_driver_probe,
 61     .remove = led_driver_remove,
 62     .driver = {
 63         .name = "plat-led", /*在/sys/ 中的驱动目录名字*/
 64     },
 65 };
 66 
 67 static int __init plat_led_init(void)
 68 {
 69     int ret;
 70     ret = platform_driver_register(&s3c_led_drv);
 71     if(ret){
 72         printk("led register failed!\n");
 73         return ret;
 74     }
 75     printk("led driver init\n");
 76 
 77     return ret;
 78 }
 79 
 80 static void __exit plat_led_exit(void)
 81 {
 82     platform_driver_unregister(&s3c_led_drv);
 83     printk("led driver exit");
 84 }
 85 
 86 module_init(plat_led_init);
 87 module_exit(plat_led_exit);
 88 
 89 MODULE_LICENSE("GPL");
 90 MODULE_AUTHOR("wenhui");                                                                                                               


   









你可能感兴趣的:(c,struct,Module,Integer,makefile,resources)