Linux 中断(irq)控制器以及device tree设置
2017-02-22 23:30
190 查看
GPIO相关中断(高通平台为例)
gpio相关的中断控制器(msm_tlmm_irq) 初始化(1) IRQCHIP_DECLARE定义irq chip #define IRQCHIP_DECLARE(name,compstr,fn) \ static const struct of_device_id irqchip_of_match_##name \ __used __section(__irqchip_of_table) \ = { .compatible = compstr, .data = fn } IRQCHIP_DECLARE(tlmmv3_irq, "qcom,msm-tlmm-gp", irq_msm_gpio_init); //定义IRQCHIP_DECLARE之后,相应的内容会保存到__irqchip_of_table里边。 //__irqchip_of_table在vmlinux.lds文件里边被放到了__irqchip_begin和__irqchip_of_end之间 #ifdef CONFIG_IRQCHIP #define IRQCHIP_OF_MATCH_TABLE() \ . = ALIGN(8); \ VMLINUX_SYMBOL(__irqchip_begin) = .; \ *(__irqchip_of_table) \ *(__irqchip_of_end) #endif __irqchip_begin和__irqchip_of_end的内容被drivers/irqchip/irqchip.c文件读出并根据其在device tree里边的内容进行初始化。
3.设置中断唤醒!!
以gpio-key的为例:以下是gpio-key的device tree设置
gpio_keys { compatible = "gpio-keys"; input-name = "gpio-keys"; pinctrl-names = "tlmm_gpio_key_active","tlmm_gpio_key_suspend"; pinctrl-0 = <&gpio_key_active>; pinctrl-1 = <&gpio_key_suspend>; home_key { label = "home_key"; gpios = <&msm_gpio 109 0x1>; linux,input-type = <1>; linux,code = <172>; gpio-key,wakeup; debounce-interval = <15>; }; vol_up { label = "volume_up"; gpios = <&msm_gpio 107 0x1>; linux,input-type = <1>; linux,code = <115>; debounce-interval = <15>; }; };
可以看到home_key里边有gpio-key,wakeup;
这个在gpio_keys相关的驱动力,在suspend的时候需要使用enable_irq_wake来进行设置才能通过home_key中断唤醒系统。
static int gpio_keys_suspend(void){ ... if (device_may_wakeup(global_dev)) { for (i = 0; i < ddata->pdata->nbuttons; i++) { struct gpio_button_data *bdata = &ddata->data[i]; if (bdata->button->wakeup)//buttong->wakeup就是通过读device tree的gpio-key,wakeup设置的 enable_irq_wake(bdata->irq);//设置该中断可唤醒系统!!具体设置看上面的中断控制器内容 } } else { mutex_lock(&input->mutex); if (input->users) gpio_keys_close(input); mutex_unlock(&input->mutex); } ... }
当然在resume的时候也要对应地取消中断函数的唤醒。
enable_irq_wake()和disable_irq_wake()函数中可以看到,irq_desc的wake_depth会记录enable或者disable的次数。
所以需要对应地enable和disable每个irq的中断唤醒功能。
static void gpio_keys_resume(void) { ... if (device_may_wakeup(global_dev)) { for (i = 0; i < ddata->pdata->nbuttons; i++) { struct gpio_button_data *bdata = &ddata->data[i]; if (bdata->button->wakeup) disable_irq_wake(bdata->irq); } } else { mutex_lock(&input->mutex); if (input->users) error = gpio_keys_open(input); mutex_unlock(&input->mutex); } ... }
上面device_may_wakeup()检查power.can_wakeup,power.wakeup
static inline bool device_may_wakeup(struct device *dev) { return dev->power.can_wakeup && !!dev->power.wakeup; }
这里的power.can_wakeup在gpio_keys_probe()函数的device_init_wakeup()函数里设置。
################################################
IRQ相关的宏
CONFIG_ARM_GIC //GIC中断控制器 CONFIG_SPARSE_IRQ CONFIG_MSM_SHOW_RESUME_IRQ CONFIG_HAVE_IRQ_TIME_ACCOUNTING CONFIG_USE_PINCTRL_IRQ CONFIG_OF_IRQ CONFIG_IRQ_WORK CONFIG_SPARSE_IRQ CONFIG_TRACE_IRQFLAGS_SUPPORT CONFIG_HARDIRQS_SW_RESEND CONFIG_SEC_DEBUG_IRQ_EXIT_LOG CONFIG_GENERIC_IRQ_PROBE CONFIG_MAY_HAVE_SPARSE_IRQ CONFIG_GENERIC_IRQ_SHOW CONFIG_IRQ_DOMAIN CONFIG_MULTI_IRQ_HANDLER CONFIG_IRQCHIP CONFIG_MSM_IRQ
###############################################
#cat /proc/interrupts 打印的内容
cat interrupts CPU0 CPU1 CPU2 CPU3 20: 1086204 465271 219385 125476 GIC arch_timer 35: 0 0 0 0 GIC apps_wdog_bark 39: 1274816 928934 431484 252063 GIC arch_mem_timer 47: 45 0 0 0 GIC cpr 56: 0 0 0 0 GIC modem 57: 6678 0 0 0 GIC qcom,smd-modem 58: 2 0 0 0 GIC qcom,smsm-modem 59: 5 0 0 0 GIC smp2p 65: 10820 0 0 0 GIC kgsl-3d0 75: 0 0 0 0 GIC msm_iommu_global_cfg_irq, msm_iommu_global_cfg_irq 76: 503 0 0 0 GIC msm_vidc 82: 9 0 0 0 GIC cci 83: 2 0 0 0 GIC csid 84: 0 0 0 0 GIC csid 89: 2 0 0 0 GIC 102: 0 0 0 0 GIC msm_iommu_nonsecure_irq, msm_iommu_nonsecure_irq, msm_iommu_nonsecure_irq, msm_iommu_nonsecure_irq, msm_iommu_nonsecure_irq, msm_iommu_nonsecure_irq, msm_iommu_nonsecure_irq, msm_iommu_nonsecure_irq, msm_iommu_secure_irq, msm_iommu_secure_irq, msm_iommu_secure_irq, msm_iommu_secure_irq, msm_iommu_secure_irq, msm_iommu_secure_irq, msm_iommu_nonsecure_irq, msm_iommu_nonsecure_irq, msm_iommu_nonsecure_irq, msm_iommu_nonsecure_irq, msm_iommu_nonsecure_irq, msm_iommu_nonsecure_irq 104: 3821 0 0 0 GIC MDSS 110: 0 0 0 0 GIC csiphy 111: 0 0 0 0 GIC csiphy 127: 0 0 0 0 GIC i2c-msm-v2-irq 128: 7893 0 0 0 GIC i2c-msm-v2-irq 130: 0 0 0 0 GIC i2c-msm-v2-irq 131: 0 0 0 0 GIC i2c-msm-v2-irq 132: 0 0 0 0 GIC i2c-msm-v2-irq 140: 576 0 0 0 GIC msm_serial_hsl0 155: 132532 0 0 0 GIC mmc0 157: 0 0 0 0 GIC mmc1 166: 511 0 0 0 GIC msm_otg, msm_hsusb 170: 663 0 0 0 GIC 7824900.sdhci 172: 0 0 0 0 GIC msm_otg 174: 1127 0 0 0 GIC qcom,smd-wcnss 175: 5 0 0 0 GIC smp2p 176: 0 0 0 0 GIC qcom,smsm-wcnss 177: 1769 0 0 0 GIC wcnss_wlan 178: 630 0 0 0 GIC wcnss_wlan 181: 0 0 0 0 GIC wcnss 200: 244890 133756 49164 25615 GIC qcom,smd-rpm 203: 427701 370801 115006 64144 GIC 601d0.qcom,mpm 216: 0 0 0 0 GIC tsens_interrupt 222: 677 0 0 0 GIC 200f000.qcom,spmi 239: 0 0 0 0 GIC sps 240: 575 0 0 0 GIC 1000000.pinctrl 253: 2 0 0 0 GIC 7864900.sdhci 273: 0 0 0 0 GIC msm_iommu_nonsecure_irq 274: 0 0 0 0 GIC msm_iommu_nonsecure_irq 280: 2 0 0 0 GIC mobicore 288: 0 0 0 0 msm_tlmm_irq sm5703 290: 0 0 0 0 msm_tlmm_irq 7864900.sdhci cd 291: 7 0 0 0 qpnp-int qpnp_kpdpwr_status 292: 2 0 0 0 qpnp-int qpnp_resin_status 294: 2 0 0 0 qpnp-int qpnp_kpdpwr_resin_bark 295: 334 0 0 0 qpnp-int qpnp_rtc_alarm 297: 0 0 0 0 qpnp-int pm8916_tz 299: 1 0 0 0 qpnp-int qpnp_adc_tm_high_interrupt 300: 0 0 0 0 qpnp-int qpnp_adc_tm_low_interrupt 330: 0 0 0 0 msm_tlmm_irq k2hh_accel 331: 0 0 0 0 msm_tlmm_irq bcm2079x-i2c 338: 0 0 0 0 sm5703 otffail 348: 0 0 0 0 sm5703 topoff 349: 0 0 0 0 sm5703 done 357: 6 0 0 0 msm_tlmm_irq sm5703 muic micro USB 454: 569 0 0 0 msm_tlmm_irq zt7554_ts 455: 0 0 0 0 msm_tlmm_irq fuelgauge-irq 456: 0 0 0 0 msm_tlmm_irq sx9500_wifi_irq 457: 0 0 0 0 smp2p_gpio modem 458: 1 0 0 0 smp2p_gpio error_ready_interrupt 459: 1 0 0 0 smp2p_gpio modem 460: 0 0 0 0 smp2p_gpio modem 489: 0 0 0 0 smp2p_gpio wcnss 490: 1 0 0 0 smp2p_gpio error_ready_interrupt 491: 1 0 0 0 smp2p_gpio wcnss 492: 0 0 0 0 smp2p_gpio wcnss 521: 0 0 0 0 msm_tlmm_irq home_key 522: 0 0 0 0 msm_tlmm_irq volume_up 523: 0 0 0 0 msm_tlmm_irq sec_headset_detect IPI0: 0 335 335 335 CPU wakeup interrupts IPI1: 22678 22996 17470 15718 Timer broadcast interrupts IPI2: 481360 374947 186478 142656 Rescheduling interrupts IPI3: 84655 100015 156993 161249 Function call interrupts IPI4: 1204 6730 6209 7108 Single function call interrupts IPI5: 0 0 0 0 CPU stop interrupts IPI6: 0 0 0 0 CPU backtrace Err: 0
相关文章推荐
- Linux 中断(irq)控制器以及device tree设置
- linux下的中断(interrupt)IRQ以及IRQ绑核小结
- linux内核中断、异常、系统调用的分析以及实践
- linux操作之:设置控制台的分辨率,中文显示以及scim的问题
- Linux 查看网卡全双工 还是半双工 以及设置网卡为半双工
- Linux安装madplay以及设置共享库连接
- Linux安装madplay以及设置共享库连接
- 给select下拉框增加option发现的问题,以及js怎么设置中断
- Linux 系统设置 ulimit 以及 Core文件的生成
- Linux 查看网卡全双工 还是半双工 以及设置网卡为半双工
- linux: 编译android源代码流程,以及linux环境变量设置。
- linux启动项ntsysv以及运行级别runlevel设置说明
- RedHat9的LINUX环境下NFS的功能设置以及与开发板的通信说明(转载)
- Flex中如何利用dataDescriptor和labelFunction属性,以及hasChildren()和getChildren()函数设置Tree中包含子节点个数
- LINUX下面的一些安全设置以及一些常见的设置
- Linux 查看网卡全双工 还是半双工 以及设置网卡为半双工
- linux 查看进程信息以及防火墙的设置命令
- VMware中Linux系统时间与主机同步以及时区设置
- VMware中Linux系统时间与主机同步以及时区设置
- Flex中如何利用dataDescriptor和labelFunction属性以及hasChildren()和getChildren()函数设置Tree中包含子节点个数的例子