mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-05 10:31:46 +09:00
Merge tag 'android14-6.1.124_r00' into android14-6.1
This merges the android14-6.1.124_r00 tag into the android14-6.1 branch, catching it up with the latest LTS releases. It contains the following commits: *e280ed497fRevert "Bluetooth: hci_core: Fix sleeping function called from invalid context" *6a643e39f7Revert "ipip,ip_tunnel,sit: Add FOU support for externally controlled ipip devices" *528ab93200Revert "ip_tunnel: annotate data-races around t->parms.link" *02dc81da43Revert "ipv4: ip_tunnel: Unmask upper DSCP bits in ip_tunnel_bind_dev()" *11a2f6348bRevert "ipv4: ip_tunnel: Unmask upper DSCP bits in ip_md_tunnel_xmit()" *302342ed43Revert "ipv4: ip_tunnel: Unmask upper DSCP bits in ip_tunnel_xmit()" *5713068b26Revert "net: Fix netns for ip_tunnel_init_flow()" *50cda709ebRevert "usb: xhci: Limit Stop Endpoint retries" *0ab35d883aRevert "xhci: Turn NEC specific quirk for handling Stop Endpoint errors generic" *4ff68760c1Merge 6.1.124 into android14-6.1-lts |\ | *c63962be84Linux 6.1.124 | *677294e4dazram: check comp is non-NULL before calling comp_destroy | *91b493f15dmptcp: don't always assume copied data in mptcp_cleanup_rbuf() | *cbdb6a4c6amptcp: fix recvbuffer adjust on sleeping rcvmsg | *09ba95321amptcp: fix TCP options overflow. | *bfb7011921mm: vmscan: account for free pages to prevent infinite Loop in throttle_direct_reclaim() | *a3f8ee1522mm/readahead: fix large folio support in async readahead | *887890bbdbdt-bindings: display: adi,adv7533: Drop single lane support | *e64d0a11a2drm: adv7511: Drop dsi single lane support | *7af63ef5fenet/sctp: Prevent autoclose integer overflow in sctp_association_init() | *eef34c0151sky2: Add device ID 11ab:4373 for Marvell 88E8075 | *0310cbad16pinctrl: mcp23s08: Fix sleeping in atomic context due to regmap locking | *346db03e99RDMA/uverbs: Prevent integer overflow issue | *9e431c67f3kcov: mark in_softirq_really() as __always_inline | *cff1de87edALSA: seq: oss: Fix races at processing SysEx messages | *12539ac4a6ALSA hda/realtek: Add quirk for Framework F111:000C | *1f8da43e12modpost: fix the missed iteration for the max bit in do_input() | *7635c2d787modpost: fix input MODULE_DEVICE_TABLE() built for 64-bit on 32-bit host | *b7350b18cbusb: xhci: Avoid queuing redundant Stop Endpoint commands | *1164026a40ARC: build: Try to guess GCC variant of cross compiler | *9336ec56cbirqchip/gic: Correct declaration of *percpu_base pointer in union gic_base | *028a68886eBluetooth: hci_core: Fix sleeping function called from invalid context | *31dc29b5d1net: usb: qmi_wwan: add Telit FE910C04 compositions | *ca2c565a7cksmbd: retry iterate_dir in smb2_query_dir | *42de603783bpf: fix potential error return | *ced1bd9297sound: usb: format: don't warn that raw DSD is unsupported | *7881f1b3b9sound: usb: enable DSD output for ddHiFi TC44C | *7815958273ALSA: hda/realtek: Add new alc2xx-fixup-headset-mic model | *1ea629e7bbbtrfs: flush delalloc workers queue before stopping cleaner kthread during unmount | *465b18e1c5drm/amdkfd: Correct the migration DMA map direction | *c217d67b29wifi: mac80211: wake the queues in case of failure in resume | *66376f1a73btrfs: fix use-after-free when COWing tree bock and tracing is enabled | *9caa207980btrfs: rename and export __btrfs_cow_block() | *eba25e21dcila: serialize calls to nf_register_net_hooks() | *5d336714dbaf_packet: fix vlan_get_protocol_dgram() vs MSG_PEEK | *d91b4a9baaaf_packet: fix vlan_get_tci() vs MSG_PEEK | *81d26fee2cnet: wwan: iosm: Properly check for valid exec stage in ipc_mmio_init() | *ad2ad4cd11net: restrict SO_REUSEPORT to inet sockets | *ac9cfef695net: reenable NETIF_F_IPV6_CSUM offload for BIG TCP packets | *32e1e748a8RDMA/rtrs: Ensure 'ib_sge list' is accessible | *b8ab9bd0c8net: wwan: t7xx: Fix FSM command timeout issue | *274cb294fanet: mv643xx_eth: fix an OF node reference leak | *847c4daa21eth: bcmsysport: fix call balance of priv->clk handling routines | *956f00d870ALSA: usb-audio: US16x08: Initialize array before use | *94dde4fd7enet: llc: reset skb->transport_header | *607774a137netfilter: nft_set_hash: unaligned atomic read on struct nft_set_ext | *3f1f094e0fdrm/i915/dg1: Fix power gate sequence. | *78a110332anetrom: check buffer length before accessing it | *d4b3978fdfnet: Fix netns for ip_tunnel_init_flow() | *9b8f85c4d5ipv4: ip_tunnel: Unmask upper DSCP bits in ip_tunnel_xmit() | *d6ff1c8611ipv4: ip_tunnel: Unmask upper DSCP bits in ip_md_tunnel_xmit() | *5fb41d9ba9ipv4: ip_tunnel: Unmask upper DSCP bits in ip_tunnel_bind_dev() | *c3c53b1692ip_tunnel: annotate data-races around t->parms.link | *19bbca7bc5ipip,ip_tunnel,sit: Add FOU support for externally controlled ipip devices | *de3f999bf8net: fix memory leak in tcp_conn_request() | *28f1e04d91net: stmmac: restructure the error path of stmmac_probe_config_dt() | *51c8cfd00enet: stmmac: don't create a MDIO bus if unnecessary | *40b78dbdf5net: stmmac: platform: provide devm_stmmac_probe_config_dt() | *b46cff8774RDMA/hns: Fix missing flush CQE for DWQE | *3f0a3e857dRDMA/hns: Fix warning storm caused by invalid input in IO path | *5a824c30dfRDMA/hns: Fix mapping error of zero-hop WQE buffer | *b32e9f4a78RDMA/hns: Remove unused parameters and variables | *8e16c8b484RDMA/hns: Refactor mtr find | *ba4014276bnet: dsa: microchip: Fix LAN937X set_ageing_time function | *9d00ab0e0dnet: dsa: microchip: add ksz_rmw8() function | *f7954e8575net: dsa: microchip: Fix KSZ9477 set_ageing_time function | *2478960146drm/bridge: adv7511_audio: Update Audio InfoFrame properly | *02c46a2d13RDMA/bnxt_re: Fix the locking while accessing the QP table | *1dcaac7a61RDMA/bnxt_re: Fix max_qp_wrs reported | *c68c136652RDMA/bnxt_re: Fix reporting hw_ver in query_device | *c50ff899afRDMA/bnxt_re: Add check for path mtu in modify_qp | *cbc35242a9RDMA/mlx5: Enforce same type port association for multiport RoCE | *6c6f477f64net: mctp: handle skb cleanup on sock_queue failures | *116b937eb4xhci: Turn NEC specific quirk for handling Stop Endpoint errors generic | *ae1a08850ausb: xhci: Limit Stop Endpoint retries | *1ae96fb8d7xhci: retry Stop Endpoint on buggy NEC controllers | *326147e4c2thunderbolt: Don't display nvm_version unless upgrade supported | *616747731fthunderbolt: Add support for Intel Panther Lake-M/P | *f26009a0d4thunderbolt: Add support for Intel Lunar Lake | *631b1e09e2tracing: Have process_string() also allow arrays | *a40de0330abtrfs: fix use-after-free in btrfs_encoded_read_endio() | *c79324d42fselinux: ignore unknown extended permissions | *16fea758adx86/hyperv: Fix hv tsc page based sched_clock for hibernation * |2e60b675e3ANDROID: GKI: add blk_mq_quiesce_queue_nowait to virtual_device build symbol list * |7d8965fde5Revert "tracing: Constify string literal data member in struct trace_event_call" * |51d8dc4e92Merge 6.1.123 into android14-6.1-lts |\| | *7dc732d24fLinux 6.1.123 | *1599e0fa15ALSA: hda/realtek: Fix spelling mistake "Firelfy" -> "Firefly" | *acddb87620Revert "rcu-tasks: Fix access non-existent percpu rtpcp variable in rcu_tasks_need_gpcb()" | *36775f42e0nfsd: cancel nfsd_shrinker_work using sync mode in nfs4_state_shutdown_net | *459ef4a242btrfs: sysfs: fix direct super block member reads | *bb8e287f59btrfs: avoid monopolizing a core when activating a swap file | *6abbbd8286power: supply: gpio-charger: Fix set charge current limits | *990730ddbdi2c: microchip-core: fix "ghost" detections | *b106ced612i2c: imx: add imx7d compatible string for applying erratum ERR007805 | *906fb74685i2c: microchip-core: actually use repeated sends | *6237331361io_uring/sqpoll: fix sqpoll error handling races | *3d15f4c244tracing: Prevent bad count for tracing_cpumask_write | *f2a16d2ba4tracing: Constify string literal data member in struct trace_event_call | *581d8a5ac1freezer, sched: Report frozen tasks as 'D' instead of 'R' | *b0ce4e8fedsched/core: Report correct state for TASK_IDLE | TASK_FREEZABLE | *da719022a4pmdomain: core: Add missing put_device() | *10d40c46dbALSA: hda/realtek: fix micmute LEDs don't work on HP Laptops | *8fb5edd202ALSA: hda/realtek: fix mute/micmute LEDs don't work for EliteBook X G1i | *4e8074bb33bpf: Check validity of link->type in bpf_link_show_fdinfo() | *db84cb4c8cnet/mlx5e: Don't call cleanup on profile rollback failure | *7b93728274MIPS: mipsregs: Set proper ISA level for virt extensions | *b016bb8f41MIPS: Probe toolchain support of -msym32 | *53e049204dvmalloc: fix accounting with i915 | *45883477b1blk-mq: register cpuhp callback after hctx is added to xarray table | *9e323f856cvirtio-blk: don't keep queue frozen during system suspend | *f61b2e5e78drm/dp_mst: Ensure mst_primary pointer is valid in drm_dp_mst_handle_up_req() | *ade7aeb0dascsi: storvsc: Do not flag MAINTENANCE_IN return of SRB_STATUS_DATA_OVERRUN as an error | *47c629d393scsi: mpt3sas: Diag-Reset when Doorbell-In-Use bit is set during driver load time | *ba3c90162bplatform/x86: asus-nb-wmi: Ignore unknown event 0xCF | *048abad5a8regmap: Use correct format specifier for logging range errors | *2ea605f61esmb: server: Fix building with GCC 15 | *385c4fdbffALSA: hda/conexant: fix Z60MR100 startup pop issue | *edadc693bfscsi: megaraid_sas: Fix for a potential deadlock | *7aafb0c400scsi: qla1280: Fix hw revision numbering for ISP1020/1040 | *e53deb6f42watchdog: it87_wdt: add PWRGD enable quirk for Qotom QCML04 | *83f5ba098atracing/kprobe: Make trace_kprobe's module callback called after jump_label update | *7357ad7d1fstddef: make __struct_group() UAPI C++-friendly | *8b2282b508powerpc/pseries/vas: Add close() callback in vas_vm_ops struct | *6ea15205d7mtd: rawnand: fix double free in atmel_pmecc_create_user() | *fdba6d5e45dmaengine: at_xdmac: avoid null_prt_deref in at_xdmac_prep_dma_memset | *f03e6bb31cdmaengine: apple-admac: Avoid accessing registers in probe | *c2610aba67dmaengine: tegra: Return correct DMA status when paused | *e1f1aa9718dmaengine: dw: Select only supported masters for ACPI devices | *341be7bdc7dmaengine: mv_xor: fix child node refcount handling in early exit | *eb71df4166phy: rockchip: naneng-combphy: fix phy reset | *a19b505563phy: usb: Toggle the PHY power during init | *8c6ef358baphy: core: Fix that API devm_phy_destroy() fails to destroy the phy | *0f46864e9dphy: core: Fix that API devm_of_phy_provider_unregister() fails to unregister the phy provider | *5c23b6b47bphy: core: Fix that API devm_phy_put() fails to release the phy | *be2c737d4aphy: core: Fix an OF node refcount leakage in of_phy_provider_lookup() | *dff3974372phy: core: Fix an OF node refcount leakage in _of_phy_get() | *138a5c7736phy: qcom-qmp: Fix register name in RX Lane config of SC8280XP | *aeace7d4c0mtd: rawnand: arasan: Fix missing de-registration of NAND | *b4b49cbd5bmtd: rawnand: arasan: Fix double assertion of chip-select | *eabe5f73aamtd: diskonchip: Cast an operand to prevent potential overflow | *61ddaac44enfsd: restore callback functionality for NFSv4.0 | *9a57119d11bpf: Check negative offsets in __bpf_skb_min_len() | *be848bde4atcp_bpf: Add sk_rmem_alloc related logic for tcp_bpf ingress redirection | *2a572e308ftcp_bpf: Charge receive socket buffer in bpf_tcp_ingress() | *b480e57d13mm/vmstat: fix a W=1 clang compiler warning | *3876e3a1c3media: dvb-frontends: dib3000mb: fix uninit-value in dib3000_write_reg * |7ec8f74da4Merge 6.1.122 into android14-6.1-lts |/ *563edd786fLinux 6.1.122 *bd050bb576drm/amdgpu: Handle NULL bo->tbo.resource (again) in amdgpu_vm_bo_update *71a7e2f5b6io_uring/rw: avoid punting to io-wq directly *57cd0416d4io_uring/rw: treat -EOPNOTSUPP for IOCB_NOWAIT like -EAGAIN *72060434a1io_uring/rw: split io_read() into a helper *400a2ae671epoll: Add synchronous wakeup support for ep_poll_callback *6c450489f9udf: Fix directory iteration for longer tail extents *91542d131bceph: validate snapdirname option length when mounting *28ca6f1d19of: Fix refcount leakage for OF node returned by __of_get_dma_parent() *76db8a75f0of: Fix error path in of_parse_phandle_with_args_map() *4fa2c639fcudmabuf: also check for F_SEAL_FUTURE_WRITE *ef942d2336nilfs2: prevent use of deleted inode *48d2fb14f9nilfs2: fix buffer head leaks in calls to truncate_inode_pages() *4c300be883of/irq: Fix using uninitialized variable @addr_len in API of_irq_parse_one() *cd126daadfof/irq: Fix interrupt-map cell length check in of_irq_parse_imap_parent() *61f3036bc2NFS/pnfs: Fix a live lock between recalled layouts and layoutget *534d59ab38io_uring: check if iowq is killed before queuing *c034ce2668io_uring: Fix registered ring file refcount leak *48d07e3a18selftests/bpf: Use asm constraint "m" for LoongArch *f3ff759ec6tracing: Add "%s" check in test_event_printk() *5a03ebbe09tracing: Add missing helper functions in event pointer dereference check *ce8d363103tracing: Fix test_event_printk() to process entire print argument *7ed4db3150KVM: x86: Play nice with protected guests in complete_hypercall_exit() *718fe694a3Drivers: hv: util: Avoid accessing a ringbuffer not initialized yet *0323e6b113btrfs: tree-checker: reject inline extent items with 0 ref count *ac3b5366b9zram: fix uninitialized ZRAM not releasing backing device *b9ca6cf45azram: refuse to use zero sized block device as backing device *2d9a4ff1a5sh: clk: Fix clk_enable() to return 0 on NULL clk *a8a1a7949dhwmon: (tmp513) Fix interpretation of values of Temperature Result and Limit Registers *51f810827ehwmon: (tmp513) Fix Current Register value interpretation *8e58bf4ac2hwmon: (tmp513) Fix interpretation of values of Shunt Voltage and Limit Registers *11fa4e178ehwmon: (tmp513) Use SI constants from units.h *7df25973b6hwmon: (tmp513) Simplify with dev_err_probe() *d2aa3d5014hwmon: (tmp513) Don't use "proxy" headers *65501a4fd8drm/amdgpu: don't access invalid sched *c7fe4305cdi915/guc: Accumulate active runtime on gt reset *7bfe589bbbi915/guc: Ensure busyness counter increases motonically *7966c6ed13i915/guc: Reset engine utilization buffer before registration *1e9307c9b5drm/panel: novatek-nt35950: fix return value check in nt35950_probe() *69fbb01e89drm/modes: Avoid divide by zero harder in drm_mode_vrefresh() *a3301461f3thunderbolt: Improve redrive mode handling *b540c716c8USB: serial: option: add Telit FE910C04 rmnet compositions *12b2347df6USB: serial: option: add MediaTek T7XX compositions *a81a361bd1USB: serial: option: add Netprisma LCUK54 modules for WWAN Ready *3274015453USB: serial: option: add MeiG Smart SLM770A *1f76595c7aUSB: serial: option: add TCL IK512 MBIM & ECM *d7205a72achexagon: Disable constant extender optimization for LLVM prior to 19.1.0 *ab765320c0efivarfs: Fix error on non-existent file *a72ff366d8i2c: riic: Always round-up when calculating bus period *ecc0e323ddchelsio/chtls: prevent potential integer overflow on 32bit *15b3121a68KVM: x86: Cache CPUID.0xD XSTATE offsets+sizes during module init *f1dec8bc31mmc: sdhci-tegra: Remove SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC quirk *26429dc63enet: mdiobus: fix an OF node reference leak *7134f6372cnetfilter: ipset: Fix for recursive locking warning *2d5b7d2c43net: ethernet: bgmac-platform: fix an OF node reference leak *e6fc9ff945net: hinic: Fix cleanup in create_rxqs/txqs() *11561dfe9aionic: use ee->offset when returning sprom data *da93a12876ionic: Fix netdev notifier unregister on failure *d10321be26netdevsim: prevent bad user input in nsim_dev_health_break_write() *59c4ca8d8dnet: mscc: ocelot: fix incorrect IFH SRC_PORT field in ocelot_ifh_set_basic() *d7d1f986ebnet/smc: check return value of sock_recvmsg when draining clc data *e1cc8be2a7net/smc: check smcd_v2_ext_offset when receiving proposal msg *62056d1592net/smc: check iparea_offset and ipv6_prefixes_cnt when receiving proposal msg *a76434c8bfnet/smc: check sndbuf_space again after NOSPACE flag is set in smc_poll *bec2f52866net/smc: protect link down work from execute after lgr freed *7334f371d1cxl/region: Fix region creation for greater than x2 switches *2dfa38be64i2c: pnx: Fix timeout in wait functions *090cd7dfc3p2sb: Do not scan and remove the P2SB device when it is unhidden *8fc1667bf9p2sb: Move P2SB hide and unhide code to p2sb_scan_and_cache() *d552e2e068p2sb: Introduce the global flag p2sb_hidden_by_bios *da3d454cd5p2sb: Factor out p2sb_read_from_cache() *1e41911ab2platform/x86: p2sb: Make p2sb_get_devfn() return void *45bbb2a63ePCI: Introduce pci_resource_n() *684e260146usb: dwc2: gadget: Don't write invalid mapped sg entries into dma_desc with iommu enabled *3469c3e32cMIPS: Loongson64: DTS: Fix msi node for ls7a *f6720b1362PCI: Add ACS quirk for Broadcom BCM5760X NIC *626b6fc9a0ASoC: Intel: sof_sdw: add quirk for Dell SKU 0B8C *0aeb5803fbASoC: Intel: sof_sdw: fix jack detection on ADL-N variant RVP *498e9f29d1usb: cdns3: Add quirk flag to enable suspend residency *ee98649645PCI: vmd: Create domain symlink before pci_bus_add_devices() *f858b0fab2PCI: Use preserve_config in place of pci_flags *9906dbe600PCI/AER: Disable AER service on suspend *489422e2benet: sched: fix ordering of qlen adjustment Change-Id: Ica347cdcd7663b7503c7ae65eda60924ec64f415 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
@@ -87,7 +87,7 @@ properties:
|
||||
adi,dsi-lanes:
|
||||
description: Number of DSI data lanes connected to the DSI host.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
enum: [ 1, 2, 3, 4 ]
|
||||
enum: [ 2, 3, 4 ]
|
||||
|
||||
ports:
|
||||
description:
|
||||
|
||||
2
Makefile
2
Makefile
@@ -1,7 +1,7 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
VERSION = 6
|
||||
PATCHLEVEL = 1
|
||||
SUBLEVEL = 121
|
||||
SUBLEVEL = 124
|
||||
EXTRAVERSION =
|
||||
NAME = Curry Ramen
|
||||
|
||||
|
||||
@@ -357946,6 +357946,15 @@ elf_symbol {
|
||||
type_id: 0x12c8ce83
|
||||
full_name: "blk_mq_quiesce_queue"
|
||||
}
|
||||
elf_symbol {
|
||||
id: 0x9d72c022
|
||||
name: "blk_mq_quiesce_queue_nowait"
|
||||
is_defined: true
|
||||
symbol_type: FUNCTION
|
||||
crc: 0xb5415515
|
||||
type_id: 0x12c8ce83
|
||||
full_name: "blk_mq_quiesce_queue_nowait"
|
||||
}
|
||||
elf_symbol {
|
||||
id: 0xcebb0cec
|
||||
name: "blk_mq_requeue_request"
|
||||
@@ -418985,6 +418994,7 @@ interface {
|
||||
symbol_id: 0x98c69e3e
|
||||
symbol_id: 0x16569be2
|
||||
symbol_id: 0x1f81c0c0
|
||||
symbol_id: 0x9d72c022
|
||||
symbol_id: 0xcebb0cec
|
||||
symbol_id: 0x27ae2b17
|
||||
symbol_id: 0xff90ba37
|
||||
|
||||
@@ -1201,6 +1201,7 @@
|
||||
blk_mq_free_tag_set
|
||||
blk_mq_map_queues
|
||||
blk_mq_quiesce_queue
|
||||
blk_mq_quiesce_queue_nowait
|
||||
blk_mq_requeue_request
|
||||
blk_mq_start_request
|
||||
blk_mq_start_stopped_hw_queues
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
KBUILD_DEFCONFIG := haps_hs_smp_defconfig
|
||||
|
||||
ifeq ($(CROSS_COMPILE),)
|
||||
CROSS_COMPILE := $(call cc-cross-prefix, arc-linux- arceb-linux-)
|
||||
CROSS_COMPILE := $(call cc-cross-prefix, arc-linux- arceb-linux- arc-linux-gnu-)
|
||||
endif
|
||||
|
||||
cflags-y += -fno-common -pipe -fno-builtin -mmedium-calls -D__linux__
|
||||
|
||||
@@ -32,3 +32,9 @@ KBUILD_LDFLAGS += $(ldflags-y)
|
||||
TIR_NAME := r19
|
||||
KBUILD_CFLAGS += -ffixed-$(TIR_NAME) -DTHREADINFO_REG=$(TIR_NAME) -D__linux__
|
||||
KBUILD_AFLAGS += -DTHREADINFO_REG=$(TIR_NAME)
|
||||
|
||||
# Disable HexagonConstExtenders pass for LLVM versions prior to 19.1.0
|
||||
# https://github.com/llvm/llvm-project/issues/99714
|
||||
ifneq ($(call clang-min-version, 190100),y)
|
||||
KBUILD_CFLAGS += -mllvm -hexagon-cext=false
|
||||
endif
|
||||
|
||||
@@ -304,7 +304,7 @@ drivers-$(CONFIG_PCI) += arch/mips/pci/
|
||||
ifdef CONFIG_64BIT
|
||||
ifndef KBUILD_SYM32
|
||||
ifeq ($(shell expr $(load-y) \< 0xffffffff80000000), 0)
|
||||
KBUILD_SYM32 = y
|
||||
KBUILD_SYM32 = $(call cc-option-yn, -msym32)
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
compatible = "loongson,pch-msi-1.0";
|
||||
reg = <0 0x2ff00000 0 0x8>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <1>;
|
||||
msi-controller;
|
||||
loongson,msi-base-vec = <64>;
|
||||
loongson,msi-num-vecs = <192>;
|
||||
|
||||
@@ -2078,7 +2078,14 @@ do { \
|
||||
_ASM_INSN_IF_MIPS(0x4200000c) \
|
||||
_ASM_INSN32_IF_MM(0x0000517c)
|
||||
#else /* !TOOLCHAIN_SUPPORTS_VIRT */
|
||||
#define _ASM_SET_VIRT ".set\tvirt\n\t"
|
||||
#if MIPS_ISA_REV >= 5
|
||||
#define _ASM_SET_VIRT_ISA
|
||||
#elif defined(CONFIG_64BIT)
|
||||
#define _ASM_SET_VIRT_ISA ".set\tmips64r5\n\t"
|
||||
#else
|
||||
#define _ASM_SET_VIRT_ISA ".set\tmips32r5\n\t"
|
||||
#endif
|
||||
#define _ASM_SET_VIRT _ASM_SET_VIRT_ISA ".set\tvirt\n\t"
|
||||
#define _ASM_SET_MFGC0 _ASM_SET_VIRT
|
||||
#define _ASM_SET_DMFGC0 _ASM_SET_VIRT
|
||||
#define _ASM_SET_MTGC0 _ASM_SET_VIRT
|
||||
@@ -2099,7 +2106,6 @@ do { \
|
||||
({ int __res; \
|
||||
__asm__ __volatile__( \
|
||||
".set\tpush\n\t" \
|
||||
".set\tmips32r5\n\t" \
|
||||
_ASM_SET_MFGC0 \
|
||||
"mfgc0\t%0, " #source ", %1\n\t" \
|
||||
_ASM_UNSET_MFGC0 \
|
||||
@@ -2113,7 +2119,6 @@ do { \
|
||||
({ unsigned long long __res; \
|
||||
__asm__ __volatile__( \
|
||||
".set\tpush\n\t" \
|
||||
".set\tmips64r5\n\t" \
|
||||
_ASM_SET_DMFGC0 \
|
||||
"dmfgc0\t%0, " #source ", %1\n\t" \
|
||||
_ASM_UNSET_DMFGC0 \
|
||||
@@ -2127,7 +2132,6 @@ do { \
|
||||
do { \
|
||||
__asm__ __volatile__( \
|
||||
".set\tpush\n\t" \
|
||||
".set\tmips32r5\n\t" \
|
||||
_ASM_SET_MTGC0 \
|
||||
"mtgc0\t%z0, " #register ", %1\n\t" \
|
||||
_ASM_UNSET_MTGC0 \
|
||||
@@ -2140,7 +2144,6 @@ do { \
|
||||
do { \
|
||||
__asm__ __volatile__( \
|
||||
".set\tpush\n\t" \
|
||||
".set\tmips64r5\n\t" \
|
||||
_ASM_SET_DMTGC0 \
|
||||
"dmtgc0\t%z0, " #register ", %1\n\t" \
|
||||
_ASM_UNSET_DMTGC0 \
|
||||
|
||||
@@ -464,7 +464,43 @@ static vm_fault_t vas_mmap_fault(struct vm_fault *vmf)
|
||||
return VM_FAULT_SIGBUS;
|
||||
}
|
||||
|
||||
/*
|
||||
* During mmap() paste address, mapping VMA is saved in VAS window
|
||||
* struct which is used to unmap during migration if the window is
|
||||
* still open. But the user space can remove this mapping with
|
||||
* munmap() before closing the window and the VMA address will
|
||||
* be invalid. Set VAS window VMA to NULL in this function which
|
||||
* is called before VMA free.
|
||||
*/
|
||||
static void vas_mmap_close(struct vm_area_struct *vma)
|
||||
{
|
||||
struct file *fp = vma->vm_file;
|
||||
struct coproc_instance *cp_inst = fp->private_data;
|
||||
struct vas_window *txwin;
|
||||
|
||||
/* Should not happen */
|
||||
if (!cp_inst || !cp_inst->txwin) {
|
||||
pr_err("No attached VAS window for the paste address mmap\n");
|
||||
return;
|
||||
}
|
||||
|
||||
txwin = cp_inst->txwin;
|
||||
/*
|
||||
* task_ref.vma is set in coproc_mmap() during mmap paste
|
||||
* address. So it has to be the same VMA that is getting freed.
|
||||
*/
|
||||
if (WARN_ON(txwin->task_ref.vma != vma)) {
|
||||
pr_err("Invalid paste address mmaping\n");
|
||||
return;
|
||||
}
|
||||
|
||||
mutex_lock(&txwin->task_ref.mmap_mutex);
|
||||
txwin->task_ref.vma = NULL;
|
||||
mutex_unlock(&txwin->task_ref.mmap_mutex);
|
||||
}
|
||||
|
||||
static const struct vm_operations_struct vas_vm_ops = {
|
||||
.close = vas_mmap_close,
|
||||
.fault = vas_mmap_fault,
|
||||
};
|
||||
|
||||
|
||||
@@ -152,6 +152,63 @@ static void hv_machine_crash_shutdown(struct pt_regs *regs)
|
||||
hyperv_cleanup();
|
||||
}
|
||||
#endif /* CONFIG_KEXEC_CORE */
|
||||
|
||||
static u64 hv_ref_counter_at_suspend;
|
||||
static void (*old_save_sched_clock_state)(void);
|
||||
static void (*old_restore_sched_clock_state)(void);
|
||||
|
||||
/*
|
||||
* Hyper-V clock counter resets during hibernation. Save and restore clock
|
||||
* offset during suspend/resume, while also considering the time passed
|
||||
* before suspend. This is to make sure that sched_clock using hv tsc page
|
||||
* based clocksource, proceeds from where it left off during suspend and
|
||||
* it shows correct time for the timestamps of kernel messages after resume.
|
||||
*/
|
||||
static void save_hv_clock_tsc_state(void)
|
||||
{
|
||||
hv_ref_counter_at_suspend = hv_read_reference_counter();
|
||||
}
|
||||
|
||||
static void restore_hv_clock_tsc_state(void)
|
||||
{
|
||||
/*
|
||||
* Adjust the offsets used by hv tsc clocksource to
|
||||
* account for the time spent before hibernation.
|
||||
* adjusted value = reference counter (time) at suspend
|
||||
* - reference counter (time) now.
|
||||
*/
|
||||
hv_adj_sched_clock_offset(hv_ref_counter_at_suspend - hv_read_reference_counter());
|
||||
}
|
||||
|
||||
/*
|
||||
* Functions to override save_sched_clock_state and restore_sched_clock_state
|
||||
* functions of x86_platform. The Hyper-V clock counter is reset during
|
||||
* suspend-resume and the offset used to measure time needs to be
|
||||
* corrected, post resume.
|
||||
*/
|
||||
static void hv_save_sched_clock_state(void)
|
||||
{
|
||||
old_save_sched_clock_state();
|
||||
save_hv_clock_tsc_state();
|
||||
}
|
||||
|
||||
static void hv_restore_sched_clock_state(void)
|
||||
{
|
||||
restore_hv_clock_tsc_state();
|
||||
old_restore_sched_clock_state();
|
||||
}
|
||||
|
||||
static void __init x86_setup_ops_for_tsc_pg_clock(void)
|
||||
{
|
||||
if (!(ms_hyperv.features & HV_MSR_REFERENCE_TSC_AVAILABLE))
|
||||
return;
|
||||
|
||||
old_save_sched_clock_state = x86_platform.save_sched_clock_state;
|
||||
x86_platform.save_sched_clock_state = hv_save_sched_clock_state;
|
||||
|
||||
old_restore_sched_clock_state = x86_platform.restore_sched_clock_state;
|
||||
x86_platform.restore_sched_clock_state = hv_restore_sched_clock_state;
|
||||
}
|
||||
#endif /* CONFIG_HYPERV */
|
||||
|
||||
static uint32_t __init ms_hyperv_platform(void)
|
||||
@@ -454,6 +511,7 @@ static void __init ms_hyperv_init_platform(void)
|
||||
|
||||
/* Register Hyper-V specific clocksource */
|
||||
hv_init_clocksource();
|
||||
x86_setup_ops_for_tsc_pg_clock();
|
||||
#endif
|
||||
/*
|
||||
* TSC should be marked as unstable only after Hyper-V
|
||||
|
||||
@@ -33,6 +33,26 @@
|
||||
u32 kvm_cpu_caps[NR_KVM_CPU_CAPS] __read_mostly;
|
||||
EXPORT_SYMBOL_GPL(kvm_cpu_caps);
|
||||
|
||||
struct cpuid_xstate_sizes {
|
||||
u32 eax;
|
||||
u32 ebx;
|
||||
u32 ecx;
|
||||
};
|
||||
|
||||
static struct cpuid_xstate_sizes xstate_sizes[XFEATURE_MAX] __ro_after_init;
|
||||
|
||||
void __init kvm_init_xstate_sizes(void)
|
||||
{
|
||||
u32 ign;
|
||||
int i;
|
||||
|
||||
for (i = XFEATURE_YMM; i < ARRAY_SIZE(xstate_sizes); i++) {
|
||||
struct cpuid_xstate_sizes *xs = &xstate_sizes[i];
|
||||
|
||||
cpuid_count(0xD, i, &xs->eax, &xs->ebx, &xs->ecx, &ign);
|
||||
}
|
||||
}
|
||||
|
||||
u32 xstate_required_size(u64 xstate_bv, bool compacted)
|
||||
{
|
||||
int feature_bit = 0;
|
||||
@@ -41,14 +61,15 @@ u32 xstate_required_size(u64 xstate_bv, bool compacted)
|
||||
xstate_bv &= XFEATURE_MASK_EXTEND;
|
||||
while (xstate_bv) {
|
||||
if (xstate_bv & 0x1) {
|
||||
u32 eax, ebx, ecx, edx, offset;
|
||||
cpuid_count(0xD, feature_bit, &eax, &ebx, &ecx, &edx);
|
||||
struct cpuid_xstate_sizes *xs = &xstate_sizes[feature_bit];
|
||||
u32 offset;
|
||||
|
||||
/* ECX[1]: 64B alignment in compacted form */
|
||||
if (compacted)
|
||||
offset = (ecx & 0x2) ? ALIGN(ret, 64) : ret;
|
||||
offset = (xs->ecx & 0x2) ? ALIGN(ret, 64) : ret;
|
||||
else
|
||||
offset = ebx;
|
||||
ret = max(ret, offset + eax);
|
||||
offset = xs->ebx;
|
||||
ret = max(ret, offset + xs->eax);
|
||||
}
|
||||
|
||||
xstate_bv >>= 1;
|
||||
|
||||
@@ -32,6 +32,7 @@ int kvm_vcpu_ioctl_get_cpuid2(struct kvm_vcpu *vcpu,
|
||||
bool kvm_cpuid(struct kvm_vcpu *vcpu, u32 *eax, u32 *ebx,
|
||||
u32 *ecx, u32 *edx, bool exact_only);
|
||||
|
||||
void __init kvm_init_xstate_sizes(void);
|
||||
u32 xstate_required_size(u64 xstate_bv, bool compacted);
|
||||
|
||||
int cpuid_query_maxphyaddr(struct kvm_vcpu *vcpu);
|
||||
|
||||
@@ -9712,7 +9712,7 @@ static int complete_hypercall_exit(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
u64 ret = vcpu->run->hypercall.ret;
|
||||
|
||||
if (!is_64_bit_mode(vcpu))
|
||||
if (!is_64_bit_hypercall(vcpu))
|
||||
ret = (u32)ret;
|
||||
kvm_rax_write(vcpu, ret);
|
||||
++vcpu->stat.hypercalls;
|
||||
@@ -13820,6 +13820,8 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_vmgexit_msr_protocol_exit);
|
||||
|
||||
static int __init kvm_x86_init(void)
|
||||
{
|
||||
kvm_init_xstate_sizes();
|
||||
|
||||
kvm_mmu_x86_module_init();
|
||||
mitigate_smt_rsb &= boot_cpu_has_bug(X86_BUG_SMT_RSB) && cpu_smt_possible();
|
||||
return 0;
|
||||
|
||||
@@ -3674,16 +3674,11 @@ static int blk_mq_init_hctx(struct request_queue *q,
|
||||
{
|
||||
hctx->queue_num = hctx_idx;
|
||||
|
||||
if (!(hctx->flags & BLK_MQ_F_STACKING))
|
||||
cpuhp_state_add_instance_nocalls(CPUHP_AP_BLK_MQ_ONLINE,
|
||||
&hctx->cpuhp_online);
|
||||
cpuhp_state_add_instance_nocalls(CPUHP_BLK_MQ_DEAD, &hctx->cpuhp_dead);
|
||||
|
||||
hctx->tags = set->tags[hctx_idx];
|
||||
|
||||
if (set->ops->init_hctx &&
|
||||
set->ops->init_hctx(hctx, set->driver_data, hctx_idx))
|
||||
goto unregister_cpu_notifier;
|
||||
goto fail;
|
||||
|
||||
if (blk_mq_init_request(set, hctx->fq->flush_rq, hctx_idx,
|
||||
hctx->numa_node))
|
||||
@@ -3692,6 +3687,11 @@ static int blk_mq_init_hctx(struct request_queue *q,
|
||||
if (xa_insert(&q->hctx_table, hctx_idx, hctx, GFP_KERNEL))
|
||||
goto exit_flush_rq;
|
||||
|
||||
if (!(hctx->flags & BLK_MQ_F_STACKING))
|
||||
cpuhp_state_add_instance_nocalls(CPUHP_AP_BLK_MQ_ONLINE,
|
||||
&hctx->cpuhp_online);
|
||||
cpuhp_state_add_instance_nocalls(CPUHP_BLK_MQ_DEAD, &hctx->cpuhp_dead);
|
||||
|
||||
return 0;
|
||||
|
||||
exit_flush_rq:
|
||||
@@ -3700,8 +3700,7 @@ static int blk_mq_init_hctx(struct request_queue *q,
|
||||
exit_hctx:
|
||||
if (set->ops->exit_hctx)
|
||||
set->ops->exit_hctx(hctx, hctx_idx);
|
||||
unregister_cpu_notifier:
|
||||
blk_mq_remove_cpuhp(hctx);
|
||||
fail:
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -2013,6 +2013,7 @@ free:
|
||||
|
||||
static void genpd_free_data(struct generic_pm_domain *genpd)
|
||||
{
|
||||
put_device(&genpd->dev);
|
||||
if (genpd_is_cpu_domain(genpd))
|
||||
free_cpumask_var(genpd->cpus);
|
||||
if (genpd->free_states)
|
||||
|
||||
@@ -1155,13 +1155,13 @@ skip_format_initialization:
|
||||
|
||||
/* Sanity check */
|
||||
if (range_cfg->range_max < range_cfg->range_min) {
|
||||
dev_err(map->dev, "Invalid range %d: %d < %d\n", i,
|
||||
dev_err(map->dev, "Invalid range %d: %u < %u\n", i,
|
||||
range_cfg->range_max, range_cfg->range_min);
|
||||
goto err_range;
|
||||
}
|
||||
|
||||
if (range_cfg->range_max > map->max_register) {
|
||||
dev_err(map->dev, "Invalid range %d: %d > %d\n", i,
|
||||
dev_err(map->dev, "Invalid range %d: %u > %u\n", i,
|
||||
range_cfg->range_max, map->max_register);
|
||||
goto err_range;
|
||||
}
|
||||
|
||||
@@ -1201,9 +1201,12 @@ static void virtblk_remove(struct virtio_device *vdev)
|
||||
static int virtblk_freeze(struct virtio_device *vdev)
|
||||
{
|
||||
struct virtio_blk *vblk = vdev->priv;
|
||||
struct request_queue *q = vblk->disk->queue;
|
||||
|
||||
/* Ensure no requests in virtqueues before deleting vqs. */
|
||||
blk_mq_freeze_queue(vblk->disk->queue);
|
||||
blk_mq_freeze_queue(q);
|
||||
blk_mq_quiesce_queue_nowait(q);
|
||||
blk_mq_unfreeze_queue(q);
|
||||
|
||||
/* Ensure we don't receive any more interrupts */
|
||||
virtio_reset_device(vdev);
|
||||
@@ -1227,8 +1230,8 @@ static int virtblk_restore(struct virtio_device *vdev)
|
||||
return ret;
|
||||
|
||||
virtio_device_ready(vdev);
|
||||
blk_mq_unquiesce_queue(vblk->disk->queue);
|
||||
|
||||
blk_mq_unfreeze_queue(vblk->disk->queue);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -530,6 +530,12 @@ static ssize_t backing_dev_store(struct device *dev,
|
||||
}
|
||||
|
||||
nr_pages = i_size_read(inode) >> PAGE_SHIFT;
|
||||
/* Refuse to use zero sized device (also prevents self reference) */
|
||||
if (!nr_pages) {
|
||||
err = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
bitmap_sz = BITS_TO_LONGS(nr_pages) * sizeof(long);
|
||||
bitmap = kvzalloc(bitmap_sz, GFP_KERNEL);
|
||||
if (!bitmap) {
|
||||
@@ -1162,12 +1168,16 @@ static void zram_meta_free(struct zram *zram, u64 disksize)
|
||||
size_t num_pages = disksize >> PAGE_SHIFT;
|
||||
size_t index;
|
||||
|
||||
if (!zram->table)
|
||||
return;
|
||||
|
||||
/* Free all pages that are still in this zram device */
|
||||
for (index = 0; index < num_pages; index++)
|
||||
zram_free_page(zram, index);
|
||||
|
||||
zs_destroy_pool(zram->mem_pool);
|
||||
vfree(zram->table);
|
||||
zram->table = NULL;
|
||||
}
|
||||
|
||||
static bool zram_meta_alloc(struct zram *zram, u64 disksize)
|
||||
@@ -1717,11 +1727,6 @@ static void zram_reset_device(struct zram *zram)
|
||||
|
||||
zram->limit_pages = 0;
|
||||
|
||||
if (!init_done(zram)) {
|
||||
up_write(&zram->init_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
set_capacity_and_notify(zram->disk, 0);
|
||||
part_stat_set_all(zram->disk->part0, 0);
|
||||
|
||||
@@ -1729,7 +1734,8 @@ static void zram_reset_device(struct zram *zram)
|
||||
zram_meta_free(zram, zram->disksize);
|
||||
zram->disksize = 0;
|
||||
memset(&zram->stats, 0, sizeof(zram->stats));
|
||||
zcomp_destroy(zram->comp);
|
||||
if (zram->comp)
|
||||
zcomp_destroy(zram->comp);
|
||||
zram->comp = NULL;
|
||||
reset_bdev(zram);
|
||||
|
||||
|
||||
@@ -27,7 +27,8 @@
|
||||
#include <asm/mshyperv.h>
|
||||
|
||||
static struct clock_event_device __percpu *hv_clock_event;
|
||||
static u64 hv_sched_clock_offset __ro_after_init;
|
||||
/* Note: offset can hold negative values after hibernation. */
|
||||
static u64 hv_sched_clock_offset __read_mostly;
|
||||
|
||||
/*
|
||||
* If false, we're using the old mechanism for stimer0 interrupts
|
||||
@@ -417,6 +418,17 @@ static void resume_hv_clock_tsc(struct clocksource *arg)
|
||||
hv_set_register(HV_REGISTER_REFERENCE_TSC, tsc_msr.as_uint64);
|
||||
}
|
||||
|
||||
/*
|
||||
* Called during resume from hibernation, from overridden
|
||||
* x86_platform.restore_sched_clock_state routine. This is to adjust offsets
|
||||
* used to calculate time for hv tsc page based sched_clock, to account for
|
||||
* time spent before hibernation.
|
||||
*/
|
||||
void hv_adj_sched_clock_offset(u64 offset)
|
||||
{
|
||||
hv_sched_clock_offset -= offset;
|
||||
}
|
||||
|
||||
#ifdef HAVE_VDSO_CLOCKMODE_HVCLOCK
|
||||
static int hv_cs_enable(struct clocksource *cs)
|
||||
{
|
||||
|
||||
@@ -974,6 +974,7 @@ static int cxl_port_setup_targets(struct cxl_port *port,
|
||||
struct cxl_region_params *p = &cxlr->params;
|
||||
struct cxl_decoder *cxld = cxl_rr->decoder;
|
||||
struct cxl_switch_decoder *cxlsd;
|
||||
struct cxl_port *iter = port;
|
||||
u16 eig, peig;
|
||||
u8 eiw, peiw;
|
||||
|
||||
@@ -990,16 +991,26 @@ static int cxl_port_setup_targets(struct cxl_port *port,
|
||||
|
||||
cxlsd = to_cxl_switch_decoder(&cxld->dev);
|
||||
if (cxl_rr->nr_targets_set) {
|
||||
int i, distance;
|
||||
int i, distance = 1;
|
||||
struct cxl_region_ref *cxl_rr_iter;
|
||||
|
||||
/*
|
||||
* Passthrough decoders impose no distance requirements between
|
||||
* peers
|
||||
* The "distance" between peer downstream ports represents which
|
||||
* endpoint positions in the region interleave a given port can
|
||||
* host.
|
||||
*
|
||||
* For example, at the root of a hierarchy the distance is
|
||||
* always 1 as every index targets a different host-bridge. At
|
||||
* each subsequent switch level those ports map every Nth region
|
||||
* position where N is the width of the switch == distance.
|
||||
*/
|
||||
if (cxl_rr->nr_targets == 1)
|
||||
distance = 0;
|
||||
else
|
||||
distance = p->nr_targets / cxl_rr->nr_targets;
|
||||
do {
|
||||
cxl_rr_iter = cxl_rr_load(iter, cxlr);
|
||||
distance *= cxl_rr_iter->nr_targets;
|
||||
iter = to_cxl_port(iter->dev.parent);
|
||||
} while (!is_cxl_root(iter));
|
||||
distance *= cxlrd->cxlsd.cxld.interleave_ways;
|
||||
|
||||
for (i = 0; i < cxl_rr->nr_targets_set; i++)
|
||||
if (ep->dport == cxlsd->target[i]) {
|
||||
rc = check_last_peer(cxled, ep, cxl_rr,
|
||||
|
||||
@@ -164,7 +164,7 @@ static const struct dma_buf_ops udmabuf_ops = {
|
||||
};
|
||||
|
||||
#define SEALS_WANTED (F_SEAL_SHRINK)
|
||||
#define SEALS_DENIED (F_SEAL_WRITE)
|
||||
#define SEALS_DENIED (F_SEAL_WRITE|F_SEAL_FUTURE_WRITE)
|
||||
|
||||
static long udmabuf_create(struct miscdevice *device,
|
||||
struct udmabuf_create_list *head,
|
||||
|
||||
@@ -152,6 +152,8 @@ static int admac_alloc_sram_carveout(struct admac_data *ad,
|
||||
{
|
||||
struct admac_sram *sram;
|
||||
int i, ret = 0, nblocks;
|
||||
ad->txcache.size = readl_relaxed(ad->base + REG_TX_SRAM_SIZE);
|
||||
ad->rxcache.size = readl_relaxed(ad->base + REG_RX_SRAM_SIZE);
|
||||
|
||||
if (dir == DMA_MEM_TO_DEV)
|
||||
sram = &ad->txcache;
|
||||
@@ -911,12 +913,7 @@ static int admac_probe(struct platform_device *pdev)
|
||||
goto free_irq;
|
||||
}
|
||||
|
||||
ad->txcache.size = readl_relaxed(ad->base + REG_TX_SRAM_SIZE);
|
||||
ad->rxcache.size = readl_relaxed(ad->base + REG_RX_SRAM_SIZE);
|
||||
|
||||
dev_info(&pdev->dev, "Audio DMA Controller\n");
|
||||
dev_info(&pdev->dev, "imprint %x TX cache %u RX cache %u\n",
|
||||
readl_relaxed(ad->base + REG_IMPRINT), ad->txcache.size, ad->rxcache.size);
|
||||
|
||||
return 0;
|
||||
|
||||
|
||||
@@ -1287,6 +1287,8 @@ at_xdmac_prep_dma_memset(struct dma_chan *chan, dma_addr_t dest, int value,
|
||||
return NULL;
|
||||
|
||||
desc = at_xdmac_memset_create_desc(chan, atchan, dest, len, value);
|
||||
if (!desc)
|
||||
return NULL;
|
||||
list_add_tail(&desc->desc_node, &desc->descs_list);
|
||||
|
||||
desc->tx_dma_desc.cookie = -EBUSY;
|
||||
|
||||
@@ -8,13 +8,15 @@
|
||||
|
||||
static bool dw_dma_acpi_filter(struct dma_chan *chan, void *param)
|
||||
{
|
||||
struct dw_dma *dw = to_dw_dma(chan->device);
|
||||
struct dw_dma_chip_pdata *data = dev_get_drvdata(dw->dma.dev);
|
||||
struct acpi_dma_spec *dma_spec = param;
|
||||
struct dw_dma_slave slave = {
|
||||
.dma_dev = dma_spec->dev,
|
||||
.src_id = dma_spec->slave_id,
|
||||
.dst_id = dma_spec->slave_id,
|
||||
.m_master = 0,
|
||||
.p_master = 1,
|
||||
.m_master = data->m_master,
|
||||
.p_master = data->p_master,
|
||||
};
|
||||
|
||||
return dw_dma_filter(chan, &slave);
|
||||
|
||||
@@ -51,11 +51,15 @@ struct dw_dma_chip_pdata {
|
||||
int (*probe)(struct dw_dma_chip *chip);
|
||||
int (*remove)(struct dw_dma_chip *chip);
|
||||
struct dw_dma_chip *chip;
|
||||
u8 m_master;
|
||||
u8 p_master;
|
||||
};
|
||||
|
||||
static __maybe_unused const struct dw_dma_chip_pdata dw_dma_chip_pdata = {
|
||||
.probe = dw_dma_probe,
|
||||
.remove = dw_dma_remove,
|
||||
.m_master = 0,
|
||||
.p_master = 1,
|
||||
};
|
||||
|
||||
static const struct dw_dma_platform_data idma32_pdata = {
|
||||
@@ -72,6 +76,8 @@ static __maybe_unused const struct dw_dma_chip_pdata idma32_chip_pdata = {
|
||||
.pdata = &idma32_pdata,
|
||||
.probe = idma32_dma_probe,
|
||||
.remove = idma32_dma_remove,
|
||||
.m_master = 0,
|
||||
.p_master = 0,
|
||||
};
|
||||
|
||||
static const struct dw_dma_platform_data xbar_pdata = {
|
||||
@@ -88,6 +94,8 @@ static __maybe_unused const struct dw_dma_chip_pdata xbar_chip_pdata = {
|
||||
.pdata = &xbar_pdata,
|
||||
.probe = idma32_dma_probe,
|
||||
.remove = idma32_dma_remove,
|
||||
.m_master = 0,
|
||||
.p_master = 0,
|
||||
};
|
||||
|
||||
#endif /* _DMA_DW_INTERNAL_H */
|
||||
|
||||
@@ -56,10 +56,10 @@ static int dw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
dw_dma_acpi_controller_register(chip->dw);
|
||||
|
||||
pci_set_drvdata(pdev, data);
|
||||
|
||||
dw_dma_acpi_controller_register(chip->dw);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1393,6 +1393,7 @@ static int mv_xor_probe(struct platform_device *pdev)
|
||||
irq = irq_of_parse_and_map(np, 0);
|
||||
if (!irq) {
|
||||
ret = -ENODEV;
|
||||
of_node_put(np);
|
||||
goto err_channel_add;
|
||||
}
|
||||
|
||||
@@ -1401,6 +1402,7 @@ static int mv_xor_probe(struct platform_device *pdev)
|
||||
if (IS_ERR(chan)) {
|
||||
ret = PTR_ERR(chan);
|
||||
irq_dispose_mapping(irq);
|
||||
of_node_put(np);
|
||||
goto err_channel_add;
|
||||
}
|
||||
|
||||
|
||||
@@ -228,6 +228,7 @@ struct tegra_dma_channel {
|
||||
bool config_init;
|
||||
char name[30];
|
||||
enum dma_transfer_direction sid_dir;
|
||||
enum dma_status status;
|
||||
int id;
|
||||
int irq;
|
||||
int slave_id;
|
||||
@@ -389,6 +390,8 @@ static int tegra_dma_pause(struct tegra_dma_channel *tdc)
|
||||
tegra_dma_dump_chan_regs(tdc);
|
||||
}
|
||||
|
||||
tdc->status = DMA_PAUSED;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -415,6 +418,8 @@ static void tegra_dma_resume(struct tegra_dma_channel *tdc)
|
||||
val = tdc_read(tdc, TEGRA_GPCDMA_CHAN_CSRE);
|
||||
val &= ~TEGRA_GPCDMA_CHAN_CSRE_PAUSE;
|
||||
tdc_write(tdc, TEGRA_GPCDMA_CHAN_CSRE, val);
|
||||
|
||||
tdc->status = DMA_IN_PROGRESS;
|
||||
}
|
||||
|
||||
static int tegra_dma_device_resume(struct dma_chan *dc)
|
||||
@@ -540,6 +545,7 @@ static void tegra_dma_xfer_complete(struct tegra_dma_channel *tdc)
|
||||
|
||||
tegra_dma_sid_free(tdc);
|
||||
tdc->dma_desc = NULL;
|
||||
tdc->status = DMA_COMPLETE;
|
||||
}
|
||||
|
||||
static void tegra_dma_chan_decode_error(struct tegra_dma_channel *tdc,
|
||||
@@ -712,6 +718,7 @@ static int tegra_dma_terminate_all(struct dma_chan *dc)
|
||||
tdc->dma_desc = NULL;
|
||||
}
|
||||
|
||||
tdc->status = DMA_COMPLETE;
|
||||
tegra_dma_sid_free(tdc);
|
||||
vchan_get_all_descriptors(&tdc->vc, &head);
|
||||
spin_unlock_irqrestore(&tdc->vc.lock, flags);
|
||||
@@ -765,6 +772,9 @@ static enum dma_status tegra_dma_tx_status(struct dma_chan *dc,
|
||||
if (ret == DMA_COMPLETE)
|
||||
return ret;
|
||||
|
||||
if (tdc->status == DMA_PAUSED)
|
||||
ret = DMA_PAUSED;
|
||||
|
||||
spin_lock_irqsave(&tdc->vc.lock, flags);
|
||||
vd = vchan_find_desc(&tdc->vc, cookie);
|
||||
if (vd) {
|
||||
|
||||
@@ -150,7 +150,6 @@ void amdgpu_job_set_resources(struct amdgpu_job *job, struct amdgpu_bo *gds,
|
||||
|
||||
void amdgpu_job_free_resources(struct amdgpu_job *job)
|
||||
{
|
||||
struct amdgpu_ring *ring = to_amdgpu_ring(job->base.sched);
|
||||
struct dma_fence *f;
|
||||
unsigned i;
|
||||
|
||||
@@ -163,7 +162,7 @@ void amdgpu_job_free_resources(struct amdgpu_job *job)
|
||||
f = NULL;
|
||||
|
||||
for (i = 0; i < job->num_ibs; ++i)
|
||||
amdgpu_ib_free(ring->adev, &job->ibs[i], f);
|
||||
amdgpu_ib_free(NULL, &job->ibs[i], f);
|
||||
}
|
||||
|
||||
static void amdgpu_job_free_cb(struct drm_sched_job *s_job)
|
||||
|
||||
@@ -1060,10 +1060,9 @@ int amdgpu_vm_bo_update(struct amdgpu_device *adev, struct amdgpu_bo_va *bo_va,
|
||||
* next command submission.
|
||||
*/
|
||||
if (bo && bo->tbo.base.resv == vm->root.bo->tbo.base.resv) {
|
||||
uint32_t mem_type = bo->tbo.resource->mem_type;
|
||||
|
||||
if (!(bo->preferred_domains &
|
||||
amdgpu_mem_type_to_domain(mem_type)))
|
||||
if (bo->tbo.resource &&
|
||||
!(bo->preferred_domains &
|
||||
amdgpu_mem_type_to_domain(bo->tbo.resource->mem_type)))
|
||||
amdgpu_vm_bo_evicted(&bo_va->base);
|
||||
else
|
||||
amdgpu_vm_bo_idle(&bo_va->base);
|
||||
|
||||
@@ -324,7 +324,7 @@ svm_migrate_copy_to_vram(struct amdgpu_device *adev, struct svm_range *prange,
|
||||
spage = migrate_pfn_to_page(migrate->src[i]);
|
||||
if (spage && !is_zone_device_page(spage)) {
|
||||
src[i] = dma_map_page(dev, spage, 0, PAGE_SIZE,
|
||||
DMA_TO_DEVICE);
|
||||
DMA_BIDIRECTIONAL);
|
||||
r = dma_mapping_error(dev, src[i]);
|
||||
if (r) {
|
||||
dev_err(adev->dev, "%s: fail %d dma_map_page\n",
|
||||
@@ -623,7 +623,7 @@ svm_migrate_copy_to_ram(struct amdgpu_device *adev, struct svm_range *prange,
|
||||
goto out_oom;
|
||||
}
|
||||
|
||||
dst[i] = dma_map_page(dev, dpage, 0, PAGE_SIZE, DMA_FROM_DEVICE);
|
||||
dst[i] = dma_map_page(dev, dpage, 0, PAGE_SIZE, DMA_BIDIRECTIONAL);
|
||||
r = dma_mapping_error(dev, dst[i]);
|
||||
if (r) {
|
||||
dev_err(adev->dev, "%s: fail %d dma_map_page\n", __func__, r);
|
||||
|
||||
@@ -153,7 +153,16 @@ static int adv7511_hdmi_hw_params(struct device *dev, void *data,
|
||||
ADV7511_AUDIO_CFG3_LEN_MASK, len);
|
||||
regmap_update_bits(adv7511->regmap, ADV7511_REG_I2C_FREQ_ID_CFG,
|
||||
ADV7511_I2C_FREQ_ID_CFG_RATE_MASK, rate << 4);
|
||||
regmap_write(adv7511->regmap, 0x73, 0x1);
|
||||
|
||||
/* send current Audio infoframe values while updating */
|
||||
regmap_update_bits(adv7511->regmap, ADV7511_REG_INFOFRAME_UPDATE,
|
||||
BIT(5), BIT(5));
|
||||
|
||||
regmap_write(adv7511->regmap, ADV7511_REG_AUDIO_INFOFRAME(0), 0x1);
|
||||
|
||||
/* use Audio infoframe updated info */
|
||||
regmap_update_bits(adv7511->regmap, ADV7511_REG_INFOFRAME_UPDATE,
|
||||
BIT(5), 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -184,8 +193,9 @@ static int audio_startup(struct device *dev, void *data)
|
||||
regmap_update_bits(adv7511->regmap, ADV7511_REG_GC(0),
|
||||
BIT(7) | BIT(6), BIT(7));
|
||||
/* use Audio infoframe updated info */
|
||||
regmap_update_bits(adv7511->regmap, ADV7511_REG_GC(1),
|
||||
regmap_update_bits(adv7511->regmap, ADV7511_REG_INFOFRAME_UPDATE,
|
||||
BIT(5), 0);
|
||||
|
||||
/* enable SPDIF receiver */
|
||||
if (adv7511->audio_source == ADV7511_AUDIO_SOURCE_SPDIF)
|
||||
regmap_update_bits(adv7511->regmap, ADV7511_REG_AUDIO_CONFIG,
|
||||
|
||||
@@ -179,7 +179,7 @@ int adv7533_parse_dt(struct device_node *np, struct adv7511 *adv)
|
||||
|
||||
of_property_read_u32(np, "adi,dsi-lanes", &num_lanes);
|
||||
|
||||
if (num_lanes < 1 || num_lanes > 4)
|
||||
if (num_lanes < 2 || num_lanes > 4)
|
||||
return -EINVAL;
|
||||
|
||||
adv->num_dsi_lanes = num_lanes;
|
||||
|
||||
@@ -4033,9 +4033,10 @@ static void drm_dp_mst_up_req_work(struct work_struct *work)
|
||||
static int drm_dp_mst_handle_up_req(struct drm_dp_mst_topology_mgr *mgr)
|
||||
{
|
||||
struct drm_dp_pending_up_req *up_req;
|
||||
struct drm_dp_mst_branch *mst_primary;
|
||||
|
||||
if (!drm_dp_get_one_sb_msg(mgr, true, NULL))
|
||||
goto out;
|
||||
goto out_clear_reply;
|
||||
|
||||
if (!mgr->up_req_recv.have_eomt)
|
||||
return 0;
|
||||
@@ -4053,10 +4054,19 @@ static int drm_dp_mst_handle_up_req(struct drm_dp_mst_topology_mgr *mgr)
|
||||
drm_dbg_kms(mgr->dev, "Received unknown up req type, ignoring: %x\n",
|
||||
up_req->msg.req_type);
|
||||
kfree(up_req);
|
||||
goto out;
|
||||
goto out_clear_reply;
|
||||
}
|
||||
|
||||
drm_dp_send_up_ack_reply(mgr, mgr->mst_primary, up_req->msg.req_type,
|
||||
mutex_lock(&mgr->lock);
|
||||
mst_primary = mgr->mst_primary;
|
||||
if (!mst_primary || !drm_dp_mst_topology_try_get_mstb(mst_primary)) {
|
||||
mutex_unlock(&mgr->lock);
|
||||
kfree(up_req);
|
||||
goto out_clear_reply;
|
||||
}
|
||||
mutex_unlock(&mgr->lock);
|
||||
|
||||
drm_dp_send_up_ack_reply(mgr, mst_primary, up_req->msg.req_type,
|
||||
false);
|
||||
|
||||
if (up_req->msg.req_type == DP_CONNECTION_STATUS_NOTIFY) {
|
||||
@@ -4073,13 +4083,13 @@ static int drm_dp_mst_handle_up_req(struct drm_dp_mst_topology_mgr *mgr)
|
||||
conn_stat->peer_device_type);
|
||||
|
||||
mutex_lock(&mgr->probe_lock);
|
||||
handle_csn = mgr->mst_primary->link_address_sent;
|
||||
handle_csn = mst_primary->link_address_sent;
|
||||
mutex_unlock(&mgr->probe_lock);
|
||||
|
||||
if (!handle_csn) {
|
||||
drm_dbg_kms(mgr->dev, "Got CSN before finish topology probing. Skip it.");
|
||||
kfree(up_req);
|
||||
goto out;
|
||||
goto out_put_primary;
|
||||
}
|
||||
} else if (up_req->msg.req_type == DP_RESOURCE_STATUS_NOTIFY) {
|
||||
const struct drm_dp_resource_status_notify *res_stat =
|
||||
@@ -4096,7 +4106,9 @@ static int drm_dp_mst_handle_up_req(struct drm_dp_mst_topology_mgr *mgr)
|
||||
mutex_unlock(&mgr->up_req_lock);
|
||||
queue_work(system_long_wq, &mgr->up_req_work);
|
||||
|
||||
out:
|
||||
out_put_primary:
|
||||
drm_dp_mst_topology_put_mstb(mst_primary);
|
||||
out_clear_reply:
|
||||
memset(&mgr->up_req_recv, 0, sizeof(struct drm_dp_sideband_msg_rx));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -808,14 +808,11 @@ EXPORT_SYMBOL(drm_mode_set_name);
|
||||
*/
|
||||
int drm_mode_vrefresh(const struct drm_display_mode *mode)
|
||||
{
|
||||
unsigned int num, den;
|
||||
unsigned int num = 1, den = 1;
|
||||
|
||||
if (mode->htotal == 0 || mode->vtotal == 0)
|
||||
return 0;
|
||||
|
||||
num = mode->clock;
|
||||
den = mode->htotal * mode->vtotal;
|
||||
|
||||
if (mode->flags & DRM_MODE_FLAG_INTERLACE)
|
||||
num *= 2;
|
||||
if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
|
||||
@@ -823,6 +820,12 @@ int drm_mode_vrefresh(const struct drm_display_mode *mode)
|
||||
if (mode->vscan > 1)
|
||||
den *= mode->vscan;
|
||||
|
||||
if (check_mul_overflow(mode->clock, num, &num))
|
||||
return 0;
|
||||
|
||||
if (check_mul_overflow(mode->htotal * mode->vtotal, den, &den))
|
||||
return 0;
|
||||
|
||||
return DIV_ROUND_CLOSEST_ULL(mul_u32_u32(num, 1000), den);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_mode_vrefresh);
|
||||
|
||||
@@ -339,6 +339,11 @@ struct intel_engine_guc_stats {
|
||||
* @start_gt_clk: GT clock time of last idle to active transition.
|
||||
*/
|
||||
u64 start_gt_clk;
|
||||
|
||||
/**
|
||||
* @total: The last value of total returned
|
||||
*/
|
||||
u64 total;
|
||||
};
|
||||
|
||||
struct intel_engine_cs {
|
||||
|
||||
@@ -134,7 +134,7 @@ static void gen11_rc6_enable(struct intel_rc6 *rc6)
|
||||
GEN9_MEDIA_PG_ENABLE |
|
||||
GEN11_MEDIA_SAMPLER_PG_ENABLE;
|
||||
|
||||
if (GRAPHICS_VER(gt->i915) >= 12) {
|
||||
if (GRAPHICS_VER(gt->i915) >= 12 && !IS_DG1(gt->i915)) {
|
||||
for (i = 0; i < I915_MAX_VCS; i++)
|
||||
if (HAS_ENGINE(gt, _VCS(i)))
|
||||
pg_enable |= (VDN_HCP_POWERGATE_ENABLE(i) |
|
||||
|
||||
@@ -1213,6 +1213,21 @@ static void __get_engine_usage_record(struct intel_engine_cs *engine,
|
||||
} while (++i < 6);
|
||||
}
|
||||
|
||||
static void __set_engine_usage_record(struct intel_engine_cs *engine,
|
||||
u32 last_in, u32 id, u32 total)
|
||||
{
|
||||
struct iosys_map rec_map = intel_guc_engine_usage_record_map(engine);
|
||||
|
||||
#define record_write(map_, field_, val_) \
|
||||
iosys_map_wr_field(map_, 0, struct guc_engine_usage_record, field_, val_)
|
||||
|
||||
record_write(&rec_map, last_switch_in_stamp, last_in);
|
||||
record_write(&rec_map, current_context_index, id);
|
||||
record_write(&rec_map, total_runtime, total);
|
||||
|
||||
#undef record_write
|
||||
}
|
||||
|
||||
static void guc_update_engine_gt_clks(struct intel_engine_cs *engine)
|
||||
{
|
||||
struct intel_engine_guc_stats *stats = &engine->stats.guc;
|
||||
@@ -1331,9 +1346,12 @@ static ktime_t guc_engine_busyness(struct intel_engine_cs *engine, ktime_t *now)
|
||||
total += intel_gt_clock_interval_to_ns(gt, clk);
|
||||
}
|
||||
|
||||
if (total > stats->total)
|
||||
stats->total = total;
|
||||
|
||||
spin_unlock_irqrestore(&guc->timestamp.lock, flags);
|
||||
|
||||
return ns_to_ktime(total);
|
||||
return ns_to_ktime(stats->total);
|
||||
}
|
||||
|
||||
static void __reset_guc_busyness_stats(struct intel_guc *guc)
|
||||
@@ -1350,8 +1368,21 @@ static void __reset_guc_busyness_stats(struct intel_guc *guc)
|
||||
|
||||
guc_update_pm_timestamp(guc, &unused);
|
||||
for_each_engine(engine, gt, id) {
|
||||
struct intel_engine_guc_stats *stats = &engine->stats.guc;
|
||||
|
||||
guc_update_engine_gt_clks(engine);
|
||||
engine->stats.guc.prev_total = 0;
|
||||
|
||||
/*
|
||||
* If resetting a running context, accumulate the active
|
||||
* time as well since there will be no context switch.
|
||||
*/
|
||||
if (stats->running) {
|
||||
u64 clk = guc->timestamp.gt_stamp - stats->start_gt_clk;
|
||||
|
||||
stats->total_gt_clks += clk;
|
||||
}
|
||||
stats->prev_total = 0;
|
||||
stats->running = 0;
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&guc->timestamp.lock, flags);
|
||||
@@ -1404,6 +1435,9 @@ static void guc_timestamp_ping(struct work_struct *wrk)
|
||||
|
||||
static int guc_action_enable_usage_stats(struct intel_guc *guc)
|
||||
{
|
||||
struct intel_gt *gt = guc_to_gt(guc);
|
||||
struct intel_engine_cs *engine;
|
||||
enum intel_engine_id id;
|
||||
u32 offset = intel_guc_engine_usage_offset(guc);
|
||||
u32 action[] = {
|
||||
INTEL_GUC_ACTION_SET_ENG_UTIL_BUFF,
|
||||
@@ -1411,6 +1445,9 @@ static int guc_action_enable_usage_stats(struct intel_guc *guc)
|
||||
0,
|
||||
};
|
||||
|
||||
for_each_engine(engine, gt, id)
|
||||
__set_engine_usage_record(engine, 0, 0xffffffff, 0);
|
||||
|
||||
return intel_guc_send(guc, action, ARRAY_SIZE(action));
|
||||
}
|
||||
|
||||
|
||||
@@ -577,9 +577,9 @@ static int nt35950_probe(struct mipi_dsi_device *dsi)
|
||||
return dev_err_probe(dev, -EPROBE_DEFER, "Cannot get secondary DSI host\n");
|
||||
|
||||
nt->dsi[1] = mipi_dsi_device_register_full(dsi_r_host, info);
|
||||
if (!nt->dsi[1]) {
|
||||
if (IS_ERR(nt->dsi[1])) {
|
||||
dev_err(dev, "Cannot get secondary DSI node\n");
|
||||
return -ENODEV;
|
||||
return PTR_ERR(nt->dsi[1]);
|
||||
}
|
||||
num_dsis++;
|
||||
}
|
||||
|
||||
@@ -767,6 +767,12 @@ hv_kvp_init(struct hv_util_service *srv)
|
||||
*/
|
||||
kvp_transaction.state = HVUTIL_DEVICE_INIT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
hv_kvp_init_transport(void)
|
||||
{
|
||||
hvt = hvutil_transport_init(kvp_devname, CN_KVP_IDX, CN_KVP_VAL,
|
||||
kvp_on_msg, kvp_on_reset);
|
||||
if (!hvt)
|
||||
|
||||
@@ -388,6 +388,12 @@ hv_vss_init(struct hv_util_service *srv)
|
||||
*/
|
||||
vss_transaction.state = HVUTIL_DEVICE_INIT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
hv_vss_init_transport(void)
|
||||
{
|
||||
hvt = hvutil_transport_init(vss_devname, CN_VSS_IDX, CN_VSS_VAL,
|
||||
vss_on_msg, vss_on_reset);
|
||||
if (!hvt) {
|
||||
|
||||
@@ -141,6 +141,7 @@ static struct hv_util_service util_heartbeat = {
|
||||
static struct hv_util_service util_kvp = {
|
||||
.util_cb = hv_kvp_onchannelcallback,
|
||||
.util_init = hv_kvp_init,
|
||||
.util_init_transport = hv_kvp_init_transport,
|
||||
.util_pre_suspend = hv_kvp_pre_suspend,
|
||||
.util_pre_resume = hv_kvp_pre_resume,
|
||||
.util_deinit = hv_kvp_deinit,
|
||||
@@ -149,6 +150,7 @@ static struct hv_util_service util_kvp = {
|
||||
static struct hv_util_service util_vss = {
|
||||
.util_cb = hv_vss_onchannelcallback,
|
||||
.util_init = hv_vss_init,
|
||||
.util_init_transport = hv_vss_init_transport,
|
||||
.util_pre_suspend = hv_vss_pre_suspend,
|
||||
.util_pre_resume = hv_vss_pre_resume,
|
||||
.util_deinit = hv_vss_deinit,
|
||||
@@ -592,6 +594,13 @@ static int util_probe(struct hv_device *dev,
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
if (srv->util_init_transport) {
|
||||
ret = srv->util_init_transport();
|
||||
if (ret) {
|
||||
vmbus_close(dev->channel);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
error:
|
||||
|
||||
@@ -365,12 +365,14 @@ void vmbus_on_event(unsigned long data);
|
||||
void vmbus_on_msg_dpc(unsigned long data);
|
||||
|
||||
int hv_kvp_init(struct hv_util_service *srv);
|
||||
int hv_kvp_init_transport(void);
|
||||
void hv_kvp_deinit(void);
|
||||
int hv_kvp_pre_suspend(void);
|
||||
int hv_kvp_pre_resume(void);
|
||||
void hv_kvp_onchannelcallback(void *context);
|
||||
|
||||
int hv_vss_init(struct hv_util_service *srv);
|
||||
int hv_vss_init_transport(void);
|
||||
void hv_vss_deinit(void);
|
||||
int hv_vss_pre_suspend(void);
|
||||
int hv_vss_pre_resume(void);
|
||||
|
||||
@@ -19,15 +19,20 @@
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*/
|
||||
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/bug.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/hwmon.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/math.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/util_macros.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/units.h>
|
||||
|
||||
// Common register definition
|
||||
#define TMP51X_SHUNT_CONFIG 0x00
|
||||
@@ -100,8 +105,8 @@
|
||||
#define TMP51X_REMOTE_TEMP_LIMIT_2_POS 8
|
||||
#define TMP513_REMOTE_TEMP_LIMIT_3_POS 7
|
||||
|
||||
#define TMP51X_VBUS_RANGE_32V 32000000
|
||||
#define TMP51X_VBUS_RANGE_16V 16000000
|
||||
#define TMP51X_VBUS_RANGE_32V (32 * MICRO)
|
||||
#define TMP51X_VBUS_RANGE_16V (16 * MICRO)
|
||||
|
||||
// Max and Min value
|
||||
#define MAX_BUS_VOLTAGE_32_LIMIT 32764
|
||||
@@ -173,7 +178,7 @@ struct tmp51x_data {
|
||||
struct regmap *regmap;
|
||||
};
|
||||
|
||||
// Set the shift based on the gain 8=4, 4=3, 2=2, 1=1
|
||||
// Set the shift based on the gain: 8 -> 1, 4 -> 2, 2 -> 3, 1 -> 4
|
||||
static inline u8 tmp51x_get_pga_shift(struct tmp51x_data *data)
|
||||
{
|
||||
return 5 - ffs(data->pga_gain);
|
||||
@@ -195,8 +200,10 @@ static int tmp51x_get_value(struct tmp51x_data *data, u8 reg, u8 pos,
|
||||
* 2's complement number shifted by one to four depending
|
||||
* on the pga gain setting. 1lsb = 10uV
|
||||
*/
|
||||
*val = sign_extend32(regval, 17 - tmp51x_get_pga_shift(data));
|
||||
*val = DIV_ROUND_CLOSEST(*val * 10000, data->shunt_uohms);
|
||||
*val = sign_extend32(regval,
|
||||
reg == TMP51X_SHUNT_CURRENT_RESULT ?
|
||||
16 - tmp51x_get_pga_shift(data) : 15);
|
||||
*val = DIV_ROUND_CLOSEST(*val * 10 * MILLI, data->shunt_uohms);
|
||||
break;
|
||||
case TMP51X_BUS_VOLTAGE_RESULT:
|
||||
case TMP51X_BUS_VOLTAGE_H_LIMIT:
|
||||
@@ -211,8 +218,8 @@ static int tmp51x_get_value(struct tmp51x_data *data, u8 reg, u8 pos,
|
||||
break;
|
||||
case TMP51X_BUS_CURRENT_RESULT:
|
||||
// Current = (ShuntVoltage * CalibrationRegister) / 4096
|
||||
*val = sign_extend32(regval, 16) * data->curr_lsb_ua;
|
||||
*val = DIV_ROUND_CLOSEST(*val, 1000);
|
||||
*val = sign_extend32(regval, 15) * (long)data->curr_lsb_ua;
|
||||
*val = DIV_ROUND_CLOSEST(*val, MILLI);
|
||||
break;
|
||||
case TMP51X_LOCAL_TEMP_RESULT:
|
||||
case TMP51X_REMOTE_TEMP_RESULT_1:
|
||||
@@ -223,7 +230,7 @@ static int tmp51x_get_value(struct tmp51x_data *data, u8 reg, u8 pos,
|
||||
case TMP51X_REMOTE_TEMP_LIMIT_2:
|
||||
case TMP513_REMOTE_TEMP_LIMIT_3:
|
||||
// 1lsb = 0.0625 degrees centigrade
|
||||
*val = sign_extend32(regval, 16) >> TMP51X_TEMP_SHIFT;
|
||||
*val = sign_extend32(regval, 15) >> TMP51X_TEMP_SHIFT;
|
||||
*val = DIV_ROUND_CLOSEST(*val * 625, 10);
|
||||
break;
|
||||
case TMP51X_N_FACTOR_AND_HYST_1:
|
||||
@@ -252,7 +259,7 @@ static int tmp51x_set_value(struct tmp51x_data *data, u8 reg, long val)
|
||||
* The user enter current value and we convert it to
|
||||
* voltage. 1lsb = 10uV
|
||||
*/
|
||||
val = DIV_ROUND_CLOSEST(val * data->shunt_uohms, 10000);
|
||||
val = DIV_ROUND_CLOSEST(val * data->shunt_uohms, 10 * MILLI);
|
||||
max_val = U16_MAX >> tmp51x_get_pga_shift(data);
|
||||
regval = clamp_val(val, -max_val, max_val);
|
||||
break;
|
||||
@@ -542,18 +549,16 @@ static int tmp51x_calibrate(struct tmp51x_data *data)
|
||||
if (data->shunt_uohms == 0)
|
||||
return regmap_write(data->regmap, TMP51X_SHUNT_CALIBRATION, 0);
|
||||
|
||||
max_curr_ma = DIV_ROUND_CLOSEST_ULL(vshunt_max * 1000 * 1000,
|
||||
data->shunt_uohms);
|
||||
max_curr_ma = DIV_ROUND_CLOSEST_ULL(vshunt_max * MICRO, data->shunt_uohms);
|
||||
|
||||
/*
|
||||
* Calculate the minimal bit resolution for the current and the power.
|
||||
* Those values will be used during register interpretation.
|
||||
*/
|
||||
data->curr_lsb_ua = DIV_ROUND_CLOSEST_ULL(max_curr_ma * 1000, 32767);
|
||||
data->curr_lsb_ua = DIV_ROUND_CLOSEST_ULL(max_curr_ma * MILLI, 32767);
|
||||
data->pwr_lsb_uw = 20 * data->curr_lsb_ua;
|
||||
|
||||
div = DIV_ROUND_CLOSEST_ULL(data->curr_lsb_ua * data->shunt_uohms,
|
||||
1000 * 1000);
|
||||
div = DIV_ROUND_CLOSEST_ULL(data->curr_lsb_ua * data->shunt_uohms, MICRO);
|
||||
|
||||
return regmap_write(data->regmap, TMP51X_SHUNT_CALIBRATION,
|
||||
DIV_ROUND_CLOSEST(40960, div));
|
||||
@@ -628,9 +633,9 @@ static int tmp51x_vbus_range_to_reg(struct device *dev,
|
||||
} else if (data->vbus_range_uvolt == TMP51X_VBUS_RANGE_16V) {
|
||||
data->shunt_config &= ~TMP51X_BUS_VOLTAGE_MASK;
|
||||
} else {
|
||||
dev_err(dev, "ti,bus-range-microvolt is invalid: %u\n",
|
||||
data->vbus_range_uvolt);
|
||||
return -EINVAL;
|
||||
return dev_err_probe(dev, -EINVAL,
|
||||
"ti,bus-range-microvolt is invalid: %u\n",
|
||||
data->vbus_range_uvolt);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -646,8 +651,8 @@ static int tmp51x_pga_gain_to_reg(struct device *dev, struct tmp51x_data *data)
|
||||
} else if (data->pga_gain == 1) {
|
||||
data->shunt_config |= CURRENT_SENSE_VOLTAGE_40_MASK;
|
||||
} else {
|
||||
dev_err(dev, "ti,pga-gain is invalid: %u\n", data->pga_gain);
|
||||
return -EINVAL;
|
||||
return dev_err_probe(dev, -EINVAL,
|
||||
"ti,pga-gain is invalid: %u\n", data->pga_gain);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -679,10 +684,10 @@ static int tmp51x_read_properties(struct device *dev, struct tmp51x_data *data)
|
||||
memcpy(data->nfactor, nfactor, (data->id == tmp513) ? 3 : 2);
|
||||
|
||||
// Check if shunt value is compatible with pga-gain
|
||||
if (data->shunt_uohms > data->pga_gain * 40 * 1000 * 1000) {
|
||||
dev_err(dev, "shunt-resistor: %u too big for pga_gain: %u\n",
|
||||
data->shunt_uohms, data->pga_gain);
|
||||
return -EINVAL;
|
||||
if (data->shunt_uohms > data->pga_gain * 40 * MICRO) {
|
||||
return dev_err_probe(dev, -EINVAL,
|
||||
"shunt-resistor: %u too big for pga_gain: %u\n",
|
||||
data->shunt_uohms, data->pga_gain);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -726,22 +731,17 @@ static int tmp51x_probe(struct i2c_client *client)
|
||||
data->id = i2c_match_id(tmp51x_id, client)->driver_data;
|
||||
|
||||
ret = tmp51x_configure(dev, data);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "error configuring the device: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
if (ret < 0)
|
||||
return dev_err_probe(dev, ret, "error configuring the device\n");
|
||||
|
||||
data->regmap = devm_regmap_init_i2c(client, &tmp51x_regmap_config);
|
||||
if (IS_ERR(data->regmap)) {
|
||||
dev_err(dev, "failed to allocate register map\n");
|
||||
return PTR_ERR(data->regmap);
|
||||
}
|
||||
if (IS_ERR(data->regmap))
|
||||
return dev_err_probe(dev, PTR_ERR(data->regmap),
|
||||
"failed to allocate register map\n");
|
||||
|
||||
ret = tmp51x_init(data);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "error configuring the device: %d\n", ret);
|
||||
return -ENODEV;
|
||||
}
|
||||
if (ret < 0)
|
||||
return dev_err_probe(dev, ret, "error configuring the device\n");
|
||||
|
||||
hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name,
|
||||
data,
|
||||
|
||||
@@ -287,6 +287,7 @@ static const struct of_device_id i2c_imx_dt_ids[] = {
|
||||
{ .compatible = "fsl,imx6sll-i2c", .data = &imx6_i2c_hwdata, },
|
||||
{ .compatible = "fsl,imx6sx-i2c", .data = &imx6_i2c_hwdata, },
|
||||
{ .compatible = "fsl,imx6ul-i2c", .data = &imx6_i2c_hwdata, },
|
||||
{ .compatible = "fsl,imx7d-i2c", .data = &imx6_i2c_hwdata, },
|
||||
{ .compatible = "fsl,imx7s-i2c", .data = &imx6_i2c_hwdata, },
|
||||
{ .compatible = "fsl,imx8mm-i2c", .data = &imx6_i2c_hwdata, },
|
||||
{ .compatible = "fsl,imx8mn-i2c", .data = &imx6_i2c_hwdata, },
|
||||
|
||||
@@ -93,27 +93,35 @@
|
||||
* @base: pointer to register struct
|
||||
* @dev: device reference
|
||||
* @i2c_clk: clock reference for i2c input clock
|
||||
* @msg_queue: pointer to the messages requiring sending
|
||||
* @buf: pointer to msg buffer for easier use
|
||||
* @msg_complete: xfer completion object
|
||||
* @adapter: core i2c abstraction
|
||||
* @msg_err: error code for completed message
|
||||
* @bus_clk_rate: current i2c bus clock rate
|
||||
* @isr_status: cached copy of local ISR status
|
||||
* @total_num: total number of messages to be sent/received
|
||||
* @current_num: index of the current message being sent/received
|
||||
* @msg_len: number of bytes transferred in msg
|
||||
* @addr: address of the current slave
|
||||
* @restart_needed: whether or not a repeated start is required after current message
|
||||
*/
|
||||
struct mchp_corei2c_dev {
|
||||
void __iomem *base;
|
||||
struct device *dev;
|
||||
struct clk *i2c_clk;
|
||||
struct i2c_msg *msg_queue;
|
||||
u8 *buf;
|
||||
struct completion msg_complete;
|
||||
struct i2c_adapter adapter;
|
||||
int msg_err;
|
||||
int total_num;
|
||||
int current_num;
|
||||
u32 bus_clk_rate;
|
||||
u32 isr_status;
|
||||
u16 msg_len;
|
||||
u8 addr;
|
||||
bool restart_needed;
|
||||
};
|
||||
|
||||
static void mchp_corei2c_core_disable(struct mchp_corei2c_dev *idev)
|
||||
@@ -222,6 +230,47 @@ static int mchp_corei2c_fill_tx(struct mchp_corei2c_dev *idev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mchp_corei2c_next_msg(struct mchp_corei2c_dev *idev)
|
||||
{
|
||||
struct i2c_msg *this_msg;
|
||||
u8 ctrl;
|
||||
|
||||
if (idev->current_num >= idev->total_num) {
|
||||
complete(&idev->msg_complete);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* If there's been an error, the isr needs to return control
|
||||
* to the "main" part of the driver, so as not to keep sending
|
||||
* messages once it completes and clears the SI bit.
|
||||
*/
|
||||
if (idev->msg_err) {
|
||||
complete(&idev->msg_complete);
|
||||
return;
|
||||
}
|
||||
|
||||
this_msg = idev->msg_queue++;
|
||||
|
||||
if (idev->current_num < (idev->total_num - 1)) {
|
||||
struct i2c_msg *next_msg = idev->msg_queue;
|
||||
|
||||
idev->restart_needed = next_msg->flags & I2C_M_RD;
|
||||
} else {
|
||||
idev->restart_needed = false;
|
||||
}
|
||||
|
||||
idev->addr = i2c_8bit_addr_from_msg(this_msg);
|
||||
idev->msg_len = this_msg->len;
|
||||
idev->buf = this_msg->buf;
|
||||
|
||||
ctrl = readb(idev->base + CORE_I2C_CTRL);
|
||||
ctrl |= CTRL_STA;
|
||||
writeb(ctrl, idev->base + CORE_I2C_CTRL);
|
||||
|
||||
idev->current_num++;
|
||||
}
|
||||
|
||||
static irqreturn_t mchp_corei2c_handle_isr(struct mchp_corei2c_dev *idev)
|
||||
{
|
||||
u32 status = idev->isr_status;
|
||||
@@ -238,8 +287,6 @@ static irqreturn_t mchp_corei2c_handle_isr(struct mchp_corei2c_dev *idev)
|
||||
ctrl &= ~CTRL_STA;
|
||||
writeb(idev->addr, idev->base + CORE_I2C_DATA);
|
||||
writeb(ctrl, idev->base + CORE_I2C_CTRL);
|
||||
if (idev->msg_len == 0)
|
||||
finished = true;
|
||||
break;
|
||||
case STATUS_M_ARB_LOST:
|
||||
idev->msg_err = -EAGAIN;
|
||||
@@ -247,10 +294,14 @@ static irqreturn_t mchp_corei2c_handle_isr(struct mchp_corei2c_dev *idev)
|
||||
break;
|
||||
case STATUS_M_SLAW_ACK:
|
||||
case STATUS_M_TX_DATA_ACK:
|
||||
if (idev->msg_len > 0)
|
||||
if (idev->msg_len > 0) {
|
||||
mchp_corei2c_fill_tx(idev);
|
||||
else
|
||||
last_byte = true;
|
||||
} else {
|
||||
if (idev->restart_needed)
|
||||
finished = true;
|
||||
else
|
||||
last_byte = true;
|
||||
}
|
||||
break;
|
||||
case STATUS_M_TX_DATA_NACK:
|
||||
case STATUS_M_SLAR_NACK:
|
||||
@@ -287,7 +338,7 @@ static irqreturn_t mchp_corei2c_handle_isr(struct mchp_corei2c_dev *idev)
|
||||
mchp_corei2c_stop(idev);
|
||||
|
||||
if (last_byte || finished)
|
||||
complete(&idev->msg_complete);
|
||||
mchp_corei2c_next_msg(idev);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
@@ -311,21 +362,48 @@ static irqreturn_t mchp_corei2c_isr(int irq, void *_dev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mchp_corei2c_xfer_msg(struct mchp_corei2c_dev *idev,
|
||||
struct i2c_msg *msg)
|
||||
static int mchp_corei2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
|
||||
int num)
|
||||
{
|
||||
u8 ctrl;
|
||||
struct mchp_corei2c_dev *idev = i2c_get_adapdata(adap);
|
||||
struct i2c_msg *this_msg = msgs;
|
||||
unsigned long time_left;
|
||||
|
||||
idev->addr = i2c_8bit_addr_from_msg(msg);
|
||||
idev->msg_len = msg->len;
|
||||
idev->buf = msg->buf;
|
||||
idev->msg_err = 0;
|
||||
|
||||
reinit_completion(&idev->msg_complete);
|
||||
u8 ctrl;
|
||||
|
||||
mchp_corei2c_core_enable(idev);
|
||||
|
||||
/*
|
||||
* The isr controls the flow of a transfer, this info needs to be saved
|
||||
* to a location that it can access the queue information from.
|
||||
*/
|
||||
idev->restart_needed = false;
|
||||
idev->msg_queue = msgs;
|
||||
idev->total_num = num;
|
||||
idev->current_num = 0;
|
||||
|
||||
/*
|
||||
* But the first entry to the isr is triggered by the start in this
|
||||
* function, so the first message needs to be "dequeued".
|
||||
*/
|
||||
idev->addr = i2c_8bit_addr_from_msg(this_msg);
|
||||
idev->msg_len = this_msg->len;
|
||||
idev->buf = this_msg->buf;
|
||||
idev->msg_err = 0;
|
||||
|
||||
if (idev->total_num > 1) {
|
||||
struct i2c_msg *next_msg = msgs + 1;
|
||||
|
||||
idev->restart_needed = next_msg->flags & I2C_M_RD;
|
||||
}
|
||||
|
||||
idev->current_num++;
|
||||
idev->msg_queue++;
|
||||
|
||||
reinit_completion(&idev->msg_complete);
|
||||
|
||||
/*
|
||||
* Send the first start to pass control to the isr
|
||||
*/
|
||||
ctrl = readb(idev->base + CORE_I2C_CTRL);
|
||||
ctrl |= CTRL_STA;
|
||||
writeb(ctrl, idev->base + CORE_I2C_CTRL);
|
||||
@@ -335,20 +413,8 @@ static int mchp_corei2c_xfer_msg(struct mchp_corei2c_dev *idev,
|
||||
if (!time_left)
|
||||
return -ETIMEDOUT;
|
||||
|
||||
return idev->msg_err;
|
||||
}
|
||||
|
||||
static int mchp_corei2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
|
||||
int num)
|
||||
{
|
||||
struct mchp_corei2c_dev *idev = i2c_get_adapdata(adap);
|
||||
int i, ret;
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
ret = mchp_corei2c_xfer_msg(idev, msgs++);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
if (idev->msg_err)
|
||||
return idev->msg_err;
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ enum {
|
||||
|
||||
static inline int wait_timeout(struct i2c_pnx_algo_data *data)
|
||||
{
|
||||
long timeout = data->timeout;
|
||||
long timeout = jiffies_to_msecs(data->timeout);
|
||||
while (timeout > 0 &&
|
||||
(ioread32(I2C_REG_STS(data)) & mstatus_active)) {
|
||||
mdelay(1);
|
||||
@@ -106,7 +106,7 @@ static inline int wait_timeout(struct i2c_pnx_algo_data *data)
|
||||
|
||||
static inline int wait_reset(struct i2c_pnx_algo_data *data)
|
||||
{
|
||||
long timeout = data->timeout;
|
||||
long timeout = jiffies_to_msecs(data->timeout);
|
||||
while (timeout > 0 &&
|
||||
(ioread32(I2C_REG_CTL(data)) & mcntrl_reset)) {
|
||||
mdelay(1);
|
||||
|
||||
@@ -325,7 +325,7 @@ static int riic_init_hw(struct riic_dev *riic, struct i2c_timings *t)
|
||||
if (brl <= (0x1F + 3))
|
||||
break;
|
||||
|
||||
total_ticks /= 2;
|
||||
total_ticks = DIV_ROUND_UP(total_ticks, 2);
|
||||
rate /= 2;
|
||||
}
|
||||
|
||||
|
||||
@@ -161,7 +161,7 @@ static const void __user *uverbs_request_next_ptr(struct uverbs_req_iter *iter,
|
||||
{
|
||||
const void __user *res = iter->cur;
|
||||
|
||||
if (iter->cur + len > iter->end)
|
||||
if (len > iter->end - iter->cur)
|
||||
return (void __force __user *)ERR_PTR(-ENOSPC);
|
||||
iter->cur += len;
|
||||
return res;
|
||||
@@ -2009,11 +2009,13 @@ static int ib_uverbs_post_send(struct uverbs_attr_bundle *attrs)
|
||||
ret = uverbs_request_start(attrs, &iter, &cmd, sizeof(cmd));
|
||||
if (ret)
|
||||
return ret;
|
||||
wqes = uverbs_request_next_ptr(&iter, cmd.wqe_size * cmd.wr_count);
|
||||
wqes = uverbs_request_next_ptr(&iter, size_mul(cmd.wqe_size,
|
||||
cmd.wr_count));
|
||||
if (IS_ERR(wqes))
|
||||
return PTR_ERR(wqes);
|
||||
sgls = uverbs_request_next_ptr(
|
||||
&iter, cmd.sge_count * sizeof(struct ib_uverbs_sge));
|
||||
sgls = uverbs_request_next_ptr(&iter,
|
||||
size_mul(cmd.sge_count,
|
||||
sizeof(struct ib_uverbs_sge)));
|
||||
if (IS_ERR(sgls))
|
||||
return PTR_ERR(sgls);
|
||||
ret = uverbs_request_finish(&iter);
|
||||
@@ -2199,11 +2201,11 @@ ib_uverbs_unmarshall_recv(struct uverbs_req_iter *iter, u32 wr_count,
|
||||
if (wqe_size < sizeof(struct ib_uverbs_recv_wr))
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
wqes = uverbs_request_next_ptr(iter, wqe_size * wr_count);
|
||||
wqes = uverbs_request_next_ptr(iter, size_mul(wqe_size, wr_count));
|
||||
if (IS_ERR(wqes))
|
||||
return ERR_CAST(wqes);
|
||||
sgls = uverbs_request_next_ptr(
|
||||
iter, sge_count * sizeof(struct ib_uverbs_sge));
|
||||
sgls = uverbs_request_next_ptr(iter, size_mul(sge_count,
|
||||
sizeof(struct ib_uverbs_sge)));
|
||||
if (IS_ERR(sgls))
|
||||
return ERR_CAST(sgls);
|
||||
ret = uverbs_request_finish(iter);
|
||||
|
||||
@@ -138,7 +138,7 @@ int bnxt_re_query_device(struct ib_device *ibdev,
|
||||
|
||||
ib_attr->vendor_id = rdev->en_dev->pdev->vendor;
|
||||
ib_attr->vendor_part_id = rdev->en_dev->pdev->device;
|
||||
ib_attr->hw_ver = rdev->en_dev->pdev->subsystem_device;
|
||||
ib_attr->hw_ver = rdev->en_dev->pdev->revision;
|
||||
ib_attr->max_qp = dev_attr->max_qp;
|
||||
ib_attr->max_qp_wr = dev_attr->max_qp_wqes;
|
||||
ib_attr->device_cap_flags =
|
||||
@@ -1940,18 +1940,20 @@ int bnxt_re_modify_qp(struct ib_qp *ib_qp, struct ib_qp_attr *qp_attr,
|
||||
}
|
||||
}
|
||||
|
||||
if (qp_attr_mask & IB_QP_PATH_MTU) {
|
||||
qp->qplib_qp.modify_flags |=
|
||||
CMDQ_MODIFY_QP_MODIFY_MASK_PATH_MTU;
|
||||
qp->qplib_qp.path_mtu = __from_ib_mtu(qp_attr->path_mtu);
|
||||
qp->qplib_qp.mtu = ib_mtu_enum_to_int(qp_attr->path_mtu);
|
||||
} else if (qp_attr->qp_state == IB_QPS_RTR) {
|
||||
qp->qplib_qp.modify_flags |=
|
||||
CMDQ_MODIFY_QP_MODIFY_MASK_PATH_MTU;
|
||||
qp->qplib_qp.path_mtu =
|
||||
__from_ib_mtu(iboe_get_mtu(rdev->netdev->mtu));
|
||||
qp->qplib_qp.mtu =
|
||||
ib_mtu_enum_to_int(iboe_get_mtu(rdev->netdev->mtu));
|
||||
if (qp_attr->qp_state == IB_QPS_RTR) {
|
||||
enum ib_mtu qpmtu;
|
||||
|
||||
qpmtu = iboe_get_mtu(rdev->netdev->mtu);
|
||||
if (qp_attr_mask & IB_QP_PATH_MTU) {
|
||||
if (ib_mtu_enum_to_int(qp_attr->path_mtu) >
|
||||
ib_mtu_enum_to_int(qpmtu))
|
||||
return -EINVAL;
|
||||
qpmtu = qp_attr->path_mtu;
|
||||
}
|
||||
|
||||
qp->qplib_qp.modify_flags |= CMDQ_MODIFY_QP_MODIFY_MASK_PATH_MTU;
|
||||
qp->qplib_qp.path_mtu = __from_ib_mtu(qpmtu);
|
||||
qp->qplib_qp.mtu = ib_mtu_enum_to_int(qpmtu);
|
||||
}
|
||||
|
||||
if (qp_attr_mask & IB_QP_TIMEOUT) {
|
||||
|
||||
@@ -1149,9 +1149,11 @@ int bnxt_qplib_create_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
|
||||
rq->dbinfo.db = qp->dpi->dbr;
|
||||
rq->dbinfo.max_slot = bnxt_qplib_set_rq_max_slot(rq->wqe_size);
|
||||
}
|
||||
spin_lock_bh(&rcfw->tbl_lock);
|
||||
tbl_indx = map_qp_id_to_tbl_indx(qp->id, rcfw);
|
||||
rcfw->qp_tbl[tbl_indx].qp_id = qp->id;
|
||||
rcfw->qp_tbl[tbl_indx].qp_handle = (void *)qp;
|
||||
spin_unlock_bh(&rcfw->tbl_lock);
|
||||
|
||||
return 0;
|
||||
fail:
|
||||
|
||||
@@ -124,7 +124,7 @@ int bnxt_qplib_get_dev_attr(struct bnxt_qplib_rcfw *rcfw,
|
||||
attr->max_qp_init_rd_atom =
|
||||
sb->max_qp_init_rd_atom > BNXT_QPLIB_MAX_OUT_RD_ATOM ?
|
||||
BNXT_QPLIB_MAX_OUT_RD_ATOM : sb->max_qp_init_rd_atom;
|
||||
attr->max_qp_wqes = le16_to_cpu(sb->max_qp_wr);
|
||||
attr->max_qp_wqes = le16_to_cpu(sb->max_qp_wr) - 1;
|
||||
/*
|
||||
* 128 WQEs needs to be reserved for the HW (8916). Prevent
|
||||
* reporting the max number
|
||||
|
||||
@@ -153,8 +153,7 @@ int hns_roce_get_kmem_bufs(struct hns_roce_dev *hr_dev, dma_addr_t *bufs,
|
||||
return total;
|
||||
}
|
||||
|
||||
int hns_roce_get_umem_bufs(struct hns_roce_dev *hr_dev, dma_addr_t *bufs,
|
||||
int buf_cnt, struct ib_umem *umem,
|
||||
int hns_roce_get_umem_bufs(dma_addr_t *bufs, int buf_cnt, struct ib_umem *umem,
|
||||
unsigned int page_shift)
|
||||
{
|
||||
struct ib_block_iter biter;
|
||||
|
||||
@@ -133,14 +133,12 @@ static int alloc_cqc(struct hns_roce_dev *hr_dev, struct hns_roce_cq *hr_cq)
|
||||
struct hns_roce_cq_table *cq_table = &hr_dev->cq_table;
|
||||
struct ib_device *ibdev = &hr_dev->ib_dev;
|
||||
u64 mtts[MTT_MIN_COUNT] = {};
|
||||
dma_addr_t dma_handle;
|
||||
int ret;
|
||||
|
||||
ret = hns_roce_mtr_find(hr_dev, &hr_cq->mtr, 0, mtts, ARRAY_SIZE(mtts),
|
||||
&dma_handle);
|
||||
if (!ret) {
|
||||
ret = hns_roce_mtr_find(hr_dev, &hr_cq->mtr, 0, mtts, ARRAY_SIZE(mtts));
|
||||
if (ret) {
|
||||
ibdev_err(ibdev, "failed to find CQ mtr, ret = %d.\n", ret);
|
||||
return -EINVAL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Get CQC memory HEM(Hardware Entry Memory) table */
|
||||
@@ -157,7 +155,8 @@ static int alloc_cqc(struct hns_roce_dev *hr_dev, struct hns_roce_cq *hr_cq)
|
||||
goto err_put;
|
||||
}
|
||||
|
||||
ret = hns_roce_create_cqc(hr_dev, hr_cq, mtts, dma_handle);
|
||||
ret = hns_roce_create_cqc(hr_dev, hr_cq, mtts,
|
||||
hns_roce_get_mtr_ba(&hr_cq->mtr));
|
||||
if (ret)
|
||||
goto err_xa;
|
||||
|
||||
|
||||
@@ -882,8 +882,7 @@ struct hns_roce_hw {
|
||||
int (*rereg_write_mtpt)(struct hns_roce_dev *hr_dev,
|
||||
struct hns_roce_mr *mr, int flags,
|
||||
void *mb_buf);
|
||||
int (*frmr_write_mtpt)(struct hns_roce_dev *hr_dev, void *mb_buf,
|
||||
struct hns_roce_mr *mr);
|
||||
int (*frmr_write_mtpt)(void *mb_buf, struct hns_roce_mr *mr);
|
||||
int (*mw_write_mtpt)(void *mb_buf, struct hns_roce_mw *mw);
|
||||
void (*write_cqc)(struct hns_roce_dev *hr_dev,
|
||||
struct hns_roce_cq *hr_cq, void *mb_buf, u64 *mtts,
|
||||
@@ -1117,8 +1116,13 @@ void hns_roce_cmd_use_polling(struct hns_roce_dev *hr_dev);
|
||||
|
||||
/* hns roce hw need current block and next block addr from mtt */
|
||||
#define MTT_MIN_COUNT 2
|
||||
static inline dma_addr_t hns_roce_get_mtr_ba(struct hns_roce_mtr *mtr)
|
||||
{
|
||||
return mtr->hem_cfg.root_ba;
|
||||
}
|
||||
|
||||
int hns_roce_mtr_find(struct hns_roce_dev *hr_dev, struct hns_roce_mtr *mtr,
|
||||
u32 offset, u64 *mtt_buf, int mtt_max, u64 *base_addr);
|
||||
u32 offset, u64 *mtt_buf, int mtt_max);
|
||||
int hns_roce_mtr_create(struct hns_roce_dev *hr_dev, struct hns_roce_mtr *mtr,
|
||||
struct hns_roce_buf_attr *buf_attr,
|
||||
unsigned int page_shift, struct ib_udata *udata,
|
||||
@@ -1177,7 +1181,7 @@ struct hns_roce_buf *hns_roce_buf_alloc(struct hns_roce_dev *hr_dev, u32 size,
|
||||
int hns_roce_get_kmem_bufs(struct hns_roce_dev *hr_dev, dma_addr_t *bufs,
|
||||
int buf_cnt, struct hns_roce_buf *buf,
|
||||
unsigned int page_shift);
|
||||
int hns_roce_get_umem_bufs(struct hns_roce_dev *hr_dev, dma_addr_t *bufs,
|
||||
int hns_roce_get_umem_bufs(dma_addr_t *bufs,
|
||||
int buf_cnt, struct ib_umem *umem,
|
||||
unsigned int page_shift);
|
||||
|
||||
|
||||
@@ -986,6 +986,7 @@ struct hns_roce_hem_item {
|
||||
size_t count; /* max ba numbers */
|
||||
int start; /* start buf offset in this hem */
|
||||
int end; /* end buf offset in this hem */
|
||||
bool exist_bt;
|
||||
};
|
||||
|
||||
/* All HEM items are linked in a tree structure */
|
||||
@@ -1014,6 +1015,7 @@ hem_list_alloc_item(struct hns_roce_dev *hr_dev, int start, int end, int count,
|
||||
}
|
||||
}
|
||||
|
||||
hem->exist_bt = exist_bt;
|
||||
hem->count = count;
|
||||
hem->start = start;
|
||||
hem->end = end;
|
||||
@@ -1024,34 +1026,32 @@ hem_list_alloc_item(struct hns_roce_dev *hr_dev, int start, int end, int count,
|
||||
}
|
||||
|
||||
static void hem_list_free_item(struct hns_roce_dev *hr_dev,
|
||||
struct hns_roce_hem_item *hem, bool exist_bt)
|
||||
struct hns_roce_hem_item *hem)
|
||||
{
|
||||
if (exist_bt)
|
||||
if (hem->exist_bt)
|
||||
dma_free_coherent(hr_dev->dev, hem->count * BA_BYTE_LEN,
|
||||
hem->addr, hem->dma_addr);
|
||||
kfree(hem);
|
||||
}
|
||||
|
||||
static void hem_list_free_all(struct hns_roce_dev *hr_dev,
|
||||
struct list_head *head, bool exist_bt)
|
||||
struct list_head *head)
|
||||
{
|
||||
struct hns_roce_hem_item *hem, *temp_hem;
|
||||
|
||||
list_for_each_entry_safe(hem, temp_hem, head, list) {
|
||||
list_del(&hem->list);
|
||||
hem_list_free_item(hr_dev, hem, exist_bt);
|
||||
hem_list_free_item(hr_dev, hem);
|
||||
}
|
||||
}
|
||||
|
||||
static void hem_list_link_bt(struct hns_roce_dev *hr_dev, void *base_addr,
|
||||
u64 table_addr)
|
||||
static void hem_list_link_bt(void *base_addr, u64 table_addr)
|
||||
{
|
||||
*(u64 *)(base_addr) = table_addr;
|
||||
}
|
||||
|
||||
/* assign L0 table address to hem from root bt */
|
||||
static void hem_list_assign_bt(struct hns_roce_dev *hr_dev,
|
||||
struct hns_roce_hem_item *hem, void *cpu_addr,
|
||||
static void hem_list_assign_bt(struct hns_roce_hem_item *hem, void *cpu_addr,
|
||||
u64 phy_addr)
|
||||
{
|
||||
hem->addr = cpu_addr;
|
||||
@@ -1141,6 +1141,10 @@ int hns_roce_hem_list_calc_root_ba(const struct hns_roce_buf_region *regions,
|
||||
|
||||
for (i = 0; i < region_cnt; i++) {
|
||||
r = (struct hns_roce_buf_region *)®ions[i];
|
||||
/* when r->hopnum = 0, the region should not occupy root_ba. */
|
||||
if (!r->hopnum)
|
||||
continue;
|
||||
|
||||
if (r->hopnum > 1) {
|
||||
step = hem_list_calc_ba_range(r->hopnum, 1, unit);
|
||||
if (step > 0)
|
||||
@@ -1222,8 +1226,7 @@ static int hem_list_alloc_mid_bt(struct hns_roce_dev *hr_dev,
|
||||
if (level > 1) {
|
||||
pre = hem_ptrs[level - 1];
|
||||
step = (cur->start - pre->start) / step * BA_BYTE_LEN;
|
||||
hem_list_link_bt(hr_dev, pre->addr + step,
|
||||
cur->dma_addr);
|
||||
hem_list_link_bt(pre->addr + step, cur->dma_addr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1235,7 +1238,7 @@ static int hem_list_alloc_mid_bt(struct hns_roce_dev *hr_dev,
|
||||
|
||||
err_exit:
|
||||
for (level = 1; level < hopnum; level++)
|
||||
hem_list_free_all(hr_dev, &temp_list[level], true);
|
||||
hem_list_free_all(hr_dev, &temp_list[level]);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -1276,16 +1279,26 @@ static int alloc_fake_root_bt(struct hns_roce_dev *hr_dev, void *cpu_base,
|
||||
{
|
||||
struct hns_roce_hem_item *hem;
|
||||
|
||||
/* This is on the has_mtt branch, if r->hopnum
|
||||
* is 0, there is no root_ba to reuse for the
|
||||
* region's fake hem, so a dma_alloc request is
|
||||
* necessary here.
|
||||
*/
|
||||
hem = hem_list_alloc_item(hr_dev, r->offset, r->offset + r->count - 1,
|
||||
r->count, false);
|
||||
r->count, !r->hopnum);
|
||||
if (!hem)
|
||||
return -ENOMEM;
|
||||
|
||||
hem_list_assign_bt(hr_dev, hem, cpu_base, phy_base);
|
||||
/* The root_ba can be reused only when r->hopnum > 0. */
|
||||
if (r->hopnum)
|
||||
hem_list_assign_bt(hem, cpu_base, phy_base);
|
||||
list_add(&hem->list, branch_head);
|
||||
list_add(&hem->sibling, leaf_head);
|
||||
|
||||
return r->count;
|
||||
/* If r->hopnum == 0, 0 is returned,
|
||||
* so that the root_bt entry is not occupied.
|
||||
*/
|
||||
return r->hopnum ? r->count : 0;
|
||||
}
|
||||
|
||||
static int setup_middle_bt(struct hns_roce_dev *hr_dev, void *cpu_base,
|
||||
@@ -1304,7 +1317,7 @@ static int setup_middle_bt(struct hns_roce_dev *hr_dev, void *cpu_base,
|
||||
/* if exist mid bt, link L1 to L0 */
|
||||
list_for_each_entry_safe(hem, temp_hem, branch_head, list) {
|
||||
offset = (hem->start - r->offset) / step * BA_BYTE_LEN;
|
||||
hem_list_link_bt(hr_dev, cpu_base + offset, hem->dma_addr);
|
||||
hem_list_link_bt(cpu_base + offset, hem->dma_addr);
|
||||
total++;
|
||||
}
|
||||
|
||||
@@ -1329,7 +1342,7 @@ setup_root_hem(struct hns_roce_dev *hr_dev, struct hns_roce_hem_list *hem_list,
|
||||
return -ENOMEM;
|
||||
|
||||
total = 0;
|
||||
for (i = 0; i < region_cnt && total < max_ba_num; i++) {
|
||||
for (i = 0; i < region_cnt && total <= max_ba_num; i++) {
|
||||
r = ®ions[i];
|
||||
if (!r->count)
|
||||
continue;
|
||||
@@ -1395,9 +1408,9 @@ static int hem_list_alloc_root_bt(struct hns_roce_dev *hr_dev,
|
||||
region_cnt);
|
||||
if (ret) {
|
||||
for (i = 0; i < region_cnt; i++)
|
||||
hem_list_free_all(hr_dev, &head.branch[i], false);
|
||||
hem_list_free_all(hr_dev, &head.branch[i]);
|
||||
|
||||
hem_list_free_all(hr_dev, &head.root, true);
|
||||
hem_list_free_all(hr_dev, &head.root);
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -1460,10 +1473,9 @@ void hns_roce_hem_list_release(struct hns_roce_dev *hr_dev,
|
||||
|
||||
for (i = 0; i < HNS_ROCE_MAX_BT_REGION; i++)
|
||||
for (j = 0; j < HNS_ROCE_MAX_BT_LEVEL; j++)
|
||||
hem_list_free_all(hr_dev, &hem_list->mid_bt[i][j],
|
||||
j != 0);
|
||||
hem_list_free_all(hr_dev, &hem_list->mid_bt[i][j]);
|
||||
|
||||
hem_list_free_all(hr_dev, &hem_list->root_bt, true);
|
||||
hem_list_free_all(hr_dev, &hem_list->root_bt);
|
||||
INIT_LIST_HEAD(&hem_list->btm_bt);
|
||||
hem_list->root_ba = 0;
|
||||
}
|
||||
|
||||
@@ -471,7 +471,7 @@ static inline int set_ud_wqe(struct hns_roce_qp *qp,
|
||||
valid_num_sge = calc_wr_sge_num(wr, &msg_len);
|
||||
|
||||
ret = set_ud_opcode(ud_sq_wqe, wr);
|
||||
if (WARN_ON(ret))
|
||||
if (WARN_ON_ONCE(ret))
|
||||
return ret;
|
||||
|
||||
ud_sq_wqe->msg_len = cpu_to_le32(msg_len);
|
||||
@@ -575,7 +575,7 @@ static inline int set_rc_wqe(struct hns_roce_qp *qp,
|
||||
rc_sq_wqe->msg_len = cpu_to_le32(msg_len);
|
||||
|
||||
ret = set_rc_opcode(hr_dev, rc_sq_wqe, wr);
|
||||
if (WARN_ON(ret))
|
||||
if (WARN_ON_ONCE(ret))
|
||||
return ret;
|
||||
|
||||
hr_reg_write(rc_sq_wqe, RC_SEND_WQE_SO,
|
||||
@@ -673,6 +673,10 @@ static void write_dwqe(struct hns_roce_dev *hr_dev, struct hns_roce_qp *qp,
|
||||
#define HNS_ROCE_SL_SHIFT 2
|
||||
struct hns_roce_v2_rc_send_wqe *rc_sq_wqe = wqe;
|
||||
|
||||
if (unlikely(qp->state == IB_QPS_ERR)) {
|
||||
flush_cqe(hr_dev, qp);
|
||||
return;
|
||||
}
|
||||
/* All kinds of DirectWQE have the same header field layout */
|
||||
hr_reg_enable(rc_sq_wqe, RC_SEND_WQE_FLAG);
|
||||
hr_reg_write(rc_sq_wqe, RC_SEND_WQE_DB_SL_L, qp->sl);
|
||||
@@ -3289,21 +3293,22 @@ static int set_mtpt_pbl(struct hns_roce_dev *hr_dev,
|
||||
u64 pages[HNS_ROCE_V2_MAX_INNER_MTPT_NUM] = { 0 };
|
||||
struct ib_device *ibdev = &hr_dev->ib_dev;
|
||||
dma_addr_t pbl_ba;
|
||||
int i, count;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
count = hns_roce_mtr_find(hr_dev, &mr->pbl_mtr, 0, pages,
|
||||
min_t(int, ARRAY_SIZE(pages), mr->npages),
|
||||
&pbl_ba);
|
||||
if (count < 1) {
|
||||
ibdev_err(ibdev, "failed to find PBL mtr, count = %d.\n",
|
||||
count);
|
||||
return -ENOBUFS;
|
||||
ret = hns_roce_mtr_find(hr_dev, &mr->pbl_mtr, 0, pages,
|
||||
min_t(int, ARRAY_SIZE(pages), mr->npages));
|
||||
if (ret) {
|
||||
ibdev_err(ibdev, "failed to find PBL mtr, ret = %d.\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Aligned to the hardware address access unit */
|
||||
for (i = 0; i < count; i++)
|
||||
for (i = 0; i < ARRAY_SIZE(pages); i++)
|
||||
pages[i] >>= 6;
|
||||
|
||||
pbl_ba = hns_roce_get_mtr_ba(&mr->pbl_mtr);
|
||||
|
||||
mpt_entry->pbl_size = cpu_to_le32(mr->npages);
|
||||
mpt_entry->pbl_ba_l = cpu_to_le32(pbl_ba >> 3);
|
||||
hr_reg_write(mpt_entry, MPT_PBL_BA_H, upper_32_bits(pbl_ba >> 3));
|
||||
@@ -3399,21 +3404,14 @@ static int hns_roce_v2_rereg_write_mtpt(struct hns_roce_dev *hr_dev,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int hns_roce_v2_frmr_write_mtpt(struct hns_roce_dev *hr_dev,
|
||||
void *mb_buf, struct hns_roce_mr *mr)
|
||||
static int hns_roce_v2_frmr_write_mtpt(void *mb_buf, struct hns_roce_mr *mr)
|
||||
{
|
||||
struct ib_device *ibdev = &hr_dev->ib_dev;
|
||||
dma_addr_t pbl_ba = hns_roce_get_mtr_ba(&mr->pbl_mtr);
|
||||
struct hns_roce_v2_mpt_entry *mpt_entry;
|
||||
dma_addr_t pbl_ba = 0;
|
||||
|
||||
mpt_entry = mb_buf;
|
||||
memset(mpt_entry, 0, sizeof(*mpt_entry));
|
||||
|
||||
if (hns_roce_mtr_find(hr_dev, &mr->pbl_mtr, 0, NULL, 0, &pbl_ba) < 0) {
|
||||
ibdev_err(ibdev, "failed to find frmr mtr.\n");
|
||||
return -ENOBUFS;
|
||||
}
|
||||
|
||||
hr_reg_write(mpt_entry, MPT_ST, V2_MPT_ST_FREE);
|
||||
hr_reg_write(mpt_entry, MPT_PD, mr->pd);
|
||||
|
||||
@@ -4372,8 +4370,7 @@ static void set_access_flags(struct hns_roce_qp *hr_qp,
|
||||
}
|
||||
|
||||
static void set_qpc_wqe_cnt(struct hns_roce_qp *hr_qp,
|
||||
struct hns_roce_v2_qp_context *context,
|
||||
struct hns_roce_v2_qp_context *qpc_mask)
|
||||
struct hns_roce_v2_qp_context *context)
|
||||
{
|
||||
hr_reg_write(context, QPC_SGE_SHIFT,
|
||||
to_hr_hem_entries_shift(hr_qp->sge.sge_cnt,
|
||||
@@ -4395,7 +4392,6 @@ static inline int get_pdn(struct ib_pd *ib_pd)
|
||||
}
|
||||
|
||||
static void modify_qp_reset_to_init(struct ib_qp *ibqp,
|
||||
const struct ib_qp_attr *attr,
|
||||
struct hns_roce_v2_qp_context *context,
|
||||
struct hns_roce_v2_qp_context *qpc_mask)
|
||||
{
|
||||
@@ -4414,7 +4410,7 @@ static void modify_qp_reset_to_init(struct ib_qp *ibqp,
|
||||
|
||||
hr_reg_write(context, QPC_RQWS, ilog2(hr_qp->rq.max_gs));
|
||||
|
||||
set_qpc_wqe_cnt(hr_qp, context, qpc_mask);
|
||||
set_qpc_wqe_cnt(hr_qp, context);
|
||||
|
||||
/* No VLAN need to set 0xFFF */
|
||||
hr_reg_write(context, QPC_VLAN_ID, 0xfff);
|
||||
@@ -4459,7 +4455,6 @@ static void modify_qp_reset_to_init(struct ib_qp *ibqp,
|
||||
}
|
||||
|
||||
static void modify_qp_init_to_init(struct ib_qp *ibqp,
|
||||
const struct ib_qp_attr *attr,
|
||||
struct hns_roce_v2_qp_context *context,
|
||||
struct hns_roce_v2_qp_context *qpc_mask)
|
||||
{
|
||||
@@ -4496,17 +4491,20 @@ static int config_qp_rq_buf(struct hns_roce_dev *hr_dev,
|
||||
{
|
||||
u64 mtts[MTT_MIN_COUNT] = { 0 };
|
||||
u64 wqe_sge_ba;
|
||||
int count;
|
||||
int ret;
|
||||
|
||||
/* Search qp buf's mtts */
|
||||
count = hns_roce_mtr_find(hr_dev, &hr_qp->mtr, hr_qp->rq.offset, mtts,
|
||||
MTT_MIN_COUNT, &wqe_sge_ba);
|
||||
if (hr_qp->rq.wqe_cnt && count < 1) {
|
||||
ret = hns_roce_mtr_find(hr_dev, &hr_qp->mtr, hr_qp->rq.offset, mtts,
|
||||
MTT_MIN_COUNT);
|
||||
if (hr_qp->rq.wqe_cnt && ret) {
|
||||
ibdev_err(&hr_dev->ib_dev,
|
||||
"failed to find RQ WQE, QPN = 0x%lx.\n", hr_qp->qpn);
|
||||
return -EINVAL;
|
||||
"failed to find QP(0x%lx) RQ WQE buf, ret = %d.\n",
|
||||
hr_qp->qpn, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
wqe_sge_ba = hns_roce_get_mtr_ba(&hr_qp->mtr);
|
||||
|
||||
context->wqe_sge_ba = cpu_to_le32(wqe_sge_ba >> 3);
|
||||
qpc_mask->wqe_sge_ba = 0;
|
||||
|
||||
@@ -4570,23 +4568,23 @@ static int config_qp_sq_buf(struct hns_roce_dev *hr_dev,
|
||||
struct ib_device *ibdev = &hr_dev->ib_dev;
|
||||
u64 sge_cur_blk = 0;
|
||||
u64 sq_cur_blk = 0;
|
||||
int count;
|
||||
int ret;
|
||||
|
||||
/* search qp buf's mtts */
|
||||
count = hns_roce_mtr_find(hr_dev, &hr_qp->mtr, 0, &sq_cur_blk, 1, NULL);
|
||||
if (count < 1) {
|
||||
ibdev_err(ibdev, "failed to find QP(0x%lx) SQ buf.\n",
|
||||
hr_qp->qpn);
|
||||
return -EINVAL;
|
||||
ret = hns_roce_mtr_find(hr_dev, &hr_qp->mtr, hr_qp->sq.offset,
|
||||
&sq_cur_blk, 1);
|
||||
if (ret) {
|
||||
ibdev_err(ibdev, "failed to find QP(0x%lx) SQ WQE buf, ret = %d.\n",
|
||||
hr_qp->qpn, ret);
|
||||
return ret;
|
||||
}
|
||||
if (hr_qp->sge.sge_cnt > 0) {
|
||||
count = hns_roce_mtr_find(hr_dev, &hr_qp->mtr,
|
||||
hr_qp->sge.offset,
|
||||
&sge_cur_blk, 1, NULL);
|
||||
if (count < 1) {
|
||||
ibdev_err(ibdev, "failed to find QP(0x%lx) SGE buf.\n",
|
||||
hr_qp->qpn);
|
||||
return -EINVAL;
|
||||
ret = hns_roce_mtr_find(hr_dev, &hr_qp->mtr,
|
||||
hr_qp->sge.offset, &sge_cur_blk, 1);
|
||||
if (ret) {
|
||||
ibdev_err(ibdev, "failed to find QP(0x%lx) SGE buf, ret = %d.\n",
|
||||
hr_qp->qpn, ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4754,8 +4752,7 @@ static int modify_qp_init_to_rtr(struct ib_qp *ibqp,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int modify_qp_rtr_to_rts(struct ib_qp *ibqp,
|
||||
const struct ib_qp_attr *attr, int attr_mask,
|
||||
static int modify_qp_rtr_to_rts(struct ib_qp *ibqp, int attr_mask,
|
||||
struct hns_roce_v2_qp_context *context,
|
||||
struct hns_roce_v2_qp_context *qpc_mask)
|
||||
{
|
||||
@@ -5123,15 +5120,14 @@ static int hns_roce_v2_set_abs_fields(struct ib_qp *ibqp,
|
||||
|
||||
if (cur_state == IB_QPS_RESET && new_state == IB_QPS_INIT) {
|
||||
memset(qpc_mask, 0, hr_dev->caps.qpc_sz);
|
||||
modify_qp_reset_to_init(ibqp, attr, context, qpc_mask);
|
||||
modify_qp_reset_to_init(ibqp, context, qpc_mask);
|
||||
} else if (cur_state == IB_QPS_INIT && new_state == IB_QPS_INIT) {
|
||||
modify_qp_init_to_init(ibqp, attr, context, qpc_mask);
|
||||
modify_qp_init_to_init(ibqp, context, qpc_mask);
|
||||
} else if (cur_state == IB_QPS_INIT && new_state == IB_QPS_RTR) {
|
||||
ret = modify_qp_init_to_rtr(ibqp, attr, attr_mask, context,
|
||||
qpc_mask);
|
||||
} else if (cur_state == IB_QPS_RTR && new_state == IB_QPS_RTS) {
|
||||
ret = modify_qp_rtr_to_rts(ibqp, attr, attr_mask, context,
|
||||
qpc_mask);
|
||||
ret = modify_qp_rtr_to_rts(ibqp, attr_mask, context, qpc_mask);
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -5689,18 +5685,20 @@ static int hns_roce_v2_write_srqc_index_queue(struct hns_roce_srq *srq,
|
||||
struct ib_device *ibdev = srq->ibsrq.device;
|
||||
struct hns_roce_dev *hr_dev = to_hr_dev(ibdev);
|
||||
u64 mtts_idx[MTT_MIN_COUNT] = {};
|
||||
dma_addr_t dma_handle_idx = 0;
|
||||
dma_addr_t dma_handle_idx;
|
||||
int ret;
|
||||
|
||||
/* Get physical address of idx que buf */
|
||||
ret = hns_roce_mtr_find(hr_dev, &idx_que->mtr, 0, mtts_idx,
|
||||
ARRAY_SIZE(mtts_idx), &dma_handle_idx);
|
||||
if (ret < 1) {
|
||||
ARRAY_SIZE(mtts_idx));
|
||||
if (ret) {
|
||||
ibdev_err(ibdev, "failed to find mtr for SRQ idx, ret = %d.\n",
|
||||
ret);
|
||||
return -ENOBUFS;
|
||||
return ret;
|
||||
}
|
||||
|
||||
dma_handle_idx = hns_roce_get_mtr_ba(&idx_que->mtr);
|
||||
|
||||
hr_reg_write(ctx, SRQC_IDX_HOP_NUM,
|
||||
to_hr_hem_hopnum(hr_dev->caps.idx_hop_num, srq->wqe_cnt));
|
||||
|
||||
@@ -5732,20 +5730,22 @@ static int hns_roce_v2_write_srqc(struct hns_roce_srq *srq, void *mb_buf)
|
||||
struct hns_roce_dev *hr_dev = to_hr_dev(ibdev);
|
||||
struct hns_roce_srq_context *ctx = mb_buf;
|
||||
u64 mtts_wqe[MTT_MIN_COUNT] = {};
|
||||
dma_addr_t dma_handle_wqe = 0;
|
||||
dma_addr_t dma_handle_wqe;
|
||||
int ret;
|
||||
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
|
||||
/* Get the physical address of srq buf */
|
||||
ret = hns_roce_mtr_find(hr_dev, &srq->buf_mtr, 0, mtts_wqe,
|
||||
ARRAY_SIZE(mtts_wqe), &dma_handle_wqe);
|
||||
if (ret < 1) {
|
||||
ARRAY_SIZE(mtts_wqe));
|
||||
if (ret) {
|
||||
ibdev_err(ibdev, "failed to find mtr for SRQ WQE, ret = %d.\n",
|
||||
ret);
|
||||
return -ENOBUFS;
|
||||
return ret;
|
||||
}
|
||||
|
||||
dma_handle_wqe = hns_roce_get_mtr_ba(&srq->buf_mtr);
|
||||
|
||||
hr_reg_write(ctx, SRQC_SRQ_ST, 1);
|
||||
hr_reg_write_bool(ctx, SRQC_SRQ_TYPE,
|
||||
srq->ibsrq.srq_type == IB_SRQT_XRC);
|
||||
@@ -6466,7 +6466,7 @@ static int config_eqc(struct hns_roce_dev *hr_dev, struct hns_roce_eq *eq,
|
||||
u64 eqe_ba[MTT_MIN_COUNT] = { 0 };
|
||||
struct hns_roce_eq_context *eqc;
|
||||
u64 bt_ba = 0;
|
||||
int count;
|
||||
int ret;
|
||||
|
||||
eqc = mb_buf;
|
||||
memset(eqc, 0, sizeof(struct hns_roce_eq_context));
|
||||
@@ -6474,13 +6474,15 @@ static int config_eqc(struct hns_roce_dev *hr_dev, struct hns_roce_eq *eq,
|
||||
init_eq_config(hr_dev, eq);
|
||||
|
||||
/* if not multi-hop, eqe buffer only use one trunk */
|
||||
count = hns_roce_mtr_find(hr_dev, &eq->mtr, 0, eqe_ba, MTT_MIN_COUNT,
|
||||
&bt_ba);
|
||||
if (count < 1) {
|
||||
dev_err(hr_dev->dev, "failed to find EQE mtr\n");
|
||||
return -ENOBUFS;
|
||||
ret = hns_roce_mtr_find(hr_dev, &eq->mtr, 0, eqe_ba,
|
||||
ARRAY_SIZE(eqe_ba));
|
||||
if (ret) {
|
||||
dev_err(hr_dev->dev, "failed to find EQE mtr, ret = %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bt_ba = hns_roce_get_mtr_ba(&eq->mtr);
|
||||
|
||||
hr_reg_write(eqc, EQC_EQ_ST, HNS_ROCE_V2_EQ_STATE_VALID);
|
||||
hr_reg_write(eqc, EQC_EQE_HOP_NUM, eq->hop_num);
|
||||
hr_reg_write(eqc, EQC_OVER_IGNORE, eq->over_ignore);
|
||||
|
||||
@@ -154,7 +154,7 @@ static int hns_roce_mr_enable(struct hns_roce_dev *hr_dev,
|
||||
if (mr->type != MR_TYPE_FRMR)
|
||||
ret = hr_dev->hw->write_mtpt(hr_dev, mailbox->buf, mr);
|
||||
else
|
||||
ret = hr_dev->hw->frmr_write_mtpt(hr_dev, mailbox->buf, mr);
|
||||
ret = hr_dev->hw->frmr_write_mtpt(mailbox->buf, mr);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to write mtpt, ret = %d.\n", ret);
|
||||
goto err_page;
|
||||
@@ -714,7 +714,7 @@ static int mtr_map_bufs(struct hns_roce_dev *hr_dev, struct hns_roce_mtr *mtr,
|
||||
return -ENOMEM;
|
||||
|
||||
if (mtr->umem)
|
||||
npage = hns_roce_get_umem_bufs(hr_dev, pages, page_count,
|
||||
npage = hns_roce_get_umem_bufs(pages, page_count,
|
||||
mtr->umem, page_shift);
|
||||
else
|
||||
npage = hns_roce_get_kmem_bufs(hr_dev, pages, page_count,
|
||||
@@ -767,11 +767,6 @@ int hns_roce_mtr_map(struct hns_roce_dev *hr_dev, struct hns_roce_mtr *mtr,
|
||||
for (i = 0, mapped_cnt = 0; i < mtr->hem_cfg.region_count &&
|
||||
mapped_cnt < page_cnt; i++) {
|
||||
r = &mtr->hem_cfg.region[i];
|
||||
/* if hopnum is 0, no need to map pages in this region */
|
||||
if (!r->hopnum) {
|
||||
mapped_cnt += r->count;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (r->offset + r->count > page_cnt) {
|
||||
ret = -EINVAL;
|
||||
@@ -802,47 +797,53 @@ int hns_roce_mtr_map(struct hns_roce_dev *hr_dev, struct hns_roce_mtr *mtr,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int hns_roce_mtr_find(struct hns_roce_dev *hr_dev, struct hns_roce_mtr *mtr,
|
||||
u32 offset, u64 *mtt_buf, int mtt_max, u64 *base_addr)
|
||||
static int hns_roce_get_direct_addr_mtt(struct hns_roce_hem_cfg *cfg,
|
||||
u32 start_index, u64 *mtt_buf,
|
||||
int mtt_cnt)
|
||||
{
|
||||
struct hns_roce_hem_cfg *cfg = &mtr->hem_cfg;
|
||||
int mtt_count, left;
|
||||
u32 start_index;
|
||||
int mtt_count;
|
||||
int total = 0;
|
||||
__le64 *mtts;
|
||||
u32 npage;
|
||||
u64 addr;
|
||||
|
||||
if (!mtt_buf || mtt_max < 1)
|
||||
goto done;
|
||||
if (mtt_cnt > cfg->region_count)
|
||||
return -EINVAL;
|
||||
|
||||
/* no mtt memory in direct mode, so just return the buffer address */
|
||||
if (cfg->is_direct) {
|
||||
start_index = offset >> HNS_HW_PAGE_SHIFT;
|
||||
for (mtt_count = 0; mtt_count < cfg->region_count &&
|
||||
total < mtt_max; mtt_count++) {
|
||||
npage = cfg->region[mtt_count].offset;
|
||||
if (npage < start_index)
|
||||
continue;
|
||||
for (mtt_count = 0; mtt_count < cfg->region_count && total < mtt_cnt;
|
||||
mtt_count++) {
|
||||
npage = cfg->region[mtt_count].offset;
|
||||
if (npage < start_index)
|
||||
continue;
|
||||
|
||||
addr = cfg->root_ba + (npage << HNS_HW_PAGE_SHIFT);
|
||||
mtt_buf[total] = addr;
|
||||
addr = cfg->root_ba + (npage << HNS_HW_PAGE_SHIFT);
|
||||
mtt_buf[total] = addr;
|
||||
|
||||
total++;
|
||||
}
|
||||
|
||||
goto done;
|
||||
total++;
|
||||
}
|
||||
|
||||
start_index = offset >> cfg->buf_pg_shift;
|
||||
left = mtt_max;
|
||||
if (!total)
|
||||
return -ENOENT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hns_roce_get_mhop_mtt(struct hns_roce_dev *hr_dev,
|
||||
struct hns_roce_mtr *mtr, u32 start_index,
|
||||
u64 *mtt_buf, int mtt_cnt)
|
||||
{
|
||||
int left = mtt_cnt;
|
||||
int total = 0;
|
||||
int mtt_count;
|
||||
__le64 *mtts;
|
||||
u32 npage;
|
||||
|
||||
while (left > 0) {
|
||||
mtt_count = 0;
|
||||
mtts = hns_roce_hem_list_find_mtt(hr_dev, &mtr->hem_list,
|
||||
start_index + total,
|
||||
&mtt_count);
|
||||
if (!mtts || !mtt_count)
|
||||
goto done;
|
||||
break;
|
||||
|
||||
npage = min(mtt_count, left);
|
||||
left -= npage;
|
||||
@@ -850,11 +851,33 @@ int hns_roce_mtr_find(struct hns_roce_dev *hr_dev, struct hns_roce_mtr *mtr,
|
||||
mtt_buf[total++] = le64_to_cpu(mtts[mtt_count]);
|
||||
}
|
||||
|
||||
done:
|
||||
if (base_addr)
|
||||
*base_addr = cfg->root_ba;
|
||||
if (!total)
|
||||
return -ENOENT;
|
||||
|
||||
return total;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int hns_roce_mtr_find(struct hns_roce_dev *hr_dev, struct hns_roce_mtr *mtr,
|
||||
u32 offset, u64 *mtt_buf, int mtt_max)
|
||||
{
|
||||
struct hns_roce_hem_cfg *cfg = &mtr->hem_cfg;
|
||||
u32 start_index;
|
||||
int ret;
|
||||
|
||||
if (!mtt_buf || mtt_max < 1)
|
||||
return -EINVAL;
|
||||
|
||||
/* no mtt memory in direct mode, so just return the buffer address */
|
||||
if (cfg->is_direct) {
|
||||
start_index = offset >> HNS_HW_PAGE_SHIFT;
|
||||
ret = hns_roce_get_direct_addr_mtt(cfg, start_index,
|
||||
mtt_buf, mtt_max);
|
||||
} else {
|
||||
start_index = offset >> cfg->buf_pg_shift;
|
||||
ret = hns_roce_get_mhop_mtt(hr_dev, mtr, start_index,
|
||||
mtt_buf, mtt_max);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mtr_init_buf_cfg(struct hns_roce_dev *hr_dev,
|
||||
|
||||
@@ -1139,7 +1139,6 @@ static int set_qp_param(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp,
|
||||
}
|
||||
|
||||
static int hns_roce_create_qp_common(struct hns_roce_dev *hr_dev,
|
||||
struct ib_pd *ib_pd,
|
||||
struct ib_qp_init_attr *init_attr,
|
||||
struct ib_udata *udata,
|
||||
struct hns_roce_qp *hr_qp)
|
||||
@@ -1293,7 +1292,6 @@ int hns_roce_create_qp(struct ib_qp *qp, struct ib_qp_init_attr *init_attr,
|
||||
struct ib_device *ibdev = qp->device;
|
||||
struct hns_roce_dev *hr_dev = to_hr_dev(ibdev);
|
||||
struct hns_roce_qp *hr_qp = to_hr_qp(qp);
|
||||
struct ib_pd *pd = qp->pd;
|
||||
int ret;
|
||||
|
||||
ret = check_qp_type(hr_dev, init_attr->qp_type, !!udata);
|
||||
@@ -1308,7 +1306,7 @@ int hns_roce_create_qp(struct ib_qp *qp, struct ib_qp_init_attr *init_attr,
|
||||
hr_qp->phy_port = hr_dev->iboe.phy_port[hr_qp->port];
|
||||
}
|
||||
|
||||
ret = hns_roce_create_qp_common(hr_dev, pd, init_attr, udata, hr_qp);
|
||||
ret = hns_roce_create_qp_common(hr_dev, init_attr, udata, hr_qp);
|
||||
if (ret)
|
||||
ibdev_err(ibdev, "create QP type 0x%x failed(%d)\n",
|
||||
init_attr->qp_type, ret);
|
||||
|
||||
@@ -249,7 +249,7 @@ static void free_srq_wqe_buf(struct hns_roce_dev *hr_dev,
|
||||
hns_roce_mtr_destroy(hr_dev, &srq->buf_mtr);
|
||||
}
|
||||
|
||||
static int alloc_srq_wrid(struct hns_roce_dev *hr_dev, struct hns_roce_srq *srq)
|
||||
static int alloc_srq_wrid(struct hns_roce_srq *srq)
|
||||
{
|
||||
srq->wrid = kvmalloc_array(srq->wqe_cnt, sizeof(u64), GFP_KERNEL);
|
||||
if (!srq->wrid)
|
||||
@@ -365,7 +365,7 @@ static int alloc_srq_buf(struct hns_roce_dev *hr_dev, struct hns_roce_srq *srq,
|
||||
goto err_idx;
|
||||
|
||||
if (!udata) {
|
||||
ret = alloc_srq_wrid(hr_dev, srq);
|
||||
ret = alloc_srq_wrid(srq);
|
||||
if (ret)
|
||||
goto err_wqe_buf;
|
||||
}
|
||||
|
||||
@@ -3265,7 +3265,8 @@ static int mlx5_ib_init_multiport_master(struct mlx5_ib_dev *dev)
|
||||
list_for_each_entry(mpi, &mlx5_ib_unaffiliated_port_list,
|
||||
list) {
|
||||
if (dev->sys_image_guid == mpi->sys_image_guid &&
|
||||
(mlx5_core_native_port_num(mpi->mdev) - 1) == i) {
|
||||
(mlx5_core_native_port_num(mpi->mdev) - 1) == i &&
|
||||
mlx5_core_same_coredev_type(dev->mdev, mpi->mdev)) {
|
||||
bound = mlx5_ib_bind_slave_port(dev, mpi);
|
||||
}
|
||||
|
||||
@@ -4280,7 +4281,8 @@ static int mlx5r_mp_probe(struct auxiliary_device *adev,
|
||||
|
||||
mutex_lock(&mlx5_ib_multiport_mutex);
|
||||
list_for_each_entry(dev, &mlx5_ib_dev_list, ib_dev_list) {
|
||||
if (dev->sys_image_guid == mpi->sys_image_guid)
|
||||
if (dev->sys_image_guid == mpi->sys_image_guid &&
|
||||
mlx5_core_same_coredev_type(dev->mdev, mpi->mdev))
|
||||
bound = mlx5_ib_bind_slave_port(dev, mpi);
|
||||
|
||||
if (bound) {
|
||||
|
||||
@@ -344,6 +344,7 @@ static int send_io_resp_imm(struct rtrs_srv_con *con, struct rtrs_srv_op *id,
|
||||
struct rtrs_srv_mr *srv_mr;
|
||||
bool need_inval = false;
|
||||
enum ib_send_flags flags;
|
||||
struct ib_sge list;
|
||||
u32 imm;
|
||||
int err;
|
||||
|
||||
@@ -396,7 +397,6 @@ static int send_io_resp_imm(struct rtrs_srv_con *con, struct rtrs_srv_op *id,
|
||||
imm = rtrs_to_io_rsp_imm(id->msg_id, errno, need_inval);
|
||||
imm_wr.wr.next = NULL;
|
||||
if (always_invalidate) {
|
||||
struct ib_sge list;
|
||||
struct rtrs_msg_rkey_rsp *msg;
|
||||
|
||||
srv_mr = &srv_path->mrs[id->msg_id];
|
||||
|
||||
@@ -64,7 +64,7 @@ static void gic_check_cpu_features(void)
|
||||
|
||||
union gic_base {
|
||||
void __iomem *common_base;
|
||||
void __percpu * __iomem *percpu_base;
|
||||
void __iomem * __percpu *percpu_base;
|
||||
};
|
||||
|
||||
struct gic_chip_data {
|
||||
|
||||
@@ -51,7 +51,7 @@ MODULE_PARM_DESC(debug, "set debugging level (1=info,2=xfer,4=setfe,8=getfe (|-a
|
||||
static int dib3000_read_reg(struct dib3000_state *state, u16 reg)
|
||||
{
|
||||
u8 wb[] = { ((reg >> 8) | 0x80) & 0xff, reg & 0xff };
|
||||
u8 rb[2];
|
||||
u8 rb[2] = {};
|
||||
struct i2c_msg msg[] = {
|
||||
{ .addr = state->config.demod_address, .flags = 0, .buf = wb, .len = 2 },
|
||||
{ .addr = state->config.demod_address, .flags = I2C_M_RD, .buf = rb, .len = 2 },
|
||||
|
||||
@@ -1520,7 +1520,6 @@ static const struct sdhci_pltfm_data sdhci_tegra186_pdata = {
|
||||
.quirks = SDHCI_QUIRK_BROKEN_TIMEOUT_VAL |
|
||||
SDHCI_QUIRK_SINGLE_POWER_WRITE |
|
||||
SDHCI_QUIRK_NO_HISPD_BIT |
|
||||
SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC |
|
||||
SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN,
|
||||
.quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN |
|
||||
SDHCI_QUIRK2_ISSUE_CMD_DAT_RESET_TOGETHER,
|
||||
|
||||
@@ -1425,8 +1425,8 @@ static int anfc_parse_cs(struct arasan_nfc *nfc)
|
||||
* case, the "not" chosen CS is assigned to nfc->spare_cs and selected
|
||||
* whenever a GPIO CS must be asserted.
|
||||
*/
|
||||
if (nfc->cs_array && nfc->ncs > 2) {
|
||||
if (!nfc->cs_array[0] && !nfc->cs_array[1]) {
|
||||
if (nfc->cs_array) {
|
||||
if (nfc->ncs > 2 && !nfc->cs_array[0] && !nfc->cs_array[1]) {
|
||||
dev_err(nfc->dev,
|
||||
"Assign a single native CS when using GPIOs\n");
|
||||
return -EINVAL;
|
||||
@@ -1510,8 +1510,15 @@ disable_controller_clk:
|
||||
|
||||
static int anfc_remove(struct platform_device *pdev)
|
||||
{
|
||||
int i;
|
||||
struct arasan_nfc *nfc = platform_get_drvdata(pdev);
|
||||
|
||||
for (i = 0; i < nfc->ncs; i++) {
|
||||
if (nfc->cs_array[i]) {
|
||||
gpiod_put(nfc->cs_array[i]);
|
||||
}
|
||||
}
|
||||
|
||||
anfc_chips_cleanup(nfc);
|
||||
|
||||
clk_disable_unprepare(nfc->bus_clk);
|
||||
|
||||
@@ -380,10 +380,8 @@ atmel_pmecc_create_user(struct atmel_pmecc *pmecc,
|
||||
user->delta = user->dmu + req->ecc.strength + 1;
|
||||
|
||||
gf_tables = atmel_pmecc_get_gf_tables(req);
|
||||
if (IS_ERR(gf_tables)) {
|
||||
kfree(user);
|
||||
if (IS_ERR(gf_tables))
|
||||
return ERR_CAST(gf_tables);
|
||||
}
|
||||
|
||||
user->gf_tables = gf_tables;
|
||||
|
||||
|
||||
@@ -1098,7 +1098,7 @@ static inline int __init inftl_partscan(struct mtd_info *mtd, struct mtd_partiti
|
||||
(i == 0) && (ip->firstUnit > 0)) {
|
||||
parts[0].name = " DiskOnChip IPL / Media Header partition";
|
||||
parts[0].offset = 0;
|
||||
parts[0].size = mtd->erasesize * ip->firstUnit;
|
||||
parts[0].size = (uint64_t)mtd->erasesize * ip->firstUnit;
|
||||
numparts = 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
/*
|
||||
* Microchip KSZ9477 switch driver main logic
|
||||
*
|
||||
* Copyright (C) 2017-2019 Microchip Technology Inc.
|
||||
* Copyright (C) 2017-2024 Microchip Technology Inc.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
@@ -964,26 +964,51 @@ void ksz9477_get_caps(struct ksz_device *dev, int port,
|
||||
int ksz9477_set_ageing_time(struct ksz_device *dev, unsigned int msecs)
|
||||
{
|
||||
u32 secs = msecs / 1000;
|
||||
u8 value;
|
||||
u8 data;
|
||||
u8 data, mult, value;
|
||||
u32 max_val;
|
||||
int ret;
|
||||
|
||||
value = FIELD_GET(SW_AGE_PERIOD_7_0_M, secs);
|
||||
#define MAX_TIMER_VAL ((1 << 8) - 1)
|
||||
|
||||
ret = ksz_write8(dev, REG_SW_LUE_CTRL_3, value);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
/* The aging timer comprises a 3-bit multiplier and an 8-bit second
|
||||
* value. Either of them cannot be zero. The maximum timer is then
|
||||
* 7 * 255 = 1785 seconds.
|
||||
*/
|
||||
if (!secs)
|
||||
secs = 1;
|
||||
|
||||
data = FIELD_GET(SW_AGE_PERIOD_10_8_M, secs);
|
||||
/* Return error if too large. */
|
||||
else if (secs > 7 * MAX_TIMER_VAL)
|
||||
return -EINVAL;
|
||||
|
||||
ret = ksz_read8(dev, REG_SW_LUE_CTRL_0, &value);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
value &= ~SW_AGE_CNT_M;
|
||||
value |= FIELD_PREP(SW_AGE_CNT_M, data);
|
||||
/* Check whether there is need to update the multiplier. */
|
||||
mult = FIELD_GET(SW_AGE_CNT_M, value);
|
||||
max_val = MAX_TIMER_VAL;
|
||||
if (mult > 0) {
|
||||
/* Try to use the same multiplier already in the register as
|
||||
* the hardware default uses multiplier 4 and 75 seconds for
|
||||
* 300 seconds.
|
||||
*/
|
||||
max_val = DIV_ROUND_UP(secs, mult);
|
||||
if (max_val > MAX_TIMER_VAL || max_val * mult != secs)
|
||||
max_val = MAX_TIMER_VAL;
|
||||
}
|
||||
|
||||
return ksz_write8(dev, REG_SW_LUE_CTRL_0, value);
|
||||
data = DIV_ROUND_UP(secs, max_val);
|
||||
if (mult != data) {
|
||||
value &= ~SW_AGE_CNT_M;
|
||||
value |= FIELD_PREP(SW_AGE_CNT_M, data);
|
||||
ret = ksz_write8(dev, REG_SW_LUE_CTRL_0, value);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
value = DIV_ROUND_UP(secs, data);
|
||||
return ksz_write8(dev, REG_SW_LUE_CTRL_3, value);
|
||||
}
|
||||
|
||||
void ksz9477_port_setup(struct ksz_device *dev, int port, bool cpu_port)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
/*
|
||||
* Microchip KSZ9477 register definitions
|
||||
*
|
||||
* Copyright (C) 2017-2018 Microchip Technology Inc.
|
||||
* Copyright (C) 2017-2024 Microchip Technology Inc.
|
||||
*/
|
||||
|
||||
#ifndef __KSZ9477_REGS_H
|
||||
@@ -190,8 +190,6 @@
|
||||
#define SW_VLAN_ENABLE BIT(7)
|
||||
#define SW_DROP_INVALID_VID BIT(6)
|
||||
#define SW_AGE_CNT_M GENMASK(5, 3)
|
||||
#define SW_AGE_CNT_S 3
|
||||
#define SW_AGE_PERIOD_10_8_M GENMASK(10, 8)
|
||||
#define SW_RESV_MCAST_ENABLE BIT(2)
|
||||
#define SW_HASH_OPTION_M 0x03
|
||||
#define SW_HASH_OPTION_CRC 1
|
||||
|
||||
@@ -454,6 +454,11 @@ static inline int ksz_write64(struct ksz_device *dev, u32 reg, u64 value)
|
||||
return regmap_bulk_write(dev->regmap[2], reg, val, 2);
|
||||
}
|
||||
|
||||
static inline int ksz_rmw8(struct ksz_device *dev, int offset, u8 mask, u8 val)
|
||||
{
|
||||
return regmap_update_bits(dev->regmap[0], offset, mask, val);
|
||||
}
|
||||
|
||||
static inline int ksz_pread8(struct ksz_device *dev, int port, int offset,
|
||||
u8 *data)
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Microchip LAN937X switch driver main logic
|
||||
* Copyright (C) 2019-2022 Microchip Technology Inc.
|
||||
* Copyright (C) 2019-2024 Microchip Technology Inc.
|
||||
*/
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
@@ -249,10 +249,66 @@ int lan937x_change_mtu(struct ksz_device *dev, int port, int new_mtu)
|
||||
|
||||
int lan937x_set_ageing_time(struct ksz_device *dev, unsigned int msecs)
|
||||
{
|
||||
u32 secs = msecs / 1000;
|
||||
u32 value;
|
||||
u8 data, mult, value8;
|
||||
bool in_msec = false;
|
||||
u32 max_val, value;
|
||||
u32 secs = msecs;
|
||||
int ret;
|
||||
|
||||
#define MAX_TIMER_VAL ((1 << 20) - 1)
|
||||
|
||||
/* The aging timer comprises a 3-bit multiplier and a 20-bit second
|
||||
* value. Either of them cannot be zero. The maximum timer is then
|
||||
* 7 * 1048575 = 7340025 seconds. As this value is too large for
|
||||
* practical use it can be interpreted as microseconds, making the
|
||||
* maximum timer 7340 seconds with finer control. This allows for
|
||||
* maximum 122 minutes compared to 29 minutes in KSZ9477 switch.
|
||||
*/
|
||||
if (msecs % 1000)
|
||||
in_msec = true;
|
||||
else
|
||||
secs /= 1000;
|
||||
if (!secs)
|
||||
secs = 1;
|
||||
|
||||
/* Return error if too large. */
|
||||
else if (secs > 7 * MAX_TIMER_VAL)
|
||||
return -EINVAL;
|
||||
|
||||
/* Configure how to interpret the number value. */
|
||||
ret = ksz_rmw8(dev, REG_SW_LUE_CTRL_2, SW_AGE_CNT_IN_MICROSEC,
|
||||
in_msec ? SW_AGE_CNT_IN_MICROSEC : 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = ksz_read8(dev, REG_SW_LUE_CTRL_0, &value8);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Check whether there is need to update the multiplier. */
|
||||
mult = FIELD_GET(SW_AGE_CNT_M, value8);
|
||||
max_val = MAX_TIMER_VAL;
|
||||
if (mult > 0) {
|
||||
/* Try to use the same multiplier already in the register as
|
||||
* the hardware default uses multiplier 4 and 75 seconds for
|
||||
* 300 seconds.
|
||||
*/
|
||||
max_val = DIV_ROUND_UP(secs, mult);
|
||||
if (max_val > MAX_TIMER_VAL || max_val * mult != secs)
|
||||
max_val = MAX_TIMER_VAL;
|
||||
}
|
||||
|
||||
data = DIV_ROUND_UP(secs, max_val);
|
||||
if (mult != data) {
|
||||
value8 &= ~SW_AGE_CNT_M;
|
||||
value8 |= FIELD_PREP(SW_AGE_CNT_M, data);
|
||||
ret = ksz_write8(dev, REG_SW_LUE_CTRL_0, value8);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
secs = DIV_ROUND_UP(secs, data);
|
||||
|
||||
value = FIELD_GET(SW_AGE_PERIOD_7_0_M, secs);
|
||||
|
||||
ret = ksz_write8(dev, REG_SW_AGE_PERIOD__1, value);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* Microchip LAN937X switch register definitions
|
||||
* Copyright (C) 2019-2021 Microchip Technology Inc.
|
||||
* Copyright (C) 2019-2024 Microchip Technology Inc.
|
||||
*/
|
||||
#ifndef __LAN937X_REG_H
|
||||
#define __LAN937X_REG_H
|
||||
@@ -48,8 +48,7 @@
|
||||
|
||||
#define SW_VLAN_ENABLE BIT(7)
|
||||
#define SW_DROP_INVALID_VID BIT(6)
|
||||
#define SW_AGE_CNT_M 0x7
|
||||
#define SW_AGE_CNT_S 3
|
||||
#define SW_AGE_CNT_M GENMASK(5, 3)
|
||||
#define SW_RESV_MCAST_ENABLE BIT(2)
|
||||
|
||||
#define REG_SW_LUE_CTRL_1 0x0311
|
||||
@@ -62,6 +61,10 @@
|
||||
#define SW_FAST_AGING BIT(1)
|
||||
#define SW_LINK_AUTO_AGING BIT(0)
|
||||
|
||||
#define REG_SW_LUE_CTRL_2 0x0312
|
||||
|
||||
#define SW_AGE_CNT_IN_MICROSEC BIT(7)
|
||||
|
||||
#define REG_SW_AGE_PERIOD__1 0x0313
|
||||
#define SW_AGE_PERIOD_7_0_M GENMASK(7, 0)
|
||||
|
||||
|
||||
@@ -1956,7 +1956,11 @@ static int bcm_sysport_open(struct net_device *dev)
|
||||
unsigned int i;
|
||||
int ret;
|
||||
|
||||
clk_prepare_enable(priv->clk);
|
||||
ret = clk_prepare_enable(priv->clk);
|
||||
if (ret) {
|
||||
netdev_err(dev, "could not enable priv clock\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Reset UniMAC */
|
||||
umac_reset(priv);
|
||||
@@ -2614,7 +2618,11 @@ static int bcm_sysport_probe(struct platform_device *pdev)
|
||||
goto err_deregister_notifier;
|
||||
}
|
||||
|
||||
clk_prepare_enable(priv->clk);
|
||||
ret = clk_prepare_enable(priv->clk);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "could not enable priv clock\n");
|
||||
goto err_deregister_netdev;
|
||||
}
|
||||
|
||||
priv->rev = topctrl_readl(priv, REV_CNTL) & REV_MASK;
|
||||
dev_info(&pdev->dev,
|
||||
@@ -2628,6 +2636,8 @@ static int bcm_sysport_probe(struct platform_device *pdev)
|
||||
|
||||
return 0;
|
||||
|
||||
err_deregister_netdev:
|
||||
unregister_netdev(dev);
|
||||
err_deregister_notifier:
|
||||
unregister_netdevice_notifier(&priv->netdev_notifier);
|
||||
err_deregister_fixed_link:
|
||||
@@ -2799,7 +2809,12 @@ static int __maybe_unused bcm_sysport_resume(struct device *d)
|
||||
if (!netif_running(dev))
|
||||
return 0;
|
||||
|
||||
clk_prepare_enable(priv->clk);
|
||||
ret = clk_prepare_enable(priv->clk);
|
||||
if (ret) {
|
||||
netdev_err(dev, "could not enable priv clock\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (priv->wolopts)
|
||||
clk_disable_unprepare(priv->wol_clk);
|
||||
|
||||
|
||||
@@ -171,6 +171,7 @@ static int platform_phy_connect(struct bgmac *bgmac)
|
||||
static int bgmac_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
struct device_node *phy_node;
|
||||
struct bgmac *bgmac;
|
||||
struct resource *regs;
|
||||
int ret;
|
||||
@@ -236,7 +237,9 @@ static int bgmac_probe(struct platform_device *pdev)
|
||||
bgmac->cco_ctl_maskset = platform_bgmac_cco_ctl_maskset;
|
||||
bgmac->get_bus_clock = platform_bgmac_get_bus_clock;
|
||||
bgmac->cmn_maskset32 = platform_bgmac_cmn_maskset32;
|
||||
if (of_parse_phandle(np, "phy-handle", 0)) {
|
||||
phy_node = of_parse_phandle(np, "phy-handle", 0);
|
||||
if (phy_node) {
|
||||
of_node_put(phy_node);
|
||||
bgmac->phy_connect = platform_phy_connect;
|
||||
} else {
|
||||
bgmac->phy_connect = bgmac_phy_connect_direct;
|
||||
|
||||
@@ -346,8 +346,9 @@ static struct sk_buff *copy_gl_to_skb_pkt(const struct pkt_gl *gl,
|
||||
* driver. Once driver synthesizes cpl_pass_accpet_req the skb will go
|
||||
* through the regular cpl_pass_accept_req processing in TOM.
|
||||
*/
|
||||
skb = alloc_skb(gl->tot_len + sizeof(struct cpl_pass_accept_req)
|
||||
- pktshift, GFP_ATOMIC);
|
||||
skb = alloc_skb(size_add(gl->tot_len,
|
||||
sizeof(struct cpl_pass_accept_req)) -
|
||||
pktshift, GFP_ATOMIC);
|
||||
if (unlikely(!skb))
|
||||
return NULL;
|
||||
__skb_put(skb, gl->tot_len + sizeof(struct cpl_pass_accept_req)
|
||||
|
||||
@@ -172,6 +172,7 @@ err_init_txq:
|
||||
hinic_sq_dbgfs_uninit(nic_dev);
|
||||
|
||||
devm_kfree(&netdev->dev, nic_dev->txqs);
|
||||
nic_dev->txqs = NULL;
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -268,6 +269,7 @@ err_init_rxq:
|
||||
hinic_rq_dbgfs_uninit(nic_dev);
|
||||
|
||||
devm_kfree(&netdev->dev, nic_dev->rxqs);
|
||||
nic_dev->rxqs = NULL;
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
@@ -2707,9 +2707,15 @@ static struct platform_device *port_platdev[3];
|
||||
|
||||
static void mv643xx_eth_shared_of_remove(void)
|
||||
{
|
||||
struct mv643xx_eth_platform_data *pd;
|
||||
int n;
|
||||
|
||||
for (n = 0; n < 3; n++) {
|
||||
if (!port_platdev[n])
|
||||
continue;
|
||||
pd = dev_get_platdata(&port_platdev[n]->dev);
|
||||
if (pd)
|
||||
of_node_put(pd->phy_node);
|
||||
platform_device_del(port_platdev[n]);
|
||||
port_platdev[n] = NULL;
|
||||
}
|
||||
@@ -2770,8 +2776,10 @@ static int mv643xx_eth_shared_of_add_port(struct platform_device *pdev,
|
||||
}
|
||||
|
||||
ppdev = platform_device_alloc(MV643XX_ETH_NAME, dev_num);
|
||||
if (!ppdev)
|
||||
return -ENOMEM;
|
||||
if (!ppdev) {
|
||||
ret = -ENOMEM;
|
||||
goto put_err;
|
||||
}
|
||||
ppdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
|
||||
ppdev->dev.of_node = pnp;
|
||||
|
||||
@@ -2793,6 +2801,8 @@ static int mv643xx_eth_shared_of_add_port(struct platform_device *pdev,
|
||||
|
||||
port_err:
|
||||
platform_device_put(ppdev);
|
||||
put_err:
|
||||
of_node_put(ppd.phy_node);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -130,6 +130,7 @@ static const struct pci_device_id sky2_id_table[] = {
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436C) }, /* 88E8072 */
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436D) }, /* 88E8055 */
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4370) }, /* 88E8075 */
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4373) }, /* 88E8075 */
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4380) }, /* 88E8057 */
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4381) }, /* 88E8059 */
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4382) }, /* 88E8079 */
|
||||
|
||||
@@ -5980,7 +5980,9 @@ static void mlx5e_remove(struct auxiliary_device *adev)
|
||||
mlx5e_dcbnl_delete_app(priv);
|
||||
unregister_netdev(priv->netdev);
|
||||
mlx5e_suspend(adev, state);
|
||||
priv->profile->cleanup(priv);
|
||||
/* Avoid cleanup if profile rollback failed. */
|
||||
if (priv->profile)
|
||||
priv->profile->cleanup(priv);
|
||||
mlx5e_devlink_port_unregister(priv);
|
||||
mlx5e_destroy_netdev(priv);
|
||||
}
|
||||
|
||||
@@ -1161,7 +1161,7 @@ void ocelot_ifh_set_basic(void *ifh, struct ocelot *ocelot, int port,
|
||||
|
||||
memset(ifh, 0, OCELOT_TAG_LEN);
|
||||
ocelot_ifh_set_bypass(ifh, 1);
|
||||
ocelot_ifh_set_src(ifh, BIT_ULL(ocelot->num_phys_ports));
|
||||
ocelot_ifh_set_src(ifh, ocelot->num_phys_ports);
|
||||
ocelot_ifh_set_dest(ifh, BIT_ULL(port));
|
||||
ocelot_ifh_set_qos_class(ifh, qos_class);
|
||||
ocelot_ifh_set_tag_type(ifh, tag_type);
|
||||
|
||||
@@ -828,8 +828,8 @@ static int ionic_get_module_eeprom(struct net_device *netdev,
|
||||
len = min_t(u32, sizeof(xcvr->sprom), ee->len);
|
||||
|
||||
do {
|
||||
memcpy(data, xcvr->sprom, len);
|
||||
memcpy(tbuf, xcvr->sprom, len);
|
||||
memcpy(data, &xcvr->sprom[ee->offset], len);
|
||||
memcpy(tbuf, &xcvr->sprom[ee->offset], len);
|
||||
|
||||
/* Let's make sure we got a consistent copy */
|
||||
if (!memcmp(data, tbuf, len))
|
||||
|
||||
@@ -3484,8 +3484,8 @@ int ionic_lif_register(struct ionic_lif *lif)
|
||||
/* only register LIF0 for now */
|
||||
err = register_netdev(lif->netdev);
|
||||
if (err) {
|
||||
dev_err(lif->ionic->dev, "Cannot register net device, aborting\n");
|
||||
ionic_lif_unregister_phc(lif);
|
||||
dev_err(lif->ionic->dev, "Cannot register net device: %d, aborting\n", err);
|
||||
ionic_lif_unregister(lif);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
|
||||
*******************************************************************************/
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/module.h>
|
||||
@@ -293,62 +294,80 @@ out:
|
||||
}
|
||||
|
||||
/**
|
||||
* stmmac_dt_phy - parse device-tree driver parameters to allocate PHY resources
|
||||
* @plat: driver data platform structure
|
||||
* @np: device tree node
|
||||
* @dev: device pointer
|
||||
* Description:
|
||||
* The mdio bus will be allocated in case of a phy transceiver is on board;
|
||||
* it will be NULL if the fixed-link is configured.
|
||||
* If there is the "snps,dwmac-mdio" sub-node the mdio will be allocated
|
||||
* in any case (for DSA, mdio must be registered even if fixed-link).
|
||||
* The table below sums the supported configurations:
|
||||
* -------------------------------
|
||||
* snps,phy-addr | Y
|
||||
* -------------------------------
|
||||
* phy-handle | Y
|
||||
* -------------------------------
|
||||
* fixed-link | N
|
||||
* -------------------------------
|
||||
* snps,dwmac-mdio |
|
||||
* even if | Y
|
||||
* fixed-link |
|
||||
* -------------------------------
|
||||
* stmmac_of_get_mdio() - Gets the MDIO bus from the devicetree.
|
||||
* @np: devicetree node
|
||||
*
|
||||
* It returns 0 in case of success otherwise -ENODEV.
|
||||
* The MDIO bus will be searched for in the following ways:
|
||||
* 1. The compatible is "snps,dwc-qos-ethernet-4.10" && a "mdio" named
|
||||
* child node exists
|
||||
* 2. A child node with the "snps,dwmac-mdio" compatible is present
|
||||
*
|
||||
* Return: The MDIO node if present otherwise NULL
|
||||
*/
|
||||
static int stmmac_dt_phy(struct plat_stmmacenet_data *plat,
|
||||
struct device_node *np, struct device *dev)
|
||||
static struct device_node *stmmac_of_get_mdio(struct device_node *np)
|
||||
{
|
||||
bool mdio = !of_phy_is_fixed_link(np);
|
||||
static const struct of_device_id need_mdio_ids[] = {
|
||||
{ .compatible = "snps,dwc-qos-ethernet-4.10" },
|
||||
{},
|
||||
};
|
||||
struct device_node *mdio_node = NULL;
|
||||
|
||||
if (of_match_node(need_mdio_ids, np)) {
|
||||
plat->mdio_node = of_get_child_by_name(np, "mdio");
|
||||
mdio_node = of_get_child_by_name(np, "mdio");
|
||||
} else {
|
||||
/**
|
||||
* If snps,dwmac-mdio is passed from DT, always register
|
||||
* the MDIO
|
||||
*/
|
||||
for_each_child_of_node(np, plat->mdio_node) {
|
||||
if (of_device_is_compatible(plat->mdio_node,
|
||||
for_each_child_of_node(np, mdio_node) {
|
||||
if (of_device_is_compatible(mdio_node,
|
||||
"snps,dwmac-mdio"))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (plat->mdio_node) {
|
||||
dev_dbg(dev, "Found MDIO subnode\n");
|
||||
mdio = true;
|
||||
}
|
||||
return mdio_node;
|
||||
}
|
||||
|
||||
if (mdio) {
|
||||
plat->mdio_bus_data =
|
||||
devm_kzalloc(dev, sizeof(struct stmmac_mdio_bus_data),
|
||||
GFP_KERNEL);
|
||||
/**
|
||||
* stmmac_mdio_setup() - Populate platform related MDIO structures.
|
||||
* @plat: driver data platform structure
|
||||
* @np: devicetree node
|
||||
* @dev: device pointer
|
||||
*
|
||||
* This searches for MDIO information from the devicetree.
|
||||
* If an MDIO node is found, it's assigned to plat->mdio_node and
|
||||
* plat->mdio_bus_data is allocated.
|
||||
* If no connection can be determined, just plat->mdio_bus_data is allocated
|
||||
* to indicate a bus should be created and scanned for a phy.
|
||||
* If it's determined there's no MDIO bus needed, both are left NULL.
|
||||
*
|
||||
* This expects that plat->phy_node has already been searched for.
|
||||
*
|
||||
* Return: 0 on success, errno otherwise.
|
||||
*/
|
||||
static int stmmac_mdio_setup(struct plat_stmmacenet_data *plat,
|
||||
struct device_node *np, struct device *dev)
|
||||
{
|
||||
bool legacy_mdio;
|
||||
|
||||
plat->mdio_node = stmmac_of_get_mdio(np);
|
||||
if (plat->mdio_node)
|
||||
dev_dbg(dev, "Found MDIO subnode\n");
|
||||
|
||||
/* Legacy devicetrees allowed for no MDIO bus description and expect
|
||||
* the bus to be scanned for devices. If there's no phy or fixed-link
|
||||
* described assume this is the case since there must be something
|
||||
* connected to the MAC.
|
||||
*/
|
||||
legacy_mdio = !of_phy_is_fixed_link(np) && !plat->phy_node;
|
||||
if (legacy_mdio)
|
||||
dev_info(dev, "Deprecated MDIO bus assumption used\n");
|
||||
|
||||
if (plat->mdio_node || legacy_mdio) {
|
||||
plat->mdio_bus_data = devm_kzalloc(dev,
|
||||
sizeof(*plat->mdio_bus_data),
|
||||
GFP_KERNEL);
|
||||
if (!plat->mdio_bus_data)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -453,10 +472,11 @@ stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac)
|
||||
if (of_property_read_u32(np, "snps,phy-addr", &plat->phy_addr) == 0)
|
||||
dev_warn(&pdev->dev, "snps,phy-addr property is deprecated\n");
|
||||
|
||||
/* To Configure PHY by using all device-tree supported properties */
|
||||
rc = stmmac_dt_phy(plat, np, &pdev->dev);
|
||||
if (rc)
|
||||
return ERR_PTR(rc);
|
||||
rc = stmmac_mdio_setup(plat, np, &pdev->dev);
|
||||
if (rc) {
|
||||
ret = ERR_PTR(rc);
|
||||
goto error_put_phy;
|
||||
}
|
||||
|
||||
of_property_read_u32(np, "tx-fifo-depth", &plat->tx_fifo_size);
|
||||
|
||||
@@ -542,8 +562,8 @@ stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac)
|
||||
dma_cfg = devm_kzalloc(&pdev->dev, sizeof(*dma_cfg),
|
||||
GFP_KERNEL);
|
||||
if (!dma_cfg) {
|
||||
stmmac_remove_config_dt(pdev, plat);
|
||||
return ERR_PTR(-ENOMEM);
|
||||
ret = ERR_PTR(-ENOMEM);
|
||||
goto error_put_mdio;
|
||||
}
|
||||
plat->dma_cfg = dma_cfg;
|
||||
|
||||
@@ -571,8 +591,8 @@ stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac)
|
||||
|
||||
rc = stmmac_mtl_setup(pdev, plat);
|
||||
if (rc) {
|
||||
stmmac_remove_config_dt(pdev, plat);
|
||||
return ERR_PTR(rc);
|
||||
ret = ERR_PTR(rc);
|
||||
goto error_put_mdio;
|
||||
}
|
||||
|
||||
/* clock setup */
|
||||
@@ -624,10 +644,48 @@ error_hw_init:
|
||||
clk_disable_unprepare(plat->pclk);
|
||||
error_pclk_get:
|
||||
clk_disable_unprepare(plat->stmmac_clk);
|
||||
error_put_mdio:
|
||||
of_node_put(plat->mdio_node);
|
||||
error_put_phy:
|
||||
of_node_put(plat->phy_node);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void devm_stmmac_remove_config_dt(void *data)
|
||||
{
|
||||
struct plat_stmmacenet_data *plat = data;
|
||||
|
||||
clk_disable_unprepare(plat->stmmac_clk);
|
||||
clk_disable_unprepare(plat->pclk);
|
||||
of_node_put(plat->mdio_node);
|
||||
of_node_put(plat->phy_node);
|
||||
}
|
||||
|
||||
/**
|
||||
* devm_stmmac_probe_config_dt
|
||||
* @pdev: platform_device structure
|
||||
* @mac: MAC address to use
|
||||
* Description: Devres variant of stmmac_probe_config_dt().
|
||||
*/
|
||||
struct plat_stmmacenet_data *
|
||||
devm_stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac)
|
||||
{
|
||||
struct plat_stmmacenet_data *plat;
|
||||
int ret;
|
||||
|
||||
plat = stmmac_probe_config_dt(pdev, mac);
|
||||
if (IS_ERR(plat))
|
||||
return plat;
|
||||
|
||||
ret = devm_add_action_or_reset(&pdev->dev,
|
||||
devm_stmmac_remove_config_dt, plat);
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
|
||||
return plat;
|
||||
}
|
||||
|
||||
/**
|
||||
* stmmac_remove_config_dt - undo the effects of stmmac_probe_config_dt()
|
||||
* @pdev: platform_device structure
|
||||
@@ -650,12 +708,19 @@ stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac)
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
struct plat_stmmacenet_data *
|
||||
devm_stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac)
|
||||
{
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
void stmmac_remove_config_dt(struct platform_device *pdev,
|
||||
struct plat_stmmacenet_data *plat)
|
||||
{
|
||||
}
|
||||
#endif /* CONFIG_OF */
|
||||
EXPORT_SYMBOL_GPL(stmmac_probe_config_dt);
|
||||
EXPORT_SYMBOL_GPL(devm_stmmac_probe_config_dt);
|
||||
EXPORT_SYMBOL_GPL(stmmac_remove_config_dt);
|
||||
|
||||
int stmmac_get_platform_resources(struct platform_device *pdev,
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
|
||||
struct plat_stmmacenet_data *
|
||||
stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac);
|
||||
struct plat_stmmacenet_data *
|
||||
devm_stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac);
|
||||
void stmmac_remove_config_dt(struct platform_device *pdev,
|
||||
struct plat_stmmacenet_data *plat);
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ fwnode_find_pse_control(struct fwnode_handle *fwnode)
|
||||
static struct mii_timestamper *
|
||||
fwnode_find_mii_timestamper(struct fwnode_handle *fwnode)
|
||||
{
|
||||
struct mii_timestamper *mii_ts;
|
||||
struct of_phandle_args arg;
|
||||
int err;
|
||||
|
||||
@@ -51,10 +52,16 @@ fwnode_find_mii_timestamper(struct fwnode_handle *fwnode)
|
||||
else if (err)
|
||||
return ERR_PTR(err);
|
||||
|
||||
if (arg.args_count != 1)
|
||||
return ERR_PTR(-EINVAL);
|
||||
if (arg.args_count != 1) {
|
||||
mii_ts = ERR_PTR(-EINVAL);
|
||||
goto put_node;
|
||||
}
|
||||
|
||||
return register_mii_timestamper(arg.np, arg.args[0]);
|
||||
mii_ts = register_mii_timestamper(arg.np, arg.args[0]);
|
||||
|
||||
put_node:
|
||||
of_node_put(arg.np);
|
||||
return mii_ts;
|
||||
}
|
||||
|
||||
int fwnode_mdiobus_phy_device_register(struct mii_bus *mdio,
|
||||
|
||||
@@ -203,6 +203,8 @@ static ssize_t nsim_dev_health_break_write(struct file *file,
|
||||
char *break_msg;
|
||||
int err;
|
||||
|
||||
if (count == 0 || count > PAGE_SIZE)
|
||||
return -EINVAL;
|
||||
break_msg = memdup_user_nul(data, count);
|
||||
if (IS_ERR(break_msg))
|
||||
return PTR_ERR(break_msg);
|
||||
|
||||
@@ -1372,6 +1372,9 @@ static const struct usb_device_id products[] = {
|
||||
{QMI_QUIRK_SET_DTR(0x1bc7, 0x10a0, 0)}, /* Telit FN920C04 */
|
||||
{QMI_QUIRK_SET_DTR(0x1bc7, 0x10a4, 0)}, /* Telit FN920C04 */
|
||||
{QMI_QUIRK_SET_DTR(0x1bc7, 0x10a9, 0)}, /* Telit FN920C04 */
|
||||
{QMI_QUIRK_SET_DTR(0x1bc7, 0x10c0, 0)}, /* Telit FE910C04 */
|
||||
{QMI_QUIRK_SET_DTR(0x1bc7, 0x10c4, 0)}, /* Telit FE910C04 */
|
||||
{QMI_QUIRK_SET_DTR(0x1bc7, 0x10c8, 0)}, /* Telit FE910C04 */
|
||||
{QMI_FIXED_INTF(0x1bc7, 0x1100, 3)}, /* Telit ME910 */
|
||||
{QMI_FIXED_INTF(0x1bc7, 0x1101, 3)}, /* Telit ME910 dual modem */
|
||||
{QMI_FIXED_INTF(0x1bc7, 0x1200, 5)}, /* Telit LE920 */
|
||||
|
||||
@@ -104,7 +104,7 @@ struct iosm_mmio *ipc_mmio_init(void __iomem *mmio, struct device *dev)
|
||||
break;
|
||||
|
||||
msleep(20);
|
||||
} while (retries-- > 0);
|
||||
} while (--retries > 0);
|
||||
|
||||
if (!retries) {
|
||||
dev_err(ipc_mmio->dev, "invalid exec stage %X", stage);
|
||||
|
||||
@@ -97,14 +97,21 @@ void t7xx_fsm_broadcast_state(struct t7xx_fsm_ctl *ctl, enum md_state state)
|
||||
fsm_state_notify(ctl->md, state);
|
||||
}
|
||||
|
||||
static void fsm_release_command(struct kref *ref)
|
||||
{
|
||||
struct t7xx_fsm_command *cmd = container_of(ref, typeof(*cmd), refcnt);
|
||||
|
||||
kfree(cmd);
|
||||
}
|
||||
|
||||
static void fsm_finish_command(struct t7xx_fsm_ctl *ctl, struct t7xx_fsm_command *cmd, int result)
|
||||
{
|
||||
if (cmd->flag & FSM_CMD_FLAG_WAIT_FOR_COMPLETION) {
|
||||
*cmd->ret = result;
|
||||
complete_all(cmd->done);
|
||||
cmd->result = result;
|
||||
complete_all(&cmd->done);
|
||||
}
|
||||
|
||||
kfree(cmd);
|
||||
kref_put(&cmd->refcnt, fsm_release_command);
|
||||
}
|
||||
|
||||
static void fsm_del_kf_event(struct t7xx_fsm_event *event)
|
||||
@@ -387,7 +394,6 @@ static int fsm_main_thread(void *data)
|
||||
|
||||
int t7xx_fsm_append_cmd(struct t7xx_fsm_ctl *ctl, enum t7xx_fsm_cmd_state cmd_id, unsigned int flag)
|
||||
{
|
||||
DECLARE_COMPLETION_ONSTACK(done);
|
||||
struct t7xx_fsm_command *cmd;
|
||||
unsigned long flags;
|
||||
int ret;
|
||||
@@ -399,11 +405,13 @@ int t7xx_fsm_append_cmd(struct t7xx_fsm_ctl *ctl, enum t7xx_fsm_cmd_state cmd_id
|
||||
INIT_LIST_HEAD(&cmd->entry);
|
||||
cmd->cmd_id = cmd_id;
|
||||
cmd->flag = flag;
|
||||
kref_init(&cmd->refcnt);
|
||||
if (flag & FSM_CMD_FLAG_WAIT_FOR_COMPLETION) {
|
||||
cmd->done = &done;
|
||||
cmd->ret = &ret;
|
||||
init_completion(&cmd->done);
|
||||
kref_get(&cmd->refcnt);
|
||||
}
|
||||
|
||||
kref_get(&cmd->refcnt);
|
||||
spin_lock_irqsave(&ctl->command_lock, flags);
|
||||
list_add_tail(&cmd->entry, &ctl->command_queue);
|
||||
spin_unlock_irqrestore(&ctl->command_lock, flags);
|
||||
@@ -413,11 +421,11 @@ int t7xx_fsm_append_cmd(struct t7xx_fsm_ctl *ctl, enum t7xx_fsm_cmd_state cmd_id
|
||||
if (flag & FSM_CMD_FLAG_WAIT_FOR_COMPLETION) {
|
||||
unsigned long wait_ret;
|
||||
|
||||
wait_ret = wait_for_completion_timeout(&done,
|
||||
wait_ret = wait_for_completion_timeout(&cmd->done,
|
||||
msecs_to_jiffies(FSM_CMD_TIMEOUT_MS));
|
||||
if (!wait_ret)
|
||||
return -ETIMEDOUT;
|
||||
|
||||
ret = wait_ret ? cmd->result : -ETIMEDOUT;
|
||||
kref_put(&cmd->refcnt, fsm_release_command);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -107,8 +107,9 @@ struct t7xx_fsm_command {
|
||||
struct list_head entry;
|
||||
enum t7xx_fsm_cmd_state cmd_id;
|
||||
unsigned int flag;
|
||||
struct completion *done;
|
||||
int *ret;
|
||||
struct completion done;
|
||||
int result;
|
||||
struct kref refcnt;
|
||||
};
|
||||
|
||||
struct t7xx_fsm_notifier {
|
||||
|
||||
@@ -595,7 +595,7 @@ struct device_node *__of_get_dma_parent(const struct device_node *np)
|
||||
if (ret < 0)
|
||||
return of_get_parent(np);
|
||||
|
||||
return of_node_get(args.np);
|
||||
return args.np;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1597,8 +1597,10 @@ int of_parse_phandle_with_args_map(const struct device_node *np,
|
||||
map_len--;
|
||||
|
||||
/* Check if not found */
|
||||
if (!new)
|
||||
if (!new) {
|
||||
ret = -EINVAL;
|
||||
goto put;
|
||||
}
|
||||
|
||||
if (!of_device_is_available(new))
|
||||
match = 0;
|
||||
@@ -1608,17 +1610,20 @@ int of_parse_phandle_with_args_map(const struct device_node *np,
|
||||
goto put;
|
||||
|
||||
/* Check for malformed properties */
|
||||
if (WARN_ON(new_size > MAX_PHANDLE_ARGS))
|
||||
goto put;
|
||||
if (map_len < new_size)
|
||||
if (WARN_ON(new_size > MAX_PHANDLE_ARGS) ||
|
||||
map_len < new_size) {
|
||||
ret = -EINVAL;
|
||||
goto put;
|
||||
}
|
||||
|
||||
/* Move forward by new node's #<list>-cells amount */
|
||||
map += new_size;
|
||||
map_len -= new_size;
|
||||
}
|
||||
if (!match)
|
||||
if (!match) {
|
||||
ret = -ENOENT;
|
||||
goto put;
|
||||
}
|
||||
|
||||
/* Get the <list>-map-pass-thru property (optional) */
|
||||
pass = of_get_property(cur, pass_name, NULL);
|
||||
|
||||
@@ -111,6 +111,7 @@ const __be32 *of_irq_parse_imap_parent(const __be32 *imap, int len, struct of_ph
|
||||
else
|
||||
np = of_find_node_by_phandle(be32_to_cpup(imap));
|
||||
imap++;
|
||||
len--;
|
||||
|
||||
/* Check if not found */
|
||||
if (!np) {
|
||||
@@ -354,6 +355,7 @@ int of_irq_parse_one(struct device_node *device, int index, struct of_phandle_ar
|
||||
return of_irq_parse_oldworld(device, index, out_irq);
|
||||
|
||||
/* Get the reg property (if any) */
|
||||
addr_len = 0;
|
||||
addr = of_get_property(device, "reg", &addr_len);
|
||||
|
||||
/* Prevent out-of-bounds read in case of longer interrupt parent address size */
|
||||
|
||||
@@ -73,10 +73,6 @@ int pci_host_common_probe(struct platform_device *pdev)
|
||||
if (IS_ERR(cfg))
|
||||
return PTR_ERR(cfg);
|
||||
|
||||
/* Do not reassign resources if probe only */
|
||||
if (!pci_has_flag(PCI_PROBE_ONLY))
|
||||
pci_add_flags(PCI_REASSIGN_ALL_BUS);
|
||||
|
||||
bridge->sysdata = cfg;
|
||||
bridge->ops = (struct pci_ops *)&ops->pci_ops;
|
||||
bridge->msi_domain = true;
|
||||
|
||||
@@ -870,6 +870,9 @@ static int vmd_enable_domain(struct vmd_dev *vmd, unsigned long features)
|
||||
dev_set_msi_domain(&vmd->bus->dev,
|
||||
dev_get_msi_domain(&vmd->dev->dev));
|
||||
|
||||
WARN(sysfs_create_link(&vmd->dev->dev.kobj, &vmd->bus->dev.kobj,
|
||||
"domain"), "Can't create symlink to domain\n");
|
||||
|
||||
vmd_acpi_begin();
|
||||
|
||||
pci_scan_child_bus(vmd->bus);
|
||||
@@ -907,9 +910,6 @@ static int vmd_enable_domain(struct vmd_dev *vmd, unsigned long features)
|
||||
pci_bus_add_devices(vmd->bus);
|
||||
|
||||
vmd_acpi_end();
|
||||
|
||||
WARN(sysfs_create_link(&vmd->dev->dev.kobj, &vmd->bus->dev.kobj,
|
||||
"domain"), "Can't create symlink to domain\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -985,8 +985,8 @@ static void vmd_remove(struct pci_dev *dev)
|
||||
{
|
||||
struct vmd_dev *vmd = pci_get_drvdata(dev);
|
||||
|
||||
sysfs_remove_link(&vmd->dev->dev.kobj, "domain");
|
||||
pci_stop_root_bus(vmd->bus);
|
||||
sysfs_remove_link(&vmd->dev->dev.kobj, "domain");
|
||||
pci_remove_root_bus(vmd->bus);
|
||||
vmd_cleanup_srcu(vmd);
|
||||
vmd_detach_resources(vmd);
|
||||
|
||||
@@ -1384,6 +1384,22 @@ static int aer_probe(struct pcie_device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aer_suspend(struct pcie_device *dev)
|
||||
{
|
||||
struct aer_rpc *rpc = get_service_data(dev);
|
||||
|
||||
aer_disable_rootport(rpc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aer_resume(struct pcie_device *dev)
|
||||
{
|
||||
struct aer_rpc *rpc = get_service_data(dev);
|
||||
|
||||
aer_enable_rootport(rpc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* aer_root_reset - reset Root Port hierarchy, RCEC, or RCiEP
|
||||
* @dev: pointer to Root Port, RCEC, or RCiEP
|
||||
@@ -1455,6 +1471,8 @@ static struct pcie_port_service_driver aerdriver = {
|
||||
.service = PCIE_PORT_SERVICE_AER,
|
||||
|
||||
.probe = aer_probe,
|
||||
.suspend = aer_suspend,
|
||||
.resume = aer_resume,
|
||||
.remove = aer_remove,
|
||||
};
|
||||
|
||||
|
||||
@@ -3075,20 +3075,18 @@ int pci_host_probe(struct pci_host_bridge *bridge)
|
||||
|
||||
bus = bridge->bus;
|
||||
|
||||
/*
|
||||
* We insert PCI resources into the iomem_resource and
|
||||
* ioport_resource trees in either pci_bus_claim_resources()
|
||||
* or pci_bus_assign_resources().
|
||||
*/
|
||||
if (pci_has_flag(PCI_PROBE_ONLY)) {
|
||||
/* If we must preserve the resource configuration, claim now */
|
||||
if (bridge->preserve_config)
|
||||
pci_bus_claim_resources(bus);
|
||||
} else {
|
||||
pci_bus_size_bridges(bus);
|
||||
pci_bus_assign_resources(bus);
|
||||
|
||||
list_for_each_entry(child, &bus->children, node)
|
||||
pcie_bus_configure_settings(child);
|
||||
}
|
||||
/*
|
||||
* Assign whatever was left unassigned. If we didn't claim above,
|
||||
* this will reassign everything.
|
||||
*/
|
||||
pci_assign_unassigned_root_bus_resources(bus);
|
||||
|
||||
list_for_each_entry(child, &bus->children, node)
|
||||
pcie_bus_configure_settings(child);
|
||||
|
||||
pci_bus_add_devices(bus);
|
||||
return 0;
|
||||
|
||||
@@ -5008,6 +5008,10 @@ static const struct pci_dev_acs_enabled {
|
||||
{ PCI_VENDOR_ID_BROADCOM, 0x1750, pci_quirk_mf_endpoint_acs },
|
||||
{ PCI_VENDOR_ID_BROADCOM, 0x1751, pci_quirk_mf_endpoint_acs },
|
||||
{ PCI_VENDOR_ID_BROADCOM, 0x1752, pci_quirk_mf_endpoint_acs },
|
||||
{ PCI_VENDOR_ID_BROADCOM, 0x1760, pci_quirk_mf_endpoint_acs },
|
||||
{ PCI_VENDOR_ID_BROADCOM, 0x1761, pci_quirk_mf_endpoint_acs },
|
||||
{ PCI_VENDOR_ID_BROADCOM, 0x1762, pci_quirk_mf_endpoint_acs },
|
||||
{ PCI_VENDOR_ID_BROADCOM, 0x1763, pci_quirk_mf_endpoint_acs },
|
||||
{ PCI_VENDOR_ID_BROADCOM, 0xD714, pci_quirk_brcm_acs },
|
||||
/* Amazon Annapurna Labs */
|
||||
{ PCI_VENDOR_ID_AMAZON_ANNAPURNA_LABS, 0x0031, pci_quirk_al_acs },
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user