This file is indexed.

/usr/bin/tlp-stat is in tlp 1.1-2.

This file is owned by root:root, with mode 0o755.

The actual contents of the file can be viewed below.

   1
   2
   3
   4
   5
   6
   7
   8
   9
  10
  11
  12
  13
  14
  15
  16
  17
  18
  19
  20
  21
  22
  23
  24
  25
  26
  27
  28
  29
  30
  31
  32
  33
  34
  35
  36
  37
  38
  39
  40
  41
  42
  43
  44
  45
  46
  47
  48
  49
  50
  51
  52
  53
  54
  55
  56
  57
  58
  59
  60
  61
  62
  63
  64
  65
  66
  67
  68
  69
  70
  71
  72
  73
  74
  75
  76
  77
  78
  79
  80
  81
  82
  83
  84
  85
  86
  87
  88
  89
  90
  91
  92
  93
  94
  95
  96
  97
  98
  99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 139
 140
 141
 142
 143
 144
 145
 146
 147
 148
 149
 150
 151
 152
 153
 154
 155
 156
 157
 158
 159
 160
 161
 162
 163
 164
 165
 166
 167
 168
 169
 170
 171
 172
 173
 174
 175
 176
 177
 178
 179
 180
 181
 182
 183
 184
 185
 186
 187
 188
 189
 190
 191
 192
 193
 194
 195
 196
 197
 198
 199
 200
 201
 202
 203
 204
 205
 206
 207
 208
 209
 210
 211
 212
 213
 214
 215
 216
 217
 218
 219
 220
 221
 222
 223
 224
 225
 226
 227
 228
 229
 230
 231
 232
 233
 234
 235
 236
 237
 238
 239
 240
 241
 242
 243
 244
 245
 246
 247
 248
 249
 250
 251
 252
 253
 254
 255
 256
 257
 258
 259
 260
 261
 262
 263
 264
 265
 266
 267
 268
 269
 270
 271
 272
 273
 274
 275
 276
 277
 278
 279
 280
 281
 282
 283
 284
 285
 286
 287
 288
 289
 290
 291
 292
 293
 294
 295
 296
 297
 298
 299
 300
 301
 302
 303
 304
 305
 306
 307
 308
 309
 310
 311
 312
 313
 314
 315
 316
 317
 318
 319
 320
 321
 322
 323
 324
 325
 326
 327
 328
 329
 330
 331
 332
 333
 334
 335
 336
 337
 338
 339
 340
 341
 342
 343
 344
 345
 346
 347
 348
 349
 350
 351
 352
 353
 354
 355
 356
 357
 358
 359
 360
 361
 362
 363
 364
 365
 366
 367
 368
 369
 370
 371
 372
 373
 374
 375
 376
 377
 378
 379
 380
 381
 382
 383
 384
 385
 386
 387
 388
 389
 390
 391
 392
 393
 394
 395
 396
 397
 398
 399
 400
 401
 402
 403
 404
 405
 406
 407
 408
 409
 410
 411
 412
 413
 414
 415
 416
 417
 418
 419
 420
 421
 422
 423
 424
 425
 426
 427
 428
 429
 430
 431
 432
 433
 434
 435
 436
 437
 438
 439
 440
 441
 442
 443
 444
 445
 446
 447
 448
 449
 450
 451
 452
 453
 454
 455
 456
 457
 458
 459
 460
 461
 462
 463
 464
 465
 466
 467
 468
 469
 470
 471
 472
 473
 474
 475
 476
 477
 478
 479
 480
 481
 482
 483
 484
 485
 486
 487
 488
 489
 490
 491
 492
 493
 494
 495
 496
 497
 498
 499
 500
 501
 502
 503
 504
 505
 506
 507
 508
 509
 510
 511
 512
 513
 514
 515
 516
 517
 518
 519
 520
 521
 522
 523
 524
 525
 526
 527
 528
 529
 530
 531
 532
 533
 534
 535
 536
 537
 538
 539
 540
 541
 542
 543
 544
 545
 546
 547
 548
 549
 550
 551
 552
 553
 554
 555
 556
 557
 558
 559
 560
 561
 562
 563
 564
 565
 566
 567
 568
 569
 570
 571
 572
 573
 574
 575
 576
 577
 578
 579
 580
 581
 582
 583
 584
 585
 586
 587
 588
 589
 590
 591
 592
 593
 594
 595
 596
 597
 598
 599
 600
 601
 602
 603
 604
 605
 606
 607
 608
 609
 610
 611
 612
 613
 614
 615
 616
 617
 618
 619
 620
 621
 622
 623
 624
 625
 626
 627
 628
 629
 630
 631
 632
 633
 634
 635
 636
 637
 638
 639
 640
 641
 642
 643
 644
 645
 646
 647
 648
 649
 650
 651
 652
 653
 654
 655
 656
 657
 658
 659
 660
 661
 662
 663
 664
 665
 666
 667
 668
 669
 670
 671
 672
 673
 674
 675
 676
 677
 678
 679
 680
 681
 682
 683
 684
 685
 686
 687
 688
 689
 690
 691
 692
 693
 694
 695
 696
 697
 698
 699
 700
 701
 702
 703
 704
 705
 706
 707
 708
 709
 710
 711
 712
 713
 714
 715
 716
 717
 718
 719
 720
 721
 722
 723
 724
 725
 726
 727
 728
 729
 730
 731
 732
 733
 734
 735
 736
 737
 738
 739
 740
 741
 742
 743
 744
 745
 746
 747
 748
 749
 750
 751
 752
 753
 754
 755
 756
 757
 758
 759
 760
 761
 762
 763
 764
 765
 766
 767
 768
 769
 770
 771
 772
 773
 774
 775
 776
 777
 778
 779
 780
 781
 782
 783
 784
 785
 786
 787
 788
 789
 790
 791
 792
 793
 794
 795
 796
 797
 798
 799
 800
 801
 802
 803
 804
 805
 806
 807
 808
 809
 810
 811
 812
 813
 814
 815
 816
 817
 818
 819
 820
 821
 822
 823
 824
 825
 826
 827
 828
 829
 830
 831
 832
 833
 834
 835
 836
 837
 838
 839
 840
 841
 842
 843
 844
 845
 846
 847
 848
 849
 850
 851
 852
 853
 854
 855
 856
 857
 858
 859
 860
 861
 862
 863
 864
 865
 866
 867
 868
 869
 870
 871
 872
 873
 874
 875
 876
 877
 878
 879
 880
 881
 882
 883
 884
 885
 886
 887
 888
 889
 890
 891
 892
 893
 894
 895
 896
 897
 898
 899
 900
 901
 902
 903
 904
 905
 906
 907
 908
 909
 910
 911
 912
 913
 914
 915
 916
 917
 918
 919
 920
 921
 922
 923
 924
 925
 926
 927
 928
 929
 930
 931
 932
 933
 934
 935
 936
 937
 938
 939
 940
 941
 942
 943
 944
 945
 946
 947
 948
 949
 950
 951
 952
 953
 954
 955
 956
 957
 958
 959
 960
 961
 962
 963
 964
 965
 966
 967
 968
 969
 970
 971
 972
 973
 974
 975
 976
 977
 978
 979
 980
 981
 982
 983
 984
 985
 986
 987
 988
 989
 990
 991
 992
 993
 994
 995
 996
 997
 998
 999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
