2008-05-23 16:32:46 +08:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2007-2008 Freescale Semiconductor, Inc. All rights reserved.
|
|
|
|
*
|
|
|
|
* Author: Tony Li <tony.li@freescale.com>
|
|
|
|
* Jason Jin <Jason.jin@freescale.com>
|
|
|
|
*
|
|
|
|
* 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; version 2 of the
|
|
|
|
* License.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
#ifndef _POWERPC_SYSDEV_FSL_MSI_H
|
|
|
|
#define _POWERPC_SYSDEV_FSL_MSI_H
|
|
|
|
|
powerpc/fsl_msi: add support for the fsl, msi property in PCI nodes
On Freescale parts with multiple MSI controllers, the controllers are
combined into one "pool" of interrupts. Whenever a device requests an MSI
interrupt, the next available interrupt from the pool is selected,
regardless of which MSI controller the interrupt is from. This works
because each PCI bus has an ATMU to all of CCSR, so any PCI device can
access any MSI interrupt register.
The fsl,msi property is used to specify that a given PCI bus should only
use a specific MSI device. This is necessary, for example, with the
Freescale hypervisor, because the MSI devices are assigned to specific
partitions.
Ideally, we'd like to be able to assign MSI devices to PCI busses within
the MSI or PCI layers. However, there does not appear to be a mechanism
to do that. Whenever the MSI layer wants to allocate an MSI interrupt to
a PCI device, it just calls arch_setup_msi_irqs(). It would be nice if we
could register an MSI device with a specific PCI bus.
So instead we remember the phandles of each MSI device, and we use that to
limit our search for an available interrupt. Whenever we are asked to
allocate a new interrupt for a PCI device, we check the fsl,msi property
of the PCI bus for that device. If it exists, then as we are looping over
all MSI devices, we skip the ones that don't have a matching phandle.
Signed-off-by: Timur Tabi <timur@freescale.com>
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
2011-11-01 06:06:35 +08:00
|
|
|
#include <linux/of.h>
|
2008-08-06 07:10:02 +08:00
|
|
|
#include <asm/msi_bitmap.h>
|
|
|
|
|
2013-06-21 18:59:14 +08:00
|
|
|
#define NR_MSI_REG_MSIIR 8 /* MSIIR can index 8 MSI registers */
|
|
|
|
#define NR_MSI_REG_MSIIR1 16 /* MSIIR1 can index 16 MSI registers */
|
|
|
|
#define NR_MSI_REG_MAX NR_MSI_REG_MSIIR1
|
2008-05-23 16:32:46 +08:00
|
|
|
#define IRQS_PER_MSI_REG 32
|
2013-06-21 18:59:14 +08:00
|
|
|
#define NR_MSI_IRQS_MAX (NR_MSI_REG_MAX * IRQS_PER_MSI_REG)
|
2008-05-23 16:32:46 +08:00
|
|
|
|
2011-12-14 04:51:59 +08:00
|
|
|
#define FSL_PIC_IP_MASK 0x0000000F
|
|
|
|
#define FSL_PIC_IP_MPIC 0x00000001
|
|
|
|
#define FSL_PIC_IP_IPIC 0x00000002
|
|
|
|
#define FSL_PIC_IP_VMPIC 0x00000003
|
2008-05-23 16:32:46 +08:00
|
|
|
|
|
|
|
struct fsl_msi {
|
2012-02-15 05:06:50 +08:00
|
|
|
struct irq_domain *irqhost;
|
2008-05-23 16:32:46 +08:00
|
|
|
|
|
|
|
unsigned long cascade_irq;
|
|
|
|
|
2011-09-24 01:41:35 +08:00
|
|
|
u32 msiir_offset; /* Offset of MSIIR, relative to start of CCSR */
|
2013-06-21 18:59:14 +08:00
|
|
|
u32 ibs_shift; /* Shift of interrupt bit select */
|
|
|
|
u32 srs_shift; /* Shift of the shared interrupt register select */
|
2008-05-23 16:32:46 +08:00
|
|
|
void __iomem *msi_regs;
|
|
|
|
u32 feature;
|
2013-06-21 18:59:14 +08:00
|
|
|
int msi_virqs[NR_MSI_REG_MAX];
|
2008-05-23 16:32:46 +08:00
|
|
|
|
2008-08-06 07:10:02 +08:00
|
|
|
struct msi_bitmap bitmap;
|
2010-04-22 16:31:36 +08:00
|
|
|
|
|
|
|
struct list_head list; /* support multiple MSI banks */
|
powerpc/fsl_msi: add support for the fsl, msi property in PCI nodes
On Freescale parts with multiple MSI controllers, the controllers are
combined into one "pool" of interrupts. Whenever a device requests an MSI
interrupt, the next available interrupt from the pool is selected,
regardless of which MSI controller the interrupt is from. This works
because each PCI bus has an ATMU to all of CCSR, so any PCI device can
access any MSI interrupt register.
The fsl,msi property is used to specify that a given PCI bus should only
use a specific MSI device. This is necessary, for example, with the
Freescale hypervisor, because the MSI devices are assigned to specific
partitions.
Ideally, we'd like to be able to assign MSI devices to PCI busses within
the MSI or PCI layers. However, there does not appear to be a mechanism
to do that. Whenever the MSI layer wants to allocate an MSI interrupt to
a PCI device, it just calls arch_setup_msi_irqs(). It would be nice if we
could register an MSI device with a specific PCI bus.
So instead we remember the phandles of each MSI device, and we use that to
limit our search for an available interrupt. Whenever we are asked to
allocate a new interrupt for a PCI device, we check the fsl,msi property
of the PCI bus for that device. If it exists, then as we are looping over
all MSI devices, we skip the ones that don't have a matching phandle.
Signed-off-by: Timur Tabi <timur@freescale.com>
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
2011-11-01 06:06:35 +08:00
|
|
|
|
|
|
|
phandle phandle;
|
2008-05-23 16:32:46 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
#endif /* _POWERPC_SYSDEV_FSL_MSI_H */
|
|
|
|
|