u32 ddl_fw_init(struct ddl_buf_addr *dram_base)
{
	u8 *dest_addr;
	dest_addr = DDL_GET_ALIGNED_VITUAL(*dram_base);
	DDL_MSG_LOW("FW Addr / FW Size : %x/%d", (u32)vidc_video_codec_fw,
		vidc_video_codec_fw_size);
	if (res_trk_check_for_sec_session() && res_trk_is_cp_enabled()) {
		if (res_trk_enable_footswitch()) {
			pr_err("Failed to enable footswitch");
			return false;
		}
		if (res_trk_enable_iommu_clocks()) {
			res_trk_disable_footswitch();
			pr_err("Failed to enable iommu clocks\n");
			return false;
		}
		dram_base->pil_cookie = subsystem_get("vidc");
		if (res_trk_disable_iommu_clocks())
			pr_err("Failed to disable iommu clocks\n");
		if (IS_ERR_OR_NULL(dram_base->pil_cookie)) {
			res_trk_disable_footswitch();
			pr_err("subsystem_get failed\n");
			return false;
		}
	} else {
		if (vidc_video_codec_fw_size > dram_base->buffer_size ||
				!vidc_video_codec_fw)
			return false;
		memcpy(dest_addr, vidc_video_codec_fw,
				vidc_video_codec_fw_size);
	}
	return true;
}
static void *msm_rmnet_load_modem(struct net_device *dev)
{
	void *pil;
	int rc;
	struct rmnet_private *p = netdev_priv(dev);

	pil = subsystem_get("modem");
	if (IS_ERR(pil))
		pr_err("[%s] %s: modem load failed\n",
			dev->name, __func__);
	else if (msm_rmnet_modem_wait) {
		rc = wait_for_completion_interruptible_timeout(
			&p->complete,
			msecs_to_jiffies(msm_rmnet_modem_wait * 1000));
		if (!rc)
			rc = -ETIMEDOUT;
		if (rc < 0) {
			pr_err("[%s] %s: wait for rmnet port failed %d\n",
			       dev->name, __func__, rc);
			msm_rmnet_unload_modem(pil);
			pil = ERR_PTR(rc);
		}
	}

	return pil;
}
示例#3
0
static int dsps_load(void)
{
	pr_debug("%s.\n", __func__);

	drv->pil = subsystem_get("dsps");
	if (IS_ERR(drv->pil)) {
		pr_err("%s: fail to load DSPS firmware.\n", __func__);
		return -ENODEV;
	}
	msleep(20);
	return 0;
}
static int sns_load_adsp(void)
{
	sns_ctl.pil = subsystem_get("adsp");
	if (IS_ERR(sns_ctl.pil)) {
		pr_err("%s: fail to load ADSP firmware\n", __func__);
		return -ENODEV;
	}

	pr_debug("%s: Q6/ADSP image is loaded\n", __func__);

	return 0;
}
static int adsp_loader_probe(struct platform_device *pdev)
{
	struct adsp_loader_private *priv;
	int rc = 0;
	const char *adsp_dt = "qcom,adsp-state";
	u32 adsp_state;

	rc = of_property_read_u32(pdev->dev.of_node, adsp_dt, &adsp_state);
	if (rc) {
		dev_err(&pdev->dev,
			"%s: ADSP state = %x\n", __func__, adsp_state);
		return rc;
	}

	if (adsp_state == APR_SUBSYS_DOWN) {
		priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
		if (!priv)
			return -ENOMEM;

		platform_set_drvdata(pdev, priv);

		priv->pil_h = subsystem_get("adsp");
		if (IS_ERR(priv->pil_h)) {
			pr_err("%s: pil get adsp failed, error:%d\n",
				__func__, rc);
			devm_kfree(&pdev->dev, priv);
			goto fail;
		}

		/* Set the state of the ADSP in APR driver */
		apr_set_q6_state(APR_SUBSYS_LOADED);
	} else if (adsp_state == APR_SUBSYS_LOADED) {
		dev_dbg(&pdev->dev,
			"%s:MDM9x25 ADSP state = %x\n", __func__, adsp_state);
		apr_set_q6_state(APR_SUBSYS_LOADED);
	}

	/* Query for MMPM API */

	pr_info("%s: Q6/ADSP image is loaded\n", __func__);
fail:
	return rc;
}
示例#6
0
static int smd_tty_port_activate(struct tty_port *tport,
				 struct tty_struct *tty)
{
	int res = 0;
	unsigned int n = tty->index;
	struct smd_tty_info *info;
	const char *peripheral = NULL;


