예제 #1
0
static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
	const struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data);
	const struct iwl_cfg *cfg_7265d __maybe_unused = NULL;
	struct iwl_trans *iwl_trans;
	struct iwl_trans_pcie *trans_pcie;
	int ret;

	iwl_trans = iwl_trans_pcie_alloc(pdev, ent, cfg);
	if (IS_ERR(iwl_trans))
		return PTR_ERR(iwl_trans);

#if IS_ENABLED(CONFIG_IWLMVM)
	/*
	 * special-case 7265D, it has the same PCI IDs.
	 *
	 * Note that because we already pass the cfg to the transport above,
	 * all the parameters that the transport uses must, until that is
	 * changed, be identical to the ones in the 7265D configuration.
	 */
	if (cfg == &iwl7265_2ac_cfg)
		cfg_7265d = &iwl7265d_2ac_cfg;
	else if (cfg == &iwl7265_2n_cfg)
		cfg_7265d = &iwl7265d_2n_cfg;
	else if (cfg == &iwl7265_n_cfg)
		cfg_7265d = &iwl7265d_n_cfg;
	if (cfg_7265d &&
	    (iwl_trans->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_7265D) {
		cfg = cfg_7265d;
		iwl_trans->cfg = cfg_7265d;
	}
#endif

	pci_set_drvdata(pdev, iwl_trans);

	trans_pcie = IWL_TRANS_GET_PCIE_TRANS(iwl_trans);
	trans_pcie->drv = iwl_drv_start(iwl_trans, cfg);

	if (IS_ERR(trans_pcie->drv)) {
		ret = PTR_ERR(trans_pcie->drv);
		goto out_free_trans;
	}

	set_dflt_pwr_limit(iwl_trans, pdev);

	/* register transport layer debugfs here */
	ret = iwl_trans_dbgfs_register(iwl_trans, iwl_trans->dbgfs_dir);
	if (ret)
		goto out_free_drv;

	return 0;

out_free_drv:
	iwl_drv_stop(trans_pcie->drv);
out_free_trans:
	iwl_trans_pcie_free(iwl_trans);
	return ret;
}
예제 #2
0
static void iwl_pci_remove(struct pci_dev *pdev)
{
	struct iwl_trans *trans = pci_get_drvdata(pdev);
	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);

	iwl_drv_stop(trans_pcie->drv);
	iwl_trans_pcie_free(trans);

	pci_set_drvdata(pdev, NULL);
}
예제 #3
0
파일: drv.c 프로젝트: acton393/linux
static void iwl_pci_remove(struct pci_dev *pdev)
{
	struct iwl_trans *trans = pci_get_drvdata(pdev);

	/* if RTPM was in use, restore it to the state before probe */
	if (trans->runtime_pm_mode != IWL_PLAT_PM_MODE_DISABLED) {
		/* We should not call forbid here, but we do for now.
		 * Check the comment to pm_runtime_allow() in
		 * iwl_pci_probe().
		 */
		pm_runtime_forbid(trans->dev);
	}

	iwl_drv_stop(trans->drv);

	iwl_trans_pcie_free(trans);
}
예제 #4
0
파일: drv.c 프로젝트: houlixin/BBB-TISDK
static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
	const struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data);
	struct iwl_trans *iwl_trans;
	struct iwl_trans_pcie *trans_pcie;
	int ret;

	iwl_trans = iwl_trans_pcie_alloc(pdev, ent, cfg);
	if (IS_ERR(iwl_trans))
		return PTR_ERR(iwl_trans);

	pci_set_drvdata(pdev, iwl_trans);

	trans_pcie = IWL_TRANS_GET_PCIE_TRANS(iwl_trans);
	trans_pcie->drv = iwl_drv_start(iwl_trans, cfg);

	if (IS_ERR(trans_pcie->drv)) {
		ret = PTR_ERR(trans_pcie->drv);
		goto out_free_trans;
	}

	set_dflt_pwr_limit(iwl_trans, pdev);

	/* register transport layer debugfs here */
	ret = iwl_trans_dbgfs_register(iwl_trans, iwl_trans->dbgfs_dir);
	if (ret)
		goto out_free_drv;

	return 0;

