PCA9555エキスパンダーの#interrupt-cell構成に関する混乱

PCA9555エキスパンダーの#interrupt-cell構成に関する混乱

私のカスタムプラットフォームで初めてデバイスツリーソースファイルを設定しようとしています。ボードにはNXP PCA9555 gpioエクスパンダがあります。デバイスのノードを設定しようとしていますが、少し混乱しています。

私のノードがdtsファイルにある場所は次のとおりです。

ioexp0: gpio-exp@21 {
        compatible = "nxp,pca9555";
        reg = <21>;

        interrupt-parent = <&gpio>;
        interrupts = <8 0>;

        gpio-controller;
        #gpio-cells = <2>;

        /*I don't understand the following two lines*/
        interrupt-controller;
        #interrupt-cells = <2>;
};

私はこれを使ってこれを達成しました。艦隊-388-gp.dtsガイドラインソース。

どのコードがこのプロパティを処理するかについての混乱があります#interrupt-cells。これバインディング文書割り込みデバイスの解釈については何も知らないので、このチップにはまったく役に立ちません。

pca953x_irq_setup機能を見るソースコード#interrupt-cellspca9555ドライバの場合 - このプロパティの処理方法は表示されません。これはLinux割り込み処理コードで処理されますか? 2つの割り込みデバイスが何を意味するのかを知る方法は混乱しています。

pca953x_irq_setupあなたの便宜のために:

static int pca953x_irq_setup(struct pca953x_chip *chip,
                 int irq_base)
{
    struct i2c_client *client = chip->client;
    int ret, i;

    if (client->irq && irq_base != -1
            && (chip->driver_data & PCA_INT)) {
        ret = pca953x_read_regs(chip,
                    chip->regs->input, chip->irq_stat);
        if (ret)
            return ret;

        /*
         * There is no way to know which GPIO line generated the
         * interrupt.  We have to rely on the previous read for
         * this purpose.
         */
        for (i = 0; i < NBANK(chip); i++)
            chip->irq_stat[i] &= chip->reg_direction[i];
        mutex_init(&chip->irq_lock);

        ret = devm_request_threaded_irq(&client->dev,
                    client->irq,
                       NULL,
                       pca953x_irq_handler,
                       IRQF_TRIGGER_LOW | IRQF_ONESHOT |
                           IRQF_SHARED,
                       dev_name(&client->dev), chip);
        if (ret) {
            dev_err(&client->dev, "failed to request irq %d\n",
                client->irq);
            return ret;
        }

        ret =  gpiochip_irqchip_add_nested(&chip->gpio_chip,
                           &pca953x_irq_chip,
                           irq_base,
                           handle_simple_irq,
                           IRQ_TYPE_NONE);
        if (ret) {
            dev_err(&client->dev,
                "could not connect irqchip to gpiochip\n");
            return ret;
        }

        gpiochip_set_nested_irqchip(&chip->gpio_chip,
                        &pca953x_irq_chip,
                        client->irq);
    }

    return 0;
}

デバイスツリーを初めて使用するので、これが私が見逃した部分がはっきりしていることを願っています。

修正する:

説明すると、4.12-rc4現在カーネルバージョンを使用しています。

これで、デバイスツリーの一部のプロパティが誤って理解されたことがわかります。以前は、ドライバがすべての属性を処理する方法を指定する必要があるという印象を受けました。今、私はLinuxが実際に(言葉になる)gpiosようinterruptsな多くの共通属性を扱うことを知りました。

intspecで発生するように変換する方法の詳細な説明は次のとおりですIRQ_TYPE*

この関数はof_irq_parse_one割り込み指定子整数struct of_phandle_args ここ。その後、このパラメータはirq_create_of_mappingコンシューマ関数を介して(たとえば)渡されますof_irq_get。その後、関数はこれらのパラメータをstruct irq_fwspecviaにマッピングしof_phandle_args_to_fwspec、対応するfwspecデータをに渡しますirq_create_fwspec_mappingirqdomain.c。この時点で、irqは私が知っている限りに属するかirq_domain使用することになります。ドライバはデフォルトドメインを使用します。このフィールドは通常、プラットフォーム固有のコードに設定されます。検索して見つけました。irq_default_domainpca853xirq_domain_ops 相互参照。その多くはintspec[1] & IRQ_TYPE_SENSE_MASKviatypeの変数の単純なコピーです。これから型は via of irq に設定されます。irq_create_fwspec_mappingirq_domain_translateirq_datairqd_set_trigger_type

ベストアンサー1

この記事のセクション2を読んでください。指定デバイスの割り込み情報...

2) 割り込みコントローラノード

デバイスは、「割り込みコントローラ」属性を持つ割り込みコントローラとして表示されます。これは空のブール属性です。追加の「#interrupt-cells」属性は、単一の割り込みを指定するために必要なセルの数を定義します。

割り込みコントローラのバインディングは、割り込み指定子の長さとフォーマットを定義するのに役立ちます。次の 2 つのバリエーションが一般的に使用されます。

a) セル


#interrupt-cells プロパティを 1 に設定すると、1 つのセルがコントローラ内の割り込みインデックスを定義します。

例:

   vic: intc@10140000 {
           compatible = "arm,versatile-vic";
           interrupt-controller;
           #interrupt-cells = <1>;
           reg = <0x10140000 0x1000>;
   };

   sic: intc@10003000 {
           compatible = "arm,versatile-sic";
           interrupt-controller;
           #interrupt-cells = <1>;
           reg = <0x10003000 0x1000>;
           interrupt-parent = <&vic>;
           interrupts = <31>; /* Cascaded to vic */
   };

b) 2 つのセル


#interrupt-cells 属性は 2 に設定され、最初のセルはコントローラ内の割り込みインデックスを定義し、2 番目のセルは次のフラグのいずれかを指定するために使用されます。

  • Bits[3:0] トリガタイプとレベルフラグ

    1 = 低エッジから高エッジまでトリガ
    2 = 高エッジから低エッジまでトリガ
    4 = アクティブ高、高感度
    8 = アクティブ低、高感度

例:

   i2c@7000c000 {
           gpioext: gpio-adnp@41 {
                   compatible = "ad,gpio-adnp";
                   reg = <0x41>;

                   interrupt-parent = <&gpio>;
                   interrupts = <160 1>;

                   gpio-controller;
                   #gpio-cells = <1>;

                   interrupt-controller;
                   #interrupt-cells = <2>;

                   nr-gpios = <64>;
           };

           sx8634@2b {
                   compatible = "smtc,sx8634";
                   reg = <0x2b>;

                   interrupt-parent = <&gpioext>;
                   interrupts = <3 0x8>;

                   #address-cells = <1>;
                   #size-cells = <0>;

                   threshold = <0x40>;
                   sensitivity = <7>;
           };
   };

したがって、2セル変換の場合、最初の数字はインデックスであり、2番目の数字は割り込み入力タイプを定義するビットマスクです。

drivers/of/irq.cデバイスツリーのこの部分は(たとえば)のコードによって処理されますof_irq_parse_one()

引用例では、引用した2行はgpio-exp@21device()を割り込みコントローラとして宣言し、それを使用したい他のデバイスは各割り込みに対して2つの単位を提供する必要があります。

gpioこの行のすぐ上には、2つの属性を介して別の割り込みコントローラ(このコントローラではなくエイリアスを持つデバイス)からの割り込みを指定するデバイスの例があります。interrupt-parentあるいは、各割り込みが異なる割り込みを使用できるようにするinterrupts新しい属性を使用することもできます。interrupts-extended親を属性の最初のセルとして指定するコントローラ)。

おすすめ記事