diff mbox

[v10,1/6] drivers/platform/x86/p2sb: New Primary to Sideband bridge support driver for Intel SOC's

Message ID 1478768430-13422-2-git-send-email-jui.nee.tan@intel.com (mailing list archive)
State Superseded, archived
Delegated to: Andy Shevchenko
Headers show

Commit Message

Tan Jui Nee Nov. 10, 2016, 9 a.m. UTC
From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

There is already one and at least one more user coming which
require an access to Primary to Sideband bridge (P2SB) in order
to get IO or MMIO bar hidden by BIOS.
Create a driver to access P2SB for x86 devices.

Signed-off-by: Yong, Jonathan <jonathan.yong@intel.com>
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
Changes in V10:
	- Since P2SB is platform enablement driver and therefore should go into
	  drivers/platform/x86 (suggested by tglx).

Changes in V9:
	- No change

Changes in V8:
	- No change

Changes in V7:
	- EXPORT_SYMBOL_GPL() and MODULE_LICENSE("GPL v2") are used for new file
	  p2sb.c.

Changes in V6:
	- No change

Changes in V5:
	- No change

Changes in V4:
	- Move Kconfig option CONFIG_X86_INTEL_NON_ACPI from
	  [PATCH 2/3] x86/platform/p2sb: New Primary to Sideband bridge support driver for Intel SOC's
	  to
	  [PATCH 3/3] mfd: lpc_ich: Add support for Intel Apollo Lake GPIO pinctrl in non-ACPI system
	  since the config is used in latter patch.

Changes in V3:
	- No change

Changes in V2:
	- Add new config option CONFIG_X86_INTEL_NON_ACPI and "select PINCTRL"
	  to fix kbuildbot error

 arch/x86/include/asm/p2sb.h   | 27 ++++++++++++
 drivers/platform/x86/Kconfig  |  4 ++
 drivers/platform/x86/Makefile |  1 +
 drivers/platform/x86/p2sb.c   | 98 +++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 130 insertions(+)
 create mode 100644 arch/x86/include/asm/p2sb.h
 create mode 100644 drivers/platform/x86/p2sb.c

Comments

Andy Shevchenko Nov. 10, 2016, 4:07 p.m. UTC | #1
On Thu, 2016-11-10 at 17:00 +0800, Tan Jui Nee wrote:
> From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> 
> There is already one and at least one more user coming which
> require an access to Primary to Sideband bridge (P2SB) in order
> to get IO or MMIO bar hidden by BIOS.
> Create a driver to access P2SB for x86 devices.
> 
> Signed-off-by: Yong, Jonathan <jonathan.yong@intel.com>
> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>


