diff mbox

[Update,2] ACPI / PCI: Set root bridge ACPI handle in advance

Message ID 3596215.suSiEFiGH8@vostro.rjw.lan (mailing list archive)
State Superseded, archived
Headers show

Commit Message

Rafael Wysocki Dec. 17, 2012, 11:30 p.m. UTC
From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

The ACPI handles of PCI root bridges need to be known to
acpi_bind_one(), so that it can create the appropriate
"firmware_node" and "physical_node" files for them, but currently
the way it gets to know those handles is not exactly straightforward
(to put it lightly).

This is how it works, roughly:

  1. acpi_bus_scan() finds the handle of a PCI root bridge,
     creates a struct acpi_device object for it and passes that
     object to acpi_pci_root_add().

  2. acpi_pci_root_add() creates a struct acpi_pci_root object,
     populates its "device" field with its argument's address
     (device->handle is the ACPI handle found in step 1).

  3. The struct acpi_pci_root object created in step 2 is passed
     to pci_acpi_scan_root() and used to get resources that are
     passed to pci_create_root_bus().

  4. pci_create_root_bus() creates a struct pci_host_bridge object
     and passes its "dev" member to device_register().

  5. platform_notify(), which for systems with ACPI is set to
     acpi_platform_notify(), is called.

So far, so good.  Now it starts to be "interesting".

  6. acpi_find_bridge_device() is used to find the ACPI handle of
     the given device (which is the PCI root bridge) and executes
     acpi_pci_find_root_bridge(), among other things, for the
     given device object.

  7. acpi_pci_find_root_bridge() uses the name (sic!) of the given
     device object to extract the segment and bus numbers of the PCI
     root bridge and passes them to acpi_get_pci_rootbridge_handle().

  8. acpi_get_pci_rootbridge_handle() browses the list of ACPI PCI
     root bridges and finds the one that matches the given segment
     and bus numbers.  Its handle is then used to initialize the
     ACPI handle of the PCI root bridge's device object by
     acpi_bind_one().  However, this is *exactly* the ACPI handle we
     started with in step 1.

Needless to say, this is quite embarassing, but it may be avoided
thanks to commit f3fd0c8 (ACPI: Allow ACPI handles of devices to be
initialized in advance), which makes it possible to initialize the
ACPI handle of a device before passing it to device_register().

Accordingly, make pci_acpi_scan_root() pass the root bridge's ACPI
handle to pci_create_root_bus() and make the latter set the ACPI
handle in its struct pci_host_bridge object's "dev" member before
passing it to device_register(), so that steps 6-8 above aren't
necessary any more.

To implement that, I decided to repurpose the 4th argument of
pci_create_root_bus(), because that allowed me to avoid defining
additional callbacks or similar things and didn't seem to impact
architectures without ACPI substantially.

All architectures using pci_create_root_bus() directly are updated
as needed, but only x86 and ia64 are affected as far as the behavior
is concerned (no one else uses ACPI).  There should be no changes in
behavior resulting from this on the other architectures.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Yinghai Lu <yinghai@kernel.org>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Acked-by: H. Peter Anvin <hpa@zytor.com>
---

Peter Anvin pointed out to me that it's better to make it clear in the
changelog what the patch actually does versus what might be left as future
work, so here's another update with a slightly modified (and hopefully better)
changelog.  The patch itself hasn't been changed.

Thanks,
Rafael

---
 arch/ia64/pci/pci.c              |    5 ++++-
 arch/powerpc/kernel/pci-common.c |    3 ++-
 arch/s390/pci/pci.c              |    3 ++-
 arch/sparc/kernel/pci.c          |    3 ++-
 arch/x86/pci/acpi.c              |    5 ++++-
 drivers/acpi/pci_root.c          |   18 ------------------
 drivers/pci/pci-acpi.c           |   19 -------------------
 drivers/pci/probe.c              |   17 ++++++++++++-----
 include/acpi/acpi_bus.h          |    1 -
 include/linux/pci.h              |    9 ++++++++-
 10 files changed, 34 insertions(+), 49 deletions(-)


--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Comments

