Back to 5.16.2

This commit is contained in:
Gerben Jan Dijkman 2022-01-29 21:14:53 +01:00
parent bc7f717547
commit 620e3bc7ea
20 changed files with 3 additions and 2749 deletions

View File

@ -1,3 +1,3 @@
DIST genpatches-5.16-4.base.tar.xz 343472 BLAKE2B a16d00c129a7833942fed29cfb7e41e7b9997c2dce1f23ec76b5598955e6f976ccbd03e7e0537d2944948bf8e0b726e85e67e01d5134791122807a6f86d25af7 SHA512 7f8f05d86f634d642fc1dad6959194feea671722455153ee19b68eb6b2dcf5cb282952611167e21867c1212d221b6554aeca3e6790ed3075709e8e1b2f6ed9fd DIST genpatches-5.16-3.base.tar.xz 27568 BLAKE2B 506c36ca597adde1cff11c4a83f1da3dfdc5ec692b932d07fd1e3145291b9f0007ea7fc86c9706ff8b609890b57aa46c224f05c2c3ba3212930bba04b2856d12 SHA512 c740ca5a6820acc94d7aacd03414ce7a9095c6924a3168865dfced1a8eeed3a22039ed5a449571888f16636fc274d6d680748cd919899782bdf02a5460f17823
DIST genpatches-5.16-4.extras.tar.xz 3780 BLAKE2B ae55d08dc691cf959804443f4c2fb06ee2d4816d95ed970106fa486ae44b88a81d6620156f9317c48506ffedde9b786df088fd3e590d5cdb7d2db0c8bfb2b3b1 SHA512 b262c03407d2647da4b00b0fd7888568ca1364b1ad36c79b01a7baa927ce41ee60f564c42b152ad1222fa52aeb085bbfd092b6b7722ca31ba5132d97a8ec08b5 DIST genpatches-5.16-3.extras.tar.xz 3780 BLAKE2B 4a4a4c50a4f76363f5701e9166470cca41bc5f34d0f9798eb68cf930d8b9799303553dd127dcd8bc73ba5c4784cf71dcf0c27e77ca146ef9645bc1a0044920cc SHA512 afcb6de6a98390b848708d1b22ea3d8e2f45ad7ed85d64be1f64618b65ca3a21e9011d8a9fb03d83f4630b95bd616507c8c12afcfe1841d032eea7d195ddfcd0
DIST linux-5.16.tar.xz 123114100 BLAKE2B 07a90cc640ff89e1359c06cee8c38abd33e51f9b9a89833e31a1d2750526fda4a59e8884db3c1ea63df0a37f0d3de6b5a922b014b7313d8abce20d90ac08adcb SHA512 7a257dd576bc8493595ec7d6f3c9cb6e22c772a8b2dbe735d2485c4f5c56e26a08695546e7e0f1f1cd04a533f25e829361958d4da0b98bf0ba8094dd57a85aaf DIST linux-5.16.tar.xz 123114100 BLAKE2B 07a90cc640ff89e1359c06cee8c38abd33e51f9b9a89833e31a1d2750526fda4a59e8884db3c1ea63df0a37f0d3de6b5a922b014b7313d8abce20d90ac08adcb SHA512 7a257dd576bc8493595ec7d6f3c9cb6e22c772a8b2dbe735d2485c4f5c56e26a08695546e7e0f1f1cd04a533f25e829361958d4da0b98bf0ba8094dd57a85aaf

View File

@ -1,24 +0,0 @@
From 22008251d617054271a65f29178e2df74dd3e33c Mon Sep 17 00:00:00 2001
From: Bhushan Shah <bshah@kde.org>
Date: Fri, 9 Apr 2021 16:22:49 +0530
Subject: [PATCH 1/5] drivers/usb: add reset_resume callback
---
drivers/usb/serial/option.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index c6969ca728390..21aeb7dc8f6ee 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -2105,6 +2105,7 @@ static struct usb_serial_driver option_1port_device = {
#ifdef CONFIG_PM
.suspend = usb_wwan_suspend,
.resume = usb_wwan_resume,
+ .reset_resume = usb_wwan_resume,
#endif
};
--
2.31.1

View File

@ -1,28 +0,0 @@
From 9d662fb865ae496a7eb51d2bdddefd2427d9a30e Mon Sep 17 00:00:00 2001
From: Bhushan Shah <bshah@kde.org>
Date: Fri, 9 Apr 2021 16:25:25 +0530
Subject: [PATCH 2/5] Revert "usb: quirks: Add USB_QUIRK_RESET for Quectel
EG25G Modem"
Reverts 8cc2a406ecc711f5
---
drivers/usb/core/quirks.c | 3 ---
1 file changed, 3 deletions(-)
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
index cb556617aa34f..6ade3daf78584 100644
--- a/drivers/usb/core/quirks.c
+++ b/drivers/usb/core/quirks.c
@@ -501,9 +501,6 @@ static const struct usb_device_id usb_quirk_list[] = {
/* INTEL VALUE SSD */
{ USB_DEVICE(0x8086, 0xf1a5), .driver_info = USB_QUIRK_RESET_RESUME },
- /* Quectel EG25G Modem */
- { USB_DEVICE(0x2c7c, 0x0125), .driver_info = USB_QUIRK_RESET },
-
{ } /* terminating entry must be last */
};
--
2.31.1

View File

