MSM8909W watch项目编译问题:
Checking build tools versions...
************************************************************
You asked for an OpenJDK based build but your version is
java version "1.8.0_131" Java(TM) SE Runtime Environment (build 1.8.0_131-b11) Java HotSpot(TM) 64-Bit Server VM (build 25.131-b11, mixed mode).
************************************************************
build/core/main.mk:231: *** stop.
make: *** [out/build-msm8909w.ninja] 错误 1

安装openjdk 1.8,注意要求的是openJDK,不是甲骨文公司的jdk
sudo add-apt-repository ppa:openjdk-r/ppa
sudo apt-get update 
sudo apt-get install openjdk-8-jdk
默认安装目录是:/usr/lib/jvm/java-1.8.0-openjdk-amd64/

用如下命令修改默认jdk,配置默认JDK版本

sudo update-alternatives --install /usr/bin/java java /usr/lib/jvm/java-1.8.0-openjdk-amd64/bin/java 300
sudo update-alternatives --install /usr/bin/javac javac /usr/lib/jvm/java-1.8.0-openjdk-amd64/bin/javac 300
sudo update-alternatives --install /usr/bin/jar jar /usr/lib/jvm/java-1.8.0-openjdk-amd64/bin/jar 300

检查:
whl@whl-Dell:~/work/law_msm8909w_android$ sudo update-alternatives --config java
有 3 个候选项可用于替换 java (提供 /usr/bin/java)。

选择       路径                                          优先级  状态
------------------------------------------------------------
  0            /usr/lib/jvm/java-7-openjdk-amd64/jre/bin/java   1071      自动模式
* 1            /usr/lib/jvm/java-1.8.0-openjdk-amd64/bin/java   300       手动模式
  2            /usr/lib/jvm/java-7-openjdk-amd64/jre/bin/java   1071      手动模式
  3            /usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java   1069      手动模式

sudo update-alternatives --config javac

要维持当前值[*]请按回车键,或者键入选择的编号:

java -version

openjdk version "1.8.0_111"
OpenJDK Runtime Environment (build 1.8.0_111-8u111-b14-3~14.04.1-b14)
OpenJDK 64-Bit Server VM (build 25.111-b14, mixed mode)

make -j8开始编译

Communication error with Jack server (52). Try 'jack-diagnose'
/bin/bash: out/target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediates/jack-rsc.tmp: 是一个目录
ninja: build stopped: subcommand failed.
make: *** [ninja_wrapper] 错误 1

使用命令启动jack:jack-admin start-server
---------------------------------------
Try increasing heap size with java option '-Xmx<size>'.
Warning: This may have produced partial or corrupted output.
[  0% 36/27253] build out/target/common/obj/JAVA_LIBRARIES/sdk_v19_intermediates/classes.jack
ninja: build stopped: subcommand failed.
make: *** [ninja_wrapper] 错误 1

从上面的错误提示中可以看到如下一句:

Try increasing heap size with java option '-Xmx<size>'.

按照上述发现的提示语句,我们对prebuilts/sdk/tools/jack-admin文件进行如下修改:

1.找到如下语句:

JACK_SERVER_COMMAND="java -XX:MaxJavaStackTraceDepth=-1 -Djava.io.tmpdir=$TMPDIR $JACK_SERVER_VM_ARGUMENTS -cp $LAUNCHER_JAR $LAUNCHER_NAME"

2.将上述语句修改为:

JACK_SERVER_COMMAND="java -XX:MaxJavaStackTraceDepth=-1 -Djava.io.tmpdir=$TMPDIR $JACK_SERVER_VM_ARGUMENTS -Xmx4096m -cp $LAUNCHER_JAR $LAUNCHER_NAME"

Android N上的代码编译使用了jack服务,对系统内存有很高的要求,在编译过程中,往往会因为请求不到可用内存而失败,主要是添加了-Xmx4096m参数,接下来在源码目录下执行如下命令重启jack-admin服务:

./prebuilts/sdk/tools/jack-admin stop-server
./prebuilts/sdk/tools/jack-admin start-server

----------------------------------------
4 warnings generated.
[ 10% 2456/22820] build out/target/product/msm8909w/gen/EXECUTABLES/iw_intermediates/version.c
FAILED: /bin/bash -c "external/iw/version.sh out/target/product/msm8909w/gen/EXECUTABLES/iw_intermediates/version.c"
fatal: 没有发现名称,无法描述任何东西。
[ 10% 2456/22820] target thumb C++: logd <= system/core/logd/LogBuffer.cpp
ninja: build stopped: subcommand failed.
make: *** [ninja_wrapper] 错误 1

解决:

vi external/iw/version.sh

可以看到如下:
if [ -d .Git ] && head=`git rev-parse --verify HEAD 2>/dev/null`; then
为了让这个脚本不走[ -d .git ]分支改成如下:
#if [ -d .git ] && head=`git rev-parse --verify HEAD 2>/dev/null`; then
if [ -d .git ] && head=`git rev-parse --verify HEAD 2>/dev/null` && [$VERSION != "4.1"]; then

------------------------
[ 96% 19601/20376] host Java: ahat-tests (out/host/common/obj/JAVA_LIBRARIES/ahat-tests_intermediates/classes)
注: art/tools/ahat/test/SortTest.java使用了未经检查或不安全的操作。
注: 有关详细信息, 请使用 -Xlint:unchecked 重新编译。
[ 96% 19704/20376] host Java: android-icu4j-host (out/host/common/obj/JAVA_LIBRARIES/android-icu4j-host_intermediates/classes)
注: 某些输入文件使用或覆盖了已过时的 API。
注: 有关详细信息, 请使用 -Xlint:deprecation 重新编译。
注: external/icu/android_icu4j/src/main/java/android/icu/impl/Relation.java使用了未经检查或不安全的操作。
注: 有关详细信息, 请使用 -Xlint:unchecked 重新编译。
[ 96% 19749/20376] host Java: android-icu4j-tests-host (out/host/common/obj/JAVA_LIBRARIES/android-icu4j-tests-host_intermediates/classes)
注: 某些输入文件使用或覆盖了已过时的 API。
注: 有关详细信息, 请使用 -Xlint:deprecation 重新编译。
注: 某些输入文件使用了未经检查或不安全的操作。
注: 有关详细信息, 请使用 -Xlint:unchecked 重新编译。
[100% 20376/20376] host Executable: primitives_tests_32 (out/host/linu...6/obj32/EXECUTABLES/primitives_tests_intermediates/primitives_tests32)

解决方法:
make update-api
---------------------
make -j4
Creating filesystem with parameters:
    Size: 1860648960
    Block size: 4096
    Blocks per group: 32768
    Inodes per group: 8112
    Inode size: 256
    Journal blocks: 7097
    Label: data
    Blocks: 454260
    Block groups: 14
    Reserved block group size: 111
Created filesystem with 209/113568 inodes and 17124/454260 blocks
Running ['mkuserimg.sh', '-s', 'out/target/product/msm8909w/data', 'out/target/product/msm8909w/userdata.img', 'ext4', 'data', '1860648960', '-D', 'out/target/product/msm8909w/system', '-L', 'data', 'out/target/product/msm8909w/root/file_contexts.bin'] command, exit code = 0
out/target/product/msm8909w/userdata.img maxsize=1899600384 blocksize=135168 total=40875316 reserve=19193856

#### make completed successfully (11:06 (mm:ss)) ####

编译成功
====================

msm8909w编译user版本问题:
make[1]:正在离开目录 `/home/whl/work/law_msm8909w_android/out/target/product/msm8909w/obj/KERNEL_OBJ'
make: *** [sub-make] 错误 2
make:离开目录“/home/whl/work/law_msm8909w_android/kernel”
[ 86% 30130/35026] target Package: SettingsProvider (out/target/product/msm8909w/obj/APPS/SettingsProvider_intermediates/package.apk)
warning: ignoring flag -c hdpi-v4. Use --preferred-density instead.
warning: ignoring flag -c mdpi-v4. Use --preferred-density instead.
warning: ignoring flag -c hdpi-v4. Use --preferred-density instead.
warning: ignoring flag -c mdpi-v4. Use --preferred-density instead.
[ 86% 30130/35026] target R.java/Manifest.java: Settings (out/target/common/obj/APPS/Settings_intermediates/src/R.stamp)
nothing matches overlay file suw_navbar_ic_back.xml, for flavor anydpi-v21
nothing matches overlay file suw_navbar_ic_more.xml, for flavor anydpi-v21
nothing matches overlay file suw_navbar_ic_next.xml, for flavor anydpi-v21
nothing matches overlay file suw_progress_bar.xml, for flavor v21
ninja: build stopped: subcommand failed.
make: *** [ninja_wrapper] 错误 1
---------------------------
user版本和userdebug版本编译tp驱动的时候都会出现以下问题:

CC      drivers/input/touchscreen/it7259_ts_i2c.o
/home/whl/work/law_msm8909w_android/kernel/drivers/input/touchscreen/it7259_ts_i2c.c: In function 'i2cDirectWriteToIT7259':
/home/whl/work/law_msm8909w_android/kernel/drivers/input/touchscreen/it7259_ts_i2c.c:449:1: warning: the frame size of 1040 bytes is larger than 1024 bytes [-Wframe-larger-than=]
error, forbidden warning: it7259_ts_i2c.c:449
make[4]: *** [drivers/input/touchscreen/it7259_ts_i2c.o] 错误 1
make[3]: *** [drivers/input/touchscreen] 错误 2
make[2]: *** [drivers/input] 错误 2
make[1]: *** [drivers] 错误 2
make[1]: *** 正在等待未完成的任务....
make[1]:正在离开目录 `/home/whl/work/law_msm8909w_android/out/target/product/msm8909w/obj/KERNEL_OBJ'
make: *** [sub-make] 错误 2

