From: Nikita Shubin Date: Mon, 10 Jun 2024 09:19:03 +0000 (+0300) Subject: [stage 1] mailbox: qemu-mailbox: Add txdone intr X-Git-Url: http://git.maquefel.me/?a=commitdiff_plain;h=9ea3c50c31f915b43ffa7f769e97e96ab770021a;p=linux.git [stage 1] mailbox: qemu-mailbox: Add txdone intr - add txdone separate interrupt - add startup()/shutdown() to unmask/mask interrupts Signed-off-by: Nikita Shubin --- diff --git a/drivers/mailbox/qemu-mailbox.c b/drivers/mailbox/qemu-mailbox.c index 999310989d897..1313b569a6255 100644 --- a/drivers/mailbox/qemu-mailbox.c +++ b/drivers/mailbox/qemu-mailbox.c @@ -21,6 +21,8 @@ #define QEMU_MBOX_CFG 0x0 #define QEMU_MBOX_ISTATUS 0x4 +#define QEMU_MBOX_IEN 0x8 +#define QEMU_MBOX_TXDONE 0x10 #define QEMU_MBOX_CHAN_STRIDE 0x20 #define QEMU_MBOX_CHAN_ADDR(chan) (QEMU_MBOX_CHAN_STRIDE + (chan * QEMU_MBOX_CHAN_STRIDE)) @@ -58,6 +60,24 @@ static irqreturn_t qemu_mbox_isr(int virq, void *data) return IRQ_HANDLED; } +static irqreturn_t qemu_mbox_txdone_isr(int virq, void *data) +{ + struct qemu_mbox *mbox = data; + struct mbox_chan *chan; + unsigned int stat = 0; + int offset; + + regmap_read(mbox->map, QEMU_MBOX_TXDONE, &stat); + + for_each_set_bit(offset, (unsigned long *)&stat, QEMU_MBOX_MAX_CHAN_CNT) { + chan = &mbox->mbox.chans[offset]; + if (chan->cl) + mbox_chan_txdone(chan, 0); + } + + return IRQ_HANDLED; +} + struct mbox_chan *qemu_mbox_request_channel(struct mbox_client *cl) { struct qemu_mbox *mbox = __mbox; @@ -86,6 +106,22 @@ static int qemu_mbox_send_data(struct mbox_chan *link, void *data) return regmap_write(mbox->map, QEMU_MBOX_CHAN_ADDR(chan), *msg); } +static int qemu_mbox_startup(struct mbox_chan *link) +{ + unsigned long chan = (unsigned long)link->con_priv; + struct qemu_mbox *mbox = get_qemu_mbox(link->mbox); + + return regmap_set_bits(mbox->map, QEMU_MBOX_IEN, BIT(chan)); +} + +static void qemu_mbox_shutdown(struct mbox_chan *link) +{ + unsigned long chan = (unsigned long)link->con_priv; + struct qemu_mbox *mbox = get_qemu_mbox(link->mbox); + + regmap_clear_bits(mbox->map, QEMU_MBOX_IEN, BIT(chan)); +} + static const struct regmap_config qemu_mbox_regmap_config = { .reg_bits = 32, .reg_stride = 4, @@ -95,6 +131,8 @@ static const struct regmap_config qemu_mbox_regmap_config = { static const struct mbox_chan_ops qemu_mbox_chan_ops = { .send_data = qemu_mbox_send_data, + .startup = qemu_mbox_startup, + .shutdown = qemu_mbox_shutdown, }; static int qemu_mbox_probe(struct pci_dev *pdev, const struct pci_device_id *id) @@ -127,7 +165,7 @@ static int qemu_mbox_probe(struct pci_dev *pdev, const struct pci_device_id *id) return dev_err_probe(dev, PTR_ERR(qemu_mbox->map), "Unable to initialize register map\n"); - err = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_MSIX); + err = pci_alloc_irq_vectors(pdev, 2, 2, PCI_IRQ_MSIX); if (err < 0) return dev_err_probe(dev, err, "Unable to allocate irqs\n"); @@ -139,6 +177,13 @@ static int qemu_mbox_probe(struct pci_dev *pdev, const struct pci_device_id *id) return dev_err_probe(dev, err, "Can't claim irq\n"); + err = devm_request_irq(&pdev->dev, pci_irq_vector(pdev, 1), + qemu_mbox_txdone_isr, 0, + "qemu_mbox_txdone_isr", qemu_mbox); + if (err) + return dev_err_probe(dev, err, + "Can't claim txdone irq\n"); + pci_set_master(pdev); mbox = &qemu_mbox->mbox;