#!/bin/sh
# tlp - display power save and usb autosuspend status
#
# Copyright (c) 2018 Thomas Koch <linrunner at gmx.net>
# This software is licensed under the GPL v2 or later.

# --- Constants

readonly LIBDIR="/usr/share/tlp"
readonly LIBS="tlp-functions tlp-rf-func"

readonly TLPUSB=tlp-usblist
readonly TLPPCI=tlp-pcilist

readonly SMARTCTL=smartctl
readonly LSBREL=lsb_release

readonly ASPM=/sys/module/pcie_aspm/parameters/policy
readonly NMIWD=/proc/sys/kernel/nmi_watchdog
readonly WQPE=/sys/module/workqueue/parameters/power_efficient

readonly IBMTHERMAL=/proc/acpi/ibm/thermal
readonly CORETEMP_DIRS="
/sys/devices/platform/coretemp.0
/sys/devices/platform/coretemp.0/hwmon/hwmon*"
readonly IBMFAN=/proc/acpi/ibm/fan
readonly HWMONFAN_DIRS="
/sys/class/hwmon/hwmon*/device
/sys/class/hwmon/hwmon*"

readonly JOURNALCTL=journalctl
readonly DEBUGLOG=/var/log/debug

readonly SYSTEMD_SERVICES="tlp.service tlp-sleep.service"
readonly RFKILL_SERVICES="systemd-rfkill.service"

readonly EFID=/sys/firmware/efi

readonly RE_ATA_ERROR='ata[0-9]+: SError: {.*CommWake }'

# --- Variables
needs_root_priv=
show_all=1
show_bat=0
show_conf=0
show_disk=0
show_graf=0
show_pcie=0
show_pev=0
show_proc=0
show_psup=0
show_rfkill=0
show_system=0
show_temp=0
show_trace=0
show_usb=0
show_verbose=0
show_warn=0

no_runtimepm=0

# --- Functions

printparm () { # formatted output of sysfile - general
    # $1: format, $2: sysfile, $3: namsg, $4: cutoff
    local format="$1"
    local sysf="$2"
    local namsg="$3"
    local cutoff="$4"
    local val=""

    if [ -f $sysf ]; then
        # sysfile exists
        val=$(cat $sysf 2> /dev/null)
        if [ $? = 0 ]; then
            # sysfile read successful
            if [ -n "$cutoff" ]; then
                val=${val%$cutoff}
            fi
        fi
    fi

    if [ -z "$val" ]; then
        # replace empty value with n/a text
        if [ -n "$namsg" ]; then
            if [ "$namsg" != "_" ]; then
                # use specific n/a text
                format=$( echo $format | sed -r "s/##(.*)##/($namsg)/" | sed -r "s/\[.*\]//" )
            else
                # _ = skip
                sysf=""
            fi
        else
            # empty n/a text, use default text
            format=$( echo $format | sed -r "s/##(.*)##/(not available)/" | sed -r "s/\[.*\]//" )
        fi
        # output n/a text or skip
        [ -n "$sysf" ] && printf "$format\n" "$sysf"
    else
        # non empty value: strip delimiters from format str
        format=$( echo $format | sed -r "s/##(.*)##/\1/" )
        printf "$format\n" "$sysf" "$val"
    fi

    return 0
}

printparm_i915 () { # formatted output of sysfile - i915 kernel module variant
    # $1: sysfile; $2: alternative; $3: 1=psr/0=other
    local sysf val

    # Check if sysfile or alternative exist
    if [ -f $1 ]; then
        sysf=$1
    elif [ -f $2 ]; then
        sysf=$2
    else
        sysf=""
    fi

    if [ -n "$sysf" ]; then
        # sysfile exists, get content
        val=$(cat $sysf 2> /dev/null)
        if [ $? = 0 ]; then
            # sysfile was readable, output content
            printf "%-44s = %2d " "$sysf" "$val"
            # Explain content
            if [ "$val" = "-1" ]; then
                echo "(use per-chip default)"
            else
                echo -n "("
                if [ "$3" = "1" ]; then
                    # enable_psr
                    case $val in
                        0) echo -n "disabled" ;;
                        1) echo -n "enabled" ;;
                        2) echo -n "force link-standby mode" ;;
                        3) echo -n "force link-off mode" ;;
                        *) echo -n "unknown" ;;
                    esac
                else
                    # other parms
                    if [ $(( $val & 1 )) -ne 0 ]; then
                        echo -n "enabled"
                    else
                        echo -n "disabled"
                    fi
                    [ $(( $val & 2 )) -ne 0 ] && echo -n " + deep"
                    [ $(( $val & 4 )) -ne 0 ] && echo -n " + deepest"
                fi
                echo ")"
            fi
        else
            # sysfile was not readable
            printf "%-44s = (not available)\n" "$sysf"
        fi
    fi

    return 0
}

printsysf () { # output a sysfile
    # $1: format; $2: sysfile
    local val

    val=$(cat $2 2> /dev/null)
    if [ $? = 0 ]; then
         # sysfile readable
        printf "$1" "$val"
    else
        # sysfile not readable
        printf "$1" "(not available)"
    fi

    return 0
}

print_tp_batstate () { # print battery charging state with an explanation when
    # a threshold inhibits charging
    # $1: sysfile; $2: 1=ThinkPad battery/0=other
    local sysf val

    # Check if bat state sysfile exists
    if [ -f $1 ]; then
        sysf=$1
    else
        sysf=""
    fi

    if [ -n "$sysf" ]; then
        # bat state sysfile exists, get content
        val=$(cat $sysf 2> /dev/null)
        if [ $? = 0 ]; then
            # sysfile was readable, output content
            printf "%-59s = %s" "$sysf" "$val"
            # Explain content if necessary
            case $val in
                Unknown) # "Unknown" means a threshold forbids charging
                    printf " (threshold effective)\n"
                    ;;

                *) # Nothing to do
                    printf "\n"
                    ;;
            esac
        else
            # sysfile was not readable
            printf "%-59s = (not available)\n" "$sysf"
        fi
    else
        # sysfile nonexistent
        printf "%-59s = (not available)\n" "$1"
    fi

    return 0
}

print_tpacpi_thresholds () { # formatted output of ThinkPad charging thresholds
    # - tpcapi-bat variant
    # $1: BAT0/BAT1; $2: bat # = 1/2
    local start_thresh stop_thresh force

    read_tpacpi_threshold ST $2
    start_thresh=$?
    if [ $start_thresh -ne 255 ]; then
        [ $start_thresh -eq 0 ] && start_thresh=96
        printf "%-59s = %6d [%%]\n" "tpacpi-bat.${1}.startThreshold" "$start_thresh"
    else
        printf "%-59s = (not available)\n" "tpacpi-bat.${1}.startThreshold"
    fi

    read_tpacpi_threshold SP $2
    stop_thresh=$?
    if [ $stop_thresh -ne 255 ]; then
        [ $stop_thresh -eq  0 ] && stop_thresh=100
        printf "%-59s = %6d [%%]\n" "tpacpi-bat.${1}.stopThreshold" "$stop_thresh"
    else
        printf "%-59s = (not available)\n" "tpacpi-bat.${1}.stopThreshold"
    fi

    get_force_discharge $2; force=$?
    if [ $force -ne 2 ]; then
        printf "%-59s = %6d\n" "tpacpi-bat.${1}.forceDischarge" "$force"
    else
        printf "%-59s = %s\n" "tpacpi-bat.${1}.forceDischarge" "(not available)"
    fi

    return 0
}

