概述
从platform中提取设备信息
函数接口
include/linux/platform_device.h
1.提取IO资源
struct resource *platform_get_resource(struct platform_device *,
unsigned int, unsigned int);
2.提取中断资源
/*
* 功能:提取中断资源
* 输入参数:struct platform_device:platform设备句柄
* unsigned int:中断资源序号
* 返回值:成功:中断号 失败;负数
*/
int platform_get_irq(struct platform_device *, unsigned int);
3.提取私有数据:
void *platform_get_drvdata(const struct platform_device *pdev)
范例
驱动端
static int demo_probe(struct platform_device *pdev)
{
int irq;
struct resource *addr;
struct privatedata *priv;
printk(KERN_INFO "%s : %s : %d - entry.\n", __FILE__, __func__, __LINE__);
priv = dev_get_platdata(&pdev->dev);//从设备树中提取私有数据
if(priv){
printk(KERN_INFO "%x : %s \n", priv->val, priv->str);
}
/*从设备树中提取IO资源*/
addr = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if(addr){
printk(KERN_INFO "0: %x : %d \n", addr->start, resource_size(addr));
}
addr = platform_get_resource(pdev, IORESOURCE_MEM, 1);
if(addr){
printk(KERN_INFO "1: %x : %d \n", addr->start, resource_size(addr));
}
addr = platform_get_resource(pdev, IORESOURCE_MEM, 2);
if(!addr){
printk(KERN_INFO "No 2 resource\n");
}
/*从设备树中提取中断资源*/
irq = platform_get_irq(pdev, 0);
if(0 > irq){
return irq;
}else{
printk(KERN_INFO "irq 0: %d \n", irq);
}
irq = platform_get_irq(pdev, 1);
if(0 > irq){
return irq;
}else{
printk(KERN_INFO "irq 0: %d \n", irq);
}
irq = platform_get_irq(pdev, 2);
if(0 > irq){
printk(KERN_INFO "No 2 irq\n");
}
return 0;
}
static int demo_remove(struct platform_device *pdev)
{
printk(KERN_INFO "%s : %s : %d - leave.\n", __FILE__, __func__, __LINE__);
return 0;
}
static struct platform_device_id tbl[] = {
{"demo0"},
{"demo1"},
{},
};
MODULE_DEVICE_TABLE(platform, tbl);
//1. alloc obj
static struct platform_driver drv = {
.probe = demo_probe,
.remove = demo_remove,
.driver = {
.name = "demo",
},
.id_table = tbl,
};
static int __init drv_init(void)
{
//get command and pid
printk(KERN_INFO "(%s:pid=%d), %s : %s : %d - entry.\n",
current->comm, current->pid, __FILE__, __func__, __LINE__);
return platform_driver_register(&drv);
}
static void __exit drv_exit(void)
{
//get command and pid
printk(KERN_INFO "(%s:pid=%d), %s : %s : %d - leave.\n",
current->comm, current->pid, __FILE__, __func__, __LINE__);
platform_driver_unregister(&drv);
}
module_init(drv_init);
module_exit(drv_exit);
//3. register obj
module_platform_driver(drv);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Farsight");
MODULE_DESCRIPTION("Demo for kernel module");
设备端
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <asm/current.h>
#include <linux/sched.h>
#include <linux/ioport.h>
#include <linux/platform_device.h>
#include "../private.h"
static struct privatedata priv = {
.val = 0x12345678,
.str = "hello world",
};
struct resource res[] = {
[0] = {
.start = 0x10000000,
.end = 0x20000000-1,
.flags = IORESOURCE_MEM
},
[1] = {
.start = 10,
.flags = IORESOURCE_IRQ
},
[2] = DEFINE_RES_MEM(0x20000000, 1024),
[3] = DEFINE_RES_IRQ(11),
};
static void dev_release(struct device *dev)
{
printk(KERN_INFO "(%s:pid=%d), %s : %s : %d - leave.\n",
current->comm, current->pid, __FILE__, __func__, __LINE__);
}
static struct platform_device demoobj = {
.name = "demo1",
.id = 0,
.dev = {
.platform_data = &priv,
.release = dev_release,
},
.num_resources = ARRAY_SIZE(res),
.resource = res,
};
#if 0
static int __init device_init(void)
{
printk(KERN_INFO "(%s:pid=%d), %s : %s : %d - leave.\n",
current->comm, current->pid, __FILE__, __func__, __LINE__);
return platform_device_register(&demoobj);
}
static void __exit device_exit(void)
{
printk(KERN_INFO "(%s:pid=%d), %s : %s : %d - leave.\n",
current->comm, current->pid, __FILE__, __func__, __LINE__);
platform_device_unregister(&demoobj);
}
module_init(device_init);
module_exit(device_exit);
#else
module_platform_device(demoobj);
#endif
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Farsight");
MODULE_DESCRIPTION("Demo for kernel module");