[PATCH] RFCv2: omapdrm DRM/KMS driver for TI OMAP platforms
Konrad Rzeszutek Wilk
konrad.wilk at oracle.com
Mon Sep 26 06:55:44 PDT 2011
> >> + commit(crtc);
> >
> > So no checking of its return value.. Should you at least wrap
> > it with WARN_ON(?)
>
> Is it safe to rely on the "payload" of the WARN_ON() always being
> evaluated, or is there any scenario that you could have something like
Hmm, good question. I assumed so, but you got me thinking.
>
> #define WARN_ON(X)
>
> ie., is this safe:
>
> WARN_ON(commit(crtc));
>
> it looked like different archs can provide their own WARN_ON, so
> wasn't sure how much to trust it..
>
>
> [snip]
>
> >> +static void page_flip_cb(void *arg)
> >> +{
> >> + struct drm_crtc *crtc = arg;
> >> + struct drm_device *dev = crtc->dev;
> >> + struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
> >> + struct drm_pending_vblank_event *event = omap_crtc->event;
> >> + struct timeval now;
> >> + unsigned long flags;
> >> +
> >> + WARN_ON(!event);
> >> +
> >> + omap_crtc->event = NULL;
> >> +
> >> + update_scanout(crtc);
> >> + commit(crtc);
> >> +
> >> + /* wakeup userspace */
> >> + // TODO: this should happen *after* flip.. somehow..
> >> + if (event) {
> >> + spin_lock_irqsave(&dev->event_lock, flags);
> >
> > So this can be called from an IRQ handler? Why the need to disable
> > the IRQs? Can you just use spin_lock?
>
> not currently.. OTOH, it should be moved somewhere that would be
> called from an IRQ..
Ok, so laying the ground work for it. That is OK - you might want to
mention that in the TODO just in case .
>
> >> + event->event.sequence =
> >> + drm_vblank_count_and_time(dev, omap_crtc->id, &now);
> >> + event->event.tv_sec = now.tv_sec;
> >> + event->event.tv_usec = now.tv_usec;
> >> + list_add_tail(&event->base.link,
> >> + &event->base.file_priv->event_list);
> >> + wake_up_interruptible(&event->base.file_priv->event_wait);
> >> + spin_unlock_irqrestore(&dev->event_lock, flags);
> >> + }
> >> +}
> >> +
>
> [snip]
>
> >> +
> >> +/* keep track of whether we are already loaded.. we may need to call
> >> + * plugin's load() if they register after we are already loaded
> >> + */
> >> +static bool loaded = false;
> >
> > Add __read_mostly.. You don't need to set false as by default it will
> > be 0 (false).
> >
> >> +
> >> +/*
> >> + * mode config funcs
> >> + */
> >> +
> >> +/* Notes about mapping DSS and DRM entities:
> >> + * CRTC: overlay
> >> + * encoder: manager.. with some extension to allow one primary CRTC
> >> + * and zero or more video CRTC's to be mapped to one encoder?
> >> + * connector: dssdev.. manager can be attached/detached from different
> >> + * devices
> >> + */
> >> +
> >> +static void omap_fb_output_poll_changed(struct drm_device *dev)
> >> +{
> >> + struct omap_drm_private *priv = dev->dev_private;
> >> + DBG("dev=%p", dev);
> >> + if (priv->fbdev) {
> >> + drm_fb_helper_hotplug_event(priv->fbdev);
> >> + }
> >> +}
> >> +
> >> +static struct drm_mode_config_funcs omap_mode_config_funcs = {
> >> + .fb_create = omap_framebuffer_create,
> >> + .output_poll_changed = omap_fb_output_poll_changed,
> >> +};
> >> +
> >> +static int get_connector_type(struct omap_dss_device *dssdev)
> >> +{
> >> + switch (dssdev->type) {
> >> + case OMAP_DISPLAY_TYPE_HDMI:
> >> + return DRM_MODE_CONNECTOR_HDMIA;
> >> + case OMAP_DISPLAY_TYPE_DPI:
> >> + if (!strcmp(dssdev->name, "dvi"))
> >
> > strncmp
>
> In this case, since one of the args is a string literal, I know it is
> properly terminated..
<nods>
> >
> > Should you check priv->num_encoders to be sure you are not
> > referencing past the priv->encoders size? Or if num_encoders is -1 then
> > hitting some other code and potentially causing a security hole.
> >
>
> currently the array size for crtc/encoder/connectors is ~2x the # of
> corresponding physical resources. But I guess it doesn't hurt to have
> some BUG_ON()'s..
Thank you.
.. snip..
> >> + /* if we couldn't find another connected connector, lets start
> >> + * looking at the unconnected connectors:
> >> + */
> >> + while (j < 2 * priv->num_connectors && !mgr) {
> >> + int idx = j - priv->num_connectors;
> >
> > You might want to use:
> > unsigned int idx = max(0, j - priv->num_connectors);
> >
> > jsut ot make sure you don't go negative.
>
> It can't (currently) happen, because you need to go all the way thru
> the first loop to enter the second loop. Although maybe that bit of
> code is a bit less than self-apparent.. but I hadn't thought of a way
> to simplify it.
A think expanding on the comment will suffice.
.. snip..
> >> + for (i = 0; i < pdata->mgr_cnt; i++) {
> >> + create_encoder(pdata->mgr_ids[i]);
> >
> > No check for return value? What if we get -ENOMEM?
>
> I'm a bit undecided on some of this error handling at startup.. I
> guess ENOMEM is clear enough. But some of the other parts, like
> connector initialization, could fail just because some hw is not
> present/populated. Like missing some LCD. I guess that it is best to
> try and limp along as best as possible and hope to get some pixels on
> some screen that the user can see. If you give up and all the
> screens/monitors/etc stay dark, it might be a bit inconvenient to
> debug..
Perhaps then just do WARN_ON, like:
if (create_encode(..))
WARN_ON(1,"Danger Danger! Limping along\n");
More information about the dri-devel
mailing list