static int ht16k33_fbdev_probe()

in ht16k33.c [584:665]


static int ht16k33_fbdev_probe(struct device *dev, struct ht16k33_priv *priv,
			       uint32_t brightness)
{
	struct ht16k33_fbdev *fbdev = &priv->fbdev;
	struct backlight_device *bl = NULL;
	int err;

	if (priv->led.dev) {
		err = ht16k33_brightness_set(priv, brightness);
		if (err)
			return err;
	} else {
		/* backwards compatibility with DT lacking an led subnode */
		struct backlight_properties bl_props;

		memset(&bl_props, 0, sizeof(struct backlight_properties));
		bl_props.type = BACKLIGHT_RAW;
		bl_props.max_brightness = MAX_BRIGHTNESS;

		bl = devm_backlight_device_register(dev, DRIVER_NAME"-bl", dev,
						    priv, &ht16k33_bl_ops,
						    &bl_props);
		if (IS_ERR(bl)) {
			dev_err(dev, "failed to register backlight\n");
			return PTR_ERR(bl);
		}

		bl->props.brightness = brightness;
		ht16k33_bl_update_status(bl);
	}

	/* Framebuffer (2 bytes per column) */
	BUILD_BUG_ON(PAGE_SIZE < HT16K33_FB_SIZE);
	fbdev->buffer = (unsigned char *) get_zeroed_page(GFP_KERNEL);
	if (!fbdev->buffer)
		return -ENOMEM;

	fbdev->cache = devm_kmalloc(dev, HT16K33_FB_SIZE, GFP_KERNEL);
	if (!fbdev->cache) {
		err = -ENOMEM;
		goto err_fbdev_buffer;
	}

	fbdev->info = framebuffer_alloc(0, dev);
	if (!fbdev->info) {
		err = -ENOMEM;
		goto err_fbdev_buffer;
	}

	err = device_property_read_u32(dev, "refresh-rate-hz",
				       &fbdev->refresh_rate);
	if (err) {
		dev_err(dev, "refresh rate not specified\n");
		goto err_fbdev_info;
	}
	fb_bl_default_curve(fbdev->info, 0, MIN_BRIGHTNESS, MAX_BRIGHTNESS);

	INIT_DELAYED_WORK(&priv->work, ht16k33_fb_update);
	fbdev->info->fbops = &ht16k33_fb_ops;
	fbdev->info->screen_base = (char __iomem *) fbdev->buffer;
	fbdev->info->screen_size = HT16K33_FB_SIZE;
	fbdev->info->fix = ht16k33_fb_fix;
	fbdev->info->var = ht16k33_fb_var;
	fbdev->info->bl_dev = bl;
	fbdev->info->pseudo_palette = NULL;
	fbdev->info->flags = FBINFO_FLAG_DEFAULT;
	fbdev->info->par = priv;

	err = register_framebuffer(fbdev->info);
	if (err)
		goto err_fbdev_info;

	ht16k33_fb_queue(priv);
	return 0;

err_fbdev_info:
	framebuffer_release(fbdev->info);
err_fbdev_buffer:
	free_page((unsigned long) fbdev->buffer);

	return err;
}