重新配置frame size
----------------------
user编译:
make[1]:正在离开目录 `/home/whl/work/law_msm8909w_android/out/target/product/MSM8909W/obj/KERNEL_OBJ'
make: *** [sub-make] 错误 2
make:离开目录“/home/whl/work/law_msm8909w_android/kernel”
[ 86% 30132/35026] target R.java/Manifest.java: Settings (out/target/common/obj/APPS/Settings_intermediates/src/R.stamp)
nothing matches overlay file suw_navbar_ic_back.xml, for flavor anydpi-v21
nothing matches overlay file suw_navbar_ic_more.xml, for flavor anydpi-v21
nothing matches overlay file suw_navbar_ic_next.xml, for flavor anydpi-v21
nothing matches overlay file suw_progress_bar.xml, for flavor v21
ninja: build stopped: subcommand failed.
make: *** [ninja_wrapper] 错误 1

重新编译就没有了
=======================================
user版本打印:
Format: Log Type - Time(microsec) - Message - Optional Info
Log Type: B - Since Boot(Power On Reset),  D - Delta,  S - Statistic
S - QC_IMAGE_VERSION_STRING=BOOT.BF.3.1.2.C3-00012
S - IMAGE_VARIANT_STRING=WAASANAZA
S - OEM_IMAGE_VERSION_STRING=Alan-PC
S - Boot Config, 0x000000e1
B -      1567 - PBL, Start
B -      4543 - bootable_media_detect_entry, Start
B -     64819 - bootable_media_detect_success, Start
B -     64823 - elf_loader_entry, Start
B -     65584 - auth_hash_seg_entry, Start
B -     65843 - auth_hash_seg_exit, Start
B -     80179 - elf_segs_hash_verify_entry, Start
B -    139018 - PBL, End
B -    152286 - SBL1, Start
B -    210175 - boot_flash_init, Start
D -        30 - boot_flash_init, Delta
B -    216763 - boot_config_data_table_init, Start
D -      7869 - boot_config_data_table_init, Delta - (0 Bytes)
B -    229299 - CDT version:3,Platform ID:8,Major ID:1,Minor ID:0,Subtype:9
B -    235490 - pm_device_init, Start
B -    238845 - pm_device_init, TEST - MSM8909 detected
B -    244244 - pm_device_init, INFO - PM8916 is selected
B -    258884 - PM_SET_VAL:Skip
D -     21716 - pm_device_init, Delta
B -    260256 - sbl1_ddr_set_params, Start
B -    262757 - cpr_init, Start
D -         0 - cpr_init, Delta
B -    268308 - Pre_DDR_clock_init, Start
D -       213 - Pre_DDR_clock_init, Delta
D -         0 - sbl1_ddr_set_params, Delta
B -    281271 - pm_driver_init, Start
B -    288194 - --> Charge init
B -      4186 - battery voltage
B -    291671 - boot up
B -        10 - Current status
D -     10736 - pm_driver_init, Delta
B -    303658 - clock_init, Start
D -       152 - clock_init, Delta
B -    354623 - Image Load, Start
D -     21106 - QSEE Image Loaded, Delta - (489660 Bytes)
B -    375760 - Image Load, Start
D -       274 - SEC Image Loaded, Delta - (2048 Bytes)
B -    384025 - sbl1_efs_handle_cookies, Start
D -       610 - sbl1_efs_handle_cookies, Delta
B -    390766 - Image Load, Start
D -     13969 - RPM Image Loaded, Delta - (157664 Bytes)
B -    404796 - Image Load, Start
D -     19581 - APPSBL Image Loaded, Delta - (482464 Bytes)
B -    424438 - QSEE Execution, Start
D -       366 - QSEE Execution, Delta
B -    430172 - SBL1, End
D -    280173 - SBL1, Delta
S - Throughput, 34000 KB/s  (1131836 Bytes,  33117 us)
S - DDR Frequency, 384 MHz
Android Bootloader - UART_DM Initialized!!!
[50] [50] Qseecom Init Done in Appsbl version is 0x405000
[60] [60] secure app region addr=0x87b00000 size=0x100000[60] [60] TZ App region notif returned with status:0 addr:87b00000 size:1048576
[70] [70] TZ App log region register returned with status:0 addr:8f692000 size:4096
[80] [80] Qseecom TZ Init Done in Appsbl
[140] [140] Not able to search the panel:
[640] [640] ERROR: Splash image header invalid
[770] [770] Device is unlocked! Skipping verification...
[5910] [5910] ERROR: Splash image header invalid
[5930] [5930] Authentication Key not yet programmed
[5970] [5970] Qseecom De-Init Done in Appsbl
[5970] [5970] Channel alloc freed

-------------------------------------------
心电厂商给我们的标准是57600波特率,心电的sensor会按照每秒22+8*512=4118字节的速率实时的上报数据,22个字节的固定帧头数据和512帧有效数据,每帧是8个字节,其中8个字节里有2个字节是心电的有效数据,所以标准是每秒我应该获取到512*2=1024字节的有效数据,但是我在串口加了打印,抓了一下log,

diff --git a/kernel/drivers/tty/serial/msm_serial_hs_lite.c b/kernel/drivers/tty/serial/msm_serial_hs_lite.c
index 15d8fb4..8a69360 100755
--- a/kernel/drivers/tty/serial/msm_serial_hs_lite.c
+++ b/kernel/drivers/tty/serial/msm_serial_hs_lite.c
        /* and now the main RX loop */
        while (count > 0) {
+               //printk("===count = %d===\n",count);
                unsigned int c;
                char flag = TTY_NORMAL;
 
                sr = msm_hsl_read(port, regmap[vid][UARTDM_SR]);
                if ((sr & UARTDM_SR_RXRDY_BMSK) == 0) {
+                       printk("===rx 1===\n");
                        msm_hsl_port->old_snap_state -= count;
                        break;
                }
                c = msm_hsl_read(port, regmap[vid][UARTDM_RF]);
+               printk("==c = 0x%8x==\n",c);
                if (sr & UARTDM_SR_RX_BREAK_BMSK) {
                        port->icount.brk++;
+                       printk("===rx 2===\n");
                        if (uart_handle_break(port))
                                continue;
                } else if (sr & UARTDM_SR_PAR_FRAME_BMSK) {
+                       printk("===rx 3===\n");
                        port->icount.frame++;
                } else {
+                       //printk("===rx 4===\n");
                        port->icount.rx++;
         
发现每次基本只能获取到926-999字节的数据,厂商怀疑是不是我们的DMA没有优化好,但是我通过以下方式验证:
 a:高通平台查看DMA传输:
echo 1 > /sys/kernel/debug/msm_serial_hsl/loopback.1 //打开回环开关
adb shell cat /dev/ttyHSL1
另起窗口
# adb shell
# echo 11111111 > /dev/ttyHSL1
若DMA通道ok,控制台会循环显示;

控制台并没有循环显示,而是echo一次,显示一次
--------------------------------------------------------------
修改震动强度:
(1)系统马达震动设置,比如长按屏幕震动:
frameworks/base/core/res/res/values/config.xml
关键字:config_longPressVibePattern

(2)来电震动
设置开关:
packages/apps/Settings/res/values/strings.xml
关键字:vibrate_when_ringing_title

上层调用接口:虽然APK在data下,但是要全编才有效果,make -j4
packages/services/Telecomm/src/com/android/server/telecom/Ringer.java
关键字:
                 mVibrator.vibrate(VIBRATION_PATTERN, VIBRATION_PATTERN_REPEAT,
                         VIBRATION_ATTRIBUTES);
                 mIsVibrating = true;

震动设置:
    private static final long[] VIBRATION_PATTERN = new long[] {
        0, // No delay before starting
        1000, // How long to vibrates
        1000, // How long to wait before vibrating agai
    };

重复设置:
    private static final int VIBRATION_PATTERN_REPEAT = 1;

(3)马达(触觉)驱动:
kernel/drivers/platform/msm/qpnp-haptic.c
设备树文件:
kernel/arch/arm/boot/dts/qcom/msm-pmi8950-oem.dtsi
额定电压:            qcom,vmax-mv = <3000>;
马达规格书,额定电压3V

(4)手动测试马达:
echo "1000" > /sys/class/timed_output/vibrator/enable
震动1S

cat /sys/class/timed_output/vibrator/dump_regs
qpnp_haptics: REG_0xc00b = 0x0
寄存器对应到qpnp-haptic.c驱动
-------------------------------------------------------------------------------------------
SSR子系统重启:
root@msm8953_64:/sys/bus/msm_subsys/devices # cat subsys0/name                 
a506_zap
root@msm8953_64:/sys/bus/msm_subsys/devices # cat subsys1/name                 
venus
root@msm8953_64:/sys/bus/msm_subsys/devices # cat subsys2/name                 
adsp
root@msm8953_64:/sys/bus/msm_subsys/devices # cat subsys3/name                 
wcnss
root@msm8953_64:/sys/bus/msm_subsys/devices # cat subsys4/name                 
modem

dump模式开关的控制节点是
shell@msm8953_64:/ $ cat sys/module/msm_poweroff/parameters/download_mode      
0 表示关 1表示开
-------------------------------------------------------------------------------
persist.sys.usb.config被修改和设置的地方和流程:
1.build/tools/post_process_props.py脚本对android系统下/default.prop文件做去重处理

# Put the modifications that you need to make into the /default.prop into this
# function. The prop object has get(name) and put(name,value) methods.
def mangle_default_prop(prop):
  # If ro.debuggable is 1, then enable adb on USB by default
  # (this is for userdebug builds)
  if prop.get("ro.debuggable") == "1":
    val = prop.get("persist.sys.usb.config")
    if val == "":
      val = "adb"
    else:
      val = val + ",adb"
    prop.put("persist.sys.usb.config", val)
  # UsbDeviceManager expects a value here.  If it doesn't get it, it will
  # default to "adb". That might not the right policy there, but it's better
  # to be explicit.
  if not prop.get("persist.sys.usb.config"):
    #prop.put("persist.sys.usb.config", "none"); set user software build usb default support debug PC port like Diag and so on. lu.xingxian@pubtron.com.cn 20170502
    prop.put("persist.sys.usb.config", "adb");

如果是debug版本,因为persist.sys.usb.config一开始为空,就设置persist.sys.usb.config为adb,所以一开始persist.sys.usb.config设置为adb,如果不为空就在原来基础上加上,adb字段。如果是user版本,persist.sys.usb.config获取不到,我们就把persist.sys.usb.config设置成adb,为了生产测试方便。

注意:
修改该文件def mangle_default_prop(prop):的字段
最终生成的out/target/product/msm8953_64/root/default.prop
所以如果有修改,应该先删除
out/target/product/msm8953_64/root/default.prop,否则make会编译不到。

比如修改val = "wanghl,adb",make -j4之后,out/target/product/msm8953_64/root/default.prop就会变为以下内容:
#
# ADDITIONAL_DEFAULT_PROPERTIES
#
ro.secure=1
security.perf_harden=1
ro.allow.mock.location=0
ro.debuggable=1
ro.zygote=zygote64_32
dalvik.vm.image-dex2oat-Xms=64m
dalvik.vm.image-dex2oat-Xmx=64m
dalvik.vm.dex2oat-Xms=64m
dalvik.vm.dex2oat-Xmx=512m
ro.dalvik.vm.native.bridge=0
debug.atrace.tags.enableflags=0
#
# BOOTIMAGE_BUILD_PROPERTIES
#
ro.bootimage.build.date=2017年 09月 01日 星期五 10:40:10 CST
ro.bootimage.build.date.utc=1504233610
ro.bootimage.build.fingerprint=Android/msm8953_64/msm8953_64:6.0.1/MMB29M/whl09011040:userdebug/test-keys
persist.sys.usb.config=wanghl,adb(恢复出厂的时候变成该值)

可以看到persist.sys.usb.config被改掉了,到时候软件烧录到机子上也可以看到同样的/default.prop被改掉。
这是第一个设置persist.sys.usb.config属性的地方,默认值。
后续有被改动的地方,需要终端下查看:getprop persist.sys.usb.config
wanghl.adb

2.device/qcom/common/rootdir/etc/init.qcom.usb.sh

usb_config=`getprop persist.sys.usb.config`
case "$usb_config" in
    "" | "adb") #USB persist config not set, select default configuration
      case "$esoc_link" in
          "PCIe")
              setprop persist.sys.usb.config diag,diag_mdm,serial_cdev,rmnet_qti_ether,mass_storage,adb
          ;;
          *)
      case "$soc_hwplatform" in
          "Dragon")
              setprop persist.sys.usb.config diag,adb
          ;;
              *)
          case "$target" in
                  ......
              "msm8952" | "msm8953")
              setprop persist.sys.usb.config diag,serial_smd,rmnet_ipa,adb
          ;;
              *)
              setprop persist.sys.usb.config diag,adb
          ;;
              esac
          ;;
      esac
      ;;
      esac
      ;;
  * ) ;; #USB persist config exists, do nothing
esac

如果getprop persist.sys.usb.config为空或者为adb(默认为adb)且是8953平台,就将他设置成:diag,serial_smd,rmnet_ipa,adb。这也是为什么user版本,在persisi.sys.usb.config里面persist.sys.usb.config设置成adb之后就能打开调试口diag口,modem口,网络口,adb口的原因。
如果getprop persist.sys.usb.config存在其他属性值,则什么也不做。保留原来的属性值。
至此,persist.sys.usb.config的属性值就确定下来了
----------------------------------------------------------------------------------------
sys.usb.config属性值被改写的地方和流程:
1.system/core/rootdir/init.usb.rc

# Used to set USB configuration at boot and to switch the configuration
# when changing the default configuration
on property:persist.sys.usb.config=*
    setprop sys.usb.config ${persist.sys.usb.config}

没错,就是它, 这个注册了一个触发器, 意思是当系统使用property更新persist.sys.usb.config的值的话,就同时更新sys.usb.config为同样的值
可以看到:sys.usb.config属性是根据persist.sys.usb.config来设置的。默认就是diag,serial_smd,rmnet_ipa,adb,所以插上USB线之后下来菜单什么也没选中,因为下来菜单的四种状态:Charging,MTP,PTP,MIDI分别对应sys.usb.config的属性值为:
(1)charging
(2)mtp,adb
(3)ptp,adb
(4)midi,adb
所以啥也不会选中。

当sys.usb.config设置成diag,serial_smd,rmnet_ipa,adb属性之后就会在文件:
device/qcom/common/rootdir/etc/init.qcom.usb.pubtron.rc(源文件是init.qcom.usb.rc)匹配上对应的操作。
on property:sys.usb.config=diag,serial_smd,rmnet_ipa,adb && property:sys.usb.configfs=0
    write /sys/class/android_usb/android0/enable 0
    write /sys/class/android_usb/android0/idVendor 05C6   设置VID
    write /sys/class/android_usb/android0/idProduct 9091   设置PID
    write /sys/class/android_usb/android0/f_diag/clients diag
    write /sys/class/android_usb/android0/f_serial/transports smd
    write /sys/class/android_usb/android0/f_rmnet/transports qti,bam2bam_ipa
    write /sys/class/android_usb/android0/functions diag,serial,rmnet,adb
    write /sys/class/android_usb/android0/enable 1
    start adbd  启动adb服务器
    setprop sys.usb.state ${sys.usb.config}  设置sys.usb.state的属性为sys.usb.config

原本的user版本,persist.sys.usb.config被设置为none,这时候sys.usb.config为mtp,所以默认就是mtp模式。但是尚未找到sys.usb.config在哪里被设置成mtp

============================================================================================================================================
  SNS_DDF_SENSOR_PROXIMITY, // 5
  SNS_DDF_SENSOR_AMBIENT, // 6

手挡住灭屏幕:传感器值是0
手拿开亮屏幕:传感器值是5

现在问题是Prox的值一开始是5,然后挡住的时候不会更新值,不会变为0

5脚的LEDA电压正常(规格书要求0.3-4.7V),有问题机器4.3V,没问题机器4.29V,VDD都是2.8V,INT有硬件上拉

SN:902707293815机器是虚焊导致的PROX sensor没反应,重新吹下来再焊接上去就好了。
------------------------------------------------------------------------------
MSM8953手机 NV项目2499这一项用到了
0:RF校准标志
1:酒精校准标志
2:酒精校准标志
------------------------------
IIC
SLA+R/W 共八位
SLA:前七位,表示从机地址(所以最多支持128个从设备),高位在前,地位在后
R/W:最后一位,为READ/WRITE控制位;如果READ/WRITE 为1,则执行读操作;否则执行写操作。

用于定制上层ROM的工程提交注意事项:
ADSP的修改,将编译后的NON—HLOS.bin拷贝到工程目录下的msm8953_android_oem/device/qcom/msm8953_64/radio
用于OTA升级。

修改hardware/libhardware/modules/health/health.c是将编译生成的out/target/product/msm8953_64/system/lib64/hw/health.default.so
拷贝到msm8953_android_oem/frameworks/base/healthmonitor/lib下

------------------------------------------------------------------------
高通panel初始化代码示例
            39 01 00 00 00 00 12 F2 00 77 03 0A 76 03 01 01 82 01 BA 57 00 00 77 0A 76
            39 01 00 00 00 00 0F F4 0B 00 00 00 21 4F 01 02 2A 7F 03 2A 00 03
            39 01 00 00 00 00 0B F5 00 00 00 00 00 11 00 00 04 04
            39 01 00 00 00 00 0A F6 02 01 06 00 06 04 06 74 06
            15 01 00 00 00 00 02 F7 02
            39 01 00 00 00 00 03 F8 33 00
            15 01 00 00 00 00 02 F9 00
            39 01 00 00 00 00 04 E3 84 06 64
            39 01 00 00 00 00 55 FA 1F 06 01 0D 17 1C 21 2B 32 30 32 3F 35 00 06 1F 0A 28 31 35 35 40 4C 51 56 5E 3E 00 19 06 01 11 1D 23 27 2F 35 34 37 56 35 00 06 19 0A 11 2C 32 32 3C 46 4A 50 5A 3E 00 05 05 01 0C 20 29 31 38 3B 36 34 3C 35 00 05 05 0A 2B 2F 2F 2C 33 3C 44 4D 5F 3E 00
            05 01 00 00 A0 00 02 11 00
            05 01 00 00 00 00 02 29 00
-------------------------------------------------------------
msm8909w的TZ部分配置信息:
core/securemsm/trustzone/qsee/include/tzbsp_blsp.h
 typedef struct tzbsp_blsp_peripheral_info_s
 {
    TzBspBlspProtocol  protocol; /* Whether this Peripheral is used for SPI/I2C/UART */
    TzBspBlspIsPersistent  isPersistent; /* Whether the protection should remain for ever starting from TZ Cold Boot and 
                                          * no dynamic switching of BLSP Peripheral b/w TZ and other sub-system. To achieve dynamic 
                                          * owner switching this field should be set to FALSE irrespective of whether cold
                                          * boot protection is enabled or not */
    TzBspBlspGpioProtType  protectionType; /* Whether the MPU/RPU protection is used of GPIO's. For Bear it is MPU and for Badger it is      */
    TzBspBlspPeripheralId  peripheralId; /* Peripheral ID starting from 1 */
    uint32  uPeripheralRgIndex; /* Peripheral (QUP/UART) RG Index */
    uint32  uBlspXpuId; /* XPU Index used for QUP/UART protection */
    uint32  uGpios[TZBSP_BLSP_GPIOS_SUPPORTED]; /* GPIO numbers used for protection and configuring functionality */
    uint32  uNumGpios; /* Total number of GPIO's used */
    uint32  uGpioIndex[TZBSP_BLSP_INDICES_SUPPORTED]; /* Index used for GPIO Protection in Bear targets. 
                                                       * NOTE:: Must contact Qualcomm for index numbers.
                                                       *        Must set unused entries to 0xFFFFFFFF. */
    uint32  uSubSystemId; /* Subsystem ID, tells to which subsystem the QUP/UART and its resources has to be assigned */
    boolean  bIsPeripheralTzUsed; /* TRUE, the QUP/UART is assigned to only TZ or shared between TZ and any other subsystem.
                                   * FALSE, not assigned to TZ (even in Dual EE) */
 } TzBsp_Blsp_Peripheral_Info;

core/securemsm/trustzone/qsee/arch/msm8909/src/tzbsp_blsp_config_8909w.c
/* This structure contains QUP/UART information to be assigned to a subsystem 
 * at cold boot stage, according to the use case.
 * 
 * Note: For GPIO index value, the customer must contact Buses team before 
 * using. The unused indices must be to 0xFFFFFFFF.
 */
 
/*
Information Format::
TZBSP_BLSP_PERIPHERAL_INFO(PROTOCOL, PERSISTENCE, GPIO_PROTECTION_TYPE, 
                    PERIPHERAL_ID, PERIPHERAL_RG_INDEX, BLSP_XPU_ID, 
                    GPIO_1, GPIO_2, GPIO_3, GPIO_4, GPIO_5, GPIO_6, NUM_GPIOS, 
                    GPIO_INDEX_1, GPIO_INDEX_2, GPIO_INDEX_3, SUBSYSTEM_ID, IS_PERIPHERAL_TZ_USED)
*/ 
TzBsp_Blsp_Peripheral_Info  TzBspBlspPeripheralInfo[] = 
{
   /* QUP 1 */
   TZBSP_BLSP_PERIPHERAL_INFO(PROTOCOL_I2C, NON_PERSISTENT, PROTECTION_TYPE_MPU, 
                       BLSP_QUP_1, TZBSP_BAM_BLSP1_RG_QUP0, HAL_XPU2_BAM_BLSP1_DMA,
                       6,7,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,2,
                       0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,TZBSP_NONE_ID,FALSE),

/* QUP 2 */ /* NFC */
   TZBSP_BLSP_PERIPHERAL_INFO(PROTOCOL_I2C, NON_PERSISTENT, PROTECTION_TYPE_MPU, 
                       BLSP_QUP_2, TZBSP_BAM_BLSP1_RG_QUP1, HAL_XPU2_BAM_BLSP1_DMA,
                       111,112,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,2,
                       0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,TZBSP_APSS_ID,FALSE),

/* QUP 3 */
   TZBSP_BLSP_PERIPHERAL_INFO(PROTOCOL_SPI, NON_PERSISTENT, PROTECTION_TYPE_MPU, 
                       BLSP_QUP_3, TZBSP_BAM_BLSP1_RG_QUP2, HAL_XPU2_BAM_BLSP1_DMA,
                       0,1,2,3,0xFFFFFFFF,0xFFFFFFFF,4,
                       0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,TZBSP_NONE_ID,FALSE),

/* QUP 4 */
   TZBSP_BLSP_PERIPHERAL_INFO(PROTOCOL_I2C, NON_PERSISTENT, PROTECTION_TYPE_MPU, 
                       BLSP_QUP_4, TZBSP_BAM_BLSP1_RG_QUP3, HAL_XPU2_BAM_BLSP1_DMA,
                       14,15,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,2,
                       0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,TZBSP_APSS_ID,FALSE),

/* QUP 5 */
   TZBSP_BLSP_PERIPHERAL_INFO(PROTOCOL_I2C, NON_PERSISTENT, PROTECTION_TYPE_MPU, 
                       BLSP_QUP_5, TZBSP_BAM_BLSP1_RG_QUP4, HAL_XPU2_BAM_BLSP1_DMA,
                       18,19,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,2,
                       0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,TZBSP_APSS_ID,FALSE),

/* QUP 6 */ 
   TZBSP_BLSP_PERIPHERAL_INFO(PROTOCOL_SPI, NON_PERSISTENT, PROTECTION_TYPE_MPU, 
                       BLSP_QUP_6, TZBSP_BAM_BLSP1_RG_QUP5, HAL_XPU2_BAM_BLSP1_DMA,
                       8,9,10,11,0xFFFFFFFF,0xFFFFFFFF,4,
                       15,0xFFFFFFFF,0xFFFFFFFF,TZBSP_APSS_ID,FALSE),

/* UART 1 */
   TZBSP_BLSP_PERIPHERAL_INFO(PROTOCOL_UART_2_LINE, NON_PERSISTENT, PROTECTION_TYPE_MPU, 
                       BLSP_UART_1, TZBSP_BAM_BLSP1_RG_UART0, HAL_XPU2_BAM_BLSP1_DMA,
                       4,5,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,2,
                       0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,TZBSP_APSS_ID,FALSE),

/* UART 2 */
   TZBSP_BLSP_PERIPHERAL_INFO(PROTOCOL_UART_2_LINE, NON_PERSISTENT, PROTECTION_TYPE_MPU, 
                       BLSP_UART_2, TZBSP_BAM_BLSP1_RG_UART1, HAL_XPU2_BAM_BLSP1_DMA,
                       20,21,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,2,
                       0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,TZBSP_APSS_ID,FALSE),
};

---------------------------------------------------------------------------
MDSS:Multimedia Display Sub-system

Display driver包括:
    SurfaceFlinger,Hardware Composer(HWC),以及overlay
    Framebuffer
    MIPI DSI驱动

DSI全称是   Display  Serial   Interface,是mipi协议的一个规范。它定义了一个在平台端和panel之间的串行总线和通信协议,总线包括一条  Clock  lane和  1~4条  Date  lane。每条 lane有两条 line(lane+和lane-),差分信号。在高通的  display框架里是  mdp的一部分,用来手机平台端和LCD传送  command和   data。HS mode lanes最大能支持到   1.5Gbps。

DSI只有两种操作模式   command和  video。

(1)command  mode从   host端获取  command和  data。但是这个使用  command  mode
的 LCD有自己的   RAM和  LCD  controller,它会自刷新静态图片。MSM能直接进入休眠,
节约电量。可会多出来 RAM和  Controller的成本。
Command mode的信息是双向的,host能从   panel上读和写数据。Host能同步数据
通过从 panel中读取  Tearing Effect(TE)信号(Vsync)去避免TE。

(2)video mode获取实时的   pixel stream。DSI  Controller必须不停的刷新  image  data,
这个模式一般用于没有 RAM的panel。Host提供  video data和同步信息。同步信息有Vsync、
Hsync、data enable和  pixel clock。Video  mode操作与  RGB接口很类似,但是使用的   pin
脚更少,所以 EMI和无线电干扰更小。

但是目前来说,video模式使用的比较广泛。使用  Command模式的项目还是比较少的。

Mobile display processor MDP 3.05

---------------------------------------------------------------------------------------------------------------------------------------------
vi 删除每一行的第一个字:
:% s/^.\{1\}//g
---------------------
依赖 depends on
这个关键字表示了在某些配置选中后,本配置项才会显示。
反向依赖 select
这个关键字表示了当本配置项选中后,其他的配置项也需要选中。
-----------------------------------------------------------------------
linux用一套键值,android自己用一套键值,两者通过keylayout(kl)文件映射
源文件
frameworks/base/data/keyboards/Generic.kl:407:key 580   APP_SWITCH
frameworks/base/core/java/android/view/KeyEvent.java:547:    public static final int KEYCODE_APP_SWITCH      = 187;
linux 驱动键值是580,andorid APP_SWITCH是187

系统跑起来后,所有*.kl文件在:/system/usr/keylayout

frameworks/base/data/keyboards/qwerty.kl已经不用了,Generic.kl里有说到

getevent可以查看linux键值

--------------------------------
SPI panel移植调试笔记
一、lk部分
int target_cont_splash_screen()
{
    uint8_t splash_screen = 0;
    if (!splash_override) {
        switch (board_hardware_id()) {
        case HW_PLATFORM_SURF:
        case HW_PLATFORM_MTP:
        case HW_PLATFORM_QRD:
        case HW_PLATFORM_RCM:
            splash_screen = 1;
            break;
        default:
            splash_screen = 0;
            break;
        }
        dprintf(SPEW, "Target_cont_splash=%d\n", splash_screen);
    }
    return splash_screen;
}
splash_screen = 1,LK打开连续LOGO显示,splash_screen = 0,LK关闭连续LOGO显示.默认打开。

K8项目默认使用SPI屏幕:
1.
ifeq ($(TARGET_PRODUCT),K8)
DEFINES += PANEL_LH154Q01_CMD=0
DEFINES += PANEL_ST7789V_SPI_CMD=1
endif
2.
#add support for 16bpp(RGB565) format imageBuffer LOGO of K8 SPI panel
ifeq ($(TARGET_PRODUCT),K8)
DEFINES += DISPLAY_TYPE_MIPI=0
else
DEFINES += DISPLAY_TYPE_MIPI=1
endif

如果K8项目想使用MIPI屏幕:
1.
ifeq ($(TARGET_PRODUCT),K8)
DEFINES += PANEL_LH154Q01_CMD=1
DEFINES += PANEL_ST7789V_SPI_CMD=0
endif
2.
#add support for 16bpp(RGB565) format imageBuffer LOGO of K8 SPI panel
ifeq ($(TARGET_PRODUCT),K8)
DEFINES += DISPLAY_TYPE_MIPI=1
else
DEFINES += DISPLAY_TYPE_MIPI=1
endif

开机显示流程:
1.初始化显示小企鹅logo:msm_display_init ->  display_image_on_screen,mipi会先fetch_image_from_partition();从分区中获取LOGO,获取不到才显示的imageBuffer_rgb888格式的图片数组,spi是直接显示imageBuffer(SPI只能配置成16bpp,否则判断失败不显示logo)

2.产生DEV_UNLOCK事件,进入ORANGE启动状态,boot_verifier: Device is in ORANGE boot state.
display_bootverify_menu_thread(DISPLAY_MENU_ORANGE);显示启动菜单:
Start > Continue boot ...那个界面
fbcon_setup函数设置颜色格式
display_fbcon_menu_message("press VOLUME keys\n\n",
        FBCON_SUBTITLE_MSG, common_factor);用来显示菜单内容,和显示logo一样,最后也是用fbcon_flush来刷新缓存内容
display_menu_thread_start(bootverify_menu_msg_info);创建一个按键检测任务,如果有音量按键按下会弹出display_bootverify_menu_thread(DISPLAY_MENU_RED);或display_bootverify_menu_thread(DISPLAY_MENU_YELLOW);等其他菜单
3.wait_for_users_action();->display_image_on_screen();超时或POWER按键按下之后再次刷新LOGO

在gcdb_display_cmdline_arg会传递屏幕类型信息到cmdline
#if PANEL_ST7789V_SPI_CMD
else if (target_is_spi())
default_str = "0:spi:0";
#endif
就像PANEL_ST7789V_SPI_CMD,如果有添加其他SPI屏幕,应该把宏开关添加到这里#if (PANEL_ST7789V_SPI_CMD || PANEL_*_SPI_CMD)

------------
LK的屏幕的头文件的和Kernel的dtsi文件通过qcom,mdss_spi_st7789v_cmd对应联系起来
lk:    bootable/bootloader/lk/dev/gcdb/display/include/panel_st7789v_spi_cmd.h
static struct panel_config st7789v_spi_cmd_panel_data = {
    "qcom,mdss_spi_st7789v_cmd", "spi:0:", "qcom,mdss-spi-panel",
    10, 0, "DISPLAY_1", 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};

kernel:    kernel/arch/arm/boot/dts/qcom/spi-panel-gc9305-qvga-cmd.dtsi
&mdss_mdp {
    spi_st7789v_cmd: qcom,mdss_spi_st7789v_cmd {
        qcom,mdss-spi-panel-name = "st7789v command mode spi panel";
        qcom,mdss-spi-panel-destination = "display_1";
        qcom,mdss-spi-panel-controller = <&mdss_spi>;
-----------------------------------------------------------------
+config FB_MSM_MDSS_SPI_PANEL
+       depends on FB_MSM_MDSS
+       bool "Support SPI panel feature"
+       default n
+       ---help---
+       The MDSS SPI Panel provides support for transmitting SPI signals of
+       MDSS frame buffer data to connected panel. Limited by SPI rate, the
+       current max fps only reach to 27fps, and limited by MDP hardware
+       architecture only supply on MDP3.

受限于SPI的速率(15.15152M):
240*240*16(bpp)*16帧 = 14745600 < 15151520
240*240*16(bpp)*17帧 = 15667200 > 15151520
所以设置
spi-max-frequency = <15151520>;
qcom,mdss-spi-panel-framerate = <16>;

如果spi-max-frequency设置的太高会出现画面跑到开机动画之后就不刷新了,就卡在开机动画界面
--------------------------------------------
/system/bin/mm-pp-daemon
是一个根据显示内容自动调节亮度的一个服务
SPI屏幕调试的时候一直报错,
<13>[  119.018869] init: Starting service 'ppd'...
<13>[  119.135770] init: Service 'ppd' (pid 3521) exited with status 255
<13>[  119.140934] init: Service 'ppd' (pid 3521) killing any children in process group

所以在脚本device/qcom/K8/init.target.rc注释掉该服务,然后重新编译kernel即可。

pr_debug("=== 1.mdp3_ctrl_on\n");//不能打印出来
pr_err("===2.mdp3_ctrl_on===\n");//能打印出来
pr_warning("===3.mdp3_ctrl_on===\n");//能打印出来
pr_info("===4.mdp3_ctrl_on===\n");//能打印出来

=======================================================================
du -lh --max-depth=1 : 查看当前目录下一级子文件和子目录占用的磁盘容量。
=======================================================================
修改开机动画文件:frameworks/base/core/res/assets/images/android-logo-mask.png
编译:mmm frameworks/base/core/res/
最好要更新一下时间戳:touch frameworks/base/core/res/assets/images/*,不然很可能编译不到
编译后生成APK是
out/target/product/K8/system/framework/framework-res.apk
framework-res.apk改为framework-res.zip可以解压看到一些源文件
=============
SPI和DSI有区别的配置:
1.lk
--- a/bootable/bootloader/lk/dev/gcdb/display/gcdb_display.c
+++ b/bootable/bootloader/lk/dev/gcdb/display/gcdb_display.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2014, 2017, The Linux Foundation. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -216,6 +216,8 @@ bool gcdb_display_cmdline_arg(char *panel_name, char *pbuf, uint16_t buf_size)
                } else {
                        if (target_is_edp())
                                default_str = "0:edp:";
+                       /*else if (target_is_spi())
+                               default_str = "0:spi:0";*/
                        else
                                default_str = "0:dsi:0:";
 
@@ -285,6 +287,57 @@ end:
        return ret;
 }

0:spi:0参数会传递给kernel,如果lk判断target_is_spi()为真则kernel不会匹配到dsi的屏幕
Kernel command line: sched_enable_hmp=0 console=ttyHSL0,115200,n8 androidboot.console=ttyHSL0 androidboot.hardware=qcom msm     _rtb.filter=0x237 ehci-hcd.park=3 androidboot.bootdevice=7824900.sdhci lpm_levels.sleep_disabled=1 earlyprintk buildvariant=userdebug andr     oidboot.bootdevice=7824900.sdhci androidboot.verifiedbootstate=orange androidboot.veritymode=enforcing androidboot.keymaster=1 androidboot     .serialno=2e591f71 androidboot.baseband=msm mdss_mdp3.panel=0:dsi:0:

2.lk
diff --git a/bootable/bootloader/lk/target/msm8909/oem_panel.c b/bootable/bootloader/lk/target/msm8909/oem_panel.c
index ba54226..3765237 100644
--- a/bootable/bootloader/lk/target/msm8909/oem_panel.c
+++ b/bootable/bootloader/lk/target/msm8909/oem_panel.c

case UNKNOWN_PANEL:
        default:
                memset(panelstruct, 0, sizeof(struct panel_struct));
@@ -573,9 +588,10 @@ int oem_panel_select(const char *panel_name, struct panel_struct *panelstruct,
                                        panel_id = AUO_H245QBN02_CMD_PANEL;
                                #elif defined(PANEL_LH154Q01_CMD)/* whl@pubtron.com.cn 20171012 */
                                        panel_id = LH154Q01_CMD_PANEL;
+                                       //panel_id = GC9305_QVGA_SPI_CMD_PANEL;
                                #else
                                        panel_id = AUO_CX_QVGA_CMD_PANEL;
-                               #endif
+                               #endif                                  
                             }
                                else
                                        panel_id = HX8394D_480P_VIDEO_PANEL;

3.内核
diff --git a/kernel/arch/arm/boot/dts/qcom/msm8909-mtp.dtsi b/kernel/arch/arm/boot/dts/qcom/msm8909-mtp.dtsi
index 5fac90f..7474789 100644
--- a/kernel/arch/arm/boot/dts/qcom/msm8909-mtp.dtsi
+++ b/kernel/arch/arm/boot/dts/qcom/msm8909-mtp.dtsi
@@ -350,6 +350,7 @@
 };
 
 &mdss_mdp {
+       //qcom,mdss-pref-prim-intf = "spi";
        qcom,mdss-pref-prim-intf = "dsi";
 };
 
@@ -439,6 +440,15 @@
        };
 };
 
+&mdss_spi {
+       qcom,spi-pref-prim-pan = <&spi_gc9305_qvga_cmd>;
+       pinctrl-names = "mdss_default", "mdss_sleep";
+       pinctrl-0 = <&mdss_te_active>;
+       pinctrl-1 = <&mdss_te_suspend>;
+
+       qcom,platform-te-gpio = <&msm_gpio 24 0>;
+       qcom,platform-reset-gpio = <&msm_gpio 25 0>;
+ };
 
 &mdss_dsi0 {
        qcom,dsi-pref-prim-pan = <&dsi_hx8394d_720_vid>;

1.对比和patch有差异的地方
(1)kernel/include/linux/mdss_io_util.h   msm8909w代码enable_load/disable_load是放在load[DSS_REG_MODE_ENABLE]/load[DSS_REG_MODE_DISABLE]里
(2)内存管理接口有不一样的地方

=====================================
ubuntu下挂载远程文件系统/目录
sudo sshfs wanghl@192.168.1.46:/home/wanghl/work /home/whl/remote_server -o idmap=user -o allow_other
-----------------------------------------------------------------------------------------------------------
diff --git a/device/qcom/K8/init.target.rc b/device/qcom/K8/init.target.rc
index 7914bae..9574c73 100755
--- a/device/qcom/K8/init.target.rc
+++ b/device/qcom/K8/init.target.rc
@@ -147,12 +147,12 @@ service wcnss-service /system/bin/wcnss_service
     group system wifi radio
     oneshot
 
-service ppd /system/bin/mm-pp-daemon
-    class late_start
-    disabled
-    user system
-    socket pps stream 0660 system system
-    group system graphics
+#service ppd /system/bin/mm-pp-daemon
+#    class late_start
+#    disabled
+#    user system
+#    socket pps stream 0660 system system
+#    group system graphics
 
 service per_mgr /system/bin/pm-service

动画在logcat报错
frameworks/base/cmds/bootanimation/BootAnimation.cpp:274:           ALOGE("Get Carrier Animation file,since it's not support carrier");
logcat.txt:1395:01-01 01:12:49.071   649   973 E BootAnimation: Get Carrier Animation file,since it's not support carrier
logcat.txt:1396:01-01 01:12:49.072   649   973 E BootAnimation: Get Carrier Animation file,since it's not support carrier

-----------

录制视频:
adb root;adb remount;adb shell;
system/bin/screenrecord data/1.mp4 --time-limit 30
adb pull

========================
AFE4400血氧芯片
LED1 (IR) and LED2 (Red)
512HZ配合心电测量PPG血压的时候,只上报LED1红外值,因为我们硬件只接了一个红外灯,没有接红光灯。
=========================================================================
H10 OTG调试:
基本流程,MSM8909的VBUS不带有输出5V的能力,所以需要增加外围提供5V输出的电路,
OTG设备插入之后,USB_ID硬件被拉低,USB驱动里的状态机会去拉高OTG_EN,使能外部的DC-DC电路输出5V给OTG设备供电,
同时硬件电路会断开模块VBUS与硬件VBUS的连接。

1:串口执行cat /sys/kernel/debug/gpio
127|la2017:/ # cat /sys/kernel/debug/gpio
GPIOs 588-619, platform/qcom,smp2pgpio-ssr-smp2p-1-out.17, master-kernel:

GPIOs 620-651, platform/qcom,smp2pgpio-ssr-smp2p-1-in.16, slave-kernel:

GPIOs 652-683, platform/qcom,smp2pgpio-ssr-smp2p-4-out.15, master-kernel:

GPIOs 684-715, platform/qcom,smp2pgpio-ssr-smp2p-4-in.14, slave-kernel:

GPIOs 716-747, platform/qcom,smp2pgpio-smp2p-4-out.12, smp2p:

GPIOs 748-779, platform/qcom,smp2pgpio-smp2p-4-in.10, smp2p:

GPIOs 780-811, platform/qcom,smp2pgpio-smp2p-1-out.8, smp2p:

GPIOs 812-843, platform/qcom,smp2pgpio-smp2p-1-in.6, smp2p:

GPIOs 844-875, platform/qcom,smp2pgpio-smp2p-7-out.4, smp2p:

GPIOs 876-907, platform/qcom,smp2pgpio-smp2p-7-in.2, smp2p:

GPIOs 908-909, spmi/qpnp-pin-3, pm8909-gpio:
 gpio-908 (hsusb-otg-vbus-en   ) out hi->说明已经执行了拉高操作!

GPIOs 910-910, spmi/qpnp-pin-2, pm8909-mpp:

GPIOs 911-1023, platform/1000000.pinctrl, msm_tlmm_gpio:
 gpio-927 (mmr901xa_rpt        ) in  hi
 gpio-928 (pump_vdd_en         ) out hi
 gpio-943 (bid0_gpio           ) in  lo
 gpio-949 (7864900.sdhci cd    ) in  hi
 gpio-999 ([auto]              ) out hi
 gpio-1001 (volume_up           ) in  hi
 gpio-1002 (volume_down         ) in  hi
 gpio-1005 (afe4400_gpio_int    ) in  lo
 gpio-1009 (MLX_VDD_EN          ) out hi
 gpio-1010 (motor_ctrl_pin      ) out lo」

2:从模块上量下pm8909_gpio1的电平
    0.8V,正常应该是1.8V,说明PMU_GPIO_1的配置有问题
3:cat /sys/kernel/debug/msm_otg/otg_state
la2017:/ # cat /sys/kernel/debug/msm_otg/otg_state
a_wait_bcon,正常应该是a_host

4:打开usb相关动态log:
echo 8 > /proc/sys/kernel/printk
echo 'file phy-msm-usb.c +p' > /sys/kernel/debug/dynamic_debug/control
echo 'file udc-core.c +p' > /sys/kernel/debug/dynamic_debug/control
echo 'file ci13xxx_msm.c +p' > /sys/kernel/debug/dynamic_debug/control

拔出OTG设备再插入的LOG:
[  496.087688] msm_otg_set_suspend(1) in a_wait_bcon state
[  496.087915] host bus suspend
[  496.087960] AFE4400 spi3.0: afe_spo2_suspend
[  496.088522] mlx90615 1-005b: MLX90615_suspend
[  496.088539] bma2x2-accel 1-0018: bma2x2_suspend
[  496.088559] bma2x2-accel 1-0018: bma2x2_set_enable enable = 0
[  496.091377] msm_otg 78d9000.usb: OTG PM suspend
[  496.091396] msm_otg 78d9000.usb: LPM ENTER START:inputs=0x100,state=9
[  496.114689] PM: suspend of devices complete after 38.744 msecs
[  496.115998] PM: late suspend of devices complete after 1.288 msecs
[  496.117662] PM: noirq suspend of devices complete after 1.650 msecs
[  496.117675] Disabling non-boot CPUs ...
[  496.121212] CPU0:msm_cpu_pm_enter_sleep mode:3 during suspend
[  496.122047] Enabling non-boot CPUs ...
[  496.123645] CPU3 is up
[  496.124553] PM: noirq resume of devices complete after 0.888 msecs
[  496.126428] PM: early resume of devices complete after 0.851 msecs
[  496.131466] msm_otg 78d9000.usb: OTG PM resume
[  496.131602] [15:14:50.405375] [000000031F5E7562] [VosRX]  wlan: [E :WDI] WDTS_RxPacketDump RX Data frame is UC
[  496.131626] [15:14:50.405403] [000000031F5E7769] [VosRX]  wlan: [E :WDI] WDTS_RxPacketDump: Data subtype:8 SA:ec:88:8f:d2:a5:3e DA:b4:36:a9:4a:3a:21
[  496.131688] [15:14:50.405464] [000000031F5E7C0C] [VosRX]  wlan: [E :HDD] hdd_log_ip_addr: src addr 203:208:41:55
[  496.131704] [15:14:50.405482] [000000031F5E7D57] [VosRX]  wlan: [E :HDD] hdd_log_ip_addr: dst addr 192:168:119:112
[  496.147569] bma2x2-accel 1-0018: bma2x2_resume
[  496.147597] mlx90615 1-005b: MLX90615_resume
[  496.147872] AFE4400 spi3.0: afe_spo2_resume
[  496.148119] msm_otg_set_suspend(0) in a_wait_bcon state
[  496.148144] msm_otg 78d9000.usb: OTG runtime resume
[  496.148163] msm_otg 78d9000.usb: LPM EXIT START:inputs=0x140,state=9
[  496.173136] msm_otg 78d9000.usb: USB exited from low power mode
[  496.238088] PM: resume of devices complete after 111.638 msecs
[  496.411728] Restarting tasks ... [  496.415650] msm_otg_set_suspend(0) in a_wait_bcon state
[  496.421752] IPC_RTR: msm_ipc_router_bind: pm-service Do not have permissions
done.
[  496.431183] msm_otg 78d9000.usb: OTG PM notify:4, sm_pending:0
[  496.432479] msm_otg_set_suspend(1) in a_wait_bcon state
[  496.432490] host bus suspend
[  496.432558] a_wait_bcon work
[  496.432579] msm_otg 78d9000.usb: OTG runtime idle
[  496.432593] msm_otg 78d9000.usb: OTG runtime suspend
[  496.432609] msm_otg 78d9000.usb: LPM ENTER START:inputs=0x100,state=9
[  496.432616] msm_bam_device_lpm_ok: Going to LPM now
[  496.432631] msm_otg 78d9000.usb: LPM ENTER 1:inputs=0x100,state=9
[  496.432641] msm_otg 78d9000.usb: LPM ENTER 2:inputs=0x100,state=9
[  496.432652] msm_otg 78d9000.usb: LPM ENTER 2:B_SESS_VLD=0,device_bus_suspend=0,dcp=0,prop_charger=0,floated_charger=0
[  496.432659] msm_otg 78d9000.usb: LPM ENTER 2:A_BUS_REQ=0,sm_work_busy=0
[  496.432667] msm_otg 78d9000.usb: LPM ENTER 3:inputs=0x100,state=9
[  496.432678] msm_otg 78d9000.usb: LPM ENTER 4:inputs=0x100,state=9
[  496.432685] msm_otg 78d9000.usb: LPM ENTER 6:inputs=0x100,state=9
[  496.432698] msm_otg_enable_phy_hv_int: bsv_id_hv = 1 dp_dm_hv_int = 1
[  496.432748] msm_otg 78d9000.usb: LPM ENTER 7:inputs=0x100,state=9
[  496.432756] msm_otg 78d9000.usb: LPM ENTER 8:inputs=0x100,state=9
[  496.535958] PM: suspend exit 2018-10-19 07:14:50.809728927 UTC
[  496.539570] msm_otg 78d9000.usb: LPM ENTER 9:inputs=0x100,state=9
[  496.539594] msm_otg 78d9000.usb: LPM caps = 90 flags = 12
[  496.539601] msm_otg 78d9000.usb: USB in low power mode
[  496.728120] IPC_RTR: msm_ipc_router_bind: pm-service Do not have permissions
[  496.873671] IPC_RTR: msm_ipc_router_bind: pm-service Do not have permissions
[  496.916184] PM: suspend entry 2018-10-19 07:14:51.189949083 UTC
[  496.921089] PM: Syncing filesystems ... done.
[  496.929747] msm_otg 78d9000.usb: OTG PM notify:3, sm_pending:0
[  496.934593] Freezing user space processes ... [  496.943403] Error: returning -512 value
(elapsed 0.010 seconds) done.
[  496.951584] Freezing remaining freezable tasks ... (elapsed 0.003 seconds) done.
[  496.962270] Suspending console(s) (use no_console_suspend to debug)

[  496.982163] msm_otg_set_suspend(1) in a_wait_bcon state
[  496.982177] host bus suspend
[  496.982230] AFE4400 spi3.0: afe_spo2_suspend
[  496.983513] mlx90615 1-005b: MLX90615_suspend
[  496.983534] bma2x2-accel 1-0018: bma2x2_suspend
[  496.983556] bma2x2-accel 1-0018: bma2x2_set_enable enable = 0
[  496.989645] msm_otg 78d9000.usb: OTG PM suspend
[  496.989670] msm_otg 78d9000.usb: LPM ENTER START:inputs=0x100,state=9
[  496.997116] PM: suspend of devices complete after 26.876 msecs
[  496.998413] PM: late suspend of devices complete after 1.284 msecs
[  497.000389] PM: noirq suspend of devices complete after 1.963 msecs
[  497.000405] Disabling non-boot CPUs ...
[  497.004138] CPU0:msm_cpu_pm_enter_sleep mode:3 during suspend
[  497.005617] Enabling non-boot CPUs ...
[  497.007941] CPU2 is up
[  497.009299] PM: noirq resume of devices complete after 1.326 msecs
[  497.010150] OTG IRQ: 172 in LPM
[  497.010242] PHY ID IRQ in LPM
[  497.011695] PM: early resume of devices complete after 1.183 msecs
[  497.016058] msm_otg 78d9000.usb: OTG PM resume
[  497.016094] msm_otg 78d9000.usb: LPM EXIT START:inputs=0x100,state=9
[  497.036740] msm_otg 78d9000.usb: ID status_w
[  497.036958] ID set
[  497.037047] msm_otg 78d9000.usb: USB exited from low power mode
[  497.061292] bma2x2-accel 1-0018: bma2x2_resume
[  497.061331] mlx90615 1-005b: MLX90615_resume
[  497.061708] AFE4400 spi3.0: afe_spo2_resume
[  497.061842] msm_otg_set_suspend(0) in a_wait_bcon state
[  497.138326] PM: resume of devices complete after 126.597 msecs
[  497.276500] Restarting tasks ... [  497.281161] msm_otg_set_suspend(0) in a_wait_bcon state
done.
[  497.301774] msm_otg 78d9000.usb: OTG PM notify:4, sm_pending:1
[  497.308398] PM: suspend exit 2018-10-19 07:15:35.050993076 UTC
[  497.309521] a_wait_bcon work
[  497.309540] (id && id_a/b/c) || a_bus_drop ||a_wait_bcon_tmout
[  497.309563] deleting a_wait_vrise timer. remaining -1677 msec
[  497.309581] msm_otg 78d9000.usb: host off
[  497.309604] msm_hsusb_host msm_hsusb_host: remove, state 85
[  497.309678] usb usb1: USB disconnect, device number 1
[  497.330847] cma: dma_release_from_contiguous(pfn af0dc)
[  497.330878] cma: dma_release_from_contiguous(pfn af0d5)
[  497.330944] msm_hsusb_host msm_hsusb_host: USB bus 1 deregistered
[  497.331558] starting a_wait_vfall timer
[  497.333931] msm_otg_set_suspend(1) in a_wait_vfall state
[  497.375857] IPC_RTR: msm_ipc_router_bind: pm-service Do not have permissions
[  497.516795] IPC_RTR: msm_ipc_router_bind: pm-service Do not have permissions
[  497.707974] IPC_RTR: msm_ipc_router_bind: pm-service Do not have permissions
[  497.833054] expired a_wait_vfall timer
[  497.836872] IPC_RTR: msm_ipc_router_bind: pm-service Do not have permissions
[  497.843421] a_wait_vfall work
[  497.846134] a_idle work
[  497.848288] id && !id_a
[  497.850790] b_idle work
[  497.853146] chg_work cancel
[  497.855938] msm_otg 78d9000.usb: OTG runtime suspend
[  497.860885] msm_otg 78d9000.usb: LPM ENTER START:inputs=0x1,state=1
[  497.867210] msm_bam_device_lpm_ok: Going to LPM now
[  497.871994] msm_otg 78d9000.usb: LPM ENTER 1:inputs=0x1,state=1
[  497.878201] msm_otg 78d9000.usb: LPM ENTER 2:inputs=0x1,state=1
[  497.883792] msm_otg 78d9000.usb: LPM ENTER 2:B_SESS_VLD=0,device_bus_suspend=0,dcp=0,prop_charger=0,floated_charger=0
[  497.894907] msm_otg 78d9000.usb: LPM ENTER 2:A_BUS_REQ=0,sm_work_busy=0
[  497.901604] msm_otg 78d9000.usb: LPM ENTER 3:inputs=0x1,state=1
[  497.907587] msm_otg 78d9000.usb: LPM ENTER 4:inputs=0x1,state=1
[  497.912786] msm_otg 78d9000.usb: LPM ENTER 6:inputs=0x1,state=1
[  497.918949] msm_otg_enable_phy_hv_int: bsv_id_hv = 1 dp_dm_hv_int = 0
[  497.925116] USB PHY is in retention
[  497.928757] msm_otg 78d9000.usb: LPM ENTER 7:inputs=0x1,state=1
[  497.937090] msm_hsusb_ldo_enable: USB reg mode (2) (OFF/HPM/LPM)
[  497.942094] msm_hsusb_config_vddcx: min_vol:0 max_vol:1200000
[  497.948433] msm_otg 78d9000.usb: LPM ENTER 8:inputs=0x1,state=1
[  497.970630] msm_otg 78d9000.usb: LPM ENTER 9:inputs=0x1,state=1
[  497.975656] msm_otg 78d9000.usb: LPM caps = 90 flags = 30
[  497.976193] PM: suspend entry 2018-10-19 07:15:35.718804117 UTC
[  497.976824] IPC_RTR: msm_ipc_router_bind: pm-service Do not have permissions
[  497.982006] PM: Syncing filesystems ... done.
[  497.999428] msm_otg 78d9000.usb: USB in low power mode
[  498.000031] msm_otg 78d9000.usb: OTG PM notify:3, sm_pending:0
[  498.004386] Error: returning -512 value
[  498.000087] Freezing user space processes ... (elapsed 0.067 seconds) done.
[  498.073710] Freezing remaining freezable tasks ... (elapsed 0.004 seconds) done.
[  498.084438] Suspending console(s) (use no_console_suspend to debug)
[  498.105482] AFE4400 spi3.0: afe_spo2_suspend
[  498.105977] mlx90615 1-005b: MLX90615_suspend
[  498.105998] bma2x2-accel 1-0018: bma2x2_suspend
[  498.106031] bma2x2-accel 1-0018: bma2x2_set_enable enable = 0
[  498.110741] msm_otg 78d9000.usb: OTG PM suspend
[  498.110767] msm_otg 78d9000.usb: LPM ENTER START:inputs=0x1,state=1
[  498.126138] PM: suspend of devices complete after 33.602 msecs
[  498.127562] PM: late suspend of devices complete after 1.407 msecs
[  498.129888] PM: noirq suspend of devices complete after 2.312 msecs
[  498.129912] Disabling non-boot CPUs ...
[  498.134808] CPU0:msm_cpu_pm_enter_sleep mode:3 during suspend
[  498.135779] Enabling non-boot CPUs ...
[  498.137331] CPU1 is up
[  498.138210] PM: noirq resume of devices complete after 0.858 msecs
[  498.138899] PHY ID IRQ in LPM
[  498.139904] PM: early resume of devices complete after 0.819 msecs
[  498.142115] msm_otg 78d9000.usb: OTG PM resume
[  498.142138] msm_otg 78d9000.usb: LPM EXIT START:inputs=0x1,state=1
[  498.160833] msm_hsusb_ldo_enable: USB reg mode (3) (OFF/HPM/LPM)
[  498.160850] msm_hsusb_config_vddcx: min_vol:1200000 max_vol:1200000
[  498.160864] msm_otg_disable_phy_hv_int: bsv_id_hv = 1 dp_dm_hv_int = 0
[  498.161072] USB PHY is exited from retention
[  498.161149] msm_otg 78d9000.usb: ID status_w
[  498.161359] ID clear
[  498.161375] msm_otg 78d9000.usb: USB exited from low power mode
[  498.178219] bma2x2-accel 1-0018: bma2x2_resume
[  498.178245] mlx90615 1-005b: MLX90615_resume
[  498.178513] AFE4400 spi3.0: afe_spo2_resume
[  498.252493] PM: resume of devices complete after 112.570 msecs
[  498.396348] Restarting tasks ... done.
[  498.413979] msm_otg 78d9000.usb: OTG PM notify:4, sm_pending:1
[  498.419808] b_idle work
[  498.421722] !id || id_A
[  498.424472] a_idle work
[  498.427175] PM: suspend exit 2018-10-19 07:15:39.142090470 UTC
[  498.432243] !a_bus_drop && (a_srp_det || a_bus_req)
[  498.437967] IPC_RTR: msm_ipc_router_bind: pm-service Do not have permissions
[  498.444554] starting a_wait_vrise timer
[  498.549024] expired a_wait_vrise timer
[  498.551973] a_wait_vrise work
[  498.554721] a_vbus_vld
[  498.557184] msm_otg 78d9000.usb: host on
[  498.560978] msm_hsusb_host msm_hsusb_host: EHCI Host Controller
[  498.570474] msm_hsusb_host msm_hsusb_host: new USB bus registered, assigned bus number 1
[  498.577888] cma: dma_alloc_from_contiguous(cma 00000000, count 1, align 0)
[  498.586062] cma: dma_alloc_from_contiguous(): returned af0d5
[  498.586202] IPC_RTR: msm_ipc_router_bind: pm-service Do not have permissions
[  498.598173] cma: dma_alloc_from_contiguous(cma 00000000, count 1, align 0)
[  498.606200] cma: dma_alloc_from_contiguous(): returned af0dc
[  498.610970] msm_hsusb_host msm_hsusb_host: irq 166, io mem 0x078d9000
[  498.635883] msm_hsusb_host msm_hsusb_host: USB 2.0 started, EHCI 1.00
[  498.641408] msm_otg_set_suspend(0) in a_wait_bcon state
[  498.647185] usb usb1: New USB device found, idVendor=1d6b, idProduct=0002
[  498.653295] usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1
[  498.660850] usb usb1: Product: EHCI Host Controller
[  498.665431] usb usb1: Manufacturer: Linux 3.10.49 ehci_hcd
[  498.670828] usb usb1: SerialNumber: msm_hsusb_host
[  498.682872] hub 1-0:1.0: USB hub found
[  498.686299] hub 1-0:1.0: 1 port detected
[  498.721426] IPC_RTR: msm_ipc_router_bind: pm-service Do not have permissions
[  498.786845] msm_otg_set_suspend(1) in a_wait_bcon state
[  498.791063] host bus suspend
[  498.794386] a_wait_bcon work
[  498.797857] msm_otg 78d9000.usb: OTG runtime idle
[  498.801553] msm_otg 78d9000.usb: OTG runtime suspend
[  498.806647] msm_otg 78d9000.usb: LPM ENTER START:inputs=0x100,state=9
[  498.812913] msm_bam_device_lpm_ok: Going to LPM now
[  498.818041] msm_otg 78d9000.usb: LPM ENTER 1:inputs=0x100,state=9
[  498.823861] msm_otg 78d9000.usb: LPM ENTER 2:inputs=0x100,state=9
[  498.830288] msm_otg 78d9000.usb: LPM ENTER 2:B_SESS_VLD=0,device_bus_suspend=0,dcp=0,prop_charger=0,floated_charger=0
[  498.840645] msm_otg 78d9000.usb: LPM ENTER 2:A_BUS_REQ=0,sm_work_busy=0
[  498.847309] msm_otg 78d9000.usb: LPM ENTER 3:inputs=0x100,state=9
[  498.853609] msm_otg 78d9000.usb: LPM ENTER 4:inputs=0x100,state=9
[  498.859334] msm_otg 78d9000.usb: LPM ENTER 6:inputs=0x100,state=9
[  498.865470] msm_otg_enable_phy_hv_int: bsv_id_hv = 1 dp_dm_hv_int = 1
[  498.866063] IPC_RTR: msm_ipc_router_bind: pm-service Do not have permissions
[  498.879215] msm_otg 78d9000.usb: LPM ENTER 7:inputs=0x100,state=9
[  498.884873] msm_otg 78d9000.usb: LPM ENTER 8:inputs=0x100,state=9
[  498.905926] msm_otg 78d9000.usb: LPM ENTER 9:inputs=0x100,state=9
[  498.911025] msm_otg 78d9000.usb: LPM caps = 90 flags = 12
[  498.911496] PM: suspend entry 2018-10-19 07:15:39.626414897 UTC
[  498.914815] PM: Syncing filesystems ... done.
[  498.927288] msm_otg 78d9000.usb: USB in low power mode
[  498.927777] msm_otg 78d9000.usb: OTG PM notify:3, sm_pending:0
[  498.932673] Error: returning -512 value
[  498.927810] Freezing user space processes ... (elapsed 0.032 seconds) done.
[  498.966294] Freezing remaining freezable tasks ... (elapsed 0.003 seconds) done.
[  498.975776] Suspending console(s) (use no_console_suspend to debug)

根据以上log,高通总结如下:

Otg unplug:
[ 497.010242] PHY ID IRQ in LPM
[ 497.036958] ID set
[ 497.037047] msm_otg 78d9000.usb: USB exited from low power mode
[ 497.309581] msm_otg 78d9000.usb: host off

otg plug:
[ 498.161072] USB PHY is exited from retention
[ 498.161149] msm_otg 78d9000.usb: ID status_w
[ 498.161359] ID clear
[ 498.161375] msm_otg 78d9000.usb: USB exited from low power mode
[ 498.557184] msm_otg 78d9000.usb: host on

流程正常,但是没检测到从设备。
-------------------------------------------------------------------------
PM8909寄存器操作GPIO,可以查PM8909的数据手册:80-np409-2x_c_pm8909_hardware_register_description_document_for_oems
拉高pm8909_gpio1
cd /sys/kernel/debug/spmi/spmi-0
echo 0xC040 > address
echo 0x11 > data
echo 0x11 > data
echo 0xC040 > address
echo 0x11 > data
echo 0x11 > data
1.8V

拉低pm8909_gpio1:
cd /sys/kernel/debug/spmi/spmi-0
echo 0xC040 > address
echo 0x10 > data
cd /sys/kernel/debug/spmi/spmi-0
echo 0xC040 > address
echo 0x10 > data
0V

cd /sys/kernel/debug/spmi/spmi-0
echo 0xC040 > address
echo 1 > count
cat data
-----------------------------------------------------------
修改如下,OTG功能即正常:
wanghl@server:~/work/H10_msm8909_android$ git diff kernel/arch/arm/boot/dts/qcom/sc806-evk/msm8909-pm8909-mtp.dtsi
diff --git a/kernel/arch/arm/boot/dts/qcom/sc806-evk/msm8909-pm8909-mtp.dtsi b/kernel/arch/arm/boot/dts/qcom/sc806-evk/msm8909-pm8909-mtp.dtsi
index 1c67a2da9e..803b4eb236 100755
--- a/kernel/arch/arm/boot/dts/qcom/sc806-evk/msm8909-pm8909-mtp.dtsi
+++ b/kernel/arch/arm/boot/dts/qcom/sc806-evk/msm8909-pm8909-mtp.dtsi
@@ -52,8 +52,16 @@
 
 &pm8909_gpios {
        gpio@c000 { /* GPIO 1 */
-               /* Battery UICC Alarm */
-               status = "disabled";
+               /* OTG Otoscope add by whl@pubtron.com.cn @ 20181022 */
+               //status = "disabled";
+               qcom,mode = <1>; /* QPNP_PIN_MODE_DIG_OUT */
+               qcom,invert = <0>; /* QPNP_PIN_INVERT_DISABLE */
+               qcom,output-type = <0>; /* QPNP_PIN_OUT_BUF_CMOS */
+               qcom,pull = <5>; /* QPNP_PIN_PULL_NO */
+               qcom,vin-sel = <0>; /* QPNP_PIN_VIN0,1,3 -> 1.8V, QPNP_PIN_VIN2 -> 1.2V */
+               qcom,out-strength = <3>; /* QPNP_PIN_OUT_STRENGTH_HIGH */
+               qcom,src-sel = <0>; /* QPNP_PIN_SEL_FUNC_CONSTANT */
+               qcom,master-en = <1>;
        };
 
        gpio@c100 { /* GPIO 2 */
wanghl@server:~/work/H10_msm8909_android$ git diff kernel/arch/arm/boot/dts/qcom/sc806-evk/msm8909.dtsi
diff --git a/kernel/arch/arm/boot/dts/qcom/sc806-evk/msm8909.dtsi b/kernel/arch/arm/boot/dts/qcom/sc806-evk/msm8909.dtsi
index 8d3fff081e..5467323250 100755
--- a/kernel/arch/arm/boot/dts/qcom/sc806-evk/msm8909.dtsi
+++ b/kernel/arch/arm/boot/dts/qcom/sc806-evk/msm8909.dtsi
@@ -863,7 +863,8 @@
                qcom,hsusb-otg-mpm-dpsehv-int = <49>;
                qcom,hsusb-otg-mpm-dmsehv-int = <58>;
 
-               qcom,hsusb-otg-vbus-en = <&pm8909_gpios 4 0>;
+               /* OTG Otoscope modify by whl@pubtron.com.cn @ 20181022 */
+               qcom,hsusb-otg-vbus-en = <&pm8909_gpios 1 0>;
 
                qcom,msm-bus,name = "usb2";
                qcom,msm-bus,num-cases = <3>;
------------------------------------------------------------
修改完之后,OTG耳窥镜正常工作的串口log:
插入:
[ 1326.018261] PHY ID IRQ in LPM
[ 1326.020464] msm_otg 78d9000.usb: OTG runtime resume
[ 1326.026045] msm_otg 78d9000.usb: LPM EXIT START:inputs=0x1,state=1
[ 1326.050242] msm_hsusb_ldo_enable: USB reg mode (3) (OFF/HPM/LPM)
[ 1326.056467] msm_hsusb_config_vddcx: min_vol:1200000 max_vol:1200000
[ 1326.063284] msm_otg_disable_phy_hv_int: bsv_id_hv = 1 dp_dm_hv_int = 0
[ 1326.069087] USB PHY is exited from retention
[ 1326.073299] msm_otg 78d9000.usb: ID status_w
[ 1326.077515] ID clear
[ 1326.079528] msm_otg 78d9000.usb: USB exited from low power mode
[ 1326.085882] b_idle work
[ 1326.087814] !id || id_A
[ 1326.091359] a_idle work
[ 1326.092787] !a_bus_drop && (a_srp_det || a_bus_req)
[ 1326.112908] starting a_wait_vrise timer
[ 1326.122082] IPC_RTR: msm_ipc_router_bind: pm-service Do not have permissions
[ 1326.215756] expired a_wait_vrise timer
[ 1326.218556] a_wait_vrise work
[ 1326.221659] a_vbus_vld
[ 1326.223795] msm_otg 78d9000.usb: host on
[ 1326.227694] msm_hsusb_host msm_hsusb_host: EHCI Host Controller
[ 1326.238294] msm_hsusb_host msm_hsusb_host: new USB bus registered, assigned bus number 1
[ 1326.246208] IPC_RTR: msm_ipc_router_bind: pm-service Do not have permissions
[ 1326.246562] cma: dma_alloc_from_contiguous(cma 00000000, count 1, align 0)
[ 1326.260474] cma: dma_alloc_from_contiguous(): returned af0d5
[ 1326.265603] cma: dma_alloc_from_contiguous(cma 00000000, count 1, align 0)
[ 1326.275071] cma: dma_alloc_from_contiguous(): returned af0dc
[ 1326.280743] msm_hsusb_host msm_hsusb_host: irq 166, io mem 0x078d9000
[ 1326.300254] msm_hsusb_host msm_hsusb_host: USB 2.0 started, EHCI 1.00
[ 1326.305780] msm_otg_set_suspend(0) in a_wait_bcon state
[ 1326.306007] portsc = 80000803
[ 1326.314459] usb usb1: New USB device found, idVendor=1d6b, idProduct=0002
[ 1326.320990] usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1
[ 1326.327814] usb usb1: Product: EHCI Host Controller
[ 1326.333401] usb usb1: Manufacturer: Linux 3.10.49 ehci_hcd
[ 1326.338168] usb usb1: SerialNumber: msm_hsusb_host
[ 1326.345100] hub 1-0:1.0: USB hub found
[ 1326.347884] hub 1-0:1.0: 1 port detected
[ 1326.411838] IPC_RTR: msm_ipc_router_bind: pm-service Do not have permissions
[ 1326.528418] IPC_RTR: msm_ipc_router_bind: pm-service Do not have permissions
[ 1326.607954] portsc = 88001205
[ 1326.671267] usb 1-1: new high-speed USB device number 2 using msm_hsusb_host
[ 1326.681173] IPC_RTR: msm_ipc_router_bind: pm-service Do not have permissions
[ 1326.736442] portsc = 88001205
[ 1326.802103] IPC_RTR: msm_ipc_router_bind: pm-service Do not have permissions
[ 1326.873805] usb 1-1: New USB device found, idVendor=f007, idProduct=b999
[ 1326.879572] usb 1-1: New USB device strings: Mfr=0, Product=2, SerialNumber=0
[ 1326.887717] usb 1-1: Product: Teslong Endoscope
[ 1326.914395] B_CONN set
[ 1326.915751] deleting a_wait_vrise timer. remaining -700 msec
[ 1326.920072] IPC_RTR: msm_ipc_router_bind: pm-service Do not have permissions
[ 1327.070314] IPC_RTR: msm_ipc_router_bind: pm-service Do not have permissions
[ 1327.145791] SELinux: initialized (dev fuse, type fuse), uses mountpoint labeling

拔出:
[ 1418.897633] portsc = 8c00100a
[ 1418.900740] PHY ID IRQ outside LPM
[ 1418.901761] usb 1-1: USB disconnect, device number 2
[ 1418.902982] B_CONN clear
[ 1418.904459] a_host work
[ 1418.904472] !b_conn
[ 1418.904488] deleting a_wait_vrise timer. remaining -92688 msec
[ 1418.921774] msm_otg 78d9000.usb: ID status_w
[ 1418.926223] ID set
[ 1418.928399] a_wait_bcon work
[ 1418.932604] (id && id_a/b/c) || a_bus_drop ||a_wait_bcon_tmout
[ 1418.937716] deleting a_wait_vrise timer. remaining -92721 msec
[ 1418.945315] msm_otg 78d9000.usb: host off
[ 1418.948327] msm_hsusb_host msm_hsusb_host: remove, state 1
[ 1418.954338] usb usb1: USB disconnect, device number 1
[ 1418.980360] msm_otg_set_suspend(1) in a_wait_bcon state
[ 1418.984581] host bus suspend
[ 1418.987742] msm_otg_set_suspend(0) in a_wait_bcon state
[ 1418.997637] cma: dma_release_from_contiguous(pfn af0dc)
[ 1419.002020] cma: dma_release_from_contiguous(pfn af0d5)
[ 1419.007130] msm_hsusb_host msm_hsusb_host: USB bus 1 deregistered
[ 1419.013636] msm_otg_set_suspend(1) in a_wait_bcon state
[ 1419.015170] starting a_wait_vfall timer
[ 1419.090964] IPC_RTR: msm_ipc_router_bind: pm-service Do not have permissions
[ 1419.291910] IPC_RTR: msm_ipc_router_bind: pm-service Do not have permissions
[ 1419.441944] IPC_RTR: msm_ipc_router_bind: pm-service Do not have permissions
[ 1419.515639] expired a_wait_vfall timer
[ 1419.518475] a_wait_vfall work
[ 1419.521477] a_idle work
[ 1419.523760] id && !id_a
[ 1419.526257] b_idle work
[ 1419.528618] chg_work cancel
[ 1419.531723] msm_otg 78d9000.usb: OTG runtime suspend
[ 1419.536358] msm_otg 78d9000.usb: LPM ENTER START:inputs=0x1,state=1
[ 1419.542668] msm_bam_device_lpm_ok: Going to LPM now
[ 1419.547469] msm_otg 78d9000.usb: LPM ENTER 1:inputs=0x1,state=1
[ 1419.550815] IPC_RTR: msm_ipc_router_bind: pm-service Do not have permissions
[ 1419.560980] msm_otg 78d9000.usb: LPM ENTER 2:inputs=0x1,state=1
[ 1419.566300] msm_otg 78d9000.usb: LPM ENTER 2:B_SESS_VLD=0,device_bus_suspend=0,dcp=0,prop_charger=0,floated_charger=0
[ 1419.576962] msm_otg 78d9000.usb: LPM ENTER 2:A_BUS_REQ=0,sm_work_busy=0
[ 1419.583639] msm_otg 78d9000.usb: LPM ENTER 3:inputs=0x1,state=1
[ 1419.589390] msm_otg 78d9000.usb: LPM ENTER 4:inputs=0x1,state=1
[ 1419.595530] msm_otg 78d9000.usb: LPM ENTER 6:inputs=0x1,state=1
[ 1419.601290] msm_otg_enable_phy_hv_int: bsv_id_hv = 1 dp_dm_hv_int = 0
[ 1419.607615] USB PHY is in retention
[ 1419.611370] msm_otg 78d9000.usb: LPM ENTER 7:inputs=0x1,state=1
[ 1419.617936] msm_hsusb_ldo_enable: USB reg mode (2) (OFF/HPM/LPM)
[ 1419.623538] msm_hsusb_config_vddcx: min_vol:0 max_vol:1200000
[ 1419.628702] msm_otg 78d9000.usb: LPM ENTER 8:inputs=0x1,state=1
[ 1419.643034] msm_otg 78d9000.usb: LPM ENTER 9:inputs=0x1,state=1
[ 1419.647951] msm_otg 78d9000.usb: LPM caps = 90 flags = 30
[ 1419.648284] PM: suspend entry 2018-10-22 07:59:26.416279999 UTC
[ 1419.659962] msm_otg 78d9000.usb: USB in low power mode
[ 1419.664982] IPC_RTR: msm_ipc_router_bind: pm-service Do not have permissions
[ 1419.672900] PM: Syncing filesystems ... done.
[ 1419.690784] msm_otg 78d9000.usb: OTG PM notify:3, sm_pending:0
[ 1419.695635] Freezing user space processes ... [ 1419.704806] Error: returning -512 value

[ 1419.707912] last active wakeup source: eventpoll
[ 1419.712469] 
[ 1419.713861] Freezing of tasks aborted after 0.012 seconds (196 tasks refusing to freeze, wq_busy=0):
[ 1419.723012] 
[ 1419.724444] Restarting tasks ... done.
[ 1419.732239] msm_otg 78d9000.usb: OTG PM notify:4, sm_pending:0
[ 1419.737721] PM: suspend exit 2018-10-22 07:59:26.505714738 UTC
[ 1419.844143] PM: suspend entry 2018-10-22 07:59:26.612132759 UTC
[ 1419.849037] PM: Syncing filesystems ... done.
[ 1419.857303] msm_otg 78d9000.usb: OTG PM notify:3, sm_pending:0
[ 1419.862769] Freezing user space processes ... [ 1419.862874] IPC_RTR: msm_ipc_router_bind: pm-service Do not have permissions
[ 1419.877909] Error: returning -512 value
(elapsed 0.086 seconds) done.
[ 1419.962052] Freezing remaining freezable tasks ... (elapsed 0.003 seconds) done.
[ 1419.971743] Suspending console(s) (use no_console_suspend to debug)

模组厂商增加了驱动去拉OTG_EN输出5V的代码:
kernel/drivers/usb/phy/phy-msm-usb.c

static int msm_otg_vbus_power_on(bool on)//拉高拉低OTG_EN
{struct msm_otg *msm_otg = the_msm_otg;if(gpio_is_valid(msm_otg->pdata->vbus_en_pin)){if(on){gpio_direction_output(msm_otg->pdata->vbus_en_pin, 1);}else{gpio_direction_output(msm_otg->pdata->vbus_en_pin, 0);}return 0;}return -1;
}static int msm_otg_probe(struct platform_device *pdev)
{
...if(pdata->vbus_en_pin > 0){if(!pdata->vbus_power)pdata->vbus_power = msm_otg_vbus_power_on;}
...
}struct msm_otg_platform_data *msm_otg_dt_to_pdata(struct platform_device *pdev)
{
...pdata->vbus_en_pin = of_get_named_gpio(node, "qcom,hsusb-otg-vbus-en", 0);if(pdata->vbus_en_pin > 0){res_gpio = gpio_request(pdata->vbus_en_pin, "hsusb-otg-vbus-en");//关联设备树文件:kernel/arch/arm/boot/dts/qcom/sc806-evk/msm8909.dtsiif(res_gpio < 0){pr_err("gpio_request hsusb-otg-vbus-en failed.\n");}}
...
}

kernel/arch/arm/boot/dts/qcom/sc806-evk/msm8909.dtsi:
qcom,hsusb-otg-vbus-en = <&pm8909_gpios 1 0>;//PMU_GPIO_1

======================================================================
K8小手机不连接USB线到电脑,且不合盖子的情况下,屏幕自己休眠之后又自己唤醒的问题:
查看串口log:
1.打印所有级别log:
echo 8 > /proc/sys/kernel/printk
2.禁止串口进入休眠:
echo N > sys/module/printk/parameters/console_suspend

断开USB与电脑的连接,自动休眠后的log

K8:/ # [  341.229232] PM: suspend entry 1970-01-01 00:18:04.652428469 UTC
[  341.234170] PM: Syncing filesystems ... done.
[  341.253790] Freezing user space processes ... 
[  341.260215] Error: returning -512 value
[  341.260924] PM: Wakeup pending, aborting suspend
[  341.260994] last active wakeup source: eventpoll
[  341.261016] 
[  341.261026] Freezing of tasks aborted after 0.003 seconds
[  341.265349] Restarting tasks ... done.
[  341.265593] PM: suspend exit 1970-01-01 00:18:04.688792271 UTC
[  341.368118] PM: suspend entry 1970-01-01 00:18:04.791315917 UTC
[  341.373074] PM: Syncing filesystems ... done.
[  341.379457] Freezing user space processes ... 
[  341.383976] Error: returning -512 value
[  341.388896] (elapsed 0.006 seconds) done.
[  341.391869] Freezing remaining freezable tasks ... (elapsed 0.002 seconds) done.
[  341.418843] K8_keypad_suspend
[  341.420883] K8_keypad_goto_sleep[  341.424623] i2c-msm-v2 78b5000.i2c: msm_bus_scale_register_client(mstr-id:86):0x11 (ok)
[  341.441536] PM: suspend of devices complete after 39.335 msecs
[  341.448329] PM: late suspend of devices complete after 1.983 msecs
[  341.456925] PM: noirq suspend of devices complete after 3.346 msecs
[  341.462246] Disabling non-boot CPUs ...
[  341.466720] migrate_irqs: 630 callbacks suppressed
[  341.466726] IRQ0 no longer affine to CPU3
[  341.466733] IRQ1 no longer affine to CPU3
[  341.466738] IRQ2 no longer affine to CPU3
[  341.466744] IRQ3 no longer affine to CPU3
[  341.466749] IRQ4 no longer affine to CPU3
[  341.466755] IRQ5 no longer affine to CPU3
[  341.466761] IRQ6 no longer affine to CPU3
[  341.466766] IRQ7 no longer affine to CPU3
[  341.466772] IRQ8 no longer affine to CPU3
[  341.466778] IRQ9 no longer affine to CPU3
[  341.467908] CPU3: shutdown
[  341.515869] CPU2:msm_cpu_pm_enter_sleep mode:3 during suspend//正常灭屏幕后log打到这里,
//但是一会儿马上又唤醒打了以下的log
[  341.516064] Enabling non-boot CPUs ...
[  341.519232] CPU3: Booted secondary processor
[  341.519970] CPU3 is up
[  341.526583] PM: noirq resume of devices complete after 1.002 msecs
[  341.533318] PM: early resume of devices complete after 1.101 �[  341.541481] gpio_keys_resume
[  341.543425] gpio_keys_report_state
[  341.546729] gpio_keys_report_state
[  341.550235] gpio_keys_report_state
[  341.553502] away from hall switch,wakeup//kernel/drivers/input/keyboard/gpio_keys.c 驱动又上报了一次WAKE_UP按键事件
[  341.559551] K8_keypad_resume
[  341.561450] K8_keypad_wakeup[  341.635291] PM: resume of devices complete after 96.810 msecs
[  341.642193] Restarting tasks ... done.
[  341.650492] PM: suspend exit 1970-01-01 00:18:09.141911383 UTC
[  341.758332] ctrl_pdata->rst_gpio = 25,ctrl_pdata->disp_dc_gpio = 23

发现是gpio_keys_report_state函数调用了gpio_keys_gpio_report_event进行的上报,gpio_keys_gpio_report_event又是由gpio_keys_resume调用引起的。
正常翻开盖子的时候log如下:
[  616.257782] Enabling non-boot CPUs ...
[  616.261085] CPU3: Booted secondary processor
[  616.261820] CPU3 is up
[  616.268425] PM: noirq resume of devices complete after 0.999 msecs
[  616.275333] PM: early resume of devices complete after 1.105 m�[  616.283851] gpio_keys_resume
[  616.285796] gpio_keys_report_state
[  616.289099] gpio_keys_report_state
[  616.292712] gpio_keys_report_state
[  616.295864] approach hall switch,sleep
[  616.302899] K8_keypad_resume
[  616.304747] K8_keypad_wakeup[  616.379184] PM: resume of devices complete after 98.533 msecs
[  616.385566] Restarting tasks ... done.
[  616.393697] PM: suspend exit 1970-01-01 00:23:03.197882410 UTC
[  616.500630] PM: suspend entry 1970-01-01 00:23:03.304811212 UTC
[  616.505523] PM: Syncing filesystems ... done.
[  616.521108] Freezing user space processes ... 
[  616.527270] Error: returning -512 value
[  616.532500] (elapsed 0.008 seconds) done.
[  616.535474] Freezing remaining freezable tasks ... (elapsed 0.002 seconds) done.
[  616.561780] K8_keypad_suspend
[  616.563716] K8_keypad_goto_sleep[  616.575923] PM: suspend of devices complete after 30.244 msecs
[  616.582888] PM: late suspend of devices complete after 1.996 msecs
[  616.591384] PM: noirq suspend of devices complete after 3.340 msecs
[  616.596637] Disabling non-boot CPUs ...
[  616.602259] CPU3: shutdown
[  616.604704] CPU2:msm_cpu_pm_enter_sleep mode:3 during suspend
[  616.604910] Enabling non-boot CPUs ...
[  616.608075] CPU3: Booted secondary processor
[  616.608857] CPU3 is up
[  616.615493] PM: noirq resume of devices complete after 0.997 msecs
[  616.622443] PM: early resume of devices complete after 1.100 m�[  616.630841] gpio_keys_resume
[  616.632787] gpio_keys_report_state//这里会调用gpio_keys_gpio_report_event上报
[  616.636090] gpio_keys_report_state
[  616.639470] gpio_keys_report_state
[  616.642993] gpio_keys_gpio_work_func//这里会调用gpio_keys_gpio_report_event上报
[  616.646418] away from hall switch,wakeup//第一次上报翻盖事件
[  616.650402] away from hall switch,wakeup//第二次上报翻盖事件
[  616.657223] K8_keypad_resume
[  616.659072] K8_keypad_wakeup[  616.735058] PM: resume of devices complete after 107.343 msecs
[  616.741507] Restarting tasks ... done.
[  616.748687] PM: suspend exit 1970-01-01 00:23:29.574660055 UTC

所以可以把异常调用gpio_keys_report_state上报翻盖事件的地方注释掉,规避这个问题,也就是在gpio_keys_resume里注释掉gpio_keys_report_state,正常翻盖不会受到影响,因为
还有gpio_keys_gpio_work_func会去上报翻盖事件。原因可能是系统休眠的时候没有休眠成功,会resume起来尝试第二次休眠,结果gpio_keys_resume就resume起来把WAKEUP按键报上去了,系统就
点亮屏幕,系统一直睡不下去,就不断的灭屏再亮屏。
--------------------------------------------------------
修改完之后,不接USB线,自动灭屏的log:
K8:/ # [  424.051754] PM: suspend entry 1970-01-01 00:49:04.809607142 UTC
[  424.056646] PM: Syncing filesystems ... done.
[  424.132267] Freezing user space processes ... 
[  424.138592] Error: returning -512 value
[  424.138624] PM: Wakeup pending, aborting suspend
[  424.138693] last active wakeup source: eventpoll
[  424.138715] 
[  424.138724] Freezing of tasks aborted after 0.003 seconds
[  424.141386] Restarting tasks ... done.
[  424.141590] PM: suspend exit 1970-01-01 00:49:04.899447506 UTC
[  424.243332] PM: suspend entry 1970-01-01 00:49:05.001186725 UTC
[  424.248222] PM: Syncing filesystems ... done.
[  424.255580] Freezing user space processes ... 
[  424.260015] Error: returning -512 value
[  424.265075] (elapsed 0.006 seconds) done.
[  424.268049] Freezing remaining freezable tasks ... (elapsed 0.002 seconds) done.
[  424.295419] K8_keypad_suspend
[  424.297353] K8_keypad_goto_sleep[  424.310780] PM: suspend of devices complete after 32.348 msecs
[  424.317557] PM: late suspend of devices complete after 1.968 msecs
[  424.326167] PM: noirq suspend of devices complete after 3.347 msecs
[  424.331464] Disabling non-boot CPUs ...
[  424.335956] migrate_irqs: 1270 callbacks suppressed
[  424.335962] IRQ0 no longer affine to CPU3
[  424.335968] IRQ1 no longer affine to CPU3
[  424.335973] IRQ2 no longer affine to CPU3
[  424.335979] IRQ3 no longer affine to CPU3
[  424.335985] IRQ4 no longer affine to CPU3
[  424.335990] IRQ5 no longer affine to CPU3
[  424.335995] IRQ6 no longer affine to CPU3
[  424.336001] IRQ7 no longer affine to CPU3
[  424.336007] IRQ8 no longer affine to CPU3
[  424.336012] IRQ9 no longer affine to CPU3
[  424.337124] CPU3: shutdown
[  424.384767] CPU2:msm_cpu_pm_enter_sleep mode:3 during suspend//第一次睡
[  424.384962] Enabling non-boot CPUs ...//又起来了
[  424.388122] CPU3: Booted secondary processor
[  424.388853] CPU3 is up
[  424.395482] PM: noirq resume of devices complete after 0.989 msecs
[  424.402343] PM: early resume of devices complete after 1.088 �[  424.410628] gpio_keys_resume//虽然调用,但是注释掉了上报,就不会再上报WAKEUP事件
[  424.415367] K8_keypad_resume
[  424.417217] K8_keypad_wakeup[  424.492404] PM: resume of devices complete after 84.896 msecs
[  424.500452] Restarting tasks ... done.
[  424.509145] PM: suspend exit 1970-01-01 00:49:09.333290785 UTC
[  424.616406] PM: suspend entry 1970-01-01 00:49:09.440550576 UTC
[  424.621411] PM: Syncing filesystems ... done.
[  424.627693] Freezing user space processes ... 
[  424.633948] Error: returning -512 value
[  424.638873] (elapsed 0.007 seconds) done.
[  424.641846] Freezing remaining freezable tasks ... (elapsed 0.002 seconds) done.
[  424.669867] K8_keypad_suspend
[  424.671804] K8_keypad_goto_sleep[  424.684245] PM: suspend of devices complete after 32.246 msecs
[  424.691159] PM: late suspend of devices complete after 2.098 msecs
[  424.699752] PM: noirq suspend of devices complete after 3.438 msecs
[  424.705005] Disabling non-boot CPUs ...
[  424.710754] CPU3: shutdown
[  424.713204] CPU2:msm_cpu_pm_enter_sleep mode:3 during suspend//第二次睡下成功,
//后面也不会再唤醒,不会再有其他log,除非按POWER键唤醒
-----------------------------------------------------------------------------------------
修改完之后,手动翻盖唤醒log:
[  446.164109] Enabling non-boot CPUs ...
[  446.167269] CPU3: Booted secondary processor
[  446.167996] CPU3 is up
[  446.174590] PM: noirq resume of devices complete after 0.986 msecs
[  446.181453] PM: early resume of devices complete after 1.115 �[  446.189639] gpio_keys_resume//不上报
[  446.194193] K8_keypad_resume
[  446.196040] K8_keypad_wakeup[  446.199543] gpio_keys_gpio_work_func//只剩下这次有效上报
[  446.202639] away from hall switch,wakeup//只报一次
[  446.278385] PM: resume of devices complete after 91.765 msecs
[  446.284939] Restarting tasks ... 
[  446.304268] healthd: battery l=98 v=3969 t=28.0 h=2 st=3 c=-4 chg=
[  446.315530] done.
[  446.320480] PM: suspend exit 1970-01-01 00:53:07.192713505 UTC
[  446.352997] ctrl_pdata->rst_gpio = 25,ctrl_pdata->disp_dc_gpio = 23

===============================================================================================================================================================
void gr_fb_blank(bool blank);  /* panel power on/off */
static void fbdev_blank(minui_backend* backend __unused, bool blank)
{
    int ret;

ret = ioctl(fb_fd, FBIOBLANK, blank ? FB_BLANK_POWERDOWN : FB_BLANK_UNBLANK);
    if (ret < 0)
        perror("ioctl(): blank");
}
android recovery mode debug notes on msm8909 platform
https://blog.csdn.net/ic_soc_arm_robin/article/details/71652423

高通LCD之亮灭屏过程简析
https://blog.csdn.net/liwei16611/article/details/52830697

ioctl命令
FB_BLANK_POWERDOWN 是灭屏操作;  MDSS_EVENT_PANEL_OFF MDSS_PANEL_POWER_OFF  MDSS_EVENT_BLANK
FB_BLANK_UNBLANK 是亮屏操作;    MDSS_EVENT_PANEL_ON  MDSS_PANEL_POWER_ON MDSS_EVENT_UNBLANK
make recoveryimage同时也会编译bootimage,

如果修改recovery的内容,不能单单编译recovery,
同时要编译kernel,
否则kenel的驱动在recovery下被调用的时候并不会被更新。

======================================================================
recovery打开串口log:
1.修改TEMPORARY_LOG_FILE:"/tmp/recovery.log"为"/dev/ttyHSL0"
diff --git a/bootable/recovery/recovery.cpp b/bootable/recovery/recovery.cpp
index 320df59080..edac3d16ca 100755
--- a/bootable/recovery/recovery.cpp
+++ b/bootable/recovery/recovery.cpp
@@ -115,7 +115,9 @@ static const char *CONVERT_FBE_FILE = "/tmp/convert_fbe/convert_fbe";
 static const char *CACHE_ROOT = "/cache";
 static const char *DATA_ROOT = "/data";
 static const char *SDCARD_ROOT = "/sdcard";
-static const char *TEMPORARY_LOG_FILE = "/tmp/recovery.log";
+//static const char *TEMPORARY_LOG_FILE = "/tmp/recovery.log";
+static const char *TEMPORARY_LOG_FILE = "/dev/ttyHSL0";

但是只修改以上log会提示权限问题,
[ 18.418291] audit: type=1400 audit(12392.159:10): avc: denied { append } for pid=294 comm="recovery" name="ttyHSL0" dev="tmpfs" ino=3616 scontext=u:r:recovery:s0 tcontext=u:object_r:console_device:s0 tclass=chr_file permissive=0
[ 18.466362] init: Service 'recovery' (pid 293) killed by signal 13
[ 18.471565] init: Service 'recovery' (pid 293) killing any children in process group
主要是因为是selinux的问题 
2.device/qcom/K8/BoardConfig.mk添加BOARD_KERNEL_CMDLINE += androidboot.selinux=permissive 
diff --git a/device/qcom/K8/BoardConfig.mk b/device/qcom/K8/BoardConfig.mk
index 0d1c71cdf4..e62c6d599f 100755
--- a/device/qcom/K8/BoardConfig.mk
+++ b/device/qcom/K8/BoardConfig.mk
@@ -109,7 +109,7 @@ ifeq ($(HOST_OS),linux)
     endif
 endif
 
-BOARD_KERNEL_CMDLINE := console=ttyHSL0,115200,n8 androidboot.console=ttyHSL0 androidboot.hardware=qcom msm_rtb.filter=0x237 ehci-hcd.park=3 androidboot.bootdevice=7824900.sdhci lpm_levels.sleep_disabled=1 earlyprintk
+BOARD_KERNEL_CMDLINE := console=ttyHSL0,115200,n8 androidboot.console=ttyHSL0 androidboot.hardware=qcom msm_rtb.filter=0x237 ehci-hcd.park=3 androidboot.bootdevice=7824900.sdhci lpm_levels.sleep_disabled=1 earlyprintk androidboot.selinux=permissive

修改device/qcom/K8/BoardConfig.mk是比较暴力的方式,像定制小手机就出现了显示不正常或其他未知问题,会把kernel的selinux也关了,但是这样就可以printf打印串口信息了。

最好还是使用第二种方法:
diff --git a/bootable/recovery/recovery.cpp b/bootable/recovery/recovery.cpp
index 82d64ca..e3cd48f 100755
--- a/bootable/recovery/recovery.cpp
+++ b/bootable/recovery/recovery.cpp
@@ -109,7 +109,7 @@ static const char *CONVERT_FBE_FILE = "/tmp/convert_fbe/convert_fbe";
static const char *CACHE_ROOT = "/cache";
static const char *DATA_ROOT = "/data";
static const char *SDCARD_ROOT = "/sdcard";
-static const char *TEMPORARY_LOG_FILE = "/tmp/recovery.log";
+static const char *TEMPORARY_LOG_FILE = "/dev/console";//或改成/dev/ttyHSL0(真实串口设备)也可以
static const char *TEMPORARY_INSTALL_FILE = "/tmp/last_install";

3.修改selinux权限文件device/qcom/msm8909w/sepolicy/common/recovery.te
diff --git a/device/qcom/msm8909w/sepolicy/common/recovery.te b/device/qcom/msm8909w/sepolicy/common/recovery.te
index c83bc974b2..1014737747 100644
--- a/device/qcom/msm8909w/sepolicy/common/recovery.te
+++ b/device/qcom/msm8909w/sepolicy/common/recovery.te
@@ -16,4 +16,5 @@ recovery_only(`
     allow recovery sg_device:chr_file rw_file_perms;
     allow recovery self:capability sys_rawio;
     allow recovery sg_device:chr_file ioctl;
