summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/arm/Marvell/README13
-rw-r--r--MAINTAINERS1
-rw-r--r--arch/arm/mach-mvebu/Kconfig6
-rw-r--r--arch/arm64/Kconfig.platforms6
-rw-r--r--arch/arm64/configs/defconfig5
-rw-r--r--drivers/irqchip/Kconfig5
-rw-r--r--drivers/irqchip/Makefile2
-rw-r--r--drivers/irqchip/irq-armada-370-xp.c156
8 files changed, 102 insertions, 92 deletions
diff --git a/Documentation/arm/Marvell/README b/Documentation/arm/Marvell/README
index ae89b67..ddbc048 100644
--- a/Documentation/arm/Marvell/README
+++ b/Documentation/arm/Marvell/README
@@ -118,6 +118,19 @@ EBU Armada family
Linux kernel mach directory: arch/arm/mach-mvebu
Linux kernel plat directory: none
+EBU Armada family ARMv8
+-----------------------
+
+ Armada 3710/3720 Flavors:
+ 88F3710
+ 88F3720
+
+ Core: ARM Cortex A53 (ARMv8)
+
+ Homepage : http://www.marvell.com/embedded-processors/armada-3700/
+
+ Device tree descritpion located in arch/arm64/boot/dts/marvell/armada-37*
+
Avanta family
-------------
diff --git a/MAINTAINERS b/MAINTAINERS
index 7f1fa4f..a8b00b5 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1278,6 +1278,7 @@ F: arch/arm/mach-mvebu/
F: drivers/rtc/rtc-armada38x.c
F: arch/arm/boot/dts/armada*
F: arch/arm/boot/dts/kirkwood*
+F: arch/arm64/boot/dts/marvell/armada*
ARM/Marvell Berlin SoC support
diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig
index 64e3d2c..b003e3a 100644
--- a/arch/arm/mach-mvebu/Kconfig
+++ b/arch/arm/mach-mvebu/Kconfig
@@ -3,7 +3,6 @@ menuconfig ARCH_MVEBU
depends on ARCH_MULTI_V7 || ARCH_MULTI_V5
select ARCH_SUPPORTS_BIG_ENDIAN
select CLKSRC_MMIO
- select GENERIC_IRQ_CHIP
select PINCTRL
select PLAT_ORION
select SOC_BUS
@@ -29,6 +28,7 @@ config MACH_ARMADA_370
bool "Marvell Armada 370 boards"
depends on ARCH_MULTI_V7
select ARMADA_370_CLK
+ select ARMADA_370_XP_IRQ
select CPU_PJ4B
select MACH_MVEBU_V7
select PINCTRL_ARMADA_370
@@ -39,6 +39,7 @@ config MACH_ARMADA_370
config MACH_ARMADA_375
bool "Marvell Armada 375 boards"
depends on ARCH_MULTI_V7
+ select ARMADA_370_XP_IRQ
select ARM_ERRATA_720789
select ARM_ERRATA_753970
select ARM_GIC
@@ -58,6 +59,7 @@ config MACH_ARMADA_38X
select ARM_ERRATA_720789
select ARM_ERRATA_753970
select ARM_GIC
+ select ARMADA_370_XP_IRQ
select ARMADA_38X_CLK
select HAVE_ARM_SCU
select HAVE_ARM_TWD if SMP
@@ -72,6 +74,7 @@ config MACH_ARMADA_39X
bool "Marvell Armada 39x boards"
depends on ARCH_MULTI_V7
select ARM_GIC
+ select ARMADA_370_XP_IRQ
select ARMADA_39X_CLK
select CACHE_L2X0
select HAVE_ARM_SCU
@@ -86,6 +89,7 @@ config MACH_ARMADA_39X
config MACH_ARMADA_XP
bool "Marvell Armada XP boards"
depends on ARCH_MULTI_V7
+ select ARMADA_370_XP_IRQ
select ARMADA_XP_CLK
select CPU_PJ4B
select MACH_MVEBU_V7
diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
index 8a09522..5938fd1 100644
--- a/arch/arm64/Kconfig.platforms
+++ b/arch/arm64/Kconfig.platforms
@@ -48,6 +48,12 @@ config ARCH_MEDIATEK
help
Support for Mediatek MT65xx & MT81xx ARMv8 SoCs
+config ARCH_MVEBU
+ bool "Marvell EBU SoC Family"
+ help
+ This enables support for Marvell EBU family such as the
+ Armada 3700 SoC family.
+
config ARCH_QCOM
bool "Qualcomm Platforms"
select PINCTRL
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 91ae263..774e51f 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -36,6 +36,7 @@ CONFIG_ARCH_EXYNOS7=y
CONFIG_ARCH_LAYERSCAPE=y
CONFIG_ARCH_HISI=y
CONFIG_ARCH_MEDIATEK=y
+CONFIG_ARCH_MVEBU=y
CONFIG_ARCH_QCOM=y
CONFIG_ARCH_ROCKCHIP=y
CONFIG_ARCH_SEATTLE=y
@@ -95,6 +96,7 @@ CONFIG_ATA=y
CONFIG_SATA_AHCI=y
CONFIG_SATA_AHCI_PLATFORM=y
CONFIG_AHCI_CEVA=y
+CONFIG_AHCI_MVEBU=y
CONFIG_AHCI_XGENE=y
CONFIG_SATA_RCAR=y
CONFIG_PATA_PLATFORM=y
@@ -136,6 +138,7 @@ CONFIG_SERIAL_MSM=y
CONFIG_SERIAL_MSM_CONSOLE=y
CONFIG_SERIAL_XILINX_PS_UART=y
CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y
+CONFIG_SERIAL_MVEBU_UART=y
CONFIG_VIRTIO_CONSOLE=y
# CONFIG_HW_RANDOM is not set
CONFIG_I2C_QUP=y
@@ -171,6 +174,8 @@ CONFIG_SND_SOC_RCAR=y
CONFIG_SND_SOC_AK4613=y
CONFIG_USB=y
CONFIG_USB_OTG=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_XHCI_PLATFORM=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_MSM=y
CONFIG_USB_EHCI_HCD_PLATFORM=y
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index fb50911..8115a32 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -60,6 +60,11 @@ config ARM_VIC_NR
The maximum number of VICs available in the system, for
power management.
+config ARMADA_370_XP_IRQ
+ bool
+ select GENERIC_IRQ_CHIP
+ select PCI_MSI_IRQ_DOMAIN if PCI_MSI
+
config ATMEL_AIC_IRQ
bool
select GENERIC_IRQ_CHIP
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index 18caacb..30dba04 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -5,7 +5,6 @@ obj-$(CONFIG_ARCH_BCM2835) += irq-bcm2836.o
obj-$(CONFIG_ARCH_EXYNOS) += exynos-combiner.o
obj-$(CONFIG_ARCH_HIP04) += irq-hip04.o
obj-$(CONFIG_ARCH_MMP) += irq-mmp.o
-obj-$(CONFIG_ARCH_MVEBU) += irq-armada-370-xp.o
obj-$(CONFIG_IRQ_MXS) += irq-mxs.o
obj-$(CONFIG_ARCH_TEGRA) += irq-tegra.o
obj-$(CONFIG_ARCH_S3C24XX) += irq-s3c24xx.o
@@ -28,6 +27,7 @@ obj-$(CONFIG_ARM_GIC_V3_ITS) += irq-gic-v3-its.o irq-gic-v3-its-pci-msi.o irq-g
obj-$(CONFIG_HISILICON_IRQ_MBIGEN) += irq-mbigen.o
obj-$(CONFIG_ARM_NVIC) += irq-nvic.o
obj-$(CONFIG_ARM_VIC) += irq-vic.o
+obj-$(CONFIG_ARMADA_370_XP_IRQ) += irq-armada-370-xp.o
obj-$(CONFIG_ATMEL_AIC_IRQ) += irq-atmel-aic-common.o irq-atmel-aic.o
obj-$(CONFIG_ATMEL_AIC5_IRQ) += irq-atmel-aic-common.o irq-atmel-aic5.o
obj-$(CONFIG_I8259) += irq-i8259.o
diff --git a/drivers/irqchip/irq-armada-370-xp.c b/drivers/irqchip/irq-armada-370-xp.c
index 3f3a8c3..e7dc6cb 100644
--- a/drivers/irqchip/irq-armada-370-xp.c
+++ b/drivers/irqchip/irq-armada-370-xp.c
@@ -71,6 +71,7 @@ static u32 doorbell_mask_reg;
static int parent_irq;
#ifdef CONFIG_PCI_MSI
static struct irq_domain *armada_370_xp_msi_domain;
+static struct irq_domain *armada_370_xp_msi_inner_domain;
static DECLARE_BITMAP(msi_used, PCI_MSI_DOORBELL_NR);
static DEFINE_MUTEX(msi_used_lock);
static phys_addr_t msi_doorbell_addr;
@@ -115,127 +116,102 @@ static void armada_370_xp_irq_unmask(struct irq_data *d)
#ifdef CONFIG_PCI_MSI
-static int armada_370_xp_alloc_msi(void)
-{
- int hwirq;
+static struct irq_chip armada_370_xp_msi_irq_chip = {
+ .name = "MPIC MSI",
+ .irq_mask = pci_msi_mask_irq,
+ .irq_unmask = pci_msi_unmask_irq,
+};
- mutex_lock(&msi_used_lock);
- hwirq = find_first_zero_bit(&msi_used, PCI_MSI_DOORBELL_NR);
- if (hwirq >= PCI_MSI_DOORBELL_NR)
- hwirq = -ENOSPC;
- else
- set_bit(hwirq, msi_used);
- mutex_unlock(&msi_used_lock);
+static struct msi_domain_info armada_370_xp_msi_domain_info = {
+ .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
+ MSI_FLAG_MULTI_PCI_MSI),
+ .chip = &armada_370_xp_msi_irq_chip,
+};
- return hwirq;
+static void armada_370_xp_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
+{
+ msg->address_lo = lower_32_bits(msi_doorbell_addr);
+ msg->address_hi = upper_32_bits(msi_doorbell_addr);
+ msg->data = 0xf00 | (data->hwirq + PCI_MSI_DOORBELL_START);
}
-static void armada_370_xp_free_msi(int hwirq)
+static int armada_370_xp_msi_set_affinity(struct irq_data *irq_data,
+ const struct cpumask *mask, bool force)
{
- mutex_lock(&msi_used_lock);
- if (!test_bit(hwirq, msi_used))
- pr_err("trying to free unused MSI#%d\n", hwirq);
- else
- clear_bit(hwirq, msi_used);
- mutex_unlock(&msi_used_lock);
+ return -EINVAL;
}
-static int armada_370_xp_setup_msi_irq(struct msi_controller *chip,
- struct pci_dev *pdev,
- struct msi_desc *desc)
-{
- struct msi_msg msg;
- int virq, hwirq;
+static struct irq_chip armada_370_xp_msi_bottom_irq_chip = {
+ .name = "MPIC MSI",
+ .irq_compose_msi_msg = armada_370_xp_compose_msi_msg,
+ .irq_set_affinity = armada_370_xp_msi_set_affinity,
+};
- /* We support MSI, but not MSI-X */
- if (desc->msi_attrib.is_msix)
- return -EINVAL;
+static int armada_370_xp_msi_alloc(struct irq_domain *domain, unsigned int virq,
+ unsigned int nr_irqs, void *args)
+{
+ int hwirq, i;
- hwirq = armada_370_xp_alloc_msi();
- if (hwirq < 0)
- return hwirq;
+ mutex_lock(&msi_used_lock);
- virq = irq_create_mapping(armada_370_xp_msi_domain, hwirq);
- if (!virq) {
- armada_370_xp_free_msi(hwirq);
- return -EINVAL;
+ hwirq = bitmap_find_next_zero_area(msi_used, PCI_MSI_DOORBELL_NR,
+ 0, nr_irqs, 0);
+ if (hwirq >= PCI_MSI_DOORBELL_NR) {
+ mutex_unlock(&msi_used_lock);
+ return -ENOSPC;
}
- irq_set_msi_desc(virq, desc);
-
- msg.address_lo = msi_doorbell_addr;
- msg.address_hi = 0;
- msg.data = 0xf00 | (hwirq + 16);
-
- pci_write_msi_msg(virq, &msg);
- return 0;
-}
+ bitmap_set(msi_used, hwirq, nr_irqs);
+ mutex_unlock(&msi_used_lock);
-static void armada_370_xp_teardown_msi_irq(struct msi_controller *chip,
- unsigned int irq)
-{
- struct irq_data *d = irq_get_irq_data(irq);
- unsigned long hwirq = d->hwirq;
+ for (i = 0; i < nr_irqs; i++) {
+ irq_domain_set_info(domain, virq + i, hwirq + i,
+ &armada_370_xp_msi_bottom_irq_chip,
+ domain->host_data, handle_simple_irq,
+ NULL, NULL);
+ }
- irq_dispose_mapping(irq);
- armada_370_xp_free_msi(hwirq);
+ return hwirq;
}
-static struct irq_chip armada_370_xp_msi_irq_chip = {
- .name = "armada_370_xp_msi_irq",
- .irq_enable = pci_msi_unmask_irq,
- .irq_disable = pci_msi_mask_irq,
- .irq_mask = pci_msi_mask_irq,
- .irq_unmask = pci_msi_unmask_irq,
-};
-
-static int armada_370_xp_msi_map(struct irq_domain *domain, unsigned int virq,
- irq_hw_number_t hw)
+static void armada_370_xp_msi_free(struct irq_domain *domain,
+ unsigned int virq, unsigned int nr_irqs)
{
- irq_set_chip_and_handler(virq, &armada_370_xp_msi_irq_chip,
- handle_simple_irq);
+ struct irq_data *d = irq_domain_get_irq_data(domain, virq);
- return 0;
+ mutex_lock(&msi_used_lock);
+ bitmap_clear(msi_used, d->hwirq, nr_irqs);
+ mutex_unlock(&msi_used_lock);
}
-static const struct irq_domain_ops armada_370_xp_msi_irq_ops = {
- .map = armada_370_xp_msi_map,
+static const struct irq_domain_ops armada_370_xp_msi_domain_ops = {
+ .alloc = armada_370_xp_msi_alloc,
+ .free = armada_370_xp_msi_free,
};
static int armada_370_xp_msi_init(struct device_node *node,
phys_addr_t main_int_phys_base)
{
- struct msi_controller *msi_chip;
u32 reg;
- int ret;
msi_doorbell_addr = main_int_phys_base +
ARMADA_370_XP_SW_TRIG_INT_OFFS;
- msi_chip = kzalloc(sizeof(*msi_chip), GFP_KERNEL);
- if (!msi_chip)
+ armada_370_xp_msi_inner_domain =
+ irq_domain_add_linear(NULL, PCI_MSI_DOORBELL_NR,
+ &armada_370_xp_msi_domain_ops, NULL);
+ if (!armada_370_xp_msi_inner_domain)
return -ENOMEM;
- msi_chip->setup_irq = armada_370_xp_setup_msi_irq;
- msi_chip->teardown_irq = armada_370_xp_teardown_msi_irq;
- msi_chip->of_node = node;
-
armada_370_xp_msi_domain =
- irq_domain_add_linear(NULL, PCI_MSI_DOORBELL_NR,
- &armada_370_xp_msi_irq_ops,
- NULL);
+ pci_msi_create_irq_domain(of_node_to_fwnode(node),
+ &armada_370_xp_msi_domain_info,
+ armada_370_xp_msi_inner_domain);
if (!armada_370_xp_msi_domain) {
- kfree(msi_chip);
+ irq_domain_remove(armada_370_xp_msi_inner_domain);
return -ENOMEM;
}
- ret = of_pci_msi_chip_add(msi_chip);
- if (ret < 0) {
- irq_domain_remove(armada_370_xp_msi_domain);
- kfree(msi_chip);
- return ret;
- }
-
reg = readl(per_cpu_int_base + ARMADA_370_XP_IN_DRBEL_MSK_OFFS)
| PCI_MSI_DOORBELL_MASK;
@@ -280,7 +256,7 @@ static int armada_xp_set_affinity(struct irq_data *d,
#endif
static struct irq_chip armada_370_xp_irq_chip = {
- .name = "armada_370_xp_irq",
+ .name = "MPIC",
.irq_mask = armada_370_xp_irq_mask,
.irq_mask_ack = armada_370_xp_irq_mask,
.irq_unmask = armada_370_xp_irq_unmask,
@@ -427,12 +403,12 @@ static void armada_370_xp_handle_msi_irq(struct pt_regs *regs, bool is_chained)
continue;
if (is_chained) {
- irq = irq_find_mapping(armada_370_xp_msi_domain,
- msinr - 16);
+ irq = irq_find_mapping(armada_370_xp_msi_inner_domain,
+ msinr - PCI_MSI_DOORBELL_START);
generic_handle_irq(irq);
} else {
- irq = msinr - 16;
- handle_domain_irq(armada_370_xp_msi_domain,
+ irq = msinr - PCI_MSI_DOORBELL_START;
+ handle_domain_irq(armada_370_xp_msi_inner_domain,
irq, regs);
}
}
@@ -604,8 +580,8 @@ static int __init armada_370_xp_mpic_of_init(struct device_node *node,
armada_370_xp_mpic_domain =
irq_domain_add_linear(node, nr_irqs,
&armada_370_xp_mpic_irq_ops, NULL);
-
BUG_ON(!armada_370_xp_mpic_domain);
+ armada_370_xp_mpic_domain->bus_token = DOMAIN_BUS_WIRED;
/* Setup for the boot CPU */
armada_xp_mpic_perf_init();