mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-05 02:21:52 +09:00
Merge 6.1.91 into android14-6.1-lts
Changes in 6.1.91
dmaengine: pl330: issue_pending waits until WFP state
dmaengine: Revert "dmaengine: pl330: issue_pending waits until WFP state"
wifi: nl80211: don't free NULL coalescing rule
rust: kernel: require `Send` for `Module` implementations
eeprom: at24: Use dev_err_probe for nvmem register failure
eeprom: at24: Probe for DDR3 thermal sensor in the SPD case
eeprom: at24: fix memory corruption race condition
Bluetooth: qca: add support for QCA2066
mm/hugetlb: add folio support to hugetlb specific flag macros
mm: add private field of first tail to struct page and struct folio
mm/hugetlb: add hugetlb_folio_subpool() helpers
mm/hugetlb: add folio_hstate()
mm/hugetlb_cgroup: convert __set_hugetlb_cgroup() to folios
mm/hugetlb_cgroup: convert hugetlb_cgroup_from_page() to folios
mm/hugetlb: convert free_huge_page to folios
mm/hugetlb_cgroup: convert hugetlb_cgroup_uncharge_page() to folios
mm/hugetlb: fix missing hugetlb_lock for resv uncharge
kbuild: refactor host*_flags
kbuild: specify output names separately for each emission type from rustc
cifs: use the least loaded channel for sending requests
smb3: missing lock when picking channel
pinctrl: pinctrl-aspeed-g6: Fix register offset for pinconf of GPIOR-T
pinctrl/meson: fix typo in PDM's pin name
pinctrl: core: delete incorrect free in pinctrl_enable()
pinctrl: mediatek: paris: Fix PIN_CONFIG_INPUT_SCHMITT_ENABLE readback
pinctrl: mediatek: paris: Rework support for PIN_CONFIG_{INPUT,OUTPUT}_ENABLE
sunrpc: add a struct rpc_stats arg to rpc_create_args
nfs: expose /proc/net/sunrpc/nfs in net namespaces
nfs: make the rpc_stat per net namespace
nfs: Handle error of rpc_proc_register() in nfs_net_init().
pinctrl: Introduce struct pinfunction and PINCTRL_PINFUNCTION() macro
pinctrl: intel: Make use of struct pinfunction and PINCTRL_PINFUNCTION()
pinctrl: baytrail: Fix selecting gpio pinctrl state
power: rt9455: hide unused rt9455_boost_voltage_values
power: supply: mt6360_charger: Fix of_match for usb-otg-vbus regulator
pinctrl: devicetree: fix refcount leak in pinctrl_dt_to_map()
regulator: mt6360: De-capitalize devicetree regulator subnodes
regulator: change stubbed devm_regulator_get_enable to return Ok
regulator: change devm_regulator_get_enable_optional() stub to return Ok
bpf, kconfig: Fix DEBUG_INFO_BTF_MODULES Kconfig definition
bpf, skmsg: Fix NULL pointer dereference in sk_psock_skb_ingress_enqueue
nvme: fix warn output about shared namespaces without CONFIG_NVME_MULTIPATH
bpf: Fix a verifier verbose message
spi: introduce new helpers with using modern naming
spi: axi-spi-engine: Convert to platform remove callback returning void
spi: spi-axi-spi-engine: switch to use modern name
spi: spi-axi-spi-engine: Use helper function devm_clk_get_enabled()
spi: axi-spi-engine: simplify driver data allocation
spi: axi-spi-engine: use devm_spi_alloc_host()
spi: axi-spi-engine: move msg state to new struct
spi: axi-spi-engine: use common AXI macros
spi: axi-spi-engine: fix version format string
spi: hisi-kunpeng: Delete the dump interface of data registers in debugfs
bpf, arm64: Fix incorrect runtime stats
s390/mm: Fix storage key clearing for guest huge pages
s390/mm: Fix clearing storage keys for huge pages
xdp: use flags field to disambiguate broadcast redirect
bna: ensure the copied buf is NUL terminated
octeontx2-af: avoid off-by-one read from userspace
nsh: Restore skb->{protocol,data,mac_header} for outer header in nsh_gso_segment().
net l2tp: drop flow hash on forward
s390/vdso: Add CFI for RA register to asm macro vdso_func
net: qede: sanitize 'rc' in qede_add_tc_flower_fltr()
net: qede: use return from qede_parse_flow_attr() for flower
net: qede: use return from qede_parse_flow_attr() for flow_spec
net: qede: use return from qede_parse_actions()
ASoC: meson: axg-fifo: use FIELD helpers
ASoC: meson: axg-fifo: use threaded irq to check periods
ASoC: meson: axg-card: make links nonatomic
ASoC: meson: axg-tdm-interface: manage formatters in trigger
ASoC: meson: cards: select SND_DYNAMIC_MINORS
ALSA: hda: intel-sdw-acpi: fix usage of device_get_named_child_node()
s390/cio: Ensure the copied buf is NUL terminated
cxgb4: Properly lock TX queue for the selftest.
net: dsa: mv88e6xxx: Fix number of databases for 88E6141 / 88E6341
spi: fix null pointer dereference within spi_sync
net: bridge: fix multicast-to-unicast with fraglist GSO
net: core: reject skb_copy(_expand) for fraglist GSO skbs
tipc: fix a possible memleak in tipc_buf_append
vxlan: Pull inner IP header in vxlan_rcv().
s390/qeth: Fix kernel panic after setting hsuid
drm/panel: ili9341: Respect deferred probe
drm/panel: ili9341: Use predefined error codes
net: gro: add flush check in udp_gro_receive_segment
clk: sunxi-ng: h6: Reparent CPUX during PLL CPUX rate change
powerpc/pseries: replace kmalloc with kzalloc in PLPKS driver
powerpc/pseries: Move PLPKS constants to header file
powerpc/pseries: make max polling consistent for longer H_CALLs
powerpc/pseries/iommu: LPAR panics during boot up with a frozen PE
KVM: arm64: vgic-v2: Use cpuid from userspace as vcpu_id
KVM: arm64: vgic-v2: Check for non-NULL vCPU in vgic_v2_parse_attr()
scsi: lpfc: Move NPIV's transport unregistration to after resource clean up
scsi: lpfc: Update lpfc_ramp_down_queue_handler() logic
scsi: lpfc: Replace hbalock with ndlp lock in lpfc_nvme_unregister_port()
scsi: lpfc: Release hbalock before calling lpfc_worker_wake_up()
gfs2: Fix invalid metadata access in punch_hole
wifi: mac80211: fix ieee80211_bss_*_flags kernel-doc
wifi: cfg80211: fix rdev_dump_mpp() arguments order
net: mark racy access on sk->sk_rcvbuf
scsi: mpi3mr: Avoid memcpy field-spanning write WARNING
scsi: bnx2fc: Remove spin_lock_bh while releasing resources after upload
btrfs: return accurate error code on open failure in open_fs_devices()
bpf: Check bloom filter map value size
kbuild: Disable KCSAN for autogenerated *.mod.c intermediaries
scsi: ufs: core: WLUN suspend dev/link state error recovery
ALSA: line6: Zero-initialize message buffers
block: fix overflow in blk_ioctl_discard()
net: bcmgenet: Reset RBUF on first open
ata: sata_gemini: Check clk_enable() result
firewire: ohci: mask bus reset interrupts between ISR and bottom half
tools/power turbostat: Fix added raw MSR output
tools/power turbostat: Increase the limit for fd opened
tools/power turbostat: Fix Bzy_MHz documentation typo
btrfs: make btrfs_clear_delalloc_extent() free delalloc reserve
btrfs: always clear PERTRANS metadata during commit
memblock tests: fix undefined reference to `early_pfn_to_nid'
memblock tests: fix undefined reference to `panic'
memblock tests: fix undefined reference to `BIT'
scsi: target: Fix SELinux error when systemd-modules loads the target module
blk-iocost: avoid out of bounds shift
gpu: host1x: Do not setup DMA for virtual devices
MIPS: scall: Save thread_info.syscall unconditionally on entry
tools/power/turbostat: Fix uncore frequency file string
drm/amdgpu: Refine IB schedule error logging
selftests: timers: Fix valid-adjtimex signed left-shift undefined behavior
Drivers: hv: vmbus: Track decrypted status in vmbus_gpadl
uio_hv_generic: Don't free decrypted memory
Drivers: hv: vmbus: Don't free ring buffers that couldn't be re-encrypted
iommu: mtk: fix module autoloading
fs/9p: only translate RWX permissions for plain 9P2000
fs/9p: translate O_TRUNC into OTRUNC
9p: explicitly deny setlease attempts
gpio: wcove: Use -ENOTSUPP consistently
gpio: crystalcove: Use -ENOTSUPP consistently
clk: Don't hold prepare_lock when calling kref_put()
fs/9p: drop inodes immediately on non-.L too
drm/nouveau/dp: Don't probe eDP ports twice harder
net:usb:qmi_wwan: support Rolling modules
kbuild: rust: avoid creating temporary files
spi: Merge spi_controller.{slave,target}_abort()
perf unwind-libunwind: Fix base address for .eh_frame
perf unwind-libdw: Handle JIT-generated DSOs properly
qibfs: fix dentry leak
xfrm: Preserve vlan tags for transport mode software GRO
ARM: 9381/1: kasan: clear stale stack poison
tcp: defer shutdown(SEND_SHUTDOWN) for TCP_SYN_RECV sockets
tcp: Use refcount_inc_not_zero() in tcp_twsk_unique().
Bluetooth: Fix use-after-free bugs caused by sco_sock_timeout
Bluetooth: msft: fix slab-use-after-free in msft_do_close()
Bluetooth: l2cap: fix null-ptr-deref in l2cap_chan_timeout
net: ks8851: Queue RX packets in IRQ handler instead of disabling BHs
rtnetlink: Correct nested IFLA_VF_VLAN_LIST attribute validation
hwmon: (corsair-cpro) Use a separate buffer for sending commands
hwmon: (corsair-cpro) Use complete_all() instead of complete() in ccp_raw_event()
hwmon: (corsair-cpro) Protect ccp->wait_input_report with a spinlock
phonet: fix rtm_phonet_notify() skb allocation
net: bridge: fix corrupted ethernet header on multicast-to-unicast
ipv6: fib6_rules: avoid possible NULL dereference in fib6_rule_action()
timers: Get rid of del_singleshot_timer_sync()
timers: Rename del_timer() to timer_delete()
net-sysfs: convert dev->operstate reads to lockless ones
hsr: Simplify code for announcing HSR nodes timer setup
ipv6: annotate data-races around cnf.disable_ipv6
ipv6: prevent NULL dereference in ip6_output()
net/smc: fix neighbour and rtable leak in smc_ib_find_route()
net: hns3: using user configure after hardware reset
net: hns3: direct return when receive a unknown mailbox message
net: hns3: change type of numa_node_mask as nodemask_t
net: hns3: release PTP resources if pf initialization failed
net: hns3: use appropriate barrier function after setting a bit value
net: hns3: fix port vlan filter not disabled issue
net: hns3: fix kernel crash when devlink reload during initialization
drm/meson: dw-hdmi: power up phy on device init
drm/meson: dw-hdmi: add bandgap setting for g12
drm/connector: Add \n to message about demoting connector force-probes
dm/amd/pm: Fix problems with reboot/shutdown for some SMU 13.0.4/13.0.11 users
gpiolib: cdev: Add missing header(s)
gpiolib: cdev: relocate debounce_period_us from struct gpio_desc
gpiolib: cdev: fix uninitialised kfifo
drm/amd/display: Atom Integrated System Info v2_2 for DCN35
MAINTAINERS: add leah to 6.1 MAINTAINERS file
drm/amdgpu: once more fix the call oder in amdgpu_ttm_move() v2
btrfs: fix kvcalloc() arguments order in btrfs_ioctl_send()
firewire: nosy: ensure user_length is taken into account when fetching packet contents
Reapply "drm/qxl: simplify qxl_fence_wait"
rust: error: Rename to_kernel_errno() -> to_errno()
rust: fix regexp in scripts/is_rust_module.sh
btf, scripts: rust: drop is_rust_module.sh
rust: module: place generated init_module() function in .init.text
rust: macros: fix soundness issue in `module!` macro
usb: typec: ucsi: Check for notifications after init
usb: typec: ucsi: Fix connector check on init
usb: Fix regression caused by invalid ep0 maxpacket in virtual SuperSpeed device
usb: ohci: Prevent missed ohci interrupts
USB: core: Fix access violation during port device removal
usb: gadget: composite: fix OS descriptors w_value logic
usb: gadget: f_fs: Fix a race condition when processing setup packets.
usb: xhci-plat: Don't include xhci.h
usb: dwc3: core: Prevent phy suspend during init
usb: typec: tcpm: unregister existing source caps before re-registration
usb: typec: tcpm: Check for port partner validity before consuming it
ALSA: hda/realtek: Fix mute led of HP Laptop 15-da3001TU
btrfs: add missing mutex_unlock in btrfs_relocate_sys_chunks()
mm/slab: make __free(kfree) accept error pointers
mptcp: ensure snd_nxt is properly initialized on connect
dt-bindings: iio: health: maxim,max30102: fix compatible check
iio:imu: adis16475: Fix sync mode setting
iio: accel: mxc4005: Interrupt handling fixes
kmsan: compiler_types: declare __no_sanitize_or_inline
tipc: fix UAF in error path
ASoC: tegra: Fix DSPK 16-bit playback
ASoC: ti: davinci-mcasp: Fix race condition during probe
dyndbg: fix old BUG_ON in >control parser
slimbus: qcom-ngd-ctrl: Add timeout for wait operation
mei: me: add lunar lake point M DID
drm/amdkfd: don't allow mapping the MMIO HDP page with large pages
drm/vmwgfx: Fix invalid reads in fence signaled events
drm/i915/bios: Fix parsing backlight BDB data
drm/amd/display: Handle Y carry-over in VCP X.Y calculation
net: fix out-of-bounds access in ops_init
hwmon: (pmbus/ucd9000) Increase delay from 250 to 500us
mm: use memalloc_nofs_save() in page_cache_ra_order()
regulator: core: fix debugfs creation regression
spi: microchip-core-qspi: fix setting spi bus clock rate
ksmbd: off ipv6only for both ipv4/ipv6 binding
ksmbd: avoid to send duplicate lease break notifications
ksmbd: do not grant v2 lease if parent lease key and epoch are not set
Bluetooth: qca: add missing firmware sanity checks
Bluetooth: qca: fix NVM configuration parsing
Bluetooth: qca: fix info leak when fetching board id
Bluetooth: qca: fix info leak when fetching fw build id
Bluetooth: qca: fix firmware check error path
VFIO: Add the SPR_DSA and SPR_IAX devices to the denylist
dmaengine: idxd: add a new security check to deal with a hardware erratum
dmaengine: idxd: add a write() method for applications to submit work
keys: Fix overwrite of key expiration on instantiation
btrfs: do not wait for short bulk allocation
mm/hugetlb: fix DEBUG_LOCKS_WARN_ON(1) when dissolve_free_hugetlb_folio()
mm,swapops: update check in is_pfn_swap_entry for hwpoison entries
md: fix kmemleak of rdev->serial
net: bcmgenet: Clear RGMII_LINK upon link down
net: bcmgenet: synchronize EXT_RGMII_OOB_CTRL access
net: bcmgenet: synchronize use of bcmgenet_set_rx_mode()
net: bcmgenet: synchronize UMAC_CMD access
Linux 6.1.91
Change-Id: I71c08414d3580e6d9b869a8f0fc3e27f02752997
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
@@ -42,7 +42,7 @@ allOf:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: maxim,max30100
|
||||
const: maxim,max30102
|
||||
then:
|
||||
properties:
|
||||
maxim,green-led-current-microamp: false
|
||||
|
||||
@@ -22599,6 +22599,7 @@ F: include/xen/swiotlb-xen.h
|
||||
|
||||
XFS FILESYSTEM
|
||||
C: irc://irc.oftc.net/xfs
|
||||
M: Leah Rumancik <leah.rumancik@gmail.com>
|
||||
M: Darrick J. Wong <djwong@kernel.org>
|
||||
L: linux-xfs@vger.kernel.org
|
||||
S: Supported
|
||||
|
||||
2
Makefile
2
Makefile
@@ -1,7 +1,7 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
VERSION = 6
|
||||
PATCHLEVEL = 1
|
||||
SUBLEVEL = 90
|
||||
SUBLEVEL = 91
|
||||
EXTRAVERSION =
|
||||
NAME = Curry Ramen
|
||||
|
||||
|
||||
@@ -127,6 +127,10 @@ cpu_resume_after_mmu:
|
||||
instr_sync
|
||||
#endif
|
||||
bl cpu_init @ restore the und/abt/irq banked regs
|
||||
#if defined(CONFIG_KASAN) && defined(CONFIG_KASAN_STACK)
|
||||
mov r0, sp
|
||||
bl kasan_unpoison_task_stack_below
|
||||
#endif
|
||||
mov r0, #0 @ return zero on success
|
||||
ldmfd sp!, {r4 - r11, pc}
|
||||
ENDPROC(cpu_resume_after_mmu)
|
||||
|
||||
@@ -337,16 +337,12 @@ int kvm_register_vgic_device(unsigned long type)
|
||||
int vgic_v2_parse_attr(struct kvm_device *dev, struct kvm_device_attr *attr,
|
||||
struct vgic_reg_attr *reg_attr)
|
||||
{
|
||||
int cpuid;
|
||||
int cpuid = FIELD_GET(KVM_DEV_ARM_VGIC_CPUID_MASK, attr->attr);
|
||||
|
||||
cpuid = (attr->attr & KVM_DEV_ARM_VGIC_CPUID_MASK) >>
|
||||
KVM_DEV_ARM_VGIC_CPUID_SHIFT;
|
||||
|
||||
if (cpuid >= atomic_read(&dev->kvm->online_vcpus))
|
||||
return -EINVAL;
|
||||
|
||||
reg_attr->vcpu = kvm_get_vcpu(dev->kvm, cpuid);
|
||||
reg_attr->addr = attr->attr & KVM_DEV_ARM_VGIC_OFFSET_MASK;
|
||||
reg_attr->vcpu = kvm_get_vcpu_by_id(dev->kvm, cpuid);
|
||||
if (!reg_attr->vcpu)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1679,15 +1679,15 @@ static void invoke_bpf_prog(struct jit_ctx *ctx, struct bpf_tramp_link *l,
|
||||
|
||||
emit_call(enter_prog, ctx);
|
||||
|
||||
/* save return value to callee saved register x20 */
|
||||
emit(A64_MOV(1, A64_R(20), A64_R(0)), ctx);
|
||||
|
||||
/* if (__bpf_prog_enter(prog) == 0)
|
||||
* goto skip_exec_of_prog;
|
||||
*/
|
||||
branch = ctx->image + ctx->idx;
|
||||
emit(A64_NOP, ctx);
|
||||
|
||||
/* save return value to callee saved register x20 */
|
||||
emit(A64_MOV(1, A64_R(20), A64_R(0)), ctx);
|
||||
|
||||
emit(A64_ADD_I(1, A64_R(0), A64_SP, args_off), ctx);
|
||||
if (!p->jited)
|
||||
emit_addr_mov_i64(A64_R(1), (const u64)p->insnsi, ctx);
|
||||
|
||||
@@ -157,7 +157,7 @@ static inline long regs_return_value(struct pt_regs *regs)
|
||||
#define instruction_pointer(regs) ((regs)->cp0_epc)
|
||||
#define profile_pc(regs) instruction_pointer(regs)
|
||||
|
||||
extern asmlinkage long syscall_trace_enter(struct pt_regs *regs, long syscall);
|
||||
extern asmlinkage long syscall_trace_enter(struct pt_regs *regs);
|
||||
extern asmlinkage void syscall_trace_leave(struct pt_regs *regs);
|
||||
|
||||
extern void die(const char *, struct pt_regs *) __noreturn;
|
||||
|
||||
@@ -98,6 +98,7 @@ void output_thread_info_defines(void)
|
||||
OFFSET(TI_CPU, thread_info, cpu);
|
||||
OFFSET(TI_PRE_COUNT, thread_info, preempt_count);
|
||||
OFFSET(TI_REGS, thread_info, regs);
|
||||
OFFSET(TI_SYSCALL, thread_info, syscall);
|
||||
DEFINE(_THREAD_SIZE, THREAD_SIZE);
|
||||
DEFINE(_THREAD_MASK, THREAD_MASK);
|
||||
DEFINE(_IRQ_STACK_SIZE, IRQ_STACK_SIZE);
|
||||
|
||||
@@ -1309,16 +1309,13 @@ long arch_ptrace(struct task_struct *child, long request,
|
||||
* Notification of system call entry/exit
|
||||
* - triggered by current->work.syscall_trace
|
||||
*/
|
||||
asmlinkage long syscall_trace_enter(struct pt_regs *regs, long syscall)
|
||||
asmlinkage long syscall_trace_enter(struct pt_regs *regs)
|
||||
{
|
||||
user_exit();
|
||||
|
||||
current_thread_info()->syscall = syscall;
|
||||
|
||||
if (test_thread_flag(TIF_SYSCALL_TRACE)) {
|
||||
if (ptrace_report_syscall_entry(regs))
|
||||
return -1;
|
||||
syscall = current_thread_info()->syscall;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SECCOMP
|
||||
@@ -1327,7 +1324,7 @@ asmlinkage long syscall_trace_enter(struct pt_regs *regs, long syscall)
|
||||
struct seccomp_data sd;
|
||||
unsigned long args[6];
|
||||
|
||||
sd.nr = syscall;
|
||||
sd.nr = current_thread_info()->syscall;
|
||||
sd.arch = syscall_get_arch(current);
|
||||
syscall_get_arguments(current, regs, args);
|
||||
for (i = 0; i < 6; i++)
|
||||
@@ -1337,23 +1334,23 @@ asmlinkage long syscall_trace_enter(struct pt_regs *regs, long syscall)
|
||||
ret = __secure_computing(&sd);
|
||||
if (ret == -1)
|
||||
return ret;
|
||||
syscall = current_thread_info()->syscall;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
|
||||
trace_sys_enter(regs, regs->regs[2]);
|
||||
|
||||
audit_syscall_entry(syscall, regs->regs[4], regs->regs[5],
|
||||
audit_syscall_entry(current_thread_info()->syscall,
|
||||
regs->regs[4], regs->regs[5],
|
||||
regs->regs[6], regs->regs[7]);
|
||||
|
||||
/*
|
||||
* Negative syscall numbers are mistaken for rejected syscalls, but
|
||||
* won't have had the return value set appropriately, so we do so now.
|
||||
*/
|
||||
if (syscall < 0)
|
||||
if (current_thread_info()->syscall < 0)
|
||||
syscall_set_return_value(current, regs, -ENOSYS, 0);
|
||||
return syscall;
|
||||
return current_thread_info()->syscall;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -77,6 +77,18 @@ loads_done:
|
||||
PTR_WD load_a7, bad_stack_a7
|
||||
.previous
|
||||
|
||||
/*
|
||||
* syscall number is in v0 unless we called syscall(__NR_###)
|
||||
* where the real syscall number is in a0
|
||||
*/
|
||||
subu t2, v0, __NR_O32_Linux
|
||||
bnez t2, 1f /* __NR_syscall at offset 0 */
|
||||
LONG_S a0, TI_SYSCALL($28) # Save a0 as syscall number
|
||||
b 2f
|
||||
1:
|
||||
LONG_S v0, TI_SYSCALL($28) # Save v0 as syscall number
|
||||
2:
|
||||
|
||||
lw t0, TI_FLAGS($28) # syscall tracing enabled?
|
||||
li t1, _TIF_WORK_SYSCALL_ENTRY
|
||||
and t0, t1
|
||||
@@ -114,16 +126,7 @@ syscall_trace_entry:
|
||||
SAVE_STATIC
|
||||
move a0, sp
|
||||
|
||||
/*
|
||||
* syscall number is in v0 unless we called syscall(__NR_###)
|
||||
* where the real syscall number is in a0
|
||||
*/
|
||||
move a1, v0
|
||||
subu t2, v0, __NR_O32_Linux
|
||||
bnez t2, 1f /* __NR_syscall at offset 0 */
|
||||
lw a1, PT_R4(sp)
|
||||
|
||||
1: jal syscall_trace_enter
|
||||
jal syscall_trace_enter
|
||||
|
||||
bltz v0, 1f # seccomp failed? Skip syscall
|
||||
|
||||
|
||||
@@ -44,6 +44,8 @@ NESTED(handle_sysn32, PT_SIZE, sp)
|
||||
|
||||
sd a3, PT_R26(sp) # save a3 for syscall restarting
|
||||
|
||||
LONG_S v0, TI_SYSCALL($28) # Store syscall number
|
||||
|
||||
li t1, _TIF_WORK_SYSCALL_ENTRY
|
||||
LONG_L t0, TI_FLAGS($28) # syscall tracing enabled?
|
||||
and t0, t1, t0
|
||||
@@ -72,7 +74,6 @@ syscall_common:
|
||||
n32_syscall_trace_entry:
|
||||
SAVE_STATIC
|
||||
move a0, sp
|
||||
move a1, v0
|
||||
jal syscall_trace_enter
|
||||
|
||||
bltz v0, 1f # seccomp failed? Skip syscall
|
||||
|
||||
@@ -46,6 +46,8 @@ NESTED(handle_sys64, PT_SIZE, sp)
|
||||
|
||||
sd a3, PT_R26(sp) # save a3 for syscall restarting
|
||||
|
||||
LONG_S v0, TI_SYSCALL($28) # Store syscall number
|
||||
|
||||
li t1, _TIF_WORK_SYSCALL_ENTRY
|
||||
LONG_L t0, TI_FLAGS($28) # syscall tracing enabled?
|
||||
and t0, t1, t0
|
||||
@@ -82,7 +84,6 @@ n64_syscall_exit:
|
||||
syscall_trace_entry:
|
||||
SAVE_STATIC
|
||||
move a0, sp
|
||||
move a1, v0
|
||||
jal syscall_trace_enter
|
||||
|
||||
bltz v0, 1f # seccomp failed? Skip syscall
|
||||
|
||||
@@ -79,6 +79,22 @@ loads_done:
|
||||
PTR_WD load_a7, bad_stack_a7
|
||||
.previous
|
||||
|
||||
/*
|
||||
* absolute syscall number is in v0 unless we called syscall(__NR_###)
|
||||
* where the real syscall number is in a0
|
||||
* note: NR_syscall is the first O32 syscall but the macro is
|
||||
* only defined when compiling with -mabi=32 (CONFIG_32BIT)
|
||||
* therefore __NR_O32_Linux is used (4000)
|
||||
*/
|
||||
|
||||
subu t2, v0, __NR_O32_Linux
|
||||
bnez t2, 1f /* __NR_syscall at offset 0 */
|
||||
LONG_S a0, TI_SYSCALL($28) # Save a0 as syscall number
|
||||
b 2f
|
||||
1:
|
||||
LONG_S v0, TI_SYSCALL($28) # Save v0 as syscall number
|
||||
2:
|
||||
|
||||
li t1, _TIF_WORK_SYSCALL_ENTRY
|
||||
LONG_L t0, TI_FLAGS($28) # syscall tracing enabled?
|
||||
and t0, t1, t0
|
||||
@@ -113,22 +129,7 @@ trace_a_syscall:
|
||||
sd a7, PT_R11(sp) # For indirect syscalls
|
||||
|
||||
move a0, sp
|
||||
/*
|
||||
* absolute syscall number is in v0 unless we called syscall(__NR_###)
|
||||
* where the real syscall number is in a0
|
||||
* note: NR_syscall is the first O32 syscall but the macro is
|
||||
* only defined when compiling with -mabi=32 (CONFIG_32BIT)
|
||||
* therefore __NR_O32_Linux is used (4000)
|
||||
*/
|
||||
.set push
|
||||
.set reorder
|
||||
subu t1, v0, __NR_O32_Linux
|
||||
move a1, v0
|
||||
bnez t1, 1f /* __NR_syscall at offset 0 */
|
||||
ld a1, PT_R4(sp) /* Arg1 for __NR_syscall case */
|
||||
.set pop
|
||||
|
||||
1: jal syscall_trace_enter
|
||||
jal syscall_trace_enter
|
||||
|
||||
bltz v0, 1f # seccomp failed? Skip syscall
|
||||
|
||||
|
||||
@@ -781,8 +781,16 @@ static void pci_dma_bus_setup_pSeriesLP(struct pci_bus *bus)
|
||||
* parent bus. During reboot, there will be ibm,dma-window property to
|
||||
* define DMA window. For kdump, there will at least be default window or DDW
|
||||
* or both.
|
||||
* There is an exception to the above. In case the PE goes into frozen
|
||||
* state, firmware may not provide ibm,dma-window property at the time
|
||||
* of LPAR boot up.
|
||||
*/
|
||||
|
||||
if (!pdn) {
|
||||
pr_debug(" no ibm,dma-window property !\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ppci = PCI_DN(pdn);
|
||||
|
||||
pr_debug(" parent is %pOF, iommu_table: 0x%p\n",
|
||||
|
||||
@@ -21,19 +21,6 @@
|
||||
|
||||
#include "plpks.h"
|
||||
|
||||
#define PKS_FW_OWNER 0x1
|
||||
#define PKS_BOOTLOADER_OWNER 0x2
|
||||
#define PKS_OS_OWNER 0x3
|
||||
|
||||
#define LABEL_VERSION 0
|
||||
#define MAX_LABEL_ATTR_SIZE 16
|
||||
#define MAX_NAME_SIZE 239
|
||||
#define MAX_DATA_SIZE 4000
|
||||
|
||||
#define PKS_FLUSH_MAX_TIMEOUT 5000 //msec
|
||||
#define PKS_FLUSH_SLEEP 10 //msec
|
||||
#define PKS_FLUSH_SLEEP_RANGE 400
|
||||
|
||||
static u8 *ospassword;
|
||||
static u16 ospasswordlength;
|
||||
|
||||
@@ -60,7 +47,7 @@ struct label_attr {
|
||||
|
||||
struct label {
|
||||
struct label_attr attr;
|
||||
u8 name[MAX_NAME_SIZE];
|
||||
u8 name[PLPKS_MAX_NAME_SIZE];
|
||||
size_t size;
|
||||
};
|
||||
|
||||
@@ -123,7 +110,7 @@ static int pseries_status_to_err(int rc)
|
||||
static int plpks_gen_password(void)
|
||||
{
|
||||
unsigned long retbuf[PLPAR_HCALL_BUFSIZE] = { 0 };
|
||||
u8 *password, consumer = PKS_OS_OWNER;
|
||||
u8 *password, consumer = PLPKS_OS_OWNER;
|
||||
int rc;
|
||||
|
||||
password = kzalloc(maxpwsize, GFP_KERNEL);
|
||||
@@ -159,22 +146,18 @@ static struct plpks_auth *construct_auth(u8 consumer)
|
||||
{
|
||||
struct plpks_auth *auth;
|
||||
|
||||
if (consumer > PKS_OS_OWNER)
|
||||
if (consumer > PLPKS_OS_OWNER)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
auth = kmalloc(struct_size(auth, password, maxpwsize), GFP_KERNEL);
|
||||
auth = kzalloc(struct_size(auth, password, maxpwsize), GFP_KERNEL);
|
||||
if (!auth)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
auth->version = 1;
|
||||
auth->consumer = consumer;
|
||||
auth->rsvd0 = 0;
|
||||
auth->rsvd1 = 0;
|
||||
|
||||
if (consumer == PKS_FW_OWNER || consumer == PKS_BOOTLOADER_OWNER) {
|
||||
auth->passwordlength = 0;
|
||||
if (consumer == PLPKS_FW_OWNER || consumer == PLPKS_BOOTLOADER_OWNER)
|
||||
return auth;
|
||||
}
|
||||
|
||||
memcpy(auth->password, ospassword, ospasswordlength);
|
||||
|
||||
@@ -193,7 +176,7 @@ static struct label *construct_label(char *component, u8 varos, u8 *name,
|
||||
struct label *label;
|
||||
size_t slen;
|
||||
|
||||
if (!name || namelen > MAX_NAME_SIZE)
|
||||
if (!name || namelen > PLPKS_MAX_NAME_SIZE)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
slen = strlen(component);
|
||||
@@ -207,9 +190,9 @@ static struct label *construct_label(char *component, u8 varos, u8 *name,
|
||||
if (component)
|
||||
memcpy(&label->attr.prefix, component, slen);
|
||||
|
||||
label->attr.version = LABEL_VERSION;
|
||||
label->attr.version = PLPKS_LABEL_VERSION;
|
||||
label->attr.os = varos;
|
||||
label->attr.length = MAX_LABEL_ATTR_SIZE;
|
||||
label->attr.length = PLPKS_MAX_LABEL_ATTR_SIZE;
|
||||
memcpy(&label->name, name, namelen);
|
||||
|
||||
label->size = sizeof(struct label_attr) + namelen;
|
||||
@@ -271,10 +254,9 @@ static int plpks_confirm_object_flushed(struct label *label,
|
||||
if (!rc && status == 1)
|
||||
break;
|
||||
|
||||
usleep_range(PKS_FLUSH_SLEEP,
|
||||
PKS_FLUSH_SLEEP + PKS_FLUSH_SLEEP_RANGE);
|
||||
timeout = timeout + PKS_FLUSH_SLEEP;
|
||||
} while (timeout < PKS_FLUSH_MAX_TIMEOUT);
|
||||
fsleep(PLPKS_FLUSH_SLEEP);
|
||||
timeout = timeout + PLPKS_FLUSH_SLEEP;
|
||||
} while (timeout < PLPKS_MAX_TIMEOUT);
|
||||
|
||||
rc = pseries_status_to_err(rc);
|
||||
|
||||
@@ -289,13 +271,13 @@ int plpks_write_var(struct plpks_var var)
|
||||
int rc;
|
||||
|
||||
if (!var.component || !var.data || var.datalen <= 0 ||
|
||||
var.namelen > MAX_NAME_SIZE || var.datalen > MAX_DATA_SIZE)
|
||||
var.namelen > PLPKS_MAX_NAME_SIZE || var.datalen > PLPKS_MAX_DATA_SIZE)
|
||||
return -EINVAL;
|
||||
|
||||
if (var.policy & SIGNEDUPDATE)
|
||||
if (var.policy & PLPKS_SIGNEDUPDATE)
|
||||
return -EINVAL;
|
||||
|
||||
auth = construct_auth(PKS_OS_OWNER);
|
||||
auth = construct_auth(PLPKS_OS_OWNER);
|
||||
if (IS_ERR(auth))
|
||||
return PTR_ERR(auth);
|
||||
|
||||
@@ -331,10 +313,10 @@ int plpks_remove_var(char *component, u8 varos, struct plpks_var_name vname)
|
||||
struct label *label;
|
||||
int rc;
|
||||
|
||||
if (!component || vname.namelen > MAX_NAME_SIZE)
|
||||
if (!component || vname.namelen > PLPKS_MAX_NAME_SIZE)
|
||||
return -EINVAL;
|
||||
|
||||
auth = construct_auth(PKS_OS_OWNER);
|
||||
auth = construct_auth(PLPKS_OS_OWNER);
|
||||
if (IS_ERR(auth))
|
||||
return PTR_ERR(auth);
|
||||
|
||||
@@ -370,14 +352,14 @@ static int plpks_read_var(u8 consumer, struct plpks_var *var)
|
||||
u8 *output;
|
||||
int rc;
|
||||
|
||||
if (var->namelen > MAX_NAME_SIZE)
|
||||
if (var->namelen > PLPKS_MAX_NAME_SIZE)
|
||||
return -EINVAL;
|
||||
|
||||
auth = construct_auth(consumer);
|
||||
if (IS_ERR(auth))
|
||||
return PTR_ERR(auth);
|
||||
|
||||
if (consumer == PKS_OS_OWNER) {
|
||||
if (consumer == PLPKS_OS_OWNER) {
|
||||
label = construct_label(var->component, var->os, var->name,
|
||||
var->namelen);
|
||||
if (IS_ERR(label)) {
|
||||
@@ -392,7 +374,7 @@ static int plpks_read_var(u8 consumer, struct plpks_var *var)
|
||||
goto out_free_label;
|
||||
}
|
||||
|
||||
if (consumer == PKS_OS_OWNER)
|
||||
if (consumer == PLPKS_OS_OWNER)
|
||||
rc = plpar_hcall(H_PKS_READ_OBJECT, retbuf, virt_to_phys(auth),
|
||||
virt_to_phys(label), label->size, virt_to_phys(output),
|
||||
maxobjsize);
|
||||
@@ -434,17 +416,17 @@ out_free_auth:
|
||||
|
||||
int plpks_read_os_var(struct plpks_var *var)
|
||||
{
|
||||
return plpks_read_var(PKS_OS_OWNER, var);
|
||||
return plpks_read_var(PLPKS_OS_OWNER, var);
|
||||
}
|
||||
|
||||
int plpks_read_fw_var(struct plpks_var *var)
|
||||
{
|
||||
return plpks_read_var(PKS_FW_OWNER, var);
|
||||
return plpks_read_var(PLPKS_FW_OWNER, var);
|
||||
}
|
||||
|
||||
int plpks_read_bootloader_var(struct plpks_var *var)
|
||||
{
|
||||
return plpks_read_var(PKS_BOOTLOADER_OWNER, var);
|
||||
return plpks_read_var(PLPKS_BOOTLOADER_OWNER, var);
|
||||
}
|
||||
|
||||
static __init int pseries_plpks_init(void)
|
||||
|
||||
@@ -12,14 +12,39 @@
|
||||
#include <linux/types.h>
|
||||
#include <linux/list.h>
|
||||
|
||||
#define OSSECBOOTAUDIT 0x40000000
|
||||
#define OSSECBOOTENFORCE 0x20000000
|
||||
#define WORLDREADABLE 0x08000000
|
||||
#define SIGNEDUPDATE 0x01000000
|
||||
// Object policy flags from supported_policies
|
||||
#define PLPKS_OSSECBOOTAUDIT PPC_BIT32(1) // OS secure boot must be audit/enforce
|
||||
#define PLPKS_OSSECBOOTENFORCE PPC_BIT32(2) // OS secure boot must be enforce
|
||||
#define PLPKS_PWSET PPC_BIT32(3) // No access without password set
|
||||
#define PLPKS_WORLDREADABLE PPC_BIT32(4) // Readable without authentication
|
||||
#define PLPKS_IMMUTABLE PPC_BIT32(5) // Once written, object cannot be removed
|
||||
#define PLPKS_TRANSIENT PPC_BIT32(6) // Object does not persist through reboot
|
||||
#define PLPKS_SIGNEDUPDATE PPC_BIT32(7) // Object can only be modified by signed updates
|
||||
#define PLPKS_HVPROVISIONED PPC_BIT32(28) // Hypervisor has provisioned this object
|
||||
|
||||
#define PLPKS_VAR_LINUX 0x02
|
||||
// Signature algorithm flags from signed_update_algorithms
|
||||
#define PLPKS_ALG_RSA2048 PPC_BIT(0)
|
||||
#define PLPKS_ALG_RSA4096 PPC_BIT(1)
|
||||
|
||||
// Object label OS metadata flags
|
||||
#define PLPKS_VAR_LINUX 0x02
|
||||
#define PLPKS_VAR_COMMON 0x04
|
||||
|
||||
// Flags for which consumer owns an object is owned by
|
||||
#define PLPKS_FW_OWNER 0x1
|
||||
#define PLPKS_BOOTLOADER_OWNER 0x2
|
||||
#define PLPKS_OS_OWNER 0x3
|
||||
|
||||
// Flags for label metadata fields
|
||||
#define PLPKS_LABEL_VERSION 0
|
||||
#define PLPKS_MAX_LABEL_ATTR_SIZE 16
|
||||
#define PLPKS_MAX_NAME_SIZE 239
|
||||
#define PLPKS_MAX_DATA_SIZE 4000
|
||||
|
||||
// Timeouts for PLPKS operations
|
||||
#define PLPKS_MAX_TIMEOUT (5 * USEC_PER_SEC)
|
||||
#define PLPKS_FLUSH_SLEEP 10000 // usec
|
||||
|
||||
struct plpks_var {
|
||||
char *component;
|
||||
u8 *name;
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#define CFI_DEF_CFA_OFFSET .cfi_def_cfa_offset
|
||||
#define CFI_ADJUST_CFA_OFFSET .cfi_adjust_cfa_offset
|
||||
#define CFI_RESTORE .cfi_restore
|
||||
#define CFI_REL_OFFSET .cfi_rel_offset
|
||||
|
||||
#ifdef CONFIG_AS_CFI_VAL_OFFSET
|
||||
#define CFI_VAL_OFFSET .cfi_val_offset
|
||||
|
||||
@@ -23,8 +23,10 @@ __kernel_\func:
|
||||
CFI_DEF_CFA_OFFSET (STACK_FRAME_OVERHEAD + WRAPPER_FRAME_SIZE)
|
||||
CFI_VAL_OFFSET 15, -STACK_FRAME_OVERHEAD
|
||||
stg %r14,STACK_FRAME_OVERHEAD(%r15)
|
||||
CFI_REL_OFFSET 14, STACK_FRAME_OVERHEAD
|
||||
brasl %r14,__s390_vdso_\func
|
||||
lg %r14,STACK_FRAME_OVERHEAD(%r15)
|
||||
CFI_RESTORE 14
|
||||
aghi %r15,WRAPPER_FRAME_SIZE
|
||||
CFI_DEF_CFA_OFFSET STACK_FRAME_OVERHEAD
|
||||
CFI_RESTORE 15
|
||||
|
||||
@@ -2647,7 +2647,7 @@ static int __s390_enable_skey_hugetlb(pte_t *pte, unsigned long addr,
|
||||
return 0;
|
||||
|
||||
start = pmd_val(*pmd) & HPAGE_MASK;
|
||||
end = start + HPAGE_SIZE - 1;
|
||||
end = start + HPAGE_SIZE;
|
||||
__storage_key_init_range(start, end);
|
||||
set_bit(PG_arch_1, &page->flags);
|
||||
cond_resched();
|
||||
|
||||
@@ -139,7 +139,7 @@ static void clear_huge_pte_skeys(struct mm_struct *mm, unsigned long rste)
|
||||
}
|
||||
|
||||
if (!test_and_set_bit(PG_arch_1, &page->flags))
|
||||
__storage_key_init_range(paddr, paddr + size - 1);
|
||||
__storage_key_init_range(paddr, paddr + size);
|
||||
}
|
||||
|
||||
void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
|
||||
|
||||
@@ -1331,7 +1331,7 @@ static bool iocg_kick_delay(struct ioc_gq *iocg, struct ioc_now *now)
|
||||
{
|
||||
struct ioc *ioc = iocg->ioc;
|
||||
struct blkcg_gq *blkg = iocg_to_blkg(iocg);
|
||||
u64 tdelta, delay, new_delay;
|
||||
u64 tdelta, delay, new_delay, shift;
|
||||
s64 vover, vover_pct;
|
||||
u32 hwa;
|
||||
|
||||
@@ -1346,8 +1346,9 @@ static bool iocg_kick_delay(struct ioc_gq *iocg, struct ioc_now *now)
|
||||
|
||||
/* calculate the current delay in effect - 1/2 every second */
|
||||
tdelta = now->now - iocg->delay_at;
|
||||
if (iocg->delay)
|
||||
delay = iocg->delay >> div64_u64(tdelta, USEC_PER_SEC);
|
||||
shift = div64_u64(tdelta, USEC_PER_SEC);
|
||||
if (iocg->delay && shift < BITS_PER_LONG)
|
||||
delay = iocg->delay >> shift;
|
||||
else
|
||||
delay = 0;
|
||||
|
||||
|
||||
@@ -89,7 +89,7 @@ static int blk_ioctl_discard(struct block_device *bdev, fmode_t mode,
|
||||
unsigned long arg)
|
||||
{
|
||||
uint64_t range[2];
|
||||
uint64_t start, len;
|
||||
uint64_t start, len, end;
|
||||
struct inode *inode = bdev->bd_inode;
|
||||
int err;
|
||||
|
||||
@@ -110,7 +110,8 @@ static int blk_ioctl_discard(struct block_device *bdev, fmode_t mode,
|
||||
if (len & 511)
|
||||
return -EINVAL;
|
||||
|
||||
if (start + len > bdev_nr_bytes(bdev))
|
||||
if (check_add_overflow(start, len, &end) ||
|
||||
end > bdev_nr_bytes(bdev))
|
||||
return -EINVAL;
|
||||
|
||||
filemap_invalidate_lock(inode->i_mapping);
|
||||
|
||||
@@ -201,7 +201,10 @@ int gemini_sata_start_bridge(struct sata_gemini *sg, unsigned int bridge)
|
||||
pclk = sg->sata0_pclk;
|
||||
else
|
||||
pclk = sg->sata1_pclk;
|
||||
clk_enable(pclk);
|
||||
ret = clk_enable(pclk);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
msleep(10);
|
||||
|
||||
/* Do not keep clocking a bridge that is not online */
|
||||
|
||||
@@ -99,7 +99,8 @@ static int qca_read_fw_build_info(struct hci_dev *hdev)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
struct edl_event_hdr *edl;
|
||||
char cmd, build_label[QCA_FW_BUILD_VER_LEN];
|
||||
char *build_label;
|
||||
char cmd;
|
||||
int build_lbl_len, err = 0;
|
||||
|
||||
bt_dev_dbg(hdev, "QCA read fw build info");
|
||||
@@ -114,6 +115,11 @@ static int qca_read_fw_build_info(struct hci_dev *hdev)
|
||||
return err;
|
||||
}
|
||||
|
||||
if (skb->len < sizeof(*edl)) {
|
||||
err = -EILSEQ;
|
||||
goto out;
|
||||
}
|
||||
|
||||
edl = (struct edl_event_hdr *)(skb->data);
|
||||
if (!edl) {
|
||||
bt_dev_err(hdev, "QCA read fw build info with no header");
|
||||
@@ -129,14 +135,25 @@ static int qca_read_fw_build_info(struct hci_dev *hdev)
|
||||
goto out;
|
||||
}
|
||||
|
||||
build_lbl_len = edl->data[0];
|
||||
if (build_lbl_len <= QCA_FW_BUILD_VER_LEN - 1) {
|
||||
memcpy(build_label, edl->data + 1, build_lbl_len);
|
||||
*(build_label + build_lbl_len) = '\0';
|
||||
if (skb->len < sizeof(*edl) + 1) {
|
||||
err = -EILSEQ;
|
||||
goto out;
|
||||
}
|
||||
|
||||
build_lbl_len = edl->data[0];
|
||||
|
||||
if (skb->len < sizeof(*edl) + 1 + build_lbl_len) {
|
||||
err = -EILSEQ;
|
||||
goto out;
|
||||
}
|
||||
|
||||
build_label = kstrndup(&edl->data[1], build_lbl_len, GFP_KERNEL);
|
||||
if (!build_label)
|
||||
goto out;
|
||||
|
||||
hci_set_fw_info(hdev, "%s", build_label);
|
||||
|
||||
kfree(build_label);
|
||||
out:
|
||||
kfree_skb(skb);
|
||||
return err;
|
||||
@@ -205,6 +222,49 @@ static int qca_send_reset(struct hci_dev *hdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int qca_read_fw_board_id(struct hci_dev *hdev, u16 *bid)
|
||||
{
|
||||
u8 cmd;
|
||||
struct sk_buff *skb;
|
||||
struct edl_event_hdr *edl;
|
||||
int err = 0;
|
||||
|
||||
cmd = EDL_GET_BID_REQ_CMD;
|
||||
skb = __hci_cmd_sync_ev(hdev, EDL_PATCH_CMD_OPCODE, EDL_PATCH_CMD_LEN,
|
||||
&cmd, 0, HCI_INIT_TIMEOUT);
|
||||
if (IS_ERR(skb)) {
|
||||
err = PTR_ERR(skb);
|
||||
bt_dev_err(hdev, "Reading QCA board ID failed (%d)", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
edl = skb_pull_data(skb, sizeof(*edl));
|
||||
if (!edl) {
|
||||
bt_dev_err(hdev, "QCA read board ID with no header");
|
||||
err = -EILSEQ;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (edl->cresp != EDL_CMD_REQ_RES_EVT ||
|
||||
edl->rtype != EDL_GET_BID_REQ_CMD) {
|
||||
bt_dev_err(hdev, "QCA Wrong packet: %d %d", edl->cresp, edl->rtype);
|
||||
err = -EIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (skb->len < 3) {
|
||||
err = -EILSEQ;
|
||||
goto out;
|
||||
}
|
||||
|
||||
*bid = (edl->data[1] << 8) + edl->data[2];
|
||||
bt_dev_dbg(hdev, "%s: bid = %x", __func__, *bid);
|
||||
|
||||
out:
|
||||
kfree_skb(skb);
|
||||
return err;
|
||||
}
|
||||
|
||||
int qca_send_pre_shutdown_cmd(struct hci_dev *hdev)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
@@ -227,9 +287,10 @@ int qca_send_pre_shutdown_cmd(struct hci_dev *hdev)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(qca_send_pre_shutdown_cmd);
|
||||
|
||||
static void qca_tlv_check_data(struct hci_dev *hdev,
|
||||
static int qca_tlv_check_data(struct hci_dev *hdev,
|
||||
struct qca_fw_config *config,
|
||||
u8 *fw_data, enum qca_btsoc_type soc_type)
|
||||
u8 *fw_data, size_t fw_size,
|
||||
enum qca_btsoc_type soc_type)
|
||||
{
|
||||
const u8 *data;
|
||||
u32 type_len;
|
||||
@@ -239,12 +300,16 @@ static void qca_tlv_check_data(struct hci_dev *hdev,
|
||||
struct tlv_type_patch *tlv_patch;
|
||||
struct tlv_type_nvm *tlv_nvm;
|
||||
uint8_t nvm_baud_rate = config->user_baud_rate;
|
||||
u8 type;
|
||||
|
||||
config->dnld_mode = QCA_SKIP_EVT_NONE;
|
||||
config->dnld_type = QCA_SKIP_EVT_NONE;
|
||||
|
||||
switch (config->type) {
|
||||
case ELF_TYPE_PATCH:
|
||||
if (fw_size < 7)
|
||||
return -EINVAL;
|
||||
|
||||
config->dnld_mode = QCA_SKIP_EVT_VSE_CC;
|
||||
config->dnld_type = QCA_SKIP_EVT_VSE_CC;
|
||||
|
||||
@@ -253,6 +318,9 @@ static void qca_tlv_check_data(struct hci_dev *hdev,
|
||||
bt_dev_dbg(hdev, "File version : 0x%x", fw_data[6]);
|
||||
break;
|
||||
case TLV_TYPE_PATCH:
|
||||
if (fw_size < sizeof(struct tlv_type_hdr) + sizeof(struct tlv_type_patch))
|
||||
return -EINVAL;
|
||||
|
||||
tlv = (struct tlv_type_hdr *)fw_data;
|
||||
type_len = le32_to_cpu(tlv->type_len);
|
||||
tlv_patch = (struct tlv_type_patch *)tlv->data;
|
||||
@@ -292,25 +360,56 @@ static void qca_tlv_check_data(struct hci_dev *hdev,
|
||||
break;
|
||||
|
||||
case TLV_TYPE_NVM:
|
||||
if (fw_size < sizeof(struct tlv_type_hdr))
|
||||
return -EINVAL;
|
||||
|
||||
tlv = (struct tlv_type_hdr *)fw_data;
|
||||
|
||||
type_len = le32_to_cpu(tlv->type_len);
|
||||
length = (type_len >> 8) & 0x00ffffff;
|
||||
length = type_len >> 8;
|
||||
type = type_len & 0xff;
|
||||
|
||||
BT_DBG("TLV Type\t\t : 0x%x", type_len & 0x000000ff);
|
||||
/* Some NVM files have more than one set of tags, only parse
|
||||
* the first set when it has type 2 for now. When there is
|
||||
* more than one set there is an enclosing header of type 4.
|
||||
*/
|
||||
if (type == 4) {
|
||||
if (fw_size < 2 * sizeof(struct tlv_type_hdr))
|
||||
return -EINVAL;
|
||||
|
||||
tlv++;
|
||||
|
||||
type_len = le32_to_cpu(tlv->type_len);
|
||||
length = type_len >> 8;
|
||||
type = type_len & 0xff;
|
||||
}
|
||||
|
||||
BT_DBG("TLV Type\t\t : 0x%x", type);
|
||||
BT_DBG("Length\t\t : %d bytes", length);
|
||||
|
||||
if (type != 2)
|
||||
break;
|
||||
|
||||
if (fw_size < length + (tlv->data - fw_data))
|
||||
return -EINVAL;
|
||||
|
||||
idx = 0;
|
||||
data = tlv->data;
|
||||
while (idx < length) {
|
||||
while (idx < length - sizeof(struct tlv_type_nvm)) {
|
||||
tlv_nvm = (struct tlv_type_nvm *)(data + idx);
|
||||
|
||||
tag_id = le16_to_cpu(tlv_nvm->tag_id);
|
||||
tag_len = le16_to_cpu(tlv_nvm->tag_len);
|
||||
|
||||
if (length < idx + sizeof(struct tlv_type_nvm) + tag_len)
|
||||
return -EINVAL;
|
||||
|
||||
/* Update NVM tags as needed */
|
||||
switch (tag_id) {
|
||||
case EDL_TAG_ID_HCI:
|
||||
if (tag_len < 3)
|
||||
return -EINVAL;
|
||||
|
||||
/* HCI transport layer parameters
|
||||
* enabling software inband sleep
|
||||
* onto controller side.
|
||||
@@ -326,6 +425,9 @@ static void qca_tlv_check_data(struct hci_dev *hdev,
|
||||
break;
|
||||
|
||||
case EDL_TAG_ID_DEEP_SLEEP:
|
||||
if (tag_len < 1)
|
||||
return -EINVAL;
|
||||
|
||||
/* Sleep enable mask
|
||||
* enabling deep sleep feature on controller.
|
||||
*/
|
||||
@@ -334,14 +436,16 @@ static void qca_tlv_check_data(struct hci_dev *hdev,
|
||||
break;
|
||||
}
|
||||
|
||||
idx += (sizeof(u16) + sizeof(u16) + 8 + tag_len);
|
||||
idx += sizeof(struct tlv_type_nvm) + tag_len;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
BT_ERR("Unknown TLV type %d", config->type);
|
||||
break;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int qca_tlv_send_segment(struct hci_dev *hdev, int seg_size,
|
||||
@@ -491,7 +595,9 @@ static int qca_download_firmware(struct hci_dev *hdev,
|
||||
memcpy(data, fw->data, size);
|
||||
release_firmware(fw);
|
||||
|
||||
qca_tlv_check_data(hdev, config, data, soc_type);
|
||||
ret = qca_tlv_check_data(hdev, config, data, size, soc_type);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
segment = data;
|
||||
remain = size;
|
||||
@@ -582,6 +688,7 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
|
||||
int err;
|
||||
u8 rom_ver = 0;
|
||||
u32 soc_ver;
|
||||
u16 boardid = 0;
|
||||
|
||||
bt_dev_dbg(hdev, "QCA setup on UART");
|
||||
|
||||
@@ -628,6 +735,9 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
|
||||
/* Give the controller some time to get ready to receive the NVM */
|
||||
msleep(10);
|
||||
|
||||
if (soc_type == QCA_QCA2066)
|
||||
qca_read_fw_board_id(hdev, &boardid);
|
||||
|
||||
/* Download NVM configuration */
|
||||
config.type = TLV_TYPE_NVM;
|
||||
if (firmware_name)
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#define EDL_PATCH_VER_REQ_CMD (0x19)
|
||||
#define EDL_PATCH_TLV_REQ_CMD (0x1E)
|
||||
#define EDL_GET_BUILD_INFO_CMD (0x20)
|
||||
#define EDL_GET_BID_REQ_CMD (0x23)
|
||||
#define EDL_NVM_ACCESS_SET_REQ_CMD (0x01)
|
||||
#define EDL_PATCH_CONFIG_CMD (0x28)
|
||||
#define MAX_SIZE_PER_TLV_SEGMENT (243)
|
||||
@@ -46,8 +47,8 @@
|
||||
#define get_soc_ver(soc_id, rom_ver) \
|
||||
((le32_to_cpu(soc_id) << 16) | (le16_to_cpu(rom_ver)))
|
||||
|
||||
#define QCA_FW_BUILD_VER_LEN 255
|
||||
|
||||
#define QCA_HSP_GF_SOC_ID 0x1200
|
||||
#define QCA_HSP_GF_SOC_MASK 0x0000ff00
|
||||
|
||||
enum qca_baudrate {
|
||||
QCA_BAUDRATE_115200 = 0,
|
||||
@@ -145,6 +146,7 @@ enum qca_btsoc_type {
|
||||
QCA_WCN3990,
|
||||
QCA_WCN3998,
|
||||
QCA_WCN3991,
|
||||
QCA_QCA2066,
|
||||
QCA_QCA6390,
|
||||
QCA_WCN6750,
|
||||
};
|
||||
|
||||
@@ -155,7 +155,7 @@ ssize_t tpm_common_read(struct file *file, char __user *buf,
|
||||
out:
|
||||
if (!priv->response_length) {
|
||||
*off = 0;
|
||||
del_singleshot_timer_sync(&priv->user_read_timer);
|
||||
del_timer_sync(&priv->user_read_timer);
|
||||
flush_work(&priv->timeout_work);
|
||||
}
|
||||
mutex_unlock(&priv->buffer_mutex);
|
||||
@@ -262,7 +262,7 @@ __poll_t tpm_common_poll(struct file *file, poll_table *wait)
|
||||
void tpm_common_release(struct file *file, struct file_priv *priv)
|
||||
{
|
||||
flush_work(&priv->async_work);
|
||||
del_singleshot_timer_sync(&priv->user_read_timer);
|
||||
del_timer_sync(&priv->user_read_timer);
|
||||
flush_work(&priv->timeout_work);
|
||||
file->private_data = NULL;
|
||||
priv->response_length = 0;
|
||||
|
||||
@@ -4500,7 +4500,8 @@ void clk_unregister(struct clk *clk)
|
||||
if (ops == &clk_nodrv_ops) {
|
||||
pr_err("%s: unregistered clock: %s\n", __func__,
|
||||
clk->core->name);
|
||||
goto unlock;
|
||||
clk_prepare_unlock();
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* Assign empty clock ops for consumers that might still hold
|
||||
@@ -4534,11 +4535,10 @@ void clk_unregister(struct clk *clk)
|
||||
if (clk->core->protect_count)
|
||||
pr_warn("%s: unregistering protected clock: %s\n",
|
||||
__func__, clk->core->name);
|
||||
clk_prepare_unlock();
|
||||
|
||||
kref_put(&clk->core->ref, __clk_release);
|
||||
free_clk(clk);
|
||||
unlock:
|
||||
clk_prepare_unlock();
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(clk_unregister);
|
||||
|
||||
@@ -4697,13 +4697,11 @@ void __clk_put(struct clk *clk)
|
||||
if (clk->min_rate > 0 || clk->max_rate < ULONG_MAX)
|
||||
clk_set_rate_range_nolock(clk, 0, ULONG_MAX);
|
||||
|
||||
owner = clk->core->owner;
|
||||
kref_put(&clk->core->ref, __clk_release);
|
||||
|
||||
clk_prepare_unlock();
|
||||
|
||||
owner = clk->core->owner;
|
||||
kref_put(&clk->core->ref, __clk_release);
|
||||
module_put(owner);
|
||||
|
||||
free_clk(clk);
|
||||
}
|
||||
|
||||
|
||||
@@ -1181,11 +1181,18 @@ static const u32 usb2_clk_regs[] = {
|
||||
SUN50I_H6_USB3_CLK_REG,
|
||||
};
|
||||
|
||||
static struct ccu_mux_nb sun50i_h6_cpu_nb = {
|
||||
.common = &cpux_clk.common,
|
||||
.cm = &cpux_clk.mux,
|
||||
.delay_us = 1,
|
||||
.bypass_index = 0, /* index of 24 MHz oscillator */
|
||||
};
|
||||
|
||||
static int sun50i_h6_ccu_probe(struct platform_device *pdev)
|
||||
{
|
||||
void __iomem *reg;
|
||||
int i, ret;
|
||||
u32 val;
|
||||
int i;
|
||||
|
||||
reg = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(reg))
|
||||
@@ -1252,7 +1259,15 @@ static int sun50i_h6_ccu_probe(struct platform_device *pdev)
|
||||
val |= BIT(24);
|
||||
writel(val, reg + SUN50I_H6_HDMI_CEC_CLK_REG);
|
||||
|
||||
return devm_sunxi_ccu_probe(&pdev->dev, reg, &sun50i_h6_ccu_desc);
|
||||
ret = devm_sunxi_ccu_probe(&pdev->dev, reg, &sun50i_h6_ccu_desc);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Reparent CPU during PLL CPUX rate changes */
|
||||
ccu_mux_notifier_register(pll_cpux_clk.common.hw.clk,
|
||||
&sun50i_h6_cpu_nb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id sun50i_h6_ccu_ids[] = {
|
||||
|
||||
@@ -197,6 +197,18 @@ static int idxd_cdev_mmap(struct file *filp, struct vm_area_struct *vma)
|
||||
int rc;
|
||||
|
||||
dev_dbg(&pdev->dev, "%s called\n", __func__);
|
||||
|
||||
/*
|
||||
* Due to an erratum in some of the devices supported by the driver,
|
||||
* direct user submission to the device can be unsafe.
|
||||
* (See the INTEL-SA-01084 security advisory)
|
||||
*
|
||||
* For the devices that exhibit this behavior, require that the user
|
||||
* has CAP_SYS_RAWIO capabilities.
|
||||
*/
|
||||
if (!idxd->user_submission_safe && !capable(CAP_SYS_RAWIO))
|
||||
return -EPERM;
|
||||
|
||||
rc = check_vma(wq, vma, __func__);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
@@ -211,6 +223,70 @@ static int idxd_cdev_mmap(struct file *filp, struct vm_area_struct *vma)
|
||||
vma->vm_page_prot);
|
||||
}
|
||||
|
||||
static int idxd_submit_user_descriptor(struct idxd_user_context *ctx,
|
||||
struct dsa_hw_desc __user *udesc)
|
||||
{
|
||||
struct idxd_wq *wq = ctx->wq;
|
||||
struct idxd_dev *idxd_dev = &wq->idxd->idxd_dev;
|
||||
const uint64_t comp_addr_align = is_dsa_dev(idxd_dev) ? 0x20 : 0x40;
|
||||
void __iomem *portal = idxd_wq_portal_addr(wq);
|
||||
struct dsa_hw_desc descriptor __aligned(64);
|
||||
int rc;
|
||||
|
||||
rc = copy_from_user(&descriptor, udesc, sizeof(descriptor));
|
||||
if (rc)
|
||||
return -EFAULT;
|
||||
|
||||
/*
|
||||
* DSA devices are capable of indirect ("batch") command submission.
|
||||
* On devices where direct user submissions are not safe, we cannot
|
||||
* allow this since there is no good way for us to verify these
|
||||
* indirect commands.
|
||||
*/
|
||||
if (is_dsa_dev(idxd_dev) && descriptor.opcode == DSA_OPCODE_BATCH &&
|
||||
!wq->idxd->user_submission_safe)
|
||||
return -EINVAL;
|
||||
/*
|
||||
* As per the programming specification, the completion address must be
|
||||
* aligned to 32 or 64 bytes. If this is violated the hardware
|
||||
* engine can get very confused (security issue).
|
||||
*/
|
||||
if (!IS_ALIGNED(descriptor.completion_addr, comp_addr_align))
|
||||
return -EINVAL;
|
||||
|
||||
if (wq_dedicated(wq))
|
||||
iosubmit_cmds512(portal, &descriptor, 1);
|
||||
else {
|
||||
descriptor.priv = 0;
|
||||
descriptor.pasid = ctx->pasid;
|
||||
rc = idxd_enqcmds(wq, portal, &descriptor);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t idxd_cdev_write(struct file *filp, const char __user *buf, size_t len,
|
||||
loff_t *unused)
|
||||
{
|
||||
struct dsa_hw_desc __user *udesc = (struct dsa_hw_desc __user *)buf;
|
||||
struct idxd_user_context *ctx = filp->private_data;
|
||||
ssize_t written = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < len/sizeof(struct dsa_hw_desc); i++) {
|
||||
int rc = idxd_submit_user_descriptor(ctx, udesc + i);
|
||||
|
||||
if (rc)
|
||||
return written ? written : rc;
|
||||
|
||||
written += sizeof(struct dsa_hw_desc);
|
||||
}
|
||||
|
||||
return written;
|
||||
}
|
||||
|
||||
static __poll_t idxd_cdev_poll(struct file *filp,
|
||||
struct poll_table_struct *wait)
|
||||
{
|
||||
@@ -233,6 +309,7 @@ static const struct file_operations idxd_cdev_fops = {
|
||||
.open = idxd_cdev_open,
|
||||
.release = idxd_cdev_release,
|
||||
.mmap = idxd_cdev_mmap,
|
||||
.write = idxd_cdev_write,
|
||||
.poll = idxd_cdev_poll,
|
||||
};
|
||||
|
||||
|
||||
@@ -258,6 +258,7 @@ struct idxd_driver_data {
|
||||
struct device_type *dev_type;
|
||||
int compl_size;
|
||||
int align;
|
||||
bool user_submission_safe;
|
||||
};
|
||||
|
||||
struct idxd_device {
|
||||
@@ -316,6 +317,8 @@ struct idxd_device {
|
||||
struct idxd_pmu *idxd_pmu;
|
||||
|
||||
unsigned long *opcap_bmap;
|
||||
|
||||
bool user_submission_safe;
|
||||
};
|
||||
|
||||
/* IDXD software descriptor */
|
||||
|
||||
@@ -47,6 +47,7 @@ static struct idxd_driver_data idxd_driver_data[] = {
|
||||
.compl_size = sizeof(struct dsa_completion_record),
|
||||
.align = 32,
|
||||
.dev_type = &dsa_device_type,
|
||||
.user_submission_safe = false, /* See INTEL-SA-01084 security advisory */
|
||||
},
|
||||
[IDXD_TYPE_IAX] = {
|
||||
.name_prefix = "iax",
|
||||
@@ -54,6 +55,7 @@ static struct idxd_driver_data idxd_driver_data[] = {
|
||||
.compl_size = sizeof(struct iax_completion_record),
|
||||
.align = 64,
|
||||
.dev_type = &iax_device_type,
|
||||
.user_submission_safe = false, /* See INTEL-SA-01084 security advisory */
|
||||
},
|
||||
};
|
||||
|
||||
@@ -640,6 +642,8 @@ static int idxd_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
dev_info(&pdev->dev, "Intel(R) Accelerator Device (v%x)\n",
|
||||
idxd->hw.version);
|
||||
|
||||
idxd->user_submission_safe = data->user_submission_safe;
|
||||
|
||||
return 0;
|
||||
|
||||
err_dev_register:
|
||||
|
||||
@@ -4,9 +4,6 @@
|
||||
#define _IDXD_REGISTERS_H_
|
||||
|
||||
/* PCI Config */
|
||||
#define PCI_DEVICE_ID_INTEL_DSA_SPR0 0x0b25
|
||||
#define PCI_DEVICE_ID_INTEL_IAX_SPR0 0x0cfe
|
||||
|
||||
#define DEVICE_VERSION_1 0x100
|
||||
#define DEVICE_VERSION_2 0x200
|
||||
|
||||
|
||||
@@ -1162,12 +1162,35 @@ static ssize_t wq_enqcmds_retries_store(struct device *dev, struct device_attrib
|
||||
static struct device_attribute dev_attr_wq_enqcmds_retries =
|
||||
__ATTR(enqcmds_retries, 0644, wq_enqcmds_retries_show, wq_enqcmds_retries_store);
|
||||
|
||||
static ssize_t op_cap_show_common(struct device *dev, char *buf, unsigned long *opcap_bmap)
|
||||
{
|
||||
ssize_t pos;
|
||||
int i;
|
||||
|
||||
pos = 0;
|
||||
for (i = IDXD_MAX_OPCAP_BITS/64 - 1; i >= 0; i--) {
|
||||
unsigned long val = opcap_bmap[i];
|
||||
|
||||
/* On systems where direct user submissions are not safe, we need to clear out
|
||||
* the BATCH capability from the capability mask in sysfs since we cannot support
|
||||
* that command on such systems.
|
||||
*/
|
||||
if (i == DSA_OPCODE_BATCH/64 && !confdev_to_idxd(dev)->user_submission_safe)
|
||||
clear_bit(DSA_OPCODE_BATCH % 64, &val);
|
||||
|
||||
pos += sysfs_emit_at(buf, pos, "%*pb", 64, &val);
|
||||
pos += sysfs_emit_at(buf, pos, "%c", i == 0 ? '\n' : ',');
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
static ssize_t wq_op_config_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct idxd_wq *wq = confdev_to_wq(dev);
|
||||
|
||||
return sysfs_emit(buf, "%*pb\n", IDXD_MAX_OPCAP_BITS, wq->opcap_bmap);
|
||||
return op_cap_show_common(dev, buf, wq->opcap_bmap);
|
||||
}
|
||||
|
||||
static int idxd_verify_supported_opcap(struct idxd_device *idxd, unsigned long *opmask)
|
||||
@@ -1381,7 +1404,7 @@ static ssize_t op_cap_show(struct device *dev,
|
||||
{
|
||||
struct idxd_device *idxd = confdev_to_idxd(dev);
|
||||
|
||||
return sysfs_emit(buf, "%*pb\n", IDXD_MAX_OPCAP_BITS, idxd->opcap_bmap);
|
||||
return op_cap_show_common(dev, buf, idxd->opcap_bmap);
|
||||
}
|
||||
static DEVICE_ATTR_RO(op_cap);
|
||||
|
||||
|
||||
@@ -148,10 +148,12 @@ packet_buffer_get(struct client *client, char __user *data, size_t user_length)
|
||||
if (atomic_read(&buffer->size) == 0)
|
||||
return -ENODEV;
|
||||
|
||||
/* FIXME: Check length <= user_length. */
|
||||
length = buffer->head->length;
|
||||
|
||||
if (length > user_length)
|
||||
return 0;
|
||||
|
||||
end = buffer->data + buffer->capacity;
|
||||
length = buffer->head->length;
|
||||
|
||||
if (&buffer->head->data[length] < end) {
|
||||
if (copy_to_user(data, buffer->head->data, length))
|
||||
|
||||
@@ -2049,6 +2049,8 @@ static void bus_reset_work(struct work_struct *work)
|
||||
|
||||
ohci->generation = generation;
|
||||
reg_write(ohci, OHCI1394_IntEventClear, OHCI1394_busReset);
|
||||
if (param_debug & OHCI_PARAM_DEBUG_BUSRESETS)
|
||||
reg_write(ohci, OHCI1394_IntMaskSet, OHCI1394_busReset);
|
||||
|
||||
if (ohci->quirks & QUIRK_RESET_PACKET)
|
||||
ohci->request_generation = generation;
|
||||
@@ -2115,12 +2117,14 @@ static irqreturn_t irq_handler(int irq, void *data)
|
||||
return IRQ_NONE;
|
||||
|
||||
/*
|
||||
* busReset and postedWriteErr must not be cleared yet
|
||||
* busReset and postedWriteErr events must not be cleared yet
|
||||
* (OHCI 1.1 clauses 7.2.3.2 and 13.2.8.1)
|
||||
*/
|
||||
reg_write(ohci, OHCI1394_IntEventClear,
|
||||
event & ~(OHCI1394_busReset | OHCI1394_postedWriteErr));
|
||||
log_irqs(ohci, event);
|
||||
if (event & OHCI1394_busReset)
|
||||
reg_write(ohci, OHCI1394_IntMaskClear, OHCI1394_busReset);
|
||||
|
||||
if (event & OHCI1394_selfIDComplete)
|
||||
queue_work(selfid_workqueue, &ohci->bus_reset_work);
|
||||
|
||||
@@ -92,7 +92,7 @@ static inline int to_reg(int gpio, enum ctrl_register reg_type)
|
||||
case 0x5e:
|
||||
return GPIOPANELCTL;
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -104,7 +104,7 @@ static inline int to_reg(int gpio, enum ctrl_register type)
|
||||
unsigned int reg = type == CTRL_IN ? GPIO_IN_CTRL_BASE : GPIO_OUT_CTRL_BASE;
|
||||
|
||||
if (gpio >= WCOVE_GPIO_NUM)
|
||||
return -EOPNOTSUPP;
|
||||
return -ENOTSUPP;
|
||||
|
||||
return reg + gpio;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <linux/bitmap.h>
|
||||
#include <linux/build_bug.h>
|
||||
#include <linux/cdev.h>
|
||||
#include <linux/cleanup.h>
|
||||
#include <linux/compat.h>
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/device.h>
|
||||
@@ -12,6 +13,7 @@
|
||||
#include <linux/file.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/gpio/driver.h>
|
||||
#include <linux/hte.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irqreturn.h>
|
||||
#include <linux/kernel.h>
|
||||
@@ -20,11 +22,13 @@
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/pinctrl/consumer.h>
|
||||
#include <linux/poll.h>
|
||||
#include <linux/rbtree.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/timekeeping.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/hte.h>
|
||||
|
||||
#include <uapi/linux/gpio.h>
|
||||
|
||||
#include "gpiolib.h"
|
||||
@@ -463,6 +467,7 @@ out_free_lh:
|
||||
|
||||
/**
|
||||
* struct line - contains the state of a requested line
|
||||
* @node: to store the object in supinfo_tree if supplemental
|
||||
* @desc: the GPIO descriptor for this line.
|
||||
* @req: the corresponding line request
|
||||
* @irq: the interrupt triggered in response to events on this GPIO
|
||||
@@ -475,6 +480,7 @@ out_free_lh:
|
||||
* @line_seqno: the seqno for the current edge event in the sequence of
|
||||
* events for this line.
|
||||
* @work: the worker that implements software debouncing
|
||||
* @debounce_period_us: the debounce period in microseconds
|
||||
* @sw_debounced: flag indicating if the software debouncer is active
|
||||
* @level: the current debounced physical level of the line
|
||||
* @hdesc: the Hardware Timestamp Engine (HTE) descriptor
|
||||
@@ -483,6 +489,7 @@ out_free_lh:
|
||||
* @last_seqno: the last sequence number before debounce period expires
|
||||
*/
|
||||
struct line {
|
||||
struct rb_node node;
|
||||
struct gpio_desc *desc;
|
||||
/*
|
||||
* -- edge detector specific fields --
|
||||
@@ -516,6 +523,15 @@ struct line {
|
||||
* -- debouncer specific fields --
|
||||
*/
|
||||
struct delayed_work work;
|
||||
/*
|
||||
* debounce_period_us is accessed by debounce_irq_handler() and
|
||||
* process_hw_ts() which are disabled when modified by
|
||||
* debounce_setup(), edge_detector_setup() or edge_detector_stop()
|
||||
* or can live with a stale version when updated by
|
||||
* edge_detector_update().
|
||||
* The modifying functions are themselves mutually exclusive.
|
||||
*/
|
||||
unsigned int debounce_period_us;
|
||||
/*
|
||||
* sw_debounce is accessed by linereq_set_config(), which is the
|
||||
* only setter, and linereq_get_values(), which can live with a
|
||||
@@ -548,6 +564,17 @@ struct line {
|
||||
#endif /* CONFIG_HTE */
|
||||
};
|
||||
|
||||
/*
|
||||
* a rbtree of the struct lines containing supplemental info.
|
||||
* Used to populate gpio_v2_line_info with cdev specific fields not contained
|
||||
* in the struct gpio_desc.
|
||||
* A line is determined to contain supplemental information by
|
||||
* line_has_supinfo().
|
||||
*/
|
||||
static struct rb_root supinfo_tree = RB_ROOT;
|
||||
/* covers supinfo_tree */
|
||||
static DEFINE_SPINLOCK(supinfo_lock);
|
||||
|
||||
/**
|
||||
* struct linereq - contains the state of a userspace line request
|
||||
* @gdev: the GPIO device the line request pertains to
|
||||
@@ -560,7 +587,8 @@ struct line {
|
||||
* this line request. Note that this is not used when @num_lines is 1, as
|
||||
* the line_seqno is then the same and is cheaper to calculate.
|
||||
* @config_mutex: mutex for serializing ioctl() calls to ensure consistency
|
||||
* of configuration, particularly multi-step accesses to desc flags.
|
||||
* of configuration, particularly multi-step accesses to desc flags and
|
||||
* changes to supinfo status.
|
||||
* @lines: the lines held by this line request, with @num_lines elements.
|
||||
*/
|
||||
struct linereq {
|
||||
@@ -575,6 +603,103 @@ struct linereq {
|
||||
struct line lines[];
|
||||
};
|
||||
|
||||
static void supinfo_insert(struct line *line)
|
||||
{
|
||||
struct rb_node **new = &(supinfo_tree.rb_node), *parent = NULL;
|
||||
struct line *entry;
|
||||
|
||||
guard(spinlock)(&supinfo_lock);
|
||||
|
||||
while (*new) {
|
||||
entry = container_of(*new, struct line, node);
|
||||
|
||||
parent = *new;
|
||||
if (line->desc < entry->desc) {
|
||||
new = &((*new)->rb_left);
|
||||
} else if (line->desc > entry->desc) {
|
||||
new = &((*new)->rb_right);
|
||||
} else {
|
||||
/* this should never happen */
|
||||
WARN(1, "duplicate line inserted");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
rb_link_node(&line->node, parent, new);
|
||||
rb_insert_color(&line->node, &supinfo_tree);
|
||||
}
|
||||
|
||||
static void supinfo_erase(struct line *line)
|
||||
{
|
||||
guard(spinlock)(&supinfo_lock);
|
||||
|
||||
rb_erase(&line->node, &supinfo_tree);
|
||||
}
|
||||
|
||||
static struct line *supinfo_find(struct gpio_desc *desc)
|
||||
{
|
||||
struct rb_node *node = supinfo_tree.rb_node;
|
||||
struct line *line;
|
||||
|
||||
while (node) {
|
||||
line = container_of(node, struct line, node);
|
||||
if (desc < line->desc)
|
||||
node = node->rb_left;
|
||||
else if (desc > line->desc)
|
||||
node = node->rb_right;
|
||||
else
|
||||
return line;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void supinfo_to_lineinfo(struct gpio_desc *desc,
|
||||
struct gpio_v2_line_info *info)
|
||||
{
|
||||
struct gpio_v2_line_attribute *attr;
|
||||
struct line *line;
|
||||
|
||||
guard(spinlock)(&supinfo_lock);
|
||||
|
||||
line = supinfo_find(desc);
|
||||
if (!line)
|
||||
return;
|
||||
|
||||
attr = &info->attrs[info->num_attrs];
|
||||
attr->id = GPIO_V2_LINE_ATTR_ID_DEBOUNCE;
|
||||
attr->debounce_period_us = READ_ONCE(line->debounce_period_us);
|
||||
info->num_attrs++;
|
||||
}
|
||||
|
||||
static inline bool line_has_supinfo(struct line *line)
|
||||
{
|
||||
return READ_ONCE(line->debounce_period_us);
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks line_has_supinfo() before and after the change to avoid unnecessary
|
||||
* supinfo_tree access.
|
||||
* Called indirectly by linereq_create() or linereq_set_config() so line
|
||||
* is already protected from concurrent changes.
|
||||
*/
|
||||
static void line_set_debounce_period(struct line *line,
|
||||
unsigned int debounce_period_us)
|
||||
{
|
||||
bool was_suppl = line_has_supinfo(line);
|
||||
|
||||
WRITE_ONCE(line->debounce_period_us, debounce_period_us);
|
||||
|
||||
/* if supinfo status is unchanged then we're done */
|
||||
if (line_has_supinfo(line) == was_suppl)
|
||||
return;
|
||||
|
||||
/* supinfo status has changed, so update the tree */
|
||||
if (was_suppl)
|
||||
supinfo_erase(line);
|
||||
else
|
||||
supinfo_insert(line);
|
||||
}
|
||||
|
||||
#define GPIO_V2_LINE_BIAS_FLAGS \
|
||||
(GPIO_V2_LINE_FLAG_BIAS_PULL_UP | \
|
||||
GPIO_V2_LINE_FLAG_BIAS_PULL_DOWN | \
|
||||
@@ -712,7 +837,7 @@ static enum hte_return process_hw_ts(struct hte_ts_data *ts, void *p)
|
||||
line->total_discard_seq++;
|
||||
line->last_seqno = ts->seq;
|
||||
mod_delayed_work(system_wq, &line->work,
|
||||
usecs_to_jiffies(READ_ONCE(line->desc->debounce_period_us)));
|
||||
usecs_to_jiffies(READ_ONCE(line->debounce_period_us)));
|
||||
} else {
|
||||
if (unlikely(ts->seq < line->line_seqno))
|
||||
return HTE_CB_HANDLED;
|
||||
@@ -853,7 +978,7 @@ static irqreturn_t debounce_irq_handler(int irq, void *p)
|
||||
struct line *line = p;
|
||||
|
||||
mod_delayed_work(system_wq, &line->work,
|
||||
usecs_to_jiffies(READ_ONCE(line->desc->debounce_period_us)));
|
||||
usecs_to_jiffies(READ_ONCE(line->debounce_period_us)));
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
@@ -935,7 +1060,7 @@ static int debounce_setup(struct line *line, unsigned int debounce_period_us)
|
||||
/* try hardware */
|
||||
ret = gpiod_set_debounce(line->desc, debounce_period_us);
|
||||
if (!ret) {
|
||||
WRITE_ONCE(line->desc->debounce_period_us, debounce_period_us);
|
||||
line_set_debounce_period(line, debounce_period_us);
|
||||
return ret;
|
||||
}
|
||||
if (ret != -ENOTSUPP)
|
||||
@@ -1014,8 +1139,7 @@ static void edge_detector_stop(struct line *line)
|
||||
cancel_delayed_work_sync(&line->work);
|
||||
WRITE_ONCE(line->sw_debounced, 0);
|
||||
WRITE_ONCE(line->edflags, 0);
|
||||
if (line->desc)
|
||||
WRITE_ONCE(line->desc->debounce_period_us, 0);
|
||||
line_set_debounce_period(line, 0);
|
||||
/* do not change line->level - see comment in debounced_value() */
|
||||
}
|
||||
|
||||
@@ -1040,7 +1164,7 @@ static int edge_detector_setup(struct line *line,
|
||||
ret = debounce_setup(line, debounce_period_us);
|
||||
if (ret)
|
||||
return ret;
|
||||
WRITE_ONCE(line->desc->debounce_period_us, debounce_period_us);
|
||||
line_set_debounce_period(line, debounce_period_us);
|
||||
}
|
||||
|
||||
/* detection disabled or sw debouncer will provide edge detection */
|
||||
@@ -1077,17 +1201,31 @@ static int edge_detector_update(struct line *line,
|
||||
struct gpio_v2_line_config *lc,
|
||||
unsigned int line_idx, u64 edflags)
|
||||
{
|
||||
u64 eflags;
|
||||
int ret;
|
||||
u64 active_edflags = READ_ONCE(line->edflags);
|
||||
unsigned int debounce_period_us =
|
||||
gpio_v2_line_config_debounce_period(lc, line_idx);
|
||||
|
||||
if ((active_edflags == edflags) &&
|
||||
(READ_ONCE(line->desc->debounce_period_us) == debounce_period_us))
|
||||
(READ_ONCE(line->debounce_period_us) == debounce_period_us))
|
||||
return 0;
|
||||
|
||||
/* sw debounced and still will be...*/
|
||||
if (debounce_period_us && READ_ONCE(line->sw_debounced)) {
|
||||
WRITE_ONCE(line->desc->debounce_period_us, debounce_period_us);
|
||||
line_set_debounce_period(line, debounce_period_us);
|
||||
/*
|
||||
* ensure event fifo is initialised if edge detection
|
||||
* is now enabled.
|
||||
*/
|
||||
eflags = edflags & GPIO_V2_LINE_EDGE_FLAGS;
|
||||
if (eflags && !kfifo_initialized(&line->req->events)) {
|
||||
ret = kfifo_alloc(&line->req->events,
|
||||
line->req->event_buffer_size,
|
||||
GFP_KERNEL);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1564,13 +1702,18 @@ static ssize_t linereq_read(struct file *file, char __user *buf,
|
||||
|
||||
static void linereq_free(struct linereq *lr)
|
||||
{
|
||||
struct line *line;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < lr->num_lines; i++) {
|
||||
if (lr->lines[i].desc) {
|
||||
edge_detector_stop(&lr->lines[i]);
|
||||
gpiod_free(lr->lines[i].desc);
|
||||
}
|
||||
line = &lr->lines[i];
|
||||
if (!line->desc)
|
||||
continue;
|
||||
|
||||
edge_detector_stop(line);
|
||||
if (line_has_supinfo(line))
|
||||
supinfo_erase(line);
|
||||
gpiod_free(line->desc);
|
||||
}
|
||||
kfifo_free(&lr->events);
|
||||
kfree(lr->label);
|
||||
@@ -2237,8 +2380,6 @@ static void gpio_desc_to_lineinfo(struct gpio_desc *desc,
|
||||
struct gpio_chip *gc = desc->gdev->chip;
|
||||
bool ok_for_pinctrl;
|
||||
unsigned long flags;
|
||||
u32 debounce_period_us;
|
||||
unsigned int num_attrs = 0;
|
||||
|
||||
memset(info, 0, sizeof(*info));
|
||||
info->offset = gpio_chip_hwgpio(desc);
|
||||
@@ -2305,14 +2446,6 @@ static void gpio_desc_to_lineinfo(struct gpio_desc *desc,
|
||||
else if (test_bit(FLAG_EVENT_CLOCK_HTE, &desc->flags))
|
||||
info->flags |= GPIO_V2_LINE_FLAG_EVENT_CLOCK_HTE;
|
||||
|
||||
debounce_period_us = READ_ONCE(desc->debounce_period_us);
|
||||
if (debounce_period_us) {
|
||||
info->attrs[num_attrs].id = GPIO_V2_LINE_ATTR_ID_DEBOUNCE;
|
||||
info->attrs[num_attrs].debounce_period_us = debounce_period_us;
|
||||
num_attrs++;
|
||||
}
|
||||
info->num_attrs = num_attrs;
|
||||
|
||||
spin_unlock_irqrestore(&gpio_lock, flags);
|
||||
}
|
||||
|
||||
@@ -2418,6 +2551,7 @@ static int lineinfo_get(struct gpio_chardev_data *cdev, void __user *ip,
|
||||
return -EBUSY;
|
||||
}
|
||||
gpio_desc_to_lineinfo(desc, &lineinfo);
|
||||
supinfo_to_lineinfo(desc, &lineinfo);
|
||||
|
||||
if (copy_to_user(ip, &lineinfo, sizeof(lineinfo))) {
|
||||
if (watch)
|
||||
@@ -2521,6 +2655,7 @@ static int lineinfo_changed_notify(struct notifier_block *nb,
|
||||
chg.event_type = action;
|
||||
chg.timestamp_ns = ktime_get_ns();
|
||||
gpio_desc_to_lineinfo(desc, &chg.info);
|
||||
supinfo_to_lineinfo(desc, &chg.info);
|
||||
|
||||
ret = kfifo_in_spinlocked(&cdev->events, &chg, 1, &cdev->wait.lock);
|
||||
if (ret)
|
||||
|
||||
@@ -301,12 +301,15 @@ static struct dma_fence *amdgpu_job_run(struct drm_sched_job *sched_job)
|
||||
dma_fence_set_error(finished, -ECANCELED);
|
||||
|
||||
if (finished->error < 0) {
|
||||
DRM_INFO("Skip scheduling IBs!\n");
|
||||
dev_dbg(adev->dev, "Skip scheduling IBs in ring(%s)",
|
||||
ring->name);
|
||||
} else {
|
||||
r = amdgpu_ib_schedule(ring, job->num_ibs, job->ibs, job,
|
||||
&fence);
|
||||
if (r)
|
||||
DRM_ERROR("Error scheduling IBs (%d)\n", r);
|
||||
dev_err(adev->dev,
|
||||
"Error scheduling IBs (%d) in ring(%s)", r,
|
||||
ring->name);
|
||||
}
|
||||
|
||||
job->job_run_counter++;
|
||||
|
||||
@@ -1222,14 +1222,18 @@ int amdgpu_bo_get_metadata(struct amdgpu_bo *bo, void *buffer,
|
||||
* amdgpu_bo_move_notify - notification about a memory move
|
||||
* @bo: pointer to a buffer object
|
||||
* @evict: if this move is evicting the buffer from the graphics address space
|
||||
* @new_mem: new resource for backing the BO
|
||||
*
|
||||
* Marks the corresponding &amdgpu_bo buffer object as invalid, also performs
|
||||
* bookkeeping.
|
||||
* TTM driver callback which is called when ttm moves a buffer.
|
||||
*/
|
||||
void amdgpu_bo_move_notify(struct ttm_buffer_object *bo, bool evict)
|
||||
void amdgpu_bo_move_notify(struct ttm_buffer_object *bo,
|
||||
bool evict,
|
||||
struct ttm_resource *new_mem)
|
||||
{
|
||||
struct amdgpu_device *adev = amdgpu_ttm_adev(bo->bdev);
|
||||
struct ttm_resource *old_mem = bo->resource;
|
||||
struct amdgpu_bo *abo;
|
||||
|
||||
if (!amdgpu_bo_is_amdgpu_bo(bo))
|
||||
@@ -1241,12 +1245,12 @@ void amdgpu_bo_move_notify(struct ttm_buffer_object *bo, bool evict)
|
||||
amdgpu_bo_kunmap(abo);
|
||||
|
||||
if (abo->tbo.base.dma_buf && !abo->tbo.base.import_attach &&
|
||||
bo->resource->mem_type != TTM_PL_SYSTEM)
|
||||
old_mem && old_mem->mem_type != TTM_PL_SYSTEM)
|
||||
dma_buf_move_notify(abo->tbo.base.dma_buf);
|
||||
|
||||
/* remember the eviction */
|
||||
if (evict)
|
||||
atomic64_inc(&adev->num_evictions);
|
||||
/* move_notify is called before move happens */
|
||||
trace_amdgpu_bo_move(abo, new_mem ? new_mem->mem_type : -1,
|
||||
old_mem ? old_mem->mem_type : -1);
|
||||
}
|
||||
|
||||
void amdgpu_bo_get_memory(struct amdgpu_bo *bo, uint64_t *vram_mem,
|
||||
|
||||
@@ -312,7 +312,9 @@ int amdgpu_bo_set_metadata (struct amdgpu_bo *bo, void *metadata,
|
||||
int amdgpu_bo_get_metadata(struct amdgpu_bo *bo, void *buffer,
|
||||
size_t buffer_size, uint32_t *metadata_size,
|
||||
uint64_t *flags);
|
||||
void amdgpu_bo_move_notify(struct ttm_buffer_object *bo, bool evict);
|
||||
void amdgpu_bo_move_notify(struct ttm_buffer_object *bo,
|
||||
bool evict,
|
||||
struct ttm_resource *new_mem);
|
||||
void amdgpu_bo_release_notify(struct ttm_buffer_object *bo);
|
||||
vm_fault_t amdgpu_bo_fault_reserve_notify(struct ttm_buffer_object *bo);
|
||||
void amdgpu_bo_fence(struct amdgpu_bo *bo, struct dma_fence *fence,
|
||||
|
||||
@@ -483,14 +483,16 @@ static int amdgpu_bo_move(struct ttm_buffer_object *bo, bool evict,
|
||||
|
||||
if (!old_mem || (old_mem->mem_type == TTM_PL_SYSTEM &&
|
||||
bo->ttm == NULL)) {
|
||||
amdgpu_bo_move_notify(bo, evict, new_mem);
|
||||
ttm_bo_move_null(bo, new_mem);
|
||||
goto out;
|
||||
return 0;
|
||||
}
|
||||
if (old_mem->mem_type == TTM_PL_SYSTEM &&
|
||||
(new_mem->mem_type == TTM_PL_TT ||
|
||||
new_mem->mem_type == AMDGPU_PL_PREEMPT)) {
|
||||
amdgpu_bo_move_notify(bo, evict, new_mem);
|
||||
ttm_bo_move_null(bo, new_mem);
|
||||
goto out;
|
||||
return 0;
|
||||
}
|
||||
if ((old_mem->mem_type == TTM_PL_TT ||
|
||||
old_mem->mem_type == AMDGPU_PL_PREEMPT) &&
|
||||
@@ -500,9 +502,10 @@ static int amdgpu_bo_move(struct ttm_buffer_object *bo, bool evict,
|
||||
return r;
|
||||
|
||||
amdgpu_ttm_backend_unbind(bo->bdev, bo->ttm);
|
||||
amdgpu_bo_move_notify(bo, evict, new_mem);
|
||||
ttm_resource_free(bo, &bo->resource);
|
||||
ttm_bo_assign_mem(bo, new_mem);
|
||||
goto out;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (old_mem->mem_type == AMDGPU_PL_GDS ||
|
||||
@@ -512,8 +515,9 @@ static int amdgpu_bo_move(struct ttm_buffer_object *bo, bool evict,
|
||||
new_mem->mem_type == AMDGPU_PL_GWS ||
|
||||
new_mem->mem_type == AMDGPU_PL_OA) {
|
||||
/* Nothing to save here */
|
||||
amdgpu_bo_move_notify(bo, evict, new_mem);
|
||||
ttm_bo_move_null(bo, new_mem);
|
||||
goto out;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (bo->type == ttm_bo_type_device &&
|
||||
@@ -525,23 +529,24 @@ static int amdgpu_bo_move(struct ttm_buffer_object *bo, bool evict,
|
||||
abo->flags &= ~AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED;
|
||||
}
|
||||
|
||||
if (adev->mman.buffer_funcs_enabled) {
|
||||
if (((old_mem->mem_type == TTM_PL_SYSTEM &&
|
||||
new_mem->mem_type == TTM_PL_VRAM) ||
|
||||
(old_mem->mem_type == TTM_PL_VRAM &&
|
||||
new_mem->mem_type == TTM_PL_SYSTEM))) {
|
||||
hop->fpfn = 0;
|
||||
hop->lpfn = 0;
|
||||
hop->mem_type = TTM_PL_TT;
|
||||
hop->flags = TTM_PL_FLAG_TEMPORARY;
|
||||
return -EMULTIHOP;
|
||||
}
|
||||
|
||||
r = amdgpu_move_blit(bo, evict, new_mem, old_mem);
|
||||
} else {
|
||||
r = -ENODEV;
|
||||
if (adev->mman.buffer_funcs_enabled &&
|
||||
((old_mem->mem_type == TTM_PL_SYSTEM &&
|
||||
new_mem->mem_type == TTM_PL_VRAM) ||
|
||||
(old_mem->mem_type == TTM_PL_VRAM &&
|
||||
new_mem->mem_type == TTM_PL_SYSTEM))) {
|
||||
hop->fpfn = 0;
|
||||
hop->lpfn = 0;
|
||||
hop->mem_type = TTM_PL_TT;
|
||||
hop->flags = TTM_PL_FLAG_TEMPORARY;
|
||||
return -EMULTIHOP;
|
||||
}
|
||||
|
||||
amdgpu_bo_move_notify(bo, evict, new_mem);
|
||||
if (adev->mman.buffer_funcs_enabled)
|
||||
r = amdgpu_move_blit(bo, evict, new_mem, old_mem);
|
||||
else
|
||||
r = -ENODEV;
|
||||
|
||||
if (r) {
|
||||
/* Check that all memory is CPU accessible */
|
||||
if (!amdgpu_mem_visible(adev, old_mem) ||
|
||||
@@ -555,11 +560,10 @@ static int amdgpu_bo_move(struct ttm_buffer_object *bo, bool evict,
|
||||
return r;
|
||||
}
|
||||
|
||||
trace_amdgpu_bo_move(abo, new_mem->mem_type, old_mem->mem_type);
|
||||
out:
|
||||
/* update statistics */
|
||||
/* update statistics after the move */
|
||||
if (evict)
|
||||
atomic64_inc(&adev->num_evictions);
|
||||
atomic64_add(bo->base.size, &adev->num_bytes_moved);
|
||||
amdgpu_bo_move_notify(bo, evict);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1505,7 +1509,7 @@ static int amdgpu_ttm_access_memory(struct ttm_buffer_object *bo,
|
||||
static void
|
||||
amdgpu_bo_delete_mem_notify(struct ttm_buffer_object *bo)
|
||||
{
|
||||
amdgpu_bo_move_notify(bo, false);
|
||||
amdgpu_bo_move_notify(bo, false, NULL);
|
||||
}
|
||||
|
||||
static struct ttm_device_funcs amdgpu_bo_driver = {
|
||||
|
||||
@@ -1106,7 +1106,7 @@ static int kfd_ioctl_alloc_memory_of_gpu(struct file *filep,
|
||||
goto err_unlock;
|
||||
}
|
||||
offset = dev->adev->rmmio_remap.bus_addr;
|
||||
if (!offset) {
|
||||
if (!offset || (PAGE_SIZE > 4096)) {
|
||||
err = -ENOMEM;
|
||||
goto err_unlock;
|
||||
}
|
||||
@@ -2215,7 +2215,7 @@ static int criu_restore_memory_of_gpu(struct kfd_process_device *pdd,
|
||||
return -EINVAL;
|
||||
}
|
||||
offset = pdd->dev->adev->rmmio_remap.bus_addr;
|
||||
if (!offset) {
|
||||
if (!offset || (PAGE_SIZE > 4096)) {
|
||||
pr_err("amdgpu_amdkfd_get_mmio_remap_phys_addr failed\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
@@ -2886,6 +2886,9 @@ static int kfd_mmio_mmap(struct kfd_dev *dev, struct kfd_process *process,
|
||||
if (vma->vm_end - vma->vm_start != PAGE_SIZE)
|
||||
return -EINVAL;
|
||||
|
||||
if (PAGE_SIZE > 4096)
|
||||
return -EINVAL;
|
||||
|
||||
address = dev->adev->rmmio_remap.bus_addr;
|
||||
|
||||
vm_flags_set(vma, VM_IO | VM_DONTCOPY | VM_DONTEXPAND | VM_NORESERVE |
|
||||
|
||||
@@ -2962,6 +2962,7 @@ static enum bp_result construct_integrated_info(
|
||||
result = get_integrated_info_v2_1(bp, info);
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
result = get_integrated_info_v2_2(bp, info);
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -393,6 +393,12 @@ void dcn31_hpo_dp_link_enc_set_throttled_vcp_size(
|
||||
x),
|
||||
25));
|
||||
|
||||
// If y rounds up to integer, carry it over to x.
|
||||
if (y >> 25) {
|
||||
x += 1;
|
||||
y = 0;
|
||||
}
|
||||
|
||||
switch (stream_encoder_inst) {
|
||||
case 0:
|
||||
REG_SET_2(DP_DPHY_SYM32_VC_RATE_CNTL0, 0,
|
||||
|
||||
@@ -222,7 +222,7 @@ static int smu_v13_0_4_system_features_control(struct smu_context *smu, bool en)
|
||||
struct amdgpu_device *adev = smu->adev;
|
||||
int ret = 0;
|
||||
|
||||
if (!en && !adev->in_s0ix) {
|
||||
if (!en && adev->in_s4) {
|
||||
/* Adds a GFX reset as workaround just before sending the
|
||||
* MP1_UNLOAD message to prevent GC/RLC/PMFW from entering
|
||||
* an invalid state.
|
||||
|
||||
@@ -2707,7 +2707,7 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
|
||||
dev->mode_config.max_width,
|
||||
dev->mode_config.max_height);
|
||||
else
|
||||
drm_dbg_kms(dev, "User-space requested a forced probe on [CONNECTOR:%d:%s] but is not the DRM master, demoting to read-only probe",
|
||||
drm_dbg_kms(dev, "User-space requested a forced probe on [CONNECTOR:%d:%s] but is not the DRM master, demoting to read-only probe\n",
|
||||
connector->base.id, connector->name);
|
||||
}
|
||||
|
||||
|
||||
@@ -1034,22 +1034,11 @@ parse_lfp_backlight(struct drm_i915_private *i915,
|
||||
|
||||
panel->vbt.backlight.type = INTEL_BACKLIGHT_DISPLAY_DDI;
|
||||
if (i915->display.vbt.version >= 191) {
|
||||
size_t exp_size;
|
||||
const struct lfp_backlight_control_method *method;
|
||||
|
||||
if (i915->display.vbt.version >= 236)
|
||||
exp_size = sizeof(struct bdb_lfp_backlight_data);
|
||||
else if (i915->display.vbt.version >= 234)
|
||||
exp_size = EXP_BDB_LFP_BL_DATA_SIZE_REV_234;
|
||||
else
|
||||
exp_size = EXP_BDB_LFP_BL_DATA_SIZE_REV_191;
|
||||
|
||||
if (get_blocksize(backlight_data) >= exp_size) {
|
||||
const struct lfp_backlight_control_method *method;
|
||||
|
||||
method = &backlight_data->backlight_control[panel_type];
|
||||
panel->vbt.backlight.type = method->type;
|
||||
panel->vbt.backlight.controller = method->controller;
|
||||
}
|
||||
method = &backlight_data->backlight_control[panel_type];
|
||||
panel->vbt.backlight.type = method->type;
|
||||
panel->vbt.backlight.controller = method->controller;
|
||||
}
|
||||
|
||||
panel->vbt.backlight.pwm_freq_hz = entry->pwm_freq_hz;
|
||||
|
||||
@@ -897,11 +897,6 @@ struct lfp_brightness_level {
|
||||
u16 reserved;
|
||||
} __packed;
|
||||
|
||||
#define EXP_BDB_LFP_BL_DATA_SIZE_REV_191 \
|
||||
offsetof(struct bdb_lfp_backlight_data, brightness_level)
|
||||
#define EXP_BDB_LFP_BL_DATA_SIZE_REV_234 \
|
||||
offsetof(struct bdb_lfp_backlight_data, brightness_precision_bits)
|
||||
|
||||
struct bdb_lfp_backlight_data {
|
||||
u8 entry_size;
|
||||
struct lfp_backlight_data_entry data[16];
|
||||
|
||||
@@ -105,6 +105,8 @@
|
||||
#define HHI_HDMI_CLK_CNTL 0x1cc /* 0x73 */
|
||||
#define HHI_HDMI_PHY_CNTL0 0x3a0 /* 0xe8 */
|
||||
#define HHI_HDMI_PHY_CNTL1 0x3a4 /* 0xe9 */
|
||||
#define PHY_CNTL1_INIT 0x03900000
|
||||
#define PHY_INVERT BIT(17)
|
||||
#define HHI_HDMI_PHY_CNTL2 0x3a8 /* 0xea */
|
||||
#define HHI_HDMI_PHY_CNTL3 0x3ac /* 0xeb */
|
||||
#define HHI_HDMI_PHY_CNTL4 0x3b0 /* 0xec */
|
||||
@@ -129,6 +131,8 @@ struct meson_dw_hdmi_data {
|
||||
unsigned int addr);
|
||||
void (*dwc_write)(struct meson_dw_hdmi *dw_hdmi,
|
||||
unsigned int addr, unsigned int data);
|
||||
u32 cntl0_init;
|
||||
u32 cntl1_init;
|
||||
};
|
||||
|
||||
struct meson_dw_hdmi {
|
||||
@@ -384,26 +388,6 @@ static int dw_hdmi_phy_init(struct dw_hdmi *hdmi, void *data,
|
||||
drm_mode_is_420_also(display, mode)))
|
||||
mode_is_420 = true;
|
||||
|
||||
/* Enable clocks */
|
||||
regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL, 0xffff, 0x100);
|
||||
|
||||
/* Bring HDMITX MEM output of power down */
|
||||
regmap_update_bits(priv->hhi, HHI_MEM_PD_REG0, 0xff << 8, 0);
|
||||
|
||||
/* Bring out of reset */
|
||||
dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_SW_RESET, 0);
|
||||
|
||||
/* Enable internal pixclk, tmds_clk, spdif_clk, i2s_clk, cecclk */
|
||||
dw_hdmi_top_write_bits(dw_hdmi, HDMITX_TOP_CLK_CNTL,
|
||||
0x3, 0x3);
|
||||
|
||||
/* Enable cec_clk and hdcp22_tmdsclk_en */
|
||||
dw_hdmi_top_write_bits(dw_hdmi, HDMITX_TOP_CLK_CNTL,
|
||||
0x3 << 4, 0x3 << 4);
|
||||
|
||||
/* Enable normal output to PHY */
|
||||
dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_BIST_CNTL, BIT(12));
|
||||
|
||||
/* TMDS pattern setup */
|
||||
if (mode->clock > 340000 && !mode_is_420) {
|
||||
dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_TMDS_CLK_PTTN_01,
|
||||
@@ -425,20 +409,6 @@ static int dw_hdmi_phy_init(struct dw_hdmi *hdmi, void *data,
|
||||
/* Setup PHY parameters */
|
||||
meson_hdmi_phy_setup_mode(dw_hdmi, mode, mode_is_420);
|
||||
|
||||
/* Setup PHY */
|
||||
regmap_update_bits(priv->hhi, HHI_HDMI_PHY_CNTL1,
|
||||
0xffff << 16, 0x0390 << 16);
|
||||
|
||||
/* BIT_INVERT */
|
||||
if (dw_hdmi_is_compatible(dw_hdmi, "amlogic,meson-gxl-dw-hdmi") ||
|
||||
dw_hdmi_is_compatible(dw_hdmi, "amlogic,meson-gxm-dw-hdmi") ||
|
||||
dw_hdmi_is_compatible(dw_hdmi, "amlogic,meson-g12a-dw-hdmi"))
|
||||
regmap_update_bits(priv->hhi, HHI_HDMI_PHY_CNTL1,
|
||||
BIT(17), 0);
|
||||
else
|
||||
regmap_update_bits(priv->hhi, HHI_HDMI_PHY_CNTL1,
|
||||
BIT(17), BIT(17));
|
||||
|
||||
/* Disable clock, fifo, fifo_wr */
|
||||
regmap_update_bits(priv->hhi, HHI_HDMI_PHY_CNTL1, 0xf, 0);
|
||||
|
||||
@@ -492,7 +462,9 @@ static void dw_hdmi_phy_disable(struct dw_hdmi *hdmi,
|
||||
|
||||
DRM_DEBUG_DRIVER("\n");
|
||||
|
||||
regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0);
|
||||
/* Fallback to init mode */
|
||||
regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL1, dw_hdmi->data->cntl1_init);
|
||||
regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, dw_hdmi->data->cntl0_init);
|
||||
}
|
||||
|
||||
static enum drm_connector_status dw_hdmi_read_hpd(struct dw_hdmi *hdmi,
|
||||
@@ -610,11 +582,22 @@ static const struct regmap_config meson_dw_hdmi_regmap_config = {
|
||||
.fast_io = true,
|
||||
};
|
||||
|
||||
static const struct meson_dw_hdmi_data meson_dw_hdmi_gx_data = {
|
||||
static const struct meson_dw_hdmi_data meson_dw_hdmi_gxbb_data = {
|
||||
.top_read = dw_hdmi_top_read,
|
||||
.top_write = dw_hdmi_top_write,
|
||||
.dwc_read = dw_hdmi_dwc_read,
|
||||
.dwc_write = dw_hdmi_dwc_write,
|
||||
.cntl0_init = 0x0,
|
||||
.cntl1_init = PHY_CNTL1_INIT | PHY_INVERT,
|
||||
};
|
||||
|
||||
static const struct meson_dw_hdmi_data meson_dw_hdmi_gxl_data = {
|
||||
.top_read = dw_hdmi_top_read,
|
||||
.top_write = dw_hdmi_top_write,
|
||||
.dwc_read = dw_hdmi_dwc_read,
|
||||
.dwc_write = dw_hdmi_dwc_write,
|
||||
.cntl0_init = 0x0,
|
||||
.cntl1_init = PHY_CNTL1_INIT,
|
||||
};
|
||||
|
||||
static const struct meson_dw_hdmi_data meson_dw_hdmi_g12a_data = {
|
||||
@@ -622,6 +605,8 @@ static const struct meson_dw_hdmi_data meson_dw_hdmi_g12a_data = {
|
||||
.top_write = dw_hdmi_g12a_top_write,
|
||||
.dwc_read = dw_hdmi_g12a_dwc_read,
|
||||
.dwc_write = dw_hdmi_g12a_dwc_write,
|
||||
.cntl0_init = 0x000b4242, /* Bandgap */
|
||||
.cntl1_init = PHY_CNTL1_INIT,
|
||||
};
|
||||
|
||||
static void meson_dw_hdmi_init(struct meson_dw_hdmi *meson_dw_hdmi)
|
||||
@@ -656,6 +641,13 @@ static void meson_dw_hdmi_init(struct meson_dw_hdmi *meson_dw_hdmi)
|
||||
meson_dw_hdmi->data->top_write(meson_dw_hdmi,
|
||||
HDMITX_TOP_CLK_CNTL, 0xff);
|
||||
|
||||
/* Enable normal output to PHY */
|
||||
meson_dw_hdmi->data->top_write(meson_dw_hdmi, HDMITX_TOP_BIST_CNTL, BIT(12));
|
||||
|
||||
/* Setup PHY */
|
||||
regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL1, meson_dw_hdmi->data->cntl1_init);
|
||||
regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, meson_dw_hdmi->data->cntl0_init);
|
||||
|
||||
/* Enable HDMI-TX Interrupt */
|
||||
meson_dw_hdmi->data->top_write(meson_dw_hdmi, HDMITX_TOP_INTR_STAT_CLR,
|
||||
HDMITX_TOP_INTR_CORE);
|
||||
@@ -883,11 +875,11 @@ static const struct dev_pm_ops meson_dw_hdmi_pm_ops = {
|
||||
|
||||
static const struct of_device_id meson_dw_hdmi_of_table[] = {
|
||||
{ .compatible = "amlogic,meson-gxbb-dw-hdmi",
|
||||
.data = &meson_dw_hdmi_gx_data },
|
||||
.data = &meson_dw_hdmi_gxbb_data },
|
||||
{ .compatible = "amlogic,meson-gxl-dw-hdmi",
|
||||
.data = &meson_dw_hdmi_gx_data },
|
||||
.data = &meson_dw_hdmi_gxl_data },
|
||||
{ .compatible = "amlogic,meson-gxm-dw-hdmi",
|
||||
.data = &meson_dw_hdmi_gx_data },
|
||||
.data = &meson_dw_hdmi_gxl_data },
|
||||
{ .compatible = "amlogic,meson-g12a-dw-hdmi",
|
||||
.data = &meson_dw_hdmi_g12a_data },
|
||||
{ }
|
||||
|
||||
@@ -109,12 +109,15 @@ nouveau_dp_detect(struct nouveau_connector *nv_connector,
|
||||
u8 *dpcd = nv_encoder->dp.dpcd;
|
||||
int ret = NOUVEAU_DP_NONE, hpd;
|
||||
|
||||
/* If we've already read the DPCD on an eDP device, we don't need to
|
||||
* reread it as it won't change
|
||||
/* eDP ports don't support hotplugging - so there's no point in probing eDP ports unless we
|
||||
* haven't probed them once before.
|
||||
*/
|
||||
if (connector->connector_type == DRM_MODE_CONNECTOR_eDP &&
|
||||
dpcd[DP_DPCD_REV] != 0)
|
||||
return NOUVEAU_DP_SST;
|
||||
if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
|
||||
if (connector->status == connector_status_connected)
|
||||
return NOUVEAU_DP_SST;
|
||||
else if (connector->status == connector_status_disconnected)
|
||||
return NOUVEAU_DP_NONE;
|
||||
}
|
||||
|
||||
mutex_lock(&nv_encoder->dp.hpd_irq_lock);
|
||||
if (mstm) {
|
||||
|
||||
@@ -420,7 +420,7 @@ static int ili9341_dpi_prepare(struct drm_panel *panel)
|
||||
|
||||
ili9341_dpi_init(ili);
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ili9341_dpi_enable(struct drm_panel *panel)
|
||||
@@ -717,18 +717,18 @@ static int ili9341_probe(struct spi_device *spi)
|
||||
|
||||
reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
|
||||
if (IS_ERR(reset))
|
||||
dev_err(dev, "Failed to get gpio 'reset'\n");
|
||||
return dev_err_probe(dev, PTR_ERR(reset), "Failed to get gpio 'reset'\n");
|
||||
|
||||
dc = devm_gpiod_get_optional(dev, "dc", GPIOD_OUT_LOW);
|
||||
if (IS_ERR(dc))
|
||||
dev_err(dev, "Failed to get gpio 'dc'\n");
|
||||
return dev_err_probe(dev, PTR_ERR(dc), "Failed to get gpio 'dc'\n");
|
||||
|
||||
if (!strcmp(id->name, "sf-tc240t-9370-t"))
|
||||
return ili9341_dpi_probe(spi, dc, reset);
|
||||
else if (!strcmp(id->name, "yx240qv29"))
|
||||
return ili9341_dbi_probe(spi, dc, reset);
|
||||
|
||||
return -1;
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static void ili9341_remove(struct spi_device *spi)
|
||||
|
||||
@@ -58,56 +58,16 @@ static long qxl_fence_wait(struct dma_fence *fence, bool intr,
|
||||
signed long timeout)
|
||||
{
|
||||
struct qxl_device *qdev;
|
||||
struct qxl_release *release;
|
||||
int count = 0, sc = 0;
|
||||
bool have_drawable_releases;
|
||||
unsigned long cur, end = jiffies + timeout;
|
||||
|
||||
qdev = container_of(fence->lock, struct qxl_device, release_lock);
|
||||
release = container_of(fence, struct qxl_release, base);
|
||||
have_drawable_releases = release->type == QXL_RELEASE_DRAWABLE;
|
||||
|
||||
retry:
|
||||
sc++;
|
||||
if (!wait_event_timeout(qdev->release_event,
|
||||
(dma_fence_is_signaled(fence) ||
|
||||
(qxl_io_notify_oom(qdev), 0)),
|
||||
timeout))
|
||||
return 0;
|
||||
|
||||
if (dma_fence_is_signaled(fence))
|
||||
goto signaled;
|
||||
|
||||
qxl_io_notify_oom(qdev);
|
||||
|
||||
for (count = 0; count < 11; count++) {
|
||||
if (!qxl_queue_garbage_collect(qdev, true))
|
||||
break;
|
||||
|
||||
if (dma_fence_is_signaled(fence))
|
||||
goto signaled;
|
||||
}
|
||||
|
||||
if (dma_fence_is_signaled(fence))
|
||||
goto signaled;
|
||||
|
||||
if (have_drawable_releases || sc < 4) {
|
||||
if (sc > 2)
|
||||
/* back off */
|
||||
usleep_range(500, 1000);
|
||||
|
||||
if (time_after(jiffies, end))
|
||||
return 0;
|
||||
|
||||
if (have_drawable_releases && sc > 300) {
|
||||
DMA_FENCE_WARN(fence,
|
||||
"failed to wait on release %llu after spincount %d\n",
|
||||
fence->context & ~0xf0000000, sc);
|
||||
goto signaled;
|
||||
}
|
||||
goto retry;
|
||||
}
|
||||
/*
|
||||
* yeah, original sync_obj_wait gave up after 3 spins when
|
||||
* have_drawable_releases is not set.
|
||||
*/
|
||||
|
||||
signaled:
|
||||
cur = jiffies;
|
||||
if (time_after(cur, end))
|
||||
return 0;
|
||||
|
||||
@@ -991,7 +991,7 @@ static int vmw_event_fence_action_create(struct drm_file *file_priv,
|
||||
}
|
||||
|
||||
event->event.base.type = DRM_VMW_EVENT_FENCE_SIGNALED;
|
||||
event->event.base.length = sizeof(*event);
|
||||
event->event.base.length = sizeof(event->event);
|
||||
event->event.user_data = user_data;
|
||||
|
||||
ret = drm_event_reserve_init(dev, file_priv, &event->base, &event->event.base);
|
||||
|
||||
@@ -368,11 +368,6 @@ static int host1x_device_uevent(struct device *dev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int host1x_dma_configure(struct device *dev)
|
||||
{
|
||||
return of_dma_configure(dev, dev->of_node, true);
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops host1x_device_pm_ops = {
|
||||
.suspend = pm_generic_suspend,
|
||||
.resume = pm_generic_resume,
|
||||
@@ -386,7 +381,6 @@ struct bus_type host1x_bus_type = {
|
||||
.name = "host1x",
|
||||
.match = host1x_device_match,
|
||||
.uevent = host1x_device_uevent,
|
||||
.dma_configure = host1x_dma_configure,
|
||||
.pm = &host1x_device_pm_ops,
|
||||
};
|
||||
|
||||
@@ -475,8 +469,6 @@ static int host1x_device_add(struct host1x *host1x,
|
||||
device->dev.bus = &host1x_bus_type;
|
||||
device->dev.parent = host1x->dev;
|
||||
|
||||
of_dma_configure(&device->dev, host1x->dev->of_node, true);
|
||||
|
||||
device->dev.dma_parms = &device->dma_parms;
|
||||
dma_set_max_seg_size(&device->dev, UINT_MAX);
|
||||
|
||||
|
||||
@@ -154,7 +154,9 @@ void vmbus_free_ring(struct vmbus_channel *channel)
|
||||
hv_ringbuffer_cleanup(&channel->inbound);
|
||||
|
||||
if (channel->ringbuffer_page) {
|
||||
__free_pages(channel->ringbuffer_page,
|
||||
/* In a CoCo VM leak the memory if it didn't get re-encrypted */
|
||||
if (!channel->ringbuffer_gpadlhandle.decrypted)
|
||||
__free_pages(channel->ringbuffer_page,
|
||||
get_order(channel->ringbuffer_pagecount
|
||||
<< PAGE_SHIFT));
|
||||
channel->ringbuffer_page = NULL;
|
||||
@@ -473,9 +475,18 @@ static int __vmbus_establish_gpadl(struct vmbus_channel *channel,
|
||||
(atomic_inc_return(&vmbus_connection.next_gpadl_handle) - 1);
|
||||
|
||||
ret = create_gpadl_header(type, kbuffer, size, send_offset, &msginfo);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
gpadl->decrypted = false;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the "decrypted" flag to true for the set_memory_decrypted()
|
||||
* success case. In the failure case, the encryption state of the
|
||||
* memory is unknown. Leave "decrypted" as true to ensure the
|
||||
* memory will be leaked instead of going back on the free list.
|
||||
*/
|
||||
gpadl->decrypted = true;
|
||||
ret = set_memory_decrypted((unsigned long)kbuffer,
|
||||
PFN_UP(size));
|
||||
if (ret) {
|
||||
@@ -564,9 +575,15 @@ cleanup:
|
||||
|
||||
kfree(msginfo);
|
||||
|
||||
if (ret)
|
||||
set_memory_encrypted((unsigned long)kbuffer,
|
||||
PFN_UP(size));
|
||||
if (ret) {
|
||||
/*
|
||||
* If set_memory_encrypted() fails, the decrypted flag is
|
||||
* left as true so the memory is leaked instead of being
|
||||
* put back on the free list.
|
||||
*/
|
||||
if (!set_memory_encrypted((unsigned long)kbuffer, PFN_UP(size)))
|
||||
gpadl->decrypted = false;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -887,6 +904,8 @@ post_msg_err:
|
||||
if (ret)
|
||||
pr_warn("Fail to set mem host visibility in GPADL teardown %d.\n", ret);
|
||||
|
||||
gpadl->decrypted = ret;
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(vmbus_teardown_gpadl);
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#define USB_VENDOR_ID_CORSAIR 0x1b1c
|
||||
@@ -77,8 +78,11 @@
|
||||
struct ccp_device {
|
||||
struct hid_device *hdev;
|
||||
struct device *hwmon_dev;
|
||||
/* For reinitializing the completion below */
|
||||
spinlock_t wait_input_report_lock;
|
||||
struct completion wait_input_report;
|
||||
struct mutex mutex; /* whenever buffer is used, lock before send_usb_cmd */
|
||||
u8 *cmd_buffer;
|
||||
u8 *buffer;
|
||||
int target[6];
|
||||
DECLARE_BITMAP(temp_cnct, NUM_TEMP_SENSORS);
|
||||
@@ -111,15 +115,23 @@ static int send_usb_cmd(struct ccp_device *ccp, u8 command, u8 byte1, u8 byte2,
|
||||
unsigned long t;
|
||||
int ret;
|
||||
|
||||
memset(ccp->buffer, 0x00, OUT_BUFFER_SIZE);
|
||||
ccp->buffer[0] = command;
|
||||
ccp->buffer[1] = byte1;
|
||||
ccp->buffer[2] = byte2;
|
||||
ccp->buffer[3] = byte3;
|
||||
memset(ccp->cmd_buffer, 0x00, OUT_BUFFER_SIZE);
|
||||
ccp->cmd_buffer[0] = command;
|
||||
ccp->cmd_buffer[1] = byte1;
|
||||
ccp->cmd_buffer[2] = byte2;
|
||||
ccp->cmd_buffer[3] = byte3;
|
||||
|
||||
/*
|
||||
* Disable raw event parsing for a moment to safely reinitialize the
|
||||
* completion. Reinit is done because hidraw could have triggered
|
||||
* the raw event parsing and marked the ccp->wait_input_report
|
||||
* completion as done.
|
||||
*/
|
||||
spin_lock_bh(&ccp->wait_input_report_lock);
|
||||
reinit_completion(&ccp->wait_input_report);
|
||||
spin_unlock_bh(&ccp->wait_input_report_lock);
|
||||
|
||||
ret = hid_hw_output_report(ccp->hdev, ccp->buffer, OUT_BUFFER_SIZE);
|
||||
ret = hid_hw_output_report(ccp->hdev, ccp->cmd_buffer, OUT_BUFFER_SIZE);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
@@ -135,11 +147,12 @@ static int ccp_raw_event(struct hid_device *hdev, struct hid_report *report, u8
|
||||
struct ccp_device *ccp = hid_get_drvdata(hdev);
|
||||
|
||||
/* only copy buffer when requested */
|
||||
if (completion_done(&ccp->wait_input_report))
|
||||
return 0;
|
||||
|
||||
memcpy(ccp->buffer, data, min(IN_BUFFER_SIZE, size));
|
||||
complete(&ccp->wait_input_report);
|
||||
spin_lock(&ccp->wait_input_report_lock);
|
||||
if (!completion_done(&ccp->wait_input_report)) {
|
||||
memcpy(ccp->buffer, data, min(IN_BUFFER_SIZE, size));
|
||||
complete_all(&ccp->wait_input_report);
|
||||
}
|
||||
spin_unlock(&ccp->wait_input_report_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -492,7 +505,11 @@ static int ccp_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
||||
if (!ccp)
|
||||
return -ENOMEM;
|
||||
|
||||
ccp->buffer = devm_kmalloc(&hdev->dev, OUT_BUFFER_SIZE, GFP_KERNEL);
|
||||
ccp->cmd_buffer = devm_kmalloc(&hdev->dev, OUT_BUFFER_SIZE, GFP_KERNEL);
|
||||
if (!ccp->cmd_buffer)
|
||||
return -ENOMEM;
|
||||
|
||||
ccp->buffer = devm_kmalloc(&hdev->dev, IN_BUFFER_SIZE, GFP_KERNEL);
|
||||
if (!ccp->buffer)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -510,7 +527,9 @@ static int ccp_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
||||
|
||||
ccp->hdev = hdev;
|
||||
hid_set_drvdata(hdev, ccp);
|
||||
|
||||
mutex_init(&ccp->mutex);
|
||||
spin_lock_init(&ccp->wait_input_report_lock);
|
||||
init_completion(&ccp->wait_input_report);
|
||||
|
||||
hid_device_io_start(hdev);
|
||||
|
||||
@@ -80,11 +80,11 @@ struct ucd9000_debugfs_entry {
|
||||
* It has been observed that the UCD90320 randomly fails register access when
|
||||
* doing another access right on the back of a register write. To mitigate this
|
||||
* make sure that there is a minimum delay between a write access and the
|
||||
* following access. The 250us is based on experimental data. At a delay of
|
||||
* 200us the issue seems to go away. Add a bit of extra margin to allow for
|
||||
* following access. The 500 is based on experimental data. At a delay of
|
||||
* 350us the issue seems to go away. Add a bit of extra margin to allow for
|
||||
* system to system differences.
|
||||
*/
|
||||
#define UCD90320_WAIT_DELAY_US 250
|
||||
#define UCD90320_WAIT_DELAY_US 500
|
||||
|
||||
static inline void ucd90320_wait(const struct ucd9000_data *data)
|
||||
{
|
||||
|
||||
@@ -27,9 +27,13 @@
|
||||
#define MXC4005_REG_ZOUT_UPPER 0x07
|
||||
#define MXC4005_REG_ZOUT_LOWER 0x08
|
||||
|
||||
#define MXC4005_REG_INT_MASK0 0x0A
|
||||
|
||||
#define MXC4005_REG_INT_MASK1 0x0B
|
||||
#define MXC4005_REG_INT_MASK1_BIT_DRDYE 0x01
|
||||
|
||||
#define MXC4005_REG_INT_CLR0 0x00
|
||||
|
||||
#define MXC4005_REG_INT_CLR1 0x01
|
||||
#define MXC4005_REG_INT_CLR1_BIT_DRDYC 0x01
|
||||
|
||||
@@ -113,7 +117,9 @@ static bool mxc4005_is_readable_reg(struct device *dev, unsigned int reg)
|
||||
static bool mxc4005_is_writeable_reg(struct device *dev, unsigned int reg)
|
||||
{
|
||||
switch (reg) {
|
||||
case MXC4005_REG_INT_CLR0:
|
||||
case MXC4005_REG_INT_CLR1:
|
||||
case MXC4005_REG_INT_MASK0:
|
||||
case MXC4005_REG_INT_MASK1:
|
||||
case MXC4005_REG_CONTROL:
|
||||
return true;
|
||||
@@ -330,17 +336,13 @@ static int mxc4005_set_trigger_state(struct iio_trigger *trig,
|
||||
{
|
||||
struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
|
||||
struct mxc4005_data *data = iio_priv(indio_dev);
|
||||
unsigned int val;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&data->mutex);
|
||||
if (state) {
|
||||
ret = regmap_write(data->regmap, MXC4005_REG_INT_MASK1,
|
||||
MXC4005_REG_INT_MASK1_BIT_DRDYE);
|
||||
} else {
|
||||
ret = regmap_write(data->regmap, MXC4005_REG_INT_MASK1,
|
||||
~MXC4005_REG_INT_MASK1_BIT_DRDYE);
|
||||
}
|
||||
|
||||
val = state ? MXC4005_REG_INT_MASK1_BIT_DRDYE : 0;
|
||||
ret = regmap_write(data->regmap, MXC4005_REG_INT_MASK1, val);
|
||||
if (ret < 0) {
|
||||
mutex_unlock(&data->mutex);
|
||||
dev_err(data->dev, "failed to update reg_int_mask1");
|
||||
@@ -382,6 +384,14 @@ static int mxc4005_chip_init(struct mxc4005_data *data)
|
||||
|
||||
dev_dbg(data->dev, "MXC4005 chip id %02x\n", reg);
|
||||
|
||||
ret = regmap_write(data->regmap, MXC4005_REG_INT_MASK0, 0);
|
||||
if (ret < 0)
|
||||
return dev_err_probe(data->dev, ret, "writing INT_MASK0\n");
|
||||
|
||||
ret = regmap_write(data->regmap, MXC4005_REG_INT_MASK1, 0);
|
||||
if (ret < 0)
|
||||
return dev_err_probe(data->dev, ret, "writing INT_MASK1\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1126,6 +1126,7 @@ static int adis16475_config_sync_mode(struct adis16475 *st)
|
||||
struct device *dev = &st->adis.spi->dev;
|
||||
const struct adis16475_sync *sync;
|
||||
u32 sync_mode;
|
||||
u16 val;
|
||||
|
||||
/* default to internal clk */
|
||||
st->clk_freq = st->info->int_clk * 1000;
|
||||
@@ -1187,8 +1188,9 @@ static int adis16475_config_sync_mode(struct adis16475 *st)
|
||||
* I'm keeping this for simplicity and avoiding extra variables
|
||||
* in chip_info.
|
||||
*/
|
||||
val = ADIS16475_SYNC_MODE(sync->sync_mode);
|
||||
ret = __adis_update_bits(&st->adis, ADIS16475_REG_MSG_CTRL,
|
||||
ADIS16475_SYNC_MODE_MASK, sync->sync_mode);
|
||||
ADIS16475_SYNC_MODE_MASK, val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
||||
@@ -440,6 +440,7 @@ static int remove_device_files(struct super_block *sb,
|
||||
return PTR_ERR(dir);
|
||||
}
|
||||
simple_recursive_removal(dir, NULL);
|
||||
dput(dir);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1570,6 +1570,7 @@ static const struct of_device_id mtk_iommu_of_ids[] = {
|
||||
{ .compatible = "mediatek,mt8195-iommu-vpp", .data = &mt8195_data_vpp},
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, mtk_iommu_of_ids);
|
||||
|
||||
static struct platform_driver mtk_iommu_driver = {
|
||||
.probe = mtk_iommu_probe,
|
||||
|
||||
@@ -602,6 +602,7 @@ static const struct of_device_id mtk_iommu_v1_of_ids[] = {
|
||||
{ .compatible = "mediatek,mt2701-m4u", },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, mtk_iommu_v1_of_ids);
|
||||
|
||||
static const struct component_master_ops mtk_iommu_v1_com_ops = {
|
||||
.bind = mtk_iommu_v1_bind,
|
||||
|
||||
@@ -2508,6 +2508,7 @@ static int bind_rdev_to_array(struct md_rdev *rdev, struct mddev *mddev)
|
||||
fail:
|
||||
pr_warn("md: failed to register dev-%s for %s\n",
|
||||
b, mdname(mddev));
|
||||
mddev_destroy_serial_pool(mddev, rdev, false);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
@@ -581,6 +581,31 @@ static unsigned int at24_get_offset_adj(u8 flags, unsigned int byte_len)
|
||||
}
|
||||
}
|
||||
|
||||
static void at24_probe_temp_sensor(struct i2c_client *client)
|
||||
{
|
||||
struct at24_data *at24 = i2c_get_clientdata(client);
|
||||
struct i2c_board_info info = { .type = "jc42" };
|
||||
int ret;
|
||||
u8 val;
|
||||
|
||||
/*
|
||||
* Byte 2 has value 11 for DDR3, earlier versions don't
|
||||
* support the thermal sensor present flag
|
||||
*/
|
||||
ret = at24_read(at24, 2, &val, 1);
|
||||
if (ret || val != 11)
|
||||
return;
|
||||
|
||||
/* Byte 32, bit 7 is set if temp sensor is present */
|
||||
ret = at24_read(at24, 32, &val, 1);
|
||||
if (ret || !(val & BIT(7)))
|
||||
return;
|
||||
|
||||
info.addr = 0x18 | (client->addr & 7);
|
||||
|
||||
i2c_new_client_device(client->adapter, &info);
|
||||
}
|
||||
|
||||
static int at24_probe(struct i2c_client *client)
|
||||
{
|
||||
struct regmap_config regmap_config = { };
|
||||
@@ -756,14 +781,6 @@ static int at24_probe(struct i2c_client *client)
|
||||
}
|
||||
pm_runtime_enable(dev);
|
||||
|
||||
at24->nvmem = devm_nvmem_register(dev, &nvmem_config);
|
||||
if (IS_ERR(at24->nvmem)) {
|
||||
pm_runtime_disable(dev);
|
||||
if (!pm_runtime_status_suspended(dev))
|
||||
regulator_disable(at24->vcc_reg);
|
||||
return PTR_ERR(at24->nvmem);
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform a one-byte test read to verify that the chip is functional,
|
||||
* unless powering on the device is to be avoided during probe (i.e.
|
||||
@@ -779,6 +796,19 @@ static int at24_probe(struct i2c_client *client)
|
||||
}
|
||||
}
|
||||
|
||||
at24->nvmem = devm_nvmem_register(dev, &nvmem_config);
|
||||
if (IS_ERR(at24->nvmem)) {
|
||||
pm_runtime_disable(dev);
|
||||
if (!pm_runtime_status_suspended(dev))
|
||||
regulator_disable(at24->vcc_reg);
|
||||
return dev_err_probe(dev, PTR_ERR(at24->nvmem),
|
||||
"failed to register nvmem\n");
|
||||
}
|
||||
|
||||
/* If this a SPD EEPROM, probe for DDR3 thermal sensor */
|
||||
if (cdata == &at24_data_spd)
|
||||
at24_probe_temp_sensor(client);
|
||||
|
||||
pm_runtime_idle(dev);
|
||||
|
||||
if (writable)
|
||||
|
||||
@@ -115,6 +115,8 @@
|
||||
#define MEI_DEV_ID_ARL_S 0x7F68 /* Arrow Lake Point S */
|
||||
#define MEI_DEV_ID_ARL_H 0x7770 /* Arrow Lake Point H */
|
||||
|
||||
#define MEI_DEV_ID_LNL_M 0xA870 /* Lunar Lake Point M */
|
||||
|
||||
/*
|
||||
* MEI HW Section
|
||||
*/
|
||||
|
||||
@@ -122,6 +122,8 @@ static const struct pci_device_id mei_me_pci_tbl[] = {
|
||||
{MEI_PCI_DEVICE(MEI_DEV_ID_ARL_S, MEI_ME_PCH15_CFG)},
|
||||
{MEI_PCI_DEVICE(MEI_DEV_ID_ARL_H, MEI_ME_PCH15_CFG)},
|
||||
|
||||
{MEI_PCI_DEVICE(MEI_DEV_ID_LNL_M, MEI_ME_PCH15_CFG)},
|
||||
|
||||
/* required last entry */
|
||||
{0, }
|
||||
};
|
||||
|
||||
@@ -5677,7 +5677,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
|
||||
.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6141,
|
||||
.family = MV88E6XXX_FAMILY_6341,
|
||||
.name = "Marvell 88E6141",
|
||||
.num_databases = 4096,
|
||||
.num_databases = 256,
|
||||
.num_macs = 2048,
|
||||
.num_ports = 6,
|
||||
.num_internal_phys = 5,
|
||||
@@ -6134,7 +6134,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
|
||||
.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6341,
|
||||
.family = MV88E6XXX_FAMILY_6341,
|
||||
.name = "Marvell 88E6341",
|
||||
.num_databases = 4096,
|
||||
.num_databases = 256,
|
||||
.num_macs = 2048,
|
||||
.num_internal_phys = 5,
|
||||
.num_ports = 6,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
/*
|
||||
* Broadcom GENET (Gigabit Ethernet) controller driver
|
||||
*
|
||||
* Copyright (c) 2014-2020 Broadcom
|
||||
* Copyright (c) 2014-2024 Broadcom
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) "bcmgenet: " fmt
|
||||
@@ -2468,14 +2468,18 @@ static void umac_enable_set(struct bcmgenet_priv *priv, u32 mask, bool enable)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
spin_lock_bh(&priv->reg_lock);
|
||||
reg = bcmgenet_umac_readl(priv, UMAC_CMD);
|
||||
if (reg & CMD_SW_RESET)
|
||||
if (reg & CMD_SW_RESET) {
|
||||
spin_unlock_bh(&priv->reg_lock);
|
||||
return;
|
||||
}
|
||||
if (enable)
|
||||
reg |= mask;
|
||||
else
|
||||
reg &= ~mask;
|
||||
bcmgenet_umac_writel(priv, reg, UMAC_CMD);
|
||||
spin_unlock_bh(&priv->reg_lock);
|
||||
|
||||
/* UniMAC stops on a packet boundary, wait for a full-size packet
|
||||
* to be processed
|
||||
@@ -2491,8 +2495,10 @@ static void reset_umac(struct bcmgenet_priv *priv)
|
||||
udelay(10);
|
||||
|
||||
/* issue soft reset and disable MAC while updating its registers */
|
||||
spin_lock_bh(&priv->reg_lock);
|
||||
bcmgenet_umac_writel(priv, CMD_SW_RESET, UMAC_CMD);
|
||||
udelay(2);
|
||||
spin_unlock_bh(&priv->reg_lock);
|
||||
}
|
||||
|
||||
static void bcmgenet_intr_disable(struct bcmgenet_priv *priv)
|
||||
@@ -3298,7 +3304,7 @@ static void bcmgenet_get_hw_addr(struct bcmgenet_priv *priv,
|
||||
}
|
||||
|
||||
/* Returns a reusable dma control register value */
|
||||
static u32 bcmgenet_dma_disable(struct bcmgenet_priv *priv)
|
||||
static u32 bcmgenet_dma_disable(struct bcmgenet_priv *priv, bool flush_rx)
|
||||
{
|
||||
unsigned int i;
|
||||
u32 reg;
|
||||
@@ -3323,6 +3329,14 @@ static u32 bcmgenet_dma_disable(struct bcmgenet_priv *priv)
|
||||
udelay(10);
|
||||
bcmgenet_umac_writel(priv, 0, UMAC_TX_FLUSH);
|
||||
|
||||
if (flush_rx) {
|
||||
reg = bcmgenet_rbuf_ctrl_get(priv);
|
||||
bcmgenet_rbuf_ctrl_set(priv, reg | BIT(0));
|
||||
udelay(10);
|
||||
bcmgenet_rbuf_ctrl_set(priv, reg);
|
||||
udelay(10);
|
||||
}
|
||||
|
||||
return dma_ctrl;
|
||||
}
|
||||
|
||||
@@ -3344,7 +3358,9 @@ static void bcmgenet_netif_start(struct net_device *dev)
|
||||
struct bcmgenet_priv *priv = netdev_priv(dev);
|
||||
|
||||
/* Start the network engine */
|
||||
netif_addr_lock_bh(dev);
|
||||
bcmgenet_set_rx_mode(dev);
|
||||
netif_addr_unlock_bh(dev);
|
||||
bcmgenet_enable_rx_napi(priv);
|
||||
|
||||
umac_enable_set(priv, CMD_TX_EN | CMD_RX_EN, true);
|
||||
@@ -3386,8 +3402,8 @@ static int bcmgenet_open(struct net_device *dev)
|
||||
|
||||
bcmgenet_set_hw_addr(priv, dev->dev_addr);
|
||||
|
||||
/* Disable RX/TX DMA and flush TX queues */
|
||||
dma_ctrl = bcmgenet_dma_disable(priv);
|
||||
/* Disable RX/TX DMA and flush TX and RX queues */
|
||||
dma_ctrl = bcmgenet_dma_disable(priv, true);
|
||||
|
||||
/* Reinitialize TDMA and RDMA and SW housekeeping */
|
||||
ret = bcmgenet_init_dma(priv);
|
||||
@@ -3605,16 +3621,19 @@ static void bcmgenet_set_rx_mode(struct net_device *dev)
|
||||
* 3. The number of filters needed exceeds the number filters
|
||||
* supported by the hardware.
|
||||
*/
|
||||
spin_lock(&priv->reg_lock);
|
||||
reg = bcmgenet_umac_readl(priv, UMAC_CMD);
|
||||
if ((dev->flags & (IFF_PROMISC | IFF_ALLMULTI)) ||
|
||||
(nfilter > MAX_MDF_FILTER)) {
|
||||
reg |= CMD_PROMISC;
|
||||
bcmgenet_umac_writel(priv, reg, UMAC_CMD);
|
||||
spin_unlock(&priv->reg_lock);
|
||||
bcmgenet_umac_writel(priv, 0, UMAC_MDF_CTRL);
|
||||
return;
|
||||
} else {
|
||||
reg &= ~CMD_PROMISC;
|
||||
bcmgenet_umac_writel(priv, reg, UMAC_CMD);
|
||||
spin_unlock(&priv->reg_lock);
|
||||
}
|
||||
|
||||
/* update MDF filter */
|
||||
@@ -4016,6 +4035,7 @@ static int bcmgenet_probe(struct platform_device *pdev)
|
||||
goto err;
|
||||
}
|
||||
|
||||
spin_lock_init(&priv->reg_lock);
|
||||
spin_lock_init(&priv->lock);
|
||||
|
||||
/* Set default pause parameters */
|
||||
@@ -4258,7 +4278,7 @@ static int bcmgenet_resume(struct device *d)
|
||||
bcmgenet_hfb_create_rxnfc_filter(priv, rule);
|
||||
|
||||
/* Disable RX/TX DMA and flush TX queues */
|
||||
dma_ctrl = bcmgenet_dma_disable(priv);
|
||||
dma_ctrl = bcmgenet_dma_disable(priv, false);
|
||||
|
||||
/* Reinitialize TDMA and RDMA and SW housekeeping */
|
||||
ret = bcmgenet_init_dma(priv);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2014-2020 Broadcom
|
||||
* Copyright (c) 2014-2024 Broadcom
|
||||
*/
|
||||
|
||||
#ifndef __BCMGENET_H__
|
||||
@@ -573,6 +573,8 @@ struct bcmgenet_rxnfc_rule {
|
||||
/* device context */
|
||||
struct bcmgenet_priv {
|
||||
void __iomem *base;
|
||||
/* reg_lock: lock to serialize access to shared registers */
|
||||
spinlock_t reg_lock;
|
||||
enum bcmgenet_version version;
|
||||
struct net_device *dev;
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
/*
|
||||
* Broadcom GENET (Gigabit Ethernet) Wake-on-LAN support
|
||||
*
|
||||
* Copyright (c) 2014-2020 Broadcom
|
||||
* Copyright (c) 2014-2024 Broadcom
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) "bcmgenet_wol: " fmt
|
||||
@@ -133,6 +133,7 @@ int bcmgenet_wol_power_down_cfg(struct bcmgenet_priv *priv,
|
||||
}
|
||||
|
||||
/* Can't suspend with WoL if MAC is still in reset */
|
||||
spin_lock_bh(&priv->reg_lock);
|
||||
reg = bcmgenet_umac_readl(priv, UMAC_CMD);
|
||||
if (reg & CMD_SW_RESET)
|
||||
reg &= ~CMD_SW_RESET;
|
||||
@@ -140,6 +141,7 @@ int bcmgenet_wol_power_down_cfg(struct bcmgenet_priv *priv,
|
||||
/* disable RX */
|
||||
reg &= ~CMD_RX_EN;
|
||||
bcmgenet_umac_writel(priv, reg, UMAC_CMD);
|
||||
spin_unlock_bh(&priv->reg_lock);
|
||||
mdelay(10);
|
||||
|
||||
if (priv->wolopts & (WAKE_MAGIC | WAKE_MAGICSECURE)) {
|
||||
@@ -185,6 +187,7 @@ int bcmgenet_wol_power_down_cfg(struct bcmgenet_priv *priv,
|
||||
}
|
||||
|
||||
/* Enable CRC forward */
|
||||
spin_lock_bh(&priv->reg_lock);
|
||||
reg = bcmgenet_umac_readl(priv, UMAC_CMD);
|
||||
priv->crc_fwd_en = 1;
|
||||
reg |= CMD_CRC_FWD;
|
||||
@@ -192,6 +195,7 @@ int bcmgenet_wol_power_down_cfg(struct bcmgenet_priv *priv,
|
||||
/* Receiver must be enabled for WOL MP detection */
|
||||
reg |= CMD_RX_EN;
|
||||
bcmgenet_umac_writel(priv, reg, UMAC_CMD);
|
||||
spin_unlock_bh(&priv->reg_lock);
|
||||
|
||||
reg = UMAC_IRQ_MPD_R;
|
||||
if (hfb_enable)
|
||||
@@ -238,7 +242,9 @@ void bcmgenet_wol_power_up_cfg(struct bcmgenet_priv *priv,
|
||||
}
|
||||
|
||||
/* Disable CRC Forward */
|
||||
spin_lock_bh(&priv->reg_lock);
|
||||
reg = bcmgenet_umac_readl(priv, UMAC_CMD);
|
||||
reg &= ~CMD_CRC_FWD;
|
||||
bcmgenet_umac_writel(priv, reg, UMAC_CMD);
|
||||
spin_unlock_bh(&priv->reg_lock);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
/*
|
||||
* Broadcom GENET MDIO routines
|
||||
*
|
||||
* Copyright (c) 2014-2017 Broadcom
|
||||
* Copyright (c) 2014-2024 Broadcom
|
||||
*/
|
||||
|
||||
#include <linux/acpi.h>
|
||||
@@ -72,10 +72,10 @@ static void bcmgenet_mac_config(struct net_device *dev)
|
||||
* Receive clock is provided by the PHY.
|
||||
*/
|
||||
reg = bcmgenet_ext_readl(priv, EXT_RGMII_OOB_CTRL);
|
||||
reg &= ~OOB_DISABLE;
|
||||
reg |= RGMII_LINK;
|
||||
bcmgenet_ext_writel(priv, reg, EXT_RGMII_OOB_CTRL);
|
||||
|
||||
spin_lock_bh(&priv->reg_lock);
|
||||
reg = bcmgenet_umac_readl(priv, UMAC_CMD);
|
||||
reg &= ~((CMD_SPEED_MASK << CMD_SPEED_SHIFT) |
|
||||
CMD_HD_EN |
|
||||
@@ -88,6 +88,7 @@ static void bcmgenet_mac_config(struct net_device *dev)
|
||||
reg |= CMD_TX_EN | CMD_RX_EN;
|
||||
}
|
||||
bcmgenet_umac_writel(priv, reg, UMAC_CMD);
|
||||
spin_unlock_bh(&priv->reg_lock);
|
||||
|
||||
priv->eee.eee_active = phy_init_eee(phydev, 0) >= 0;
|
||||
bcmgenet_eee_enable_set(dev,
|
||||
@@ -100,10 +101,18 @@ static void bcmgenet_mac_config(struct net_device *dev)
|
||||
*/
|
||||
void bcmgenet_mii_setup(struct net_device *dev)
|
||||
{
|
||||
struct bcmgenet_priv *priv = netdev_priv(dev);
|
||||
struct phy_device *phydev = dev->phydev;
|
||||
u32 reg;
|
||||
|
||||
if (phydev->link)
|
||||
if (phydev->link) {
|
||||
bcmgenet_mac_config(dev);
|
||||
} else {
|
||||
reg = bcmgenet_ext_readl(priv, EXT_RGMII_OOB_CTRL);
|
||||
reg &= ~RGMII_LINK;
|
||||
bcmgenet_ext_writel(priv, reg, EXT_RGMII_OOB_CTRL);
|
||||
}
|
||||
|
||||
phy_print_status(phydev);
|
||||
}
|
||||
|
||||
@@ -264,18 +273,22 @@ int bcmgenet_mii_config(struct net_device *dev, bool init)
|
||||
(priv->phy_interface != PHY_INTERFACE_MODE_MOCA);
|
||||
|
||||
/* This is an external PHY (xMII), so we need to enable the RGMII
|
||||
* block for the interface to work
|
||||
* block for the interface to work, unconditionally clear the
|
||||
* Out-of-band disable since we do not need it.
|
||||
*/
|
||||
mutex_lock(&phydev->lock);
|
||||
reg = bcmgenet_ext_readl(priv, EXT_RGMII_OOB_CTRL);
|
||||
reg &= ~OOB_DISABLE;
|
||||
if (priv->ext_phy) {
|
||||
reg = bcmgenet_ext_readl(priv, EXT_RGMII_OOB_CTRL);
|
||||
reg &= ~ID_MODE_DIS;
|
||||
reg |= id_mode_dis;
|
||||
if (GENET_IS_V1(priv) || GENET_IS_V2(priv) || GENET_IS_V3(priv))
|
||||
reg |= RGMII_MODE_EN_V123;
|
||||
else
|
||||
reg |= RGMII_MODE_EN;
|
||||
bcmgenet_ext_writel(priv, reg, EXT_RGMII_OOB_CTRL);
|
||||
}
|
||||
bcmgenet_ext_writel(priv, reg, EXT_RGMII_OOB_CTRL);
|
||||
mutex_unlock(&phydev->lock);
|
||||
|
||||
if (init)
|
||||
dev_info(kdev, "configuring instance for %s\n", phy_name);
|
||||
|
||||
@@ -312,7 +312,7 @@ bnad_debugfs_write_regrd(struct file *file, const char __user *buf,
|
||||
void *kern_buf;
|
||||
|
||||
/* Copy the user space buf */
|
||||
kern_buf = memdup_user(buf, nbytes);
|
||||
kern_buf = memdup_user_nul(buf, nbytes);
|
||||
if (IS_ERR(kern_buf))
|
||||
return PTR_ERR(kern_buf);
|
||||
|
||||
@@ -372,7 +372,7 @@ bnad_debugfs_write_regwr(struct file *file, const char __user *buf,
|
||||
void *kern_buf;
|
||||
|
||||
/* Copy the user space buf */
|
||||
kern_buf = memdup_user(buf, nbytes);
|
||||
kern_buf = memdup_user_nul(buf, nbytes);
|
||||
if (IS_ERR(kern_buf))
|
||||
return PTR_ERR(kern_buf);
|
||||
|
||||
|
||||
@@ -2684,12 +2684,12 @@ int cxgb4_selftest_lb_pkt(struct net_device *netdev)
|
||||
lb->loopback = 1;
|
||||
|
||||
q = &adap->sge.ethtxq[pi->first_qset];
|
||||
__netif_tx_lock(q->txq, smp_processor_id());
|
||||
__netif_tx_lock_bh(q->txq);
|
||||
|
||||
reclaim_completed_tx(adap, &q->q, -1, true);
|
||||
credits = txq_avail(&q->q) - ndesc;
|
||||
if (unlikely(credits < 0)) {
|
||||
__netif_tx_unlock(q->txq);
|
||||
__netif_tx_unlock_bh(q->txq);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
@@ -2724,7 +2724,7 @@ int cxgb4_selftest_lb_pkt(struct net_device *netdev)
|
||||
init_completion(&lb->completion);
|
||||
txq_advance(&q->q, ndesc);
|
||||
cxgb4_ring_tx_db(adap, &q->q, ndesc);
|
||||
__netif_tx_unlock(q->txq);
|
||||
__netif_tx_unlock_bh(q->txq);
|
||||
|
||||
/* wait for the pkt to return */
|
||||
ret = wait_for_completion_timeout(&lb->completion, 10 * HZ);
|
||||
|
||||
@@ -873,7 +873,7 @@ struct hnae3_handle {
|
||||
struct hnae3_roce_private_info rinfo;
|
||||
};
|
||||
|
||||
u32 numa_node_mask; /* for multi-chip support */
|
||||
nodemask_t numa_node_mask; /* for multi-chip support */
|
||||
|
||||
enum hnae3_port_base_vlan_state port_base_vlan_state;
|
||||
|
||||
|
||||
@@ -1624,6 +1624,9 @@ static int hclge_configure(struct hclge_dev *hdev)
|
||||
cfg.default_speed, ret);
|
||||
return ret;
|
||||
}
|
||||
hdev->hw.mac.req_speed = hdev->hw.mac.speed;
|
||||
hdev->hw.mac.req_autoneg = AUTONEG_ENABLE;
|
||||
hdev->hw.mac.req_duplex = DUPLEX_FULL;
|
||||
|
||||
hclge_parse_link_mode(hdev, cfg.speed_ability);
|
||||
|
||||
@@ -1853,7 +1856,8 @@ static int hclge_vport_setup(struct hclge_vport *vport, u16 num_tqps)
|
||||
|
||||
nic->pdev = hdev->pdev;
|
||||
nic->ae_algo = &ae_algo;
|
||||
nic->numa_node_mask = hdev->numa_node_mask;
|
||||
bitmap_copy(nic->numa_node_mask.bits, hdev->numa_node_mask.bits,
|
||||
MAX_NUMNODES);
|
||||
nic->kinfo.io_base = hdev->hw.hw.io_base;
|
||||
|
||||
ret = hclge_knic_setup(vport, num_tqps,
|
||||
@@ -2545,7 +2549,8 @@ static int hclge_init_roce_base_info(struct hclge_vport *vport)
|
||||
|
||||
roce->pdev = nic->pdev;
|
||||
roce->ae_algo = nic->ae_algo;
|
||||
roce->numa_node_mask = nic->numa_node_mask;
|
||||
bitmap_copy(roce->numa_node_mask.bits, nic->numa_node_mask.bits,
|
||||
MAX_NUMNODES);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -3429,9 +3434,9 @@ hclge_set_phy_link_ksettings(struct hnae3_handle *handle,
|
||||
return ret;
|
||||
}
|
||||
|
||||
hdev->hw.mac.autoneg = cmd->base.autoneg;
|
||||
hdev->hw.mac.speed = cmd->base.speed;
|
||||
hdev->hw.mac.duplex = cmd->base.duplex;
|
||||
hdev->hw.mac.req_autoneg = cmd->base.autoneg;
|
||||
hdev->hw.mac.req_speed = cmd->base.speed;
|
||||
hdev->hw.mac.req_duplex = cmd->base.duplex;
|
||||
linkmode_copy(hdev->hw.mac.advertising, cmd->link_modes.advertising);
|
||||
|
||||
return 0;
|
||||
@@ -3464,9 +3469,9 @@ static int hclge_tp_port_init(struct hclge_dev *hdev)
|
||||
if (!hnae3_dev_phy_imp_supported(hdev))
|
||||
return 0;
|
||||
|
||||
cmd.base.autoneg = hdev->hw.mac.autoneg;
|
||||
cmd.base.speed = hdev->hw.mac.speed;
|
||||
cmd.base.duplex = hdev->hw.mac.duplex;
|
||||
cmd.base.autoneg = hdev->hw.mac.req_autoneg;
|
||||
cmd.base.speed = hdev->hw.mac.req_speed;
|
||||
cmd.base.duplex = hdev->hw.mac.req_duplex;
|
||||
linkmode_copy(cmd.link_modes.advertising, hdev->hw.mac.advertising);
|
||||
|
||||
return hclge_set_phy_link_ksettings(&hdev->vport->nic, &cmd);
|
||||
@@ -8046,8 +8051,7 @@ static void hclge_set_timer_task(struct hnae3_handle *handle, bool enable)
|
||||
/* Set the DOWN flag here to disable link updating */
|
||||
set_bit(HCLGE_STATE_DOWN, &hdev->state);
|
||||
|
||||
/* flush memory to make sure DOWN is seen by service task */
|
||||
smp_mb__before_atomic();
|
||||
smp_mb__after_atomic(); /* flush memory to make sure DOWN is seen by service task */
|
||||
hclge_flush_link_update(hdev);
|
||||
}
|
||||
}
|
||||
@@ -10000,6 +10004,7 @@ static int hclge_set_vlan_protocol_type(struct hclge_dev *hdev)
|
||||
static int hclge_init_vlan_filter(struct hclge_dev *hdev)
|
||||
{
|
||||
struct hclge_vport *vport;
|
||||
bool enable = true;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
@@ -10019,8 +10024,12 @@ static int hclge_init_vlan_filter(struct hclge_dev *hdev)
|
||||
vport->cur_vlan_fltr_en = true;
|
||||
}
|
||||
|
||||
if (test_bit(HNAE3_DEV_SUPPORT_VLAN_FLTR_MDF_B, hdev->ae_dev->caps) &&
|
||||
!test_bit(HNAE3_DEV_SUPPORT_PORT_VLAN_BYPASS_B, hdev->ae_dev->caps))
|
||||
enable = false;
|
||||
|
||||
return hclge_set_vlan_filter_ctrl(hdev, HCLGE_FILTER_TYPE_PORT,
|
||||
HCLGE_FILTER_FE_INGRESS, true, 0);
|
||||
HCLGE_FILTER_FE_INGRESS, enable, 0);
|
||||
}
|
||||
|
||||
static int hclge_init_vlan_type(struct hclge_dev *hdev)
|
||||
@@ -11600,16 +11609,10 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev)
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
ret = hclge_devlink_init(hdev);
|
||||
if (ret)
|
||||
goto err_pci_uninit;
|
||||
|
||||
devl_lock(hdev->devlink);
|
||||
|
||||
/* Firmware command queue initialize */
|
||||
ret = hclge_comm_cmd_queue_init(hdev->pdev, &hdev->hw.hw);
|
||||
if (ret)
|
||||
goto err_devlink_uninit;
|
||||
goto err_pci_uninit;
|
||||
|
||||
/* Firmware command initialize */
|
||||
ret = hclge_comm_cmd_init(hdev->ae_dev, &hdev->hw.hw, &hdev->fw_version,
|
||||
@@ -11737,7 +11740,7 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev)
|
||||
|
||||
ret = hclge_update_port_info(hdev);
|
||||
if (ret)
|
||||
goto err_mdiobus_unreg;
|
||||
goto err_ptp_uninit;
|
||||
|
||||
INIT_KFIFO(hdev->mac_tnl_log);
|
||||
|
||||
@@ -11772,6 +11775,10 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev)
|
||||
/* Enable MISC vector(vector0) */
|
||||
hclge_enable_vector(&hdev->misc_vector, true);
|
||||
|
||||
ret = hclge_devlink_init(hdev);
|
||||
if (ret)
|
||||
goto err_ptp_uninit;
|
||||
|
||||
hclge_state_init(hdev);
|
||||
hdev->last_reset_time = jiffies;
|
||||
|
||||
@@ -11779,10 +11786,10 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev)
|
||||
HCLGE_DRIVER_NAME);
|
||||
|
||||
hclge_task_schedule(hdev, round_jiffies_relative(HZ));
|
||||
|
||||
devl_unlock(hdev->devlink);
|
||||
return 0;
|
||||
|
||||
err_ptp_uninit:
|
||||
hclge_ptp_uninit(hdev);
|
||||
err_mdiobus_unreg:
|
||||
if (hdev->hw.mac.phydev)
|
||||
mdiobus_unregister(hdev->hw.mac.mdio_bus);
|
||||
@@ -11792,9 +11799,6 @@ err_msi_uninit:
|
||||
pci_free_irq_vectors(pdev);
|
||||
err_cmd_uninit:
|
||||
hclge_comm_cmd_uninit(hdev->ae_dev, &hdev->hw.hw);
|
||||
err_devlink_uninit:
|
||||
devl_unlock(hdev->devlink);
|
||||
hclge_devlink_uninit(hdev);
|
||||
err_pci_uninit:
|
||||
pcim_iounmap(pdev, hdev->hw.hw.io_base);
|
||||
pci_clear_master(pdev);
|
||||
|
||||
@@ -256,11 +256,14 @@ struct hclge_mac {
|
||||
u8 media_type; /* port media type, e.g. fibre/copper/backplane */
|
||||
u8 mac_addr[ETH_ALEN];
|
||||
u8 autoneg;
|
||||
u8 req_autoneg;
|
||||
u8 duplex;
|
||||
u8 req_duplex;
|
||||
u8 support_autoneg;
|
||||
u8 speed_type; /* 0: sfp speed, 1: active speed */
|
||||
u8 lane_num;
|
||||
u32 speed;
|
||||
u32 req_speed;
|
||||
u32 max_speed;
|
||||
u32 speed_ability; /* speed ability supported by current media */
|
||||
u32 module_type; /* sub media type, e.g. kr/cr/sr/lr */
|
||||
@@ -872,7 +875,7 @@ struct hclge_dev {
|
||||
|
||||
u16 fdir_pf_filter_count; /* Num of guaranteed filters for this PF */
|
||||
u16 num_alloc_vport; /* Num vports this driver supports */
|
||||
u32 numa_node_mask;
|
||||
nodemask_t numa_node_mask;
|
||||
u16 rx_buf_len;
|
||||
u16 num_tx_desc; /* desc num of per tx queue */
|
||||
u16 num_rx_desc; /* desc num of per rx queue */
|
||||
|
||||
@@ -1077,12 +1077,13 @@ static void hclge_mbx_request_handling(struct hclge_mbx_ops_param *param)
|
||||
|
||||
hdev = param->vport->back;
|
||||
cmd_func = hclge_mbx_ops_list[param->req->msg.code];
|
||||
if (cmd_func)
|
||||
ret = cmd_func(param);
|
||||
else
|
||||
if (!cmd_func) {
|
||||
dev_err(&hdev->pdev->dev,
|
||||
"un-supported mailbox message, code = %u\n",
|
||||
param->req->msg.code);
|
||||
return;
|
||||
}
|
||||
ret = cmd_func(param);
|
||||
|
||||
/* PF driver should not reply IMP */
|
||||
if (hnae3_get_bit(param->req->mbx_need_resp, HCLGE_MBX_NEED_RESP_B) &&
|
||||
|
||||
@@ -464,7 +464,8 @@ static int hclgevf_set_handle_info(struct hclgevf_dev *hdev)
|
||||
|
||||
nic->ae_algo = &ae_algovf;
|
||||
nic->pdev = hdev->pdev;
|
||||
nic->numa_node_mask = hdev->numa_node_mask;
|
||||
bitmap_copy(nic->numa_node_mask.bits, hdev->numa_node_mask.bits,
|
||||
MAX_NUMNODES);
|
||||
nic->flags |= HNAE3_SUPPORT_VF;
|
||||
nic->kinfo.io_base = hdev->hw.hw.io_base;
|
||||
|
||||
@@ -2136,8 +2137,8 @@ static int hclgevf_init_roce_base_info(struct hclgevf_dev *hdev)
|
||||
|
||||
roce->pdev = nic->pdev;
|
||||
roce->ae_algo = nic->ae_algo;
|
||||
roce->numa_node_mask = nic->numa_node_mask;
|
||||
|
||||
bitmap_copy(roce->numa_node_mask.bits, nic->numa_node_mask.bits,
|
||||
MAX_NUMNODES);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2235,8 +2236,7 @@ static void hclgevf_set_timer_task(struct hnae3_handle *handle, bool enable)
|
||||
} else {
|
||||
set_bit(HCLGEVF_STATE_DOWN, &hdev->state);
|
||||
|
||||
/* flush memory to make sure DOWN is seen by service task */
|
||||
smp_mb__before_atomic();
|
||||
smp_mb__after_atomic(); /* flush memory to make sure DOWN is seen by service task */
|
||||
hclgevf_flush_link_update(hdev);
|
||||
}
|
||||
}
|
||||
@@ -2902,10 +2902,6 @@ static int hclgevf_init_hdev(struct hclgevf_dev *hdev)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = hclgevf_devlink_init(hdev);
|
||||
if (ret)
|
||||
goto err_devlink_init;
|
||||
|
||||
ret = hclge_comm_cmd_queue_init(hdev->pdev, &hdev->hw.hw);
|
||||
if (ret)
|
||||
goto err_cmd_queue_init;
|
||||
@@ -2998,6 +2994,10 @@ static int hclgevf_init_hdev(struct hclgevf_dev *hdev)
|
||||
|
||||
hclgevf_init_rxd_adv_layout(hdev);
|
||||
|
||||
ret = hclgevf_devlink_init(hdev);
|
||||
if (ret)
|
||||
goto err_config;
|
||||
|
||||
set_bit(HCLGEVF_STATE_SERVICE_INITED, &hdev->state);
|
||||
|
||||
hdev->last_reset_time = jiffies;
|
||||
@@ -3017,8 +3017,6 @@ err_misc_irq_init:
|
||||
err_cmd_init:
|
||||
hclge_comm_cmd_uninit(hdev->ae_dev, &hdev->hw.hw);
|
||||
err_cmd_queue_init:
|
||||
hclgevf_devlink_uninit(hdev);
|
||||
err_devlink_init:
|
||||
hclgevf_pci_uninit(hdev);
|
||||
clear_bit(HCLGEVF_STATE_IRQ_INITED, &hdev->state);
|
||||
return ret;
|
||||
|
||||
@@ -236,7 +236,7 @@ struct hclgevf_dev {
|
||||
u16 rss_size_max; /* HW defined max RSS task queue */
|
||||
|
||||
u16 num_alloc_vport; /* num vports this driver supports */
|
||||
u32 numa_node_mask;
|
||||
nodemask_t numa_node_mask;
|
||||
u16 rx_buf_len;
|
||||
u16 num_tx_desc; /* desc num of per tx queue */
|
||||
u16 num_rx_desc; /* desc num of per rx queue */
|
||||
|
||||
@@ -999,12 +999,10 @@ static ssize_t rvu_dbg_qsize_write(struct file *filp,
|
||||
u16 pcifunc;
|
||||
int ret, lf;
|
||||
|
||||
cmd_buf = memdup_user(buffer, count + 1);
|
||||
cmd_buf = memdup_user_nul(buffer, count);
|
||||
if (IS_ERR(cmd_buf))
|
||||
return -ENOMEM;
|
||||
|
||||
cmd_buf[count] = '\0';
|
||||
|
||||
cmd_buf_tmp = strchr(cmd_buf, '\n');
|
||||
if (cmd_buf_tmp) {
|
||||
*cmd_buf_tmp = '\0';
|
||||
|
||||
@@ -234,12 +234,13 @@ static void ks8851_dbg_dumpkkt(struct ks8851_net *ks, u8 *rxpkt)
|
||||
/**
|
||||
* ks8851_rx_pkts - receive packets from the host
|
||||
* @ks: The device information.
|
||||
* @rxq: Queue of packets received in this function.
|
||||
*
|
||||
* This is called from the IRQ work queue when the system detects that there
|
||||
* are packets in the receive queue. Find out how many packets there are and
|
||||
* read them from the FIFO.
|
||||
*/
|
||||
static void ks8851_rx_pkts(struct ks8851_net *ks)
|
||||
static void ks8851_rx_pkts(struct ks8851_net *ks, struct sk_buff_head *rxq)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
unsigned rxfc;
|
||||
@@ -299,7 +300,7 @@ static void ks8851_rx_pkts(struct ks8851_net *ks)
|
||||
ks8851_dbg_dumpkkt(ks, rxpkt);
|
||||
|
||||
skb->protocol = eth_type_trans(skb, ks->netdev);
|
||||
__netif_rx(skb);
|
||||
__skb_queue_tail(rxq, skb);
|
||||
|
||||
ks->netdev->stats.rx_packets++;
|
||||
ks->netdev->stats.rx_bytes += rxlen;
|
||||
@@ -326,11 +327,11 @@ static void ks8851_rx_pkts(struct ks8851_net *ks)
|
||||
static irqreturn_t ks8851_irq(int irq, void *_ks)
|
||||
{
|
||||
struct ks8851_net *ks = _ks;
|
||||
struct sk_buff_head rxq;
|
||||
unsigned handled = 0;
|
||||
unsigned long flags;
|
||||
unsigned int status;
|
||||
|
||||
local_bh_disable();
|
||||
struct sk_buff *skb;
|
||||
|
||||
ks8851_lock(ks, &flags);
|
||||
|
||||
@@ -384,7 +385,8 @@ static irqreturn_t ks8851_irq(int irq, void *_ks)
|
||||
* from the device so do not bother masking just the RX
|
||||
* from the device. */
|
||||
|
||||
ks8851_rx_pkts(ks);
|
||||
__skb_queue_head_init(&rxq);
|
||||
ks8851_rx_pkts(ks, &rxq);
|
||||
}
|
||||
|
||||
/* if something stopped the rx process, probably due to wanting
|
||||
@@ -408,7 +410,9 @@ static irqreturn_t ks8851_irq(int irq, void *_ks)
|
||||
if (status & IRQ_LCI)
|
||||
mii_check_link(&ks->mii);
|
||||
|
||||
local_bh_enable();
|
||||
if (status & IRQ_RXI)
|
||||
while ((skb = __skb_dequeue(&rxq)))
|
||||
netif_rx(skb);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
@@ -1868,8 +1868,8 @@ int qede_add_tc_flower_fltr(struct qede_dev *edev, __be16 proto,
|
||||
struct flow_cls_offload *f)
|
||||
{
|
||||
struct qede_arfs_fltr_node *n;
|
||||
int min_hlen, rc = -EINVAL;
|
||||
struct qede_arfs_tuple t;
|
||||
int min_hlen, rc;
|
||||
|
||||
__qede_lock(edev);
|
||||
|
||||
@@ -1879,7 +1879,8 @@ int qede_add_tc_flower_fltr(struct qede_dev *edev, __be16 proto,
|
||||
}
|
||||
|
||||
/* parse flower attribute and prepare filter */
|
||||
if (qede_parse_flow_attr(edev, proto, f->rule, &t))
|
||||
rc = qede_parse_flow_attr(edev, proto, f->rule, &t);
|
||||
if (rc)
|
||||
goto unlock;
|
||||
|
||||
/* Validate profile mode and number of filters */
|
||||
@@ -1888,11 +1889,13 @@ int qede_add_tc_flower_fltr(struct qede_dev *edev, __be16 proto,
|
||||
DP_NOTICE(edev,
|
||||
"Filter configuration invalidated, filter mode=0x%x, configured mode=0x%x, filter count=0x%x\n",
|
||||
t.mode, edev->arfs->mode, edev->arfs->filter_count);
|
||||
rc = -EINVAL;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
/* parse tc actions and get the vf_id */
|
||||
if (qede_parse_actions(edev, &f->rule->action, f->common.extack))
|
||||
rc = qede_parse_actions(edev, &f->rule->action, f->common.extack);
|
||||
if (rc)
|
||||
goto unlock;
|
||||
|
||||
if (qede_flow_find_fltr(edev, &t)) {
|
||||
@@ -1998,10 +2001,9 @@ static int qede_flow_spec_to_rule(struct qede_dev *edev,
|
||||
if (IS_ERR(flow))
|
||||
return PTR_ERR(flow);
|
||||
|
||||
if (qede_parse_flow_attr(edev, proto, flow->rule, t)) {
|
||||
err = -EINVAL;
|
||||
err = qede_parse_flow_attr(edev, proto, flow->rule, t);
|
||||
if (err)
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
/* Make sure location is valid and filter isn't already set */
|
||||
err = qede_flow_spec_validate(edev, &flow->rule->action, t,
|
||||
|
||||
@@ -1429,6 +1429,7 @@ static const struct usb_device_id products[] = {
|
||||
{QMI_FIXED_INTF(0x0489, 0xe0b5, 0)}, /* Foxconn T77W968 LTE with eSIM support*/
|
||||
{QMI_FIXED_INTF(0x2692, 0x9025, 4)}, /* Cellient MPL200 (rebranded Qualcomm 05c6:9025) */
|
||||
{QMI_QUIRK_SET_DTR(0x1546, 0x1342, 4)}, /* u-blox LARA-L6 */
|
||||
{QMI_QUIRK_SET_DTR(0x33f8, 0x0104, 4)}, /* Rolling RW101 RMNET */
|
||||
|
||||
/* 4. Gobi 1000 devices */
|
||||
{QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */
|
||||
|
||||
@@ -1721,6 +1721,7 @@ static int vxlan_rcv(struct sock *sk, struct sk_buff *skb)
|
||||
bool raw_proto = false;
|
||||
void *oiph;
|
||||
__be32 vni = 0;
|
||||
int nh;
|
||||
|
||||
/* Need UDP and VXLAN header to be present */
|
||||
if (!pskb_may_pull(skb, VXLAN_HLEN))
|
||||
@@ -1809,9 +1810,25 @@ static int vxlan_rcv(struct sock *sk, struct sk_buff *skb)
|
||||
skb->pkt_type = PACKET_HOST;
|
||||
}
|
||||
|
||||
oiph = skb_network_header(skb);
|
||||
/* Save offset of outer header relative to skb->head,
|
||||
* because we are going to reset the network header to the inner header
|
||||
* and might change skb->head.
|
||||
*/
|
||||
nh = skb_network_header(skb) - skb->head;
|
||||
|
||||
skb_reset_network_header(skb);
|
||||
|
||||
if (!pskb_inet_may_pull(skb)) {
|
||||
DEV_STATS_INC(vxlan->dev, rx_length_errors);
|
||||
DEV_STATS_INC(vxlan->dev, rx_errors);
|
||||
vxlan_vnifilter_count(vxlan, vni, vninode,
|
||||
VXLAN_VNI_STATS_RX_ERRORS, 0);
|
||||
goto drop;
|
||||
}
|
||||
|
||||
/* Get the outer header. */
|
||||
oiph = skb->head + nh;
|
||||
|
||||
if (!vxlan_ecn_decapsulate(vs, oiph, skb)) {
|
||||
++vxlan->dev->stats.rx_frame_errors;
|
||||
++vxlan->dev->stats.rx_errors;
|
||||
|
||||
@@ -4284,7 +4284,7 @@ static int nvme_init_ns_head(struct nvme_ns *ns, struct nvme_ns_info *info)
|
||||
"Found shared namespace %d, but multipathing not supported.\n",
|
||||
info->nsid);
|
||||
dev_warn_once(ctrl->device,
|
||||
"Support for shared namespaces without CONFIG_NVME_MULTIPATH is deprecated and will be removed in Linux 6.0\n.");
|
||||
"Support for shared namespaces without CONFIG_NVME_MULTIPATH is deprecated and will be removed in Linux 6.0.\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
#define SCU614 0x614 /* Disable GPIO Internal Pull-Down #1 */
|
||||
#define SCU618 0x618 /* Disable GPIO Internal Pull-Down #2 */
|
||||
#define SCU61C 0x61c /* Disable GPIO Internal Pull-Down #3 */
|
||||
#define SCU620 0x620 /* Disable GPIO Internal Pull-Down #4 */
|
||||
#define SCU630 0x630 /* Disable GPIO Internal Pull-Down #4 */
|
||||
#define SCU634 0x634 /* Disable GPIO Internal Pull-Down #5 */
|
||||
#define SCU638 0x638 /* Disable GPIO Internal Pull-Down #6 */
|
||||
#define SCU690 0x690 /* Multi-function Pin Control #24 */
|
||||
@@ -2494,38 +2494,38 @@ static struct aspeed_pin_config aspeed_g6_configs[] = {
|
||||
ASPEED_PULL_DOWN_PINCONF(D14, SCU61C, 0),
|
||||
|
||||
/* GPIOS7 */
|
||||
ASPEED_PULL_DOWN_PINCONF(T24, SCU620, 23),
|
||||
ASPEED_PULL_DOWN_PINCONF(T24, SCU630, 23),
|
||||
/* GPIOS6 */
|
||||
ASPEED_PULL_DOWN_PINCONF(P23, SCU620, 22),
|
||||
ASPEED_PULL_DOWN_PINCONF(P23, SCU630, 22),
|
||||
/* GPIOS5 */
|
||||
ASPEED_PULL_DOWN_PINCONF(P24, SCU620, 21),
|
||||
ASPEED_PULL_DOWN_PINCONF(P24, SCU630, 21),
|
||||
/* GPIOS4 */
|
||||
ASPEED_PULL_DOWN_PINCONF(R26, SCU620, 20),
|
||||
ASPEED_PULL_DOWN_PINCONF(R26, SCU630, 20),
|
||||
/* GPIOS3*/
|
||||
ASPEED_PULL_DOWN_PINCONF(R24, SCU620, 19),
|
||||
ASPEED_PULL_DOWN_PINCONF(R24, SCU630, 19),
|
||||
/* GPIOS2 */
|
||||
ASPEED_PULL_DOWN_PINCONF(T26, SCU620, 18),
|
||||
ASPEED_PULL_DOWN_PINCONF(T26, SCU630, 18),
|
||||
/* GPIOS1 */
|
||||
ASPEED_PULL_DOWN_PINCONF(T25, SCU620, 17),
|
||||
ASPEED_PULL_DOWN_PINCONF(T25, SCU630, 17),
|
||||
/* GPIOS0 */
|
||||
ASPEED_PULL_DOWN_PINCONF(R23, SCU620, 16),
|
||||
ASPEED_PULL_DOWN_PINCONF(R23, SCU630, 16),
|
||||
|
||||
/* GPIOR7 */
|
||||
ASPEED_PULL_DOWN_PINCONF(U26, SCU620, 15),
|
||||
ASPEED_PULL_DOWN_PINCONF(U26, SCU630, 15),
|
||||
/* GPIOR6 */
|
||||
ASPEED_PULL_DOWN_PINCONF(W26, SCU620, 14),
|
||||
ASPEED_PULL_DOWN_PINCONF(W26, SCU630, 14),
|
||||
/* GPIOR5 */
|
||||
ASPEED_PULL_DOWN_PINCONF(T23, SCU620, 13),
|
||||
ASPEED_PULL_DOWN_PINCONF(T23, SCU630, 13),
|
||||
/* GPIOR4 */
|
||||
ASPEED_PULL_DOWN_PINCONF(U25, SCU620, 12),
|
||||
ASPEED_PULL_DOWN_PINCONF(U25, SCU630, 12),
|
||||
/* GPIOR3*/
|
||||
ASPEED_PULL_DOWN_PINCONF(V26, SCU620, 11),
|
||||
ASPEED_PULL_DOWN_PINCONF(V26, SCU630, 11),
|
||||
/* GPIOR2 */
|
||||
ASPEED_PULL_DOWN_PINCONF(V24, SCU620, 10),
|
||||
ASPEED_PULL_DOWN_PINCONF(V24, SCU630, 10),
|
||||
/* GPIOR1 */
|
||||
ASPEED_PULL_DOWN_PINCONF(U24, SCU620, 9),
|
||||
ASPEED_PULL_DOWN_PINCONF(U24, SCU630, 9),
|
||||
/* GPIOR0 */
|
||||
ASPEED_PULL_DOWN_PINCONF(V25, SCU620, 8),
|
||||
ASPEED_PULL_DOWN_PINCONF(V25, SCU630, 8),
|
||||
|
||||
/* GPIOX7 */
|
||||
ASPEED_PULL_DOWN_PINCONF(AB10, SCU634, 31),
|
||||
|
||||
@@ -2098,13 +2098,7 @@ int pinctrl_enable(struct pinctrl_dev *pctldev)
|
||||
|
||||
error = pinctrl_claim_hogs(pctldev);
|
||||
if (error) {
|
||||
dev_err(pctldev->dev, "could not claim hogs: %i\n",
|
||||
error);
|
||||
pinctrl_free_pindescs(pctldev, pctldev->desc->pins,
|
||||
pctldev->desc->npins);
|
||||
mutex_destroy(&pctldev->mutex);
|
||||
kfree(pctldev);
|
||||
|
||||
dev_err(pctldev->dev, "could not claim hogs: %i\n", error);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
@@ -220,14 +220,16 @@ int pinctrl_dt_to_map(struct pinctrl *p, struct pinctrl_dev *pctldev)
|
||||
for (state = 0; ; state++) {
|
||||
/* Retrieve the pinctrl-* property */
|
||||
propname = kasprintf(GFP_KERNEL, "pinctrl-%d", state);
|
||||
if (!propname)
|
||||
return -ENOMEM;
|
||||
if (!propname) {
|
||||
ret = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
prop = of_find_property(np, propname, &size);
|
||||
kfree(propname);
|
||||
if (!prop) {
|
||||
if (state == 0) {
|
||||
of_node_put(np);
|
||||
return -ENODEV;
|
||||
ret = -ENODEV;
|
||||
goto err;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -276,33 +276,33 @@ static const unsigned int byt_score_plt_clk5_pins[] = { 101 };
|
||||
static const unsigned int byt_score_smbus_pins[] = { 51, 52, 53 };
|
||||
|
||||
static const struct intel_pingroup byt_score_groups[] = {
|
||||
PIN_GROUP("uart1_grp", byt_score_uart1_pins, 1),
|
||||
PIN_GROUP("uart2_grp", byt_score_uart2_pins, 1),
|
||||
PIN_GROUP("pwm0_grp", byt_score_pwm0_pins, 1),
|
||||
PIN_GROUP("pwm1_grp", byt_score_pwm1_pins, 1),
|
||||
PIN_GROUP("ssp2_grp", byt_score_ssp2_pins, 1),
|
||||
PIN_GROUP("sio_spi_grp", byt_score_sio_spi_pins, 1),
|
||||
PIN_GROUP("i2c5_grp", byt_score_i2c5_pins, 1),
|
||||
PIN_GROUP("i2c6_grp", byt_score_i2c6_pins, 1),
|
||||
PIN_GROUP("i2c4_grp", byt_score_i2c4_pins, 1),
|
||||
PIN_GROUP("i2c3_grp", byt_score_i2c3_pins, 1),
|
||||
PIN_GROUP("i2c2_grp", byt_score_i2c2_pins, 1),
|
||||
PIN_GROUP("i2c1_grp", byt_score_i2c1_pins, 1),
|
||||
PIN_GROUP("i2c0_grp", byt_score_i2c0_pins, 1),
|
||||
PIN_GROUP("ssp0_grp", byt_score_ssp0_pins, 1),
|
||||
PIN_GROUP("ssp1_grp", byt_score_ssp1_pins, 1),
|
||||
PIN_GROUP("sdcard_grp", byt_score_sdcard_pins, byt_score_sdcard_mux_values),
|
||||
PIN_GROUP("sdio_grp", byt_score_sdio_pins, 1),
|
||||
PIN_GROUP("emmc_grp", byt_score_emmc_pins, 1),
|
||||
PIN_GROUP("lpc_grp", byt_score_ilb_lpc_pins, 1),
|
||||
PIN_GROUP("sata_grp", byt_score_sata_pins, 1),
|
||||
PIN_GROUP("plt_clk0_grp", byt_score_plt_clk0_pins, 1),
|
||||
PIN_GROUP("plt_clk1_grp", byt_score_plt_clk1_pins, 1),
|
||||
PIN_GROUP("plt_clk2_grp", byt_score_plt_clk2_pins, 1),
|
||||
PIN_GROUP("plt_clk3_grp", byt_score_plt_clk3_pins, 1),
|
||||
PIN_GROUP("plt_clk4_grp", byt_score_plt_clk4_pins, 1),
|
||||
PIN_GROUP("plt_clk5_grp", byt_score_plt_clk5_pins, 1),
|
||||
PIN_GROUP("smbus_grp", byt_score_smbus_pins, 1),
|
||||
PIN_GROUP_GPIO("uart1_grp", byt_score_uart1_pins, 1),
|
||||
PIN_GROUP_GPIO("uart2_grp", byt_score_uart2_pins, 1),
|
||||
PIN_GROUP_GPIO("pwm0_grp", byt_score_pwm0_pins, 1),
|
||||
PIN_GROUP_GPIO("pwm1_grp", byt_score_pwm1_pins, 1),
|
||||
PIN_GROUP_GPIO("ssp2_grp", byt_score_ssp2_pins, 1),
|
||||
PIN_GROUP_GPIO("sio_spi_grp", byt_score_sio_spi_pins, 1),
|
||||
PIN_GROUP_GPIO("i2c5_grp", byt_score_i2c5_pins, 1),
|
||||
PIN_GROUP_GPIO("i2c6_grp", byt_score_i2c6_pins, 1),
|
||||
PIN_GROUP_GPIO("i2c4_grp", byt_score_i2c4_pins, 1),
|
||||
PIN_GROUP_GPIO("i2c3_grp", byt_score_i2c3_pins, 1),
|
||||
PIN_GROUP_GPIO("i2c2_grp", byt_score_i2c2_pins, 1),
|
||||
PIN_GROUP_GPIO("i2c1_grp", byt_score_i2c1_pins, 1),
|
||||
PIN_GROUP_GPIO("i2c0_grp", byt_score_i2c0_pins, 1),
|
||||
PIN_GROUP_GPIO("ssp0_grp", byt_score_ssp0_pins, 1),
|
||||
PIN_GROUP_GPIO("ssp1_grp", byt_score_ssp1_pins, 1),
|
||||
PIN_GROUP_GPIO("sdcard_grp", byt_score_sdcard_pins, byt_score_sdcard_mux_values),
|
||||
PIN_GROUP_GPIO("sdio_grp", byt_score_sdio_pins, 1),
|
||||
PIN_GROUP_GPIO("emmc_grp", byt_score_emmc_pins, 1),
|
||||
PIN_GROUP_GPIO("lpc_grp", byt_score_ilb_lpc_pins, 1),
|
||||
PIN_GROUP_GPIO("sata_grp", byt_score_sata_pins, 1),
|
||||
PIN_GROUP_GPIO("plt_clk0_grp", byt_score_plt_clk0_pins, 1),
|
||||
PIN_GROUP_GPIO("plt_clk1_grp", byt_score_plt_clk1_pins, 1),
|
||||
PIN_GROUP_GPIO("plt_clk2_grp", byt_score_plt_clk2_pins, 1),
|
||||
PIN_GROUP_GPIO("plt_clk3_grp", byt_score_plt_clk3_pins, 1),
|
||||
PIN_GROUP_GPIO("plt_clk4_grp", byt_score_plt_clk4_pins, 1),
|
||||
PIN_GROUP_GPIO("plt_clk5_grp", byt_score_plt_clk5_pins, 1),
|
||||
PIN_GROUP_GPIO("smbus_grp", byt_score_smbus_pins, 1),
|
||||
};
|
||||
|
||||
static const char * const byt_score_uart_groups[] = {
|
||||
@@ -330,12 +330,14 @@ static const char * const byt_score_plt_clk_groups[] = {
|
||||
};
|
||||
static const char * const byt_score_smbus_groups[] = { "smbus_grp" };
|
||||
static const char * const byt_score_gpio_groups[] = {
|
||||
"uart1_grp", "uart2_grp", "pwm0_grp", "pwm1_grp", "ssp0_grp",
|
||||
"ssp1_grp", "ssp2_grp", "sio_spi_grp", "i2c0_grp", "i2c1_grp",
|
||||
"i2c2_grp", "i2c3_grp", "i2c4_grp", "i2c5_grp", "i2c6_grp",
|
||||
"sdcard_grp", "sdio_grp", "emmc_grp", "lpc_grp", "sata_grp",
|
||||
"plt_clk0_grp", "plt_clk1_grp", "plt_clk2_grp", "plt_clk3_grp",
|
||||
"plt_clk4_grp", "plt_clk5_grp", "smbus_grp",
|
||||
"uart1_grp_gpio", "uart2_grp_gpio", "pwm0_grp_gpio",
|
||||
"pwm1_grp_gpio", "ssp0_grp_gpio", "ssp1_grp_gpio", "ssp2_grp_gpio",
|
||||
"sio_spi_grp_gpio", "i2c0_grp_gpio", "i2c1_grp_gpio", "i2c2_grp_gpio",
|
||||
"i2c3_grp_gpio", "i2c4_grp_gpio", "i2c5_grp_gpio", "i2c6_grp_gpio",
|
||||
"sdcard_grp_gpio", "sdio_grp_gpio", "emmc_grp_gpio", "lpc_grp_gpio",
|
||||
"sata_grp_gpio", "plt_clk0_grp_gpio", "plt_clk1_grp_gpio",
|
||||
"plt_clk2_grp_gpio", "plt_clk3_grp_gpio", "plt_clk4_grp_gpio",
|
||||
"plt_clk5_grp_gpio", "smbus_grp_gpio",
|
||||
};
|
||||
|
||||
static const struct intel_function byt_score_functions[] = {
|
||||
@@ -454,8 +456,8 @@ static const struct intel_pingroup byt_sus_groups[] = {
|
||||
PIN_GROUP("usb_oc_grp_gpio", byt_sus_usb_over_current_pins, byt_sus_usb_over_current_gpio_mode_values),
|
||||
PIN_GROUP("usb_ulpi_grp_gpio", byt_sus_usb_ulpi_pins, byt_sus_usb_ulpi_gpio_mode_values),
|
||||
PIN_GROUP("pcu_spi_grp_gpio", byt_sus_pcu_spi_pins, byt_sus_pcu_spi_gpio_mode_values),
|
||||
PIN_GROUP("pmu_clk1_grp", byt_sus_pmu_clk1_pins, 1),
|
||||
PIN_GROUP("pmu_clk2_grp", byt_sus_pmu_clk2_pins, 1),
|
||||
PIN_GROUP_GPIO("pmu_clk1_grp", byt_sus_pmu_clk1_pins, 1),
|
||||
PIN_GROUP_GPIO("pmu_clk2_grp", byt_sus_pmu_clk2_pins, 1),
|
||||
};
|
||||
|
||||
static const char * const byt_sus_usb_groups[] = {
|
||||
@@ -467,7 +469,7 @@ static const char * const byt_sus_pmu_clk_groups[] = {
|
||||
};
|
||||
static const char * const byt_sus_gpio_groups[] = {
|
||||
"usb_oc_grp_gpio", "usb_ulpi_grp_gpio", "pcu_spi_grp_gpio",
|
||||
"pmu_clk1_grp", "pmu_clk2_grp",
|
||||
"pmu_clk1_grp_gpio", "pmu_clk2_grp_gpio",
|
||||
};
|
||||
|
||||
static const struct intel_function byt_sus_functions[] = {
|
||||
|
||||
@@ -362,7 +362,7 @@ static const char *intel_get_function_name(struct pinctrl_dev *pctldev,
|
||||
{
|
||||
struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
|
||||
|
||||
return pctrl->soc->functions[function].name;
|
||||
return pctrl->soc->functions[function].func.name;
|
||||
}
|
||||
|
||||
static int intel_get_function_groups(struct pinctrl_dev *pctldev,
|
||||
@@ -372,8 +372,8 @@ static int intel_get_function_groups(struct pinctrl_dev *pctldev,
|
||||
{
|
||||
struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
|
||||
|
||||
*groups = pctrl->soc->functions[function].groups;
|
||||
*ngroups = pctrl->soc->functions[function].ngroups;
|
||||
*groups = pctrl->soc->functions[function].func.groups;
|
||||
*ngroups = pctrl->soc->functions[function].func.ngroups;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -36,11 +36,13 @@ struct intel_pingroup {
|
||||
|
||||
/**
|
||||
* struct intel_function - Description about a function
|
||||
* @func: Generic data of the pin function (name and groups of pins)
|
||||
* @name: Name of the function
|
||||
* @groups: An array of groups for this function
|
||||
* @ngroups: Number of groups in @groups
|
||||
*/
|
||||
struct intel_function {
|
||||
struct pinfunction func;
|
||||
const char *name;
|
||||
const char * const *groups;
|
||||
size_t ngroups;
|
||||
@@ -158,11 +160,16 @@ struct intel_community {
|
||||
.modes = __builtin_choose_expr(__builtin_constant_p((m)), NULL, (m)), \
|
||||
}
|
||||
|
||||
#define FUNCTION(n, g) \
|
||||
{ \
|
||||
.name = (n), \
|
||||
.groups = (g), \
|
||||
.ngroups = ARRAY_SIZE((g)), \
|
||||
#define PIN_GROUP_GPIO(n, p, m) \
|
||||
PIN_GROUP(n, p, m), \
|
||||
PIN_GROUP(n "_gpio", p, 0)
|
||||
|
||||
#define FUNCTION(n, g) \
|
||||
{ \
|
||||
.func = PINCTRL_PINFUNCTION((n), (g), ARRAY_SIZE(g)), \
|
||||
.name = (n), \
|
||||
.groups = (g), \
|
||||
.ngroups = ARRAY_SIZE((g)), \
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -160,20 +160,21 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
|
||||
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SR, &ret);
|
||||
break;
|
||||
case PIN_CONFIG_INPUT_ENABLE:
|
||||
case PIN_CONFIG_OUTPUT_ENABLE:
|
||||
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_IES, &ret);
|
||||
if (!ret)
|
||||
err = -EINVAL;
|
||||
break;
|
||||
case PIN_CONFIG_OUTPUT:
|
||||
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &ret);
|
||||
if (err)
|
||||
break;
|
||||
/* CONFIG Current direction return value
|
||||
* ------------- ----------------- ----------------------
|
||||
* OUTPUT_ENABLE output 1 (= HW value)
|
||||
* input 0 (= HW value)
|
||||
* INPUT_ENABLE output 0 (= reverse HW value)
|
||||
* input 1 (= reverse HW value)
|
||||
*/
|
||||
if (param == PIN_CONFIG_INPUT_ENABLE)
|
||||
ret = !ret;
|
||||
|
||||
if (!ret) {
|
||||
err = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DO, &ret);
|
||||
break;
|
||||
case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
|
||||
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &ret);
|
||||
@@ -188,6 +189,8 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
|
||||
}
|
||||
|
||||
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SMT, &ret);
|
||||
if (!ret)
|
||||
err = -EINVAL;
|
||||
break;
|
||||
case PIN_CONFIG_DRIVE_STRENGTH:
|
||||
if (!hw->soc->drive_get)
|
||||
@@ -276,26 +279,9 @@ static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
|
||||
break;
|
||||
err = hw->soc->bias_set_combo(hw, desc, 0, arg);
|
||||
break;
|
||||
case PIN_CONFIG_OUTPUT_ENABLE:
|
||||
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SMT,
|
||||
MTK_DISABLE);
|
||||
/* Keep set direction to consider the case that a GPIO pin
|
||||
* does not have SMT control
|
||||
*/
|
||||
if (err != -ENOTSUPP)
|
||||
break;
|
||||
|
||||
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR,
|
||||
MTK_OUTPUT);
|
||||
break;
|
||||
case PIN_CONFIG_INPUT_ENABLE:
|
||||
/* regard all non-zero value as enable */
|
||||
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_IES, !!arg);
|
||||
if (err)
|
||||
break;
|
||||
|
||||
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR,
|
||||
MTK_INPUT);
|
||||
break;
|
||||
case PIN_CONFIG_SLEW_RATE:
|
||||
/* regard all non-zero value as enable */
|
||||
|
||||
@@ -250,7 +250,7 @@ static const unsigned int pdm_dclk_x_pins[] = { GPIOX_10 };
|
||||
static const unsigned int pdm_din2_a_pins[] = { GPIOA_6 };
|
||||
static const unsigned int pdm_din1_a_pins[] = { GPIOA_7 };
|
||||
static const unsigned int pdm_din0_a_pins[] = { GPIOA_8 };
|
||||
static const unsigned int pdm_dclk_pins[] = { GPIOA_9 };
|
||||
static const unsigned int pdm_dclk_a_pins[] = { GPIOA_9 };
|
||||
|
||||
/* gen_clk */
|
||||
static const unsigned int gen_clk_x_pins[] = { GPIOX_7 };
|
||||
@@ -591,7 +591,7 @@ static struct meson_pmx_group meson_a1_periphs_groups[] = {
|
||||
GROUP(pdm_din2_a, 3),
|
||||
GROUP(pdm_din1_a, 3),
|
||||
GROUP(pdm_din0_a, 3),
|
||||
GROUP(pdm_dclk, 3),
|
||||
GROUP(pdm_dclk_a, 3),
|
||||
GROUP(pwm_c_a, 3),
|
||||
GROUP(pwm_b_a, 3),
|
||||
|
||||
@@ -755,7 +755,7 @@ static const char * const spi_a_groups[] = {
|
||||
|
||||
static const char * const pdm_groups[] = {
|
||||
"pdm_din0_x", "pdm_din1_x", "pdm_din2_x", "pdm_dclk_x", "pdm_din2_a",
|
||||
"pdm_din1_a", "pdm_din0_a", "pdm_dclk",
|
||||
"pdm_din1_a", "pdm_din0_a", "pdm_dclk_a",
|
||||
};
|
||||
|
||||
static const char * const gen_clk_groups[] = {
|
||||
|
||||
@@ -591,7 +591,7 @@ static const struct regulator_ops mt6360_chg_otg_ops = {
|
||||
};
|
||||
|
||||
static const struct regulator_desc mt6360_otg_rdesc = {
|
||||
.of_match = "usb-otg-vbus",
|
||||
.of_match = "usb-otg-vbus-regulator",
|
||||
.name = "usb-otg-vbus",
|
||||
.ops = &mt6360_chg_otg_ops,
|
||||
.owner = THIS_MODULE,
|
||||
|
||||
@@ -193,6 +193,7 @@ static const int rt9455_voreg_values[] = {
|
||||
4450000, 4450000, 4450000, 4450000, 4450000, 4450000, 4450000, 4450000
|
||||
};
|
||||
|
||||
#if IS_ENABLED(CONFIG_USB_PHY)
|
||||
/*
|
||||
* When the charger is in boost mode, REG02[7:2] represent boost output
|
||||
* voltage.
|
||||
@@ -208,6 +209,7 @@ static const int rt9455_boost_voltage_values[] = {
|
||||
5600000, 5600000, 5600000, 5600000, 5600000, 5600000, 5600000, 5600000,
|
||||
5600000, 5600000, 5600000, 5600000, 5600000, 5600000, 5600000, 5600000,
|
||||
};
|
||||
#endif
|
||||
|
||||
/* REG07[3:0] (VMREG) in uV */
|
||||
static const int rt9455_vmreg_values[] = {
|
||||
|
||||
@@ -1916,19 +1916,24 @@ static struct regulator *create_regulator(struct regulator_dev *rdev,
|
||||
}
|
||||
}
|
||||
|
||||
if (err != -EEXIST)
|
||||
if (err != -EEXIST) {
|
||||
regulator->debugfs = debugfs_create_dir(supply_name, rdev->debugfs);
|
||||
if (IS_ERR(regulator->debugfs))
|
||||
rdev_dbg(rdev, "Failed to create debugfs directory\n");
|
||||
if (IS_ERR(regulator->debugfs)) {
|
||||
rdev_dbg(rdev, "Failed to create debugfs directory\n");
|
||||
regulator->debugfs = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
debugfs_create_u32("uA_load", 0444, regulator->debugfs,
|
||||
®ulator->uA_load);
|
||||
debugfs_create_u32("min_uV", 0444, regulator->debugfs,
|
||||
®ulator->voltage[PM_SUSPEND_ON].min_uV);
|
||||
debugfs_create_u32("max_uV", 0444, regulator->debugfs,
|
||||
®ulator->voltage[PM_SUSPEND_ON].max_uV);
|
||||
debugfs_create_file("constraint_flags", 0444, regulator->debugfs,
|
||||
regulator, &constraint_flags_fops);
|
||||
if (regulator->debugfs) {
|
||||
debugfs_create_u32("uA_load", 0444, regulator->debugfs,
|
||||
®ulator->uA_load);
|
||||
debugfs_create_u32("min_uV", 0444, regulator->debugfs,
|
||||
®ulator->voltage[PM_SUSPEND_ON].min_uV);
|
||||
debugfs_create_u32("max_uV", 0444, regulator->debugfs,
|
||||
®ulator->voltage[PM_SUSPEND_ON].max_uV);
|
||||
debugfs_create_file("constraint_flags", 0444, regulator->debugfs,
|
||||
regulator, &constraint_flags_fops);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check now if the regulator is an always on regulator - if
|
||||
|
||||
@@ -319,15 +319,15 @@ static unsigned int mt6360_regulator_of_map_mode(unsigned int hw_mode)
|
||||
}
|
||||
}
|
||||
|
||||
#define MT6360_REGULATOR_DESC(_name, _sname, ereg, emask, vreg, vmask, \
|
||||
mreg, mmask, streg, stmask, vranges, \
|
||||
vcnts, offon_delay, irq_tbls) \
|
||||
#define MT6360_REGULATOR_DESC(match, _name, _sname, ereg, emask, vreg, \
|
||||
vmask, mreg, mmask, streg, stmask, \
|
||||
vranges, vcnts, offon_delay, irq_tbls) \
|
||||
{ \
|
||||
.desc = { \
|
||||
.name = #_name, \
|
||||
.supply_name = #_sname, \
|
||||
.id = MT6360_REGULATOR_##_name, \
|
||||
.of_match = of_match_ptr(#_name), \
|
||||
.of_match = of_match_ptr(match), \
|
||||
.regulators_node = of_match_ptr("regulator"), \
|
||||
.of_map_mode = mt6360_regulator_of_map_mode, \
|
||||
.owner = THIS_MODULE, \
|
||||
@@ -351,21 +351,29 @@ static unsigned int mt6360_regulator_of_map_mode(unsigned int hw_mode)
|
||||
}
|
||||
|
||||
static const struct mt6360_regulator_desc mt6360_regulator_descs[] = {
|
||||
MT6360_REGULATOR_DESC(BUCK1, BUCK1_VIN, 0x117, 0x40, 0x110, 0xff, 0x117, 0x30, 0x117, 0x04,
|
||||
MT6360_REGULATOR_DESC("buck1", BUCK1, BUCK1_VIN,
|
||||
0x117, 0x40, 0x110, 0xff, 0x117, 0x30, 0x117, 0x04,
|
||||
buck_vout_ranges, 256, 0, buck1_irq_tbls),
|
||||
MT6360_REGULATOR_DESC(BUCK2, BUCK2_VIN, 0x127, 0x40, 0x120, 0xff, 0x127, 0x30, 0x127, 0x04,
|
||||
MT6360_REGULATOR_DESC("buck2", BUCK2, BUCK2_VIN,
|
||||
0x127, 0x40, 0x120, 0xff, 0x127, 0x30, 0x127, 0x04,
|
||||
buck_vout_ranges, 256, 0, buck2_irq_tbls),
|
||||
MT6360_REGULATOR_DESC(LDO6, LDO_VIN3, 0x137, 0x40, 0x13B, 0xff, 0x137, 0x30, 0x137, 0x04,
|
||||
MT6360_REGULATOR_DESC("ldo6", LDO6, LDO_VIN3,
|
||||
0x137, 0x40, 0x13B, 0xff, 0x137, 0x30, 0x137, 0x04,
|
||||
ldo_vout_ranges1, 256, 0, ldo6_irq_tbls),
|
||||
MT6360_REGULATOR_DESC(LDO7, LDO_VIN3, 0x131, 0x40, 0x135, 0xff, 0x131, 0x30, 0x131, 0x04,
|
||||
MT6360_REGULATOR_DESC("ldo7", LDO7, LDO_VIN3,
|
||||
0x131, 0x40, 0x135, 0xff, 0x131, 0x30, 0x131, 0x04,
|
||||
ldo_vout_ranges1, 256, 0, ldo7_irq_tbls),
|
||||
MT6360_REGULATOR_DESC(LDO1, LDO_VIN1, 0x217, 0x40, 0x21B, 0xff, 0x217, 0x30, 0x217, 0x04,
|
||||
MT6360_REGULATOR_DESC("ldo1", LDO1, LDO_VIN1,
|
||||
0x217, 0x40, 0x21B, 0xff, 0x217, 0x30, 0x217, 0x04,
|
||||
ldo_vout_ranges2, 256, 0, ldo1_irq_tbls),
|
||||
MT6360_REGULATOR_DESC(LDO2, LDO_VIN1, 0x211, 0x40, 0x215, 0xff, 0x211, 0x30, 0x211, 0x04,
|
||||
MT6360_REGULATOR_DESC("ldo2", LDO2, LDO_VIN1,
|
||||
0x211, 0x40, 0x215, 0xff, 0x211, 0x30, 0x211, 0x04,
|
||||
ldo_vout_ranges2, 256, 0, ldo2_irq_tbls),
|
||||
MT6360_REGULATOR_DESC(LDO3, LDO_VIN1, 0x205, 0x40, 0x209, 0xff, 0x205, 0x30, 0x205, 0x04,
|
||||
MT6360_REGULATOR_DESC("ldo3", LDO3, LDO_VIN1,
|
||||
0x205, 0x40, 0x209, 0xff, 0x205, 0x30, 0x205, 0x04,
|
||||
ldo_vout_ranges2, 256, 100, ldo3_irq_tbls),
|
||||
MT6360_REGULATOR_DESC(LDO5, LDO_VIN2, 0x20B, 0x40, 0x20F, 0x7f, 0x20B, 0x30, 0x20B, 0x04,
|
||||
MT6360_REGULATOR_DESC("ldo5", LDO5, LDO_VIN2,
|
||||
0x20B, 0x40, 0x20F, 0x7f, 0x20B, 0x30, 0x20B, 0x04,
|
||||
ldo_vout_ranges3, 128, 100, ldo5_irq_tbls),
|
||||
};
|
||||
|
||||
|
||||
@@ -95,7 +95,7 @@ static ssize_t crw_inject_write(struct file *file, const char __user *buf,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
buffer = vmemdup_user(buf, lbuf);
|
||||
buffer = memdup_user_nul(buf, lbuf);
|
||||
if (IS_ERR(buffer))
|
||||
return -ENOMEM;
|
||||
|
||||
|
||||
@@ -364,22 +364,6 @@ out:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int qeth_alloc_cq(struct qeth_card *card)
|
||||
{
|
||||
if (card->options.cq == QETH_CQ_ENABLED) {
|
||||
QETH_CARD_TEXT(card, 2, "cqon");
|
||||
card->qdio.c_q = qeth_alloc_qdio_queue();
|
||||
if (!card->qdio.c_q) {
|
||||
dev_err(&card->gdev->dev, "Failed to create completion queue\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
} else {
|
||||
QETH_CARD_TEXT(card, 2, "nocq");
|
||||
card->qdio.c_q = NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void qeth_free_cq(struct qeth_card *card)
|
||||
{
|
||||
if (card->qdio.c_q) {
|
||||
@@ -388,6 +372,25 @@ static void qeth_free_cq(struct qeth_card *card)
|
||||
}
|
||||
}
|
||||
|
||||
static int qeth_alloc_cq(struct qeth_card *card)
|
||||
{
|
||||
if (card->options.cq == QETH_CQ_ENABLED) {
|
||||
QETH_CARD_TEXT(card, 2, "cqon");
|
||||
if (!card->qdio.c_q) {
|
||||
card->qdio.c_q = qeth_alloc_qdio_queue();
|
||||
if (!card->qdio.c_q) {
|
||||
dev_err(&card->gdev->dev,
|
||||
"Failed to create completion queue\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
QETH_CARD_TEXT(card, 2, "nocq");
|
||||
qeth_free_cq(card);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static enum iucv_tx_notify qeth_compute_cq_notification(int sbalf15,
|
||||
int delayed)
|
||||
{
|
||||
@@ -2628,6 +2631,10 @@ static int qeth_alloc_qdio_queues(struct qeth_card *card)
|
||||
|
||||
QETH_CARD_TEXT(card, 2, "allcqdbf");
|
||||
|
||||
/* completion */
|
||||
if (qeth_alloc_cq(card))
|
||||
goto out_err;
|
||||
|
||||
if (atomic_cmpxchg(&card->qdio.state, QETH_QDIO_UNINITIALIZED,
|
||||
QETH_QDIO_ALLOCATED) != QETH_QDIO_UNINITIALIZED)
|
||||
return 0;
|
||||
@@ -2663,10 +2670,6 @@ static int qeth_alloc_qdio_queues(struct qeth_card *card)
|
||||
queue->priority = QETH_QIB_PQUE_PRIO_DEFAULT;
|
||||
}
|
||||
|
||||
/* completion */
|
||||
if (qeth_alloc_cq(card))
|
||||
goto out_freeoutq;
|
||||
|
||||
return 0;
|
||||
|
||||
out_freeoutq:
|
||||
@@ -2677,6 +2680,8 @@ out_freeoutq:
|
||||
qeth_free_buffer_pool(card);
|
||||
out_buffer_pool:
|
||||
atomic_set(&card->qdio.state, QETH_QDIO_UNINITIALIZED);
|
||||
qeth_free_cq(card);
|
||||
out_err:
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
@@ -2684,11 +2689,12 @@ static void qeth_free_qdio_queues(struct qeth_card *card)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
qeth_free_cq(card);
|
||||
|
||||
if (atomic_xchg(&card->qdio.state, QETH_QDIO_UNINITIALIZED) ==
|
||||
QETH_QDIO_UNINITIALIZED)
|
||||
return;
|
||||
|
||||
qeth_free_cq(card);
|
||||
for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j) {
|
||||
if (card->qdio.in_q->bufs[j].rx_skb) {
|
||||
consume_skb(card->qdio.in_q->bufs[j].rx_skb);
|
||||
@@ -3740,24 +3746,11 @@ static void qeth_qdio_poll(struct ccw_device *cdev, unsigned long card_ptr)
|
||||
|
||||
int qeth_configure_cq(struct qeth_card *card, enum qeth_cq cq)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (card->options.cq == QETH_CQ_NOTAVAILABLE) {
|
||||
rc = -1;
|
||||
goto out;
|
||||
} else {
|
||||
if (card->options.cq == cq) {
|
||||
rc = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
qeth_free_qdio_queues(card);
|
||||
card->options.cq = cq;
|
||||
rc = 0;
|
||||
}
|
||||
out:
|
||||
return rc;
|
||||
if (card->options.cq == QETH_CQ_NOTAVAILABLE)
|
||||
return -1;
|
||||
|
||||
card->options.cq = cq;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(qeth_configure_cq);
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user