/* 64 irqs (Pin0-pin63) are reserved for each mbigen chip */ #define RESERVED_IRQ_PER_MBIGEN_CHIP 64
/* The maximum IRQ pin number of mbigen chip(start from 0) */ #define MAXIMUM_IRQ_PIN_NUM 1407
/* * In mbigen vector register * bit[21:12]: event id value * bit[11:0]: device id
*/ #define IRQ_EVENT_ID_SHIFT 12 #define IRQ_EVENT_ID_MASK 0x3ff
/* register range of each mbigen node */ #define MBIGEN_NODE_OFFSET 0x1000
/* offset of vector register in mbigen node */ #define REG_MBIGEN_VEC_OFFSET 0x200
/* * offset of clear register in mbigen node * This register is used to clear the status * of interrupt
*/ #define REG_MBIGEN_CLEAR_OFFSET 0xa000
/* * offset of interrupt type register * This register is used to configure interrupt * trigger type
*/ #define REG_MBIGEN_TYPE_OFFSET 0x0
/** * struct mbigen_device - holds the information of mbigen device. * * @pdev: pointer to the platform device structure of mbigen chip. * @base: mapped address of this mbigen chip.
*/ struct mbigen_device { struct platform_device *pdev; void __iomem *base;
};
staticinlineunsignedint get_mbigen_node_offset(unsignedint nid)
{ unsignedint offset = nid * MBIGEN_NODE_OFFSET;
/* * To avoid touched clear register in unexpected way, we need to directly * skip clear register when access to more than 10 mbigen nodes.
*/ if (nid >= (REG_MBIGEN_CLEAR_OFFSET / MBIGEN_NODE_OFFSET))
offset += MBIGEN_NODE_OFFSET;
base += get_mbigen_vec_reg(d->hwirq);
val = readl_relaxed(base);
val &= ~(IRQ_EVENT_ID_MASK << IRQ_EVENT_ID_SHIFT);
val |= (msg->data << IRQ_EVENT_ID_SHIFT);
/* The address of doorbell is encoded in mbigen register by default * So,we don't need to program the doorbell address at here
*/
writel_relaxed(val, base);
}
/* If there is no valid irq type, just use the default type */ if ((fwspec->param[1] == IRQ_TYPE_EDGE_RISING) ||
(fwspec->param[1] == IRQ_TYPE_LEVEL_HIGH))
*type = fwspec->param[1]; else return -EINVAL;
/* * "num-pins" is the total number of interrupt pins implemented in * this mbigen instance, and mbigen is an interrupt controller * connected to ITS converting wired interrupts into MSI, so we * use "num-pins" to alloc MSI vectors which are needed by client * devices connected to it. * * Here is the DSDT device node used for mbigen in firmware: * Device(MBI0) { * Name(_HID, "HISI0152") * Name(_UID, Zero) * Name(_CRS, ResourceTemplate() { * Memory32Fixed(ReadWrite, 0xa0080000, 0x10000) * }) * * Name(_DSD, Package () { * ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), * Package () { * Package () {"num-pins", 378} * } * }) * }
*/
ret = device_property_read_u32(&pdev->dev, "num-pins", &num_pins); if (ret || num_pins == 0) return -EINVAL;
if (!mbigen_create_device_domain(&pdev->dev, num_pins, mgn_chip)) return -ENOMEM;
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.