[PATCH 7/7] drm/gma500: Pass fb_info to psb_fbdev_vm_fault()

Patrik Jakobsson patrik.r.jakobsson at gmail.com
Mon Mar 6 14:52:26 UTC 2023


On Thu, Feb 23, 2023 at 1:17 PM Thomas Zimmermann <tzimmermann at suse.de> wrote:
>
> Instead of the DRM framebuffer, pass the FB info strcuture to the
> fbdev page-fault handler psb_fbdev_vm_fault(). The framebuffer is a
> high-level data structure and does not belong into fault handling.
> The fb_info has all necessary information. Also set fix.smem_start
> to the correct value (the beginning of the framebuffer in physical
> address space) and streamline the page-fault handler.
>
> Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>
> ---
>  drivers/gpu/drm/gma500/fbdev.c | 39 ++++++++++++----------------------
>  1 file changed, 14 insertions(+), 25 deletions(-)
>
> diff --git a/drivers/gpu/drm/gma500/fbdev.c b/drivers/gpu/drm/gma500/fbdev.c
> index a70ca4c5013f..c8dbcb33ddb5 100644
> --- a/drivers/gpu/drm/gma500/fbdev.c
> +++ b/drivers/gpu/drm/gma500/fbdev.c
> @@ -22,32 +22,24 @@
>  static vm_fault_t psb_fbdev_vm_fault(struct vm_fault *vmf)
>  {
>         struct vm_area_struct *vma = vmf->vma;
> -       struct drm_framebuffer *fb = vma->vm_private_data;
> -       struct drm_device *dev = fb->dev;
> -       struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
> -       struct psb_gem_object *pobj = to_psb_gem_object(fb->obj[0]);
> -       int page_num;
> -       int i;
> -       unsigned long address;
> -       vm_fault_t ret = VM_FAULT_SIGBUS;
> -       unsigned long pfn;
> -       unsigned long phys_addr = (unsigned long)dev_priv->stolen_base + pobj->offset;
> -
> -       page_num = vma_pages(vma);
> -       address = vmf->address - (vmf->pgoff << PAGE_SHIFT);
> +       struct fb_info *info = vma->vm_private_data;
> +       unsigned long address = vmf->address - (vmf->pgoff << PAGE_SHIFT);
> +       unsigned long pfn = info->fix.smem_start >> PAGE_SHIFT;
> +       vm_fault_t err = VM_FAULT_SIGBUS;
> +       unsigned long page_num = vma_pages(vma);
> +       unsigned long i;
>
>         vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
>
> -       for (i = 0; i < page_num; i++) {
> -               pfn = (phys_addr >> PAGE_SHIFT);
> -
> -               ret = vmf_insert_mixed(vma, address, __pfn_to_pfn_t(pfn, PFN_DEV));
> -               if (unlikely(ret & VM_FAULT_ERROR))
> +       for (i = 0; i < page_num; ++i) {
> +               err = vmf_insert_mixed(vma, address, __pfn_to_pfn_t(pfn, PFN_DEV));
> +               if (unlikely(err & VM_FAULT_ERROR))
>                         break;
>                 address += PAGE_SIZE;
> -               phys_addr += PAGE_SIZE;
> +               ++pfn;
>         }
> -       return ret;
> +
> +       return err;
>  }
>
>  static const struct vm_operations_struct psb_fbdev_vm_ops = {
> @@ -102,9 +94,6 @@ static int psb_fbdev_fb_setcolreg(unsigned int regno,
>
>  static int psb_fbdev_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
>  {
> -       struct drm_fb_helper *fb_helper = info->par;
> -       struct drm_framebuffer *fb = fb_helper->fb;
> -
>         if (vma->vm_pgoff != 0)
>                 return -EINVAL;
>         if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
> @@ -116,7 +105,7 @@ static int psb_fbdev_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
>          * suitable for our mmap work
>          */
>         vma->vm_ops = &psb_fbdev_vm_ops;
> -       vma->vm_private_data = (void *)fb;
> +       vma->vm_private_data = info;
>         vma->vm_flags |= VM_IO | VM_MIXEDMAP | VM_DONTEXPAND | VM_DONTDUMP;
>
>         return 0;
> @@ -235,7 +224,7 @@ static int psbfb_probe(struct drm_fb_helper *fb_helper,
>
>         drm_fb_helper_fill_info(info, fb_helper, sizes);
>
> -       info->fix.smem_start = dev_priv->fb_base;
> +       info->fix.smem_start = dev_priv->stolen_base + backing->offset;

With this change, ->fb_base is no longer used and can be removed. We
already store PSB_BSM (base of stolen memory) in ->stolen_base so no
need to keep fb_base.


>         info->fix.smem_len = size;
>         info->fix.ywrapstep = 0;
>         info->fix.ypanstep = 0;
> --
> 2.39.2
>


More information about the dri-devel mailing list