mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-05 18:41:58 +09:00
Merge 6.1.136 into android14-6.1-lts
Changes in 6.1.136 module: sign with sha512 instead of sha1 by default tracing: Add __cpumask to denote a trace event field that is a cpumask_t tracing: Fix cpumask() example typo tracing: Add __string_len() example tracing: Add __print_dynamic_array() helper tracing: Verify event formats that have "%*p.." auxdisplay: hd44780: Convert to platform remove callback returning void auxdisplay: hd44780: Fix an API misuse in hd44780.c net: dsa: mv88e6xxx: don't dispose of Global2 IRQ mappings from mdiobus code net: dsa: add support for mac_prepare() and mac_finish() calls net: dsa: mv88e6xxx: move link forcing to mac_prepare/mac_finish net: dsa: mv88e6xxx: pass directly chip structure to mv88e6xxx_phy_is_internal net: dsa: mv88e6xxx: add field to specify internal phys layout net: dsa: mv88e6xxx: fix internal PHYs for 6320 family net: dsa: mv88e6xxx: fix VTU methods for 6320 family iio: adc: ad7768-1: Move setting of val a bit later to avoid unnecessary return value check iio: adc: ad7768-1: Fix conversion result sign backlight: led_bl: Convert to platform remove callback returning void backlight: led_bl: Hold led_access lock when calling led_sysfs_disable() clk: renesas: rzg2l: Use u32 for flag and mux_flags clk: renesas: rzg2l: Add struct clk_hw_data clk: renesas: rzg2l: Remove CPG_SDHI_DSEL from generic header clk: renesas: rzg2l: Refactor SD mux driver clk: renesas: r9a07g04[34]: Use SEL_SDHI1_STS status configuration for SD1 mux clk: renesas: r9a07g04[34]: Fix typo for sel_shdi variable clk: renesas: r9a07g043: Fix HP clock source for RZ/Five of: resolver: Simplify of_resolve_phandles() using __free() of: resolver: Fix device node refcount leakage in of_resolve_phandles() PCI: Assign PCI domain IDs by ida_alloc() PCI: Fix reference leak in pci_register_host_bridge() phy: freescale: imx8m-pcie: Add i.MX8MP PCIe PHY support phy: freescale: imx8m-pcie: assert phy reset and perst in power off ASoC: qcom: q6dsp: add support to more display ports ASoC: qcom: Fix sc7280 lpass potential buffer overflow selftests/mm: generate a temporary mountpoint for cgroup filesystem dma/contiguous: avoid warning about unused size_bytes cpufreq: scmi: Fix null-ptr-deref in scmi_cpufreq_get_rate() cpufreq: scpi: Fix null-ptr-deref in scpi_cpufreq_get_rate() cpufreq: cppc: Fix invalid return value in .get() callback btrfs: avoid page_lockend underflow in btrfs_punch_hole_lock_range() scsi: core: Clear flags for scsi_cmnd that did not complete net: lwtunnel: disable BHs when required net: phy: leds: fix memory leak tipc: fix NULL pointer dereference in tipc_mon_reinit_self() net_sched: hfsc: Fix a UAF vulnerability in class handling net_sched: hfsc: Fix a potential UAF in hfsc_dequeue() too iommu/amd: Return an error if vCPU affinity is set for non-vCPU IRTE perf/x86: Fix non-sampling (counting) events on certain x86 platforms LoongArch: Select ARCH_USE_MEMTEST LoongArch: Make regs_irqs_disabled() more clear wifi: mac80211: export ieee80211_purge_tx_queue() for drivers wifi: rtw88: use ieee80211_purge_tx_queue() to purge TX skb virtio_console: fix missing byte order handling for cols and rows xen-netfront: handle NULL returned by xdp_convert_buff_to_frame() net: selftests: initialize TCP header and skb payload with zero drm/amd/display: Fix gpu reset in multidisplay config drm/amd/display: Force full update in gpu reset LoongArch: Return NULL from huge_pte_offset() for invalid PMD LoongArch: Remove a bogus reference to ZONE_DMA KVM: SVM: Allocate IR data using atomic allocation mcb: fix a double free bug in chameleon_parse_gdd() USB: storage: quirk for ADATA Portable HDD CH94 mei: me: add panther lake H DID KVM: x86: Explicitly treat routing entry type changes as changes KVM: x86: Reset IRTE to host control if *new* route isn't postable misc: microchip: pci1xxxx: Fix Kernel panic during IRQ handler registration misc: microchip: pci1xxxx: Fix incorrect IRQ status handling during ack serial: msm: Configure correct working mode before starting earlycon serial: sifive: lock port in startup()/shutdown() callbacks USB: serial: ftdi_sio: add support for Abacus Electrics Optical Probe USB: serial: option: add Sierra Wireless EM9291 USB: serial: simple: add OWON HDS200 series oscilloscope support usb: cdns3: Fix deadlock when using NCM gadget usb: chipidea: ci_hdrc_imx: fix usbmisc handling usb: chipidea: ci_hdrc_imx: fix call balance of regulator routines usb: chipidea: ci_hdrc_imx: implement usb_phy_init() error handling USB: OHCI: Add quirk for LS7A OHCI controller (rev 0x02) usb: dwc3: gadget: check that event count does not exceed event buffer length usb: dwc3: xilinx: Prevent spike in reset signal usb: quirks: add DELAY_INIT quirk for Silicon Motion Flash Drive usb: quirks: Add delay init quirk for SanDisk 3.2Gen1 Flash Drive USB: VLI disk crashes if LPM is used USB: wdm: handle IO errors in wdm_wwan_port_start USB: wdm: close race between wdm_open and wdm_wwan_port_stop USB: wdm: wdm_wwan_port_tx_complete mutex in atomic context USB: wdm: add annotation pinctrl: renesas: rza2: Fix potential NULL pointer dereference MIPS: cm: Detect CM quirks from device tree crypto: null - Use spin lock instead of mutex bpf: Fix deadlock between rcu_tasks_trace and event_mutex. clk: check for disabled clock-provider in of_clk_get_hw_from_clkspec() parisc: PDT: Fix missing prototype warning s390/sclp: Add check for get_zeroed_page() s390/tty: Fix a potential memory leak bug usb: host: max3421-hcd: Add missing spi_device_id table fs/ntfs3: Fix WARNING in ntfs_extend_initialized_size usb: dwc3: gadget: Refactor loop to avoid NULL endpoints usb: dwc3: gadget: Avoid using reserved endpoints on Intel Merrifield sound/virtio: Fix cancel_sync warnings on uninitialized work_structs dmaengine: dmatest: Fix dmatest waiting less when interrupted usb: xhci: Avoid Stop Endpoint retry loop if the endpoint seems Running usb: gadget: aspeed: Add NULL pointer check in ast_vhub_init_dev() usb: host: xhci-plat: mvebu: use ->quirks instead of ->init_quirk() func thunderbolt: Scan retimers after device router has been enumerated objtool: Silence more KCOV warnings objtool, ASoC: codecs: wcd934x: Remove potential undefined behavior in wcd934x_slim_irq_handler() objtool, lkdtm: Obfuscate the do_nothing() pointer qibfs: fix _another_ leak ntb: reduce stack usage in idt_scan_mws ntb_hw_amd: Add NTB PCI ID for new gen CPU 9p/net: fix improper handling of bogus negative read/write replies rtc: pcf85063: do a SW reset if POR failed sched/isolation: Make CONFIG_CPU_ISOLATION depend on CONFIG_SMP KVM: s390: Don't use %pK through tracepoints udmabuf: fix a buf size overflow issue during udmabuf creation selftests: ublk: fix test_stripe_04 xen: Change xen-acpi-processor dom0 dependency nvme: requeue namespace scan on missed AENs ACPI: EC: Set ec_no_wakeup for Lenovo Go S ACPI PPTT: Fix coding mistakes in a couple of sizeof() calls nvme: re-read ANA log page after ns scan completes objtool: Stop UNRET validation on UD2 selftests/mincore: Allow read-ahead pages to reach the end of the file x86/bugs: Use SBPB in write_ibpb() if applicable x86/bugs: Don't fill RSB on VMEXIT with eIBRS+retpoline x86/bugs: Don't fill RSB on context switch with eIBRS nvmet-fc: take tgtport reference only once nvmet-fc: put ref when assoc->del_work is already scheduled ext4: make block validity check resistent to sb bh corruption scsi: hisi_sas: Fix I/O errors caused by hardware port ID changes scsi: ufs: exynos: Ensure pre_link() executes before exynos_ufs_phy_init() scsi: pm80xx: Set phy_attached to zero when device is gone x86/i8253: Call clockevent_i8253_disable() with interrupts disabled loop: aio inherit the ioprio of original request spi: tegra210-quad: use WARN_ON_ONCE instead of WARN_ON for timeouts spi: tegra210-quad: add rate limiting and simplify timeout error message ubsan: Fix panic from test_ubsan_out_of_bounds md/raid1: Add check for missing source disk in process_checks() spi: spi-imx: Add check for spi_imx_setupxfer() of: module: add buffer overflow check in of_modalias() jfs: define xtree root and page independently comedi: jr3_pci: Fix synchronous deletion of timer crypto: atmel-sha204a - Set hwrng quality to lowest possible net/sched: act_mirred: don't override retval if we already lost the skb net: dsa: mv88e6xxx: fix atu_move_port_mask for 6341 family net: dsa: mv88e6xxx: enable PVT for 6321 switch net: dsa: mv88e6xxx: enable .port_set_policy() for 6320 family net: dsa: mv88e6xxx: enable STU methods for 6320 family xdp: Reset bpf_redirect_info before running a xdp's BPF prog. MIPS: cm: Fix warning if MIPS_CM is disabled nvme: fixup scan failure for non-ANA multipath controllers phy: freescale: imx8m-pcie: Do CMN_RST just before PHY PLL lock check phy: freescale: imx8m-pcie: Add one missing error return tracing: Remove pointer (asterisk) and brackets from cpumask_t field PCI: Fix use-after-free in pci_bus_release_domain_nr() ASoC: qcom: q6afe-dai: fix Display Port Playback stream name objtool: Silence more KCOV warnings, part 2 Linux 6.1.136 Change-Id: I0649fe0aedec1cc3666200fb579b48f449380179 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
2
Makefile
2
Makefile
@@ -1,7 +1,7 @@
|
|||||||
# SPDX-License-Identifier: GPL-2.0
|
# SPDX-License-Identifier: GPL-2.0
|
||||||
VERSION = 6
|
VERSION = 6
|
||||||
PATCHLEVEL = 1
|
PATCHLEVEL = 1
|
||||||
SUBLEVEL = 135
|
SUBLEVEL = 136
|
||||||
EXTRAVERSION =
|
EXTRAVERSION =
|
||||||
NAME = Curry Ramen
|
NAME = Curry Ramen
|
||||||
|
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ config LOONGARCH
|
|||||||
select ARCH_SUPPORTS_NUMA_BALANCING
|
select ARCH_SUPPORTS_NUMA_BALANCING
|
||||||
select ARCH_USE_BUILTIN_BSWAP
|
select ARCH_USE_BUILTIN_BSWAP
|
||||||
select ARCH_USE_CMPXCHG_LOCKREF
|
select ARCH_USE_CMPXCHG_LOCKREF
|
||||||
|
select ARCH_USE_MEMTEST
|
||||||
select ARCH_USE_QUEUED_RWLOCKS
|
select ARCH_USE_QUEUED_RWLOCKS
|
||||||
select ARCH_USE_QUEUED_SPINLOCKS
|
select ARCH_USE_QUEUED_SPINLOCKS
|
||||||
select ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT
|
select ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT
|
||||||
|
|||||||
@@ -32,9 +32,9 @@ struct pt_regs {
|
|||||||
unsigned long __last[];
|
unsigned long __last[];
|
||||||
} __aligned(8);
|
} __aligned(8);
|
||||||
|
|
||||||
static inline int regs_irqs_disabled(struct pt_regs *regs)
|
static __always_inline bool regs_irqs_disabled(struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
return arch_irqs_disabled_flags(regs->csr_prmd);
|
return !(regs->csr_prmd & CSR_PRMD_PIE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline unsigned long kernel_stack_pointer(struct pt_regs *regs)
|
static inline unsigned long kernel_stack_pointer(struct pt_regs *regs)
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr,
|
|||||||
pmd = pmd_offset(pud, addr);
|
pmd = pmd_offset(pud, addr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (pte_t *) pmd;
|
return pmd_none(pmdp_get(pmd)) ? NULL : (pte_t *) pmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -89,9 +89,6 @@ void __init paging_init(void)
|
|||||||
{
|
{
|
||||||
unsigned long max_zone_pfns[MAX_NR_ZONES];
|
unsigned long max_zone_pfns[MAX_NR_ZONES];
|
||||||
|
|
||||||
#ifdef CONFIG_ZONE_DMA
|
|
||||||
max_zone_pfns[ZONE_DMA] = MAX_DMA_PFN;
|
|
||||||
#endif
|
|
||||||
#ifdef CONFIG_ZONE_DMA32
|
#ifdef CONFIG_ZONE_DMA32
|
||||||
max_zone_pfns[ZONE_DMA32] = MAX_DMA32_PFN;
|
max_zone_pfns[ZONE_DMA32] = MAX_DMA32_PFN;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -47,6 +47,16 @@ extern phys_addr_t __mips_cm_phys_base(void);
|
|||||||
*/
|
*/
|
||||||
extern int mips_cm_is64;
|
extern int mips_cm_is64;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* mips_cm_is_l2_hci_broken - determine if HCI is broken
|
||||||
|
*
|
||||||
|
* Some CM reports show that Hardware Cache Initialization is
|
||||||
|
* complete, but in reality it's not the case. They also incorrectly
|
||||||
|
* indicate that Hardware Cache Initialization is supported. This
|
||||||
|
* flags allows warning about this broken feature.
|
||||||
|
*/
|
||||||
|
extern bool mips_cm_is_l2_hci_broken;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* mips_cm_error_report - Report CM cache errors
|
* mips_cm_error_report - Report CM cache errors
|
||||||
*/
|
*/
|
||||||
@@ -85,6 +95,18 @@ static inline bool mips_cm_present(void)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mips_cm_update_property - update property from the device tree
|
||||||
|
*
|
||||||
|
* Retrieve the properties from the device tree if a CM node exist and
|
||||||
|
* update the internal variable based on this.
|
||||||
|
*/
|
||||||
|
#ifdef CONFIG_MIPS_CM
|
||||||
|
extern void mips_cm_update_property(void);
|
||||||
|
#else
|
||||||
|
static inline void mips_cm_update_property(void) {}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* mips_cm_has_l2sync - determine whether an L2-only sync region is present
|
* mips_cm_has_l2sync - determine whether an L2-only sync region is present
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/errno.h>
|
#include <linux/errno.h>
|
||||||
|
#include <linux/of.h>
|
||||||
#include <linux/percpu.h>
|
#include <linux/percpu.h>
|
||||||
#include <linux/spinlock.h>
|
#include <linux/spinlock.h>
|
||||||
|
|
||||||
@@ -14,6 +15,7 @@
|
|||||||
void __iomem *mips_gcr_base;
|
void __iomem *mips_gcr_base;
|
||||||
void __iomem *mips_cm_l2sync_base;
|
void __iomem *mips_cm_l2sync_base;
|
||||||
int mips_cm_is64;
|
int mips_cm_is64;
|
||||||
|
bool mips_cm_is_l2_hci_broken;
|
||||||
|
|
||||||
static char *cm2_tr[8] = {
|
static char *cm2_tr[8] = {
|
||||||
"mem", "gcr", "gic", "mmio",
|
"mem", "gcr", "gic", "mmio",
|
||||||
@@ -238,6 +240,18 @@ static void mips_cm_probe_l2sync(void)
|
|||||||
mips_cm_l2sync_base = ioremap(addr, MIPS_CM_L2SYNC_SIZE);
|
mips_cm_l2sync_base = ioremap(addr, MIPS_CM_L2SYNC_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void mips_cm_update_property(void)
|
||||||
|
{
|
||||||
|
struct device_node *cm_node;
|
||||||
|
|
||||||
|
cm_node = of_find_compatible_node(of_root, NULL, "mobileye,eyeq6-cm");
|
||||||
|
if (!cm_node)
|
||||||
|
return;
|
||||||
|
pr_info("HCI (Hardware Cache Init for the L2 cache) in GCR_L2_RAM_CONFIG from the CM3 is broken");
|
||||||
|
mips_cm_is_l2_hci_broken = true;
|
||||||
|
of_node_put(cm_node);
|
||||||
|
}
|
||||||
|
|
||||||
int mips_cm_probe(void)
|
int mips_cm_probe(void)
|
||||||
{
|
{
|
||||||
phys_addr_t addr;
|
phys_addr_t addr;
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ static unsigned long pdt_entry[MAX_PDT_ENTRIES] __page_aligned_bss;
|
|||||||
#define PDT_ADDR_PERM_ERR (pdt_type != PDT_PDC ? 2UL : 0UL)
|
#define PDT_ADDR_PERM_ERR (pdt_type != PDT_PDC ? 2UL : 0UL)
|
||||||
#define PDT_ADDR_SINGLE_ERR 1UL
|
#define PDT_ADDR_SINGLE_ERR 1UL
|
||||||
|
|
||||||
|
#ifdef CONFIG_PROC_FS
|
||||||
/* report PDT entries via /proc/meminfo */
|
/* report PDT entries via /proc/meminfo */
|
||||||
void arch_report_meminfo(struct seq_file *m)
|
void arch_report_meminfo(struct seq_file *m)
|
||||||
{
|
{
|
||||||
@@ -73,6 +74,7 @@ void arch_report_meminfo(struct seq_file *m)
|
|||||||
seq_printf(m, "PDT_cur_entries: %7lu\n",
|
seq_printf(m, "PDT_cur_entries: %7lu\n",
|
||||||
pdt_status.pdt_entries);
|
pdt_status.pdt_entries);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static int get_info_pat_new(void)
|
static int get_info_pat_new(void)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ TRACE_EVENT(kvm_s390_create_vcpu,
|
|||||||
__entry->sie_block = sie_block;
|
__entry->sie_block = sie_block;
|
||||||
),
|
),
|
||||||
|
|
||||||
TP_printk("create cpu %d at 0x%pK, sie block at 0x%pK",
|
TP_printk("create cpu %d at 0x%p, sie block at 0x%p",
|
||||||
__entry->id, __entry->vcpu, __entry->sie_block)
|
__entry->id, __entry->vcpu, __entry->sie_block)
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -255,7 +255,7 @@ TRACE_EVENT(kvm_s390_enable_css,
|
|||||||
__entry->kvm = kvm;
|
__entry->kvm = kvm;
|
||||||
),
|
),
|
||||||
|
|
||||||
TP_printk("enabling channel I/O support (kvm @ %pK)\n",
|
TP_printk("enabling channel I/O support (kvm @ %p)\n",
|
||||||
__entry->kvm)
|
__entry->kvm)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
SYM_FUNC_START(entry_ibpb)
|
SYM_FUNC_START(entry_ibpb)
|
||||||
movl $MSR_IA32_PRED_CMD, %ecx
|
movl $MSR_IA32_PRED_CMD, %ecx
|
||||||
movl $PRED_CMD_IBPB, %eax
|
movl _ASM_RIP(x86_pred_cmd), %eax
|
||||||
xorl %edx, %edx
|
xorl %edx, %edx
|
||||||
wrmsr
|
wrmsr
|
||||||
|
|
||||||
|
|||||||
@@ -621,7 +621,7 @@ int x86_pmu_hw_config(struct perf_event *event)
|
|||||||
if (event->attr.type == event->pmu->type)
|
if (event->attr.type == event->pmu->type)
|
||||||
event->hw.config |= event->attr.config & X86_RAW_EVENT_MASK;
|
event->hw.config |= event->attr.config & X86_RAW_EVENT_MASK;
|
||||||
|
|
||||||
if (!event->attr.freq && x86_pmu.limit_period) {
|
if (is_sampling_event(event) && !event->attr.freq && x86_pmu.limit_period) {
|
||||||
s64 left = event->attr.sample_period;
|
s64 left = event->attr.sample_period;
|
||||||
x86_pmu.limit_period(event, &left);
|
x86_pmu.limit_period(event, &left);
|
||||||
if (left > event->attr.sample_period)
|
if (left > event->attr.sample_period)
|
||||||
|
|||||||
@@ -1553,7 +1553,7 @@ static void __init spec_ctrl_disable_kernel_rrsba(void)
|
|||||||
rrsba_disabled = true;
|
rrsba_disabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __init spectre_v2_determine_rsb_fill_type_at_vmexit(enum spectre_v2_mitigation mode)
|
static void __init spectre_v2_select_rsb_mitigation(enum spectre_v2_mitigation mode)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Similar to context switches, there are two types of RSB attacks
|
* Similar to context switches, there are two types of RSB attacks
|
||||||
@@ -1577,27 +1577,30 @@ static void __init spectre_v2_determine_rsb_fill_type_at_vmexit(enum spectre_v2_
|
|||||||
*/
|
*/
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case SPECTRE_V2_NONE:
|
case SPECTRE_V2_NONE:
|
||||||
return;
|
break;
|
||||||
|
|
||||||
case SPECTRE_V2_EIBRS_LFENCE:
|
|
||||||
case SPECTRE_V2_EIBRS:
|
case SPECTRE_V2_EIBRS:
|
||||||
if (boot_cpu_has_bug(X86_BUG_EIBRS_PBRSB)) {
|
case SPECTRE_V2_EIBRS_LFENCE:
|
||||||
setup_force_cpu_cap(X86_FEATURE_RSB_VMEXIT_LITE);
|
|
||||||
pr_info("Spectre v2 / PBRSB-eIBRS: Retire a single CALL on VMEXIT\n");
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
|
|
||||||
case SPECTRE_V2_EIBRS_RETPOLINE:
|
case SPECTRE_V2_EIBRS_RETPOLINE:
|
||||||
|
if (boot_cpu_has_bug(X86_BUG_EIBRS_PBRSB)) {
|
||||||
|
pr_info("Spectre v2 / PBRSB-eIBRS: Retire a single CALL on VMEXIT\n");
|
||||||
|
setup_force_cpu_cap(X86_FEATURE_RSB_VMEXIT_LITE);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case SPECTRE_V2_RETPOLINE:
|
case SPECTRE_V2_RETPOLINE:
|
||||||
case SPECTRE_V2_LFENCE:
|
case SPECTRE_V2_LFENCE:
|
||||||
case SPECTRE_V2_IBRS:
|
case SPECTRE_V2_IBRS:
|
||||||
|
pr_info("Spectre v2 / SpectreRSB: Filling RSB on context switch and VMEXIT\n");
|
||||||
|
setup_force_cpu_cap(X86_FEATURE_RSB_CTXSW);
|
||||||
setup_force_cpu_cap(X86_FEATURE_RSB_VMEXIT);
|
setup_force_cpu_cap(X86_FEATURE_RSB_VMEXIT);
|
||||||
pr_info("Spectre v2 / SpectreRSB : Filling RSB on VMEXIT\n");
|
break;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
pr_warn_once("Unknown Spectre v2 mode, disabling RSB mitigation at VM exit");
|
default:
|
||||||
dump_stack();
|
pr_warn_once("Unknown Spectre v2 mode, disabling RSB mitigation\n");
|
||||||
|
dump_stack();
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1822,10 +1825,7 @@ static void __init spectre_v2_select_mitigation(void)
|
|||||||
*
|
*
|
||||||
* FIXME: Is this pointless for retbleed-affected AMD?
|
* FIXME: Is this pointless for retbleed-affected AMD?
|
||||||
*/
|
*/
|
||||||
setup_force_cpu_cap(X86_FEATURE_RSB_CTXSW);
|
spectre_v2_select_rsb_mitigation(mode);
|
||||||
pr_info("Spectre v2 / SpectreRSB mitigation: Filling RSB on context switch\n");
|
|
||||||
|
|
||||||
spectre_v2_determine_rsb_fill_type_at_vmexit(mode);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Retpoline protects the kernel, but doesn't protect firmware. IBRS
|
* Retpoline protects the kernel, but doesn't protect firmware. IBRS
|
||||||
|
|||||||
@@ -46,7 +46,8 @@ bool __init pit_timer_init(void)
|
|||||||
* VMMs otherwise steal CPU time just to pointlessly waggle
|
* VMMs otherwise steal CPU time just to pointlessly waggle
|
||||||
* the (masked) IRQ.
|
* the (masked) IRQ.
|
||||||
*/
|
*/
|
||||||
clockevent_i8253_disable();
|
scoped_guard(irq)
|
||||||
|
clockevent_i8253_disable();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
clockevent_i8253_init(true);
|
clockevent_i8253_init(true);
|
||||||
|
|||||||
@@ -839,7 +839,7 @@ static int svm_ir_list_add(struct vcpu_svm *svm, struct amd_iommu_pi_data *pi)
|
|||||||
* Allocating new amd_iommu_pi_data, which will get
|
* Allocating new amd_iommu_pi_data, which will get
|
||||||
* add to the per-vcpu ir_list.
|
* add to the per-vcpu ir_list.
|
||||||
*/
|
*/
|
||||||
ir = kzalloc(sizeof(struct amd_svm_iommu_ir), GFP_KERNEL_ACCOUNT);
|
ir = kzalloc(sizeof(struct amd_svm_iommu_ir), GFP_ATOMIC | __GFP_ACCOUNT);
|
||||||
if (!ir) {
|
if (!ir) {
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
goto out;
|
goto out;
|
||||||
@@ -915,6 +915,7 @@ int avic_pi_update_irte(struct kvm *kvm, unsigned int host_irq,
|
|||||||
{
|
{
|
||||||
struct kvm_kernel_irq_routing_entry *e;
|
struct kvm_kernel_irq_routing_entry *e;
|
||||||
struct kvm_irq_routing_table *irq_rt;
|
struct kvm_irq_routing_table *irq_rt;
|
||||||
|
bool enable_remapped_mode = true;
|
||||||
int idx, ret = 0;
|
int idx, ret = 0;
|
||||||
|
|
||||||
if (!kvm_arch_has_assigned_device(kvm) ||
|
if (!kvm_arch_has_assigned_device(kvm) ||
|
||||||
@@ -952,6 +953,8 @@ int avic_pi_update_irte(struct kvm *kvm, unsigned int host_irq,
|
|||||||
kvm_vcpu_apicv_active(&svm->vcpu)) {
|
kvm_vcpu_apicv_active(&svm->vcpu)) {
|
||||||
struct amd_iommu_pi_data pi;
|
struct amd_iommu_pi_data pi;
|
||||||
|
|
||||||
|
enable_remapped_mode = false;
|
||||||
|
|
||||||
/* Try to enable guest_mode in IRTE */
|
/* Try to enable guest_mode in IRTE */
|
||||||
pi.base = __sme_set(page_to_phys(svm->avic_backing_page) &
|
pi.base = __sme_set(page_to_phys(svm->avic_backing_page) &
|
||||||
AVIC_HPA_MASK);
|
AVIC_HPA_MASK);
|
||||||
@@ -970,33 +973,6 @@ int avic_pi_update_irte(struct kvm *kvm, unsigned int host_irq,
|
|||||||
*/
|
*/
|
||||||
if (!ret && pi.is_guest_mode)
|
if (!ret && pi.is_guest_mode)
|
||||||
svm_ir_list_add(svm, &pi);
|
svm_ir_list_add(svm, &pi);
|
||||||
} else {
|
|
||||||
/* Use legacy mode in IRTE */
|
|
||||||
struct amd_iommu_pi_data pi;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Here, pi is used to:
|
|
||||||
* - Tell IOMMU to use legacy mode for this interrupt.
|
|
||||||
* - Retrieve ga_tag of prior interrupt remapping data.
|
|
||||||
*/
|
|
||||||
pi.prev_ga_tag = 0;
|
|
||||||
pi.is_guest_mode = false;
|
|
||||||
ret = irq_set_vcpu_affinity(host_irq, &pi);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if the posted interrupt was previously
|
|
||||||
* setup with the guest_mode by checking if the ga_tag
|
|
||||||
* was cached. If so, we need to clean up the per-vcpu
|
|
||||||
* ir_list.
|
|
||||||
*/
|
|
||||||
if (!ret && pi.prev_ga_tag) {
|
|
||||||
int id = AVIC_GATAG_TO_VCPUID(pi.prev_ga_tag);
|
|
||||||
struct kvm_vcpu *vcpu;
|
|
||||||
|
|
||||||
vcpu = kvm_get_vcpu_by_id(kvm, id);
|
|
||||||
if (vcpu)
|
|
||||||
svm_ir_list_del(to_svm(vcpu), &pi);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ret && svm) {
|
if (!ret && svm) {
|
||||||
@@ -1012,6 +988,34 @@ int avic_pi_update_irte(struct kvm *kvm, unsigned int host_irq,
|
|||||||
}
|
}
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
if (enable_remapped_mode) {
|
||||||
|
/* Use legacy mode in IRTE */
|
||||||
|
struct amd_iommu_pi_data pi;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Here, pi is used to:
|
||||||
|
* - Tell IOMMU to use legacy mode for this interrupt.
|
||||||
|
* - Retrieve ga_tag of prior interrupt remapping data.
|
||||||
|
*/
|
||||||
|
pi.prev_ga_tag = 0;
|
||||||
|
pi.is_guest_mode = false;
|
||||||
|
ret = irq_set_vcpu_affinity(host_irq, &pi);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the posted interrupt was previously
|
||||||
|
* setup with the guest_mode by checking if the ga_tag
|
||||||
|
* was cached. If so, we need to clean up the per-vcpu
|
||||||
|
* ir_list.
|
||||||
|
*/
|
||||||
|
if (!ret && pi.prev_ga_tag) {
|
||||||
|
int id = AVIC_GATAG_TO_VCPUID(pi.prev_ga_tag);
|
||||||
|
struct kvm_vcpu *vcpu;
|
||||||
|
|
||||||
|
vcpu = kvm_get_vcpu_by_id(kvm, id);
|
||||||
|
if (vcpu)
|
||||||
|
svm_ir_list_del(to_svm(vcpu), &pi);
|
||||||
|
}
|
||||||
|
}
|
||||||
out:
|
out:
|
||||||
srcu_read_unlock(&kvm->irq_srcu, idx);
|
srcu_read_unlock(&kvm->irq_srcu, idx);
|
||||||
return ret;
|
return ret;
|
||||||
|
|||||||
@@ -272,6 +272,7 @@ int vmx_pi_update_irte(struct kvm *kvm, unsigned int host_irq,
|
|||||||
{
|
{
|
||||||
struct kvm_kernel_irq_routing_entry *e;
|
struct kvm_kernel_irq_routing_entry *e;
|
||||||
struct kvm_irq_routing_table *irq_rt;
|
struct kvm_irq_routing_table *irq_rt;
|
||||||
|
bool enable_remapped_mode = true;
|
||||||
struct kvm_lapic_irq irq;
|
struct kvm_lapic_irq irq;
|
||||||
struct kvm_vcpu *vcpu;
|
struct kvm_vcpu *vcpu;
|
||||||
struct vcpu_data vcpu_info;
|
struct vcpu_data vcpu_info;
|
||||||
@@ -310,21 +311,8 @@ int vmx_pi_update_irte(struct kvm *kvm, unsigned int host_irq,
|
|||||||
|
|
||||||
kvm_set_msi_irq(kvm, e, &irq);
|
kvm_set_msi_irq(kvm, e, &irq);
|
||||||
if (!kvm_intr_is_single_vcpu(kvm, &irq, &vcpu) ||
|
if (!kvm_intr_is_single_vcpu(kvm, &irq, &vcpu) ||
|
||||||
!kvm_irq_is_postable(&irq)) {
|
!kvm_irq_is_postable(&irq))
|
||||||
/*
|
|
||||||
* Make sure the IRTE is in remapped mode if
|
|
||||||
* we don't handle it in posted mode.
|
|
||||||
*/
|
|
||||||
ret = irq_set_vcpu_affinity(host_irq, NULL);
|
|
||||||
if (ret < 0) {
|
|
||||||
printk(KERN_INFO
|
|
||||||
"failed to back to remapped mode, irq: %u\n",
|
|
||||||
host_irq);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
vcpu_info.pi_desc_addr = __pa(vcpu_to_pi_desc(vcpu));
|
vcpu_info.pi_desc_addr = __pa(vcpu_to_pi_desc(vcpu));
|
||||||
vcpu_info.vector = irq.vector;
|
vcpu_info.vector = irq.vector;
|
||||||
@@ -332,11 +320,12 @@ int vmx_pi_update_irte(struct kvm *kvm, unsigned int host_irq,
|
|||||||
trace_kvm_pi_irte_update(host_irq, vcpu->vcpu_id, e->gsi,
|
trace_kvm_pi_irte_update(host_irq, vcpu->vcpu_id, e->gsi,
|
||||||
vcpu_info.vector, vcpu_info.pi_desc_addr, set);
|
vcpu_info.vector, vcpu_info.pi_desc_addr, set);
|
||||||
|
|
||||||
if (set)
|
if (!set)
|
||||||
ret = irq_set_vcpu_affinity(host_irq, &vcpu_info);
|
continue;
|
||||||
else
|
|
||||||
ret = irq_set_vcpu_affinity(host_irq, NULL);
|
|
||||||
|
|
||||||
|
enable_remapped_mode = false;
|
||||||
|
|
||||||
|
ret = irq_set_vcpu_affinity(host_irq, &vcpu_info);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
printk(KERN_INFO "%s: failed to update PI IRTE\n",
|
printk(KERN_INFO "%s: failed to update PI IRTE\n",
|
||||||
__func__);
|
__func__);
|
||||||
@@ -344,6 +333,9 @@ int vmx_pi_update_irte(struct kvm *kvm, unsigned int host_irq,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (enable_remapped_mode)
|
||||||
|
ret = irq_set_vcpu_affinity(host_irq, NULL);
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
out:
|
out:
|
||||||
srcu_read_unlock(&kvm->irq_srcu, idx);
|
srcu_read_unlock(&kvm->irq_srcu, idx);
|
||||||
|
|||||||
@@ -13426,7 +13426,8 @@ int kvm_arch_update_irqfd_routing(struct kvm *kvm, unsigned int host_irq,
|
|||||||
bool kvm_arch_irqfd_route_changed(struct kvm_kernel_irq_routing_entry *old,
|
bool kvm_arch_irqfd_route_changed(struct kvm_kernel_irq_routing_entry *old,
|
||||||
struct kvm_kernel_irq_routing_entry *new)
|
struct kvm_kernel_irq_routing_entry *new)
|
||||||
{
|
{
|
||||||
if (new->type != KVM_IRQ_ROUTING_MSI)
|
if (old->type != KVM_IRQ_ROUTING_MSI ||
|
||||||
|
new->type != KVM_IRQ_ROUTING_MSI)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return !!memcmp(&old->msi, &new->msi, sizeof(new->msi));
|
return !!memcmp(&old->msi, &new->msi, sizeof(new->msi));
|
||||||
|
|||||||
@@ -385,9 +385,9 @@ static void cond_mitigation(struct task_struct *next)
|
|||||||
prev_mm = this_cpu_read(cpu_tlbstate.last_user_mm_spec);
|
prev_mm = this_cpu_read(cpu_tlbstate.last_user_mm_spec);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Avoid user/user BTB poisoning by flushing the branch predictor
|
* Avoid user->user BTB/RSB poisoning by flushing them when switching
|
||||||
* when switching between processes. This stops one process from
|
* between processes. This stops one process from doing Spectre-v2
|
||||||
* doing Spectre-v2 attacks on another.
|
* attacks on another.
|
||||||
*
|
*
|
||||||
* Both, the conditional and the always IBPB mode use the mm
|
* Both, the conditional and the always IBPB mode use the mm
|
||||||
* pointer to avoid the IBPB when switching between tasks of the
|
* pointer to avoid the IBPB when switching between tasks of the
|
||||||
|
|||||||
@@ -17,10 +17,10 @@
|
|||||||
#include <crypto/internal/skcipher.h>
|
#include <crypto/internal/skcipher.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/mm.h>
|
#include <linux/spinlock.h>
|
||||||
#include <linux/string.h>
|
#include <linux/string.h>
|
||||||
|
|
||||||
static DEFINE_MUTEX(crypto_default_null_skcipher_lock);
|
static DEFINE_SPINLOCK(crypto_default_null_skcipher_lock);
|
||||||
static struct crypto_sync_skcipher *crypto_default_null_skcipher;
|
static struct crypto_sync_skcipher *crypto_default_null_skcipher;
|
||||||
static int crypto_default_null_skcipher_refcnt;
|
static int crypto_default_null_skcipher_refcnt;
|
||||||
|
|
||||||
@@ -152,23 +152,32 @@ MODULE_ALIAS_CRYPTO("cipher_null");
|
|||||||
|
|
||||||
struct crypto_sync_skcipher *crypto_get_default_null_skcipher(void)
|
struct crypto_sync_skcipher *crypto_get_default_null_skcipher(void)
|
||||||
{
|
{
|
||||||
|
struct crypto_sync_skcipher *ntfm = NULL;
|
||||||
struct crypto_sync_skcipher *tfm;
|
struct crypto_sync_skcipher *tfm;
|
||||||
|
|
||||||
mutex_lock(&crypto_default_null_skcipher_lock);
|
spin_lock_bh(&crypto_default_null_skcipher_lock);
|
||||||
tfm = crypto_default_null_skcipher;
|
tfm = crypto_default_null_skcipher;
|
||||||
|
|
||||||
if (!tfm) {
|
if (!tfm) {
|
||||||
tfm = crypto_alloc_sync_skcipher("ecb(cipher_null)", 0, 0);
|
spin_unlock_bh(&crypto_default_null_skcipher_lock);
|
||||||
if (IS_ERR(tfm))
|
|
||||||
goto unlock;
|
|
||||||
|
|
||||||
crypto_default_null_skcipher = tfm;
|
ntfm = crypto_alloc_sync_skcipher("ecb(cipher_null)", 0, 0);
|
||||||
|
if (IS_ERR(ntfm))
|
||||||
|
return ntfm;
|
||||||
|
|
||||||
|
spin_lock_bh(&crypto_default_null_skcipher_lock);
|
||||||
|
tfm = crypto_default_null_skcipher;
|
||||||
|
if (!tfm) {
|
||||||
|
tfm = ntfm;
|
||||||
|
ntfm = NULL;
|
||||||
|
crypto_default_null_skcipher = tfm;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
crypto_default_null_skcipher_refcnt++;
|
crypto_default_null_skcipher_refcnt++;
|
||||||
|
spin_unlock_bh(&crypto_default_null_skcipher_lock);
|
||||||
|
|
||||||
unlock:
|
crypto_free_sync_skcipher(ntfm);
|
||||||
mutex_unlock(&crypto_default_null_skcipher_lock);
|
|
||||||
|
|
||||||
return tfm;
|
return tfm;
|
||||||
}
|
}
|
||||||
@@ -176,12 +185,16 @@ EXPORT_SYMBOL_GPL(crypto_get_default_null_skcipher);
|
|||||||
|
|
||||||
void crypto_put_default_null_skcipher(void)
|
void crypto_put_default_null_skcipher(void)
|
||||||
{
|
{
|
||||||
mutex_lock(&crypto_default_null_skcipher_lock);
|
struct crypto_sync_skcipher *tfm = NULL;
|
||||||
|
|
||||||
|
spin_lock_bh(&crypto_default_null_skcipher_lock);
|
||||||
if (!--crypto_default_null_skcipher_refcnt) {
|
if (!--crypto_default_null_skcipher_refcnt) {
|
||||||
crypto_free_sync_skcipher(crypto_default_null_skcipher);
|
tfm = crypto_default_null_skcipher;
|
||||||
crypto_default_null_skcipher = NULL;
|
crypto_default_null_skcipher = NULL;
|
||||||
}
|
}
|
||||||
mutex_unlock(&crypto_default_null_skcipher_lock);
|
spin_unlock_bh(&crypto_default_null_skcipher_lock);
|
||||||
|
|
||||||
|
crypto_free_sync_skcipher(tfm);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(crypto_put_default_null_skcipher);
|
EXPORT_SYMBOL_GPL(crypto_put_default_null_skcipher);
|
||||||
|
|
||||||
|
|||||||
@@ -2260,6 +2260,34 @@ static const struct dmi_system_id acpi_ec_no_wakeup[] = {
|
|||||||
DMI_MATCH(DMI_PRODUCT_FAMILY, "103C_5336AN HP ZHAN 66 Pro"),
|
DMI_MATCH(DMI_PRODUCT_FAMILY, "103C_5336AN HP ZHAN 66 Pro"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
/*
|
||||||
|
* Lenovo Legion Go S; touchscreen blocks HW sleep when woken up from EC
|
||||||
|
* https://gitlab.freedesktop.org/drm/amd/-/issues/3929
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
.matches = {
|
||||||
|
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
|
||||||
|
DMI_MATCH(DMI_PRODUCT_NAME, "83L3"),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.matches = {
|
||||||
|
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
|
||||||
|
DMI_MATCH(DMI_PRODUCT_NAME, "83N6"),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.matches = {
|
||||||
|
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
|
||||||
|
DMI_MATCH(DMI_PRODUCT_NAME, "83Q2"),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.matches = {
|
||||||
|
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
|
||||||
|
DMI_MATCH(DMI_PRODUCT_NAME, "83Q3"),
|
||||||
|
}
|
||||||
|
},
|
||||||
{ },
|
{ },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -217,7 +217,7 @@ static int acpi_pptt_leaf_node(struct acpi_table_header *table_hdr,
|
|||||||
node_entry = ACPI_PTR_DIFF(node, table_hdr);
|
node_entry = ACPI_PTR_DIFF(node, table_hdr);
|
||||||
entry = ACPI_ADD_PTR(struct acpi_subtable_header, table_hdr,
|
entry = ACPI_ADD_PTR(struct acpi_subtable_header, table_hdr,
|
||||||
sizeof(struct acpi_table_pptt));
|
sizeof(struct acpi_table_pptt));
|
||||||
proc_sz = sizeof(struct acpi_pptt_processor *);
|
proc_sz = sizeof(struct acpi_pptt_processor);
|
||||||
|
|
||||||
while ((unsigned long)entry + proc_sz < table_end) {
|
while ((unsigned long)entry + proc_sz < table_end) {
|
||||||
cpu_node = (struct acpi_pptt_processor *)entry;
|
cpu_node = (struct acpi_pptt_processor *)entry;
|
||||||
@@ -258,7 +258,7 @@ static struct acpi_pptt_processor *acpi_find_processor_node(struct acpi_table_he
|
|||||||
table_end = (unsigned long)table_hdr + table_hdr->length;
|
table_end = (unsigned long)table_hdr + table_hdr->length;
|
||||||
entry = ACPI_ADD_PTR(struct acpi_subtable_header, table_hdr,
|
entry = ACPI_ADD_PTR(struct acpi_subtable_header, table_hdr,
|
||||||
sizeof(struct acpi_table_pptt));
|
sizeof(struct acpi_table_pptt));
|
||||||
proc_sz = sizeof(struct acpi_pptt_processor *);
|
proc_sz = sizeof(struct acpi_pptt_processor);
|
||||||
|
|
||||||
/* find the processor structure associated with this cpuid */
|
/* find the processor structure associated with this cpuid */
|
||||||
while ((unsigned long)entry + proc_sz < table_end) {
|
while ((unsigned long)entry + proc_sz < table_end) {
|
||||||
|
|||||||
@@ -313,13 +313,13 @@ static int hd44780_probe(struct platform_device *pdev)
|
|||||||
fail3:
|
fail3:
|
||||||
kfree(hd);
|
kfree(hd);
|
||||||
fail2:
|
fail2:
|
||||||
kfree(lcd);
|
charlcd_free(lcd);
|
||||||
fail1:
|
fail1:
|
||||||
kfree(hdc);
|
kfree(hdc);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int hd44780_remove(struct platform_device *pdev)
|
static void hd44780_remove(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct charlcd *lcd = platform_get_drvdata(pdev);
|
struct charlcd *lcd = platform_get_drvdata(pdev);
|
||||||
struct hd44780_common *hdc = lcd->drvdata;
|
struct hd44780_common *hdc = lcd->drvdata;
|
||||||
@@ -328,8 +328,7 @@ static int hd44780_remove(struct platform_device *pdev)
|
|||||||
kfree(hdc->hd44780);
|
kfree(hdc->hd44780);
|
||||||
kfree(lcd->drvdata);
|
kfree(lcd->drvdata);
|
||||||
|
|
||||||
kfree(lcd);
|
charlcd_free(lcd);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct of_device_id hd44780_of_match[] = {
|
static const struct of_device_id hd44780_of_match[] = {
|
||||||
@@ -340,7 +339,7 @@ MODULE_DEVICE_TABLE(of, hd44780_of_match);
|
|||||||
|
|
||||||
static struct platform_driver hd44780_driver = {
|
static struct platform_driver hd44780_driver = {
|
||||||
.probe = hd44780_probe,
|
.probe = hd44780_probe,
|
||||||
.remove = hd44780_remove,
|
.remove_new = hd44780_remove,
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "hd44780",
|
.name = "hd44780",
|
||||||
.of_match_table = hd44780_of_match,
|
.of_match_table = hd44780_of_match,
|
||||||
|
|||||||
@@ -441,7 +441,7 @@ static int lo_rw_aio(struct loop_device *lo, struct loop_cmd *cmd,
|
|||||||
cmd->iocb.ki_filp = file;
|
cmd->iocb.ki_filp = file;
|
||||||
cmd->iocb.ki_complete = lo_rw_aio_complete;
|
cmd->iocb.ki_complete = lo_rw_aio_complete;
|
||||||
cmd->iocb.ki_flags = IOCB_DIRECT;
|
cmd->iocb.ki_flags = IOCB_DIRECT;
|
||||||
cmd->iocb.ki_ioprio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_NONE, 0);
|
cmd->iocb.ki_ioprio = req_get_ioprio(rq);
|
||||||
|
|
||||||
if (rw == ITER_SOURCE)
|
if (rw == ITER_SOURCE)
|
||||||
ret = call_write_iter(file, &cmd->iocb, &iter);
|
ret = call_write_iter(file, &cmd->iocb, &iter);
|
||||||
|
|||||||
@@ -1615,8 +1615,8 @@ static void handle_control_message(struct virtio_device *vdev,
|
|||||||
break;
|
break;
|
||||||
case VIRTIO_CONSOLE_RESIZE: {
|
case VIRTIO_CONSOLE_RESIZE: {
|
||||||
struct {
|
struct {
|
||||||
__u16 rows;
|
__virtio16 rows;
|
||||||
__u16 cols;
|
__virtio16 cols;
|
||||||
} size;
|
} size;
|
||||||
|
|
||||||
if (!is_console_port(port))
|
if (!is_console_port(port))
|
||||||
@@ -1624,7 +1624,8 @@ static void handle_control_message(struct virtio_device *vdev,
|
|||||||
|
|
||||||
memcpy(&size, buf->buf + buf->offset + sizeof(*cpkt),
|
memcpy(&size, buf->buf + buf->offset + sizeof(*cpkt),
|
||||||
sizeof(size));
|
sizeof(size));
|
||||||
set_console_size(port, size.rows, size.cols);
|
set_console_size(port, virtio16_to_cpu(vdev, size.rows),
|
||||||
|
virtio16_to_cpu(vdev, size.cols));
|
||||||
|
|
||||||
port->cons.hvc->irq_requested = 1;
|
port->cons.hvc->irq_requested = 1;
|
||||||
resize_console(port);
|
resize_console(port);
|
||||||
|
|||||||
@@ -5193,6 +5193,10 @@ of_clk_get_hw_from_clkspec(struct of_phandle_args *clkspec)
|
|||||||
if (!clkspec)
|
if (!clkspec)
|
||||||
return ERR_PTR(-EINVAL);
|
return ERR_PTR(-EINVAL);
|
||||||
|
|
||||||
|
/* Check if node in clkspec is in disabled/fail state */
|
||||||
|
if (!of_device_is_available(clkspec->np))
|
||||||
|
return ERR_PTR(-ENOENT);
|
||||||
|
|
||||||
mutex_lock(&of_clk_mutex);
|
mutex_lock(&of_clk_mutex);
|
||||||
list_for_each_entry(provider, &of_clk_providers, link) {
|
list_for_each_entry(provider, &of_clk_providers, link) {
|
||||||
if (provider->node == clkspec->np) {
|
if (provider->node == clkspec->np) {
|
||||||
|
|||||||
@@ -14,6 +14,17 @@
|
|||||||
|
|
||||||
#include "rzg2l-cpg.h"
|
#include "rzg2l-cpg.h"
|
||||||
|
|
||||||
|
/* Specific registers. */
|
||||||
|
#define CPG_PL2SDHI_DSEL (0x218)
|
||||||
|
|
||||||
|
/* Clock select configuration. */
|
||||||
|
#define SEL_SDHI0 SEL_PLL_PACK(CPG_PL2SDHI_DSEL, 0, 2)
|
||||||
|
#define SEL_SDHI1 SEL_PLL_PACK(CPG_PL2SDHI_DSEL, 4, 2)
|
||||||
|
|
||||||
|
/* Clock status configuration. */
|
||||||
|
#define SEL_SDHI0_STS SEL_PLL_PACK(CPG_CLKSTATUS, 28, 1)
|
||||||
|
#define SEL_SDHI1_STS SEL_PLL_PACK(CPG_CLKSTATUS, 29, 1)
|
||||||
|
|
||||||
enum clk_ids {
|
enum clk_ids {
|
||||||
/* Core Clock Outputs exported to DT */
|
/* Core Clock Outputs exported to DT */
|
||||||
LAST_DT_CORE_CLK = R9A07G043_CLK_P0_DIV2,
|
LAST_DT_CORE_CLK = R9A07G043_CLK_P0_DIV2,
|
||||||
@@ -75,8 +86,12 @@ static const struct clk_div_table dtable_1_32[] = {
|
|||||||
|
|
||||||
/* Mux clock tables */
|
/* Mux clock tables */
|
||||||
static const char * const sel_pll3_3[] = { ".pll3_533", ".pll3_400" };
|
static const char * const sel_pll3_3[] = { ".pll3_533", ".pll3_400" };
|
||||||
|
#ifdef CONFIG_ARM64
|
||||||
static const char * const sel_pll6_2[] = { ".pll6_250", ".pll5_250" };
|
static const char * const sel_pll6_2[] = { ".pll6_250", ".pll5_250" };
|
||||||
static const char * const sel_shdi[] = { ".clk_533", ".clk_400", ".clk_266" };
|
#endif
|
||||||
|
static const char * const sel_sdhi[] = { ".clk_533", ".clk_400", ".clk_266" };
|
||||||
|
|
||||||
|
static const u32 mtable_sdhi[] = { 1, 2, 3 };
|
||||||
|
|
||||||
static const struct cpg_core_clk r9a07g043_core_clks[] __initconst = {
|
static const struct cpg_core_clk r9a07g043_core_clks[] __initconst = {
|
||||||
/* External Clock Inputs */
|
/* External Clock Inputs */
|
||||||
@@ -120,11 +135,18 @@ static const struct cpg_core_clk r9a07g043_core_clks[] __initconst = {
|
|||||||
DEF_DIV("P2", R9A07G043_CLK_P2, CLK_PLL3_DIV2_4_2, DIVPL3A, dtable_1_32),
|
DEF_DIV("P2", R9A07G043_CLK_P2, CLK_PLL3_DIV2_4_2, DIVPL3A, dtable_1_32),
|
||||||
DEF_FIXED("M0", R9A07G043_CLK_M0, CLK_PLL3_DIV2_4, 1, 1),
|
DEF_FIXED("M0", R9A07G043_CLK_M0, CLK_PLL3_DIV2_4, 1, 1),
|
||||||
DEF_FIXED("ZT", R9A07G043_CLK_ZT, CLK_PLL3_DIV2_4_2, 1, 1),
|
DEF_FIXED("ZT", R9A07G043_CLK_ZT, CLK_PLL3_DIV2_4_2, 1, 1),
|
||||||
|
#ifdef CONFIG_ARM64
|
||||||
DEF_MUX("HP", R9A07G043_CLK_HP, SEL_PLL6_2, sel_pll6_2),
|
DEF_MUX("HP", R9A07G043_CLK_HP, SEL_PLL6_2, sel_pll6_2),
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_RISCV
|
||||||
|
DEF_FIXED("HP", R9A07G043_CLK_HP, CLK_PLL6_250, 1, 1),
|
||||||
|
#endif
|
||||||
DEF_FIXED("SPI0", R9A07G043_CLK_SPI0, CLK_DIV_PLL3_C, 1, 2),
|
DEF_FIXED("SPI0", R9A07G043_CLK_SPI0, CLK_DIV_PLL3_C, 1, 2),
|
||||||
DEF_FIXED("SPI1", R9A07G043_CLK_SPI1, CLK_DIV_PLL3_C, 1, 4),
|
DEF_FIXED("SPI1", R9A07G043_CLK_SPI1, CLK_DIV_PLL3_C, 1, 4),
|
||||||
DEF_SD_MUX("SD0", R9A07G043_CLK_SD0, SEL_SDHI0, sel_shdi),
|
DEF_SD_MUX("SD0", R9A07G043_CLK_SD0, SEL_SDHI0, SEL_SDHI0_STS, sel_sdhi,
|
||||||
DEF_SD_MUX("SD1", R9A07G043_CLK_SD1, SEL_SDHI1, sel_shdi),
|
mtable_sdhi, 0, rzg2l_cpg_sd_clk_mux_notifier),
|
||||||
|
DEF_SD_MUX("SD1", R9A07G043_CLK_SD1, SEL_SDHI1, SEL_SDHI1_STS, sel_sdhi,
|
||||||
|
mtable_sdhi, 0, rzg2l_cpg_sd_clk_mux_notifier),
|
||||||
DEF_FIXED("SD0_DIV4", CLK_SD0_DIV4, R9A07G043_CLK_SD0, 1, 4),
|
DEF_FIXED("SD0_DIV4", CLK_SD0_DIV4, R9A07G043_CLK_SD0, 1, 4),
|
||||||
DEF_FIXED("SD1_DIV4", CLK_SD1_DIV4, R9A07G043_CLK_SD1, 1, 4),
|
DEF_FIXED("SD1_DIV4", CLK_SD1_DIV4, R9A07G043_CLK_SD1, 1, 4),
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -15,6 +15,17 @@
|
|||||||
|
|
||||||
#include "rzg2l-cpg.h"
|
#include "rzg2l-cpg.h"
|
||||||
|
|
||||||
|
/* Specific registers. */
|
||||||
|
#define CPG_PL2SDHI_DSEL (0x218)
|
||||||
|
|
||||||
|
/* Clock select configuration. */
|
||||||
|
#define SEL_SDHI0 SEL_PLL_PACK(CPG_PL2SDHI_DSEL, 0, 2)
|
||||||
|
#define SEL_SDHI1 SEL_PLL_PACK(CPG_PL2SDHI_DSEL, 4, 2)
|
||||||
|
|
||||||
|
/* Clock status configuration. */
|
||||||
|
#define SEL_SDHI0_STS SEL_PLL_PACK(CPG_CLKSTATUS, 28, 1)
|
||||||
|
#define SEL_SDHI1_STS SEL_PLL_PACK(CPG_CLKSTATUS, 29, 1)
|
||||||
|
|
||||||
enum clk_ids {
|
enum clk_ids {
|
||||||
/* Core Clock Outputs exported to DT */
|
/* Core Clock Outputs exported to DT */
|
||||||
LAST_DT_CORE_CLK = R9A07G054_CLK_DRP_A,
|
LAST_DT_CORE_CLK = R9A07G054_CLK_DRP_A,
|
||||||
@@ -95,9 +106,11 @@ static const struct clk_div_table dtable_16_128[] = {
|
|||||||
static const char * const sel_pll3_3[] = { ".pll3_533", ".pll3_400" };
|
static const char * const sel_pll3_3[] = { ".pll3_533", ".pll3_400" };
|
||||||
static const char * const sel_pll5_4[] = { ".pll5_foutpostdiv", ".pll5_fout1ph0" };
|
static const char * const sel_pll5_4[] = { ".pll5_foutpostdiv", ".pll5_fout1ph0" };
|
||||||
static const char * const sel_pll6_2[] = { ".pll6_250", ".pll5_250" };
|
static const char * const sel_pll6_2[] = { ".pll6_250", ".pll5_250" };
|
||||||
static const char * const sel_shdi[] = { ".clk_533", ".clk_400", ".clk_266" };
|
static const char * const sel_sdhi[] = { ".clk_533", ".clk_400", ".clk_266" };
|
||||||
static const char * const sel_gpu2[] = { ".pll6", ".pll3_div2_2" };
|
static const char * const sel_gpu2[] = { ".pll6", ".pll3_div2_2" };
|
||||||
|
|
||||||
|
static const u32 mtable_sdhi[] = { 1, 2, 3 };
|
||||||
|
|
||||||
static const struct {
|
static const struct {
|
||||||
struct cpg_core_clk common[56];
|
struct cpg_core_clk common[56];
|
||||||
#ifdef CONFIG_CLK_R9A07G054
|
#ifdef CONFIG_CLK_R9A07G054
|
||||||
@@ -163,8 +176,10 @@ static const struct {
|
|||||||
DEF_MUX("HP", R9A07G044_CLK_HP, SEL_PLL6_2, sel_pll6_2),
|
DEF_MUX("HP", R9A07G044_CLK_HP, SEL_PLL6_2, sel_pll6_2),
|
||||||
DEF_FIXED("SPI0", R9A07G044_CLK_SPI0, CLK_DIV_PLL3_C, 1, 2),
|
DEF_FIXED("SPI0", R9A07G044_CLK_SPI0, CLK_DIV_PLL3_C, 1, 2),
|
||||||
DEF_FIXED("SPI1", R9A07G044_CLK_SPI1, CLK_DIV_PLL3_C, 1, 4),
|
DEF_FIXED("SPI1", R9A07G044_CLK_SPI1, CLK_DIV_PLL3_C, 1, 4),
|
||||||
DEF_SD_MUX("SD0", R9A07G044_CLK_SD0, SEL_SDHI0, sel_shdi),
|
DEF_SD_MUX("SD0", R9A07G044_CLK_SD0, SEL_SDHI0, SEL_SDHI0_STS, sel_sdhi,
|
||||||
DEF_SD_MUX("SD1", R9A07G044_CLK_SD1, SEL_SDHI1, sel_shdi),
|
mtable_sdhi, 0, rzg2l_cpg_sd_clk_mux_notifier),
|
||||||
|
DEF_SD_MUX("SD1", R9A07G044_CLK_SD1, SEL_SDHI1, SEL_SDHI1_STS, sel_sdhi,
|
||||||
|
mtable_sdhi, 0, rzg2l_cpg_sd_clk_mux_notifier),
|
||||||
DEF_FIXED("SD0_DIV4", CLK_SD0_DIV4, R9A07G044_CLK_SD0, 1, 4),
|
DEF_FIXED("SD0_DIV4", CLK_SD0_DIV4, R9A07G044_CLK_SD0, 1, 4),
|
||||||
DEF_FIXED("SD1_DIV4", CLK_SD1_DIV4, R9A07G044_CLK_SD1, 1, 4),
|
DEF_FIXED("SD1_DIV4", CLK_SD1_DIV4, R9A07G044_CLK_SD1, 1, 4),
|
||||||
DEF_DIV("G", R9A07G044_CLK_G, CLK_SEL_GPU2, DIVGPU, dtable_1_8),
|
DEF_DIV("G", R9A07G044_CLK_G, CLK_SEL_GPU2, DIVGPU, dtable_1_8),
|
||||||
|
|||||||
@@ -57,15 +57,37 @@
|
|||||||
#define GET_REG_SAMPLL_CLK1(val) ((val >> 22) & 0xfff)
|
#define GET_REG_SAMPLL_CLK1(val) ((val >> 22) & 0xfff)
|
||||||
#define GET_REG_SAMPLL_CLK2(val) ((val >> 12) & 0xfff)
|
#define GET_REG_SAMPLL_CLK2(val) ((val >> 12) & 0xfff)
|
||||||
|
|
||||||
|
#define CPG_WEN_BIT BIT(16)
|
||||||
|
|
||||||
#define MAX_VCLK_FREQ (148500000)
|
#define MAX_VCLK_FREQ (148500000)
|
||||||
|
|
||||||
struct sd_hw_data {
|
/**
|
||||||
|
* struct clk_hw_data - clock hardware data
|
||||||
|
* @hw: clock hw
|
||||||
|
* @conf: clock configuration (register offset, shift, width)
|
||||||
|
* @sconf: clock status configuration (register offset, shift, width)
|
||||||
|
* @priv: CPG private data structure
|
||||||
|
*/
|
||||||
|
struct clk_hw_data {
|
||||||
struct clk_hw hw;
|
struct clk_hw hw;
|
||||||
u32 conf;
|
u32 conf;
|
||||||
|
u32 sconf;
|
||||||
struct rzg2l_cpg_priv *priv;
|
struct rzg2l_cpg_priv *priv;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define to_sd_hw_data(_hw) container_of(_hw, struct sd_hw_data, hw)
|
#define to_clk_hw_data(_hw) container_of(_hw, struct clk_hw_data, hw)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct sd_mux_hw_data - SD MUX clock hardware data
|
||||||
|
* @hw_data: clock hw data
|
||||||
|
* @mtable: clock mux table
|
||||||
|
*/
|
||||||
|
struct sd_mux_hw_data {
|
||||||
|
struct clk_hw_data hw_data;
|
||||||
|
const u32 *mtable;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define to_sd_mux_hw_data(_hw) container_of(_hw, struct sd_mux_hw_data, hw_data)
|
||||||
|
|
||||||
struct rzg2l_pll5_param {
|
struct rzg2l_pll5_param {
|
||||||
u32 pl5_fracin;
|
u32 pl5_fracin;
|
||||||
@@ -119,6 +141,76 @@ static void rzg2l_cpg_del_clk_provider(void *data)
|
|||||||
of_clk_del_provider(data);
|
of_clk_del_provider(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Must be called in atomic context. */
|
||||||
|
static int rzg2l_cpg_wait_clk_update_done(void __iomem *base, u32 conf)
|
||||||
|
{
|
||||||
|
u32 bitmask = GENMASK(GET_WIDTH(conf) - 1, 0) << GET_SHIFT(conf);
|
||||||
|
u32 off = GET_REG_OFFSET(conf);
|
||||||
|
u32 val;
|
||||||
|
|
||||||
|
return readl_poll_timeout_atomic(base + off, val, !(val & bitmask), 10, 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
int rzg2l_cpg_sd_clk_mux_notifier(struct notifier_block *nb, unsigned long event,
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
struct clk_notifier_data *cnd = data;
|
||||||
|
struct clk_hw *hw = __clk_get_hw(cnd->clk);
|
||||||
|
struct clk_hw_data *clk_hw_data = to_clk_hw_data(hw);
|
||||||
|
struct rzg2l_cpg_priv *priv = clk_hw_data->priv;
|
||||||
|
u32 off = GET_REG_OFFSET(clk_hw_data->conf);
|
||||||
|
u32 shift = GET_SHIFT(clk_hw_data->conf);
|
||||||
|
const u32 clk_src_266 = 3;
|
||||||
|
unsigned long flags;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (event != PRE_RATE_CHANGE || (cnd->new_rate / MEGA == 266))
|
||||||
|
return NOTIFY_DONE;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&priv->rmw_lock, flags);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* As per the HW manual, we should not directly switch from 533 MHz to
|
||||||
|
* 400 MHz and vice versa. To change the setting from 2’b01 (533 MHz)
|
||||||
|
* to 2’b10 (400 MHz) or vice versa, Switch to 2’b11 (266 MHz) first,
|
||||||
|
* and then switch to the target setting (2’b01 (533 MHz) or 2’b10
|
||||||
|
* (400 MHz)).
|
||||||
|
* Setting a value of '0' to the SEL_SDHI0_SET or SEL_SDHI1_SET clock
|
||||||
|
* switching register is prohibited.
|
||||||
|
* The clock mux has 3 input clocks(533 MHz, 400 MHz, and 266 MHz), and
|
||||||
|
* the index to value mapping is done by adding 1 to the index.
|
||||||
|
*/
|
||||||
|
|
||||||
|
writel((CPG_WEN_BIT | clk_src_266) << shift, priv->base + off);
|
||||||
|
|
||||||
|
/* Wait for the update done. */
|
||||||
|
ret = rzg2l_cpg_wait_clk_update_done(priv->base, clk_hw_data->sconf);
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(&priv->rmw_lock, flags);
|
||||||
|
|
||||||
|
if (ret)
|
||||||
|
dev_err(priv->dev, "failed to switch to safe clk source\n");
|
||||||
|
|
||||||
|
return notifier_from_errno(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rzg2l_register_notifier(struct clk_hw *hw, const struct cpg_core_clk *core,
|
||||||
|
struct rzg2l_cpg_priv *priv)
|
||||||
|
{
|
||||||
|
struct notifier_block *nb;
|
||||||
|
|
||||||
|
if (!core->notifier)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
nb = devm_kzalloc(priv->dev, sizeof(*nb), GFP_KERNEL);
|
||||||
|
if (!nb)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
nb->notifier_call = core->notifier;
|
||||||
|
|
||||||
|
return clk_notifier_register(hw->clk, nb);
|
||||||
|
}
|
||||||
|
|
||||||
static struct clk * __init
|
static struct clk * __init
|
||||||
rzg2l_cpg_div_clk_register(const struct cpg_core_clk *core,
|
rzg2l_cpg_div_clk_register(const struct cpg_core_clk *core,
|
||||||
struct clk **clks,
|
struct clk **clks,
|
||||||
@@ -187,63 +279,44 @@ static int rzg2l_cpg_sd_clk_mux_determine_rate(struct clk_hw *hw,
|
|||||||
|
|
||||||
static int rzg2l_cpg_sd_clk_mux_set_parent(struct clk_hw *hw, u8 index)
|
static int rzg2l_cpg_sd_clk_mux_set_parent(struct clk_hw *hw, u8 index)
|
||||||
{
|
{
|
||||||
struct sd_hw_data *hwdata = to_sd_hw_data(hw);
|
struct clk_hw_data *clk_hw_data = to_clk_hw_data(hw);
|
||||||
struct rzg2l_cpg_priv *priv = hwdata->priv;
|
struct sd_mux_hw_data *sd_mux_hw_data = to_sd_mux_hw_data(clk_hw_data);
|
||||||
u32 off = GET_REG_OFFSET(hwdata->conf);
|
struct rzg2l_cpg_priv *priv = clk_hw_data->priv;
|
||||||
u32 shift = GET_SHIFT(hwdata->conf);
|
u32 off = GET_REG_OFFSET(clk_hw_data->conf);
|
||||||
const u32 clk_src_266 = 2;
|
u32 shift = GET_SHIFT(clk_hw_data->conf);
|
||||||
u32 msk, val, bitmask;
|
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
u32 val;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/*
|
val = clk_mux_index_to_val(sd_mux_hw_data->mtable, CLK_MUX_ROUND_CLOSEST, index);
|
||||||
* As per the HW manual, we should not directly switch from 533 MHz to
|
|
||||||
* 400 MHz and vice versa. To change the setting from 2’b01 (533 MHz)
|
|
||||||
* to 2’b10 (400 MHz) or vice versa, Switch to 2’b11 (266 MHz) first,
|
|
||||||
* and then switch to the target setting (2’b01 (533 MHz) or 2’b10
|
|
||||||
* (400 MHz)).
|
|
||||||
* Setting a value of '0' to the SEL_SDHI0_SET or SEL_SDHI1_SET clock
|
|
||||||
* switching register is prohibited.
|
|
||||||
* The clock mux has 3 input clocks(533 MHz, 400 MHz, and 266 MHz), and
|
|
||||||
* the index to value mapping is done by adding 1 to the index.
|
|
||||||
*/
|
|
||||||
bitmask = (GENMASK(GET_WIDTH(hwdata->conf) - 1, 0) << shift) << 16;
|
|
||||||
msk = off ? CPG_CLKSTATUS_SELSDHI1_STS : CPG_CLKSTATUS_SELSDHI0_STS;
|
|
||||||
spin_lock_irqsave(&priv->rmw_lock, flags);
|
spin_lock_irqsave(&priv->rmw_lock, flags);
|
||||||
if (index != clk_src_266) {
|
|
||||||
writel(bitmask | ((clk_src_266 + 1) << shift), priv->base + off);
|
|
||||||
|
|
||||||
ret = readl_poll_timeout_atomic(priv->base + CPG_CLKSTATUS, val,
|
writel((CPG_WEN_BIT | val) << shift, priv->base + off);
|
||||||
!(val & msk), 10,
|
|
||||||
CPG_SDHI_CLK_SWITCH_STATUS_TIMEOUT_US);
|
|
||||||
if (ret)
|
|
||||||
goto unlock;
|
|
||||||
}
|
|
||||||
|
|
||||||
writel(bitmask | ((index + 1) << shift), priv->base + off);
|
/* Wait for the update done. */
|
||||||
|
ret = rzg2l_cpg_wait_clk_update_done(priv->base, clk_hw_data->sconf);
|
||||||
|
|
||||||
ret = readl_poll_timeout_atomic(priv->base + CPG_CLKSTATUS, val,
|
|
||||||
!(val & msk), 10,
|
|
||||||
CPG_SDHI_CLK_SWITCH_STATUS_TIMEOUT_US);
|
|
||||||
unlock:
|
|
||||||
spin_unlock_irqrestore(&priv->rmw_lock, flags);
|
spin_unlock_irqrestore(&priv->rmw_lock, flags);
|
||||||
|
|
||||||
if (ret)
|
if (ret)
|
||||||
dev_err(priv->dev, "failed to switch clk source\n");
|
dev_err(priv->dev, "Failed to switch parent\n");
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static u8 rzg2l_cpg_sd_clk_mux_get_parent(struct clk_hw *hw)
|
static u8 rzg2l_cpg_sd_clk_mux_get_parent(struct clk_hw *hw)
|
||||||
{
|
{
|
||||||
struct sd_hw_data *hwdata = to_sd_hw_data(hw);
|
struct clk_hw_data *clk_hw_data = to_clk_hw_data(hw);
|
||||||
struct rzg2l_cpg_priv *priv = hwdata->priv;
|
struct sd_mux_hw_data *sd_mux_hw_data = to_sd_mux_hw_data(clk_hw_data);
|
||||||
u32 val = readl(priv->base + GET_REG_OFFSET(hwdata->conf));
|
struct rzg2l_cpg_priv *priv = clk_hw_data->priv;
|
||||||
|
u32 val;
|
||||||
|
|
||||||
val >>= GET_SHIFT(hwdata->conf);
|
val = readl(priv->base + GET_REG_OFFSET(clk_hw_data->conf));
|
||||||
val &= GENMASK(GET_WIDTH(hwdata->conf) - 1, 0);
|
val >>= GET_SHIFT(clk_hw_data->conf);
|
||||||
|
val &= GENMASK(GET_WIDTH(clk_hw_data->conf) - 1, 0);
|
||||||
|
|
||||||
return val ? val - 1 : 0;
|
return clk_mux_val_to_index(hw, sd_mux_hw_data->mtable, CLK_MUX_ROUND_CLOSEST, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct clk_ops rzg2l_cpg_sd_clk_mux_ops = {
|
static const struct clk_ops rzg2l_cpg_sd_clk_mux_ops = {
|
||||||
@@ -257,31 +330,40 @@ rzg2l_cpg_sd_mux_clk_register(const struct cpg_core_clk *core,
|
|||||||
void __iomem *base,
|
void __iomem *base,
|
||||||
struct rzg2l_cpg_priv *priv)
|
struct rzg2l_cpg_priv *priv)
|
||||||
{
|
{
|
||||||
struct sd_hw_data *clk_hw_data;
|
struct sd_mux_hw_data *sd_mux_hw_data;
|
||||||
struct clk_init_data init;
|
struct clk_init_data init;
|
||||||
struct clk_hw *clk_hw;
|
struct clk_hw *clk_hw;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
clk_hw_data = devm_kzalloc(priv->dev, sizeof(*clk_hw_data), GFP_KERNEL);
|
sd_mux_hw_data = devm_kzalloc(priv->dev, sizeof(*sd_mux_hw_data), GFP_KERNEL);
|
||||||
if (!clk_hw_data)
|
if (!sd_mux_hw_data)
|
||||||
return ERR_PTR(-ENOMEM);
|
return ERR_PTR(-ENOMEM);
|
||||||
|
|
||||||
clk_hw_data->priv = priv;
|
sd_mux_hw_data->hw_data.priv = priv;
|
||||||
clk_hw_data->conf = core->conf;
|
sd_mux_hw_data->hw_data.conf = core->conf;
|
||||||
|
sd_mux_hw_data->hw_data.sconf = core->sconf;
|
||||||
|
sd_mux_hw_data->mtable = core->mtable;
|
||||||
|
|
||||||
init.name = GET_SHIFT(core->conf) ? "sd1" : "sd0";
|
init.name = GET_SHIFT(core->conf) ? "sd1" : "sd0";
|
||||||
init.ops = &rzg2l_cpg_sd_clk_mux_ops;
|
init.ops = &rzg2l_cpg_sd_clk_mux_ops;
|
||||||
init.flags = 0;
|
init.flags = core->flag;
|
||||||
init.num_parents = core->num_parents;
|
init.num_parents = core->num_parents;
|
||||||
init.parent_names = core->parent_names;
|
init.parent_names = core->parent_names;
|
||||||
|
|
||||||
clk_hw = &clk_hw_data->hw;
|
clk_hw = &sd_mux_hw_data->hw_data.hw;
|
||||||
clk_hw->init = &init;
|
clk_hw->init = &init;
|
||||||
|
|
||||||
ret = devm_clk_hw_register(priv->dev, clk_hw);
|
ret = devm_clk_hw_register(priv->dev, clk_hw);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ERR_PTR(ret);
|
return ERR_PTR(ret);
|
||||||
|
|
||||||
|
ret = rzg2l_register_notifier(clk_hw, core, priv);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(priv->dev, "Failed to register notifier for %s\n",
|
||||||
|
core->name);
|
||||||
|
return ERR_PTR(ret);
|
||||||
|
}
|
||||||
|
|
||||||
return clk_hw->clk;
|
return clk_hw->clk;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,8 @@
|
|||||||
#ifndef __RENESAS_RZG2L_CPG_H__
|
#ifndef __RENESAS_RZG2L_CPG_H__
|
||||||
#define __RENESAS_RZG2L_CPG_H__
|
#define __RENESAS_RZG2L_CPG_H__
|
||||||
|
|
||||||
|
#include <linux/notifier.h>
|
||||||
|
|
||||||
#define CPG_SIPLL5_STBY (0x140)
|
#define CPG_SIPLL5_STBY (0x140)
|
||||||
#define CPG_SIPLL5_CLK1 (0x144)
|
#define CPG_SIPLL5_CLK1 (0x144)
|
||||||
#define CPG_SIPLL5_CLK3 (0x14C)
|
#define CPG_SIPLL5_CLK3 (0x14C)
|
||||||
@@ -19,7 +21,6 @@
|
|||||||
#define CPG_PL2_DDIV (0x204)
|
#define CPG_PL2_DDIV (0x204)
|
||||||
#define CPG_PL3A_DDIV (0x208)
|
#define CPG_PL3A_DDIV (0x208)
|
||||||
#define CPG_PL6_DDIV (0x210)
|
#define CPG_PL6_DDIV (0x210)
|
||||||
#define CPG_PL2SDHI_DSEL (0x218)
|
|
||||||
#define CPG_CLKSTATUS (0x280)
|
#define CPG_CLKSTATUS (0x280)
|
||||||
#define CPG_PL3_SSEL (0x408)
|
#define CPG_PL3_SSEL (0x408)
|
||||||
#define CPG_PL6_SSEL (0x414)
|
#define CPG_PL6_SSEL (0x414)
|
||||||
@@ -43,8 +44,6 @@
|
|||||||
#define CPG_CLKSTATUS_SELSDHI0_STS BIT(28)
|
#define CPG_CLKSTATUS_SELSDHI0_STS BIT(28)
|
||||||
#define CPG_CLKSTATUS_SELSDHI1_STS BIT(29)
|
#define CPG_CLKSTATUS_SELSDHI1_STS BIT(29)
|
||||||
|
|
||||||
#define CPG_SDHI_CLK_SWITCH_STATUS_TIMEOUT_US 200
|
|
||||||
|
|
||||||
/* n = 0/1/2 for PLL1/4/6 */
|
/* n = 0/1/2 for PLL1/4/6 */
|
||||||
#define CPG_SAMPLL_CLK1(n) (0x04 + (16 * n))
|
#define CPG_SAMPLL_CLK1(n) (0x04 + (16 * n))
|
||||||
#define CPG_SAMPLL_CLK2(n) (0x08 + (16 * n))
|
#define CPG_SAMPLL_CLK2(n) (0x08 + (16 * n))
|
||||||
@@ -69,9 +68,6 @@
|
|||||||
#define SEL_PLL6_2 SEL_PLL_PACK(CPG_PL6_ETH_SSEL, 0, 1)
|
#define SEL_PLL6_2 SEL_PLL_PACK(CPG_PL6_ETH_SSEL, 0, 1)
|
||||||
#define SEL_GPU2 SEL_PLL_PACK(CPG_PL6_SSEL, 12, 1)
|
#define SEL_GPU2 SEL_PLL_PACK(CPG_PL6_SSEL, 12, 1)
|
||||||
|
|
||||||
#define SEL_SDHI0 DDIV_PACK(CPG_PL2SDHI_DSEL, 0, 2)
|
|
||||||
#define SEL_SDHI1 DDIV_PACK(CPG_PL2SDHI_DSEL, 4, 2)
|
|
||||||
|
|
||||||
#define EXTAL_FREQ_IN_MEGA_HZ (24)
|
#define EXTAL_FREQ_IN_MEGA_HZ (24)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -90,10 +86,13 @@ struct cpg_core_clk {
|
|||||||
unsigned int mult;
|
unsigned int mult;
|
||||||
unsigned int type;
|
unsigned int type;
|
||||||
unsigned int conf;
|
unsigned int conf;
|
||||||
|
unsigned int sconf;
|
||||||
const struct clk_div_table *dtable;
|
const struct clk_div_table *dtable;
|
||||||
|
const u32 *mtable;
|
||||||
const char * const *parent_names;
|
const char * const *parent_names;
|
||||||
int flag;
|
notifier_fn_t notifier;
|
||||||
int mux_flags;
|
u32 flag;
|
||||||
|
u32 mux_flags;
|
||||||
int num_parents;
|
int num_parents;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -151,10 +150,11 @@ enum clk_types {
|
|||||||
.parent_names = _parent_names, \
|
.parent_names = _parent_names, \
|
||||||
.num_parents = ARRAY_SIZE(_parent_names), \
|
.num_parents = ARRAY_SIZE(_parent_names), \
|
||||||
.mux_flags = CLK_MUX_READ_ONLY)
|
.mux_flags = CLK_MUX_READ_ONLY)
|
||||||
#define DEF_SD_MUX(_name, _id, _conf, _parent_names) \
|
#define DEF_SD_MUX(_name, _id, _conf, _sconf, _parent_names, _mtable, _clk_flags, _notifier) \
|
||||||
DEF_TYPE(_name, _id, CLK_TYPE_SD_MUX, .conf = _conf, \
|
DEF_TYPE(_name, _id, CLK_TYPE_SD_MUX, .conf = _conf, .sconf = _sconf, \
|
||||||
.parent_names = _parent_names, \
|
.parent_names = _parent_names, \
|
||||||
.num_parents = ARRAY_SIZE(_parent_names))
|
.num_parents = ARRAY_SIZE(_parent_names), \
|
||||||
|
.mtable = _mtable, .flag = _clk_flags, .notifier = _notifier)
|
||||||
#define DEF_PLL5_FOUTPOSTDIV(_name, _id, _parent) \
|
#define DEF_PLL5_FOUTPOSTDIV(_name, _id, _parent) \
|
||||||
DEF_TYPE(_name, _id, CLK_TYPE_SIPLL5, .parent = _parent)
|
DEF_TYPE(_name, _id, CLK_TYPE_SIPLL5, .parent = _parent)
|
||||||
#define DEF_PLL5_4_MUX(_name, _id, _conf, _parent_names) \
|
#define DEF_PLL5_4_MUX(_name, _id, _conf, _parent_names) \
|
||||||
@@ -269,4 +269,6 @@ extern const struct rzg2l_cpg_info r9a07g044_cpg_info;
|
|||||||
extern const struct rzg2l_cpg_info r9a07g054_cpg_info;
|
extern const struct rzg2l_cpg_info r9a07g054_cpg_info;
|
||||||
extern const struct rzg2l_cpg_info r9a09g011_cpg_info;
|
extern const struct rzg2l_cpg_info r9a09g011_cpg_info;
|
||||||
|
|
||||||
|
int rzg2l_cpg_sd_clk_mux_notifier(struct notifier_block *nb, unsigned long event, void *data);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -87,6 +87,7 @@ struct jr3_pci_poll_delay {
|
|||||||
struct jr3_pci_dev_private {
|
struct jr3_pci_dev_private {
|
||||||
struct timer_list timer;
|
struct timer_list timer;
|
||||||
struct comedi_device *dev;
|
struct comedi_device *dev;
|
||||||
|
bool timer_enable;
|
||||||
};
|
};
|
||||||
|
|
||||||
union jr3_pci_single_range {
|
union jr3_pci_single_range {
|
||||||
@@ -596,10 +597,11 @@ static void jr3_pci_poll_dev(struct timer_list *t)
|
|||||||
delay = sub_delay.max;
|
delay = sub_delay.max;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (devpriv->timer_enable) {
|
||||||
|
devpriv->timer.expires = jiffies + msecs_to_jiffies(delay);
|
||||||
|
add_timer(&devpriv->timer);
|
||||||
|
}
|
||||||
spin_unlock_irqrestore(&dev->spinlock, flags);
|
spin_unlock_irqrestore(&dev->spinlock, flags);
|
||||||
|
|
||||||
devpriv->timer.expires = jiffies + msecs_to_jiffies(delay);
|
|
||||||
add_timer(&devpriv->timer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct jr3_pci_subdev_private *
|
static struct jr3_pci_subdev_private *
|
||||||
@@ -748,6 +750,7 @@ static int jr3_pci_auto_attach(struct comedi_device *dev,
|
|||||||
devpriv->dev = dev;
|
devpriv->dev = dev;
|
||||||
timer_setup(&devpriv->timer, jr3_pci_poll_dev, 0);
|
timer_setup(&devpriv->timer, jr3_pci_poll_dev, 0);
|
||||||
devpriv->timer.expires = jiffies + msecs_to_jiffies(1000);
|
devpriv->timer.expires = jiffies + msecs_to_jiffies(1000);
|
||||||
|
devpriv->timer_enable = true;
|
||||||
add_timer(&devpriv->timer);
|
add_timer(&devpriv->timer);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -757,8 +760,12 @@ static void jr3_pci_detach(struct comedi_device *dev)
|
|||||||
{
|
{
|
||||||
struct jr3_pci_dev_private *devpriv = dev->private;
|
struct jr3_pci_dev_private *devpriv = dev->private;
|
||||||
|
|
||||||
if (devpriv)
|
if (devpriv) {
|
||||||
|
spin_lock_bh(&dev->spinlock);
|
||||||
|
devpriv->timer_enable = false;
|
||||||
|
spin_unlock_bh(&dev->spinlock);
|
||||||
del_timer_sync(&devpriv->timer);
|
del_timer_sync(&devpriv->timer);
|
||||||
|
}
|
||||||
|
|
||||||
comedi_pci_detach(dev);
|
comedi_pci_detach(dev);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -749,7 +749,7 @@ static unsigned int cppc_cpufreq_get_rate(unsigned int cpu)
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!policy)
|
if (!policy)
|
||||||
return -ENODEV;
|
return 0;
|
||||||
|
|
||||||
cpu_data = policy->driver_data;
|
cpu_data = policy->driver_data;
|
||||||
|
|
||||||
|
|||||||
@@ -33,11 +33,17 @@ static const struct scmi_perf_proto_ops *perf_ops;
|
|||||||
|
|
||||||
static unsigned int scmi_cpufreq_get_rate(unsigned int cpu)
|
static unsigned int scmi_cpufreq_get_rate(unsigned int cpu)
|
||||||
{
|
{
|
||||||
struct cpufreq_policy *policy = cpufreq_cpu_get_raw(cpu);
|
struct cpufreq_policy *policy;
|
||||||
struct scmi_data *priv = policy->driver_data;
|
struct scmi_data *priv;
|
||||||
unsigned long rate;
|
unsigned long rate;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
policy = cpufreq_cpu_get_raw(cpu);
|
||||||
|
if (unlikely(!policy))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
priv = policy->driver_data;
|
||||||
|
|
||||||
ret = perf_ops->freq_get(ph, priv->domain_id, &rate, false);
|
ret = perf_ops->freq_get(ph, priv->domain_id, &rate, false);
|
||||||
if (ret)
|
if (ret)
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -29,9 +29,16 @@ static struct scpi_ops *scpi_ops;
|
|||||||
|
|
||||||
static unsigned int scpi_cpufreq_get_rate(unsigned int cpu)
|
static unsigned int scpi_cpufreq_get_rate(unsigned int cpu)
|
||||||
{
|
{
|
||||||
struct cpufreq_policy *policy = cpufreq_cpu_get_raw(cpu);
|
struct cpufreq_policy *policy;
|
||||||
struct scpi_data *priv = policy->driver_data;
|
struct scpi_data *priv;
|
||||||
unsigned long rate = clk_get_rate(priv->clk);
|
unsigned long rate;
|
||||||
|
|
||||||
|
policy = cpufreq_cpu_get_raw(cpu);
|
||||||
|
if (unlikely(!policy))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
priv = policy->driver_data;
|
||||||
|
rate = clk_get_rate(priv->clk);
|
||||||
|
|
||||||
return rate / 1000;
|
return rate / 1000;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -107,7 +107,12 @@ static int atmel_sha204a_probe(struct i2c_client *client,
|
|||||||
|
|
||||||
i2c_priv->hwrng.name = dev_name(&client->dev);
|
i2c_priv->hwrng.name = dev_name(&client->dev);
|
||||||
i2c_priv->hwrng.read = atmel_sha204a_rng_read;
|
i2c_priv->hwrng.read = atmel_sha204a_rng_read;
|
||||||
i2c_priv->hwrng.quality = 1024;
|
|
||||||
|
/*
|
||||||
|
* According to review by Bill Cox [1], this HWRNG has very low entropy.
|
||||||
|
* [1] https://www.metzdowd.com/pipermail/cryptography/2014-December/023858.html
|
||||||
|
*/
|
||||||
|
i2c_priv->hwrng.quality = 1;
|
||||||
|
|
||||||
ret = devm_hwrng_register(&client->dev, &i2c_priv->hwrng);
|
ret = devm_hwrng_register(&client->dev, &i2c_priv->hwrng);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
|||||||
@@ -186,7 +186,7 @@ static long udmabuf_create(struct miscdevice *device,
|
|||||||
if (!ubuf)
|
if (!ubuf)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
pglimit = (size_limit_mb * 1024 * 1024) >> PAGE_SHIFT;
|
pglimit = ((u64)size_limit_mb * 1024 * 1024) >> PAGE_SHIFT;
|
||||||
for (i = 0; i < head->count; i++) {
|
for (i = 0; i < head->count; i++) {
|
||||||
if (!IS_ALIGNED(list[i].offset, PAGE_SIZE))
|
if (!IS_ALIGNED(list[i].offset, PAGE_SIZE))
|
||||||
goto err;
|
goto err;
|
||||||
|
|||||||
@@ -827,9 +827,9 @@ static int dmatest_func(void *data)
|
|||||||
} else {
|
} else {
|
||||||
dma_async_issue_pending(chan);
|
dma_async_issue_pending(chan);
|
||||||
|
|
||||||
wait_event_freezable_timeout(thread->done_wait,
|
wait_event_timeout(thread->done_wait,
|
||||||
done->done,
|
done->done,
|
||||||
msecs_to_jiffies(params->timeout));
|
msecs_to_jiffies(params->timeout));
|
||||||
|
|
||||||
status = dma_async_is_tx_complete(chan, cookie, NULL,
|
status = dma_async_is_tx_complete(chan, cookie, NULL,
|
||||||
NULL);
|
NULL);
|
||||||
|
|||||||
@@ -2795,16 +2795,16 @@ static void dm_gpureset_commit_state(struct dc_state *dc_state,
|
|||||||
for (k = 0; k < dc_state->stream_count; k++) {
|
for (k = 0; k < dc_state->stream_count; k++) {
|
||||||
bundle->stream_update.stream = dc_state->streams[k];
|
bundle->stream_update.stream = dc_state->streams[k];
|
||||||
|
|
||||||
for (m = 0; m < dc_state->stream_status->plane_count; m++) {
|
for (m = 0; m < dc_state->stream_status[k].plane_count; m++) {
|
||||||
bundle->surface_updates[m].surface =
|
bundle->surface_updates[m].surface =
|
||||||
dc_state->stream_status->plane_states[m];
|
dc_state->stream_status[k].plane_states[m];
|
||||||
bundle->surface_updates[m].surface->force_full_update =
|
bundle->surface_updates[m].surface->force_full_update =
|
||||||
true;
|
true;
|
||||||
}
|
}
|
||||||
|
|
||||||
update_planes_and_stream_adapter(dm->dc,
|
update_planes_and_stream_adapter(dm->dc,
|
||||||
UPDATE_TYPE_FULL,
|
UPDATE_TYPE_FULL,
|
||||||
dc_state->stream_status->plane_count,
|
dc_state->stream_status[k].plane_count,
|
||||||
dc_state->streams[k],
|
dc_state->streams[k],
|
||||||
&bundle->stream_update,
|
&bundle->stream_update,
|
||||||
bundle->surface_updates);
|
bundle->surface_updates);
|
||||||
@@ -9358,6 +9358,9 @@ static bool should_reset_plane(struct drm_atomic_state *state,
|
|||||||
if (adev->ip_versions[DCE_HWIP][0] < IP_VERSION(3, 2, 0) && state->allow_modeset)
|
if (adev->ip_versions[DCE_HWIP][0] < IP_VERSION(3, 2, 0) && state->allow_modeset)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
if (amdgpu_in_reset(adev) && state->allow_modeset)
|
||||||
|
return true;
|
||||||
|
|
||||||
/* Exit early if we know that we're adding or removing the plane. */
|
/* Exit early if we know that we're adding or removing the plane. */
|
||||||
if (old_plane_state->crtc != new_plane_state->crtc)
|
if (old_plane_state->crtc != new_plane_state->crtc)
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ static const struct iio_chan_spec ad7768_channels[] = {
|
|||||||
.channel = 0,
|
.channel = 0,
|
||||||
.scan_index = 0,
|
.scan_index = 0,
|
||||||
.scan_type = {
|
.scan_type = {
|
||||||
.sign = 'u',
|
.sign = 's',
|
||||||
.realbits = 24,
|
.realbits = 24,
|
||||||
.storagebits = 32,
|
.storagebits = 32,
|
||||||
.shift = 8,
|
.shift = 8,
|
||||||
@@ -370,12 +370,11 @@ static int ad7768_read_raw(struct iio_dev *indio_dev,
|
|||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
ret = ad7768_scan_direct(indio_dev);
|
ret = ad7768_scan_direct(indio_dev);
|
||||||
if (ret >= 0)
|
|
||||||
*val = ret;
|
|
||||||
|
|
||||||
iio_device_release_direct_mode(indio_dev);
|
iio_device_release_direct_mode(indio_dev);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
*val = sign_extend32(ret, chan->scan_type.realbits - 1);
|
||||||
|
|
||||||
return IIO_VAL_INT;
|
return IIO_VAL_INT;
|
||||||
|
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ static int qibfs_mknod(struct inode *dir, struct dentry *dentry,
|
|||||||
struct inode *inode = new_inode(dir->i_sb);
|
struct inode *inode = new_inode(dir->i_sb);
|
||||||
|
|
||||||
if (!inode) {
|
if (!inode) {
|
||||||
|
dput(dentry);
|
||||||
error = -EPERM;
|
error = -EPERM;
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3593,7 +3593,7 @@ static int amd_ir_set_vcpu_affinity(struct irq_data *data, void *vcpu_info)
|
|||||||
* we should not modify the IRTE
|
* we should not modify the IRTE
|
||||||
*/
|
*/
|
||||||
if (!dev_data || !dev_data->use_vapic)
|
if (!dev_data || !dev_data->use_vapic)
|
||||||
return 0;
|
return -EINVAL;
|
||||||
|
|
||||||
ir_data->cfg = irqd_cfg(data);
|
ir_data->cfg = irqd_cfg(data);
|
||||||
pi_data->ir_data = ir_data;
|
pi_data->ir_data = ir_data;
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ static int chameleon_parse_gdd(struct mcb_bus *bus,
|
|||||||
|
|
||||||
ret = mcb_device_register(bus, mdev);
|
ret = mcb_device_register(bus, mdev);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto err;
|
return ret;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|||||||
@@ -2068,14 +2068,9 @@ static int fix_sync_read_error(struct r1bio *r1_bio)
|
|||||||
if (!rdev_set_badblocks(rdev, sect, s, 0))
|
if (!rdev_set_badblocks(rdev, sect, s, 0))
|
||||||
abort = 1;
|
abort = 1;
|
||||||
}
|
}
|
||||||
if (abort) {
|
if (abort)
|
||||||
conf->recovery_disabled =
|
|
||||||
mddev->recovery_disabled;
|
|
||||||
set_bit(MD_RECOVERY_INTR, &mddev->recovery);
|
|
||||||
md_done_sync(mddev, r1_bio->sectors, 0);
|
|
||||||
put_buf(r1_bio);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
/* Try next page */
|
/* Try next page */
|
||||||
sectors -= s;
|
sectors -= s;
|
||||||
sect += s;
|
sect += s;
|
||||||
@@ -2214,10 +2209,21 @@ static void sync_request_write(struct mddev *mddev, struct r1bio *r1_bio)
|
|||||||
int disks = conf->raid_disks * 2;
|
int disks = conf->raid_disks * 2;
|
||||||
struct bio *wbio;
|
struct bio *wbio;
|
||||||
|
|
||||||
if (!test_bit(R1BIO_Uptodate, &r1_bio->state))
|
if (!test_bit(R1BIO_Uptodate, &r1_bio->state)) {
|
||||||
/* ouch - failed to read all of that. */
|
/*
|
||||||
if (!fix_sync_read_error(r1_bio))
|
* ouch - failed to read all of that.
|
||||||
|
* No need to fix read error for check/repair
|
||||||
|
* because all member disks are read.
|
||||||
|
*/
|
||||||
|
if (test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery) ||
|
||||||
|
!fix_sync_read_error(r1_bio)) {
|
||||||
|
conf->recovery_disabled = mddev->recovery_disabled;
|
||||||
|
set_bit(MD_RECOVERY_INTR, &mddev->recovery);
|
||||||
|
md_done_sync(mddev, r1_bio->sectors, 0);
|
||||||
|
put_buf(r1_bio);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery))
|
if (test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery))
|
||||||
process_checks(r1_bio);
|
process_checks(r1_bio);
|
||||||
|
|||||||
@@ -28,6 +28,13 @@ static const unsigned long rodata = 0xAA55AA55;
|
|||||||
/* This is marked __ro_after_init, so it should ultimately be .rodata. */
|
/* This is marked __ro_after_init, so it should ultimately be .rodata. */
|
||||||
static unsigned long ro_after_init __ro_after_init = 0x55AA5500;
|
static unsigned long ro_after_init __ro_after_init = 0x55AA5500;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is a pointer to do_nothing() which is initialized at runtime rather
|
||||||
|
* than build time to avoid objtool IBT validation warnings caused by an
|
||||||
|
* inlined unrolled memcpy() in execute_location().
|
||||||
|
*/
|
||||||
|
static void __ro_after_init *do_nothing_ptr;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This just returns to the caller. It is designed to be copied into
|
* This just returns to the caller. It is designed to be copied into
|
||||||
* non-executable memory regions.
|
* non-executable memory regions.
|
||||||
@@ -65,13 +72,12 @@ static noinline void execute_location(void *dst, bool write)
|
|||||||
{
|
{
|
||||||
void (*func)(void);
|
void (*func)(void);
|
||||||
func_desc_t fdesc;
|
func_desc_t fdesc;
|
||||||
void *do_nothing_text = dereference_function_descriptor(do_nothing);
|
|
||||||
|
|
||||||
pr_info("attempting ok execution at %px\n", do_nothing_text);
|
pr_info("attempting ok execution at %px\n", do_nothing_ptr);
|
||||||
do_nothing();
|
do_nothing();
|
||||||
|
|
||||||
if (write == CODE_WRITE) {
|
if (write == CODE_WRITE) {
|
||||||
memcpy(dst, do_nothing_text, EXEC_SIZE);
|
memcpy(dst, do_nothing_ptr, EXEC_SIZE);
|
||||||
flush_icache_range((unsigned long)dst,
|
flush_icache_range((unsigned long)dst,
|
||||||
(unsigned long)dst + EXEC_SIZE);
|
(unsigned long)dst + EXEC_SIZE);
|
||||||
}
|
}
|
||||||
@@ -267,6 +273,8 @@ static void lkdtm_ACCESS_NULL(void)
|
|||||||
|
|
||||||
void __init lkdtm_perms_init(void)
|
void __init lkdtm_perms_init(void)
|
||||||
{
|
{
|
||||||
|
do_nothing_ptr = dereference_function_descriptor(do_nothing);
|
||||||
|
|
||||||
/* Make sure we can write to __ro_after_init values during __init */
|
/* Make sure we can write to __ro_after_init values during __init */
|
||||||
ro_after_init |= 0xAA;
|
ro_after_init |= 0xAA;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,6 +37,7 @@
|
|||||||
struct pci1xxxx_gpio {
|
struct pci1xxxx_gpio {
|
||||||
struct auxiliary_device *aux_dev;
|
struct auxiliary_device *aux_dev;
|
||||||
void __iomem *reg_base;
|
void __iomem *reg_base;
|
||||||
|
raw_spinlock_t wa_lock;
|
||||||
struct gpio_chip gpio;
|
struct gpio_chip gpio;
|
||||||
spinlock_t lock;
|
spinlock_t lock;
|
||||||
int irq_base;
|
int irq_base;
|
||||||
@@ -164,7 +165,7 @@ static void pci1xxxx_gpio_irq_ack(struct irq_data *data)
|
|||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
spin_lock_irqsave(&priv->lock, flags);
|
spin_lock_irqsave(&priv->lock, flags);
|
||||||
pci1xxx_assign_bit(priv->reg_base, INTR_STAT_OFFSET(gpio), (gpio % 32), true);
|
writel(BIT(gpio % 32), priv->reg_base + INTR_STAT_OFFSET(gpio));
|
||||||
spin_unlock_irqrestore(&priv->lock, flags);
|
spin_unlock_irqrestore(&priv->lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -250,6 +251,7 @@ static irqreturn_t pci1xxxx_gpio_irq_handler(int irq, void *dev_id)
|
|||||||
struct pci1xxxx_gpio *priv = dev_id;
|
struct pci1xxxx_gpio *priv = dev_id;
|
||||||
struct gpio_chip *gc = &priv->gpio;
|
struct gpio_chip *gc = &priv->gpio;
|
||||||
unsigned long int_status = 0;
|
unsigned long int_status = 0;
|
||||||
|
unsigned long wa_flags;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
u8 pincount;
|
u8 pincount;
|
||||||
int bit;
|
int bit;
|
||||||
@@ -273,7 +275,9 @@ static irqreturn_t pci1xxxx_gpio_irq_handler(int irq, void *dev_id)
|
|||||||
writel(BIT(bit), priv->reg_base + INTR_STATUS_OFFSET(gpiobank));
|
writel(BIT(bit), priv->reg_base + INTR_STATUS_OFFSET(gpiobank));
|
||||||
spin_unlock_irqrestore(&priv->lock, flags);
|
spin_unlock_irqrestore(&priv->lock, flags);
|
||||||
irq = irq_find_mapping(gc->irq.domain, (bit + (gpiobank * 32)));
|
irq = irq_find_mapping(gc->irq.domain, (bit + (gpiobank * 32)));
|
||||||
handle_nested_irq(irq);
|
raw_spin_lock_irqsave(&priv->wa_lock, wa_flags);
|
||||||
|
generic_handle_irq(irq);
|
||||||
|
raw_spin_unlock_irqrestore(&priv->wa_lock, wa_flags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
spin_lock_irqsave(&priv->lock, flags);
|
spin_lock_irqsave(&priv->lock, flags);
|
||||||
|
|||||||
@@ -117,6 +117,7 @@
|
|||||||
|
|
||||||
#define MEI_DEV_ID_LNL_M 0xA870 /* Lunar Lake Point M */
|
#define MEI_DEV_ID_LNL_M 0xA870 /* Lunar Lake Point M */
|
||||||
|
|
||||||
|
#define MEI_DEV_ID_PTL_H 0xE370 /* Panther Lake H */
|
||||||
#define MEI_DEV_ID_PTL_P 0xE470 /* Panther Lake P */
|
#define MEI_DEV_ID_PTL_P 0xE470 /* Panther Lake P */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -124,6 +124,7 @@ static const struct pci_device_id mei_me_pci_tbl[] = {
|
|||||||
|
|
||||||
{MEI_PCI_DEVICE(MEI_DEV_ID_LNL_M, MEI_ME_PCH15_CFG)},
|
{MEI_PCI_DEVICE(MEI_DEV_ID_LNL_M, MEI_ME_PCH15_CFG)},
|
||||||
|
|
||||||
|
{MEI_PCI_DEVICE(MEI_DEV_ID_PTL_H, MEI_ME_PCH15_CFG)},
|
||||||
{MEI_PCI_DEVICE(MEI_DEV_ID_PTL_P, MEI_ME_PCH15_CFG)},
|
{MEI_PCI_DEVICE(MEI_DEV_ID_PTL_P, MEI_ME_PCH15_CFG)},
|
||||||
|
|
||||||
/* required last entry */
|
/* required last entry */
|
||||||
|
|||||||
@@ -470,11 +470,11 @@ restore_link:
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mv88e6xxx_phy_is_internal(struct dsa_switch *ds, int port)
|
static int mv88e6xxx_phy_is_internal(struct mv88e6xxx_chip *chip, int port)
|
||||||
{
|
{
|
||||||
struct mv88e6xxx_chip *chip = ds->priv;
|
return port >= chip->info->internal_phys_offset &&
|
||||||
|
port < chip->info->num_internal_phys +
|
||||||
return port < chip->info->num_internal_phys;
|
chip->info->internal_phys_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mv88e6xxx_port_ppu_updates(struct mv88e6xxx_chip *chip, int port)
|
static int mv88e6xxx_port_ppu_updates(struct mv88e6xxx_chip *chip, int port)
|
||||||
@@ -591,7 +591,7 @@ static void mv88e6095_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
|
|||||||
|
|
||||||
config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100;
|
config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100;
|
||||||
|
|
||||||
if (mv88e6xxx_phy_is_internal(chip->ds, port)) {
|
if (mv88e6xxx_phy_is_internal(chip, port)) {
|
||||||
__set_bit(PHY_INTERFACE_MODE_MII, config->supported_interfaces);
|
__set_bit(PHY_INTERFACE_MODE_MII, config->supported_interfaces);
|
||||||
} else {
|
} else {
|
||||||
if (cmode < ARRAY_SIZE(mv88e6185_phy_interface_modes) &&
|
if (cmode < ARRAY_SIZE(mv88e6185_phy_interface_modes) &&
|
||||||
@@ -839,7 +839,7 @@ static void mv88e6xxx_get_caps(struct dsa_switch *ds, int port,
|
|||||||
chip->info->ops->phylink_get_caps(chip, port, config);
|
chip->info->ops->phylink_get_caps(chip, port, config);
|
||||||
mv88e6xxx_reg_unlock(chip);
|
mv88e6xxx_reg_unlock(chip);
|
||||||
|
|
||||||
if (mv88e6xxx_phy_is_internal(ds, port)) {
|
if (mv88e6xxx_phy_is_internal(chip, port)) {
|
||||||
__set_bit(PHY_INTERFACE_MODE_INTERNAL,
|
__set_bit(PHY_INTERFACE_MODE_INTERNAL,
|
||||||
config->supported_interfaces);
|
config->supported_interfaces);
|
||||||
/* Internal ports with no phy-mode need GMII for PHYLIB */
|
/* Internal ports with no phy-mode need GMII for PHYLIB */
|
||||||
@@ -848,29 +848,38 @@ static void mv88e6xxx_get_caps(struct dsa_switch *ds, int port,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int mv88e6xxx_mac_prepare(struct dsa_switch *ds, int port,
|
||||||
|
unsigned int mode, phy_interface_t interface)
|
||||||
|
{
|
||||||
|
struct mv88e6xxx_chip *chip = ds->priv;
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
/* 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 &&
|
||||||
|
chip->ports[port].interface != interface &&
|
||||||
|
chip->info->ops->port_set_link) {
|
||||||
|
mv88e6xxx_reg_lock(chip);
|
||||||
|
err = chip->info->ops->port_set_link(chip, port,
|
||||||
|
LINK_FORCED_DOWN);
|
||||||
|
mv88e6xxx_reg_unlock(chip);
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
static void mv88e6xxx_mac_config(struct dsa_switch *ds, int port,
|
static void mv88e6xxx_mac_config(struct dsa_switch *ds, int port,
|
||||||
unsigned int mode,
|
unsigned int mode,
|
||||||
const struct phylink_link_state *state)
|
const struct phylink_link_state *state)
|
||||||
{
|
{
|
||||||
struct mv88e6xxx_chip *chip = ds->priv;
|
struct mv88e6xxx_chip *chip = ds->priv;
|
||||||
struct mv88e6xxx_port *p;
|
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
p = &chip->ports[port];
|
|
||||||
|
|
||||||
mv88e6xxx_reg_lock(chip);
|
mv88e6xxx_reg_lock(chip);
|
||||||
|
|
||||||
if (mode != MLO_AN_PHY || !mv88e6xxx_phy_is_internal(ds, port)) {
|
if (mode != MLO_AN_PHY || !mv88e6xxx_phy_is_internal(chip, 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_port_config_interface(chip, port,
|
err = mv88e6xxx_port_config_interface(chip, port,
|
||||||
state->interface);
|
state->interface);
|
||||||
if (err && err != -EOPNOTSUPP)
|
if (err && err != -EOPNOTSUPP)
|
||||||
@@ -887,24 +896,38 @@ static void mv88e6xxx_mac_config(struct dsa_switch *ds, int port,
|
|||||||
err = 0;
|
err = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err_unlock:
|
||||||
|
mv88e6xxx_reg_unlock(chip);
|
||||||
|
|
||||||
|
if (err && err != -EOPNOTSUPP)
|
||||||
|
dev_err(ds->dev, "p%d: failed to configure MAC/PCS\n", port);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mv88e6xxx_mac_finish(struct dsa_switch *ds, int port,
|
||||||
|
unsigned int mode, phy_interface_t interface)
|
||||||
|
{
|
||||||
|
struct mv88e6xxx_chip *chip = ds->priv;
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
/* Undo the forced down state above after completing configuration
|
/* Undo the forced down state above after completing configuration
|
||||||
* irrespective of its state on entry, which allows the link to come
|
* 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
|
* 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
|
* 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.)
|
* in PHY mode (we treat the PPU as an effective in-band mechanism.)
|
||||||
*/
|
*/
|
||||||
|
mv88e6xxx_reg_lock(chip);
|
||||||
|
|
||||||
if (chip->info->ops->port_set_link &&
|
if (chip->info->ops->port_set_link &&
|
||||||
((mode == MLO_AN_INBAND && p->interface != state->interface) ||
|
((mode == MLO_AN_INBAND &&
|
||||||
|
chip->ports[port].interface != interface) ||
|
||||||
(mode == MLO_AN_PHY && mv88e6xxx_port_ppu_updates(chip, port))))
|
(mode == MLO_AN_PHY && mv88e6xxx_port_ppu_updates(chip, port))))
|
||||||
chip->info->ops->port_set_link(chip, port, LINK_UNFORCED);
|
err = chip->info->ops->port_set_link(chip, port, LINK_UNFORCED);
|
||||||
|
|
||||||
p->interface = state->interface;
|
|
||||||
|
|
||||||
err_unlock:
|
|
||||||
mv88e6xxx_reg_unlock(chip);
|
mv88e6xxx_reg_unlock(chip);
|
||||||
|
|
||||||
if (err && err != -EOPNOTSUPP)
|
chip->ports[port].interface = interface;
|
||||||
dev_err(ds->dev, "p%d: failed to configure MAC/PCS\n", port);
|
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mv88e6xxx_mac_link_down(struct dsa_switch *ds, int port,
|
static void mv88e6xxx_mac_link_down(struct dsa_switch *ds, int port,
|
||||||
@@ -5150,6 +5173,7 @@ static const struct mv88e6xxx_ops mv88e6320_ops = {
|
|||||||
.port_set_rgmii_delay = mv88e6320_port_set_rgmii_delay,
|
.port_set_rgmii_delay = mv88e6320_port_set_rgmii_delay,
|
||||||
.port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
|
.port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
|
||||||
.port_tag_remap = mv88e6095_port_tag_remap,
|
.port_tag_remap = mv88e6095_port_tag_remap,
|
||||||
|
.port_set_policy = mv88e6352_port_set_policy,
|
||||||
.port_set_frame_mode = mv88e6351_port_set_frame_mode,
|
.port_set_frame_mode = mv88e6351_port_set_frame_mode,
|
||||||
.port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
|
.port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
|
||||||
.port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
|
.port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
|
||||||
@@ -5174,8 +5198,10 @@ static const struct mv88e6xxx_ops mv88e6320_ops = {
|
|||||||
.hardware_reset_pre = mv88e6xxx_g2_eeprom_wait,
|
.hardware_reset_pre = mv88e6xxx_g2_eeprom_wait,
|
||||||
.hardware_reset_post = mv88e6xxx_g2_eeprom_wait,
|
.hardware_reset_post = mv88e6xxx_g2_eeprom_wait,
|
||||||
.reset = mv88e6352_g1_reset,
|
.reset = mv88e6352_g1_reset,
|
||||||
.vtu_getnext = mv88e6185_g1_vtu_getnext,
|
.vtu_getnext = mv88e6352_g1_vtu_getnext,
|
||||||
.vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
|
.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
|
||||||
|
.stu_getnext = mv88e6352_g1_stu_getnext,
|
||||||
|
.stu_loadpurge = mv88e6352_g1_stu_loadpurge,
|
||||||
.gpio_ops = &mv88e6352_gpio_ops,
|
.gpio_ops = &mv88e6352_gpio_ops,
|
||||||
.avb_ops = &mv88e6352_avb_ops,
|
.avb_ops = &mv88e6352_avb_ops,
|
||||||
.ptp_ops = &mv88e6352_ptp_ops,
|
.ptp_ops = &mv88e6352_ptp_ops,
|
||||||
@@ -5198,6 +5224,7 @@ static const struct mv88e6xxx_ops mv88e6321_ops = {
|
|||||||
.port_set_rgmii_delay = mv88e6320_port_set_rgmii_delay,
|
.port_set_rgmii_delay = mv88e6320_port_set_rgmii_delay,
|
||||||
.port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
|
.port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
|
||||||
.port_tag_remap = mv88e6095_port_tag_remap,
|
.port_tag_remap = mv88e6095_port_tag_remap,
|
||||||
|
.port_set_policy = mv88e6352_port_set_policy,
|
||||||
.port_set_frame_mode = mv88e6351_port_set_frame_mode,
|
.port_set_frame_mode = mv88e6351_port_set_frame_mode,
|
||||||
.port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
|
.port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
|
||||||
.port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
|
.port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
|
||||||
@@ -5221,8 +5248,10 @@ static const struct mv88e6xxx_ops mv88e6321_ops = {
|
|||||||
.hardware_reset_pre = mv88e6xxx_g2_eeprom_wait,
|
.hardware_reset_pre = mv88e6xxx_g2_eeprom_wait,
|
||||||
.hardware_reset_post = mv88e6xxx_g2_eeprom_wait,
|
.hardware_reset_post = mv88e6xxx_g2_eeprom_wait,
|
||||||
.reset = mv88e6352_g1_reset,
|
.reset = mv88e6352_g1_reset,
|
||||||
.vtu_getnext = mv88e6185_g1_vtu_getnext,
|
.vtu_getnext = mv88e6352_g1_vtu_getnext,
|
||||||
.vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
|
.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
|
||||||
|
.stu_getnext = mv88e6352_g1_stu_getnext,
|
||||||
|
.stu_loadpurge = mv88e6352_g1_stu_loadpurge,
|
||||||
.gpio_ops = &mv88e6352_gpio_ops,
|
.gpio_ops = &mv88e6352_gpio_ops,
|
||||||
.avb_ops = &mv88e6352_avb_ops,
|
.avb_ops = &mv88e6352_avb_ops,
|
||||||
.ptp_ops = &mv88e6352_ptp_ops,
|
.ptp_ops = &mv88e6352_ptp_ops,
|
||||||
@@ -5790,7 +5819,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
|
|||||||
.global1_addr = 0x1b,
|
.global1_addr = 0x1b,
|
||||||
.global2_addr = 0x1c,
|
.global2_addr = 0x1c,
|
||||||
.age_time_coeff = 3750,
|
.age_time_coeff = 3750,
|
||||||
.atu_move_port_mask = 0x1f,
|
.atu_move_port_mask = 0xf,
|
||||||
.g1_irqs = 9,
|
.g1_irqs = 9,
|
||||||
.g2_irqs = 10,
|
.g2_irqs = 10,
|
||||||
.pvt = true,
|
.pvt = true,
|
||||||
@@ -6189,9 +6218,11 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
|
|||||||
.num_databases = 4096,
|
.num_databases = 4096,
|
||||||
.num_macs = 8192,
|
.num_macs = 8192,
|
||||||
.num_ports = 7,
|
.num_ports = 7,
|
||||||
.num_internal_phys = 5,
|
.num_internal_phys = 2,
|
||||||
|
.internal_phys_offset = 3,
|
||||||
.num_gpio = 15,
|
.num_gpio = 15,
|
||||||
.max_vid = 4095,
|
.max_vid = 4095,
|
||||||
|
.max_sid = 63,
|
||||||
.port_base_addr = 0x10,
|
.port_base_addr = 0x10,
|
||||||
.phy_base_addr = 0x0,
|
.phy_base_addr = 0x0,
|
||||||
.global1_addr = 0x1b,
|
.global1_addr = 0x1b,
|
||||||
@@ -6214,9 +6245,11 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
|
|||||||
.num_databases = 4096,
|
.num_databases = 4096,
|
||||||
.num_macs = 8192,
|
.num_macs = 8192,
|
||||||
.num_ports = 7,
|
.num_ports = 7,
|
||||||
.num_internal_phys = 5,
|
.num_internal_phys = 2,
|
||||||
|
.internal_phys_offset = 3,
|
||||||
.num_gpio = 15,
|
.num_gpio = 15,
|
||||||
.max_vid = 4095,
|
.max_vid = 4095,
|
||||||
|
.max_sid = 63,
|
||||||
.port_base_addr = 0x10,
|
.port_base_addr = 0x10,
|
||||||
.phy_base_addr = 0x0,
|
.phy_base_addr = 0x0,
|
||||||
.global1_addr = 0x1b,
|
.global1_addr = 0x1b,
|
||||||
@@ -6225,6 +6258,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
|
|||||||
.g1_irqs = 8,
|
.g1_irqs = 8,
|
||||||
.g2_irqs = 10,
|
.g2_irqs = 10,
|
||||||
.atu_move_port_mask = 0xf,
|
.atu_move_port_mask = 0xf,
|
||||||
|
.pvt = true,
|
||||||
.multi_chip = true,
|
.multi_chip = true,
|
||||||
.edsa_support = MV88E6XXX_EDSA_SUPPORTED,
|
.edsa_support = MV88E6XXX_EDSA_SUPPORTED,
|
||||||
.ptp_support = true,
|
.ptp_support = true,
|
||||||
@@ -6247,7 +6281,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
|
|||||||
.global1_addr = 0x1b,
|
.global1_addr = 0x1b,
|
||||||
.global2_addr = 0x1c,
|
.global2_addr = 0x1c,
|
||||||
.age_time_coeff = 3750,
|
.age_time_coeff = 3750,
|
||||||
.atu_move_port_mask = 0x1f,
|
.atu_move_port_mask = 0xf,
|
||||||
.g1_irqs = 9,
|
.g1_irqs = 9,
|
||||||
.g2_irqs = 10,
|
.g2_irqs = 10,
|
||||||
.pvt = true,
|
.pvt = true,
|
||||||
@@ -7024,7 +7058,9 @@ static const struct dsa_switch_ops mv88e6xxx_switch_ops = {
|
|||||||
.port_teardown = mv88e6xxx_port_teardown,
|
.port_teardown = mv88e6xxx_port_teardown,
|
||||||
.phylink_get_caps = mv88e6xxx_get_caps,
|
.phylink_get_caps = mv88e6xxx_get_caps,
|
||||||
.phylink_mac_link_state = mv88e6xxx_serdes_pcs_get_state,
|
.phylink_mac_link_state = mv88e6xxx_serdes_pcs_get_state,
|
||||||
|
.phylink_mac_prepare = mv88e6xxx_mac_prepare,
|
||||||
.phylink_mac_config = mv88e6xxx_mac_config,
|
.phylink_mac_config = mv88e6xxx_mac_config,
|
||||||
|
.phylink_mac_finish = mv88e6xxx_mac_finish,
|
||||||
.phylink_mac_an_restart = mv88e6xxx_serdes_pcs_an_restart,
|
.phylink_mac_an_restart = mv88e6xxx_serdes_pcs_an_restart,
|
||||||
.phylink_mac_link_down = mv88e6xxx_mac_link_down,
|
.phylink_mac_link_down = mv88e6xxx_mac_link_down,
|
||||||
.phylink_mac_link_up = mv88e6xxx_mac_link_up,
|
.phylink_mac_link_up = mv88e6xxx_mac_link_up,
|
||||||
|
|||||||
@@ -167,6 +167,11 @@ struct mv88e6xxx_info {
|
|||||||
|
|
||||||
/* Supports PTP */
|
/* Supports PTP */
|
||||||
bool ptp_support;
|
bool ptp_support;
|
||||||
|
|
||||||
|
/* Internal PHY start index. 0 means that internal PHYs range starts at
|
||||||
|
* port 0, 1 means internal PHYs range starts at port 1, etc
|
||||||
|
*/
|
||||||
|
unsigned int internal_phys_offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mv88e6xxx_atu_entry {
|
struct mv88e6xxx_atu_entry {
|
||||||
|
|||||||
@@ -1184,31 +1184,22 @@ out:
|
|||||||
int mv88e6xxx_g2_irq_mdio_setup(struct mv88e6xxx_chip *chip,
|
int mv88e6xxx_g2_irq_mdio_setup(struct mv88e6xxx_chip *chip,
|
||||||
struct mii_bus *bus)
|
struct mii_bus *bus)
|
||||||
{
|
{
|
||||||
int phy, irq, err, err_phy;
|
int phy_start = chip->info->internal_phys_offset;
|
||||||
|
int phy_end = chip->info->internal_phys_offset +
|
||||||
|
chip->info->num_internal_phys;
|
||||||
|
int phy, irq;
|
||||||
|
|
||||||
for (phy = 0; phy < chip->info->num_internal_phys; phy++) {
|
for (phy = phy_start; phy < phy_end; phy++) {
|
||||||
irq = irq_find_mapping(chip->g2_irq.domain, phy);
|
irq = irq_find_mapping(chip->g2_irq.domain, phy);
|
||||||
if (irq < 0) {
|
if (irq < 0)
|
||||||
err = irq;
|
return irq;
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
bus->irq[chip->info->phy_base_addr + phy] = irq;
|
bus->irq[chip->info->phy_base_addr + phy] = irq;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
out:
|
|
||||||
err_phy = phy;
|
|
||||||
|
|
||||||
for (phy = 0; phy < err_phy; phy++)
|
|
||||||
irq_dispose_mapping(bus->irq[phy]);
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void mv88e6xxx_g2_irq_mdio_free(struct mv88e6xxx_chip *chip,
|
void mv88e6xxx_g2_irq_mdio_free(struct mv88e6xxx_chip *chip,
|
||||||
struct mii_bus *bus)
|
struct mii_bus *bus)
|
||||||
{
|
{
|
||||||
int phy;
|
|
||||||
|
|
||||||
for (phy = 0; phy < chip->info->num_internal_phys; phy++)
|
|
||||||
irq_dispose_mapping(bus->irq[phy]);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -91,9 +91,8 @@ int phy_led_triggers_register(struct phy_device *phy)
|
|||||||
if (!phy->phy_num_led_triggers)
|
if (!phy->phy_num_led_triggers)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
phy->led_link_trigger = devm_kzalloc(&phy->mdio.dev,
|
phy->led_link_trigger = kzalloc(sizeof(*phy->led_link_trigger),
|
||||||
sizeof(*phy->led_link_trigger),
|
GFP_KERNEL);
|
||||||
GFP_KERNEL);
|
|
||||||
if (!phy->led_link_trigger) {
|
if (!phy->led_link_trigger) {
|
||||||
err = -ENOMEM;
|
err = -ENOMEM;
|
||||||
goto out_clear;
|
goto out_clear;
|
||||||
@@ -103,10 +102,9 @@ int phy_led_triggers_register(struct phy_device *phy)
|
|||||||
if (err)
|
if (err)
|
||||||
goto out_free_link;
|
goto out_free_link;
|
||||||
|
|
||||||
phy->phy_led_triggers = devm_kcalloc(&phy->mdio.dev,
|
phy->phy_led_triggers = kcalloc(phy->phy_num_led_triggers,
|
||||||
phy->phy_num_led_triggers,
|
sizeof(struct phy_led_trigger),
|
||||||
sizeof(struct phy_led_trigger),
|
GFP_KERNEL);
|
||||||
GFP_KERNEL);
|
|
||||||
if (!phy->phy_led_triggers) {
|
if (!phy->phy_led_triggers) {
|
||||||
err = -ENOMEM;
|
err = -ENOMEM;
|
||||||
goto out_unreg_link;
|
goto out_unreg_link;
|
||||||
@@ -127,11 +125,11 @@ int phy_led_triggers_register(struct phy_device *phy)
|
|||||||
out_unreg:
|
out_unreg:
|
||||||
while (i--)
|
while (i--)
|
||||||
phy_led_trigger_unregister(&phy->phy_led_triggers[i]);
|
phy_led_trigger_unregister(&phy->phy_led_triggers[i]);
|
||||||
devm_kfree(&phy->mdio.dev, phy->phy_led_triggers);
|
kfree(phy->phy_led_triggers);
|
||||||
out_unreg_link:
|
out_unreg_link:
|
||||||
phy_led_trigger_unregister(phy->led_link_trigger);
|
phy_led_trigger_unregister(phy->led_link_trigger);
|
||||||
out_free_link:
|
out_free_link:
|
||||||
devm_kfree(&phy->mdio.dev, phy->led_link_trigger);
|
kfree(phy->led_link_trigger);
|
||||||
phy->led_link_trigger = NULL;
|
phy->led_link_trigger = NULL;
|
||||||
out_clear:
|
out_clear:
|
||||||
phy->phy_num_led_triggers = 0;
|
phy->phy_num_led_triggers = 0;
|
||||||
@@ -145,8 +143,13 @@ void phy_led_triggers_unregister(struct phy_device *phy)
|
|||||||
|
|
||||||
for (i = 0; i < phy->phy_num_led_triggers; i++)
|
for (i = 0; i < phy->phy_num_led_triggers; i++)
|
||||||
phy_led_trigger_unregister(&phy->phy_led_triggers[i]);
|
phy_led_trigger_unregister(&phy->phy_led_triggers[i]);
|
||||||
|
kfree(phy->phy_led_triggers);
|
||||||
|
phy->phy_led_triggers = NULL;
|
||||||
|
|
||||||
if (phy->led_link_trigger)
|
if (phy->led_link_trigger) {
|
||||||
phy_led_trigger_unregister(phy->led_link_trigger);
|
phy_led_trigger_unregister(phy->led_link_trigger);
|
||||||
|
kfree(phy->led_link_trigger);
|
||||||
|
phy->led_link_trigger = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(phy_led_triggers_unregister);
|
EXPORT_SYMBOL_GPL(phy_led_triggers_unregister);
|
||||||
|
|||||||
@@ -2146,7 +2146,7 @@ void rtw_core_deinit(struct rtw_dev *rtwdev)
|
|||||||
|
|
||||||
destroy_workqueue(rtwdev->tx_wq);
|
destroy_workqueue(rtwdev->tx_wq);
|
||||||
spin_lock_irqsave(&rtwdev->tx_report.q_lock, flags);
|
spin_lock_irqsave(&rtwdev->tx_report.q_lock, flags);
|
||||||
skb_queue_purge(&rtwdev->tx_report.queue);
|
ieee80211_purge_tx_queue(rtwdev->hw, &rtwdev->tx_report.queue);
|
||||||
skb_queue_purge(&rtwdev->coex.queue);
|
skb_queue_purge(&rtwdev->coex.queue);
|
||||||
spin_unlock_irqrestore(&rtwdev->tx_report.q_lock, flags);
|
spin_unlock_irqrestore(&rtwdev->tx_report.q_lock, flags);
|
||||||
|
|
||||||
|
|||||||
@@ -169,7 +169,7 @@ void rtw_tx_report_purge_timer(struct timer_list *t)
|
|||||||
rtw_warn(rtwdev, "failed to get tx report from firmware\n");
|
rtw_warn(rtwdev, "failed to get tx report from firmware\n");
|
||||||
|
|
||||||
spin_lock_irqsave(&tx_report->q_lock, flags);
|
spin_lock_irqsave(&tx_report->q_lock, flags);
|
||||||
skb_queue_purge(&tx_report->queue);
|
ieee80211_purge_tx_queue(rtwdev->hw, &tx_report->queue);
|
||||||
spin_unlock_irqrestore(&tx_report->q_lock, flags);
|
spin_unlock_irqrestore(&tx_report->q_lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -985,20 +985,27 @@ static u32 xennet_run_xdp(struct netfront_queue *queue, struct page *pdata,
|
|||||||
act = bpf_prog_run_xdp(prog, xdp);
|
act = bpf_prog_run_xdp(prog, xdp);
|
||||||
switch (act) {
|
switch (act) {
|
||||||
case XDP_TX:
|
case XDP_TX:
|
||||||
get_page(pdata);
|
|
||||||
xdpf = xdp_convert_buff_to_frame(xdp);
|
xdpf = xdp_convert_buff_to_frame(xdp);
|
||||||
err = xennet_xdp_xmit(queue->info->netdev, 1, &xdpf, 0);
|
if (unlikely(!xdpf)) {
|
||||||
if (unlikely(!err))
|
|
||||||
xdp_return_frame_rx_napi(xdpf);
|
|
||||||
else if (unlikely(err < 0))
|
|
||||||
trace_xdp_exception(queue->info->netdev, prog, act);
|
trace_xdp_exception(queue->info->netdev, prog, act);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
get_page(pdata);
|
||||||
|
err = xennet_xdp_xmit(queue->info->netdev, 1, &xdpf, 0);
|
||||||
|
if (unlikely(err <= 0)) {
|
||||||
|
if (err < 0)
|
||||||
|
trace_xdp_exception(queue->info->netdev, prog, act);
|
||||||
|
xdp_return_frame_rx_napi(xdpf);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case XDP_REDIRECT:
|
case XDP_REDIRECT:
|
||||||
get_page(pdata);
|
get_page(pdata);
|
||||||
err = xdp_do_redirect(queue->info->netdev, xdp, prog);
|
err = xdp_do_redirect(queue->info->netdev, xdp, prog);
|
||||||
*need_xdp_flush = true;
|
*need_xdp_flush = true;
|
||||||
if (unlikely(err))
|
if (unlikely(err)) {
|
||||||
trace_xdp_exception(queue->info->netdev, prog, act);
|
trace_xdp_exception(queue->info->netdev, prog, act);
|
||||||
|
xdp_return_buff(xdp);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case XDP_PASS:
|
case XDP_PASS:
|
||||||
case XDP_DROP:
|
case XDP_DROP:
|
||||||
|
|||||||
@@ -1323,6 +1323,7 @@ static const struct pci_device_id amd_ntb_pci_tbl[] = {
|
|||||||
{ PCI_VDEVICE(AMD, 0x148b), (kernel_ulong_t)&dev_data[1] },
|
{ PCI_VDEVICE(AMD, 0x148b), (kernel_ulong_t)&dev_data[1] },
|
||||||
{ PCI_VDEVICE(AMD, 0x14c0), (kernel_ulong_t)&dev_data[1] },
|
{ PCI_VDEVICE(AMD, 0x14c0), (kernel_ulong_t)&dev_data[1] },
|
||||||
{ PCI_VDEVICE(AMD, 0x14c3), (kernel_ulong_t)&dev_data[1] },
|
{ PCI_VDEVICE(AMD, 0x14c3), (kernel_ulong_t)&dev_data[1] },
|
||||||
|
{ PCI_VDEVICE(AMD, 0x155a), (kernel_ulong_t)&dev_data[1] },
|
||||||
{ PCI_VDEVICE(HYGON, 0x145b), (kernel_ulong_t)&dev_data[0] },
|
{ PCI_VDEVICE(HYGON, 0x145b), (kernel_ulong_t)&dev_data[0] },
|
||||||
{ 0, }
|
{ 0, }
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1041,7 +1041,7 @@ static inline char *idt_get_mw_name(enum idt_mw_type mw_type)
|
|||||||
static struct idt_mw_cfg *idt_scan_mws(struct idt_ntb_dev *ndev, int port,
|
static struct idt_mw_cfg *idt_scan_mws(struct idt_ntb_dev *ndev, int port,
|
||||||
unsigned char *mw_cnt)
|
unsigned char *mw_cnt)
|
||||||
{
|
{
|
||||||
struct idt_mw_cfg mws[IDT_MAX_NR_MWS], *ret_mws;
|
struct idt_mw_cfg *mws;
|
||||||
const struct idt_ntb_bar *bars;
|
const struct idt_ntb_bar *bars;
|
||||||
enum idt_mw_type mw_type;
|
enum idt_mw_type mw_type;
|
||||||
unsigned char widx, bidx, en_cnt;
|
unsigned char widx, bidx, en_cnt;
|
||||||
@@ -1049,6 +1049,11 @@ static struct idt_mw_cfg *idt_scan_mws(struct idt_ntb_dev *ndev, int port,
|
|||||||
int aprt_size;
|
int aprt_size;
|
||||||
u32 data;
|
u32 data;
|
||||||
|
|
||||||
|
mws = devm_kcalloc(&ndev->ntb.pdev->dev, IDT_MAX_NR_MWS,
|
||||||
|
sizeof(*mws), GFP_KERNEL);
|
||||||
|
if (!mws)
|
||||||
|
return ERR_PTR(-ENOMEM);
|
||||||
|
|
||||||
/* Retrieve the array of the BARs registers */
|
/* Retrieve the array of the BARs registers */
|
||||||
bars = portdata_tbl[port].bars;
|
bars = portdata_tbl[port].bars;
|
||||||
|
|
||||||
@@ -1103,16 +1108,7 @@ static struct idt_mw_cfg *idt_scan_mws(struct idt_ntb_dev *ndev, int port,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate memory for memory window descriptors */
|
return mws;
|
||||||
ret_mws = devm_kcalloc(&ndev->ntb.pdev->dev, *mw_cnt, sizeof(*ret_mws),
|
|
||||||
GFP_KERNEL);
|
|
||||||
if (!ret_mws)
|
|
||||||
return ERR_PTR(-ENOMEM);
|
|
||||||
|
|
||||||
/* Copy the info of detected memory windows */
|
|
||||||
memcpy(ret_mws, mws, (*mw_cnt)*sizeof(*ret_mws));
|
|
||||||
|
|
||||||
return ret_mws;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -4704,6 +4704,15 @@ static void nvme_scan_work(struct work_struct *work)
|
|||||||
if (nvme_scan_ns_list(ctrl) != 0)
|
if (nvme_scan_ns_list(ctrl) != 0)
|
||||||
nvme_scan_ns_sequential(ctrl);
|
nvme_scan_ns_sequential(ctrl);
|
||||||
mutex_unlock(&ctrl->scan_lock);
|
mutex_unlock(&ctrl->scan_lock);
|
||||||
|
|
||||||
|
/* Requeue if we have missed AENs */
|
||||||
|
if (test_bit(NVME_AER_NOTICE_NS_CHANGED, &ctrl->events))
|
||||||
|
nvme_queue_scan(ctrl);
|
||||||
|
#ifdef CONFIG_NVME_MULTIPATH
|
||||||
|
else if (ctrl->ana_log_buf)
|
||||||
|
/* Re-read the ANA log page to not miss updates */
|
||||||
|
queue_work(nvme_wq, &ctrl->ana_work);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -1030,33 +1030,24 @@ nvmet_fc_alloc_hostport(struct nvmet_fc_tgtport *tgtport, void *hosthandle)
|
|||||||
struct nvmet_fc_hostport *newhost, *match = NULL;
|
struct nvmet_fc_hostport *newhost, *match = NULL;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Caller holds a reference on tgtport.
|
||||||
|
*/
|
||||||
|
|
||||||
/* if LLDD not implemented, leave as NULL */
|
/* if LLDD not implemented, leave as NULL */
|
||||||
if (!hosthandle)
|
if (!hosthandle)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/*
|
|
||||||
* take reference for what will be the newly allocated hostport if
|
|
||||||
* we end up using a new allocation
|
|
||||||
*/
|
|
||||||
if (!nvmet_fc_tgtport_get(tgtport))
|
|
||||||
return ERR_PTR(-EINVAL);
|
|
||||||
|
|
||||||
spin_lock_irqsave(&tgtport->lock, flags);
|
spin_lock_irqsave(&tgtport->lock, flags);
|
||||||
match = nvmet_fc_match_hostport(tgtport, hosthandle);
|
match = nvmet_fc_match_hostport(tgtport, hosthandle);
|
||||||
spin_unlock_irqrestore(&tgtport->lock, flags);
|
spin_unlock_irqrestore(&tgtport->lock, flags);
|
||||||
|
|
||||||
if (match) {
|
if (match)
|
||||||
/* no new allocation - release reference */
|
|
||||||
nvmet_fc_tgtport_put(tgtport);
|
|
||||||
return match;
|
return match;
|
||||||
}
|
|
||||||
|
|
||||||
newhost = kzalloc(sizeof(*newhost), GFP_KERNEL);
|
newhost = kzalloc(sizeof(*newhost), GFP_KERNEL);
|
||||||
if (!newhost) {
|
if (!newhost)
|
||||||
/* no new allocation - release reference */
|
|
||||||
nvmet_fc_tgtport_put(tgtport);
|
|
||||||
return ERR_PTR(-ENOMEM);
|
return ERR_PTR(-ENOMEM);
|
||||||
}
|
|
||||||
|
|
||||||
spin_lock_irqsave(&tgtport->lock, flags);
|
spin_lock_irqsave(&tgtport->lock, flags);
|
||||||
match = nvmet_fc_match_hostport(tgtport, hosthandle);
|
match = nvmet_fc_match_hostport(tgtport, hosthandle);
|
||||||
@@ -1065,6 +1056,7 @@ nvmet_fc_alloc_hostport(struct nvmet_fc_tgtport *tgtport, void *hosthandle)
|
|||||||
kfree(newhost);
|
kfree(newhost);
|
||||||
newhost = match;
|
newhost = match;
|
||||||
} else {
|
} else {
|
||||||
|
nvmet_fc_tgtport_get(tgtport);
|
||||||
newhost->tgtport = tgtport;
|
newhost->tgtport = tgtport;
|
||||||
newhost->hosthandle = hosthandle;
|
newhost->hosthandle = hosthandle;
|
||||||
INIT_LIST_HEAD(&newhost->host_list);
|
INIT_LIST_HEAD(&newhost->host_list);
|
||||||
@@ -1099,7 +1091,8 @@ static void
|
|||||||
nvmet_fc_schedule_delete_assoc(struct nvmet_fc_tgt_assoc *assoc)
|
nvmet_fc_schedule_delete_assoc(struct nvmet_fc_tgt_assoc *assoc)
|
||||||
{
|
{
|
||||||
nvmet_fc_tgtport_get(assoc->tgtport);
|
nvmet_fc_tgtport_get(assoc->tgtport);
|
||||||
queue_work(nvmet_wq, &assoc->del_work);
|
if (!queue_work(nvmet_wq, &assoc->del_work))
|
||||||
|
nvmet_fc_tgtport_put(assoc->tgtport);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct nvmet_fc_tgt_assoc *
|
static struct nvmet_fc_tgt_assoc *
|
||||||
|
|||||||
@@ -264,14 +264,15 @@ static ssize_t of_device_get_modalias(struct device *dev, char *str, ssize_t len
|
|||||||
csize = snprintf(str, len, "of:N%pOFn%c%s", dev->of_node, 'T',
|
csize = snprintf(str, len, "of:N%pOFn%c%s", dev->of_node, 'T',
|
||||||
of_node_get_device_type(dev->of_node));
|
of_node_get_device_type(dev->of_node));
|
||||||
tsize = csize;
|
tsize = csize;
|
||||||
|
if (csize >= len)
|
||||||
|
csize = len > 0 ? len - 1 : 0;
|
||||||
len -= csize;
|
len -= csize;
|
||||||
if (str)
|
str += csize;
|
||||||
str += csize;
|
|
||||||
|
|
||||||
of_property_for_each_string(dev->of_node, "compatible", p, compat) {
|
of_property_for_each_string(dev->of_node, "compatible", p, compat) {
|
||||||
csize = strlen(compat) + 1;
|
csize = strlen(compat) + 1;
|
||||||
tsize += csize;
|
tsize += csize;
|
||||||
if (csize > len)
|
if (csize >= len)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
csize = snprintf(str, len, "C%s", compat);
|
csize = snprintf(str, len, "C%s", compat);
|
||||||
|
|||||||
@@ -262,25 +262,22 @@ static int adjust_local_phandle_references(struct device_node *local_fixups,
|
|||||||
*/
|
*/
|
||||||
int of_resolve_phandles(struct device_node *overlay)
|
int of_resolve_phandles(struct device_node *overlay)
|
||||||
{
|
{
|
||||||
struct device_node *child, *local_fixups, *refnode;
|
struct device_node *child, *refnode;
|
||||||
struct device_node *tree_symbols, *overlay_fixups;
|
struct device_node *overlay_fixups;
|
||||||
|
struct device_node __free(device_node) *local_fixups = NULL;
|
||||||
struct property *prop;
|
struct property *prop;
|
||||||
const char *refpath;
|
const char *refpath;
|
||||||
phandle phandle, phandle_delta;
|
phandle phandle, phandle_delta;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
tree_symbols = NULL;
|
|
||||||
|
|
||||||
if (!overlay) {
|
if (!overlay) {
|
||||||
pr_err("null overlay\n");
|
pr_err("null overlay\n");
|
||||||
err = -EINVAL;
|
return -EINVAL;
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!of_node_check_flag(overlay, OF_DETACHED)) {
|
if (!of_node_check_flag(overlay, OF_DETACHED)) {
|
||||||
pr_err("overlay not detached\n");
|
pr_err("overlay not detached\n");
|
||||||
err = -EINVAL;
|
return -EINVAL;
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
phandle_delta = live_tree_max_phandle() + 1;
|
phandle_delta = live_tree_max_phandle() + 1;
|
||||||
@@ -292,7 +289,7 @@ int of_resolve_phandles(struct device_node *overlay)
|
|||||||
|
|
||||||
err = adjust_local_phandle_references(local_fixups, overlay, phandle_delta);
|
err = adjust_local_phandle_references(local_fixups, overlay, phandle_delta);
|
||||||
if (err)
|
if (err)
|
||||||
goto out;
|
return err;
|
||||||
|
|
||||||
overlay_fixups = NULL;
|
overlay_fixups = NULL;
|
||||||
|
|
||||||
@@ -301,16 +298,13 @@ int of_resolve_phandles(struct device_node *overlay)
|
|||||||
overlay_fixups = child;
|
overlay_fixups = child;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!overlay_fixups) {
|
if (!overlay_fixups)
|
||||||
err = 0;
|
return 0;
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
tree_symbols = of_find_node_by_path("/__symbols__");
|
struct device_node __free(device_node) *tree_symbols = of_find_node_by_path("/__symbols__");
|
||||||
if (!tree_symbols) {
|
if (!tree_symbols) {
|
||||||
pr_err("no symbols in root of device tree.\n");
|
pr_err("no symbols in root of device tree.\n");
|
||||||
err = -EINVAL;
|
return -EINVAL;
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for_each_property_of_node(overlay_fixups, prop) {
|
for_each_property_of_node(overlay_fixups, prop) {
|
||||||
@@ -324,14 +318,12 @@ int of_resolve_phandles(struct device_node *overlay)
|
|||||||
if (err) {
|
if (err) {
|
||||||
pr_err("node label '%s' not found in live devicetree symbols table\n",
|
pr_err("node label '%s' not found in live devicetree symbols table\n",
|
||||||
prop->name);
|
prop->name);
|
||||||
goto out;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
refnode = of_find_node_by_path(refpath);
|
refnode = of_find_node_by_path(refpath);
|
||||||
if (!refnode) {
|
if (!refnode)
|
||||||
err = -ENOENT;
|
return -ENOENT;
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
phandle = refnode->phandle;
|
phandle = refnode->phandle;
|
||||||
of_node_put(refnode);
|
of_node_put(refnode);
|
||||||
@@ -341,11 +333,8 @@ int of_resolve_phandles(struct device_node *overlay)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
|
||||||
if (err)
|
if (err)
|
||||||
pr_err("overlay phandle fixup failed: %d\n", err);
|
pr_err("overlay phandle fixup failed: %d\n", err);
|
||||||
of_node_put(tree_symbols);
|
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(of_resolve_phandles);
|
EXPORT_SYMBOL_GPL(of_resolve_phandles);
|
||||||
|
|||||||
@@ -6808,60 +6808,70 @@ static void pci_no_domains(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_PCI_DOMAINS_GENERIC
|
#ifdef CONFIG_PCI_DOMAINS_GENERIC
|
||||||
static atomic_t __domain_nr = ATOMIC_INIT(-1);
|
static DEFINE_IDA(pci_domain_nr_static_ida);
|
||||||
|
static DEFINE_IDA(pci_domain_nr_dynamic_ida);
|
||||||
|
|
||||||
static int pci_get_new_domain_nr(void)
|
static void of_pci_reserve_static_domain_nr(void)
|
||||||
{
|
{
|
||||||
return atomic_inc_return(&__domain_nr);
|
struct device_node *np;
|
||||||
|
int domain_nr;
|
||||||
|
|
||||||
|
for_each_node_by_type(np, "pci") {
|
||||||
|
domain_nr = of_get_pci_domain_nr(np);
|
||||||
|
if (domain_nr < 0)
|
||||||
|
continue;
|
||||||
|
/*
|
||||||
|
* Permanently allocate domain_nr in dynamic_ida
|
||||||
|
* to prevent it from dynamic allocation.
|
||||||
|
*/
|
||||||
|
ida_alloc_range(&pci_domain_nr_dynamic_ida,
|
||||||
|
domain_nr, domain_nr, GFP_KERNEL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int of_pci_bus_find_domain_nr(struct device *parent)
|
static int of_pci_bus_find_domain_nr(struct device *parent)
|
||||||
{
|
{
|
||||||
static int use_dt_domains = -1;
|
static bool static_domains_reserved = false;
|
||||||
int domain = -1;
|
int domain_nr;
|
||||||
|
|
||||||
if (parent)
|
/* On the first call scan device tree for static allocations. */
|
||||||
domain = of_get_pci_domain_nr(parent->of_node);
|
if (!static_domains_reserved) {
|
||||||
|
of_pci_reserve_static_domain_nr();
|
||||||
/*
|
static_domains_reserved = true;
|
||||||
* Check DT domain and use_dt_domains values.
|
|
||||||
*
|
|
||||||
* If DT domain property is valid (domain >= 0) and
|
|
||||||
* use_dt_domains != 0, the DT assignment is valid since this means
|
|
||||||
* we have not previously allocated a domain number by using
|
|
||||||
* pci_get_new_domain_nr(); we should also update use_dt_domains to
|
|
||||||
* 1, to indicate that we have just assigned a domain number from
|
|
||||||
* DT.
|
|
||||||
*
|
|
||||||
* If DT domain property value is not valid (ie domain < 0), and we
|
|
||||||
* have not previously assigned a domain number from DT
|
|
||||||
* (use_dt_domains != 1) we should assign a domain number by
|
|
||||||
* using the:
|
|
||||||
*
|
|
||||||
* pci_get_new_domain_nr()
|
|
||||||
*
|
|
||||||
* API and update the use_dt_domains value to keep track of method we
|
|
||||||
* are using to assign domain numbers (use_dt_domains = 0).
|
|
||||||
*
|
|
||||||
* All other combinations imply we have a platform that is trying
|
|
||||||
* to mix domain numbers obtained from DT and pci_get_new_domain_nr(),
|
|
||||||
* which is a recipe for domain mishandling and it is prevented by
|
|
||||||
* invalidating the domain value (domain = -1) and printing a
|
|
||||||
* corresponding error.
|
|
||||||
*/
|
|
||||||
if (domain >= 0 && use_dt_domains) {
|
|
||||||
use_dt_domains = 1;
|
|
||||||
} else if (domain < 0 && use_dt_domains != 1) {
|
|
||||||
use_dt_domains = 0;
|
|
||||||
domain = pci_get_new_domain_nr();
|
|
||||||
} else {
|
|
||||||
if (parent)
|
|
||||||
pr_err("Node %pOF has ", parent->of_node);
|
|
||||||
pr_err("Inconsistent \"linux,pci-domain\" property in DT\n");
|
|
||||||
domain = -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return domain;
|
if (parent) {
|
||||||
|
/*
|
||||||
|
* If domain is in DT, allocate it in static IDA. This
|
||||||
|
* prevents duplicate static allocations in case of errors
|
||||||
|
* in DT.
|
||||||
|
*/
|
||||||
|
domain_nr = of_get_pci_domain_nr(parent->of_node);
|
||||||
|
if (domain_nr >= 0)
|
||||||
|
return ida_alloc_range(&pci_domain_nr_static_ida,
|
||||||
|
domain_nr, domain_nr,
|
||||||
|
GFP_KERNEL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If domain was not specified in DT, choose a free ID from dynamic
|
||||||
|
* allocations. All domain numbers from DT are permanently in
|
||||||
|
* dynamic allocations to prevent assigning them to other DT nodes
|
||||||
|
* without static domain.
|
||||||
|
*/
|
||||||
|
return ida_alloc(&pci_domain_nr_dynamic_ida, GFP_KERNEL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void of_pci_bus_release_domain_nr(struct pci_bus *bus, struct device *parent)
|
||||||
|
{
|
||||||
|
if (bus->domain_nr < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Release domain from IDA where it was allocated. */
|
||||||
|
if (of_get_pci_domain_nr(parent->of_node) == bus->domain_nr)
|
||||||
|
ida_free(&pci_domain_nr_static_ida, bus->domain_nr);
|
||||||
|
else
|
||||||
|
ida_free(&pci_domain_nr_dynamic_ida, bus->domain_nr);
|
||||||
}
|
}
|
||||||
|
|
||||||
int pci_bus_find_domain_nr(struct pci_bus *bus, struct device *parent)
|
int pci_bus_find_domain_nr(struct pci_bus *bus, struct device *parent)
|
||||||
@@ -6869,6 +6879,13 @@ int pci_bus_find_domain_nr(struct pci_bus *bus, struct device *parent)
|
|||||||
return acpi_disabled ? of_pci_bus_find_domain_nr(parent) :
|
return acpi_disabled ? of_pci_bus_find_domain_nr(parent) :
|
||||||
acpi_pci_bus_find_domain_nr(bus);
|
acpi_pci_bus_find_domain_nr(bus);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void pci_bus_release_domain_nr(struct pci_bus *bus, struct device *parent)
|
||||||
|
{
|
||||||
|
if (!acpi_disabled)
|
||||||
|
return;
|
||||||
|
of_pci_bus_release_domain_nr(bus, parent);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -888,6 +888,7 @@ static int pci_register_host_bridge(struct pci_host_bridge *bridge)
|
|||||||
resource_size_t offset, next_offset;
|
resource_size_t offset, next_offset;
|
||||||
LIST_HEAD(resources);
|
LIST_HEAD(resources);
|
||||||
struct resource *res, *next_res;
|
struct resource *res, *next_res;
|
||||||
|
bool bus_registered = false;
|
||||||
char addr[64], *fmt;
|
char addr[64], *fmt;
|
||||||
const char *name;
|
const char *name;
|
||||||
int err;
|
int err;
|
||||||
@@ -906,6 +907,10 @@ static int pci_register_host_bridge(struct pci_host_bridge *bridge)
|
|||||||
bus->domain_nr = pci_bus_find_domain_nr(bus, parent);
|
bus->domain_nr = pci_bus_find_domain_nr(bus, parent);
|
||||||
else
|
else
|
||||||
bus->domain_nr = bridge->domain_nr;
|
bus->domain_nr = bridge->domain_nr;
|
||||||
|
if (bus->domain_nr < 0) {
|
||||||
|
err = bus->domain_nr;
|
||||||
|
goto free;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
b = pci_find_bus(pci_domain_nr(bus), bridge->busnr);
|
b = pci_find_bus(pci_domain_nr(bus), bridge->busnr);
|
||||||
@@ -947,6 +952,7 @@ static int pci_register_host_bridge(struct pci_host_bridge *bridge)
|
|||||||
name = dev_name(&bus->dev);
|
name = dev_name(&bus->dev);
|
||||||
|
|
||||||
err = device_register(&bus->dev);
|
err = device_register(&bus->dev);
|
||||||
|
bus_registered = true;
|
||||||
if (err)
|
if (err)
|
||||||
goto unregister;
|
goto unregister;
|
||||||
|
|
||||||
@@ -1030,9 +1036,15 @@ static int pci_register_host_bridge(struct pci_host_bridge *bridge)
|
|||||||
unregister:
|
unregister:
|
||||||
put_device(&bridge->dev);
|
put_device(&bridge->dev);
|
||||||
device_del(&bridge->dev);
|
device_del(&bridge->dev);
|
||||||
|
|
||||||
free:
|
free:
|
||||||
kfree(bus);
|
#ifdef CONFIG_PCI_DOMAINS_GENERIC
|
||||||
|
pci_bus_release_domain_nr(bus, parent);
|
||||||
|
#endif
|
||||||
|
if (bus_registered)
|
||||||
|
put_device(&bus->dev);
|
||||||
|
else
|
||||||
|
kfree(bus);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -157,6 +157,13 @@ void pci_remove_root_bus(struct pci_bus *bus)
|
|||||||
list_for_each_entry_safe(child, tmp,
|
list_for_each_entry_safe(child, tmp,
|
||||||
&bus->devices, bus_list)
|
&bus->devices, bus_list)
|
||||||
pci_remove_bus_device(child);
|
pci_remove_bus_device(child);
|
||||||
|
|
||||||
|
#ifdef CONFIG_PCI_DOMAINS_GENERIC
|
||||||
|
/* Release domain_nr if it was dynamically allocated */
|
||||||
|
if (host_bridge->domain_nr == PCI_DOMAIN_NR_NOT_SET)
|
||||||
|
pci_bus_release_domain_nr(bus, host_bridge->dev.parent);
|
||||||
|
#endif
|
||||||
|
|
||||||
pci_remove_bus(bus);
|
pci_remove_bus(bus);
|
||||||
host_bridge->bus = NULL;
|
host_bridge->bus = NULL;
|
||||||
|
|
||||||
|
|||||||
@@ -50,6 +50,7 @@
|
|||||||
|
|
||||||
enum imx8_pcie_phy_type {
|
enum imx8_pcie_phy_type {
|
||||||
IMX8MM,
|
IMX8MM,
|
||||||
|
IMX8MP,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct imx8_pcie_phy_drvdata {
|
struct imx8_pcie_phy_drvdata {
|
||||||
@@ -62,6 +63,7 @@ struct imx8_pcie_phy {
|
|||||||
struct clk *clk;
|
struct clk *clk;
|
||||||
struct phy *phy;
|
struct phy *phy;
|
||||||
struct regmap *iomuxc_gpr;
|
struct regmap *iomuxc_gpr;
|
||||||
|
struct reset_control *perst;
|
||||||
struct reset_control *reset;
|
struct reset_control *reset;
|
||||||
u32 refclk_pad_mode;
|
u32 refclk_pad_mode;
|
||||||
u32 tx_deemph_gen1;
|
u32 tx_deemph_gen1;
|
||||||
@@ -76,11 +78,11 @@ static int imx8_pcie_phy_power_on(struct phy *phy)
|
|||||||
u32 val, pad_mode;
|
u32 val, pad_mode;
|
||||||
struct imx8_pcie_phy *imx8_phy = phy_get_drvdata(phy);
|
struct imx8_pcie_phy *imx8_phy = phy_get_drvdata(phy);
|
||||||
|
|
||||||
reset_control_assert(imx8_phy->reset);
|
|
||||||
|
|
||||||
pad_mode = imx8_phy->refclk_pad_mode;
|
pad_mode = imx8_phy->refclk_pad_mode;
|
||||||
switch (imx8_phy->drvdata->variant) {
|
switch (imx8_phy->drvdata->variant) {
|
||||||
case IMX8MM:
|
case IMX8MM:
|
||||||
|
reset_control_assert(imx8_phy->reset);
|
||||||
|
|
||||||
/* Tune PHY de-emphasis setting to pass PCIe compliance. */
|
/* Tune PHY de-emphasis setting to pass PCIe compliance. */
|
||||||
if (imx8_phy->tx_deemph_gen1)
|
if (imx8_phy->tx_deemph_gen1)
|
||||||
writel(imx8_phy->tx_deemph_gen1,
|
writel(imx8_phy->tx_deemph_gen1,
|
||||||
@@ -89,6 +91,8 @@ static int imx8_pcie_phy_power_on(struct phy *phy)
|
|||||||
writel(imx8_phy->tx_deemph_gen2,
|
writel(imx8_phy->tx_deemph_gen2,
|
||||||
imx8_phy->base + PCIE_PHY_TRSV_REG6);
|
imx8_phy->base + PCIE_PHY_TRSV_REG6);
|
||||||
break;
|
break;
|
||||||
|
case IMX8MP: /* Do nothing. */
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pad_mode == IMX8_PCIE_REFCLK_PAD_INPUT ||
|
if (pad_mode == IMX8_PCIE_REFCLK_PAD_INPUT ||
|
||||||
@@ -139,18 +143,21 @@ static int imx8_pcie_phy_power_on(struct phy *phy)
|
|||||||
IMX8MM_GPR_PCIE_REF_CLK_PLL);
|
IMX8MM_GPR_PCIE_REF_CLK_PLL);
|
||||||
usleep_range(100, 200);
|
usleep_range(100, 200);
|
||||||
|
|
||||||
/* Do the PHY common block reset */
|
|
||||||
regmap_update_bits(imx8_phy->iomuxc_gpr, IOMUXC_GPR14,
|
|
||||||
IMX8MM_GPR_PCIE_CMN_RST,
|
|
||||||
IMX8MM_GPR_PCIE_CMN_RST);
|
|
||||||
|
|
||||||
switch (imx8_phy->drvdata->variant) {
|
switch (imx8_phy->drvdata->variant) {
|
||||||
|
case IMX8MP:
|
||||||
|
reset_control_deassert(imx8_phy->perst);
|
||||||
|
fallthrough;
|
||||||
case IMX8MM:
|
case IMX8MM:
|
||||||
reset_control_deassert(imx8_phy->reset);
|
reset_control_deassert(imx8_phy->reset);
|
||||||
usleep_range(200, 500);
|
usleep_range(200, 500);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Do the PHY common block reset */
|
||||||
|
regmap_update_bits(imx8_phy->iomuxc_gpr, IOMUXC_GPR14,
|
||||||
|
IMX8MM_GPR_PCIE_CMN_RST,
|
||||||
|
IMX8MM_GPR_PCIE_CMN_RST);
|
||||||
|
|
||||||
/* Polling to check the phy is ready or not. */
|
/* Polling to check the phy is ready or not. */
|
||||||
ret = readl_poll_timeout(imx8_phy->base + IMX8MM_PCIE_PHY_CMN_REG75,
|
ret = readl_poll_timeout(imx8_phy->base + IMX8MM_PCIE_PHY_CMN_REG75,
|
||||||
val, val == PCIE_PHY_CMN_REG75_PLL_DONE,
|
val, val == PCIE_PHY_CMN_REG75_PLL_DONE,
|
||||||
@@ -158,6 +165,16 @@ static int imx8_pcie_phy_power_on(struct phy *phy)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int imx8_pcie_phy_power_off(struct phy *phy)
|
||||||
|
{
|
||||||
|
struct imx8_pcie_phy *imx8_phy = phy_get_drvdata(phy);
|
||||||
|
|
||||||
|
reset_control_assert(imx8_phy->reset);
|
||||||
|
reset_control_assert(imx8_phy->perst);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int imx8_pcie_phy_init(struct phy *phy)
|
static int imx8_pcie_phy_init(struct phy *phy)
|
||||||
{
|
{
|
||||||
struct imx8_pcie_phy *imx8_phy = phy_get_drvdata(phy);
|
struct imx8_pcie_phy *imx8_phy = phy_get_drvdata(phy);
|
||||||
@@ -178,6 +195,7 @@ static const struct phy_ops imx8_pcie_phy_ops = {
|
|||||||
.init = imx8_pcie_phy_init,
|
.init = imx8_pcie_phy_init,
|
||||||
.exit = imx8_pcie_phy_exit,
|
.exit = imx8_pcie_phy_exit,
|
||||||
.power_on = imx8_pcie_phy_power_on,
|
.power_on = imx8_pcie_phy_power_on,
|
||||||
|
.power_off = imx8_pcie_phy_power_off,
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -186,8 +204,14 @@ static const struct imx8_pcie_phy_drvdata imx8mm_drvdata = {
|
|||||||
.variant = IMX8MM,
|
.variant = IMX8MM,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct imx8_pcie_phy_drvdata imx8mp_drvdata = {
|
||||||
|
.gpr = "fsl,imx8mp-iomuxc-gpr",
|
||||||
|
.variant = IMX8MP,
|
||||||
|
};
|
||||||
|
|
||||||
static const struct of_device_id imx8_pcie_phy_of_match[] = {
|
static const struct of_device_id imx8_pcie_phy_of_match[] = {
|
||||||
{.compatible = "fsl,imx8mm-pcie-phy", .data = &imx8mm_drvdata, },
|
{.compatible = "fsl,imx8mm-pcie-phy", .data = &imx8mm_drvdata, },
|
||||||
|
{.compatible = "fsl,imx8mp-pcie-phy", .data = &imx8mp_drvdata, },
|
||||||
{ },
|
{ },
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(of, imx8_pcie_phy_of_match);
|
MODULE_DEVICE_TABLE(of, imx8_pcie_phy_of_match);
|
||||||
@@ -243,6 +267,14 @@ static int imx8_pcie_phy_probe(struct platform_device *pdev)
|
|||||||
return PTR_ERR(imx8_phy->reset);
|
return PTR_ERR(imx8_phy->reset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (imx8_phy->drvdata->variant == IMX8MP) {
|
||||||
|
imx8_phy->perst =
|
||||||
|
devm_reset_control_get_exclusive(dev, "perst");
|
||||||
|
if (IS_ERR(imx8_phy->perst))
|
||||||
|
return dev_err_probe(dev, PTR_ERR(imx8_phy->perst),
|
||||||
|
"Failed to get PCIE PHY PERST control\n");
|
||||||
|
}
|
||||||
|
|
||||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||||
imx8_phy->base = devm_ioremap_resource(dev, res);
|
imx8_phy->base = devm_ioremap_resource(dev, res);
|
||||||
if (IS_ERR(imx8_phy->base))
|
if (IS_ERR(imx8_phy->base))
|
||||||
|
|||||||
@@ -242,6 +242,9 @@ static int rza2_gpio_register(struct rza2_pinctrl_priv *priv)
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
chip.label = devm_kasprintf(priv->dev, GFP_KERNEL, "%pOFn", np);
|
chip.label = devm_kasprintf(priv->dev, GFP_KERNEL, "%pOFn", np);
|
||||||
|
if (!chip.label)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
chip.parent = priv->dev;
|
chip.parent = priv->dev;
|
||||||
chip.ngpio = priv->npins;
|
chip.ngpio = priv->npins;
|
||||||
|
|
||||||
|
|||||||
@@ -35,6 +35,7 @@
|
|||||||
#define PCF85063_REG_CTRL1_CAP_SEL BIT(0)
|
#define PCF85063_REG_CTRL1_CAP_SEL BIT(0)
|
||||||
#define PCF85063_REG_CTRL1_STOP BIT(5)
|
#define PCF85063_REG_CTRL1_STOP BIT(5)
|
||||||
#define PCF85063_REG_CTRL1_EXT_TEST BIT(7)
|
#define PCF85063_REG_CTRL1_EXT_TEST BIT(7)
|
||||||
|
#define PCF85063_REG_CTRL1_SWR 0x58
|
||||||
|
|
||||||
#define PCF85063_REG_CTRL2 0x01
|
#define PCF85063_REG_CTRL2 0x01
|
||||||
#define PCF85063_CTRL2_AF BIT(6)
|
#define PCF85063_CTRL2_AF BIT(6)
|
||||||
@@ -606,7 +607,7 @@ static int pcf85063_probe(struct i2c_client *client)
|
|||||||
|
|
||||||
i2c_set_clientdata(client, pcf85063);
|
i2c_set_clientdata(client, pcf85063);
|
||||||
|
|
||||||
err = regmap_read(pcf85063->regmap, PCF85063_REG_CTRL1, &tmp);
|
err = regmap_read(pcf85063->regmap, PCF85063_REG_SC, &tmp);
|
||||||
if (err) {
|
if (err) {
|
||||||
dev_err(&client->dev, "RTC chip is not present\n");
|
dev_err(&client->dev, "RTC chip is not present\n");
|
||||||
return err;
|
return err;
|
||||||
@@ -616,6 +617,22 @@ static int pcf85063_probe(struct i2c_client *client)
|
|||||||
if (IS_ERR(pcf85063->rtc))
|
if (IS_ERR(pcf85063->rtc))
|
||||||
return PTR_ERR(pcf85063->rtc);
|
return PTR_ERR(pcf85063->rtc);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If a Power loss is detected, SW reset the device.
|
||||||
|
* From PCF85063A datasheet:
|
||||||
|
* There is a low probability that some devices will have corruption
|
||||||
|
* of the registers after the automatic power-on reset...
|
||||||
|
*/
|
||||||
|
if (tmp & PCF85063_REG_SC_OS) {
|
||||||
|
dev_warn(&client->dev,
|
||||||
|
"POR issue detected, sending a SW reset\n");
|
||||||
|
err = regmap_write(pcf85063->regmap, PCF85063_REG_CTRL1,
|
||||||
|
PCF85063_REG_CTRL1_SWR);
|
||||||
|
if (err < 0)
|
||||||
|
dev_warn(&client->dev,
|
||||||
|
"SW reset failed, trying to continue\n");
|
||||||
|
}
|
||||||
|
|
||||||
err = pcf85063_load_capacitance(pcf85063, client->dev.of_node,
|
err = pcf85063_load_capacitance(pcf85063, client->dev.of_node,
|
||||||
config->force_cap_7000 ? 7000 : 0);
|
config->force_cap_7000 ? 7000 : 0);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
|
|||||||
@@ -263,6 +263,19 @@ static struct console sclp_console =
|
|||||||
.index = 0 /* ttyS0 */
|
.index = 0 /* ttyS0 */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Release allocated pages.
|
||||||
|
*/
|
||||||
|
static void __init __sclp_console_free_pages(void)
|
||||||
|
{
|
||||||
|
struct list_head *page, *p;
|
||||||
|
|
||||||
|
list_for_each_safe(page, p, &sclp_con_pages) {
|
||||||
|
list_del(page);
|
||||||
|
free_page((unsigned long)page);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* called by console_init() in drivers/char/tty_io.c at boot-time.
|
* called by console_init() in drivers/char/tty_io.c at boot-time.
|
||||||
*/
|
*/
|
||||||
@@ -282,6 +295,10 @@ sclp_console_init(void)
|
|||||||
/* Allocate pages for output buffering */
|
/* Allocate pages for output buffering */
|
||||||
for (i = 0; i < sclp_console_pages; i++) {
|
for (i = 0; i < sclp_console_pages; i++) {
|
||||||
page = (void *) get_zeroed_page(GFP_KERNEL | GFP_DMA);
|
page = (void *) get_zeroed_page(GFP_KERNEL | GFP_DMA);
|
||||||
|
if (!page) {
|
||||||
|
__sclp_console_free_pages();
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
list_add_tail(page, &sclp_con_pages);
|
list_add_tail(page, &sclp_con_pages);
|
||||||
}
|
}
|
||||||
sclp_conbuf = NULL;
|
sclp_conbuf = NULL;
|
||||||
|
|||||||
@@ -490,6 +490,17 @@ static const struct tty_operations sclp_ops = {
|
|||||||
.flush_buffer = sclp_tty_flush_buffer,
|
.flush_buffer = sclp_tty_flush_buffer,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Release allocated pages. */
|
||||||
|
static void __init __sclp_tty_free_pages(void)
|
||||||
|
{
|
||||||
|
struct list_head *page, *p;
|
||||||
|
|
||||||
|
list_for_each_safe(page, p, &sclp_tty_pages) {
|
||||||
|
list_del(page);
|
||||||
|
free_page((unsigned long)page);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int __init
|
static int __init
|
||||||
sclp_tty_init(void)
|
sclp_tty_init(void)
|
||||||
{
|
{
|
||||||
@@ -516,6 +527,7 @@ sclp_tty_init(void)
|
|||||||
for (i = 0; i < MAX_KMEM_PAGES; i++) {
|
for (i = 0; i < MAX_KMEM_PAGES; i++) {
|
||||||
page = (void *) get_zeroed_page(GFP_KERNEL | GFP_DMA);
|
page = (void *) get_zeroed_page(GFP_KERNEL | GFP_DMA);
|
||||||
if (page == NULL) {
|
if (page == NULL) {
|
||||||
|
__sclp_tty_free_pages();
|
||||||
tty_driver_kref_put(driver);
|
tty_driver_kref_put(driver);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -865,8 +865,28 @@ static void hisi_sas_phyup_work_common(struct work_struct *work,
|
|||||||
container_of(work, typeof(*phy), works[event]);
|
container_of(work, typeof(*phy), works[event]);
|
||||||
struct hisi_hba *hisi_hba = phy->hisi_hba;
|
struct hisi_hba *hisi_hba = phy->hisi_hba;
|
||||||
struct asd_sas_phy *sas_phy = &phy->sas_phy;
|
struct asd_sas_phy *sas_phy = &phy->sas_phy;
|
||||||
|
struct asd_sas_port *sas_port = sas_phy->port;
|
||||||
|
struct hisi_sas_port *port = phy->port;
|
||||||
|
struct device *dev = hisi_hba->dev;
|
||||||
|
struct domain_device *port_dev;
|
||||||
int phy_no = sas_phy->id;
|
int phy_no = sas_phy->id;
|
||||||
|
|
||||||
|
if (!test_bit(HISI_SAS_RESETTING_BIT, &hisi_hba->flags) &&
|
||||||
|
sas_port && port && (port->id != phy->port_id)) {
|
||||||
|
dev_info(dev, "phy%d's hw port id changed from %d to %llu\n",
|
||||||
|
phy_no, port->id, phy->port_id);
|
||||||
|
port_dev = sas_port->port_dev;
|
||||||
|
if (port_dev && !dev_is_expander(port_dev->dev_type)) {
|
||||||
|
/*
|
||||||
|
* Set the device state to gone to block
|
||||||
|
* sending IO to the device.
|
||||||
|
*/
|
||||||
|
set_bit(SAS_DEV_GONE, &port_dev->state);
|
||||||
|
hisi_sas_notify_phy_event(phy, HISI_PHYE_LINK_RESET);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
phy->wait_phyup_cnt = 0;
|
phy->wait_phyup_cnt = 0;
|
||||||
if (phy->identify.target_port_protocols == SAS_PROTOCOL_SSP)
|
if (phy->identify.target_port_protocols == SAS_PROTOCOL_SSP)
|
||||||
hisi_hba->hw->sl_notify_ssp(hisi_hba, phy_no);
|
hisi_hba->hw->sl_notify_ssp(hisi_hba, phy_no);
|
||||||
|
|||||||
@@ -720,6 +720,7 @@ static void pm8001_dev_gone_notify(struct domain_device *dev)
|
|||||||
spin_lock_irqsave(&pm8001_ha->lock, flags);
|
spin_lock_irqsave(&pm8001_ha->lock, flags);
|
||||||
}
|
}
|
||||||
PM8001_CHIP_DISP->dereg_dev_req(pm8001_ha, device_id);
|
PM8001_CHIP_DISP->dereg_dev_req(pm8001_ha, device_id);
|
||||||
|
pm8001_ha->phy[pm8001_dev->attached_phy].phy_attached = 0;
|
||||||
pm8001_free_dev(pm8001_dev);
|
pm8001_free_dev(pm8001_dev);
|
||||||
} else {
|
} else {
|
||||||
pm8001_dbg(pm8001_ha, DISC, "Found dev has gone.\n");
|
pm8001_dbg(pm8001_ha, DISC, "Found dev has gone.\n");
|
||||||
|
|||||||
@@ -1157,8 +1157,12 @@ EXPORT_SYMBOL_GPL(scsi_alloc_request);
|
|||||||
*/
|
*/
|
||||||
static void scsi_cleanup_rq(struct request *rq)
|
static void scsi_cleanup_rq(struct request *rq)
|
||||||
{
|
{
|
||||||
|
struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(rq);
|
||||||
|
|
||||||
|
cmd->flags = 0;
|
||||||
|
|
||||||
if (rq->rq_flags & RQF_DONTPREP) {
|
if (rq->rq_flags & RQF_DONTPREP) {
|
||||||
scsi_mq_uninit_cmd(blk_mq_rq_to_pdu(rq));
|
scsi_mq_uninit_cmd(cmd);
|
||||||
rq->rq_flags &= ~RQF_DONTPREP;
|
rq->rq_flags &= ~RQF_DONTPREP;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1605,10 +1605,13 @@ static int spi_imx_transfer_one(struct spi_controller *controller,
|
|||||||
struct spi_device *spi,
|
struct spi_device *spi,
|
||||||
struct spi_transfer *transfer)
|
struct spi_transfer *transfer)
|
||||||
{
|
{
|
||||||
|
int ret;
|
||||||
struct spi_imx_data *spi_imx = spi_controller_get_devdata(spi->controller);
|
struct spi_imx_data *spi_imx = spi_controller_get_devdata(spi->controller);
|
||||||
unsigned long hz_per_byte, byte_limit;
|
unsigned long hz_per_byte, byte_limit;
|
||||||
|
|
||||||
spi_imx_setupxfer(spi, transfer);
|
ret = spi_imx_setupxfer(spi, transfer);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
transfer->effective_speed_hz = spi_imx->spi_bus_clk;
|
transfer->effective_speed_hz = spi_imx->spi_bus_clk;
|
||||||
|
|
||||||
/* flush rxfifo before transfer */
|
/* flush rxfifo before transfer */
|
||||||
|
|||||||
@@ -1110,9 +1110,9 @@ static int tegra_qspi_combined_seq_xfer(struct tegra_qspi *tqspi,
|
|||||||
(&tqspi->xfer_completion,
|
(&tqspi->xfer_completion,
|
||||||
QSPI_DMA_TIMEOUT);
|
QSPI_DMA_TIMEOUT);
|
||||||
|
|
||||||
if (WARN_ON(ret == 0)) {
|
if (WARN_ON_ONCE(ret == 0)) {
|
||||||
dev_err(tqspi->dev, "QSPI Transfer failed with timeout: %d\n",
|
dev_err_ratelimited(tqspi->dev,
|
||||||
ret);
|
"QSPI Transfer failed with timeout\n");
|
||||||
if (tqspi->is_curr_dma_xfer &&
|
if (tqspi->is_curr_dma_xfer &&
|
||||||
(tqspi->cur_direction & DATA_DIR_TX))
|
(tqspi->cur_direction & DATA_DIR_TX))
|
||||||
dmaengine_terminate_all
|
dmaengine_terminate_all
|
||||||
|
|||||||
@@ -640,11 +640,15 @@ static void tb_scan_port(struct tb_port *port)
|
|||||||
goto out_rpm_put;
|
goto out_rpm_put;
|
||||||
}
|
}
|
||||||
|
|
||||||
tb_retimer_scan(port, true);
|
|
||||||
|
|
||||||
sw = tb_switch_alloc(port->sw->tb, &port->sw->dev,
|
sw = tb_switch_alloc(port->sw->tb, &port->sw->dev,
|
||||||
tb_downstream_route(port));
|
tb_downstream_route(port));
|
||||||
if (IS_ERR(sw)) {
|
if (IS_ERR(sw)) {
|
||||||
|
/*
|
||||||
|
* Make the downstream retimers available even if there
|
||||||
|
* is no router connected.
|
||||||
|
*/
|
||||||
|
tb_retimer_scan(port, true);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If there is an error accessing the connected switch
|
* If there is an error accessing the connected switch
|
||||||
* it may be connected to another domain. Also we allow
|
* it may be connected to another domain. Also we allow
|
||||||
@@ -704,6 +708,14 @@ static void tb_scan_port(struct tb_port *port)
|
|||||||
tb_switch_lane_bonding_enable(sw);
|
tb_switch_lane_bonding_enable(sw);
|
||||||
/* Set the link configured */
|
/* Set the link configured */
|
||||||
tb_switch_configure_link(sw);
|
tb_switch_configure_link(sw);
|
||||||
|
/*
|
||||||
|
* Scan for downstream retimers. We only scan them after the
|
||||||
|
* router has been enumerated to avoid issues with certain
|
||||||
|
* Pluggable devices that expect the host to enumerate them
|
||||||
|
* within certain timeout.
|
||||||
|
*/
|
||||||
|
tb_retimer_scan(port, true);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* CL0s and CL1 are enabled and supported together.
|
* CL0s and CL1 are enabled and supported together.
|
||||||
* Silently ignore CLx enabling in case CLx is not supported.
|
* Silently ignore CLx enabling in case CLx is not supported.
|
||||||
|
|||||||
@@ -1745,6 +1745,12 @@ msm_serial_early_console_setup_dm(struct earlycon_device *device,
|
|||||||
if (!device->port.membase)
|
if (!device->port.membase)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
|
/* Disable DM / single-character modes */
|
||||||
|
msm_write(&device->port, 0, UARTDM_DMEN);
|
||||||
|
msm_write(&device->port, MSM_UART_CR_CMD_RESET_RX, MSM_UART_CR);
|
||||||
|
msm_write(&device->port, MSM_UART_CR_CMD_RESET_TX, MSM_UART_CR);
|
||||||
|
msm_write(&device->port, MSM_UART_CR_TX_ENABLE, MSM_UART_CR);
|
||||||
|
|
||||||
device->con->write = msm_serial_early_write_dm;
|
device->con->write = msm_serial_early_write_dm;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -583,8 +583,11 @@ static void sifive_serial_break_ctl(struct uart_port *port, int break_state)
|
|||||||
static int sifive_serial_startup(struct uart_port *port)
|
static int sifive_serial_startup(struct uart_port *port)
|
||||||
{
|
{
|
||||||
struct sifive_serial_port *ssp = port_to_sifive_serial_port(port);
|
struct sifive_serial_port *ssp = port_to_sifive_serial_port(port);
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
uart_port_lock_irqsave(&ssp->port, &flags);
|
||||||
__ssp_enable_rxwm(ssp);
|
__ssp_enable_rxwm(ssp);
|
||||||
|
uart_port_unlock_irqrestore(&ssp->port, flags);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -592,9 +595,12 @@ static int sifive_serial_startup(struct uart_port *port)
|
|||||||
static void sifive_serial_shutdown(struct uart_port *port)
|
static void sifive_serial_shutdown(struct uart_port *port)
|
||||||
{
|
{
|
||||||
struct sifive_serial_port *ssp = port_to_sifive_serial_port(port);
|
struct sifive_serial_port *ssp = port_to_sifive_serial_port(port);
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
uart_port_lock_irqsave(&ssp->port, &flags);
|
||||||
__ssp_disable_rxwm(ssp);
|
__ssp_disable_rxwm(ssp);
|
||||||
__ssp_disable_txwm(ssp);
|
__ssp_disable_txwm(ssp);
|
||||||
|
uart_port_unlock_irqrestore(&ssp->port, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -990,9 +990,14 @@ static int exynos_ufs_pre_link(struct ufs_hba *hba)
|
|||||||
exynos_ufs_config_intr(ufs, DFES_DEF_L4_ERRS, UNIPRO_L4);
|
exynos_ufs_config_intr(ufs, DFES_DEF_L4_ERRS, UNIPRO_L4);
|
||||||
exynos_ufs_set_unipro_pclk_div(ufs);
|
exynos_ufs_set_unipro_pclk_div(ufs);
|
||||||
|
|
||||||
|
exynos_ufs_setup_clocks(hba, true, PRE_CHANGE);
|
||||||
|
|
||||||
/* unipro */
|
/* unipro */
|
||||||
exynos_ufs_config_unipro(ufs);
|
exynos_ufs_config_unipro(ufs);
|
||||||
|
|
||||||
|
if (ufs->drv_data->pre_link)
|
||||||
|
ufs->drv_data->pre_link(ufs);
|
||||||
|
|
||||||
/* m-phy */
|
/* m-phy */
|
||||||
exynos_ufs_phy_init(ufs);
|
exynos_ufs_phy_init(ufs);
|
||||||
if (!(ufs->opts & EXYNOS_UFS_OPT_SKIP_CONFIG_PHY_ATTR)) {
|
if (!(ufs->opts & EXYNOS_UFS_OPT_SKIP_CONFIG_PHY_ATTR)) {
|
||||||
@@ -1000,11 +1005,6 @@ static int exynos_ufs_pre_link(struct ufs_hba *hba)
|
|||||||
exynos_ufs_config_phy_cap_attr(ufs);
|
exynos_ufs_config_phy_cap_attr(ufs);
|
||||||
}
|
}
|
||||||
|
|
||||||
exynos_ufs_setup_clocks(hba, true, PRE_CHANGE);
|
|
||||||
|
|
||||||
if (ufs->drv_data->pre_link)
|
|
||||||
ufs->drv_data->pre_link(ufs);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1960,6 +1960,7 @@ static irqreturn_t cdns3_device_thread_irq_handler(int irq, void *data)
|
|||||||
unsigned int bit;
|
unsigned int bit;
|
||||||
unsigned long reg;
|
unsigned long reg;
|
||||||
|
|
||||||
|
local_bh_disable();
|
||||||
spin_lock_irqsave(&priv_dev->lock, flags);
|
spin_lock_irqsave(&priv_dev->lock, flags);
|
||||||
|
|
||||||
reg = readl(&priv_dev->regs->usb_ists);
|
reg = readl(&priv_dev->regs->usb_ists);
|
||||||
@@ -2001,6 +2002,7 @@ static irqreturn_t cdns3_device_thread_irq_handler(int irq, void *data)
|
|||||||
irqend:
|
irqend:
|
||||||
writel(~0, &priv_dev->regs->ep_ien);
|
writel(~0, &priv_dev->regs->ep_ien);
|
||||||
spin_unlock_irqrestore(&priv_dev->lock, flags);
|
spin_unlock_irqrestore(&priv_dev->lock, flags);
|
||||||
|
local_bh_enable();
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -324,6 +324,13 @@ static int ci_hdrc_imx_notify_event(struct ci_hdrc *ci, unsigned int event)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ci_hdrc_imx_disable_regulator(void *arg)
|
||||||
|
{
|
||||||
|
struct ci_hdrc_imx_data *data = arg;
|
||||||
|
|
||||||
|
regulator_disable(data->hsic_pad_regulator);
|
||||||
|
}
|
||||||
|
|
||||||
static int ci_hdrc_imx_probe(struct platform_device *pdev)
|
static int ci_hdrc_imx_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct ci_hdrc_imx_data *data;
|
struct ci_hdrc_imx_data *data;
|
||||||
@@ -381,6 +388,13 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
|
|||||||
"Failed to enable HSIC pad regulator\n");
|
"Failed to enable HSIC pad regulator\n");
|
||||||
goto err_put;
|
goto err_put;
|
||||||
}
|
}
|
||||||
|
ret = devm_add_action_or_reset(dev,
|
||||||
|
ci_hdrc_imx_disable_regulator, data);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(dev,
|
||||||
|
"Failed to add regulator devm action\n");
|
||||||
|
goto err_put;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -419,11 +433,11 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
|
|||||||
|
|
||||||
ret = imx_get_clks(dev);
|
ret = imx_get_clks(dev);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto disable_hsic_regulator;
|
goto qos_remove_request;
|
||||||
|
|
||||||
ret = imx_prepare_enable_clks(dev);
|
ret = imx_prepare_enable_clks(dev);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto disable_hsic_regulator;
|
goto qos_remove_request;
|
||||||
|
|
||||||
data->phy = devm_usb_get_phy_by_phandle(dev, "fsl,usbphy", 0);
|
data->phy = devm_usb_get_phy_by_phandle(dev, "fsl,usbphy", 0);
|
||||||
if (IS_ERR(data->phy)) {
|
if (IS_ERR(data->phy)) {
|
||||||
@@ -449,7 +463,11 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
|
|||||||
of_usb_get_phy_mode(np) == USBPHY_INTERFACE_MODE_ULPI) {
|
of_usb_get_phy_mode(np) == USBPHY_INTERFACE_MODE_ULPI) {
|
||||||
pdata.flags |= CI_HDRC_OVERRIDE_PHY_CONTROL;
|
pdata.flags |= CI_HDRC_OVERRIDE_PHY_CONTROL;
|
||||||
data->override_phy_control = true;
|
data->override_phy_control = true;
|
||||||
usb_phy_init(pdata.usb_phy);
|
ret = usb_phy_init(pdata.usb_phy);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(dev, "Failed to init phy\n");
|
||||||
|
goto err_clk;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pdata.flags & CI_HDRC_SUPPORTS_RUNTIME_PM)
|
if (pdata.flags & CI_HDRC_SUPPORTS_RUNTIME_PM)
|
||||||
@@ -458,7 +476,7 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
|
|||||||
ret = imx_usbmisc_init(data->usbmisc_data);
|
ret = imx_usbmisc_init(data->usbmisc_data);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(dev, "usbmisc init failed, ret=%d\n", ret);
|
dev_err(dev, "usbmisc init failed, ret=%d\n", ret);
|
||||||
goto err_clk;
|
goto phy_shutdown;
|
||||||
}
|
}
|
||||||
|
|
||||||
data->ci_pdev = ci_hdrc_add_device(dev,
|
data->ci_pdev = ci_hdrc_add_device(dev,
|
||||||
@@ -467,7 +485,7 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
|
|||||||
if (IS_ERR(data->ci_pdev)) {
|
if (IS_ERR(data->ci_pdev)) {
|
||||||
ret = PTR_ERR(data->ci_pdev);
|
ret = PTR_ERR(data->ci_pdev);
|
||||||
dev_err_probe(dev, ret, "ci_hdrc_add_device failed\n");
|
dev_err_probe(dev, ret, "ci_hdrc_add_device failed\n");
|
||||||
goto err_clk;
|
goto phy_shutdown;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data->usbmisc_data) {
|
if (data->usbmisc_data) {
|
||||||
@@ -501,17 +519,18 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
|
|||||||
|
|
||||||
disable_device:
|
disable_device:
|
||||||
ci_hdrc_remove_device(data->ci_pdev);
|
ci_hdrc_remove_device(data->ci_pdev);
|
||||||
|
phy_shutdown:
|
||||||
|
if (data->override_phy_control)
|
||||||
|
usb_phy_shutdown(data->phy);
|
||||||
err_clk:
|
err_clk:
|
||||||
imx_disable_unprepare_clks(dev);
|
imx_disable_unprepare_clks(dev);
|
||||||
disable_hsic_regulator:
|
qos_remove_request:
|
||||||
if (data->hsic_pad_regulator)
|
|
||||||
/* don't overwrite original ret (cf. EPROBE_DEFER) */
|
|
||||||
regulator_disable(data->hsic_pad_regulator);
|
|
||||||
if (pdata.flags & CI_HDRC_PMQOS)
|
if (pdata.flags & CI_HDRC_PMQOS)
|
||||||
cpu_latency_qos_remove_request(&data->pm_qos_req);
|
cpu_latency_qos_remove_request(&data->pm_qos_req);
|
||||||
data->ci_pdev = NULL;
|
data->ci_pdev = NULL;
|
||||||
err_put:
|
err_put:
|
||||||
put_device(data->usbmisc_data->dev);
|
if (data->usbmisc_data)
|
||||||
|
put_device(data->usbmisc_data->dev);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -532,10 +551,9 @@ static void ci_hdrc_imx_remove(struct platform_device *pdev)
|
|||||||
imx_disable_unprepare_clks(&pdev->dev);
|
imx_disable_unprepare_clks(&pdev->dev);
|
||||||
if (data->plat_data->flags & CI_HDRC_PMQOS)
|
if (data->plat_data->flags & CI_HDRC_PMQOS)
|
||||||
cpu_latency_qos_remove_request(&data->pm_qos_req);
|
cpu_latency_qos_remove_request(&data->pm_qos_req);
|
||||||
if (data->hsic_pad_regulator)
|
|
||||||
regulator_disable(data->hsic_pad_regulator);
|
|
||||||
}
|
}
|
||||||
put_device(data->usbmisc_data->dev);
|
if (data->usbmisc_data)
|
||||||
|
put_device(data->usbmisc_data->dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ci_hdrc_imx_shutdown(struct platform_device *pdev)
|
static void ci_hdrc_imx_shutdown(struct platform_device *pdev)
|
||||||
|
|||||||
@@ -726,7 +726,7 @@ static int wdm_open(struct inode *inode, struct file *file)
|
|||||||
rv = -EBUSY;
|
rv = -EBUSY;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
smp_rmb(); /* ordered against wdm_wwan_port_stop() */
|
||||||
rv = usb_autopm_get_interface(desc->intf);
|
rv = usb_autopm_get_interface(desc->intf);
|
||||||
if (rv < 0) {
|
if (rv < 0) {
|
||||||
dev_err(&desc->intf->dev, "Error autopm - %d\n", rv);
|
dev_err(&desc->intf->dev, "Error autopm - %d\n", rv);
|
||||||
@@ -829,6 +829,7 @@ static struct usb_class_driver wdm_class = {
|
|||||||
static int wdm_wwan_port_start(struct wwan_port *port)
|
static int wdm_wwan_port_start(struct wwan_port *port)
|
||||||
{
|
{
|
||||||
struct wdm_device *desc = wwan_port_get_drvdata(port);
|
struct wdm_device *desc = wwan_port_get_drvdata(port);
|
||||||
|
int rv;
|
||||||
|
|
||||||
/* The interface is both exposed via the WWAN framework and as a
|
/* The interface is both exposed via the WWAN framework and as a
|
||||||
* legacy usbmisc chardev. If chardev is already open, just fail
|
* legacy usbmisc chardev. If chardev is already open, just fail
|
||||||
@@ -848,7 +849,15 @@ static int wdm_wwan_port_start(struct wwan_port *port)
|
|||||||
wwan_port_txon(port);
|
wwan_port_txon(port);
|
||||||
|
|
||||||
/* Start getting events */
|
/* Start getting events */
|
||||||
return usb_submit_urb(desc->validity, GFP_KERNEL);
|
rv = usb_submit_urb(desc->validity, GFP_KERNEL);
|
||||||
|
if (rv < 0) {
|
||||||
|
wwan_port_txoff(port);
|
||||||
|
desc->manage_power(desc->intf, 0);
|
||||||
|
/* this must be last lest we race with chardev open */
|
||||||
|
clear_bit(WDM_WWAN_IN_USE, &desc->flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void wdm_wwan_port_stop(struct wwan_port *port)
|
static void wdm_wwan_port_stop(struct wwan_port *port)
|
||||||
@@ -859,8 +868,10 @@ static void wdm_wwan_port_stop(struct wwan_port *port)
|
|||||||
poison_urbs(desc);
|
poison_urbs(desc);
|
||||||
desc->manage_power(desc->intf, 0);
|
desc->manage_power(desc->intf, 0);
|
||||||
clear_bit(WDM_READ, &desc->flags);
|
clear_bit(WDM_READ, &desc->flags);
|
||||||
clear_bit(WDM_WWAN_IN_USE, &desc->flags);
|
|
||||||
unpoison_urbs(desc);
|
unpoison_urbs(desc);
|
||||||
|
smp_wmb(); /* ordered against wdm_open() */
|
||||||
|
/* this must be last lest we open a poisoned device */
|
||||||
|
clear_bit(WDM_WWAN_IN_USE, &desc->flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void wdm_wwan_port_tx_complete(struct urb *urb)
|
static void wdm_wwan_port_tx_complete(struct urb *urb)
|
||||||
@@ -868,7 +879,7 @@ static void wdm_wwan_port_tx_complete(struct urb *urb)
|
|||||||
struct sk_buff *skb = urb->context;
|
struct sk_buff *skb = urb->context;
|
||||||
struct wdm_device *desc = skb_shinfo(skb)->destructor_arg;
|
struct wdm_device *desc = skb_shinfo(skb)->destructor_arg;
|
||||||
|
|
||||||
usb_autopm_put_interface(desc->intf);
|
usb_autopm_put_interface_async(desc->intf);
|
||||||
wwan_port_txon(desc->wwanp);
|
wwan_port_txon(desc->wwanp);
|
||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
}
|
}
|
||||||
@@ -898,7 +909,7 @@ static int wdm_wwan_port_tx(struct wwan_port *port, struct sk_buff *skb)
|
|||||||
req->bRequestType = (USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE);
|
req->bRequestType = (USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE);
|
||||||
req->bRequest = USB_CDC_SEND_ENCAPSULATED_COMMAND;
|
req->bRequest = USB_CDC_SEND_ENCAPSULATED_COMMAND;
|
||||||
req->wValue = 0;
|
req->wValue = 0;
|
||||||
req->wIndex = desc->inum;
|
req->wIndex = desc->inum; /* already converted */
|
||||||
req->wLength = cpu_to_le16(skb->len);
|
req->wLength = cpu_to_le16(skb->len);
|
||||||
|
|
||||||
skb_shinfo(skb)->destructor_arg = desc;
|
skb_shinfo(skb)->destructor_arg = desc;
|
||||||
|
|||||||
@@ -369,6 +369,9 @@ static const struct usb_device_id usb_quirk_list[] = {
|
|||||||
{ USB_DEVICE(0x0781, 0x5583), .driver_info = USB_QUIRK_NO_LPM },
|
{ USB_DEVICE(0x0781, 0x5583), .driver_info = USB_QUIRK_NO_LPM },
|
||||||
{ USB_DEVICE(0x0781, 0x5591), .driver_info = USB_QUIRK_NO_LPM },
|
{ USB_DEVICE(0x0781, 0x5591), .driver_info = USB_QUIRK_NO_LPM },
|
||||||
|
|
||||||
|
/* SanDisk Corp. SanDisk 3.2Gen1 */
|
||||||
|
{ USB_DEVICE(0x0781, 0x55a3), .driver_info = USB_QUIRK_DELAY_INIT },
|
||||||
|
|
||||||
/* Realforce 87U Keyboard */
|
/* Realforce 87U Keyboard */
|
||||||
{ USB_DEVICE(0x0853, 0x011b), .driver_info = USB_QUIRK_NO_LPM },
|
{ USB_DEVICE(0x0853, 0x011b), .driver_info = USB_QUIRK_NO_LPM },
|
||||||
|
|
||||||
@@ -383,6 +386,9 @@ static const struct usb_device_id usb_quirk_list[] = {
|
|||||||
{ USB_DEVICE(0x0904, 0x6103), .driver_info =
|
{ USB_DEVICE(0x0904, 0x6103), .driver_info =
|
||||||
USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL },
|
USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL },
|
||||||
|
|
||||||
|
/* Silicon Motion Flash Drive */
|
||||||
|
{ USB_DEVICE(0x090c, 0x1000), .driver_info = USB_QUIRK_DELAY_INIT },
|
||||||
|
|
||||||
/* Sound Devices USBPre2 */
|
/* Sound Devices USBPre2 */
|
||||||
{ USB_DEVICE(0x0926, 0x0202), .driver_info =
|
{ USB_DEVICE(0x0926, 0x0202), .driver_info =
|
||||||
USB_QUIRK_ENDPOINT_IGNORE },
|
USB_QUIRK_ENDPOINT_IGNORE },
|
||||||
@@ -536,6 +542,9 @@ static const struct usb_device_id usb_quirk_list[] = {
|
|||||||
{ USB_DEVICE(0x2040, 0x7200), .driver_info =
|
{ USB_DEVICE(0x2040, 0x7200), .driver_info =
|
||||||
USB_QUIRK_CONFIG_INTF_STRINGS },
|
USB_QUIRK_CONFIG_INTF_STRINGS },
|
||||||
|
|
||||||
|
/* VLI disk */
|
||||||
|
{ USB_DEVICE(0x2109, 0x0711), .driver_info = USB_QUIRK_NO_LPM },
|
||||||
|
|
||||||
/* Raydium Touchscreen */
|
/* Raydium Touchscreen */
|
||||||
{ USB_DEVICE(0x2386, 0x3114), .driver_info = USB_QUIRK_NO_LPM },
|
{ USB_DEVICE(0x2386, 0x3114), .driver_info = USB_QUIRK_NO_LPM },
|
||||||
|
|
||||||
|
|||||||
@@ -143,11 +143,21 @@ static const struct property_entry dwc3_pci_intel_byt_properties[] = {
|
|||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Intel Merrifield SoC uses these endpoints for tracing and they cannot
|
||||||
|
* be re-allocated if being used because the side band flow control signals
|
||||||
|
* are hard wired to certain endpoints:
|
||||||
|
* - 1 High BW Bulk IN (IN#1) (RTIT)
|
||||||
|
* - 1 1KB BW Bulk IN (IN#8) + 1 1KB BW Bulk OUT (Run Control) (OUT#8)
|
||||||
|
*/
|
||||||
|
static const u8 dwc3_pci_mrfld_reserved_endpoints[] = { 3, 16, 17 };
|
||||||
|
|
||||||
static const struct property_entry dwc3_pci_mrfld_properties[] = {
|
static const struct property_entry dwc3_pci_mrfld_properties[] = {
|
||||||
PROPERTY_ENTRY_STRING("dr_mode", "otg"),
|
PROPERTY_ENTRY_STRING("dr_mode", "otg"),
|
||||||
PROPERTY_ENTRY_STRING("linux,extcon-name", "mrfld_bcove_pwrsrc"),
|
PROPERTY_ENTRY_STRING("linux,extcon-name", "mrfld_bcove_pwrsrc"),
|
||||||
PROPERTY_ENTRY_BOOL("snps,dis_u3_susphy_quirk"),
|
PROPERTY_ENTRY_BOOL("snps,dis_u3_susphy_quirk"),
|
||||||
PROPERTY_ENTRY_BOOL("snps,dis_u2_susphy_quirk"),
|
PROPERTY_ENTRY_BOOL("snps,dis_u2_susphy_quirk"),
|
||||||
|
PROPERTY_ENTRY_U8_ARRAY("snps,reserved-endpoints", dwc3_pci_mrfld_reserved_endpoints),
|
||||||
PROPERTY_ENTRY_BOOL("snps,usb2-gadget-lpm-disable"),
|
PROPERTY_ENTRY_BOOL("snps,usb2-gadget-lpm-disable"),
|
||||||
PROPERTY_ENTRY_BOOL("linux,sysdev_is_parent"),
|
PROPERTY_ENTRY_BOOL("linux,sysdev_is_parent"),
|
||||||
{}
|
{}
|
||||||
|
|||||||
@@ -208,15 +208,13 @@ static int dwc3_xlnx_init_zynqmp(struct dwc3_xlnx *priv_data)
|
|||||||
|
|
||||||
skip_usb3_phy:
|
skip_usb3_phy:
|
||||||
/* ulpi reset via gpio-modepin or gpio-framework driver */
|
/* ulpi reset via gpio-modepin or gpio-framework driver */
|
||||||
reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
|
reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
|
||||||
if (IS_ERR(reset_gpio)) {
|
if (IS_ERR(reset_gpio)) {
|
||||||
return dev_err_probe(dev, PTR_ERR(reset_gpio),
|
return dev_err_probe(dev, PTR_ERR(reset_gpio),
|
||||||
"Failed to request reset GPIO\n");
|
"Failed to request reset GPIO\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reset_gpio) {
|
if (reset_gpio) {
|
||||||
/* Toggle ulpi to reset the phy. */
|
|
||||||
gpiod_set_value_cansleep(reset_gpio, 1);
|
|
||||||
usleep_range(5000, 10000);
|
usleep_range(5000, 10000);
|
||||||
gpiod_set_value_cansleep(reset_gpio, 0);
|
gpiod_set_value_cansleep(reset_gpio, 0);
|
||||||
usleep_range(5000, 10000);
|
usleep_range(5000, 10000);
|
||||||
|
|||||||
@@ -548,6 +548,7 @@ static int dwc3_gadget_set_xfer_resource(struct dwc3_ep *dep)
|
|||||||
int dwc3_gadget_start_config(struct dwc3 *dwc, unsigned int resource_index)
|
int dwc3_gadget_start_config(struct dwc3 *dwc, unsigned int resource_index)
|
||||||
{
|
{
|
||||||
struct dwc3_gadget_ep_cmd_params params;
|
struct dwc3_gadget_ep_cmd_params params;
|
||||||
|
struct dwc3_ep *dep;
|
||||||
u32 cmd;
|
u32 cmd;
|
||||||
int i;
|
int i;
|
||||||
int ret;
|
int ret;
|
||||||
@@ -564,8 +565,13 @@ int dwc3_gadget_start_config(struct dwc3 *dwc, unsigned int resource_index)
|
|||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
/* Reset resource allocation flags */
|
/* Reset resource allocation flags */
|
||||||
for (i = resource_index; i < dwc->num_eps && dwc->eps[i]; i++)
|
for (i = resource_index; i < dwc->num_eps; i++) {
|
||||||
dwc->eps[i]->flags &= ~DWC3_EP_RESOURCE_ALLOCATED;
|
dep = dwc->eps[i];
|
||||||
|
if (!dep)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
dep->flags &= ~DWC3_EP_RESOURCE_ALLOCATED;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -714,9 +720,11 @@ void dwc3_gadget_clear_tx_fifos(struct dwc3 *dwc)
|
|||||||
|
|
||||||
dwc->last_fifo_depth = fifo_depth;
|
dwc->last_fifo_depth = fifo_depth;
|
||||||
/* Clear existing TXFIFO for all IN eps except ep0 */
|
/* Clear existing TXFIFO for all IN eps except ep0 */
|
||||||
for (num = 3; num < min_t(int, dwc->num_eps, DWC3_ENDPOINTS_NUM);
|
for (num = 3; num < min_t(int, dwc->num_eps, DWC3_ENDPOINTS_NUM); num += 2) {
|
||||||
num += 2) {
|
|
||||||
dep = dwc->eps[num];
|
dep = dwc->eps[num];
|
||||||
|
if (!dep)
|
||||||
|
continue;
|
||||||
|
|
||||||
/* Don't change TXFRAMNUM on usb31 version */
|
/* Don't change TXFRAMNUM on usb31 version */
|
||||||
size = DWC3_IP_IS(DWC3) ? 0 :
|
size = DWC3_IP_IS(DWC3) ? 0 :
|
||||||
dwc3_readl(dwc->regs, DWC3_GTXFIFOSIZ(num >> 1)) &
|
dwc3_readl(dwc->regs, DWC3_GTXFIFOSIZ(num >> 1)) &
|
||||||
@@ -3534,6 +3542,8 @@ out:
|
|||||||
|
|
||||||
for (i = 0; i < DWC3_ENDPOINTS_NUM; i++) {
|
for (i = 0; i < DWC3_ENDPOINTS_NUM; i++) {
|
||||||
dep = dwc->eps[i];
|
dep = dwc->eps[i];
|
||||||
|
if (!dep)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (!(dep->flags & DWC3_EP_ENABLED))
|
if (!(dep->flags & DWC3_EP_ENABLED))
|
||||||
continue;
|
continue;
|
||||||
@@ -3722,6 +3732,10 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc,
|
|||||||
u8 epnum = event->endpoint_number;
|
u8 epnum = event->endpoint_number;
|
||||||
|
|
||||||
dep = dwc->eps[epnum];
|
dep = dwc->eps[epnum];
|
||||||
|
if (!dep) {
|
||||||
|
dev_warn(dwc->dev, "spurious event, endpoint %u is not allocated\n", epnum);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!(dep->flags & DWC3_EP_ENABLED)) {
|
if (!(dep->flags & DWC3_EP_ENABLED)) {
|
||||||
if ((epnum > 1) && !(dep->flags & DWC3_EP_TRANSFER_STARTED))
|
if ((epnum > 1) && !(dep->flags & DWC3_EP_TRANSFER_STARTED))
|
||||||
@@ -4418,6 +4432,12 @@ static irqreturn_t dwc3_check_event_buf(struct dwc3_event_buffer *evt)
|
|||||||
if (!count)
|
if (!count)
|
||||||
return IRQ_NONE;
|
return IRQ_NONE;
|
||||||
|
|
||||||
|
if (count > evt->length) {
|
||||||
|
dev_err_ratelimited(dwc->dev, "invalid count(%u) > evt->length(%u)\n",
|
||||||
|
count, evt->length);
|
||||||
|
return IRQ_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
evt->count = count;
|
evt->count = count;
|
||||||
evt->flags |= DWC3_EVENT_PENDING;
|
evt->flags |= DWC3_EVENT_PENDING;
|
||||||
|
|
||||||
|
|||||||
@@ -549,6 +549,9 @@ int ast_vhub_init_dev(struct ast_vhub *vhub, unsigned int idx)
|
|||||||
d->vhub = vhub;
|
d->vhub = vhub;
|
||||||
d->index = idx;
|
d->index = idx;
|
||||||
d->name = devm_kasprintf(parent, GFP_KERNEL, "port%d", idx+1);
|
d->name = devm_kasprintf(parent, GFP_KERNEL, "port%d", idx+1);
|
||||||
|
if (!d->name)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
d->regs = vhub->regs + 0x100 + 0x10 * idx;
|
d->regs = vhub->regs + 0x100 + 0x10 * idx;
|
||||||
|
|
||||||
ast_vhub_init_ep0(vhub, &d->ep0, d);
|
ast_vhub_init_ep0(vhub, &d->ep0, d);
|
||||||
|
|||||||
@@ -1955,6 +1955,12 @@ max3421_remove(struct spi_device *spi)
|
|||||||
usb_put_hcd(hcd);
|
usb_put_hcd(hcd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct spi_device_id max3421_spi_ids[] = {
|
||||||
|
{ "max3421" },
|
||||||
|
{ },
|
||||||
|
};
|
||||||
|
MODULE_DEVICE_TABLE(spi, max3421_spi_ids);
|
||||||
|
|
||||||
static const struct of_device_id max3421_of_match_table[] = {
|
static const struct of_device_id max3421_of_match_table[] = {
|
||||||
{ .compatible = "maxim,max3421", },
|
{ .compatible = "maxim,max3421", },
|
||||||
{},
|
{},
|
||||||
@@ -1964,6 +1970,7 @@ MODULE_DEVICE_TABLE(of, max3421_of_match_table);
|
|||||||
static struct spi_driver max3421_driver = {
|
static struct spi_driver max3421_driver = {
|
||||||
.probe = max3421_probe,
|
.probe = max3421_probe,
|
||||||
.remove = max3421_remove,
|
.remove = max3421_remove,
|
||||||
|
.id_table = max3421_spi_ids,
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "max3421-hcd",
|
.name = "max3421-hcd",
|
||||||
.of_match_table = of_match_ptr(max3421_of_match_table),
|
.of_match_table = of_match_ptr(max3421_of_match_table),
|
||||||
|
|||||||
@@ -165,6 +165,25 @@ static int ohci_quirk_amd700(struct usb_hcd *hcd)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int ohci_quirk_loongson(struct usb_hcd *hcd)
|
||||||
|
{
|
||||||
|
struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Loongson's LS7A OHCI controller (rev 0x02) has a
|
||||||
|
* flaw. MMIO register with offset 0x60/64 is treated
|
||||||
|
* as legacy PS2-compatible keyboard/mouse interface.
|
||||||
|
* Since OHCI only use 4KB BAR resource, LS7A OHCI's
|
||||||
|
* 32KB BAR is wrapped around (the 2nd 4KB BAR space
|
||||||
|
* is the same as the 1st 4KB internally). So add 4KB
|
||||||
|
* offset (0x1000) to the OHCI registers as a quirk.
|
||||||
|
*/
|
||||||
|
if (pdev->revision == 0x2)
|
||||||
|
hcd->regs += SZ_4K; /* SZ_4K = 0x1000 */
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int ohci_quirk_qemu(struct usb_hcd *hcd)
|
static int ohci_quirk_qemu(struct usb_hcd *hcd)
|
||||||
{
|
{
|
||||||
struct ohci_hcd *ohci = hcd_to_ohci(hcd);
|
struct ohci_hcd *ohci = hcd_to_ohci(hcd);
|
||||||
@@ -224,6 +243,10 @@ static const struct pci_device_id ohci_pci_quirks[] = {
|
|||||||
PCI_DEVICE(PCI_VENDOR_ID_ATI, 0x4399),
|
PCI_DEVICE(PCI_VENDOR_ID_ATI, 0x4399),
|
||||||
.driver_data = (unsigned long)ohci_quirk_amd700,
|
.driver_data = (unsigned long)ohci_quirk_amd700,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
PCI_DEVICE(PCI_VENDOR_ID_LOONGSON, 0x7a24),
|
||||||
|
.driver_data = (unsigned long)ohci_quirk_loongson,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
.vendor = PCI_VENDOR_ID_APPLE,
|
.vendor = PCI_VENDOR_ID_APPLE,
|
||||||
.device = 0x003f,
|
.device = 0x003f,
|
||||||
|
|||||||
@@ -73,13 +73,3 @@ int xhci_mvebu_mbus_init_quirk(struct usb_hcd *hcd)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int xhci_mvebu_a3700_init_quirk(struct usb_hcd *hcd)
|
|
||||||
{
|
|
||||||
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
|
|
||||||
|
|
||||||
/* Without reset on resume, the HC won't work at all */
|
|
||||||
xhci->quirks |= XHCI_RESET_ON_RESUME;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -12,16 +12,10 @@ struct usb_hcd;
|
|||||||
|
|
||||||
#if IS_ENABLED(CONFIG_USB_XHCI_MVEBU)
|
#if IS_ENABLED(CONFIG_USB_XHCI_MVEBU)
|
||||||
int xhci_mvebu_mbus_init_quirk(struct usb_hcd *hcd);
|
int xhci_mvebu_mbus_init_quirk(struct usb_hcd *hcd);
|
||||||
int xhci_mvebu_a3700_init_quirk(struct usb_hcd *hcd);
|
|
||||||
#else
|
#else
|
||||||
static inline int xhci_mvebu_mbus_init_quirk(struct usb_hcd *hcd)
|
static inline int xhci_mvebu_mbus_init_quirk(struct usb_hcd *hcd)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int xhci_mvebu_a3700_init_quirk(struct usb_hcd *hcd)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
#endif /* __LINUX_XHCI_MVEBU_H */
|
#endif /* __LINUX_XHCI_MVEBU_H */
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ static const struct xhci_plat_priv xhci_plat_marvell_armada = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static const struct xhci_plat_priv xhci_plat_marvell_armada3700 = {
|
static const struct xhci_plat_priv xhci_plat_marvell_armada3700 = {
|
||||||
.init_quirk = xhci_mvebu_a3700_init_quirk,
|
.quirks = XHCI_RESET_ON_RESUME,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct xhci_plat_priv xhci_plat_renesas_rcar_gen2 = {
|
static const struct xhci_plat_priv xhci_plat_renesas_rcar_gen2 = {
|
||||||
|
|||||||
@@ -1093,6 +1093,8 @@ static const struct usb_device_id id_table_combined[] = {
|
|||||||
{ USB_DEVICE_INTERFACE_NUMBER(ALTERA_VID, ALTERA_UB3_602E_PID, 1) },
|
{ USB_DEVICE_INTERFACE_NUMBER(ALTERA_VID, ALTERA_UB3_602E_PID, 1) },
|
||||||
{ USB_DEVICE_INTERFACE_NUMBER(ALTERA_VID, ALTERA_UB3_602E_PID, 2) },
|
{ USB_DEVICE_INTERFACE_NUMBER(ALTERA_VID, ALTERA_UB3_602E_PID, 2) },
|
||||||
{ USB_DEVICE_INTERFACE_NUMBER(ALTERA_VID, ALTERA_UB3_602E_PID, 3) },
|
{ USB_DEVICE_INTERFACE_NUMBER(ALTERA_VID, ALTERA_UB3_602E_PID, 3) },
|
||||||
|
/* Abacus Electrics */
|
||||||
|
{ USB_DEVICE(FTDI_VID, ABACUS_OPTICAL_PROBE_PID) },
|
||||||
{ } /* Terminating entry */
|
{ } /* Terminating entry */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -442,6 +442,11 @@
|
|||||||
#define LINX_FUTURE_1_PID 0xF44B /* Linx future device */
|
#define LINX_FUTURE_1_PID 0xF44B /* Linx future device */
|
||||||
#define LINX_FUTURE_2_PID 0xF44C /* Linx future device */
|
#define LINX_FUTURE_2_PID 0xF44C /* Linx future device */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Abacus Electrics
|
||||||
|
*/
|
||||||
|
#define ABACUS_OPTICAL_PROBE_PID 0xf458 /* ABACUS ELECTRICS Optical Probe */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Oceanic product ids
|
* Oceanic product ids
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -611,6 +611,7 @@ static void option_instat_callback(struct urb *urb);
|
|||||||
/* Sierra Wireless products */
|
/* Sierra Wireless products */
|
||||||
#define SIERRA_VENDOR_ID 0x1199
|
#define SIERRA_VENDOR_ID 0x1199
|
||||||
#define SIERRA_PRODUCT_EM9191 0x90d3
|
#define SIERRA_PRODUCT_EM9191 0x90d3
|
||||||
|
#define SIERRA_PRODUCT_EM9291 0x90e3
|
||||||
|
|
||||||
/* UNISOC (Spreadtrum) products */
|
/* UNISOC (Spreadtrum) products */
|
||||||
#define UNISOC_VENDOR_ID 0x1782
|
#define UNISOC_VENDOR_ID 0x1782
|
||||||
@@ -2432,6 +2433,8 @@ static const struct usb_device_id option_ids[] = {
|
|||||||
{ USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9191, 0xff, 0xff, 0x30) },
|
{ USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9191, 0xff, 0xff, 0x30) },
|
||||||
{ USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9191, 0xff, 0xff, 0x40) },
|
{ USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9191, 0xff, 0xff, 0x40) },
|
||||||
{ USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9191, 0xff, 0, 0) },
|
{ USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9191, 0xff, 0, 0) },
|
||||||
|
{ USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9291, 0xff, 0xff, 0x30) },
|
||||||
|
{ USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9291, 0xff, 0xff, 0x40) },
|
||||||
{ USB_DEVICE_AND_INTERFACE_INFO(UNISOC_VENDOR_ID, TOZED_PRODUCT_LT70C, 0xff, 0, 0) },
|
{ USB_DEVICE_AND_INTERFACE_INFO(UNISOC_VENDOR_ID, TOZED_PRODUCT_LT70C, 0xff, 0, 0) },
|
||||||
{ USB_DEVICE_AND_INTERFACE_INFO(UNISOC_VENDOR_ID, LUAT_PRODUCT_AIR720U, 0xff, 0, 0) },
|
{ USB_DEVICE_AND_INTERFACE_INFO(UNISOC_VENDOR_ID, LUAT_PRODUCT_AIR720U, 0xff, 0, 0) },
|
||||||
{ USB_DEVICE_INTERFACE_CLASS(0x1bbb, 0x0530, 0xff), /* TCL IK512 MBIM */
|
{ USB_DEVICE_INTERFACE_CLASS(0x1bbb, 0x0530, 0xff), /* TCL IK512 MBIM */
|
||||||
|
|||||||
@@ -101,6 +101,11 @@ DEVICE(nokia, NOKIA_IDS);
|
|||||||
{ USB_DEVICE(0x09d7, 0x0100) } /* NovAtel FlexPack GPS */
|
{ USB_DEVICE(0x09d7, 0x0100) } /* NovAtel FlexPack GPS */
|
||||||
DEVICE_N(novatel_gps, NOVATEL_IDS, 3);
|
DEVICE_N(novatel_gps, NOVATEL_IDS, 3);
|
||||||
|
|
||||||
|
/* OWON electronic test and measurement equipment driver */
|
||||||
|
#define OWON_IDS() \
|
||||||
|
{ USB_DEVICE(0x5345, 0x1234) } /* HDS200 oscilloscopes and others */
|
||||||
|
DEVICE(owon, OWON_IDS);
|
||||||
|
|
||||||
/* Siemens USB/MPI adapter */
|
/* Siemens USB/MPI adapter */
|
||||||
#define SIEMENS_IDS() \
|
#define SIEMENS_IDS() \
|
||||||
{ USB_DEVICE(0x908, 0x0004) }
|
{ USB_DEVICE(0x908, 0x0004) }
|
||||||
@@ -135,6 +140,7 @@ static struct usb_serial_driver * const serial_drivers[] = {
|
|||||||
&motorola_tetra_device,
|
&motorola_tetra_device,
|
||||||
&nokia_device,
|
&nokia_device,
|
||||||
&novatel_gps_device,
|
&novatel_gps_device,
|
||||||
|
&owon_device,
|
||||||
&siemens_mpi_device,
|
&siemens_mpi_device,
|
||||||
&suunto_device,
|
&suunto_device,
|
||||||
&vivopay_device,
|
&vivopay_device,
|
||||||
@@ -154,6 +160,7 @@ static const struct usb_device_id id_table[] = {
|
|||||||
MOTOROLA_TETRA_IDS(),
|
MOTOROLA_TETRA_IDS(),
|
||||||
NOKIA_IDS(),
|
NOKIA_IDS(),
|
||||||
NOVATEL_IDS(),
|
NOVATEL_IDS(),
|
||||||
|
OWON_IDS(),
|
||||||
SIEMENS_IDS(),
|
SIEMENS_IDS(),
|
||||||
SUUNTO_IDS(),
|
SUUNTO_IDS(),
|
||||||
VIVOPAY_IDS(),
|
VIVOPAY_IDS(),
|
||||||
|
|||||||
@@ -83,6 +83,13 @@ UNUSUAL_DEV(0x0bc2, 0x331a, 0x0000, 0x9999,
|
|||||||
USB_SC_DEVICE, USB_PR_DEVICE, NULL,
|
USB_SC_DEVICE, USB_PR_DEVICE, NULL,
|
||||||
US_FL_NO_REPORT_LUNS),
|
US_FL_NO_REPORT_LUNS),
|
||||||
|
|
||||||
|
/* Reported-by: Oliver Neukum <oneukum@suse.com> */
|
||||||
|
UNUSUAL_DEV(0x125f, 0xa94a, 0x0160, 0x0160,
|
||||||
|
"ADATA",
|
||||||
|
"Portable HDD CH94",
|
||||||
|
USB_SC_DEVICE, USB_PR_DEVICE, NULL,
|
||||||
|
US_FL_NO_ATA_1X),
|
||||||
|
|
||||||
/* Reported-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> */
|
/* Reported-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> */
|
||||||
UNUSUAL_DEV(0x13fd, 0x3940, 0x0000, 0x9999,
|
UNUSUAL_DEV(0x13fd, 0x3940, 0x0000, 0x9999,
|
||||||
"Initio Corporation",
|
"Initio Corporation",
|
||||||
|
|||||||
@@ -217,7 +217,7 @@ static int led_bl_probe(struct platform_device *pdev)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int led_bl_remove(struct platform_device *pdev)
|
static void led_bl_remove(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct led_bl_data *priv = platform_get_drvdata(pdev);
|
struct led_bl_data *priv = platform_get_drvdata(pdev);
|
||||||
struct backlight_device *bl = priv->bl_dev;
|
struct backlight_device *bl = priv->bl_dev;
|
||||||
@@ -226,10 +226,11 @@ static int led_bl_remove(struct platform_device *pdev)
|
|||||||
backlight_device_unregister(bl);
|
backlight_device_unregister(bl);
|
||||||
|
|
||||||
led_bl_power_off(priv);
|
led_bl_power_off(priv);
|
||||||
for (i = 0; i < priv->nb_leds; i++)
|
for (i = 0; i < priv->nb_leds; i++) {
|
||||||
|
mutex_lock(&priv->leds[i]->led_access);
|
||||||
led_sysfs_enable(priv->leds[i]);
|
led_sysfs_enable(priv->leds[i]);
|
||||||
|
mutex_unlock(&priv->leds[i]->led_access);
|
||||||
return 0;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct of_device_id led_bl_of_match[] = {
|
static const struct of_device_id led_bl_of_match[] = {
|
||||||
@@ -245,7 +246,7 @@ static struct platform_driver led_bl_driver = {
|
|||||||
.of_match_table = of_match_ptr(led_bl_of_match),
|
.of_match_table = of_match_ptr(led_bl_of_match),
|
||||||
},
|
},
|
||||||
.probe = led_bl_probe,
|
.probe = led_bl_probe,
|
||||||
.remove = led_bl_remove,
|
.remove_new = led_bl_remove,
|
||||||
};
|
};
|
||||||
|
|
||||||
module_platform_driver(led_bl_driver);
|
module_platform_driver(led_bl_driver);
|
||||||
|
|||||||
@@ -271,7 +271,7 @@ config XEN_PRIVCMD
|
|||||||
|
|
||||||
config XEN_ACPI_PROCESSOR
|
config XEN_ACPI_PROCESSOR
|
||||||
tristate "Xen ACPI processor"
|
tristate "Xen ACPI processor"
|
||||||
depends on XEN && XEN_PV_DOM0 && X86 && ACPI_PROCESSOR && CPU_FREQ
|
depends on XEN && XEN_DOM0 && X86 && ACPI_PROCESSOR && CPU_FREQ
|
||||||
default m
|
default m
|
||||||
help
|
help
|
||||||
This ACPI processor uploads Power Management information to the Xen
|
This ACPI processor uploads Power Management information to the Xen
|
||||||
|
|||||||
@@ -2224,15 +2224,20 @@ static void btrfs_punch_hole_lock_range(struct inode *inode,
|
|||||||
* will always return true.
|
* will always return true.
|
||||||
* So here we need to do extra page alignment for
|
* So here we need to do extra page alignment for
|
||||||
* filemap_range_has_page().
|
* filemap_range_has_page().
|
||||||
|
*
|
||||||
|
* And do not decrease page_lockend right now, as it can be 0.
|
||||||
*/
|
*/
|
||||||
const u64 page_lockstart = round_up(lockstart, PAGE_SIZE);
|
const u64 page_lockstart = round_up(lockstart, PAGE_SIZE);
|
||||||
const u64 page_lockend = round_down(lockend + 1, PAGE_SIZE) - 1;
|
const u64 page_lockend = round_down(lockend + 1, PAGE_SIZE);
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
truncate_pagecache_range(inode, lockstart, lockend);
|
truncate_pagecache_range(inode, lockstart, lockend);
|
||||||
|
|
||||||
lock_extent(&BTRFS_I(inode)->io_tree, lockstart, lockend,
|
lock_extent(&BTRFS_I(inode)->io_tree, lockstart, lockend,
|
||||||
cached_state);
|
cached_state);
|
||||||
|
/* The same page or adjacent pages. */
|
||||||
|
if (page_lockend <= page_lockstart)
|
||||||
|
break;
|
||||||
/*
|
/*
|
||||||
* We can't have ordered extents in the range, nor dirty/writeback
|
* We can't have ordered extents in the range, nor dirty/writeback
|
||||||
* pages, because we have locked the inode's VFS lock in exclusive
|
* pages, because we have locked the inode's VFS lock in exclusive
|
||||||
@@ -2244,7 +2249,7 @@ static void btrfs_punch_hole_lock_range(struct inode *inode,
|
|||||||
* we do, unlock the range and retry.
|
* we do, unlock the range and retry.
|
||||||
*/
|
*/
|
||||||
if (!filemap_range_has_page(inode->i_mapping, page_lockstart,
|
if (!filemap_range_has_page(inode->i_mapping, page_lockstart,
|
||||||
page_lockend))
|
page_lockend - 1))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
unlock_extent(&BTRFS_I(inode)->io_tree, lockstart, lockend,
|
unlock_extent(&BTRFS_I(inode)->io_tree, lockstart, lockend,
|
||||||
|
|||||||
@@ -351,10 +351,9 @@ int ext4_check_blockref(const char *function, unsigned int line,
|
|||||||
{
|
{
|
||||||
__le32 *bref = p;
|
__le32 *bref = p;
|
||||||
unsigned int blk;
|
unsigned int blk;
|
||||||
|
journal_t *journal = EXT4_SB(inode->i_sb)->s_journal;
|
||||||
|
|
||||||
if (ext4_has_feature_journal(inode->i_sb) &&
|
if (journal && inode == journal->j_inode)
|
||||||
(inode->i_ino ==
|
|
||||||
le32_to_cpu(EXT4_SB(inode->i_sb)->s_es->s_journal_inum)))
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
while (bref < p+max) {
|
while (bref < p+max) {
|
||||||
|
|||||||
@@ -406,10 +406,11 @@ static int __check_block_validity(struct inode *inode, const char *func,
|
|||||||
unsigned int line,
|
unsigned int line,
|
||||||
struct ext4_map_blocks *map)
|
struct ext4_map_blocks *map)
|
||||||
{
|
{
|
||||||
if (ext4_has_feature_journal(inode->i_sb) &&
|
journal_t *journal = EXT4_SB(inode->i_sb)->s_journal;
|
||||||
(inode->i_ino ==
|
|
||||||
le32_to_cpu(EXT4_SB(inode->i_sb)->s_es->s_journal_inum)))
|
if (journal && inode == journal->j_inode)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (!ext4_inode_block_valid(inode, map->m_pblk, map->m_len)) {
|
if (!ext4_inode_block_valid(inode, map->m_pblk, map->m_len)) {
|
||||||
ext4_error_inode(inode, func, line, map->m_pblk,
|
ext4_error_inode(inode, func, line, map->m_pblk,
|
||||||
"lblock %lu mapped to illegal pblock %llu "
|
"lblock %lu mapped to illegal pblock %llu "
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ struct dinode {
|
|||||||
#define di_gengen u._file._u1._imap._gengen
|
#define di_gengen u._file._u1._imap._gengen
|
||||||
|
|
||||||
union {
|
union {
|
||||||
xtpage_t _xtroot;
|
xtroot_t _xtroot;
|
||||||
struct {
|
struct {
|
||||||
u8 unused[16]; /* 16: */
|
u8 unused[16]; /* 16: */
|
||||||
dxd_t _dxd; /* 16: */
|
dxd_t _dxd; /* 16: */
|
||||||
|
|||||||
@@ -673,7 +673,7 @@ int diWrite(tid_t tid, struct inode *ip)
|
|||||||
* This is the special xtree inside the directory for storing
|
* This is the special xtree inside the directory for storing
|
||||||
* the directory table
|
* the directory table
|
||||||
*/
|
*/
|
||||||
xtpage_t *p, *xp;
|
xtroot_t *p, *xp;
|
||||||
xad_t *xad;
|
xad_t *xad;
|
||||||
|
|
||||||
jfs_ip->xtlid = 0;
|
jfs_ip->xtlid = 0;
|
||||||
@@ -687,7 +687,7 @@ int diWrite(tid_t tid, struct inode *ip)
|
|||||||
* copy xtree root from inode to dinode:
|
* copy xtree root from inode to dinode:
|
||||||
*/
|
*/
|
||||||
p = &jfs_ip->i_xtroot;
|
p = &jfs_ip->i_xtroot;
|
||||||
xp = (xtpage_t *) &dp->di_dirtable;
|
xp = (xtroot_t *) &dp->di_dirtable;
|
||||||
lv = ilinelock->lv;
|
lv = ilinelock->lv;
|
||||||
for (n = 0; n < ilinelock->index; n++, lv++) {
|
for (n = 0; n < ilinelock->index; n++, lv++) {
|
||||||
memcpy(&xp->xad[lv->offset], &p->xad[lv->offset],
|
memcpy(&xp->xad[lv->offset], &p->xad[lv->offset],
|
||||||
@@ -716,7 +716,7 @@ int diWrite(tid_t tid, struct inode *ip)
|
|||||||
* regular file: 16 byte (XAD slot) granularity
|
* regular file: 16 byte (XAD slot) granularity
|
||||||
*/
|
*/
|
||||||
if (type & tlckXTREE) {
|
if (type & tlckXTREE) {
|
||||||
xtpage_t *p, *xp;
|
xtroot_t *p, *xp;
|
||||||
xad_t *xad;
|
xad_t *xad;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user