print_file_modtime_and_age () { # show a file's last modification time
    #  and age in secs -- $1: file
    local mtime age

    if [ -f $1 ]; then
        mtime=$(date +%X -r $1)
        age=$(( $(date +%s) - $(date +%s -r $1) ))
        printf '%s, %6d sec(s) ago' "$mtime" "$age"
    else
        printf "unknown"
    fi
}

print_saved_powerstate () { # read and print saved state
    case "$(cat $PWRRUNFILE 2> /dev/null)" in
        0) echo "AC" ;;
        1) echo "battery" ;;
        *) echo "unknown" ;;
    esac

    return 0
}

check_ata_errors () { # check kernel log for ata errors
    # (possibly) caused by SATA_LINKPWR_ON_AC/BAT != max_performance
    # stdout: error count

    if wordinlist $SATA_LINKPWR_ON_BAT "min_power medium_power" || \
       wordinlist $SATA_LINKPWR_ON_AC "min_power medium_power"; then
        # config values != max_performance exist --> check kernel log

        # count matching error lines
        echo $( dmesg | egrep -c "${RE_ATA_ERROR}" 2> /dev/null )
    else
        # no values in question configured
        echo "0"
    fi

    return 0
}

# @stdout glob_files ( glob_pattern, dir[, dir...] )
#
#  Nested for-loop that applies a glob expression to several directories
#  (or file path prefixes) and prints matching file paths to stdout.
#
glob_files () {
    [ -n "${1-}" ] || return 64
    local glob_pattern file_iter

    glob_pattern="${1}"

    while shift && [ $# -gt 0 ]; do
        for file_iter in ${1}${glob_pattern}; do
            [ ! -f "${file_iter}" ] || echo "${file_iter}"
        done
    done
}

read_args () { # read command line arguments
    for a in $*; do
        case $a in
            "-b"|"--battery")
                show_all=0
                show_bat=1
                needs_root_priv=1
                ;;

            "-c"|"--config")
                show_all=0
                show_conf=1
                : ${needs_root_priv:=0}
                ;;

            "-d"|"--disk")
                show_all=0
                show_disk=1
                needs_root_priv=1
                ;;

            "-e"|"--pcie")
                show_all=0
                show_pcie=1
                : ${needs_root_priv:=0}
                ;;

            "-g"|"--graphics")
                show_all=0
                show_graf=1
                : ${needs_root_priv:=0}
                ;;

            "-p"|"--processor")
                show_all=0
                show_proc=1
                needs_root_priv=1
                ;;

            "-r"|"--rfkill")
                show_all=0
                show_rfkill=1
                : ${needs_root_priv:=0}
                ;;

            "-s"|"--system")
                show_all=0
                show_system=1
                : ${needs_root_priv:=0}
                ;;

            "-t"|"--temp")
                show_all=0
                show_temp=1
                : ${needs_root_priv:=0}
                ;;

            "-u"|"--usb")
                show_all=0
                show_usb=1
                : ${needs_root_priv:=0}
                ;;

            "-v"|"--verbose")
                show_verbose=1
                ;;

            "-w"|"--warn")
                show_all=0
                show_warn=1
                : ${needs_root_priv:=0}
                ;;

            "-P"|"--pev")
                show_all=0
                show_pev=1
                needs_root_priv=1
                ;;

            "--psup")
                show_all=0
                show_psup=1
                : ${needs_root_priv:=0}
                ;;

            "-T"|"--trace")
                show_all=0
                show_trace=1
                needs_root_priv=1
                ;;

            *)
                echo "Usage: tlp-stat [ -b | --battery   | -c | --config    |"
                echo "                  -d | --disk      | -e | --pcie      |"
                echo "                  -g | --graphics  | -p | --processor |"
                echo "                  -r | --rfkill    | -s | --system    |"
                echo "                  -t | --temp      | -u | --usb       |"
                echo "                  -w | --warn      | -v | --verbose   |"
                echo "                  -P | --pev       |    | --psup      |"
                echo "                  -T | --trace ]"
                exit 3
                ;;
        esac
    done
}

# --- Source libraries
for lib in $LIBS; do
    if [ ! -f $LIBDIR/$lib ]; then
        echo "Error: missing function library \'$LIBDIR/$lib\'." 1>&2
        exit 1
    fi
    . $LIBDIR/$lib
done

# --- MAIN
add_sbin2path

read_args $*
: ${needs_root_priv:=1}

# inhibit trace output
nodebug=1

# check for and read conffile
read_defaults
conf_present=$?

# check prerequisites
if [ "$needs_root_priv" = "1" ]; then
    check_root
    load_modules $MOD_MSR $MOD_TEMP
    check_thinkpad
    check_tpacpi
    check_tpsmapi
fi

echo "--- TLP $TLPVER --------------------------------------------"
echo

# --- show configuration
if [ "$show_conf" = "1" ] || [ "$show_all" = "1" ]; then
    if [ $conf_present -eq 0 ]; then
        echo "+++ Configured Settings: $CONFFILE"
        egrep -v '^#|^\s*$' $CONFFILE
        echo
    else
        echo "Error: config file $CONFFILE not present." 1>&2
        echo
    fi
fi # show_conf

if [ "$show_system" = "1" ] || [ "$show_all" = "1" ] ; then
    # --- show system info
    echo "+++ System Info"

    echo "System         = $( read_dmi sys_vendor product_version product_name )"
    echo "BIOS           = $( read_dmi bios_version )"

    # --- show release & kernel info
    cmd_exists $LSBREL && echo "Release        = $($LSBREL -d -s)"
    echo "Kernel         = $(uname -r -m -v)"
    printparm "%-14s = %s" /proc/cmdline

    # --- show init system info
    if check_systemd; then
        echo "Init system    = systemd $(systemd --version 2> /dev/null | sed -rn 's/systemd ([0-9]+)/v\1/p')"
    elif check_upstart; then
        echo "Init system    = upstart"
    elif check_openrc; then
        echo "Init system    = openrc"
    else
        echo "Init system    = sysvinit"
    fi
    if [ -d $EFID ]; then
        echo "Boot mode      = UEFI"
    else
        echo "Boot mode      = BIOS (CSM, Legacy)"
    fi
    echo

    # --- show TLP status
    echo "+++ TLP Status"
    if [ "$TLP_ENABLE" = "1" ]; then
        printf "State          = enabled\n"
    else
        printf "State          = disabled\n"
    fi

    # --- show last invocation time
    printf "Last run       = %s\n" "$(print_file_modtime_and_age ${LOCKFILE}_tlp)"

    # --- show actual power mode
    printf "Mode           = %s\n" "$(print_saved_powerstate)"

    # ---- show actual power source
    get_sys_power_supply
    case $? in
        0) printf "Power source   = AC\n" ;;
        1) printf "Power source   = battery\n" ;;
        *) printf "Power source   = unknown\n" ;;
    esac
    echo

    # -- check systemd service units status
    if check_systemd; then
        cnt=0
        for su in $SYSTEMD_SERVICES; do
            if ! $SYSTEMCTL is-enabled $su > /dev/null 2>&1 ; then
                echo "Notice: $su is not enabled -- invoke \"systemctl enable $su\" to correct this!"
                cnt=$((cnt+1))
            fi
        done
        for su in $RFKILL_SERVICES; do
            ise=$($SYSTEMCTL is-enabled $su 2> /dev/null)
            if [ -n "$ise" ] && [ "$ise" != "masked" ]; then
                echo "Notice: $su is not masked -- invoke \"systemctl mask $su\" to correct this!"
                cnt=$((cnt+1))
            fi
        done
        [ $cnt -gt 0 ] && echo
    fi

    # -- show warning if l-m-t detected
    check_laptop_mode_tools

