summaryrefslogtreecommitdiff
path: root/drivers/pci/host
diff options
context:
space:
mode:
authorSrinivasarao P <spathi@codeaurora.org>2017-12-26 17:23:34 +0530
committerSrinivasarao P <spathi@codeaurora.org>2017-12-26 17:29:34 +0530
commit202fde333dc0065e2f2ca3539f5a06a9126f896d (patch)
tree61e9ae04c1d693ff0c498520a37bf7618ce5baea /drivers/pci/host
parentbb6e8073112e0a7dd53e2cbd166b20f585a5bb79 (diff)
parent03d4af8271682742aa21bbbf3032a839764f591a (diff)
Merge android-4.4.98 (3d4af8) into msm-4.4
* refs/heads/tmp-03d4af8 Linux 4.4.98 PKCS#7: fix unitialized boolean 'want' x86/oprofile/ppro: Do not use __this_cpu*() in preemptible context can: c_can: don't indicate triple sampling support for D_CAN can: sun4i: handle overrun in RX FIFO rbd: use GFP_NOIO for parent stat and data requests drm/vmwgfx: Fix Ubuntu 17.10 Wayland black screen issue Input: elan_i2c - add ELAN060C to the ACPI table MIPS: AR7: Ensure that serial ports are properly set up MIPS: AR7: Defer registration of GPIO tools: firmware: check for distro fallback udev cancel rule selftests: firmware: send expected errors to /dev/null selftests: firmware: add empty string and async tests test: firmware_class: report errors properly on failure MIPS: SMP: Fix deadlock & online race MIPS: Fix race on setting and getting cpu_online_mask MIPS: SMP: Use a completion event to signal CPU up MIPS: Fix CM region target definitions MIPS: microMIPS: Fix incorrect mask in insn_table_MM ALSA: seq: Avoid invalid lockdep class warning ALSA: seq: Fix OSS sysex delivery in OSS emulation ARM: 8720/1: ensure dump_instr() checks addr_limit KEYS: fix NULL pointer dereference during ASN.1 parsing [ver #2] crypto: x86/sha1-mb - fix panic due to unaligned access workqueue: Fix NULL pointer dereference x86/uaccess, sched/preempt: Verify access_ok() context platform/x86: hp-wmi: Do not shadow error values platform/x86: hp-wmi: Fix error value for hp_wmi_tablet_state KEYS: trusted: fix writing past end of buffer in trusted_read() KEYS: trusted: sanitize all key material cdc_ncm: Set NTB format again after altsetting switch for Huawei devices platform/x86: hp-wmi: Fix detection for dock and tablet mode net: dsa: select NET_SWITCHDEV s390/qeth: issue STARTLAN as first IPA command IB/ipoib: Change list_del to list_del_init in the tx object Input: mpr121 - set missing event capability Input: mpr121 - handle multiple bits change of status register IPsec: do not ignore crypto err in ah4 input netfilter: nft_meta: deal with PACKET_LOOPBACK in netdev family usb: hcd: initialize hcd->flags to 0 when rm hcd serial: sh-sci: Fix register offsets for the IRDA serial port phy: increase size of MII_BUS_ID_SIZE and bus_id iio: trigger: free trigger resource correctly crypto: vmx - disable preemption to enable vsx in aes_ctr.c ARM: omap2plus_defconfig: Fix probe errors on UARTs 5 and 6 powerpc/corenet: explicitly disable the SDHC controller on kmcoge4 iommu/arm-smmu-v3: Clear prior settings when updating STEs KVM: PPC: Book 3S: XICS: correct the real mode ICP rejecting counter drm: drm_minor_register(): Clean up debugfs on failure xen/netback: set default upper limit of tx/rx queues to 8 PCI: mvebu: Handle changes to the bridge windows while enabled video: fbdev: pmag-ba-fb: Remove bad `__init' annotation adv7604: Initialize drive strength to default when using DT ANDROID: binder: clarify deferred thread work. FROMLIST: arm64: Avoid aligning normal memory pointers in __memcpy_{to,from}io Conflicts: arch/arm64/kernel/io.c Change-Id: I992fcf368dbc672ad7d6ae31e87f289f4d7df2bf Signed-off-by: Srinivasarao P <spathi@codeaurora.org>
Diffstat (limited to 'drivers/pci/host')
-rw-r--r--drivers/pci/host/pci-mvebu.c101
1 files changed, 60 insertions, 41 deletions
diff --git a/drivers/pci/host/pci-mvebu.c b/drivers/pci/host/pci-mvebu.c
index 53b79c5f0559..379d08f76146 100644
--- a/drivers/pci/host/pci-mvebu.c
+++ b/drivers/pci/host/pci-mvebu.c
@@ -131,6 +131,12 @@ struct mvebu_pcie {
int nports;
};
+struct mvebu_pcie_window {
+ phys_addr_t base;
+ phys_addr_t remap;
+ size_t size;
+};
+
/* Structure representing one PCIe interface */
struct mvebu_pcie_port {
char *name;
@@ -148,10 +154,8 @@ struct mvebu_pcie_port {
struct mvebu_sw_pci_bridge bridge;
struct device_node *dn;
struct mvebu_pcie *pcie;
- phys_addr_t memwin_base;
- size_t memwin_size;
- phys_addr_t iowin_base;
- size_t iowin_size;
+ struct mvebu_pcie_window memwin;
+ struct mvebu_pcie_window iowin;
u32 saved_pcie_stat;
};
@@ -377,23 +381,45 @@ static void mvebu_pcie_add_windows(struct mvebu_pcie_port *port,
}
}
+static void mvebu_pcie_set_window(struct mvebu_pcie_port *port,
+ unsigned int target, unsigned int attribute,
+ const struct mvebu_pcie_window *desired,
+ struct mvebu_pcie_window *cur)
+{
+ if (desired->base == cur->base && desired->remap == cur->remap &&
+ desired->size == cur->size)
+ return;
+
+ if (cur->size != 0) {
+ mvebu_pcie_del_windows(port, cur->base, cur->size);
+ cur->size = 0;
+ cur->base = 0;
+
+ /*
+ * If something tries to change the window while it is enabled
+ * the change will not be done atomically. That would be
+ * difficult to do in the general case.
+ */
+ }
+
+ if (desired->size == 0)
+ return;
+
+ mvebu_pcie_add_windows(port, target, attribute, desired->base,
+ desired->size, desired->remap);
+ *cur = *desired;
+}
+
static void mvebu_pcie_handle_iobase_change(struct mvebu_pcie_port *port)
{
- phys_addr_t iobase;
+ struct mvebu_pcie_window desired = {};
/* Are the new iobase/iolimit values invalid? */
if (port->bridge.iolimit < port->bridge.iobase ||
port->bridge.iolimitupper < port->bridge.iobaseupper ||
!(port->bridge.command & PCI_COMMAND_IO)) {
-
- /* If a window was configured, remove it */
- if (port->iowin_base) {
- mvebu_pcie_del_windows(port, port->iowin_base,
- port->iowin_size);
- port->iowin_base = 0;
- port->iowin_size = 0;
- }
-
+ mvebu_pcie_set_window(port, port->io_target, port->io_attr,
+ &desired, &port->iowin);
return;
}
@@ -410,32 +436,27 @@ static void mvebu_pcie_handle_iobase_change(struct mvebu_pcie_port *port)
* specifications. iobase is the bus address, port->iowin_base
* is the CPU address.
*/
- iobase = ((port->bridge.iobase & 0xF0) << 8) |
- (port->bridge.iobaseupper << 16);
- port->iowin_base = port->pcie->io.start + iobase;
- port->iowin_size = ((0xFFF | ((port->bridge.iolimit & 0xF0) << 8) |
- (port->bridge.iolimitupper << 16)) -
- iobase) + 1;
-
- mvebu_pcie_add_windows(port, port->io_target, port->io_attr,
- port->iowin_base, port->iowin_size,
- iobase);
+ desired.remap = ((port->bridge.iobase & 0xF0) << 8) |
+ (port->bridge.iobaseupper << 16);
+ desired.base = port->pcie->io.start + desired.remap;
+ desired.size = ((0xFFF | ((port->bridge.iolimit & 0xF0) << 8) |
+ (port->bridge.iolimitupper << 16)) -
+ desired.remap) +
+ 1;
+
+ mvebu_pcie_set_window(port, port->io_target, port->io_attr, &desired,
+ &port->iowin);
}
static void mvebu_pcie_handle_membase_change(struct mvebu_pcie_port *port)
{
+ struct mvebu_pcie_window desired = {.remap = MVEBU_MBUS_NO_REMAP};
+
/* Are the new membase/memlimit values invalid? */
if (port->bridge.memlimit < port->bridge.membase ||
!(port->bridge.command & PCI_COMMAND_MEMORY)) {
-
- /* If a window was configured, remove it */
- if (port->memwin_base) {
- mvebu_pcie_del_windows(port, port->memwin_base,
- port->memwin_size);
- port->memwin_base = 0;
- port->memwin_size = 0;
- }
-
+ mvebu_pcie_set_window(port, port->mem_target, port->mem_attr,
+ &desired, &port->memwin);
return;
}
@@ -445,14 +466,12 @@ static void mvebu_pcie_handle_membase_change(struct mvebu_pcie_port *port)
* window to setup, according to the PCI-to-PCI bridge
* specifications.
*/
- port->memwin_base = ((port->bridge.membase & 0xFFF0) << 16);
- port->memwin_size =
- (((port->bridge.memlimit & 0xFFF0) << 16) | 0xFFFFF) -
- port->memwin_base + 1;
-
- mvebu_pcie_add_windows(port, port->mem_target, port->mem_attr,
- port->memwin_base, port->memwin_size,
- MVEBU_MBUS_NO_REMAP);
+ desired.base = ((port->bridge.membase & 0xFFF0) << 16);
+ desired.size = (((port->bridge.memlimit & 0xFFF0) << 16) | 0xFFFFF) -
+ desired.base + 1;
+
+ mvebu_pcie_set_window(port, port->mem_target, port->mem_attr, &desired,
+ &port->memwin);
}
/*