	if (n >= MAX_SMD_TTYS || !smd_tty[n].smd)
		return -ENODEV;

	info = smd_tty + n;

	mutex_lock(&smd_tty_lock);
	tty->driver_data = info;

	peripheral = smd_edge_to_subsystem(smd_tty[n].smd->edge);
	if (peripheral) {
		info->pil = subsystem_get(peripheral);
		if (IS_ERR(info->pil)) {
			SMD_TTY_INFO(
				"%s failed on smd_tty device :%s subsystem_get failed for %s",
				__func__, smd_tty[n].smd->port_name,
				peripheral);

			/*
			 * Sleep, inorder to reduce the frequency of
			 * retry by user-space modules and to avoid
			 * possible watchdog bite.
			 */
			msleep((smd_tty[n].open_wait * 1000));
			res = PTR_ERR(info->pil);
			goto out;
		}

		/* Wait for the modem SMSM to be inited for the SMD
		 * Loopback channel to be allocated at the modem. Since
		 * the wait need to be done atmost once, using msleep
		 * doesn't degrade the performance.
		 */
		if (n == LOOPBACK_IDX) {
			if (!is_modem_smsm_inited())
				msleep(5000);
			smsm_change_state(SMSM_APPS_STATE,
					  0, SMSM_SMD_LOOPBACK);
			msleep(100);
		}

		/*
		 * Wait for a channel to be allocated so we know
		 * the modem is ready enough.
		 */
		if (smd_tty[n].open_wait) {
			res = wait_for_completion_interruptible_timeout(
					&info->ch_allocated,
					msecs_to_jiffies(smd_tty[n].open_wait *
									1000));

			if (res == 0) {
				SMD_TTY_INFO(
					"Timed out waiting for SMD channel %s",
					smd_tty[n].smd->port_name);
				res = -ETIMEDOUT;
				goto release_pil;
			} else if (res < 0) {
				SMD_TTY_INFO(
					"Error waiting for SMD channel %s : %d\n",
					smd_tty[n].smd->port_name, res);
				goto release_pil;
			}
#ifdef CONFIG_MSM_SMD_TTY_DS_LEGACY
			/*
			 * on boot, process tried to open smd0 sleeps until
			 * modem is ready or timeout.
			 */
			if (n == DS_IDX) {
				/* wait for open ready status in seconds */
				pr_info("%s: checking DS modem status\n", __func__);
				res = wait_event_interruptible_timeout(
						info->ch_opened_wait_queue,
						info->is_dsmodem_ready,
						(smd_tty_ds_modem_wait * HZ));
				if (!res) {
					res = -ETIMEDOUT;
					pr_err("%s: timeout to wait for %s modem: %d\n",
							__func__,
							smd_tty[n].smd->port_name,
							res);
					goto release_pil;
				} else if (res < 0) {
					pr_err("%s: Error waiting for %s modem: %d\n",
							__func__,
							smd_tty[n].smd->port_name,
							res);
					goto release_pil;
				}
				pr_info("%s: DS modem is OK, open smd0..\n",
						__func__);
			}
#endif
		}
	}

	tasklet_init(&info->tty_tsklt, smd_tty_read, (unsigned long)info);
	wake_lock_init(&info->wake_lock, WAKE_LOCK_SUSPEND,
			smd_tty[n].smd->port_name);
	scnprintf(info->ra_wake_lock_name, MAX_RA_WAKE_LOCK_NAME_LEN,
		  "SMD_TTY_%s_RA", smd_tty[n].smd->port_name);
	wake_lock_init(&info->ra_wake_lock, WAKE_LOCK_SUSPEND,
			info->ra_wake_lock_name);

