Merge commit '904ebc320c2c18c0c07fcb75341de2a055137343' of https://android.googlesource.com/kernel/common

* commit '904ebc320c2c18c0c07fcb75341de2a055137343':
  Revert "UPSTREAM: unicode: Don't special case ignorable code points"
  ANDROID: KVM: arm64: Fix missing mutex init for hyp trace readers
  ANDROID: mm: EXPORT_SYMBOL_GPL(reclaim_pages) position adjustment
  ANDROID: GKI: Update symbol list for mtk
  UPSTREAM: HID: core: zero-initialize the report buffer
  ANDROID: GKI: Update symbol list for mtk
  UPSTREAM: of: property: fw_devlink: Add support for "post-init-providers" property
  UPSTREAM: driver core: Add FWLINK_FLAG_IGNORE to completely ignore a fwnode link
  UPSTREAM: driver core: Adds flags param to fwnode_link_add()
  UPSTREAM: f2fs: modify f2fs_is_checkpoint_ready logic to allow more data to be written with the CP disable
  BACKPORT: f2fs: introduce get_available_block_count() for cleanup
  FROMGIT: pinmux: Use sequential access to access desc->pinmux data
  BACKPORT: firmware: arm_scmi: Support 'reg-io-width' property for shared memory
  UPSTREAM: dt-bindings: sram: Document reg-io-width property
  ANDROID: GKI: Update symbol list for mtk

Change-Id: Ifff0c89fd6f3c692bd4c1412e0acffb2b4e027ca
This commit is contained in:
Tao Huang
2025-01-10 18:04:05 +08:00
21 changed files with 3842 additions and 3478 deletions

View File

@@ -100,6 +100,12 @@ patternProperties:
IO mem address range, relative to the SRAM range.
maxItems: 1
reg-io-width:
description:
The size (in bytes) of the IO accesses that should be performed on the
SRAM.
enum: [1, 2, 4, 8]
pool:
description:
Indicates that the particular reserved SRAM area is addressable

View File

