linux pinctrl驱动

转载地址:https://blog.csdn.net/chenliang0224/article/details/78777995

linux系统下采用pinctrl子系统管理所有的IO管脚,并对设备外围管脚(如串口、I2C、spi、LCD)都有相应的配置模式,本博客以pinctrl子系统细说该驱动架构。

1. pinctrl设备注册、退出

[cpp]  view plain  copy
  1. static int __init nuc970_pinctrl_init(void)  
  2. {  
  3.     return platform_driver_register(&nuc970_pinctrl_driver);  
  4. }  
  5. arch_initcall(nuc970_pinctrl_init);  
  6.   
  7. static void __exit nuc970_pinctrl_exit(void)  
  8. {  
  9.     platform_driver_unregister(&nuc970_pinctrl_driver);  
  10. }  
  11.   
  12. module_exit(nuc970_pinctrl_exit);  
[cpp]  view plain  copy
  1. static struct platform_driver nuc970_pinctrl_driver = {  
  2.     .driver = {  
  3.         .name = "pinctrl-nuc970",  
  4.         .owner = THIS_MODULE,  
  5.     },  
  6.     .probe = nuc970_pinctrl_probe,  
  7.     .remove = nuc970_pinctrl_remove,  
  8. };  
[cpp]  view plain  copy
  1. static int nuc970_pinctrl_probe(struct platform_device *pdev)  
  2. {  
  3.     struct pinctrl_dev *pctl;  
  4.   
  5.     pctl = pinctrl_register(&nuc970_pinctrl_desc, &pdev->dev, NULL);  
  6.     if (IS_ERR(pctl))  
  7.         pr_err("could not register NUC970 pin driver\n");  
  8.   
  9.     platform_set_drvdata(pdev, pctl);  
  10.   
  11.     return pinctrl_register_mappings(nuc970_pinmap, ARRAY_SIZE(nuc970_pinmap));  
  12.   
  13. }  
platform平台驱动设备的注册流程都是类似,具体注册流程可参考: 点击打开链接 ,而arch_initcall(...)系统接口函数将注册该驱动,函数路径:inux-3.10.x\include\linux\init.h。现在我们主要分析下结构体struct nuc970_pinctrl_desc管脚描述。

2. struct nuc970_pinctrl_desc

先看下struct pinctrl_desc结构体定义的具体内容:

[cpp]  view plain  copy
  1. struct pinctrl_desc {  
  2.     const char *name; //管脚控制名字  
  3.     struct pinctrl_pin_desc const *pins; //管脚描述,包括管脚编号和管脚字符串描述,见下面!  
  4.     unsigned int npins; //管脚个数  
  5.     const struct pinctrl_ops *pctlops; //管脚控制操作,见下面!  
  6.     const struct pinmux_ops *pmxops; //管脚复用操作,见下面!  
  7.     const struct pinconf_ops *confops; //管脚配置操作,见下面!  
  8.     struct module *owner;  
  9. };  

管脚描述符控制结构体:

[cpp]  view plain  copy
  1. struct pinctrl_pin_desc {  
  2.     unsigned number; //pin管脚值 如:PA01=0x00  
  3.     const char *name; //pin管脚名字 如:PA01="PA0"  
  4. };  

管脚操作结构体:
[cpp]  view plain  copy
  1. struct pinctrl_ops {  
  2.     int (*get_groups_count) (struct pinctrl_dev *pctldev); //一个驱动控制器由哪些管脚构成,这里表示获取多少个控制器设备,见结构体nuc970_pinctrl_groups[]!  
  3.     const char *(*get_group_name) (struct pinctrl_dev *pctldev,  
  4.                        unsigned selector); //每一组控制器都有对应的名字,如下面nuc970_pinctrl_groups[]结构体中第一个成员控制器的名字为“emac0_grp”  
  5.     int (*get_group_pins) (struct pinctrl_dev *pctldev,  
  6.                    unsigned selector,  
  7.                    const unsigned **pins,  
  8.                    unsigned *num_pins); //获取一个驱动控制器由哪些外围管脚构成和管脚的个数,如"emac0_grp"是由“emac0_pins[]”数组构成  
  9.     void (*pin_dbg_show) (struct pinctrl_dev *pctldev, struct seq_file *s,  
  10.               unsigned offset);  
  11.     int (*dt_node_to_map) (struct pinctrl_dev *pctldev,  
  12.                    struct device_node *np_config,  
  13.                    struct pinctrl_map **map, unsigned *num_maps);  
  14.     void (*dt_free_map) (struct pinctrl_dev *pctldev,  
  15.                  struct pinctrl_map *map, unsigned num_maps);  
  16. };  

