Merge branch 'cleanup/io-pci' into next/cleanups

From Rob Herring <robherring2@gmail.com>:

This is the 2nd part of mach/io.h removals. This series removes io.h on
platforms with PCI by creating a fixed virtual I/O mapping and a common
__io() macro.

This version has changed a bit to accommodate Tegra converting its PCIe
host to a platform driver. Now the virtual space is only reserved during
early boot before .map_io() is called. The mapping is not created until
calling pci_ioremap_io which can be done at any point after vmalloc is
initialized.

I've gone back to fixed 64K windows for each PCI bus. This allows
removing all the i/o resource setup from the individually platforms and
placing it within the common ARM PCI code.

I've only tested versatilepb under qemu (with the model hacked up to
actually enable i/o space), so any testing is appreciated. iop3xx and
mv78xx0 have some risk of breaking as the PCI bus addresses are moved
to 0 from matching the cpu host bus addesss.

* cleanup/io-pci:
  ARM: iop3xx: use fixed PCI i/o mapping
  ARM: mv78xx0: use fixed pci i/o mapping
  ARM: iop13xx: use fixed PCI i/o mapping
  iop13xx: use more regular PCI I/O space handling
  ARM: orion5x: use fixed PCI i/o mapping
  ARM: kirkwood: use fixed PCI i/o mapping
  ARM: dove: use fixed PCI i/o mapping
  ARM: footbridge: use fixed PCI i/o mapping
  ARM: shark: use fixed PCI i/o mapping
  ARM: integrator: remove trailing whitespace on pci_v3.c
  ARM: integrator: use fixed PCI i/o mapping
  ARM: tegra: use fixed PCI i/o mapping
  ARM: versatile: use fixed PCI i/o mapping
  ARM: move PCI i/o resource setup into common code
  ARM: Add fixed PCI i/o mapping
  i2c: iop3xx: use standard gpiolib functions
  i2c: iop3xx: clean-up trailing whitespace

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
Arnd Bergmann 2012-08-13 16:56:29 +02:00
commit 19ec6caca2
56 changed files with 416 additions and 912 deletions

View File

@ -51,6 +51,9 @@ ffc00000 ffefffff DMA memory mapping region. Memory returned
ff000000 ffbfffff Reserved for future expansion of DMA
mapping region.
fee00000 feffffff Mapping of PCI I/O space. This is a static
mapping within the vmalloc space.
VMALLOC_START VMALLOC_END-1 vmalloc() / ioremap() space.
Memory returned by vmalloc/ioremap will
be dynamically placed in this region.

View File

@ -285,7 +285,6 @@ config ARCH_INTEGRATOR
select GENERIC_CLOCKEVENTS
select PLAT_VERSATILE
select PLAT_VERSATILE_FPGA_IRQ
select NEED_MACH_IO_H
select NEED_MACH_MEMORY_H
select SPARSE_IRQ
select MULTI_IRQ_HANDLER
@ -318,7 +317,6 @@ config ARCH_VERSATILE
select ICST
select GENERIC_CLOCKEVENTS
select ARCH_WANT_OPTIONAL_GPIOLIB
select NEED_MACH_IO_H if PCI
select PLAT_VERSATILE
select PLAT_VERSATILE_CLOCK
select PLAT_VERSATILE_CLCD
@ -462,7 +460,7 @@ config ARCH_FOOTBRIDGE
select FOOTBRIDGE
select GENERIC_CLOCKEVENTS
select HAVE_IDE
select NEED_MACH_IO_H
select NEED_MACH_IO_H if !MMU
select NEED_MACH_MEMORY_H
help
Support for systems based on the DC21285 companion chip
@ -519,7 +517,6 @@ config ARCH_IOP13XX
select PCI
select ARCH_SUPPORTS_MSI
select VMSPLIT_1G
select NEED_MACH_IO_H
select NEED_MACH_MEMORY_H
select NEED_RET_TO_USER
help
@ -529,7 +526,6 @@ config ARCH_IOP32X
bool "IOP32x-based"
depends on MMU
select CPU_XSCALE
select NEED_MACH_IO_H
select NEED_RET_TO_USER
select PLAT_IOP
select PCI
@ -542,7 +538,6 @@ config ARCH_IOP33X
bool "IOP33x-based"
depends on MMU
select CPU_XSCALE
select NEED_MACH_IO_H
select NEED_RET_TO_USER
select PLAT_IOP
select PCI
@ -582,7 +577,6 @@ config ARCH_DOVE
select PCI
select ARCH_REQUIRE_GPIOLIB
select GENERIC_CLOCKEVENTS
select NEED_MACH_IO_H
select PLAT_ORION
help
Support for the Marvell Dove SoC 88AP510
@ -593,7 +587,6 @@ config ARCH_KIRKWOOD
select PCI
select ARCH_REQUIRE_GPIOLIB
select GENERIC_CLOCKEVENTS
select NEED_MACH_IO_H
select PLAT_ORION
help
Support for the following Marvell Kirkwood series SoCs:
@ -620,7 +613,6 @@ config ARCH_MV78XX0
select PCI
select ARCH_REQUIRE_GPIOLIB
select GENERIC_CLOCKEVENTS
select NEED_MACH_IO_H
select PLAT_ORION
help
Support for the following Marvell MV78xx0 series SoCs:
@ -633,7 +625,6 @@ config ARCH_ORION5X
select PCI
select ARCH_REQUIRE_GPIOLIB
select GENERIC_CLOCKEVENTS
select NEED_MACH_IO_H
select PLAT_ORION
help
Support for the following Marvell Orion 5x series SoCs:
@ -689,7 +680,6 @@ config ARCH_TEGRA
select HAVE_CLK
select HAVE_SMP
select MIGHT_HAVE_CACHE_L2X0
select NEED_MACH_IO_H if PCI
select ARCH_HAS_CPUFREQ
select USE_OF
help
@ -918,7 +908,6 @@ config ARCH_SHARK
select PCI
select ARCH_USES_GETTIMEOFFSET
select NEED_MACH_MEMORY_H
select NEED_MACH_IO_H
help
Support for the StrongARM based Digital DNARD machine, also known
as "Shark" (<http://www.shark-linux.de/shark.html>).

View File

@ -217,18 +217,8 @@ extern int iop3xx_get_init_atu(void);
#define IOP3XX_PCI_LOWER_MEM_PA 0x80000000
#define IOP3XX_PCI_MEM_WINDOW_SIZE 0x08000000
#define IOP3XX_PCI_IO_WINDOW_SIZE 0x00010000
#define IOP3XX_PCI_LOWER_IO_PA 0x90000000
#define IOP3XX_PCI_LOWER_IO_VA 0xfe000000
#define IOP3XX_PCI_LOWER_IO_BA 0x90000000
#define IOP3XX_PCI_UPPER_IO_PA (IOP3XX_PCI_LOWER_IO_PA +\
IOP3XX_PCI_IO_WINDOW_SIZE - 1)
#define IOP3XX_PCI_UPPER_IO_VA (IOP3XX_PCI_LOWER_IO_VA +\
IOP3XX_PCI_IO_WINDOW_SIZE - 1)
#define IOP3XX_PCI_IO_PHYS_TO_VIRT(addr) (((u32) (addr) -\
IOP3XX_PCI_LOWER_IO_PA) +\
IOP3XX_PCI_LOWER_IO_VA)
#define IOP3XX_PCI_LOWER_IO_BA 0x00000000
#ifndef __ASSEMBLY__

View File

@ -113,11 +113,19 @@ static inline void __iomem *__typesafe_io(unsigned long addr)
#define __iowmb() do { } while (0)
#endif
/* PCI fixed i/o mapping */
#define PCI_IO_VIRT_BASE 0xfee00000
extern int pci_ioremap_io(unsigned int offset, phys_addr_t phys_addr);
/*
* Now, pick up the machine-defined IO definitions
*/
#ifdef CONFIG_NEED_MACH_IO_H
#include <mach/io.h>
#elif defined(CONFIG_PCI)
#define IO_SPACE_LIMIT ((resource_size_t)0xfffff)
#define __io(a) __typesafe_io(PCI_IO_VIRT_BASE + ((a) & IO_SPACE_LIMIT))
#else
#define __io(a) __typesafe_io((a) & IO_SPACE_LIMIT)
#endif

View File

