ひでみのアイデア帳

くだらないことなんだけど、忘れないために・・・

UbuntuのLinux Kernelのアップグレード

UbuntuのLinux Kernelがv4.15.0なのがとっても気になって気持ち悪かったんだよね。

ZynqのLinux Kernelだと迷わずv4.19とか使ったりするのにね・・・

そこでその気持ち悪さを払拭するためにUbuntuのLinux Kernelをアップグレードした。

ukuuのインストール

Ubuntu Kernel Uprade Utilitiesをインストールする。

$ sudo add-apt-repository ppa:teejee2008/ppa
$ sudo apt update
$ sudo apt-get install ukuu

インストールできるバージョンの表示

インストールできるバージョン一覧を表示する。

$ ukuu --list
ukuu v18.9
Distribution: Ubuntu 18.04.1 LTS
Architecture: amd64
Running kernel: 4.15.0-39-generic
Kernel version: 4.15.0.39.42
Cache: /home/hidemi/.cache/ukuu
Temp: /tmp/ukuu/rfzLjLsi
aria2c version: 1.33.1
Fetching index from kernel.ubuntu.com...
OK

Fetching index...

▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ 100 %  

----------------------------------------------------------------------
Found installed: 4.15.0-38.41
Found installed: 4.15.0-39.42
Found installed: 4.15.0.39.41
----------------------------------------------------------------------

======================================================================
Available Kernels
======================================================================
v4.19.2                        4.19.2                    
v4.19.1                        4.19.1                    
v4.19                          4.19                      
v4.18.19                       4.18.19                   
v4.18.18                       4.18.18                   
v4.18.17                       4.18.17                   
v4.18.16                       4.18.16                   
v4.18.15                       4.18.15                   
ずらずらと・・・

インストール

好きなバージョンのLinux Kernelをインストールする。

$ sudo ukuu --install v4.19.2
ukuu v18.9
Distribution: Ubuntu 18.04.1 LTS
Architecture: amd64
Running kernel: 4.15.0-39-generic
Kernel version: 4.15.0.39.42
Cache: /home/hidemi/.cache/ukuu
Temp: /tmp/ukuu/Df01mrEb
aria2c version: 1.33.1

Fetching index...

▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ 100 % 

----------------------------------------------------------------------
Found installed: 4.15.0-39.42
Found installed: 4.15.0.39.41
Found installed: 4.15.0-36.39
----------------------------------------------------------------------

Downloading: 'linux-headers-4.19.2-041902_4.19.2-041902.201811132032_all.deb'... 
OK                                                                    

Downloading: 'linux-headers-4.19.2-041902-generic_4.19.2-041902.201811132032_amd64.deb'... 
OK                                                                    

Downloading: 'linux-image-unsigned-4.19.2-041902-generic_4.19.2-041902.201811132032_amd64.deb'... 
6.4 MB / 8.2 MB, 208.1 KB/s (8s)                            

インストールが完了したらリブートする。

結果

インストール前

$ uname -r
4.15.0-39-generic

インストール後

$ uname -r
4.19.2-041902-generic
2018年11月21日 17時41分00秒 - Permament Link

今日もラック作り

今日も先週に続き、ラックを制作した。

先週作製した本棚が意外に綺麗にデスクの下に収まっているのでここに開発用ラックを追加することにした。

それとデスクと壁の間に50mmの棚を増設して、その50mmのところに電源アダプターとかLANのHUBとか置けるようにしてみた。

まずはデスクと壁の間の棚

こんな感じで棚を作製。

このデスクと壁の間の棚の中段には電源や電源アダプタ、LANのHUBなどを置ける棚がある。

この棚のおかげで電源グッズがかなりスッキリした。

コミックや開発ラックを収納

本日、作製した開発用ラックやコミックをデスクの下に収納すると600mm幅のデスクの真下にラックが全て綺麗に収まるようにした。

これでラックを引っ張り出せばいつでも漫画を読める。

ラックを作製して増殖してた評価ボードや開発環境、コミックが無造作に散乱してたものが片付いてスッキリ綺麗なお部屋になった。

2018年11月18日 21時53分40秒 - Permament Link

ET2018に行ってきた。

お約束のクリスマスツリー。

当の展示会は全くつまらなかった。

Embeddedなの?

Edgeなの?

デバイス関連はChip1StopやMouserがデパート作ってるし・・・

いい天気でしたね。

いい天気でした。

海上保安庁の「いず」です。

