diff --git a/arch/mips/pci/pci-mt7620.c b/arch/mips/pci/pci-mt7620.c
index d36061603752..f132e7de45bf 100644
--- a/arch/mips/pci/pci-mt7620.c
+++ b/arch/mips/pci/pci-mt7620.c
@@ -16,15 +16,28 @@
 #include <linux/of_irq.h>
 #include <linux/of_pci.h>
 #include <linux/reset.h>
+#include <linux/pci.h>
 #include <linux/platform_device.h>
 
 #include <asm/mach-ralink/ralink_regs.h>
 #include <asm/mach-ralink/mt7620.h>
 
+#define RALINK_MT7628_SPREAD_SPECTRUM
+
+/* region for IO port accesses */
 #define RALINK_PCI_IO_MAP_BASE		0x10160000
-#define RALINK_PCI_MEMORY_BASE		0x0
 
-#define RALINK_INT_PCIE0		4
+/* region for indirect MEM accesses */
+#define RALINK_PCI_IND_MEM_MAP_BASE	0x10150000
+
+/*
+ * RAM address offset for PCIe MEM access from device
+ * 0 = direct mapping
+ */
+#define RALINK_PCI_BUSMASTER_OFFSET	0x0
+
+/* IRQ number for all interrupts from PCIe */
+#define RALINK_IRQ_PCIE0		4
 
 #define RALINK_CLKCFG1			0x30
 #define RALINK_GPIOMODE			0x60
@@ -43,12 +56,13 @@
 #define PCIRST				BIT(1)
 
 #define RALINK_PCI_PCIENA		0x0C
+/* NOTICE on MT7628 this is called PCIINT0 */
 #define PCIINT2				BIT(20)
 
 #define RALINK_PCI_CONFIG_ADDR		0x20
 #define RALINK_PCI_CONFIG_DATA_VIRT_REG	0x24
-#define RALINK_PCI_MEMBASE		0x28
-#define RALINK_PCI_IOBASE		0x2C
+#define RALINK_PCI_MEM_OFFSET		0x28
+#define RALINK_PCI_IO_OFFSET		0x2C
 
 /* PCI RC registers */
 #define RALINK_PCI0_BAR0SETUP_ADDR	0x10
@@ -70,7 +84,6 @@
 #define DATA_SHIFT			0
 #define ADDR_SHIFT			8
 
-
 static void __iomem *bridge_base;
 static void __iomem *pcie_base;
 
@@ -86,6 +99,15 @@ static inline u32 bridge_r32(unsigned reg)
 	return ioread32(bridge_base + reg);
 }
 
