色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

全志T507 PF4引腳無法被正常設置為中斷模式的問題分析

冬至子 ? 來源:丨budboool ? 作者:丨budboool ? 2023-11-24 17:42 ? 次閱讀

相關信息

硬件平臺:全志T507
系統版本:Android 10 / Linux 4.9.170
問題描述:PF4 無法通過標準接口設置為中斷模式,而 PF1、PF2、PF3、PF5 正常可用。

分析過程

一開始以為是引腳被其它驅動占用引起,或者該引腳不具備中斷功能,經過排查,已排除這兩種可能,因此通過從源碼分析來找問題的根因。

以下是以 gpio_keys.c 驅動為入口進行分析:

// drivers/input/keyboard/gpio_keys.c
static int gpio_keys_setup_key(struct platform_device *pdev,
                struct input_dev *input,
                struct gpio_button_data *bdata,
                const struct gpio_keys_button *button)
{
    ......
    error = devm_request_any_context_irq(&pdev- >dev, bdata- >irq,
                         isr, irqflags, desc, bdata);
}

// kernel/irq/devres.c
int devm_request_any_context_irq(struct device *dev, unsigned int irq,
                  irq_handler_t handler, unsigned long irqflags,
                  const char *devname, void *dev_id)
{
    ......
    rc = request_any_context_irq(irq, handler, irqflags, devname, dev_id);
    if (rc < 0) {
        devres_free(dr);
        return rc;
    }
    ......
    return rc;
}

// kernel/irq/manage.c
int request_any_context_irq(unsigned int irq, irq_handler_t handler,
                unsigned long flags, const char *name, void *dev_id)
{
    ......
    ret = request_irq(irq, handler, flags, name, dev_id);
    return !ret ? IRQC_IS_HARDIRQ : ret;
}

// include/linux/interrupt.h
static inline int __must_check
request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags,
        const char *name, void *dev)
{
    return request_threaded_irq(irq, handler, NULL, flags, name, dev);
}

// kernel/irq/manage.c
int request_threaded_irq(unsigned int irq, irq_handler_t handler,
             irq_handler_t thread_fn, unsigned long irqflags,
             const char *devname, void *dev_id)
{
    ......
    chip_bus_lock(desc);
    retval = __setup_irq(irq, desc, action);
    chip_bus_sync_unlock(desc);
    ......
    return retval;
}

// kernel/irq/manage.c
static int __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
{
    ......

    if (!shared) {
        ret = irq_request_resources(desc);
        if (ret) {
            pr_err("Failed to request resources for %s (irq %d) on irqchip %sn",
                   new- >name, irq, desc- >irq_data.chip- >name);
            goto out_mask;
        }
        ......
    } 
    ......
}

// kernel/irq/manage.c
static int irq_request_resources(struct irq_desc *desc)
{
    struct irq_data *d = &desc- >irq_data;
    struct irq_chip *c = d- >chip;

    return c- >irq_request_resources ? c- >irq_request_resources(d) : 0;
}

// drivers/pinctrl/sunxi/pinctrl-sunxi.c
static struct irq_chip sunxi_pinctrl_edge_irq_chip = {
    .name        = "sunxi_pio_edge",
    .irq_ack    = sunxi_pinctrl_irq_ack,
    .irq_mask    = sunxi_pinctrl_irq_mask,
    .irq_unmask    = sunxi_pinctrl_irq_unmask,
    .irq_request_resources = sunxi_pinctrl_irq_request_resources,
    .irq_release_resources = sunxi_pinctrl_irq_release_resources,
    .irq_set_type    = sunxi_pinctrl_irq_set_type,
    .irq_set_wake    = sunxi_pinctrl_irq_set_wake,
};