+    allow recovery console_device:chr_file rw_file_perms;
 ')
补充:
system/sepolicy/file_contexts:66:/dev/console        u:object_r:console_device:s0
system/core/init/init.cpp:78:std::string console_name = "/dev/console";
可以看出/dev/console就是一个console_device

device/qcom/msm8909w/sepolicy/common/file_contexts:36:/dev/ttyHSL0                                    u:object_r:console_device:s0
/dev/ttyHSL0也是一个console_device,所以static const char *TEMPORARY_LOG_FILE 改成 "/dev/ttyHSL0";这种方法也可以。
改完需要全编,否则不生效
===================================
充电口vid和pid
Bus 001 Device 122: ID 05c6:f000 Qualcomm, Inc.
===============================================
SPI屏幕数据发送接口:
普通模式发送SPI数据:
mdss_spi_panel_kickoff(mdp3_session->panel,
    (void *)(int)data->addr,//-495185920
    (int)data->len,//122880
    stride);//stride = mdp3_session->dma->source_config.stride = 512

recovery模式发送SPI数据:
mdss_spi_panel_kickoff(mdp3_session->panel,
    (void *)(int)(mfd->fbi->screen_base + offset),
    (int)fbi->fix.smem_len,//smemlen = 245760,因为双缓存:fix.smem_len = 240*512*2 = 245760
    stride);//stride = fbi->fix.line_length = 512

