Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
This commit is contained in:
Коммит
44d84d7272
|
@ -10,12 +10,13 @@ Optional properties:
|
|||
Each button (key) is represented as a sub-node of "gpio-keys":
|
||||
Subnode properties:
|
||||
|
||||
- gpios: OF device-tree gpio specification.
|
||||
- interrupts: the interrupt line for that input.
|
||||
- label: Descriptive name of the key.
|
||||
- linux,code: Keycode to emit.
|
||||
|
||||
Required mutual exclusive subnode-properties:
|
||||
- gpios: OF device-tree gpio specification.
|
||||
- interrupts: the interrupt line for that input
|
||||
Note that either "interrupts" or "gpios" properties can be omitted, but not
|
||||
both at the same time. Specifying both properties is allowed.
|
||||
|
||||
Optional subnode-properties:
|
||||
- linux,input-type: Specify event type this button/key generates.
|
||||
|
@ -23,6 +24,9 @@ Optional subnode-properties:
|
|||
- debounce-interval: Debouncing interval time in milliseconds.
|
||||
If not specified defaults to 5.
|
||||
- gpio-key,wakeup: Boolean, button can wake-up the system.
|
||||
- linux,can-disable: Boolean, indicates that button is connected
|
||||
to dedicated (not shared) interrupt which can be disabled to
|
||||
suppress events from the button.
|
||||
|
||||
Example nodes:
|
||||
|
||||
|
|
|
@ -8,6 +8,8 @@ Optional properties:
|
|||
- debounce-interval : Debouncing interval time in milliseconds
|
||||
- st,scan-count : Scanning cycles elapsed before key data is updated
|
||||
- st,no-autorepeat : If specified device will not autorepeat
|
||||
- keypad,num-rows : See ./matrix-keymap.txt
|
||||
- keypad,num-columns : See ./matrix-keymap.txt
|
||||
|
||||
Example:
|
||||
|
||||
|
|
2
Makefile
2
Makefile
|
@ -1,7 +1,7 @@
|
|||
VERSION = 3
|
||||
PATCHLEVEL = 19
|
||||
SUBLEVEL = 0
|
||||
EXTRAVERSION = -rc2
|
||||
EXTRAVERSION = -rc3
|
||||
NAME = Diseased Newt
|
||||
|
||||
# *DOCUMENTATION*
|
||||
|
|
|
@ -203,27 +203,3 @@
|
|||
compatible = "linux,spdif-dir";
|
||||
};
|
||||
};
|
||||
|
||||
&pinctrl {
|
||||
/*
|
||||
* These pins might be muxed as I2S by
|
||||
* the bootloader, but it conflicts
|
||||
* with the real I2S pins that are
|
||||
* muxed using i2s_pins. We must mux
|
||||
* those pins to a function other than
|
||||
* I2S.
|
||||
*/
|
||||
pinctrl-0 = <&hog_pins1 &hog_pins2>;
|
||||
pinctrl-names = "default";
|
||||
|
||||
hog_pins1: hog-pins1 {
|
||||
marvell,pins = "mpp6", "mpp8", "mpp10",
|
||||
"mpp12", "mpp13";
|
||||
marvell,function = "gpio";
|
||||
};
|
||||
|
||||
hog_pins2: hog-pins2 {
|
||||
marvell,pins = "mpp5", "mpp7", "mpp9";
|
||||
marvell,function = "gpo";
|
||||
};
|
||||
};
|
||||
|
|
|
@ -338,6 +338,7 @@ CONFIG_USB=y
|
|||
CONFIG_USB_XHCI_HCD=y
|
||||
CONFIG_USB_XHCI_MVEBU=y
|
||||
CONFIG_USB_EHCI_HCD=y
|
||||
CONFIG_USB_EHCI_EXYNOS=y
|
||||
CONFIG_USB_EHCI_TEGRA=y
|
||||
CONFIG_USB_EHCI_HCD_STI=y
|
||||
CONFIG_USB_EHCI_HCD_PLATFORM=y
|
||||
|
|
|
@ -1046,6 +1046,15 @@ static int c_show(struct seq_file *m, void *v)
|
|||
seq_printf(m, "model name\t: %s rev %d (%s)\n",
|
||||
cpu_name, cpuid & 15, elf_platform);
|
||||
|
||||
#if defined(CONFIG_SMP)
|
||||
seq_printf(m, "BogoMIPS\t: %lu.%02lu\n",
|
||||
per_cpu(cpu_data, i).loops_per_jiffy / (500000UL/HZ),
|
||||
(per_cpu(cpu_data, i).loops_per_jiffy / (5000UL/HZ)) % 100);
|
||||
#else
|
||||
seq_printf(m, "BogoMIPS\t: %lu.%02lu\n",
|
||||
loops_per_jiffy / (500000/HZ),
|
||||
(loops_per_jiffy / (5000/HZ)) % 100);
|
||||
#endif
|
||||
/* dump out the processor features */
|
||||
seq_puts(m, "Features\t: ");
|
||||
|
||||
|
|
|
@ -387,6 +387,18 @@ asmlinkage void secondary_start_kernel(void)
|
|||
|
||||
void __init smp_cpus_done(unsigned int max_cpus)
|
||||
{
|
||||
int cpu;
|
||||
unsigned long bogosum = 0;
|
||||
|
||||
for_each_online_cpu(cpu)
|
||||
bogosum += per_cpu(cpu_data, cpu).loops_per_jiffy;
|
||||
|
||||
printk(KERN_INFO "SMP: Total of %d processors activated "
|
||||
"(%lu.%02lu BogoMIPS).\n",
|
||||
num_online_cpus(),
|
||||
bogosum / (500000/HZ),
|
||||
(bogosum / (5000/HZ)) % 100);
|
||||
|
||||
hyp_mode_check();
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
|
||||
|
||||
#define NR_syscalls 318 /* length of syscall table */
|
||||
#define NR_syscalls 319 /* length of syscall table */
|
||||
|
||||
/*
|
||||
* The following defines stop scripts/checksyscalls.sh from complaining about
|
||||
|
|
|
@ -331,5 +331,6 @@
|
|||
#define __NR_getrandom 1339
|
||||
#define __NR_memfd_create 1340
|
||||
#define __NR_bpf 1341
|
||||
#define __NR_execveat 1342
|
||||
|
||||
#endif /* _UAPI_ASM_IA64_UNISTD_H */
|
||||
|
|
|
@ -1779,6 +1779,7 @@ sys_call_table:
|
|||
data8 sys_getrandom
|
||||
data8 sys_memfd_create // 1340
|
||||
data8 sys_bpf
|
||||
data8 sys_execveat
|
||||
|
||||
.org sys_call_table + 8*NR_syscalls // guard against failures to increase NR_syscalls
|
||||
#endif /* __IA64_ASM_PARAVIRTUALIZED_NATIVE */
|
||||
|
|
|
@ -72,6 +72,7 @@ void __init setup_cpuinfo(void)
|
|||
cpuinfo.has_div = fcpu_has(cpu, "altr,has-div");
|
||||
cpuinfo.has_mul = fcpu_has(cpu, "altr,has-mul");
|
||||
cpuinfo.has_mulx = fcpu_has(cpu, "altr,has-mulx");
|
||||
cpuinfo.mmu = fcpu_has(cpu, "altr,has-mmu");
|
||||
|
||||
if (IS_ENABLED(CONFIG_NIOS2_HW_DIV_SUPPORT) && !cpuinfo.has_div)
|
||||
err_cpu("DIV");
|
||||
|
|
|
@ -365,30 +365,14 @@ ENTRY(ret_from_interrupt)
|
|||
GET_THREAD_INFO r1
|
||||
ldw r4, TI_PREEMPT_COUNT(r1)
|
||||
bne r4, r0, restore_all
|
||||
|
||||
need_resched:
|
||||
ldw r4, TI_FLAGS(r1) /* ? Need resched set */
|
||||
BTBZ r10, r4, TIF_NEED_RESCHED, restore_all
|
||||
ldw r4, PT_ESTATUS(sp) /* ? Interrupts off */
|
||||
andi r10, r4, ESTATUS_EPIE
|
||||
beq r10, r0, restore_all
|
||||
movia r4, PREEMPT_ACTIVE
|
||||
stw r4, TI_PREEMPT_COUNT(r1)
|
||||
rdctl r10, status /* enable intrs again */
|
||||
ori r10, r10 ,STATUS_PIE
|
||||
wrctl status, r10
|
||||
PUSH r1
|
||||
call schedule
|
||||
POP r1
|
||||
mov r4, r0
|
||||
stw r4, TI_PREEMPT_COUNT(r1)
|
||||
rdctl r10, status /* disable intrs */
|
||||
andi r10, r10, %lo(~STATUS_PIE)
|
||||
wrctl status, r10
|
||||
br need_resched
|
||||
#else
|
||||
br restore_all
|
||||
call preempt_schedule_irq
|
||||
#endif
|
||||
br restore_all
|
||||
|
||||
/***********************************************************************
|
||||
* A few syscall wrappers
|
||||
|
|
|
@ -86,6 +86,11 @@ extern int overlaps_crashkernel(unsigned long start, unsigned long size);
|
|||
extern void reserve_crashkernel(void);
|
||||
extern void machine_kexec_mask_interrupts(void);
|
||||
|
||||
static inline bool kdump_in_progress(void)
|
||||
{
|
||||
return crashing_cpu >= 0;
|
||||
}
|
||||
|
||||
#else /* !CONFIG_KEXEC */
|
||||
static inline void crash_kexec_secondary(struct pt_regs *regs) { }
|
||||
|
||||
|
@ -106,6 +111,11 @@ static inline int crash_shutdown_unregister(crash_shutdown_t handler)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static inline bool kdump_in_progress(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_KEXEC */
|
||||
#endif /* ! __ASSEMBLY__ */
|
||||
#endif /* __KERNEL__ */
|
||||
|
|
|
@ -366,3 +366,4 @@ SYSCALL_SPU(seccomp)
|
|||
SYSCALL_SPU(getrandom)
|
||||
SYSCALL_SPU(memfd_create)
|
||||
SYSCALL_SPU(bpf)
|
||||
COMPAT_SYS(execveat)
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
#include <uapi/asm/unistd.h>
|
||||
|
||||
|
||||
#define __NR_syscalls 362
|
||||
#define __NR_syscalls 363
|
||||
|
||||
#define __NR__exit __NR_exit
|
||||
#define NR_syscalls __NR_syscalls
|
||||
|
|
|
@ -384,5 +384,6 @@
|
|||
#define __NR_getrandom 359
|
||||
#define __NR_memfd_create 360
|
||||
#define __NR_bpf 361
|
||||
#define __NR_execveat 362
|
||||
|
||||
#endif /* _UAPI_ASM_POWERPC_UNISTD_H_ */
|
||||
|
|
|
@ -330,7 +330,7 @@ void default_machine_kexec(struct kimage *image)
|
|||
* using debugger IPI.
|
||||
*/
|
||||
|
||||
if (crashing_cpu == -1)
|
||||
if (!kdump_in_progress())
|
||||
kexec_prepare_cpus();
|
||||
|
||||
pr_debug("kexec: Starting switchover sequence.\n");
|
||||
|
|
|
@ -700,6 +700,7 @@ void start_secondary(void *unused)
|
|||
smp_store_cpu_info(cpu);
|
||||
set_dec(tb_ticks_per_jiffy);
|
||||
preempt_disable();
|
||||
cpu_callin_map[cpu] = 1;
|
||||
|
||||
if (smp_ops->setup_cpu)
|
||||
smp_ops->setup_cpu(cpu);
|
||||
|
@ -738,14 +739,6 @@ void start_secondary(void *unused)
|
|||
notify_cpu_starting(cpu);
|
||||
set_cpu_online(cpu, true);
|
||||
|
||||
/*
|
||||
* CPU must be marked active and online before we signal back to the
|
||||
* master, because the scheduler needs to see the cpu_online and
|
||||
* cpu_active bits set.
|
||||
*/
|
||||
smp_wmb();
|
||||
cpu_callin_map[cpu] = 1;
|
||||
|
||||
local_irq_enable();
|
||||
|
||||
cpu_startup_entry(CPUHP_ONLINE);
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#include <asm/trace.h>
|
||||
#include <asm/firmware.h>
|
||||
#include <asm/plpar_wrappers.h>
|
||||
#include <asm/kexec.h>
|
||||
#include <asm/fadump.h>
|
||||
|
||||
#include "pseries.h"
|
||||
|
@ -267,8 +268,13 @@ static void pSeries_lpar_hptab_clear(void)
|
|||
* out to the user, but at least this will stop us from
|
||||
* continuing on further and creating an even more
|
||||
* difficult to debug situation.
|
||||
*
|
||||
* There is a known problem when kdump'ing, if cpus are offline
|
||||
* the above call will fail. Rather than panicking again, keep
|
||||
* going and hope the kdump kernel is also little endian, which
|
||||
* it usually is.
|
||||
*/
|
||||
if (rc)
|
||||
if (rc && !kdump_in_progress())
|
||||
panic("Could not enable big endian exceptions");
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -3,6 +3,7 @@ config UML
|
|||
default y
|
||||
select HAVE_ARCH_AUDITSYSCALL
|
||||
select HAVE_UID16
|
||||
select HAVE_FUTEX_CMPXCHG if FUTEX
|
||||
select GENERIC_IRQ_SHOW
|
||||
select GENERIC_CPU_DEVICES
|
||||
select GENERIC_IO
|
||||
|
|
|
@ -34,7 +34,7 @@ typedef asmlinkage void (*sys_call_ptr_t)(void);
|
|||
|
||||
extern asmlinkage void sys_ni_syscall(void);
|
||||
|
||||
const sys_call_ptr_t sys_call_table[] __cacheline_aligned = {
|
||||
const sys_call_ptr_t sys_call_table[] ____cacheline_aligned = {
|
||||
/*
|
||||
* Smells like a compiler bug -- it doesn't work
|
||||
* when the & below is removed.
|
||||
|
|
|
@ -47,7 +47,7 @@ typedef void (*sys_call_ptr_t)(void);
|
|||
|
||||
extern void sys_ni_syscall(void);
|
||||
|
||||
const sys_call_ptr_t sys_call_table[] __cacheline_aligned = {
|
||||
const sys_call_ptr_t sys_call_table[] ____cacheline_aligned = {
|
||||
/*
|
||||
* Smells like a compiler bug -- it doesn't work
|
||||
* when the & below is removed.
|
||||
|
|
|
@ -455,6 +455,9 @@ void af_alg_complete(struct crypto_async_request *req, int err)
|
|||
{
|
||||
struct af_alg_completion *completion = req->data;
|
||||
|
||||
if (err == -EINPROGRESS)
|
||||
return;
|
||||
|
||||
completion->err = err;
|
||||
complete(&completion->completion);
|
||||
}
|
||||
|
|
|
@ -969,7 +969,8 @@ static void sender(void *send_info,
|
|||
|
||||
do_gettimeofday(&t);
|
||||
pr_info("**Enqueue %02x %02x: %ld.%6.6ld\n",
|
||||
msg->data[0], msg->data[1], t.tv_sec, t.tv_usec);
|
||||
msg->data[0], msg->data[1],
|
||||
(long) t.tv_sec, (long) t.tv_usec);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -463,7 +463,7 @@ static void __init arch_counter_register(unsigned type)
|
|||
|
||||
/* Register the CP15 based counter if we have one */
|
||||
if (type & ARCH_CP15_TIMER) {
|
||||
if (arch_timer_use_virtual)
|
||||
if (IS_ENABLED(CONFIG_ARM64) || arch_timer_use_virtual)
|
||||
arch_timer_read_counter = arch_counter_get_cntvct;
|
||||
else
|
||||
arch_timer_read_counter = arch_counter_get_cntpct;
|
||||
|
|
|
@ -28,6 +28,13 @@
|
|||
#include <linux/cdev.h>
|
||||
#include "input-compat.h"
|
||||
|
||||
enum evdev_clock_type {
|
||||
EV_CLK_REAL = 0,
|
||||
EV_CLK_MONO,
|
||||
EV_CLK_BOOT,
|
||||
EV_CLK_MAX
|
||||
};
|
||||
|
||||
struct evdev {
|
||||
int open;
|
||||
struct input_handle handle;
|
||||
|
@ -49,12 +56,32 @@ struct evdev_client {
|
|||
struct fasync_struct *fasync;
|
||||
struct evdev *evdev;
|
||||
struct list_head node;
|
||||
int clkid;
|
||||
int clk_type;
|
||||
bool revoked;
|
||||
unsigned int bufsize;
|
||||
struct input_event buffer[];
|
||||
};
|
||||
|
||||
static int evdev_set_clk_type(struct evdev_client *client, unsigned int clkid)
|
||||
{
|
||||
switch (clkid) {
|
||||
|
||||
case CLOCK_REALTIME:
|
||||
client->clk_type = EV_CLK_REAL;
|
||||
break;
|
||||
case CLOCK_MONOTONIC:
|
||||
client->clk_type = EV_CLK_MONO;
|
||||
break;
|
||||
case CLOCK_BOOTTIME:
|
||||
client->clk_type = EV_CLK_BOOT;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* flush queued events of type @type, caller must hold client->buffer_lock */
|
||||
static void __evdev_flush_queue(struct evdev_client *client, unsigned int type)
|
||||
{
|
||||
|
@ -108,8 +135,11 @@ static void evdev_queue_syn_dropped(struct evdev_client *client)
|
|||
struct input_event ev;
|
||||
ktime_t time;
|
||||
|
||||
time = (client->clkid == CLOCK_MONOTONIC) ?
|
||||
ktime_get() : ktime_get_real();
|
||||
time = client->clk_type == EV_CLK_REAL ?
|
||||
ktime_get_real() :
|
||||
client->clk_type == EV_CLK_MONO ?
|
||||
ktime_get() :
|
||||
ktime_get_boottime();
|
||||
|
||||
ev.time = ktime_to_timeval(time);
|
||||
ev.type = EV_SYN;
|
||||
|
@ -159,7 +189,7 @@ static void __pass_event(struct evdev_client *client,
|
|||
|
||||
static void evdev_pass_values(struct evdev_client *client,
|
||||
const struct input_value *vals, unsigned int count,
|
||||
ktime_t mono, ktime_t real)
|
||||
ktime_t *ev_time)
|
||||
{
|
||||
struct evdev *evdev = client->evdev;
|
||||
const struct input_value *v;
|
||||
|
@ -169,8 +199,7 @@ static void evdev_pass_values(struct evdev_client *client,
|
|||
if (client->revoked)
|
||||
return;
|
||||
|
||||
event.time = ktime_to_timeval(client->clkid == CLOCK_MONOTONIC ?
|
||||
mono : real);
|
||||
event.time = ktime_to_timeval(ev_time[client->clk_type]);
|
||||
|
||||
/* Interrupts are disabled, just acquire the lock. */
|
||||
spin_lock(&client->buffer_lock);
|
||||
|
@ -198,21 +227,22 @@ static void evdev_events(struct input_handle *handle,
|
|||
{
|
||||
struct evdev *evdev = handle->private;
|
||||
struct evdev_client *client;
|
||||
ktime_t time_mono, time_real;
|
||||
ktime_t ev_time[EV_CLK_MAX];
|
||||
|
||||
time_mono = ktime_get();
|
||||
time_real = ktime_mono_to_real(time_mono);
|
||||
ev_time[EV_CLK_MONO] = ktime_get();
|
||||
ev_time[EV_CLK_REAL] = ktime_mono_to_real(ev_time[EV_CLK_MONO]);
|
||||
ev_time[EV_CLK_BOOT] = ktime_mono_to_any(ev_time[EV_CLK_MONO],
|
||||
TK_OFFS_BOOT);
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
client = rcu_dereference(evdev->grab);
|
||||
|
||||
if (client)
|
||||
evdev_pass_values(client, vals, count, time_mono, time_real);
|
||||
evdev_pass_values(client, vals, count, ev_time);
|
||||
else
|
||||
list_for_each_entry_rcu(client, &evdev->client_list, node)
|
||||
evdev_pass_values(client, vals, count,
|
||||
time_mono, time_real);
|
||||
evdev_pass_values(client, vals, count, ev_time);
|
||||
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
@ -877,10 +907,8 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd,
|
|||
case EVIOCSCLOCKID:
|
||||
if (copy_from_user(&i, p, sizeof(unsigned int)))
|
||||
return -EFAULT;
|
||||
if (i != CLOCK_MONOTONIC && i != CLOCK_REALTIME)
|
||||
return -EINVAL;
|
||||
client->clkid = i;
|
||||
return 0;
|
||||
|
||||
return evdev_set_clk_type(client, i);
|
||||
|
||||
case EVIOCGKEYCODE:
|
||||
return evdev_handle_get_keycode(dev, p);
|
||||
|
|
|
@ -1974,18 +1974,22 @@ static unsigned int input_estimate_events_per_packet(struct input_dev *dev)
|
|||
|
||||
events = mt_slots + 1; /* count SYN_MT_REPORT and SYN_REPORT */
|
||||
|
||||
for (i = 0; i < ABS_CNT; i++) {
|
||||
if (test_bit(i, dev->absbit)) {
|
||||
if (input_is_mt_axis(i))
|
||||
events += mt_slots;
|
||||
else
|
||||
events++;
|
||||
if (test_bit(EV_ABS, dev->evbit)) {
|
||||
for (i = 0; i < ABS_CNT; i++) {
|
||||
if (test_bit(i, dev->absbit)) {
|
||||
if (input_is_mt_axis(i))
|
||||
events += mt_slots;
|
||||
else
|
||||
events++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < REL_CNT; i++)
|
||||
if (test_bit(i, dev->relbit))
|
||||
events++;
|
||||
if (test_bit(EV_REL, dev->evbit)) {
|
||||
for (i = 0; i < REL_CNT; i++)
|
||||
if (test_bit(i, dev->relbit))
|
||||
events++;
|
||||
}
|
||||
|
||||
/* Make room for KEY and MSC events */
|
||||
events += 7;
|
||||
|
|
|
@ -559,6 +559,7 @@ config KEYBOARD_SH_KEYSC
|
|||
config KEYBOARD_STMPE
|
||||
tristate "STMPE keypad support"
|
||||
depends on MFD_STMPE
|
||||
depends on OF
|
||||
select INPUT_MATRIXKMAP
|
||||
help
|
||||
Say Y here if you want to use the keypad controller on STMPE I/O
|
||||
|
|
|
@ -35,9 +35,13 @@
|
|||
struct gpio_button_data {
|
||||
const struct gpio_keys_button *button;
|
||||
struct input_dev *input;
|
||||
struct timer_list timer;
|
||||
struct work_struct work;
|
||||
unsigned int timer_debounce; /* in msecs */
|
||||
|
||||
struct timer_list release_timer;
|
||||
unsigned int release_delay; /* in msecs, for IRQ-only buttons */
|
||||
|
||||
struct delayed_work work;
|
||||
unsigned int software_debounce; /* in msecs, for GPIO-driven buttons */
|
||||
|
||||
unsigned int irq;
|
||||
spinlock_t lock;
|
||||
bool disabled;
|
||||
|
@ -116,11 +120,14 @@ static void gpio_keys_disable_button(struct gpio_button_data *bdata)
|
|||
{
|
||||
if (!bdata->disabled) {
|
||||
/*
|
||||
* Disable IRQ and possible debouncing timer.
|
||||
* Disable IRQ and associated timer/work structure.
|
||||
*/
|
||||
disable_irq(bdata->irq);
|
||||
if (bdata->timer_debounce)
|
||||
del_timer_sync(&bdata->timer);
|
||||
|
||||
if (gpio_is_valid(bdata->button->gpio))
|
||||
cancel_delayed_work_sync(&bdata->work);
|
||||
else
|
||||
del_timer_sync(&bdata->release_timer);
|
||||
|
||||
bdata->disabled = true;
|
||||
}
|
||||
|
@ -343,7 +350,7 @@ static void gpio_keys_gpio_report_event(struct gpio_button_data *bdata)
|
|||
static void gpio_keys_gpio_work_func(struct work_struct *work)
|
||||
{
|
||||
struct gpio_button_data *bdata =
|
||||
container_of(work, struct gpio_button_data, work);
|
||||
container_of(work, struct gpio_button_data, work.work);
|
||||
|
||||
gpio_keys_gpio_report_event(bdata);
|
||||
|
||||
|
@ -351,13 +358,6 @@ static void gpio_keys_gpio_work_func(struct work_struct *work)
|
|||
pm_relax(bdata->input->dev.parent);
|
||||
}
|
||||
|
||||
static void gpio_keys_gpio_timer(unsigned long _data)
|
||||
{
|
||||
struct gpio_button_data *bdata = (struct gpio_button_data *)_data;
|
||||
|
||||
schedule_work(&bdata->work);
|
||||
}
|
||||
|
||||
static irqreturn_t gpio_keys_gpio_isr(int irq, void *dev_id)
|
||||
{
|
||||
struct gpio_button_data *bdata = dev_id;
|
||||
|
@ -366,11 +366,10 @@ static irqreturn_t gpio_keys_gpio_isr(int irq, void *dev_id)
|
|||
|
||||
if (bdata->button->wakeup)
|
||||
pm_stay_awake(bdata->input->dev.parent);
|
||||
if (bdata->timer_debounce)
|
||||
mod_timer(&bdata->timer,
|
||||
jiffies + msecs_to_jiffies(bdata->timer_debounce));
|
||||
else
|
||||
schedule_work(&bdata->work);
|
||||
|
||||
mod_delayed_work(system_wq,
|
||||
&bdata->work,
|
||||
msecs_to_jiffies(bdata->software_debounce));
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
@ -408,7 +407,7 @@ static irqreturn_t gpio_keys_irq_isr(int irq, void *dev_id)
|
|||
input_event(input, EV_KEY, button->code, 1);
|
||||
input_sync(input);
|
||||
|
||||
if (!bdata->timer_debounce) {
|
||||
if (!bdata->release_delay) {
|
||||
input_event(input, EV_KEY, button->code, 0);
|
||||
input_sync(input);
|
||||
goto out;
|
||||
|
@ -417,9 +416,9 @@ static irqreturn_t gpio_keys_irq_isr(int irq, void *dev_id)
|
|||
bdata->key_pressed = true;
|
||||
}
|
||||
|
||||
if (bdata->timer_debounce)
|
||||
mod_timer(&bdata->timer,
|
||||
jiffies + msecs_to_jiffies(bdata->timer_debounce));
|
||||
if (bdata->release_delay)
|
||||
mod_timer(&bdata->release_timer,
|
||||
jiffies + msecs_to_jiffies(bdata->release_delay));
|
||||
out:
|
||||
spin_unlock_irqrestore(&bdata->lock, flags);
|
||||
return IRQ_HANDLED;
|
||||
|
@ -429,10 +428,10 @@ static void gpio_keys_quiesce_key(void *data)
|
|||
{
|
||||
struct gpio_button_data *bdata = data;
|
||||
|
||||
if (bdata->timer_debounce)
|
||||
del_timer_sync(&bdata->timer);
|
||||
|
||||
cancel_work_sync(&bdata->work);
|
||||
if (gpio_is_valid(bdata->button->gpio))
|
||||
cancel_delayed_work_sync(&bdata->work);
|
||||
else
|
||||
del_timer_sync(&bdata->release_timer);
|
||||
}
|
||||
|
||||
static int gpio_keys_setup_key(struct platform_device *pdev,
|
||||
|
@ -466,23 +465,25 @@ static int gpio_keys_setup_key(struct platform_device *pdev,
|
|||
button->debounce_interval * 1000);
|
||||
/* use timer if gpiolib doesn't provide debounce */
|
||||
if (error < 0)
|
||||
bdata->timer_debounce =
|
||||
bdata->software_debounce =
|
||||
button->debounce_interval;
|
||||
}
|
||||
|
||||
irq = gpio_to_irq(button->gpio);
|
||||
if (irq < 0) {
|
||||
error = irq;
|
||||
dev_err(dev,
|
||||
"Unable to get irq number for GPIO %d, error %d\n",
|
||||
button->gpio, error);
|
||||
return error;
|
||||
if (button->irq) {
|
||||
bdata->irq = button->irq;
|
||||
} else {
|
||||
irq = gpio_to_irq(button->gpio);
|
||||
if (irq < 0) {
|
||||
error = irq;
|
||||
dev_err(dev,
|
||||
"Unable to get irq number for GPIO %d, error %d\n",
|
||||
button->gpio, error);
|
||||
return error;
|
||||
}
|
||||
bdata->irq = irq;
|
||||
}
|
||||
bdata->irq = irq;
|
||||
|
||||
INIT_WORK(&bdata->work, gpio_keys_gpio_work_func);
|
||||
setup_timer(&bdata->timer,
|
||||
gpio_keys_gpio_timer, (unsigned long)bdata);
|
||||
INIT_DELAYED_WORK(&bdata->work, gpio_keys_gpio_work_func);
|
||||
|
||||
isr = gpio_keys_gpio_isr;
|
||||
irqflags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING;
|
||||
|
@ -499,8 +500,8 @@ static int gpio_keys_setup_key(struct platform_device *pdev,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
bdata->timer_debounce = button->debounce_interval;
|
||||
setup_timer(&bdata->timer,
|
||||
bdata->release_delay = button->debounce_interval;
|
||||
setup_timer(&bdata->release_timer,
|
||||
gpio_keys_irq_timer, (unsigned long)bdata);
|
||||
|
||||
isr = gpio_keys_irq_isr;
|
||||
|
@ -510,7 +511,7 @@ static int gpio_keys_setup_key(struct platform_device *pdev,
|
|||
input_set_capability(input, button->type ?: EV_KEY, button->code);
|
||||
|
||||
/*
|
||||
* Install custom action to cancel debounce timer and
|
||||
* Install custom action to cancel release timer and
|
||||
* workqueue item.
|
||||
*/
|
||||
error = devm_add_action(&pdev->dev, gpio_keys_quiesce_key, bdata);
|
||||
|
@ -618,33 +619,30 @@ gpio_keys_get_devtree_pdata(struct device *dev)
|
|||
|
||||
i = 0;
|
||||
for_each_child_of_node(node, pp) {
|
||||
int gpio = -1;
|
||||
enum of_gpio_flags flags;
|
||||
|
||||
button = &pdata->buttons[i++];
|
||||
|
||||
if (!of_find_property(pp, "gpios", NULL)) {
|
||||
button->irq = irq_of_parse_and_map(pp, 0);
|
||||
if (button->irq == 0) {
|
||||
i--;
|
||||
pdata->nbuttons--;
|
||||
dev_warn(dev, "Found button without gpios or irqs\n");
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
gpio = of_get_gpio_flags(pp, 0, &flags);
|
||||
if (gpio < 0) {
|
||||
error = gpio;
|
||||
button->gpio = of_get_gpio_flags(pp, 0, &flags);
|
||||
if (button->gpio < 0) {
|
||||
error = button->gpio;
|
||||
if (error != -ENOENT) {
|
||||
if (error != -EPROBE_DEFER)
|
||||
dev_err(dev,
|
||||
"Failed to get gpio flags, error: %d\n",
|
||||
error);
|
||||
return ERR_PTR(error);
|
||||
}
|
||||
} else {
|
||||
button->active_low = flags & OF_GPIO_ACTIVE_LOW;
|
||||
}
|
||||
|
||||
button->gpio = gpio;
|
||||
button->active_low = flags & OF_GPIO_ACTIVE_LOW;
|
||||
button->irq = irq_of_parse_and_map(pp, 0);
|
||||
|
||||
if (!gpio_is_valid(button->gpio) && !button->irq) {
|
||||
dev_err(dev, "Found button without gpios or irqs\n");
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
if (of_property_read_u32(pp, "linux,code", &button->code)) {
|
||||
dev_err(dev, "Button without keycode: 0x%x\n",
|
||||
|
@ -659,6 +657,8 @@ gpio_keys_get_devtree_pdata(struct device *dev)
|
|||
|
||||
button->wakeup = !!of_get_property(pp, "gpio-key,wakeup", NULL);
|
||||
|
||||
button->can_disable = !!of_get_property(pp, "linux,can-disable", NULL);
|
||||
|
||||
if (of_property_read_u32(pp, "debounce-interval",
|
||||
&button->debounce_interval))
|
||||
button->debounce_interval = 5;
|
||||
|
|
|
@ -473,7 +473,7 @@ static int hil_dev_connect(struct serio *serio, struct serio_driver *drv)
|
|||
if (error)
|
||||
goto bail1;
|
||||
|
||||
init_completion(&dev->cmd_done);
|
||||
reinit_completion(&dev->cmd_done);
|
||||
serio_write(serio, 0);
|
||||
serio_write(serio, 0);
|
||||
serio_write(serio, HIL_PKT_CMD >> 8);
|
||||
|
@ -482,7 +482,7 @@ static int hil_dev_connect(struct serio *serio, struct serio_driver *drv)
|
|||
if (error)
|
||||
goto bail1;
|
||||
|
||||
init_completion(&dev->cmd_done);
|
||||
reinit_completion(&dev->cmd_done);
|
||||
serio_write(serio, 0);
|
||||
serio_write(serio, 0);
|
||||
serio_write(serio, HIL_PKT_CMD >> 8);
|
||||
|
@ -491,7 +491,7 @@ static int hil_dev_connect(struct serio *serio, struct serio_driver *drv)
|
|||
if (error)
|
||||
goto bail1;
|
||||
|
||||
init_completion(&dev->cmd_done);
|
||||
reinit_completion(&dev->cmd_done);
|
||||
serio_write(serio, 0);
|
||||
serio_write(serio, 0);
|
||||
serio_write(serio, HIL_PKT_CMD >> 8);
|
||||
|
|
|
@ -45,13 +45,14 @@
|
|||
#define STMPE_KEYPAD_MAX_ROWS 8
|
||||
#define STMPE_KEYPAD_MAX_COLS 8
|
||||
#define STMPE_KEYPAD_ROW_SHIFT 3
|
||||
#define STMPE_KEYPAD_KEYMAP_SIZE \
|
||||
#define STMPE_KEYPAD_KEYMAP_MAX_SIZE \
|
||||
(STMPE_KEYPAD_MAX_ROWS * STMPE_KEYPAD_MAX_COLS)
|
||||
|
||||
/**
|
||||
* struct stmpe_keypad_variant - model-specific attributes
|
||||
* @auto_increment: whether the KPC_DATA_BYTE register address
|
||||
* auto-increments on multiple read
|
||||
* @set_pullup: whether the pins need to have their pull-ups set
|
||||
* @num_data: number of data bytes
|
||||
* @num_normal_data: number of normal keys' data bytes
|
||||
* @max_cols: maximum number of columns supported
|
||||
|
@ -61,6 +62,7 @@
|
|||
*/
|
||||
struct stmpe_keypad_variant {
|
||||
bool auto_increment;
|
||||
bool set_pullup;
|
||||
int num_data;
|
||||
int num_normal_data;
|
||||
int max_cols;
|
||||
|
@ -81,6 +83,7 @@ static const struct stmpe_keypad_variant stmpe_keypad_variants[] = {
|
|||
},
|
||||
[STMPE2401] = {
|
||||
.auto_increment = false,
|
||||
.set_pullup = true,
|
||||
.num_data = 3,
|
||||
.num_normal_data = 2,
|
||||
.max_cols = 8,
|
||||
|
@ -90,6 +93,7 @@ static const struct stmpe_keypad_variant stmpe_keypad_variants[] = {
|
|||
},
|
||||
[STMPE2403] = {
|
||||
.auto_increment = true,
|
||||
.set_pullup = true,
|
||||
.num_data = 5,
|
||||
.num_normal_data = 3,
|
||||
.max_cols = 8,
|
||||
|
@ -99,16 +103,30 @@ static const struct stmpe_keypad_variant stmpe_keypad_variants[] = {
|
|||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* struct stmpe_keypad - STMPE keypad state container
|
||||
* @stmpe: pointer to parent STMPE device
|
||||
* @input: spawned input device
|
||||
* @variant: STMPE variant
|
||||
* @debounce_ms: debounce interval, in ms. Maximum is
|
||||
* %STMPE_KEYPAD_MAX_DEBOUNCE.
|
||||
* @scan_count: number of key scanning cycles to confirm key data.
|
||||
* Maximum is %STMPE_KEYPAD_MAX_SCAN_COUNT.
|
||||
* @no_autorepeat: disable key autorepeat
|
||||
* @rows: bitmask for the rows
|
||||
* @cols: bitmask for the columns
|
||||
* @keymap: the keymap
|
||||
*/
|
||||
struct stmpe_keypad {
|
||||
struct stmpe *stmpe;
|
||||
struct input_dev *input;
|
||||
const struct stmpe_keypad_variant *variant;
|
||||
const struct stmpe_keypad_platform_data *plat;
|
||||
|
||||
unsigned int debounce_ms;
|
||||
unsigned int scan_count;
|
||||
bool no_autorepeat;
|
||||
unsigned int rows;
|
||||
unsigned int cols;
|
||||
|
||||
unsigned short keymap[STMPE_KEYPAD_KEYMAP_SIZE];
|
||||
unsigned short keymap[STMPE_KEYPAD_KEYMAP_MAX_SIZE];
|
||||
};
|
||||
|
||||
static int stmpe_keypad_read_data(struct stmpe_keypad *keypad, u8 *data)
|
||||
|
@ -171,7 +189,10 @@ static int stmpe_keypad_altfunc_init(struct stmpe_keypad *keypad)
|
|||
unsigned int col_gpios = variant->col_gpios;
|
||||
unsigned int row_gpios = variant->row_gpios;
|
||||
struct stmpe *stmpe = keypad->stmpe;
|
||||
u8 pureg = stmpe->regs[STMPE_IDX_GPPUR_LSB];
|
||||
unsigned int pins = 0;
|
||||
unsigned int pu_pins = 0;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
/*
|
||||
|
@ -188,8 +209,10 @@ static int stmpe_keypad_altfunc_init(struct stmpe_keypad *keypad)
|
|||
for (i = 0; i < variant->max_cols; i++) {
|
||||
int num = __ffs(col_gpios);
|
||||
|
||||
if (keypad->cols & (1 << i))
|
||||
if (keypad->cols & (1 << i)) {
|
||||
pins |= 1 << num;
|
||||
pu_pins |= 1 << num;
|
||||
}
|
||||
|
||||
col_gpios &= ~(1 << num);
|
||||
}
|
||||
|
@ -203,20 +226,43 @@ static int stmpe_keypad_altfunc_init(struct stmpe_keypad *keypad)
|
|||
row_gpios &= ~(1 << num);
|
||||
}
|
||||
|
||||
return stmpe_set_altfunc(stmpe, pins, STMPE_BLOCK_KEYPAD);
|
||||
ret = stmpe_set_altfunc(stmpe, pins, STMPE_BLOCK_KEYPAD);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* On STMPE24xx, set pin bias to pull-up on all keypad input
|
||||
* pins (columns), this incidentally happen to be maximum 8 pins
|
||||
* and placed at GPIO0-7 so only the LSB of the pull up register
|
||||
* ever needs to be written.
|
||||
*/
|
||||
if (variant->set_pullup) {
|
||||
u8 val;
|
||||
|
||||
ret = stmpe_reg_read(stmpe, pureg);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Do not touch unused pins, may be used for GPIO */
|
||||
val = ret & ~pu_pins;
|
||||
val |= pu_pins;
|
||||
|
||||
ret = stmpe_reg_write(stmpe, pureg, val);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stmpe_keypad_chip_init(struct stmpe_keypad *keypad)
|
||||
{
|
||||
const struct stmpe_keypad_platform_data *plat = keypad->plat;
|
||||
const struct stmpe_keypad_variant *variant = keypad->variant;
|
||||
struct stmpe *stmpe = keypad->stmpe;
|
||||
int ret;
|
||||
|
||||
if (plat->debounce_ms > STMPE_KEYPAD_MAX_DEBOUNCE)
|
||||
if (keypad->debounce_ms > STMPE_KEYPAD_MAX_DEBOUNCE)
|
||||
return -EINVAL;
|
||||
|
||||
if (plat->scan_count > STMPE_KEYPAD_MAX_SCAN_COUNT)
|
||||
if (keypad->scan_count > STMPE_KEYPAD_MAX_SCAN_COUNT)
|
||||
return -EINVAL;
|
||||
|
||||
ret = stmpe_enable(stmpe, STMPE_BLOCK_KEYPAD);
|
||||
|
@ -245,7 +291,7 @@ static int stmpe_keypad_chip_init(struct stmpe_keypad *keypad)
|
|||
|
||||
ret = stmpe_set_bits(stmpe, STMPE_KPC_CTRL_MSB,
|
||||
STMPE_KPC_CTRL_MSB_SCAN_COUNT,
|
||||
plat->scan_count << 4);
|
||||
keypad->scan_count << 4);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
@ -253,17 +299,18 @@ static int stmpe_keypad_chip_init(struct stmpe_keypad *keypad)
|
|||
STMPE_KPC_CTRL_LSB_SCAN |
|
||||
STMPE_KPC_CTRL_LSB_DEBOUNCE,
|
||||
STMPE_KPC_CTRL_LSB_SCAN |
|
||||
(plat->debounce_ms << 1));
|
||||
(keypad->debounce_ms << 1));
|
||||
}
|
||||
|
||||
static void stmpe_keypad_fill_used_pins(struct stmpe_keypad *keypad)
|
||||
static void stmpe_keypad_fill_used_pins(struct stmpe_keypad *keypad,
|
||||
u32 used_rows, u32 used_cols)
|
||||
{
|
||||
int row, col;
|
||||
|
||||
for (row = 0; row < STMPE_KEYPAD_MAX_ROWS; row++) {
|
||||
for (col = 0; col < STMPE_KEYPAD_MAX_COLS; col++) {
|
||||
for (row = 0; row < used_rows; row++) {
|
||||
for (col = 0; col < used_cols; col++) {
|
||||
int code = MATRIX_SCAN_CODE(row, col,
|
||||
STMPE_KEYPAD_ROW_SHIFT);
|
||||
STMPE_KEYPAD_ROW_SHIFT);
|
||||
if (keypad->keymap[code] != KEY_RESERVED) {
|
||||
keypad->rows |= 1 << row;
|
||||
keypad->cols |= 1 << col;
|
||||
|
@ -272,51 +319,17 @@ static void stmpe_keypad_fill_used_pins(struct stmpe_keypad *keypad)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static const struct stmpe_keypad_platform_data *
|
||||
stmpe_keypad_of_probe(struct device *dev)
|
||||
{
|
||||
struct device_node *np = dev->of_node;
|
||||
struct stmpe_keypad_platform_data *plat;
|
||||
|
||||
if (!np)
|
||||
return ERR_PTR(-ENODEV);
|
||||
|
||||
plat = devm_kzalloc(dev, sizeof(*plat), GFP_KERNEL);
|
||||
if (!plat)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
of_property_read_u32(np, "debounce-interval", &plat->debounce_ms);
|
||||
of_property_read_u32(np, "st,scan-count", &plat->scan_count);
|
||||
|
||||
plat->no_autorepeat = of_property_read_bool(np, "st,no-autorepeat");
|
||||
|
||||
return plat;
|
||||
}
|
||||
#else
|
||||
static inline const struct stmpe_keypad_platform_data *
|
||||
stmpe_keypad_of_probe(struct device *dev)
|
||||
{
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int stmpe_keypad_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct stmpe *stmpe = dev_get_drvdata(pdev->dev.parent);
|
||||
const struct stmpe_keypad_platform_data *plat;
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
struct stmpe_keypad *keypad;
|
||||
struct input_dev *input;
|
||||
u32 rows;
|
||||
u32 cols;
|
||||
int error;
|
||||
int irq;
|
||||
|
||||
plat = stmpe->pdata->keypad;
|
||||
if (!plat) {
|
||||
plat = stmpe_keypad_of_probe(&pdev->dev);
|
||||
if (IS_ERR(plat))
|
||||
return PTR_ERR(plat);
|
||||
}
|
||||
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq < 0)
|
||||
return irq;
|
||||
|
@ -326,6 +339,13 @@ static int stmpe_keypad_probe(struct platform_device *pdev)
|
|||
if (!keypad)
|
||||
return -ENOMEM;
|
||||
|
||||
keypad->stmpe = stmpe;
|
||||
keypad->variant = &stmpe_keypad_variants[stmpe->partnum];
|
||||
|
||||
of_property_read_u32(np, "debounce-interval", &keypad->debounce_ms);
|
||||
of_property_read_u32(np, "st,scan-count", &keypad->scan_count);
|
||||
keypad->no_autorepeat = of_property_read_bool(np, "st,no-autorepeat");
|
||||
|
||||
input = devm_input_allocate_device(&pdev->dev);
|
||||
if (!input)
|
||||
return -ENOMEM;
|
||||
|
@ -334,23 +354,22 @@ static int stmpe_keypad_probe(struct platform_device *pdev)
|
|||
input->id.bustype = BUS_I2C;
|
||||
input->dev.parent = &pdev->dev;
|
||||
|
||||
error = matrix_keypad_build_keymap(plat->keymap_data, NULL,
|
||||
STMPE_KEYPAD_MAX_ROWS,
|
||||
STMPE_KEYPAD_MAX_COLS,
|
||||
error = matrix_keypad_parse_of_params(&pdev->dev, &rows, &cols);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
error = matrix_keypad_build_keymap(NULL, NULL, rows, cols,
|
||||
keypad->keymap, input);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
input_set_capability(input, EV_MSC, MSC_SCAN);
|
||||
if (!plat->no_autorepeat)
|
||||
if (!keypad->no_autorepeat)
|
||||
__set_bit(EV_REP, input->evbit);
|
||||
|
||||
stmpe_keypad_fill_used_pins(keypad);
|
||||
stmpe_keypad_fill_used_pins(keypad, rows, cols);
|
||||
|
||||
keypad->stmpe = stmpe;
|
||||
keypad->plat = plat;
|
||||
keypad->input = input;
|
||||
keypad->variant = &stmpe_keypad_variants[stmpe->partnum];
|
||||
|
||||
error = stmpe_keypad_chip_init(keypad);
|
||||
if (error < 0)
|
||||
|
|
|
@ -881,6 +881,34 @@ static void alps_get_finger_coordinate_v7(struct input_mt_pos *mt,
|
|||
unsigned char *pkt,
|
||||
unsigned char pkt_id)
|
||||
{
|
||||
/*
|
||||
* packet-fmt b7 b6 b5 b4 b3 b2 b1 b0
|
||||
* Byte0 TWO & MULTI L 1 R M 1 Y0-2 Y0-1 Y0-0
|
||||
* Byte0 NEW L 1 X1-5 1 1 Y0-2 Y0-1 Y0-0
|
||||
* Byte1 Y0-10 Y0-9 Y0-8 Y0-7 Y0-6 Y0-5 Y0-4 Y0-3
|
||||
* Byte2 X0-11 1 X0-10 X0-9 X0-8 X0-7 X0-6 X0-5
|
||||
* Byte3 X1-11 1 X0-4 X0-3 1 X0-2 X0-1 X0-0
|
||||
* Byte4 TWO X1-10 TWO X1-9 X1-8 X1-7 X1-6 X1-5 X1-4
|
||||
* Byte4 MULTI X1-10 TWO X1-9 X1-8 X1-7 X1-6 Y1-5 1
|
||||
* Byte4 NEW X1-10 TWO X1-9 X1-8 X1-7 X1-6 0 0
|
||||
* Byte5 TWO & NEW Y1-10 0 Y1-9 Y1-8 Y1-7 Y1-6 Y1-5 Y1-4
|
||||
* Byte5 MULTI Y1-10 0 Y1-9 Y1-8 Y1-7 Y1-6 F-1 F-0
|
||||
* L: Left button
|
||||
* R / M: Non-clickpads: Right / Middle button
|
||||
* Clickpads: When > 2 fingers are down, and some fingers
|
||||
* are in the button area, then the 2 coordinates reported
|
||||
* are for fingers outside the button area and these report
|
||||
* extra fingers being present in the right / left button
|
||||
* area. Note these fingers are not added to the F field!
|
||||
* so if a TWO packet is received and R = 1 then there are
|
||||
* 3 fingers down, etc.
|
||||
* TWO: 1: Two touches present, byte 0/4/5 are in TWO fmt
|
||||
* 0: If byte 4 bit 0 is 1, then byte 0/4/5 are in MULTI fmt
|
||||
* otherwise byte 0 bit 4 must be set and byte 0/4/5 are
|
||||
* in NEW fmt
|
||||
* F: Number of fingers - 3, 0 means 3 fingers, 1 means 4 ...
|
||||
*/
|
||||
|
||||
mt[0].x = ((pkt[2] & 0x80) << 4);
|
||||
mt[0].x |= ((pkt[2] & 0x3F) << 5);
|
||||
mt[0].x |= ((pkt[3] & 0x30) >> 1);
|
||||
|
@ -919,18 +947,21 @@ static void alps_get_finger_coordinate_v7(struct input_mt_pos *mt,
|
|||
|
||||
static int alps_get_mt_count(struct input_mt_pos *mt)
|
||||
{
|
||||
int i;
|
||||
int i, fingers = 0;
|
||||
|
||||
for (i = 0; i < MAX_TOUCHES && mt[i].x != 0 && mt[i].y != 0; i++)
|
||||
/* empty */;
|
||||
for (i = 0; i < MAX_TOUCHES; i++) {
|
||||
if (mt[i].x != 0 || mt[i].y != 0)
|
||||
fingers++;
|
||||
}
|
||||
|
||||
return i;
|
||||
return fingers;
|
||||
}
|
||||
|
||||
static int alps_decode_packet_v7(struct alps_fields *f,
|
||||
unsigned char *p,
|
||||
struct psmouse *psmouse)
|
||||
{
|
||||
struct alps_data *priv = psmouse->private;
|
||||
unsigned char pkt_id;
|
||||
|
||||
pkt_id = alps_get_packet_id_v7(p);
|
||||
|
@ -938,19 +969,52 @@ static int alps_decode_packet_v7(struct alps_fields *f,
|
|||
return 0;
|
||||
if (pkt_id == V7_PACKET_ID_UNKNOWN)
|
||||
return -1;
|
||||
/*
|
||||
* NEW packets are send to indicate a discontinuity in the finger
|
||||
* coordinate reporting. Specifically a finger may have moved from
|
||||
* slot 0 to 1 or vice versa. INPUT_MT_TRACK takes care of this for
|
||||
* us.
|
||||
*
|
||||
* NEW packets have 3 problems:
|
||||
* 1) They do not contain middle / right button info (on non clickpads)
|
||||
* this can be worked around by preserving the old button state
|
||||
* 2) They do not contain an accurate fingercount, and they are
|
||||
* typically send when the number of fingers changes. We cannot use
|
||||
* the old finger count as that may mismatch with the amount of
|
||||
* touch coordinates we've available in the NEW packet
|
||||
* 3) Their x data for the second touch is inaccurate leading to
|
||||
* a possible jump of the x coordinate by 16 units when the first
|
||||
* non NEW packet comes in
|
||||
* Since problems 2 & 3 cannot be worked around, just ignore them.
|
||||
*/
|
||||
if (pkt_id == V7_PACKET_ID_NEW)
|
||||
return 1;
|
||||
|
||||
alps_get_finger_coordinate_v7(f->mt, p, pkt_id);
|
||||
|
||||
if (pkt_id == V7_PACKET_ID_TWO || pkt_id == V7_PACKET_ID_MULTI) {
|
||||
f->left = (p[0] & 0x80) >> 7;
|
||||
if (pkt_id == V7_PACKET_ID_TWO)
|
||||
f->fingers = alps_get_mt_count(f->mt);
|
||||
else /* pkt_id == V7_PACKET_ID_MULTI */
|
||||
f->fingers = 3 + (p[5] & 0x03);
|
||||
|
||||
f->left = (p[0] & 0x80) >> 7;
|
||||
if (priv->flags & ALPS_BUTTONPAD) {
|
||||
if (p[0] & 0x20)
|
||||
f->fingers++;
|
||||
if (p[0] & 0x10)
|
||||
f->fingers++;
|
||||
} else {
|
||||
f->right = (p[0] & 0x20) >> 5;
|
||||
f->middle = (p[0] & 0x10) >> 4;
|
||||
}
|
||||
|
||||
if (pkt_id == V7_PACKET_ID_TWO)
|
||||
f->fingers = alps_get_mt_count(f->mt);
|
||||
else if (pkt_id == V7_PACKET_ID_MULTI)
|
||||
f->fingers = 3 + (p[5] & 0x03);
|
||||
/* Sometimes a single touch is reported in mt[1] rather then mt[0] */
|
||||
if (f->fingers == 1 && f->mt[0].x == 0 && f->mt[0].y == 0) {
|
||||
f->mt[0].x = f->mt[1].x;
|
||||
f->mt[0].y = f->mt[1].y;
|
||||
f->mt[1].x = 0;
|
||||
f->mt[1].y = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -227,6 +227,7 @@ TRACKPOINT_INT_ATTR(thresh, TP_THRESH, TP_DEF_THRESH);
|
|||
TRACKPOINT_INT_ATTR(upthresh, TP_UP_THRESH, TP_DEF_UP_THRESH);
|
||||
TRACKPOINT_INT_ATTR(ztime, TP_Z_TIME, TP_DEF_Z_TIME);
|
||||
TRACKPOINT_INT_ATTR(jenks, TP_JENKS_CURV, TP_DEF_JENKS_CURV);
|
||||
TRACKPOINT_INT_ATTR(drift_time, TP_DRIFT_TIME, TP_DEF_DRIFT_TIME);
|
||||
|
||||
TRACKPOINT_BIT_ATTR(press_to_select, TP_TOGGLE_PTSON, TP_MASK_PTSON, 0,
|
||||
TP_DEF_PTSON);
|
||||
|
@ -246,6 +247,7 @@ static struct attribute *trackpoint_attrs[] = {
|
|||
&psmouse_attr_upthresh.dattr.attr,
|
||||
&psmouse_attr_ztime.dattr.attr,
|
||||
&psmouse_attr_jenks.dattr.attr,
|
||||
&psmouse_attr_drift_time.dattr.attr,
|
||||
&psmouse_attr_press_to_select.dattr.attr,
|
||||
&psmouse_attr_skipback.dattr.attr,
|
||||
&psmouse_attr_ext_dev.dattr.attr,
|
||||
|
@ -312,6 +314,7 @@ static int trackpoint_sync(struct psmouse *psmouse, bool in_power_on_state)
|
|||
TRACKPOINT_UPDATE(in_power_on_state, psmouse, tp, upthresh);
|
||||
TRACKPOINT_UPDATE(in_power_on_state, psmouse, tp, ztime);
|
||||
TRACKPOINT_UPDATE(in_power_on_state, psmouse, tp, jenks);
|
||||
TRACKPOINT_UPDATE(in_power_on_state, psmouse, tp, drift_time);
|
||||
|
||||
/* toggles */
|
||||
TRACKPOINT_UPDATE(in_power_on_state, psmouse, tp, press_to_select);
|
||||
|
@ -332,6 +335,7 @@ static void trackpoint_defaults(struct trackpoint_data *tp)
|
|||
TRACKPOINT_SET_POWER_ON_DEFAULT(tp, upthresh);
|
||||
TRACKPOINT_SET_POWER_ON_DEFAULT(tp, ztime);
|
||||
TRACKPOINT_SET_POWER_ON_DEFAULT(tp, jenks);
|
||||
TRACKPOINT_SET_POWER_ON_DEFAULT(tp, drift_time);
|
||||
TRACKPOINT_SET_POWER_ON_DEFAULT(tp, inertia);
|
||||
|
||||
/* toggles */
|
||||
|
|
|
@ -70,6 +70,9 @@
|
|||
#define TP_UP_THRESH 0x5A /* Used to generate a 'click' on Z-axis */
|
||||
#define TP_Z_TIME 0x5E /* How sharp of a press */
|
||||
#define TP_JENKS_CURV 0x5D /* Minimum curvature for double click */
|
||||
#define TP_DRIFT_TIME 0x5F /* How long a 'hands off' condition */
|
||||
/* must last (x*107ms) for drift */
|
||||
/* correction to occur */
|
||||
|
||||
/*
|
||||
* Toggling Flag bits
|
||||
|
@ -120,6 +123,7 @@
|
|||
#define TP_DEF_UP_THRESH 0xFF
|
||||
#define TP_DEF_Z_TIME 0x26
|
||||
#define TP_DEF_JENKS_CURV 0x87
|
||||
#define TP_DEF_DRIFT_TIME 0x05
|
||||
|
||||
/* Toggles */
|
||||
#define TP_DEF_MB 0x00
|
||||
|
@ -137,6 +141,7 @@ struct trackpoint_data
|
|||
unsigned char draghys, mindrag;
|
||||
unsigned char thresh, upthresh;
|
||||
unsigned char ztime, jenks;
|
||||
unsigned char drift_time;
|
||||
|
||||
/* toggles */
|
||||
unsigned char press_to_select;
|
||||
|
|
|
@ -99,13 +99,9 @@
|
|||
#define MXT_T6_STATUS_COMSERR (1 << 2)
|
||||
|
||||
/* MXT_GEN_POWER_T7 field */
|
||||
struct t7_config {
|
||||
u8 idle;
|
||||
u8 active;
|
||||
} __packed;
|
||||
|
||||
#define MXT_POWER_CFG_RUN 0
|
||||
#define MXT_POWER_CFG_DEEPSLEEP 1
|
||||
#define MXT_POWER_IDLEACQINT 0
|
||||
#define MXT_POWER_ACTVACQINT 1
|
||||
#define MXT_POWER_ACTV2IDLETO 2
|
||||
|
||||
/* MXT_GEN_ACQUIRE_T8 field */
|
||||
#define MXT_ACQUIRE_CHRGTIME 0
|
||||
|
@ -117,6 +113,7 @@ struct t7_config {
|
|||
#define MXT_ACQUIRE_ATCHCALSTHR 7
|
||||
|
||||
/* MXT_TOUCH_MULTI_T9 field */
|
||||
#define MXT_TOUCH_CTRL 0
|
||||
#define MXT_T9_ORIENT 9
|
||||
#define MXT_T9_RANGE 18
|
||||
|
||||
|
@ -256,7 +253,6 @@ struct mxt_data {
|
|||
bool update_input;
|
||||
u8 last_message_count;
|
||||
u8 num_touchids;
|
||||
struct t7_config t7_cfg;
|
||||
|
||||
/* Cached parameters from object table */
|
||||
u16 T5_address;
|
||||
|
@ -672,6 +668,20 @@ static void mxt_proc_t6_messages(struct mxt_data *data, u8 *msg)
|
|||
data->t6_status = status;
|
||||
}
|
||||
|
||||
static int mxt_write_object(struct mxt_data *data,
|
||||
u8 type, u8 offset, u8 val)
|
||||
{
|
||||
struct mxt_object *object;
|
||||
u16 reg;
|
||||
|
||||
object = mxt_get_object(data, type);
|
||||
if (!object || offset >= mxt_obj_size(object))
|
||||
return -EINVAL;
|
||||
|
||||
reg = object->start_address;
|
||||
return mxt_write_reg(data->client, reg + offset, val);
|
||||
}
|
||||
|
||||
static void mxt_input_button(struct mxt_data *data, u8 *message)
|
||||
{
|
||||
struct input_dev *input = data->input_dev;
|
||||
|
@ -1742,60 +1752,6 @@ err_free_object_table:
|
|||
return error;
|
||||
}
|
||||
|
||||
static int mxt_set_t7_power_cfg(struct mxt_data *data, u8 sleep)
|
||||
{
|
||||
struct device *dev = &data->client->dev;
|
||||
int error;
|
||||
struct t7_config *new_config;
|
||||
struct t7_config deepsleep = { .active = 0, .idle = 0 };
|
||||
|
||||
if (sleep == MXT_POWER_CFG_DEEPSLEEP)
|
||||
new_config = &deepsleep;
|
||||
else
|
||||
new_config = &data->t7_cfg;
|
||||
|
||||
error = __mxt_write_reg(data->client, data->T7_address,
|
||||
sizeof(data->t7_cfg), new_config);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
dev_dbg(dev, "Set T7 ACTV:%d IDLE:%d\n",
|
||||
new_config->active, new_config->idle);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mxt_init_t7_power_cfg(struct mxt_data *data)
|
||||
{
|
||||
struct device *dev = &data->client->dev;
|
||||
int error;
|
||||
bool retry = false;
|
||||
|
||||
recheck:
|
||||
error = __mxt_read_reg(data->client, data->T7_address,
|
||||
sizeof(data->t7_cfg), &data->t7_cfg);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
if (data->t7_cfg.active == 0 || data->t7_cfg.idle == 0) {
|
||||
if (!retry) {
|
||||
dev_dbg(dev, "T7 cfg zero, resetting\n");
|
||||
mxt_soft_reset(data);
|
||||
retry = true;
|
||||
goto recheck;
|
||||
} else {
|
||||
dev_dbg(dev, "T7 cfg zero after reset, overriding\n");
|
||||
data->t7_cfg.active = 20;
|
||||
data->t7_cfg.idle = 100;
|
||||
return mxt_set_t7_power_cfg(data, MXT_POWER_CFG_RUN);
|
||||
}
|
||||
}
|
||||
|
||||
dev_dbg(dev, "Initialized power cfg: ACTV %d, IDLE %d\n",
|
||||
data->t7_cfg.active, data->t7_cfg.idle);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mxt_configure_objects(struct mxt_data *data,
|
||||
const struct firmware *cfg)
|
||||
{
|
||||
|
@ -1809,12 +1765,6 @@ static int mxt_configure_objects(struct mxt_data *data,
|
|||
dev_warn(dev, "Error %d updating config\n", error);
|
||||
}
|
||||
|
||||
error = mxt_init_t7_power_cfg(data);
|
||||
if (error) {
|
||||
dev_err(dev, "Failed to initialize power cfg\n");
|
||||
return error;
|
||||
}
|
||||
|
||||
error = mxt_initialize_t9_input_device(data);
|
||||
if (error)
|
||||
return error;
|
||||
|
@ -2093,15 +2043,16 @@ static const struct attribute_group mxt_attr_group = {
|
|||
|
||||
static void mxt_start(struct mxt_data *data)
|
||||
{
|
||||
mxt_set_t7_power_cfg(data, MXT_POWER_CFG_RUN);
|
||||
|
||||
/* Recalibrate since chip has been in deep sleep */
|
||||
mxt_t6_command(data, MXT_COMMAND_CALIBRATE, 1, false);
|
||||
/* Touch enable */
|
||||
mxt_write_object(data,
|
||||
MXT_TOUCH_MULTI_T9, MXT_TOUCH_CTRL, 0x83);
|
||||
}
|
||||
|
||||
static void mxt_stop(struct mxt_data *data)
|
||||
{
|
||||
mxt_set_t7_power_cfg(data, MXT_POWER_CFG_DEEPSLEEP);
|
||||
/* Touch disable */
|
||||
mxt_write_object(data,
|
||||
MXT_TOUCH_MULTI_T9, MXT_TOUCH_CTRL, 0);
|
||||
}
|
||||
|
||||
static int mxt_input_open(struct input_dev *dev)
|
||||
|
@ -2266,6 +2217,8 @@ static int __maybe_unused mxt_resume(struct device *dev)
|
|||
struct mxt_data *data = i2c_get_clientdata(client);
|
||||
struct input_dev *input_dev = data->input_dev;
|
||||
|
||||
mxt_soft_reset(data);
|
||||
|
||||
mutex_lock(&input_dev->mutex);
|
||||
|
||||
if (input_dev->users)
|
||||
|
|
|
@ -850,9 +850,11 @@ static int edt_ft5x06_ts_identify(struct i2c_client *client,
|
|||
}
|
||||
|
||||
#define EDT_ATTR_CHECKSET(name, reg) \
|
||||
do { \
|
||||
if (pdata->name >= edt_ft5x06_attr_##name.limit_low && \
|
||||
pdata->name <= edt_ft5x06_attr_##name.limit_high) \
|
||||
edt_ft5x06_register_write(tsdata, reg, pdata->name)
|
||||
edt_ft5x06_register_write(tsdata, reg, pdata->name); \
|
||||
} while (0)
|
||||
|
||||
#define EDT_GET_PROP(name, reg) { \
|
||||
u32 val; \
|
||||
|
|
|
@ -519,6 +519,7 @@ static const u8 stmpe1601_regs[] = {
|
|||
[STMPE_IDX_GPDR_LSB] = STMPE1601_REG_GPIO_SET_DIR_LSB,
|
||||
[STMPE_IDX_GPRER_LSB] = STMPE1601_REG_GPIO_RE_LSB,
|
||||
[STMPE_IDX_GPFER_LSB] = STMPE1601_REG_GPIO_FE_LSB,
|
||||
[STMPE_IDX_GPPUR_LSB] = STMPE1601_REG_GPIO_PU_LSB,
|
||||
[STMPE_IDX_GPAFR_U_MSB] = STMPE1601_REG_GPIO_AF_U_MSB,
|
||||
[STMPE_IDX_IEGPIOR_LSB] = STMPE1601_REG_INT_EN_GPIO_MASK_LSB,
|
||||
[STMPE_IDX_ISGPIOR_MSB] = STMPE1601_REG_INT_STA_GPIO_MSB,
|
||||
|
@ -667,6 +668,7 @@ static const u8 stmpe1801_regs[] = {
|
|||
[STMPE_IDX_GPDR_LSB] = STMPE1801_REG_GPIO_SET_DIR_LOW,
|
||||
[STMPE_IDX_GPRER_LSB] = STMPE1801_REG_GPIO_RE_LOW,
|
||||
[STMPE_IDX_GPFER_LSB] = STMPE1801_REG_GPIO_FE_LOW,
|
||||
[STMPE_IDX_GPPUR_LSB] = STMPE1801_REG_GPIO_PULL_UP_LOW,
|
||||
[STMPE_IDX_IEGPIOR_LSB] = STMPE1801_REG_INT_EN_GPIO_MASK_LOW,
|
||||
[STMPE_IDX_ISGPIOR_LSB] = STMPE1801_REG_INT_STA_GPIO_LOW,
|
||||
};
|
||||
|
@ -750,6 +752,8 @@ static const u8 stmpe24xx_regs[] = {
|
|||
[STMPE_IDX_GPDR_LSB] = STMPE24XX_REG_GPDR_LSB,
|
||||
[STMPE_IDX_GPRER_LSB] = STMPE24XX_REG_GPRER_LSB,
|
||||
[STMPE_IDX_GPFER_LSB] = STMPE24XX_REG_GPFER_LSB,
|
||||
[STMPE_IDX_GPPUR_LSB] = STMPE24XX_REG_GPPUR_LSB,
|
||||
[STMPE_IDX_GPPDR_LSB] = STMPE24XX_REG_GPPDR_LSB,
|
||||
[STMPE_IDX_GPAFR_U_MSB] = STMPE24XX_REG_GPAFR_U_MSB,
|
||||
[STMPE_IDX_IEGPIOR_LSB] = STMPE24XX_REG_IEGPIOR_LSB,
|
||||
[STMPE_IDX_ISGPIOR_MSB] = STMPE24XX_REG_ISGPIOR_MSB,
|
||||
|
|
|
@ -188,6 +188,7 @@ int stmpe_remove(struct stmpe *stmpe);
|
|||
#define STMPE1601_REG_GPIO_ED_MSB 0x8A
|
||||
#define STMPE1601_REG_GPIO_RE_LSB 0x8D
|
||||
#define STMPE1601_REG_GPIO_FE_LSB 0x8F
|
||||
#define STMPE1601_REG_GPIO_PU_LSB 0x91
|
||||
#define STMPE1601_REG_GPIO_AF_U_MSB 0x92
|
||||
|
||||
#define STMPE1601_SYS_CTRL_ENABLE_GPIO (1 << 3)
|
||||
|
@ -276,6 +277,8 @@ int stmpe_remove(struct stmpe *stmpe);
|
|||
#define STMPE24XX_REG_GPEDR_MSB 0x8C
|
||||
#define STMPE24XX_REG_GPRER_LSB 0x91
|
||||
#define STMPE24XX_REG_GPFER_LSB 0x94
|
||||
#define STMPE24XX_REG_GPPUR_LSB 0x97
|
||||
#define STMPE24XX_REG_GPPDR_LSB 0x9a
|
||||
#define STMPE24XX_REG_GPAFR_U_MSB 0x9B
|
||||
|
||||
#define STMPE24XX_SYS_CTRL_ENABLE_GPIO (1 << 3)
|
||||
|
|
|
@ -850,8 +850,10 @@ static int emac_probe(struct platform_device *pdev)
|
|||
}
|
||||
|
||||
db->clk = devm_clk_get(&pdev->dev, NULL);
|
||||
if (IS_ERR(db->clk))
|
||||
if (IS_ERR(db->clk)) {
|
||||
ret = PTR_ERR(db->clk);
|
||||
goto out;
|
||||
}
|
||||
|
||||
clk_prepare_enable(db->clk);
|
||||
|
||||
|
|
|
@ -1170,10 +1170,6 @@ tx_request_irq_error:
|
|||
init_error:
|
||||
free_skbufs(dev);
|
||||
alloc_skbuf_error:
|
||||
if (priv->phydev) {
|
||||
phy_disconnect(priv->phydev);
|
||||
priv->phydev = NULL;
|
||||
}
|
||||
phy_error:
|
||||
return ret;
|
||||
}
|
||||
|
@ -1186,12 +1182,9 @@ static int tse_shutdown(struct net_device *dev)
|
|||
int ret;
|
||||
unsigned long int flags;
|
||||
|
||||
/* Stop and disconnect the PHY */
|
||||
if (priv->phydev) {
|
||||
/* Stop the PHY */
|
||||
if (priv->phydev)
|
||||
phy_stop(priv->phydev);
|
||||
phy_disconnect(priv->phydev);
|
||||
priv->phydev = NULL;
|
||||
}
|
||||
|
||||
netif_stop_queue(dev);
|
||||
napi_disable(&priv->napi);
|
||||
|
@ -1525,6 +1518,10 @@ err_free_netdev:
|
|||
static int altera_tse_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct net_device *ndev = platform_get_drvdata(pdev);
|
||||
struct altera_tse_private *priv = netdev_priv(ndev);
|
||||
|
||||
if (priv->phydev)
|
||||
phy_disconnect(priv->phydev);
|
||||
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
altera_tse_mdio_destroy(ndev);
|
||||
|
|
|
@ -1653,7 +1653,7 @@ static int enic_open(struct net_device *netdev)
|
|||
if (vnic_rq_desc_used(&enic->rq[i]) == 0) {
|
||||
netdev_err(netdev, "Unable to alloc receive buffers\n");
|
||||
err = -ENOMEM;
|
||||
goto err_out_notify_unset;
|
||||
goto err_out_free_rq;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1686,7 +1686,9 @@ static int enic_open(struct net_device *netdev)
|
|||
|
||||
return 0;
|
||||
|
||||
err_out_notify_unset:
|
||||
err_out_free_rq:
|
||||
for (i = 0; i < enic->rq_count; i++)
|
||||
vnic_rq_clean(&enic->rq[i], enic_free_rq_buf);
|
||||
enic_dev_notify_unset(enic);
|
||||
err_out_free_intr:
|
||||
enic_free_intr(enic);
|
||||
|
|
|
@ -1543,7 +1543,7 @@ static int e100_phy_init(struct nic *nic)
|
|||
mdio_write(netdev, nic->mii.phy_id, MII_BMCR, bmcr);
|
||||
} else if ((nic->mac >= mac_82550_D102) || ((nic->flags & ich) &&
|
||||
(mdio_read(netdev, nic->mii.phy_id, MII_TPISTATUS) & 0x8000) &&
|
||||
!(nic->eeprom[eeprom_cnfg_mdix] & eeprom_mdix_enabled))) {
|
||||
(nic->eeprom[eeprom_cnfg_mdix] & eeprom_mdix_enabled))) {
|
||||
/* enable/disable MDI/MDI-X auto-switching. */
|
||||
mdio_write(netdev, nic->mii.phy_id, MII_NCONFIG,
|
||||
nic->mii.force_media ? 0 : NCONFIG_AUTO_SWITCH);
|
||||
|
|
|
@ -829,7 +829,7 @@ static void i40e_dbg_dump_desc(int cnt, int vsi_seid, int ring_id, int desc_n,
|
|||
if (desc_n >= ring->count || desc_n < 0) {
|
||||
dev_info(&pf->pdev->dev,
|
||||
"descriptor %d not found\n", desc_n);
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
if (!is_rx_ring) {
|
||||
txd = I40E_TX_DESC(ring, desc_n);
|
||||
|
@ -855,6 +855,8 @@ static void i40e_dbg_dump_desc(int cnt, int vsi_seid, int ring_id, int desc_n,
|
|||
} else {
|
||||
dev_info(&pf->pdev->dev, "dump desc rx/tx <vsi_seid> <ring_id> [<desc_n>]\n");
|
||||
}
|
||||
|
||||
out:
|
||||
kfree(ring);
|
||||
}
|
||||
|
||||
|
|
|
@ -1125,7 +1125,7 @@ static s32 igb_acquire_swfw_sync_82575(struct e1000_hw *hw, u16 mask)
|
|||
u32 swmask = mask;
|
||||
u32 fwmask = mask << 16;
|
||||
s32 ret_val = 0;
|
||||
s32 i = 0, timeout = 200; /* FIXME: find real value to use here */
|
||||
s32 i = 0, timeout = 200;
|
||||
|
||||
while (i < timeout) {
|
||||
if (igb_get_hw_semaphore(hw)) {
|
||||
|
|
|
@ -1829,7 +1829,7 @@ static int mlx4_init_hca(struct mlx4_dev *dev)
|
|||
err = mlx4_dev_cap(dev, &dev_cap);
|
||||
if (err) {
|
||||
mlx4_err(dev, "QUERY_DEV_CAP command failed, aborting\n");
|
||||
goto err_stop_fw;
|
||||
return err;
|
||||
}
|
||||
|
||||
choose_steering_mode(dev, &dev_cap);
|
||||
|
@ -1860,7 +1860,7 @@ static int mlx4_init_hca(struct mlx4_dev *dev)
|
|||
&init_hca);
|
||||
if ((long long) icm_size < 0) {
|
||||
err = icm_size;
|
||||
goto err_stop_fw;
|
||||
return err;
|
||||
}
|
||||
|
||||
dev->caps.max_fmr_maps = (1 << (32 - ilog2(dev->caps.num_mpts))) - 1;
|
||||
|
@ -1874,7 +1874,7 @@ static int mlx4_init_hca(struct mlx4_dev *dev)
|
|||
|
||||
err = mlx4_init_icm(dev, &dev_cap, &init_hca, icm_size);
|
||||
if (err)
|
||||
goto err_stop_fw;
|
||||
return err;
|
||||
|
||||
err = mlx4_INIT_HCA(dev, &init_hca);
|
||||
if (err) {
|
||||
|
@ -1886,7 +1886,7 @@ static int mlx4_init_hca(struct mlx4_dev *dev)
|
|||
err = mlx4_query_func(dev, &dev_cap);
|
||||
if (err < 0) {
|
||||
mlx4_err(dev, "QUERY_FUNC command failed, aborting.\n");
|
||||
goto err_stop_fw;
|
||||
goto err_close;
|
||||
} else if (err & MLX4_QUERY_FUNC_NUM_SYS_EQS) {
|
||||
dev->caps.num_eqs = dev_cap.max_eqs;
|
||||
dev->caps.reserved_eqs = dev_cap.reserved_eqs;
|
||||
|
@ -2006,11 +2006,6 @@ err_free_icm:
|
|||
if (!mlx4_is_slave(dev))
|
||||
mlx4_free_icms(dev);
|
||||
|
||||
err_stop_fw:
|
||||
if (!mlx4_is_slave(dev)) {
|
||||
mlx4_UNMAP_FA(dev);
|
||||
mlx4_free_icm(dev, priv->fw.fw_icm, 0);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
|
|
|
@ -584,6 +584,7 @@ EXPORT_SYMBOL_GPL(mlx4_mr_free);
|
|||
void mlx4_mr_rereg_mem_cleanup(struct mlx4_dev *dev, struct mlx4_mr *mr)
|
||||
{
|
||||
mlx4_mtt_cleanup(dev, &mr->mtt);
|
||||
mr->mtt.order = -1;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mlx4_mr_rereg_mem_cleanup);
|
||||
|
||||
|
@ -593,14 +594,14 @@ int mlx4_mr_rereg_mem_write(struct mlx4_dev *dev, struct mlx4_mr *mr,
|
|||
{
|
||||
int err;
|
||||
|
||||
mpt_entry->start = cpu_to_be64(iova);
|
||||
mpt_entry->length = cpu_to_be64(size);
|
||||
mpt_entry->entity_size = cpu_to_be32(page_shift);
|
||||
|
||||
err = mlx4_mtt_init(dev, npages, page_shift, &mr->mtt);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
mpt_entry->start = cpu_to_be64(mr->iova);
|
||||
mpt_entry->length = cpu_to_be64(mr->size);
|
||||
mpt_entry->entity_size = cpu_to_be32(mr->mtt.page_shift);
|
||||
|
||||
mpt_entry->pd_flags &= cpu_to_be32(MLX4_MPT_PD_MASK |
|
||||
MLX4_MPT_PD_FLAG_EN_INV);
|
||||
mpt_entry->flags &= cpu_to_be32(MLX4_MPT_FLAG_FREE |
|
||||
|
|
|
@ -4033,8 +4033,10 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
(void)pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
|
||||
mgp->cmd = dma_alloc_coherent(&pdev->dev, sizeof(*mgp->cmd),
|
||||
&mgp->cmd_bus, GFP_KERNEL);
|
||||
if (mgp->cmd == NULL)
|
||||
if (!mgp->cmd) {
|
||||
status = -ENOMEM;
|
||||
goto abort_with_enabled;
|
||||
}
|
||||
|
||||
mgp->board_span = pci_resource_len(pdev, 0);
|
||||
mgp->iomem_base = pci_resource_start(pdev, 0);
|
||||
|
|
|
@ -146,10 +146,7 @@ static int ql_wait_for_drvr_lock(struct ql3_adapter *qdev)
|
|||
{
|
||||
int i = 0;
|
||||
|
||||
while (i < 10) {
|
||||
if (i)
|
||||
ssleep(1);
|
||||
|
||||
do {
|
||||
if (ql_sem_lock(qdev,
|
||||
QL_DRVR_SEM_MASK,
|
||||
(QL_RESOURCE_BITS_BASE_CODE | (qdev->mac_index)
|
||||
|
@ -158,7 +155,8 @@ static int ql_wait_for_drvr_lock(struct ql3_adapter *qdev)
|
|||
"driver lock acquired\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
ssleep(1);
|
||||
} while (++i < 10);
|
||||
|
||||
netdev_err(qdev->ndev, "Timed out waiting for driver lock...\n");
|
||||
return 0;
|
||||
|
|
|
@ -2605,6 +2605,7 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
} else {
|
||||
dev_err(&pdev->dev,
|
||||
"%s: failed. Please Reboot\n", __func__);
|
||||
err = -ENODEV;
|
||||
goto err_out_free_hw;
|
||||
}
|
||||
|
||||
|
|
|
@ -757,6 +757,14 @@ requeue:
|
|||
static irqreturn_t cpsw_interrupt(int irq, void *dev_id)
|
||||
{
|
||||
struct cpsw_priv *priv = dev_id;
|
||||
int value = irq - priv->irqs_table[0];
|
||||
|
||||
/* NOTICE: Ending IRQ here. The trick with the 'value' variable above
|
||||
* is to make sure we will always write the correct value to the EOI
|
||||
* register. Namely 0 for RX_THRESH Interrupt, 1 for RX Interrupt, 2
|
||||
* for TX Interrupt and 3 for MISC Interrupt.
|
||||
*/
|
||||
cpdma_ctlr_eoi(priv->dma, value);
|
||||
|
||||
cpsw_intr_disable(priv);
|
||||
if (priv->irq_enabled == true) {
|
||||
|
@ -786,8 +794,6 @@ static int cpsw_poll(struct napi_struct *napi, int budget)
|
|||
int num_tx, num_rx;
|
||||
|
||||
num_tx = cpdma_chan_process(priv->txch, 128);
|
||||
if (num_tx)
|
||||
cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_TX);
|
||||
|
||||
num_rx = cpdma_chan_process(priv->rxch, budget);
|
||||
if (num_rx < budget) {
|
||||
|
@ -795,7 +801,6 @@ static int cpsw_poll(struct napi_struct *napi, int budget)
|
|||
|
||||
napi_complete(napi);
|
||||
cpsw_intr_enable(priv);
|
||||
cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_RX);
|
||||
prim_cpsw = cpsw_get_slave_priv(priv, 0);
|
||||
if (prim_cpsw->irq_enabled == false) {
|
||||
prim_cpsw->irq_enabled = true;
|
||||
|
@ -1310,8 +1315,6 @@ static int cpsw_ndo_open(struct net_device *ndev)
|
|||
napi_enable(&priv->napi);
|
||||
cpdma_ctlr_start(priv->dma);
|
||||
cpsw_intr_enable(priv);
|
||||
cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_RX);
|
||||
cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_TX);
|
||||
|
||||
prim_cpsw = cpsw_get_slave_priv(priv, 0);
|
||||
if (prim_cpsw->irq_enabled == false) {
|
||||
|
@ -1578,9 +1581,6 @@ static void cpsw_ndo_tx_timeout(struct net_device *ndev)
|
|||
cpdma_chan_start(priv->txch);
|
||||
cpdma_ctlr_int_ctrl(priv->dma, true);
|
||||
cpsw_intr_enable(priv);
|
||||
cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_RX);
|
||||
cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_TX);
|
||||
|
||||
}
|
||||
|
||||
static int cpsw_ndo_set_mac_address(struct net_device *ndev, void *p)
|
||||
|
@ -1620,9 +1620,6 @@ static void cpsw_ndo_poll_controller(struct net_device *ndev)
|
|||
cpsw_interrupt(ndev->irq, priv);
|
||||
cpdma_ctlr_int_ctrl(priv->dma, true);
|
||||
cpsw_intr_enable(priv);
|
||||
cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_RX);
|
||||
cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_TX);
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1043,6 +1043,7 @@ static int temac_of_probe(struct platform_device *op)
|
|||
lp->regs = of_iomap(op->dev.of_node, 0);
|
||||
if (!lp->regs) {
|
||||
dev_err(&op->dev, "could not map temac regs.\n");
|
||||
rc = -ENOMEM;
|
||||
goto nodev;
|
||||
}
|
||||
|
||||
|
@ -1062,6 +1063,7 @@ static int temac_of_probe(struct platform_device *op)
|
|||
np = of_parse_phandle(op->dev.of_node, "llink-connected", 0);
|
||||
if (!np) {
|
||||
dev_err(&op->dev, "could not find DMA node\n");
|
||||
rc = -ENODEV;
|
||||
goto err_iounmap;
|
||||
}
|
||||
|
||||
|
|
|
@ -1501,6 +1501,7 @@ static int axienet_of_probe(struct platform_device *op)
|
|||
lp->regs = of_iomap(op->dev.of_node, 0);
|
||||
if (!lp->regs) {
|
||||
dev_err(&op->dev, "could not map Axi Ethernet regs.\n");
|
||||
ret = -ENOMEM;
|
||||
goto nodev;
|
||||
}
|
||||
/* Setup checksum offload, but default to off if not specified */
|
||||
|
@ -1563,6 +1564,7 @@ static int axienet_of_probe(struct platform_device *op)
|
|||
np = of_parse_phandle(op->dev.of_node, "axistream-connected", 0);
|
||||
if (!np) {
|
||||
dev_err(&op->dev, "could not find DMA node\n");
|
||||
ret = -ENODEV;
|
||||
goto err_iounmap;
|
||||
}
|
||||
lp->dma_regs = of_iomap(np, 0);
|
||||
|
|
|
@ -1109,6 +1109,7 @@ static int xemaclite_of_probe(struct platform_device *ofdev)
|
|||
res = platform_get_resource(ofdev, IORESOURCE_IRQ, 0);
|
||||
if (!res) {
|
||||
dev_err(dev, "no IRQ found\n");
|
||||
rc = -ENXIO;
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
|
|
@ -56,6 +56,8 @@ struct qmi_wwan_state {
|
|||
/* default ethernet address used by the modem */
|
||||
static const u8 default_modem_addr[ETH_ALEN] = {0x02, 0x50, 0xf3};
|
||||
|
||||
static const u8 buggy_fw_addr[ETH_ALEN] = {0x00, 0xa0, 0xc6, 0x00, 0x00, 0x00};
|
||||
|
||||
/* Make up an ethernet header if the packet doesn't have one.
|
||||
*
|
||||
* A firmware bug common among several devices cause them to send raw
|
||||
|
@ -332,10 +334,12 @@ next_desc:
|
|||
usb_driver_release_interface(driver, info->data);
|
||||
}
|
||||
|
||||
/* Never use the same address on both ends of the link, even
|
||||
* if the buggy firmware told us to.
|
||||
/* Never use the same address on both ends of the link, even if the
|
||||
* buggy firmware told us to. Or, if device is assigned the well-known
|
||||
* buggy firmware MAC address, replace it with a random address,
|
||||
*/
|
||||
if (ether_addr_equal(dev->net->dev_addr, default_modem_addr))
|
||||
if (ether_addr_equal(dev->net->dev_addr, default_modem_addr) ||
|
||||
ether_addr_equal(dev->net->dev_addr, buggy_fw_addr))
|
||||
eth_hw_addr_random(dev->net);
|
||||
|
||||
/* make MAC addr easily distinguishable from an IP header */
|
||||
|
|
|
@ -1897,6 +1897,22 @@ static void _rtl8152_set_rx_mode(struct net_device *netdev)
|
|||
netif_wake_queue(netdev);
|
||||
}
|
||||
|
||||
static netdev_features_t
|
||||
rtl8152_features_check(struct sk_buff *skb, struct net_device *dev,
|
||||
netdev_features_t features)
|
||||
{
|
||||
u32 mss = skb_shinfo(skb)->gso_size;
|
||||
int max_offset = mss ? GTTCPHO_MAX : TCPHO_MAX;
|
||||
int offset = skb_transport_offset(skb);
|
||||
|
||||
if ((mss || skb->ip_summed == CHECKSUM_PARTIAL) && offset > max_offset)
|
||||
features &= ~(NETIF_F_ALL_CSUM | NETIF_F_GSO_MASK);
|
||||
else if ((skb->len + sizeof(struct tx_desc)) > agg_buf_sz)
|
||||
features &= ~NETIF_F_GSO_MASK;
|
||||
|
||||
return features;
|
||||
}
|
||||
|
||||
static netdev_tx_t rtl8152_start_xmit(struct sk_buff *skb,
|
||||
struct net_device *netdev)
|
||||
{
|
||||
|
@ -3706,6 +3722,7 @@ static const struct net_device_ops rtl8152_netdev_ops = {
|
|||
.ndo_set_mac_address = rtl8152_set_mac_address,
|
||||
.ndo_change_mtu = rtl8152_change_mtu,
|
||||
.ndo_validate_addr = eth_validate_addr,
|
||||
.ndo_features_check = rtl8152_features_check,
|
||||
};
|
||||
|
||||
static void r8152b_get_version(struct r8152 *tp)
|
||||
|
|
|
@ -737,6 +737,7 @@ static void connect(struct backend_info *be)
|
|||
}
|
||||
|
||||
queue->remaining_credit = credit_bytes;
|
||||
queue->credit_usec = credit_usec;
|
||||
|
||||
err = connect_rings(be, queue);
|
||||
if (err) {
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
|
||||
#define DRV_NAME "fnic"
|
||||
#define DRV_DESCRIPTION "Cisco FCoE HBA Driver"
|
||||
#define DRV_VERSION "1.6.0.16"
|
||||
#define DRV_VERSION "1.6.0.17"
|
||||
#define PFX DRV_NAME ": "
|
||||
#define DFX DRV_NAME "%d: "
|
||||
|
||||
|
|
|
@ -1892,6 +1892,21 @@ int fnic_abort_cmd(struct scsi_cmnd *sc)
|
|||
goto fnic_abort_cmd_end;
|
||||
}
|
||||
|
||||
/* IO out of order */
|
||||
|
||||
if (!(CMD_FLAGS(sc) & (FNIC_IO_ABORTED | FNIC_IO_DONE))) {
|
||||
spin_unlock_irqrestore(io_lock, flags);
|
||||
FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host,
|
||||
"Issuing Host reset due to out of order IO\n");
|
||||
|
||||
if (fnic_host_reset(sc) == FAILED) {
|
||||
FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host,
|
||||
"fnic_host_reset failed.\n");
|
||||
}
|
||||
ret = FAILED;
|
||||
goto fnic_abort_cmd_end;
|
||||
}
|
||||
|
||||
CMD_STATE(sc) = FNIC_IOREQ_ABTS_COMPLETE;
|
||||
|
||||
/*
|
||||
|
|
|
@ -1041,7 +1041,7 @@ retry:
|
|||
}
|
||||
/* signal not to enter either branch of the if () below */
|
||||
timeleft = 0;
|
||||
rtn = NEEDS_RETRY;
|
||||
rtn = FAILED;
|
||||
} else {
|
||||
timeleft = wait_for_completion_timeout(&done, timeout);
|
||||
rtn = SUCCESS;
|
||||
|
@ -1081,7 +1081,7 @@ retry:
|
|||
rtn = FAILED;
|
||||
break;
|
||||
}
|
||||
} else if (!rtn) {
|
||||
} else if (rtn != FAILED) {
|
||||
scsi_abort_eh_cmnd(scmd);
|
||||
rtn = FAILED;
|
||||
}
|
||||
|
|
|
@ -2623,8 +2623,9 @@ static void sd_read_block_limits(struct scsi_disk *sdkp)
|
|||
sd_config_discard(sdkp, SD_LBP_WS16);
|
||||
|
||||
} else { /* LBP VPD page tells us what to use */
|
||||
|
||||
if (sdkp->lbpws)
|
||||
if (sdkp->lbpu && sdkp->max_unmap_blocks && !sdkp->lbprz)
|
||||
sd_config_discard(sdkp, SD_LBP_UNMAP);
|
||||
else if (sdkp->lbpws)
|
||||
sd_config_discard(sdkp, SD_LBP_WS16);
|
||||
else if (sdkp->lbpws10)
|
||||
sd_config_discard(sdkp, SD_LBP_WS10);
|
||||
|
|
|
@ -713,9 +713,13 @@ long vhost_vring_ioctl(struct vhost_dev *d, int ioctl, void __user *argp)
|
|||
r = -EFAULT;
|
||||
break;
|
||||
}
|
||||
if ((a.avail_user_addr & (sizeof *vq->avail->ring - 1)) ||
|
||||
(a.used_user_addr & (sizeof *vq->used->ring - 1)) ||
|
||||
(a.log_guest_addr & (sizeof *vq->used->ring - 1))) {
|
||||
|
||||
/* Make sure it's safe to cast pointers to vring types. */
|
||||
BUILD_BUG_ON(__alignof__ *vq->avail > VRING_AVAIL_ALIGN_SIZE);
|
||||
BUILD_BUG_ON(__alignof__ *vq->used > VRING_USED_ALIGN_SIZE);
|
||||
if ((a.avail_user_addr & (VRING_AVAIL_ALIGN_SIZE - 1)) ||
|
||||
(a.used_user_addr & (VRING_USED_ALIGN_SIZE - 1)) ||
|
||||
(a.log_guest_addr & (sizeof(u64) - 1))) {
|
||||
r = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -83,9 +83,10 @@ int fb_deferred_io_fsync(struct file *file, loff_t start, loff_t end, int datasy
|
|||
cancel_delayed_work_sync(&info->deferred_work);
|
||||
|
||||
/* Run it immediately */
|
||||
err = schedule_delayed_work(&info->deferred_work, 0);
|
||||
schedule_delayed_work(&info->deferred_work, 0);
|
||||
mutex_unlock(&inode->i_mutex);
|
||||
return err;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(fb_deferred_io_fsync);
|
||||
|
||||
|
|
|
@ -132,7 +132,6 @@ static const struct dss_pll_hw dss_omap4_hdmi_pll_hw = {
|
|||
.mX_max = 127,
|
||||
.fint_min = 500000,
|
||||
.fint_max = 2500000,
|
||||
.clkdco_max = 1800000000,
|
||||
|
||||
.clkdco_min = 500000000,
|
||||
.clkdco_low = 1000000000,
|
||||
|
@ -156,7 +155,6 @@ static const struct dss_pll_hw dss_omap5_hdmi_pll_hw = {
|
|||
.mX_max = 127,
|
||||
.fint_min = 620000,
|
||||
.fint_max = 2500000,
|
||||
.clkdco_max = 1800000000,
|
||||
|
||||
.clkdco_min = 750000000,
|
||||
.clkdco_low = 1500000000,
|
||||
|
|
|
@ -97,7 +97,8 @@ int dss_pll_enable(struct dss_pll *pll)
|
|||
return 0;
|
||||
|
||||
err_enable:
|
||||
regulator_disable(pll->regulator);
|
||||
if (pll->regulator)
|
||||
regulator_disable(pll->regulator);
|
||||
err_reg:
|
||||
clk_disable_unprepare(pll->clkin);
|
||||
return r;
|
||||
|
|
|
@ -342,6 +342,8 @@ static void sdi_init_output(struct platform_device *pdev)
|
|||
out->output_type = OMAP_DISPLAY_TYPE_SDI;
|
||||
out->name = "sdi.0";
|
||||
out->dispc_channel = OMAP_DSS_CHANNEL_LCD;
|
||||
/* We have SDI only on OMAP3, where it's on port 1 */
|
||||
out->port_num = 1;
|
||||
out->ops.sdi = &sdi_ops;
|
||||
out->owner = THIS_MODULE;
|
||||
|
||||
|
|
|
@ -21,6 +21,21 @@ static bool nologo;
|
|||
module_param(nologo, bool, 0);
|
||||
MODULE_PARM_DESC(nologo, "Disables startup logo");
|
||||
|
||||
/*
|
||||
* Logos are located in the initdata, and will be freed in kernel_init.
|
||||
* Use late_init to mark the logos as freed to prevent any further use.
|
||||
*/
|
||||
|
||||
static bool logos_freed;
|
||||
|
||||
static int __init fb_logo_late_init(void)
|
||||
{
|
||||
logos_freed = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
late_initcall(fb_logo_late_init);
|
||||
|
||||
/* logo's are marked __initdata. Use __init_refok to tell
|
||||
* modpost that it is intended that this function uses data
|
||||
* marked __initdata.
|
||||
|
@ -29,7 +44,7 @@ const struct linux_logo * __init_refok fb_find_logo(int depth)
|
|||
{
|
||||
const struct linux_logo *logo = NULL;
|
||||
|
||||
if (nologo)
|
||||
if (nologo || logos_freed)
|
||||
return NULL;
|
||||
|
||||
if (depth >= 1) {
|
||||
|
|
|
@ -5166,8 +5166,8 @@ int ext4_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
|
|||
|
||||
/* fallback to generic here if not in extents fmt */
|
||||
if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)))
|
||||
return __generic_block_fiemap(inode, fieinfo, start, len,
|
||||
ext4_get_block);
|
||||
return generic_block_fiemap(inode, fieinfo, start, len,
|
||||
ext4_get_block);
|
||||
|
||||
if (fiemap_check_flags(fieinfo, EXT4_FIEMAP_FLAGS))
|
||||
return -EBADR;
|
||||
|
|
224
fs/ext4/file.c
224
fs/ext4/file.c
|
@ -273,19 +273,24 @@ static int ext4_file_open(struct inode * inode, struct file * filp)
|
|||
* we determine this extent as a data or a hole according to whether the
|
||||
* page cache has data or not.
|
||||
*/
|
||||
static int ext4_find_unwritten_pgoff(struct inode *inode, int whence,
|
||||
loff_t endoff, loff_t *offset)
|
||||
static int ext4_find_unwritten_pgoff(struct inode *inode,
|
||||
int whence,
|
||||
struct ext4_map_blocks *map,
|
||||
loff_t *offset)
|
||||
{
|
||||
struct pagevec pvec;
|
||||
unsigned int blkbits;
|
||||
pgoff_t index;
|
||||
pgoff_t end;
|
||||
loff_t endoff;
|
||||
loff_t startoff;
|
||||
loff_t lastoff;
|
||||
int found = 0;
|
||||
|
||||
blkbits = inode->i_sb->s_blocksize_bits;
|
||||
startoff = *offset;
|
||||
lastoff = startoff;
|
||||
|
||||
endoff = (loff_t)(map->m_lblk + map->m_len) << blkbits;
|
||||
|
||||
index = startoff >> PAGE_CACHE_SHIFT;
|
||||
end = endoff >> PAGE_CACHE_SHIFT;
|
||||
|
@ -403,144 +408,147 @@ out:
|
|||
static loff_t ext4_seek_data(struct file *file, loff_t offset, loff_t maxsize)
|
||||
{
|
||||
struct inode *inode = file->f_mapping->host;
|
||||
struct fiemap_extent_info fie;
|
||||
struct fiemap_extent ext[2];
|
||||
loff_t next;
|
||||
int i, ret = 0;
|
||||
struct ext4_map_blocks map;
|
||||
struct extent_status es;
|
||||
ext4_lblk_t start, last, end;
|
||||
loff_t dataoff, isize;
|
||||
int blkbits;
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&inode->i_mutex);
|
||||
if (offset >= inode->i_size) {
|
||||
|
||||
isize = i_size_read(inode);
|
||||
if (offset >= isize) {
|
||||
mutex_unlock(&inode->i_mutex);
|
||||
return -ENXIO;
|
||||
}
|
||||
fie.fi_flags = 0;
|
||||
fie.fi_extents_max = 2;
|
||||
fie.fi_extents_start = (struct fiemap_extent __user *) &ext;
|
||||
while (1) {
|
||||
mm_segment_t old_fs = get_fs();
|
||||
|
||||
fie.fi_extents_mapped = 0;
|
||||
memset(ext, 0, sizeof(*ext) * fie.fi_extents_max);
|
||||
blkbits = inode->i_sb->s_blocksize_bits;
|
||||
start = offset >> blkbits;
|
||||
last = start;
|
||||
end = isize >> blkbits;
|
||||
dataoff = offset;
|
||||
|
||||
set_fs(get_ds());
|
||||
ret = ext4_fiemap(inode, &fie, offset, maxsize - offset);
|
||||
set_fs(old_fs);
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
/* No extents found, EOF */
|
||||
if (!fie.fi_extents_mapped) {
|
||||
ret = -ENXIO;
|
||||
do {
|
||||
map.m_lblk = last;
|
||||
map.m_len = end - last + 1;
|
||||
ret = ext4_map_blocks(NULL, inode, &map, 0);
|
||||
if (ret > 0 && !(map.m_flags & EXT4_MAP_UNWRITTEN)) {
|
||||
if (last != start)
|
||||
dataoff = (loff_t)last << blkbits;
|
||||
break;
|
||||
}
|
||||
for (i = 0; i < fie.fi_extents_mapped; i++) {
|
||||
next = (loff_t)(ext[i].fe_length + ext[i].fe_logical);
|
||||
|
||||
if (offset < (loff_t)ext[i].fe_logical)
|
||||
offset = (loff_t)ext[i].fe_logical;
|
||||
/*
|
||||
* If extent is not unwritten, then it contains valid
|
||||
* data, mapped or delayed.
|
||||
*/
|
||||
if (!(ext[i].fe_flags & FIEMAP_EXTENT_UNWRITTEN))
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* If there is a unwritten extent at this offset,
|
||||
* it will be as a data or a hole according to page
|
||||
* cache that has data or not.
|
||||
*/
|
||||
if (ext4_find_unwritten_pgoff(inode, SEEK_DATA,
|
||||
next, &offset))
|
||||
goto out;
|
||||
|
||||
if (ext[i].fe_flags & FIEMAP_EXTENT_LAST) {
|
||||
ret = -ENXIO;
|
||||
goto out;
|
||||
}
|
||||
offset = next;
|
||||
/*
|
||||
* If there is a delay extent at this offset,
|
||||
* it will be as a data.
|
||||
*/
|
||||
ext4_es_find_delayed_extent_range(inode, last, last, &es);
|
||||
if (es.es_len != 0 && in_range(last, es.es_lblk, es.es_len)) {
|
||||
if (last != start)
|
||||
dataoff = (loff_t)last << blkbits;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (offset > inode->i_size)
|
||||
offset = inode->i_size;
|
||||
out:
|
||||
|
||||
/*
|
||||
* If there is a unwritten extent at this offset,
|
||||
* it will be as a data or a hole according to page
|
||||
* cache that has data or not.
|
||||
*/
|
||||
if (map.m_flags & EXT4_MAP_UNWRITTEN) {
|
||||
int unwritten;
|
||||
unwritten = ext4_find_unwritten_pgoff(inode, SEEK_DATA,
|
||||
&map, &dataoff);
|
||||
if (unwritten)
|
||||
break;
|
||||
}
|
||||
|
||||
last++;
|
||||
dataoff = (loff_t)last << blkbits;
|
||||
} while (last <= end);
|
||||
|
||||
mutex_unlock(&inode->i_mutex);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return vfs_setpos(file, offset, maxsize);
|
||||
if (dataoff > isize)
|
||||
return -ENXIO;
|
||||
|
||||
return vfs_setpos(file, dataoff, maxsize);
|
||||
}
|
||||
|
||||
/*
|
||||
* ext4_seek_hole() retrieves the offset for SEEK_HOLE
|
||||
* ext4_seek_hole() retrieves the offset for SEEK_HOLE.
|
||||
*/
|
||||
static loff_t ext4_seek_hole(struct file *file, loff_t offset, loff_t maxsize)
|
||||
{
|
||||
struct inode *inode = file->f_mapping->host;
|
||||
struct fiemap_extent_info fie;
|
||||
struct fiemap_extent ext[2];
|
||||
loff_t next;
|
||||
int i, ret = 0;
|
||||
struct ext4_map_blocks map;
|
||||
struct extent_status es;
|
||||
ext4_lblk_t start, last, end;
|
||||
loff_t holeoff, isize;
|
||||
int blkbits;
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&inode->i_mutex);
|
||||
if (offset >= inode->i_size) {
|
||||
|
||||
isize = i_size_read(inode);
|
||||
if (offset >= isize) {
|
||||
mutex_unlock(&inode->i_mutex);
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
fie.fi_flags = 0;
|
||||
fie.fi_extents_max = 2;
|
||||
fie.fi_extents_start = (struct fiemap_extent __user *)&ext;
|
||||
while (1) {
|
||||
mm_segment_t old_fs = get_fs();
|
||||
blkbits = inode->i_sb->s_blocksize_bits;
|
||||
start = offset >> blkbits;
|
||||
last = start;
|
||||
end = isize >> blkbits;
|
||||
holeoff = offset;
|
||||
|
||||
fie.fi_extents_mapped = 0;
|
||||
memset(ext, 0, sizeof(*ext));
|
||||
do {
|
||||
map.m_lblk = last;
|
||||
map.m_len = end - last + 1;
|
||||
ret = ext4_map_blocks(NULL, inode, &map, 0);
|
||||
if (ret > 0 && !(map.m_flags & EXT4_MAP_UNWRITTEN)) {
|
||||
last += ret;
|
||||
holeoff = (loff_t)last << blkbits;
|
||||
continue;
|
||||
}
|
||||
|
||||
set_fs(get_ds());
|
||||
ret = ext4_fiemap(inode, &fie, offset, maxsize - offset);
|
||||
set_fs(old_fs);
|
||||
if (ret)
|
||||
break;
|
||||
/*
|
||||
* If there is a delay extent at this offset,
|
||||
* we will skip this extent.
|
||||
*/
|
||||
ext4_es_find_delayed_extent_range(inode, last, last, &es);
|
||||
if (es.es_len != 0 && in_range(last, es.es_lblk, es.es_len)) {
|
||||
last = es.es_lblk + es.es_len;
|
||||
holeoff = (loff_t)last << blkbits;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* No extents found */
|
||||
if (!fie.fi_extents_mapped)
|
||||
break;
|
||||
|
||||
for (i = 0; i < fie.fi_extents_mapped; i++) {
|
||||
next = (loff_t)(ext[i].fe_logical + ext[i].fe_length);
|
||||
/*
|
||||
* If extent is not unwritten, then it contains valid
|
||||
* data, mapped or delayed.
|
||||
*/
|
||||
if (!(ext[i].fe_flags & FIEMAP_EXTENT_UNWRITTEN)) {
|
||||
if (offset < (loff_t)ext[i].fe_logical)
|
||||
goto out;
|
||||
offset = next;
|
||||
/*
|
||||
* If there is a unwritten extent at this offset,
|
||||
* it will be as a data or a hole according to page
|
||||
* cache that has data or not.
|
||||
*/
|
||||
if (map.m_flags & EXT4_MAP_UNWRITTEN) {
|
||||
int unwritten;
|
||||
unwritten = ext4_find_unwritten_pgoff(inode, SEEK_HOLE,
|
||||
&map, &holeoff);
|
||||
if (!unwritten) {
|
||||
last += ret;
|
||||
holeoff = (loff_t)last << blkbits;
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
* If there is a unwritten extent at this offset,
|
||||
* it will be as a data or a hole according to page
|
||||
* cache that has data or not.
|
||||
*/
|
||||
if (ext4_find_unwritten_pgoff(inode, SEEK_HOLE,
|
||||
next, &offset))
|
||||
goto out;
|
||||
|
||||
offset = next;
|
||||
if (ext[i].fe_flags & FIEMAP_EXTENT_LAST)
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
if (offset > inode->i_size)
|
||||
offset = inode->i_size;
|
||||
out:
|
||||
mutex_unlock(&inode->i_mutex);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return vfs_setpos(file, offset, maxsize);
|
||||
/* find a hole */
|
||||
break;
|
||||
} while (last <= end);
|
||||
|
||||
mutex_unlock(&inode->i_mutex);
|
||||
|
||||
if (holeoff > isize)
|
||||
holeoff = isize;
|
||||
|
||||
return vfs_setpos(file, holeoff, maxsize);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -23,6 +23,18 @@ int ext4_resize_begin(struct super_block *sb)
|
|||
if (!capable(CAP_SYS_RESOURCE))
|
||||
return -EPERM;
|
||||
|
||||
/*
|
||||
* If we are not using the primary superblock/GDT copy don't resize,
|
||||
* because the user tools have no way of handling this. Probably a
|
||||
* bad time to do it anyways.
|
||||
*/
|
||||
if (EXT4_SB(sb)->s_sbh->b_blocknr !=
|
||||
le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block)) {
|
||||
ext4_warning(sb, "won't resize using backup superblock at %llu",
|
||||
(unsigned long long)EXT4_SB(sb)->s_sbh->b_blocknr);
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
/*
|
||||
* We are not allowed to do online-resizing on a filesystem mounted
|
||||
* with error, because it can destroy the filesystem easily.
|
||||
|
@ -758,18 +770,6 @@ static int add_new_gdb(handle_t *handle, struct inode *inode,
|
|||
"EXT4-fs: ext4_add_new_gdb: adding group block %lu\n",
|
||||
gdb_num);
|
||||
|
||||
/*
|
||||
* If we are not using the primary superblock/GDT copy don't resize,
|
||||
* because the user tools have no way of handling this. Probably a
|
||||
* bad time to do it anyways.
|
||||
*/
|
||||
if (EXT4_SB(sb)->s_sbh->b_blocknr !=
|
||||
le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block)) {
|
||||
ext4_warning(sb, "won't resize using backup superblock at %llu",
|
||||
(unsigned long long)EXT4_SB(sb)->s_sbh->b_blocknr);
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
gdb_bh = sb_bread(sb, gdblock);
|
||||
if (!gdb_bh)
|
||||
return -EIO;
|
||||
|
|
|
@ -3482,7 +3482,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
|
|||
if (EXT4_HAS_RO_COMPAT_FEATURE(sb,
|
||||
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM) &&
|
||||
EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_GDT_CSUM))
|
||||
ext4_warning(sb, KERN_INFO "metadata_csum and uninit_bg are "
|
||||
ext4_warning(sb, "metadata_csum and uninit_bg are "
|
||||
"redundant flags; please run fsck.");
|
||||
|
||||
/* Check for a known checksum algorithm */
|
||||
|
|
|
@ -50,6 +50,8 @@ enum {
|
|||
STMPE_IDX_GPEDR_MSB,
|
||||
STMPE_IDX_GPRER_LSB,
|
||||
STMPE_IDX_GPFER_LSB,
|
||||
STMPE_IDX_GPPUR_LSB,
|
||||
STMPE_IDX_GPPDR_LSB,
|
||||
STMPE_IDX_GPAFR_U_MSB,
|
||||
STMPE_IDX_IEGPIOR_LSB,
|
||||
STMPE_IDX_ISGPIOR_LSB,
|
||||
|
@ -113,24 +115,6 @@ extern int stmpe_set_altfunc(struct stmpe *stmpe, u32 pins,
|
|||
extern int stmpe_enable(struct stmpe *stmpe, unsigned int blocks);
|
||||
extern int stmpe_disable(struct stmpe *stmpe, unsigned int blocks);
|
||||
|
||||
struct matrix_keymap_data;
|
||||
|
||||
/**
|
||||
* struct stmpe_keypad_platform_data - STMPE keypad platform data
|
||||
* @keymap_data: key map table and size
|
||||
* @debounce_ms: debounce interval, in ms. Maximum is
|
||||
* %STMPE_KEYPAD_MAX_DEBOUNCE.
|
||||
* @scan_count: number of key scanning cycles to confirm key data.
|
||||
* Maximum is %STMPE_KEYPAD_MAX_SCAN_COUNT.
|
||||
* @no_autorepeat: disable key autorepeat
|
||||
*/
|
||||
struct stmpe_keypad_platform_data {
|
||||
const struct matrix_keymap_data *keymap_data;
|
||||
unsigned int debounce_ms;
|
||||
unsigned int scan_count;
|
||||
bool no_autorepeat;
|
||||
};
|
||||
|
||||
#define STMPE_GPIO_NOREQ_811_TOUCH (0xf0)
|
||||
|
||||
/**
|
||||
|
@ -199,7 +183,6 @@ struct stmpe_ts_platform_data {
|
|||
* @irq_gpio: gpio number over which irq will be requested (significant only if
|
||||
* irq_over_gpio is true)
|
||||
* @gpio: GPIO-specific platform data
|
||||
* @keypad: keypad-specific platform data
|
||||
* @ts: touchscreen-specific platform data
|
||||
*/
|
||||
struct stmpe_platform_data {
|
||||
|
@ -212,7 +195,6 @@ struct stmpe_platform_data {
|
|||
int autosleep_timeout;
|
||||
|
||||
struct stmpe_gpio_platform_data *gpio;
|
||||
struct stmpe_keypad_platform_data *keypad;
|
||||
struct stmpe_ts_platform_data *ts;
|
||||
};
|
||||
|
||||
|
|
|
@ -1952,7 +1952,7 @@ extern int expand_downwards(struct vm_area_struct *vma,
|
|||
#if VM_GROWSUP
|
||||
extern int expand_upwards(struct vm_area_struct *vma, unsigned long address);
|
||||
#else
|
||||
#define expand_upwards(vma, address) do { } while (0)
|
||||
#define expand_upwards(vma, address) (0)
|
||||
#endif
|
||||
|
||||
/* Look up the first VMA which satisfies addr < vm_end, NULL if none. */
|
||||
|
|
|
@ -1270,8 +1270,7 @@ struct ieee80211_vif *wdev_to_ieee80211_vif(struct wireless_dev *wdev);
|
|||
*
|
||||
* @IEEE80211_KEY_FLAG_GENERATE_IV: This flag should be set by the
|
||||
* driver to indicate that it requires IV generation for this
|
||||
* particular key. Setting this flag does not necessarily mean that SKBs
|
||||
* will have sufficient tailroom for ICV or MIC.
|
||||
* particular key.
|
||||
* @IEEE80211_KEY_FLAG_GENERATE_MMIC: This flag should be set by
|
||||
* the driver for a TKIP key if it requires Michael MIC
|
||||
* generation in software.
|
||||
|
@ -1283,9 +1282,7 @@ struct ieee80211_vif *wdev_to_ieee80211_vif(struct wireless_dev *wdev);
|
|||
* @IEEE80211_KEY_FLAG_PUT_IV_SPACE: This flag should be set by the driver
|
||||
* if space should be prepared for the IV, but the IV
|
||||
* itself should not be generated. Do not set together with
|
||||
* @IEEE80211_KEY_FLAG_GENERATE_IV on the same key. Setting this flag does
|
||||
* not necessarily mean that SKBs will have sufficient tailroom for ICV or
|
||||
* MIC.
|
||||
* @IEEE80211_KEY_FLAG_GENERATE_IV on the same key.
|
||||
* @IEEE80211_KEY_FLAG_RX_MGMT: This key will be used to decrypt received
|
||||
* management frames. The flag can help drivers that have a hardware
|
||||
* crypto implementation that doesn't deal with management frames
|
||||
|
|
|
@ -857,7 +857,7 @@ static inline unsigned int params_channels(const struct snd_pcm_hw_params *p)
|
|||
}
|
||||
|
||||
/**
|
||||
* params_channels - Get the sample rate from the hw params
|
||||
* params_rate - Get the sample rate from the hw params
|
||||
* @p: hw params
|
||||
*/
|
||||
static inline unsigned int params_rate(const struct snd_pcm_hw_params *p)
|
||||
|
@ -866,7 +866,7 @@ static inline unsigned int params_rate(const struct snd_pcm_hw_params *p)
|
|||
}
|
||||
|
||||
/**
|
||||
* params_channels - Get the period size (in frames) from the hw params
|
||||
* params_period_size - Get the period size (in frames) from the hw params
|
||||
* @p: hw params
|
||||
*/
|
||||
static inline unsigned int params_period_size(const struct snd_pcm_hw_params *p)
|
||||
|
@ -875,7 +875,7 @@ static inline unsigned int params_period_size(const struct snd_pcm_hw_params *p)
|
|||
}
|
||||
|
||||
/**
|
||||
* params_channels - Get the number of periods from the hw params
|
||||
* params_periods - Get the number of periods from the hw params
|
||||
* @p: hw params
|
||||
*/
|
||||
static inline unsigned int params_periods(const struct snd_pcm_hw_params *p)
|
||||
|
@ -884,7 +884,7 @@ static inline unsigned int params_periods(const struct snd_pcm_hw_params *p)
|
|||
}
|
||||
|
||||
/**
|
||||
* params_channels - Get the buffer size (in frames) from the hw params
|
||||
* params_buffer_size - Get the buffer size (in frames) from the hw params
|
||||
* @p: hw params
|
||||
*/
|
||||
static inline unsigned int params_buffer_size(const struct snd_pcm_hw_params *p)
|
||||
|
@ -893,7 +893,7 @@ static inline unsigned int params_buffer_size(const struct snd_pcm_hw_params *p)
|
|||
}
|
||||
|
||||
/**
|
||||
* params_channels - Get the buffer size (in bytes) from the hw params
|
||||
* params_buffer_bytes - Get the buffer size (in bytes) from the hw params
|
||||
* @p: hw params
|
||||
*/
|
||||
static inline unsigned int params_buffer_bytes(const struct snd_pcm_hw_params *p)
|
||||
|
|
|
@ -101,6 +101,13 @@ struct vring {
|
|||
struct vring_used *used;
|
||||
};
|
||||
|
||||
/* Alignment requirements for vring elements.
|
||||
* When using pre-virtio 1.0 layout, these fall out naturally.
|
||||
*/
|
||||
#define VRING_AVAIL_ALIGN_SIZE 2
|
||||
#define VRING_USED_ALIGN_SIZE 4
|
||||
#define VRING_DESC_ALIGN_SIZE 16
|
||||
|
||||
/* The standard layout for the ring is a continuous chunk of memory which looks
|
||||
* like this. We assume num is a power of 2.
|
||||
*
|
||||
|
|
|
@ -72,6 +72,8 @@
|
|||
#include <linux/fs_struct.h>
|
||||
#include <linux/compat.h>
|
||||
#include <linux/ctype.h>
|
||||
#include <linux/string.h>
|
||||
#include <uapi/linux/limits.h>
|
||||
|
||||
#include "audit.h"
|
||||
|
||||
|
@ -1861,8 +1863,7 @@ void __audit_inode(struct filename *name, const struct dentry *dentry,
|
|||
}
|
||||
|
||||
list_for_each_entry_reverse(n, &context->names_list, list) {
|
||||
/* does the name pointer match? */
|
||||
if (!n->name || n->name->name != name->name)
|
||||
if (!n->name || strcmp(n->name->name, name->name))
|
||||
continue;
|
||||
|
||||
/* match the correct record type */
|
||||
|
@ -1881,14 +1882,44 @@ out_alloc:
|
|||
n = audit_alloc_name(context, AUDIT_TYPE_UNKNOWN);
|
||||
if (!n)
|
||||
return;
|
||||
if (name)
|
||||
/* since name is not NULL we know there is already a matching
|
||||
* name record, see audit_getname(), so there must be a type
|
||||
* mismatch; reuse the string path since the original name
|
||||
* record will keep the string valid until we free it in
|
||||
* audit_free_names() */
|
||||
n->name = name;
|
||||
/* unfortunately, while we may have a path name to record with the
|
||||
* inode, we can't always rely on the string lasting until the end of
|
||||
* the syscall so we need to create our own copy, it may fail due to
|
||||
* memory allocation issues, but we do our best */
|
||||
if (name) {
|
||||
/* we can't use getname_kernel() due to size limits */
|
||||
size_t len = strlen(name->name) + 1;
|
||||
struct filename *new = __getname();
|
||||
|
||||
if (unlikely(!new))
|
||||
goto out;
|
||||
|
||||
if (len <= (PATH_MAX - sizeof(*new))) {
|
||||
new->name = (char *)(new) + sizeof(*new);
|
||||
new->separate = false;
|
||||
} else if (len <= PATH_MAX) {
|
||||
/* this looks odd, but is due to final_putname() */
|
||||
struct filename *new2;
|
||||
|
||||
new2 = kmalloc(sizeof(*new2), GFP_KERNEL);
|
||||
if (unlikely(!new2)) {
|
||||
__putname(new);
|
||||
goto out;
|
||||
}
|
||||
new2->name = (char *)new;
|
||||
new2->separate = true;
|
||||
new = new2;
|
||||
} else {
|
||||
/* we should never get here, but let's be safe */
|
||||
__putname(new);
|
||||
goto out;
|
||||
}
|
||||
strlcpy((char *)new->name, name->name, len);
|
||||
new->uptr = NULL;
|
||||
new->aname = n;
|
||||
n->name = new;
|
||||
n->name_put = true;
|
||||
}
|
||||
out:
|
||||
if (parent) {
|
||||
n->name_len = n->name ? parent_len(n->name->name) : AUDIT_NAME_FULL;
|
||||
|
|
|
@ -2593,7 +2593,7 @@ static inline int check_stack_guard_page(struct vm_area_struct *vma, unsigned lo
|
|||
if (prev && prev->vm_end == address)
|
||||
return prev->vm_flags & VM_GROWSDOWN ? 0 : -ENOMEM;
|
||||
|
||||
expand_downwards(vma, address - PAGE_SIZE);
|
||||
return expand_downwards(vma, address - PAGE_SIZE);
|
||||
}
|
||||
if ((vma->vm_flags & VM_GROWSUP) && address + PAGE_SIZE == vma->vm_end) {
|
||||
struct vm_area_struct *next = vma->vm_next;
|
||||
|
@ -2602,7 +2602,7 @@ static inline int check_stack_guard_page(struct vm_area_struct *vma, unsigned lo
|
|||
if (next && next->vm_start == address + PAGE_SIZE)
|
||||
return next->vm_flags & VM_GROWSUP ? 0 : -ENOMEM;
|
||||
|
||||
expand_upwards(vma, address + PAGE_SIZE);
|
||||
return expand_upwards(vma, address + PAGE_SIZE);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -685,11 +685,13 @@ static void batadv_mcast_tvlv_ogm_handler_v1(struct batadv_priv *bat_priv,
|
|||
if (orig_initialized)
|
||||
atomic_dec(&bat_priv->mcast.num_disabled);
|
||||
orig->capabilities |= BATADV_ORIG_CAPA_HAS_MCAST;
|
||||
/* If mcast support is being switched off increase the disabled
|
||||
* mcast node counter.
|
||||
/* If mcast support is being switched off or if this is an initial
|
||||
* OGM without mcast support then increase the disabled mcast
|
||||
* node counter.
|
||||
*/
|
||||
} else if (!orig_mcast_enabled &&
|
||||
orig->capabilities & BATADV_ORIG_CAPA_HAS_MCAST) {
|
||||
(orig->capabilities & BATADV_ORIG_CAPA_HAS_MCAST ||
|
||||
!orig_initialized)) {
|
||||
atomic_inc(&bat_priv->mcast.num_disabled);
|
||||
orig->capabilities &= ~BATADV_ORIG_CAPA_HAS_MCAST;
|
||||
}
|
||||
|
@ -738,7 +740,8 @@ void batadv_mcast_purge_orig(struct batadv_orig_node *orig)
|
|||
{
|
||||
struct batadv_priv *bat_priv = orig->bat_priv;
|
||||
|
||||
if (!(orig->capabilities & BATADV_ORIG_CAPA_HAS_MCAST))
|
||||
if (!(orig->capabilities & BATADV_ORIG_CAPA_HAS_MCAST) &&
|
||||
orig->capa_initialized & BATADV_ORIG_CAPA_HAS_MCAST)
|
||||
atomic_dec(&bat_priv->mcast.num_disabled);
|
||||
|
||||
batadv_mcast_want_unsnoop_update(bat_priv, orig, BATADV_NO_FLAGS);
|
||||
|
|
|
@ -133,7 +133,7 @@ int batadv_nc_mesh_init(struct batadv_priv *bat_priv)
|
|||
if (!bat_priv->nc.decoding_hash)
|
||||
goto err;
|
||||
|
||||
batadv_hash_set_lock_class(bat_priv->nc.coding_hash,
|
||||
batadv_hash_set_lock_class(bat_priv->nc.decoding_hash,
|
||||
&batadv_nc_decoding_hash_lock_class_key);
|
||||
|
||||
INIT_DELAYED_WORK(&bat_priv->nc.work, batadv_nc_worker);
|
||||
|
|
|
@ -570,9 +570,6 @@ static void batadv_orig_node_free_rcu(struct rcu_head *rcu)
|
|||
|
||||
batadv_frag_purge_orig(orig_node, NULL);
|
||||
|
||||
batadv_tt_global_del_orig(orig_node->bat_priv, orig_node, -1,
|
||||
"originator timed out");
|
||||
|
||||
if (orig_node->bat_priv->bat_algo_ops->bat_orig_free)
|
||||
orig_node->bat_priv->bat_algo_ops->bat_orig_free(orig_node);
|
||||
|
||||
|
@ -678,6 +675,7 @@ struct batadv_orig_node *batadv_orig_node_new(struct batadv_priv *bat_priv,
|
|||
atomic_set(&orig_node->last_ttvn, 0);
|
||||
orig_node->tt_buff = NULL;
|
||||
orig_node->tt_buff_len = 0;
|
||||
orig_node->last_seen = jiffies;
|
||||
reset_time = jiffies - 1 - msecs_to_jiffies(BATADV_RESET_PROTECTION_MS);
|
||||
orig_node->bcast_seqno_reset = reset_time;
|
||||
#ifdef CONFIG_BATMAN_ADV_MCAST
|
||||
|
@ -977,6 +975,9 @@ static void _batadv_purge_orig(struct batadv_priv *bat_priv)
|
|||
if (batadv_purge_orig_node(bat_priv, orig_node)) {
|
||||
batadv_gw_node_delete(bat_priv, orig_node);
|
||||
hlist_del_rcu(&orig_node->hash_entry);
|
||||
batadv_tt_global_del_orig(orig_node->bat_priv,
|
||||
orig_node, -1,
|
||||
"originator timed out");
|
||||
batadv_orig_node_free_ref(orig_node);
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -443,11 +443,13 @@ batadv_find_router(struct batadv_priv *bat_priv,
|
|||
|
||||
router = batadv_orig_router_get(orig_node, recv_if);
|
||||
|
||||
if (!router)
|
||||
return router;
|
||||
|
||||
/* only consider bonding for recv_if == BATADV_IF_DEFAULT (first hop)
|
||||
* and if activated.
|
||||
*/
|
||||
if (recv_if == BATADV_IF_DEFAULT || !atomic_read(&bat_priv->bonding) ||
|
||||
!router)
|
||||
if (!(recv_if == BATADV_IF_DEFAULT && atomic_read(&bat_priv->bonding)))
|
||||
return router;
|
||||
|
||||
/* bonding: loop through the list of possible routers found
|
||||
|
|
|
@ -2019,7 +2019,7 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle,
|
|||
if (unlikely(!tcp_snd_wnd_test(tp, skb, mss_now)))
|
||||
break;
|
||||
|
||||
if (tso_segs == 1) {
|
||||
if (tso_segs == 1 || !max_segs) {
|
||||
if (unlikely(!tcp_nagle_test(tp, skb, mss_now,
|
||||
(tcp_skb_is_last(sk, skb) ?
|
||||
nonagle : TCP_NAGLE_PUSH))))
|
||||
|
@ -2032,7 +2032,7 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle,
|
|||
}
|
||||
|
||||
limit = mss_now;
|
||||
if (tso_segs > 1 && !tcp_urg_mode(tp))
|
||||
if (tso_segs > 1 && max_segs && !tcp_urg_mode(tp))
|
||||
limit = tcp_mss_split_point(sk, skb, mss_now,
|
||||
min_t(unsigned int,
|
||||
cwnd_quota,
|
||||
|
|
|
@ -140,7 +140,9 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
|
|||
if (!ret) {
|
||||
key->flags |= KEY_FLAG_UPLOADED_TO_HARDWARE;
|
||||
|
||||
if (!(key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC))
|
||||
if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) ||
|
||||
(key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) ||
|
||||
(key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)))
|
||||
sdata->crypto_tx_tailroom_needed_cnt--;
|
||||
|
||||
WARN_ON((key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE) &&
|
||||
|
@ -188,7 +190,9 @@ static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key)
|
|||
sta = key->sta;
|
||||
sdata = key->sdata;
|
||||
|
||||
if (!(key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC))
|
||||
if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) ||
|
||||
(key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) ||
|
||||
(key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)))
|
||||
increment_tailroom_need_count(sdata);
|
||||
|
||||
ret = drv_set_key(key->local, DISABLE_KEY, sdata,
|
||||
|
@ -884,7 +888,9 @@ void ieee80211_remove_key(struct ieee80211_key_conf *keyconf)
|
|||
if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) {
|
||||
key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE;
|
||||
|
||||
if (!(key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC))
|
||||
if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) ||
|
||||
(key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) ||
|
||||
(key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)))
|
||||
increment_tailroom_need_count(key->sdata);
|
||||
}
|
||||
|
||||
|
|
|
@ -70,6 +70,7 @@ void ovs_flow_stats_update(struct sw_flow *flow, __be16 tcp_flags,
|
|||
{
|
||||
struct flow_stats *stats;
|
||||
int node = numa_node_id();
|
||||
int len = skb->len + (vlan_tx_tag_present(skb) ? VLAN_HLEN : 0);
|
||||
|
||||
stats = rcu_dereference(flow->stats[node]);
|
||||
|
||||
|
@ -105,7 +106,7 @@ void ovs_flow_stats_update(struct sw_flow *flow, __be16 tcp_flags,
|
|||
if (likely(new_stats)) {
|
||||
new_stats->used = jiffies;
|
||||
new_stats->packet_count = 1;
|
||||
new_stats->byte_count = skb->len;
|
||||
new_stats->byte_count = len;
|
||||
new_stats->tcp_flags = tcp_flags;
|
||||
spin_lock_init(&new_stats->lock);
|
||||
|
||||
|
@ -120,7 +121,7 @@ void ovs_flow_stats_update(struct sw_flow *flow, __be16 tcp_flags,
|
|||
|
||||
stats->used = jiffies;
|
||||
stats->packet_count++;
|
||||
stats->byte_count += skb->len;
|
||||
stats->byte_count += len;
|
||||
stats->tcp_flags |= tcp_flags;
|
||||
unlock:
|
||||
spin_unlock(&stats->lock);
|
||||
|
|
|
@ -480,7 +480,7 @@ void ovs_vport_receive(struct vport *vport, struct sk_buff *skb,
|
|||
stats = this_cpu_ptr(vport->percpu_stats);
|
||||
u64_stats_update_begin(&stats->syncp);
|
||||
stats->rx_packets++;
|
||||
stats->rx_bytes += skb->len;
|
||||
stats->rx_bytes += skb->len + (vlan_tx_tag_present(skb) ? VLAN_HLEN : 0);
|
||||
u64_stats_update_end(&stats->syncp);
|
||||
|
||||
OVS_CB(skb)->input_vport = vport;
|
||||
|
|
|
@ -175,7 +175,7 @@ config CFG80211_INTERNAL_REGDB
|
|||
Most distributions have a CRDA package. So if unsure, say N.
|
||||
|
||||
config CFG80211_WEXT
|
||||
bool
|
||||
bool "cfg80211 wireless extensions compatibility"
|
||||
depends on CFG80211
|
||||
select WEXT_CORE
|
||||
help
|
||||
|
|
|
@ -784,8 +784,8 @@ static unsigned int bst_tlv[] = {
|
|||
static int rt5677_dsp_vad_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
|
||||
struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
|
||||
struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
|
||||
struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component);
|
||||
|
||||
ucontrol->value.integer.value[0] = rt5677->dsp_vad_en;
|
||||
|
||||
|
@ -795,8 +795,9 @@ static int rt5677_dsp_vad_get(struct snd_kcontrol *kcontrol,
|
|||
static int rt5677_dsp_vad_put(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
|
||||
struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
|
||||
struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
|
||||
struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component);
|
||||
struct snd_soc_codec *codec = snd_soc_component_to_codec(component);
|
||||
|
||||
rt5677->dsp_vad_en = !!ucontrol->value.integer.value[0];
|
||||
|
||||
|
|
|
@ -209,16 +209,9 @@ static int dw_i2s_hw_params(struct snd_pcm_substream *substream,
|
|||
|
||||
switch (config->chan_nr) {
|
||||
case EIGHT_CHANNEL_SUPPORT:
|
||||
ch_reg = 3;
|
||||
break;
|
||||
case SIX_CHANNEL_SUPPORT:
|
||||
ch_reg = 2;
|
||||
break;
|
||||
case FOUR_CHANNEL_SUPPORT:
|
||||
ch_reg = 1;
|
||||
break;
|
||||
case TWO_CHANNEL_SUPPORT:
|
||||
ch_reg = 0;
|
||||
break;
|
||||
default:
|
||||
dev_err(dev->dev, "channel not supported\n");
|
||||
|
@ -227,18 +220,22 @@ static int dw_i2s_hw_params(struct snd_pcm_substream *substream,
|
|||
|
||||
i2s_disable_channels(dev, substream->stream);
|
||||
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||
i2s_write_reg(dev->i2s_base, TCR(ch_reg), xfer_resolution);
|
||||
i2s_write_reg(dev->i2s_base, TFCR(ch_reg), 0x02);
|
||||
irq = i2s_read_reg(dev->i2s_base, IMR(ch_reg));
|
||||
i2s_write_reg(dev->i2s_base, IMR(ch_reg), irq & ~0x30);
|
||||
i2s_write_reg(dev->i2s_base, TER(ch_reg), 1);
|
||||
} else {
|
||||
i2s_write_reg(dev->i2s_base, RCR(ch_reg), xfer_resolution);
|
||||
i2s_write_reg(dev->i2s_base, RFCR(ch_reg), 0x07);
|
||||
irq = i2s_read_reg(dev->i2s_base, IMR(ch_reg));
|
||||
i2s_write_reg(dev->i2s_base, IMR(ch_reg), irq & ~0x03);
|
||||
i2s_write_reg(dev->i2s_base, RER(ch_reg), 1);
|
||||
for (ch_reg = 0; ch_reg < (config->chan_nr / 2); ch_reg++) {
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||
i2s_write_reg(dev->i2s_base, TCR(ch_reg),
|
||||
xfer_resolution);
|
||||
i2s_write_reg(dev->i2s_base, TFCR(ch_reg), 0x02);
|
||||
irq = i2s_read_reg(dev->i2s_base, IMR(ch_reg));
|
||||
i2s_write_reg(dev->i2s_base, IMR(ch_reg), irq & ~0x30);
|
||||
i2s_write_reg(dev->i2s_base, TER(ch_reg), 1);
|
||||
} else {
|
||||
i2s_write_reg(dev->i2s_base, RCR(ch_reg),
|
||||
xfer_resolution);
|
||||
i2s_write_reg(dev->i2s_base, RFCR(ch_reg), 0x07);
|
||||
irq = i2s_read_reg(dev->i2s_base, IMR(ch_reg));
|
||||
i2s_write_reg(dev->i2s_base, IMR(ch_reg), irq & ~0x03);
|
||||
i2s_write_reg(dev->i2s_base, RER(ch_reg), 1);
|
||||
}
|
||||
}
|
||||
|
||||
i2s_write_reg(dev->i2s_base, CCR, ccr);
|
||||
|
@ -263,6 +260,19 @@ static void dw_i2s_shutdown(struct snd_pcm_substream *substream,
|
|||
snd_soc_dai_set_dma_data(dai, substream, NULL);
|
||||
}
|
||||
|
||||
static int dw_i2s_prepare(struct snd_pcm_substream *substream,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
|
||||
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
i2s_write_reg(dev->i2s_base, TXFFR, 1);
|
||||
else
|
||||
i2s_write_reg(dev->i2s_base, RXFFR, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dw_i2s_trigger(struct snd_pcm_substream *substream,
|
||||
int cmd, struct snd_soc_dai *dai)
|
||||
{
|
||||
|
@ -294,6 +304,7 @@ static struct snd_soc_dai_ops dw_i2s_dai_ops = {
|
|||
.startup = dw_i2s_startup,
|
||||
.shutdown = dw_i2s_shutdown,
|
||||
.hw_params = dw_i2s_hw_params,
|
||||
.prepare = dw_i2s_prepare,
|
||||
.trigger = dw_i2s_trigger,
|
||||
};
|
||||
|
||||
|
|
|
@ -89,7 +89,7 @@ config SND_SOC_INTEL_BROADWELL_MACH
|
|||
|
||||
config SND_SOC_INTEL_BYTCR_RT5640_MACH
|
||||
tristate "ASoC Audio DSP Support for MID BYT Platform"
|
||||
depends on X86
|
||||
depends on X86 && I2C
|
||||
select SND_SOC_RT5640
|
||||
select SND_SST_MFLD_PLATFORM
|
||||
select SND_SST_IPC_ACPI
|
||||
|
@ -101,7 +101,7 @@ config SND_SOC_INTEL_BYTCR_RT5640_MACH
|
|||
|
||||
config SND_SOC_INTEL_CHT_BSW_RT5672_MACH
|
||||
tristate "ASoC Audio driver for Intel Cherrytrail & Braswell with RT5672 codec"
|
||||
depends on X86_INTEL_LPSS
|
||||
depends on X86_INTEL_LPSS && I2C
|
||||
select SND_SOC_RT5670
|
||||
select SND_SST_MFLD_PLATFORM
|
||||
select SND_SST_IPC_ACPI
|
||||
|
|
|
@ -227,4 +227,4 @@ module_platform_driver(snd_byt_mc_driver);
|
|||
MODULE_DESCRIPTION("ASoC Intel(R) Baytrail CR Machine driver");
|
||||
MODULE_AUTHOR("Subhransu S. Prusty <subhransu.s.prusty@intel.com>");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_ALIAS("platform:bytrt5640-audio");
|
||||
MODULE_ALIAS("platform:bytt100_rt5640");
|
||||
|
|
|
@ -763,8 +763,12 @@ static int block_alloc_fixed(struct sst_dsp *dsp, struct sst_block_allocator *ba
|
|||
/* does block span more than 1 section */
|
||||
if (ba->offset >= block->offset && ba->offset < block_end) {
|
||||
|
||||
/* add block */
|
||||
list_move(&block->list, &dsp->used_block_list);
|
||||
list_add(&block->module_list, block_list);
|
||||
/* align ba to block boundary */
|
||||
ba->offset = block->offset;
|
||||
ba->size -= block_end - ba->offset;
|
||||
ba->offset = block_end;
|
||||
|
||||
err = block_alloc_contiguous(dsp, ba, block_list);
|
||||
if (err < 0)
|
||||
|
|
|
@ -343,7 +343,7 @@ int sst_acpi_remove(struct platform_device *pdev)
|
|||
}
|
||||
|
||||
static struct sst_machines sst_acpi_bytcr[] = {
|
||||
{"10EC5640", "T100", "bytt100_rt5640", NULL, "fw_sst_0f28.bin",
|
||||
{"10EC5640", "T100", "bytt100_rt5640", NULL, "intel/fw_sst_0f28.bin",
|
||||
&byt_rvp_platform_data },
|
||||
{},
|
||||
};
|
||||
|
|
|
@ -454,11 +454,11 @@ static int rockchip_i2s_probe(struct platform_device *pdev)
|
|||
|
||||
i2s->playback_dma_data.addr = res->start + I2S_TXDR;
|
||||
i2s->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
|
||||
i2s->playback_dma_data.maxburst = 16;
|
||||
i2s->playback_dma_data.maxburst = 4;
|
||||
|
||||
i2s->capture_dma_data.addr = res->start + I2S_RXDR;
|
||||
i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
|
||||
i2s->capture_dma_data.maxburst = 16;
|
||||
i2s->capture_dma_data.maxburst = 4;
|
||||
|
||||
i2s->dev = &pdev->dev;
|
||||
dev_set_drvdata(&pdev->dev, i2s);
|
||||
|
|
|
@ -127,7 +127,7 @@
|
|||
#define I2S_DMACR_TDE_DISABLE (0 << I2S_DMACR_TDE_SHIFT)
|
||||
#define I2S_DMACR_TDE_ENABLE (1 << I2S_DMACR_TDE_SHIFT)
|
||||
#define I2S_DMACR_TDL_SHIFT 0
|
||||
#define I2S_DMACR_TDL(x) ((x - 1) << I2S_DMACR_TDL_SHIFT)
|
||||
#define I2S_DMACR_TDL(x) ((x) << I2S_DMACR_TDL_SHIFT)
|
||||
#define I2S_DMACR_TDL_MASK (0x1f << I2S_DMACR_TDL_SHIFT)
|
||||
|
||||
/*
|
||||
|
|
|
@ -3230,7 +3230,7 @@ int snd_soc_of_parse_audio_routing(struct snd_soc_card *card,
|
|||
const char *propname)
|
||||
{
|
||||
struct device_node *np = card->dev->of_node;
|
||||
int num_routes, old_routes;
|
||||
int num_routes;
|
||||
struct snd_soc_dapm_route *routes;
|
||||
int i, ret;
|
||||
|
||||
|
@ -3248,9 +3248,7 @@ int snd_soc_of_parse_audio_routing(struct snd_soc_card *card,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
old_routes = card->num_dapm_routes;
|
||||
routes = devm_kzalloc(card->dev,
|
||||
(old_routes + num_routes) * sizeof(*routes),
|
||||
routes = devm_kzalloc(card->dev, num_routes * sizeof(*routes),
|
||||
GFP_KERNEL);
|
||||
if (!routes) {
|
||||
dev_err(card->dev,
|
||||
|
@ -3258,11 +3256,9 @@ int snd_soc_of_parse_audio_routing(struct snd_soc_card *card,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
memcpy(routes, card->dapm_routes, old_routes * sizeof(*routes));
|
||||
|
||||
for (i = 0; i < num_routes; i++) {
|
||||
ret = of_property_read_string_index(np, propname,
|
||||
2 * i, &routes[old_routes + i].sink);
|
||||
2 * i, &routes[i].sink);
|
||||
if (ret) {
|
||||
dev_err(card->dev,
|
||||
"ASoC: Property '%s' index %d could not be read: %d\n",
|
||||
|
@ -3270,7 +3266,7 @@ int snd_soc_of_parse_audio_routing(struct snd_soc_card *card,
|
|||
return -EINVAL;
|
||||
}
|
||||
ret = of_property_read_string_index(np, propname,
|
||||
(2 * i) + 1, &routes[old_routes + i].source);
|
||||
(2 * i) + 1, &routes[i].source);
|
||||
if (ret) {
|
||||
dev_err(card->dev,
|
||||
"ASoC: Property '%s' index %d could not be read: %d\n",
|
||||
|
@ -3279,7 +3275,7 @@ int snd_soc_of_parse_audio_routing(struct snd_soc_card *card,
|
|||
}
|
||||
}
|
||||
|
||||
card->num_dapm_routes += num_routes;
|
||||
card->num_dapm_routes = num_routes;
|
||||
card->dapm_routes = routes;
|
||||
|
||||
return 0;
|
||||
|
|
Загрузка…
Ссылка в новой задаче