+static inline void bridge_m32(u32 clr, u32 set, unsigned reg)
+{
+	u32 val = bridge_r32(reg);
+
+	val &= ~clr;
+	val |= set;
+	bridge_w32(val, reg);
+}
+
 static inline void pcie_w32(u32 val, unsigned reg)
 {
 	iowrite32(val, pcie_base + reg);
@@ -113,7 +135,7 @@ static int wait_pciephy_busy(void)
 		reg_value = pcie_r32(PCIEPHY0_CFG);
 
 		if (reg_value & BUSY)
-			mdelay(100);
+			msleep(100);
 		else
 			break;
 		if (retry++ > WAITRETRY_MAX) {
@@ -129,7 +151,7 @@ static void pcie_phy(unsigned long addr, unsigned long val)
 	wait_pciephy_busy();
 	pcie_w32(WRITE_MODE | (val << DATA_SHIFT) | (addr << ADDR_SHIFT),
 		 PCIEPHY0_CFG);
-	mdelay(1);
+	msleep(1);
 	wait_pciephy_busy();
 }
 
@@ -206,16 +228,86 @@ struct pci_ops mt7620_pci_ops = {
 	.write	= pci_config_write,
 };
 
-static struct resource mt7620_res_pci_mem1;
-static struct resource mt7620_res_pci_io1;
-struct pci_controller mt7620_controller = {
-	.pci_ops	= &mt7620_pci_ops,
-	.mem_resource	= &mt7620_res_pci_mem1,
-	.mem_offset	= 0x00000000UL,
-	.io_resource	= &mt7620_res_pci_io1,
-	.io_offset	= 0x00000000UL,
-	.io_map_base	= 0xa0000000,
-};
+unsigned long pci_address_to_pio(phys_addr_t address)
+{
+
+//get 0- 0xffff IO port value from physical address
+	return address - RALINK_PCI_IO_MAP_BASE;
+}
+
+void __iomem *__pci_ioport_map(struct pci_dev *dev,
+			       unsigned long port, unsigned int nr)
+{
+	void __iomem * temp;
+
+//get iomem address for driver accesses from IO port value
+	temp = (void __iomem *) (mips_io_port_base + port);
+
+	return temp;
+}
+
+/*
+ * TODO change it to WARN or BUG
+ * if this irq occurs, the PCIe controller "crashed"
+ * otherwise it would meant link down normally
+ */
+static irqreturn_t mt7628_irq_handler_link(int irq, void *data)
+{
+	u32 val = 0;
+
+	pr_emerg("PCIe link down, unstable system due HW BUG\n");
+
+//TODO maybe call bug?
+//delete vvvv, not working!
+#if 0
+
+	pr_info("**PCIe link down event %08x %08x\n",
+		bridge_r32(0x08),
+		pcie_r32(0x7414)
+	);
+
+	/* voodoo from the SDK driver */
+	pcie_m32(~0xff, 0x5, RALINK_PCIEPHY_P0_CTL_OFFSET);
+
+	// spread spectrum enable
+	pcie_w32(0x10000000, 0x7414);
+
+	pci_config_read(NULL, 0, 0x70, 4, &val);
+	val |= 1 << (8+16);
+	pci_config_write(NULL, 0, 0x70, 4, val);
+
+	pci_config_read(NULL, 0, 0x84, 4, &val);
+pr_info("slotcap1=%08x\n",val);
+
+	val &= ~(1 << 6);	//hotplug capable
+	val &= ~(1 << 5);	//hotplug surprise
+	val &= ~(1 << 0);	//no attn
+	val &= ~(1 << 1);	//no power control
+	val &= ~(1 << 2);	//no manual retention sensor
+	val &= ~(1 << 3);	//no attention indicator
+	val &= ~(1 << 4);	//no power indicator
+	val &= ~(1 << 17);	//no electromech interlock
+	pci_config_write(NULL, 0, 0x84, 4, val);
+
+	pci_config_read(NULL, 0, 0x84, 4, &val);
+pr_info("slotcap2=%08x\n",val);
+
+	pci_config_read(NULL, 0, 0x88, 4, &val);
+pr_info("slotstat=%08x\n",val);
+	val |= 0xffbf1008;	//clear  states
+	pci_config_write(NULL, 0, 0x88, 4, val);
+
+	pci_config_read(NULL, 0, 0x70c, 4, &val);
+	val &= ~(0xff) << 8;
+	val |= 0x80 << 8;
+	pci_config_write(NULL, 0, 0x70c, 4, val);
+
+//	bridge_w32(0xffffffff,0x08);
+// 	pr_info("aft fl=%08lx\n",bridge_r32(0x08));
+#endif
+	/* Nothing to do */
+	return IRQ_HANDLED;
+}
 
 static int mt7620_pci_hw_init(struct platform_device *pdev)
 {
@@ -227,7 +319,7 @@ static int mt7620_pci_hw_init(struct platform_device *pdev)
 	pcie_phy(0x68, 0xB4);
 
 	/* put core into reset */
-	pcie_m32(0, PCIRST, RALINK_PCI_PCICFG_ADDR);
+	bridge_m32(0, PCIRST, RALINK_PCI_PCICFG_ADDR);
 	reset_control_assert(rstpcie0);
 
 	/* disable power and all clocks */
@@ -237,7 +329,7 @@ static int mt7620_pci_hw_init(struct platform_device *pdev)
 	/* bring core out of reset */
 	reset_control_deassert(rstpcie0);
 	rt_sysc_m32(0, RALINK_PCIE0_CLK_EN, RALINK_CLKCFG1);
-	mdelay(100);
+	msleep(100);
 
 	if (!(rt_sysc_r32(PPLL_CFG1) & PDRV_SW_SET)) {
 		dev_err(&pdev->dev, "MT7620 PPLL unlock\n");
@@ -256,25 +348,59 @@ static int mt7620_pci_hw_init(struct platform_device *pdev)
 static int mt7628_pci_hw_init(struct platform_device *pdev)
 {
 	u32 val = 0;
+	int err;
+	int irq;
 
-	/* bring the core out of reset */
+	/* put core into reset */
+	reset_control_assert(rstpcie0);
+
+	/* FIXME someone with mt7620: is there link down interrupt too? */
+	irq = of_irq_get(pdev->dev.of_node, 0);
+	if (irq <= 0) {
+		dev_err(&pdev->dev, "failed to get IRQ\n");
+		return irq ? irq : -EINVAL;
+	}
+
+	err = devm_request_irq(&pdev->dev, irq, mt7628_irq_handler_link,
+			       0, "PCIe link down", NULL);
+	if (err) {
+		dev_err(&pdev->dev, "failed to request IRQ %i\n", irq);
+		return err;
+	}
+
+	/* disable GPIO on PERST pinmux */
 	rt_sysc_m32(BIT(16), 0, RALINK_GPIOMODE);
+
+	/* bring the core out of reset, PERST is left asserted */
 	reset_control_deassert(rstpcie0);
 
 	/* enable the pci clk */
 	rt_sysc_m32(0, RALINK_PCIE0_CLK_EN, RALINK_CLKCFG1);
-	mdelay(100);
 
-	/* voodoo from the SDK driver */
+	/* voodoo from the SDK driver, phy LDO setting: 1..1.0V - 5..1.2V */
 	pcie_m32(~0xff, 0x5, RALINK_PCIEPHY_P0_CTL_OFFSET);
 
+#if defined(RALINK_MT7628_SPREAD_SPECTRUM)
+	/* spread spectrum enable */
+	pcie_w32(0x10000000, 0x7414);
+#endif
+
+	/* wait for clock stabilization */
+	msleep(100);
+
+	/* set "slot implemented" flag */
+	pci_config_read(NULL, 0, 0x70, 4, &val);
+	val |= 1 << (8 + 16);
+	pci_config_write(NULL, 0, 0x70, 4, val);
+
+	/* Increase N_FTS, undocumented */
 	pci_config_read(NULL, 0, 0x70c, 4, &val);
 	val &= ~(0xff) << 8;
 	val |= 0x50 << 8;
 	pci_config_write(NULL, 0, 0x70c, 4, val);
 
 	pci_config_read(NULL, 0, 0x70c, 4, &val);
-	dev_err(&pdev->dev, "Port 0 N_FTS = %x\n", (unsigned int) val);
+	dev_info(&pdev->dev, "Port 0 N_FTS = %x\n", (unsigned int) val);
 
 	return 0;
 }
@@ -285,6 +411,8 @@ static int mt7620_pci_probe(struct platform_device *pdev)
 							    IORESOURCE_MEM, 0);
 	struct resource *pcie_res = platform_get_resource(pdev,
 							  IORESOURCE_MEM, 1);
+	struct pci_host_bridge *bridge;
+	int err;
 	u32 val = 0;
 
 	rstpcie0 = devm_reset_control_get_exclusive(&pdev->dev, "pcie0");
@@ -299,50 +427,56 @@ static int mt7620_pci_probe(struct platform_device *pdev)
 	if (IS_ERR(pcie_base))
 		return PTR_ERR(pcie_base);
 
-	iomem_resource.start = 0;
-	iomem_resource.end = ~0;
-	ioport_resource.start = 0;
-	ioport_resource.end = ~0;
-
 	/* bring up the pci core */
 	switch (ralink_soc) {
 	case MT762X_SOC_MT7620A:
-		if (mt7620_pci_hw_init(pdev))
-			return -1;
+		err = mt7620_pci_hw_init(pdev);
+		if (err)
+			goto fail_and_disable;
 		break;
 
 	case MT762X_SOC_MT7628AN:
 	case MT762X_SOC_MT7688:
-		if (mt7628_pci_hw_init(pdev))
-			return -1;
+		err = mt7628_pci_hw_init(pdev);
+		if (err)
+			goto fail_and_disable;
 		break;
 
 	default:
 		dev_err(&pdev->dev, "pcie is not supported on this hardware\n");
-		return -1;
+		err = -ENODEV;
+		goto fail_and_disable;
 	}
-	mdelay(50);
 
-	/* enable write access */
-	pcie_m32(PCIRST, 0, RALINK_PCI_PCICFG_ADDR);
-	mdelay(100);
+	/*
+	 * deactivate PERST after power and clock stabilization
+	 *
+	 * FIXME if mt7620 leaves PERST asserted too,
+	 * next wait can probably go away
+	 */
+	msleep(50);
+	bridge_m32(PCIRST, 0, RALINK_PCI_PCICFG_ADDR);
+
+	/* wait until device enables link */
+	msleep(100);
 
 	/* check if there is a card present */
 	if ((pcie_r32(RALINK_PCI0_STATUS) & PCIE_LINK_UP_ST) == 0) {
-		reset_control_assert(rstpcie0);
-		rt_sysc_m32(RALINK_PCIE0_CLK_EN, 0, RALINK_CLKCFG1);
-		if (ralink_soc == MT762X_SOC_MT7620A)
-			rt_sysc_m32(LC_CKDRVPD, PDRV_SW_SET, PPLL_DRV);
-		dev_err(&pdev->dev, "PCIE0 no card, disable it(RST&CLK)\n");
-		return -1;
+		dev_err(&pdev->dev, "No card detected, disable PCIe core\n");
+		err = -ENODEV;
+		goto fail_and_disable;
 	}
 
-	/* setup ranges */
-	bridge_w32(0xffffffff, RALINK_PCI_MEMBASE);
-	bridge_w32(RALINK_PCI_IO_MAP_BASE, RALINK_PCI_IOBASE);
+	/* offset of access in 0x1015xxxx will add to the reg val */
+	bridge_w32(0x30000000, RALINK_PCI_MEM_OFFSET);	//a valid value
+
+	/* no offset for IO access */
+	bridge_w32(0, RALINK_PCI_IO_OFFSET);
+
+	/* default offset for busmaster = beginning of RAM */
+	pcie_w32(RALINK_PCI_BUSMASTER_OFFSET, RALINK_PCI0_IMBASEBAR0_ADDR);
 
-	pcie_w32(0x7FFF0001, RALINK_PCI0_BAR0SETUP_ADDR);
-	pcie_w32(RALINK_PCI_MEMORY_BASE, RALINK_PCI0_IMBASEBAR0_ADDR);
+	/* change default class (wifi adapter) */
 	pcie_w32(0x06040001, RALINK_PCI0_CLASS);
 
 	/* enable interrupts */
@@ -352,51 +486,45 @@ static int mt7620_pci_probe(struct platform_device *pdev)
 	pci_config_read(NULL, 0, 4, 4, &val);
 	pci_config_write(NULL, 0, 4, 4, val | 0x7);
 
-	pci_load_of_ranges(&mt7620_controller, pdev->dev.of_node);
-	register_pci_controller(&mt7620_controller);
+	/* don't start IO ports from 0 */
+	PCIBIOS_MIN_IO = 0x1000;
+	PCIBIOS_MIN_MEM = 0x20000000;
 
-	return 0;
-}
+	set_io_port_base(KSEG1 + RALINK_PCI_IO_MAP_BASE);
 
-int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
-{
-	u16 cmd;
-	u32 val;
-	int irq = 0;
-
-	if ((dev->bus->number == 0) && (slot == 0)) {
-		pcie_w32(0x7FFF0001, RALINK_PCI0_BAR0SETUP_ADDR);
-		pci_config_write(dev->bus, 0, PCI_BASE_ADDRESS_0, 4,
-				 RALINK_PCI_MEMORY_BASE);
-		pci_config_read(dev->bus, 0, PCI_BASE_ADDRESS_0, 4, &val);
-	} else if ((dev->bus->number == 1) && (slot == 0x0)) {
-		irq = RALINK_INT_PCIE0;
-	} else {
-		dev_err(&dev->dev, "no irq found - bus=0x%x, slot = 0x%x\n",
-			dev->bus->number, slot);
-		return 0;
+        bridge = devm_pci_alloc_host_bridge(&pdev->dev, 0);
+        if (!bridge) {
+                err = -ENOMEM;
+		goto fail_and_disable;
 	}
-	dev_err(&dev->dev, "card - bus=0x%x, slot = 0x%x irq=%d\n",
-		dev->bus->number, slot, irq);
-
-	/* configure the cache line size to 0x14 */
-	pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 0x14);
-
-	/* configure latency timer to 0xff */
-	pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0xff);
-	pci_read_config_word(dev, PCI_COMMAND, &cmd);
-
-	/* setup the slot */
-	cmd = cmd | PCI_COMMAND_MASTER | PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
-	pci_write_config_word(dev, PCI_COMMAND, cmd);
-	pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
 
-	return irq;
-}
+	err = pci_parse_request_of_pci_ranges(&pdev->dev, &bridge->windows, NULL);
+	if (err)
+		goto fail_and_disable;
+
+	bridge->dev.parent = &pdev->dev;
+	bridge->busnr = 0;
+	bridge->ops = &mt7620_pci_ops;
+	bridge->swizzle_irq = pci_common_swizzle;
+	bridge->map_irq = of_irq_parse_and_map_pci;
+
+	err = pci_host_probe(bridge);
+	if (err < 0) {
+		dev_err(&pdev->dev, "failed to probe host %d\n", err);
+		pci_free_resource_list(&bridge->windows);
+		goto fail_and_disable;
+	}
 
