Merge 7c8dcac8d7 ("Merge tag 'v6.18-p2' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6") into android-mainline
Steps on the way to v6.18-rc1 Change-Id: Ib27ee401dc393b00bd7e0ddd83c8ec7506bb1131 Signed-off-by: Carlos Llamas <cmllamas@google.com>
This commit is contained in:
commit
b3558dc0f2
59 files changed
+725
-381
No files matched your search
@@ -274,10 +274,6 @@ are the following:
|
||||
The time it takes to switch the CPUs belonging to this policy from one
|
||||
P-state to another, in nanoseconds.
|
||||
|
||||
If unknown or if known to be so high that the scaling driver does not
|
||||
work with the `ondemand`_ governor, -1 (:c:macro:`CPUFREQ_ETERNAL`)
|
||||
will be returned by reads from this attribute.
|
||||
|
||||
``related_cpus``
|
||||
List of all (online and offline) CPUs belonging to this policy.
|
||||
|
||||
|
||||
@@ -109,8 +109,7 @@ Then, the driver must fill in the following values:
|
||||
+-----------------------------------+--------------------------------------+
|
||||
|policy->cpuinfo.transition_latency | the time it takes on this CPU to |
|
||||
| | switch between two frequencies in |
|
||||
| | nanoseconds (if appropriate, else |
|
||||
| | specify CPUFREQ_ETERNAL) |
|
||||
| | nanoseconds |
|
||||
+-----------------------------------+--------------------------------------+
|
||||
|policy->cur | The current operating frequency of |
|
||||
| | this CPU (if appropriate) |
|
||||
|
||||
@@ -112,8 +112,7 @@ CPUfreq核心层注册一个cpufreq_driver结构体。
|
||||
| | |
|
||||
+-----------------------------------+--------------------------------------+
|
||||
|policy->cpuinfo.transition_latency | CPU在两个频率之间切换所需的时间,以 |
|
||||
| | 纳秒为单位(如不适用,设定为 |
|
||||
| | CPUFREQ_ETERNAL) |
|
||||
| | 纳秒为单位 |
|
||||
| | |
|
||||
+-----------------------------------+--------------------------------------+
|
||||
|policy->cur | 该CPU当前的工作频率(如适用) |
|
||||
|
||||
@@ -112,8 +112,7 @@ CPUfreq核心層註冊一個cpufreq_driver結構體。
|
||||
| | |
|
||||
+-----------------------------------+--------------------------------------+
|
||||
|policy->cpuinfo.transition_latency | CPU在兩個頻率之間切換所需的時間,以 |
|
||||
| | 納秒爲單位(如不適用,設定爲 |
|
||||
| | CPUFREQ_ETERNAL) |
|
||||
| | 納秒爲單位 |
|
||||
| | |
|
||||
+-----------------------------------+--------------------------------------+
|
||||
|policy->cur | 該CPU當前的工作頻率(如適用) |
|
||||
|
||||
+7
-7
@@ -21954,13 +21954,6 @@ S: Maintained
|
||||
F: Documentation/devicetree/bindings/iio/potentiometer/renesas,x9250.yaml
|
||||
F: drivers/iio/potentiometer/x9250.c
|
||||
|
||||
RENESAS RZ/G3S THERMAL SENSOR UNIT DRIVER
|
||||
M: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
|
||||
L: linux-pm@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/thermal/renesas,r9a08g045-tsu.yaml
|
||||
F: drivers/thermal/renesas/rzg3s_thermal.c
|
||||
|
||||
RENESAS RZ/G3E THERMAL SENSOR UNIT DRIVER
|
||||
M: John Madieu <john.madieu.xa@bp.renesas.com>
|
||||
L: linux-pm@vger.kernel.org
|
||||
@@ -21968,6 +21961,13 @@ S: Maintained
|
||||
F: Documentation/devicetree/bindings/thermal/renesas,r9a09g047-tsu.yaml
|
||||
F: drivers/thermal/renesas/rzg3e_thermal.c
|
||||
|
||||
RENESAS RZ/G3S THERMAL SENSOR UNIT DRIVER
|
||||
M: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
|
||||
L: linux-pm@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/thermal/renesas,r9a08g045-tsu.yaml
|
||||
F: drivers/thermal/renesas/rzg3s_thermal.c
|
||||
|
||||
RESET CONTROLLER FRAMEWORK
|
||||
M: Philipp Zabel <p.zabel@pengutronix.de>
|
||||
S: Maintained
|
||||
|
||||
@@ -110,6 +110,7 @@ config ARM
|
||||
select HAVE_GUP_FAST if ARM_LPAE
|
||||
select HAVE_FUNCTION_ERROR_INJECTION
|
||||
select HAVE_FUNCTION_GRAPH_TRACER
|
||||
select HAVE_FUNCTION_GRAPH_FREGS
|
||||
select HAVE_FUNCTION_TRACER if !XIP_KERNEL
|
||||
select HAVE_GCC_PLUGINS
|
||||
select HAVE_HW_BREAKPOINT if PERF_EVENTS && (CPU_V6 || CPU_V6K || CPU_V7)
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/string_choices.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
@@ -337,8 +338,8 @@ void pcibios_fixup_bus(struct pci_bus *bus)
|
||||
/*
|
||||
* Report what we did for this bus
|
||||
*/
|
||||
pr_info("PCI: bus%d: Fast back to back transfers %sabled\n",
|
||||
bus->number, (features & PCI_COMMAND_FAST_BACK) ? "en" : "dis");
|
||||
pr_info("PCI: bus%d: Fast back to back transfers %s\n",
|
||||
bus->number, str_enabled_disabled(features & PCI_COMMAND_FAST_BACK));
|
||||
}
|
||||
EXPORT_SYMBOL(pcibios_fixup_bus);
|
||||
|
||||
|
||||
@@ -257,11 +257,21 @@ ENDPROC(ftrace_graph_regs_caller)
|
||||
|
||||
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
|
||||
ENTRY(return_to_handler)
|
||||
stmdb sp!, {r0-r3}
|
||||
add r0, sp, #16 @ sp at exit of instrumented routine
|
||||
mov ip, sp @ sp at exit of instrumented routine
|
||||
sub sp, #PT_REGS_SIZE
|
||||
str r0, [sp, #S_R0]
|
||||
str r1, [sp, #S_R1]
|
||||
str r2, [sp, #S_R2]
|
||||
str r3, [sp, #S_R3]
|
||||
str ip, [sp, #S_FP]
|
||||
mov r0, sp
|
||||
bl ftrace_return_to_handler
|
||||
mov lr, r0 @ r0 has real ret addr
|
||||
ldmia sp!, {r0-r3}
|
||||
mov lr, r0 @ r0 has real ret addr
|
||||
ldr r3, [sp, #S_R3]
|
||||
ldr r2, [sp, #S_R2]
|
||||
ldr r1, [sp, #S_R1]
|
||||
ldr r0, [sp, #S_R0]
|
||||
add sp, sp, #PT_REGS_SIZE @ restore stack pointer
|
||||
ret lr
|
||||
ENDPROC(return_to_handler)
|
||||
#endif
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <linux/io.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/string_choices.h>
|
||||
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/cp15.h>
|
||||
@@ -667,9 +668,9 @@ static void __init l2c310_enable(void __iomem *base, unsigned num_lock)
|
||||
u32 power_ctrl;
|
||||
|
||||
power_ctrl = readl_relaxed(base + L310_POWER_CTRL);
|
||||
pr_info("L2C-310 dynamic clock gating %sabled, standby mode %sabled\n",
|
||||
power_ctrl & L310_DYNAMIC_CLK_GATING_EN ? "en" : "dis",
|
||||
power_ctrl & L310_STNDBY_MODE_EN ? "en" : "dis");
|
||||
pr_info("L2C-310 dynamic clock gating %s, standby mode %s\n",
|
||||
str_enabled_disabled(power_ctrl & L310_DYNAMIC_CLK_GATING_EN),
|
||||
str_enabled_disabled(power_ctrl & L310_STNDBY_MODE_EN));
|
||||
}
|
||||
|
||||
if (aux & L310_AUX_CTRL_FULL_LINE_ZERO)
|
||||
|
||||
+1
-2
@@ -135,8 +135,7 @@ static void die_kernel_fault(const char *msg, struct mm_struct *mm,
|
||||
bust_spinlocks(1);
|
||||
pr_alert("8<--- cut here ---\n");
|
||||
pr_alert("Unable to handle kernel %s at virtual address %08lx when %s\n",
|
||||
msg, addr, fsr & FSR_LNX_PF ? "execute" :
|
||||
fsr & FSR_WRITE ? "write" : "read");
|
||||
msg, addr, fsr & FSR_LNX_PF ? "execute" : str_write_read(fsr & FSR_WRITE));
|
||||
|
||||
show_pte(KERN_ALERT, mm, addr);
|
||||
die("Oops", regs, fsr);
|
||||
|
||||
@@ -89,7 +89,7 @@ void acpi_processor_power_init_bm_check(struct acpi_processor_flags *flags,
|
||||
*/
|
||||
flags->bm_control = 0;
|
||||
}
|
||||
if (c->x86_vendor == X86_VENDOR_AMD && c->x86 >= 0x17) {
|
||||
if (cpu_feature_enabled(X86_FEATURE_ZEN)) {
|
||||
/*
|
||||
* For all AMD Zen or newer CPUs that support C3, caches
|
||||
* should not be flushed by software while entering C3
|
||||
|
||||
@@ -168,6 +168,11 @@ out:
|
||||
EXPORT_SYMBOL_GPL(crypto_del_default_rng);
|
||||
#endif
|
||||
|
||||
static void rng_default_set_ent(struct crypto_rng *tfm, const u8 *data,
|
||||
unsigned int len)
|
||||
{
|
||||
}
|
||||
|
||||
int crypto_register_rng(struct rng_alg *alg)
|
||||
{
|
||||
struct crypto_alg *base = &alg->base;
|
||||
@@ -179,6 +184,9 @@ int crypto_register_rng(struct rng_alg *alg)
|
||||
base->cra_flags &= ~CRYPTO_ALG_TYPE_MASK;
|
||||
base->cra_flags |= CRYPTO_ALG_TYPE_RNG;
|
||||
|
||||
if (!alg->set_ent)
|
||||
alg->set_ent = rng_default_set_ent;
|
||||
|
||||
return crypto_register_alg(base);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(crypto_register_rng);
|
||||
|
||||
@@ -4187,6 +4187,7 @@ static const struct alg_test_desc alg_test_descs[] = {
|
||||
.alg = "authenc(hmac(sha1),cbc(aes))",
|
||||
.generic_driver = "authenc(hmac-sha1-lib,cbc(aes-generic))",
|
||||
.test = alg_test_aead,
|
||||
.fips_allowed = 1,
|
||||
.suite = {
|
||||
.aead = __VECS(hmac_sha1_aes_cbc_tv_temp)
|
||||
}
|
||||
@@ -4207,6 +4208,7 @@ static const struct alg_test_desc alg_test_descs[] = {
|
||||
}, {
|
||||
.alg = "authenc(hmac(sha1),ctr(aes))",
|
||||
.test = alg_test_null,
|
||||
.fips_allowed = 1,
|
||||
}, {
|
||||
.alg = "authenc(hmac(sha1),ecb(cipher_null))",
|
||||
.generic_driver = "authenc(hmac-sha1-lib,ecb-cipher_null)",
|
||||
@@ -4217,6 +4219,7 @@ static const struct alg_test_desc alg_test_descs[] = {
|
||||
}, {
|
||||
.alg = "authenc(hmac(sha1),rfc3686(ctr(aes)))",
|
||||
.test = alg_test_null,
|
||||
.fips_allowed = 1,
|
||||
}, {
|
||||
.alg = "authenc(hmac(sha224),cbc(des))",
|
||||
.generic_driver = "authenc(hmac-sha224-lib,cbc(des-generic))",
|
||||
@@ -5075,6 +5078,7 @@ static const struct alg_test_desc alg_test_descs[] = {
|
||||
.alg = "hmac(sha1)",
|
||||
.generic_driver = "hmac-sha1-lib",
|
||||
.test = alg_test_hash,
|
||||
.fips_allowed = 1,
|
||||
.suite = {
|
||||
.hash = __VECS(hmac_sha1_tv_template)
|
||||
}
|
||||
@@ -5448,6 +5452,7 @@ static const struct alg_test_desc alg_test_descs[] = {
|
||||
.alg = "sha1",
|
||||
.generic_driver = "sha1-lib",
|
||||
.test = alg_test_hash,
|
||||
.fips_allowed = 1,
|
||||
.suite = {
|
||||
.hash = __VECS(sha1_tv_template)
|
||||
}
|
||||
|
||||
+1
-1
@@ -83,7 +83,7 @@ static void zstd_exit(struct crypto_acomp *acomp_tfm)
|
||||
static int zstd_compress_one(struct acomp_req *req, struct zstd_ctx *ctx,
|
||||
const void *src, void *dst, unsigned int *dlen)
|
||||
{
|
||||
unsigned int out_len;
|
||||
size_t out_len;
|
||||
|
||||
ctx->cctx = zstd_init_cctx(ctx->wksp, ctx->wksp_size);
|
||||
if (!ctx->cctx)
|
||||
|
||||
@@ -1207,12 +1207,10 @@ static int ghes_notify_hed(struct notifier_block *this, unsigned long event,
|
||||
int ret = NOTIFY_DONE;
|
||||
|
||||
spin_lock_irqsave(&ghes_notify_lock_irq, flags);
|
||||
rcu_read_lock();
|
||||
list_for_each_entry_rcu(ghes, &ghes_hed, list) {
|
||||
if (!ghes_proc(ghes))
|
||||
ret = NOTIFY_OK;
|
||||
}
|
||||
rcu_read_unlock();
|
||||
spin_unlock_irqrestore(&ghes_notify_lock_irq, flags);
|
||||
|
||||
return ret;
|
||||
|
||||
+29
-14
@@ -92,7 +92,7 @@ enum {
|
||||
|
||||
struct acpi_battery {
|
||||
struct mutex lock;
|
||||
struct mutex sysfs_lock;
|
||||
struct mutex update_lock;
|
||||
struct power_supply *bat;
|
||||
struct power_supply_desc bat_desc;
|
||||
struct acpi_device *device;
|
||||
@@ -904,15 +904,12 @@ static int sysfs_add_battery(struct acpi_battery *battery)
|
||||
|
||||
static void sysfs_remove_battery(struct acpi_battery *battery)
|
||||
{
|
||||
mutex_lock(&battery->sysfs_lock);
|
||||
if (!battery->bat) {
|
||||
mutex_unlock(&battery->sysfs_lock);
|
||||
if (!battery->bat)
|
||||
return;
|
||||
}
|
||||
|
||||
battery_hook_remove_battery(battery);
|
||||
power_supply_unregister(battery->bat);
|
||||
battery->bat = NULL;
|
||||
mutex_unlock(&battery->sysfs_lock);
|
||||
}
|
||||
|
||||
static void find_battery(const struct dmi_header *dm, void *private)
|
||||
@@ -1072,6 +1069,9 @@ static void acpi_battery_notify(acpi_handle handle, u32 event, void *data)
|
||||
|
||||
if (!battery)
|
||||
return;
|
||||
|
||||
guard(mutex)(&battery->update_lock);
|
||||
|
||||
old = battery->bat;
|
||||
/*
|
||||
* On Acer Aspire V5-573G notifications are sometimes triggered too
|
||||
@@ -1094,21 +1094,22 @@ static void acpi_battery_notify(acpi_handle handle, u32 event, void *data)
|
||||
}
|
||||
|
||||
static int battery_notify(struct notifier_block *nb,
|
||||
unsigned long mode, void *_unused)
|
||||
unsigned long mode, void *_unused)
|
||||
{
|
||||
struct acpi_battery *battery = container_of(nb, struct acpi_battery,
|
||||
pm_nb);
|
||||
int result;
|
||||
|
||||
switch (mode) {
|
||||
case PM_POST_HIBERNATION:
|
||||
case PM_POST_SUSPEND:
|
||||
if (mode == PM_POST_SUSPEND || mode == PM_POST_HIBERNATION) {
|
||||
guard(mutex)(&battery->update_lock);
|
||||
|
||||
if (!acpi_battery_present(battery))
|
||||
return 0;
|
||||
|
||||
if (battery->bat) {
|
||||
acpi_battery_refresh(battery);
|
||||
} else {
|
||||
int result;
|
||||
|
||||
result = acpi_battery_get_info(battery);
|
||||
if (result)
|
||||
return result;
|
||||
@@ -1120,7 +1121,6 @@ static int battery_notify(struct notifier_block *nb,
|
||||
|
||||
acpi_battery_init_alarm(battery);
|
||||
acpi_battery_get_state(battery);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -1198,6 +1198,8 @@ static int acpi_battery_update_retry(struct acpi_battery *battery)
|
||||
{
|
||||
int retry, ret;
|
||||
|
||||
guard(mutex)(&battery->update_lock);
|
||||
|
||||
for (retry = 5; retry; retry--) {
|
||||
ret = acpi_battery_update(battery, false);
|
||||
if (!ret)
|
||||
@@ -1208,6 +1210,13 @@ static int acpi_battery_update_retry(struct acpi_battery *battery)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void sysfs_battery_cleanup(struct acpi_battery *battery)
|
||||
{
|
||||
guard(mutex)(&battery->update_lock);
|
||||
|
||||
sysfs_remove_battery(battery);
|
||||
}
|
||||
|
||||
static int acpi_battery_add(struct acpi_device *device)
|
||||
{
|
||||
int result = 0;
|
||||
@@ -1230,7 +1239,7 @@ static int acpi_battery_add(struct acpi_device *device)
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
result = devm_mutex_init(&device->dev, &battery->sysfs_lock);
|
||||
result = devm_mutex_init(&device->dev, &battery->update_lock);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
@@ -1262,7 +1271,7 @@ fail_pm:
|
||||
device_init_wakeup(&device->dev, 0);
|
||||
unregister_pm_notifier(&battery->pm_nb);
|
||||
fail:
|
||||
sysfs_remove_battery(battery);
|
||||
sysfs_battery_cleanup(battery);
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -1281,6 +1290,9 @@ static void acpi_battery_remove(struct acpi_device *device)
|
||||
|
||||
device_init_wakeup(&device->dev, 0);
|
||||
unregister_pm_notifier(&battery->pm_nb);
|
||||
|
||||
guard(mutex)(&battery->update_lock);
|
||||
|
||||
sysfs_remove_battery(battery);
|
||||
}
|
||||
|
||||
@@ -1297,6 +1309,9 @@ static int acpi_battery_resume(struct device *dev)
|
||||
return -EINVAL;
|
||||
|
||||
battery->update_time = 0;
|
||||
|
||||
guard(mutex)(&battery->update_lock);
|
||||
|
||||
acpi_battery_update(battery, true);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1876,7 +1876,7 @@ EXPORT_SYMBOL_GPL(cppc_set_perf);
|
||||
* If desired_reg is in the SystemMemory or SystemIo ACPI address space,
|
||||
* then assume there is no latency.
|
||||
*/
|
||||
unsigned int cppc_get_transition_latency(int cpu_num)
|
||||
int cppc_get_transition_latency(int cpu_num)
|
||||
{
|
||||
/*
|
||||
* Expected transition latency is based on the PCCT timing values
|
||||
@@ -1889,31 +1889,29 @@ unsigned int cppc_get_transition_latency(int cpu_num)
|
||||
* completion of a command before issuing the next command,
|
||||
* in microseconds.
|
||||
*/
|
||||
unsigned int latency_ns = 0;
|
||||
struct cpc_desc *cpc_desc;
|
||||
struct cpc_register_resource *desired_reg;
|
||||
int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpu_num);
|
||||
struct cppc_pcc_data *pcc_ss_data;
|
||||
int latency_ns = 0;
|
||||
|
||||
cpc_desc = per_cpu(cpc_desc_ptr, cpu_num);
|
||||
if (!cpc_desc)
|
||||
return CPUFREQ_ETERNAL;
|
||||
return -ENODATA;
|
||||
|
||||
desired_reg = &cpc_desc->cpc_regs[DESIRED_PERF];
|
||||
if (CPC_IN_SYSTEM_MEMORY(desired_reg) || CPC_IN_SYSTEM_IO(desired_reg))
|
||||
return 0;
|
||||
else if (!CPC_IN_PCC(desired_reg))
|
||||
return CPUFREQ_ETERNAL;
|
||||
|
||||
if (pcc_ss_id < 0)
|
||||
return CPUFREQ_ETERNAL;
|
||||
if (!CPC_IN_PCC(desired_reg) || pcc_ss_id < 0)
|
||||
return -ENODATA;
|
||||
|
||||
pcc_ss_data = pcc_data[pcc_ss_id];
|
||||
if (pcc_ss_data->pcc_mpar)
|
||||
latency_ns = 60 * (1000 * 1000 * 1000 / pcc_ss_data->pcc_mpar);
|
||||
|
||||
latency_ns = max(latency_ns, pcc_ss_data->pcc_nominal * 1000);
|
||||
latency_ns = max(latency_ns, pcc_ss_data->pcc_mrtt * 1000);
|
||||
latency_ns = max_t(int, latency_ns, pcc_ss_data->pcc_nominal * 1000);
|
||||
latency_ns = max_t(int, latency_ns, pcc_ss_data->pcc_mrtt * 1000);
|
||||
|
||||
return latency_ns;
|
||||
}
|
||||
|
||||
+23
-1
@@ -1388,6 +1388,28 @@ struct fwnode_handle *acpi_get_next_subnode(const struct fwnode_handle *fwnode,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* acpi_get_next_present_subnode - Return the next present child node handle
|
||||
* @fwnode: Firmware node to find the next child node for.
|
||||
* @child: Handle to one of the device's child nodes or a null handle.
|
||||
*
|
||||
* Like acpi_get_next_subnode(), but the device nodes returned by
|
||||
* acpi_get_next_present_subnode() are guaranteed to be present.
|
||||
*
|
||||
* Returns: The fwnode handle of the next present sub-node.
|
||||
*/
|
||||
static struct fwnode_handle *
|
||||
acpi_get_next_present_subnode(const struct fwnode_handle *fwnode,
|
||||
struct fwnode_handle *child)
|
||||
{
|
||||
do {
|
||||
child = acpi_get_next_subnode(fwnode, child);
|
||||
} while (is_acpi_device_node(child) &&
|
||||
!acpi_device_is_present(to_acpi_device_node(child)));
|
||||
|
||||
return child;
|
||||
}
|
||||
|
||||
/**
|
||||
* acpi_node_get_parent - Return parent fwnode of this fwnode
|
||||
* @fwnode: Firmware node whose parent to get
|
||||
@@ -1722,7 +1744,7 @@ static int acpi_fwnode_irq_get(const struct fwnode_handle *fwnode,
|
||||
.property_read_string_array = \
|
||||
acpi_fwnode_property_read_string_array, \
|
||||
.get_parent = acpi_node_get_parent, \
|
||||
.get_next_child_node = acpi_get_next_subnode, \
|
||||
.get_next_child_node = acpi_get_next_present_subnode, \
|
||||
.get_named_child_node = acpi_fwnode_get_named_child_node, \
|
||||
.get_name = acpi_fwnode_get_name, \
|
||||
.get_name_prefix = acpi_fwnode_get_name_prefix, \
|
||||
|
||||
@@ -167,6 +167,12 @@ config PM_QOS_KUNIT_TEST
|
||||
depends on KUNIT=y
|
||||
default KUNIT_ALL_TESTS
|
||||
|
||||
config PM_RUNTIME_KUNIT_TEST
|
||||
tristate "KUnit Tests for runtime PM" if !KUNIT_ALL_TESTS
|
||||
depends on KUNIT
|
||||
depends on PM
|
||||
default KUNIT_ALL_TESTS
|
||||
|
||||
config HMEM_REPORTING
|
||||
bool
|
||||
default n
|
||||
|
||||
@@ -248,6 +248,7 @@ void device_links_driver_cleanup(struct device *dev);
|
||||
void device_links_no_driver(struct device *dev);
|
||||
bool device_links_busy(struct device *dev);
|
||||
void device_links_unbind_consumers(struct device *dev);
|
||||
bool device_link_flag_is_sync_state_only(u32 flags);
|
||||
void fw_devlink_drivers_done(void);
|
||||
void fw_devlink_probing_done(void);
|
||||
|
||||
|
||||
+1
-1
@@ -287,7 +287,7 @@ static bool device_is_ancestor(struct device *dev, struct device *target)
|
||||
#define DL_MARKER_FLAGS (DL_FLAG_INFERRED | \
|
||||
DL_FLAG_CYCLE | \
|
||||
DL_FLAG_MANAGED)
|
||||
static inline bool device_link_flag_is_sync_state_only(u32 flags)
|
||||
bool device_link_flag_is_sync_state_only(u32 flags)
|
||||
{
|
||||
return (flags & ~DL_MARKER_FLAGS) == DL_FLAG_SYNC_STATE_ONLY;
|
||||
}
|
||||
|
||||
@@ -4,5 +4,6 @@ obj-$(CONFIG_PM_SLEEP) += main.o wakeup.o wakeup_stats.o
|
||||
obj-$(CONFIG_PM_TRACE_RTC) += trace.o
|
||||
obj-$(CONFIG_HAVE_CLK) += clock_ops.o
|
||||
obj-$(CONFIG_PM_QOS_KUNIT_TEST) += qos-test.o
|
||||
obj-$(CONFIG_PM_RUNTIME_KUNIT_TEST) += runtime-test.o
|
||||
|
||||
ccflags-$(CONFIG_DEBUG_DRIVER) := -DDEBUG
|
||||
@@ -280,7 +280,8 @@ static void dpm_wait_for_suppliers(struct device *dev, bool async)
|
||||
* walking.
|
||||
*/
|
||||
dev_for_each_link_to_supplier(link, dev)
|
||||
if (READ_ONCE(link->status) != DL_STATE_DORMANT)
|
||||
if (READ_ONCE(link->status) != DL_STATE_DORMANT &&
|
||||
!device_link_flag_is_sync_state_only(link->flags))
|
||||
dpm_wait(link->supplier, async);
|
||||
|
||||
device_links_read_unlock(idx);
|
||||
@@ -337,7 +338,8 @@ static void dpm_wait_for_consumers(struct device *dev, bool async)
|
||||
* unregistration).
|
||||
*/
|
||||
dev_for_each_link_to_consumer(link, dev)
|
||||
if (READ_ONCE(link->status) != DL_STATE_DORMANT)
|
||||
if (READ_ONCE(link->status) != DL_STATE_DORMANT &&
|
||||
!device_link_flag_is_sync_state_only(link->flags))
|
||||
dpm_wait(link->consumer, async);
|
||||
|
||||
device_links_read_unlock(idx);
|
||||
|
||||
@@ -0,0 +1,253 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright 2025 Google, Inc.
|
||||
*/
|
||||
|
||||
#include <linux/cleanup.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <kunit/device.h>
|
||||
#include <kunit/test.h>
|
||||
|
||||
#define DEVICE_NAME "pm_runtime_test_device"
|
||||
|
||||
static void pm_runtime_depth_test(struct kunit *test)
|
||||
{
|
||||
struct device *dev = kunit_device_register(test, DEVICE_NAME);
|
||||
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
|
||||
|
||||
pm_runtime_enable(dev);
|
||||
|
||||
KUNIT_EXPECT_TRUE(test, pm_runtime_suspended(dev));
|
||||
KUNIT_EXPECT_EQ(test, 0, pm_runtime_get_sync(dev));
|
||||
KUNIT_EXPECT_TRUE(test, pm_runtime_active(dev));
|
||||
KUNIT_EXPECT_EQ(test, 1, pm_runtime_get_sync(dev)); /* "already active" */
|
||||
KUNIT_EXPECT_EQ(test, 0, pm_runtime_put_sync(dev));
|
||||
KUNIT_EXPECT_EQ(test, 0, pm_runtime_put_sync(dev));
|
||||
KUNIT_EXPECT_TRUE(test, pm_runtime_suspended(dev));
|
||||
}
|
||||
|
||||
/* Test pm_runtime_put() and friends when already suspended. */
|
||||
static void pm_runtime_already_suspended_test(struct kunit *test)
|
||||
{
|
||||
struct device *dev = kunit_device_register(test, DEVICE_NAME);
|
||||
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
|
||||
|
||||
pm_runtime_enable(dev);
|
||||
KUNIT_EXPECT_TRUE(test, pm_runtime_suspended(dev));
|
||||
|
||||
pm_runtime_get_noresume(dev);
|
||||
KUNIT_EXPECT_EQ(test, 0, pm_runtime_barrier(dev)); /* no wakeup needed */
|
||||
pm_runtime_put(dev);
|
||||
|
||||
pm_runtime_get_noresume(dev);
|
||||
KUNIT_EXPECT_EQ(test, 1, pm_runtime_put_sync(dev));
|
||||
|
||||
KUNIT_EXPECT_EQ(test, 1, pm_runtime_suspend(dev));
|
||||
KUNIT_EXPECT_EQ(test, 1, pm_runtime_autosuspend(dev));
|
||||
KUNIT_EXPECT_EQ(test, 1, pm_request_autosuspend(dev));
|
||||
|
||||
pm_runtime_get_noresume(dev);
|
||||
KUNIT_EXPECT_EQ(test, 1, pm_runtime_put_sync_autosuspend(dev));
|
||||
|
||||
pm_runtime_get_noresume(dev);
|
||||
pm_runtime_put_autosuspend(dev);
|
||||
|
||||
/* Grab 2 refcounts */
|
||||
pm_runtime_get_noresume(dev);
|
||||
pm_runtime_get_noresume(dev);
|
||||
/* The first put() sees usage_count 1 */
|
||||
KUNIT_EXPECT_EQ(test, 0, pm_runtime_put_sync_autosuspend(dev));
|
||||
/* The second put() sees usage_count 0 but tells us "already suspended". */
|
||||
KUNIT_EXPECT_EQ(test, 1, pm_runtime_put_sync_autosuspend(dev));
|
||||
|
||||
/* Should have remained suspended the whole time. */
|
||||
KUNIT_EXPECT_TRUE(test, pm_runtime_suspended(dev));
|
||||
}
|
||||
|
||||
static void pm_runtime_idle_test(struct kunit *test)
|
||||
{
|
||||
struct device *dev = kunit_device_register(test, DEVICE_NAME);
|
||||
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
|
||||
|
||||
pm_runtime_enable(dev);
|
||||
|
||||
KUNIT_EXPECT_TRUE(test, pm_runtime_suspended(dev));
|
||||
KUNIT_EXPECT_EQ(test, 0, pm_runtime_get_sync(dev));
|
||||
KUNIT_EXPECT_TRUE(test, pm_runtime_active(dev));
|
||||
KUNIT_EXPECT_EQ(test, -EAGAIN, pm_runtime_idle(dev));
|
||||
KUNIT_EXPECT_TRUE(test, pm_runtime_active(dev));
|
||||
pm_runtime_put_noidle(dev);
|
||||
KUNIT_EXPECT_TRUE(test, pm_runtime_active(dev));
|
||||
KUNIT_EXPECT_EQ(test, 0, pm_runtime_idle(dev));
|
||||
KUNIT_EXPECT_TRUE(test, pm_runtime_suspended(dev));
|
||||
KUNIT_EXPECT_EQ(test, -EAGAIN, pm_runtime_idle(dev));
|
||||
KUNIT_EXPECT_EQ(test, -EAGAIN, pm_request_idle(dev));
|
||||
}
|
||||
|
||||
static void pm_runtime_disabled_test(struct kunit *test)
|
||||
{
|
||||
struct device *dev = kunit_device_register(test, DEVICE_NAME);
|
||||
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
|
||||
|
||||
/* Never called pm_runtime_enable() */
|
||||
KUNIT_EXPECT_FALSE(test, pm_runtime_enabled(dev));
|
||||
|
||||
/* "disabled" is treated as "active" */
|
||||
KUNIT_EXPECT_TRUE(test, pm_runtime_active(dev));
|
||||
KUNIT_EXPECT_FALSE(test, pm_runtime_suspended(dev));
|
||||
|
||||
/*
|
||||
* Note: these "fail", but they still acquire/release refcounts, so
|
||||
* keep them balanced.
|
||||
*/
|
||||
KUNIT_EXPECT_EQ(test, -EACCES, pm_runtime_get(dev));
|
||||
pm_runtime_put(dev);
|
||||
|
||||
KUNIT_EXPECT_EQ(test, -EACCES, pm_runtime_get_sync(dev));
|
||||
KUNIT_EXPECT_EQ(test, -EACCES, pm_runtime_put_sync(dev));
|
||||
|
||||
KUNIT_EXPECT_EQ(test, -EACCES, pm_runtime_get(dev));
|
||||
pm_runtime_put_autosuspend(dev);
|
||||
|
||||
KUNIT_EXPECT_EQ(test, -EACCES, pm_runtime_resume_and_get(dev));
|
||||
KUNIT_EXPECT_EQ(test, -EACCES, pm_runtime_idle(dev));
|
||||
KUNIT_EXPECT_EQ(test, -EACCES, pm_request_idle(dev));
|
||||
KUNIT_EXPECT_EQ(test, -EACCES, pm_request_resume(dev));
|
||||
KUNIT_EXPECT_EQ(test, -EACCES, pm_request_autosuspend(dev));
|
||||
KUNIT_EXPECT_EQ(test, -EACCES, pm_runtime_suspend(dev));
|
||||
KUNIT_EXPECT_EQ(test, -EACCES, pm_runtime_resume(dev));
|
||||
KUNIT_EXPECT_EQ(test, -EACCES, pm_runtime_autosuspend(dev));
|
||||
|
||||
/* Still disabled */
|
||||
KUNIT_EXPECT_TRUE(test, pm_runtime_active(dev));
|
||||
KUNIT_EXPECT_FALSE(test, pm_runtime_enabled(dev));
|
||||
}
|
||||
|
||||
static void pm_runtime_error_test(struct kunit *test)
|
||||
{
|
||||
struct device *dev = kunit_device_register(test, DEVICE_NAME);
|
||||
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
|
||||
|
||||
pm_runtime_enable(dev);
|
||||
KUNIT_EXPECT_TRUE(test, pm_runtime_suspended(dev));
|
||||
|
||||
/* Fake a .runtime_resume() error */
|
||||
dev->power.runtime_error = -EIO;
|
||||
|
||||
/*
|
||||
* Note: these "fail", but they still acquire/release refcounts, so
|
||||
* keep them balanced.
|
||||
*/
|
||||
KUNIT_EXPECT_EQ(test, -EINVAL, pm_runtime_get(dev));
|
||||
pm_runtime_put(dev);
|
||||
|
||||
KUNIT_EXPECT_EQ(test, -EINVAL, pm_runtime_get_sync(dev));
|
||||
KUNIT_EXPECT_EQ(test, -EINVAL, pm_runtime_put_sync(dev));
|
||||
|
||||
KUNIT_EXPECT_EQ(test, -EINVAL, pm_runtime_get(dev));
|
||||
pm_runtime_put_autosuspend(dev);
|
||||
|
||||
KUNIT_EXPECT_EQ(test, -EINVAL, pm_runtime_get(dev));
|
||||
KUNIT_EXPECT_EQ(test, -EINVAL, pm_runtime_put_sync_autosuspend(dev));
|
||||
|
||||
KUNIT_EXPECT_EQ(test, -EINVAL, pm_runtime_resume_and_get(dev));
|
||||
KUNIT_EXPECT_EQ(test, -EINVAL, pm_runtime_idle(dev));
|
||||
KUNIT_EXPECT_EQ(test, -EINVAL, pm_request_idle(dev));
|
||||
KUNIT_EXPECT_EQ(test, -EINVAL, pm_request_resume(dev));
|
||||
KUNIT_EXPECT_EQ(test, -EINVAL, pm_request_autosuspend(dev));
|
||||
KUNIT_EXPECT_EQ(test, -EINVAL, pm_runtime_suspend(dev));
|
||||
KUNIT_EXPECT_EQ(test, -EINVAL, pm_runtime_resume(dev));
|
||||
KUNIT_EXPECT_EQ(test, -EINVAL, pm_runtime_autosuspend(dev));
|
||||
|
||||
/* Error is still pending */
|
||||
KUNIT_EXPECT_TRUE(test, pm_runtime_suspended(dev));
|
||||
KUNIT_EXPECT_EQ(test, -EIO, dev->power.runtime_error);
|
||||
/* Clear error */
|
||||
KUNIT_EXPECT_EQ(test, 0, pm_runtime_set_suspended(dev));
|
||||
KUNIT_EXPECT_EQ(test, 0, dev->power.runtime_error);
|
||||
/* Still suspended */
|
||||
KUNIT_EXPECT_TRUE(test, pm_runtime_suspended(dev));
|
||||
|
||||
KUNIT_EXPECT_EQ(test, 0, pm_runtime_get(dev));
|
||||
KUNIT_EXPECT_EQ(test, 1, pm_runtime_barrier(dev)); /* resume was pending */
|
||||
pm_runtime_put(dev);
|
||||
pm_runtime_suspend(dev); /* flush the put(), to suspend */
|
||||
KUNIT_EXPECT_TRUE(test, pm_runtime_suspended(dev));
|
||||
|
||||
KUNIT_EXPECT_EQ(test, 0, pm_runtime_get_sync(dev));
|
||||
KUNIT_EXPECT_EQ(test, 0, pm_runtime_put_sync(dev));
|
||||
|
||||
KUNIT_EXPECT_EQ(test, 0, pm_runtime_get_sync(dev));
|
||||
pm_runtime_put_autosuspend(dev);
|
||||
|
||||
KUNIT_EXPECT_EQ(test, 0, pm_runtime_resume_and_get(dev));
|
||||
|
||||
/*
|
||||
* The following should all return -EAGAIN (usage is non-zero) or 1
|
||||
* (already resumed).
|
||||
*/
|
||||
KUNIT_EXPECT_EQ(test, -EAGAIN, pm_runtime_idle(dev));
|
||||
KUNIT_EXPECT_EQ(test, -EAGAIN, pm_request_idle(dev));
|
||||
KUNIT_EXPECT_EQ(test, 1, pm_request_resume(dev));
|
||||
KUNIT_EXPECT_EQ(test, -EAGAIN, pm_request_autosuspend(dev));
|
||||
KUNIT_EXPECT_EQ(test, -EAGAIN, pm_runtime_suspend(dev));
|
||||
KUNIT_EXPECT_EQ(test, 1, pm_runtime_resume(dev));
|
||||
KUNIT_EXPECT_EQ(test, -EAGAIN, pm_runtime_autosuspend(dev));
|
||||
|
||||
KUNIT_EXPECT_EQ(test, 0, pm_runtime_put_sync(dev));
|
||||
|
||||
/* Suspended again */
|
||||
KUNIT_EXPECT_TRUE(test, pm_runtime_suspended(dev));
|
||||
}
|
||||
|
||||
/*
|
||||
* Explore a typical probe() sequence in which a device marks itself powered,
|
||||
* but doesn't hold any runtime PM reference, so it suspends as soon as it goes
|
||||
* idle.
|
||||
*/
|
||||
static void pm_runtime_probe_active_test(struct kunit *test)
|
||||
{
|
||||
struct device *dev = kunit_device_register(test, DEVICE_NAME);
|
||||
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
|
||||
|
||||
KUNIT_EXPECT_TRUE(test, pm_runtime_status_suspended(dev));
|
||||
|
||||
KUNIT_EXPECT_EQ(test, 0, pm_runtime_set_active(dev));
|
||||
KUNIT_EXPECT_TRUE(test, pm_runtime_active(dev));
|
||||
|
||||
pm_runtime_enable(dev);
|
||||
KUNIT_EXPECT_TRUE(test, pm_runtime_active(dev));
|
||||
|
||||
/* Nothing to flush. We stay active. */
|
||||
KUNIT_EXPECT_EQ(test, 0, pm_runtime_barrier(dev));
|
||||
KUNIT_EXPECT_TRUE(test, pm_runtime_active(dev));
|
||||
|
||||
/* Ask for idle? Now we suspend. */
|
||||
KUNIT_EXPECT_EQ(test, 0, pm_runtime_idle(dev));
|
||||
KUNIT_EXPECT_TRUE(test, pm_runtime_suspended(dev));
|
||||
}
|
||||
|
||||
static struct kunit_case pm_runtime_test_cases[] = {
|
||||
KUNIT_CASE(pm_runtime_depth_test),
|
||||
KUNIT_CASE(pm_runtime_already_suspended_test),
|
||||
KUNIT_CASE(pm_runtime_idle_test),
|
||||
KUNIT_CASE(pm_runtime_disabled_test),
|
||||
KUNIT_CASE(pm_runtime_error_test),
|
||||
KUNIT_CASE(pm_runtime_probe_active_test),
|
||||
{}
|
||||
};
|
||||
|
||||
static struct kunit_suite pm_runtime_test_suite = {
|
||||
.name = "pm_runtime_test_cases",
|
||||
.test_cases = pm_runtime_test_cases,
|
||||
};
|
||||
|
||||
kunit_test_suite(pm_runtime_test_suite);
|
||||
MODULE_DESCRIPTION("Runtime power management unit test suite");
|
||||
MODULE_LICENSE("GPL");
|
||||
@@ -498,6 +498,9 @@ static int rpm_idle(struct device *dev, int rpmflags)
|
||||
if (retval < 0)
|
||||
; /* Conditions are wrong. */
|
||||
|
||||
else if ((rpmflags & RPM_GET_PUT) && retval == 1)
|
||||
; /* put() is allowed in RPM_SUSPENDED */
|
||||
|
||||
/* Idle notifications are allowed only in the RPM_ACTIVE state. */
|
||||
else if (dev->power.runtime_status != RPM_ACTIVE)
|
||||
retval = -EAGAIN;
|
||||
@@ -796,6 +799,8 @@ static int rpm_resume(struct device *dev, int rpmflags)
|
||||
if (dev->power.runtime_status == RPM_ACTIVE &&
|
||||
dev->power.last_status == RPM_ACTIVE)
|
||||
retval = 1;
|
||||
else if (rpmflags & RPM_TRANSPARENT)
|
||||
goto out;
|
||||
else
|
||||
retval = -EACCES;
|
||||
}
|
||||
|
||||
@@ -872,10 +872,10 @@ static void amd_pstate_update_limits(struct cpufreq_policy *policy)
|
||||
*/
|
||||
static u32 amd_pstate_get_transition_delay_us(unsigned int cpu)
|
||||
{
|
||||
u32 transition_delay_ns;
|
||||
int transition_delay_ns;
|
||||
|
||||
transition_delay_ns = cppc_get_transition_latency(cpu);
|
||||
if (transition_delay_ns == CPUFREQ_ETERNAL) {
|
||||
if (transition_delay_ns < 0) {
|
||||
if (cpu_feature_enabled(X86_FEATURE_AMD_FAST_CPPC))
|
||||
return AMD_PSTATE_FAST_CPPC_TRANSITION_DELAY;
|
||||
else
|
||||
@@ -891,10 +891,10 @@ static u32 amd_pstate_get_transition_delay_us(unsigned int cpu)
|
||||
*/
|
||||
static u32 amd_pstate_get_transition_latency(unsigned int cpu)
|
||||
{
|
||||
u32 transition_latency;
|
||||
int transition_latency;
|
||||
|
||||
transition_latency = cppc_get_transition_latency(cpu);
|
||||
if (transition_latency == CPUFREQ_ETERNAL)
|
||||
if (transition_latency < 0)
|
||||
return AMD_PSTATE_TRANSITION_LATENCY;
|
||||
|
||||
return transition_latency;
|
||||
|
||||
@@ -308,6 +308,16 @@ static int cppc_verify_policy(struct cpufreq_policy_data *policy)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned int __cppc_cpufreq_get_transition_delay_us(unsigned int cpu)
|
||||
{
|
||||
int transition_latency_ns = cppc_get_transition_latency(cpu);
|
||||
|
||||
if (transition_latency_ns < 0)
|
||||
return CPUFREQ_DEFAULT_TRANSITION_LATENCY_NS / NSEC_PER_USEC;
|
||||
|
||||
return transition_latency_ns / NSEC_PER_USEC;
|
||||
}
|
||||
|
||||
/*
|
||||
* The PCC subspace describes the rate at which platform can accept commands
|
||||
* on the shared PCC channel (including READs which do not count towards freq
|
||||
@@ -330,12 +340,12 @@ static unsigned int cppc_cpufreq_get_transition_delay_us(unsigned int cpu)
|
||||
return 10000;
|
||||
}
|
||||
}
|
||||
return cppc_get_transition_latency(cpu) / NSEC_PER_USEC;
|
||||
return __cppc_cpufreq_get_transition_delay_us(cpu);
|
||||
}
|
||||
#else
|
||||
static unsigned int cppc_cpufreq_get_transition_delay_us(unsigned int cpu)
|
||||
{
|
||||
return cppc_get_transition_latency(cpu) / NSEC_PER_USEC;
|
||||
return __cppc_cpufreq_get_transition_delay_us(cpu);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -104,7 +104,7 @@ static int cpufreq_init(struct cpufreq_policy *policy)
|
||||
|
||||
transition_latency = dev_pm_opp_get_max_transition_latency(cpu_dev);
|
||||
if (!transition_latency)
|
||||
transition_latency = CPUFREQ_ETERNAL;
|
||||
transition_latency = CPUFREQ_DEFAULT_TRANSITION_LATENCY_NS;
|
||||
|
||||
cpumask_copy(policy->cpus, priv->cpus);
|
||||
policy->driver_data = priv;
|
||||
|
||||
@@ -442,7 +442,7 @@ soc_opp_out:
|
||||
}
|
||||
|
||||
if (of_property_read_u32(np, "clock-latency", &transition_latency))
|
||||
transition_latency = CPUFREQ_ETERNAL;
|
||||
transition_latency = CPUFREQ_DEFAULT_TRANSITION_LATENCY_NS;
|
||||
|
||||
/*
|
||||
* Calculate the ramp time for max voltage change in the
|
||||
|
||||
@@ -309,7 +309,7 @@ static int mtk_cpufreq_hw_cpu_init(struct cpufreq_policy *policy)
|
||||
|
||||
latency = readl_relaxed(data->reg_bases[REG_FREQ_LATENCY]) * 1000;
|
||||
if (!latency)
|
||||
latency = CPUFREQ_ETERNAL;
|
||||
latency = CPUFREQ_DEFAULT_TRANSITION_LATENCY_NS;
|
||||
|
||||
policy->cpuinfo.transition_latency = latency;
|
||||
policy->fast_switch_possible = true;
|
||||
|
||||
@@ -403,9 +403,11 @@ static int mtk_cpu_dvfs_info_init(struct mtk_cpu_dvfs_info *info, int cpu)
|
||||
}
|
||||
|
||||
info->cpu_clk = clk_get(cpu_dev, "cpu");
|
||||
if (IS_ERR(info->cpu_clk))
|
||||
return dev_err_probe(cpu_dev, PTR_ERR(info->cpu_clk),
|
||||
"cpu%d: failed to get cpu clk\n", cpu);
|
||||
if (IS_ERR(info->cpu_clk)) {
|
||||
ret = PTR_ERR(info->cpu_clk);
|
||||
dev_err_probe(cpu_dev, ret, "cpu%d: failed to get cpu clk\n", cpu);
|
||||
goto out_put_cci_dev;
|
||||
}
|
||||
|
||||
info->inter_clk = clk_get(cpu_dev, "intermediate");
|
||||
if (IS_ERR(info->inter_clk)) {
|
||||
@@ -551,6 +553,10 @@ out_free_inter_clock:
|
||||
out_free_mux_clock:
|
||||
clk_put(info->cpu_clk);
|
||||
|
||||
out_put_cci_dev:
|
||||
if (info->soc_data->ccifreq_supported)
|
||||
put_device(info->cci_dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -568,6 +574,8 @@ static void mtk_cpu_dvfs_info_release(struct mtk_cpu_dvfs_info *info)
|
||||
clk_put(info->inter_clk);
|
||||
dev_pm_opp_of_cpumask_remove_table(&info->cpus);
|
||||
dev_pm_opp_unregister_notifier(info->cpu_dev, &info->opp_nb);
|
||||
if (info->soc_data->ccifreq_supported)
|
||||
put_device(info->cci_dev);
|
||||
}
|
||||
|
||||
static int mtk_cpufreq_init(struct cpufreq_policy *policy)
|
||||
|
||||
@@ -28,15 +28,11 @@ fn find_supply_name_exact(dev: &Device, name: &str) -> Option<CString> {
|
||||
/// Finds supply name for the CPU from DT.
|
||||
fn find_supply_names(dev: &Device, cpu: cpu::CpuId) -> Option<KVec<CString>> {
|
||||
// Try "cpu0" for older DTs, fallback to "cpu".
|
||||
let name = (cpu.as_u32() == 0)
|
||||
(cpu.as_u32() == 0)
|
||||
.then(|| find_supply_name_exact(dev, "cpu0"))
|
||||
.flatten()
|
||||
.or_else(|| find_supply_name_exact(dev, "cpu"))?;
|
||||
|
||||
let mut list = KVec::with_capacity(1, GFP_KERNEL).ok()?;
|
||||
list.push(name, GFP_KERNEL).ok()?;
|
||||
|
||||
Some(list)
|
||||
.or_else(|| find_supply_name_exact(dev, "cpu"))
|
||||
.and_then(|name| kernel::kvec![name].ok())
|
||||
}
|
||||
|
||||
/// Represents the cpufreq dt device.
|
||||
@@ -123,7 +119,7 @@ impl cpufreq::Driver for CPUFreqDTDriver {
|
||||
|
||||
let mut transition_latency = opp_table.max_transition_latency_ns() as u32;
|
||||
if transition_latency == 0 {
|
||||
transition_latency = cpufreq::ETERNAL_LATENCY_NS;
|
||||
transition_latency = cpufreq::DEFAULT_TRANSITION_LATENCY_NS;
|
||||
}
|
||||
|
||||
policy
|
||||
|
||||
@@ -294,7 +294,7 @@ static int scmi_cpufreq_init(struct cpufreq_policy *policy)
|
||||
|
||||
latency = perf_ops->transition_latency_get(ph, domain);
|
||||
if (!latency)
|
||||
latency = CPUFREQ_ETERNAL;
|
||||
latency = CPUFREQ_DEFAULT_TRANSITION_LATENCY_NS;
|
||||
|
||||
policy->cpuinfo.transition_latency = latency;
|
||||
|
||||
|
||||
@@ -157,7 +157,7 @@ static int scpi_cpufreq_init(struct cpufreq_policy *policy)
|
||||
|
||||
latency = scpi_ops->get_transition_latency(cpu_dev);
|
||||
if (!latency)
|
||||
latency = CPUFREQ_ETERNAL;
|
||||
latency = CPUFREQ_DEFAULT_TRANSITION_LATENCY_NS;
|
||||
|
||||
policy->cpuinfo.transition_latency = latency;
|
||||
|
||||
|
||||
@@ -182,7 +182,7 @@ static int spear_cpufreq_probe(struct platform_device *pdev)
|
||||
|
||||
if (of_property_read_u32(np, "clock-latency",
|
||||
&spear_cpufreq.transition_latency))
|
||||
spear_cpufreq.transition_latency = CPUFREQ_ETERNAL;
|
||||
spear_cpufreq.transition_latency = CPUFREQ_DEFAULT_TRANSITION_LATENCY_NS;
|
||||
|
||||
cnt = of_property_count_u32_elems(np, "cpufreq_tbl");
|
||||
if (cnt <= 0) {
|
||||
|
||||
@@ -93,10 +93,14 @@ static int tegra186_cpufreq_set_target(struct cpufreq_policy *policy,
|
||||
{
|
||||
struct tegra186_cpufreq_data *data = cpufreq_get_driver_data();
|
||||
struct cpufreq_frequency_table *tbl = policy->freq_table + index;
|
||||
unsigned int edvd_offset = data->cpus[policy->cpu].edvd_offset;
|
||||
unsigned int edvd_offset;
|
||||
u32 edvd_val = tbl->driver_data;
|
||||
u32 cpu;
|
||||
|
||||
writel(edvd_val, data->regs + edvd_offset);
|
||||
for_each_cpu(cpu, policy->cpus) {
|
||||
edvd_offset = data->cpus[cpu].edvd_offset;
|
||||
writel(edvd_val, data->regs + edvd_offset);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -132,13 +136,14 @@ static struct cpufreq_driver tegra186_cpufreq_driver = {
|
||||
|
||||
static struct cpufreq_frequency_table *init_vhint_table(
|
||||
struct platform_device *pdev, struct tegra_bpmp *bpmp,
|
||||
struct tegra186_cpufreq_cluster *cluster, unsigned int cluster_id)
|
||||
struct tegra186_cpufreq_cluster *cluster, unsigned int cluster_id,
|
||||
int *num_rates)
|
||||
{
|
||||
struct cpufreq_frequency_table *table;
|
||||
struct mrq_cpu_vhint_request req;
|
||||
struct tegra_bpmp_message msg;
|
||||
struct cpu_vhint_data *data;
|
||||
int err, i, j, num_rates = 0;
|
||||
int err, i, j;
|
||||
dma_addr_t phys;
|
||||
void *virt;
|
||||
|
||||
@@ -168,6 +173,7 @@ static struct cpufreq_frequency_table *init_vhint_table(
|
||||
goto free;
|
||||
}
|
||||
|
||||
*num_rates = 0;
|
||||
for (i = data->vfloor; i <= data->vceil; i++) {
|
||||
u16 ndiv = data->ndiv[i];
|
||||
|
||||
@@ -178,10 +184,10 @@ static struct cpufreq_frequency_table *init_vhint_table(
|
||||
if (i > 0 && ndiv == data->ndiv[i - 1])
|
||||
continue;
|
||||
|
||||
num_rates++;
|
||||
(*num_rates)++;
|
||||
}
|
||||
|
||||
table = devm_kcalloc(&pdev->dev, num_rates + 1, sizeof(*table),
|
||||
table = devm_kcalloc(&pdev->dev, *num_rates + 1, sizeof(*table),
|
||||
GFP_KERNEL);
|
||||
if (!table) {
|
||||
table = ERR_PTR(-ENOMEM);
|
||||
@@ -223,7 +229,9 @@ static int tegra186_cpufreq_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct tegra186_cpufreq_data *data;
|
||||
struct tegra_bpmp *bpmp;
|
||||
unsigned int i = 0, err;
|
||||
unsigned int i = 0, err, edvd_offset;
|
||||
int num_rates = 0;
|
||||
u32 edvd_val, cpu;
|
||||
|
||||
data = devm_kzalloc(&pdev->dev,
|
||||
struct_size(data, clusters, TEGRA186_NUM_CLUSTERS),
|
||||
@@ -246,10 +254,21 @@ static int tegra186_cpufreq_probe(struct platform_device *pdev)
|
||||
for (i = 0; i < TEGRA186_NUM_CLUSTERS; i++) {
|
||||
struct tegra186_cpufreq_cluster *cluster = &data->clusters[i];
|
||||
|
||||
cluster->table = init_vhint_table(pdev, bpmp, cluster, i);
|
||||
cluster->table = init_vhint_table(pdev, bpmp, cluster, i, &num_rates);
|
||||
if (IS_ERR(cluster->table)) {
|
||||
err = PTR_ERR(cluster->table);
|
||||
goto put_bpmp;
|
||||
} else if (!num_rates) {
|
||||
err = -EINVAL;
|
||||
goto put_bpmp;
|
||||
}
|
||||
|
||||
for (cpu = 0; cpu < ARRAY_SIZE(tegra186_cpus); cpu++) {
|
||||
if (data->cpus[cpu].bpmp_cluster_id == i) {
|
||||
edvd_val = cluster->table[num_rates - 1].driver_data;
|
||||
edvd_offset = data->cpus[cpu].edvd_offset;
|
||||
writel(edvd_val, data->regs + edvd_offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -367,6 +367,7 @@ static struct skcipher_engine_alg cipher_algs[] = {
|
||||
.cra_driver_name = "ecb-aes-dthev2",
|
||||
.cra_priority = 299,
|
||||
.cra_flags = CRYPTO_ALG_TYPE_SKCIPHER |
|
||||
CRYPTO_ALG_ASYNC |
|
||||
CRYPTO_ALG_KERN_DRIVER_ONLY,
|
||||
.cra_alignmask = AES_BLOCK_SIZE - 1,
|
||||
.cra_blocksize = AES_BLOCK_SIZE,
|
||||
@@ -389,6 +390,7 @@ static struct skcipher_engine_alg cipher_algs[] = {
|
||||
.cra_driver_name = "cbc-aes-dthev2",
|
||||
.cra_priority = 299,
|
||||
.cra_flags = CRYPTO_ALG_TYPE_SKCIPHER |
|
||||
CRYPTO_ALG_ASYNC |
|
||||
CRYPTO_ALG_KERN_DRIVER_ONLY,
|
||||
.cra_alignmask = AES_BLOCK_SIZE - 1,
|
||||
.cra_blocksize = AES_BLOCK_SIZE,
|
||||
|
||||
+58
-31
@@ -320,11 +320,11 @@ static void fastrpc_free_map(struct kref *ref)
|
||||
|
||||
perm.vmid = QCOM_SCM_VMID_HLOS;
|
||||
perm.perm = QCOM_SCM_PERM_RWX;
|
||||
err = qcom_scm_assign_mem(map->phys, map->size,
|
||||
err = qcom_scm_assign_mem(map->phys, map->len,
|
||||
&src_perms, &perm, 1);
|
||||
if (err) {
|
||||
dev_err(map->fl->sctx->dev, "Failed to assign memory phys 0x%llx size 0x%llx err %d\n",
|
||||
map->phys, map->size, err);
|
||||
map->phys, map->len, err);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -360,26 +360,21 @@ static int fastrpc_map_get(struct fastrpc_map *map)
|
||||
|
||||
|
||||
static int fastrpc_map_lookup(struct fastrpc_user *fl, int fd,
|
||||
struct fastrpc_map **ppmap, bool take_ref)
|
||||
struct fastrpc_map **ppmap)
|
||||
{
|
||||
struct fastrpc_session_ctx *sess = fl->sctx;
|
||||
struct fastrpc_map *map = NULL;
|
||||
struct dma_buf *buf;
|
||||
int ret = -ENOENT;
|
||||
|
||||
buf = dma_buf_get(fd);
|
||||
if (IS_ERR(buf))
|
||||
return PTR_ERR(buf);
|
||||
|
||||
spin_lock(&fl->lock);
|
||||
list_for_each_entry(map, &fl->maps, node) {
|
||||
if (map->fd != fd)
|
||||
if (map->fd != fd || map->buf != buf)
|
||||
continue;
|
||||
|
||||
if (take_ref) {
|
||||
ret = fastrpc_map_get(map);
|
||||
if (ret) {
|
||||
dev_dbg(sess->dev, "%s: Failed to get map fd=%d ret=%d\n",
|
||||
__func__, fd, ret);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*ppmap = map;
|
||||
ret = 0;
|
||||
break;
|
||||
@@ -749,16 +744,14 @@ static const struct dma_buf_ops fastrpc_dma_buf_ops = {
|
||||
.release = fastrpc_release,
|
||||
};
|
||||
|
||||
static int fastrpc_map_create(struct fastrpc_user *fl, int fd,
|
||||
static int fastrpc_map_attach(struct fastrpc_user *fl, int fd,
|
||||
u64 len, u32 attr, struct fastrpc_map **ppmap)
|
||||
{
|
||||
struct fastrpc_session_ctx *sess = fl->sctx;
|
||||
struct fastrpc_map *map = NULL;
|
||||
struct sg_table *table;
|
||||
int err = 0;
|
||||
|
||||
if (!fastrpc_map_lookup(fl, fd, ppmap, true))
|
||||
return 0;
|
||||
struct scatterlist *sgl = NULL;
|
||||
int err = 0, sgl_index = 0;
|
||||
|
||||
map = kzalloc(sizeof(*map), GFP_KERNEL);
|
||||
if (!map)
|
||||
@@ -795,7 +788,15 @@ static int fastrpc_map_create(struct fastrpc_user *fl, int fd,
|
||||
map->phys = sg_dma_address(map->table->sgl);
|
||||
map->phys += ((u64)fl->sctx->sid << 32);
|
||||
}
|
||||
map->size = len;
|
||||
for_each_sg(map->table->sgl, sgl, map->table->nents,
|
||||
sgl_index)
|
||||
map->size += sg_dma_len(sgl);
|
||||
if (len > map->size) {
|
||||
dev_dbg(sess->dev, "Bad size passed len 0x%llx map size 0x%llx\n",
|
||||
len, map->size);
|
||||
err = -EINVAL;
|
||||
goto map_err;
|
||||
}
|
||||
map->va = sg_virt(map->table->sgl);
|
||||
map->len = len;
|
||||
|
||||
@@ -812,10 +813,10 @@ static int fastrpc_map_create(struct fastrpc_user *fl, int fd,
|
||||
dst_perms[1].vmid = fl->cctx->vmperms[0].vmid;
|
||||
dst_perms[1].perm = QCOM_SCM_PERM_RWX;
|
||||
map->attr = attr;
|
||||
err = qcom_scm_assign_mem(map->phys, (u64)map->size, &src_perms, dst_perms, 2);
|
||||
err = qcom_scm_assign_mem(map->phys, (u64)map->len, &src_perms, dst_perms, 2);
|
||||
if (err) {
|
||||
dev_err(sess->dev, "Failed to assign memory with phys 0x%llx size 0x%llx err %d\n",
|
||||
map->phys, map->size, err);
|
||||
map->phys, map->len, err);
|
||||
goto map_err;
|
||||
}
|
||||
}
|
||||
@@ -836,6 +837,24 @@ get_err:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int fastrpc_map_create(struct fastrpc_user *fl, int fd,
|
||||
u64 len, u32 attr, struct fastrpc_map **ppmap)
|
||||
{
|
||||
struct fastrpc_session_ctx *sess = fl->sctx;
|
||||
int err = 0;
|
||||
|
||||
if (!fastrpc_map_lookup(fl, fd, ppmap)) {
|
||||
if (!fastrpc_map_get(*ppmap))
|
||||
return 0;
|
||||
dev_dbg(sess->dev, "%s: Failed to get map fd=%d\n",
|
||||
__func__, fd);
|
||||
}
|
||||
|
||||
err = fastrpc_map_attach(fl, fd, len, attr, ppmap);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fastrpc payload buffer with metadata looks like:
|
||||
*
|
||||
@@ -908,8 +927,12 @@ static int fastrpc_create_maps(struct fastrpc_invoke_ctx *ctx)
|
||||
ctx->args[i].length == 0)
|
||||
continue;
|
||||
|
||||
err = fastrpc_map_create(ctx->fl, ctx->args[i].fd,
|
||||
ctx->args[i].length, ctx->args[i].attr, &ctx->maps[i]);
|
||||
if (i < ctx->nbufs)
|
||||
err = fastrpc_map_create(ctx->fl, ctx->args[i].fd,
|
||||
ctx->args[i].length, ctx->args[i].attr, &ctx->maps[i]);
|
||||
else
|
||||
err = fastrpc_map_attach(ctx->fl, ctx->args[i].fd,
|
||||
ctx->args[i].length, ctx->args[i].attr, &ctx->maps[i]);
|
||||
if (err) {
|
||||
dev_err(dev, "Error Creating map %d\n", err);
|
||||
return -EINVAL;
|
||||
@@ -1068,6 +1091,7 @@ static int fastrpc_put_args(struct fastrpc_invoke_ctx *ctx,
|
||||
struct fastrpc_phy_page *pages;
|
||||
u64 *fdlist;
|
||||
int i, inbufs, outbufs, handles;
|
||||
int ret = 0;
|
||||
|
||||
inbufs = REMOTE_SCALARS_INBUFS(ctx->sc);
|
||||
outbufs = REMOTE_SCALARS_OUTBUFS(ctx->sc);
|
||||
@@ -1083,23 +1107,26 @@ static int fastrpc_put_args(struct fastrpc_invoke_ctx *ctx,
|
||||
u64 len = rpra[i].buf.len;
|
||||
|
||||
if (!kernel) {
|
||||
if (copy_to_user((void __user *)dst, src, len))
|
||||
return -EFAULT;
|
||||
if (copy_to_user((void __user *)dst, src, len)) {
|
||||
ret = -EFAULT;
|
||||
goto cleanup_fdlist;
|
||||
}
|
||||
} else {
|
||||
memcpy(dst, src, len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cleanup_fdlist:
|
||||
/* Clean up fdlist which is updated by DSP */
|
||||
for (i = 0; i < FASTRPC_MAX_FDLIST; i++) {
|
||||
if (!fdlist[i])
|
||||
break;
|
||||
if (!fastrpc_map_lookup(fl, (int)fdlist[i], &mmap, false))
|
||||
if (!fastrpc_map_lookup(fl, (int)fdlist[i], &mmap))
|
||||
fastrpc_map_put(mmap);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int fastrpc_invoke_send(struct fastrpc_session_ctx *sctx,
|
||||
@@ -2031,7 +2058,7 @@ static int fastrpc_req_mem_map(struct fastrpc_user *fl, char __user *argp)
|
||||
args[0].length = sizeof(req_msg);
|
||||
|
||||
pages.addr = map->phys;
|
||||
pages.size = map->size;
|
||||
pages.size = map->len;
|
||||
|
||||
args[1].ptr = (u64) (uintptr_t) &pages;
|
||||
args[1].length = sizeof(pages);
|
||||
@@ -2046,7 +2073,7 @@ static int fastrpc_req_mem_map(struct fastrpc_user *fl, char __user *argp)
|
||||
err = fastrpc_internal_invoke(fl, true, FASTRPC_INIT_HANDLE, sc, &args[0]);
|
||||
if (err) {
|
||||
dev_err(dev, "mem mmap error, fd %d, vaddr %llx, size %lld\n",
|
||||
req.fd, req.vaddrin, map->size);
|
||||
req.fd, req.vaddrin, map->len);
|
||||
goto err_invoke;
|
||||
}
|
||||
|
||||
@@ -2059,7 +2086,7 @@ static int fastrpc_req_mem_map(struct fastrpc_user *fl, char __user *argp)
|
||||
if (copy_to_user((void __user *)argp, &req, sizeof(req))) {
|
||||
/* unmap the memory and release the buffer */
|
||||
req_unmap.vaddr = (uintptr_t) rsp_msg.vaddr;
|
||||
req_unmap.length = map->size;
|
||||
req_unmap.length = map->len;
|
||||
fastrpc_req_mem_unmap_impl(fl, &req_unmap);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
@@ -45,11 +45,24 @@ static void nvmem_layout_bus_remove(struct device *dev)
|
||||
return drv->remove(layout);
|
||||
}
|
||||
|
||||
static int nvmem_layout_bus_uevent(const struct device *dev,
|
||||
struct kobj_uevent_env *env)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = of_device_uevent_modalias(dev, env);
|
||||
if (ret != ENODEV)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct bus_type nvmem_layout_bus_type = {
|
||||
.name = "nvmem-layout",
|
||||
.match = nvmem_layout_bus_match,
|
||||
.probe = nvmem_layout_bus_probe,
|
||||
.remove = nvmem_layout_bus_remove,
|
||||
.uevent = nvmem_layout_bus_uevent,
|
||||
};
|
||||
|
||||
int __nvmem_layout_driver_register(struct nvmem_layout_driver *drv,
|
||||
|
||||
@@ -1517,8 +1517,9 @@ static ssize_t reset_method_store(struct device *dev,
|
||||
return count;
|
||||
}
|
||||
|
||||
pm_runtime_get_sync(dev);
|
||||
struct device *pmdev __free(pm_runtime_put) = dev;
|
||||
ACQUIRE(pm_runtime_active_try, pm)(dev);
|
||||
if (ACQUIRE_ERR(pm_runtime_active_try, &pm))
|
||||
return -ENXIO;
|
||||
|
||||
if (sysfs_streq(buf, "default")) {
|
||||
pci_init_reset_methods(pdev);
|
||||
|
||||
@@ -43,7 +43,6 @@
|
||||
#define DRIVER_NAME "axis_fifo"
|
||||
|
||||
#define READ_BUF_SIZE 128U /* read buffer length in words */
|
||||
#define WRITE_BUF_SIZE 128U /* write buffer length in words */
|
||||
|
||||
#define AXIS_FIFO_DEBUG_REG_NAME_MAX_LEN 4
|
||||
|
||||
@@ -231,6 +230,7 @@ static ssize_t axis_fifo_read(struct file *f, char __user *buf,
|
||||
}
|
||||
|
||||
bytes_available = ioread32(fifo->base_addr + XLLF_RLR_OFFSET);
|
||||
words_available = bytes_available / sizeof(u32);
|
||||
if (!bytes_available) {
|
||||
dev_err(fifo->dt_device, "received a packet of length 0\n");
|
||||
ret = -EIO;
|
||||
@@ -241,7 +241,7 @@ static ssize_t axis_fifo_read(struct file *f, char __user *buf,
|
||||
dev_err(fifo->dt_device, "user read buffer too small (available bytes=%zu user buffer bytes=%zu)\n",
|
||||
bytes_available, len);
|
||||
ret = -EINVAL;
|
||||
goto end_unlock;
|
||||
goto err_flush_rx;
|
||||
}
|
||||
|
||||
if (bytes_available % sizeof(u32)) {
|
||||
@@ -250,11 +250,9 @@ static ssize_t axis_fifo_read(struct file *f, char __user *buf,
|
||||
*/
|
||||
dev_err(fifo->dt_device, "received a packet that isn't word-aligned\n");
|
||||
ret = -EIO;
|
||||
goto end_unlock;
|
||||
goto err_flush_rx;
|
||||
}
|
||||
|
||||
words_available = bytes_available / sizeof(u32);
|
||||
|
||||
/* read data into an intermediate buffer, copying the contents
|
||||
* to userspace when the buffer is full
|
||||
*/
|
||||
@@ -266,18 +264,23 @@ static ssize_t axis_fifo_read(struct file *f, char __user *buf,
|
||||
tmp_buf[i] = ioread32(fifo->base_addr +
|
||||
XLLF_RDFD_OFFSET);
|
||||
}
|
||||
words_available -= copy;
|
||||
|
||||
if (copy_to_user(buf + copied * sizeof(u32), tmp_buf,
|
||||
copy * sizeof(u32))) {
|
||||
ret = -EFAULT;
|
||||
goto end_unlock;
|
||||
goto err_flush_rx;
|
||||
}
|
||||
|
||||
copied += copy;
|
||||
words_available -= copy;
|
||||
}
|
||||
mutex_unlock(&fifo->read_lock);
|
||||
|
||||
ret = bytes_available;
|
||||
return bytes_available;
|
||||
|
||||
err_flush_rx:
|
||||
while (words_available--)
|
||||
ioread32(fifo->base_addr + XLLF_RDFD_OFFSET);
|
||||
|
||||
end_unlock:
|
||||
mutex_unlock(&fifo->read_lock);
|
||||
@@ -305,11 +308,8 @@ static ssize_t axis_fifo_write(struct file *f, const char __user *buf,
|
||||
{
|
||||
struct axis_fifo *fifo = (struct axis_fifo *)f->private_data;
|
||||
unsigned int words_to_write;
|
||||
unsigned int copied;
|
||||
unsigned int copy;
|
||||
unsigned int i;
|
||||
u32 *txbuf;
|
||||
int ret;
|
||||
u32 tmp_buf[WRITE_BUF_SIZE];
|
||||
|
||||
if (len % sizeof(u32)) {
|
||||
dev_err(fifo->dt_device,
|
||||
@@ -325,11 +325,17 @@ static ssize_t axis_fifo_write(struct file *f, const char __user *buf,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (words_to_write > fifo->tx_fifo_depth) {
|
||||
dev_err(fifo->dt_device, "tried to write more words [%u] than slots in the fifo buffer [%u]\n",
|
||||
words_to_write, fifo->tx_fifo_depth);
|
||||
/*
|
||||
* In 'Store-and-Forward' mode, the maximum packet that can be
|
||||
* transmitted is limited by the size of the FIFO, which is
|
||||
* (C_TX_FIFO_DEPTH–4)*(data interface width/8) bytes.
|
||||
*
|
||||
* Do not attempt to send a packet larger than 'tx_fifo_depth - 4',
|
||||
* otherwise a 'Transmit Packet Overrun Error' interrupt will be
|
||||
* raised, which requires a reset of the TX circuit to recover.
|
||||
*/
|
||||
if (words_to_write > (fifo->tx_fifo_depth - 4))
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (fifo->write_flags & O_NONBLOCK) {
|
||||
/*
|
||||
@@ -368,32 +374,20 @@ static ssize_t axis_fifo_write(struct file *f, const char __user *buf,
|
||||
}
|
||||
}
|
||||
|
||||
/* write data from an intermediate buffer into the fifo IP, refilling
|
||||
* the buffer with userspace data as needed
|
||||
*/
|
||||
copied = 0;
|
||||
while (words_to_write > 0) {
|
||||
copy = min(words_to_write, WRITE_BUF_SIZE);
|
||||
|
||||
if (copy_from_user(tmp_buf, buf + copied * sizeof(u32),
|
||||
copy * sizeof(u32))) {
|
||||
ret = -EFAULT;
|
||||
goto end_unlock;
|
||||
}
|
||||
|
||||
for (i = 0; i < copy; i++)
|
||||
iowrite32(tmp_buf[i], fifo->base_addr +
|
||||
XLLF_TDFD_OFFSET);
|
||||
|
||||
copied += copy;
|
||||
words_to_write -= copy;
|
||||
txbuf = vmemdup_user(buf, len);
|
||||
if (IS_ERR(txbuf)) {
|
||||
ret = PTR_ERR(txbuf);
|
||||
goto end_unlock;
|
||||
}
|
||||
|
||||
ret = copied * sizeof(u32);
|
||||
for (int i = 0; i < words_to_write; ++i)
|
||||
iowrite32(txbuf[i], fifo->base_addr + XLLF_TDFD_OFFSET);
|
||||
|
||||
/* write packet size to fifo */
|
||||
iowrite32(ret, fifo->base_addr + XLLF_TLR_OFFSET);
|
||||
iowrite32(len, fifo->base_addr + XLLF_TLR_OFFSET);
|
||||
|
||||
ret = len;
|
||||
kvfree(txbuf);
|
||||
end_unlock:
|
||||
mutex_unlock(&fifo->write_lock);
|
||||
|
||||
|
||||
@@ -27,6 +27,13 @@ config RZG2L_THERMAL
|
||||
Enable this to plug the RZ/G2L thermal sensor driver into the Linux
|
||||
thermal framework.
|
||||
|
||||
config RZG3E_THERMAL
|
||||
tristate "Renesas RZ/G3E thermal driver"
|
||||
depends on ARCH_RENESAS || COMPILE_TEST
|
||||
help
|
||||
Enable this to plug the RZ/G3E thermal sensor driver into the Linux
|
||||
thermal framework.
|
||||
|
||||
config RZG3S_THERMAL
|
||||
tristate "Renesas RZ/G3S thermal driver"
|
||||
depends on ARCH_R9A08G045 || COMPILE_TEST
|
||||
@@ -34,10 +41,3 @@ config RZG3S_THERMAL
|
||||
help
|
||||
Enable this to plug the RZ/G3S thermal sensor driver into the Linux
|
||||
thermal framework.
|
||||
|
||||
config RZG3E_THERMAL
|
||||
tristate "Renesas RZ/G3E thermal driver"
|
||||
depends on ARCH_RENESAS || COMPILE_TEST
|
||||
help
|
||||
Enable this to plug the RZ/G3E thermal sensor driver into the Linux
|
||||
thermal framework.
|
||||
@@ -5,4 +5,3 @@ obj-$(CONFIG_RCAR_THERMAL) += rcar_thermal.o
|
||||
obj-$(CONFIG_RZG2L_THERMAL) += rzg2l_thermal.o
|
||||
obj-$(CONFIG_RZG3E_THERMAL) += rzg3e_thermal.o
|
||||
obj-$(CONFIG_RZG3S_THERMAL) += rzg3s_thermal.o
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
#include <linux/irq.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/pm_domain.h>
|
||||
#include <linux/pm_opp.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
@@ -102,16 +101,10 @@
|
||||
#define DMA_RX_BUF_SIZE 2048
|
||||
|
||||
static DEFINE_IDA(port_ida);
|
||||
#define DOMAIN_IDX_POWER 0
|
||||
#define DOMAIN_IDX_PERF 1
|
||||
|
||||
struct qcom_geni_device_data {
|
||||
bool console;
|
||||
enum geni_se_xfer_mode mode;
|
||||
struct dev_pm_domain_attach_data pd_data;
|
||||
int (*resources_init)(struct uart_port *uport);
|
||||
int (*set_rate)(struct uart_port *uport, unsigned int baud);
|
||||
int (*power_state)(struct uart_port *uport, bool state);
|
||||
};
|
||||
|
||||
struct qcom_geni_private_data {
|
||||
@@ -149,7 +142,6 @@ struct qcom_geni_serial_port {
|
||||
|
||||
struct qcom_geni_private_data private_data;
|
||||
const struct qcom_geni_device_data *dev_data;
|
||||
struct dev_pm_domain_list *pd_list;
|
||||
};
|
||||
|
||||
static const struct uart_ops qcom_geni_console_pops;
|
||||
@@ -1307,42 +1299,6 @@ static int geni_serial_set_rate(struct uart_port *uport, unsigned int baud)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int geni_serial_set_level(struct uart_port *uport, unsigned int baud)
|
||||
{
|
||||
struct qcom_geni_serial_port *port = to_dev_port(uport);
|
||||
struct device *perf_dev = port->pd_list->pd_devs[DOMAIN_IDX_PERF];
|
||||
|
||||
/*
|
||||
* The performance protocol sets UART communication
|
||||
* speeds by selecting different performance levels
|
||||
* through the OPP framework.
|
||||
*
|
||||
* Supported perf levels for baudrates in firmware are below
|
||||
* +---------------------+--------------------+
|
||||
* | Perf level value | Baudrate values |
|
||||
* +---------------------+--------------------+
|
||||
* | 300 | 300 |
|
||||
* | 1200 | 1200 |
|
||||
* | 2400 | 2400 |
|
||||
* | 4800 | 4800 |
|
||||
* | 9600 | 9600 |
|
||||
* | 19200 | 19200 |
|
||||
* | 38400 | 38400 |
|
||||
* | 57600 | 57600 |
|
||||
* | 115200 | 115200 |
|
||||
* | 230400 | 230400 |
|
||||
* | 460800 | 460800 |
|
||||
* | 921600 | 921600 |
|
||||
* | 2000000 | 2000000 |
|
||||
* | 3000000 | 3000000 |
|
||||
* | 3200000 | 3200000 |
|
||||
* | 4000000 | 4000000 |
|
||||
* +---------------------+--------------------+
|
||||
*/
|
||||
|
||||
return dev_pm_opp_set_level(perf_dev, baud);
|
||||
}
|
||||
|
||||
static void qcom_geni_serial_set_termios(struct uart_port *uport,
|
||||
struct ktermios *termios,
|
||||
const struct ktermios *old)
|
||||
@@ -1361,7 +1317,7 @@ static void qcom_geni_serial_set_termios(struct uart_port *uport,
|
||||
/* baud rate */
|
||||
baud = uart_get_baud_rate(uport, termios, old, 300, 8000000);
|
||||
|
||||
ret = port->dev_data->set_rate(uport, baud);
|
||||
ret = geni_serial_set_rate(uport, baud);
|
||||
if (ret)
|
||||
return;
|
||||
|
||||
@@ -1648,27 +1604,8 @@ static int geni_serial_resources_off(struct uart_port *uport)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int geni_serial_resource_state(struct uart_port *uport, bool power_on)
|
||||
static int geni_serial_resource_init(struct qcom_geni_serial_port *port)
|
||||
{
|
||||
return power_on ? geni_serial_resources_on(uport) : geni_serial_resources_off(uport);
|
||||
}
|
||||
|
||||
static int geni_serial_pwr_init(struct uart_port *uport)
|
||||
{
|
||||
struct qcom_geni_serial_port *port = to_dev_port(uport);
|
||||
int ret;
|
||||
|
||||
ret = dev_pm_domain_attach_list(port->se.dev,
|
||||
&port->dev_data->pd_data, &port->pd_list);
|
||||
if (ret <= 0)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int geni_serial_resource_init(struct uart_port *uport)
|
||||
{
|
||||
struct qcom_geni_serial_port *port = to_dev_port(uport);
|
||||
int ret;
|
||||
|
||||
port->se.clk = devm_clk_get(port->se.dev, "se");
|
||||
@@ -1713,10 +1650,10 @@ static void qcom_geni_serial_pm(struct uart_port *uport,
|
||||
old_state = UART_PM_STATE_OFF;
|
||||
|
||||
if (new_state == UART_PM_STATE_ON && old_state == UART_PM_STATE_OFF)
|
||||
pm_runtime_resume_and_get(uport->dev);
|
||||
geni_serial_resources_on(uport);
|
||||
else if (new_state == UART_PM_STATE_OFF &&
|
||||
old_state == UART_PM_STATE_ON)
|
||||
pm_runtime_put_sync(uport->dev);
|
||||
geni_serial_resources_off(uport);
|
||||
|
||||
}
|
||||
|
||||
@@ -1819,16 +1756,13 @@ static int qcom_geni_serial_probe(struct platform_device *pdev)
|
||||
port->se.dev = &pdev->dev;
|
||||
port->se.wrapper = dev_get_drvdata(pdev->dev.parent);
|
||||
|
||||
ret = port->dev_data->resources_init(uport);
|
||||
ret = geni_serial_resource_init(port);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!res) {
|
||||
ret = -EINVAL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!res)
|
||||
return -EINVAL;
|
||||
uport->mapbase = res->start;
|
||||
|
||||
uport->rs485_config = qcom_geni_rs485_config;
|
||||
@@ -1840,26 +1774,19 @@ static int qcom_geni_serial_probe(struct platform_device *pdev)
|
||||
if (!data->console) {
|
||||
port->rx_buf = devm_kzalloc(uport->dev,
|
||||
DMA_RX_BUF_SIZE, GFP_KERNEL);
|
||||
if (!port->rx_buf) {
|
||||
ret = -ENOMEM;
|
||||
goto error;
|
||||
}
|
||||
if (!port->rx_buf)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
port->name = devm_kasprintf(uport->dev, GFP_KERNEL,
|
||||
"qcom_geni_serial_%s%d",
|
||||
uart_console(uport) ? "console" : "uart", uport->line);
|
||||
if (!port->name) {
|
||||
ret = -ENOMEM;
|
||||
goto error;
|
||||
}
|
||||
if (!port->name)
|
||||
return -ENOMEM;
|
||||
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq < 0) {
|
||||
ret = irq;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (irq < 0)
|
||||
return irq;
|
||||
uport->irq = irq;
|
||||
uport->has_sysrq = IS_ENABLED(CONFIG_SERIAL_QCOM_GENI_CONSOLE);
|
||||
|
||||
@@ -1881,18 +1808,16 @@ static int qcom_geni_serial_probe(struct platform_device *pdev)
|
||||
IRQF_TRIGGER_HIGH, port->name, uport);
|
||||
if (ret) {
|
||||
dev_err(uport->dev, "Failed to get IRQ ret %d\n", ret);
|
||||
goto error;
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = uart_get_rs485_mode(uport);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
devm_pm_runtime_enable(port->se.dev);
|
||||
|
||||
ret = uart_add_one_port(drv, uport);
|
||||
if (ret)
|
||||
goto error;
|
||||
return ret;
|
||||
|
||||
if (port->wakeup_irq > 0) {
|
||||
device_init_wakeup(&pdev->dev, true);
|
||||
@@ -1902,15 +1827,11 @@ static int qcom_geni_serial_probe(struct platform_device *pdev)
|
||||
device_init_wakeup(&pdev->dev, false);
|
||||
ida_free(&port_ida, uport->line);
|
||||
uart_remove_one_port(drv, uport);
|
||||
goto error;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
dev_pm_domain_detach_list(port->pd_list);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void qcom_geni_serial_remove(struct platform_device *pdev)
|
||||
@@ -1923,31 +1844,6 @@ static void qcom_geni_serial_remove(struct platform_device *pdev)
|
||||
device_init_wakeup(&pdev->dev, false);
|
||||
ida_free(&port_ida, uport->line);
|
||||
uart_remove_one_port(drv, &port->uport);
|
||||
dev_pm_domain_detach_list(port->pd_list);
|
||||
}
|
||||
|
||||
static int __maybe_unused qcom_geni_serial_runtime_suspend(struct device *dev)
|
||||
{
|
||||
struct qcom_geni_serial_port *port = dev_get_drvdata(dev);
|
||||
struct uart_port *uport = &port->uport;
|
||||
int ret = 0;
|
||||
|
||||
if (port->dev_data->power_state)
|
||||
ret = port->dev_data->power_state(uport, false);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __maybe_unused qcom_geni_serial_runtime_resume(struct device *dev)
|
||||
{
|
||||
struct qcom_geni_serial_port *port = dev_get_drvdata(dev);
|
||||
struct uart_port *uport = &port->uport;
|
||||
int ret = 0;
|
||||
|
||||
if (port->dev_data->power_state)
|
||||
ret = port->dev_data->power_state(uport, true);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int qcom_geni_serial_suspend(struct device *dev)
|
||||
@@ -1985,46 +1881,14 @@ static int qcom_geni_serial_resume(struct device *dev)
|
||||
static const struct qcom_geni_device_data qcom_geni_console_data = {
|
||||
.console = true,
|
||||
.mode = GENI_SE_FIFO,
|
||||
.resources_init = geni_serial_resource_init,
|
||||
.set_rate = geni_serial_set_rate,
|
||||
.power_state = geni_serial_resource_state,
|
||||
};
|
||||
|
||||
static const struct qcom_geni_device_data qcom_geni_uart_data = {
|
||||
.console = false,
|
||||
.mode = GENI_SE_DMA,
|
||||
.resources_init = geni_serial_resource_init,
|
||||
.set_rate = geni_serial_set_rate,
|
||||
.power_state = geni_serial_resource_state,
|
||||
};
|
||||
|
||||
static const struct qcom_geni_device_data sa8255p_qcom_geni_console_data = {
|
||||
.console = true,
|
||||
.mode = GENI_SE_FIFO,
|
||||
.pd_data = {
|
||||
.pd_flags = PD_FLAG_DEV_LINK_ON,
|
||||
.pd_names = (const char*[]) { "power", "perf" },
|
||||
.num_pd_names = 2,
|
||||
},
|
||||
.resources_init = geni_serial_pwr_init,
|
||||
.set_rate = geni_serial_set_level,
|
||||
};
|
||||
|
||||
static const struct qcom_geni_device_data sa8255p_qcom_geni_uart_data = {
|
||||
.console = false,
|
||||
.mode = GENI_SE_DMA,
|
||||
.pd_data = {
|
||||
.pd_flags = PD_FLAG_DEV_LINK_ON,
|
||||
.pd_names = (const char*[]) { "power", "perf" },
|
||||
.num_pd_names = 2,
|
||||
},
|
||||
.resources_init = geni_serial_pwr_init,
|
||||
.set_rate = geni_serial_set_level,
|
||||
};
|
||||
|
||||
static const struct dev_pm_ops qcom_geni_serial_pm_ops = {
|
||||
SET_RUNTIME_PM_OPS(qcom_geni_serial_runtime_suspend,
|
||||
qcom_geni_serial_runtime_resume, NULL)
|
||||
SYSTEM_SLEEP_PM_OPS(qcom_geni_serial_suspend, qcom_geni_serial_resume)
|
||||
};
|
||||
|
||||
@@ -2033,18 +1897,10 @@ static const struct of_device_id qcom_geni_serial_match_table[] = {
|
||||
.compatible = "qcom,geni-debug-uart",
|
||||
.data = &qcom_geni_console_data,
|
||||
},
|
||||
{
|
||||
.compatible = "qcom,sa8255p-geni-debug-uart",
|
||||
.data = &sa8255p_qcom_geni_console_data,
|
||||
},
|
||||
{
|
||||
.compatible = "qcom,geni-uart",
|
||||
.data = &qcom_geni_uart_data,
|
||||
},
|
||||
{
|
||||
.compatible = "qcom,sa8255p-geni-uart",
|
||||
.data = &sa8255p_qcom_geni_uart_data,
|
||||
},
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, qcom_geni_serial_match_table);
|
||||
|
||||
@@ -160,7 +160,7 @@ extern unsigned int cppc_khz_to_perf(struct cppc_perf_caps *caps, unsigned int f
|
||||
extern bool acpi_cpc_valid(void);
|
||||
extern bool cppc_allow_fast_switch(void);
|
||||
extern int acpi_get_psd_map(unsigned int cpu, struct cppc_cpudata *cpu_data);
|
||||
extern unsigned int cppc_get_transition_latency(int cpu);
|
||||
extern int cppc_get_transition_latency(int cpu);
|
||||
extern bool cpc_ffh_supported(void);
|
||||
extern bool cpc_supported_by_cpu(void);
|
||||
extern int cpc_read_ffh(int cpunum, struct cpc_reg *reg, u64 *val);
|
||||
@@ -216,9 +216,9 @@ static inline bool cppc_allow_fast_switch(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
static inline unsigned int cppc_get_transition_latency(int cpu)
|
||||
static inline int cppc_get_transition_latency(int cpu)
|
||||
{
|
||||
return CPUFREQ_ETERNAL;
|
||||
return -ENODATA;
|
||||
}
|
||||
static inline bool cpc_ffh_supported(void)
|
||||
{
|
||||
|
||||
@@ -26,12 +26,10 @@
|
||||
*********************************************************************/
|
||||
/*
|
||||
* Frequency values here are CPU kHz
|
||||
*
|
||||
* Maximum transition latency is in nanoseconds - if it's unknown,
|
||||
* CPUFREQ_ETERNAL shall be used.
|
||||
*/
|
||||
|
||||
#define CPUFREQ_ETERNAL (-1)
|
||||
#define CPUFREQ_DEFAULT_TRANSITION_LATENCY_NS NSEC_PER_MSEC
|
||||
|
||||
#define CPUFREQ_NAME_LEN 16
|
||||
/* Print length for names. Extra 1 space for accommodating '\n' in prints */
|
||||
#define CPUFREQ_NAME_PLEN (CPUFREQ_NAME_LEN + 1)
|
||||
|
||||
+69
-36
@@ -21,6 +21,7 @@
|
||||
#define RPM_GET_PUT 0x04 /* Increment/decrement the
|
||||
usage_count */
|
||||
#define RPM_AUTO 0x08 /* Use autosuspend_delay */
|
||||
#define RPM_TRANSPARENT 0x10 /* Succeed if runtime PM is disabled */
|
||||
|
||||
/*
|
||||
* Use this for defining a set of PM operations to be used in all situations
|
||||
@@ -350,13 +351,12 @@ static inline int pm_runtime_force_resume(struct device *dev) { return -ENXIO; }
|
||||
* * 0: Success.
|
||||
* * -EINVAL: Runtime PM error.
|
||||
* * -EACCES: Runtime PM disabled.
|
||||
* * -EAGAIN: Runtime PM usage_count non-zero, Runtime PM status change ongoing
|
||||
* or device not in %RPM_ACTIVE state.
|
||||
* * -EAGAIN: Runtime PM usage counter non-zero, Runtime PM status change
|
||||
* ongoing or device not in %RPM_ACTIVE state.
|
||||
* * -EBUSY: Runtime PM child_count non-zero.
|
||||
* * -EPERM: Device PM QoS resume latency 0.
|
||||
* * -EINPROGRESS: Suspend already in progress.
|
||||
* * -ENOSYS: CONFIG_PM not enabled.
|
||||
* * 1: Device already suspended.
|
||||
* Other values and conditions for the above values are possible as returned by
|
||||
* Runtime PM idle and suspend callbacks.
|
||||
*/
|
||||
@@ -370,14 +370,15 @@ static inline int pm_runtime_idle(struct device *dev)
|
||||
* @dev: Target device.
|
||||
*
|
||||
* Return:
|
||||
* * 1: Success; device was already suspended.
|
||||
* * 0: Success.
|
||||
* * -EINVAL: Runtime PM error.
|
||||
* * -EACCES: Runtime PM disabled.
|
||||
* * -EAGAIN: Runtime PM usage_count non-zero or Runtime PM status change ongoing.
|
||||
* * -EAGAIN: Runtime PM usage counter non-zero or Runtime PM status change
|
||||
* ongoing.
|
||||
* * -EBUSY: Runtime PM child_count non-zero.
|
||||
* * -EPERM: Device PM QoS resume latency 0.
|
||||
* * -ENOSYS: CONFIG_PM not enabled.
|
||||
* * 1: Device already suspended.
|
||||
* Other values and conditions for the above values are possible as returned by
|
||||
* Runtime PM suspend callbacks.
|
||||
*/
|
||||
@@ -396,14 +397,15 @@ static inline int pm_runtime_suspend(struct device *dev)
|
||||
* engaging its "idle check" callback.
|
||||
*
|
||||
* Return:
|
||||
* * 1: Success; device was already suspended.
|
||||
* * 0: Success.
|
||||
* * -EINVAL: Runtime PM error.
|
||||
* * -EACCES: Runtime PM disabled.
|
||||
* * -EAGAIN: Runtime PM usage_count non-zero or Runtime PM status change ongoing.
|
||||
* * -EAGAIN: Runtime PM usage counter non-zero or Runtime PM status change
|
||||
* ongoing.
|
||||
* * -EBUSY: Runtime PM child_count non-zero.
|
||||
* * -EPERM: Device PM QoS resume latency 0.
|
||||
* * -ENOSYS: CONFIG_PM not enabled.
|
||||
* * 1: Device already suspended.
|
||||
* Other values and conditions for the above values are possible as returned by
|
||||
* Runtime PM suspend callbacks.
|
||||
*/
|
||||
@@ -433,13 +435,12 @@ static inline int pm_runtime_resume(struct device *dev)
|
||||
* * 0: Success.
|
||||
* * -EINVAL: Runtime PM error.
|
||||
* * -EACCES: Runtime PM disabled.
|
||||
* * -EAGAIN: Runtime PM usage_count non-zero, Runtime PM status change ongoing
|
||||
* or device not in %RPM_ACTIVE state.
|
||||
* * -EAGAIN: Runtime PM usage counter non-zero, Runtime PM status change
|
||||
* ongoing or device not in %RPM_ACTIVE state.
|
||||
* * -EBUSY: Runtime PM child_count non-zero.
|
||||
* * -EPERM: Device PM QoS resume latency 0.
|
||||
* * -EINPROGRESS: Suspend already in progress.
|
||||
* * -ENOSYS: CONFIG_PM not enabled.
|
||||
* * 1: Device already suspended.
|
||||
*/
|
||||
static inline int pm_request_idle(struct device *dev)
|
||||
{
|
||||
@@ -464,15 +465,16 @@ static inline int pm_request_resume(struct device *dev)
|
||||
* equivalent pm_runtime_autosuspend() for @dev asynchronously.
|
||||
*
|
||||
* Return:
|
||||
* * 1: Success; device was already suspended.
|
||||
* * 0: Success.
|
||||
* * -EINVAL: Runtime PM error.
|
||||
* * -EACCES: Runtime PM disabled.
|
||||
* * -EAGAIN: Runtime PM usage_count non-zero or Runtime PM status change ongoing.
|
||||
* * -EAGAIN: Runtime PM usage counter non-zero or Runtime PM status change
|
||||
* ongoing.
|
||||
* * -EBUSY: Runtime PM child_count non-zero.
|
||||
* * -EPERM: Device PM QoS resume latency 0.
|
||||
* * -EINPROGRESS: Suspend already in progress.
|
||||
* * -ENOSYS: CONFIG_PM not enabled.
|
||||
* * 1: Device already suspended.
|
||||
*/
|
||||
static inline int pm_request_autosuspend(struct device *dev)
|
||||
{
|
||||
@@ -511,6 +513,19 @@ static inline int pm_runtime_get_sync(struct device *dev)
|
||||
return __pm_runtime_resume(dev, RPM_GET_PUT);
|
||||
}
|
||||
|
||||
static inline int pm_runtime_get_active(struct device *dev, int rpmflags)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = __pm_runtime_resume(dev, RPM_GET_PUT | rpmflags);
|
||||
if (ret < 0) {
|
||||
pm_runtime_put_noidle(dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_runtime_resume_and_get - Bump up usage counter of a device and resume it.
|
||||
* @dev: Target device.
|
||||
@@ -521,15 +536,7 @@ static inline int pm_runtime_get_sync(struct device *dev)
|
||||
*/
|
||||
static inline int pm_runtime_resume_and_get(struct device *dev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = __pm_runtime_resume(dev, RPM_GET_PUT);
|
||||
if (ret < 0) {
|
||||
pm_runtime_put_noidle(dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return pm_runtime_get_active(dev, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -540,23 +547,22 @@ static inline int pm_runtime_resume_and_get(struct device *dev)
|
||||
* equal to 0, queue up a work item for @dev like in pm_request_idle().
|
||||
*
|
||||
* Return:
|
||||
* * 1: Success. Usage counter dropped to zero, but device was already suspended.
|
||||
* * 0: Success.
|
||||
* * -EINVAL: Runtime PM error.
|
||||
* * -EACCES: Runtime PM disabled.
|
||||
* * -EAGAIN: Runtime PM usage_count non-zero or Runtime PM status change ongoing.
|
||||
* * -EAGAIN: Runtime PM usage counter became non-zero or Runtime PM status
|
||||
* change ongoing.
|
||||
* * -EBUSY: Runtime PM child_count non-zero.
|
||||
* * -EPERM: Device PM QoS resume latency 0.
|
||||
* * -EINPROGRESS: Suspend already in progress.
|
||||
* * -ENOSYS: CONFIG_PM not enabled.
|
||||
* * 1: Device already suspended.
|
||||
*/
|
||||
static inline int pm_runtime_put(struct device *dev)
|
||||
{
|
||||
return __pm_runtime_idle(dev, RPM_GET_PUT | RPM_ASYNC);
|
||||
}
|
||||
|
||||
DEFINE_FREE(pm_runtime_put, struct device *, if (_T) pm_runtime_put(_T))
|
||||
|
||||
/**
|
||||
* __pm_runtime_put_autosuspend - Drop device usage counter and queue autosuspend if 0.
|
||||
* @dev: Target device.
|
||||
@@ -565,15 +571,16 @@ DEFINE_FREE(pm_runtime_put, struct device *, if (_T) pm_runtime_put(_T))
|
||||
* equal to 0, queue up a work item for @dev like in pm_request_autosuspend().
|
||||
*
|
||||
* Return:
|
||||
* * 1: Success. Usage counter dropped to zero, but device was already suspended.
|
||||
* * 0: Success.
|
||||
* * -EINVAL: Runtime PM error.
|
||||
* * -EACCES: Runtime PM disabled.
|
||||
* * -EAGAIN: Runtime PM usage_count non-zero or Runtime PM status change ongoing.
|
||||
* * -EAGAIN: Runtime PM usage counter became non-zero or Runtime PM status
|
||||
* change ongoing.
|
||||
* * -EBUSY: Runtime PM child_count non-zero.
|
||||
* * -EPERM: Device PM QoS resume latency 0.
|
||||
* * -EINPROGRESS: Suspend already in progress.
|
||||
* * -ENOSYS: CONFIG_PM not enabled.
|
||||
* * 1: Device already suspended.
|
||||
*/
|
||||
static inline int __pm_runtime_put_autosuspend(struct device *dev)
|
||||
{
|
||||
@@ -590,15 +597,16 @@ static inline int __pm_runtime_put_autosuspend(struct device *dev)
|
||||
* in pm_request_autosuspend().
|
||||
*
|
||||
* Return:
|
||||
* * 1: Success. Usage counter dropped to zero, but device was already suspended.
|
||||
* * 0: Success.
|
||||
* * -EINVAL: Runtime PM error.
|
||||
* * -EACCES: Runtime PM disabled.
|
||||
* * -EAGAIN: Runtime PM usage_count non-zero or Runtime PM status change ongoing.
|
||||
* * -EAGAIN: Runtime PM usage counter became non-zero or Runtime PM status
|
||||
* change ongoing.
|
||||
* * -EBUSY: Runtime PM child_count non-zero.
|
||||
* * -EPERM: Device PM QoS resume latency 0.
|
||||
* * -EINPROGRESS: Suspend already in progress.
|
||||
* * -ENOSYS: CONFIG_PM not enabled.
|
||||
* * 1: Device already suspended.
|
||||
*/
|
||||
static inline int pm_runtime_put_autosuspend(struct device *dev)
|
||||
{
|
||||
@@ -606,6 +614,29 @@ static inline int pm_runtime_put_autosuspend(struct device *dev)
|
||||
return __pm_runtime_put_autosuspend(dev);
|
||||
}
|
||||
|
||||
DEFINE_GUARD(pm_runtime_noresume, struct device *,
|
||||
pm_runtime_get_noresume(_T), pm_runtime_put_noidle(_T));
|
||||
|
||||
DEFINE_GUARD(pm_runtime_active, struct device *,
|
||||
pm_runtime_get_sync(_T), pm_runtime_put(_T));
|
||||
DEFINE_GUARD(pm_runtime_active_auto, struct device *,
|
||||
pm_runtime_get_sync(_T), pm_runtime_put_autosuspend(_T));
|
||||
/*
|
||||
* Use the following guards with ACQUIRE()/ACQUIRE_ERR().
|
||||
*
|
||||
* The difference between the "_try" and "_try_enabled" variants is that the
|
||||
* former do not produce an error when runtime PM is disabled for the given
|
||||
* device.
|
||||
*/
|
||||
DEFINE_GUARD_COND(pm_runtime_active, _try,
|
||||
pm_runtime_get_active(_T, RPM_TRANSPARENT))
|
||||
DEFINE_GUARD_COND(pm_runtime_active, _try_enabled,
|
||||
pm_runtime_resume_and_get(_T))
|
||||
DEFINE_GUARD_COND(pm_runtime_active_auto, _try,
|
||||
pm_runtime_get_active(_T, RPM_TRANSPARENT))
|
||||
DEFINE_GUARD_COND(pm_runtime_active_auto, _try_enabled,
|
||||
pm_runtime_resume_and_get(_T))
|
||||
|
||||
/**
|
||||
* pm_runtime_put_sync - Drop device usage counter and run "idle check" if 0.
|
||||
* @dev: Target device.
|
||||
@@ -619,14 +650,15 @@ static inline int pm_runtime_put_autosuspend(struct device *dev)
|
||||
* if it returns an error code.
|
||||
*
|
||||
* Return:
|
||||
* * 1: Success. Usage counter dropped to zero, but device was already suspended.
|
||||
* * 0: Success.
|
||||
* * -EINVAL: Runtime PM error.
|
||||
* * -EACCES: Runtime PM disabled.
|
||||
* * -EAGAIN: Runtime PM usage_count non-zero or Runtime PM status change ongoing.
|
||||
* * -EAGAIN: Runtime PM usage counter became non-zero or Runtime PM status
|
||||
* change ongoing.
|
||||
* * -EBUSY: Runtime PM child_count non-zero.
|
||||
* * -EPERM: Device PM QoS resume latency 0.
|
||||
* * -ENOSYS: CONFIG_PM not enabled.
|
||||
* * 1: Device already suspended.
|
||||
* Other values and conditions for the above values are possible as returned by
|
||||
* Runtime PM suspend callbacks.
|
||||
*/
|
||||
@@ -646,15 +678,15 @@ static inline int pm_runtime_put_sync(struct device *dev)
|
||||
* if it returns an error code.
|
||||
*
|
||||
* Return:
|
||||
* * 1: Success. Usage counter dropped to zero, but device was already suspended.
|
||||
* * 0: Success.
|
||||
* * -EINVAL: Runtime PM error.
|
||||
* * -EACCES: Runtime PM disabled.
|
||||
* * -EAGAIN: Runtime PM usage_count non-zero or Runtime PM status change ongoing.
|
||||
* * -EAGAIN: usage_count non-zero or Runtime PM status change ongoing.
|
||||
* * -EAGAIN: Runtime PM usage counter became non-zero or Runtime PM status
|
||||
* change ongoing.
|
||||
* * -EBUSY: Runtime PM child_count non-zero.
|
||||
* * -EPERM: Device PM QoS resume latency 0.
|
||||
* * -ENOSYS: CONFIG_PM not enabled.
|
||||
* * 1: Device already suspended.
|
||||
* Other values and conditions for the above values are possible as returned by
|
||||
* Runtime PM suspend callbacks.
|
||||
*/
|
||||
@@ -677,15 +709,16 @@ static inline int pm_runtime_put_sync_suspend(struct device *dev)
|
||||
* if it returns an error code.
|
||||
*
|
||||
* Return:
|
||||
* * 1: Success. Usage counter dropped to zero, but device was already suspended.
|
||||
* * 0: Success.
|
||||
* * -EINVAL: Runtime PM error.
|
||||
* * -EACCES: Runtime PM disabled.
|
||||
* * -EAGAIN: Runtime PM usage_count non-zero or Runtime PM status change ongoing.
|
||||
* * -EAGAIN: Runtime PM usage counter became non-zero or Runtime PM status
|
||||
* change ongoing.
|
||||
* * -EBUSY: Runtime PM child_count non-zero.
|
||||
* * -EPERM: Device PM QoS resume latency 0.
|
||||
* * -EINPROGRESS: Suspend already in progress.
|
||||
* * -ENOSYS: CONFIG_PM not enabled.
|
||||
* * 1: Device already suspended.
|
||||
* Other values and conditions for the above values are possible as returned by
|
||||
* Runtime PM suspend callbacks.
|
||||
*/
|
||||
|
||||
@@ -133,6 +133,7 @@ DECLARE_EVENT_CLASS(dma_alloc_class,
|
||||
__entry->dma_addr = dma_addr;
|
||||
__entry->size = size;
|
||||
__entry->flags = flags;
|
||||
__entry->dir = dir;
|
||||
__entry->attrs = attrs;
|
||||
),
|
||||
|
||||
|
||||
+1
-2
@@ -339,13 +339,12 @@ static void kmsan_handle_dma_page(const void *addr, size_t size,
|
||||
void kmsan_handle_dma(phys_addr_t phys, size_t size,
|
||||
enum dma_data_direction dir)
|
||||
{
|
||||
struct page *page = phys_to_page(phys);
|
||||
u64 page_offset, to_go;
|
||||
void *addr;
|
||||
|
||||
if (PhysHighMem(phys))
|
||||
return;
|
||||
addr = page_to_virt(page);
|
||||
addr = phys_to_virt(phys);
|
||||
/*
|
||||
* The kernel may occasionally give us adjacent DMA pages not belonging
|
||||
* to the same allocation. Process them separately to avoid triggering
|
||||
|
||||
@@ -38,7 +38,8 @@ use macros::vtable;
|
||||
const CPUFREQ_NAME_LEN: usize = bindings::CPUFREQ_NAME_LEN as usize;
|
||||
|
||||
/// Default transition latency value in nanoseconds.
|
||||
pub const ETERNAL_LATENCY_NS: u32 = bindings::CPUFREQ_ETERNAL as u32;
|
||||
pub const DEFAULT_TRANSITION_LATENCY_NS: u32 =
|
||||
bindings::CPUFREQ_DEFAULT_TRANSITION_LATENCY_NS;
|
||||
|
||||
/// CPU frequency driver flags.
|
||||
pub mod flags {
|
||||
@@ -399,13 +400,13 @@ impl TableBuilder {
|
||||
/// The following example demonstrates how to create a CPU frequency table.
|
||||
///
|
||||
/// ```
|
||||
/// use kernel::cpufreq::{ETERNAL_LATENCY_NS, Policy};
|
||||
/// use kernel::cpufreq::{DEFAULT_TRANSITION_LATENCY_NS, Policy};
|
||||
///
|
||||
/// fn update_policy(policy: &mut Policy) {
|
||||
/// policy
|
||||
/// .set_dvfs_possible_from_any_cpu(true)
|
||||
/// .set_fast_switch_possible(true)
|
||||
/// .set_transition_latency_ns(ETERNAL_LATENCY_NS);
|
||||
/// .set_transition_latency_ns(DEFAULT_TRANSITION_LATENCY_NS);
|
||||
///
|
||||
/// pr_info!("The policy details are: {:?}\n", (policy.cpu(), policy.cur()));
|
||||
/// }
|
||||
|
||||
@@ -411,7 +411,7 @@ bool sym_dep_errors(void)
|
||||
void sym_calc_value(struct symbol *sym)
|
||||
{
|
||||
struct symbol_value newval, oldval;
|
||||
struct property *prop;
|
||||
struct property *prop = NULL;
|
||||
struct menu *choice_menu;
|
||||
|
||||
if (!sym)
|
||||
@@ -520,6 +520,19 @@ void sym_calc_value(struct symbol *sym)
|
||||
;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the symbol lacks a user value but its value comes from a
|
||||
* single transitional symbol with an existing user value, mark
|
||||
* this symbol as having a user value to avoid prompting.
|
||||
*/
|
||||
if (prop && !sym_has_value(sym)) {
|
||||
struct symbol *ds = prop_get_symbol(prop);
|
||||
if (ds && (ds->flags & SYMBOL_TRANS) && sym_has_value(ds)) {
|
||||
sym->def[S_DEF_USER] = newval;
|
||||
sym->flags |= SYMBOL_DEF_USER;
|
||||
}
|
||||
}
|
||||
|
||||
sym->curr = newval;
|
||||
sym_validate_range(sym);
|
||||
|
||||
|
||||
@@ -96,5 +96,37 @@ config OLD_WITH_HELP
|
||||
help
|
||||
This transitional symbol has a help section to validate that help is allowed.
|
||||
|
||||
# Test that we can set something to =n via transitional symbol
|
||||
config NEW_DISABLED
|
||||
tristate "Check for setting to disabled"
|
||||
default OLD_DISABLED
|
||||
|
||||
config OLD_DISABLED
|
||||
tristate
|
||||
transitional
|
||||
|
||||
# Test that a potential new value disappears if it lacks a prompt
|
||||
config NEW_DISABLED_UNSAVED
|
||||
tristate
|
||||
default OLD_DISABLED
|
||||
|
||||
config OLD_DISABLED_UNSAVED
|
||||
tristate
|
||||
transitional
|
||||
|
||||
# Test conditional default: transitional value should not prevent prompting
|
||||
# when default visibility makes the expression evaluate to 'no'
|
||||
config DEPENDENCY_TEST
|
||||
bool "Dependency for testing"
|
||||
default n
|
||||
|
||||
config NEW_CONDITIONAL_DEFAULT
|
||||
bool "New option with conditional default"
|
||||
default OLD_CONDITIONAL_DEFAULT if DEPENDENCY_TEST
|
||||
|
||||
config OLD_CONDITIONAL_DEFAULT
|
||||
bool
|
||||
transitional
|
||||
|
||||
config REGULAR_OPTION
|
||||
bool "Regular option"
|
||||
@@ -6,6 +6,7 @@ This tests that:
|
||||
- OLD_* options in existing .config cause NEW_* options to be set
|
||||
- OLD_* options are not written to the new .config file
|
||||
- NEW_* options appear in the new .config file with correct values
|
||||
- NEW_* options with defaults from transitional symbols are not prompted
|
||||
- All Kconfig types work correctly: bool, tristate, string, hex, int
|
||||
- User-set NEW values take precedence over conflicting OLD transitional values
|
||||
"""
|
||||
@@ -16,3 +17,9 @@ def test(conf):
|
||||
|
||||
# Check that the configuration matches expected output
|
||||
assert conf.config_contains('expected_config')
|
||||
|
||||
# Test oldconfig to ensure symbols with transitional defaults are not prompted
|
||||
assert conf.oldconfig(dot_config='initial_config', in_keys='n\n') == 0
|
||||
|
||||
# Except for when conditional default evaluates to 'no'
|
||||
assert conf.stdout_contains('expected_stdout')
|
||||
@@ -9,4 +9,7 @@ CONFIG_NEW_STRING_PRECEDENCE="user value"
|
||||
CONFIG_NEW_TRISTATE_PRECEDENCE=y
|
||||
CONFIG_NEW_HEX_PRECEDENCE=0xABCD
|
||||
CONFIG_NEW_INT_PRECEDENCE=100
|
||||
# CONFIG_NEW_DISABLED is not set
|
||||
# CONFIG_DEPENDENCY_TEST is not set
|
||||
# CONFIG_NEW_CONDITIONAL_DEFAULT is not set
|
||||
# CONFIG_REGULAR_OPTION is not set
|
||||
@@ -0,0 +1 @@
|
||||
New option with conditional default (NEW_CONDITIONAL_DEFAULT) [N/y/?] (NEW) n
|
||||
@@ -14,3 +14,7 @@ CONFIG_NEW_HEX_PRECEDENCE=0xABCD
|
||||
CONFIG_OLD_HEX_PRECEDENCE=0x5678
|
||||
CONFIG_NEW_INT_PRECEDENCE=100
|
||||
CONFIG_OLD_INT_PRECEDENCE=200
|
||||
# CONFIG_OLD_DISABLED is not set
|
||||
# CONFIG_OLD_DISABLED_UNSAVED is not set
|
||||
# CONFIG_DEPENDENCY_TEST is not set
|
||||
CONFIG_OLD_CONDITIONAL_DEFAULT=y
|
||||
@@ -43,7 +43,7 @@
|
||||
|
||||
#else /* __ASSEMBLY__ */
|
||||
|
||||
#ifdef CONFIG_CFI_CLANG
|
||||
#ifdef CONFIG_CFI
|
||||
#define DEFINE_CFI_TYPE(name, func) \
|
||||
/* \
|
||||
* Force a reference to the function so the compiler generates \
|
||||
|
||||
@@ -46,8 +46,12 @@ else
|
||||
CFLAGS := -g -Wall
|
||||
endif
|
||||
|
||||
NL3_CFLAGS = $(shell pkg-config --cflags libnl-3.0 2>/dev/null)
|
||||
ifeq ($(NL3_CFLAGS),)
|
||||
NL3_CFLAGS = -I/usr/include/libnl3
|
||||
endif
|
||||
|
||||
INCLUDES = \
|
||||
-I/usr/include/libnl3 \
|
||||
-I$(srctree)/tools/lib/thermal/include \
|
||||
-I$(srctree)/tools/lib/ \
|
||||
-I$(srctree)/tools/include \
|
||||
@@ -59,6 +63,7 @@ INCLUDES = \
|
||||
override CFLAGS += $(EXTRA_WARNINGS)
|
||||
override CFLAGS += -Werror -Wall
|
||||
override CFLAGS += -fPIC
|
||||
override CFLAGS += $(NL3_CFLAGS)
|
||||
override CFLAGS += $(INCLUDES)
|
||||
override CFLAGS += -fvisibility=hidden
|
||||
override CFGLAS += -Wl,-L.
|
||||
@@ -134,7 +139,7 @@ endef
|
||||
install_lib: libs
|
||||
$(call QUIET_INSTALL, $(LIBTHERMAL_ALL)) \
|
||||
$(call do_install_mkdir,$(libdir_SQ)); \
|
||||
cp -fpR $(LIBTHERMAL_ALL) $(DESTDIR)$(libdir_SQ)
|
||||
cp -fR --preserve=mode,timestamp $(LIBTHERMAL_ALL) $(DESTDIR)$(libdir_SQ)
|
||||
|
||||
install_headers:
|
||||
$(call QUIET_INSTALL, headers) \
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
LIBTHERMAL_0.0.1 {
|
||||
global:
|
||||
thermal_init;
|
||||
for_each_thermal_zone;
|
||||
for_each_thermal_trip;
|
||||
for_each_thermal_cdev;
|
||||
@@ -9,9 +8,12 @@ LIBTHERMAL_0.0.1 {
|
||||
thermal_zone_find_by_id;
|
||||
thermal_zone_discover;
|
||||
thermal_init;
|
||||
thermal_exit;
|
||||
thermal_events_exit;
|
||||
thermal_events_init;
|
||||
thermal_events_handle;
|
||||
thermal_events_fd;
|
||||
thermal_cmd_exit;
|
||||
thermal_cmd_init;
|
||||
thermal_cmd_get_tz;
|
||||
thermal_cmd_get_cdev;
|
||||
@@ -22,6 +24,7 @@ LIBTHERMAL_0.0.1 {
|
||||
thermal_cmd_threshold_add;
|
||||
thermal_cmd_threshold_delete;
|
||||
thermal_cmd_threshold_flush;
|
||||
thermal_sampling_exit;
|
||||
thermal_sampling_init;
|
||||
thermal_sampling_handle;
|
||||
thermal_sampling_fd;
|
||||
|
||||
Reference in new issue
Block a user