#include <drm/drm_plane_helper.h>
#include <linux/component.h>
+#include <linux/list.h>
#include <linux/reset.h>
#include "sun4i_backend.h"
if (!backend)
return -ENOMEM;
dev_set_drvdata(dev, backend);
- drv->backend = backend;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
regs = devm_ioremap_resource(dev, res);
}
}
+ list_add_tail(&backend->list, &drv->backend_list);
+
/* Reset the registers */
for (i = 0x800; i < 0x1000; i += 4)
regmap_write(backend->regs, i, 0);
{
struct sun4i_backend *backend = dev_get_drvdata(dev);
+ list_del(&backend->list);
+
if (of_device_is_compatible(dev->of_node,
"allwinner,sun8i-a33-display-backend"))
sun4i_backend_free_sat(dev);
#define _SUN4I_BACKEND_H_
#include <linux/clk.h>
+#include <linux/list.h>
#include <linux/regmap.h>
#include <linux/reset.h>
struct clk *sat_clk;
struct reset_control *sat_reset;
+
+ /* Backend list management */
+ struct list_head list;
};
void sun4i_backend_apply_color_correction(struct sun4i_backend *backend);
goto free_drm;
}
drm->dev_private = drv;
+ INIT_LIST_HEAD(&drv->backend_list);
+ INIT_LIST_HEAD(&drv->tcon_list);
ret = of_reserved_mem_device_init(dev);
if (ret && ret != -ENODEV) {
#define _SUN4I_DRV_H_
#include <linux/clk.h>
+#include <linux/list.h>
#include <linux/regmap.h>
struct sun4i_drv {
- struct sun4i_backend *backend;
- struct sun4i_tcon *tcon;
+ struct list_head backend_list;
+ struct list_head tcon_list;
struct drm_fbdev_cma *fbdev;
};
#include <linux/regmap.h>
#include <linux/reset.h>
+#include "sun4i_backend.h"
#include "sun4i_crtc.h"
#include "sun4i_dotclock.h"
#include "sun4i_drv.h"
{
struct drm_device *drm = data;
struct sun4i_drv *drv = drm->dev_private;
+ struct sun4i_backend *backend;
struct sun4i_tcon *tcon;
int ret;
+ /* Wait for a backend to be registered */
+ if (list_empty(&drv->backend_list))
+ return -EPROBE_DEFER;
+
tcon = devm_kzalloc(dev, sizeof(*tcon), GFP_KERNEL);
if (!tcon)
return -ENOMEM;
dev_set_drvdata(dev, tcon);
- drv->tcon = tcon;
tcon->drm = drm;
tcon->dev = dev;
tcon->quirks = of_device_get_match_data(dev);
goto err_free_dotclock;
}
- tcon->crtc = sun4i_crtc_init(drm, drv->backend, tcon);
+ backend = list_first_entry(&drv->backend_list,
+ struct sun4i_backend, list);
+ tcon->crtc = sun4i_crtc_init(drm, backend, tcon);
if (IS_ERR(tcon->crtc)) {
dev_err(dev, "Couldn't create our CRTC\n");
ret = PTR_ERR(tcon->crtc);
if (ret < 0)
goto err_free_clocks;
+ list_add_tail(&tcon->list, &drv->tcon_list);
+
return 0;
err_free_dotclock:
{
struct sun4i_tcon *tcon = dev_get_drvdata(dev);
+ list_del(&tcon->list);
sun4i_dclk_free(tcon);
sun4i_tcon_free_clocks(tcon);
}
#include <drm/drm_crtc.h>
#include <linux/kernel.h>
+#include <linux/list.h>
#include <linux/reset.h>
#define SUN4I_TCON_GCTL_REG 0x0
/* Associated crtc */
struct sun4i_crtc *crtc;
+
+ /* TCON list management */
+ struct list_head list;
};
struct drm_bridge *sun4i_tcon_find_bridge(struct device_node *node);