static int __devinit pil_mss_driver_probe(struct platform_device *pdev)
{
	struct q6v5_data *drv;
	struct pil_desc *desc;
	struct resource *res;
	int ret;

	desc = pil_q6v5_init(pdev);
	if (IS_ERR(desc))
		return PTR_ERR(desc);
	drv = platform_get_drvdata(pdev);
	if (drv == NULL)
		return -ENODEV;

	desc->ops = &pil_mss_ops;
	desc->owner = THIS_MODULE;
	desc->proxy_timeout = PROXY_TIMEOUT_MS;

	of_property_read_u32(pdev->dev.of_node, "qcom,pil-self-auth",
			     &drv->self_auth);
	if (drv->self_auth) {
		res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
		drv->rmb_base = devm_ioremap(&pdev->dev, res->start,
					     resource_size(res));
		if (!drv->rmb_base)
			return -ENOMEM;
	}

	res = platform_get_resource(pdev, IORESOURCE_MEM, 3);
	drv->restart_reg = devm_ioremap(&pdev->dev, res->start,
					resource_size(res));
	if (!drv->restart_reg)
		return -ENOMEM;

	drv->vreg = devm_regulator_get(&pdev->dev, "vdd_mss");
	if (IS_ERR(drv->vreg))
		return PTR_ERR(drv->vreg);

	ret = regulator_set_voltage(drv->vreg, 1150000, 1150000);
	if (ret)
		dev_err(&pdev->dev, "Failed to set regulator's voltage.\n");

	ret = regulator_set_optimum_mode(drv->vreg, 100000);
	if (ret < 0) {
		dev_err(&pdev->dev, "Failed to set regulator's mode.\n");
		return ret;
	}

	drv->mem_clk = devm_clk_get(&pdev->dev, "mem_clk");
	if (IS_ERR(drv->mem_clk))
		return PTR_ERR(drv->mem_clk);

	drv->pil = msm_pil_register(desc);
	if (IS_ERR(drv->pil))
		return PTR_ERR(drv->pil);

	return 0;
}
static int __devinit pil_lpass_driver_probe(struct platform_device *pdev)
{
	struct lpass_data *drv;
	struct q6v5_data *q6;
	struct pil_desc *desc;
	struct resource *res;
	int ret;

	drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_KERNEL);
	if (!drv)
		return -ENOMEM;
	platform_set_drvdata(pdev, drv);

	q6 = pil_q6v5_init(pdev);
	if (IS_ERR(q6))
		return PTR_ERR(q6);
	drv->q6 = q6;

	desc = &q6->desc;
	desc->owner = THIS_MODULE;
	desc->proxy_timeout = PROXY_TIMEOUT_MS;

	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "restart_reg");
	q6->restart_reg = devm_request_and_ioremap(&pdev->dev, res);
	if (!q6->restart_reg)
		return -ENOMEM;

	q6->core_clk = devm_clk_get(&pdev->dev, "core_clk");
	if (IS_ERR(q6->core_clk))
		return PTR_ERR(q6->core_clk);

	q6->ahb_clk = devm_clk_get(&pdev->dev, "iface_clk");
	if (IS_ERR(q6->ahb_clk))
		return PTR_ERR(q6->ahb_clk);

	q6->axi_clk = devm_clk_get(&pdev->dev, "bus_clk");
	if (IS_ERR(q6->axi_clk))
		return PTR_ERR(q6->axi_clk);

	q6->reg_clk = devm_clk_get(&pdev->dev, "reg_clk");
	if (IS_ERR(q6->reg_clk))
		return PTR_ERR(q6->reg_clk);

	if (pas_supported(PAS_Q6) > 0) {
		desc->ops = &pil_lpass_ops_trusted;
		dev_info(&pdev->dev, "using secure boot\n");
	} else {
		desc->ops = &pil_lpass_ops;
		dev_info(&pdev->dev, "using non-secure boot\n");
	}

	scm_pas_init(MSM_BUS_MASTER_CRYPTO_CORE0);

	ret = pil_desc_init(desc);
	if (ret)
		return ret;

	drv->subsys_desc.name = desc->name;
	drv->subsys_desc.owner = THIS_MODULE;
	drv->subsys_desc.dev = &pdev->dev;
	drv->subsys_desc.shutdown = adsp_shutdown;
	drv->subsys_desc.powerup = adsp_powerup;
	drv->subsys_desc.ramdump = adsp_ramdump;
	drv->subsys_desc.crash_shutdown = adsp_crash_shutdown;
	drv->subsys_desc.err_fatal_handler = adsp_err_fatal_intr_handler;
	drv->subsys_desc.wdog_bite_handler = adsp_wdog_bite_irq;

	INIT_WORK(&drv->work, adsp_fatal_fn);

	drv->ramdump_dev = create_ramdump_device("adsp", &pdev->dev);
	if (!drv->ramdump_dev) {
		ret = -ENOMEM;
		goto err_ramdump;
	}

	drv->subsys = subsys_register(&drv->subsys_desc);
	if (IS_ERR(drv->subsys)) {
		ret = PTR_ERR(drv->subsys);
		goto err_subsys;
	}

	lpass_status = kobject_create_and_add("audio_voice_service",
						kernel_kobj);
	if (!lpass_status) {
		pr_err("%s: kobject create failed\n", __func__);
		ret = -ENOMEM;
		goto err_create_kobj;
	}

	ret = sysfs_create_group(lpass_status, &attr_group);
	if (ret) {
		pr_err("%s: sysfs create group failed\n", __func__);
		goto err_kobj;
	}

	adsp_set_state("ONLINE");
	return 0;
