You've already forked linux-rockchip
mirror of
https://github.com/armbian/linux-rockchip.git
synced 2026-01-06 11:08:10 -08:00
Merge 5.10.106 into android12-5.10-lts
Changes in 5.10.106 ARM: boot: dts: bcm2711: Fix HVS register range clk: qcom: gdsc: Add support to update GDSC transition delay HID: vivaldi: fix sysfs attributes leak arm64: dts: armada-3720-turris-mox: Add missing ethernet0 alias tipc: fix kernel panic when enabling bearer mISDN: Remove obsolete PIPELINE_DEBUG debugging information mISDN: Fix memory leak in dsp_pipeline_build() virtio-blk: Don't use MAX_DISCARD_SEGMENTS if max_discard_seg is zero isdn: hfcpci: check the return value of dma_set_mask() in setup_hw() net: qlogic: check the return value of dma_alloc_coherent() in qed_vf_hw_prepare() esp: Fix BEET mode inter address family tunneling on GSO qed: return status of qed_iov_get_link drm/sun4i: mixer: Fix P010 and P210 format numbers net: dsa: mt7530: fix incorrect test in mt753x_phylink_validate() ARM: dts: aspeed: Fix AST2600 quad spi group i40e: stop disabling VFs due to PF error responses ice: stop disabling VFs due to PF error responses ice: Align macro names to the specification ice: Remove unnecessary checker loop ice: Rename a couple of variables ice: Fix curr_link_speed advertised speed ethernet: Fix error handling in xemaclite_of_probe tipc: fix incorrect order of state message data sanity check net: ethernet: ti: cpts: Handle error for clk_enable net: ethernet: lpc_eth: Handle error for clk_enable ax25: Fix NULL pointer dereference in ax25_kill_by_device net/mlx5: Fix size field in bufferx_reg struct net/mlx5: Fix a race on command flush flow net/mlx5e: Lag, Only handle events from highest priority multipath entry NFC: port100: fix use-after-free in port100_send_complete selftests: pmtu.sh: Kill tcpdump processes launched by subshell. gpio: ts4900: Do not set DAT and OE together gianfar: ethtool: Fix refcount leak in gfar_get_ts_info net: phy: DP83822: clear MISR2 register to disable interrupts sctp: fix kernel-infoleak for SCTP sockets net: bcmgenet: Don't claim WOL when its not available selftests/bpf: Add test for bpf_timer overwriting crash spi: rockchip: Fix error in getting num-cs property spi: rockchip: terminate dma transmission when slave abort net-sysfs: add check for netdevice being present to speed_show hwmon: (pmbus) Clear pmbus fault/warning bits after read gpio: Return EPROBE_DEFER if gc->to_irq is NULL Revert "xen-netback: remove 'hotplug-status' once it has served its purpose" Revert "xen-netback: Check for hotplug-status existence before watching" ipv6: prevent a possible race condition with lifetimes tracing: Ensure trace buffer is at least 4096 bytes large selftest/vm: fix map_fixed_noreplace test failure selftests/memfd: clean up mapping in mfd_fail_write ARM: Spectre-BHB: provide empty stub for non-config fuse: fix pipe buffer lifetime for direct_io staging: rtl8723bs: Fix access-point mode deadlock staging: gdm724x: fix use after free in gdm_lte_rx() net: macb: Fix lost RX packet wakeup race in NAPI receive mmc: meson: Fix usage of meson_mmc_post_req() riscv: Fix auipc+jalr relocation range checks arm64: dts: marvell: armada-37xx: Remap IO space to bus address 0x0 virtio: unexport virtio_finalize_features virtio: acknowledge all features before access watch_queue, pipe: Free watchqueue state after clearing pipe ring watch_queue: Fix to release page in ->release() watch_queue: Fix to always request a pow-of-2 pipe ring size watch_queue: Fix the alloc bitmap size to reflect notes allocated watch_queue: Free the alloc bitmap when the watch_queue is torn down watch_queue: Fix lack of barrier/sync/lock between post and read watch_queue: Make comment about setting ->defunct more accurate x86/boot: Fix memremap of setup_indirect structures x86/boot: Add setup_indirect support in early_memremap_is_setup_data() x86/traps: Mark do_int3() NOKPROBE_SYMBOL ext4: add check to prevent attempting to resize an fs with sparse_super2 ARM: fix Thumb2 regression with Spectre BHB watch_queue: Fix filter limit check Linux 5.10.106 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com> Change-Id: Ic7943bdf8c771bff4a95fcf0585ec9c24057cb5b
This commit is contained in:
2
Makefile
2
Makefile
@@ -1,7 +1,7 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
VERSION = 5
|
||||
PATCHLEVEL = 10
|
||||
SUBLEVEL = 105
|
||||
SUBLEVEL = 106
|
||||
EXTRAVERSION =
|
||||
NAME = Dare mighty things
|
||||
|
||||
|
||||
@@ -118,7 +118,7 @@
|
||||
};
|
||||
|
||||
pinctrl_fwqspid_default: fwqspid_default {
|
||||
function = "FWQSPID";
|
||||
function = "FWSPID";
|
||||
groups = "FWQSPID";
|
||||
};
|
||||
|
||||
|
||||
@@ -290,6 +290,7 @@
|
||||
|
||||
hvs: hvs@7e400000 {
|
||||
compatible = "brcm,bcm2711-hvs";
|
||||
reg = <0x7e400000 0x8000>;
|
||||
interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>;
|
||||
};
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
aliases {
|
||||
spi0 = &spi0;
|
||||
ethernet0 = ð0;
|
||||
ethernet1 = ð1;
|
||||
mmc0 = &sdhci0;
|
||||
mmc1 = &sdhci1;
|
||||
@@ -137,7 +138,9 @@
|
||||
/*
|
||||
* U-Boot port for Turris Mox has a bug which always expects that "ranges" DT property
|
||||
* contains exactly 2 ranges with 3 (child) address cells, 2 (parent) address cells and
|
||||
* 2 size cells and also expects that the second range starts at 16 MB offset. If these
|
||||
* 2 size cells and also expects that the second range starts at 16 MB offset. Also it
|
||||
* expects that first range uses same address for PCI (child) and CPU (parent) cells (so
|
||||
* no remapping) and that this address is the lowest from all specified ranges. If these
|
||||
* conditions are not met then U-Boot crashes during loading kernel DTB file. PCIe address
|
||||
* space is 128 MB long, so the best split between MEM and IO is to use fixed 16 MB window
|
||||
* for IO and the rest 112 MB (64+32+16) for MEM, despite that maximal IO size is just 64 kB.
|
||||
@@ -146,6 +149,9 @@
|
||||
* https://source.denx.de/u-boot/u-boot/-/commit/cb2ddb291ee6fcbddd6d8f4ff49089dfe580f5d7
|
||||
* https://source.denx.de/u-boot/u-boot/-/commit/c64ac3b3185aeb3846297ad7391fc6df8ecd73bf
|
||||
* https://source.denx.de/u-boot/u-boot/-/commit/4a82fca8e330157081fc132a591ebd99ba02ee33
|
||||
* Bug related to requirement of same child and parent addresses for first range is fixed
|
||||
* in U-Boot version 2022.04 by following commit:
|
||||
* https://source.denx.de/u-boot/u-boot/-/commit/1fd54253bca7d43d046bba4853fe5fafd034bc17
|
||||
*/
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
|
||||
@@ -495,7 +495,7 @@
|
||||
* (totaling 127 MiB) for MEM.
|
||||
*/
|
||||
ranges = <0x82000000 0 0xe8000000 0 0xe8000000 0 0x07f00000 /* Port 0 MEM */
|
||||
0x81000000 0 0xefff0000 0 0xefff0000 0 0x00010000>; /* Port 0 IO */
|
||||
0x81000000 0 0x00000000 0 0xefff0000 0 0x00010000>; /* Port 0 IO */
|
||||
interrupt-map-mask = <0 0 0 7>;
|
||||
interrupt-map = <0 0 0 1 &pcie_intc 0>,
|
||||
<0 0 0 2 &pcie_intc 1>,
|
||||
|
||||
@@ -13,6 +13,19 @@
|
||||
#include <linux/pgtable.h>
|
||||
#include <asm/sections.h>
|
||||
|
||||
/*
|
||||
* The auipc+jalr instruction pair can reach any PC-relative offset
|
||||
* in the range [-2^31 - 2^11, 2^31 - 2^11)
|
||||
*/
|
||||
static bool riscv_insn_valid_32bit_offset(ptrdiff_t val)
|
||||
{
|
||||
#ifdef CONFIG_32BIT
|
||||
return true;
|
||||
#else
|
||||
return (-(1L << 31) - (1L << 11)) <= val && val < ((1L << 31) - (1L << 11));
|
||||
#endif
|
||||
}
|
||||
|
||||
static int apply_r_riscv_32_rela(struct module *me, u32 *location, Elf_Addr v)
|
||||
{
|
||||
if (v != (u32)v) {
|
||||
@@ -95,7 +108,7 @@ static int apply_r_riscv_pcrel_hi20_rela(struct module *me, u32 *location,
|
||||
ptrdiff_t offset = (void *)v - (void *)location;
|
||||
s32 hi20;
|
||||
|
||||
if (offset != (s32)offset) {
|
||||
if (!riscv_insn_valid_32bit_offset(offset)) {
|
||||
pr_err(
|
||||
"%s: target %016llx can not be addressed by the 32-bit offset from PC = %p\n",
|
||||
me->name, (long long)v, location);
|
||||
@@ -197,10 +210,9 @@ static int apply_r_riscv_call_plt_rela(struct module *me, u32 *location,
|
||||
Elf_Addr v)
|
||||
{
|
||||
ptrdiff_t offset = (void *)v - (void *)location;
|
||||
s32 fill_v = offset;
|
||||
u32 hi20, lo12;
|
||||
|
||||
if (offset != fill_v) {
|
||||
if (!riscv_insn_valid_32bit_offset(offset)) {
|
||||
/* Only emit the plt entry if offset over 32-bit range */
|
||||
if (IS_ENABLED(CONFIG_MODULE_SECTIONS)) {
|
||||
offset = module_emit_plt_entry(me, v);
|
||||
@@ -224,10 +236,9 @@ static int apply_r_riscv_call_rela(struct module *me, u32 *location,
|
||||
Elf_Addr v)
|
||||
{
|
||||
ptrdiff_t offset = (void *)v - (void *)location;
|
||||
s32 fill_v = offset;
|
||||
u32 hi20, lo12;
|
||||
|
||||
if (offset != fill_v) {
|
||||
if (!riscv_insn_valid_32bit_offset(offset)) {
|
||||
pr_err(
|
||||
"%s: target %016llx can not be addressed by the 32-bit offset from PC = %p\n",
|
||||
me->name, (long long)v, location);
|
||||
|
||||
@@ -995,8 +995,10 @@ early_param("memmap", parse_memmap_opt);
|
||||
*/
|
||||
void __init e820__reserve_setup_data(void)
|
||||
{
|
||||
struct setup_indirect *indirect;
|
||||
struct setup_data *data;
|
||||
u64 pa_data;
|
||||
u64 pa_data, pa_next;
|
||||
u32 len;
|
||||
|
||||
pa_data = boot_params.hdr.setup_data;
|
||||
if (!pa_data)
|
||||
@@ -1004,6 +1006,14 @@ void __init e820__reserve_setup_data(void)
|
||||
|
||||
while (pa_data) {
|
||||
data = early_memremap(pa_data, sizeof(*data));
|
||||
if (!data) {
|
||||
pr_warn("e820: failed to memremap setup_data entry\n");
|
||||
return;
|
||||
}
|
||||
|
||||
len = sizeof(*data);
|
||||
pa_next = data->next;
|
||||
|
||||
e820__range_update(pa_data, sizeof(*data)+data->len, E820_TYPE_RAM, E820_TYPE_RESERVED_KERN);
|
||||
|
||||
/*
|
||||
@@ -1015,18 +1025,27 @@ void __init e820__reserve_setup_data(void)
|
||||
sizeof(*data) + data->len,
|
||||
E820_TYPE_RAM, E820_TYPE_RESERVED_KERN);
|
||||
|
||||
if (data->type == SETUP_INDIRECT &&
|
||||
((struct setup_indirect *)data->data)->type != SETUP_INDIRECT) {
|
||||
e820__range_update(((struct setup_indirect *)data->data)->addr,
|
||||
((struct setup_indirect *)data->data)->len,
|
||||
E820_TYPE_RAM, E820_TYPE_RESERVED_KERN);
|
||||
e820__range_update_kexec(((struct setup_indirect *)data->data)->addr,
|
||||
((struct setup_indirect *)data->data)->len,
|
||||
E820_TYPE_RAM, E820_TYPE_RESERVED_KERN);
|
||||
if (data->type == SETUP_INDIRECT) {
|
||||
len += data->len;
|
||||
early_memunmap(data, sizeof(*data));
|
||||
data = early_memremap(pa_data, len);
|
||||
if (!data) {
|
||||
pr_warn("e820: failed to memremap indirect setup_data\n");
|
||||
return;
|
||||
}
|
||||
|
||||
indirect = (struct setup_indirect *)data->data;
|
||||
|
||||
if (indirect->type != SETUP_INDIRECT) {
|
||||
e820__range_update(indirect->addr, indirect->len,
|
||||
E820_TYPE_RAM, E820_TYPE_RESERVED_KERN);
|
||||
e820__range_update_kexec(indirect->addr, indirect->len,
|
||||
E820_TYPE_RAM, E820_TYPE_RESERVED_KERN);
|
||||
}
|
||||
}
|
||||
|
||||
pa_data = data->next;
|
||||
early_memunmap(data, sizeof(*data));
|
||||
pa_data = pa_next;
|
||||
early_memunmap(data, len);
|
||||
}
|
||||
|
||||
e820__update_table(e820_table);
|
||||
|
||||
@@ -88,11 +88,13 @@ create_setup_data_node(struct dentry *parent, int no,
|
||||
|
||||
static int __init create_setup_data_nodes(struct dentry *parent)
|
||||
{
|
||||
struct setup_indirect *indirect;
|
||||
struct setup_data_node *node;
|
||||
struct setup_data *data;
|
||||
int error;
|
||||
u64 pa_data, pa_next;
|
||||
struct dentry *d;
|
||||
u64 pa_data;
|
||||
int error;
|
||||
u32 len;
|
||||
int no = 0;
|
||||
|
||||
d = debugfs_create_dir("setup_data", parent);
|
||||
@@ -112,12 +114,29 @@ static int __init create_setup_data_nodes(struct dentry *parent)
|
||||
error = -ENOMEM;
|
||||
goto err_dir;
|
||||
}
|
||||
pa_next = data->next;
|
||||
|
||||
if (data->type == SETUP_INDIRECT &&
|
||||
((struct setup_indirect *)data->data)->type != SETUP_INDIRECT) {
|
||||
node->paddr = ((struct setup_indirect *)data->data)->addr;
|
||||
node->type = ((struct setup_indirect *)data->data)->type;
|
||||
node->len = ((struct setup_indirect *)data->data)->len;
|
||||
if (data->type == SETUP_INDIRECT) {
|
||||
len = sizeof(*data) + data->len;
|
||||
memunmap(data);
|
||||
data = memremap(pa_data, len, MEMREMAP_WB);
|
||||
if (!data) {
|
||||
kfree(node);
|
||||
error = -ENOMEM;
|
||||
goto err_dir;
|
||||
}
|
||||
|
||||
indirect = (struct setup_indirect *)data->data;
|
||||
|
||||
if (indirect->type != SETUP_INDIRECT) {
|
||||
node->paddr = indirect->addr;
|
||||
node->type = indirect->type;
|
||||
node->len = indirect->len;
|
||||
} else {
|
||||
node->paddr = pa_data;
|
||||
node->type = data->type;
|
||||
node->len = data->len;
|
||||
}
|
||||
} else {
|
||||
node->paddr = pa_data;
|
||||
node->type = data->type;
|
||||
@@ -125,7 +144,7 @@ static int __init create_setup_data_nodes(struct dentry *parent)
|
||||
}
|
||||
|
||||
create_setup_data_node(d, no, node);
|
||||
pa_data = data->next;
|
||||
pa_data = pa_next;
|
||||
|
||||
memunmap(data);
|
||||
no++;
|
||||
|
||||
@@ -91,26 +91,41 @@ static int get_setup_data_paddr(int nr, u64 *paddr)
|
||||
|
||||
static int __init get_setup_data_size(int nr, size_t *size)
|
||||
{
|
||||
int i = 0;
|
||||
u64 pa_data = boot_params.hdr.setup_data, pa_next;
|
||||
struct setup_indirect *indirect;
|
||||
struct setup_data *data;
|
||||
u64 pa_data = boot_params.hdr.setup_data;
|
||||
int i = 0;
|
||||
u32 len;
|
||||
|
||||
while (pa_data) {
|
||||
data = memremap(pa_data, sizeof(*data), MEMREMAP_WB);
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
pa_next = data->next;
|
||||
|
||||
if (nr == i) {
|
||||
if (data->type == SETUP_INDIRECT &&
|
||||
((struct setup_indirect *)data->data)->type != SETUP_INDIRECT)
|
||||
*size = ((struct setup_indirect *)data->data)->len;
|
||||
else
|
||||
if (data->type == SETUP_INDIRECT) {
|
||||
len = sizeof(*data) + data->len;
|
||||
memunmap(data);
|
||||
data = memremap(pa_data, len, MEMREMAP_WB);
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
|
||||
indirect = (struct setup_indirect *)data->data;
|
||||
|
||||
if (indirect->type != SETUP_INDIRECT)
|
||||
*size = indirect->len;
|
||||
else
|
||||
*size = data->len;
|
||||
} else {
|
||||
*size = data->len;
|
||||
}
|
||||
|
||||
memunmap(data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pa_data = data->next;
|
||||
pa_data = pa_next;
|
||||
memunmap(data);
|
||||
i++;
|
||||
}
|
||||
@@ -120,9 +135,11 @@ static int __init get_setup_data_size(int nr, size_t *size)
|
||||
static ssize_t type_show(struct kobject *kobj,
|
||||
struct kobj_attribute *attr, char *buf)
|
||||
{
|
||||
struct setup_indirect *indirect;
|
||||
struct setup_data *data;
|
||||
int nr, ret;
|
||||
u64 paddr;
|
||||
struct setup_data *data;
|
||||
u32 len;
|
||||
|
||||
ret = kobj_to_setup_data_nr(kobj, &nr);
|
||||
if (ret)
|
||||
@@ -135,10 +152,20 @@ static ssize_t type_show(struct kobject *kobj,
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
|
||||
if (data->type == SETUP_INDIRECT)
|
||||
ret = sprintf(buf, "0x%x\n", ((struct setup_indirect *)data->data)->type);
|
||||
else
|
||||
if (data->type == SETUP_INDIRECT) {
|
||||
len = sizeof(*data) + data->len;
|
||||
memunmap(data);
|
||||
data = memremap(paddr, len, MEMREMAP_WB);
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
|
||||
indirect = (struct setup_indirect *)data->data;
|
||||
|
||||
ret = sprintf(buf, "0x%x\n", indirect->type);
|
||||
} else {
|
||||
ret = sprintf(buf, "0x%x\n", data->type);
|
||||
}
|
||||
|
||||
memunmap(data);
|
||||
return ret;
|
||||
}
|
||||
@@ -149,9 +176,10 @@ static ssize_t setup_data_data_read(struct file *fp,
|
||||
char *buf,
|
||||
loff_t off, size_t count)
|
||||
{
|
||||
struct setup_indirect *indirect;
|
||||
struct setup_data *data;
|
||||
int nr, ret = 0;
|
||||
u64 paddr, len;
|
||||
struct setup_data *data;
|
||||
void *p;
|
||||
|
||||
ret = kobj_to_setup_data_nr(kobj, &nr);
|
||||
@@ -165,10 +193,27 @@ static ssize_t setup_data_data_read(struct file *fp,
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
|
||||
if (data->type == SETUP_INDIRECT &&
|
||||
((struct setup_indirect *)data->data)->type != SETUP_INDIRECT) {
|
||||
paddr = ((struct setup_indirect *)data->data)->addr;
|
||||
len = ((struct setup_indirect *)data->data)->len;
|
||||
if (data->type == SETUP_INDIRECT) {
|
||||
len = sizeof(*data) + data->len;
|
||||
memunmap(data);
|
||||
data = memremap(paddr, len, MEMREMAP_WB);
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
|
||||
indirect = (struct setup_indirect *)data->data;
|
||||
|
||||
if (indirect->type != SETUP_INDIRECT) {
|
||||
paddr = indirect->addr;
|
||||
len = indirect->len;
|
||||
} else {
|
||||
/*
|
||||
* Even though this is technically undefined, return
|
||||
* the data as though it is a normal setup_data struct.
|
||||
* This will at least allow it to be inspected.
|
||||
*/
|
||||
paddr += sizeof(*data);
|
||||
len = data->len;
|
||||
}
|
||||
} else {
|
||||
paddr += sizeof(*data);
|
||||
len = data->len;
|
||||
|
||||
@@ -371,21 +371,41 @@ static void __init parse_setup_data(void)
|
||||
|
||||
static void __init memblock_x86_reserve_range_setup_data(void)
|
||||
{
|
||||
struct setup_indirect *indirect;
|
||||
struct setup_data *data;
|
||||
u64 pa_data;
|
||||
u64 pa_data, pa_next;
|
||||
u32 len;
|
||||
|
||||
pa_data = boot_params.hdr.setup_data;
|
||||
while (pa_data) {
|
||||
data = early_memremap(pa_data, sizeof(*data));
|
||||
if (!data) {
|
||||
pr_warn("setup: failed to memremap setup_data entry\n");
|
||||
return;
|
||||
}
|
||||
|
||||
len = sizeof(*data);
|
||||
pa_next = data->next;
|
||||
|
||||
memblock_reserve(pa_data, sizeof(*data) + data->len);
|
||||
|
||||
if (data->type == SETUP_INDIRECT &&
|
||||
((struct setup_indirect *)data->data)->type != SETUP_INDIRECT)
|
||||
memblock_reserve(((struct setup_indirect *)data->data)->addr,
|
||||
((struct setup_indirect *)data->data)->len);
|
||||
if (data->type == SETUP_INDIRECT) {
|
||||
len += data->len;
|
||||
early_memunmap(data, sizeof(*data));
|
||||
data = early_memremap(pa_data, len);
|
||||
if (!data) {
|
||||
pr_warn("setup: failed to memremap indirect setup_data\n");
|
||||
return;
|
||||
}
|
||||
|
||||
pa_data = data->next;
|
||||
early_memunmap(data, sizeof(*data));
|
||||
indirect = (struct setup_indirect *)data->data;
|
||||
|
||||
if (indirect->type != SETUP_INDIRECT)
|
||||
memblock_reserve(indirect->addr, indirect->len);
|
||||
}
|
||||
|
||||
pa_data = pa_next;
|
||||
early_memunmap(data, len);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -651,6 +651,7 @@ static bool do_int3(struct pt_regs *regs)
|
||||
|
||||
return res == NOTIFY_STOP;
|
||||
}
|
||||
NOKPROBE_SYMBOL(do_int3);
|
||||
|
||||
static void do_int3_user(struct pt_regs *regs)
|
||||
{
|
||||
|
||||
@@ -633,6 +633,7 @@ static bool memremap_is_efi_data(resource_size_t phys_addr,
|
||||
static bool memremap_is_setup_data(resource_size_t phys_addr,
|
||||
unsigned long size)
|
||||
{
|
||||
struct setup_indirect *indirect;
|
||||
struct setup_data *data;
|
||||
u64 paddr, paddr_next;
|
||||
|
||||
@@ -645,6 +646,10 @@ static bool memremap_is_setup_data(resource_size_t phys_addr,
|
||||
|
||||
data = memremap(paddr, sizeof(*data),
|
||||
MEMREMAP_WB | MEMREMAP_DEC);
|
||||
if (!data) {
|
||||
pr_warn("failed to memremap setup_data entry\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
paddr_next = data->next;
|
||||
len = data->len;
|
||||
@@ -654,10 +659,21 @@ static bool memremap_is_setup_data(resource_size_t phys_addr,
|
||||
return true;
|
||||
}
|
||||
|
||||
if (data->type == SETUP_INDIRECT &&
|
||||
((struct setup_indirect *)data->data)->type != SETUP_INDIRECT) {
|
||||
paddr = ((struct setup_indirect *)data->data)->addr;
|
||||
len = ((struct setup_indirect *)data->data)->len;
|
||||
if (data->type == SETUP_INDIRECT) {
|
||||
memunmap(data);
|
||||
data = memremap(paddr, sizeof(*data) + len,
|
||||
MEMREMAP_WB | MEMREMAP_DEC);
|
||||
if (!data) {
|
||||
pr_warn("failed to memremap indirect setup_data\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
indirect = (struct setup_indirect *)data->data;
|
||||
|
||||
if (indirect->type != SETUP_INDIRECT) {
|
||||
paddr = indirect->addr;
|
||||
len = indirect->len;
|
||||
}
|
||||
}
|
||||
|
||||
memunmap(data);
|
||||
@@ -678,22 +694,51 @@ static bool memremap_is_setup_data(resource_size_t phys_addr,
|
||||
static bool __init early_memremap_is_setup_data(resource_size_t phys_addr,
|
||||
unsigned long size)
|
||||
{
|
||||
struct setup_indirect *indirect;
|
||||
struct setup_data *data;
|
||||
u64 paddr, paddr_next;
|
||||
|
||||
paddr = boot_params.hdr.setup_data;
|
||||
while (paddr) {
|
||||
unsigned int len;
|
||||
unsigned int len, size;
|
||||
|
||||
if (phys_addr == paddr)
|
||||
return true;
|
||||
|
||||
data = early_memremap_decrypted(paddr, sizeof(*data));
|
||||
if (!data) {
|
||||
pr_warn("failed to early memremap setup_data entry\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
size = sizeof(*data);
|
||||
|
||||
paddr_next = data->next;
|
||||
len = data->len;
|
||||
|
||||
early_memunmap(data, sizeof(*data));
|
||||
if ((phys_addr > paddr) && (phys_addr < (paddr + len))) {
|
||||
early_memunmap(data, sizeof(*data));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (data->type == SETUP_INDIRECT) {
|
||||
size += len;
|
||||
early_memunmap(data, sizeof(*data));
|
||||
data = early_memremap_decrypted(paddr, size);
|
||||
if (!data) {
|
||||
pr_warn("failed to early memremap indirect setup_data\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
indirect = (struct setup_indirect *)data->data;
|
||||
|
||||
if (indirect->type != SETUP_INDIRECT) {
|
||||
paddr = indirect->addr;
|
||||
len = indirect->len;
|
||||
}
|
||||
}
|
||||
|
||||
early_memunmap(data, size);
|
||||
|
||||
if ((phys_addr > paddr) && (phys_addr < (paddr + len)))
|
||||
return true;
|
||||
|
||||
@@ -871,9 +871,15 @@ static int virtblk_probe(struct virtio_device *vdev)
|
||||
|
||||
virtio_cread(vdev, struct virtio_blk_config, max_discard_seg,
|
||||
&v);
|
||||
|
||||
/*
|
||||
* max_discard_seg == 0 is out of spec but we always
|
||||
* handled it.
|
||||
*/
|
||||
if (!v)
|
||||
v = sg_elems - 2;
|
||||
blk_queue_max_discard_segments(q,
|
||||
min_not_zero(v,
|
||||
MAX_DISCARD_SEGMENTS));
|
||||
min(v, MAX_DISCARD_SEGMENTS));
|
||||
|
||||
blk_queue_flag_set(QUEUE_FLAG_DISCARD, q);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2015, 2017-2018, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2015, 2017-2018, 2022, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/bitops.h>
|
||||
@@ -34,9 +34,14 @@
|
||||
#define CFG_GDSCR_OFFSET 0x4
|
||||
|
||||
/* Wait 2^n CXO cycles between all states. Here, n=2 (4 cycles). */
|
||||
#define EN_REST_WAIT_VAL (0x2 << 20)
|
||||
#define EN_FEW_WAIT_VAL (0x8 << 16)
|
||||
#define CLK_DIS_WAIT_VAL (0x2 << 12)
|
||||
#define EN_REST_WAIT_VAL 0x2
|
||||
#define EN_FEW_WAIT_VAL 0x8
|
||||
#define CLK_DIS_WAIT_VAL 0x2
|
||||
|
||||
/* Transition delay shifts */
|
||||
#define EN_REST_WAIT_SHIFT 20
|
||||
#define EN_FEW_WAIT_SHIFT 16
|
||||
#define CLK_DIS_WAIT_SHIFT 12
|
||||
|
||||
#define RETAIN_MEM BIT(14)
|
||||
#define RETAIN_PERIPH BIT(13)
|
||||
@@ -341,7 +346,18 @@ static int gdsc_init(struct gdsc *sc)
|
||||
*/
|
||||
mask = HW_CONTROL_MASK | SW_OVERRIDE_MASK |
|
||||
EN_REST_WAIT_MASK | EN_FEW_WAIT_MASK | CLK_DIS_WAIT_MASK;
|
||||
val = EN_REST_WAIT_VAL | EN_FEW_WAIT_VAL | CLK_DIS_WAIT_VAL;
|
||||
|
||||
if (!sc->en_rest_wait_val)
|
||||
sc->en_rest_wait_val = EN_REST_WAIT_VAL;
|
||||
if (!sc->en_few_wait_val)
|
||||
sc->en_few_wait_val = EN_FEW_WAIT_VAL;
|
||||
if (!sc->clk_dis_wait_val)
|
||||
sc->clk_dis_wait_val = CLK_DIS_WAIT_VAL;
|
||||
|
||||
val = sc->en_rest_wait_val << EN_REST_WAIT_SHIFT |
|
||||
sc->en_few_wait_val << EN_FEW_WAIT_SHIFT |
|
||||
sc->clk_dis_wait_val << CLK_DIS_WAIT_SHIFT;
|
||||
|
||||
ret = regmap_update_bits(sc->regmap, sc->gdscr, mask, val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2015, 2017-2018, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2015, 2017-2018, 2022, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __QCOM_GDSC_H__
|
||||
@@ -22,6 +22,9 @@ struct reset_controller_dev;
|
||||
* @cxcs: offsets of branch registers to toggle mem/periph bits in
|
||||
* @cxc_count: number of @cxcs
|
||||
* @pwrsts: Possible powerdomain power states
|
||||
* @en_rest_wait_val: transition delay value for receiving enr ack signal
|
||||
* @en_few_wait_val: transition delay value for receiving enf ack signal
|
||||
* @clk_dis_wait_val: transition delay value for halting clock
|
||||
* @resets: ids of resets associated with this gdsc
|
||||
* @reset_count: number of @resets
|
||||
* @rcdev: reset controller
|
||||
@@ -35,6 +38,9 @@ struct gdsc {
|
||||
unsigned int clamp_io_ctrl;
|
||||
unsigned int *cxcs;
|
||||
unsigned int cxc_count;
|
||||
unsigned int en_rest_wait_val;
|
||||
unsigned int en_few_wait_val;
|
||||
unsigned int clk_dis_wait_val;
|
||||
const u8 pwrsts;
|
||||
/* Powerdomain allowable state bitfields */
|
||||
#define PWRSTS_OFF BIT(0)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Digital I/O driver for Technologic Systems I2C FPGA Core
|
||||
*
|
||||
* Copyright (C) 2015 Technologic Systems
|
||||
* Copyright (C) 2015, 2018 Technologic Systems
|
||||
* Copyright (C) 2016 Savoir-Faire Linux
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
@@ -55,19 +55,33 @@ static int ts4900_gpio_direction_input(struct gpio_chip *chip,
|
||||
{
|
||||
struct ts4900_gpio_priv *priv = gpiochip_get_data(chip);
|
||||
|
||||
/*
|
||||
* This will clear the output enable bit, the other bits are
|
||||
* dontcare when this is cleared
|
||||
/* Only clear the OE bit here, requires a RMW. Prevents potential issue
|
||||
* with OE and data getting to the physical pin at different times.
|
||||
*/
|
||||
return regmap_write(priv->regmap, offset, 0);
|
||||
return regmap_update_bits(priv->regmap, offset, TS4900_GPIO_OE, 0);
|
||||
}
|
||||
|
||||
static int ts4900_gpio_direction_output(struct gpio_chip *chip,
|
||||
unsigned int offset, int value)
|
||||
{
|
||||
struct ts4900_gpio_priv *priv = gpiochip_get_data(chip);
|
||||
unsigned int reg;
|
||||
int ret;
|
||||
|
||||
/* If changing from an input to an output, we need to first set the
|
||||
* proper data bit to what is requested and then set OE bit. This
|
||||
* prevents a glitch that can occur on the IO line
|
||||
*/
|
||||
regmap_read(priv->regmap, offset, ®);
|
||||
if (!(reg & TS4900_GPIO_OE)) {
|
||||
if (value)
|
||||
reg = TS4900_GPIO_OUT;
|
||||
else
|
||||
reg &= ~TS4900_GPIO_OUT;
|
||||
|
||||
regmap_write(priv->regmap, offset, reg);
|
||||
}
|
||||
|
||||
if (value)
|
||||
ret = regmap_write(priv->regmap, offset, TS4900_GPIO_OE |
|
||||
TS4900_GPIO_OUT);
|
||||
|
||||
@@ -3216,6 +3216,16 @@ int gpiod_to_irq(const struct gpio_desc *desc)
|
||||
|
||||
return retirq;
|
||||
}
|
||||
#ifdef CONFIG_GPIOLIB_IRQCHIP
|
||||
if (gc->irq.chip) {
|
||||
/*
|
||||
* Avoid race condition with other code, which tries to lookup
|
||||
* an IRQ before the irqchip has been properly registered,
|
||||
* i.e. while gpiochip is still being brought up.
|
||||
*/
|
||||
return -EPROBE_DEFER;
|
||||
}
|
||||
#endif
|
||||
return -ENXIO;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(gpiod_to_irq);
|
||||
|
||||
@@ -113,10 +113,10 @@
|
||||
/* format 13 is semi-planar YUV411 VUVU */
|
||||
#define SUN8I_MIXER_FBFMT_YUV411 14
|
||||
/* format 15 doesn't exist */
|
||||
/* format 16 is P010 YVU */
|
||||
#define SUN8I_MIXER_FBFMT_P010_YUV 17
|
||||
/* format 18 is P210 YVU */
|
||||
#define SUN8I_MIXER_FBFMT_P210_YUV 19
|
||||
#define SUN8I_MIXER_FBFMT_P010_YUV 16
|
||||
/* format 17 is P010 YVU */
|
||||
#define SUN8I_MIXER_FBFMT_P210_YUV 18
|
||||
/* format 19 is P210 YVU */
|
||||
/* format 20 is packed YVU444 10-bit */
|
||||
/* format 21 is packed YUV444 10-bit */
|
||||
|
||||
|
||||
@@ -143,7 +143,7 @@ out:
|
||||
static int vivaldi_input_configured(struct hid_device *hdev,
|
||||
struct hid_input *hidinput)
|
||||
{
|
||||
return sysfs_create_group(&hdev->dev.kobj, &input_attribute_group);
|
||||
return devm_device_add_group(&hdev->dev, &input_attribute_group);
|
||||
}
|
||||
|
||||
static const struct hid_device_id vivaldi_table[] = {
|
||||
|
||||
@@ -898,6 +898,11 @@ static int pmbus_get_boolean(struct i2c_client *client, struct pmbus_boolean *b,
|
||||
pmbus_update_sensor_data(client, s2);
|
||||
|
||||
regval = status & mask;
|
||||
if (regval) {
|
||||
ret = pmbus_write_byte_data(client, page, reg, regval);
|
||||
if (ret)
|
||||
goto unlock;
|
||||
}
|
||||
if (s1 && s2) {
|
||||
s64 v1, v2;
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user