	res = smd_named_open_on_edge(smd_tty[n].smd->port_name,
				     smd_tty[n].smd->edge, &info->ch, info,
				     smd_tty_notify);
	if (res < 0) {
		SMD_TTY_INFO("%s: %s open failed %d\n",
			      __func__, smd_tty[n].smd->port_name, res);
		goto release_wl_tl;
	}

	res = wait_event_interruptible_timeout(info->ch_opened_wait_queue,
					       info->is_open, (2 * HZ));
	if (res == 0)
		res = -ETIMEDOUT;
	if (res < 0) {
		SMD_TTY_INFO("%s: wait for %s smd_open failed %d\n",
			      __func__, smd_tty[n].smd->port_name, res);
		goto close_ch;
	}
	SMD_TTY_INFO("%s with PID %u opened port %s",
		      current->comm, current->pid, smd_tty[n].smd->port_name);
	smd_disable_read_intr(info->ch);
	mutex_unlock(&smd_tty_lock);
	return 0;

close_ch:
	smd_close(info->ch);
	info->ch = NULL;

release_wl_tl:
	tasklet_kill(&info->tty_tsklt);
	wake_lock_destroy(&info->wake_lock);
	wake_lock_destroy(&info->ra_wake_lock);

release_pil:
	subsystem_put(info->pil);
out:
	mutex_unlock(&smd_tty_lock);