err_kobj:
	kobject_put(lpass_status);
err_create_kobj:
	subsys_unregister(drv->subsys);
err_subsys:
	destroy_ramdump_device(drv->ramdump_dev);
err_ramdump:
	pil_desc_release(desc);
	return ret;
}
static int pil_mss_loadable_init(struct modem_data *drv,
					struct platform_device *pdev)
{
	struct q6v5_data *q6;
	struct pil_desc *q6_desc;
	struct resource *res;
	struct property *prop;
	int ret;

	q6 = pil_q6v5_init(pdev);
	if (IS_ERR(q6))
		return PTR_ERR(q6);
	drv->q6 = q6;
	drv->xo = q6->xo;

	q6_desc = &q6->desc;
	q6_desc->owner = THIS_MODULE;
	q6_desc->proxy_timeout = PROXY_TIMEOUT_MS;

	q6_desc->ops = &pil_msa_mss_ops;

	q6->self_auth = of_property_read_bool(pdev->dev.of_node,
							"qcom,pil-self-auth");
	if (q6->self_auth) {
		res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
						    "rmb_base");
		q6->rmb_base = devm_request_and_ioremap(&pdev->dev, res);
		if (!q6->rmb_base)
			return -ENOMEM;
		drv->rmb_base = q6->rmb_base;
		q6_desc->ops = &pil_msa_mss_ops_selfauth;
	}

	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "restart_reg");
	if (!res) {
		res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
							"restart_reg_sec");
		q6->restart_reg_sec = true;
	}

	q6->restart_reg = devm_request_and_ioremap(&pdev->dev, res);
	if (!q6->restart_reg)
		return -ENOMEM;

	q6->vreg = NULL;

	prop = of_find_property(pdev->dev.of_node, "vdd_mss-supply", NULL);
	if (prop) {
		q6->vreg = devm_regulator_get(&pdev->dev, "vdd_mss");
		if (IS_ERR(q6->vreg))
			return PTR_ERR(q6->vreg);

		ret = regulator_set_voltage(q6->vreg, VDD_MSS_UV,
						MAX_VDD_MSS_UV);
		if (ret)
			dev_err(&pdev->dev, "Failed to set vreg voltage.\n");

		ret = regulator_set_optimum_mode(q6->vreg, 100000);
		if (ret < 0) {
			dev_err(&pdev->dev, "Failed to set vreg mode.\n");
			return ret;
		}
	}

	q6->vreg_mx = devm_regulator_get(&pdev->dev, "vdd_mx");
	if (IS_ERR(q6->vreg_mx))
		return PTR_ERR(q6->vreg_mx);
	prop = of_find_property(pdev->dev.of_node, "vdd_mx-uV", NULL);
	if (!prop) {
		dev_err(&pdev->dev, "Missing vdd_mx-uV property\n");
		return -EINVAL;
	}

	res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
		"cxrail_bhs_reg");
	if (res)
		q6->cxrail_bhs = devm_ioremap(&pdev->dev, res->start,
					  resource_size(res));

	q6->ahb_clk = devm_clk_get(&pdev->dev, "iface_clk");
	if (IS_ERR(q6->ahb_clk))
		return PTR_ERR(q6->ahb_clk);

	q6->axi_clk = devm_clk_get(&pdev->dev, "bus_clk");
	if (IS_ERR(q6->axi_clk))
		return PTR_ERR(q6->axi_clk);

	q6->rom_clk = devm_clk_get(&pdev->dev, "mem_clk");
	if (IS_ERR(q6->rom_clk))
		return PTR_ERR(q6->rom_clk);

	/* Optional. */
	if (of_property_match_string(pdev->dev.of_node,
			"qcom,active-clock-names", "gpll0_mss_clk") >= 0)
		q6->gpll0_mss_clk = devm_clk_get(&pdev->dev, "gpll0_mss_clk");

	ret = pil_desc_init(q6_desc);

	return ret;
}
static int __devinit pil_mss_loadable_init(struct modem_data *drv,
					struct platform_device *pdev)
{
	struct q6v5_data *q6;
	struct mba_data *mba;
	struct pil_desc *q6_desc, *mba_desc;
	struct resource *res;
	struct property *prop;
	int ret;

#ifdef CONFIG_MACH_LGE
	dev_info(&pdev->dev, " pil_mss_loadable init.");
#endif

