OSDN Git Service

esoc: mdm-4x: Add support for mdm9x45 and apq8096
authorArun KS <arunks@codeaurora.org>
Mon, 16 Jan 2017 12:30:37 +0000 (18:00 +0530)
committerArun KS <arunks@codeaurora.org>
Sun, 30 Apr 2017 13:40:38 +0000 (19:10 +0530)
Add mdm_ops for mdm9x45 and apq8064.

Change-Id: Iea167175b9bd35a515d15a72897947a889093c03
Signed-off-by: Arun KS <arunks@codeaurora.org>
Signed-off-by: Srivatsa Vaddagiri <vatsa@codeaurora.org>
Documentation/devicetree/bindings/arm/msm/mdm-modem.txt
drivers/esoc/esoc-mdm-4x.c
drivers/esoc/esoc-mdm-drv.c
drivers/esoc/esoc-mdm-pon.c
drivers/esoc/esoc-mdm.h

index a6537eb..86d2268 100644 (file)
@@ -6,8 +6,8 @@ to be reset.
 
 Required Properties:
 - compatible:  The bus devices need to be compatible with
-               "qcom,mdm2-modem", "qcom,ext-mdm9x25", "qcom,ext-mdm9x35", "qcom, ext-mdm9x45",
-               "qcom,ext-mdm9x55".
+               "qcom,mdm2-modem", "qcom,ext-mdm9x25", "qcom,ext-mdm9x35", "qcom,ext-mdm9x45",
+               "qcom,ext-mdm9x55", "qcom,ext-apq8096".
 
 Required named gpio properties:
 - qcom,mdm2ap-errfatal-gpio: gpio for the external modem to indicate to the apps processor
index ac8d800..618ceb9 100644 (file)
@@ -945,6 +945,80 @@ static int mdm9x35_setup_hw(struct mdm_ctrl *mdm,
        return 0;
 }
 
+static int mdm9x45_setup_hw(struct mdm_ctrl *mdm,
+                                       const struct mdm_ops *ops,
+                                       struct platform_device *pdev)
+{
+       int ret;
+       struct esoc_clink *esoc;
+       const struct esoc_clink_ops *const clink_ops = ops->clink_ops;
+       const struct mdm_pon_ops *pon_ops = ops->pon_ops;
+
+       mdm->dev = &pdev->dev;
+       mdm->pon_ops = pon_ops;
+       esoc = devm_kzalloc(mdm->dev, sizeof(*esoc), GFP_KERNEL);
+       if (IS_ERR_OR_NULL(esoc)) {
+               dev_err(mdm->dev, "cannot allocate esoc device\n");
+               return PTR_ERR(esoc);
+       }
+       esoc->pdev = pdev;
+       mdm->mdm_queue = alloc_workqueue("mdm_queue", 0, 0);
+       if (!mdm->mdm_queue) {
+               dev_err(mdm->dev, "could not create mdm_queue\n");
+               return -ENOMEM;
+       }
+       mdm->irq_mask = 0;
+       mdm->ready = false;
+       ret = mdm_dt_parse_gpios(mdm);
+       if (ret)
+               return ret;
+       dev_err(mdm->dev, "parsing gpio done\n");
+       ret = mdm_pon_dt_init(mdm);
+       if (ret)
+               return ret;
+       dev_dbg(mdm->dev, "pon dt init done\n");
+       ret = mdm_pinctrl_init(mdm);
+       if (ret)
+               return ret;
+       dev_err(mdm->dev, "pinctrl init done\n");
+       ret = mdm_pon_setup(mdm);
+       if (ret)
+               return ret;
+       dev_dbg(mdm->dev, "pon setup done\n");
+       ret = mdm_configure_ipc(mdm, pdev);
+       if (ret)
+               return ret;
+       mdm_configure_debug(mdm);
+       dev_err(mdm->dev, "ipc configure done\n");
+       esoc->name = MDM9x45_LABEL;
+       esoc->link_name = MDM9x45_PCIE;
+       esoc->clink_ops = clink_ops;
+       esoc->parent = mdm->dev;
+       esoc->owner = THIS_MODULE;
+       esoc->np = pdev->dev.of_node;
+
+       esoc->auto_boot = of_property_read_bool(esoc->np,
+                                               "qcom,mdm-auto-boot");
+       set_esoc_clink_data(esoc, mdm);
+       ret = esoc_clink_register(esoc);
+       if (ret) {
+               dev_err(mdm->dev, "esoc registration failed\n");
+               return ret;
+       }
+       dev_dbg(mdm->dev, "esoc registration done\n");
+       init_completion(&mdm->debug_done);
+       INIT_WORK(&mdm->mdm_status_work, mdm_status_fn);
+       INIT_WORK(&mdm->restart_reason_work, mdm_get_restart_reason);
+       INIT_DELAYED_WORK(&mdm->mdm2ap_status_check_work, mdm2ap_status_check);
+       mdm->get_restart_reason = false;
+       mdm->debug_fail = false;
+       mdm->esoc = esoc;
+       mdm->init = 0;
+       if (esoc->auto_boot)
+               gpio_direction_output(MDM_GPIO(mdm, AP2MDM_STATUS), 1);
+       return 0;
+}
+
 static int mdm9x55_setup_hw(struct mdm_ctrl *mdm,
                                        const struct mdm_ops *ops,
                                        struct platform_device *pdev)