由于一个控制器设备存在复用管脚,如nuc972 nandflash设备有两路管脚选择,所以我们在实际使用过程中需要选择任意一路,而struct pinmux就是对控制器设备复用选择操作:

[cpp]  view plain  copy
  1. struct pinmux_ops {  
  2.     int (*request) (struct pinctrl_dev *pctldev, unsigned offset);  
  3.     int (*free) (struct pinctrl_dev *pctldev, unsigned offset);  
  4.     int (*get_functions_count) (struct pinctrl_dev *pctldev); //获取管脚复用个数  
  5.     const char *(*get_function_name) (struct pinctrl_dev *pctldev,  
  6.                       unsigned selector); //获取管脚复用名字,如“emac0”  
  7.     int (*get_function_groups) (struct pinctrl_dev *pctldev,  
  8.                   unsigned selector,  
  9.                   const char * const **groups,  
  10.                   unsigned * const num_groups); //获取控制器有多少个复用,我们还是以“emac0”为例,它只对应一个,即“emac0_grp”  
  11.     int (*enable) (struct pinctrl_dev *pctldev, unsigned func_selector,   
  12.                unsigned group_selector); //使能控制器,即配置控制器如果存在管脚复用,在实际使用中需选择一路来运用,下面会介绍  
  13.     void (*disable) (struct pinctrl_dev *pctldev, unsigned func_selector,  
  14.              unsigned group_selector); //释放管脚  
  15.     int (*gpio_request_enable) (struct pinctrl_dev *pctldev,  
  16.                     struct pinctrl_gpio_range *range,  
  17.                     unsigned offset);  
  18.     void (*gpio_disable_free) (struct pinctrl_dev *pctldev,  
  19.                    struct pinctrl_gpio_range *range,  
  20.                    unsigned offset);  
  21.     int (*gpio_set_direction) (struct pinctrl_dev *pctldev,  
  22.                    struct pinctrl_gpio_range *range,  
  23.                    unsigned offset,  
  24.                    bool input);  
  25. };  
管脚配置操作结构体:
[cpp]  view plain  copy
  1. struct pinconf_ops {  
  2. #ifdef CONFIG_GENERIC_PINCONF  
  3.     bool is_generic;  
  4. #endif    
  5.     int (*pin_config_get) (struct pinctrl_dev *pctldev,  
  6.                    unsigned pin,  
  7.                    unsigned long *config);  
  8.     int (*pin_config_set) (struct pinctrl_dev *pctldev,  
  9.                    unsigned pin,  
  10.                    unsigned long config);  
  11.     int (*pin_config_group_get) (struct pinctrl_dev *pctldev,  
  12.                      unsigned selector,  
  13.                      unsigned long *config);  
  14.     int (*pin_config_group_set) (struct pinctrl_dev *pctldev,  
  15.                      unsigned selector,  
  16.                      unsigned long config);  
  17.     int (*pin_config_dbg_parse_modify) (struct pinctrl_dev *pctldev,  
  18.                        const char *arg,  
  19.                        unsigned long *config);  
  20.     void (*pin_config_dbg_show) (struct pinctrl_dev *pctldev,  
  21.                      struct seq_file *s,  
  22.                      unsigned offset);  
  23.     void (*pin_config_group_dbg_show) (struct pinctrl_dev *pctldev,  
  24.                        struct seq_file *s,  
  25.                        unsigned selector);  
  26.     void (*pin_config_config_dbg_show) (struct pinctrl_dev *pctldev,  
  27.                         struct seq_file *s,  
  28.                         unsigned long config);  
  29. };  