// drivers/pinctrl/sunxi/pinctrl-sunxi.c
static int sunxi_pinctrl_irq_request_resources(struct irq_data *d)
{
    struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d);
    struct sunxi_desc_function *func;

    func = sunxi_pinctrl_desc_find_function_by_pin(pctl,
                    pctl- >irq_array[d- >hwirq], "irq");
    if (!func)
        return -EINVAL;

    /* Change muxing to INT mode */
    printk(KERN_EMERG"[lmx] irq:%d set int mode pin:%d d- >hwirq:%ld func- >muxval:%dn", d- >irq, pctl- >irq_array[d- >hwirq], d- >hwirq, func- >muxval);
    sunxi_pmx_set(pctl- >pctl_dev, pctl- >irq_array[d- >hwirq], func- >muxval);

    return 0;
}

// drivers/pinctrl/sunxi/pinctrl-sunxi.c
static void sunxi_pmx_set(struct pinctrl_dev *pctldev,
                 unsigned pin,
                 u8 config)
{
    struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
    unsigned long flags;
    u32 val, mask;

    raw_spin_lock_irqsave(&pctl- >lock, flags);
    pin -= pctl- >desc- >pin_base;
    val = readl(pctl- >membase + sunxi_mux_reg(pin));
    mask = MUX_PINS_MASK < < sunxi_mux_offset(pin);
    writel((val & ~mask) | config < < sunxi_mux_offset(pin),
        pctl- >membase + sunxi_mux_reg(pin));
    raw_spin_unlock_irqrestore(&pctl- >lock, flags);
}

無論有多復雜的代碼,最終都需要通過讀寫寄存器的方式來實現控制芯片,而通過上述代碼分析,即可發現 sunxi_pmx_set() 接口用于配置寄存器,是最底層的接口,可以通過打印輸出傳入的參數,來檢查是否有問題。

PF3 打印輸出為:

[   10.683205] [lmx] irq:148 set int mode pin:163 d- >hwirq:131 func- >muxval:6

PF4 打印輸出為:

[   10.683557] [lmx] irq:149 set int mode pin:196 d- >hwirq:132 func- >muxval:6

這里就能看出很奇怪的地方,PF3 的引腳編號是 163,而 PF4 卻是 196,跨度很大。

通過以下指令查詢 PF4 的正確引腳編號,也可以得知 196 引腳編號是哪一組:

mercury-demo:/ # cat /sys/kernel/debug/pinctrl/pio/pins
registered pins: 137
......
pin 160 (PF0)
pin 161 (PF1)
pin 162 (PF2)
pin 163 (PF3)
pin 164 (PF4)
pin 165 (PF5)
pin 166 (PF6)
......
pin 196 (PG4)
pin 197 (PG5)
......

確認 PF4 正確引腳編號是 164,而 196 對應是 PG4,實際生效的是 PG4,通過以下指令即可確認:

mercury-demo:/sys/kernel/debug/sunxi_pinctrl # echo PG4 > sunxi_pin
mercury-demo:/sys/kernel/debug/sunxi_pinctrl # cat *
pin[PG4] data: 1
pio
pin[PG4] dlevel: 1
pin[PG4] funciton: 6
NOMATCH
pin[PG4] pull: 1
PG4
pin[PG4] funciton: 6
pin[PG4] data: 1
pin[PG4] dlevel: 1
pin[PG4] pull: 1

根據代碼確定引腳編號來源于 pctl->irq_array 數組,通過 pctl->irq_array 賦值的地方進行打印輸出,是否一開始就出錯了:

// drivers/pinctrl/sunxi/pinctrl-sunxi.c
static int sunxi_pinctrl_build_state(struct platform_device *pdev)
{
    ......
    /* Count functions associated groups */
    for (i = 0; i  pctl- >desc- >npins; i++) {
        const struct sunxi_desc_pin *pin = pctl- >desc- >pins + i;
        struct sunxi_desc_function *func = pin- >functions;
        while (func- >name) {
            /* Create interrupt mapping while we're at it */
            if (!strcmp(func- >name, "irq")) {
                int irqnum = func- >irqnum + func- >irqbank * IRQ_PER_BANK;
                pctl- >irq_array[irqnum] = pin- >pin.number;
                printk(KERN_EMERG"[lmx] pctl- >irq_array[%d] = %d   (func- >irqnum:%d func- >irqbank:%d)n", irqnum, pin- >pin.number, func- >irqnum, func- >irqbank);
            }
            sunxi_pinctrl_add_function(pctl, func- >name);
            func++;
        }
    }
    ......
    return 0;
}
// drivers/pinctrl/sunxi/pinctrl-sunxi.h
#define IRQ_PER_BANK        32

