LyoKICoJUENJIGhhbmRsaW5nIG9mIEkyTyBjb250cm9sbGVyCiAqCiAqIAlDb3B5cmlnaHQgKEMpIDE5OTktMjAwMglSZWQgSGF0IFNvZnR3YXJlCiAqCiAqCVdyaXR0ZW4gYnkgQWxhbiBDb3gsIEJ1aWxkaW5nIE51bWJlciBUaHJlZSBMdGQKICoKICoJVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICoJdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlCiAqCUZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24gMiBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIKICoJb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICoJQSBsb3Qgb2YgdGhlIEkyTyBtZXNzYWdlIHNpZGUgY29kZSBmcm9tIHRoaXMgaXMgdGFrZW4gZnJvbSB0aGUgUmVkCiAqCUNyZWVrIFJDUENJNDUgYWRhcHRlciBkcml2ZXIgYnkgUmVkIENyZWVrIENvbW11bmljYXRpb25zCiAqCiAqCUZpeGVzL2FkZGl0aW9uczoKICoJCVBoaWxpcHAgUnVtcGYKICoJCUp1aGEgU2llduRuZW4gPEp1aGEuU2lldmFuZW5AY3MuSGVsc2lua2kuRkk+CiAqCQlBdXZvIEjka2tpbmVuIDxBdXZvLkhha2tpbmVuQGNzLkhlbHNpbmtpLkZJPgogKgkJRGVlcGFrIFNheGVuYSA8ZGVlcGFrQHBsZXhpdHkubmV0PgogKgkJQm9qaSBUIEthbm5hbnRoYW5hbSA8Ym9qaS50Lmthbm5hbnRoYW5hbUBpbnRlbC5jb20+CiAqCQlBbGFuIENveCA8YWxhbkByZWRoYXQuY29tPjoKICoJCQlQb3J0ZWQgdG8gTGludXggMi41LgogKgkJTWFya3VzIExpZGVsIDxNYXJrdXMuTGlkZWxAc2hhZG93Y29ubmVjdC5jb20+OgogKgkJCU1pbm9yIGZpeGVzIGZvciAyLjYuCiAqCQlNYXJrdXMgTGlkZWwgPE1hcmt1cy5MaWRlbEBzaGFkb3djb25uZWN0LmNvbT46CiAqCQkJU3VwcG9ydCBmb3Igc3lzZnMgaW5jbHVkZWQuCiAqLwoKI2luY2x1ZGUgPGxpbnV4L3BjaS5oPgojaW5jbHVkZSA8bGludXgvaW50ZXJydXB0Lmg+CiNpbmNsdWRlIDxsaW51eC9pMm8uaD4KI2luY2x1ZGUgImNvcmUuaCIKCiNkZWZpbmUgT1NNX0RFU0NSSVBUSU9OCSJJMk8tc3Vic3lzdGVtIgoKLyogUENJIGRldmljZSBpZCB0YWJsZSBmb3IgYWxsIEkyTyBjb250cm9sbGVycyAqLwpzdGF0aWMgc3RydWN0IHBjaV9kZXZpY2VfaWQgX19kZXZpbml0ZGF0YSBpMm9fcGNpX2lkc1tdID0gewoJe1BDSV9ERVZJQ0VfQ0xBU1MoUENJX0NMQVNTX0lOVEVMTElHRU5UX0kyTyA8PCA4LCAweGZmZmYwMCl9LAoJe1BDSV9ERVZJQ0UoUENJX1ZFTkRPUl9JRF9EUFQsIDB4YTUxMSl9LAoJey52ZW5kb3IgPSBQQ0lfVkVORE9SX0lEX0lOVEVMLC5kZXZpY2UgPSAweDE5NjIsCgkgLnN1YnZlbmRvciA9IFBDSV9WRU5ET1JfSURfUFJPTUlTRSwuc3ViZGV2aWNlID0gUENJX0FOWV9JRH0sCgl7MH0KfTsKCi8qKgogKglpMm9fcGNpX2ZyZWUgLSBGcmVlcyB0aGUgRE1BIG1lbW9yeSBmb3IgdGhlIEkyTyBjb250cm9sbGVyCiAqCUBjOiBJMk8gY29udHJvbGxlciB0byBmcmVlCiAqCiAqCVJlbW92ZSBhbGwgYWxsb2NhdGVkIERNQSBtZW1vcnkgYW5kIHVubWFwIG1lbW9yeSBJTyByZWdpb25zLiBJZiBNVFJSCiAqCWlzIGVuYWJsZWQsIGFsc28gcmVtb3ZlIGl0IGFnYWluLgogKi8Kc3RhdGljIHZvaWQgaTJvX3BjaV9mcmVlKHN0cnVjdCBpMm9fY29udHJvbGxlciAqYykKewoJc3RydWN0IGRldmljZSAqZGV2OwoKCWRldiA9ICZjLT5wZGV2LT5kZXY7CgoJaTJvX2RtYV9mcmVlKGRldiwgJmMtPm91dF9xdWV1ZSk7CglpMm9fZG1hX2ZyZWUoZGV2LCAmYy0+c3RhdHVzX2Jsb2NrKTsKCWtmcmVlKGMtPmxjdCk7CglpMm9fZG1hX2ZyZWUoZGV2LCAmYy0+ZGxjdCk7CglpMm9fZG1hX2ZyZWUoZGV2LCAmYy0+aHJ0KTsKCWkyb19kbWFfZnJlZShkZXYsICZjLT5zdGF0dXMpOwoKCWlmIChjLT5yYXB0b3IgJiYgYy0+aW5fcXVldWUudmlydCkKCQlpb3VubWFwKGMtPmluX3F1ZXVlLnZpcnQpOwoKCWlmIChjLT5iYXNlLnZpcnQpCgkJaW91bm1hcChjLT5iYXNlLnZpcnQpOwoKCXBjaV9yZWxlYXNlX3JlZ2lvbnMoYy0+cGRldik7Cn0KCi8qKgogKglpMm9fcGNpX2FsbG9jIC0gQWxsb2NhdGUgRE1BIG1lbW9yeSwgbWFwIElPIG1lbW9yeSBmb3IgSTJPIGNvbnRyb2xsZXIKICoJQGM6IEkyTyBjb250cm9sbGVyCiAqCiAqCUFsbG9jYXRlIERNQSBtZW1vcnkgZm9yIGEgUENJIChvciBpbiB0aGVvcnkgQUdQKSBJMk8gY29udHJvbGxlci4gQWxsCiAqCUlPIG1hcHBpbmdzIGFyZSBhbHNvIGRvbmUgaGVyZS4gSWYgTVRSUiBpcyBlbmFibGVkLCBhbHNvIGRvIGFkZCBtZW1vcnkKICoJcmVnaW9ucyBoZXJlLgogKgogKglSZXR1cm5zIDAgb24gc3VjY2VzcyBvciBuZWdhdGl2ZSBlcnJvciBjb2RlIG9uIGZhaWx1cmUuCiAqLwpzdGF0aWMgaW50IF9fZGV2aW5pdCBpMm9fcGNpX2FsbG9jKHN0cnVjdCBpMm9fY29udHJvbGxlciAqYykKewoJc3RydWN0IHBjaV9kZXYgKnBkZXYgPSBjLT5wZGV2OwoJc3RydWN0IGRldmljZSAqZGV2ID0gJnBkZXYtPmRldjsKCWludCBpOwoKCWlmIChwY2lfcmVxdWVzdF9yZWdpb25zKHBkZXYsIE9TTV9ERVNDUklQVElPTikpIHsKCQlwcmludGsoS0VSTl9FUlIgIiVzOiBkZXZpY2UgYWxyZWFkeSBjbGFpbWVkXG4iLCBjLT5uYW1lKTsKCQlyZXR1cm4gLUVOT0RFVjsKCX0KCglmb3IgKGkgPSAwOyBpIDwgNjsgaSsrKSB7CgkJLyogU2tpcCBJL08gc3BhY2VzICovCgkJaWYgKCEocGNpX3Jlc291cmNlX2ZsYWdzKHBkZXYsIGkpICYgSU9SRVNPVVJDRV9JTykpIHsKCQkJaWYgKCFjLT5iYXNlLnBoeXMpIHsKCQkJCWMtPmJhc2UucGh5cyA9IHBjaV9yZXNvdXJjZV9zdGFydChwZGV2LCBpKTsKCQkJCWMtPmJhc2UubGVuID0gcGNpX3Jlc291cmNlX2xlbihwZGV2LCBpKTsKCgkJCQkvKgoJCQkJICogSWYgd2Uga25vdyB3aGF0IGNhcmQgaXQgaXMsIHNldCB0aGUgc2l6ZQoJCQkJICogY29ycmVjdGx5LiBDb2RlIGlzIHRha2VuIGZyb20gZHB0X2kyby5jCgkJCQkgKi8KCQkJCWlmIChwZGV2LT5kZXZpY2UgPT0gMHhhNTAxKSB7CgkJCQkJaWYgKHBkZXYtPnN1YnN5c3RlbV9kZXZpY2UgPj0gMHhjMDMyICYmCgkJCQkJICAgIHBkZXYtPnN1YnN5c3RlbV9kZXZpY2UgPD0gMHhjMDNiKSB7CgkJCQkJCWlmIChjLT5iYXNlLmxlbiA+IDB4NDAwMDAwKQoJCQkJCQkJYy0+YmFzZS5sZW4gPSAweDQwMDAwMDsKCQkJCQl9IGVsc2UgewoJCQkJCQlpZiAoYy0+YmFzZS5sZW4gPiAweDEwMDAwMCkKCQkJCQkJCWMtPmJhc2UubGVuID0gMHgxMDAwMDA7CgkJCQkJfQoJCQkJfQoJCQkJaWYgKCFjLT5yYXB0b3IpCgkJCQkJYnJlYWs7CgkJCX0gZWxzZSB7CgkJCQljLT5pbl9xdWV1ZS5waHlzID0gcGNpX3Jlc291cmNlX3N0YXJ0KHBkZXYsIGkpOwoJCQkJYy0+aW5fcXVldWUubGVuID0gcGNpX3Jlc291cmNlX2xlbihwZGV2LCBpKTsKCQkJCWJyZWFrOwoJCQl9CgkJfQoJfQoKCWlmIChpID09IDYpIHsKCQlwcmludGsoS0VSTl9FUlIgIiVzOiBJMk8gY29udHJvbGxlciBoYXMgbm8gbWVtb3J5IHJlZ2lvbnMiCgkJICAgICAgICIgZGVmaW5lZC5cbiIsIGMtPm5hbWUpOwoJCWkyb19wY2lfZnJlZShjKTsKCQlyZXR1cm4gLUVJTlZBTDsKCX0KCgkvKiBNYXAgdGhlIEkyTyBjb250cm9sbGVyICovCglpZiAoYy0+cmFwdG9yKSB7CgkJcHJpbnRrKEtFUk5fSU5GTyAiJXM6IFBDSSBJMk8gY29udHJvbGxlclxuIiwgYy0+bmFtZSk7CgkJcHJpbnRrKEtFUk5fSU5GTyAiICAgICBCQVIwIGF0IDB4JTA4bFggc2l6ZT0lbGRcbiIsCgkJICAgICAgICh1bnNpZ25lZCBsb25nKWMtPmJhc2UucGh5cywgKHVuc2lnbmVkIGxvbmcpYy0+YmFzZS5sZW4pOwoJCXByaW50ayhLRVJOX0lORk8gIiAgICAgQkFSMSBhdCAweCUwOGxYIHNpemU9JWxkXG4iLAoJCSAgICAgICAodW5zaWduZWQgbG9uZyljLT5pbl9xdWV1ZS5waHlzLAoJCSAgICAgICAodW5zaWduZWQgbG9uZyljLT5pbl9xdWV1ZS5sZW4pOwoJfSBlbHNlCgkJcHJpbnRrKEtFUk5fSU5GTyAiJXM6IFBDSSBJMk8gY29udHJvbGxlciBhdCAlMDhsWCBzaXplPSVsZFxuIiwKCQkgICAgICAgYy0+bmFtZSwgKHVuc2lnbmVkIGxvbmcpYy0+YmFzZS5waHlzLAoJCSAgICAgICAodW5zaWduZWQgbG9uZyljLT5iYXNlLmxlbik7CgoJYy0+YmFzZS52aXJ0ID0gaW9yZW1hcF9ub2NhY2hlKGMtPmJhc2UucGh5cywgYy0+YmFzZS5sZW4pOwoJaWYgKCFjLT5iYXNlLnZpcnQpIHsKCQlwcmludGsoS0VSTl9FUlIgIiVzOiBVbmFibGUgdG8gbWFwIGNvbnRyb2xsZXIuXG4iLCBjLT5uYW1lKTsKCQlpMm9fcGNpX2ZyZWUoYyk7CgkJcmV0dXJuIC1FTk9NRU07Cgl9CgoJaWYgKGMtPnJhcHRvcikgewoJCWMtPmluX3F1ZXVlLnZpcnQgPQoJCSAgICBpb3JlbWFwX25vY2FjaGUoYy0+aW5fcXVldWUucGh5cywgYy0+aW5fcXVldWUubGVuKTsKCQlpZiAoIWMtPmluX3F1ZXVlLnZpcnQpIHsKCQkJcHJpbnRrKEtFUk5fRVJSICIlczogVW5hYmxlIHRvIG1hcCBjb250cm9sbGVyLlxuIiwKCQkJICAgICAgIGMtPm5hbWUpOwoJCQlpMm9fcGNpX2ZyZWUoYyk7CgkJCXJldHVybiAtRU5PTUVNOwoJCX0KCX0gZWxzZQoJCWMtPmluX3F1ZXVlID0gYy0+YmFzZTsKCgljLT5pcnFfc3RhdHVzID0gYy0+YmFzZS52aXJ0ICsgSTJPX0lSUV9TVEFUVVM7CgljLT5pcnFfbWFzayA9IGMtPmJhc2UudmlydCArIEkyT19JUlFfTUFTSzsKCWMtPmluX3BvcnQgPSBjLT5iYXNlLnZpcnQgKyBJMk9fSU5fUE9SVDsKCWMtPm91dF9wb3J0ID0gYy0+YmFzZS52aXJ0ICsgSTJPX09VVF9QT1JUOwoKCS8qIE1vdG9yb2xhL0ZyZWVzY2FsZSBjaGlwIGRvZXMgbm90IGZvbGxvdyBzcGVjICovCglpZiAocGRldi0+dmVuZG9yID09IFBDSV9WRU5ET1JfSURfTU9UT1JPTEEgJiYgcGRldi0+ZGV2aWNlID09IDB4MThjMCkgewoJCS8qIENoZWNrIGlmIENQVSBpcyBlbmFibGVkICovCgkJaWYgKGJlMzJfdG9fY3B1KHJlYWRsKGMtPmJhc2UudmlydCArIDB4MTAwMDApKSAmIDB4MTAwMDAwMDApIHsKCQkJcHJpbnRrKEtFUk5fSU5GTyAiJXM6IE1QQzgyWFggbmVlZHMgQ1BVIHJ1bm5pbmcgdG8gIgoJCQkgICAgICAgInNlcnZpY2UgSTJPLlxuIiwgYy0+bmFtZSk7CgkJCWkyb19wY2lfZnJlZShjKTsKCQkJcmV0dXJuIC1FTk9ERVY7CgkJfSBlbHNlIHsKCQkJYy0+aXJxX3N0YXR1cyArPSBJMk9fTU9UT1JPTEFfUE9SVF9PRkZTRVQ7CgkJCWMtPmlycV9tYXNrICs9IEkyT19NT1RPUk9MQV9QT1JUX09GRlNFVDsKCQkJYy0+aW5fcG9ydCArPSBJMk9fTU9UT1JPTEFfUE9SVF9PRkZTRVQ7CgkJCWMtPm91dF9wb3J0ICs9IEkyT19NT1RPUk9MQV9QT1JUX09GRlNFVDsKCQkJcHJpbnRrKEtFUk5fSU5GTyAiJXM6IE1QQzgyWFggd29ya2Fyb3VuZHMgYWN0aXZhdGVkLlxuIiwKCQkJICAgICAgIGMtPm5hbWUpOwoJCX0KCX0KCglpZiAoaTJvX2RtYV9hbGxvYyhkZXYsICZjLT5zdGF0dXMsIDgsIEdGUF9LRVJORUwpKSB7CgkJaTJvX3BjaV9mcmVlKGMpOwoJCXJldHVybiAtRU5PTUVNOwoJfQoKCWlmIChpMm9fZG1hX2FsbG9jKGRldiwgJmMtPmhydCwgc2l6ZW9mKGkyb19ocnQpLCBHRlBfS0VSTkVMKSkgewoJCWkyb19wY2lfZnJlZShjKTsKCQlyZXR1cm4gLUVOT01FTTsKCX0KCglpZiAoaTJvX2RtYV9hbGxvYyhkZXYsICZjLT5kbGN0LCA4MTkyLCBHRlBfS0VSTkVMKSkgewoJCWkyb19wY2lfZnJlZShjKTsKCQlyZXR1cm4gLUVOT01FTTsKCX0KCglpZiAoaTJvX2RtYV9hbGxvYyhkZXYsICZjLT5zdGF0dXNfYmxvY2ssIHNpemVvZihpMm9fc3RhdHVzX2Jsb2NrKSwKCQkJICBHRlBfS0VSTkVMKSkgewoJCWkyb19wY2lfZnJlZShjKTsKCQlyZXR1cm4gLUVOT01FTTsKCX0KCglpZiAoaTJvX2RtYV9hbGxvYwoJICAgIChkZXYsICZjLT5vdXRfcXVldWUsCgkgICAgIEkyT19NQVhfT1VUQk9VTkRfTVNHX0ZSQU1FUyAqIEkyT19PVVRCT1VORF9NU0dfRlJBTUVfU0laRSAqCgkgICAgIHNpemVvZih1MzIpLCBHRlBfS0VSTkVMKSkgewoJCWkyb19wY2lfZnJlZShjKTsKCQlyZXR1cm4gLUVOT01FTTsKCX0KCglwY2lfc2V0X2RydmRhdGEocGRldiwgYyk7CgoJcmV0dXJuIDA7Cn0KCi8qKgogKglpMm9fcGNpX2ludGVycnVwdCAtIEludGVycnVwdCBoYW5kbGVyIGZvciBJMk8gY29udHJvbGxlcgogKglAaXJxOiBpbnRlcnJ1cHQgbGluZQogKglAZGV2X2lkOiBwb2ludGVyIHRvIHRoZSBJMk8gY29udHJvbGxlcgogKglAcjogcG9pbnRlciB0byByZWdpc3RlcnMKICoKICoJSGFuZGxlIGFuIGludGVycnVwdCBmcm9tIGEgUENJIGJhc2VkIEkyTyBjb250cm9sbGVyLiBUaGlzIHR1cm5zIG91dAogKgl0byBiZSByYXRoZXIgc2ltcGxlLiBXZSBrZWVwIHRoZSBjb250cm9sbGVyIHBvaW50ZXIgaW4gdGhlIGNvb2tpZS4KICovCnN0YXRpYyBpcnFyZXR1cm5fdCBpMm9fcGNpX2ludGVycnVwdChpbnQgaXJxLCB2b2lkICpkZXZfaWQsIHN0cnVjdCBwdF9yZWdzICpyKQp7CglzdHJ1Y3QgaTJvX2NvbnRyb2xsZXIgKmMgPSBkZXZfaWQ7Cgl1MzIgbTsKCWlycXJldHVybl90IHJjID0gSVJRX05PTkU7CgoJd2hpbGUgKHJlYWRsKGMtPmlycV9zdGF0dXMpICYgSTJPX0lSUV9PVVRCT1VORF9QT1NUKSB7CgkJbSA9IHJlYWRsKGMtPm91dF9wb3J0KTsKCQlpZiAobSA9PSBJMk9fUVVFVUVfRU1QVFkpIHsKCQkJLyoKCQkJICogT2xkIDk2MCBzdGVwcGluZ3MgaGFkIGEgYnVnIGluIHRoZSBJMk8gdW5pdCB0aGF0CgkJCSAqIGNhdXNlZCB0aGUgcXVldWUgdG8gYXBwZWFyIGVtcHR5IHdoZW4gaXQgd2Fzbid0LgoJCQkgKi8KCQkJbSA9IHJlYWRsKGMtPm91dF9wb3J0KTsKCQkJaWYgKHVubGlrZWx5KG0gPT0gSTJPX1FVRVVFX0VNUFRZKSkKCQkJCWJyZWFrOwoJCX0KCgkJLyogZGlzcGF0Y2ggaXQgKi8KCQlpZiAoaTJvX2RyaXZlcl9kaXNwYXRjaChjLCBtKSkKCQkJLyogZmx1c2ggaXQgaWYgcmVzdWx0ICE9IDAgKi8KCQkJaTJvX2ZsdXNoX3JlcGx5KGMsIG0pOwoKCQlyYyA9IElSUV9IQU5ETEVEOwoJfQoKCXJldHVybiByYzsKfQoKLyoqCiAqCWkyb19wY2lfaXJxX2VuYWJsZSAtIEFsbG9jYXRlIGludGVycnVwdCBmb3IgSTJPIGNvbnRyb2xsZXIKICoKICoJQWxsb2NhdGUgYW4gaW50ZXJydXB0IGZvciB0aGUgSTJPIGNvbnRyb2xsZXIsIGFuZCBhY3RpdmF0ZSBpbnRlcnJ1cHRzCiAqCW9uIHRoZSBJMk8gY29udHJvbGxlci4KICoKICoJUmV0dXJucyAwIG9uIHN1Y2Nlc3Mgb3IgbmVnYXRpdmUgZXJyb3IgY29kZSBvbiBmYWlsdXJlLgogKi8Kc3RhdGljIGludCBpMm9fcGNpX2lycV9lbmFibGUoc3RydWN0IGkyb19jb250cm9sbGVyICpjKQp7CglzdHJ1Y3QgcGNpX2RldiAqcGRldiA9IGMtPnBkZXY7CglpbnQgcmM7CgoJd3JpdGVsKDB4ZmZmZmZmZmYsIGMtPmlycV9tYXNrKTsKCglpZiAocGRldi0+aXJxKSB7CgkJcmMgPSByZXF1ZXN0X2lycShwZGV2LT5pcnEsIGkyb19wY2lfaW50ZXJydXB0LCBTQV9TSElSUSwKCQkJCSBjLT5uYW1lLCBjKTsKCQlpZiAocmMgPCAwKSB7CgkJCXByaW50ayhLRVJOX0VSUiAiJXM6IHVuYWJsZSB0byBhbGxvY2F0ZSBpbnRlcnJ1cHQgJWQuIgoJCQkgICAgICAgIlxuIiwgYy0+bmFtZSwgcGRldi0+aXJxKTsKCQkJcmV0dXJuIHJjOwoJCX0KCX0KCgl3cml0ZWwoMHgwMDAwMDAwMCwgYy0+aXJxX21hc2spOwoKCXByaW50ayhLRVJOX0lORk8gIiVzOiBJbnN0YWxsZWQgYXQgSVJRICVkXG4iLCBjLT5uYW1lLCBwZGV2LT5pcnEpOwoKCXJldHVybiAwOwp9CgovKioKICoJaTJvX3BjaV9pcnFfZGlzYWJsZSAtIEZyZWUgaW50ZXJydXB0IGZvciBJMk8gY29udHJvbGxlcgogKglAYzogSTJPIGNvbnRyb2xsZXIKICoKICoJRGlzYWJsZSBpbnRlcnJ1cHRzIGluIEkyTyBjb250cm9sbGVyIGFuZCB0aGVuIGZyZWUgaW50ZXJydXB0LgogKi8Kc3RhdGljIHZvaWQgaTJvX3BjaV9pcnFfZGlzYWJsZShzdHJ1Y3QgaTJvX2NvbnRyb2xsZXIgKmMpCnsKCXdyaXRlbCgweGZmZmZmZmZmLCBjLT5pcnFfbWFzayk7CgoJaWYgKGMtPnBkZXYtPmlycSA+IDApCgkJZnJlZV9pcnEoYy0+cGRldi0+aXJxLCBjKTsKfQoKLyoqCiAqCWkyb19wY2lfcHJvYmUgLSBQcm9iZSB0aGUgUENJIGRldmljZSBmb3IgYW4gSTJPIGNvbnRyb2xsZXIKICoJQGRldjogUENJIGRldmljZSB0byB0ZXN0CiAqCUBpZDogaWQgd2hpY2ggbWF0Y2hlZCB3aXRoIHRoZSBQQ0kgZGV2aWNlIGlkIHRhYmxlCiAqCiAqCVByb2JlIHRoZSBQQ0kgZGV2aWNlIGZvciBhbnkgZGV2aWNlIHdoaWNoIGlzIGEgbWVtb3J5IG9mIHRoZQogKglJbnRlbGxpZ2VudCwgSTJPIGNsYXNzIG9yIGFuIEFkYXB0ZWMgWmVybyBDaGFubmVsIENvbnRyb2xsZXIuIFdlCiAqCWF0dGVtcHQgdG8gc2V0IHVwIGVhY2ggc3VjaCBkZXZpY2UgYW5kIHJlZ2lzdGVyIGl0IHdpdGggdGhlIGNvcmUuCiAqCiAqCVJldHVybnMgMCBvbiBzdWNjZXNzIG9yIG5lZ2F0aXZlIGVycm9yIGNvZGUgb24gZmFpbHVyZS4KICovCnN0YXRpYyBpbnQgX19kZXZpbml0IGkyb19wY2lfcHJvYmUoc3RydWN0IHBjaV9kZXYgKnBkZXYsCgkJCQkgICBjb25zdCBzdHJ1Y3QgcGNpX2RldmljZV9pZCAqaWQpCnsKCXN0cnVjdCBpMm9fY29udHJvbGxlciAqYzsKCWludCByYzsKCXN0cnVjdCBwY2lfZGV2ICppOTYwID0gTlVMTDsKCWludCBlbmFibGVkID0gcGRldi0+aXNfZW5hYmxlZDsKCglwcmludGsoS0VSTl9JTkZPICJpMm86IENoZWNraW5nIGZvciBQQ0kgSTJPIGNvbnRyb2xsZXJzLi4uXG4iKTsKCglpZiAoKHBkZXYtPmNsYXNzICYgMHhmZikgPiAxKSB7CgkJcHJpbnRrKEtFUk5fV0FSTklORyAiaTJvOiAlcyBkb2VzIG5vdCBzdXBwb3J0IEkyTyAxLjUgIgoJCSAgICAgICAiKHNraXBwaW5nKS5cbiIsIHBjaV9uYW1lKHBkZXYpKTsKCQlyZXR1cm4gLUVOT0RFVjsKCX0KCglpZiAoIWVuYWJsZWQpCgkJaWYgKChyYyA9IHBjaV9lbmFibGVfZGV2aWNlKHBkZXYpKSkgewoJCQlwcmludGsoS0VSTl9XQVJOSU5HICJpMm86IGNvdWxkbid0IGVuYWJsZSBkZXZpY2UgJXNcbiIsCgkJCSAgICAgICBwY2lfbmFtZShwZGV2KSk7CgkJCXJldHVybiByYzsKCQl9CgoJaWYgKHBjaV9zZXRfZG1hX21hc2socGRldiwgRE1BXzMyQklUX01BU0spKSB7CgkJcHJpbnRrKEtFUk5fV0FSTklORyAiaTJvOiBubyBzdWl0YWJsZSBETUEgZm91bmQgZm9yICVzXG4iLAoJCSAgICAgICBwY2lfbmFtZShwZGV2KSk7CgkJcmMgPSAtRU5PREVWOwoJCWdvdG8gZGlzYWJsZTsKCX0KCglwY2lfc2V0X21hc3RlcihwZGV2KTsKCgljID0gaTJvX2lvcF9hbGxvYygpOwoJaWYgKElTX0VSUihjKSkgewoJCXByaW50ayhLRVJOX0VSUiAiaTJvOiBjb3VsZG4ndCBhbGxvY2F0ZSBtZW1vcnkgZm9yICVzXG4iLAoJCSAgICAgICBwY2lfbmFtZShwZGV2KSk7CgkJcmMgPSBQVFJfRVJSKGMpOwoJCWdvdG8gZGlzYWJsZTsKCX0gZWxzZQoJCXByaW50ayhLRVJOX0lORk8gIiVzOiBjb250cm9sbGVyIGZvdW5kICglcylcbiIsIGMtPm5hbWUsCgkJICAgICAgIHBjaV9uYW1lKHBkZXYpKTsKCgljLT5wZGV2ID0gcGRldjsKCWMtPmRldmljZS5wYXJlbnQgPSAmcGRldi0+ZGV2OwoKCS8qIENhcmRzIHRoYXQgZmFsbCBhcGFydCBpZiB5b3UgaGl0IHRoZW0gd2l0aCBsYXJnZSBJL08gbG9hZHMuLi4gKi8KCWlmIChwZGV2LT52ZW5kb3IgPT0gUENJX1ZFTkRPUl9JRF9OQ1IgJiYgcGRldi0+ZGV2aWNlID09IDB4MDYzMCkgewoJCWMtPnNob3J0X3JlcSA9IDE7CgkJcHJpbnRrKEtFUk5fSU5GTyAiJXM6IFN5bWJpb3MgRkM5MjAgd29ya2Fyb3VuZHMgYWN0aXZhdGVkLlxuIiwKCQkgICAgICAgYy0+bmFtZSk7Cgl9CgoJaWYgKHBkZXYtPnN1YnN5c3RlbV92ZW5kb3IgPT0gUENJX1ZFTkRPUl9JRF9QUk9NSVNFKSB7CgkJLyoKCQkgKiBFeHBvc2UgdGhlIHNoaXAgYmVoaW5kIGk5NjAgZm9yIGluaXRpYWxpemF0aW9uLCBvciBpdCB3aWxsCgkJICogZmFpbGVkCgkJICovCgkJaTk2MCA9CgkJICAgIHBjaV9maW5kX3Nsb3QoYy0+cGRldi0+YnVzLT5udW1iZXIsCgkJCQkgIFBDSV9ERVZGTihQQ0lfU0xPVChjLT5wZGV2LT5kZXZmbiksIDApKTsKCgkJaWYgKGk5NjApCgkJCXBjaV93cml0ZV9jb25maWdfd29yZChpOTYwLCAweDQyLCAwKTsKCgkJYy0+cHJvbWlzZSA9IDE7CgkJYy0+bGltaXRfc2VjdG9ycyA9IDE7Cgl9CgoJaWYgKHBkZXYtPnN1YnN5c3RlbV92ZW5kb3IgPT0gUENJX1ZFTkRPUl9JRF9EUFQpCgkJYy0+YWRhcHRlYyA9IDE7CgoJLyogQ2FyZHMgdGhhdCBnbyBiYW5hbmFzIGlmIHlvdSBxdWllc2NlIHRoZW0gYmVmb3JlIHlvdSByZXNldCB0aGVtLiAqLwoJaWYgKHBkZXYtPnZlbmRvciA9PSBQQ0lfVkVORE9SX0lEX0RQVCkgewoJCWMtPm5vX3F1aWVzY2UgPSAxOwoJCWlmIChwZGV2LT5kZXZpY2UgPT0gMHhhNTExKQoJCQljLT5yYXB0b3IgPSAxOwoKCQlpZiAocGRldi0+c3Vic3lzdGVtX2RldmljZSA9PSAweGMwNWEpIHsKCQkJYy0+bGltaXRfc2VjdG9ycyA9IDE7CgkJCXByaW50ayhLRVJOX0lORk8KCQkJICAgICAgICIlczogbGltaXQgc2VjdG9ycyBwZXIgcmVxdWVzdCB0byAlZFxuIiwgYy0+bmFtZSwKCQkJICAgICAgIEkyT19NQVhfU0VDVE9SU19MSU1JVEVEKTsKCQl9CiNpZmRlZiBDT05GSUdfSTJPX0VYVF9BREFQVEVDX0RNQTY0CgkJaWYgKHNpemVvZihkbWFfYWRkcl90KSA+IDQpIHsKCQkJaWYgKHBjaV9zZXRfZG1hX21hc2socGRldiwgRE1BXzY0QklUX01BU0spKQoJCQkJcHJpbnRrKEtFUk5fSU5GTyAiJXM6IDY0LWJpdCBETUEgdW5hdmFpbGFibGVcbiIsCgkJCQkgICAgICAgYy0+bmFtZSk7CgkJCWVsc2UgewoJCQkJYy0+cGFlX3N1cHBvcnQgPSAxOwoJCQkJcHJpbnRrKEtFUk5fSU5GTyAiJXM6IHVzaW5nIDY0LWJpdCBETUFcbiIsCgkJCQkgICAgICAgYy0+bmFtZSk7CgkJCX0KCQl9CiNlbmRpZgoJfQoKCWlmICgocmMgPSBpMm9fcGNpX2FsbG9jKGMpKSkgewoJCXByaW50ayhLRVJOX0VSUiAiJXM6IERNQSAvIElPIGFsbG9jYXRpb24gZm9yIEkyTyBjb250cm9sbGVyICIKCQkgICAgICAgImZhaWxlZFxuIiwgYy0+bmFtZSk7CgkJZ290byBmcmVlX2NvbnRyb2xsZXI7Cgl9CgoJaWYgKGkyb19wY2lfaXJxX2VuYWJsZShjKSkgewoJCXByaW50ayhLRVJOX0VSUiAiJXM6IHVuYWJsZSB0byBlbmFibGUgaW50ZXJydXB0cyBmb3IgSTJPICIKCQkgICAgICAgImNvbnRyb2xsZXJcbiIsIGMtPm5hbWUpOwoJCWdvdG8gZnJlZV9wY2k7Cgl9CgoJaWYgKChyYyA9IGkyb19pb3BfYWRkKGMpKSkKCQlnb3RvIHVuaW5zdGFsbDsKCglpZiAoaTk2MCkKCQlwY2lfd3JpdGVfY29uZmlnX3dvcmQoaTk2MCwgMHg0MiwgMHgwM2ZmKTsKCglyZXR1cm4gMDsKCiAgICAgIHVuaW5zdGFsbDoKCWkyb19wY2lfaXJxX2Rpc2FibGUoYyk7CgogICAgICBmcmVlX3BjaToKCWkyb19wY2lfZnJlZShjKTsKCiAgICAgIGZyZWVfY29udHJvbGxlcjoKCWkyb19pb3BfZnJlZShjKTsKCiAgICAgIGRpc2FibGU6CglpZiAoIWVuYWJsZWQpCgkJcGNpX2Rpc2FibGVfZGV2aWNlKHBkZXYpOwoKCXJldHVybiByYzsKfQoKLyoqCiAqCWkyb19wY2lfcmVtb3ZlIC0gUmVtb3ZlcyBhIEkyTyBjb250cm9sbGVyIGZyb20gdGhlIHN5c3RlbQogKglwZGV2OiBJMk8gY29udHJvbGxlciB3aGljaCBzaG91bGQgYmUgcmVtb3ZlZAogKgogKglSZXNldCB0aGUgSTJPIGNvbnRyb2xsZXIsIGRpc2FibGUgaW50ZXJydXB0cyBhbmQgcmVtb3ZlIGFsbCBhbGxvY2F0ZWQKICoJcmVzb3VyY2VzLgogKi8Kc3RhdGljIHZvaWQgX19kZXZleGl0IGkyb19wY2lfcmVtb3ZlKHN0cnVjdCBwY2lfZGV2ICpwZGV2KQp7CglzdHJ1Y3QgaTJvX2NvbnRyb2xsZXIgKmM7CgljID0gcGNpX2dldF9kcnZkYXRhKHBkZXYpOwoKCWkyb19pb3BfcmVtb3ZlKGMpOwoJaTJvX3BjaV9pcnFfZGlzYWJsZShjKTsKCWkyb19wY2lfZnJlZShjKTsKCglwY2lfZGlzYWJsZV9kZXZpY2UocGRldik7CgoJcHJpbnRrKEtFUk5fSU5GTyAiJXM6IENvbnRyb2xsZXIgcmVtb3ZlZC5cbiIsIGMtPm5hbWUpOwoKCXB1dF9kZXZpY2UoJmMtPmRldmljZSk7Cn07CgovKiBQQ0kgZHJpdmVyIGZvciBJMk8gY29udHJvbGxlciAqLwpzdGF0aWMgc3RydWN0IHBjaV9kcml2ZXIgaTJvX3BjaV9kcml2ZXIgPSB7CgkubmFtZSA9ICJQQ0lfSTJPIiwKCS5pZF90YWJsZSA9IGkyb19wY2lfaWRzLAoJLnByb2JlID0gaTJvX3BjaV9wcm9iZSwKCS5yZW1vdmUgPSBfX2RldmV4aXRfcChpMm9fcGNpX3JlbW92ZSksCn07CgovKioKICoJaTJvX3BjaV9pbml0IC0gcmVnaXN0ZXJzIEkyTyBQQ0kgZHJpdmVyIGluIFBDSSBzdWJzeXN0ZW0KICoKICoJUmV0dXJucyA+IDAgb24gc3VjY2VzcyBvciBuZWdhdGl2ZSBlcnJvciBjb2RlIG9uIGZhaWx1cmUuCiAqLwppbnQgX19pbml0IGkyb19wY2lfaW5pdCh2b2lkKQp7CglyZXR1cm4gcGNpX3JlZ2lzdGVyX2RyaXZlcigmaTJvX3BjaV9kcml2ZXIpOwp9OwoKLyoqCiAqCWkyb19wY2lfZXhpdCAtIHVucmVnaXN0ZXJzIEkyTyBQQ0kgZHJpdmVyIGZyb20gUENJIHN1YnN5c3RlbQogKi8Kdm9pZCBfX2V4aXQgaTJvX3BjaV9leGl0KHZvaWQpCnsKCXBjaV91bnJlZ2lzdGVyX2RyaXZlcigmaTJvX3BjaV9kcml2ZXIpOwp9OwoKTU9EVUxFX0RFVklDRV9UQUJMRShwY2ksIGkyb19wY2lfaWRzKTsK