调试注意事项:
(1)
在recovery模式下,如果要防止死机后重复进入recovery模式,可以屏蔽掉get_args(&argc, &argv);因为这句会调用write_bootloader_message写
"boot-recovery"和"recovery\n"到misc分区的command和recovery字段,直到调用finish_recovery() 才会被清除,所以如果还没跑到finish_recovery()就死机,下次还是会进入recovery模式。
struct bootloader_message {
    char command[32];
    char status[32];
    char recovery[768];

// The 'recovery' field used to be 1024 bytes.  It has only ever
    // been used to store the recovery command line, so 768 bytes
    // should be plenty.  We carve off the last 256 bytes to store the
    // stage string (for multistage packages) and possible future
    // expansion.
    char stage[32];
    char slot_suffix[32];
    char reserved[192];
};

(2)recovery模式下抓死机的dump信息和正常抓dump信息一样,CONFIG_MSM_DLOAD_MODE开关默认就是打开的,需要将CONFIG_MAGIC_SYSRQ = y也打开
It's same as normal mode. System will enter into dump mode if you enable it before.
How to make device enter download mode:

1. first you should have CONFIG_MAGIC_SYSRQ = y and CONFIG_MSM_DLOAD_MODE=y enabled when building kernel
2. enable download mode
echo 1 > /sys/module/restart/parameters/download_mode              #我们的msm8909w系统没有这个目录,但是不影响QPST抓dump信息
echo 1 > /sys/module/msm_poweroff/parameters/download_mode

3. echo 1 > /proc/sys/kernel/sysrq                #我们的msm8909w系统没有这个目录,也不影响QPST抓dump信息

4. make system enter into dump mode
echo c > /proc/sysrq-trigger
it would trigger panic and device would go into dump mode.

调试recovery显示过程中出现了两个主要问题:1.死机 2.发送SPI数据总是超时,没有显示。解决这两个问题SPI屏幕就能在recovery模式下正常显示了
1.死机问题,通过QCAP分析dump数据可以看到问题处在kenel crash上面(dmesg log):
     9.150236:   <6> ===MDSS_EVENT_PANEL_ON===
     9.295802:   <2> Division by zero in kernel.
     9.295812:   <6> ------------[ cut here ]------------
     9.295818:   <6> kernel BUG at /home/whl/work/msm8909w_law_android/kernel/arch/arm/kernel/traps.c:855!
     9.295822:   <6> Internal error: Oops - BUG: 0 [#1] PREEMPT SMP ARM
     9.295830:   <2> Modules linked in:
     9.295837:   <6> CPU: 0 PID: 266 Comm: recovery Not tainted 3.18.24 #255
     9.295843:   <6> task: dce60000 ti: dba28000 task.ti: dba28000
     9.295854:   <2> PC is at __div0+0xc/0x14
     9.295860:   <2> LR is at __div0+0xc/0x14
     9.295866:   <2> pc : [<c0011b10>]    lr : [<c0011b10>]    psr: 600b0013  sp : dba29cd8  ip : 0000000b  fp : 00000001
     9.295869:   <2> r10: 00000000  r9 : 00000000  r8 : 00010000
     9.295874:   <2> r7 : dc456290  r6 : dbf60800  r5 : dba29e30  r4 : dbf60800
     9.295878:   <2> r3 : 00000000  r2 : 00000000  r1 : 200b0013  r0 : 0000001b
     9.295883:   <2> Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment user
     9.295888:   <2> Control: 10c5387d  Table: 9ba3006a  DAC: 00000015
     9.295892:   <6> Process recovery (pid: 266, stack limit = 0xdba28238)
     9.295896:   <6> Stack: (0xdba29cd8 to 0xdba2a000)
    ........................
     9.296136:   <2> [<c0011b10>] (__div0) from [<c026a250>] (Ldiv0+0x8/0x10)
     9.296152:   <2> [<c026a250>] (Ldiv0) from [<c03276a0>] (mdss_fb_var_to_panelinfo+0xb0/0xd8)
     9.296165:   <2> [<c03276a0>] (mdss_fb_var_to_panelinfo) from [<c0328390>] (mdss_fb_check_var+0x2dc/0x338)
     9.296177:   <2> [<c0328390>] (mdss_fb_check_var) from [<c02a4ee0>] (fb_set_var+0x168/0x330)
     9.296188:   <2> [<c02a4ee0>] (fb_set_var) from [<c02a529c>] (do_fb_ioctl+0x194/0x5dc)
     9.296200:   <2> [<c02a529c>] (do_fb_ioctl) from [<c01384e0>] (do_vfs_ioctl+0x480/0x57c)
     9.296210:   <2> [<c01384e0>] (do_vfs_ioctl) from [<c0138628>] (SyS_ioctl+0x4c/0x74)
     9.296221:   <2> [<c0138628>] (SyS_ioctl) from [<c000e060>] (ret_fast_syscall+0x0/0x38)
     9.296230:   <6> Code: c0bc9d60 e92d4008 e59f0004 eb24dc86 (e7f001f2) 
     9.296235:   <6> ---[ end trace d06f2bd2169e5490 ]---

发现有除0操作导致系统崩溃,具体调用位置是系统调用do_fb_ioctl,从而调用了fb_set_var函数,最终调用了mdss_fb_var_to_panelinfo函数,该函数
出现了除零操作。具体流程是在recovery模式下bootable/recovery/recovery.cpp的main()函数跑到 ui->Init();的时候调用了void ScreenRecoveryUI::Init(),
里面调用了gr_init();gr_init()里执行了open_fbdev并进行了相应的初始化static GRSurface* fbdev_init(minui_backend* backend),该函数打开了
/dev/graphics/fb0设备并通过ioctl获取了屏幕的参数FBIOGET_FSCREENINFO和FBIOGET_VSCREENINFO并进行了mmap内存映射都没有问题,并支持了double_buffered
双缓存,但是在跑到set_displayed_framebuffer(0);设置参数的时候出了问题:该函数调用了ioctl(fb_fd, FBIOPUT_VSCREENINFO, &vi);于是就会调用到内核的
kernel/drivers/video/fbdev/core/fbmem.c的ioctl的处理函数:
static long do_fb_ioctl(struct fb_info *info, unsigned int cmd,    unsigned long arg, struct file *file)
在该函数的FBIOPUT_VSCREENINFO的case分支里调用了fb_set_var(info, &var);函数,这就和死机log的堆栈信息对应上了,fb_set_var里调用了info->fbops->fb_check_var,这个实际上从高通屏幕的驱动kernel/drivers/video/msm/mdss/mdss_fb.c可以看出是调用了.fb_check_var = mdss_fb_check_var,    /* vinfo check */函数,进入该函数发现是mdss_fb_check_var又调用了mdss_fb_var_to_panelinfo,该函数将fb_var_screeninfo信息传给了mdss_panel_info
pinfo->xres = var->xres;
pinfo->yres = var->yres;
pinfo->lcdc.v_front_porch = var->lower_margin;
pinfo->lcdc.v_back_porch = var->upper_margin;
pinfo->lcdc.v_pulse_width = var->vsync_len;
pinfo->lcdc.h_front_porch = var->right_margin;
pinfo->lcdc.h_back_porch = var->left_margin;
pinfo->lcdc.h_pulse_width = var->hsync_len;

这些也没有问题,并且从log可以看到打印出来也是对的,和dtsi的设置对应上的,但是跑到
pinfo->clk_rate = PICOS2KHZ(var->pixclock) * 1000;
这句就出问题了,因为对于SPI 屏幕来说,var->pixclock打印出来的值是0,所以执行
#define PICOS2KHZ(a) (1000000000UL/(a))
就出现了PICOS2KHZ(0)除0操作,系统就崩溃了。
对于定制小手机 mipi屏幕(240*432)来说,var->pixclock = 5446,pinfo->clk_rate算出来是183621006(180多M)
所以这里对SPI屏幕强行设置一个clkrate:
pinfo->clk_rate = PICOS2KHZ(66666) * 1000;
        pr_info("===spi pinfo->clk_rate = %lld===\n", pinfo->clk_rate); //15M多
或者直接加一个判断条件:
             if(var->pixclock != 0)
                 pinfo->clk_rate = PICOS2KHZ(var->pixclock) * 1000;
不进行pinfo->clk_rate的设置也可以,这里采用第二种方法。

2.发送数据30S超时:
[    9.652811] ===fb_set_var===                                                                                                              
[    9.652812] ===fb_pan_display===                                                                                                            
[    9.652816] mdss_fb_pan_display: ===mdss_fb_pan_display===                                                                                  
[    9.652818] mdss_fb_pan_display_ex: ===mdss_fb_pan_display_ex===                                                                            
[   39.650119] mdss_fb_wait_for_kickoff: mdss_fb_pan_display_ex+0x90/0x22c: wait for kickoff timeout koff=1 commits=0                          
[   39.650135] mdp3_runtime_resume:2990        =>[0       :1026764    :  1026764][1   ]:1111                                                   
[   39.650143] mdp3_footswitch_ctrl:2697       =>[1       :1026767    :        3][1   ]:1                                                      
[   39.650151] mdp3_clk_update:448             =>[2       :1026840    :       73][1   ]:1                                                      
[   39.650159] mdp3_clk_update:456             =>[3       :1026868    :       28][1   ]:0                                                      
[   39.650167] mdp3_runtime_suspend:3015       =>[4       :1026949    :       81][35  ]:1111                                                   
[   39.650175] mdp3_footswitch_ctrl:2697       =>[5       :1026951    :        2][35  ]:0                                                      
[   39.650184] mdp3_runtime_resume:2990        =>[6       :1035856    :     8905][1   ]:1111                                                   
[   39.650192] mdp3_footswitch_ctrl:2697       =>[7       :1035859    :        3][1   ]:1                                                      
[   39.650199] mdp3_clk_update:448             =>[8       :1035931    :       72][1   ]:1                                                      
[   39.650209] mdp3_ctrl_on:861                =>[9       :8219429    :  7183498][267 ]:1111 35d 0                                             
[   39.650218] mdp3_ctrl_on:886                =>[10      :8490180    :   270751][267 ]:2222 376 0                                             
[   39.650228] mdp3_ctrl_off:1013              =>[11      :8511951    :    21771][267 ]:1111 3f5 0 0                                           
[   39.650237] mdp3_ctrl_off:1178              =>[12      :8800258    :   288307][267 ]:2222 49a                                               
[   39.650246] mdp3_ctrl_on:861                =>[13      :8834631    :    34373][267 ]:1111 35d 0                                             
[   39.650254] mdss_smmu_attach:120            =>[14      :8834668    :       37][267 ]:0                                                      
[   39.650263] mdp3_ctrl_on:973                =>[15      :9390650    :   555982][267 ]:2222 3cd 0                                             
[   39.650272] __mdss_fb_display_thread:3585   =>[16      :9438156    :    47506][280 ]:0 1111                                                 
[   39.650280] __mdss_fb_display_thread:3587   =>[17      :9520206    :    82050][280 ]:0 2222                                                 
[   39.650284] ======== VBIF Debug bus DUMP =========                                                                                          
[   39.650286] ======== NRT VBIF Debug bus DUMP =========                                                                                      
[   39.650290] mdss_fb_pan_display_ex: wait_for_kick failed. rc=-110

系统每次刷新数据调用fbdev_flip都会调用set_displayed_framebuffer(1-displayed_buffer);从而发送ioctl的FBIOPUT_VSCREENINFO命令,调用到
内核的对应的do_fb_ioctl的case分支,FBIOPUT_VSCREENINFO,从而调用到fb_set_var,它会调用fb_pan_display(info, &info->var);然后调用
info->fbops->fb_pan_display(),具体就会调用到高通的显示驱动
.fb_pan_display = mdss_fb_pan_display,    /* pan display */
从而又调用到mdss_fb_pan_display_ex(info, &disp_commit);接着调用mdss_fb_wait_for_kickoff(mfd);打印出超时log

ret = wait_event_timeout(mfd->kickoff_wait_q,
            (!atomic_read(&mfd->kickoff_pending) ||
             mfd->shutdown_pending),
            msecs_to_jiffies(WAIT_DISP_OP_TIMEOUT));
    if (!ret) {
        pr_err("%pS: wait for kickoff timeout koff=%d commits=%d\n",
                __builtin_return_address(0),
                atomic_read(&mfd->kickoff_pending),
                atomic_read(&mfd->commits_pending));
        MDSS_XLOG_TOUT_HANDLER("mdp", "vbif", "vbif_nrt",
            "dbg_bus", "vbif_dbg_bus");
        ret = -ETIMEDOUT;
    } else if (mfd->shutdown_pending) {
        pr_debug("Shutdown signalled\n");
        ret = -ESHUTDOWN;
    } else {
        ret = 0;
    }

查看wait_event_timeout - sleep until a condition gets true or a timeout elapses
可以看出只有条件为真,休眠才会跳出来,否则就一直等到超时才跳出来,
原因就在于atomic_read(&mfd->kickoff_pending)读出来是1(一直在等待kickoff完成),!atomic_read(&mfd->kickoff_pending)不为真,mfd->shutdown_pending也不为真,查找代码发现这个变量只有在注册的时候mdss_fb_register设置为0:atomic_set(&mfd->kickoff_pending, 0);还有就是在mdss_fb_release_kickoff的时候设置为0,
static void mdss_fb_release_kickoff(struct msm_fb_data_type *mfd)
{
    if (mfd->wait_for_kickoff) {
        atomic_set(&mfd->kickoff_pending, 0);
        wake_up_all(&mfd->kickoff_wait_q);
    }
}

搜所这个函数可以发现他在两个地方被调用:
1.
__mdss_fb_sync_buf_done_callback函数里的

case MDP_NOTIFY_FRAME_CTX_DONE:
             pr_info("===MDP_NOTIFY_FRAME_CTX_DONE===\n");
        mdss_fb_release_kickoff(mfd);
        break;
    }
说明收到MDP_NOTIFY_FRAME_CTX_DONE通知的时候会去清零&mfd->kickoff_pending
2.
__mdss_fb_perform_commit
        if (IS_ERR_VALUE(ret) || !sync_pt_data->flushed) {
             pr_info("===mdss_fb_release_kickoff __mdss_fb_perform_commit===\n");
        mdss_fb_release_kickoff(mfd);
        mdss_fb_signal_timeline(sync_pt_data);
    }

但是打印的log显示IS_ERR_VALUE(ret)为0,sync_pt_data->flushed为1,条件不满足

3.__mdss_fb_display_thread
    while (1) {
        wait_event(mfd->commit_wait_q,
                (atomic_read(&mfd->commits_pending) ||
                 kthread_should_stop()));

if (kthread_should_stop())
            break;

MDSS_XLOG(mfd->index, XLOG_FUNC_ENTRY);
        ret = __mdss_fb_perform_commit(mfd);
        MDSS_XLOG(mfd->index, XLOG_FUNC_EXIT);

atomic_dec(&mfd->commits_pending);
        wake_up_all(&mfd->idle_wait_q);
    }
    pr_info("===mdss_fb_release_kickoff in __mdss_fb_display_thread===\n");
    mdss_fb_release_kickoff(mfd);
这个是已经跳出整个内核显示线程了才释放清零,也排除.

所以只能是第一种情况,查找MDP_NOTIFY_FRAME_CTX_DONE发现问题出在mdp3_ctrl.c里的mdp3_ctrl_pan_display函数
            if (mdp3_ctrl_get_intf_type(mfd) ==
                MDP3_DMA_OUTPUT_SEL_SPI_CMD) {
            stride = fbi->fix.line_length;
            pr_info("addr = %x, smemlen = %d, stride = %d, offset = %x\n",
                (int)mfd->iova, (int)fbi->fix.smem_len,
                    stride, (int)offset);
            rc = mdss_spi_panel_kickoff(mdp3_session->panel,
                (void *)(int)(mfd->fbi->screen_base + offset),
                (int)fbi->fix.smem_len,
                stride);
                    pr_info("===mdss_spi_panel_kickoff ret = %d===\n", rc);
        } else {
            rc = mdp3_session->dma->update(mdp3_session->dma,
                    (void *)(int)(mfd->iova + offset), mdp3_session->intf,
                    mdp3_session->first_commit, NULL);
               }
        /* This is for the previous frame */
        if (rc < 0) {
                  pr_info("===MDP_NOTIFY_FRAME_TIMEOUT===\n");
            mdp3_ctrl_notify(mdp3_session,
                MDP_NOTIFY_FRAME_TIMEOUT);
        } else {
            pr_info("===MDP_NOTIFY_FRAME_DONE and MDP_NOTIFY_FRAME_CTX_DONE===\n");
            if (mdp3_ctrl_get_intf_type(mfd) ==
                MDP3_DMA_OUTPUT_SEL_DSI_VIDEO /*||
                mdp3_ctrl_get_intf_type(mfd) ==
                    MDP3_DMA_OUTPUT_SEL_SPI_CMD*/) {
                mdp3_ctrl_notify(mdp3_session,
                    MDP_NOTIFY_FRAME_DONE);
                mdp3_ctrl_notify(mdp3_session,
                    MDP_NOTIFY_FRAME_CTX_DONE);
            }
        }

mdss_spi_panel_kickoff发完SPI数据之后,没有通过mdp3_ctrl_notify通知MDP_NOTIFY_FRAME_CTX_DONE事件完成,加上这个判断之后,显示就正常了。

当然recovery层要做RGBA8888到RGB565的格式转换,

至此,显示OK。

另外,mdp3_ctrl_pan_display是怎么刷新数据的?
查看log:
[    8.206292] ===fb_blank===
[    8.206296] ===info->fbops->fb_blank(blank, info);===
[    8.206300] mdss_fb_blank: ===5===
[    8.206303] mdss_fb_blank_sub: ==mdss_fb_blank_sub==
[    8.206308] mdss_fb_blank_unblank: ===mdss_fb_blank_unblank===
[    8.206324] mdss_fb_start_disp_thread: ===mdss_fb_blank_unblank.part.27+0x110/0x26c: start display thread fb0

查看代码:
fbdev_init的最后会调用    
fbdev_blank(backend, true);关闭显示
fbdev_blank(backend, false);打开显示
fbdev_blank调用了ioctl函数发送FBIOBLANK命令: ioctl(fb_fd, FBIOBLANK, blank ? FB_BLANK_POWERDOWN : FB_BLANK_UNBLANK);
这个命令处理do_fb_ioctl里面会执行 fb_blank(info, arg);函数,接着调用(info->fbops->fb_blank),fb_blank又对应到高通驱动    
.fb_blank = mdss_fb_blank,    /* blank display */
然后调用mdss_fb_blank_sub,然后调用mdss_fb_blank_unblank,在mdss_fb_blank_unblank调用mdss_fb_start_disp_thread启用了一个内核线程:
mfd->disp_thread = kthread_run(__mdss_fb_display_thread,
                mfd, "mdss_fb%d", mfd->index);

static int __mdss_fb_display_thread(void *data)
{
    struct msm_fb_data_type *mfd = data;
    int ret;
    struct sched_param param;

/*
     * this priority was found during empiric testing to have appropriate
     * realtime scheduling to process display updates and interact with
     * other real time and normal priority tasks
     */
    param.sched_priority = 16;
    ret = sched_setscheduler(current, SCHED_FIFO, &param);
    if (ret)
        pr_warn("set priority failed for fb%d display thread\n",
                mfd->index);

while (1) {
        wait_event(mfd->commit_wait_q,
                (atomic_read(&mfd->commits_pending) ||
                 kthread_should_stop()));

if (kthread_should_stop())
            break;

MDSS_XLOG(mfd->index, XLOG_FUNC_ENTRY);
        ret = __mdss_fb_perform_commit(mfd);
        MDSS_XLOG(mfd->index, XLOG_FUNC_EXIT);

atomic_dec(&mfd->commits_pending);
        wake_up_all(&mfd->idle_wait_q);
    }
    pr_info("===mdss_fb_release_kickoff in __mdss_fb_display_thread===\n");
    mdss_fb_release_kickoff(mfd);
    atomic_set(&mfd->commits_pending, 0);
    wake_up_all(&mfd->idle_wait_q);

return ret;
}

__mdss_fb_perform_commit里面就会调用mdss_fb_pan_display_sub执行mfd->mdp.dma_fnc(mfd);
它就对应了高通驱动:
    mdp3_interface->dma_fnc = mdp3_ctrl_pan_display;

所以说recovery模式下的显示是通过mdp3_ctrl_pan_display一直在刷新数据,死循环一直在跑。
=======================================================================================
高通开机logo要求:
图片资源必须为png,且色深为8-bit的RGB或者RGBA格式。
制作splash.img开机logo分区的脚本:device/qcom/msm8909w/common/display/logo/logo_gen.py
=======================================================================================
NV项说明:
MSM8953定制手机
NV项 定义
2499 NV_FACTORY_DATA_3_I
1943 MEID 
550  IMEI 
7233 OPTION

MSM8909W手表
2499 NV_FACTORY_DATA_3_I
1943 NV_MEID_I 7个字节
550  NV_UE_IMEI_I 9个字节
7233 OPTION 这一项我们不需要读,这个是做产测工具的同事用的,用来多次写MEID和IMEI,因为用QXDM写550和1943只能写一次,做产测工具的同事工厂写MEID和IMEI到7233项,底层再写到550和1943项
7234 NV_OEM_WATCH_INFO_I 其中dev_id占四个字节(CCF00015),akey占8个字节(4455DB91),qr_code占20个字节(0AD9F46F4B0872AC683E94717AB79676F4D9),实际写了18个字节,qxdm读不了这一项
7235 NV_OEM_CSS_URL_I 服务器地址128个字节,以ascii码字符串写入,所以不需要做格式转换,qxdm读不了这一项

adb shell am start -n com.android.dialer/.DialtactsActivity
打开拨号键盘,输入“*#06#”现实MEID和IMEI号码为:
MEID:A10000470107A5 
QXDM查看1943项为meid:0xA10000470107A5(meid为uint64类型,56 bits/8 bit=7 byte),用户看起来就是14个字符
IMEI:869303030000218  用户看起来是15个字符
QXDM查看00550项:
ue_imei[0] 0x08 //长度
ue_imei[1] 0x8A //A不显示,从8开始显示
ue_imei[2] 0x96 //以下开始高低字节反序
ue_imei[3] 0x03
ue_imei[4] 0x03
ue_imei[5] 0x03
ue_imei[6] 0x00
ue_imei[7] 0x20
ue_imei[8] 0x81
qcril读回来ue_imei后要转成16进制字符串“088A96030303002081”再传到android应用层,然后应用层再做格式转化,否则上层调用方法nvReadItem读item ID的时候遇到0x00就会被截断了。所以NV_OEM_WATCH_INFO_I、NV_UE_IMEI_I、NV_OEM_WATCH_INFO_I都会有0x00的情况或大于127(上层显示不出来)的情况,所以需要做格式转换,NV_OEM_CSS_URL_I为服务器地址,以ascii字符串写入,所以不需要转格式。
===============================
原生Dialer(蓝色) 没有被overlay覆盖的就走这个工程
mmm packages/apps/Dialer/
out/target/product/MSM8909W/system/priv-app/Dialer/Dialer.apk

MSM8909W手表改过的Dialer(黑色)
mmm packages/apps/pubtron/MSM8909W/Dialer/
out/target/product/MSM8909W/system/priv-app/MSM8909WDialer/MSM8909WDialer.apk
===================================================================
MSM8909W手表 modem死机的原因:MODEM - sns_smgr_sensor.c:307   config_odr - sensor=1 odr=16 status=7
log打印config_odr - sensor=1 是ACC传感器
status=7是SNS_DDF_EBUS,             /**< Failure in the underlying bus or bus driver. */总线驱动的潜在原因导致
typedef enum
{
     SNS_DDF_SUCCESS,          /**< No error. */
     SNS_DDF_PENDING,          /**< Status cannot be provided immediately and will
                                    be returned asynchronously instead. */
     SNS_DDF_EFAIL,            /**< Unspecified error. */
     SNS_DDF_ENOMEM,           /**< Insufficient memory to process the request. */
     SNS_DDF_EINVALID_DATA,    /**< Invalid data found in input buffer. */
     SNS_DDF_EINVALID_PARAM,   /**< Invalid value of an input parameter. */
     SNS_DDF_EINVALID_ATTR,    /**< Invalid attribute ID. */
     SNS_DDF_EBUS,             /**< Failure in the underlying bus or bus driver. */
     SNS_DDF_EDEVICE,          /**< Failure in the device. */
     SNS_DDF_EDATA_BOUND,      /**< One or more data samples are out-of-bound. */
     SNS_DDF_EDEVICE_BUSY,     /**< Device is busy and can't service the request. */
     SNS_DDF_EINVALID_TEST,    /**< Invalid test case requested for this device. */
     SNS_DDF_EINVALID_DAF_REQ, /**< Invalid Driver Access request. */
     SNS_DDF_ELAST
} sns_ddf_status_e;

