drivers/gpu/drm/tegra/output.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/tegra/output.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/tegra/output.c
Extension
.c
Size
6433 bytes
Lines
283
Domain
Driver Families
Bucket
drivers/gpu
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (!output->ddc) {
			err = -EPROBE_DEFER;
			return err;
		}
	}

	edid = of_get_property(output->of_node, "nvidia,edid", &size);
	output->drm_edid = drm_edid_alloc(edid, size);

	output->hpd_gpio = devm_fwnode_gpiod_get(output->dev,
					of_fwnode_handle(output->of_node),
					"nvidia,hpd",
					GPIOD_IN,
					"HDMI hotplug detect");
	if (IS_ERR(output->hpd_gpio)) {
		if (PTR_ERR(output->hpd_gpio) != -ENOENT) {
			err = PTR_ERR(output->hpd_gpio);
			goto put_i2c;
		}

		output->hpd_gpio = NULL;
	}

	if (output->hpd_gpio) {
		err = gpiod_to_irq(output->hpd_gpio);
		if (err < 0) {
			dev_err(output->dev, "gpiod_to_irq(): %d\n", err);
			goto put_i2c;
		}

		output->hpd_irq = err;

		flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
			IRQF_ONESHOT;

		err = request_threaded_irq(output->hpd_irq, NULL, hpd_irq,
					   flags, "hpd", output);
		if (err < 0) {
			dev_err(output->dev, "failed to request IRQ#%u: %d\n",
				output->hpd_irq, err);
			goto put_i2c;
		}

		output->connector.polled = DRM_CONNECTOR_POLL_HPD;

		/*
		 * Disable the interrupt until the connector has been
		 * initialized to avoid a race in the hotplug interrupt
		 * handler.
		 */
		disable_irq(output->hpd_irq);
	}

	return 0;

put_i2c:
	if (output->ddc)
		i2c_put_adapter(output->ddc);

	drm_edid_free(output->drm_edid);

	return err;
}

void tegra_output_remove(struct tegra_output *output)
{
	if (output->hpd_gpio)
		free_irq(output->hpd_irq, output);

	if (output->ddc)
		i2c_put_adapter(output->ddc);

	drm_edid_free(output->drm_edid);
}

int tegra_output_init(struct drm_device *drm, struct tegra_output *output)
{
	int connector_type;

	/*
	 * The connector is now registered and ready to receive hotplug events
	 * so the hotplug interrupt can be enabled.
	 */
	if (output->hpd_gpio)
		enable_irq(output->hpd_irq);

	connector_type = output->connector.connector_type;
	/*
	 * Create a CEC notifier for HDMI connector.
	 */

Annotation

Implementation Notes