上面主要介绍需要用到的结构体,下面我们将一步步分析pinctrl配置:
[cpp]  view plain  copy
  1. static struct pinctrl_desc nuc970_pinctrl_desc = {  
  2.     .name = "nuc970-pinctrl_desc"//见下面  
  3.     .pins = nuc970_pins,  
  4.     .npins = ARRAY_SIZE(nuc970_pins),  
  5.     .pctlops = &nuc970_pctrl_ops, //见下面   
  6.     .pmxops = &nuc970_pmxops,  
  7.     .owner = THIS_MODULE,  
  8. };  

"nuc970_pins"管脚映射结构体:

[cpp]  view plain  copy
  1. const struct pinctrl_pin_desc nuc970_pins[] = {  
  2.     PINCTRL_PIN(0x00, "PA0"),  
  3.     PINCTRL_PIN(0x01, "PA1"),  
  4.     //......  
  5.     PINCTRL_PIN(0x40, "PE0"),  
  6.     PINCTRL_PIN(0x41, "PE1"),  
  7.     PINCTRL_PIN(0x42, "PE2"),  
  8.     PINCTRL_PIN(0x43, "PE3"),  
  9.     PINCTRL_PIN(0x44, "PE4"),  
  10.     PINCTRL_PIN(0x45, "PE5"),  
  11.     PINCTRL_PIN(0x46, "PE6"),  
  12.     PINCTRL_PIN(0x47, "PE7"),  
  13.     PINCTRL_PIN(0x48, "PE8"),  
  14.     PINCTRL_PIN(0x49, "PE9"),  
  15.     PINCTRL_PIN(0x4A, "PE10"),  
  16.     PINCTRL_PIN(0x4B, "PE11"),  
  17.     PINCTRL_PIN(0x4C, "PE12"),  
  18.     PINCTRL_PIN(0x4D, "PE13"),  
  19.     PINCTRL_PIN(0x4E, "PE14"),  
  20.     PINCTRL_PIN(0x4F, "PE15"),  
  21.     PINCTRL_PIN(0x50, "PF0"),  
  22.     PINCTRL_PIN(0x51, "PF1"),  
  23.     PINCTRL_PIN(0x52, "PF2"),  
  24.     PINCTRL_PIN(0x53, "PF3"),  
  25.     PINCTRL_PIN(0x54, "PF4"),  
  26.     PINCTRL_PIN(0x55, "PF5"),  
  27.     PINCTRL_PIN(0x56, "PF6"),  
  28.     PINCTRL_PIN(0x57, "PF7"),  
  29.     PINCTRL_PIN(0x58, "PF8"),  
  30.     PINCTRL_PIN(0x59, "PF9"),  
  31.     PINCTRL_PIN(0x5A, "PF10"),  
  32.     PINCTRL_PIN(0x5B, "PF11"),  
  33.     PINCTRL_PIN(0x5C, "PF12"),  
  34.     PINCTRL_PIN(0x5D, "PF13"),  
  35.     PINCTRL_PIN(0x5E, "PF14"),  
  36.     PINCTRL_PIN(0x5F, "PF15"),  
  37.     //......  
  38. };  

[cpp]  view plain  copy
  1. static struct pinctrl_ops nuc970_pctrl_ops = {  
  2.     .get_groups_count = nuc970_get_groups_count,  
  3.     .get_group_name = nuc970_get_group_name,  
  4.     .get_group_pins = nuc970_get_group_pins,  
  5. };  
结构体的函数比较简单,如下:
[cpp]  view plain  copy
  1. static int nuc970_get_groups_count(struct pinctrl_dev *pctldev)  
  2. {  
  3.     return ARRAY_SIZE(nuc970_pinctrl_groups);  
  4. }  
  5.   
  6. static const char *nuc970_get_group_name(struct pinctrl_dev *pctldev,  
  7.                        unsigned selector)  
  8. {;  
  9.     return nuc970_pinctrl_groups[selector].name;  
  10. }  
  11.   
  12. static int nuc970_get_group_pins(struct pinctrl_dev *pctldev, unsigned selector,  
  13.                    const unsigned ** pins,  
  14.                    unsigned * num_pins)  
  15. {  
  16.     *pins = (unsigned *) nuc970_pinctrl_groups[selector].pins;  
  17.     *num_pins = nuc970_pinctrl_groups[selector].num_pins;  
  18.     return 0;  
  19. }  