代码出错的地方:
    ddf_status = sns_smgr_set_attr(sensor_ptr, sensor_type, SNS_DDF_ATTRIB_ODR, &odr);//设置ODR的时候这里返回7:SNS_DDF_EBUS
    if ( SNS_DDF_SUCCESS == ddf_status )
    {
      ddf_sensor_ptr->requested_odr = odr;
      if ( SMGR_SENSOR_IS_SELF_SCHED(sensor_ptr) && 
           !SMGR_SENSOR_FIFO_IS_ENABLE(sensor_ptr) )
      {
        if ( odr > 0 )
        {
          sns_smgr_update_ewur( FX_CONV_Q16(odr,0), FX_CONV_Q16(ddf_sensor_ptr->current_odr,0), 
                                sensor_ptr->is_uimg_refac, 
                                !sns_smgr_ddf_sensor_is_event_sensor(ddf_sensor_ptr) );

/* trigger self schedule */
          sns_smgr_dd_enable_sched_data(sensor_ptr, sensor_type, true);
        }
        else
        { 
          sns_smgr_update_ewur( 0, FX_CONV_Q16(ddf_sensor_ptr->current_odr,0), 
                                sensor_ptr->is_uimg_refac, 
                                !sns_smgr_ddf_sensor_is_event_sensor(ddf_sensor_ptr) );

/* stops streaming */
          sns_smgr_dd_enable_sched_data(sensor_ptr, sensor_type, false);
        }
      }
    }
    //高通的措施是else if ( (SNS_DDF_EBUS != ddf_status) && (SNS_DDF_EDEVICE != ddf_status) ),让其不要产生fatal err
    else if ( (SNS_DDF_EBUS != ddf_status) || (SNS_DDF_EDEVICE != ddf_status) )
    {
      /* should not fail */
      ERR_FATAL("config_odr - sensor=%u odr=%u status=%u",
                sensor_type, odr, ddf_status);
    }
======================================================================================================================
关于屏幕送显示数据与TE信号的同步问题:
画面刷新有残留(tearing effect,即TE)的问题。根本原因是主控写图像数据的速度与LCM刷屏的速度不一致造成的,具体是刷屏速度要快于主控写速度。好在很多LCM驱动芯片都有一个Fmark脚,用来与主控同步,当Fmark发出一个信号给主控时,主控才开始写一帧数据,这样就可以保证两边同步。所以屏幕刷新数据的时候需要等待TE中断信号到来了才能刷新数据,如果TE信号没来就等待。如果TE信号来了就在中断处理函数里去唤醒一个完成量,通过函数
complete(struct completion *x);//(1)x->done++,(2)唤醒一个处于等待该完成量x的进程或线程
唤醒正在处于等待的刷新屏幕数据的进程或线程
刷新数据的函数里就一直在等待这个完成量被唤醒,刷新函数里其实需要做三件事情:
1.使能TE中断
2.动态将完成量清零,通过动态初始化:void init_completion(struct completion *x);//x->done=0;
3.进入等待状态,等待TE中断到来,等待完成量被唤醒,通过unsigned long wait_for_completion_timeout(struct completion *x, unsigned long timeout);//在规定的时间内等待
等待到完成量被唤醒之后就可以发送显示数据了。

具体来说:
在SPI屏幕中,完成量x是struct completion spi_panel_te;等待发数据的线程是:mdss_spi_panel_kickoff,将被mdp3_ctrl_pan_display(recovery模式)或mdp3_ctrl_display_commit_kickoff(正常模式)在mdp3_ctrl.c中被调用,这两个函数是在显示的内核线程中死循环执行的。TE中断处理函数:spi_panel_te_handler(),调用complete(&ctrl_pdata->spi_panel_te);唤醒刷新数据的进程函数:
int mdss_spi_panel_kickoff(struct mdss_panel_data *pdata,
            char *buf, int len, int dma_stride)

看下完成量的原型:
struct completion {
    unsigned int done;
    wait_queue_head_t wait;
};

除了有一个用于计数用的done,还有一个等待队列,
 * Completions currently use a FIFO to queue threads that have to wait for
 * the "completion" event.
可以看出完成量现在使用一个FIFO队列来存放那些需要等待完成量的线程,
typedef struct __wait_queue_head wait_queue_head_t;
struct __wait_queue_head {
    spinlock_t        lock;
    struct list_head    task_list;
};

wait_queue_head_t等待队列由一个自旋锁lock和一个链表task_list组成。完成量主要用于实现执行单元A和执行单元B的同步功能。completion是一种轻量级的机制,它允许一个线程告诉另一个线程某个工作已经完成。
========================================================
panel crash现象:
   195.340327:   <6> BUG: spinlock lockup suspected on CPU#3, mdss_fb0/5348
   195.345485:   <6>  lock: 0xdd80a53c, .magic: dead4ead, .owner: <none>/-1, .owner_cpu: -1

dump信息:
CPU 1 Call Stacks (dumped by TZ):
-000|arch_timer_read_counter_long()
-001|read_current_timer()
-002|__timer_delay()
-003|do_raw_spin_lock()
-004|_raw_spin_lock_irqsave()
-005|complete()
-006|spi_panel_te_handler()
-007|handle_irq_event_percpu()
-008|handle_irq_event()
-009|handle_edge_irq()
-010|generic_handle_irq()
-011|msm_gpio_irq_handler()
-012|generic_handle_irq()
-013|__handle_domain_irq()
-014|gic_handle_irq()
-015|__irq_usr()
----|end of frame

可以看到死机的时候,跑到了TE的中断处理函数里spi_panel_te_handler(),查看该函数源码可以看到:
irqreturn_t spi_panel_te_handler(int irq, void *data)
{
    struct spi_panel_data *ctrl_pdata = (struct spi_panel_data *)data;
    static int count = 2;
    if (!ctrl_pdata) {
        pr_err("%s: SPI display not available\n", __func__);
        return IRQ_HANDLED;
    }
    complete(&ctrl_pdata->spi_panel_te);

if (ctrl_pdata->vsync_client.handler && !(--count)) {
        ctrl_pdata->vsync_client.handler(ctrl_pdata->vsync_client.arg);
        count = 2;
    }

return IRQ_HANDLED;
}
调用了complete修改完成量来唤醒发显示数据的函数,complete调用了spin_lock_irqsave(&x->wait.lock, flags);一直去获取等待队列的自旋锁,然后可能一直获取
不到锁,然后就造成了死锁,系统就crash了。另外一个可能拥有锁的地方就是在刷数据里的等待:wait_for_completion_timeout,这里面也会去获得锁和释放锁。
void complete(struct completion *x)
{
    unsigned long flags;

spin_lock_irqsave(&x->wait.lock, flags);
    x->done++;
    __wake_up_locked(&x->wait, TASK_NORMAL, 1);//唤醒一个处于等待该完成量x的进程或线程
    spin_unlock_irqrestore(&x->wait.lock, flags);
}
关于这个自旋锁的API:
spin_lock_irqsave(lock, flags)该宏获得自旋锁的同时把标志寄存器的值保存到变量flags中并失效本地中断。
spin_unlock_irqrestore(lock, flags)该宏释放自旋锁lock的同时,也恢复标志寄存器的值为变量flags保存的值。它与spin_lock_irqsave配对使用。
在使用spin_lock_irq和spin_unlock_irq的情况下,完全可以用spin_lock_irqsave和spin_unlock_irqrestore取代,那具体应该使用哪一个也需要依情况而定,如果可以确信在对共享资源访问前中断是使能的,那么使用spin_lock_irq更好一些。因为它比spin_lock_irqsave要快一些,但是如果你不能确定是否中断使能,那么使用spin_lock_irqsave和spin_unlock_irqrestore更好,因为它将恢复访问共享资源前的中断标志而不是直接使能中断。

关于自旋锁的特性:
1.如果自旋锁已经被别的执行单元持有,调用者就一直循环在那里看是否该自旋锁的保持者已经释放了锁,"自旋"一词就是因此而得名。只有在占用时间极短的情况下,使用自旋锁才是合理的,如果要长时间占有锁,使用自旋锁会降低系统的性能。
2.自旋锁使用者一般保持锁时间非常短,不会引起调用者睡眠;信号量和读写信号量适合于保持时间较长的情况,它们会导致调用者睡眠,因此只能在进程上下文使用
3.如果被保护的共享资源需要在中断上下文访问(包括顶半部即中断处理句柄和底半部即软中断),就必须使用自旋锁。上(顶)半部指的是中断处理程序,下(底)半部BH(bottom half)则指的是一些虽然与中断有相关性但是可以延后执行的任务。下半部的机制实际上包括软中断、tasklet和工作队列3种机制。软中断可以并发运行在多个CPU上(即使同一类型的也可以)。所以软中断必须设计为可重入的函数(允许多个CPU同时操作),因此也需要使用自旋锁来保护其数据结构。一种特定类型的tasklet只能运行在一个CPU上,不能并行,只能串行执行。 工作队列可以把工作推后,交由一个内核线程去执行,可以睡眠。所以tasklet和工作队列应该不会用到自旋锁,如果被保护的共享资源只在一个tasklet或timer上下文访问,那么不需要任何自旋锁保护,因为同一个tasklet或timer只能在一个CPU上运行,即使是在SMP环境下也是如此。实际上tasklet在调用tasklet_schedule标记其需要被调度时已经把该tasklet绑定到当前CPU,因此同一个tasklet决不可能同时在其他CPU上运行。timer也是在其被使用add_timer添加到timer队列中时已经被帮定到当前CPU,所以同一个timer绝不可能运行在其他CPU上。软中断需要用到自旋锁,但是驱动编写者很少直接使用软中断。
4.自旋锁保持期间是会抢占内核的,在单CPU且内核可抢占的系统中,自旋锁持有期间内核的抢占将被禁止,而信号量和读写信号量保持期间内核是可以被抢占的。自旋锁只有在单CPU但内核可抢占或SMP的情况下才真正需要,在单CPU且不可抢占的内核下,自旋锁的所有操作都是空操作。
5.尽管使用了自旋锁可以保证临界区不受别的CPU和本CPU内的抢占进程打扰,但是得到锁的代码路径在执行临界区的时候,还可能受到中断和底半部BH的影响。为了防止这种影响才会有自旋锁的衍生。
spin_lock_irqsave() = spin_lock() + local_irq_save()
spin_unlock_irqrestore() = spin_unlock() + local_irq_restore()
spin_lock_irq() = spin_lock() + local_irq_disable()关中断 --避免突如其来的中断驶入对系统的危害
spin_unlock_irq() = spin_unlock() + local_irq_enable()开中断
spin_lock_bh() = spin_lock() + local_bh_disable()--在得到自旋锁的同时失效本地软中断。
spin_unlock_bh() = spin_unlock() + local_bh_enable()

看下spinlock_t的定义:
typedef struct spinlock {
    union {
        struct raw_spinlock rlock;

#ifdef CONFIG_DEBUG_LOCK_ALLOC
# define LOCK_PADSIZE (offsetof(struct raw_spinlock, dep_map))
        struct {
            u8 __padding[LOCK_PADSIZE];
            struct lockdep_map dep_map;
        };
#endif
    };
} spinlock_t;

再看下原始的raw_spinlock:
typedef struct raw_spinlock {
    arch_spinlock_t raw_lock;
#ifdef CONFIG_GENERIC_LOCKBREAK//userdebug、user版本都没有定义
    unsigned int break_lock;
#endif
#ifdef CONFIG_DEBUG_SPINLOCK//userdebug有定义,user版本并没有定义
    unsigned int magic, owner_cpu;
    void *owner;
#endif
#ifdef CONFIG_DEBUG_LOCK_ALLOC//userdebug、user版本都没有定义
    struct lockdep_map dep_map;
#endif
} raw_spinlock_t;
从上面代码来分析一个完整的spinlock_t的结构至少有4个成员:raw_lock/ magic/ owner_cpu/ owner

他们的初始值由spin_lock_init最后调用到__raw_spin_lock_init给出来
void __raw_spin_lock_init(raw_spinlock_t *lock, const char *name,
              struct lock_class_key *key)
{
#ifdef CONFIG_DEBUG_LOCK_ALLOC
    /*
     * Make sure we are not reinitializing a held lock:
     */
    debug_check_no_locks_freed((void *)lock, sizeof(*lock));
    lockdep_init_map(&lock->dep_map, name, key, 0);
#endif
    lock->raw_lock = (arch_spinlock_t)__ARCH_SPIN_LOCK_UNLOCKED;//解锁状态
    lock->magic = SPINLOCK_MAGIC;//#define SPINLOCK_MAGIC        0xdead4ead
    lock->owner = SPINLOCK_OWNER_INIT;//#define SPINLOCK_OWNER_INIT    ((void *)-1L)
    lock->owner_cpu = -1;
}

spin_lock_irqsave的调用关系:
#define spin_lock_irqsave(lock, flags)                \
do {                                \
    raw_spin_lock_irqsave(spinlock_check(lock), flags);    \
} while (0)

#define raw_spin_lock_irqsave(lock, flags)            \
    do {                        \
        typecheck(unsigned long, flags);    \
        flags = _raw_spin_lock_irqsave(lock);    \
    } while (0)

_raw_spin_lock_irqsave(lock)就与dump信息的调用关系
_raw_spin_lock_irqsave()一致了,证实了死机的时候就是跑到这里来了
继续往下追:
somehow,
_raw_spin_lock_irqsave调用到了do_raw_spin_lock()
do_raw_spin_lock()调用了debug_spin_lock_before
void do_raw_spin_lock(raw_spinlock_t *lock)
{
    debug_spin_lock_before(lock);
    if (unlikely(!arch_spin_trylock(&lock->raw_lock)))
        __spin_lock_debug(lock);
    debug_spin_lock_after(lock);
}

debug_spin_lock_before调用了SPIN_BUG_ON
static inline void
debug_spin_lock_before(raw_spinlock_t *lock)
{
    SPIN_BUG_ON(lock->magic != SPINLOCK_MAGIC, lock, "bad magic");
    SPIN_BUG_ON(lock->owner == current, lock, "recursion");
    SPIN_BUG_ON(lock->owner_cpu == raw_smp_processor_id(),
                            lock, "cpu recursion");
}

#define SPIN_BUG_ON(cond, lock, msg) if (unlikely(cond)) spin_bug(lock, msg)
static void spin_bug(raw_spinlock_t *lock, const char *msg)
{
    if (!debug_locks_off())
        return;

spin_dump(lock, msg);
}

static void spin_dump(raw_spinlock_t *lock, const char *msg)
{
    struct task_struct *owner = NULL;

if (lock->owner && lock->owner != SPINLOCK_OWNER_INIT)
        owner = lock->owner;
    printk(KERN_EMERG "BUG: spinlock %s on CPU#%d, %s/%d\n",
        msg, raw_smp_processor_id(),
        current->comm, task_pid_nr(current));
    printk(KERN_EMERG " lock: %pS, .magic: %08x, .owner: %s/%d, "
            ".owner_cpu: %d\n",
        lock, lock->magic,
        owner ? owner->comm : "<none>",
        owner ? task_pid_nr(owner) : -1,
        lock->owner_cpu);
#ifdef CONFIG_DEBUG_SPINLOCK_BITE_ON_BUG
    msm_trigger_wdog_bite();
#elif defined(CONFIG_DEBUG_SPINLOCK_PANIC_ON_BUG)
    BUG();
#endif
    dump_stack();
}

spin_dump就是最后打印了dump信息的地方:
   195.340327:   <6> BUG: spinlock lockup suspected on CPU#3, mdss_fb0/5348
   195.345485:   <6>  lock: 0xdd80a53c, .magic: dead4ead, .owner: <none>/-1, .owner_cpu: -1

mdss_fb0是current->comm,5348是mdss_fb0的pid,
查看comm的定义:
struct task_struct {
...
char comm[16];   //进程正在运行的可执行文件名
...
}

造成系统死锁的可能原因:
1.如果该锁一直获取不到,死锁了,可能有进程持有相应的锁而一直不释放,导致本进程一直获取不到锁。
2.多做了一次unlock操作(出现的可能性极小,因为,spin_lock和spin_unlock操作肯定是配对的,内核中有相应的静态检查机制,也有相应的死锁检测机制,出现这种直接错误的可能性极小。)
3.并发修改该spinlock。比如:在该spinlock还在被使用时,有其它进程并发修改该spinlock。更具体的例子:在CPU1上,某上下文进行spin_lock操作后,在spin_unlock之前;在CPU2上,另一上下文对该spinlock重新进行了初始化(即将该lock值改为0);然后在CPU1上执行unlock操作,此时该lock的Owner就被多unlock了1次,其Owner就被多加了1(但是据高通回复,kickoff是单线程,只会在一个CPU上跑)
4.递归使用一个自旋锁,如果一个已经拥有某个自旋锁的CPU想第二次获得这个自旋锁,则该CPU将死锁。
5.自旋锁锁定期间不能调用可能引起进程调度的函数。如果进程获得锁之后再阻塞,如调用copy_from_user(),copy_to_user(),kmalloc(),msleep()函数,可能会导致内核崩溃。

解决路径:
1.Removing CONFIG_DEBUG_SPINLOCK=y 关闭debug宏开关,user版本已经默认关闭了。
2.可能是问题3,继续分析这个completion的使用逻辑,发显示数据的函数在init_completion后,调用wait_for_completion_timeout等待该completion变量完成,即等待其它地方调用completion()函数来唤醒该进程。看起来逻辑没啥问题,但问题在于:如果在调用init_completion之前,就有地方调用complete()函数的话,可能就有问题了(但其实应该也不会,因为probe的时候已经有init_completion了一次了),此时,如果另外的上下文刚好在lock之后unlock之前,就刚好符合之前说的情况3了。其实该问题的本质在于对completion结构的访问没有进行保护,由于可能在多CPU上并发访问,按理应该有相应的机制进行保护才对(比如锁)

这个问题因为只复现过一次,目前还没有对应措施去对应解决,只是先分析到这里。

=====================================================================================
当系统crash的时候,如果机器有接串口线,也可以查看到死机的信息,比如modem crash
[   71.991405] Fatal error on the modem.
[   71.994052] modem subsystem failure reason: sns_smgr_sensor.c:307:config_odr - sensor=1 odr=16 status=7.
[   72.003834] M-Notify: General: 8
[   72.110245] Kernel panic - not syncing: subsys-restart: Resetting the SoC - modem crashed.
[   72.117498] CPU: 2 PID: 2736 Comm: kworker/2:2 Not tainted 3.18.24 #11

如果是整机,没有串口线,那就只能通过QPST来抓取crash log,再用QCAP来分析了。
=====================================================================================
MSM8909W待机功耗高的问题(达到20几mA),待机底电流1mA以下正常,1mA以上就不正常了
<3>[ 4042.193513] BUG: sleeping function called from invalid context at /home//work/msm8909w_law_android/kernel/kernel/locking/mutex.c:97
<3>[ 4042.204716] in_atomic(): 1, irqs_disabled(): 0, pid: 2096, name: android.bg
<3>[ 4042.211669] Preemption disabled at:[<  (null)>]   (null)
<6>[ 4042.216895] 
<6>[ 4042.216918] CPU: 3 PID: 2096 Comm: android.bg Tainted: G           O   3.18.24 #2
<6>[ 4042.216956] [<c00147f0>] (unwind_backtrace) from [<c0011c34>] (show_stack+0x10/0x14)
<6>[ 4042.216981] [<c0011c34>] (show_stack) from [<c0948c94>] (dump_stack+0x6c/0xb8)
<6>[ 4042.217002] [<c0948c94>] (dump_stack) from [<c0950ccc>] (mutex_lock+0x18/0x3c)
<6>[ 4042.217023] [<c0950ccc>] (mutex_lock) from [<c03bbe20>] (kgsl_get_egl_counts+0x24/0x98)
<6>[ 4042.217046] [<c03bbe20>] (kgsl_get_egl_counts) from [<c03d05c0>] (print_mem_entry+0x128/0x224)
<6>[ 4042.217068] [<c03d05c0>] (print_mem_entry) from [<c026cf90>] (idr_for_each+0xac/0xd4)
<6>[ 4042.217087] [<c026cf90>] (idr_for_each) from [<c03d0740>] (process_mem_print+0x84/0xcc)
<6>[ 4042.217109] [<c03d0740>] (process_mem_print) from [<c01466b0>] (seq_read+0x1a8/0x400)
<6>[ 4042.217131] [<c01466b0>] (seq_read) from [<c0128f0c>] (vfs_read+0x90/0x124)
<6>[ 4042.217150] [<c0128f0c>] (vfs_read) from [<c012944c>] (SyS_read+0x40/0x80)
<6>[ 4042.217169] [<c012944c>] (SyS_read) from [<c000e060>] (ret_fast_syscall+0x0/0x38)
<6>[ 4062.063296] ctrl_pdata->rst_gpio = 25,ctrl_pdata->disp_dc_gpio = 23

先看下这个log在哪里打印,
打印的源码位置:
void __might_sleep(const char *file, int line, int preempt_offset)
{
...

printk(KERN_ERR
        "BUG: sleeping function called from invalid context at %s:%d\n",
            file, line);
    printk(KERN_ERR
        "in_atomic(): %d, irqs_disabled(): %d, pid: %d, name: %s\n",
            in_atomic(), irqs_disabled(),
            current->pid, current->comm);

...
}
这段代码受到宏开关CONFIG_DEBUG_ATOMIC_SLEEP控制,user版本关闭,userdebug版本打开。

<3>[ 4042.193513] BUG: sleeping function called from invalid context at /home//work/msm8909w_law_android/kernel/kernel/locking/mutex.c:97
<3>[ 4042.204716] in_atomic(): 1, irqs_disabled(): 0, pid: 2096, name: android.bg

说明是mutex.c调用了,可能会进入休眠操作,这个只是个提示信息:

void __sched mutex_lock(struct mutex *lock)
{
    might_sleep();
    /*
     * The locking fastpath is the 1->0 transition from
     * 'unlocked' into 'locked' state.
     */
    __mutex_fastpath_lock(&lock->count, __mutex_lock_slowpath);
    mutex_set_owner(lock);
}

表示代码在原子上下文中休眠了!
kernel BUG() was trigged due to mutex call(can be slept) inside invalid context( atomic environment) in below call stack.
-----------------------------------------------

另外一些提示报错:
Freezing of tasks aborted after 0.005 seconds
Error: returning -512 value
冻结任务被终止
kernel\power\process.c
static int try_to_freeze_tasks(bool user_only)
{
    ...
    while (true) {
        ...

if (pm_wakeup_pending()) {//执行pm_wakeup_pending,用来判断当前的的power transition是否应该终止。正常情况下这里不应该终止,
#ifdef CONFIG_PM_SLEEP//user和debug都没有定义
            pm_get_active_wakeup_sources(suspend_abort,
                MAX_SUSPEND_ABORT_LEN);
            log_suspend_abort_reason(suspend_abort);
#endif
            wakeup = true;
            break;
        }
        ...
    }

...
    if (wakeup) {//说明是有唤醒事件在等待,所以没有睡下去
        printk("\n");
        printk(KERN_ERR "Freezing of tasks aborted after %d.%03d seconds",
               elapsed_msecs / 1000, elapsed_msecs % 1000);
    } else if (todo) {
        printk("\n");
        printk(KERN_ERR "Freezing of tasks failed after %d.%03d seconds"
               " (%d tasks refusing to freeze, wq_busy=%d):\n",
               elapsed_msecs / 1000, elapsed_msecs % 1000,
               todo - wq_busy, wq_busy);
            ...
    } else {
        printk("(elapsed %d.%03d seconds) ", elapsed_msecs / 1000,
            elapsed_msecs % 1000);
    }

return todo ? -EBUSY : 0;
}

android手机频繁地进出suspend/resume状况,因此需要pm_wakeup_pending()机制,用来检查进入这段时间是否有被唤醒的事件发生。
/**
 * pm_wakeup_pending - Check if power transition in progress should be aborted.
 *
 * Compare the current number of registered wakeup events with its preserved
 * value from the past and return true if new wakeup events have been registered
 * since the old value was stored.  Also return true if the current number of
 * wakeup events being processed is different from zero.
 */
bool pm_wakeup_pending(void)
{
    unsigned long flags;
    bool ret = false;

spin_lock_irqsave(&events_lock, flags);
    if (events_check_enabled) {
        unsigned int cnt, inpr;

split_counters(&cnt, &inpr);
        ret = (cnt != saved_count || inpr > 0);//如果注册的wakeup events 数量有变化,或是目前wakeup events数(in progress wakeup_sources数)大于0,则True,表示要终止suspend,即resume起来后再suspend动作
        events_check_enabled = !ret;
    }
    spin_unlock_irqrestore(&events_lock, flags);

if (ret) {
        pr_info("PM: Wakeup pending, aborting suspend\n");
        pm_print_active_wakeup_sources();
    }

return ret || pm_abort_suspend;
}
/*
 * Combined counters of registered wakeup events and wakeup events in progress.
 * They need to be modified together atomically, so it's better to use one
 * atomic variable to hold them both.
 */
static void split_counters(unsigned int *cnt, unsigned int *inpr)
{
    unsigned int comb = atomic_read(&combined_event_count);

*cnt = (comb >> IN_PROGRESS_BITS);//counters of registered wakeup events 
    *inpr = comb & MAX_IN_PROGRESS;//wakeup events in progress.
}
可看出实际是:combined_event_count发生了变化导致的,有两个函数会去改变这个变量:
1.wakeup_source_activate
2.wakeup_source_deactivate
添加打印,查看ws->name
if(events_check_enabled)
    printk(KERN_ERR "wakeup_source_activate(), ws->name = %s", ws->name);

查看系统中的wakeup_source
adb shell cat sys/kernel/debug/wakeup_sources > wakeup_source.txt

然后看log,确实suspend过程中有一些wakeup_source出现,不过系统会尝试去关闭这些wakeup_source并最终达到休眠的目的。所以关键是要看suspend的流程有没有
正常走完,高通给了正常和异常的两个参考log:
1. abnormal suspend log as below,

<6>[ 325.473149] Freezing user space processes ...
<3>[ 325.477249] Error: returning -512 value
<6>[ 325.497303] PM: Wakeup pending, aborting suspend
<6>[ 325.497326] active wakeup source: wlan
<6>[ 325.497437]
<3>[ 325.497441] Freezing of tasks aborted after 0.024 seconds//出现了我们此次出现的错误log
<6>[ 325.497447] Restarting tasks ... done.
<6>[ 325.519114] PM: suspend exit 1970-01-01 04:08:55.139500300 UTC

2. normal suspend log as below,

<6>[ 327.744179] PM: suspend entry 1970-01-01 04:09:45.013117468 UTC
<6>[ 327.744191] PM: Syncing filesystems ... done.
<7>[ 327.810413] PM: Preparing system for mem sleep
<6>[ 327.811782] Freezing user space processes ...
<3>[ 327.815645] Error: returning -512 value
<6>[ 327.855215] (elapsed 0.043 seconds) done.
<6>[ 327.855230] Freezing remaining freezable tasks ... (elapsed 0.004 seconds) done.
<7>[ 327.859799] PM: Entering mem sleep
<6>[ 327.859805] Suspending console(s) (use no_console_suspend to debug)
<6>[ 327.909332] PM: suspend of devices complete after 48.306 msecs
<6>[ 327.911141] PM: late suspend of devices complete after 1.802 msecs
<6>[ 327.917696] PM: noirq suspend of devices complete after 6.547 msecs
<6>[ 327.917702] Disabling non-boot CPUs ...

- - - - - - - - - - - - - - - - - - - 
至于log一直返回-512是怎么回事?
网上的解释:
每次设备进入睡眠的时候,有个进程总是会打印出-512的错误,经查这个是因为daemon被wake_up后,condition不满足但是daemon收到了signal导致的。
daemon通过系统调用ioctl进入内核空间,然后调用wait_event_interruptible函数让自身休眠,注意这个wait_event_interruptible是可以被signal打断的。
wait_event_interruptible的具体代码如下,其只是对__wait_event_interruptible的封装,所以直接看封装前的代码,如下:
/**
 * wait_event_interruptible - sleep until a condition gets true
 * @wq: the waitqueue to wait on
 * @condition: a C expression for the event to wait for
 *
 * The process is put to sleep (TASK_INTERRUPTIBLE) until the
 * @condition evaluates to true or a signal is received.
 * The @condition is checked each time the waitqueue @wq is woken up.
 *
 * wake_up() has to be called after changing any variable that could
 * change the result of the wait condition.
 *
 * The function will return -ERESTARTSYS if it was interrupted by a
 * signal and 0 if @condition evaluated to true.
 */
#define wait_event_interruptible(wq, condition)                \
({                                    \
    int __ret = 0;                            \
    if (!(condition))                        \
        __ret = __wait_event_interruptible(wq, condition);    \
    __ret;                                \
})
最后会调用到long prepare_to_wait_event(wait_queue_head_t *q, wait_queue_t *wait, int state)
{
    unsigned long flags;

if (signal_pending_state(state, current))
        return -ERESTARTSYS;//#define ERESTARTSYS    512
    ...

return 0;
}
那是哪里一直打印:“Error: returning -512 value”
搜索代码发现是kernel/drivers/usb/gadget/function/f_fs.c
static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data)
{
    ...    /*
         * if ep is disabled, this fails all current IOs
         * and wait for next epfile open to happen
         */
        if (!atomic_read(&epfile->error)) {
            ret = wait_event_interruptible(epfile->wait,
                    (ep = epfile->ep));//休眠直到ep = epfile->ep为true,当休眠因为收到signal而中断的时候返回-ERESTARTSYS
                               //ep = epfile->ep为true为true之后,函数返回0
            if (ret < 0)
                goto error;
        }
    ...
    if (ret < 0)
        pr_err_ratelimited("===Error: returning %zd value\n", ret);
    return ret;
}函数
ffs_epfile_read(),ffs_epfile_write(),ffs_epfile_aio_write(),ffs_epfile_aio_read()会去调用ffs_epfile_io()接口
都是该驱动提供的一些读写接口:
static const struct file_operations ffs_epfile_operations = {
    .llseek =    no_llseek,

.open =        ffs_epfile_open,
    .write =    ffs_epfile_write,
    .read =        ffs_epfile_read,
    .aio_write =    ffs_epfile_aio_write,
    .aio_read =    ffs_epfile_aio_read,
    .release =    ffs_epfile_release,
    .unlocked_ioctl =    ffs_epfile_ioctl,
};
PC一般是USB Host 手机等数码设备通常是USB Device
OTG则使设备既可以是USB Device, 也可以是USB Host
在Linux中, 作为USB Device的设备被称为gadget.当把pad/手机插到pc上时,可以作为u盘、网卡等usb功能设备呈现,这个就叫做gadget。可以理解为usb 从设备端,和host对应。初步理解应该是USB构建文件系统相关的读写接口,报错了。
但是这个log,MIPI屏幕也会报。而且是插着USB线不会报(可能是手表这时候正常的充当着gadget的角色),不插USB先才会报,而且高通的参考log,正常休眠也会报这个log,所以suspend异常的问题与此并无关系。
-------------------------------------
下一个问题
[  197.691250] dpm_run_callback(): platform_pm_suspend+0x0/0x54 returns -16
[  197.691261] PM: Device alarmtimer failed to suspend: error -16
[  197.691269] PM: Some devices failed to suspend, or early wake event detected

标准的linux休眠则执行error = enter_state(state);
调用流程是(调用者->被调用者):state_store->pm_suspend->pm_suspend_marker(entry)->enter_state->suspend_devices_and_enter
->dpm_suspend_start->dpm_suspend->dpm_show_time->suspend_enter->dpm_suspend_late->dpm_suspend_noirq->disable_nonboot_cpus
->msm_cpu_pm_enter_sleep(串口log打印打开的情况下,这是串口log打印最后一条并保持很久直到power按键唤醒)
/**
 * enter_state - Do common work needed to enter system sleep state.
 * @state: System sleep state to enter.
 *
 * Make sure that no one else is trying to put the system into a sleep state.
 * Fail if that's not the case.  Otherwise, prepare for system suspend, make the
 * system enter the given sleep state and clean up after wakeup.
 */

