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)
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,
.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,
.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);