static int __devinit pil_q6v4_modem_driver_probe(struct platform_device *pdev)
{
	struct q6v4_data *drv_fw, *drv_sw;
	struct q6v4_modem *drv;
	struct resource *res;
	struct regulator *pll_supply;
	int ret;
	const struct pil_q6v4_pdata *pdata = pdev->dev.platform_data;

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

	drv_fw = &drv->q6_fw;
	drv_sw = &drv->q6_sw;

	drv_fw->wdog_irq = platform_get_irq(pdev, 0);
	if (drv_fw->wdog_irq < 0)
		return drv_fw->wdog_irq;

	drv_sw->wdog_irq = platform_get_irq(pdev, 1);
	if (drv_sw->wdog_irq < 0)
		return drv_sw->wdog_irq;

	drv->loadable = !!pdata; /* No pdata = don't use PIL */
	if (drv->loadable) {
		ret = pil_q6v4_proc_init(drv_fw, pdev, 0);
		if (ret)
			return ret;

		ret = pil_q6v4_proc_init(drv_sw, pdev, 1);
		if (ret)
			return ret;

		pll_supply = devm_regulator_get(&pdev->dev, "pll_vdd");
		drv_fw->pll_supply = drv_sw->pll_supply = pll_supply;
		if (IS_ERR(pll_supply))
			return PTR_ERR(pll_supply);

		ret = regulator_set_voltage(pll_supply, 1800000, 1800000);
		if (ret) {
			dev_err(&pdev->dev, "failed to set pll voltage\n");
			return ret;
		}

		ret = regulator_set_optimum_mode(pll_supply, 100000);
		if (ret < 0) {
			dev_err(&pdev->dev, "failed to set pll optimum mode\n");
			return ret;
		}

		res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
		drv->modem_base = devm_request_and_ioremap(&pdev->dev, res);
		if (!drv->modem_base)
			return -ENOMEM;

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

		ret = pil_desc_init(&drv_fw->desc);
		if (ret)
			return ret;

		ret = pil_desc_init(&drv_sw->desc);
		if (ret)
			goto err_pil_sw;
	}

	drv->subsys_desc.name = "modem";
	drv->subsys_desc.depends_on = "adsp";
	drv->subsys_desc.dev = &pdev->dev;
	drv->subsys_desc.owner = THIS_MODULE;
	drv->subsys_desc.shutdown = modem_shutdown;
	drv->subsys_desc.powerup = modem_powerup;
	drv->subsys_desc.ramdump = modem_ramdump;
	drv->subsys_desc.crash_shutdown = modem_crash_shutdown;

	drv->fw_ramdump_dev = create_ramdump_device("modem_fw", &pdev->dev);
	if (!drv->fw_ramdump_dev) {
		ret = -ENOMEM;
		goto err_fw_ramdump;
	}

	drv->sw_ramdump_dev = create_ramdump_device("modem_sw", &pdev->dev);
	if (!drv->sw_ramdump_dev) {
		ret = -ENOMEM;
		goto err_sw_ramdump;
	}

	drv->smem_ramdump_dev = create_ramdump_device("smem-modem", &pdev->dev);
	if (!drv->smem_ramdump_dev) {
		ret = -ENOMEM;
		goto err_smem_ramdump;
	}

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

	ret = devm_request_irq(&pdev->dev, drv_fw->wdog_irq,
			modem_wdog_bite_irq, IRQF_TRIGGER_RISING,
			dev_name(&pdev->dev), drv);
	if (ret)
		goto err_irq;
	disable_irq(drv_fw->wdog_irq);

	ret = devm_request_irq(&pdev->dev, drv_sw->wdog_irq,
			modem_wdog_bite_irq, IRQF_TRIGGER_RISING,
			dev_name(&pdev->dev), drv);
	if (ret)
		goto err_irq;
	disable_irq(drv_sw->wdog_irq);

	scm_pas_init(MSM_BUS_MASTER_SPS);

	ret = smsm_state_cb_register(SMSM_MODEM_STATE, SMSM_RESET,
			smsm_state_cb, drv);
	if (ret)
		goto err_irq;
	return 0;

err_irq:
	subsys_unregister(drv->subsys);
err_subsys:
	destroy_ramdump_device(drv->smem_ramdump_dev);
err_smem_ramdump:
	destroy_ramdump_device(drv->sw_ramdump_dev);
err_sw_ramdump:
	destroy_ramdump_device(drv->fw_ramdump_dev);
err_fw_ramdump:
	if (drv->loadable)
		pil_desc_release(&drv_sw->desc);
err_pil_sw:
	pil_desc_release(&drv_fw->desc);
	return ret;
}
Exemplo n.º 2
0
static int __devinit pil_modem_driver_probe(struct platform_device *pdev)
{
	struct modem_data *drv;
	struct resource *res;
	struct pil_desc *desc;
	int ret;

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

	drv->irq = platform_get_irq(pdev, 0);
	if (drv->irq < 0)
		return drv->irq;

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

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	drv->base = devm_request_and_ioremap(&pdev->dev, res);
	if (!drv->base)
		return -ENOMEM;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
	drv->wdog = devm_request_and_ioremap(&pdev->dev, res);
	if (!drv->wdog)
		return -ENOMEM;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
	if (!res)
		return -EINVAL;

	drv->cbase = devm_ioremap(&pdev->dev, res->start, resource_size(res));
	if (!drv->cbase)
		return -ENOMEM;

	desc = &drv->pil_desc;
	desc->name = "modem";
	desc->dev = &pdev->dev;
	desc->owner = THIS_MODULE;
	desc->proxy_timeout = 10000;

	if (pas_supported(PAS_MODEM) > 0) {
		desc->ops = &pil_modem_ops_trusted;
		dev_info(&pdev->dev, "using secure boot\n");
	} else {
		desc->ops = &pil_modem_ops;
		dev_info(&pdev->dev, "using non-secure boot\n");
	}
	ret = pil_desc_init(desc);
	if (ret)
		return ret;

	drv->notifier.notifier_call = modem_notif_handler,
	ret = modem_register_notifier(&drv->notifier);
	if (ret)
		goto err_notify;

	drv->subsys_desc.name = "modem";
	drv->subsys_desc.depends_on = "adsp";
	drv->subsys_desc.dev = &pdev->dev;
	drv->subsys_desc.owner = THIS_MODULE;
	drv->subsys_desc.start = modem_start;
	drv->subsys_desc.stop = modem_stop;
	drv->subsys_desc.shutdown = modem_shutdown;
	drv->subsys_desc.powerup = modem_powerup;
	drv->subsys_desc.ramdump = modem_ramdump;
	drv->subsys_desc.crash_shutdown = modem_crash_shutdown;

	INIT_WORK(&drv->fatal_work, modem_fatal_fn);
	INIT_DELAYED_WORK(&drv->unlock_work, modem_unlock_timeout);

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

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

	scm_pas_init(MSM_BUS_MASTER_SPS);

	ret = devm_request_irq(&pdev->dev, drv->irq, modem_wdog_bite_irq,
			IRQF_TRIGGER_RISING, "modem_watchdog", drv);
	if (ret)
		goto err_irq;
	return 0;

err_irq:
	destroy_ramdump_device(drv->ramdump_dev);
err_ramdump:
	subsys_unregister(drv->subsys);
err_subsys:
	modem_unregister_notifier(&drv->notifier);
err_notify:
	pil_desc_release(desc);
	return ret;
}
Exemplo n.º 3
0
static int dsps_alloc_resources(struct platform_device *pdev)
{
	int ret = -ENODEV;
	struct resource *ppss_res;
	struct resource *ppss_wdog;
	int i;

	pr_debug("%s.\n", __func__);

	if ((drv->pdata->signature != DSPS_SIGNATURE)) {
		pr_err("%s: invalid signature for pdata.", __func__);
		return -EINVAL;
	}

	ppss_res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
						"ppss_reg");
	if (!ppss_res) {
		pr_err("%s: failed to get ppss_reg resource.\n", __func__);
		return -EINVAL;
	}

	for (i = 0; i < drv->pdata->clks_num; i++) {
		const char *name = drv->pdata->clks[i].name;
		struct clk *clock;

		drv->pdata->clks[i].clock = NULL;

		pr_debug("%s: get clk %s.", __func__, name);

		clock = clk_get(drv->dev, name);
		if (IS_ERR(clock)) {
			pr_err("%s: can't get clk %s.", __func__, name);
			goto clk_err;
		}
		drv->pdata->clks[i].clock = clock;
	}

	for (i = 0; i < drv->pdata->gpios_num; i++) {
		const char *name = drv->pdata->gpios[i].name;
		int num = drv->pdata->gpios[i].num;

		drv->pdata->gpios[i].is_owner = false;

		pr_debug("%s: get gpio %s.", __func__, name);

		ret = gpio_request(num, name);
		if (ret) {
			pr_err("%s: request GPIO %s err %d.",
			       __func__, name, ret);
			goto gpio_err;
		}

		drv->pdata->gpios[i].is_owner = true;

	}

	for (i = 0; i < drv->pdata->regs_num; i++) {
		const char *name = drv->pdata->regs[i].name;

		drv->pdata->regs[i].reg = NULL;

		pr_debug("%s: get regulator %s.", __func__, name);

		drv->pdata->regs[i].reg = regulator_get(drv->dev, name);
		if (IS_ERR(drv->pdata->regs[i].reg)) {
			pr_err("%s: get regulator %s failed.",
			       __func__, name);
			goto reg_err;
		}
	}

	drv->ppss_base = ioremap(ppss_res->start,
				 resource_size(ppss_res));

	ppss_wdog = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
						"ppss_wdog");
	if (ppss_wdog) {
		drv->wdog_irq = ppss_wdog->start;
		ret = request_irq(drv->wdog_irq, dsps_wdog_bite_irq,
				  IRQF_TRIGGER_RISING, "dsps_wdog", NULL);
		if (ret) {
			pr_err("%s: request_irq fail %d\n", __func__, ret);
			goto request_irq_err;
		}
	} else {
		drv->wdog_irq = -1;
		pr_debug("%s: ppss_wdog not supported.\n", __func__);
	}

	drv->dspsfw_ramdump_segments[0].address = drv->pdata->tcm_code_start;
	drv->dspsfw_ramdump_segments[0].size =  drv->pdata->tcm_code_size;
	drv->dspsfw_ramdump_segments[1].address = drv->pdata->tcm_buf_start;
	drv->dspsfw_ramdump_segments[1].size =  drv->pdata->tcm_buf_size;
	drv->dspsfw_ramdump_segments[2].address = drv->pdata->pipe_start;
	drv->dspsfw_ramdump_segments[2].size =  drv->pdata->pipe_size;
	drv->dspsfw_ramdump_segments[3].address = drv->pdata->ddr_start;
	drv->dspsfw_ramdump_segments[3].size =  drv->pdata->ddr_size;

	drv->dspsfw_ramdump_dev = create_ramdump_device("dsps");
	if (!drv->dspsfw_ramdump_dev) {
		pr_err("%s: create_ramdump_device(\"dsps\") fail\n",
			      __func__);
		goto create_ramdump_err;
	}

	drv->smem_ramdump_segments[0].address = drv->pdata->smem_start;
	drv->smem_ramdump_segments[0].size =  drv->pdata->smem_size;
	drv->smem_ramdump_dev = create_ramdump_device("smem-dsps");
	if (!drv->smem_ramdump_dev) {
		pr_err("%s: create_ramdump_device(\"smem\") fail\n",
		       __func__);
		goto create_ramdump_err;
	}

	if (drv->pdata->init)
		drv->pdata->init(drv->pdata);

	return 0;