@ -9,6 +9,9 @@
*
* Page table mapping constructs and function prototypes
*/
#ifndef __ASM_MACH_MAP_H
#define __ASM_MACH_MAP_H
#include <asm/io.h>
struct map_desc {
@ -34,6 +37,8 @@ struct map_desc {
#ifdef CONFIG_MMU
extern void iotable_init(struct map_desc *, int);
extern void vm_reserve_area_early(unsigned long addr, unsigned long size,
void *caller);
struct mem_type;
extern const struct mem_type *get_mem_type(unsigned int type);
@ -44,4 +49,7 @@ extern int ioremap_page(unsigned long virt, unsigned long phys,
const struct mem_type *mtype);
#else
#define iotable_init(map,num) do { } while (0)
#define vm_reserve_area_early(a,s,c) do { } while (0)
#endif
#endif

View File

@ -11,6 +11,8 @@
#ifndef __ASM_MACH_PCI_H
#define __ASM_MACH_PCI_H
#include <linux/ioport.h>
struct pci_sys_data;
struct pci_ops;
struct pci_bus;
@ -42,6 +44,8 @@ struct pci_sys_data {
unsigned long io_offset; /* bus->cpu IO mapping offset */
struct pci_bus *bus; /* PCI bus */
struct list_head resources; /* root bus resources (apertures) */
struct resource io_res;
char io_res_name[12];
/* Bridge swizzling */
u8 (*swizzle)(struct pci_dev *, u8 *);
/* IRQ mapping */
@ -54,6 +58,15 @@ struct pci_sys_data {
*/
void pci_common_init(struct hw_pci *);
/*
* Setup early fixed I/O mapping.
*/
#if defined(CONFIG_PCI)
extern void pci_map_io_early(unsigned long pfn);
#else
static inline void pci_map_io_early(unsigned long pfn) {}
#endif
/*
* PCI controllers
*/

View File

@ -13,6 +13,7 @@
#include <linux/io.h>
#include <asm/mach-types.h>
#include <asm/mach/map.h>
#include <asm/mach/pci.h>
static int debug_pci;
@ -423,6 +424,38 @@ static int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
return irq;
}
static int __init pcibios_init_resources(int busnr, struct pci_sys_data *sys)
{
int ret;
struct pci_host_bridge_window *window;
if (list_empty(&sys->resources)) {
pci_add_resource_offset(&sys->resources,
&iomem_resource, sys->mem_offset);
}
list_for_each_entry(window, &sys->resources, list) {
if (resource_type(window->res) == IORESOURCE_IO)
return 0;
}
sys->io_res.start = (busnr * SZ_64K) ? : pcibios_min_io;
sys->io_res.end = (busnr + 1) * SZ_64K - 1;
sys->io_res.flags = IORESOURCE_IO;
sys->io_res.name = sys->io_res_name;
sprintf(sys->io_res_name, "PCI%d I/O", busnr);
ret = request_resource(&ioport_resource, &sys->io_res);
if (ret) {
pr_err("PCI: unable to allocate I/O port region (%d)\n", ret);
return ret;
}
pci_add_resource_offset(&sys->resources, &sys->io_res,
sys->io_offset);
return 0;
}
static void __init pcibios_init_hw(struct hw_pci *hw, struct list_head *head)
{
struct pci_sys_data *sys = NULL;
@ -445,11 +478,10 @@ static void __init pcibios_init_hw(struct hw_pci *hw, struct list_head *head)
ret = hw->setup(nr, sys);
if (ret > 0) {
if (list_empty(&sys->resources)) {
pci_add_resource_offset(&sys->resources,
&ioport_resource, sys->io_offset);
pci_add_resource_offset(&sys->resources,
&iomem_resource, sys->mem_offset);
ret = pcibios_init_resources(nr, sys);
if (ret) {
kfree(sys);
break;
}
if (hw->scan)
@ -627,3 +659,15 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
return 0;
}
void __init pci_map_io_early(unsigned long pfn)
{
struct map_desc pci_io_desc = {
.virtual = PCI_IO_VIRT_BASE,
.type = MT_DEVICE,
.length = SZ_64K,
};
pci_io_desc.pfn = pfn;
iotable_init(&pci_io_desc, 1);
}

View File

@ -49,16 +49,6 @@ static struct map_desc dove_io_desc[] __initdata = {
.pfn = __phys_to_pfn(DOVE_NB_REGS_PHYS_BASE),
.length = DOVE_NB_REGS_SIZE,
.type = MT_DEVICE,
}, {
.virtual = DOVE_PCIE0_IO_VIRT_BASE,
.pfn = __phys_to_pfn(DOVE_PCIE0_IO_PHYS_BASE),
.length = DOVE_PCIE0_IO_SIZE,
.type = MT_DEVICE,
}, {
.virtual = DOVE_PCIE1_IO_VIRT_BASE,
.pfn = __phys_to_pfn(DOVE_PCIE1_IO_PHYS_BASE),
.length = DOVE_PCIE1_IO_SIZE,
.type = MT_DEVICE,
},
};

View File

@ -50,14 +50,12 @@
#define DOVE_NB_REGS_SIZE SZ_8M
#define DOVE_PCIE0_IO_PHYS_BASE 0xf2000000
#define DOVE_PCIE0_IO_VIRT_BASE 0xfee00000
#define DOVE_PCIE0_IO_BUS_BASE 0x00000000
#define DOVE_PCIE0_IO_SIZE SZ_1M
#define DOVE_PCIE0_IO_SIZE SZ_64K
#define DOVE_PCIE1_IO_PHYS_BASE 0xf2100000
#define DOVE_PCIE1_IO_VIRT_BASE 0xfef00000
#define DOVE_PCIE1_IO_BUS_BASE 0x00100000
#define DOVE_PCIE1_IO_SIZE SZ_1M
#define DOVE_PCIE1_IO_BUS_BASE 0x00010000
#define DOVE_PCIE1_IO_SIZE SZ_64K
/*
* Dove Core Registers Map

View File

@ -1,19 +0,0 @@
/*
* arch/arm/mach-dove/include/mach/io.h
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#ifndef __ASM_ARCH_IO_H
#define __ASM_ARCH_IO_H
#include "dove.h"
#define IO_SPACE_LIMIT 0xffffffff
#define __io(a) ((void __iomem *)(((a) - DOVE_PCIE0_IO_BUS_BASE) + \
DOVE_PCIE0_IO_VIRT_BASE))
#endif

View File

@ -26,9 +26,8 @@ struct pcie_port {
u8 root_bus_nr;
void __iomem *base;
spinlock_t conf_lock;
char io_space_name[16];
char mem_space_name[16];
struct resource res[2];
struct resource res;
};
static struct pcie_port pcie_port[2];
@ -53,24 +52,10 @@ static int __init dove_pcie_setup(int nr, struct pci_sys_data *sys)
orion_pcie_setup(pp->base);
/*
* IORESOURCE_IO
*/
snprintf(pp->io_space_name, sizeof(pp->io_space_name),
"PCIe %d I/O", pp->index);
pp->io_space_name[sizeof(pp->io_space_name) - 1] = 0;
pp->res[0].name = pp->io_space_name;
if (pp->index == 0) {
pp->res[0].start = DOVE_PCIE0_IO_PHYS_BASE;
pp->res[0].end = pp->res[0].start + DOVE_PCIE0_IO_SIZE - 1;
} else {
pp->res[0].start = DOVE_PCIE1_IO_PHYS_BASE;
pp->res[0].end = pp->res[0].start + DOVE_PCIE1_IO_SIZE - 1;
}
pp->res[0].flags = IORESOURCE_IO;
if (request_resource(&ioport_resource, &pp->res[0]))
panic("Request PCIe IO resource failed\n");
pci_add_resource_offset(&sys->resources, &pp->res[0], sys->io_offset);
if (pp->index == 0)
pci_ioremap_io(sys->busnr * SZ_64K, DOVE_PCIE0_IO_PHYS_BASE);
else
pci_ioremap_io(sys->busnr * SZ_64K, DOVE_PCIE1_IO_PHYS_BASE);
/*
* IORESOURCE_MEM
@ -78,18 +63,18 @@ static int __init dove_pcie_setup(int nr, struct pci_sys_data *sys)
snprintf(pp->mem_space_name, sizeof(pp->mem_space_name),
"PCIe %d MEM", pp->index);
pp->mem_space_name[sizeof(pp->mem_space_name) - 1] = 0;
pp->res[1].name = pp->mem_space_name;
pp->res.name = pp->mem_space_name;
if (pp->index == 0) {
pp->res[1].start = DOVE_PCIE0_MEM_PHYS_BASE;
pp->res[1].end = pp->res[1].start + DOVE_PCIE0_MEM_SIZE - 1;
pp->res.start = DOVE_PCIE0_MEM_PHYS_BASE;
pp->res.end = pp->res.start + DOVE_PCIE0_MEM_SIZE - 1;
} else {
pp->res[1].start = DOVE_PCIE1_MEM_PHYS_BASE;
pp->res[1].end = pp->res[1].start + DOVE_PCIE1_MEM_SIZE - 1;
pp->res.start = DOVE_PCIE1_MEM_PHYS_BASE;
pp->res.end = pp->res.start + DOVE_PCIE1_MEM_SIZE - 1;
}
pp->res[1].flags = IORESOURCE_MEM;
if (request_resource(&iomem_resource, &pp->res[1]))
pp->res.flags = IORESOURCE_MEM;
if (request_resource(&iomem_resource, &pp->res))
panic("Request PCIe Memory resource failed\n");
pci_add_resource_offset(&sys->resources, &pp->res[1], sys->mem_offset);
pci_add_resource_offset(&sys->resources, &pp->res, sys->mem_offset);
return 1;
}
@ -210,7 +195,7 @@ static void __init add_pcie_port(int index, unsigned long base)
pp->root_bus_nr = -1;
pp->base = (void __iomem *)base;
spin_lock_init(&pp->conf_lock);
memset(pp->res, 0, sizeof(pp->res));
memset(&pp->res, 0, sizeof(pp->res));
} else {
printk(KERN_INFO "link down, ignoring\n");
}

View File

@ -15,7 +15,7 @@
#include <linux/init.h>
#include <linux/io.h>
#include <linux/spinlock.h>
#include <asm/pgtable.h>
#include <asm/page.h>
#include <asm/irq.h>
@ -26,6 +26,7 @@
#include <asm/mach/irq.h>
#include <asm/mach/map.h>
#include <asm/mach/pci.h>
#include "common.h"
@ -175,11 +176,6 @@ static struct map_desc ebsa285_host_io_desc[] __initdata = {
.pfn = __phys_to_pfn(DC21285_PCI_IACK),
.length = PCIIACK_SIZE,
.type = MT_DEVICE,
}, {
.virtual = PCIO_BASE,
.pfn = __phys_to_pfn(DC21285_PCI_IO),
.length = PCIO_SIZE,
.type = MT_DEVICE,
},
#endif
};
@ -196,8 +192,10 @@ void __init footbridge_map_io(void)
* Now, work out what we've got to map in addition on this
* platform.
*/
if (footbridge_cfn_mode())
if (footbridge_cfn_mode()) {
iotable_init(ebsa285_host_io_desc, ARRAY_SIZE(ebsa285_host_io_desc));
pci_map_io_early(__phys_to_pfn(DC21285_PCI_IO));
}
}
void footbridge_restart(char mode, const char *cmd)

View File

@ -276,8 +276,8 @@ int __init dc21285_setup(int nr, struct pci_sys_data *sys)
sys->mem_offset = DC21285_PCI_MEM;
pci_add_resource_offset(&sys->resources,
&ioport_resource, sys->io_offset);
pci_ioremap_io(0, DC21285_PCI_IO);
pci_add_resource_offset(&sys->resources, &res[0], sys->mem_offset);
pci_add_resource_offset(&sys->resources, &res[1], sys->mem_offset);
@ -298,7 +298,7 @@ void __init dc21285_preinit(void)
mem_size = (unsigned int)high_memory - PAGE_OFFSET;
for (mem_mask = 0x00100000; mem_mask < 0x10000000; mem_mask <<= 1)
if (mem_mask >= mem_size)
break;
break;
/*
* These registers need to be set up whether we're the
@ -350,14 +350,6 @@ void __init dc21285_preinit(void)
"PCI data parity", NULL);
if (cfn_mode) {
static struct resource csrio;
csrio.flags = IORESOURCE_IO;
csrio.name = "Footbridge";
allocate_resource(&ioport_resource, &csrio, 128,
0xff00, 0xffff, 128, NULL, NULL);
/*
* Map our SDRAM at a known address in PCI space, just in case
* the firmware had other ideas. Using a nonzero base is
@ -365,7 +357,7 @@ void __init dc21285_preinit(void)
* in the range 0x000a0000 to 0x000c0000. (eg, S3 cards).
*/
*CSR_PCICSRBASE = 0xf4000000;
*CSR_PCICSRIOBASE = csrio.start;
*CSR_PCICSRIOBASE = 0;
*CSR_PCISDRAMBASE = __virt_to_bus(PAGE_OFFSET);
*CSR_PCIROMBASE = 0;
*CSR_PCICMD = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |

View File

@ -17,7 +17,8 @@
/* For NetWinder debugging */
.macro addruart, rp, rv, tmp
mov \rp, #0x000003f8
orr \rv, \rp, #0xff000000 @ virtual
orr \rv, \rp, #0xfe000000 @ virtual
orr \rv, \rv, #0x00e00000 @ virtual
orr \rp, \rp, #0x7c000000 @ physical
.endm

View File

@ -14,18 +14,10 @@
#ifndef __ASM_ARM_ARCH_IO_H
#define __ASM_ARM_ARCH_IO_H
#ifdef CONFIG_MMU
#define MMU_IO(a, b) (a)
#else
#define MMU_IO(a, b) (b)
#endif
#define PCIO_SIZE 0x00100000
#define PCIO_BASE MMU_IO(0xff000000, 0x7c000000)
/*
* Translation of various region addresses to virtual addresses
* Translation of various i/o addresses to host addresses for !CONFIG_MMU
*/
#define PCIO_BASE 0x7c000000
#define __io(a) ((void __iomem *)(PCIO_BASE + (a)))
#endif

View File

@ -1,33 +0,0 @@
/*
* arch/arm/mach-integrator/include/mach/io.h
*
* Copyright (C) 1999 ARM Limited
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __ASM_ARM_ARCH_IO_H
#define __ASM_ARM_ARCH_IO_H
/*
* WARNING: this has to mirror definitions in platform.h
*/
#define PCI_MEMORY_VADDR 0xe8000000
#define PCI_CONFIG_VADDR 0xec000000
#define PCI_V3_VADDR 0xed000000
#define PCI_IO_VADDR 0xee000000
#define __io(a) ((void __iomem *)(PCI_IO_VADDR + (a)))
#endif

View File

@ -324,6 +324,10 @@
*/
#define PHYS_PCI_V3_BASE 0x62000000
#define PCI_MEMORY_VADDR 0xe8000000
#define PCI_CONFIG_VADDR 0xec000000
#define PCI_V3_VADDR 0xed000000
/* ------------------------------------------------------------------------
* Integrator Interrupt Controllers
* ------------------------------------------------------------------------

View File

@ -50,6 +50,7 @@
#include <asm/mach/arch.h>
#include <asm/mach/irq.h>
#include <asm/mach/map.h>
#include <asm/mach/pci.h>
#include <asm/mach/time.h>
#include <plat/fpga-irq.h>
@ -73,7 +74,7 @@
* e8000000 40000000 PCI memory PHYS_PCI_MEM_BASE (max 512M)
* ec000000 61000000 PCI config space PHYS_PCI_CONFIG_BASE (max 16M)
* ed000000 62000000 PCI V3 regs PHYS_PCI_V3_BASE (max 64k)
* ee000000 60000000 PCI IO PHYS_PCI_IO_BASE (max 16M)
* fee00000 60000000 PCI IO PHYS_PCI_IO_BASE (max 16M)
* ef000000 Cache flush
* f1000000 10000000 Core module registers
* f1100000 11000000 System controller registers
@ -147,11 +148,6 @@ static struct map_desc ap_io_desc[] __initdata = {
.pfn = __phys_to_pfn(PHYS_PCI_V3_BASE),
.length = SZ_64K,
.type = MT_DEVICE
}, {
.virtual = PCI_IO_VADDR,
.pfn = __phys_to_pfn(PHYS_PCI_IO_BASE),
.length = SZ_64K,
.type = MT_DEVICE
}
};
@ -159,6 +155,7 @@ static void __init ap_map_io(void)
{
iotable_init(ap_io_desc, ARRAY_SIZE(ap_io_desc));
vga_base = PCI_MEMORY_VADDR;
pci_map_io_early(__phys_to_pfn(PHYS_PCI_IO_BASE));
}
#define INTEGRATOR_SC_VALID_INT 0x003fffff

View File

@ -41,61 +41,61 @@
/*
* The V3 PCI interface chip in Integrator provides several windows from
* local bus memory into the PCI memory areas. Unfortunately, there
* are not really enough windows for our usage, therefore we reuse
* are not really enough windows for our usage, therefore we reuse
* one of the windows for access to PCI configuration space. The
* memory map is as follows:
*
*
* Local Bus Memory Usage
*
*
* 40000000 - 4FFFFFFF PCI memory. 256M non-prefetchable
* 50000000 - 5FFFFFFF PCI memory. 256M prefetchable
* 60000000 - 60FFFFFF PCI IO. 16M
* 61000000 - 61FFFFFF PCI Configuration. 16M
*
*
* There are three V3 windows, each described by a pair of V3 registers.
* These are LB_BASE0/LB_MAP0, LB_BASE1/LB_MAP1 and LB_BASE2/LB_MAP2.
* Base0 and Base1 can be used for any type of PCI memory access. Base2
* can be used either for PCI I/O or for I20 accesses. By default, uHAL
* uses this only for PCI IO space.
*
*
* Normally these spaces are mapped using the following base registers:
*
*
* Usage Local Bus Memory Base/Map registers used
*
*
* Mem 40000000 - 4FFFFFFF LB_BASE0/LB_MAP0
* Mem 50000000 - 5FFFFFFF LB_BASE1/LB_MAP1
* IO 60000000 - 60FFFFFF LB_BASE2/LB_MAP2
* Cfg 61000000 - 61FFFFFF
*
*
* This means that I20 and PCI configuration space accesses will fail.
* When PCI configuration accesses are needed (via the uHAL PCI
* When PCI configuration accesses are needed (via the uHAL PCI
* configuration space primitives) we must remap the spaces as follows:
*
*
* Usage Local Bus Memory Base/Map registers used
*
*
* Mem 40000000 - 4FFFFFFF LB_BASE0/LB_MAP0
* Mem 50000000 - 5FFFFFFF LB_BASE0/LB_MAP0
* IO 60000000 - 60FFFFFF LB_BASE2/LB_MAP2
* Cfg 61000000 - 61FFFFFF LB_BASE1/LB_MAP1
*
*
* To make this work, the code depends on overlapping windows working.
* The V3 chip translates an address by checking its range within
* The V3 chip translates an address by checking its range within
* each of the BASE/MAP pairs in turn (in ascending register number
* order). It will use the first matching pair. So, for example,
* if the same address is mapped by both LB_BASE0/LB_MAP0 and
* LB_BASE1/LB_MAP1, the V3 will use the translation from
* LB_BASE1/LB_MAP1, the V3 will use the translation from
* LB_BASE0/LB_MAP0.
*
*
* To allow PCI Configuration space access, the code enlarges the
* window mapped by LB_BASE0/LB_MAP0 from 256M to 512M. This occludes
* the windows currently mapped by LB_BASE1/LB_MAP1 so that it can
* be remapped for use by configuration cycles.
*
* At the end of the PCI Configuration space accesses,
*
* At the end of the PCI Configuration space accesses,
* LB_BASE1/LB_MAP1 is reset to map PCI Memory. Finally the window
* mapped by LB_BASE0/LB_MAP0 is reduced in size from 512M to 256M to
* reveal the now restored LB_BASE1/LB_MAP1 window.
*
*
* NOTE: We do not set up I2O mapping. I suspect that this is only
* for an intelligent (target) device. Using I2O disables most of
* the mappings into PCI memory.
@ -127,8 +127,8 @@
*
* returns: configuration address to play on the PCI bus
*
* To generate the appropriate PCI configuration cycles in the PCI
* configuration address space, you present the V3 with the following pattern
* To generate the appropriate PCI configuration cycles in the PCI
* configuration address space, you present the V3 with the following pattern
* (which is very nearly a type 1 (except that the lower two bits are 00 and
* not 01). In order for this mapping to work you need to set up one of
* the local to PCI aperatures to 16Mbytes in length translating to
@ -138,7 +138,7 @@
*
* Type 0:
*
* 3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1
* 3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1
* 3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | | |D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|F|F|F|R|R|R|R|R|R|0|0|
@ -150,7 +150,7 @@
*
* Type 1:
*
* 3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1
* 3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1
* 3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | | | | | | | | | | |B|B|B|B|B|B|B|B|D|D|D|D|D|F|F|F|R|R|R|R|R|R|0|1|
@ -161,7 +161,7 @@
* 15:11 Device number (5 bits)
* 10:8 function number
* 7:2 register number
*
*
*/
static DEFINE_RAW_SPINLOCK(v3_lock);
@ -374,12 +374,9 @@ static int __init pci_v3_setup_resources(struct pci_sys_data *sys)
}
/*
* the IO resource for this bus
* the mem resource for this bus
* the prefetch mem resource for this bus
*/
pci_add_resource_offset(&sys->resources,
&ioport_resource, sys->io_offset);
pci_add_resource_offset(&sys->resources, &non_mem, sys->mem_offset);
pci_add_resource_offset(&sys->resources, &pre_mem, sys->mem_offset);
@ -498,7 +495,6 @@ void __init pci_v3_preinit(void)
unsigned int temp;
int ret;
pcibios_min_io = 0x6000;
pcibios_min_mem = 0x00100000;
/*

View File

@ -1,28 +0,0 @@
/*
* iop13xx custom ioremap implementation
* Copyright (c) 2005-2006, Intel Corporation.
*
* 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.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307 USA.
*
*/
#ifndef __ASM_ARM_ARCH_IO_H
#define __ASM_ARM_ARCH_IO_H
#define IO_SPACE_LIMIT 0xffffffff
#define __io(a) __iop13xx_io(a)
extern void __iomem * __iop13xx_io(unsigned long io_addr);
#endif

View File

@ -69,21 +69,11 @@ extern unsigned long get_iop_tick_rate(void);
* 0x8000.0000 + 928M 0x2.8000.0000 (ioremap) PCIE outbound memory window
*
* IO MAP
* 0x1000 + 64K 0x0.fffb.1000 0xfec6.1000 PCIX outbound i/o window
* 0x1000 + 64K 0x0.fffd.1000 0xfed7.1000 PCIE outbound i/o window
* 0x00000 + 64K 0x0.fffb.0000 0xfee0.0000 PCIX outbound i/o window
* 0x10000 + 64K 0x0.fffd.0000 0xfee1.0000 PCIE outbound i/o window
*/
#define IOP13XX_PCIX_IO_WINDOW_SIZE 0x10000UL
#define IOP13XX_PCIX_LOWER_IO_PA 0xfffb0000UL
#define IOP13XX_PCIX_LOWER_IO_VA 0xfec60000UL
#define IOP13XX_PCIX_LOWER_IO_BA 0x0UL /* OIOTVR */
#define IOP13XX_PCIX_IO_BUS_OFFSET 0x1000UL
#define IOP13XX_PCIX_UPPER_IO_PA (IOP13XX_PCIX_LOWER_IO_PA +\
IOP13XX_PCIX_IO_WINDOW_SIZE - 1)
#define IOP13XX_PCIX_UPPER_IO_VA (IOP13XX_PCIX_LOWER_IO_VA +\
IOP13XX_PCIX_IO_WINDOW_SIZE - 1)
#define IOP13XX_PCIX_IO_PHYS_TO_VIRT(addr) (u32) ((u32) addr -\
(IOP13XX_PCIX_LOWER_IO_PA\
- IOP13XX_PCIX_LOWER_IO_VA))
#define IOP13XX_PCIX_MEM_PHYS_OFFSET 0x100000000ULL
#define IOP13XX_PCIX_MEM_WINDOW_SIZE 0x3a000000UL
@ -103,20 +93,8 @@ extern unsigned long get_iop_tick_rate(void);
IOP13XX_PCIX_LOWER_MEM_BA)
/* PCI-E ranges */
#define IOP13XX_PCIE_IO_WINDOW_SIZE 0x10000UL
#define IOP13XX_PCIE_LOWER_IO_PA 0xfffd0000UL
#define IOP13XX_PCIE_LOWER_IO_VA 0xfed70000UL
#define IOP13XX_PCIE_LOWER_IO_BA 0x0UL /* OIOTVR */
#define IOP13XX_PCIE_IO_BUS_OFFSET 0x1000UL
#define IOP13XX_PCIE_UPPER_IO_PA (IOP13XX_PCIE_LOWER_IO_PA +\
IOP13XX_PCIE_IO_WINDOW_SIZE - 1)
#define IOP13XX_PCIE_UPPER_IO_VA (IOP13XX_PCIE_LOWER_IO_VA +\
IOP13XX_PCIE_IO_WINDOW_SIZE - 1)
#define IOP13XX_PCIE_UPPER_IO_BA (IOP13XX_PCIE_LOWER_IO_BA +\
IOP13XX_PCIE_IO_WINDOW_SIZE - 1)
#define IOP13XX_PCIE_IO_PHYS_TO_VIRT(addr) (u32) ((u32) addr -\
(IOP13XX_PCIE_LOWER_IO_PA\
- IOP13XX_PCIE_LOWER_IO_VA))
#define IOP13XX_PCIE_LOWER_IO_BA 0x10000UL /* OIOTVR */
#define IOP13XX_PCIE_MEM_PHYS_OFFSET 0x200000000ULL
#define IOP13XX_PCIE_MEM_WINDOW_SIZE 0x3a000000UL