这里主要分析上面折几个函数内部调用的“nuc970_pinctrl_groups”结构体,这里已“emac0_grp”为例:
[cpp]  view plain  copy
  1. static const struct nuc970_pinctrl_group nuc970_pinctrl_groups[] = {  
  2.     {  
  3.         .name = "emac0_grp",  
  4.         .pins = emac0_pins,  
  5.         .num_pins = ARRAY_SIZE(emac0_pins),  
  6.         .func = 0x1, //通过查看datasheet “emac0_pins”中的管脚是复用管脚,0x01表示选择选择emac0,如下截图!  
  7.     },  
  8.     {  
  9.         .name = "emac1_grp",  
  10.         .pins = emac1_pins,  
  11.         .num_pins = ARRAY_SIZE(emac1_pins),  
  12.         .func = 0x1,  
  13.     },  
  14.     //......  
  15. }  

这里以“emac0_pins”举例,我们看如下的定义:

[cpp]  view plain  copy
  1. static const unsigned emac0_pins[] = {0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59}; // Port F  
emac0_pins数组中内容16进制数表示对应的管脚,通过上面nuc970_pins结构体可以找到对应关系 0x50~0x59对用port F0~F7管脚。

emac0_pins结构体成员“.func=0x1”表示设置该管脚的寄存器值为1,通过查看下面的截图中红框部分得知它们为emac0的配置!

  

到这里就分析完了“nuc970_pctrl_ops”结构体,接下来我们继续回到“struct nuc970_pinctrl_desc”结构体来分析管脚复用成员“struct nuc970_pmxops”:

[cpp]  view plain  copy
  1. struct pinmux_ops nuc970_pmxops = {  
  2.     .get_functions_count = nuc970_get_functions_count,  
  3.     .get_function_name = nuc970_get_fname,  
  4.     .get_function_groups = nuc970_get_groups,  
  5.     .enable = nuc970_enable,  
  6.     .disable = nuc970_disable,  
  7. };  

nuc970_pmxops结构体中成员函数如下:

[cpp]  view plain  copy
  1. int nuc970_get_functions_count(struct pinctrl_dev *pctldev)  
  2. {  
  3.     return ARRAY_SIZE(nuc970_functions);  
  4. }  
  5.   
  6. const char *nuc970_get_fname(struct pinctrl_dev *pctldev, unsigned selector)  
  7. {  
  8.     return nuc970_functions[selector].name;  
  9. }  
  10.   
  11. static int nuc970_get_groups(struct pinctrl_dev *pctldev, unsigned selector,  
  12.               const char * const **groups,  
  13.               unsigned * const num_groups)  
  14. {  
  15.     *groups = nuc970_functions[selector].groups;  
  16.     *num_groups = nuc970_functions[selector].num_groups;  
  17.     return 0;  
  18. }  
  19.   
  20. /* 
  21.  * selector = data.nux.func, which is entry number in nuc970_functions, 
  22.  * and group = data.mux.group, which is entry number in nuc970_pmx_func 
  23.  * group is not used since some function use different setting between 
  24.  * different ports. for example UART.... 
  25.  */  
[cpp]  view plain  copy
  1.   