fi # show_system

if [ "$show_proc" = "1" ] || [ "$show_all" = "1" ]; then
    # --- show cpu info
    echo "+++ Processor"
    sed -rn 's/model name[ \t]+: (.+)/CPU model      = \1/p' /proc/cpuinfo | head -1
    echo

    # -- show scaling gov and freq info
    for cpuf in /sys/devices/system/cpu/cpu*/cpufreq; do
        if [ -f $cpuf/scaling_driver ]; then
            printparm "%-54s = ##%s##" $cpuf/scaling_driver
            printparm "%-54s = ##%s##" $cpuf/scaling_governor
            printparm "%s = ##%s##" $cpuf/scaling_available_governors _

            if [ -f $cpuf/scaling_min_freq ]; then
                printf "%-54s = %8d [kHz]\n" "$cpuf/scaling_min_freq" "$(cat $cpuf/scaling_min_freq 2> /dev/null)"
            fi

            if [ -f $cpuf/scaling_max_freq ]; then
                printf "%-54s = %8d [kHz]\n" "$cpuf/scaling_max_freq" "$(cat $cpuf/scaling_max_freq 2> /dev/null)"
            fi

            if [ -f $cpuf/scaling_available_frequencies ]; then
                printf "%s = " "$cpuf/scaling_available_frequencies"
                for freq in $(cat $cpuf/scaling_available_frequencies 2> /dev/null); do
                    printf "%s " "$freq"
                done
                printf "[kHz]\n"
            fi

            if [ -f $cpuf/energy_performance_preference ]; then
                printparm "%s = ##%s##" $cpuf/energy_performance_preference
            fi
            if [ -f $cpuf/energy_performance_available_preferences ]; then
                printparm "%s = ##%s##" $cpuf/energy_performance_available_preferences
            fi

            printf "\n"
        fi
    done

    check_intel_pstate

    if [ $intel_pstate -eq 1 ]; then
        # show Intel P-state info
        printparm "%-54s = ##%3d## [%%]" $CPU_MIN_PERF_PCT
        printparm "%-54s = ##%3d## [%%]" $CPU_MAX_PERF_PCT
        printparm "%-54s = ##%3d##"      $CPU_TURBO_PSTATE
        printparm "%-54s = ##%3d## [%%]" $INTEL_PSTATED/turbo_pct
        printparm "%-54s = ##%3d##"      $INTEL_PSTATED/num_pstates

    elif [ -f $CPU_BOOST_ALL_CTRL ]; then
        # show turbo boost info
        get_sysval $CPU_BOOST_ALL_CTRL; boost=$?

        # simple test for attribute "w" doesn't work, so actually write
        if { printf '%s\n' "$boost" > $CPU_BOOST_ALL_CTRL; } 2> /dev/null; then
            printparm "%-54s = ##%d##" $CPU_BOOST_ALL_CTRL
        else
            printparm "%-54s = ##%d## (cpu not supported)" $CPU_BOOST_ALL_CTRL
        fi
    else
         printparm "%-54s = (not available)" $CPU_BOOST_ALL_CTRL
    fi

    # --- show sched power save info
    for pool in mc smp smt; do
        sdev="/sys/devices/system/cpu/sched_${pool}_power_savings"
        printparm "%-54s = ##%d##" $sdev _
    done
    echo

    # --- show x86 energy perf policy info
    if cmd_exists $ENERGYPERF; then
        # check CPU support
        $ENERGYPERF -r > /dev/null 2>&1
        case $? in
            0)  # parse x86_energy_perf_policy output:
                # - replace numbers with descriptive strings
                # - remove ":"
                # - indent and align
                $ENERGYPERF -r 2>/dev/null | \
                    sed -r 's/://;
                            s/(0x0000000000000000|EPB 0)/performance/;
                            s/(0x0000000000000004|EPB 4)/balance-performance/;
                            s/(0x0000000000000006|EPB 6)/default/;
                            s/(0x0000000000000008|EPB 8)/balance-power/;
                            s/(0x000000000000000f|EPB 15)/power/' | \
                    awk '{ printf "x86_energy_perf_policy.%-31s = %s %s\n", $1, $2, $3; }'
                ;;

            1) echo "x86_energy_perf_policy: unsupported CPU." ;;
            2) echo "x86_energy_perf_policy: program for your kernel not installed." ;;
            *) echo "x86_energy_perf_policy: not available." ;;
        esac
        echo
    else
        echo "x86_energy_perf_policy: program not installed."
        echo
    fi

    # --- show workqueue power efficient status
    printparm "%-54s = ##%s##" $WQPE

    # --- show nmi watchdog
    printparm "%-54s = ##%d##" $NMIWD
    echo

    # --- show voltages
    echo "+++ Undervolting"
    phc_avail=0
    for cpuf in /sys/devices/system/cpu/cpu*/cpufreq; do
        if [ -f $cpuf/phc_controls ]; then
            phc_avail=1
            printparm "%-58s = ##%s##" $cpuf/phc_controls
            printparm "%-58s = ##%s##" $cpuf/phc_default_controls
            echo
        fi
    done
    if [ $phc_avail = 0 ]; then
        echo "PHC kernel not available."
        echo
    fi
fi # show_proc

if [ "$show_temp" = "1" ] || [ "$show_all" = "1" ]; then
    # --- show temperatures
    echo "+++ Temperatures"
    if [ -f $IBMTHERMAL ]; then
        # use thinkpad-specific sysfile
        echo "$IBMTHERMAL = $(cat $IBMTHERMAL 2> /dev/null | cut -f2  ) [°C]"
    else
        # use sensors
        cmax=0
        for sens in $(glob_files '/temp?*_input' $CORETEMP_DIRS); do
            if grep -q -- 'Physical' ${sens%input}label 2>/dev/null; then
                # package info is available -> ignore remaining sensors
                read -r cmax < $sens
                break
            else
                # core info -> find max value
                read -r ctemp < $sens && [ $ctemp -gt $cmax ] && cmax=$ctemp
            fi
        done
        if [ $cmax -gt 0 ]; then
            perl -e 'printf ("CPU temp               = %5d [°C]\n", '$cmax' / 1000.0);'
        fi

    fi

    # --- show fan speed
    if is_thinkpad && [ -f $IBMFAN ]; then
        # use thinkpad-specific sysfile
        awk '$1 ~ /speed:/ { printf "'$IBMFAN'     = %5d [/min]\n", $2 }' $IBMFAN
    else
        # use hwmon
        have_any_fan=
        for fan in $(glob_files '/fan?*_input' $HWMONFAN_DIRS); do
            if read -r fan_speed < $fan; then
                fan_name="${fan##*/}"; fan_name="${fan_name%_input}"
                have_any_fan=y

                printf "Fan speed (%s)       = %5d [/min]\n" \
                    "${fan_name}" "${fan_speed}"
            fi
        done
        if [ -z "${have_any_fan}" ]; then
            printf "Fan speed              = (not available)\n"
        fi
    fi
    echo
