diff options
Diffstat (limited to 'arch/sh/drivers/pci')
| -rw-r--r-- | arch/sh/drivers/pci/fixups-cayman.c | 2 | ||||
| -rw-r--r-- | arch/sh/drivers/pci/fixups-dreamcast.c | 22 | ||||
| -rw-r--r-- | arch/sh/drivers/pci/fixups-landisk.c | 33 | ||||
| -rw-r--r-- | arch/sh/drivers/pci/fixups-r7780rp.c | 9 | ||||
| -rw-r--r-- | arch/sh/drivers/pci/fixups-rts7751r2d.c | 2 | ||||
| -rw-r--r-- | arch/sh/drivers/pci/fixups-sdk7780.c | 20 | ||||
| -rw-r--r-- | arch/sh/drivers/pci/fixups-sdk7786.c | 4 | ||||
| -rw-r--r-- | arch/sh/drivers/pci/fixups-se7751.c | 7 | ||||
| -rw-r--r-- | arch/sh/drivers/pci/fixups-sh03.c | 21 | ||||
| -rw-r--r-- | arch/sh/drivers/pci/fixups-snapgear.c | 13 | ||||
| -rw-r--r-- | arch/sh/drivers/pci/fixups-titan.c | 2 | ||||
| -rw-r--r-- | arch/sh/drivers/pci/pci-sh5.c | 4 | ||||
| -rw-r--r-- | arch/sh/drivers/pci/pci-sh7751.h | 2 | ||||
| -rw-r--r-- | arch/sh/drivers/pci/pci-sh7780.c | 19 | ||||
| -rw-r--r-- | arch/sh/drivers/pci/pci.c | 169 | ||||
| -rw-r--r-- | arch/sh/drivers/pci/pcie-sh7786.c | 55 | ||||
| -rw-r--r-- | arch/sh/drivers/pci/pcie-sh7786.h | 3 | 
17 files changed, 169 insertions, 218 deletions
diff --git a/arch/sh/drivers/pci/fixups-cayman.c b/arch/sh/drivers/pci/fixups-cayman.c index b68b61d22c6..edc2fb7a5bb 100644 --- a/arch/sh/drivers/pci/fixups-cayman.c +++ b/arch/sh/drivers/pci/fixups-cayman.c @@ -5,7 +5,7 @@  #include <cpu/irq.h>  #include "pci-sh5.h" -int __init pcibios_map_platform_irq(struct pci_dev *dev, u8 slot, u8 pin) +int __init pcibios_map_platform_irq(const struct pci_dev *dev, u8 slot, u8 pin)  {  	int result = -1; diff --git a/arch/sh/drivers/pci/fixups-dreamcast.c b/arch/sh/drivers/pci/fixups-dreamcast.c index 942ef4f155f..1d1c5a227e5 100644 --- a/arch/sh/drivers/pci/fixups-dreamcast.c +++ b/arch/sh/drivers/pci/fixups-dreamcast.c @@ -28,9 +28,11 @@  #include <asm/irq.h>  #include <mach/pci.h> -static void __init gapspci_fixup_resources(struct pci_dev *dev) +static void gapspci_fixup_resources(struct pci_dev *dev)  {  	struct pci_channel *p = dev->sysdata; +	struct resource res; +	struct pci_bus_region region;  	printk(KERN_NOTICE "PCI: Fixing up device %s\n", pci_name(dev)); @@ -50,11 +52,21 @@ static void __init gapspci_fixup_resources(struct pci_dev *dev)  		/*  		 * Redirect dma memory allocations to special memory window. +		 * +		 * If this GAPSPCI region were mapped by a BAR, the CPU +		 * phys_addr_t would be pci_resource_start(), and the bus +		 * address would be pci_bus_address(pci_resource_start()). +		 * But apparently there's no BAR mapping it, so we just +		 * "know" its CPU address is GAPSPCI_DMA_BASE.  		 */ +		res.start = GAPSPCI_DMA_BASE; +		res.end = GAPSPCI_DMA_BASE + GAPSPCI_DMA_SIZE - 1; +		res.flags = IORESOURCE_MEM; +		pcibios_resource_to_bus(dev->bus, ®ion, &res);  		BUG_ON(!dma_declare_coherent_memory(&dev->dev, -						GAPSPCI_DMA_BASE, -						GAPSPCI_DMA_BASE, -						GAPSPCI_DMA_SIZE, +						res.start, +						region.start, +						resource_size(&res),  						DMA_MEMORY_MAP |  						DMA_MEMORY_EXCLUSIVE));  		break; @@ -64,7 +76,7 @@ static void __init gapspci_fixup_resources(struct pci_dev *dev)  }  DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, gapspci_fixup_resources); -int __init pcibios_map_platform_irq(struct pci_dev *dev, u8 slot, u8 pin) +int __init pcibios_map_platform_irq(const struct pci_dev *dev, u8 slot, u8 pin)  {  	/*  	 * The interrupt routing semantics here are quite trivial. diff --git a/arch/sh/drivers/pci/fixups-landisk.c b/arch/sh/drivers/pci/fixups-landisk.c index bb1a6bb5149..db5b40a98e6 100644 --- a/arch/sh/drivers/pci/fixups-landisk.c +++ b/arch/sh/drivers/pci/fixups-landisk.c @@ -1,9 +1,10 @@  /* - * arch/sh/drivers/pci/ops-landisk.c + * arch/sh/drivers/pci/fixups-landisk.c   *   * PCI initialization for the I-O DATA Device, Inc. LANDISK board   *   * Copyright (C) 2006 kogiidena + * Copyright (C) 2010 Nobuhiro Iwamatsu   *   * May be copied or modified under the terms of the GNU General Public   * License.  See linux/COPYING for more information. @@ -13,9 +14,13 @@  #include <linux/init.h>  #include <linux/delay.h>  #include <linux/pci.h> +#include <linux/sh_intc.h>  #include "pci-sh4.h" -int pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) +#define PCIMCR_MRSET_OFF	0xBFFFFFFF +#define PCIMCR_RFSH_OFF		0xFFFFFFFB + +int pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin)  {  	/*  	 * slot0: pin1-4 = irq5,6,7,8 @@ -23,12 +28,32 @@ int pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin)  	 * slot2: pin1-4 = irq7,8,5,6  	 * slot3: pin1-4 = irq8,5,6,7  	 */ -	int irq = ((slot + pin - 1) & 0x3) + 5; +	int irq = ((slot + pin - 1) & 0x3) + evt2irq(0x2a0);  	if ((slot | (pin - 1)) > 0x3) { -		printk("PCI: Bad IRQ mapping request for slot %d pin %c\n", +		printk(KERN_WARNING "PCI: Bad IRQ mapping request for slot %d pin %c\n",  		       slot, pin - 1 + 'A');  		return -1;  	}  	return irq;  } + +int pci_fixup_pcic(struct pci_channel *chan) +{ +	unsigned long bcr1, mcr; + +	bcr1 = __raw_readl(SH7751_BCR1); +	bcr1 |= 0x40080000;	/* Enable Bit 19 BREQEN, set PCIC to slave */ +	pci_write_reg(chan, bcr1, SH4_PCIBCR1); + +	mcr = __raw_readl(SH7751_MCR); +	mcr = (mcr & PCIMCR_MRSET_OFF) & PCIMCR_RFSH_OFF; +	pci_write_reg(chan, mcr, SH4_PCIMCR); + +	pci_write_reg(chan, 0x0c000000, SH7751_PCICONF5); +	pci_write_reg(chan, 0xd0000000, SH7751_PCICONF6); +	pci_write_reg(chan, 0x0c000000, SH4_PCILAR0); +	pci_write_reg(chan, 0x00000000, SH4_PCILAR1); + +	return 0; +} diff --git a/arch/sh/drivers/pci/fixups-r7780rp.c b/arch/sh/drivers/pci/fixups-r7780rp.c index 08b2d8658a0..57ed3f09d0c 100644 --- a/arch/sh/drivers/pci/fixups-r7780rp.c +++ b/arch/sh/drivers/pci/fixups-r7780rp.c @@ -12,13 +12,10 @@   */  #include <linux/pci.h>  #include <linux/io.h> +#include <linux/sh_intc.h>  #include "pci-sh4.h" -static char irq_tab[] __initdata = { -	65, 66, 67, 68, -}; - -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 irq_tab[slot]; +	return evt2irq(0xa20) + slot;  } diff --git a/arch/sh/drivers/pci/fixups-rts7751r2d.c b/arch/sh/drivers/pci/fixups-rts7751r2d.c index e248516118a..eaddb56c45c 100644 --- a/arch/sh/drivers/pci/fixups-rts7751r2d.c +++ b/arch/sh/drivers/pci/fixups-rts7751r2d.c @@ -31,7 +31,7 @@ static char lboxre2_irq_tab[] __initdata = {  	IRQ_ETH0, IRQ_ETH1, IRQ_INTA, IRQ_INTD,  }; -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)  {  	if (mach_is_lboxre2())  		return lboxre2_irq_tab[slot]; diff --git a/arch/sh/drivers/pci/fixups-sdk7780.c b/arch/sh/drivers/pci/fixups-sdk7780.c index 0930f988ac2..c0a015ae6ec 100644 --- a/arch/sh/drivers/pci/fixups-sdk7780.c +++ b/arch/sh/drivers/pci/fixups-sdk7780.c @@ -13,21 +13,31 @@   */  #include <linux/pci.h>  #include <linux/io.h> +#include <linux/sh_intc.h>  #include "pci-sh4.h" +#define IRQ_INTA	evt2irq(0xa20) +#define IRQ_INTB	evt2irq(0xa40) +#define IRQ_INTC	evt2irq(0xa60) +#define IRQ_INTD	evt2irq(0xa80) +  /* IDSEL [16][17][18][19][20][21][22][23][24][25][26][27][28][29][30][31] */  static char sdk7780_irq_tab[4][16] __initdata = {  	/* INTA */ -	{ 65, 68, 67, 68, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +	{ IRQ_INTA, IRQ_INTD, IRQ_INTC, IRQ_INTD, -1, -1, -1, -1, -1, -1, +	  -1, -1, -1, -1, -1, -1 },  	/* INTB */ -	{ 66, 65, -1, 65, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +	{ IRQ_INTB, IRQ_INTA, -1, IRQ_INTA, -1, -1, -1, -1, -1, -1, -1, -1, +	  -1, -1, -1, -1 },  	/* INTC */ -	{ 67, 66, -1, 66, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +	{ IRQ_INTC, IRQ_INTB, -1, IRQ_INTB, -1, -1, -1, -1, -1, -1, -1, -1, +	  -1, -1, -1, -1 },  	/* INTD */ -	{ 68, 67, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +	{ IRQ_INTD, IRQ_INTC, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +	  -1, -1, -1 },  }; -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 sdk7780_irq_tab[pin-1][slot];  } diff --git a/arch/sh/drivers/pci/fixups-sdk7786.c b/arch/sh/drivers/pci/fixups-sdk7786.c index 0e18ee33255..36eb6fc3c18 100644 --- a/arch/sh/drivers/pci/fixups-sdk7786.c +++ b/arch/sh/drivers/pci/fixups-sdk7786.c @@ -23,9 +23,9 @@   * Misconfigurations can be detected through the FPGA via the slot   * resistors to determine card presence. Hotplug remains unsupported.   */ -static unsigned int slot4en __devinitdata; +static unsigned int slot4en __initdata; -char *__devinit pcibios_setup(char *str) +char *__init pcibios_setup(char *str)  {  	if (strcmp(str, "slot4en") == 0) {  		slot4en = 1; diff --git a/arch/sh/drivers/pci/fixups-se7751.c b/arch/sh/drivers/pci/fixups-se7751.c index a4c7d3a4efc..84a88ca9200 100644 --- a/arch/sh/drivers/pci/fixups-se7751.c +++ b/arch/sh/drivers/pci/fixups-se7751.c @@ -4,13 +4,14 @@  #include <linux/delay.h>  #include <linux/pci.h>  #include <linux/io.h> +#include <linux/sh_intc.h>  #include "pci-sh4.h" -int __init pcibios_map_platform_irq(u8 slot, u8 pin) +int __init pcibios_map_platform_irq(const struct pci_dev *, u8 slot, u8 pin)  {          switch (slot) { -        case 0: return 13; -        case 1: return 13;	/* AMD Ethernet controller */ +        case 0: return evt2irq(0x3a0); +        case 1: return evt2irq(0x3a0);	/* AMD Ethernet controller */          case 2: return -1;          case 3: return -1;          case 4: return -1; diff --git a/arch/sh/drivers/pci/fixups-sh03.c b/arch/sh/drivers/pci/fixups-sh03.c index 2e8a18b7ee5..16207bef9f5 100644 --- a/arch/sh/drivers/pci/fixups-sh03.c +++ b/arch/sh/drivers/pci/fixups-sh03.c @@ -2,28 +2,29 @@  #include <linux/init.h>  #include <linux/types.h>  #include <linux/pci.h> +#include <linux/sh_intc.h> -int __init pcibios_map_platform_irq(struct pci_dev *dev, u8 slot, u8 pin) +int __init pcibios_map_platform_irq(const struct pci_dev *dev, u8 slot, u8 pin)  {  	int irq;  	if (dev->bus->number == 0) {  		switch (slot) { -		case 4: return 5;	/* eth0       */ -		case 8: return 5;	/* eth1       */ -		case 6: return 2;	/* PCI bridge */ +		case 4: return evt2irq(0x2a0);	/* eth0       */ +		case 8: return evt2irq(0x2a0);	/* eth1       */ +		case 6: return evt2irq(0x240);	/* PCI bridge */  		default:  			printk(KERN_ERR "PCI: Bad IRQ mapping request "  					"for slot %d\n", slot); -			return 2; +			return evt2irq(0x240);  		}  	} else {  		switch (pin) { -		case 0:   irq =  2; break; -		case 1:   irq =  2; break; -		case 2:   irq =  2; break; -		case 3:   irq =  2; break; -		case 4:   irq =  2; break; +		case 0:   irq =  evt2irq(0x240); break; +		case 1:   irq =  evt2irq(0x240); break; +		case 2:   irq =  evt2irq(0x240); break; +		case 3:   irq =  evt2irq(0x240); break; +		case 4:   irq =  evt2irq(0x240); break;  		default:  irq = -1; break;  		}  	} diff --git a/arch/sh/drivers/pci/fixups-snapgear.c b/arch/sh/drivers/pci/fixups-snapgear.c index 5a39ecc1adb..6e33ba4cd07 100644 --- a/arch/sh/drivers/pci/fixups-snapgear.c +++ b/arch/sh/drivers/pci/fixups-snapgear.c @@ -16,19 +16,20 @@  #include <linux/types.h>  #include <linux/init.h>  #include <linux/pci.h> +#include <linux/sh_intc.h>  #include "pci-sh4.h" -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)  {  	int irq = -1;  	switch (slot) {  	case 8:  /* the PCI bridge */ break; -	case 11: irq = 8;  break; /* USB    */ -	case 12: irq = 11; break; /* PCMCIA */ -	case 13: irq = 5;  break; /* eth0   */ -	case 14: irq = 8;  break; /* eth1   */ -	case 15: irq = 11; break; /* safenet (unused) */ +	case 11: irq = evt2irq(0x300); break; /* USB    */ +	case 12: irq = evt2irq(0x360); break; /* PCMCIA */ +	case 13: irq = evt2irq(0x2a0); break; /* eth0   */ +	case 14: irq = evt2irq(0x300); break; /* eth1   */ +	case 15: irq = evt2irq(0x360); break; /* safenet (unused) */  	}  	printk("PCI: Mapping SnapGear IRQ for slot %d, pin %c to irq %d\n", diff --git a/arch/sh/drivers/pci/fixups-titan.c b/arch/sh/drivers/pci/fixups-titan.c index 3a79fa8254a..bd1addb1b8b 100644 --- a/arch/sh/drivers/pci/fixups-titan.c +++ b/arch/sh/drivers/pci/fixups-titan.c @@ -27,7 +27,7 @@ static char titan_irq_tab[] __initdata = {  	TITAN_IRQ_USB,  }; -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)  {  	int irq = titan_irq_tab[slot]; diff --git a/arch/sh/drivers/pci/pci-sh5.c b/arch/sh/drivers/pci/pci-sh5.c index 0bf296c7879..16c1e721bf5 100644 --- a/arch/sh/drivers/pci/pci-sh5.c +++ b/arch/sh/drivers/pci/pci-sh5.c @@ -107,13 +107,13 @@ static int __init sh5pci_init(void)  	u32 uval;          if (request_irq(IRQ_ERR, pcish5_err_irq, -                        IRQF_DISABLED, "PCI Error",NULL) < 0) { +                        0, "PCI Error",NULL) < 0) {                  printk(KERN_ERR "PCISH5: Cannot hook PCI_PERR interrupt\n");                  return -EINVAL;          }          if (request_irq(IRQ_SERR, pcish5_serr_irq, -                        IRQF_DISABLED, "PCI SERR interrupt", NULL) < 0) { +                        0, "PCI SERR interrupt", NULL) < 0) {                  printk(KERN_ERR "PCISH5: Cannot hook PCI_SERR interrupt\n");                  return -EINVAL;          } diff --git a/arch/sh/drivers/pci/pci-sh7751.h b/arch/sh/drivers/pci/pci-sh7751.h index 4983a4d2035..5ede38c330d 100644 --- a/arch/sh/drivers/pci/pci-sh7751.h +++ b/arch/sh/drivers/pci/pci-sh7751.h @@ -61,7 +61,7 @@    #define SH7751_PCICONF3_BIST7      0x80000000  /* Bist Supported */    #define SH7751_PCICONF3_BIST6      0x40000000  /* Bist Executing */    #define SH7751_PCICONF3_BIST3_0    0x0F000000  /* Bist Passed */ -  #define SH7751_PCICONF3_HD7        0x00800000  /* Single Funtion device */ +  #define SH7751_PCICONF3_HD7        0x00800000  /* Single Function device */    #define SH7751_PCICONF3_HD6_0      0x007F0000  /* Configuration Layout */    #define SH7751_PCICONF3_LAT        0x0000FF00  /* Latency Timer */    #define SH7751_PCICONF3_CLS        0x000000FF  /* Cache Line Size */ diff --git a/arch/sh/drivers/pci/pci-sh7780.c b/arch/sh/drivers/pci/pci-sh7780.c index edb7cca1488..5a6dab6e27d 100644 --- a/arch/sh/drivers/pci/pci-sh7780.c +++ b/arch/sh/drivers/pci/pci-sh7780.c @@ -21,6 +21,13 @@  #include <asm/mmu.h>  #include <asm/sizes.h> +#if defined(CONFIG_CPU_BIG_ENDIAN) +# define PCICR_ENDIANNESS SH4_PCICR_BSWP +#else +# define PCICR_ENDIANNESS 0 +#endif + +  static struct resource sh7785_pci_resources[] = {  	{  		.name	= "PCI IO", @@ -74,7 +81,7 @@ struct pci_errors {  	{ SH4_PCIINT_MLCK,	"master lock error" },  	{ SH4_PCIINT_TABT,	"target-target abort" },  	{ SH4_PCIINT_TRET,	"target retry time out" }, -	{ SH4_PCIINT_MFDE,	"master function disable erorr" }, +	{ SH4_PCIINT_MFDE,	"master function disable error" },  	{ SH4_PCIINT_PRTY,	"address parity error" },  	{ SH4_PCIINT_SERR,	"SERR" },  	{ SH4_PCIINT_TWDP,	"data parity error for target write" }, @@ -172,7 +179,7 @@ static int __init sh7780_pci_setup_irqs(struct pci_channel *hose)  		     PCI_STATUS_SIG_TARGET_ABORT | \  		     PCI_STATUS_PARITY, hose->reg_base + PCI_STATUS); -	ret = request_irq(hose->serr_irq, sh7780_pci_serr_irq, IRQF_DISABLED, +	ret = request_irq(hose->serr_irq, sh7780_pci_serr_irq, 0,  			  "PCI SERR interrupt", hose);  	if (unlikely(ret)) {  		printk(KERN_ERR "PCI: Failed hooking SERR IRQ\n"); @@ -254,7 +261,7 @@ static int __init sh7780_pci_init(void)  	__raw_writel(PCIECR_ENBL, PCIECR);  	/* Reset */ -	__raw_writel(SH4_PCICR_PREFIX | SH4_PCICR_PRST, +	__raw_writel(SH4_PCICR_PREFIX | SH4_PCICR_PRST | PCICR_ENDIANNESS,  		     chan->reg_base + SH4_PCICR);  	/* @@ -290,7 +297,8 @@ static int __init sh7780_pci_init(void)  	 * Now throw it in to register initialization mode and  	 * start the real work.  	 */ -	__raw_writel(SH4_PCICR_PREFIX, chan->reg_base + SH4_PCICR); +	__raw_writel(SH4_PCICR_PREFIX | PCICR_ENDIANNESS, +		     chan->reg_base + SH4_PCICR);  	memphys = __pa(memory_start);  	memsize = roundup_pow_of_two(memory_end - memory_start); @@ -380,7 +388,8 @@ static int __init sh7780_pci_init(void)  	 * Initialization mode complete, release the control register and  	 * enable round robin mode to stop device overruns/starvation.  	 */ -	__raw_writel(SH4_PCICR_PREFIX | SH4_PCICR_CFIN | SH4_PCICR_FTO, +	__raw_writel(SH4_PCICR_PREFIX | SH4_PCICR_CFIN | SH4_PCICR_FTO | +		     PCICR_ENDIANNESS,  		     chan->reg_base + SH4_PCICR);  	ret = register_pci_controller(chan); diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c index 60ee09a4e12..1bc09ee7948 100644 --- a/arch/sh/drivers/pci/pci.c +++ b/arch/sh/drivers/pci/pci.c @@ -20,6 +20,7 @@  #include <linux/io.h>  #include <linux/mutex.h>  #include <linux/spinlock.h> +#include <linux/export.h>  unsigned long PCIBIOS_MIN_IO = 0x0000;  unsigned long PCIBIOS_MIN_MEM = 0; @@ -31,19 +32,34 @@ static struct pci_channel *hose_head, **hose_tail = &hose_head;  static int pci_initialized; -static void __devinit pcibios_scanbus(struct pci_channel *hose) +static void pcibios_scanbus(struct pci_channel *hose)  {  	static int next_busno;  	static int need_domain_info; +	LIST_HEAD(resources); +	struct resource *res; +	resource_size_t offset; +	int i;  	struct pci_bus *bus; -	bus = pci_scan_bus(next_busno, hose->pci_ops, hose); +	for (i = 0; i < hose->nr_resources; i++) { +		res = hose->resources + i; +		offset = 0; +		if (res->flags & IORESOURCE_IO) +			offset = hose->io_offset; +		else if (res->flags & IORESOURCE_MEM) +			offset = hose->mem_offset; +		pci_add_resource_offset(&resources, res, offset); +	} + +	bus = pci_scan_root_bus(NULL, next_busno, hose->pci_ops, hose, +				&resources);  	hose->bus = bus;  	need_domain_info = need_domain_info || hose->index;  	hose->need_domain_info = need_domain_info;  	if (bus) { -		next_busno = bus->subordinate + 1; +		next_busno = bus->busn_res.end + 1;  		/* Don't allow 8-bit bus number overflow inside the hose -  		   reserve some space for bridges. */  		if (next_busno > 224) { @@ -53,7 +69,8 @@ static void __devinit pcibios_scanbus(struct pci_channel *hose)  		pci_bus_size_bridges(bus);  		pci_bus_assign_resources(bus); -		pci_enable_bridges(bus); +	} else { +		pci_free_resource_list(&resources);  	}  } @@ -64,7 +81,7 @@ static void __devinit pcibios_scanbus(struct pci_channel *hose)  DEFINE_RAW_SPINLOCK(pci_config_lock);  static DEFINE_MUTEX(pci_scan_mutex); -int __devinit register_pci_controller(struct pci_channel *hose) +int register_pci_controller(struct pci_channel *hose)  {  	int i; @@ -84,7 +101,7 @@ int __devinit register_pci_controller(struct pci_channel *hose)  	hose_tail = &hose->next;  	/* -	 * Do not panic here but later - this might hapen before console init. +	 * Do not panic here but later - this might happen before console init.  	 */  	if (!hose->io_map_base) {  		printk(KERN_WARNING @@ -134,50 +151,12 @@ static int __init pcibios_init(void)  }  subsys_initcall(pcibios_init); -static void pcibios_fixup_device_resources(struct pci_dev *dev, -	struct pci_bus *bus) -{ -	/* Update device resources.  */ -	struct pci_channel *hose = bus->sysdata; -	unsigned long offset = 0; -	int i; - -	for (i = 0; i < PCI_NUM_RESOURCES; i++) { -		if (!dev->resource[i].start) -			continue; -		if (dev->resource[i].flags & IORESOURCE_IO) -			offset = hose->io_offset; -		else if (dev->resource[i].flags & IORESOURCE_MEM) -			offset = hose->mem_offset; - -		dev->resource[i].start += offset; -		dev->resource[i].end += offset; -	} -} -  /*   *  Called after each bus is probed, but before its children   *  are examined.   */ -void __devinit pcibios_fixup_bus(struct pci_bus *bus) +void pcibios_fixup_bus(struct pci_bus *bus)  { -	struct pci_dev *dev = bus->self; -	struct list_head *ln; -	struct pci_channel *hose = bus->sysdata; - -	if (!dev) { -		int i; - -		for (i = 0; i < hose->nr_resources; i++) -			bus->resource[i] = hose->resources + i; -	} - -	for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) { -		dev = pci_dev_b(ln); - -		if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI) -			pcibios_fixup_device_resources(dev, bus); -	}  }  /* @@ -207,72 +186,6 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res,  	return start;  } -void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, -			     struct resource *res) -{ -	struct pci_channel *hose = dev->sysdata; -	unsigned long offset = 0; - -	if (res->flags & IORESOURCE_IO) -		offset = hose->io_offset; -	else if (res->flags & IORESOURCE_MEM) -		offset = hose->mem_offset; - -	region->start = res->start - offset; -	region->end = res->end - offset; -} - -void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, -			     struct pci_bus_region *region) -{ -	struct pci_channel *hose = dev->sysdata; -	unsigned long offset = 0; - -	if (res->flags & IORESOURCE_IO) -		offset = hose->io_offset; -	else if (res->flags & IORESOURCE_MEM) -		offset = hose->mem_offset; - -	res->start = region->start + offset; -	res->end = region->end + offset; -} - -int pcibios_enable_device(struct pci_dev *dev, int mask) -{ -	return pci_enable_resources(dev, mask); -} - -/* - *  If we set up a device for bus mastering, we need to check and set - *  the latency timer as it may not be properly set. - */ -static unsigned int pcibios_max_latency = 255; - -void pcibios_set_master(struct pci_dev *dev) -{ -	u8 lat; -	pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat); -	if (lat < 16) -		lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency; -	else if (lat > pcibios_max_latency) -		lat = pcibios_max_latency; -	else -		return; -	printk(KERN_INFO "PCI: Setting latency timer of device %s to %d\n", -	       pci_name(dev), lat); -	pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat); -} - -void __init pcibios_update_irq(struct pci_dev *dev, int irq) -{ -	pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); -} - -char * __devinit __weak pcibios_setup(char *str) -{ -	return str; -} -  static void __init  pcibios_bus_report_status_early(struct pci_channel *hose,  				int top_bus, int current_bus, @@ -376,46 +289,22 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,  #ifndef CONFIG_GENERIC_IOMAP -static void __iomem *ioport_map_pci(struct pci_dev *dev, -				    unsigned long port, unsigned int nr) +void __iomem *__pci_ioport_map(struct pci_dev *dev, +			       unsigned long port, unsigned int nr)  {  	struct pci_channel *chan = dev->sysdata;  	if (unlikely(!chan->io_map_base)) { -		chan->io_map_base = generic_io_base; +		chan->io_map_base = sh_io_port_base;  		if (pci_domains_supported)  			panic("To avoid data corruption io_map_base MUST be "  			      "set with multiple PCI domains.");  	} -  	return (void __iomem *)(chan->io_map_base + port);  } -void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen) -{ -	resource_size_t start = pci_resource_start(dev, bar); -	resource_size_t len = pci_resource_len(dev, bar); -	unsigned long flags = pci_resource_flags(dev, bar); - -	if (unlikely(!len || !start)) -		return NULL; -	if (maxlen && len > maxlen) -		len = maxlen; - -	if (flags & IORESOURCE_IO) -		return ioport_map_pci(dev, start, len); -	if (flags & IORESOURCE_MEM) { -		if (flags & IORESOURCE_CACHEABLE) -			return ioremap(start, len); -		return ioremap_nocache(start, len); -	} - -	return NULL; -} -EXPORT_SYMBOL(pci_iomap); -  void pci_iounmap(struct pci_dev *dev, void __iomem *addr)  {  	iounmap(addr); @@ -424,9 +313,5 @@ EXPORT_SYMBOL(pci_iounmap);  #endif /* CONFIG_GENERIC_IOMAP */ -#ifdef CONFIG_HOTPLUG -EXPORT_SYMBOL(pcibios_resource_to_bus); -EXPORT_SYMBOL(pcibios_bus_to_resource);  EXPORT_SYMBOL(PCIBIOS_MIN_IO);  EXPORT_SYMBOL(PCIBIOS_MIN_MEM); -#endif 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;  } diff --git a/arch/sh/drivers/pci/pcie-sh7786.h b/arch/sh/drivers/pci/pcie-sh7786.h index 1ee054e47ea..4a6ff55f759 100644 --- a/arch/sh/drivers/pci/pcie-sh7786.h +++ b/arch/sh/drivers/pci/pcie-sh7786.h @@ -145,9 +145,6 @@  /*	PCIERMSGIER	*/  #define	SH4A_PCIERMSGIER	(0x004040)	/* R/W - 0x0000 0000 32 */ -/*	PCIEPHYCTLR	*/ -#define SH4A_PCIEPHYCTLR	(0x010000)	/* R/W - 0x0000 0000 32 */ -  /*	PCIEPHYADRR	*/  #define	SH4A_PCIEPHYADRR	(0x010004)	/* R/W - 0x0000 0000 32 */  #define		BITS_ACK	(24)			// Rev1.171  | 