	mba = devm_kzalloc(&pdev->dev, sizeof(*mba), GFP_KERNEL);
	if (!mba)
		return -ENOMEM;
	drv->mba = mba;

#ifdef CONFIG_MACH_LGE
	dev_info(&pdev->dev, " pil_mss_loadable init.");
#endif

	q6 = pil_q6v5_init(pdev);
	if (IS_ERR(q6))
		return PTR_ERR(q6);
	drv->q6 = q6;
	drv->mba->xo = q6->xo;

	q6_desc = &q6->desc;
	q6_desc->ops = &pil_msa_pbl_ops;
	q6_desc->owner = THIS_MODULE;
	q6_desc->proxy_timeout = PROXY_TIMEOUT_MS;

	q6->self_auth = of_property_read_bool(pdev->dev.of_node,
							"qcom,pil-self-auth");
	if (q6->self_auth) {
		res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
						    "rmb_base");
		q6->rmb_base = devm_request_and_ioremap(&pdev->dev, res);
		if (!q6->rmb_base)
			return -ENOMEM;
		mba->rmb_base = q6->rmb_base;
	}

	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "restart_reg");
	q6->restart_reg = devm_request_and_ioremap(&pdev->dev, res);
	if (!q6->restart_reg)
		return -ENOMEM;

	q6->vreg = NULL;

	prop = of_find_property(pdev->dev.of_node, "vdd_mss-supply", NULL);
	if (prop) {
		q6->vreg = devm_regulator_get(&pdev->dev, "vdd_mss");
		if (IS_ERR(q6->vreg))
			return PTR_ERR(q6->vreg);

		ret = regulator_set_voltage(q6->vreg, VDD_MSS_UV,
						MAX_VDD_MSS_UV);
		if (ret)
			dev_err(&pdev->dev, "Failed to set vreg voltage.\n");

		ret = regulator_set_optimum_mode(q6->vreg, 100000);
		if (ret < 0) {
			dev_err(&pdev->dev, "Failed to set vreg mode.\n");
			return ret;
		}
	}

	q6->vreg_mx = devm_regulator_get(&pdev->dev, "vdd_mx");
	if (IS_ERR(q6->vreg_mx))
		return PTR_ERR(q6->vreg_mx);

	res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
		"cxrail_bhs_reg");
	if (res)
		q6->cxrail_bhs = devm_ioremap(&pdev->dev, res->start,
					  resource_size(res));

	q6->ahb_clk = devm_clk_get(&pdev->dev, "iface_clk");
	if (IS_ERR(q6->ahb_clk))
		return PTR_ERR(q6->ahb_clk);

	q6->axi_clk = devm_clk_get(&pdev->dev, "bus_clk");
	if (IS_ERR(q6->axi_clk))
		return PTR_ERR(q6->axi_clk);

	q6->rom_clk = devm_clk_get(&pdev->dev, "mem_clk");
	if (IS_ERR(q6->rom_clk))
		return PTR_ERR(q6->rom_clk);

	ret = pil_desc_init(q6_desc);
	if (ret)
		return ret;
