mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-01-11 17:10:13 +00:00
Compare commits
50 Commits
d26143bb38
...
f8f9c1f4d0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f8f9c1f4d0 | ||
|
|
c875a6c324 | ||
|
|
15225b910c | ||
|
|
1c55bc8710 | ||
|
|
03de3e44a7 | ||
|
|
cd80afff48 | ||
|
|
c48c0fd0e1 | ||
|
|
22201800f1 | ||
|
|
e7a9f66001 | ||
|
|
2e46b4e024 | ||
|
|
174e7d0f47 | ||
|
|
784b756dde | ||
|
|
df3e316930 | ||
|
|
0dc580d4a6 | ||
|
|
8ff242c041 | ||
|
|
ad6fb7367e | ||
|
|
b4c61e542f | ||
|
|
b4b64fda4d | ||
|
|
782be79e45 | ||
|
|
5106dbab44 | ||
|
|
0831269b5f | ||
|
|
267ee93c41 | ||
|
|
c3ca8a0aac | ||
|
|
f54151148b | ||
|
|
608328ba5b | ||
|
|
fbe409d138 | ||
|
|
b94b735675 | ||
|
|
f1164534ad | ||
|
|
42f53b3900 | ||
|
|
c2296a1e42 | ||
|
|
5efaf92da4 | ||
|
|
f02dd25472 | ||
|
|
6118ebed3b | ||
|
|
3f0cbfb8a1 | ||
|
|
4115155baf | ||
|
|
e0e51a0de0 | ||
|
|
425cc087fb | ||
|
|
1e6084d5c4 | ||
|
|
818d78ba1b | ||
|
|
5edb7338d6 | ||
|
|
24ec03cc55 | ||
|
|
3b4961313d | ||
|
|
14ad4c10d5 | ||
|
|
c84117912b | ||
|
|
128bb7fab3 | ||
|
|
41ca62e3e2 | ||
|
|
36cc7e09df | ||
|
|
d14cd998e6 | ||
|
|
e1003aa7ec | ||
|
|
74098cc06e |
@ -281,6 +281,14 @@ The following keys are defined:
|
||||
* :c:macro:`RISCV_HWPROBE_EXT_ZICBOP`: The Zicbop extension is supported, as
|
||||
ratified in commit 3dd606f ("Create cmobase-v1.0.pdf") of riscv-CMOs.
|
||||
|
||||
* :c:macro:`RISCV_HWPROBE_EXT_ZILSD`: The Zilsd extension is supported as
|
||||
defined in the RISC-V ISA manual starting from commit f88abf1 ("Integrating
|
||||
load/store pair for RV32 with the main manual") of the riscv-isa-manual.
|
||||
|
||||
* :c:macro:`RISCV_HWPROBE_EXT_ZCLSD`: The Zclsd extension is supported as
|
||||
defined in the RISC-V ISA manual starting from commit f88abf1 ("Integrating
|
||||
load/store pair for RV32 with the main manual") of the riscv-isa-manual.
|
||||
|
||||
* :c:macro:`RISCV_HWPROBE_KEY_CPUPERF_0`: Deprecated. Returns similar values to
|
||||
:c:macro:`RISCV_HWPROBE_KEY_MISALIGNED_SCALAR_PERF`, but the key was
|
||||
mistakenly classified as a bitmask rather than a value.
|
||||
|
||||
@ -377,6 +377,20 @@ properties:
|
||||
guarantee on LR/SC sequences, as ratified in commit b1d806605f87
|
||||
("Updated to ratified state.") of the riscv profiles specification.
|
||||
|
||||
- const: zilsd
|
||||
description:
|
||||
The standard Zilsd extension which provides support for aligned
|
||||
register-pair load and store operations in 32-bit instruction
|
||||
encodings, as ratified in commit f88abf1 ("Integrating
|
||||
load/store pair for RV32 with the main manual") of riscv-isa-manual.
|
||||
|
||||
- const: zclsd
|
||||
description:
|
||||
The Zclsd extension implements the compressed (16-bit) version of the
|
||||
Load/Store Pair for RV32. As with Zilsd, this extension was ratified
|
||||
in commit f88abf1 ("Integrating load/store pair for RV32 with the
|
||||
main manual") of riscv-isa-manual.
|
||||
|
||||
- const: zk
|
||||
description:
|
||||
The standard Zk Standard Scalar cryptography extension as ratified
|
||||
@ -882,6 +896,16 @@ properties:
|
||||
anyOf:
|
||||
- const: v
|
||||
- const: zve32x
|
||||
# Zclsd depends on Zilsd and Zca
|
||||
- if:
|
||||
contains:
|
||||
anyOf:
|
||||
- const: zclsd
|
||||
then:
|
||||
contains:
|
||||
allOf:
|
||||
- const: zilsd
|
||||
- const: zca
|
||||
|
||||
allOf:
|
||||
# Zcf extension does not exist on rv64
|
||||
@ -899,6 +923,18 @@ allOf:
|
||||
not:
|
||||
contains:
|
||||
const: zcf
|
||||
# Zilsd extension does not exist on rv64
|
||||
- if:
|
||||
properties:
|
||||
riscv,isa-base:
|
||||
contains:
|
||||
const: rv64i
|
||||
then:
|
||||
properties:
|
||||
riscv,isa-extensions:
|
||||
not:
|
||||
contains:
|
||||
const: zilsd
|
||||
|
||||
additionalProperties: true
|
||||
...
|
||||
|
||||
2
Makefile
2
Makefile
@ -2,7 +2,7 @@
|
||||
VERSION = 6
|
||||
PATCHLEVEL = 19
|
||||
SUBLEVEL = 0
|
||||
EXTRAVERSION = -rc2
|
||||
EXTRAVERSION = -rc3
|
||||
NAME = Baby Opossum Posse
|
||||
|
||||
# *DOCUMENTATION*
|
||||
|
||||
@ -90,7 +90,7 @@ static inline void __hard_EE_RI_disable(void)
|
||||
if (IS_ENABLED(CONFIG_BOOKE))
|
||||
wrtee(0);
|
||||
else if (IS_ENABLED(CONFIG_PPC_8xx))
|
||||
wrtspr(SPRN_NRI);
|
||||
wrtspr_sync(SPRN_NRI);
|
||||
else if (IS_ENABLED(CONFIG_PPC_BOOK3S_64))
|
||||
__mtmsrd(0, 1);
|
||||
else
|
||||
|
||||
@ -1400,6 +1400,7 @@ static inline void mtmsr_isync(unsigned long val)
|
||||
: "r" ((unsigned long)(v)) \
|
||||
: "memory")
|
||||
#define wrtspr(rn) asm volatile("mtspr " __stringify(rn) ",2" : : : "memory")
|
||||
#define wrtspr_sync(rn) asm volatile("mtspr " __stringify(rn) ",2; sync" : : : "memory")
|
||||
|
||||
static inline void wrtee(unsigned long val)
|
||||
{
|
||||
|
||||
@ -20,6 +20,7 @@
|
||||
#include <asm/io.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/udbg.h>
|
||||
#include <asm/setup.h>
|
||||
|
||||
#define NO_SCROLL
|
||||
|
||||
@ -463,7 +464,7 @@ static noinline void draw_byte(unsigned char c, long locX, long locY)
|
||||
{
|
||||
unsigned char *base = calc_base(locX << 3, locY << 4);
|
||||
unsigned int font_index = c * 16;
|
||||
const unsigned char *font = font_sun_8x16.data + font_index;
|
||||
const unsigned char *font = PTRRELOC(font_sun_8x16.data) + font_index;
|
||||
int rb = dispDeviceRowBytes;
|
||||
|
||||
rmci_maybe_on();
|
||||
|
||||
@ -101,17 +101,6 @@ SYM_FUNC_END(__kuep_unlock)
|
||||
.endm
|
||||
#endif
|
||||
|
||||
.macro clr_ri trash
|
||||
#ifndef CONFIG_BOOKE
|
||||
#ifdef CONFIG_PPC_8xx
|
||||
mtspr SPRN_NRI, \trash
|
||||
#else
|
||||
li \trash, MSR_KERNEL & ~MSR_RI
|
||||
mtmsr \trash
|
||||
#endif
|
||||
#endif
|
||||
.endm
|
||||
|
||||
.globl transfer_to_syscall
|
||||
transfer_to_syscall:
|
||||
stw r3, ORIG_GPR3(r1)
|
||||
@ -160,7 +149,6 @@ ret_from_syscall:
|
||||
cmpwi r3,0
|
||||
REST_GPR(3, r1)
|
||||
syscall_exit_finish:
|
||||
clr_ri r4
|
||||
mtspr SPRN_SRR0,r7
|
||||
mtspr SPRN_SRR1,r8
|
||||
|
||||
@ -237,7 +225,6 @@ fast_exception_return:
|
||||
/* Clear the exception marker on the stack to avoid confusing stacktrace */
|
||||
li r10, 0
|
||||
stw r10, 8(r11)
|
||||
clr_ri r10
|
||||
mtspr SPRN_SRR1,r9
|
||||
mtspr SPRN_SRR0,r12
|
||||
REST_GPR(9, r11)
|
||||
@ -270,7 +257,6 @@ interrupt_return:
|
||||
.Lfast_user_interrupt_return:
|
||||
lwz r11,_NIP(r1)
|
||||
lwz r12,_MSR(r1)
|
||||
clr_ri r4
|
||||
mtspr SPRN_SRR0,r11
|
||||
mtspr SPRN_SRR1,r12
|
||||
|
||||
@ -313,7 +299,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_NEED_PAIRED_STWCX)
|
||||
cmpwi cr1,r3,0
|
||||
lwz r11,_NIP(r1)
|
||||
lwz r12,_MSR(r1)
|
||||
clr_ri r4
|
||||
mtspr SPRN_SRR0,r11
|
||||
mtspr SPRN_SRR1,r12
|
||||
|
||||
|
||||
@ -38,7 +38,7 @@ static inline bool exit_must_hard_disable(void)
|
||||
#else
|
||||
static inline bool exit_must_hard_disable(void)
|
||||
{
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -443,6 +443,9 @@ again:
|
||||
|
||||
if (unlikely(stack_store))
|
||||
__hard_EE_RI_disable();
|
||||
#else
|
||||
} else {
|
||||
__hard_EE_RI_disable();
|
||||
#endif /* CONFIG_PPC64 */
|
||||
}
|
||||
|
||||
|
||||
@ -202,6 +202,23 @@ static void kexec_prepare_cpus_wait(int wait_state)
|
||||
mb();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The add_cpu() call in wake_offline_cpus() can fail as cpu_bootable()
|
||||
* returns false for CPUs that fail the cpu_smt_thread_allowed() check
|
||||
* or non primary threads if SMT is disabled. Re-enable SMT and set the
|
||||
* number of SMT threads to threads per core.
|
||||
*/
|
||||
static void kexec_smt_reenable(void)
|
||||
{
|
||||
#if defined(CONFIG_SMP) && defined(CONFIG_HOTPLUG_SMT)
|
||||
lock_device_hotplug();
|
||||
cpu_smt_num_threads = threads_per_core;
|
||||
cpu_smt_control = CPU_SMT_ENABLED;
|
||||
unlock_device_hotplug();
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* We need to make sure each present CPU is online. The next kernel will scan
|
||||
* the device tree and assume primary threads are online and query secondary
|
||||
@ -216,6 +233,8 @@ static void wake_offline_cpus(void)
|
||||
{
|
||||
int cpu = 0;
|
||||
|
||||
kexec_smt_reenable();
|
||||
|
||||
for_each_present_cpu(cpu) {
|
||||
if (!cpu_online(cpu)) {
|
||||
printk(KERN_INFO "kexec: Waking offline cpu %d.\n",
|
||||
|
||||
@ -1171,8 +1171,9 @@ static void __init pnv_arch300_idle_init(void)
|
||||
u64 max_residency_ns = 0;
|
||||
int i;
|
||||
|
||||
/* stop is not really architected, we only have p9,p10 drivers */
|
||||
if (!pvr_version_is(PVR_POWER10) && !pvr_version_is(PVR_POWER9))
|
||||
/* stop is not really architected, we only have p9,p10 and p11 drivers */
|
||||
if (!pvr_version_is(PVR_POWER9) && !pvr_version_is(PVR_POWER10) &&
|
||||
!pvr_version_is(PVR_POWER11))
|
||||
return;
|
||||
|
||||
/*
|
||||
@ -1189,8 +1190,8 @@ static void __init pnv_arch300_idle_init(void)
|
||||
struct pnv_idle_states_t *state = &pnv_idle_states[i];
|
||||
u64 psscr_rl = state->psscr_val & PSSCR_RL_MASK;
|
||||
|
||||
/* No deep loss driver implemented for POWER10 yet */
|
||||
if (pvr_version_is(PVR_POWER10) &&
|
||||
/* No deep loss driver implemented for POWER10 and POWER11 yet */
|
||||
if ((pvr_version_is(PVR_POWER10) || pvr_version_is(PVR_POWER11)) &&
|
||||
state->flags & (OPAL_PM_TIMEBASE_STOP|OPAL_PM_LOSE_FULL_CONTEXT))
|
||||
continue;
|
||||
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
set -e
|
||||
set -o pipefail
|
||||
|
||||
# To debug, uncomment the following line
|
||||
# set -x
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
set -e
|
||||
set -o pipefail
|
||||
|
||||
# To debug, uncomment the following line
|
||||
# set -x
|
||||
|
||||
@ -203,7 +203,7 @@ ATOMIC_OPS(xor, xor, i)
|
||||
" add %[rc], %[p], %[a]\n" \
|
||||
" sc." sfx ".rl %[rc], %[rc], %[c]\n" \
|
||||
" bnez %[rc], 0b\n" \
|
||||
" fence rw, rw\n" \
|
||||
RISCV_FULL_BARRIER \
|
||||
"1:\n" \
|
||||
: [p]"=&r" (_prev), [rc]"=&r" (_rc), [c]"+A" (counter) \
|
||||
: [a]"r" (_a), [u]"r" (_u) \
|
||||
@ -242,7 +242,7 @@ static __always_inline s64 arch_atomic64_fetch_add_unless(atomic64_t *v, s64 a,
|
||||
" addi %[rc], %[p], 1\n" \
|
||||
" sc." sfx ".rl %[rc], %[rc], %[c]\n" \
|
||||
" bnez %[rc], 0b\n" \
|
||||
" fence rw, rw\n" \
|
||||
RISCV_FULL_BARRIER \
|
||||
"1:\n" \
|
||||
: [p]"=&r" (_prev), [rc]"=&r" (_rc), [c]"+A" (counter) \
|
||||
: \
|
||||
@ -268,7 +268,7 @@ static __always_inline bool arch_atomic_inc_unless_negative(atomic_t *v)
|
||||
" addi %[rc], %[p], -1\n" \
|
||||
" sc." sfx ".rl %[rc], %[rc], %[c]\n" \
|
||||
" bnez %[rc], 0b\n" \
|
||||
" fence rw, rw\n" \
|
||||
RISCV_FULL_BARRIER \
|
||||
"1:\n" \
|
||||
: [p]"=&r" (_prev), [rc]"=&r" (_rc), [c]"+A" (counter) \
|
||||
: \
|
||||
@ -294,7 +294,7 @@ static __always_inline bool arch_atomic_dec_unless_positive(atomic_t *v)
|
||||
" bltz %[rc], 1f\n" \
|
||||
" sc." sfx ".rl %[rc], %[rc], %[c]\n" \
|
||||
" bnez %[rc], 0b\n" \
|
||||
" fence rw, rw\n" \
|
||||
RISCV_FULL_BARRIER \
|
||||
"1:\n" \
|
||||
: [p]"=&r" (_prev), [rc]"=&r" (_rc), [c]"+A" (counter) \
|
||||
: \
|
||||
|
||||
@ -108,6 +108,8 @@
|
||||
#define RISCV_ISA_EXT_ZICBOP 99
|
||||
#define RISCV_ISA_EXT_SVRSW60T59B 100
|
||||
#define RISCV_ISA_EXT_ZALASR 101
|
||||
#define RISCV_ISA_EXT_ZILSD 102
|
||||
#define RISCV_ISA_EXT_ZCLSD 103
|
||||
|
||||
#define RISCV_ISA_EXT_XLINUXENVCFG 127
|
||||
|
||||
|
||||
@ -660,7 +660,13 @@ extern int ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned long a
|
||||
static inline pte_t ptep_get_and_clear(struct mm_struct *mm,
|
||||
unsigned long address, pte_t *ptep)
|
||||
{
|
||||
pte_t pte = __pte(atomic_long_xchg((atomic_long_t *)ptep, 0));
|
||||
#ifdef CONFIG_SMP
|
||||
pte_t pte = __pte(xchg(&ptep->pte, 0));
|
||||
#else
|
||||
pte_t pte = *ptep;
|
||||
|
||||
set_pte(ptep, __pte(0));
|
||||
#endif
|
||||
|
||||
page_table_check_pte_clear(mm, pte);
|
||||
|
||||
@ -997,7 +1003,13 @@ static inline int pmdp_test_and_clear_young(struct vm_area_struct *vma,
|
||||
static inline pmd_t pmdp_huge_get_and_clear(struct mm_struct *mm,
|
||||
unsigned long address, pmd_t *pmdp)
|
||||
{
|
||||
pmd_t pmd = __pmd(atomic_long_xchg((atomic_long_t *)pmdp, 0));
|
||||
#ifdef CONFIG_SMP
|
||||
pmd_t pmd = __pmd(xchg(&pmdp->pmd, 0));
|
||||
#else
|
||||
pmd_t pmd = *pmdp;
|
||||
|
||||
pmd_clear(pmdp);
|
||||
#endif
|
||||
|
||||
page_table_check_pmd_clear(mm, pmd);
|
||||
|
||||
|
||||
@ -37,6 +37,7 @@ enum sbi_ext_id {
|
||||
SBI_EXT_NACL = 0x4E41434C,
|
||||
SBI_EXT_FWFT = 0x46574654,
|
||||
SBI_EXT_MPXY = 0x4D505859,
|
||||
SBI_EXT_DBTR = 0x44425452,
|
||||
|
||||
/* Experimentals extensions must lie within this range */
|
||||
SBI_EXT_EXPERIMENTAL_START = 0x08000000,
|
||||
@ -505,6 +506,34 @@ enum sbi_mpxy_rpmi_attribute_id {
|
||||
#define SBI_MPXY_CHAN_CAP_SEND_WITHOUT_RESP BIT(4)
|
||||
#define SBI_MPXY_CHAN_CAP_GET_NOTIFICATIONS BIT(5)
|
||||
|
||||
/* SBI debug triggers function IDs */
|
||||
enum sbi_ext_dbtr_fid {
|
||||
SBI_EXT_DBTR_NUM_TRIGGERS = 0,
|
||||
SBI_EXT_DBTR_SETUP_SHMEM,
|
||||
SBI_EXT_DBTR_TRIG_READ,
|
||||
SBI_EXT_DBTR_TRIG_INSTALL,
|
||||
SBI_EXT_DBTR_TRIG_UPDATE,
|
||||
SBI_EXT_DBTR_TRIG_UNINSTALL,
|
||||
SBI_EXT_DBTR_TRIG_ENABLE,
|
||||
SBI_EXT_DBTR_TRIG_DISABLE,
|
||||
};
|
||||
|
||||
struct sbi_dbtr_data_msg {
|
||||
unsigned long tstate;
|
||||
unsigned long tdata1;
|
||||
unsigned long tdata2;
|
||||
unsigned long tdata3;
|
||||
};
|
||||
|
||||
struct sbi_dbtr_id_msg {
|
||||
unsigned long idx;
|
||||
};
|
||||
|
||||
union sbi_dbtr_shmem_entry {
|
||||
struct sbi_dbtr_data_msg data;
|
||||
struct sbi_dbtr_id_msg id;
|
||||
};
|
||||
|
||||
/* SBI spec version fields */
|
||||
#define SBI_SPEC_VERSION_DEFAULT 0x1
|
||||
#define SBI_SPEC_VERSION_MAJOR_SHIFT 24
|
||||
|
||||
@ -424,6 +424,9 @@ static inline bool riscv_v_vstate_ctrl_user_allowed(void) { return false; }
|
||||
#define riscv_v_thread_free(tsk) do {} while (0)
|
||||
#define riscv_v_setup_ctx_cache() do {} while (0)
|
||||
#define riscv_v_thread_alloc(tsk) do {} while (0)
|
||||
#define get_cpu_vector_context() do {} while (0)
|
||||
#define put_cpu_vector_context() do {} while (0)
|
||||
#define riscv_v_vstate_set_restore(task, regs) do {} while (0)
|
||||
|
||||
#endif /* CONFIG_RISCV_ISA_V */
|
||||
|
||||
|
||||
@ -84,6 +84,9 @@ struct riscv_hwprobe {
|
||||
#define RISCV_HWPROBE_EXT_ZABHA (1ULL << 58)
|
||||
#define RISCV_HWPROBE_EXT_ZALASR (1ULL << 59)
|
||||
#define RISCV_HWPROBE_EXT_ZICBOP (1ULL << 60)
|
||||
#define RISCV_HWPROBE_EXT_ZILSD (1ULL << 61)
|
||||
#define RISCV_HWPROBE_EXT_ZCLSD (1ULL << 62)
|
||||
|
||||
#define RISCV_HWPROBE_KEY_CPUPERF_0 5
|
||||
#define RISCV_HWPROBE_MISALIGNED_UNKNOWN (0 << 0)
|
||||
#define RISCV_HWPROBE_MISALIGNED_EMULATED (1 << 0)
|
||||
|
||||
@ -242,6 +242,28 @@ static int riscv_ext_zcf_validate(const struct riscv_isa_ext_data *data,
|
||||
return -EPROBE_DEFER;
|
||||
}
|
||||
|
||||
static int riscv_ext_zilsd_validate(const struct riscv_isa_ext_data *data,
|
||||
const unsigned long *isa_bitmap)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_64BIT))
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int riscv_ext_zclsd_validate(const struct riscv_isa_ext_data *data,
|
||||
const unsigned long *isa_bitmap)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_64BIT))
|
||||
return -EINVAL;
|
||||
|
||||
if (__riscv_isa_extension_available(isa_bitmap, RISCV_ISA_EXT_ZILSD) &&
|
||||
__riscv_isa_extension_available(isa_bitmap, RISCV_ISA_EXT_ZCA))
|
||||
return 0;
|
||||
|
||||
return -EPROBE_DEFER;
|
||||
}
|
||||
|
||||
static int riscv_vector_f_validate(const struct riscv_isa_ext_data *data,
|
||||
const unsigned long *isa_bitmap)
|
||||
{
|
||||
@ -484,6 +506,8 @@ const struct riscv_isa_ext_data riscv_isa_ext[] = {
|
||||
__RISCV_ISA_EXT_DATA_VALIDATE(zcd, RISCV_ISA_EXT_ZCD, riscv_ext_zcd_validate),
|
||||
__RISCV_ISA_EXT_DATA_VALIDATE(zcf, RISCV_ISA_EXT_ZCF, riscv_ext_zcf_validate),
|
||||
__RISCV_ISA_EXT_DATA_VALIDATE(zcmop, RISCV_ISA_EXT_ZCMOP, riscv_ext_zca_depends),
|
||||
__RISCV_ISA_EXT_DATA_VALIDATE(zclsd, RISCV_ISA_EXT_ZCLSD, riscv_ext_zclsd_validate),
|
||||
__RISCV_ISA_EXT_DATA_VALIDATE(zilsd, RISCV_ISA_EXT_ZILSD, riscv_ext_zilsd_validate),
|
||||
__RISCV_ISA_EXT_DATA(zba, RISCV_ISA_EXT_ZBA),
|
||||
__RISCV_ISA_EXT_DATA(zbb, RISCV_ISA_EXT_ZBB),
|
||||
__RISCV_ISA_EXT_DATA(zbc, RISCV_ISA_EXT_ZBC),
|
||||
|
||||
@ -68,18 +68,19 @@ static long save_fp_state(struct pt_regs *regs,
|
||||
#define restore_fp_state(task, regs) (0)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_RISCV_ISA_V
|
||||
|
||||
static long save_v_state(struct pt_regs *regs, void __user **sc_vec)
|
||||
static long save_v_state(struct pt_regs *regs, void __user *sc_vec)
|
||||
{
|
||||
struct __riscv_ctx_hdr __user *hdr;
|
||||
struct __sc_riscv_v_state __user *state;
|
||||
void __user *datap;
|
||||
long err;
|
||||
|
||||
hdr = *sc_vec;
|
||||
/* Place state to the user's signal context space after the hdr */
|
||||
state = (struct __sc_riscv_v_state __user *)(hdr + 1);
|
||||
if (!IS_ENABLED(CONFIG_RISCV_ISA_V) ||
|
||||
!((has_vector() || has_xtheadvector()) &&
|
||||
riscv_v_vstate_query(regs)))
|
||||
return 0;
|
||||
|
||||
/* Place state to the user's signal context space */
|
||||
state = (struct __sc_riscv_v_state __user *)sc_vec;
|
||||
/* Point datap right after the end of __sc_riscv_v_state */
|
||||
datap = state + 1;
|
||||
|
||||
@ -97,15 +98,11 @@ static long save_v_state(struct pt_regs *regs, void __user **sc_vec)
|
||||
err |= __put_user((__force void *)datap, &state->v_state.datap);
|
||||
/* Copy the whole vector content to user space datap. */
|
||||
err |= __copy_to_user(datap, current->thread.vstate.datap, riscv_v_vsize);
|
||||
/* Copy magic to the user space after saving all vector conetext */
|
||||
err |= __put_user(RISCV_V_MAGIC, &hdr->magic);
|
||||
err |= __put_user(riscv_v_sc_size, &hdr->size);
|
||||
if (unlikely(err))
|
||||
return err;
|
||||
return -EFAULT;
|
||||
|
||||
/* Only progress the sv_vec if everything has done successfully */
|
||||
*sc_vec += riscv_v_sc_size;
|
||||
return 0;
|
||||
/* Only return the size if everything has done successfully */
|
||||
return riscv_v_sc_size;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -142,10 +139,20 @@ static long __restore_v_state(struct pt_regs *regs, void __user *sc_vec)
|
||||
*/
|
||||
return copy_from_user(current->thread.vstate.datap, datap, riscv_v_vsize);
|
||||
}
|
||||
#else
|
||||
#define save_v_state(task, regs) (0)
|
||||
#define __restore_v_state(task, regs) (0)
|
||||
#endif
|
||||
|
||||
struct arch_ext_priv {
|
||||
__u32 magic;
|
||||
long (*save)(struct pt_regs *regs, void __user *sc_vec);
|
||||
};
|
||||
|
||||
struct arch_ext_priv arch_ext_list[] = {
|
||||
{
|
||||
.magic = RISCV_V_MAGIC,
|
||||
.save = &save_v_state,
|
||||
},
|
||||
};
|
||||
|
||||
const size_t nr_arch_exts = ARRAY_SIZE(arch_ext_list);
|
||||
|
||||
static long restore_sigcontext(struct pt_regs *regs,
|
||||
struct sigcontext __user *sc)
|
||||
@ -270,7 +277,8 @@ static long setup_sigcontext(struct rt_sigframe __user *frame,
|
||||
{
|
||||
struct sigcontext __user *sc = &frame->uc.uc_mcontext;
|
||||
struct __riscv_ctx_hdr __user *sc_ext_ptr = &sc->sc_extdesc.hdr;
|
||||
long err;
|
||||
struct arch_ext_priv *arch_ext;
|
||||
long err, i, ext_size;
|
||||
|
||||
/* sc_regs is structured the same as the start of pt_regs */
|
||||
err = __copy_to_user(&sc->sc_regs, regs, sizeof(sc->sc_regs));
|
||||
@ -278,8 +286,20 @@ static long setup_sigcontext(struct rt_sigframe __user *frame,
|
||||
if (has_fpu())
|
||||
err |= save_fp_state(regs, &sc->sc_fpregs);
|
||||
/* Save the vector state. */
|
||||
if ((has_vector() || has_xtheadvector()) && riscv_v_vstate_query(regs))
|
||||
err |= save_v_state(regs, (void __user **)&sc_ext_ptr);
|
||||
for (i = 0; i < nr_arch_exts; i++) {
|
||||
arch_ext = &arch_ext_list[i];
|
||||
if (!arch_ext->save)
|
||||
continue;
|
||||
|
||||
ext_size = arch_ext->save(regs, sc_ext_ptr + 1);
|
||||
if (ext_size <= 0) {
|
||||
err |= ext_size;
|
||||
} else {
|
||||
err |= __put_user(arch_ext->magic, &sc_ext_ptr->magic);
|
||||
err |= __put_user(ext_size, &sc_ext_ptr->size);
|
||||
sc_ext_ptr = (void *)sc_ext_ptr + ext_size;
|
||||
}
|
||||
}
|
||||
/* Write zero to fp-reserved space and check it on restore_sigcontext */
|
||||
err |= __put_user(0, &sc->sc_extdesc.reserved);
|
||||
/* And put END __riscv_ctx_hdr at the end. */
|
||||
|
||||
@ -121,6 +121,7 @@ static void hwprobe_isa_ext0(struct riscv_hwprobe *pair,
|
||||
EXT_KEY(ZBS);
|
||||
EXT_KEY(ZCA);
|
||||
EXT_KEY(ZCB);
|
||||
EXT_KEY(ZCLSD);
|
||||
EXT_KEY(ZCMOP);
|
||||
EXT_KEY(ZICBOM);
|
||||
EXT_KEY(ZICBOP);
|
||||
@ -130,6 +131,7 @@ static void hwprobe_isa_ext0(struct riscv_hwprobe *pair,
|
||||
EXT_KEY(ZIHINTNTL);
|
||||
EXT_KEY(ZIHINTPAUSE);
|
||||
EXT_KEY(ZIHPM);
|
||||
EXT_KEY(ZILSD);
|
||||
EXT_KEY(ZIMOP);
|
||||
EXT_KEY(ZKND);
|
||||
EXT_KEY(ZKNE);
|
||||
|
||||
@ -36,6 +36,8 @@
|
||||
|
||||
static char driver_name[] = KBUILD_MODNAME;
|
||||
|
||||
#define RCV_BUFFER_SIZE (16 * 1024)
|
||||
|
||||
/* this is the physical layout of a PCL, its size is 128 bytes */
|
||||
struct pcl {
|
||||
__le32 next;
|
||||
@ -517,16 +519,14 @@ remove_card(struct pci_dev *dev)
|
||||
lynx->rcv_start_pcl, lynx->rcv_start_pcl_bus);
|
||||
dma_free_coherent(&lynx->pci_device->dev, sizeof(struct pcl),
|
||||
lynx->rcv_pcl, lynx->rcv_pcl_bus);
|
||||
dma_free_coherent(&lynx->pci_device->dev, PAGE_SIZE, lynx->rcv_buffer,
|
||||
lynx->rcv_buffer_bus);
|
||||
dma_free_coherent(&lynx->pci_device->dev, RCV_BUFFER_SIZE,
|
||||
lynx->rcv_buffer, lynx->rcv_buffer_bus);
|
||||
|
||||
iounmap(lynx->registers);
|
||||
pci_disable_device(dev);
|
||||
lynx_put(lynx);
|
||||
}
|
||||
|
||||
#define RCV_BUFFER_SIZE (16 * 1024)
|
||||
|
||||
static int
|
||||
add_card(struct pci_dev *dev, const struct pci_device_id *unused)
|
||||
{
|
||||
@ -680,7 +680,7 @@ fail_deallocate_buffers:
|
||||
dma_free_coherent(&lynx->pci_device->dev, sizeof(struct pcl),
|
||||
lynx->rcv_pcl, lynx->rcv_pcl_bus);
|
||||
if (lynx->rcv_buffer)
|
||||
dma_free_coherent(&lynx->pci_device->dev, PAGE_SIZE,
|
||||
dma_free_coherent(&lynx->pci_device->dev, RCV_BUFFER_SIZE,
|
||||
lynx->rcv_buffer, lynx->rcv_buffer_bus);
|
||||
iounmap(lynx->registers);
|
||||
|
||||
|
||||
@ -128,8 +128,8 @@ static int loongson_uart_probe(struct platform_device *pdev)
|
||||
port->private_data = priv;
|
||||
|
||||
port->membase = devm_platform_get_and_ioremap_resource(pdev, 0, &priv->res);
|
||||
if (!port->membase)
|
||||
return -ENOMEM;
|
||||
if (IS_ERR(port->membase))
|
||||
return PTR_ERR(port->membase);
|
||||
|
||||
port->mapbase = priv->res->start;
|
||||
port->mapsize = resource_size(priv->res);
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
#include <linux/device.h>
|
||||
#include <linux/idr.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/serial_core.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/spinlock.h>
|
||||
@ -60,6 +60,7 @@ void serial_base_driver_unregister(struct device_driver *driver)
|
||||
driver_unregister(driver);
|
||||
}
|
||||
|
||||
/* On failure the caller must put device @dev with put_device() */
|
||||
static int serial_base_device_init(struct uart_port *port,
|
||||
struct device *dev,
|
||||
struct device *parent_dev,
|
||||
@ -73,7 +74,9 @@ static int serial_base_device_init(struct uart_port *port,
|
||||
dev->parent = parent_dev;
|
||||
dev->bus = &serial_base_bus_type;
|
||||
dev->release = release;
|
||||
device_set_of_node_from_dev(dev, parent_dev);
|
||||
dev->of_node_reused = true;
|
||||
|
||||
device_set_node(dev, fwnode_handle_get(dev_fwnode(parent_dev)));
|
||||
|
||||
if (!serial_base_initialized) {
|
||||
dev_dbg(port->dev, "uart_add_one_port() called before arch_initcall()?\n");
|
||||
@ -94,7 +97,7 @@ static void serial_base_ctrl_release(struct device *dev)
|
||||
{
|
||||
struct serial_ctrl_device *ctrl_dev = to_serial_base_ctrl_device(dev);
|
||||
|
||||
of_node_put(dev->of_node);
|
||||
fwnode_handle_put(dev_fwnode(dev));
|
||||
kfree(ctrl_dev);
|
||||
}
|
||||
|
||||
@ -142,7 +145,7 @@ static void serial_base_port_release(struct device *dev)
|
||||
{
|
||||
struct serial_port_device *port_dev = to_serial_base_port_device(dev);
|
||||
|
||||
of_node_put(dev->of_node);
|
||||
fwnode_handle_put(dev_fwnode(dev));
|
||||
kfree(port_dev);
|
||||
}
|
||||
|
||||
|
||||
@ -1914,7 +1914,7 @@ static void sci_dma_check_tx_occurred(struct sci_port *s)
|
||||
struct dma_tx_state state;
|
||||
enum dma_status status;
|
||||
|
||||
if (!s->chan_tx)
|
||||
if (!s->chan_tx || s->cookie_tx <= 0)
|
||||
return;
|
||||
|
||||
status = dmaengine_tx_status(s->chan_tx, s->cookie_tx, &state);
|
||||
|
||||
@ -428,10 +428,17 @@ static void cdns_uart_handle_tx(void *dev_id)
|
||||
struct tty_port *tport = &port->state->port;
|
||||
unsigned int numbytes;
|
||||
unsigned char ch;
|
||||
ktime_t rts_delay;
|
||||
|
||||
if (kfifo_is_empty(&tport->xmit_fifo) || uart_tx_stopped(port)) {
|
||||
/* Disable the TX Empty interrupt */
|
||||
writel(CDNS_UART_IXR_TXEMPTY, port->membase + CDNS_UART_IDR);
|
||||
/* Set RTS line after delay */
|
||||
if (cdns_uart->port->rs485.flags & SER_RS485_ENABLED) {
|
||||
cdns_uart->tx_timer.function = &cdns_rs485_rx_callback;
|
||||
rts_delay = ns_to_ktime(cdns_calc_after_tx_delay(cdns_uart));
|
||||
hrtimer_start(&cdns_uart->tx_timer, rts_delay, HRTIMER_MODE_REL);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@ -448,13 +455,6 @@ static void cdns_uart_handle_tx(void *dev_id)
|
||||
|
||||
/* Enable the TX Empty interrupt */
|
||||
writel(CDNS_UART_IXR_TXEMPTY, cdns_uart->port->membase + CDNS_UART_IER);
|
||||
|
||||
if (cdns_uart->port->rs485.flags & SER_RS485_ENABLED &&
|
||||
(kfifo_is_empty(&tport->xmit_fifo) || uart_tx_stopped(port))) {
|
||||
hrtimer_update_function(&cdns_uart->tx_timer, cdns_rs485_rx_callback);
|
||||
hrtimer_start(&cdns_uart->tx_timer,
|
||||
ns_to_ktime(cdns_calc_after_tx_delay(cdns_uart)), HRTIMER_MODE_REL);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -70,11 +70,11 @@ static int dwc3_of_simple_probe(struct platform_device *pdev)
|
||||
simple->num_clocks = ret;
|
||||
ret = clk_bulk_prepare_enable(simple->num_clocks, simple->clks);
|
||||
if (ret)
|
||||
goto err_resetc_assert;
|
||||
goto err_clk_put_all;
|
||||
|
||||
ret = of_platform_populate(np, NULL, NULL, dev);
|
||||
if (ret)
|
||||
goto err_clk_put;
|
||||
goto err_clk_disable;
|
||||
|
||||
pm_runtime_set_active(dev);
|
||||
pm_runtime_enable(dev);
|
||||
@ -82,8 +82,9 @@ static int dwc3_of_simple_probe(struct platform_device *pdev)
|
||||
|
||||
return 0;
|
||||
|
||||
err_clk_put:
|
||||
err_clk_disable:
|
||||
clk_bulk_disable_unprepare(simple->num_clocks, simple->clks);
|
||||
err_clk_put_all:
|
||||
clk_bulk_put_all(simple->num_clocks, simple->clks);
|
||||
|
||||
err_resetc_assert:
|
||||
|
||||
@ -4826,7 +4826,7 @@ void dwc3_gadget_exit(struct dwc3 *dwc)
|
||||
if (!dwc->gadget)
|
||||
return;
|
||||
|
||||
dwc3_enable_susphy(dwc, false);
|
||||
dwc3_enable_susphy(dwc, true);
|
||||
usb_del_gadget(dwc->gadget);
|
||||
dwc3_gadget_free_endpoints(dwc);
|
||||
usb_put_gadget(dwc->gadget);
|
||||
|
||||
@ -227,7 +227,7 @@ void dwc3_host_exit(struct dwc3 *dwc)
|
||||
if (dwc->sys_wakeup)
|
||||
device_init_wakeup(&dwc->xhci->dev, false);
|
||||
|
||||
dwc3_enable_susphy(dwc, false);
|
||||
dwc3_enable_susphy(dwc, true);
|
||||
platform_device_unregister(dwc->xhci);
|
||||
dwc->xhci = NULL;
|
||||
}
|
||||
|
||||
@ -3020,7 +3020,7 @@ static int lpc32xx_udc_probe(struct platform_device *pdev)
|
||||
pdev->dev.dma_mask = &lpc32xx_usbd_dmamask;
|
||||
retval = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
|
||||
if (retval)
|
||||
return retval;
|
||||
goto err_put_client;
|
||||
|
||||
udc->board = &lpc32xx_usbddata;
|
||||
|
||||
@ -3038,28 +3038,32 @@ static int lpc32xx_udc_probe(struct platform_device *pdev)
|
||||
/* Get IRQs */
|
||||
for (i = 0; i < 4; i++) {
|
||||
udc->udp_irq[i] = platform_get_irq(pdev, i);
|
||||
if (udc->udp_irq[i] < 0)
|
||||
return udc->udp_irq[i];
|
||||
if (udc->udp_irq[i] < 0) {
|
||||
retval = udc->udp_irq[i];
|
||||
goto err_put_client;
|
||||
}
|
||||
}
|
||||
|
||||
udc->udp_baseaddr = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(udc->udp_baseaddr)) {
|
||||
dev_err(udc->dev, "IO map failure\n");
|
||||
return PTR_ERR(udc->udp_baseaddr);
|
||||
retval = PTR_ERR(udc->udp_baseaddr);
|
||||
goto err_put_client;
|
||||
}
|
||||
|
||||
/* Get USB device clock */
|
||||
udc->usb_slv_clk = devm_clk_get(&pdev->dev, NULL);
|
||||
if (IS_ERR(udc->usb_slv_clk)) {
|
||||
dev_err(udc->dev, "failed to acquire USB device clock\n");
|
||||
return PTR_ERR(udc->usb_slv_clk);
|
||||
retval = PTR_ERR(udc->usb_slv_clk);
|
||||
goto err_put_client;
|
||||
}
|
||||
|
||||
/* Enable USB device clock */
|
||||
retval = clk_prepare_enable(udc->usb_slv_clk);
|
||||
if (retval < 0) {
|
||||
dev_err(udc->dev, "failed to start USB device clock\n");
|
||||
return retval;
|
||||
goto err_put_client;
|
||||
}
|
||||
|
||||
/* Setup deferred workqueue data */
|
||||
@ -3080,7 +3084,7 @@ static int lpc32xx_udc_probe(struct platform_device *pdev)
|
||||
if (!udc->udca_v_base) {
|
||||
dev_err(udc->dev, "error getting UDCA region\n");
|
||||
retval = -ENOMEM;
|
||||
goto i2c_fail;
|
||||
goto err_disable_clk;
|
||||
}
|
||||
udc->udca_p_base = dma_handle;
|
||||
dev_dbg(udc->dev, "DMA buffer(0x%x bytes), P:0x%08x, V:0x%p\n",
|
||||
@ -3093,7 +3097,7 @@ static int lpc32xx_udc_probe(struct platform_device *pdev)
|
||||
if (!udc->dd_cache) {
|
||||
dev_err(udc->dev, "error getting DD DMA region\n");
|
||||
retval = -ENOMEM;
|
||||
goto dma_alloc_fail;
|
||||
goto err_free_dma;
|
||||
}
|
||||
|
||||
/* Clear USB peripheral and initialize gadget endpoints */
|
||||
@ -3107,14 +3111,14 @@ static int lpc32xx_udc_probe(struct platform_device *pdev)
|
||||
if (retval < 0) {
|
||||
dev_err(udc->dev, "LP request irq %d failed\n",
|
||||
udc->udp_irq[IRQ_USB_LP]);
|
||||
goto irq_req_fail;
|
||||
goto err_destroy_pool;
|
||||
}
|
||||
retval = devm_request_irq(dev, udc->udp_irq[IRQ_USB_HP],
|
||||
lpc32xx_usb_hp_irq, 0, "udc_hp", udc);
|
||||
if (retval < 0) {
|
||||
dev_err(udc->dev, "HP request irq %d failed\n",
|
||||
udc->udp_irq[IRQ_USB_HP]);
|
||||
goto irq_req_fail;
|
||||
goto err_destroy_pool;
|
||||
}
|
||||
|
||||
retval = devm_request_irq(dev, udc->udp_irq[IRQ_USB_DEVDMA],
|
||||
@ -3122,7 +3126,7 @@ static int lpc32xx_udc_probe(struct platform_device *pdev)
|
||||
if (retval < 0) {
|
||||
dev_err(udc->dev, "DEV request irq %d failed\n",
|
||||
udc->udp_irq[IRQ_USB_DEVDMA]);
|
||||
goto irq_req_fail;
|
||||
goto err_destroy_pool;
|
||||
}
|
||||
|
||||
/* The transceiver interrupt is used for VBUS detection and will
|
||||
@ -3133,7 +3137,7 @@ static int lpc32xx_udc_probe(struct platform_device *pdev)
|
||||
if (retval < 0) {
|
||||
dev_err(udc->dev, "VBUS request irq %d failed\n",
|
||||
udc->udp_irq[IRQ_USB_ATX]);
|
||||
goto irq_req_fail;
|
||||
goto err_destroy_pool;
|
||||
}
|
||||
|
||||
/* Initialize wait queue */
|
||||
@ -3142,7 +3146,7 @@ static int lpc32xx_udc_probe(struct platform_device *pdev)
|
||||
|
||||
retval = usb_add_gadget_udc(dev, &udc->gadget);
|
||||
if (retval < 0)
|
||||
goto add_gadget_fail;
|
||||
goto err_destroy_pool;
|
||||
|
||||
dev_set_drvdata(dev, udc);
|
||||
device_init_wakeup(dev, 1);
|
||||
@ -3154,14 +3158,16 @@ static int lpc32xx_udc_probe(struct platform_device *pdev)
|
||||
dev_info(udc->dev, "%s version %s\n", driver_name, DRIVER_VERSION);
|
||||
return 0;
|
||||
|
||||
add_gadget_fail:
|
||||
irq_req_fail:
|
||||
err_destroy_pool:
|
||||
dma_pool_destroy(udc->dd_cache);
|
||||
dma_alloc_fail:
|
||||
err_free_dma:
|
||||
dma_free_coherent(&pdev->dev, UDCA_BUFF_SIZE,
|
||||
udc->udca_v_base, udc->udca_p_base);
|
||||
i2c_fail:
|
||||
err_disable_clk:
|
||||
clk_disable_unprepare(udc->usb_slv_clk);
|
||||
err_put_client:
|
||||
put_device(&udc->isp1301_i2c_client->dev);
|
||||
|
||||
dev_err(udc->dev, "%s probe failed, %d\n", driver_name, retval);
|
||||
|
||||
return retval;
|
||||
@ -3190,6 +3196,8 @@ static void lpc32xx_udc_remove(struct platform_device *pdev)
|
||||
udc->udca_v_base, udc->udca_p_base);
|
||||
|
||||
clk_disable_unprepare(udc->usb_slv_clk);
|
||||
|
||||
put_device(&udc->isp1301_i2c_client->dev);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
|
||||
@ -169,13 +169,13 @@ static int ohci_hcd_nxp_probe(struct platform_device *pdev)
|
||||
|
||||
ret = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
|
||||
if (ret)
|
||||
goto fail_disable;
|
||||
goto err_put_client;
|
||||
|
||||
dev_dbg(&pdev->dev, "%s: " DRIVER_DESC " (nxp)\n", hcd_name);
|
||||
if (usb_disabled()) {
|
||||
dev_err(&pdev->dev, "USB is disabled\n");
|
||||
ret = -ENODEV;
|
||||
goto fail_disable;
|
||||
goto err_put_client;
|
||||
}
|
||||
|
||||
/* Enable USB host clock */
|
||||
@ -183,7 +183,7 @@ static int ohci_hcd_nxp_probe(struct platform_device *pdev)
|
||||
if (IS_ERR(usb_host_clk)) {
|
||||
dev_err(&pdev->dev, "failed to acquire and start USB OHCI clock\n");
|
||||
ret = PTR_ERR(usb_host_clk);
|
||||
goto fail_disable;
|
||||
goto err_put_client;
|
||||
}
|
||||
|
||||
isp1301_configure();
|
||||
@ -192,13 +192,13 @@ static int ohci_hcd_nxp_probe(struct platform_device *pdev)
|
||||
if (!hcd) {
|
||||
dev_err(&pdev->dev, "Failed to allocate HC buffer\n");
|
||||
ret = -ENOMEM;
|
||||
goto fail_disable;
|
||||
goto err_put_client;
|
||||
}
|
||||
|
||||
hcd->regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
|
||||
if (IS_ERR(hcd->regs)) {
|
||||
ret = PTR_ERR(hcd->regs);
|
||||
goto fail_resource;
|
||||
goto err_put_hcd;
|
||||
}
|
||||
hcd->rsrc_start = res->start;
|
||||
hcd->rsrc_len = resource_size(res);
|
||||
@ -206,7 +206,7 @@ static int ohci_hcd_nxp_probe(struct platform_device *pdev)
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq < 0) {
|
||||
ret = -ENXIO;
|
||||
goto fail_resource;
|
||||
goto err_put_hcd;
|
||||
}
|
||||
|
||||
ohci_nxp_start_hc();
|
||||
@ -220,9 +220,10 @@ static int ohci_hcd_nxp_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
ohci_nxp_stop_hc();
|
||||
fail_resource:
|
||||
err_put_hcd:
|
||||
usb_put_hcd(hcd);
|
||||
fail_disable:
|
||||
err_put_client:
|
||||
put_device(&isp1301_i2c_client->dev);
|
||||
isp1301_i2c_client = NULL;
|
||||
return ret;
|
||||
}
|
||||
@ -234,6 +235,7 @@ static void ohci_hcd_nxp_remove(struct platform_device *pdev)
|
||||
usb_remove_hcd(hcd);
|
||||
ohci_nxp_stop_hc();
|
||||
usb_put_hcd(hcd);
|
||||
put_device(&isp1301_i2c_client->dev);
|
||||
isp1301_i2c_client = NULL;
|
||||
}
|
||||
|
||||
|
||||
@ -554,7 +554,7 @@ static void xhci_dbc_tty_unregister_device(struct xhci_dbc *dbc)
|
||||
* Hang up the TTY. This wakes up any blocked
|
||||
* writers and causes subsequent writes to fail.
|
||||
*/
|
||||
tty_vhangup(port->port.tty);
|
||||
tty_port_tty_vhangup(&port->port);
|
||||
|
||||
tty_unregister_device(dbc_tty_driver, port->minor);
|
||||
xhci_dbc_tty_exit_port(port);
|
||||
|
||||
@ -988,6 +988,7 @@ static void fsl_otg_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct fsl_usb2_platform_data *pdata = dev_get_platdata(&pdev->dev);
|
||||
|
||||
disable_delayed_work_sync(&fsl_otg_dev->otg_event);
|
||||
usb_remove_phy(&fsl_otg_dev->phy);
|
||||
free_irq(fsl_otg_dev->irq, fsl_otg_dev);
|
||||
|
||||
|
||||
@ -149,7 +149,12 @@ struct i2c_client *isp1301_get_client(struct device_node *node)
|
||||
return client;
|
||||
|
||||
/* non-DT: only one ISP1301 chip supported */
|
||||
return isp1301_i2c_client;
|
||||
if (isp1301_i2c_client) {
|
||||
get_device(&isp1301_i2c_client->dev);
|
||||
return isp1301_i2c_client;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(isp1301_get_client);
|
||||
|
||||
|
||||
@ -713,11 +713,13 @@ struct usbhs_pipe *usbhs_pipe_malloc(struct usbhs_priv *priv,
|
||||
/* make sure pipe is not busy */
|
||||
ret = usbhsp_pipe_barrier(pipe);
|
||||
if (ret < 0) {
|
||||
usbhsp_put_pipe(pipe);
|
||||
dev_err(dev, "pipe setup failed %d\n", usbhs_pipe_number(pipe));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (usbhsp_setup_pipecfg(pipe, is_host, dir_in, &pipecfg)) {
|
||||
usbhsp_put_pipe(pipe);
|
||||
dev_err(dev, "can't setup pipe\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -98,7 +98,7 @@ UNUSUAL_DEV(0x125f, 0xa94a, 0x0160, 0x0160,
|
||||
US_FL_NO_ATA_1X),
|
||||
|
||||
/* Reported-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> */
|
||||
UNUSUAL_DEV(0x13fd, 0x3940, 0x0309, 0x0309,
|
||||
UNUSUAL_DEV(0x13fd, 0x3940, 0x0000, 0x0309,
|
||||
"Initio Corporation",
|
||||
"INIC-3069",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, NULL,
|
||||
|
||||
@ -766,12 +766,16 @@ int dp_altmode_probe(struct typec_altmode *alt)
|
||||
if (!(DP_CAP_PIN_ASSIGN_DFP_D(port->vdo) &
|
||||
DP_CAP_PIN_ASSIGN_UFP_D(alt->vdo)) &&
|
||||
!(DP_CAP_PIN_ASSIGN_UFP_D(port->vdo) &
|
||||
DP_CAP_PIN_ASSIGN_DFP_D(alt->vdo)))
|
||||
DP_CAP_PIN_ASSIGN_DFP_D(alt->vdo))) {
|
||||
typec_altmode_put_plug(plug);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
dp = devm_kzalloc(&alt->dev, sizeof(*dp), GFP_KERNEL);
|
||||
if (!dp)
|
||||
if (!dp) {
|
||||
typec_altmode_put_plug(plug);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
INIT_WORK(&dp->work, dp_altmode_work);
|
||||
mutex_init(&dp->lock);
|
||||
|
||||
@ -96,6 +96,7 @@ config UCSI_LENOVO_YOGA_C630
|
||||
config UCSI_HUAWEI_GAOKUN
|
||||
tristate "UCSI Interface Driver for Huawei Matebook E Go"
|
||||
depends on EC_HUAWEI_GAOKUN
|
||||
depends on DRM || !DRM
|
||||
select DRM_AUX_HPD_BRIDGE if DRM_BRIDGE && OF
|
||||
help
|
||||
This driver enables UCSI support on the Huawei Matebook E Go tablet,
|
||||
|
||||
@ -105,12 +105,13 @@ static int cros_ucsi_async_control(struct ucsi *ucsi, u64 cmd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cros_ucsi_sync_control(struct ucsi *ucsi, u64 cmd, u32 *cci)
|
||||
static int cros_ucsi_sync_control(struct ucsi *ucsi, u64 cmd, u32 *cci,
|
||||
void *data, size_t size)
|
||||
{
|
||||
struct cros_ucsi_data *udata = ucsi_get_drvdata(ucsi);
|
||||
int ret;
|
||||
|
||||
ret = ucsi_sync_control_common(ucsi, cmd, cci);
|
||||
ret = ucsi_sync_control_common(ucsi, cmd, cci, data, size);
|
||||
switch (ret) {
|
||||
case -EBUSY:
|
||||
/* EC may return -EBUSY if CCI.busy is set.
|
||||
|
||||
@ -37,9 +37,7 @@ static int ucsi_cmd(void *data, u64 val)
|
||||
case UCSI_SET_USB:
|
||||
case UCSI_SET_POWER_LEVEL:
|
||||
case UCSI_READ_POWER_LEVEL:
|
||||
case UCSI_SET_PDOS:
|
||||
ucsi->message_in_size = 0;
|
||||
ret = ucsi_send_command(ucsi, val);
|
||||
ret = ucsi_send_command(ucsi, val, NULL, 0);
|
||||
break;
|
||||
case UCSI_GET_CAPABILITY:
|
||||
case UCSI_GET_CONNECTOR_CAPABILITY:
|
||||
@ -54,9 +52,9 @@ static int ucsi_cmd(void *data, u64 val)
|
||||
case UCSI_GET_ATTENTION_VDO:
|
||||
case UCSI_GET_CAM_CS:
|
||||
case UCSI_GET_LPM_PPM_INFO:
|
||||
ucsi->message_in_size = sizeof(ucsi->debugfs->response);
|
||||
ret = ucsi_send_command(ucsi, val);
|
||||
memcpy(&ucsi->debugfs->response, ucsi->message_in, sizeof(ucsi->debugfs->response));
|
||||
ret = ucsi_send_command(ucsi, val,
|
||||
&ucsi->debugfs->response,
|
||||
sizeof(ucsi->debugfs->response));
|
||||
break;
|
||||
default:
|
||||
ret = -EOPNOTSUPP;
|
||||
@ -111,30 +109,6 @@ static int ucsi_vbus_volt_show(struct seq_file *m, void *v)
|
||||
}
|
||||
DEFINE_SHOW_ATTRIBUTE(ucsi_vbus_volt);
|
||||
|
||||
static ssize_t ucsi_message_out_write(struct file *file,
|
||||
const char __user *data, size_t count, loff_t *ppos)
|
||||
{
|
||||
struct ucsi *ucsi = file->private_data;
|
||||
int ret;
|
||||
|
||||
char *buf __free(kfree) = memdup_user_nul(data, count);
|
||||
if (IS_ERR(buf))
|
||||
return PTR_ERR(buf);
|
||||
|
||||
ucsi->message_out_size = min(count / 2, UCSI_MAX_MESSAGE_OUT_LENGTH);
|
||||
ret = hex2bin(ucsi->message_out, buf, ucsi->message_out_size);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static const struct file_operations ucsi_message_out_fops = {
|
||||
.open = simple_open,
|
||||
.write = ucsi_message_out_write,
|
||||
.llseek = generic_file_llseek,
|
||||
};
|
||||
|
||||
void ucsi_debugfs_register(struct ucsi *ucsi)
|
||||
{
|
||||
ucsi->debugfs = kzalloc(sizeof(*ucsi->debugfs), GFP_KERNEL);
|
||||
@ -147,8 +121,6 @@ void ucsi_debugfs_register(struct ucsi *ucsi)
|
||||
debugfs_create_file("peak_current", 0400, ucsi->debugfs->dentry, ucsi, &ucsi_peak_curr_fops);
|
||||
debugfs_create_file("avg_current", 0400, ucsi->debugfs->dentry, ucsi, &ucsi_avg_curr_fops);
|
||||
debugfs_create_file("vbus_voltage", 0400, ucsi->debugfs->dentry, ucsi, &ucsi_vbus_volt_fops);
|
||||
debugfs_create_file("message_out", 0200, ucsi->debugfs->dentry, ucsi,
|
||||
&ucsi_message_out_fops);
|
||||
}
|
||||
|
||||
void ucsi_debugfs_unregister(struct ucsi *ucsi)
|
||||
|
||||
@ -67,14 +67,11 @@ static int ucsi_displayport_enter(struct typec_altmode *alt, u32 *vdo)
|
||||
}
|
||||
|
||||
command = UCSI_GET_CURRENT_CAM | UCSI_CONNECTOR_NUMBER(dp->con->num);
|
||||
ucsi->message_in_size = sizeof(cur);
|
||||
ret = ucsi_send_command(ucsi, command);
|
||||
ret = ucsi_send_command(ucsi, command, &cur, sizeof(cur));
|
||||
if (ret < 0) {
|
||||
if (ucsi->version > 0x0100)
|
||||
goto err_unlock;
|
||||
cur = 0xff;
|
||||
} else {
|
||||
memcpy(&cur, ucsi->message_in, ucsi->message_in_size);
|
||||
}
|
||||
|
||||
if (cur != 0xff) {
|
||||
@ -129,8 +126,7 @@ static int ucsi_displayport_exit(struct typec_altmode *alt)
|
||||
}
|
||||
|
||||
command = UCSI_CMD_SET_NEW_CAM(dp->con->num, 0, dp->offset, 0);
|
||||
dp->con->ucsi->message_in_size = 0;
|
||||
ret = ucsi_send_command(dp->con->ucsi, command);
|
||||
ret = ucsi_send_command(dp->con->ucsi, command, NULL, 0);
|
||||
if (ret < 0)
|
||||
goto out_unlock;
|
||||
|
||||
@ -197,8 +193,7 @@ static int ucsi_displayport_configure(struct ucsi_dp *dp)
|
||||
|
||||
command = UCSI_CMD_SET_NEW_CAM(dp->con->num, 1, dp->offset, pins);
|
||||
|
||||
dp->con->ucsi->message_in_size = 0;
|
||||
return ucsi_send_command(dp->con->ucsi, command);
|
||||
return ucsi_send_command(dp->con->ucsi, command, NULL, 0);
|
||||
}
|
||||
|
||||
static int ucsi_displayport_vdm(struct typec_altmode *alt,
|
||||
|
||||
@ -55,7 +55,8 @@ void ucsi_notify_common(struct ucsi *ucsi, u32 cci)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ucsi_notify_common);
|
||||
|
||||
int ucsi_sync_control_common(struct ucsi *ucsi, u64 command, u32 *cci)
|
||||
int ucsi_sync_control_common(struct ucsi *ucsi, u64 command, u32 *cci,
|
||||
void *data, size_t size)
|
||||
{
|
||||
bool ack = UCSI_COMMAND(command) == UCSI_ACK_CC_CI;
|
||||
int ret;
|
||||
@ -67,20 +68,6 @@ int ucsi_sync_control_common(struct ucsi *ucsi, u64 command, u32 *cci)
|
||||
|
||||
reinit_completion(&ucsi->complete);
|
||||
|
||||
if (ucsi->message_out_size > 0) {
|
||||
if (!ucsi->ops->write_message_out) {
|
||||
ucsi->message_out_size = 0;
|
||||
ret = -EOPNOTSUPP;
|
||||
goto out_clear_bit;
|
||||
}
|
||||
|
||||
ret = ucsi->ops->write_message_out(ucsi, ucsi->message_out,
|
||||
ucsi->message_out_size);
|
||||
ucsi->message_out_size = 0;
|
||||
if (ret)
|
||||
goto out_clear_bit;
|
||||
}
|
||||
|
||||
ret = ucsi->ops->async_control(ucsi, command);
|
||||
if (ret)
|
||||
goto out_clear_bit;
|
||||
@ -97,10 +84,9 @@ out_clear_bit:
|
||||
if (!ret && cci)
|
||||
ret = ucsi->ops->read_cci(ucsi, cci);
|
||||
|
||||
if (!ret && ucsi->message_in_size > 0 &&
|
||||
if (!ret && data &&
|
||||
(*cci & UCSI_CCI_COMMAND_COMPLETE))
|
||||
ret = ucsi->ops->read_message_in(ucsi, ucsi->message_in,
|
||||
ucsi->message_in_size);
|
||||
ret = ucsi->ops->read_message_in(ucsi, data, size);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -117,25 +103,23 @@ static int ucsi_acknowledge(struct ucsi *ucsi, bool conn_ack)
|
||||
ctrl |= UCSI_ACK_CONNECTOR_CHANGE;
|
||||
}
|
||||
|
||||
ucsi->message_in_size = 0;
|
||||
return ucsi->ops->sync_control(ucsi, ctrl, NULL);
|
||||
return ucsi->ops->sync_control(ucsi, ctrl, NULL, NULL, 0);
|
||||
}
|
||||
|
||||
static int ucsi_run_command(struct ucsi *ucsi, u64 command, u32 *cci, bool conn_ack)
|
||||
static int ucsi_run_command(struct ucsi *ucsi, u64 command, u32 *cci,
|
||||
void *data, size_t size, bool conn_ack)
|
||||
{
|
||||
int ret, err;
|
||||
|
||||
*cci = 0;
|
||||
|
||||
if (ucsi->message_in_size > UCSI_MAX_DATA_LENGTH(ucsi))
|
||||
if (size > UCSI_MAX_DATA_LENGTH(ucsi))
|
||||
return -EINVAL;
|
||||
|
||||
ret = ucsi->ops->sync_control(ucsi, command, cci);
|
||||
ret = ucsi->ops->sync_control(ucsi, command, cci, data, size);
|
||||
|
||||
if (*cci & UCSI_CCI_BUSY) {
|
||||
ucsi->message_in_size = 0;
|
||||
return ucsi_run_command(ucsi, UCSI_CANCEL, cci, false) ?: -EBUSY;
|
||||
}
|
||||
if (*cci & UCSI_CCI_BUSY)
|
||||
return ucsi_run_command(ucsi, UCSI_CANCEL, cci, NULL, 0, false) ?: -EBUSY;
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@ -167,13 +151,10 @@ static int ucsi_read_error(struct ucsi *ucsi, u8 connector_num)
|
||||
int ret;
|
||||
|
||||
command = UCSI_GET_ERROR_STATUS | UCSI_CONNECTOR_NUMBER(connector_num);
|
||||
ucsi->message_in_size = sizeof(error);
|
||||
ret = ucsi_run_command(ucsi, command, &cci, false);
|
||||
ret = ucsi_run_command(ucsi, command, &cci, &error, sizeof(error), false);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
memcpy(&error, ucsi->message_in, sizeof(error));
|
||||
|
||||
switch (error) {
|
||||
case UCSI_ERROR_INCOMPATIBLE_PARTNER:
|
||||
return -EOPNOTSUPP;
|
||||
@ -219,7 +200,8 @@ static int ucsi_read_error(struct ucsi *ucsi, u8 connector_num)
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
static int ucsi_send_command_common(struct ucsi *ucsi, u64 cmd, bool conn_ack)
|
||||
static int ucsi_send_command_common(struct ucsi *ucsi, u64 cmd,
|
||||
void *data, size_t size, bool conn_ack)
|
||||
{
|
||||
u8 connector_num;
|
||||
u32 cci;
|
||||
@ -247,7 +229,7 @@ static int ucsi_send_command_common(struct ucsi *ucsi, u64 cmd, bool conn_ack)
|
||||
|
||||
mutex_lock(&ucsi->ppm_lock);
|
||||
|
||||
ret = ucsi_run_command(ucsi, cmd, &cci, conn_ack);
|
||||
ret = ucsi_run_command(ucsi, cmd, &cci, data, size, conn_ack);
|
||||
|
||||
if (cci & UCSI_CCI_ERROR)
|
||||
ret = ucsi_read_error(ucsi, connector_num);
|
||||
@ -256,9 +238,10 @@ static int ucsi_send_command_common(struct ucsi *ucsi, u64 cmd, bool conn_ack)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ucsi_send_command(struct ucsi *ucsi, u64 command)
|
||||
int ucsi_send_command(struct ucsi *ucsi, u64 command,
|
||||
void *data, size_t size)
|
||||
{
|
||||
return ucsi_send_command_common(ucsi, command, false);
|
||||
return ucsi_send_command_common(ucsi, command, data, size, false);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ucsi_send_command);
|
||||
|
||||
@ -336,8 +319,7 @@ void ucsi_altmode_update_active(struct ucsi_connector *con)
|
||||
int i;
|
||||
|
||||
command = UCSI_GET_CURRENT_CAM | UCSI_CONNECTOR_NUMBER(con->num);
|
||||
con->ucsi->message_in_size = sizeof(cur);
|
||||
ret = ucsi_send_command(con->ucsi, command);
|
||||
ret = ucsi_send_command(con->ucsi, command, &cur, sizeof(cur));
|
||||
if (ret < 0) {
|
||||
if (con->ucsi->version > 0x0100) {
|
||||
dev_err(con->ucsi->dev,
|
||||
@ -345,8 +327,6 @@ void ucsi_altmode_update_active(struct ucsi_connector *con)
|
||||
return;
|
||||
}
|
||||
cur = 0xff;
|
||||
} else {
|
||||
memcpy(&cur, con->ucsi->message_in, sizeof(cur));
|
||||
}
|
||||
|
||||
if (cur < UCSI_MAX_ALTMODES)
|
||||
@ -530,8 +510,7 @@ ucsi_register_altmodes_nvidia(struct ucsi_connector *con, u8 recipient)
|
||||
command |= UCSI_GET_ALTMODE_RECIPIENT(recipient);
|
||||
command |= UCSI_GET_ALTMODE_CONNECTOR_NUMBER(con->num);
|
||||
command |= UCSI_GET_ALTMODE_OFFSET(i);
|
||||
ucsi->message_in_size = sizeof(alt);
|
||||
len = ucsi_send_command(con->ucsi, command);
|
||||
len = ucsi_send_command(con->ucsi, command, &alt, sizeof(alt));
|
||||
/*
|
||||
* We are collecting all altmodes first and then registering.
|
||||
* Some type-C device will return zero length data beyond last
|
||||
@ -540,8 +519,6 @@ ucsi_register_altmodes_nvidia(struct ucsi_connector *con, u8 recipient)
|
||||
if (len < 0)
|
||||
return len;
|
||||
|
||||
memcpy(&alt, ucsi->message_in, sizeof(alt));
|
||||
|
||||
/* We got all altmodes, now break out and register them */
|
||||
if (!len || !alt.svid)
|
||||
break;
|
||||
@ -609,15 +586,12 @@ static int ucsi_register_altmodes(struct ucsi_connector *con, u8 recipient)
|
||||
command |= UCSI_GET_ALTMODE_RECIPIENT(recipient);
|
||||
command |= UCSI_GET_ALTMODE_CONNECTOR_NUMBER(con->num);
|
||||
command |= UCSI_GET_ALTMODE_OFFSET(i);
|
||||
con->ucsi->message_in_size = sizeof(alt);
|
||||
len = ucsi_send_command(con->ucsi, command);
|
||||
len = ucsi_send_command(con->ucsi, command, alt, sizeof(alt));
|
||||
if (len == -EBUSY)
|
||||
continue;
|
||||
if (len <= 0)
|
||||
return len;
|
||||
|
||||
memcpy(&alt, con->ucsi->message_in, sizeof(alt));
|
||||
|
||||
/*
|
||||
* This code is requesting one alt mode at a time, but some PPMs
|
||||
* may still return two. If that happens both alt modes need be
|
||||
@ -685,9 +659,7 @@ static int ucsi_get_connector_status(struct ucsi_connector *con, bool conn_ack)
|
||||
UCSI_MAX_DATA_LENGTH(con->ucsi));
|
||||
int ret;
|
||||
|
||||
con->ucsi->message_in_size = size;
|
||||
ret = ucsi_send_command_common(con->ucsi, command, conn_ack);
|
||||
memcpy(&con->status, con->ucsi->message_in, size);
|
||||
ret = ucsi_send_command_common(con->ucsi, command, &con->status, size, conn_ack);
|
||||
|
||||
return ret < 0 ? ret : 0;
|
||||
}
|
||||
@ -710,9 +682,8 @@ static int ucsi_read_pdos(struct ucsi_connector *con,
|
||||
command |= UCSI_GET_PDOS_PDO_OFFSET(offset);
|
||||
command |= UCSI_GET_PDOS_NUM_PDOS(num_pdos - 1);
|
||||
command |= is_source(role) ? UCSI_GET_PDOS_SRC_PDOS : 0;
|
||||
ucsi->message_in_size = num_pdos * sizeof(u32);
|
||||
ret = ucsi_send_command(ucsi, command);
|
||||
memcpy(pdos + offset, ucsi->message_in, num_pdos * sizeof(u32));
|
||||
ret = ucsi_send_command(ucsi, command, pdos + offset,
|
||||
num_pdos * sizeof(u32));
|
||||
if (ret < 0 && ret != -ETIMEDOUT)
|
||||
dev_err(ucsi->dev, "UCSI_GET_PDOS failed (%d)\n", ret);
|
||||
|
||||
@ -799,9 +770,7 @@ static int ucsi_get_pd_message(struct ucsi_connector *con, u8 recipient,
|
||||
command |= UCSI_GET_PD_MESSAGE_BYTES(len);
|
||||
command |= UCSI_GET_PD_MESSAGE_TYPE(type);
|
||||
|
||||
con->ucsi->message_in_size = len;
|
||||
ret = ucsi_send_command(con->ucsi, command);
|
||||
memcpy(data + offset, con->ucsi->message_in, len);
|
||||
ret = ucsi_send_command(con->ucsi, command, data + offset, len);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
@ -966,9 +935,7 @@ static int ucsi_register_cable(struct ucsi_connector *con)
|
||||
int ret;
|
||||
|
||||
command = UCSI_GET_CABLE_PROPERTY | UCSI_CONNECTOR_NUMBER(con->num);
|
||||
con->ucsi->message_in_size = sizeof(cable_prop);
|
||||
ret = ucsi_send_command(con->ucsi, command);
|
||||
memcpy(&cable_prop, con->ucsi->message_in, sizeof(cable_prop));
|
||||
ret = ucsi_send_command(con->ucsi, command, &cable_prop, sizeof(cable_prop));
|
||||
if (ret < 0) {
|
||||
dev_err(con->ucsi->dev, "GET_CABLE_PROPERTY failed (%d)\n", ret);
|
||||
return ret;
|
||||
@ -1029,9 +996,7 @@ static int ucsi_check_connector_capability(struct ucsi_connector *con)
|
||||
return 0;
|
||||
|
||||
command = UCSI_GET_CONNECTOR_CAPABILITY | UCSI_CONNECTOR_NUMBER(con->num);
|
||||
con->ucsi->message_in_size = sizeof(con->cap);
|
||||
ret = ucsi_send_command(con->ucsi, command);
|
||||
memcpy(&con->cap, con->ucsi->message_in, sizeof(con->cap));
|
||||
ret = ucsi_send_command(con->ucsi, command, &con->cap, sizeof(con->cap));
|
||||
if (ret < 0) {
|
||||
dev_err(con->ucsi->dev, "GET_CONNECTOR_CAPABILITY failed (%d)\n", ret);
|
||||
return ret;
|
||||
@ -1415,8 +1380,7 @@ static int ucsi_reset_connector(struct ucsi_connector *con, bool hard)
|
||||
else if (con->ucsi->version >= UCSI_VERSION_2_0)
|
||||
command |= hard ? 0 : UCSI_CONNECTOR_RESET_DATA_VER_2_0;
|
||||
|
||||
con->ucsi->message_in_size = 0;
|
||||
return ucsi_send_command(con->ucsi, command);
|
||||
return ucsi_send_command(con->ucsi, command, NULL, 0);
|
||||
}
|
||||
|
||||
static int ucsi_reset_ppm(struct ucsi *ucsi)
|
||||
@ -1497,8 +1461,7 @@ static int ucsi_role_cmd(struct ucsi_connector *con, u64 command)
|
||||
{
|
||||
int ret;
|
||||
|
||||
con->ucsi->message_in_size = 0;
|
||||
ret = ucsi_send_command(con->ucsi, command);
|
||||
ret = ucsi_send_command(con->ucsi, command, NULL, 0);
|
||||
if (ret == -ETIMEDOUT) {
|
||||
u64 c;
|
||||
|
||||
@ -1506,8 +1469,7 @@ static int ucsi_role_cmd(struct ucsi_connector *con, u64 command)
|
||||
ucsi_reset_ppm(con->ucsi);
|
||||
|
||||
c = UCSI_SET_NOTIFICATION_ENABLE | con->ucsi->ntfy;
|
||||
con->ucsi->message_in_size = 0;
|
||||
ucsi_send_command(con->ucsi, c);
|
||||
ucsi_send_command(con->ucsi, c, NULL, 0);
|
||||
|
||||
ucsi_reset_connector(con, true);
|
||||
}
|
||||
@ -1660,13 +1622,10 @@ static int ucsi_register_port(struct ucsi *ucsi, struct ucsi_connector *con)
|
||||
/* Get connector capability */
|
||||
command = UCSI_GET_CONNECTOR_CAPABILITY;
|
||||
command |= UCSI_CONNECTOR_NUMBER(con->num);
|
||||
ucsi->message_in_size = sizeof(con->cap);
|
||||
ret = ucsi_send_command(ucsi, command);
|
||||
ret = ucsi_send_command(ucsi, command, &con->cap, sizeof(con->cap));
|
||||
if (ret < 0)
|
||||
goto out_unlock;
|
||||
|
||||
memcpy(&con->cap, ucsi->message_in, sizeof(con->cap));
|
||||
|
||||
if (UCSI_CONCAP(con, OPMODE_DRP))
|
||||
cap->data = TYPEC_PORT_DRD;
|
||||
else if (UCSI_CONCAP(con, OPMODE_DFP))
|
||||
@ -1863,20 +1822,17 @@ static int ucsi_init(struct ucsi *ucsi)
|
||||
/* Enable basic notifications */
|
||||
ntfy = UCSI_ENABLE_NTFY_CMD_COMPLETE | UCSI_ENABLE_NTFY_ERROR;
|
||||
command = UCSI_SET_NOTIFICATION_ENABLE | ntfy;
|
||||
ucsi->message_in_size = 0;
|
||||
ret = ucsi_send_command(ucsi, command);
|
||||
ret = ucsi_send_command(ucsi, command, NULL, 0);
|
||||
if (ret < 0)
|
||||
goto err_reset;
|
||||
|
||||
/* Get PPM capabilities */
|
||||
command = UCSI_GET_CAPABILITY;
|
||||
ucsi->message_in_size = BITS_TO_BYTES(UCSI_GET_CAPABILITY_SIZE);
|
||||
ret = ucsi_send_command(ucsi, command);
|
||||
ret = ucsi_send_command(ucsi, command, &ucsi->cap,
|
||||
BITS_TO_BYTES(UCSI_GET_CAPABILITY_SIZE));
|
||||
if (ret < 0)
|
||||
goto err_reset;
|
||||
|
||||
memcpy(&ucsi->cap, ucsi->message_in, BITS_TO_BYTES(UCSI_GET_CAPABILITY_SIZE));
|
||||
|
||||
if (!ucsi->cap.num_connectors) {
|
||||
ret = -ENODEV;
|
||||
goto err_reset;
|
||||
@ -1906,8 +1862,7 @@ static int ucsi_init(struct ucsi *ucsi)
|
||||
/* Enable all supported notifications */
|
||||
ntfy = ucsi_get_supported_notifications(ucsi);
|
||||
command = UCSI_SET_NOTIFICATION_ENABLE | ntfy;
|
||||
ucsi->message_in_size = 0;
|
||||
ret = ucsi_send_command(ucsi, command);
|
||||
ret = ucsi_send_command(ucsi, command, NULL, 0);
|
||||
if (ret < 0)
|
||||
goto err_unregister;
|
||||
|
||||
@ -1958,8 +1913,7 @@ static void ucsi_resume_work(struct work_struct *work)
|
||||
|
||||
/* Restore UCSI notification enable mask after system resume */
|
||||
command = UCSI_SET_NOTIFICATION_ENABLE | ucsi->ntfy;
|
||||
ucsi->message_in_size = 0;
|
||||
ret = ucsi_send_command(ucsi, command);
|
||||
ret = ucsi_send_command(ucsi, command, NULL, 0);
|
||||
if (ret < 0) {
|
||||
dev_err(ucsi->dev, "failed to re-enable notifications (%d)\n", ret);
|
||||
return;
|
||||
|
||||
@ -29,10 +29,6 @@ struct dentry;
|
||||
#define UCSI_MESSAGE_OUT 32
|
||||
#define UCSIv2_MESSAGE_OUT 272
|
||||
|
||||
/* Define maximum lengths for message buffers */
|
||||
#define UCSI_MAX_MESSAGE_IN_LENGTH 256
|
||||
#define UCSI_MAX_MESSAGE_OUT_LENGTH 256
|
||||
|
||||
/* UCSI versions */
|
||||
#define UCSI_VERSION_1_0 0x0100
|
||||
#define UCSI_VERSION_1_1 0x0110
|
||||
@ -69,7 +65,6 @@ struct dentry;
|
||||
* @read_cci: Read CCI register
|
||||
* @poll_cci: Read CCI register while polling with notifications disabled
|
||||
* @read_message_in: Read message data from UCSI
|
||||
* @write_message_out: Write message data to UCSI
|
||||
* @sync_control: Blocking control operation
|
||||
* @async_control: Non-blocking control operation
|
||||
* @update_altmodes: Squashes duplicate DP altmodes
|
||||
@ -85,8 +80,8 @@ struct ucsi_operations {
|
||||
int (*read_cci)(struct ucsi *ucsi, u32 *cci);
|
||||
int (*poll_cci)(struct ucsi *ucsi, u32 *cci);
|
||||
int (*read_message_in)(struct ucsi *ucsi, void *val, size_t val_len);
|
||||
int (*write_message_out)(struct ucsi *ucsi, void *data, size_t data_len);
|
||||
int (*sync_control)(struct ucsi *ucsi, u64 command, u32 *cci);
|
||||
int (*sync_control)(struct ucsi *ucsi, u64 command, u32 *cci,
|
||||
void *data, size_t size);
|
||||
int (*async_control)(struct ucsi *ucsi, u64 command);
|
||||
bool (*update_altmodes)(struct ucsi *ucsi, u8 recipient,
|
||||
struct ucsi_altmode *orig,
|
||||
@ -137,7 +132,6 @@ void ucsi_connector_change(struct ucsi *ucsi, u8 num);
|
||||
#define UCSI_GET_PD_MESSAGE 0x15
|
||||
#define UCSI_GET_CAM_CS 0x18
|
||||
#define UCSI_SET_SINK_PATH 0x1c
|
||||
#define UCSI_SET_PDOS 0x1d
|
||||
#define UCSI_READ_POWER_LEVEL 0x1e
|
||||
#define UCSI_SET_USB 0x21
|
||||
#define UCSI_GET_LPM_PPM_INFO 0x22
|
||||
@ -499,12 +493,6 @@ struct ucsi {
|
||||
unsigned long quirks;
|
||||
#define UCSI_NO_PARTNER_PDOS BIT(0) /* Don't read partner's PDOs */
|
||||
#define UCSI_DELAY_DEVICE_PDOS BIT(1) /* Reading PDOs fails until the parter is in PD mode */
|
||||
|
||||
/* Fixed-size buffers for incoming and outgoing messages */
|
||||
u8 message_in[UCSI_MAX_MESSAGE_IN_LENGTH];
|
||||
size_t message_in_size;
|
||||
u8 message_out[UCSI_MAX_MESSAGE_OUT_LENGTH];
|
||||
size_t message_out_size;
|
||||
};
|
||||
|
||||
#define UCSI_MAX_DATA_LENGTH(u) (((u)->version < UCSI_VERSION_2_0) ? 0x10 : 0xff)
|
||||
@ -567,13 +555,15 @@ struct ucsi_connector {
|
||||
struct usb_pd_identity cable_identity;
|
||||
};
|
||||
|
||||
int ucsi_send_command(struct ucsi *ucsi, u64 command);
|
||||
int ucsi_send_command(struct ucsi *ucsi, u64 command,
|
||||
void *retval, size_t size);
|
||||
|
||||
void ucsi_altmode_update_active(struct ucsi_connector *con);
|
||||
int ucsi_resume(struct ucsi *ucsi);
|
||||
|
||||
void ucsi_notify_common(struct ucsi *ucsi, u32 cci);
|
||||
int ucsi_sync_control_common(struct ucsi *ucsi, u64 command, u32 *cci);
|
||||
int ucsi_sync_control_common(struct ucsi *ucsi, u64 command, u32 *cci,
|
||||
void *data, size_t size);
|
||||
|
||||
#if IS_ENABLED(CONFIG_POWER_SUPPLY)
|
||||
int ucsi_register_port_psy(struct ucsi_connector *con);
|
||||
|
||||
@ -86,21 +86,6 @@ static int ucsi_acpi_read_message_in(struct ucsi *ucsi, void *val, size_t val_le
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ucsi_acpi_write_message_out(struct ucsi *ucsi, void *data, size_t data_len)
|
||||
{
|
||||
struct ucsi_acpi *ua = ucsi_get_drvdata(ucsi);
|
||||
|
||||
if (!data || !data_len)
|
||||
return -EINVAL;
|
||||
|
||||
if (ucsi->version <= UCSI_VERSION_1_2)
|
||||
memcpy(ua->base + UCSI_MESSAGE_OUT, data, data_len);
|
||||
else
|
||||
memcpy(ua->base + UCSIv2_MESSAGE_OUT, data, data_len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ucsi_acpi_async_control(struct ucsi *ucsi, u64 command)
|
||||
{
|
||||
struct ucsi_acpi *ua = ucsi_get_drvdata(ucsi);
|
||||
@ -116,19 +101,19 @@ static const struct ucsi_operations ucsi_acpi_ops = {
|
||||
.read_cci = ucsi_acpi_read_cci,
|
||||
.poll_cci = ucsi_acpi_poll_cci,
|
||||
.read_message_in = ucsi_acpi_read_message_in,
|
||||
.write_message_out = ucsi_acpi_write_message_out,
|
||||
.sync_control = ucsi_sync_control_common,
|
||||
.async_control = ucsi_acpi_async_control
|
||||
};
|
||||
|
||||
static int ucsi_gram_sync_control(struct ucsi *ucsi, u64 command, u32 *cci)
|
||||
static int ucsi_gram_sync_control(struct ucsi *ucsi, u64 command, u32 *cci,
|
||||
void *val, size_t len)
|
||||
{
|
||||
u16 bogus_change = UCSI_CONSTAT_POWER_LEVEL_CHANGE |
|
||||
UCSI_CONSTAT_PDOS_CHANGE;
|
||||
struct ucsi_acpi *ua = ucsi_get_drvdata(ucsi);
|
||||
int ret;
|
||||
|
||||
ret = ucsi_sync_control_common(ucsi, command, cci);
|
||||
ret = ucsi_sync_control_common(ucsi, command, cci, val, len);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
@ -140,8 +125,8 @@ static int ucsi_gram_sync_control(struct ucsi *ucsi, u64 command, u32 *cci)
|
||||
if (UCSI_COMMAND(ua->cmd) == UCSI_GET_CONNECTOR_STATUS &&
|
||||
ua->check_bogus_event) {
|
||||
/* Clear the bogus change */
|
||||
if (*(u16 *)ucsi->message_in == bogus_change)
|
||||
*(u16 *)ucsi->message_in = 0;
|
||||
if (*(u16 *)val == bogus_change)
|
||||
*(u16 *)val = 0;
|
||||
|
||||
ua->check_bogus_event = false;
|
||||
}
|
||||
|
||||
@ -606,7 +606,8 @@ static int ucsi_ccg_async_control(struct ucsi *ucsi, u64 command)
|
||||
return ccg_write(uc, reg, (u8 *)&command, sizeof(command));
|
||||
}
|
||||
|
||||
static int ucsi_ccg_sync_control(struct ucsi *ucsi, u64 command, u32 *cci)
|
||||
static int ucsi_ccg_sync_control(struct ucsi *ucsi, u64 command, u32 *cci,
|
||||
void *data, size_t size)
|
||||
{
|
||||
struct ucsi_ccg *uc = ucsi_get_drvdata(ucsi);
|
||||
struct ucsi_connector *con;
|
||||
@ -628,16 +629,16 @@ static int ucsi_ccg_sync_control(struct ucsi *ucsi, u64 command, u32 *cci)
|
||||
ucsi_ccg_update_set_new_cam_cmd(uc, con, &command);
|
||||
}
|
||||
|
||||
ret = ucsi_sync_control_common(ucsi, command, cci);
|
||||
ret = ucsi_sync_control_common(ucsi, command, cci, data, size);
|
||||
|
||||
switch (UCSI_COMMAND(command)) {
|
||||
case UCSI_GET_CURRENT_CAM:
|
||||
if (uc->has_multiple_dp)
|
||||
ucsi_ccg_update_get_current_cam_cmd(uc, (u8 *)ucsi->message_in);
|
||||
ucsi_ccg_update_get_current_cam_cmd(uc, (u8 *)data);
|
||||
break;
|
||||
case UCSI_GET_ALTERNATE_MODES:
|
||||
if (UCSI_ALTMODE_RECIPIENT(command) == UCSI_RECIPIENT_SOP) {
|
||||
struct ucsi_altmode *alt = (struct ucsi_altmode *)ucsi->message_in;
|
||||
struct ucsi_altmode *alt = data;
|
||||
|
||||
if (alt[0].svid == USB_TYPEC_NVIDIA_VLINK_SID)
|
||||
ucsi_ccg_nvidia_altmode(uc, alt, command);
|
||||
@ -645,7 +646,7 @@ static int ucsi_ccg_sync_control(struct ucsi *ucsi, u64 command, u32 *cci)
|
||||
break;
|
||||
case UCSI_GET_CAPABILITY:
|
||||
if (uc->fw_build == CCG_FW_BUILD_NVIDIA_TEGRA) {
|
||||
struct ucsi_capability *cap = (struct ucsi_capability *)ucsi->message_in;
|
||||
struct ucsi_capability *cap = data;
|
||||
|
||||
cap->features &= ~UCSI_CAP_ALT_MODE_DETAILS;
|
||||
}
|
||||
|
||||
@ -88,7 +88,8 @@ static int yoga_c630_ucsi_async_control(struct ucsi *ucsi, u64 command)
|
||||
|
||||
static int yoga_c630_ucsi_sync_control(struct ucsi *ucsi,
|
||||
u64 command,
|
||||
u32 *cci)
|
||||
u32 *cci,
|
||||
void *data, size_t size)
|
||||
{
|
||||
int ret;
|
||||
|
||||
@ -106,8 +107,8 @@ static int yoga_c630_ucsi_sync_control(struct ucsi *ucsi,
|
||||
};
|
||||
|
||||
dev_dbg(ucsi->dev, "faking DP altmode for con1\n");
|
||||
memset(ucsi->message_in, 0, ucsi->message_in_size);
|
||||
memcpy(ucsi->message_in, &alt, min(sizeof(alt), ucsi->message_in_size));
|
||||
memset(data, 0, size);
|
||||
memcpy(data, &alt, min(sizeof(alt), size));
|
||||
*cci = UCSI_CCI_COMMAND_COMPLETE | UCSI_SET_CCI_LENGTH(sizeof(alt));
|
||||
return 0;
|
||||
}
|
||||
@ -120,18 +121,18 @@ static int yoga_c630_ucsi_sync_control(struct ucsi *ucsi,
|
||||
if (UCSI_COMMAND(command) == UCSI_GET_ALTERNATE_MODES &&
|
||||
UCSI_GET_ALTMODE_GET_CONNECTOR_NUMBER(command) == 2) {
|
||||
dev_dbg(ucsi->dev, "ignoring altmodes for con2\n");
|
||||
memset(ucsi->message_in, 0, ucsi->message_in_size);
|
||||
memset(data, 0, size);
|
||||
*cci = UCSI_CCI_COMMAND_COMPLETE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = ucsi_sync_control_common(ucsi, command, cci);
|
||||
ret = ucsi_sync_control_common(ucsi, command, cci, data, size);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* UCSI_GET_CURRENT_CAM is off-by-one on all ports */
|
||||
if (UCSI_COMMAND(command) == UCSI_GET_CURRENT_CAM && ucsi->message_in_size > 0)
|
||||
ucsi->message_in[0]--;
|
||||
if (UCSI_COMMAND(command) == UCSI_GET_CURRENT_CAM && data)
|
||||
((u8 *)data)[0]--;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
bhrb_filter_map_test
|
||||
bhrb_no_crash_wo_pmu_test
|
||||
check_extended_reg_test
|
||||
intr_regs_no_crash_wo_pmu_test
|
||||
mmcr0_cc56run_test
|
||||
mmcr0_exceptionbits_test
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user