mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-05 18:41:58 +09:00
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:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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", ®_io_width);
|
||||
switch (reg_io_width) {
|
||||
case 4:
|
||||
return &shmem_io_ops32;
|
||||
}
|
||||
|
||||
return &shmem_io_ops_default;
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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);
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user