View File

@ -23,25 +23,6 @@
#include "pci.h"
void * __iomem __iop13xx_io(unsigned long io_addr)
{
void __iomem * io_virt;
switch (io_addr) {
case IOP13XX_PCIE_LOWER_IO_PA ... IOP13XX_PCIE_UPPER_IO_PA:
io_virt = (void *) IOP13XX_PCIE_IO_PHYS_TO_VIRT(io_addr);
break;
case IOP13XX_PCIX_LOWER_IO_PA ... IOP13XX_PCIX_UPPER_IO_PA:
io_virt = (void *) IOP13XX_PCIX_IO_PHYS_TO_VIRT(io_addr);
break;
default:
BUG();
}
return io_virt;
}
EXPORT_SYMBOL(__iop13xx_io);
static void __iomem *__iop13xx_ioremap_caller(unsigned long cookie,
size_t size, unsigned int mtype, void *caller)
{
@ -67,12 +48,6 @@ static void __iomem *__iop13xx_ioremap_caller(unsigned long cookie,
(cookie - IOP13XX_PBI_LOWER_MEM_RA),
size, mtype, __builtin_return_address(0));
break;
case IOP13XX_PCIE_LOWER_IO_PA ... IOP13XX_PCIE_UPPER_IO_PA:
retval = (void *) IOP13XX_PCIE_IO_PHYS_TO_VIRT(cookie);
break;
case IOP13XX_PCIX_LOWER_IO_PA ... IOP13XX_PCIX_UPPER_IO_PA:
retval = (void *) IOP13XX_PCIX_IO_PHYS_TO_VIRT(cookie);
break;
case IOP13XX_PMMR_PHYS_MEM_BASE ... IOP13XX_PMMR_UPPER_MEM_PA:
retval = (void *) IOP13XX_PMMR_PHYS_TO_VIRT(cookie);
break;
@ -99,8 +74,6 @@ static void __iop13xx_iounmap(volatile void __iomem *addr)
goto skip;
switch ((u32) addr) {
case IOP13XX_PCIE_LOWER_IO_VA ... IOP13XX_PCIE_UPPER_IO_VA:
case IOP13XX_PCIX_LOWER_IO_VA ... IOP13XX_PCIX_UPPER_IO_VA:
case IOP13XX_PMMR_VIRT_MEM_BASE ... IOP13XX_PMMR_UPPER_MEM_VA:
goto skip;
}

View File

@ -970,7 +970,6 @@ void __init iop13xx_pci_init(void)
__raw_writel(__raw_readl(IOP13XX_XBG_BECSR) & 3, IOP13XX_XBG_BECSR);
/* Setup the Min Address for PCI memory... */
pcibios_min_io = 0;
pcibios_min_mem = IOP13XX_PCIX_LOWER_MEM_BA;
/* if Linux is given control of an ATU
@ -1003,7 +1002,7 @@ int iop13xx_pci_setup(int nr, struct pci_sys_data *sys)
if (nr > 1)
return 0;
res = kcalloc(2, sizeof(struct resource), GFP_KERNEL);
res = kzalloc(sizeof(struct resource), GFP_KERNEL);
if (!res)
panic("PCI: unable to alloc resources");
@ -1042,17 +1041,13 @@ int iop13xx_pci_setup(int nr, struct pci_sys_data *sys)
<< IOP13XX_ATUX_PCIXSR_FUNC_NUM;
__raw_writel(pcixsr, IOP13XX_ATUX_PCIXSR);
res[0].start = IOP13XX_PCIX_LOWER_IO_PA + IOP13XX_PCIX_IO_BUS_OFFSET;
res[0].end = IOP13XX_PCIX_UPPER_IO_PA;
res[0].name = "IQ81340 ATUX PCI I/O Space";
res[0].flags = IORESOURCE_IO;
pci_ioremap_io(0, IOP13XX_PCIX_LOWER_IO_PA);
res[1].start = IOP13XX_PCIX_LOWER_MEM_RA;
res[1].end = IOP13XX_PCIX_UPPER_MEM_RA;
res[1].name = "IQ81340 ATUX PCI Memory Space";
res[1].flags = IORESOURCE_MEM;
res->start = IOP13XX_PCIX_LOWER_MEM_RA;
res->end = IOP13XX_PCIX_UPPER_MEM_RA;
res->name = "IQ81340 ATUX PCI Memory Space";
res->flags = IORESOURCE_MEM;
sys->mem_offset = IOP13XX_PCIX_MEM_OFFSET;
sys->io_offset = IOP13XX_PCIX_LOWER_IO_PA;
break;
case IOP13XX_INIT_ATU_ATUE:
/* Note: the function number field in the PCSR is ro */
@ -1063,17 +1058,13 @@ int iop13xx_pci_setup(int nr, struct pci_sys_data *sys)
__raw_writel(pcsr, IOP13XX_ATUE_PCSR);
res[0].start = IOP13XX_PCIE_LOWER_IO_PA + IOP13XX_PCIE_IO_BUS_OFFSET;
res[0].end = IOP13XX_PCIE_UPPER_IO_PA;
res[0].name = "IQ81340 ATUE PCI I/O Space";
res[0].flags = IORESOURCE_IO;
pci_ioremap_io(SZ_64K, IOP13XX_PCIE_LOWER_IO_PA);
res[1].start = IOP13XX_PCIE_LOWER_MEM_RA;
res[1].end = IOP13XX_PCIE_UPPER_MEM_RA;
res[1].name = "IQ81340 ATUE PCI Memory Space";
res[1].flags = IORESOURCE_MEM;
res->start = IOP13XX_PCIE_LOWER_MEM_RA;
res->end = IOP13XX_PCIE_UPPER_MEM_RA;
res->name = "IQ81340 ATUE PCI Memory Space";
res->flags = IORESOURCE_MEM;
sys->mem_offset = IOP13XX_PCIE_MEM_OFFSET;
sys->io_offset = IOP13XX_PCIE_LOWER_IO_PA;
sys->map_irq = iop13xx_pcie_map_irq;
break;
default:
@ -1081,11 +1072,9 @@ int iop13xx_pci_setup(int nr, struct pci_sys_data *sys)
return 0;
}
request_resource(&ioport_resource, &res[0]);
request_resource(&iomem_resource, &res[1]);
request_resource(&iomem_resource, res);
pci_add_resource_offset(&sys->resources, &res[0], sys->io_offset);
pci_add_resource_offset(&sys->resources, &res[1], sys->mem_offset);
pci_add_resource_offset(&sys->resources, res, sys->mem_offset);
return 1;
}