MIPI 320P正常休眠过程,待机功耗0.4mA正常的,
按POWER按键休眠,断开USB,只接串口,然后 cat proc/kmsg
<6>[  140.830151] ===state_store,state = 3//3是mem
<6>[  140.830169] ===pm_suspend,state = 3
<6>[  140.830188] ===PM: suspend entry 1970-01-01 00:05:40.128041187 UTC
[  140.854684] ===Error: returning -512 value
(串口log只打到这里,因为串口也休眠了,所以有一部分休眠log要唤醒的时候才看得到)
[  140.899711] migrate_irqs: 310 callbacks suppressed
[  140.899716] IRQ0 no longer affine to CPU3
[  140.899722] IRQ1 no longer affine to CPU3
[  140.899728] IRQ2 no longer affine to CPU3
[  140.899733] IRQ3 no longer affine to CPU3
[  140.899739] IRQ4 no longer affine to CPU3
[  140.899744] IRQ5 no longer affine to CPU3
[  140.899750] IRQ6 no longer affine to CPU3
[  140.899755] IRQ7 no longer affine to CPU3
[  140.899761] IRQ8 no longer affine to CPU3
[  140.899766] IRQ9 no longer affine to CPU3
[  140.901008] CPU3: shutdown
<6>[  140.830200] ===PM: Syncing filesystems ... done.
<6>[  140.850555] ===PM: Preparing system for mem sleep
<6>[  140.85116[  141.045131] healthd: battery l=65 v=3901 t=34.0 h=2 st=3 c=1 chg=
6] Freezing user space processes ... 
<3>[  140.854684] ===Error: returning -512 value
<6>[  140.863249] (elapsed 0.012 seconds) done.
<6>[  140.863273] Freezing remaining freezable tasks ... (elapsed 0.002 seconds) done.
<6>[  140.865806] ===PM: suspend_prepare return 0
<6>[  140.865818] ===PM: Entering mem sleep
<6>[  140.865828] Suspending console(s) (use no_console_suspend to debug)
<6>[  140.893443] PM: suspend of devices complete after 26.281 msecs
<6>[  140.895458] PM: late suspend of devices complete after 2.002 msecs
<6>[  140.898929] PM: noirq suspend of devices complete after 3.456 msecs
<6>[  140.898941] Disabling non-boot CPUs ...//休眠成功
<4>[  140.899711] migrate_irqs: 310 callbacks suppressed
<4>[  140.899716] IRQ0 no longer affine to CPU3
<4>[  140.899722] IRQ1 no longer affine to CPU3
<4>[  140.899728] IRQ2 no longer affine to CPU3
<4>[  140.899733] IRQ3 no longer affine to CPU3
<4>[  140.899739] IRQ4 no longer affine to CPU3
<4>[  140.899744] IRQ5 no longer affine to CPU3
<4>[  140.899750] IRQ6 no longer affine to CPU3
<4>[  140.899755] IRQ7 no longer affine to CPU3
<4>[  140.899761] IRQ8 no longer affine to CPU3
<4>[  140.899766] IRQ9 no longer affine to CPU3
<5>[  140.901008] CPU3: shutdown
<6>[  140.902151] CPU2:msm_cpu_pm_enter_sleep mode:3 during suspend//休眠成功
-----------------真正POWER键唤醒应该是从这里开始打印:--------------
<6>[  140.902351] Enabling non-boot CPUs ...
<6>[  140.902791] CPU3: Booted secondary processor
<6>[  140.903577] CPU3 is up
<6>[  140.904607] PM: noirq resume of devices complete after 1.010 msecs
<6>[  140.906389] PM: early resume of devices complete after 1.135 msecs
<6>[  140.983662] PM: resume of devices complete after 77.257 msecs
<6>[  141.033011] ===PM: suspend_devices_and_enter return 0
<6>[  141.033022] Restarting tasks ... done.
<12>[  141.045131] healthd: battery l=65 v=3901 t=34.0 h=2 st=3 c=1 chg=

以上的log看起来挺正常的,但是有时候也会出现这样的log:
MSM8909W手表:/ # cat proc/kmsg
[   97.473874] BUG: sleeping function called from invalid context at /home/whl/work/msm8909w_law_android/kernel/kernel/locking/mutex.c:97
[   97.485286] in_atomic(): 1, irqs_disabled(): 0, pid: 2045, name: android.bg
[   97.492155] Preemption disabled at:[<  (null)>]   (null)
<3>[   97.492155] Preemption disabled at:[<  (null)>]   (null)
<6>[   97.497340] 
<6>[   97.497359] CPU: 2 PID: 2045 Comm: android.bg Not tainted 3.18.24 #19
<6>[   97.497396] [<c00147f0>] (unwind_backtrace) from [<c0011c34>] (show_stack+0x10/0x14)
<6>[   97.497419] [<c0011c34>] (show_stack) from [<c09469e8>] (dump_stack+0x6c/0xb8)
<6>[   97.497441] [<c09469e8>] (dump_stack) from [<c094ea1c>] (mutex_lock+0x18/0x3c)
<6>[   97.497465] [<c094ea1c>] (mutex_lock) from [<c03b9ab8>] (kgsl_get_egl_counts+0x24/0x98)
<6>[   97.497488] [<c03b9ab8>] (kgsl_get_egl_counts) from [<c03ce258>] (print_mem_entry+0x128/0x224)
<6>[   97.497509] [<c03ce258>] (print_mem_entry) from [<c026cf90>] (idr_for_each+0xac/0xd4)
<6>[   97.497528] [<c026cf90>] (idr_for_each) from [<c03ce3d8>] (process_mem_print+0x84/0xcc)
<6>[   97.497551] [<c03ce3d8>] (process_mem_print) from [<c01466cc>] (seq_read+0x1a8/0x400)
<6>[   97.497573] [<c01466cc>] (seq_read) from [<c0128f28>] (vfs_read+0x90/0x124)      
<6>[   97.497593] [<c0128f28>] (vfs_read) from [<c0129468>] (SyS_read+0x40/0x80)       
<6>[   97.497613] [<c0129468>] (SyS_read) from [<c000e060>] (ret_fast_syscall+0x0/0x38)
<6>[   97.657302] ===state_store,state = 3
<6>[   97.657320] ===pm_suspend,state = 3
<6>[   97.657340] ===PM: suspend entry 1970-01-01 00:47:21.383590845 UTC
[   97.673111] ===wakeup_source_activate(), ws->name = NETLINK
[   97.678855] ===wakeup_source_activate(), ws->name = eventpoll
<6>[   97.657352] ===PM: Syncing filesystems ... done.
<6>[   9[   97.684877] ===wakeup_source_deactivate(), ws->name = NETLINK
[   97.692116] Freezing of tasks aborted after 0.002 seconds
[   97.694130] ===Error: returning -512 value
7.671736] ===PM: Preparing system for mem sleep
<3>[   97.673111] ===wakeup_source_activate(), ws->name = NETLINK
<3>[   97.678855] ===wakeup_source_activate(), ws->name = eventpoll
<3>[   97.684877] ===wakeup_source_deactivate(), ws->name = NETLINK
<6>[   97.692016] Freezing user space processes ... 
<6>[   97.692017] ===PM: Wakeup pending, aborting suspend
<6>[   97.692066] ===active wakeup source: eventpoll
<6>[   97.692107] 
<3>[   97.692116] Freezing of tasks aborted after 0.002 seconds
<6>[   97.694129] Restarting tasks ... 
<3>[   97.694130] ===Error: returning -512 value
<6>[   97.701218] done.
<6>[   97.701442] ===PM: suspend_prepare return -16
<6>[   97.701456] ===PM: suspend exit 1970-01-01 00:47:21.427707772 UTC
//休眠失败了,退出
[   97.810280] ===Error: returning -512 value
[   97.858261] migrate_irqs: 310 callbacks suppressed
[   97.858267] IRQ0 no longer affine to CPU3
[   97.858273] IRQ1 no longer affine to CPU3
[   97.858279] IRQ2 no longer affine to CPU3
[   97.858284] IRQ3 no longer affine to CPU3
[   97.858289] IRQ4 no longer affine to CPU3
[   97.858295] IRQ5 no longer affine to CPU3
[   97.858300] IRQ6 no longer affine to CPU3
[   97.858305] IRQ7 no longer affine to CPU3
[   97.858311] IRQ8 no longer affine to CPU3
[   97.858317] IRQ9 no longer affine to CPU3
[   97.859469] CPU3: shutdown
//继续休眠
<6>[   97.803013] ===state_store,state = 3
<6>[   97.803031]   98.003484] healthd: battery l=62 v=3837 t=34.0 h=2 st=3 c=14 chg=
=pm_suspend,state = 3
<6>[   97.803050] ===PM: suspend entry 1970-01-01 00:47:21.529301731 UTC
<6>[   97.803062] ===PM: Syncing filesystems ... done.
<6>[   97.806178] ===PM: Preparing system for mem sleep
<6>[   97.806798] Freezing user space processes ... 
<3>[   97.810280] ===Error: returning -512 value
<6>[   97.815187] (elapsed 0.008 seconds) done.
<6>[   97.815211] Freezing remaining freezable tasks ... (elapsed 0.002 seconds) done.
<6>[   97.817978] ===PM: suspend_prepare return 0
<6>[   97.817989] ===PM: Entering mem sleep
<6>[   97.818000] Suspending console(s) (use no_console_suspend to debug)
<6>[   97.852280] PM: suspend of devices complete after 32.947 msecs
<6>[   97.854288] PM: late suspend of devices complete after 1.995 msecs
<6>[   97.857649] PM: noirq suspend of devices complete after 3.347 msecs
<6>[   97.857661] Disabling non-boot CPUs ...
<4>[   97.858261] migrate_irqs: 310 callbacks suppressed
<4>[   97.858267] IRQ0 no longer affine to CPU3
<4>[   97.858273] IRQ1 no longer affine to CPU3
<4>[   97.858279] IRQ2 no longer affine to CPU3
<4>[   97.858284] IRQ3 no longer affine to CPU3
<4>[   97.858289] IRQ4 no longer affine to CPU3
<4>[   97.858295] IRQ5 no longer affine to CPU3
<4>[   97.858300] IRQ6 no longer affine to CPU3
<4>[   97.858305] IRQ7 no longer affine to CPU3
<4>[   97.858311] IRQ8 no longer affine to CPU3
<4>[   97.858317] IRQ9 no longer affine to CPU3
<5>[   97.859469] CPU3: shutdown
<6>[   97.861096] CPU2:msm_cpu_pm_enter_sleep mode:3 during suspend
//正常休眠成功
//正常唤醒
<6>[   97.861313] Enabling non-boot CPUs ...
<6>[   97.861759] CPU3: Booted secondary processor
<6>[   97.862545] CPU3 is up
<6>[   97.863581] PM: noirq resume of devices complete after 1.016 msecs
<6>[   97.865331] PM: early resume of devices complete after 1.138 msecs
<6>[   97.947246] PM: resume of devices complete after 81.898 msecs
<6>[   97.995430] ===PM: suspend_devices_and_enter return 0

//有时候的log是这样的:
<6>[  113.772929] ===state_store,state = 3
<6>[  113.772947] ===pm_suspend,state = 3
<6>[  113.772967] ===PM: suspend entry 1970-01-01 00:54:45.106990988 UTC
[  113.824586] ===wakeup_source_activate(), ws->name = modem_IPCRTR
[  113.829615] ===wakeup_source_deactivate(), ws->name = modem_IPCRTR
<6>[  113.772979] ===PM: Syncing filesystems ... 
[  113.836149] ===wakeup_source_activate(), ws->name = ipc00000084_Binder:1974_1

<3>[  113.824586] ===wakeup_source_activate(), ws->name = mode
[  113.847456] ===wakeup_source_deactivate(), ws->name = ipc00000084_Binder:19741
[  113.852951] Freezing of tasks aborted after 0.004 seconds
m_IPCRTR
<3>[  113.829615] ===wakeup_source_deactivate(), ws->n[  113.866763] ===Error: returning -512 value
ame = modem_IPCRTR
<3>[  113.836149] ===wakeup_source_activate(), ws->name = ipc00000084_Binder:1974_1
<3>[  113.847456] ===wakeup_source_deactivate(), ws->name = ipc00000084_Binder:1974_1
<6>[  113.848195] done.
<6>[  113.848201] ===PM: Preparing system for mem sleep
<6>[  113.852842] Freezing user space processes ... 
<6>[  113.852843] ===PM: Wakeup pending, aborting suspend
<6>[  113.852919] last active wakeup source: ipc00000084_Binder:1974_1
<6>[  113.852943] 
<3>[  113.852951] Freezing of tasks aborted after 0.004 seconds
<6>[  113.860052] Restarting tasks ... done.
<6>[  113.860225] ===PM: suspend_prepare return -16
<6>[  113.860239] ===PM: suspend exit 1970-01-01 00:54:45.194264894 UTC
[  113.965998] ===Error: returning -512 value
//刚开始没睡下去
//再次休眠
[  114.009964] CPU3: shutdown
<6>[  113.961509] ===state_store,state = 3
<6>[  113.961527]  114.108368] healthd: battery l=62 v=3848 t=27.0 h=2 st=3 c=13 chg=
=pm_suspend,state = 3
<6>[  113.961547] ===PM: suspend entry 19[  114.119482] healthd: battery l=62 v=3846 t=27.0 h=2 st=3 c=13 chg=
70-01-01 00:54:45.295572290 UTC
<6>[  113.961558] ===PM: Syncing filesystems ... done.
<6>[  113.963923] ===PM: Preparing system for mem sleep
<6>[  113.964527] Freezing user space processes ... 
<3>[  113.965998] ===Error: returning -512 value
<12>[  114.119482] healthd: battery l=62 v=3846 t=27.0 h=2 st=3 c=13 chg=
[  114.215436] ===Error: returning -512 value
[  114.255245] migrate_irqs: 630 callbacks suppressed
[  114.255250] IRQ0 no longer affine to CPU3
[  114.255257] IRQ1 no longer affine to CPU3
[  114.255262] IRQ2 no longer affine to CPU3
[  114.255268] IRQ3 no longer affine to CPU3
[  114.255274] IRQ4 no longer affine to CPU3
[  114.255279] IRQ5 no longer affine to CPU3
[  114.255284] IRQ6 no longer affine to CPU3
[  114.255290] IRQ7 no longer affine to CPU3
[  114.255296] IRQ8 no longer affine to CPU3
[  114.255302] IRQ9 no longer affine to CPU3
[  114.256435] CPU3: shutdown
<6>[  114.209101] ===PM: Syncing filesystems ... done.
<6>[  114.213389] ===PM: Preparing system for mem sleep
<6>[  114.213993] Freezing user space processes ... 
<3>[  114.215436] ===Error: returning -512 value
//这里不知道睡下去了没有,log不知道是没打出来还是没睡下去,但是电流值已经是满足要求了,暂且认为是正常休眠了
//唤醒了
<6>[  114.259938] PM: noirq resume of devices complete after 1.166 msecs
<6>[  114.261686] PM: early resume of devices complete after 1.149 msecs
<6>[  114.340672] PM: resume of devices complete after 78.971 msecs
<6>[  114.389310] ===PM: suspend_devices_and_enter return 0

-------------------------------------------------------------
SPI 240P 屏幕suspend 过程:
t86:/ # cat proc/kmsg
[  195.054625] BUG: sleeping function called from invalid context at /home/whl/work/msm8909w_law_android/kernel/kernel/locking/mutex.c:97
[  195.065964] in_atomic(): 1, irqs_disabled(): 0, pid: 2043, name: android.bg
[  195.072874] Preemption disabled at:[<  (null)>]   (null)
<3>[  195.054625] BUG: sleeping function called from invalid context at /home/whl/work/msm8909w_law_android/kernel/kernel/locking/mutex.c:97
<3>[  195.065964] in_atomic(): 1, irqs_disabled(): 0, pid: 2043, name: android.bg
<3>[  195.072874] Preemption disabled at:[<  (null)>]   (null)
<6>[  195.078086] 
<6>[  195.078102] CPU: 2 PID: 2043 Comm: android.bg Not tainted 3.18.24 #20
<6>[  195.078148] [<c00147f0>] (unwind_backtrace) from [<c0011c34>] (show_stack+0x10/0x14)
<6>[  195.078172] [<c0011c34>] (show_stack) from [<c0948d74>] (dump_stack+0x6c/0xb8)
[  200.737128] mdss_spi_panel_event_handler: MDSS_EVENT_BLANK
[  200.760478] mdss_spi_panel_event_handler: MDSS_EVENT_PANEL_OFF
<3>[  200.737128] mdss_spi_panel_event_handler: MDSS_EVENT_BLANK
<3>[  200.760478] mdss_spi_panel_event_handler: MDSS_EVENT_PANEL_OFF
<6>[  201.074644] ===state_store,state = 3
<6>[  201.074663] ===pm_suspend,state = 3
<6>[  201.074682] ===PM: suspend entry 1970-01-01 00:24:05.337336245 UTC
[  201.092553] ===wakeup_source_activate(), ws->name = NETLINK
[  201.098961] ===wakeup_source_activate(), ws->name = eventpoll
<6>[  201.074694] ===PM: Syncing filesystems ... done.
<6>[  20[  201.104656] ===wakeup_source_deactivate(), ws->name = NETLINK
[  201.111697] Freezing of tasks aborted after 0.002 seconds
[  201.113765] ===Error: returning -512 value
1.091252] ===PM: Preparing system for mem sleep
<3>[  201.092553] ===wakeup_source_activate(), ws->name = NETLINK
<3>[  201.098961] ===wakeup_source_activate(), ws->name = eventpoll
<6>[  201.111599] Freezing user space processes ... 
<6>[  201.111601] ===PM: Wakeup pending, aborting suspend
<6>[  201.111649] ===active wakeup source: eventpoll//休眠失败,被终止
<6>[  201.111687] 
<3>[  201.111697] Freezing of tasks aborted after 0.002 seconds
<6>[  201.113764] Restarting tasks ... 
<3>[  201.113765] ===Error: returning -512 value
<6>[  201.116006] done.
<6>[  201.116120] ===PM: suspend_prepare return -16
<6>[  201.116135] ===PM: suspend exit 1970-01-01 00:24:05.378789370 UTC
//再次休眠
<6>[  201.217760] ===state_store,state = 3
<6>[  201.217778] ===pm_suspend,state = 3
<6>[  201.217797] ===PM: suspend entry 1970-01-01 00:24:05.480451714 UTC
[  201.243596] ===Error: returning -512 value
[  201.287292] migrate_irqs: 310 callbacks suppressed
[  201.287297] IRQ0 no longer affine to CPU3
[  201.287304] IRQ1 no longer affine to CPU3
[  201.287310] IRQ2 no longer affine to CPU3
[  201.287316] IRQ3 no longer affine to CPU3
[  201.287321] IRQ4 no longer affine to CPU3
[  201.287328] IRQ5 no longer affine to CPU3
[  201.287333] IRQ6 no longer affine to CPU3
[  201.287339] IRQ7 no longer affine to CPU3
[  201.287345] IRQ8 no longer affine to CPU3
[  201.287351] IRQ9 no longer affine to CPU3
[  201.288477] CPU3: shutdown
<6>[  201.217809] ===PM: Syncing filesystems ... done.
<6>[  201.241689] ===PM: Preparing system for mem sleep
<6>[  201.24229[  201.428326] healthd: battery l=42 v=3786 t=37.0 h=2 st=3 c=18 chg=
4] Freezing user space processes ... 
<3>[  201.243596] ===Error: returning -512 value
<6>[  201.250110] (elapsed 0.007 seconds) done.
<6>[  201.250135] Freezing remaining freezable tasks ... (elapsed 0.002 seconds) done.
<6>[  201.252905] ===PM: suspend_prepare return 0
<6>[  201.252918] ===PM: Entering mem sleep
<6>[  201.252929] Suspending console(s) (use no_console_suspend to debug)
<6>[  201.281101] PM: suspend of devices complete after 26.818 msecs
<6>[  201.283135] PM: late suspend of devices complete after 2.022 msecs
<6>[  201.286540] PM: noirq suspend of devices complete after 3.390 msecs
<6>[  201.286556] Disabling non-boot CPUs ...
//至此挂起成功了
<4>[  201.287292] migrate_irqs: 310 callbacks suppressed
<4>[  201.287297] IRQ0 no longer affine to CPU3
<4>[  201.287304] IRQ1 no longer affine to CPU3
<4>[  201.287310] IRQ2 no longer affine to CPU3
<4>[  201.287316] IRQ3 no longer affine to CPU3
<4>[  201.287321] IRQ4 no longer affine to CPU3
<4>[  201.287328] IRQ5 no longer affine to CPU3
<4>[  201.287333] IRQ6 no longer affine to CPU3
<4>[  201.287339] IRQ7 no longer affine to CPU3
<4>[  201.287345] IRQ8 no longer affine to CPU3
<4>[  201.287351] IRQ9 no longer affine to CPU3
<5>[  201.288477] CPU3: shutdown
<6>[  201.289925] CPU2:msm_cpu_pm_enter_sleep mode:3 during suspend
//按POWER按键唤醒
<6>[  201.290263] Enabling non-boot CPUs ...
<6>[  201.290705] CPU3: Booted secondary processor
<6>[  201.291468] CPU3 is up
<6>[  201.292519] PM: noirq resume of devices complete after 1.024 msecs
<6>[  201.294300] PM: early resume of devices complete after 1.126 msecs
<6>[  201.367715] PM: resume of devices complete after 73.397 msecs
<6>[  201.415807] ===PM: suspend_devices_and_enter return 0
<6>[  201.486073] ctrl_pdata->rst_gpio = 25,ctrl_pdata->disp_dc_gpio = 23//屏幕复位

//有时候的log是这样的
[  388.085659] mdss_spi_panel_event_handler: MDSS_EVENT_BLANK
[  388.111414] mdss_spi_panel_event_handler: MDSS_EVENT_PANEL_OFF
<3>[  388.085659] mdss_spi_panel_event_handler: MDSS_EVENT_BLANK
<3>[  388.111414] mdss_spi_panel_event_handler: MDSS_EVENT_PANEL_OFF
<6>[  388.426952] ===state_store,state = 3
<6>[  388.426970] ===pm_suspend,state = 3
<6>[  388.426989] ===PM: suspend entry 1970-01-01 00:27:23.126746647 UTC
[  388.450149] ===wakeup_source_activate(), ws->name = NETLINK
[  388.454733] ===wakeup_source_activate(), ws->name = eventpoll
<3>[  388.454733] ===wakeup_source_activate(), ws->name = eventp[  388.460687] ===wakeup_source_deactivate(), ws->name = NETLINK
[  388.467401] Freezing of tasks aborted after 0.002 seconds
[  388.469106] ===Error: returning -512 value
oll
<3>[  388.460687] ===wakeup_source_deactivate(), ws->name = NETLINK
<6>[  388.467300] Freezing user space processes ... 
<6>[  388.467301] ===PM: Wakeup pending, aborting suspend
<6>[  388.467350] ===active wakeup source: eventpoll
<6>[  388.467392] 
<3>[  388.467401] Freezing of tasks aborted after 0.002 seconds
<6>[  388.469105] Restarting tasks ... 
<3>[  388.469106] ===Error: returning -512 value
<6>[  388.481344] done.
<6>[  388.481553] ===PM: suspend_prepare return -16
<6>[  388.481576] ===PM: suspend exit 1970-01-01 00:27:23.181333105 UTC//休眠失败了
[  388.590301] ===Error: returning -512 value
[  388.631445] migrate_irqs: 310 callbacks suppressed
[  388.631451] IRQ0 no longer affine to CPU3
[  388.631457] IRQ1 no longer affine to CPU3
[  388.631463] IRQ2 no longer affine to CPU3
[  388.631469] IRQ3 no longer affine to CPU3
[  388.631474] IRQ4 no longer affine to CPU3
[  388.631481] IRQ5 no longer affine to CPU3
[  388.631486] IRQ6 no longer affine to CPU3
[  388.631492] IRQ7 no longer affine to CPU3
[  388.631497] IRQ8 no longer affine to CPU3
[  388.631504] IRQ9 no longer affine to CPU3
[  388.632646] CPU3: shutdown
//再次休眠
<6>[  388.582090] ===state_store,state = 3
<6>[  388.582108] ===pm_suspend,state = 3
<6>[  388.582127] =[  388.771733] healthd: battery l=41 v=3788 t=33.0 h=2 st=3 c=22 chg=
==PM: suspend entry 1970-01-01 00:27:23.281884199 UTC
<6>[  388.582138] ===PM: Syncing filesystems ... done.
<6>[  388.586276] ===PM: Preparing system for mem sleep
<6>[  388.586868] Freezing user space processes ... 
<3>[  388.590301] ===Error: returning -512 value
<6>[  388.599558] (elapsed 0.012 seconds) done.
<6>[  388.599586] Freezing remaining freezable tasks ... (elapsed 0.002 seconds) done.
<6>[  388.602440] ===PM: suspend_prepare return 0
<6>[  388.602452] ===PM: Entering mem sleep
<6>[  388.602463] Suspending console(s) (use no_console_suspend to debug)
<6>[  388.625211] PM: suspend of devices complete after 21.392 msecs
<6>[  388.627250] PM: late suspend of devices complete after 2.025 msecs
<6>[  388.630815] PM: noirq suspend of devices complete after 3.548 msecs
<6>[  388.630833] Disabling non-boot CPUs ...
//正常suspend了
<4>[  388.631445] migrate_irqs: 310 callbacks suppressed
<4>[  388.631451] IRQ0 no longer affine to CPU3
<4>[  388.631457] IRQ1 no longer affine to CPU3
<4>[  388.631463] IRQ2 no longer affine to CPU3
<4>[  388.631469] IRQ3 no longer affine to CPU3
<4>[  388.631474] IRQ4 no longer affine to CPU3
<4>[  388.631481] IRQ5 no longer affine to CPU3
<4>[  388.631486] IRQ6 no longer affine to CPU3
<4>[  388.631492] IRQ7 no longer affine to CPU3
<4>[  388.631497] IRQ8 no longer affine to CPU3
<4>[  388.631504] IRQ9 no longer affine to CPU3
<5>[  388.632646] CPU3: shutdown
<6>[  388.634094] CPU2:msm_cpu_pm_enter_sleep mode:3 during suspend
//POWER按键唤醒了
<6>[  388.634309] Enabling non-boot CPUs ...
<6>[  388.634754] CPU3: Booted secondary processor
<6>[  388.635531] CPU3 is up
<6>[  388.636581] PM: noirq resume of devices complete after 1.022 msecs
<6>[  388.638350] PM: early resume of devices complete after 1.126 msecs
<6>[  388.713135] PM: resume of devices complete after 74.767 msecs
<6>[  388.761268] ===PM: suspend_devices_and_enter return 0
<6>[  388.761279] Restarting tasks ... done.
<6>[  388.769017] ===PM: suspend exit 1970-01-01 00:27:39.078235547 UTC
<12>[  388.771733] healthd: battery l=41 v=3788 t=33.0 h=2 st=3 c=22 chg=
<6>[  388.845212] ctrl_pdata->rst_gpio = 25,ctrl_pdata->disp_dc_gpio = 23

//有时候的log是这样:
[  660.012739] BUG: sleeping function called from invalid context at /home/whl/work/msm8909w_law_android/kernel/kernel/locking/mutex.c:97
[  660.024107] in_atomic(): 1, irqs_disabled(): 0, pid: 2043, name: android.bg
[  660.031016] Preemption disabled at:[<  (null)>]   (null)
<3>[  660.012739] BUG: sleeping function called from invalid context at /home/whl/work/msm8909w_law_android/kernel/kernel/locking/mutex.c:97
<3>[  660.024107] in_atomic(): 1, irqs_disabled(): 0, pid: 2043, name: android.bg
<3>[  660.031016] Preemption disabled at:[<  (null)>]   (null)
<6>[  660.036201] 
<6>[  660.036220] CPU: 2 PID: 2043 Comm: android.bg Not tainted 3.18.24 #20
<6>[  660.036256] [<c00147f0>] (unwind_backtrace) from [<c0011c34>] (show_stack+0x10/0x14)
<6>[  660.036281] [<c0011c34>] (show_stack) from [<c0948d74>] (dump_stack+0x6c/0xb8)
<6>[  660.036301] [<c0948d74>] (dump_stack) from [<c0950dac>] (mutex_lock+0x18/0x3c)
<6>[  660.036323] [<c0950dac>] (mutex_lock) from [<c03bbe44>] (kgsl_get_egl_counts+0x24/0x98)
<6>[  660.036346] [<c03bbe44>] (kgsl_get_egl_counts) from [<c03d05e4>] (print_mem_entry+0x128/0x224)
<6>[  660.036367] [<c03d05e4>] (print_mem_entry) from [<c026cf90>] (idr_for_each+0xac/0xd4)
<6>[  660.036387] [<c026cf90>] (idr_for_each) from [<c03d0764>] (process_mem_print+0x84/0xcc)
<6>[  660.036410] [<c03d0764>] (process_mem_print) from [<c01466cc>] (seq_read+0x1a8/0x400)
<6>[  660.036432] [<c01466cc>] (seq_read) from [<c0128f28>] (vfs_read+0x90/0x124)
<6>[  660.036450] [<c0128f28>] (vfs_read) from [<c0129468>] (SyS_read+0x40/0x80)
<6>[  660.036470] [<c0129468>] (SyS_read) from [<c000e060>] (ret_fast_syscall+0x0/0x38)
[  660.101324] mdss_spi_panel_event_handler: MDSS_EVENT_BLANK
[  660.130359] mdss_spi_panel_event_handler: MDSS_EVENT_PANEL_OFF
[  660.403810] ===wakeup_source_activate(), ws->name = PowerManagerService.Broadcasts
<3>[  660.101324] mdss_spi_panel_event_handler: MDSS_EVENT_BLANK
<3>[  660.130359] mdss_spi_panel_event_handler: MDSS_EVENT_PANEL_OFF
<6>[  660.403294] ===state_store,state = 3
<6>[  660.403311] ===pm_suspend,state = 3
<6>[  660.403329] ===PM: suspend entry 1970-01-01 00:32:18.604926534 UTC
<6>[  660.403341] ===PM: Syncing filesystems ... 
<3>[  660.403810] ===wakeup_source_a[  660.439197] ===wakeup_source_activate(), ws->name = NETLINK
ctivate(), ws->name = PowerManagerService.Broadcasts
[  660.449994] ===wakeup_source_activate(), ws->name = eventpoll
[  660.459654] ===wakeup_source_deactivate(), ws->name = NETLINK
<6>[  660.437900] done.
<6>[  660.437922] ===PM: Preparing syst[  660.466390] ===wakeup_source_deactivate(), ws->name = PowerManagerService.Broadcasts
[  660.472932] Freezing of tasks aborted after 0.002 seconds
[  660.474160] ===Error: returning -512 value
em for mem sleep
<3>[  660.439197] ===wakeup_source_activate(), ws->name = NETLINK
<3>[  660.449994] ===wakeup_source_activate(), ws->name = eventpoll
<6>[  660.472836] Freezing user space processes ... 
<6>[  660.472837] ===PM: Wakeup pending, aborting suspend
<6>[  660.472884] ===active wakeup source: eventpoll
<6>[  660.472924] 
<3>[  660.472932] Freezing of tasks aborted after 0.002 seconds
<6>[  660.474159] Restarting tasks ... 
<3>[  660.474160] ===Error: returning -512 value
<6>[  660.474289] done.
<6>[  660.474450] ===PM: suspend_prepare return -16
<6>[  660.474464] ===PM: suspend exit 1970-01-01 00:32:18.676061065 UTC//休眠失败
[  660.582369] ===Error: returning -512 value
[  660.620211] migrate_irqs: 310 callbacks suppressed
[  660.620217] IRQ0 no longer affine to CPU3
[  660.620223] IRQ1 no longer affine to CPU3
[  660.620229] IRQ2 no longer affine to CPU3
[  660.620235] IRQ3 no longer affine to CPU3
[  660.620241] IRQ4 no longer affine to CPU3
[  660.620246] IRQ5 no longer affine to CPU3
[  660.620253] IRQ6 no longer affine to CPU3
[  660.620258] IRQ7 no longer affine to CPU3
[  660.620264] IRQ8 no longer affine to CPU3
[  660.620270] IRQ9 no longer affine to CPU3
[  660.621415] CPU3: shutdown
<6>[  660.575870] ===state_store,state =   660.760744] healthd: battery l=39 v=3788 t=34.0 h=2 st=3 c=22 chg=

<6>[  660.575888] ===pm_suspend,state = 3//再次休眠
<6>[  660.575907] ===PM: suspend entry 1970-01-01 00:32:18.777503617 UTC
<6>[  660.575919] ===PM: Syncing filesystems ... done.
<6>[  660.578345] ===PM: Preparing system for mem sleep
<6>[  660.578953] Freezing user space processes ... 
<3>[  660.582369] ===Error: returning -512 value
<6>[  660.587419] (elapsed 0.008 seconds) done.
<6>[  660.587445] Freezing remaining freezable tasks ... (elapsed 0.002 seconds) done.
<6>[  660.590297] ===PM: suspend_prepare return 0
<6>[  660.590310] ===PM: Entering mem sleep
<6>[  660.590321] Suspending console(s) (use no_console_suspend to debug)
<6>[  660.613996] PM: suspend of devices complete after 22.325 msecs
<6>[  660.616035] PM: late suspend of devices complete after 2.025 msecs
<6>[  660.619435] PM: noirq suspend of devices complete after 3.386 msecs
<6>[  660.619453] Disabling non-boot CPUs ...
//休眠成功
<4>[  660.620211] migrate_irqs: 310 callbacks suppressed
<4>[  660.620217] IRQ0 no longer affine to CPU3
<4>[  660.620223] IRQ1 no longer affine to CPU3
<4>[  660.620229] IRQ2 no longer affine to CPU3
<4>[  660.620235] IRQ3 no longer affine to CPU3
<4>[  660.620241] IRQ4 no longer affine to CPU3
<4>[  660.620246] IRQ5 no longer affine to CPU3
<4>[  660.620253] IRQ6 no longer affine to CPU3
<4>[  660.620258] IRQ7 no longer affine to CPU3
<4>[  660.620264] IRQ8 no longer affine to CPU3
<4>[  660.620270] IRQ9 no longer affine to CPU3
<5>[  660.621415] CPU3: shutdown
<6>[  660.622703] CPU2:msm_cpu_pm_enter_sleep mode:3 during suspend
//POWER按键唤醒
<6>[  660.622923] Enabling non-boot CPUs ...
<6>[  660.623366] CPU3: Booted secondary processor
<6>[  660.624144] CPU3 is up
<6>[  660.625197] PM: noirq resume of devices complete after 1.026 msecs
<6>[  660.626962] PM: early resume of devices complete after 1.127 msecs
<6>[  660.705031] PM: resume of devices complete after 78.051 msecs
<6>[  660.753109] ===PM: suspend_devices_and_enter return 0
<6>[  660.753120] Restarting tasks ... done.
<6>[  660.759976] ===PM: suspend exit 1970-01-01 00:32:29.074370331 UTC
<12>[  660.760744] healthd: battery l=39 v=3788 t=34.0 h=2 st=3 c=22 chg=
<6>[  660.841382] ctrl_pdata->rst_gpio = 25,ctrl_pdata->disp_dc_gpio = 23

