mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-06 10:58:48 +09:00
Merge 5.15.8 into android13-5.15
Changes in 5.15.8
usb: gadget: uvc: fix multiple opens
HID: quirks: Add quirk for the Microsoft Surface 3 type-cover
HID: google: add eel USB id
HID: intel-ish-hid: ipc: only enable IRQ wakeup when requested
HID: add hid_is_usb() function to make it simpler for USB detection
HID: add USB_HID dependancy to hid-prodikeys
HID: add USB_HID dependancy to hid-chicony
HID: add USB_HID dependancy on some USB HID drivers
HID: bigbenff: prevent null pointer dereference
HID: wacom: fix problems when device is not a valid USB device
HID: check for valid USB device for many HID drivers
mtd: dataflash: Add device-tree SPI IDs
mmc: spi: Add device-tree SPI IDs
HID: sony: fix error path in probe
HID: Ignore battery for Elan touchscreen on Asus UX550VE
platform/x86/intel: hid: add quirk to support Surface Go 3
nft_set_pipapo: Fix bucket load in AVX2 lookup routine for six 8-bit groups
IB/hfi1: Insure use of smp_processor_id() is preempt disabled
IB/hfi1: Fix early init panic
IB/hfi1: Fix leak of rcvhdrtail_dummy_kvaddr
can: kvaser_usb: get CAN clock frequency from device
can: kvaser_pciefd: kvaser_pciefd_rx_error_frame(): increase correct stats->{rx,tx}_errors counter
can: sja1000: fix use after free in ems_pcmcia_add_card()
can: pch_can: pch_can_rx_normal: fix use after free
can: m_can: m_can_read_fifo: fix memory leak in error branch
can: m_can: pci: fix incorrect reference clock rate
can: m_can: pci: fix iomap_read_fifo() and iomap_write_fifo()
can: m_can: Disable and ignore ELO interrupt
net: dsa: mv88e6xxx: fix "don't use PHY_DETECT on internal PHY's"
net: dsa: mv88e6xxx: allow use of PHYs on CPU and DSA ports
x86/sme: Explicitly map new EFI memmap table as encrypted
platform/x86: amd-pmc: Fix s2idle failures on certain AMD laptops
nfc: fix potential NULL pointer deref in nfc_genl_dump_ses_done
selftests: netfilter: add a vrf+conntrack testcase
vrf: don't run conntrack on vrf with !dflt qdisc
bpf, x86: Fix "no previous prototype" warning
bpf, sockmap: Attach map progs to psock early for feature probes
bpf: Make sure bpf_disable_instrumentation() is safe vs preemption.
bpf: Fix the off-by-two error in range markings
ice: ignore dropped packets during init
ethtool: do not perform operations on net devices being unregistered
bonding: make tx_rebalance_counter an atomic
nfp: Fix memory leak in nfp_cpp_area_cache_add()
seg6: fix the iif in the IPv6 socket control block
udp: using datalen to cap max gso segments
netfilter: nft_exthdr: break evaluation if setting TCP option fails
netfilter: conntrack: annotate data-races around ct->timeout
iavf: restore MSI state on reset
iavf: Fix reporting when setting descriptor count
IB/hfi1: Correct guard on eager buffer deallocation
devlink: fix netns refcount leak in devlink_nl_cmd_reload()
net: bcm4908: Handle dma_set_coherent_mask error codes
net: dsa: mv88e6xxx: error handling for serdes_power functions
net: dsa: felix: Fix memory leak in felix_setup_mmio_filtering
net/sched: fq_pie: prevent dismantle issue
net: mvpp2: fix XDP rx queues registering
KVM: x86: Don't WARN if userspace mucks with RCX during string I/O exit
KVM: x86: Ignore sparse banks size for an "all CPUs", non-sparse IPI req
KVM: x86: Wait for IPIs to be delivered when handling Hyper-V TLB flush hypercall
timers: implement usleep_idle_range()
mm/damon/core: fix fake load reports due to uninterruptible sleeps
mm/slub: fix endianness bug for alloc/free_traces attributes
mm: bdi: initialize bdi_min_ratio when bdi is unregistered
ALSA: ctl: Fix copy of updated id with element read/write
ALSA: hda/realtek - Add headset Mic support for Lenovo ALC897 platform
ALSA: hda/realtek: Fix quirk for TongFang PHxTxX1
ALSA: pcm: oss: Fix negative period/buffer sizes
ALSA: pcm: oss: Limit the period size to 16MB
ALSA: pcm: oss: Handle missing errors in snd_pcm_oss_change_params*()
cifs: Fix crash on unload of cifs_arc4.ko
scsi: qla2xxx: Format log strings only if needed
btrfs: clear extent buffer uptodate when we fail to write it
btrfs: fix re-dirty process of tree-log nodes
btrfs: replace the BUG_ON in btrfs_del_root_ref with proper error handling
btrfs: free exchange changeset on failures
perf intel-pt: Fix some PGE (packet generation enable/control flow packets) usage
perf intel-pt: Fix sync state when a PSB (synchronization) packet is found
perf intel-pt: Fix intel_pt_fup_event() assumptions about setting state type
perf intel-pt: Fix state setting when receiving overflow (OVF) packet
perf intel-pt: Fix next 'err' value, walking trace
perf intel-pt: Fix missing 'instruction' events with 'q' option
perf intel-pt: Fix error timestamp setting on the decoder error path
md: fix update super 1.0 on rdev size change
nfsd: fix use-after-free due to delegation race
nfsd: Fix nsfd startup race (again)
tracefs: Have new files inherit the ownership of their parent
selftests: KVM: avoid failures due to reserved HyperTransport region
hwmon: (pwm-fan) Ensure the fan going on in .probe()
mmc: renesas_sdhi: initialize variable properly when tuning
clk: qcom: regmap-mux: fix parent clock lookup
thermal: int340x: Fix VCoRefLow MMIO bit offset for TGL
drm/syncobj: Deal with signalled fences in drm_syncobj_find_fence.
libata: add horkage for ASMedia 1092
io_uring: ensure task_work gets run as part of cancelations
wait: add wake_up_pollfree()
binder: use wake_up_pollfree()
signalfd: use wake_up_pollfree()
aio: keep poll requests on waitqueue until completed
aio: fix use-after-free due to missing POLLFREE handling
tracefs: Set all files to the same group ownership as the mount option
i2c: mpc: Use atomic read and fix break condition
block: fix ioprio_get(IOPRIO_WHO_PGRP) vs setuid(2)
scsi: pm80xx: Do not call scsi_remove_host() in pm8001_alloc()
scsi: scsi_debug: Fix buffer size of REPORT ZONES command
ALSA: usb-audio: Reorder snd_djm_devices[] entries
qede: validate non LSO skb length
PM: runtime: Fix pm_runtime_active() kerneldoc comment
ASoC: rt5682: Fix crash due to out of scope stack vars
ASoC: qdsp6: q6routing: Fix return value from msm_routing_put_audio_mixer
ASoC: codecs: wsa881x: fix return values from kcontrol put
ASoC: codecs: wcd934x: handle channel mappping list correctly
ASoC: codecs: wcd934x: return correct value from mixer put
RDMA/hns: Do not halt commands during reset until later
RDMA/hns: Do not destroy QP resources in the hw resetting phase
hwmon: (dell-smm) Fix warning on /proc/i8k creation error
clk: imx: use module_platform_driver
clk: qcom: clk-alpha-pll: Don't reconfigure running Trion
i40e: Fix failed opcode appearing if handling messages from VF
i40e: Fix pre-set max number of queues for VF
mtd: rawnand: fsmc: Take instruction delay into account
mtd: rawnand: fsmc: Fix timing computation
bpf, sockmap: Re-evaluate proto ops when psock is removed from sockmap
i40e: Fix NULL pointer dereference in i40e_dbg_dump_desc
Revert "PCI: aardvark: Fix support for PCI_ROM_ADDRESS1 on emulated bridge"
drm/amd/display: Fix DPIA outbox timeout after S3/S4/reset
perf tools: Fix SMT detection fast read path
Documentation/locking/locktypes: Update migrate_disable() bits.
dt-bindings: net: Reintroduce PHY no lane swap binding
tools build: Remove needless libpython-version feature check that breaks test-all fast path
net: cdc_ncm: Allow for dwNtbOutMaxSize to be unset or zero
net: altera: set a couple error code in probe()
net: fec: only clear interrupt of handling queue in fec_enet_rx_queue()
net, neigh: clear whole pneigh_entry at alloc time
net/qla3xxx: fix an error code in ql_adapter_up()
selftests/fib_tests: Rework fib_rp_filter_test()
USB: gadget: detect too-big endpoint 0 requests
USB: gadget: zero allocate endpoint 0 buffers
Revert "usb: dwc3: dwc3-qcom: Enable tx-fifo-resize property by default"
usb: core: config: fix validation of wMaxPacketValue entries
xhci: Remove CONFIG_USB_DEFAULT_PERSIST to prevent xHCI from runtime suspending
usb: core: config: using bit mask instead of individual bits
xhci: avoid race between disable slot command and host runtime suspend
iio: gyro: adxrs290: fix data signedness
iio: trigger: Fix reference counting
iio: trigger: stm32-timer: fix MODULE_ALIAS
iio: stk3310: Don't return error code in interrupt handler
iio: mma8452: Fix trigger reference couting
iio: ltr501: Don't return error code in trigger handler
iio: kxsd9: Don't return error code in trigger handler
iio: itg3200: Call iio_trigger_notify_done() on error
iio: dln2-adc: Fix lockdep complaint
iio: dln2: Check return value of devm_iio_trigger_register()
iio: at91-sama5d2: Fix incorrect sign extension
iio: adc: stm32: fix a current leak by resetting pcsel before disabling vdda
iio: adc: axp20x_adc: fix charging current reporting on AXP22x
iio: ad7768-1: Call iio_trigger_notify_done() on error
iio: accel: kxcjk-1013: Fix possible memory leak in probe and remove
misc: rtsx: Avoid mangling IRQ during runtime PM
nvmem: eeprom: at25: fix FRAM byte_len
bus: mhi: pci_generic: Fix device recovery failed issue
bus: mhi: core: Add support for forced PM resume
csky: fix typo of fpu config macro
irqchip/aspeed-scu: Replace update_bits with write_bits.
irqchip/armada-370-xp: Fix return value of armada_370_xp_msi_alloc()
irqchip/armada-370-xp: Fix support for Multi-MSI interrupts
aio: Fix incorrect usage of eventfd_signal_allowed()
irqchip/irq-gic-v3-its.c: Force synchronisation when issuing INVALL
irqchip: nvic: Fix offset for Interrupt Priority Offsets
misc: fastrpc: fix improper packet size calculation
clocksource/drivers/dw_apb_timer_of: Fix probe failure
bpf: Add selftests to cover packet access corner cases
Linux 5.15.8
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Change-Id: I4d543d6826c20e322ce477fe82c462791dc36ce4
This commit is contained in:
@@ -91,6 +91,14 @@ properties:
|
||||
compensate for the board being designed with the lanes
|
||||
swapped.
|
||||
|
||||
enet-phy-lane-no-swap:
|
||||
$ref: /schemas/types.yaml#/definitions/flag
|
||||
description:
|
||||
If set, indicates that PHY will disable swap of the
|
||||
TX/RX lanes. This property allows the PHY to work correcly after
|
||||
e.g. wrong bootstrap configuration caused by issues in PCB
|
||||
layout design.
|
||||
|
||||
eee-broken-100tx:
|
||||
$ref: /schemas/types.yaml#/definitions/flag
|
||||
description:
|
||||
|
||||
@@ -439,11 +439,9 @@ preemption. The following substitution works on both kernels::
|
||||
spin_lock(&p->lock);
|
||||
p->count += this_cpu_read(var2);
|
||||
|
||||
On a non-PREEMPT_RT kernel migrate_disable() maps to preempt_disable()
|
||||
which makes the above code fully equivalent. On a PREEMPT_RT kernel
|
||||
migrate_disable() ensures that the task is pinned on the current CPU which
|
||||
in turn guarantees that the per-CPU access to var1 and var2 are staying on
|
||||
the same CPU.
|
||||
the same CPU while the task remains preemptible.
|
||||
|
||||
The migrate_disable() substitution is not valid for the following
|
||||
scenario::
|
||||
@@ -456,9 +454,8 @@ scenario::
|
||||
p = this_cpu_ptr(&var1);
|
||||
p->val = func2();
|
||||
|
||||
While correct on a non-PREEMPT_RT kernel, this breaks on PREEMPT_RT because
|
||||
here migrate_disable() does not protect against reentrancy from a
|
||||
preempting task. A correct substitution for this case is::
|
||||
This breaks because migrate_disable() does not protect against reentrancy from
|
||||
a preempting task. A correct substitution for this case is::
|
||||
|
||||
func()
|
||||
{
|
||||
|
||||
2
Makefile
2
Makefile
@@ -1,7 +1,7 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
VERSION = 5
|
||||
PATCHLEVEL = 15
|
||||
SUBLEVEL = 7
|
||||
SUBLEVEL = 8
|
||||
EXTRAVERSION =
|
||||
NAME = Trick or Treat
|
||||
|
||||
|
||||
@@ -209,7 +209,7 @@ asmlinkage void do_trap_illinsn(struct pt_regs *regs)
|
||||
|
||||
asmlinkage void do_trap_fpe(struct pt_regs *regs)
|
||||
{
|
||||
#ifdef CONFIG_CPU_HAS_FP
|
||||
#ifdef CONFIG_CPU_HAS_FPU
|
||||
return fpu_fpe(regs);
|
||||
#else
|
||||
do_trap_error(regs, SIGILL, ILL_ILLOPC, regs->pc,
|
||||
@@ -219,7 +219,7 @@ asmlinkage void do_trap_fpe(struct pt_regs *regs)
|
||||
|
||||
asmlinkage void do_trap_priv(struct pt_regs *regs)
|
||||
{
|
||||
#ifdef CONFIG_CPU_HAS_FP
|
||||
#ifdef CONFIG_CPU_HAS_FPU
|
||||
if (user_mode(regs) && fpu_libc_helper(regs))
|
||||
return;
|
||||
#endif
|
||||
|
||||
@@ -1919,6 +1919,7 @@ config EFI
|
||||
depends on ACPI
|
||||
select UCS2_STRING
|
||||
select EFI_RUNTIME_WRAPPERS
|
||||
select ARCH_USE_MEMREMAP_PROT
|
||||
help
|
||||
This enables the kernel to use EFI runtime services that are
|
||||
available (such as the EFI variable services).
|
||||
|
||||
@@ -98,7 +98,7 @@
|
||||
KVM_ARCH_REQ_FLAGS(25, KVM_REQUEST_WAIT | KVM_REQUEST_NO_WAKEUP)
|
||||
#define KVM_REQ_TLB_FLUSH_CURRENT KVM_ARCH_REQ(26)
|
||||
#define KVM_REQ_TLB_FLUSH_GUEST \
|
||||
KVM_ARCH_REQ_FLAGS(27, KVM_REQUEST_NO_WAKEUP)
|
||||
KVM_ARCH_REQ_FLAGS(27, KVM_REQUEST_WAIT | KVM_REQUEST_NO_WAKEUP)
|
||||
#define KVM_REQ_APF_READY KVM_ARCH_REQ(28)
|
||||
#define KVM_REQ_MSR_FILTER_CHANGED KVM_ARCH_REQ(29)
|
||||
#define KVM_REQ_UPDATE_CPU_DIRTY_LOGGING \
|
||||
|
||||
@@ -1922,11 +1922,13 @@ static u64 kvm_hv_send_ipi(struct kvm_vcpu *vcpu, struct kvm_hv_hcall *hc, bool
|
||||
|
||||
all_cpus = send_ipi_ex.vp_set.format == HV_GENERIC_SET_ALL;
|
||||
|
||||
if (all_cpus)
|
||||
goto check_and_send_ipi;
|
||||
|
||||
if (!sparse_banks_len)
|
||||
goto ret_success;
|
||||
|
||||
if (!all_cpus &&
|
||||
kvm_read_guest(kvm,
|
||||
if (kvm_read_guest(kvm,
|
||||
hc->ingpa + offsetof(struct hv_send_ipi_ex,
|
||||
vp_set.bank_contents),
|
||||
sparse_banks,
|
||||
@@ -1934,6 +1936,7 @@ static u64 kvm_hv_send_ipi(struct kvm_vcpu *vcpu, struct kvm_hv_hcall *hc, bool
|
||||
return HV_STATUS_INVALID_HYPERCALL_INPUT;
|
||||
}
|
||||
|
||||
check_and_send_ipi:
|
||||
if ((vector < HV_IPI_LOW_VECTOR) || (vector > HV_IPI_HIGH_VECTOR))
|
||||
return HV_STATUS_INVALID_HYPERCALL_INPUT;
|
||||
|
||||
|
||||
@@ -7021,7 +7021,13 @@ static int emulator_pio_in(struct kvm_vcpu *vcpu, int size,
|
||||
unsigned short port, void *val, unsigned int count)
|
||||
{
|
||||
if (vcpu->arch.pio.count) {
|
||||
/* Complete previous iteration. */
|
||||
/*
|
||||
* Complete a previous iteration that required userspace I/O.
|
||||
* Note, @count isn't guaranteed to match pio.count as userspace
|
||||
* can modify ECX before rerunning the vCPU. Ignore any such
|
||||
* shenanigans as KVM doesn't support modifying the rep count,
|
||||
* and the emulator ensures @count doesn't overflow the buffer.
|
||||
*/
|
||||
} else {
|
||||
int r = __emulator_pio_in(vcpu, size, port, count);
|
||||
if (!r)
|
||||
@@ -7030,7 +7036,6 @@ static int emulator_pio_in(struct kvm_vcpu *vcpu, int size,
|
||||
/* Results already available, fall through. */
|
||||
}
|
||||
|
||||
WARN_ON(count != vcpu->arch.pio.count);
|
||||
complete_emulator_pio_in(vcpu, val);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -277,7 +277,8 @@ void __init efi_arch_mem_reserve(phys_addr_t addr, u64 size)
|
||||
return;
|
||||
}
|
||||
|
||||
new = early_memremap(data.phys_map, data.size);
|
||||
new = early_memremap_prot(data.phys_map, data.size,
|
||||
pgprot_val(pgprot_encrypted(FIXMAP_PAGE_NORMAL)));
|
||||
if (!new) {
|
||||
pr_err("Failed to map new boot services memmap\n");
|
||||
return;
|
||||
|
||||
@@ -220,6 +220,7 @@ SYSCALL_DEFINE2(ioprio_get, int, which, int, who)
|
||||
pgrp = task_pgrp(current);
|
||||
else
|
||||
pgrp = find_vpid(who);
|
||||
read_lock(&tasklist_lock);
|
||||
do_each_pid_thread(pgrp, PIDTYPE_PGID, p) {
|
||||
tmpio = get_task_ioprio(p);
|
||||
if (tmpio < 0)
|
||||
@@ -229,6 +230,8 @@ SYSCALL_DEFINE2(ioprio_get, int, which, int, who)
|
||||
else
|
||||
ret = ioprio_best(ret, tmpio);
|
||||
} while_each_pid_thread(pgrp, PIDTYPE_PGID, p);
|
||||
read_unlock(&tasklist_lock);
|
||||
|
||||
break;
|
||||
case IOPRIO_WHO_USER:
|
||||
uid = make_kuid(current_user_ns(), who);
|
||||
|
||||
@@ -4579,23 +4579,20 @@ static int binder_thread_release(struct binder_proc *proc,
|
||||
__release(&t->lock);
|
||||
|
||||
/*
|
||||
* If this thread used poll, make sure we remove the waitqueue
|
||||
* from any epoll data structures holding it with POLLFREE.
|
||||
* waitqueue_active() is safe to use here because we're holding
|
||||
* the inner lock.
|
||||
* If this thread used poll, make sure we remove the waitqueue from any
|
||||
* poll data structures holding it.
|
||||
*/
|
||||
if ((thread->looper & BINDER_LOOPER_STATE_POLL) &&
|
||||
waitqueue_active(&thread->wait)) {
|
||||
wake_up_poll(&thread->wait, EPOLLHUP | POLLFREE);
|
||||
}
|
||||
if (thread->looper & BINDER_LOOPER_STATE_POLL)
|
||||
wake_up_pollfree(&thread->wait);
|
||||
|
||||
binder_inner_proc_unlock(thread->proc);
|
||||
|
||||
/*
|
||||
* This is needed to avoid races between wake_up_poll() above and
|
||||
* and ep_remove_waitqueue() called for other reasons (eg the epoll file
|
||||
* descriptor being closed); ep_remove_waitqueue() holds an RCU read
|
||||
* lock, so we can be sure it's done after calling synchronize_rcu().
|
||||
* This is needed to avoid races between wake_up_pollfree() above and
|
||||
* someone else removing the last entry from the queue for other reasons
|
||||
* (e.g. ep_remove_wait_queue() being called due to an epoll file
|
||||
* descriptor being closed). Such other users hold an RCU read lock, so
|
||||
* we can be sure they're done after we call synchronize_rcu().
|
||||
*/
|
||||
if (thread->looper & BINDER_LOOPER_STATE_POLL)
|
||||
synchronize_rcu();
|
||||
|
||||
@@ -3856,6 +3856,8 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
|
||||
{ "VRFDFC22048UCHC-TE*", NULL, ATA_HORKAGE_NODMA },
|
||||
/* Odd clown on sil3726/4726 PMPs */
|
||||
{ "Config Disk", NULL, ATA_HORKAGE_DISABLE },
|
||||
/* Similar story with ASMedia 1092 */
|
||||
{ "ASMT109x- Config", NULL, ATA_HORKAGE_DISABLE },
|
||||
|
||||
/* Weird ATAPI devices */
|
||||
{ "TORiSAN DVD-ROM DRD-N216", NULL, ATA_HORKAGE_MAX_SEC_128 },
|
||||
|
||||
@@ -881,7 +881,7 @@ int mhi_pm_suspend(struct mhi_controller *mhi_cntrl)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mhi_pm_suspend);
|
||||
|
||||
int mhi_pm_resume(struct mhi_controller *mhi_cntrl)
|
||||
static int __mhi_pm_resume(struct mhi_controller *mhi_cntrl, bool force)
|
||||
{
|
||||
struct mhi_chan *itr, *tmp;
|
||||
struct device *dev = &mhi_cntrl->mhi_dev->dev;
|
||||
@@ -898,8 +898,12 @@ int mhi_pm_resume(struct mhi_controller *mhi_cntrl)
|
||||
if (MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state))
|
||||
return -EIO;
|
||||
|
||||
if (mhi_get_mhi_state(mhi_cntrl) != MHI_STATE_M3)
|
||||
return -EINVAL;
|
||||
if (mhi_get_mhi_state(mhi_cntrl) != MHI_STATE_M3) {
|
||||
dev_warn(dev, "Resuming from non M3 state (%s)\n",
|
||||
TO_MHI_STATE_STR(mhi_get_mhi_state(mhi_cntrl)));
|
||||
if (!force)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Notify clients about exiting LPM */
|
||||
list_for_each_entry_safe(itr, tmp, &mhi_cntrl->lpm_chans, node) {
|
||||
@@ -940,8 +944,19 @@ int mhi_pm_resume(struct mhi_controller *mhi_cntrl)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mhi_pm_resume(struct mhi_controller *mhi_cntrl)
|
||||
{
|
||||
return __mhi_pm_resume(mhi_cntrl, false);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mhi_pm_resume);
|
||||
|
||||
int mhi_pm_resume_force(struct mhi_controller *mhi_cntrl)
|
||||
{
|
||||
return __mhi_pm_resume(mhi_cntrl, true);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mhi_pm_resume_force);
|
||||
|
||||
int __mhi_device_get_sync(struct mhi_controller *mhi_cntrl)
|
||||
{
|
||||
int ret;
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
#define MHI_PCI_DEFAULT_BAR_NUM 0
|
||||
|
||||
#define MHI_POST_RESET_DELAY_MS 500
|
||||
#define MHI_POST_RESET_DELAY_MS 2000
|
||||
|
||||
#define HEALTH_CHECK_PERIOD (HZ * 2)
|
||||
|
||||
|
||||
@@ -370,7 +370,7 @@ static struct platform_driver imx8qxp_lpcg_clk_driver = {
|
||||
.probe = imx8qxp_lpcg_clk_probe,
|
||||
};
|
||||
|
||||
builtin_platform_driver(imx8qxp_lpcg_clk_driver);
|
||||
module_platform_driver(imx8qxp_lpcg_clk_driver);
|
||||
|
||||
MODULE_AUTHOR("Aisheng Dong <aisheng.dong@nxp.com>");
|
||||
MODULE_DESCRIPTION("NXP i.MX8QXP LPCG clock driver");
|
||||
|
||||
@@ -308,7 +308,7 @@ static struct platform_driver imx8qxp_clk_driver = {
|
||||
},
|
||||
.probe = imx8qxp_clk_probe,
|
||||
};
|
||||
builtin_platform_driver(imx8qxp_clk_driver);
|
||||
module_platform_driver(imx8qxp_clk_driver);
|
||||
|
||||
MODULE_AUTHOR("Aisheng Dong <aisheng.dong@nxp.com>");
|
||||
MODULE_DESCRIPTION("NXP i.MX8QXP clock driver");
|
||||
|
||||
@@ -1429,6 +1429,15 @@ EXPORT_SYMBOL_GPL(clk_alpha_pll_postdiv_fabia_ops);
|
||||
void clk_trion_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
|
||||
const struct alpha_pll_config *config)
|
||||
{
|
||||
/*
|
||||
* If the bootloader left the PLL enabled it's likely that there are
|
||||
* RCGs that will lock up if we disable the PLL below.
|
||||
*/
|
||||
if (trion_pll_is_enabled(pll, regmap)) {
|
||||
pr_debug("Trion PLL is already enabled, skipping configuration\n");
|
||||
return;
|
||||
}
|
||||
|
||||
clk_alpha_pll_write_config(regmap, PLL_L_VAL(pll), config->l);
|
||||
regmap_write(regmap, PLL_CAL_L_VAL(pll), TRION_PLL_CAL_VAL);
|
||||
clk_alpha_pll_write_config(regmap, PLL_ALPHA_VAL(pll), config->alpha);
|
||||
|
||||
@@ -28,7 +28,7 @@ static u8 mux_get_parent(struct clk_hw *hw)
|
||||
val &= mask;
|
||||
|
||||
if (mux->parent_map)
|
||||
return qcom_find_src_index(hw, mux->parent_map, val);
|
||||
return qcom_find_cfg_index(hw, mux->parent_map, val);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
@@ -69,6 +69,18 @@ int qcom_find_src_index(struct clk_hw *hw, const struct parent_map *map, u8 src)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(qcom_find_src_index);
|
||||
|
||||
int qcom_find_cfg_index(struct clk_hw *hw, const struct parent_map *map, u8 cfg)
|
||||
{
|
||||
int i, num_parents = clk_hw_get_num_parents(hw);
|
||||
|
||||
for (i = 0; i < num_parents; i++)
|
||||
if (cfg == map[i].cfg)
|
||||
return i;
|
||||
|
||||
return -ENOENT;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(qcom_find_cfg_index);
|
||||
|
||||
struct regmap *
|
||||
qcom_cc_map(struct platform_device *pdev, const struct qcom_cc_desc *desc)
|
||||
{
|
||||
|
||||
@@ -49,6 +49,8 @@ extern void
|
||||
qcom_pll_set_fsm_mode(struct regmap *m, u32 reg, u8 bias_count, u8 lock_count);
|
||||
extern int qcom_find_src_index(struct clk_hw *hw, const struct parent_map *map,
|
||||
u8 src);
|
||||
extern int qcom_find_cfg_index(struct clk_hw *hw, const struct parent_map *map,
|
||||
u8 cfg);
|
||||
|
||||
extern int qcom_cc_register_board_clk(struct device *dev, const char *path,
|
||||
const char *name, unsigned long rate);
|
||||
|
||||
@@ -47,7 +47,7 @@ static int __init timer_get_base_and_rate(struct device_node *np,
|
||||
pr_warn("pclk for %pOFn is present, but could not be activated\n",
|
||||
np);
|
||||
|
||||
if (!of_property_read_u32(np, "clock-freq", rate) &&
|
||||
if (!of_property_read_u32(np, "clock-freq", rate) ||
|
||||
!of_property_read_u32(np, "clock-frequency", rate))
|
||||
return 0;
|
||||
|
||||
|
||||
@@ -2213,7 +2213,8 @@ static int dm_resume(void *handle)
|
||||
if (amdgpu_in_reset(adev)) {
|
||||
dc_state = dm->cached_dc_state;
|
||||
|
||||
amdgpu_dm_outbox_init(adev);
|
||||
if (dc_enable_dmub_notifications(adev->dm.dc))
|
||||
amdgpu_dm_outbox_init(adev);
|
||||
|
||||
r = dm_dmub_hw_init(adev);
|
||||
if (r)
|
||||
@@ -2262,6 +2263,10 @@ static int dm_resume(void *handle)
|
||||
/* TODO: Remove dc_state->dccg, use dc->dccg directly. */
|
||||
dc_resource_state_construct(dm->dc, dm_state->context);
|
||||
|
||||
/* Re-enable outbox interrupts for DPIA. */
|
||||
if (dc_enable_dmub_notifications(adev->dm.dc))
|
||||
amdgpu_dm_outbox_init(adev);
|
||||
|
||||
/* Before powering on DC we need to re-initialize DMUB. */
|
||||
r = dm_dmub_hw_init(adev);
|
||||
if (r)
|
||||
|
||||
@@ -404,8 +404,17 @@ int drm_syncobj_find_fence(struct drm_file *file_private,
|
||||
|
||||
if (*fence) {
|
||||
ret = dma_fence_chain_find_seqno(fence, point);
|
||||
if (!ret)
|
||||
if (!ret) {
|
||||
/* If the requested seqno is already signaled
|
||||
* drm_syncobj_find_fence may return a NULL
|
||||
* fence. To make sure the recipient gets
|
||||
* signalled, use a new fence instead.
|
||||
*/
|
||||
if (!*fence)
|
||||
*fence = dma_fence_get_stub();
|
||||
|
||||
goto out;
|
||||
}
|
||||
dma_fence_put(*fence);
|
||||
} else {
|
||||
ret = -EINVAL;
|
||||
|
||||
@@ -207,14 +207,14 @@ config HID_CHERRY
|
||||
|
||||
config HID_CHICONY
|
||||
tristate "Chicony devices"
|
||||
depends on HID
|
||||
depends on USB_HID
|
||||
default !EXPERT
|
||||
help
|
||||
Support for Chicony Tactical pad and special keys on Chicony keyboards.
|
||||
|
||||
config HID_CORSAIR
|
||||
tristate "Corsair devices"
|
||||
depends on HID && USB && LEDS_CLASS
|
||||
depends on USB_HID && LEDS_CLASS
|
||||
help
|
||||
Support for Corsair devices that are not fully compliant with the
|
||||
HID standard.
|
||||
@@ -245,7 +245,7 @@ config HID_MACALLY
|
||||
|
||||
config HID_PRODIKEYS
|
||||
tristate "Prodikeys PC-MIDI Keyboard support"
|
||||
depends on HID && SND
|
||||
depends on USB_HID && SND
|
||||
select SND_RAWMIDI
|
||||
help
|
||||
Support for Prodikeys PC-MIDI Keyboard device support.
|
||||
@@ -553,7 +553,7 @@ config HID_LENOVO
|
||||
|
||||
config HID_LOGITECH
|
||||
tristate "Logitech devices"
|
||||
depends on HID
|
||||
depends on USB_HID
|
||||
depends on LEDS_CLASS
|
||||
default !EXPERT
|
||||
help
|
||||
@@ -930,7 +930,7 @@ config HID_SAITEK
|
||||
|
||||
config HID_SAMSUNG
|
||||
tristate "Samsung InfraRed remote control or keyboards"
|
||||
depends on HID
|
||||
depends on USB_HID
|
||||
help
|
||||
Support for Samsung InfraRed remote control or keyboards.
|
||||
|
||||
|
||||
@@ -1028,8 +1028,7 @@ static int asus_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
||||
if (drvdata->quirks & QUIRK_IS_MULTITOUCH)
|
||||
drvdata->tp = &asus_i2c_tp;
|
||||
|
||||
if ((drvdata->quirks & QUIRK_T100_KEYBOARD) &&
|
||||
hid_is_using_ll_driver(hdev, &usb_hid_driver)) {
|
||||
if ((drvdata->quirks & QUIRK_T100_KEYBOARD) && hid_is_usb(hdev)) {
|
||||
struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
|
||||
|
||||
if (intf->altsetting->desc.bInterfaceNumber == T100_TPAD_INTF) {
|
||||
@@ -1057,8 +1056,7 @@ static int asus_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
||||
drvdata->tp = &asus_t100chi_tp;
|
||||
}
|
||||
|
||||
if ((drvdata->quirks & QUIRK_MEDION_E1239T) &&
|
||||
hid_is_using_ll_driver(hdev, &usb_hid_driver)) {
|
||||
if ((drvdata->quirks & QUIRK_MEDION_E1239T) && hid_is_usb(hdev)) {
|
||||
struct usb_host_interface *alt =
|
||||
to_usb_interface(hdev->dev.parent)->altsetting;
|
||||
|
||||
|
||||
@@ -191,7 +191,7 @@ static void bigben_worker(struct work_struct *work)
|
||||
struct bigben_device, worker);
|
||||
struct hid_field *report_field = bigben->report->field[0];
|
||||
|
||||
if (bigben->removed)
|
||||
if (bigben->removed || !report_field)
|
||||
return;
|
||||
|
||||
if (bigben->work_led) {
|
||||
|
||||
@@ -114,6 +114,9 @@ static int ch_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!hid_is_usb(hdev))
|
||||
return -EINVAL;
|
||||
|
||||
hdev->quirks |= HID_QUIRK_INPUT_PER_APP;
|
||||
ret = hid_parse(hdev);
|
||||
if (ret) {
|
||||
|
||||
@@ -553,7 +553,12 @@ static int corsair_probe(struct hid_device *dev, const struct hid_device_id *id)
|
||||
int ret;
|
||||
unsigned long quirks = id->driver_data;
|
||||
struct corsair_drvdata *drvdata;
|
||||
struct usb_interface *usbif = to_usb_interface(dev->dev.parent);
|
||||
struct usb_interface *usbif;
|
||||
|
||||
if (!hid_is_usb(dev))
|
||||
return -EINVAL;
|
||||
|
||||
usbif = to_usb_interface(dev->dev.parent);
|
||||
|
||||
drvdata = devm_kzalloc(&dev->dev, sizeof(struct corsair_drvdata),
|
||||
GFP_KERNEL);
|
||||
|
||||
@@ -50,7 +50,7 @@ struct elan_drvdata {
|
||||
|
||||
static int is_not_elan_touchpad(struct hid_device *hdev)
|
||||
{
|
||||
if (hdev->bus == BUS_USB) {
|
||||
if (hid_is_usb(hdev)) {
|
||||
struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
|
||||
|
||||
return (intf->altsetting->desc.bInterfaceNumber !=
|
||||
|
||||
@@ -230,6 +230,9 @@ static int elo_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
||||
int ret;
|
||||
struct usb_device *udev;
|
||||
|
||||
if (!hid_is_usb(hdev))
|
||||
return -EINVAL;
|
||||
|
||||
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -915,6 +915,9 @@ static int ft260_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
||||
struct ft260_get_chip_version_report version;
|
||||
int ret;
|
||||
|
||||
if (!hid_is_usb(hdev))
|
||||
return -EINVAL;
|
||||
|
||||
dev = devm_kzalloc(&hdev->dev, sizeof(*dev), GFP_KERNEL);
|
||||
if (!dev)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -585,6 +585,8 @@ static void hammer_remove(struct hid_device *hdev)
|
||||
static const struct hid_device_id hammer_devices[] = {
|
||||
{ HID_DEVICE(BUS_USB, HID_GROUP_GENERIC,
|
||||
USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_DON) },
|
||||
{ HID_DEVICE(BUS_USB, HID_GROUP_GENERIC,
|
||||
USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_EEL) },
|
||||
{ HID_DEVICE(BUS_USB, HID_GROUP_GENERIC,
|
||||
USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_HAMMER) },
|
||||
{ HID_DEVICE(BUS_USB, HID_GROUP_GENERIC,
|
||||
|
||||
@@ -140,12 +140,17 @@ static int holtek_kbd_input_event(struct input_dev *dev, unsigned int type,
|
||||
static int holtek_kbd_probe(struct hid_device *hdev,
|
||||
const struct hid_device_id *id)
|
||||
{
|
||||
struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
|
||||
int ret = hid_parse(hdev);
|
||||
struct usb_interface *intf;
|
||||
int ret;
|
||||
|
||||
if (!hid_is_usb(hdev))
|
||||
return -EINVAL;
|
||||
|
||||
ret = hid_parse(hdev);
|
||||
if (!ret)
|
||||
ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
|
||||
|
||||
intf = to_usb_interface(hdev->dev.parent);
|
||||
if (!ret && intf->cur_altsetting->desc.bInterfaceNumber == 1) {
|
||||
struct hid_input *hidinput;
|
||||
list_for_each_entry(hidinput, &hdev->inputs, list) {
|
||||
|
||||
@@ -62,6 +62,14 @@ static __u8 *holtek_mouse_report_fixup(struct hid_device *hdev, __u8 *rdesc,
|
||||
return rdesc;
|
||||
}
|
||||
|
||||
static int holtek_mouse_probe(struct hid_device *hdev,
|
||||
const struct hid_device_id *id)
|
||||
{
|
||||
if (!hid_is_usb(hdev))
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct hid_device_id holtek_mouse_devices[] = {
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT,
|
||||
USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A067) },
|
||||
@@ -83,6 +91,7 @@ static struct hid_driver holtek_mouse_driver = {
|
||||
.name = "holtek_mouse",
|
||||
.id_table = holtek_mouse_devices,
|
||||
.report_fixup = holtek_mouse_report_fixup,
|
||||
.probe = holtek_mouse_probe,
|
||||
};
|
||||
|
||||
module_hid_driver(holtek_mouse_driver);
|
||||
|
||||
@@ -394,6 +394,7 @@
|
||||
#define USB_DEVICE_ID_HP_X2 0x074d
|
||||
#define USB_DEVICE_ID_HP_X2_10_COVER 0x0755
|
||||
#define I2C_DEVICE_ID_HP_SPECTRE_X360_15 0x2817
|
||||
#define USB_DEVICE_ID_ASUS_UX550VE_TOUCHSCREEN 0x2544
|
||||
#define USB_DEVICE_ID_ASUS_UX550_TOUCHSCREEN 0x2706
|
||||
#define I2C_DEVICE_ID_SURFACE_GO_TOUCHSCREEN 0x261A
|
||||
|
||||
@@ -496,6 +497,7 @@
|
||||
#define USB_DEVICE_ID_GOOGLE_MAGNEMITE 0x503d
|
||||
#define USB_DEVICE_ID_GOOGLE_MOONBALL 0x5044
|
||||
#define USB_DEVICE_ID_GOOGLE_DON 0x5050
|
||||
#define USB_DEVICE_ID_GOOGLE_EEL 0x5057
|
||||
|
||||
#define USB_VENDOR_ID_GOTOP 0x08f2
|
||||
#define USB_DEVICE_ID_SUPER_Q2 0x007f
|
||||
@@ -881,6 +883,7 @@
|
||||
#define USB_DEVICE_ID_MS_TOUCH_COVER_2 0x07a7
|
||||
#define USB_DEVICE_ID_MS_TYPE_COVER_2 0x07a9
|
||||
#define USB_DEVICE_ID_MS_POWER_COVER 0x07da
|
||||
#define USB_DEVICE_ID_MS_SURFACE3_COVER 0x07de
|
||||
#define USB_DEVICE_ID_MS_XBOX_ONE_S_CONTROLLER 0x02fd
|
||||
#define USB_DEVICE_ID_MS_PIXART_MOUSE 0x00cb
|
||||
#define USB_DEVICE_ID_8BITDO_SN30_PRO_PLUS 0x02e0
|
||||
|
||||
@@ -325,6 +325,8 @@ static const struct hid_device_id hid_battery_quirks[] = {
|
||||
HID_BATTERY_QUIRK_IGNORE },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ASUS_UX550_TOUCHSCREEN),
|
||||
HID_BATTERY_QUIRK_IGNORE },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ASUS_UX550VE_TOUCHSCREEN),
|
||||
HID_BATTERY_QUIRK_IGNORE },
|
||||
{ HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_HP_SPECTRE_X360_15),
|
||||
HID_BATTERY_QUIRK_IGNORE },
|
||||
{ HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_SURFACE_GO_TOUCHSCREEN),
|
||||
|
||||
@@ -749,12 +749,18 @@ static int lg_raw_event(struct hid_device *hdev, struct hid_report *report,
|
||||
|
||||
static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
||||
{
|
||||
struct usb_interface *iface = to_usb_interface(hdev->dev.parent);
|
||||
__u8 iface_num = iface->cur_altsetting->desc.bInterfaceNumber;
|
||||
struct usb_interface *iface;
|
||||
__u8 iface_num;
|
||||
unsigned int connect_mask = HID_CONNECT_DEFAULT;
|
||||
struct lg_drv_data *drv_data;
|
||||
int ret;
|
||||
|
||||
if (!hid_is_usb(hdev))
|
||||
return -EINVAL;
|
||||
|
||||
iface = to_usb_interface(hdev->dev.parent);
|
||||
iface_num = iface->cur_altsetting->desc.bInterfaceNumber;
|
||||
|
||||
/* G29 only work with the 1st interface */
|
||||
if ((hdev->product == USB_DEVICE_ID_LOGITECH_G29_WHEEL) &&
|
||||
(iface_num != 0)) {
|
||||
|
||||
@@ -1777,7 +1777,7 @@ static int logi_dj_probe(struct hid_device *hdev,
|
||||
case recvr_type_bluetooth: no_dj_interfaces = 2; break;
|
||||
case recvr_type_dinovo: no_dj_interfaces = 2; break;
|
||||
}
|
||||
if (hid_is_using_ll_driver(hdev, &usb_hid_driver)) {
|
||||
if (hid_is_usb(hdev)) {
|
||||
intf = to_usb_interface(hdev->dev.parent);
|
||||
if (intf && intf->altsetting->desc.bInterfaceNumber >=
|
||||
no_dj_interfaces) {
|
||||
|
||||
@@ -798,12 +798,18 @@ static int pk_raw_event(struct hid_device *hdev, struct hid_report *report,
|
||||
static int pk_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
||||
{
|
||||
int ret;
|
||||
struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
|
||||
unsigned short ifnum = intf->cur_altsetting->desc.bInterfaceNumber;
|
||||
struct usb_interface *intf;
|
||||
unsigned short ifnum;
|
||||
unsigned long quirks = id->driver_data;
|
||||
struct pk_device *pk;
|
||||
struct pcmidi_snd *pm = NULL;
|
||||
|
||||
if (!hid_is_usb(hdev))
|
||||
return -EINVAL;
|
||||
|
||||
intf = to_usb_interface(hdev->dev.parent);
|
||||
ifnum = intf->cur_altsetting->desc.bInterfaceNumber;
|
||||
|
||||
pk = kzalloc(sizeof(*pk), GFP_KERNEL);
|
||||
if (pk == NULL) {
|
||||
hid_err(hdev, "can't alloc descriptor\n");
|
||||
|
||||
@@ -124,6 +124,7 @@ static const struct hid_device_id hid_quirks[] = {
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_MCS, USB_DEVICE_ID_MCS_GAMEPADBLOCK), HID_QUIRK_MULTI_INPUT },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PIXART_MOUSE), HID_QUIRK_ALWAYS_POLL },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_POWER_COVER), HID_QUIRK_NO_INIT_REPORTS },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_SURFACE3_COVER), HID_QUIRK_NO_INIT_REPORTS },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_SURFACE_PRO_2), HID_QUIRK_NO_INIT_REPORTS },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TOUCH_COVER_2), HID_QUIRK_NO_INIT_REPORTS },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_2), HID_QUIRK_NO_INIT_REPORTS },
|
||||
|
||||
@@ -344,6 +344,9 @@ static int arvo_probe(struct hid_device *hdev,
|
||||
{
|
||||
int retval;
|
||||
|
||||
if (!hid_is_usb(hdev))
|
||||
return -EINVAL;
|
||||
|
||||
retval = hid_parse(hdev);
|
||||
if (retval) {
|
||||
hid_err(hdev, "parse failed\n");
|
||||
|
||||
@@ -324,6 +324,9 @@ static int isku_probe(struct hid_device *hdev,
|
||||
{
|
||||
int retval;
|
||||
|
||||
if (!hid_is_usb(hdev))
|
||||
return -EINVAL;
|
||||
|
||||
retval = hid_parse(hdev);
|
||||
if (retval) {
|
||||
hid_err(hdev, "parse failed\n");
|
||||
|
||||
@@ -749,6 +749,9 @@ static int kone_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
||||
{
|
||||
int retval;
|
||||
|
||||
if (!hid_is_usb(hdev))
|
||||
return -EINVAL;
|
||||
|
||||
retval = hid_parse(hdev);
|
||||
if (retval) {
|
||||
hid_err(hdev, "parse failed\n");
|
||||
|
||||
@@ -431,6 +431,9 @@ static int koneplus_probe(struct hid_device *hdev,
|
||||
{
|
||||
int retval;
|
||||
|
||||
if (!hid_is_usb(hdev))
|
||||
return -EINVAL;
|
||||
|
||||
retval = hid_parse(hdev);
|
||||
if (retval) {
|
||||
hid_err(hdev, "parse failed\n");
|
||||
|
||||
@@ -133,6 +133,9 @@ static int konepure_probe(struct hid_device *hdev,
|
||||
{
|
||||
int retval;
|
||||
|
||||
if (!hid_is_usb(hdev))
|
||||
return -EINVAL;
|
||||
|
||||
retval = hid_parse(hdev);
|
||||
if (retval) {
|
||||
hid_err(hdev, "parse failed\n");
|
||||
|
||||
@@ -501,6 +501,9 @@ static int kovaplus_probe(struct hid_device *hdev,
|
||||
{
|
||||
int retval;
|
||||
|
||||
if (!hid_is_usb(hdev))
|
||||
return -EINVAL;
|
||||
|
||||
retval = hid_parse(hdev);
|
||||
if (retval) {
|
||||
hid_err(hdev, "parse failed\n");
|
||||
|
||||
@@ -160,6 +160,9 @@ static int lua_probe(struct hid_device *hdev,
|
||||
{
|
||||
int retval;
|
||||
|
||||
if (!hid_is_usb(hdev))
|
||||
return -EINVAL;
|
||||
|
||||
retval = hid_parse(hdev);
|
||||
if (retval) {
|
||||
hid_err(hdev, "parse failed\n");
|
||||
|
||||
@@ -449,6 +449,9 @@ static int pyra_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
||||
{
|
||||
int retval;
|
||||
|
||||
if (!hid_is_usb(hdev))
|
||||
return -EINVAL;
|
||||
|
||||
retval = hid_parse(hdev);
|
||||
if (retval) {
|
||||
hid_err(hdev, "parse failed\n");
|
||||
|
||||
@@ -141,6 +141,9 @@ static int ryos_probe(struct hid_device *hdev,
|
||||
{
|
||||
int retval;
|
||||
|
||||
if (!hid_is_usb(hdev))
|
||||
return -EINVAL;
|
||||
|
||||
retval = hid_parse(hdev);
|
||||
if (retval) {
|
||||
hid_err(hdev, "parse failed\n");
|
||||
|
||||
@@ -113,6 +113,9 @@ static int savu_probe(struct hid_device *hdev,
|
||||
{
|
||||
int retval;
|
||||
|
||||
if (!hid_is_usb(hdev))
|
||||
return -EINVAL;
|
||||
|
||||
retval = hid_parse(hdev);
|
||||
if (retval) {
|
||||
hid_err(hdev, "parse failed\n");
|
||||
|
||||
@@ -152,6 +152,9 @@ static int samsung_probe(struct hid_device *hdev,
|
||||
int ret;
|
||||
unsigned int cmask = HID_CONNECT_DEFAULT;
|
||||
|
||||
if (!hid_is_usb(hdev))
|
||||
return -EINVAL;
|
||||
|
||||
ret = hid_parse(hdev);
|
||||
if (ret) {
|
||||
hid_err(hdev, "parse failed\n");
|
||||
|
||||
@@ -3000,7 +3000,6 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
||||
sc->quirks = quirks;
|
||||
hid_set_drvdata(hdev, sc);
|
||||
sc->hdev = hdev;
|
||||
usbdev = to_usb_device(sc->hdev->dev.parent->parent);
|
||||
|
||||
ret = hid_parse(hdev);
|
||||
if (ret) {
|
||||
@@ -3038,14 +3037,23 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
||||
*/
|
||||
if (!(hdev->claimed & HID_CLAIMED_INPUT)) {
|
||||
hid_err(hdev, "failed to claim input\n");
|
||||
hid_hw_stop(hdev);
|
||||
return -ENODEV;
|
||||
ret = -ENODEV;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (sc->quirks & (GHL_GUITAR_PS3WIIU | GHL_GUITAR_PS4)) {
|
||||
if (!hid_is_usb(hdev)) {
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
usbdev = to_usb_device(sc->hdev->dev.parent->parent);
|
||||
|
||||
sc->ghl_urb = usb_alloc_urb(0, GFP_ATOMIC);
|
||||
if (!sc->ghl_urb)
|
||||
return -ENOMEM;
|
||||
if (!sc->ghl_urb) {
|
||||
ret = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (sc->quirks & GHL_GUITAR_PS3WIIU)
|
||||
ret = ghl_init_urb(sc, usbdev, ghl_ps3wiiu_magic_data,
|
||||
@@ -3055,7 +3063,7 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
||||
ARRAY_SIZE(ghl_ps4_magic_data));
|
||||
if (ret) {
|
||||
hid_err(hdev, "error preparing URB\n");
|
||||
return ret;
|
||||
goto err;
|
||||
}
|
||||
|
||||
timer_setup(&sc->ghl_poke_timer, ghl_magic_poke, 0);
|
||||
@@ -3064,6 +3072,10 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
err:
|
||||
hid_hw_stop(hdev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void sony_remove(struct hid_device *hdev)
|
||||
|
||||
@@ -274,6 +274,9 @@ static int thrustmaster_probe(struct hid_device *hdev, const struct hid_device_i
|
||||
int ret = 0;
|
||||
struct tm_wheel *tm_wheel = 0;
|
||||
|
||||
if (!hid_is_usb(hdev))
|
||||
return -EINVAL;
|
||||
|
||||
ret = hid_parse(hdev);
|
||||
if (ret) {
|
||||
hid_err(hdev, "parse failed with error %d\n", ret);
|
||||
|
||||
@@ -290,7 +290,7 @@ static int u2fzero_probe(struct hid_device *hdev,
|
||||
unsigned int minor;
|
||||
int ret;
|
||||
|
||||
if (!hid_is_using_ll_driver(hdev, &usb_hid_driver))
|
||||
if (!hid_is_usb(hdev))
|
||||
return -EINVAL;
|
||||
|
||||
dev = devm_kzalloc(&hdev->dev, sizeof(*dev), GFP_KERNEL);
|
||||
|
||||
@@ -164,6 +164,9 @@ static int uclogic_probe(struct hid_device *hdev,
|
||||
struct uclogic_drvdata *drvdata = NULL;
|
||||
bool params_initialized = false;
|
||||
|
||||
if (!hid_is_usb(hdev))
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* libinput requires the pad interface to be on a different node
|
||||
* than the pen, so use QUIRK_MULTI_INPUT for all tablets.
|
||||
|
||||
@@ -843,8 +843,7 @@ int uclogic_params_init(struct uclogic_params *params,
|
||||
struct uclogic_params p = {0, };
|
||||
|
||||
/* Check arguments */
|
||||
if (params == NULL || hdev == NULL ||
|
||||
!hid_is_using_ll_driver(hdev, &usb_hid_driver)) {
|
||||
if (params == NULL || hdev == NULL || !hid_is_usb(hdev)) {
|
||||
rc = -EINVAL;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
@@ -266,7 +266,8 @@ static void __maybe_unused ish_resume_handler(struct work_struct *work)
|
||||
|
||||
if (ish_should_leave_d0i3(pdev) && !dev->suspend_flag
|
||||
&& IPC_IS_ISH_ILUP(fwsts)) {
|
||||
disable_irq_wake(pdev->irq);
|
||||
if (device_may_wakeup(&pdev->dev))
|
||||
disable_irq_wake(pdev->irq);
|
||||
|
||||
ish_set_host_ready(dev);
|
||||
|
||||
@@ -337,7 +338,8 @@ static int __maybe_unused ish_suspend(struct device *device)
|
||||
*/
|
||||
pci_save_state(pdev);
|
||||
|
||||
enable_irq_wake(pdev->irq);
|
||||
if (device_may_wakeup(&pdev->dev))
|
||||
enable_irq_wake(pdev->irq);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
|
||||
@@ -726,7 +726,7 @@ static void wacom_retrieve_hid_descriptor(struct hid_device *hdev,
|
||||
* Skip the query for this type and modify defaults based on
|
||||
* interface number.
|
||||
*/
|
||||
if (features->type == WIRELESS) {
|
||||
if (features->type == WIRELESS && intf) {
|
||||
if (intf->cur_altsetting->desc.bInterfaceNumber == 0)
|
||||
features->device_type = WACOM_DEVICETYPE_WL_MONITOR;
|
||||
else
|
||||
@@ -2217,7 +2217,7 @@ static void wacom_update_name(struct wacom *wacom, const char *suffix)
|
||||
if ((features->type == HID_GENERIC) && !strcmp("Wacom HID", features->name)) {
|
||||
char *product_name = wacom->hdev->name;
|
||||
|
||||
if (hid_is_using_ll_driver(wacom->hdev, &usb_hid_driver)) {
|
||||
if (hid_is_usb(wacom->hdev)) {
|
||||
struct usb_interface *intf = to_usb_interface(wacom->hdev->dev.parent);
|
||||
struct usb_device *dev = interface_to_usbdev(intf);
|
||||
product_name = dev->product;
|
||||
@@ -2454,6 +2454,9 @@ static void wacom_wireless_work(struct work_struct *work)
|
||||
|
||||
wacom_destroy_battery(wacom);
|
||||
|
||||
if (!usbdev)
|
||||
return;
|
||||
|
||||
/* Stylus interface */
|
||||
hdev1 = usb_get_intfdata(usbdev->config->interface[1]);
|
||||
wacom1 = hid_get_drvdata(hdev1);
|
||||
@@ -2733,8 +2736,6 @@ static void wacom_mode_change_work(struct work_struct *work)
|
||||
static int wacom_probe(struct hid_device *hdev,
|
||||
const struct hid_device_id *id)
|
||||
{
|
||||
struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
|
||||
struct usb_device *dev = interface_to_usbdev(intf);
|
||||
struct wacom *wacom;
|
||||
struct wacom_wac *wacom_wac;
|
||||
struct wacom_features *features;
|
||||
@@ -2769,8 +2770,14 @@ static int wacom_probe(struct hid_device *hdev,
|
||||
wacom_wac->hid_data.inputmode = -1;
|
||||
wacom_wac->mode_report = -1;
|
||||
|
||||
wacom->usbdev = dev;
|
||||
wacom->intf = intf;
|
||||
if (hid_is_usb(hdev)) {
|
||||
struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
|
||||
struct usb_device *dev = interface_to_usbdev(intf);
|
||||
|
||||
wacom->usbdev = dev;
|
||||
wacom->intf = intf;
|
||||
}
|
||||
|
||||
mutex_init(&wacom->lock);
|
||||
INIT_DELAYED_WORK(&wacom->init_work, wacom_init_work);
|
||||
INIT_WORK(&wacom->wireless_work, wacom_wireless_work);
|
||||
|
||||
@@ -623,10 +623,9 @@ static void __init i8k_init_procfs(struct device *dev)
|
||||
{
|
||||
struct dell_smm_data *data = dev_get_drvdata(dev);
|
||||
|
||||
/* Register the proc entry */
|
||||
proc_create_data("i8k", 0, NULL, &i8k_proc_ops, data);
|
||||
|
||||
devm_add_action_or_reset(dev, i8k_exit_procfs, NULL);
|
||||
/* Only register exit function if creation was successful */
|
||||
if (proc_create_data("i8k", 0, NULL, &i8k_proc_ops, data))
|
||||
devm_add_action_or_reset(dev, i8k_exit_procfs, NULL);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
@@ -336,8 +336,6 @@ static int pwm_fan_probe(struct platform_device *pdev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ctx->pwm_value = MAX_PWM;
|
||||
|
||||
pwm_init_state(ctx->pwm, &ctx->pwm_state);
|
||||
|
||||
/*
|
||||
|
||||
@@ -636,7 +636,7 @@ static irqreturn_t mpc_i2c_isr(int irq, void *dev_id)
|
||||
status = readb(i2c->base + MPC_I2C_SR);
|
||||
if (status & CSR_MIF) {
|
||||
/* Wait up to 100us for transfer to properly complete */
|
||||
readb_poll_timeout(i2c->base + MPC_I2C_SR, status, !(status & CSR_MCF), 0, 100);
|
||||
readb_poll_timeout_atomic(i2c->base + MPC_I2C_SR, status, status & CSR_MCF, 0, 100);
|
||||
writeb(0, i2c->base + MPC_I2C_SR);
|
||||
mpc_i2c_do_intr(i2c, status);
|
||||
return IRQ_HANDLED;
|
||||
|
||||
@@ -1595,8 +1595,7 @@ static int kxcjk1013_probe(struct i2c_client *client,
|
||||
return 0;
|
||||
|
||||
err_buffer_cleanup:
|
||||
if (data->dready_trig)
|
||||
iio_triggered_buffer_cleanup(indio_dev);
|
||||
iio_triggered_buffer_cleanup(indio_dev);
|
||||
err_trigger_unregister:
|
||||
if (data->dready_trig)
|
||||
iio_trigger_unregister(data->dready_trig);
|
||||
@@ -1618,8 +1617,8 @@ static int kxcjk1013_remove(struct i2c_client *client)
|
||||
pm_runtime_disable(&client->dev);
|
||||
pm_runtime_set_suspended(&client->dev);
|
||||
|
||||
iio_triggered_buffer_cleanup(indio_dev);
|
||||
if (data->dready_trig) {
|
||||
iio_triggered_buffer_cleanup(indio_dev);
|
||||
iio_trigger_unregister(data->dready_trig);
|
||||
iio_trigger_unregister(data->motion_trig);
|
||||
}
|
||||
|
||||
@@ -224,14 +224,14 @@ static irqreturn_t kxsd9_trigger_handler(int irq, void *p)
|
||||
hw_values.chan,
|
||||
sizeof(hw_values.chan));
|
||||
if (ret) {
|
||||
dev_err(st->dev,
|
||||
"error reading data\n");
|
||||
return ret;
|
||||
dev_err(st->dev, "error reading data: %d\n", ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
iio_push_to_buffers_with_timestamp(indio_dev,
|
||||
&hw_values,
|
||||
iio_get_time_ns(indio_dev));
|
||||
out:
|
||||
iio_trigger_notify_done(indio_dev->trig);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
|
||||
@@ -1470,7 +1470,7 @@ static int mma8452_trigger_setup(struct iio_dev *indio_dev)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
indio_dev->trig = trig;
|
||||
indio_dev->trig = iio_trigger_get(trig);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -480,8 +480,8 @@ static irqreturn_t ad7768_trigger_handler(int irq, void *p)
|
||||
iio_push_to_buffers_with_timestamp(indio_dev, &st->data.scan,
|
||||
iio_get_time_ns(indio_dev));
|
||||
|
||||
iio_trigger_notify_done(indio_dev->trig);
|
||||
err_unlock:
|
||||
iio_trigger_notify_done(indio_dev->trig);
|
||||
mutex_unlock(&st->lock);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
|
||||
@@ -1377,7 +1377,8 @@ static int at91_adc_read_info_raw(struct iio_dev *indio_dev,
|
||||
*val = st->conversion_value;
|
||||
ret = at91_adc_adjust_val_osr(st, val);
|
||||
if (chan->scan_type.sign == 's')
|
||||
*val = sign_extend32(*val, 11);
|
||||
*val = sign_extend32(*val,
|
||||
chan->scan_type.realbits - 1);
|
||||
st->conversion_done = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -251,19 +251,8 @@ static int axp22x_adc_raw(struct iio_dev *indio_dev,
|
||||
struct iio_chan_spec const *chan, int *val)
|
||||
{
|
||||
struct axp20x_adc_iio *info = iio_priv(indio_dev);
|
||||
int size;
|
||||
|
||||
/*
|
||||
* N.B.: Unlike the Chinese datasheets tell, the charging current is
|
||||
* stored on 12 bits, not 13 bits. Only discharging current is on 13
|
||||
* bits.
|
||||
*/
|
||||
if (chan->type == IIO_CURRENT && chan->channel == AXP22X_BATT_DISCHRG_I)
|
||||
size = 13;
|
||||
else
|
||||
size = 12;
|
||||
|
||||
*val = axp20x_read_variable_width(info->regmap, chan->address, size);
|
||||
*val = axp20x_read_variable_width(info->regmap, chan->address, 12);
|
||||
if (*val < 0)
|
||||
return *val;
|
||||
|
||||
@@ -386,9 +375,8 @@ static int axp22x_adc_scale(struct iio_chan_spec const *chan, int *val,
|
||||
return IIO_VAL_INT_PLUS_MICRO;
|
||||
|
||||
case IIO_CURRENT:
|
||||
*val = 0;
|
||||
*val2 = 500000;
|
||||
return IIO_VAL_INT_PLUS_MICRO;
|
||||
*val = 1;
|
||||
return IIO_VAL_INT;
|
||||
|
||||
case IIO_TEMP:
|
||||
*val = 100;
|
||||
|
||||
@@ -248,7 +248,6 @@ static int dln2_adc_set_chan_period(struct dln2_adc *dln2,
|
||||
static int dln2_adc_read(struct dln2_adc *dln2, unsigned int channel)
|
||||
{
|
||||
int ret, i;
|
||||
struct iio_dev *indio_dev = platform_get_drvdata(dln2->pdev);
|
||||
u16 conflict;
|
||||
__le16 value;
|
||||
int olen = sizeof(value);
|
||||
@@ -257,13 +256,9 @@ static int dln2_adc_read(struct dln2_adc *dln2, unsigned int channel)
|
||||
.chan = channel,
|
||||
};
|
||||
|
||||
ret = iio_device_claim_direct_mode(indio_dev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = dln2_adc_set_chan_enabled(dln2, channel, true);
|
||||
if (ret < 0)
|
||||
goto release_direct;
|
||||
return ret;
|
||||
|
||||
ret = dln2_adc_set_port_enabled(dln2, true, &conflict);
|
||||
if (ret < 0) {
|
||||
@@ -300,8 +295,6 @@ disable_port:
|
||||
dln2_adc_set_port_enabled(dln2, false, NULL);
|
||||
disable_chan:
|
||||
dln2_adc_set_chan_enabled(dln2, channel, false);
|
||||
release_direct:
|
||||
iio_device_release_direct_mode(indio_dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -337,10 +330,16 @@ static int dln2_adc_read_raw(struct iio_dev *indio_dev,
|
||||
|
||||
switch (mask) {
|
||||
case IIO_CHAN_INFO_RAW:
|
||||
ret = iio_device_claim_direct_mode(indio_dev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
mutex_lock(&dln2->mutex);
|
||||
ret = dln2_adc_read(dln2, chan->channel);
|
||||
mutex_unlock(&dln2->mutex);
|
||||
|
||||
iio_device_release_direct_mode(indio_dev);
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
@@ -656,7 +655,11 @@ static int dln2_adc_probe(struct platform_device *pdev)
|
||||
return -ENOMEM;
|
||||
}
|
||||
iio_trigger_set_drvdata(dln2->trig, dln2);
|
||||
devm_iio_trigger_register(dev, dln2->trig);
|
||||
ret = devm_iio_trigger_register(dev, dln2->trig);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to register trigger: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
iio_trigger_set_immutable(indio_dev, dln2->trig);
|
||||
|
||||
ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL,
|
||||
|
||||
@@ -975,6 +975,7 @@ static void stm32h7_adc_unprepare(struct iio_dev *indio_dev)
|
||||
{
|
||||
struct stm32_adc *adc = iio_priv(indio_dev);
|
||||
|
||||
stm32_adc_writel(adc, STM32H7_ADC_PCSEL, 0);
|
||||
stm32h7_adc_disable(indio_dev);
|
||||
stm32h7_adc_enter_pwr_down(adc);
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
*/
|
||||
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/kernel.h>
|
||||
@@ -124,7 +125,7 @@ static int adxrs290_get_rate_data(struct iio_dev *indio_dev, const u8 cmd, int *
|
||||
goto err_unlock;
|
||||
}
|
||||
|
||||
*val = temp;
|
||||
*val = sign_extend32(temp, 15);
|
||||
|
||||
err_unlock:
|
||||
mutex_unlock(&st->lock);
|
||||
@@ -146,7 +147,7 @@ static int adxrs290_get_temp_data(struct iio_dev *indio_dev, int *val)
|
||||
}
|
||||
|
||||
/* extract lower 12 bits temperature reading */
|
||||
*val = temp & 0x0FFF;
|
||||
*val = sign_extend32(temp, 11);
|
||||
|
||||
err_unlock:
|
||||
mutex_unlock(&st->lock);
|
||||
|
||||
@@ -61,9 +61,9 @@ static irqreturn_t itg3200_trigger_handler(int irq, void *p)
|
||||
|
||||
iio_push_to_buffers_with_timestamp(indio_dev, &scan, pf->timestamp);
|
||||
|
||||
error_ret:
|
||||
iio_trigger_notify_done(indio_dev->trig);
|
||||
|
||||
error_ret:
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
|
||||
@@ -556,7 +556,6 @@ struct iio_trigger *viio_trigger_alloc(struct device *parent,
|
||||
irq_modify_status(trig->subirq_base + i,
|
||||
IRQ_NOREQUEST | IRQ_NOAUTOEN, IRQ_NOPROBE);
|
||||
}
|
||||
get_device(&trig->dev);
|
||||
|
||||
return trig;
|
||||
|
||||
|
||||
@@ -1273,7 +1273,7 @@ static irqreturn_t ltr501_trigger_handler(int irq, void *p)
|
||||
ret = regmap_bulk_read(data->regmap, LTR501_ALS_DATA1,
|
||||
als_buf, sizeof(als_buf));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
goto done;
|
||||
if (test_bit(0, indio_dev->active_scan_mask))
|
||||
scan.channels[j++] = le16_to_cpu(als_buf[1]);
|
||||
if (test_bit(1, indio_dev->active_scan_mask))
|
||||
|
||||
@@ -546,9 +546,8 @@ static irqreturn_t stk3310_irq_event_handler(int irq, void *private)
|
||||
mutex_lock(&data->lock);
|
||||
ret = regmap_field_read(data->reg_flag_nf, &dir);
|
||||
if (ret < 0) {
|
||||
dev_err(&data->client->dev, "register read failed\n");
|
||||
mutex_unlock(&data->lock);
|
||||
return ret;
|
||||
dev_err(&data->client->dev, "register read failed: %d\n", ret);
|
||||
goto out;
|
||||
}
|
||||
event = IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, 1,
|
||||
IIO_EV_TYPE_THRESH,
|
||||
@@ -560,6 +559,7 @@ static irqreturn_t stk3310_irq_event_handler(int irq, void *private)
|
||||
ret = regmap_field_write(data->reg_flag_psint, 0);
|
||||
if (ret < 0)
|
||||
dev_err(&data->client->dev, "failed to reset interrupts\n");
|
||||
out:
|
||||
mutex_unlock(&data->lock);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
|
||||
@@ -912,6 +912,6 @@ static struct platform_driver stm32_timer_trigger_driver = {
|
||||
};
|
||||
module_platform_driver(stm32_timer_trigger_driver);
|
||||
|
||||
MODULE_ALIAS("platform: stm32-timer-trigger");
|
||||
MODULE_ALIAS("platform:stm32-timer-trigger");
|
||||
MODULE_DESCRIPTION("STMicroelectronics STM32 Timer Trigger driver");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
||||
@@ -8414,6 +8414,8 @@ static void receive_interrupt_common(struct hfi1_ctxtdata *rcd)
|
||||
*/
|
||||
static void __hfi1_rcd_eoi_intr(struct hfi1_ctxtdata *rcd)
|
||||
{
|
||||
if (!rcd->rcvhdrq)
|
||||
return;
|
||||
clear_recv_intr(rcd);
|
||||
if (check_packet_present(rcd))
|
||||
force_recv_intr(rcd);
|
||||
|
||||
@@ -1011,6 +1011,8 @@ int handle_receive_interrupt(struct hfi1_ctxtdata *rcd, int thread)
|
||||
struct hfi1_packet packet;
|
||||
int skip_pkt = 0;
|
||||
|
||||
if (!rcd->rcvhdrq)
|
||||
return RCV_PKT_OK;
|
||||
/* Control context will always use the slow path interrupt handler */
|
||||
needset = (rcd->ctxt == HFI1_CTRL_CTXT) ? 0 : 1;
|
||||
|
||||
|
||||
@@ -112,7 +112,6 @@ static int hfi1_create_kctxt(struct hfi1_devdata *dd,
|
||||
rcd->fast_handler = get_dma_rtail_setting(rcd) ?
|
||||
handle_receive_interrupt_dma_rtail :
|
||||
handle_receive_interrupt_nodma_rtail;
|
||||
rcd->slow_handler = handle_receive_interrupt;
|
||||
|
||||
hfi1_set_seq_cnt(rcd, 1);
|
||||
|
||||
@@ -333,6 +332,8 @@ int hfi1_create_ctxtdata(struct hfi1_pportdata *ppd, int numa,
|
||||
rcd->numa_id = numa;
|
||||
rcd->rcv_array_groups = dd->rcv_entries.ngroups;
|
||||
rcd->rhf_rcv_function_map = normal_rhf_rcv_functions;
|
||||
rcd->slow_handler = handle_receive_interrupt;
|
||||
rcd->do_interrupt = rcd->slow_handler;
|
||||
rcd->msix_intr = CCE_NUM_MSIX_VECTORS;
|
||||
|
||||
mutex_init(&rcd->exp_mutex);
|
||||
@@ -873,18 +874,6 @@ int hfi1_init(struct hfi1_devdata *dd, int reinit)
|
||||
if (ret)
|
||||
goto done;
|
||||
|
||||
/* allocate dummy tail memory for all receive contexts */
|
||||
dd->rcvhdrtail_dummy_kvaddr = dma_alloc_coherent(&dd->pcidev->dev,
|
||||
sizeof(u64),
|
||||
&dd->rcvhdrtail_dummy_dma,
|
||||
GFP_KERNEL);
|
||||
|
||||
if (!dd->rcvhdrtail_dummy_kvaddr) {
|
||||
dd_dev_err(dd, "cannot allocate dummy tail memory\n");
|
||||
ret = -ENOMEM;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* dd->rcd can be NULL if early initialization failed */
|
||||
for (i = 0; dd->rcd && i < dd->first_dyn_alloc_ctxt; ++i) {
|
||||
/*
|
||||
@@ -897,8 +886,6 @@ int hfi1_init(struct hfi1_devdata *dd, int reinit)
|
||||
if (!rcd)
|
||||
continue;
|
||||
|
||||
rcd->do_interrupt = &handle_receive_interrupt;
|
||||
|
||||
lastfail = hfi1_create_rcvhdrq(dd, rcd);
|
||||
if (!lastfail)
|
||||
lastfail = hfi1_setup_eagerbufs(rcd);
|
||||
@@ -1119,7 +1106,7 @@ void hfi1_free_ctxtdata(struct hfi1_devdata *dd, struct hfi1_ctxtdata *rcd)
|
||||
rcd->egrbufs.rcvtids = NULL;
|
||||
|
||||
for (e = 0; e < rcd->egrbufs.alloced; e++) {
|
||||
if (rcd->egrbufs.buffers[e].dma)
|
||||
if (rcd->egrbufs.buffers[e].addr)
|
||||
dma_free_coherent(&dd->pcidev->dev,
|
||||
rcd->egrbufs.buffers[e].len,
|
||||
rcd->egrbufs.buffers[e].addr,
|
||||
@@ -1200,6 +1187,11 @@ void hfi1_free_devdata(struct hfi1_devdata *dd)
|
||||
dd->tx_opstats = NULL;
|
||||
kfree(dd->comp_vect);
|
||||
dd->comp_vect = NULL;
|
||||
if (dd->rcvhdrtail_dummy_kvaddr)
|
||||
dma_free_coherent(&dd->pcidev->dev, sizeof(u64),
|
||||
(void *)dd->rcvhdrtail_dummy_kvaddr,
|
||||
dd->rcvhdrtail_dummy_dma);
|
||||
dd->rcvhdrtail_dummy_kvaddr = NULL;
|
||||
sdma_clean(dd, dd->num_sdma);
|
||||
rvt_dealloc_device(&dd->verbs_dev.rdi);
|
||||
}
|
||||
@@ -1297,6 +1289,15 @@ static struct hfi1_devdata *hfi1_alloc_devdata(struct pci_dev *pdev,
|
||||
goto bail;
|
||||
}
|
||||
|
||||
/* allocate dummy tail memory for all receive contexts */
|
||||
dd->rcvhdrtail_dummy_kvaddr =
|
||||
dma_alloc_coherent(&dd->pcidev->dev, sizeof(u64),
|
||||
&dd->rcvhdrtail_dummy_dma, GFP_KERNEL);
|
||||
if (!dd->rcvhdrtail_dummy_kvaddr) {
|
||||
ret = -ENOMEM;
|
||||
goto bail;
|
||||
}
|
||||
|
||||
atomic_set(&dd->ipoib_rsm_usr_num, 0);
|
||||
return dd;
|
||||
|
||||
@@ -1504,13 +1505,6 @@ static void cleanup_device_data(struct hfi1_devdata *dd)
|
||||
|
||||
free_credit_return(dd);
|
||||
|
||||
if (dd->rcvhdrtail_dummy_kvaddr) {
|
||||
dma_free_coherent(&dd->pcidev->dev, sizeof(u64),
|
||||
(void *)dd->rcvhdrtail_dummy_kvaddr,
|
||||
dd->rcvhdrtail_dummy_dma);
|
||||
dd->rcvhdrtail_dummy_kvaddr = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Free any resources still in use (usually just kernel contexts)
|
||||
* at unload; we do for ctxtcnt, because that's what we allocate.
|
||||
|
||||
@@ -838,8 +838,8 @@ struct sdma_engine *sdma_select_user_engine(struct hfi1_devdata *dd,
|
||||
if (current->nr_cpus_allowed != 1)
|
||||
goto out;
|
||||
|
||||
cpu_id = smp_processor_id();
|
||||
rcu_read_lock();
|
||||
cpu_id = smp_processor_id();
|
||||
rht_node = rhashtable_lookup(dd->sdma_rht, &cpu_id,
|
||||
sdma_rht_params);
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/types.h>
|
||||
#include <net/addrconf.h>
|
||||
@@ -1050,9 +1051,14 @@ static u32 hns_roce_v2_cmd_hw_resetting(struct hns_roce_dev *hr_dev,
|
||||
unsigned long instance_stage,
|
||||
unsigned long reset_stage)
|
||||
{
|
||||
#define HW_RESET_TIMEOUT_US 1000000
|
||||
#define HW_RESET_SLEEP_US 1000
|
||||
|
||||
struct hns_roce_v2_priv *priv = hr_dev->priv;
|
||||
struct hnae3_handle *handle = priv->handle;
|
||||
const struct hnae3_ae_ops *ops = handle->ae_algo->ops;
|
||||
unsigned long val;
|
||||
int ret;
|
||||
|
||||
/* When hardware reset is detected, we should stop sending mailbox&cmq&
|
||||
* doorbell to hardware. If now in .init_instance() function, we should
|
||||
@@ -1064,7 +1070,11 @@ static u32 hns_roce_v2_cmd_hw_resetting(struct hns_roce_dev *hr_dev,
|
||||
* again.
|
||||
*/
|
||||
hr_dev->dis_db = true;
|
||||
if (!ops->get_hw_reset_stat(handle))
|
||||
|
||||
ret = read_poll_timeout(ops->ae_dev_reset_cnt, val,
|
||||
val > hr_dev->reset_cnt, HW_RESET_SLEEP_US,
|
||||
HW_RESET_TIMEOUT_US, false, handle);
|
||||
if (!ret)
|
||||
hr_dev->is_reset = true;
|
||||
|
||||
if (!hr_dev->is_reset || reset_stage == HNS_ROCE_STATE_RST_INIT ||
|
||||
@@ -6397,10 +6407,8 @@ static int hns_roce_hw_v2_reset_notify_down(struct hnae3_handle *handle)
|
||||
if (!hr_dev)
|
||||
return 0;
|
||||
|
||||
hr_dev->is_reset = true;
|
||||
hr_dev->active = false;
|
||||
hr_dev->dis_db = true;
|
||||
|
||||
hr_dev->state = HNS_ROCE_DEVICE_STATE_RST_DOWN;
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -232,17 +232,13 @@ static int armada_370_xp_msi_alloc(struct irq_domain *domain, unsigned int virq,
|
||||
int hwirq, i;
|
||||
|
||||
mutex_lock(&msi_used_lock);
|
||||
|
||||
hwirq = bitmap_find_next_zero_area(msi_used, PCI_MSI_DOORBELL_NR,
|
||||
0, nr_irqs, 0);
|
||||
if (hwirq >= PCI_MSI_DOORBELL_NR) {
|
||||
mutex_unlock(&msi_used_lock);
|
||||
return -ENOSPC;
|
||||
}
|
||||
|
||||
bitmap_set(msi_used, hwirq, nr_irqs);
|
||||
hwirq = bitmap_find_free_region(msi_used, PCI_MSI_DOORBELL_NR,
|
||||
order_base_2(nr_irqs));
|
||||
mutex_unlock(&msi_used_lock);
|
||||
|
||||
if (hwirq < 0)
|
||||
return -ENOSPC;
|
||||
|
||||
for (i = 0; i < nr_irqs; i++) {
|
||||
irq_domain_set_info(domain, virq + i, hwirq + i,
|
||||
&armada_370_xp_msi_bottom_irq_chip,
|
||||
@@ -250,7 +246,7 @@ static int armada_370_xp_msi_alloc(struct irq_domain *domain, unsigned int virq,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
return hwirq;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void armada_370_xp_msi_free(struct irq_domain *domain,
|
||||
@@ -259,7 +255,7 @@ static void armada_370_xp_msi_free(struct irq_domain *domain,
|
||||
struct irq_data *d = irq_domain_get_irq_data(domain, virq);
|
||||
|
||||
mutex_lock(&msi_used_lock);
|
||||
bitmap_clear(msi_used, d->hwirq, nr_irqs);
|
||||
bitmap_release_region(msi_used, d->hwirq, order_base_2(nr_irqs));
|
||||
mutex_unlock(&msi_used_lock);
|
||||
}
|
||||
|
||||
|
||||
@@ -76,8 +76,8 @@ static void aspeed_scu_ic_irq_handler(struct irq_desc *desc)
|
||||
generic_handle_domain_irq(scu_ic->irq_domain,
|
||||
bit - scu_ic->irq_shift);
|
||||
|
||||
regmap_update_bits(scu_ic->scu, scu_ic->reg, mask,
|
||||
BIT(bit + ASPEED_SCU_IC_STATUS_SHIFT));
|
||||
regmap_write_bits(scu_ic->scu, scu_ic->reg, mask,
|
||||
BIT(bit + ASPEED_SCU_IC_STATUS_SHIFT));
|
||||
}
|
||||
|
||||
chained_irq_exit(chip, desc);
|
||||
|
||||
@@ -743,7 +743,7 @@ static struct its_collection *its_build_invall_cmd(struct its_node *its,
|
||||
|
||||
its_fixup_cmd(cmd);
|
||||
|
||||
return NULL;
|
||||
return desc->its_invall_cmd.col;
|
||||
}
|
||||
|
||||
static struct its_vpe *its_build_vinvall_cmd(struct its_node *its,
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
#define NVIC_ISER 0x000
|
||||
#define NVIC_ICER 0x080
|
||||
#define NVIC_IPR 0x300
|
||||
#define NVIC_IPR 0x400
|
||||
|
||||
#define NVIC_MAX_BANKS 16
|
||||
/*
|
||||
|
||||
@@ -2193,6 +2193,7 @@ super_1_rdev_size_change(struct md_rdev *rdev, sector_t num_sectors)
|
||||
|
||||
if (!num_sectors || num_sectors > max_sectors)
|
||||
num_sectors = max_sectors;
|
||||
rdev->sb_start = sb_start;
|
||||
}
|
||||
sb = page_address(rdev->sb_page);
|
||||
sb->data_size = cpu_to_le64(num_sectors);
|
||||
|
||||
@@ -1803,8 +1803,6 @@ static int rtsx_pci_runtime_suspend(struct device *device)
|
||||
mutex_lock(&pcr->pcr_mutex);
|
||||
rtsx_pci_power_off(pcr, HOST_ENTER_S3);
|
||||
|
||||
free_irq(pcr->irq, (void *)pcr);
|
||||
|
||||
mutex_unlock(&pcr->pcr_mutex);
|
||||
|
||||
pcr->is_runtime_suspended = true;
|
||||
@@ -1825,8 +1823,6 @@ static int rtsx_pci_runtime_resume(struct device *device)
|
||||
mutex_lock(&pcr->pcr_mutex);
|
||||
|
||||
rtsx_pci_write_register(pcr, HOST_SLEEP_STATE, 0x03, 0x00);
|
||||
rtsx_pci_acquire_irq(pcr);
|
||||
synchronize_irq(pcr->irq);
|
||||
|
||||
if (pcr->ops->fetch_vendor_settings)
|
||||
pcr->ops->fetch_vendor_settings(pcr);
|
||||
|
||||
@@ -376,7 +376,6 @@ MODULE_DEVICE_TABLE(spi, at25_spi_ids);
|
||||
static int at25_probe(struct spi_device *spi)
|
||||
{
|
||||
struct at25_data *at25 = NULL;
|
||||
struct spi_eeprom chip;
|
||||
int err;
|
||||
int sr;
|
||||
u8 id[FM25_ID_LEN];
|
||||
@@ -389,15 +388,18 @@ static int at25_probe(struct spi_device *spi)
|
||||
if (match && !strcmp(match->compatible, "cypress,fm25"))
|
||||
is_fram = 1;
|
||||
|
||||
at25 = devm_kzalloc(&spi->dev, sizeof(struct at25_data), GFP_KERNEL);
|
||||
if (!at25)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Chip description */
|
||||
if (!spi->dev.platform_data) {
|
||||
if (!is_fram) {
|
||||
err = at25_fw_to_chip(&spi->dev, &chip);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
} else
|
||||
chip = *(struct spi_eeprom *)spi->dev.platform_data;
|
||||
if (spi->dev.platform_data) {
|
||||
memcpy(&at25->chip, spi->dev.platform_data, sizeof(at25->chip));
|
||||
} else if (!is_fram) {
|
||||
err = at25_fw_to_chip(&spi->dev, &at25->chip);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Ping the chip ... the status register is pretty portable,
|
||||
* unlike probing manufacturer IDs. We do expect that system
|
||||
@@ -409,12 +411,7 @@ static int at25_probe(struct spi_device *spi)
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
at25 = devm_kzalloc(&spi->dev, sizeof(struct at25_data), GFP_KERNEL);
|
||||
if (!at25)
|
||||
return -ENOMEM;
|
||||
|
||||
mutex_init(&at25->lock);
|
||||
at25->chip = chip;
|
||||
at25->spi = spi;
|
||||
spi_set_drvdata(spi, at25);
|
||||
|
||||
@@ -431,7 +428,7 @@ static int at25_probe(struct spi_device *spi)
|
||||
dev_err(&spi->dev, "Error: unsupported size (id %02x)\n", id[7]);
|
||||
return -ENODEV;
|
||||
}
|
||||
chip.byte_len = int_pow(2, id[7] - 0x21 + 4) * 1024;
|
||||
at25->chip.byte_len = int_pow(2, id[7] - 0x21 + 4) * 1024;
|
||||
|
||||
if (at25->chip.byte_len > 64 * 1024)
|
||||
at25->chip.flags |= EE_ADDR3;
|
||||
@@ -464,7 +461,7 @@ static int at25_probe(struct spi_device *spi)
|
||||
at25->nvmem_config.type = is_fram ? NVMEM_TYPE_FRAM : NVMEM_TYPE_EEPROM;
|
||||
at25->nvmem_config.name = dev_name(&spi->dev);
|
||||
at25->nvmem_config.dev = &spi->dev;
|
||||
at25->nvmem_config.read_only = chip.flags & EE_READONLY;
|
||||
at25->nvmem_config.read_only = at25->chip.flags & EE_READONLY;
|
||||
at25->nvmem_config.root_only = true;
|
||||
at25->nvmem_config.owner = THIS_MODULE;
|
||||
at25->nvmem_config.compat = true;
|
||||
@@ -474,17 +471,18 @@ static int at25_probe(struct spi_device *spi)
|
||||
at25->nvmem_config.priv = at25;
|
||||
at25->nvmem_config.stride = 1;
|
||||
at25->nvmem_config.word_size = 1;
|
||||
at25->nvmem_config.size = chip.byte_len;
|
||||
at25->nvmem_config.size = at25->chip.byte_len;
|
||||
|
||||
at25->nvmem = devm_nvmem_register(&spi->dev, &at25->nvmem_config);
|
||||
if (IS_ERR(at25->nvmem))
|
||||
return PTR_ERR(at25->nvmem);
|
||||
|
||||
dev_info(&spi->dev, "%d %s %s %s%s, pagesize %u\n",
|
||||
(chip.byte_len < 1024) ? chip.byte_len : (chip.byte_len / 1024),
|
||||
(chip.byte_len < 1024) ? "Byte" : "KByte",
|
||||
(at25->chip.byte_len < 1024) ?
|
||||
at25->chip.byte_len : (at25->chip.byte_len / 1024),
|
||||
(at25->chip.byte_len < 1024) ? "Byte" : "KByte",
|
||||
at25->chip.name, is_fram ? "fram" : "eeprom",
|
||||
(chip.flags & EE_READONLY) ? " (readonly)" : "",
|
||||
(at25->chip.flags & EE_READONLY) ? " (readonly)" : "",
|
||||
at25->chip.page_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -719,16 +719,18 @@ static int fastrpc_get_meta_size(struct fastrpc_invoke_ctx *ctx)
|
||||
static u64 fastrpc_get_payload_size(struct fastrpc_invoke_ctx *ctx, int metalen)
|
||||
{
|
||||
u64 size = 0;
|
||||
int i;
|
||||
int oix;
|
||||
|
||||
size = ALIGN(metalen, FASTRPC_ALIGN);
|
||||
for (i = 0; i < ctx->nscalars; i++) {
|
||||
for (oix = 0; oix < ctx->nbufs; oix++) {
|
||||
int i = ctx->olaps[oix].raix;
|
||||
|
||||
if (ctx->args[i].fd == 0 || ctx->args[i].fd == -1) {
|
||||
|
||||
if (ctx->olaps[i].offset == 0)
|
||||
if (ctx->olaps[oix].offset == 0)
|
||||
size = ALIGN(size, FASTRPC_ALIGN);
|
||||
|
||||
size += (ctx->olaps[i].mend - ctx->olaps[i].mstart);
|
||||
size += (ctx->olaps[oix].mend - ctx->olaps[oix].mstart);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1514,6 +1514,12 @@ static int mmc_spi_remove(struct spi_device *spi)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct spi_device_id mmc_spi_dev_ids[] = {
|
||||
{ "mmc-spi-slot"},
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(spi, mmc_spi_dev_ids);
|
||||
|
||||
static const struct of_device_id mmc_spi_of_match_table[] = {
|
||||
{ .compatible = "mmc-spi-slot", },
|
||||
{},
|
||||
@@ -1525,6 +1531,7 @@ static struct spi_driver mmc_spi_driver = {
|
||||
.name = "mmc_spi",
|
||||
.of_match_table = mmc_spi_of_match_table,
|
||||
},
|
||||
.id_table = mmc_spi_dev_ids,
|
||||
.probe = mmc_spi_probe,
|
||||
.remove = mmc_spi_remove,
|
||||
};
|
||||
|
||||
@@ -673,7 +673,7 @@ static int renesas_sdhi_execute_tuning(struct mmc_host *mmc, u32 opcode)
|
||||
|
||||
/* Issue CMD19 twice for each tap */
|
||||
for (i = 0; i < 2 * priv->tap_num; i++) {
|
||||
int cmd_error;
|
||||
int cmd_error = 0;
|
||||
|
||||
/* Set sampling clock position */
|
||||
sd_scc_write32(host, priv, SH_MOBILE_SDHI_SCC_TAPSET, i % priv->tap_num);
|
||||
|
||||
@@ -96,6 +96,13 @@ struct dataflash {
|
||||
struct mtd_info mtd;
|
||||
};
|
||||
|
||||
static const struct spi_device_id dataflash_dev_ids[] = {
|
||||
{ "at45" },
|
||||
{ "dataflash" },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(spi, dataflash_dev_ids);
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static const struct of_device_id dataflash_dt_ids[] = {
|
||||
{ .compatible = "atmel,at45", },
|
||||
@@ -927,6 +934,7 @@ static struct spi_driver dataflash_driver = {
|
||||
.name = "mtd_dataflash",
|
||||
.of_match_table = of_match_ptr(dataflash_dt_ids),
|
||||
},
|
||||
.id_table = dataflash_dev_ids,
|
||||
|
||||
.probe = dataflash_probe,
|
||||
.remove = dataflash_remove,
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/completion.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/dmaengine.h>
|
||||
#include <linux/dma-direction.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
@@ -93,6 +94,14 @@
|
||||
|
||||
#define FSMC_BUSY_WAIT_TIMEOUT (1 * HZ)
|
||||
|
||||
/*
|
||||
* According to SPEAr300 Reference Manual (RM0082)
|
||||
* TOUDEL = 7ns (Output delay from the flip-flops to the board)
|
||||
* TINDEL = 5ns (Input delay from the board to the flipflop)
|
||||
*/
|
||||
#define TOUTDEL 7000
|
||||
#define TINDEL 5000
|
||||
|
||||
struct fsmc_nand_timings {
|
||||
u8 tclr;
|
||||
u8 tar;
|
||||
@@ -277,7 +286,7 @@ static int fsmc_calc_timings(struct fsmc_nand_data *host,
|
||||
{
|
||||
unsigned long hclk = clk_get_rate(host->clk);
|
||||
unsigned long hclkn = NSEC_PER_SEC / hclk;
|
||||
u32 thiz, thold, twait, tset;
|
||||
u32 thiz, thold, twait, tset, twait_min;
|
||||
|
||||
if (sdrt->tRC_min < 30000)
|
||||
return -EOPNOTSUPP;
|
||||
@@ -309,13 +318,6 @@ static int fsmc_calc_timings(struct fsmc_nand_data *host,
|
||||
else if (tims->thold > FSMC_THOLD_MASK)
|
||||
tims->thold = FSMC_THOLD_MASK;
|
||||
|
||||
twait = max(sdrt->tRP_min, sdrt->tWP_min);
|
||||
tims->twait = DIV_ROUND_UP(twait / 1000, hclkn) - 1;
|
||||
if (tims->twait == 0)
|
||||
tims->twait = 1;
|
||||
else if (tims->twait > FSMC_TWAIT_MASK)
|
||||
tims->twait = FSMC_TWAIT_MASK;
|
||||
|
||||
tset = max(sdrt->tCS_min - sdrt->tWP_min,
|
||||
sdrt->tCEA_max - sdrt->tREA_max);
|
||||
tims->tset = DIV_ROUND_UP(tset / 1000, hclkn) - 1;
|
||||
@@ -324,6 +326,21 @@ static int fsmc_calc_timings(struct fsmc_nand_data *host,
|
||||
else if (tims->tset > FSMC_TSET_MASK)
|
||||
tims->tset = FSMC_TSET_MASK;
|
||||
|
||||
/*
|
||||
* According to SPEAr300 Reference Manual (RM0082) which gives more
|
||||
* information related to FSMSC timings than the SPEAr600 one (RM0305),
|
||||
* twait >= tCEA - (tset * TCLK) + TOUTDEL + TINDEL
|
||||
*/
|
||||
twait_min = sdrt->tCEA_max - ((tims->tset + 1) * hclkn * 1000)
|
||||
+ TOUTDEL + TINDEL;
|
||||
twait = max3(sdrt->tRP_min, sdrt->tWP_min, twait_min);
|
||||
|
||||
tims->twait = DIV_ROUND_UP(twait / 1000, hclkn) - 1;
|
||||
if (tims->twait == 0)
|
||||
tims->twait = 1;
|
||||
else if (tims->twait > FSMC_TWAIT_MASK)
|
||||
tims->twait = FSMC_TWAIT_MASK;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -664,6 +681,9 @@ static int fsmc_exec_op(struct nand_chip *chip, const struct nand_operation *op,
|
||||
instr->ctx.waitrdy.timeout_ms);
|
||||
break;
|
||||
}
|
||||
|
||||
if (instr->delay_ns)
|
||||
ndelay(instr->delay_ns);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
@@ -1502,14 +1502,14 @@ void bond_alb_monitor(struct work_struct *work)
|
||||
struct slave *slave;
|
||||
|
||||
if (!bond_has_slaves(bond)) {
|
||||
bond_info->tx_rebalance_counter = 0;
|
||||
atomic_set(&bond_info->tx_rebalance_counter, 0);
|
||||
bond_info->lp_counter = 0;
|
||||
goto re_arm;
|
||||
}
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
bond_info->tx_rebalance_counter++;
|
||||
atomic_inc(&bond_info->tx_rebalance_counter);
|
||||
bond_info->lp_counter++;
|
||||
|
||||
/* send learning packets */
|
||||
@@ -1531,7 +1531,7 @@ void bond_alb_monitor(struct work_struct *work)
|
||||
}
|
||||
|
||||
/* rebalance tx traffic */
|
||||
if (bond_info->tx_rebalance_counter >= BOND_TLB_REBALANCE_TICKS) {
|
||||
if (atomic_read(&bond_info->tx_rebalance_counter) >= BOND_TLB_REBALANCE_TICKS) {
|
||||
bond_for_each_slave_rcu(bond, slave, iter) {
|
||||
tlb_clear_slave(bond, slave, 1);
|
||||
if (slave == rcu_access_pointer(bond->curr_active_slave)) {
|
||||
@@ -1541,7 +1541,7 @@ void bond_alb_monitor(struct work_struct *work)
|
||||
bond_info->unbalanced_load = 0;
|
||||
}
|
||||
}
|
||||
bond_info->tx_rebalance_counter = 0;
|
||||
atomic_set(&bond_info->tx_rebalance_counter, 0);
|
||||
}
|
||||
|
||||
if (bond_info->rlb_enabled) {
|
||||
@@ -1611,7 +1611,8 @@ int bond_alb_init_slave(struct bonding *bond, struct slave *slave)
|
||||
tlb_init_slave(slave);
|
||||
|
||||
/* order a rebalance ASAP */
|
||||
bond->alb_info.tx_rebalance_counter = BOND_TLB_REBALANCE_TICKS;
|
||||
atomic_set(&bond->alb_info.tx_rebalance_counter,
|
||||
BOND_TLB_REBALANCE_TICKS);
|
||||
|
||||
if (bond->alb_info.rlb_enabled)
|
||||
bond->alb_info.rlb_rebalance = 1;
|
||||
@@ -1648,7 +1649,8 @@ void bond_alb_handle_link_change(struct bonding *bond, struct slave *slave, char
|
||||
rlb_clear_slave(bond, slave);
|
||||
} else if (link == BOND_LINK_UP) {
|
||||
/* order a rebalance ASAP */
|
||||
bond_info->tx_rebalance_counter = BOND_TLB_REBALANCE_TICKS;
|
||||
atomic_set(&bond_info->tx_rebalance_counter,
|
||||
BOND_TLB_REBALANCE_TICKS);
|
||||
if (bond->alb_info.rlb_enabled) {
|
||||
bond->alb_info.rlb_rebalance = 1;
|
||||
/* If the updelay module parameter is smaller than the
|
||||
|
||||
@@ -248,6 +248,9 @@ MODULE_DESCRIPTION("CAN driver for Kvaser CAN/PCIe devices");
|
||||
#define KVASER_PCIEFD_SPACK_EWLR BIT(23)
|
||||
#define KVASER_PCIEFD_SPACK_EPLR BIT(24)
|
||||
|
||||
/* Kvaser KCAN_EPACK second word */
|
||||
#define KVASER_PCIEFD_EPACK_DIR_TX BIT(0)
|
||||
|
||||
struct kvaser_pciefd;
|
||||
|
||||
struct kvaser_pciefd_can {
|
||||
@@ -1285,7 +1288,10 @@ static int kvaser_pciefd_rx_error_frame(struct kvaser_pciefd_can *can,
|
||||
|
||||
can->err_rep_cnt++;
|
||||
can->can.can_stats.bus_error++;
|
||||
stats->rx_errors++;
|
||||
if (p->header[1] & KVASER_PCIEFD_EPACK_DIR_TX)
|
||||
stats->tx_errors++;
|
||||
else
|
||||
stats->rx_errors++;
|
||||
|
||||
can->bec.txerr = bec.txerr;
|
||||
can->bec.rxerr = bec.rxerr;
|
||||
|
||||
@@ -204,16 +204,16 @@ enum m_can_reg {
|
||||
|
||||
/* Interrupts for version 3.0.x */
|
||||
#define IR_ERR_LEC_30X (IR_STE | IR_FOE | IR_ACKE | IR_BE | IR_CRCE)
|
||||
#define IR_ERR_BUS_30X (IR_ERR_LEC_30X | IR_WDI | IR_ELO | IR_BEU | \
|
||||
IR_BEC | IR_TOO | IR_MRAF | IR_TSW | IR_TEFL | \
|
||||
IR_RF1L | IR_RF0L)
|
||||
#define IR_ERR_BUS_30X (IR_ERR_LEC_30X | IR_WDI | IR_BEU | IR_BEC | \
|
||||
IR_TOO | IR_MRAF | IR_TSW | IR_TEFL | IR_RF1L | \
|
||||
IR_RF0L)
|
||||
#define IR_ERR_ALL_30X (IR_ERR_STATE | IR_ERR_BUS_30X)
|
||||
|
||||
/* Interrupts for version >= 3.1.x */
|
||||
#define IR_ERR_LEC_31X (IR_PED | IR_PEA)
|
||||
#define IR_ERR_BUS_31X (IR_ERR_LEC_31X | IR_WDI | IR_ELO | IR_BEU | \
|
||||
IR_BEC | IR_TOO | IR_MRAF | IR_TSW | IR_TEFL | \
|
||||
IR_RF1L | IR_RF0L)
|
||||
#define IR_ERR_BUS_31X (IR_ERR_LEC_31X | IR_WDI | IR_BEU | IR_BEC | \
|
||||
IR_TOO | IR_MRAF | IR_TSW | IR_TEFL | IR_RF1L | \
|
||||
IR_RF0L)
|
||||
#define IR_ERR_ALL_31X (IR_ERR_STATE | IR_ERR_BUS_31X)
|
||||
|
||||
/* Interrupt Line Select (ILS) */
|
||||
@@ -517,7 +517,7 @@ static int m_can_read_fifo(struct net_device *dev, u32 rxfs)
|
||||
err = m_can_fifo_read(cdev, fgi, M_CAN_FIFO_DATA,
|
||||
cf->data, DIV_ROUND_UP(cf->len, 4));
|
||||
if (err)
|
||||
goto out_fail;
|
||||
goto out_free_skb;
|
||||
}
|
||||
|
||||
/* acknowledge rx fifo 0 */
|
||||
@@ -532,6 +532,8 @@ static int m_can_read_fifo(struct net_device *dev, u32 rxfs)
|
||||
|
||||
return 0;
|
||||
|
||||
out_free_skb:
|
||||
kfree_skb(skb);
|
||||
out_fail:
|
||||
netdev_err(dev, "FIFO read returned %d\n", err);
|
||||
return err;
|
||||
@@ -810,8 +812,6 @@ static void m_can_handle_other_err(struct net_device *dev, u32 irqstatus)
|
||||
{
|
||||
if (irqstatus & IR_WDI)
|
||||
netdev_err(dev, "Message RAM Watchdog event due to missing READY\n");
|
||||
if (irqstatus & IR_ELO)
|
||||
netdev_err(dev, "Error Logging Overflow\n");
|
||||
if (irqstatus & IR_BEU)
|
||||
netdev_err(dev, "Bit Error Uncorrected\n");
|
||||
if (irqstatus & IR_BEC)
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
#define M_CAN_PCI_MMIO_BAR 0
|
||||
|
||||
#define M_CAN_CLOCK_FREQ_EHL 100000000
|
||||
#define M_CAN_CLOCK_FREQ_EHL 200000000
|
||||
#define CTL_CSR_INT_CTL_OFFSET 0x508
|
||||
|
||||
struct m_can_pci_priv {
|
||||
@@ -42,8 +42,13 @@ static u32 iomap_read_reg(struct m_can_classdev *cdev, int reg)
|
||||
static int iomap_read_fifo(struct m_can_classdev *cdev, int offset, void *val, size_t val_count)
|
||||
{
|
||||
struct m_can_pci_priv *priv = cdev_to_priv(cdev);
|
||||
void __iomem *src = priv->base + offset;
|
||||
|
||||
ioread32_rep(priv->base + offset, val, val_count);
|
||||
while (val_count--) {
|
||||
*(unsigned int *)val = ioread32(src);
|
||||
val += 4;
|
||||
src += 4;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -61,8 +66,13 @@ static int iomap_write_fifo(struct m_can_classdev *cdev, int offset,
|
||||
const void *val, size_t val_count)
|
||||
{
|
||||
struct m_can_pci_priv *priv = cdev_to_priv(cdev);
|
||||
void __iomem *dst = priv->base + offset;
|
||||
|
||||
iowrite32_rep(priv->base + offset, val, val_count);
|
||||
while (val_count--) {
|
||||
iowrite32(*(unsigned int *)val, dst);
|
||||
val += 4;
|
||||
dst += 4;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -692,11 +692,11 @@ static int pch_can_rx_normal(struct net_device *ndev, u32 obj_num, int quota)
|
||||
cf->data[i + 1] = data_reg >> 8;
|
||||
}
|
||||
|
||||
netif_receive_skb(skb);
|
||||
rcv_pkts++;
|
||||
stats->rx_packets++;
|
||||
quota--;
|
||||
stats->rx_bytes += cf->len;
|
||||
netif_receive_skb(skb);
|
||||
|
||||
pch_fifo_thresh(priv, obj_num);
|
||||
obj_num++;
|
||||
|
||||
@@ -234,7 +234,12 @@ static int ems_pcmcia_add_card(struct pcmcia_device *pdev, unsigned long base)
|
||||
free_sja1000dev(dev);
|
||||
}
|
||||
|
||||
err = request_irq(dev->irq, &ems_pcmcia_interrupt, IRQF_SHARED,
|
||||
if (!card->channels) {
|
||||
err = -ENODEV;
|
||||
goto failure_cleanup;
|
||||
}
|
||||
|
||||
err = request_irq(pdev->irq, &ems_pcmcia_interrupt, IRQF_SHARED,
|
||||
DRV_NAME, card);
|
||||
if (!err)
|
||||
return 0;
|
||||
|
||||
@@ -28,10 +28,6 @@
|
||||
|
||||
#include "kvaser_usb.h"
|
||||
|
||||
/* Forward declaration */
|
||||
static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_dev_cfg;
|
||||
|
||||
#define CAN_USB_CLOCK 8000000
|
||||
#define MAX_USBCAN_NET_DEVICES 2
|
||||
|
||||
/* Command header size */
|
||||
@@ -80,6 +76,12 @@ static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_dev_cfg;
|
||||
|
||||
#define CMD_LEAF_LOG_MESSAGE 106
|
||||
|
||||
/* Leaf frequency options */
|
||||
#define KVASER_USB_LEAF_SWOPTION_FREQ_MASK 0x60
|
||||
#define KVASER_USB_LEAF_SWOPTION_FREQ_16_MHZ_CLK 0
|
||||
#define KVASER_USB_LEAF_SWOPTION_FREQ_32_MHZ_CLK BIT(5)
|
||||
#define KVASER_USB_LEAF_SWOPTION_FREQ_24_MHZ_CLK BIT(6)
|
||||
|
||||
/* error factors */
|
||||
#define M16C_EF_ACKE BIT(0)
|
||||
#define M16C_EF_CRCE BIT(1)
|
||||
@@ -340,6 +342,50 @@ struct kvaser_usb_err_summary {
|
||||
};
|
||||
};
|
||||
|
||||
static const struct can_bittiming_const kvaser_usb_leaf_bittiming_const = {
|
||||
.name = "kvaser_usb",
|
||||
.tseg1_min = KVASER_USB_TSEG1_MIN,
|
||||
.tseg1_max = KVASER_USB_TSEG1_MAX,
|
||||
.tseg2_min = KVASER_USB_TSEG2_MIN,
|
||||
.tseg2_max = KVASER_USB_TSEG2_MAX,
|
||||
.sjw_max = KVASER_USB_SJW_MAX,
|
||||
.brp_min = KVASER_USB_BRP_MIN,
|
||||
.brp_max = KVASER_USB_BRP_MAX,
|
||||
.brp_inc = KVASER_USB_BRP_INC,
|
||||
};
|
||||
|
||||
static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_dev_cfg_8mhz = {
|
||||
.clock = {
|
||||
.freq = 8000000,
|
||||
},
|
||||
.timestamp_freq = 1,
|
||||
.bittiming_const = &kvaser_usb_leaf_bittiming_const,
|
||||
};
|
||||
|
||||
static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_dev_cfg_16mhz = {
|
||||
.clock = {
|
||||
.freq = 16000000,
|
||||
},
|
||||
.timestamp_freq = 1,
|
||||
.bittiming_const = &kvaser_usb_leaf_bittiming_const,
|
||||
};
|
||||
|
||||
static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_dev_cfg_24mhz = {
|
||||
.clock = {
|
||||
.freq = 24000000,
|
||||
},
|
||||
.timestamp_freq = 1,
|
||||
.bittiming_const = &kvaser_usb_leaf_bittiming_const,
|
||||
};
|
||||
|
||||
static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_dev_cfg_32mhz = {
|
||||
.clock = {
|
||||
.freq = 32000000,
|
||||
},
|
||||
.timestamp_freq = 1,
|
||||
.bittiming_const = &kvaser_usb_leaf_bittiming_const,
|
||||
};
|
||||
|
||||
static void *
|
||||
kvaser_usb_leaf_frame_to_cmd(const struct kvaser_usb_net_priv *priv,
|
||||
const struct sk_buff *skb, int *frame_len,
|
||||
@@ -471,6 +517,27 @@ static int kvaser_usb_leaf_send_simple_cmd(const struct kvaser_usb *dev,
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void kvaser_usb_leaf_get_software_info_leaf(struct kvaser_usb *dev,
|
||||
const struct leaf_cmd_softinfo *softinfo)
|
||||
{
|
||||
u32 sw_options = le32_to_cpu(softinfo->sw_options);
|
||||
|
||||
dev->fw_version = le32_to_cpu(softinfo->fw_version);
|
||||
dev->max_tx_urbs = le16_to_cpu(softinfo->max_outstanding_tx);
|
||||
|
||||
switch (sw_options & KVASER_USB_LEAF_SWOPTION_FREQ_MASK) {
|
||||
case KVASER_USB_LEAF_SWOPTION_FREQ_16_MHZ_CLK:
|
||||
dev->cfg = &kvaser_usb_leaf_dev_cfg_16mhz;
|
||||
break;
|
||||
case KVASER_USB_LEAF_SWOPTION_FREQ_24_MHZ_CLK:
|
||||
dev->cfg = &kvaser_usb_leaf_dev_cfg_24mhz;
|
||||
break;
|
||||
case KVASER_USB_LEAF_SWOPTION_FREQ_32_MHZ_CLK:
|
||||
dev->cfg = &kvaser_usb_leaf_dev_cfg_32mhz;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int kvaser_usb_leaf_get_software_info_inner(struct kvaser_usb *dev)
|
||||
{
|
||||
struct kvaser_cmd cmd;
|
||||
@@ -486,14 +553,13 @@ static int kvaser_usb_leaf_get_software_info_inner(struct kvaser_usb *dev)
|
||||
|
||||
switch (dev->card_data.leaf.family) {
|
||||
case KVASER_LEAF:
|
||||
dev->fw_version = le32_to_cpu(cmd.u.leaf.softinfo.fw_version);
|
||||
dev->max_tx_urbs =
|
||||
le16_to_cpu(cmd.u.leaf.softinfo.max_outstanding_tx);
|
||||
kvaser_usb_leaf_get_software_info_leaf(dev, &cmd.u.leaf.softinfo);
|
||||
break;
|
||||
case KVASER_USBCAN:
|
||||
dev->fw_version = le32_to_cpu(cmd.u.usbcan.softinfo.fw_version);
|
||||
dev->max_tx_urbs =
|
||||
le16_to_cpu(cmd.u.usbcan.softinfo.max_outstanding_tx);
|
||||
dev->cfg = &kvaser_usb_leaf_dev_cfg_8mhz;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1225,24 +1291,11 @@ static int kvaser_usb_leaf_init_card(struct kvaser_usb *dev)
|
||||
{
|
||||
struct kvaser_usb_dev_card_data *card_data = &dev->card_data;
|
||||
|
||||
dev->cfg = &kvaser_usb_leaf_dev_cfg;
|
||||
card_data->ctrlmode_supported |= CAN_CTRLMODE_3_SAMPLES;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct can_bittiming_const kvaser_usb_leaf_bittiming_const = {
|
||||
.name = "kvaser_usb",
|
||||
.tseg1_min = KVASER_USB_TSEG1_MIN,
|
||||
.tseg1_max = KVASER_USB_TSEG1_MAX,
|
||||
.tseg2_min = KVASER_USB_TSEG2_MIN,
|
||||
.tseg2_max = KVASER_USB_TSEG2_MAX,
|
||||
.sjw_max = KVASER_USB_SJW_MAX,
|
||||
.brp_min = KVASER_USB_BRP_MIN,
|
||||
.brp_max = KVASER_USB_BRP_MAX,
|
||||
.brp_inc = KVASER_USB_BRP_INC,
|
||||
};
|
||||
|
||||
static int kvaser_usb_leaf_set_bittiming(struct net_device *netdev)
|
||||
{
|
||||
struct kvaser_usb_net_priv *priv = netdev_priv(netdev);
|
||||
@@ -1348,11 +1401,3 @@ const struct kvaser_usb_dev_ops kvaser_usb_leaf_dev_ops = {
|
||||
.dev_read_bulk_callback = kvaser_usb_leaf_read_bulk_callback,
|
||||
.dev_frame_to_cmd = kvaser_usb_leaf_frame_to_cmd,
|
||||
};
|
||||
|
||||
static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_dev_cfg = {
|
||||
.clock = {
|
||||
.freq = CAN_USB_CLOCK,
|
||||
},
|
||||
.timestamp_freq = 1,
|
||||
.bittiming_const = &kvaser_usb_leaf_bittiming_const,
|
||||
};
|
||||
|
||||
@@ -471,6 +471,12 @@ static int mv88e6xxx_port_ppu_updates(struct mv88e6xxx_chip *chip, int port)
|
||||
u16 reg;
|
||||
int err;
|
||||
|
||||
/* The 88e6250 family does not have the PHY detect bit. Instead,
|
||||
* report whether the port is internal.
|
||||
*/
|
||||
if (chip->info->family == MV88E6XXX_FAMILY_6250)
|
||||
return port < chip->info->num_internal_phys;
|
||||
|
||||
err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, ®);
|
||||
if (err) {
|
||||
dev_err(chip->dev,
|
||||
@@ -693,44 +699,48 @@ static void mv88e6xxx_mac_config(struct dsa_switch *ds, int port,
|
||||
{
|
||||
struct mv88e6xxx_chip *chip = ds->priv;
|
||||
struct mv88e6xxx_port *p;
|
||||
int err;
|
||||
int err = 0;
|
||||
|
||||
p = &chip->ports[port];
|
||||
|
||||
/* FIXME: is this the correct test? If we're in fixed mode on an
|
||||
* internal port, why should we process this any different from
|
||||
* PHY mode? On the other hand, the port may be automedia between
|
||||
* an internal PHY and the serdes...
|
||||
*/
|
||||
if ((mode == MLO_AN_PHY) && mv88e6xxx_phy_is_internal(ds, port))
|
||||
return;
|
||||
|
||||
mv88e6xxx_reg_lock(chip);
|
||||
/* In inband mode, the link may come up at any time while the link
|
||||
* is not forced down. Force the link down while we reconfigure the
|
||||
* interface mode.
|
||||
*/
|
||||
if (mode == MLO_AN_INBAND && p->interface != state->interface &&
|
||||
chip->info->ops->port_set_link)
|
||||
chip->info->ops->port_set_link(chip, port, LINK_FORCED_DOWN);
|
||||
|
||||
err = mv88e6xxx_port_config_interface(chip, port, state->interface);
|
||||
if (err && err != -EOPNOTSUPP)
|
||||
goto err_unlock;
|
||||
if (mode != MLO_AN_PHY || !mv88e6xxx_phy_is_internal(ds, port)) {
|
||||
/* In inband mode, the link may come up at any time while the
|
||||
* link is not forced down. Force the link down while we
|
||||
* reconfigure the interface mode.
|
||||
*/
|
||||
if (mode == MLO_AN_INBAND &&
|
||||
p->interface != state->interface &&
|
||||
chip->info->ops->port_set_link)
|
||||
chip->info->ops->port_set_link(chip, port,
|
||||
LINK_FORCED_DOWN);
|
||||
|
||||
err = mv88e6xxx_serdes_pcs_config(chip, port, mode, state->interface,
|
||||
state->advertising);
|
||||
/* FIXME: we should restart negotiation if something changed - which
|
||||
* is something we get if we convert to using phylinks PCS operations.
|
||||
*/
|
||||
if (err > 0)
|
||||
err = 0;
|
||||
err = mv88e6xxx_port_config_interface(chip, port,
|
||||
state->interface);
|
||||
if (err && err != -EOPNOTSUPP)
|
||||
goto err_unlock;
|
||||
|
||||
err = mv88e6xxx_serdes_pcs_config(chip, port, mode,
|
||||
state->interface,
|
||||
state->advertising);
|
||||
/* FIXME: we should restart negotiation if something changed -
|
||||
* which is something we get if we convert to using phylinks
|
||||
* PCS operations.
|
||||
*/
|
||||
if (err > 0)
|
||||
err = 0;
|
||||
}
|
||||
|
||||
/* Undo the forced down state above after completing configuration
|
||||
* irrespective of its state on entry, which allows the link to come up.
|
||||
* irrespective of its state on entry, which allows the link to come
|
||||
* up in the in-band case where there is no separate SERDES. Also
|
||||
* ensure that the link can come up if the PPU is in use and we are
|
||||
* in PHY mode (we treat the PPU as an effective in-band mechanism.)
|
||||
*/
|
||||
if (mode == MLO_AN_INBAND && p->interface != state->interface &&
|
||||
chip->info->ops->port_set_link)
|
||||
if (chip->info->ops->port_set_link &&
|
||||
((mode == MLO_AN_INBAND && p->interface != state->interface) ||
|
||||
(mode == MLO_AN_PHY && mv88e6xxx_port_ppu_updates(chip, port))))
|
||||
chip->info->ops->port_set_link(chip, port, LINK_UNFORCED);
|
||||
|
||||
p->interface = state->interface;
|
||||
@@ -753,11 +763,10 @@ static void mv88e6xxx_mac_link_down(struct dsa_switch *ds, int port,
|
||||
ops = chip->info->ops;
|
||||
|
||||
mv88e6xxx_reg_lock(chip);
|
||||
/* Internal PHYs propagate their configuration directly to the MAC.
|
||||
* External PHYs depend on whether the PPU is enabled for this port.
|
||||
/* Force the link down if we know the port may not be automatically
|
||||
* updated by the switch or if we are using fixed-link mode.
|
||||
*/
|
||||
if (((!mv88e6xxx_phy_is_internal(ds, port) &&
|
||||
!mv88e6xxx_port_ppu_updates(chip, port)) ||
|
||||
if ((!mv88e6xxx_port_ppu_updates(chip, port) ||
|
||||
mode == MLO_AN_FIXED) && ops->port_sync_link)
|
||||
err = ops->port_sync_link(chip, port, mode, false);
|
||||
mv88e6xxx_reg_unlock(chip);
|
||||
@@ -780,11 +789,11 @@ static void mv88e6xxx_mac_link_up(struct dsa_switch *ds, int port,
|
||||
ops = chip->info->ops;
|
||||
|
||||
mv88e6xxx_reg_lock(chip);
|
||||
/* Internal PHYs propagate their configuration directly to the MAC.
|
||||
* External PHYs depend on whether the PPU is enabled for this port.
|
||||
/* Configure and force the link up if we know that the port may not
|
||||
* automatically updated by the switch or if we are using fixed-link
|
||||
* mode.
|
||||
*/
|
||||
if ((!mv88e6xxx_phy_is_internal(ds, port) &&
|
||||
!mv88e6xxx_port_ppu_updates(chip, port)) ||
|
||||
if (!mv88e6xxx_port_ppu_updates(chip, port) ||
|
||||
mode == MLO_AN_FIXED) {
|
||||
/* FIXME: for an automedia port, should we force the link
|
||||
* down here - what if the link comes up due to "other" media
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user