On Thu, Feb 23, 2023 at 1:17 PM Thomas Zimmermann <tzimmermann@xxxxxxx> 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@xxxxxxx> > --- > 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 >