-int pcibios_plat_dev_init(struct pci_dev *dev)
-{
 	return 0;
+
+fail_and_disable:
+#if 0
+	reset_control_assert(rstpcie0);
+	rt_sysc_m32(RALINK_PCIE0_CLK_EN, 0, RALINK_CLKCFG1);
+	if (ralink_soc == MT762X_SOC_MT7620A)
+		rt_sysc_m32(LC_CKDRVPD, PDRV_SW_SET, PPLL_DRV);
+#endif
+	return err;
 }
 
 static const struct of_device_id mt7620_pci_ids[] = {
@@ -414,7 +542,32 @@ static struct platform_driver mt7620_pci_driver = {
 
 static int __init mt7620_pci_init(void)
 {
-	return platform_driver_register(&mt7620_pci_driver);
+	int ret;
+
+	ret = platform_driver_register(&mt7620_pci_driver);
+	return ret;
 }
 
 arch_initcall(mt7620_pci_init);
+
+static void mediatek_fixup_bar(struct pci_dev *dev) {
+pr_info("++++++ mediatek_fixup_bar dev=%px\n",dev);
+
+//TODO probably put it directly to init, here only if mt7620 work OK
+//	dev->non_compliant_bars = true;
+
+	pcie_w32(0x0, RALINK_PCI0_BAR0SETUP_ADDR);
+	pcie_w32(0x0, RALINK_PCI0_BAR0SETUP_ADDR + 4);
+}
+DECLARE_PCI_FIXUP_EARLY(0x14c3, 0x0801, mediatek_fixup_bar);
+
+static void mediatek_fixup_final_bar(struct pci_dev *dev) {
+
+pr_info("++++++ MTK final fixup, BAR0 must-be-set bug\n");
+
+	pcie_w32(0x0FFF0001, RALINK_PCI0_BAR0SETUP_ADDR);
+	pcie_w32(0x0FFF0001, RALINK_PCI0_BAR0SETUP_ADDR);
+}
+
+//TODO for mt7620 ... or does it works there OK?
+DECLARE_PCI_FIXUP_FINAL(0x14c3, 0x0801, mediatek_fixup_final_bar);
diff --git a/arch/mips/ralink/Kconfig b/arch/mips/ralink/Kconfig
index 49c22ddd9c41..ac89d01cf7d5 100644
--- a/arch/mips/ralink/Kconfig
+++ b/arch/mips/ralink/Kconfig
@@ -38,8 +38,14 @@ choice
 
 	config SOC_MT7620
 		bool "MT7620/8"
+		select SYS_SUPPORTS_HIGHMEM
 		select CPU_MIPSR2_IRQ_VI
 		select HAVE_PCI
+#		select COMMON_CLK
+		select CPU_HAS_PREFETCH
+	        select PCI_DRIVERS_GENERIC
+	        select NO_GENERIC_PCI_IOPORT_MAP
+
 
 	config SOC_MT7621
 		bool "MT7621"
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index f20a3de57d21..2da5d8b4ba59 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -3941,6 +3941,8 @@ unsigned long __weak pci_address_to_pio(phys_addr_t address)
  */
 int pci_remap_iospace(const struct resource *res, phys_addr_t phys_addr)
 {
+
+#if 0
 #if defined(PCI_IOBASE) && defined(CONFIG_MMU)
 	unsigned long vaddr = (unsigned long)PCI_IOBASE + res->start;
 
@@ -3960,6 +3962,8 @@ int pci_remap_iospace(const struct resource *res, phys_addr_t phys_addr)
 	WARN_ONCE(1, "This architecture does not support memory mapped I/O\n");
 	return -ENODEV;
 #endif
+#endif
+return 0;
 }
 EXPORT_SYMBOL(pci_remap_iospace);
 
