set_irq_type函数解析

理解Linux内核:set_irq_type函数详解
本文深入解析set_irq_type函数,探讨如何设置中断类型。通过介绍该函数的参数,阐述中断号和触发方式,并分析struct irq_desc结构体内的中断链表和irq_chip的回调函数。同时,讲解如何更新中断标志位并存储于desc->status。
/*
 * These correspond to the IORESOURCE_IRQ_* defines in
 * linux/ioport.h to select the interrupt line behaviour.  When
 * requesting an interrupt without specifying a IRQF_TRIGGER, the
 * setting should be assumed to be "as already configured", which
 * may be as per machine or firmware initialisation.
 */
#define IRQF_TRIGGER_NONE	0x00000000	
#define IRQF_TRIGGER_RISING	0x00000001	/*上升沿触发*/
#define IRQF_TRIGGER_FALLING	0x00000002	/*下降沿触发*/
#define IRQF_TRIGGER_HIGH	0x00000004	/*高电平触发*/
#define IRQF_TRIGGER_LOW	0x00000008	/*低电平触发*/
#define IRQF_TRIGGER_MASK	(IRQF_TRIGGER_HIGH | IRQF_TRIGGER_LOW | \
				 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)
#define IRQF_TRIGGER_PROBE	0x00000010

上述参数为set_irq_type函数的第二个函数的参考值。


                
static irqreturn_t accdet_eint_func(int irq, void *data) 500 { 501 int ret = 0; 502 503 ACCDET_DEBUG("[Accdet]Enter accdet_eint_func !!!!!!\n"); 504 if (cur_eint_state == EINT_PIN_PLUG_IN) { 505 /* 506 To trigger EINT when the headset was plugged in 507 We set the polarity back as we initialed. 508 */ 509 #ifndef CONFIG_ACCDET_EINT_IRQ 510 if (accdet_eint_type == IRQ_TYPE_LEVEL_HIGH) 511 irq_set_irq_type(accdet_irq, IRQ_TYPE_LEVEL_HIGH); 512 else 513 irq_set_irq_type(accdet_irq, IRQ_TYPE_LEVEL_LOW); 514 #endif 515 #ifdef CONFIG_ACCDET_EINT_IRQ 516 pmic_pwrap_write(ACCDET_EINT_CTL, pmic_pwrap_read(ACCDET_EINT_CTL) & (~(7 << 4))); 517 /*debounce=256ms*/ 518 pmic_pwrap_write(ACCDET_EINT_CTL, pmic_pwrap_read(ACCDET_EINT_CTL) | EINT_IRQ_DE_IN); 519 pmic_pwrap_write(ACCDET_DEBOUNCE3, cust_headset_settings->debounce3); 520 521 #else 522 gpio_set_debounce(gpiopin, headsetdebounce); 523 #endif 524 525 /* update the eint status */ 526 cur_eint_state = EINT_PIN_PLUG_OUT; 527 } else { 528 /* 529 To trigger EINT when the headset was plugged out 530 We set the opposite polarity to what we initialed. 531 */ 532 #ifndef CONFIG_ACCDET_EINT_IRQ 533 if (accdet_eint_type == IRQ_TYPE_LEVEL_HIGH) 534 irq_set_irq_type(accdet_irq, IRQ_TYPE_LEVEL_LOW); 535 else 536 irq_set_irq_type(accdet_irq, IRQ_TYPE_LEVEL_HIGH); 537 #endif 538 539 #ifdef CONFIG_ACCDET_EINT_IRQ 540 pmic_pwrap_write(ACCDET_EINT_CTL, pmic_pwrap_read(ACCDET_EINT_CTL) & (~(7 << 4))); 541 /*debounce=16ms*/ 542 pmic_pwrap_write(ACCDET_EINT_CTL, pmic_pwrap_read(ACCDET_EINT_CTL) | EINT_IRQ_DE_OUT); 543 #else 544 gpio_set_debounce(gpiopin, accdet_dts_data.accdet_plugout_debounce * 1000); 545 #endif 546 /* update the eint status */ 547 cur_eint_state = EINT_PIN_PLUG_IN; 548 549 mod_timer(&micbias_timer, jiffies + MICBIAS_DISABLE_TIMER); 550 } 551 #ifndef CONFIG_ACCDET_EINT_IRQ 552 disable_irq_nosync(accdet_irq); 553 #endif 554 ACCDET_DEBUG("[Accdet]accdet_eint_func after cur_eint_state=%d\n", cur_eint_state); 555 556 ret = queue_work(accdet_eint_workqueue, &accdet_eint_work); 557 return IRQ_HANDLED; 558 } 559 #ifndef CONFIG_ACCDET_EINT_IRQ 560 static inline int accdet_setup_eint(struct platform_device *accdet_device) 561 { 562 int ret; 563 u32 ints[2] = { 0, 0 }; 564 u32 ints1[2] = { 0, 0 }; 565 struct device_node *node = NULL; 566 struct pinctrl_state *pins_default; 567 568 /*configure to GPIO function, external interrupt */ 569 ACCDET_INFO("[Accdet]accdet_setup_eint\n"); 570 accdet_pinctrl1 = devm_pinctrl_get(&accdet_device->dev); 571 if (IS_ERR(accdet_pinctrl1)) { 572 ret = PTR_ERR(accdet_pinctrl1); 573 dev_err(&accdet_device->dev, "fwq Cannot find accdet accdet_pinctrl1!\n"); 574 return ret; 575 } 576 577 pins_default = pinctrl_lookup_state(accdet_pinctrl1, "default"); 578 if (IS_ERR(pins_default)) { 579 ret = PTR_ERR(pins_default); 580 /*dev_err(&accdet_device->dev, "fwq Cannot find accdet pinctrl default!\n");*/ 581 } 582 583 pins_eint_int = pinctrl_lookup_state(accdet_pinctrl1, "state_eint_as_int"); 584 if (IS_ERR(pins_eint_int)) { 585 ret = PTR_ERR(pins_eint_int); 586 dev_err(&accdet_device->dev, "fwq Cannot find accdet pinctrl state_eint_accdet!\n"); 587 return ret; 588 } 589 pinctrl_select_state(accdet_pinctrl1, pins_eint_int); 590 591 /*node = of_find_matching_node(node, accdet_of_match);*/ 592 node = of_find_matching_node(node, accdet_of_match); 593 if (node) { 594 of_property_read_u32_array(node, "debounce", ints, ARRAY_SIZE(ints)); 595 of_property_read_u32_array(node, "interrupts", ints1, ARRAY_SIZE(ints1)); 596 gpiopin = ints[0]; 597 headsetdebounce = ints[1]; 598 accdet_eint_type = ints1[1]; 599 gpio_set_debounce(gpiopin, headsetdebounce); 600 accdet_irq = irq_of_parse_and_map(node, 0); 601 ret = request_irq(accdet_irq, accdet_eint_func, IRQF_TRIGGER_NONE, "accdet-eint", NULL); 602 if (ret != 0) { 603 ACCDET_ERROR("[Accdet]EINT IRQ LINE NOT AVAILABLE\n"); 604 } else { 605 ACCDET_ERROR("[Accdet]accdet set EINT finished, accdet_irq=%d, headsetdebounce=%d\n", 606 accdet_irq, headsetdebounce); 607 } 608 } else { 609 ACCDET_ERROR("[Accdet]%s can't find compatible node\n", __func__); 610 } 611 return 0; 612 }
最新发布
07-15
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值