Lv Zheng Dec. 19, 2012, 6 a.m. UTC | #1
V2lsbCBmdXR1cmUgaW1wbGVtZW50YXRpb24gbW92ZSBfUkVHIGV2YWx1YXRpb25zIGZyb20gQUNQ
SUNBIGNvcmUgdG8gYSBwbGFjZSBiZWZvcmUgZHJpdmVyLT5wcm9iZSBhcyBhbGwgb2YgdGhlIHBo
eXNpY2FsIGRldmljZXMgd2lsbCBrbm93IHRoZWlyICJhY3BpX2hhbmRsZSIgc29vbiBhZnRlciBp
dCBpcyBjcmVhdGVkLg0KDQpUaGlzIHNlZW1zIHRvIGJlIGEgc29sdXRpb24gdG8gc29sdmUgcHJv
YmxlbXMgY2FuIGJlIGZvdW5kIGxpa2U6DQpPcnBoYW4gX1JFRyAvIF9ERVAgc3VwcG9ydC4uLg0K
SSdtIG5vdCBzdXJlIHRob3VnaCB0aGlzIHNvdW5kcyBiZXR0ZXIgdG8gbWFrZSBvbmVzIG9wZXJh
dGlvbmFsIHJlZ2lvbnMgcmVhZHkgb25seSBpZiBhIGRyaXZlciBpcyBnb2luZyB0byBiZSAiYXR0
YWNoZWQiIHRvIHRoZSBwaHlzaWNhbCBkZXZpY2UuDQoNClRoYW5rcw0KLUx2DQoNCj4gLS0tLS1P
cmlnaW5hbCBNZXNzYWdlLS0tLS0NCj4gRnJvbTogbGludXgtYWNwaS1vd25lckB2Z2VyLmtlcm5l
bC5vcmcNCj4gW21haWx0bzpsaW51eC1hY3BpLW93bmVyQHZnZXIua2VybmVsLm9yZ10gT24gQmVo
YWxmIE9mIFJhZmFlbCBKLiBXeXNvY2tpDQo+IFNlbnQ6IFR1ZXNkYXksIERlY2VtYmVyIDE4LCAy
MDEyIDc6MzAgQU0NCj4gVG86IEFDUEkgRGV2ZWwgTWFsaW5nIExpc3QNCj4gQ2M6IEdyZWcgS3Jv
YWgtSGFydG1hbjsgTEtNTDsgQmpvcm4gSGVsZ2FhczsgQmVuamFtaW4gSGVycmVuc2NobWlkdDsN
Cj4gRGF2aWQgTWlsbGVyOyBMdWNrLCBUb255OyBILiBQZXRlciBBbnZpbjsgWWluZ2hhaSBMdTsg
SmlhbmcgTGl1OyBNYXJ0aW4NCj4gU2Nod2lkZWZza3k7IEphbiBHbGF1YmVyDQo+IFN1YmplY3Q6
IFtVcGRhdGUgMl1bUEFUQ0hdIEFDUEkgLyBQQ0k6IFNldCByb290IGJyaWRnZSBBQ1BJIGhhbmRs
ZSBpbiBhZHZhbmNlDQo+IA0KPiBGcm9tOiBSYWZhZWwgSi4gV3lzb2NraSA8cmFmYWVsLmoud3lz
b2NraUBpbnRlbC5jb20+DQo+IA0KPiBUaGUgQUNQSSBoYW5kbGVzIG9mIFBDSSByb290IGJyaWRn
ZXMgbmVlZCB0byBiZSBrbm93biB0bw0KPiBhY3BpX2JpbmRfb25lKCksIHNvIHRoYXQgaXQgY2Fu
IGNyZWF0ZSB0aGUgYXBwcm9wcmlhdGUNCj4gImZpcm13YXJlX25vZGUiIGFuZCAicGh5c2ljYWxf
bm9kZSIgZmlsZXMgZm9yIHRoZW0sIGJ1dCBjdXJyZW50bHkNCj4gdGhlIHdheSBpdCBnZXRzIHRv
IGtub3cgdGhvc2UgaGFuZGxlcyBpcyBub3QgZXhhY3RseSBzdHJhaWdodGZvcndhcmQNCj4gKHRv
IHB1dCBpdCBsaWdodGx5KS4NCj4gDQo+IFRoaXMgaXMgaG93IGl0IHdvcmtzLCByb3VnaGx5Og0K
PiANCj4gICAxLiBhY3BpX2J1c19zY2FuKCkgZmluZHMgdGhlIGhhbmRsZSBvZiBhIFBDSSByb290
IGJyaWRnZSwNCj4gICAgICBjcmVhdGVzIGEgc3RydWN0IGFjcGlfZGV2aWNlIG9iamVjdCBmb3Ig
aXQgYW5kIHBhc3NlcyB0aGF0DQo+ICAgICAgb2JqZWN0IHRvIGFjcGlfcGNpX3Jvb3RfYWRkKCku
DQo+IA0KPiAgIDIuIGFjcGlfcGNpX3Jvb3RfYWRkKCkgY3JlYXRlcyBhIHN0cnVjdCBhY3BpX3Bj
aV9yb290IG9iamVjdCwNCj4gICAgICBwb3B1bGF0ZXMgaXRzICJkZXZpY2UiIGZpZWxkIHdpdGgg
aXRzIGFyZ3VtZW50J3MgYWRkcmVzcw0KPiAgICAgIChkZXZpY2UtPmhhbmRsZSBpcyB0aGUgQUNQ
SSBoYW5kbGUgZm91bmQgaW4gc3RlcCAxKS4NCj4gDQo+ICAgMy4gVGhlIHN0cnVjdCBhY3BpX3Bj
aV9yb290IG9iamVjdCBjcmVhdGVkIGluIHN0ZXAgMiBpcyBwYXNzZWQNCj4gICAgICB0byBwY2lf
YWNwaV9zY2FuX3Jvb3QoKSBhbmQgdXNlZCB0byBnZXQgcmVzb3VyY2VzIHRoYXQgYXJlDQo+ICAg
ICAgcGFzc2VkIHRvIHBjaV9jcmVhdGVfcm9vdF9idXMoKS4NCj4gDQo+ICAgNC4gcGNpX2NyZWF0
ZV9yb290X2J1cygpIGNyZWF0ZXMgYSBzdHJ1Y3QgcGNpX2hvc3RfYnJpZGdlIG9iamVjdA0KPiAg
ICAgIGFuZCBwYXNzZXMgaXRzICJkZXYiIG1lbWJlciB0byBkZXZpY2VfcmVnaXN0ZXIoKS4NCj4g
DQo+ICAgNS4gcGxhdGZvcm1fbm90aWZ5KCksIHdoaWNoIGZvciBzeXN0ZW1zIHdpdGggQUNQSSBp
cyBzZXQgdG8NCj4gICAgICBhY3BpX3BsYXRmb3JtX25vdGlmeSgpLCBpcyBjYWxsZWQuDQo+IA0K
PiBTbyBmYXIsIHNvIGdvb2QuICBOb3cgaXQgc3RhcnRzIHRvIGJlICJpbnRlcmVzdGluZyIuDQo+
IA0KPiAgIDYuIGFjcGlfZmluZF9icmlkZ2VfZGV2aWNlKCkgaXMgdXNlZCB0byBmaW5kIHRoZSBB
Q1BJIGhhbmRsZSBvZg0KPiAgICAgIHRoZSBnaXZlbiBkZXZpY2UgKHdoaWNoIGlzIHRoZSBQQ0kg
cm9vdCBicmlkZ2UpIGFuZCBleGVjdXRlcw0KPiAgICAgIGFjcGlfcGNpX2ZpbmRfcm9vdF9icmlk
Z2UoKSwgYW1vbmcgb3RoZXIgdGhpbmdzLCBmb3IgdGhlDQo+ICAgICAgZ2l2ZW4gZGV2aWNlIG9i
amVjdC4NCj4gDQo+ICAgNy4gYWNwaV9wY2lfZmluZF9yb290X2JyaWRnZSgpIHVzZXMgdGhlIG5h
bWUgKHNpYyEpIG9mIHRoZSBnaXZlbg0KPiAgICAgIGRldmljZSBvYmplY3QgdG8gZXh0cmFjdCB0
aGUgc2VnbWVudCBhbmQgYnVzIG51bWJlcnMgb2YgdGhlIFBDSQ0KPiAgICAgIHJvb3QgYnJpZGdl
IGFuZCBwYXNzZXMgdGhlbSB0byBhY3BpX2dldF9wY2lfcm9vdGJyaWRnZV9oYW5kbGUoKS4NCj4g
DQo+ICAgOC4gYWNwaV9nZXRfcGNpX3Jvb3RicmlkZ2VfaGFuZGxlKCkgYnJvd3NlcyB0aGUgbGlz
dCBvZiBBQ1BJIFBDSQ0KPiAgICAgIHJvb3QgYnJpZGdlcyBhbmQgZmluZHMgdGhlIG9uZSB0aGF0
IG1hdGNoZXMgdGhlIGdpdmVuIHNlZ21lbnQNCj4gICAgICBhbmQgYnVzIG51bWJlcnMuICBJdHMg
aGFuZGxlIGlzIHRoZW4gdXNlZCB0byBpbml0aWFsaXplIHRoZQ0KPiAgICAgIEFDUEkgaGFuZGxl
IG9mIHRoZSBQQ0kgcm9vdCBicmlkZ2UncyBkZXZpY2Ugb2JqZWN0IGJ5DQo+ICAgICAgYWNwaV9i
aW5kX29uZSgpLiAgSG93ZXZlciwgdGhpcyBpcyAqZXhhY3RseSogdGhlIEFDUEkgaGFuZGxlIHdl
DQo+ICAgICAgc3RhcnRlZCB3aXRoIGluIHN0ZXAgMS4NCj4gDQo+IE5lZWRsZXNzIHRvIHNheSwg
dGhpcyBpcyBxdWl0ZSBlbWJhcmFzc2luZywgYnV0IGl0IG1heSBiZSBhdm9pZGVkDQo+IHRoYW5r
cyB0byBjb21taXQgZjNmZDBjOCAoQUNQSTogQWxsb3cgQUNQSSBoYW5kbGVzIG9mIGRldmljZXMg
dG8gYmUNCj4gaW5pdGlhbGl6ZWQgaW4gYWR2YW5jZSksIHdoaWNoIG1ha2VzIGl0IHBvc3NpYmxl
IHRvIGluaXRpYWxpemUgdGhlDQo+IEFDUEkgaGFuZGxlIG9mIGEgZGV2aWNlIGJlZm9yZSBwYXNz
aW5nIGl0IHRvIGRldmljZV9yZWdpc3RlcigpLg0KPiANCj4gQWNjb3JkaW5nbHksIG1ha2UgcGNp
X2FjcGlfc2Nhbl9yb290KCkgcGFzcyB0aGUgcm9vdCBicmlkZ2UncyBBQ1BJDQo+IGhhbmRsZSB0
byBwY2lfY3JlYXRlX3Jvb3RfYnVzKCkgYW5kIG1ha2UgdGhlIGxhdHRlciBzZXQgdGhlIEFDUEkN
Cj4gaGFuZGxlIGluIGl0cyBzdHJ1Y3QgcGNpX2hvc3RfYnJpZGdlIG9iamVjdCdzICJkZXYiIG1l
bWJlciBiZWZvcmUNCj4gcGFzc2luZyBpdCB0byBkZXZpY2VfcmVnaXN0ZXIoKSwgc28gdGhhdCBz
dGVwcyA2LTggYWJvdmUgYXJlbid0DQo+IG5lY2Vzc2FyeSBhbnkgbW9yZS4NCj4gDQo+IFRvIGlt
cGxlbWVudCB0aGF0LCBJIGRlY2lkZWQgdG8gcmVwdXJwb3NlIHRoZSA0dGggYXJndW1lbnQgb2YN
Cj4gcGNpX2NyZWF0ZV9yb290X2J1cygpLCBiZWNhdXNlIHRoYXQgYWxsb3dlZCBtZSB0byBhdm9p
ZCBkZWZpbmluZw0KPiBhZGRpdGlvbmFsIGNhbGxiYWNrcyBvciBzaW1pbGFyIHRoaW5ncyBhbmQg
ZGlkbid0IHNlZW0gdG8gaW1wYWN0DQo+IGFyY2hpdGVjdHVyZXMgd2l0aG91dCBBQ1BJIHN1YnN0
YW50aWFsbHkuDQo+IA0KPiBBbGwgYXJjaGl0ZWN0dXJlcyB1c2luZyBwY2lfY3JlYXRlX3Jvb3Rf
YnVzKCkgZGlyZWN0bHkgYXJlIHVwZGF0ZWQNCj4gYXMgbmVlZGVkLCBidXQgb25seSB4ODYgYW5k
IGlhNjQgYXJlIGFmZmVjdGVkIGFzIGZhciBhcyB0aGUgYmVoYXZpb3INCj4gaXMgY29uY2VybmVk
IChubyBvbmUgZWxzZSB1c2VzIEFDUEkpLiAgVGhlcmUgc2hvdWxkIGJlIG5vIGNoYW5nZXMgaW4N
Cj4gYmVoYXZpb3IgcmVzdWx0aW5nIGZyb20gdGhpcyBvbiB0aGUgb3RoZXIgYXJjaGl0ZWN0dXJl
cy4NCj4gDQo+IFNpZ25lZC1vZmYtYnk6IFJhZmFlbCBKLiBXeXNvY2tpIDxyYWZhZWwuai53eXNv
Y2tpQGludGVsLmNvbT4NCj4gQWNrZWQtYnk6IFlpbmdoYWkgTHUgPHlpbmdoYWlAa2VybmVsLm9y
Zz4NCj4gQWNrZWQtYnk6IEdyZWcgS3JvYWgtSGFydG1hbiA8Z3JlZ2toQGxpbnV4Zm91bmRhdGlv
bi5vcmc+DQo+IEFja2VkLWJ5OiBILiBQZXRlciBBbnZpbiA8aHBhQHp5dG9yLmNvbT4NCj4gLS0t
DQo+IA0KPiBQZXRlciBBbnZpbiBwb2ludGVkIG91dCB0byBtZSB0aGF0IGl0J3MgYmV0dGVyIHRv
IG1ha2UgaXQgY2xlYXIgaW4gdGhlDQo+IGNoYW5nZWxvZyB3aGF0IHRoZSBwYXRjaCBhY3R1YWxs
eSBkb2VzIHZlcnN1cyB3aGF0IG1pZ2h0IGJlIGxlZnQgYXMgZnV0dXJlDQo+IHdvcmssIHNvIGhl
cmUncyBhbm90aGVyIHVwZGF0ZSB3aXRoIGEgc2xpZ2h0bHkgbW9kaWZpZWQgKGFuZCBob3BlZnVs
bHkgYmV0dGVyKQ0KPiBjaGFuZ2Vsb2cuICBUaGUgcGF0Y2ggaXRzZWxmIGhhc24ndCBiZWVuIGNo
YW5nZWQuDQo+IA0KPiBUaGFua3MsDQo+IFJhZmFlbA0KPiANCj4gLS0tDQo+ICBhcmNoL2lhNjQv
cGNpL3BjaS5jICAgICAgICAgICAgICB8ICAgIDUgKysrKy0NCj4gIGFyY2gvcG93ZXJwYy9rZXJu
ZWwvcGNpLWNvbW1vbi5jIHwgICAgMyArKy0NCj4gIGFyY2gvczM5MC9wY2kvcGNpLmMgICAgICAg
ICAgICAgIHwgICAgMyArKy0NCj4gIGFyY2gvc3BhcmMva2VybmVsL3BjaS5jICAgICAgICAgIHwg
ICAgMyArKy0NCj4gIGFyY2gveDg2L3BjaS9hY3BpLmMgICAgICAgICAgICAgIHwgICAgNSArKysr
LQ0KPiAgZHJpdmVycy9hY3BpL3BjaV9yb290LmMgICAgICAgICAgfCAgIDE4IC0tLS0tLS0tLS0t
LS0tLS0tLQ0KPiAgZHJpdmVycy9wY2kvcGNpLWFjcGkuYyAgICAgICAgICAgfCAgIDE5IC0tLS0t
LS0tLS0tLS0tLS0tLS0NCj4gIGRyaXZlcnMvcGNpL3Byb2JlLmMgICAgICAgICAgICAgIHwgICAx
NyArKysrKysrKysrKystLS0tLQ0KPiAgaW5jbHVkZS9hY3BpL2FjcGlfYnVzLmggICAgICAgICAg
fCAgICAxIC0NCj4gIGluY2x1ZGUvbGludXgvcGNpLmggICAgICAgICAgICAgIHwgICAgOSArKysr
KysrKy0NCj4gIDEwIGZpbGVzIGNoYW5nZWQsIDM0IGluc2VydGlvbnMoKyksIDQ5IGRlbGV0aW9u
cygtKQ0KPiANCj4gSW5kZXg6IGxpbnV4LXBtL2FyY2gveDg2L3BjaS9hY3BpLmMNCj4gPT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
PQ0KPiA9PT0NCj4gLS0tIGxpbnV4LXBtLm9yaWcvYXJjaC94ODYvcGNpL2FjcGkuYw0KPiArKysg
bGludXgtcG0vYXJjaC94ODYvcGNpL2FjcGkuYw0KPiBAQCAtNDgzLDYgKzQ4Myw3IEBAIHN0cnVj
dCBwY2lfYnVzICogX19kZXZpbml0IHBjaV9hY3BpX3NjYW4NCj4gIAlMSVNUX0hFQUQocmVzb3Vy
Y2VzKTsNCj4gIAlzdHJ1Y3QgcGNpX2J1cyAqYnVzID0gTlVMTDsNCj4gIAlzdHJ1Y3QgcGNpX3N5
c2RhdGEgKnNkOw0KPiArCXN0cnVjdCBwY2lfcm9vdF9zeXNfaW5mbyBzaTsNCj4gIAlpbnQgbm9k
ZTsNCj4gICNpZmRlZiBDT05GSUdfQUNQSV9OVU1BDQo+ICAJaW50IHB4bTsNCj4gQEAgLTUyMiw2
ICs1MjMsOCBAQCBzdHJ1Y3QgcGNpX2J1cyAqIF9fZGV2aW5pdCBwY2lfYWNwaV9zY2FuDQo+ICAJ
c2QgPSAmaW5mby0+c2Q7DQo+ICAJc2QtPmRvbWFpbiA9IGRvbWFpbjsNCj4gIAlzZC0+bm9kZSA9
IG5vZGU7DQo+ICsJc2kuYWNwaV9ub2RlLmhhbmRsZSA9IGRldmljZS0+aGFuZGxlOw0KPiArCXNp
LnN5c2RhdGEgPSBzZDsNCj4gIAkvKg0KPiAgCSAqIE1heWJlIHRoZSBkZXNpcmVkIHBjaSBidXMg
aGFzIGJlZW4gYWxyZWFkeSBzY2FubmVkLiBJbiBzdWNoIGNhc2UNCj4gIAkgKiBpdCBpcyB1bm5l
Y2Vzc2FyeSB0byBzY2FuIHRoZSBwY2kgYnVzIHdpdGggdGhlIGdpdmVuIGRvbWFpbixidXNudW0u
DQo+IEBAIC01NTMsNyArNTU2LDcgQEAgc3RydWN0IHBjaV9idXMgKiBfX2RldmluaXQgcGNpX2Fj
cGlfc2Nhbg0KPiAgCQlpZiAoIXNldHVwX21jZmdfbWFwKGluZm8sIGRvbWFpbiwgKHU4KXJvb3Qt
PnNlY29uZGFyeS5zdGFydCwNCj4gIAkJCQkgICAgKHU4KXJvb3QtPnNlY29uZGFyeS5lbmQsIHJv
b3QtPm1jZmdfYWRkcikpDQo+ICAJCQlidXMgPSBwY2lfY3JlYXRlX3Jvb3RfYnVzKE5VTEwsIGJ1
c251bSwgJnBjaV9yb290X29wcywNCj4gLQkJCQkJCSAgc2QsICZyZXNvdXJjZXMpOw0KPiArCQkJ
CQkJICAmc2ksICZyZXNvdXJjZXMpOw0KPiANCj4gIAkJaWYgKGJ1cykgew0KPiAgCQkJcGNpX3Nj
YW5fY2hpbGRfYnVzKGJ1cyk7DQo+IEluZGV4OiBsaW51eC1wbS9kcml2ZXJzL3BjaS9wcm9iZS5j
DQo+ID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT0NCj4gPT09DQo+IC0tLSBsaW51eC1wbS5vcmlnL2RyaXZlcnMvcGNpL3Byb2Jl
LmMNCj4gKysrIGxpbnV4LXBtL2RyaXZlcnMvcGNpL3Byb2JlLmMNCj4gQEAgLTE2MzQsNyArMTYz
NCw5IEBAIHVuc2lnbmVkIGludCBwY2lfc2Nhbl9jaGlsZF9idXMoc3RydWN0IHANCj4gIH0NCj4g
DQo+ICBzdHJ1Y3QgcGNpX2J1cyAqcGNpX2NyZWF0ZV9yb290X2J1cyhzdHJ1Y3QgZGV2aWNlICpw
YXJlbnQsIGludCBidXMsDQo+IC0JCXN0cnVjdCBwY2lfb3BzICpvcHMsIHZvaWQgKnN5c2RhdGEs
IHN0cnVjdCBsaXN0X2hlYWQgKnJlc291cmNlcykNCj4gKwkJCQkgICAgc3RydWN0IHBjaV9vcHMg
Km9wcywNCj4gKwkJCQkgICAgc3RydWN0IHBjaV9yb290X3N5c19pbmZvICpzeXNfaW5mbywNCj4g
KwkJCQkgICAgc3RydWN0IGxpc3RfaGVhZCAqcmVzb3VyY2VzKQ0KPiAgew0KPiAgCWludCBlcnJv
cjsNCj4gIAlzdHJ1Y3QgcGNpX2hvc3RfYnJpZGdlICpicmlkZ2U7DQo+IEBAIC0xNjUwLDcgKzE2
NTIsNyBAQCBzdHJ1Y3QgcGNpX2J1cyAqcGNpX2NyZWF0ZV9yb290X2J1cyhzdHJ1DQo+ICAJaWYg
KCFiKQ0KPiAgCQlyZXR1cm4gTlVMTDsNCj4gDQo+IC0JYi0+c3lzZGF0YSA9IHN5c2RhdGE7DQo+
ICsJYi0+c3lzZGF0YSA9IHN5c19pbmZvID8gc3lzX2luZm8tPnN5c2RhdGEgOiBOVUxMOw0KPiAg
CWItPm9wcyA9IG9wczsNCj4gIAliMiA9IHBjaV9maW5kX2J1cyhwY2lfZG9tYWluX25yKGIpLCBi
dXMpOw0KPiAgCWlmIChiMikgew0KPiBAQCAtMTY2Niw2ICsxNjY4LDggQEAgc3RydWN0IHBjaV9i
dXMgKnBjaV9jcmVhdGVfcm9vdF9idXMoc3RydQ0KPiAgCWJyaWRnZS0+ZGV2LnBhcmVudCA9IHBh
cmVudDsNCj4gIAlicmlkZ2UtPmRldi5yZWxlYXNlID0gcGNpX3JlbGVhc2VfYnVzX2JyaWRnZV9k
ZXY7DQo+ICAJZGV2X3NldF9uYW1lKCZicmlkZ2UtPmRldiwgInBjaSUwNHg6JTAyeCIsIHBjaV9k
b21haW5fbnIoYiksIGJ1cyk7DQo+ICsJQUNQSV9IQU5ETEVfU0VUKCZicmlkZ2UtPmRldiwNCj4g
KwkJCXN5c19pbmZvID8gc3lzX2luZm8tPmFjcGlfbm9kZS5oYW5kbGUgOiBOVUxMKTsNCj4gIAll
cnJvciA9IGRldmljZV9yZWdpc3RlcigmYnJpZGdlLT5kZXYpOw0KPiAgCWlmIChlcnJvcikNCj4g
IAkJZ290byBicmlkZ2VfZGV2X3JlZ19lcnI7DQo+IEBAIC0xNzk4LDYgKzE4MDIsNyBAQCBzdHJ1
Y3QgcGNpX2J1cyAqcGNpX3NjYW5fcm9vdF9idXMoc3RydWN0DQo+ICAJCXN0cnVjdCBwY2lfb3Bz
ICpvcHMsIHZvaWQgKnN5c2RhdGEsIHN0cnVjdCBsaXN0X2hlYWQgKnJlc291cmNlcykNCj4gIHsN
Cj4gIAlzdHJ1Y3QgcGNpX2hvc3RfYnJpZGdlX3dpbmRvdyAqd2luZG93Ow0KPiArCXN0cnVjdCBw
Y2lfcm9vdF9zeXNfaW5mbyBzaSA9IHsgLnN5c2RhdGEgPSBzeXNkYXRhLCB9Ow0KPiAgCWJvb2wg
Zm91bmQgPSBmYWxzZTsNCj4gIAlzdHJ1Y3QgcGNpX2J1cyAqYjsNCj4gIAlpbnQgbWF4Ow0KPiBA
QCAtMTgwOCw3ICsxODEzLDcgQEAgc3RydWN0IHBjaV9idXMgKnBjaV9zY2FuX3Jvb3RfYnVzKHN0
cnVjdA0KPiAgCQkJYnJlYWs7DQo+ICAJCX0NCj4gDQo+IC0JYiA9IHBjaV9jcmVhdGVfcm9vdF9i
dXMocGFyZW50LCBidXMsIG9wcywgc3lzZGF0YSwgcmVzb3VyY2VzKTsNCj4gKwliID0gcGNpX2Ny
ZWF0ZV9yb290X2J1cyhwYXJlbnQsIGJ1cywgb3BzLCAmc2ksIHJlc291cmNlcyk7DQo+ICAJaWYg
KCFiKQ0KPiAgCQlyZXR1cm4gTlVMTDsNCj4gDQo+IEBAIC0xODMzLDEzICsxODM4LDE0IEBAIEVY
UE9SVF9TWU1CT0wocGNpX3NjYW5fcm9vdF9idXMpOw0KPiAgc3RydWN0IHBjaV9idXMgKnBjaV9z
Y2FuX2J1c19wYXJlbnRlZChzdHJ1Y3QgZGV2aWNlICpwYXJlbnQsDQo+ICAJCWludCBidXMsIHN0
cnVjdCBwY2lfb3BzICpvcHMsIHZvaWQgKnN5c2RhdGEpDQo+ICB7DQo+ICsJc3RydWN0IHBjaV9y
b290X3N5c19pbmZvIHNpID0geyAuc3lzZGF0YSA9IHN5c2RhdGEsIH07DQo+ICAJTElTVF9IRUFE
KHJlc291cmNlcyk7DQo+ICAJc3RydWN0IHBjaV9idXMgKmI7DQo+IA0KPiAgCXBjaV9hZGRfcmVz
b3VyY2UoJnJlc291cmNlcywgJmlvcG9ydF9yZXNvdXJjZSk7DQo+ICAJcGNpX2FkZF9yZXNvdXJj
ZSgmcmVzb3VyY2VzLCAmaW9tZW1fcmVzb3VyY2UpOw0KPiAgCXBjaV9hZGRfcmVzb3VyY2UoJnJl
c291cmNlcywgJmJ1c25fcmVzb3VyY2UpOw0KPiAtCWIgPSBwY2lfY3JlYXRlX3Jvb3RfYnVzKHBh
cmVudCwgYnVzLCBvcHMsIHN5c2RhdGEsICZyZXNvdXJjZXMpOw0KPiArCWIgPSBwY2lfY3JlYXRl
X3Jvb3RfYnVzKHBhcmVudCwgYnVzLCBvcHMsICZzaSwgJnJlc291cmNlcyk7DQo+ICAJaWYgKGIp
DQo+ICAJCXBjaV9zY2FuX2NoaWxkX2J1cyhiKTsNCj4gIAllbHNlDQo+IEBAIC0xODUxLDEzICsx
ODU3LDE0IEBAIEVYUE9SVF9TWU1CT0wocGNpX3NjYW5fYnVzX3BhcmVudGVkKTsNCj4gIHN0cnVj
dCBwY2lfYnVzICpwY2lfc2Nhbl9idXMoaW50IGJ1cywgc3RydWN0IHBjaV9vcHMgKm9wcywNCj4g
IAkJCQkJdm9pZCAqc3lzZGF0YSkNCj4gIHsNCj4gKwlzdHJ1Y3QgcGNpX3Jvb3Rfc3lzX2luZm8g
c2kgPSB7IC5zeXNkYXRhID0gc3lzZGF0YSwgfTsNCj4gIAlMSVNUX0hFQUQocmVzb3VyY2VzKTsN
Cj4gIAlzdHJ1Y3QgcGNpX2J1cyAqYjsNCj4gDQo+ICAJcGNpX2FkZF9yZXNvdXJjZSgmcmVzb3Vy
Y2VzLCAmaW9wb3J0X3Jlc291cmNlKTsNCj4gIAlwY2lfYWRkX3Jlc291cmNlKCZyZXNvdXJjZXMs
ICZpb21lbV9yZXNvdXJjZSk7DQo+ICAJcGNpX2FkZF9yZXNvdXJjZSgmcmVzb3VyY2VzLCAmYnVz
bl9yZXNvdXJjZSk7DQo+IC0JYiA9IHBjaV9jcmVhdGVfcm9vdF9idXMoTlVMTCwgYnVzLCBvcHMs
IHN5c2RhdGEsICZyZXNvdXJjZXMpOw0KPiArCWIgPSBwY2lfY3JlYXRlX3Jvb3RfYnVzKE5VTEws
IGJ1cywgb3BzLCAmc2ksICZyZXNvdXJjZXMpOw0KPiAgCWlmIChiKSB7DQo+ICAJCXBjaV9zY2Fu
X2NoaWxkX2J1cyhiKTsNCj4gIAkJcGNpX2J1c19hZGRfZGV2aWNlcyhiKTsNCj4gSW5kZXg6IGxp
bnV4LXBtL2luY2x1ZGUvbGludXgvcGNpLmgNCj4gPT09PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQ0KPiA9PT0NCj4gLS0tIGxpbnV4
LXBtLm9yaWcvaW5jbHVkZS9saW51eC9wY2kuaA0KPiArKysgbGludXgtcG0vaW5jbHVkZS9saW51
eC9wY2kuaA0KPiBAQCAtNzAwLDggKzcwMCwxNSBAQCB2b2lkIHBjaV9idXNfYWRkX2RldmljZXMo
Y29uc3Qgc3RydWN0IHBjDQo+ICBzdHJ1Y3QgcGNpX2J1cyAqcGNpX3NjYW5fYnVzX3BhcmVudGVk
KHN0cnVjdCBkZXZpY2UgKnBhcmVudCwgaW50IGJ1cywNCj4gIAkJCQkgICAgICBzdHJ1Y3QgcGNp
X29wcyAqb3BzLCB2b2lkICpzeXNkYXRhKTsNCj4gIHN0cnVjdCBwY2lfYnVzICpwY2lfc2Nhbl9i
dXMoaW50IGJ1cywgc3RydWN0IHBjaV9vcHMgKm9wcywgdm9pZCAqc3lzZGF0YSk7DQo+ICsNCj4g
K3N0cnVjdCBwY2lfcm9vdF9zeXNfaW5mbyB7DQo+ICsJdm9pZCAqc3lzZGF0YTsNCj4gKwlzdHJ1
Y3QgYWNwaV9kZXZfbm9kZSBhY3BpX25vZGU7DQo+ICt9Ow0KPiArDQo+ICBzdHJ1Y3QgcGNpX2J1
cyAqcGNpX2NyZWF0ZV9yb290X2J1cyhzdHJ1Y3QgZGV2aWNlICpwYXJlbnQsIGludCBidXMsDQo+
IC0JCQkJICAgIHN0cnVjdCBwY2lfb3BzICpvcHMsIHZvaWQgKnN5c2RhdGEsDQo+ICsJCQkJICAg
IHN0cnVjdCBwY2lfb3BzICpvcHMsDQo+ICsJCQkJICAgIHN0cnVjdCBwY2lfcm9vdF9zeXNfaW5m
byAqc3lzX2luZm8sDQo+ICAJCQkJICAgIHN0cnVjdCBsaXN0X2hlYWQgKnJlc291cmNlcyk7DQo+
ICBpbnQgcGNpX2J1c19pbnNlcnRfYnVzbl9yZXMoc3RydWN0IHBjaV9idXMgKmIsIGludCBidXMs
IGludCBidXNtYXgpOw0KPiAgaW50IHBjaV9idXNfdXBkYXRlX2J1c25fcmVzX2VuZChzdHJ1Y3Qg
cGNpX2J1cyAqYiwgaW50IGJ1c21heCk7DQo+IEluZGV4OiBsaW51eC1wbS9hcmNoL2lhNjQvcGNp
L3BjaS5jDQo+ID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT0NCj4gPT09DQo+IC0tLSBsaW51eC1wbS5vcmlnL2FyY2gvaWE2NC9w
Y2kvcGNpLmMNCj4gKysrIGxpbnV4LXBtL2FyY2gvaWE2NC9wY2kvcGNpLmMNCj4gQEAgLTMzMyw2
ICszMzMsNyBAQCBwY2lfYWNwaV9zY2FuX3Jvb3Qoc3RydWN0IGFjcGlfcGNpX3Jvb3QNCj4gIAlz
dHJ1Y3QgcGNpX2NvbnRyb2xsZXIgKmNvbnRyb2xsZXI7DQo+ICAJdW5zaWduZWQgaW50IHdpbmRv
d3MgPSAwOw0KPiAgCXN0cnVjdCBwY2lfcm9vdF9pbmZvIGluZm87DQo+ICsJc3RydWN0IHBjaV9y
b290X3N5c19pbmZvIHNpOw0KPiAgCXN0cnVjdCBwY2lfYnVzICpwYnVzOw0KPiAgCWNoYXIgKm5h
bWU7DQo+ICAJaW50IHB4bTsNCj4gQEAgLTM3OCw3ICszNzksOSBAQCBwY2lfYWNwaV9zY2FuX3Jv
b3Qoc3RydWN0IGFjcGlfcGNpX3Jvb3QNCj4gIAkgKiBzaG91bGQgaGFuZGxlIHRoZSBjYXNlIGhl
cmUsIGJ1dCBpdCBhcHBlYXJzIHRoYXQgSUE2NCBoYXNuJ3QNCj4gIAkgKiBzdWNoIHF1aXJrLiBT
byB3ZSBqdXN0IGlnbm9yZSB0aGUgY2FzZSBub3cuDQo+ICAJICovDQo+IC0JcGJ1cyA9IHBjaV9j
cmVhdGVfcm9vdF9idXMoTlVMTCwgYnVzLCAmcGNpX3Jvb3Rfb3BzLCBjb250cm9sbGVyLA0KPiAr
CXNpLnN5c2RhdGEgPSBjb250cm9sbGVyOw0KPiArCXNpLmFjcGlfbm9kZS5oYW5kbGUgPSBjb250
cm9sbGVyLT5hY3BpX2hhbmRsZTsNCj4gKwlwYnVzID0gcGNpX2NyZWF0ZV9yb290X2J1cyhOVUxM
LCBidXMsICZwY2lfcm9vdF9vcHMsICZzaSwNCj4gIAkJCQkgICAmaW5mby5yZXNvdXJjZXMpOw0K
PiAgCWlmICghcGJ1cykgew0KPiAgCQlwY2lfZnJlZV9yZXNvdXJjZV9saXN0KCZpbmZvLnJlc291
cmNlcyk7DQo+IEluZGV4OiBsaW51eC1wbS9hcmNoL3Bvd2VycGMva2VybmVsL3BjaS1jb21tb24u
Yw0KPiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09DQo+ID09PQ0KPiAtLS0gbGludXgtcG0ub3JpZy9hcmNoL3Bvd2VycGMva2Vy
bmVsL3BjaS1jb21tb24uYw0KPiArKysgbGludXgtcG0vYXJjaC9wb3dlcnBjL2tlcm5lbC9wY2kt
Y29tbW9uLmMNCj4gQEAgLTE2NDQsNiArMTY0NCw3IEBAIHZvaWQgX19kZXZpbml0IHBjaWJpb3Nf
c2Nhbl9waGIoc3RydWN0IHANCj4gIAlMSVNUX0hFQUQocmVzb3VyY2VzKTsNCj4gIAlzdHJ1Y3Qg
cGNpX2J1cyAqYnVzOw0KPiAgCXN0cnVjdCBkZXZpY2Vfbm9kZSAqbm9kZSA9IGhvc2UtPmRuOw0K
PiArCXN0cnVjdCBwY2lfcm9vdF9zeXNfaW5mbyBzaSA9IHsgLnN5c2RhdGEgPSBob3NlLCB9Ow0K
PiAgCWludCBtb2RlOw0KPiANCj4gIAlwcl9kZWJ1ZygiUENJOiBTY2FubmluZyBQSEIgJXNcbiIs
IG9mX25vZGVfZnVsbF9uYW1lKG5vZGUpKTsNCj4gQEAgLTE2NjEsNyArMTY2Miw3IEBAIHZvaWQg
X19kZXZpbml0IHBjaWJpb3Nfc2Nhbl9waGIoc3RydWN0IHANCj4gDQo+ICAJLyogQ3JlYXRlIGFu
IGVtcHR5IGJ1cyBmb3IgdGhlIHRvcGxldmVsICovDQo+ICAJYnVzID0gcGNpX2NyZWF0ZV9yb290
X2J1cyhob3NlLT5wYXJlbnQsIGhvc2UtPmZpcnN0X2J1c25vLA0KPiAtCQkJCSAgaG9zZS0+b3Bz
LCBob3NlLCAmcmVzb3VyY2VzKTsNCj4gKwkJCQkgIGhvc2UtPm9wcywgJnNpLCAmcmVzb3VyY2Vz
KTsNCj4gIAlpZiAoYnVzID09IE5VTEwpIHsNCj4gIAkJcHJfZXJyKCJGYWlsZWQgdG8gY3JlYXRl
IGJ1cyBmb3IgUENJIGRvbWFpbiAlMDR4XG4iLA0KPiAgCQkJaG9zZS0+Z2xvYmFsX251bWJlcik7
DQo+IEluZGV4OiBsaW51eC1wbS9hcmNoL3NwYXJjL2tlcm5lbC9wY2kuYw0KPiA9PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09DQo+
ID09PQ0KPiAtLS0gbGludXgtcG0ub3JpZy9hcmNoL3NwYXJjL2tlcm5lbC9wY2kuYw0KPiArKysg
bGludXgtcG0vYXJjaC9zcGFyYy9rZXJuZWwvcGNpLmMNCj4gQEAgLTU5MCw2ICs1OTAsNyBAQCBz
dHJ1Y3QgcGNpX2J1cyAqIF9fZGV2aW5pdCBwY2lfc2Nhbl9vbmVfDQo+ICB7DQo+ICAJTElTVF9I
RUFEKHJlc291cmNlcyk7DQo+ICAJc3RydWN0IGRldmljZV9ub2RlICpub2RlID0gcGJtLT5vcC0+
ZGV2Lm9mX25vZGU7DQo+ICsJc3RydWN0IHBjaV9yb290X3N5c19pbmZvIHNpID0geyAuc3lzZGF0
YSA9IHBibSwgfTsNCj4gIAlzdHJ1Y3QgcGNpX2J1cyAqYnVzOw0KPiANCj4gIAlwcmludGsoIlBD
STogU2Nhbm5pbmcgUEJNICVzXG4iLCBub2RlLT5mdWxsX25hbWUpOw0KPiBAQCAtNjAzLDcgKzYw
NCw3IEBAIHN0cnVjdCBwY2lfYnVzICogX19kZXZpbml0IHBjaV9zY2FuX29uZV8NCj4gIAlwYm0t
PmJ1c24uZmxhZ3MJPSBJT1JFU09VUkNFX0JVUzsNCj4gIAlwY2lfYWRkX3Jlc291cmNlKCZyZXNv
dXJjZXMsICZwYm0tPmJ1c24pOw0KPiAgCWJ1cyA9IHBjaV9jcmVhdGVfcm9vdF9idXMocGFyZW50
LCBwYm0tPnBjaV9maXJzdF9idXNubywgcGJtLT5wY2lfb3BzLA0KPiAtCQkJCSAgcGJtLCAmcmVz
b3VyY2VzKTsNCj4gKwkJCQkgICZzaSwgJnJlc291cmNlcyk7DQo+ICAJaWYgKCFidXMpIHsNCj4g
IAkJcHJpbnRrKEtFUk5fRVJSICJGYWlsZWQgdG8gY3JlYXRlIGJ1cyBmb3IgJXNcbiIsDQo+ICAJ
CSAgICAgICBub2RlLT5mdWxsX25hbWUpOw0KPiBJbmRleDogbGludXgtcG0vZHJpdmVycy9wY2kv
cGNpLWFjcGkuYw0KPiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09DQo+ID09PQ0KPiAtLS0gbGludXgtcG0ub3JpZy9kcml2ZXJz
L3BjaS9wY2ktYWNwaS5jDQo+ICsrKyBsaW51eC1wbS9kcml2ZXJzL3BjaS9wY2ktYWNwaS5jDQo+
IEBAIC0zMDMsMjggKzMwMyw5IEBAIHN0YXRpYyBpbnQgYWNwaV9wY2lfZmluZF9kZXZpY2Uoc3Ry
dWN0IGQNCj4gIAlyZXR1cm4gMDsNCj4gIH0NCj4gDQo+IC1zdGF0aWMgaW50IGFjcGlfcGNpX2Zp
bmRfcm9vdF9icmlkZ2Uoc3RydWN0IGRldmljZSAqZGV2LCBhY3BpX2hhbmRsZSAqaGFuZGxlKQ0K
PiAtew0KPiAtCWludCBudW07DQo+IC0JdW5zaWduZWQgaW50IHNlZywgYnVzOw0KPiAtDQo+IC0J
LyoNCj4gLQkgKiBUaGUgc3RyaW5nIHNob3VsZCBiZSB0aGUgc2FtZSBhcyByb290IGJyaWRnZSdz
IG5hbWUNCj4gLQkgKiBQbGVhc2UgbG9vayBhdCAncGNpX3NjYW5fYnVzX3BhcmVudGVkJw0KPiAt
CSAqLw0KPiAtCW51bSA9IHNzY2FuZihkZXZfbmFtZShkZXYpLCAicGNpJTA0eDolMDJ4IiwgJnNl
ZywgJmJ1cyk7DQo+IC0JaWYgKG51bSAhPSAyKQ0KPiAtCQlyZXR1cm4gLUVOT0RFVjsNCj4gLQkq
aGFuZGxlID0gYWNwaV9nZXRfcGNpX3Jvb3RicmlkZ2VfaGFuZGxlKHNlZywgYnVzKTsNCj4gLQlp
ZiAoISpoYW5kbGUpDQo+IC0JCXJldHVybiAtRU5PREVWOw0KPiAtCXJldHVybiAwOw0KPiAtfQ0K
PiAtDQo+ICBzdGF0aWMgc3RydWN0IGFjcGlfYnVzX3R5cGUgYWNwaV9wY2lfYnVzID0gew0KPiAg
CS5idXMgPSAmcGNpX2J1c190eXBlLA0KPiAgCS5maW5kX2RldmljZSA9IGFjcGlfcGNpX2ZpbmRf
ZGV2aWNlLA0KPiAtCS5maW5kX2JyaWRnZSA9IGFjcGlfcGNpX2ZpbmRfcm9vdF9icmlkZ2UsDQo+
ICB9Ow0KPiANCj4gIHN0YXRpYyBpbnQgX19pbml0IGFjcGlfcGNpX2luaXQodm9pZCkNCj4gSW5k
ZXg6IGxpbnV4LXBtL2RyaXZlcnMvYWNwaS9wY2lfcm9vdC5jDQo+ID09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0NCj4gPT09DQo+
IC0tLSBsaW51eC1wbS5vcmlnL2RyaXZlcnMvYWNwaS9wY2lfcm9vdC5jDQo+ICsrKyBsaW51eC1w
bS9kcml2ZXJzL2FjcGkvcGNpX3Jvb3QuYw0KPiBAQCAtMTA3LDI0ICsxMDcsNiBAQCB2b2lkIGFj
cGlfcGNpX3VucmVnaXN0ZXJfZHJpdmVyKHN0cnVjdCBhDQo+ICB9DQo+ICBFWFBPUlRfU1lNQk9M
KGFjcGlfcGNpX3VucmVnaXN0ZXJfZHJpdmVyKTsNCj4gDQo+IC1hY3BpX2hhbmRsZSBhY3BpX2dl
dF9wY2lfcm9vdGJyaWRnZV9oYW5kbGUodW5zaWduZWQgaW50IHNlZywgdW5zaWduZWQgaW50DQo+
IGJ1cykNCj4gLXsNCj4gLQlzdHJ1Y3QgYWNwaV9wY2lfcm9vdCAqcm9vdDsNCj4gLQlhY3BpX2hh
bmRsZSBoYW5kbGUgPSBOVUxMOw0KPiAtDQo+IC0JbXV0ZXhfbG9jaygmYWNwaV9wY2lfcm9vdF9s
b2NrKTsNCj4gLQlsaXN0X2Zvcl9lYWNoX2VudHJ5KHJvb3QsICZhY3BpX3BjaV9yb290cywgbm9k
ZSkNCj4gLQkJaWYgKChyb290LT5zZWdtZW50ID09ICh1MTYpIHNlZykgJiYNCj4gLQkJICAgIChy
b290LT5zZWNvbmRhcnkuc3RhcnQgPT0gKHUxNikgYnVzKSkgew0KPiAtCQkJaGFuZGxlID0gcm9v
dC0+ZGV2aWNlLT5oYW5kbGU7DQo+IC0JCQlicmVhazsNCj4gLQkJfQ0KPiAtCW11dGV4X3VubG9j
aygmYWNwaV9wY2lfcm9vdF9sb2NrKTsNCj4gLQlyZXR1cm4gaGFuZGxlOw0KPiAtfQ0KPiAtDQo+
IC1FWFBPUlRfU1lNQk9MX0dQTChhY3BpX2dldF9wY2lfcm9vdGJyaWRnZV9oYW5kbGUpOw0KPiAt
DQo+ICAvKioNCj4gICAqIGFjcGlfaXNfcm9vdF9icmlkZ2UgLSBkZXRlcm1pbmUgd2hldGhlciBh
biBBQ1BJIENBIG5vZGUgaXMgYSBQQ0kgcm9vdA0KPiBicmlkZ2UNCj4gICAqIEBoYW5kbGUgLSB0
aGUgQUNQSSBDQSBub2RlIGluIHF1ZXN0aW9uLg0KPiBJbmRleDogbGludXgtcG0vaW5jbHVkZS9h
Y3BpL2FjcGlfYnVzLmgNCj4gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PQ0KPiA9PT0NCj4gLS0tIGxpbnV4LXBtLm9yaWcvaW5j
bHVkZS9hY3BpL2FjcGlfYnVzLmgNCj4gKysrIGxpbnV4LXBtL2luY2x1ZGUvYWNwaS9hY3BpX2J1
cy5oDQo+IEBAIC00NDMsNyArNDQzLDYgQEAgc3RydWN0IGFjcGlfcGNpX3Jvb3Qgew0KPiAgLyog
aGVscGVyICovDQo+ICBhY3BpX2hhbmRsZSBhY3BpX2dldF9jaGlsZChhY3BpX2hhbmRsZSwgdTY0
KTsNCj4gIGludCBhY3BpX2lzX3Jvb3RfYnJpZGdlKGFjcGlfaGFuZGxlKTsNCj4gLWFjcGlfaGFu
ZGxlIGFjcGlfZ2V0X3BjaV9yb290YnJpZGdlX2hhbmRsZSh1bnNpZ25lZCBpbnQsIHVuc2lnbmVk
IGludCk7DQo+ICBzdHJ1Y3QgYWNwaV9wY2lfcm9vdCAqYWNwaV9wY2lfZmluZF9yb290KGFjcGlf
aGFuZGxlIGhhbmRsZSk7DQo+ICAjZGVmaW5lIERFVklDRV9BQ1BJX0hBTkRMRShkZXYpICgoYWNw
aV9oYW5kbGUpQUNQSV9IQU5ETEUoZGV2KSkNCj4gDQo+IEluZGV4OiBsaW51eC1wbS9hcmNoL3Mz
OTAvcGNpL3BjaS5jDQo+ID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT0NCj4gPT09DQo+IC0tLSBsaW51eC1wbS5vcmlnL2FyY2gv
czM5MC9wY2kvcGNpLmMNCj4gKysrIGxpbnV4LXBtL2FyY2gvczM5MC9wY2kvcGNpLmMNCj4gQEAg
LTg1Miw2ICs4NTIsNyBAQCBzdGF0aWMgdm9pZCB6cGNpX2ZyZWVfaW9tYXAoc3RydWN0IHpwY2lf
DQo+IA0KPiAgc3RhdGljIGludCB6cGNpX2NyZWF0ZV9kZXZpY2VfYnVzKHN0cnVjdCB6cGNpX2Rl
diAqemRldikNCj4gIHsNCj4gKwlzdHJ1Y3QgcGNpX3Jvb3Rfc3lzX2luZm8gc2kgPSB7IC5zeXNk
YXRhID0gemRldiwgfTsNCj4gIAlzdHJ1Y3QgcmVzb3VyY2UgKnJlczsNCj4gIAlMSVNUX0hFQUQo
cmVzb3VyY2VzKTsNCj4gIAlpbnQgaTsNCj4gQEAgLTg4OCw3ICs4ODksNyBAQCBzdGF0aWMgaW50
IHpwY2lfY3JlYXRlX2RldmljZV9idXMoc3RydWN0DQo+ICAJfQ0KPiANCj4gIAl6ZGV2LT5idXMg
PSBwY2lfY3JlYXRlX3Jvb3RfYnVzKE5VTEwsIFpQQ0lfQlVTX05SLCAmcGNpX3Jvb3Rfb3BzLA0K
PiAtCQkJCQl6ZGV2LCAmcmVzb3VyY2VzKTsNCj4gKwkJCQkJJnNpLCAmcmVzb3VyY2VzKTsNCj4g
IAlpZiAoIXpkZXYtPmJ1cykNCj4gIAkJcmV0dXJuIC1FSU87DQo+IA0KPiANCj4gLS0NCj4gVG8g
dW5zdWJzY3JpYmUgZnJvbSB0aGlzIGxpc3Q6IHNlbmQgdGhlIGxpbmUgInVuc3Vic2NyaWJlIGxp
bnV4LWFjcGkiIGluDQo+IHRoZSBib2R5IG9mIGEgbWVzc2FnZSB0byBtYWpvcmRvbW9Admdlci5r
ZXJuZWwub3JnDQo+IE1vcmUgbWFqb3Jkb21vIGluZm8gYXQgIGh0dHA6Ly92Z2VyLmtlcm5lbC5v
cmcvbWFqb3Jkb21vLWluZm8uaHRtbA0K
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Rafael Wysocki Dec. 19, 2012, 10:50 a.m. UTC | #2
On Wednesday, December 19, 2012 06:00:18 AM Zheng, Lv wrote:
> Will future implementation move _REG evaluations from ACPICA core to a place before
> driver->probe as all of the physical devices will know their "acpi_handle" soon after
> it is created.