说明不管是MIPI屏幕还是SPI屏幕,其实串口log都是正常打印的,有执行正常的suspend流程,
虽然SPI屏幕不能一下子就休眠成功,但是最终也是有正常休眠下去
----------------------------------------------------------------------------
高通给出了以下方法查看系统信息:
1) cat /sys/kernel/debug/rpm_master_stats
2) cat /sys/kernel/debug/rpm_stats 
SPI屏幕,执行几次休眠操作之后,执行结果如下:
1.MSM8909W手表:/ # cat sys/kernel/debug/rpm_master_stats
APSS
shutdown_req:0x27D7B5FF2
wakeup_ind:0x27D7C642E
bringup_req:0x27D7C64CA
bringup_ack:0x27D7C651A
last_sleep_transition_duration:0x2694
last_wake_transition_duration:0x4cd
wakeup_reason:0x1
numshutdowns:0x191d
active_cores:0x1//说明休眠的时候,AP侧在活动,
core0
MPSS
shutdown_req:0x27D790F10
wakeup_ind:0x27D78B0AA
bringup_req:0x27D78B188
bringup_ack:0x27D78B1D8
last_sleep_transition_duration:0x3550
last_wake_transition_duration:0x4057
wakeup_reason:0x0
numshutdowns:0x3faa
active_cores:0x0//说明休眠的时候,Modem已经不在激活状态,已经睡下去了
PRONTO
shutdown_req:0x41FEF1B7
wakeup_ind:0x22A54001
bringup_req:0x41FDB9A8
bringup_ack:0x41FDDD94
last_sleep_transition_duration:0x1aa5
last_wake_transition_duration:0x1f74
wakeup_reason:0x0
numshutdowns:0x8
active_cores:0x0//说明休眠的时候,wlan已经不在激活状态,已经睡下去了

2.
130|MSM8909W手表:/ # cat /sys/kernel/debug/rpm_stats
RPM Mode:vlow
count:0//说明一次vlow的计数都没有
time in last mode(msec):0
time since last mode(sec):605
actual last sleep(msec):0
client votes: 0x03010301

RPM Mode:vmin
count:0//说明一次vmin的计数都没有,说明一次进入低功耗休眠都没有
time in last mode(msec):0
time since last mode(sec):605
actual last sleep(msec):0
client votes: 0x00000000

MIPI屏的结果如下:
MSM8909W手表:/ # cat sys/kernel/debug/rpm_stats
RPM Mode:vlow
count:0
time in last mode(msec):0
time since last mode(sec):510
actual last sleep(msec):0
client votes: 0x03010301

RPM Mode:vmin
count:13//说明确实有几次进入了低功耗模式
time in last mode(msec):2000
time since last mode(sec):2
actual last sleep(msec):25000
client votes: 0x00000000

由此可以确认SPI屏幕虽然有走完suspend的流程,但是系统其实并没有真正进入低功耗模式。
-----------------------------------------------------------------
高通再次提供几个log开关,执行以下几个开关
1) echo 9 > /sys/module/mpm_of/parameters/debug_mask //这条log太多,而且参考意义不大
我们查看下面三个开关的log
2) echo 1 > /sys/module/msm_show_resume_irq/parameters/debug_mask
3) echo 0 >/sys/module/qpnp_rtc/parameters/poweron_alarm
4) echo 1 > /sys/kernel/debug/clk/debug_suspend

//按POWER按键休眠,一会儿后再按POWER按键唤醒
//后抓取SPI suspend的log:

[  264.990537] mdss_spi_panel_event_handler: MDSS_EVENT_BLANK
[  265.021330] mdss_spi_panel_event_handler: MDSS_EVENT_PANEL_OFF
<3>[  264.990537] mdss_spi_panel_event_handler: MDSS_EVENT_BLANK
<3>[  265.021330] mdss_spi_panel_event_handler: MDSS_EVENT_PANEL_OFF
<6>[  265.327869] ===state_store,state = 3
<6>[  265.327887] ===pm_suspend,state = 3
<6>[  265.327905] ===PM: suspend entry 1970-01-01 01:19:57.968042290 UTC
[  265.357053] ===Error: returning -512 value
[  265.400397] migrate_irqs: 310 callbacks suppressed
[  265.400403] IRQ0 no longer affine to CPU3
[  265.400409] IRQ1 no longer affine to CPU3
[  265.400415] IRQ2 no longer affine to CPU3
[  265.400421] IRQ3 no longer affine to CPU3
[  265.400426] IRQ4 no longer affine to CPU3
[  265.400432] IRQ5 no longer affine to CPU3
[  265.400438] IRQ6 no longer affine to CPU3
[  265.400443] IRQ7 no longer affine to CPU3
[  265.400450] IRQ8 no longer affine to CPU3
[  265.400455] IRQ9 no longer affine to CPU3
[  265.401558] CPU3: shutdown
[  265.402823] __qpnpint_handle_irq: 43 triggered [0x0, 0x08,0x0] qpnp_kpdpwr_status
[  265.402823] gic_show_resume_irq: 200 triggered qcom,smd-rpm
[  265.402823] gic_show_resume_irq: 222 triggered 200f000.qcom,spmi
<6>[  265.327917] ===PM: Syncing filesystems ... done.
<6>[  265.353215] ===PM: Preparing system for mem sleep
<6>[  265.353812] Freezing user space processes ... 
<3>[  265.357053] ===Error: returning -512 value
<6>[  265.360946] (elapsed 0.007 seconds) done.
<6>[  265.360970] Freezing remaining freezable tasks ... (elapsed 0.002 seconds) done.
<6>[  265.363531] ===PM: suspend_prepare return 0
<6>[  265.363544] ===PM: Entering mem sleep
<6>[  265.363555] Suspending console(s) (use no_console_suspend to debug)
<6>[  265.394219] PM: suspend of devices complete after 29.329 msecs
<6>[  265.396241] PM: late suspend of devices complete after 2.008 msecs
<6>[  265.399617] PM: noirq suspend of devices complete after 3.361 msecs
<6>[  265.399635] Disabling non-boot CPUs ...
<4>[  265.400397] migrate_irqs: 310 callbacks suppressed
<4>[  265.400403] IRQ0 no longer affine to CPU3
<4>[  265.400409] IRQ1 no longer affine to CPU3
<4>[  265.400415] IRQ2 no longer affine to CPU3
<4>[  265.400421] IRQ3 no longer affine to CPU3
<4>[  265.400426] IRQ4 no longer affine to CPU3
<4>[  265.400432] IRQ5 no longer affine to CPU3
<4>[  265.400438] IRQ6 no longer affine to CPU3
<4>[  265.400443] IRQ7 no longer affine to CPU3
<4>[  265.400450] IRQ8 no longer affine to CPU3
<4>[  265.400455] IRQ9 no longer affine to CPU3
<5>[  265.401558] CPU3: shutdown
<6>[  265.402823] Enabled clocks:
<6>[  265.402823]       xo_clk_src:1:1 [19200000]
<6>[  265.402823]       xo_a_clk_src:2:2 [19200000]
<6>[  265.402823]       pcnoc_a_clk:1:1 [19200000]
<6>[  265.402823]       bimc_clk:1:1 [95944704]
<6>[  265.402823]       bimc_msmbus_clk:1:1 [95944704] -> bimc_clk:1:1 [95944704]
<6>[  265.402823]       bimc_a_clk:1:1 [383909888]
<6>[  265.402823]       bimc_msmbus_a_clk:1:1 [383909888] -> bimc_a_clk:1:1 [383909888]
<6>[  265.402823]       pcnoc_keepalive_a_clk:1:1 [19200000] -> pcnoc_a_clk:1:1 [19200000]
<6>[  265.402823]       qdss_clk:5:5 [1000]
<6>[  265.402823]       xo_clk_src:2:2 [19200000] -> xo_clk_src:1:1 [19200000]
<6>[  265.402823]       gpll0_clk_src:1:1 [800000000] -> xo_clk_src:2:2 [19200000] -> xo_clk_src:1:1 [19200000]
<6>[  265.402823]       xo_a_clk_src:2:2 [19200000] -> xo_a_clk_src:2:2 [19200000]
<6>[  265.402823]       gpll0_ao_clk_src:1:1 [800000000] -> xo_a_clk_src:2:2 [19200000] -> xo_a_clk_src:2:2 [19200000]
<6>[  265.402823]       apss_ahb_clk_src:1:1 [19200000] -> xo_a_clk_src:2:2 [19200000] -> xo_a_clk_src:2:2 [19200000]
<6>[  265.402823]       mdp_clk_src:2:2 [160000000, 1] -> gpll0_clk_src:1:1 [800000000] -> xo_clk_src:2:2 [19200000] -> xo_clk_src:1:1 [192000]
<6>[  265.402823]       vsync_clk_src:1:1 [19200000, 1] -> xo_clk_src:2:2 [19200000] -> xo_clk_src:1:1 [19200000]
<6>[  265.402823]       gcc_boot_rom_ahb_clk:1:1 [0]
<6>[  265.402823]       gcc_apss_tcu_clk:1:0 [0]
<6>[  265.402823]       gcc_gfx_tcu_clk:1:0 [0]
<6>[  265.402823]       gcc_smmu_cfg_clk:2:0 [0]
<6>[  265.402823]       gcc_mdss_ahb_clk:1:1 [0]
<6>[  265.402823]       gcc_mdss_axi_clk:1:1 [0]
<6>[  265.402823]       gcc_mdss_mdp_clk:1:1 [0] -> mdp_clk_src:2:2 [160000000, 1] -> gpll0_clk_src:1:1 [800000000] -> xo_clk_src:2:2 [1920000]
<6>[  265.402823]       gcc_mdss_vsync_clk:1:1 [0] -> vsync_clk_src:1:1 [19200000, 1] -> xo_clk_src:2:2 [19200000] -> xo_clk_src:1:1 [19200000]
<6>[  265.402823]       gcc_mss_cfg_ahb_clk:1:1 [0]
<6>[  265.402823]       gcc_mss_q6_bimc_axi_clk:1:1 [0]
<6>[  265.402823]       gcc_usb2a_phy_sleep_clk:1:1 [0]
<6>[  265.402823]       a7ssmux:1:1 [800000000, 1] -> gpll0_ao_clk_src:1:1 [800000000] -> xo_a_clk_src:2:2 [19200000] -> xo_a_clk_src:2:2 [192]
<6>[  265.402823] Enabled clock count: 28
<6>[  265.402823] CPU1:msm_cpu_pm_enter_sleep mode:3 during suspend//正常休眠
<4>[  265.402823] __qpnpint_handle_irq: 43 triggered [0x0, 0x08,0x0] qpnp_kpdpwr_status
<4>[  265.402823] gic_show_resume_irq: 200 triggered qcom,smd-rpm
<4>[  265.402823] gic_show_resume_irq: 222 triggered 200f000.qcom,spmi
<6>[  265.403036] Enabling non-boot CPUs ...
<6>[  265.403478] CPU3: Booted secondary processor
<6>[  265.404268] CPU3 is up
<6>[  265.405309] PM: noirq resume of devices complete after 1.013 msecs
<6>[  265.407061] PM: early resume of devices complete after 1.120 msecs
<6>[  265.484078] PM: resume of devices complete after 76.994 msecs
<6>[  265.551232] ===PM: suspend_devices_and_enter return 0
<6>[  265.627343] ctrl_pdata->rst_gpio = 25,ctrl_pdata->disp_dc_gpio = 23

//另外一次的log:
[  294.738757] mdss_spi_panel_event_handler: MDSS_EVENT_BLANK
[  294.759936] mdss_spi_panel_event_handler: MDSS_EVENT_PANEL_OFF
<3>[  294.738757] mdss_spi_panel_event_handler: MDSS_EVENT_BLANK
<3>[  294.759936] mdss_spi_panel_event_handler: MDSS_EVENT_PANEL_OFF
<6>[  295.067956] ===state_store,state = 3
<6>[  295.067975] ===pm_suspend,state = 3
<6>[  295.067993] ===PM: suspend entry 1970-01-01 01:22:27.166584151 UTC
[  295.104113] ===Error: returning -512 value
[  295.151592] migrate_irqs: 950 callbacks suppressed
[  295.151598] IRQ0 no longer affine to CPU3
[  295.151603] IRQ1 no longer affine to CPU3
[  295.151610] IRQ2 no longer affine to CPU3
[  295.151616] IRQ3 no longer affine to CPU3
[  295.151622] IRQ4 no longer affine to CPU3
[  295.151627] IRQ5 no longer affine to CPU3
[  295.151633] IRQ6 no longer affine to CPU3
[  295.151638] IRQ7 no longer affine to CPU3
[  295.151645] IRQ8 no longer affine to CPU3
[  295.151650] IRQ9 no longer affine to CPU3
[  295.152756] CPU3: shutdown
[  295.154066] __qpnpint_handle_irq: 43 triggered [0x0, 0x08,0x0] qpnp_kpdpwr_status
[  295.154066] gic_show_resume_irq: 200 triggered qcom,smd-rpm
[  295.154066] gic_show_resume_irq: 222 triggered 200f000.qcom,spmi
<6>[  295.068005] ===PM: Syncing filesystems ... done.
<6>[  295.101672] ===PM: Preparing system for mem sleep
<6>[  295.102275] Freezing user space processes ... 
<3>[  295.104113] ===Error: returning -512 value
<6>[  295.110054] (elapsed 0.007 seconds) done.
<6>[  295.110080] Freezing remaining freezable tasks ... (elapsed 0.002 seconds) done.
<6>[  295.112824] ===PM: suspend_prepare return 0
<6>[  295.112836] ===PM: Entering mem sleep
<6>[  295.112848] Suspending console(s) (use no_console_suspend to debug)
<6>[  295.145565] PM: suspend of devices complete after 31.384 msecs
<6>[  295.147593] PM: late suspend of devices complete after 2.014 msecs
<6>[  295.150976] PM: noirq suspend of devices complete after 3.368 msecs
<6>[  295.150993] Disabling non-boot CPUs ...
<4>[  295.151592] migrate_irqs: 950 callbacks suppressed
<4>[  295.151598] IRQ0 no longer affine to CPU3
<4>[  295.151603] IRQ1 no longer affine to CPU3
<4>[  295.151610] IRQ2 no longer affine to CPU3
<4>[  295.151616] IRQ3 no longer affine to CPU3
<4>[  295.151622] IRQ4 no longer affine to CPU3
<4>[  295.151627] IRQ5 no longer affine to CPU3
<4>[  295.151633] IRQ6 no longer affine to CPU3
<4>[  295.151638] IRQ7 no longer affine to CPU3
<4>[  295.151645] IRQ8 no longer affine to CPU3
<4>[  295.151650] IRQ9 no longer affine to CPU3
<5>[  295.152756] CPU3: shutdown
<6>[  295.154066] Enabled clocks:
<6>[  295.154066]       xo_clk_src:1:1 [19200000]
<6>[  295.154066]       xo_a_clk_src:2:2 [19200000]
<6>[  295.154066]       pcnoc_a_clk:1:1 [19200000]
<6>[  295.154066]       bimc_clk:1:1 [95944704]
<6>[  295.154066]       bimc_msmbus_clk:1:1 [95944704] -> bimc_clk:1:1 [95944704]
<6>[  295.154066]       bimc_a_clk:1:1 [383909888]
<6>[  295.154066]       bimc_msmbus_a_clk:1:1 [383909888] -> bimc_a_clk:1:1 [383909888]
<6>[  295.154066]       pcnoc_keepalive_a_clk:1:1 [19200000] -> pcnoc_a_clk:1:1 [19200000]
<6>[  295.154066]       qdss_clk:5:5 [1000]
<6>[  295.154066]       xo_clk_src:2:2 [19200000] -> xo_clk_src:1:1 [19200000]
<6>[  295.154066]       gpll0_clk_src:1:1 [800000000] -> xo_clk_src:2:2 [19200000] -> xo_clk_src:1:1 [19200000]
<6>[  295.154066]       xo_a_clk_src:2:2 [19200000] -> xo_a_clk_src:2:2 [19200000]
<6>[  295.154066]       gpll0_ao_clk_src:1:1 [800000000] -> xo_a_clk_src:2:2 [19200000] -> xo_a_clk_src:2:2 [19200000]
<6>[  295.154066]       apss_ahb_clk_src:1:1 [19200000] -> xo_a_clk_src:2:2 [19200000] -> xo_a_clk_src:2:2 [19200000]
<6>[  295.154066]       mdp_clk_src:2:2 [160000000, 1] -> gpll0_clk_src:1:1 [800000000] -> xo_clk_src:2:2 [19200000] -> xo_clk_src:1:1 [192000]
<6>[  295.154066]       vsync_clk_src:1:1 [19200000, 1] -> xo_clk_src:2:2 [19200000] -> xo_clk_src:1:1 [19200000]
<6>[  295.154066]       gcc_boot_rom_ahb_clk:1:1 [0]
<6>[  295.154066]       gcc_apss_tcu_clk:1:0 [0]
<6>[  295.154066]       gcc_gfx_tcu_clk:1:0 [0]
<6>[  295.154066]       gcc_smmu_cfg_clk:2:0 [0]
<6>[  295.154066]       gcc_mdss_ahb_clk:1:1 [0]
<6>[  295.154066]       gcc_mdss_axi_clk:1:1 [0]
<6>[  295.154066]       gcc_mdss_mdp_clk:1:1 [0] -> mdp_clk_src:2:2 [160000000, 1] -> gpll0_clk_src:1:1 [800000000] -> xo_clk_src:2:2 [1920000]
<6>[  295.154066]       gcc_mdss_vsync_clk:1:1 [0] -> vsync_clk_src:1:1 [19200000, 1] -> xo_clk_src:2:2 [19200000] -> xo_clk_src:1:1 [19200000]
<6>[  295.154066]       gcc_mss_cfg_ahb_clk:1:1 [0]
<6>[  295.154066]       gcc_mss_q6_bimc_axi_clk:1:1 [0]
<6>[  295.154066]       gcc_usb2a_phy_sleep_clk:1:1 [0]
<6>[  295.154066]       a7ssmux:1:1 [800000000, 1] -> gpll0_ao_clk_src:1:1 [800000000] -> xo_a_clk_src:2:2 [19200000] -> xo_a_clk_src:2:2 [192]
<6>[  295.154066] Enabled clock count: 28
<6>[  295.154066] CPU1:msm_cpu_pm_enter_sleep mode:3 during suspend//正常休眠
<4>[  295.154066] __qpnpint_handle_irq: 43 triggered [0x0, 0x08,0x0] qpnp_kpdpwr_status
<4>[  295.154066] gic_show_resume_irq: 200 triggered qcom,smd-rpm
<4>[  295.154066] gic_show_resume_irq: 222 triggered 200f000.qcom,spmi
<6>[  295.154275] Enabling non-boot CPUs ...
<6>[  295.154716] CPU3: Booted secondary processor
<6>[  295.155511] CPU3 is up
<6>[  295.156551] PM: noirq resume of devices complete after 1.012 msecs
<6>[  295.158328] PM: early resume of devices complete after 1.125 msecs
<6>[  295.233722] PM: resume of devices complete after 75.378 msecs
<6>[  295.301148] ===PM: suspend_devices_and_enter return 0
<6>[  295.372174] ctrl_pdata->rst_gpio = 25,ctrl_pdata->disp_dc_gpio = 23

我们重点关注休眠的时候,enable的CLK和MIPI屏幕有什么区别,可以看到SPI屏幕有28个时钟源:
<6>[  295.154066] Enabled clocks:
<6>[  295.154066]       xo_clk_src:1:1 [19200000]
<6>[  295.154066]       xo_a_clk_src:2:2 [19200000]
<6>[  295.154066]       pcnoc_a_clk:1:1 [19200000]
<6>[  295.154066]       bimc_clk:1:1 [95944704]
<6>[  295.154066]       bimc_msmbus_clk:1:1 [95944704] -> bimc_clk:1:1 [95944704]
<6>[  295.154066]       bimc_a_clk:1:1 [383909888]
<6>[  295.154066]       bimc_msmbus_a_clk:1:1 [383909888] -> bimc_a_clk:1:1 [383909888]
<6>[  295.154066]       pcnoc_keepalive_a_clk:1:1 [19200000] -> pcnoc_a_clk:1:1 [19200000]
<6>[  295.154066]       qdss_clk:5:5 [1000]
<6>[  295.154066]       xo_clk_src:2:2 [19200000] -> xo_clk_src:1:1 [19200000]
<6>[  295.154066]       gpll0_clk_src:1:1 [800000000] -> xo_clk_src:2:2 [19200000] -> xo_clk_src:1:1 [19200000]
<6>[  295.154066]       xo_a_clk_src:2:2 [19200000] -> xo_a_clk_src:2:2 [19200000]
<6>[  295.154066]       gpll0_ao_clk_src:1:1 [800000000] -> xo_a_clk_src:2:2 [19200000] -> xo_a_clk_src:2:2 [19200000]
<6>[  295.154066]       apss_ahb_clk_src:1:1 [19200000] -> xo_a_clk_src:2:2 [19200000] -> xo_a_clk_src:2:2 [19200000]
<6>[  295.154066]       mdp_clk_src:2:2 [160000000, 1] -> gpll0_clk_src:1:1 [800000000] -> xo_clk_src:2:2 [19200000] -> xo_clk_src:1:1 [192000]
<6>[  295.154066]       vsync_clk_src:1:1 [19200000, 1] -> xo_clk_src:2:2 [19200000] -> xo_clk_src:1:1 [19200000]
<6>[  295.154066]       gcc_boot_rom_ahb_clk:1:1 [0]
<6>[  295.154066]       gcc_apss_tcu_clk:1:0 [0]
<6>[  295.154066]       gcc_gfx_tcu_clk:1:0 [0]
<6>[  295.154066]       gcc_smmu_cfg_clk:2:0 [0]
<6>[  295.154066]       gcc_mdss_ahb_clk:1:1 [0]
<6>[  295.154066]       gcc_mdss_axi_clk:1:1 [0]
<6>[  295.154066]       gcc_mdss_mdp_clk:1:1 [0] -> mdp_clk_src:2:2 [160000000, 1] -> gpll0_clk_src:1:1 [800000000] -> xo_clk_src:2:2 [1920000]
<6>[  295.154066]       gcc_mdss_vsync_clk:1:1 [0] -> vsync_clk_src:1:1 [19200000, 1] -> xo_clk_src:2:2 [19200000] -> xo_clk_src:1:1 [19200000]
<6>[  295.154066]       gcc_mss_cfg_ahb_clk:1:1 [0]
<6>[  295.154066]       gcc_mss_q6_bimc_axi_clk:1:1 [0]
<6>[  295.154066]       gcc_usb2a_phy_sleep_clk:1:1 [0]
<6>[  295.154066]       a7ssmux:1:1 [800000000, 1] -> gpll0_ao_clk_src:1:1 [800000000] -> xo_a_clk_src:2:2 [19200000] -> xo_a_clk_src:2:2 [192]
<6>[  295.154066] Enabled clock count: 28

而MIPI屏幕只有19个时钟源
[ 324.861193] Enabled clocks:
[ 324.861193] xo_a_clk_src:2:2 [19200000]
[ 324.861193] pcnoc_a_clk:1:1 [19200000]
[ 324.861193] bimc_clk:1:1 [95944704]
[ 324.861193] bimc_msmbus_clk:1:1 [95944704] -> bimc_clk:1:1 [95944704]
[ 324.861193] bimc_a_clk:1:1 [383909888]
[ 324.861193] bimc_msmbus_a_clk:1:1 [383909888] -> bimc_a_clk:1:1 [383909888]
[ 324.861193] pcnoc_keepalive_a_clk:1:1 [19200000] -> pcnoc_a_clk:1:1 [19200000]
[ 324.861193] qdss_clk:5:5 [1000]
[ 324.861193] xo_a_clk_src:2:2 [19200000] -> xo_a_clk_src:2:2 [19200000]
[ 324.861193] gpll0_ao_clk_src:1:1 [800000000] -> xo_a_clk_src:2:2 [19200000] -> xo_a_clk_src:2:2 [19200000]
[ 324.861193] apss_ahb_clk_src:1:1 [19200000] -> xo_a_clk_src:2:2 [19200000] -> xo_a_clk_src:2:2 [19200000]
[ 324.861193] gcc_boot_rom_ahb_clk:1:1 [0]
[ 324.861193] gcc_apss_tcu_clk:1:0 [0]
[ 324.861193] gcc_gfx_tcu_clk:1:0 [0]
[ 324.861193] gcc_smmu_cfg_clk:2:0 [0]
[ 324.861193] gcc_mss_cfg_ahb_clk:1:1 [0]
[ 324.861193] gcc_mss_q6_bimc_axi_clk:1:1 [0]
[ 324.861193] gcc_usb2a_phy_sleep_clk:1:1 [0]
[ 324.861193] a7ssmux:1:1 [800000000, 1] -> gpll0_ao_clk_src:1:1 [800000000] -> xo_a_clk_src:2:2 [19200000] -> xo_a_clk_src:2:2 [19200000]
[ 324.861193] Enabled clock count: 19

SPI多了以下9个时钟源没有被关闭:
<6>[ 265.402823] xo_clk_src:1:1 [19200000]
<6>[ 265.402823] xo_clk_src:2:2 [19200000] -> xo_clk_src:1:1 [19200000]
<6>[ 265.402823] gpll0_clk_src:1:1 [800000000] -> xo_clk_src:2:2 [19200000] -> xo_clk_src:1:1 [19200000]
<6>[ 265.402823] mdp_clk_src:2:2 [160000000, 1] -> gpll0_clk_src:1:1 [800000000] -> xo_clk_src:2:2 [19200000] -> xo_clk_src:1:1 [192000]
<6>[ 265.402823] vsync_clk_src:1:1 [19200000, 1] -> xo_clk_src:2:2 [19200000] -> xo_clk_src:1:1 [19200000]
<6>[ 265.402823] gcc_mdss_ahb_clk:1:1 [0]
<6>[ 265.402823] gcc_mdss_axi_clk:1:1 [0]
<6>[ 265.402823] gcc_mdss_mdp_clk:1:1 [0] -> mdp_clk_src:2:2 [160000000, 1] -> gpll0_clk_src:1:1 [800000000] -> xo_clk_src:2:2 [1920000]
<6>[ 265.402823] gcc_mdss_vsync_clk:1:1 [0] -> vsync_clk_src:1:1 [19200000, 1] -> xo_clk_src:2:2 [19200000] -> xo_clk_src:1:1 [19200000]

mdp_clk_src,gcc_mdss_ahb_clk,gcc_mdss_axi_clk,gcc_mdss_mdp_clk,gcc_mdss_vsync_clk都是显示相关的CLK,
mdp3.h有相对应的CLK的定义:
enum  {
    MDP3_CLK_AHB,
    MDP3_CLK_AXI,
    MDP3_CLK_MDP_SRC,
    MDP3_CLK_MDP_CORE,
    MDP3_CLK_VSYNC,
    MDP3_CLK_DSI,
    MDP3_MAX_CLK
};
mdp3.c里mdp3_clk_enable有控制到这些时钟源:
int mdp3_clk_enable(int enable, int dsi_clk)
{
...
    rc = mdp3_clk_update(MDP3_CLK_AHB, enable);
    rc |= mdp3_clk_update(MDP3_CLK_AXI, enable);
    rc |= mdp3_clk_update(MDP3_CLK_MDP_SRC, enable);
    rc |= mdp3_clk_update(MDP3_CLK_MDP_CORE, enable);
    rc |= mdp3_clk_update(MDP3_CLK_VSYNC, enable);
...
}

可以看出这些CLK都是MDP显示相关的CLK,说明MDP有些CLK没有关闭。搜索mdp3_clk_enable被调用的地方,发现问题是在mdp3_is_display_on没有调用mdp3_clk_enable
来关闭时钟源。mdp3_is_display_on只会去关闭MIPI_CMD_PANEL的屏幕,并不会关闭SPI_PANEL的屏幕,所以要加上SPI_PANEL类型判断。
diff --git a/kernel/drivers/video/msm/mdss/mdp3.c b/kernel/drivers/video/msm/mdss/mdp3.c
index d8feb8c..79ba58f 100644
--- a/kernel/drivers/video/msm/mdss/mdp3.c
+++ b/kernel/drivers/video/msm/mdss/mdp3.c
@@ -2265,7 +2265,7 @@ static int mdp3_is_display_on(struct mdss_panel_data *pdata)

mdp3_res->splash_mem_addr = MDP3_REG_READ(MDP3_REG_DMA_P_IBUF_ADDR);

