/* * Annapurna Labs MSIX support services * * Copyright (C) 2016, Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Antoine Tenart <antoine.tenart@free-electrons.com> * * 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.
*/
struct alpine_msix_data {
spinlock_t msi_map_lock;
phys_addr_t addr;
u32 spi_first; /* The SGI number that MSIs start */
u32 num_spis; /* The number of SGIs for MSIs */ unsignedlong *msi_map;
};
staticint alpine_msix_allocate_sgi(struct alpine_msix_data *priv, int num_req)
{ int first;
guard(spinlock)(&priv->msi_map_lock);
first = bitmap_find_next_zero_area(priv->msi_map, priv->num_spis, 0, num_req, 0); if (first >= priv->num_spis) return -ENOSPC;
ret = of_address_to_resource(node, 0, &res); if (ret) {
pr_err("Failed to allocate resource\n"); return ret;
}
/* * The 20 least significant bits of addr provide direct information * regarding the interrupt destination. * * To select the primary GIC as the target GIC, bits [18:17] must be set * to 0x0. In this case, bit 16 (SPI_TARGET_CLUSTER0) must be set.
*/
priv->addr = res.start & GENMASK_ULL(63,20);
priv->addr |= ALPINE_MSIX_SPI_TARGET_CLUSTER0;
if (of_property_read_u32(node, "al,msi-base-spi", &priv->spi_first)) {
pr_err("Unable to parse MSI base\n"); return -EINVAL;
}
if (of_property_read_u32(node, "al,msi-num-spis", &priv->num_spis)) {
pr_err("Unable to parse MSI numbers\n"); return -EINVAL;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.