create_ramdump_err:
	disable_irq_nosync(drv->wdog_irq);
	free_irq(drv->wdog_irq, NULL);

request_irq_err:
	iounmap(drv->ppss_base);

reg_err:
	for (i = 0; i < drv->pdata->regs_num; i++) {
		if (drv->pdata->regs[i].reg) {
			regulator_put(drv->pdata->regs[i].reg);
			drv->pdata->regs[i].reg = NULL;
		}
	}

gpio_err:
	for (i = 0; i < drv->pdata->gpios_num; i++)
		if (drv->pdata->gpios[i].is_owner) {
			gpio_free(drv->pdata->gpios[i].num);
			drv->pdata->gpios[i].is_owner = false;
		}
clk_err:
	for (i = 0; i < drv->pdata->clks_num; i++)
		if (drv->pdata->clks[i].clock) {
			clk_put(drv->pdata->clks[i].clock);
			drv->pdata->clks[i].clock = NULL;
		}

	return ret;
}
static int __init gss_8064_init(void)
{
	int ret;

	if (!cpu_is_apq8064())
		return -ENODEV;

	ret = smsm_state_cb_register(SMSM_MODEM_STATE, SMSM_RESET,
		smsm_state_cb, 0);

	if (ret < 0)
		pr_err("%s: Unable to register SMSM callback! (%d)\n",
				__func__, ret);

	ret = request_irq(GSS_A5_WDOG_EXPIRED, gss_wdog_bite_irq,
			IRQF_TRIGGER_RISING, "gss_a5_wdog", NULL);

	if (ret < 0) {
		pr_err("%s: Unable to request gss watchdog IRQ. (%d)\n",
				__func__, ret);
		disable_irq_nosync(GSS_A5_WDOG_EXPIRED);
		goto out;
	}

	ret = gss_subsystem_restart_init();

	if (ret < 0) {
		pr_err("%s: Unable to reg with subsystem restart. (%d)\n",
				__func__, ret);
		goto out;
	}

	gss_data.gss_dev.minor = MISC_DYNAMIC_MINOR;
	gss_data.gss_dev.name = "gss";
	gss_data.gss_dev.fops = &gss_file_ops;
	ret = misc_register(&gss_data.gss_dev);

	if (ret) {
		pr_err("%s: misc_registers failed for %s (%d)", __func__,
				gss_data.gss_dev.name, ret);
		goto out;
	}

	gss_data.gss_ramdump_dev = create_ramdump_device("gss");

	if (!gss_data.gss_ramdump_dev) {
		pr_err("%s: Unable to create gss ramdump device. (%d)\n",
				__func__, -ENOMEM);
		ret = -ENOMEM;
		goto out;
	}

	gss_data.smem_ramdump_dev = create_ramdump_device("smem-gss");

	if (!gss_data.smem_ramdump_dev) {
		pr_err("%s: Unable to create smem ramdump device. (%d)\n",
				__func__, -ENOMEM);
		ret = -ENOMEM;
		goto out;
	}

	pr_info("%s: gss fatal driver init'ed.\n", __func__);
out:
	return ret;
}
static int __devinit pil_pronto_probe(struct platform_device *pdev)
{
	struct pronto_data *drv;
	struct resource *res;
	struct pil_desc *desc;
	int ret;
	uint32_t regval;

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

	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pmu_base");
	drv->base = devm_request_and_ioremap(&pdev->dev, res);
	if (!drv->base)
		return -ENOMEM;

	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "clk_base");
	drv->reset_base = devm_request_and_ioremap(&pdev->dev, res);
	if (!drv->reset_base)
		return -ENOMEM;

	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "halt_base");
	drv->axi_halt_base = devm_request_and_ioremap(&pdev->dev, res);
	if (!drv->axi_halt_base)
		return -ENOMEM;

	desc = &drv->desc;
	ret = of_property_read_string(pdev->dev.of_node, "qcom,firmware-name",
				      &desc->name);
	if (ret)
		return ret;

	desc->dev = &pdev->dev;
	desc->owner = THIS_MODULE;
	desc->proxy_timeout = 10000;

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

	drv->vreg = devm_regulator_get(&pdev->dev, "vdd_pronto_pll");
	if (IS_ERR(drv->vreg)) {
		dev_err(&pdev->dev, "failed to get pronto pll supply");
		return PTR_ERR(drv->vreg);
	}

	ret = regulator_set_voltage(drv->vreg, 1800000, 1800000);
	if (ret) {
		dev_err(&pdev->dev, "failed to set pll supply voltage\n");
		return ret;
	}

	ret = regulator_set_optimum_mode(drv->vreg, 18000);
	if (ret < 0) {
		dev_err(&pdev->dev, "failed to set pll supply mode\n");
		return ret;
	}

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

	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.dev = &pdev->dev;
	drv->subsys_desc.owner = THIS_MODULE;
	drv->subsys_desc.shutdown = wcnss_shutdown;
	drv->subsys_desc.powerup = wcnss_powerup;
	drv->subsys_desc.ramdump = wcnss_ramdump;
	drv->subsys_desc.crash_shutdown = crash_shutdown;
	drv->subsys_desc.start = pronto_start;
	drv->subsys_desc.stop = pronto_stop;
	drv->subsys_desc.err_fatal_handler = wcnss_err_fatal_intr_handler;
	drv->subsys_desc.wdog_bite_handler = wcnss_wdog_bite_irq_hdlr;

	INIT_DELAYED_WORK(&drv->cancel_vote_work, wcnss_post_bootup);

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

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

	/* Initialize common_ss GDSCR to wait 4 cycles between states */
	regval = readl_relaxed(drv->base + PRONTO_PMU_COMMON_GDSCR)
		& PRONTO_PMU_COMMON_GDSCR_SW_COLLAPSE;
	regval |= (2 << EN_REST_WAIT) | (2 << EN_FEW_WAIT)
		  | (2 << CLK_DIS_WAIT);
	writel_relaxed(regval, drv->base + PRONTO_PMU_COMMON_GDSCR);

	return 0;

