Skip to content

Commit

Permalink
arm64: Add architectural support for PCI
Browse files Browse the repository at this point in the history
Use the generic PCI domain and OF functions to provide support for PCI
on arm64.

[bhelgaas: Change comments to use generic PCI, not just PCIe.  Nothing at
this level is PCIe-specific.]
Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
  • Loading branch information
Liviu Dudau authored and Bjorn Helgaas committed Sep 30, 2014
1 parent 8b921ac commit d1e6dc9
Show file tree
Hide file tree
Showing 7 changed files with 134 additions and 2 deletions.
22 changes: 21 additions & 1 deletion arch/arm64/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ config MMU
def_bool y

config NO_IOPORT_MAP
def_bool y
def_bool y if !PCI

config STACKTRACE_SUPPORT
def_bool y
Expand Down Expand Up @@ -156,6 +156,26 @@ menu "Bus support"
config ARM_AMBA
bool

config PCI
bool "PCI support"
help
This feature enables support for PCI bus system. If you say Y
here, the kernel will include drivers and infrastructure code
to support PCI bus devices.

config PCI_DOMAINS
def_bool PCI

config PCI_DOMAINS_GENERIC
def_bool PCI

config PCI_SYSCALL
def_bool PCI

source "drivers/pci/Kconfig"
source "drivers/pci/pcie/Kconfig"
source "drivers/pci/hotplug/Kconfig"

endmenu

menu "Kernel Features"
Expand Down
1 change: 1 addition & 0 deletions arch/arm64/include/asm/Kbuild
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ generic-y += mman.h
generic-y += msgbuf.h
generic-y += mutex.h
generic-y += pci.h
generic-y += pci-bridge.h
generic-y += poll.h
generic-y += preempt.h
generic-y += resource.h
Expand Down
3 changes: 2 additions & 1 deletion arch/arm64/include/asm/io.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,8 @@ static inline u64 __raw_readq(const volatile void __iomem *addr)
/*
* I/O port access primitives.
*/
#define IO_SPACE_LIMIT 0xffff
#define arch_has_dev_port() (1)
#define IO_SPACE_LIMIT (SZ_32M - 1)
#define PCI_IOBASE ((void __iomem *)(MODULES_VADDR - SZ_32M))

static inline u8 inb(unsigned long addr)
Expand Down
37 changes: 37 additions & 0 deletions arch/arm64/include/asm/pci.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#ifndef __ASM_PCI_H
#define __ASM_PCI_H
#ifdef __KERNEL__

#include <linux/types.h>
#include <linux/slab.h>
#include <linux/dma-mapping.h>

#include <asm/io.h>
#include <asm-generic/pci-bridge.h>
#include <asm-generic/pci-dma-compat.h>

#define PCIBIOS_MIN_IO 0x1000
#define PCIBIOS_MIN_MEM 0

/*
* Set to 1 if the kernel should re-assign all PCI bus numbers
*/
#define pcibios_assign_all_busses() \
(pci_has_flag(PCI_REASSIGN_ALL_BUS))

/*
* PCI address space differs from physical memory address space
*/
#define PCI_DMA_BUS_IS_PHYS (0)

extern int isa_dma_bridge_buggy;

#ifdef CONFIG_PCI
static inline int pci_proc_domain(struct pci_bus *bus)
{
return 1;
}
#endif /* CONFIG_PCI */

#endif /* __KERNEL__ */
#endif /* __ASM_PCI_H */
2 changes: 2 additions & 0 deletions arch/arm64/include/asm/pgtable.h
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,8 @@ static inline int has_transparent_hugepage(void)
__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_nGnRnE) | PTE_PXN | PTE_UXN)
#define pgprot_writecombine(prot) \
__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC) | PTE_PXN | PTE_UXN)
#define pgprot_device(prot) \
__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_nGnRE) | PTE_PXN | PTE_UXN)
#define __HAVE_PHYS_MEM_ACCESS_PROT
struct file;
extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
Expand Down
1 change: 1 addition & 0 deletions arch/arm64/kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ arm64-obj-$(CONFIG_ARM64_CPU_SUSPEND) += sleep.o suspend.o
arm64-obj-$(CONFIG_JUMP_LABEL) += jump_label.o
arm64-obj-$(CONFIG_KGDB) += kgdb.o
arm64-obj-$(CONFIG_EFI) += efi.o efi-stub.o efi-entry.o
arm64-obj-$(CONFIG_PCI) += pci.o

obj-y += $(arm64-obj-y) vdso/
obj-m += $(arm64-obj-m)
Expand Down
70 changes: 70 additions & 0 deletions arch/arm64/kernel/pci.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* Code borrowed from powerpc/kernel/pci-common.c
*
* Copyright (C) 2003 Anton Blanchard <anton@au.ibm.com>, IBM
* Copyright (C) 2014 ARM Ltd.
*
* 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.
*
*/

#include <linux/init.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/of_pci.h>
#include <linux/of_platform.h>
#include <linux/slab.h>

#include <asm/pci-bridge.h>

/*
* Called after each bus is probed, but before its children are examined
*/
void pcibios_fixup_bus(struct pci_bus *bus)
{
/* nothing to do, expected to be removed in the future */
}

/*
* We don't have to worry about legacy ISA devices, so nothing to do here
*/
resource_size_t pcibios_align_resource(void *data, const struct resource *res,
resource_size_t size, resource_size_t align)
{
return res->start;
}

/*
* Try to assign the IRQ number from DT when adding a new device
*/
int pcibios_add_device(struct pci_dev *dev)
{
dev->irq = of_irq_parse_and_map_pci(dev, 0, 0);

return 0;
}


#ifdef CONFIG_PCI_DOMAINS_GENERIC
static bool dt_domain_found = false;

void pci_bus_assign_domain_nr(struct pci_bus *bus, struct device *parent)
{
int domain = of_get_pci_domain_nr(parent->of_node);

if (domain >= 0) {
dt_domain_found = true;
} else if (dt_domain_found == true) {
dev_err(parent, "Node %s is missing \"linux,pci-domain\" property in DT\n",
parent->of_node->full_name);
return;
} else {
domain = pci_get_new_domain_nr();
}

bus->domain_nr = domain;
}
#endif

0 comments on commit d1e6dc9

Please sign in to comment.