View File

@ -40,16 +40,6 @@ static struct map_desc iop13xx_std_desc[] __initdata = {
.pfn = __phys_to_pfn(IOP13XX_PMMR_PHYS_MEM_BASE),
.length = IOP13XX_PMMR_SIZE,
.type = MT_DEVICE,
}, { /* PCIE IO space */
.virtual = IOP13XX_PCIE_LOWER_IO_VA,
.pfn = __phys_to_pfn(IOP13XX_PCIE_LOWER_IO_PA),
.length = IOP13XX_PCIX_IO_WINDOW_SIZE,
.type = MT_DEVICE,
}, { /* PCIX IO space */
.virtual = IOP13XX_PCIX_LOWER_IO_VA,
.pfn = __phys_to_pfn(IOP13XX_PCIX_LOWER_IO_PA),
.length = IOP13XX_PCIX_IO_WINDOW_SIZE,
.type = MT_DEVICE,
},
};

View File

@ -1,19 +0,0 @@
/*
* arch/arm/mach-iop32x/include/mach/io.h
*
* Copyright (C) 2001 MontaVista Software, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef __IO_H
#define __IO_H
#include <asm/hardware/iop3xx.h>
#define IO_SPACE_LIMIT 0xffffffff
#define __io(p) ((void __iomem *)IOP3XX_PCI_IO_PHYS_TO_VIRT(p))
#endif

View File

@ -1,19 +0,0 @@
/*
* arch/arm/mach-iop33x/include/mach/io.h
*
* Copyright (C) 2001 MontaVista Software, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef __IO_H
#define __IO_H
#include <asm/hardware/iop3xx.h>
#define IO_SPACE_LIMIT 0xffffffff
#define __io(p) ((void __iomem *)IOP3XX_PCI_IO_PHYS_TO_VIRT(p))
#endif

View File

@ -42,16 +42,6 @@
****************************************************************************/
static struct map_desc kirkwood_io_desc[] __initdata = {
{
.virtual = KIRKWOOD_PCIE_IO_VIRT_BASE,
.pfn = __phys_to_pfn(KIRKWOOD_PCIE_IO_PHYS_BASE),
.length = KIRKWOOD_PCIE_IO_SIZE,
.type = MT_DEVICE,
}, {
.virtual = KIRKWOOD_PCIE1_IO_VIRT_BASE,
.pfn = __phys_to_pfn(KIRKWOOD_PCIE1_IO_PHYS_BASE),
.length = KIRKWOOD_PCIE1_IO_SIZE,
.type = MT_DEVICE,
}, {
.virtual = KIRKWOOD_REGS_VIRT_BASE,
.pfn = __phys_to_pfn(KIRKWOOD_REGS_PHYS_BASE),
.length = KIRKWOOD_REGS_SIZE,

View File

@ -1,24 +0,0 @@
/*
* arch/arm/mach-kirkwood/include/mach/io.h
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#ifndef __ASM_ARCH_IO_H
#define __ASM_ARCH_IO_H
#include "kirkwood.h"
#define IO_SPACE_LIMIT 0xffffffff
static inline void __iomem *__io(unsigned long addr)
{
return (void __iomem *)((addr - KIRKWOOD_PCIE_IO_BUS_BASE)
+ KIRKWOOD_PCIE_IO_VIRT_BASE);
}
#define __io(a) __io(a)
#endif

View File

@ -37,14 +37,12 @@
#define KIRKWOOD_NAND_MEM_SIZE SZ_1K
#define KIRKWOOD_PCIE1_IO_PHYS_BASE 0xf3000000
#define KIRKWOOD_PCIE1_IO_VIRT_BASE 0xfef00000
#define KIRKWOOD_PCIE1_IO_BUS_BASE 0x00100000
#define KIRKWOOD_PCIE1_IO_SIZE SZ_1M
#define KIRKWOOD_PCIE1_IO_BUS_BASE 0x00010000
#define KIRKWOOD_PCIE1_IO_SIZE SZ_64K
#define KIRKWOOD_PCIE_IO_PHYS_BASE 0xf2000000
#define KIRKWOOD_PCIE_IO_VIRT_BASE 0xfee00000
#define KIRKWOOD_PCIE_IO_BUS_BASE 0x00000000
#define KIRKWOOD_PCIE_IO_SIZE SZ_1M
#define KIRKWOOD_PCIE_IO_SIZE SZ_64K
#define KIRKWOOD_REGS_PHYS_BASE 0xf1000000
#define KIRKWOOD_REGS_VIRT_BASE 0xfed00000

View File

@ -56,7 +56,7 @@ struct pcie_port {
void __iomem *base;
spinlock_t conf_lock;
int irq;
struct resource res[2];
struct resource res;
};
static int pcie_port_map[2];
@ -136,21 +136,13 @@ static void __init pcie0_ioresources_init(struct pcie_port *pp)
pp->base = (void __iomem *)PCIE_VIRT_BASE;
pp->irq = IRQ_KIRKWOOD_PCIE;
/*
* IORESOURCE_IO
*/
pp->res[0].name = "PCIe 0 I/O Space";
pp->res[0].start = KIRKWOOD_PCIE_IO_BUS_BASE;
pp->res[0].end = pp->res[0].start + KIRKWOOD_PCIE_IO_SIZE - 1;
pp->res[0].flags = IORESOURCE_IO;
/*
* IORESOURCE_MEM
*/
pp->res[1].name = "PCIe 0 MEM";
pp->res[1].start = KIRKWOOD_PCIE_MEM_PHYS_BASE;
pp->res[1].end = pp->res[1].start + KIRKWOOD_PCIE_MEM_SIZE - 1;
pp->res[1].flags = IORESOURCE_MEM;
pp->res.name = "PCIe 0 MEM";
pp->res.start = KIRKWOOD_PCIE_MEM_PHYS_BASE;
pp->res.end = pp->res.start + KIRKWOOD_PCIE_MEM_SIZE - 1;
pp->res.flags = IORESOURCE_MEM;
}
static void __init pcie1_ioresources_init(struct pcie_port *pp)
@ -158,21 +150,13 @@ static void __init pcie1_ioresources_init(struct pcie_port *pp)
pp->base = (void __iomem *)PCIE1_VIRT_BASE;
pp->irq = IRQ_KIRKWOOD_PCIE1;
/*
* IORESOURCE_IO
*/
pp->res[0].name = "PCIe 1 I/O Space";
pp->res[0].start = KIRKWOOD_PCIE1_IO_BUS_BASE;
pp->res[0].end = pp->res[0].start + KIRKWOOD_PCIE1_IO_SIZE - 1;
pp->res[0].flags = IORESOURCE_IO;
/*
* IORESOURCE_MEM
*/
pp->res[1].name = "PCIe 1 MEM";
pp->res[1].start = KIRKWOOD_PCIE1_MEM_PHYS_BASE;
pp->res[1].end = pp->res[1].start + KIRKWOOD_PCIE1_MEM_SIZE - 1;
pp->res[1].flags = IORESOURCE_MEM;
pp->res.name = "PCIe 1 MEM";
pp->res.start = KIRKWOOD_PCIE1_MEM_PHYS_BASE;
pp->res.end = pp->res.start + KIRKWOOD_PCIE1_MEM_SIZE - 1;
pp->res.flags = IORESOURCE_MEM;
}
static int __init kirkwood_pcie_setup(int nr, struct pci_sys_data *sys)
@ -197,23 +181,21 @@ static int __init kirkwood_pcie_setup(int nr, struct pci_sys_data *sys)
case 0:
kirkwood_enable_pcie_clk("0");
pcie0_ioresources_init(pp);
pci_ioremap_io(SZ_64K * sys->busnr, KIRKWOOD_PCIE_IO_PHYS_BASE);
break;
case 1:
kirkwood_enable_pcie_clk("1");
pcie1_ioresources_init(pp);
pci_ioremap_io(SZ_64K * sys->busnr, KIRKWOOD_PCIE1_IO_PHYS_BASE);
break;
default:
panic("PCIe setup: invalid controller %d", index);
}
if (request_resource(&ioport_resource, &pp->res[0]))
panic("Request PCIe%d IO resource failed\n", index);
if (request_resource(&iomem_resource, &pp->res[1]))
if (request_resource(&iomem_resource, &pp->res))
panic("Request PCIe%d Memory resource failed\n", index);
sys->io_offset = 0;
pci_add_resource_offset(&sys->resources, &pp->res[0], sys->io_offset);
pci_add_resource_offset(&sys->resources, &pp->res[1], sys->mem_offset);
pci_add_resource_offset(&sys->resources, &pp->res, sys->mem_offset);
/*
* Generic PCIe unit setup.

View File

@ -13,6 +13,7 @@
#include <linux/mbus.h>
#include <linux/io.h>
#include <plat/addr-map.h>
#include <mach/mv78xx0.h>
#include "common.h"
/*
@ -81,7 +82,7 @@ void __init mv78xx0_setup_pcie_io_win(int window, u32 base, u32 size,
int maj, int min)
{
orion_setup_cpu_win(&addr_map_cfg, window, base, size,
TARGET_PCIE(maj), ATTR_PCIE_IO(min), -1);
TARGET_PCIE(maj), ATTR_PCIE_IO(min), 0);
}
void __init mv78xx0_setup_pcie_mem_win(int window, u32 base, u32 size,

View File

@ -134,11 +134,6 @@ static struct map_desc mv78xx0_io_desc[] __initdata = {
.pfn = 0,
.length = MV78XX0_CORE_REGS_SIZE,
.type = MT_DEVICE,
}, {
.virtual = MV78XX0_PCIE_IO_VIRT_BASE(0),
.pfn = __phys_to_pfn(MV78XX0_PCIE_IO_PHYS_BASE(0)),
.length = MV78XX0_PCIE_IO_SIZE * 8,
.type = MT_DEVICE,
}, {
.virtual = MV78XX0_REGS_VIRT_BASE,
.pfn = __phys_to_pfn(MV78XX0_REGS_PHYS_BASE),

View File

@ -1,24 +0,0 @@
/*
* arch/arm/mach-mv78xx0/include/mach/io.h
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#ifndef __ASM_ARCH_IO_H
#define __ASM_ARCH_IO_H
#include "mv78xx0.h"
#define IO_SPACE_LIMIT 0xffffffff
static inline void __iomem *__io(unsigned long addr)
{
return (void __iomem *)((addr - MV78XX0_PCIE_IO_PHYS_BASE(0))
+ MV78XX0_PCIE_IO_VIRT_BASE(0));
}
#define __io(a) __io(a)
#endif

View File

@ -29,15 +29,15 @@
*
* virt phys size
* fe400000 f102x000 16K core-specific peripheral registers
* fe700000 f0800000 1M PCIe #0 I/O space
* fe800000 f0900000 1M PCIe #1 I/O space
* fe900000 f0a00000 1M PCIe #2 I/O space
* fea00000 f0b00000 1M PCIe #3 I/O space
* feb00000 f0c00000 1M PCIe #4 I/O space
* fec00000 f0d00000 1M PCIe #5 I/O space
* fed00000 f0e00000 1M PCIe #6 I/O space
* fee00000 f0f00000 1M PCIe #7 I/O space
* fef00000 f1000000 1M on-chip peripheral registers
* fee00000 f0800000 64K PCIe #0 I/O space
* fee10000 f0900000 64K PCIe #1 I/O space
* fee20000 f0a00000 64K PCIe #2 I/O space
* fee30000 f0b00000 64K PCIe #3 I/O space
* fee40000 f0c00000 64K PCIe #4 I/O space
* fee50000 f0d00000 64K PCIe #5 I/O space
* fee60000 f0e00000 64K PCIe #6 I/O space
* fee70000 f0f00000 64K PCIe #7 I/O space
* fd000000 f1000000 1M on-chip peripheral registers
*/
#define MV78XX0_CORE0_REGS_PHYS_BASE 0xf1020000
#define MV78XX0_CORE1_REGS_PHYS_BASE 0xf1024000
@ -46,11 +46,10 @@
#define MV78XX0_CORE_REGS_SIZE SZ_16K
#define MV78XX0_PCIE_IO_PHYS_BASE(i) (0xf0800000 + ((i) << 20))
#define MV78XX0_PCIE_IO_VIRT_BASE(i) (0xfe700000 + ((i) << 20))
#define MV78XX0_PCIE_IO_SIZE SZ_1M
#define MV78XX0_REGS_PHYS_BASE 0xf1000000
#define MV78XX0_REGS_VIRT_BASE 0xfef00000
#define MV78XX0_REGS_VIRT_BASE 0xfd000000
#define MV78XX0_REGS_SIZE SZ_1M
#define MV78XX0_PCIE_MEM_PHYS_BASE 0xc0000000