[cpp]  view plain  copy
  1. int nuc970_enable(struct pinctrl_dev *pctldev, unsigned selector,  
  2.         unsigned group)  
  3. {  
  4.     unsigned int i, j;  
  5.     unsigned int reg, offset;  
  6.   
  7.     //printk("enable =>%x %x\n", selector, group);  
  8.     for(i = 0; i < nuc970_pinctrl_groups[group].num_pins; i++) {  
  9.         j = nuc970_pinctrl_groups[group].pins[i];  
  10.         /* 
  11.             offset值要分两层意思理解: 
  12.             1. (j >> 4) * 8  
  13.                 表示j/16*8,我们知道管脚PA0~PA15=0x00~0x0f,PB0~PB15=0x10~0x1f,.... 
  14.                 所以,(j >> 4)表示j属于哪一组管脚,如j=0x08,即是PA,j=0x12,即是PB, 
  15.                 而*8呢?通过下面GPA_L,GPA_H,GPB_L,GPB_H可知,GPAL与GPAH相差0x4,而 
  16.                 GPAL与GPBL相差0x08,所以这里的(j >> 4) * 8表示的是当前j属于PA还是PB... 
  17.                  
  18.                 #define REG_MFP_GPA_L   (GCR_BA+0x070)   
  19.                 #define REG_MFP_GPA_H   (GCR_BA+0x074)   
  20.                 #define REG_MFP_GPB_L   (GCR_BA+0x078)   
  21.                 #define REG_MFP_GPB_H   (GCR_BA+0x07C)   
  22.             2. ((j & 0x8) ? 4 : 0) 
  23.                 由1.分析可知(j >> 4) * 8表示属于哪类管脚(PA\PB\PC...), 而((j & 0x8) ? 4 : 0) 
  24.                 表示的是哪类管脚(PA\PB\PC...)的高低字节,即PA_L\PA_H,PB_L\PB_H, PC_L\PC_H 
  25.  
  26.             所以,通过(j >> 4) * 8 + ((j & 0x8) ? 4 : 0)我们可以计算出当前的j是位于哪个管脚配置 
  27.             寄存器EG_MFP_Px_y的哪种功能! 
  28.         */  
  29.         offset = (j >> 4) * 8 + ((j & 0x8) ? 4 : 0);  
  30.   
  31.         reg = __raw_readl(REG_MFP_GPA_L + offset);  
  32.         reg = (reg & ~(0xF << ((j & 0x7) * 4))) | (nuc970_pinctrl_groups[group].func << ((j & 0x7) * 4));  
  33.   
  34.         __raw_writel(reg, REG_MFP_GPA_L + offset);  
  35.     }  
  36.   
  37.     /* SD0 pin value is 0x6, SD1 PI pin value is 0x4, should set the correct value */  
  38.     if (strcmp(nuc970_pinctrl_groups[group].name, "sd01_0_grp") == 0)  
  39.     {  
  40.         for(i = 8; i < nuc970_pinctrl_groups[group].num_pins; i++) {  
  41.             j = nuc970_pinctrl_groups[group].pins[i];  
  42.             offset = (j >> 4) * 8 + ((j & 0x8) ? 4 : 0);  
  43.   
  44.             reg = __raw_readl(REG_MFP_GPA_L + offset);  
  45.             reg = (reg & ~(0xF << ((j & 0x7) * 4))) | (0x4 << ((j & 0x7) * 4));  
  46.   
  47.             __raw_writel(reg, REG_MFP_GPA_L + offset);  
  48.         }  
  49.     }  
  50.     return 0;  
  51. }  

 
 
[cpp]  view plain  copy
  1. /* 
  2.  * By disable a function, we'll switch it back to GPIO 
  3.  */  
  4. void nuc970_disable(struct pinctrl_dev *pctldev, unsigned selector,  
  5.         unsigned group)  
  6. {  
  7.   
  8.     unsigned int i, j;  
  9.     unsigned int reg, offset;  
  10.   
  11.     //printk("disable =>%x %x\n", selector, group);  
  12.     for(i = 0; i < nuc970_pinctrl_groups[group].num_pins; i++) {  
  13.         j = nuc970_pinctrl_groups[group].pins[i];  
  14.         offset = (j >> 4) * 8 + ((j & 0x8) ? 4 : 0); //获取寄存器偏移位置  
  15.   
  16.         reg = __raw_readl(REG_MFP_GPA_L + offset);  
  17.         reg &= ~(0xF << ((j & 0x7) * 4));  
  18.         __raw_writel(reg, REG_MFP_GPA_L + offset);  
  19.     }  
  20.   
  21.     return;  
  22. }  
这里我们主要分析上面函数中“struct nuc970_functions”结构体的作用, 这里还是以“emac0”为例:

[cpp]  view plain  copy
  1. static const struct nuc970_pmx_func nuc970_functions[] = {  
  2.     {  
  3.         .name = "emac0",  
  4.         .groups = emac0_groups,  
  5.         .num_groups = ARRAY_SIZE(emac0_groups),  
  6.     },  
  7.     {  
  8.         .name = "emac1",  
  9.         .groups = emac1_groups,  
  10.         .num_groups = ARRAY_SIZE(emac1_groups),  
  11.     },  
  12.     //.......  
  13. }  

