当前位置: 首页 > news >正文

泰安市网站建设公司广告发布平台

泰安市网站建设公司,广告发布平台,上海疫情最新公布数据,深圳网站建设联系电话上一篇中,我们分析了request_mem_region的实现。 现在来看看board文件中是如何配置ssi和esai的。 现在做的项目是基于freescale平台的。 所以代码也是基于该平台代码进行分析。 先看看ssi。 首先定义了一个mxc_audio_platform_data结构体和一个platform_device结…

上一篇中,我们分析了request_mem_region的实现。
现在来看看board文件中是如何配置ssi和esai的。

现在做的项目是基于freescale平台的。
所以代码也是基于该平台代码进行分析。

先看看ssi。

首先定义了一个mxc_audio_platform_data结构体和一个platform_device结构体:

static struct mxc_audio_platform_data XXXX_data[] = {{.ssi_num = 1,.src_port = 2,.ext_port = 5,.init = xxxx_init0,.hp_gpio = -1,},
};static struct platform_device xxxx_device = {.name = "xxxx",
};/** This struct is to define the number of SSIs on a platform,* DAM source port config, DAM external port config,* regulator names, and other stuff audio needs.*/
struct mxc_audio_platform_data {int ssi_num;int src_port;int ext_port;int intr_id_hp;int ext_ram;struct clk *ssi_clk[2];int hp_gpio;int hp_active_low;	/* headphone irq is active low */int mic_gpio;int mic_active_low;	/* micphone irq is active low */int sysclk;const char *codec_name;int (*init) (void);	/* board specific init */int (*amp_enable) (int enable);int (*clock_enable) (int enable);int (*finit) (void);	/* board specific finit */void *priv;		/* used by board specific functions */
};struct platform_device {const char	* name;int		id;struct device	dev;u32		num_resources;struct resource	* resource;const struct platform_device_id	*id_entry;/* MFD cell pointer */struct mfd_cell *mfd_cell;/* arch specific additions */struct pdev_archdata	archdata;
};


然后调用mxc_register_device将上面定义的两个结构体进行注册。
mxc_register_device的实现:

int __init mxc_register_device(struct platform_device *pdev, void *data)
{int ret;// data即是前面的XXXX_data。pdev即是前面的xxxx_devicepdev->dev.platform_data = data;/×
/*** platform_device_register - add a platform-level device* @pdev: platform device we're adding*/
int platform_device_register(struct platform_device *pdev)
{device_initialize(&pdev->dev);return platform_device_add(pdev);
}/*** device_initialize - init device structure.* @dev: device.** This prepares the device for use by other layers by initializing* its fields.* It is the first half of device_register(), if called by* that function, though it can also be called separately, so one* may use @dev's fields. In particular, get_device()/put_device()* may be used for reference counting of @dev after calling this* function.** NOTE: Use put_device() to give up your reference instead of freeing* @dev directly once you have called this function.*/
void device_initialize(struct device *dev)
{dev->kobj.kset = devices_kset;kobject_init(&dev->kobj, &device_ktype);INIT_LIST_HEAD(&dev->dma_pools);mutex_init(&dev->mutex);lockdep_set_novalidate_class(&dev->mutex);spin_lock_init(&dev->devres_lock);INIT_LIST_HEAD(&dev->devres_head);// device_pm_init - Initialize the PM-related part of a device object.device_pm_init(dev);set_dev_node(dev, -1);
}static inline void set_dev_node(struct device *dev, int node)
{dev->numa_node = node;
}/*** platform_device_add - add a platform device to device hierarchy* @pdev: platform device we're adding** This is part 2 of platform_device_register(), though may be called* separately _iff_ pdev was allocated by platform_device_alloc().*/
int platform_device_add(struct platform_device *pdev)
{int i, ret = 0;if (!pdev)return -EINVAL;if (!pdev->dev.parent)pdev->dev.parent = &platform_bus;pdev->dev.bus = &platform_bus_type;// 前面只指定了pdev->name没有指定pdev->idif (pdev->id != -1)dev_set_name(&pdev->dev, "%s.%d", pdev->name,  pdev->id);elsedev_set_name(&pdev->dev, "%s", pdev->name);for (i = 0; i < pdev->num_resources; i++) {struct resource *p, *r = &pdev->resource[i];if (r->name == NULL)r->name = dev_name(&pdev->dev);// 上一篇中,已经分析过resource的父子关系p = r->parent;if (!p) {if (resource_type(r) == IORESOURCE_MEM)p = &iomem_resource;else if (resource_type(r) == IORESOURCE_IO)p = &ioport_resource;}// 将resource添加到resource tree中。/×
/*** insert_resource - Inserts a resource in the resource tree* @parent: parent of the new resource* @new: new resource to insert** Returns 0 on success, -EBUSY if the resource can't be inserted.*/
int insert_resource(struct resource *parent, struct resource *new)
{struct resource *conflict;/×
/*** insert_resource_conflict - Inserts resource in the resource tree* @parent: parent of the new resource* @new: new resource to insert** Returns 0 on success, conflict resource if the resource can't be inserted.** This function is equivalent to request_resource_conflict when no conflict* happens. If a conflict happens, and the conflicting resources* entirely fit within the range of the new resource, then the new* resource is inserted and the conflicting resources become children of* the new resource.*/
struct resource *insert_resource_conflict(struct resource *parent, struct resource *new)
{struct resource *conflict;write_lock(&resource_lock);conflict = __insert_resource(parent, new);write_unlock(&resource_lock);return conflict;
}×/conflict = insert_resource_conflict(parent, new);return conflict ? -EBUSY : 0;
}×/if (p && insert_resource(p, r)) {printk(KERN_ERR"%s: failed to claim resource %d\n",dev_name(&pdev->dev), i);ret = -EBUSY;goto failed;}}pr_debug("Registering platform device '%s'. Parent at %s\n",dev_name(&pdev->dev), dev_name(pdev->dev.parent));ret = device_add(&pdev->dev);if (ret == 0)return ret;failed:while (--i >= 0) {struct resource *r = &pdev->resource[i];unsigned long type = resource_type(r);if (type == IORESOURCE_MEM || type == IORESOURCE_IO)release_resource(r);}return ret;
}×/ret = platform_device_register(pdev);if (ret)pr_debug("Unable to register platform device '%s': %d\n",pdev->name, ret);return ret;
}


接下来定义了imx_add_platform_device结构体:

static struct imx_ssi_platform_data xxx_ssi0_pdata = {.flags = IMX_SSI_DMA | IMX_SSI_SYN,
};


然后调用imx6q_add_imx_ssi进行注册:

imx6q_add_imx_ssi(0, &xxx_ssi0_pdata);


imx6q_add_imx_ssi的实现:

#define imx6q_add_imx_ssi(id, pdata)            \imx_add_imx_ssi(&imx6_imx_ssi_data[id], pdata)


其中imx6_imx_ssi_data的定义:

const struct imx_imx_ssi_data imx6_imx_ssi_data[] __initconst = {
#define imx6q_imx_ssi_data_entry(_id, _hwid)				\imx_imx_ssi_data_entry(MX6Q, _id, _hwid, SZ_4K)imx6q_imx_ssi_data_entry(0, 1),imx6q_imx_ssi_data_entry(1, 2),imx6q_imx_ssi_data_entry(2, 3),
};#define imx_imx_ssi_data_entry(soc, _id, _hwid, _size)			\[_id] = {							\.id = _id,						\.iobase = soc ## _SSI ## _hwid ## _BASE_ADDR,		\.iosize = _size,					\.irq = soc ## _INT_SSI ## _hwid,			\.dmatx0 = soc ## _DMA_REQ_SSI ## _hwid ## _TX0,		\.dmarx0 = soc ## _DMA_REQ_SSI ## _hwid ## _RX0,		\.dmatx1 = soc ## _DMA_REQ_SSI ## _hwid ## _TX1,		\.dmarx1 = soc ## _DMA_REQ_SSI ## _hwid ## _RX1,		\}


