MSM8260中的设置中断唤醒的分析:
/*下面是设置的两个接口*/
static inline int enable_irq_wake(unsigned int irq)
{
return set_irq_wake(irq, 1);
}
static inline int disable_irq_wake(unsigned int irq)
{
return set_irq_wake(irq, 0);
}
/*上面的两个接口都调用如下函数*/
int set_irq_wake(unsigned int irq, unsigned int on)
{
struct irq_desc *desc = irq_to_desc(irq);//由irq获得该irq的中断描述符
unsigned long flags;
int ret = 0;
raw_spin_lock_irqsave(&desc->lock, flags);
if (on) {//如果使能唤醒功能
if (desc->wake_depth++ == 0) {//如果wake_depth为0,则执行真正的使能函数
ret = set_irq_wake_real(irq, on);
if (ret)
desc->wake_depth = 0;
else
desc->status |= IRQ_WAKEUP;//如果使能成功,则置为IRQ_WAKEUP
}
} else {//如果去使能唤醒功能
if (desc->wake_depth == 0) {
WARN(1, "Unbalanced IRQ %d wake disable\n", irq);
} else if (--desc->wake_depth == 0) {//如果--为0则,走真正的去使能函数
ret = set_irq_wake_real(irq, on);
if (ret)
desc->wake_depth = 1;
else
desc->status &= ~IRQ_WAKEUP;//如果使能成功,则清除IRQ_WAKEUP
}
}
raw_spin_unlock_irqrestore(&desc->lock, flags);
return ret;
}
EXPORT_SYMBOL(set_irq_wake);
/*上面的函数会调用如下函数*/
static int set_irq_wake_real(unsigned int irq, unsigned int on)
{
struct irq_desc *desc = irq_to_desc(irq);
int ret = -ENXIO;
if (desc->chip->set_wake)//如果芯片的操作函数不为空,则调用该函数
ret = desc->chip->set_wake(irq, on);
return ret;
}
————————————————————————————————————————————————————————————————————————————————
下面分析该底层的操作函数
————————————————————————————————————————————————————————————————————————————————
/*底层的硬件操作函数*/
static struct irq_chip msm_gpio_irq_chip = {
.name = "msmgpio",
.mask = msm_gpio_irq_mask,
.unmask = msm_gpio_irq_unmask,
.ack = msm_gpio_irq_ack,
.set_type = msm_gpio_irq_set_type,
.set_wake = msm_gpio_irq_set_wake,//设置是否该irq有唤醒功能
.disable = msm_gpio_irq_disable,
};
/*唤醒回调函数的实现*/
#define GIC_SPI_START 32
#define TLMM_MSM_SUMMARY_IRQ (GIC_SPI_START + 16)
#define NR_MSM_IRQS 256
#define MSM_GPIO_TO_INT(n) (NR_MSM_IRQS + (n))
static inline int msm_irq_to_gpio(struct gpio_chip *chip, unsigned irq)
{
return irq - MSM_GPIO_TO_INT(chip->base);//MSM_GPIO_TO_INT(0)
}
static int msm_gpio_irq_set_wake(unsigned int irq, unsigned int on)
{
int gpio = msm_irq_to_gpio(&msm_gpio.gpio_chip, irq);
if (on) {
if (bitmap_empty(msm_gpio.wake_irqs, NR_MSM_GPIOS))//如果wake_irqs中都为空,则设置为1
set_irq_wake(TLMM_MSM_SUMMARY_IRQ, 1);
set_bit(gpio, msm_gpio.wake_irqs);//设置相应的位为1
} else {
clear_bit(gpio, msm_gpio.wake_irqs);//设置相应的位为0
if (bitmap_empty(msm_gpio.wake_irqs, NR_MSM_GPIOS))//如果wake_irqs中都为空,则设置为0
set_irq_wake(TLMM_MSM_SUMMARY_IRQ, 0);
}
#ifdef CONFIG_MSM_RPM
msm_mpm_set_irq_wake(irq, on);
#endif
return 0;
}
/*下面是上面用到的结构体变量msm_gpio的定义*/
#define NR_GPIO_IRQS 173
#define NR_MSM_GPIOS NR_GPIO_IRQS
#define BITS_PER_BYTE 8
#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long))
#define DECLARE_BITMAP(name,bits) unsigned long name[BITS_TO_LONGS(bits)]
struct msm_gpio_dev {
struct gpio_chip gpio_chip;
DECLARE_BITMAP(enabled_irqs, NR_MSM_GPIOS);
DECLARE_BITMAP(wake_irqs, NR_MSM_GPIOS);//分配一个数组,向上取整,并且根据long的长度(可移植性),去分配数组成员的个数。
DECLARE_BITMAP(dual_edge_irqs, NR_MSM_GPIOS);
};
/*结构体变量*/
static struct msm_gpio_dev msm_gpio = {
.gpio_chip = {
.base = 0,
.ngpio = NR_MSM_GPIOS,//173
.direction_input = msm_gpio_direction_input,
.direction_output = msm_gpio_direction_output,
.get = msm_gpio_get,
.set = msm_gpio_set,
.to_irq = msm_gpio_to_irq,
.request = msm_gpio_request,
.free = msm_gpio_free,
},
};
/*高通底层中断处理函数注册*/
static int __devinit msm_gpio_probe(struct sysdev_class *sysclass)
{
.....................
/*把msm_gpio里面的成员变量初始化为0*/
bitmap_zero(msm_gpio.enabled_irqs, NR_MSM_GPIOS);
bitmap_zero(msm_gpio.wake_irqs, NR_MSM_GPIOS);
bitmap_zero(msm_gpio.dual_edge_irqs, NR_MSM_GPIOS);
msm_gpio.gpio_chip.label = sysclass->name;
ret = gpiochip_add(&msm_gpio.gpio_chip);//注册一个chip结构
...................
/*初始化中断体系结构的处理函数*/
for (i = 0; i < msm_gpio.gpio_chip.ngpio; ++i) {
irq = msm_gpio_to_irq(&msm_gpio.gpio_chip, i);
set_irq_chip(irq, &msm_gpio_irq_chip);//初始化芯片级操作函数
set_irq_handler(irq, handle_level_irq);//初始化该irq处理函数的总入口
set_irq_flags(irq, IRQF_VALID);//设置该irq可用
}
/*为总中断入口申请函数*/
ret = request_irq(TLMM_MSM_SUMMARY_IRQ, msm_summary_irq_handler,IRQF_TRIGGER_HIGH, "msmgpio", NULL);
return 0;
}
阅读(5809) | 评论(0) | 转发(0) |