赤レンガ倉庫付近。

氷川丸。

最後に夜のクリスマスツリー。

2018年11月15日 23時59分59秒 - Permament Link

本棚を作ってみた

来年の新開発環境を整備するためにまずは漫画を整理し始めた。

と、いうか、こういう本棚が欲しかったんだけど、なかなかちょうどいいサイズが見つからなかったので作った。

3年ぐらいは探してかな?

ディノスやベルメゾンに良さげなのがあるんだけど、俺、コミック専用棚でいいんだよなぁ。

今回は4つの棚を作って、3つはコミック(B6版サイズ)専用で1つはA4サイズの本専用でデスクの下に入るようにした。

本棚

木材はホームセンターで切ってもらって、あとは家でドリルでネジ締めだけ。

皿ネジ止めようの穴を開けてからネジ止めだけど・・・

本棚の下にはキャスターが付いているので引き出せるようになっている。

ちょぉ〜、満足♪

ダンボールで屋根裏に眠っている新旧の漫画を入れ替えたりして、本棚のラインナップを整理。

デスクの上が騒然となっているので来週はデスクの後ろに50mm程度の配線をまとめる棚を作成する予定。

今日のUltra96

昨日のUltra96のPowerDownはUIOで制御にしたら落とせるよってのナシね。

2018年11月11日 22時12分19秒 - Permament Link

Ultra96の電源制御

LTC2954のエラー内容は下記のとおりです。

root@ultra96:~# dmesg | grep -i ltc
[    1.393172] ltc2952-poweroff ltc2954: pm_power_off already registered
[    1.393186] ltc2952-poweroff: probe of ltc2954 failed with error -16

単純に言えば、すでに登録されてしまっているんだなってことだよね。

ということは誰に負けたのかを見つければいいだけで・・・

Devicetreeから逆に追いかけるとltc2954-poweroff.cにたどり着く。

ソースコードをみるとprobeの最初でエラーしていることがわかる。