soc ## _SSI ## _hwid ## _BASE_ADDR拼出来其实是:
MX6Q_SSI1_BASE_ADDR
MX6Q_SSI2_BASE_ADDR
MX6Q_SSI3_BASE_ADDR

看看它们的定义:

#define MX6Q_SSI1_BASE_ADDR		(ATZ1_BASE_ADDR + 0x28000) /* slot 10 */
#define MX6Q_SSI2_BASE_ADDR		(ATZ1_BASE_ADDR + 0x2C000) /* slot 11 */
#define MX6Q_SSI3_BASE_ADDR		(ATZ1_BASE_ADDR + 0x30000) /* slot 12 */


与data sheet中一致。

再看imx_add_imx_ssi的实现:

struct platform_device *__init imx_add_imx_ssi(const struct imx_imx_ssi_data *data,const struct imx_ssi_platform_data *pdata)
{struct resource res[] = {{.start = data->iobase,.end = data->iobase + data->iosize - 1,.flags = IORESOURCE_MEM,}, {.start = data->irq,.end = data->irq,.flags = IORESOURCE_IRQ,},
#define DMARES(_name) {							\.name = #_name,							\.start = data->dma ## _name,					\.end = data->dma ## _name,					\.flags = IORESOURCE_DMA,					\
}DMARES(tx0),DMARES(rx0),DMARES(tx1),DMARES(rx1),};// data->id是0.res就是前面定义的。pdata就是xxx_ssi0_pdatareturn imx_add_platform_device("imx-ssi", data->id,res, ARRAY_SIZE(res),pdata, sizeof(*pdata));
}static inline struct platform_device *imx_add_platform_device(const char *name, int id,const struct resource *res, unsigned int num_resources,const void *data, size_t size_data)
{return imx_add_platform_device_dmamask(name, id, res, num_resources, data, size_data, 0);
}struct platform_device *__init imx_add_platform_device_dmamask(const char *name, int id,const struct resource *res, unsigned int num_resources,const void *data, size_t size_data, u64 dmamask)
{int ret = -ENOMEM;struct platform_device *pdev;/*** platform_device_alloc - create a platform device* @name: base name of the device we're adding* @id: instance id** Create a platform device object which can have other objects attached* to it, and which will have attached objects freed when it is released.*/	pdev = platform_device_alloc(name, id);if (!pdev)goto err;if (dmamask) {/** This memory isn't freed when the device is put,* I don't have a nice idea for that though.  Conceptually* dma_mask in struct device should not be a pointer.* See http://thread.gmane.org/gmane.linux.kernel.pci/9081*/pdev->dev.dma_mask =kmalloc(sizeof(*pdev->dev.dma_mask), GFP_KERNEL);if (!pdev->dev.dma_mask)/* ret is still -ENOMEM; */goto err;*pdev->dev.dma_mask = dmamask;pdev->dev.coherent_dma_mask = dmamask;}/×
/*** platform_device_add_resources - add resources to a platform device* @pdev: platform device allocated by platform_device_alloc to add resources to* @res: set of resources that needs to be allocated for the device* @num: number of resources** Add a copy of the resources to the platform device.  The memory* associated with the resources will be freed when the platform device is* released.*/
int platform_device_add_resources(struct platform_device *pdev,const struct resource *res, unsigned int num)
{struct resource *r = NULL;if (res) {r = kmemdup(res, sizeof(struct resource) * num, GFP_KERNEL);if (!r)return -ENOMEM;}kfree(pdev->resource);pdev->resource = r;pdev->num_resources = num;return 0;
}×/if (res) {// 此处add的resource在ssi的probe函数中调用platform_get_resource可以获取。// platform_get_resource(pdev, IORESOURCE_MEM, 0)ret = platform_device_add_resources(pdev, res, num_resources);if (ret)goto err;}/*
/*** platform_device_add_data - add platform-specific data to a platform device* @pdev: platform device allocated by platform_device_alloc to add resources to* @data: platform specific data for this platform device* @size: size of platform specific data** Add a copy of platform specific data to the platform device's* platform_data pointer.  The memory associated with the platform data* will be freed when the platform device is released.*/
int platform_device_add_data(struct platform_device *pdev, const void *data,size_t size)
{void *d = NULL;if (data) {d = kmemdup(data, size, GFP_KERNEL);if (!d)return -ENOMEM;}kfree(pdev->dev.platform_data);pdev->dev.platform_data = d;return 0;
}*/if (data) {ret = platform_device_add_data(pdev, data, size_data);if (ret)goto err;}ret = platform_device_add(pdev);if (ret) {
err:if (dmamask)kfree(pdev->dev.dma_mask);platform_device_put(pdev);return ERR_PTR(ret);}return pdev;
}


从上面的代码看,imx6_imx_ssi_data只有3个成员。
当调用
imx6q_add_imx_ssi(3, &mx6_smartauto_ssi3_pdata);
时,访问了imx6_imx_ssi_data[3],超出了数组的界限。
难道刚好esai的data数组刚好在ssi的后面,所以imx6_imx_ssi_data[3]其实访问的是esai的数组?
但是为什么probe中打印出来的resource name是ssi-0呢?
看了下前面data数组的定义,其中没有name相关的内容。
再看res数组的定义,也没有name。
所以imx6_imx_ssi_data[3]访问了esai的data数组,但是data数组中并没有name信息,所以name还为ssi-0。
这个name从哪儿来的呢?
又看了一遍代码,也没发现哪儿对resource name进行赋值。

http://www.lbrq.cn/news/2525905.html

相关文章:

  • 湖南网站建设网站制作搜索引擎的网站
  • 招聘网站评估怎么做百度怎么投放自己的广告
  • 专业网站建设套餐快速排名服务平台
  • 深圳软件外包公司列表连云港网站seo
  • 网站内怎样做关键词有效果微信群免费推广平台
  • 国外的自建站平台是什么肇庆seo优化
  • 开创云网站建设支持竞价托管怎么做
  • 平湖网站建设seo综合查询怎么进入网站
  • 范例网站怎么做人力资源培训
  • 网站的建设任务百度旗下的所有产品
  • dreamweaver怎么读南昌seo技术外包
  • 宜宾县企业项目建设影响环境登记表网站肇庆seo
  • 网站建设 开源百度站长工具平台登录
  • 青岛市规划建设局网站网站排名首页前三位
  • 网站后台怎么修改淄博网站制作
  • 济宁网站建设平台百度推广官方
  • seo是搜索引擎优化吗抖音seo优化怎么做
  • 外贸免费网站建设买友情链接有用吗
  • 征婚网站怎么做网站推广策划书模板
  • 青岛互联网设计公司一个具体网站的seo优化方案
  • 公司网站制作需要什么长沙网络营销公司排名
  • 甘肃做高端网站排名网站
  • 南京营销型网站制作网站建设工作总结
  • 汕头百度公司南宁seo推广优化
  • 去设计公司还是去企业焦作网站seo
  • 网站导航做多大网站关键词优化工具
  • 长春 万网 网站建设关键词seo排名优化推荐
  • 维护网站计划书什么软件可以搜索关键词精准
  • 长沙百度做网站多少钱河南关键词优化搜索
  • 青岛公司网站佛山网络推广哪里好
  • TCPDump实战手册:协议/端口/IP过滤与组合分析指南
  • 重塑浏览器!微软在Edge加入AI Agent,自动化搜索、预测、整合
  • redis未授权getshell四种方式
  • 坚鹏:AI智能体培训是知行学成为AI智能体创新应用引领者的基础
  • ROS2入门之开发环境搭建
  • 电流变送器电路的分析与计算