Merge d3eeb99bbc ("Merge tag 'block-6.19-20260116' of git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux") into android-mainline
Steps on the way to 6.19-rc6 Change-Id: Ic590355cb23c79437b7332c9d5efd36b14c77714 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
commit
c344dcb3e8
95 files changed
+1166
-658
No files matched your search
@@ -49,6 +49,10 @@ properties:
|
||||
items:
|
||||
- const: mclk
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
description: Headphone detect interrupt
|
||||
|
||||
port:
|
||||
$ref: audio-graph-port.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
@@ -47,6 +47,12 @@ properties:
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
clock-names:
|
||||
const: mclk
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
description: The CODEC's interrupt output.
|
||||
@@ -98,6 +104,7 @@ properties:
|
||||
- 4 # Use GPIO2 for jack-detect
|
||||
- 5 # Use GPIO3 for jack-detect
|
||||
- 6 # Use GPIO4 for jack-detect
|
||||
- 7 # Use HDA header for jack-detect
|
||||
|
||||
realtek,jack-detect-not-inverted:
|
||||
description:
|
||||
@@ -121,6 +128,10 @@ properties:
|
||||
- 2 # Scale current by 1.0
|
||||
- 3 # Scale current by 1.5
|
||||
|
||||
port:
|
||||
$ref: audio-graph-port.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
@@ -70,6 +70,9 @@ properties:
|
||||
"#sound-dai-cells":
|
||||
const: 0
|
||||
|
||||
port:
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
@@ -0,0 +1,175 @@
|
||||
# SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause)
|
||||
#
|
||||
# Copyright (c) 2025 Valve Corporation.
|
||||
#
|
||||
---
|
||||
name: dev-energymodel
|
||||
|
||||
doc: |
|
||||
Energy model netlink interface to notify its changes.
|
||||
|
||||
protocol: genetlink
|
||||
|
||||
uapi-header: linux/dev_energymodel.h
|
||||
|
||||
definitions:
|
||||
-
|
||||
type: flags
|
||||
name: perf-state-flags
|
||||
entries:
|
||||
-
|
||||
name: perf-state-inefficient
|
||||
doc: >-
|
||||
The performance state is inefficient. There is in this perf-domain,
|
||||
another performance state with a higher frequency but a lower or
|
||||
equal power cost.
|
||||
-
|
||||
type: flags
|
||||
name: perf-domain-flags
|
||||
entries:
|
||||
-
|
||||
name: perf-domain-microwatts
|
||||
doc: >-
|
||||
The power values are in micro-Watts or some other scale.
|
||||
-
|
||||
name: perf-domain-skip-inefficiencies
|
||||
doc: >-
|
||||
Skip inefficient states when estimating energy consumption.
|
||||
-
|
||||
name: perf-domain-artificial
|
||||
doc: >-
|
||||
The power values are artificial and might be created by platform
|
||||
missing real power information.
|
||||
|
||||
attribute-sets:
|
||||
-
|
||||
name: perf-domain
|
||||
doc: >-
|
||||
Information on a single performance domains.
|
||||
attributes:
|
||||
-
|
||||
name: pad
|
||||
type: pad
|
||||
-
|
||||
name: perf-domain-id
|
||||
type: u32
|
||||
doc: >-
|
||||
A unique ID number for each performance domain.
|
||||
-
|
||||
name: flags
|
||||
type: u64
|
||||
doc: >-
|
||||
Bitmask of performance domain flags.
|
||||
enum: perf-domain-flags
|
||||
-
|
||||
name: cpus
|
||||
type: u64
|
||||
multi-attr: true
|
||||
doc: >-
|
||||
CPUs that belong to this performance domain.
|
||||
-
|
||||
name: perf-table
|
||||
doc: >-
|
||||
Performance states table.
|
||||
attributes:
|
||||
-
|
||||
name: perf-domain-id
|
||||
type: u32
|
||||
doc: >-
|
||||
A unique ID number for each performance domain.
|
||||
-
|
||||
name: perf-state
|
||||
type: nest
|
||||
nested-attributes: perf-state
|
||||
multi-attr: true
|
||||
-
|
||||
name: perf-state
|
||||
doc: >-
|
||||
Performance state of a performance domain.
|
||||
attributes:
|
||||
-
|
||||
name: pad
|
||||
type: pad
|
||||
-
|
||||
name: performance
|
||||
type: u64
|
||||
doc: >-
|
||||
CPU performance (capacity) at a given frequency.
|
||||
-
|
||||
name: frequency
|
||||
type: u64
|
||||
doc: >-
|
||||
The frequency in KHz, for consistency with CPUFreq.
|
||||
-
|
||||
name: power
|
||||
type: u64
|
||||
doc: >-
|
||||
The power consumed at this level (by 1 CPU or by a registered
|
||||
device). It can be a total power: static and dynamic.
|
||||
-
|
||||
name: cost
|
||||
type: u64
|
||||
doc: >-
|
||||
The cost coefficient associated with this level, used during energy
|
||||
calculation. Equal to: power * max_frequency / frequency.
|
||||
-
|
||||
name: flags
|
||||
type: u64
|
||||
doc: >-
|
||||
Bitmask of performance state flags.
|
||||
enum: perf-state-flags
|
||||
|
||||
operations:
|
||||
list:
|
||||
-
|
||||
name: get-perf-domains
|
||||
attribute-set: perf-domain
|
||||
doc: Get the list of information for all performance domains.
|
||||
do:
|
||||
request:
|
||||
attributes:
|
||||
- perf-domain-id
|
||||
reply:
|
||||
attributes: &perf-domain-attrs
|
||||
- pad
|
||||
- perf-domain-id
|
||||
- flags
|
||||
- cpus
|
||||
dump:
|
||||
reply:
|
||||
attributes: *perf-domain-attrs
|
||||
-
|
||||
name: get-perf-table
|
||||
attribute-set: perf-table
|
||||
doc: Get the energy model table of a performance domain.
|
||||
do:
|
||||
request:
|
||||
attributes:
|
||||
- perf-domain-id
|
||||
reply:
|
||||
attributes:
|
||||
- perf-domain-id
|
||||
- perf-state
|
||||
-
|
||||
name: perf-domain-created
|
||||
doc: A performance domain is created.
|
||||
notify: get-perf-table
|
||||
mcgrp: event
|
||||
-
|
||||
name: perf-domain-updated
|
||||
doc: A performance domain is updated.
|
||||
notify: get-perf-table
|
||||
mcgrp: event
|
||||
-
|
||||
name: perf-domain-deleted
|
||||
doc: A performance domain is deleted.
|
||||
attribute-set: perf-table
|
||||
event:
|
||||
attributes:
|
||||
- perf-domain-id
|
||||
mcgrp: event
|
||||
|
||||
mcast-groups:
|
||||
list:
|
||||
-
|
||||
name: event
|
||||
@@ -1,113 +0,0 @@
|
||||
# SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause)
|
||||
|
||||
name: em
|
||||
|
||||
doc: |
|
||||
Energy model netlink interface to notify its changes.
|
||||
|
||||
protocol: genetlink
|
||||
|
||||
uapi-header: linux/energy_model.h
|
||||
|
||||
attribute-sets:
|
||||
-
|
||||
name: pds
|
||||
attributes:
|
||||
-
|
||||
name: pd
|
||||
type: nest
|
||||
nested-attributes: pd
|
||||
multi-attr: true
|
||||
-
|
||||
name: pd
|
||||
attributes:
|
||||
-
|
||||
name: pad
|
||||
type: pad
|
||||
-
|
||||
name: pd-id
|
||||
type: u32
|
||||
-
|
||||
name: flags
|
||||
type: u64
|
||||
-
|
||||
name: cpus
|
||||
type: string
|
||||
-
|
||||
name: pd-table
|
||||
attributes:
|
||||
-
|
||||
name: pd-id
|
||||
type: u32
|
||||
-
|
||||
name: ps
|
||||
type: nest
|
||||
nested-attributes: ps
|
||||
multi-attr: true
|
||||
-
|
||||
name: ps
|
||||
attributes:
|
||||
-
|
||||
name: pad
|
||||
type: pad
|
||||
-
|
||||
name: performance
|
||||
type: u64
|
||||
-
|
||||
name: frequency
|
||||
type: u64
|
||||
-
|
||||
name: power
|
||||
type: u64
|
||||
-
|
||||
name: cost
|
||||
type: u64
|
||||
-
|
||||
name: flags
|
||||
type: u64
|
||||
|
||||
operations:
|
||||
list:
|
||||
-
|
||||
name: get-pds
|
||||
attribute-set: pds
|
||||
doc: Get the list of information for all performance domains.
|
||||
do:
|
||||
reply:
|
||||
attributes:
|
||||
- pd
|
||||
-
|
||||
name: get-pd-table
|
||||
attribute-set: pd-table
|
||||
doc: Get the energy model table of a performance domain.
|
||||
do:
|
||||
request:
|
||||
attributes:
|
||||
- pd-id
|
||||
reply:
|
||||
attributes:
|
||||
- pd-id
|
||||
- ps
|
||||
-
|
||||
name: pd-created
|
||||
doc: A performance domain is created.
|
||||
notify: get-pd-table
|
||||
mcgrp: event
|
||||
-
|
||||
name: pd-updated
|
||||
doc: A performance domain is updated.
|
||||
notify: get-pd-table
|
||||
mcgrp: event
|
||||
-
|
||||
name: pd-deleted
|
||||
doc: A performance domain is deleted.
|
||||
attribute-set: pd-table
|
||||
event:
|
||||
attributes:
|
||||
- pd-id
|
||||
mcgrp: event
|
||||
|
||||
mcast-groups:
|
||||
list:
|
||||
-
|
||||
name: event
|
||||
+4
-4
@@ -9304,12 +9304,12 @@ M: Lukasz Luba <lukasz.luba@arm.com>
|
||||
M: "Rafael J. Wysocki" <rafael@kernel.org>
|
||||
L: linux-pm@vger.kernel.org
|
||||
S: Maintained
|
||||
F: kernel/power/energy_model.c
|
||||
F: include/linux/energy_model.h
|
||||
F: Documentation/netlink/specs/dev-energymodel.yaml
|
||||
F: Documentation/power/energy-model.rst
|
||||
F: Documentation/netlink/specs/em.yaml
|
||||
F: include/uapi/linux/energy_model.h
|
||||
F: include/linux/energy_model.h
|
||||
F: include/uapi/linux/dev_energymodel.h
|
||||
F: kernel/power/em_netlink*.*
|
||||
F: kernel/power/energy_model.c
|
||||
|
||||
EPAPR HYPERVISOR BYTE CHANNEL DEVICE DRIVER
|
||||
M: Laurentiu Tudor <laurentiu.tudor@nxp.com>
|
||||
|
||||
+5
-5
@@ -115,12 +115,12 @@ void __init kernel_randomize_memory(void)
|
||||
|
||||
/*
|
||||
* Adapt physical memory region size based on available memory,
|
||||
* except when CONFIG_PCI_P2PDMA is enabled. P2PDMA exposes the
|
||||
* device BAR space assuming the direct map space is large enough
|
||||
* for creating a ZONE_DEVICE mapping in the direct map corresponding
|
||||
* to the physical BAR address.
|
||||
* except when CONFIG_ZONE_DEVICE is enabled. ZONE_DEVICE wants to map
|
||||
* any physical address into the direct-map. KASLR wants to reliably
|
||||
* steal some physical address bits. Those design choices are in direct
|
||||
* conflict.
|
||||
*/
|
||||
if (!IS_ENABLED(CONFIG_PCI_P2PDMA) && (memory_tb < kaslr_regions[0].size_tb))
|
||||
if (!IS_ENABLED(CONFIG_ZONE_DEVICE) && (memory_tb < kaslr_regions[0].size_tb))
|
||||
kaslr_regions[0].size_tb = memory_tb;
|
||||
|
||||
/*
|
||||
|
||||
@@ -140,7 +140,7 @@ bool bio_integrity_prep(struct bio *bio)
|
||||
return true;
|
||||
set_flags = false;
|
||||
gfp |= __GFP_ZERO;
|
||||
} else if (bi->csum_type == BLK_INTEGRITY_CSUM_NONE)
|
||||
} else if (bi->metadata_size > bi->pi_tuple_size)
|
||||
gfp |= __GFP_ZERO;
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -28,6 +28,10 @@ static bool sleep_no_lps0 __read_mostly;
|
||||
module_param(sleep_no_lps0, bool, 0644);
|
||||
MODULE_PARM_DESC(sleep_no_lps0, "Do not use the special LPS0 device interface");
|
||||
|
||||
static bool check_lps0_constraints __read_mostly;
|
||||
module_param(check_lps0_constraints, bool, 0644);
|
||||
MODULE_PARM_DESC(check_lps0_constraints, "Check LPS0 device constraints");
|
||||
|
||||
static const struct acpi_device_id lps0_device_ids[] = {
|
||||
{"PNP0D80", },
|
||||
{"", },
|
||||
@@ -515,7 +519,8 @@ static struct acpi_scan_handler lps0_handler = {
|
||||
|
||||
static int acpi_s2idle_begin_lps0(void)
|
||||
{
|
||||
if (pm_debug_messages_on && !lpi_constraints_table) {
|
||||
if (lps0_device_handle && !sleep_no_lps0 && check_lps0_constraints &&
|
||||
!lpi_constraints_table) {
|
||||
if (acpi_s2idle_vendor_amd())
|
||||
lpi_device_get_constraints_amd();
|
||||
else
|
||||
@@ -539,7 +544,7 @@ static int acpi_s2idle_prepare_late_lps0(void)
|
||||
if (!lps0_device_handle || sleep_no_lps0)
|
||||
return 0;
|
||||
|
||||
if (pm_debug_messages_on)
|
||||
if (check_lps0_constraints)
|
||||
lpi_check_constraints();
|
||||
|
||||
/* Screen off */
|
||||
|
||||
@@ -665,12 +665,22 @@ static void nullb_add_fault_config(struct nullb_device *dev)
|
||||
configfs_add_default_group(&dev->init_hctx_fault_config.group, &dev->group);
|
||||
}
|
||||
|
||||
static void nullb_del_fault_config(struct nullb_device *dev)
|
||||
{
|
||||
config_item_put(&dev->init_hctx_fault_config.group.cg_item);
|
||||
config_item_put(&dev->requeue_config.group.cg_item);
|
||||
config_item_put(&dev->timeout_config.group.cg_item);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static void nullb_add_fault_config(struct nullb_device *dev)
|
||||
{
|
||||
}
|
||||
|
||||
static void nullb_del_fault_config(struct nullb_device *dev)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct
|
||||
@@ -702,7 +712,7 @@ nullb_group_drop_item(struct config_group *group, struct config_item *item)
|
||||
null_del_dev(dev->nullb);
|
||||
mutex_unlock(&lock);
|
||||
}
|
||||
|
||||
nullb_del_fault_config(dev);
|
||||
config_item_put(item);
|
||||
}
|
||||
|
||||
|
||||
@@ -1662,7 +1662,6 @@ static void destroy_sysfs(struct rnbd_clt_dev *dev,
|
||||
/* To avoid deadlock firstly remove itself */
|
||||
sysfs_remove_file_self(&dev->kobj, sysfs_self);
|
||||
kobject_del(&dev->kobj);
|
||||
kobject_put(&dev->kobj);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+9
-2
@@ -75,9 +75,16 @@ EXPORT_SYMBOL_FOR_MODULES(cxl_do_xormap_calc, "cxl_translate");
|
||||
|
||||
static u64 cxl_apply_xor_maps(struct cxl_root_decoder *cxlrd, u64 addr)
|
||||
{
|
||||
struct cxl_cxims_data *cximsd = cxlrd->platform_data;
|
||||
int hbiw = cxlrd->cxlsd.nr_targets;
|
||||
struct cxl_cxims_data *cximsd;
|
||||
|
||||
return cxl_do_xormap_calc(cximsd, addr, cxlrd->cxlsd.nr_targets);
|
||||
/* No xormaps for host bridge interleave ways of 1 or 3 */
|
||||
if (hbiw == 1 || hbiw == 3)
|
||||
return addr;
|
||||
|
||||
cximsd = cxlrd->platform_data;
|
||||
|
||||
return cxl_do_xormap_calc(cximsd, addr, hbiw);
|
||||
}
|
||||
|
||||
struct cxl_cxims_context {
|
||||
|
||||
@@ -403,7 +403,7 @@ static int __cxl_dpa_reserve(struct cxl_endpoint_decoder *cxled,
|
||||
* is not set.
|
||||
*/
|
||||
if (cxled->part < 0)
|
||||
for (int i = 0; cxlds->nr_partitions; i++)
|
||||
for (int i = 0; i < cxlds->nr_partitions; i++)
|
||||
if (resource_contains(&cxlds->part[i].res, res)) {
|
||||
cxled->part = i;
|
||||
break;
|
||||
@@ -530,7 +530,7 @@ resource_size_t cxl_dpa_size(struct cxl_endpoint_decoder *cxled)
|
||||
|
||||
resource_size_t cxl_dpa_resource_start(struct cxl_endpoint_decoder *cxled)
|
||||
{
|
||||
resource_size_t base = -1;
|
||||
resource_size_t base = RESOURCE_SIZE_MAX;
|
||||
|
||||
lockdep_assert_held(&cxl_rwsem.dpa);
|
||||
if (cxled->dpa_res)
|
||||
|
||||
@@ -1590,7 +1590,7 @@ static int update_decoder_targets(struct device *dev, void *data)
|
||||
cxlsd->target[i] = dport;
|
||||
dev_dbg(dev, "dport%d found in target list, index %d\n",
|
||||
dport->port_id, i);
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -759,7 +759,7 @@ static ssize_t extended_linear_cache_size_show(struct device *dev,
|
||||
ACQUIRE(rwsem_read_intr, rwsem)(&cxl_rwsem.region);
|
||||
if ((rc = ACQUIRE_ERR(rwsem_read_intr, &rwsem)))
|
||||
return rc;
|
||||
return sysfs_emit(buf, "%#llx\n", p->cache_size);
|
||||
return sysfs_emit(buf, "%pap\n", &p->cache_size);
|
||||
}
|
||||
static DEVICE_ATTR_RO(extended_linear_cache_size);
|
||||
|
||||
@@ -3118,7 +3118,7 @@ u64 cxl_dpa_to_hpa(struct cxl_region *cxlr, const struct cxl_memdev *cxlmd,
|
||||
struct cxl_root_decoder *cxlrd = to_cxl_root_decoder(cxlr->dev.parent);
|
||||
struct cxl_region_params *p = &cxlr->params;
|
||||
struct cxl_endpoint_decoder *cxled = NULL;
|
||||
u64 dpa_offset, hpa_offset, hpa;
|
||||
u64 base, dpa_offset, hpa_offset, hpa;
|
||||
u16 eig = 0;
|
||||
u8 eiw = 0;
|
||||
int pos;
|
||||
@@ -3136,8 +3136,14 @@ u64 cxl_dpa_to_hpa(struct cxl_region *cxlr, const struct cxl_memdev *cxlmd,
|
||||
ways_to_eiw(p->interleave_ways, &eiw);
|
||||
granularity_to_eig(p->interleave_granularity, &eig);
|
||||
|
||||
dpa_offset = dpa - cxl_dpa_resource_start(cxled);
|
||||
base = cxl_dpa_resource_start(cxled);
|
||||
if (base == RESOURCE_SIZE_MAX)
|
||||
return ULLONG_MAX;
|
||||
|
||||
dpa_offset = dpa - base;
|
||||
hpa_offset = cxl_calculate_hpa_offset(dpa_offset, pos, eiw, eig);
|
||||
if (hpa_offset == ULLONG_MAX)
|
||||
return ULLONG_MAX;
|
||||
|
||||
/* Apply the hpa_offset to the region base address */
|
||||
hpa = hpa_offset + p->res->start + p->cache_size;
|
||||
@@ -3146,6 +3152,9 @@ u64 cxl_dpa_to_hpa(struct cxl_region *cxlr, const struct cxl_memdev *cxlmd,
|
||||
if (cxlrd->ops.hpa_to_spa)
|
||||
hpa = cxlrd->ops.hpa_to_spa(cxlrd, hpa);
|
||||
|
||||
if (hpa == ULLONG_MAX)
|
||||
return ULLONG_MAX;
|
||||
|
||||
if (!cxl_resource_contains_addr(p->res, hpa)) {
|
||||
dev_dbg(&cxlr->dev,
|
||||
"Addr trans fail: hpa 0x%llx not in region\n", hpa);
|
||||
@@ -3170,7 +3179,8 @@ static int region_offset_to_dpa_result(struct cxl_region *cxlr, u64 offset,
|
||||
struct cxl_region_params *p = &cxlr->params;
|
||||
struct cxl_root_decoder *cxlrd = to_cxl_root_decoder(cxlr->dev.parent);
|
||||
struct cxl_endpoint_decoder *cxled;
|
||||
u64 hpa, hpa_offset, dpa_offset;
|
||||
u64 hpa_offset = offset;
|
||||
u64 dpa, dpa_offset;
|
||||
u16 eig = 0;
|
||||
u8 eiw = 0;
|
||||
int pos;
|
||||
@@ -3187,10 +3197,13 @@ static int region_offset_to_dpa_result(struct cxl_region *cxlr, u64 offset,
|
||||
* CXL HPA is assumed to equal SPA.
|
||||
*/
|
||||
if (cxlrd->ops.spa_to_hpa) {
|
||||
hpa = cxlrd->ops.spa_to_hpa(cxlrd, p->res->start + offset);
|
||||
hpa_offset = hpa - p->res->start;
|
||||
} else {
|
||||
hpa_offset = offset;
|
||||
hpa_offset = cxlrd->ops.spa_to_hpa(cxlrd, p->res->start + offset);
|
||||
if (hpa_offset == ULLONG_MAX) {
|
||||
dev_dbg(&cxlr->dev, "HPA not found for %pr offset %#llx\n",
|
||||
p->res, offset);
|
||||
return -ENXIO;
|
||||
}
|
||||
hpa_offset -= p->res->start;
|
||||
}
|
||||
|
||||
pos = cxl_calculate_position(hpa_offset, eiw, eig);
|
||||
@@ -3207,8 +3220,13 @@ static int region_offset_to_dpa_result(struct cxl_region *cxlr, u64 offset,
|
||||
cxled = p->targets[i];
|
||||
if (cxled->pos != pos)
|
||||
continue;
|
||||
|
||||
dpa = cxl_dpa_resource_start(cxled);
|
||||
if (dpa != RESOURCE_SIZE_MAX)
|
||||
dpa += dpa_offset;
|
||||
|
||||
result->cxlmd = cxled_to_memdev(cxled);
|
||||
result->dpa = cxl_dpa_resource_start(cxled) + dpa_offset;
|
||||
result->dpa = dpa;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
* Copyright (c) 2007, MontaVista Software, Inc. <source@mvista.com>
|
||||
*/
|
||||
|
||||
#include <linux/cleanup.h>
|
||||
#include <linux/gpio/driver.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/kernel.h>
|
||||
@@ -109,6 +110,22 @@ davinci_direction_out(struct gpio_chip *chip, unsigned offset, int value)
|
||||
return __davinci_direction(chip, offset, true, value);
|
||||
}
|
||||
|
||||
static int davinci_get_direction(struct gpio_chip *chip, unsigned int offset)
|
||||
{
|
||||
struct davinci_gpio_controller *d = gpiochip_get_data(chip);
|
||||
struct davinci_gpio_regs __iomem *g;
|
||||
u32 mask = __gpio_mask(offset), val;
|
||||
int bank = offset / 32;
|
||||
|
||||
g = d->regs[bank];
|
||||
|
||||
guard(spinlock_irqsave)(&d->lock);
|
||||
|
||||
val = readl_relaxed(&g->dir);
|
||||
|
||||
return (val & mask) ? GPIO_LINE_DIRECTION_IN : GPIO_LINE_DIRECTION_OUT;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read the pin's value (works even if it's set up as output);
|
||||
* returns zero/nonzero.
|
||||
@@ -203,6 +220,7 @@ static int davinci_gpio_probe(struct platform_device *pdev)
|
||||
chips->chip.get = davinci_gpio_get;
|
||||
chips->chip.direction_output = davinci_direction_out;
|
||||
chips->chip.set = davinci_gpio_set;
|
||||
chips->chip.get_direction = davinci_get_direction;
|
||||
|
||||
chips->chip.ngpio = ngpio;
|
||||
chips->chip.base = -1;
|
||||
|
||||
@@ -468,9 +468,6 @@ int gpiod_get_direction(struct gpio_desc *desc)
|
||||
test_bit(GPIOD_FLAG_IS_OUT, &flags))
|
||||
return 0;
|
||||
|
||||
if (!guard.gc->get_direction)
|
||||
return -ENOTSUPP;
|
||||
|
||||
ret = gpiochip_get_direction(guard.gc, offset);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
@@ -274,6 +274,8 @@ extern int amdgpu_rebar;
|
||||
extern int amdgpu_wbrf;
|
||||
extern int amdgpu_user_queue;
|
||||
|
||||
extern uint amdgpu_hdmi_hpd_debounce_delay_ms;
|
||||
|
||||
#define AMDGPU_VM_MAX_NUM_CTX 4096
|
||||
#define AMDGPU_SG_THRESHOLD (256*1024*1024)
|
||||
#define AMDGPU_WAIT_IDLE_TIMEOUT_IN_MS 3000
|
||||
|
||||
@@ -5063,6 +5063,14 @@ void amdgpu_device_fini_hw(struct amdgpu_device *adev)
|
||||
|
||||
amdgpu_ttm_set_buffer_funcs_status(adev, false);
|
||||
|
||||
/*
|
||||
* device went through surprise hotplug; we need to destroy topology
|
||||
* before ip_fini_early to prevent kfd locking refcount issues by calling
|
||||
* amdgpu_amdkfd_suspend()
|
||||
*/
|
||||
if (drm_dev_is_unplugged(adev_to_drm(adev)))
|
||||
amdgpu_amdkfd_device_fini_sw(adev);
|
||||
|
||||
amdgpu_device_ip_fini_early(adev);
|
||||
|
||||
amdgpu_irq_fini_hw(adev);
|
||||
|
||||
@@ -1880,7 +1880,12 @@ int amdgpu_display_get_scanout_buffer(struct drm_plane *plane,
|
||||
struct drm_scanout_buffer *sb)
|
||||
{
|
||||
struct amdgpu_bo *abo;
|
||||
struct drm_framebuffer *fb = plane->state->fb;
|
||||
struct drm_framebuffer *fb;
|
||||
|
||||
if (drm_drv_uses_atomic_modeset(plane->dev))
|
||||
fb = plane->state->fb;
|
||||
else
|
||||
fb = plane->fb;
|
||||
|
||||
if (!fb)
|
||||
return -EINVAL;
|
||||
|
||||
@@ -83,18 +83,6 @@ static int amdgpu_dma_buf_attach(struct dma_buf *dmabuf,
|
||||
struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
|
||||
int r;
|
||||
|
||||
/*
|
||||
* Disable peer-to-peer access for DCC-enabled VRAM surfaces on GFX12+.
|
||||
* Such buffers cannot be safely accessed over P2P due to device-local
|
||||
* compression metadata. Fallback to system-memory path instead.
|
||||
* Device supports GFX12 (GC 12.x or newer)
|
||||
* BO was created with the AMDGPU_GEM_CREATE_GFX12_DCC flag
|
||||
*
|
||||
*/
|
||||
if (amdgpu_ip_version(adev, GC_HWIP, 0) >= IP_VERSION(12, 0, 0) &&
|
||||
bo->flags & AMDGPU_GEM_CREATE_GFX12_DCC)
|
||||
attach->peer2peer = false;
|
||||
|
||||
/*
|
||||
* Disable peer-to-peer access for DCC-enabled VRAM surfaces on GFX12+.
|
||||
* Such buffers cannot be safely accessed over P2P due to device-local
|
||||
|
||||
@@ -247,6 +247,7 @@ int amdgpu_damage_clips = -1; /* auto */
|
||||
int amdgpu_umsch_mm_fwlog;
|
||||
int amdgpu_rebar = -1; /* auto */
|
||||
int amdgpu_user_queue = -1;
|
||||
uint amdgpu_hdmi_hpd_debounce_delay_ms;
|
||||
|
||||
DECLARE_DYNDBG_CLASSMAP(drm_debug_classes, DD_CLASS_TYPE_DISJOINT_BITS, 0,
|
||||
"DRM_UT_CORE",
|
||||
@@ -1123,6 +1124,16 @@ module_param_named(rebar, amdgpu_rebar, int, 0444);
|
||||
MODULE_PARM_DESC(user_queue, "Enable user queues (-1 = auto (default), 0 = disable, 1 = enable, 2 = enable UQs and disable KQs)");
|
||||
module_param_named(user_queue, amdgpu_user_queue, int, 0444);
|
||||
|
||||
/*
|
||||
* DOC: hdmi_hpd_debounce_delay_ms (uint)
|
||||
* HDMI HPD disconnect debounce delay in milliseconds.
|
||||
*
|
||||
* Used to filter short disconnect->reconnect HPD toggles some HDMI sinks
|
||||
* generate while entering/leaving power save. Set to 0 to disable by default.
|
||||
*/
|
||||
MODULE_PARM_DESC(hdmi_hpd_debounce_delay_ms, "HDMI HPD disconnect debounce delay in milliseconds (0 to disable (by default), 1500 is common)");
|
||||
module_param_named(hdmi_hpd_debounce_delay_ms, amdgpu_hdmi_hpd_debounce_delay_ms, uint, 0644);
|
||||
|
||||
/* These devices are not supported by amdgpu.
|
||||
* They are supported by the mach64, r128, radeon drivers
|
||||
*/
|
||||
|
||||
@@ -375,7 +375,7 @@ void amdgpu_gart_map(struct amdgpu_device *adev, uint64_t offset,
|
||||
* @start_page: first page to map in the GART aperture
|
||||
* @num_pages: number of pages to be mapped
|
||||
* @flags: page table entry flags
|
||||
* @dst: CPU address of the GART table
|
||||
* @dst: valid CPU address of GART table, cannot be null
|
||||
*
|
||||
* Binds a BO that is allocated in VRAM to the GART page table
|
||||
* (all ASICs).
|
||||
@@ -396,7 +396,7 @@ void amdgpu_gart_map_vram_range(struct amdgpu_device *adev, uint64_t pa,
|
||||
return;
|
||||
|
||||
for (i = 0; i < num_pages; ++i) {
|
||||
amdgpu_gmc_set_pte_pde(adev, adev->gart.ptr,
|
||||
amdgpu_gmc_set_pte_pde(adev, dst,
|
||||
start_page + i, pa + AMDGPU_GPU_PAGE_SIZE * i, flags);
|
||||
}
|
||||
|
||||
|
||||
@@ -732,6 +732,10 @@ int amdgpu_gmc_flush_gpu_tlb_pasid(struct amdgpu_device *adev, uint16_t pasid,
|
||||
return 0;
|
||||
|
||||
if (!adev->gmc.flush_pasid_uses_kiq || !ring->sched.ready) {
|
||||
|
||||
if (!adev->gmc.gmc_funcs->flush_gpu_tlb_pasid)
|
||||
return 0;
|
||||
|
||||
if (adev->gmc.flush_tlb_needs_extra_type_2)
|
||||
adev->gmc.gmc_funcs->flush_gpu_tlb_pasid(adev, pasid,
|
||||
2, all_hub,
|
||||
|
||||
@@ -885,12 +885,28 @@ static int amdgpu_userq_input_args_validate(struct drm_device *dev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool amdgpu_userq_enabled(struct drm_device *dev)
|
||||
{
|
||||
struct amdgpu_device *adev = drm_to_adev(dev);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < AMDGPU_HW_IP_NUM; i++) {
|
||||
if (adev->userq_funcs[i])
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int amdgpu_userq_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_file *filp)
|
||||
{
|
||||
union drm_amdgpu_userq *args = data;
|
||||
int r;
|
||||
|
||||
if (!amdgpu_userq_enabled(dev))
|
||||
return -ENOTSUPP;
|
||||
|
||||
if (amdgpu_userq_input_args_validate(dev, args, filp) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
|
||||
@@ -141,6 +141,7 @@ uint64_t amdgpu_userq_get_doorbell_index(struct amdgpu_userq_mgr *uq_mgr,
|
||||
struct drm_file *filp);
|
||||
|
||||
u32 amdgpu_userq_get_supported_ip_mask(struct amdgpu_device *adev);
|
||||
bool amdgpu_userq_enabled(struct drm_device *dev);
|
||||
|
||||
int amdgpu_userq_suspend(struct amdgpu_device *adev);
|
||||
int amdgpu_userq_resume(struct amdgpu_device *adev);
|
||||
|
||||
@@ -141,6 +141,8 @@ static void amdgpu_userq_walk_and_drop_fence_drv(struct xarray *xa)
|
||||
void
|
||||
amdgpu_userq_fence_driver_free(struct amdgpu_usermode_queue *userq)
|
||||
{
|
||||
dma_fence_put(userq->last_fence);
|
||||
|
||||
amdgpu_userq_walk_and_drop_fence_drv(&userq->fence_drv_xa);
|
||||
xa_destroy(&userq->fence_drv_xa);
|
||||
/* Drop the fence_drv reference held by user queue */
|
||||
@@ -471,6 +473,9 @@ int amdgpu_userq_signal_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_exec exec;
|
||||
u64 wptr;
|
||||
|
||||
if (!amdgpu_userq_enabled(dev))
|
||||
return -ENOTSUPP;
|
||||
|
||||
num_syncobj_handles = args->num_syncobj_handles;
|
||||
syncobj_handles = memdup_user(u64_to_user_ptr(args->syncobj_handles),
|
||||
size_mul(sizeof(u32), num_syncobj_handles));
|
||||
@@ -653,6 +658,9 @@ int amdgpu_userq_wait_ioctl(struct drm_device *dev, void *data,
|
||||
int r, i, rentry, wentry, cnt;
|
||||
struct drm_exec exec;
|
||||
|
||||
if (!amdgpu_userq_enabled(dev))
|
||||
return -ENOTSUPP;
|
||||
|
||||
num_read_bo_handles = wait_info->num_bo_read_handles;
|
||||
bo_handles_read = memdup_user(u64_to_user_ptr(wait_info->bo_read_handles),
|
||||
size_mul(sizeof(u32), num_read_bo_handles));
|
||||
|
||||
@@ -1069,9 +1069,7 @@ amdgpu_vm_tlb_flush(struct amdgpu_vm_update_params *params,
|
||||
}
|
||||
|
||||
/* Prepare a TLB flush fence to be attached to PTs */
|
||||
if (!params->unlocked &&
|
||||
/* SI doesn't support pasid or KIQ/MES */
|
||||
params->adev->family > AMDGPU_FAMILY_SI) {
|
||||
if (!params->unlocked) {
|
||||
amdgpu_vm_tlb_fence_create(params->adev, vm, fence);
|
||||
|
||||
/* Makes sure no PD/PT is freed before the flush */
|
||||
|
||||
@@ -1235,16 +1235,16 @@ static void gmc_v9_0_get_vm_pte(struct amdgpu_device *adev,
|
||||
*flags = AMDGPU_PTE_MTYPE_VG10(*flags, MTYPE_NC);
|
||||
break;
|
||||
case AMDGPU_VM_MTYPE_WC:
|
||||
*flags |= AMDGPU_PTE_MTYPE_VG10(*flags, MTYPE_WC);
|
||||
*flags = AMDGPU_PTE_MTYPE_VG10(*flags, MTYPE_WC);
|
||||
break;
|
||||
case AMDGPU_VM_MTYPE_RW:
|
||||
*flags |= AMDGPU_PTE_MTYPE_VG10(*flags, MTYPE_RW);
|
||||
*flags = AMDGPU_PTE_MTYPE_VG10(*flags, MTYPE_RW);
|
||||
break;
|
||||
case AMDGPU_VM_MTYPE_CC:
|
||||
*flags |= AMDGPU_PTE_MTYPE_VG10(*flags, MTYPE_CC);
|
||||
*flags = AMDGPU_PTE_MTYPE_VG10(*flags, MTYPE_CC);
|
||||
break;
|
||||
case AMDGPU_VM_MTYPE_UC:
|
||||
*flags |= AMDGPU_PTE_MTYPE_VG10(*flags, MTYPE_UC);
|
||||
*flags = AMDGPU_PTE_MTYPE_VG10(*flags, MTYPE_UC);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -1209,14 +1209,8 @@ static int evict_process_queues_cpsch(struct device_queue_manager *dqm,
|
||||
pr_debug_ratelimited("Evicting process pid %d queues\n",
|
||||
pdd->process->lead_thread->pid);
|
||||
|
||||
if (dqm->dev->kfd->shared_resources.enable_mes) {
|
||||
if (dqm->dev->kfd->shared_resources.enable_mes)
|
||||
pdd->last_evict_timestamp = get_jiffies_64();
|
||||
retval = suspend_all_queues_mes(dqm);
|
||||
if (retval) {
|
||||
dev_err(dev, "Suspending all queues failed");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
/* Mark all queues as evicted. Deactivate all active queues on
|
||||
* the qpd.
|
||||
@@ -1246,10 +1240,6 @@ static int evict_process_queues_cpsch(struct device_queue_manager *dqm,
|
||||
KFD_UNMAP_QUEUES_FILTER_ALL_QUEUES :
|
||||
KFD_UNMAP_QUEUES_FILTER_DYNAMIC_QUEUES, 0,
|
||||
USE_DEFAULT_GRACE_PERIOD);
|
||||
} else {
|
||||
retval = resume_all_queues_mes(dqm);
|
||||
if (retval)
|
||||
dev_err(dev, "Resuming all queues failed");
|
||||
}
|
||||
|
||||
out:
|
||||
@@ -2919,6 +2909,14 @@ static int allocate_hiq_sdma_mqd(struct device_queue_manager *dqm)
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void deallocate_hiq_sdma_mqd(struct kfd_node *dev,
|
||||
struct kfd_mem_obj *mqd)
|
||||
{
|
||||
WARN(!mqd, "No hiq sdma mqd trunk to free");
|
||||
|
||||
amdgpu_amdkfd_free_gtt_mem(dev->adev, &mqd->gtt_mem);
|
||||
}
|
||||
|
||||
struct device_queue_manager *device_queue_manager_init(struct kfd_node *dev)
|
||||
{
|
||||
struct device_queue_manager *dqm;
|
||||
@@ -3042,19 +3040,14 @@ struct device_queue_manager *device_queue_manager_init(struct kfd_node *dev)
|
||||
return dqm;
|
||||
}
|
||||
|
||||
if (!dev->kfd->shared_resources.enable_mes)
|
||||
deallocate_hiq_sdma_mqd(dev, &dqm->hiq_sdma_mqd);
|
||||
|
||||
out_free:
|
||||
kfree(dqm);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void deallocate_hiq_sdma_mqd(struct kfd_node *dev,
|
||||
struct kfd_mem_obj *mqd)
|
||||
{
|
||||
WARN(!mqd, "No hiq sdma mqd trunk to free");
|
||||
|
||||
amdgpu_amdkfd_free_gtt_mem(dev->adev, &mqd->gtt_mem);
|
||||
}
|
||||
|
||||
void device_queue_manager_uninit(struct device_queue_manager *dqm)
|
||||
{
|
||||
dqm->ops.stop(dqm);
|
||||
|
||||
@@ -5266,6 +5266,8 @@ amdgpu_dm_register_backlight_device(struct amdgpu_dm_connector *aconnector)
|
||||
struct amdgpu_dm_backlight_caps *caps;
|
||||
char bl_name[16];
|
||||
int min, max;
|
||||
int real_brightness;
|
||||
int init_brightness;
|
||||
|
||||
if (aconnector->bl_idx == -1)
|
||||
return;
|
||||
@@ -5290,6 +5292,8 @@ amdgpu_dm_register_backlight_device(struct amdgpu_dm_connector *aconnector)
|
||||
} else
|
||||
props.brightness = props.max_brightness = MAX_BACKLIGHT_LEVEL;
|
||||
|
||||
init_brightness = props.brightness;
|
||||
|
||||
if (caps->data_points && !(amdgpu_dc_debug_mask & DC_DISABLE_CUSTOM_BRIGHTNESS_CURVE)) {
|
||||
drm_info(drm, "Using custom brightness curve\n");
|
||||
props.scale = BACKLIGHT_SCALE_NON_LINEAR;
|
||||
@@ -5308,8 +5312,20 @@ amdgpu_dm_register_backlight_device(struct amdgpu_dm_connector *aconnector)
|
||||
if (IS_ERR(dm->backlight_dev[aconnector->bl_idx])) {
|
||||
drm_err(drm, "DM: Backlight registration failed!\n");
|
||||
dm->backlight_dev[aconnector->bl_idx] = NULL;
|
||||
} else
|
||||
} else {
|
||||
/*
|
||||
* dm->brightness[x] can be inconsistent just after startup until
|
||||
* ops.get_brightness is called.
|
||||
*/
|
||||
real_brightness =
|
||||
amdgpu_dm_backlight_ops.get_brightness(dm->backlight_dev[aconnector->bl_idx]);
|
||||
|
||||
if (real_brightness != init_brightness) {
|
||||
dm->actual_brightness[aconnector->bl_idx] = real_brightness;
|
||||
dm->brightness[aconnector->bl_idx] = real_brightness;
|
||||
}
|
||||
drm_dbg_driver(drm, "DM: Registered Backlight device: %s\n", bl_name);
|
||||
}
|
||||
}
|
||||
|
||||
static int initialize_plane(struct amdgpu_display_manager *dm,
|
||||
@@ -5626,7 +5642,8 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
|
||||
|
||||
if (psr_feature_enabled) {
|
||||
amdgpu_dm_set_psr_caps(link);
|
||||
drm_info(adev_to_drm(adev), "PSR support %d, DC PSR ver %d, sink PSR ver %d DPCD caps 0x%x su_y_granularity %d\n",
|
||||
drm_info(adev_to_drm(adev), "%s: PSR support %d, DC PSR ver %d, sink PSR ver %d DPCD caps 0x%x su_y_granularity %d\n",
|
||||
aconnector->base.name,
|
||||
link->psr_settings.psr_feature_enabled,
|
||||
link->psr_settings.psr_version,
|
||||
link->dpcd_caps.psr_info.psr_version,
|
||||
@@ -8930,9 +8947,18 @@ void amdgpu_dm_connector_init_helper(struct amdgpu_display_manager *dm,
|
||||
mutex_init(&aconnector->hpd_lock);
|
||||
mutex_init(&aconnector->handle_mst_msg_ready);
|
||||
|
||||
aconnector->hdmi_hpd_debounce_delay_ms = AMDGPU_DM_HDMI_HPD_DEBOUNCE_MS;
|
||||
INIT_DELAYED_WORK(&aconnector->hdmi_hpd_debounce_work, hdmi_hpd_debounce_work);
|
||||
aconnector->hdmi_prev_sink = NULL;
|
||||
/*
|
||||
* If HDMI HPD debounce delay is set, use the minimum between selected
|
||||
* value and AMDGPU_DM_MAX_HDMI_HPD_DEBOUNCE_MS
|
||||
*/
|
||||
if (amdgpu_hdmi_hpd_debounce_delay_ms) {
|
||||
aconnector->hdmi_hpd_debounce_delay_ms = min(amdgpu_hdmi_hpd_debounce_delay_ms,
|
||||
AMDGPU_DM_MAX_HDMI_HPD_DEBOUNCE_MS);
|
||||
INIT_DELAYED_WORK(&aconnector->hdmi_hpd_debounce_work, hdmi_hpd_debounce_work);
|
||||
aconnector->hdmi_prev_sink = NULL;
|
||||
} else {
|
||||
aconnector->hdmi_hpd_debounce_delay_ms = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* configure support HPD hot plug connector_>polled default value is 0
|
||||
|
||||
@@ -59,7 +59,10 @@
|
||||
|
||||
#define AMDGPU_HDR_MULT_DEFAULT (0x100000000LL)
|
||||
|
||||
#define AMDGPU_DM_HDMI_HPD_DEBOUNCE_MS 1500
|
||||
/*
|
||||
* Maximum HDMI HPD debounce delay in milliseconds
|
||||
*/
|
||||
#define AMDGPU_DM_MAX_HDMI_HPD_DEBOUNCE_MS 5000
|
||||
/*
|
||||
#include "include/amdgpu_dal_power_if.h"
|
||||
#include "amdgpu_dm_irq.h"
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
/* kHZ*/
|
||||
#define DP_ADAPTOR_DVI_MAX_TMDS_CLK 165000
|
||||
/* kHZ*/
|
||||
#define DP_ADAPTOR_HDMI_SAFE_MAX_TMDS_CLK 165000
|
||||
#define DP_ADAPTOR_HDMI_SAFE_MAX_TMDS_CLK 340000
|
||||
|
||||
struct dp_hdmi_dongle_signature_data {
|
||||
int8_t id[15];/* "DP-HDMI ADAPTOR"*/
|
||||
|
||||
@@ -336,7 +336,7 @@ static void query_dp_dual_mode_adaptor(
|
||||
|
||||
/* Assume we have no valid DP passive dongle connected */
|
||||
*dongle = DISPLAY_DONGLE_NONE;
|
||||
sink_cap->max_hdmi_pixel_clock = DP_ADAPTOR_HDMI_SAFE_MAX_TMDS_CLK;
|
||||
sink_cap->max_hdmi_pixel_clock = DP_ADAPTOR_DVI_MAX_TMDS_CLK;
|
||||
|
||||
/* Read DP-HDMI dongle I2c (no response interpreted as DP-DVI dongle)*/
|
||||
if (!i2c_read(
|
||||
@@ -392,6 +392,8 @@ static void query_dp_dual_mode_adaptor(
|
||||
|
||||
}
|
||||
}
|
||||
if (is_valid_hdmi_signature)
|
||||
sink_cap->max_hdmi_pixel_clock = DP_ADAPTOR_HDMI_SAFE_MAX_TMDS_CLK;
|
||||
|
||||
if (is_type2_dongle) {
|
||||
uint32_t max_tmds_clk =
|
||||
|
||||
@@ -1702,8 +1702,9 @@ static int smu_v14_0_2_get_power_limit(struct smu_context *smu,
|
||||
table_context->power_play_table;
|
||||
PPTable_t *pptable = table_context->driver_pptable;
|
||||
CustomSkuTable_t *skutable = &pptable->CustomSkuTable;
|
||||
uint32_t power_limit, od_percent_upper = 0, od_percent_lower = 0;
|
||||
int16_t od_percent_upper = 0, od_percent_lower = 0;
|
||||
uint32_t msg_limit = pptable->SkuTable.MsgLimits.Power[PPT_THROTTLER_PPT0][POWER_SOURCE_AC];
|
||||
uint32_t power_limit;
|
||||
|
||||
if (smu_v14_0_get_current_power_limit(smu, &power_limit))
|
||||
power_limit = smu->adev->pm.ac_power ?
|
||||
|
||||
@@ -163,6 +163,7 @@ struct dw_hdmi_qp {
|
||||
|
||||
unsigned long ref_clk_rate;
|
||||
struct regmap *regm;
|
||||
int main_irq;
|
||||
|
||||
unsigned long tmds_char_rate;
|
||||
};
|
||||
@@ -1271,6 +1272,7 @@ struct dw_hdmi_qp *dw_hdmi_qp_bind(struct platform_device *pdev,
|
||||
|
||||
dw_hdmi_qp_init_hw(hdmi);
|
||||
|
||||
hdmi->main_irq = plat_data->main_irq;
|
||||
ret = devm_request_threaded_irq(dev, plat_data->main_irq,
|
||||
dw_hdmi_qp_main_hardirq, NULL,
|
||||
IRQF_SHARED, dev_name(dev), hdmi);
|
||||
@@ -1331,9 +1333,16 @@ struct dw_hdmi_qp *dw_hdmi_qp_bind(struct platform_device *pdev,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(dw_hdmi_qp_bind);
|
||||
|
||||
void dw_hdmi_qp_suspend(struct device *dev, struct dw_hdmi_qp *hdmi)
|
||||
{
|
||||
disable_irq(hdmi->main_irq);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(dw_hdmi_qp_suspend);
|
||||
|
||||
void dw_hdmi_qp_resume(struct device *dev, struct dw_hdmi_qp *hdmi)
|
||||
{
|
||||
dw_hdmi_qp_init_hw(hdmi);
|
||||
enable_irq(hdmi->main_irq);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(dw_hdmi_qp_resume);
|
||||
|
||||
|
||||
+51
-24
@@ -1602,24 +1602,23 @@ drm_gpuvm_bo_create(struct drm_gpuvm *gpuvm,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(drm_gpuvm_bo_create);
|
||||
|
||||
/*
|
||||
* drm_gpuvm_bo_destroy_not_in_lists() - final part of drm_gpuvm_bo cleanup
|
||||
* @vm_bo: the &drm_gpuvm_bo to destroy
|
||||
*
|
||||
* It is illegal to call this method if the @vm_bo is present in the GEMs gpuva
|
||||
* list, the extobj list, or the evicted list.
|
||||
*
|
||||
* Note that this puts a refcount on the GEM object, which may destroy the GEM
|
||||
* object if the refcount reaches zero. It's illegal for this to happen if the
|
||||
* caller holds the GEMs gpuva mutex because it would free the mutex.
|
||||
*/
|
||||
static void
|
||||
drm_gpuvm_bo_destroy(struct kref *kref)
|
||||
drm_gpuvm_bo_destroy_not_in_lists(struct drm_gpuvm_bo *vm_bo)
|
||||
{
|
||||
struct drm_gpuvm_bo *vm_bo = container_of(kref, struct drm_gpuvm_bo,
|
||||
kref);
|
||||
struct drm_gpuvm *gpuvm = vm_bo->vm;
|
||||
const struct drm_gpuvm_ops *ops = gpuvm->ops;
|
||||
struct drm_gem_object *obj = vm_bo->obj;
|
||||
bool lock = !drm_gpuvm_resv_protected(gpuvm);
|
||||
|
||||
if (!lock)
|
||||
drm_gpuvm_resv_assert_held(gpuvm);
|
||||
|
||||
drm_gpuvm_bo_list_del(vm_bo, extobj, lock);
|
||||
drm_gpuvm_bo_list_del(vm_bo, evict, lock);
|
||||
|
||||
drm_gem_gpuva_assert_lock_held(gpuvm, obj);
|
||||
list_del(&vm_bo->list.entry.gem);
|
||||
|
||||
if (ops && ops->vm_bo_free)
|
||||
ops->vm_bo_free(vm_bo);
|
||||
@@ -1630,6 +1629,35 @@ drm_gpuvm_bo_destroy(struct kref *kref)
|
||||
drm_gem_object_put(obj);
|
||||
}
|
||||
|
||||
static void
|
||||
drm_gpuvm_bo_destroy_not_in_lists_kref(struct kref *kref)
|
||||
{
|
||||
struct drm_gpuvm_bo *vm_bo = container_of(kref, struct drm_gpuvm_bo,
|
||||
kref);
|
||||
|
||||
drm_gpuvm_bo_destroy_not_in_lists(vm_bo);
|
||||
}
|
||||
|
||||
static void
|
||||
drm_gpuvm_bo_destroy(struct kref *kref)
|
||||
{
|
||||
struct drm_gpuvm_bo *vm_bo = container_of(kref, struct drm_gpuvm_bo,
|
||||
kref);
|
||||
struct drm_gpuvm *gpuvm = vm_bo->vm;
|
||||
bool lock = !drm_gpuvm_resv_protected(gpuvm);
|
||||
|
||||
if (!lock)
|
||||
drm_gpuvm_resv_assert_held(gpuvm);
|
||||
|
||||
drm_gpuvm_bo_list_del(vm_bo, extobj, lock);
|
||||
drm_gpuvm_bo_list_del(vm_bo, evict, lock);
|
||||
|
||||
drm_gem_gpuva_assert_lock_held(gpuvm, vm_bo->obj);
|
||||
list_del(&vm_bo->list.entry.gem);
|
||||
|
||||
drm_gpuvm_bo_destroy_not_in_lists(vm_bo);
|
||||
}
|
||||
|
||||
/**
|
||||
* drm_gpuvm_bo_put() - drop a struct drm_gpuvm_bo reference
|
||||
* @vm_bo: the &drm_gpuvm_bo to release the reference of
|
||||
@@ -1745,9 +1773,7 @@ EXPORT_SYMBOL_GPL(drm_gpuvm_bo_put_deferred);
|
||||
void
|
||||
drm_gpuvm_bo_deferred_cleanup(struct drm_gpuvm *gpuvm)
|
||||
{
|
||||
const struct drm_gpuvm_ops *ops = gpuvm->ops;
|
||||
struct drm_gpuvm_bo *vm_bo;
|
||||
struct drm_gem_object *obj;
|
||||
struct llist_node *bo_defer;
|
||||
|
||||
bo_defer = llist_del_all(&gpuvm->bo_defer);
|
||||
@@ -1766,14 +1792,7 @@ drm_gpuvm_bo_deferred_cleanup(struct drm_gpuvm *gpuvm)
|
||||
while (bo_defer) {
|
||||
vm_bo = llist_entry(bo_defer, struct drm_gpuvm_bo, list.entry.bo_defer);
|
||||
bo_defer = bo_defer->next;
|
||||
obj = vm_bo->obj;
|
||||
if (ops && ops->vm_bo_free)
|
||||
ops->vm_bo_free(vm_bo);
|
||||
else
|
||||
kfree(vm_bo);
|
||||
|
||||
drm_gpuvm_put(gpuvm);
|
||||
drm_gem_object_put(obj);
|
||||
drm_gpuvm_bo_destroy_not_in_lists(vm_bo);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(drm_gpuvm_bo_deferred_cleanup);
|
||||
@@ -1861,6 +1880,9 @@ EXPORT_SYMBOL_GPL(drm_gpuvm_bo_obtain);
|
||||
* count is decreased. If not found @__vm_bo is returned without further
|
||||
* increase of the reference count.
|
||||
*
|
||||
* The provided @__vm_bo must not already be in the gpuva, evict, or extobj
|
||||
* lists prior to calling this method.
|
||||
*
|
||||
* A new &drm_gpuvm_bo is added to the GEMs gpuva list.
|
||||
*
|
||||
* Returns: a pointer to the found &drm_gpuvm_bo or @__vm_bo if no existing
|
||||
@@ -1873,14 +1895,19 @@ drm_gpuvm_bo_obtain_prealloc(struct drm_gpuvm_bo *__vm_bo)
|
||||
struct drm_gem_object *obj = __vm_bo->obj;
|
||||
struct drm_gpuvm_bo *vm_bo;
|
||||
|
||||
drm_WARN_ON(gpuvm->drm, !drm_gpuvm_immediate_mode(gpuvm));
|
||||
|
||||
mutex_lock(&obj->gpuva.lock);
|
||||
vm_bo = drm_gpuvm_bo_find(gpuvm, obj);
|
||||
if (vm_bo) {
|
||||
drm_gpuvm_bo_put(__vm_bo);
|
||||
mutex_unlock(&obj->gpuva.lock);
|
||||
kref_put(&__vm_bo->kref, drm_gpuvm_bo_destroy_not_in_lists_kref);
|
||||
return vm_bo;
|
||||
}
|
||||
|
||||
drm_gem_gpuva_assert_lock_held(gpuvm, obj);
|
||||
list_add_tail(&__vm_bo->list.entry.gem, &obj->gpuva.list);
|
||||
mutex_unlock(&obj->gpuva.lock);
|
||||
|
||||
return __vm_bo;
|
||||
}
|
||||
|
||||
@@ -457,27 +457,20 @@ int gud_plane_atomic_check(struct drm_plane *plane,
|
||||
struct drm_plane_state *old_plane_state = drm_atomic_get_old_plane_state(state, plane);
|
||||
struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state, plane);
|
||||
struct drm_crtc *crtc = new_plane_state->crtc;
|
||||
struct drm_crtc_state *crtc_state;
|
||||
struct drm_crtc_state *crtc_state = NULL;
|
||||
const struct drm_display_mode *mode;
|
||||
struct drm_framebuffer *old_fb = old_plane_state->fb;
|
||||
struct drm_connector_state *connector_state = NULL;
|
||||
struct drm_framebuffer *fb = new_plane_state->fb;
|
||||
const struct drm_format_info *format = fb->format;
|
||||
const struct drm_format_info *format;
|
||||
struct drm_connector *connector;
|
||||
unsigned int i, num_properties;
|
||||
struct gud_state_req *req;
|
||||
int idx, ret;
|
||||
size_t len;
|
||||
|
||||
if (drm_WARN_ON_ONCE(plane->dev, !fb))
|
||||
return -EINVAL;
|
||||
|
||||
if (drm_WARN_ON_ONCE(plane->dev, !crtc))
|
||||
return -EINVAL;
|
||||
|
||||
crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
|
||||
|
||||
mode = &crtc_state->mode;
|
||||
if (crtc)
|
||||
crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
|
||||
|
||||
ret = drm_atomic_helper_check_plane_state(new_plane_state, crtc_state,
|
||||
DRM_PLANE_NO_SCALING,
|
||||
@@ -492,6 +485,9 @@ int gud_plane_atomic_check(struct drm_plane *plane,
|
||||
if (old_plane_state->rotation != new_plane_state->rotation)
|
||||
crtc_state->mode_changed = true;
|
||||
|
||||
mode = &crtc_state->mode;
|
||||
format = fb->format;
|
||||
|
||||
if (old_fb && old_fb->format != format)
|
||||
crtc_state->mode_changed = true;
|
||||
|
||||
@@ -598,7 +594,7 @@ void gud_plane_atomic_update(struct drm_plane *plane,
|
||||
struct drm_atomic_helper_damage_iter iter;
|
||||
int ret, idx;
|
||||
|
||||
if (crtc->state->mode_changed || !crtc->state->enable) {
|
||||
if (!crtc || crtc->state->mode_changed || !crtc->state->enable) {
|
||||
cancel_work_sync(&gdrm->work);
|
||||
mutex_lock(&gdrm->damage_lock);
|
||||
if (gdrm->fb) {
|
||||
|
||||
@@ -686,7 +686,7 @@ static void err_print_guc_ctb(struct drm_i915_error_state_buf *m,
|
||||
}
|
||||
|
||||
/* This list includes registers that are useful in debugging GuC hangs. */
|
||||
const struct {
|
||||
static const struct {
|
||||
u32 start;
|
||||
u32 count;
|
||||
} guc_hw_reg_state[] = {
|
||||
|
||||
@@ -84,6 +84,7 @@ curs507a_prepare(struct nv50_wndw *wndw, struct nv50_head_atom *asyh,
|
||||
asyh->curs.handle = handle;
|
||||
asyh->curs.offset = offset;
|
||||
asyh->set.curs = asyh->curs.visible;
|
||||
nv50_atom(asyh->state.state)->lock_core = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -43,6 +43,9 @@ nv50_head_flush_clr(struct nv50_head *head,
|
||||
union nv50_head_atom_mask clr = {
|
||||
.mask = asyh->clr.mask & ~(flush ? 0 : asyh->set.mask),
|
||||
};
|
||||
|
||||
lockdep_assert_held(&head->disp->mutex);
|
||||
|
||||
if (clr.crc) nv50_crc_atomic_clr(head);
|
||||
if (clr.olut) head->func->olut_clr(head);
|
||||
if (clr.core) head->func->core_clr(head);
|
||||
@@ -65,6 +68,8 @@ nv50_head_flush_set_wndw(struct nv50_head *head, struct nv50_head_atom *asyh)
|
||||
void
|
||||
nv50_head_flush_set(struct nv50_head *head, struct nv50_head_atom *asyh)
|
||||
{
|
||||
lockdep_assert_held(&head->disp->mutex);
|
||||
|
||||
if (asyh->set.view ) head->func->view (head, asyh);
|
||||
if (asyh->set.mode ) head->func->mode (head, asyh);
|
||||
if (asyh->set.core ) head->func->core_set(head, asyh);
|
||||
|
||||
@@ -623,8 +623,61 @@ static struct panel_simple *panel_simple_probe(struct device *dev)
|
||||
if (IS_ERR(desc))
|
||||
return ERR_CAST(desc);
|
||||
|
||||
connector_type = desc->connector_type;
|
||||
/* Catch common mistakes for panels. */
|
||||
switch (connector_type) {
|
||||
case 0:
|
||||
dev_warn(dev, "Specify missing connector_type\n");
|
||||
connector_type = DRM_MODE_CONNECTOR_DPI;
|
||||
break;
|
||||
case DRM_MODE_CONNECTOR_LVDS:
|
||||
WARN_ON(desc->bus_flags &
|
||||
~(DRM_BUS_FLAG_DE_LOW |
|
||||
DRM_BUS_FLAG_DE_HIGH |
|
||||
DRM_BUS_FLAG_DATA_MSB_TO_LSB |
|
||||
DRM_BUS_FLAG_DATA_LSB_TO_MSB));
|
||||
WARN_ON(desc->bus_format != MEDIA_BUS_FMT_RGB666_1X7X3_SPWG &&
|
||||
desc->bus_format != MEDIA_BUS_FMT_RGB888_1X7X4_SPWG &&
|
||||
desc->bus_format != MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA);
|
||||
WARN_ON(desc->bus_format == MEDIA_BUS_FMT_RGB666_1X7X3_SPWG &&
|
||||
desc->bpc != 6);
|
||||
WARN_ON((desc->bus_format == MEDIA_BUS_FMT_RGB888_1X7X4_SPWG ||
|
||||
desc->bus_format == MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA) &&
|
||||
desc->bpc != 8);
|
||||
break;
|
||||
case DRM_MODE_CONNECTOR_eDP:
|
||||
dev_warn(dev, "eDP panels moved to panel-edp\n");
|
||||
return ERR_PTR(-EINVAL);
|
||||
case DRM_MODE_CONNECTOR_DSI:
|
||||
if (desc->bpc != 6 && desc->bpc != 8)
|
||||
dev_warn(dev, "Expected bpc in {6,8} but got: %u\n", desc->bpc);
|
||||
break;
|
||||
case DRM_MODE_CONNECTOR_DPI:
|
||||
bus_flags = DRM_BUS_FLAG_DE_LOW |
|
||||
DRM_BUS_FLAG_DE_HIGH |
|
||||
DRM_BUS_FLAG_PIXDATA_SAMPLE_POSEDGE |
|
||||
DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE |
|
||||
DRM_BUS_FLAG_DATA_MSB_TO_LSB |
|
||||
DRM_BUS_FLAG_DATA_LSB_TO_MSB |
|
||||
DRM_BUS_FLAG_SYNC_SAMPLE_POSEDGE |
|
||||
DRM_BUS_FLAG_SYNC_SAMPLE_NEGEDGE;
|
||||
if (desc->bus_flags & ~bus_flags)
|
||||
dev_warn(dev, "Unexpected bus_flags(%d)\n", desc->bus_flags & ~bus_flags);
|
||||
if (!(desc->bus_flags & bus_flags))
|
||||
dev_warn(dev, "Specify missing bus_flags\n");
|
||||
if (desc->bus_format == 0)
|
||||
dev_warn(dev, "Specify missing bus_format\n");
|
||||
if (desc->bpc != 6 && desc->bpc != 8)
|
||||
dev_warn(dev, "Expected bpc in {6,8} but got: %u\n", desc->bpc);
|
||||
break;
|
||||
default:
|
||||
dev_warn(dev, "Specify a valid connector_type: %d\n", desc->connector_type);
|
||||
connector_type = DRM_MODE_CONNECTOR_DPI;
|
||||
break;
|
||||
}
|
||||
|
||||
panel = devm_drm_panel_alloc(dev, struct panel_simple, base,
|
||||
&panel_simple_funcs, desc->connector_type);
|
||||
&panel_simple_funcs, connector_type);
|
||||
if (IS_ERR(panel))
|
||||
return ERR_CAST(panel);
|
||||
|
||||
@@ -666,60 +719,6 @@ static struct panel_simple *panel_simple_probe(struct device *dev)
|
||||
goto free_ddc;
|
||||
}
|
||||
|
||||
connector_type = desc->connector_type;
|
||||
/* Catch common mistakes for panels. */
|
||||
switch (connector_type) {
|
||||
case 0:
|
||||
dev_warn(dev, "Specify missing connector_type\n");
|
||||
connector_type = DRM_MODE_CONNECTOR_DPI;
|
||||
break;
|
||||
case DRM_MODE_CONNECTOR_LVDS:
|
||||
WARN_ON(desc->bus_flags &
|
||||
~(DRM_BUS_FLAG_DE_LOW |
|
||||
DRM_BUS_FLAG_DE_HIGH |
|
||||
DRM_BUS_FLAG_DATA_MSB_TO_LSB |
|
||||
DRM_BUS_FLAG_DATA_LSB_TO_MSB));
|
||||
WARN_ON(desc->bus_format != MEDIA_BUS_FMT_RGB666_1X7X3_SPWG &&
|
||||
desc->bus_format != MEDIA_BUS_FMT_RGB888_1X7X4_SPWG &&
|
||||
desc->bus_format != MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA);
|
||||
WARN_ON(desc->bus_format == MEDIA_BUS_FMT_RGB666_1X7X3_SPWG &&
|
||||
desc->bpc != 6);
|
||||
WARN_ON((desc->bus_format == MEDIA_BUS_FMT_RGB888_1X7X4_SPWG ||
|
||||
desc->bus_format == MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA) &&
|
||||
desc->bpc != 8);
|
||||
break;
|
||||
case DRM_MODE_CONNECTOR_eDP:
|
||||
dev_warn(dev, "eDP panels moved to panel-edp\n");
|
||||
err = -EINVAL;
|
||||
goto free_ddc;
|
||||
case DRM_MODE_CONNECTOR_DSI:
|
||||
if (desc->bpc != 6 && desc->bpc != 8)
|
||||
dev_warn(dev, "Expected bpc in {6,8} but got: %u\n", desc->bpc);
|
||||
break;
|
||||
case DRM_MODE_CONNECTOR_DPI:
|
||||
bus_flags = DRM_BUS_FLAG_DE_LOW |
|
||||
DRM_BUS_FLAG_DE_HIGH |
|
||||
DRM_BUS_FLAG_PIXDATA_SAMPLE_POSEDGE |
|
||||
DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE |
|
||||
DRM_BUS_FLAG_DATA_MSB_TO_LSB |
|
||||
DRM_BUS_FLAG_DATA_LSB_TO_MSB |
|
||||
DRM_BUS_FLAG_SYNC_SAMPLE_POSEDGE |
|
||||
DRM_BUS_FLAG_SYNC_SAMPLE_NEGEDGE;
|
||||
if (desc->bus_flags & ~bus_flags)
|
||||
dev_warn(dev, "Unexpected bus_flags(%d)\n", desc->bus_flags & ~bus_flags);
|
||||
if (!(desc->bus_flags & bus_flags))
|
||||
dev_warn(dev, "Specify missing bus_flags\n");
|
||||
if (desc->bus_format == 0)
|
||||
dev_warn(dev, "Specify missing bus_format\n");
|
||||
if (desc->bpc != 6 && desc->bpc != 8)
|
||||
dev_warn(dev, "Expected bpc in {6,8} but got: %u\n", desc->bpc);
|
||||
break;
|
||||
default:
|
||||
dev_warn(dev, "Specify a valid connector_type: %d\n", desc->connector_type);
|
||||
connector_type = DRM_MODE_CONNECTOR_DPI;
|
||||
break;
|
||||
}
|
||||
|
||||
dev_set_drvdata(dev, panel);
|
||||
|
||||
/*
|
||||
@@ -1900,6 +1899,7 @@ static const struct panel_desc dataimage_scf0700c48ggu18 = {
|
||||
},
|
||||
.bus_format = MEDIA_BUS_FMT_RGB888_1X24,
|
||||
.bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE,
|
||||
.connector_type = DRM_MODE_CONNECTOR_DPI,
|
||||
};
|
||||
|
||||
static const struct display_timing dlc_dlc0700yzg_1_timing = {
|
||||
|
||||
@@ -1252,17 +1252,7 @@ static int panthor_vm_prepare_map_op_ctx(struct panthor_vm_op_ctx *op_ctx,
|
||||
goto err_cleanup;
|
||||
}
|
||||
|
||||
/* drm_gpuvm_bo_obtain_prealloc() will call drm_gpuvm_bo_put() on our
|
||||
* pre-allocated BO if the <BO,VM> association exists. Given we
|
||||
* only have one ref on preallocated_vm_bo, drm_gpuvm_bo_destroy() will
|
||||
* be called immediately, and we have to hold the VM resv lock when
|
||||
* calling this function.
|
||||
*/
|
||||
dma_resv_lock(panthor_vm_resv(vm), NULL);
|
||||
mutex_lock(&bo->base.base.gpuva.lock);
|
||||
op_ctx->map.vm_bo = drm_gpuvm_bo_obtain_prealloc(preallocated_vm_bo);
|
||||
mutex_unlock(&bo->base.base.gpuva.lock);
|
||||
dma_resv_unlock(panthor_vm_resv(vm));
|
||||
|
||||
op_ctx->map.bo_offset = offset;
|
||||
|
||||
|
||||
@@ -121,7 +121,7 @@ static void dw_hdmi_qp_rockchip_encoder_enable(struct drm_encoder *encoder)
|
||||
struct drm_crtc *crtc = encoder->crtc;
|
||||
|
||||
/* Unconditionally switch to TMDS as FRL is not yet supported */
|
||||
gpiod_set_value(hdmi->frl_enable_gpio, 0);
|
||||
gpiod_set_value_cansleep(hdmi->frl_enable_gpio, 0);
|
||||
|
||||
if (!crtc || !crtc->state)
|
||||
return;
|
||||
@@ -640,6 +640,15 @@ static void dw_hdmi_qp_rockchip_remove(struct platform_device *pdev)
|
||||
component_del(&pdev->dev, &dw_hdmi_qp_rockchip_ops);
|
||||
}
|
||||
|
||||
static int __maybe_unused dw_hdmi_qp_rockchip_suspend(struct device *dev)
|
||||
{
|
||||
struct rockchip_hdmi_qp *hdmi = dev_get_drvdata(dev);
|
||||
|
||||
dw_hdmi_qp_suspend(dev, hdmi->hdmi);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __maybe_unused dw_hdmi_qp_rockchip_resume(struct device *dev)
|
||||
{
|
||||
struct rockchip_hdmi_qp *hdmi = dev_get_drvdata(dev);
|
||||
@@ -655,7 +664,8 @@ static int __maybe_unused dw_hdmi_qp_rockchip_resume(struct device *dev)
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops dw_hdmi_qp_rockchip_pm = {
|
||||
SET_SYSTEM_SLEEP_PM_OPS(NULL, dw_hdmi_qp_rockchip_resume)
|
||||
SET_SYSTEM_SLEEP_PM_OPS(dw_hdmi_qp_rockchip_suspend,
|
||||
dw_hdmi_qp_rockchip_resume)
|
||||
};
|
||||
|
||||
struct platform_driver dw_hdmi_qp_rockchip_pltfm_driver = {
|
||||
|
||||
@@ -2104,7 +2104,7 @@ static void rk3568_vop2_wait_for_port_mux_done(struct vop2 *vop2)
|
||||
* Spin until the previous port_mux figuration is done.
|
||||
*/
|
||||
ret = readx_poll_timeout_atomic(rk3568_vop2_read_port_mux, vop2, port_mux_sel,
|
||||
port_mux_sel == vop2->old_port_sel, 0, 50 * 1000);
|
||||
port_mux_sel == vop2->old_port_sel, 10, 50 * 1000);
|
||||
if (ret)
|
||||
DRM_DEV_ERROR(vop2->dev, "wait port_mux done timeout: 0x%x--0x%x\n",
|
||||
port_mux_sel, vop2->old_port_sel);
|
||||
@@ -2124,7 +2124,7 @@ static void rk3568_vop2_wait_for_layer_cfg_done(struct vop2 *vop2, u32 cfg)
|
||||
* Spin until the previous layer configuration is done.
|
||||
*/
|
||||
ret = readx_poll_timeout_atomic(rk3568_vop2_read_layer_cfg, vop2, atv_layer_cfg,
|
||||
atv_layer_cfg == cfg, 0, 50 * 1000);
|
||||
atv_layer_cfg == cfg, 10, 50 * 1000);
|
||||
if (ret)
|
||||
DRM_DEV_ERROR(vop2->dev, "wait layer cfg done timeout: 0x%x--0x%x\n",
|
||||
atv_layer_cfg, cfg);
|
||||
@@ -2144,6 +2144,7 @@ static void rk3568_vop2_setup_layer_mixer(struct vop2_video_port *vp)
|
||||
u8 layer_sel_id;
|
||||
unsigned int ofs;
|
||||
u32 ovl_ctrl;
|
||||
u32 cfg_done;
|
||||
int i;
|
||||
struct vop2_video_port *vp0 = &vop2->vps[0];
|
||||
struct vop2_video_port *vp1 = &vop2->vps[1];
|
||||
@@ -2298,8 +2299,16 @@ static void rk3568_vop2_setup_layer_mixer(struct vop2_video_port *vp)
|
||||
rk3568_vop2_wait_for_port_mux_done(vop2);
|
||||
}
|
||||
|
||||
if (layer_sel != old_layer_sel && atv_layer_sel != old_layer_sel)
|
||||
rk3568_vop2_wait_for_layer_cfg_done(vop2, vop2->old_layer_sel);
|
||||
if (layer_sel != old_layer_sel && atv_layer_sel != old_layer_sel) {
|
||||
cfg_done = vop2_readl(vop2, RK3568_REG_CFG_DONE);
|
||||
cfg_done &= (BIT(vop2->data->nr_vps) - 1);
|
||||
cfg_done &= ~BIT(vp->id);
|
||||
/*
|
||||
* Changes of other VPs' overlays have not taken effect
|
||||
*/
|
||||
if (cfg_done)
|
||||
rk3568_vop2_wait_for_layer_cfg_done(vop2, vop2->old_layer_sel);
|
||||
}
|
||||
|
||||
vop2_writel(vop2, RK3568_OVL_LAYER_SEL, layer_sel);
|
||||
mutex_unlock(&vop2->ovl_lock);
|
||||
|
||||
@@ -54,15 +54,6 @@ const struct drm_format_info *drm_sysfb_get_format_si(struct drm_device *dev,
|
||||
const struct screen_info *si);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Input parsing
|
||||
*/
|
||||
|
||||
int drm_sysfb_get_validated_int(struct drm_device *dev, const char *name,
|
||||
u64 value, u32 max);
|
||||
int drm_sysfb_get_validated_int0(struct drm_device *dev, const char *name,
|
||||
u64 value, u32 max);
|
||||
|
||||
/*
|
||||
* Display modes
|
||||
*/
|
||||
|
||||
@@ -32,9 +32,15 @@
|
||||
|
||||
#include <drm/ttm/ttm_placement.h>
|
||||
|
||||
static void vmw_bo_release(struct vmw_bo *vbo)
|
||||
/**
|
||||
* vmw_bo_free - vmw_bo destructor
|
||||
*
|
||||
* @bo: Pointer to the embedded struct ttm_buffer_object
|
||||
*/
|
||||
static void vmw_bo_free(struct ttm_buffer_object *bo)
|
||||
{
|
||||
struct vmw_resource *res;
|
||||
struct vmw_bo *vbo = to_vmw_bo(&bo->base);
|
||||
|
||||
WARN_ON(kref_read(&vbo->tbo.base.refcount) != 0);
|
||||
vmw_bo_unmap(vbo);
|
||||
@@ -62,20 +68,8 @@ static void vmw_bo_release(struct vmw_bo *vbo)
|
||||
}
|
||||
vmw_surface_unreference(&vbo->dumb_surface);
|
||||
}
|
||||
drm_gem_object_release(&vbo->tbo.base);
|
||||
}
|
||||
|
||||
/**
|
||||
* vmw_bo_free - vmw_bo destructor
|
||||
*
|
||||
* @bo: Pointer to the embedded struct ttm_buffer_object
|
||||
*/
|
||||
static void vmw_bo_free(struct ttm_buffer_object *bo)
|
||||
{
|
||||
struct vmw_bo *vbo = to_vmw_bo(&bo->base);
|
||||
|
||||
WARN_ON(!RB_EMPTY_ROOT(&vbo->res_tree));
|
||||
vmw_bo_release(vbo);
|
||||
drm_gem_object_release(&vbo->tbo.base);
|
||||
WARN_ON(vbo->dirty);
|
||||
kfree(vbo);
|
||||
}
|
||||
|
||||
@@ -515,12 +515,12 @@ int vmw_fence_obj_unref_ioctl(struct drm_device *dev, void *data,
|
||||
/**
|
||||
* vmw_event_fence_action_seq_passed
|
||||
*
|
||||
* @action: The struct vmw_fence_action embedded in a struct
|
||||
* vmw_event_fence_action.
|
||||
* @f: The struct dma_fence which provides timestamp for the action event
|
||||
* @cb: The struct dma_fence_cb callback for the action event.
|
||||
*
|
||||
* This function is called when the seqno of the fence where @action is
|
||||
* attached has passed. It queues the event on the submitter's event list.
|
||||
* This function is always called from atomic context.
|
||||
* This function is called when the seqno of the fence has passed
|
||||
* and it is always called from atomic context.
|
||||
* It queues the event on the submitter's event list.
|
||||
*/
|
||||
static void vmw_event_fence_action_seq_passed(struct dma_fence *f,
|
||||
struct dma_fence_cb *cb)
|
||||
|
||||
@@ -766,13 +766,15 @@ err_out:
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
ttm_bo_reserve(&bo->tbo, false, false, NULL);
|
||||
ret = vmw_bo_dirty_add(bo);
|
||||
if (!ret && surface && surface->res.func->dirty_alloc) {
|
||||
surface->res.coherent = true;
|
||||
ret = surface->res.func->dirty_alloc(&surface->res);
|
||||
if (bo) {
|
||||
ttm_bo_reserve(&bo->tbo, false, false, NULL);
|
||||
ret = vmw_bo_dirty_add(bo);
|
||||
if (!ret && surface && surface->res.func->dirty_alloc) {
|
||||
surface->res.coherent = true;
|
||||
ret = surface->res.func->dirty_alloc(&surface->res);
|
||||
}
|
||||
ttm_bo_unreserve(&bo->tbo);
|
||||
}
|
||||
ttm_bo_unreserve(&bo->tbo);
|
||||
|
||||
return &vfb->base;
|
||||
}
|
||||
|
||||
@@ -923,8 +923,10 @@ int vmw_compat_shader_add(struct vmw_private *dev_priv,
|
||||
ttm_bo_unreserve(&buf->tbo);
|
||||
|
||||
res = vmw_shader_alloc(dev_priv, buf, size, 0, shader_type);
|
||||
if (unlikely(ret != 0))
|
||||
if (IS_ERR(res)) {
|
||||
ret = PTR_ERR(res);
|
||||
goto no_reserve;
|
||||
}
|
||||
|
||||
ret = vmw_cmdbuf_res_add(man, vmw_cmdbuf_res_shader,
|
||||
vmw_shader_key(user_key, shader_type),
|
||||
|
||||
@@ -1704,6 +1704,7 @@ static const struct apple_nvme_hw apple_nvme_t8103_hw = {
|
||||
|
||||
static const struct of_device_id apple_nvme_of_match[] = {
|
||||
{ .compatible = "apple,t8015-nvme-ans2", .data = &apple_nvme_t8015_hw },
|
||||
{ .compatible = "apple,t8103-nvme-ans2", .data = &apple_nvme_t8103_hw },
|
||||
{ .compatible = "apple,nvme-ans2", .data = &apple_nvme_t8103_hw },
|
||||
{},
|
||||
};
|
||||
|
||||
@@ -3587,6 +3587,8 @@ fail_ctrl:
|
||||
|
||||
ctrl->ctrl.opts = NULL;
|
||||
|
||||
if (ctrl->ctrl.admin_tagset)
|
||||
nvme_remove_admin_tag_set(&ctrl->ctrl);
|
||||
/* initiate nvme ctrl ref counting teardown */
|
||||
nvme_uninit_ctrl(&ctrl->ctrl);
|
||||
|
||||
|
||||
@@ -1532,7 +1532,10 @@ static int nvme_pci_subsystem_reset(struct nvme_ctrl *ctrl)
|
||||
}
|
||||
|
||||
writel(NVME_SUBSYS_RESET, dev->bar + NVME_REG_NSSR);
|
||||
nvme_change_ctrl_state(ctrl, NVME_CTRL_LIVE);
|
||||
|
||||
if (!nvme_change_ctrl_state(ctrl, NVME_CTRL_CONNECTING) ||
|
||||
!nvme_change_ctrl_state(ctrl, NVME_CTRL_LIVE))
|
||||
goto unlock;
|
||||
|
||||
/*
|
||||
* Read controller status to flush the previous write and trigger a
|
||||
@@ -3999,6 +4002,8 @@ static const struct pci_device_id nvme_id_table[] = {
|
||||
.driver_data = NVME_QUIRK_NO_DEEPEST_PS, },
|
||||
{ PCI_DEVICE(0x1e49, 0x0041), /* ZHITAI TiPro7000 NVMe SSD */
|
||||
.driver_data = NVME_QUIRK_NO_DEEPEST_PS, },
|
||||
{ PCI_DEVICE(0x1fa0, 0x2283), /* Wodposit WPBSNM8-256GTP */
|
||||
.driver_data = NVME_QUIRK_NO_SECONDARY_TEMP_THRESH, },
|
||||
{ PCI_DEVICE(0x025e, 0xf1ac), /* SOLIDIGM P44 pro SSDPFKKW020X7 */
|
||||
.driver_data = NVME_QUIRK_NO_DEEPEST_PS, },
|
||||
{ PCI_DEVICE(0xc0a9, 0x540a), /* Crucial P2 */
|
||||
|
||||
@@ -150,7 +150,7 @@ static u16 nvmet_passthru_override_id_ctrl(struct nvmet_req *req)
|
||||
* code path with duplicate ctrl subsysnqn. In order to prevent that we
|
||||
* mask the passthru-ctrl subsysnqn with the target ctrl subsysnqn.
|
||||
*/
|
||||
memcpy(id->subnqn, ctrl->subsys->subsysnqn, sizeof(id->subnqn));
|
||||
strscpy(id->subnqn, ctrl->subsys->subsysnqn, sizeof(id->subnqn));
|
||||
|
||||
/* use fabric id-ctrl values */
|
||||
id->ioccsz = cpu_to_le32((sizeof(struct nvme_command) +
|
||||
|
||||
@@ -982,6 +982,18 @@ static int nvmet_tcp_handle_h2c_data_pdu(struct nvmet_tcp_queue *queue)
|
||||
pr_err("H2CData PDU len %u is invalid\n", cmd->pdu_len);
|
||||
goto err_proto;
|
||||
}
|
||||
/*
|
||||
* Ensure command data structures are initialized. We must check both
|
||||
* cmd->req.sg and cmd->iov because they can have different NULL states:
|
||||
* - Uninitialized commands: both NULL
|
||||
* - READ commands: cmd->req.sg allocated, cmd->iov NULL
|
||||
* - WRITE commands: both allocated
|
||||
*/
|
||||
if (unlikely(!cmd->req.sg || !cmd->iov)) {
|
||||
pr_err("queue %d: H2CData PDU received for invalid command state (ttag %u)\n",
|
||||
queue->idx, data->ttag);
|
||||
goto err_proto;
|
||||
}
|
||||
cmd->pdu_recv = 0;
|
||||
nvmet_tcp_build_pdu_iovec(cmd);
|
||||
queue->cmd = cmd;
|
||||
@@ -1992,14 +2004,13 @@ static void nvmet_tcp_listen_data_ready(struct sock *sk)
|
||||
|
||||
trace_sk_data_ready(sk);
|
||||
|
||||
if (sk->sk_state != TCP_LISTEN)
|
||||
return;
|
||||
|
||||
read_lock_bh(&sk->sk_callback_lock);
|
||||
port = sk->sk_user_data;
|
||||
if (!port)
|
||||
goto out;
|
||||
|
||||
if (sk->sk_state == TCP_LISTEN)
|
||||
if (port)
|
||||
queue_work(nvmet_wq, &port->accept_work);
|
||||
out:
|
||||
read_unlock_bh(&sk->sk_callback_lock);
|
||||
}
|
||||
|
||||
|
||||
@@ -225,12 +225,6 @@ config PCI_P2PDMA
|
||||
P2P DMA transactions must be between devices behind the same root
|
||||
port.
|
||||
|
||||
Enabling this option will reduce the entropy of x86 KASLR memory
|
||||
regions. For example - on a 46 bit system, the entropy goes down
|
||||
from 16 bits to 15 bits. The actual reduction in entropy depends
|
||||
on the physical address bits, on processor features, kernel config
|
||||
(5 level page table) and physical memory present on the system.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
config PCI_LABEL
|
||||
|
||||
@@ -23,6 +23,7 @@ const struct device_type sdw_slave_type = {
|
||||
.release = sdw_slave_release,
|
||||
.uevent = sdw_slave_uevent,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(sdw_slave_type);
|
||||
|
||||
int sdw_slave_add(struct sdw_bus *bus,
|
||||
struct sdw_slave_id *id, struct fwnode_handle *fwnode)
|
||||
|
||||
@@ -848,15 +848,16 @@ sparse_alloc:
|
||||
* invalid inode records, such as records that start at agbno 0
|
||||
* or extend beyond the AG.
|
||||
*
|
||||
* Set min agbno to the first aligned, non-zero agbno and max to
|
||||
* the last aligned agbno that is at least one full chunk from
|
||||
* the end of the AG.
|
||||
* Set min agbno to the first chunk aligned, non-zero agbno and
|
||||
* max to one less than the last chunk aligned agbno from the
|
||||
* end of the AG. We subtract 1 from max so that the cluster
|
||||
* allocation alignment takes over and allows allocation within
|
||||
* the last full inode chunk in the AG.
|
||||
*/
|
||||
args.min_agbno = args.mp->m_sb.sb_inoalignmt;
|
||||
args.max_agbno = round_down(xfs_ag_block_count(args.mp,
|
||||
pag_agno(pag)),
|
||||
args.mp->m_sb.sb_inoalignmt) -
|
||||
igeo->ialloc_blks;
|
||||
args.mp->m_sb.sb_inoalignmt) - 1;
|
||||
|
||||
error = xfs_alloc_vextent_near_bno(&args,
|
||||
xfs_agbno_to_fsb(pag,
|
||||
|
||||
+27
-26
@@ -48,6 +48,31 @@ xfs_rtgroup_min_block(
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Compute the number of rt extents in this realtime group. */
|
||||
static xfs_rtxnum_t
|
||||
__xfs_rtgroup_extents(
|
||||
struct xfs_mount *mp,
|
||||
xfs_rgnumber_t rgno,
|
||||
xfs_rgnumber_t rgcount,
|
||||
xfs_rtbxlen_t rextents)
|
||||
{
|
||||
ASSERT(rgno < rgcount);
|
||||
if (rgno == rgcount - 1)
|
||||
return rextents - ((xfs_rtxnum_t)rgno * mp->m_sb.sb_rgextents);
|
||||
|
||||
ASSERT(xfs_has_rtgroups(mp));
|
||||
return mp->m_sb.sb_rgextents;
|
||||
}
|
||||
|
||||
xfs_rtxnum_t
|
||||
xfs_rtgroup_extents(
|
||||
struct xfs_mount *mp,
|
||||
xfs_rgnumber_t rgno)
|
||||
{
|
||||
return __xfs_rtgroup_extents(mp, rgno, mp->m_sb.sb_rgcount,
|
||||
mp->m_sb.sb_rextents);
|
||||
}
|
||||
|
||||
/* Precompute this group's geometry */
|
||||
void
|
||||
xfs_rtgroup_calc_geometry(
|
||||
@@ -58,7 +83,8 @@ xfs_rtgroup_calc_geometry(
|
||||
xfs_rtbxlen_t rextents)
|
||||
{
|
||||
rtg->rtg_extents = __xfs_rtgroup_extents(mp, rgno, rgcount, rextents);
|
||||
rtg_group(rtg)->xg_block_count = rtg->rtg_extents * mp->m_sb.sb_rextsize;
|
||||
rtg_group(rtg)->xg_block_count =
|
||||
rtg->rtg_extents * mp->m_sb.sb_rextsize;
|
||||
rtg_group(rtg)->xg_min_gbno = xfs_rtgroup_min_block(mp, rgno);
|
||||
}
|
||||
|
||||
@@ -136,31 +162,6 @@ out_unwind_new_rtgs:
|
||||
return error;
|
||||
}
|
||||
|
||||
/* Compute the number of rt extents in this realtime group. */
|
||||
xfs_rtxnum_t
|
||||
__xfs_rtgroup_extents(
|
||||
struct xfs_mount *mp,
|
||||
xfs_rgnumber_t rgno,
|
||||
xfs_rgnumber_t rgcount,
|
||||
xfs_rtbxlen_t rextents)
|
||||
{
|
||||
ASSERT(rgno < rgcount);
|
||||
if (rgno == rgcount - 1)
|
||||
return rextents - ((xfs_rtxnum_t)rgno * mp->m_sb.sb_rgextents);
|
||||
|
||||
ASSERT(xfs_has_rtgroups(mp));
|
||||
return mp->m_sb.sb_rgextents;
|
||||
}
|
||||
|
||||
xfs_rtxnum_t
|
||||
xfs_rtgroup_extents(
|
||||
struct xfs_mount *mp,
|
||||
xfs_rgnumber_t rgno)
|
||||
{
|
||||
return __xfs_rtgroup_extents(mp, rgno, mp->m_sb.sb_rgcount,
|
||||
mp->m_sb.sb_rextents);
|
||||
}
|
||||
|
||||
/*
|
||||
* Update the rt extent count of the previous tail rtgroup if it changed during
|
||||
* recovery (i.e. recovery of a growfs).
|
||||
|
||||
@@ -285,8 +285,6 @@ void xfs_free_rtgroups(struct xfs_mount *mp, xfs_rgnumber_t first_rgno,
|
||||
int xfs_initialize_rtgroups(struct xfs_mount *mp, xfs_rgnumber_t first_rgno,
|
||||
xfs_rgnumber_t end_rgno, xfs_rtbxlen_t rextents);
|
||||
|
||||
xfs_rtxnum_t __xfs_rtgroup_extents(struct xfs_mount *mp, xfs_rgnumber_t rgno,
|
||||
xfs_rgnumber_t rgcount, xfs_rtbxlen_t rextents);
|
||||
xfs_rtxnum_t xfs_rtgroup_extents(struct xfs_mount *mp, xfs_rgnumber_t rgno);
|
||||
void xfs_rtgroup_calc_geometry(struct xfs_mount *mp, struct xfs_rtgroup *rtg,
|
||||
xfs_rgnumber_t rgno, xfs_rgnumber_t rgcount,
|
||||
|
||||
+5
-3
@@ -1180,9 +1180,11 @@ xfs_log_cover(
|
||||
int error = 0;
|
||||
bool need_covered;
|
||||
|
||||
ASSERT((xlog_cil_empty(mp->m_log) && xlog_iclogs_empty(mp->m_log) &&
|
||||
!xfs_ail_min_lsn(mp->m_log->l_ailp)) ||
|
||||
xlog_is_shutdown(mp->m_log));
|
||||
if (!xlog_is_shutdown(mp->m_log)) {
|
||||
ASSERT(xlog_cil_empty(mp->m_log));
|
||||
ASSERT(xlog_iclogs_empty(mp->m_log));
|
||||
ASSERT(!xfs_ail_min_lsn(mp->m_log->l_ailp));
|
||||
}
|
||||
|
||||
if (!xfs_log_writable(mp))
|
||||
return 0;
|
||||
|
||||
@@ -126,7 +126,7 @@ xfs_rtcopy_summary(
|
||||
error = 0;
|
||||
out:
|
||||
xfs_rtbuf_cache_relse(oargs);
|
||||
return 0;
|
||||
return error;
|
||||
}
|
||||
/*
|
||||
* Mark an extent specified by start and len allocated.
|
||||
@@ -1265,7 +1265,7 @@ xfs_growfs_check_rtgeom(
|
||||
uint32_t rem;
|
||||
|
||||
if (rextsize != 1)
|
||||
return -EINVAL;
|
||||
goto out_inval;
|
||||
div_u64_rem(nmp->m_sb.sb_rblocks, gblocks, &rem);
|
||||
if (rem) {
|
||||
xfs_warn(mp,
|
||||
@@ -1326,7 +1326,7 @@ xfs_grow_last_rtg(
|
||||
return true;
|
||||
if (mp->m_sb.sb_rgcount == 0)
|
||||
return false;
|
||||
return xfs_rtgroup_extents(mp, mp->m_sb.sb_rgcount - 1) <=
|
||||
return xfs_rtgroup_extents(mp, mp->m_sb.sb_rgcount - 1) <
|
||||
mp->m_sb.sb_rgextents;
|
||||
}
|
||||
|
||||
|
||||
@@ -34,5 +34,6 @@ struct dw_hdmi_qp_plat_data {
|
||||
struct dw_hdmi_qp *dw_hdmi_qp_bind(struct platform_device *pdev,
|
||||
struct drm_encoder *encoder,
|
||||
const struct dw_hdmi_qp_plat_data *plat_data);
|
||||
void dw_hdmi_qp_suspend(struct device *dev, struct dw_hdmi_qp *hdmi);
|
||||
void dw_hdmi_qp_resume(struct device *dev, struct dw_hdmi_qp *hdmi);
|
||||
#endif /* __DW_HDMI_QP__ */
|
||||
@@ -551,6 +551,22 @@ ssize_t drm_dp_dpcd_read(struct drm_dp_aux *aux, unsigned int offset,
|
||||
ssize_t drm_dp_dpcd_write(struct drm_dp_aux *aux, unsigned int offset,
|
||||
void *buffer, size_t size);
|
||||
|
||||
/**
|
||||
* drm_dp_dpcd_readb() - read a single byte from the DPCD
|
||||
* @aux: DisplayPort AUX channel
|
||||
* @offset: address of the register to read
|
||||
* @valuep: location where the value of the register will be stored
|
||||
*
|
||||
* Returns the number of bytes transferred (1) on success, or a negative
|
||||
* error code on failure. In most of the cases you should be using
|
||||
* drm_dp_dpcd_read_byte() instead.
|
||||
*/
|
||||
static inline ssize_t drm_dp_dpcd_readb(struct drm_dp_aux *aux,
|
||||
unsigned int offset, u8 *valuep)
|
||||
{
|
||||
return drm_dp_dpcd_read(aux, offset, valuep, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* drm_dp_dpcd_read_data() - read a series of bytes from the DPCD
|
||||
* @aux: DisplayPort AUX channel (SST or MST)
|
||||
@@ -570,12 +586,29 @@ static inline int drm_dp_dpcd_read_data(struct drm_dp_aux *aux,
|
||||
void *buffer, size_t size)
|
||||
{
|
||||
int ret;
|
||||
size_t i;
|
||||
u8 *buf = buffer;
|
||||
|
||||
ret = drm_dp_dpcd_read(aux, offset, buffer, size);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (ret < size)
|
||||
return -EPROTO;
|
||||
if (ret >= 0) {
|
||||
if (ret < size)
|
||||
return -EPROTO;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Workaround for USB-C hubs/adapters with buggy firmware that fail
|
||||
* multi-byte AUX reads but work with single-byte reads.
|
||||
* Known affected devices:
|
||||
* - Lenovo USB-C to VGA adapter (VIA VL817, idVendor=17ef, idProduct=7217)
|
||||
* - Dell DA310 USB-C hub (idVendor=413c, idProduct=c010)
|
||||
* Attempt byte-by-byte reading as a fallback.
|
||||
*/
|
||||
for (i = 0; i < size; i++) {
|
||||
ret = drm_dp_dpcd_readb(aux, offset + i, &buf[i]);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -609,22 +642,6 @@ static inline int drm_dp_dpcd_write_data(struct drm_dp_aux *aux,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* drm_dp_dpcd_readb() - read a single byte from the DPCD
|
||||
* @aux: DisplayPort AUX channel
|
||||
* @offset: address of the register to read
|
||||
* @valuep: location where the value of the register will be stored
|
||||
*
|
||||
* Returns the number of bytes transferred (1) on success, or a negative
|
||||
* error code on failure. In most of the cases you should be using
|
||||
* drm_dp_dpcd_read_byte() instead.
|
||||
*/
|
||||
static inline ssize_t drm_dp_dpcd_readb(struct drm_dp_aux *aux,
|
||||
unsigned int offset, u8 *valuep)
|
||||
{
|
||||
return drm_dp_dpcd_read(aux, offset, valuep, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* drm_dp_dpcd_writeb() - write a single byte to the DPCD
|
||||
* @aux: DisplayPort AUX channel
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
* @power: The power consumed at this level (by 1 CPU or by a registered
|
||||
* device). It can be a total power: static and dynamic.
|
||||
* @cost: The cost coefficient associated with this level, used during
|
||||
* energy calculation. Equal to: power * max_frequency / frequency
|
||||
* energy calculation. Equal to: 10 * power * max_frequency / frequency
|
||||
* @flags: see "em_perf_state flags" description below.
|
||||
*/
|
||||
struct em_perf_state {
|
||||
|
||||
@@ -2210,6 +2210,10 @@ pci_alloc_irq_vectors(struct pci_dev *dev, unsigned int min_vecs,
|
||||
{
|
||||
return -ENOSPC;
|
||||
}
|
||||
|
||||
static inline void pci_free_irq_vectors(struct pci_dev *dev)
|
||||
{
|
||||
}
|
||||
#endif /* CONFIG_PCI */
|
||||
|
||||
/* Include architecture-dependent settings and functions */
|
||||
|
||||
+1
-1
@@ -1402,7 +1402,7 @@ int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream, struct vm_area_s
|
||||
#define snd_pcm_lib_mmap_iomem NULL
|
||||
#endif
|
||||
|
||||
void snd_pcm_runtime_buffer_set_silence(struct snd_pcm_runtime *runtime);
|
||||
int snd_pcm_runtime_buffer_set_silence(struct snd_pcm_runtime *runtime);
|
||||
|
||||
/**
|
||||
* snd_pcm_limit_isa_dma_size - Get the max size fitting with ISA DMA transfer
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */
|
||||
/* Do not edit directly, auto-generated from: */
|
||||
/* Documentation/netlink/specs/dev-energymodel.yaml */
|
||||
/* YNL-GEN uapi header */
|
||||
/* To regenerate run: tools/net/ynl/ynl-regen.sh */
|
||||
|
||||
#ifndef _UAPI_LINUX_DEV_ENERGYMODEL_H
|
||||
#define _UAPI_LINUX_DEV_ENERGYMODEL_H
|
||||
|
||||
#define DEV_ENERGYMODEL_FAMILY_NAME "dev-energymodel"
|
||||
#define DEV_ENERGYMODEL_FAMILY_VERSION 1
|
||||
|
||||
/**
|
||||
* enum dev_energymodel_perf_state_flags
|
||||
* @DEV_ENERGYMODEL_PERF_STATE_FLAGS_PERF_STATE_INEFFICIENT: The performance
|
||||
* state is inefficient. There is in this perf-domain, another performance
|
||||
* state with a higher frequency but a lower or equal power cost.
|
||||
*/
|
||||
enum dev_energymodel_perf_state_flags {
|
||||
DEV_ENERGYMODEL_PERF_STATE_FLAGS_PERF_STATE_INEFFICIENT = 1,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum dev_energymodel_perf_domain_flags
|
||||
* @DEV_ENERGYMODEL_PERF_DOMAIN_FLAGS_PERF_DOMAIN_MICROWATTS: The power values
|
||||
* are in micro-Watts or some other scale.
|
||||
* @DEV_ENERGYMODEL_PERF_DOMAIN_FLAGS_PERF_DOMAIN_SKIP_INEFFICIENCIES: Skip
|
||||
* inefficient states when estimating energy consumption.
|
||||
* @DEV_ENERGYMODEL_PERF_DOMAIN_FLAGS_PERF_DOMAIN_ARTIFICIAL: The power values
|
||||
* are artificial and might be created by platform missing real power
|
||||
* information.
|
||||
*/
|
||||
enum dev_energymodel_perf_domain_flags {
|
||||
DEV_ENERGYMODEL_PERF_DOMAIN_FLAGS_PERF_DOMAIN_MICROWATTS = 1,
|
||||
DEV_ENERGYMODEL_PERF_DOMAIN_FLAGS_PERF_DOMAIN_SKIP_INEFFICIENCIES = 2,
|
||||
DEV_ENERGYMODEL_PERF_DOMAIN_FLAGS_PERF_DOMAIN_ARTIFICIAL = 4,
|
||||
};
|
||||
|
||||
enum {
|
||||
DEV_ENERGYMODEL_A_PERF_DOMAIN_PAD = 1,
|
||||
DEV_ENERGYMODEL_A_PERF_DOMAIN_PERF_DOMAIN_ID,
|
||||
DEV_ENERGYMODEL_A_PERF_DOMAIN_FLAGS,
|
||||
DEV_ENERGYMODEL_A_PERF_DOMAIN_CPUS,
|
||||
|
||||
__DEV_ENERGYMODEL_A_PERF_DOMAIN_MAX,
|
||||
DEV_ENERGYMODEL_A_PERF_DOMAIN_MAX = (__DEV_ENERGYMODEL_A_PERF_DOMAIN_MAX - 1)
|
||||
};
|
||||
|
||||
enum {
|
||||
DEV_ENERGYMODEL_A_PERF_TABLE_PERF_DOMAIN_ID = 1,
|
||||
DEV_ENERGYMODEL_A_PERF_TABLE_PERF_STATE,
|
||||
|
||||
__DEV_ENERGYMODEL_A_PERF_TABLE_MAX,
|
||||
DEV_ENERGYMODEL_A_PERF_TABLE_MAX = (__DEV_ENERGYMODEL_A_PERF_TABLE_MAX - 1)
|
||||
};
|
||||
|
||||
enum {
|
||||
DEV_ENERGYMODEL_A_PERF_STATE_PAD = 1,
|
||||
DEV_ENERGYMODEL_A_PERF_STATE_PERFORMANCE,
|
||||
DEV_ENERGYMODEL_A_PERF_STATE_FREQUENCY,
|
||||
DEV_ENERGYMODEL_A_PERF_STATE_POWER,
|
||||
DEV_ENERGYMODEL_A_PERF_STATE_COST,
|
||||
DEV_ENERGYMODEL_A_PERF_STATE_FLAGS,
|
||||
|
||||
__DEV_ENERGYMODEL_A_PERF_STATE_MAX,
|
||||
DEV_ENERGYMODEL_A_PERF_STATE_MAX = (__DEV_ENERGYMODEL_A_PERF_STATE_MAX - 1)
|
||||
};
|
||||
|
||||
enum {
|
||||
DEV_ENERGYMODEL_CMD_GET_PERF_DOMAINS = 1,
|
||||
DEV_ENERGYMODEL_CMD_GET_PERF_TABLE,
|
||||
DEV_ENERGYMODEL_CMD_PERF_DOMAIN_CREATED,
|
||||
DEV_ENERGYMODEL_CMD_PERF_DOMAIN_UPDATED,
|
||||
DEV_ENERGYMODEL_CMD_PERF_DOMAIN_DELETED,
|
||||
|
||||
__DEV_ENERGYMODEL_CMD_MAX,
|
||||
DEV_ENERGYMODEL_CMD_MAX = (__DEV_ENERGYMODEL_CMD_MAX - 1)
|
||||
};
|
||||
|
||||
#define DEV_ENERGYMODEL_MCGRP_EVENT "event"
|
||||
|
||||
#endif /* _UAPI_LINUX_DEV_ENERGYMODEL_H */
|
||||
@@ -1,63 +0,0 @@
|
||||
/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */
|
||||
/* Do not edit directly, auto-generated from: */
|
||||
/* Documentation/netlink/specs/em.yaml */
|
||||
/* YNL-GEN uapi header */
|
||||
/* To regenerate run: tools/net/ynl/ynl-regen.sh */
|
||||
|
||||
#ifndef _UAPI_LINUX_ENERGY_MODEL_H
|
||||
#define _UAPI_LINUX_ENERGY_MODEL_H
|
||||
|
||||
#define EM_FAMILY_NAME "em"
|
||||
#define EM_FAMILY_VERSION 1
|
||||
|
||||
enum {
|
||||
EM_A_PDS_PD = 1,
|
||||
|
||||
__EM_A_PDS_MAX,
|
||||
EM_A_PDS_MAX = (__EM_A_PDS_MAX - 1)
|
||||
};
|
||||
|
||||
enum {
|
||||
EM_A_PD_PAD = 1,
|
||||
EM_A_PD_PD_ID,
|
||||
EM_A_PD_FLAGS,
|
||||
EM_A_PD_CPUS,
|
||||
|
||||
__EM_A_PD_MAX,
|
||||
EM_A_PD_MAX = (__EM_A_PD_MAX - 1)
|
||||
};
|
||||
|
||||
enum {
|
||||
EM_A_PD_TABLE_PD_ID = 1,
|
||||
EM_A_PD_TABLE_PS,
|
||||
|
||||
__EM_A_PD_TABLE_MAX,
|
||||
EM_A_PD_TABLE_MAX = (__EM_A_PD_TABLE_MAX - 1)
|
||||
};
|
||||
|
||||
enum {
|
||||
EM_A_PS_PAD = 1,
|
||||
EM_A_PS_PERFORMANCE,
|
||||
EM_A_PS_FREQUENCY,
|
||||
EM_A_PS_POWER,
|
||||
EM_A_PS_COST,
|
||||
EM_A_PS_FLAGS,
|
||||
|
||||
__EM_A_PS_MAX,
|
||||
EM_A_PS_MAX = (__EM_A_PS_MAX - 1)
|
||||
};
|
||||
|
||||
enum {
|
||||
EM_CMD_GET_PDS = 1,
|
||||
EM_CMD_GET_PD_TABLE,
|
||||
EM_CMD_PD_CREATED,
|
||||
EM_CMD_PD_UPDATED,
|
||||
EM_CMD_PD_DELETED,
|
||||
|
||||
__EM_CMD_MAX,
|
||||
EM_CMD_MAX = (__EM_CMD_MAX - 1)
|
||||
};
|
||||
|
||||
#define EM_MCGRP_EVENT "event"
|
||||
|
||||
#endif /* _UAPI_LINUX_ENERGY_MODEL_H */
|
||||
+4
-4
@@ -3003,12 +3003,12 @@ static __cold void io_ring_exit_work(struct work_struct *work)
|
||||
mutex_unlock(&ctx->uring_lock);
|
||||
}
|
||||
|
||||
if (ctx->flags & IORING_SETUP_DEFER_TASKRUN)
|
||||
io_move_task_work_from_local(ctx);
|
||||
|
||||
/* The SQPOLL thread never reaches this path */
|
||||
while (io_uring_try_cancel_requests(ctx, NULL, true, false))
|
||||
do {
|
||||
if (ctx->flags & IORING_SETUP_DEFER_TASKRUN)
|
||||
io_move_task_work_from_local(ctx);
|
||||
cond_resched();
|
||||
} while (io_uring_try_cancel_requests(ctx, NULL, true, false));
|
||||
|
||||
if (ctx->sq_data) {
|
||||
struct io_sq_data *sqd = ctx->sq_data;
|
||||
|
||||
+140
-73
@@ -12,27 +12,35 @@
|
||||
#include <linux/energy_model.h>
|
||||
#include <net/sock.h>
|
||||
#include <net/genetlink.h>
|
||||
#include <uapi/linux/energy_model.h>
|
||||
#include <uapi/linux/dev_energymodel.h>
|
||||
|
||||
#include "em_netlink.h"
|
||||
#include "em_netlink_autogen.h"
|
||||
|
||||
#define EM_A_PD_CPUS_LEN 256
|
||||
|
||||
/*************************** Command encoding ********************************/
|
||||
struct dump_ctx {
|
||||
int idx;
|
||||
int start;
|
||||
struct sk_buff *skb;
|
||||
struct netlink_callback *cb;
|
||||
};
|
||||
|
||||
static int __em_nl_get_pd_size(struct em_perf_domain *pd, void *data)
|
||||
{
|
||||
char cpus_buf[EM_A_PD_CPUS_LEN];
|
||||
int nr_cpus, msg_sz, cpus_sz;
|
||||
int *tot_msg_sz = data;
|
||||
int msg_sz, cpus_sz;
|
||||
|
||||
cpus_sz = snprintf(cpus_buf, sizeof(cpus_buf), "%*pb",
|
||||
cpumask_pr_args(to_cpumask(pd->cpus)));
|
||||
nr_cpus = cpumask_weight(to_cpumask(pd->cpus));
|
||||
cpus_sz = nla_total_size_64bit(sizeof(u64)) * nr_cpus;
|
||||
|
||||
msg_sz = nla_total_size(0) + /* EM_A_PDS_PD */
|
||||
nla_total_size(sizeof(u32)) + /* EM_A_PD_PD_ID */
|
||||
nla_total_size_64bit(sizeof(u64)) + /* EM_A_PD_FLAGS */
|
||||
nla_total_size(cpus_sz); /* EM_A_PD_CPUS */
|
||||
msg_sz = nla_total_size(0) +
|
||||
/* DEV_ENERGYMODEL_A_PERF_DOMAINS_PERF_DOMAIN */
|
||||
nla_total_size(sizeof(u32)) +
|
||||
/* DEV_ENERGYMODEL_A_PERF_DOMAIN_PERF_DOMAIN_ID */
|
||||
nla_total_size_64bit(sizeof(u64)) +
|
||||
/* DEV_ENERGYMODEL_A_PERF_DOMAIN_FLAGS */
|
||||
nla_total_size(cpus_sz);
|
||||
/* DEV_ENERGYMODEL_A_PERF_DOMAIN_CPUS */
|
||||
|
||||
*tot_msg_sz += nlmsg_total_size(genlmsg_msg_size(msg_sz));
|
||||
return 0;
|
||||
@@ -40,56 +48,80 @@ static int __em_nl_get_pd_size(struct em_perf_domain *pd, void *data)
|
||||
|
||||
static int __em_nl_get_pd(struct em_perf_domain *pd, void *data)
|
||||
{
|
||||
char cpus_buf[EM_A_PD_CPUS_LEN];
|
||||
struct sk_buff *msg = data;
|
||||
struct nlattr *entry;
|
||||
struct cpumask *cpumask;
|
||||
int cpu;
|
||||
|
||||
entry = nla_nest_start(msg, EM_A_PDS_PD);
|
||||
if (!entry)
|
||||
if (nla_put_u32(msg, DEV_ENERGYMODEL_A_PERF_DOMAIN_PERF_DOMAIN_ID,
|
||||
pd->id))
|
||||
goto out_cancel_nest;
|
||||
|
||||
if (nla_put_u32(msg, EM_A_PD_PD_ID, pd->id))
|
||||
if (nla_put_u64_64bit(msg, DEV_ENERGYMODEL_A_PERF_DOMAIN_FLAGS,
|
||||
pd->flags, DEV_ENERGYMODEL_A_PERF_DOMAIN_PAD))
|
||||
goto out_cancel_nest;
|
||||
|
||||
if (nla_put_u64_64bit(msg, EM_A_PD_FLAGS, pd->flags, EM_A_PD_PAD))
|
||||
goto out_cancel_nest;
|
||||
|
||||
snprintf(cpus_buf, sizeof(cpus_buf), "%*pb",
|
||||
cpumask_pr_args(to_cpumask(pd->cpus)));
|
||||
if (nla_put_string(msg, EM_A_PD_CPUS, cpus_buf))
|
||||
goto out_cancel_nest;
|
||||
|
||||
nla_nest_end(msg, entry);
|
||||
cpumask = to_cpumask(pd->cpus);
|
||||
for_each_cpu(cpu, cpumask) {
|
||||
if (nla_put_u64_64bit(msg, DEV_ENERGYMODEL_A_PERF_DOMAIN_CPUS,
|
||||
cpu, DEV_ENERGYMODEL_A_PERF_DOMAIN_PAD))
|
||||
goto out_cancel_nest;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
out_cancel_nest:
|
||||
nla_nest_cancel(msg, entry);
|
||||
|
||||
return -EMSGSIZE;
|
||||
}
|
||||
|
||||
int em_nl_get_pds_doit(struct sk_buff *skb, struct genl_info *info)
|
||||
static int __em_nl_get_pd_for_dump(struct em_perf_domain *pd, void *data)
|
||||
{
|
||||
const struct genl_info *info;
|
||||
struct dump_ctx *ctx = data;
|
||||
void *hdr;
|
||||
int ret;
|
||||
|
||||
if (ctx->idx++ < ctx->start)
|
||||
return 0;
|
||||
|
||||
info = genl_info_dump(ctx->cb);
|
||||
hdr = genlmsg_iput(ctx->skb, info);
|
||||
if (!hdr) {
|
||||
genlmsg_cancel(ctx->skb, hdr);
|
||||
return -EMSGSIZE;
|
||||
}
|
||||
|
||||
ret = __em_nl_get_pd(pd, ctx->skb);
|
||||
genlmsg_end(ctx->skb, hdr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int dev_energymodel_nl_get_perf_domains_doit(struct sk_buff *skb,
|
||||
struct genl_info *info)
|
||||
{
|
||||
int id, ret = -EMSGSIZE, msg_sz = 0;
|
||||
int cmd = info->genlhdr->cmd;
|
||||
struct em_perf_domain *pd;
|
||||
struct sk_buff *msg;
|
||||
void *hdr;
|
||||
int cmd = info->genlhdr->cmd;
|
||||
int ret = -EMSGSIZE, msg_sz = 0;
|
||||
|
||||
for_each_em_perf_domain(__em_nl_get_pd_size, &msg_sz);
|
||||
if (!info->attrs[DEV_ENERGYMODEL_A_PERF_DOMAIN_PERF_DOMAIN_ID])
|
||||
return -EINVAL;
|
||||
|
||||
id = nla_get_u32(info->attrs[DEV_ENERGYMODEL_A_PERF_DOMAIN_PERF_DOMAIN_ID]);
|
||||
pd = em_perf_domain_get_by_id(id);
|
||||
|
||||
__em_nl_get_pd_size(pd, &msg_sz);
|
||||
msg = genlmsg_new(msg_sz, GFP_KERNEL);
|
||||
if (!msg)
|
||||
return -ENOMEM;
|
||||
|
||||
hdr = genlmsg_put_reply(msg, info, &em_nl_family, 0, cmd);
|
||||
hdr = genlmsg_put_reply(msg, info, &dev_energymodel_nl_family, 0, cmd);
|
||||
if (!hdr)
|
||||
goto out_free_msg;
|
||||
|
||||
ret = for_each_em_perf_domain(__em_nl_get_pd, msg);
|
||||
ret = __em_nl_get_pd(pd, msg);
|
||||
if (ret)
|
||||
goto out_cancel_msg;
|
||||
|
||||
genlmsg_end(msg, hdr);
|
||||
|
||||
return genlmsg_reply(msg, info);
|
||||
@@ -98,19 +130,31 @@ out_cancel_msg:
|
||||
genlmsg_cancel(msg, hdr);
|
||||
out_free_msg:
|
||||
nlmsg_free(msg);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int dev_energymodel_nl_get_perf_domains_dumpit(struct sk_buff *skb,
|
||||
struct netlink_callback *cb)
|
||||
{
|
||||
struct dump_ctx ctx = {
|
||||
.idx = 0,
|
||||
.start = cb->args[0],
|
||||
.skb = skb,
|
||||
.cb = cb,
|
||||
};
|
||||
|
||||
return for_each_em_perf_domain(__em_nl_get_pd_for_dump, &ctx);
|
||||
}
|
||||
|
||||
static struct em_perf_domain *__em_nl_get_pd_table_id(struct nlattr **attrs)
|
||||
{
|
||||
struct em_perf_domain *pd;
|
||||
int id;
|
||||
|
||||
if (!attrs[EM_A_PD_TABLE_PD_ID])
|
||||
if (!attrs[DEV_ENERGYMODEL_A_PERF_TABLE_PERF_DOMAIN_ID])
|
||||
return NULL;
|
||||
|
||||
id = nla_get_u32(attrs[EM_A_PD_TABLE_PD_ID]);
|
||||
id = nla_get_u32(attrs[DEV_ENERGYMODEL_A_PERF_TABLE_PERF_DOMAIN_ID]);
|
||||
pd = em_perf_domain_get_by_id(id);
|
||||
return pd;
|
||||
}
|
||||
@@ -119,25 +163,34 @@ static int __em_nl_get_pd_table_size(const struct em_perf_domain *pd)
|
||||
{
|
||||
int id_sz, ps_sz;
|
||||
|
||||
id_sz = nla_total_size(sizeof(u32)); /* EM_A_PD_TABLE_PD_ID */
|
||||
ps_sz = nla_total_size(0) + /* EM_A_PD_TABLE_PS */
|
||||
nla_total_size_64bit(sizeof(u64)) + /* EM_A_PS_PERFORMANCE */
|
||||
nla_total_size_64bit(sizeof(u64)) + /* EM_A_PS_FREQUENCY */
|
||||
nla_total_size_64bit(sizeof(u64)) + /* EM_A_PS_POWER */
|
||||
nla_total_size_64bit(sizeof(u64)) + /* EM_A_PS_COST */
|
||||
nla_total_size_64bit(sizeof(u64)); /* EM_A_PS_FLAGS */
|
||||
id_sz = nla_total_size(sizeof(u32));
|
||||
/* DEV_ENERGYMODEL_A_PERF_TABLE_PERF_DOMAIN_ID */
|
||||
ps_sz = nla_total_size(0) +
|
||||
/* DEV_ENERGYMODEL_A_PERF_TABLE_PERF_STATE */
|
||||
nla_total_size_64bit(sizeof(u64)) +
|
||||
/* DEV_ENERGYMODEL_A_PERF_STATE_PERFORMANCE */
|
||||
nla_total_size_64bit(sizeof(u64)) +
|
||||
/* DEV_ENERGYMODEL_A_PERF_STATE_FREQUENCY */
|
||||
nla_total_size_64bit(sizeof(u64)) +
|
||||
/* DEV_ENERGYMODEL_A_PERF_STATE_POWER */
|
||||
nla_total_size_64bit(sizeof(u64)) +
|
||||
/* DEV_ENERGYMODEL_A_PERF_STATE_COST */
|
||||
nla_total_size_64bit(sizeof(u64));
|
||||
/* DEV_ENERGYMODEL_A_PERF_STATE_FLAGS */
|
||||
ps_sz *= pd->nr_perf_states;
|
||||
|
||||
return nlmsg_total_size(genlmsg_msg_size(id_sz + ps_sz));
|
||||
}
|
||||
|
||||
static int __em_nl_get_pd_table(struct sk_buff *msg, const struct em_perf_domain *pd)
|
||||
static
|
||||
int __em_nl_get_pd_table(struct sk_buff *msg, const struct em_perf_domain *pd)
|
||||
{
|
||||
struct em_perf_state *table, *ps;
|
||||
struct nlattr *entry;
|
||||
int i;
|
||||
|
||||
if (nla_put_u32(msg, EM_A_PD_TABLE_PD_ID, pd->id))
|
||||
if (nla_put_u32(msg, DEV_ENERGYMODEL_A_PERF_TABLE_PERF_DOMAIN_ID,
|
||||
pd->id))
|
||||
goto out_err;
|
||||
|
||||
rcu_read_lock();
|
||||
@@ -146,24 +199,35 @@ static int __em_nl_get_pd_table(struct sk_buff *msg, const struct em_perf_domain
|
||||
for (i = 0; i < pd->nr_perf_states; i++) {
|
||||
ps = &table[i];
|
||||
|
||||
entry = nla_nest_start(msg, EM_A_PD_TABLE_PS);
|
||||
entry = nla_nest_start(msg,
|
||||
DEV_ENERGYMODEL_A_PERF_TABLE_PERF_STATE);
|
||||
if (!entry)
|
||||
goto out_unlock_ps;
|
||||
|
||||
if (nla_put_u64_64bit(msg, EM_A_PS_PERFORMANCE,
|
||||
ps->performance, EM_A_PS_PAD))
|
||||
if (nla_put_u64_64bit(msg,
|
||||
DEV_ENERGYMODEL_A_PERF_STATE_PERFORMANCE,
|
||||
ps->performance,
|
||||
DEV_ENERGYMODEL_A_PERF_STATE_PAD))
|
||||
goto out_cancel_ps_nest;
|
||||
if (nla_put_u64_64bit(msg, EM_A_PS_FREQUENCY,
|
||||
ps->frequency, EM_A_PS_PAD))
|
||||
if (nla_put_u64_64bit(msg,
|
||||
DEV_ENERGYMODEL_A_PERF_STATE_FREQUENCY,
|
||||
ps->frequency,
|
||||
DEV_ENERGYMODEL_A_PERF_STATE_PAD))
|
||||
goto out_cancel_ps_nest;
|
||||
if (nla_put_u64_64bit(msg, EM_A_PS_POWER,
|
||||
ps->power, EM_A_PS_PAD))
|
||||
if (nla_put_u64_64bit(msg,
|
||||
DEV_ENERGYMODEL_A_PERF_STATE_POWER,
|
||||
ps->power,
|
||||
DEV_ENERGYMODEL_A_PERF_STATE_PAD))
|
||||
goto out_cancel_ps_nest;
|
||||
if (nla_put_u64_64bit(msg, EM_A_PS_COST,
|
||||
ps->cost, EM_A_PS_PAD))
|
||||
if (nla_put_u64_64bit(msg,
|
||||
DEV_ENERGYMODEL_A_PERF_STATE_COST,
|
||||
ps->cost,
|
||||
DEV_ENERGYMODEL_A_PERF_STATE_PAD))
|
||||
goto out_cancel_ps_nest;
|
||||
if (nla_put_u64_64bit(msg, EM_A_PS_FLAGS,
|
||||
ps->flags, EM_A_PS_PAD))
|
||||
if (nla_put_u64_64bit(msg,
|
||||
DEV_ENERGYMODEL_A_PERF_STATE_FLAGS,
|
||||
ps->flags,
|
||||
DEV_ENERGYMODEL_A_PERF_STATE_PAD))
|
||||
goto out_cancel_ps_nest;
|
||||
|
||||
nla_nest_end(msg, entry);
|
||||
@@ -179,7 +243,8 @@ out_err:
|
||||
return -EMSGSIZE;
|
||||
}
|
||||
|
||||
int em_nl_get_pd_table_doit(struct sk_buff *skb, struct genl_info *info)
|
||||
int dev_energymodel_nl_get_perf_table_doit(struct sk_buff *skb,
|
||||
struct genl_info *info)
|
||||
{
|
||||
int cmd = info->genlhdr->cmd;
|
||||
int msg_sz, ret = -EMSGSIZE;
|
||||
@@ -197,7 +262,7 @@ int em_nl_get_pd_table_doit(struct sk_buff *skb, struct genl_info *info)
|
||||
if (!msg)
|
||||
return -ENOMEM;
|
||||
|
||||
hdr = genlmsg_put_reply(msg, info, &em_nl_family, 0, cmd);
|
||||
hdr = genlmsg_put_reply(msg, info, &dev_energymodel_nl_family, 0, cmd);
|
||||
if (!hdr)
|
||||
goto out_free_msg;
|
||||
|
||||
@@ -221,7 +286,7 @@ static void __em_notify_pd_table(const struct em_perf_domain *pd, int ntf_type)
|
||||
int msg_sz, ret = -EMSGSIZE;
|
||||
void *hdr;
|
||||
|
||||
if (!genl_has_listeners(&em_nl_family, &init_net, EM_NLGRP_EVENT))
|
||||
if (!genl_has_listeners(&dev_energymodel_nl_family, &init_net, DEV_ENERGYMODEL_NLGRP_EVENT))
|
||||
return;
|
||||
|
||||
msg_sz = __em_nl_get_pd_table_size(pd);
|
||||
@@ -230,7 +295,7 @@ static void __em_notify_pd_table(const struct em_perf_domain *pd, int ntf_type)
|
||||
if (!msg)
|
||||
return;
|
||||
|
||||
hdr = genlmsg_put(msg, 0, 0, &em_nl_family, 0, ntf_type);
|
||||
hdr = genlmsg_put(msg, 0, 0, &dev_energymodel_nl_family, 0, ntf_type);
|
||||
if (!hdr)
|
||||
goto out_free_msg;
|
||||
|
||||
@@ -240,28 +305,28 @@ static void __em_notify_pd_table(const struct em_perf_domain *pd, int ntf_type)
|
||||
|
||||
genlmsg_end(msg, hdr);
|
||||
|
||||
genlmsg_multicast(&em_nl_family, msg, 0, EM_NLGRP_EVENT, GFP_KERNEL);
|
||||
genlmsg_multicast(&dev_energymodel_nl_family, msg, 0,
|
||||
DEV_ENERGYMODEL_NLGRP_EVENT, GFP_KERNEL);
|
||||
|
||||
return;
|
||||
|
||||
out_free_msg:
|
||||
nlmsg_free(msg);
|
||||
return;
|
||||
}
|
||||
|
||||
void em_notify_pd_created(const struct em_perf_domain *pd)
|
||||
{
|
||||
__em_notify_pd_table(pd, EM_CMD_PD_CREATED);
|
||||
__em_notify_pd_table(pd, DEV_ENERGYMODEL_CMD_PERF_DOMAIN_CREATED);
|
||||
}
|
||||
|
||||
void em_notify_pd_updated(const struct em_perf_domain *pd)
|
||||
{
|
||||
__em_notify_pd_table(pd, EM_CMD_PD_UPDATED);
|
||||
__em_notify_pd_table(pd, DEV_ENERGYMODEL_CMD_PERF_DOMAIN_UPDATED);
|
||||
}
|
||||
|
||||
static int __em_notify_pd_deleted_size(const struct em_perf_domain *pd)
|
||||
{
|
||||
int id_sz = nla_total_size(sizeof(u32)); /* EM_A_PD_TABLE_PD_ID */
|
||||
int id_sz = nla_total_size(sizeof(u32)); /* DEV_ENERGYMODEL_A_PERF_TABLE_PERF_DOMAIN_ID */
|
||||
|
||||
return nlmsg_total_size(genlmsg_msg_size(id_sz));
|
||||
}
|
||||
@@ -272,7 +337,8 @@ void em_notify_pd_deleted(const struct em_perf_domain *pd)
|
||||
void *hdr;
|
||||
int msg_sz;
|
||||
|
||||
if (!genl_has_listeners(&em_nl_family, &init_net, EM_NLGRP_EVENT))
|
||||
if (!genl_has_listeners(&dev_energymodel_nl_family, &init_net,
|
||||
DEV_ENERGYMODEL_NLGRP_EVENT))
|
||||
return;
|
||||
|
||||
msg_sz = __em_notify_pd_deleted_size(pd);
|
||||
@@ -281,28 +347,29 @@ void em_notify_pd_deleted(const struct em_perf_domain *pd)
|
||||
if (!msg)
|
||||
return;
|
||||
|
||||
hdr = genlmsg_put(msg, 0, 0, &em_nl_family, 0, EM_CMD_PD_DELETED);
|
||||
hdr = genlmsg_put(msg, 0, 0, &dev_energymodel_nl_family, 0,
|
||||
DEV_ENERGYMODEL_CMD_PERF_DOMAIN_DELETED);
|
||||
if (!hdr)
|
||||
goto out_free_msg;
|
||||
|
||||
if (nla_put_u32(msg, EM_A_PD_TABLE_PD_ID, pd->id)) {
|
||||
if (nla_put_u32(msg, DEV_ENERGYMODEL_A_PERF_TABLE_PERF_DOMAIN_ID,
|
||||
pd->id))
|
||||
goto out_free_msg;
|
||||
}
|
||||
|
||||
genlmsg_end(msg, hdr);
|
||||
|
||||
genlmsg_multicast(&em_nl_family, msg, 0, EM_NLGRP_EVENT, GFP_KERNEL);
|
||||
genlmsg_multicast(&dev_energymodel_nl_family, msg, 0,
|
||||
DEV_ENERGYMODEL_NLGRP_EVENT, GFP_KERNEL);
|
||||
|
||||
return;
|
||||
|
||||
out_free_msg:
|
||||
nlmsg_free(msg);
|
||||
return;
|
||||
}
|
||||
|
||||
/**************************** Initialization *********************************/
|
||||
static int __init em_netlink_init(void)
|
||||
{
|
||||
return genl_register_family(&em_nl_family);
|
||||
return genl_register_family(&dev_energymodel_nl_family);
|
||||
}
|
||||
postcore_initcall(em_netlink_init);
|
||||
@@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause)
|
||||
/* Do not edit directly, auto-generated from: */
|
||||
/* Documentation/netlink/specs/em.yaml */
|
||||
/* Documentation/netlink/specs/dev-energymodel.yaml */
|
||||
/* YNL-GEN kernel source */
|
||||
/* To regenerate run: tools/net/ynl/ynl-regen.sh */
|
||||
|
||||
@@ -9,41 +9,53 @@
|
||||
|
||||
#include "em_netlink_autogen.h"
|
||||
|
||||
#include <uapi/linux/energy_model.h>
|
||||
#include <uapi/linux/dev_energymodel.h>
|
||||
|
||||
/* EM_CMD_GET_PD_TABLE - do */
|
||||
static const struct nla_policy em_get_pd_table_nl_policy[EM_A_PD_TABLE_PD_ID + 1] = {
|
||||
[EM_A_PD_TABLE_PD_ID] = { .type = NLA_U32, },
|
||||
/* DEV_ENERGYMODEL_CMD_GET_PERF_DOMAINS - do */
|
||||
static const struct nla_policy dev_energymodel_get_perf_domains_nl_policy[DEV_ENERGYMODEL_A_PERF_DOMAIN_PERF_DOMAIN_ID + 1] = {
|
||||
[DEV_ENERGYMODEL_A_PERF_DOMAIN_PERF_DOMAIN_ID] = { .type = NLA_U32, },
|
||||
};
|
||||
|
||||
/* Ops table for em */
|
||||
static const struct genl_split_ops em_nl_ops[] = {
|
||||
/* DEV_ENERGYMODEL_CMD_GET_PERF_TABLE - do */
|
||||
static const struct nla_policy dev_energymodel_get_perf_table_nl_policy[DEV_ENERGYMODEL_A_PERF_TABLE_PERF_DOMAIN_ID + 1] = {
|
||||
[DEV_ENERGYMODEL_A_PERF_TABLE_PERF_DOMAIN_ID] = { .type = NLA_U32, },
|
||||
};
|
||||
|
||||
/* Ops table for dev_energymodel */
|
||||
static const struct genl_split_ops dev_energymodel_nl_ops[] = {
|
||||
{
|
||||
.cmd = EM_CMD_GET_PDS,
|
||||
.doit = em_nl_get_pds_doit,
|
||||
.flags = GENL_CMD_CAP_DO,
|
||||
.cmd = DEV_ENERGYMODEL_CMD_GET_PERF_DOMAINS,
|
||||
.doit = dev_energymodel_nl_get_perf_domains_doit,
|
||||
.policy = dev_energymodel_get_perf_domains_nl_policy,
|
||||
.maxattr = DEV_ENERGYMODEL_A_PERF_DOMAIN_PERF_DOMAIN_ID,
|
||||
.flags = GENL_CMD_CAP_DO,
|
||||
},
|
||||
{
|
||||
.cmd = EM_CMD_GET_PD_TABLE,
|
||||
.doit = em_nl_get_pd_table_doit,
|
||||
.policy = em_get_pd_table_nl_policy,
|
||||
.maxattr = EM_A_PD_TABLE_PD_ID,
|
||||
.cmd = DEV_ENERGYMODEL_CMD_GET_PERF_DOMAINS,
|
||||
.dumpit = dev_energymodel_nl_get_perf_domains_dumpit,
|
||||
.flags = GENL_CMD_CAP_DUMP,
|
||||
},
|
||||
{
|
||||
.cmd = DEV_ENERGYMODEL_CMD_GET_PERF_TABLE,
|
||||
.doit = dev_energymodel_nl_get_perf_table_doit,
|
||||
.policy = dev_energymodel_get_perf_table_nl_policy,
|
||||
.maxattr = DEV_ENERGYMODEL_A_PERF_TABLE_PERF_DOMAIN_ID,
|
||||
.flags = GENL_CMD_CAP_DO,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct genl_multicast_group em_nl_mcgrps[] = {
|
||||
[EM_NLGRP_EVENT] = { "event", },
|
||||
static const struct genl_multicast_group dev_energymodel_nl_mcgrps[] = {
|
||||
[DEV_ENERGYMODEL_NLGRP_EVENT] = { "event", },
|
||||
};
|
||||
|
||||
struct genl_family em_nl_family __ro_after_init = {
|
||||
.name = EM_FAMILY_NAME,
|
||||
.version = EM_FAMILY_VERSION,
|
||||
struct genl_family dev_energymodel_nl_family __ro_after_init = {
|
||||
.name = DEV_ENERGYMODEL_FAMILY_NAME,
|
||||
.version = DEV_ENERGYMODEL_FAMILY_VERSION,
|
||||
.netnsok = true,
|
||||
.parallel_ops = true,
|
||||
.module = THIS_MODULE,
|
||||
.split_ops = em_nl_ops,
|
||||
.n_split_ops = ARRAY_SIZE(em_nl_ops),
|
||||
.mcgrps = em_nl_mcgrps,
|
||||
.n_mcgrps = ARRAY_SIZE(em_nl_mcgrps),
|
||||
.split_ops = dev_energymodel_nl_ops,
|
||||
.n_split_ops = ARRAY_SIZE(dev_energymodel_nl_ops),
|
||||
.mcgrps = dev_energymodel_nl_mcgrps,
|
||||
.n_mcgrps = ARRAY_SIZE(dev_energymodel_nl_mcgrps),
|
||||
};
|
||||
@@ -1,24 +1,28 @@
|
||||
/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */
|
||||
/* Do not edit directly, auto-generated from: */
|
||||
/* Documentation/netlink/specs/em.yaml */
|
||||
/* Documentation/netlink/specs/dev-energymodel.yaml */
|
||||
/* YNL-GEN kernel header */
|
||||
/* To regenerate run: tools/net/ynl/ynl-regen.sh */
|
||||
|
||||
#ifndef _LINUX_EM_GEN_H
|
||||
#define _LINUX_EM_GEN_H
|
||||
#ifndef _LINUX_DEV_ENERGYMODEL_GEN_H
|
||||
#define _LINUX_DEV_ENERGYMODEL_GEN_H
|
||||
|
||||
#include <net/netlink.h>
|
||||
#include <net/genetlink.h>
|
||||
|
||||
#include <uapi/linux/energy_model.h>
|
||||
#include <uapi/linux/dev_energymodel.h>
|
||||
|
||||
int em_nl_get_pds_doit(struct sk_buff *skb, struct genl_info *info);
|
||||
int em_nl_get_pd_table_doit(struct sk_buff *skb, struct genl_info *info);
|
||||
int dev_energymodel_nl_get_perf_domains_doit(struct sk_buff *skb,
|
||||
struct genl_info *info);
|
||||
int dev_energymodel_nl_get_perf_domains_dumpit(struct sk_buff *skb,
|
||||
struct netlink_callback *cb);
|
||||
int dev_energymodel_nl_get_perf_table_doit(struct sk_buff *skb,
|
||||
struct genl_info *info);
|
||||
|
||||
enum {
|
||||
EM_NLGRP_EVENT,
|
||||
DEV_ENERGYMODEL_NLGRP_EVENT,
|
||||
};
|
||||
|
||||
extern struct genl_family em_nl_family;
|
||||
extern struct genl_family dev_energymodel_nl_family;
|
||||
|
||||
#endif /* _LINUX_EM_GEN_H */
|
||||
#endif /* _LINUX_DEV_ENERGYMODEL_GEN_H */
|
||||
@@ -449,8 +449,10 @@ static int em_create_pd(struct device *dev, int nr_states,
|
||||
INIT_LIST_HEAD(&pd->node);
|
||||
|
||||
id = ida_alloc(&em_pd_ida, GFP_KERNEL);
|
||||
if (id < 0)
|
||||
return -ENOMEM;
|
||||
if (id < 0) {
|
||||
kfree(pd);
|
||||
return id;
|
||||
}
|
||||
pd->id = id;
|
||||
|
||||
em_table = em_table_alloc(pd);
|
||||
|
||||
+18
-20
@@ -1557,18 +1557,27 @@ static int __nbcon_atomic_flush_pending_con(struct console *con, u64 stop_seq)
|
||||
ctxt->allow_unsafe_takeover = nbcon_allow_unsafe_takeover();
|
||||
|
||||
while (nbcon_seq_read(con) < stop_seq) {
|
||||
if (!nbcon_context_try_acquire(ctxt, false))
|
||||
return -EPERM;
|
||||
|
||||
/*
|
||||
* nbcon_emit_next_record() returns false when the console was
|
||||
* handed over or taken over. In both cases the context is no
|
||||
* longer valid.
|
||||
* Atomic flushing does not use console driver synchronization
|
||||
* (i.e. it does not hold the port lock for uart consoles).
|
||||
* Therefore IRQs must be disabled to avoid being interrupted
|
||||
* and then calling into a driver that will deadlock trying
|
||||
* to acquire console ownership.
|
||||
*/
|
||||
if (!nbcon_emit_next_record(&wctxt, true))
|
||||
return -EAGAIN;
|
||||
scoped_guard(irqsave) {
|
||||
if (!nbcon_context_try_acquire(ctxt, false))
|
||||
return -EPERM;
|
||||
|
||||
nbcon_context_release(ctxt);
|
||||
/*
|
||||
* nbcon_emit_next_record() returns false when
|
||||
* the console was handed over or taken over.
|
||||
* In both cases the context is no longer valid.
|
||||
*/
|
||||
if (!nbcon_emit_next_record(&wctxt, true))
|
||||
return -EAGAIN;
|
||||
|
||||
nbcon_context_release(ctxt);
|
||||
}
|
||||
|
||||
if (!ctxt->backlog) {
|
||||
/* Are there reserved but not yet finalized records? */
|
||||
@@ -1595,22 +1604,11 @@ static int __nbcon_atomic_flush_pending_con(struct console *con, u64 stop_seq)
|
||||
static void nbcon_atomic_flush_pending_con(struct console *con, u64 stop_seq)
|
||||
{
|
||||
struct console_flush_type ft;
|
||||
unsigned long flags;
|
||||
int err;
|
||||
|
||||
again:
|
||||
/*
|
||||
* Atomic flushing does not use console driver synchronization (i.e.
|
||||
* it does not hold the port lock for uart consoles). Therefore IRQs
|
||||
* must be disabled to avoid being interrupted and then calling into
|
||||
* a driver that will deadlock trying to acquire console ownership.
|
||||
*/
|
||||
local_irq_save(flags);
|
||||
|
||||
err = __nbcon_atomic_flush_pending_con(con, stop_seq);
|
||||
|
||||
local_irq_restore(flags);
|
||||
|
||||
/*
|
||||
* If there was a new owner (-EPERM, -EAGAIN), that context is
|
||||
* responsible for completing.
|
||||
|
||||
+7
-3
@@ -1220,10 +1220,14 @@ config ZONE_DEVICE
|
||||
Device memory hotplug support allows for establishing pmem,
|
||||
or other device driver discovered memory regions, in the
|
||||
memmap. This allows pfn_to_page() lookups of otherwise
|
||||
"device-physical" addresses which is needed for using a DAX
|
||||
mapping in an O_DIRECT operation, among other things.
|
||||
"device-physical" addresses which is needed for DAX, PCI_P2PDMA, and
|
||||
DEVICE_PRIVATE features among others.
|
||||
|
||||
If FS_DAX is enabled, then say Y.
|
||||
Enabling this option will reduce the entropy of x86 KASLR memory
|
||||
regions. For example - on a 46 bit system, the entropy goes down
|
||||
from 16 bits to 15 bits. The actual reduction in entropy depends
|
||||
on the physical address bits, on processor features, kernel config
|
||||
(5 level page table) and physical memory present on the system.
|
||||
|
||||
#
|
||||
# Helpers to mirror range of the CPU page tables of a process into device page
|
||||
|
||||
@@ -1074,7 +1074,9 @@ static int snd_pcm_oss_change_params_locked(struct snd_pcm_substream *substream)
|
||||
runtime->oss.params = 0;
|
||||
runtime->oss.prepare = 1;
|
||||
runtime->oss.buffer_used = 0;
|
||||
snd_pcm_runtime_buffer_set_silence(runtime);
|
||||
err = snd_pcm_runtime_buffer_set_silence(runtime);
|
||||
if (err < 0)
|
||||
goto failure;
|
||||
|
||||
runtime->oss.period_frames = snd_pcm_alsa_frames(substream, oss_period_size);
|
||||
|
||||
|
||||
@@ -730,13 +730,18 @@ static void snd_pcm_buffer_access_unlock(struct snd_pcm_runtime *runtime)
|
||||
}
|
||||
|
||||
/* fill the PCM buffer with the current silence format; called from pcm_oss.c */
|
||||
void snd_pcm_runtime_buffer_set_silence(struct snd_pcm_runtime *runtime)
|
||||
int snd_pcm_runtime_buffer_set_silence(struct snd_pcm_runtime *runtime)
|
||||
{
|
||||
snd_pcm_buffer_access_lock(runtime);
|
||||
int err;
|
||||
|
||||
err = snd_pcm_buffer_access_lock(runtime);
|
||||
if (err < 0)
|
||||
return err;
|
||||
if (runtime->dma_area)
|
||||
snd_pcm_format_set_silence(runtime->format, runtime->dma_area,
|
||||
bytes_to_samples(runtime, runtime->dma_bytes));
|
||||
snd_pcm_buffer_access_unlock(runtime);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_pcm_runtime_buffer_set_silence);
|
||||
|
||||
|
||||
@@ -6613,6 +6613,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
|
||||
SND_PCI_QUIRK(0x103c, 0x8a2e, "HP Envy 16", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
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, 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),
|
||||
SND_PCI_QUIRK(0x103c, 0x8a74, "HP ProBook 440 G8 Notebook PC", ALC236_FIXUP_HP_GPIO_LED),
|
||||
@@ -6817,6 +6818,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
|
||||
SND_PCI_QUIRK(0x103c, 0x8f42, "HP ZBook 8 G2a 14W", ALC245_FIXUP_HP_TAS2781_I2C_MUTE_LED),
|
||||
SND_PCI_QUIRK(0x103c, 0x8f57, "HP Trekker G7JC", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
SND_PCI_QUIRK(0x103c, 0x8f62, "HP ZBook 8 G2a 16W", ALC245_FIXUP_HP_TAS2781_I2C_MUTE_LED),
|
||||
SND_PCI_QUIRK(0x1043, 0x1024, "ASUS Zephyrus G14 2025", ALC285_FIXUP_ASUS_GA403U_HEADSET_MIC),
|
||||
SND_PCI_QUIRK(0x1043, 0x1032, "ASUS VivoBook X513EA", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x1043, 0x1034, "ASUS GU605C", ALC285_FIXUP_ASUS_GU605_SPI_SPEAKER2_TO_DAC1),
|
||||
SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC),
|
||||
|
||||
@@ -103,6 +103,7 @@ static int cirrus_scodec_test_gpio_probe(struct platform_device *pdev)
|
||||
|
||||
/* GPIO core modifies our struct gpio_chip so use a copy */
|
||||
gpio_priv->chip = cirrus_scodec_test_gpio_chip;
|
||||
gpio_priv->chip.parent = &pdev->dev;
|
||||
ret = devm_gpiochip_add_data(&pdev->dev, &gpio_priv->chip, gpio_priv);
|
||||
if (ret)
|
||||
return dev_err_probe(&pdev->dev, ret, "Failed to add gpiochip\n");
|
||||
@@ -319,7 +320,7 @@ static struct kunit_case cirrus_scodec_test_cases[] = {
|
||||
};
|
||||
|
||||
static struct kunit_suite cirrus_scodec_test_suite = {
|
||||
.name = "snd-hda-scodec-cs35l56-test",
|
||||
.name = "snd-hda-cirrus-scodec-test",
|
||||
.init = cirrus_scodec_test_case_init,
|
||||
.test_cases = cirrus_scodec_test_cases,
|
||||
};
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
//
|
||||
// TAS2781 HDA I2C driver
|
||||
//
|
||||
// Copyright 2023 - 2025 Texas Instruments, Inc.
|
||||
// Copyright 2023 - 2026 Texas Instruments, Inc.
|
||||
//
|
||||
// Author: Shenghao Ding <shenghao-ding@ti.com>
|
||||
// Current maintainer: Baojun Xu <baojun.xu@ti.com>
|
||||
@@ -60,6 +60,7 @@ struct tas2781_hda_i2c_priv {
|
||||
int (*save_calibration)(struct tas2781_hda *h);
|
||||
|
||||
int hda_chip_id;
|
||||
bool skip_calibration;
|
||||
};
|
||||
|
||||
static int tas2781_get_i2c_res(struct acpi_resource *ares, void *data)
|
||||
@@ -491,7 +492,8 @@ static void tasdevice_dspfw_init(void *context)
|
||||
/* If calibrated data occurs error, dsp will still works with default
|
||||
* calibrated data inside algo.
|
||||
*/
|
||||
hda_priv->save_calibration(tas_hda);
|
||||
if (!hda_priv->skip_calibration)
|
||||
hda_priv->save_calibration(tas_hda);
|
||||
}
|
||||
|
||||
static void tasdev_fw_ready(const struct firmware *fmw, void *context)
|
||||
@@ -548,6 +550,7 @@ static int tas2781_hda_bind(struct device *dev, struct device *master,
|
||||
void *master_data)
|
||||
{
|
||||
struct tas2781_hda *tas_hda = dev_get_drvdata(dev);
|
||||
struct tas2781_hda_i2c_priv *hda_priv = tas_hda->hda_priv;
|
||||
struct hda_component_parent *parent = master_data;
|
||||
struct hda_component *comp;
|
||||
struct hda_codec *codec;
|
||||
@@ -568,11 +571,22 @@ static int tas2781_hda_bind(struct device *dev, struct device *master,
|
||||
case 0x1028:
|
||||
tas_hda->catlog_id = DELL;
|
||||
break;
|
||||
case 0x103C:
|
||||
tas_hda->catlog_id = HP;
|
||||
break;
|
||||
default:
|
||||
tas_hda->catlog_id = LENOVO;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Using ASUS ROG Xbox Ally X (RC73XA) UEFI calibration data
|
||||
* causes audio dropouts during playback, use fallback data
|
||||
* from DSP firmware as a workaround.
|
||||
*/
|
||||
if (codec->core.subsystem_id == 0x10431384)
|
||||
hda_priv->skip_calibration = true;
|
||||
|
||||
pm_runtime_get_sync(dev);
|
||||
|
||||
comp->dev = dev;
|
||||
|
||||
@@ -416,6 +416,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "M6500RC"),
|
||||
}
|
||||
},
|
||||
{
|
||||
.driver_data = &acp6x_card,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK COMPUTER INC."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "M6500RE"),
|
||||
}
|
||||
},
|
||||
{
|
||||
.driver_data = &acp6x_card,
|
||||
.matches = {
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
#include "tlv320adcx140.h"
|
||||
|
||||
struct adcx140_priv {
|
||||
struct snd_soc_component *component;
|
||||
struct regulator *supply_areg;
|
||||
struct gpio_desc *gpio_reset;
|
||||
struct regmap *regmap;
|
||||
@@ -338,7 +337,7 @@ static const struct snd_kcontrol_new adcx140_dapm_ch4_dre_en_switch =
|
||||
SOC_DAPM_SINGLE("Switch", ADCX140_CH4_CFG0, 0, 1, 0);
|
||||
|
||||
static const struct snd_kcontrol_new adcx140_dapm_dre_en_switch =
|
||||
SOC_DAPM_SINGLE("Switch", ADCX140_DSP_CFG1, 3, 1, 0);
|
||||
SOC_DAPM_SINGLE("Switch", ADCX140_DSP_CFG1, 3, 1, 1);
|
||||
|
||||
/* Output Mixer */
|
||||
static const struct snd_kcontrol_new adcx140_output_mixer_controls[] = {
|
||||
@@ -699,7 +698,6 @@ static void adcx140_pwr_ctrl(struct adcx140_priv *adcx140, bool power_state)
|
||||
{
|
||||
int pwr_ctrl = 0;
|
||||
int ret = 0;
|
||||
struct snd_soc_component *component = adcx140->component;
|
||||
|
||||
if (power_state)
|
||||
pwr_ctrl = ADCX140_PWR_CFG_ADC_PDZ | ADCX140_PWR_CFG_PLL_PDZ;
|
||||
@@ -711,7 +709,7 @@ static void adcx140_pwr_ctrl(struct adcx140_priv *adcx140, bool power_state)
|
||||
ret = regmap_write(adcx140->regmap, ADCX140_PHASE_CALIB,
|
||||
adcx140->phase_calib_on ? 0x00 : 0x40);
|
||||
if (ret)
|
||||
dev_err(component->dev, "%s: register write error %d\n",
|
||||
dev_err(adcx140->dev, "%s: register write error %d\n",
|
||||
__func__, ret);
|
||||
}
|
||||
|
||||
@@ -727,7 +725,7 @@ static int adcx140_hw_params(struct snd_pcm_substream *substream,
|
||||
struct adcx140_priv *adcx140 = snd_soc_component_get_drvdata(component);
|
||||
u8 data = 0;
|
||||
|
||||
switch (params_width(params)) {
|
||||
switch (params_physical_width(params)) {
|
||||
case 16:
|
||||
data = ADCX140_16_BIT_WORD;
|
||||
break;
|
||||
@@ -742,7 +740,7 @@ static int adcx140_hw_params(struct snd_pcm_substream *substream,
|
||||
break;
|
||||
default:
|
||||
dev_err(component->dev, "%s: Unsupported width %d\n",
|
||||
__func__, params_width(params));
|
||||
__func__, params_physical_width(params));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -1156,6 +1154,9 @@ static int adcx140_i2c_probe(struct i2c_client *i2c)
|
||||
adcx140->gpio_reset = devm_gpiod_get_optional(adcx140->dev,
|
||||
"reset", GPIOD_OUT_LOW);
|
||||
if (IS_ERR(adcx140->gpio_reset))
|
||||
return dev_err_probe(&i2c->dev, PTR_ERR(adcx140->gpio_reset),
|
||||
"Failed to get Reset GPIO\n");
|
||||
if (!adcx140->gpio_reset)
|
||||
dev_info(&i2c->dev, "Reset GPIO not defined\n");
|
||||
|
||||
adcx140->supply_areg = devm_regulator_get_optional(adcx140->dev,
|
||||
|
||||
@@ -678,6 +678,7 @@ struct wsa881x_priv {
|
||||
*/
|
||||
unsigned int sd_n_val;
|
||||
int active_ports;
|
||||
bool hw_init;
|
||||
bool port_prepared[WSA881X_MAX_SWR_PORTS];
|
||||
bool port_enable[WSA881X_MAX_SWR_PORTS];
|
||||
};
|
||||
@@ -687,6 +688,9 @@ static void wsa881x_init(struct wsa881x_priv *wsa881x)
|
||||
struct regmap *rm = wsa881x->regmap;
|
||||
unsigned int val = 0;
|
||||
|
||||
if (wsa881x->hw_init)
|
||||
return;
|
||||
|
||||
regmap_register_patch(wsa881x->regmap, wsa881x_rev_2_0,
|
||||
ARRAY_SIZE(wsa881x_rev_2_0));
|
||||
|
||||
@@ -724,6 +728,8 @@ static void wsa881x_init(struct wsa881x_priv *wsa881x)
|
||||
regmap_update_bits(rm, WSA881X_OTP_REG_28, 0x3F, 0x3A);
|
||||
regmap_update_bits(rm, WSA881X_BONGO_RESRV_REG1, 0xFF, 0xB2);
|
||||
regmap_update_bits(rm, WSA881X_BONGO_RESRV_REG2, 0xFF, 0x05);
|
||||
|
||||
wsa881x->hw_init = true;
|
||||
}
|
||||
|
||||
static int wsa881x_component_probe(struct snd_soc_component *comp)
|
||||
@@ -1067,6 +1073,9 @@ static int wsa881x_update_status(struct sdw_slave *slave,
|
||||
{
|
||||
struct wsa881x_priv *wsa881x = dev_get_drvdata(&slave->dev);
|
||||
|
||||
if (status == SDW_SLAVE_UNATTACHED)
|
||||
wsa881x->hw_init = false;
|
||||
|
||||
if (status == SDW_SLAVE_ATTACHED && slave->dev_num > 0)
|
||||
wsa881x_init(wsa881x);
|
||||
|
||||
|
||||
@@ -475,6 +475,7 @@ struct wsa883x_priv {
|
||||
int active_ports;
|
||||
int dev_mode;
|
||||
int comp_offset;
|
||||
bool hw_init;
|
||||
/*
|
||||
* Protects temperature reading code (related to speaker protection) and
|
||||
* fields: temperature and pa_on.
|
||||
@@ -1043,6 +1044,9 @@ static int wsa883x_init(struct wsa883x_priv *wsa883x)
|
||||
struct regmap *regmap = wsa883x->regmap;
|
||||
int variant, version, ret;
|
||||
|
||||
if (wsa883x->hw_init)
|
||||
return 0;
|
||||
|
||||
ret = regmap_read(regmap, WSA883X_OTP_REG_0, &variant);
|
||||
if (ret)
|
||||
return ret;
|
||||
@@ -1054,22 +1058,23 @@ static int wsa883x_init(struct wsa883x_priv *wsa883x)
|
||||
|
||||
switch (variant) {
|
||||
case WSA8830:
|
||||
dev_info(wsa883x->dev, "WSA883X Version 1_%d, Variant: WSA8830\n",
|
||||
version);
|
||||
dev_dbg(wsa883x->dev, "WSA883X Version 1_%d, Variant: WSA8830\n",
|
||||
version);
|
||||
break;
|
||||
case WSA8835:
|
||||
dev_info(wsa883x->dev, "WSA883X Version 1_%d, Variant: WSA8835\n",
|
||||
version);
|
||||
dev_dbg(wsa883x->dev, "WSA883X Version 1_%d, Variant: WSA8835\n",
|
||||
version);
|
||||
break;
|
||||
case WSA8832:
|
||||
dev_info(wsa883x->dev, "WSA883X Version 1_%d, Variant: WSA8832\n",
|
||||
version);
|
||||
dev_dbg(wsa883x->dev, "WSA883X Version 1_%d, Variant: WSA8832\n",
|
||||
version);
|
||||
break;
|
||||
case WSA8835_V2:
|
||||
dev_info(wsa883x->dev, "WSA883X Version 1_%d, Variant: WSA8835_V2\n",
|
||||
version);
|
||||
dev_dbg(wsa883x->dev, "WSA883X Version 1_%d, Variant: WSA8835_V2\n",
|
||||
version);
|
||||
break;
|
||||
default:
|
||||
dev_warn(wsa883x->dev, "unknown variant: %d\n", variant);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1085,6 +1090,8 @@ static int wsa883x_init(struct wsa883x_priv *wsa883x)
|
||||
wsa883x->comp_offset);
|
||||
}
|
||||
|
||||
wsa883x->hw_init = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1093,6 +1100,9 @@ static int wsa883x_update_status(struct sdw_slave *slave,
|
||||
{
|
||||
struct wsa883x_priv *wsa883x = dev_get_drvdata(&slave->dev);
|
||||
|
||||
if (status == SDW_SLAVE_UNATTACHED)
|
||||
wsa883x->hw_init = false;
|
||||
|
||||
if (status == SDW_SLAVE_ATTACHED && slave->dev_num > 0)
|
||||
return wsa883x_init(wsa883x);
|
||||
|
||||
|
||||
@@ -1534,7 +1534,7 @@ static void wsa884x_init(struct wsa884x_priv *wsa884x)
|
||||
|
||||
wsa884x_set_gain_parameters(wsa884x);
|
||||
|
||||
wsa884x->hw_init = false;
|
||||
wsa884x->hw_init = true;
|
||||
}
|
||||
|
||||
static int wsa884x_update_status(struct sdw_slave *slave,
|
||||
@@ -2109,7 +2109,6 @@ static int wsa884x_probe(struct sdw_slave *pdev,
|
||||
|
||||
/* Start in cache-only until device is enumerated */
|
||||
regcache_cache_only(wsa884x->regmap, true);
|
||||
wsa884x->hw_init = true;
|
||||
|
||||
if (IS_REACHABLE(CONFIG_HWMON)) {
|
||||
struct device *hwmon;
|
||||
|
||||
@@ -1179,9 +1179,9 @@ void graph_util_parse_link_direction(struct device_node *np,
|
||||
bool is_playback_only = of_property_read_bool(np, "playback-only");
|
||||
bool is_capture_only = of_property_read_bool(np, "capture-only");
|
||||
|
||||
if (playback_only)
|
||||
if (np && playback_only)
|
||||
*playback_only = is_playback_only;
|
||||
if (capture_only)
|
||||
if (np && capture_only)
|
||||
*capture_only = is_capture_only;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(graph_util_parse_link_direction);
|
||||
|
||||
@@ -764,6 +764,14 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = {
|
||||
.driver_data = (void *)(SOC_SDW_CODEC_SPKR),
|
||||
},
|
||||
/* Pantherlake devices*/
|
||||
{
|
||||
.callback = sof_sdw_quirk_cb,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
|
||||
DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0DD6")
|
||||
},
|
||||
.driver_data = (void *)(SOC_SDW_SIDECAR_AMPS),
|
||||
},
|
||||
{
|
||||
.callback = sof_sdw_quirk_cb,
|
||||
.matches = {
|
||||
|
||||
@@ -44,7 +44,7 @@ static const struct snd_soc_dapm_route cs42l43_dmic_map[] = {
|
||||
static struct snd_soc_jack_pin soc_jack_pins[] = {
|
||||
{
|
||||
.pin = "Headphone",
|
||||
.mask = SND_JACK_HEADPHONE,
|
||||
.mask = SND_JACK_HEADPHONE | SND_JACK_LINEOUT,
|
||||
},
|
||||
{
|
||||
.pin = "Headset Mic",
|
||||
|
||||
@@ -841,6 +841,19 @@ struct asoc_sdw_codec_info *asoc_sdw_find_codec_info_part(const u64 adr)
|
||||
}
|
||||
EXPORT_SYMBOL_NS(asoc_sdw_find_codec_info_part, "SND_SOC_SDW_UTILS");
|
||||
|
||||
static struct asoc_sdw_codec_info *asoc_sdw_find_codec_info_sdw_id(const struct sdw_slave_id *id)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(codec_info_list); i++)
|
||||
if (id->part_id == codec_info_list[i].part_id &&
|
||||
(!codec_info_list[i].version_id ||
|
||||
id->sdw_version == codec_info_list[i].version_id))
|
||||
return &codec_info_list[i];
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct asoc_sdw_codec_info *asoc_sdw_find_codec_info_acpi(const u8 *acpi_id)
|
||||
{
|
||||
int i;
|
||||
@@ -873,22 +886,46 @@ struct asoc_sdw_codec_info *asoc_sdw_find_codec_info_dai(const char *dai_name, i
|
||||
}
|
||||
EXPORT_SYMBOL_NS(asoc_sdw_find_codec_info_dai, "SND_SOC_SDW_UTILS");
|
||||
|
||||
static int asoc_sdw_find_codec_info_dai_index(const struct asoc_sdw_codec_info *codec_info,
|
||||
const char *dai_name)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < codec_info->dai_num; i++) {
|
||||
if (!strcmp(codec_info->dais[i].dai_name, dai_name))
|
||||
return i;
|
||||
}
|
||||
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
int asoc_sdw_rtd_init(struct snd_soc_pcm_runtime *rtd)
|
||||
{
|
||||
struct snd_soc_card *card = rtd->card;
|
||||
struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card);
|
||||
struct asoc_sdw_codec_info *codec_info;
|
||||
struct snd_soc_dai *dai;
|
||||
struct sdw_slave *sdw_peripheral;
|
||||
const char *spk_components="";
|
||||
int dai_index;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
for_each_rtd_codec_dais(rtd, i, dai) {
|
||||
codec_info = asoc_sdw_find_codec_info_dai(dai->name, &dai_index);
|
||||
if (is_sdw_slave(dai->component->dev))
|
||||
sdw_peripheral = dev_to_sdw_dev(dai->component->dev);
|
||||
else if (dai->component->dev->parent && is_sdw_slave(dai->component->dev->parent))
|
||||
sdw_peripheral = dev_to_sdw_dev(dai->component->dev->parent);
|
||||
else
|
||||
continue;
|
||||
|
||||
codec_info = asoc_sdw_find_codec_info_sdw_id(&sdw_peripheral->id);
|
||||
if (!codec_info)
|
||||
return -EINVAL;
|
||||
|
||||
dai_index = asoc_sdw_find_codec_info_dai_index(codec_info, dai->name);
|
||||
WARN_ON(dai_index < 0);
|
||||
|
||||
/*
|
||||
* A codec dai can be connected to different dai links for capture and playback,
|
||||
* but we only need to call the rtd_init function once.
|
||||
@@ -898,6 +935,10 @@ int asoc_sdw_rtd_init(struct snd_soc_pcm_runtime *rtd)
|
||||
if (codec_info->dais[dai_index].rtd_init_done)
|
||||
continue;
|
||||
|
||||
dev_dbg(card->dev, "%#x/%s initializing for %s/%s\n",
|
||||
codec_info->part_id, codec_info->dais[dai_index].dai_name,
|
||||
dai->component->name, dai->name);
|
||||
|
||||
/*
|
||||
* Add card controls and dapm widgets for the first codec dai.
|
||||
* The controls and widgets will be used for all codec dais.
|
||||
|
||||
+2
-2
@@ -543,11 +543,11 @@ int snd_soc_bytes_get(struct snd_kcontrol *kcontrol,
|
||||
ucontrol->value.bytes.data[0] &= ~params->mask;
|
||||
break;
|
||||
case 2:
|
||||
((u16 *)(&ucontrol->value.bytes.data))[0]
|
||||
((__be16 *)(&ucontrol->value.bytes.data))[0]
|
||||
&= cpu_to_be16(~params->mask);
|
||||
break;
|
||||
case 4:
|
||||
((u32 *)(&ucontrol->value.bytes.data))[0]
|
||||
((__be32 *)(&ucontrol->value.bytes.data))[0]
|
||||
&= cpu_to_be32(~params->mask);
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -2077,7 +2077,7 @@ static const struct regmap_config tegra210_ahub_regmap_config = {
|
||||
.val_bits = 32,
|
||||
.reg_stride = 4,
|
||||
.max_register = TEGRA210_MAX_REGISTER_ADDR,
|
||||
.cache_type = REGCACHE_FLAT_S,
|
||||
.cache_type = REGCACHE_FLAT,
|
||||
};
|
||||
|
||||
static const struct regmap_config tegra186_ahub_regmap_config = {
|
||||
@@ -2085,7 +2085,7 @@ static const struct regmap_config tegra186_ahub_regmap_config = {
|
||||
.val_bits = 32,
|
||||
.reg_stride = 4,
|
||||
.max_register = TEGRA186_MAX_REGISTER_ADDR,
|
||||
.cache_type = REGCACHE_FLAT_S,
|
||||
.cache_type = REGCACHE_FLAT,
|
||||
};
|
||||
|
||||
static const struct regmap_config tegra264_ahub_regmap_config = {
|
||||
@@ -2094,7 +2094,7 @@ static const struct regmap_config tegra264_ahub_regmap_config = {
|
||||
.reg_stride = 4,
|
||||
.writeable_reg = tegra264_ahub_wr_reg,
|
||||
.max_register = TEGRA264_MAX_REGISTER_ADDR,
|
||||
.cache_type = REGCACHE_FLAT_S,
|
||||
.cache_type = REGCACHE_FLAT,
|
||||
};
|
||||
|
||||
static const struct tegra_ahub_soc_data soc_data_tegra210 = {
|
||||
|
||||
@@ -194,27 +194,32 @@ static int davinci_evm_probe(struct platform_device *pdev)
|
||||
return -EINVAL;
|
||||
|
||||
dai->cpus->of_node = of_parse_phandle(np, "ti,mcasp-controller", 0);
|
||||
if (!dai->cpus->of_node)
|
||||
return -EINVAL;
|
||||
if (!dai->cpus->of_node) {
|
||||
ret = -EINVAL;
|
||||
goto err_put;
|
||||
}
|
||||
|
||||
dai->platforms->of_node = dai->cpus->of_node;
|
||||
|
||||
evm_soc_card.dev = &pdev->dev;
|
||||
ret = snd_soc_of_parse_card_name(&evm_soc_card, "ti,model");
|
||||
if (ret)
|
||||
return ret;
|
||||
goto err_put;
|
||||
|
||||
mclk = devm_clk_get(&pdev->dev, "mclk");
|
||||
if (PTR_ERR(mclk) == -EPROBE_DEFER) {
|
||||
return -EPROBE_DEFER;
|
||||
ret = -EPROBE_DEFER;
|
||||
goto err_put;
|
||||
} else if (IS_ERR(mclk)) {
|
||||
dev_dbg(&pdev->dev, "mclk not found.\n");
|
||||
mclk = NULL;
|
||||
}
|
||||
|
||||
drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
|
||||
if (!drvdata)
|
||||
return -ENOMEM;
|
||||
if (!drvdata) {
|
||||
ret = -ENOMEM;
|
||||
goto err_put;
|
||||
}
|
||||
|
||||
drvdata->mclk = mclk;
|
||||
|
||||
@@ -224,7 +229,8 @@ static int davinci_evm_probe(struct platform_device *pdev)
|
||||
if (!drvdata->mclk) {
|
||||
dev_err(&pdev->dev,
|
||||
"No clock or clock rate defined.\n");
|
||||
return -EINVAL;
|
||||
ret = -EINVAL;
|
||||
goto err_put;
|
||||
}
|
||||
drvdata->sysclk = clk_get_rate(drvdata->mclk);
|
||||
} else if (drvdata->mclk) {
|
||||
@@ -240,8 +246,25 @@ static int davinci_evm_probe(struct platform_device *pdev)
|
||||
snd_soc_card_set_drvdata(&evm_soc_card, drvdata);
|
||||
ret = devm_snd_soc_register_card(&pdev->dev, &evm_soc_card);
|
||||
|
||||
if (ret)
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
|
||||
goto err_put;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
err_put:
|
||||
dai->platforms->of_node = NULL;
|
||||
|
||||
if (dai->cpus->of_node) {
|
||||
of_node_put(dai->cpus->of_node);
|
||||
dai->cpus->of_node = NULL;
|
||||
}
|
||||
|
||||
if (dai->codecs->of_node) {
|
||||
of_node_put(dai->codecs->of_node);
|
||||
dai->codecs->of_node = NULL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
+1
-1
@@ -1553,7 +1553,7 @@ static int prepare_playback_urb(struct snd_usb_substream *subs,
|
||||
|
||||
for (i = 0; i < ctx->packets; i++) {
|
||||
counts = snd_usb_endpoint_next_packet_size(ep, ctx, i, avail);
|
||||
if (counts < 0)
|
||||
if (counts < 0 || frames + counts >= ep->max_urb_frames)
|
||||
break;
|
||||
/* set up descriptor */
|
||||
urb->iso_frame_desc[i].offset = frames * stride;
|
||||
|
||||
@@ -68,6 +68,8 @@ static u64 to_hpa(u64 dpa_offset, int pos, u8 r_eiw, u16 r_eig, u8 hb_ways,
|
||||
|
||||
/* Calculate base HPA offset from DPA and position */
|
||||
hpa_offset = cxl_calculate_hpa_offset(dpa_offset, pos, r_eiw, r_eig);
|
||||
if (hpa_offset == ULLONG_MAX)
|
||||
return ULLONG_MAX;
|
||||
|
||||
if (math == XOR_MATH) {
|
||||
cximsd->nr_maps = hbiw_to_nr_maps[hb_ways];
|
||||
@@ -258,19 +260,23 @@ static int test_random_params(void)
|
||||
pos = get_random_u32() % ways;
|
||||
dpa = get_random_u64() >> 12;
|
||||
|
||||
reverse_dpa = ULLONG_MAX;
|
||||
reverse_pos = -1;
|
||||
|
||||
hpa = cxl_calculate_hpa_offset(dpa, pos, eiw, eig);
|
||||
reverse_dpa = cxl_calculate_dpa_offset(hpa, eiw, eig);
|
||||
reverse_pos = cxl_calculate_position(hpa, eiw, eig);
|
||||
if (hpa != ULLONG_MAX) {
|
||||
reverse_dpa = cxl_calculate_dpa_offset(hpa, eiw, eig);
|
||||
reverse_pos = cxl_calculate_position(hpa, eiw, eig);
|
||||
if (reverse_dpa == dpa && reverse_pos == pos)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (reverse_dpa != dpa || reverse_pos != pos) {
|
||||
pr_err("test random iter %d FAIL hpa=%llu, dpa=%llu reverse_dpa=%llu, pos=%d reverse_pos=%d eiw=%u eig=%u\n",
|
||||
i, hpa, dpa, reverse_dpa, pos, reverse_pos, eiw,
|
||||
eig);
|
||||
pr_err("test random iter %d FAIL hpa=%llu, dpa=%llu reverse_dpa=%llu, pos=%d reverse_pos=%d eiw=%u eig=%u\n",
|
||||
i, hpa, dpa, reverse_dpa, pos, reverse_pos, eiw, eig);
|
||||
|
||||
if (failures++ > 10) {
|
||||
pr_err("test random too many failures, stop\n");
|
||||
break;
|
||||
}
|
||||
if (failures++ > 10) {
|
||||
pr_err("test random too many failures, stop\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
pr_info("..... test random: PASS %d FAIL %d\n", i - failures, failures);
|
||||
|
||||
Reference in new issue
Block a user