satip-axe/kernel/drivers/stm/pcie.c

912 lines
23 KiB
C

/*
* drivers/stm/pcie.c
*
* PCI express driver
*
* Copyright 2010 ST Microelectronics (R&D) Ltd.
* Author: David J. McKay (david.mckay@st.com)
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the top level directory for more details.
*
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
#include <linux/platform_device.h>
#include <linux/pci.h>
#include <linux/pci_regs.h>
#include <linux/msi.h>
#include <linux/errno.h>
#include <linux/io.h>
#include <linux/stm/platform.h>
#include <linux/stm/pci-glue.h>
#include <linux/stm/miphy.h>
#include <linux/gpio.h>
#include <linux/cache.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <asm/clock.h>
#include "pcie-regs.h"
struct stm_msi_info;
struct stm_pcie_dev_data {
void __iomem *cntrl; /* Main PCIe control registers */
void __iomem *ahb; /* Amba->stbus convertor registers */
void __iomem *config_area; /* Config read/write */
struct stm_msi_info *msi;
struct stm_miphy *miphy_dev; /* Handle for associated miphy */
};
/* Routines to access the DBI port of the synopsys IP. This contains the
* standard config registers, as well as some other registers. Unfortunately,
* byte and half word accesses are totally broken, as the synopsys IP doesn't
* support them. Which is a pain.
*
* We do not have a spinlock for these, so be careful of your usage. Relies on
* the config spinlock for config cycles.
*/
/* Little helper function to build up correct data */
static inline u32 shift_data_read(int where, int size, u32 data)
{
data >>= (8 * (where & 0x3));
switch (size) {
case 1:
data &= 0xff;
break;
case 2:
BUG_ON(where & 1);
data &= 0xffff;
break;
case 4:
BUG_ON(where & 3);
break;
default:
BUG();
}
return data;
}
static u32 dbi_read(struct stm_pcie_dev_data *priv, int where, int size)
{
u32 data;
/* Read the dword aligned data */
data = readl(priv->cntrl + (where & ~0x3));
return shift_data_read(where, size, data);
}
static inline u8 dbi_readb(struct stm_pcie_dev_data *priv, unsigned addr)
{
return (u8) dbi_read(priv, addr, 1);
}
static inline u16 dbi_readw(struct stm_pcie_dev_data *priv, unsigned addr)
{
return (u16) dbi_read(priv, addr, 2);
}
static inline u32 dbi_readl(struct stm_pcie_dev_data *priv, unsigned addr)
{
return dbi_read(priv, addr, 4);
}
static inline u32 shift_data_write(int where, int size, u32 val, u32 data)
{
int shift_bits = (where & 0x3) * 8;
switch (size) {
case 1:
data &= ~(0xff << shift_bits);
data |= ((val & 0xff) << shift_bits);
break;
case 2:
data &= ~(0xffff << shift_bits);
data |= ((val & 0xffff) << shift_bits);
BUG_ON(where & 1);
break;
case 4:
data = val;
BUG_ON(where & 3);
break;
default:
BUG();
}
return data;
}
static void dbi_write(struct stm_pcie_dev_data *priv,
u32 val, int where, int size)
{
u32 data;
int aligned_addr = where & ~0x3;
/* Read the dword aligned data if we have to */
if (size != 4)
data = readl(priv->cntrl + aligned_addr);
data = shift_data_write(where, size, val, data);
writel(data, priv->cntrl + aligned_addr);
}
static inline void dbi_writeb(struct stm_pcie_dev_data *priv,
u8 val, unsigned addr)
{
dbi_write(priv, (u32) val, addr, 1);
}
static inline void dbi_writew(struct stm_pcie_dev_data *priv,
u16 val, unsigned addr)
{
dbi_write(priv, (u32) val, addr, 2);
}
static inline void dbi_writel(struct stm_pcie_dev_data *priv,
u32 val, unsigned addr)
{
dbi_write(priv, (u32) val, addr, 4);
}
static inline void pcie_cap_writew(struct stm_pcie_dev_data *priv,
u16 val, unsigned cap)
{
dbi_writew(priv, val, CFG_PCIE_CAP + cap);
}
static inline u16 pcie_cap_readw(struct stm_pcie_dev_data *priv,
unsigned cap)
{
return dbi_readw(priv, CFG_PCIE_CAP + cap);
}
/* Time to wait between testing the link in usecs. There is a mystery
* here, in that if you reduce this time to say 10us, the link never
* actually appears to come up. I cannot think of any explanation
* for this behaviour
*/
#define LINK_LOOP_DELAY_USECS 8000
/* Total amount of time to wait for the link to come up in msecs */
#define LINK_WAIT_MSECS 80
#define LINK_LOOP_COUNT ((LINK_WAIT_MSECS * 1000) / LINK_LOOP_DELAY_USECS)
/* Function to test if the link is in an operational state or not. We must
* ensure the link is operational before we try to do a configuration access,
* as the hardware hangs if the link is down. I think this is a bug.
*/
static int link_up(struct stm_pcie_dev_data *priv)
{
u32 status;
int link_up;
int count = 0;
/* We have to be careful here. This is used in config read/write,
* The higher levels switch off interrupts, so you cannot use
* jiffies to do a timeout, or reschedule
*/
do {
/* What about L2? I think software intervention is
* required to get it out of L2, so in effect the link
* is down. Requires more work when/if we implement power
* management
*/
status = dbi_readl(priv, PORT_LOGIC_DEBUG_REG_0);
status &= DEBUG_REG_0_LTSSM_MASK;
link_up = (status == S_L0) || (status == S_L0S) ||
(status == S_L1_IDLE);
/* It can take some considerable time for the link to actually
* come up, caused by the PLLs. Experiments indicate it takes
* about 8ms to actually bring the link up, but this can vary
* considerably according to the specification. This code should
* allow sufficient time
*/
if (!link_up)
udelay(LINK_LOOP_DELAY_USECS);
} while (!link_up && ++count < LINK_LOOP_COUNT);
return link_up;
}
/* Spinlock for access to configuration space. We have to do read-modify-write
* cycles here, so need to lock out for the duration to prevent races
*/
static DEFINE_SPINLOCK(stm_pcie_config_lock);
static struct stm_pcie_dev_data *stm_pci_bus_to_dev_data(struct pci_bus *bus)
{
struct platform_device *pdev;
/* This must only be called for pci express type buses */
if (stm_pci_controller_type(bus) != STM_PCI_EXPRESS)
return NULL;
pdev = stm_pci_bus_to_platform(bus);
if (!pdev)
return NULL;
return platform_get_drvdata(pdev);
}
static int stm_pcie_config_read(struct pci_bus *bus, unsigned int devfn,
int where, int size, u32 *val)
{
u16 bdf;
u32 data;
int slot = PCI_SLOT(devfn);
unsigned long flags;
struct stm_pcie_dev_data *priv = stm_pci_bus_to_dev_data(bus);
if (!priv) {
*val = ~0;
return PCIBIOS_DEVICE_NOT_FOUND;
}
/* It's not clear to me how this works when we have a switch in the
* system. If you have a PCIe switch, you can only have one EP on each
* link, so there is no point in probing multiple devices. I think the
* upper layer should probably know this hopefully, as it is tricky to
* filter it out at this level. For the root complex it is trivial
* though.
*/
if ((pci_is_root_bus(bus) && slot != 1) || !link_up(priv)) {
*val = ~0;
return PCIBIOS_DEVICE_NOT_FOUND;
}
bdf = (bus->number << 8) | devfn;
/* Claim lock, FUNC0_BDF_NUM has to remain unchanged for the whole
* cycle
*/
spin_lock_irqsave(&stm_pcie_config_lock, flags);
/* Set the config packet devfn */
dbi_writel(priv, bdf, FUNC0_BDF_NUM);
/* Read the dword aligned data */
data = readl(priv->config_area + (where & ~0x3));
spin_unlock_irqrestore(&stm_pcie_config_lock, flags);
*val = shift_data_read(where, size, data);
return PCIBIOS_SUCCESSFUL;
}
static int stm_pcie_config_write(struct pci_bus *bus, unsigned int devfn,
int where, int size, u32 val)
{
unsigned long flags;
u16 bdf;
u32 data;
int slot = PCI_SLOT(devfn);
struct stm_pcie_dev_data *priv = stm_pci_bus_to_dev_data(bus);
if (!priv || (pci_is_root_bus(bus) && slot != 1) || !link_up(priv))
return PCIBIOS_DEVICE_NOT_FOUND;
bdf = (bus->number << 8) | devfn;
/* Claim lock, FUNC0_BDF_NUM has to remain unchanged for the whole
* cycle
*/
spin_lock_irqsave(&stm_pcie_config_lock, flags);
/* Set the config packet devfn */
dbi_writel(priv, bdf, FUNC0_BDF_NUM);
/* Read the dword aligned data */
if (size != 4)
data = readl(priv->config_area + (where & ~0x3));
data = shift_data_write(where, size, val, data);
writel(data, priv->config_area + (where & ~0x3));
spin_unlock_irqrestore(&stm_pcie_config_lock, flags);
return PCIBIOS_SUCCESSFUL;
}
/* The configuration read/write functions. This is exported so
* the arch specific code can do whatever is needed to plug it
* into its framework
*/
static struct pci_ops stm_pcie_config_ops = {
.read = stm_pcie_config_read,
.write = stm_pcie_config_write,
};
static void stm_pcie_board_reset(struct device *dev)
{
struct stm_plat_pcie_config *config = dev_get_platdata(dev);
/* We have a valid function, so call it */
if (config->reset) {
config->reset();
return;
}
/* We haven't got a valid gpio */
if (!gpio_is_valid(config->reset_gpio))
return;
if (gpio_direction_output(config->reset_gpio, 0)) {
dev_err(dev, "Cannot set PERST# (gpio %u) to output\n",
config->reset_gpio);
return;
}
mdelay(1); /* From PCIe spec */
gpio_direction_output(config->reset_gpio, 1);
}
/* Sets up any clocking, resets the controller and disables link training */
static int __devinit stm_pcie_hw_init(struct device *dev)
{
struct stm_plat_pcie_config *config = dev_get_platdata(dev);
struct stm_plat_pcie_ops *ops = config->ops;
if (!ops)
return -EINVAL;
ops->init(config->ops_handle);
ops->disable_ltssm(config->ops_handle);
return 0;
}
static int __devinit stm_pcie_hw_setup(struct device *dev,
unsigned long pci_window_start,
unsigned long pci_window_size,
unsigned long config_window_start)
{
struct stm_plat_pcie_config *config = dev_get_platdata(dev);
struct stm_pcie_dev_data *priv = dev_get_drvdata(dev);
struct stm_plat_pcie_ops *ops = config->ops;
if (!ops)
return -EINVAL;
ops->disable_ltssm(config->ops_handle);
/* Don't see any point in enabling IO here */
dbi_writew(priv, PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER, PCI_COMMAND);
/* Set up the config window to the top of the PCI address space */
dbi_writel(priv, config_window_start, CFG_BASE_ADDRESS);
/* Open up all of memory to the PCI controller. We could do slightly
* better than this and exclude the kernel text segment and bss etc.
* They are base/limit registers so can be of arbitrary alignment
* presumably
*/
dbi_writel(priv, CONFIG_MEMORY_START, IN0_MEM_ADDR_START);
dbi_writel(priv, CONFIG_MEMORY_START + CONFIG_MEMORY_SIZE - 1,
IN0_MEM_ADDR_LIMIT);
/* Disable the 2nd region */
dbi_writel(priv, ~0, IN1_MEM_ADDR_START);
dbi_writel(priv, 0, IN1_MEM_ADDR_LIMIT);
dbi_writel(priv, RC_PASS_ADDR_RANGE, TRANSLATION_CONTROL);
/* This will die as we will have a common method of setting the bridge
* settings
*/
writel(config->ahb_val, priv->ahb + 4);
/* Later versions of the AMBA bridge have a merging capability, whereby
* reads and writes are merged into an AHB burst transaction. This
* breaks PCIe as it will then prefetch a maximally sized transaction.
* We have to disable this capability, which is controlled by bit 3 of
* the SD_CONFIG register. Bit 2 (the busy bit) must always be written
* as zero. We set the cont_on_error bit, as this is the reset state.
*/
writel(0x2, priv->ahb);
/* Now assert the board level reset to the other PCIe device */
stm_pcie_board_reset(dev);
/* Re-enable the link */
ops->enable_ltssm(config->ops_handle);
return 0;
}
static int __devinit remap_named_resource(struct platform_device *pdev,
const char *name,
void __iomem **io_ptr)
{
struct resource *res;
resource_size_t size;
void __iomem *p;
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, name);
if (!res)
return -ENXIO;
size = resource_size(res);
if (!devm_request_mem_region(&pdev->dev,
res->start, size, name))
return -EBUSY;
p = devm_ioremap_nocache(&pdev->dev, res->start, size);
if (!p)
return -ENOMEM;
*io_ptr = p;
return 0;
}
static irqreturn_t stm_pcie_sys_err(int irq, void *dev_data)
{
panic("PCI express serious error raised\n");
}
#ifdef CONFIG_PCI_MSI
static int __devinit stm_msi_probe(struct platform_device *pdev);
#else
static int __devinit stm_msi_probe(struct platform_device *pdev) { return 0; }
#endif
/* Probe function for PCI data When we get here, we can assume that the PCI
* block is powered up and ready to rock, and that all sysconfigs have been
* set correctly.
*/
static int __devinit stm_pcie_probe(struct platform_device *pdev)
{
struct resource *res;
unsigned long pci_window_start, pci_window_size;
struct stm_plat_pcie_config *config = dev_get_platdata(&pdev->dev);
unsigned long config_window_start;
struct stm_pcie_dev_data *priv;
int err, serr_irq;
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
platform_set_drvdata(pdev, priv);
err = remap_named_resource(pdev, "pcie cntrl", &priv->cntrl);
if (err)
return err;
err = remap_named_resource(pdev, "pcie ahb", &priv->ahb);
if (err)
return err;
/* Extract where the PCI memory window is supposed to be */
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pcie memory");
if (!res)
return -ENXIO;
pci_window_start = res->start;
/* We put the start of the configuration region at the very top of the
* PCI window so we don't have an annoying 64K chunk at the bottom
* destroying our nice alignment
*/
config_window_start =
(res->end - (CFG_REGION_SIZE - 1)) & ~(CFG_REGION_SIZE - 1);
pci_window_size = config_window_start - pci_window_start;
/* Now remap the config region */
if (!devm_request_mem_region
(&pdev->dev, config_window_start, CFG_REGION_SIZE, "pcie config"))
return -EBUSY;
priv->config_area =
devm_ioremap_nocache(&pdev->dev, config_window_start,
CFG_REGION_SIZE);
if (!priv->config_area)
return -ENOMEM;
serr_irq = platform_get_irq_byname(pdev, "pcie syserr");
if (serr_irq < 0)
return serr_irq;
err = devm_request_irq(&pdev->dev, serr_irq, stm_pcie_sys_err,
IRQF_DISABLED, "pcie syserr", priv);
if (err)
return err;
/* We have to initialise the PCIe cell on some hardware before we can
* talk to the phy
*/
err = stm_pcie_hw_init(&pdev->dev);
if (err)
return err;
/* Now claim the associated miphy */
priv->miphy_dev = stm_miphy_claim(config->miphy_num, PCIE_MODE,
&pdev->dev);
if (!priv->miphy_dev) {
dev_err(&pdev->dev, "Cannot claim MiPHY %d!\n",
config->miphy_num);
return -EBUSY;
}
/* Claim the GPIO for PRST# if available */
if (!config->reset && gpio_is_valid(config->reset_gpio) &&
gpio_request(config->reset_gpio, "PERST#")) {
dev_err(&pdev->dev, "Cannot request reset PIO %d\n",
config->reset_gpio);
config->reset_gpio = -EINVAL;
}
/* Now do all the register poking */
err = stm_pcie_hw_setup(&pdev->dev, pci_window_start, pci_window_size,
config_window_start);
if (err)
return err;
/* MSI configuration */
err = stm_msi_probe(pdev);
if (err)
return err;
/* And now hook this into the generic driver */
err = stm_pci_register_controller(pdev, &stm_pcie_config_ops,
STM_PCI_EXPRESS);
return err;
}
static struct platform_driver stm_pcie_driver = {
.driver.name = "pcie_stm",
.driver.owner = THIS_MODULE,
.probe = stm_pcie_probe,
};
static int __init stm_pcie_init(void)
{
return platform_driver_register(&stm_pcie_driver);
}
subsys_initcall(stm_pcie_init);
#ifdef CONFIG_PCI_MSI
/* When allocating interrupts to endpoints, we have to have a lock, but
* we can use a global one for everybody as there is not going to be
* any contention
*/
static DEFINE_SPINLOCK(msi_alloc_lock);
struct stm_msi_info {
void __iomem *regs;
unsigned first_irq, last_irq, mux_irq;
int num_irqs_per_ep;
int num_eps;
int ep_allocated[MSI_NUM_ENDPOINTS];
spinlock_t reg_lock;
};
static inline int irq_to_ep(struct stm_msi_info *msi, unsigned int irq)
{
return (irq - msi->first_irq) / msi->num_irqs_per_ep;
}
/* Which bit in the irq, 0 means bit 0 etc */
static inline int irq_to_bitnum(struct stm_msi_info *msi, unsigned int irq)
{
return (irq - msi->first_irq) % msi->num_irqs_per_ep;
}
static inline int irq_num(struct stm_msi_info *msi, int ep_num, int bitnum)
{
return (ep_num * msi->num_irqs_per_ep) + bitnum + msi->first_irq;
}
static void msi_irq_demux(unsigned int mux_irq, struct irq_desc *mux_desc)
{
int ep;
int bitnum;
u32 status;
u32 mask;
int irq;
struct stm_msi_info *msi = get_irq_desc_data(mux_desc);
/* Run down the status registers looking for which one to take.
* No need for any locks, we only ever read stuff here
*/
for (ep = 0; ep < msi->num_eps; ep++) {
do {
status = readl(msi->regs + MSI_INTERRUPT_STATUS(ep));
mask = readl(msi->regs + MSI_INTERRUPT_MASK(ep));
status &= ~mask;
if (status) {
/* ffs return 1 if bit zero set */
bitnum = ffs(status) - 1 ;
irq = irq_num(msi, ep, bitnum);
generic_handle_irq(irq);
}
} while (status);
}
}
static inline void set_msi_bit(struct stm_msi_info *msi,
unsigned int reg_base, unsigned int irq)
{
int ep = irq_to_ep(msi, irq);
int val;
unsigned long flags;
spin_lock_irqsave(&msi->reg_lock, flags);
val = readl(msi->regs + reg_base + MSI_OFFSET_REG(ep));
val |= 1 << irq_to_bitnum(msi, irq);
writel(val, msi->regs + reg_base + MSI_OFFSET_REG(ep));
/* Read back for write posting */
readl(msi->regs + reg_base + MSI_OFFSET_REG(ep));
spin_unlock_irqrestore(&msi->reg_lock, flags);
}
static inline void clear_msi_bit(struct stm_msi_info *msi,
unsigned int reg_base, unsigned int irq)
{
int ep = irq_to_ep(msi, irq);
int val;
unsigned long flags;
spin_lock_irqsave(&msi->reg_lock, flags);
val = readl(msi->regs + reg_base + MSI_OFFSET_REG(ep));
val &= ~(1 << irq_to_bitnum(msi, irq));
writel(val, msi->regs + reg_base + MSI_OFFSET_REG(ep));
/* Read back for write posting */
readl(msi->regs + reg_base + MSI_OFFSET_REG(ep));
spin_unlock_irqrestore(&msi->reg_lock, flags);
}
static void stm_enable_msi_irq(unsigned int irq)
{
struct stm_msi_info *msi = get_irq_data(irq);
set_msi_bit(msi, MSI_INTERRUPT_ENABLE(0), irq);
/* The generic code will have masked all interrupts for device that
* support the optional Mask capability. Therefore we have to unmask
* interrupts on the device if the device supports the Mask capability.
*
* We do not have to this in the irq mask/unmask functions, as we can
* mask at the MSI interrupt controller itself.
*/
unmask_msi_irq(irq);
}
static void stm_disable_msi_irq(unsigned int irq)
{
struct stm_msi_info *msi = get_irq_data(irq);
/* Disable the msi irq on the device */
mask_msi_irq(irq);
clear_msi_bit(msi, MSI_INTERRUPT_ENABLE(0), irq);
}
static void stm_mask_msi_irq(unsigned int irq)
{
struct stm_msi_info *msi = get_irq_data(irq);
set_msi_bit(msi, MSI_INTERRUPT_MASK(0), irq);
}
static void stm_unmask_msi_irq(unsigned int irq)
{
struct stm_msi_info *msi = get_irq_data(irq);
clear_msi_bit(msi, MSI_INTERRUPT_MASK(0), irq);
}
static void stm_ack_msi_irq(unsigned int irq)
{
struct stm_msi_info *msi = get_irq_data(irq);
int ep = irq_to_ep(msi, irq);
int val;
/* Don't need to do a RMW cycle here, as
* the hardware is sane
*/
val = (1 << irq_to_bitnum(msi, irq));
writel(val, msi->regs + MSI_INTERRUPT_STATUS(ep));
/* Read back for write posting */
readl(msi->regs + MSI_INTERRUPT_STATUS(ep));
}
static struct irq_chip msi_chip = {
.name = "pcie",
.enable = stm_enable_msi_irq,
.disable = stm_disable_msi_irq,
.mask = stm_mask_msi_irq,
.unmask = stm_unmask_msi_irq,
.ack = stm_ack_msi_irq,
};
static void __devinit msi_init_one(struct stm_msi_info *msi)
{
int ep;
/* Set the magic address the hardware responds to. This has to be in
* the range the PCI controller can write to. We just use the value
* of the stm_msi_info data structure, but anything will do
*/
writel(0, msi->regs + MSI_UPPER_ADDRESS);
writel(virt_to_phys(msi), msi->regs + MSI_ADDRESS);
/* Disable everything to start with */
for (ep = 0; ep < MSI_NUM_ENDPOINTS; ep++) {
writel(0, msi->regs + MSI_INTERRUPT_ENABLE(ep));
writel(0, msi->regs + MSI_INTERRUPT_MASK(ep));
writel(~0, msi->regs + MSI_INTERRUPT_STATUS(ep));
}
}
static int __devinit stm_msi_probe(struct platform_device *pdev)
{
int irq;
struct resource *res;
struct stm_pcie_dev_data *priv = platform_get_drvdata(pdev);
struct stm_msi_info *msi;
int num_irqs;
msi = devm_kzalloc(&pdev->dev, sizeof(*msi), GFP_KERNEL);
if (!msi)
return -ENOMEM;
spin_lock_init(&msi->reg_lock);
/* Copy over the register pointer for convenience */
msi->regs = priv->cntrl;
res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "msi range");
if (!res)
return -ENODEV;
msi->first_irq = res->start;
num_irqs = resource_size(res);
msi->num_eps = min(num_irqs, MSI_NUM_ENDPOINTS);
msi->num_irqs_per_ep = rounddown_pow_of_two(num_irqs / msi->num_eps);
/* Maximum of 32 irqs per endpoint */
if (msi->num_irqs_per_ep > 32)
msi->num_irqs_per_ep = 32;
if (msi->num_irqs_per_ep == 0)
return -ENOSPC;
num_irqs = msi->num_irqs_per_ep * msi->num_eps;
msi->last_irq = msi->first_irq + num_irqs - 1;
res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "msi mux");
if (!res)
return -ENODEV;
msi->mux_irq = res->start;
msi_init_one(msi);
/* Hook up the multiplexor */
set_irq_chained_handler(msi->mux_irq, msi_irq_demux);
set_irq_data(msi->mux_irq, msi);
for (irq = msi->first_irq; irq <= msi->last_irq; irq++) {
if (get_irq_chip(irq) != &no_irq_chip)
dev_err(&pdev->dev, "MSI irq %d in use!!\n", irq);
set_irq_chip_and_handler_name(irq, &msi_chip,
handle_level_irq, "msi");
set_irq_data(irq, msi);
}
/* Set the private data, arch_setup_msi_irq() will always fail
* if we haven't got as far as this
*/
priv->msi = msi;
return 0;
}
int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
{
int ep;
struct msi_msg msg;
int irq;
struct stm_pcie_dev_data *priv;
struct stm_msi_info *msi;
/* It is legitimate for this function to be called with a non-express
* bus device, as it is a global function. This check ensures that it
* will fail in this case, as the stm_pci_bus_to_dev_data() checks
* that it is being called on an express bus and will return NULL
* otherwise
*/
priv = stm_pci_bus_to_dev_data(dev->bus);
if (!priv)
return -ENXIO;
msi = priv->msi;
if (!msi)
return -ENXIO;
/* We only support one interrupt, although the hardware can do 32.
* The reason is that we currently do not implement
* arch_setup_msi_irqs() (plural) and things will go wrong if allocate
* more than one interrupt here. If there is a need we can implement
* it in the future.
*/
spin_lock(&msi_alloc_lock);
/* Now we have to find a free EP to use */
for (ep = 0; ep < msi->num_eps; ep++)
if (!msi->ep_allocated[ep])
break;
/* Hell, they are all in use. We are stuffed */
if (ep == msi->num_eps) {
spin_unlock(&msi_alloc_lock);
return -ENOSPC;
}
irq = irq_num(msi, ep, 0);
msi->ep_allocated[ep] = irq;
spin_unlock(&msi_alloc_lock);
/* Set up the data the card needs in order to raise
* interrupt. The format of the data word is
* [7:5] Selects endpoint register
* [4:0] Interrupt number to raise
*/
msg.data = (ep << 5);
msg.address_hi = 0;
msg.address_lo = virt_to_phys(msi);
/* We have to update this, it will be written back to the chip by
* write_msi_msg()
*/
desc->msi_attrib.multiple = 0;
set_irq_msi(irq, desc);
write_msi_msg(irq, &msg);
return 0;
}
void arch_teardown_msi_irq(unsigned int irq)
{
struct stm_msi_info *msi = get_irq_data(irq);
int ep = irq_to_ep(msi, irq);
spin_lock(&msi_alloc_lock);
msi->ep_allocated[ep] = 0;
spin_unlock(&msi_alloc_lock);
}
#endif /* CONFIG_PCI_MSI */