@@ -10083,6 +10083,11 @@ pointer_reference {
kind: POINTER
pointee_type_id: 0x4d998a91
}
pointer_reference {
id: 0x19f68db9
kind: POINTER
pointee_type_id: 0x4d9ad078
}
pointer_reference {
id: 0x19fa9e98
kind: POINTER
@@ -309236,6 +309241,12 @@ function {
return_type_id: 0x18bd6530
parameter_id: 0x0356cddf
}
function {
id: 0x564ae602
return_type_id: 0x18bd6530
parameter_id: 0x0258f96e
parameter_id: 0x129a6a0a
}
function {
id: 0x5659e8fb
return_type_id: 0x18bd6530
@@ -311705,6 +311716,11 @@ function {
return_type_id: 0x3e10b518
parameter_id: 0x4296745b
}
function {
id: 0x83085622
return_type_id: 0x19f68db9
parameter_id: 0x18ea6ae3
}
function {
id: 0x832143d7
return_type_id: 0x11e6864c
@@ -337264,6 +337280,13 @@ function {
return_type_id: 0x0a193bb7
parameter_id: 0x1d19a9d5
}
function {
id: 0xac365a8e
return_type_id: 0x6720d32f
parameter_id: 0xc714b5b1
parameter_id: 0x18bd6530
parameter_id: 0x4585663f
}
function {
id: 0xac45ce43
return_type_id: 0x6720d32f
@@ -338464,6 +338487,11 @@ function {
return_type_id: 0x02c35f57
parameter_id: 0x02c35f57
}
function {
id: 0xc85f6a93
return_type_id: 0x4585663f
parameter_id: 0x1a1051a0
}
function {
id: 0xc867c639
return_type_id: 0x2b16c036
@@ -366035,6 +366063,15 @@ elf_symbol {
type_id: 0x5468daf3
full_name: "devm_memremap"
}
elf_symbol {
id: 0xa21e8009
name: "devm_memremap_pages"
is_defined: true
symbol_type: FUNCTION
crc: 0x8748c39e
type_id: 0x564ae602
full_name: "devm_memremap_pages"
}
elf_symbol {
id: 0x86c1623f
name: "devm_memunmap"
@@ -397882,6 +397919,15 @@ elf_symbol {
type_id: 0x97f16301
full_name: "rproc_del"
}
elf_symbol {
id: 0xede9cf60
name: "rproc_detach"
is_defined: true
symbol_type: FUNCTION
crc: 0xb927eafd
type_id: 0x97f16301
full_name: "rproc_detach"
}
elf_symbol {
id: 0x4f3dccb0
name: "rproc_elf_find_loaded_rsc_table"
@@ -402167,6 +402213,15 @@ elf_symbol {
type_id: 0xac45ce43
full_name: "snd_pcm_format_physical_width"
}
elf_symbol {
id: 0xb132031d
name: "snd_pcm_format_set_silence"
is_defined: true
symbol_type: FUNCTION
crc: 0x5e7f4920
type_id: 0xac365a8e
full_name: "snd_pcm_format_set_silence"
}
elf_symbol {
id: 0xaec05601
name: "snd_pcm_format_size"
@@ -407732,6 +407787,15 @@ elf_symbol {
type_id: 0x9a98740b
full_name: "tty_buffer_set_limit"
}
elf_symbol {
id: 0x5d10efc1
name: "tty_buffer_space_avail"
is_defined: true
symbol_type: FUNCTION
crc: 0x9fb6be5e
type_id: 0xc85f6a93
full_name: "tty_buffer_space_avail"
}
elf_symbol {
id: 0x0b4dd20d
name: "tty_chars_in_buffer"
@@ -408236,6 +408300,33 @@ elf_symbol {
type_id: 0xc564dee2
full_name: "tty_write_room"
}
elf_symbol {
id: 0xa46589d6
name: "tun_get_socket"
is_defined: true
symbol_type: FUNCTION
crc: 0x6776ec47
type_id: 0x229f1818
full_name: "tun_get_socket"
}
elf_symbol {
id: 0x3d3dcefb
name: "tun_get_tx_ring"
is_defined: true
symbol_type: FUNCTION
crc: 0x40825473
type_id: 0x83085622
full_name: "tun_get_tx_ring"
}
elf_symbol {
id: 0x7219254d
name: "tun_ptr_free"
is_defined: true
symbol_type: FUNCTION
crc: 0x4099f919
type_id: 0x16b708df
full_name: "tun_ptr_free"
}
elf_symbol {
id: 0xfb5efe2e
name: "typec_altmode_attention"
@@ -419219,6 +419310,7 @@ interface {
symbol_id: 0x57498e16
symbol_id: 0x407c1985
symbol_id: 0x888f691d
symbol_id: 0xa21e8009
symbol_id: 0x86c1623f
symbol_id: 0x36e39cf6
symbol_id: 0x6e37c2ad
@@ -422755,6 +422847,7 @@ interface {
symbol_id: 0x4f384161
symbol_id: 0x79536269
symbol_id: 0xb55db035
symbol_id: 0xede9cf60
symbol_id: 0x4f3dccb0
symbol_id: 0xa341b4f5
symbol_id: 0x7450c7fb
@@ -423231,6 +423324,7 @@ interface {
symbol_id: 0x68c67cd0
symbol_id: 0xc10b3ddb
symbol_id: 0xcd9887e8
symbol_id: 0xb132031d
symbol_id: 0xaec05601
symbol_id: 0x9ebdc6d8
symbol_id: 0x4974f847
@@ -423850,6 +423944,7 @@ interface {
symbol_id: 0xcbabaff3
symbol_id: 0x01afa7bb
symbol_id: 0x3ffae0cf
symbol_id: 0x5d10efc1
symbol_id: 0x0b4dd20d
symbol_id: 0xae3ac3f6
symbol_id: 0xa7c71d5a
@@ -423906,6 +424001,9 @@ interface {
symbol_id: 0x6590f3a5
symbol_id: 0x8e95f895
symbol_id: 0x30438a62
symbol_id: 0xa46589d6
symbol_id: 0x3d3dcefb
symbol_id: 0x7219254d
symbol_id: 0xfb5efe2e
symbol_id: 0x58687602
symbol_id: 0xe7fb597f

View File

@@ -527,6 +527,7 @@
devm_mbox_controller_register
devm_mdiobus_alloc_size
devm_memremap
devm_memremap_pages
devm_mfd_add_devices
devm_nvmem_cell_get
devm_nvmem_device_get
@@ -2363,6 +2364,7 @@
rproc_alloc
rproc_boot
rproc_del
rproc_detach
rproc_free
rproc_get_by_phandle
rproc_put
@@ -2568,6 +2570,7 @@
snd_ctl_boolean_mono_info
snd_jack_set_key
snd_pcm_format_physical_width
snd_pcm_format_set_silence
snd_pcm_format_width
snd_pcm_hw_constraint_integer
snd_pcm_hw_constraint_minmax
@@ -3054,6 +3057,7 @@
try_module_get
try_wait_for_completion
__tty_alloc_driver
tty_buffer_space_avail
tty_chars_in_buffer
tty_driver_flush_buffer
tty_driver_kref_put
@@ -3094,6 +3098,9 @@
tty_vhangup
tty_wakeup
tty_write_room
tun_get_socket
tun_get_tx_ring
tun_ptr_free
typec_get_drvdata
typec_mux_get_drvdata
typec_mux_put

View File

@@ -979,6 +979,9 @@ int init_hyp_tracefs(void)
if (!is_protected_kvm_enabled())
return 0;
for_each_possible_cpu(cpu)
mutex_init(&per_cpu(hyp_trace_reader_lock, cpu));
root_dir = tracefs_create_dir(TRACEFS_DIR, NULL);
if (!root_dir) {
pr_err("Failed to create tracefs "TRACEFS_DIR"/\n");

View File

@@ -104,12 +104,13 @@ static int __fwnode_link_add(struct fwnode_handle *con,
return 0;
}
int fwnode_link_add(struct fwnode_handle *con, struct fwnode_handle *sup)
int fwnode_link_add(struct fwnode_handle *con, struct fwnode_handle *sup,
u8 flags)
{
int ret;
mutex_lock(&fwnode_link_lock);
ret = __fwnode_link_add(con, sup, 0);
ret = __fwnode_link_add(con, sup, flags);
mutex_unlock(&fwnode_link_lock);
return ret;
}
@@ -1082,7 +1083,8 @@ static struct fwnode_handle *fwnode_links_check_suppliers(
return NULL;
list_for_each_entry(link, &fwnode->suppliers, c_hook)
if (!(link->flags & FWLINK_FLAG_CYCLE))
if (!(link->flags &
(FWLINK_FLAG_CYCLE | FWLINK_FLAG_IGNORE)))
return link->supplier;
return NULL;
@@ -1972,6 +1974,9 @@ static bool __fw_devlink_relax_cycles(struct device *con,
}
list_for_each_entry(link, &sup_handle->suppliers, c_hook) {
if (link->flags & FWLINK_FLAG_IGNORE)
continue;
if (__fw_devlink_relax_cycles(con, link->supplier)) {
__fwnode_link_cycle(link);
ret = true;
@@ -2045,6 +2050,9 @@ static int fw_devlink_create_devlink(struct device *con,
int ret = 0;
u32 flags;
if (link->flags & FWLINK_FLAG_IGNORE)
return 0;
if (con->fwnode == link->consumer)
flags = fw_devlink_get_flags(link->flags);
else

View File

@@ -231,20 +231,44 @@ extern const struct scmi_desc scmi_optee_desc;
void scmi_rx_callback(struct scmi_chan_info *cinfo, u32 msg_hdr, void *priv);
void scmi_free_channel(struct scmi_chan_info *cinfo, struct idr *idr, int id);
/* Used for compactness and signature validation of the function pointers being
* passed.
*/
typedef void (*shmem_copy_toio_t)(void __iomem *to, const void *from,
size_t count);
typedef void (*shmem_copy_fromio_t)(void *to, const void __iomem *from,
size_t count);
/**
* struct scmi_shmem_io_ops - I/O operations to read from/write to
* Shared Memory
*
* @toio: Copy data to the shared memory area
* @fromio: Copy data from the shared memory area
*/
struct scmi_shmem_io_ops {
shmem_copy_fromio_t fromio;
shmem_copy_toio_t toio;
};
/* shmem related declarations */
struct scmi_shared_mem;
void shmem_tx_prepare(struct scmi_shared_mem __iomem *shmem,
struct scmi_xfer *xfer, struct scmi_chan_info *cinfo);
struct scmi_xfer *xfer, struct scmi_chan_info *cinfo,
shmem_copy_toio_t toio);
u32 shmem_read_header(struct scmi_shared_mem __iomem *shmem);
void shmem_fetch_response(struct scmi_shared_mem __iomem *shmem,
struct scmi_xfer *xfer);
struct scmi_xfer *xfer,
shmem_copy_fromio_t fromio);
void shmem_fetch_notification(struct scmi_shared_mem __iomem *shmem,
size_t max_len, struct scmi_xfer *xfer);
size_t max_len, struct scmi_xfer *xfer,
shmem_copy_fromio_t fromio);
void shmem_clear_channel(struct scmi_shared_mem __iomem *shmem);
bool shmem_poll_done(struct scmi_shared_mem __iomem *shmem,
struct scmi_xfer *xfer);
bool shmem_channel_free(struct scmi_shared_mem __iomem *shmem);
struct scmi_shmem_io_ops *shmem_get_io_ops(struct device_node *shmem);
/* declarations for message passing transports */
struct scmi_msg_payld;

View File

@@ -23,6 +23,7 @@
* @cinfo: SCMI channel info
* @shmem: Transmit/Receive shared memory area
* @chan_lock: Lock that prevents multiple xfers from being queued
* @io_ops: Transport specific I/O operations
*/
struct scmi_mailbox {
struct mbox_client cl;
@@ -30,6 +31,7 @@ struct scmi_mailbox {
struct scmi_chan_info *cinfo;
struct scmi_shared_mem __iomem *shmem;
struct mutex chan_lock;
struct scmi_shmem_io_ops *io_ops;
};
#define client_to_scmi_mailbox(c) container_of(c, struct scmi_mailbox, cl)
@@ -38,7 +40,8 @@ static void tx_prepare(struct mbox_client *cl, void *m)
{
struct scmi_mailbox *smbox = client_to_scmi_mailbox(cl);
shmem_tx_prepare(smbox->shmem, m, smbox->cinfo);
shmem_tx_prepare(smbox->shmem, m, smbox->cinfo,
smbox->io_ops->toio);
}
static void rx_callback(struct mbox_client *cl, void *m)
@@ -147,6 +150,7 @@ static int mailbox_chan_setup(struct scmi_chan_info *cinfo, struct device *dev,
cl->rx_callback = rx_callback;
cl->tx_block = false;
cl->knows_txdone = tx;
smbox->io_ops = shmem_get_io_ops(shmem);
smbox->chan = mbox_request_channel(cl, tx ? 0 : 1);
if (IS_ERR(smbox->chan)) {
@@ -222,7 +226,7 @@ static void mailbox_fetch_response(struct scmi_chan_info *cinfo,
{
struct scmi_mailbox *smbox = cinfo->transport_info;
shmem_fetch_response(smbox->shmem, xfer);
shmem_fetch_response(smbox->shmem, xfer, smbox->io_ops->fromio);
}
static void mailbox_fetch_notification(struct scmi_chan_info *cinfo,
@@ -230,7 +234,8 @@ static void mailbox_fetch_notification(struct scmi_chan_info *cinfo,
{
struct scmi_mailbox *smbox = cinfo->transport_info;
shmem_fetch_notification(smbox->shmem, max_len, xfer);
shmem_fetch_notification(smbox->shmem, max_len, xfer,
smbox->io_ops->fromio);
}
static void mailbox_clear_channel(struct scmi_chan_info *cinfo)

View File

@@ -111,6 +111,7 @@ enum scmi_optee_pta_cmd {
* @cinfo: SCMI channel information
* @shmem: Virtual base address of the shared memory
* @req: Shared memory protocol handle for SCMI request and synchronous response
* @io_ops: Transport specific I/O operations
* @tee_shm: TEE shared memory handle @req or NULL if using IOMEM shmem
* @link: Reference in agent's channel list
*/
@@ -125,6 +126,7 @@ struct scmi_optee_channel {
struct scmi_shared_mem __iomem *shmem;
struct scmi_msg_payld *msg;
} req;
struct scmi_shmem_io_ops *io_ops;
struct tee_shm *tee_shm;
struct list_head link;
};
@@ -392,6 +394,8 @@ static int setup_static_shmem(struct device *dev, struct scmi_chan_info *cinfo,
goto out;
}
channel->io_ops = shmem_get_io_ops(np);
ret = 0;
out:
@@ -505,7 +509,8 @@ static int scmi_optee_send_message(struct scmi_chan_info *cinfo,
msg_tx_prepare(channel->req.msg, xfer);
ret = invoke_process_msg_channel(channel, msg_command_size(xfer));
} else {
shmem_tx_prepare(channel->req.shmem, xfer, cinfo);
shmem_tx_prepare(channel->req.shmem, xfer, cinfo,
channel->io_ops->toio);
ret = invoke_process_smt_channel(channel);
}
@@ -523,7 +528,8 @@ static void scmi_optee_fetch_response(struct scmi_chan_info *cinfo,
if (channel->tee_shm)
msg_fetch_response(channel->req.msg, channel->rx_len, xfer);
else
shmem_fetch_response(channel->req.shmem, xfer);
shmem_fetch_response(channel->req.shmem, xfer,
channel->io_ops->fromio);
}
static void scmi_optee_mark_txdone(struct scmi_chan_info *cinfo, int ret,

View File

@@ -7,6 +7,7 @@
#include <linux/ktime.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/processor.h>
#include <linux/types.h>
@@ -32,8 +33,58 @@ struct scmi_shared_mem {
u8 msg_payload[];
};
static inline void shmem_memcpy_fromio32(void *to,
const void __iomem *from,
size_t count)
{
WARN_ON(!IS_ALIGNED((unsigned long)from, 4) ||
!IS_ALIGNED((unsigned long)to, 4) ||
count % 4);
__ioread32_copy(to, from, count / 4);
}
static inline void shmem_memcpy_toio32(void __iomem *to,
const void *from,
size_t count)
{
WARN_ON(!IS_ALIGNED((unsigned long)from, 4) ||
!IS_ALIGNED((unsigned long)to, 4) ||
count % 4);
__iowrite32_copy(to, from, count / 4);
}
static struct scmi_shmem_io_ops shmem_io_ops32 = {
.fromio = shmem_memcpy_fromio32,
.toio = shmem_memcpy_toio32,
};
/* Wrappers are needed for proper memcpy_{from,to}_io expansion by the
* pre-processor.
*/
static inline void shmem_memcpy_fromio(void *to,
const void __iomem *from,
size_t count)
{
memcpy_fromio(to, from, count);
}
static inline void shmem_memcpy_toio(void __iomem *to,
const void *from,
size_t count)
{
memcpy_toio(to, from, count);
}
static struct scmi_shmem_io_ops shmem_io_ops_default = {
.fromio = shmem_memcpy_fromio,
.toio = shmem_memcpy_toio,
};
void shmem_tx_prepare(struct scmi_shared_mem __iomem *shmem,
struct scmi_xfer *xfer, struct scmi_chan_info *cinfo)
struct scmi_xfer *xfer, struct scmi_chan_info *cinfo,
shmem_copy_toio_t copy_toio)
{
ktime_t stop;
@@ -70,7 +121,7 @@ void shmem_tx_prepare(struct scmi_shared_mem __iomem *shmem,
iowrite32(sizeof(shmem->msg_header) + xfer->tx.len, &shmem->length);
iowrite32(pack_scmi_header(&xfer->hdr), &shmem->msg_header);
if (xfer->tx.buf)
memcpy_toio(shmem->msg_payload, xfer->tx.buf, xfer->tx.len);
copy_toio(shmem->msg_payload, xfer->tx.buf, xfer->tx.len);
}
u32 shmem_read_header(struct scmi_shared_mem __iomem *shmem)
@@ -79,7 +130,8 @@ u32 shmem_read_header(struct scmi_shared_mem __iomem *shmem)
}
void shmem_fetch_response(struct scmi_shared_mem __iomem *shmem,
struct scmi_xfer *xfer)
struct scmi_xfer *xfer,
shmem_copy_fromio_t copy_fromio)
{
size_t len = ioread32(&shmem->length);
@@ -88,11 +140,12 @@ void shmem_fetch_response(struct scmi_shared_mem __iomem *shmem,
xfer->rx.len = min_t(size_t, xfer->rx.len, len > 8 ? len - 8 : 0);
/* Take a copy to the rx buffer.. */
memcpy_fromio(xfer->rx.buf, shmem->msg_payload + 4, xfer->rx.len);
copy_fromio(xfer->rx.buf, shmem->msg_payload + 4, xfer->rx.len);
}
void shmem_fetch_notification(struct scmi_shared_mem __iomem *shmem,
size_t max_len, struct scmi_xfer *xfer)
size_t max_len, struct scmi_xfer *xfer,
shmem_copy_fromio_t copy_fromio)
{
size_t len = ioread32(&shmem->length);
@@ -100,7 +153,7 @@ void shmem_fetch_notification(struct scmi_shared_mem __iomem *shmem,
xfer->rx.len = min_t(size_t, max_len, len > 4 ? len - 4 : 0);
/* Take a copy to the rx buffer.. */
memcpy_fromio(xfer->rx.buf, shmem->msg_payload, xfer->rx.len);
copy_fromio(xfer->rx.buf, shmem->msg_payload, xfer->rx.len);
}
void shmem_clear_channel(struct scmi_shared_mem __iomem *shmem)
@@ -128,3 +181,16 @@ bool shmem_channel_free(struct scmi_shared_mem __iomem *shmem)
return (ioread32(&shmem->channel_status) &
SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE);
}
struct scmi_shmem_io_ops *shmem_get_io_ops(struct device_node *shmem)
{
u32 reg_io_width;
of_property_read_u32(shmem, "reg-io-width", &reg_io_width);
switch (reg_io_width) {
case 4:
return &shmem_io_ops32;
}
return &shmem_io_ops_default;
}

View File

@@ -26,6 +26,7 @@
* @irq: An optional IRQ for completion
* @cinfo: SCMI channel info
* @shmem: Transmit/Receive shared memory area
* @io_ops: Transport specific I/O operations
* @shmem_lock: Lock to protect access to Tx/Rx shared memory area.
* Used when NOT operating in atomic mode.
* @inflight: Atomic flag to protect access to Tx/Rx shared memory area.
@@ -37,6 +38,7 @@ struct scmi_smc {
int irq;
struct scmi_chan_info *cinfo;
struct scmi_shared_mem __iomem *shmem;
struct scmi_shmem_io_ops *io_ops;
/* Protect access to shmem area */
struct mutex shmem_lock;
#define INFLIGHT_NONE MSG_TOKEN_MAX
@@ -158,6 +160,8 @@ static int smc_chan_setup(struct scmi_chan_info *cinfo, struct device *dev,
cinfo->no_completion_irq = true;
}
scmi_info->io_ops = shmem_get_io_ops(np);
scmi_info->func_id = func_id;
scmi_info->cinfo = cinfo;
smc_channel_lock_init(scmi_info);
@@ -202,7 +206,8 @@ static int smc_send_message(struct scmi_chan_info *cinfo,
*/
smc_channel_lock_acquire(scmi_info, xfer);
shmem_tx_prepare(scmi_info->shmem, xfer, cinfo);
shmem_tx_prepare(scmi_info->shmem, xfer, cinfo,
scmi_info->io_ops->toio);
arm_smccc_1_1_invoke(scmi_info->func_id, 0, 0, 0, 0, 0, 0, 0, &res);
@@ -220,7 +225,8 @@ static void smc_fetch_response(struct scmi_chan_info *cinfo,
{
struct scmi_smc *scmi_info = cinfo->transport_info;
shmem_fetch_response(scmi_info->shmem, xfer);
shmem_fetch_response(scmi_info->shmem, xfer,
scmi_info->io_ops->fromio);
}
static void smc_mark_txdone(struct scmi_chan_info *cinfo, int ret,

View File

@@ -336,7 +336,7 @@ static int efifb_add_links(struct fwnode_handle *fwnode)
if (!sup_np)
return 0;
fwnode_link_add(fwnode, of_fwnode_handle(sup_np));
fwnode_link_add(fwnode, of_fwnode_handle(sup_np), 0);
of_node_put(sup_np);
return 0;

View File

@@ -1095,7 +1095,8 @@ static struct device_node *of_get_compat_node_parent(struct device_node *np)
}
static void of_link_to_phandle(struct device_node *con_np,
struct device_node *sup_np)
struct device_node *sup_np,
u8 flags)
{
struct device_node *tmp_np = of_node_get(sup_np);
@@ -1114,7 +1115,7 @@ static void of_link_to_phandle(struct device_node *con_np,
tmp_np = of_get_next_parent(tmp_np);
}
fwnode_link_add(of_fwnode_handle(con_np), of_fwnode_handle(sup_np));
fwnode_link_add(of_fwnode_handle(con_np), of_fwnode_handle(sup_np), flags);
}
/**
@@ -1227,6 +1228,8 @@ static struct device_node *parse_##fname(struct device_node *np, \
* @node_not_dev: The consumer node containing the property is never converted
* to a struct device. Instead, parse ancestor nodes for the
* compatible property to find a node corresponding to a device.
* @fwlink_flags: Optional fwnode link flags to use when creating a fwnode link
* for this property.
*
* Returns:
* parse_prop() return values are
@@ -1239,6 +1242,7 @@ struct supplier_bindings {
const char *prop_name, int index);
bool optional;
bool node_not_dev;
u8 fwlink_flags;
};
DEFINE_SIMPLE_PROP(clocks, "clocks", "#clock-cells")
@@ -1268,6 +1272,7 @@ DEFINE_SIMPLE_PROP(resets, "resets", "#reset-cells")
DEFINE_SIMPLE_PROP(leds, "leds", NULL)
DEFINE_SIMPLE_PROP(backlight, "backlight", NULL)
DEFINE_SIMPLE_PROP(panel, "panel", NULL)
DEFINE_SIMPLE_PROP(post_init_providers, "post-init-providers", NULL)
DEFINE_SUFFIX_PROP(regulators, "-supply", NULL)
DEFINE_SUFFIX_PROP(gpio, "-gpio", "#gpio-cells")
@@ -1373,6 +1378,10 @@ static const struct supplier_bindings of_supplier_bindings[] = {
{ .parse_prop = parse_regulators, },
{ .parse_prop = parse_gpio, },
{ .parse_prop = parse_gpios, },
{
.parse_prop = parse_post_init_providers,
.fwlink_flags = FWLINK_FLAG_IGNORE,
},
{}
};
@@ -1417,7 +1426,7 @@ static int of_link_property(struct device_node *con_np, const char *prop_name)
: of_node_get(con_np);
matched = true;
i++;
of_link_to_phandle(con_dev_np, phandle);
of_link_to_phandle(con_dev_np, phandle, s->fwlink_flags);
of_node_put(phandle);
of_node_put(con_dev_np);
}

View File

@@ -220,6 +220,9 @@ static int pinctrl_register_one_pin(struct pinctrl_dev *pctldev,
/* Set owner */
pindesc->pctldev = pctldev;
#ifdef CONFIG_PINMUX
mutex_init(&pindesc->mux_lock);
#endif
/* Copy basic pin info */
if (pin->name) {

View File

@@ -167,6 +167,7 @@ struct pin_desc {
const char *mux_owner;
const struct pinctrl_setting_mux *mux_setting;
const char *gpio_owner;
struct mutex mux_lock;
#endif
};

View File

@@ -13,6 +13,7 @@
#define pr_fmt(fmt) "pinmux core: " fmt
#include <linux/ctype.h>
#include <linux/cleanup.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
@@ -90,6 +91,7 @@ bool pinmux_can_be_used_for_gpio(struct pinctrl_dev *pctldev, unsigned pin)
if (!desc || !ops)
return true;
guard(mutex)(&desc->mux_lock);
if (ops->strict && desc->mux_usecount)
return false;
@@ -124,29 +126,31 @@ static int pin_request(struct pinctrl_dev *pctldev,
dev_dbg(pctldev->dev, "request pin %d (%s) for %s\n",
pin, desc->name, owner);
if ((!gpio_range || ops->strict) &&
desc->mux_usecount && strcmp(desc->mux_owner, owner)) {
dev_err(pctldev->dev,
"pin %s already requested by %s; cannot claim for %s\n",
desc->name, desc->mux_owner, owner);
goto out;
}
scoped_guard(mutex, &desc->mux_lock) {
if ((!gpio_range || ops->strict) &&
desc->mux_usecount && strcmp(desc->mux_owner, owner)) {
dev_err(pctldev->dev,
"pin %s already requested by %s; cannot claim for %s\n",
desc->name, desc->mux_owner, owner);
goto out;
}
if ((gpio_range || ops->strict) && desc->gpio_owner) {
dev_err(pctldev->dev,
"pin %s already requested by %s; cannot claim for %s\n",
desc->name, desc->gpio_owner, owner);
goto out;
}
if ((gpio_range || ops->strict) && desc->gpio_owner) {
dev_err(pctldev->dev,
"pin %s already requested by %s; cannot claim for %s\n",
desc->name, desc->gpio_owner, owner);
goto out;
}
if (gpio_range) {
desc->gpio_owner = owner;
} else {
desc->mux_usecount++;
if (desc->mux_usecount > 1)
return 0;
if (gpio_range) {
desc->gpio_owner = owner;
} else {
desc->mux_usecount++;
if (desc->mux_usecount > 1)
return 0;
desc->mux_owner = owner;
desc->mux_owner = owner;
}
}
/* Let each pin increase references to this module */
@@ -177,12 +181,14 @@ static int pin_request(struct pinctrl_dev *pctldev,
out_free_pin:
if (status) {
if (gpio_range) {
desc->gpio_owner = NULL;
} else {
desc->mux_usecount--;
if (!desc->mux_usecount)
desc->mux_owner = NULL;
scoped_guard(mutex, &desc->mux_lock) {
if (gpio_range) {
desc->gpio_owner = NULL;
} else {
desc->mux_usecount--;
if (!desc->mux_usecount)
desc->mux_owner = NULL;
}
}
}
out:
@@ -218,15 +224,17 @@ static const char *pin_free(struct pinctrl_dev *pctldev, int pin,
return NULL;
}
if (!gpio_range) {
/*
* A pin should not be freed more times than allocated.
*/
if (WARN_ON(!desc->mux_usecount))
return NULL;
desc->mux_usecount--;
if (desc->mux_usecount)
return NULL;
scoped_guard(mutex, &desc->mux_lock) {
if (!gpio_range) {
/*
* A pin should not be freed more times than allocated.
*/
if (WARN_ON(!desc->mux_usecount))
return NULL;
desc->mux_usecount--;
if (desc->mux_usecount)
return NULL;
}
}
/*
@@ -238,13 +246,15 @@ static const char *pin_free(struct pinctrl_dev *pctldev, int pin,
else if (ops->free)
ops->free(pctldev, pin);
if (gpio_range) {
owner = desc->gpio_owner;
desc->gpio_owner = NULL;
} else {
owner = desc->mux_owner;
desc->mux_owner = NULL;
desc->mux_setting = NULL;
scoped_guard(mutex, &desc->mux_lock) {
if (gpio_range) {
owner = desc->gpio_owner;
desc->gpio_owner = NULL;
} else {
owner = desc->mux_owner;
desc->mux_owner = NULL;
desc->mux_setting = NULL;
}
}
module_put(pctldev->owner);
@@ -458,7 +468,8 @@ int pinmux_enable_setting(const struct pinctrl_setting *setting)
pins[i]);
continue;
}
desc->mux_setting = &(setting->data.mux);
scoped_guard(mutex, &desc->mux_lock)
desc->mux_setting = &(setting->data.mux);
}
ret = ops->set_mux(pctldev, setting->data.mux.func,
@@ -472,8 +483,10 @@ int pinmux_enable_setting(const struct pinctrl_setting *setting)
err_set_mux:
for (i = 0; i < num_pins; i++) {
desc = pin_desc_get(pctldev, pins[i]);
if (desc)
desc->mux_setting = NULL;
if (desc) {
scoped_guard(mutex, &desc->mux_lock)
desc->mux_setting = NULL;
}
}
err_pin_request:
/* On error release all taken pins */
@@ -492,6 +505,7 @@ void pinmux_disable_setting(const struct pinctrl_setting *setting)
unsigned num_pins = 0;
int i;
struct pin_desc *desc;
bool is_equal;
if (pctlops->get_group_pins)
ret = pctlops->get_group_pins(pctldev, setting->data.mux.group,
@@ -517,7 +531,10 @@ void pinmux_disable_setting(const struct pinctrl_setting *setting)
pins[i]);
continue;
}
if (desc->mux_setting == &(setting->data.mux)) {
scoped_guard(mutex, &desc->mux_lock)
is_equal = (desc->mux_setting == &(setting->data.mux));
if (is_equal) {
pin_free(pctldev, pins[i], NULL);
} else {
const char *gname;
@@ -609,40 +626,42 @@ static int pinmux_pins_show(struct seq_file *s, void *what)
if (desc == NULL)
continue;
if (desc->mux_owner &&
!strcmp(desc->mux_owner, pinctrl_dev_get_name(pctldev)))
is_hog = true;
scoped_guard(mutex, &desc->mux_lock) {
if (desc->mux_owner &&
!strcmp(desc->mux_owner, pinctrl_dev_get_name(pctldev)))
is_hog = true;
if (pmxops->strict) {
if (desc->mux_owner)
seq_printf(s, "pin %d (%s): device %s%s",
pin, desc->name, desc->mux_owner,
if (pmxops->strict) {
if (desc->mux_owner)
seq_printf(s, "pin %d (%s): device %s%s",
pin, desc->name, desc->mux_owner,
is_hog ? " (HOG)" : "");
else if (desc->gpio_owner)
seq_printf(s, "pin %d (%s): GPIO %s",
pin, desc->name, desc->gpio_owner);
else
seq_printf(s, "pin %d (%s): UNCLAIMED",
pin, desc->name);
} else {
/* For non-strict controllers */
seq_printf(s, "pin %d (%s): %s %s%s", pin, desc->name,
desc->mux_owner ? desc->mux_owner
: "(MUX UNCLAIMED)",
desc->gpio_owner ? desc->gpio_owner
: "(GPIO UNCLAIMED)",
is_hog ? " (HOG)" : "");
else if (desc->gpio_owner)
seq_printf(s, "pin %d (%s): GPIO %s",
pin, desc->name, desc->gpio_owner);
else
seq_printf(s, "pin %d (%s): UNCLAIMED",
pin, desc->name);
} else {
/* For non-strict controllers */
seq_printf(s, "pin %d (%s): %s %s%s", pin, desc->name,
desc->mux_owner ? desc->mux_owner
: "(MUX UNCLAIMED)",
desc->gpio_owner ? desc->gpio_owner
: "(GPIO UNCLAIMED)",
is_hog ? " (HOG)" : "");
}
}
/* If mux: print function+group claiming the pin */
if (desc->mux_setting)
seq_printf(s, " function %s group %s\n",
pmxops->get_function_name(pctldev,
desc->mux_setting->func),
pctlops->get_group_name(pctldev,
desc->mux_setting->group));
else
seq_putc(s, '\n');
/* If mux: print function+group claiming the pin */
if (desc->mux_setting)
seq_printf(s, " function %s group %s\n",
pmxops->get_function_name(pctldev,
desc->mux_setting->func),
pctlops->get_group_name(pctldev,
desc->mux_setting->group));
else
seq_putc(s, '\n');
}
}
mutex_unlock(&pctldev->mutex);

View File

@@ -2239,6 +2239,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, bool partial)
@@ -2264,22 +2289,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;
avail_user_block_count = get_available_block_count(sbi, inode, true);
if (!__allow_reserved_blocks(sbi, inode, true))
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;
}
if (unlikely(sbi->total_valid_block_count > avail_user_block_count)) {
if (!partial) {
spin_unlock(&sbi->stat_lock);
@@ -2599,7 +2610,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) {
@@ -2619,21 +2631,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;
valid_block_count = sbi->total_valid_block_count + 1;
avail_user_block_count = get_available_block_count(sbi, inode, false);
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;
if (unlikely(valid_block_count > user_block_count)) {
if (unlikely(valid_block_count > avail_user_block_count)) {
spin_unlock(&sbi->stat_lock);
goto enospc;
}

View File

@@ -639,12 +639,30 @@ static inline bool has_enough_free_secs(struct f2fs_sb_info *sbi,
return !has_not_enough_free_secs(sbi, freed, needed);
}
static inline bool has_enough_free_blks(struct f2fs_sb_info *sbi)
{
unsigned int total_free_blocks = 0;
unsigned int avail_user_block_count;
spin_lock(&sbi->stat_lock);
avail_user_block_count = get_available_block_count(sbi, NULL, true);
total_free_blocks = avail_user_block_count - (unsigned int)valid_user_blocks(sbi);
spin_unlock(&sbi->stat_lock);
return total_free_blocks > 0;
}
static inline bool f2fs_is_checkpoint_ready(struct f2fs_sb_info *sbi)
{
if (likely(!is_sbi_flag_set(sbi, SBI_CP_DISABLED)))
return true;
if (likely(has_enough_free_secs(sbi, 0, 0)))
return true;
if (!f2fs_lfs_mode(sbi) &&
likely(has_enough_free_blks(sbi)))
return true;
return false;
}

View File

@@ -2230,6 +2230,75 @@ static void nfdicf_init(void)
file_fail(fold_name);
}
static void ignore_init(void)
{
FILE *file;
unsigned int unichar;
unsigned int first;
unsigned int last;
unsigned int *um;
int count;
int ret;
if (verbose > 0)
printf("Parsing %s\n", prop_name);
file = fopen(prop_name, "r");
if (!file)
open_fail(prop_name, errno);
assert(file);
count = 0;
while (fgets(line, LINESIZE, file)) {
ret = sscanf(line, "%X..%X ; %s # ", &first, &last, buf0);
if (ret == 3) {
if (strcmp(buf0, "Default_Ignorable_Code_Point"))
continue;
if (!utf32valid(first) || !utf32valid(last))
line_fail(prop_name, line);
for (unichar = first; unichar <= last; unichar++) {
free(unicode_data[unichar].utf32nfdi);
um = malloc(sizeof(unsigned int));
*um = 0;
unicode_data[unichar].utf32nfdi = um;
free(unicode_data[unichar].utf32nfdicf);
um = malloc(sizeof(unsigned int));
*um = 0;
unicode_data[unichar].utf32nfdicf = um;
count++;
}
if (verbose > 1)
printf(" %X..%X Default_Ignorable_Code_Point\n",
first, last);
continue;
}
ret = sscanf(line, "%X ; %s # ", &unichar, buf0);
if (ret == 2) {
if (strcmp(buf0, "Default_Ignorable_Code_Point"))
continue;
if (!utf32valid(unichar))
line_fail(prop_name, line);
free(unicode_data[unichar].utf32nfdi);
um = malloc(sizeof(unsigned int));
*um = 0;
unicode_data[unichar].utf32nfdi = um;
free(unicode_data[unichar].utf32nfdicf);
um = malloc(sizeof(unsigned int));
*um = 0;
unicode_data[unichar].utf32nfdicf = um;
if (verbose > 1)
printf(" %X Default_Ignorable_Code_Point\n",
unichar);
count++;
continue;
}
}
fclose(file);
if (verbose > 0)
printf("Found %d entries\n", count);
if (count == 0)
file_fail(prop_name);
}
static void corrections_init(void)
{
FILE *file;
@@ -3341,6 +3410,7 @@ int main(int argc, char *argv[])
ccc_init();
nfdi_init();
nfdicf_init();
ignore_init();
corrections_init();
hangul_decompose();
nfdi_decompose();

File diff suppressed because it is too large Load Diff

View File

@@ -53,8 +53,10 @@ struct fwnode_handle {
* fwnode link flags
*
* CYCLE: The fwnode link is part of a cycle. Don't defer probe.
* IGNORE: Completely ignore this link, even during cycle detection.
*/
#define FWLINK_FLAG_CYCLE BIT(0)
#define FWLINK_FLAG_IGNORE BIT(1)
struct fwnode_link {
struct fwnode_handle *supplier;
@@ -213,7 +215,8 @@ static inline void fwnode_dev_initialized(struct fwnode_handle *fwnode,
}
extern bool fw_devlink_is_strict(void);
int fwnode_link_add(struct fwnode_handle *con, struct fwnode_handle *sup);
int fwnode_link_add(struct fwnode_handle *con, struct fwnode_handle *sup,
u8 flags);
void fwnode_links_purge(struct fwnode_handle *fwnode);
void fw_devlink_purge_absent_suppliers(struct fwnode_handle *fwnode);

View File

@@ -2814,12 +2814,12 @@ unsigned long __reclaim_pages(struct list_head *folio_list, void *private)
return nr_reclaimed;
}
EXPORT_SYMBOL_GPL(reclaim_pages);
unsigned long reclaim_pages(struct list_head *folio_list)
{
return __reclaim_pages(folio_list, NULL);
}
EXPORT_SYMBOL_GPL(reclaim_pages);
static unsigned long shrink_list(enum lru_list lru, unsigned long nr_to_scan,
struct lruvec *lruvec, struct scan_control *sc)