out_free_drv:
	iwl_drv_stop(trans_pcie->drv);
out_free_trans:
	iwl_trans_pcie_free(iwl_trans);
	return ret;
}
예제 #5
0
static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
	const struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data);
	struct iwl_trans *iwl_trans;
	struct iwl_trans_pcie *trans_pcie;

	iwl_trans = iwl_trans_pcie_alloc(pdev, ent, cfg);
	if (iwl_trans == NULL)
		return -ENOMEM;

	pci_set_drvdata(pdev, iwl_trans);

	trans_pcie = IWL_TRANS_GET_PCIE_TRANS(iwl_trans);
	trans_pcie->drv = iwl_drv_start(iwl_trans, cfg);
	if (!trans_pcie->drv)
		goto out_free_trans;

	return 0;

out_free_trans:
	iwl_trans_pcie_free(iwl_trans);
	pci_set_drvdata(pdev, NULL);
	return -EFAULT;
}
예제 #6
0
파일: drv.c 프로젝트: acton393/linux
static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
	const struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data);
	const struct iwl_cfg *cfg_7265d __maybe_unused = NULL;
	struct iwl_trans *iwl_trans;
	int ret;

	iwl_trans = iwl_trans_pcie_alloc(pdev, ent, cfg);
	if (IS_ERR(iwl_trans))
		return PTR_ERR(iwl_trans);

#if IS_ENABLED(CONFIG_IWLMVM)
	/*
	 * special-case 7265D, it has the same PCI IDs.
	 *
	 * Note that because we already pass the cfg to the transport above,
	 * all the parameters that the transport uses must, until that is
	 * changed, be identical to the ones in the 7265D configuration.
	 */
	if (cfg == &iwl7265_2ac_cfg)
		cfg_7265d = &iwl7265d_2ac_cfg;
	else if (cfg == &iwl7265_2n_cfg)
		cfg_7265d = &iwl7265d_2n_cfg;
	else if (cfg == &iwl7265_n_cfg)
		cfg_7265d = &iwl7265d_n_cfg;
	if (cfg_7265d &&
	    (iwl_trans->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_7265D) {
		cfg = cfg_7265d;
		iwl_trans->cfg = cfg_7265d;
	}

	if (iwl_trans->cfg->rf_id) {
		if (cfg == &iwl9460_2ac_cfg &&
		    iwl_trans->hw_rf_id == CSR_HW_RF_ID_TYPE_LC) {
			cfg = &iwl9000lc_2ac_cfg;
			iwl_trans->cfg = cfg;
		}
	}
#endif

	pci_set_drvdata(pdev, iwl_trans);
	iwl_trans->drv = iwl_drv_start(iwl_trans, cfg);

	if (IS_ERR(iwl_trans->drv)) {
		ret = PTR_ERR(iwl_trans->drv);
		goto out_free_trans;
	}

	set_dflt_pwr_limit(iwl_trans, pdev);

	/* register transport layer debugfs here */
	ret = iwl_trans_pcie_dbgfs_register(iwl_trans);
	if (ret)
		goto out_free_drv;

	/* if RTPM is in use, enable it in our device */
	if (iwl_trans->runtime_pm_mode != IWL_PLAT_PM_MODE_DISABLED) {
		/* We explicitly set the device to active here to
		 * clear contingent errors.
		 */
		pm_runtime_set_active(&pdev->dev);

		pm_runtime_set_autosuspend_delay(&pdev->dev,
					 iwlwifi_mod_params.d0i3_entry_delay);
		pm_runtime_use_autosuspend(&pdev->dev);

		/* We are not supposed to call pm_runtime_allow() by
		 * ourselves, but let userspace enable runtime PM via
		 * sysfs.  However, since we don't enable this from
		 * userspace yet, we need to allow/forbid() ourselves.
		*/
		pm_runtime_allow(&pdev->dev);
	}

	/* The PCI device starts with a reference taken and we are
	 * supposed to release it here.  But to simplify the
	 * interaction with the opmode, we don't do it now, but let
	 * the opmode release it when it's ready.
	 */

	return 0;

out_free_drv:
	iwl_drv_stop(iwl_trans->drv);
out_free_trans:
	iwl_trans_pcie_free(iwl_trans);
	return ret;
}