Merge branch 'linux-4.14.y' of https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux into mcqueen
* 'linux-4.14.y' of https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux: (211 commits) Linux 4.14.264 drm/vmwgfx: Fix stale file descriptors on failed usercopy can: bcm: fix UAF of bcm op drm/i915: Flush TLBs before releasing backing store Linux 4.14.263 NFSv4: Initialise connection to the server in nfs4_alloc_client() gianfar: fix jumbo packets+napi+rx overrun crash gianfar: simplify FCS handling and fix memory leak fuse: fix live lock in fuse_iget() fuse: fix bad inode drm/ttm/nouveau: don't call tt destroy callback on alloc failure. mips,s390,sh,sparc: gup: Work around the "COW can break either way" issue lib82596: Fix IRQ check in sni_82596_probe scripts/dtc: dtx_diff: remove broken example from help text bcmgenet: add WOL IRQ check net_sched: restore "mpu xxx" handling dmaengine: at_xdmac: Fix at_xdmac_lld struct definition dmaengine: at_xdmac: Fix lld view setting dmaengine: at_xdmac: Print debug message after realeasing the lock dmaengine: at_xdmac: Don't start transactions at tx_submit level ... Signed-off-by: SagarMakhar <sagarmakhar@gmail.com>
This commit is contained in:
@@ -468,7 +468,7 @@ Spectre variant 2
|
||||
before invoking any firmware code to prevent Spectre variant 2 exploits
|
||||
using the firmware.
|
||||
|
||||
Using kernel address space randomization (CONFIG_RANDOMIZE_SLAB=y
|
||||
Using kernel address space randomization (CONFIG_RANDOMIZE_BASE=y
|
||||
and CONFIG_SLAB_FREELIST_RANDOM=y in the kernel configuration) makes
|
||||
attacks on the kernel generally more difficult.
|
||||
|
||||
|
||||
2
Makefile
2
Makefile
@@ -1,7 +1,7 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
VERSION = 4
|
||||
PATCHLEVEL = 14
|
||||
SUBLEVEL = 212
|
||||
SUBLEVEL = 264
|
||||
EXTRAVERSION =
|
||||
NAME = Petit Gorille
|
||||
|
||||
|
||||
@@ -351,7 +351,7 @@
|
||||
|
||||
ccplex@e000000 {
|
||||
compatible = "nvidia,tegra186-ccplex-cluster";
|
||||
reg = <0x0 0x0e000000 0x0 0x3fffff>;
|
||||
reg = <0x0 0x0e000000 0x0 0x400000>;
|
||||
|
||||
nvidia,bpmp = <&bpmp>;
|
||||
};
|
||||
|
||||
@@ -26,8 +26,8 @@
|
||||
#size-cells = <2>;
|
||||
|
||||
aliases {
|
||||
sdhc1 = &sdhc_1; /* SDC1 eMMC slot */
|
||||
sdhc2 = &sdhc_2; /* SDC2 SD card slot */
|
||||
mmc0 = &sdhc_1; /* SDC1 eMMC slot */
|
||||
mmc1 = &sdhc_2; /* SDC2 SD card slot */
|
||||
};
|
||||
|
||||
chosen { };
|
||||
|
||||
@@ -337,6 +337,18 @@ void clk_disable(struct clk *clk)
|
||||
|
||||
EXPORT_SYMBOL(clk_disable);
|
||||
|
||||
struct clk *clk_get_parent(struct clk *clk)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(clk_get_parent);
|
||||
|
||||
int clk_set_parent(struct clk *clk, struct clk *parent)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(clk_set_parent);
|
||||
|
||||
unsigned long clk_get_rate(struct clk *clk)
|
||||
{
|
||||
if (!clk)
|
||||
|
||||
@@ -328,6 +328,7 @@ static int __init octeon_ehci_device_init(void)
|
||||
|
||||
pd->dev.platform_data = &octeon_ehci_pdata;
|
||||
octeon_ehci_hw_start(&pd->dev);
|
||||
put_device(&pd->dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -391,6 +392,7 @@ static int __init octeon_ohci_device_init(void)
|
||||
|
||||
pd->dev.platform_data = &octeon_ohci_pdata;
|
||||
octeon_ohci_hw_start(&pd->dev);
|
||||
put_device(&pd->dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -543,6 +543,7 @@ static int __init dwc3_octeon_device_init(void)
|
||||
devm_iounmap(&pdev->dev, base);
|
||||
devm_release_mem_region(&pdev->dev, res->start,
|
||||
resource_size(res));
|
||||
put_device(&pdev->dev);
|
||||
}
|
||||
} while (node != NULL);
|
||||
|
||||
|
||||
@@ -315,7 +315,7 @@ enum cvmx_chip_types_enum {
|
||||
|
||||
/* Functions to return string based on type */
|
||||
#define ENUM_BRD_TYPE_CASE(x) \
|
||||
case x: return(#x + 16); /* Skip CVMX_BOARD_TYPE_ */
|
||||
case x: return (&#x[16]); /* Skip CVMX_BOARD_TYPE_ */
|
||||
static inline const char *cvmx_board_type_to_string(enum
|
||||
cvmx_board_types_enum type)
|
||||
{
|
||||
@@ -404,7 +404,7 @@ static inline const char *cvmx_board_type_to_string(enum
|
||||
}
|
||||
|
||||
#define ENUM_CHIP_TYPE_CASE(x) \
|
||||
case x: return(#x + 15); /* Skip CVMX_CHIP_TYPE */
|
||||
case x: return (&#x[15]); /* Skip CVMX_CHIP_TYPE */
|
||||
static inline const char *cvmx_chip_type_to_string(enum
|
||||
cvmx_chip_types_enum type)
|
||||
{
|
||||
|
||||
@@ -160,6 +160,18 @@ void clk_deactivate(struct clk *clk)
|
||||
}
|
||||
EXPORT_SYMBOL(clk_deactivate);
|
||||
|
||||
struct clk *clk_get_parent(struct clk *clk)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(clk_get_parent);
|
||||
|
||||
int clk_set_parent(struct clk *clk, struct clk *parent)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(clk_set_parent);
|
||||
|
||||
static inline u32 get_counter_resolution(void)
|
||||
{
|
||||
u32 res;
|
||||
|
||||
@@ -272,7 +272,14 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write,
|
||||
next = pgd_addr_end(addr, end);
|
||||
if (pgd_none(pgd))
|
||||
goto slow;
|
||||
if (!gup_pud_range(pgd, addr, next, write, pages, &nr))
|
||||
/*
|
||||
* The FAST_GUP case requires FOLL_WRITE even for pure reads,
|
||||
* because get_user_pages() may need to cause an early COW in
|
||||
* order to avoid confusing the normal COW routines. So only
|
||||
* targets that are already writable are safe to do by just
|
||||
* looking at the page tables.
|
||||
*/
|
||||
if (!gup_pud_range(pgd, addr, next, 1, pages, &nr))
|
||||
goto slow;
|
||||
} while (pgdp++, addr = next, addr != end);
|
||||
local_irq_enable();
|
||||
|
||||
@@ -795,7 +795,7 @@ void notrace handle_interruption(int code, struct pt_regs *regs)
|
||||
* unless pagefault_disable() was called before.
|
||||
*/
|
||||
|
||||
if (fault_space == 0 && !faulthandler_disabled())
|
||||
if (faulthandler_disabled() || fault_space == 0)
|
||||
{
|
||||
/* Clean up and return if in exception table. */
|
||||
if (fixup_exception(regs))
|
||||
|
||||
@@ -78,6 +78,7 @@ fman0: fman@400000 {
|
||||
#size-cells = <0>;
|
||||
compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
|
||||
reg = <0xfc000 0x1000>;
|
||||
fsl,erratum-a009885;
|
||||
};
|
||||
|
||||
xmdio0: mdio@fd000 {
|
||||
@@ -85,6 +86,7 @@ fman0: fman@400000 {
|
||||
#size-cells = <0>;
|
||||
compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
|
||||
reg = <0xfd000 0x1000>;
|
||||
fsl,erratum-a009885;
|
||||
};
|
||||
|
||||
ptp_timer0: ptp-timer@fe000 {
|
||||
|
||||
@@ -258,8 +258,10 @@ int __init btext_find_display(int allow_nonstdout)
|
||||
rc = btext_initialize(np);
|
||||
printk("result: %d\n", rc);
|
||||
}
|
||||
if (rc == 0)
|
||||
if (rc == 0) {
|
||||
of_node_put(np);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -2774,7 +2774,7 @@ static void __init fixup_device_tree_efika_add_phy(void)
|
||||
|
||||
/* Check if the phy-handle property exists - bail if it does */
|
||||
rv = prom_getprop(node, "phy-handle", prop, sizeof(prop));
|
||||
if (!rv)
|
||||
if (rv <= 0)
|
||||
return;
|
||||
|
||||
/*
|
||||
|
||||
@@ -1009,10 +1009,12 @@ void start_secondary(void *unused)
|
||||
BUG();
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PROFILING
|
||||
int setup_profiling_timer(unsigned int multiplier)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SCHED_SMT
|
||||
/* cpumask of CPUs with asymetric SMT dependancy */
|
||||
|
||||
@@ -106,6 +106,10 @@ static void set_cpumask_stuck(const struct cpumask *cpumask, u64 tb)
|
||||
{
|
||||
cpumask_or(&wd_smp_cpus_stuck, &wd_smp_cpus_stuck, cpumask);
|
||||
cpumask_andnot(&wd_smp_cpus_pending, &wd_smp_cpus_pending, cpumask);
|
||||
/*
|
||||
* See wd_smp_clear_cpu_pending()
|
||||
*/
|
||||
smp_mb();
|
||||
if (cpumask_empty(&wd_smp_cpus_pending)) {
|
||||
wd_smp_last_reset_tb = tb;
|
||||
cpumask_andnot(&wd_smp_cpus_pending,
|
||||
@@ -177,13 +181,44 @@ static void wd_smp_clear_cpu_pending(int cpu, u64 tb)
|
||||
wd_smp_lock(&flags);
|
||||
cpumask_clear_cpu(cpu, &wd_smp_cpus_stuck);
|
||||
wd_smp_unlock(&flags);
|
||||
} else {
|
||||
/*
|
||||
* The last CPU to clear pending should have reset the
|
||||
* watchdog so we generally should not find it empty
|
||||
* here if our CPU was clear. However it could happen
|
||||
* due to a rare race with another CPU taking the
|
||||
* last CPU out of the mask concurrently.
|
||||
*
|
||||
* We can't add a warning for it. But just in case
|
||||
* there is a problem with the watchdog that is causing
|
||||
* the mask to not be reset, try to kick it along here.
|
||||
*/
|
||||
if (unlikely(cpumask_empty(&wd_smp_cpus_pending)))
|
||||
goto none_pending;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
cpumask_clear_cpu(cpu, &wd_smp_cpus_pending);
|
||||
|
||||
/*
|
||||
* Order the store to clear pending with the load(s) to check all
|
||||
* words in the pending mask to check they are all empty. This orders
|
||||
* with the same barrier on another CPU. This prevents two CPUs
|
||||
* clearing the last 2 pending bits, but neither seeing the other's
|
||||
* store when checking if the mask is empty, and missing an empty
|
||||
* mask, which ends with a false positive.
|
||||
*/
|
||||
smp_mb();
|
||||
if (cpumask_empty(&wd_smp_cpus_pending)) {
|
||||
unsigned long flags;
|
||||
|
||||
none_pending:
|
||||
/*
|
||||
* Double check under lock because more than one CPU could see
|
||||
* a clear mask with the lockless check after clearing their
|
||||
* pending bits.
|
||||
*/
|
||||
wd_smp_lock(&flags);
|
||||
if (cpumask_empty(&wd_smp_cpus_pending)) {
|
||||
wd_smp_last_reset_tb = tb;
|
||||
@@ -276,8 +311,12 @@ void arch_touch_nmi_watchdog(void)
|
||||
{
|
||||
unsigned long ticks = tb_ticks_per_usec * wd_timer_period_ms * 1000;
|
||||
int cpu = smp_processor_id();
|
||||
u64 tb = get_tb();
|
||||
u64 tb;
|
||||
|
||||
if (!cpumask_test_cpu(cpu, &watchdog_cpumask))
|
||||
return;
|
||||
|
||||
tb = get_tb();
|
||||
if (tb - per_cpu(wd_timer_tb, cpu) >= ticks) {
|
||||
per_cpu(wd_timer_tb, cpu) = tb;
|
||||
wd_smp_clear_cpu_pending(cpu, tb);
|
||||
|
||||
@@ -1088,6 +1088,7 @@ static int __init cell_iommu_fixed_mapping_init(void)
|
||||
if (hbase < dbase || (hend > (dbase + dsize))) {
|
||||
pr_debug("iommu: hash window doesn't fit in"
|
||||
"real DMA window\n");
|
||||
of_node_put(np);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,6 +90,7 @@ static int cbe_system_reset_exception(struct pt_regs *regs)
|
||||
switch (regs->msr & SRR1_WAKEMASK) {
|
||||
case SRR1_WAKEDEC:
|
||||
set_dec(1);
|
||||
break;
|
||||
case SRR1_WAKEEE:
|
||||
/*
|
||||
* Handle these when interrupts get re-enabled and we take
|
||||
|
||||
@@ -220,6 +220,7 @@ void hlwd_pic_probe(void)
|
||||
irq_set_chained_handler(cascade_virq,
|
||||
hlwd_pic_irq_cascade);
|
||||
hlwd_irq_host = host;
|
||||
of_node_put(np);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -400,6 +400,7 @@ void __init opal_lpc_init(void)
|
||||
if (!of_get_property(np, "primary", NULL))
|
||||
continue;
|
||||
opal_lpc_chip_id = of_get_ibm_chip_id(np);
|
||||
of_node_put(np);
|
||||
break;
|
||||
}
|
||||
if (opal_lpc_chip_id < 0)
|
||||
|
||||
@@ -285,7 +285,14 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write,
|
||||
|
||||
might_sleep();
|
||||
start &= PAGE_MASK;
|
||||
nr = __get_user_pages_fast(start, nr_pages, write, pages);
|
||||
/*
|
||||
* The FAST_GUP case requires FOLL_WRITE even for pure reads,
|
||||
* because get_user_pages() may need to cause an early COW in
|
||||
* order to avoid confusing the normal COW routines. So only
|
||||
* targets that are already writable are safe to do by just
|
||||
* looking at the page tables.
|
||||
*/
|
||||
nr = __get_user_pages_fast(start, nr_pages, 1, pages);
|
||||
if (nr == nr_pages)
|
||||
return nr;
|
||||
|
||||
|
||||
@@ -240,7 +240,14 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write,
|
||||
next = pgd_addr_end(addr, end);
|
||||
if (pgd_none(pgd))
|
||||
goto slow;
|
||||
if (!gup_pud_range(pgd, addr, next, write, pages, &nr))
|
||||
/*
|
||||
* The FAST_GUP case requires FOLL_WRITE even for pure reads,
|
||||
* because get_user_pages() may need to cause an early COW in
|
||||
* order to avoid confusing the normal COW routines. So only
|
||||
* targets that are already writable are safe to do by just
|
||||
* looking at the page tables.
|
||||
*/
|
||||
if (!gup_pud_range(pgd, addr, next, 1, pages, &nr))
|
||||
goto slow;
|
||||
} while (pgdp++, addr = next, addr != end);
|
||||
local_irq_enable();
|
||||
|
||||
@@ -262,7 +262,14 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write,
|
||||
next = pgd_addr_end(addr, end);
|
||||
if (pgd_none(pgd))
|
||||
goto slow;
|
||||
if (!gup_pud_range(pgd, addr, next, write, pages, &nr))
|
||||
/*
|
||||
* The FAST_GUP case requires FOLL_WRITE even for pure reads,
|
||||
* because get_user_pages() may need to cause an early COW in
|
||||
* order to avoid confusing the normal COW routines. So only
|
||||
* targets that are already writable are safe to do by just
|
||||
* looking at the page tables.
|
||||
*/
|
||||
if (!gup_pud_range(pgd, addr, next, 1, pages, &nr))
|
||||
goto slow;
|
||||
} while (pgdp++, addr = next, addr != end);
|
||||
|
||||
|
||||
@@ -16,8 +16,8 @@ extern int restore_fp_registers(int pid, unsigned long *fp_regs);
|
||||
extern int save_fpx_registers(int pid, unsigned long *fp_regs);
|
||||
extern int restore_fpx_registers(int pid, unsigned long *fp_regs);
|
||||
extern int save_registers(int pid, struct uml_pt_regs *regs);
|
||||
extern int restore_registers(int pid, struct uml_pt_regs *regs);
|
||||
extern int init_registers(int pid);
|
||||
extern int restore_pid_registers(int pid, struct uml_pt_regs *regs);
|
||||
extern int init_pid_registers(int pid);
|
||||
extern void get_safe_registers(unsigned long *regs, unsigned long *fp_regs);
|
||||
extern unsigned long get_thread_reg(int reg, jmp_buf *buf);
|
||||
extern int get_fp_registers(int pid, unsigned long *regs);
|
||||
|
||||
@@ -21,7 +21,7 @@ int save_registers(int pid, struct uml_pt_regs *regs)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int restore_registers(int pid, struct uml_pt_regs *regs)
|
||||
int restore_pid_registers(int pid, struct uml_pt_regs *regs)
|
||||
{
|
||||
int err;
|
||||
|
||||
@@ -36,7 +36,7 @@ int restore_registers(int pid, struct uml_pt_regs *regs)
|
||||
static unsigned long exec_regs[MAX_REG_NR];
|
||||
static unsigned long exec_fp_regs[FP_SIZE];
|
||||
|
||||
int init_registers(int pid)
|
||||
int init_pid_registers(int pid)
|
||||
{
|
||||
int err;
|
||||
|
||||
|
||||
@@ -336,7 +336,7 @@ void __init os_early_checks(void)
|
||||
check_tmpexec();
|
||||
|
||||
pid = start_ptraced_child();
|
||||
if (init_registers(pid))
|
||||
if (init_pid_registers(pid))
|
||||
fatal("Failed to initialize default registers");
|
||||
stop_ptraced_child(pid, 1, 1);
|
||||
}
|
||||
|
||||
@@ -354,7 +354,7 @@ static ssize_t flags_write(struct file *filp, const char __user *ubuf,
|
||||
char buf[MAX_FLAG_OPT_SIZE], *__buf;
|
||||
int err;
|
||||
|
||||
if (cnt > MAX_FLAG_OPT_SIZE)
|
||||
if (!cnt || cnt > MAX_FLAG_OPT_SIZE)
|
||||
return -EINVAL;
|
||||
|
||||
if (copy_from_user(&buf, ubuf, cnt))
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <linux/uaccess.h>
|
||||
#include <asm/prctl.h> /* XXX This should get the constants from libc */
|
||||
#include <os.h>
|
||||
#include <registers.h>
|
||||
|
||||
long arch_prctl(struct task_struct *task, int option,
|
||||
unsigned long __user *arg2)
|
||||
@@ -35,7 +36,7 @@ long arch_prctl(struct task_struct *task, int option,
|
||||
switch (option) {
|
||||
case ARCH_SET_FS:
|
||||
case ARCH_SET_GS:
|
||||
ret = restore_registers(pid, ¤t->thread.regs.regs);
|
||||
ret = restore_pid_registers(pid, ¤t->thread.regs.regs);
|
||||
if (ret)
|
||||
return ret;
|
||||
break;
|
||||
|
||||
@@ -1041,7 +1041,8 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state)
|
||||
(walk_state, return_desc,
|
||||
&temp_desc);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
goto cleanup;
|
||||
return_ACPI_STATUS
|
||||
(status);
|
||||
}
|
||||
|
||||
return_desc = temp_desc;
|
||||
|
||||
@@ -138,7 +138,9 @@ acpi_status acpi_hw_extended_sleep(u8 sleep_state)
|
||||
|
||||
/* Flush caches, as per ACPI specification */
|
||||
|
||||
ACPI_FLUSH_CPU_CACHE();
|
||||
if (sleep_state < ACPI_STATE_S4) {
|
||||
ACPI_FLUSH_CPU_CACHE();
|
||||
}
|
||||
|
||||
status = acpi_os_enter_sleep(sleep_state, sleep_control, 0);
|
||||
if (status == AE_CTRL_TERMINATE) {
|
||||
|
||||
@@ -149,7 +149,9 @@ acpi_status acpi_hw_legacy_sleep(u8 sleep_state)
|
||||
|
||||
/* Flush caches, as per ACPI specification */
|
||||
|
||||
ACPI_FLUSH_CPU_CACHE();
|
||||
if (sleep_state < ACPI_STATE_S4) {
|
||||
ACPI_FLUSH_CPU_CACHE();
|
||||
}
|
||||
|
||||
status = acpi_os_enter_sleep(sleep_state, pm1a_control, pm1b_control);
|
||||
if (status == AE_CTRL_TERMINATE) {
|
||||
|
||||
@@ -223,8 +223,6 @@ acpi_status acpi_enter_sleep_state_s4bios(void)
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
ACPI_FLUSH_CPU_CACHE();
|
||||
|
||||
status = acpi_hw_write_port(acpi_gbl_FADT.smi_command,
|
||||
(u32)acpi_gbl_FADT.s4_bios_request, 8);
|
||||
|
||||
|
||||
@@ -442,6 +442,7 @@ acpi_ut_update_ref_count(union acpi_operand_object *object, u32 action)
|
||||
ACPI_WARNING((AE_INFO,
|
||||
"Obj %p, Reference Count is already zero, cannot decrement\n",
|
||||
object));
|
||||
return;
|
||||
}
|
||||
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
|
||||
|
||||
@@ -994,7 +994,7 @@ static DECLARE_DELAYED_WORK(fd_timer, fd_timer_workfn);
|
||||
static void cancel_activity(void)
|
||||
{
|
||||
do_floppy = NULL;
|
||||
cancel_delayed_work_sync(&fd_timer);
|
||||
cancel_delayed_work(&fd_timer);
|
||||
cancel_work_sync(&floppy_work);
|
||||
}
|
||||
|
||||
@@ -3118,6 +3118,8 @@ static void raw_cmd_free(struct floppy_raw_cmd **ptr)
|
||||
}
|
||||
}
|
||||
|
||||
#define MAX_LEN (1UL << MAX_ORDER << PAGE_SHIFT)
|
||||
|
||||
static int raw_cmd_copyin(int cmd, void __user *param,
|
||||
struct floppy_raw_cmd **rcmd)
|
||||
{
|
||||
@@ -3155,7 +3157,7 @@ loop:
|
||||
ptr->resultcode = 0;
|
||||
|
||||
if (ptr->flags & (FD_RAW_READ | FD_RAW_WRITE)) {
|
||||
if (ptr->length <= 0)
|
||||
if (ptr->length <= 0 || ptr->length >= MAX_LEN)
|
||||
return -EINVAL;
|
||||
ptr->kernel_data = (char *)fd_dma_mem_alloc(ptr->length);
|
||||
fallback_on_nodma_alloc(&ptr->kernel_data, ptr->length);
|
||||
|
||||
@@ -644,6 +644,9 @@ static int bfusb_probe(struct usb_interface *intf, const struct usb_device_id *i
|
||||
data->bulk_out_ep = bulk_out_ep->desc.bEndpointAddress;
|
||||
data->bulk_pkt_size = le16_to_cpu(bulk_out_ep->desc.wMaxPacketSize);
|
||||
|
||||
if (!data->bulk_pkt_size)
|
||||
goto done;
|
||||
|
||||
rwlock_init(&data->lock);
|
||||
|
||||
data->reassembly = NULL;
|
||||
|
||||
@@ -2548,11 +2548,9 @@ static const struct qca_device_info qca_devices_table[] = {
|
||||
{ 0x00000302, 28, 4, 18 }, /* Rome 3.2 */
|
||||
};
|
||||
|
||||
static int btusb_qca_send_vendor_req(struct hci_dev *hdev, u8 request,
|
||||
static int btusb_qca_send_vendor_req(struct usb_device *udev, u8 request,
|
||||
void *data, u16 size)
|
||||
{
|
||||
struct btusb_data *btdata = hci_get_drvdata(hdev);
|
||||
struct usb_device *udev = btdata->udev;
|
||||
int pipe, err;
|
||||
u8 *buf;
|
||||
|
||||
@@ -2567,7 +2565,7 @@ static int btusb_qca_send_vendor_req(struct hci_dev *hdev, u8 request,
|
||||
err = usb_control_msg(udev, pipe, request, USB_TYPE_VENDOR | USB_DIR_IN,
|
||||
0, 0, buf, size, USB_CTRL_SET_TIMEOUT);
|
||||
if (err < 0) {
|
||||
BT_ERR("%s: Failed to access otp area (%d)", hdev->name, err);
|
||||
dev_err(&udev->dev, "Failed to access otp area (%d)", err);
|
||||
goto done;
|
||||
}
|
||||
|
||||
@@ -2718,20 +2716,38 @@ static int btusb_setup_qca_load_nvm(struct hci_dev *hdev,
|
||||
return err;
|
||||
}
|
||||
|
||||
/* identify the ROM version and check whether patches are needed */
|
||||
static bool btusb_qca_need_patch(struct usb_device *udev)
|
||||
{
|
||||
struct qca_version ver;
|
||||
|
||||
if (btusb_qca_send_vendor_req(udev, QCA_GET_TARGET_VERSION, &ver,
|
||||
sizeof(ver)) < 0)
|
||||
return false;
|
||||
/* only low ROM versions need patches */
|
||||
return !(le32_to_cpu(ver.rom_version) & ~0xffffU);
|
||||
}
|
||||
|
||||
static int btusb_setup_qca(struct hci_dev *hdev)
|
||||
{
|
||||
struct btusb_data *btdata = hci_get_drvdata(hdev);
|
||||
struct usb_device *udev = btdata->udev;
|
||||
const struct qca_device_info *info = NULL;
|
||||
struct qca_version ver;
|
||||
u32 ver_rom;
|
||||
u8 status;
|
||||
int i, err;
|
||||
|
||||
err = btusb_qca_send_vendor_req(hdev, QCA_GET_TARGET_VERSION, &ver,
|
||||
err = btusb_qca_send_vendor_req(udev, QCA_GET_TARGET_VERSION, &ver,
|
||||
sizeof(ver));
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
ver_rom = le32_to_cpu(ver.rom_version);
|
||||
/* Don't care about high ROM versions */
|
||||
if (ver_rom & ~0xffffU)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(qca_devices_table); i++) {
|
||||
if (ver_rom == qca_devices_table[i].rom_version)
|
||||
info = &qca_devices_table[i];
|
||||
@@ -2742,7 +2758,7 @@ static int btusb_setup_qca(struct hci_dev *hdev)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
err = btusb_qca_send_vendor_req(hdev, QCA_CHECK_STATUS, &status,
|
||||
err = btusb_qca_send_vendor_req(udev, QCA_CHECK_STATUS, &status,
|
||||
sizeof(status));
|
||||
if (err < 0)
|
||||
return err;
|
||||
@@ -2969,7 +2985,8 @@ static int btusb_probe(struct usb_interface *intf,
|
||||
/* Old firmware would otherwise let ath3k driver load
|
||||
* patch and sysconfig files
|
||||
*/
|
||||
if (le16_to_cpu(udev->descriptor.bcdDevice) <= 0x0001)
|
||||
if (le16_to_cpu(udev->descriptor.bcdDevice) <= 0x0001 &&
|
||||
!btusb_qca_need_patch(udev))
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
@@ -3131,6 +3148,7 @@ static int btusb_probe(struct usb_interface *intf,
|
||||
}
|
||||
|
||||
if (id->driver_info & BTUSB_ATH3012) {
|
||||
data->setup_on_usb = btusb_setup_qca;
|
||||
hdev->set_bdaddr = btusb_set_bdaddr_ath3012;
|
||||
set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks);
|
||||
set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks);
|
||||
|
||||
@@ -68,7 +68,7 @@ typedef struct {
|
||||
unsigned char ClockControl:1; /* RW: Clock control: 0=normal, 1=stop 3780i clocks */
|
||||
unsigned char SoftReset:1; /* RW: Soft reset 0=normal, 1=soft reset active */
|
||||
unsigned char ConfigMode:1; /* RW: Configuration mode, 0=normal, 1=config mode */
|
||||
unsigned char Reserved:5; /* 0: Reserved */
|
||||
unsigned short Reserved:13; /* 0: Reserved */
|
||||
} DSP_ISA_SLAVE_CONTROL;
|
||||
|
||||
|
||||
|
||||
@@ -812,8 +812,8 @@ static void do_numa_crng_init(struct work_struct *work)
|
||||
crng_initialize(crng);
|
||||
pool[i] = crng;
|
||||
}
|
||||
mb();
|
||||
if (cmpxchg(&crng_node_pool, NULL, pool)) {
|
||||
/* pairs with READ_ONCE() in select_crng() */
|
||||
if (cmpxchg_release(&crng_node_pool, NULL, pool) != NULL) {
|
||||
for_each_node(i)
|
||||
kfree(pool[i]);
|
||||
kfree(pool);
|
||||
@@ -826,8 +826,26 @@ static void numa_crng_init(void)
|
||||
{
|
||||
schedule_work(&numa_crng_init_work);
|
||||
}
|
||||
|
||||
static struct crng_state *select_crng(void)
|
||||
{
|
||||
struct crng_state **pool;
|
||||
int nid = numa_node_id();
|
||||
|
||||
/* pairs with cmpxchg_release() in do_numa_crng_init() */
|
||||
pool = READ_ONCE(crng_node_pool);
|
||||
if (pool && pool[nid])
|
||||
return pool[nid];
|
||||
|
||||
return &primary_crng;
|
||||
}
|
||||
#else
|
||||
static void numa_crng_init(void) {}
|
||||
|
||||
static struct crng_state *select_crng(void)
|
||||
{
|
||||
return &primary_crng;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -932,7 +950,7 @@ static void crng_reseed(struct crng_state *crng, struct entropy_store *r)
|
||||
crng->state[i+4] ^= buf.key[i] ^ rv;
|
||||
}
|
||||
memzero_explicit(&buf, sizeof(buf));
|
||||
crng->init_time = jiffies;
|
||||
WRITE_ONCE(crng->init_time, jiffies);
|
||||
spin_unlock_irqrestore(&crng->lock, flags);
|
||||
if (crng == &primary_crng && crng_init < 2) {
|
||||
invalidate_batched_entropy();
|
||||
@@ -959,12 +977,15 @@ static void crng_reseed(struct crng_state *crng, struct entropy_store *r)
|
||||
static void _extract_crng(struct crng_state *crng,
|
||||
__u8 out[CHACHA_BLOCK_SIZE])
|
||||
{
|
||||
unsigned long v, flags;
|
||||
unsigned long v, flags, init_time;
|
||||
|
||||
if (crng_ready() &&
|
||||
(time_after(crng_global_init_time, crng->init_time) ||
|
||||
time_after(jiffies, crng->init_time + CRNG_RESEED_INTERVAL)))
|
||||
crng_reseed(crng, crng == &primary_crng ? &input_pool : NULL);
|
||||
if (crng_ready()) {
|
||||
init_time = READ_ONCE(crng->init_time);
|
||||
if (time_after(READ_ONCE(crng_global_init_time), init_time) ||
|
||||
time_after(jiffies, init_time + CRNG_RESEED_INTERVAL))
|
||||
crng_reseed(crng, crng == &primary_crng ?
|
||||
&input_pool : NULL);
|
||||
}
|
||||
spin_lock_irqsave(&crng->lock, flags);
|
||||
if (arch_get_random_long(&v))
|
||||
crng->state[14] ^= v;
|
||||
@@ -976,15 +997,7 @@ static void _extract_crng(struct crng_state *crng,
|
||||
|
||||
static void extract_crng(__u8 out[CHACHA_BLOCK_SIZE])
|
||||
{
|
||||
struct crng_state *crng = NULL;
|
||||
|
||||
#ifdef CONFIG_NUMA
|
||||
if (crng_node_pool)
|
||||
crng = crng_node_pool[numa_node_id()];
|
||||
if (crng == NULL)
|
||||
#endif
|
||||
crng = &primary_crng;
|
||||
_extract_crng(crng, out);
|
||||
_extract_crng(select_crng(), out);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1013,15 +1026,7 @@ static void _crng_backtrack_protect(struct crng_state *crng,
|
||||
|
||||
static void crng_backtrack_protect(__u8 tmp[CHACHA_BLOCK_SIZE], int used)
|
||||
{
|
||||
struct crng_state *crng = NULL;
|
||||
|
||||
#ifdef CONFIG_NUMA
|
||||
if (crng_node_pool)
|
||||
crng = crng_node_pool[numa_node_id()];
|
||||
if (crng == NULL)
|
||||
#endif
|
||||
crng = &primary_crng;
|
||||
_crng_backtrack_protect(crng, tmp, used);
|
||||
_crng_backtrack_protect(select_crng(), tmp, used);
|
||||
}
|
||||
|
||||
static ssize_t extract_crng_user(void __user *buf, size_t nbytes)
|
||||
@@ -1983,8 +1988,8 @@ static long random_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
|
||||
return -EPERM;
|
||||
if (crng_init < 2)
|
||||
return -ENODATA;
|
||||
crng_reseed(&primary_crng, NULL);
|
||||
crng_global_init_time = jiffies - 1;
|
||||
crng_reseed(&primary_crng, &input_pool);
|
||||
WRITE_ONCE(crng_global_init_time, jiffies - 1);
|
||||
return 0;
|
||||
default:
|
||||
return -EINVAL;
|
||||
|
||||
@@ -808,7 +808,15 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
|
||||
intmask |= TPM_INTF_CMD_READY_INT | TPM_INTF_LOCALITY_CHANGE_INT |
|
||||
TPM_INTF_DATA_AVAIL_INT | TPM_INTF_STS_VALID_INT;
|
||||
intmask &= ~TPM_GLOBAL_INT_ENABLE;
|
||||
|
||||
rc = request_locality(chip, 0);
|
||||
if (rc < 0) {
|
||||
rc = -ENODEV;
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), intmask);
|
||||
release_locality(chip, 0);
|
||||
|
||||
rc = tpm2_probe(chip);
|
||||
if (rc)
|
||||
|
||||
@@ -949,8 +949,7 @@ static int bcm2835_clock_is_on(struct clk_hw *hw)
|
||||
|
||||
static u32 bcm2835_clock_choose_div(struct clk_hw *hw,
|
||||
unsigned long rate,
|
||||
unsigned long parent_rate,
|
||||
bool round_up)
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw);
|
||||
const struct bcm2835_clock_data *data = clock->data;
|
||||
@@ -962,10 +961,6 @@ static u32 bcm2835_clock_choose_div(struct clk_hw *hw,
|
||||
|
||||
rem = do_div(temp, rate);
|
||||
div = temp;
|
||||
|
||||
/* Round up and mask off the unused bits */
|
||||
if (round_up && ((div & unused_frac_mask) != 0 || rem != 0))
|
||||
div += unused_frac_mask + 1;
|
||||
div &= ~unused_frac_mask;
|
||||
|
||||
/* different clamping limits apply for a mash clock */
|
||||
@@ -1096,7 +1091,7 @@ static int bcm2835_clock_set_rate(struct clk_hw *hw,
|
||||
struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw);
|
||||
struct bcm2835_cprman *cprman = clock->cprman;
|
||||
const struct bcm2835_clock_data *data = clock->data;
|
||||
u32 div = bcm2835_clock_choose_div(hw, rate, parent_rate, false);
|
||||
u32 div = bcm2835_clock_choose_div(hw, rate, parent_rate);
|
||||
u32 ctl;
|
||||
|
||||
spin_lock(&cprman->regs_lock);
|
||||
@@ -1147,7 +1142,7 @@ static unsigned long bcm2835_clock_choose_div_and_prate(struct clk_hw *hw,
|
||||
|
||||
if (!(BIT(parent_idx) & data->set_rate_parent)) {
|
||||
*prate = clk_hw_get_rate(parent);
|
||||
*div = bcm2835_clock_choose_div(hw, rate, *prate, true);
|
||||
*div = bcm2835_clock_choose_div(hw, rate, *prate);
|
||||
|
||||
*avgrate = bcm2835_clock_rate_from_divisor(clock, *prate, *div);
|
||||
|
||||
@@ -1233,7 +1228,7 @@ static int bcm2835_clock_determine_rate(struct clk_hw *hw,
|
||||
rate = bcm2835_clock_choose_div_and_prate(hw, i, req->rate,
|
||||
&div, &prate,
|
||||
&avgrate);
|
||||
if (rate > best_rate && rate <= req->rate) {
|
||||
if (abs(req->rate - rate) < abs(req->rate - best_rate)) {
|
||||
best_parent = parent;
|
||||
best_prate = prate;
|
||||
best_rate = rate;
|
||||
|
||||
@@ -544,8 +544,8 @@ static int qce_ahash_register_one(const struct qce_ahash_def *def,
|
||||
|
||||
ret = crypto_register_ahash(alg);
|
||||
if (ret) {
|
||||
kfree(tmpl);
|
||||
dev_err(qce->dev, "%s registration failed\n", base->cra_name);
|
||||
kfree(tmpl);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -206,7 +206,7 @@ static struct shash_alg algs[] = {
|
||||
.digestsize = CHKSUM_DIGEST_SIZE,
|
||||
.base = {
|
||||
.cra_name = "crc32",
|
||||
.cra_driver_name = DRIVER_NAME,
|
||||
.cra_driver_name = "stm32-crc32-crc32",
|
||||
.cra_priority = 200,
|
||||
.cra_flags = CRYPTO_ALG_OPTIONAL_KEY,
|
||||
.cra_blocksize = CHKSUM_BLOCK_SIZE,
|
||||
@@ -228,7 +228,7 @@ static struct shash_alg algs[] = {
|
||||
.digestsize = CHKSUM_DIGEST_SIZE,
|
||||
.base = {
|
||||
.cra_name = "crc32c",
|
||||
.cra_driver_name = DRIVER_NAME,
|
||||
.cra_driver_name = "stm32-crc32-crc32c",
|
||||
.cra_priority = 200,
|
||||
.cra_flags = CRYPTO_ALG_OPTIONAL_KEY,
|
||||
.cra_blocksize = CHKSUM_BLOCK_SIZE,
|
||||
|
||||
@@ -100,6 +100,7 @@
|
||||
#define AT_XDMAC_CNDC_NDE (0x1 << 0) /* Channel x Next Descriptor Enable */
|
||||
#define AT_XDMAC_CNDC_NDSUP (0x1 << 1) /* Channel x Next Descriptor Source Update */
|
||||
#define AT_XDMAC_CNDC_NDDUP (0x1 << 2) /* Channel x Next Descriptor Destination Update */
|
||||
#define AT_XDMAC_CNDC_NDVIEW_MASK GENMASK(28, 27)
|
||||
#define AT_XDMAC_CNDC_NDVIEW_NDV0 (0x0 << 3) /* Channel x Next Descriptor View 0 */
|
||||
#define AT_XDMAC_CNDC_NDVIEW_NDV1 (0x1 << 3) /* Channel x Next Descriptor View 1 */
|
||||
#define AT_XDMAC_CNDC_NDVIEW_NDV2 (0x2 << 3) /* Channel x Next Descriptor View 2 */
|
||||
@@ -231,15 +232,15 @@ struct at_xdmac {
|
||||
|
||||
/* Linked List Descriptor */
|
||||
struct at_xdmac_lld {
|
||||
dma_addr_t mbr_nda; /* Next Descriptor Member */
|
||||
u32 mbr_ubc; /* Microblock Control Member */
|
||||
dma_addr_t mbr_sa; /* Source Address Member */
|
||||
dma_addr_t mbr_da; /* Destination Address Member */
|
||||
u32 mbr_cfg; /* Configuration Register */
|
||||
u32 mbr_bc; /* Block Control Register */
|
||||
u32 mbr_ds; /* Data Stride Register */
|
||||
u32 mbr_sus; /* Source Microblock Stride Register */
|
||||
u32 mbr_dus; /* Destination Microblock Stride Register */
|
||||
u32 mbr_nda; /* Next Descriptor Member */
|
||||
u32 mbr_ubc; /* Microblock Control Member */
|
||||
u32 mbr_sa; /* Source Address Member */
|
||||
u32 mbr_da; /* Destination Address Member */
|
||||
u32 mbr_cfg; /* Configuration Register */
|
||||
u32 mbr_bc; /* Block Control Register */
|
||||
u32 mbr_ds; /* Data Stride Register */
|
||||
u32 mbr_sus; /* Source Microblock Stride Register */
|
||||
u32 mbr_dus; /* Destination Microblock Stride Register */
|
||||
};
|
||||
|
||||
/* 64-bit alignment needed to update CNDA and CUBC registers in an atomic way. */
|
||||
@@ -344,9 +345,6 @@ static void at_xdmac_start_xfer(struct at_xdmac_chan *atchan,
|
||||
|
||||
dev_vdbg(chan2dev(&atchan->chan), "%s: desc 0x%p\n", __func__, first);
|
||||
|
||||
if (at_xdmac_chan_is_enabled(atchan))
|
||||
return;
|
||||
|
||||
/* Set transfer as active to not try to start it again. */
|
||||
first->active_xfer = true;
|
||||
|
||||
@@ -362,7 +360,8 @@ static void at_xdmac_start_xfer(struct at_xdmac_chan *atchan,
|
||||
*/
|
||||
if (at_xdmac_chan_is_cyclic(atchan))
|
||||
reg = AT_XDMAC_CNDC_NDVIEW_NDV1;
|
||||
else if (first->lld.mbr_ubc & AT_XDMAC_MBR_UBC_NDV3)
|
||||
else if ((first->lld.mbr_ubc &
|
||||
AT_XDMAC_CNDC_NDVIEW_MASK) == AT_XDMAC_MBR_UBC_NDV3)
|
||||
reg = AT_XDMAC_CNDC_NDVIEW_NDV3;
|
||||
else
|
||||
reg = AT_XDMAC_CNDC_NDVIEW_NDV2;
|
||||
@@ -427,13 +426,12 @@ static dma_cookie_t at_xdmac_tx_submit(struct dma_async_tx_descriptor *tx)
|
||||
spin_lock_irqsave(&atchan->lock, irqflags);
|
||||
cookie = dma_cookie_assign(tx);
|
||||
|
||||
list_add_tail(&desc->xfer_node, &atchan->xfers_list);
|
||||
spin_unlock_irqrestore(&atchan->lock, irqflags);
|
||||
|
||||
dev_vdbg(chan2dev(tx->chan), "%s: atchan 0x%p, add desc 0x%p to xfers_list\n",
|
||||
__func__, atchan, desc);
|
||||
list_add_tail(&desc->xfer_node, &atchan->xfers_list);
|
||||
if (list_is_singular(&atchan->xfers_list))
|
||||
at_xdmac_start_xfer(atchan, desc);
|
||||
|
||||
spin_unlock_irqrestore(&atchan->lock, irqflags);
|
||||
return cookie;
|
||||
}
|
||||
|
||||
|
||||
@@ -722,12 +722,6 @@ static int mmp_pdma_config(struct dma_chan *dchan,
|
||||
|
||||
chan->dir = cfg->direction;
|
||||
chan->dev_addr = addr;
|
||||
/* FIXME: drivers should be ported over to use the filter
|
||||
* function. Once that's done, the following two lines can
|
||||
* be removed.
|
||||
*/
|
||||
if (cfg->slave_id)
|
||||
chan->drcmr = cfg->slave_id;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -956,13 +956,6 @@ static void pxad_get_config(struct pxad_chan *chan,
|
||||
*dcmd |= PXA_DCMD_BURST16;
|
||||
else if (maxburst == 32)
|
||||
*dcmd |= PXA_DCMD_BURST32;
|
||||
|
||||
/* FIXME: drivers should be ported over to use the filter
|
||||
* function. Once that's done, the following two lines can
|
||||
* be removed.
|
||||
*/
|
||||
if (chan->cfg.slave_id)
|
||||
chan->drcmr = chan->cfg.slave_id;
|
||||
}
|
||||
|
||||
static struct dma_async_tx_descriptor *
|
||||
|
||||
@@ -2,9 +2,9 @@ menuconfig GOOGLE_FIRMWARE
|
||||
bool "Google Firmware Drivers"
|
||||
default n
|
||||
help
|
||||
These firmware drivers are used by Google's servers. They are
|
||||
only useful if you are working directly on one of their
|
||||
proprietary servers. If in doubt, say "N".
|
||||
These firmware drivers are used by Google servers,
|
||||
Chromebooks and other devices using coreboot firmware.
|
||||
If in doubt, say "N".
|
||||
|
||||
if GOOGLE_FIRMWARE
|
||||
|
||||
|
||||
@@ -943,10 +943,17 @@ int acpi_dev_gpio_irq_get(struct acpi_device *adev, int index)
|
||||
irq_flags = acpi_dev_get_irq_type(info.triggering,
|
||||
info.polarity);
|
||||
|
||||
/* Set type if specified and different than the current one */
|
||||
if (irq_flags != IRQ_TYPE_NONE &&
|
||||
irq_flags != irq_get_trigger_type(irq))
|
||||
irq_set_irq_type(irq, irq_flags);
|
||||
/*
|
||||
* If the IRQ is not already in use then set type
|
||||
* if specified and different than the current one.
|
||||
*/
|
||||
if (can_request_irq(irq, irq_flags)) {
|
||||
if (irq_flags != IRQ_TYPE_NONE &&
|
||||
irq_flags != irq_get_trigger_type(irq))
|
||||
irq_set_irq_type(irq, irq_flags);
|
||||
} else {
|
||||
dev_dbg(&adev->dev, "IRQ %d already in use\n", irq);
|
||||
}
|
||||
|
||||
return irq;
|
||||
}
|
||||
|
||||
@@ -404,6 +404,9 @@ amdgpu_connector_lcd_native_mode(struct drm_encoder *encoder)
|
||||
native_mode->vdisplay != 0 &&
|
||||
native_mode->clock != 0) {
|
||||
mode = drm_mode_duplicate(dev, native_mode);
|
||||
if (!mode)
|
||||
return NULL;
|
||||
|
||||
mode->type = DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER;
|
||||
drm_mode_set_name(mode);
|
||||
|
||||
@@ -418,6 +421,9 @@ amdgpu_connector_lcd_native_mode(struct drm_encoder *encoder)
|
||||
* simpler.
|
||||
*/
|
||||
mode = drm_cvt_mode(dev, native_mode->hdisplay, native_mode->vdisplay, 60, true, false, false);
|
||||
if (!mode)
|
||||
return NULL;
|
||||
|
||||
mode->type = DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER;
|
||||
DRM_DEBUG_KMS("Adding cvt approximation of native panel mode %s\n", mode->name);
|
||||
}
|
||||
|
||||
@@ -302,19 +302,10 @@ out:
|
||||
mutex_unlock(&ge_b850v3_lvds_dev_mutex);
|
||||
}
|
||||
|
||||
static int stdp4028_ge_b850v3_fw_probe(struct i2c_client *stdp4028_i2c,
|
||||
const struct i2c_device_id *id)
|
||||
static int ge_b850v3_register(void)
|
||||
{
|
||||
struct i2c_client *stdp4028_i2c = ge_b850v3_lvds_ptr->stdp4028_i2c;
|
||||
struct device *dev = &stdp4028_i2c->dev;
|
||||
int ret;
|
||||
|
||||
ret = ge_b850v3_lvds_init(dev);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ge_b850v3_lvds_ptr->stdp4028_i2c = stdp4028_i2c;
|
||||
i2c_set_clientdata(stdp4028_i2c, ge_b850v3_lvds_ptr);
|
||||
|
||||
/* drm bridge initialization */
|
||||
ge_b850v3_lvds_ptr->bridge.funcs = &ge_b850v3_lvds_funcs;
|
||||
@@ -336,6 +327,27 @@ static int stdp4028_ge_b850v3_fw_probe(struct i2c_client *stdp4028_i2c,
|
||||
"ge-b850v3-lvds-dp", ge_b850v3_lvds_ptr);
|
||||
}
|
||||
|
||||
static int stdp4028_ge_b850v3_fw_probe(struct i2c_client *stdp4028_i2c,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct device *dev = &stdp4028_i2c->dev;
|
||||
int ret;
|
||||
|
||||
ret = ge_b850v3_lvds_init(dev);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ge_b850v3_lvds_ptr->stdp4028_i2c = stdp4028_i2c;
|
||||
i2c_set_clientdata(stdp4028_i2c, ge_b850v3_lvds_ptr);
|
||||
|
||||
/* Only register after both bridges are probed */
|
||||
if (!ge_b850v3_lvds_ptr->stdp2690_i2c)
|
||||
return 0;
|
||||
|
||||
return ge_b850v3_register();
|
||||
}
|
||||
|
||||
static int stdp4028_ge_b850v3_fw_remove(struct i2c_client *stdp4028_i2c)
|
||||
{
|
||||
ge_b850v3_lvds_remove();
|
||||
@@ -379,7 +391,11 @@ static int stdp2690_ge_b850v3_fw_probe(struct i2c_client *stdp2690_i2c,
|
||||
ge_b850v3_lvds_ptr->stdp2690_i2c = stdp2690_i2c;
|
||||
i2c_set_clientdata(stdp2690_i2c, ge_b850v3_lvds_ptr);
|
||||
|
||||
return 0;
|
||||
/* Only register after both bridges are probed */
|
||||
if (!ge_b850v3_lvds_ptr->stdp4028_i2c)
|
||||
return 0;
|
||||
|
||||
return ge_b850v3_register();
|
||||
}
|
||||
|
||||
static int stdp2690_ge_b850v3_fw_remove(struct i2c_client *stdp2690_i2c)
|
||||
|
||||
@@ -2166,6 +2166,8 @@ struct drm_i915_private {
|
||||
|
||||
struct intel_uncore uncore;
|
||||
|
||||
struct mutex tlb_invalidate_lock;
|
||||
|
||||
struct i915_virtual_gpu vgpu;
|
||||
|
||||
struct intel_gvt *gvt;
|
||||
|
||||
@@ -2220,6 +2220,76 @@ static void __i915_gem_object_reset_page_iter(struct drm_i915_gem_object *obj)
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
struct reg_and_bit {
|
||||
i915_reg_t reg;
|
||||
u32 bit;
|
||||
};
|
||||
|
||||
static struct reg_and_bit
|
||||
get_reg_and_bit(const struct intel_engine_cs *engine,
|
||||
const i915_reg_t *regs, const unsigned int num)
|
||||
{
|
||||
const unsigned int class = engine->class;
|
||||
struct reg_and_bit rb = { .bit = 1 };
|
||||
|
||||
if (WARN_ON_ONCE(class >= num || !regs[class].reg))
|
||||
return rb;
|
||||
|
||||
rb.reg = regs[class];
|
||||
if (class == VIDEO_DECODE_CLASS)
|
||||
rb.reg.reg += 4 * engine->instance; /* GEN8_M2TCR */
|
||||
|
||||
return rb;
|
||||
}
|
||||
|
||||
static void invalidate_tlbs(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
static const i915_reg_t gen8_regs[] = {
|
||||
[RENDER_CLASS] = GEN8_RTCR,
|
||||
[VIDEO_DECODE_CLASS] = GEN8_M1TCR, /* , GEN8_M2TCR */
|
||||
[VIDEO_ENHANCEMENT_CLASS] = GEN8_VTCR,
|
||||
[COPY_ENGINE_CLASS] = GEN8_BTCR,
|
||||
};
|
||||
const unsigned int num = ARRAY_SIZE(gen8_regs);
|
||||
const i915_reg_t *regs = gen8_regs;
|
||||
struct intel_engine_cs *engine;
|
||||
enum intel_engine_id id;
|
||||
|
||||
if (INTEL_GEN(dev_priv) < 8)
|
||||
return;
|
||||
|
||||
assert_rpm_wakelock_held(dev_priv);
|
||||
|
||||
mutex_lock(&dev_priv->tlb_invalidate_lock);
|
||||
intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
|
||||
|
||||
for_each_engine(engine, dev_priv, id) {
|
||||
/*
|
||||
* HW architecture suggest typical invalidation time at 40us,
|
||||
* with pessimistic cases up to 100us and a recommendation to
|
||||
* cap at 1ms. We go a bit higher just in case.
|
||||
*/
|
||||
const unsigned int timeout_us = 100;
|
||||
const unsigned int timeout_ms = 4;
|
||||
struct reg_and_bit rb;
|
||||
|
||||
rb = get_reg_and_bit(engine, regs, num);
|
||||
if (!i915_mmio_reg_offset(rb.reg))
|
||||
continue;
|
||||
|
||||
I915_WRITE_FW(rb.reg, rb.bit);
|
||||
if (__intel_wait_for_register_fw(dev_priv,
|
||||
rb.reg, rb.bit, 0,
|
||||
timeout_us, timeout_ms,
|
||||
NULL))
|
||||
DRM_ERROR_RATELIMITED("%s TLB invalidation did not complete in %ums!\n",
|
||||
engine->name, timeout_ms);
|
||||
}
|
||||
|
||||
intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
|
||||
mutex_unlock(&dev_priv->tlb_invalidate_lock);
|
||||
}
|
||||
|
||||
void __i915_gem_object_put_pages(struct drm_i915_gem_object *obj,
|
||||
enum i915_mm_subclass subclass)
|
||||
{
|
||||
@@ -2257,8 +2327,18 @@ void __i915_gem_object_put_pages(struct drm_i915_gem_object *obj,
|
||||
|
||||
__i915_gem_object_reset_page_iter(obj);
|
||||
|
||||
if (!IS_ERR(pages))
|
||||
if (!IS_ERR(pages)) {
|
||||
if (test_and_clear_bit(I915_BO_WAS_BOUND_BIT, &obj->flags)) {
|
||||
struct drm_i915_private *i915 = to_i915(obj->base.dev);
|
||||
|
||||
if (intel_runtime_pm_get_if_in_use(i915)) {
|
||||
invalidate_tlbs(i915);
|
||||
intel_runtime_pm_put(i915);
|
||||
}
|
||||
}
|
||||
|
||||
obj->ops->put_pages(obj, pages);
|
||||
}
|
||||
|
||||
unlock:
|
||||
mutex_unlock(&obj->mm.lock);
|
||||
@@ -4972,6 +5052,8 @@ i915_gem_load_init(struct drm_i915_private *dev_priv)
|
||||
|
||||
spin_lock_init(&dev_priv->fb_tracking.lock);
|
||||
|
||||
mutex_init(&dev_priv->tlb_invalidate_lock);
|
||||
|
||||
return 0;
|
||||
|
||||
err_priorities:
|
||||
|
||||
@@ -135,6 +135,7 @@ struct drm_i915_gem_object {
|
||||
* activity?
|
||||
*/
|
||||
#define I915_BO_ACTIVE_REF 0
|
||||
#define I915_BO_WAS_BOUND_BIT 1
|
||||
|
||||
/*
|
||||
* Is the object to be mapped as read-only to the GPU
|
||||
|
||||
@@ -2380,6 +2380,12 @@ enum i915_power_well_id {
|
||||
#define GAMT_CHKN_BIT_REG _MMIO(0x4ab8)
|
||||
#define GAMT_CHKN_DISABLE_DYNAMIC_CREDIT_SHARING (1<<28)
|
||||
|
||||
#define GEN8_RTCR _MMIO(0x4260)
|
||||
#define GEN8_M1TCR _MMIO(0x4264)
|
||||
#define GEN8_M2TCR _MMIO(0x4268)
|
||||
#define GEN8_BTCR _MMIO(0x426c)
|
||||
#define GEN8_VTCR _MMIO(0x4270)
|
||||
|
||||
#if 0
|
||||
#define PRB0_TAIL _MMIO(0x2030)
|
||||
#define PRB0_HEAD _MMIO(0x2034)
|
||||
|
||||
@@ -272,6 +272,10 @@ int i915_vma_bind(struct i915_vma *vma, enum i915_cache_level cache_level,
|
||||
return ret;
|
||||
|
||||
vma->flags |= bind_flags;
|
||||
|
||||
if (vma->obj)
|
||||
set_bit(I915_BO_WAS_BOUND_BIT, &vma->obj->flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -2985,9 +2985,9 @@ static void snb_wm_latency_quirk(struct drm_i915_private *dev_priv)
|
||||
* The BIOS provided WM memory latency values are often
|
||||
* inadequate for high resolution displays. Adjust them.
|
||||
*/
|
||||
changed = ilk_increase_wm_latency(dev_priv, dev_priv->wm.pri_latency, 12) |
|
||||
ilk_increase_wm_latency(dev_priv, dev_priv->wm.spr_latency, 12) |
|
||||
ilk_increase_wm_latency(dev_priv, dev_priv->wm.cur_latency, 12);
|
||||
changed = ilk_increase_wm_latency(dev_priv, dev_priv->wm.pri_latency, 12);
|
||||
changed |= ilk_increase_wm_latency(dev_priv, dev_priv->wm.spr_latency, 12);
|
||||
changed |= ilk_increase_wm_latency(dev_priv, dev_priv->wm.cur_latency, 12);
|
||||
|
||||
if (!changed)
|
||||
return;
|
||||
|
||||
@@ -106,12 +106,9 @@ nouveau_sgdma_create_ttm(struct ttm_bo_device *bdev,
|
||||
else
|
||||
nvbe->ttm.ttm.func = &nv50_sgdma_backend;
|
||||
|
||||
if (ttm_dma_tt_init(&nvbe->ttm, bdev, size, page_flags, dummy_read_page))
|
||||
/*
|
||||
* A failing ttm_dma_tt_init() will call ttm_tt_destroy()
|
||||
* and thus our nouveau_sgdma_destroy() hook, so we don't need
|
||||
* to free nvbe here.
|
||||
*/
|
||||
if (ttm_dma_tt_init(&nvbe->ttm, bdev, size, page_flags, dummy_read_page)) {
|
||||
kfree(nvbe);
|
||||
return NULL;
|
||||
}
|
||||
return &nvbe->ttm.ttm;
|
||||
}
|
||||
|
||||
@@ -70,20 +70,13 @@ nvkm_pmu_fini(struct nvkm_subdev *subdev, bool suspend)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
static void
|
||||
nvkm_pmu_reset(struct nvkm_pmu *pmu)
|
||||
{
|
||||
struct nvkm_device *device = pmu->subdev.device;
|
||||
|
||||
if (!pmu->func->enabled(pmu))
|
||||
return 0;
|
||||
|
||||
/* Inhibit interrupts, and wait for idle. */
|
||||
nvkm_wr32(device, 0x10a014, 0x0000ffff);
|
||||
nvkm_msec(device, 2000,
|
||||
if (!nvkm_rd32(device, 0x10a04c))
|
||||
break;
|
||||
);
|
||||
return;
|
||||
|
||||
/* Reset. */
|
||||
if (pmu->func->reset)
|
||||
@@ -94,25 +87,37 @@ nvkm_pmu_reset(struct nvkm_pmu *pmu)
|
||||
if (!(nvkm_rd32(device, 0x10a10c) & 0x00000006))
|
||||
break;
|
||||
);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
nvkm_pmu_preinit(struct nvkm_subdev *subdev)
|
||||
{
|
||||
struct nvkm_pmu *pmu = nvkm_pmu(subdev);
|
||||
return nvkm_pmu_reset(pmu);
|
||||
nvkm_pmu_reset(pmu);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
nvkm_pmu_init(struct nvkm_subdev *subdev)
|
||||
{
|
||||
struct nvkm_pmu *pmu = nvkm_pmu(subdev);
|
||||
int ret = nvkm_pmu_reset(pmu);
|
||||
if (ret == 0 && pmu->func->init)
|
||||
ret = pmu->func->init(pmu);
|
||||
return ret;
|
||||
struct nvkm_device *device = pmu->subdev.device;
|
||||
|
||||
if (!pmu->func->init)
|
||||
return 0;
|
||||
|
||||
if (pmu->func->enabled(pmu)) {
|
||||
/* Inhibit interrupts, and wait for idle. */
|
||||
nvkm_wr32(device, 0x10a014, 0x0000ffff);
|
||||
nvkm_msec(device, 2000,
|
||||
if (!nvkm_rd32(device, 0x10a04c))
|
||||
break;
|
||||
);
|
||||
|
||||
nvkm_pmu_reset(pmu);
|
||||
}
|
||||
|
||||
return pmu->func->init(pmu);
|
||||
}
|
||||
|
||||
static int
|
||||
|
||||
@@ -654,6 +654,8 @@ void radeon_driver_lastclose_kms(struct drm_device *dev)
|
||||
int radeon_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv)
|
||||
{
|
||||
struct radeon_device *rdev = dev->dev_private;
|
||||
struct radeon_fpriv *fpriv;
|
||||
struct radeon_vm *vm;
|
||||
int r;
|
||||
|
||||
file_priv->driver_priv = NULL;
|
||||
@@ -666,48 +668,52 @@ int radeon_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv)
|
||||
|
||||
/* new gpu have virtual address space support */
|
||||
if (rdev->family >= CHIP_CAYMAN) {
|
||||
struct radeon_fpriv *fpriv;
|
||||
struct radeon_vm *vm;
|
||||
|
||||
fpriv = kzalloc(sizeof(*fpriv), GFP_KERNEL);
|
||||
if (unlikely(!fpriv)) {
|
||||
r = -ENOMEM;
|
||||
goto out_suspend;
|
||||
goto err_suspend;
|
||||
}
|
||||
|
||||
if (rdev->accel_working) {
|
||||
vm = &fpriv->vm;
|
||||
r = radeon_vm_init(rdev, vm);
|
||||
if (r) {
|
||||
kfree(fpriv);
|
||||
goto out_suspend;
|
||||
}
|
||||
if (r)
|
||||
goto err_fpriv;
|
||||
|
||||
r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false);
|
||||
if (r) {
|
||||
radeon_vm_fini(rdev, vm);
|
||||
kfree(fpriv);
|
||||
goto out_suspend;
|
||||
}
|
||||
if (r)
|
||||
goto err_vm_fini;
|
||||
|
||||
/* map the ib pool buffer read only into
|
||||
* virtual address space */
|
||||
vm->ib_bo_va = radeon_vm_bo_add(rdev, vm,
|
||||
rdev->ring_tmp_bo.bo);
|
||||
if (!vm->ib_bo_va) {
|
||||
r = -ENOMEM;
|
||||
goto err_vm_fini;
|
||||
}
|
||||
|
||||
r = radeon_vm_bo_set_addr(rdev, vm->ib_bo_va,
|
||||
RADEON_VA_IB_OFFSET,
|
||||
RADEON_VM_PAGE_READABLE |
|
||||
RADEON_VM_PAGE_SNOOPED);
|
||||
if (r) {
|
||||
radeon_vm_fini(rdev, vm);
|
||||
kfree(fpriv);
|
||||
goto out_suspend;
|
||||
}
|
||||
if (r)
|
||||
goto err_vm_fini;
|
||||
}
|
||||
file_priv->driver_priv = fpriv;
|
||||
}
|
||||
|
||||
out_suspend:
|
||||
pm_runtime_mark_last_busy(dev->dev);
|
||||
pm_runtime_put_autosuspend(dev->dev);
|
||||
return 0;
|
||||
|
||||
err_vm_fini:
|
||||
radeon_vm_fini(rdev, vm);
|
||||
err_fpriv:
|
||||
kfree(fpriv);
|
||||
|
||||
err_suspend:
|
||||
pm_runtime_mark_last_busy(dev->dev);
|
||||
pm_runtime_put_autosuspend(dev->dev);
|
||||
return r;
|
||||
|
||||
@@ -199,7 +199,6 @@ int ttm_tt_init(struct ttm_tt *ttm, struct ttm_bo_device *bdev,
|
||||
|
||||
ttm_tt_alloc_page_directory(ttm);
|
||||
if (!ttm->pages) {
|
||||
ttm_tt_destroy(ttm);
|
||||
pr_err("Failed allocating page table\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
@@ -232,7 +231,6 @@ int ttm_dma_tt_init(struct ttm_dma_tt *ttm_dma, struct ttm_bo_device *bdev,
|
||||
INIT_LIST_HEAD(&ttm_dma->pages_list);
|
||||
ttm_dma_tt_alloc_page_directory(ttm_dma);
|
||||
if (!ttm->pages) {
|
||||
ttm_tt_destroy(ttm);
|
||||
pr_err("Failed allocating page table\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
@@ -837,15 +837,14 @@ extern int vmw_execbuf_fence_commands(struct drm_file *file_priv,
|
||||
struct vmw_private *dev_priv,
|
||||
struct vmw_fence_obj **p_fence,
|
||||
uint32_t *p_handle);
|
||||
extern void vmw_execbuf_copy_fence_user(struct vmw_private *dev_priv,
|
||||
extern int vmw_execbuf_copy_fence_user(struct vmw_private *dev_priv,
|
||||
struct vmw_fpriv *vmw_fp,
|
||||
int ret,
|
||||
struct drm_vmw_fence_rep __user
|
||||
*user_fence_rep,
|
||||
struct vmw_fence_obj *fence,
|
||||
uint32_t fence_handle,
|
||||
int32_t out_fence_fd,
|
||||
struct sync_file *sync_file);
|
||||
int32_t out_fence_fd);
|
||||
extern int vmw_validate_single_buffer(struct vmw_private *dev_priv,
|
||||
struct ttm_buffer_object *bo,
|
||||
bool interruptible,
|
||||
|
||||
@@ -3848,20 +3848,19 @@ int vmw_execbuf_fence_commands(struct drm_file *file_priv,
|
||||
* object so we wait for it immediately, and then unreference the
|
||||
* user-space reference.
|
||||
*/
|
||||
void
|
||||
int
|
||||
vmw_execbuf_copy_fence_user(struct vmw_private *dev_priv,
|
||||
struct vmw_fpriv *vmw_fp,
|
||||
int ret,
|
||||
struct drm_vmw_fence_rep __user *user_fence_rep,
|
||||
struct vmw_fence_obj *fence,
|
||||
uint32_t fence_handle,
|
||||
int32_t out_fence_fd,
|
||||
struct sync_file *sync_file)
|
||||
int32_t out_fence_fd)
|
||||
{
|
||||
struct drm_vmw_fence_rep fence_rep;
|
||||
|
||||
if (user_fence_rep == NULL)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
memset(&fence_rep, 0, sizeof(fence_rep));
|
||||
|
||||
@@ -3889,20 +3888,14 @@ vmw_execbuf_copy_fence_user(struct vmw_private *dev_priv,
|
||||
* and unreference the handle.
|
||||
*/
|
||||
if (unlikely(ret != 0) && (fence_rep.error == 0)) {
|
||||
if (sync_file)
|
||||
fput(sync_file->file);
|
||||
|
||||
if (fence_rep.fd != -1) {
|
||||
put_unused_fd(fence_rep.fd);
|
||||
fence_rep.fd = -1;
|
||||
}
|
||||
|
||||
ttm_ref_object_base_unref(vmw_fp->tfile,
|
||||
fence_handle, TTM_REF_USAGE);
|
||||
DRM_ERROR("Fence copy error. Syncing.\n");
|
||||
(void) vmw_fence_obj_wait(fence, false, false,
|
||||
VMW_FENCE_WAIT_TIMEOUT);
|
||||
}
|
||||
|
||||
return ret ? -EFAULT : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -4262,16 +4255,23 @@ int vmw_execbuf_process(struct drm_file *file_priv,
|
||||
|
||||
(void) vmw_fence_obj_wait(fence, false, false,
|
||||
VMW_FENCE_WAIT_TIMEOUT);
|
||||
}
|
||||
}
|
||||
|
||||
ret = vmw_execbuf_copy_fence_user(dev_priv, vmw_fpriv(file_priv), ret,
|
||||
user_fence_rep, fence, handle, out_fence_fd);
|
||||
|
||||
if (sync_file) {
|
||||
if (ret) {
|
||||
/* usercopy of fence failed, put the file object */
|
||||
fput(sync_file->file);
|
||||
put_unused_fd(out_fence_fd);
|
||||
} else {
|
||||
/* Link the fence with the FD created earlier */
|
||||
fd_install(out_fence_fd, sync_file->file);
|
||||
}
|
||||
}
|
||||
|
||||
vmw_execbuf_copy_fence_user(dev_priv, vmw_fpriv(file_priv), ret,
|
||||
user_fence_rep, fence, handle,
|
||||
out_fence_fd, sync_file);
|
||||
|
||||
/* Don't unreference when handing fence out */
|
||||
if (unlikely(out_fence != NULL)) {
|
||||
*out_fence = fence;
|
||||
@@ -4290,7 +4290,7 @@ int vmw_execbuf_process(struct drm_file *file_priv,
|
||||
*/
|
||||
vmw_resource_list_unreference(sw_context, &resource_list);
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
|
||||
out_unlock_binding:
|
||||
mutex_unlock(&dev_priv->binding_mutex);
|
||||
|
||||
@@ -1150,7 +1150,7 @@ int vmw_fence_event_ioctl(struct drm_device *dev, void *data,
|
||||
}
|
||||
|
||||
vmw_execbuf_copy_fence_user(dev_priv, vmw_fp, 0, user_fence_rep, fence,
|
||||
handle, -1, NULL);
|
||||
handle, -1);
|
||||
vmw_fence_obj_unreference(&fence);
|
||||
return 0;
|
||||
out_no_create:
|
||||
|
||||
@@ -2511,7 +2511,7 @@ void vmw_kms_helper_buffer_finish(struct vmw_private *dev_priv,
|
||||
if (file_priv)
|
||||
vmw_execbuf_copy_fence_user(dev_priv, vmw_fpriv(file_priv),
|
||||
ret, user_fence_rep, fence,
|
||||
handle, -1, NULL);
|
||||
handle, -1);
|
||||
if (out_fence)
|
||||
*out_fence = fence;
|
||||
else
|
||||
|
||||
@@ -385,7 +385,7 @@ static int apple_input_configured(struct hid_device *hdev,
|
||||
|
||||
if ((asc->quirks & APPLE_HAS_FN) && !asc->fn_found) {
|
||||
hid_info(hdev, "Fn key not found (Apple Wireless Keyboard clone?), disabling Fn key handling\n");
|
||||
asc->quirks = 0;
|
||||
asc->quirks &= ~APPLE_HAS_FN;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -32,11 +32,22 @@
|
||||
|
||||
struct uhid_device {
|
||||
struct mutex devlock;
|
||||
|
||||
/* This flag tracks whether the HID device is usable for commands from
|
||||
* userspace. The flag is already set before hid_add_device(), which
|
||||
* runs in workqueue context, to allow hid_add_device() to communicate
|
||||
* with userspace.
|
||||
* However, if hid_add_device() fails, the flag is cleared without
|
||||
* holding devlock.
|
||||
* We guarantee that if @running changes from true to false while you're
|
||||
* holding @devlock, it's still fine to access @hid.
|
||||
*/
|
||||
bool running;
|
||||
|
||||
__u8 *rd_data;
|
||||
uint rd_size;
|
||||
|
||||
/* When this is NULL, userspace may use UHID_CREATE/UHID_CREATE2. */
|
||||
struct hid_device *hid;
|
||||
struct uhid_event input_buf;
|
||||
|
||||
@@ -67,9 +78,18 @@ static void uhid_device_add_worker(struct work_struct *work)
|
||||
if (ret) {
|
||||
hid_err(uhid->hid, "Cannot register HID device: error %d\n", ret);
|
||||
|
||||
hid_destroy_device(uhid->hid);
|
||||
uhid->hid = NULL;
|
||||
/* We used to call hid_destroy_device() here, but that's really
|
||||
* messy to get right because we have to coordinate with
|
||||
* concurrent writes from userspace that might be in the middle
|
||||
* of using uhid->hid.
|
||||
* Just leave uhid->hid as-is for now, and clean it up when
|
||||
* userspace tries to close or reinitialize the uhid instance.
|
||||
*
|
||||
* However, we do have to clear the ->running flag and do a
|
||||
* wakeup to make sure userspace knows that the device is gone.
|
||||
*/
|
||||
uhid->running = false;
|
||||
wake_up_interruptible(&uhid->report_wait);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -478,7 +498,7 @@ static int uhid_dev_create2(struct uhid_device *uhid,
|
||||
void *rd_data;
|
||||
int ret;
|
||||
|
||||
if (uhid->running)
|
||||
if (uhid->hid)
|
||||
return -EALREADY;
|
||||
|
||||
rd_size = ev->u.create2.rd_size;
|
||||
@@ -559,7 +579,7 @@ static int uhid_dev_create(struct uhid_device *uhid,
|
||||
|
||||
static int uhid_dev_destroy(struct uhid_device *uhid)
|
||||
{
|
||||
if (!uhid->running)
|
||||
if (!uhid->hid)
|
||||
return -EINVAL;
|
||||
|
||||
uhid->running = false;
|
||||
@@ -568,6 +588,7 @@ static int uhid_dev_destroy(struct uhid_device *uhid)
|
||||
cancel_work_sync(&uhid->worker);
|
||||
|
||||
hid_destroy_device(uhid->hid);
|
||||
uhid->hid = NULL;
|
||||
kfree(uhid->rd_data);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -2424,6 +2424,24 @@ static void wacom_wac_finger_slot(struct wacom_wac *wacom_wac,
|
||||
}
|
||||
}
|
||||
|
||||
static bool wacom_wac_slot_is_active(struct input_dev *dev, int key)
|
||||
{
|
||||
struct input_mt *mt = dev->mt;
|
||||
struct input_mt_slot *s;
|
||||
|
||||
if (!mt)
|
||||
return false;
|
||||
|
||||
for (s = mt->slots; s != mt->slots + mt->num_slots; s++) {
|
||||
if (s->key == key &&
|
||||
input_mt_get_value(s, ABS_MT_TRACKING_ID) >= 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void wacom_wac_finger_event(struct hid_device *hdev,
|
||||
struct hid_field *field, struct hid_usage *usage, __s32 value)
|
||||
{
|
||||
@@ -2458,8 +2476,14 @@ static void wacom_wac_finger_event(struct hid_device *hdev,
|
||||
|
||||
|
||||
if (usage->usage_index + 1 == field->report_count) {
|
||||
if (equivalent_usage == wacom_wac->hid_data.last_slot_field)
|
||||
wacom_wac_finger_slot(wacom_wac, wacom_wac->touch_input);
|
||||
if (equivalent_usage == wacom_wac->hid_data.last_slot_field) {
|
||||
bool touch_removed = wacom_wac_slot_is_active(wacom_wac->touch_input,
|
||||
wacom_wac->hid_data.id) && !wacom_wac->hid_data.tipswitch;
|
||||
|
||||
if (wacom_wac->hid_data.confidence || touch_removed) {
|
||||
wacom_wac_finger_slot(wacom_wac, wacom_wac->touch_input);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2471,6 +2495,12 @@ static void wacom_wac_finger_pre_report(struct hid_device *hdev,
|
||||
struct hid_data* hid_data = &wacom_wac->hid_data;
|
||||
int i;
|
||||
|
||||
hid_data->confidence = true;
|
||||
|
||||
hid_data->cc_report = 0;
|
||||
hid_data->cc_index = -1;
|
||||
hid_data->cc_value_index = -1;
|
||||
|
||||
for (i = 0; i < report->maxfield; i++) {
|
||||
struct hid_field *field = report->field[i];
|
||||
int j;
|
||||
|
||||
@@ -115,6 +115,7 @@ struct hsi_client *hsi_new_client(struct hsi_port *port,
|
||||
if (device_register(&cl->device) < 0) {
|
||||
pr_err("hsi: failed to register client: %s\n", info->name);
|
||||
put_device(&cl->device);
|
||||
goto err;
|
||||
}
|
||||
|
||||
return cl;
|
||||
|
||||
@@ -50,10 +50,10 @@ enum dw_pci_ctl_id_t {
|
||||
};
|
||||
|
||||
struct dw_scl_sda_cfg {
|
||||
u32 ss_hcnt;
|
||||
u32 fs_hcnt;
|
||||
u32 ss_lcnt;
|
||||
u32 fs_lcnt;
|
||||
u16 ss_hcnt;
|
||||
u16 fs_hcnt;
|
||||
u16 ss_lcnt;
|
||||
u16 fs_lcnt;
|
||||
u32 sda_hold;
|
||||
};
|
||||
|
||||
|
||||
@@ -771,6 +771,11 @@ static int i801_block_transaction(struct i801_priv *priv,
|
||||
int result = 0;
|
||||
unsigned char hostc;
|
||||
|
||||
if (read_write == I2C_SMBUS_READ && command == I2C_SMBUS_BLOCK_DATA)
|
||||
data->block[0] = I2C_SMBUS_BLOCK_MAX;
|
||||
else if (data->block[0] < 1 || data->block[0] > I2C_SMBUS_BLOCK_MAX)
|
||||
return -EPROTO;
|
||||
|
||||
if (command == I2C_SMBUS_I2C_BLOCK_DATA) {
|
||||
if (read_write == I2C_SMBUS_WRITE) {
|
||||
/* set I2C_EN bit in configuration register */
|
||||
@@ -784,16 +789,6 @@ static int i801_block_transaction(struct i801_priv *priv,
|
||||
}
|
||||
}
|
||||
|
||||
if (read_write == I2C_SMBUS_WRITE
|
||||
|| command == I2C_SMBUS_I2C_BLOCK_DATA) {
|
||||
if (data->block[0] < 1)
|
||||
data->block[0] = 1;
|
||||
if (data->block[0] > I2C_SMBUS_BLOCK_MAX)
|
||||
data->block[0] = I2C_SMBUS_BLOCK_MAX;
|
||||
} else {
|
||||
data->block[0] = 32; /* max for SMBus block reads */
|
||||
}
|
||||
|
||||
/* Experience has shown that the block buffer can only be used for
|
||||
SMBus (not I2C) block transactions, even though the datasheet
|
||||
doesn't mention this limitation. */
|
||||
|
||||
@@ -104,23 +104,30 @@ static irqreturn_t mpc_i2c_isr(int irq, void *dev_id)
|
||||
/* Sometimes 9th clock pulse isn't generated, and slave doesn't release
|
||||
* the bus, because it wants to send ACK.
|
||||
* Following sequence of enabling/disabling and sending start/stop generates
|
||||
* the 9 pulses, so it's all OK.
|
||||
* the 9 pulses, each with a START then ending with STOP, so it's all OK.
|
||||
*/
|
||||
static void mpc_i2c_fixup(struct mpc_i2c *i2c)
|
||||
{
|
||||
int k;
|
||||
u32 delay_val = 1000000 / i2c->real_clk + 1;
|
||||
|
||||
if (delay_val < 2)
|
||||
delay_val = 2;
|
||||
unsigned long flags;
|
||||
|
||||
for (k = 9; k; k--) {
|
||||
writeccr(i2c, 0);
|
||||
writeccr(i2c, CCR_MSTA | CCR_MTX | CCR_MEN);
|
||||
writeb(0, i2c->base + MPC_I2C_SR); /* clear any status bits */
|
||||
writeccr(i2c, CCR_MEN | CCR_MSTA); /* START */
|
||||
readb(i2c->base + MPC_I2C_DR); /* init xfer */
|
||||
udelay(15); /* let it hit the bus */
|
||||
local_irq_save(flags); /* should not be delayed further */
|
||||
writeccr(i2c, CCR_MEN | CCR_MSTA | CCR_RSTA); /* delay SDA */
|
||||
readb(i2c->base + MPC_I2C_DR);
|
||||
writeccr(i2c, CCR_MEN);
|
||||
udelay(delay_val << 1);
|
||||
if (k != 1)
|
||||
udelay(5);
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
writeccr(i2c, CCR_MEN); /* Initiate STOP */
|
||||
readb(i2c->base + MPC_I2C_DR);
|
||||
udelay(15); /* Let STOP propagate */
|
||||
writeccr(i2c, 0);
|
||||
}
|
||||
|
||||
static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing)
|
||||
|
||||
@@ -1075,7 +1075,8 @@ int ib_find_gid(struct ib_device *device, union ib_gid *gid,
|
||||
for (i = 0; i < device->port_immutable[port].gid_tbl_len; ++i) {
|
||||
ret = ib_query_gid(device, port, i, &tmp_gid, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
continue;
|
||||
|
||||
if (!memcmp(&tmp_gid, gid, sizeof *gid)) {
|
||||
*port_num = port;
|
||||
if (index)
|
||||
|
||||
@@ -66,7 +66,7 @@ void ib_copy_ah_attr_to_user(struct ib_device *device,
|
||||
struct rdma_ah_attr *src = ah_attr;
|
||||
struct rdma_ah_attr conv_ah;
|
||||
|
||||
memset(&dst->grh.reserved, 0, sizeof(dst->grh.reserved));
|
||||
memset(&dst->grh, 0, sizeof(dst->grh));
|
||||
|
||||
if ((ah_attr->type == RDMA_AH_ATTR_TYPE_OPA) &&
|
||||
(rdma_ah_get_dlid(ah_attr) >=
|
||||
|
||||
@@ -2114,6 +2114,7 @@ int c4iw_ib_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
|
||||
memset(attr, 0, sizeof *attr);
|
||||
memset(init_attr, 0, sizeof *init_attr);
|
||||
attr->qp_state = to_ib_qp_state(qhp->attr.state);
|
||||
attr->cur_qp_state = to_ib_qp_state(qhp->attr.state);
|
||||
init_attr->cap.max_send_wr = qhp->attr.sq_num_entries;
|
||||
init_attr->cap.max_recv_wr = qhp->attr.rq_num_entries;
|
||||
init_attr->cap.max_send_sge = qhp->attr.sq_max_sges;
|
||||
|
||||
@@ -294,6 +294,9 @@ static int hns_roce_query_gid(struct ib_device *ib_dev, u8 port_num, int index,
|
||||
static int hns_roce_query_pkey(struct ib_device *ib_dev, u8 port, u16 index,
|
||||
u16 *pkey)
|
||||
{
|
||||
if (index > 0)
|
||||
return -EINVAL;
|
||||
|
||||
*pkey = PKEY_ID;
|
||||
|
||||
return 0;
|
||||
@@ -374,7 +377,7 @@ static int hns_roce_mmap(struct ib_ucontext *context,
|
||||
return -EINVAL;
|
||||
|
||||
if (vma->vm_pgoff == 0) {
|
||||
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
|
||||
vma->vm_page_prot = pgprot_device(vma->vm_page_prot);
|
||||
if (io_remap_pfn_range(vma, vma->vm_start,
|
||||
to_hr_ucontext(context)->uar.pfn,
|
||||
PAGE_SIZE, vma->vm_page_prot))
|
||||
|
||||
@@ -137,7 +137,7 @@ struct rxe_opcode_info rxe_opcode[RXE_NUM_OPCODE] = {
|
||||
}
|
||||
},
|
||||
[IB_OPCODE_RC_SEND_MIDDLE] = {
|
||||
.name = "IB_OPCODE_RC_SEND_MIDDLE]",
|
||||
.name = "IB_OPCODE_RC_SEND_MIDDLE",
|
||||
.mask = RXE_PAYLOAD_MASK | RXE_REQ_MASK | RXE_SEND_MASK
|
||||
| RXE_MIDDLE_MASK,
|
||||
.length = RXE_BTH_BYTES,
|
||||
|
||||
@@ -68,8 +68,7 @@ static void free_iova_flush_queue(struct iova_domain *iovad)
|
||||
if (!has_iova_flush_queue(iovad))
|
||||
return;
|
||||
|
||||
if (timer_pending(&iovad->fq_timer))
|
||||
del_timer(&iovad->fq_timer);
|
||||
del_timer_sync(&iovad->fq_timer);
|
||||
|
||||
fq_destroy_all_entries(iovad);
|
||||
|
||||
|
||||
@@ -390,7 +390,7 @@ mISDNInit(void)
|
||||
err = mISDN_inittimer(&debug);
|
||||
if (err)
|
||||
goto error2;
|
||||
err = l1_init(&debug);
|
||||
err = Isdnl1_Init(&debug);
|
||||
if (err)
|
||||
goto error3;
|
||||
err = Isdnl2_Init(&debug);
|
||||
@@ -404,7 +404,7 @@ mISDNInit(void)
|
||||
error5:
|
||||
Isdnl2_cleanup();
|
||||
error4:
|
||||
l1_cleanup();
|
||||
Isdnl1_cleanup();
|
||||
error3:
|
||||
mISDN_timer_cleanup();
|
||||
error2:
|
||||
@@ -417,7 +417,7 @@ static void mISDN_cleanup(void)
|
||||
{
|
||||
misdn_sock_cleanup();
|
||||
Isdnl2_cleanup();
|
||||
l1_cleanup();
|
||||
Isdnl1_cleanup();
|
||||
mISDN_timer_cleanup();
|
||||
class_unregister(&mISDN_class);
|
||||
|
||||
|
||||
@@ -69,8 +69,8 @@ struct Bprotocol *get_Bprotocol4id(u_int);
|
||||
extern int mISDN_inittimer(u_int *);
|
||||
extern void mISDN_timer_cleanup(void);
|
||||
|
||||
extern int l1_init(u_int *);
|
||||
extern void l1_cleanup(void);
|
||||
extern int Isdnl1_Init(u_int *);
|
||||
extern void Isdnl1_cleanup(void);
|
||||
extern int Isdnl2_Init(u_int *);
|
||||
extern void Isdnl2_cleanup(void);
|
||||
|
||||
|
||||
@@ -407,7 +407,7 @@ create_l1(struct dchannel *dch, dchannel_l1callback *dcb) {
|
||||
EXPORT_SYMBOL(create_l1);
|
||||
|
||||
int
|
||||
l1_init(u_int *deb)
|
||||
Isdnl1_Init(u_int *deb)
|
||||
{
|
||||
debug = deb;
|
||||
l1fsm_s.state_count = L1S_STATE_COUNT;
|
||||
@@ -418,7 +418,7 @@ l1_init(u_int *deb)
|
||||
}
|
||||
|
||||
void
|
||||
l1_cleanup(void)
|
||||
Isdnl1_cleanup(void)
|
||||
{
|
||||
mISDN_FsmFree(&l1fsm_s);
|
||||
}
|
||||
|
||||
@@ -83,14 +83,16 @@ void inc_children(struct dm_transaction_manager *tm, struct btree_node *n,
|
||||
}
|
||||
|
||||
static int insert_at(size_t value_size, struct btree_node *node, unsigned index,
|
||||
uint64_t key, void *value)
|
||||
__dm_written_to_disk(value)
|
||||
uint64_t key, void *value)
|
||||
__dm_written_to_disk(value)
|
||||
{
|
||||
uint32_t nr_entries = le32_to_cpu(node->header.nr_entries);
|
||||
uint32_t max_entries = le32_to_cpu(node->header.max_entries);
|
||||
__le64 key_le = cpu_to_le64(key);
|
||||
|
||||
if (index > nr_entries ||
|
||||
index >= le32_to_cpu(node->header.max_entries)) {
|
||||
index >= max_entries ||
|
||||
nr_entries >= max_entries) {
|
||||
DMERR("too many entries in btree node for insert");
|
||||
__dm_unbless_for_disk(value);
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -279,6 +279,11 @@ int sm_ll_lookup_bitmap(struct ll_disk *ll, dm_block_t b, uint32_t *result)
|
||||
struct disk_index_entry ie_disk;
|
||||
struct dm_block *blk;
|
||||
|
||||
if (b >= ll->nr_blocks) {
|
||||
DMERR_LIMIT("metadata block out of bounds");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
b = do_div(index, ll->entries_per_block);
|
||||
r = ll->load_ie(ll, index, &ie_disk);
|
||||
if (r < 0)
|
||||
|
||||
@@ -524,7 +524,7 @@ int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv)
|
||||
ERR("out of memory. aborting.\n");
|
||||
kfree(vv);
|
||||
v4l2_ctrl_handler_free(hdl);
|
||||
return -1;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
saa7146_video_uops.init(dev,vv);
|
||||
|
||||
@@ -4842,7 +4842,7 @@ static const struct file_operations dbgfs_filters_fops = {
|
||||
|
||||
int dvb_dmxdev_init(struct dmxdev *dmxdev, struct dvb_adapter *dvb_adapter)
|
||||
{
|
||||
int i;
|
||||
int i, ret;
|
||||
struct dmx_caps caps;
|
||||
|
||||
if (dmxdev->demux->open(dmxdev->demux) < 0)
|
||||
@@ -4865,10 +4865,15 @@ int dvb_dmxdev_init(struct dmxdev *dmxdev, struct dvb_adapter *dvb_adapter)
|
||||
DMXDEV_STATE_FREE);
|
||||
}
|
||||
|
||||
dvb_register_device(dvb_adapter, &dmxdev->dvbdev, &dvbdev_demux, dmxdev,
|
||||
ret = dvb_register_device(dvb_adapter, &dmxdev->dvbdev, &dvbdev_demux, dmxdev,
|
||||
DVB_DEVICE_DEMUX, dmxdev->filternum);
|
||||
dvb_register_device(dvb_adapter, &dmxdev->dvr_dvbdev, &dvbdev_dvr,
|
||||
if (ret < 0)
|
||||
goto err_register_dvbdev;
|
||||
|
||||
ret = dvb_register_device(dvb_adapter, &dmxdev->dvr_dvbdev, &dvbdev_dvr,
|
||||
dmxdev, DVB_DEVICE_DVR, dmxdev->filternum);
|
||||
if (ret < 0)
|
||||
goto err_register_dvr_dvbdev;
|
||||
|
||||
dvb_ringbuffer_init(&dmxdev->dvr_buffer, NULL, 8192);
|
||||
dvb_ringbuffer_init(&dmxdev->dvr_input_buffer, NULL, 8192);
|
||||
@@ -4886,6 +4891,13 @@ int dvb_dmxdev_init(struct dmxdev *dmxdev, struct dvb_adapter *dvb_adapter)
|
||||
&dbgfs_filters_fops);
|
||||
|
||||
return 0;
|
||||
|
||||
err_register_dvr_dvbdev:
|
||||
dvb_unregister_device(dmxdev->dvbdev);
|
||||
err_register_dvbdev:
|
||||
vfree(dmxdev->filter);
|
||||
dmxdev->filter = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(dvb_dmxdev_init);
|
||||
|
||||
@@ -4452,8 +4452,10 @@ static struct dvb_frontend *dib8000_init(struct i2c_adapter *i2c_adap, u8 i2c_ad
|
||||
|
||||
state->timf_default = cfg->pll->timf;
|
||||
|
||||
if (dib8000_identify(&state->i2c) == 0)
|
||||
if (dib8000_identify(&state->i2c) == 0) {
|
||||
kfree(fe);
|
||||
goto error;
|
||||
}
|
||||
|
||||
dibx000_init_i2c_master(&state->i2c_master, DIB8000, state->i2c.adap, state->i2c.addr);
|
||||
|
||||
|
||||
@@ -184,6 +184,8 @@ static irqreturn_t flexcop_pci_isr(int irq, void *dev_id)
|
||||
dma_addr_t cur_addr =
|
||||
fc->read_ibi_reg(fc,dma1_008).dma_0x8.dma_cur_addr << 2;
|
||||
u32 cur_pos = cur_addr - fc_pci->dma[0].dma_addr0;
|
||||
if (cur_pos > fc_pci->dma[0].size * 2)
|
||||
goto error;
|
||||
|
||||
deb_irq("%u irq: %08x cur_addr: %llx: cur_pos: %08x, last_cur_pos: %08x ",
|
||||
jiffies_to_usecs(jiffies - fc_pci->last_irq),
|
||||
@@ -224,6 +226,7 @@ static irqreturn_t flexcop_pci_isr(int irq, void *dev_id)
|
||||
ret = IRQ_NONE;
|
||||
}
|
||||
|
||||
error:
|
||||
spin_unlock_irqrestore(&fc_pci->irq_lock, flags);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -296,7 +296,12 @@ static int hexium_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_d
|
||||
hexium_set_input(hexium, 0);
|
||||
hexium->cur_input = 0;
|
||||
|
||||
saa7146_vv_init(dev, &vv_data);
|
||||
ret = saa7146_vv_init(dev, &vv_data);
|
||||
if (ret) {
|
||||
i2c_del_adapter(&hexium->i2c_adapter);
|
||||
kfree(hexium);
|
||||
return ret;
|
||||
}
|
||||
|
||||
vv_data.vid_ops.vidioc_enum_input = vidioc_enum_input;
|
||||
vv_data.vid_ops.vidioc_g_input = vidioc_g_input;
|
||||
|
||||
@@ -366,10 +366,16 @@ static struct saa7146_ext_vv vv_data;
|
||||
static int hexium_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
|
||||
{
|
||||
struct hexium *hexium = (struct hexium *) dev->ext_priv;
|
||||
int ret;
|
||||
|
||||
DEB_EE("\n");
|
||||
|
||||
saa7146_vv_init(dev, &vv_data);
|
||||
ret = saa7146_vv_init(dev, &vv_data);
|
||||
if (ret) {
|
||||
pr_err("Error in saa7146_vv_init()\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
vv_data.vid_ops.vidioc_enum_input = vidioc_enum_input;
|
||||
vv_data.vid_ops.vidioc_g_input = vidioc_g_input;
|
||||
vv_data.vid_ops.vidioc_s_input = vidioc_s_input;
|
||||
|
||||
@@ -693,10 +693,16 @@ static struct saa7146_ext_vv vv_data;
|
||||
static int mxb_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
|
||||
{
|
||||
struct mxb *mxb;
|
||||
int ret;
|
||||
|
||||
DEB_EE("dev:%p\n", dev);
|
||||
|
||||
saa7146_vv_init(dev, &vv_data);
|
||||
ret = saa7146_vv_init(dev, &vv_data);
|
||||
if (ret) {
|
||||
ERR("Error in saa7146_vv_init()");
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (mxb_probe(dev)) {
|
||||
saa7146_vv_release(dev);
|
||||
return -1;
|
||||
|
||||
@@ -217,11 +217,11 @@ static int fops_vcodec_release(struct file *file)
|
||||
mtk_v4l2_debug(1, "[%d] encoder", ctx->id);
|
||||
mutex_lock(&dev->dev_mutex);
|
||||
|
||||
v4l2_m2m_ctx_release(ctx->m2m_ctx);
|
||||
mtk_vcodec_enc_release(ctx);
|
||||
v4l2_fh_del(&ctx->fh);
|
||||
v4l2_fh_exit(&ctx->fh);
|
||||
v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
|
||||
v4l2_m2m_ctx_release(ctx->m2m_ctx);
|
||||
|
||||
list_del_init(&ctx->list);
|
||||
kfree(ctx);
|
||||
|
||||
@@ -73,9 +73,11 @@ static void igorplugusb_irdata(struct igorplugusb *ir, unsigned len)
|
||||
if (start >= len) {
|
||||
dev_err(ir->dev, "receive overflow invalid: %u", overflow);
|
||||
} else {
|
||||
if (overflow > 0)
|
||||
if (overflow > 0) {
|
||||
dev_warn(ir->dev, "receive overflow, at least %u lost",
|
||||
overflow);
|
||||
ir_raw_event_reset(ir->rc);
|
||||
}
|
||||
|
||||
do {
|
||||
rawir.duration = ir->buf_in[i] * 85333;
|
||||
|
||||
@@ -1116,7 +1116,7 @@ static void mceusb_gen1_init(struct mceusb_dev *ir)
|
||||
*/
|
||||
ret = usb_control_msg(ir->usbdev, usb_rcvctrlpipe(ir->usbdev, 0),
|
||||
USB_REQ_SET_ADDRESS, USB_TYPE_VENDOR, 0, 0,
|
||||
data, USB_CTRL_MSG_SZ, HZ * 3);
|
||||
data, USB_CTRL_MSG_SZ, 3000);
|
||||
dev_dbg(dev, "set address - ret = %d", ret);
|
||||
dev_dbg(dev, "set address - data[0] = %d, data[1] = %d",
|
||||
data[0], data[1]);
|
||||
@@ -1124,20 +1124,20 @@ static void mceusb_gen1_init(struct mceusb_dev *ir)
|
||||
/* set feature: bit rate 38400 bps */
|
||||
ret = usb_control_msg(ir->usbdev, usb_sndctrlpipe(ir->usbdev, 0),
|
||||
USB_REQ_SET_FEATURE, USB_TYPE_VENDOR,
|
||||
0xc04e, 0x0000, NULL, 0, HZ * 3);
|
||||
0xc04e, 0x0000, NULL, 0, 3000);
|
||||
|
||||
dev_dbg(dev, "set feature - ret = %d", ret);
|
||||
|
||||
/* bRequest 4: set char length to 8 bits */
|
||||
ret = usb_control_msg(ir->usbdev, usb_sndctrlpipe(ir->usbdev, 0),
|
||||
4, USB_TYPE_VENDOR,
|
||||
0x0808, 0x0000, NULL, 0, HZ * 3);
|
||||
0x0808, 0x0000, NULL, 0, 3000);
|
||||
dev_dbg(dev, "set char length - retB = %d", ret);
|
||||
|
||||
/* bRequest 2: set handshaking to use DTR/DSR */
|
||||
ret = usb_control_msg(ir->usbdev, usb_sndctrlpipe(ir->usbdev, 0),
|
||||
2, USB_TYPE_VENDOR,
|
||||
0x0000, 0x0100, NULL, 0, HZ * 3);
|
||||
0x0000, 0x0100, NULL, 0, 3000);
|
||||
dev_dbg(dev, "set handshake - retC = %d", ret);
|
||||
|
||||
/* device resume */
|
||||
|
||||
@@ -415,7 +415,7 @@ static int redrat3_send_cmd(int cmd, struct redrat3_dev *rr3)
|
||||
udev = rr3->udev;
|
||||
res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), cmd,
|
||||
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
|
||||
0x0000, 0x0000, data, sizeof(u8), HZ * 10);
|
||||
0x0000, 0x0000, data, sizeof(u8), 10000);
|
||||
|
||||
if (res < 0) {
|
||||
dev_err(rr3->dev, "%s: Error sending rr3 cmd res %d, data %d",
|
||||
@@ -491,7 +491,7 @@ static u32 redrat3_get_timeout(struct redrat3_dev *rr3)
|
||||
pipe = usb_rcvctrlpipe(rr3->udev, 0);
|
||||
ret = usb_control_msg(rr3->udev, pipe, RR3_GET_IR_PARAM,
|
||||
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
|
||||
RR3_IR_IO_SIG_TIMEOUT, 0, tmp, len, HZ * 5);
|
||||
RR3_IR_IO_SIG_TIMEOUT, 0, tmp, len, 5000);
|
||||
if (ret != len)
|
||||
dev_warn(rr3->dev, "Failed to read timeout from hardware\n");
|
||||
else {
|
||||
@@ -521,7 +521,7 @@ static int redrat3_set_timeout(struct rc_dev *rc_dev, unsigned int timeoutns)
|
||||
ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), RR3_SET_IR_PARAM,
|
||||
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
|
||||
RR3_IR_IO_SIG_TIMEOUT, 0, timeout, sizeof(*timeout),
|
||||
HZ * 25);
|
||||
25000);
|
||||
dev_dbg(dev, "set ir parm timeout %d ret 0x%02x\n",
|
||||
be32_to_cpu(*timeout), ret);
|
||||
|
||||
@@ -553,32 +553,32 @@ static void redrat3_reset(struct redrat3_dev *rr3)
|
||||
*val = 0x01;
|
||||
rc = usb_control_msg(udev, rxpipe, RR3_RESET,
|
||||
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
|
||||
RR3_CPUCS_REG_ADDR, 0, val, len, HZ * 25);
|
||||
RR3_CPUCS_REG_ADDR, 0, val, len, 25000);
|
||||
dev_dbg(dev, "reset returned 0x%02x\n", rc);
|
||||
|
||||
*val = length_fuzz;
|
||||
rc = usb_control_msg(udev, txpipe, RR3_SET_IR_PARAM,
|
||||
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
|
||||
RR3_IR_IO_LENGTH_FUZZ, 0, val, len, HZ * 25);
|
||||
RR3_IR_IO_LENGTH_FUZZ, 0, val, len, 25000);
|
||||
dev_dbg(dev, "set ir parm len fuzz %d rc 0x%02x\n", *val, rc);
|
||||
|
||||
*val = (65536 - (minimum_pause * 2000)) / 256;
|
||||
rc = usb_control_msg(udev, txpipe, RR3_SET_IR_PARAM,
|
||||
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
|
||||
RR3_IR_IO_MIN_PAUSE, 0, val, len, HZ * 25);
|
||||
RR3_IR_IO_MIN_PAUSE, 0, val, len, 25000);
|
||||
dev_dbg(dev, "set ir parm min pause %d rc 0x%02x\n", *val, rc);
|
||||
|
||||
*val = periods_measure_carrier;
|
||||
rc = usb_control_msg(udev, txpipe, RR3_SET_IR_PARAM,
|
||||
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
|
||||
RR3_IR_IO_PERIODS_MF, 0, val, len, HZ * 25);
|
||||
RR3_IR_IO_PERIODS_MF, 0, val, len, 25000);
|
||||
dev_dbg(dev, "set ir parm periods measure carrier %d rc 0x%02x", *val,
|
||||
rc);
|
||||
|
||||
*val = RR3_DRIVER_MAXLENS;
|
||||
rc = usb_control_msg(udev, txpipe, RR3_SET_IR_PARAM,
|
||||
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
|
||||
RR3_IR_IO_MAX_LENGTHS, 0, val, len, HZ * 25);
|
||||
RR3_IR_IO_MAX_LENGTHS, 0, val, len, 25000);
|
||||
dev_dbg(dev, "set ir parm max lens %d rc 0x%02x\n", *val, rc);
|
||||
|
||||
kfree(val);
|
||||
@@ -596,7 +596,7 @@ static void redrat3_get_firmware_rev(struct redrat3_dev *rr3)
|
||||
rc = usb_control_msg(rr3->udev, usb_rcvctrlpipe(rr3->udev, 0),
|
||||
RR3_FW_VERSION,
|
||||
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
|
||||
0, 0, buffer, RR3_FW_VERSION_LEN, HZ * 5);
|
||||
0, 0, buffer, RR3_FW_VERSION_LEN, 5000);
|
||||
|
||||
if (rc >= 0)
|
||||
dev_info(rr3->dev, "Firmware rev: %s", buffer);
|
||||
@@ -836,14 +836,14 @@ static int redrat3_transmit_ir(struct rc_dev *rcdev, unsigned *txbuf,
|
||||
|
||||
pipe = usb_sndbulkpipe(rr3->udev, rr3->ep_out->bEndpointAddress);
|
||||
ret = usb_bulk_msg(rr3->udev, pipe, irdata,
|
||||
sendbuf_len, &ret_len, 10 * HZ);
|
||||
sendbuf_len, &ret_len, 10000);
|
||||
dev_dbg(dev, "sent %d bytes, (ret %d)\n", ret_len, ret);
|
||||
|
||||
/* now tell the hardware to transmit what we sent it */
|
||||
pipe = usb_rcvctrlpipe(rr3->udev, 0);
|
||||
ret = usb_control_msg(rr3->udev, pipe, RR3_TX_SEND_SIGNAL,
|
||||
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
|
||||
0, 0, irdata, 2, HZ * 10);
|
||||
0, 0, irdata, 2, 10000);
|
||||
|
||||
if (ret < 0)
|
||||
dev_err(dev, "Error: control msg send failed, rc %d\n", ret);
|
||||
|
||||
@@ -464,6 +464,13 @@ static int msi001_probe(struct spi_device *spi)
|
||||
V4L2_CID_RF_TUNER_BANDWIDTH_AUTO, 0, 1, 1, 1);
|
||||
dev->bandwidth = v4l2_ctrl_new_std(&dev->hdl, &msi001_ctrl_ops,
|
||||
V4L2_CID_RF_TUNER_BANDWIDTH, 200000, 8000000, 1, 200000);
|
||||
if (dev->hdl.error) {
|
||||
ret = dev->hdl.error;
|
||||
dev_err(&spi->dev, "Could not initialize controls\n");
|
||||
/* control init failed, free handler */
|
||||
goto err_ctrl_handler_free;
|
||||
}
|
||||
|
||||
v4l2_ctrl_auto_cluster(2, &dev->bandwidth_auto, 0, false);
|
||||
dev->lna_gain = v4l2_ctrl_new_std(&dev->hdl, &msi001_ctrl_ops,
|
||||
V4L2_CID_RF_TUNER_LNA_GAIN, 0, 1, 1, 1);
|
||||
|
||||
@@ -89,7 +89,7 @@ static int si2157_init(struct dvb_frontend *fe)
|
||||
dev_dbg(&client->dev, "\n");
|
||||
|
||||
/* Try to get Xtal trim property, to verify tuner still running */
|
||||
memcpy(cmd.args, "\x15\x00\x04\x02", 4);
|
||||
memcpy(cmd.args, "\x15\x00\x02\x04", 4);
|
||||
cmd.wlen = 4;
|
||||
cmd.rlen = 4;
|
||||
ret = si2157_cmd_execute(client, &cmd);
|
||||
|
||||
@@ -86,7 +86,7 @@ static int flexcop_usb_readwrite_dw(struct flexcop_device *fc, u16 wRegOffsPCI,
|
||||
0,
|
||||
fc_usb->data,
|
||||
sizeof(u32),
|
||||
B2C2_WAIT_FOR_OPERATION_RDW * HZ);
|
||||
B2C2_WAIT_FOR_OPERATION_RDW);
|
||||
|
||||
if (ret != sizeof(u32)) {
|
||||
err("error while %s dword from %d (%d).", read ? "reading" :
|
||||
@@ -154,7 +154,7 @@ static int flexcop_usb_v8_memory_req(struct flexcop_usb *fc_usb,
|
||||
wIndex,
|
||||
fc_usb->data,
|
||||
buflen,
|
||||
nWaitTime * HZ);
|
||||
nWaitTime);
|
||||
if (ret != buflen)
|
||||
ret = -EIO;
|
||||
|
||||
@@ -248,13 +248,13 @@ static int flexcop_usb_i2c_req(struct flexcop_i2c_adapter *i2c,
|
||||
/* DKT 020208 - add this to support special case of DiSEqC */
|
||||
case USB_FUNC_I2C_CHECKWRITE:
|
||||
pipe = B2C2_USB_CTRL_PIPE_OUT;
|
||||
nWaitTime = 2;
|
||||
nWaitTime = 2000;
|
||||
request_type |= USB_DIR_OUT;
|
||||
break;
|
||||
case USB_FUNC_I2C_READ:
|
||||
case USB_FUNC_I2C_REPEATREAD:
|
||||
pipe = B2C2_USB_CTRL_PIPE_IN;
|
||||
nWaitTime = 2;
|
||||
nWaitTime = 2000;
|
||||
request_type |= USB_DIR_IN;
|
||||
break;
|
||||
default:
|
||||
@@ -281,7 +281,7 @@ static int flexcop_usb_i2c_req(struct flexcop_i2c_adapter *i2c,
|
||||
wIndex,
|
||||
fc_usb->data,
|
||||
buflen,
|
||||
nWaitTime * HZ);
|
||||
nWaitTime);
|
||||
|
||||
if (ret != buflen)
|
||||
ret = -EIO;
|
||||
|
||||
@@ -91,13 +91,13 @@ typedef enum {
|
||||
UTILITY_SRAM_TESTVERIFY = 0x16,
|
||||
} flexcop_usb_utility_function_t;
|
||||
|
||||
#define B2C2_WAIT_FOR_OPERATION_RW (1*HZ)
|
||||
#define B2C2_WAIT_FOR_OPERATION_RDW (3*HZ)
|
||||
#define B2C2_WAIT_FOR_OPERATION_WDW (1*HZ)
|
||||
#define B2C2_WAIT_FOR_OPERATION_RW 1000
|
||||
#define B2C2_WAIT_FOR_OPERATION_RDW 3000
|
||||
#define B2C2_WAIT_FOR_OPERATION_WDW 1000
|
||||
|
||||
#define B2C2_WAIT_FOR_OPERATION_V8READ (3*HZ)
|
||||
#define B2C2_WAIT_FOR_OPERATION_V8WRITE (3*HZ)
|
||||
#define B2C2_WAIT_FOR_OPERATION_V8FLASH (3*HZ)
|
||||
#define B2C2_WAIT_FOR_OPERATION_V8READ 3000
|
||||
#define B2C2_WAIT_FOR_OPERATION_V8WRITE 3000
|
||||
#define B2C2_WAIT_FOR_OPERATION_V8FLASH 3000
|
||||
|
||||
typedef enum {
|
||||
V8_MEMORY_PAGE_DVB_CI = 0x20,
|
||||
|
||||
@@ -559,7 +559,7 @@ static int write_packet(struct usb_device *udev,
|
||||
0, /* index */
|
||||
buf, /* buffer */
|
||||
size,
|
||||
HZ);
|
||||
1000);
|
||||
|
||||
kfree(buf);
|
||||
return ret;
|
||||
@@ -591,7 +591,7 @@ static int read_packet(struct usb_device *udev,
|
||||
0, /* index */
|
||||
buf, /* buffer */
|
||||
size,
|
||||
HZ);
|
||||
1000);
|
||||
|
||||
if (ret >= 0)
|
||||
memcpy(registers, buf, size);
|
||||
|
||||
@@ -619,8 +619,6 @@ int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
|
||||
deb_info("the endpoint number (%i) is not correct, use the adapter id instead", adap->fe_adap[0].stream.props.endpoint);
|
||||
if (onoff)
|
||||
st->channel_state |= 1 << (adap->id);
|
||||
else
|
||||
st->channel_state |= 1 << ~(adap->id);
|
||||
} else {
|
||||
if (onoff)
|
||||
st->channel_state |= 1 << (adap->fe_adap[0].stream.props.endpoint-2);
|
||||
|
||||
@@ -2103,46 +2103,153 @@ static struct dvb_usb_device_properties s6x0_properties = {
|
||||
}
|
||||
};
|
||||
|
||||
static const struct dvb_usb_device_description d1100 = {
|
||||
"Prof 1100 USB ",
|
||||
{&dw2102_table[PROF_1100], NULL},
|
||||
{NULL},
|
||||
static struct dvb_usb_device_properties p1100_properties = {
|
||||
.caps = DVB_USB_IS_AN_I2C_ADAPTER,
|
||||
.usb_ctrl = DEVICE_SPECIFIC,
|
||||
.size_of_priv = sizeof(struct dw2102_state),
|
||||
.firmware = P1100_FIRMWARE,
|
||||
.no_reconnect = 1,
|
||||
|
||||
.i2c_algo = &s6x0_i2c_algo,
|
||||
.rc.core = {
|
||||
.rc_interval = 150,
|
||||
.rc_codes = RC_MAP_TBS_NEC,
|
||||
.module_name = "dw2102",
|
||||
.allowed_protos = RC_PROTO_BIT_NEC,
|
||||
.rc_query = prof_rc_query,
|
||||
},
|
||||
|
||||
.generic_bulk_ctrl_endpoint = 0x81,
|
||||
.num_adapters = 1,
|
||||
.download_firmware = dw2102_load_firmware,
|
||||
.read_mac_address = s6x0_read_mac_address,
|
||||
.adapter = {
|
||||
{
|
||||
.num_frontends = 1,
|
||||
.fe = {{
|
||||
.frontend_attach = stv0288_frontend_attach,
|
||||
.stream = {
|
||||
.type = USB_BULK,
|
||||
.count = 8,
|
||||
.endpoint = 0x82,
|
||||
.u = {
|
||||
.bulk = {
|
||||
.buffersize = 4096,
|
||||
}
|
||||
}
|
||||
},
|
||||
} },
|
||||
}
|
||||
},
|
||||
.num_device_descs = 1,
|
||||
.devices = {
|
||||
{"Prof 1100 USB ",
|
||||
{&dw2102_table[PROF_1100], NULL},
|
||||
{NULL},
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
static const struct dvb_usb_device_description d660 = {
|
||||
"TeVii S660 USB",
|
||||
{&dw2102_table[TEVII_S660], NULL},
|
||||
{NULL},
|
||||
static struct dvb_usb_device_properties s660_properties = {
|
||||
.caps = DVB_USB_IS_AN_I2C_ADAPTER,
|
||||
.usb_ctrl = DEVICE_SPECIFIC,
|
||||
.size_of_priv = sizeof(struct dw2102_state),
|
||||
.firmware = S660_FIRMWARE,
|
||||
.no_reconnect = 1,
|
||||
|
||||
.i2c_algo = &s6x0_i2c_algo,
|
||||
.rc.core = {
|
||||
.rc_interval = 150,
|
||||
.rc_codes = RC_MAP_TEVII_NEC,
|
||||
.module_name = "dw2102",
|
||||
.allowed_protos = RC_PROTO_BIT_NEC,
|
||||
.rc_query = dw2102_rc_query,
|
||||
},
|
||||
|
||||
.generic_bulk_ctrl_endpoint = 0x81,
|
||||
.num_adapters = 1,
|
||||
.download_firmware = dw2102_load_firmware,
|
||||
.read_mac_address = s6x0_read_mac_address,
|
||||
.adapter = {
|
||||
{
|
||||
.num_frontends = 1,
|
||||
.fe = {{
|
||||
.frontend_attach = ds3000_frontend_attach,
|
||||
.stream = {
|
||||
.type = USB_BULK,
|
||||
.count = 8,
|
||||
.endpoint = 0x82,
|
||||
.u = {
|
||||
.bulk = {
|
||||
.buffersize = 4096,
|
||||
}
|
||||
}
|
||||
},
|
||||
} },
|
||||
}
|
||||
},
|
||||
.num_device_descs = 3,
|
||||
.devices = {
|
||||
{"TeVii S660 USB",
|
||||
{&dw2102_table[TEVII_S660], NULL},
|
||||
{NULL},
|
||||
},
|
||||
{"TeVii S480.1 USB",
|
||||
{&dw2102_table[TEVII_S480_1], NULL},
|
||||
{NULL},
|
||||
},
|
||||
{"TeVii S480.2 USB",
|
||||
{&dw2102_table[TEVII_S480_2], NULL},
|
||||
{NULL},
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
static const struct dvb_usb_device_description d480_1 = {
|
||||
"TeVii S480.1 USB",
|
||||
{&dw2102_table[TEVII_S480_1], NULL},
|
||||
{NULL},
|
||||
};
|
||||
static struct dvb_usb_device_properties p7500_properties = {
|
||||
.caps = DVB_USB_IS_AN_I2C_ADAPTER,
|
||||
.usb_ctrl = DEVICE_SPECIFIC,
|
||||
.size_of_priv = sizeof(struct dw2102_state),
|
||||
.firmware = P7500_FIRMWARE,
|
||||
.no_reconnect = 1,
|
||||
|
||||
static const struct dvb_usb_device_description d480_2 = {
|
||||
"TeVii S480.2 USB",
|
||||
{&dw2102_table[TEVII_S480_2], NULL},
|
||||
{NULL},
|
||||
};
|
||||
.i2c_algo = &s6x0_i2c_algo,
|
||||
.rc.core = {
|
||||
.rc_interval = 150,
|
||||
.rc_codes = RC_MAP_TBS_NEC,
|
||||
.module_name = "dw2102",
|
||||
.allowed_protos = RC_PROTO_BIT_NEC,
|
||||
.rc_query = prof_rc_query,
|
||||
},
|
||||
|
||||
static const struct dvb_usb_device_description d7500 = {
|
||||
"Prof 7500 USB DVB-S2",
|
||||
{&dw2102_table[PROF_7500], NULL},
|
||||
{NULL},
|
||||
};
|
||||
|
||||
static const struct dvb_usb_device_description d421 = {
|
||||
"TeVii S421 PCI",
|
||||
{&dw2102_table[TEVII_S421], NULL},
|
||||
{NULL},
|
||||
};
|
||||
|
||||
static const struct dvb_usb_device_description d632 = {
|
||||
"TeVii S632 USB",
|
||||
{&dw2102_table[TEVII_S632], NULL},
|
||||
{NULL},
|
||||
.generic_bulk_ctrl_endpoint = 0x81,
|
||||
.num_adapters = 1,
|
||||
.download_firmware = dw2102_load_firmware,
|
||||
.read_mac_address = s6x0_read_mac_address,
|
||||
.adapter = {
|
||||
{
|
||||
.num_frontends = 1,
|
||||
.fe = {{
|
||||
.frontend_attach = prof_7500_frontend_attach,
|
||||
.stream = {
|
||||
.type = USB_BULK,
|
||||
.count = 8,
|
||||
.endpoint = 0x82,
|
||||
.u = {
|
||||
.bulk = {
|
||||
.buffersize = 4096,
|
||||
}
|
||||
}
|
||||
},
|
||||
} },
|
||||
}
|
||||
},
|
||||
.num_device_descs = 1,
|
||||
.devices = {
|
||||
{"Prof 7500 USB DVB-S2",
|
||||
{&dw2102_table[PROF_7500], NULL},
|
||||
{NULL},
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
static struct dvb_usb_device_properties su3000_properties = {
|
||||
@@ -2214,6 +2321,59 @@ static struct dvb_usb_device_properties su3000_properties = {
|
||||
}
|
||||
};
|
||||
|
||||
static struct dvb_usb_device_properties s421_properties = {
|
||||
.caps = DVB_USB_IS_AN_I2C_ADAPTER,
|
||||
.usb_ctrl = DEVICE_SPECIFIC,
|
||||
.size_of_priv = sizeof(struct dw2102_state),
|
||||
.power_ctrl = su3000_power_ctrl,
|
||||
.num_adapters = 1,
|
||||
.identify_state = su3000_identify_state,
|
||||
.i2c_algo = &su3000_i2c_algo,
|
||||
|
||||
.rc.core = {
|
||||
.rc_interval = 150,
|
||||
.rc_codes = RC_MAP_SU3000,
|
||||
.module_name = "dw2102",
|
||||
.allowed_protos = RC_PROTO_BIT_RC5,
|
||||
.rc_query = su3000_rc_query,
|
||||
},
|
||||
|
||||
.read_mac_address = su3000_read_mac_address,
|
||||
|
||||
.generic_bulk_ctrl_endpoint = 0x01,
|
||||
|
||||
.adapter = {
|
||||
{
|
||||
.num_frontends = 1,
|
||||
.fe = {{
|
||||
.streaming_ctrl = su3000_streaming_ctrl,
|
||||
.frontend_attach = m88rs2000_frontend_attach,
|
||||
.stream = {
|
||||
.type = USB_BULK,
|
||||
.count = 8,
|
||||
.endpoint = 0x82,
|
||||
.u = {
|
||||
.bulk = {
|
||||
.buffersize = 4096,
|
||||
}
|
||||
}
|
||||
}
|
||||
} },
|
||||
}
|
||||
},
|
||||
.num_device_descs = 2,
|
||||
.devices = {
|
||||
{ "TeVii S421 PCI",
|
||||
{ &dw2102_table[TEVII_S421], NULL },
|
||||
{ NULL },
|
||||
},
|
||||
{ "TeVii S632 USB",
|
||||
{ &dw2102_table[TEVII_S632], NULL },
|
||||
{ NULL },
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
static struct dvb_usb_device_properties t220_properties = {
|
||||
.caps = DVB_USB_IS_AN_I2C_ADAPTER,
|
||||
.usb_ctrl = DEVICE_SPECIFIC,
|
||||
@@ -2331,101 +2491,33 @@ static struct dvb_usb_device_properties tt_s2_4600_properties = {
|
||||
static int dw2102_probe(struct usb_interface *intf,
|
||||
const struct usb_device_id *id)
|
||||
{
|
||||
int retval = -ENOMEM;
|
||||
struct dvb_usb_device_properties *p1100;
|
||||
struct dvb_usb_device_properties *s660;
|
||||
struct dvb_usb_device_properties *p7500;
|
||||
struct dvb_usb_device_properties *s421;
|
||||
|
||||
p1100 = kmemdup(&s6x0_properties,
|
||||
sizeof(struct dvb_usb_device_properties), GFP_KERNEL);
|
||||
if (!p1100)
|
||||
goto err0;
|
||||
|
||||
/* copy default structure */
|
||||
/* fill only different fields */
|
||||
p1100->firmware = P1100_FIRMWARE;
|
||||
p1100->devices[0] = d1100;
|
||||
p1100->rc.core.rc_query = prof_rc_query;
|
||||
p1100->rc.core.rc_codes = RC_MAP_TBS_NEC;
|
||||
p1100->adapter->fe[0].frontend_attach = stv0288_frontend_attach;
|
||||
|
||||
s660 = kmemdup(&s6x0_properties,
|
||||
sizeof(struct dvb_usb_device_properties), GFP_KERNEL);
|
||||
if (!s660)
|
||||
goto err1;
|
||||
|
||||
s660->firmware = S660_FIRMWARE;
|
||||
s660->num_device_descs = 3;
|
||||
s660->devices[0] = d660;
|
||||
s660->devices[1] = d480_1;
|
||||
s660->devices[2] = d480_2;
|
||||
s660->adapter->fe[0].frontend_attach = ds3000_frontend_attach;
|
||||
|
||||
p7500 = kmemdup(&s6x0_properties,
|
||||
sizeof(struct dvb_usb_device_properties), GFP_KERNEL);
|
||||
if (!p7500)
|
||||
goto err2;
|
||||
|
||||
p7500->firmware = P7500_FIRMWARE;
|
||||
p7500->devices[0] = d7500;
|
||||
p7500->rc.core.rc_query = prof_rc_query;
|
||||
p7500->rc.core.rc_codes = RC_MAP_TBS_NEC;
|
||||
p7500->adapter->fe[0].frontend_attach = prof_7500_frontend_attach;
|
||||
|
||||
|
||||
s421 = kmemdup(&su3000_properties,
|
||||
sizeof(struct dvb_usb_device_properties), GFP_KERNEL);
|
||||
if (!s421)
|
||||
goto err3;
|
||||
|
||||
s421->num_device_descs = 2;
|
||||
s421->devices[0] = d421;
|
||||
s421->devices[1] = d632;
|
||||
s421->adapter->fe[0].frontend_attach = m88rs2000_frontend_attach;
|
||||
|
||||
if (0 == dvb_usb_device_init(intf, &dw2102_properties,
|
||||
THIS_MODULE, NULL, adapter_nr) ||
|
||||
0 == dvb_usb_device_init(intf, &dw2104_properties,
|
||||
THIS_MODULE, NULL, adapter_nr) ||
|
||||
0 == dvb_usb_device_init(intf, &dw3101_properties,
|
||||
THIS_MODULE, NULL, adapter_nr) ||
|
||||
0 == dvb_usb_device_init(intf, &s6x0_properties,
|
||||
THIS_MODULE, NULL, adapter_nr) ||
|
||||
0 == dvb_usb_device_init(intf, p1100,
|
||||
THIS_MODULE, NULL, adapter_nr) ||
|
||||
0 == dvb_usb_device_init(intf, s660,
|
||||
THIS_MODULE, NULL, adapter_nr) ||
|
||||
0 == dvb_usb_device_init(intf, p7500,
|
||||
THIS_MODULE, NULL, adapter_nr) ||
|
||||
0 == dvb_usb_device_init(intf, s421,
|
||||
THIS_MODULE, NULL, adapter_nr) ||
|
||||
0 == dvb_usb_device_init(intf, &su3000_properties,
|
||||
THIS_MODULE, NULL, adapter_nr) ||
|
||||
0 == dvb_usb_device_init(intf, &t220_properties,
|
||||
THIS_MODULE, NULL, adapter_nr) ||
|
||||
0 == dvb_usb_device_init(intf, &tt_s2_4600_properties,
|
||||
THIS_MODULE, NULL, adapter_nr)) {
|
||||
|
||||
/* clean up copied properties */
|
||||
kfree(s421);
|
||||
kfree(p7500);
|
||||
kfree(s660);
|
||||
kfree(p1100);
|
||||
if (!(dvb_usb_device_init(intf, &dw2102_properties,
|
||||
THIS_MODULE, NULL, adapter_nr) &&
|
||||
dvb_usb_device_init(intf, &dw2104_properties,
|
||||
THIS_MODULE, NULL, adapter_nr) &&
|
||||
dvb_usb_device_init(intf, &dw3101_properties,
|
||||
THIS_MODULE, NULL, adapter_nr) &&
|
||||
dvb_usb_device_init(intf, &s6x0_properties,
|
||||
THIS_MODULE, NULL, adapter_nr) &&
|
||||
dvb_usb_device_init(intf, &p1100_properties,
|
||||
THIS_MODULE, NULL, adapter_nr) &&
|
||||
dvb_usb_device_init(intf, &s660_properties,
|
||||
THIS_MODULE, NULL, adapter_nr) &&
|
||||
dvb_usb_device_init(intf, &p7500_properties,
|
||||
THIS_MODULE, NULL, adapter_nr) &&
|
||||
dvb_usb_device_init(intf, &s421_properties,
|
||||
THIS_MODULE, NULL, adapter_nr) &&
|
||||
dvb_usb_device_init(intf, &su3000_properties,
|
||||
THIS_MODULE, NULL, adapter_nr) &&
|
||||
dvb_usb_device_init(intf, &t220_properties,
|
||||
THIS_MODULE, NULL, adapter_nr) &&
|
||||
dvb_usb_device_init(intf, &tt_s2_4600_properties,
|
||||
THIS_MODULE, NULL, adapter_nr))) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
retval = -ENODEV;
|
||||
kfree(s421);
|
||||
err3:
|
||||
kfree(p7500);
|
||||
err2:
|
||||
kfree(s660);
|
||||
err1:
|
||||
kfree(p1100);
|
||||
err0:
|
||||
return retval;
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static void dw2102_disconnect(struct usb_interface *intf)
|
||||
|
||||
@@ -280,6 +280,13 @@ static int m920x_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int nu
|
||||
/* Should check for ack here, if we knew how. */
|
||||
}
|
||||
if (msg[i].flags & I2C_M_RD) {
|
||||
char *read = kmalloc(1, GFP_KERNEL);
|
||||
if (!read) {
|
||||
ret = -ENOMEM;
|
||||
kfree(read);
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
for (j = 0; j < msg[i].len; j++) {
|
||||
/* Last byte of transaction?
|
||||
* Send STOP, otherwise send ACK. */
|
||||
@@ -287,9 +294,12 @@ static int m920x_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int nu
|
||||
|
||||
if ((ret = m920x_read(d->udev, M9206_I2C, 0x0,
|
||||
0x20 | stop,
|
||||
&msg[i].buf[j], 1)) != 0)
|
||||
read, 1)) != 0)
|
||||
goto unlock;
|
||||
msg[i].buf[j] = read[0];
|
||||
}
|
||||
|
||||
kfree(read);
|
||||
} else {
|
||||
for (j = 0; j < msg[i].len; j++) {
|
||||
/* Last byte of transaction? Then send STOP. */
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user