[cpp]  view plain  copy
  1. static const char * const emac0_groups[] = {"emac0_grp"};  
可以看到emac0_groups中内容为“emac0_grp”,这个就是对应我们上面分析到结构体nuc970_pinctrl_groups中的“emac0”,由于我们的“emac0”只有1个,所以emac0_groups中定义“emac0_grp”,例如nandflash有两路,所以就会定义两个,如下:

[cpp]  view plain  copy
  1. static const char * const nand_groups[] = {"nand_0_grp""nand_1_grp"};  

到这里就介绍完了“nuc970_pinctrl_desc”结构体,下面将分析如何注册该结构体。

3. pinctrl_register()

直接上代码:

[cpp]  view plain  copy
  1. static int nuc970_pinctrl_probe(struct platform_device *pdev)  
  2. {  
  3.     struct pinctrl_dev *pctl;  
  4.   
  5.     pctl = pinctrl_register(&nuc970_pinctrl_desc, &pdev->dev, NULL);  
  6.     if (IS_ERR(pctl))  
  7.         pr_err("could not register NUC970 pin driver\n");  
  8.   
  9.     platform_set_drvdata(pdev, pctl);  
  10.   
  11.     return pinctrl_register_mappings(nuc970_pinmap, ARRAY_SIZE(nuc970_pinmap));  
  12.   
  13. }  
管脚注册:
[cpp]  view plain  copy
  1. struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc,  
  2.                     struct device *dev, void *driver_data)  
  3. {  
  4.     struct pinctrl_dev *pctldev;  
  5.     int ret;  
  6.   
  7.     if (!pctldesc)  
  8.         return NULL;  
  9.     if (!pctldesc->name)  
  10.         return NULL;  
  11.   
  12.     pctldev = kzalloc(sizeof(*pctldev), GFP_KERNEL); //分配管脚设备内存  
  13.     if (pctldev == NULL) {  
  14.         dev_err(dev, "failed to alloc struct pinctrl_dev\n");  
  15.         return NULL;  
  16.     }  
  17.   
  18.     /* Initialize pin control device struct */  
  19.     pctldev->owner = pctldesc->owner;  
  20.     pctldev->desc = pctldesc; //将pctrldesc与管脚控制设备绑定  
  21.     pctldev->driver_data = driver_data;  
  22.     INIT_RADIX_TREE(&pctldev->pin_desc_tree, GFP_KERNEL); //初始化“基数树”,关于基数数可自行查相关资料  
  23.     INIT_LIST_HEAD(&pctldev->gpio_ranges); //初始化链表  
  24.     pctldev->dev = dev;  
  25.     mutex_init(&pctldev->mutex); //初始化互彻锁  
  26.   
  27.     /* check core ops for sanity */  
  28.     if (pinctrl_check_ops(pctldev)) {  
  29.         dev_err(dev, "pinctrl ops lacks necessary functions\n");  
  30.         goto out_err;  
  31.     }  
  32.   
  33.     /* If we're implementing pinmuxing, check the ops for sanity */  
  34.     if (pctldesc->pmxops) {  
  35.         if (pinmux_check_ops(pctldev))  
  36.             goto out_err;  
  37.     }  
  38.   
  39.     /* If we're implementing pinconfig, check the ops for sanity */  
  40.     if (pctldesc->confops) {  
  41.         if (pinconf_check_ops(pctldev))  
  42.             goto out_err;  
  43.     }  
  44.   
  45.     /* Register all the pins */  
  46.     dev_dbg(dev, "try to register %d pins ...\n",  pctldesc->npins);  
  47.     ret = pinctrl_register_pins(pctldev, pctldesc->pins, pctldesc->npins); //注册管脚,见下面  
  48.     if (ret) {  
  49.         dev_err(dev, "error during pin registration\n");  
  50.         pinctrl_free_pindescs(pctldev, pctldesc->pins,  
  51.                       pctldesc->npins);  
  52.         goto out_err;  
  53.     }  
  54.   
  55.     mutex_lock(&pinctrldev_list_mutex);  
  56.     list_add_tail(&pctldev->node, &pinctrldev_list); //pinctrldev_list为全局链表,这里将pctrldev设备以节点的形式加入到链表pinctrldev_list中  
  57.     mutex_unlock(&pinctrldev_list_mutex);  
  58.   
  59.     pctldev->p = pinctrl_get(pctldev->dev);  
  60.   
  61.     if (!IS_ERR(pctldev->p)) {  
  62.         pctldev->hog_default =  
  63.             pinctrl_lookup_state(pctldev->p, PINCTRL_STATE_DEFAULT);  
  64.         if (IS_ERR(pctldev->hog_default)) {  
  65.             dev_dbg(dev, "failed to lookup the default state\n");  
  66.         } else {  
  67.             if (pinctrl_select_state(pctldev->p,  
  68.                         pctldev->hog_default))  
  69.                 dev_err(dev,  
  70.                     "failed to select default state\n");  
  71.         }  
  72.   
  73.         pctldev->hog_sleep =  
  74.             pinctrl_lookup_state(pctldev->p,  
  75.                             PINCTRL_STATE_SLEEP);  
  76.         if (IS_ERR(pctldev->hog_sleep))  
  77.             dev_dbg(dev, "failed to lookup the sleep state\n");  
  78.     }  
  79.   
  80.     pinctrl_init_device_debugfs(pctldev);   
  81.   
  82.     return pctldev;  
  83.   
  84. out_err:  
  85.     mutex_destroy(&pctldev->mutex);  
  86.     kfree(pctldev);  
  87.     return NULL;  
  88. }  

