Weston中的检测
drm_backend_create在创建时,会创建一个循环获取热拔插事件。
b->udev_drm_source =
wl_event_loop_add_fd(loop,
udev_monitor_get_fd(b->udev_monitor),
WL_EVENT_READABLE, udev_drm_event, b);
static int
udev_drm_event(int fd, uint32_t mask, void *data)
{
struct drm_backend *b = data;
struct udev_device *event;
uint32_t conn_id, prop_id;
event = udev_monitor_receive_device(b->udev_monitor);
if (udev_event_is_hotplug(b, event)) {
if (udev_event_is_conn_prop_change(b, event, &conn_id, &prop_id))
drm_backend_update_conn_props(b, conn_id, prop_id);
else
drm_backend_update_heads(b, event);
}
udev_device_unref(event);
return 1;
}
udev_device_get_property_value(device, "HOTPLUG")检测drm驱动中“HOTPLUG”属性的值,产生热拔插后,驱动层。
我们使用udevadm monitor --property命令来检测热拔插事件。
monitor will print the received events for:
UDEV - the event which udev sends out after rule processing
KERNEL - the kernel uevent
KERNEL[4940.661886] change /devices/platform/display-subsystem/drm/card1 (drm)
ACTION=change
DEVPATH=/devices/platform/display-subsystem/drm/card1
SUBSYSTEM=drm
HOTPLUG=1
DEVNAME=/dev/dri/card1
DEVTYPE=drm_minor
SEQNUM=4255
MAJOR=226
MINOR=1
Bridge驱动的检测
驱动层通过devm_request_threaded_irq来开辟一个中断检测线程,检测到irq后,需要通过drm_helper_hpd_irq_event和drm_bridge_hpd_notify函数才能将irq事件发送给drm设备。
第一步:drm_helper_hpd_irq_event
drm_helper_hpd_irq_event此时来修改connector的状态,然后drm_kms_helper_hotplug_event会在用户空间触发uevent事件。也就是刚才我们之前使用udevadm命令所看到uevent的信息。
第二步:drm_bridge_hpd_notify
drm_bridge_hpd_notify将drm_connector_status值传给bridge设备,通知bridge驱动来处理热拔插事件。