fi # show_temp

if [ "$show_all" = "1" ]; then
    # --- show laptop-mode, dirty buffers params
    echo "+++ File System"
    printparm "%-38s = ##%5d##" /proc/sys/vm/laptop_mode
    printparm "%-38s = ##%5d##" /proc/sys/vm/dirty_writeback_centisecs
    printparm "%-38s = ##%5d##" /proc/sys/vm/dirty_expire_centisecs
    printparm "%-38s = ##%5d##" /proc/sys/vm/dirty_ratio
    printparm "%-38s = ##%5d##" /proc/sys/vm/dirty_background_ratio
    printparm "%-38s = ##%5d##" /proc/sys/fs/xfs/age_buffer_centisecs _
    printparm "%-38s = ##%5d##" /proc/sys/fs/xfs/xfssyncd_centisecs _
    printparm "%-38s = ##%5d##" /proc/sys/fs/xfs/xfsbufd_centisecs _
    echo
fi # show_all

if [ "$show_disk" = "1" ] || [ "$show_all" = "1" ]; then
    # --- show disk info form hdparm
    echo "+++ Storage Devices"
    : ${DISK_DEVICES:=${DEFAULT_DISK_DEVICES}}
    for dev in $DISK_DEVICES; do # iterate all devices
        get_disk_dev $dev

        if [ -b /dev/$disk_dev ]; then
            get_disk_state $disk_dev
            check_disk_hdparm_cap $disk_dev
            if [ $? = 0 ]; then
                echo "/dev/$disk_dev:"

                if [ -n "$disk_id" ]; then
                    echo "  Disk ID   = $disk_id"
                fi

                echo -n "  Model     = "
                echo_disk_model $disk_dev

                echo -n "  Firmware  = "
                echo_disk_firmware $disk_dev

                get_disk_apm_level $disk_dev
                apm=$?
                echo -n "  APM Level = "
                case $apm in
                    0|255) echo "none/disabled" ;;
                    *)     echo $apm ;;
                esac

                echo "  Status    = $disk_state"

                get_disk_trim_capability $disk_dev
                trim=$?
                case $trim in
                    0) echo "  TRIM      = not supported" ;;
                    1) echo "  TRIM      = supported" ;;
                esac

                if [ -f /sys/block/$disk_dev/queue/scheduler ]; then
                    sched="$(cat /sys/block/$disk_dev/queue/scheduler 2> /dev/null | sed -r 's/.*\[(.*)\].*/\1/')"
                    if [ "$sched" = "none" ] && [ -d /sys/block/$disk_dev/mq ]; then
                        sched="blk-mq"
                    fi
                    printf "  Scheduler = %s\n" "$sched"
                fi

                ddev=/sys/block/$disk_dev/device/power
                if [ -f $ddev/control ]; then
                    echo
                    printsysf "  Runtime PM: control = %s, " $ddev/control
                    printsysf "autosuspend_delay = %4s\n"    $ddev/autosuspend_delay_ms
                fi

                if cmd_exists $SMARTCTL ; then
                    # --- show SMART data
                    echo
                    echo "  SMART info:"
                    $SMARTCTL -A /dev/$disk_dev | grep -v '<==' | \
                      awk -F ' ' '$2 ~ /Power_Cycle_Count|Start_Stop_Count|Load_Cycle_Count|Reallocated_Sector_Ct/ \
                                        { printf "    %3d %-25s = %8d \n", $1, $2, $10 } ; \
                                  $2 ~ /Used_Rsvd_Blk_Cnt_Chip|Used_Rsvd_Blk_Cnt_Tot|Unused_Rsvd_Blk_Cnt_Tot/ \
                                        { printf "    %3d %-25s = %8d \n", $1, $2, $10 } ; \
                                  $2 ~ /Power_On_Hours/ \
                                        { printf "    %3d %-25s = %8d %s\n", $1, $2, $10, "[h]" } ; \
                                  $2 ~ /Temperature_Celsius/ \
                                        { printf "    %3d %-25s = %8d %s %s %s %s\n", $1, $2, $10, $11, $12, $13, "[°C]" } ; \
                                  $2 ~ /Airflow_Temperature_Cel/ \
                                        { printf "    %3d %-25s = %8d %s\n", $1, $2, $10, "[°C]" } ; \
                                  $2 ~ /G-Sense_Error_Rate/ \
                                        { printf "    %3d %-25s = %8d \n", $1, $2, $10 } ; \
                                  $2 ~ /Host_Writes/ \
                                        { printf "    %3d %-25s = %8.3f %s\n", $1, $2, $10 / 32768.0, "[TB]" } ; \
                                  $2 ~ /Total_LBAs_Written/ \
                                        { printf "    %3d %-25s = %8.3f %s\n", $1, $2, $10 / 2147483648.0, "[TB]" } ; \
                                  $2 ~ /NAND_Writes_1GiB/ \
                                        { printf "    %3d %-25s = %8d %s\n", $1, $2, $10, "[GB]" } ; \
                                  $2 ~ /Available_Reservd_Space|Media_Wearout_Indicator|Wear_Leveling_Count/ \
                                        { printf "    %3d %-25s = %8d %s\n", $1, $2, $4, "[%]" }'
                fi
                echo

                # restore standby state
                [ "$disk_state" = "standby" ] && spindown_disk $disk_dev
            fi
        fi
    done
    echo

    # --- show sata alpm mode
    echo "+++ AHCI Link Power Management (ALPM)"
    if stat -t /sys/class/scsi_host/host*/link_power_management_policy > /dev/null 2>&1; then
        for i in /sys/class/scsi_host/host* ; do
            printparm "%-56s = ##%s##" $i/link_power_management_policy _
        done
    else
        echo "No AHCI-enabled host controller detected."
    fi
    echo

    # --- show ahci runtime pm
    if stat -t ${AHCID}/power > /dev/null 2>&1; then
        echo "+++ AHCI Host Controller Runtime Power Management"
        for dev in ${AHCID}/power ; do
            printparm "%-40s = ##%s##" $dev/control
        done
        echo
    fi

    # -- show docks
    cnt=0
    for dock in $DOCKGLOB; do
        [ ! -d $dock ] && break # no dock/bay detected

        # dock/bay detected, print header
        [ $cnt -eq 0 ] && echo "+++ Docks and Device Bays"
        cnt=$((cnt+1))

        # get dock type
        { read -r dock_type < $dock/type; } 2>/dev/null

        # get dock state
        if check_is_docked; then
            # docked
            case $dock_type in
                ata_bay)      dock_state="drive present" ;;
                battery_bay)  dock_state="battery present" ;;
                dock_station) dock_state="docked" ;;

                *)  dock_state="docked"
                    dock_type="unknown"
                    ;;
            esac
        else
            # not docked
            case $dock_type in
                ata_bay)      dock_state="no drive (or powered off)" ;;
                battery_bay)  dock_state="no battery " ;;
                dock_station) dock_state="undocked" ;;

                *)  dock_state="undocked"
                    dock_type="unknown"
                    ;;
            esac
        fi

        # print dock data
        printf "%s: %-13s = %s\n" "$dock" "$dock_type" "$dock_state"
    done
    [ $cnt -gt 0 ] && echo
fi # show_disk