We may do that, although quite frankly I haven't been considering that.

> This seems to be a solution to solve problems can be found like:
> Orphan _REG / _DEP support...
> I'm not sure though this sounds better to make ones operational regions ready
> only if a driver is going to be "attached" to the physical device.

Well, they may be accessed by unrelated AML in theory.

Thanks,
Rafael


> > -----Original Message-----
> > From: linux-acpi-owner@vger.kernel.org
> > [mailto:linux-acpi-owner@vger.kernel.org] On Behalf Of Rafael J. Wysocki
> > Sent: Tuesday, December 18, 2012 7:30 AM
> > To: ACPI Devel Maling List
> > Cc: Greg Kroah-Hartman; LKML; Bjorn Helgaas; Benjamin Herrenschmidt;
> > David Miller; Luck, Tony; H. Peter Anvin; Yinghai Lu; Jiang Liu; Martin
> > Schwidefsky; Jan Glauber
> > Subject: [Update 2][PATCH] ACPI / PCI: Set root bridge ACPI handle in advance
> > 
> > From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> > 
> > The ACPI handles of PCI root bridges need to be known to
> > acpi_bind_one(), so that it can create the appropriate
> > "firmware_node" and "physical_node" files for them, but currently
> > the way it gets to know those handles is not exactly straightforward
> > (to put it lightly).
> > 
> > This is how it works, roughly:
> > 
> >   1. acpi_bus_scan() finds the handle of a PCI root bridge,
> >      creates a struct acpi_device object for it and passes that
> >      object to acpi_pci_root_add().
> > 
> >   2. acpi_pci_root_add() creates a struct acpi_pci_root object,
> >      populates its "device" field with its argument's address
> >      (device->handle is the ACPI handle found in step 1).
> > 
> >   3. The struct acpi_pci_root object created in step 2 is passed
> >      to pci_acpi_scan_root() and used to get resources that are
> >      passed to pci_create_root_bus().
> > 
> >   4. pci_create_root_bus() creates a struct pci_host_bridge object
> >      and passes its "dev" member to device_register().
> > 
> >   5. platform_notify(), which for systems with ACPI is set to
> >      acpi_platform_notify(), is called.
> > 
> > So far, so good.  Now it starts to be "interesting".
> > 
> >   6. acpi_find_bridge_device() is used to find the ACPI handle of
> >      the given device (which is the PCI root bridge) and executes
> >      acpi_pci_find_root_bridge(), among other things, for the
> >      given device object.
> > 
> >   7. acpi_pci_find_root_bridge() uses the name (sic!) of the given
> >      device object to extract the segment and bus numbers of the PCI
> >      root bridge and passes them to acpi_get_pci_rootbridge_handle().
> > 
> >   8. acpi_get_pci_rootbridge_handle() browses the list of ACPI PCI
> >      root bridges and finds the one that matches the given segment
> >      and bus numbers.  Its handle is then used to initialize the
> >      ACPI handle of the PCI root bridge's device object by
> >      acpi_bind_one().  However, this is *exactly* the ACPI handle we
> >      started with in step 1.
> > 
> > Needless to say, this is quite embarassing, but it may be avoided
> > thanks to commit f3fd0c8 (ACPI: Allow ACPI handles of devices to be
> > initialized in advance), which makes it possible to initialize the
> > ACPI handle of a device before passing it to device_register().
> > 
> > Accordingly, make pci_acpi_scan_root() pass the root bridge's ACPI
> > handle to pci_create_root_bus() and make the latter set the ACPI
> > handle in its struct pci_host_bridge object's "dev" member before
> > passing it to device_register(), so that steps 6-8 above aren't
> > necessary any more.
> > 
> > To implement that, I decided to repurpose the 4th argument of
> > pci_create_root_bus(), because that allowed me to avoid defining
> > additional callbacks or similar things and didn't seem to impact
> > architectures without ACPI substantially.
> > 
> > All architectures using pci_create_root_bus() directly are updated
> > as needed, but only x86 and ia64 are affected as far as the behavior
> > is concerned (no one else uses ACPI).  There should be no changes in
> > behavior resulting from this on the other architectures.
> > 
> > Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> > Acked-by: Yinghai Lu <yinghai@kernel.org>
> > Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> > Acked-by: H. Peter Anvin <hpa@zytor.com>
> > ---
> > 
> > Peter Anvin pointed out to me that it's better to make it clear in the
> > changelog what the patch actually does versus what might be left as future
> > work, so here's another update with a slightly modified (and hopefully better)
> > changelog.  The patch itself hasn't been changed.
> > 
> > Thanks,
> > Rafael
> > 
> > ---
> >  arch/ia64/pci/pci.c              |    5 ++++-
> >  arch/powerpc/kernel/pci-common.c |    3 ++-
> >  arch/s390/pci/pci.c              |    3 ++-
> >  arch/sparc/kernel/pci.c          |    3 ++-
> >  arch/x86/pci/acpi.c              |    5 ++++-
> >  drivers/acpi/pci_root.c          |   18 ------------------
> >  drivers/pci/pci-acpi.c           |   19 -------------------
> >  drivers/pci/probe.c              |   17 ++++++++++++-----
> >  include/acpi/acpi_bus.h          |    1 -
> >  include/linux/pci.h              |    9 ++++++++-
> >  10 files changed, 34 insertions(+), 49 deletions(-)
> > 
> > Index: linux-pm/arch/x86/pci/acpi.c
> > ================================================================
> > ===
> > --- linux-pm.orig/arch/x86/pci/acpi.c
> > +++ linux-pm/arch/x86/pci/acpi.c
> > @@ -483,6 +483,7 @@ struct pci_bus * __devinit pci_acpi_scan
> >  	LIST_HEAD(resources);
> >  	struct pci_bus *bus = NULL;
> >  	struct pci_sysdata *sd;
> > +	struct pci_root_sys_info si;
> >  	int node;
> >  #ifdef CONFIG_ACPI_NUMA
> >  	int pxm;
> > @@ -522,6 +523,8 @@ struct pci_bus * __devinit pci_acpi_scan
> >  	sd = &info->sd;
> >  	sd->domain = domain;
> >  	sd->node = node;
> > +	si.acpi_node.handle = device->handle;
> > +	si.sysdata = sd;
> >  	/*
> >  	 * Maybe the desired pci bus has been already scanned. In such case
> >  	 * it is unnecessary to scan the pci bus with the given domain,busnum.
> > @@ -553,7 +556,7 @@ struct pci_bus * __devinit pci_acpi_scan
> >  		if (!setup_mcfg_map(info, domain, (u8)root->secondary.start,
> >  				    (u8)root->secondary.end, root->mcfg_addr))
> >  			bus = pci_create_root_bus(NULL, busnum, &pci_root_ops,
> > -						  sd, &resources);
> > +						  &si, &resources);
> > 
> >  		if (bus) {
> >  			pci_scan_child_bus(bus);
> > Index: linux-pm/drivers/pci/probe.c
> > ================================================================
> > ===
> > --- linux-pm.orig/drivers/pci/probe.c
> > +++ linux-pm/drivers/pci/probe.c
> > @@ -1634,7 +1634,9 @@ unsigned int pci_scan_child_bus(struct p
> >  }
> > 
> >  struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
> > -		struct pci_ops *ops, void *sysdata, struct list_head *resources)
> > +				    struct pci_ops *ops,
> > +				    struct pci_root_sys_info *sys_info,
> > +				    struct list_head *resources)
> >  {
> >  	int error;
> >  	struct pci_host_bridge *bridge;
> > @@ -1650,7 +1652,7 @@ struct pci_bus *pci_create_root_bus(stru
> >  	if (!b)
> >  		return NULL;
> > 
> > -	b->sysdata = sysdata;
> > +	b->sysdata = sys_info ? sys_info->sysdata : NULL;
> >  	b->ops = ops;
> >  	b2 = pci_find_bus(pci_domain_nr(b), bus);
> >  	if (b2) {
> > @@ -1666,6 +1668,8 @@ struct pci_bus *pci_create_root_bus(stru
> >  	bridge->dev.parent = parent;
> >  	bridge->dev.release = pci_release_bus_bridge_dev;
> >  	dev_set_name(&bridge->dev, "pci%04x:%02x", pci_domain_nr(b), bus);
> > +	ACPI_HANDLE_SET(&bridge->dev,
> > +			sys_info ? sys_info->acpi_node.handle : NULL);
> >  	error = device_register(&bridge->dev);
> >  	if (error)
> >  		goto bridge_dev_reg_err;
> > @@ -1798,6 +1802,7 @@ struct pci_bus *pci_scan_root_bus(struct
> >  		struct pci_ops *ops, void *sysdata, struct list_head *resources)
> >  {
> >  	struct pci_host_bridge_window *window;
> > +	struct pci_root_sys_info si = { .sysdata = sysdata, };
> >  	bool found = false;
> >  	struct pci_bus *b;
> >  	int max;
> > @@ -1808,7 +1813,7 @@ struct pci_bus *pci_scan_root_bus(struct
> >  			break;
> >  		}
> > 
> > -	b = pci_create_root_bus(parent, bus, ops, sysdata, resources);
> > +	b = pci_create_root_bus(parent, bus, ops, &si, resources);
> >  	if (!b)
> >  		return NULL;
> > 
> > @@ -1833,13 +1838,14 @@ EXPORT_SYMBOL(pci_scan_root_bus);
> >  struct pci_bus *pci_scan_bus_parented(struct device *parent,
> >  		int bus, struct pci_ops *ops, void *sysdata)
> >  {
> > +	struct pci_root_sys_info si = { .sysdata = sysdata, };
> >  	LIST_HEAD(resources);
> >  	struct pci_bus *b;
> > 
> >  	pci_add_resource(&resources, &ioport_resource);
> >  	pci_add_resource(&resources, &iomem_resource);
> >  	pci_add_resource(&resources, &busn_resource);
> > -	b = pci_create_root_bus(parent, bus, ops, sysdata, &resources);
> > +	b = pci_create_root_bus(parent, bus, ops, &si, &resources);
> >  	if (b)
> >  		pci_scan_child_bus(b);
> >  	else
> > @@ -1851,13 +1857,14 @@ EXPORT_SYMBOL(pci_scan_bus_parented);
> >  struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops,
> >  					void *sysdata)
> >  {
> > +	struct pci_root_sys_info si = { .sysdata = sysdata, };
> >  	LIST_HEAD(resources);
> >  	struct pci_bus *b;
> > 
> >  	pci_add_resource(&resources, &ioport_resource);
> >  	pci_add_resource(&resources, &iomem_resource);
> >  	pci_add_resource(&resources, &busn_resource);
> > -	b = pci_create_root_bus(NULL, bus, ops, sysdata, &resources);
> > +	b = pci_create_root_bus(NULL, bus, ops, &si, &resources);
> >  	if (b) {
> >  		pci_scan_child_bus(b);
> >  		pci_bus_add_devices(b);
> > Index: linux-pm/include/linux/pci.h
> > ================================================================
> > ===
> > --- linux-pm.orig/include/linux/pci.h
> > +++ linux-pm/include/linux/pci.h
> > @@ -700,8 +700,15 @@ void pci_bus_add_devices(const struct pc
> >  struct pci_bus *pci_scan_bus_parented(struct device *parent, int bus,
> >  				      struct pci_ops *ops, void *sysdata);
> >  struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops, void *sysdata);
> > +
> > +struct pci_root_sys_info {
> > +	void *sysdata;
> > +	struct acpi_dev_node acpi_node;
> > +};
> > +
> >  struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
> > -				    struct pci_ops *ops, void *sysdata,
> > +				    struct pci_ops *ops,
> > +				    struct pci_root_sys_info *sys_info,
> >  				    struct list_head *resources);
> >  int pci_bus_insert_busn_res(struct pci_bus *b, int bus, int busmax);
> >  int pci_bus_update_busn_res_end(struct pci_bus *b, int busmax);
> > Index: linux-pm/arch/ia64/pci/pci.c
> > ================================================================
> > ===
> > --- linux-pm.orig/arch/ia64/pci/pci.c
> > +++ linux-pm/arch/ia64/pci/pci.c
> > @@ -333,6 +333,7 @@ pci_acpi_scan_root(struct acpi_pci_root
> >  	struct pci_controller *controller;
> >  	unsigned int windows = 0;
> >  	struct pci_root_info info;
> > +	struct pci_root_sys_info si;
> >  	struct pci_bus *pbus;
> >  	char *name;
> >  	int pxm;
> > @@ -378,7 +379,9 @@ pci_acpi_scan_root(struct acpi_pci_root
> >  	 * should handle the case here, but it appears that IA64 hasn't
> >  	 * such quirk. So we just ignore the case now.
> >  	 */
> > -	pbus = pci_create_root_bus(NULL, bus, &pci_root_ops, controller,
> > +	si.sysdata = controller;
> > +	si.acpi_node.handle = controller->acpi_handle;
> > +	pbus = pci_create_root_bus(NULL, bus, &pci_root_ops, &si,
> >  				   &info.resources);
> >  	if (!pbus) {
> >  		pci_free_resource_list(&info.resources);
> > Index: linux-pm/arch/powerpc/kernel/pci-common.c
> > ================================================================
> > ===
> > --- linux-pm.orig/arch/powerpc/kernel/pci-common.c
> > +++ linux-pm/arch/powerpc/kernel/pci-common.c
> > @@ -1644,6 +1644,7 @@ void __devinit pcibios_scan_phb(struct p
> >  	LIST_HEAD(resources);
> >  	struct pci_bus *bus;
> >  	struct device_node *node = hose->dn;
> > +	struct pci_root_sys_info si = { .sysdata = hose, };
> >  	int mode;
> > 
> >  	pr_debug("PCI: Scanning PHB %s\n", of_node_full_name(node));
> > @@ -1661,7 +1662,7 @@ void __devinit pcibios_scan_phb(struct p
> > 
> >  	/* Create an empty bus for the toplevel */
> >  	bus = pci_create_root_bus(hose->parent, hose->first_busno,
> > -				  hose->ops, hose, &resources);
> > +				  hose->ops, &si, &resources);
> >  	if (bus == NULL) {
> >  		pr_err("Failed to create bus for PCI domain %04x\n",
> >  			hose->global_number);
> > Index: linux-pm/arch/sparc/kernel/pci.c
> > ================================================================
> > ===
> > --- linux-pm.orig/arch/sparc/kernel/pci.c
> > +++ linux-pm/arch/sparc/kernel/pci.c
> > @@ -590,6 +590,7 @@ struct pci_bus * __devinit pci_scan_one_
> >  {
> >  	LIST_HEAD(resources);
> >  	struct device_node *node = pbm->op->dev.of_node;
> > +	struct pci_root_sys_info si = { .sysdata = pbm, };
> >  	struct pci_bus *bus;
> > 
> >  	printk("PCI: Scanning PBM %s\n", node->full_name);
> > @@ -603,7 +604,7 @@ struct pci_bus * __devinit pci_scan_one_
> >  	pbm->busn.flags	= IORESOURCE_BUS;
> >  	pci_add_resource(&resources, &pbm->busn);
> >  	bus = pci_create_root_bus(parent, pbm->pci_first_busno, pbm->pci_ops,
> > -				  pbm, &resources);
> > +				  &si, &resources);
> >  	if (!bus) {
> >  		printk(KERN_ERR "Failed to create bus for %s\n",
> >  		       node->full_name);
> > Index: linux-pm/drivers/pci/pci-acpi.c
> > ================================================================
> > ===
> > --- linux-pm.orig/drivers/pci/pci-acpi.c
> > +++ linux-pm/drivers/pci/pci-acpi.c
> > @@ -303,28 +303,9 @@ static int acpi_pci_find_device(struct d
> >  	return 0;
> >  }
> > 
> > -static int acpi_pci_find_root_bridge(struct device *dev, acpi_handle *handle)
> > -{
> > -	int num;
> > -	unsigned int seg, bus;
> > -
> > -	/*
> > -	 * The string should be the same as root bridge's name
> > -	 * Please look at 'pci_scan_bus_parented'
> > -	 */
> > -	num = sscanf(dev_name(dev), "pci%04x:%02x", &seg, &bus);
> > -	if (num != 2)
> > -		return -ENODEV;
> > -	*handle = acpi_get_pci_rootbridge_handle(seg, bus);
> > -	if (!*handle)
> > -		return -ENODEV;
> > -	return 0;
> > -}
> > -
> >  static struct acpi_bus_type acpi_pci_bus = {
> >  	.bus = &pci_bus_type,
> >  	.find_device = acpi_pci_find_device,
> > -	.find_bridge = acpi_pci_find_root_bridge,
> >  };
> > 
> >  static int __init acpi_pci_init(void)
> > Index: linux-pm/drivers/acpi/pci_root.c
> > ================================================================
> > ===
> > --- linux-pm.orig/drivers/acpi/pci_root.c
> > +++ linux-pm/drivers/acpi/pci_root.c
> > @@ -107,24 +107,6 @@ void acpi_pci_unregister_driver(struct a
> >  }
> >  EXPORT_SYMBOL(acpi_pci_unregister_driver);
> > 
> > -acpi_handle acpi_get_pci_rootbridge_handle(unsigned int seg, unsigned int
> > bus)
> > -{
> > -	struct acpi_pci_root *root;
> > -	acpi_handle handle = NULL;
> > -
> > -	mutex_lock(&acpi_pci_root_lock);
> > -	list_for_each_entry(root, &acpi_pci_roots, node)
> > -		if ((root->segment == (u16) seg) &&
> > -		    (root->secondary.start == (u16) bus)) {
> > -			handle = root->device->handle;
> > -			break;
> > -		}
> > -	mutex_unlock(&acpi_pci_root_lock);
> > -	return handle;
> > -}
> > -
> > -EXPORT_SYMBOL_GPL(acpi_get_pci_rootbridge_handle);
> > -
> >  /**
> >   * acpi_is_root_bridge - determine whether an ACPI CA node is a PCI root
> > bridge
> >   * @handle - the ACPI CA node in question.
> > Index: linux-pm/include/acpi/acpi_bus.h
> > ================================================================
> > ===
> > --- linux-pm.orig/include/acpi/acpi_bus.h
> > +++ linux-pm/include/acpi/acpi_bus.h
> > @@ -443,7 +443,6 @@ struct acpi_pci_root {
> >  /* helper */
> >  acpi_handle acpi_get_child(acpi_handle, u64);
> >  int acpi_is_root_bridge(acpi_handle);
> > -acpi_handle acpi_get_pci_rootbridge_handle(unsigned int, unsigned int);
> >  struct acpi_pci_root *acpi_pci_find_root(acpi_handle handle);
> >  #define DEVICE_ACPI_HANDLE(dev) ((acpi_handle)ACPI_HANDLE(dev))
> > 
> > Index: linux-pm/arch/s390/pci/pci.c
> > ================================================================
> > ===
> > --- linux-pm.orig/arch/s390/pci/pci.c
> > +++ linux-pm/arch/s390/pci/pci.c
> > @@ -852,6 +852,7 @@ static void zpci_free_iomap(struct zpci_
> > 
> >  static int zpci_create_device_bus(struct zpci_dev *zdev)
> >  {
> > +	struct pci_root_sys_info si = { .sysdata = zdev, };
> >  	struct resource *res;
> >  	LIST_HEAD(resources);
> >  	int i;
> > @@ -888,7 +889,7 @@ static int zpci_create_device_bus(struct
> >  	}
> > 
> >  	zdev->bus = pci_create_root_bus(NULL, ZPCI_BUS_NR, &pci_root_ops,
> > -					zdev, &resources);
> > +					&si, &resources);
> >  	if (!zdev->bus)
> >  		return -EIO;
> > 
> > 
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
> > the body of a message to majordomo@vger.kernel.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
Bjorn Helgaas Dec. 20, 2012, 9:13 p.m. UTC | #3
[+cc linux-pci, Myron]

On Mon, Dec 17, 2012 at 4:30 PM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
>
> The ACPI handles of PCI root bridges need to be known to
> acpi_bind_one(), so that it can create the appropriate
> "firmware_node" and "physical_node" files for them, but currently
> the way it gets to know those handles is not exactly straightforward
> (to put it lightly).
>
> This is how it works, roughly:
>
>   1. acpi_bus_scan() finds the handle of a PCI root bridge,
>      creates a struct acpi_device object for it and passes that
>      object to acpi_pci_root_add().
>
>   2. acpi_pci_root_add() creates a struct acpi_pci_root object,
>      populates its "device" field with its argument's address
>      (device->handle is the ACPI handle found in step 1).
>
>   3. The struct acpi_pci_root object created in step 2 is passed
>      to pci_acpi_scan_root() and used to get resources that are
>      passed to pci_create_root_bus().
>
>   4. pci_create_root_bus() creates a struct pci_host_bridge object
>      and passes its "dev" member to device_register().
>
>   5. platform_notify(), which for systems with ACPI is set to
>      acpi_platform_notify(), is called.
>
> So far, so good.  Now it starts to be "interesting".
>
>   6. acpi_find_bridge_device() is used to find the ACPI handle of
>      the given device (which is the PCI root bridge) and executes
>      acpi_pci_find_root_bridge(), among other things, for the
>      given device object.
>
>   7. acpi_pci_find_root_bridge() uses the name (sic!) of the given
>      device object to extract the segment and bus numbers of the PCI
>      root bridge and passes them to acpi_get_pci_rootbridge_handle().
>
>   8. acpi_get_pci_rootbridge_handle() browses the list of ACPI PCI
>      root bridges and finds the one that matches the given segment
>      and bus numbers.  Its handle is then used to initialize the
>      ACPI handle of the PCI root bridge's device object by
>      acpi_bind_one().  However, this is *exactly* the ACPI handle we
>      started with in step 1.
>
> Needless to say, this is quite embarassing, but it may be avoided
> thanks to commit f3fd0c8 (ACPI: Allow ACPI handles of devices to be
> initialized in advance), which makes it possible to initialize the
> ACPI handle of a device before passing it to device_register().

This was a mess.  Thanks for cleaning it up.

> Accordingly, make pci_acpi_scan_root() pass the root bridge's ACPI
> handle to pci_create_root_bus() and make the latter set the ACPI
> handle in its struct pci_host_bridge object's "dev" member before
> passing it to device_register(), so that steps 6-8 above aren't
> necessary any more.
>
> To implement that, I decided to repurpose the 4th argument of
> pci_create_root_bus(), because that allowed me to avoid defining
> additional callbacks or similar things and didn't seem to impact
> architectures without ACPI substantially.
>
> All architectures using pci_create_root_bus() directly are updated
> as needed, but only x86 and ia64 are affected as far as the behavior
> is concerned (no one else uses ACPI).  There should be no changes in
> behavior resulting from this on the other architectures.

I'd like to converge all architectures on a single higher-level
interface, pci_scan_root_bus(), then deprecate and remove
pci_create_root_bus(), pci_scan_bus_parented(), and pci_scan_bus().
You're changing the underlying pci_create_root_bus(), but not the
higher-level interfaces that use it, which will make converging a bit
harder.

Here's an alternate implementation strategy; see what you think:

- Add "struct acpi_dev_node acpi_node" to struct pci_sysdata (x86) and
struct pci_controller (ia64).  These are the only two arches that use
ACPI.

- Add an empty generic (weak) pcibios_create_root_ bus().

- Add pcibios_create_root_bus() for x86 and ia64 that does the
ACPI_HANDLE_SET().

It does add a pcibios callback, which you were trying to avoid, but it
does have the advantages that all the higher-level interfaces that use
pci_create_root_bus() will keep working and only the ACPI arches have
the acpi_dev_node member and associated code.

> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> Acked-by: Yinghai Lu <yinghai@kernel.org>
> Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Acked-by: H. Peter Anvin <hpa@zytor.com>
> ---
>
> Peter Anvin pointed out to me that it's better to make it clear in the
> changelog what the patch actually does versus what might be left as future
> work, so here's another update with a slightly modified (and hopefully better)
> changelog.  The patch itself hasn't been changed.
>
> Thanks,
> Rafael
>
> ---
>  arch/ia64/pci/pci.c              |    5 ++++-
>  arch/powerpc/kernel/pci-common.c |    3 ++-
>  arch/s390/pci/pci.c              |    3 ++-
>  arch/sparc/kernel/pci.c          |    3 ++-
>  arch/x86/pci/acpi.c              |    5 ++++-
>  drivers/acpi/pci_root.c          |   18 ------------------
>  drivers/pci/pci-acpi.c           |   19 -------------------
>  drivers/pci/probe.c              |   17 ++++++++++++-----
>  include/acpi/acpi_bus.h          |    1 -
>  include/linux/pci.h              |    9 ++++++++-
>  10 files changed, 34 insertions(+), 49 deletions(-)
>
> Index: linux-pm/arch/x86/pci/acpi.c
> ===================================================================
> --- linux-pm.orig/arch/x86/pci/acpi.c
> +++ linux-pm/arch/x86/pci/acpi.c
> @@ -483,6 +483,7 @@ struct pci_bus * __devinit pci_acpi_scan
>         LIST_HEAD(resources);
>         struct pci_bus *bus = NULL;
>         struct pci_sysdata *sd;
> +       struct pci_root_sys_info si;
>         int node;
>  #ifdef CONFIG_ACPI_NUMA
>         int pxm;
> @@ -522,6 +523,8 @@ struct pci_bus * __devinit pci_acpi_scan
>         sd = &info->sd;
>         sd->domain = domain;
>         sd->node = node;
> +       si.acpi_node.handle = device->handle;
> +       si.sysdata = sd;
>         /*
>          * Maybe the desired pci bus has been already scanned. In such case
>          * it is unnecessary to scan the pci bus with the given domain,busnum.
> @@ -553,7 +556,7 @@ struct pci_bus * __devinit pci_acpi_scan
>                 if (!setup_mcfg_map(info, domain, (u8)root->secondary.start,
>                                     (u8)root->secondary.end, root->mcfg_addr))
>                         bus = pci_create_root_bus(NULL, busnum, &pci_root_ops,
> -                                                 sd, &resources);
> +                                                 &si, &resources);
>
>                 if (bus) {
>                         pci_scan_child_bus(bus);
> Index: linux-pm/drivers/pci/probe.c
> ===================================================================
> --- linux-pm.orig/drivers/pci/probe.c
> +++ linux-pm/drivers/pci/probe.c
> @@ -1634,7 +1634,9 @@ unsigned int pci_scan_child_bus(struct p
>  }
>
>  struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
> -               struct pci_ops *ops, void *sysdata, struct list_head *resources)
> +                                   struct pci_ops *ops,
> +                                   struct pci_root_sys_info *sys_info,
> +                                   struct list_head *resources)
>  {
>         int error;
>         struct pci_host_bridge *bridge;
> @@ -1650,7 +1652,7 @@ struct pci_bus *pci_create_root_bus(stru
>         if (!b)
>                 return NULL;
>
> -       b->sysdata = sysdata;
> +       b->sysdata = sys_info ? sys_info->sysdata : NULL;
>         b->ops = ops;
>         b2 = pci_find_bus(pci_domain_nr(b), bus);
>         if (b2) {
> @@ -1666,6 +1668,8 @@ struct pci_bus *pci_create_root_bus(stru
>         bridge->dev.parent = parent;
>         bridge->dev.release = pci_release_bus_bridge_dev;
>         dev_set_name(&bridge->dev, "pci%04x:%02x", pci_domain_nr(b), bus);
> +       ACPI_HANDLE_SET(&bridge->dev,
> +                       sys_info ? sys_info->acpi_node.handle : NULL);
>         error = device_register(&bridge->dev);
>         if (error)
>                 goto bridge_dev_reg_err;
> @@ -1798,6 +1802,7 @@ struct pci_bus *pci_scan_root_bus(struct
>                 struct pci_ops *ops, void *sysdata, struct list_head *resources)
>  {
>         struct pci_host_bridge_window *window;
> +       struct pci_root_sys_info si = { .sysdata = sysdata, };
>         bool found = false;
>         struct pci_bus *b;
>         int max;
> @@ -1808,7 +1813,7 @@ struct pci_bus *pci_scan_root_bus(struct
>                         break;
>                 }
>
> -       b = pci_create_root_bus(parent, bus, ops, sysdata, resources);
> +       b = pci_create_root_bus(parent, bus, ops, &si, resources);
>         if (!b)
>                 return NULL;
>
> @@ -1833,13 +1838,14 @@ EXPORT_SYMBOL(pci_scan_root_bus);
>  struct pci_bus *pci_scan_bus_parented(struct device *parent,
>                 int bus, struct pci_ops *ops, void *sysdata)
>  {
> +       struct pci_root_sys_info si = { .sysdata = sysdata, };
>         LIST_HEAD(resources);
>         struct pci_bus *b;
>
>         pci_add_resource(&resources, &ioport_resource);
>         pci_add_resource(&resources, &iomem_resource);
>         pci_add_resource(&resources, &busn_resource);
> -       b = pci_create_root_bus(parent, bus, ops, sysdata, &resources);
> +       b = pci_create_root_bus(parent, bus, ops, &si, &resources);
>         if (b)
>                 pci_scan_child_bus(b);
>         else
> @@ -1851,13 +1857,14 @@ EXPORT_SYMBOL(pci_scan_bus_parented);
>  struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops,
>                                         void *sysdata)
>  {
> +       struct pci_root_sys_info si = { .sysdata = sysdata, };
>         LIST_HEAD(resources);
>         struct pci_bus *b;
>
>         pci_add_resource(&resources, &ioport_resource);
>         pci_add_resource(&resources, &iomem_resource);
>         pci_add_resource(&resources, &busn_resource);
> -       b = pci_create_root_bus(NULL, bus, ops, sysdata, &resources);
> +       b = pci_create_root_bus(NULL, bus, ops, &si, &resources);
>         if (b) {
>                 pci_scan_child_bus(b);
>                 pci_bus_add_devices(b);
> Index: linux-pm/include/linux/pci.h
> ===================================================================
> --- linux-pm.orig/include/linux/pci.h
> +++ linux-pm/include/linux/pci.h
> @@ -700,8 +700,15 @@ void pci_bus_add_devices(const struct pc
>  struct pci_bus *pci_scan_bus_parented(struct device *parent, int bus,
>                                       struct pci_ops *ops, void *sysdata);
>  struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops, void *sysdata);
> +
> +struct pci_root_sys_info {
> +       void *sysdata;
> +       struct acpi_dev_node acpi_node;
> +};
> +
>  struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
> -                                   struct pci_ops *ops, void *sysdata,
> +                                   struct pci_ops *ops,
> +                                   struct pci_root_sys_info *sys_info,
>                                     struct list_head *resources);
>  int pci_bus_insert_busn_res(struct pci_bus *b, int bus, int busmax);
>  int pci_bus_update_busn_res_end(struct pci_bus *b, int busmax);
> Index: linux-pm/arch/ia64/pci/pci.c
> ===================================================================
> --- linux-pm.orig/arch/ia64/pci/pci.c
> +++ linux-pm/arch/ia64/pci/pci.c
> @@ -333,6 +333,7 @@ pci_acpi_scan_root(struct acpi_pci_root
>         struct pci_controller *controller;
>         unsigned int windows = 0;
>         struct pci_root_info info;
> +       struct pci_root_sys_info si;
>         struct pci_bus *pbus;
>         char *name;
>         int pxm;
> @@ -378,7 +379,9 @@ pci_acpi_scan_root(struct acpi_pci_root
>          * should handle the case here, but it appears that IA64 hasn't
>          * such quirk. So we just ignore the case now.
>          */
> -       pbus = pci_create_root_bus(NULL, bus, &pci_root_ops, controller,
> +       si.sysdata = controller;
> +       si.acpi_node.handle = controller->acpi_handle;
> +       pbus = pci_create_root_bus(NULL, bus, &pci_root_ops, &si,
>                                    &info.resources);
>         if (!pbus) {
>                 pci_free_resource_list(&info.resources);
> Index: linux-pm/arch/powerpc/kernel/pci-common.c
> ===================================================================
> --- linux-pm.orig/arch/powerpc/kernel/pci-common.c
> +++ linux-pm/arch/powerpc/kernel/pci-common.c
> @@ -1644,6 +1644,7 @@ void __devinit pcibios_scan_phb(struct p
>         LIST_HEAD(resources);
>         struct pci_bus *bus;
>         struct device_node *node = hose->dn;
> +       struct pci_root_sys_info si = { .sysdata = hose, };
>         int mode;
>
>         pr_debug("PCI: Scanning PHB %s\n", of_node_full_name(node));
> @@ -1661,7 +1662,7 @@ void __devinit pcibios_scan_phb(struct p
>
>         /* Create an empty bus for the toplevel */
>         bus = pci_create_root_bus(hose->parent, hose->first_busno,
> -                                 hose->ops, hose, &resources);
> +                                 hose->ops, &si, &resources);
>         if (bus == NULL) {
>                 pr_err("Failed to create bus for PCI domain %04x\n",
>                         hose->global_number);
> Index: linux-pm/arch/sparc/kernel/pci.c
> ===================================================================
> --- linux-pm.orig/arch/sparc/kernel/pci.c
> +++ linux-pm/arch/sparc/kernel/pci.c
> @@ -590,6 +590,7 @@ struct pci_bus * __devinit pci_scan_one_
>  {
>         LIST_HEAD(resources);
>         struct device_node *node = pbm->op->dev.of_node;
> +       struct pci_root_sys_info si = { .sysdata = pbm, };
>         struct pci_bus *bus;
>
>         printk("PCI: Scanning PBM %s\n", node->full_name);
> @@ -603,7 +604,7 @@ struct pci_bus * __devinit pci_scan_one_
>         pbm->busn.flags = IORESOURCE_BUS;
>         pci_add_resource(&resources, &pbm->busn);
>         bus = pci_create_root_bus(parent, pbm->pci_first_busno, pbm->pci_ops,
> -                                 pbm, &resources);
> +                                 &si, &resources);
>         if (!bus) {
>                 printk(KERN_ERR "Failed to create bus for %s\n",
>                        node->full_name);
> Index: linux-pm/drivers/pci/pci-acpi.c
> ===================================================================
> --- linux-pm.orig/drivers/pci/pci-acpi.c
> +++ linux-pm/drivers/pci/pci-acpi.c
> @@ -303,28 +303,9 @@ static int acpi_pci_find_device(struct d
>         return 0;
>  }
>
> -static int acpi_pci_find_root_bridge(struct device *dev, acpi_handle *handle)
> -{
> -       int num;
> -       unsigned int seg, bus;
> -
> -       /*
> -        * The string should be the same as root bridge's name
> -        * Please look at 'pci_scan_bus_parented'
> -        */
> -       num = sscanf(dev_name(dev), "pci%04x:%02x", &seg, &bus);
> -       if (num != 2)
> -               return -ENODEV;
> -       *handle = acpi_get_pci_rootbridge_handle(seg, bus);
> -       if (!*handle)
> -               return -ENODEV;
> -       return 0;
> -}
> -
>  static struct acpi_bus_type acpi_pci_bus = {
>         .bus = &pci_bus_type,
>         .find_device = acpi_pci_find_device,
> -       .find_bridge = acpi_pci_find_root_bridge,
>  };
>
>  static int __init acpi_pci_init(void)
> Index: linux-pm/drivers/acpi/pci_root.c
> ===================================================================
> --- linux-pm.orig/drivers/acpi/pci_root.c
> +++ linux-pm/drivers/acpi/pci_root.c
> @@ -107,24 +107,6 @@ void acpi_pci_unregister_driver(struct a
>  }
>  EXPORT_SYMBOL(acpi_pci_unregister_driver);
>
> -acpi_handle acpi_get_pci_rootbridge_handle(unsigned int seg, unsigned int bus)
> -{
> -       struct acpi_pci_root *root;
> -       acpi_handle handle = NULL;
> -
> -       mutex_lock(&acpi_pci_root_lock);
> -       list_for_each_entry(root, &acpi_pci_roots, node)
> -               if ((root->segment == (u16) seg) &&
> -                   (root->secondary.start == (u16) bus)) {
> -                       handle = root->device->handle;
> -                       break;
> -               }
> -       mutex_unlock(&acpi_pci_root_lock);
> -       return handle;
> -}
> -
> -EXPORT_SYMBOL_GPL(acpi_get_pci_rootbridge_handle);
> -
>  /**
>   * acpi_is_root_bridge - determine whether an ACPI CA node is a PCI root bridge
>   * @handle - the ACPI CA node in question.
> Index: linux-pm/include/acpi/acpi_bus.h
> ===================================================================
> --- linux-pm.orig/include/acpi/acpi_bus.h
> +++ linux-pm/include/acpi/acpi_bus.h
> @@ -443,7 +443,6 @@ struct acpi_pci_root {
>  /* helper */
>  acpi_handle acpi_get_child(acpi_handle, u64);
>  int acpi_is_root_bridge(acpi_handle);
> -acpi_handle acpi_get_pci_rootbridge_handle(unsigned int, unsigned int);
>  struct acpi_pci_root *acpi_pci_find_root(acpi_handle handle);
>  #define DEVICE_ACPI_HANDLE(dev) ((acpi_handle)ACPI_HANDLE(dev))
>
> Index: linux-pm/arch/s390/pci/pci.c
> ===================================================================
> --- linux-pm.orig/arch/s390/pci/pci.c
> +++ linux-pm/arch/s390/pci/pci.c
> @@ -852,6 +852,7 @@ static void zpci_free_iomap(struct zpci_
>
>  static int zpci_create_device_bus(struct zpci_dev *zdev)
>  {
> +       struct pci_root_sys_info si = { .sysdata = zdev, };
>         struct resource *res;
>         LIST_HEAD(resources);
>         int i;
> @@ -888,7 +889,7 @@ static int zpci_create_device_bus(struct
>         }
>
>         zdev->bus = pci_create_root_bus(NULL, ZPCI_BUS_NR, &pci_root_ops,
> -                                       zdev, &resources);
> +                                       &si, &resources);
>         if (!zdev->bus)
>                 return -EIO;
>
>
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
H. Peter Anvin Dec. 20, 2012, 9:19 p.m. UTC | #4
On 12/20/2012 01:13 PM, Bjorn Helgaas wrote:
> 
> - Add "struct acpi_dev_node acpi_node" to struct pci_sysdata (x86) and
> struct pci_controller (ia64).  These are the only two arches that use
> ACPI.
> 

Currently.  There will be ARM platforms with ACPI soon, if there aren't
already.

	-hpa


--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Rafael Wysocki Dec. 20, 2012, 10:56 p.m. UTC | #5
On Thursday, December 20, 2012 02:13:15 PM Bjorn Helgaas wrote:
> [+cc linux-pci, Myron]
> 
> On Mon, Dec 17, 2012 at 4:30 PM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> > From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> >
> > The ACPI handles of PCI root bridges need to be known to
> > acpi_bind_one(), so that it can create the appropriate
> > "firmware_node" and "physical_node" files for them, but currently
> > the way it gets to know those handles is not exactly straightforward
> > (to put it lightly).
> >
> > This is how it works, roughly:
> >
> >   1. acpi_bus_scan() finds the handle of a PCI root bridge,
> >      creates a struct acpi_device object for it and passes that
> >      object to acpi_pci_root_add().
> >
> >   2. acpi_pci_root_add() creates a struct acpi_pci_root object,
> >      populates its "device" field with its argument's address
> >      (device->handle is the ACPI handle found in step 1).
> >
> >   3. The struct acpi_pci_root object created in step 2 is passed
> >      to pci_acpi_scan_root() and used to get resources that are
> >      passed to pci_create_root_bus().
> >
> >   4. pci_create_root_bus() creates a struct pci_host_bridge object
> >      and passes its "dev" member to device_register().
> >
> >   5. platform_notify(), which for systems with ACPI is set to
> >      acpi_platform_notify(), is called.
> >
> > So far, so good.  Now it starts to be "interesting".
> >
> >   6. acpi_find_bridge_device() is used to find the ACPI handle of
> >      the given device (which is the PCI root bridge) and executes
> >      acpi_pci_find_root_bridge(), among other things, for the
> >      given device object.
> >
> >   7. acpi_pci_find_root_bridge() uses the name (sic!) of the given
> >      device object to extract the segment and bus numbers of the PCI
> >      root bridge and passes them to acpi_get_pci_rootbridge_handle().
> >
> >   8. acpi_get_pci_rootbridge_handle() browses the list of ACPI PCI
> >      root bridges and finds the one that matches the given segment
> >      and bus numbers.  Its handle is then used to initialize the
> >      ACPI handle of the PCI root bridge's device object by
> >      acpi_bind_one().  However, this is *exactly* the ACPI handle we
> >      started with in step 1.
> >
> > Needless to say, this is quite embarassing, but it may be avoided
> > thanks to commit f3fd0c8 (ACPI: Allow ACPI handles of devices to be
> > initialized in advance), which makes it possible to initialize the
> > ACPI handle of a device before passing it to device_register().
> 
> This was a mess.  Thanks for cleaning it up.
> 
> > Accordingly, make pci_acpi_scan_root() pass the root bridge's ACPI
> > handle to pci_create_root_bus() and make the latter set the ACPI
> > handle in its struct pci_host_bridge object's "dev" member before
> > passing it to device_register(), so that steps 6-8 above aren't
> > necessary any more.
> >
> > To implement that, I decided to repurpose the 4th argument of
> > pci_create_root_bus(), because that allowed me to avoid defining
> > additional callbacks or similar things and didn't seem to impact
> > architectures without ACPI substantially.
> >
> > All architectures using pci_create_root_bus() directly are updated
> > as needed, but only x86 and ia64 are affected as far as the behavior
> > is concerned (no one else uses ACPI).  There should be no changes in
> > behavior resulting from this on the other architectures.
> 
> I'd like to converge all architectures on a single higher-level
> interface, pci_scan_root_bus(), then deprecate and remove
> pci_create_root_bus(), pci_scan_bus_parented(), and pci_scan_bus().
> You're changing the underlying pci_create_root_bus(), but not the
> higher-level interfaces that use it, which will make converging a bit
> harder.

Do you mean that pci_scan_root_bus() and friends should take a
struct pci_root_sys_info pointer rather than (void *) as an argument?
That's not too difficult to do on top of my patch.  I can do that if you
want me to, no problem.

> Here's an alternate implementation strategy; see what you think:
> 
> - Add "struct acpi_dev_node acpi_node" to struct pci_sysdata (x86) and
> struct pci_controller (ia64).  These are the only two arches that use
> ACPI.
> 
> - Add an empty generic (weak) pcibios_create_root_ bus().

Well, in my opinion things like that make following the code more difficult.
If you were new to the code in question and wanted to understand what it was
doing, you'd need to inspect all architectures to see (1) if they defined
pcibios_create_root_bus() and (2) what was in there if so.

> - Add pcibios_create_root_bus() for x86 and ia64 that does the
> ACPI_HANDLE_SET().
> 
> It does add a pcibios callback, which you were trying to avoid, but it
> does have the advantages that all the higher-level interfaces that use
> pci_create_root_bus() will keep working and only the ACPI arches have
> the acpi_dev_node member and associated code.

All of the things that use pci_create_root_bus() are still working with my
patch applied, hopefully. :-)

You seem to would like the headers of all the involved functions, including
pci_create_root_bus(), not to change.

Thanks,
Rafael
Bjorn Helgaas Dec. 21, 2012, 12:25 a.m. UTC | #6
On Thu, Dec 20, 2012 at 3:56 PM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> On Thursday, December 20, 2012 02:13:15 PM Bjorn Helgaas wrote:
>> [+cc linux-pci, Myron]
>>
>> On Mon, Dec 17, 2012 at 4:30 PM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
>> > From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
>> >
>> > The ACPI handles of PCI root bridges need to be known to
>> > acpi_bind_one(), so that it can create the appropriate
>> > "firmware_node" and "physical_node" files for them, but currently
>> > the way it gets to know those handles is not exactly straightforward
>> > (to put it lightly).
>> >
>> > This is how it works, roughly:
>> >
>> >   1. acpi_bus_scan() finds the handle of a PCI root bridge,
>> >      creates a struct acpi_device object for it and passes that
>> >      object to acpi_pci_root_add().
>> >
>> >   2. acpi_pci_root_add() creates a struct acpi_pci_root object,
>> >      populates its "device" field with its argument's address
>> >      (device->handle is the ACPI handle found in step 1).
>> >
>> >   3. The struct acpi_pci_root object created in step 2 is passed
>> >      to pci_acpi_scan_root() and used to get resources that are
>> >      passed to pci_create_root_bus().
>> >
>> >   4. pci_create_root_bus() creates a struct pci_host_bridge object
>> >      and passes its "dev" member to device_register().
>> >
>> >   5. platform_notify(), which for systems with ACPI is set to
>> >      acpi_platform_notify(), is called.
>> >
>> > So far, so good.  Now it starts to be "interesting".
>> >
>> >   6. acpi_find_bridge_device() is used to find the ACPI handle of
>> >      the given device (which is the PCI root bridge) and executes
>> >      acpi_pci_find_root_bridge(), among other things, for the
>> >      given device object.
>> >
>> >   7. acpi_pci_find_root_bridge() uses the name (sic!) of the given
>> >      device object to extract the segment and bus numbers of the PCI
>> >      root bridge and passes them to acpi_get_pci_rootbridge_handle().
>> >
>> >   8. acpi_get_pci_rootbridge_handle() browses the list of ACPI PCI
>> >      root bridges and finds the one that matches the given segment
>> >      and bus numbers.  Its handle is then used to initialize the
>> >      ACPI handle of the PCI root bridge's device object by
>> >      acpi_bind_one().  However, this is *exactly* the ACPI handle we
>> >      started with in step 1.
>> >
>> > Needless to say, this is quite embarassing, but it may be avoided
>> > thanks to commit f3fd0c8 (ACPI: Allow ACPI handles of devices to be
>> > initialized in advance), which makes it possible to initialize the
>> > ACPI handle of a device before passing it to device_register().
>>
>> This was a mess.  Thanks for cleaning it up.
>>
>> > Accordingly, make pci_acpi_scan_root() pass the root bridge's ACPI
>> > handle to pci_create_root_bus() and make the latter set the ACPI
>> > handle in its struct pci_host_bridge object's "dev" member before
>> > passing it to device_register(), so that steps 6-8 above aren't
>> > necessary any more.
>> >
>> > To implement that, I decided to repurpose the 4th argument of
>> > pci_create_root_bus(), because that allowed me to avoid defining
>> > additional callbacks or similar things and didn't seem to impact
>> > architectures without ACPI substantially.
>> >
>> > All architectures using pci_create_root_bus() directly are updated
>> > as needed, but only x86 and ia64 are affected as far as the behavior
>> > is concerned (no one else uses ACPI).  There should be no changes in
>> > behavior resulting from this on the other architectures.
>>
>> I'd like to converge all architectures on a single higher-level
>> interface, pci_scan_root_bus(), then deprecate and remove
>> pci_create_root_bus(), pci_scan_bus_parented(), and pci_scan_bus().
>> You're changing the underlying pci_create_root_bus(), but not the
>> higher-level interfaces that use it, which will make converging a bit
>> harder.
>
> Do you mean that pci_scan_root_bus() and friends should take a
> struct pci_root_sys_info pointer rather than (void *) as an argument?
> That's not too difficult to do on top of my patch.  I can do that if you
> want me to, no problem.
>
>> Here's an alternate implementation strategy; see what you think:
>>
>> - Add "struct acpi_dev_node acpi_node" to struct pci_sysdata (x86) and
>> struct pci_controller (ia64).  These are the only two arches that use
>> ACPI.
>>
>> - Add an empty generic (weak) pcibios_create_root_ bus().
>
> Well, in my opinion things like that make following the code more difficult.
> If you were new to the code in question and wanted to understand what it was
> doing, you'd need to inspect all architectures to see (1) if they defined
> pcibios_create_root_bus() and (2) what was in there if so.

It's a trade-off.  Your approach puts arch-specific ACPI code in the
generic PCI path.  I wouldn't like to see that extended to do
ACPI_HANDLE_SET(), PDC_HPA_SET(), OF_HANDLE_SET(), etc., all in the
generic code.  I guess I'm used to using "make ALLSOURCE_ARCHS=all
cscope" so I see all the architectures all the time, and I actually
like the fact that we have arch-specific hooks (we have too many right
now, but we do need some).

pcibios_create_root_bus() isn't really a good name; it only gives a
hint about where it's called.  Maybe
pcibios_host_bridge_platform_info() or something would make it more
readable.

>> - Add pcibios_create_root_bus() for x86 and ia64 that does the
>> ACPI_HANDLE_SET().
>>
>> It does add a pcibios callback, which you were trying to avoid, but it
>> does have the advantages that all the higher-level interfaces that use
>> pci_create_root_bus() will keep working and only the ACPI arches have
>> the acpi_dev_node member and associated code.
>
> All of the things that use pci_create_root_bus() are still working with my
> patch applied, hopefully. :-)

Well, sure, but only because no ACPI architectures use pci_scan_root_bus() yet.

> You seem to would like the headers of all the involved functions, including
> pci_create_root_bus(), not to change.

I think it's OK to change the pci_create_root_bus() signature because
it's not exported to modules.  But yes, I think it will be a problem
to change pci_scan_root_bus(), because it *is* exported.  So distros
won't be able to backport a change there unless you change the name.

Bjorn
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

Index: linux-pm/arch/x86/pci/acpi.c
===================================================================
--- linux-pm.orig/arch/x86/pci/acpi.c
+++ linux-pm/arch/x86/pci/acpi.c
@@ -483,6 +483,7 @@  struct pci_bus * __devinit pci_acpi_scan
 	LIST_HEAD(resources);
 	struct pci_bus *bus = NULL;
 	struct pci_sysdata *sd;
+	struct pci_root_sys_info si;
 	int node;
 #ifdef CONFIG_ACPI_NUMA
 	int pxm;
@@ -522,6 +523,8 @@  struct pci_bus * __devinit pci_acpi_scan
 	sd = &info->sd;
 	sd->domain = domain;
 	sd->node = node;
+	si.acpi_node.handle = device->handle;
+	si.sysdata = sd;
 	/*
 	 * Maybe the desired pci bus has been already scanned. In such case
 	 * it is unnecessary to scan the pci bus with the given domain,busnum.
@@ -553,7 +556,7 @@  struct pci_bus * __devinit pci_acpi_scan
 		if (!setup_mcfg_map(info, domain, (u8)root->secondary.start,
 				    (u8)root->secondary.end, root->mcfg_addr))
 			bus = pci_create_root_bus(NULL, busnum, &pci_root_ops,
-						  sd, &resources);
+						  &si, &resources);
 
 		if (bus) {
 			pci_scan_child_bus(bus);
Index: linux-pm/drivers/pci/probe.c
===================================================================
--- linux-pm.orig/drivers/pci/probe.c
+++ linux-pm/drivers/pci/probe.c
@@ -1634,7 +1634,9 @@  unsigned int pci_scan_child_bus(struct p
 }
 
 struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
-		struct pci_ops *ops, void *sysdata, struct list_head *resources)
+				    struct pci_ops *ops,
+				    struct pci_root_sys_info *sys_info,
+				    struct list_head *resources)
 {
 	int error;
 	struct pci_host_bridge *bridge;
@@ -1650,7 +1652,7 @@  struct pci_bus *pci_create_root_bus(stru
 	if (!b)
 		return NULL;
 
-	b->sysdata = sysdata;
+	b->sysdata = sys_info ? sys_info->sysdata : NULL;
 	b->ops = ops;
 	b2 = pci_find_bus(pci_domain_nr(b), bus);
 	if (b2) {
@@ -1666,6 +1668,8 @@  struct pci_bus *pci_create_root_bus(stru
 	bridge->dev.parent = parent;
 	bridge->dev.release = pci_release_bus_bridge_dev;
 	dev_set_name(&bridge->dev, "pci%04x:%02x", pci_domain_nr(b), bus);
+	ACPI_HANDLE_SET(&bridge->dev,
+			sys_info ? sys_info->acpi_node.handle : NULL);
 	error = device_register(&bridge->dev);
 	if (error)
 		goto bridge_dev_reg_err;
@@ -1798,6 +1802,7 @@  struct pci_bus *pci_scan_root_bus(struct
 		struct pci_ops *ops, void *sysdata, struct list_head *resources)
 {
 	struct pci_host_bridge_window *window;
+	struct pci_root_sys_info si = { .sysdata = sysdata, };
 	bool found = false;
 	struct pci_bus *b;
 	int max;
@@ -1808,7 +1813,7 @@  struct pci_bus *pci_scan_root_bus(struct
 			break;
 		}
 
-	b = pci_create_root_bus(parent, bus, ops, sysdata, resources);
+	b = pci_create_root_bus(parent, bus, ops, &si, resources);
 	if (!b)
 		return NULL;
 
@@ -1833,13 +1838,14 @@  EXPORT_SYMBOL(pci_scan_root_bus);
 struct pci_bus *pci_scan_bus_parented(struct device *parent,
 		int bus, struct pci_ops *ops, void *sysdata)
 {
+	struct pci_root_sys_info si = { .sysdata = sysdata, };
 	LIST_HEAD(resources);
 	struct pci_bus *b;
 
 	pci_add_resource(&resources, &ioport_resource);
 	pci_add_resource(&resources, &iomem_resource);
 	pci_add_resource(&resources, &busn_resource);
-	b = pci_create_root_bus(parent, bus, ops, sysdata, &resources);
+	b = pci_create_root_bus(parent, bus, ops, &si, &resources);
 	if (b)
 		pci_scan_child_bus(b);
 	else
@@ -1851,13 +1857,14 @@  EXPORT_SYMBOL(pci_scan_bus_parented);
 struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops,
 					void *sysdata)
 {
+	struct pci_root_sys_info si = { .sysdata = sysdata, };
 	LIST_HEAD(resources);
 	struct pci_bus *b;
 
 	pci_add_resource(&resources, &ioport_resource);
 	pci_add_resource(&resources, &iomem_resource);
 	pci_add_resource(&resources, &busn_resource);
-	b = pci_create_root_bus(NULL, bus, ops, sysdata, &resources);
+	b = pci_create_root_bus(NULL, bus, ops, &si, &resources);
 	if (b) {
 		pci_scan_child_bus(b);
 		pci_bus_add_devices(b);
Index: linux-pm/include/linux/pci.h
===================================================================
--- linux-pm.orig/include/linux/pci.h
+++ linux-pm/include/linux/pci.h
@@ -700,8 +700,15 @@  void pci_bus_add_devices(const struct pc
 struct pci_bus *pci_scan_bus_parented(struct device *parent, int bus,
 				      struct pci_ops *ops, void *sysdata);
 struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops, void *sysdata);
+
+struct pci_root_sys_info {
+	void *sysdata;
+	struct acpi_dev_node acpi_node;
+};
+
 struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
-				    struct pci_ops *ops, void *sysdata,
+				    struct pci_ops *ops,
+				    struct pci_root_sys_info *sys_info,
 				    struct list_head *resources);
 int pci_bus_insert_busn_res(struct pci_bus *b, int bus, int busmax);
 int pci_bus_update_busn_res_end(struct pci_bus *b, int busmax);
Index: linux-pm/arch/ia64/pci/pci.c
===================================================================
--- linux-pm.orig/arch/ia64/pci/pci.c
+++ linux-pm/arch/ia64/pci/pci.c
@@ -333,6 +333,7 @@  pci_acpi_scan_root(struct acpi_pci_root
 	struct pci_controller *controller;
 	unsigned int windows = 0;
 	struct pci_root_info info;
+	struct pci_root_sys_info si;
 	struct pci_bus *pbus;
 	char *name;
 	int pxm;
@@ -378,7 +379,9 @@  pci_acpi_scan_root(struct acpi_pci_root
 	 * should handle the case here, but it appears that IA64 hasn't
 	 * such quirk. So we just ignore the case now.
 	 */
-	pbus = pci_create_root_bus(NULL, bus, &pci_root_ops, controller,
+	si.sysdata = controller;
+	si.acpi_node.handle = controller->acpi_handle;
+	pbus = pci_create_root_bus(NULL, bus, &pci_root_ops, &si,
 				   &info.resources);
 	if (!pbus) {
 		pci_free_resource_list(&info.resources);
Index: linux-pm/arch/powerpc/kernel/pci-common.c
===================================================================
--- linux-pm.orig/arch/powerpc/kernel/pci-common.c
+++ linux-pm/arch/powerpc/kernel/pci-common.c
@@ -1644,6 +1644,7 @@  void __devinit pcibios_scan_phb(struct p
 	LIST_HEAD(resources);
 	struct pci_bus *bus;
 	struct device_node *node = hose->dn;
+	struct pci_root_sys_info si = { .sysdata = hose, };
 	int mode;
 
 	pr_debug("PCI: Scanning PHB %s\n", of_node_full_name(node));
@@ -1661,7 +1662,7 @@  void __devinit pcibios_scan_phb(struct p
 
 	/* Create an empty bus for the toplevel */
 	bus = pci_create_root_bus(hose->parent, hose->first_busno,
-				  hose->ops, hose, &resources);
+				  hose->ops, &si, &resources);
 	if (bus == NULL) {
 		pr_err("Failed to create bus for PCI domain %04x\n",
 			hose->global_number);
Index: linux-pm/arch/sparc/kernel/pci.c
===================================================================
--- linux-pm.orig/arch/sparc/kernel/pci.c
+++ linux-pm/arch/sparc/kernel/pci.c
@@ -590,6 +590,7 @@  struct pci_bus * __devinit pci_scan_one_
 {
 	LIST_HEAD(resources);
 	struct device_node *node = pbm->op->dev.of_node;
+	struct pci_root_sys_info si = { .sysdata = pbm, };
 	struct pci_bus *bus;
 
 	printk("PCI: Scanning PBM %s\n", node->full_name);
@@ -603,7 +604,7 @@  struct pci_bus * __devinit pci_scan_one_
 	pbm->busn.flags	= IORESOURCE_BUS;
 	pci_add_resource(&resources, &pbm->busn);
 	bus = pci_create_root_bus(parent, pbm->pci_first_busno, pbm->pci_ops,
-				  pbm, &resources);
+				  &si, &resources);
 	if (!bus) {
 		printk(KERN_ERR "Failed to create bus for %s\n",
 		       node->full_name);
Index: linux-pm/drivers/pci/pci-acpi.c
===================================================================
--- linux-pm.orig/drivers/pci/pci-acpi.c
+++ linux-pm/drivers/pci/pci-acpi.c
@@ -303,28 +303,9 @@  static int acpi_pci_find_device(struct d
 	return 0;
 }
 
-static int acpi_pci_find_root_bridge(struct device *dev, acpi_handle *handle)
-{
-	int num;
-	unsigned int seg, bus;
-
-	/*
-	 * The string should be the same as root bridge's name
-	 * Please look at 'pci_scan_bus_parented'
-	 */
-	num = sscanf(dev_name(dev), "pci%04x:%02x", &seg, &bus);
-	if (num != 2)
-		return -ENODEV;
-	*handle = acpi_get_pci_rootbridge_handle(seg, bus);
-	if (!*handle)
-		return -ENODEV;
-	return 0;
-}
-
 static struct acpi_bus_type acpi_pci_bus = {
 	.bus = &pci_bus_type,
 	.find_device = acpi_pci_find_device,
-	.find_bridge = acpi_pci_find_root_bridge,
 };
 
 static int __init acpi_pci_init(void)
Index: linux-pm/drivers/acpi/pci_root.c
===================================================================
--- linux-pm.orig/drivers/acpi/pci_root.c
+++ linux-pm/drivers/acpi/pci_root.c
@@ -107,24 +107,6 @@  void acpi_pci_unregister_driver(struct a
 }
 EXPORT_SYMBOL(acpi_pci_unregister_driver);
 
-acpi_handle acpi_get_pci_rootbridge_handle(unsigned int seg, unsigned int bus)
-{
-	struct acpi_pci_root *root;
-	acpi_handle handle = NULL;
-	
-	mutex_lock(&acpi_pci_root_lock);
-	list_for_each_entry(root, &acpi_pci_roots, node)
-		if ((root->segment == (u16) seg) &&
-		    (root->secondary.start == (u16) bus)) {
-			handle = root->device->handle;
-			break;
-		}
-	mutex_unlock(&acpi_pci_root_lock);
-	return handle;
-}
-
-EXPORT_SYMBOL_GPL(acpi_get_pci_rootbridge_handle);
-
 /**
  * acpi_is_root_bridge - determine whether an ACPI CA node is a PCI root bridge
  * @handle - the ACPI CA node in question.
Index: linux-pm/include/acpi/acpi_bus.h
===================================================================
--- linux-pm.orig/include/acpi/acpi_bus.h
+++ linux-pm/include/acpi/acpi_bus.h
@@ -443,7 +443,6 @@  struct acpi_pci_root {
 /* helper */
 acpi_handle acpi_get_child(acpi_handle, u64);
 int acpi_is_root_bridge(acpi_handle);
-acpi_handle acpi_get_pci_rootbridge_handle(unsigned int, unsigned int);
 struct acpi_pci_root *acpi_pci_find_root(acpi_handle handle);
 #define DEVICE_ACPI_HANDLE(dev) ((acpi_handle)ACPI_HANDLE(dev))
 
Index: linux-pm/arch/s390/pci/pci.c
===================================================================
--- linux-pm.orig/arch/s390/pci/pci.c
+++ linux-pm/arch/s390/pci/pci.c
@@ -852,6 +852,7 @@  static void zpci_free_iomap(struct zpci_
 
 static int zpci_create_device_bus(struct zpci_dev *zdev)
 {
+	struct pci_root_sys_info si = { .sysdata = zdev, };
 	struct resource *res;
 	LIST_HEAD(resources);
 	int i;
@@ -888,7 +889,7 @@  static int zpci_create_device_bus(struct
 	}
 
 	zdev->bus = pci_create_root_bus(NULL, ZPCI_BUS_NR, &pci_root_ops,
-					zdev, &resources);
+					&si, &resources);
 	if (!zdev->bus)
 		return -EIO;