@ -1,150 +0,0 @@
--- b/drivers/video/fbdev/core/bitblit.c
+++ a/drivers/video/fbdev/core/bitblit.c
@@ -234,7 +234,7 @@
}
static void bit_cursor(struct vc_data *vc, struct fb_info *info, int mode,
+ int softback_lines, int fg, int bg)
- int fg, int bg)
{
struct fb_cursor cursor;
struct fbcon_ops *ops = info->fbcon_par;
@@ -247,6 +247,15 @@
cursor.set = 0;
+ if (softback_lines) {
+ if (y + softback_lines >= vc->vc_rows) {
+ mode = CM_ERASE;
+ ops->cursor_flash = 0;
+ return;
+ } else
+ y += softback_lines;
+ }
+
c = scr_readw((u16 *) vc->vc_pos);
attribute = get_attribute(info, c);
src = vc->vc_font.data + ((c & charmask) * (w * vc->vc_font.height));
--- b/drivers/video/fbdev/core/fbcon.c
+++ a/drivers/video/fbdev/core/fbcon.c
@@ -394,7 +394,7 @@
c = scr_readw((u16 *) vc->vc_pos);
mode = (!ops->cursor_flash || ops->cursor_state.enable) ?
CM_ERASE : CM_DRAW;
+ ops->cursor(vc, info, mode, 0, get_color(vc, info, c, 1),
- ops->cursor(vc, info, mode, get_color(vc, info, c, 1),
get_color(vc, info, c, 0));
console_unlock();
}
@@ -1345,7 +1345,7 @@
ops->cursor_flash = (mode == CM_ERASE) ? 0 : 1;
+ ops->cursor(vc, info, mode, 0, get_color(vc, info, c, 1),
- ops->cursor(vc, info, mode, get_color(vc, info, c, 1),
get_color(vc, info, c, 0));
}
--- b/drivers/video/fbdev/core/fbcon.h
+++ a/drivers/video/fbdev/core/fbcon.h
@@ -62,7 +62,7 @@
void (*clear_margins)(struct vc_data *vc, struct fb_info *info,
int color, int bottom_only);
void (*cursor)(struct vc_data *vc, struct fb_info *info, int mode,
+ int softback_lines, int fg, int bg);
- int fg, int bg);
int (*update_start)(struct fb_info *info);
int (*rotate_font)(struct fb_info *info, struct vc_data *vc);
struct fb_var_screeninfo var; /* copy of the current fb_var_screeninfo */
--- b/drivers/video/fbdev/core/fbcon_ccw.c
+++ a/drivers/video/fbdev/core/fbcon_ccw.c
@@ -219,7 +219,7 @@
}
static void ccw_cursor(struct vc_data *vc, struct fb_info *info, int mode,
+ int softback_lines, int fg, int bg)
- int fg, int bg)
{
struct fb_cursor cursor;
struct fbcon_ops *ops = info->fbcon_par;
@@ -236,6 +236,15 @@
cursor.set = 0;
+ if (softback_lines) {
+ if (y + softback_lines >= vc->vc_rows) {
+ mode = CM_ERASE;
+ ops->cursor_flash = 0;
+ return;
+ } else
+ y += softback_lines;
+ }
+
c = scr_readw((u16 *) vc->vc_pos);
attribute = get_attribute(info, c);
src = ops->fontbuffer + ((c & charmask) * (w * vc->vc_font.width));
--- b/drivers/video/fbdev/core/fbcon_cw.c
+++ a/drivers/video/fbdev/core/fbcon_cw.c
@@ -202,7 +202,7 @@
}
static void cw_cursor(struct vc_data *vc, struct fb_info *info, int mode,
+ int softback_lines, int fg, int bg)
- int fg, int bg)
{
struct fb_cursor cursor;
struct fbcon_ops *ops = info->fbcon_par;
@@ -219,6 +219,15 @@
cursor.set = 0;
+ if (softback_lines) {
+ if (y + softback_lines >= vc->vc_rows) {
+ mode = CM_ERASE;
+ ops->cursor_flash = 0;
+ return;
+ } else
+ y += softback_lines;
+ }
+
c = scr_readw((u16 *) vc->vc_pos);
attribute = get_attribute(info, c);
src = ops->fontbuffer + ((c & charmask) * (w * vc->vc_font.width));
--- b/drivers/video/fbdev/core/fbcon_ud.c
+++ a/drivers/video/fbdev/core/fbcon_ud.c
@@ -249,7 +249,7 @@
}
static void ud_cursor(struct vc_data *vc, struct fb_info *info, int mode,
+ int softback_lines, int fg, int bg)
- int fg, int bg)
{
struct fb_cursor cursor;
struct fbcon_ops *ops = info->fbcon_par;
@@ -267,6 +267,15 @@
cursor.set = 0;
+ if (softback_lines) {
+ if (y + softback_lines >= vc->vc_rows) {
+ mode = CM_ERASE;
+ ops->cursor_flash = 0;
+ return;
+ } else
+ y += softback_lines;
+ }
+
c = scr_readw((u16 *) vc->vc_pos);
attribute = get_attribute(info, c);
src = ops->fontbuffer + ((c & charmask) * (w * vc->vc_font.height));
--- b/drivers/video/fbdev/core/tileblit.c
+++ a/drivers/video/fbdev/core/tileblit.c
@@ -80,7 +80,7 @@
}
static void tile_cursor(struct vc_data *vc, struct fb_info *info, int mode,
+ int softback_lines, int fg, int bg)
- int fg, int bg)
{
struct fb_tilecursor cursor;
int use_sw = (vc->vc_cursor_type & 0x10);

View File

@ -1,51 +0,0 @@
From 562a6c114ce736db51e41b8c06c408104b79b126 Mon Sep 17 00:00:00 2001
From: Bhushan Shah <bshah@kde.org>
Date: Wed, 14 Apr 2021 10:29:39 +0530
Subject: [PATCH 3/5] qmi_wwan: provide wrapper for reset_resume
---
drivers/net/usb/qmi_wwan.c | 21 ++++++++++++++++++++-
1 file changed, 20 insertions(+), 1 deletion(-)
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
index e18ded349d840..cd6ae9696b56a 100644
--- a/drivers/net/usb/qmi_wwan.c
+++ b/drivers/net/usb/qmi_wwan.c
@@ -840,6 +840,25 @@ static int qmi_wwan_resume(struct usb_interface *intf)
return ret;
}
+static int qmi_wwan_reset_resume(struct usb_interface *intf)
+{
+ struct usbnet *dev = usb_get_intfdata(intf);
+ struct qmi_wwan_state *info = (void *)&dev->data;
+ int ret = 0;
+ bool callsub = (intf == info->control && info->subdriver &&
+ info->subdriver->reset_resume);
+
+ if (callsub)
+ ret = info->subdriver->reset_resume(intf);
+ if (ret < 0)
+ goto err;
+ ret = usbnet_resume(intf);
+ if (ret < 0 && callsub)
+ info->subdriver->suspend(intf, PMSG_SUSPEND);
+err:
+ return ret;
+}
+
static const struct driver_info qmi_wwan_info = {
.description = "WWAN/QMI device",
.flags = FLAG_WWAN | FLAG_SEND_ZLP,
@@ -1478,7 +1497,7 @@ static struct usb_driver qmi_wwan_driver = {
.disconnect = qmi_wwan_disconnect,
.suspend = qmi_wwan_suspend,
.resume = qmi_wwan_resume,
- .reset_resume = qmi_wwan_resume,
+ .reset_resume = qmi_wwan_reset_resume,
.supports_autosuspend = 1,
.disable_hub_initiated_lpm = 1,
};
--
2.31.1

View File

@ -1,31 +0,0 @@
--- b/drivers/video/fbdev/core/fbcon.c
+++ a/drivers/video/fbdev/core/fbcon.c
@@ -163,6 +163,8 @@
#define advance_row(p, delta) (unsigned short *)((unsigned long)(p) + (delta) * vc->vc_size_row)
+static int fbcon_set_origin(struct vc_data *);
+
static int fbcon_cursor_noblink;
#define divides(a, b) ((!(a) || (b)%(a)) ? 0 : 1)
@@ -2633,6 +2635,11 @@
}
}
+static int fbcon_set_origin(struct vc_data *vc)
+{
+ return 0;
+}
+
void fbcon_suspended(struct fb_info *info)
{
struct vc_data *vc = NULL;
@@ -3103,6 +3110,7 @@
.con_font_default = fbcon_set_def_font,
.con_font_copy = fbcon_copy_font,
.con_set_palette = fbcon_set_palette,
+ .con_set_origin = fbcon_set_origin,
.con_invert_region = fbcon_invert_region,
.con_screen_pos = fbcon_screen_pos,
.con_getxy = fbcon_getxy,

View File

@ -1,65 +0,0 @@
From 3af7a8b44f265a482c8297b420085cfb53725136 Mon Sep 17 00:00:00 2001
From: Bhushan Shah <bshah@kde.org>
Date: Wed, 14 Apr 2021 10:29:57 +0530
Subject: [PATCH 4/5] cdc-wdm: provide wrapper for reset_resume
---
drivers/usb/class/cdc-wdm.c | 35 ++++++++++++++++++++++++++++++++++-
1 file changed, 34 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c
index 508b1c3f8b731..2b9355ed4a2ad 100644
--- a/drivers/usb/class/cdc-wdm.c
+++ b/drivers/usb/class/cdc-wdm.c
@@ -1119,6 +1119,39 @@ static int wdm_resume(struct usb_interface *intf)
return rv;
}
+
+static int wdm_reset_resume(struct usb_interface *intf)
+{
+ struct wdm_device *desc = wdm_find_device(intf);
+ int rv;
+
+ dev_dbg(&desc->intf->dev, "wdm%d_reset_resume\n", intf->minor);
+
+ spin_lock_irq(&desc->iuspin);
+ set_bit(WDM_RESETTING, &desc->flags);
+ set_bit(WDM_READ, &desc->flags);
+ clear_bit(WDM_IN_USE, &desc->flags);
+
+ desc->rerr = -EINTR;
+
+ spin_unlock_irq(&desc->iuspin);
+ wake_up_all(&desc->wait);
+ mutex_lock(&desc->rlock);
+ mutex_lock(&desc->wlock);
+ poison_urbs(desc);
+ cancel_work_sync(&desc->rxwork);
+ cancel_work_sync(&desc->service_outs_intr);
+
+ clear_bit(WDM_SUSPENDING, &desc->flags);
+ clear_bit(WDM_OVERFLOW, &desc->flags);
+ clear_bit(WDM_RESETTING, &desc->flags);
+
+ rv = recover_from_urb_loss(desc);
+ mutex_unlock(&desc->wlock);
+ mutex_unlock(&desc->rlock);
+
+ return rv;
+}
#endif
static int wdm_pre_reset(struct usb_interface *intf)
@@ -1166,7 +1199,7 @@ static struct usb_driver wdm_driver = {
#ifdef CONFIG_PM
.suspend = wdm_suspend,
.resume = wdm_resume,
- .reset_resume = wdm_resume,
+ .reset_resume = wdm_reset_resume,
#endif
.pre_reset = wdm_pre_reset,
.post_reset = wdm_post_reset,
--
2.31.1

View File

@ -1,500 +0,0 @@
--- b/drivers/video/fbdev/core/fbcon.c
+++ a/drivers/video/fbdev/core/fbcon.c
@@ -122,6 +122,12 @@
/* logo_shown is an index to vc_cons when >= 0; otherwise follows FBCON_LOGO
enums. */
static int logo_shown = FBCON_LOGO_CANSHOW;
+/* Software scrollback */
+static int fbcon_softback_size = 32768;
+static unsigned long softback_buf, softback_curr;
+static unsigned long softback_in;
+static unsigned long softback_top, softback_end;
+static int softback_lines;
/* console mappings */
static int first_fb_vc;
static int last_fb_vc = MAX_NR_CONSOLES - 1;
@@ -161,6 +167,8 @@
static const struct consw fb_con;
+#define CM_SOFTBACK (8)
+
#define advance_row(p, delta) (unsigned short *)((unsigned long)(p) + (delta) * vc->vc_size_row)
static int fbcon_set_origin(struct vc_data *);
@@ -365,6 +373,18 @@
return color;
}
+static void fbcon_update_softback(struct vc_data *vc)
+{
+ int l = fbcon_softback_size / vc->vc_size_row;
+
+ if (l > 5)
+ softback_end = softback_buf + l * vc->vc_size_row;
+ else
+ /* Smaller scrollback makes no sense, and 0 would screw
+ the operation totally */
+ softback_top = 0;
+}
+
static void fb_flashcursor(struct work_struct *work)
{
struct fb_info *info = container_of(work, struct fb_info, queue);
@@ -394,7 +414,7 @@
c = scr_readw((u16 *) vc->vc_pos);
mode = (!ops->cursor_flash || ops->cursor_state.enable) ?
CM_ERASE : CM_DRAW;
+ ops->cursor(vc, info, mode, softback_lines, get_color(vc, info, c, 1),
- ops->cursor(vc, info, mode, 0, get_color(vc, info, c, 1),
get_color(vc, info, c, 0));
console_unlock();
}
@@ -451,7 +471,13 @@
}
if (!strncmp(options, "scrollback:", 11)) {
+ options += 11;
+ if (*options) {
+ fbcon_softback_size = simple_strtoul(options, &options, 0);
+ if (*options == 'k' || *options == 'K') {
+ fbcon_softback_size *= 1024;
+ }
+ }
- pr_warn("Ignoring scrollback size option\n");
continue;
}
@@ -996,6 +1022,31 @@
set_blitting_type(vc, info);
+ if (info->fix.type != FB_TYPE_TEXT) {
+ if (fbcon_softback_size) {
+ if (!softback_buf) {
+ softback_buf =
+ (unsigned long)
+ kvmalloc(fbcon_softback_size,
+ GFP_KERNEL);
+ if (!softback_buf) {
+ fbcon_softback_size = 0;
+ softback_top = 0;
+ }
+ }
+ } else {
+ if (softback_buf) {
+ kvfree((void *) softback_buf);
+ softback_buf = 0;
+ softback_top = 0;
+ }
+ }
+ if (softback_buf)
+ softback_in = softback_top = softback_curr =
+ softback_buf;
+ softback_lines = 0;
+ }
+
/* Setup default font */
if (!p->fontdata && !vc->vc_font.data) {
if (!fontname[0] || !(font = find_font(fontname)))
@@ -1169,6 +1220,9 @@
if (logo)
fbcon_prepare_logo(vc, info, cols, rows, new_cols, new_rows);
+ if (vc == svc && softback_buf)
+ fbcon_update_softback(vc);
+
if (ops->rotate_font && ops->rotate_font(info, vc)) {
ops->rotate = FB_ROTATE_UR;
set_blitting_type(vc, info);
@@ -1331,6 +1385,7 @@
{
struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
struct fbcon_ops *ops = info->fbcon_par;
+ int y;
int c = scr_readw((u16 *) vc->vc_pos);
ops->cur_blink_jiffies = msecs_to_jiffies(vc->vc_cur_blink_ms);
@@ -1334,11 +1389,19 @@ static void fbcon_cursor(struct vc_data
fbcon_add_cursor_timer(info);
ops->cursor_flash = (mode == CM_ERASE) ? 0 : 1;
+ if (mode & CM_SOFTBACK) {
+ mode &= ~CM_SOFTBACK;
+ y = softback_lines;
+ } else {
+ if (softback_lines)
+ fbcon_set_origin(vc);
+ y = 0;
+ }
if (!ops->cursor)
return;
- ops->cursor(vc, info, mode, 0, get_color(vc, info, c, 1),
+ ops->cursor(vc, info, mode, y, get_color(vc, info, c, 1),
get_color(vc, info, c, 0));
}
@@ -1416,6 +1479,8 @@
if (con_is_visible(vc)) {
update_screen(vc);
+ if (softback_buf)
+ fbcon_update_softback(vc);
}
}
@@ -1553,6 +1618,99 @@
scrollback_current = 0;
}
+static void fbcon_redraw_softback(struct vc_data *vc, struct fbcon_display *p,
+ long delta)
+{
+ int count = vc->vc_rows;
+ unsigned short *d, *s;
+ unsigned long n;
+ int line = 0;
+
+ d = (u16 *) softback_curr;
+ if (d == (u16 *) softback_in)
+ d = (u16 *) vc->vc_origin;
+ n = softback_curr + delta * vc->vc_size_row;
+ softback_lines -= delta;
+ if (delta < 0) {
+ if (softback_curr < softback_top && n < softback_buf) {
+ n += softback_end - softback_buf;
+ if (n < softback_top) {
+ softback_lines -=
+ (softback_top - n) / vc->vc_size_row;
+ n = softback_top;
+ }
+ } else if (softback_curr >= softback_top
+ && n < softback_top) {
+ softback_lines -=
+ (softback_top - n) / vc->vc_size_row;
+ n = softback_top;
+ }
+ } else {
+ if (softback_curr > softback_in && n >= softback_end) {
+ n += softback_buf - softback_end;
+ if (n > softback_in) {
+ n = softback_in;
+ softback_lines = 0;
+ }
+ } else if (softback_curr <= softback_in && n > softback_in) {
+ n = softback_in;
+ softback_lines = 0;
+ }
+ }
+ if (n == softback_curr)
+ return;
+ softback_curr = n;
+ s = (u16 *) softback_curr;
+ if (s == (u16 *) softback_in)
+ s = (u16 *) vc->vc_origin;
+ while (count--) {
+ unsigned short *start;
+ unsigned short *le;
+ unsigned short c;
+ int x = 0;
+ unsigned short attr = 1;
+
+ start = s;
+ le = advance_row(s, 1);
+ do {
+ c = scr_readw(s);
+ if (attr != (c & 0xff00)) {
+ attr = c & 0xff00;
+ if (s > start) {
+ fbcon_putcs(vc, start, s - start,
+ line, x);
+ x += s - start;
+ start = s;
+ }
+ }
+ if (c == scr_readw(d)) {
+ if (s > start) {
+ fbcon_putcs(vc, start, s - start,
+ line, x);
+ x += s - start + 1;
+ start = s + 1;
+ } else {
+ x++;
+ start++;
+ }
+ }
+ s++;
+ d++;
+ } while (s < le);
+ if (s > start)
+ fbcon_putcs(vc, start, s - start, line, x);
+ line++;
+ if (d == (u16 *) softback_end)
+ d = (u16 *) softback_buf;
+ if (d == (u16 *) softback_in)
+ d = (u16 *) vc->vc_origin;
+ if (s == (u16 *) softback_end)
+ s = (u16 *) softback_buf;
+ if (s == (u16 *) softback_in)
+ s = (u16 *) vc->vc_origin;
+ }
+}
+
static void fbcon_redraw_move(struct vc_data *vc, struct fbcon_display *p,
int line, int count, int dy)
{
@@ -1692,6 +1850,31 @@
}
}
+static inline void fbcon_softback_note(struct vc_data *vc, int t,
+ int count)
+{
+ unsigned short *p;
+
+ if (vc->vc_num != fg_console)
+ return;
+ p = (unsigned short *) (vc->vc_origin + t * vc->vc_size_row);
+
+ while (count) {
+ scr_memcpyw((u16 *) softback_in, p, vc->vc_size_row);
+ count--;
+ p = advance_row(p, 1);
+ softback_in += vc->vc_size_row;
+ if (softback_in == softback_end)
+ softback_in = softback_buf;
+ if (softback_in == softback_top) {
+ softback_top += vc->vc_size_row;
+ if (softback_top == softback_end)
+ softback_top = softback_buf;
+ }
+ }
+ softback_curr = softback_in;
+}
+
static bool fbcon_scroll(struct vc_data *vc, unsigned int t, unsigned int b,
enum con_scroll dir, unsigned int count)
{
@@ -1714,6 +1897,8 @@
case SM_UP:
if (count > vc->vc_rows) /* Maximum realistic size */
count = vc->vc_rows;
+ if (softback_top)
+ fbcon_softback_note(vc, t, count);
if (logo_shown >= 0)
goto redraw_up;
switch (p->scrollmode) {
@@ -2084,6 +2269,14 @@
info = registered_fb[con2fb_map[vc->vc_num]];
ops = info->fbcon_par;
+ if (softback_top) {
+ if (softback_lines)
+ fbcon_set_origin(vc);
+ softback_top = softback_curr = softback_in = softback_buf;
+ softback_lines = 0;
+ fbcon_update_softback(vc);
+ }
+
if (logo_shown >= 0) {
struct vc_data *conp2 = vc_cons[logo_shown].d;
@@ -2407,6 +2600,9 @@
int cnt;
char *old_data = NULL;
+ if (con_is_visible(vc) && softback_lines)
+ fbcon_set_origin(vc);
+
resize = (w != vc->vc_font.width) || (h != vc->vc_font.height);
if (p->userfont)
old_data = vc->vc_font.data;
@@ -2432,6 +2628,8 @@
cols /= w;
rows /= h;
vc_resize(vc, cols, rows);
+ if (con_is_visible(vc) && softback_buf)
+ fbcon_update_softback(vc);
} else if (con_is_visible(vc)
&& vc->vc_mode == KD_TEXT) {
fbcon_clear_margins(vc, 0);
@@ -2590,7 +2788,19 @@
static u16 *fbcon_screen_pos(struct vc_data *vc, int offset)
{
+ unsigned long p;
+ int line;
+
+ if (vc->vc_num != fg_console || !softback_lines)
+ return (u16 *) (vc->vc_origin + offset);
+ line = offset / vc->vc_size_row;
+ if (line >= softback_lines)
+ return (u16 *) (vc->vc_origin + offset -
+ softback_lines * vc->vc_size_row);
+ p = softback_curr + offset;
+ if (p >= softback_end)
+ p += softback_buf - softback_end;
+ return (u16 *) p;
- return (u16 *) (vc->vc_origin + offset);
}
static unsigned long fbcon_getxy(struct vc_data *vc, unsigned long pos,
@@ -2604,7 +2814,22 @@
x = offset % vc->vc_cols;
y = offset / vc->vc_cols;
+ if (vc->vc_num == fg_console)
+ y += softback_lines;
ret = pos + (vc->vc_cols - x) * 2;
+ } else if (vc->vc_num == fg_console && softback_lines) {
+ unsigned long offset = pos - softback_curr;
+
+ if (pos < softback_curr)
+ offset += softback_end - softback_buf;
+ offset /= 2;
+ x = offset % vc->vc_cols;
+ y = offset / vc->vc_cols;
+ ret = pos + (vc->vc_cols - x) * 2;
+ if (ret == softback_end)
+ ret = softback_buf;
+ if (ret == softback_in)
+ ret = vc->vc_origin;
} else {
/* Should not happen */
x = y = 0;
@@ -2632,11 +2857,106 @@
a = ((a) & 0x88ff) | (((a) & 0x7000) >> 4) |
(((a) & 0x0700) << 4);
scr_writew(a, p++);
+ if (p == (u16 *) softback_end)
+ p = (u16 *) softback_buf;
+ if (p == (u16 *) softback_in)
+ p = (u16 *) vc->vc_origin;
+ }
+}
+
+static void fbcon_scrolldelta(struct vc_data *vc, int lines)
+{
+ struct fb_info *info = registered_fb[con2fb_map[fg_console]];
+ struct fbcon_ops *ops = info->fbcon_par;
+ struct fbcon_display *disp = &fb_display[fg_console];
+ int offset, limit, scrollback_old;
+
+ if (softback_top) {
+ if (vc->vc_num != fg_console)
+ return;
+ if (vc->vc_mode != KD_TEXT || !lines)
+ return;
+ if (logo_shown >= 0) {
+ struct vc_data *conp2 = vc_cons[logo_shown].d;
+
+ if (conp2->vc_top == logo_lines
+ && conp2->vc_bottom == conp2->vc_rows)
+ conp2->vc_top = 0;
+ if (logo_shown == vc->vc_num) {
+ unsigned long p, q;
+ int i;
+
+ p = softback_in;
+ q = vc->vc_origin +
+ logo_lines * vc->vc_size_row;
+ for (i = 0; i < logo_lines; i++) {
+ if (p == softback_top)
+ break;
+ if (p == softback_buf)
+ p = softback_end;
+ p -= vc->vc_size_row;
+ q -= vc->vc_size_row;
+ scr_memcpyw((u16 *) q, (u16 *) p,
+ vc->vc_size_row);
+ }
+ softback_in = softback_curr = p;
+ update_region(vc, vc->vc_origin,
+ logo_lines * vc->vc_cols);
+ }
+ logo_shown = FBCON_LOGO_CANSHOW;
+ }
+ fbcon_cursor(vc, CM_ERASE | CM_SOFTBACK);
+ fbcon_redraw_softback(vc, disp, lines);
+ fbcon_cursor(vc, CM_DRAW | CM_SOFTBACK);
+ return;
}
+
+ if (!scrollback_phys_max)
+ return;
+
+ scrollback_old = scrollback_current;
+ scrollback_current -= lines;
+ if (scrollback_current < 0)
+ scrollback_current = 0;
+ else if (scrollback_current > scrollback_max)
+ scrollback_current = scrollback_max;
+ if (scrollback_current == scrollback_old)
+ return;
+
+ if (fbcon_is_inactive(vc, info))
+ return;
+
+ fbcon_cursor(vc, CM_ERASE);
+
+ offset = disp->yscroll - scrollback_current;
+ limit = disp->vrows;
+ switch (disp->scrollmode) {
+ case SCROLL_WRAP_MOVE:
+ info->var.vmode |= FB_VMODE_YWRAP;
+ break;
+ case SCROLL_PAN_MOVE:
+ case SCROLL_PAN_REDRAW:
+ limit -= vc->vc_rows;
+ info->var.vmode &= ~FB_VMODE_YWRAP;
+ break;
+ }
+ if (offset < 0)
+ offset += limit;
+ else if (offset >= limit)
+ offset -= limit;
+
+ ops->var.xoffset = 0;
+ ops->var.yoffset = offset * vc->vc_font.height;
+ ops->update_start(info);
+
+ if (!scrollback_current)
+ fbcon_cursor(vc, CM_DRAW);
}
static int fbcon_set_origin(struct vc_data *vc)
{
+ if (softback_lines)
+ fbcon_scrolldelta(vc, softback_lines);
return 0;
}
@@ -2700,6 +3020,8 @@
fbcon_set_palette(vc, color_table);
update_screen(vc);
+ if (softback_buf)
+ fbcon_update_softback(vc);
}
}
@@ -3110,6 +3432,7 @@
.con_font_default = fbcon_set_def_font,
.con_font_copy = fbcon_copy_font,
.con_set_palette = fbcon_set_palette,
+ .con_scrolldelta = fbcon_scrolldelta,
.con_set_origin = fbcon_set_origin,
.con_invert_region = fbcon_invert_region,
.con_screen_pos = fbcon_screen_pos,
@@ -3344,6 +3667,9 @@
}
#endif
+ kvfree((void *)softback_buf);
+ softback_buf = 0UL;
+
for_each_registered_fb(i) {
int pending = 0;

View File

@ -1,34 +0,0 @@
From ed73c96e313c549f710df58c8fbe47200ee13df1 Mon Sep 17 00:00:00 2001
From: Bhushan Shah <bshah@kde.org>
Date: Sat, 10 Apr 2021 08:52:05 +0530
Subject: [PATCH 5/5] net: usb: qmi_wwan: set the DTR when resuming
If usb device does reset_resume instead of unbind/bind, we need to
re-enable the DTR quirk, that way after resuming connection QMI
communication between host and modem is possible again.
Signed-off-by: Bhushan Shah <bshah@kde.org>
Tested-by: Dalton Durst <d@ltondur.st>
---
drivers/net/usb/qmi_wwan.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
index cd6ae9696b56a..ada94a3242146 100644
--- a/drivers/net/usb/qmi_wwan.c
+++ b/drivers/net/usb/qmi_wwan.c
@@ -855,6 +855,11 @@ static int qmi_wwan_reset_resume(struct usb_interface *intf)
ret = usbnet_resume(intf);
if (ret < 0 && callsub)
info->subdriver->suspend(intf, PMSG_SUSPEND);
+
+ if (dev->driver_info->data & QMI_WWAN_QUIRK_DTR ||
+ le16_to_cpu(dev->udev->descriptor.bcdUSB) >= 0x0201) {
+ qmi_wwan_change_dtr(dev, true);
+ }
err:
return ret;
}
--
2.31.1

