On Thu, Dec 05, 2024 at 05:41:36PM +0000, Tudor Ambarus wrote: > The samsung exynos mailbox controller has 16 flag bits for hardware Here, subject and other text/descriptions: s/samsung/Samsung/ s/exynos/Exynos/ > interrupt generation and a shared register for passing mailbox messages. > When the controller is used by the ACPM protocol the shared register is > ignored and the mailbox controller acts as a doorbell. The controller > just raises the interrupt to APM after the ACPM protocol has written > the message to SRAM. ... > +static int exynos_mbox_send_data(struct mbox_chan *chan, void *data) > +{ > + struct exynos_mbox *exynos_mbox = dev_get_drvdata(chan->mbox->dev); > + int index; > + > + index = exynos_mbox_chan_index(chan); > + if (index < 0) > + return index; > + > + writel_relaxed(BIT(index), exynos_mbox->regs + EXYNOS_MBOX_INTGR1); writel() > + > + return 0; > +} > + > +static const struct mbox_chan_ops exynos_mbox_chan_ops = { > + .send_data = exynos_mbox_send_data, > +}; > + > +static const struct of_device_id exynos_mbox_match[] = { > + { .compatible = "google,gs101-acpm-mbox" }, > + {}, > +}; > +MODULE_DEVICE_TABLE(of, exynos_mbox_match); > + > +static int exynos_mbox_probe(struct platform_device *pdev) > +{ > + struct device *dev = &pdev->dev; > + struct exynos_mbox *exynos_mbox; > + struct mbox_controller *mbox; > + struct mbox_chan *chans; > + int i; > + > + exynos_mbox = devm_kzalloc(dev, sizeof(*exynos_mbox), GFP_KERNEL); > + if (!exynos_mbox) > + return -ENOMEM; > + > + mbox = devm_kzalloc(dev, sizeof(*mbox), GFP_KERNEL); > + if (!mbox) > + return -ENOMEM; > + > + chans = devm_kcalloc(dev, EXYNOS_MBOX_CHAN_COUNT, sizeof(*chans), > + GFP_KERNEL); > + if (!chans) > + return -ENOMEM; > + > + exynos_mbox->regs = devm_platform_ioremap_resource(pdev, 0); > + if (IS_ERR(exynos_mbox->regs)) > + return PTR_ERR(exynos_mbox->regs); > + > + exynos_mbox->pclk = devm_clk_get_enabled(dev, "pclk"); > + if (IS_ERR(exynos_mbox->pclk)) > + return dev_err_probe(dev, PTR_ERR(exynos_mbox->pclk), > + "Failed to enable clock.\n"); > + > + mbox->num_chans = EXYNOS_MBOX_CHAN_COUNT; > + mbox->chans = chans; > + mbox->dev = dev; > + mbox->ops = &exynos_mbox_chan_ops; > + > + for (i = 0; i < EXYNOS_MBOX_CHAN_COUNT; i++) > + chans[i].mbox = mbox; > + > + exynos_mbox->dev = dev; > + exynos_mbox->mbox = mbox; > + > + platform_set_drvdata(pdev, exynos_mbox); > + > + /* Mask out all interrupts. We support just polling channels for now. */ > + writel_relaxed(EXYNOS_MBOX_INTMR0_MASK, writel() > + exynos_mbox->regs + EXYNOS_MBOX_INTMR0); > + > + return devm_mbox_controller_register(dev, mbox); > +} > + > +static struct platform_driver exynos_mbox_driver = { > + .probe = exynos_mbox_probe, > + .driver = { > + .name = "exynos-acpm-mbox", > + .of_match_table = of_match_ptr(exynos_mbox_match), Drop of_match_ptr() - unused symbol warnings. Best regards, Krzysztof