#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))
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;
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,
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)
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");
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;