[cpp]  view plain  copy
  1. static int pinctrl_register_pins(struct pinctrl_dev *pctldev,  
  2.                  struct pinctrl_pin_desc const *pins,  
  3.                  unsigned num_descs)  
  4. {  
  5.     unsigned i;  
  6.     int ret = 0;  
  7.   
  8.     for (i = 0; i < num_descs; i++) {  
  9.         ret = pinctrl_register_one_pin(pctldev,  
  10.                            pins[i].number, pins[i].name);  
  11.         if (ret)  
  12.             return ret;  
  13.     }  
  14.   
  15.     return 0;  
  16. }  
[cpp]  view plain  copy
  1. static int pinctrl_register_one_pin(struct pinctrl_dev *pctldev,  
  2.                     unsigned number, const char *name)  
  3. {  
  4.     struct pin_desc *pindesc;  
  5.   
  6.     pindesc = pin_desc_get(pctldev, number);    //��δ���忴?????add by cl 20170411 23:41  
  7.     if (pindesc != NULL) {  
  8.         pr_err("pin %d already registered on %s\n", number,  
  9.                pctldev->desc->name);  
  10.         return -EINVAL;  
  11.     }  
  12.   
  13.     pindesc = kzalloc(sizeof(*pindesc), GFP_KERNEL);  
  14.     if (pindesc == NULL) {  
  15.         dev_err(pctldev->dev, "failed to alloc struct pin_desc\n");  
  16.         return -ENOMEM;  
  17.     }  
  18.   
  19.     /* Set owner */  
  20.     pindesc->pctldev = pctldev;  
  21.   
  22.     /* Copy basic pin info */  
  23.     if (name) {  
  24.         pindesc->name = name;  
  25.     } else {  
  26.         pindesc->name = kasprintf(GFP_KERNEL, "PIN%u", number);  
  27.             } else {  
  28.         pindesc->name = kasprintf(GFP_KERNEL, "PIN%u", number);  
  29.         if (pindesc->name == NULL) {  
  30.             kfree(pindesc);  
  31.             return -ENOMEM;  
  32.         }  
  33.         pindesc->dynamic_name = true;  
  34.     }  
  35.   
  36.     radix_tree_insert(&pctldev->pin_desc_tree, number, pindesc); //将管脚值和管脚名称加入到“基数数”里面  
  37.     pr_debug("registered pin %d (%s) on %s\n",  
  38.          number, pindesc->name, pctldev->desc->name);  
  39.     return 0;  
  40. }  
 
 

至此就完成了管脚的注册,接下来分析管脚的映射“pinctrl_register_mappings”。

4. pinctrl_register_mappings()

[cpp] 
相关文章
相关标签/搜索