> +int p2sb_bar(struct pci_dev *pdev, unsigned int devfn,
> +	struct resource *res)
> +{
> +	u32 base_addr;
> +	u64 base64_addr;
> +	unsigned long flags;
> +
> 

> +	if (!res)
> +		return -EINVAL;

I don't remember the details, one version was quite changed, so, I think
these lines are not needed anymore.

> +	/* Get IO or MMIO BAR */
> +	pci_bus_read_config_dword(pdev->bus, devfn, SBREG_BAR,
> &base_addr);
> +	if ((base_addr & PCI_BASE_ADDRESS_SPACE) ==
> PCI_BASE_ADDRESS_SPACE_IO) {
> +		flags = IORESOURCE_IO;
> +		base64_addr = base_addr & PCI_BASE_ADDRESS_IO_MASK;
> +	} else {
> +		flags = IORESOURCE_MEM;
> +		base64_addr = base_addr & PCI_BASE_ADDRESS_MEM_MASK;
> +		if (base_addr & PCI_BASE_ADDRESS_MEM_TYPE_64) {
> +			flags |= IORESOURCE_MEM_64;
> 

> +			pci_bus_read_config_dword(pdev->bus, devfn,
> +				SBREG_BAR + 4, &base_addr);

Fix indentation.

> +			base64_addr |= (u64)base_addr << 32;
> +		}
> +	}
> +
> +	/* Hide the P2SB device */
> +	pci_bus_write_config_byte(pdev->bus, devfn, SBREG_HIDE,
> 0x01);
> +
> +	spin_unlock(&p2sb_spinlock);
> +

> +	/* User provides prefilled resources */

Not anymore as far I as I can see. You just return here the result.

> +	res->start = (resource_size_t)base64_addr;
> +	res->flags = flags;
Tan Jui Nee Dec. 9, 2016, 7:50 a.m. UTC | #2
DQoNCj4gLS0tLS1PcmlnaW5hbCBNZXNzYWdlLS0tLS0NCj4gRnJvbTogbGludXgtZ3Bpby1vd25l
ckB2Z2VyLmtlcm5lbC5vcmcgW21haWx0bzpsaW51eC1ncGlvLQ0KPiBvd25lckB2Z2VyLmtlcm5l
bC5vcmddIE9uIEJlaGFsZiBPZiBBbmR5IFNoZXZjaGVua28NCj4gU2VudDogRnJpZGF5LCBOb3Zl
bWJlciAxMSwgMjAxNiAxMjowNyBBTQ0KPiBUbzogVGFuLCBKdWkgTmVlIDxqdWkubmVlLnRhbkBp
bnRlbC5jb20+OyBtaWthLndlc3RlcmJlcmdAbGludXguaW50ZWwuY29tOw0KPiBoZWlra2kua3Jv
Z2VydXNAbGludXguaW50ZWwuY29tOyB0Z2x4QGxpbnV0cm9uaXguZGU7IGR2aGFydEBpbmZyYWRl
YWQub3JnOw0KPiBtaW5nb0ByZWRoYXQuY29tOyBocGFAenl0b3IuY29tOyB4ODZAa2VybmVsLm9y
ZzsgcHR5c2VyQHhlcy1pbmMuY29tOw0KPiBsZWUuam9uZXNAbGluYXJvLm9yZzsgbGludXMud2Fs
bGVpakBsaW5hcm8ub3JnDQo+IENjOiBsaW51eC1ncGlvQHZnZXIua2VybmVsLm9yZzsgcGxhdGZv
cm0tZHJpdmVyLXg4NkB2Z2VyLmtlcm5lbC5vcmc7DQo+IGxpbnV4LWtlcm5lbEB2Z2VyLmtlcm5l
bC5vcmc7IFlvbmcsIEpvbmF0aGFuIDxqb25hdGhhbi55b25nQGludGVsLmNvbT47DQo+IFl1LCBP
bmcgSG9jayA8b25nLmhvY2sueXVAaW50ZWwuY29tPjsgTHVjaywgVG9ueSA8dG9ueS5sdWNrQGlu
dGVsLmNvbT47DQo+IFdhbiBNb2hhbWFkLCBXYW4gQWhtYWQgWmFpbmllIDx3YW4uYWhtYWQuemFp
bmllLndhbi5tb2hhbWFkQGludGVsLmNvbT47DQo+IFN1biwgWXVueWluZyA8eXVueWluZy5zdW5A
aW50ZWwuY29tPg0KPiBTdWJqZWN0OiBSZTogW1BBVENIIHYxMCAxLzZdIGRyaXZlcnMvcGxhdGZv
cm0veDg2L3Ayc2I6IE5ldyBQcmltYXJ5IHRvDQo+IFNpZGViYW5kIGJyaWRnZSBzdXBwb3J0IGRy
aXZlciBmb3IgSW50ZWwgU09DJ3MNCj4gDQo+IE9uIFRodSwgMjAxNi0xMS0xMCBhdCAxNzowMCAr
MDgwMCwgVGFuIEp1aSBOZWUgd3JvdGU6DQo+ID4gRnJvbTogQW5keSBTaGV2Y2hlbmtvIDxhbmRy
aXkuc2hldmNoZW5rb0BsaW51eC5pbnRlbC5jb20+DQo+ID4NCj4gPiBUaGVyZSBpcyBhbHJlYWR5
IG9uZSBhbmQgYXQgbGVhc3Qgb25lIG1vcmUgdXNlciBjb21pbmcgd2hpY2ggcmVxdWlyZQ0KPiA+
IGFuIGFjY2VzcyB0byBQcmltYXJ5IHRvIFNpZGViYW5kIGJyaWRnZSAoUDJTQikgaW4gb3JkZXIg
dG8gZ2V0IElPIG9yDQo+ID4gTU1JTyBiYXIgaGlkZGVuIGJ5IEJJT1MuDQo+ID4gQ3JlYXRlIGEg
ZHJpdmVyIHRvIGFjY2VzcyBQMlNCIGZvciB4ODYgZGV2aWNlcy4NCj4gPg0KPiA+IFNpZ25lZC1v
ZmYtYnk6IFlvbmcsIEpvbmF0aGFuIDxqb25hdGhhbi55b25nQGludGVsLmNvbT4NCj4gPiBTaWdu
ZWQtb2ZmLWJ5OiBBbmR5IFNoZXZjaGVua28gPGFuZHJpeS5zaGV2Y2hlbmtvQGxpbnV4LmludGVs
LmNvbT4NCj4gDQo+IA0KPiA+ICtpbnQgcDJzYl9iYXIoc3RydWN0IHBjaV9kZXYgKnBkZXYsIHVu
c2lnbmVkIGludCBkZXZmbiwNCj4gPiArCXN0cnVjdCByZXNvdXJjZSAqcmVzKQ0KPiA+ICt7DQo+
ID4gKwl1MzIgYmFzZV9hZGRyOw0KPiA+ICsJdTY0IGJhc2U2NF9hZGRyOw0KPiA+ICsJdW5zaWdu
ZWQgbG9uZyBmbGFnczsNCj4gPiArDQo+ID4NCj4gDQo+ID4gKwlpZiAoIXJlcykNCj4gPiArCQly
ZXR1cm4gLUVJTlZBTDsNCj4gDQo+IEkgZG9uJ3QgcmVtZW1iZXIgdGhlIGRldGFpbHMsIG9uZSB2
ZXJzaW9uIHdhcyBxdWl0ZSBjaGFuZ2VkLCBzbywgSSB0aGluaw0KPiB0aGVzZSBsaW5lcyBhcmUg
bm90IG5lZWRlZCBhbnltb3JlLg0KPiANCk5vdGVkLCB0aGVzZSBsaW5lcyB3aWxsIGJlIHJlbW92
ZWQgaW4gbmV4dCBwYXRjaCB2ZXJzaW9uICh2MTIpLg0KPiA+ICsJLyogR2V0IElPIG9yIE1NSU8g
QkFSICovDQo+ID4gKwlwY2lfYnVzX3JlYWRfY29uZmlnX2R3b3JkKHBkZXYtPmJ1cywgZGV2Zm4s
IFNCUkVHX0JBUiwNCj4gPiAmYmFzZV9hZGRyKTsNCj4gPiArCWlmICgoYmFzZV9hZGRyICYgUENJ
X0JBU0VfQUREUkVTU19TUEFDRSkgPT0NCj4gPiBQQ0lfQkFTRV9BRERSRVNTX1NQQUNFX0lPKSB7
DQo+ID4gKwkJZmxhZ3MgPSBJT1JFU09VUkNFX0lPOw0KPiA+ICsJCWJhc2U2NF9hZGRyID0gYmFz
ZV9hZGRyICYgUENJX0JBU0VfQUREUkVTU19JT19NQVNLOw0KPiA+ICsJfSBlbHNlIHsNCj4gPiAr
CQlmbGFncyA9IElPUkVTT1VSQ0VfTUVNOw0KPiA+ICsJCWJhc2U2NF9hZGRyID0gYmFzZV9hZGRy
ICYgUENJX0JBU0VfQUREUkVTU19NRU1fTUFTSzsNCj4gPiArCQlpZiAoYmFzZV9hZGRyICYgUENJ
X0JBU0VfQUREUkVTU19NRU1fVFlQRV82NCkgew0KPiA+ICsJCQlmbGFncyB8PSBJT1JFU09VUkNF
X01FTV82NDsNCj4gPg0KPiANCj4gPiArCQkJcGNpX2J1c19yZWFkX2NvbmZpZ19kd29yZChwZGV2
LT5idXMsIGRldmZuLA0KPiA+ICsJCQkJU0JSRUdfQkFSICsgNCwgJmJhc2VfYWRkcik7DQo+IA0K
PiBGaXggaW5kZW50YXRpb24uDQo+IA0KVGhhbmtzIGZvciBwb2ludGluZyB0aGF0IG91dC4gSSB3
aWxsIGZpeCB0aGF0IGluIG5leHQgcGF0Y2ggdmVyc2lvbiAodjEyKS4gDQo+ID4gKwkJCWJhc2U2
NF9hZGRyIHw9ICh1NjQpYmFzZV9hZGRyIDw8IDMyOw0KPiA+ICsJCX0NCj4gPiArCX0NCj4gPiAr
DQo+ID4gKwkvKiBIaWRlIHRoZSBQMlNCIGRldmljZSAqLw0KPiA+ICsJcGNpX2J1c193cml0ZV9j
b25maWdfYnl0ZShwZGV2LT5idXMsIGRldmZuLCBTQlJFR19ISURFLA0KPiA+IDB4MDEpOw0KPiA+
ICsNCj4gPiArCXNwaW5fdW5sb2NrKCZwMnNiX3NwaW5sb2NrKTsNCj4gPiArDQo+IA0KPiA+ICsJ
LyogVXNlciBwcm92aWRlcyBwcmVmaWxsZWQgcmVzb3VyY2VzICovDQo+IA0KPiBOb3QgYW55bW9y
ZSBhcyBmYXIgSSBhcyBJIGNhbiBzZWUuIFlvdSBqdXN0IHJldHVybiBoZXJlIHRoZSByZXN1bHQu
DQo+IA0KQ3VycmVudCB2ZXJzaW9uIGlzIHJldHVybmluZyBzdGF0dXMgb2YgcDJzYl9iYXIgZnVu
Y3Rpb24sIGkuZS4sIDAgb24gc3VjY2VzcyBvciBhcHByb3ByaWF0ZSBlcnJubyB2YWx1ZSBvbiBl
cnJvci4gUGVyaGFwcyB5b3UgY291bGQgc2hhcmUgdGhlIHJlYXNvbiBvZiByZXR1cm4gdGhlIHJl
c3VsdCBpbnN0ZWFkIG9mIHN0YXR1cy4gDQo+ID4gKwlyZXMtPnN0YXJ0ID0gKHJlc291cmNlX3Np
emVfdCliYXNlNjRfYWRkcjsNCj4gPiArCXJlcy0+ZmxhZ3MgPSBmbGFnczsNCj4gDQo+IC0tDQo+
IEFuZHkgU2hldmNoZW5rbyA8YW5kcml5LnNoZXZjaGVua29AbGludXguaW50ZWwuY29tPg0KPiBJ
bnRlbCBGaW5sYW5kIE95DQo+IC0tDQo+IFRvIHVuc3Vic2NyaWJlIGZyb20gdGhpcyBsaXN0OiBz
ZW5kIHRoZSBsaW5lICJ1bnN1YnNjcmliZSBsaW51eC1ncGlvIiBpbg0KPiB0aGUgYm9keSBvZiBh
IG1lc3NhZ2UgdG8gbWFqb3Jkb21vQHZnZXIua2VybmVsLm9yZyBNb3JlIG1ham9yZG9tbyBpbmZv
IGF0DQo+IGh0dHA6Ly92Z2VyLmtlcm5lbC5vcmcvbWFqb3Jkb21vLWluZm8uaHRtbA0K
--
To unsubscribe from this list: send the line "unsubscribe platform-driver-x86" 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

diff --git a/arch/x86/include/asm/p2sb.h b/arch/x86/include/asm/p2sb.h
new file mode 100644
index 0000000..686e07b
--- /dev/null
+++ b/arch/x86/include/asm/p2sb.h
@@ -0,0 +1,27 @@ 
+/*
+ * Primary to Sideband bridge (P2SB) access support
+ */
+
+#ifndef P2SB_SYMS_H
+#define P2SB_SYMS_H
+
+#include <linux/ioport.h>
+#include <linux/pci.h>
+
+#if IS_ENABLED(CONFIG_P2SB)
+
+int p2sb_bar(struct pci_dev *pdev, unsigned int devfn,
+	struct resource *res);
+
+#else /* CONFIG_P2SB is not set */
+
+static inline
+int p2sb_bar(struct pci_dev *pdev, unsigned int devfn,
+	struct resource *res)
+{
+	return -ENODEV;
+}
+
+#endif /* CONFIG_P2SB */
+
+#endif /* P2SB_SYMS_H */
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index b8a21d7..65ef6a0 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -1027,4 +1027,8 @@  config INTEL_TELEMETRY
 	  used to get various SoC events and parameters
 	  directly via debugfs files. Various tools may use
 	  this interface for SoC state monitoring.
+
+config P2SB
+	tristate
+	depends on PCI
 endif # X86_PLATFORM_DEVICES
diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
index 2efa86d..c39a13d 100644
--- a/drivers/platform/x86/Makefile
+++ b/drivers/platform/x86/Makefile
@@ -71,3 +71,4 @@  obj-$(CONFIG_INTEL_TELEMETRY)	+= intel_telemetry_core.o \
 				   intel_telemetry_pltdrv.o \
 				   intel_telemetry_debugfs.o
 obj-$(CONFIG_INTEL_PMC_CORE)    += intel_pmc_core.o
+obj-$(CONFIG_P2SB)			+= p2sb.o
diff --git a/drivers/platform/x86/p2sb.c b/drivers/platform/x86/p2sb.c
new file mode 100644
index 0000000..b1d784c
--- /dev/null
+++ b/drivers/platform/x86/p2sb.c
@@ -0,0 +1,98 @@ 
+/*
+ * Primary to Sideband bridge (P2SB) driver
+ *
+ * Copyright (c) 2016, Intel Corporation.
+ *
+ * Authors: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+ *			Jonathan Yong <jonathan.yong@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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 <linux/ioport.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/spinlock.h>
+
+#include <asm/p2sb.h>
+
+#define SBREG_BAR	0x10
+#define SBREG_HIDE	0xe1
+
+static DEFINE_SPINLOCK(p2sb_spinlock);
+
+/*
+ * p2sb_bar - Get Primary to Sideband bridge (P2SB) BAR
+ * @pdev:	PCI device to get PCI bus to communicate with
+ * @devfn:	PCI device and function to communicate with
+ * @res:	resources to be filled in
+ *
+ * The BIOS prevents the P2SB device from being enumerated by the PCI
+ * subsystem, so we need to unhide and hide it back to lookup the P2SB BAR.
+ *
+ * Locking is handled by spinlock - cannot sleep.
+ *
+ * Return:
+ * 0 on success or appropriate errno value on error.
+ */
+int p2sb_bar(struct pci_dev *pdev, unsigned int devfn,
+	struct resource *res)
+{
+	u32 base_addr;
+	u64 base64_addr;
+	unsigned long flags;
+
+	if (!res)
+		return -EINVAL;
+
+	spin_lock(&p2sb_spinlock);
+
+	/* Unhide the P2SB device */
+	pci_bus_write_config_byte(pdev->bus, devfn, SBREG_HIDE, 0x00);
+
+	/* Check if device present */
+	pci_bus_read_config_dword(pdev->bus, devfn, 0, &base_addr);
+	if (base_addr == 0xffffffff || base_addr == 0x00000000) {
+		spin_unlock(&p2sb_spinlock);
+		dev_warn(&pdev->dev, "P2SB device access disabled by BIOS?\n");
+		return -ENODEV;
+	}
+
+	/* Get IO or MMIO BAR */
+	pci_bus_read_config_dword(pdev->bus, devfn, SBREG_BAR, &base_addr);
+	if ((base_addr & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO) {
+		flags = IORESOURCE_IO;
+		base64_addr = base_addr & PCI_BASE_ADDRESS_IO_MASK;
+	} else {
+		flags = IORESOURCE_MEM;
+		base64_addr = base_addr & PCI_BASE_ADDRESS_MEM_MASK;
+		if (base_addr & PCI_BASE_ADDRESS_MEM_TYPE_64) {
+			flags |= IORESOURCE_MEM_64;
+			pci_bus_read_config_dword(pdev->bus, devfn,
+				SBREG_BAR + 4, &base_addr);
+			base64_addr |= (u64)base_addr << 32;
+		}
+	}
+
+	/* Hide the P2SB device */
+	pci_bus_write_config_byte(pdev->bus, devfn, SBREG_HIDE, 0x01);
+
+	spin_unlock(&p2sb_spinlock);
+
+	/* User provides prefilled resources */
+	res->start = (resource_size_t)base64_addr;
+	res->flags = flags;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(p2sb_bar);
+
+MODULE_LICENSE("GPL v2");