err_irq:
	subsys_unregister(drv->subsys);
err_subsys:
	pil_desc_release(desc);
	return ret;
}
Exemplo n.º 6
0
static int __init modem_8960_init(void)
{
	int ret;

	if (cpu_is_apq8064())
		return -ENODEV;

	ret = smsm_state_cb_register(SMSM_MODEM_STATE, SMSM_RESET,
		smsm_state_cb, 0);

	if (ret < 0)
		pr_err("%s: Unable to register SMSM callback! (%d)\n",
				__func__, ret);

	ret = request_irq(Q6FW_WDOG_EXPIRED_IRQ, modem_wdog_bite_irq,
			IRQF_TRIGGER_RISING, "modem_wdog_fw", NULL);

	if (ret < 0) {
		pr_err("%s: Unable to request q6fw watchdog IRQ. (%d)\n",
				__func__, ret);
		goto out;
	}

	ret = request_irq(Q6SW_WDOG_EXPIRED_IRQ, modem_wdog_bite_irq,
			IRQF_TRIGGER_RISING, "modem_wdog_sw", NULL);

	if (ret < 0) {
		pr_err("%s: Unable to request q6sw watchdog IRQ. (%d)\n",
				__func__, ret);
		disable_irq_nosync(Q6FW_WDOG_EXPIRED_IRQ);
		goto out;
	}

	ret = modem_subsystem_restart_init();

	if (ret < 0) {
		pr_err("%s: Unable to reg with subsystem restart. (%d)\n",
				__func__, ret);
		goto out;
	}

	modemfw_ramdump_dev = create_ramdump_device("modem_fw");

	if (!modemfw_ramdump_dev) {
		pr_err("%s: Unable to create modem fw ramdump device. (%d)\n",
				__func__, -ENOMEM);
		ret = -ENOMEM;
		goto out;
	}

	modemsw_ramdump_dev = create_ramdump_device("modem_sw");

	if (!modemsw_ramdump_dev) {
		pr_err("%s: Unable to create modem sw ramdump device. (%d)\n",
				__func__, -ENOMEM);
		ret = -ENOMEM;
		goto out;
	}

	smem_ramdump_dev = create_ramdump_device("smem-modem");

	if (!smem_ramdump_dev) {
		pr_err("%s: Unable to create smem ramdump device. (%d)\n",
				__func__, -ENOMEM);
		ret = -ENOMEM;
		goto out;
	}

	ret = modem_debugfs_init();

	pr_info("%s: modem fatal driver init'ed.\n", __func__);
out:
	return ret;
}