static int ltc2952_poweroff_probe(struct platform_device *pdev)
{
    int ret;
    struct ltc2952_poweroff *data;

    if (pm_power_off) {
        dev_err(&pdev->dev, "pm_power_off already registered");
        return -EBUSY;
    }

ということはpm_power_offを先にセットした奴を見つければよいのだ。

これは単なる犯人探しゲームのようなものだな。

さて、ざっくりとソースコードからpm_power_off変数にセットする奴を探してみましょう。

grep -R -i pm_power_off|grep pm_power_off
platform/x86/pmc_atom.c:    if (acpi_base_addr != 0 && pm_power_off == NULL)
platform/x86/pmc_atom.c:        pm_power_off = pmc_power_off;
parisc/power.c:         if (pm_power_off)
parisc/power.c:             pm_power_off();
char/ipmi/ipmi_poweroff.c:  old_poweroff_func = pm_power_off;
char/ipmi/ipmi_poweroff.c:  pm_power_off = ipmi_poweroff_function;
char/ipmi/ipmi_poweroff.c:  pm_power_off = old_poweroff_func;
char/ipmi/ipmi_poweroff.c:      pm_power_off = old_poweroff_func;
mfd/tps80031.c: if (pdata->use_power_off && !pm_power_off) {
mfd/tps80031.c:     pm_power_off = tps80031_power_off;
mfd/tps80031.c:     pm_power_off = NULL;
mfd/rn5t618.c:static struct rn5t618 *rn5t618_pm_power_off;
mfd/rn5t618.c:  regmap_update_bits(rn5t618_pm_power_off->regmap, RN5T618_REPCNT,
mfd/rn5t618.c:  regmap_update_bits(rn5t618_pm_power_off->regmap, RN5T618_SLPCNT,
mfd/rn5t618.c:  rn5t618_pm_power_off = priv;
mfd/rn5t618.c:      if (!pm_power_off)
mfd/rn5t618.c:          pm_power_off = rn5t618_power_off;
mfd/rn5t618.c:  if (priv == rn5t618_pm_power_off) {
mfd/rn5t618.c:      rn5t618_pm_power_off = NULL;
mfd/rn5t618.c:      pm_power_off = NULL;
mfd/tps65910.c: if (pmic_plat_data->pm_off && !pm_power_off) {
mfd/tps65910.c:     pm_power_off = tps65910_power_off;
mfd/max8907.c:  if (pm_off && !pm_power_off) {
mfd/max8907.c:      pm_power_off = max8907_power_off;
mfd/palmas.c:       } else if (pdata->pm_off && !pm_power_off) {
mfd/palmas.c:           pm_power_off = palmas_power_off;
mfd/palmas.c:       pm_power_off = NULL;
mfd/retu-mfd.c:static struct retu_dev *retu_pm_power_off;
mfd/retu-mfd.c: struct retu_dev *rdev = retu_pm_power_off;
mfd/retu-mfd.c: mutex_lock(&retu_pm_power_off->mutex);
mfd/retu-mfd.c: mutex_unlock(&retu_pm_power_off->mutex);
mfd/retu-mfd.c: if (i2c->addr == 1 && !pm_power_off) {
mfd/retu-mfd.c:     retu_pm_power_off = rdev;
mfd/retu-mfd.c:     pm_power_off      = retu_power_off;
mfd/retu-mfd.c: if (retu_pm_power_off == rdev) {
mfd/retu-mfd.c:     pm_power_off      = NULL;
mfd/retu-mfd.c:     retu_pm_power_off = NULL;
mfd/tps6586x.c: if (pdata->pm_off && !pm_power_off) {
mfd/tps6586x.c:     pm_power_off = tps6586x_power_off;
mfd/rk808.c:    if (pm_off && !pm_power_off) {
mfd/rk808.c:        pm_power_off = pm_pwroff_fn;
mfd/rk808.c:    pm_power_off = NULL;
mfd/axp20x.c:static struct axp20x_dev *axp20x_pm_power_off;
mfd/axp20x.c:   if (axp20x_pm_power_off->variant == AXP288_ID)
mfd/axp20x.c:   regmap_write(axp20x_pm_power_off->regmap, AXP20X_OFF_CTRL,
mfd/axp20x.c:   if (!pm_power_off) {
mfd/axp20x.c:       axp20x_pm_power_off = axp20x;
mfd/axp20x.c:       pm_power_off = axp20x_power_off;
mfd/axp20x.c:   if (axp20x == axp20x_pm_power_off) {
mfd/axp20x.c:       axp20x_pm_power_off = NULL;
mfd/axp20x.c:       pm_power_off = NULL;
mfd/dm355evm_msp.c: pm_power_off = NULL;
mfd/dm355evm_msp.c: pm_power_off = dm355evm_power_off;
mfd/ab8500-sysctrl.c:   if (!pm_power_off)
mfd/ab8500-sysctrl.c:       pm_power_off = ab8500_power_off;
mfd/ab8500-sysctrl.c:   if (pm_power_off == ab8500_power_off)
mfd/ab8500-sysctrl.c:       pm_power_off = NULL;
mfd/twl4030-power.c:    if (twl4030_power_use_poweroff(pdata, node) && !pm_power_off) {
mfd/twl4030-power.c:        pm_power_off = twl4030_power_off;
rtc/rtc-jz4740.c:       if (!pm_power_off) {
rtc/rtc-jz4740.c:           pm_power_off = jz4740_rtc_power_off;
rtc/rtc-omap.c:     if (!pm_power_off) {
rtc/rtc-omap.c:         pm_power_off = omap_rtc_power_off;
rtc/rtc-omap.c: if (pm_power_off == omap_rtc_power_off &&
rtc/rtc-omap.c:     pm_power_off = NULL;
pinctrl/qcom/pinctrl-msm.c:         pm_power_off = msm_ps_hold_poweroff;
memory/emif.c:      if (pm_power_off) {
memory/emif.c:          WARN(1, "FIXME: NO pm_power_off!!! trying restart\n");
staging/nvec/nvec.c:    pm_power_off = nvec_power_off;
staging/nvec/nvec.c:    pm_power_off = NULL;
power/reset/vexpress-poweroff.c:        pm_power_off = vexpress_power_off;
power/reset/restart-poweroff.c: /* If a pm_power_off function has already been added, leave it alone */
power/reset/restart-poweroff.c: if (pm_power_off != NULL) {
power/reset/restart-poweroff.c:         "pm_power_off function already registered");
power/reset/restart-poweroff.c: pm_power_off = &restart_poweroff_do_poweroff;
power/reset/restart-poweroff.c: if (pm_power_off == &restart_poweroff_do_poweroff)
power/reset/restart-poweroff.c:     pm_power_off = NULL;
power/reset/at91-poweroff.c:    pm_power_off = at91_poweroff;
power/reset/at91-poweroff.c:        pm_power_off = at91_lpddr_poweroff;
power/reset/at91-poweroff.c:    if (pm_power_off == at91_poweroff ||
power/reset/at91-poweroff.c:        pm_power_off == at91_lpddr_poweroff)
power/reset/at91-poweroff.c:        pm_power_off = NULL;
power/reset/Kconfig:      say N here or disable in dts to make sure pm_power_off never be
power/reset/qnap-poweroff.c:    if (pm_power_off) {
power/reset/qnap-poweroff.c:        lookup_symbol_name((ulong)pm_power_off, symname);
power/reset/qnap-poweroff.c:            "pm_power_off already claimed %p %s",
power/reset/qnap-poweroff.c:            pm_power_off, symname);
power/reset/qnap-poweroff.c:    pm_power_off = qnap_power_off;
power/reset/qnap-poweroff.c:    pm_power_off = NULL;
power/reset/gpio-poweroff.c: * since pm_power_off itself is global.
power/reset/gpio-poweroff.c:    /* If a pm_power_off function has already been added, leave it alone */
power/reset/gpio-poweroff.c:    if (pm_power_off != NULL) {
power/reset/gpio-poweroff.c:            "%s: pm_power_off function already registered",
power/reset/gpio-poweroff.c:    pm_power_off = &gpio_poweroff_do_poweroff;
power/reset/gpio-poweroff.c:    if (pm_power_off == &gpio_poweroff_do_poweroff)
power/reset/gpio-poweroff.c:        pm_power_off = NULL;
power/reset/gemini-poweroff.c:  pm_power_off = gemini_poweroff;
power/reset/syscon-poweroff.c:  if (pm_power_off) {
power/reset/syscon-poweroff.c:      lookup_symbol_name((ulong)pm_power_off, symname);
power/reset/syscon-poweroff.c:      "pm_power_off already claimed %p %s",
power/reset/syscon-poweroff.c:      pm_power_off, symname);
power/reset/syscon-poweroff.c:  pm_power_off = syscon_poweroff;
power/reset/syscon-poweroff.c:  if (pm_power_off == syscon_poweroff)
power/reset/syscon-poweroff.c:      pm_power_off = NULL;
power/reset/imx-snvs-poweroff.c:    pm_power_off = do_imx_poweroff;
power/reset/piix4-poweroff.c:   pm_power_off = piix4_poweroff;
power/reset/piix4-poweroff.c:   if (pm_power_off == piix4_poweroff)
power/reset/piix4-poweroff.c:       pm_power_off = NULL;
power/reset/at91-sama5d2_shdwc.c: * since pm_power_off itself is global.
power/reset/at91-sama5d2_shdwc.c:   pm_power_off = at91_poweroff;
power/reset/at91-sama5d2_shdwc.c:       pm_power_off = at91_lpddr_poweroff;
power/reset/at91-sama5d2_shdwc.c:   if (pm_power_off == at91_poweroff ||
power/reset/at91-sama5d2_shdwc.c:       pm_power_off == at91_lpddr_poweroff)
power/reset/at91-sama5d2_shdwc.c:       pm_power_off = NULL;
power/reset/ltc2952-poweroff.c: * This global variable is only needed for pm_power_off. We should
power/reset/ltc2952-poweroff.c: if (pm_power_off) {
power/reset/ltc2952-poweroff.c:     dev_err(&pdev->dev, "pm_power_off already registered");
power/reset/ltc2952-poweroff.c: pm_power_off = ltc2952_poweroff_kill;
power/reset/ltc2952-poweroff.c: pm_power_off = NULL;
power/reset/msm-poweroff.c: pm_power_off = do_msm_poweroff;
power/reset/as3722-poweroff.c:static void as3722_pm_power_off(void)
power/reset/as3722-poweroff.c:  if (!pm_power_off)
power/reset/as3722-poweroff.c:      pm_power_off = as3722_pm_power_off;
power/reset/as3722-poweroff.c:  if (pm_power_off == as3722_pm_power_off)
power/reset/as3722-poweroff.c:      pm_power_off = NULL;
acpi/sleep.c:       pm_power_off_prepare = acpi_power_off_prepare;
acpi/sleep.c:       pm_power_off = acpi_power_off;
regulator/act8865-regulator.c:      if (!pm_power_off && (off_reg > 0)) {
regulator/act8865-regulator.c:          pm_power_off = act8865_power_off;
firmware/psci.c:    pm_power_off = psci_sys_poweroff;
firmware/efi/reboot.c:static void (*orig_pm_power_off)(void);
firmware/efi/reboot.c:  if (orig_pm_power_off)
firmware/efi/reboot.c:      orig_pm_power_off();
firmware/efi/reboot.c:      orig_pm_power_off = pm_power_off;
firmware/efi/reboot.c:      pm_power_off = efi_power_off;
watchdog/bcm2835_wdt.c: if (pm_power_off == NULL)
watchdog/bcm2835_wdt.c:     pm_power_off = bcm2835_power_off;
watchdog/bcm2835_wdt.c: if (pm_power_off == bcm2835_power_off)
watchdog/bcm2835_wdt.c:     pm_power_off = NULL;

これでおおよそ、"pm_power_off = "で、もちろんスペース込みで検索すればさらに犯人を絞れます。

$ grep -R -i pm_power_off|grep "pm_power_off = "
platform/x86/pmc_atom.c:        pm_power_off = pmc_power_off;
char/ipmi/ipmi_poweroff.c:  pm_power_off = ipmi_poweroff_function;
char/ipmi/ipmi_poweroff.c:  pm_power_off = old_poweroff_func;
char/ipmi/ipmi_poweroff.c:      pm_power_off = old_poweroff_func;
mfd/tps80031.c:     pm_power_off = tps80031_power_off;
mfd/tps80031.c:     pm_power_off = NULL;
mfd/rn5t618.c:  rn5t618_pm_power_off = priv;
mfd/rn5t618.c:          pm_power_off = rn5t618_power_off;
mfd/rn5t618.c:      rn5t618_pm_power_off = NULL;
mfd/rn5t618.c:      pm_power_off = NULL;
mfd/tps65910.c:     pm_power_off = tps65910_power_off;
mfd/max8907.c:      pm_power_off = max8907_power_off;
mfd/palmas.c:           pm_power_off = palmas_power_off;
mfd/palmas.c:       pm_power_off = NULL;
mfd/retu-mfd.c:     retu_pm_power_off = rdev;
mfd/retu-mfd.c:     retu_pm_power_off = NULL;
mfd/tps6586x.c:     pm_power_off = tps6586x_power_off;
mfd/rk808.c:        pm_power_off = pm_pwroff_fn;
mfd/rk808.c:    pm_power_off = NULL;
mfd/axp20x.c:       axp20x_pm_power_off = axp20x;
mfd/axp20x.c:       pm_power_off = axp20x_power_off;
mfd/axp20x.c:       axp20x_pm_power_off = NULL;
mfd/axp20x.c:       pm_power_off = NULL;
mfd/dm355evm_msp.c: pm_power_off = NULL;
mfd/dm355evm_msp.c: pm_power_off = dm355evm_power_off;
mfd/ab8500-sysctrl.c:       pm_power_off = ab8500_power_off;
mfd/ab8500-sysctrl.c:       pm_power_off = NULL;
mfd/twl4030-power.c:        pm_power_off = twl4030_power_off;
rtc/rtc-jz4740.c:           pm_power_off = jz4740_rtc_power_off;
rtc/rtc-omap.c:         pm_power_off = omap_rtc_power_off;
rtc/rtc-omap.c:     pm_power_off = NULL;
pinctrl/qcom/pinctrl-msm.c:         pm_power_off = msm_ps_hold_poweroff;
staging/nvec/nvec.c:    pm_power_off = nvec_power_off;
staging/nvec/nvec.c:    pm_power_off = NULL;
power/reset/vexpress-poweroff.c:        pm_power_off = vexpress_power_off;
power/reset/restart-poweroff.c: pm_power_off = &restart_poweroff_do_poweroff;
power/reset/restart-poweroff.c:     pm_power_off = NULL;
power/reset/at91-poweroff.c:    pm_power_off = at91_poweroff;
power/reset/at91-poweroff.c:        pm_power_off = at91_lpddr_poweroff;
power/reset/at91-poweroff.c:        pm_power_off = NULL;
power/reset/qnap-poweroff.c:    pm_power_off = qnap_power_off;
power/reset/qnap-poweroff.c:    pm_power_off = NULL;
power/reset/gpio-poweroff.c:    pm_power_off = &gpio_poweroff_do_poweroff;
power/reset/gpio-poweroff.c:        pm_power_off = NULL;
power/reset/gemini-poweroff.c:  pm_power_off = gemini_poweroff;
power/reset/syscon-poweroff.c:  pm_power_off = syscon_poweroff;
power/reset/syscon-poweroff.c:      pm_power_off = NULL;
power/reset/imx-snvs-poweroff.c:    pm_power_off = do_imx_poweroff;
power/reset/piix4-poweroff.c:   pm_power_off = piix4_poweroff;
power/reset/piix4-poweroff.c:       pm_power_off = NULL;
power/reset/at91-sama5d2_shdwc.c:   pm_power_off = at91_poweroff;
power/reset/at91-sama5d2_shdwc.c:       pm_power_off = at91_lpddr_poweroff;
power/reset/at91-sama5d2_shdwc.c:       pm_power_off = NULL;
power/reset/ltc2952-poweroff.c: pm_power_off = ltc2952_poweroff_kill;
power/reset/ltc2952-poweroff.c: pm_power_off = NULL;
power/reset/msm-poweroff.c: pm_power_off = do_msm_poweroff;
power/reset/as3722-poweroff.c:      pm_power_off = as3722_pm_power_off;
power/reset/as3722-poweroff.c:      pm_power_off = NULL;
acpi/sleep.c:       pm_power_off = acpi_power_off;
regulator/act8865-regulator.c:          pm_power_off = act8865_power_off;
firmware/psci.c:    pm_power_off = psci_sys_poweroff;
firmware/efi/reboot.c:      orig_pm_power_off = pm_power_off;
firmware/efi/reboot.c:      pm_power_off = efi_power_off;
watchdog/bcm2835_wdt.c:     pm_power_off = bcm2835_power_off;
watchdog/bcm2835_wdt.c:     pm_power_off = NULL;

オブジェクトが作成されているか確認する

相当な数を絞って、最後にこの中からオブジェクトになっているソースコードのみに絞ります。

そしたら、下記のように3だけがpm_power_offを書き込むのね。

$ grep -R -i pm_power_off|grep "pm_power_off = "
power/reset/ltc2952-poweroff.c: pm_power_off = ltc2952_poweroff_kill;
firmware/psci.c:    pm_power_off = psci_sys_poweroff;
firmware/efi/reboot.c:      pm_power_off = efi_power_off;

printkを入れて犯人探し

3つぐらいの関数ならprintkを入れて実行した一発で答え出ますよ。

root@ultra96:~# dmesg|grep KNL
[    0.000000] [KNL] psci_0_2_set_functions: ffffff800875d4f8
[    1.395875] [KNL] ltc2952_poweroff_probe: ffffff800875d4f8

ほらね。

犯人はfirmware/psci.cでした。

ここからどうするかです

じゃぁ、firmware/psci.cをロードさせているトリガーは何か探す必要が有ります。

このドライバがDeviceTreeでロードされているのか、それとも固定的に組み込まれているドライバなのか判断する必要が有ります。

もし、固定的なドライバならコンフィグで外せるか、もしくは、固定的に組み込まれて勝てないので諦めるかしなければいけません。

これがもし、DeviceTreeでロードされているなら設定の方法によって対照することができる可能性が残っています。

と、compatibleを見てみると・・・

static const struct of_device_id psci_of_match[] __initconst = {
    { .compatible = "arm,psci", .data = psci_0_1_init},
    { .compatible = "arm,psci-0.2", .data = psci_0_2_init},
    { .compatible = "arm,psci-1.0", .data = psci_0_2_init},
    {},
};

DeviceTreeでロードしてるので確認すると・・・

        idle-states {
            entry-method = "arm,psci";

            CPU_SLEEP_0: cpu-sleep-0 {
                compatible = "arm,idle-state";
                arm,psci-suspend-param = <0x40000000>;
                local-timer-stop;
                entry-latency-us = <300>;
                exit-latency-us = <600>;
                min-residency-us = <10000>;
            };
        };
    psci {
        compatible = "arm,psci-0.2";
        method = "smc";
    };

Ultra96のsysfdを確認するとどうも後者側の方で呼び出されているようです。

そこでDeviceTreeからpsciを無効にしました。

そうすると次のようにLTC2954のドライバが読み込まれました。

[    1.462987] ltc2952-poweroff ltc2954: unable to claim gpio "watchdog"
[    4.328691] ltc2952-poweroff ltc2954: probe successful

ここまでできたのですが、poweroffとかshutdownで電源が落ちません。

しかも、シリアルポートが見えないのでどこまで進んだかわからずじまい・・・

まぁ、落ちなくてもいいかぁ・・・

2018年11月10日 20時52分53秒 - Permament Link