Skip to content

Commit

Permalink
Merge branch 'android12-5.10-lts' of https://android.googlesource.com…
Browse files Browse the repository at this point in the history
…/kernel/common

Signed-off-by: dopaemon <[email protected]>
  • Loading branch information
dopaemon committed Jan 13, 2025
2 parents 70568a1 + ce60eb1 commit 87f0123
Show file tree
Hide file tree
Showing 22 changed files with 190 additions and 233 deletions.
2 changes: 2 additions & 0 deletions arch/arm64/include/asm/mman.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
#define __ASM_MMAN_H__

#include <linux/compiler.h>
#ifndef __GENKSYMS__
#include <linux/fs.h>
#include <linux/shmem_fs.h>
#endif
#include <linux/types.h>
#include <uapi/asm/mman.h>

Expand Down
2 changes: 2 additions & 0 deletions drivers/gpu/drm/drm_gem_shmem_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@
#include <drm/drm_prime.h>
#include <drm/drm_print.h>

#ifndef __GENKSYMS__
#include "../../../mm/internal.h" /* is_cow_mapping() */
#endif

/**
* DOC: overview
Expand Down
83 changes: 22 additions & 61 deletions drivers/i3c/master.c
Original file line number Diff line number Diff line change
Expand Up @@ -346,44 +346,32 @@ struct bus_type i3c_bus_type = {
};

static enum i3c_addr_slot_status
i3c_bus_get_addr_slot_status_mask(struct i3c_bus *bus, u16 addr, u32 mask)
i3c_bus_get_addr_slot_status(struct i3c_bus *bus, u16 addr)
{
unsigned long status;
int bitpos = addr * I3C_ADDR_SLOT_STATUS_BITS;
int status, bitpos = addr * 2;

if (addr > I2C_MAX_ADDR)
return I3C_ADDR_SLOT_RSVD;

status = bus->addrslots[bitpos / BITS_PER_LONG];
status >>= bitpos % BITS_PER_LONG;

return status & mask;
}

static enum i3c_addr_slot_status
i3c_bus_get_addr_slot_status(struct i3c_bus *bus, u16 addr)
{
return i3c_bus_get_addr_slot_status_mask(bus, addr, I3C_ADDR_SLOT_STATUS_MASK);
return status & I3C_ADDR_SLOT_STATUS_MASK;
}

static void i3c_bus_set_addr_slot_status_mask(struct i3c_bus *bus, u16 addr,
enum i3c_addr_slot_status status, u32 mask)
static void i3c_bus_set_addr_slot_status(struct i3c_bus *bus, u16 addr,
enum i3c_addr_slot_status status)
{
int bitpos = addr * I3C_ADDR_SLOT_STATUS_BITS;
int bitpos = addr * 2;
unsigned long *ptr;

if (addr > I2C_MAX_ADDR)
return;

ptr = bus->addrslots + (bitpos / BITS_PER_LONG);
*ptr &= ~((unsigned long)mask << (bitpos % BITS_PER_LONG));
*ptr |= ((unsigned long)status & mask) << (bitpos % BITS_PER_LONG);
}

static void i3c_bus_set_addr_slot_status(struct i3c_bus *bus, u16 addr,
enum i3c_addr_slot_status status)
{
i3c_bus_set_addr_slot_status_mask(bus, addr, status, I3C_ADDR_SLOT_STATUS_MASK);
*ptr &= ~((unsigned long)I3C_ADDR_SLOT_STATUS_MASK <<
(bitpos % BITS_PER_LONG));
*ptr |= (unsigned long)status << (bitpos % BITS_PER_LONG);
}

static bool i3c_bus_dev_addr_is_avail(struct i3c_bus *bus, u8 addr)
Expand All @@ -395,44 +383,13 @@ static bool i3c_bus_dev_addr_is_avail(struct i3c_bus *bus, u8 addr)
return status == I3C_ADDR_SLOT_FREE;
}

/*
* ┌────┬─────────────┬───┬─────────┬───┐
* │S/Sr│ 7'h7E RnW=0 │ACK│ ENTDAA │ T ├────┐
* └────┴─────────────┴───┴─────────┴───┘ │
* ┌─────────────────────────────────────────┘
* │ ┌──┬─────────────┬───┬─────────────────┬────────────────┬───┬─────────┐
* └─►│Sr│7'h7E RnW=1 │ACK│48bit UID BCR DCR│Assign 7bit Addr│PAR│ ACK/NACK│
* └──┴─────────────┴───┴─────────────────┴────────────────┴───┴─────────┘
* Some master controllers (such as HCI) need to prepare the entire above transaction before
* sending it out to the I3C bus. This means that a 7-bit dynamic address needs to be allocated
* before knowing the target device's UID information.
*
* However, some I3C targets may request specific addresses (called as "init_dyn_addr"), which is
* typically specified by the DT-'s assigned-address property. Lower addresses having higher IBI
* priority. If it is available, i3c_bus_get_free_addr() preferably return a free address that is
* not in the list of desired addresses (called as "init_dyn_addr"). This allows the device with
* the "init_dyn_addr" to switch to its "init_dyn_addr" when it hot-joins the I3C bus. Otherwise,
* if the "init_dyn_addr" is already in use by another I3C device, the target device will not be
* able to switch to its desired address.
*
* If the previous step fails, fallback returning one of the remaining unassigned address,
* regardless of its state in the desired list.
*/
static int i3c_bus_get_free_addr(struct i3c_bus *bus, u8 start_addr)
{
enum i3c_addr_slot_status status;
u8 addr;

for (addr = start_addr; addr < I3C_MAX_ADDR; addr++) {
status = i3c_bus_get_addr_slot_status_mask(bus, addr,
I3C_ADDR_SLOT_EXT_STATUS_MASK);
if (status == I3C_ADDR_SLOT_FREE)
return addr;
}

for (addr = start_addr; addr < I3C_MAX_ADDR; addr++) {
status = i3c_bus_get_addr_slot_status_mask(bus, addr,
I3C_ADDR_SLOT_STATUS_MASK);
status = i3c_bus_get_addr_slot_status(bus, addr);
if (status == I3C_ADDR_SLOT_FREE)
return addr;
}
Expand Down Expand Up @@ -1414,9 +1371,16 @@ static int i3c_master_reattach_i3c_dev(struct i3c_dev_desc *dev,
u8 old_dyn_addr)
{
struct i3c_master_controller *master = i3c_dev_get_master(dev);
enum i3c_addr_slot_status status;
int ret;

if (dev->info.dyn_addr != old_dyn_addr) {
if (dev->info.dyn_addr != old_dyn_addr &&
(!dev->boardinfo ||
dev->info.dyn_addr != dev->boardinfo->init_dyn_addr)) {
status = i3c_bus_get_addr_slot_status(&master->bus,
dev->info.dyn_addr);
if (status != I3C_ADDR_SLOT_FREE)
return -EBUSY;
i3c_bus_set_addr_slot_status(&master->bus,
dev->info.dyn_addr,
I3C_ADDR_SLOT_I3C_DEV);
Expand Down Expand Up @@ -1801,11 +1765,9 @@ static int i3c_master_bus_init(struct i3c_master_controller *master)
goto err_rstdaa;
}

/* Do not mark as occupied until real device exist in bus */
i3c_bus_set_addr_slot_status_mask(&master->bus,
i3cboardinfo->init_dyn_addr,
I3C_ADDR_SLOT_EXT_DESIRED,
I3C_ADDR_SLOT_EXT_STATUS_MASK);
i3c_bus_set_addr_slot_status(&master->bus,
i3cboardinfo->init_dyn_addr,
I3C_ADDR_SLOT_I3C_DEV);

/*
* Only try to create/attach devices that have a static
Expand Down Expand Up @@ -1972,8 +1934,7 @@ int i3c_master_add_i3c_dev_locked(struct i3c_master_controller *master,
else
expected_dyn_addr = newdev->info.dyn_addr;

if (newdev->info.dyn_addr != expected_dyn_addr &&
i3c_bus_get_addr_slot_status(&master->bus, expected_dyn_addr) == I3C_ADDR_SLOT_FREE) {
if (newdev->info.dyn_addr != expected_dyn_addr) {
/*
* Try to apply the expected dynamic address. If it fails, keep
* the address assigned by the master.
Expand Down
11 changes: 6 additions & 5 deletions drivers/net/netdevsim/ipsec.c
Original file line number Diff line number Diff line change
Expand Up @@ -171,13 +171,14 @@ static int nsim_ipsec_add_sa(struct xfrm_state *xs)
return ret;
}

if (xs->xso.dir == XFRM_DEV_OFFLOAD_IN)
if (xs->xso.flags & XFRM_OFFLOAD_INBOUND) {
sa.rx = true;

if (xs->props.family == AF_INET6)
memcpy(sa.ipaddr, &xs->id.daddr.a6, 16);
else
memcpy(&sa.ipaddr[3], &xs->id.daddr.a4, 4);
if (xs->props.family == AF_INET6)
memcpy(sa.ipaddr, &xs->id.daddr.a6, 16);
else
memcpy(&sa.ipaddr[3], &xs->id.daddr.a4, 4);
}

/* the preparations worked, so save the info */
memcpy(&ipsec->sa[sa_idx], &sa, sizeof(sa));
Expand Down
21 changes: 10 additions & 11 deletions drivers/spi/spi.c
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,12 @@ static LIST_HEAD(spi_controller_list);
*/
static DEFINE_MUTEX(board_lock);

/*
* Prevents addition of devices with same chip select and
* addition of devices below an unregistering controller.
*/
static DEFINE_MUTEX(spi_add_lock);

/**
* spi_alloc_device - Allocate a new SPI device
* @ctlr: Controller to which device is connected
Expand Down Expand Up @@ -585,7 +591,7 @@ int spi_add_device(struct spi_device *spi)
* chipselect **BEFORE** we call setup(), else we'll trash
* its configuration. Lock against concurrent add() calls.
*/
mutex_lock(&ctlr->add_lock);
mutex_lock(&spi_add_lock);

status = bus_for_each_dev(&spi_bus_type, NULL, spi, spi_dev_check);
if (status) {
Expand Down Expand Up @@ -629,7 +635,7 @@ int spi_add_device(struct spi_device *spi)
}

done:
mutex_unlock(&ctlr->add_lock);
mutex_unlock(&spi_add_lock);
return status;
}
EXPORT_SYMBOL_GPL(spi_add_device);
Expand Down Expand Up @@ -2734,7 +2740,6 @@ int spi_register_controller(struct spi_controller *ctlr)
spin_lock_init(&ctlr->bus_lock_spinlock);
mutex_init(&ctlr->bus_lock_mutex);
mutex_init(&ctlr->io_mutex);
mutex_init(&ctlr->add_lock);
ctlr->bus_lock_flag = 0;
init_completion(&ctlr->xfer_completion);
if (!ctlr->max_dma_len)
Expand Down Expand Up @@ -2885,7 +2890,7 @@ void spi_unregister_controller(struct spi_controller *ctlr)

/* Prevent addition of new devices, unregister existing ones */
if (IS_ENABLED(CONFIG_SPI_DYNAMIC))
mutex_lock(&ctlr->add_lock);
mutex_lock(&spi_add_lock);

device_for_each_child(&ctlr->dev, NULL, __unregister);

Expand Down Expand Up @@ -2917,13 +2922,7 @@ void spi_unregister_controller(struct spi_controller *ctlr)
mutex_unlock(&board_lock);

if (IS_ENABLED(CONFIG_SPI_DYNAMIC))
mutex_unlock(&ctlr->add_lock);

/* Release the last reference on the controller if its driver
* has not yet been converted to devm_spi_alloc_master/slave().
*/
if (!ctlr->devm_allocated)
put_device(&ctlr->dev);
mutex_unlock(&spi_add_lock);
}
EXPORT_SYMBOL_GPL(spi_unregister_controller);

Expand Down
5 changes: 3 additions & 2 deletions drivers/usb/host/xhci-ring.c
Original file line number Diff line number Diff line change
Expand Up @@ -418,8 +418,9 @@ static int xhci_abort_cmd_ring(struct xhci_hcd *xhci, unsigned long flags)
* In the future we should distinguish between -ENODEV and -ETIMEDOUT
* and try to recover a -ETIMEDOUT with a host controller reset.
*/
ret = xhci_handshake(&xhci->op_regs->cmd_ring,
CMD_RING_RUNNING, 0, 5 * 1000 * 1000);
ret = xhci_handshake_check_state(xhci, &xhci->op_regs->cmd_ring,
CMD_RING_RUNNING, 0, 5 * 1000 * 1000,
XHCI_STATE_REMOVING);
if (ret < 0) {
xhci_err(xhci, "Abort failed to stop command ring: %d\n", ret);
xhci_halt(xhci);
Expand Down
26 changes: 25 additions & 1 deletion drivers/usb/host/xhci.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,29 @@ int xhci_handshake(void __iomem *ptr, u32 mask, u32 done, u64 timeout_us)
return ret;
}

/*
* xhci_handshake_check_state - same as xhci_handshake but takes an additional
* exit_state parameter, and bails out with an error immediately when xhc_state
* has exit_state flag set.
*/
int xhci_handshake_check_state(struct xhci_hcd *xhci, void __iomem *ptr,
u32 mask, u32 done, int usec, unsigned int exit_state)
{
u32 result;
int ret;

ret = readl_poll_timeout_atomic(ptr, result,
(result & mask) == done ||
result == U32_MAX ||
xhci->xhc_state & exit_state,
1, usec);

if (result == U32_MAX || xhci->xhc_state & exit_state)
return -ENODEV;

return ret;
}

/*
* Disable interrupts and begin the xHCI halting process.
*/
Expand Down Expand Up @@ -198,7 +221,8 @@ int xhci_reset(struct xhci_hcd *xhci, u64 timeout_us)
if (xhci->quirks & XHCI_INTEL_HOST)
udelay(1000);

ret = xhci_handshake(&xhci->op_regs->command, CMD_RESET, 0, timeout_us);
ret = xhci_handshake_check_state(xhci, &xhci->op_regs->command,
CMD_RESET, 0, timeout_us, XHCI_STATE_REMOVING);
if (ret)
return ret;

Expand Down
2 changes: 2 additions & 0 deletions drivers/usb/host/xhci.h
Original file line number Diff line number Diff line change
Expand Up @@ -2106,6 +2106,8 @@ void xhci_free_container_ctx(struct xhci_hcd *xhci,
/* xHCI host controller glue */
typedef void (*xhci_get_quirks_t)(struct device *, struct xhci_hcd *);
int xhci_handshake(void __iomem *ptr, u32 mask, u32 done, u64 timeout_us);
int xhci_handshake_check_state(struct xhci_hcd *xhci, void __iomem *ptr,
u32 mask, u32 done, int usec, unsigned int exit_state);
void xhci_quiesce(struct xhci_hcd *xhci);
int xhci_halt(struct xhci_hcd *xhci);
int xhci_start(struct xhci_hcd *xhci);
Expand Down
61 changes: 31 additions & 30 deletions fs/f2fs/f2fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -2266,6 +2266,31 @@ static inline bool __allow_reserved_blocks(struct f2fs_sb_info *sbi,
return false;
}

static inline unsigned int get_available_block_count(struct f2fs_sb_info *sbi,
struct inode *inode, bool cap)
{
block_t avail_user_block_count;

avail_user_block_count = sbi->user_block_count -
sbi->current_reserved_blocks;

if (!__allow_reserved_blocks(sbi, inode, cap))
avail_user_block_count -= F2FS_OPTION(sbi).root_reserved_blocks;

if (F2FS_IO_ALIGNED(sbi))
avail_user_block_count -= sbi->blocks_per_seg *
SM_I(sbi)->additional_reserved_segments;

if (unlikely(is_sbi_flag_set(sbi, SBI_CP_DISABLED))) {
if (avail_user_block_count > sbi->unusable_block_count)
avail_user_block_count -= sbi->unusable_block_count;
else
avail_user_block_count = 0;
}

return avail_user_block_count;
}

static inline void f2fs_i_blocks_write(struct inode *, block_t, bool, bool);
static inline int inc_valid_block_count(struct f2fs_sb_info *sbi,
struct inode *inode, blkcnt_t *count)
Expand All @@ -2292,22 +2317,8 @@ static inline int inc_valid_block_count(struct f2fs_sb_info *sbi,

spin_lock(&sbi->stat_lock);
sbi->total_valid_block_count += (block_t)(*count);
avail_user_block_count = sbi->user_block_count -
sbi->current_reserved_blocks;

if (!__allow_reserved_blocks(sbi, inode, true))
avail_user_block_count -= F2FS_OPTION(sbi).root_reserved_blocks;
avail_user_block_count = get_available_block_count(sbi, inode, true);

if (F2FS_IO_ALIGNED(sbi))
avail_user_block_count -= sbi->blocks_per_seg *
SM_I(sbi)->additional_reserved_segments;

if (unlikely(is_sbi_flag_set(sbi, SBI_CP_DISABLED))) {
if (avail_user_block_count > sbi->unusable_block_count)
avail_user_block_count -= sbi->unusable_block_count;
else
avail_user_block_count = 0;
}
if (unlikely(sbi->total_valid_block_count > avail_user_block_count)) {
diff = sbi->total_valid_block_count - avail_user_block_count;
if (diff > *count)
Expand Down Expand Up @@ -2522,7 +2533,8 @@ static inline int inc_valid_node_count(struct f2fs_sb_info *sbi,
struct inode *inode, bool is_inode)
{
block_t valid_block_count;
unsigned int valid_node_count, user_block_count;
unsigned int valid_node_count;
unsigned int avail_user_block_count;
int err;

if (is_inode) {
Expand All @@ -2544,21 +2556,10 @@ static inline int inc_valid_node_count(struct f2fs_sb_info *sbi,

spin_lock(&sbi->stat_lock);

valid_block_count = sbi->total_valid_block_count +
sbi->current_reserved_blocks + 1;

if (!__allow_reserved_blocks(sbi, inode, false))
valid_block_count += F2FS_OPTION(sbi).root_reserved_blocks;

if (F2FS_IO_ALIGNED(sbi))
valid_block_count += sbi->blocks_per_seg *
SM_I(sbi)->additional_reserved_segments;

user_block_count = sbi->user_block_count;
if (unlikely(is_sbi_flag_set(sbi, SBI_CP_DISABLED)))
user_block_count -= sbi->unusable_block_count;
valid_block_count = sbi->total_valid_block_count + 1;
avail_user_block_count = get_available_block_count(sbi, inode, false);

if (unlikely(valid_block_count > user_block_count)) {
if (unlikely(valid_block_count > avail_user_block_count)) {
spin_unlock(&sbi->stat_lock);
goto enospc;
}
Expand Down
Loading

0 comments on commit 87f0123

Please sign in to comment.