platform设备资源与数据

目录

 

  1. 设备端资源定义
  2. 驱动端资源获取
  3. 设备端数据定义
  4. 驱动端数据获取

设备端资源定义

上一篇文章(https://blog.csdn.net/qq_37600027/article/details/100802337)中,我们定义了一个platform_device设备结构体,其中有一变量resource,他描述了platform的资源数据,资源本身由resource结构体描述。结构体原型如下所示:

struct resource {
	resource_size_t start;
	resource_size_t end;
	const char *name;
	unsigned long flags;
	struct resource *parent, *sibling, *child;
};

结构体重主要的参数为三个,start、end、flags

start:资源的起始值

end:资源的终止值

flags:资源类型

flags资源类型startend
IORESOURCE_IOIO地址空间IO起始地址IO终止地址
IORESOURCE_MEM内存内存起始地址内存终止地址
IORESOURCE_IRQ中断起始中断号终止中断号
IORESOURCE_DMADMA内存内存起始地址内存终止地址
IORESOURCE_BUS总线  

 

上篇文章中定义的platform_device如下所示:

#define PIN_BASE        32
#define CHIPSELECT_2	0x30000000
#define PIN_PC11	    (PIN_BASE + 0x40 + 11)
#define GPIO_PF9	    9
#define CH_SPI          5
#define DATA_FLAG       5

static struct resource globalmem_resoure[] = {
	[0] = {
		.start	= CHIPSELECT_2,
		.end	= CHIPSELECT_2 + 3,
		.flags	= IORESOURCE_MEM
	},
	[1] = {
		.start	= CHIPSELECT_2 + 0x44,
		.end	= CHIPSELECT_2 + 0xFF,
		.flags	= IORESOURCE_MEM
	},
	[2] = {
		.start	= PIN_PC11,
		.end	= PIN_PC11,
		.flags	= IORESOURCE_IRQ
			| IORESOURCE_IRQ_LOWEDGE | IORESOURCE_IRQ_HIGHEDGE,
	},
	[3] = {
		.start = GPIO_PF9,
		.end = GPIO_PF9,
		.flags = IORESOURCE_IO,
	},
};

struct plat_platform {
    unsigned long   iobase;     /* io base address */
    unsigned int    irq;        /* interrupt number */
    unsigned int    clk;    /* UART clock rate */
    int       flags;      /* UPF_* flags */

};

#define PORT(base, int)							\
{                                   \
    .iobase     = base,                     \
    .irq        = int,                      \
    .clk        = 1843200,                  \
    .flags      = DATA_FLAG,        \
}

static struct plat_platform platform_data[] = {
    PORT(0x3F8, 4),
    PORT(0x2F8, 3),
    PORT(0x3E8, 4),
    PORT(0x2E8, 3),
    { },
};
static struct platform_device platform_uart_device2 = {
    .name = "globalfifo",
    .id = -1,
    .resource = globalmem_resoure,
    .num_resources = ARRAY_SIZE(globalmem_resoure),
    .dev = {
        .platform_data = platform_data,
    }
};

#define PA_IIC1		0xEC20F000
#define IRQ_IIC1		((5) + 32)

static struct resource i2c_resource[] = {
    [0] = {
        .start = PA_IIC1,
        .end   = PA_IIC1 + SZ_4K - 1,
        .flags = IORESOURCE_MEM,
    },
    [1] = {
        .start = IRQ_IIC1,
        .end   = IRQ_IIC1,
        .flags = IORESOURCE_IRQ,
    },
};

struct platform_device device_i2c1 = {
    .name         = "s3c2410-i2c",
    .id       = -1,
    .num_resources    = ARRAY_SIZE(i2c_resource),
    .resource     = i2c_resource,
};

#define PA_USBDEV	(0x15200140)
#define SZ_USBDEV   SZ_1M
#define IRQ_USBD	        18
static struct resource usbgadget_resource[] = {
	[0] = {
		.start = PA_USBDEV,
		.end   = PA_USBDEV + SZ_USBDEV - 1,
		.flags = IORESOURCE_MEM,
	},
	[1] = {
		.start = IRQ_USBD,
		.end   = IRQ_USBD,
		.flags = IORESOURCE_IRQ,
	}

};

struct platform_device device_usbgadget = {
	.name		  = "s3c2410-usbgadget",
	.id		  = -1,
	.num_resources	  = ARRAY_SIZE(usbgadget_resource),
	.resource	  = usbgadget_resource,
};

struct platform_device *globaofifo_device[3] = {
    &platform_uart_device2,
    &device_i2c1,
    &device_usbgadget,
};

EXPORT_SYMBOL(globaofifo_device);

其中globalmem_resoure中定义了三种资源:IORESOURCE_IRQ、IORESOURCE_MEM、IORESOURCE_IO

IORESOURCE_IRQ:中断号是32 + 0x40 + 11

IORESOURCE_MEM:内存起始地址0x30000000为,第一块mem长度为3,第二块长度为0xff-0x44

IORESOURCE_IO:io地址为9

驱动端资源获取

这个是设备端定义的资源,那么我们如何在驱动端获取到这些数据呢

    struct resource *res_mem[2];
    struct resource *res_irq;
    struct resource *res_io;	

    res_mem[0] = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if(!res_mem[0]){
        printk("%s %d \n",__func__,__LINE__);
	} else{
        printk("%s %d start=0x%x end=0x%x\n",__func__,__LINE__,res_mem[0]->start,res_mem[0]->end);
	}

	res_mem[1] = platform_get_resource(pdev, IORESOURCE_MEM, 1);
	if(!res_mem[1]){
        printk("%s %d \n",__func__,__LINE__);
	} else{
        printk("%s %d start=0x%x end=0x%x\n",__func__,__LINE__,res_mem[1]->start,res_mem[1]->end);
	}

	res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if(!res_irq){
        printk("%s %d \n",__func__,__LINE__);
	} else{
        printk("%s %d start=0x%x end=0x%x\n",__func__,__LINE__,res_irq->start,res_irq->end);
	}

	res_io = platform_get_resource(pdev, IORESOURCE_IO, 0);
	if(!res_io){
        printk("%s %d \n",__func__,__LINE__);
	} else{
        printk("%s %d start=0x%x end=0x%x\n",__func__,__LINE__,res_io->start,res_io->end);
	}

驱动端使用函数platform_get_resource来获取资源,函数的原型如下所示:

struct resource *platform_get_resource(struct platform_device *dev,
				       unsigned int type, unsigned int num)

第一个变量为platform的设备结构体,第二个变量为资源类型,第三个变量为资源对用的编号,比如说,想要获取mem的第一个资源,函数platform_get_resource的最后一个参数为0,想要获取mem的第二个资源,函数platform_get_resource的最后一个参数为1.

	res_mem[0] = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	res_mem[1] = platform_get_resource(pdev, IORESOURCE_MEM, 1);

设备端数据定义

在设备端我们除了可以定义资源以外,还可以附加一些自定义数据,作为设备的私有数据,数据的类型我们可以自行定义

上述模块中,我们定义了自定义数据为:

struct plat_platform {
    unsigned long   iobase;     /* io base address */
    unsigned int    irq;        /* interrupt number */
    unsigned int    clk;    /* UART clock rate */
    int       flags;      /* UPF_* flags */

};
#define PORT(base, int)							\
{                                   \
    .iobase     = base,                     \
    .irq        = int,                      \
    .clk        = 1843200,                  \
    .flags      = DATA_FLAG,        \
}

static struct plat_platform platform_data[] = {
    PORT(0x3F8, 4),
    PORT(0x2F8, 3),
    PORT(0x3E8, 4),
    PORT(0x2E8, 3),
    { },
};

驱动端数据获取

数据段使用函数dev_get_platdata来获取私有数据,函数原型为

static inline void *dev_get_platdata(const struct device *dev)

函数,参数为&pdev->dev,pdev为platform_device的指针

驱动端示例代码如下所示

static struct plat_platform {
    unsigned long   iobase;     /* io base address */
    unsigned int    irq;        /* interrupt number */
    unsigned int    clk;    /* UART clock rate */
    int       flags;      /* UPF_* flags */

};    
struct plat_platform *platform_data;
    
platform_data = dev_get_platdata(&pdev->dev);
if(!platform_data){
     printk("%s %d \n",__func__,__LINE__);
} else{
     printk("%s %d iobase=0x%x irq=0x%x\n",__func__,__LINE__,platform_data->iobase,platform_data->irq);
     printk("%s %d clk=0x%x flags=0x%x\n",__func__,__LINE__,platform_data->clk,platform_data->flags);
}

上一篇:platform总线设备与驱动:https://blog.csdn.net/qq_37600027/article/details/100802337

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值