博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
慢慢欣赏linux 中断描述符
阅读量:4070 次
发布时间:2019-05-25

本文共 4200 字,大约阅读时间需要 14 分钟。

unsigned int __irq_entry do_IRQ(struct pt_regs *regs){	desc = __this_cpu_read(vector_irq[vector]); 根据硬中断号找到中断描述符}

以RTC时钟中断注册为例

static int mtk_rtc_probe(struct platform_device *pdev){	struct resource *res;	struct mt6397_chip *mt6397_chip = dev_get_drvdata(pdev->dev.parent);	struct mt6397_rtc *rtc;	int ret;	rtc = devm_kzalloc(&pdev->dev, sizeof(struct mt6397_rtc), GFP_KERNEL);	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);	rtc->addr_base = res->start;	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);	// 第一步 获取中断资源, 中断号, 高/低 边沿/电平触发	rtc->irq = irq_create_mapping(mt6397_chip->irq_domain, res->start);	// 第二步 进行软硬中断映射	=>unsigned int irq_create_mapping(struct irq_domain *domain,				irq_hw_number_t hwirq)	{		struct device_node *of_node;		int virq;		/* Look for default domain if nececssary */		if (domain == NULL)			domain = irq_default_domain;		of_node = irq_domain_get_of_node(domain);		/* Check if mapping already exists */		virq = irq_find_mapping(domain, hwirq);	// 已经映射则返回		=>unsigned int irq_find_mapping(struct irq_domain *domain,			      irq_hw_number_t hwirq)		{			struct irq_data *data;			/* Look for default domain if nececssary */			if (domain == NULL)				domain = irq_default_domain;			if (domain == NULL)				return 0;			if (hwirq < domain->revmap_direct_max_irq) {				data = irq_domain_get_irq_data(domain, hwirq);				if (data && data->hwirq == hwirq)					return hwirq;			}			/* Check if the hwirq is in the linear revmap. */			if (hwirq < domain->revmap_size)				return domain->linear_revmap[hwirq];			rcu_read_lock();			data = radix_tree_lookup(&domain->revmap_tree, hwirq);	// 树查找			rcu_read_unlock();			return data ? data->irq : 0;		}		if (virq) {			return virq;		}		/* Allocate a virtual interrupt number */		virq = irq_domain_alloc_descs(-1, 1, hwirq, of_node_to_nid(of_node), NULL);		=>int irq_domain_alloc_descs(int virq, unsigned int cnt, irq_hw_number_t hwirq,			   int node, const struct cpumask *affinity)		{			virq = __irq_alloc_descs(virq, virq, cnt, node, THIS_MODULE,					 affinity);			=>int __ref __irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node,				struct module *owner, const struct cpumask *affinity)			{				start = bitmap_find_next_zero_area(allocated_irqs, IRQ_BITMAP_BITS,					   from, cnt, 0);				ret = alloc_descs(start, cnt, node, affinity, owner);				return ret;			}					 			return virq;		}		irq_domain_associate(domain, virq, hwirq)		return virq;	}	rtc->regmap = mt6397_chip->regmap;	rtc->dev = &pdev->dev;	mutex_init(&rtc->lock);	platform_set_drvdata(pdev, rtc);	ret = request_threaded_irq(rtc->irq, NULL,	// 第三步 挂接中断action				   mtk_rtc_irq_handler_thread,				   IRQF_ONESHOT | IRQF_TRIGGER_HIGH,				   "mt6397-rtc", rtc);	device_init_wakeup(&pdev->dev, 1);	rtc->rtc_dev = rtc_device_register("mt6397-rtc", &pdev->dev,					   &mtk_rtc_ops, THIS_MODULE);	return 0;}

中断描述符的申请使用如下函数:alloc_descs 函数根据条件编译宏分静态分配和动态申请

动态申请如下

static int alloc_descs(unsigned int start, unsigned int cnt, int node,		       const struct cpumask *affinity, struct module *owner){	const struct cpumask *mask = NULL;	struct irq_desc *desc;	unsigned int flags;	int i;	flags = affinity ? IRQD_AFFINITY_MANAGED | IRQD_MANAGED_SHUTDOWN : 0;	mask = NULL;	for (i = 0; i < cnt; i++) {		if (affinity) {			node = cpu_to_node(cpumask_first(affinity));			mask = affinity;			affinity++;		}		desc = alloc_desc(start + i, node, flags, mask, owner);				irq_insert_desc(start + i, desc);		irq_sysfs_add(start + i, desc);		irq_add_debugfs_entry(start + i, desc);	}	bitmap_set(allocated_irqs, start, cnt);	return start;}

静态申请

static inline int alloc_descs(unsigned int start, unsigned int cnt, int node,			      const struct cpumask *affinity,			      struct module *owner){	u32 i;	for (i = 0; i < cnt; i++) {		struct irq_desc *desc = irq_to_desc(start + i);'		=>struct irq_desc *irq_to_desc(unsigned int irq)		{			return (irq < NR_IRQS) ? irq_desc + irq : NULL;			==>struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned_in_smp = {	// 静态定义数组				[0 ... NR_IRQS-1] = {					.handle_irq	= handle_bad_irq,					.depth		= 1,					.lock		= __RAW_SPIN_LOCK_UNLOCKED(irq_desc->lock),				}			};		}		desc->owner = owner;	}	bitmap_set(allocated_irqs, start, cnt);	return start;}

 

转载地址:http://ndlji.baihongyu.com/

你可能感兴趣的文章
platform_device与platform_driver
查看>>
platform_driver平台驱动注册和注销过程(下)
查看>>
.net强制退出主窗口的方法——Application.Exit()方法和Environment.Exit(0)方法
查看>>
c# 如何调用win8自带的屏幕键盘(非osk.exe)
查看>>
build/envsetup.sh 简介
查看>>
C++后继有人——D语言
查看>>
Android framework中修改或者添加资源无变化或编译不通过问题详解
查看>>
linux怎么切换到root里面?
查看>>
linux串口操作及设置详解
查看>>
安装alien,DEB与RPM互换
查看>>
linux系统下怎么安装.deb文件?
查看>>
编译Android4.0源码时常见错误及解决办法
查看>>
Android 源码编译make的错误处理
查看>>
linux环境下C语言中sleep的问题
查看>>
ubuntu 12.04 安装 GMA3650驱动
查看>>
新版本的linux如何生成xorg.conf
查看>>
xorg.conf的编写
查看>>
启用SELinux时遇到的问题
查看>>
virbr0 虚拟网卡卸载方法
查看>>
No devices detected. Fatal server error: no screens found
查看>>