summaryrefslogtreecommitdiffstats
path: root/drivers/video/fbdev/sunxvr1000.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2026-10-02 12:17:24 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2026-10-02 12:17:24 -0700
commit3f1fe48a36b0b6722dc3fd421d93512bac138e9a (patch)
treeb767d7f6e26bc64334d3f14f8422d187239dc45d /drivers/video/fbdev/sunxvr1000.c
downloadlinux-stable-3f1fe48a36b0b6722dc3fd421d93512bac138e9a.tar.gz
linux-stable-3f1fe48a36b0b6722dc3fd421d93512bac138e9a.zip
Merge tag 'io_uring-7.3-20261002' of git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linuxgrafted
Pull io_uring fixes from Jens Axboe: - Fix a task_work add use-after-free with SQPOLL. The sqpoll thread could pop and complete the last request while io_req_normal_work_add() was still looking at them after the mpscq push. Use the same approach as DEFER_TASKRUN to protect from that, holding an RCU read lock across the add, and have exit wait for an RCU grace period for SQPOLL rings as well. - CQE32 ring fixes: correct the free entry check for 32b CQEs, zero the big_cqe for aux CQEs, and only post the dummy skip CQE on CQE_MIXED rings - Mark the source filter table as COW when cloning bpf filters, so registering another filter on the source doesn't modify the shared table in place - Initialize the task context before running the BPF loop - Requeue zcrx multishot receives stopped by a local resource - End a TX_TIMESTAMP multishot cmd when the CQ is full (lollipopkit) * tag 'io_uring-7.3-20261002' of git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux: io_uring: fix task_work add use-after-free with SQPOLL io_uring/cmd_net: end TX_TIMESTAMP multishot when the CQ is full io_uring/zcrx: requeue multishot receives stopped by a local resource io_uring: initialize task context before running the BPF loop io_uring: zero big_cqe for aux CQEs on CQE32 rings io_uring: fix free entry check for 32b CQEs on CQE32 rings io_uring: only post the dummy skip CQE on CQE_MIXED rings io_uring/bpf_filter: mark source as COW when cloning filters
Diffstat (limited to 'drivers/video/fbdev/sunxvr1000.c')
-rw-r--r--drivers/video/fbdev/sunxvr1000.c197
1 files changed, 197 insertions, 0 deletions
diff --git a/drivers/video/fbdev/sunxvr1000.c b/drivers/video/fbdev/sunxvr1000.c
new file mode 100644
index 000000000..a93b06614
--- /dev/null
+++ b/drivers/video/fbdev/sunxvr1000.c
@@ -0,0 +1,197 @@
+/* sunxvr1000.c: Sun XVR-1000 fb driver for sparc64 systems
+ *
+ * License: GPL
+ *
+ * Copyright (C) 2010 David S. Miller (davem@davemloft.net)
+ */
+
+#include <linux/kernel.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+
+struct gfb_info {
+ struct fb_info *info;
+
+ char __iomem *fb_base;
+ unsigned long fb_base_phys;
+
+ struct device_node *of_node;
+
+ unsigned int width;
+ unsigned int height;
+ unsigned int depth;
+ unsigned int fb_size;
+
+ u32 pseudo_palette[16];
+};
+
+static int gfb_get_props(struct gfb_info *gp)
+{
+ gp->width = of_getintprop_default(gp->of_node, "width", 0);
+ gp->height = of_getintprop_default(gp->of_node, "height", 0);
+ gp->depth = of_getintprop_default(gp->of_node, "depth", 32);
+
+ if (!gp->width || !gp->height) {
+ printk(KERN_ERR "gfb: Critical properties missing for %pOF\n",
+ gp->of_node);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int gfb_setcolreg(unsigned regno,
+ unsigned red, unsigned green, unsigned blue,
+ unsigned transp, struct fb_info *info)
+{
+ u32 value;
+
+ if (regno < 16) {
+ red >>= 8;
+ green >>= 8;
+ blue >>= 8;
+
+ value = (blue << 16) | (green << 8) | red;
+ ((u32 *)info->pseudo_palette)[regno] = value;
+ }
+
+ return 0;
+}
+
+static const struct fb_ops gfb_ops = {
+ .owner = THIS_MODULE,
+ FB_DEFAULT_IOMEM_OPS,
+ .fb_setcolreg = gfb_setcolreg,
+};
+
+static int gfb_set_fbinfo(struct gfb_info *gp)
+{
+ struct fb_info *info = gp->info;
+ struct fb_var_screeninfo *var = &info->var;
+
+ info->fbops = &gfb_ops;
+ info->screen_base = gp->fb_base;
+ info->screen_size = gp->fb_size;
+
+ info->pseudo_palette = gp->pseudo_palette;
+
+ /* Fill fix common fields */
+ strscpy(info->fix.id, "gfb", sizeof(info->fix.id));
+ info->fix.smem_start = gp->fb_base_phys;
+ info->fix.smem_len = gp->fb_size;
+ info->fix.type = FB_TYPE_PACKED_PIXELS;
+ if (gp->depth == 32 || gp->depth == 24)
+ info->fix.visual = FB_VISUAL_TRUECOLOR;
+ else
+ info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
+
+ var->xres = gp->width;
+ var->yres = gp->height;
+ var->xres_virtual = var->xres;
+ var->yres_virtual = var->yres;
+ var->bits_per_pixel = gp->depth;
+
+ var->red.offset = 0;
+ var->red.length = 8;
+ var->green.offset = 8;
+ var->green.length = 8;
+ var->blue.offset = 16;
+ var->blue.length = 8;
+ var->transp.offset = 0;
+ var->transp.length = 0;
+
+ if (fb_alloc_cmap(&info->cmap, 256, 0)) {
+ printk(KERN_ERR "gfb: Cannot allocate color map.\n");
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+static int gfb_probe(struct platform_device *op)
+{
+ struct device_node *dp = op->dev.of_node;
+ struct fb_info *info;
+ struct gfb_info *gp;
+ int err;
+
+ info = framebuffer_alloc(sizeof(struct gfb_info), &op->dev);
+ if (!info) {
+ err = -ENOMEM;
+ goto err_out;
+ }
+
+ gp = info->par;
+ gp->info = info;
+ gp->of_node = dp;
+
+ gp->fb_base_phys = op->resource[6].start;
+
+ err = gfb_get_props(gp);
+ if (err)
+ goto err_release_fb;
+
+ /* Framebuffer length is the same regardless of resolution. */
+ info->fix.line_length = 16384;
+ gp->fb_size = info->fix.line_length * gp->height;
+
+ gp->fb_base = of_ioremap(&op->resource[6], 0,
+ gp->fb_size, "gfb fb");
+ if (!gp->fb_base) {
+ err = -ENOMEM;
+ goto err_release_fb;
+ }
+
+ err = gfb_set_fbinfo(gp);
+ if (err)
+ goto err_unmap_fb;
+
+ printk("gfb: Found device at %pOF\n", dp);
+
+ err = register_framebuffer(info);
+ if (err < 0) {
+ printk(KERN_ERR "gfb: Could not register framebuffer %pOF\n",
+ dp);
+ goto err_unmap_fb;
+ }
+
+ dev_set_drvdata(&op->dev, info);
+
+ return 0;
+
+err_unmap_fb:
+ of_iounmap(&op->resource[6], gp->fb_base, gp->fb_size);
+
+err_release_fb:
+ framebuffer_release(info);
+
+err_out:
+ return err;
+}
+
+static const struct of_device_id gfb_match[] = {
+ {
+ .name = "SUNW,gfb",
+ },
+ {},
+};
+
+static struct platform_driver gfb_driver = {
+ .probe = gfb_probe,
+ .driver = {
+ .name = "gfb",
+ .of_match_table = gfb_match,
+ .suppress_bind_attrs = true,
+ },
+};
+
+static int __init gfb_init(void)
+{
+ if (fb_get_options("gfb", NULL))
+ return -ENODEV;
+
+ return platform_driver_register(&gfb_driver);
+}
+device_initcall(gfb_init);