View File

@ -15,6 +15,7 @@
#include <asm/mach/pci.h>
#include <plat/pcie.h>
#include <plat/addr-map.h>
#include <mach/mv78xx0.h>
#include "common.h"
struct pcie_port {
@ -23,16 +24,13 @@ struct pcie_port {
u8 root_bus_nr;
void __iomem *base;
spinlock_t conf_lock;
char io_space_name[16];
char mem_space_name[16];
struct resource res[2];
struct resource res;
};
static struct pcie_port pcie_port[8];
static int num_pcie_ports;
static struct resource pcie_io_space;
static struct resource pcie_mem_space;
void __init mv78xx0_pcie_id(u32 *dev, u32 *rev)
{
@ -40,102 +38,59 @@ void __init mv78xx0_pcie_id(u32 *dev, u32 *rev)
*rev = orion_pcie_rev((void __iomem *)PCIE00_VIRT_BASE);
}
u32 pcie_port_size[8] = {
0,
0x30000000,
0x10000000,
0x10000000,
0x08000000,
0x08000000,
0x08000000,
0x04000000,
};
static void __init mv78xx0_pcie_preinit(void)
{
int i;
u32 size_each;
u32 start;
int win;
int win = 0;
pcie_io_space.name = "PCIe I/O Space";
pcie_io_space.start = MV78XX0_PCIE_IO_PHYS_BASE(0);
pcie_io_space.end =
MV78XX0_PCIE_IO_PHYS_BASE(0) + MV78XX0_PCIE_IO_SIZE * 8 - 1;
pcie_io_space.flags = IORESOURCE_IO;
pcie_io_space.flags = IORESOURCE_MEM;
if (request_resource(&iomem_resource, &pcie_io_space))
panic("can't allocate PCIe I/O space");
pcie_mem_space.name = "PCIe MEM Space";
pcie_mem_space.start = MV78XX0_PCIE_MEM_PHYS_BASE;
pcie_mem_space.end =
MV78XX0_PCIE_MEM_PHYS_BASE + MV78XX0_PCIE_MEM_SIZE - 1;
pcie_mem_space.flags = IORESOURCE_MEM;
if (request_resource(&iomem_resource, &pcie_mem_space))
panic("can't allocate PCIe MEM space");
for (i = 0; i < num_pcie_ports; i++) {
struct pcie_port *pp = pcie_port + i;
snprintf(pp->io_space_name, sizeof(pp->io_space_name),
"PCIe %d.%d I/O", pp->maj, pp->min);
pp->io_space_name[sizeof(pp->io_space_name) - 1] = 0;
pp->res[0].name = pp->io_space_name;
pp->res[0].start = MV78XX0_PCIE_IO_PHYS_BASE(i);
pp->res[0].end = pp->res[0].start + MV78XX0_PCIE_IO_SIZE - 1;
pp->res[0].flags = IORESOURCE_IO;
snprintf(pp->mem_space_name, sizeof(pp->mem_space_name),
"PCIe %d.%d MEM", pp->maj, pp->min);
pp->mem_space_name[sizeof(pp->mem_space_name) - 1] = 0;
pp->res[1].name = pp->mem_space_name;
pp->res[1].flags = IORESOURCE_MEM;
}
switch (num_pcie_ports) {
case 0:
size_each = 0;
break;
case 1:
size_each = 0x30000000;
break;
case 2 ... 3:
size_each = 0x10000000;
break;
case 4 ... 6:
size_each = 0x08000000;
break;
case 7:
size_each = 0x04000000;
break;
default:
if (num_pcie_ports > 7)
panic("invalid number of PCIe ports");
}
size_each = pcie_port_size[num_pcie_ports];
start = MV78XX0_PCIE_MEM_PHYS_BASE;
for (i = 0; i < num_pcie_ports; i++) {
struct pcie_port *pp = pcie_port + i;
pp->res[1].start = start;
pp->res[1].end = start + size_each - 1;
snprintf(pp->mem_space_name, sizeof(pp->mem_space_name),
"PCIe %d.%d MEM", pp->maj, pp->min);
pp->mem_space_name[sizeof(pp->mem_space_name) - 1] = 0;
pp->res.name = pp->mem_space_name;
pp->res.flags = IORESOURCE_MEM;
pp->res.start = start;
pp->res.end = start + size_each - 1;
start += size_each;
}
for (i = 0; i < num_pcie_ports; i++) {
struct pcie_port *pp = pcie_port + i;
if (request_resource(&pcie_io_space, &pp->res[0]))
panic("can't allocate PCIe I/O sub-space");
if (request_resource(&pcie_mem_space, &pp->res[1]))
if (request_resource(&iomem_resource, &pp->res))
panic("can't allocate PCIe MEM sub-space");
}
win = 0;
for (i = 0; i < num_pcie_ports; i++) {
struct pcie_port *pp = pcie_port + i;
mv78xx0_setup_pcie_io_win(win++, pp->res[0].start,
resource_size(&pp->res[0]),
pp->maj, pp->min);
mv78xx0_setup_pcie_mem_win(win++, pp->res[1].start,
resource_size(&pp->res[1]),
mv78xx0_setup_pcie_mem_win(win + i + 8, pp->res.start,
resource_size(&pp->res),
pp->maj, pp->min);
mv78xx0_setup_pcie_io_win(win + i, i * SZ_64K, SZ_64K,
pp->maj, pp->min);
}
}
@ -156,8 +111,9 @@ static int __init mv78xx0_pcie_setup(int nr, struct pci_sys_data *sys)
orion_pcie_set_local_bus_nr(pp->base, sys->busnr);
orion_pcie_setup(pp->base);
pci_add_resource_offset(&sys->resources, &pp->res[0], sys->io_offset);
pci_add_resource_offset(&sys->resources, &pp->res[1], sys->mem_offset);
pci_ioremap_io(nr * SZ_64K, MV78XX0_PCIE_IO_PHYS_BASE(nr));
pci_add_resource_offset(&sys->resources, &pp->res, sys->mem_offset);
return 1;
}
@ -281,7 +237,7 @@ static void __init add_pcie_port(int maj, int min, unsigned long base)
pp->root_bus_nr = -1;
pp->base = (void __iomem *)base;
spin_lock_init(&pp->conf_lock);
memset(pp->res, 0, sizeof(pp->res));
memset(&pp->res, 0, sizeof(pp->res));
} else {
printk("link down, ignoring\n");
}

View File

@ -46,16 +46,6 @@ static struct map_desc orion5x_io_desc[] __initdata = {
.pfn = __phys_to_pfn(ORION5X_REGS_PHYS_BASE),
.length = ORION5X_REGS_SIZE,
.type = MT_DEVICE,
}, {
.virtual = ORION5X_PCIE_IO_VIRT_BASE,
.pfn = __phys_to_pfn(ORION5X_PCIE_IO_PHYS_BASE),
.length = ORION5X_PCIE_IO_SIZE,
.type = MT_DEVICE,
}, {
.virtual = ORION5X_PCI_IO_VIRT_BASE,
.pfn = __phys_to_pfn(ORION5X_PCI_IO_PHYS_BASE),
.length = ORION5X_PCI_IO_SIZE,
.type = MT_DEVICE,
}, {
.virtual = ORION5X_PCIE_WA_VIRT_BASE,
.pfn = __phys_to_pfn(ORION5X_PCIE_WA_PHYS_BASE),

View File

@ -1,22 +0,0 @@
/*
* arch/arm/mach-orion5x/include/mach/io.h
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#ifndef __ASM_ARCH_IO_H
#define __ASM_ARCH_IO_H
#include <mach/orion5x.h>
#include <asm/sizes.h>
#define IO_SPACE_LIMIT SZ_2M
static inline void __iomem *__io(unsigned long addr)
{
return (void __iomem *)(addr + ORION5X_PCIE_IO_VIRT_BASE);
}
#define __io(a) __io(a)
#endif

View File

@ -31,31 +31,29 @@
* fc000000 device bus mappings (cs0/cs1)
*
* virt phys size
* fdd00000 f1000000 1M on-chip peripheral registers
* fde00000 f2000000 1M PCIe I/O space
* fdf00000 f2100000 1M PCI I/O space
* fe000000 f0000000 16M PCIe WA space (Orion-1/Orion-NAS only)
* fe000000 f1000000 1M on-chip peripheral registers
* fee00000 f2000000 64K PCIe I/O space
* fee10000 f2100000 64K PCI I/O space
* fd000000 f0000000 16M PCIe WA space (Orion-1/Orion-NAS only)
****************************************************************************/
#define ORION5X_REGS_PHYS_BASE 0xf1000000
#define ORION5X_REGS_VIRT_BASE 0xfdd00000
#define ORION5X_REGS_VIRT_BASE 0xfe000000
#define ORION5X_REGS_SIZE SZ_1M
#define ORION5X_PCIE_IO_PHYS_BASE 0xf2000000
#define ORION5X_PCIE_IO_VIRT_BASE 0xfde00000
#define ORION5X_PCIE_IO_BUS_BASE 0x00000000
#define ORION5X_PCIE_IO_SIZE SZ_1M
#define ORION5X_PCIE_IO_SIZE SZ_64K
#define ORION5X_PCI_IO_PHYS_BASE 0xf2100000
#define ORION5X_PCI_IO_VIRT_BASE 0xfdf00000
#define ORION5X_PCI_IO_BUS_BASE 0x00100000
#define ORION5X_PCI_IO_SIZE SZ_1M
#define ORION5X_PCI_IO_BUS_BASE 0x00010000
#define ORION5X_PCI_IO_SIZE SZ_64K
#define ORION5X_SRAM_PHYS_BASE (0xf2200000)
#define ORION5X_SRAM_SIZE SZ_8K
/* Relevant only for Orion-1/Orion-NAS */
#define ORION5X_PCIE_WA_PHYS_BASE 0xf0000000
#define ORION5X_PCIE_WA_VIRT_BASE 0xfe000000
#define ORION5X_PCIE_WA_VIRT_BASE 0xfd000000
#define ORION5X_PCIE_WA_SIZE SZ_16M
#define ORION5X_PCIE_MEM_PHYS_BASE 0xe0000000

View File

@ -162,35 +162,25 @@ static int __init pcie_setup(struct pci_sys_data *sys)
pcie_ops.read = pcie_rd_conf_wa;
}
pci_ioremap_io(sys->busnr * SZ_64K, ORION5X_PCIE_IO_PHYS_BASE);
/*
* Request resources.
*/
res = kzalloc(sizeof(struct resource) * 2, GFP_KERNEL);
res = kzalloc(sizeof(struct resource), GFP_KERNEL);
if (!res)
panic("pcie_setup unable to alloc resources");
/*
* IORESOURCE_IO
*/
sys->io_offset = 0;
res[0].name = "PCIe I/O Space";
res[0].flags = IORESOURCE_IO;
res[0].start = ORION5X_PCIE_IO_BUS_BASE;
res[0].end = res[0].start + ORION5X_PCIE_IO_SIZE - 1;
if (request_resource(&ioport_resource, &res[0]))
panic("Request PCIe IO resource failed\n");
pci_add_resource_offset(&sys->resources, &res[0], sys->io_offset);
/*
* IORESOURCE_MEM
*/
res[1].name = "PCIe Memory Space";
res[1].flags = IORESOURCE_MEM;
res[1].start = ORION5X_PCIE_MEM_PHYS_BASE;
res[1].end = res[1].start + ORION5X_PCIE_MEM_SIZE - 1;
if (request_resource(&iomem_resource, &res[1]))
res->name = "PCIe Memory Space";
res->flags = IORESOURCE_MEM;
res->start = ORION5X_PCIE_MEM_PHYS_BASE;
res->end = res->start + ORION5X_PCIE_MEM_SIZE - 1;
if (request_resource(&iomem_resource, res))
panic("Request PCIe Memory resource failed\n");
pci_add_resource_offset(&sys->resources, &res[1], sys->mem_offset);
pci_add_resource_offset(&sys->resources, res, sys->mem_offset);
return 1;
}
@ -489,35 +479,25 @@ static int __init pci_setup(struct pci_sys_data *sys)
*/
orion5x_setbits(PCI_CMD, PCI_CMD_HOST_REORDER);
pci_ioremap_io(sys->busnr * SZ_64K, ORION5X_PCI_IO_PHYS_BASE);
/*
* Request resources
*/
res = kzalloc(sizeof(struct resource) * 2, GFP_KERNEL);
res = kzalloc(sizeof(struct resource), GFP_KERNEL);
if (!res)
panic("pci_setup unable to alloc resources");
/*
* IORESOURCE_IO
*/
sys->io_offset = 0;
res[0].name = "PCI I/O Space";
res[0].flags = IORESOURCE_IO;
res[0].start = ORION5X_PCI_IO_BUS_BASE;
res[0].end = res[0].start + ORION5X_PCI_IO_SIZE - 1;
if (request_resource(&ioport_resource, &res[0]))
panic("Request PCI IO resource failed\n");
pci_add_resource_offset(&sys->resources, &res[0], sys->io_offset);
/*
* IORESOURCE_MEM
*/
res[1].name = "PCI Memory Space";
res[1].flags = IORESOURCE_MEM;
res[1].start = ORION5X_PCI_MEM_PHYS_BASE;
res[1].end = res[1].start + ORION5X_PCI_MEM_SIZE - 1;
if (request_resource(&iomem_resource, &res[1]))
res->name = "PCI Memory Space";
res->flags = IORESOURCE_MEM;
res->start = ORION5X_PCI_MEM_PHYS_BASE;
res->end = res->start + ORION5X_PCI_MEM_SIZE - 1;
if (request_resource(&iomem_resource, res))
panic("Request PCI Memory resource failed\n");
pci_add_resource_offset(&sys->resources, &res[1], sys->mem_offset);
pci_add_resource_offset(&sys->resources, res, sys->mem_offset);
return 1;
}