View File

@ -1,27 +0,0 @@
From 1671ef2de0f3f698622bed7ba0e9a605fdd260fc Mon Sep 17 00:00:00 2001
From: Bhushan Shah <bshah@kde.org>
Date: Wed, 14 Apr 2021 18:58:41 +0530
Subject: [PATCH 6/6] cdc-wdm: send HUP if we are resetting
If userspace is polling the cdc-wdm socket, and device resets then we
should notify userspace/client about reset.
---
drivers/usb/class/cdc-wdm.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c
index 2b9355ed4a2ad..93d9bacc18384 100644
--- a/drivers/usb/class/cdc-wdm.c
+++ b/drivers/usb/class/cdc-wdm.c
@@ -666,6 +666,8 @@ static __poll_t wdm_poll(struct file *file, struct poll_table_struct *wait)
spin_unlock_irqrestore(&desc->iuspin, flags);
goto desc_out;
}
+ if (test_bit(WDM_RESETTING, &desc->flags))
+ mask = EPOLLHUP;
if (test_bit(WDM_READ, &desc->flags))
mask = EPOLLIN | EPOLLRDNORM;
if (desc->rerr || desc->werr)
--
2.31.1

View File

@ -1,12 +0,0 @@
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 03b83aa91277..dfc6c7d1b0e7 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -4070,6 +4070,7 @@ static int btusb_setup_qca(struct hci_dev *hdev)
}
if (!info) {
bt_dev_err(hdev, "don't support firmware rome 0x%x", ver_rom);
+ if (ver_rom & ~0xffffU) return 0;
return -ENODEV;
}

