drm/gma500: Run DRM default client setup
Rework fbdev probing to support fbdev_probe in struct drm_driver and remove the old fb_probe callback. Provide an initializer macro for struct drm_driver that sets the callback according to the kernel configuration. Call drm_client_setup() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. v5: - select DRM_CLIENT_SELECTION Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Patrik Jakobsson <patrik.r.jakobsson@gmail.com> Acked-by: Javier Martinez Canillas <javierm@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-76-tzimmermann@suse.de
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
config DRM_GMA500
|
||||
tristate "Intel GMA500/600/3600/3650 KMS Framebuffer"
|
||||
depends on DRM && PCI && X86 && MMU
|
||||
select DRM_CLIENT_SELECTION
|
||||
select DRM_KMS_HELPER
|
||||
select FB_IOMEM_HELPERS if DRM_FBDEV_EMULATION
|
||||
select I2C
|
||||
|
||||
@@ -143,12 +143,15 @@ static const struct fb_ops psb_fbdev_fb_ops = {
|
||||
.fb_destroy = psb_fbdev_fb_destroy,
|
||||
};
|
||||
|
||||
static const struct drm_fb_helper_funcs psb_fbdev_fb_helper_funcs = {
|
||||
};
|
||||
|
||||
/*
|
||||
* struct drm_fb_helper_funcs
|
||||
* struct drm_driver
|
||||
*/
|
||||
|
||||
static int psb_fbdev_fb_probe(struct drm_fb_helper *fb_helper,
|
||||
struct drm_fb_helper_surface_size *sizes)
|
||||
int psb_fbdev_driver_fbdev_probe(struct drm_fb_helper *fb_helper,
|
||||
struct drm_fb_helper_surface_size *sizes)
|
||||
{
|
||||
struct drm_device *dev = fb_helper->dev;
|
||||
struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
|
||||
@@ -206,6 +209,7 @@ static int psb_fbdev_fb_probe(struct drm_fb_helper *fb_helper,
|
||||
goto err_drm_gem_object_put;
|
||||
}
|
||||
|
||||
fb_helper->funcs = &psb_fbdev_fb_helper_funcs;
|
||||
fb_helper->fb = fb;
|
||||
|
||||
info = drm_fb_helper_alloc_info(fb_helper);
|
||||
@@ -246,93 +250,3 @@ err_drm_gem_object_put:
|
||||
drm_gem_object_put(obj);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct drm_fb_helper_funcs psb_fbdev_fb_helper_funcs = {
|
||||
.fb_probe = psb_fbdev_fb_probe,
|
||||
};
|
||||
|
||||
/*
|
||||
* struct drm_client_funcs and setup code
|
||||
*/
|
||||
|
||||
static void psb_fbdev_client_unregister(struct drm_client_dev *client)
|
||||
{
|
||||
struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client);
|
||||
|
||||
if (fb_helper->info) {
|
||||
drm_fb_helper_unregister_info(fb_helper);
|
||||
} else {
|
||||
drm_fb_helper_unprepare(fb_helper);
|
||||
drm_client_release(&fb_helper->client);
|
||||
kfree(fb_helper);
|
||||
}
|
||||
}
|
||||
|
||||
static int psb_fbdev_client_restore(struct drm_client_dev *client)
|
||||
{
|
||||
drm_fb_helper_lastclose(client->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int psb_fbdev_client_hotplug(struct drm_client_dev *client)
|
||||
{
|
||||
struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client);
|
||||
struct drm_device *dev = client->dev;
|
||||
int ret;
|
||||
|
||||
if (dev->fb_helper)
|
||||
return drm_fb_helper_hotplug_event(dev->fb_helper);
|
||||
|
||||
ret = drm_fb_helper_init(dev, fb_helper);
|
||||
if (ret)
|
||||
goto err_drm_err;
|
||||
|
||||
if (!drm_drv_uses_atomic_modeset(dev))
|
||||
drm_helper_disable_unused_functions(dev);
|
||||
|
||||
ret = drm_fb_helper_initial_config(fb_helper);
|
||||
if (ret)
|
||||
goto err_drm_fb_helper_fini;
|
||||
|
||||
return 0;
|
||||
|
||||
err_drm_fb_helper_fini:
|
||||
drm_fb_helper_fini(fb_helper);
|
||||
err_drm_err:
|
||||
drm_err(dev, "Failed to setup gma500 fbdev emulation (ret=%d)\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct drm_client_funcs psb_fbdev_client_funcs = {
|
||||
.owner = THIS_MODULE,
|
||||
.unregister = psb_fbdev_client_unregister,
|
||||
.restore = psb_fbdev_client_restore,
|
||||
.hotplug = psb_fbdev_client_hotplug,
|
||||
};
|
||||
|
||||
void psb_fbdev_setup(struct drm_psb_private *dev_priv)
|
||||
{
|
||||
struct drm_device *dev = &dev_priv->dev;
|
||||
struct drm_fb_helper *fb_helper;
|
||||
int ret;
|
||||
|
||||
fb_helper = kzalloc(sizeof(*fb_helper), GFP_KERNEL);
|
||||
if (!fb_helper)
|
||||
return;
|
||||
drm_fb_helper_prepare(dev, fb_helper, 32, &psb_fbdev_fb_helper_funcs);
|
||||
|
||||
ret = drm_client_init(dev, &fb_helper->client, "fbdev-gma500", &psb_fbdev_client_funcs);
|
||||
if (ret) {
|
||||
drm_err(dev, "Failed to register client: %d\n", ret);
|
||||
goto err_drm_fb_helper_unprepare;
|
||||
}
|
||||
|
||||
drm_client_register(&fb_helper->client);
|
||||
|
||||
return;
|
||||
|
||||
err_drm_fb_helper_unprepare:
|
||||
drm_fb_helper_unprepare(fb_helper);
|
||||
kfree(fb_helper);
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <acpi/video.h>
|
||||
|
||||
#include <drm/drm.h>
|
||||
#include <drm/drm_client_setup.h>
|
||||
#include <drm/drm_drv.h>
|
||||
#include <drm/drm_file.h>
|
||||
#include <drm/drm_ioctl.h>
|
||||
@@ -475,7 +476,7 @@ static int psb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
psb_fbdev_setup(dev_priv);
|
||||
drm_client_setup(dev, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -506,6 +507,7 @@ static const struct drm_driver driver = {
|
||||
.num_ioctls = ARRAY_SIZE(psb_ioctls),
|
||||
|
||||
.dumb_create = psb_gem_dumb_create,
|
||||
PSB_FBDEV_DRIVER_OPS,
|
||||
.ioctls = psb_ioctls,
|
||||
.fops = &psb_gem_fops,
|
||||
.name = DRIVER_NAME,
|
||||
|
||||
@@ -184,6 +184,9 @@
|
||||
#define KSEL_BYPASS_25 6
|
||||
#define KSEL_BYPASS_83_100 7
|
||||
|
||||
struct drm_fb_helper;
|
||||
struct drm_fb_helper_surface_size;
|
||||
|
||||
struct opregion_header;
|
||||
struct opregion_acpi;
|
||||
struct opregion_swsci;
|
||||
@@ -597,10 +600,13 @@ struct drm_framebuffer *psb_framebuffer_create(struct drm_device *dev,
|
||||
|
||||
/* fbdev */
|
||||
#if defined(CONFIG_DRM_FBDEV_EMULATION)
|
||||
void psb_fbdev_setup(struct drm_psb_private *dev_priv);
|
||||
int psb_fbdev_driver_fbdev_probe(struct drm_fb_helper *fb_helper,
|
||||
struct drm_fb_helper_surface_size *sizes);
|
||||
#define PSB_FBDEV_DRIVER_OPS \
|
||||
.fbdev_probe = psb_fbdev_driver_fbdev_probe
|
||||
#else
|
||||
static inline void psb_fbdev_setup(struct drm_psb_private *dev_priv)
|
||||
{ }
|
||||
#define PSB_FBDEV_DRIVER_OPS \
|
||||
.fbdev_probe = NULL
|
||||
#endif
|
||||
|
||||
/* backlight.c */
|
||||
|
||||
Reference in New Issue
Block a user