1.png

可以發現,PF4(164)對應的索引是 132,原本被正確賦值為 164,但又被覆蓋為 PG4(196)。
不難發現,出現覆蓋的原因是因為 PG4 的 func->irqbank 數值錯誤(4),導致索引下標計算錯誤。

根據前后文來看,func->irqbank 的正確數值應該是 5,代入計算得到正確的值 164:
int irqnum(164) = func->irqnum(4) + func->irqbank(5) * IRQ_PER_BANK(32);

大概率硬件資源描述配置出錯,通過搜索 irqbank 被賦值的方法,來定位描述配置出錯的地方:

// drivers/pinctrl/sunxi/pinctrl-sunxi.h
#define SUNXI_FUNCTION_IRQ_BANK(_val, _bank, _irq)        
    {                            
        .name = "irq",                    
        .muxval = _val,                    
        .irqbank = _bank,                
        .irqnum = _irq,                    
    }

使用的是 SUNXI_FUNCTION_IRQ_BANK 宏,重點檢查第二個參數:

//    drivers/pinctrl/sunxi/pinctrl-sun50iw9p1.c
static const struct sunxi_desc_pin sun50iw9p1_pins[] = {
    ......
    SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 3),
        SUNXI_FUNCTION(0x0, "gpio_in"),
        SUNXI_FUNCTION(0x1, "gpio_out"),
        SUNXI_FUNCTION(0x2, "sdc1"),        /* D1 */
        SUNXI_FUNCTION_IRQ_BANK(0x6, 5, 3),  /*  PG_EINT3    */
        SUNXI_FUNCTION(0x7, "io_disabled")),
    SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 4),
        SUNXI_FUNCTION(0x0, "gpio_in"),
        SUNXI_FUNCTION(0x1, "gpio_out"),
        SUNXI_FUNCTION(0x2, "sdc1"),        /* D2 */
        // 可以發現第二個參數恰好是 4,根據分析結果,以及結合上下文,正確的應該是 5
        SUNXI_FUNCTION_IRQ_BANK(0x6, 4, 4),  /*  PG_EINT4    */
        SUNXI_FUNCTION(0x7, "io_disabled")),
    SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 5),
        SUNXI_FUNCTION(0x0, "gpio_in"),
        SUNXI_FUNCTION(0x1, "gpio_out"),
        SUNXI_FUNCTION(0x2, "sdc1"),        /* D3 */
        SUNXI_FUNCTION_IRQ_BANK(0x6, 5, 5),  /*  PG_EINT5    */
        SUNXI_FUNCTION(0x7, "io_disabled")),
    ......
};

修改之后的 pctl->irq_array 打印輸出正確:

2.png

進行實測,PF4 已經可以正常的被設置為中斷模式。

問題總結

全志原廠提供的 SoCs pinctrl driver 中的 PG4 中斷信息描述錯誤,導致覆蓋了 PF4 的引腳編號,因此只要修正 PG4 的描述信息,即可解決問題。

這個問題不僅僅會影響 PF4 無法使用,也會影響 PG4 引腳無法使用,從代碼來看,想要設置為 PG4 為中斷模式,實際修改的會 PA0(0)。

--- a/longan/kernel/linux-4.9/drivers/pinctrl/sunxi/pinctrl-sun50iw9p1.c
+++ b/longan/kernel/linux-4.9/drivers/pinctrl/sunxi/pinctrl-sun50iw9p1.c
@@ -693,7 +693,7 @@
                SUNXI_FUNCTION(0x0, "gpio_in"),
                SUNXI_FUNCTION(0x1, "gpio_out"),
                SUNXI_FUNCTION(0x2, "sdc1"),            /* D2 */
