学習を駆動するgpiolibの確立過程


1:gpiolibの学習ポイント
(1)gpiolibの確立プロセス:gpiolibは仮想アドレスマッピングと類似しており、確立も必要である
プロセスのため、学習の時、gpiolibがいつ確立されたのか、確立関数がどこで呼び出されたのかを理解する必要があります.
(2)gpiolibの使用方法:申請、使用、解放
(3)gpiolibのアーキテクチャ:どのディレクトリに関連するファイル
2:gpiolibとは何か、なぜgpiolibを使用する必要があるのか
linuxでは2.6.35以降からgpiolibライブラリがあり、gpiolibの役割はすべてのgpioに対して統一管理を実行することであり、駆動は仕事の時、いくつかの駆動が同じgpioを共同で使用する場合があるからである.これは混乱をもたらす.カーネルはgpioリソースを管理するためのいくつかの方法を提供しています.
3:gpiolibの初期化関数
私たちのmach-smdkc 110.cファイルの
smdkc110_map_io
s5pv210_gpiolib_init  この関数はgpiolibの初期化関数です
smdkc110_map_ioという関数の呼び出し過程は,静的マッピングを解析する際に解析された.
4:構造体struct s 3 c_gpio_chip
struct s3c_gpio_chip
 {
    struct gpio_chipchip;
    struct s3c_gpio_cfg*config;
    struct s3c_gpio_pm*pm;
    void __iomem*base;
    inteint_offset;
    spinlock_t lock;
    #ifdef CONFIG_PM
    u32pm_save[7];
    #endif
};

(1)arch/arm/palt-samsung/include/plat/gpio-core.hにおけるこの構造体
(2)1つのs 3 c_gpio_chip構造体タイプの変数は、1つのgpioポートを記述するために使用することができる(ここでは、IOポートではなく、1つのポートに複数のIOポートがあることに注意してください(一般的には、1つのポートに8つのIOがあります))
(3)struct gpio_が必要chip構造体の要素
const char *label;
この要素は、現在のIOが座っているIOポートの名前を記録するために使用されます.例えば、IOポートGPA 0.0があるIOポートがGPA 0です.
(4)int base;  
現在のIOポートが属するIOポートの番号で、私たちのgpiolibにIOを記録する方法は、各IOのポートベース番号を記録し、1つのIOのポートを通じてこの基準ポートに重ね合わせればいいです.
例:
ポートGPA 0には8個のIOがあり、IOポート番号は0-7であり、基準番号は0、すなわちbase=0である.
ポートGPA 1には4つのIOがあり、IOポート番号は8-11であり、基準番号は8、すなわちbase=8である.
5:s5pv210_gpio_4bit
(1)s5pv210_gpio_4 bitはs 3 c_gpio_chipタイプの構造体配列.
(2)すべてのgpioの.chip構造体のいくつかの要素を初期化し,この配列のすべての要素はデータマニュアルのすべてのgpioに対応している.
(4)解析から分かるように,この配列は現在のMPUにおけるすべてのIOポートと各ポートのIOポートについて統一的に記述されており,この配列があれば,現在の開発ボードに何個のポートがあるか,何個のIOポートがあるか,および各IOポートの番号を知ることができる.
6:s5pv210_gpiolib_init
__init int s5pv210_gpiolib_init(void)
{
    struct s3c_gpio_chip *chip = s5pv210_gpio_4bit;
    int nr_chips = ARRAY_SIZE(s5pv210_gpio_4bit);
    int i = 0;
    for (i = 0; i config == NULL)
        chip->config = &gpio_cfg;
        if (chip->base == NULL)
        chip->base = S5PV210_BANK_BASE(i);
    }
    samsung_gpiolib_add_4bit_chips(s5pv210_gpio_4bit, nr_chips);

    return 0;
}

(1)上記の分析から、s 5 pv 210_gpiolib_Initという関数の役割は,我々の開発ボードのすべてのGPIOのポートを構成し,すべてのGPIOポートに1つの基準ポートの仮想アドレスを割り当て,この基準アドレスによりこのポートのすべてのIOポートのレジスタのアドレスを得ることである.
(2)前にお話ししたように、s 5 pv 210_gpio_4 bitこの配列には開発ボード内のすべてのIOポートの情報がバインドされており、int nr_chips = ARRAY_SIZE(s5pv210_gpio_4bit);我々s 5 pv 210を得るgpio_4 bit配列の要素数、samsung_を呼び出しますgpiolib_add_4bit_chipsという関数は、開発ボードのすべての情報を私たちのシステムに登録し、現在のシステムのIOポートの情報を知ることができます.
7:samsung_gpiolib_add_4bit_chips
void __init samsung_gpiolib_add_4bit_chips(struct s3c_gpio_chip *chip,int nr_chips)
{
    for (; nr_chips > 0; nr_chips--, chip++)
     {
        samsung_gpiolib_add_4bit(chip);   //   chip  +1          
        s3c_gpiolib_add(chip);
    }
}

(1)分析の結果、samsung_gpiolib_add_4 bit内部は実はgpiolibの登録作業ではなく、まだ充填されており、GPIOごとに入力モード/出力モードに設定された操作方法が充填されている.
(2)s3c_gpiolib_add
__init void s3c_gpiolib_add(struct s3c_gpio_chip *chip)
{
    struct gpio_chip *gc = &chip->chip;
    int ret;
    BUG_ON(!chip->base);
    BUG_ON(!gc->label);
    BUG_ON(!gc->ngpio);
    spin_lock_init(&chip->lock);
    if (!gc->direction_input)
    gc->direction_input = s3c_gpiolib_input;
    if (!gc->direction_output)
    gc->direction_output = s3c_gpiolib_output;
    if (!gc->set)
    gc->set = s3c_gpiolib_set;
    if (!gc->get)
    gc->get = s3c_gpiolib_get;
    #ifdef CONFIG_PM
    if (chip->pm != NULL) 
    {
        if (!chip->pm->save || !chip->pm->resume)
        printk(KERN_ERR "gpio: %s has missing PM functions
",gc->label);     }      else         printk(KERN_ERR "gpio: %s has no PM function
", gc->label);     #endif     /* gpiochip_add() prints own failure message on error. */     ret = gpiochip_add(gc);     if (ret >= 0)     s3c_gpiolib_track(chip); }

(1)まず前の解析からsamsung_gpiolib_add_4 bit関数には,我々のinputとoutputメソッドが追加されているので,ここでのifは成立せず,解析関数から,ここで掛けたinputとoutputメソッドは2 bitのCONレジスタのチップ(2440)であることが分かった.
(2)この関数はまず我々のGPIOをさらに充填し,主にsetとgetを追加する方法である.
(3)gpiochip_を呼び出すadd関数は、真の登録を完了します.