参考源码:x3399_nougat_industry
驱动路径:kernel\drivers\leds\leds-gpio.c
static struct platform_driver gpio_led_driver = {
.probe = gpio_led_probe,
.remove = gpio_led_remove,
.shutdown = gpio_led_shutdown,
.driver = {
.name = "leds-gpio",
.of_match_table = of_gpio_leds_match,
},
};
module_platform_driver(gpio_led_driver);
module_platform_driver(xxx)宏定义在kernel\include\linux\platform_device.h这样定义
/* module_platform_driver() - Helper macro for drivers that don't do
* anything special in module init/exit. This eliminates a lot of
* boilerplate. Each module may only use this macro once, and
* calling it replaces module_init() and module_exit()
*/
#define module_platform_driver(__platform_driver) \
module_driver(__platform_driver, platform_driver_register, \
platform_driver_unregister)
module_driver 在kernel\include\linux\device.h定义如下:
/**
* module_driver() - Helper macro for drivers that don't do anything
* special in module init/exit. This eliminates a lot of boilerplate.
* Each module may only use this macro once, and calling it replaces
* module_init() and module_exit().
*
* @__driver: driver name
* @__register: register function for this driver type
* @__unregister: unregister function for this driver type
* @...: Additional arguments to be passed to __register and __unregister.
*
* Use this macro to construct bus specific macros for registering
* drivers, and do not use it on its own.
*/
#define module_driver(__driver, __register, __unregister, ...) \
static int __init __driver##_init(void) \
{ \
return __register(&(__driver) , ##__VA_ARGS__); \
} \
module_init(__driver##_init); \
static void __exit __driver##_exit(void) \
{ \
__unregister(&(__driver) , ##__VA_ARGS__); \
} \
module_exit(__driver##_exit);
可以看出这个模块是在platform总线上注册,模块包含有驱动的注册与驱动的卸载。
非热插拔平台设备可以使用这种方法,以便使用probe()和 它的支持可能存在于__init节中,以保存运行时内存。
/*
* use a macro to avoid include chaining to get THIS_MODULE
*/
#define platform_driver_register(drv) \
__platform_driver_register(drv, THIS_MODULE)
extern int __platform_driver_register(struct platform_driver *,
struct module *);
extern void platform_driver_unregister(struct platform_driver *);
platform device 描述
struct platform_device {
const char *name;
int id;
bool id_auto;
struct device dev;
u32 num_resources;
struct resource *resource;
const struct platform_device_id *id_entry;
char *driver_override; /* Driver name to force a match */
/* MFD cell pointer */
struct mfd_cell *mfd_cell;
/* arch specific additions */
struct pdev_archdata archdata;
};
platform_driver 描述
struct platform_driver {
int (*probe)(struct platform_device *);
int (*remove)(struct platform_device *);
void (*shutdown)(struct platform_device *);
int (*suspend)(struct platform_device *, pm_message_t state);
int (*resume)(struct platform_device *);
struct device_driver driver;
const struct platform_device_id *id_table;
bool prevent_deferred_probe;
};
struct device_driver driver;描述
struct device_driver {
const char *name;
struct bus_type *bus;
struct module *owner;
const char *mod_name; /* used for built-in modules */
bool suppress_bind_attrs; /* disables bind/unbind via sysfs */
enum probe_type probe_type;
const struct of_device_id *of_match_table;
const struct acpi_device_id *acpi_match_table;
int (*probe) (struct device *dev);
int (*remove) (struct device *dev);
void (*shutdown) (struct device *dev);
int (*suspend) (struct device *dev, pm_message_t state);
int (*resume) (struct device *dev);
const struct attribute_group **groups;
const struct dev_pm_ops *pm;
struct driver_private *p;
};
platform_device和platform_driver 里面的驱动名称要一样 才能适配的上,否者probe不执行。
相当于:
static int __init gpio_led_driver_init(void)
{
printk("welcome_to_gpio_led_driver_init\n");
return platform_driver_register(&gpio_led_driver);
}
static void __exit gpio_led_driver_exit(void)
{
platform_driver_unregister(&gpio_led_driver);
}
module_init(gpio_led_driver_init);
module_exit(gpio_led_driver_exit);
如果驱动注册成功:/sys/bus/platform/drivers 会生成对应的驱动名称,这里的驱动名称是leds-gpio。
查看驱动打印出现:welcome_to_gpio_led_driver_init 说明驱动有编译生效。
[ 4.203839] dwmmc_rockchip fe320000.dwmmc: 1 slots initialized
[ 4.204389] sdhci-pltfm: SDHCI platform and OF driver helper
[ 4.206494] sdhci-arasan fe330000.sdhci: No vmmc regulator found
[ 4.206530] sdhci-arasan fe330000.sdhci: No vqmmc regulator found
[ 4.232811] mmc1: SDHCI controller on fe330000.sdhci [fe330000.sdhci] using ADMA
[ 4.233570] welcome_to_gpio_led_driver_init
[ 4.234975] ===========================zdong=====================
[ 4.236837] hidraw: raw HID events driver (C) Jiri Kosina
[ 4.239521] usbcore: registered new interface driver usbhid
[ 4.239539] usbhid: USB HID core driver
[ 4.239698] inv_mpu_iio: inv_mpu_init:746
[ 4.240320] ashmem: initialized
[ 4.243849] ff100000.saradc supply vref not found, using dummy regulator
[ 4.245127] rknandbase v1.1 2016-11-08
关于设备名的查看,请查看我另一篇博客: