From: Arun KS Date: Mon, 16 Jan 2017 12:30:37 +0000 (+0530) Subject: esoc: mdm-4x: Add support for mdm9x45 and apq8096 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=6a8855841643dd07e95f493d4b8b8fde6fd8f4c9;p=sagit-ice-cold%2Fkernel_xiaomi_msm8998.git esoc: mdm-4x: Add support for mdm9x45 and apq8096 Add mdm_ops for mdm9x45 and apq8064. Change-Id: Iea167175b9bd35a515d15a72897947a889093c03 Signed-off-by: Arun KS Signed-off-by: Srivatsa Vaddagiri --- diff --git a/Documentation/devicetree/bindings/arm/msm/mdm-modem.txt b/Documentation/devicetree/bindings/arm/msm/mdm-modem.txt index a6537ebd2512..86d2268c8b53 100644 --- a/Documentation/devicetree/bindings/arm/msm/mdm-modem.txt +++ b/Documentation/devicetree/bindings/arm/msm/mdm-modem.txt @@ -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 diff --git a/drivers/esoc/esoc-mdm-4x.c b/drivers/esoc/esoc-mdm-4x.c index ac8d8002bcd3..618ceb957c65 100644 --- a/drivers/esoc/esoc-mdm-4x.c +++ b/drivers/esoc/esoc-mdm-4x.c @@ -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); diff --git a/drivers/esoc/esoc-mdm-drv.c b/drivers/esoc/esoc-mdm-drv.c index 266eaccf8b69..9c2c68dfef65 100644 --- a/drivers/esoc/esoc-mdm-drv.c +++ b/drivers/esoc/esoc-mdm-drv.c @@ -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 = { diff --git a/drivers/esoc/esoc-mdm-pon.c b/drivers/esoc/esoc-mdm-pon.c index a54c3e2715dd..d9b16b23839b 100644 --- a/drivers/esoc/esoc-mdm-pon.c +++ b/drivers/esoc/esoc-mdm-pon.c @@ -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, +}; diff --git a/drivers/esoc/esoc-mdm.h b/drivers/esoc/esoc-mdm.h index ac811720b035..9343e49559f2 100644 --- a/drivers/esoc/esoc-mdm.h +++ b/drivers/esoc/esoc-mdm.h @@ -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