#ifdef CONFIG_MACH_LGE
	if (q6_desc && q6_desc->name)
		dev_info(&pdev->dev, " %s description init success",
				q6_desc->name);
#endif

	mba_desc = &mba->desc;
	mba_desc->name = "modem";
	mba_desc->dev = &pdev->dev;
	mba_desc->ops = &pil_msa_mba_ops;
	mba_desc->owner = THIS_MODULE;
#ifdef CONFIG_MACH_LGE
	if (mba_desc && mba_desc->name)
		dev_info(&pdev->dev, " %s description init success",
				mba_desc->name);
#endif

	ret = pil_desc_init(mba_desc);
	if (ret)
		goto err_mba_desc;

	return 0;

err_mba_desc:
	pil_desc_release(q6_desc);
	return ret;

}
static int pil_femto_modem_driver_probe(
	struct platform_device *pdev)
{
	struct femto_modem_data *drv;
	struct q6v5_data *q6;
	struct pil_desc *q6_desc;
	struct device_node *p_node = pdev->dev.of_node;
	int ret = 0;

	drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_KERNEL);
	if (!drv)
		return -ENOMEM;
	platform_set_drvdata(pdev, drv);

	/* Retrieve the maximum number of modems */
	ret = of_property_read_u32(p_node, "qcom,max-num-modems",
		&drv->max_num_modems);
	if (ret)
		return ret;

	/* Max number of modems must be greater than zero */
	if (!drv->max_num_modems)
		return -EINVAL;

	/* Allocate memory for modem structs */
	drv->modem = devm_kzalloc(&pdev->dev,
		(sizeof(*(drv->modem)) * drv->max_num_modems), GFP_KERNEL);
	if (!drv->modem)
		return -ENOMEM;

	/* This controls the loading of the MBA firmware to Q6[0] */
	q6 = pil_q6v5_init(pdev);
	if (IS_ERR(q6))
		return PTR_ERR(q6);
	drv->q6 = q6;

	/* This is needed for legacy code.  Always on. */
	q6->self_auth = 1;

	q6_desc = &q6->desc;
	q6_desc->ops = &pil_msa_mss_ops;
	q6_desc->owner = THIS_MODULE;
	q6_desc->proxy_timeout = 0;
	q6_desc->map_fw_mem = pil_femto_modem_map_fw_mem;
	q6_desc->unmap_fw_mem = NULL;

	/* For this target, PBL interactions are different. */
	pil_msa_mss_ops.proxy_vote = NULL;
	pil_msa_mss_ops.proxy_unvote = NULL;

	/* Initialize the number of discovered modems. */
	drv->disc_modems = 0;

	/* Parse the device tree to get RMB regs and filenames for each modem */
	ret = of_platform_populate(p_node, NULL, NULL, &pdev->dev);
	if (ret)
		return ret;

	/* Initialize the PIL descriptor */
	ret = pil_desc_init(q6_desc);

	if (ret)
		return ret;

	/* Create the sysfs attributes */
	ret = pil_femto_modem_create_sysfs(drv);

	if (ret)
		pil_desc_release(q6_desc);

	return ret;
}