if [ "$show_all" = "1" ]; then
    # --- show pcie aspm state
    echo "+++ PCIe Active State Power Management"
    if [ -f $ASPM ]; then
        pol=$(cat $ASPM 2> /dev/null | sed -r 's/.*\[(.*)\].*/\1/')
        { printf '%s' "$pol" > $ASPM; } 2> /dev/null
        if [ $? = 0 ]; then
            echo "$ASPM = $pol"
        else
            echo "$ASPM = $pol (using bios preferences)"
        fi
    else
        echo "$ASPM = (not available)"
    fi
    echo
fi # show_all

if [ "$show_graf" = "1" ] || [ "$show_all" = "1" ]; then
    # --- show i915 power mgmt
    for card in $I915D; do
        if [ -d $card ]; then
            echo "+++ Intel Graphics"
            printparm_i915 $card/powersave
            printparm_i915 $card/enable_rc6 $card/i915_enable_rc6
            printparm_i915 $card/enable_dc
            printparm_i915 $card/enable_fbc $card/i915_enable_fbc
            printparm_i915 $card/enable_psr "" 1
            printparm_i915 $card/lvds_downclock
            printparm_i915 $card/modeset
            printparm_i915 $card/semaphores
            echo
        fi
    done

    # --- show radeon power profile or dpm state
    if [ -d $RADD ]; then
        for card in /sys/class/drm/card[0-9]/device ; do
            if [ -f $card/power_dpm_state ] && [ -f $card/power_dpm_force_performance_level ]; then
                # Use new radeon dpm state
                echo "+++ Radeon Graphics"
                printparm "%-25s = ##%s##" $card/power_dpm_state
                printparm "%-25s = ##%s##" $card/power_dpm_force_performance_level
                echo
                break

            elif [ -f $card/power_method ] && [ -f $card/power_profile ]; then
                # Use old radeon power profile
                echo "+++ Radeon Graphics"
                printparm "%-25s = ##%s##" $card/power_method
                printparm "%-25s = ##%s##" $card/power_profile
                echo
                break
            fi
        done
    fi
fi # show_graf

if [ "$show_rfkill" = "1" ] || [ "$show_all" = "1" ]; then
    echo "+++ Wireless"
    # --- show rfkill state
    for i in bluetooth wifi wwan; do
        get_devc $i
        get_devs $i
        echo_device_state $i $devs
    done
    echo

    ifshown=0

    # --- show bluetooth
    get_bluetooth_ifaces
    for iface in $bifaces; do
        if [ -n "$iface" ]; then
            ifshown=1

            # get bluetooth driver
            get_bluetooth_driver $iface
            printf "%-30s: bluetooth, " "$iface($bluetoothdrv)"
            if bluetooth_in_use $iface; then
                echo "connected"
            else
                echo "not connected"
            fi
        fi
    done

    # --- show wifi data
    get_wifi_ifaces
    for iface in $wifaces; do
        if [ -n "$iface" ]; then
            ifshown=1

            # get wifi power mgmt state
            wifipm=""
            if [ "$X_DONT_USE_IW" != "1" ] && cmd_exists $IW; then
                # try with iw first
                wifipm=$($IW dev $iface get power_save 2> /dev/null | \
                    grep "Power save" | \
                    sed -r 's/.*Power save: (on|off).*/\1/')
            fi
            if cmd_exists $IWC; then
                if [ -z "$wifipm" ]; then
                    # iw did not succeed or iw not installed -> try with iwconfig
                    wifipm=$($IWC $iface 2> /dev/null | \
                        grep "Power Management" | \
                        sed -r 's/.*Power Management:(on|off).*/\1/')
                fi
            fi

            # get wifi driver
            get_wifi_driver $iface
            printf "%-30s: wifi, " "$iface($wifidrv)"
            if wireless_in_use $iface; then
                printf "connected, "
            else
                printf "not connected, "
            fi
            printf "power management = "
            case $wifipm in
                on|off) printf "$wifipm" ;;
                *)      printf "unknown" ;;
            esac
            printf "\n"
        fi
    done

    # --- show wwan data
    get_wwan_ifaces
    for iface in $wanifaces; do
        if [ -n "$iface" ]; then
            ifshown=1

            # get wwan driver
            get_wwan_driver $iface

            printf "%-30s: wwan, " "$iface($wwandrv)"
            if wireless_in_use $iface; then
                printf "connected"
            else
                printf "not connected"
            fi
            printf "\n"
        fi
    done
    [ "$ifshown" = "1" ] && echo

fi # show_rfkill

if [ "$show_all" = "1" ]; then
    # --- show sound power mode
    echo "+++ Audio"
    if [ -d /sys/module/snd_hda_intel ]; then
        printparm "%-58s = ##%s##" /sys/module/snd_hda_intel/parameters/power_save
        printparm "%-58s = ##%s##" /sys/module/snd_hda_intel/parameters/power_save_controller
    fi
    if [ -d /sys/module/snd_ac97_codec ]; then
        printparm "%s = ##%s##" /sys/module/snd_ac97_codec/parameters/power_save
    fi
    echo
fi # show_all

if [ "$show_pcie" = "1" ] || [ "$show_all" = "1" ]; then
    # -- show runtime pm
    echo "+++ Runtime Power Management"
    echo "Device blacklist = ${RUNTIME_PM_BLACKLIST:=(not configured)}"
    pmdbl="${RUNTIME_PM_DRIVER_BLACKLIST-${DEFAULT_PM_DRIVER_BLACKLIST} (default)}"
    echo "Driver blacklist = ${pmdbl:-(disabled)}"
    echo

    if cmd_exists $TLPPCI; then
        $TLPPCI
        [ $? -eq 4 ] && no_runtimepm=1
    else
        echo "Error: missing subcommand $TLPPCI." 1>&2
    fi
    echo

fi # show_pcie

if [ "$show_usb" = "1" ] || [ "$show_all" = "1" ]; then
    # -- show usb autosuspend
    echo "+++ USB"
    if [ "$USB_AUTOSUSPEND" = "1" ]; then
        echo "Autosuspend         = enabled"
    else
        echo "Autosuspend         = disabled"
    fi
    echo "Device whitelist    = ${USB_WHITELIST:=(not configured)}"
    echo "Device blacklist    = ${USB_BLACKLIST:=(not configured)}"
    if [ "${USB_BLACKLIST_BTUSB:-0}" = "1" ]; then
        echo "Bluetooth blacklist = enabled"
    else
        echo "Bluetooth blacklist = disabled"
    fi
    if [ "${USB_BLACKLIST_PHONE:-0}" = "1" ]; then
        echo "Phone blacklist     = enabled"
    else
        echo "Phone blacklist     = disabled"
    fi
    if [ "${USB_BLACKLIST_WWAN:-1}" = "1" ]; then
        echo "WWAN blacklist      = enabled"
    else
        echo "WWAN blacklist      = disabled"
    fi
    if [ -n "$USB_DRIVER_BLACKLIST" ] && [ "$USB_DRIVER_BLACKLIST" != "usbhid" ]; then
        echo "Notice: USB_DRIVER_BLACKLIST is no longer supported, use USB_BLACKLIST."
    fi
    echo

    if cmd_exists $TLPUSB; then
        $TLPUSB
        [ $? -eq 4 ] && no_runtimepm=1
    else
        echo "Error: missing subcommand $TLPUSB." 1>&2
    fi
    echo

