MLK-21503 rpmsg: imx: refine imx rpmsg codes
authorRichard Zhu <hongxing.zhu@nxp.com>
Fri, 19 Apr 2019 09:01:50 +0000 (17:01 +0800)
committerRichard Zhu <hongxing.zhu@nxp.com>
Tue, 23 Apr 2019 02:48:08 +0000 (10:48 +0800)
No functions changes.
- Use the dynamic allocation, and remove the pre-defined static
  structure.
- Remove the vdev layer notify block codes.

Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
drivers/rpmsg/imx_rpmsg.c

index 64fef61..3a2aa70 100644 (file)
@@ -54,8 +54,7 @@ struct imx_virdev {
        struct virtqueue *vq[2];
        int base_vq_id;
        int num_of_vqs;
-       u32 vproc_id;
-       struct notifier_block nb;
+       struct imx_rpmsg_vproc *rpdev;
 };
 
 struct imx_rpmsg_vproc {
@@ -77,7 +76,7 @@ struct imx_rpmsg_vproc {
        u32 out_idx;
        u32 core_id;
        u32 mub_partition;
-       struct notifier_block *pnotifier;
+       struct notifier_block proc_nb;
        spinlock_t mu_lock;
        struct platform_device *pdev;
 };
@@ -121,13 +120,6 @@ struct imx_rpmsg_vq_info {
        struct imx_rpmsg_vproc *rpdev;
 };
 
-static int imx_rpmsg_partion_notify0(struct notifier_block *nb,
-                               unsigned long event, void *group);
-static int imx_rpmsg_partion_notify1(struct notifier_block *nb,
-                               unsigned long event, void *group);
-
-static struct imx_rpmsg_vproc imx_rpmsg_vprocs[];
-
 static u64 imx_rpmsg_get_features(struct virtio_device *vdev)
 {
        /* VIRTIO_RPMSG_F_NS has been made private */
@@ -172,58 +164,6 @@ static bool imx_rpmsg_notify(struct virtqueue *vq)
        return true;
 }
 
-static int imx_mu_rpmsg_callback(struct notifier_block *this,
-                                       unsigned long index, void *data)
-{
-       u32 mu_msg = (phys_addr_t) data;
-       struct imx_virdev *virdev;
-
-       virdev = container_of(this, struct imx_virdev, nb);
-
-       pr_debug("%s mu_msg: 0x%x\n", __func__, mu_msg);
-       /* ignore vq indices which are clearly not for us */
-       mu_msg = mu_msg >> 16;
-       if (mu_msg < virdev->base_vq_id || mu_msg > virdev->base_vq_id + 1) {
-               pr_debug("mu_msg: 0x%x is invalid\n", mu_msg);
-               return NOTIFY_DONE;
-       }
-
-       mu_msg -= virdev->base_vq_id;
-
-       /*
-        * Currently both PENDING_MSG and explicit-virtqueue-index
-        * messaging are supported.
-        * Whatever approach is taken, at this point 'mu_msg' contains
-        * the index of the vring which was just triggered.
-        */
-       if (mu_msg < virdev->num_of_vqs)
-               vring_interrupt(mu_msg, virdev->vq[mu_msg]);
-
-       return NOTIFY_DONE;
-}
-
-static int imx_mu_rpmsg_register_nb(struct imx_rpmsg_vproc *rpdev,
-               struct notifier_block *nb)
-{
-       if ((rpdev == NULL) || (nb == NULL))
-               return -EINVAL;
-
-       blocking_notifier_chain_register(&(rpdev->notifier), nb);
-
-       return 0;
-}
-
-static int imx_mu_rpmsg_unregister_nb(struct imx_rpmsg_vproc *rpdev,
-               struct notifier_block *nb)
-{
-       if ((rpdev == NULL) || (nb == NULL))
-               return -EINVAL;
-
-       blocking_notifier_chain_unregister(&(rpdev->notifier), nb);
-
-       return 0;
-}
-
 static struct virtqueue *rp_find_vq(struct virtio_device *vdev,
                                    unsigned int index,
                                    void (*callback)(struct virtqueue *vq),
@@ -231,8 +171,7 @@ static struct virtqueue *rp_find_vq(struct virtio_device *vdev,
                                    bool ctx)
 {
        struct imx_virdev *virdev = to_imx_virdev(vdev);
-       int id = virdev->vproc_id;
-       struct imx_rpmsg_vproc *rpdev = &imx_rpmsg_vprocs[id];
+       struct imx_rpmsg_vproc *rpdev = virdev->rpdev;
        struct imx_rpmsg_vq_info *rpvq;
        struct virtqueue *vq;
        int err;
@@ -285,9 +224,6 @@ free_rpvq:
 static void imx_rpmsg_del_vqs(struct virtio_device *vdev)
 {
        struct virtqueue *vq, *n;
-       struct imx_virdev *virdev = to_imx_virdev(vdev);
-       int id = virdev->vproc_id;
-       struct imx_rpmsg_vproc *rpdev = &imx_rpmsg_vprocs[id];
 
        list_for_each_entry_safe(vq, n, &vdev->vqs, list) {
                struct imx_rpmsg_vq_info *rpvq = vq->priv;
@@ -296,9 +232,6 @@ static void imx_rpmsg_del_vqs(struct virtio_device *vdev)
                vring_del_virtqueue(vq);
                kfree(rpvq);
        }
-
-       if (&virdev->nb)
-               imx_mu_rpmsg_unregister_nb(rpdev, &virdev->nb);
 }
 
 static int imx_rpmsg_find_vqs(struct virtio_device *vdev, unsigned int nvqs,
@@ -309,8 +242,6 @@ static int imx_rpmsg_find_vqs(struct virtio_device *vdev, unsigned int nvqs,
                       struct irq_affinity *desc)
 {
        struct imx_virdev *virdev = to_imx_virdev(vdev);
-       int id = virdev->vproc_id;
-       struct imx_rpmsg_vproc *rpdev = &imx_rpmsg_vprocs[id];
        int i, err;
 
        /* we maintain two virtqueues per remote processor (for RX and TX) */
@@ -327,10 +258,6 @@ static int imx_rpmsg_find_vqs(struct virtio_device *vdev, unsigned int nvqs,
        }
 
        virdev->num_of_vqs = nvqs;
-
-       virdev->nb.notifier_call = imx_mu_rpmsg_callback;
-       imx_mu_rpmsg_register_nb(rpdev, &virdev->nb);
-
        return 0;
 
 error:
@@ -368,26 +295,6 @@ static struct virtio_config_ops imx_rpmsg_config_ops = {
        .get_status     = imx_rpmsg_get_status,
 };
 
-static struct notifier_block imx_rpmsg_partion_notifier[] = {
-       {
-               .notifier_call = imx_rpmsg_partion_notify0,
-       },
-       {
-               .notifier_call = imx_rpmsg_partion_notify1,
-       },
-};
-
-static struct imx_rpmsg_vproc imx_rpmsg_vprocs[] = {
-       {
-               .rproc_name     = "m4",
-               .pnotifier      = &imx_rpmsg_partion_notifier[0],
-       },
-       {
-               .rproc_name     = "m4",
-               .pnotifier      = &imx_rpmsg_partion_notifier[1],
-       },
-};
-
 static const struct of_device_id imx_rpmsg_dt_ids[] = {
        { .compatible = "fsl,imx6sx-rpmsg",  .data = (void *)IMX6SX, },
        { .compatible = "fsl,imx7d-rpmsg",   .data = (void *)IMX7D, },
@@ -440,6 +347,7 @@ static void rpmsg_work_handler(struct work_struct *work)
 {
        u32 message;
        unsigned long flags;
+       struct imx_virdev *virdev;
        struct delayed_work *dwork = to_delayed_work(work);
        struct imx_rpmsg_vproc *rpdev = container_of(dwork,
                        struct imx_rpmsg_vproc, rpmsg_work);
@@ -450,8 +358,20 @@ static void rpmsg_work_handler(struct work_struct *work)
                message = rpdev->m4_message[rpdev->out_idx % MAX_NUM];
                spin_unlock_irqrestore(&rpdev->mu_lock, flags);
 
-               blocking_notifier_call_chain(&(rpdev->notifier), 4,
-                                               (void *)(phys_addr_t)message);
+               virdev = rpdev->ivdev[(message >> 16) / 2];
+
+               pr_debug("%s msg: 0x%x\n", __func__, message);
+               message = message >> 16;
+               message -= virdev->base_vq_id;
+
+               /*
+                * Currently both PENDING_MSG and explicit-virtqueue-index
+                * messaging are supported.
+                * Whatever approach is taken, at this point message contains
+                * the index of the vring which was just triggered.
+                */
+               if (message  < virdev->num_of_vqs)
+                       vring_interrupt(message, virdev->vq[message]);
 
                spin_lock_irqsave(&rpdev->mu_lock, flags);
                rpdev->m4_message[rpdev->out_idx % MAX_NUM] = 0;
@@ -550,35 +470,20 @@ void imx_rpmsg_restore(struct imx_rpmsg_vproc *rpdev)
                rpdev->ivdev[i]->vdev.dev.parent = &rpdev->pdev->dev;
                rpdev->ivdev[i]->vdev.dev.release = imx_rpmsg_vproc_release;
                rpdev->ivdev[i]->base_vq_id = i * 2;
-               rpdev->ivdev[i]->vproc_id = rpdev->core_id;
+               rpdev->ivdev[i]->rpdev = rpdev;
 
                if (register_virtio_device(&rpdev->ivdev[i]->vdev))
                        pr_err("%s failed to register rpdev.\n", __func__);
        }
 }
 
-static int imx_rpmsg_partion_notify0(struct notifier_block *nb,
+static int imx_rpmsg_partion_notify(struct notifier_block *nb,
                                      unsigned long event, void *group)
 {
 #ifdef CONFIG_HAVE_IMX_SC
-       struct imx_rpmsg_vproc *rpdev = &imx_rpmsg_vprocs[0];
-
-       /* Ignore other irqs */
-       if (!((event & BIT(rpdev->mub_partition)) &&
-               (*(sc_irq_group_t *)group == SC_IRQ_GROUP_REBOOTED)))
-               return 0;
-
-       imx_rpmsg_restore(rpdev);
-       pr_info("Patition%d reset!\n", rpdev->mub_partition);
-#endif
-       return 0;
-}
+       struct imx_rpmsg_vproc *rpdev;
 
-static int imx_rpmsg_partion_notify1(struct notifier_block *nb,
-                                     unsigned long event, void *group)
-{
-#ifdef CONFIG_HAVE_IMX_SC
-       struct imx_rpmsg_vproc *rpdev = &imx_rpmsg_vprocs[1];
+       rpdev = container_of(nb, struct imx_rpmsg_vproc, proc_nb);
 
        /* Ignore other irqs */
        if (!((event & BIT(rpdev->mub_partition)) &&
@@ -600,9 +505,15 @@ static int imx_rpmsg_probe(struct platform_device *pdev)
        struct device_node *np = pdev->dev.of_node;
        struct imx_rpmsg_vproc *rpdev;
 
+       rpdev = devm_kzalloc(dev, sizeof(*rpdev), GFP_KERNEL);
+       if (!rpdev)
+               return -ENOMEM;
+       rpdev->none_suspend = 1;
+       rpdev->rproc_name = "m4";
+       rpdev->proc_nb.notifier_call = imx_rpmsg_partion_notify;
+
        if (of_property_read_u32(np, "multi-core-id", &core_id))
                core_id = 0;
-       rpdev = &imx_rpmsg_vprocs[core_id];
        rpdev->core_id = core_id;
        rpdev->variant = (enum imx_rpmsg_variants)of_device_get_match_data(dev);
 
@@ -704,7 +615,7 @@ static int imx_rpmsg_probe(struct platform_device *pdev)
                rpdev->ivdev[j]->vdev.dev.parent = &pdev->dev;
                rpdev->ivdev[j]->vdev.dev.release = imx_rpmsg_vproc_release;
                rpdev->ivdev[j]->base_vq_id = j * 2;
-               rpdev->ivdev[j]->vproc_id = rpdev->core_id;
+               rpdev->ivdev[j]->rpdev = rpdev;
 
                ret = register_virtio_device(&rpdev->ivdev[j]->vdev);
                if (ret) {
@@ -757,7 +668,7 @@ static int imx_rpmsg_probe(struct platform_device *pdev)
                if (sciErr)
                        pr_info("Cannot request partition reset interrupt\n");
 
-               return register_scu_notifier(rpdev->pnotifier);
+               return register_scu_notifier(&rpdev->proc_nb);
 
        }
 #endif