zoukankan      html  css  js  c++  java
  • am335x omap serial 驱动分析

    • am335x 自身的 uart 驱动集成在 kernel 的 arch/arm/mach-omap2/ 里面。

    • 文件是 arch/arm/mach-omap2/serial.c

        // 看到最底部 omap_serial_init  入口函数。
        void __init omap_serial_init(void)     
        {                                                 
            omap_serial_board_init(NULL);   // ---> 1.0
        }                  
    
    • 1.0 omap_serial_board_init

        void __init omap_serial_board_init(struct omap_uart_port_info *info)            
        {               
            struct omap_uart_state *uart;     // ---> 1.1
            struct omap_board_data bdata;     // ---> 1.1
            // 这里是轮询所有 uart ,并配置基本的属性一下
            // 在这里,我们主要要弄懂 uart_list 是怎么来的,在哪里被初始化
            list_for_each_entry(uart, &uart_list, node) {           
                bdata.id = uart->num;     
                bdata.flags = 0;   
                bdata.pads = NULL;  
                bdata.pads_cnt = 0;   
                                 
                if (cpu_is_omap44xx() || (cpu_is_omap34xx() &&     
                                    !cpu_is_am33xx()))  
                    omap_serial_fill_default_pads(&bdata);  
                    
                if (!info)  
                    omap_serial_init_port(&bdata, NULL);   // ---> 2.0
                else        
                    omap_serial_init_port(&bdata, &info[uart->num]);  
            }    
        }     
    
    • 1.1 struct omap_uart_state 和 struct omap_board_data

        //  arch/arm/mach-omap2/serial.c
        //  
        struct omap_uart_state {    
            int num;  
            int can_sleep;  
       
            struct list_head node;  
            struct omap_hwmod *oh;  
            struct platform_device *pdev;     
        }; 
        
        //  arch/arm/mach-omap2/mux.h   
        //  struct omap_board_data - board specific device data 
        struct omap_board_data { 
            int         id;   
            u32         flags;   
            struct omap_device_pad  *pads;    
            int         pads_cnt;        
        };   
    
    • 2.0 omap_serial_init_port

        void __init omap_serial_init_port(struct omap_board_data *bdata,                
                struct omap_uart_port_info *info)                                   
        {                                                                               
            struct omap_uart_state *uart;                                               
            struct omap_hwmod *oh;                                                      
            struct platform_device *pdev;                                               
            void *pdata = NULL;                                                         
            u32 pdata_size = 0;                                                         
            char *name;                                                                 
            struct omap_uart_port_info omap_up;                                         
                                                                                    
            if (WARN_ON(!bdata))                                                        
                return;                                                                 
            if (WARN_ON(bdata->id < 0))                                                 
                return;                                                                 
            if (WARN_ON(bdata->id >= num_uarts))                                        
                return;                                                                 
                                                                                    
            list_for_each_entry(uart, &uart_list, node)                                 
                if (bdata->id == uart->num)                                             
                    break;                                                              
            if (!info)                                                                  
                info = omap_serial_default_info;                                        
                                                                                    
            oh = uart->oh;                                                              
            name = DRIVER_NAME;                                                         
                                                                                    
            omap_up.dma_enabled = info->dma_enabled;                                    
            omap_up.uartclk = OMAP24XX_BASE_BAUD * 16;                                  
            omap_up.flags = UPF_BOOT_AUTOCONF;                                          
            omap_up.get_context_loss_count = omap_pm_get_dev_context_loss_count;        
            omap_up.set_forceidle = omap_uart_set_forceidle;                            
            omap_up.set_noidle = omap_uart_set_noidle;                                  
            omap_up.enable_wakeup = omap_uart_enable_wakeup;                            
            omap_up.dma_rx_buf_size = info->dma_rx_buf_size;                            
            omap_up.dma_rx_timeout = info->dma_rx_timeout;                              
            omap_up.dma_rx_poll_rate = info->dma_rx_poll_rate;                          
            omap_up.autosuspend_timeout = info->autosuspend_timeout;                    
                                                                                    
            /* Enable the MDR1 Errata i202 for OMAP2430/3xxx/44xx */                    
            if (!cpu_is_omap2420() && !cpu_is_ti816x())                                 
                omap_up.errata |= UART_ERRATA_i202_MDR1_ACCESS;                         
                                                                                    
            /* Enable DMA Mode Force Idle Errata i291 for omap34xx/3630 */              
            if ((cpu_is_omap34xx() || cpu_is_omap3630()) && !cpu_is_am33xx())           
                omap_up.errata |= UART_ERRATA_i291_DMA_FORCEIDLE;                       
                                                                                   
            pdata = &omap_up;                                                           
            pdata_size = sizeof(struct omap_uart_port_info);                            
                                                                                    
            if (WARN_ON(!oh))                                                           
                return;                                                                 
                                                                                    
            pdev = omap_device_build(name, uart->num, oh, pdata, pdata_size,            
                         NULL, 0, false);                                               
            WARN(IS_ERR(pdev), "Could not build omap_device for %s: %s.
    ",             
                 name, oh->name);                                                       
                                                                                    
            if ((console_uart_id == bdata->id) && no_console_suspend)                   
                omap_device_disable_idle_on_suspend(pdev);                              
                                                                                    
            oh->mux = omap_hwmod_mux_init(bdata->pads, bdata->pads_cnt);                
                                                                                    
            uart->pdev = pdev;                                                          
                                                                                    
            oh->dev_attr = uart;                                                        
                                                                                    
            if (((cpu_is_omap34xx() || cpu_is_omap44xx()) && bdata->pads)               
                    && !uart_debug)                                                     
                device_init_wakeup(&pdev->dev, true);                                   
        }                                                                               
    
  • 相关阅读:
    【洛谷3778】[APIO2017] 商旅(分数规划+Floyd)
    【AT4114】[ARC095D] Permutation Tree(简单题)
    【AT4352】[ARC101C] Ribbons on Tree(容斥+DP)
    【AT4169】[ARC100D] Colorful Sequences(DP)
    【洛谷4581】[BJOI2014] 想法(随机算法)
    【洛谷5659】[CSP-S2019] 树上的数(思维)
    【AT4439】[AGC028E] High Elements(线段树)
    【CF590E】Birthday(AC自动机+二分图匹配)
    【洛谷4298】[CTSC2008] 祭祀(Dilworth定理+二分图匹配)
    【洛谷3774】[CTSC2017] 最长上升子序列(杨表)
  • 原文地址:https://www.cnblogs.com/chenfulin5/p/7081287.html
Copyright © 2011-2022 走看看