View File

@ -21,9 +21,6 @@
#include <asm/mach/arch.h>
#include <asm/mach/time.h>
#define IO_BASE 0xe0000000
#define IO_SIZE 0x08000000
#define IO_START 0x40000000
#define ROMCARD_SIZE 0x08000000
#define ROMCARD_START 0x10000000
@ -104,20 +101,6 @@ arch_initcall(shark_init);
extern void shark_init_irq(void);
static struct map_desc shark_io_desc[] __initdata = {
{
.virtual = IO_BASE,
.pfn = __phys_to_pfn(IO_START),
.length = IO_SIZE,
.type = MT_DEVICE
}
};
static void __init shark_map_io(void)
{
iotable_init(shark_io_desc, ARRAY_SIZE(shark_io_desc));
}
#define IRQ_TIMER 0
#define HZ_TIME ((1193180 + HZ/2) / HZ)
@ -158,7 +141,6 @@ static void shark_init_early(void)
MACHINE_START(SHARK, "Shark")
/* Maintainer: Alexander Schulz */
.atag_offset = 0x3000,
.map_io = shark_map_io,
.init_early = shark_init_early,
.init_irq = shark_init_irq,
.timer = &shark_timer,

View File

@ -12,9 +12,10 @@
*/
.macro addruart, rp, rv, tmp
mov \rp, #0xe0000000
orr \rp, \rp, #0x000003f8
mov \rv, \rp
mov \rp, #0x3f8
orr \rv, \rp, #0xfe000000
orr \rv, \rv, #0x00e00000
orr \rp, \rp, #0x40000000
.endm
.macro senduart,rd,rx

View File

@ -8,7 +8,8 @@
* warranty of any kind, whether express or implied.
*/
.macro get_irqnr_preamble, base, tmp
mov \base, #0xe0000000
mov \base, #0xfe000000
orr \base, \base, #0x00e00000
.endm
.macro get_irqnr_and_base, irqnr, irqstat, base, tmp

View File

@ -1,18 +0,0 @@
/*
* arch/arm/mach-shark/include/mach/io.h
*
* by Alexander Schulz
*
* derived from:
* arch/arm/mach-ebsa110/include/mach/io.h
* Copyright (C) 1997,1998 Russell King
*/
#ifndef __ASM_ARM_ARCH_IO_H
#define __ASM_ARM_ARCH_IO_H
#define IO_SPACE_LIMIT 0xffffffff
#define __io(a) ((void __iomem *)(0xe0000000 + (a)))
#endif

View File

