Merge 99e08debac ("Merge tag 'gpio-fixes-for-v7.1-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux") into android-mainline
Steps on the way to v7.1-rc5 Change-Id: I172c5a77ec91ac0bdbe4d14023556b8f7e089a35 Signed-off-by: Carlos Llamas <cmllamas@google.com>
This commit is contained in:
commit
63a597911b
73 files changed
+645
-389
No files matched your search
@@ -358,9 +358,9 @@ Dynamic energy performance profile
|
||||
The amd-pstate driver supports dynamically selecting the energy performance
|
||||
profile based on whether the machine is running on AC or DC power.
|
||||
|
||||
Whether this behavior is enabled by default depends on the kernel
|
||||
config option `CONFIG_X86_AMD_PSTATE_DYNAMIC_EPP`. This behavior can also be overridden
|
||||
at runtime by the sysfs file ``/sys/devices/system/cpu/cpufreq/policyX/dynamic_epp``.
|
||||
Whether this behavior is enabled by default depends on the kernel command line option
|
||||
``amd_dynamic_epp`` is set. This behavior can also be overridden
|
||||
at runtime by the sysfs file ``/sys/devices/system/cpu/amd_pstate/dynamic_epp``.
|
||||
|
||||
When set to enabled, the driver will select a different energy performance
|
||||
profile when the machine is running on battery or AC power. The driver will
|
||||
@@ -485,9 +485,8 @@ kernel parameter ``amd_prefcore=disable``.
|
||||
``amd_dynamic_epp``
|
||||
|
||||
When AMD pstate is in auto mode, dynamic EPP will control whether the kernel
|
||||
autonomously changes the EPP mode. The default is configured by
|
||||
``CONFIG_X86_AMD_PSTATE_DYNAMIC_EPP`` but can be explicitly enabled with
|
||||
``amd_dynamic_epp=enable`` or disabled with ``amd_dynamic_epp=disable``.
|
||||
autonomously changes the EPP mode. The default is disabled. It can be enabled
|
||||
with the kernel parameter ``amd_dynamic_epp=enable``.
|
||||
|
||||
User Space Interface in ``sysfs`` - General
|
||||
===========================================
|
||||
|
||||
@@ -355,11 +355,12 @@ HyperThreading (HT) in the context of Intel processors, is enabled on at least
|
||||
one core, ``intel_pstate`` assigns performance-based priorities to CPUs. Namely,
|
||||
the priority of a given CPU reflects its highest HWP performance level which
|
||||
causes the CPU scheduler to generally prefer more performant CPUs, so the less
|
||||
performant CPUs are used when the other ones are fully loaded. However, SMT
|
||||
siblings (that is, logical CPUs sharing one physical core) are treated in a
|
||||
special way such that if one of them is in use, the effective priority of the
|
||||
other ones is lowered below the priorities of the CPUs located in the other
|
||||
physical cores.
|
||||
performant CPUs are used when the other ones are fully loaded. SMT siblings
|
||||
(that is, logical CPUs sharing one physical core) are given the same priority.
|
||||
The scheduler can pull tasks from lower-priority cores and place them on any
|
||||
sibling. Since the scheduler spreads tasks among physical cores, tasks will be
|
||||
placed on the SMT siblings of physical cores only after all physical cores are
|
||||
busy.
|
||||
|
||||
This approach maximizes performance in the majority of cases, but unfortunately
|
||||
it also leads to excessive energy usage in some important scenarios, like video
|
||||
|
||||
@@ -18,7 +18,9 @@ properties:
|
||||
description: Phandles of rt5650 and rt5514 codecs
|
||||
items:
|
||||
- description: phandle of rt5650 codec
|
||||
maxItems: 1
|
||||
- description: phandle of rt5514 codec
|
||||
maxItems: 1
|
||||
|
||||
mediatek,platform:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
|
||||
+1
-10
@@ -12799,7 +12799,6 @@ M: Cezary Rojewski <cezary.rojewski@intel.com>
|
||||
M: Liam Girdwood <liam.r.girdwood@linux.intel.com>
|
||||
M: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
|
||||
M: Bard Liao <yung-chuan.liao@linux.intel.com>
|
||||
M: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
|
||||
M: Kai Vehmanen <kai.vehmanen@linux.intel.com>
|
||||
R: Pierre-Louis Bossart <pierre-louis.bossart@linux.dev>
|
||||
L: linux-sound@vger.kernel.org
|
||||
@@ -19470,7 +19469,6 @@ F: include/misc/ocxl*
|
||||
F: include/uapi/misc/ocxl.h
|
||||
|
||||
OMAP AUDIO SUPPORT
|
||||
M: Peter Ujfalusi <peter.ujfalusi@gmail.com>
|
||||
M: Jarkko Nikula <jarkko.nikula@bitmer.com>
|
||||
L: linux-sound@vger.kernel.org
|
||||
L: linux-omap@vger.kernel.org
|
||||
@@ -25078,7 +25076,6 @@ SOUND - SOUND OPEN FIRMWARE (SOF) DRIVERS
|
||||
M: Liam Girdwood <lgirdwood@gmail.com>
|
||||
M: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
|
||||
M: Bard Liao <yung-chuan.liao@linux.intel.com>
|
||||
M: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
|
||||
M: Daniel Baluta <daniel.baluta@nxp.com>
|
||||
R: Kai Vehmanen <kai.vehmanen@linux.intel.com>
|
||||
R: Pierre-Louis Bossart <pierre-louis.bossart@linux.dev>
|
||||
@@ -26371,7 +26368,7 @@ F: arch/xtensa/
|
||||
F: drivers/irqchip/irq-xtensa-*
|
||||
|
||||
TEXAS INSTRUMENTS ASoC DRIVERS
|
||||
M: Peter Ujfalusi <peter.ujfalusi@gmail.com>
|
||||
M: Sen Wang <sen@ti.com>
|
||||
L: linux-sound@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/sound/davinci-mcasp-audio.yaml
|
||||
@@ -26873,12 +26870,6 @@ S: Maintained
|
||||
F: Documentation/devicetree/bindings/iio/adc/ti,tsc2046.yaml
|
||||
F: drivers/iio/adc/ti-tsc2046.c
|
||||
|
||||
TI TWL4030 SERIES SOC CODEC DRIVER
|
||||
M: Peter Ujfalusi <peter.ujfalusi@gmail.com>
|
||||
L: linux-sound@vger.kernel.org
|
||||
S: Maintained
|
||||
F: sound/soc/codecs/twl4030*
|
||||
|
||||
TI VPE/CAL DRIVERS
|
||||
M: Yemike Abhilash Chandra <y-abhilashchandra@ti.com>
|
||||
L: linux-media@vger.kernel.org
|
||||
|
||||
@@ -409,7 +409,7 @@ __AARCH64_INSN_FUNCS(cbz, 0x7F000000, 0x34000000)
|
||||
__AARCH64_INSN_FUNCS(cbnz, 0x7F000000, 0x35000000)
|
||||
__AARCH64_INSN_FUNCS(tbz, 0x7F000000, 0x36000000)
|
||||
__AARCH64_INSN_FUNCS(tbnz, 0x7F000000, 0x37000000)
|
||||
__AARCH64_INSN_FUNCS(bcond, 0xFF000010, 0x54000000)
|
||||
__AARCH64_INSN_FUNCS(bcond, 0xFF000000, 0x54000000)
|
||||
__AARCH64_INSN_FUNCS(svc, 0xFFE0001F, 0xD4000001)
|
||||
__AARCH64_INSN_FUNCS(hvc, 0xFFE0001F, 0xD4000002)
|
||||
__AARCH64_INSN_FUNCS(smc, 0xFFE0001F, 0xD4000003)
|
||||
|
||||
@@ -53,7 +53,8 @@ static inline int tlb_get_level(struct mmu_gather *tlb)
|
||||
static inline void tlb_flush(struct mmu_gather *tlb)
|
||||
{
|
||||
struct vm_area_struct vma = TLB_FLUSH_VMA(tlb->mm, 0);
|
||||
tlbf_t flags = tlb->freed_tables ? TLBF_NONE : TLBF_NOWALKCACHE;
|
||||
tlbf_t flags = (tlb->freed_tables || tlb->unshared_tables) ?
|
||||
TLBF_NONE : TLBF_NOWALKCACHE;
|
||||
unsigned long stride = tlb_get_unmap_size(tlb);
|
||||
int tlb_level = tlb_get_level(tlb);
|
||||
|
||||
|
||||
+21
-10
@@ -186,6 +186,13 @@ static u64 pai_getctr(unsigned long *page, int nr, unsigned long offset)
|
||||
return page[nr];
|
||||
}
|
||||
|
||||
static void pai_setctr(unsigned long *page, int nr, unsigned long offset, u64 v)
|
||||
{
|
||||
if (offset)
|
||||
nr += offset / sizeof(*page);
|
||||
page[nr] = v;
|
||||
}
|
||||
|
||||
/* Read the counter values. Return value from location in CMP. For base
|
||||
* event xxx_ALL sum up all events. Returns counter value.
|
||||
*/
|
||||
@@ -551,6 +558,8 @@ static void paicrypt_del(struct perf_event *event, int flags)
|
||||
/* Create raw data and save it in buffer. Calculate the delta for each
|
||||
* counter between this invocation and the last invocation.
|
||||
* Returns number of bytes copied.
|
||||
* After reading from PAI counter page, save the read value to the old
|
||||
* page to calculate PAI counter deltas.
|
||||
* Saves only entries with positive counter difference of the form
|
||||
* 2 bytes: Number of counter
|
||||
* 8 bytes: Value of counter
|
||||
@@ -562,16 +571,22 @@ static size_t pai_copy(struct pai_userdata *userdata, unsigned long *page,
|
||||
int i, outidx = 0;
|
||||
|
||||
for (i = 1; i <= pp->num_avail; i++) {
|
||||
u64 val = 0, val_old = 0;
|
||||
u64 val = 0, val_old = 0, val_k = 0, val_old_k = 0;
|
||||
|
||||
if (!exclude_kernel) {
|
||||
val += pai_getctr(page, i, pp->kernel_offset);
|
||||
val_old += pai_getctr(page_old, i, pp->kernel_offset);
|
||||
val_k = pai_getctr(page, i, pp->kernel_offset);
|
||||
val_old_k = pai_getctr(page_old, i, pp->kernel_offset);
|
||||
if (val_k != val_old_k)
|
||||
pai_setctr(page_old, i, pp->kernel_offset, val_k);
|
||||
}
|
||||
if (!exclude_user) {
|
||||
val += pai_getctr(page, i, 0);
|
||||
val_old += pai_getctr(page_old, i, 0);
|
||||
val = pai_getctr(page, i, 0);
|
||||
val_old = pai_getctr(page_old, i, 0);
|
||||
if (val != val_old)
|
||||
pai_setctr(page_old, i, 0, val);
|
||||
}
|
||||
val += val_k;
|
||||
val_old += val_old_k;
|
||||
if (val >= val_old)
|
||||
val -= val_old;
|
||||
else
|
||||
@@ -602,8 +617,6 @@ static size_t pai_copy(struct pai_userdata *userdata, unsigned long *page,
|
||||
static int pai_push_sample(size_t rawsize, struct pai_map *cpump,
|
||||
struct perf_event *event)
|
||||
{
|
||||
int idx = PAI_PMU_IDX(event);
|
||||
struct pai_pmu *pp = &pai_pmu[idx];
|
||||
struct perf_sample_data data;
|
||||
struct perf_raw_record raw;
|
||||
struct pt_regs regs;
|
||||
@@ -634,8 +647,6 @@ static int pai_push_sample(size_t rawsize, struct pai_map *cpump,
|
||||
|
||||
overflow = perf_event_overflow(event, &data, ®s);
|
||||
perf_event_update_userpage(event);
|
||||
/* Save crypto counter lowcore page after reading event data. */
|
||||
memcpy((void *)PAI_SAVE_AREA(event), cpump->area, pp->area_size);
|
||||
return overflow;
|
||||
}
|
||||
|
||||
@@ -651,7 +662,7 @@ static void pai_have_sample(struct perf_event *event, struct pai_map *cpump)
|
||||
rawsize = pai_copy(cpump->save, cpump->area, pp,
|
||||
(unsigned long *)PAI_SAVE_AREA(event),
|
||||
event->attr.exclude_user,
|
||||
event->attr.exclude_kernel);
|
||||
!pp->kernel_offset ? true : event->attr.exclude_kernel);
|
||||
if (rawsize) /* No incremented counters */
|
||||
pai_push_sample(rawsize, cpump, event);
|
||||
}
|
||||
|
||||
@@ -192,17 +192,21 @@ static void tl_to_masks(struct sysinfo_15_1_x *info)
|
||||
end = (union topology_entry *)((unsigned long)info + info->length);
|
||||
while (tle < end) {
|
||||
switch (tle->nl) {
|
||||
/*
|
||||
* Adjust drawer_id, book_id, and socked_id so they match the
|
||||
* numbering scheme of e.g. the hardware management console.
|
||||
*/
|
||||
case 3:
|
||||
drawer = drawer->next;
|
||||
drawer->id = tle->container.id;
|
||||
drawer->id = tle->container.id - 1;
|
||||
break;
|
||||
case 2:
|
||||
book = book->next;
|
||||
book->id = tle->container.id;
|
||||
book->id = tle->container.id - 1;
|
||||
break;
|
||||
case 1:
|
||||
socket = socket->next;
|
||||
socket->id = tle->container.id;
|
||||
socket->id = tle->container.id - 1;
|
||||
break;
|
||||
case 0:
|
||||
add_cpus_to_mask(&tle->cpu, drawer, book, socket);
|
||||
|
||||
@@ -55,6 +55,10 @@ int fs_bio_integrity_verify(struct bio *bio, sector_t sector, unsigned int size)
|
||||
{
|
||||
struct blk_integrity *bi = blk_get_integrity(bio->bi_bdev->bd_disk);
|
||||
struct bio_integrity_payload *bip = bio_integrity(bio);
|
||||
struct bvec_iter data_iter = {
|
||||
.bi_sector = sector,
|
||||
.bi_size = size,
|
||||
};
|
||||
|
||||
/*
|
||||
* Reinitialize bip->bip_iter.
|
||||
@@ -65,7 +69,7 @@ int fs_bio_integrity_verify(struct bio *bio, sector_t sector, unsigned int size)
|
||||
memset(&bip->bip_iter, 0, sizeof(bip->bip_iter));
|
||||
bip->bip_iter.bi_sector = sector;
|
||||
bip->bip_iter.bi_size = bio_integrity_bytes(bi, size >> SECTOR_SHIFT);
|
||||
return blk_status_to_errno(bio_integrity_verify(bio, &bip->bip_iter));
|
||||
return blk_status_to_errno(bio_integrity_verify(bio, &data_iter));
|
||||
}
|
||||
|
||||
static int __init fs_bio_integrity_init(void)
|
||||
|
||||
+9
-25
@@ -3077,7 +3077,7 @@ static struct request *blk_mq_get_new_requests(struct request_queue *q,
|
||||
/*
|
||||
* Check if there is a suitable cached request and return it.
|
||||
*/
|
||||
static struct request *blk_mq_peek_cached_request(struct blk_plug *plug,
|
||||
static struct request *blk_mq_get_cached_request(struct blk_plug *plug,
|
||||
struct request_queue *q, blk_opf_t opf)
|
||||
{
|
||||
enum hctx_type type = blk_mq_get_hctx_type(opf);
|
||||
@@ -3093,27 +3093,10 @@ static struct request *blk_mq_peek_cached_request(struct blk_plug *plug,
|
||||
return NULL;
|
||||
if (op_is_flush(rq->cmd_flags) != op_is_flush(opf))
|
||||
return NULL;
|
||||
rq_list_pop(&plug->cached_rqs);
|
||||
return rq;
|
||||
}
|
||||
|
||||
static void blk_mq_use_cached_rq(struct request *rq, struct blk_plug *plug,
|
||||
struct bio *bio)
|
||||
{
|
||||
if (rq_list_pop(&plug->cached_rqs) != rq)
|
||||
WARN_ON_ONCE(1);
|
||||
|
||||
/*
|
||||
* If any qos ->throttle() end up blocking, we will have flushed the
|
||||
* plug and hence killed the cached_rq list as well. Pop this entry
|
||||
* before we throttle.
|
||||
*/
|
||||
rq_qos_throttle(rq->q, bio);
|
||||
|
||||
blk_mq_rq_time_init(rq, blk_time_get_ns());
|
||||
rq->cmd_flags = bio->bi_opf;
|
||||
INIT_LIST_HEAD(&rq->queuelist);
|
||||
}
|
||||
|
||||
static bool bio_unaligned(const struct bio *bio, struct request_queue *q)
|
||||
{
|
||||
unsigned int bs_mask = queue_logical_block_size(q) - 1;
|
||||
@@ -3152,7 +3135,7 @@ void blk_mq_submit_bio(struct bio *bio)
|
||||
/*
|
||||
* If the plug has a cached request for this queue, try to use it.
|
||||
*/
|
||||
rq = blk_mq_peek_cached_request(plug, q, bio->bi_opf);
|
||||
rq = blk_mq_get_cached_request(plug, q, bio->bi_opf);
|
||||
|
||||
/*
|
||||
* A BIO that was released from a zone write plug has already been
|
||||
@@ -3211,7 +3194,10 @@ void blk_mq_submit_bio(struct bio *bio)
|
||||
|
||||
new_request:
|
||||
if (rq) {
|
||||
blk_mq_use_cached_rq(rq, plug, bio);
|
||||
rq_qos_throttle(rq->q, bio);
|
||||
blk_mq_rq_time_init(rq, blk_time_get_ns());
|
||||
rq->cmd_flags = bio->bi_opf;
|
||||
INIT_LIST_HEAD(&rq->queuelist);
|
||||
} else {
|
||||
rq = blk_mq_get_new_requests(q, plug, bio);
|
||||
if (unlikely(!rq)) {
|
||||
@@ -3257,12 +3243,10 @@ new_request:
|
||||
return;
|
||||
|
||||
queue_exit:
|
||||
/*
|
||||
* Don't drop the queue reference if we were trying to use a cached
|
||||
* request and thus didn't acquire one.
|
||||
*/
|
||||
if (!rq)
|
||||
blk_queue_exit(q);
|
||||
else
|
||||
blk_mq_free_request(rq);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BLK_MQ_STACKING
|
||||
|
||||
+3
-4
@@ -2001,8 +2001,10 @@ static void disk_set_zones_cond_array(struct gendisk *disk, u8 *zones_cond)
|
||||
|
||||
void disk_free_zone_resources(struct gendisk *disk)
|
||||
{
|
||||
if (disk->zone_wplugs_worker)
|
||||
if (disk->zone_wplugs_worker) {
|
||||
kthread_stop(disk->zone_wplugs_worker);
|
||||
disk->zone_wplugs_worker = NULL;
|
||||
}
|
||||
WARN_ON_ONCE(!list_empty(&disk->zone_wplugs_list));
|
||||
|
||||
if (disk->zone_wplugs_wq) {
|
||||
@@ -2135,9 +2137,6 @@ commit:
|
||||
ret = queue_limits_commit_update(q, &lim);
|
||||
|
||||
unfreeze:
|
||||
if (ret)
|
||||
disk_free_zone_resources(disk);
|
||||
|
||||
blk_mq_unfreeze_queue(q, memflags);
|
||||
|
||||
return ret;
|
||||
|
||||
@@ -94,6 +94,7 @@ struct acpi_battery {
|
||||
struct power_supply *bat;
|
||||
struct power_supply_desc bat_desc;
|
||||
struct acpi_device *device;
|
||||
struct device *phys_dev;
|
||||
struct notifier_block pm_nb;
|
||||
struct list_head list;
|
||||
unsigned long update_time;
|
||||
@@ -1033,7 +1034,7 @@ static int acpi_battery_update(struct acpi_battery *battery, bool resume)
|
||||
if ((battery->state & ACPI_BATTERY_STATE_CRITICAL) ||
|
||||
(test_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags) &&
|
||||
(battery->capacity_now <= battery->alarm)))
|
||||
acpi_pm_wakeup_event(&battery->device->dev);
|
||||
acpi_pm_wakeup_event(battery->phys_dev);
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -1231,6 +1232,7 @@ static int acpi_battery_probe(struct platform_device *pdev)
|
||||
|
||||
platform_set_drvdata(pdev, battery);
|
||||
|
||||
battery->phys_dev = &pdev->dev;
|
||||
battery->device = device;
|
||||
|
||||
result = devm_mutex_init(&pdev->dev, &battery->update_lock);
|
||||
|
||||
@@ -70,18 +70,6 @@ config X86_AMD_PSTATE_DEFAULT_MODE
|
||||
For details, take a look at:
|
||||
<file:Documentation/admin-guide/pm/amd-pstate.rst>.
|
||||
|
||||
config X86_AMD_PSTATE_DYNAMIC_EPP
|
||||
bool "AMD Processor P-State dynamic EPP support"
|
||||
depends on X86_AMD_PSTATE
|
||||
default n
|
||||
help
|
||||
Allow the kernel to dynamically change the energy performance
|
||||
value from events like ACPI platform profile and AC adapter plug
|
||||
events.
|
||||
|
||||
This feature can also be changed at runtime, this configuration
|
||||
option only sets the kernel default value behavior.
|
||||
|
||||
config X86_AMD_PSTATE_UT
|
||||
tristate "selftest for AMD Processor P-State driver"
|
||||
depends on X86 && ACPI_PROCESSOR
|
||||
|
||||
@@ -274,20 +274,21 @@ static int amd_pstate_set_mode(enum amd_pstate_mode mode)
|
||||
|
||||
static int amd_pstate_ut_epp(u32 index)
|
||||
{
|
||||
struct cpufreq_policy *policy __free(put_cpufreq_policy) = NULL;
|
||||
char *buf __free(cleanup_page) = NULL;
|
||||
static const char * const epp_strings[] = {
|
||||
"performance",
|
||||
"balance_performance",
|
||||
"balance_power",
|
||||
"power",
|
||||
"balance_power",
|
||||
"balance_performance",
|
||||
"performance",
|
||||
};
|
||||
struct amd_cpudata *cpudata;
|
||||
char *buf __free(cleanup_page) = NULL;
|
||||
struct cpufreq_policy *policy = NULL;
|
||||
enum amd_pstate_mode orig_mode;
|
||||
struct amd_cpudata *cpudata;
|
||||
unsigned long orig_policy;
|
||||
bool orig_dynamic_epp;
|
||||
int ret, cpu = 0;
|
||||
int i;
|
||||
u16 epp;
|
||||
int i;
|
||||
|
||||
policy = cpufreq_cpu_get(cpu);
|
||||
if (!policy)
|
||||
@@ -297,6 +298,10 @@ static int amd_pstate_ut_epp(u32 index)
|
||||
orig_mode = amd_pstate_get_status();
|
||||
orig_dynamic_epp = cpudata->dynamic_epp;
|
||||
|
||||
/* Drop reference before potential driver change. */
|
||||
cpufreq_cpu_put(policy);
|
||||
policy = NULL;
|
||||
|
||||
/* disable dynamic EPP before running test */
|
||||
if (cpudata->dynamic_epp) {
|
||||
pr_debug("Dynamic EPP is enabled, disabling it\n");
|
||||
@@ -311,6 +316,17 @@ static int amd_pstate_ut_epp(u32 index)
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
policy = cpufreq_cpu_get(cpu);
|
||||
if (!policy) {
|
||||
ret = -ENODEV;
|
||||
goto out;
|
||||
}
|
||||
|
||||
down_write(&policy->rwsem);
|
||||
cpudata = policy->driver_data;
|
||||
orig_policy = cpudata->policy;
|
||||
cpudata->policy = CPUFREQ_POLICY_POWERSAVE;
|
||||
|
||||
for (epp = 0; epp <= U8_MAX; epp++) {
|
||||
u8 val;
|
||||
|
||||
@@ -358,6 +374,12 @@ static int amd_pstate_ut_epp(u32 index)
|
||||
ret = 0;
|
||||
|
||||
out:
|
||||
if (policy) {
|
||||
cpudata->policy = orig_policy;
|
||||
up_write(&policy->rwsem);
|
||||
cpufreq_cpu_put(policy);
|
||||
}
|
||||
|
||||
if (orig_dynamic_epp) {
|
||||
int ret2;
|
||||
|
||||
|
||||
@@ -87,11 +87,7 @@ static struct cpufreq_driver amd_pstate_driver;
|
||||
static struct cpufreq_driver amd_pstate_epp_driver;
|
||||
static int cppc_state = AMD_PSTATE_UNDEFINED;
|
||||
static bool amd_pstate_prefcore = true;
|
||||
#ifdef CONFIG_X86_AMD_PSTATE_DYNAMIC_EPP
|
||||
static bool dynamic_epp = CONFIG_X86_AMD_PSTATE_DYNAMIC_EPP;
|
||||
#else
|
||||
static bool dynamic_epp;
|
||||
#endif
|
||||
static struct quirk_entry *quirks;
|
||||
|
||||
/*
|
||||
@@ -1291,6 +1287,8 @@ static int amd_pstate_set_dynamic_epp(struct cpufreq_policy *policy)
|
||||
return ret;
|
||||
|
||||
cpudata->profile_name = kasprintf(GFP_KERNEL, "amd-pstate-epp-cpu%d", cpudata->cpu);
|
||||
if (!cpudata->profile_name)
|
||||
return -ENOMEM;
|
||||
|
||||
cpudata->ppdev = platform_profile_register(get_cpu_device(policy->cpu),
|
||||
cpudata->profile_name,
|
||||
@@ -1427,7 +1425,7 @@ ssize_t store_energy_performance_preference(struct cpufreq_policy *policy,
|
||||
if (ret)
|
||||
epp = epp_values[ret];
|
||||
else
|
||||
epp = amd_pstate_get_balanced_epp(policy);
|
||||
epp = cpudata->epp_default_dc;
|
||||
}
|
||||
|
||||
if (cpudata->policy == CPUFREQ_POLICY_PERFORMANCE) {
|
||||
@@ -1707,6 +1705,8 @@ static int amd_pstate_change_driver_mode(int mode)
|
||||
{
|
||||
int ret;
|
||||
|
||||
lockdep_assert_held(&amd_pstate_driver_lock);
|
||||
|
||||
ret = amd_pstate_unregister_driver(0);
|
||||
if (ret)
|
||||
return ret;
|
||||
@@ -1821,8 +1821,16 @@ static ssize_t dynamic_epp_store(struct device *a, struct device_attribute *b,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (dynamic_epp == enabled)
|
||||
guard(mutex)(&amd_pstate_driver_lock);
|
||||
|
||||
if (cppc_state != AMD_PSTATE_ACTIVE) {
|
||||
pr_debug("dynamic_epp can only be toggled in active mode\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Nothing to do */
|
||||
if (dynamic_epp == enabled)
|
||||
return count;
|
||||
|
||||
/* reinitialize with desired dynamic EPP value */
|
||||
dynamic_epp = enabled;
|
||||
@@ -1942,7 +1950,7 @@ static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy)
|
||||
if (dynamic_epp)
|
||||
ret = amd_pstate_set_dynamic_epp(policy);
|
||||
else
|
||||
ret = amd_pstate_set_epp(policy, amd_pstate_get_balanced_epp(policy));
|
||||
ret = amd_pstate_set_epp(policy, cpudata->epp_default_dc);
|
||||
if (ret)
|
||||
goto free_cpudata1;
|
||||
|
||||
@@ -1970,12 +1978,13 @@ static void amd_pstate_epp_cpu_exit(struct cpufreq_policy *policy)
|
||||
if (cpudata) {
|
||||
union perf_cached perf = READ_ONCE(cpudata->perf);
|
||||
|
||||
if (cpudata->dynamic_epp)
|
||||
amd_pstate_clear_dynamic_epp(policy);
|
||||
|
||||
/* Reset CPPC_REQ MSR to the BIOS value */
|
||||
amd_pstate_update_perf(policy, perf.bios_min_perf, 0U, 0U, 0U, false);
|
||||
amd_pstate_set_floor_perf(policy, cpudata->bios_floor_perf);
|
||||
|
||||
if (cpudata->dynamic_epp)
|
||||
amd_pstate_clear_dynamic_epp(policy);
|
||||
kfree(cpudata);
|
||||
policy->driver_data = NULL;
|
||||
}
|
||||
|
||||
@@ -2279,7 +2279,7 @@ static int hwp_get_cpu_scaling(int cpu)
|
||||
* Return the hybrid scaling factor for P-cores and use the
|
||||
* default core scaling for E-cores.
|
||||
*/
|
||||
if (hybrid_get_cpu_type(cpu) == INTEL_CPU_TYPE_CORE)
|
||||
if (hybrid_get_cpu_type(cpu) != INTEL_CPU_TYPE_ATOM)
|
||||
return hybrid_scaling_factor;
|
||||
|
||||
return core_get_scaling();
|
||||
@@ -3734,6 +3734,7 @@ static const struct x86_cpu_id intel_hybrid_scaling_factor[] = {
|
||||
X86_MATCH_VFM(INTEL_RAPTORLAKE, HYBRID_SCALING_FACTOR_ADL),
|
||||
X86_MATCH_VFM(INTEL_RAPTORLAKE_P, HYBRID_SCALING_FACTOR_ADL),
|
||||
X86_MATCH_VFM(INTEL_RAPTORLAKE_S, HYBRID_SCALING_FACTOR_ADL),
|
||||
X86_MATCH_VFM(INTEL_BARTLETTLAKE, HYBRID_SCALING_FACTOR_ADL),
|
||||
X86_MATCH_VFM(INTEL_METEORLAKE_L, HYBRID_SCALING_FACTOR_MTL),
|
||||
X86_MATCH_VFM(INTEL_LUNARLAKE_M, HYBRID_SCALING_FACTOR_LNL),
|
||||
{}
|
||||
|
||||
@@ -968,9 +968,12 @@ static int gpio_aggregator_activate(struct gpio_aggregator *aggr)
|
||||
}
|
||||
|
||||
wait_for_device_probe();
|
||||
if (!device_is_bound(&pdev->dev)) {
|
||||
ret = -ENXIO;
|
||||
goto err_unregister_pdev;
|
||||
|
||||
scoped_guard(device, &pdev->dev) {
|
||||
if (!device_is_bound(&pdev->dev)) {
|
||||
ret = -ENXIO;
|
||||
goto err_unregister_pdev;
|
||||
}
|
||||
}
|
||||
|
||||
aggr->pdev = pdev;
|
||||
@@ -979,8 +982,8 @@ static int gpio_aggregator_activate(struct gpio_aggregator *aggr)
|
||||
err_unregister_pdev:
|
||||
platform_device_unregister(pdev);
|
||||
err_remove_lookup_table:
|
||||
kfree(aggr->lookups->dev_id);
|
||||
gpiod_remove_lookup_table(aggr->lookups);
|
||||
kfree(aggr->lookups->dev_id);
|
||||
err_remove_swnode:
|
||||
fwnode_remove_software_node(swnode);
|
||||
err_remove_lookups:
|
||||
@@ -991,11 +994,15 @@ err_remove_lookups:
|
||||
|
||||
static void gpio_aggregator_deactivate(struct gpio_aggregator *aggr)
|
||||
{
|
||||
struct fwnode_handle *swnode;
|
||||
|
||||
swnode = dev_fwnode(&aggr->pdev->dev);
|
||||
platform_device_unregister(aggr->pdev);
|
||||
aggr->pdev = NULL;
|
||||
gpiod_remove_lookup_table(aggr->lookups);
|
||||
kfree(aggr->lookups->dev_id);
|
||||
kfree(aggr->lookups);
|
||||
fwnode_remove_software_node(swnode);
|
||||
}
|
||||
|
||||
static void gpio_aggregator_lockup_configfs(struct gpio_aggregator *aggr,
|
||||
|
||||
@@ -1411,7 +1411,7 @@ static int pca953x_resume(struct device *dev)
|
||||
ret = regulator_enable(chip->regulator);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to enable regulator: %d\n", ret);
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -901,7 +901,7 @@ static int gpio_sim_device_activate(struct gpio_sim_device *dev)
|
||||
struct platform_device *pdev;
|
||||
struct fwnode_handle *swnode;
|
||||
struct gpio_sim_bank *bank;
|
||||
int ret;
|
||||
int ret = 0;
|
||||
|
||||
lockdep_assert_held(&dev->lock);
|
||||
|
||||
@@ -945,9 +945,12 @@ static int gpio_sim_device_activate(struct gpio_sim_device *dev)
|
||||
}
|
||||
|
||||
wait_for_device_probe();
|
||||
if (!device_is_bound(&pdev->dev)) {
|
||||
ret = -ENXIO;
|
||||
goto err_unregister_pdev;
|
||||
|
||||
scoped_guard(device, &pdev->dev) {
|
||||
if (!device_is_bound(&pdev->dev)) {
|
||||
ret = -ENXIO;
|
||||
goto err_unregister_pdev;
|
||||
}
|
||||
}
|
||||
|
||||
dev->pdev = pdev;
|
||||
|
||||
@@ -1477,9 +1477,12 @@ gpio_virtuser_device_activate(struct gpio_virtuser_device *dev)
|
||||
}
|
||||
|
||||
wait_for_device_probe();
|
||||
if (!device_is_bound(&pdev->dev)) {
|
||||
ret = -ENXIO;
|
||||
goto err_unregister_pdev;
|
||||
|
||||
scoped_guard(device, &pdev->dev) {
|
||||
if (!device_is_bound(&pdev->dev)) {
|
||||
ret = -ENXIO;
|
||||
goto err_unregister_pdev;
|
||||
}
|
||||
}
|
||||
|
||||
dev->pdev = pdev;
|
||||
|
||||
@@ -1184,6 +1184,7 @@ static int gpio_v2_line_flags_validate(u64 flags)
|
||||
static int gpio_v2_line_config_validate(struct gpio_v2_line_config *lc,
|
||||
unsigned int num_lines)
|
||||
{
|
||||
size_t unused_attrs;
|
||||
unsigned int i;
|
||||
u64 flags;
|
||||
int ret;
|
||||
@@ -1191,9 +1192,21 @@ static int gpio_v2_line_config_validate(struct gpio_v2_line_config *lc,
|
||||
if (lc->num_attrs > GPIO_V2_LINE_NUM_ATTRS_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
unused_attrs = GPIO_V2_LINE_NUM_ATTRS_MAX - lc->num_attrs;
|
||||
|
||||
if (!mem_is_zero(lc->padding, sizeof(lc->padding)))
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < lc->num_attrs; i++) {
|
||||
if (lc->attrs[i].attr.padding != 0)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (unused_attrs) {
|
||||
if (!mem_is_zero(&lc->attrs[lc->num_attrs], unused_attrs * sizeof(*lc->attrs)))
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_lines; i++) {
|
||||
flags = gpio_v2_line_config_flags(lc, i);
|
||||
ret = gpio_v2_line_flags_validate(flags);
|
||||
|
||||
+30
-4
@@ -966,7 +966,8 @@ static bool nvme_pci_prp_save_mapping(struct request *req,
|
||||
{
|
||||
struct nvme_iod *iod = blk_mq_rq_to_pdu(req);
|
||||
|
||||
if (dma_use_iova(&iod->dma_state) || !dma_need_unmap(dma_dev))
|
||||
if (dma_use_iova(&iod->dma_state) || !dma_need_unmap(dma_dev) ||
|
||||
(iod->flags & IOD_DATA_P2P))
|
||||
return true;
|
||||
|
||||
if (!iod->nr_dma_vecs) {
|
||||
@@ -996,6 +997,23 @@ static bool nvme_pci_prp_iter_next(struct request *req, struct device *dma_dev,
|
||||
return nvme_pci_prp_save_mapping(req, dma_dev, iter);
|
||||
}
|
||||
|
||||
static void nvme_unmap_iter(struct request *req, struct blk_dma_iter *iter,
|
||||
struct dma_iova_state *state)
|
||||
{
|
||||
struct nvme_queue *nvmeq = req->mq_hctx->driver_data;
|
||||
struct device *dev = nvmeq->dev->dev;
|
||||
|
||||
if (!blk_rq_dma_unmap(req, dev, state, iter->len, iter->p2pdma.map)) {
|
||||
unsigned int attrs = 0;
|
||||
|
||||
if (iter->p2pdma.map == PCI_P2PDMA_MAP_THRU_HOST_BRIDGE)
|
||||
attrs |= DMA_ATTR_MMIO;
|
||||
|
||||
dma_unmap_phys(dev, iter->addr, iter->len, rq_dma_dir(req),
|
||||
attrs);
|
||||
}
|
||||
}
|
||||
|
||||
static blk_status_t nvme_pci_setup_data_prp(struct request *req,
|
||||
struct blk_dma_iter *iter)
|
||||
{
|
||||
@@ -1006,8 +1024,10 @@ static blk_status_t nvme_pci_setup_data_prp(struct request *req,
|
||||
unsigned int prp_len, i;
|
||||
__le64 *prp_list;
|
||||
|
||||
if (!nvme_pci_prp_save_mapping(req, nvmeq->dev->dev, iter))
|
||||
if (!nvme_pci_prp_save_mapping(req, nvmeq->dev->dev, iter)) {
|
||||
nvme_unmap_iter(req, iter, &iod->dma_state);
|
||||
return iter->status;
|
||||
}
|
||||
|
||||
/*
|
||||
* PRP1 always points to the start of the DMA transfers.
|
||||
@@ -1112,6 +1132,7 @@ bad_sgl:
|
||||
dev_err_once(nvmeq->dev->dev,
|
||||
"Incorrectly formed request for payload:%d nents:%d\n",
|
||||
blk_rq_payload_bytes(req), blk_rq_nr_phys_segments(req));
|
||||
nvme_unmap_data(req);
|
||||
return BLK_STS_IOERR;
|
||||
}
|
||||
|
||||
@@ -1155,8 +1176,11 @@ static blk_status_t nvme_pci_setup_data_sgl(struct request *req,
|
||||
|
||||
sg_list = dma_pool_alloc(nvme_dma_pool(nvmeq, iod), GFP_ATOMIC,
|
||||
&sgl_dma);
|
||||
if (!sg_list)
|
||||
if (!sg_list) {
|
||||
nvme_unmap_iter(req, iter, &iod->dma_state);
|
||||
return BLK_STS_RESOURCE;
|
||||
}
|
||||
|
||||
iod->descriptors[iod->nr_descriptors++] = sg_list;
|
||||
|
||||
do {
|
||||
@@ -1313,8 +1337,10 @@ static blk_status_t nvme_pci_setup_meta_iter(struct request *req)
|
||||
|
||||
sg_list = dma_pool_alloc(nvmeq->descriptor_pools.small, GFP_ATOMIC,
|
||||
&sgl_dma);
|
||||
if (!sg_list)
|
||||
if (!sg_list) {
|
||||
nvme_unmap_iter(req, &iter, &iod->meta_dma_state);
|
||||
return BLK_STS_RESOURCE;
|
||||
}
|
||||
|
||||
iod->meta_descriptor = sg_list;
|
||||
iod->meta_dma = sgl_dma;
|
||||
|
||||
@@ -1142,8 +1142,8 @@ int __init chsc_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
sei_page = (void *)get_zeroed_page(GFP_KERNEL);
|
||||
chsc_page = (void *)get_zeroed_page(GFP_KERNEL);
|
||||
sei_page = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
|
||||
chsc_page = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
|
||||
if (!sei_page || !chsc_page) {
|
||||
ret = -ENOMEM;
|
||||
goto out_err;
|
||||
|
||||
+10
-10
@@ -292,7 +292,7 @@ static int chsc_ioctl_start(void __user *user_area)
|
||||
if (!css_general_characteristics.dynio)
|
||||
/* It makes no sense to try. */
|
||||
return -EOPNOTSUPP;
|
||||
chsc_area = (void *)get_zeroed_page(GFP_KERNEL);
|
||||
chsc_area = (void *)get_zeroed_page(GFP_DMA | GFP_KERNEL);
|
||||
if (!chsc_area)
|
||||
return -ENOMEM;
|
||||
request = kzalloc_obj(*request);
|
||||
@@ -340,7 +340,7 @@ static int chsc_ioctl_on_close_set(void __user *user_area)
|
||||
ret = -ENOMEM;
|
||||
goto out_unlock;
|
||||
}
|
||||
on_close_chsc_area = (void *)get_zeroed_page(GFP_KERNEL);
|
||||
on_close_chsc_area = (void *)get_zeroed_page(GFP_DMA | GFP_KERNEL);
|
||||
if (!on_close_chsc_area) {
|
||||
ret = -ENOMEM;
|
||||
goto out_free_request;
|
||||
@@ -392,7 +392,7 @@ static int chsc_ioctl_start_sync(void __user *user_area)
|
||||
struct chsc_sync_area *chsc_area;
|
||||
int ret, ccode;
|
||||
|
||||
chsc_area = (void *)get_zeroed_page(GFP_KERNEL);
|
||||
chsc_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
|
||||
if (!chsc_area)
|
||||
return -ENOMEM;
|
||||
if (copy_from_user(chsc_area, user_area, PAGE_SIZE)) {
|
||||
@@ -438,7 +438,7 @@ static int chsc_ioctl_info_channel_path(void __user *user_cd)
|
||||
u8 data[PAGE_SIZE - 20];
|
||||
} __attribute__ ((packed)) *scpcd_area;
|
||||
|
||||
scpcd_area = (void *)get_zeroed_page(GFP_KERNEL);
|
||||
scpcd_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
|
||||
if (!scpcd_area)
|
||||
return -ENOMEM;
|
||||
cd = kzalloc_obj(*cd);
|
||||
@@ -500,7 +500,7 @@ static int chsc_ioctl_info_cu(void __user *user_cd)
|
||||
u8 data[PAGE_SIZE - 20];
|
||||
} __attribute__ ((packed)) *scucd_area;
|
||||
|
||||
scucd_area = (void *)get_zeroed_page(GFP_KERNEL);
|
||||
scucd_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
|
||||
if (!scucd_area)
|
||||
return -ENOMEM;
|
||||
cd = kzalloc_obj(*cd);
|
||||
@@ -563,7 +563,7 @@ static int chsc_ioctl_info_sch_cu(void __user *user_cud)
|
||||
u8 data[PAGE_SIZE - 20];
|
||||
} __attribute__ ((packed)) *sscud_area;
|
||||
|
||||
sscud_area = (void *)get_zeroed_page(GFP_KERNEL);
|
||||
sscud_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
|
||||
if (!sscud_area)
|
||||
return -ENOMEM;
|
||||
cud = kzalloc_obj(*cud);
|
||||
@@ -625,7 +625,7 @@ static int chsc_ioctl_conf_info(void __user *user_ci)
|
||||
u8 data[PAGE_SIZE - 20];
|
||||
} __attribute__ ((packed)) *sci_area;
|
||||
|
||||
sci_area = (void *)get_zeroed_page(GFP_KERNEL);
|
||||
sci_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
|
||||
if (!sci_area)
|
||||
return -ENOMEM;
|
||||
ci = kzalloc_obj(*ci);
|
||||
@@ -696,7 +696,7 @@ static int chsc_ioctl_conf_comp_list(void __user *user_ccl)
|
||||
u32 res;
|
||||
} __attribute__ ((packed)) *cssids_parm;
|
||||
|
||||
sccl_area = (void *)get_zeroed_page(GFP_KERNEL);
|
||||
sccl_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
|
||||
if (!sccl_area)
|
||||
return -ENOMEM;
|
||||
ccl = kzalloc_obj(*ccl);
|
||||
@@ -756,7 +756,7 @@ static int chsc_ioctl_chpd(void __user *user_chpd)
|
||||
int ret;
|
||||
|
||||
chpd = kzalloc_obj(*chpd);
|
||||
scpd_area = (void *)get_zeroed_page(GFP_KERNEL);
|
||||
scpd_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
|
||||
if (!scpd_area || !chpd) {
|
||||
ret = -ENOMEM;
|
||||
goto out_free;
|
||||
@@ -796,7 +796,7 @@ static int chsc_ioctl_dcal(void __user *user_dcal)
|
||||
u8 data[PAGE_SIZE - 36];
|
||||
} __attribute__ ((packed)) *sdcal_area;
|
||||
|
||||
sdcal_area = (void *)get_zeroed_page(GFP_KERNEL);
|
||||
sdcal_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
|
||||
if (!sdcal_area)
|
||||
return -ENOMEM;
|
||||
dcal = kzalloc_obj(*dcal);
|
||||
|
||||
@@ -229,7 +229,7 @@ int scm_update_information(void)
|
||||
size_t num;
|
||||
int ret;
|
||||
|
||||
scm_info = (void *)__get_free_page(GFP_KERNEL);
|
||||
scm_info = (void *)__get_free_page(GFP_KERNEL | GFP_DMA);
|
||||
if (!scm_info)
|
||||
return -ENOMEM;
|
||||
|
||||
|
||||
@@ -868,7 +868,7 @@ static int amd_spi_probe(struct platform_device *pdev)
|
||||
dev_dbg(dev, "io_remap_address: %p\n", amd_spi->io_remap_addr);
|
||||
|
||||
amd_spi->version = (uintptr_t)device_get_match_data(dev);
|
||||
host->bus_num = 0;
|
||||
host->bus_num = (amd_spi->version == AMD_HID2_SPI) ? 2 : 0;
|
||||
|
||||
return amd_spi_probe_common(dev, host);
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
*/
|
||||
|
||||
#include <linux/list.h>
|
||||
#include <linux/cred.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/string.h>
|
||||
#include <keys/user-type.h>
|
||||
@@ -40,12 +41,27 @@ cifs_spnego_key_destroy(struct key *key)
|
||||
kfree(key->payload.data[0]);
|
||||
}
|
||||
|
||||
static int
|
||||
cifs_spnego_key_vet_description(const char *description)
|
||||
{
|
||||
/*
|
||||
* cifs.spnego descriptions are authority-bearing inputs to cifs.upcall.
|
||||
* They are only valid when produced by CIFS while using the private
|
||||
* spnego_cred installed below. Do not let userspace create this type
|
||||
* of key through request_key(2)/add_key(2), since the helper treats
|
||||
* pid/uid/creduid/upcall_target as kernel-originating fields.
|
||||
*/
|
||||
if (current_cred() != spnego_cred)
|
||||
return -EPERM;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* keytype for CIFS spnego keys
|
||||
*/
|
||||
struct key_type cifs_spnego_key_type = {
|
||||
.name = "cifs.spnego",
|
||||
.vet_description = cifs_spnego_key_vet_description,
|
||||
.instantiate = cifs_spnego_key_instantiate,
|
||||
.destroy = cifs_spnego_key_destroy,
|
||||
.describe = user_describe,
|
||||
|
||||
@@ -306,6 +306,8 @@ static void cifs_kill_sb(struct super_block *sb)
|
||||
|
||||
/* Wait for all pending oplock breaks to complete */
|
||||
flush_workqueue(cifsoplockd_wq);
|
||||
/* Wait for all opened files to release */
|
||||
flush_workqueue(deferredclose_wq);
|
||||
|
||||
/* finally release root dentry */
|
||||
dput(cifs_sb->root);
|
||||
|
||||
@@ -420,7 +420,7 @@ static int parse_symlink_flavor(struct fs_context *fc, char *value,
|
||||
#define DUP_CTX_STR(field) \
|
||||
do { \
|
||||
if (ctx->field) { \
|
||||
new_ctx->field = kstrdup(ctx->field, GFP_ATOMIC); \
|
||||
new_ctx->field = kstrdup(ctx->field, GFP_KERNEL); \
|
||||
if (new_ctx->field == NULL) { \
|
||||
smb3_cleanup_fs_context_contents(new_ctx); \
|
||||
return -ENOMEM; \
|
||||
|
||||
@@ -33,13 +33,17 @@ static const struct nla_policy cifs_genl_policy[CIFS_GENL_ATTR_MAX + 1] = {
|
||||
static const struct genl_ops cifs_genl_ops[] = {
|
||||
{
|
||||
.cmd = CIFS_GENL_CMD_SWN_NOTIFY,
|
||||
.flags = GENL_ADMIN_PERM,
|
||||
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
|
||||
.doit = cifs_swn_notify,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct genl_multicast_group cifs_genl_mcgrps[] = {
|
||||
[CIFS_GENL_MCGRP_SWN] = { .name = CIFS_GENL_MCGRP_SWN_NAME },
|
||||
[CIFS_GENL_MCGRP_SWN] = {
|
||||
.name = CIFS_GENL_MCGRP_SWN_NAME,
|
||||
.flags = GENL_MCAST_CAP_NET_ADMIN,
|
||||
},
|
||||
};
|
||||
|
||||
struct genl_family cifs_genl_family = {
|
||||
|
||||
@@ -4836,7 +4836,7 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid,
|
||||
}
|
||||
|
||||
/* Copy the data to the output I/O iterator. */
|
||||
rdata->result = cifs_copy_folioq_to_iter(buffer, buffer_len,
|
||||
rdata->result = cifs_copy_folioq_to_iter(buffer, data_len,
|
||||
cur_off, &rdata->subreq.io_iter);
|
||||
if (rdata->result != 0) {
|
||||
if (is_offloaded)
|
||||
@@ -4845,7 +4845,7 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid,
|
||||
dequeue_mid(server, mid, rdata->result);
|
||||
return 0;
|
||||
}
|
||||
rdata->got_bytes = buffer_len;
|
||||
rdata->got_bytes = data_len;
|
||||
|
||||
} else if (!check_add_overflow(data_offset, data_len, &end_off) &&
|
||||
buf_len >= end_off) {
|
||||
|
||||
@@ -169,7 +169,9 @@ smb2_find_smb_sess_tcon_unlocked(struct cifs_ses *ses, __u32 tid)
|
||||
list_for_each_entry(tcon, &ses->tcon_list, tcon_list) {
|
||||
if (tcon->tid != tid)
|
||||
continue;
|
||||
spin_lock(&tcon->tc_lock);
|
||||
++tcon->tc_count;
|
||||
spin_unlock(&tcon->tc_lock);
|
||||
trace_smb3_tcon_ref(tcon->debug_id, tcon->tc_count,
|
||||
netfs_trace_tcon_ref_get_find_sess_tcon);
|
||||
return tcon;
|
||||
|
||||
@@ -40,7 +40,7 @@ void smbdirect_connection_legacy_debug_proc_show(struct smbdirect_socket *sc,
|
||||
|
||||
seq_puts(m, "\n");
|
||||
seq_printf(m, "Conn keep_alive_interval: %u ",
|
||||
sp->keepalive_interval_msec * 1000);
|
||||
sp->keepalive_interval_msec / 1000);
|
||||
seq_printf(m, "max_readwrite_size: %u rdma_readwrite_threshold: %u",
|
||||
sp->max_read_write_size,
|
||||
rdma_readwrite_threshold);
|
||||
|
||||
+5
-1
@@ -610,10 +610,14 @@ static long zonefs_fname_to_fno(const struct qstr *fname)
|
||||
return c - '0';
|
||||
|
||||
for (i = 0, rname = name + len - 1; i < len; i++, rname--) {
|
||||
long digit;
|
||||
|
||||
c = *rname;
|
||||
if (!isdigit(c))
|
||||
return -ENOENT;
|
||||
fno += (c - '0') * shift;
|
||||
digit = (c - '0') * shift;
|
||||
if (check_add_overflow(fno, digit, &fno))
|
||||
return -ENOENT;
|
||||
shift *= 10;
|
||||
}
|
||||
|
||||
|
||||
+4
-5
@@ -1738,10 +1738,9 @@ static int io_init_req(struct io_ring_ctx *ctx, struct io_kiocb *req,
|
||||
const struct io_issue_def *def;
|
||||
unsigned int sqe_flags;
|
||||
int personality;
|
||||
u8 opcode;
|
||||
|
||||
req->ctx = ctx;
|
||||
req->opcode = opcode = READ_ONCE(sqe->opcode);
|
||||
req->opcode = READ_ONCE(sqe->opcode);
|
||||
/* same numerical values with corresponding REQ_F_*, safe to copy */
|
||||
sqe_flags = READ_ONCE(sqe->flags);
|
||||
req->flags = (__force io_req_flags_t) sqe_flags;
|
||||
@@ -1751,13 +1750,13 @@ static int io_init_req(struct io_ring_ctx *ctx, struct io_kiocb *req,
|
||||
req->cancel_seq_set = false;
|
||||
req->async_data = NULL;
|
||||
|
||||
if (unlikely(opcode >= IORING_OP_LAST)) {
|
||||
if (unlikely(req->opcode >= IORING_OP_LAST)) {
|
||||
req->opcode = 0;
|
||||
return io_init_fail_req(req, -EINVAL);
|
||||
}
|
||||
opcode = array_index_nospec(opcode, IORING_OP_LAST);
|
||||
req->opcode = array_index_nospec(req->opcode, IORING_OP_LAST);
|
||||
|
||||
def = &io_issue_defs[opcode];
|
||||
def = &io_issue_defs[req->opcode];
|
||||
if (def->is_128 && !(ctx->flags & IORING_SETUP_SQE128)) {
|
||||
/*
|
||||
* A 128b op on a non-128b SQ requires mixed SQE support as
|
||||
|
||||
+25
-1
@@ -4,6 +4,7 @@
|
||||
#include <linux/file.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/net.h>
|
||||
#include <linux/un.h>
|
||||
#include <linux/compat.h>
|
||||
#include <net/compat.h>
|
||||
#include <linux/io_uring.h>
|
||||
@@ -1799,11 +1800,29 @@ out:
|
||||
return IOU_COMPLETE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if bind request would potentially end up with filename_create(),
|
||||
* which in turn end up in mnt_want_write() which will grab the fs
|
||||
* percpu start write sem. This can trigger a lockdep warning.
|
||||
*/
|
||||
static int io_bind_file_create(const struct io_async_msghdr *io, int addr_len)
|
||||
{
|
||||
const struct sockaddr_un *sun;
|
||||
|
||||
if (io->addr.ss_family != AF_UNIX)
|
||||
return 0;
|
||||
if (addr_len <= offsetof(struct sockaddr_un, sun_path))
|
||||
return 0;
|
||||
sun = (const struct sockaddr_un *) &io->addr;
|
||||
return sun->sun_path[0] != '\0';
|
||||
}
|
||||
|
||||
int io_bind_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
|
||||
{
|
||||
struct io_bind *bind = io_kiocb_to_cmd(req, struct io_bind);
|
||||
struct sockaddr __user *uaddr;
|
||||
struct io_async_msghdr *io;
|
||||
int ret;
|
||||
|
||||
if (sqe->len || sqe->buf_index || sqe->rw_flags || sqe->splice_fd_in)
|
||||
return -EINVAL;
|
||||
@@ -1814,7 +1833,12 @@ int io_bind_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
|
||||
io = io_msg_alloc_async(req);
|
||||
if (unlikely(!io))
|
||||
return -ENOMEM;
|
||||
return move_addr_to_kernel(uaddr, bind->addr_len, &io->addr);
|
||||
ret = move_addr_to_kernel(uaddr, bind->addr_len, &io->addr);
|
||||
if (unlikely(ret))
|
||||
return ret;
|
||||
if (io_bind_file_create(io, bind->addr_len))
|
||||
req->flags |= REQ_F_FORCE_ASYNC;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int io_bind(struct io_kiocb *req, unsigned int issue_flags)
|
||||
|
||||
+2
-2
@@ -79,9 +79,9 @@ done:
|
||||
if (ret < 0)
|
||||
req_set_fail(req);
|
||||
if (nop->flags & IORING_NOP_CQE32)
|
||||
io_req_set_res32(req, nop->result, 0, nop->extra1, nop->extra2);
|
||||
io_req_set_res32(req, ret, 0, nop->extra1, nop->extra2);
|
||||
else
|
||||
io_req_set_res(req, nop->result, 0);
|
||||
io_req_set_res(req, ret, 0);
|
||||
if (nop->flags & IORING_NOP_TW) {
|
||||
req->io_task_work.func = io_req_task_complete;
|
||||
io_req_task_work_add(req);
|
||||
|
||||
+3
-1
@@ -417,8 +417,10 @@ static enum hrtimer_restart io_link_timeout_fn(struct hrtimer *timer)
|
||||
* done in io_req_task_link_timeout(), if needed.
|
||||
*/
|
||||
if (prev) {
|
||||
if (!req_ref_inc_not_zero(prev))
|
||||
if (!req_ref_inc_not_zero(prev)) {
|
||||
io_remove_next_linked(prev);
|
||||
prev = NULL;
|
||||
}
|
||||
}
|
||||
list_del(&timeout->list);
|
||||
timeout->prev = prev;
|
||||
|
||||
@@ -275,6 +275,7 @@ int io_waitid_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
|
||||
iw->options = READ_ONCE(sqe->file_index);
|
||||
iw->head = NULL;
|
||||
iw->infop = u64_to_user_ptr(READ_ONCE(sqe->addr2));
|
||||
memset(&iw->info, 0, sizeof(iw->info));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -334,7 +334,7 @@ int snd_parse_eld(struct device *dev, struct snd_parsed_hdmi_eld *e,
|
||||
e->eld_ver = GRAB_BITS(buf, 0, 3, 5);
|
||||
if (e->eld_ver != ELD_VER_CEA_861D &&
|
||||
e->eld_ver != ELD_VER_PARTIAL) {
|
||||
dev_info(dev, "HDMI: Unknown ELD version %d\n", e->eld_ver);
|
||||
dev_info_ratelimited(dev, "HDMI: Unknown ELD version %d\n", e->eld_ver);
|
||||
goto out_fail;
|
||||
}
|
||||
|
||||
@@ -357,7 +357,7 @@ int snd_parse_eld(struct device *dev, struct snd_parsed_hdmi_eld *e,
|
||||
e->product_id = get_unaligned_le16(buf + 18);
|
||||
|
||||
if (mnl > ELD_MAX_MNL) {
|
||||
dev_info(dev, "HDMI: MNL is reserved value %d\n", mnl);
|
||||
dev_info_ratelimited(dev, "HDMI: MNL is reserved value %d\n", mnl);
|
||||
goto out_fail;
|
||||
} else if (ELD_FIXED_BYTES + mnl > size) {
|
||||
dev_info(dev, "HDMI: out of range MNL %d\n", mnl);
|
||||
|
||||
@@ -2138,6 +2138,9 @@ static int interleaved_copy(struct snd_pcm_substream *substream,
|
||||
off = frames_to_bytes(runtime, off);
|
||||
frames = frames_to_bytes(runtime, frames);
|
||||
|
||||
if (!data)
|
||||
return fill_silence(substream, 0, hwoff, NULL, frames);
|
||||
|
||||
return do_transfer(substream, 0, hwoff, data + off, frames, transfer,
|
||||
in_kernel);
|
||||
}
|
||||
|
||||
@@ -144,18 +144,21 @@ int snd_seq_create_port(struct snd_seq_client *client, int port,
|
||||
num = max(port, 0);
|
||||
guard(mutex)(&client->ports_mutex);
|
||||
guard(write_lock_irq)(&client->ports_lock);
|
||||
struct list_head *insert_before = &client->ports_list_head;
|
||||
list_for_each_entry(p, &client->ports_list_head, list) {
|
||||
if (p->addr.port == port) {
|
||||
kfree(new_port);
|
||||
return -EBUSY;
|
||||
}
|
||||
if (p->addr.port > num)
|
||||
if (p->addr.port > num) {
|
||||
insert_before = &p->list;
|
||||
break;
|
||||
}
|
||||
if (port < 0) /* auto-probe mode */
|
||||
num = p->addr.port + 1;
|
||||
}
|
||||
/* insert the new port */
|
||||
list_add_tail(&new_port->list, &p->list);
|
||||
list_add_tail(&new_port->list, insert_before);
|
||||
client->num_ports++;
|
||||
new_port->addr.port = num; /* store the port number in the port */
|
||||
sprintf(new_port->name, "port-%d", num);
|
||||
|
||||
@@ -37,6 +37,7 @@ struct seq_ump_client {
|
||||
struct snd_ump_endpoint *ump; /* assigned endpoint */
|
||||
int seq_client; /* sequencer client id */
|
||||
int opened[2]; /* current opens for each direction */
|
||||
rwlock_t output_lock; /* protects out_rfile output access */
|
||||
struct snd_rawmidi_file out_rfile; /* rawmidi for output */
|
||||
struct seq_ump_input_buffer input; /* input parser context */
|
||||
void *ump_info[SNDRV_UMP_MAX_BLOCKS + 1]; /* shadow of seq client ump_info */
|
||||
@@ -88,6 +89,7 @@ static int seq_ump_process_event(struct snd_seq_event *ev, int direct,
|
||||
unsigned char type;
|
||||
int len;
|
||||
|
||||
guard(read_lock_irqsave)(&client->output_lock);
|
||||
substream = client->out_rfile.output;
|
||||
if (!substream)
|
||||
return -ENODEV;
|
||||
@@ -106,6 +108,7 @@ static int seq_ump_process_event(struct snd_seq_event *ev, int direct,
|
||||
static int seq_ump_client_open(struct seq_ump_client *client, int dir)
|
||||
{
|
||||
struct snd_ump_endpoint *ump = client->ump;
|
||||
struct snd_rawmidi_file rfile = {};
|
||||
int err;
|
||||
|
||||
guard(mutex)(&ump->open_mutex);
|
||||
@@ -113,9 +116,11 @@ static int seq_ump_client_open(struct seq_ump_client *client, int dir)
|
||||
err = snd_rawmidi_kernel_open(&ump->core, 0,
|
||||
SNDRV_RAWMIDI_LFLG_OUTPUT |
|
||||
SNDRV_RAWMIDI_LFLG_APPEND,
|
||||
&client->out_rfile);
|
||||
&rfile);
|
||||
if (err < 0)
|
||||
return err;
|
||||
scoped_guard(write_lock_irqsave, &client->output_lock)
|
||||
client->out_rfile = rfile;
|
||||
}
|
||||
client->opened[dir]++;
|
||||
return 0;
|
||||
@@ -125,11 +130,19 @@ static int seq_ump_client_open(struct seq_ump_client *client, int dir)
|
||||
static int seq_ump_client_close(struct seq_ump_client *client, int dir)
|
||||
{
|
||||
struct snd_ump_endpoint *ump = client->ump;
|
||||
struct snd_rawmidi_file rfile = {};
|
||||
|
||||
guard(mutex)(&ump->open_mutex);
|
||||
if (!--client->opened[dir])
|
||||
if (dir == STR_OUT)
|
||||
snd_rawmidi_kernel_release(&client->out_rfile);
|
||||
if (!--client->opened[dir]) {
|
||||
if (dir == STR_OUT) {
|
||||
scoped_guard(write_lock_irqsave, &client->output_lock) {
|
||||
rfile = client->out_rfile;
|
||||
client->out_rfile = (struct snd_rawmidi_file){};
|
||||
}
|
||||
if (rfile.rmidi)
|
||||
snd_rawmidi_kernel_release(&rfile);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -467,6 +480,7 @@ static int snd_seq_ump_probe(struct snd_seq_device *dev)
|
||||
|
||||
INIT_WORK(&client->group_notify_work, handle_group_notify);
|
||||
client->ump = ump;
|
||||
rwlock_init(&client->output_lock);
|
||||
|
||||
client->seq_client =
|
||||
snd_seq_create_kernel_client(card, ump->core.device,
|
||||
|
||||
+14
-5
@@ -1007,6 +1007,7 @@ static int snd_timer_dev_register(struct snd_device *dev)
|
||||
{
|
||||
struct snd_timer *timer = dev->device_data;
|
||||
struct snd_timer *timer1;
|
||||
struct list_head *insert_before = &snd_timer_list;
|
||||
|
||||
if (snd_BUG_ON(!timer || !timer->hw.start || !timer->hw.stop))
|
||||
return -ENXIO;
|
||||
@@ -1016,28 +1017,36 @@ static int snd_timer_dev_register(struct snd_device *dev)
|
||||
|
||||
guard(mutex)(®ister_mutex);
|
||||
list_for_each_entry(timer1, &snd_timer_list, device_list) {
|
||||
if (timer1->tmr_class > timer->tmr_class)
|
||||
if (timer1->tmr_class > timer->tmr_class) {
|
||||
insert_before = &timer1->device_list;
|
||||
break;
|
||||
}
|
||||
if (timer1->tmr_class < timer->tmr_class)
|
||||
continue;
|
||||
if (timer1->card && timer->card) {
|
||||
if (timer1->card->number > timer->card->number)
|
||||
if (timer1->card->number > timer->card->number) {
|
||||
insert_before = &timer1->device_list;
|
||||
break;
|
||||
}
|
||||
if (timer1->card->number < timer->card->number)
|
||||
continue;
|
||||
}
|
||||
if (timer1->tmr_device > timer->tmr_device)
|
||||
if (timer1->tmr_device > timer->tmr_device) {
|
||||
insert_before = &timer1->device_list;
|
||||
break;
|
||||
}
|
||||
if (timer1->tmr_device < timer->tmr_device)
|
||||
continue;
|
||||
if (timer1->tmr_subdevice > timer->tmr_subdevice)
|
||||
if (timer1->tmr_subdevice > timer->tmr_subdevice) {
|
||||
insert_before = &timer1->device_list;
|
||||
break;
|
||||
}
|
||||
if (timer1->tmr_subdevice < timer->tmr_subdevice)
|
||||
continue;
|
||||
/* conflicts.. */
|
||||
return -EBUSY;
|
||||
}
|
||||
list_add_tail(&timer->device_list, &timer1->device_list);
|
||||
list_add_tail(&timer->device_list, insert_before);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -6955,6 +6955,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
|
||||
SND_PCI_QUIRK(0x103c, 0x84da, "HP OMEN dc0019-ur", ALC295_FIXUP_HP_OMEN),
|
||||
SND_PCI_QUIRK(0x103c, 0x84e7, "HP Pavilion 15", ALC269_FIXUP_HP_MUTE_LED_MIC3),
|
||||
SND_PCI_QUIRK(0x103c, 0x8519, "HP Spectre x360 15-df0xxx", ALC285_FIXUP_HP_SPECTRE_X360),
|
||||
SND_PCI_QUIRK(0x103c, 0x8536, "HP ProBook 430 G6", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
|
||||
SND_PCI_QUIRK(0x103c, 0x8537, "HP ProBook 440 G6", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
|
||||
SND_PCI_QUIRK(0x103c, 0x8548, "HP EliteBook x360 830 G6", ALC285_FIXUP_HP_GPIO_LED),
|
||||
SND_PCI_QUIRK(0x103c, 0x854a, "HP EliteBook 830 G6", ALC285_FIXUP_HP_GPIO_LED),
|
||||
@@ -7084,6 +7085,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
|
||||
SND_PCI_QUIRK(0x103c, 0x8a30, "HP Envy 17", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
SND_PCI_QUIRK(0x103c, 0x8a31, "HP Envy 15", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
SND_PCI_QUIRK(0x103c, 0x8a34, "HP Pavilion x360 2-in-1 Laptop 14-ek0xxx", ALC245_FIXUP_HP_MUTE_LED_COEFBIT),
|
||||
SND_PCI_QUIRK(0x103c, 0x8a36, "HP Pavilion Plus 14-eh0xxx", ALC245_FIXUP_HP_MUTE_LED_COEFBIT),
|
||||
SND_PCI_QUIRK(0x103c, 0x8a3d, "HP Victus 15-fb0xxx (MB 8A3D)", ALC245_FIXUP_HP_MUTE_LED_V2_COEFBIT),
|
||||
SND_PCI_QUIRK(0x103c, 0x8a4f, "HP Victus 15-fa0xxx (MB 8A4F)", ALC245_FIXUP_HP_MUTE_LED_COEFBIT),
|
||||
SND_PCI_QUIRK(0x103c, 0x8a6e, "HP EDNA 360", ALC287_FIXUP_CS35L41_I2C_4),
|
||||
@@ -7103,6 +7105,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
|
||||
SND_PCI_QUIRK(0x103c, 0x8ad8, "HP 800 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
|
||||
SND_PCI_QUIRK(0x103c, 0x8b0f, "HP Elite mt645 G7 Mobile Thin Client U81", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
|
||||
SND_PCI_QUIRK(0x103c, 0x8b2f, "HP 255 15.6 inch G10 Notebook PC", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2),
|
||||
SND_PCI_QUIRK(0x103c, 0x8b34, "HP 250 15.6 inch G10 Notebook PC", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2),
|
||||
SND_PCI_QUIRK(0x103c, 0x8b3a, "HP Envy 15", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
SND_PCI_QUIRK(0x103c, 0x8b3f, "HP mt440 Mobile Thin Client U91", ALC236_FIXUP_HP_GPIO_LED),
|
||||
SND_PCI_QUIRK(0x103c, 0x8b42, "HP", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
|
||||
@@ -7229,7 +7232,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
|
||||
SND_PCI_QUIRK(0x103c, 0x8da0, "HP 16 Clipper OmniBook 7(X360)", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
SND_PCI_QUIRK(0x103c, 0x8da1, "HP 16 Clipper OmniBook X", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
SND_PCI_QUIRK(0x103c, 0x8da7, "HP 14 Enstrom OmniBook X", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
SND_PCI_QUIRK(0x103c, 0x8da8, "HP 16 Piston OmniBook X", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
SND_PCI_QUIRK(0x103c, 0x8da8, "HP 16 Piston OmniBook X", ALC245_FIXUP_HP_ENVY_X360_15_FH0XXX),
|
||||
SND_PCI_QUIRK(0x103c, 0x8dc9, "HP Laptop 15-fc0xxx", ALC236_FIXUP_HP_DMIC),
|
||||
SND_PCI_QUIRK(0x103c, 0x8dd4, "HP EliteStudio 8 AIO", ALC274_FIXUP_HP_AIO_BIND_DACS),
|
||||
SND_PCI_QUIRK(0x103c, 0x8dd7, "HP Laptop 15-fd0xxx", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2),
|
||||
@@ -7241,6 +7244,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
|
||||
SND_PCI_QUIRK(0x103c, 0x8def, "HP EliteBook 660 G12", ALC236_FIXUP_HP_GPIO_LED),
|
||||
SND_PCI_QUIRK(0x103c, 0x8df0, "HP EliteBook 630 G12", ALC236_FIXUP_HP_GPIO_LED),
|
||||
SND_PCI_QUIRK(0x103c, 0x8df1, "HP EliteBook 630 G12", ALC236_FIXUP_HP_GPIO_LED),
|
||||
SND_PCI_QUIRK(0x103c, 0x8df7, "HP Z66 G6", ALC236_FIXUP_HP_GPIO_LED),
|
||||
SND_PCI_QUIRK(0x103c, 0x8dfb, "HP EliteBook 6 G1a 14", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
|
||||
SND_PCI_QUIRK(0x103c, 0x8dfc, "HP EliteBook 645 G12", ALC236_FIXUP_HP_GPIO_LED),
|
||||
SND_PCI_QUIRK(0x103c, 0x8dfd, "HP EliteBook 6 G1a 16", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
|
||||
@@ -7453,12 +7457,12 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
|
||||
SND_PCI_QUIRK(0x1043, 0x3e00, "ASUS G814FH/FM/FP", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
SND_PCI_QUIRK(0x1043, 0x3e20, "ASUS G814PH/PM/PP", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
SND_PCI_QUIRK(0x1043, 0x3e30, "ASUS TP3607SA", ALC287_FIXUP_TAS2781_I2C),
|
||||
SND_PCI_QUIRK(0x1043, 0x3ee0, "ASUS Strix G815_JHR_JMR_JPR", ALC287_FIXUP_TAS2781_I2C),
|
||||
SND_PCI_QUIRK(0x1043, 0x3ef0, "ASUS Strix G635LR_LW_LX", ALC287_FIXUP_TAS2781_I2C),
|
||||
SND_PCI_QUIRK(0x1043, 0x3f00, "ASUS Strix G815LH_LM_LP", ALC287_FIXUP_TAS2781_I2C),
|
||||
SND_PCI_QUIRK(0x1043, 0x3f10, "ASUS Strix G835LR_LW_LX", ALC287_FIXUP_TAS2781_I2C),
|
||||
SND_PCI_QUIRK(0x1043, 0x3f20, "ASUS Strix G615LR_LW", ALC287_FIXUP_TAS2781_I2C),
|
||||
SND_PCI_QUIRK(0x1043, 0x3f30, "ASUS Strix G815LR_LW", ALC287_FIXUP_TAS2781_I2C),
|
||||
SND_PCI_QUIRK(0x1043, 0x3ee0, "ASUS Strix G815_JHR_JMR_JPR", ALC287_FIXUP_TXNW2781_I2C),
|
||||
SND_PCI_QUIRK(0x1043, 0x3ef0, "ASUS Strix G635LR_LW_LX", ALC287_FIXUP_TXNW2781_I2C),
|
||||
SND_PCI_QUIRK(0x1043, 0x3f00, "ASUS Strix G815LH_LM_LP", ALC287_FIXUP_TXNW2781_I2C),
|
||||
SND_PCI_QUIRK(0x1043, 0x3f10, "ASUS Strix G835LR_LW_LX", ALC287_FIXUP_TXNW2781_I2C),
|
||||
SND_PCI_QUIRK(0x1043, 0x3f20, "ASUS Strix G615LR_LW", ALC287_FIXUP_TXNW2781_I2C),
|
||||
SND_PCI_QUIRK(0x1043, 0x3f30, "ASUS Strix G815LR_LW", ALC287_FIXUP_TXNW2781_I2C),
|
||||
SND_PCI_QUIRK(0x1043, 0x3fd0, "ASUS B3605CVA", ALC245_FIXUP_CS35L41_SPI_2),
|
||||
SND_PCI_QUIRK(0x1043, 0x3ff0, "ASUS B5405CVA", ALC245_FIXUP_CS35L41_SPI_2),
|
||||
SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC),
|
||||
|
||||
@@ -1013,7 +1013,7 @@ void snd_hda_pick_fixup(struct hda_codec *codec,
|
||||
const char *name = NULL;
|
||||
const char *type = NULL;
|
||||
unsigned int vendor, device;
|
||||
u16 pci_vendor, pci_device;
|
||||
u16 pci_vendor = 0, pci_device = 0;
|
||||
u16 codec_vendor, codec_device;
|
||||
|
||||
if (codec->fixup_id != HDA_FIXUP_ID_NOT_SET)
|
||||
@@ -1066,7 +1066,7 @@ void snd_hda_pick_fixup(struct hda_codec *codec,
|
||||
/* match primarily with the PCI SSID */
|
||||
for (q = quirk; q->subvendor || q->subdevice; q++) {
|
||||
/* if the entry is specific to codec SSID, check with it */
|
||||
if (!codec->bus->pci || q->match_codec_ssid) {
|
||||
if (!pci_vendor || !pci_device || q->match_codec_ssid) {
|
||||
if (hda_quirk_match(codec_vendor, codec_device, q)) {
|
||||
type = "codec SSID";
|
||||
goto found_device;
|
||||
|
||||
@@ -97,6 +97,8 @@ static int azx_pcm_close(struct snd_pcm_substream *substream)
|
||||
|
||||
trace_azx_pcm_close(chip, azx_dev);
|
||||
scoped_guard(mutex, &chip->open_mutex) {
|
||||
if (chip->ops->pcm_close)
|
||||
chip->ops->pcm_close(chip, azx_dev);
|
||||
azx_release_device(azx_dev);
|
||||
if (hinfo->ops.close)
|
||||
hinfo->ops.close(hinfo, apcm->codec, substream);
|
||||
@@ -1264,19 +1266,17 @@ int azx_codec_configure(struct azx *chip)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(azx_codec_configure);
|
||||
|
||||
static int stream_direction(struct azx *chip, unsigned char index)
|
||||
void azx_add_stream(struct azx *chip, struct azx_dev *azx_dev, int idx, int tag)
|
||||
{
|
||||
if (index >= chip->capture_index_offset &&
|
||||
index < chip->capture_index_offset + chip->capture_streams)
|
||||
return SNDRV_PCM_STREAM_CAPTURE;
|
||||
return SNDRV_PCM_STREAM_PLAYBACK;
|
||||
snd_hdac_stream_init(azx_bus(chip), azx_stream(azx_dev), idx,
|
||||
azx_stream_direction(chip, idx), tag);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(azx_add_stream);
|
||||
|
||||
/* initialize SD streams */
|
||||
int azx_init_streams(struct azx *chip)
|
||||
{
|
||||
int i;
|
||||
int stream_tags[2] = { 0, 0 };
|
||||
|
||||
/* initialize each stream (aka device)
|
||||
* assign the starting bdl address to each stream (device)
|
||||
@@ -1284,24 +1284,10 @@ int azx_init_streams(struct azx *chip)
|
||||
*/
|
||||
for (i = 0; i < chip->num_streams; i++) {
|
||||
struct azx_dev *azx_dev = kzalloc_obj(*azx_dev);
|
||||
int dir, tag;
|
||||
|
||||
if (!azx_dev)
|
||||
return -ENOMEM;
|
||||
|
||||
dir = stream_direction(chip, i);
|
||||
/* stream tag must be unique throughout
|
||||
* the stream direction group,
|
||||
* valid values 1...15
|
||||
* use separate stream tag if the flag
|
||||
* AZX_DCAPS_SEPARATE_STREAM_TAG is used
|
||||
*/
|
||||
if (chip->driver_caps & AZX_DCAPS_SEPARATE_STREAM_TAG)
|
||||
tag = ++stream_tags[dir];
|
||||
else
|
||||
tag = i + 1;
|
||||
snd_hdac_stream_init(azx_bus(chip), azx_stream(azx_dev),
|
||||
i, dir, tag);
|
||||
azx_add_stream(chip, azx_dev, i, i + 1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -57,13 +57,12 @@ enum {
|
||||
struct azx_dev {
|
||||
struct hdac_stream core;
|
||||
|
||||
unsigned int irq_pending:1;
|
||||
/*
|
||||
* For VIA:
|
||||
* A flag to ensure DMA position is 0
|
||||
* when link position is not greater than FIFO size
|
||||
*/
|
||||
unsigned int insufficient:1;
|
||||
bool insufficient;
|
||||
};
|
||||
|
||||
#define azx_stream(dev) (&(dev)->core)
|
||||
@@ -79,6 +78,8 @@ struct hda_controller_ops {
|
||||
int (*position_check)(struct azx *chip, struct azx_dev *azx_dev);
|
||||
/* enable/disable the link power */
|
||||
int (*link_power)(struct azx *chip, bool enable);
|
||||
/* additional hook for PCM */
|
||||
void (*pcm_close)(struct azx *chip, struct azx_dev *azx_dev);
|
||||
};
|
||||
|
||||
struct azx_pcm {
|
||||
@@ -206,6 +207,15 @@ int azx_bus_init(struct azx *chip, const char *model);
|
||||
int azx_probe_codecs(struct azx *chip, unsigned int max_slots);
|
||||
int azx_codec_configure(struct azx *chip);
|
||||
int azx_init_streams(struct azx *chip);
|
||||
void azx_add_stream(struct azx *chip, struct azx_dev *s, int idx, int tag);
|
||||
void azx_free_streams(struct azx *chip);
|
||||
|
||||
static inline int azx_stream_direction(struct azx *chip, unsigned char index)
|
||||
{
|
||||
if (index >= chip->capture_index_offset &&
|
||||
index < chip->capture_index_offset + chip->capture_streams)
|
||||
return SNDRV_PCM_STREAM_CAPTURE;
|
||||
return SNDRV_PCM_STREAM_PLAYBACK;
|
||||
}
|
||||
|
||||
#endif /* __SOUND_HDA_CONTROLLER_H */
|
||||
@@ -615,17 +615,17 @@ static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev);
|
||||
/* called from IRQ */
|
||||
static int azx_position_check(struct azx *chip, struct azx_dev *azx_dev)
|
||||
{
|
||||
struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
|
||||
struct hda_intel_stream *istream = azx_dev_to_istream(azx_dev);
|
||||
int ok;
|
||||
|
||||
ok = azx_position_ok(chip, azx_dev);
|
||||
if (ok == 1) {
|
||||
azx_dev->irq_pending = 0;
|
||||
istream->irq_pending = false;
|
||||
return ok;
|
||||
} else if (ok == 0) {
|
||||
/* bogus IRQ, process it later */
|
||||
azx_dev->irq_pending = 1;
|
||||
schedule_work(&hda->irq_pending_work);
|
||||
istream->irq_pending = true;
|
||||
schedule_work(&istream->irq_pending_work);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -721,11 +721,13 @@ static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev)
|
||||
*/
|
||||
static void azx_irq_pending_work(struct work_struct *work)
|
||||
{
|
||||
struct hda_intel *hda = container_of(work, struct hda_intel, irq_pending_work);
|
||||
struct hda_intel_stream *istream =
|
||||
container_of(work, struct hda_intel_stream, irq_pending_work);
|
||||
struct azx_dev *azx_dev = &istream->azx_dev;
|
||||
struct hda_intel *hda = istream->hda;
|
||||
struct azx *chip = &hda->chip;
|
||||
struct hdac_bus *bus = azx_bus(chip);
|
||||
struct hdac_stream *s;
|
||||
int pending, ok;
|
||||
int ok;
|
||||
|
||||
if (!hda->irq_pending_warned) {
|
||||
dev_info(chip->card->dev,
|
||||
@@ -735,42 +737,51 @@ static void azx_irq_pending_work(struct work_struct *work)
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
pending = 0;
|
||||
spin_lock_irq(&bus->reg_lock);
|
||||
list_for_each_entry(s, &bus->stream_list, list) {
|
||||
struct azx_dev *azx_dev = stream_to_azx_dev(s);
|
||||
if (!azx_dev->irq_pending ||
|
||||
!s->substream ||
|
||||
!s->running)
|
||||
continue;
|
||||
scoped_guard(spinlock_irq, &bus->reg_lock) {
|
||||
if (!istream->irq_pending ||
|
||||
!azx_dev->core.substream ||
|
||||
!azx_dev->core.running) {
|
||||
return;
|
||||
}
|
||||
|
||||
ok = azx_position_ok(chip, azx_dev);
|
||||
if (ok > 0) {
|
||||
azx_dev->irq_pending = 0;
|
||||
spin_unlock(&bus->reg_lock);
|
||||
snd_pcm_period_elapsed(s->substream);
|
||||
spin_lock(&bus->reg_lock);
|
||||
} else if (ok < 0) {
|
||||
pending = 0; /* too early */
|
||||
} else
|
||||
pending++;
|
||||
if (ok < 0)
|
||||
return; /* too early */
|
||||
if (ok > 0)
|
||||
istream->irq_pending = false;
|
||||
}
|
||||
spin_unlock_irq(&bus->reg_lock);
|
||||
if (!pending)
|
||||
|
||||
if (ok) {
|
||||
snd_pcm_period_elapsed(azx_dev->core.substream);
|
||||
return;
|
||||
}
|
||||
|
||||
msleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* clear irq_pending flags and assure no on-going workq */
|
||||
static void hda_intel_stream_clear_irq_pending(struct azx_dev *azx_dev)
|
||||
{
|
||||
struct hda_intel_stream *istream = azx_dev_to_istream(azx_dev);
|
||||
|
||||
istream->irq_pending = false;
|
||||
cancel_work_sync(&istream->irq_pending_work);
|
||||
}
|
||||
|
||||
/* called at PCM close */
|
||||
static void hda_intel_pcm_close(struct azx *chip, struct azx_dev *azx_dev)
|
||||
{
|
||||
hda_intel_stream_clear_irq_pending(azx_dev);
|
||||
}
|
||||
|
||||
static void azx_clear_irq_pending(struct azx *chip)
|
||||
{
|
||||
struct hdac_bus *bus = azx_bus(chip);
|
||||
struct hdac_stream *s;
|
||||
|
||||
guard(spinlock_irq)(&bus->reg_lock);
|
||||
list_for_each_entry(s, &bus->stream_list, list) {
|
||||
struct azx_dev *azx_dev = stream_to_azx_dev(s);
|
||||
azx_dev->irq_pending = 0;
|
||||
hda_intel_stream_clear_irq_pending(stream_to_azx_dev(s));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1797,7 +1808,6 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci,
|
||||
if (jackpoll_ms[dev] >= 50 && jackpoll_ms[dev] <= 60000)
|
||||
chip->jackpoll_interval = msecs_to_jiffies(jackpoll_ms[dev]);
|
||||
INIT_LIST_HEAD(&chip->pcm_list);
|
||||
INIT_WORK(&hda->irq_pending_work, azx_irq_pending_work);
|
||||
INIT_LIST_HEAD(&hda->list);
|
||||
init_vga_switcheroo(chip);
|
||||
init_completion(&hda->probe_wait);
|
||||
@@ -1846,6 +1856,39 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* create and assign streams */
|
||||
static int hda_init_streams(struct azx *chip)
|
||||
{
|
||||
int i;
|
||||
int stream_tags[2] = { 0, 0 };
|
||||
|
||||
for (i = 0; i < chip->num_streams; i++) {
|
||||
struct hda_intel_stream *s = kzalloc_obj(*s);
|
||||
int tag, dir;
|
||||
|
||||
if (!s)
|
||||
return -ENOMEM;
|
||||
|
||||
s->hda = container_of(chip, struct hda_intel, chip);
|
||||
INIT_WORK(&s->irq_pending_work, azx_irq_pending_work);
|
||||
|
||||
/* stream tag must be unique throughout
|
||||
* the stream direction group,
|
||||
* valid values 1...15
|
||||
* use separate stream tag if the flag
|
||||
* AZX_DCAPS_SEPARATE_STREAM_TAG is used
|
||||
*/
|
||||
dir = azx_stream_direction(chip, i);
|
||||
if (chip->driver_caps & AZX_DCAPS_SEPARATE_STREAM_TAG)
|
||||
tag = ++stream_tags[dir];
|
||||
else
|
||||
tag = i + 1;
|
||||
azx_add_stream(chip, &s->azx_dev, i, tag);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int azx_first_init(struct azx *chip)
|
||||
{
|
||||
int dev = chip->dev_index;
|
||||
@@ -2000,7 +2043,7 @@ static int azx_first_init(struct azx *chip)
|
||||
}
|
||||
|
||||
/* initialize streams */
|
||||
err = azx_init_streams(chip);
|
||||
err = hda_init_streams(chip);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
@@ -2099,6 +2142,7 @@ static const struct dmi_system_id driver_denylist_dmi[] = {
|
||||
static const struct hda_controller_ops pci_hda_ops = {
|
||||
.disable_msi_reset_irq = disable_msi_reset_irq,
|
||||
.position_check = azx_position_check,
|
||||
.pcm_close = hda_intel_pcm_close,
|
||||
};
|
||||
|
||||
static DECLARE_BITMAP(probed_devs, SNDRV_CARDS);
|
||||
|
||||
@@ -9,9 +9,6 @@
|
||||
struct hda_intel {
|
||||
struct azx chip;
|
||||
|
||||
/* for pending irqs */
|
||||
struct work_struct irq_pending_work;
|
||||
|
||||
/* sync probing */
|
||||
struct completion probe_wait;
|
||||
struct delayed_work probe_work;
|
||||
@@ -35,4 +32,16 @@ struct hda_intel {
|
||||
int probe_retry; /* being probe-retry */
|
||||
};
|
||||
|
||||
struct hda_intel_stream {
|
||||
struct azx_dev azx_dev;
|
||||
|
||||
/* for pending irqs */
|
||||
struct hda_intel *hda;
|
||||
struct work_struct irq_pending_work;
|
||||
bool irq_pending;
|
||||
};
|
||||
|
||||
#define azx_dev_to_istream(azx_dev) \
|
||||
container_of(azx_dev, struct hda_intel_stream, azx_dev)
|
||||
|
||||
#endif
|
||||
@@ -276,6 +276,12 @@ static short find_control(u16 control_index,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (control_index >= p_cache->control_count) {
|
||||
HPI_DEBUG_LOG(VERBOSE, "control_index out of bounce %d\n",
|
||||
control_index);
|
||||
return 0;
|
||||
}
|
||||
|
||||
*pI = p_cache->p_info[control_index];
|
||||
if (!*pI) {
|
||||
HPI_DEBUG_LOG(VERBOSE, "Uncached Control %d\n",
|
||||
|
||||
@@ -30,6 +30,13 @@ static const struct dmi_system_id acp70_acpi_flag_override_table[] = {
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "HN7306EA"),
|
||||
},
|
||||
},
|
||||
{
|
||||
/* ASUS Zenbook S16 UM5606GA (Strix Point, ACP 7.0) */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK COMPUTER INC."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Zenbook S16 UM5606GA"),
|
||||
},
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
@@ -260,9 +260,9 @@ static int create_sdw_dailink(struct snd_soc_card *card,
|
||||
cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL,
|
||||
"SDW%d Pin%d",
|
||||
link_num, cpu_pin_id);
|
||||
dev_dbg(dev, "cpu->dai_name:%s\n", cpus->dai_name);
|
||||
if (!cpus->dai_name)
|
||||
return -ENOMEM;
|
||||
dev_dbg(dev, "cpu->dai_name:%s\n", cpus->dai_name);
|
||||
|
||||
codec_maps[j].cpu = 0;
|
||||
codec_maps[j].codec = j;
|
||||
|
||||
@@ -898,7 +898,6 @@ menu "CS35L56 driver options"
|
||||
|
||||
config SND_SOC_CS35L56_CAL_DEBUGFS
|
||||
bool "CS35L56 create debugfs for factory calibration"
|
||||
default N
|
||||
depends on DEBUG_FS
|
||||
select SND_SOC_CS35L56_CAL_DEBUGFS_COMMON
|
||||
help
|
||||
@@ -909,7 +908,6 @@ config SND_SOC_CS35L56_CAL_DEBUGFS
|
||||
|
||||
config SND_SOC_CS35L56_CAL_SET_CTRL
|
||||
bool "CS35L56 ALSA control to restore factory calibration"
|
||||
default N
|
||||
select SND_SOC_CS35L56_CAL_DEBUGFS_COMMON
|
||||
help
|
||||
Allow restoring factory calibration data through an ALSA
|
||||
@@ -923,7 +921,6 @@ config SND_SOC_CS35L56_CAL_SET_CTRL
|
||||
|
||||
config SND_SOC_CS35L56_CAL_PERFORM_CTRL
|
||||
bool "CS35L56 ALSA control to perform factory calibration"
|
||||
default N
|
||||
select SND_SOC_CS35L56_CAL_DEBUGFS_COMMON
|
||||
help
|
||||
Allow performing factory calibration data through an ALSA
|
||||
|
||||
@@ -118,7 +118,7 @@ static int cs_amp_read_cal_coeff(struct cs_dsp *dsp,
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
dev_err(dsp->dev, "Failed to write to '%s': %d\n", ctl_name, ret);
|
||||
dev_err(dsp->dev, "Failed to read '%s': %d\n", ctl_name, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -500,7 +500,7 @@ static int _cs_amp_set_efi_calibration_data(struct device *dev, int amp_index, i
|
||||
* must be set.
|
||||
*/
|
||||
if (data->count == 0)
|
||||
data->count = (data->size - sizeof(data)) / sizeof(data->data[0]);
|
||||
data->count = (data->size - struct_offset(data, data)) / sizeof(data->data[0]);
|
||||
|
||||
if (amp_index < 0) {
|
||||
/* Is there already a slot for this target? */
|
||||
@@ -833,11 +833,18 @@ EXPORT_SYMBOL_NS_GPL(cs_amp_devm_get_vendor_specific_variant_id, "SND_SOC_CS_AMP
|
||||
*/
|
||||
struct dentry *cs_amp_create_debugfs(struct device *dev)
|
||||
{
|
||||
struct dentry *dir;
|
||||
struct dentry *dir, *created;
|
||||
|
||||
/* debugfs_lookup() can return NULL or ERR_PTR on error */
|
||||
dir = debugfs_lookup("cirrus_logic", NULL);
|
||||
if (!dir)
|
||||
dir = debugfs_create_dir("cirrus_logic", NULL);
|
||||
if (!IS_ERR_OR_NULL(dir)) {
|
||||
created = debugfs_create_dir(dev_name(dev), dir);
|
||||
dput(dir);
|
||||
|
||||
return created;
|
||||
}
|
||||
|
||||
dir = debugfs_create_dir("cirrus_logic", NULL);
|
||||
|
||||
return debugfs_create_dir(dev_name(dev), dir);
|
||||
}
|
||||
|
||||
@@ -385,18 +385,19 @@ static int cs35l56_sdw_update_status(struct sdw_slave *peripheral,
|
||||
|
||||
switch (status) {
|
||||
case SDW_SLAVE_ATTACHED:
|
||||
dev_dbg(cs35l56->base.dev, "%s: ATTACHED\n", __func__);
|
||||
cs35l56->sdw_in_clock_stop_1 = false;
|
||||
if (cs35l56->sdw_attached)
|
||||
break;
|
||||
|
||||
dev_dbg(cs35l56->base.dev, "%s: ATTACHED\n", __func__);
|
||||
if (!cs35l56->base.init_done || cs35l56->soft_resetting)
|
||||
cs35l56_sdw_init(peripheral);
|
||||
|
||||
cs35l56->sdw_attached = true;
|
||||
break;
|
||||
case SDW_SLAVE_UNATTACHED:
|
||||
dev_dbg(cs35l56->base.dev, "%s: UNATTACHED\n", __func__);
|
||||
if (cs35l56->sdw_attached)
|
||||
dev_dbg(cs35l56->base.dev, "%s: UNATTACHED\n", __func__);
|
||||
cs35l56->sdw_attached = false;
|
||||
break;
|
||||
default:
|
||||
@@ -584,10 +585,11 @@ static void cs35l56_sdw_remove(struct sdw_slave *peripheral)
|
||||
|
||||
/* Disable SoundWire interrupts */
|
||||
cs35l56->sdw_irq_no_unmask = true;
|
||||
cancel_work_sync(&cs35l56->sdw_irq_work);
|
||||
flush_work(&cs35l56->sdw_irq_work);
|
||||
sdw_write_no_pm(peripheral, CS35L56_SDW_GEN_INT_MASK_1, 0);
|
||||
sdw_read_no_pm(peripheral, CS35L56_SDW_GEN_INT_STAT_1);
|
||||
sdw_write_no_pm(peripheral, CS35L56_SDW_GEN_INT_STAT_1, 0xFF);
|
||||
flush_work(&cs35l56->sdw_irq_work);
|
||||
|
||||
cs35l56_remove(cs35l56);
|
||||
}
|
||||
|
||||
@@ -867,11 +867,16 @@ static void cs35l56_dsp_work(struct work_struct *work)
|
||||
if (!cs35l56->base.init_done)
|
||||
return;
|
||||
|
||||
pm_runtime_get_sync(cs35l56->base.dev);
|
||||
PM_RUNTIME_ACQUIRE(cs35l56->base.dev, pm);
|
||||
ret = PM_RUNTIME_ACQUIRE_ERR(&pm);
|
||||
if (ret) {
|
||||
dev_err(cs35l56->base.dev, "dsp_work failed to runtime-resume: %d\n", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
ret = cs35l56_read_prot_status(&cs35l56->base, &firmware_missing, &firmware_version);
|
||||
if (ret)
|
||||
goto err;
|
||||
return;
|
||||
|
||||
/* Populate fw file qualifier with the revision and security state */
|
||||
kfree(cs35l56->dsp.fwf_name);
|
||||
@@ -887,7 +892,7 @@ static void cs35l56_dsp_work(struct work_struct *work)
|
||||
}
|
||||
|
||||
if (!cs35l56->dsp.fwf_name)
|
||||
goto err;
|
||||
return;
|
||||
|
||||
dev_dbg(cs35l56->base.dev, "DSP fwf name: '%s' system name: '%s'\n",
|
||||
cs35l56->dsp.fwf_name, cs35l56->dsp.system_name);
|
||||
@@ -905,8 +910,6 @@ static void cs35l56_dsp_work(struct work_struct *work)
|
||||
cs35l56_patch(cs35l56, firmware_missing);
|
||||
|
||||
cs35l56_log_tuning(&cs35l56->base, &cs35l56->dsp.cs_dsp);
|
||||
err:
|
||||
pm_runtime_put_autosuspend(cs35l56->base.dev);
|
||||
}
|
||||
|
||||
static struct snd_soc_dapm_context *cs35l56_power_up_for_cal(struct cs35l56_private *cs35l56)
|
||||
|
||||
@@ -968,7 +968,7 @@ static int fs210x_effect_scene_info(struct snd_kcontrol *kcontrol,
|
||||
if (scene->name)
|
||||
name = scene->name;
|
||||
|
||||
strscpy(uinfo->value.enumerated.name, name, strlen(name) + 1);
|
||||
strscpy(uinfo->value.enumerated.name, name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -235,7 +235,7 @@ static int pcm512x_overclock_pll_put(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
|
||||
struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol);
|
||||
struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component);
|
||||
struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component);
|
||||
|
||||
switch (snd_soc_dapm_get_bias_level(dapm)) {
|
||||
@@ -264,7 +264,7 @@ static int pcm512x_overclock_dsp_put(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
|
||||
struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol);
|
||||
struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component);
|
||||
struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component);
|
||||
|
||||
switch (snd_soc_dapm_get_bias_level(dapm)) {
|
||||
@@ -293,7 +293,7 @@ static int pcm512x_overclock_dac_put(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
|
||||
struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol);
|
||||
struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component);
|
||||
struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component);
|
||||
|
||||
switch (snd_soc_dapm_get_bias_level(dapm)) {
|
||||
|
||||
+36
-7
@@ -1370,6 +1370,31 @@ static int fsl_sai_check_version(struct device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fsl_sai_reset_hw(struct device *dev)
|
||||
{
|
||||
struct fsl_sai *sai = dev_get_drvdata(dev);
|
||||
unsigned char ofs = sai->soc_data->reg_offset;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Clear TCSR/RCSR to reset SAI and disable all interrupts.
|
||||
* Bootloader may leave SAI running causing interrupt storm.
|
||||
*/
|
||||
ret = regmap_write(sai->regmap, FSL_SAI_TCSR(ofs), 0);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to clear TCSR: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = regmap_write(sai->regmap, FSL_SAI_RCSR(ofs), 0);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to clear RCSR: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate the offset between first two datalines, don't
|
||||
* different offset in one case.
|
||||
@@ -1575,13 +1600,6 @@ static int fsl_sai_probe(struct platform_device *pdev)
|
||||
if (irq < 0)
|
||||
return irq;
|
||||
|
||||
ret = devm_request_irq(dev, irq, fsl_sai_isr, IRQF_SHARED,
|
||||
np->name, sai);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to claim irq %u\n", irq);
|
||||
return ret;
|
||||
}
|
||||
|
||||
memcpy(&sai->cpu_dai_drv, fsl_sai_dai_template,
|
||||
sizeof(*fsl_sai_dai_template) * ARRAY_SIZE(fsl_sai_dai_template));
|
||||
|
||||
@@ -1656,6 +1674,10 @@ static int fsl_sai_probe(struct platform_device *pdev)
|
||||
if (ret < 0)
|
||||
dev_warn(dev, "Error reading SAI version: %d\n", ret);
|
||||
|
||||
ret = fsl_sai_reset_hw(dev);
|
||||
if (ret < 0)
|
||||
dev_warn(dev, "Failed to reset hardware: %d\n", ret);
|
||||
|
||||
/* Select MCLK direction */
|
||||
if (sai->mclk_direction_output &&
|
||||
sai->soc_data->max_register >= FSL_SAI_MCTL) {
|
||||
@@ -1667,6 +1689,13 @@ static int fsl_sai_probe(struct platform_device *pdev)
|
||||
if (ret < 0 && ret != -ENOSYS)
|
||||
goto err_pm_get_sync;
|
||||
|
||||
ret = devm_request_irq(dev, irq, fsl_sai_isr, IRQF_SHARED,
|
||||
np->name, sai);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to claim irq %u\n", irq);
|
||||
goto err_pm_get_sync;
|
||||
}
|
||||
|
||||
if (of_device_is_compatible(np, "fsl,imx952-sai") &&
|
||||
!of_property_read_string(np, "fsl,sai-amix-mode", &str)) {
|
||||
if (!strcmp(str, "bypass"))
|
||||
|
||||
@@ -837,6 +837,14 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = {
|
||||
SOF_BT_OFFLOAD_SSP(2) |
|
||||
SOF_SSP_BT_OFFLOAD_PRESENT),
|
||||
},
|
||||
/* Novalake devices*/
|
||||
{
|
||||
.callback = sof_sdw_quirk_cb,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_PRODUCT_FAMILY, "Intel_nvlrvp"),
|
||||
},
|
||||
.driver_data = (void *)(SOC_SDW_PCH_DMIC),
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <sound/soc-acpi.h>
|
||||
#include <sound/soc-acpi-intel-match.h>
|
||||
#include <sound/soc-acpi-intel-ssp-common.h>
|
||||
#include "soc-acpi-intel-sdca-quirks.h"
|
||||
#include "sof-function-topology-lib.h"
|
||||
|
||||
static const struct snd_soc_acpi_endpoint single_endpoint = {
|
||||
@@ -237,6 +238,15 @@ static const struct snd_soc_acpi_adr_device rt722_0_agg_adr[] = {
|
||||
}
|
||||
};
|
||||
|
||||
static const struct snd_soc_acpi_adr_device rt712_0_agg_adr[] = {
|
||||
{
|
||||
.adr = 0x000030025D071201ull,
|
||||
.num_endpoints = ARRAY_SIZE(jack_amp_g1_dmic_endpoints),
|
||||
.endpoints = jack_amp_g1_dmic_endpoints,
|
||||
.name_prefix = "rt712"
|
||||
}
|
||||
};
|
||||
|
||||
static const struct snd_soc_acpi_adr_device rt1316_3_single_adr[] = {
|
||||
{
|
||||
.adr = 0x000330025D131601ull,
|
||||
@@ -255,6 +265,15 @@ static const struct snd_soc_acpi_adr_device rt1320_2_single_adr[] = {
|
||||
}
|
||||
};
|
||||
|
||||
static const struct snd_soc_acpi_adr_device rt1320_3_group1_adr[] = {
|
||||
{
|
||||
.adr = 0x000330025D132001ull,
|
||||
.num_endpoints = 1,
|
||||
.endpoints = &spk_r_endpoint,
|
||||
.name_prefix = "rt1320-1"
|
||||
}
|
||||
};
|
||||
|
||||
static const struct snd_soc_acpi_link_adr arl_cs42l43_l0[] = {
|
||||
{
|
||||
.mask = BIT(0),
|
||||
@@ -404,6 +423,20 @@ static const struct snd_soc_acpi_link_adr arl_rt722_l0_rt1320_l2[] = {
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct snd_soc_acpi_link_adr arl_rt712_l0_rt1320_l3[] = {
|
||||
{
|
||||
.mask = BIT(0),
|
||||
.num_adr = ARRAY_SIZE(rt712_0_agg_adr),
|
||||
.adr_d = rt712_0_agg_adr,
|
||||
},
|
||||
{
|
||||
.mask = BIT(3),
|
||||
.num_adr = ARRAY_SIZE(rt1320_3_group1_adr),
|
||||
.adr_d = rt1320_3_group1_adr,
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct snd_soc_acpi_codecs arl_essx_83x6 = {
|
||||
.num_codecs = 3,
|
||||
.codecs = { "ESSX8316", "ESSX8326", "ESSX8336"},
|
||||
@@ -483,10 +516,24 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_arl_sdw_machines[] = {
|
||||
.get_function_tplg_files = sof_sdw_get_tplg_files,
|
||||
},
|
||||
{
|
||||
.link_mask = BIT(0),
|
||||
.links = arl_cs42l43_l0,
|
||||
.link_mask = BIT(0) | BIT(2),
|
||||
.links = arl_rt722_l0_rt1320_l2,
|
||||
.drv_name = "sof_sdw",
|
||||
.sof_tplg_filename = "sof-arl-cs42l43-l0.tplg",
|
||||
.sof_tplg_filename = "sof-arl-rt722-l0_rt1320-l2.tplg",
|
||||
.get_function_tplg_files = sof_sdw_get_tplg_files,
|
||||
},
|
||||
{
|
||||
.link_mask = BIT(0) | BIT(3),
|
||||
.links = arl_rt711_l0_rt1316_l3,
|
||||
.drv_name = "sof_sdw",
|
||||
.sof_tplg_filename = "sof-arl-rt711-l0-rt1316-l3.tplg",
|
||||
},
|
||||
{
|
||||
.link_mask = BIT(0) | BIT(3),
|
||||
.links = arl_rt712_l0_rt1320_l3,
|
||||
.drv_name = "sof_sdw",
|
||||
.machine_check = snd_soc_acpi_intel_sdca_is_device_rt712_vb,
|
||||
.sof_tplg_filename = "sof-arl-rt712-l0-rt1320-l3.tplg",
|
||||
.get_function_tplg_files = sof_sdw_get_tplg_files,
|
||||
},
|
||||
{
|
||||
@@ -497,18 +544,12 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_arl_sdw_machines[] = {
|
||||
.get_function_tplg_files = sof_sdw_get_tplg_files,
|
||||
},
|
||||
{
|
||||
.link_mask = BIT(2),
|
||||
.links = arl_cs42l43_l2,
|
||||
.link_mask = BIT(0),
|
||||
.links = arl_cs42l43_l0,
|
||||
.drv_name = "sof_sdw",
|
||||
.sof_tplg_filename = "sof-arl-cs42l43-l2.tplg",
|
||||
.sof_tplg_filename = "sof-arl-cs42l43-l0.tplg",
|
||||
.get_function_tplg_files = sof_sdw_get_tplg_files,
|
||||
},
|
||||
{
|
||||
.link_mask = BIT(0) | BIT(3),
|
||||
.links = arl_rt711_l0_rt1316_l3,
|
||||
.drv_name = "sof_sdw",
|
||||
.sof_tplg_filename = "sof-arl-rt711-l0-rt1316-l3.tplg",
|
||||
},
|
||||
{
|
||||
.link_mask = 0x1, /* link0 required */
|
||||
.links = arl_rvp,
|
||||
@@ -522,10 +563,10 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_arl_sdw_machines[] = {
|
||||
.sof_tplg_filename = "sof-arl-rt711-l0.tplg",
|
||||
},
|
||||
{
|
||||
.link_mask = BIT(0) | BIT(2),
|
||||
.links = arl_rt722_l0_rt1320_l2,
|
||||
.link_mask = BIT(2),
|
||||
.links = arl_cs42l43_l2,
|
||||
.drv_name = "sof_sdw",
|
||||
.sof_tplg_filename = "sof-arl-rt722-l0_rt1320-l2.tplg",
|
||||
.sof_tplg_filename = "sof-arl-cs42l43-l2.tplg",
|
||||
.get_function_tplg_files = sof_sdw_get_tplg_files,
|
||||
},
|
||||
{},
|
||||
|
||||
@@ -10,7 +10,20 @@
|
||||
#include <sound/soc-acpi-intel-match.h>
|
||||
#include "soc-acpi-intel-sdw-mockup-match.h"
|
||||
|
||||
static const struct snd_soc_acpi_codecs nvl_essx_83x6 = {
|
||||
.num_codecs = 3,
|
||||
.codecs = { "ESSX8316", "ESSX8326", "ESSX8336"},
|
||||
};
|
||||
|
||||
struct snd_soc_acpi_mach snd_soc_acpi_intel_nvl_machines[] = {
|
||||
{
|
||||
.comp_ids = &nvl_essx_83x6,
|
||||
.drv_name = "sof-essx8336",
|
||||
.sof_tplg_filename = "sof-nvl-es8336", /* the tplg suffix is added at run time */
|
||||
.tplg_quirk_mask = SND_SOC_ACPI_TPLG_INTEL_SSP_NUMBER |
|
||||
SND_SOC_ACPI_TPLG_INTEL_SSP_MSB |
|
||||
SND_SOC_ACPI_TPLG_INTEL_DMIC_NUMBER,
|
||||
},
|
||||
{},
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_nvl_machines);
|
||||
|
||||
@@ -92,48 +92,6 @@ static const struct snd_soc_acpi_endpoint spk_r_endpoint = {
|
||||
.group_id = 1,
|
||||
};
|
||||
|
||||
static const struct snd_soc_acpi_endpoint spk_1_endpoint = {
|
||||
.num = 0,
|
||||
.aggregated = 1,
|
||||
.group_position = 1,
|
||||
.group_id = 1,
|
||||
};
|
||||
|
||||
static const struct snd_soc_acpi_endpoint spk_2_endpoint = {
|
||||
.num = 0,
|
||||
.aggregated = 1,
|
||||
.group_position = 2,
|
||||
.group_id = 1,
|
||||
};
|
||||
|
||||
static const struct snd_soc_acpi_endpoint spk_3_endpoint = {
|
||||
.num = 0,
|
||||
.aggregated = 1,
|
||||
.group_position = 3,
|
||||
.group_id = 1,
|
||||
};
|
||||
|
||||
static const struct snd_soc_acpi_endpoint spk_4_endpoint = {
|
||||
.num = 0,
|
||||
.aggregated = 1,
|
||||
.group_position = 4,
|
||||
.group_id = 1,
|
||||
};
|
||||
|
||||
static const struct snd_soc_acpi_endpoint spk_5_endpoint = {
|
||||
.num = 0,
|
||||
.aggregated = 1,
|
||||
.group_position = 5,
|
||||
.group_id = 1,
|
||||
};
|
||||
|
||||
static const struct snd_soc_acpi_endpoint spk_6_endpoint = {
|
||||
.num = 0,
|
||||
.aggregated = 1,
|
||||
.group_position = 6,
|
||||
.group_id = 1,
|
||||
};
|
||||
|
||||
static const struct snd_soc_acpi_endpoint jack_dmic_endpoints[] = {
|
||||
/* Jack Endpoint */
|
||||
{
|
||||
@@ -202,15 +160,6 @@ static const struct snd_soc_acpi_endpoint cs42l43_amp_spkagg_endpoints[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static const struct snd_soc_acpi_adr_device cs42l43_2_adr[] = {
|
||||
{
|
||||
.adr = 0x00023001fa424301ull,
|
||||
.num_endpoints = ARRAY_SIZE(cs42l43_amp_spkagg_endpoints),
|
||||
.endpoints = cs42l43_amp_spkagg_endpoints,
|
||||
.name_prefix = "cs42l43"
|
||||
}
|
||||
};
|
||||
|
||||
static const struct snd_soc_acpi_adr_device cs42l43_3_agg_adr[] = {
|
||||
{
|
||||
.adr = 0x00033001FA424301ull,
|
||||
@@ -235,48 +184,6 @@ static const struct snd_soc_acpi_adr_device cs35l56_2_lr_adr[] = {
|
||||
}
|
||||
};
|
||||
|
||||
static const struct snd_soc_acpi_adr_device cs35l56_1_3amp_adr[] = {
|
||||
{
|
||||
.adr = 0x00013001fa355601ull,
|
||||
.num_endpoints = 1,
|
||||
.endpoints = &spk_1_endpoint,
|
||||
.name_prefix = "AMP1"
|
||||
},
|
||||
{
|
||||
.adr = 0x00013101fa355601ull,
|
||||
.num_endpoints = 1,
|
||||
.endpoints = &spk_2_endpoint,
|
||||
.name_prefix = "AMP2"
|
||||
},
|
||||
{
|
||||
.adr = 0x00013201fa355601ull,
|
||||
.num_endpoints = 1,
|
||||
.endpoints = &spk_3_endpoint,
|
||||
.name_prefix = "AMP3"
|
||||
}
|
||||
};
|
||||
|
||||
static const struct snd_soc_acpi_adr_device cs35l56_3_3amp_adr[] = {
|
||||
{
|
||||
.adr = 0x00033301fa355601ull,
|
||||
.num_endpoints = 1,
|
||||
.endpoints = &spk_4_endpoint,
|
||||
.name_prefix = "AMP4"
|
||||
},
|
||||
{
|
||||
.adr = 0x00033401fa355601ull,
|
||||
.num_endpoints = 1,
|
||||
.endpoints = &spk_5_endpoint,
|
||||
.name_prefix = "AMP5"
|
||||
},
|
||||
{
|
||||
.adr = 0x00033501fa355601ull,
|
||||
.num_endpoints = 1,
|
||||
.endpoints = &spk_6_endpoint,
|
||||
.name_prefix = "AMP6"
|
||||
}
|
||||
};
|
||||
|
||||
static const struct snd_soc_acpi_adr_device rt711_sdca_0_adr[] = {
|
||||
{
|
||||
.adr = 0x000030025D071101ull,
|
||||
@@ -408,25 +315,6 @@ static const struct snd_soc_acpi_link_adr ptl_cs42l43_agg_l3_cs35l56_l2[] = {
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct snd_soc_acpi_link_adr ptl_cs42l43_l2_cs35l56x6_l13[] = {
|
||||
{
|
||||
.mask = BIT(2),
|
||||
.num_adr = ARRAY_SIZE(cs42l43_2_adr),
|
||||
.adr_d = cs42l43_2_adr,
|
||||
},
|
||||
{
|
||||
.mask = BIT(1),
|
||||
.num_adr = ARRAY_SIZE(cs35l56_1_3amp_adr),
|
||||
.adr_d = cs35l56_1_3amp_adr,
|
||||
},
|
||||
{
|
||||
.mask = BIT(3),
|
||||
.num_adr = ARRAY_SIZE(cs35l56_3_3amp_adr),
|
||||
.adr_d = cs35l56_3_3amp_adr,
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct snd_soc_acpi_link_adr ptl_rt722_l0_rt1320_l23[] = {
|
||||
{
|
||||
.mask = BIT(0),
|
||||
@@ -493,6 +381,20 @@ static const struct snd_soc_acpi_link_adr ptl_sdw_rt713_vb_l3_rt1320_l12[] = {
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct snd_soc_acpi_link_adr ptl_sdw_rt713_vb_l3_rt1320_l1[] = {
|
||||
{
|
||||
.mask = BIT(3),
|
||||
.num_adr = ARRAY_SIZE(rt713_vb_3_adr),
|
||||
.adr_d = rt713_vb_3_adr,
|
||||
},
|
||||
{
|
||||
.mask = BIT(1),
|
||||
.num_adr = ARRAY_SIZE(rt1320_1_group2_adr),
|
||||
.adr_d = rt1320_1_group2_adr,
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct snd_soc_acpi_link_adr ptl_sdw_rt712_vb_l2_rt1320_l1[] = {
|
||||
{
|
||||
.mask = BIT(2),
|
||||
@@ -579,10 +481,11 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_ptl_sdw_machines[] = {
|
||||
.get_function_tplg_files = sof_sdw_get_tplg_files,
|
||||
},
|
||||
{
|
||||
.link_mask = BIT(1) | BIT(2) | BIT(3),
|
||||
.links = ptl_cs42l43_l2_cs35l56x6_l13,
|
||||
.link_mask = BIT(1) | BIT(3),
|
||||
.links = ptl_sdw_rt713_vb_l3_rt1320_l1,
|
||||
.drv_name = "sof_sdw",
|
||||
.sof_tplg_filename = "sof-ptl-cs42l43-l2-cs35l56x6-l13.tplg",
|
||||
.sof_tplg_filename = "sof-ptl-rt713-l3-rt1320-l1.tplg",
|
||||
.get_function_tplg_files = sof_sdw_get_tplg_files,
|
||||
},
|
||||
{
|
||||
.link_mask = BIT(0) | BIT(2) | BIT(3),
|
||||
@@ -611,6 +514,7 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_ptl_sdw_machines[] = {
|
||||
.link_mask = BIT(2) | BIT(3),
|
||||
.links = ptl_cs42l43_agg_l3_cs35l56_l2,
|
||||
.drv_name = "sof_sdw",
|
||||
.machine_check = snd_soc_acpi_intel_no_function_topology,
|
||||
.sof_tplg_filename = "sof-ptl-cs42l43-agg-l3-cs35l56-l2.tplg",
|
||||
},
|
||||
{
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/dmi.h>
|
||||
#include <linux/soundwire/sdw_intel.h>
|
||||
#include <sound/sdca.h>
|
||||
#include <sound/soc-acpi.h>
|
||||
@@ -37,6 +38,21 @@ bool snd_soc_acpi_intel_sdca_is_device_rt712_vb(void *arg)
|
||||
}
|
||||
EXPORT_SYMBOL_NS(snd_soc_acpi_intel_sdca_is_device_rt712_vb, "SND_SOC_ACPI_INTEL_SDCA_QUIRKS");
|
||||
|
||||
static const struct dmi_system_id function_topology_quirk_table[] = {
|
||||
{
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Google"),
|
||||
},
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
bool snd_soc_acpi_intel_no_function_topology(void *arg)
|
||||
{
|
||||
return !!dmi_check_system(function_topology_quirk_table);
|
||||
}
|
||||
EXPORT_SYMBOL_NS(snd_soc_acpi_intel_no_function_topology, "SND_SOC_ACPI_INTEL_SDCA_QUIRKS");
|
||||
|
||||
MODULE_DESCRIPTION("ASoC ACPI Intel SDCA quirks");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_IMPORT_NS("SND_SOC_SDCA");
|
||||
@@ -10,5 +10,6 @@
|
||||
#define _SND_SOC_ACPI_INTEL_SDCA_QUIRKS
|
||||
|
||||
bool snd_soc_acpi_intel_sdca_is_device_rt712_vb(void *arg);
|
||||
bool snd_soc_acpi_intel_no_function_topology(void *arg);
|
||||
|
||||
#endif
|
||||
@@ -497,7 +497,12 @@ static int q6apm_dai_pcm_new(struct snd_soc_component *component, struct snd_soc
|
||||
{
|
||||
struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
|
||||
struct snd_pcm *pcm = rtd->pcm;
|
||||
int size = BUFFER_BYTES_MAX;
|
||||
/*
|
||||
* Allocate one extra page as a workaround for a DSP bug where 32-bit
|
||||
* address arithmetic can overflow when the buffer is placed near the
|
||||
* end of the addressable range.
|
||||
*/
|
||||
int size = BUFFER_BYTES_MAX + PAGE_SIZE;
|
||||
int graph_id, ret;
|
||||
struct snd_pcm_substream *substream;
|
||||
|
||||
|
||||
@@ -194,6 +194,8 @@ struct asoc_sdw_codec_info codec_info_list[] = {
|
||||
.dai_type = SOC_SDW_DAI_TYPE_MIC,
|
||||
.dailink = {SOC_SDW_UNUSED_DAI_ID, SOC_SDW_DMIC_DAI_ID},
|
||||
.rtd_init = asoc_sdw_rt_dmic_rtd_init,
|
||||
.quirk = SOC_SDW_CODEC_MIC,
|
||||
.quirk_exclude = true,
|
||||
},
|
||||
},
|
||||
.dai_num = 3,
|
||||
@@ -501,6 +503,8 @@ struct asoc_sdw_codec_info codec_info_list[] = {
|
||||
.dai_type = SOC_SDW_DAI_TYPE_MIC,
|
||||
.dailink = {SOC_SDW_UNUSED_DAI_ID, SOC_SDW_DMIC_DAI_ID},
|
||||
.rtd_init = asoc_sdw_rt_dmic_rtd_init,
|
||||
.quirk = SOC_SDW_CODEC_MIC,
|
||||
.quirk_exclude = true,
|
||||
},
|
||||
},
|
||||
.dai_num = 3,
|
||||
@@ -1110,7 +1114,7 @@ int asoc_sdw_rtd_init(struct snd_soc_pcm_runtime *rtd)
|
||||
struct asoc_sdw_codec_info *codec_info;
|
||||
struct snd_soc_dai *dai;
|
||||
struct sdw_slave *sdw_peripheral;
|
||||
const char *spk_components="";
|
||||
const char *spk_components = NULL;
|
||||
int dai_index;
|
||||
int ret;
|
||||
int i;
|
||||
@@ -1193,7 +1197,7 @@ skip_add_controls_widgets:
|
||||
else
|
||||
component = codec_info->dais[dai_index].component_name;
|
||||
|
||||
if (strlen (spk_components) == 0)
|
||||
if (!spk_components)
|
||||
spk_components =
|
||||
devm_kasprintf(card->dev, GFP_KERNEL, "%s", component);
|
||||
else
|
||||
@@ -1201,13 +1205,15 @@ skip_add_controls_widgets:
|
||||
spk_components =
|
||||
devm_kasprintf(card->dev, GFP_KERNEL,
|
||||
"%s+%s", spk_components, component);
|
||||
|
||||
if (!spk_components)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
codec_info->dais[dai_index].rtd_init_done = true;
|
||||
|
||||
}
|
||||
|
||||
if (strlen (spk_components) > 0) {
|
||||
if (spk_components) {
|
||||
/* Update card components for speaker components */
|
||||
card->components = devm_kasprintf(card->dev, GFP_KERNEL, "%s spk:%s",
|
||||
card->components, spk_components);
|
||||
|
||||
@@ -36,6 +36,7 @@ int snd_soc_ret(const struct device *dev, int ret, const char *fmt, ...)
|
||||
vaf.va = &args;
|
||||
|
||||
dev_err(dev, "ASoC error (%d): %pV", ret, &vaf);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
@@ -223,7 +223,7 @@ static int psp_send_cmd(struct acp_dev_data *adata, int cmd)
|
||||
{
|
||||
struct snd_sof_dev *sdev = adata->dev;
|
||||
int ret;
|
||||
u32 data;
|
||||
int data;
|
||||
|
||||
if (!cmd)
|
||||
return -EINVAL;
|
||||
|
||||
@@ -328,7 +328,7 @@ static int omap_dmic_select_fclk(struct omap_dmic *dmic, int clk_id,
|
||||
}
|
||||
|
||||
mux = clk_get_parent(dmic->fclk);
|
||||
if (IS_ERR(mux)) {
|
||||
if (!mux) {
|
||||
dev_err(dmic->dev, "can't get fck mux parent\n");
|
||||
clk_put(parent_clk);
|
||||
return -ENODEV;
|
||||
|
||||
@@ -894,8 +894,9 @@ find_format_descriptor(struct usb_interface *interface)
|
||||
struct uac_format_type_i_discrete_descriptor *desc;
|
||||
|
||||
desc = (struct uac_format_type_i_discrete_descriptor *)extra;
|
||||
if (desc->bLength > extralen) {
|
||||
dev_err(&interface->dev, "descriptor overflow\n");
|
||||
if (desc->bLength < sizeof(struct usb_descriptor_header) ||
|
||||
desc->bLength > extralen) {
|
||||
dev_err(&interface->dev, "invalid descriptor length\n");
|
||||
return NULL;
|
||||
}
|
||||
if (desc->bLength == UAC_FORMAT_TYPE_I_DISCRETE_DESC_SIZE(1) &&
|
||||
|
||||
@@ -9187,12 +9187,15 @@ static long scarlett2_hwdep_write(struct snd_hwdep *hw,
|
||||
flash_size = private->flash_segment_blocks[segment_id] *
|
||||
SCARLETT2_FLASH_BLOCK_SIZE;
|
||||
|
||||
if (count < 0 || *offset < 0 || *offset + count >= flash_size)
|
||||
return -ENOSPC;
|
||||
if (count < 0 || *offset < 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (!count)
|
||||
return 0;
|
||||
|
||||
if (*offset >= flash_size || count > flash_size - *offset)
|
||||
return -ENOSPC;
|
||||
|
||||
/* Limit the *req size to SCARLETT2_FLASH_RW_MAX */
|
||||
if (count > max_data_size)
|
||||
count = max_data_size;
|
||||
|
||||
Reference in new issue
Block a user