#include <linux/rpmsg.h>
 #include <linux/of.h>
 
-struct apr {
+enum {
+       PR_TYPE_APR = 0,
+};
+
+struct packet_router {
        struct rpmsg_endpoint *ch;
        struct device *dev;
        spinlock_t svcs_lock;
        spinlock_t rx_lock;
        struct idr svcs_idr;
        int dest_domain_id;
+       int type;
        struct pdr_handle *pdr;
        struct workqueue_struct *rxwq;
        struct work_struct rx_work;
  */
 int apr_send_pkt(struct apr_device *adev, struct apr_pkt *pkt)
 {
-       struct apr *apr = dev_get_drvdata(adev->dev.parent);
+       struct packet_router *apr = dev_get_drvdata(adev->dev.parent);
        struct apr_hdr *hdr;
        unsigned long flags;
        int ret;
 
-       spin_lock_irqsave(&adev->lock, flags);
+       spin_lock_irqsave(&adev->svc.lock, flags);
 
        hdr = &pkt->hdr;
        hdr->src_domain = APR_DOMAIN_APPS;
-       hdr->src_svc = adev->svc_id;
+       hdr->src_svc = adev->svc.id;
        hdr->dest_domain = adev->domain_id;
-       hdr->dest_svc = adev->svc_id;
+       hdr->dest_svc = adev->svc.id;
 
        ret = rpmsg_trysend(apr->ch, pkt, hdr->pkt_size);
-       spin_unlock_irqrestore(&adev->lock, flags);
+       spin_unlock_irqrestore(&adev->svc.lock, flags);
 
        return ret ? ret : hdr->pkt_size;
 }
 static int apr_callback(struct rpmsg_device *rpdev, void *buf,
                                  int len, void *priv, u32 addr)
 {
-       struct apr *apr = dev_get_drvdata(&rpdev->dev);
+       struct packet_router *apr = dev_get_drvdata(&rpdev->dev);
        struct apr_rx_buf *abuf;
        unsigned long flags;
 
        return 0;
 }
 
-
-static int apr_do_rx_callback(struct apr *apr, struct apr_rx_buf *abuf)
+static int apr_do_rx_callback(struct packet_router *apr, struct apr_rx_buf *abuf)
 {
        uint16_t hdr_size, msg_type, ver, svc_id;
-       struct apr_device *svc = NULL;
+       struct pkt_router_svc *svc;
+       struct apr_device *adev;
        struct apr_driver *adrv = NULL;
        struct apr_resp_pkt resp;
        struct apr_hdr *hdr;
        svc_id = hdr->dest_svc;
        spin_lock_irqsave(&apr->svcs_lock, flags);
        svc = idr_find(&apr->svcs_idr, svc_id);
-       if (svc && svc->dev.driver)
-               adrv = to_apr_driver(svc->dev.driver);
+       if (svc && svc->dev->driver) {
+               adev = svc_to_apr_device(svc);
+               adrv = to_apr_driver(adev->dev.driver);
+       }
        spin_unlock_irqrestore(&apr->svcs_lock, flags);
 
-       if (!adrv) {
-               dev_err(apr->dev, "APR: service is not registered\n");
+       if (!adrv || !adev) {
+               dev_err(apr->dev, "APR: service is not registered (%d)\n",
+                       svc_id);
                return -EINVAL;
        }
 
        if (resp.payload_size > 0)
                resp.payload = buf + hdr_size;
 
-       adrv->callback(svc, &resp);
+       adrv->callback(adev, &resp);
 
        return 0;
 }
 
 static void apr_rxwq(struct work_struct *work)
 {
-       struct apr *apr = container_of(work, struct apr, rx_work);
+       struct packet_router *apr = container_of(work, struct packet_router, rx_work);
        struct apr_rx_buf *abuf, *b;
        unsigned long flags;
 
        if (!list_empty(&apr->rx_list)) {
                list_for_each_entry_safe(abuf, b, &apr->rx_list, node) {
-                       apr_do_rx_callback(apr, abuf);
+                       switch (apr->type) {
+                       case PR_TYPE_APR:
+                               apr_do_rx_callback(apr, abuf);
+                               break;
+                       default:
+                               break;
+                       }
                        spin_lock_irqsave(&apr->rx_lock, flags);
                        list_del(&abuf->node);
                        spin_unlock_irqrestore(&apr->rx_lock, flags);
 
        while (id->domain_id != 0 || id->svc_id != 0) {
                if (id->domain_id == adev->domain_id &&
-                   id->svc_id == adev->svc_id)
+                   id->svc_id == adev->svc.id)
                        return 1;
                id++;
        }
 {
        struct apr_device *adev = to_apr_device(dev);
        struct apr_driver *adrv;
-       struct apr *apr = dev_get_drvdata(adev->dev.parent);
+       struct packet_router *apr = dev_get_drvdata(adev->dev.parent);
 
        if (dev->driver) {
                adrv = to_apr_driver(dev->driver);
                if (adrv->remove)
                        adrv->remove(adev);
                spin_lock(&apr->svcs_lock);
-               idr_remove(&apr->svcs_idr, adev->svc_id);
+               idr_remove(&apr->svcs_idr, adev->svc.id);
                spin_unlock(&apr->svcs_lock);
        }
 }
 EXPORT_SYMBOL_GPL(aprbus);
 
 static int apr_add_device(struct device *dev, struct device_node *np,
-                         const struct apr_device_id *id)
+                         u32 svc_id, u32 domain_id)
 {
-       struct apr *apr = dev_get_drvdata(dev);
+       struct packet_router *apr = dev_get_drvdata(dev);
        struct apr_device *adev = NULL;
+       struct pkt_router_svc *svc;
        int ret;
 
        adev = kzalloc(sizeof(*adev), GFP_KERNEL);
        if (!adev)
                return -ENOMEM;
 
-       spin_lock_init(&adev->lock);
+       adev->svc_id = svc_id;
+       svc = &adev->svc;
+
+       svc->id = svc_id;
+       svc->pr = apr;
+       svc->priv = adev;
+       svc->dev = dev;
+       spin_lock_init(&svc->lock);
+
+       adev->domain_id = domain_id;
 
-       adev->svc_id = id->svc_id;
-       adev->domain_id = id->domain_id;
-       adev->version = id->svc_version;
        if (np)
                snprintf(adev->name, APR_NAME_SIZE, "%pOFn", np);
-       else
-               strscpy(adev->name, id->name, APR_NAME_SIZE);
 
-       dev_set_name(&adev->dev, "aprsvc:%s:%x:%x", adev->name,
-                    id->domain_id, id->svc_id);
+       switch (apr->type) {
+       case PR_TYPE_APR:
+               dev_set_name(&adev->dev, "aprsvc:%s:%x:%x", adev->name,
+                            domain_id, svc_id);
+               break;
+       default:
+               break;
+       }
 
        adev->dev.bus = &aprbus;
        adev->dev.parent = dev;
        adev->dev.driver = NULL;
 
        spin_lock(&apr->svcs_lock);
-       idr_alloc(&apr->svcs_idr, adev, id->svc_id,
-                 id->svc_id + 1, GFP_ATOMIC);
+       idr_alloc(&apr->svcs_idr, svc, svc_id, svc_id + 1, GFP_ATOMIC);
        spin_unlock(&apr->svcs_lock);
 
        of_property_read_string_index(np, "qcom,protection-domain",
 static int of_apr_add_pd_lookups(struct device *dev)
 {
        const char *service_name, *service_path;
-       struct apr *apr = dev_get_drvdata(dev);
+       struct packet_router *apr = dev_get_drvdata(dev);
        struct device_node *node;
        struct pdr_service *pds;
        int ret;
 
 static void of_register_apr_devices(struct device *dev, const char *svc_path)
 {
-       struct apr *apr = dev_get_drvdata(dev);
+       struct packet_router *apr = dev_get_drvdata(dev);
        struct device_node *node;
        const char *service_path;
        int ret;
 
        for_each_child_of_node(dev->of_node, node) {
-               struct apr_device_id id = { {0} };
+               u32 svc_id;
+               u32 domain_id;
 
                /*
                 * This function is called with svc_path NULL during
                                continue;
                }
 
-               if (of_property_read_u32(node, "reg", &id.svc_id))
+               if (of_property_read_u32(node, "reg", &svc_id))
                        continue;
 
-               id.domain_id = apr->dest_domain_id;
+               domain_id = apr->dest_domain_id;
 
-               if (apr_add_device(dev, node, &id))
-                       dev_err(dev, "Failed to add apr %d svc\n", id.svc_id);
+               if (apr_add_device(dev, node, svc_id, domain_id))
+                       dev_err(dev, "Failed to add apr %d svc\n", svc_id);
        }
 }
 
 
 static void apr_pd_status(int state, char *svc_path, void *priv)
 {
-       struct apr *apr = (struct apr *)priv;
+       struct packet_router *apr = (struct packet_router *)priv;
 
        switch (state) {
        case SERVREG_SERVICE_STATE_UP:
 static int apr_probe(struct rpmsg_device *rpdev)
 {
        struct device *dev = &rpdev->dev;
-       struct apr *apr;
+       struct packet_router *apr;
        int ret;
 
        apr = devm_kzalloc(dev, sizeof(*apr), GFP_KERNEL);
        if (!apr)
                return -ENOMEM;
 
-       ret = of_property_read_u32(dev->of_node, "qcom,apr-domain", &apr->dest_domain_id);
+       ret = of_property_read_u32(dev->of_node, "qcom,domain", &apr->dest_domain_id);
+       if (ret) /* try deprecated apr-domain property */
+               ret = of_property_read_u32(dev->of_node, "qcom,apr-domain",
+                                          &apr->dest_domain_id);
+       apr->type = PR_TYPE_APR;
        if (ret) {
-               dev_err(dev, "APR Domain ID not specified in DT\n");
+               dev_err(dev, "Domain ID not specified in DT\n");
                return ret;
        }
 
 
 static void apr_remove(struct rpmsg_device *rpdev)
 {
-       struct apr *apr = dev_get_drvdata(&rpdev->dev);
+       struct packet_router *apr = dev_get_drvdata(&rpdev->dev);
 
        pdr_handle_release(apr->pdr);
        device_for_each_child(&rpdev->dev, NULL, apr_remove_device);
 }
 EXPORT_SYMBOL_GPL(apr_driver_unregister);
 
-static const struct of_device_id apr_of_match[] = {
+static const struct of_device_id pkt_router_of_match[] = {
        { .compatible = "qcom,apr"},
        { .compatible = "qcom,apr-v2"},
        {}
 };
-MODULE_DEVICE_TABLE(of, apr_of_match);
+MODULE_DEVICE_TABLE(of, pkt_router_of_match);
 
-static struct rpmsg_driver apr_driver = {
+static struct rpmsg_driver packet_router_driver = {
        .probe = apr_probe,
        .remove = apr_remove,
        .callback = apr_callback,
        .drv = {
                .name = "qcom,apr",
-               .of_match_table = apr_of_match,
+               .of_match_table = pkt_router_of_match,
        },
 };
 
 
        ret = bus_register(&aprbus);
        if (!ret)
-               ret = register_rpmsg_driver(&apr_driver);
+               ret = register_rpmsg_driver(&packet_router_driver);
        else
                bus_unregister(&aprbus);
 
 static void __exit apr_exit(void)
 {
        bus_unregister(&aprbus);
-       unregister_rpmsg_driver(&apr_driver);
+       unregister_rpmsg_driver(&packet_router_driver);
 }
 
 subsys_initcall(apr_init);