View File

@ -1,49 +0,0 @@
From cb408fb65a08bd45543724c1e9b8f38ae1bebc4a Mon Sep 17 00:00:00 2001
From: Arnaud Ferraris <arnaud.ferraris@gmail.com>
Date: Tue, 4 Aug 2020 15:12:59 +0200
Subject: [PATCH 177/183] leds-gpio: make max_brightness configurable
---
drivers/leds/leds-gpio.c | 4 ++++
include/linux/leds.h | 3 ++-
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c
index 93f5b1b60fde..f8483fab1164 100644
--- a/drivers/leds/leds-gpio.c
+++ b/drivers/leds/leds-gpio.c
@@ -108,6 +108,8 @@ static int create_gpio_led(const struct gpio_led *template,
if (ret < 0)
return ret;
+ led_dat->cdev.max_brightness = template->max_brightness;
+
if (template->name) {
led_dat->cdev.name = template->name;
ret = devm_led_classdev_register(parent, &led_dat->cdev);
@@ -177,6 +179,8 @@ static struct gpio_leds_priv *gpio_leds_create(struct platform_device *pdev)
if (fwnode_property_present(child, "panic-indicator"))
led.panic_indicator = 1;
+ fwnode_property_read_u32(child, "max-brightness", &led.max_brightness);
+
ret = create_gpio_led(&led, led_dat, dev, child, NULL);
if (ret < 0) {
fwnode_handle_put(child);
diff --git a/include/linux/leds.h b/include/linux/leds.h
index 6a8d6409c993..99a80092114d 100644
--- a/include/linux/leds.h
+++ b/include/linux/leds.h
@@ -513,7 +513,8 @@ typedef int (*gpio_blink_set_t)(struct gpio_desc *desc, int state,
struct gpio_led {
const char *name;
const char *default_trigger;
- unsigned gpio;
+ unsigned gpio;
+ unsigned max_brightness;
unsigned active_low : 1;
unsigned retain_state_suspended : 1;
unsigned panic_indicator : 1;
--
2.30.0

View File

@ -1,50 +0,0 @@
diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
index 149cfde817cb..0399d8714fd0 100644
--- a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
+++ b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
@@ -984,6 +984,8 @@ static int sun50i_a64_ccu_probe(struct p
if (IS_ERR(reg))
return PTR_ERR(reg);
+ platform_set_drvdata(pdev, reg);
+
/* Force the pll-audio variable divider to 3 */
val = readl(reg + SUN50I_A64_PLL_AUDIO_REG);
val &= ~GENMASK(19, 16);
@@ -1031,12 +1031,36 @@ static const struct of_device_id sun50i_
{ }
};
+#define USBPHY_CFG_REG 0x0cc
+
+static int sun50i_a64_ccu_suspend(struct device *dev)
+{
+ void __iomem *reg = dev_get_drvdata(dev);
+
+ writel(readl(reg + USBPHY_CFG_REG) | 0xa00000, reg + USBPHY_CFG_REG);
+
+ return 0;
+}
+
+static int sun50i_a64_ccu_resume(struct device *dev)
+{
+ void __iomem *reg = dev_get_drvdata(dev);
+
+ writel(readl(reg + USBPHY_CFG_REG) & ~0xa00000, reg + USBPHY_CFG_REG);
+
+ return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(sun50i_a64_ccu_pm_ops,
+ sun50i_a64_ccu_suspend, sun50i_a64_ccu_resume);
+
static struct platform_driver sun50i_a64_ccu_driver = {
.probe = sun50i_a64_ccu_probe,
.driver = {
.name = "sun50i-a64-ccu",
.suppress_bind_attrs = true,
.of_match_table = sun50i_a64_ccu_ids,
+ .pm = &sun50i_a64_ccu_pm_ops,
},
};
builtin_platform_driver(sun50i_a64_ccu_driver);

View File

@ -1,175 +0,0 @@
From 5da6a7e3f4d6e11f4887893672f849d2d4fa5b58 Mon Sep 17 00:00:00 2001
From: Clayton Craft <clayton@craftyguy.net>
Date: Wed, 16 Dec 2020 20:16:14 -0800
Subject: [PATCH] dts: pinephone: drop modem-power node
---
.../allwinner/sun50i-a64-pinephone-1.0.dts | 26 +++---------------
.../allwinner/sun50i-a64-pinephone-1.1.dts | 27 +++----------------
.../allwinner/sun50i-a64-pinephone-1.2.dts | 27 +++----------------
.../dts/allwinner/sun50i-a64-pinephone.dtsi | 12 +++++++++
4 files changed, 24 insertions(+), 68 deletions(-)
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.0.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.0.dts
index 0f6faa44ce3e..2cc513772172 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.0.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.0.dts
@@ -86,28 +86,6 @@ &reg_drivevbus {
status = "okay";
};
-&uart3 {
- modem {
- compatible = "quectel,eg25";
- char-device-name = "modem-power";
-
- power-supply = <&reg_vbat_bb>; /* PL7 */
-
- enable-gpios = <&pio 7 8 GPIO_ACTIVE_LOW>; /* PH8 */
- reset-gpios = <&pio 2 4 GPIO_ACTIVE_HIGH>; /* PC4 */
- pwrkey-gpios = <&pio 1 3 GPIO_ACTIVE_HIGH>; /* PB3 */
-
- sleep-gpios = <&pio 7 7 GPIO_ACTIVE_HIGH>; /* PH7 */
- wakeup-gpios = <&pio 1 2 GPIO_ACTIVE_HIGH>; /* PB2-RI */
-
- cts-gpios = <&pio 3 5 GPIO_ACTIVE_HIGH>; /* PD5-CTS */
- dtr-gpios = <&r_pio 0 6 GPIO_ACTIVE_HIGH>; /* PL6-DTR */
- rts-gpios = <&pio 3 4 GPIO_ACTIVE_HIGH>; /* PD4-RTS */
-
- quectel,qdai = "1,1,0,1,0,0,1,1";
- };
-};
-
&usbphy {
usb-role-switch;
@@ -118,6 +96,10 @@ usb0_drd_sw: endpoint {
};
};
+&ring_indicator {
+ gpios = <&pio 1 2 GPIO_ACTIVE_LOW>; /* PB2 */
+};
+
&sgm3140 {
flash-gpios = <&pio 3 24 GPIO_ACTIVE_HIGH>; /* PD24 */
enable-gpios = <&pio 2 3 GPIO_ACTIVE_HIGH>; /* PC3 */
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.1.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.1.dts
index 95a880fdc9ce..5f3b6a1a142f 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.1.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.1.dts
@@ -109,34 +109,15 @@
status = "okay";
};
+&ring_indicator {
+ gpios = <&pio 1 2 GPIO_ACTIVE_LOW>; /* PB2 */
+};
+
&sgm3140 {
enable-gpios = <&pio 3 24 GPIO_ACTIVE_HIGH>; /* PD24 */
flash-gpios = <&pio 2 3 GPIO_ACTIVE_HIGH>; /* PC3 */
};
-&uart3 {
- modem {
- compatible = "quectel,eg25";
- char-device-name = "modem-power";
-
- power-supply = <&reg_vbat_bb>; /* PL7 */
-
- enable-gpios = <&pio 7 8 GPIO_ACTIVE_LOW>; /* PH8 */
- reset-gpios = <&pio 2 4 GPIO_ACTIVE_HIGH>; /* PC4 */
- pwrkey-gpios = <&pio 1 3 GPIO_ACTIVE_HIGH>; /* PB3 */
- //status-pwrkey-multiplexed; /* status acts as pwrkey */
-
- sleep-gpios = <&pio 7 7 GPIO_ACTIVE_HIGH>; /* PH7 */
- wakeup-gpios = <&pio 1 2 GPIO_ACTIVE_HIGH>; /* PB2-RI */
-
- dtr-gpios = <&r_pio 0 6 GPIO_ACTIVE_HIGH>; /* PL6-DTR */
- cts-gpios = <&pio 3 5 GPIO_ACTIVE_HIGH>; /* PD5-CTS */
- rts-gpios = <&pio 3 4 GPIO_ACTIVE_HIGH>; /* PD4-RTS */
-
- quectel,qdai = "1,1,0,1,0,0,1,1";
- };
-};
-
&usbphy {
usb-role-switch;
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.2.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.2.dts
index 23ba72508cfc..889841ca5b8a 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.2.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.2.dts
@@ -101,34 +101,15 @@
enable-active-high;
};
+&ring_indicator {
+ gpios = <&r_pio 0 6 GPIO_ACTIVE_LOW>; /* PL6 */
+};
+
&sgm3140 {
enable-gpios = <&pio 3 24 GPIO_ACTIVE_HIGH>; /* PD24 */
flash-gpios = <&pio 2 3 GPIO_ACTIVE_HIGH>; /* PC3 */
};
-&uart3 {
- modem {
- compatible = "quectel,eg25";
- char-device-name = "modem-power";
-
- power-supply = <&reg_vbat_bb>; /* PL7 */
-
- enable-gpios = <&pio 7 8 GPIO_ACTIVE_LOW>; /* PH8 */
- reset-gpios = <&pio 2 4 GPIO_ACTIVE_HIGH>; /* PC4 */
- status-gpios = <&pio 7 9 GPIO_ACTIVE_HIGH>; /* PH9 */
- pwrkey-gpios = <&pio 1 3 GPIO_ACTIVE_HIGH>; /* PB3 */
-
- host-ready-gpios = <&pio 7 7 GPIO_ACTIVE_HIGH>; /* PH7 */
- wakeup-gpios = <&r_pio 0 6 GPIO_ACTIVE_HIGH>; /* PL6-RI */
-
- dtr-gpios = <&pio 1 2 GPIO_ACTIVE_HIGH>; /* PB2-DTR */
- cts-gpios = <&pio 3 5 GPIO_ACTIVE_HIGH>; /* PD5-CTS */
- rts-gpios = <&pio 3 4 GPIO_ACTIVE_HIGH>; /* PD4-RTS */
-
- quectel,qdai = "1,1,0,1,0,0,1,1";
- };
-};
-
&usbphy {
usb-role-switch;
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
index 02d82980cf39..979d01de8d84 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
@@ -192,6 +192,17 @@ ec25_codec: ec25-codec {
compatible = "quectel,ec25";
};
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ ring_indicator: ring-indicator {
+ label = "Ring Indicator";
+ linux,can-disable;
+ linux,code = <KEY_WAKEUP>;
+ wakeup-source;
+ };
+ };
+
i2c_csi: i2c-csi {
compatible = "i2c-gpio";
sda-gpios = <&pio 4 13 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; /* PE13 */
@@ -256,6 +267,7 @@ reg_usb_5v: usb-5v {
reg_vbat_bb: vbat-bb {
compatible = "regulator-fixed";
regulator-name = "vbat-bb";
+ regulator-always-on;
regulator-min-microvolt = <3500000>;
regulator-max-microvolt = <3500000>;
gpio = <&r_pio 0 7 GPIO_ACTIVE_HIGH>; /* PL7 */
--
2.29.2

View File

@ -1,409 +0,0 @@
From f062022f2a2781d6b8ca63c460b0e72ebac30870 Mon Sep 17 00:00:00 2001
From: Martijn Braam <martijn@brixit.nl>
Date: Mon, 28 Sep 2020 14:26:11 +0200
Subject: [PATCH] media: ov5640: Implement autofocus
The autofocus functionality needs a firmware blob loaded into the
internal microcontroller.
V4L2 doesn't have an api to control all autofocus functionality, but
this at least makes it possible to focus on the center of the sensor.
Signed-off-by: Martijn Braam <martijn@brixit.nl>
---
drivers/media/i2c/ov5640.c | 254 +++++++++++++++++++++++++++++++++++++
1 file changed, 254 insertions(+)
diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c
index df0a507c211f..08a5304c0e95 100644
--- a/drivers/media/i2c/ov5640.c
+++ b/drivers/media/i2c/ov5640.c
@@ -9,6 +9,7 @@
#include <linux/clkdev.h>
#include <linux/ctype.h>
#include <linux/delay.h>
+#include <linux/firmware.h>
#include <linux/device.h>
#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
@@ -31,7 +32,11 @@
#define OV5640_DEFAULT_SLAVE_ID 0x3c
+#define OV5640_REG_SYS_RESET00 0x3000
+#define OV5640_REG_SYS_RESET01 0x3001
#define OV5640_REG_SYS_RESET02 0x3002
+#define OV5640_REG_SYS_CLOCK_ENABLE00 0x3004
+#define OV5640_REG_SYS_CLOCK_ENABLE01 0x3005
#define OV5640_REG_SYS_CLOCK_ENABLE02 0x3006
#define OV5640_REG_SYS_CTRL0 0x3008
#define OV5640_REG_SYS_CTRL0_SW_PWDN 0x42
@@ -41,6 +46,14 @@
#define OV5640_REG_PAD_OUTPUT_ENABLE01 0x3017
#define OV5640_REG_PAD_OUTPUT_ENABLE02 0x3018
#define OV5640_REG_PAD_OUTPUT00 0x3019
+#define OV5640_REG_FW_CMD_MAIN 0x3022
+#define OV5640_REG_FW_CMD_ACK 0x3023
+#define OV5640_REG_FW_CMD_PARA0 0x3024
+#define OV5640_REG_FW_CMD_PARA1 0x3025
+#define OV5640_REG_FW_CMD_PARA2 0x3026
+#define OV5640_REG_FW_CMD_PARA3 0x3027
+#define OV5640_REG_FW_CMD_PARA4 0x3028
+#define OV5640_REG_FW_STATUS 0x3029
#define OV5640_REG_SYSTEM_CONTROL1 0x302e
#define OV5640_REG_SC_PLL_CTRL0 0x3034
#define OV5640_REG_SC_PLL_CTRL1 0x3035
@@ -59,6 +72,7 @@
#define OV5640_REG_AEC_PK_MANUAL 0x3503
#define OV5640_REG_AEC_PK_REAL_GAIN 0x350a
#define OV5640_REG_AEC_PK_VTS 0x350c
+#define OV5640_REG_VCM_CONTROL4 0x3606
#define OV5640_REG_TIMING_DVPHO 0x3808
#define OV5640_REG_TIMING_DVPVO 0x380a
#define OV5640_REG_TIMING_HTS 0x380c
@@ -95,6 +109,20 @@
#define OV5640_REG_SDE_CTRL4 0x5584
#define OV5640_REG_SDE_CTRL5 0x5585
#define OV5640_REG_AVG_READOUT 0x56a1
+#define OV5640_REG_FIRMWARE_BASE 0x8000
+
+#define OV5640_FW_STATUS_S_FIRMWARE 0x7f
+#define OV5640_FW_STATUS_S_STARTUP 0x7e
+#define OV5640_FW_STATUS_S_IDLE 0x70
+#define OV5640_FW_STATUS_S_FOCUSING 0x00
+#define OV5640_FW_STATUS_S_FOCUSED 0x10
+
+#define OV5640_FW_CMD_TRIGGER_FOCUS 0x03
+#define OV5640_FW_CMD_CONTINUOUS_FOCUS 0x04
+#define OV5640_FW_CMD_GET_FOCUS_RESULT 0x07
+#define OV5640_FW_CMD_RELEASE_FOCUS 0x08
+#define OV5640_FW_CMD_ZONE_CONFIG 0x12
+#define OV5640_FW_CMD_DEFAULT_ZONES 0x80
enum ov5640_mode_id {
OV5640_MODE_QCIF_176_144 = 0,
@@ -218,6 +246,12 @@ struct ov5640_ctrls {
struct v4l2_ctrl *auto_gain;
struct v4l2_ctrl *gain;
};
+ struct {
+ struct v4l2_ctrl *focus_auto;
+ struct v4l2_ctrl *af_start;
+ struct v4l2_ctrl *af_stop;
+ struct v4l2_ctrl *af_status;
+ };
struct v4l2_ctrl *brightness;
struct v4l2_ctrl *light_freq;
struct v4l2_ctrl *saturation;
@@ -261,6 +295,8 @@ struct ov5640_dev {
bool pending_mode_change;
bool streaming;
+
+ bool af_initialized;
};
static inline struct ov5640_dev *to_ov5640_dev(struct v4l2_subdev *sd)
@@ -1967,6 +2003,118 @@ static void ov5640_reset(struct ov5640_dev *sensor)
usleep_range(20000, 25000);
}
+static int ov5640_copy_fw_to_device(struct ov5640_dev *sensor,
+ const struct firmware *fw)
+{
+ struct i2c_client *client = sensor->i2c_client;
+ const u8 *data = (const u8 *)fw->data;
+ u8 fw_status;
+ int i;
+ int ret;
+
+ // Putting MCU in reset state
+ ret = ov5640_write_reg(sensor, OV5640_REG_SYS_RESET00, 0x20);
+ if (ret)
+ return ret;
+
+ // Write firmware
+ for (i = 0; i < fw->size / sizeof(u8); i++)
+ ov5640_write_reg(sensor,
+ OV5640_REG_FIRMWARE_BASE + i,
+ data[i]);
+
+ // Reset MCU state
+ ov5640_write_reg(sensor, OV5640_REG_FW_CMD_MAIN, 0x00);
+ ov5640_write_reg(sensor, OV5640_REG_FW_CMD_ACK, 0x00);
+ ov5640_write_reg(sensor, OV5640_REG_FW_CMD_PARA0, 0x00);
+ ov5640_write_reg(sensor, OV5640_REG_FW_CMD_PARA1, 0x00);
+ ov5640_write_reg(sensor, OV5640_REG_FW_CMD_PARA2, 0x00);
+ ov5640_write_reg(sensor, OV5640_REG_FW_CMD_PARA3, 0x00);
+ ov5640_write_reg(sensor, OV5640_REG_FW_CMD_PARA4, 0x00);
+ ov5640_write_reg(sensor, OV5640_REG_FW_STATUS, 0x7f);
+
+ // Start AF MCU
+ ret = ov5640_write_reg(sensor, OV5640_REG_SYS_RESET00, 0x00);
+ if (ret)
+ return ret;
+
+ dev_info(&client->dev, "firmware upload success\n");
+
+ // Wait for firmware to be ready
+ for (i = 0; i < 5; i++) {
+ ret = ov5640_read_reg(sensor, OV5640_REG_FW_STATUS, &fw_status);
+ if (fw_status == OV5640_FW_STATUS_S_IDLE) {
+ dev_info(&client->dev, "fw started after %d ms\n", i * 50);
+ return ret;
+ }
+ msleep(50);
+ }
+ dev_err(&client->dev, "uploaded firmware didn't start, got to 0x%x, retrying...\n", fw_status);
+
+ // Putting MCU in reset state
+ ret = ov5640_write_reg(sensor, OV5640_REG_SYS_RESET00, 0x20);
+ if (ret)
+ return ret;
+ // Start AF MCU
+ ret = ov5640_write_reg(sensor, OV5640_REG_SYS_RESET00, 0x00);
+ if (ret)
+ return ret;
+ // Wait for firmware to be ready
+ for (i = 0; i < 5; i++) {
+ ret = ov5640_read_reg(sensor, OV5640_REG_FW_STATUS, &fw_status);
+ if (fw_status == OV5640_FW_STATUS_S_IDLE) {
+ dev_info(&client->dev, "fw started after %d ms\n", i * 50);
+ return ret;
+ }
+ msleep(50);
+ }
+ dev_err(&client->dev, "uploaded firmware didn't start, got to 0x%x\n", fw_status);
+ return -ETIMEDOUT;
+}
+
+static int ov5640_af_init(struct ov5640_dev *sensor)
+{
+ struct i2c_client *client = sensor->i2c_client;
+ const char* fwname = "ov5640_af.bin";
+ const struct firmware *fw;
+ int ret;
+
+ if (sensor->af_initialized) {
+ return 0;
+ }
+
+ if (firmware_request_nowarn(&fw, fwname, &client->dev) == 0) {
+ ret = ov5640_copy_fw_to_device(sensor, fw);
+ if (ret == 0)
+ sensor->af_initialized = 1;
+ } else {
+ dev_warn(&client->dev, "%s: no autofocus firmware available (%s)\n",
+ __func__, fwname);
+ ret = -1;
+ }
+ release_firmware(fw);
+
+ if (ret)
+ return ret;
+
+ // Enable AF systems
+ ret = ov5640_mod_reg(sensor, OV5640_REG_SYS_CLOCK_ENABLE00,
+ (BIT(6) | BIT(5)), (BIT(6) | BIT(5)));
+ if (ret)
+ return ret;
+ ret = ov5640_mod_reg(sensor, OV5640_REG_SYS_CLOCK_ENABLE01,
+ BIT(6), BIT(6));
+ if (ret)
+ return ret;
+
+ // Set lens focus driver on
+ ov5640_write_reg(sensor, OV5640_REG_VCM_CONTROL4, 0x3f);
+ if (ret)
+ return ret;
+
+ return ret;
+}
+
static int ov5640_set_power_on(struct ov5640_dev *sensor)
{
struct i2c_client *client = sensor->i2c_client;
@@ -1988,6 +2117,8 @@ static int ov5640_set_power_on(struct ov5640_dev *sensor)
goto xclk_off;
}
+ sensor->af_initialized = 0;
+
ov5640_reset(sensor);
ov5640_power(sensor, true);
@@ -2416,6 +2547,35 @@ static int ov5640_set_framefmt(struct ov5640_dev *sensor,
is_jpeg ? (BIT(5) | BIT(3)) : 0);
}
+static int ov5640_fw_command(struct ov5640_dev *sensor, int command)
+{
+ u8 fw_ack;
+ int i;
+ int ret;
+
+ ret = ov5640_write_reg(sensor, OV5640_REG_FW_CMD_ACK, 0x01);
+ if(ret)
+ return ret;
+
+ ret = ov5640_write_reg(sensor, OV5640_REG_FW_CMD_MAIN, command);
+ if(ret)
+ return ret;
+
+ for (i = 0; i < 100; i++) {
+ ret = ov5640_read_reg(sensor, OV5640_REG_FW_CMD_ACK, &fw_ack);
+ if (ret)
+ return ret;
+
+ if (fw_ack == 0){
+ return ret;
+ }
+
+ msleep(50);
+ }
+ return -ETIMEDOUT;
+}
+
+
/*
* Sensor Controls.
*/
@@ -2532,6 +2692,41 @@ static int ov5640_set_ctrl_exposure(struct ov5640_dev *sensor,
return ret;
}
+static int ov5640_set_ctrl_focus(struct ov5640_dev *sensor, int command)
+{
+ struct i2c_client *client = sensor->i2c_client;
+ int ret;
+
+ ret = ov5640_af_init(sensor);
+ if (ret) {
+ dev_err(&client->dev, "%s: no autofocus firmware loaded\n",
+ __func__);
+ return 0;
+ }
+
+ if (command == OV5640_FW_CMD_RELEASE_FOCUS) {
+ dev_dbg(&client->dev, "%s: Releasing autofocus\n",
+ __func__);
+ return ov5640_fw_command(sensor, OV5640_FW_CMD_RELEASE_FOCUS);
+ }
+
+ // Restart zone config
+ ret = ov5640_fw_command(sensor, OV5640_FW_CMD_ZONE_CONFIG);
+ if (ret)
+ return ret;
+
+ // Set default focus zones
+ ret = ov5640_fw_command(sensor, OV5640_FW_CMD_DEFAULT_ZONES);
+ if (ret)
+ return ret;
+
+ dev_dbg(&client->dev, "%s: Triggering autofocus\n",
+ __func__);
+
+ // Start focussing
+ return ov5640_fw_command(sensor, command);
+}
+
static int ov5640_set_ctrl_gain(struct ov5640_dev *sensor, bool auto_gain)
{
struct ov5640_ctrls *ctrls = &sensor->ctrls;
@@ -2638,6 +2833,32 @@ static int ov5640_set_ctrl_vflip(struct ov5640_dev *sensor, int value)
(BIT(2) | BIT(1)) : 0);
}
+static int ov5640_get_af_status(struct ov5640_dev *sensor)
+{
+ u8 fw_status;
+ int ret;
+
+ ret = ov5640_read_reg(sensor, OV5640_REG_FW_STATUS, &fw_status);
+ if (ret)
+ return ret;
+
+ switch (fw_status) {
+ case OV5640_FW_STATUS_S_FIRMWARE:
+ case OV5640_FW_STATUS_S_STARTUP:
+ return V4L2_AUTO_FOCUS_STATUS_FAILED;
+ break;
+ case OV5640_FW_STATUS_S_IDLE:
+ return V4L2_AUTO_FOCUS_STATUS_IDLE;
+ break;
+ case OV5640_FW_STATUS_S_FOCUSED:
+ return V4L2_AUTO_FOCUS_STATUS_REACHED;
+ break;
+ default:
+ return V4L2_AUTO_FOCUS_STATUS_BUSY;
+ break;
+ }
+}
+
static int ov5640_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
{
struct v4l2_subdev *sd = ctrl_to_sd(ctrl);
@@ -2659,6 +2880,12 @@ static int ov5640_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
return val;
sensor->ctrls.exposure->val = val;
break;
+ case V4L2_CID_FOCUS_AUTO:
+ val = ov5640_get_af_status(sensor);
+ if (val < 0)
+ return val;
+ sensor->ctrls.af_status->val = val;
+ break;
}
return 0;
@@ -2690,6 +2917,18 @@ static int ov5640_s_ctrl(struct v4l2_ctrl *ctrl)
case V4L2_CID_AUTO_WHITE_BALANCE:
ret = ov5640_set_ctrl_white_balance(sensor, ctrl->val);
break;
+ case V4L2_CID_FOCUS_AUTO:
+ if (ctrl->val)
+ ret = ov5640_set_ctrl_focus(sensor, OV5640_FW_CMD_CONTINUOUS_FOCUS);
+ else
+ ret = ov5640_set_ctrl_focus(sensor, OV5640_FW_CMD_RELEASE_FOCUS);
+ break;
+ case V4L2_CID_AUTO_FOCUS_START:
+ ret = ov5640_set_ctrl_focus(sensor, OV5640_FW_CMD_TRIGGER_FOCUS);
+ break;
+ case V4L2_CID_AUTO_FOCUS_STOP:
+ ret = ov5640_set_ctrl_focus(sensor, OV5640_FW_CMD_RELEASE_FOCUS);
+ break;
case V4L2_CID_HUE:
ret = ov5640_set_ctrl_hue(sensor, ctrl->val);
break;
@@ -2762,6 +3001,20 @@ static int ov5640_init_controls(struct ov5640_dev *sensor)
ctrls->gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_GAIN,
0, 1023, 1, 0);
+ /* Autofocus */
+ ctrls->focus_auto = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FOCUS_AUTO,
+ 0, 1, 1, 0);
+ ctrls->af_start = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_AUTO_FOCUS_START,
+ 0, 1, 1, 0);
+ ctrls->af_stop = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_AUTO_FOCUS_STOP,
+ 0, 1, 1, 0);
+ ctrls->af_status = v4l2_ctrl_new_std(hdl, ops,
+ V4L2_CID_AUTO_FOCUS_STATUS, 0,
+ (V4L2_AUTO_FOCUS_STATUS_BUSY |
+ V4L2_AUTO_FOCUS_STATUS_REACHED |
+ V4L2_AUTO_FOCUS_STATUS_FAILED),
+ 0, V4L2_AUTO_FOCUS_STATUS_IDLE);
+
ctrls->saturation = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_SATURATION,
0, 255, 1, 64);
ctrls->hue = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_HUE,
@@ -2795,6 +3048,7 @@ static int ov5640_init_controls(struct ov5640_dev *sensor)
v4l2_ctrl_auto_cluster(3, &ctrls->auto_wb, 0, false);
v4l2_ctrl_auto_cluster(2, &ctrls->auto_gain, 0, true);
v4l2_ctrl_auto_cluster(2, &ctrls->auto_exp, 1, true);
+ v4l2_ctrl_cluster(4, &ctrls->focus_auto);
sensor->sd.ctrl_handler = hdl;
return 0;
--
2.25.4

View File

@ -1,12 +0,0 @@
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
index 1c555456b..05fab5d79 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
@@ -78,6 +78,7 @@ green {
};
led-2 {
+ linux,default-trigger = "panic";
function = LED_FUNCTION_INDICATOR;
color = <LED_COLOR_ID_RED>;
gpios = <&pio 3 19 GPIO_ACTIVE_HIGH>; /* PD19 */

View File

@ -1,26 +0,0 @@
From 5a3d7fd96843710d468603412a3270e7eefe997a Mon Sep 17 00:00:00 2001
From: Danct12 <danct12@disroot.org>
Date: Wed, 14 Oct 2020 01:18:40 +0700
Subject: [PATCH] arm64: dts: pinephone: remove flash node for ov5640
Signed-off-by: Danct12 <danct12@disroot.org>
---
arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi | 2 --
1 file changed, 2 deletions(-)
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
index 3781eb8ea..6bc0e9d6d 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
@@ -439,8 +439,6 @@ ov5640: rear-camera@4c {
reset-gpios = <&pio 3 3 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>; /* PD3 */
powerdown-gpios = <&pio 2 0 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; /* PC0 */
- flash-leds = <&sgm3140_flash>;
-
port {
ov5640_ep: endpoint {
remote-endpoint = <&csi_ov5640_ep>;
--
2.28.0

View File

@ -1,57 +0,0 @@
--- b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
+++ a/arch/arm64/boot/dts/rockchip/rk3399.dtsi
@@ -361,54 +361,6 @@
status = "disabled";
};
- debug@fe430000 {
- compatible = "arm,coresight-cpu-debug", "arm,primecell";
- reg = <0 0xfe430000 0 0x1000>;
- clocks = <&cru PCLK_COREDBG_L>;
- clock-names = "apb_pclk";
- cpu = <&cpu_l0>;
- };
-
- debug@fe432000 {
- compatible = "arm,coresight-cpu-debug", "arm,primecell";
- reg = <0 0xfe432000 0 0x1000>;
- clocks = <&cru PCLK_COREDBG_L>;
- clock-names = "apb_pclk";
- cpu = <&cpu_l1>;
- };
-
- debug@fe434000 {
- compatible = "arm,coresight-cpu-debug", "arm,primecell";
- reg = <0 0xfe434000 0 0x1000>;
- clocks = <&cru PCLK_COREDBG_L>;
- clock-names = "apb_pclk";
- cpu = <&cpu_l2>;
- };
-
- debug@fe436000 {
- compatible = "arm,coresight-cpu-debug", "arm,primecell";
- reg = <0 0xfe436000 0 0x1000>;
- clocks = <&cru PCLK_COREDBG_L>;
- clock-names = "apb_pclk";
- cpu = <&cpu_l3>;
- };
-
- debug@fe610000 {
- compatible = "arm,coresight-cpu-debug", "arm,primecell";
- reg = <0 0xfe610000 0 0x1000>;
- clocks = <&cru PCLK_COREDBG_B>;
- clock-names = "apb_pclk";
- cpu = <&cpu_b0>;
- };
-
- debug@fe710000 {
- compatible = "arm,coresight-cpu-debug", "arm,primecell";
- reg = <0 0xfe710000 0 0x1000>;
- clocks = <&cru PCLK_COREDBG_B>;
- clock-names = "apb_pclk";
- cpu = <&cpu_b1>;
- };
-
usbdrd3_0: usb@fe800000 {
compatible = "rockchip,rk3399-dwc3";
#address-cells = <2>;

View File

@ -5,7 +5,7 @@
EAPI="8" EAPI="8"
ETYPE="sources" ETYPE="sources"
K_WANT_GENPATCHES="base extras" K_WANT_GENPATCHES="base extras"
K_GENPATCHES_VER="4" K_GENPATCHES_VER="3"
inherit kernel-2 inherit kernel-2
detect_version detect_version
@ -57,14 +57,6 @@ pkg_postinst() {
einfo "If you use dracut you can run:" einfo "If you use dracut you can run:"
einfo "# dracut -m \"rootfs-block base\" --host-only --kver 5.16.2-pinehone-gentoo-arm64" einfo "# dracut -m \"rootfs-block base\" --host-only --kver 5.16.2-pinehone-gentoo-arm64"
einfo "Change 5.16.2-pinehone-gentoo-arm64 to your kernel version installed in /lib/modules" einfo "Change 5.16.2-pinehone-gentoo-arm64 to your kernel version installed in /lib/modules"
einfo ""
einfo "Due to some bugs you might want to run the following commands:"
einfo "# install -Dt \"/usr/lib/modules/5.16.2-pinephone-gentoo-arm64/build/drivers/md\" -m644 drivers/md/*.h"
einfo "# install -Dt \"/usr/lib/modules/5.16.2-pinephone-gentoo-arm64/build/net/mac80211\" -m644 net/mac80211/*.h"
einfo "# install -Dt \"/usr/lib/modules/5.16.2-pinephone-gentoo-arm64/build/drivers/media/i2c\" -m644 drivers/media/i2c/msp3400-driver.h"
einfo "# install -Dt \"/usr/lib/modules/5.16.2-pinephone-gentoo-arm64/build/drivers/media/usb/dvb-usb\" -m644 drivers/media/usb/dvb-usb/*.h"
einfo "# install -Dt \"/usr/lib/modules/5.16.2-pinephone-gentoo-arm64/build/drivers/media/dvb-frontends\" -m644 drivers/media/dvb-frontends/*.h"
einfo "# install -Dt \"/usr/lib/modules/5.16.2-pinephone-gentoo-arm64/build/drivers/media/tuners\" -m644 drivers/media/tuners/*.h"
} }
pkg_postrm() { pkg_postrm() {