fi # show_usb

if [ "$show_bat" = "1" ] || [ "$show_all" = "1" ]; then
    # --- show battery info & charge thresholds
    bcnt=0
    efsum=0
    ensum=0

    # --- show availability of ThinkPad battery features
    if is_thinkpad; then
        echo "+++ ThinkPad Battery Features"
        echo -n "tp-smapi   = "
        case $tpsmapi in
            0)   echo "active" ;;
            2)   echo "inactive (kernel module 'tp_smapi' load error)" ;;
            127) echo "inactive (kernel module 'tp_smapi' not installed)" ;;
            255) echo "inactive (unsupported hardware)" ;;
            *)   echo "unknown status"
        esac

        echo -n "tpacpi-bat = "
        case $tpacpi in
            0)   echo "active" ;;
            2)   echo "inactive (kernel module 'acpi_call' load error)" ;;
            4)   echo "inactive (disabled by user configuration)" ;;
            127) echo "inactive (kernel module 'acpi_call' not installed)" ;;
            255) echo "inactive (unsupported hardware)" ;;
        esac
        echo
    fi

    if [ $tpsmapi -eq 0 ]; then
        # it's a ThinkPad with tp-smapi

        for batd in $SMAPIDIR/BAT[01]; do
            if [ -d $batd ]; then
                batt=${batd##/*/}

                if check_tp_battery $batt; then # battery is present
                    case $bat_idx in
                        1) echo "+++ ThinkPad Battery Status: $batt (Main / Internal)" ;;
                        2) echo "+++ ThinkPad Battery Status: $batt (Ultrabay / Slice / Replaceable)" ;;
                        0) echo "+++ ThinkPad Battery Status: $batt" ;;
                    esac

                    printparm "%-59s = ##%s##" $batd/manufacturer
                    printparm "%-59s = ##%s##" $batd/model
                    printparm "%-59s = ##%s##" $batd/manufacture_date
                    printparm "%-59s = ##%s##" $batd/first_use_date
                    printparm "%-59s = ##%6d##" $batd/cycle_count

                    if [ -f $batd/temperature ]; then
                        perl -e 'printf ("%-59s = %6d [°C]\n", "'$batd/temperature'", '$(catsysfd $batd/temperature 0)' / 1000.0);'
                    fi

                    printparm "%-59s = ##%6d## [mWh]" $batd/design_capacity
                    printparm "%-59s = ##%6d## [mWh]" $batd/last_full_capacity
                    printparm "%-59s = ##%6d## [mWh]" $batd/remaining_capacity
                    printparm "%-59s = ##%6d## [%%]" $batd/remaining_percent
                    printparm "%-59s = ##%6s## [min]" $batd/remaining_running_time_now
                    printparm "%-59s = ##%6s## [min]" $batd/remaining_charging_time
                    printparm "%-59s = ##%6d## [mW]" $batd/power_now
                    printparm "%-59s = ##%6d## [mW]" $batd/power_avg
                    print_tp_batstate $batd/state
                    echo
                    if [ $show_verbose -eq 1 ]; then
                        printparm "%-59s = ##%6s## [mV]" $batd/design_voltage
                        printparm "%-59s = ##%6s## [mV]" $batd/voltage
                        printparm "%-59s = ##%6s## [mV]" $batd/group0_voltage
                        printparm "%-59s = ##%6s## [mV]" $batd/group1_voltage
                        printparm "%-59s = ##%6s## [mV]" $batd/group2_voltage
                        printparm "%-59s = ##%6s## [mV]" $batd/group3_voltage
                        echo
                    fi

                    if [ $tpacpi -eq 0 ]; then
                        # --- show ThinkPad charge thresholds via tpacpi-bat
                        print_tpacpi_thresholds $batt $bat_idx
                    else
                        # show thresholds via tp-smapi
                        printparm "%-59s = ##%6d## [%%]" $batd/start_charge_thresh
                        printparm "%-59s = ##%6d## [%%]" $batd/stop_charge_thresh
                        printparm "%-59s = ##%6d##" $batd/force_discharge
                    fi
                    echo

                    # store values for charge / capacity calculation below
                    ed=$(catsysfd $batd/design_capacity 0)
                    ef=$(catsysfd $batd/last_full_capacity 0)
                    en=$(catsysfd $batd/remaining_capacity 0)
                    efsum=$(($efsum + $ef))
                    ensum=$(($ensum + $en))

                    # show charge + capacity
                    lcnt=0
                    if [ $ef -ne 0 ]; then
                        perl -e 'printf ("%-59s = %6.1f [%%]\n", "Charge",   100.0 * '$en' / '$ef');'
                        lcnt=$(($lcnt+1))
                    fi
                    if [ $ed -ne 0 ]; then
                        perl -e 'printf ("%-59s = %6.1f [%%]\n", "Capacity", 100.0 * '$ef' / '$ed');'
                        lcnt=$(($lcnt+1))
                    fi
                    [ $lcnt -gt 0 ] && echo

                    bcnt=$(($bcnt+1))
                fi
            fi
        done
    elif [ -d $ACPIBATDIR ]; then
        # --- show ACPI data

        for batd in $ACPIBATDIR/*; do
            batt=${batd##/*/}
            tpbat=0

            if check_tp_battery $batt; then
                # ThinkPad battery is present
                tpbat=1

                if [ $tpacpi -eq 0 ]; then
                    # it's a ThinkPad with tpacpi-bat only
                    case $bat_idx in
                        1) echo "+++ ThinkPad Battery Status: $batt (Main / Internal)" ;;
                        2) echo "+++ ThinkPad Battery Status: $batt (Ultrabay / Slice / Replaceable)" ;;
                        0) echo "+++ ThinkPad Battery Status: $batt" ;;
                    esac
                else
                   # it's a ThinkPad with neither tp-smapi nor tpacpi-bat
                    echo "+++ Battery Status"
                fi
            elif [ -d $batd ] \
                 && [ "$(cat $batd/type 2> /dev/null)" = "Battery" ] \
                 && [ "$(cat $batd/present 2> /dev/null )" = "1" ]; then
                    # it's some other laptop model or brand
                    echo "+++ Battery Status"
            else
                batt="" # power supply is not a battery
            fi

            if [ -n "$batt" ]; then
                printparm "%-59s = ##%s##" $batd/manufacturer
                printparm "%-59s = ##%s##" $batd/model_name

                cc=$(cat $batd/cycle_count 2> /dev/null)
                if [ $? -eq 0 ] && [ -n "$cc" ] && [ $cc -gt 0 ]; then
                    printf "%-59s = %6d\n" "$batd/cycle_count" "$cc"
                else
                    printf "%-59s = (not supported)\n" "$batd/cycle_count"
                fi

                if [ -f $batd/energy_full ]; then
                    printparm "%-59s = ##%6d## [mWh]" $batd/energy_full_design "" 000
                    printparm "%-59s = ##%6d## [mWh]" $batd/energy_full "" 000
                    printparm "%-59s = ##%6d## [mWh]" $batd/energy_now "" 000
                    printparm "%-59s = ##%6d## [mW]" $batd/power_now "" 000

                    # store values for charge / capacity calculation below
                    ed=$(catsysfd $batd/energy_full_design 0)
                    ef=$(catsysfd $batd/energy_full 0)
                    en=$(catsysfd $batd/energy_now 0)
                    efsum=$(($efsum + $ef))
                    ensum=$(($ensum + $en))

                elif [ -f $batd/charge_full ]; then
                    printparm "%-59s = ##%6d## [mAh]" $batd/charge_full_design "" 000
                    printparm "%-59s = ##%6d## [mAh]" $batd/charge_full "" 000
                    printparm "%-59s = ##%6d## [mAh]" $batd/charge_now "" 000
                    printparm "%-59s = ##%6d## [mA]" $batd/current_now "" 000

                    # store values for charge / capacity calculation below
                    ed=$(catsysfd $batd/charge_full_design 0)
                    ef=$(catsysfd $batd/charge_full 0)
                    en=$(catsysfd $batd/charge_now 0)
                    efsum=$(($efsum + $ef))
                    ensum=$(($ensum + $en))

                else
                    ed=0
                    ef=0
                    en=0

                fi
                if [ $tpbat -eq 1 ]; then
                    print_tp_batstate $batd/status
                else
                    printparm "%-59s = ##%s##" $batd/status
                fi
                echo

                if [ $show_verbose -eq 1 ]; then
                    printparm "%-59s = ##%6s## [mV]" $batd/voltage_min_design "" 000
                    printparm "%-59s = ##%6s## [mV]" $batd/voltage_now "" 000
                    echo
                fi

                if [ $tpacpi -eq 0 ]; then
                    # --- show ThinkPad charge thresholds via tpacpi-bat
                    print_tpacpi_thresholds $batt $bat_idx
                    echo
                fi # if $tpcacpi

                # show charge + capacity
                lcnt=0
                if [ $ef -ne 0 ]; then
                    perl -e 'printf ("%-59s = %6.1f [%%]\n", "Charge",   100.0 * '$en' / '$ef');'
                    lcnt=$(($lcnt+1))
                fi
                if [ $ed -ne 0 ]; then
                    perl -e 'printf ("%-59s = %6.1f [%%]\n", "Capacity", 100.0 * '$ef' / '$ed');'
                    lcnt=$(($lcnt+1))
                fi
                [ $lcnt -gt 0 ] && echo

                bcnt=$(($bcnt+1))
            fi # if $batt
        done # $batd

    fi # if /sys/class/power_supply

    if [ $bcnt -eq 0 ]; then
        # no battery detected
        printf "+++ Battery Status\n"
        printf "No batteries detected.\n\n"
    elif [ $bcnt -gt 1 ] && [ $efsum -ne 0 ]; then
        # more than one battery detected --> show charge total
        perl -e 'printf ("%-59s = %6.1f [%%]\n", "+++ Charge total",   100.0 * '$ensum' / '$efsum');'
        echo
    fi