	return res;
}
示例#7
0
static int
wcnss_trigger_config(struct platform_device *pdev)
{
	int ret;
	struct qcom_wcnss_opts *pdata;
	unsigned long wcnss_phys_addr;
	int size = 0;
	struct resource *res;
	int has_pronto_hw = of_property_read_bool(pdev->dev.of_node,
									"qcom,has_pronto_hw");

	/* make sure we are only triggered once */
	if (penv->triggered)
		return 0;
	penv->triggered = 1;

	/* initialize the WCNSS device configuration */
	pdata = pdev->dev.platform_data;
	if (WCNSS_CONFIG_UNSPECIFIED == has_48mhz_xo) {
		if (has_pronto_hw) {
			has_48mhz_xo = of_property_read_bool(pdev->dev.of_node,
										"qcom,has_48mhz_xo");
		} else {
			has_48mhz_xo = pdata->has_48mhz_xo;
		}
	}
	penv->wcnss_hw_type = (has_pronto_hw) ? WCNSS_PRONTO_HW : WCNSS_RIVA_HW;
	penv->wlan_config.use_48mhz_xo = has_48mhz_xo;

	penv->thermal_mitigation = 0;
	strlcpy(penv->wcnss_version, "INVALID", WCNSS_VERSION_LEN);

	/* Configure 5 wire GPIOs */
	if (!has_pronto_hw) {
		penv->gpios_5wire = platform_get_resource_byname(pdev,
					IORESOURCE_IO, "wcnss_gpios_5wire");

		/* allocate 5-wire GPIO resources */
		if (!penv->gpios_5wire) {
			dev_err(&pdev->dev, "insufficient IO resources\n");
			ret = -ENOENT;
			goto fail_gpio_res;
		}
		ret = wcnss_gpios_config(penv->gpios_5wire, true);
	} else
		ret = wcnss_pronto_gpios_config(&pdev->dev, true);

	if (ret) {
		dev_err(&pdev->dev, "WCNSS gpios config failed.\n");
		goto fail_gpio_res;
	}

	/* power up the WCNSS */
	ret = wcnss_wlan_power(&pdev->dev, &penv->wlan_config,
					WCNSS_WLAN_SWITCH_ON);
	if (ret) {
		dev_err(&pdev->dev, "WCNSS Power-up failed.\n");
		goto fail_power;
	}

	/* trigger initialization of the WCNSS */
	penv->pil = subsystem_get(WCNSS_PIL_DEVICE);
	if (IS_ERR(penv->pil)) {
		dev_err(&pdev->dev, "Peripheral Loader failed on WCNSS.\n");
		ret = PTR_ERR(penv->pil);
		penv->pil = NULL;
		goto fail_pil;
	}

	/* allocate resources */
	penv->mmio_res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
							"wcnss_mmio");
	penv->tx_irq_res = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
							"wcnss_wlantx_irq");
	penv->rx_irq_res = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
							"wcnss_wlanrx_irq");

	if (!(penv->mmio_res && penv->tx_irq_res && penv->rx_irq_res)) {
		dev_err(&pdev->dev, "insufficient resources\n");
		ret = -ENOENT;
		goto fail_res;
	}
	INIT_WORK(&penv->wcnssctrl_rx_work, wcnssctrl_rx_handler);
	INIT_WORK(&penv->wcnssctrl_version_work, wcnss_send_version_req);
	INIT_WORK(&penv->wcnssctrl_nvbin_dnld_work, wcnss_nvbin_dnld_req);

	wake_lock_init(&penv->wcnss_wake_lock, WAKE_LOCK_SUSPEND, "wcnss");

	if (wcnss_hardware_type() == WCNSS_PRONTO_HW) {
		size = 0x3000;
		wcnss_phys_addr = MSM_PRONTO_PHYS;
	} else {
		wcnss_phys_addr = MSM_RIVA_PHYS;
		size = SZ_256;
	}

	penv->msm_wcnss_base = ioremap(wcnss_phys_addr, size);
	if (!penv->msm_wcnss_base) {
		ret = -ENOMEM;
		pr_err("%s: ioremap wcnss physical failed\n", __func__);
		goto fail_wake;
	}

	if (wcnss_hardware_type() == WCNSS_RIVA_HW) {
		penv->riva_ccu_base =  ioremap(MSM_RIVA_CCU_BASE, SZ_512);
		if (!penv->riva_ccu_base) {
			ret = -ENOMEM;
			pr_err("%s: ioremap wcnss physical failed\n", __func__);
			goto fail_ioremap;
		}
	} else {
		penv->pronto_a2xb_base =  ioremap(MSM_PRONTO_A2XB_BASE, SZ_512);
		if (!penv->pronto_a2xb_base) {
			ret = -ENOMEM;
			pr_err("%s: ioremap wcnss physical failed\n", __func__);
			goto fail_ioremap;
		}
		penv->pronto_ccpu_base =  ioremap(MSM_PRONTO_CCPU_BASE, SZ_512);
		if (!penv->pronto_ccpu_base) {
			ret = -ENOMEM;
			pr_err("%s: ioremap wcnss physical failed\n", __func__);
			goto fail_ioremap2;
		}
		/* for reset FIQ */
		res = platform_get_resource_byname(penv->pdev,
				IORESOURCE_MEM, "wcnss_fiq");
		if (!res) {
			dev_err(&pdev->dev, "insufficient irq mem resources\n");
			ret = -ENOENT;
			goto fail_ioremap3;
		}
		penv->fiq_reg = ioremap_nocache(res->start, resource_size(res));
		if (!penv->fiq_reg) {
			pr_err("wcnss: %s: ioremap_nocache() failed fiq_reg addr:%pr\n",
				__func__, &res->start);
			ret = -ENOMEM;
			goto fail_ioremap3;
		}
	}
	penv->cold_boot_done = 1;

	return 0;

fail_ioremap3:
	iounmap(penv->pronto_ccpu_base);
fail_ioremap2:
	iounmap(penv->pronto_a2xb_base);
fail_ioremap:
	iounmap(penv->msm_wcnss_base);
fail_wake:
	wake_lock_destroy(&penv->wcnss_wake_lock);
fail_res:
	if (penv->pil)
		subsystem_put(penv->pil);
fail_pil:
	wcnss_wlan_power(&pdev->dev, &penv->wlan_config,
				WCNSS_WLAN_SWITCH_OFF);
fail_power:
	if (has_pronto_hw)
		wcnss_pronto_gpios_config(&pdev->dev, false);
	else
		wcnss_gpios_config(penv->gpios_5wire, false);
fail_gpio_res:
	penv = NULL;
	return ret;
}