*/
 
 #include <linux/platform_device.h>
+#include <linux/acpi.h>
 #include <rdma/ib_umem.h>
 #include "hns_roce_common.h"
 #include "hns_roce_device.h"
  * @enable: true -- drop reset, false -- reset
  * return 0 - success , negative --fail
  */
-int hns_roce_v1_reset(struct hns_roce_dev *hr_dev, bool enable)
+int hns_roce_v1_reset(struct hns_roce_dev *hr_dev, bool dereset)
 {
        struct device_node *dsaf_node;
        struct device *dev = &hr_dev->pdev->dev;
        struct device_node *np = dev->of_node;
+       struct fwnode_handle *fwnode;
        int ret;
 
-       dsaf_node = of_parse_phandle(np, "dsaf-handle", 0);
-       if (!dsaf_node) {
-               dev_err(dev, "Unable to get dsaf node by dsaf-handle!\n");
-               return -EINVAL;
+       /* check if this is DT/ACPI case */
+       if (dev_of_node(dev)) {
+               dsaf_node = of_parse_phandle(np, "dsaf-handle", 0);
+               if (!dsaf_node) {
+                       dev_err(dev, "could not find dsaf-handle\n");
+                       return -EINVAL;
+               }
+               fwnode = &dsaf_node->fwnode;
+       } else if (is_acpi_device_node(dev->fwnode)) {
+               struct acpi_reference_args args;
+
+               ret = acpi_node_get_property_reference(dev->fwnode,
+                                                      "dsaf-handle", 0, &args);
+               if (ret) {
+                       dev_err(dev, "could not find dsaf-handle\n");
+                       return ret;
+               }
+               fwnode = acpi_fwnode_handle(args.adev);
+       } else {
+               dev_err(dev, "cannot read data from DT or ACPI\n");
+               return -ENXIO;
        }
 
-       ret = hns_dsaf_roce_reset(&dsaf_node->fwnode, false);
+       ret = hns_dsaf_roce_reset(fwnode, false);
        if (ret)
                return ret;
 
-       if (enable) {
+       if (dereset) {
                msleep(SLEEP_TIME_INTERVAL);
-               return hns_dsaf_roce_reset(&dsaf_node->fwnode, true);
+               ret = hns_dsaf_roce_reset(fwnode, true);
        }
 
-       return 0;
+       return ret;
 }
 
 void hns_roce_v1_profile(struct hns_roce_dev *hr_dev)
 
  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-
+#include <linux/acpi.h>
 #include <linux/of_platform.h>
 #include <rdma/ib_addr.h>
 #include <rdma/ib_smi.h>
        return ret;
 }
 
+static const struct of_device_id hns_roce_of_match[] = {
+       { .compatible = "hisilicon,hns-roce-v1", .data = &hns_roce_hw_v1, },
+       {},
+};
+MODULE_DEVICE_TABLE(of, hns_roce_of_match);
+
+static const struct acpi_device_id hns_roce_acpi_match[] = {
+       { "HISI00D1", (kernel_ulong_t)&hns_roce_hw_v1 },
+       {},
+};
+MODULE_DEVICE_TABLE(acpi, hns_roce_acpi_match);
+
+static int hns_roce_node_match(struct device *dev, void *fwnode)
+{
+       return dev->fwnode == fwnode;
+}
+
+static struct
+platform_device *hns_roce_find_pdev(struct fwnode_handle *fwnode)
+{
+       struct device *dev;
+
+       /* get the 'device'corresponding to matching 'fwnode' */
+       dev = bus_find_device(&platform_bus_type, NULL,
+                             fwnode, hns_roce_node_match);
+       /* get the platform device */
+       return dev ? to_platform_device(dev) : NULL;
+}
+
 static int hns_roce_get_cfg(struct hns_roce_dev *hr_dev)
 {
        int i;
+       int ret;
        u8 phy_port;
        int port_cnt = 0;
        struct device *dev = &hr_dev->pdev->dev;
-       struct device_node *np = dev->of_node;
        struct device_node *net_node;
        struct net_device *netdev = NULL;
        struct platform_device *pdev = NULL;
        struct resource *res;
 
-       if (of_device_is_compatible(np, "hisilicon,hns-roce-v1")) {
-               hr_dev->hw = &hns_roce_hw_v1;
+       /* check if we are compatible with the underlying SoC */
+       if (dev_of_node(dev)) {
+               const struct of_device_id *of_id;
+
+               of_id = of_match_node(hns_roce_of_match, dev->of_node);
+               if (!of_id) {
+                       dev_err(dev, "device is not compatible!\n");
+                       return -ENXIO;
+               }
+               hr_dev->hw = (struct hns_roce_hw *)of_id->data;
+               if (!hr_dev->hw) {
+                       dev_err(dev, "couldn't get H/W specific DT data!\n");
+                       return -ENXIO;
+               }
+       } else if (is_acpi_device_node(dev->fwnode)) {
+               const struct acpi_device_id *acpi_id;
+
+               acpi_id = acpi_match_device(hns_roce_acpi_match, dev);
+               if (!acpi_id) {
+                       dev_err(dev, "device is not compatible!\n");
+                       return -ENXIO;
+               }
+               hr_dev->hw = (struct hns_roce_hw *) acpi_id->driver_data;
+               if (!hr_dev->hw) {
+                       dev_err(dev, "couldn't get H/W specific ACPI data!\n");
+                       return -ENXIO;
+               }
        } else {
-               dev_err(dev, "device no compatible!\n");
-               return -EINVAL;
+               dev_err(dev, "can't read compatibility data from DT or ACPI\n");
+               return -ENXIO;
        }
 
+       /* get the mapped register base address */
        res = platform_get_resource(hr_dev->pdev, IORESOURCE_MEM, 0);
+       if (!res) {
+               dev_err(dev, "memory resource not found!\n");
+               return -EINVAL;
+       }
        hr_dev->reg_base = devm_ioremap_resource(dev, res);
        if (IS_ERR(hr_dev->reg_base))
                return PTR_ERR(hr_dev->reg_base);
 
+       /* get the RoCE associated ethernet ports or netdevices */
        for (i = 0; i < HNS_ROCE_MAX_PORTS; i++) {
-               net_node = of_parse_phandle(np, "eth-handle", i);
-               if (net_node) {
+               if (dev_of_node(dev)) {
+                       net_node = of_parse_phandle(dev->of_node, "eth-handle",
+                                                   i);
+                       if (!net_node)
+                               continue;
                        pdev = of_find_device_by_node(net_node);
+               } else if (is_acpi_device_node(dev->fwnode)) {
+                       struct acpi_reference_args args;
+                       struct fwnode_handle *fwnode;
+
+                       ret = acpi_node_get_property_reference(dev->fwnode,
+                                                              "eth-handle",
+                                                              i, &args);
+                       if (ret)
+                               continue;
+                       fwnode = acpi_fwnode_handle(args.adev);
+                       pdev = hns_roce_find_pdev(fwnode);
+               } else {
+                       dev_err(dev, "cannot read data from DT or ACPI\n");
+                       return -ENXIO;
+               }
+
+               if (pdev) {
                        netdev = platform_get_drvdata(pdev);
                        phy_port = (u8)i;
                        if (netdev) {
                                hr_dev->iboe.netdevs[port_cnt] = netdev;
                                hr_dev->iboe.phy_port[port_cnt] = phy_port;
                        } else {
+                               dev_err(dev, "no netdev found with pdev %s\n",
+                                       pdev->name);
                                return -ENODEV;
                        }
                        port_cnt++;
        }
 
        if (port_cnt == 0) {
-               dev_err(dev, "Unable to get available port by eth-handle!\n");
+               dev_err(dev, "unable to get eth-handle for available ports!\n");
                return -EINVAL;
        }
 
        hr_dev->caps.num_ports = port_cnt;
 
-       /* Cmd issue mode: 0 is poll, 1 is event */
+       /* cmd issue mode: 0 is poll, 1 is event */
        hr_dev->cmd_mod = 1;
        hr_dev->loop_idc = 0;
 
+       /* read the interrupt names from the DT or ACPI */
+       ret = device_property_read_string_array(dev, "interrupt-names",
+                                               hr_dev->irq_names,
+                                               HNS_ROCE_MAX_IRQ_NUM);
+       if (ret < 0) {
+               dev_err(dev, "couldn't get interrupt names from DT or ACPI!\n");
+               return ret;
+       }
+
+       /* fetch the interrupt numbers */
        for (i = 0; i < HNS_ROCE_MAX_IRQ_NUM; i++) {
                hr_dev->irq[i] = platform_get_irq(hr_dev->pdev, i);
                if (hr_dev->irq[i] <= 0) {
-                       dev_err(dev, "Get No.%d irq resource failed!\n", i);
+                       dev_err(dev, "platform get of irq[=%d] failed!\n", i);
                        return -EINVAL;
                }
-
-               if (of_property_read_string_index(np, "interrupt-names", i,
-                                                 &hr_dev->irq_names))
-                       return -EINVAL;
        }
 
        return 0;
 
        if (dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64ULL)) &&
            dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32ULL))) {
-               dev_err(dev, "No usable DMA addressing mode\n");
+               dev_err(dev, "Not usable DMA addressing mode\n");
                ret = -EIO;
                goto error_failed_get_cfg;
        }
        return 0;
 }
 
-static const struct of_device_id hns_roce_of_match[] = {
-       { .compatible = "hisilicon,hns-roce-v1",},
-       {},
-};
-MODULE_DEVICE_TABLE(of, hns_roce_of_match);
-
 static struct platform_driver hns_roce_driver = {
        .probe = hns_roce_probe,
        .remove = hns_roce_remove,
        .driver = {
                .name = DRV_NAME,
                .of_match_table = hns_roce_of_match,
+               .acpi_match_table = ACPI_PTR(hns_roce_acpi_match),
        },
 };