- if ((pdata->panel_info.type == MIPI_CMD_PANEL) ||(!rc)) {
+ if ((pdata->panel_info.type == MIPI_CMD_PANEL) ||(!rc)||(pdata->panel_info.type == SPI_PANEL)) {
if (mdp3_clk_enable(0, 0))
pr_err("fail to turn off MDP core clks\n");
}

在这里关闭CLK,功耗就正常了,下降到0.4mA,
查看下mdp3_is_display_on的调用关系,看到底是哪里没有关闭时钟源,调用关系如下(被调用者<-调用者)
mdp3_is_display_on<-mdp3_panel_register_done<-mdp3_probe(.panel_register_done = mdp3_panel_register_done,)<-panel_register_done<-mdss_register_panel<-spi_panel_device_register<-mdss_spi_panel_probe(.probe = mdss_spi_panel_probe,)
说明是SPI屏幕驱动,在一开始probe的时候就没有去关闭,后面就一直开着直到睡眠,因为SPI屏幕是通过内存映射直接将数据送到SPI接口,都没有走MDP3对应的接口,
所以后面也没有去关闭对应的MDP core clks的时钟。但是MIPI因为会走MDP3对应的接口,虽然一开始时钟也是关闭的,但是后面系统在正常运行的时候会去动态的打开
或关闭时钟,最终也是有关闭时钟的,所以MIPI的时钟最终关闭并达到要求的功耗。自此,问题解决。
---------------------------------------------------------------
调试技巧1:打开suspend模式的串口打印,禁止串口休眠,命令行执行命令:echo N > sys/module/printk/parameters/console_suspend
另外调试过程中,有个比较实用的调试技巧就是打开休眠状态下的串口打印,休眠不关闭串口打印log:
工程代码搜索no_console_suspend,kernel/Documentation/kernel-parameters.txt
    no_console_suspend [HW] Never suspend the console
            Disable suspending of consoles during suspend and
            hibernate operations.  Once disabled, debugging
            messages can reach various consoles while the rest
            of the system is being put to sleep (ie, while
            debugging driver suspend/resume hooks).  This may
            not work reliably with all consoles, but is known
            to work with serial and VGA consoles.
            To facilitate more flexible debugging, we also add
            console_suspend, a printk module parameter to control
            it. Users could use console_suspend (usually
            /sys/module/printk/parameters/console_suspend) to
            turn on/off it dynamically.

echo N > sys/module/printk/parameters/console_suspend
可以通过动态修改 sys/module/printk/parameters/console_suspend为N,就可以休眠时打开串口打印,但是最终也是会关闭,只是会尽可能打印更多的suspend Log
原来的值是Y,最后一条只会打印到:
[  295.835596] Suspending console(s) (use no_console_suspend to debug)
没打印出来的log,只能在下次按POWER按键唤醒的时候,连同唤醒log一起打印出来。

[  449.510464] Enabled clocks:
[  449.510464]  xo_clk_src:1:1 [19200000]
[  449.510464]  xo_a_clk_src:2:2 [19200000]
[  449.510464]  pcnoc_a_clk:1:1 [19200000]
[  449.510464]  bimc_clk:1:1 [95944704]
[  449.510464]  bimc_msmbus_clk:1:1 [95944704] -> bimc_clk:1:1 [95944704]
[  449.510464]  bimc_a_clk:1:1 [383909888]
[  449.510464]  bimc_msmbus_a_clk:1:1 [383909888] -> bimc_a_clk:1:1 [383909888]
[  449.510464]  pcnoc_keepalive_a_clk:1:1 [19200000] -> pcnoc_a_clk:1:1 [19200000]
[  449.510464]  qdss_clk:5:5 [1000]
[  449.510464]  xo_clk_src:1:1 [19200000] -> xo_clk_src:1:1 [19200000]
[  449.510464]  gpll0_clk_src:1:1 [800000000] -> xo_clk_src:1:1 [19200000] -> xo_clk_src:1:1 [19200000]
[  449.510464]  xo_a_clk_src:2:2 [19200000] -> xo_a_clk_src:2:2 [19200000]
[  449.510464]  gpll0_ao_clk_src:1:1 [800000000] -> xo_a_clk_src:2:2 [19200000] -> xo_a_clk_src:2:2 [19200000]
[  449.510464]  apss_ahb_clk_src:1:1 [19200000] -> xo_a_clk_src:2:2 [19200000] -> xo_a_clk_src:2:2 [19200000]
[  449.510464]  blsp1_uart1_apps_clk_src:1:1 [7372800, 1] -> gpll0_clk_src:1:1 [800000000] -> xo_clk_src:1:1 [19200000] -> xo_clk_src:1:1 [192]
[  449.510464]  gcc_blsp1_ahb_clk:1:1 [0]
[  449.510464]  gcc_boot_rom_ahb_clk:1:1 [0]
[  449.510464]  gcc_apss_tcu_clk:1:0 [0]
[  449.510464]  gcc_gfx_tcu_clk:1:0 [0]
[  449.510464]  gcc_smmu_cfg_clk:2:0 [0]
[  449.510464]  gcc_blsp1_uart1_apps_clk:1:1 [7372800] -> blsp1_uart1_apps_clk_src:1:1 [7372800, 1] -> gpll0_clk_src:1:1 [800000000] -> xo_clk]
[  449.510464]  gcc_mss_cfg_ahb_clk:1:1 [0]
[  449.510464]  gcc_mss_q6_bimc_axi_clk:1:1 [0]
[  449.510464]  gcc_usb2a_phy_sleep_clk:1:1 [0]
[  449.510464]  a7ssmux:1:1 [800000000, 1] -> gpll0_ao_clk_src:1:1 [800000000] -> xo_a_clk_src:2:2 [19200000] -> xo_a_clk_src:2:2 [19200000]
[  449.510464] Enabled clock count: 25
但是打开串口开关,可以看到gcc_blsp1_uart1_apps_clk,串口的时钟源,不会被关闭,电流将达到20mA,msm8909w这个平台不会去真正关闭串口,其他平台有的会直接关闭串口时钟,平台有差异,所以打开串口只作为调试手段,真正测算功耗电流的时候应该把休眠下的串口打印关闭
echo Y > sys/module/printk/parameters/console_suspend
---------------------------------------------------------------
调试技巧2:让串口打印所有级别的log,命令行执行命令:# echo 8 > /proc/sys/kernel/printk
串口日志级别:
日誌級別一共有8個級別,printk的日誌級別定義如下
kernel/include/linux/kern_levels.h
#define KERN_EMERG    KERN_SOH "0"    /* system is unusable */
#define KERN_ALERT    KERN_SOH "1"    /* action must be taken immediately */
#define KERN_CRIT    KERN_SOH "2"    /* critical conditions */
#define KERN_ERR    KERN_SOH "3"    /* error conditions */
#define KERN_WARNING    KERN_SOH "4"    /* warning conditions */
#define KERN_NOTICE    KERN_SOH "5"    /* normal but significant condition */
#define KERN_INFO    KERN_SOH "6"    /* informational */
#define KERN_DEBUG    KERN_SOH "7"    /* debug-level messages */
MSM8909W手表:/ # cat proc/sys/kernel/printk                                            
6       6       1       7
上面顯示的4個數據分別對應
控制台日誌級別:优先级高于该值的消息将被打印至控制台
默認的消息日誌級別:将用该优先级来打印没有优先级的消息(printk("HelloWorld");)
最低的控制台日誌級別:控制台日志级别可被设置的最小值(最高优先级)
默認的控制台日誌級別:控制台日志级别的缺省值
(1)第一个参数6 表示小于6优先级消息才会被输出到控制台。
(2)第二个参数6 表示默认的printk消息优先级别,即printk(“hell world”);优先级为6, 由于6不<6,故不可以被打印到控制台。
(3)第三个参数1 表示可接收的最高优先级,当printk disable控制台输出时,设置第一个参数为1,但是,从内核等级来看,还有优先级0,这个是printk最高级优先级,一般用于内核严重消息打印。比如内存错误或者 watchdog reset.也可以设置第一个和第三个参数为0
(4)第四个参数7 默认控制台优先级,即第一个参数的默认优先级。

當printk日誌級別小於console_loglevel時,消息才能顯示出來。 變量console_loglevel的初始值是CONSOLE_LOGLEVEL_DEFAULT(7),可以通過sys_syslog系統調用進行修改。調用klogd時可以指定-c開關選項來修改這個變量。如果要修改它的當前值,必須先殺掉klogd,再加-c選項重新啟動它。數值越小日誌級別越高,分為從 0-7共計8個日誌級別),如果該字段的日記級別高於console默認的日誌級別那麼才會打印出來。也就是printk日志级别小于7的才会被打印出来,至少要KERN_INFO及以上级别才会被打印出来
int console_printk[4] = {
    CONSOLE_LOGLEVEL_DEFAULT,    /* console_loglevel */7
    MESSAGE_LOGLEVEL_DEFAULT,    /* default_message_loglevel */
    CONSOLE_LOGLEVEL_MIN,        /* minimum_console_loglevel */1
    CONSOLE_LOGLEVEL_DEFAULT,    /* default_console_loglevel */7
};
所以printk() 可以这样用:printk(KERN_INFO "Hello, world!\n");
沒有指定日誌級別的printk語句默認採用的級別是:MESSAGE_LOGLEVEL_DEFAULT(這個默認級別一般為<4>,即與KERN_WARNING在一個級別上),其定義在kernel/printk.c中可以找到。但我们系统中是 
#define MESSAGE_LOGLEVEL_DEFAULT CONFIG_MESSAGE_LOGLEVEL_DEFAULT
搜索工程CONFIG_MESSAGE_LOGLEVEL_DEFAULT只发现以下
./out/target/product/MSM8909W/obj/KERNEL_OBJ/include/config/auto.conf:1219:CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4
./out/target/product/MSM8909W/obj/KERNEL_OBJ/include/generated/autoconf.h:1221:#define CONFIG_MESSAGE_LOGLEVEL_DEFAULT 4
./out/target/product/MSM8909W/obj/KERNEL_OBJ/.config.old:3677:CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4
./out/target/product/MSM8909W/obj/KERNEL_OBJ/.config:3677:CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4
所以不知道为什么系统起来后看到的是6

可用下面的命令設置當前日誌級別:
# echo 8 > /proc/sys/kernel/printk
MSM8909W手表:/ # cat proc/sys/kernel/printk                                            
8       6       1       7
這樣所有級別<8,(0-7)的消息都可以顯示在控制台上.
我想屏蔽掉所有的内核printk打印,那么我只需要把第一个数值调到最小值1或者0。
# echo 1 6 1 7> /proc/sys/kernel/printk
或者
# echo 0 6 0 7 > /proc/sys/kernel/printk

======================================================================
MSM8909W原生动画图片: android闪动效果
frameworks/base/core/res/assets/images/android-logo-mask.png
==============================================================
关于panel crash的问题
<6>[  660.036256] [<c00147f0>] (unwind_backtrace) from [<c0011c34>] (show_stack+0x10/0x14)
<6>[  660.036281] [<c0011c34>] (show_stack) from [<c0948d74>] (dump_stack+0x6c/0xb8)
<6>[  660.036301] [<c0948d74>] (dump_stack) from [<c0950dac>] (mutex_lock+0x18/0x3c)
<6>[  660.036323] [<c0950dac>] (mutex_lock) from [<c03bbe44>] (kgsl_get_egl_counts+0x24/0x98)
<6>[  660.036346] [<c03bbe44>] (kgsl_get_egl_counts) from [<c03d05e4>] (print_mem_entry+0x128/0x224)
<6>[  660.036367] [<c03d05e4>] (print_mem_entry) from [<c026cf90>] (idr_for_each+0xac/0xd4)
<6>[  660.036387] [<c026cf90>] (idr_for_each) from [<c03d0764>] (process_mem_print+0x84/0xcc)
<6>[  660.036410] [<c03d0764>] (process_mem_print) from [<c01466cc>] (seq_read+0x1a8/0x400)
<6>[  660.036432] [<c01466cc>] (seq_read) from [<c0128f28>] (vfs_read+0x90/0x124)
<6>[  660.036450] [<c0128f28>] (vfs_read) from [<c0129468>] (SyS_read+0x40/0x80)
<6>[  660.036470] [<c0129468>] (SyS_read) from [<c000e060>] (ret_fast_syscall+0x0/0x38)

关于内核会打印以上log,从print_mem_entry可以看出read the debugfs node too fast,
print_mem_entry()的调用关系是print_mem_entry()<-process_mem_print()<-process_mem_open(),
static const struct file_operations process_mem_fops = {
.open = process_mem_open,
最终是调用了kgsl_debugfs.c驱动的open,这个文件高通有个patch:
https://source.codeaurora.org/quic/la/kernel/msm-3.18/commit/?h=rel%2Fmsm-3.18&id=1868ddab68e2fe4b 
合入这个patch之后,就不会有这个log打印了,关于这个patch的说明是:
msm: kgsl: use seq_file for mem_entry debugfs
A process may have many kgsl mem entries in use. Outputing all of them
as a single debugfs seq_file record takes twice as long as necessary
because seq_file must retry higher order page allocations for the output
buffer until it is large enough to hold all mem entries.

Additionally, process_mem_print() currently holds the spinlock
private->mem_lock during this process. This is too much time to
disable interrupts, and prevents locking mutex in print_mem_entry.

Change the kgsl_mem_entry debugfs functions to output one entry at a
time. Then the seq_file only need to kmalloc one page regardless of
the number of kgsl_mem_entries.

虽然不知道和panel crash有没有直接的关系,但是先把这个patch打上,后续有死机现象再具体分析。
看这个patch的说明,
Additionally, process_mem_print() currently holds the spinlock private->mem_lock during this process. This is too much time to disable interrupts, and prevents locking mutex in print_mem_entry.
有提到一个spinlock,但是好像和crash dump的log不是同一个spinlock?
195.340327: <6> BUG: spinlock lockup suspected on CPU#3, mdss_fb0/5348
195.345485: <6> lock: 0xdd80a53c, .magic: dead4ead, .owner: <none>/-1, .owner_cpu: -1

因为你看QCAP的报告,死机的时候明显有调用到这个spinlock的流程,然后就死机了:
CPU 1 Call Stacks (dumped by TZ):
-000|arch_timer_read_counter_long()
-001|read_current_timer()
-002|__timer_delay()
-003|do_raw_spin_lock()
-004|_raw_spin_lock_irqsave()
-005|complete()//这里会去获取锁
-006|spi_panel_te_handler()
-007|handle_irq_event_percpu()
-008|handle_irq_event()
-009|handle_edge_irq()
-010|generic_handle_irq()
-011|msm_gpio_irq_handler()
-012|generic_handle_irq()
-013|__handle_domain_irq()
-014|gic_handle_irq()
-015|__irq_usr()
----|end of frame
=====================================================================================
MSM8909W手表 OTA升级说明
MSM8909W手表使用自定义ota的fotaapp,测试ota升级已经完成,需要测试部在测试一轮。
OTA初始包与后续ota升级包说明:
初始包最重要:
1.生成初始包需要先编译AP的代码(make -j)
2.将编译完后的out目录下的文件拷贝到MSM8909W手表工程LINUX目录下的out文件夹内
3.运行genbin后使用qfile的flat meta build生成emmc文件夹
4.将文件夹里的emmc_appsboot.mbn、 rpm.mbn 、tz.mbn、 sbl1.mbn、 NON-HLOS.bin 5个文件拷贝到AP devices/qcom/MSM8909W/radio/里
5.编译OTA包(make otapackage)
6.将编译完后的out目录下的文件拷贝到MSM8909W工程LINUX目录下的out文件夹内
7运行genbin后使用qfile的flat meta build生成emmc文件夹
8.将编译完OTA包的out文件夹里的emmc_appsboot.mbn、 rpm.mbn 、tz.mbn、 sbl1.mbn、 NON-HLOS.bin 5个文件拷贝到flat meta build生成emmc文件夹里替换原来的文件。
9.使用qfile下载初始版本到设备

OTA升级包
1.编译AP的代码(make -j)
2.将编译完后的out目录下的文件拷贝到MSM8909W工程LINUX目录下的out文件夹内
3.运行genbin后使用qfile的flat meta build生成emmc文件夹
4.将文件夹里的emmc_appsboot.mbn、 rpm.mbn 、tz.mbn、 sbl1.mbn、 NON-HLOS.bin 5个文件拷贝到AP devices/qcom/MSM8909W/radio/里
5.编译OTA升级包(make otapackage)

差分包生成与部署
1.打开艾拉比差分生成工具
2.选择原版本(初始包)与目标版本(升级包)的ota文件包(out下的target-files-package.zip)
3.一直下一步直至部署完成。
=======================================
SPI屏幕在recovery模式显示显示异常的问题:
recovery模式下,adb shell默认进不了,需要在recovery菜单选择执行Mount /system终端才可以进入文件系统。recovery有自己的一套文件系统生成在out目录下:out/target/product/MSM8909W/recovery/root/res/images
进入之后所有的图片资源在系统目录下:/res/image/xxx.png
130|MSM8909W手表:/ # ls /res/images/                                                                                                                  
erasing_text.png             loop00007.png loop00020.png loop00033.png loop00046.png loop00059.png loop00072.png loop00085.png       
error_text.png               loop00008.png loop00021.png loop00034.png loop00047.png loop00060.png loop00073.png loop00086.png       
font.png                     loop00009.png loop00022.png loop00035.png loop00048.png loop00061.png loop00074.png loop00087.png       
icon_error.png               loop00010.png loop00023.png loop00036.png loop00049.png loop00062.png loop00075.png loop00088.png       
installing_security_text.png loop00011.png loop00024.png loop00037.png loop00050.png loop00063.png loop00076.png loop00089.png       
installing_text.png          loop00012.png loop00025.png loop00038.png loop00051.png loop00064.png loop00077.png loop00090.png       
loop00000.png                loop00013.png loop00026.png loop00039.png loop00052.png loop00065.png loop00078.png no_command_text.png 
loop00001.png                loop00014.png loop00027.png loop00040.png loop00053.png loop00066.png loop00079.png progress_empty.png  
loop00002.png                loop00015.png loop00028.png loop00041.png loop00054.png loop00067.png loop00080.png progress_fill.png   
loop00003.png                loop00016.png loop00029.png loop00042.png loop00055.png loop00068.png loop00081.png stage_empty.png     
loop00004.png                loop00017.png loop00030.png loop00043.png loop00056.png loop00069.png loop00082.png stage_fill.png      
loop00005.png                loop00018.png loop00031.png loop00044.png loop00057.png loop00070.png loop00083.png 
loop00006.png                loop00019.png loop00032.png loop00045.png loop00058.png loop00071.png loop00084.png

然后把erasing_text.png拉出来看下是哪张图:adb pull res/images/erasing_text.png
android recovery模式支持adb shell需要在recovery菜单里选择Mount /system才能进行adb shell,
拉出来发现是351*5072的图片,对应分辨率是源码目录的msm8909w_law_android/bootable/recovery/res-xhdpi/images/erasing_text.png
定制小手机也是使用这个分辨率的图片(定制小手机 run graphic test除了进度条,其他文字图片显示正常),健康手表项目的320*320的屏幕也是使用xhdpi的图片(但是健康手表项目的run graphic test显示正常,且进度条也正常,APP同事之前OTA升级的时候,MSM8909W手表 320P的屏幕,显示也正常,进度条也正常)
其他分辨率的erasing_text.png图片大小如下:
mdpi:173*2602
hdpi:266*3902
xhdpi:351*5072
xxhdpi:525*7542
xxxhdpi:703*10012
res-560dpi:703*10012 ?

可以通过以下的代码来设置本地语言为中文,查看run graphic test的中文效果。
    locale = "zh_CN";//中文
    ui->SetLocale(locale);

locale保存在"/cache/recovery/last_locale",以备下次进入recovery选择正确语言。

static void run_graphics_test(Device* device) {
    // Switch to graphics screen.
    printf("===run_graphics_test===\n");
    ui->ShowText(false);//不显示菜单

ui->SetProgressType(RecoveryUI::INDETERMINATE);
    ui->SetBackground(RecoveryUI::INSTALLING_UPDATE);//“正在安装系统更新”
    sleep(1);

ui->SetBackground(RecoveryUI::ERROR);//“出错了!”
    sleep(1);

ui->SetBackground(RecoveryUI::NO_COMMAND);//“无命令”
    sleep(1);

ui->SetBackground(RecoveryUI::ERASING);//“正在清空”
    sleep(1);

ui->SetBackground(RecoveryUI::INSTALLING_UPDATE);//“正在安装系统更新”

ui->SetProgressType(RecoveryUI::DETERMINATE);
    ui->ShowProgress(1.0, 10.0);
    float fraction = 0.0;
    for (size_t i = 0; i < 100; ++i) {
      fraction += .01;
      ui->SetProgress(fraction);//进度条
      usleep(100000);
    }

ui->ShowText(true);//返回菜单
}

定制小手机分辨率是240*432,健康手表项目是320*320,健康手表项目能正常显示进度条,定制小手机不能是因为进度条的图片本身太大了,进度条progress_empty.png和progress_fill.png大小是252*7,宽度大过了屏幕的最大宽度240,所以MSM8909W手表(240*240)和定制小手机的屏幕都不能显示出进度条,把进度条改成150*7就可以显示出来了。
$ pnginfo progress_empty.png 
progress_empty.png...
  Image Width: 252 Image Length: 7
  Bitdepth (Bits/Sample): 1
  Channels (Samples/Pixel): 1
  Pixel depth (Pixel Depth): 1
  Colour Type (Photometric Interpretation): PALETTED COLOUR (1 colours, 0 transparent) 
  Image filter: Single row per byte filter 
  Interlacing: No interlacing 
  Compression Scheme: Deflate method 8, 32k window
  Resolution: 0, 0 (unit unknown)
  FillOrder: msb-to-lsb
  Byte Order: Network (Big Endian)
  Number of text strings: 0 of 0

$ file progress_empty.png 
progress_empty.png: PNG image data, 252 x 7, 1-bit colormap, non-interlaced

可以看出进度条图片的格式要求是1-bit  PALETTED png;

至于为什么文字图片显示不出来是因为坐标不对,并不是图片太大,查看log可以看到图片的文字取出来并不会超标:
erasing_text: zh_CN (109 x 38 @ 4875)
no_command_text: zh_CN (83 x 38 @ 4875)
error_text: zh_CN (92 x 38 @ 4875)
installing_text: zh_CN (222 x 38 @ 5766)
最大的“正在安装系统更新”也才222,并不会超出屏幕的宽度。

追一下显示的流程:
画recovery 菜单:draw_screen_locked,
调用者->被调用者
SetBackground/StartMenu/SelectMenu/EndMenu/ShowText/Redraw->
update_screen_locked/update_progress_locked->
draw_screen_locked->
draw_background_locked

最终调用的是draw_background_locked来完成背景图以及文字图片的显示;调用gr_texticon函数来显示图片文字,最后调用text_blend来显示文字。
LoadBitmap用于加载背景图和进度条 
    LoadBitmap("icon_error", &error_icon);//背景图,出错的机器人
    LoadBitmap("progress_empty", &progressBarEmpty);//进度条
    LoadBitmap("progress_fill", &progressBarFill);//进度条填充
    LoadBitmap("stage_empty", &stageMarkerEmpty);
    LoadBitmap("stage_fill", &stageMarkerFill);
    LoadBitmap(android::base::StringPrintf("loop%05d", i).c_str(), &loopFrames[i]);//Init的时候会加载动画,但loop00000.png是400*400,太大,不显示
LoadLocalizedBitmap加载文字图片
    LoadLocalizedBitmap("installing_security_text", &installing_text);//installing_security_text.png “正在安装安全更新”
    LoadLocalizedBitmap("installing_text", &installing_text);//installing_text.png “正在安装系统更新”
    LoadLocalizedBitmap("erasing_text", &erasing_text);//erasing_text.png “正在清空”
    LoadLocalizedBitmap("no_command_text", &no_command_text);// no_command_text.png “无命令”
    LoadLocalizedBitmap("error_text", &error_text);//error_text.png “出错了!”

图片格式要求:
    if (bit_depth == 8 && *channels == 3 && color_type == PNG_COLOR_TYPE_RGB) {//8bit 3 channels PNG_COLOR_TYPE_RGB
        // 8-bit RGB images: great, nothing to do.
    } else if (bit_depth <= 8 && *channels == 1 && color_type == PNG_COLOR_TYPE_GRAY) {//<=8bit 1 channel PNG_COLOR_TYPE_GRAY
        // 1-, 2-, 4-, or 8-bit gray images: expand to 8-bit gray.
        png_set_expand_gray_1_2_4_to_8(*png_ptr);//扩充为8bit
    } else if (bit_depth <= 8 && *channels == 1 && color_type == PNG_COLOR_TYPE_PALETTE) {//<=8bit 1 channel PNG_COLOR_TYPE_PALETTE
        // paletted images: expand to 8-bit RGB.  Note that we DON'T
        // currently expand the tRNS chunk (if any) to an alpha
        // channel, because minui doesn't support alpha channels in
        // general.
        png_set_palette_to_rgb(*png_ptr);//PNG_COLOR_TYPE_PALETTE转为PNG_COLOR_TYPE_RGB
        *channels = 3;
    }

所以在显示图片文字的gr_texticon函数打印下坐标信息:
void ScreenRecoveryUI::draw_background_locked() {
    pagesIdentical = false;
    gr_color(0, 255, 0, 255);//green
    gr_clear();

if (currentIcon != NONE) {
        if (max_stage != -1) {
            int stage_height = gr_get_height(stageMarkerEmpty);
            int stage_width = gr_get_width(stageMarkerEmpty);
            int x = (gr_fb_width() - max_stage * gr_get_width(stageMarkerEmpty)) / 2;
            int y = gr_fb_height() - stage_height;
            for (int i = 0; i < max_stage; ++i) {
                GRSurface* stage_surface = (i < stage) ? stageMarkerFill : stageMarkerEmpty;
                gr_blit(stage_surface, 0, 0, stage_width, stage_height, x, y);
                x += stage_width;
            }
        }

GRSurface* text_surface = GetCurrentText();
        int text_x = (gr_fb_width() - gr_get_width(text_surface)) / 2;
        int text_y = GetTextBaseline();
        gr_color(0, 0, 255, 255);//blue
        //text_x = 0;
     //text_y = 100;//如果强制设置坐标就能在run graphic test显示出文字了
     printf("===text_x = %d, text_y = %d===\n", text_x, text_y);//text_y打印出来都是负的
        gr_texticon(text_x, text_y, text_surface);
    }
}

负的会导致什么后果呢?
void gr_texticon(int x, int y, GRSurface* icon) {
...
    if (outside(x, y) || outside(x+icon->width-1, y+icon->height-1))
    {
            printf("===outside,x=%d,y=%d,icon->width =%d,icon->height = %d,return===\n", x, y, icon->width, icon->height);
        return;
    }
    ...
    text_blend(src_p, icon->row_bytes,
               dst_p, gr_draw->row_bytes,
               icon->width, icon->height);
...
}
发现y坐标每次打印出来都是负数,执行outside(x,y)后直接return,都不会执行到text_blend来显示文字。这就是为什么图片文字显示不出来了,因为text_blend实际上会执行write_rgba_to_565进行格式转换的,所以数据的格式转换也是没有问题,
所以问题出在:int text_y = GetTextBaseline();

int ScreenRecoveryUI::GetAnimationBaseline() {
    printf("===GetTextBaseline() = %d===\n", GetTextBaseline());//图片文字TEXT的y坐标
    printf("===layout_ = %d===\n", layout_);//0
    printf("===PixelsFromDp(kLayouts[layout_][ICON]) = %d===\n", PixelsFromDp(kLayouts[layout_][ICON]));//kLayouts[0][2]=68
    printf("===gr_get_height(loopFrames[0]) = %d===\n", gr_get_height(loopFrames[0]));//400
    return GetTextBaseline() - PixelsFromDp(kLayouts[layout_][ICON]) -
            gr_get_height(loopFrames[0]);
}

int ScreenRecoveryUI::GetTextBaseline() {
    printf("===GetProgressBaseline() = %d===\n", GetProgressBaseline());//进度条Progress的y坐标
    printf("===layout_ = %d===\n", layout_);//0
    printf("===PixelsFromDp(kLayouts[layout_][TEXT]) = %d===\n", PixelsFromDp(kLayouts[layout_][TEXT]));//kLayouts[0][1]=32
    printf("===gr_get_height(installing_text) = %d===\n", gr_get_height(installing_text));//38
    return GetProgressBaseline() - PixelsFromDp(kLayouts[layout_][TEXT]) -
            gr_get_height(installing_text);
}

int ScreenRecoveryUI::GetProgressBaseline() {
    printf("===gr_fb_height() = %d===\n", gr_fb_height());//240
    printf("===layout_ = %d===\n", layout_);//0
    printf("===PixelsFromDp(kLayouts[layout_][PROGRESS]) = %d===\n", PixelsFromDp(kLayouts[layout_][PROGRESS]));//kLayouts[0][0]=194
    printf("===gr_get_height(progressBarFill) = %d===\n", gr_get_height(progressBarFill));//7
    return gr_fb_height() - PixelsFromDp(kLayouts[layout_][PROGRESS]) -
            gr_get_height(progressBarFill);
}

int ScreenRecoveryUI::PixelsFromDp(int dp) {
    return dp * density_;//
}
系统dpi:[ro.sf.lcd_density]: [160]
所以:
    density_ = static_cast<float>(property_get_int32("ro.sf.lcd_density", 160)) / 160.f;
    printf("density_ = %f\n", density_);//density_ = 1.0
PixelsFromDp实际返回dp

layout_ = (gr_fb_width() > gr_fb_height()) ? LANDSCAPE : PORTRAIT;
竖屏幕,就是是等高240*240,也不会宽比高大,所以layout_ = PORTRAIT;
PORTRAIT = 0;
enum Dimension { PROGRESS = 0, TEXT = 1, ICON = 2, DIMENSION_MAX };

和这个kLayouts密切相关
static constexpr int kLayouts[LAYOUT_MAX][DIMENSION_MAX] = {
    { 194,  32,  68, }, // PORTRAIT
    { 340,  32,  68, }, // PORTRAIT_LARGE
    { 131,  26,  56, }, // LANDSCAPE
    { 262,  52, 112, }, // LANDSCAPE_LARGE
};
kLayouts[layout_][ICON]即kLayouts[0][PROGRESS]、kLayouts[0][TEXT]、kLayouts[0][ICON]
当取kLayouts[0][PROGRESS]位置的时候问题就出现了kLayouts[0][0] = 194,太大了,kLayouts的从上到下布局是这样的:
------------------------------屏幕顶部------------
间隔 大小可变
ICON 具体多大就多大
间隔 大小为68
TEXT 具体多大就多大,图片资源是读出来38高
间隔 大小为32
PROGRESS 具体多大就多个,图片资源是7高
间隔 大小194
------------------------------屏幕底部------------

所以240-194-7是39,是进度条的y坐标,
但是39-32-38就是负数了,图片文字就显示不出来了,所以需要把194改小。
static constexpr int kLayouts[LAYOUT_MAX][DIMENSION_MAX] = {
    { 40,  32,  25, }, // PORTRAIT
    { 340,  32,  68, }, // PORTRAIT_LARGE
    { 131,  26,  56, }, // LANDSCAPE
    { 262,  52, 112, }, // LANDSCAPE_LARGE
};

显示正常。
===============================
版本号修改:
whl@whl-Dell:~/work/msm8909w_law_android$ git diff build/core/Makefile
diff --git a/build/core/Makefile b/build/core/Makefile
index 7a4ad71..6615b69 100755
--- a/build/core/Makefile
+++ b/build/core/Makefile
@@ -183,7 +183,7 @@ endif
 
 #Add by MSM8909W手表 version show Build.DISPLAY
 ifeq ($(TARGET_PRODUCT),MSM8909W)
-  BUILD_DISPLAY_ID := "V1.0.2"
+  BUILD_DISPLAY_ID := "V1.0.3"
   PRODUCT_MODEL := "MSM8909W_D9"
   BUILD_VERSION_TAGS := "watch"
 endif

====================================
恢复出厂卡在“正在清空”,串口log:
[    3.756669] -- Wiping data...
[    3.756687] ===erase_volume===
[    3.756705] Formatting /data...
[    3.756744] Creating filesystem with parameters:
[    3.756766]     Size: 1542418432
[    3.756785]     Block size: 4096
[    3.756804]     Blocks per group: 32768
[    3.756823]     Inodes per group: 7856
[    3.756841]     Inode size: 256
[    3.756859]     Journal blocks: 5883
[    3.756878]     Label: 
[    3.756896]     Blocks: 376567
[    3.756914]     Block groups: 12
[    3.756932]     Reserved block group size: 95
[    3.756951] Created filesystem with 11/94272 inodes and 12384/376567 blocks
[    5.104390] ===erase_volume===
[    5.126327] Formatting /cache...
[   12.577306] EXT4-fs (mmcblk0p23): warning: maximal mount count reached, running e2fsck is recommended
[   12.578602] EXT4-fs (mmcblk0p23): recovery complete
[   12.579598] EXT4-fs (mmcblk0p23): mounted filesystem with ordered data mode. Opts: barrier=1,data=ordered
[    5.281999] Creating filesystem with parameters:
[    5.282080]     Size: 67108864
[    5.282103]     Block size: 4096
[    5.282123]     Blocks per group: 32768
[    5.282142]     Inodes per group: 4096
[    5.282162]     Inode size: 256
[    5.282180]     Journal blocks: 1024
[    5.282199]     Label: 
[    5.282222]     Blocks: 16384
[    5.282241]     Block groups: 1
[    5.282260]     Reserved block group size: 7
[    5.282808] Created filesystem with 11/4096 inodes and 1294/16384 blocks
[   12.971016] EXT4-fs (mmcblk0p23): mounted filesystem with ordered data mode. Opts: barrier=1,data=ordered
[   37.459557] random: nonblocking pool is initialized

[   99.801145] recovery (287) used greatest stack depth: 6064 bytes left
原因还没查,下次开机也卡在这。后来把recovery模式下的串口打印关闭就正常了,能够正常恢复出厂,不会卡住。可能是打印串口打印耗费了太多栈内存了。
====================================

note_2019_7相关推荐

最新文章

  1. 目标检测 | 盘点目标检测中的特征融合技巧(根据YOLO v4总结)
  2. mysql 物理备份工具_mysql物理备份工具Xtrabackup安装配置
  3. python dict排序 reduce函数
  4. 教你一招画素描, 不写程序时陶冶陶冶情操
  5. KnowledgeTree简体中文汉化包安装指导
  6. 汇编语言学习——第四章 第一个汇编程序
  7. 计算机自带游戏在哪里打开,电脑自带游戏选项在哪里打开
  8. 一图搞定ML!2020版机器学习技术路线图,35页ppt
  9. Github | ICCV2019论文1000余篇更新!附下载链接
  10. Jenkins环境拓扑及部署流程
  11. 从开源开发者身上学到的 5 种品质
  12. 腾讯QQ2010安装时提示“C:\windows\Installer\QQ2010.msi时发生网络错误”的解决方 ......
  13. 知识蒸馏方法的演进历史综述
  14. 每一句都值得品味的话
  15. 贝叶斯网络、马尔可夫模型、马尔可夫过程、马尔可夫链、马尔可夫网络基本概念
  16. Qt QLineedit 控件出发clicked信号问题
  17. 获取华为云课程内嵌的课件pdf文件
  18. AT指令(中文详解版)二 [转载]
  19. 让我们难忘的那些歌曲
  20. 网站关键词优化方法有哪些

热门文章

  1. LM1117MPX-2.5参数
  2. Python测试题——学习通(高校邦)
  3. 微信小程序图片内容审核功能云函数+小程序端代码完整实现【填坑】
  4. 习题 3.2 设圆半径r=1.5, 圆柱高h=3, 求圆周长、圆面积、圆球表面积、圆球体积、圆柱体积。用cin输入数据,输出计算结果,输出时要求有文字说明,取小数点后两位数字。请编程序。
  5. python海龟绘图零基础学习
  6. 『功守道』软件供应链安全大赛·C源代码赛季启示录
  7. JSON,JSONArray以及转换Java Bean
  8. 文件改名,如何将文件批量重命名并使用随机命名方式进行改名。
  9. Delphi RenameFile 文件改名
  10. 云服务器创建FTP站点