From mboxrd@z Thu Jan 1 00:00:00 1970 From: =?UTF-8?q?Arve=20Hj=C3=B8nnev=C3=A5g?= Subject: [PATCH 1/8] PM: Add suspend block api. Date: Thu, 13 May 2010 21:11:06 -0700 Message-ID: <1273810273-3039-2-git-send-email-arve@android.com> References: <1273810273-3039-1-git-send-email-arve@android.com> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: In-Reply-To: <1273810273-3039-1-git-send-email-arve@android.com> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: linux-pm-bounces@lists.linux-foundation.org Errors-To: linux-pm-bounces@lists.linux-foundation.org To: linux-pm@lists.linux-foundation.org, linux-kernel@vger.kernel.org Cc: Len Brown , Andi Kleen , linux-doc@vger.kernel.org, Jesse Barnes , Tejun Heo , Magnus Damm , Andrew Morton , Wu Fengguang List-Id: linux-pm@vger.kernel.org QWRkcyAvc3lzL3Bvd2VyL3BvbGljeSB0aGF0IHNlbGVjdHMgdGhlIGJlaGF2aW91ciBvZiAvc3lz L3Bvd2VyL3N0YXRlLgpBZnRlciBzZXR0aW5nIHRoZSBwb2xpY3kgdG8gb3Bwb3J0dW5pc3RpYywg d3JpdGVzIHRvIC9zeXMvcG93ZXIvc3RhdGUKYmVjb21lIG5vbi1ibG9ja2luZyByZXF1ZXN0cyB0 aGF0IHNwZWNpZnkgd2hpY2ggc3VzcGVuZCBzdGF0ZSB0byBlbnRlcgp3aGVuIG5vIHN1c3BlbmQg YmxvY2tlcnMgYXJlIGFjdGl2ZS4gQSBzcGVjaWFsIHN0YXRlLCAib24iLCBzdG9wcyB0aGUKcHJv Y2VzcyBieSBhY3RpdmF0aW5nIHRoZSAibWFpbiIgc3VzcGVuZCBibG9ja2VyLgoKU2lnbmVkLW9m Zi1ieTogQXJ2ZSBIasO4bm5ldsOlZyA8YXJ2ZUBhbmRyb2lkLmNvbT4KLS0tCiBEb2N1bWVudGF0 aW9uL3Bvd2VyL29wcG9ydHVuaXN0aWMtc3VzcGVuZC50eHQgfCAgMTI5ICsrKysrKysrKysrCiBp bmNsdWRlL2xpbnV4L3N1c3BlbmQuaCAgICAgICAgICAgICAgICAgICAgICAgfCAgICAxICsKIGlu Y2x1ZGUvbGludXgvc3VzcGVuZF9ibG9ja2VyLmggICAgICAgICAgICAgICB8ICAgNzQgKysrKysr Kwoga2VybmVsL3Bvd2VyL0tjb25maWcgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAxNiAr Kwoga2VybmVsL3Bvd2VyL01ha2VmaWxlICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgMSAr CiBrZXJuZWwvcG93ZXIvbWFpbi5jICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgMTI4ICsr KysrKysrKysrLQoga2VybmVsL3Bvd2VyL29wcG9ydHVuaXN0aWNfc3VzcGVuZC5jICAgICAgICAg IHwgIDI4NCArKysrKysrKysrKysrKysrKysrKysrKysrCiBrZXJuZWwvcG93ZXIvcG93ZXIuaCAg ICAgICAgICAgICAgICAgICAgICAgICAgfCAgICA5ICsKIGtlcm5lbC9wb3dlci9zdXNwZW5kLmMg ICAgICAgICAgICAgICAgICAgICAgICB8ICAgIDMgKy0KIDkgZmlsZXMgY2hhbmdlZCwgNjM3IGlu c2VydGlvbnMoKyksIDggZGVsZXRpb25zKC0pCiBjcmVhdGUgbW9kZSAxMDA2NDQgRG9jdW1lbnRh dGlvbi9wb3dlci9vcHBvcnR1bmlzdGljLXN1c3BlbmQudHh0CiBjcmVhdGUgbW9kZSAxMDA3NTUg aW5jbHVkZS9saW51eC9zdXNwZW5kX2Jsb2NrZXIuaAogY3JlYXRlIG1vZGUgMTAwNjQ0IGtlcm5l bC9wb3dlci9vcHBvcnR1bmlzdGljX3N1c3BlbmQuYwoKZGlmZiAtLWdpdCBhL0RvY3VtZW50YXRp b24vcG93ZXIvb3Bwb3J0dW5pc3RpYy1zdXNwZW5kLnR4dCBiL0RvY3VtZW50YXRpb24vcG93ZXIv b3Bwb3J0dW5pc3RpYy1zdXNwZW5kLnR4dApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAw MDAwLi40YmVlN2JjCi0tLSAvZGV2L251bGwKKysrIGIvRG9jdW1lbnRhdGlvbi9wb3dlci9vcHBv cnR1bmlzdGljLXN1c3BlbmQudHh0CkBAIC0wLDAgKzEsMTI5IEBACitPcHBvcnR1bmlzdGljIFN1 c3BlbmQKKz09PT09PT09PT09PT09PT09PT09PQorCitPcHBvcnR1bmlzdGljIHN1c3BlbmQgaXMg YSBmZWF0dXJlIGFsbG93aW5nIHRoZSBzeXN0ZW0gdG8gYmUgc3VzcGVuZGVkIChpZS4gcHV0Citp bnRvIG9uZSBvZiB0aGUgYXZhaWxhYmxlIHNsZWVwIHN0YXRlcykgYXV0b21hdGljYWxseSB3aGVu ZXZlciBpdCBpcyByZWdhcmRlZAorYXMgaWRsZS4gIFRoZSBzdXNwZW5kIGJsb2NrZXJzIGZyYW1l d29yayBkZXNjcmliZWQgYmVsb3cgaXMgdXNlZCB0byBkZXRlcm1pbmUKK3doZW4gdGhhdCBoYXBw ZW5zLgorCitUaGUgL3N5cy9wb3dlci9wb2xpY3kgc3lzZnMgYXR0cmlidXRlIGlzIHVzZWQgdG8g c3dpdGNoIHRoZSBzeXN0ZW0gYmV0d2VlbiB0aGUKK29wcG9ydHVuaXN0aWMgYW5kICJmb3JjZWQi IHN1c3BlbmQgYmVoYXZpb3IsIHdoZXJlIGluIHRoZSBsYXR0ZXIgY2FzZSB0aGUKK3N5c3RlbSBp cyBvbmx5IHN1c3BlbmRlZCBpZiBhIHNwZWNpZmljIHZhbHVlLCBjb3JyZXNwb25kaW5nIHRvIG9u ZSBvZiB0aGUKK2F2YWlsYWJsZSBzeXN0ZW0gc2xlZXAgc3RhdGVzLCBpcyB3cml0dGVuIGludG8g L3N5cy9wb3dlci9zdGF0ZS4gIEhvd2V2ZXIsIGluCit0aGUgZm9ybWVyLCBvcHBvcnR1bmlzdGlj LCBjYXNlIHRoZSBzeXN0ZW0gaXMgcHV0IGludG8gdGhlIHNsZWVwIHN0YXRlCitjb3JyZXNwb25k aW5nIHRvIHRoZSB2YWx1ZSB3cml0dGVuIHRvIC9zeXMvcG93ZXIvc3RhdGUgd2hlbmV2ZXIgdGhl cmUgYXJlIG5vCithY3RpdmUgc3VzcGVuZCBibG9ja2Vycy4gVGhlIGRlZmF1bHQgcG9saWN5IGlz ICJmb3JjZWQiLiBBbHNvLCBzdXNwZW5kIGJsb2NrZXJzCitkbyBub3QgYWZmZWN0IHNsZWVwIHN0 YXRlcyBlbnRlcmVkIGZyb20gaWRsZS4KKworV2hlbiB0aGUgcG9saWN5IGlzICJvcHBvcnR1bmlz aWMiLCB0aGVyZSBpcyBhIHNwZWNpYWwgdmFsdWUsICJvbiIsIHRoYXQgY2FuIGJlCit3cml0dGVu IHRvIC9zeXMvcG93ZXIvc3RhdGUuIFRoaXMgd2lsbCBibG9jayB0aGUgYXV0b21hdGljIHNsZWVw IHJlcXVlc3QsIGFzIGlmCithIHN1c3BlbmQgYmxvY2tlciB3YXMgdXNlZCBieSBhIGRldmljZSBk cml2ZXIuIFRoaXMgd2F5IHRoZSBvcHBvcnR1bmlzdGljCitzdXNwZW5kIG1heSBiZSBibG9ja2Vk IGJ5IHVzZXIgc3BhY2Ugd2hpdGhvdXQgc3dpdGNoaW5nIGJhY2sgdG8gdGhlICJmb3JjZWQiCitt b2RlLgorCitBIHN1c3BlbmQgYmxvY2tlciBpcyBhbiBvYmplY3QgdXNlZCB0byBpbmZvcm0gdGhl IFBNIHN1YnN5c3RlbSB3aGVuIHRoZSBzeXN0ZW0KK2NhbiBvciBjYW5ub3QgYmUgc3VzcGVuZGVk IGluIHRoZSAib3Bwb3J0dW5pc3RpYyIgbW9kZSAodGhlICJmb3JjZWQiIG1vZGUKK2lnbm9yZXMg c3VzcGVuZCBibG9ja2VycykuICBUbyB1c2UgaXQsIGEgZGV2aWNlIGRyaXZlciBjcmVhdGVzIGEg c3RydWN0CitzdXNwZW5kX2Jsb2NrZXIgdGhhdCBtdXN0IGJlIGluaXRpYWxpemVkIHdpdGggc3Vz cGVuZF9ibG9ja2VyX2luaXQoKS4gQmVmb3JlCitmcmVlaW5nIHRoZSBzdXNwZW5kX2Jsb2NrZXIg c3RydWN0dXJlIG9yIGl0cyBuYW1lLCBzdXNwZW5kX2Jsb2NrZXJfdW5yZWdpc3RlcigpCittdXN0 IGJlIGNhbGxlZCBvbiBpdC4KKworQSBzdXNwZW5kIGJsb2NrZXIgaXMgYWN0aXZhdGVkIHVzaW5n IHN1c3BlbmRfYmxvY2soKSwgd2hpY2ggcHJldmVudHMgdGhlIFBNCitzdWJzeXN0ZW0gZnJvbSBw dXR0aW5nIHRoZSBzeXN0ZW0gaW50byB0aGUgcmVxdWVzdGVkIHNsZWVwIHN0YXRlIGluIHRoZQor Im9wcG9ydHVuaXN0aWMiIG1vZGUgdW50aWwgdGhlIHN1c3BlbmQgYmxvY2tlciBpcyBkZWFjdGl2 YXRlZCB3aXRoCitzdXNwZW5kX3VuYmxvY2soKS4gTXVsdGlwbGUgc3VzcGVuZCBibG9ja2VycyBt YXkgYmUgYWN0aXZlIHNpbXVsdGFuZW91c2x5LCBhbmQKK3RoZSBzeXN0ZW0gd2lsbCBub3Qgc3Vz cGVuZCBhcyBsb25nIGFzIGF0IGxlYXN0IG9uZSBvZiB0aGVtIGlzIGFjdGl2ZS4KKworSWYgb3Bw b3J0dW5pc3RpYyBzdXNwZW5kIGlzIGFscmVhZHkgaW4gcHJvZ3Jlc3Mgd2hlbiBzdXNwZW5kX2Js b2NrKCkgaXMgY2FsbGVkLAoraXQgd2lsbCBhYm9ydCB0aGUgc3VzcGVuZCwgdW5sZXNzIHN1c3Bl bmRfb3BzLT5lbnRlciBoYXMgYWxyZWFkeSBiZWVuCitleGVjdXRlZC4gSWYgc3VzcGVuZCBpcyBh Ym9ydGVkIHRoaXMgd2F5LCB0aGUgc3lzdGVtIGlzIHVzdWFsbHkgbm90IGZ1bGx5CitvcGVyYXRp b25hbCBhdCB0aGF0IHBvaW50LiBUaGUgc3VzcGVuZCBjYWxsYmFja3Mgb2Ygc29tZSBkcml2ZXJz IG1heSBzdGlsbCBiZQorcnVubmluZyBhbmQgaXQgdXN1YWxseSB0YWtlcyB0aW1lIHRvIHJlc3Rv cmUgdGhlIHN5c3RlbSB0byB0aGUgZnVsbHkgb3BlcmF0aW9uYWwKK3N0YXRlLgorCitIZXJlJ3Mg YW4gZXhhbXBsZSBzaG93aW5nIGhvdyBhIGNlbGwgcGhvbmUgb3Igb3RoZXIgZW1iZWRkZWQgc3lz dGVtIGNhbiBoYW5kbGUKK2tleXN0cm9rZXMgKG9yIG90aGVyIGlucHV0IGV2ZW50cykgaW4gdGhl IHByZXNlbmNlIG9mIHN1c3BlbmQgYmxvY2tlcnMuIFVzZQorc2V0X2lycV93YWtlIG9yIGEgcGxh dGZvcm0gc3BlY2lmaWMgQVBJIHRvIG1ha2Ugc3VyZSB0aGUga2V5cGFkIGludGVycnVwdCB3YWtl cwordXAgdGhlIGNwdS4gT25jZSB0aGUga2V5cGFkIGRyaXZlciBoYXMgcmVzdW1lZCwgdGhlIHNl cXVlbmNlIG9mIGV2ZW50cyBjYW4gbG9vaworbGlrZSB0aGlzOgorCistIFRoZSBLZXlwYWQgZHJp dmVyIGdldHMgYW4gaW50ZXJydXB0LiBJdCB0aGVuIGNhbGxzIHN1c3BlbmRfYmxvY2sgb24gdGhl CisgIGtleXBhZC1zY2FuIHN1c3BlbmRfYmxvY2tlciBhbmQgc3RhcnRzIHNjYW5uaW5nIHRoZSBr ZXlwYWQgbWF0cml4LgorLSBUaGUga2V5cGFkLXNjYW4gY29kZSBkZXRlY3RzIGEga2V5IGNoYW5n ZSBhbmQgcmVwb3J0cyBpdCB0byB0aGUgaW5wdXQtZXZlbnQKKyAgZHJpdmVyLgorLSBUaGUgaW5w dXQtZXZlbnQgZHJpdmVyIHNlZXMgdGhlIGtleSBjaGFuZ2UsIGVucXVldWVzIGFuIGV2ZW50LCBh bmQgY2FsbHMKKyAgc3VzcGVuZF9ibG9jayBvbiB0aGUgaW5wdXQtZXZlbnQtcXVldWUgc3VzcGVu ZF9ibG9ja2VyLgorLSBUaGUga2V5cGFkLXNjYW4gY29kZSBkZXRlY3RzIHRoYXQgbm8ga2V5cyBh cmUgaGVsZCBhbmQgY2FsbHMgc3VzcGVuZF91bmJsb2NrCisgIG9uIHRoZSBrZXlwYWQtc2NhbiBz dXNwZW5kX2Jsb2NrZXIuCistIFRoZSB1c2VyLXNwYWNlIGlucHV0LWV2ZW50IHRocmVhZCByZXR1 cm5zIGZyb20gc2VsZWN0L3BvbGwsIGNhbGxzCisgIHN1c3BlbmRfYmxvY2sgb24gdGhlIHByb2Nl c3MtaW5wdXQtZXZlbnRzIHN1c3BlbmRfYmxvY2tlciBhbmQgdGhlbiBjYWxscyByZWFkCisgIG9u IHRoZSBpbnB1dC1ldmVudCBkZXZpY2UuCistIFRoZSBpbnB1dC1ldmVudCBkcml2ZXIgZGVxdWV1 ZXMgdGhlIGtleS1ldmVudCBhbmQsIHNpbmNlIHRoZSBxdWV1ZSBpcyBub3cKKyAgZW1wdHksIGl0 IGNhbGxzIHN1c3BlbmRfdW5ibG9jayBvbiB0aGUgaW5wdXQtZXZlbnQtcXVldWUgc3VzcGVuZF9i bG9ja2VyLgorLSBUaGUgdXNlci1zcGFjZSBpbnB1dC1ldmVudCB0aHJlYWQgcmV0dXJucyBmcm9t IHJlYWQuIElmIGl0IGRldGVybWluZXMgdGhhdAorICB0aGUga2V5IHNob3VsZCBiZSBpZ25vcmVk LCBpdCBjYWxscyBzdXNwZW5kX3VuYmxvY2sgb24gdGhlCisgIHByb2Nlc3NfaW5wdXRfZXZlbnRz IHN1c3BlbmRfYmxvY2tlciBhbmQgdGhlbiBjYWxscyBzZWxlY3Qgb3IgcG9sbC4gVGhlCisgIHN5 c3RlbSB3aWxsIGF1dG9tYXRpY2FsbHkgc3VzcGVuZCBhZ2Fpbiwgc2luY2Ugbm93IG5vIHN1c3Bl bmQgYmxvY2tlcnMgYXJlCisgIGFjdGl2ZS4KKworSWYgdGhlIGtleSB0aGF0IHdhcyBwcmVzc2Vk IGluc3RlYWQgc2hvdWxkIHByZWZvcm0gYSBzaW1wbGUgYWN0aW9uIChmb3IgZXhhbXBsZSwKK2Fk anVzdGluZyB0aGUgdm9sdW1lKSwgdGhpcyBhY3Rpb24gY2FuIGJlIHBlcmZvcm1lZCByaWdodCBi ZWZvcmUgY2FsbGluZworc3VzcGVuZF91bmJsb2NrIG9uIHRoZSBwcm9jZXNzX2lucHV0X2V2ZW50 cyBzdXNwZW5kX2Jsb2NrZXIuIEhvd2V2ZXIsIGlmIHRoZSBrZXkKK3RyaWdnZXJzIGEgbG9uZ2Vy LXJ1bm5pbmcgYWN0aW9uLCB0aGF0IGFjdGlvbiBuZWVkcyBpdHMgb3duIHN1c3BlbmRfYmxvY2tl ciBhbmQKK3N1c3BlbmRfYmxvY2sgbXVzdCBiZSBjYWxsZWQgb24gdGhhdCBzdXNwZW5kIGJsb2Nr ZXIgYmVmb3JlIGNhbGxpbmcKK3N1c3BlbmRfdW5ibG9jayBvbiB0aGUgcHJvY2Vzc19pbnB1dF9l dmVudHMgc3VzcGVuZF9ibG9ja2VyLgorCisgICAgICAgICAgICAgICAgIEtleSBwcmVzc2VkICAg S2V5IHJlbGVhc2VkCisgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgIHwKK2tleXBh ZC1zY2FuICAgICAgICAgICsrKysrKysrKysrKysrKysrKworaW5wdXQtZXZlbnQtcXVldWUgICAg ICAgICsrKyAgICAgICAgICArKysKK3Byb2Nlc3MtaW5wdXQtZXZlbnRzICAgICAgICsrKyAgICAg ICAgICArKysKKworCitEcml2ZXIgQVBJCis9PT09PT09PT09CisKK0EgZHJpdmVyIGNhbiB1c2Ug dGhlIHN1c3BlbmQgYmxvY2sgQVBJIGJ5IGFkZGluZyBhIHN1c3BlbmRfYmxvY2tlciB2YXJpYWJs ZSB0bworaXRzIHN0YXRlIGFuZCBjYWxsaW5nIHN1c3BlbmRfYmxvY2tlcl9pbml0KCkuIEZvciBp bnN0YW5jZToKKworc3RydWN0IHN0YXRlIHsKKwlzdHJ1Y3Qgc3VzcGVuZF9ibG9ja2VyIHN1c3Bl bmRfYmxvY2tlcjsKK30KKworaW5pdCgpIHsKKwlzdXNwZW5kX2Jsb2NrZXJfaW5pdCgmc3RhdGUt PnN1c3BlbmRfYmxvY2tlciwgbmFtZSk7Cit9CisKK0lmIHRoZSBzdXNwZW5kX2Jsb2NrZXIgdmFy aWFibGUgaXMgYWxsb2NhdGVkIHN0YXRpY2FsbHksCitERUZJTkVfU1VTUEVORF9CTE9DS0VSKCkg c2hvdWxkIGJlIHVzZWQgdG8gaW5pdGlhbGl6ZSBpdCwgZm9yIGV4YW1wbGU6CisKK3N0YXRpYyBE RUZJTkVfU1VTUEVORF9CTE9DS0VSKGJsb2NrZXIsIG5hbWUpOworCithbmQgc3VzcGVuZF9ibG9j a2VyX3JlZ2lzdGVyKCZibG9ja2VyKSBoYXMgdG8gYmUgY2FsbGVkIHRvIG1ha2UgdGhlIHN1c3Bl bmQKK2Jsb2NrZXIgdXNhYmxlLgorCitCZWZvcmUgZnJlZWluZyB0aGUgbWVtb3J5IGluIHdoaWNo IGEgc3VzcGVuZF9ibG9ja2VyIHZhcmlhYmxlIGlzIGxvY2F0ZWQsCitzdXNwZW5kX2Jsb2NrZXJf dW5yZWdpc3RlcigpIG11c3QgYmUgY2FsbGVkLCBmb3IgaW5zdGFuY2U6CisKK3VuaW5pdCgpIHsK KwlzdXNwZW5kX2Jsb2NrZXJfdW5yZWdpc3Rlcigmc3RhdGUtPnN1c3BlbmRfYmxvY2tlcik7Cit9 CisKK1doZW4gdGhlIGRyaXZlciBkZXRlcm1pbmVzIHRoYXQgaXQgbmVlZHMgdG8gcnVuICh1c3Vh bGx5IGluIGFuIGludGVycnVwdAoraGFuZGxlcikgaXQgY2FsbHMgc3VzcGVuZF9ibG9jaygpOgor CisJc3VzcGVuZF9ibG9jaygmc3RhdGUtPnN1c3BlbmRfYmxvY2tlcik7CisKK1doZW4gaXQgbm8g bG9uZ2VyIG5lZWRzIHRvIHJ1biBpdCBjYWxscyBzdXNwZW5kX3VuYmxvY2soKToKKworCXN1c3Bl bmRfdW5ibG9jaygmc3RhdGUtPnN1c3BlbmRfYmxvY2tlcik7CisKK0NhbGxpbmcgc3VzcGVuZF9i bG9jaygpIHdoZW4gdGhlIHN1c3BlbmQgYmxvY2tlciBpcyBhY3RpdmUgb3Igc3VzcGVuZF91bmJs b2NrKCkKK3doZW4gaXQgaXMgbm90IGFjdGl2ZSBoYXMgbm8gZWZmZWN0IChpLmUuLCB0aGVzZSBm dW5jdGlvbnMgZG9uJ3QgbmVzdCkuIFRoaXMKK2FsbG93cyBkcml2ZXJzIHRvIHVwZGF0ZSB0aGVp ciBzdGF0ZSBhbmQgY2FsbCBzdXNwZW5kIHN1c3BlbmRfYmxvY2soKSBvcgorc3VzcGVuZF91bmJs b2NrKCkgYmFzZWQgb24gdGhlIHJlc3VsdC4gRm9yIGluc3RhbmNlOgorCitpZiAobGlzdF9lbXB0 eSgmc3RhdGUtPnBlbmRpbmdfd29yaykpCisJc3VzcGVuZF91bmJsb2NrKCZzdGF0ZS0+c3VzcGVu ZF9ibG9ja2VyKTsKK2Vsc2UKKwlzdXNwZW5kX2Jsb2NrKCZzdGF0ZS0+c3VzcGVuZF9ibG9ja2Vy KTsKZGlmZiAtLWdpdCBhL2luY2x1ZGUvbGludXgvc3VzcGVuZC5oIGIvaW5jbHVkZS9saW51eC9z dXNwZW5kLmgKaW5kZXggNWU3ODFkOC4uMDcwMjNkMyAxMDA2NDQKLS0tIGEvaW5jbHVkZS9saW51 eC9zdXNwZW5kLmgKKysrIGIvaW5jbHVkZS9saW51eC9zdXNwZW5kLmgKQEAgLTYsNiArNiw3IEBA CiAjaW5jbHVkZSA8bGludXgvaW5pdC5oPgogI2luY2x1ZGUgPGxpbnV4L3BtLmg+CiAjaW5jbHVk ZSA8bGludXgvbW0uaD4KKyNpbmNsdWRlIDxsaW51eC9zdXNwZW5kX2Jsb2NrZXIuaD4KICNpbmNs dWRlIDxhc20vZXJybm8uaD4KIAogI2lmIGRlZmluZWQoQ09ORklHX1BNX1NMRUVQKSAmJiBkZWZp bmVkKENPTkZJR19WVCkgJiYgZGVmaW5lZChDT05GSUdfVlRfQ09OU09MRSkKZGlmZiAtLWdpdCBh L2luY2x1ZGUvbGludXgvc3VzcGVuZF9ibG9ja2VyLmggYi9pbmNsdWRlL2xpbnV4L3N1c3BlbmRf YmxvY2tlci5oCm5ldyBmaWxlIG1vZGUgMTAwNzU1CmluZGV4IDAwMDAwMDAuLjg3ODgzMDIKLS0t IC9kZXYvbnVsbAorKysgYi9pbmNsdWRlL2xpbnV4L3N1c3BlbmRfYmxvY2tlci5oCkBAIC0wLDAg KzEsNzQgQEAKKy8qIGluY2x1ZGUvbGludXgvc3VzcGVuZF9ibG9ja2VyLmgKKyAqCisgKiBDb3B5 cmlnaHQgKEMpIDIwMDctMjAxMCBHb29nbGUsIEluYy4KKyAqCisgKiBUaGlzIHNvZnR3YXJlIGlz IGxpY2Vuc2VkIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljCisgKiBM aWNlbnNlIHZlcnNpb24gMiwgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5k YXRpb24sIGFuZAorICogbWF5IGJlIGNvcGllZCwgZGlzdHJpYnV0ZWQsIGFuZCBtb2RpZmllZCB1 bmRlciB0aG9zZSB0ZXJtcy4KKyAqCisgKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4g dGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKKyAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJS QU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCisgKiBNRVJDSEFOVEFC SUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCisgKiBH TlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgorICoKKyAqLworCisj aWZuZGVmIF9MSU5VWF9TVVNQRU5EX0JMT0NLRVJfSAorI2RlZmluZSBfTElOVVhfU1VTUEVORF9C TE9DS0VSX0gKKworI2luY2x1ZGUgPGxpbnV4L2xpc3QuaD4KKworLyoqCisgKiBzdHJ1Y3Qgc3Vz cGVuZF9ibG9ja2VyIC0gdGhlIGJhc2ljIHN1c3BlbmRfYmxvY2tlciBzdHJ1Y3R1cmUKKyAqIEBs aW5rOiBMaXN0IGVudHJ5IGZvciBhY3RpdmUgb3IgaW5hY3RpdmUgbGlzdC4KKyAqIEBmbGFnczog VHJhY2tzIGluaXRpYWxpemVkIGFuZCBhY3RpdmUgc3RhdGUuCisgKiBAbmFtZTogU3VzcGVuZCBi bG9ja2VyIG5hbWUgdXNlZCBmb3IgZGVidWdnaW5nLgorICoKKyAqIFdoZW4gYSBzdXNwZW5kX2Js b2NrZXIgaXMgYWN0aXZlIGl0IHByZXZlbnRzIHRoZSBzeXN0ZW0gZnJvbSBlbnRlcmluZworICog b3Bwb3J0dW5pc3RpYyBzdXNwZW5kLgorICoKKyAqIFRoZSBzdXNwZW5kX2Jsb2NrZXIgc3RydWN0 dXJlIG11c3QgYmUgaW5pdGlhbGl6ZWQgYnkgc3VzcGVuZF9ibG9ja2VyX2luaXQoKQorICovCitz dHJ1Y3Qgc3VzcGVuZF9ibG9ja2VyIHsKKyNpZmRlZiBDT05GSUdfT1BQT1JUVU5JU1RJQ19TVVNQ RU5ECisJc3RydWN0IGxpc3RfaGVhZCBsaW5rOworCWludCBmbGFnczsKKwljb25zdCBjaGFyICpu YW1lOworI2VuZGlmCit9OworCisjaWZkZWYgQ09ORklHX09QUE9SVFVOSVNUSUNfU1VTUEVORAor I2RlZmluZSBfX1NVU1BFTkRfQkxPQ0tFUl9JTklUSUFMSVpFUihibG9ja2VyX25hbWUpIFwKKwl7 IC5uYW1lID0gI2Jsb2NrZXJfbmFtZSwgfQorCisjZGVmaW5lIERFRklORV9TVVNQRU5EX0JMT0NL RVIoYmxvY2tlciwgbmFtZSkgXAorCXN0cnVjdCBzdXNwZW5kX2Jsb2NrZXIgYmxvY2tlciA9IF9f U1VTUEVORF9CTE9DS0VSX0lOSVRJQUxJWkVSKG5hbWUpCisKK2V4dGVybiB2b2lkIHN1c3BlbmRf YmxvY2tlcl9yZWdpc3RlcihzdHJ1Y3Qgc3VzcGVuZF9ibG9ja2VyICpibG9ja2VyKTsKK2V4dGVy biB2b2lkIHN1c3BlbmRfYmxvY2tlcl9pbml0KHN0cnVjdCBzdXNwZW5kX2Jsb2NrZXIgKmJsb2Nr ZXIsCisJCQkJIGNvbnN0IGNoYXIgKm5hbWUpOworZXh0ZXJuIHZvaWQgc3VzcGVuZF9ibG9ja2Vy X3VucmVnaXN0ZXIoc3RydWN0IHN1c3BlbmRfYmxvY2tlciAqYmxvY2tlcik7CitleHRlcm4gdm9p ZCBzdXNwZW5kX2Jsb2NrKHN0cnVjdCBzdXNwZW5kX2Jsb2NrZXIgKmJsb2NrZXIpOworZXh0ZXJu IHZvaWQgc3VzcGVuZF91bmJsb2NrKHN0cnVjdCBzdXNwZW5kX2Jsb2NrZXIgKmJsb2NrZXIpOwor ZXh0ZXJuIGJvb2wgc3VzcGVuZF9ibG9ja2VyX2lzX2FjdGl2ZShzdHJ1Y3Qgc3VzcGVuZF9ibG9j a2VyICpibG9ja2VyKTsKK2V4dGVybiBib29sIHN1c3BlbmRfaXNfYmxvY2tlZCh2b2lkKTsKKwor I2Vsc2UKKworI2RlZmluZSBERUZJTkVfU1VTUEVORF9CTE9DS0VSKGJsb2NrZXIsIG5hbWUpIFwK KwlzdHJ1Y3Qgc3VzcGVuZF9ibG9ja2VyIGJsb2NrZXIKKworc3RhdGljIGlubGluZSB2b2lkIHN1 c3BlbmRfYmxvY2tlcl9yZWdpc3RlcihzdHJ1Y3Qgc3VzcGVuZF9ibG9ja2VyICpibCkge30KK3N0 YXRpYyBpbmxpbmUgdm9pZCBzdXNwZW5kX2Jsb2NrZXJfaW5pdChzdHJ1Y3Qgc3VzcGVuZF9ibG9j a2VyICpibCwKKwkJCQkJY29uc3QgY2hhciAqbikge30KK3N0YXRpYyBpbmxpbmUgdm9pZCBzdXNw ZW5kX2Jsb2NrZXJfdW5yZWdpc3RlcihzdHJ1Y3Qgc3VzcGVuZF9ibG9ja2VyICpibCkge30KK3N0 YXRpYyBpbmxpbmUgdm9pZCBzdXNwZW5kX2Jsb2NrKHN0cnVjdCBzdXNwZW5kX2Jsb2NrZXIgKmJs KSB7fQorc3RhdGljIGlubGluZSB2b2lkIHN1c3BlbmRfdW5ibG9jayhzdHJ1Y3Qgc3VzcGVuZF9i bG9ja2VyICpibCkge30KK3N0YXRpYyBpbmxpbmUgYm9vbCBzdXNwZW5kX2Jsb2NrZXJfaXNfYWN0 aXZlKHN0cnVjdCBzdXNwZW5kX2Jsb2NrZXIgKmJsKQoreworCXJldHVybiBmYWxzZTsKK30KK3N0 YXRpYyBpbmxpbmUgYm9vbCBzdXNwZW5kX2lzX2Jsb2NrZWQodm9pZCkgeyByZXR1cm4gZmFsc2U7 IH0KKyNlbmRpZgorCisjZW5kaWYKZGlmZiAtLWdpdCBhL2tlcm5lbC9wb3dlci9LY29uZmlnIGIv a2VybmVsL3Bvd2VyL0tjb25maWcKaW5kZXggNWMzNmVhOS4uNmQxMWE0NSAxMDA2NDQKLS0tIGEv a2VybmVsL3Bvd2VyL0tjb25maWcKKysrIGIva2VybmVsL3Bvd2VyL0tjb25maWcKQEAgLTEzMCw2 ICsxMzAsMjIgQEAgY29uZmlnIFNVU1BFTkRfRlJFRVpFUgogCiAJICBUdXJuaW5nIE9GRiB0aGlz IHNldHRpbmcgaXMgTk9UIHJlY29tbWVuZGVkISBJZiBpbiBkb3VidCwgc2F5IFkuCiAKK2NvbmZp ZyBPUFBPUlRVTklTVElDX1NVU1BFTkQKKwlib29sICJPcHBvcnR1bmlzdGljIHN1c3BlbmQiCisJ ZGVwZW5kcyBvbiBTVVNQRU5ECisJc2VsZWN0IFJUQ19MSUIKKwlkZWZhdWx0IG4KKwktLS1oZWxw LS0tCisJICBPcHBvcnR1bmlzdGljIHNsZWVwIHN1cHBvcnQuICBBbGxvd3MgdGhlIHN5c3RlbSB0 byBiZSBwdXQgaW50byBhIHNsZWVwCisJICBzdGF0ZSBvcHBvcnR1bmlzdGljYWxseSwgaWYgaXQg ZG9lc24ndCBkbyBhbnkgdXNlZnVsIHdvcmsgYXQgdGhlCisJICBtb21lbnQuIFRoZSBQTSBzdWJz eXN0ZW0gaXMgc3dpdGNoZWQgaW50byB0aGlzIG1vZGUgb2Ygb3BlcmF0aW9uIGJ5CisJICB3cml0 aW5nICJvcHBvcnR1bmlzdGljIiBpbnRvIC9zeXMvcG93ZXIvcG9saWN5LCB3aGlsZSB3cml0aW5n CisJICAiZm9yY2VkIiB0byB0aGlzIGZpbGUgdHVybnMgdGhlIG9wcG9ydHVuaXN0aWMgc3VzcGVu ZCBmZWF0dXJlIG9mZi4KKwkgIEluIHRoZSAib3Bwb3J0dW5pc3RpYyIgbW9kZSBzdXNwZW5kIGJs b2NrZXJzIGFyZSB1c2VkIHRvIGRldGVybWluZQorCSAgd2hlbiB0byBzdXNwZW5kIHRoZSBzeXN0 ZW0gYW5kIHRoZSB2YWx1ZSB3cml0dGVuIHRvIC9zeXMvcG93ZXIvc3RhdGUKKwkgIGRldGVybWlu ZXMgdGhlIHNsZWVwIHN0YXRlIHRoZSBzeXN0ZW0gd2lsbCBiZSBwdXQgaW50byB3aGVuIHRoZXJl IGFyZQorCSAgbm8gYWN0aXZlIHN1c3BlbmQgYmxvY2tlcnMuCisKIGNvbmZpZyBISUJFUk5BVElP Tl9OVlMKIAlib29sCiAKZGlmZiAtLWdpdCBhL2tlcm5lbC9wb3dlci9NYWtlZmlsZSBiL2tlcm5l bC9wb3dlci9NYWtlZmlsZQppbmRleCA0MzE5MTgxLi45NWQ4ZTZkIDEwMDY0NAotLS0gYS9rZXJu ZWwvcG93ZXIvTWFrZWZpbGUKKysrIGIva2VybmVsL3Bvd2VyL01ha2VmaWxlCkBAIC03LDYgKzcs NyBAQCBvYmotJChDT05GSUdfUE0pCQkrPSBtYWluLm8KIG9iai0kKENPTkZJR19QTV9TTEVFUCkJ CSs9IGNvbnNvbGUubwogb2JqLSQoQ09ORklHX0ZSRUVaRVIpCQkrPSBwcm9jZXNzLm8KIG9iai0k KENPTkZJR19TVVNQRU5EKQkJKz0gc3VzcGVuZC5vCitvYmotJChDT05GSUdfT1BQT1JUVU5JU1RJ Q19TVVNQRU5EKQkrPSBvcHBvcnR1bmlzdGljX3N1c3BlbmQubwogb2JqLSQoQ09ORklHX1BNX1RF U1RfU1VTUEVORCkJKz0gc3VzcGVuZF90ZXN0Lm8KIG9iai0kKENPTkZJR19ISUJFUk5BVElPTikJ Kz0gaGliZXJuYXRlLm8gc25hcHNob3QubyBzd2FwLm8gdXNlci5vCiBvYmotJChDT05GSUdfSElC RVJOQVRJT05fTlZTKQkrPSBoaWJlcm5hdGVfbnZzLm8KZGlmZiAtLWdpdCBhL2tlcm5lbC9wb3dl ci9tYWluLmMgYi9rZXJuZWwvcG93ZXIvbWFpbi5jCmluZGV4IGI1ODgwMGIuLmFmYmI0ZGQgMTAw NjQ0Ci0tLSBhL2tlcm5lbC9wb3dlci9tYWluLmMKKysrIGIva2VybmVsL3Bvd2VyL21haW4uYwpA QCAtMjAsNiArMjAsNTggQEAgREVGSU5FX01VVEVYKHBtX211dGV4KTsKIHVuc2lnbmVkIGludCBw bV9mbGFnczsKIEVYUE9SVF9TWU1CT0wocG1fZmxhZ3MpOwogCisjaWZkZWYgQ09ORklHX09QUE9S VFVOSVNUSUNfU1VTUEVORAorc3RydWN0IHBtX3BvbGljeSB7CisJY29uc3QgY2hhciAqbmFtZTsK Kwlib29sICgqdmFsaWRfc3RhdGUpKHN1c3BlbmRfc3RhdGVfdCBzdGF0ZSk7CisJaW50ICgqc2V0 X3N0YXRlKShzdXNwZW5kX3N0YXRlX3Qgc3RhdGUpOworfTsKKworc3RhdGljIHN0cnVjdCBwbV9w b2xpY3kgcG9saWNpZXNbXSA9IHsKKwl7CisJCS5uYW1lCQk9ICJmb3JjZWQiLAorCQkudmFsaWRf c3RhdGUJPSB2YWxpZF9zdGF0ZSwKKwkJLnNldF9zdGF0ZQk9IGVudGVyX3N0YXRlLAorCX0sCisJ eworCQkubmFtZQkJPSAib3Bwb3J0dW5pc3RpYyIsCisJCS52YWxpZF9zdGF0ZQk9IG9wcG9ydHVu aXN0aWNfc3VzcGVuZF92YWxpZF9zdGF0ZSwKKwkJLnNldF9zdGF0ZQk9IG9wcG9ydHVuaXN0aWNf c3VzcGVuZF9zdGF0ZSwKKwl9LAorfTsKKworc3RhdGljIGludCBwb2xpY3k7CisKK3N0YXRpYyBp bmxpbmUgYm9vbCBoaWJlcm5hdGlvbl9zdXBwb3J0ZWQodm9pZCkKK3sKKwlyZXR1cm4gIXN0cm5j bXAocG9saWNpZXNbcG9saWN5XS5uYW1lLCAiZm9yY2VkIiwgNik7Cit9CisKK3N0YXRpYyBpbmxp bmUgYm9vbCBwbV9zdGF0ZV92YWxpZChpbnQgc3RhdGVfaWR4KQoreworCXJldHVybiBwbV9zdGF0 ZXNbc3RhdGVfaWR4XSAmJiBwb2xpY2llc1twb2xpY3ldLnZhbGlkX3N0YXRlKHN0YXRlX2lkeCk7 Cit9CisKK3N0YXRpYyBpbmxpbmUgaW50IHBtX2VudGVyX3N0YXRlKGludCBzdGF0ZV9pZHgpCit7 CisJcmV0dXJuIHBvbGljaWVzW3BvbGljeV0uc2V0X3N0YXRlKHN0YXRlX2lkeCk7Cit9CisKKyNl bHNlCisKK3N0YXRpYyBpbmxpbmUgYm9vbCBoaWJlcm5hdGlvbl9zdXBwb3J0ZWQodm9pZCkgeyBy ZXR1cm4gdHJ1ZTsgfQorCitzdGF0aWMgaW5saW5lIGJvb2wgcG1fc3RhdGVfdmFsaWQoaW50IHN0 YXRlX2lkeCkKK3sKKwlyZXR1cm4gcG1fc3RhdGVzW3N0YXRlX2lkeF0gJiYgdmFsaWRfc3RhdGUo c3RhdGVfaWR4KTsKK30KKworc3RhdGljIGlubGluZSBpbnQgcG1fZW50ZXJfc3RhdGUoaW50IHN0 YXRlX2lkeCkKK3sKKwlyZXR1cm4gZW50ZXJfc3RhdGUoc3RhdGVfaWR4KTsKK30KKyNlbmRpZiAv KiBDT05GSUdfT1BQT1JUVU5JU1RJQ19TVVNQRU5EICovCisKICNpZmRlZiBDT05GSUdfUE1fU0xF RVAKIAogLyogUm91dGluZXMgZm9yIFBNLXRyYW5zaXRpb24gbm90aWZpY2F0aW9ucyAqLwpAQCAt MTQ2LDYgKzE5OCwxMiBAQCBzdHJ1Y3Qga29iamVjdCAqcG93ZXJfa29iajsKICAqCiAgKglzdG9y ZSgpIGFjY2VwdHMgb25lIG9mIHRob3NlIHN0cmluZ3MsIHRyYW5zbGF0ZXMgaXQgaW50byB0aGUg CiAgKglwcm9wZXIgZW51bWVyYXRlZCB2YWx1ZSwgYW5kIGluaXRpYXRlcyBhIHN1c3BlbmQgdHJh bnNpdGlvbi4KKyAqCisgKglJZiBwb2xpY3kgaXMgc2V0IHRvIG9wcG9ydHVuaXN0aWMsIHN0b3Jl KCkgZG9lcyBub3QgYmxvY2sgdW50aWwgdGhlCisgKglzeXN0ZW0gcmVzdW1lcywgYW5kIGl0IHdp bGwgdHJ5IHRvIHJlLWVudGVyIHRoZSBzdGF0ZSB1bnRpbCBhbm90aGVyCisgKglzdGF0ZSBpcyBy ZXF1ZXN0ZWQuIFN1c3BlbmQgYmxvY2tlcnMgYXJlIHJlc3BlY3RlZCBhbmQgdGhlIHJlcXVlc3Rl ZAorICoJc3RhdGUgd2lsbCBvbmx5IGJlIGVudGVyZWQgd2hlbiBubyBzdXNwZW5kIGJsb2NrZXJz IGFyZSBhY3RpdmUuCisgKglXcml0ZSAib24iIHRvIGRpc2FibGUuCiAgKi8KIHN0YXRpYyBzc2l6 ZV90IHN0YXRlX3Nob3coc3RydWN0IGtvYmplY3QgKmtvYmosIHN0cnVjdCBrb2JqX2F0dHJpYnV0 ZSAqYXR0ciwKIAkJCSAgY2hhciAqYnVmKQpAQCAtMTU1LDEyICsyMTMsMTMgQEAgc3RhdGljIHNz aXplX3Qgc3RhdGVfc2hvdyhzdHJ1Y3Qga29iamVjdCAqa29iaiwgc3RydWN0IGtvYmpfYXR0cmli dXRlICphdHRyLAogCWludCBpOwogCiAJZm9yIChpID0gMDsgaSA8IFBNX1NVU1BFTkRfTUFYOyBp KyspIHsKLQkJaWYgKHBtX3N0YXRlc1tpXSAmJiB2YWxpZF9zdGF0ZShpKSkKKwkJaWYgKHBtX3N0 YXRlX3ZhbGlkKGkpKQogCQkJcyArPSBzcHJpbnRmKHMsIiVzICIsIHBtX3N0YXRlc1tpXSk7CiAJ fQogI2VuZGlmCiAjaWZkZWYgQ09ORklHX0hJQkVSTkFUSU9OCi0JcyArPSBzcHJpbnRmKHMsICIl c1xuIiwgImRpc2siKTsKKwlpZiAoaGliZXJuYXRpb25fc3VwcG9ydGVkKCkpCisJCXMgKz0gc3By aW50ZihzLCAiJXNcbiIsICJkaXNrIik7CiAjZWxzZQogCWlmIChzICE9IGJ1ZikKIAkJLyogY29u dmVydCB0aGUgbGFzdCBzcGFjZSB0byBhIG5ld2xpbmUgKi8KQEAgLTE3Myw3ICsyMzIsNyBAQCBz dGF0aWMgc3NpemVfdCBzdGF0ZV9zdG9yZShzdHJ1Y3Qga29iamVjdCAqa29iaiwgc3RydWN0IGtv YmpfYXR0cmlidXRlICphdHRyLAogCQkJICAgY29uc3QgY2hhciAqYnVmLCBzaXplX3QgbikKIHsK ICNpZmRlZiBDT05GSUdfU1VTUEVORAotCXN1c3BlbmRfc3RhdGVfdCBzdGF0ZSA9IFBNX1NVU1BF TkRfU1RBTkRCWTsKKwlzdXNwZW5kX3N0YXRlX3Qgc3RhdGUgPSBQTV9TVVNQRU5EX09OOwogCWNv bnN0IGNoYXIgKiBjb25zdCAqczsKICNlbmRpZgogCWNoYXIgKnA7CkBAIC0xODUsOCArMjQ0LDkg QEAgc3RhdGljIHNzaXplX3Qgc3RhdGVfc3RvcmUoc3RydWN0IGtvYmplY3QgKmtvYmosIHN0cnVj dCBrb2JqX2F0dHJpYnV0ZSAqYXR0ciwKIAogCS8qIEZpcnN0LCBjaGVjayBpZiB3ZSBhcmUgcmVx dWVzdGVkIHRvIGhpYmVybmF0ZSAqLwogCWlmIChsZW4gPT0gNCAmJiAhc3RybmNtcChidWYsICJk aXNrIiwgbGVuKSkgewotCQllcnJvciA9IGhpYmVybmF0ZSgpOwotICBnb3RvIEV4aXQ7CisJCWlm IChoaWJlcm5hdGlvbl9zdXBwb3J0ZWQoKSkKKwkJCWVycm9yID0gaGliZXJuYXRlKCk7CisJCWdv dG8gRXhpdDsKIAl9CiAKICNpZmRlZiBDT05GSUdfU1VTUEVORApAQCAtMTk1LDcgKzI1NSw3IEBA IHN0YXRpYyBzc2l6ZV90IHN0YXRlX3N0b3JlKHN0cnVjdCBrb2JqZWN0ICprb2JqLCBzdHJ1Y3Qg a29ial9hdHRyaWJ1dGUgKmF0dHIsCiAJCQlicmVhazsKIAl9CiAJaWYgKHN0YXRlIDwgUE1fU1VT UEVORF9NQVggJiYgKnMpCi0JCWVycm9yID0gZW50ZXJfc3RhdGUoc3RhdGUpOworCQllcnJvciA9 IHBtX2VudGVyX3N0YXRlKHN0YXRlKTsKICNlbmRpZgogCiAgRXhpdDoKQEAgLTIwNCw2ICsyNjQs NTYgQEAgc3RhdGljIHNzaXplX3Qgc3RhdGVfc3RvcmUoc3RydWN0IGtvYmplY3QgKmtvYmosIHN0 cnVjdCBrb2JqX2F0dHJpYnV0ZSAqYXR0ciwKIAogcG93ZXJfYXR0cihzdGF0ZSk7CiAKKyNpZmRl ZiBDT05GSUdfT1BQT1JUVU5JU1RJQ19TVVNQRU5ECisvKioKKyAqCXBvbGljeSAtIHNldCBwb2xp Y3kgZm9yIHN0YXRlCisgKi8KK3N0YXRpYyBzc2l6ZV90IHBvbGljeV9zaG93KHN0cnVjdCBrb2Jq ZWN0ICprb2JqLAorCQkJICAgc3RydWN0IGtvYmpfYXR0cmlidXRlICphdHRyLCBjaGFyICpidWYp Cit7CisJY2hhciAqcyA9IGJ1ZjsKKwlpbnQgaTsKKworCWZvciAoaSA9IDA7IGkgPCBBUlJBWV9T SVpFKHBvbGljaWVzKTsgaSsrKSB7CisJCWlmIChpID09IHBvbGljeSkKKwkJCXMgKz0gc3ByaW50 ZihzLCAiWyVzXSAiLCBwb2xpY2llc1tpXS5uYW1lKTsKKwkJZWxzZQorCQkJcyArPSBzcHJpbnRm KHMsICIlcyAiLCBwb2xpY2llc1tpXS5uYW1lKTsKKwl9CisJaWYgKHMgIT0gYnVmKQorCQkvKiBj b252ZXJ0IHRoZSBsYXN0IHNwYWNlIHRvIGEgbmV3bGluZSAqLworCQkqKHMtMSkgPSAnXG4nOwor CXJldHVybiAocyAtIGJ1Zik7Cit9CisKK3N0YXRpYyBzc2l6ZV90IHBvbGljeV9zdG9yZShzdHJ1 Y3Qga29iamVjdCAqa29iaiwKKwkJCSAgICBzdHJ1Y3Qga29ial9hdHRyaWJ1dGUgKmF0dHIsCisJ CQkgICAgY29uc3QgY2hhciAqYnVmLCBzaXplX3QgbikKK3sKKwljb25zdCBjaGFyICpzOworCWNo YXIgKnA7CisJaW50IGxlbjsKKwlpbnQgaTsKKworCXAgPSBtZW1jaHIoYnVmLCAnXG4nLCBuKTsK KwlsZW4gPSBwID8gcCAtIGJ1ZiA6IG47CisKKwlmb3IgKGkgPSAwOyBpIDwgQVJSQVlfU0laRShw b2xpY2llcyk7IGkrKykgeworCQlzID0gcG9saWNpZXNbaV0ubmFtZTsKKwkJaWYgKHMgJiYgbGVu ID09IHN0cmxlbihzKSAmJiAhc3RybmNtcChidWYsIHMsIGxlbikpIHsKKwkJCW11dGV4X2xvY2so JnBtX211dGV4KTsKKwkJCXBvbGljaWVzW3BvbGljeV0uc2V0X3N0YXRlKFBNX1NVU1BFTkRfT04p OworCQkJcG9saWN5ID0gaTsKKwkJCW11dGV4X3VubG9jaygmcG1fbXV0ZXgpOworCQkJcmV0dXJu IG47CisJCX0KKwl9CisJcmV0dXJuIC1FSU5WQUw7Cit9CisKK3Bvd2VyX2F0dHIocG9saWN5KTsK KyNlbmRpZiAvKiBDT05GSUdfT1BQT1JUVU5JU1RJQ19TVVNQRU5EICovCisKICNpZmRlZiBDT05G SUdfUE1fVFJBQ0UKIGludCBwbV90cmFjZV9lbmFibGVkOwogCkBAIC0yMzYsNiArMzQ2LDkgQEAg c3RhdGljIHN0cnVjdCBhdHRyaWJ1dGUgKiBnW10gPSB7CiAjZW5kaWYKICNpZmRlZiBDT05GSUdf UE1fU0xFRVAKIAkmcG1fYXN5bmNfYXR0ci5hdHRyLAorI2lmZGVmIENPTkZJR19PUFBPUlRVTklT VElDX1NVU1BFTkQKKwkmcG9saWN5X2F0dHIuYXR0ciwKKyNlbmRpZgogI2lmZGVmIENPTkZJR19Q TV9ERUJVRwogCSZwbV90ZXN0X2F0dHIuYXR0ciwKICNlbmRpZgpAQCAtMjQ3LDcgKzM2MCw3IEBA IHN0YXRpYyBzdHJ1Y3QgYXR0cmlidXRlX2dyb3VwIGF0dHJfZ3JvdXAgPSB7CiAJLmF0dHJzID0g ZywKIH07CiAKLSNpZmRlZiBDT05GSUdfUE1fUlVOVElNRQorI2lmIGRlZmluZWQoQ09ORklHX1BN X1JVTlRJTUUpIHx8IGRlZmluZWQoQ09ORklHX09QUE9SVFVOSVNUSUNfU1VTUEVORCkKIHN0cnVj dCB3b3JrcXVldWVfc3RydWN0ICpwbV93cTsKIEVYUE9SVF9TWU1CT0xfR1BMKHBtX3dxKTsKIApA QCAtMjY2LDYgKzM3OSw3IEBAIHN0YXRpYyBpbnQgX19pbml0IHBtX2luaXQodm9pZCkKIAlpbnQg ZXJyb3IgPSBwbV9zdGFydF93b3JrcXVldWUoKTsKIAlpZiAoZXJyb3IpCiAJCXJldHVybiBlcnJv cjsKKwlvcHBvcnR1bmlzdGljX3N1c3BlbmRfaW5pdCgpOwogCXBvd2VyX2tvYmogPSBrb2JqZWN0 X2NyZWF0ZV9hbmRfYWRkKCJwb3dlciIsIE5VTEwpOwogCWlmICghcG93ZXJfa29iaikKIAkJcmV0 dXJuIC1FTk9NRU07CmRpZmYgLS1naXQgYS9rZXJuZWwvcG93ZXIvb3Bwb3J0dW5pc3RpY19zdXNw ZW5kLmMgYi9rZXJuZWwvcG93ZXIvb3Bwb3J0dW5pc3RpY19zdXNwZW5kLmMKbmV3IGZpbGUgbW9k ZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWNjMTY1MQotLS0gL2Rldi9udWxsCisrKyBiL2tlcm5l bC9wb3dlci9vcHBvcnR1bmlzdGljX3N1c3BlbmQuYwpAQCAtMCwwICsxLDI4NCBAQAorLyoKKyAq IGtlcm5lbC9wb3dlci9vcHBvcnR1bmlzdGljX3N1c3BlbmQuYworICoKKyAqIENvcHlyaWdodCAo QykgMjAwNS0yMDEwIEdvb2dsZSwgSW5jLgorICoKKyAqIFRoaXMgc29mdHdhcmUgaXMgbGljZW5z ZWQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMKKyAqIExpY2Vuc2Ug dmVyc2lvbiAyLCBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwg YW5kCisgKiBtYXkgYmUgY29waWVkLCBkaXN0cmlidXRlZCwgYW5kIG1vZGlmaWVkIHVuZGVyIHRo b3NlIHRlcm1zLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9w ZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAorICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3 aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKKyAqIE1FUkNIQU5UQUJJTElUWSBv ciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUKKyAqIEdOVSBHZW5l cmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCisgKgorICovCisKKyNpbmNsdWRl IDxsaW51eC9tb2R1bGUuaD4KKyNpbmNsdWRlIDxsaW51eC9ydGMuaD4KKyNpbmNsdWRlIDxsaW51 eC9zdXNwZW5kLmg+CisKKyNpbmNsdWRlICJwb3dlci5oIgorCitleHRlcm4gc3RydWN0IHdvcmtx dWV1ZV9zdHJ1Y3QgKnBtX3dxOworCitlbnVtIHsKKwlERUJVR19FWElUX1NVU1BFTkQgPSAxVSA8 PCAwLAorCURFQlVHX1dBS0VVUCA9IDFVIDw8IDEsCisJREVCVUdfVVNFUl9TVEFURSA9IDFVIDw8 IDIsCisJREVCVUdfU1VTUEVORCA9IDFVIDw8IDMsCisJREVCVUdfU1VTUEVORF9CTE9DS0VSID0g MVUgPDwgNCwKK307CitzdGF0aWMgaW50IGRlYnVnX21hc2sgPSBERUJVR19FWElUX1NVU1BFTkQg fCBERUJVR19XQUtFVVAgfCBERUJVR19VU0VSX1NUQVRFOworbW9kdWxlX3BhcmFtX25hbWVkKGRl YnVnX21hc2ssIGRlYnVnX21hc2ssIGludCwgU19JUlVHTyB8IFNfSVdVU1IgfCBTX0lXR1JQKTsK KworI2RlZmluZSBTQl9JTklUSUFMSVpFRCAgICAgICAgICAgICgxVSA8PCA4KQorI2RlZmluZSBT Ql9BQ1RJVkUgICAgICAgICAgICAgICAgICgxVSA8PCA5KQorCitERUZJTkVfU1VTUEVORF9CTE9D S0VSKG1haW5fc3VzcGVuZF9ibG9ja2VyLCBtYWluKTsKKworc3RhdGljIERFRklORV9TUElOTE9D SyhsaXN0X2xvY2spOworc3RhdGljIERFRklORV9TUElOTE9DSyhzdGF0ZV9sb2NrKTsKK3N0YXRp YyBMSVNUX0hFQUQoaW5hY3RpdmVfYmxvY2tlcnMpOworc3RhdGljIExJU1RfSEVBRChhY3RpdmVf YmxvY2tlcnMpOworc3RhdGljIGludCBjdXJyZW50X2V2ZW50X251bTsKK3N0YXRpYyBzdXNwZW5k X3N0YXRlX3QgcmVxdWVzdGVkX3N1c3BlbmRfc3RhdGUgPSBQTV9TVVNQRU5EX01FTTsKK3N0YXRp YyBib29sIGVuYWJsZV9zdXNwZW5kX2Jsb2NrZXJzOworCisjZGVmaW5lIHByX2luZm9fdGltZShm bXQsIGFyZ3MuLi4pIFwKKwlkbyB7IFwKKwkJc3RydWN0IHRpbWVzcGVjIHRzOyBcCisJCXN0cnVj dCBydGNfdGltZSB0bTsgXAorCQlnZXRuc3RpbWVvZmRheSgmdHMpOyBcCisJCXJ0Y190aW1lX3Rv X3RtKHRzLnR2X3NlYywgJnRtKTsgXAorCQlwcl9pbmZvKGZtdCAiKCVkLSUwMmQtJTAyZCAlMDJk OiUwMmQ6JTAyZC4lMDlsdSBVVEMpXG4iICwgXAorCQkJYXJncywgXAorCQkJdG0udG1feWVhciAr IDE5MDAsIHRtLnRtX21vbiArIDEsIHRtLnRtX21kYXksIFwKKwkJCXRtLnRtX2hvdXIsIHRtLnRt X21pbiwgdG0udG1fc2VjLCB0cy50dl9uc2VjKTsgXAorCX0gd2hpbGUgKDApOworCitzdGF0aWMg dm9pZCBwcmludF9hY3RpdmVfc3VzcGVuZF9ibG9ja2Vycyh2b2lkKQoreworCXN0cnVjdCBzdXNw ZW5kX2Jsb2NrZXIgKmJsb2NrZXI7CisKKwlsaXN0X2Zvcl9lYWNoX2VudHJ5KGJsb2NrZXIsICZh Y3RpdmVfYmxvY2tlcnMsIGxpbmspCisJCXByX2luZm8oIlBNOiBBY3RpdmUgc3VzcGVuZCBibG9j a2VyICVzXG4iLCBibG9ja2VyLT5uYW1lKTsKK30KKworLyoqCisgKiBzdXNwZW5kX2lzX2Jsb2Nr ZWQgLSBDaGVjayBpZiB0aGVyZSBhcmUgYWN0aXZlIHN1c3BlbmQgYmxvY2tlcnMuCisgKgorICog UmV0dXJuIHRydWUgaWYgc3VzcGVuZCBibG9ja2VycyBhcmUgZW5hYmxlZCBhbmQgdGhlcmUgYXJl IGFjdGl2ZSBzdXNwZW5kCisgKiBibG9ja2VycywgaW4gd2hpY2ggY2FzZSB0aGUgc3lzdGVtIGNh bm5vdCBiZSBwdXQgdG8gc2xlZXAgb3Bwb3J0dW5pc3RpY2FsbHkuCisgKi8KK2Jvb2wgc3VzcGVu ZF9pc19ibG9ja2VkKHZvaWQpCit7CisJcmV0dXJuIGVuYWJsZV9zdXNwZW5kX2Jsb2NrZXJzICYm ICFsaXN0X2VtcHR5KCZhY3RpdmVfYmxvY2tlcnMpOworfQorCitzdGF0aWMgdm9pZCBzdXNwZW5k X3dvcmtlcihzdHJ1Y3Qgd29ya19zdHJ1Y3QgKndvcmspCit7CisJaW50IHJldDsKKwlpbnQgZW50 cnlfZXZlbnRfbnVtOworCisJZW5hYmxlX3N1c3BlbmRfYmxvY2tlcnMgPSB0cnVlOworCisJaWYg KHN1c3BlbmRfaXNfYmxvY2tlZCgpKSB7CisJCWlmIChkZWJ1Z19tYXNrICYgREVCVUdfU1VTUEVO RCkKKwkJCXByX2luZm8oIlBNOiBBdXRvbWF0aWMgc3VzcGVuZCBhYm9ydGVkXG4iKTsKKwkJZ290 byBhYm9ydDsKKwl9CisKKwllbnRyeV9ldmVudF9udW0gPSBjdXJyZW50X2V2ZW50X251bTsKKwor CWlmIChkZWJ1Z19tYXNrICYgREVCVUdfU1VTUEVORCkKKwkJcHJfaW5mbygiUE06IEF1dG9tYXRp YyBzdXNwZW5kXG4iKTsKKworCXJldCA9IHBtX3N1c3BlbmQocmVxdWVzdGVkX3N1c3BlbmRfc3Rh dGUpOworCisJaWYgKGRlYnVnX21hc2sgJiBERUJVR19FWElUX1NVU1BFTkQpCisJCXByX2luZm9f dGltZSgiUE06IEF1dG9tYXRpYyBzdXNwZW5kIGV4aXQsIHJldCA9ICVkICIsIHJldCk7CisKKwlp ZiAoY3VycmVudF9ldmVudF9udW0gPT0gZW50cnlfZXZlbnRfbnVtKSB7CisJCWlmIChkZWJ1Z19t YXNrICYgREVCVUdfU1VTUEVORCkKKwkJCXByX2luZm8oIlBNOiBwbV9zdXNwZW5kKCkgcmV0dXJu ZWQgd2l0aCBubyBldmVudFxuIik7CisJCXF1ZXVlX3dvcmsocG1fd3EsIHdvcmspOworCX0KKwor YWJvcnQ6CisJZW5hYmxlX3N1c3BlbmRfYmxvY2tlcnMgPSBmYWxzZTsKK30KK3N0YXRpYyBERUNM QVJFX1dPUksoc3VzcGVuZF93b3JrLCBzdXNwZW5kX3dvcmtlcik7CisKKy8qKgorICogc3VzcGVu ZF9ibG9ja2VyX3JlZ2lzdGVyIC0gUHJlcGFyZSBhIHN1c3BlbmQgYmxvY2tlciBmb3IgYmVpbmcg dXNlZC4KKyAqIEBibG9ja2VyOiBTdXNwZW5kIGJsb2NrZXIgdG8gaGFuZGxlLgorICoKKyAqIFRo ZSBzdXNwZW5kIGJsb2NrZXIgc3RydWN0IGFuZCBuYW1lIG11c3Qgbm90IGJlIGZyZWVkIGJlZm9y ZSBjYWxsaW5nCisgKiBzdXNwZW5kX2Jsb2NrZXJfdW5yZWdpc3RlcigpLgorICovCit2b2lkIHN1 c3BlbmRfYmxvY2tlcl9yZWdpc3RlcihzdHJ1Y3Qgc3VzcGVuZF9ibG9ja2VyICpibG9ja2VyKQor eworCXVuc2lnbmVkIGxvbmcgaXJxZmxhZ3MgPSAwOworCisJV0FSTl9PTighYmxvY2tlci0+bmFt ZSk7CisKKwlpZiAoZGVidWdfbWFzayAmIERFQlVHX1NVU1BFTkRfQkxPQ0tFUikKKwkJcHJfaW5m bygiJXM6IFJlZ2lzdGVyaW5nICVzXG4iLCBfX2Z1bmNfXywgYmxvY2tlci0+bmFtZSk7CisKKwli bG9ja2VyLT5mbGFncyA9IFNCX0lOSVRJQUxJWkVEOworCUlOSVRfTElTVF9IRUFEKCZibG9ja2Vy LT5saW5rKTsKKworCXNwaW5fbG9ja19pcnFzYXZlKCZsaXN0X2xvY2ssIGlycWZsYWdzKTsKKwls aXN0X2FkZCgmYmxvY2tlci0+bGluaywgJmluYWN0aXZlX2Jsb2NrZXJzKTsKKwlzcGluX3VubG9j a19pcnFyZXN0b3JlKCZsaXN0X2xvY2ssIGlycWZsYWdzKTsKK30KK0VYUE9SVF9TWU1CT0woc3Vz cGVuZF9ibG9ja2VyX3JlZ2lzdGVyKTsKKworLyoqCisgKiBzdXNwZW5kX2Jsb2NrZXJfaW5pdCAt IEluaXRpYWxpemUgYSBzdXNwZW5kIGJsb2NrZXIncyBuYW1lIGFuZCByZWdpc3RlciBpdC4KKyAq IEBibG9ja2VyOiBTdXNwZW5kIGJsb2NrZXIgdG8gaW5pdGlhbGl6ZS4KKyAqIEBuYW1lOiAgICBU aGUgbmFtZSBvZiB0aGUgc3VzcGVuZCBibG9ja2VyIHRvIHNob3cgaW4gZGVidWcgbWVzc2FnZXMu CisgKgorICogVGhlIHN1c3BlbmQgYmxvY2tlciBzdHJ1Y3QgYW5kIG5hbWUgbXVzdCBub3QgYmUg ZnJlZWQgYmVmb3JlIGNhbGxpbmcKKyAqIHN1c3BlbmRfYmxvY2tlcl91bnJlZ2lzdGVyKCkuCisg Ki8KK3ZvaWQgc3VzcGVuZF9ibG9ja2VyX2luaXQoc3RydWN0IHN1c3BlbmRfYmxvY2tlciAqYmxv Y2tlciwgY29uc3QgY2hhciAqbmFtZSkKK3sKKwlibG9ja2VyLT5uYW1lID0gbmFtZTsKKwlzdXNw ZW5kX2Jsb2NrZXJfcmVnaXN0ZXIoYmxvY2tlcik7Cit9CitFWFBPUlRfU1lNQk9MKHN1c3BlbmRf YmxvY2tlcl9pbml0KTsKKworLyoqCisgKiBzdXNwZW5kX2Jsb2NrZXJfdW5yZWdpc3RlciAtIFVu cmVnaXN0ZXIgYSBzdXNwZW5kIGJsb2NrZXIuCisgKiBAYmxvY2tlcjogU3VzcGVuZCBibG9ja2Vy IHRvIGhhbmRsZS4KKyAqLwordm9pZCBzdXNwZW5kX2Jsb2NrZXJfdW5yZWdpc3RlcihzdHJ1Y3Qg c3VzcGVuZF9ibG9ja2VyICpibG9ja2VyKQoreworCXVuc2lnbmVkIGxvbmcgaXJxZmxhZ3M7CisK KwlpZiAoV0FSTl9PTighKGJsb2NrZXItPmZsYWdzICYgU0JfSU5JVElBTElaRUQpKSkKKwkJcmV0 dXJuOworCisJc3Bpbl9sb2NrX2lycXNhdmUoJmxpc3RfbG9jaywgaXJxZmxhZ3MpOworCWJsb2Nr ZXItPmZsYWdzICY9IH5TQl9JTklUSUFMSVpFRDsKKwlsaXN0X2RlbCgmYmxvY2tlci0+bGluayk7 CisJaWYgKChibG9ja2VyLT5mbGFncyAmIFNCX0FDVElWRSkgJiYgbGlzdF9lbXB0eSgmYWN0aXZl X2Jsb2NrZXJzKSkKKwkJcXVldWVfd29yayhwbV93cSwgJnN1c3BlbmRfd29yayk7CisJc3Bpbl91 bmxvY2tfaXJxcmVzdG9yZSgmbGlzdF9sb2NrLCBpcnFmbGFncyk7CisKKwlpZiAoZGVidWdfbWFz ayAmIERFQlVHX1NVU1BFTkRfQkxPQ0tFUikKKwkJcHJfaW5mbygiJXM6IFVucmVnaXN0ZXJlZCAl c1xuIiwgX19mdW5jX18sIGJsb2NrZXItPm5hbWUpOworfQorRVhQT1JUX1NZTUJPTChzdXNwZW5k X2Jsb2NrZXJfdW5yZWdpc3Rlcik7CisKKy8qKgorICogc3VzcGVuZF9ibG9jayAtIEJsb2NrIHN5 c3RlbSBzdXNwZW5kLgorICogQGJsb2NrZXI6IFN1c3BlbmQgYmxvY2tlciB0byB1c2UuCisgKgor ICogSXQgaXMgc2FmZSB0byBjYWxsIHRoaXMgZnVuY3Rpb24gZnJvbSBpbnRlcnJ1cHQgY29udGV4 dC4KKyAqLwordm9pZCBzdXNwZW5kX2Jsb2NrKHN0cnVjdCBzdXNwZW5kX2Jsb2NrZXIgKmJsb2Nr ZXIpCit7CisJdW5zaWduZWQgbG9uZyBpcnFmbGFnczsKKworCWlmIChXQVJOX09OKCEoYmxvY2tl ci0+ZmxhZ3MgJiBTQl9JTklUSUFMSVpFRCkpKQorCQlyZXR1cm47CisKKwlzcGluX2xvY2tfaXJx c2F2ZSgmbGlzdF9sb2NrLCBpcnFmbGFncyk7CisKKwlpZiAoZGVidWdfbWFzayAmIERFQlVHX1NV U1BFTkRfQkxPQ0tFUikKKwkJcHJfaW5mbygiJXM6ICVzXG4iLCBfX2Z1bmNfXywgYmxvY2tlci0+ bmFtZSk7CisKKwlibG9ja2VyLT5mbGFncyB8PSBTQl9BQ1RJVkU7CisJbGlzdF9tb3ZlKCZibG9j a2VyLT5saW5rLCAmYWN0aXZlX2Jsb2NrZXJzKTsKKworCWN1cnJlbnRfZXZlbnRfbnVtKys7CisK KwlzcGluX3VubG9ja19pcnFyZXN0b3JlKCZsaXN0X2xvY2ssIGlycWZsYWdzKTsKK30KK0VYUE9S VF9TWU1CT0woc3VzcGVuZF9ibG9jayk7CisKKy8qKgorICogc3VzcGVuZF91bmJsb2NrIC0gQWxs b3cgc3lzdGVtIHN1c3BlbmQgdG8gaGFwcGVuLgorICogQGJsb2NrZXI6IFN1c3BlbmQgYmxvY2tl ciB0byB1bmJsb2NrLgorICoKKyAqIElmIG5vIG90aGVyIHN1c3BlbmQgYmxvY2tlcnMgYXJlIGFj dGl2ZSwgc2NoZWR1bGUgc3VzcGVuZCBvZiB0aGUgc3lzdGVtLgorICoKKyAqIEl0IGlzIHNhZmUg dG8gY2FsbCB0aGlzIGZ1bmN0aW9uIGZyb20gaW50ZXJydXB0IGNvbnRleHQuCisgKi8KK3ZvaWQg c3VzcGVuZF91bmJsb2NrKHN0cnVjdCBzdXNwZW5kX2Jsb2NrZXIgKmJsb2NrZXIpCit7CisJdW5z aWduZWQgbG9uZyBpcnFmbGFnczsKKworCWlmIChXQVJOX09OKCEoYmxvY2tlci0+ZmxhZ3MgJiBT Ql9JTklUSUFMSVpFRCkpKQorCQlyZXR1cm47CisKKwlzcGluX2xvY2tfaXJxc2F2ZSgmbGlzdF9s b2NrLCBpcnFmbGFncyk7CisKKwlpZiAoZGVidWdfbWFzayAmIERFQlVHX1NVU1BFTkRfQkxPQ0tF UikKKwkJcHJfaW5mbygiJXM6ICVzXG4iLCBfX2Z1bmNfXywgYmxvY2tlci0+bmFtZSk7CisKKwls aXN0X21vdmUoJmJsb2NrZXItPmxpbmssICZpbmFjdGl2ZV9ibG9ja2Vycyk7CisJaWYgKChibG9j a2VyLT5mbGFncyAmIFNCX0FDVElWRSkgJiYgbGlzdF9lbXB0eSgmYWN0aXZlX2Jsb2NrZXJzKSkK KwkJcXVldWVfd29yayhwbV93cSwgJnN1c3BlbmRfd29yayk7CisJYmxvY2tlci0+ZmxhZ3MgJj0g fihTQl9BQ1RJVkUpOworCisJaWYgKChkZWJ1Z19tYXNrICYgREVCVUdfU1VTUEVORCkgJiYgYmxv Y2tlciA9PSAmbWFpbl9zdXNwZW5kX2Jsb2NrZXIpCisJCXByaW50X2FjdGl2ZV9zdXNwZW5kX2Js b2NrZXJzKCk7CisKKwlzcGluX3VubG9ja19pcnFyZXN0b3JlKCZsaXN0X2xvY2ssIGlycWZsYWdz KTsKK30KK0VYUE9SVF9TWU1CT0woc3VzcGVuZF91bmJsb2NrKTsKKworLyoqCisgKiBzdXNwZW5k X2Jsb2NrZXJfaXNfYWN0aXZlIC0gVGVzdCBpZiBhIHN1c3BlbmQgYmxvY2tlciBpcyBibG9ja2lu ZyBzdXNwZW5kCisgKiBAYmxvY2tlcjogU3VzcGVuZCBibG9ja2VyIHRvIGNoZWNrLgorICoKKyAq IFJldHVybnMgdHJ1ZSBpZiB0aGUgc3VzcGVuZF9ibG9ja2VyIGlzIGN1cnJlbnRseSBhY3RpdmUu CisgKi8KK2Jvb2wgc3VzcGVuZF9ibG9ja2VyX2lzX2FjdGl2ZShzdHJ1Y3Qgc3VzcGVuZF9ibG9j a2VyICpibG9ja2VyKQoreworCVdBUk5fT04oIShibG9ja2VyLT5mbGFncyAmIFNCX0lOSVRJQUxJ WkVEKSk7CisKKwlyZXR1cm4gISEoYmxvY2tlci0+ZmxhZ3MgJiBTQl9BQ1RJVkUpOworfQorRVhQ T1JUX1NZTUJPTChzdXNwZW5kX2Jsb2NrZXJfaXNfYWN0aXZlKTsKKworYm9vbCBvcHBvcnR1bmlz dGljX3N1c3BlbmRfdmFsaWRfc3RhdGUoc3VzcGVuZF9zdGF0ZV90IHN0YXRlKQoreworCXJldHVy biAoc3RhdGUgPT0gUE1fU1VTUEVORF9PTikgfHwgdmFsaWRfc3RhdGUoc3RhdGUpOworfQorCitp bnQgb3Bwb3J0dW5pc3RpY19zdXNwZW5kX3N0YXRlKHN1c3BlbmRfc3RhdGVfdCBzdGF0ZSkKK3sK Kwl1bnNpZ25lZCBsb25nIGlycWZsYWdzOworCisJaWYgKCFvcHBvcnR1bmlzdGljX3N1c3BlbmRf dmFsaWRfc3RhdGUoc3RhdGUpKQorCQlyZXR1cm4gLUVOT0RFVjsKKworCXNwaW5fbG9ja19pcnFz YXZlKCZzdGF0ZV9sb2NrLCBpcnFmbGFncyk7CisKKwlpZiAoZGVidWdfbWFzayAmIERFQlVHX1VT RVJfU1RBVEUpCisJCXByX2luZm9fdGltZSgiJXM6ICVzICglZC0+JWQpIGF0ICVsbGQgIiwgX19m dW5jX18sCisJCQkgICAgIHN0YXRlICE9IFBNX1NVU1BFTkRfT04gPyAic2xlZXAiIDogIndha2V1 cCIsCisJCQkgICAgIHJlcXVlc3RlZF9zdXNwZW5kX3N0YXRlLCBzdGF0ZSwKKwkJCSAgICAga3Rp bWVfdG9fbnMoa3RpbWVfZ2V0KCkpKTsKKworCXJlcXVlc3RlZF9zdXNwZW5kX3N0YXRlID0gc3Rh dGU7CisJaWYgKHN0YXRlID09IFBNX1NVU1BFTkRfT04pCisJCXN1c3BlbmRfYmxvY2soJm1haW5f c3VzcGVuZF9ibG9ja2VyKTsKKwllbHNlCisJCXN1c3BlbmRfdW5ibG9jaygmbWFpbl9zdXNwZW5k X2Jsb2NrZXIpOworCisJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmc3RhdGVfbG9jaywgaXJxZmxh Z3MpOworCisJcmV0dXJuIDA7Cit9CisKK3ZvaWQgX19pbml0IG9wcG9ydHVuaXN0aWNfc3VzcGVu ZF9pbml0KHZvaWQpCit7CisJc3VzcGVuZF9ibG9ja2VyX3JlZ2lzdGVyKCZtYWluX3N1c3BlbmRf YmxvY2tlcik7CisJc3VzcGVuZF9ibG9jaygmbWFpbl9zdXNwZW5kX2Jsb2NrZXIpOworfQpkaWZm IC0tZ2l0IGEva2VybmVsL3Bvd2VyL3Bvd2VyLmggYi9rZXJuZWwvcG93ZXIvcG93ZXIuaAppbmRl eCA0NmM1YTI2Li4yZTljZmQ1IDEwMDY0NAotLS0gYS9rZXJuZWwvcG93ZXIvcG93ZXIuaAorKysg Yi9rZXJuZWwvcG93ZXIvcG93ZXIuaApAQCAtMjM2LDMgKzIzNiwxMiBAQCBzdGF0aWMgaW5saW5l IHZvaWQgc3VzcGVuZF90aGF3X3Byb2Nlc3Nlcyh2b2lkKQogewogfQogI2VuZGlmCisKKyNpZmRl ZiBDT05GSUdfT1BQT1JUVU5JU1RJQ19TVVNQRU5ECisvKiBrZXJuZWwvcG93ZXIvb3Bwb3J0dW5p c3RpY19zdXNwZW5kLmMgKi8KK2V4dGVybiBpbnQgb3Bwb3J0dW5pc3RpY19zdXNwZW5kX3N0YXRl KHN1c3BlbmRfc3RhdGVfdCBzdGF0ZSk7CitleHRlcm4gYm9vbCBvcHBvcnR1bmlzdGljX3N1c3Bl bmRfdmFsaWRfc3RhdGUoc3VzcGVuZF9zdGF0ZV90IHN0YXRlKTsKK2V4dGVybiB2b2lkIF9faW5p dCBvcHBvcnR1bmlzdGljX3N1c3BlbmRfaW5pdCh2b2lkKTsKKyNlbHNlCitzdGF0aWMgaW5saW5l IHZvaWQgb3Bwb3J0dW5pc3RpY19zdXNwZW5kX2luaXQodm9pZCkge30KKyNlbmRpZgpkaWZmIC0t Z2l0IGEva2VybmVsL3Bvd2VyL3N1c3BlbmQuYyBiL2tlcm5lbC9wb3dlci9zdXNwZW5kLmMKaW5k ZXggNTZlN2RiYi4uOWViMzg3NiAxMDA2NDQKLS0tIGEva2VybmVsL3Bvd2VyL3N1c3BlbmQuYwor KysgYi9rZXJuZWwvcG93ZXIvc3VzcGVuZC5jCkBAIC0yMCw2ICsyMCw3IEBACiAjaW5jbHVkZSAi cG93ZXIuaCIKIAogY29uc3QgY2hhciAqY29uc3QgcG1fc3RhdGVzW1BNX1NVU1BFTkRfTUFYXSA9 IHsKKwlbUE1fU1VTUEVORF9PTl0JCT0gIm9uIiwKIAlbUE1fU1VTUEVORF9TVEFOREJZXQk9ICJz dGFuZGJ5IiwKIAlbUE1fU1VTUEVORF9NRU1dCT0gIm1lbSIsCiB9OwpAQCAtMTU3LDcgKzE1OCw3 IEBAIHN0YXRpYyBpbnQgc3VzcGVuZF9lbnRlcihzdXNwZW5kX3N0YXRlX3Qgc3RhdGUpCiAKIAll cnJvciA9IHN5c2Rldl9zdXNwZW5kKFBNU0dfU1VTUEVORCk7CiAJaWYgKCFlcnJvcikgewotCQlp ZiAoIXN1c3BlbmRfdGVzdChURVNUX0NPUkUpKQorCQlpZiAoIXN1c3BlbmRfaXNfYmxvY2tlZCgp ICYmICFzdXNwZW5kX3Rlc3QoVEVTVF9DT1JFKSkKIAkJCWVycm9yID0gc3VzcGVuZF9vcHMtPmVu dGVyKHN0YXRlKTsKIAkJc3lzZGV2X3Jlc3VtZSgpOwogCX0KLS0gCjEuNi41LjEKCl9fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fCmxpbnV4LXBtIG1haWxpbmcg bGlzdApsaW51eC1wbUBsaXN0cy5saW51eC1mb3VuZGF0aW9uLm9yZwpodHRwczovL2xpc3RzLmxp bnV4LWZvdW5kYXRpb24ub3JnL21haWxtYW4vbGlzdGluZm8vbGludXgtcG0= From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751586Ab0ENELa (ORCPT ); Fri, 14 May 2010 00:11:30 -0400 Received: from mail-pv0-f174.google.com ([74.125.83.174]:51269 "EHLO mail-pv0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751422Ab0ENELZ (ORCPT ); Fri, 14 May 2010 00:11:25 -0400 From: =?UTF-8?q?Arve=20Hj=C3=B8nnev=C3=A5g?= To: linux-pm@lists.linux-foundation.org, linux-kernel@vger.kernel.org Cc: "Rafael J. Wysocki" , =?UTF-8?q?Arve=20Hj=C3=B8nnev=C3=A5g?= , Len Brown , Pavel Machek , Randy Dunlap , Andrew Morton , Andi Kleen , Cornelia Huck , Tejun Heo , Jesse Barnes , Magnus Damm , Nigel Cunningham , Alan Stern , Ming Lei , Wu Fengguang , Maxim Levitsky , linux-doc@vger.kernel.org Subject: [PATCH 1/8] PM: Add suspend block api. Date: Thu, 13 May 2010 21:11:06 -0700 Message-Id: <1273810273-3039-2-git-send-email-arve@android.com> X-Mailer: git-send-email 1.6.5.1 In-Reply-To: <1273810273-3039-1-git-send-email-arve@android.com> References: <1273810273-3039-1-git-send-email-arve@android.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Adds /sys/power/policy that selects the behaviour of /sys/power/state. After setting the policy to opportunistic, writes to /sys/power/state become non-blocking requests that specify which suspend state to enter when no suspend blockers are active. A special state, "on", stops the process by activating the "main" suspend blocker. Signed-off-by: Arve Hjønnevåg --- Documentation/power/opportunistic-suspend.txt | 129 +++++++++++ include/linux/suspend.h | 1 + include/linux/suspend_blocker.h | 74 +++++++ kernel/power/Kconfig | 16 ++ kernel/power/Makefile | 1 + kernel/power/main.c | 128 +++++++++++- kernel/power/opportunistic_suspend.c | 284 +++++++++++++++++++++++++ kernel/power/power.h | 9 + kernel/power/suspend.c | 3 +- 9 files changed, 637 insertions(+), 8 deletions(-) create mode 100644 Documentation/power/opportunistic-suspend.txt create mode 100755 include/linux/suspend_blocker.h create mode 100644 kernel/power/opportunistic_suspend.c diff --git a/Documentation/power/opportunistic-suspend.txt b/Documentation/power/opportunistic-suspend.txt new file mode 100644 index 0000000..4bee7bc --- /dev/null +++ b/Documentation/power/opportunistic-suspend.txt @@ -0,0 +1,129 @@ +Opportunistic Suspend +===================== + +Opportunistic suspend is a feature allowing the system to be suspended (ie. put +into one of the available sleep states) automatically whenever it is regarded +as idle. The suspend blockers framework described below is used to determine +when that happens. + +The /sys/power/policy sysfs attribute is used to switch the system between the +opportunistic and "forced" suspend behavior, where in the latter case the +system is only suspended if a specific value, corresponding to one of the +available system sleep states, is written into /sys/power/state. However, in +the former, opportunistic, case the system is put into the sleep state +corresponding to the value written to /sys/power/state whenever there are no +active suspend blockers. The default policy is "forced". Also, suspend blockers +do not affect sleep states entered from idle. + +When the policy is "opportunisic", there is a special value, "on", that can be +written to /sys/power/state. This will block the automatic sleep request, as if +a suspend blocker was used by a device driver. This way the opportunistic +suspend may be blocked by user space whithout switching back to the "forced" +mode. + +A suspend blocker is an object used to inform the PM subsystem when the system +can or cannot be suspended in the "opportunistic" mode (the "forced" mode +ignores suspend blockers). To use it, a device driver creates a struct +suspend_blocker that must be initialized with suspend_blocker_init(). Before +freeing the suspend_blocker structure or its name, suspend_blocker_unregister() +must be called on it. + +A suspend blocker is activated using suspend_block(), which prevents the PM +subsystem from putting the system into the requested sleep state in the +"opportunistic" mode until the suspend blocker is deactivated with +suspend_unblock(). Multiple suspend blockers may be active simultaneously, and +the system will not suspend as long as at least one of them is active. + +If opportunistic suspend is already in progress when suspend_block() is called, +it will abort the suspend, unless suspend_ops->enter has already been +executed. If suspend is aborted this way, the system is usually not fully +operational at that point. The suspend callbacks of some drivers may still be +running and it usually takes time to restore the system to the fully operational +state. + +Here's an example showing how a cell phone or other embedded system can handle +keystrokes (or other input events) in the presence of suspend blockers. Use +set_irq_wake or a platform specific API to make sure the keypad interrupt wakes +up the cpu. Once the keypad driver has resumed, the sequence of events can look +like this: + +- The Keypad driver gets an interrupt. It then calls suspend_block on the + keypad-scan suspend_blocker and starts scanning the keypad matrix. +- The keypad-scan code detects a key change and reports it to the input-event + driver. +- The input-event driver sees the key change, enqueues an event, and calls + suspend_block on the input-event-queue suspend_blocker. +- The keypad-scan code detects that no keys are held and calls suspend_unblock + on the keypad-scan suspend_blocker. +- The user-space input-event thread returns from select/poll, calls + suspend_block on the process-input-events suspend_blocker and then calls read + on the input-event device. +- The input-event driver dequeues the key-event and, since the queue is now + empty, it calls suspend_unblock on the input-event-queue suspend_blocker. +- The user-space input-event thread returns from read. If it determines that + the key should be ignored, it calls suspend_unblock on the + process_input_events suspend_blocker and then calls select or poll. The + system will automatically suspend again, since now no suspend blockers are + active. + +If the key that was pressed instead should preform a simple action (for example, +adjusting the volume), this action can be performed right before calling +suspend_unblock on the process_input_events suspend_blocker. However, if the key +triggers a longer-running action, that action needs its own suspend_blocker and +suspend_block must be called on that suspend blocker before calling +suspend_unblock on the process_input_events suspend_blocker. + + Key pressed Key released + | | +keypad-scan ++++++++++++++++++ +input-event-queue +++ +++ +process-input-events +++ +++ + + +Driver API +========== + +A driver can use the suspend block API by adding a suspend_blocker variable to +its state and calling suspend_blocker_init(). For instance: + +struct state { + struct suspend_blocker suspend_blocker; +} + +init() { + suspend_blocker_init(&state->suspend_blocker, name); +} + +If the suspend_blocker variable is allocated statically, +DEFINE_SUSPEND_BLOCKER() should be used to initialize it, for example: + +static DEFINE_SUSPEND_BLOCKER(blocker, name); + +and suspend_blocker_register(&blocker) has to be called to make the suspend +blocker usable. + +Before freeing the memory in which a suspend_blocker variable is located, +suspend_blocker_unregister() must be called, for instance: + +uninit() { + suspend_blocker_unregister(&state->suspend_blocker); +} + +When the driver determines that it needs to run (usually in an interrupt +handler) it calls suspend_block(): + + suspend_block(&state->suspend_blocker); + +When it no longer needs to run it calls suspend_unblock(): + + suspend_unblock(&state->suspend_blocker); + +Calling suspend_block() when the suspend blocker is active or suspend_unblock() +when it is not active has no effect (i.e., these functions don't nest). This +allows drivers to update their state and call suspend suspend_block() or +suspend_unblock() based on the result. For instance: + +if (list_empty(&state->pending_work)) + suspend_unblock(&state->suspend_blocker); +else + suspend_block(&state->suspend_blocker); diff --git a/include/linux/suspend.h b/include/linux/suspend.h index 5e781d8..07023d3 100644 --- a/include/linux/suspend.h +++ b/include/linux/suspend.h @@ -6,6 +6,7 @@ #include #include #include +#include #include #if defined(CONFIG_PM_SLEEP) && defined(CONFIG_VT) && defined(CONFIG_VT_CONSOLE) diff --git a/include/linux/suspend_blocker.h b/include/linux/suspend_blocker.h new file mode 100755 index 0000000..8788302 --- /dev/null +++ b/include/linux/suspend_blocker.h @@ -0,0 +1,74 @@ +/* include/linux/suspend_blocker.h + * + * Copyright (C) 2007-2010 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _LINUX_SUSPEND_BLOCKER_H +#define _LINUX_SUSPEND_BLOCKER_H + +#include + +/** + * struct suspend_blocker - the basic suspend_blocker structure + * @link: List entry for active or inactive list. + * @flags: Tracks initialized and active state. + * @name: Suspend blocker name used for debugging. + * + * When a suspend_blocker is active it prevents the system from entering + * opportunistic suspend. + * + * The suspend_blocker structure must be initialized by suspend_blocker_init() + */ +struct suspend_blocker { +#ifdef CONFIG_OPPORTUNISTIC_SUSPEND + struct list_head link; + int flags; + const char *name; +#endif +}; + +#ifdef CONFIG_OPPORTUNISTIC_SUSPEND +#define __SUSPEND_BLOCKER_INITIALIZER(blocker_name) \ + { .name = #blocker_name, } + +#define DEFINE_SUSPEND_BLOCKER(blocker, name) \ + struct suspend_blocker blocker = __SUSPEND_BLOCKER_INITIALIZER(name) + +extern void suspend_blocker_register(struct suspend_blocker *blocker); +extern void suspend_blocker_init(struct suspend_blocker *blocker, + const char *name); +extern void suspend_blocker_unregister(struct suspend_blocker *blocker); +extern void suspend_block(struct suspend_blocker *blocker); +extern void suspend_unblock(struct suspend_blocker *blocker); +extern bool suspend_blocker_is_active(struct suspend_blocker *blocker); +extern bool suspend_is_blocked(void); + +#else + +#define DEFINE_SUSPEND_BLOCKER(blocker, name) \ + struct suspend_blocker blocker + +static inline void suspend_blocker_register(struct suspend_blocker *bl) {} +static inline void suspend_blocker_init(struct suspend_blocker *bl, + const char *n) {} +static inline void suspend_blocker_unregister(struct suspend_blocker *bl) {} +static inline void suspend_block(struct suspend_blocker *bl) {} +static inline void suspend_unblock(struct suspend_blocker *bl) {} +static inline bool suspend_blocker_is_active(struct suspend_blocker *bl) +{ + return false; +} +static inline bool suspend_is_blocked(void) { return false; } +#endif + +#endif diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig index 5c36ea9..6d11a45 100644 --- a/kernel/power/Kconfig +++ b/kernel/power/Kconfig @@ -130,6 +130,22 @@ config SUSPEND_FREEZER Turning OFF this setting is NOT recommended! If in doubt, say Y. +config OPPORTUNISTIC_SUSPEND + bool "Opportunistic suspend" + depends on SUSPEND + select RTC_LIB + default n + ---help--- + Opportunistic sleep support. Allows the system to be put into a sleep + state opportunistically, if it doesn't do any useful work at the + moment. The PM subsystem is switched into this mode of operation by + writing "opportunistic" into /sys/power/policy, while writing + "forced" to this file turns the opportunistic suspend feature off. + In the "opportunistic" mode suspend blockers are used to determine + when to suspend the system and the value written to /sys/power/state + determines the sleep state the system will be put into when there are + no active suspend blockers. + config HIBERNATION_NVS bool diff --git a/kernel/power/Makefile b/kernel/power/Makefile index 4319181..95d8e6d 100644 --- a/kernel/power/Makefile +++ b/kernel/power/Makefile @@ -7,6 +7,7 @@ obj-$(CONFIG_PM) += main.o obj-$(CONFIG_PM_SLEEP) += console.o obj-$(CONFIG_FREEZER) += process.o obj-$(CONFIG_SUSPEND) += suspend.o +obj-$(CONFIG_OPPORTUNISTIC_SUSPEND) += opportunistic_suspend.o obj-$(CONFIG_PM_TEST_SUSPEND) += suspend_test.o obj-$(CONFIG_HIBERNATION) += hibernate.o snapshot.o swap.o user.o obj-$(CONFIG_HIBERNATION_NVS) += hibernate_nvs.o diff --git a/kernel/power/main.c b/kernel/power/main.c index b58800b..afbb4dd 100644 --- a/kernel/power/main.c +++ b/kernel/power/main.c @@ -20,6 +20,58 @@ DEFINE_MUTEX(pm_mutex); unsigned int pm_flags; EXPORT_SYMBOL(pm_flags); +#ifdef CONFIG_OPPORTUNISTIC_SUSPEND +struct pm_policy { + const char *name; + bool (*valid_state)(suspend_state_t state); + int (*set_state)(suspend_state_t state); +}; + +static struct pm_policy policies[] = { + { + .name = "forced", + .valid_state = valid_state, + .set_state = enter_state, + }, + { + .name = "opportunistic", + .valid_state = opportunistic_suspend_valid_state, + .set_state = opportunistic_suspend_state, + }, +}; + +static int policy; + +static inline bool hibernation_supported(void) +{ + return !strncmp(policies[policy].name, "forced", 6); +} + +static inline bool pm_state_valid(int state_idx) +{ + return pm_states[state_idx] && policies[policy].valid_state(state_idx); +} + +static inline int pm_enter_state(int state_idx) +{ + return policies[policy].set_state(state_idx); +} + +#else + +static inline bool hibernation_supported(void) { return true; } + +static inline bool pm_state_valid(int state_idx) +{ + return pm_states[state_idx] && valid_state(state_idx); +} + +static inline int pm_enter_state(int state_idx) +{ + return enter_state(state_idx); +} +#endif /* CONFIG_OPPORTUNISTIC_SUSPEND */ + #ifdef CONFIG_PM_SLEEP /* Routines for PM-transition notifications */ @@ -146,6 +198,12 @@ struct kobject *power_kobj; * * store() accepts one of those strings, translates it into the * proper enumerated value, and initiates a suspend transition. + * + * If policy is set to opportunistic, store() does not block until the + * system resumes, and it will try to re-enter the state until another + * state is requested. Suspend blockers are respected and the requested + * state will only be entered when no suspend blockers are active. + * Write "on" to disable. */ static ssize_t state_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) @@ -155,12 +213,13 @@ static ssize_t state_show(struct kobject *kobj, struct kobj_attribute *attr, int i; for (i = 0; i < PM_SUSPEND_MAX; i++) { - if (pm_states[i] && valid_state(i)) + if (pm_state_valid(i)) s += sprintf(s,"%s ", pm_states[i]); } #endif #ifdef CONFIG_HIBERNATION - s += sprintf(s, "%s\n", "disk"); + if (hibernation_supported()) + s += sprintf(s, "%s\n", "disk"); #else if (s != buf) /* convert the last space to a newline */ @@ -173,7 +232,7 @@ static ssize_t state_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t n) { #ifdef CONFIG_SUSPEND - suspend_state_t state = PM_SUSPEND_STANDBY; + suspend_state_t state = PM_SUSPEND_ON; const char * const *s; #endif char *p; @@ -185,8 +244,9 @@ static ssize_t state_store(struct kobject *kobj, struct kobj_attribute *attr, /* First, check if we are requested to hibernate */ if (len == 4 && !strncmp(buf, "disk", len)) { - error = hibernate(); - goto Exit; + if (hibernation_supported()) + error = hibernate(); + goto Exit; } #ifdef CONFIG_SUSPEND @@ -195,7 +255,7 @@ static ssize_t state_store(struct kobject *kobj, struct kobj_attribute *attr, break; } if (state < PM_SUSPEND_MAX && *s) - error = enter_state(state); + error = pm_enter_state(state); #endif Exit: @@ -204,6 +264,56 @@ static ssize_t state_store(struct kobject *kobj, struct kobj_attribute *attr, power_attr(state); +#ifdef CONFIG_OPPORTUNISTIC_SUSPEND +/** + * policy - set policy for state + */ +static ssize_t policy_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + char *s = buf; + int i; + + for (i = 0; i < ARRAY_SIZE(policies); i++) { + if (i == policy) + s += sprintf(s, "[%s] ", policies[i].name); + else + s += sprintf(s, "%s ", policies[i].name); + } + if (s != buf) + /* convert the last space to a newline */ + *(s-1) = '\n'; + return (s - buf); +} + +static ssize_t policy_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, size_t n) +{ + const char *s; + char *p; + int len; + int i; + + p = memchr(buf, '\n', n); + len = p ? p - buf : n; + + for (i = 0; i < ARRAY_SIZE(policies); i++) { + s = policies[i].name; + if (s && len == strlen(s) && !strncmp(buf, s, len)) { + mutex_lock(&pm_mutex); + policies[policy].set_state(PM_SUSPEND_ON); + policy = i; + mutex_unlock(&pm_mutex); + return n; + } + } + return -EINVAL; +} + +power_attr(policy); +#endif /* CONFIG_OPPORTUNISTIC_SUSPEND */ + #ifdef CONFIG_PM_TRACE int pm_trace_enabled; @@ -236,6 +346,9 @@ static struct attribute * g[] = { #endif #ifdef CONFIG_PM_SLEEP &pm_async_attr.attr, +#ifdef CONFIG_OPPORTUNISTIC_SUSPEND + &policy_attr.attr, +#endif #ifdef CONFIG_PM_DEBUG &pm_test_attr.attr, #endif @@ -247,7 +360,7 @@ static struct attribute_group attr_group = { .attrs = g, }; -#ifdef CONFIG_PM_RUNTIME +#if defined(CONFIG_PM_RUNTIME) || defined(CONFIG_OPPORTUNISTIC_SUSPEND) struct workqueue_struct *pm_wq; EXPORT_SYMBOL_GPL(pm_wq); @@ -266,6 +379,7 @@ static int __init pm_init(void) int error = pm_start_workqueue(); if (error) return error; + opportunistic_suspend_init(); power_kobj = kobject_create_and_add("power", NULL); if (!power_kobj) return -ENOMEM; diff --git a/kernel/power/opportunistic_suspend.c b/kernel/power/opportunistic_suspend.c new file mode 100644 index 0000000..acc1651 --- /dev/null +++ b/kernel/power/opportunistic_suspend.c @@ -0,0 +1,284 @@ +/* + * kernel/power/opportunistic_suspend.c + * + * Copyright (C) 2005-2010 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include + +#include "power.h" + +extern struct workqueue_struct *pm_wq; + +enum { + DEBUG_EXIT_SUSPEND = 1U << 0, + DEBUG_WAKEUP = 1U << 1, + DEBUG_USER_STATE = 1U << 2, + DEBUG_SUSPEND = 1U << 3, + DEBUG_SUSPEND_BLOCKER = 1U << 4, +}; +static int debug_mask = DEBUG_EXIT_SUSPEND | DEBUG_WAKEUP | DEBUG_USER_STATE; +module_param_named(debug_mask, debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP); + +#define SB_INITIALIZED (1U << 8) +#define SB_ACTIVE (1U << 9) + +DEFINE_SUSPEND_BLOCKER(main_suspend_blocker, main); + +static DEFINE_SPINLOCK(list_lock); +static DEFINE_SPINLOCK(state_lock); +static LIST_HEAD(inactive_blockers); +static LIST_HEAD(active_blockers); +static int current_event_num; +static suspend_state_t requested_suspend_state = PM_SUSPEND_MEM; +static bool enable_suspend_blockers; + +#define pr_info_time(fmt, args...) \ + do { \ + struct timespec ts; \ + struct rtc_time tm; \ + getnstimeofday(&ts); \ + rtc_time_to_tm(ts.tv_sec, &tm); \ + pr_info(fmt "(%d-%02d-%02d %02d:%02d:%02d.%09lu UTC)\n" , \ + args, \ + tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, \ + tm.tm_hour, tm.tm_min, tm.tm_sec, ts.tv_nsec); \ + } while (0); + +static void print_active_suspend_blockers(void) +{ + struct suspend_blocker *blocker; + + list_for_each_entry(blocker, &active_blockers, link) + pr_info("PM: Active suspend blocker %s\n", blocker->name); +} + +/** + * suspend_is_blocked - Check if there are active suspend blockers. + * + * Return true if suspend blockers are enabled and there are active suspend + * blockers, in which case the system cannot be put to sleep opportunistically. + */ +bool suspend_is_blocked(void) +{ + return enable_suspend_blockers && !list_empty(&active_blockers); +} + +static void suspend_worker(struct work_struct *work) +{ + int ret; + int entry_event_num; + + enable_suspend_blockers = true; + + if (suspend_is_blocked()) { + if (debug_mask & DEBUG_SUSPEND) + pr_info("PM: Automatic suspend aborted\n"); + goto abort; + } + + entry_event_num = current_event_num; + + if (debug_mask & DEBUG_SUSPEND) + pr_info("PM: Automatic suspend\n"); + + ret = pm_suspend(requested_suspend_state); + + if (debug_mask & DEBUG_EXIT_SUSPEND) + pr_info_time("PM: Automatic suspend exit, ret = %d ", ret); + + if (current_event_num == entry_event_num) { + if (debug_mask & DEBUG_SUSPEND) + pr_info("PM: pm_suspend() returned with no event\n"); + queue_work(pm_wq, work); + } + +abort: + enable_suspend_blockers = false; +} +static DECLARE_WORK(suspend_work, suspend_worker); + +/** + * suspend_blocker_register - Prepare a suspend blocker for being used. + * @blocker: Suspend blocker to handle. + * + * The suspend blocker struct and name must not be freed before calling + * suspend_blocker_unregister(). + */ +void suspend_blocker_register(struct suspend_blocker *blocker) +{ + unsigned long irqflags = 0; + + WARN_ON(!blocker->name); + + if (debug_mask & DEBUG_SUSPEND_BLOCKER) + pr_info("%s: Registering %s\n", __func__, blocker->name); + + blocker->flags = SB_INITIALIZED; + INIT_LIST_HEAD(&blocker->link); + + spin_lock_irqsave(&list_lock, irqflags); + list_add(&blocker->link, &inactive_blockers); + spin_unlock_irqrestore(&list_lock, irqflags); +} +EXPORT_SYMBOL(suspend_blocker_register); + +/** + * suspend_blocker_init - Initialize a suspend blocker's name and register it. + * @blocker: Suspend blocker to initialize. + * @name: The name of the suspend blocker to show in debug messages. + * + * The suspend blocker struct and name must not be freed before calling + * suspend_blocker_unregister(). + */ +void suspend_blocker_init(struct suspend_blocker *blocker, const char *name) +{ + blocker->name = name; + suspend_blocker_register(blocker); +} +EXPORT_SYMBOL(suspend_blocker_init); + +/** + * suspend_blocker_unregister - Unregister a suspend blocker. + * @blocker: Suspend blocker to handle. + */ +void suspend_blocker_unregister(struct suspend_blocker *blocker) +{ + unsigned long irqflags; + + if (WARN_ON(!(blocker->flags & SB_INITIALIZED))) + return; + + spin_lock_irqsave(&list_lock, irqflags); + blocker->flags &= ~SB_INITIALIZED; + list_del(&blocker->link); + if ((blocker->flags & SB_ACTIVE) && list_empty(&active_blockers)) + queue_work(pm_wq, &suspend_work); + spin_unlock_irqrestore(&list_lock, irqflags); + + if (debug_mask & DEBUG_SUSPEND_BLOCKER) + pr_info("%s: Unregistered %s\n", __func__, blocker->name); +} +EXPORT_SYMBOL(suspend_blocker_unregister); + +/** + * suspend_block - Block system suspend. + * @blocker: Suspend blocker to use. + * + * It is safe to call this function from interrupt context. + */ +void suspend_block(struct suspend_blocker *blocker) +{ + unsigned long irqflags; + + if (WARN_ON(!(blocker->flags & SB_INITIALIZED))) + return; + + spin_lock_irqsave(&list_lock, irqflags); + + if (debug_mask & DEBUG_SUSPEND_BLOCKER) + pr_info("%s: %s\n", __func__, blocker->name); + + blocker->flags |= SB_ACTIVE; + list_move(&blocker->link, &active_blockers); + + current_event_num++; + + spin_unlock_irqrestore(&list_lock, irqflags); +} +EXPORT_SYMBOL(suspend_block); + +/** + * suspend_unblock - Allow system suspend to happen. + * @blocker: Suspend blocker to unblock. + * + * If no other suspend blockers are active, schedule suspend of the system. + * + * It is safe to call this function from interrupt context. + */ +void suspend_unblock(struct suspend_blocker *blocker) +{ + unsigned long irqflags; + + if (WARN_ON(!(blocker->flags & SB_INITIALIZED))) + return; + + spin_lock_irqsave(&list_lock, irqflags); + + if (debug_mask & DEBUG_SUSPEND_BLOCKER) + pr_info("%s: %s\n", __func__, blocker->name); + + list_move(&blocker->link, &inactive_blockers); + if ((blocker->flags & SB_ACTIVE) && list_empty(&active_blockers)) + queue_work(pm_wq, &suspend_work); + blocker->flags &= ~(SB_ACTIVE); + + if ((debug_mask & DEBUG_SUSPEND) && blocker == &main_suspend_blocker) + print_active_suspend_blockers(); + + spin_unlock_irqrestore(&list_lock, irqflags); +} +EXPORT_SYMBOL(suspend_unblock); + +/** + * suspend_blocker_is_active - Test if a suspend blocker is blocking suspend + * @blocker: Suspend blocker to check. + * + * Returns true if the suspend_blocker is currently active. + */ +bool suspend_blocker_is_active(struct suspend_blocker *blocker) +{ + WARN_ON(!(blocker->flags & SB_INITIALIZED)); + + return !!(blocker->flags & SB_ACTIVE); +} +EXPORT_SYMBOL(suspend_blocker_is_active); + +bool opportunistic_suspend_valid_state(suspend_state_t state) +{ + return (state == PM_SUSPEND_ON) || valid_state(state); +} + +int opportunistic_suspend_state(suspend_state_t state) +{ + unsigned long irqflags; + + if (!opportunistic_suspend_valid_state(state)) + return -ENODEV; + + spin_lock_irqsave(&state_lock, irqflags); + + if (debug_mask & DEBUG_USER_STATE) + pr_info_time("%s: %s (%d->%d) at %lld ", __func__, + state != PM_SUSPEND_ON ? "sleep" : "wakeup", + requested_suspend_state, state, + ktime_to_ns(ktime_get())); + + requested_suspend_state = state; + if (state == PM_SUSPEND_ON) + suspend_block(&main_suspend_blocker); + else + suspend_unblock(&main_suspend_blocker); + + spin_unlock_irqrestore(&state_lock, irqflags); + + return 0; +} + +void __init opportunistic_suspend_init(void) +{ + suspend_blocker_register(&main_suspend_blocker); + suspend_block(&main_suspend_blocker); +} diff --git a/kernel/power/power.h b/kernel/power/power.h index 46c5a26..2e9cfd5 100644 --- a/kernel/power/power.h +++ b/kernel/power/power.h @@ -236,3 +236,12 @@ static inline void suspend_thaw_processes(void) { } #endif + +#ifdef CONFIG_OPPORTUNISTIC_SUSPEND +/* kernel/power/opportunistic_suspend.c */ +extern int opportunistic_suspend_state(suspend_state_t state); +extern bool opportunistic_suspend_valid_state(suspend_state_t state); +extern void __init opportunistic_suspend_init(void); +#else +static inline void opportunistic_suspend_init(void) {} +#endif diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c index 56e7dbb..9eb3876 100644 --- a/kernel/power/suspend.c +++ b/kernel/power/suspend.c @@ -20,6 +20,7 @@ #include "power.h" const char *const pm_states[PM_SUSPEND_MAX] = { + [PM_SUSPEND_ON] = "on", [PM_SUSPEND_STANDBY] = "standby", [PM_SUSPEND_MEM] = "mem", }; @@ -157,7 +158,7 @@ static int suspend_enter(suspend_state_t state) error = sysdev_suspend(PMSG_SUSPEND); if (!error) { - if (!suspend_test(TEST_CORE)) + if (!suspend_is_blocked() && !suspend_test(TEST_CORE)) error = suspend_ops->enter(state); sysdev_resume(); } -- 1.6.5.1