示例#1
0
/**
 * drm_dp_cec_unregister_connector() - unregister the CEC adapter, if any
 * @aux: DisplayPort AUX channel
 */
void drm_dp_cec_unregister_connector(struct drm_dp_aux *aux)
{
	if (!aux->cec.adap)
		return;
	cancel_delayed_work_sync(&aux->cec.unregister_work);
	cec_unregister_adapter(aux->cec.adap);
	aux->cec.adap = NULL;
}
示例#2
0
文件: s5p_cec.c 项目: asmalldev/linux
static int s5p_cec_remove(struct platform_device *pdev)
{
	struct s5p_cec_dev *cec = platform_get_drvdata(pdev);

	cec_unregister_adapter(cec->adap);
	cec_notifier_put(cec->notifier);
	pm_runtime_disable(&pdev->dev);
	return 0;
}
示例#3
0
/*
 * Called if the HPD was low for more than drm_dp_cec_unregister_delay
 * seconds. This unregisters the CEC adapter.
 */
static void drm_dp_cec_unregister_work(struct work_struct *work)
{
	struct drm_dp_aux *aux = container_of(work, struct drm_dp_aux,
					      cec.unregister_work.work);

	mutex_lock(&aux->cec.lock);
	cec_unregister_adapter(aux->cec.adap);
	aux->cec.adap = NULL;
	mutex_unlock(&aux->cec.lock);
}
示例#4
0
static int tegra_cec_remove(struct platform_device *pdev)
{
	struct tegra_cec *cec = platform_get_drvdata(pdev);

	clk_disable_unprepare(cec->clk);

	cec_unregister_adapter(cec->adap);
	cec_notifier_put(cec->notifier);

	return 0;
}
示例#5
0
static void rain_disconnect(struct serio *serio)
{
	struct rain *rain = serio_get_drvdata(serio);

	cancel_work_sync(&rain->work);
	cec_unregister_adapter(rain->adap);
	dev_info(&serio->dev, "disconnected\n");
	serio_close(serio);
	serio_set_drvdata(serio, NULL);
	kfree(rain);
}
示例#6
0
static void sun4i_hdmi_unbind(struct device *dev, struct device *master,
			    void *data)
{
	struct sun4i_hdmi *hdmi = dev_get_drvdata(dev);

	cec_unregister_adapter(hdmi->cec_adap);
	drm_connector_cleanup(&hdmi->connector);
	drm_encoder_cleanup(&hdmi->encoder);
	i2c_del_adapter(hdmi->i2c);
	clk_disable_unprepare(hdmi->mod_clk);
	clk_disable_unprepare(hdmi->bus_clk);
}
示例#7
0
文件: ao-cec.c 项目: avagin/linux
static int meson_ao_cec_remove(struct platform_device *pdev)
{
	struct meson_ao_cec_device *ao_cec = platform_get_drvdata(pdev);

	clk_disable_unprepare(ao_cec->core);

	cec_unregister_adapter(ao_cec->adap);

	cec_notifier_put(ao_cec->notify);

	return 0;
}
示例#8
0
static int cros_ec_cec_remove(struct platform_device *pdev)
{
	struct cros_ec_cec *cros_ec_cec = platform_get_drvdata(pdev);
	struct device *dev = &pdev->dev;
	int ret;

	ret = blocking_notifier_chain_unregister(
			&cros_ec_cec->cros_ec->event_notifier,
			&cros_ec_cec->notifier);

	if (ret) {
		dev_err(dev, "failed to unregister notifier\n");
		return ret;
	}

	cec_unregister_adapter(cros_ec_cec->adap);

	if (cros_ec_cec->notify)
		cec_notifier_put(cros_ec_cec->notify);

	return 0;
}
示例#9
0
/*
 * A new EDID is set. If there is no CEC adapter, then create one. If
 * there was a CEC adapter, then check if the CEC adapter properties
 * were unchanged and just update the CEC physical address. Otherwise
 * unregister the old CEC adapter and create a new one.
 */
void drm_dp_cec_set_edid(struct drm_dp_aux *aux, const struct edid *edid)
{
	u32 cec_caps = CEC_CAP_DEFAULTS | CEC_CAP_NEEDS_HPD;
	unsigned int num_las = 1;
	u8 cap;

	/* No transfer function was set, so not a DP connector */
	if (!aux->transfer)
		return;

#ifndef CONFIG_MEDIA_CEC_RC
	/*
	 * CEC_CAP_RC is part of CEC_CAP_DEFAULTS, but it is stripped by
	 * cec_allocate_adapter() if CONFIG_MEDIA_CEC_RC is undefined.
	 *
	 * Do this here as well to ensure the tests against cec_caps are
	 * correct.
	 */
	cec_caps &= ~CEC_CAP_RC;
#endif
	cancel_delayed_work_sync(&aux->cec.unregister_work);

	mutex_lock(&aux->cec.lock);
	if (!drm_dp_cec_cap(aux, &cap)) {
		/* CEC is not supported, unregister any existing adapter */
		cec_unregister_adapter(aux->cec.adap);
		aux->cec.adap = NULL;
		goto unlock;
	}

	if (cap & DP_CEC_SNOOPING_CAPABLE)
		cec_caps |= CEC_CAP_MONITOR_ALL;
	if (cap & DP_CEC_MULTIPLE_LA_CAPABLE)
		num_las = CEC_MAX_LOG_ADDRS;

	if (aux->cec.adap) {
		if (aux->cec.adap->capabilities == cec_caps &&
		    aux->cec.adap->available_log_addrs == num_las) {
			/* Unchanged, so just set the phys addr */
			cec_s_phys_addr_from_edid(aux->cec.adap, edid);
			goto unlock;
		}
		/*
		 * The capabilities changed, so unregister the old
		 * adapter first.
		 */
		cec_unregister_adapter(aux->cec.adap);
	}

	/* Create a new adapter */
	aux->cec.adap = cec_allocate_adapter(&drm_dp_cec_adap_ops,
					     aux, aux->cec.name, cec_caps,
					     num_las);
	if (IS_ERR(aux->cec.adap)) {
		aux->cec.adap = NULL;
		goto unlock;
	}
	if (cec_register_adapter(aux->cec.adap, aux->cec.parent)) {
		cec_delete_adapter(aux->cec.adap);
		aux->cec.adap = NULL;
	} else {
		/*
		 * Update the phys addr for the new CEC adapter. When called
		 * from drm_dp_cec_register_connector() edid == NULL, so in
		 * that case the phys addr is just invalidated.
		 */
		cec_s_phys_addr_from_edid(aux->cec.adap, edid);
	}
unlock:
	mutex_unlock(&aux->cec.lock);
}