aboutsummaryrefslogtreecommitdiff
path: root/arch/sh/drivers/pci/pcie-sh7786.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sh/drivers/pci/pcie-sh7786.c')
-rw-r--r--arch/sh/drivers/pci/pcie-sh7786.c55
1 files changed, 34 insertions, 21 deletions
diff --git a/arch/sh/drivers/pci/pcie-sh7786.c b/arch/sh/drivers/pci/pcie-sh7786.c
index 96e9b058aa1..a162a7f86b2 100644
--- a/arch/sh/drivers/pci/pcie-sh7786.c
+++ b/arch/sh/drivers/pci/pcie-sh7786.c
@@ -1,20 +1,24 @@
/*
* Low-Level PCI Express Support for the SH7786
*
- * Copyright (C) 2009 - 2010 Paul Mundt
+ * Copyright (C) 2009 - 2011 Paul Mundt
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*/
+#define pr_fmt(fmt) "PCI: " fmt
+
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/io.h>
+#include <linux/async.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/clk.h>
#include <linux/sh_clk.h>
+#include <linux/sh_intc.h>
#include "pcie-sh7786.h"
#include <asm/sizes.h>
@@ -31,7 +35,7 @@ static unsigned int nr_ports;
static struct sh7786_pcie_hwops {
int (*core_init)(void);
- int (*port_init_hw)(struct sh7786_pcie_port *port);
+ async_func_t port_init_hw;
} *sh7786_pcie_hwops;
static struct resource sh7786_pci0_resources[] = {
@@ -128,7 +132,7 @@ static struct clk fixed_pciexclkp = {
.rate = 100000000, /* 100 MHz reference clock */
};
-static void __devinit sh7786_pci_fixup(struct pci_dev *dev)
+static void sh7786_pci_fixup(struct pci_dev *dev)
{
/*
* Prevent enumeration of root complex resources.
@@ -235,7 +239,7 @@ static int __init pcie_clk_init(struct sh7786_pcie_port *port)
clk->enable_reg = (void __iomem *)(chan->reg_base + SH4A_PCIEPHYCTLR);
clk->enable_bit = BITS_CKE;
- ret = sh_clk_mstp32_register(clk, 1);
+ ret = sh_clk_mstp_register(clk, 1);
if (unlikely(ret < 0))
goto err_phy;
@@ -463,9 +467,9 @@ static int __init pcie_init(struct sh7786_pcie_port *port)
return 0;
}
-int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin)
+int __init pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
{
- return 71;
+ return evt2irq(0xae0);
}
static int __init sh7786_pcie_core_init(void)
@@ -474,8 +478,9 @@ static int __init sh7786_pcie_core_init(void)
return test_mode_pin(MODE_PIN12) ? 3 : 2;
}
-static int __init sh7786_pcie_init_hw(struct sh7786_pcie_port *port)
+static void __init sh7786_pcie_init_hw(void *data, async_cookie_t cookie)
{
+ struct sh7786_pcie_port *port = data;
int ret;
/*
@@ -488,18 +493,30 @@ static int __init sh7786_pcie_init_hw(struct sh7786_pcie_port *port)
* Setup clocks, needed both for PHY and PCIe registers.
*/
ret = pcie_clk_init(port);
- if (unlikely(ret < 0))
- return ret;
+ if (unlikely(ret < 0)) {
+ pr_err("clock initialization failed for port#%d\n",
+ port->index);
+ return;
+ }
ret = phy_init(port);
- if (unlikely(ret < 0))
- return ret;
+ if (unlikely(ret < 0)) {
+ pr_err("phy initialization failed for port#%d\n",
+ port->index);
+ return;
+ }
ret = pcie_init(port);
- if (unlikely(ret < 0))
- return ret;
+ if (unlikely(ret < 0)) {
+ pr_err("core initialization failed for port#%d\n",
+ port->index);
+ return;
+ }
- return register_pci_controller(port->hose);
+ /* In the interest of preserving device ordering, synchronize */
+ async_synchronize_cookie(cookie);
+
+ register_pci_controller(port->hose);
}
static struct sh7786_pcie_hwops sh7786_65nm_pcie_hwops __initdata = {
@@ -510,7 +527,7 @@ static struct sh7786_pcie_hwops sh7786_65nm_pcie_hwops __initdata = {
static int __init sh7786_pcie_init(void)
{
struct clk *platclk;
- int ret = 0, i;
+ int i;
printk(KERN_NOTICE "PCI: Starting initialization.\n");
@@ -552,14 +569,10 @@ static int __init sh7786_pcie_init(void)
port->hose = sh7786_pci_channels + i;
port->hose->io_map_base = port->hose->resources[0].start;
- ret |= sh7786_pcie_hwops->port_init_hw(port);
+ async_schedule(sh7786_pcie_hwops->port_init_hw, port);
}
- if (unlikely(ret)) {
- clk_disable(platclk);
- clk_put(platclk);
- return ret;
- }
+ async_synchronize_full();
return 0;
}