fi # show_bat

if [ "$show_warn" = "1" ] || [ "$show_disk" = "1" ] || [ "$show_all" = "1" ]; then
    # --- show warnings
    # ata errors (possibly) caused by SATA_LINKPWR_ON_AC/BAT != max_performance
    ecnt=$( check_ata_errors )
    if [ $ecnt -ne 0 ]; then
        echo "+++ Warnings"
        printf "* Kernel log shows ata errors (%d) possibly caused by the configuration\n" $ecnt
        printf "  SATA_LINKPWR_ON_AC/BAT=min_power or medium_power.\n"
        printf "  Consider using medium_power or max_performance instead.\n"
        printf "  See the FAQ: http://linrunner.de/en/tlp/docs/tlp-faq.html#warnings\n"
        printf "  Details:\n"
        dmesg | egrep -A 5 "${RE_ATA_ERROR}"
        echo
    elif [ "$show_warn" = "1" ]; then
        echo "No warnings detected."
        echo ""
    fi

fi # show_warn

if [ "$show_all" = "1" ]; then
    # -- show suggestions
    suout=""

    if [ "$no_runtimepm" = "1" ]; then
        suout="${suout}Reconfigure your Linux kernel with PM_RUNTIME=y to reduce your laptop's power consumption.\n"
    fi

    if is_thinkpad; then
        # add ThinkPad specific suggestions -- $tpmodel preset by check_thinkpad()
        if supports_tpsmapi_only; then
            # tp-smapi only capable models
            [ $tpsmapi -eq 127 ] && suout="${suout}Install tp-smapi kernel modules for ThinkPad battery features\n"

        elif supports_tpacpi_only; then
            # tpacpi-bat only capable models
            [ $tpacpi -eq 127 ] && suout="${suout}Install acpi-call kernel module for ThinkPad battery features\n"

        elif supports_tpsmapi_and_tpacpi; then
            # tp-smapi and tpacpi-bat capable models
            [ $tpsmapi -eq 127 ] && suout="${suout}Install tp-smapi kernel modules for ThinkPad battery features\n"
            [ $tpacpi -eq 127 ]  && suout="${suout}Install acpi-call kernel module for ThinkPad battery features\n"

        elif supports_no_tp_bat_funcs; then
            : # models that are neither tp_smapi nor tpacpi-bat capable

        else
            # all others assumed tp-smapi capable ...
            [ $tpsmapi -eq 127 ] && suout="${suout}Install tp-smapi kernel modules for ThinkPad battery features\n"

        fi
    fi # if ThinkPad

    # add other suggestions
    cmd_exists ethtool || suout="${suout}Install ethtool to disable Wake On LAN (WOL)\n"
    cmd_exists smartctl || suout="${suout}Install smartmontools for disk drive health info\n"

    if [ -n "$suout" ]; then
        echo "+++ Suggestions"
        printf "$suout" | sed -r 's/^/\* /'
        echo
    fi

fi # show_all

if [ "$show_pev" = "1" ]; then
    # --- show udev power_supply events

    # check for udevadm
    if cmd_exists $UDEVADM; then
        echo "+++ Monitor power supply events -- cancel with ^C"
        echo
        $UDEVADM monitor --udev --property --subsystem-match=power_supply
    fi
fi # show_pev

if [ "$show_psup" = "1" ]; then
    # --- show power_supply diagnostic
    echo "+++ Power supply diagnostic"
    for ps in /sys/class/power_supply/*; do
        grep -s '.*' $ps/type $ps/online $ps/present $ps/device/path
    done
fi # show_sup

if [ "$show_trace" = "1" ]; then
    # --- show debug log

    # check for systemd journal
    jdone=0
    if cmd_exists $JOURNALCTL; then
        # retrieve trace output from journal
        $JOURNALCTL -p debug --no-pager SYSLOG_IDENTIFIER=tlp 2> /dev/null
        # check result -- rc=1 if journald has no data available
        [ $? -eq 0 ] && jdone=1
    fi

    if [ "$jdone" = "0"  ]; then
        # no journald data available --> retrieve trace output from logfile
        if [ -f $DEBUGLOG ]; then
            grep "tlp\[" $DEBUGLOG
        else
            echo "Error: $DEBUGLOG does not exist." 1>&2
            echo 1>&2
            echo "Solution: create an rsyslog conffile /etc/rsyslog.d/90-debug.conf with the following contents" 1>&2
            echo " *.=debug;\\" 1>&2
            echo " mail,authpriv,cron.none;\\" 1>&2
            echo " local0,local1,local3,local4,\\" 1>&2
            echo " local5,local6,local7.none    -/var/log/debug" 1>&2
            echo "and restart the rsyslog daemon." 1>&2
            echo 1>&2
        fi
    fi
fi # show_trace

exit 0