@ -8,12 +8,15 @@
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/io.h>
#include <video/vga.h>
#include <asm/irq.h>
#include <asm/mach/pci.h>
#include <asm/mach-types.h>
#define IO_START 0x40000000
static int __init shark_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
{
if (dev->bus->number == 0)
@ -44,6 +47,8 @@ static int __init shark_pci_init(void)
pcibios_min_mem = 0x50000000;
vga_base = 0xe8000000;
pci_ioremap_io(0, IO_START);
pci_common_init(&shark_pci);
return 0;

View File

@ -1,46 +0,0 @@
/*
* arch/arm/mach-tegra/include/mach/io.h
*
* Copyright (C) 2010 Google, Inc.
*
* Author:
* Colin Cross <ccross@google.com>
* Erik Gilling <konkers@google.com>
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that 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.
*
*/
#ifndef __MACH_TEGRA_IO_H
#define __MACH_TEGRA_IO_H
#define IO_SPACE_LIMIT 0xffff
#ifndef __ASSEMBLER__
#ifdef CONFIG_TEGRA_PCI
extern void __iomem *tegra_pcie_io_base;
static inline void __iomem *__io(unsigned long addr)
{
return tegra_pcie_io_base + (addr & IO_SPACE_LIMIT);
}
#else
static inline void __iomem *__io(unsigned long addr)
{
return (void __iomem *)addr;
}
#endif
#define __io(a) __io(a)
#endif
#endif

View File

@ -303,6 +303,9 @@
#define IO_APB_VIRT IOMEM(0xFE300000)
#define IO_APB_SIZE SZ_1M
#define TEGRA_PCIE_BASE 0x80000000
#define TEGRA_PCIE_IO_BASE (TEGRA_PCIE_BASE + SZ_4M)
#define IO_TO_VIRT_BETWEEN(p, st, sz) ((p) >= (st) && (p) < ((st) + (sz)))
#define IO_TO_VIRT_XLATE(p, pst, vst) (((p) - (pst) + (vst)))

View File

@ -171,8 +171,6 @@ static void __iomem *reg_pmc_base = IO_ADDRESS(TEGRA_PMC_BASE);
* 0x90000000 - 0x9fffffff - non-prefetchable memory
* 0xa0000000 - 0xbfffffff - prefetchable memory
*/
#define TEGRA_PCIE_BASE 0x80000000
#define PCIE_REGS_SZ SZ_16K
#define PCIE_CFG_OFF PCIE_REGS_SZ
#define PCIE_CFG_SZ SZ_1M
@ -180,8 +178,6 @@ static void __iomem *reg_pmc_base = IO_ADDRESS(TEGRA_PMC_BASE);
#define PCIE_EXT_CFG_SZ SZ_1M
#define PCIE_IOMAP_SZ (PCIE_REGS_SZ + PCIE_CFG_SZ + PCIE_EXT_CFG_SZ)
#define MMIO_BASE (TEGRA_PCIE_BASE + SZ_4M)
#define MMIO_SIZE SZ_64K
#define MEM_BASE_0 (TEGRA_PCIE_BASE + SZ_256M)
#define MEM_SIZE_0 SZ_128M
#define MEM_BASE_1 (MEM_BASE_0 + MEM_SIZE_0)
@ -204,10 +200,9 @@ struct tegra_pcie_port {
bool link_up;
char io_space_name[16];
char mem_space_name[16];
char prefetch_space_name[20];
struct resource res[3];
struct resource res[2];
};
struct tegra_pcie_info {
@ -223,17 +218,7 @@ struct tegra_pcie_info {
struct clk *pll_e;
};
static struct tegra_pcie_info tegra_pcie = {
.res_mmio = {
.name = "PCI IO",
.start = MMIO_BASE,
.end = MMIO_BASE + MMIO_SIZE - 1,
.flags = IORESOURCE_MEM,
},
};
void __iomem *tegra_pcie_io_base;
EXPORT_SYMBOL(tegra_pcie_io_base);
static struct tegra_pcie_info tegra_pcie;
static inline void afi_writel(u32 value, unsigned long offset)
{
@ -391,24 +376,7 @@ static int tegra_pcie_setup(int nr, struct pci_sys_data *sys)
pp = tegra_pcie.port + nr;
pp->root_bus_nr = sys->busnr;
/*
* IORESOURCE_IO
*/
snprintf(pp->io_space_name, sizeof(pp->io_space_name),
"PCIe %d I/O", pp->index);
pp->io_space_name[sizeof(pp->io_space_name) - 1] = 0;
pp->res[0].name = pp->io_space_name;
if (pp->index == 0) {
pp->res[0].start = PCIBIOS_MIN_IO;
pp->res[0].end = pp->res[0].start + SZ_32K - 1;
} else {
pp->res[0].start = PCIBIOS_MIN_IO + SZ_32K;
pp->res[0].end = IO_SPACE_LIMIT;
}
pp->res[0].flags = IORESOURCE_IO;
if (request_resource(&ioport_resource, &pp->res[0]))
panic("Request PCIe IO resource failed\n");
pci_add_resource_offset(&sys->resources, &pp->res[0], sys->io_offset);
pci_ioremap_io(nr * SZ_64K, TEGRA_PCIE_IO_BASE);
/*
* IORESOURCE_MEM
@ -416,18 +384,18 @@ static int tegra_pcie_setup(int nr, struct pci_sys_data *sys)
snprintf(pp->mem_space_name, sizeof(pp->mem_space_name),
"PCIe %d MEM", pp->index);
pp->mem_space_name[sizeof(pp->mem_space_name) - 1] = 0;
pp->res[1].name = pp->mem_space_name;
pp->res[0].name = pp->mem_space_name;
if (pp->index == 0) {
pp->res[1].start = MEM_BASE_0;
pp->res[1].end = pp->res[1].start + MEM_SIZE_0 - 1;
pp->res[0].start = MEM_BASE_0;
pp->res[0].end = pp->res[0].start + MEM_SIZE_0 - 1;
} else {
pp->res[1].start = MEM_BASE_1;
pp->res[1].end = pp->res[1].start + MEM_SIZE_1 - 1;
pp->res[0].start = MEM_BASE_1;
pp->res[0].end = pp->res[0].start + MEM_SIZE_1 - 1;
}
pp->res[1].flags = IORESOURCE_MEM;
if (request_resource(&iomem_resource, &pp->res[1]))
pp->res[0].flags = IORESOURCE_MEM;
if (request_resource(&iomem_resource, &pp->res[0]))
panic("Request PCIe Memory resource failed\n");
pci_add_resource_offset(&sys->resources, &pp->res[1], sys->mem_offset);
pci_add_resource_offset(&sys->resources, &pp->res[0], sys->mem_offset);
/*
* IORESOURCE_MEM | IORESOURCE_PREFETCH
@ -435,18 +403,18 @@ static int tegra_pcie_setup(int nr, struct pci_sys_data *sys)
snprintf(pp->prefetch_space_name, sizeof(pp->prefetch_space_name),
"PCIe %d PREFETCH MEM", pp->index);
pp->prefetch_space_name[sizeof(pp->prefetch_space_name) - 1] = 0;
pp->res[2].name = pp->prefetch_space_name;
pp->res[1].name = pp->prefetch_space_name;
if (pp->index == 0) {
pp->res[2].start = PREFETCH_MEM_BASE_0;
pp->res[2].end = pp->res[2].start + PREFETCH_MEM_SIZE_0 - 1;
pp->res[1].start = PREFETCH_MEM_BASE_0;
pp->res[1].end = pp->res[1].start + PREFETCH_MEM_SIZE_0 - 1;
} else {
pp->res[2].start = PREFETCH_MEM_BASE_1;
pp->res[2].end = pp->res[2].start + PREFETCH_MEM_SIZE_1 - 1;
pp->res[1].start = PREFETCH_MEM_BASE_1;
pp->res[1].end = pp->res[1].start + PREFETCH_MEM_SIZE_1 - 1;
}
pp->res[2].flags = IORESOURCE_MEM | IORESOURCE_PREFETCH;
if (request_resource(&iomem_resource, &pp->res[2]))
pp->res[1].flags = IORESOURCE_MEM | IORESOURCE_PREFETCH;
if (request_resource(&iomem_resource, &pp->res[1]))
panic("Request PCIe Prefetch Memory resource failed\n");
pci_add_resource_offset(&sys->resources, &pp->res[2], sys->mem_offset);
pci_add_resource_offset(&sys->resources, &pp->res[1], sys->mem_offset);
return 1;
}
@ -541,8 +509,8 @@ static void tegra_pcie_setup_translations(void)
/* Bar 2: downstream IO bar */
fpci_bar = ((__u32)0xfdfc << 16);
size = MMIO_SIZE;
axi_address = MMIO_BASE;
size = SZ_128K;
axi_address = TEGRA_PCIE_IO_BASE;
afi_writel(axi_address, AFI_AXI_BAR2_START);
afi_writel(size >> 12, AFI_AXI_BAR2_SZ);
afi_writel(fpci_bar, AFI_FPCI_BAR2);
@ -776,7 +744,6 @@ static void tegra_pcie_clocks_put(void)
static int __init tegra_pcie_get_resources(void)
{
struct resource *res_mmio = &tegra_pcie.res_mmio;
int err;
err = tegra_pcie_clocks_get();
@ -798,34 +765,16 @@ static int __init tegra_pcie_get_resources(void)
goto err_map_reg;
}
err = request_resource(&iomem_resource, res_mmio);
if (err) {
pr_err("PCIE: Failed to request resources: %d\n", err);
goto err_req_io;
}
tegra_pcie_io_base = ioremap_nocache(res_mmio->start,
resource_size(res_mmio));
if (tegra_pcie_io_base == NULL) {
pr_err("PCIE: Failed to map IO\n");
err = -ENOMEM;
goto err_map_io;
}
err = request_irq(INT_PCIE_INTR, tegra_pcie_isr,
IRQF_SHARED, "PCIE", &tegra_pcie);
if (err) {
pr_err("PCIE: Failed to register IRQ: %d\n", err);
goto err_irq;
goto err_req_io;
}
set_irq_flags(INT_PCIE_INTR, IRQF_VALID);
return 0;
err_irq:
iounmap(tegra_pcie_io_base);
err_map_io:
release_resource(&tegra_pcie.res_mmio);
err_req_io:
iounmap(tegra_pcie.regs);
err_map_reg:

View File

@ -169,11 +169,6 @@ static struct map_desc versatile_io_desc[] __initdata = {
.pfn = __phys_to_pfn(VERSATILE_PCI_CFG_BASE),
.length = VERSATILE_PCI_CFG_BASE_SIZE,
.type = MT_DEVICE
}, {
.virtual = (unsigned long)VERSATILE_PCI_VIRT_MEM_BASE0,
.pfn = __phys_to_pfn(VERSATILE_PCI_MEM_BASE0),
.length = IO_SPACE_LIMIT,
.type = MT_DEVICE
},
#endif
};

View File

@ -29,7 +29,6 @@
*/
#define VERSATILE_PCI_VIRT_BASE (void __iomem *)0xe8000000ul
#define VERSATILE_PCI_CFG_VIRT_BASE (void __iomem *)0xe9000000ul
#define VERSATILE_PCI_VIRT_MEM_BASE0 (void __iomem *)PCIO_BASE
/* macro to get at MMIO space when running virtually */
#define IO_ADDRESS(x) (((x) & 0x0fffffff) + (((x) >> 4) & 0x0f000000) + 0xf0000000)

View File

@ -1,27 +0,0 @@
/*
* arch/arm/mach-versatile/include/mach/io.h
*
* Copyright (C) 2003 ARM Limited
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __ASM_ARM_ARCH_IO_H
#define __ASM_ARM_ARCH_IO_H
#define PCIO_BASE 0xeb000000ul
#define __io(a) ((a) + PCIO_BASE)
#endif

View File

@ -169,13 +169,6 @@ static struct pci_ops pci_versatile_ops = {
.write = versatile_write_config,
};
static struct resource io_port = {
.name = "PCI",
.start = 0,
.end = IO_SPACE_LIMIT,
.flags = IORESOURCE_IO,
};
static struct resource io_mem = {
.name = "PCI I/O space",
.start = VERSATILE_PCI_MEM_BASE0,
@ -207,12 +200,6 @@ static int __init pci_versatile_setup_resources(struct pci_sys_data *sys)
"memory region (%d)\n", ret);
goto out;
}
ret = request_resource(&ioport_resource, &io_port);
if (ret) {
printk(KERN_ERR "PCI: unable to allocate I/O "
"port region (%d)\n", ret);
goto out;
}
ret = request_resource(&iomem_resource, &non_mem);
if (ret) {
printk(KERN_ERR "PCI: unable to allocate non-prefetchable "
@ -227,11 +214,9 @@ static int __init pci_versatile_setup_resources(struct pci_sys_data *sys)
}
/*
* the IO resource for this bus
* the mem resource for this bus
* the prefetch mem resource for this bus
*/
pci_add_resource_offset(&sys->resources, &io_port, sys->io_offset);
pci_add_resource_offset(&sys->resources, &non_mem, sys->mem_offset);
pci_add_resource_offset(&sys->resources, &pre_mem, sys->mem_offset);
@ -260,9 +245,11 @@ int __init pci_versatile_setup(int nr, struct pci_sys_data *sys)
goto out;
}
ret = pci_ioremap_io(0, VERSATILE_PCI_MEM_BASE0);
if (ret)
goto out;
if (nr == 0) {
sys->mem_offset = 0;
sys->io_offset = 0;
ret = pci_versatile_setup_resources(sys);
if (ret < 0) {
printk("pci_versatile_setup: resources... oops?\n");
@ -319,7 +306,6 @@ int __init pci_versatile_setup(int nr, struct pci_sys_data *sys)
void __init pci_versatile_preinit(void)
{
pcibios_min_io = 0x44000000;
pcibios_min_mem = 0x50000000;
__raw_writel(VERSATILE_PCI_MEM_BASE0 >> 28, PCI_IMAP0);

View File

@ -36,6 +36,7 @@
#include <asm/system_info.h>
#include <asm/mach/map.h>
#include <asm/mach/pci.h>
#include "mm.h"
int ioremap_page(unsigned long virt, unsigned long phys,
@ -383,3 +384,16 @@ void __arm_iounmap(volatile void __iomem *io_addr)
arch_iounmap(io_addr);
}
EXPORT_SYMBOL(__arm_iounmap);
#ifdef CONFIG_PCI
int pci_ioremap_io(unsigned int offset, phys_addr_t phys_addr)
{
BUG_ON(offset + SZ_64K > IO_SPACE_LIMIT);
return ioremap_page_range(PCI_IO_VIRT_BASE + offset,
PCI_IO_VIRT_BASE + offset + SZ_64K,
phys_addr,
__pgprot(get_mem_type(MT_DEVICE)->prot_pte));
}
EXPORT_SYMBOL_GPL(pci_ioremap_io);
#endif

View File

@ -31,6 +31,7 @@
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/pci.h>
#include "mm.h"
@ -216,7 +217,7 @@ static struct mem_type mem_types[] = {
.prot_l1 = PMD_TYPE_TABLE,
.prot_sect = PROT_SECT_DEVICE | PMD_SECT_WB,
.domain = DOMAIN_IO,
},
},
[MT_DEVICE_WC] = { /* ioremap_wc */
.prot_pte = PROT_PTE_DEVICE | L_PTE_MT_DEV_WC,
.prot_l1 = PMD_TYPE_TABLE,
@ -777,14 +778,27 @@ void __init iotable_init(struct map_desc *io_desc, int nr)
create_mapping(md);
vm->addr = (void *)(md->virtual & PAGE_MASK);
vm->size = PAGE_ALIGN(md->length + (md->virtual & ~PAGE_MASK));
vm->phys_addr = __pfn_to_phys(md->pfn);
vm->flags = VM_IOREMAP | VM_ARM_STATIC_MAPPING;
vm->phys_addr = __pfn_to_phys(md->pfn);
vm->flags = VM_IOREMAP | VM_ARM_STATIC_MAPPING;
vm->flags |= VM_ARM_MTYPE(md->type);
vm->caller = iotable_init;
vm_area_add_early(vm++);
}
}
void __init vm_reserve_area_early(unsigned long addr, unsigned long size,
void *caller)
{
struct vm_struct *vm;
vm = early_alloc_aligned(sizeof(*vm), __alignof__(*vm));
vm->addr = (void *)addr;
vm->size = size;
vm->flags = VM_IOREMAP | VM_ARM_STATIC_MAPPING;
vm->caller = caller;
vm_area_add_early(vm);
}
#ifndef CONFIG_ARM_LPAE
/*
@ -802,14 +816,7 @@ void __init iotable_init(struct map_desc *io_desc, int nr)
static void __init pmd_empty_section_gap(unsigned long addr)
{
struct vm_struct *vm;
vm = early_alloc_aligned(sizeof(*vm), __alignof__(*vm));
vm->addr = (void *)addr;
vm->size = SECTION_SIZE;
vm->flags = VM_IOREMAP | VM_ARM_STATIC_MAPPING;
vm->caller = pmd_empty_section_gap;
vm_area_add_early(vm);
vm_reserve_area_early(addr, SECTION_SIZE, pmd_empty_section_gap);
}
static void __init fill_pmd_gaps(void)
@ -858,6 +865,28 @@ static void __init fill_pmd_gaps(void)
#define fill_pmd_gaps() do { } while (0)
#endif
#if defined(CONFIG_PCI) && !defined(CONFIG_NEED_MACH_IO_H)
static void __init pci_reserve_io(void)
{
struct vm_struct *vm;
unsigned long addr;
/* we're still single threaded hence no lock needed here */
for (vm = vmlist; vm; vm = vm->next) {
if (!(vm->flags & VM_ARM_STATIC_MAPPING))
continue;
addr = (unsigned long)vm->addr;
addr &= ~(SZ_2M - 1);
if (addr == PCI_IO_VIRT_BASE)
return;
}
vm_reserve_area_early(PCI_IO_VIRT_BASE, SZ_2M, pci_reserve_io);
}
#else
#define pci_reserve_io() do { } while (0)
#endif
static void * __initdata vmalloc_min =
(void *)(VMALLOC_END - (240 << 20) - VMALLOC_OFFSET);
@ -1141,6 +1170,9 @@ static void __init devicemaps_init(struct machine_desc *mdesc)
mdesc->map_io();
fill_pmd_gaps();
/* Reserve fixed i/o space in VMALLOC region */
pci_reserve_io();
/*
* Finally flush the caches and tlb to ensure that we're in a
* consistent state wrt the writebuffer. This also ensures that

View File

@ -192,30 +192,24 @@ int iop3xx_pci_setup(int nr, struct pci_sys_data *sys)
if (nr != 0)
return 0;
res = kzalloc(2 * sizeof(struct resource), GFP_KERNEL);
res = kzalloc(sizeof(struct resource), GFP_KERNEL);
if (!res)
panic("PCI: unable to alloc resources");
res[0].start = IOP3XX_PCI_LOWER_IO_PA;
res[0].end = IOP3XX_PCI_LOWER_IO_PA + IOP3XX_PCI_IO_WINDOW_SIZE - 1;
res[0].name = "IOP3XX PCI I/O Space";
res[0].flags = IORESOURCE_IO;
request_resource(&ioport_resource, &res[0]);
res[1].start = IOP3XX_PCI_LOWER_MEM_PA;
res[1].end = IOP3XX_PCI_LOWER_MEM_PA + IOP3XX_PCI_MEM_WINDOW_SIZE - 1;
res[1].name = "IOP3XX PCI Memory Space";
res[1].flags = IORESOURCE_MEM;
request_resource(&iomem_resource, &res[1]);
res->start = IOP3XX_PCI_LOWER_MEM_PA;
res->end = IOP3XX_PCI_LOWER_MEM_PA + IOP3XX_PCI_MEM_WINDOW_SIZE - 1;
res->name = "IOP3XX PCI Memory Space";
res->flags = IORESOURCE_MEM;
request_resource(&iomem_resource, res);
/*
* Use whatever translation is already setup.
*/
sys->mem_offset = IOP3XX_PCI_LOWER_MEM_PA - *IOP3XX_OMWTVR0;
sys->io_offset = IOP3XX_PCI_LOWER_IO_PA - *IOP3XX_OIOWTVR;
pci_add_resource_offset(&sys->resources, &res[0], sys->io_offset);
pci_add_resource_offset(&sys->resources, &res[1], sys->mem_offset);
pci_add_resource_offset(&sys->resources, res, sys->mem_offset);
pci_ioremap_io(0, IOP3XX_PCI_LOWER_IO_PA);
return 1;
}
@ -367,7 +361,6 @@ void __init iop3xx_pci_preinit_cond(void)
void __init iop3xx_pci_preinit(void)
{
pcibios_min_io = 0;
pcibios_min_mem = 0;
iop3xx_atu_disable();

View File

@ -25,11 +25,6 @@ static struct map_desc iop3xx_std_desc[] __initdata = {
.pfn = __phys_to_pfn(IOP3XX_PERIPHERAL_PHYS_BASE),
.length = IOP3XX_PERIPHERAL_SIZE,
.type = MT_UNCACHED,
}, { /* PCI IO space */
.virtual = IOP3XX_PCI_LOWER_IO_VA,
.pfn = __phys_to_pfn(IOP3XX_PCI_LOWER_IO_PA),
.length = IOP3XX_PCI_IO_WINDOW_SIZE,
.type = MT_DEVICE,
},
};