@@ -1021,6 +1095,82 @@ static int mdm9x55_setup_hw(struct mdm_ctrl *mdm,
        return 0;
 }
 
+static int apq8096_setup_hw(struct mdm_ctrl *mdm,
+                                       const struct mdm_ops *ops,
+                                       struct platform_device *pdev)
+{
+       int ret;
+       struct device_node *node;
+       struct esoc_clink *esoc;
+       const struct esoc_clink_ops *const clink_ops = ops->clink_ops;
+       const struct mdm_pon_ops *pon_ops = ops->pon_ops;
+
+       mdm->dev = &pdev->dev;
+       mdm->pon_ops = pon_ops;
+       node = pdev->dev.of_node;
+       esoc = devm_kzalloc(mdm->dev, sizeof(*esoc), GFP_KERNEL);
+       if (IS_ERR_OR_NULL(esoc)) {
+               dev_err(mdm->dev, "cannot allocate esoc device\n");
+               return PTR_ERR(esoc);
+       }
+       esoc->pdev = pdev;
+       mdm->mdm_queue = alloc_workqueue("mdm_queue", 0, 0);
+       if (!mdm->mdm_queue) {
+               dev_err(mdm->dev, "could not create mdm_queue\n");
+               return -ENOMEM;
+       }
+       mdm->irq_mask = 0;
+       mdm->ready = false;
+       ret = mdm_dt_parse_gpios(mdm);
+       if (ret)
+               return ret;
+       dev_dbg(mdm->dev, "parsing gpio done\n");
+       ret = mdm_pon_dt_init(mdm);
+       if (ret)
+               return ret;
+       dev_dbg(mdm->dev, "pon dt init done\n");
+       ret = mdm_pinctrl_init(mdm);
+       if (ret)
+               return ret;
+       dev_dbg(mdm->dev, "pinctrl init done\n");
+       ret = mdm_pon_setup(mdm);
+       if (ret)
+               return ret;
+       dev_dbg(mdm->dev, "pon setup done\n");
+       ret = mdm_configure_ipc(mdm, pdev);
+       if (ret)
+               return ret;
+       dev_dbg(mdm->dev, "ipc configure done\n");
+       esoc->name = APQ8096_LABEL;
+       esoc->link_name = APQ8096_PCIE;
+       esoc->clink_ops = clink_ops;
+       esoc->parent = mdm->dev;
+       esoc->owner = THIS_MODULE;
+       esoc->np = pdev->dev.of_node;
+       esoc->auto_boot = of_property_read_bool(esoc->np,
+                               "qcom,mdm-auto-boot");
+       esoc->primary = of_property_read_bool(esoc->np,
+                               "qcom,mdm-primary");
+       set_esoc_clink_data(esoc, mdm);
+       ret = esoc_clink_register(esoc);
+       if (ret) {
+               dev_err(mdm->dev, "esoc registration failed\n");
+               return ret;
+       }
+       dev_dbg(mdm->dev, "esoc registration done\n");
+       init_completion(&mdm->debug_done);
+       INIT_WORK(&mdm->mdm_status_work, mdm_status_fn);
+       INIT_WORK(&mdm->restart_reason_work, mdm_get_restart_reason);
+       INIT_DELAYED_WORK(&mdm->mdm2ap_status_check_work, mdm2ap_status_check);
+       mdm->get_restart_reason = false;
+       mdm->debug_fail = false;
+       mdm->esoc = esoc;
+       mdm->init = 0;
+       gpio_direction_output(MDM_GPIO(mdm, AP2MDM_STATUS), 1);
+       gpio_direction_output(MDM_GPIO(mdm, AP2MDM_ERRFATAL), 0);
+       return 0;
+}
+
 static struct esoc_clink_ops mdm_cops = {
        .cmd_exe = mdm_cmd_exe,
        .get_status = mdm_get_status,
@@ -1040,6 +1190,18 @@ static struct mdm_ops mdm9x35_ops = {
        .pon_ops = &mdm9x35_pon_ops,
 };
 
+static struct mdm_ops mdm9x45_ops = {
+       .clink_ops = &mdm_cops,
+       .config_hw = mdm9x45_setup_hw,
+       .pon_ops = &mdm9x45_pon_ops,
+};
+
+static struct mdm_ops apq8096_ops = {
+       .clink_ops = &mdm_cops,
+       .config_hw = apq8096_setup_hw,
+       .pon_ops = &apq8096_pon_ops,
+};
+
 static struct mdm_ops mdm9x55_ops = {
        .clink_ops = &mdm_cops,
        .config_hw = mdm9x55_setup_hw,
@@ -1051,8 +1213,12 @@ static const struct of_device_id mdm_dt_match[] = {
                .data = &mdm9x25_ops, },
        { .compatible = "qcom,ext-mdm9x35",
                .data = &mdm9x35_ops, },
+       { .compatible = "qcom,ext-mdm9x45",
+               .data = &mdm9x45_ops, },
        { .compatible = "qcom,ext-mdm9x55",
                .data = &mdm9x55_ops, },
+       { .compatible = "qcom,ext-apq8096",
+               .data = &apq8096_ops, },
        {},
 };
 MODULE_DEVICE_TABLE(of, mdm_dt_match);
index 266eacc..9c2c68d 100644 (file)
@@ -306,6 +306,14 @@ static struct esoc_compat compat_table[] = {
                .name = "MDM9x55",
                .data = NULL,
        },
+       {
+               .name = "MDM9x45",
+               .data = NULL,
+       },
+       {
+               .name = "APQ8096",
+               .data = NULL,
+       },
 };
 
 static struct esoc_drv esoc_ssr_drv = {
index a54c3e2..d9b16b2 100644 (file)
@@ -158,6 +158,11 @@ static void mdm9x55_cold_reset(struct mdm_ctrl *mdm)
                        !mdm->soft_reset_inverted);
 }
 
+static int apq8096_pon_dt_init(struct mdm_ctrl *mdm)
+{
+       return 0;
+}
+
 static int mdm4x_pon_dt_init(struct mdm_ctrl *mdm)
 {
        int val;
@@ -189,6 +194,21 @@ static int mdm4x_pon_setup(struct mdm_ctrl *mdm)
        return 0;
 }
 
+/* This function can be called from atomic context. */
+static int apq8096_toggle_soft_reset(struct mdm_ctrl *mdm, bool atomic)
+{
+       return 0;
+}
+
+static int apq8096_power_down(struct mdm_ctrl *mdm)
+{
+       return 0;
+}
+
+static void apq8096_cold_reset(struct mdm_ctrl *mdm)
+{
+}
+
 struct mdm_pon_ops mdm9x25_pon_ops = {
        .pon = mdm4x_do_first_power_on,
        .soft_reset = mdm4x_toggle_soft_reset,
@@ -224,3 +244,12 @@ struct mdm_pon_ops mdm9x55_pon_ops = {
        .dt_init = mdm4x_pon_dt_init,
        .setup = mdm4x_pon_setup,
 };
+
+struct mdm_pon_ops apq8096_pon_ops = {
+       .pon = mdm4x_do_first_power_on,
+       .soft_reset = apq8096_toggle_soft_reset,
+       .poff_force = apq8096_power_down,
+       .cold_reset = apq8096_cold_reset,
+       .dt_init = apq8096_pon_dt_init,
+       .setup = mdm4x_pon_setup,
+};
index ac81172..9343e49 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2015, 2017, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -37,6 +37,8 @@
 #define MDM9x45_PCIE                   "PCIe"
 #define MDM9x55_LABEL                  "MDM9x55"
 #define MDM9x55_PCIE                   "PCIe"
+#define APQ8096_LABEL                  "APQ8096"
+#define APQ8096_PCIE                   "PCIe"
 #define MDM2AP_STATUS_TIMEOUT_MS       120000L
 #define MDM_MODEM_TIMEOUT              3000
 #define DEF_RAMDUMP_TIMEOUT            120000
@@ -153,4 +155,5 @@ extern struct mdm_pon_ops mdm9x25_pon_ops;
 extern struct mdm_pon_ops mdm9x35_pon_ops;
 extern struct mdm_pon_ops mdm9x45_pon_ops;
 extern struct mdm_pon_ops mdm9x55_pon_ops;
+extern struct mdm_pon_ops apq8096_pon_ops;
 #endif