-               SUNXI_FUNCTION_IRQ_BANK(0x6, 4, 4),  /*  PG_EINT4       */
+               SUNXI_FUNCTION_IRQ_BANK(0x6, 5, 4),  /*  PG_EINT4       */
                SUNXI_FUNCTION(0x7, "io_disabled")),
        SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 5),
                SUNXI_FUNCTION(0x0, "gpio_in"),
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 驅動器
    +關注

    關注

    52

    文章

    8227

    瀏覽量

    146258
  • 寄存器
    +關注

    關注

    31

    文章

    5336

    瀏覽量

    120232
  • Linux系統
    +關注

    關注

    4

    文章

    593

    瀏覽量

    27392
  • IRQ
    IRQ
    +關注

    關注

    0

    文章

    16

    瀏覽量

    10761
收藏 人收藏

    評論

    相關推薦

    T507-C核心板引腳功能修改指引

    飛凌T507-C核心板CPU四核Cortex-A53,1.5GHz主頻;GPUG31 MP2;核心板集成2GB DDR3 RAM,8
    發表于 12-09 09:04

    T507操作小技巧連載1-T507屏幕切換的兩種方式

    、Android、Ubuntu*操作系統,適用于車載電子、電力、醫療、工業控制、物聯網、智能終端等領域。本文不再對硬件參數進行敘述,在參考本文進行軟件開發前請閱讀飛凌嵌入式提供的T507用戶手冊 ,路徑
    發表于 01-14 11:26

    硬件調試筆記--T507電源防漏電設計

    TLV809ED29DBZR的2引腳會輸出低電平導致Q1關閉,FDS4435因為4引腳電平高,所以FDS4435管子關閉不輸出電壓而達到斷電的目的,如圖下圖所示:方法2:參考以下圖,
    發表于 03-23 16:47

    分析筆記】 T507 PF4 引腳無法正常設置中斷模式的問題分析

    相關信息 硬件平臺:T507 系統版本:Android 10/ Linux 4.9.170 問題描述:PF4 無法通過標準接口
    發表于 11-24 10:57

    T507開發板以太網配置方法

    本文硬件平臺采用T507四核車規級處理器設計開發板,本文講解T507開發板以太網配置方法。其它板卡設置略有不同,請參考使用。
    發表于 06-29 11:10 ?1002次閱讀
    <b class='flag-5'>全</b><b class='flag-5'>志</b><b class='flag-5'>T507</b>開發板以太網配置方法

    T507實現SPI轉CAN 全過程的詳細講解

    T507處理器本身不支持CAN功能,那有什么方法可以實現CAN功能呢? 我們已知FETT507-C核心板是支持SPI接口的,但底板沒有引出該接口,所以小編打算通過
    發表于 01-19 11:38 ?2041次閱讀

    詳解T507實現SPI轉CAN功能

      ?T507處理器本身不支持CAN功能,那有什么方法可以實現CAN功能呢?
    發表于 02-10 14:53 ?1220次閱讀
    詳解<b class='flag-5'>全</b><b class='flag-5'>志</b><b class='flag-5'>T507</b>實現SPI轉CAN功能

    T507核心板常見問題解析

    本文硬件平臺采用T507四核車規級處理器設計核心板,本文整理在使用飛凌嵌入式T507產品過程種,常常碰到的幾個問題,其它板卡設置,請參考
    發表于 03-18 16:41 ?1036次閱讀
    <b class='flag-5'>全</b><b class='flag-5'>志</b><b class='flag-5'>T507</b>核心板常見問題解析

    T507處理器如何實現SPI轉CAN功能

    T507處理器本身不支持CAN功能,那有什么方法可以實現CAN功能呢?
    的頭像 發表于 04-15 10:06 ?2541次閱讀

    T507平臺,應用于運動控制行業

    快來戳,快來戳, 天嵌科技的T507平臺 專為運動控制類行業打造的合適Arm 平臺 T507 平臺國產4核A53工業級平臺,支持 Liu
    的頭像 發表于 12-05 17:25 ?1171次閱讀
    <b class='flag-5'>全</b><b class='flag-5'>志</b><b class='flag-5'>T507</b>平臺,應用于運動控制行業

    方案 | 基于T507核心板設計電子AI后視鏡

    電子AI后視鏡終端產品可借助飛凌FETT507-C核心板實現,該核心板基于T507四核車規級處理器設計開發,并且通過了汽車AEC-Q100測試,且FETT
    的頭像 發表于 08-31 18:37 ?1138次閱讀
    方案 | 基于<b class='flag-5'>全</b><b class='flag-5'>志</b><b class='flag-5'>T507</b>核心板設計電子AI后視鏡

    T3(A40I)/T5(T507)性能對比,一代更比一代強

    T3(A40I)/T5(T507)性能對比
    的頭像 發表于 05-27 15:47 ?8347次閱讀
    <b class='flag-5'>全</b><b class='flag-5'>志</b><b class='flag-5'>T</b>3(A40I)/<b class='flag-5'>T</b>5(<b class='flag-5'>T507</b>)性能對比,一代更比一代強

    T507操作小技巧連載2-T507以太網配置方法

    本文硬件平臺采用T507四核車規級處理器設計開發板,本文講解T507開發板以太網配置方法。其它板卡設置略有不同,請參考使用。 一、
    的頭像 發表于 08-31 19:19 ?2674次閱讀
    <b class='flag-5'>全</b><b class='flag-5'>志</b><b class='flag-5'>T507</b>操作小技巧連載2-<b class='flag-5'>T507</b>以太網配置方法

    T507|T507核心板價格|芯片參數配置|資料|原理圖|性能|功耗-飛凌

    T5系列是一個高性能四核CortexTM?– A53處理器,適用于新一代汽車市場。T507系列符合汽車AEC – Q100測試要求。T507
    的頭像 發表于 11-10 17:02 ?2w次閱讀
    <b class='flag-5'>T507</b>|<b class='flag-5'>全</b><b class='flag-5'>志</b><b class='flag-5'>T507</b>核心板價格|芯片參數配置|資料|原理圖|性能|功耗-飛凌

    T507-T507核心板常見問題解析-飛凌嵌入式T507核心板

    本文硬件平臺采用T507四核車規級處理器設計核心板,本文整理在使用飛凌嵌入式T507產品過程種,常常碰到的幾個問題,其它T507板卡
    的頭像 發表于 10-28 17:54 ?1908次閱讀
    <b class='flag-5'>T507</b>-<b class='flag-5'>全</b><b class='flag-5'>志</b><b class='flag-5'>T507</b>核心板常見問題解析-飛凌嵌入式<b class='flag-5'>T507</b>核心板
    主站蜘蛛池模板: 超碰99热在线精品视频| 国产精品1区2区| 乱码国产丰满人妻WWW| 小夫妻天天恶战| 国产精品 中文字幕 亚洲 欧美 | 欧美区一区二| bt成人社区| 秋霞电影网午夜免费鲁丝片| 2012中文字幕在线动漫电影| 久久不射网| 曰产无码久久久久久精品| 无码AV精品一区二区三区| freevideoshd| 久久中文电影| 最新国自产拍天天更新| 蜜臀AV中文字幕熟女人妻| 2020亚洲国产在线播放在线| 久久久久伊人| 99国产精品综合AV无码| 欧美人与动牲交A精品| 超碰97av 在线人人操| 色妺妺免费影院| 国产又黄又粗又爽又色的视频软件 | 在线观看免费av网| 国产九色在线| 亚洲野狼综合网站| 久久这里只有精品无码3D| 99久久婷婷国产综合精品青草 | 亚洲日本va中文字幕久久| 久久午夜夜伦痒痒想咳嗽P| 91久久夜色精品| 国产精选视频在线观看| 欧美zzzoooxxx| 野花日本韩国视频免费高清观看 | 国产精品无码AV天天爽色欲 | 亚洲 国产 日韩 欧美 在线| 99久久人妻无码精品系列性欧美| 久久精品国产96精品亚洲| 午夜视频在线网站| 岛国大片在线播放高清| 免费国产麻豆传|