View File

@ -4,13 +4,13 @@
/* Copyright (C) 2003 Peter Milne, D-TACQ Solutions Ltd
* <Peter dot Milne at D hyphen TACQ dot com>
*
* With acknowledgements to i2c-algo-ibm_ocp.c by
* With acknowledgements to i2c-algo-ibm_ocp.c by
* Ian DaSilva, MontaVista Software, Inc. idasilva@mvista.com
*
* And i2c-algo-pcf.c, which was created by Simon G. Vogl and Hans Berglund:
*
* Copyright (C) 1995-1997 Simon G. Vogl, 1998-2000 Hans Berglund
*
*
* And which acknowledged Kyösti Mälkki <kmalkki@cc.hut.fi>,
* Frodo Looijaard <frodol@dds.nl>, Martin Bailey<mbailey@littlefeet-inc.com>
*
@ -39,14 +39,15 @@
#include <linux/platform_device.h>
#include <linux/i2c.h>
#include <linux/io.h>
#include <linux/gpio.h>
#include "i2c-iop3xx.h"
/* global unit counter */
static int i2c_id;
static inline unsigned char
iic_cook_addr(struct i2c_msg *msg)
static inline unsigned char
iic_cook_addr(struct i2c_msg *msg)
{
unsigned char addr;
@ -55,38 +56,38 @@ iic_cook_addr(struct i2c_msg *msg)
if (msg->flags & I2C_M_RD)
addr |= 1;
return addr;
return addr;
}
static void
static void
iop3xx_i2c_reset(struct i2c_algo_iop3xx_data *iop3xx_adap)
{
/* Follows devman 9.3 */
__raw_writel(IOP3XX_ICR_UNIT_RESET, iop3xx_adap->ioaddr + CR_OFFSET);
__raw_writel(IOP3XX_ISR_CLEARBITS, iop3xx_adap->ioaddr + SR_OFFSET);
__raw_writel(0, iop3xx_adap->ioaddr + CR_OFFSET);
}
}
static void
static void
iop3xx_i2c_enable(struct i2c_algo_iop3xx_data *iop3xx_adap)
{
u32 cr = IOP3XX_ICR_GCD | IOP3XX_ICR_SCLEN | IOP3XX_ICR_UE;
/*
/*
* Every time unit enable is asserted, GPOD needs to be cleared
* on IOP3XX to avoid data corruption on the bus.
*/
#if defined(CONFIG_ARCH_IOP32X) || defined(CONFIG_ARCH_IOP33X)
if (iop3xx_adap->id == 0) {
gpio_line_set(IOP3XX_GPIO_LINE(7), GPIO_LOW);
gpio_line_set(IOP3XX_GPIO_LINE(6), GPIO_LOW);
gpio_set_value(7, 0);
gpio_set_value(6, 0);
} else {
gpio_line_set(IOP3XX_GPIO_LINE(5), GPIO_LOW);
gpio_line_set(IOP3XX_GPIO_LINE(4), GPIO_LOW);
gpio_set_value(5, 0);
gpio_set_value(4, 0);
}
#endif
/* NB SR bits not same position as CR IE bits :-( */
iop3xx_adap->SR_enabled =
iop3xx_adap->SR_enabled =
IOP3XX_ISR_ALD | IOP3XX_ISR_BERRD |
IOP3XX_ISR_RXFULL | IOP3XX_ISR_TXEMPTY;
@ -96,23 +97,23 @@ iop3xx_i2c_enable(struct i2c_algo_iop3xx_data *iop3xx_adap)
__raw_writel(cr, iop3xx_adap->ioaddr + CR_OFFSET);
}
static void
static void
iop3xx_i2c_transaction_cleanup(struct i2c_algo_iop3xx_data *iop3xx_adap)
{
unsigned long cr = __raw_readl(iop3xx_adap->ioaddr + CR_OFFSET);
cr &= ~(IOP3XX_ICR_MSTART | IOP3XX_ICR_TBYTE |
cr &= ~(IOP3XX_ICR_MSTART | IOP3XX_ICR_TBYTE |
IOP3XX_ICR_MSTOP | IOP3XX_ICR_SCLEN);
__raw_writel(cr, iop3xx_adap->ioaddr + CR_OFFSET);
}
/*
* NB: the handler has to clear the source of the interrupt!
/*
* NB: the handler has to clear the source of the interrupt!
* Then it passes the SR flags of interest to BH via adap data
*/
static irqreturn_t
iop3xx_i2c_irq_handler(int this_irq, void *dev_id)
static irqreturn_t
iop3xx_i2c_irq_handler(int this_irq, void *dev_id)
{
struct i2c_algo_iop3xx_data *iop3xx_adap = dev_id;
u32 sr = __raw_readl(iop3xx_adap->ioaddr + SR_OFFSET);
@ -126,7 +127,7 @@ iop3xx_i2c_irq_handler(int this_irq, void *dev_id)
}
/* check all error conditions, clear them , report most important */
static int
static int
iop3xx_i2c_error(u32 sr)
{
int rc = 0;
@ -135,12 +136,12 @@ iop3xx_i2c_error(u32 sr)
if ( !rc ) rc = -I2C_ERR_BERR;
}
if ((sr & IOP3XX_ISR_ALD)) {
if ( !rc ) rc = -I2C_ERR_ALD;
if ( !rc ) rc = -I2C_ERR_ALD;
}
return rc;
return rc;
}
static inline u32
static inline u32
iop3xx_i2c_get_srstat(struct i2c_algo_iop3xx_data *iop3xx_adap)
{
unsigned long flags;
@ -161,8 +162,8 @@ iop3xx_i2c_get_srstat(struct i2c_algo_iop3xx_data *iop3xx_adap)
typedef int (* compare_func)(unsigned test, unsigned mask);
/* returns 1 on correct comparison */
static int
iop3xx_i2c_wait_event(struct i2c_algo_iop3xx_data *iop3xx_adap,
static int
iop3xx_i2c_wait_event(struct i2c_algo_iop3xx_data *iop3xx_adap,
unsigned flags, unsigned* status,
compare_func compare)
{
@ -192,47 +193,47 @@ iop3xx_i2c_wait_event(struct i2c_algo_iop3xx_data *iop3xx_adap,
}
/*
* Concrete compare_funcs
* Concrete compare_funcs
*/
static int
static int
all_bits_clear(unsigned test, unsigned mask)
{
return (test & mask) == 0;
}
static int
static int
any_bits_set(unsigned test, unsigned mask)
{
return (test & mask) != 0;
}
static int
static int
iop3xx_i2c_wait_tx_done(struct i2c_algo_iop3xx_data *iop3xx_adap, int *status)
{
return iop3xx_i2c_wait_event(
iop3xx_adap,
return iop3xx_i2c_wait_event(
iop3xx_adap,
IOP3XX_ISR_TXEMPTY | IOP3XX_ISR_ALD | IOP3XX_ISR_BERRD,
status, any_bits_set);
}
static int
static int
iop3xx_i2c_wait_rx_done(struct i2c_algo_iop3xx_data *iop3xx_adap, int *status)
{
return iop3xx_i2c_wait_event(
iop3xx_adap,
return iop3xx_i2c_wait_event(
iop3xx_adap,
IOP3XX_ISR_RXFULL | IOP3XX_ISR_ALD | IOP3XX_ISR_BERRD,
status, any_bits_set);
}
static int
static int
iop3xx_i2c_wait_idle(struct i2c_algo_iop3xx_data *iop3xx_adap, int *status)
{
return iop3xx_i2c_wait_event(
return iop3xx_i2c_wait_event(
iop3xx_adap, IOP3XX_ISR_UNITBUSY, status, all_bits_clear);
}
static int
iop3xx_i2c_send_target_addr(struct i2c_algo_iop3xx_data *iop3xx_adap,
static int
iop3xx_i2c_send_target_addr(struct i2c_algo_iop3xx_data *iop3xx_adap,
struct i2c_msg* msg)
{
unsigned long cr = __raw_readl(iop3xx_adap->ioaddr + CR_OFFSET);
@ -247,7 +248,7 @@ iop3xx_i2c_send_target_addr(struct i2c_algo_iop3xx_data *iop3xx_adap,
}
__raw_writel(iic_cook_addr(msg), iop3xx_adap->ioaddr + DBR_OFFSET);
cr &= ~(IOP3XX_ICR_MSTOP | IOP3XX_ICR_NACK);
cr |= IOP3XX_ICR_MSTART | IOP3XX_ICR_TBYTE;
@ -257,8 +258,8 @@ iop3xx_i2c_send_target_addr(struct i2c_algo_iop3xx_data *iop3xx_adap,
return rc;
}
static int
iop3xx_i2c_write_byte(struct i2c_algo_iop3xx_data *iop3xx_adap, char byte,
static int
iop3xx_i2c_write_byte(struct i2c_algo_iop3xx_data *iop3xx_adap, char byte,
int stop)
{
unsigned long cr = __raw_readl(iop3xx_adap->ioaddr + CR_OFFSET);
@ -277,10 +278,10 @@ iop3xx_i2c_write_byte(struct i2c_algo_iop3xx_data *iop3xx_adap, char byte,
rc = iop3xx_i2c_wait_tx_done(iop3xx_adap, &status);
return rc;
}
}
static int
iop3xx_i2c_read_byte(struct i2c_algo_iop3xx_data *iop3xx_adap, char* byte,
static int
iop3xx_i2c_read_byte(struct i2c_algo_iop3xx_data *iop3xx_adap, char* byte,
int stop)
{
unsigned long cr = __raw_readl(iop3xx_adap->ioaddr + CR_OFFSET);
@ -304,19 +305,19 @@ iop3xx_i2c_read_byte(struct i2c_algo_iop3xx_data *iop3xx_adap, char* byte,
return rc;
}
static int
static int
iop3xx_i2c_writebytes(struct i2c_adapter *i2c_adap, const char *buf, int count)
{
struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data;
int ii;
int rc = 0;
for (ii = 0; rc == 0 && ii != count; ++ii)
for (ii = 0; rc == 0 && ii != count; ++ii)
rc = iop3xx_i2c_write_byte(iop3xx_adap, buf[ii], ii==count-1);
return rc;
}
static int
static int
iop3xx_i2c_readbytes(struct i2c_adapter *i2c_adap, char *buf, int count)
{
struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data;
@ -325,7 +326,7 @@ iop3xx_i2c_readbytes(struct i2c_adapter *i2c_adap, char *buf, int count)
for (ii = 0; rc == 0 && ii != count; ++ii)
rc = iop3xx_i2c_read_byte(iop3xx_adap, &buf[ii], ii==count-1);
return rc;
}
@ -336,8 +337,8 @@ iop3xx_i2c_readbytes(struct i2c_adapter *i2c_adap, char *buf, int count)
* Each transfer (i.e. a read or a write) is separated by a repeated start
* condition.
*/
static int
iop3xx_i2c_handle_msg(struct i2c_adapter *i2c_adap, struct i2c_msg* pmsg)
static int
iop3xx_i2c_handle_msg(struct i2c_adapter *i2c_adap, struct i2c_msg* pmsg)
{
struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data;
int rc;
@ -357,8 +358,8 @@ iop3xx_i2c_handle_msg(struct i2c_adapter *i2c_adap, struct i2c_msg* pmsg)
/*
* master_xfer() - main read/write entry
*/
static int
iop3xx_i2c_master_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs,
static int
iop3xx_i2c_master_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs,
int num)
{
struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data;
@ -375,14 +376,14 @@ iop3xx_i2c_master_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs,
}
iop3xx_i2c_transaction_cleanup(iop3xx_adap);
if(ret)
return ret;
return im;
return im;
}
static u32
static u32
iop3xx_i2c_func(struct i2c_adapter *adap)
{
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
@ -393,11 +394,11 @@ static const struct i2c_algorithm iop3xx_i2c_algo = {
.functionality = iop3xx_i2c_func,
};
static int
static int
iop3xx_i2c_remove(struct platform_device *pdev)
{
struct i2c_adapter *padapter = platform_get_drvdata(pdev);
struct i2c_algo_iop3xx_data *adapter_data =
struct i2c_algo_iop3xx_data *adapter_data =
(struct i2c_algo_iop3xx_data *)padapter->algo_data;
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
unsigned long cr = __raw_readl(adapter_data->ioaddr + CR_OFFSET);
@ -419,7 +420,7 @@ iop3xx_i2c_remove(struct platform_device *pdev)
return 0;
}
static int
static int
iop3xx_i2c_probe(struct platform_device *pdev)
{
struct resource *res;