Merge branch 'linux-linaro-lsk' into linux-linaro-lsk-android
This commit is contained in:
commit
69284a3b89
121 changed files with 1026 additions and 410 deletions
|
|
@ -25,6 +25,8 @@ Supported adapters:
|
|||
* Intel Avoton (SOC)
|
||||
* Intel Wellsburg (PCH)
|
||||
* Intel Coleto Creek (PCH)
|
||||
* Intel Wildcat Point-LP (PCH)
|
||||
* Intel BayTrail (SOC)
|
||||
Datasheets: Publicly available at the Intel website
|
||||
|
||||
On Intel Patsburg and later chipsets, both the normal host SMBus controller
|
||||
|
|
|
|||
|
|
@ -504,9 +504,12 @@ byte 5:
|
|||
* reg_10
|
||||
|
||||
bit 7 6 5 4 3 2 1 0
|
||||
0 0 0 0 0 0 0 A
|
||||
0 0 0 0 R F T A
|
||||
|
||||
A: 1 = enable absolute tracking
|
||||
T: 1 = enable two finger mode auto correct
|
||||
F: 1 = disable ABS Position Filter
|
||||
R: 1 = enable real hardware resolution
|
||||
|
||||
6.2 Native absolute mode 6 byte packet format
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
|
|
|||
|
|
@ -315,7 +315,7 @@ Andrew Morton が Linux-kernel メーリングリストにカーネルリリー
|
|||
もし、2.6.x.y カーネルが存在しない場合には、番号が一番大きい 2.6.x が
|
||||
最新の安定版カーネルです。
|
||||
|
||||
2.6.x.y は "stable" チーム <stable@kernel.org> でメンテされており、必
|
||||
2.6.x.y は "stable" チーム <stable@vger.kernel.org> でメンテされており、必
|
||||
要に応じてリリースされます。通常のリリース期間は 2週間毎ですが、差し迫っ
|
||||
た問題がなければもう少し長くなることもあります。セキュリティ関連の問題
|
||||
の場合はこれに対してだいたいの場合、すぐにリリースがされます。
|
||||
|
|
|
|||
|
|
@ -50,16 +50,16 @@ linux-2.6.29/Documentation/stable_kernel_rules.txt
|
|||
|
||||
-stable ツリーにパッチを送付する手続き-
|
||||
|
||||
- 上記の規則に従っているかを確認した後に、stable@kernel.org にパッチ
|
||||
- 上記の規則に従っているかを確認した後に、stable@vger.kernel.org にパッチ
|
||||
を送る。
|
||||
- 送信者はパッチがキューに受け付けられた際には ACK を、却下された場合
|
||||
には NAK を受け取る。この反応は開発者たちのスケジュールによって、数
|
||||
日かかる場合がある。
|
||||
- もし受け取られたら、パッチは他の開発者たちと関連するサブシステムの
|
||||
メンテナーによるレビューのために -stable キューに追加される。
|
||||
- パッチに stable@kernel.org のアドレスが付加されているときには、それ
|
||||
- パッチに stable@vger.kernel.org のアドレスが付加されているときには、それ
|
||||
が Linus のツリーに入る時に自動的に stable チームに email される。
|
||||
- セキュリティパッチはこのエイリアス (stable@kernel.org) に送られるべ
|
||||
- セキュリティパッチはこのエイリアス (stable@vger.kernel.org) に送られるべ
|
||||
きではなく、代わりに security@kernel.org のアドレスに送られる。
|
||||
|
||||
レビューサイクル-
|
||||
|
|
|
|||
|
|
@ -237,7 +237,7 @@ kernel.org网站的pub/linux/kernel/v2.6/目录下找到它。它的开发遵循
|
|||
如果没有2.6.x.y版本内核存在,那么最新的2.6.x版本内核就相当于是当前的稳定
|
||||
版内核。
|
||||
|
||||
2.6.x.y版本由“稳定版”小组(邮件地址<stable@kernel.org>)维护,一般隔周发
|
||||
2.6.x.y版本由“稳定版”小组(邮件地址<stable@vger.kernel.org>)维护,一般隔周发
|
||||
布新版本。
|
||||
|
||||
内核源码中的Documentation/stable_kernel_rules.txt文件具体描述了可被稳定
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ Documentation/stable_kernel_rules.txt 的中文翻译
|
|||
|
||||
向稳定版代码树提交补丁的过程:
|
||||
|
||||
- 在确认了补丁符合以上的规则后,将补丁发送到stable@kernel.org。
|
||||
- 在确认了补丁符合以上的规则后,将补丁发送到stable@vger.kernel.org。
|
||||
- 如果补丁被接受到队列里,发送者会收到一个ACK回复,如果没有被接受,收
|
||||
到的是NAK回复。回复需要几天的时间,这取决于开发者的时间安排。
|
||||
- 被接受的补丁会被加到稳定版本队列里,等待其他开发者的审查。
|
||||
|
|
|
|||
2
Makefile
2
Makefile
|
|
@ -1,6 +1,6 @@
|
|||
VERSION = 3
|
||||
PATCHLEVEL = 10
|
||||
SUBLEVEL = 41
|
||||
SUBLEVEL = 42
|
||||
EXTRAVERSION =
|
||||
NAME = TOSSUG Baby Fish
|
||||
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@
|
|||
ipu: ipu@18000000 {
|
||||
#crtc-cells = <1>;
|
||||
compatible = "fsl,imx53-ipu";
|
||||
reg = <0x18000000 0x080000000>;
|
||||
reg = <0x18000000 0x08000000>;
|
||||
interrupts = <11 10>;
|
||||
clocks = <&clks 59>, <&clks 110>, <&clks 61>;
|
||||
clock-names = "bus", "di0", "di1";
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
|
|||
if (!csize)
|
||||
return 0;
|
||||
|
||||
vaddr = ioremap(pfn << PAGE_SHIFT, PAGE_SIZE);
|
||||
vaddr = ioremap(__pfn_to_phys(pfn), PAGE_SIZE);
|
||||
if (!vaddr)
|
||||
return -ENOMEM;
|
||||
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ static inline void wr_fence(void)
|
|||
volatile int *flushptr = (volatile int *) LINSYSEVENT_WR_FENCE;
|
||||
barrier();
|
||||
*flushptr = 0;
|
||||
barrier();
|
||||
}
|
||||
|
||||
#else /* CONFIG_METAG_META21 */
|
||||
|
|
@ -35,6 +36,7 @@ static inline void wr_fence(void)
|
|||
*flushptr = 0;
|
||||
*flushptr = 0;
|
||||
*flushptr = 0;
|
||||
barrier();
|
||||
}
|
||||
|
||||
#endif /* !CONFIG_METAG_META21 */
|
||||
|
|
@ -68,6 +70,7 @@ static inline void fence(void)
|
|||
volatile int *flushptr = (volatile int *) LINSYSEVENT_WR_ATOMIC_UNLOCK;
|
||||
barrier();
|
||||
*flushptr = 0;
|
||||
barrier();
|
||||
}
|
||||
#define smp_mb() fence()
|
||||
#define smp_rmb() fence()
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@
|
|||
/* Add an extra page of padding at the top of the stack for the guard page. */
|
||||
#define STACK_TOP (TASK_SIZE - PAGE_SIZE)
|
||||
#define STACK_TOP_MAX STACK_TOP
|
||||
/* Maximum virtual space for stack */
|
||||
#define STACK_SIZE_MAX (1 << 28) /* 256 MB */
|
||||
|
||||
/* This decides where the kernel will search for a free chunk of vm
|
||||
* space during mmap's.
|
||||
|
|
|
|||
|
|
@ -635,7 +635,7 @@ static void octeon_irq_cpu_offline_ciu(struct irq_data *data)
|
|||
cpumask_clear(&new_affinity);
|
||||
cpumask_set_cpu(cpumask_first(cpu_online_mask), &new_affinity);
|
||||
}
|
||||
__irq_set_affinity_locked(data, &new_affinity);
|
||||
irq_set_affinity_locked(data, &new_affinity, false);
|
||||
}
|
||||
|
||||
static int octeon_irq_ciu_set_affinity(struct irq_data *data,
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
};
|
||||
|
||||
memory@0 {
|
||||
device_type = "memory";
|
||||
reg = <0x0 0x2000000>;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
model = "Ralink MT7620A evaluation board";
|
||||
|
||||
memory@0 {
|
||||
device_type = "memory";
|
||||
reg = <0x0 0x2000000>;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
model = "Ralink RT2880 evaluation board";
|
||||
|
||||
memory@0 {
|
||||
device_type = "memory";
|
||||
reg = <0x8000000 0x2000000>;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
model = "Ralink RT3052 evaluation board";
|
||||
|
||||
memory@0 {
|
||||
device_type = "memory";
|
||||
reg = <0x0 0x2000000>;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
model = "Ralink RT3883 evaluation board";
|
||||
|
||||
memory@0 {
|
||||
device_type = "memory";
|
||||
reg = <0x0 0x2000000>;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -53,6 +53,8 @@
|
|||
#define STACK_TOP TASK_SIZE
|
||||
#define STACK_TOP_MAX DEFAULT_TASK_SIZE
|
||||
|
||||
#define STACK_SIZE_MAX (1 << 30) /* 1 GB */
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
|
|
|||
|
|
@ -97,7 +97,9 @@ CFLAGS-$(CONFIG_POWER7_CPU) += $(call cc-option,-mcpu=power7)
|
|||
|
||||
CFLAGS-$(CONFIG_TUNE_CELL) += $(call cc-option,-mtune=cell)
|
||||
|
||||
KBUILD_CPPFLAGS += -Iarch/$(ARCH)
|
||||
asinstr := $(call as-instr,lis 9$(comma)foo@high,-DHAVE_AS_ATHIGH=1)
|
||||
|
||||
KBUILD_CPPFLAGS += -Iarch/$(ARCH) $(asinstr)
|
||||
KBUILD_AFLAGS += -Iarch/$(ARCH)
|
||||
KBUILD_CFLAGS += -msoft-float -pipe -Iarch/$(ARCH) $(CFLAGS-y)
|
||||
CPP = $(CC) -E $(KBUILD_CFLAGS)
|
||||
|
|
|
|||
|
|
@ -390,11 +390,16 @@ n:
|
|||
* ld rY,ADDROFF(name)(rX)
|
||||
*/
|
||||
#ifdef __powerpc64__
|
||||
#ifdef HAVE_AS_ATHIGH
|
||||
#define __AS_ATHIGH high
|
||||
#else
|
||||
#define __AS_ATHIGH h
|
||||
#endif
|
||||
#define LOAD_REG_IMMEDIATE(reg,expr) \
|
||||
lis reg,(expr)@highest; \
|
||||
ori reg,reg,(expr)@higher; \
|
||||
rldicr reg,reg,32,31; \
|
||||
oris reg,reg,(expr)@h; \
|
||||
oris reg,reg,(expr)@__AS_ATHIGH; \
|
||||
ori reg,reg,(expr)@l;
|
||||
|
||||
#define LOAD_REG_ADDR(reg,name) \
|
||||
|
|
|
|||
|
|
@ -948,6 +948,16 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
|
|||
flush_altivec_to_thread(src);
|
||||
flush_vsx_to_thread(src);
|
||||
flush_spe_to_thread(src);
|
||||
/*
|
||||
* Flush TM state out so we can copy it. __switch_to_tm() does this
|
||||
* flush but it removes the checkpointed state from the current CPU and
|
||||
* transitions the CPU out of TM mode. Hence we need to call
|
||||
* tm_recheckpoint_new_task() (on the same task) to restore the
|
||||
* checkpointed state back and the TM mode.
|
||||
*/
|
||||
__switch_to_tm(src);
|
||||
tm_recheckpoint_new_task(src);
|
||||
|
||||
*dst = *src;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -818,6 +818,9 @@ static int ctr_aes_crypt(struct blkcipher_desc *desc, long func,
|
|||
else
|
||||
memcpy(walk->iv, ctrptr, AES_BLOCK_SIZE);
|
||||
spin_unlock(&ctrblk_lock);
|
||||
} else {
|
||||
if (!nbytes)
|
||||
memcpy(walk->iv, ctrptr, AES_BLOCK_SIZE);
|
||||
}
|
||||
/*
|
||||
* final block may be < AES_BLOCK_SIZE, copy only nbytes
|
||||
|
|
|
|||
|
|
@ -429,6 +429,9 @@ static int ctr_desall_crypt(struct blkcipher_desc *desc, long func,
|
|||
else
|
||||
memcpy(walk->iv, ctrptr, DES_BLOCK_SIZE);
|
||||
spin_unlock(&ctrblk_lock);
|
||||
} else {
|
||||
if (!nbytes)
|
||||
memcpy(walk->iv, ctrptr, DES_BLOCK_SIZE);
|
||||
}
|
||||
/* final block may be < DES_BLOCK_SIZE, copy only nbytes */
|
||||
if (nbytes) {
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
|
|||
static inline void huge_ptep_clear_flush(struct vm_area_struct *vma,
|
||||
unsigned long addr, pte_t *ptep)
|
||||
{
|
||||
ptep_clear_flush(vma, addr, ptep);
|
||||
}
|
||||
|
||||
static inline int huge_pte_none(pte_t pte)
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@
|
|||
#include <asm/mmu_context.h>
|
||||
#include <asm/syscalls.h>
|
||||
|
||||
int sysctl_ldt16 = 0;
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
static void flush_ldt(void *current_mm)
|
||||
{
|
||||
|
|
@ -234,7 +236,7 @@ static int write_ldt(void __user *ptr, unsigned long bytecount, int oldmode)
|
|||
* IRET leaking the high bits of the kernel stack address.
|
||||
*/
|
||||
#ifdef CONFIG_X86_64
|
||||
if (!ldt_info.seg_32bit) {
|
||||
if (!ldt_info.seg_32bit && !sysctl_ldt16) {
|
||||
error = -EINVAL;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ enum {
|
|||
#ifdef CONFIG_X86_64
|
||||
#define vdso_enabled sysctl_vsyscall32
|
||||
#define arch_setup_additional_pages syscall32_setup_pages
|
||||
extern int sysctl_ldt16;
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -380,6 +381,13 @@ static ctl_table abi_table2[] = {
|
|||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec
|
||||
},
|
||||
{
|
||||
.procname = "ldt16",
|
||||
.data = &sysctl_ldt16,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ static void __exit crypto_wq_exit(void)
|
|||
destroy_workqueue(kcrypto_wq);
|
||||
}
|
||||
|
||||
module_init(crypto_wq_init);
|
||||
subsys_initcall(crypto_wq_init);
|
||||
module_exit(crypto_wq_exit);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
|||
|
|
@ -327,6 +327,19 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = {
|
|||
DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T500"),
|
||||
},
|
||||
},
|
||||
/*
|
||||
* Without this this EEEpc exports a non working WMI interface, with
|
||||
* this it exports a working "good old" eeepc_laptop interface, fixing
|
||||
* both brightness control, and rfkill not working.
|
||||
*/
|
||||
{
|
||||
.callback = dmi_enable_osi_linux,
|
||||
.ident = "Asus EEE PC 1015PX",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer INC."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "1015PX"),
|
||||
},
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -6300,6 +6300,8 @@ int ata_host_activate(struct ata_host *host, int irq,
|
|||
static void ata_port_detach(struct ata_port *ap)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct ata_link *link;
|
||||
struct ata_device *dev;
|
||||
|
||||
if (!ap->ops->error_handler)
|
||||
goto skip_eh;
|
||||
|
|
@ -6319,6 +6321,13 @@ static void ata_port_detach(struct ata_port *ap)
|
|||
cancel_delayed_work_sync(&ap->hotplug_task);
|
||||
|
||||
skip_eh:
|
||||
/* clean up zpodd on port removal */
|
||||
ata_for_each_link(link, ap, HOST_FIRST) {
|
||||
ata_for_each_dev(dev, link, ALL) {
|
||||
if (zpodd_dev_enabled(dev))
|
||||
zpodd_exit(dev);
|
||||
}
|
||||
}
|
||||
if (ap->pmp_link) {
|
||||
int i;
|
||||
for (i = 0; i < SATA_PMP_MAX_PORTS; i++)
|
||||
|
|
|
|||
|
|
@ -408,12 +408,13 @@ static int pata_at91_probe(struct platform_device *pdev)
|
|||
|
||||
host->private_data = info;
|
||||
|
||||
return ata_host_activate(host, gpio_is_valid(irq) ? gpio_to_irq(irq) : 0,
|
||||
gpio_is_valid(irq) ? ata_sff_interrupt : NULL,
|
||||
irq_flags, &pata_at91_sht);
|
||||
ret = ata_host_activate(host, gpio_is_valid(irq) ? gpio_to_irq(irq) : 0,
|
||||
gpio_is_valid(irq) ? ata_sff_interrupt : NULL,
|
||||
irq_flags, &pata_at91_sht);
|
||||
if (ret)
|
||||
goto err_put;
|
||||
|
||||
if (!ret)
|
||||
return 0;
|
||||
return 0;
|
||||
|
||||
err_put:
|
||||
clk_put(info->mck);
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ static DEFINE_MUTEX(deferred_probe_mutex);
|
|||
static LIST_HEAD(deferred_probe_pending_list);
|
||||
static LIST_HEAD(deferred_probe_active_list);
|
||||
static struct workqueue_struct *deferred_wq;
|
||||
static atomic_t deferred_trigger_count = ATOMIC_INIT(0);
|
||||
|
||||
/**
|
||||
* deferred_probe_work_func() - Retry probing devices in the active list.
|
||||
|
|
@ -135,6 +136,17 @@ static bool driver_deferred_probe_enable = false;
|
|||
* This functions moves all devices from the pending list to the active
|
||||
* list and schedules the deferred probe workqueue to process them. It
|
||||
* should be called anytime a driver is successfully bound to a device.
|
||||
*
|
||||
* Note, there is a race condition in multi-threaded probe. In the case where
|
||||
* more than one device is probing at the same time, it is possible for one
|
||||
* probe to complete successfully while another is about to defer. If the second
|
||||
* depends on the first, then it will get put on the pending list after the
|
||||
* trigger event has already occured and will be stuck there.
|
||||
*
|
||||
* The atomic 'deferred_trigger_count' is used to determine if a successful
|
||||
* trigger has occurred in the midst of probing a driver. If the trigger count
|
||||
* changes in the midst of a probe, then deferred processing should be triggered
|
||||
* again.
|
||||
*/
|
||||
static void driver_deferred_probe_trigger(void)
|
||||
{
|
||||
|
|
@ -147,6 +159,7 @@ static void driver_deferred_probe_trigger(void)
|
|||
* into the active list so they can be retried by the workqueue
|
||||
*/
|
||||
mutex_lock(&deferred_probe_mutex);
|
||||
atomic_inc(&deferred_trigger_count);
|
||||
list_splice_tail_init(&deferred_probe_pending_list,
|
||||
&deferred_probe_active_list);
|
||||
mutex_unlock(&deferred_probe_mutex);
|
||||
|
|
@ -265,6 +278,7 @@ static DECLARE_WAIT_QUEUE_HEAD(probe_waitqueue);
|
|||
static int really_probe(struct device *dev, struct device_driver *drv)
|
||||
{
|
||||
int ret = 0;
|
||||
int local_trigger_count = atomic_read(&deferred_trigger_count);
|
||||
|
||||
atomic_inc(&probe_count);
|
||||
pr_debug("bus: '%s': %s: probing driver %s with device %s\n",
|
||||
|
|
@ -310,6 +324,9 @@ probe_failed:
|
|||
/* Driver requested deferred probing */
|
||||
dev_info(dev, "Driver %s requests probe deferral\n", drv->name);
|
||||
driver_deferred_probe_add(dev);
|
||||
/* Did a trigger occur while probing? Need to re-trigger if yes */
|
||||
if (local_trigger_count != atomic_read(&deferred_trigger_count))
|
||||
driver_deferred_probe_trigger();
|
||||
} else if (ret != -ENODEV && ret != -ENXIO) {
|
||||
/* driver matched but the probe failed */
|
||||
printk(KERN_WARNING
|
||||
|
|
|
|||
|
|
@ -40,8 +40,7 @@
|
|||
static ssize_t show_##name(struct device *dev, \
|
||||
struct device_attribute *attr, char *buf) \
|
||||
{ \
|
||||
unsigned int cpu = dev->id; \
|
||||
return sprintf(buf, "%d\n", topology_##name(cpu)); \
|
||||
return sprintf(buf, "%d\n", topology_##name(dev->id)); \
|
||||
}
|
||||
|
||||
#if defined(topology_thread_cpumask) || defined(topology_core_cpumask) || \
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@ struct blkfront_info
|
|||
struct work_struct work;
|
||||
struct gnttab_free_callback callback;
|
||||
struct blk_shadow shadow[BLK_RING_SIZE];
|
||||
struct list_head persistent_gnts;
|
||||
struct list_head grants;
|
||||
unsigned int persistent_gnts_c;
|
||||
unsigned long shadow_free;
|
||||
unsigned int feature_flush;
|
||||
|
|
@ -175,15 +175,17 @@ static int fill_grant_buffer(struct blkfront_info *info, int num)
|
|||
if (!gnt_list_entry)
|
||||
goto out_of_memory;
|
||||
|
||||
granted_page = alloc_page(GFP_NOIO);
|
||||
if (!granted_page) {
|
||||
kfree(gnt_list_entry);
|
||||
goto out_of_memory;
|
||||
if (info->feature_persistent) {
|
||||
granted_page = alloc_page(GFP_NOIO);
|
||||
if (!granted_page) {
|
||||
kfree(gnt_list_entry);
|
||||
goto out_of_memory;
|
||||
}
|
||||
gnt_list_entry->pfn = page_to_pfn(granted_page);
|
||||
}
|
||||
|
||||
gnt_list_entry->pfn = page_to_pfn(granted_page);
|
||||
gnt_list_entry->gref = GRANT_INVALID_REF;
|
||||
list_add(&gnt_list_entry->node, &info->persistent_gnts);
|
||||
list_add(&gnt_list_entry->node, &info->grants);
|
||||
i++;
|
||||
}
|
||||
|
||||
|
|
@ -191,9 +193,10 @@ static int fill_grant_buffer(struct blkfront_info *info, int num)
|
|||
|
||||
out_of_memory:
|
||||
list_for_each_entry_safe(gnt_list_entry, n,
|
||||
&info->persistent_gnts, node) {
|
||||
&info->grants, node) {
|
||||
list_del(&gnt_list_entry->node);
|
||||
__free_page(pfn_to_page(gnt_list_entry->pfn));
|
||||
if (info->feature_persistent)
|
||||
__free_page(pfn_to_page(gnt_list_entry->pfn));
|
||||
kfree(gnt_list_entry);
|
||||
i--;
|
||||
}
|
||||
|
|
@ -202,14 +205,14 @@ out_of_memory:
|
|||
}
|
||||
|
||||
static struct grant *get_grant(grant_ref_t *gref_head,
|
||||
unsigned long pfn,
|
||||
struct blkfront_info *info)
|
||||
{
|
||||
struct grant *gnt_list_entry;
|
||||
unsigned long buffer_mfn;
|
||||
|
||||
BUG_ON(list_empty(&info->persistent_gnts));
|
||||
gnt_list_entry = list_first_entry(&info->persistent_gnts, struct grant,
|
||||
node);
|
||||
BUG_ON(list_empty(&info->grants));
|
||||
gnt_list_entry = list_first_entry(&info->grants, struct grant, node);
|
||||
list_del(&gnt_list_entry->node);
|
||||
|
||||
if (gnt_list_entry->gref != GRANT_INVALID_REF) {
|
||||
|
|
@ -220,6 +223,10 @@ static struct grant *get_grant(grant_ref_t *gref_head,
|
|||
/* Assign a gref to this page */
|
||||
gnt_list_entry->gref = gnttab_claim_grant_reference(gref_head);
|
||||
BUG_ON(gnt_list_entry->gref == -ENOSPC);
|
||||
if (!info->feature_persistent) {
|
||||
BUG_ON(!pfn);
|
||||
gnt_list_entry->pfn = pfn;
|
||||
}
|
||||
buffer_mfn = pfn_to_mfn(gnt_list_entry->pfn);
|
||||
gnttab_grant_foreign_access_ref(gnt_list_entry->gref,
|
||||
info->xbdev->otherend_id,
|
||||
|
|
@ -430,12 +437,12 @@ static int blkif_queue_request(struct request *req)
|
|||
fsect = sg->offset >> 9;
|
||||
lsect = fsect + (sg->length >> 9) - 1;
|
||||
|
||||
gnt_list_entry = get_grant(&gref_head, info);
|
||||
gnt_list_entry = get_grant(&gref_head, page_to_pfn(sg_page(sg)), info);
|
||||
ref = gnt_list_entry->gref;
|
||||
|
||||
info->shadow[id].grants_used[i] = gnt_list_entry;
|
||||
|
||||
if (rq_data_dir(req)) {
|
||||
if (rq_data_dir(req) && info->feature_persistent) {
|
||||
char *bvec_data;
|
||||
void *shared_data;
|
||||
|
||||
|
|
@ -828,16 +835,17 @@ static void blkif_free(struct blkfront_info *info, int suspend)
|
|||
blk_stop_queue(info->rq);
|
||||
|
||||
/* Remove all persistent grants */
|
||||
if (!list_empty(&info->persistent_gnts)) {
|
||||
if (!list_empty(&info->grants)) {
|
||||
list_for_each_entry_safe(persistent_gnt, n,
|
||||
&info->persistent_gnts, node) {
|
||||
&info->grants, node) {
|
||||
list_del(&persistent_gnt->node);
|
||||
if (persistent_gnt->gref != GRANT_INVALID_REF) {
|
||||
gnttab_end_foreign_access(persistent_gnt->gref,
|
||||
0, 0UL);
|
||||
info->persistent_gnts_c--;
|
||||
}
|
||||
__free_page(pfn_to_page(persistent_gnt->pfn));
|
||||
if (info->feature_persistent)
|
||||
__free_page(pfn_to_page(persistent_gnt->pfn));
|
||||
kfree(persistent_gnt);
|
||||
}
|
||||
}
|
||||
|
|
@ -874,7 +882,7 @@ static void blkif_completion(struct blk_shadow *s, struct blkfront_info *info,
|
|||
|
||||
nseg = s->req.u.rw.nr_segments;
|
||||
|
||||
if (bret->operation == BLKIF_OP_READ) {
|
||||
if (bret->operation == BLKIF_OP_READ && info->feature_persistent) {
|
||||
/*
|
||||
* Copy the data received from the backend into the bvec.
|
||||
* Since bv_offset can be different than 0, and bv_len different
|
||||
|
|
@ -894,9 +902,30 @@ static void blkif_completion(struct blk_shadow *s, struct blkfront_info *info,
|
|||
}
|
||||
}
|
||||
/* Add the persistent grant into the list of free grants */
|
||||
for (i = 0; i < s->req.u.rw.nr_segments; i++) {
|
||||
list_add(&s->grants_used[i]->node, &info->persistent_gnts);
|
||||
info->persistent_gnts_c++;
|
||||
for (i = 0; i < nseg; i++) {
|
||||
if (gnttab_query_foreign_access(s->grants_used[i]->gref)) {
|
||||
/*
|
||||
* If the grant is still mapped by the backend (the
|
||||
* backend has chosen to make this grant persistent)
|
||||
* we add it at the head of the list, so it will be
|
||||
* reused first.
|
||||
*/
|
||||
if (!info->feature_persistent)
|
||||
pr_alert_ratelimited("backed has not unmapped grant: %u\n",
|
||||
s->grants_used[i]->gref);
|
||||
list_add(&s->grants_used[i]->node, &info->grants);
|
||||
info->persistent_gnts_c++;
|
||||
} else {
|
||||
/*
|
||||
* If the grant is not mapped by the backend we end the
|
||||
* foreign access and add it to the tail of the list,
|
||||
* so it will not be picked again unless we run out of
|
||||
* persistent grants.
|
||||
*/
|
||||
gnttab_end_foreign_access(s->grants_used[i]->gref, 0, 0UL);
|
||||
s->grants_used[i]->gref = GRANT_INVALID_REF;
|
||||
list_add_tail(&s->grants_used[i]->node, &info->grants);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1034,12 +1063,6 @@ static int setup_blkring(struct xenbus_device *dev,
|
|||
for (i = 0; i < BLK_RING_SIZE; i++)
|
||||
sg_init_table(info->shadow[i].sg, BLKIF_MAX_SEGMENTS_PER_REQUEST);
|
||||
|
||||
/* Allocate memory for grants */
|
||||
err = fill_grant_buffer(info, BLK_RING_SIZE *
|
||||
BLKIF_MAX_SEGMENTS_PER_REQUEST);
|
||||
if (err)
|
||||
goto fail;
|
||||
|
||||
err = xenbus_grant_ring(dev, virt_to_mfn(info->ring.sring));
|
||||
if (err < 0) {
|
||||
free_page((unsigned long)sring);
|
||||
|
|
@ -1198,7 +1221,7 @@ static int blkfront_probe(struct xenbus_device *dev,
|
|||
spin_lock_init(&info->io_lock);
|
||||
info->xbdev = dev;
|
||||
info->vdevice = vdevice;
|
||||
INIT_LIST_HEAD(&info->persistent_gnts);
|
||||
INIT_LIST_HEAD(&info->grants);
|
||||
info->persistent_gnts_c = 0;
|
||||
info->connected = BLKIF_STATE_DISCONNECTED;
|
||||
INIT_WORK(&info->work, blkif_restart_queue);
|
||||
|
|
@ -1227,7 +1250,8 @@ static int blkif_recover(struct blkfront_info *info)
|
|||
int i;
|
||||
struct blkif_request *req;
|
||||
struct blk_shadow *copy;
|
||||
int j;
|
||||
unsigned int persistent;
|
||||
int j, rc;
|
||||
|
||||
/* Stage 1: Make a safe copy of the shadow state. */
|
||||
copy = kmemdup(info->shadow, sizeof(info->shadow),
|
||||
|
|
@ -1242,6 +1266,24 @@ static int blkif_recover(struct blkfront_info *info)
|
|||
info->shadow_free = info->ring.req_prod_pvt;
|
||||
info->shadow[BLK_RING_SIZE-1].req.u.rw.id = 0x0fffffff;
|
||||
|
||||
/* Check if the backend supports persistent grants */
|
||||
rc = xenbus_gather(XBT_NIL, info->xbdev->otherend,
|
||||
"feature-persistent", "%u", &persistent,
|
||||
NULL);
|
||||
if (rc)
|
||||
info->feature_persistent = 0;
|
||||
else
|
||||
info->feature_persistent = persistent;
|
||||
|
||||
/* Allocate memory for grants */
|
||||
rc = fill_grant_buffer(info, BLK_RING_SIZE *
|
||||
BLKIF_MAX_SEGMENTS_PER_REQUEST);
|
||||
if (rc) {
|
||||
xenbus_dev_fatal(info->xbdev, rc, "setting grant buffer failed");
|
||||
kfree(copy);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Stage 3: Find pending requests and requeue them. */
|
||||
for (i = 0; i < BLK_RING_SIZE; i++) {
|
||||
/* Not in use? */
|
||||
|
|
@ -1306,8 +1348,12 @@ static int blkfront_resume(struct xenbus_device *dev)
|
|||
blkif_free(info, info->connected == BLKIF_STATE_CONNECTED);
|
||||
|
||||
err = talk_to_blkback(dev, info);
|
||||
if (info->connected == BLKIF_STATE_SUSPENDED && !err)
|
||||
err = blkif_recover(info);
|
||||
|
||||
/*
|
||||
* We have to wait for the backend to switch to
|
||||
* connected state, since we want to read which
|
||||
* features it supports.
|
||||
*/
|
||||
|
||||
return err;
|
||||
}
|
||||
|
|
@ -1411,9 +1457,16 @@ static void blkfront_connect(struct blkfront_info *info)
|
|||
sectors);
|
||||
set_capacity(info->gd, sectors);
|
||||
revalidate_disk(info->gd);
|
||||
return;
|
||||
|
||||
/* fall through */
|
||||
case BLKIF_STATE_SUSPENDED:
|
||||
/*
|
||||
* If we are recovering from suspension, we need to wait
|
||||
* for the backend to announce it's features before
|
||||
* reconnecting, we need to know if the backend supports
|
||||
* persistent grants.
|
||||
*/
|
||||
blkif_recover(info);
|
||||
return;
|
||||
|
||||
default:
|
||||
|
|
@ -1481,6 +1534,14 @@ static void blkfront_connect(struct blkfront_info *info)
|
|||
else
|
||||
info->feature_persistent = persistent;
|
||||
|
||||
/* Allocate memory for grants */
|
||||
err = fill_grant_buffer(info, BLK_RING_SIZE *
|
||||
BLKIF_MAX_SEGMENTS_PER_REQUEST);
|
||||
if (err) {
|
||||
xenbus_dev_fatal(info->xbdev, err, "setting grant buffer failed");
|
||||
return;
|
||||
}
|
||||
|
||||
err = xlvbd_alloc_gendisk(sectors, info, binfo, sector_size);
|
||||
if (err) {
|
||||
xenbus_dev_fatal(info->xbdev, err, "xlvbd_add at %s",
|
||||
|
|
|
|||
|
|
@ -82,6 +82,7 @@ static struct usb_device_id ath3k_table[] = {
|
|||
{ USB_DEVICE(0x04CA, 0x3004) },
|
||||
{ USB_DEVICE(0x04CA, 0x3005) },
|
||||
{ USB_DEVICE(0x04CA, 0x3006) },
|
||||
{ USB_DEVICE(0x04CA, 0x3007) },
|
||||
{ USB_DEVICE(0x04CA, 0x3008) },
|
||||
{ USB_DEVICE(0x13d3, 0x3362) },
|
||||
{ USB_DEVICE(0x0CF3, 0xE004) },
|
||||
|
|
@ -124,6 +125,7 @@ static struct usb_device_id ath3k_blist_tbl[] = {
|
|||
{ USB_DEVICE(0x04ca, 0x3004), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x04ca, 0x3007), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 },
|
||||
|
|
|
|||
|
|
@ -146,6 +146,7 @@ static struct usb_device_id blacklist_table[] = {
|
|||
{ USB_DEVICE(0x04ca, 0x3004), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x04ca, 0x3007), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 },
|
||||
|
|
|
|||
|
|
@ -250,12 +250,6 @@ static int mvebu_mbus_window_conflicts(struct mvebu_mbus_state *mbus,
|
|||
*/
|
||||
if ((u64)base < wend && end > wbase)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Check if target/attribute conflicts
|
||||
*/
|
||||
if (target == wtarget && attr == wattr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
|
|
|||
|
|
@ -251,8 +251,9 @@ static inline int check_obf(struct si_sm_data *kcs, unsigned char status,
|
|||
if (!GET_STATUS_OBF(status)) {
|
||||
kcs->obf_timeout -= time;
|
||||
if (kcs->obf_timeout < 0) {
|
||||
start_error_recovery(kcs, "OBF not ready in time");
|
||||
return 1;
|
||||
kcs->obf_timeout = OBF_RETRY_TIMEOUT;
|
||||
start_error_recovery(kcs, "OBF not ready in time");
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -244,6 +244,9 @@ struct smi_info {
|
|||
/* The timer for this si. */
|
||||
struct timer_list si_timer;
|
||||
|
||||
/* This flag is set, if the timer is running (timer_pending() isn't enough) */
|
||||
bool timer_running;
|
||||
|
||||
/* The time (in jiffies) the last timeout occurred at. */
|
||||
unsigned long last_timeout_jiffies;
|
||||
|
||||
|
|
@ -427,6 +430,13 @@ static void start_clear_flags(struct smi_info *smi_info)
|
|||
smi_info->si_state = SI_CLEARING_FLAGS;
|
||||
}
|
||||
|
||||
static void smi_mod_timer(struct smi_info *smi_info, unsigned long new_val)
|
||||
{
|
||||
smi_info->last_timeout_jiffies = jiffies;
|
||||
mod_timer(&smi_info->si_timer, new_val);
|
||||
smi_info->timer_running = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* When we have a situtaion where we run out of memory and cannot
|
||||
* allocate messages, we just leave them in the BMC and run the system
|
||||
|
|
@ -439,8 +449,7 @@ static inline void disable_si_irq(struct smi_info *smi_info)
|
|||
start_disable_irq(smi_info);
|
||||
smi_info->interrupt_disabled = 1;
|
||||
if (!atomic_read(&smi_info->stop_operation))
|
||||
mod_timer(&smi_info->si_timer,
|
||||
jiffies + SI_TIMEOUT_JIFFIES);
|
||||
smi_mod_timer(smi_info, jiffies + SI_TIMEOUT_JIFFIES);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -900,15 +909,7 @@ static void sender(void *send_info,
|
|||
list_add_tail(&msg->link, &smi_info->xmit_msgs);
|
||||
|
||||
if (smi_info->si_state == SI_NORMAL && smi_info->curr_msg == NULL) {
|
||||
/*
|
||||
* last_timeout_jiffies is updated here to avoid
|
||||
* smi_timeout() handler passing very large time_diff
|
||||
* value to smi_event_handler() that causes
|
||||
* the send command to abort.
|
||||
*/
|
||||
smi_info->last_timeout_jiffies = jiffies;
|
||||
|
||||
mod_timer(&smi_info->si_timer, jiffies + SI_TIMEOUT_JIFFIES);
|
||||
smi_mod_timer(smi_info, jiffies + SI_TIMEOUT_JIFFIES);
|
||||
|
||||
if (smi_info->thread)
|
||||
wake_up_process(smi_info->thread);
|
||||
|
|
@ -997,6 +998,17 @@ static int ipmi_thread(void *data)
|
|||
|
||||
spin_lock_irqsave(&(smi_info->si_lock), flags);
|
||||
smi_result = smi_event_handler(smi_info, 0);
|
||||
|
||||
/*
|
||||
* If the driver is doing something, there is a possible
|
||||
* race with the timer. If the timer handler see idle,
|
||||
* and the thread here sees something else, the timer
|
||||
* handler won't restart the timer even though it is
|
||||
* required. So start it here if necessary.
|
||||
*/
|
||||
if (smi_result != SI_SM_IDLE && !smi_info->timer_running)
|
||||
smi_mod_timer(smi_info, jiffies + SI_TIMEOUT_JIFFIES);
|
||||
|
||||
spin_unlock_irqrestore(&(smi_info->si_lock), flags);
|
||||
busy_wait = ipmi_thread_busy_wait(smi_result, smi_info,
|
||||
&busy_until);
|
||||
|
|
@ -1066,10 +1078,6 @@ static void smi_timeout(unsigned long data)
|
|||
* SI_USEC_PER_JIFFY);
|
||||
smi_result = smi_event_handler(smi_info, time_diff);
|
||||
|
||||
spin_unlock_irqrestore(&(smi_info->si_lock), flags);
|
||||
|
||||
smi_info->last_timeout_jiffies = jiffies_now;
|
||||
|
||||
if ((smi_info->irq) && (!smi_info->interrupt_disabled)) {
|
||||
/* Running with interrupts, only do long timeouts. */
|
||||
timeout = jiffies + SI_TIMEOUT_JIFFIES;
|
||||
|
|
@ -1091,7 +1099,10 @@ static void smi_timeout(unsigned long data)
|
|||
|
||||
do_mod_timer:
|
||||
if (smi_result != SI_SM_IDLE)
|
||||
mod_timer(&(smi_info->si_timer), timeout);
|
||||
smi_mod_timer(smi_info, timeout);
|
||||
else
|
||||
smi_info->timer_running = false;
|
||||
spin_unlock_irqrestore(&(smi_info->si_lock), flags);
|
||||
}
|
||||
|
||||
static irqreturn_t si_irq_handler(int irq, void *data)
|
||||
|
|
@ -1139,8 +1150,7 @@ static int smi_start_processing(void *send_info,
|
|||
|
||||
/* Set up the timer that drives the interface. */
|
||||
setup_timer(&new_smi->si_timer, smi_timeout, (long)new_smi);
|
||||
new_smi->last_timeout_jiffies = jiffies;
|
||||
mod_timer(&new_smi->si_timer, jiffies + SI_TIMEOUT_JIFFIES);
|
||||
smi_mod_timer(new_smi, jiffies + SI_TIMEOUT_JIFFIES);
|
||||
|
||||
/*
|
||||
* Check if the user forcefully enabled the daemon.
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ void __init vexpress_osc_of_setup(struct device_node *node)
|
|||
|
||||
osc = kzalloc(sizeof(*osc), GFP_KERNEL);
|
||||
if (!osc)
|
||||
goto error;
|
||||
return;
|
||||
|
||||
osc->func = vexpress_config_func_get_by_node(node);
|
||||
if (!osc->func) {
|
||||
|
|
|
|||
|
|
@ -429,8 +429,6 @@ static int __cpuinit exynos4_local_timer_setup(struct clock_event_device *evt)
|
|||
evt->set_mode = exynos4_tick_set_mode;
|
||||
evt->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
|
||||
evt->rating = 450;
|
||||
clockevents_config_and_register(evt, clk_rate / (TICK_BASE_CNT + 1),
|
||||
0xf, 0x7fffffff);
|
||||
|
||||
exynos4_mct_write(TICK_BASE_CNT, mevt->base + MCT_L_TCNTB_OFFSET);
|
||||
|
||||
|
|
@ -448,6 +446,8 @@ static int __cpuinit exynos4_local_timer_setup(struct clock_event_device *evt)
|
|||
} else {
|
||||
enable_percpu_irq(mct_irqs[MCT_L0_IRQ], 0);
|
||||
}
|
||||
clockevents_config_and_register(evt, clk_rate / (TICK_BASE_CNT + 1),
|
||||
0xf, 0x7fffffff);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,9 +16,13 @@
|
|||
char *tmp; \
|
||||
\
|
||||
tmp = kmalloc(sizeof(format) + max_alloc, GFP_ATOMIC); \
|
||||
sprintf(tmp, format, param); \
|
||||
strcat(str, tmp); \
|
||||
kfree(tmp); \
|
||||
if (likely(tmp)) { \
|
||||
sprintf(tmp, format, param); \
|
||||
strcat(str, tmp); \
|
||||
kfree(tmp); \
|
||||
} else { \
|
||||
strcat(str, "kmalloc failure in SPRINTFCAT"); \
|
||||
} \
|
||||
}
|
||||
|
||||
static void report_jump_idx(u32 status, char *outstr)
|
||||
|
|
|
|||
|
|
@ -9123,15 +9123,6 @@ void intel_modeset_init(struct drm_device *dev)
|
|||
intel_disable_fbc(dev);
|
||||
}
|
||||
|
||||
static void
|
||||
intel_connector_break_all_links(struct intel_connector *connector)
|
||||
{
|
||||
connector->base.dpms = DRM_MODE_DPMS_OFF;
|
||||
connector->base.encoder = NULL;
|
||||
connector->encoder->connectors_active = false;
|
||||
connector->encoder->base.crtc = NULL;
|
||||
}
|
||||
|
||||
static void intel_enable_pipe_a(struct drm_device *dev)
|
||||
{
|
||||
struct intel_connector *connector;
|
||||
|
|
@ -9213,8 +9204,17 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc)
|
|||
if (connector->encoder->base.crtc != &crtc->base)
|
||||
continue;
|
||||
|
||||
intel_connector_break_all_links(connector);
|
||||
connector->base.dpms = DRM_MODE_DPMS_OFF;
|
||||
connector->base.encoder = NULL;
|
||||
}
|
||||
/* multiple connectors may have the same encoder:
|
||||
* handle them and break crtc link separately */
|
||||
list_for_each_entry(connector, &dev->mode_config.connector_list,
|
||||
base.head)
|
||||
if (connector->encoder->base.crtc == &crtc->base) {
|
||||
connector->encoder->base.crtc = NULL;
|
||||
connector->encoder->connectors_active = false;
|
||||
}
|
||||
|
||||
WARN_ON(crtc->active);
|
||||
crtc->base.enabled = false;
|
||||
|
|
@ -9285,6 +9285,8 @@ static void intel_sanitize_encoder(struct intel_encoder *encoder)
|
|||
drm_get_encoder_name(&encoder->base));
|
||||
encoder->disable(encoder);
|
||||
}
|
||||
encoder->base.crtc = NULL;
|
||||
encoder->connectors_active = false;
|
||||
|
||||
/* Inconsistent output/port/pipe state happens presumably due to
|
||||
* a bug in one of the get_hw_state functions. Or someplace else
|
||||
|
|
@ -9295,8 +9297,8 @@ static void intel_sanitize_encoder(struct intel_encoder *encoder)
|
|||
base.head) {
|
||||
if (connector->encoder != encoder)
|
||||
continue;
|
||||
|
||||
intel_connector_break_all_links(connector);
|
||||
connector->base.dpms = DRM_MODE_DPMS_OFF;
|
||||
connector->base.encoder = NULL;
|
||||
}
|
||||
}
|
||||
/* Enabled encoders without active connectors will be fixed in
|
||||
|
|
|
|||
|
|
@ -54,8 +54,10 @@ nouveau_fan_update(struct nouveau_fan *fan, bool immediate, int target)
|
|||
|
||||
/* check that we're not already at the target duty cycle */
|
||||
duty = fan->get(therm);
|
||||
if (duty == target)
|
||||
goto done;
|
||||
if (duty == target) {
|
||||
spin_unlock_irqrestore(&fan->lock, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* smooth out the fanspeed increase/decrease */
|
||||
if (!immediate && duty >= 0) {
|
||||
|
|
@ -73,8 +75,15 @@ nouveau_fan_update(struct nouveau_fan *fan, bool immediate, int target)
|
|||
|
||||
nv_debug(therm, "FAN update: %d\n", duty);
|
||||
ret = fan->set(therm, duty);
|
||||
if (ret)
|
||||
goto done;
|
||||
if (ret) {
|
||||
spin_unlock_irqrestore(&fan->lock, flags);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* fan speed updated, drop the fan lock before grabbing the
|
||||
* alarm-scheduling lock and risking a deadlock
|
||||
*/
|
||||
spin_unlock_irqrestore(&fan->lock, flags);
|
||||
|
||||
/* schedule next fan update, if not at target speed already */
|
||||
if (list_empty(&fan->alarm.head) && target != duty) {
|
||||
|
|
@ -92,8 +101,6 @@ nouveau_fan_update(struct nouveau_fan *fan, bool immediate, int target)
|
|||
ptimer->alarm(ptimer, delay * 1000 * 1000, &fan->alarm);
|
||||
}
|
||||
|
||||
done:
|
||||
spin_unlock_irqrestore(&fan->lock, flags);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -372,9 +372,6 @@ bool nouveau_acpi_rom_supported(struct pci_dev *pdev)
|
|||
acpi_status status;
|
||||
acpi_handle dhandle, rom_handle;
|
||||
|
||||
if (!nouveau_dsm_priv.dsm_detected && !nouveau_dsm_priv.optimus_detected)
|
||||
return false;
|
||||
|
||||
dhandle = DEVICE_ACPI_HANDLE(&pdev->dev);
|
||||
if (!dhandle)
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -523,6 +523,13 @@ static bool radeon_atpx_detect(void)
|
|||
has_atpx |= (radeon_atpx_pci_probe_handle(pdev) == true);
|
||||
}
|
||||
|
||||
/* some newer PX laptops mark the dGPU as a non-VGA display device */
|
||||
while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_OTHER << 8, pdev)) != NULL) {
|
||||
vga_count++;
|
||||
|
||||
has_atpx |= (radeon_atpx_pci_probe_handle(pdev) == true);
|
||||
}
|
||||
|
||||
if (has_atpx && vga_count == 2) {
|
||||
acpi_get_name(radeon_atpx_priv.atpx.handle, ACPI_FULL_PATHNAME, &buffer);
|
||||
printk(KERN_INFO "VGA switcheroo: detected switching method %s handle\n",
|
||||
|
|
|
|||
|
|
@ -449,6 +449,10 @@ static int radeon_uvd_cs_reloc(struct radeon_cs_parser *p,
|
|||
cmd = radeon_get_ib_value(p, p->idx) >> 1;
|
||||
|
||||
if (cmd < 0x4) {
|
||||
if (end <= start) {
|
||||
DRM_ERROR("invalid reloc offset %X!\n", offset);
|
||||
return -EINVAL;
|
||||
}
|
||||
if ((end - start) < buf_sizes[cmd]) {
|
||||
DRM_ERROR("buffer to small (%d / %d)!\n",
|
||||
(unsigned)(end - start), buf_sizes[cmd]);
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ static irqreturn_t syncpt_thresh_isr(int irq, void *dev_id)
|
|||
unsigned long reg;
|
||||
int i, id;
|
||||
|
||||
for (i = 0; i <= BIT_WORD(host->info->nb_pts); i++) {
|
||||
for (i = 0; i < DIV_ROUND_UP(host->info->nb_pts, 32); i++) {
|
||||
reg = host1x_sync_readl(host,
|
||||
HOST1X_SYNC_SYNCPT_THRESH_CPU0_INT_STATUS(i));
|
||||
for_each_set_bit(id, ®, BITS_PER_LONG) {
|
||||
|
|
@ -65,7 +65,7 @@ static void _host1x_intr_disable_all_syncpt_intrs(struct host1x *host)
|
|||
{
|
||||
u32 i;
|
||||
|
||||
for (i = 0; i <= BIT_WORD(host->info->nb_pts); ++i) {
|
||||
for (i = 0; i < DIV_ROUND_UP(host->info->nb_pts, 32); ++i) {
|
||||
host1x_sync_writel(host, 0xffffffffu,
|
||||
HOST1X_SYNC_SYNCPT_THRESH_INT_DISABLE(i));
|
||||
host1x_sync_writel(host, 0xffffffffu,
|
||||
|
|
|
|||
|
|
@ -55,6 +55,9 @@ static __u32 vmbus_get_next_version(__u32 current_version)
|
|||
case (VERSION_WIN8):
|
||||
return VERSION_WIN7;
|
||||
|
||||
case (VERSION_WIN8_1):
|
||||
return VERSION_WIN8;
|
||||
|
||||
case (VERSION_WS2008):
|
||||
default:
|
||||
return VERSION_INVAL;
|
||||
|
|
@ -80,6 +83,9 @@ static int vmbus_negotiate_version(struct vmbus_channel_msginfo *msginfo,
|
|||
(void *)((unsigned long)vmbus_connection.monitor_pages +
|
||||
PAGE_SIZE));
|
||||
|
||||
if (version == VERSION_WIN8_1)
|
||||
msg->target_vcpu = hv_context.vp_index[smp_processor_id()];
|
||||
|
||||
/*
|
||||
* Add to list before we send the request since we may
|
||||
* receive the response before returning from this routine
|
||||
|
|
|
|||
|
|
@ -162,7 +162,7 @@ static ssize_t store_hyst(struct device *dev,
|
|||
if (retval < 0)
|
||||
goto fail;
|
||||
|
||||
hyst = val - retval * 1000;
|
||||
hyst = retval * 1000 - val;
|
||||
hyst = DIV_ROUND_CLOSEST(hyst, 1000);
|
||||
if (hyst < 0 || hyst > 255) {
|
||||
retval = -ERANGE;
|
||||
|
|
@ -295,7 +295,7 @@ static int emc1403_detect(struct i2c_client *client,
|
|||
}
|
||||
|
||||
id = i2c_smbus_read_byte_data(client, THERMAL_REVISION_REG);
|
||||
if (id != 0x01)
|
||||
if (id < 0x01 || id > 0x04)
|
||||
return -ENODEV;
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -109,6 +109,8 @@ config I2C_I801
|
|||
Avoton (SOC)
|
||||
Wellsburg (PCH)
|
||||
Coleto Creek (PCH)
|
||||
Wildcat Point-LP (PCH)
|
||||
BayTrail (SOC)
|
||||
|
||||
This driver can also be built as a module. If so, the module
|
||||
will be called i2c-i801.
|
||||
|
|
|
|||
|
|
@ -380,6 +380,9 @@ static void i2c_dw_xfer_init(struct dw_i2c_dev *dev)
|
|||
ic_con &= ~DW_IC_CON_10BITADDR_MASTER;
|
||||
dw_writel(dev, ic_con, DW_IC_CON);
|
||||
|
||||
/* enforce disabled interrupts (due to HW issues) */
|
||||
i2c_dw_disable_int(dev);
|
||||
|
||||
/* Enable the adapter */
|
||||
__i2c_dw_enable(dev, true);
|
||||
|
||||
|
|
|
|||
|
|
@ -59,6 +59,8 @@
|
|||
Wellsburg (PCH) MS 0x8d7e 32 hard yes yes yes
|
||||
Wellsburg (PCH) MS 0x8d7f 32 hard yes yes yes
|
||||
Coleto Creek (PCH) 0x23b0 32 hard yes yes yes
|
||||
Wildcat Point-LP (PCH) 0x9ca2 32 hard yes yes yes
|
||||
BayTrail (SOC) 0x0f12 32 hard yes yes yes
|
||||
|
||||
Features supported by this driver:
|
||||
Software PEC no
|
||||
|
|
@ -161,6 +163,7 @@
|
|||
STATUS_ERROR_FLAGS)
|
||||
|
||||
/* Older devices have their ID defined in <linux/pci_ids.h> */
|
||||
#define PCI_DEVICE_ID_INTEL_BAYTRAIL_SMBUS 0x0f12
|
||||
#define PCI_DEVICE_ID_INTEL_COUGARPOINT_SMBUS 0x1c22
|
||||
#define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS 0x1d22
|
||||
/* Patsburg also has three 'Integrated Device Function' SMBus controllers */
|
||||
|
|
@ -178,6 +181,7 @@
|
|||
#define PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS1 0x8d7e
|
||||
#define PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS2 0x8d7f
|
||||
#define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_SMBUS 0x9c22
|
||||
#define PCI_DEVICE_ID_INTEL_WILDCATPOINT_LP_SMBUS 0x9ca2
|
||||
|
||||
struct i801_mux_config {
|
||||
char *gpio_chip;
|
||||
|
|
@ -820,6 +824,8 @@ static DEFINE_PCI_DEVICE_TABLE(i801_ids) = {
|
|||
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS1) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS2) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_COLETOCREEK_SMBUS) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WILDCATPOINT_LP_SMBUS) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BAYTRAIL_SMBUS) },
|
||||
{ 0, }
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -541,6 +541,12 @@ static int rcar_i2c_master_xfer(struct i2c_adapter *adap,
|
|||
|
||||
ret = -EINVAL;
|
||||
for (i = 0; i < num; i++) {
|
||||
/* This HW can't send STOP after address phase */
|
||||
if (msgs[i].len == 0) {
|
||||
ret = -EOPNOTSUPP;
|
||||
break;
|
||||
}
|
||||
|
||||
/*-------------- spin lock -----------------*/
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
|
||||
|
|
@ -605,7 +611,8 @@ static int rcar_i2c_master_xfer(struct i2c_adapter *adap,
|
|||
|
||||
static u32 rcar_i2c_func(struct i2c_adapter *adap)
|
||||
{
|
||||
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
|
||||
/* This HW can't do SMBUS_QUICK and NOSTART */
|
||||
return I2C_FUNC_I2C | (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK);
|
||||
}
|
||||
|
||||
static const struct i2c_algorithm rcar_i2c_algo = {
|
||||
|
|
|
|||
|
|
@ -1204,10 +1204,10 @@ static int s3c24xx_i2c_resume(struct device *dev)
|
|||
struct platform_device *pdev = to_platform_device(dev);
|
||||
struct s3c24xx_i2c *i2c = platform_get_drvdata(pdev);
|
||||
|
||||
i2c->suspended = 0;
|
||||
clk_prepare_enable(i2c->clk);
|
||||
s3c24xx_i2c_init(i2c);
|
||||
clk_disable_unprepare(i2c->clk);
|
||||
i2c->suspended = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -660,6 +660,7 @@ static int inv_mpu_probe(struct i2c_client *client,
|
|||
{
|
||||
struct inv_mpu6050_state *st;
|
||||
struct iio_dev *indio_dev;
|
||||
struct inv_mpu6050_platform_data *pdata;
|
||||
int result;
|
||||
|
||||
if (!i2c_check_functionality(client->adapter,
|
||||
|
|
@ -675,8 +676,10 @@ static int inv_mpu_probe(struct i2c_client *client,
|
|||
}
|
||||
st = iio_priv(indio_dev);
|
||||
st->client = client;
|
||||
st->plat_data = *(struct inv_mpu6050_platform_data
|
||||
*)dev_get_platdata(&client->dev);
|
||||
pdata = (struct inv_mpu6050_platform_data
|
||||
*)dev_get_platdata(&client->dev);
|
||||
if (pdata)
|
||||
st->plat_data = *pdata;
|
||||
/* power is turned on inside check chip type*/
|
||||
result = inv_check_and_setup_chip(st, id);
|
||||
if (result)
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
#include <target/target_core_base.h>
|
||||
#include <target/target_core_fabric.h>
|
||||
#include <target/iscsi/iscsi_transport.h>
|
||||
#include <linux/semaphore.h>
|
||||
|
||||
#include "isert_proto.h"
|
||||
#include "ib_isert.h"
|
||||
|
|
@ -459,11 +460,11 @@ isert_connect_request(struct rdma_cm_id *cma_id, struct rdma_cm_event *event)
|
|||
goto out_conn_dev;
|
||||
|
||||
mutex_lock(&isert_np->np_accept_mutex);
|
||||
list_add_tail(&isert_np->np_accept_list, &isert_conn->conn_accept_node);
|
||||
list_add_tail(&isert_conn->conn_accept_node, &isert_np->np_accept_list);
|
||||
mutex_unlock(&isert_np->np_accept_mutex);
|
||||
|
||||
pr_debug("isert_connect_request() waking up np_accept_wq: %p\n", np);
|
||||
wake_up(&isert_np->np_accept_wq);
|
||||
pr_debug("isert_connect_request() up np_sem np: %p\n", np);
|
||||
up(&isert_np->np_sem);
|
||||
return 0;
|
||||
|
||||
out_conn_dev:
|
||||
|
|
@ -2042,7 +2043,7 @@ isert_setup_np(struct iscsi_np *np,
|
|||
pr_err("Unable to allocate struct isert_np\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
init_waitqueue_head(&isert_np->np_accept_wq);
|
||||
sema_init(&isert_np->np_sem, 0);
|
||||
mutex_init(&isert_np->np_accept_mutex);
|
||||
INIT_LIST_HEAD(&isert_np->np_accept_list);
|
||||
init_completion(&isert_np->np_login_comp);
|
||||
|
|
@ -2090,18 +2091,6 @@ out:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
isert_check_accept_queue(struct isert_np *isert_np)
|
||||
{
|
||||
int empty;
|
||||
|
||||
mutex_lock(&isert_np->np_accept_mutex);
|
||||
empty = list_empty(&isert_np->np_accept_list);
|
||||
mutex_unlock(&isert_np->np_accept_mutex);
|
||||
|
||||
return empty;
|
||||
}
|
||||
|
||||
static int
|
||||
isert_rdma_accept(struct isert_conn *isert_conn)
|
||||
{
|
||||
|
|
@ -2186,16 +2175,14 @@ isert_accept_np(struct iscsi_np *np, struct iscsi_conn *conn)
|
|||
int max_accept = 0, ret;
|
||||
|
||||
accept_wait:
|
||||
ret = wait_event_interruptible(isert_np->np_accept_wq,
|
||||
!isert_check_accept_queue(isert_np) ||
|
||||
np->np_thread_state == ISCSI_NP_THREAD_RESET);
|
||||
ret = down_interruptible(&isert_np->np_sem);
|
||||
if (max_accept > 5)
|
||||
return -ENODEV;
|
||||
|
||||
spin_lock_bh(&np->np_thread_lock);
|
||||
if (np->np_thread_state == ISCSI_NP_THREAD_RESET) {
|
||||
spin_unlock_bh(&np->np_thread_lock);
|
||||
pr_err("ISCSI_NP_THREAD_RESET for isert_accept_np\n");
|
||||
pr_debug("ISCSI_NP_THREAD_RESET for isert_accept_np\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
spin_unlock_bh(&np->np_thread_lock);
|
||||
|
|
|
|||
|
|
@ -131,7 +131,7 @@ struct isert_device {
|
|||
};
|
||||
|
||||
struct isert_np {
|
||||
wait_queue_head_t np_accept_wq;
|
||||
struct semaphore np_sem;
|
||||
struct rdma_cm_id *np_cm_id;
|
||||
struct mutex np_accept_mutex;
|
||||
struct list_head np_accept_list;
|
||||
|
|
|
|||
|
|
@ -243,6 +243,12 @@ static void (*atkbd_platform_fixup)(struct atkbd *, const void *data);
|
|||
static void *atkbd_platform_fixup_data;
|
||||
static unsigned int (*atkbd_platform_scancode_fixup)(struct atkbd *, unsigned int);
|
||||
|
||||
/*
|
||||
* Certain keyboards to not like ATKBD_CMD_RESET_DIS and stop responding
|
||||
* to many commands until full reset (ATKBD_CMD_RESET_BAT) is performed.
|
||||
*/
|
||||
static bool atkbd_skip_deactivate;
|
||||
|
||||
static ssize_t atkbd_attr_show_helper(struct device *dev, char *buf,
|
||||
ssize_t (*handler)(struct atkbd *, char *));
|
||||
static ssize_t atkbd_attr_set_helper(struct device *dev, const char *buf, size_t count,
|
||||
|
|
@ -768,7 +774,8 @@ static int atkbd_probe(struct atkbd *atkbd)
|
|||
* Make sure nothing is coming from the keyboard and disturbs our
|
||||
* internal state.
|
||||
*/
|
||||
atkbd_deactivate(atkbd);
|
||||
if (!atkbd_skip_deactivate)
|
||||
atkbd_deactivate(atkbd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1638,6 +1645,12 @@ static int __init atkbd_setup_scancode_fixup(const struct dmi_system_id *id)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int __init atkbd_deactivate_fixup(const struct dmi_system_id *id)
|
||||
{
|
||||
atkbd_skip_deactivate = true;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const struct dmi_system_id atkbd_dmi_quirk_table[] __initconst = {
|
||||
{
|
||||
.matches = {
|
||||
|
|
@ -1775,6 +1788,20 @@ static const struct dmi_system_id atkbd_dmi_quirk_table[] __initconst = {
|
|||
.callback = atkbd_setup_scancode_fixup,
|
||||
.driver_data = atkbd_oqo_01plus_scancode_fixup,
|
||||
},
|
||||
{
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "LG Electronics"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "LW25-B7HV"),
|
||||
},
|
||||
.callback = atkbd_deactivate_fixup,
|
||||
},
|
||||
{
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "LG Electronics"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "P1-J273B"),
|
||||
},
|
||||
.callback = atkbd_deactivate_fixup,
|
||||
},
|
||||
{ }
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
*/
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/dmi.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/input.h>
|
||||
|
|
@ -801,7 +802,11 @@ static int elantech_set_absolute_mode(struct psmouse *psmouse)
|
|||
break;
|
||||
|
||||
case 3:
|
||||
etd->reg_10 = 0x0b;
|
||||
if (etd->set_hw_resolution)
|
||||
etd->reg_10 = 0x0b;
|
||||
else
|
||||
etd->reg_10 = 0x03;
|
||||
|
||||
if (elantech_write_reg(psmouse, 0x10, etd->reg_10))
|
||||
rc = -1;
|
||||
|
||||
|
|
@ -1300,6 +1305,22 @@ static int elantech_reconnect(struct psmouse *psmouse)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Some hw_version 3 models go into error state when we try to set bit 3 of r10
|
||||
*/
|
||||
static const struct dmi_system_id no_hw_res_dmi_table[] = {
|
||||
#if defined(CONFIG_DMI) && defined(CONFIG_X86)
|
||||
{
|
||||
/* Gigabyte U2442 */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "U2442"),
|
||||
},
|
||||
},
|
||||
#endif
|
||||
{ }
|
||||
};
|
||||
|
||||
/*
|
||||
* determine hardware version and set some properties according to it.
|
||||
*/
|
||||
|
|
@ -1351,6 +1372,9 @@ static int elantech_set_properties(struct elantech_data *etd)
|
|||
etd->reports_pressure = true;
|
||||
}
|
||||
|
||||
/* Enable real hardware resolution on hw_version 3 ? */
|
||||
etd->set_hw_resolution = !dmi_check_system(no_hw_res_dmi_table);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -129,6 +129,7 @@ struct elantech_data {
|
|||
bool paritycheck;
|
||||
bool jumpy_cursor;
|
||||
bool reports_pressure;
|
||||
bool set_hw_resolution;
|
||||
unsigned char hw_version;
|
||||
unsigned int fw_version;
|
||||
unsigned int single_finger_reports;
|
||||
|
|
|
|||
|
|
@ -1552,7 +1552,7 @@ static const struct dmi_system_id min_max_dmi_table[] __initconst = {
|
|||
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
||||
DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T540"),
|
||||
},
|
||||
.driver_data = (int []){1024, 5056, 2058, 4832},
|
||||
.driver_data = (int []){1024, 5112, 2024, 4832},
|
||||
},
|
||||
{
|
||||
/* Lenovo ThinkPad L540 */
|
||||
|
|
@ -1562,6 +1562,14 @@ static const struct dmi_system_id min_max_dmi_table[] __initconst = {
|
|||
},
|
||||
.driver_data = (int []){1024, 5112, 2024, 4832},
|
||||
},
|
||||
{
|
||||
/* Lenovo ThinkPad W540 */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
||||
DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad W540"),
|
||||
},
|
||||
.driver_data = (int []){1024, 5112, 2024, 4832},
|
||||
},
|
||||
{
|
||||
/* Lenovo Yoga S1 */
|
||||
.matches = {
|
||||
|
|
|
|||
|
|
@ -3959,7 +3959,7 @@ static struct irq_remap_table *get_irq_table(u16 devid, bool ioapic)
|
|||
iommu_flush_dte(iommu, devid);
|
||||
if (devid != alias) {
|
||||
irq_lookup_table[alias] = table;
|
||||
set_dte_irq_entry(devid, table);
|
||||
set_dte_irq_entry(alias, table);
|
||||
iommu_flush_dte(iommu, alias);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -247,10 +247,14 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
|
|||
bool force)
|
||||
{
|
||||
void __iomem *reg = gic_dist_base(d) + GIC_DIST_TARGET + (gic_irq(d) & ~3);
|
||||
unsigned int shift = (gic_irq(d) % 4) * 8;
|
||||
unsigned int cpu = cpumask_any_and(mask_val, cpu_online_mask);
|
||||
unsigned int cpu, shift = (gic_irq(d) % 4) * 8;
|
||||
u32 val, mask, bit;
|
||||
|
||||
if (!force)
|
||||
cpu = cpumask_any_and(mask_val, cpu_online_mask);
|
||||
else
|
||||
cpu = cpumask_first(mask_val);
|
||||
|
||||
if (cpu >= NR_GIC_CPU_IF || cpu >= nr_cpu_ids)
|
||||
return -EINVAL;
|
||||
|
||||
|
|
|
|||
|
|
@ -82,6 +82,15 @@ static inline size_t sizeof_pwm_leds_priv(int num_leds)
|
|||
(sizeof(struct led_pwm_data) * num_leds);
|
||||
}
|
||||
|
||||
static void led_pwm_cleanup(struct led_pwm_priv *priv)
|
||||
{
|
||||
while (priv->num_leds--) {
|
||||
led_classdev_unregister(&priv->leds[priv->num_leds].cdev);
|
||||
if (priv->leds[priv->num_leds].can_sleep)
|
||||
cancel_work_sync(&priv->leds[priv->num_leds].work);
|
||||
}
|
||||
}
|
||||
|
||||
static struct led_pwm_priv *led_pwm_create_of(struct platform_device *pdev)
|
||||
{
|
||||
struct device_node *node = pdev->dev.of_node;
|
||||
|
|
@ -139,8 +148,7 @@ static struct led_pwm_priv *led_pwm_create_of(struct platform_device *pdev)
|
|||
|
||||
return priv;
|
||||
err:
|
||||
while (priv->num_leds--)
|
||||
led_classdev_unregister(&priv->leds[priv->num_leds].cdev);
|
||||
led_pwm_cleanup(priv);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -200,8 +208,8 @@ static int led_pwm_probe(struct platform_device *pdev)
|
|||
return 0;
|
||||
|
||||
err:
|
||||
while (i--)
|
||||
led_classdev_unregister(&priv->leds[i].cdev);
|
||||
priv->num_leds = i;
|
||||
led_pwm_cleanup(priv);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -209,13 +217,8 @@ err:
|
|||
static int led_pwm_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct led_pwm_priv *priv = platform_get_drvdata(pdev);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < priv->num_leds; i++) {
|
||||
led_classdev_unregister(&priv->leds[i].cdev);
|
||||
if (priv->leds[i].can_sleep)
|
||||
cancel_work_sync(&priv->leds[i].work);
|
||||
}
|
||||
led_pwm_cleanup(priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@
|
|||
#include <linux/crypto.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/backing-dev.h>
|
||||
#include <linux/percpu.h>
|
||||
#include <linux/atomic.h>
|
||||
#include <linux/scatterlist.h>
|
||||
#include <asm/page.h>
|
||||
|
|
@ -44,6 +43,7 @@ struct convert_context {
|
|||
unsigned int idx_out;
|
||||
sector_t cc_sector;
|
||||
atomic_t cc_pending;
|
||||
struct ablkcipher_request *req;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
@ -105,15 +105,7 @@ struct iv_lmk_private {
|
|||
enum flags { DM_CRYPT_SUSPENDED, DM_CRYPT_KEY_VALID };
|
||||
|
||||
/*
|
||||
* Duplicated per-CPU state for cipher.
|
||||
*/
|
||||
struct crypt_cpu {
|
||||
struct ablkcipher_request *req;
|
||||
};
|
||||
|
||||
/*
|
||||
* The fields in here must be read only after initialization,
|
||||
* changing state should be in crypt_cpu.
|
||||
* The fields in here must be read only after initialization.
|
||||
*/
|
||||
struct crypt_config {
|
||||
struct dm_dev *dev;
|
||||
|
|
@ -143,12 +135,6 @@ struct crypt_config {
|
|||
sector_t iv_offset;
|
||||
unsigned int iv_size;
|
||||
|
||||
/*
|
||||
* Duplicated per cpu state. Access through
|
||||
* per_cpu_ptr() only.
|
||||
*/
|
||||
struct crypt_cpu __percpu *cpu;
|
||||
|
||||
/* ESSIV: struct crypto_cipher *essiv_tfm */
|
||||
void *iv_private;
|
||||
struct crypto_ablkcipher **tfms;
|
||||
|
|
@ -184,11 +170,6 @@ static void clone_init(struct dm_crypt_io *, struct bio *);
|
|||
static void kcryptd_queue_crypt(struct dm_crypt_io *io);
|
||||
static u8 *iv_of_dmreq(struct crypt_config *cc, struct dm_crypt_request *dmreq);
|
||||
|
||||
static struct crypt_cpu *this_crypt_config(struct crypt_config *cc)
|
||||
{
|
||||
return this_cpu_ptr(cc->cpu);
|
||||
}
|
||||
|
||||
/*
|
||||
* Use this to access cipher attributes that are the same for each CPU.
|
||||
*/
|
||||
|
|
@ -738,16 +719,15 @@ static void kcryptd_async_done(struct crypto_async_request *async_req,
|
|||
static void crypt_alloc_req(struct crypt_config *cc,
|
||||
struct convert_context *ctx)
|
||||
{
|
||||
struct crypt_cpu *this_cc = this_crypt_config(cc);
|
||||
unsigned key_index = ctx->cc_sector & (cc->tfms_count - 1);
|
||||
|
||||
if (!this_cc->req)
|
||||
this_cc->req = mempool_alloc(cc->req_pool, GFP_NOIO);
|
||||
if (!ctx->req)
|
||||
ctx->req = mempool_alloc(cc->req_pool, GFP_NOIO);
|
||||
|
||||
ablkcipher_request_set_tfm(this_cc->req, cc->tfms[key_index]);
|
||||
ablkcipher_request_set_callback(this_cc->req,
|
||||
ablkcipher_request_set_tfm(ctx->req, cc->tfms[key_index]);
|
||||
ablkcipher_request_set_callback(ctx->req,
|
||||
CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
|
||||
kcryptd_async_done, dmreq_of_req(cc, this_cc->req));
|
||||
kcryptd_async_done, dmreq_of_req(cc, ctx->req));
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -756,7 +736,6 @@ static void crypt_alloc_req(struct crypt_config *cc,
|
|||
static int crypt_convert(struct crypt_config *cc,
|
||||
struct convert_context *ctx)
|
||||
{
|
||||
struct crypt_cpu *this_cc = this_crypt_config(cc);
|
||||
int r;
|
||||
|
||||
atomic_set(&ctx->cc_pending, 1);
|
||||
|
|
@ -768,7 +747,7 @@ static int crypt_convert(struct crypt_config *cc,
|
|||
|
||||
atomic_inc(&ctx->cc_pending);
|
||||
|
||||
r = crypt_convert_block(cc, ctx, this_cc->req);
|
||||
r = crypt_convert_block(cc, ctx, ctx->req);
|
||||
|
||||
switch (r) {
|
||||
/* async */
|
||||
|
|
@ -777,7 +756,7 @@ static int crypt_convert(struct crypt_config *cc,
|
|||
INIT_COMPLETION(ctx->restart);
|
||||
/* fall through*/
|
||||
case -EINPROGRESS:
|
||||
this_cc->req = NULL;
|
||||
ctx->req = NULL;
|
||||
ctx->cc_sector++;
|
||||
continue;
|
||||
|
||||
|
|
@ -876,6 +855,7 @@ static struct dm_crypt_io *crypt_io_alloc(struct crypt_config *cc,
|
|||
io->sector = sector;
|
||||
io->error = 0;
|
||||
io->base_io = NULL;
|
||||
io->ctx.req = NULL;
|
||||
atomic_set(&io->io_pending, 0);
|
||||
|
||||
return io;
|
||||
|
|
@ -901,6 +881,8 @@ static void crypt_dec_pending(struct dm_crypt_io *io)
|
|||
if (!atomic_dec_and_test(&io->io_pending))
|
||||
return;
|
||||
|
||||
if (io->ctx.req)
|
||||
mempool_free(io->ctx.req, cc->req_pool);
|
||||
mempool_free(io, cc->io_pool);
|
||||
|
||||
if (likely(!base_io))
|
||||
|
|
@ -1326,8 +1308,6 @@ static int crypt_wipe_key(struct crypt_config *cc)
|
|||
static void crypt_dtr(struct dm_target *ti)
|
||||
{
|
||||
struct crypt_config *cc = ti->private;
|
||||
struct crypt_cpu *cpu_cc;
|
||||
int cpu;
|
||||
|
||||
ti->private = NULL;
|
||||
|
||||
|
|
@ -1339,13 +1319,6 @@ static void crypt_dtr(struct dm_target *ti)
|
|||
if (cc->crypt_queue)
|
||||
destroy_workqueue(cc->crypt_queue);
|
||||
|
||||
if (cc->cpu)
|
||||
for_each_possible_cpu(cpu) {
|
||||
cpu_cc = per_cpu_ptr(cc->cpu, cpu);
|
||||
if (cpu_cc->req)
|
||||
mempool_free(cpu_cc->req, cc->req_pool);
|
||||
}
|
||||
|
||||
crypt_free_tfms(cc);
|
||||
|
||||
if (cc->bs)
|
||||
|
|
@ -1364,9 +1337,6 @@ static void crypt_dtr(struct dm_target *ti)
|
|||
if (cc->dev)
|
||||
dm_put_device(ti, cc->dev);
|
||||
|
||||
if (cc->cpu)
|
||||
free_percpu(cc->cpu);
|
||||
|
||||
kzfree(cc->cipher);
|
||||
kzfree(cc->cipher_string);
|
||||
|
||||
|
|
@ -1421,13 +1391,6 @@ static int crypt_ctr_cipher(struct dm_target *ti,
|
|||
if (tmp)
|
||||
DMWARN("Ignoring unexpected additional cipher options");
|
||||
|
||||
cc->cpu = __alloc_percpu(sizeof(*(cc->cpu)),
|
||||
__alignof__(struct crypt_cpu));
|
||||
if (!cc->cpu) {
|
||||
ti->error = "Cannot allocate per cpu state";
|
||||
goto bad_mem;
|
||||
}
|
||||
|
||||
/*
|
||||
* For compatibility with the original dm-crypt mapping format, if
|
||||
* only the cipher name is supplied, use cbc-plain.
|
||||
|
|
|
|||
|
|
@ -8481,7 +8481,8 @@ static int md_notify_reboot(struct notifier_block *this,
|
|||
if (mddev_trylock(mddev)) {
|
||||
if (mddev->pers)
|
||||
__md_stop_writes(mddev);
|
||||
mddev->safemode = 2;
|
||||
if (mddev->persistent)
|
||||
mddev->safemode = 2;
|
||||
mddev_unlock(mddev);
|
||||
}
|
||||
need_delay = 1;
|
||||
|
|
|
|||
|
|
@ -1110,7 +1110,7 @@ static int ov7670_enum_framesizes(struct v4l2_subdev *sd,
|
|||
* windows that fall outside that.
|
||||
*/
|
||||
for (i = 0; i < n_win_sizes; i++) {
|
||||
struct ov7670_win_size *win = &info->devtype->win_sizes[index];
|
||||
struct ov7670_win_size *win = &info->devtype->win_sizes[i];
|
||||
if (info->min_width && win->width < info->min_width)
|
||||
continue;
|
||||
if (info->min_height && win->height < info->min_height)
|
||||
|
|
|
|||
|
|
@ -93,6 +93,7 @@ static long media_device_enum_entities(struct media_device *mdev,
|
|||
struct media_entity *ent;
|
||||
struct media_entity_desc u_ent;
|
||||
|
||||
memset(&u_ent, 0, sizeof(u_ent));
|
||||
if (copy_from_user(&u_ent.id, &uent->id, sizeof(u_ent.id)))
|
||||
return -EFAULT;
|
||||
|
||||
|
|
|
|||
|
|
@ -2249,6 +2249,7 @@ static int isp_probe(struct platform_device *pdev)
|
|||
ret = iommu_attach_device(isp->domain, &pdev->dev);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "can't attach iommu device: %d\n", ret);
|
||||
ret = -EPROBE_DEFER;
|
||||
goto free_domain;
|
||||
}
|
||||
|
||||
|
|
@ -2287,6 +2288,7 @@ detach_dev:
|
|||
iommu_detach_device(isp->domain, &pdev->dev);
|
||||
free_domain:
|
||||
iommu_domain_free(isp->domain);
|
||||
isp->domain = NULL;
|
||||
error_isp:
|
||||
isp_xclk_cleanup(isp);
|
||||
omap3isp_put(isp);
|
||||
|
|
|
|||
|
|
@ -195,7 +195,7 @@ static int fc2580_set_params(struct dvb_frontend *fe)
|
|||
|
||||
f_ref = 2UL * priv->cfg->clock / r_val;
|
||||
n_val = div_u64_rem(f_vco, f_ref, &k_val);
|
||||
k_val_reg = 1UL * k_val * (1 << 20) / f_ref;
|
||||
k_val_reg = div_u64(1ULL * k_val * (1 << 20), f_ref);
|
||||
|
||||
ret = fc2580_wr_reg(priv, 0x18, r18_val | ((k_val_reg >> 16) & 0xff));
|
||||
if (ret < 0)
|
||||
|
|
@ -348,8 +348,8 @@ static int fc2580_set_params(struct dvb_frontend *fe)
|
|||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
ret = fc2580_wr_reg(priv, 0x37, 1UL * priv->cfg->clock * \
|
||||
fc2580_if_filter_lut[i].mul / 1000000000);
|
||||
ret = fc2580_wr_reg(priv, 0x37, div_u64(1ULL * priv->cfg->clock *
|
||||
fc2580_if_filter_lut[i].mul, 1000000000));
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
#define FC2580_PRIV_H
|
||||
|
||||
#include "fc2580.h"
|
||||
#include <linux/math64.h>
|
||||
|
||||
struct fc2580_reg_val {
|
||||
u8 reg;
|
||||
|
|
|
|||
|
|
@ -178,6 +178,9 @@ struct v4l2_create_buffers32 {
|
|||
|
||||
static int __get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
|
||||
{
|
||||
if (get_user(kp->type, &up->type))
|
||||
return -EFAULT;
|
||||
|
||||
switch (kp->type) {
|
||||
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
|
||||
case V4L2_BUF_TYPE_VIDEO_OUTPUT:
|
||||
|
|
@ -204,17 +207,16 @@ static int __get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __us
|
|||
|
||||
static int get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
|
||||
{
|
||||
if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_format32)) ||
|
||||
get_user(kp->type, &up->type))
|
||||
return -EFAULT;
|
||||
if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_format32)))
|
||||
return -EFAULT;
|
||||
return __get_v4l2_format32(kp, up);
|
||||
}
|
||||
|
||||
static int get_v4l2_create32(struct v4l2_create_buffers *kp, struct v4l2_create_buffers32 __user *up)
|
||||
{
|
||||
if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_create_buffers32)) ||
|
||||
copy_from_user(kp, up, offsetof(struct v4l2_create_buffers32, format.fmt)))
|
||||
return -EFAULT;
|
||||
copy_from_user(kp, up, offsetof(struct v4l2_create_buffers32, format)))
|
||||
return -EFAULT;
|
||||
return __get_v4l2_format32(&kp->format, &up->format);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1255,14 +1255,16 @@ void ath_tx_aggr_sleep(struct ieee80211_sta *sta, struct ath_softc *sc,
|
|||
for (tidno = 0, tid = &an->tid[tidno];
|
||||
tidno < IEEE80211_NUM_TIDS; tidno++, tid++) {
|
||||
|
||||
if (!tid->sched)
|
||||
continue;
|
||||
|
||||
ac = tid->ac;
|
||||
txq = ac->txq;
|
||||
|
||||
ath_txq_lock(sc, txq);
|
||||
|
||||
if (!tid->sched) {
|
||||
ath_txq_unlock(sc, txq);
|
||||
continue;
|
||||
}
|
||||
|
||||
buffered = !skb_queue_empty(&tid->buf_q);
|
||||
|
||||
tid->sched = false;
|
||||
|
|
|
|||
|
|
@ -426,6 +426,12 @@ static int brcms_ops_start(struct ieee80211_hw *hw)
|
|||
bool blocked;
|
||||
int err;
|
||||
|
||||
if (!wl->ucode.bcm43xx_bomminor) {
|
||||
err = brcms_request_fw(wl, wl->wlc->hw->d11core);
|
||||
if (err)
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
ieee80211_wake_queues(hw);
|
||||
spin_lock_bh(&wl->lock);
|
||||
blocked = brcms_rfkill_set_hw_state(wl);
|
||||
|
|
@ -433,14 +439,6 @@ static int brcms_ops_start(struct ieee80211_hw *hw)
|
|||
if (!blocked)
|
||||
wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy);
|
||||
|
||||
if (!wl->ucode.bcm43xx_bomminor) {
|
||||
err = brcms_request_fw(wl, wl->wlc->hw->d11core);
|
||||
if (err) {
|
||||
brcms_remove(wl->wlc->hw->d11core);
|
||||
return -ENOENT;
|
||||
}
|
||||
}
|
||||
|
||||
spin_lock_bh(&wl->lock);
|
||||
/* avoid acknowledging frames before a non-monitor device is added */
|
||||
wl->mute_tx = true;
|
||||
|
|
|
|||
|
|
@ -622,21 +622,19 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
|
|||
rt2x00lib_config_intf(rt2x00dev, intf, vif->type, NULL,
|
||||
bss_conf->bssid);
|
||||
|
||||
/*
|
||||
* Update the beacon. This is only required on USB devices. PCI
|
||||
* devices fetch beacons periodically.
|
||||
*/
|
||||
if (changes & BSS_CHANGED_BEACON && rt2x00_is_usb(rt2x00dev))
|
||||
rt2x00queue_update_beacon(rt2x00dev, vif);
|
||||
|
||||
/*
|
||||
* Start/stop beaconing.
|
||||
*/
|
||||
if (changes & BSS_CHANGED_BEACON_ENABLED) {
|
||||
if (!bss_conf->enable_beacon && intf->enable_beacon) {
|
||||
rt2x00queue_clear_beacon(rt2x00dev, vif);
|
||||
rt2x00dev->intf_beaconing--;
|
||||
intf->enable_beacon = false;
|
||||
/*
|
||||
* Clear beacon in the H/W for this vif. This is needed
|
||||
* to disable beaconing on this particular interface
|
||||
* and keep it running on other interfaces.
|
||||
*/
|
||||
rt2x00queue_clear_beacon(rt2x00dev, vif);
|
||||
|
||||
if (rt2x00dev->intf_beaconing == 0) {
|
||||
/*
|
||||
|
|
@ -647,11 +645,15 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
|
|||
rt2x00queue_stop_queue(rt2x00dev->bcn);
|
||||
mutex_unlock(&intf->beacon_skb_mutex);
|
||||
}
|
||||
|
||||
|
||||
} else if (bss_conf->enable_beacon && !intf->enable_beacon) {
|
||||
rt2x00dev->intf_beaconing++;
|
||||
intf->enable_beacon = true;
|
||||
/*
|
||||
* Upload beacon to the H/W. This is only required on
|
||||
* USB devices. PCI devices fetch beacons periodically.
|
||||
*/
|
||||
if (rt2x00_is_usb(rt2x00dev))
|
||||
rt2x00queue_update_beacon(rt2x00dev, vif);
|
||||
|
||||
if (rt2x00dev->intf_beaconing == 1) {
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -1001,7 +1001,7 @@ int rtl92cu_hw_init(struct ieee80211_hw *hw)
|
|||
err = _rtl92cu_init_mac(hw);
|
||||
if (err) {
|
||||
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "init mac failed!\n");
|
||||
return err;
|
||||
goto exit;
|
||||
}
|
||||
err = rtl92c_download_fw(hw);
|
||||
if (err) {
|
||||
|
|
|
|||
|
|
@ -282,8 +282,8 @@ static int board_added(struct slot *p_slot)
|
|||
return WRONG_BUS_FREQUENCY;
|
||||
}
|
||||
|
||||
bsp = ctrl->pci_dev->bus->cur_bus_speed;
|
||||
msp = ctrl->pci_dev->bus->max_bus_speed;
|
||||
bsp = ctrl->pci_dev->subordinate->cur_bus_speed;
|
||||
msp = ctrl->pci_dev->subordinate->max_bus_speed;
|
||||
|
||||
/* Check if there are other slots or devices on the same bus */
|
||||
if (!list_empty(&ctrl->pci_dev->subordinate->devices))
|
||||
|
|
|
|||
|
|
@ -796,10 +796,10 @@ int se_dev_set_emulate_write_cache(struct se_device *dev, int flag)
|
|||
pr_err("emulate_write_cache not supported for pSCSI\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (dev->transport->get_write_cache) {
|
||||
pr_warn("emulate_write_cache cannot be changed when underlying"
|
||||
" HW reports WriteCacheEnabled, ignoring request\n");
|
||||
return 0;
|
||||
if (flag &&
|
||||
dev->transport->get_write_cache) {
|
||||
pr_err("emulate_write_cache not supported for this device\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
dev->dev_attrib.emulate_write_cache = flag;
|
||||
|
|
|
|||
|
|
@ -1520,7 +1520,7 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir)
|
|||
status = serial8250_rx_chars(up, status);
|
||||
}
|
||||
serial8250_modem_status(up);
|
||||
if (status & UART_LSR_THRE)
|
||||
if (!up->dma && (status & UART_LSR_THRE))
|
||||
serial8250_tx_chars(up);
|
||||
|
||||
spin_unlock_irqrestore(&port->lock, flags);
|
||||
|
|
|
|||
|
|
@ -20,12 +20,15 @@ static void __dma_tx_complete(void *param)
|
|||
struct uart_8250_port *p = param;
|
||||
struct uart_8250_dma *dma = p->dma;
|
||||
struct circ_buf *xmit = &p->port.state->xmit;
|
||||
|
||||
dma->tx_running = 0;
|
||||
unsigned long flags;
|
||||
|
||||
dma_sync_single_for_cpu(dma->txchan->device->dev, dma->tx_addr,
|
||||
UART_XMIT_SIZE, DMA_TO_DEVICE);
|
||||
|
||||
spin_lock_irqsave(&p->port.lock, flags);
|
||||
|
||||
dma->tx_running = 0;
|
||||
|
||||
xmit->tail += dma->tx_size;
|
||||
xmit->tail &= UART_XMIT_SIZE - 1;
|
||||
p->port.icount.tx += dma->tx_size;
|
||||
|
|
@ -35,6 +38,8 @@ static void __dma_tx_complete(void *param)
|
|||
|
||||
if (!uart_circ_empty(xmit) && !uart_tx_stopped(&p->port))
|
||||
serial8250_tx_dma(p);
|
||||
|
||||
spin_unlock_irqrestore(&p->port.lock, flags);
|
||||
}
|
||||
|
||||
static void __dma_rx_complete(void *param)
|
||||
|
|
|
|||
|
|
@ -1703,16 +1703,6 @@ static int at91udc_probe(struct platform_device *pdev)
|
|||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (pdev->num_resources != 2) {
|
||||
DBG("invalid num_resources\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
if ((pdev->resource[0].flags != IORESOURCE_MEM)
|
||||
|| (pdev->resource[1].flags != IORESOURCE_IRQ)) {
|
||||
DBG("invalid resource type\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!res)
|
||||
return -ENXIO;
|
||||
|
|
|
|||
|
|
@ -261,7 +261,8 @@ static int ehci_fsl_setup_phy(struct usb_hcd *hcd,
|
|||
break;
|
||||
}
|
||||
|
||||
if (pdata->have_sysif_regs && pdata->controller_ver &&
|
||||
if (pdata->have_sysif_regs &&
|
||||
pdata->controller_ver > FSL_USB_VER_1_6 &&
|
||||
(phy_mode == FSL_USB2_PHY_ULPI)) {
|
||||
/* check PHY_CLK_VALID to get phy clk valid */
|
||||
if (!spin_event_timeout(in_be32(non_ehci + FSL_SOC_USB_CTRL) &
|
||||
|
|
|
|||
|
|
@ -90,6 +90,24 @@ __acquires(ohci->lock)
|
|||
dl_done_list (ohci);
|
||||
finish_unlinks (ohci, ohci_frame_no(ohci));
|
||||
|
||||
/*
|
||||
* Some controllers don't handle "global" suspend properly if
|
||||
* there are unsuspended ports. For these controllers, put all
|
||||
* the enabled ports into suspend before suspending the root hub.
|
||||
*/
|
||||
if (ohci->flags & OHCI_QUIRK_GLOBAL_SUSPEND) {
|
||||
__hc32 __iomem *portstat = ohci->regs->roothub.portstatus;
|
||||
int i;
|
||||
unsigned temp;
|
||||
|
||||
for (i = 0; i < ohci->num_ports; (++i, ++portstat)) {
|
||||
temp = ohci_readl(ohci, portstat);
|
||||
if ((temp & (RH_PS_PES | RH_PS_PSS)) ==
|
||||
RH_PS_PES)
|
||||
ohci_writel(ohci, RH_PS_PSS, portstat);
|
||||
}
|
||||
}
|
||||
|
||||
/* maybe resume can wake root hub */
|
||||
if (ohci_to_hcd(ohci)->self.root_hub->do_remote_wakeup || autostop) {
|
||||
ohci->hc_control |= OHCI_CTRL_RWE;
|
||||
|
|
|
|||
|
|
@ -172,6 +172,7 @@ static int ohci_quirk_amd700(struct usb_hcd *hcd)
|
|||
pci_dev_put(amd_smbus_dev);
|
||||
amd_smbus_dev = NULL;
|
||||
|
||||
ohci->flags |= OHCI_QUIRK_GLOBAL_SUSPEND;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -405,6 +405,8 @@ struct ohci_hcd {
|
|||
#define OHCI_QUIRK_HUB_POWER 0x100 /* distrust firmware power/oc setup */
|
||||
#define OHCI_QUIRK_AMD_PLL 0x200 /* AMD PLL quirk*/
|
||||
#define OHCI_QUIRK_AMD_PREFETCH 0x400 /* pre-fetch for ISO transfer */
|
||||
#define OHCI_QUIRK_GLOBAL_SUSPEND 0x800 /* must suspend ports */
|
||||
|
||||
// there are also chip quirks/bugs in init logic
|
||||
|
||||
struct work_struct nec_work; /* Worker for NEC quirk */
|
||||
|
|
|
|||
|
|
@ -151,6 +151,21 @@ static const struct usb_device_id id_table[] = {
|
|||
{USB_DEVICE_INTERFACE_NUMBER(0x1199, 0x9051, 0)}, /* Netgear AirCard 340U Device Management */
|
||||
{USB_DEVICE_INTERFACE_NUMBER(0x1199, 0x9051, 2)}, /* Netgear AirCard 340U NMEA */
|
||||
{USB_DEVICE_INTERFACE_NUMBER(0x1199, 0x9051, 3)}, /* Netgear AirCard 340U Modem */
|
||||
{USB_DEVICE_INTERFACE_NUMBER(0x413c, 0x81a2, 0)}, /* Dell Wireless 5806 Gobi(TM) 4G LTE Mobile Broadband Card Device Management */
|
||||
{USB_DEVICE_INTERFACE_NUMBER(0x413c, 0x81a2, 2)}, /* Dell Wireless 5806 Gobi(TM) 4G LTE Mobile Broadband Card NMEA */
|
||||
{USB_DEVICE_INTERFACE_NUMBER(0x413c, 0x81a2, 3)}, /* Dell Wireless 5806 Gobi(TM) 4G LTE Mobile Broadband Card Modem */
|
||||
{USB_DEVICE_INTERFACE_NUMBER(0x413c, 0x81a3, 0)}, /* Dell Wireless 5570 HSPA+ (42Mbps) Mobile Broadband Card Device Management */
|
||||
{USB_DEVICE_INTERFACE_NUMBER(0x413c, 0x81a3, 2)}, /* Dell Wireless 5570 HSPA+ (42Mbps) Mobile Broadband Card NMEA */
|
||||
{USB_DEVICE_INTERFACE_NUMBER(0x413c, 0x81a3, 3)}, /* Dell Wireless 5570 HSPA+ (42Mbps) Mobile Broadband Card Modem */
|
||||
{USB_DEVICE_INTERFACE_NUMBER(0x413c, 0x81a4, 0)}, /* Dell Wireless 5570e HSPA+ (42Mbps) Mobile Broadband Card Device Management */
|
||||
{USB_DEVICE_INTERFACE_NUMBER(0x413c, 0x81a4, 2)}, /* Dell Wireless 5570e HSPA+ (42Mbps) Mobile Broadband Card NMEA */
|
||||
{USB_DEVICE_INTERFACE_NUMBER(0x413c, 0x81a4, 3)}, /* Dell Wireless 5570e HSPA+ (42Mbps) Mobile Broadband Card Modem */
|
||||
{USB_DEVICE_INTERFACE_NUMBER(0x413c, 0x81a8, 0)}, /* Dell Wireless 5808 Gobi(TM) 4G LTE Mobile Broadband Card Device Management */
|
||||
{USB_DEVICE_INTERFACE_NUMBER(0x413c, 0x81a8, 2)}, /* Dell Wireless 5808 Gobi(TM) 4G LTE Mobile Broadband Card NMEA */
|
||||
{USB_DEVICE_INTERFACE_NUMBER(0x413c, 0x81a8, 3)}, /* Dell Wireless 5808 Gobi(TM) 4G LTE Mobile Broadband Card Modem */
|
||||
{USB_DEVICE_INTERFACE_NUMBER(0x413c, 0x81a9, 0)}, /* Dell Wireless 5808e Gobi(TM) 4G LTE Mobile Broadband Card Device Management */
|
||||
{USB_DEVICE_INTERFACE_NUMBER(0x413c, 0x81a9, 2)}, /* Dell Wireless 5808e Gobi(TM) 4G LTE Mobile Broadband Card NMEA */
|
||||
{USB_DEVICE_INTERFACE_NUMBER(0x413c, 0x81a9, 3)}, /* Dell Wireless 5808e Gobi(TM) 4G LTE Mobile Broadband Card Modem */
|
||||
|
||||
{ } /* Terminating entry */
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1851,7 +1851,7 @@ static int usbat_probe(struct usb_interface *intf,
|
|||
us->transport_name = "Shuttle USBAT";
|
||||
us->transport = usbat_flash_transport;
|
||||
us->transport_reset = usb_stor_CB_reset;
|
||||
us->max_lun = 1;
|
||||
us->max_lun = 0;
|
||||
|
||||
result = usb_stor_probe2(us);
|
||||
return result;
|
||||
|
|
|
|||
|
|
@ -234,6 +234,20 @@ UNUSUAL_DEV( 0x0421, 0x0495, 0x0370, 0x0370,
|
|||
USB_SC_DEVICE, USB_PR_DEVICE, NULL,
|
||||
US_FL_MAX_SECTORS_64 ),
|
||||
|
||||
/* Reported by Daniele Forsi <dforsi@gmail.com> */
|
||||
UNUSUAL_DEV( 0x0421, 0x04b9, 0x0350, 0x0350,
|
||||
"Nokia",
|
||||
"5300",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, NULL,
|
||||
US_FL_MAX_SECTORS_64 ),
|
||||
|
||||
/* Patch submitted by Victor A. Santos <victoraur.santos@gmail.com> */
|
||||
UNUSUAL_DEV( 0x0421, 0x05af, 0x0742, 0x0742,
|
||||
"Nokia",
|
||||
"305",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, NULL,
|
||||
US_FL_MAX_SECTORS_64),
|
||||
|
||||
/* Patch submitted by Mikhail Zolotaryov <lebon@lebon.org.ua> */
|
||||
UNUSUAL_DEV( 0x0421, 0x06aa, 0x1110, 0x1110,
|
||||
"Nokia",
|
||||
|
|
|
|||
|
|
@ -654,10 +654,10 @@ int setup_arg_pages(struct linux_binprm *bprm,
|
|||
unsigned long rlim_stack;
|
||||
|
||||
#ifdef CONFIG_STACK_GROWSUP
|
||||
/* Limit stack size to 1GB */
|
||||
/* Limit stack size */
|
||||
stack_base = rlimit_max(RLIMIT_STACK);
|
||||
if (stack_base > (1 << 30))
|
||||
stack_base = 1 << 30;
|
||||
if (stack_base > STACK_SIZE_MAX)
|
||||
stack_base = STACK_SIZE_MAX;
|
||||
|
||||
/* Make sure we didn't let the argument array grow too large. */
|
||||
if (vma->vm_end - vma->vm_start > stack_base)
|
||||
|
|
|
|||
|
|
@ -385,8 +385,10 @@ sort_pacl(struct posix_acl *pacl)
|
|||
* by uid/gid. */
|
||||
int i, j;
|
||||
|
||||
if (pacl->a_count <= 4)
|
||||
return; /* no users or groups */
|
||||
/* no users or groups */
|
||||
if (!pacl || pacl->a_count <= 4)
|
||||
return;
|
||||
|
||||
i = 1;
|
||||
while (pacl->a_entries[i].e_tag == ACL_USER)
|
||||
i++;
|
||||
|
|
@ -513,13 +515,12 @@ posix_state_to_acl(struct posix_acl_state *state, unsigned int flags)
|
|||
|
||||
/*
|
||||
* ACLs with no ACEs are treated differently in the inheritable
|
||||
* and effective cases: when there are no inheritable ACEs, we
|
||||
* set a zero-length default posix acl:
|
||||
* and effective cases: when there are no inheritable ACEs,
|
||||
* calls ->set_acl with a NULL ACL structure.
|
||||
*/
|
||||
if (state->empty && (flags & NFS4_ACL_TYPE_DEFAULT)) {
|
||||
pacl = posix_acl_alloc(0, GFP_KERNEL);
|
||||
return pacl ? pacl : ERR_PTR(-ENOMEM);
|
||||
}
|
||||
if (state->empty && (flags & NFS4_ACL_TYPE_DEFAULT))
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* When there are no effective ACEs, the following will end
|
||||
* up setting a 3-element effective posix ACL with all
|
||||
|
|
|
|||
|
|
@ -1081,6 +1081,18 @@ static struct nfs4_client *alloc_client(struct xdr_netobj name)
|
|||
return NULL;
|
||||
}
|
||||
clp->cl_name.len = name.len;
|
||||
INIT_LIST_HEAD(&clp->cl_sessions);
|
||||
idr_init(&clp->cl_stateids);
|
||||
atomic_set(&clp->cl_refcount, 0);
|
||||
clp->cl_cb_state = NFSD4_CB_UNKNOWN;
|
||||
INIT_LIST_HEAD(&clp->cl_idhash);
|
||||
INIT_LIST_HEAD(&clp->cl_openowners);
|
||||
INIT_LIST_HEAD(&clp->cl_delegations);
|
||||
INIT_LIST_HEAD(&clp->cl_lru);
|
||||
INIT_LIST_HEAD(&clp->cl_callbacks);
|
||||
INIT_LIST_HEAD(&clp->cl_revoked);
|
||||
spin_lock_init(&clp->cl_lock);
|
||||
rpc_init_wait_queue(&clp->cl_cb_waitq, "Backchannel slot table");
|
||||
return clp;
|
||||
}
|
||||
|
||||
|
|
@ -1098,6 +1110,7 @@ free_client(struct nfs4_client *clp)
|
|||
WARN_ON_ONCE(atomic_read(&ses->se_ref));
|
||||
free_session(ses);
|
||||
}
|
||||
rpc_destroy_wait_queue(&clp->cl_cb_waitq);
|
||||
free_svc_cred(&clp->cl_cred);
|
||||
kfree(clp->cl_name.data);
|
||||
idr_destroy(&clp->cl_stateids);
|
||||
|
|
@ -1315,7 +1328,6 @@ static struct nfs4_client *create_client(struct xdr_netobj name,
|
|||
if (clp == NULL)
|
||||
return NULL;
|
||||
|
||||
INIT_LIST_HEAD(&clp->cl_sessions);
|
||||
ret = copy_cred(&clp->cl_cred, &rqstp->rq_cred);
|
||||
if (ret) {
|
||||
spin_lock(&nn->client_lock);
|
||||
|
|
@ -1323,20 +1335,9 @@ static struct nfs4_client *create_client(struct xdr_netobj name,
|
|||
spin_unlock(&nn->client_lock);
|
||||
return NULL;
|
||||
}
|
||||
idr_init(&clp->cl_stateids);
|
||||
atomic_set(&clp->cl_refcount, 0);
|
||||
clp->cl_cb_state = NFSD4_CB_UNKNOWN;
|
||||
INIT_LIST_HEAD(&clp->cl_idhash);
|
||||
INIT_LIST_HEAD(&clp->cl_openowners);
|
||||
INIT_LIST_HEAD(&clp->cl_delegations);
|
||||
INIT_LIST_HEAD(&clp->cl_lru);
|
||||
INIT_LIST_HEAD(&clp->cl_callbacks);
|
||||
INIT_LIST_HEAD(&clp->cl_revoked);
|
||||
spin_lock_init(&clp->cl_lock);
|
||||
nfsd4_init_callback(&clp->cl_cb_null);
|
||||
clp->cl_time = get_seconds();
|
||||
clear_bit(0, &clp->cl_cb_slot_busy);
|
||||
rpc_init_wait_queue(&clp->cl_cb_waitq, "Backchannel slot table");
|
||||
copy_verf(clp, verf);
|
||||
rpc_copy_addr((struct sockaddr *) &clp->cl_addr, sa);
|
||||
gen_confirm(clp);
|
||||
|
|
@ -3598,9 +3599,16 @@ out:
|
|||
static __be32
|
||||
nfsd4_free_lock_stateid(struct nfs4_ol_stateid *stp)
|
||||
{
|
||||
if (check_for_locks(stp->st_file, lockowner(stp->st_stateowner)))
|
||||
struct nfs4_lockowner *lo = lockowner(stp->st_stateowner);
|
||||
|
||||
if (check_for_locks(stp->st_file, lo))
|
||||
return nfserr_locks_held;
|
||||
release_lock_stateid(stp);
|
||||
/*
|
||||
* Currently there's a 1-1 lock stateid<->lockowner
|
||||
* correspondance, and we have to delete the lockowner when we
|
||||
* delete the lock stateid:
|
||||
*/
|
||||
unhash_lockowner(lo);
|
||||
return nfs_ok;
|
||||
}
|
||||
|
||||
|
|
@ -4044,6 +4052,10 @@ static bool same_lockowner_ino(struct nfs4_lockowner *lo, struct inode *inode, c
|
|||
|
||||
if (!same_owner_str(&lo->lo_owner, owner, clid))
|
||||
return false;
|
||||
if (list_empty(&lo->lo_owner.so_stateids)) {
|
||||
WARN_ON_ONCE(1);
|
||||
return false;
|
||||
}
|
||||
lst = list_first_entry(&lo->lo_owner.so_stateids,
|
||||
struct nfs4_ol_stateid, st_perstateowner);
|
||||
return lst->st_file->fi_inode == inode;
|
||||
|
|
|
|||
|
|
@ -158,6 +158,12 @@ posix_acl_equiv_mode(const struct posix_acl *acl, umode_t *mode_p)
|
|||
umode_t mode = 0;
|
||||
int not_equiv = 0;
|
||||
|
||||
/*
|
||||
* A null ACL can always be presented as mode bits.
|
||||
*/
|
||||
if (!acl)
|
||||
return 0;
|
||||
|
||||
FOREACH_ACL_ENTRY(pa, acl, pe) {
|
||||
switch (pa->e_tag) {
|
||||
case ACL_USER_OBJ:
|
||||
|
|
|
|||
|
|
@ -524,6 +524,7 @@ static inline int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_a
|
|||
extern int ftrace_arch_read_dyn_info(char *buf, int size);
|
||||
|
||||
extern int skip_trace(unsigned long ip);
|
||||
extern void ftrace_module_init(struct module *mod);
|
||||
|
||||
extern void ftrace_disable_daemon(void);
|
||||
extern void ftrace_enable_daemon(void);
|
||||
|
|
@ -533,6 +534,7 @@ static inline int ftrace_force_update(void) { return 0; }
|
|||
static inline void ftrace_disable_daemon(void) { }
|
||||
static inline void ftrace_enable_daemon(void) { }
|
||||
static inline void ftrace_release_mod(struct module *mod) {}
|
||||
static inline void ftrace_module_init(struct module *mod) {}
|
||||
static inline int register_ftrace_command(struct ftrace_func_command *cmd)
|
||||
{
|
||||
return -EINVAL;
|
||||
|
|
|
|||
|
|
@ -483,15 +483,18 @@ hv_get_ringbuffer_availbytes(struct hv_ring_buffer_info *rbi,
|
|||
* 0 . 13 (Windows Server 2008)
|
||||
* 1 . 1 (Windows 7)
|
||||
* 2 . 4 (Windows 8)
|
||||
* 3 . 0 (Windows 8 R2)
|
||||
*/
|
||||
|
||||
#define VERSION_WS2008 ((0 << 16) | (13))
|
||||
#define VERSION_WIN7 ((1 << 16) | (1))
|
||||
#define VERSION_WIN8 ((2 << 16) | (4))
|
||||
#define VERSION_WIN8_1 ((3 << 16) | (0))
|
||||
|
||||
|
||||
#define VERSION_INVAL -1
|
||||
|
||||
#define VERSION_CURRENT VERSION_WIN8
|
||||
#define VERSION_CURRENT VERSION_WIN8_1
|
||||
|
||||
/* Make maximum size of pipe payload of 16K */
|
||||
#define MAX_PIPE_DATA_PAYLOAD (sizeof(u8) * 16384)
|
||||
|
|
@ -894,7 +897,7 @@ struct vmbus_channel_relid_released {
|
|||
struct vmbus_channel_initiate_contact {
|
||||
struct vmbus_channel_message_header header;
|
||||
u32 vmbus_version_requested;
|
||||
u32 padding2;
|
||||
u32 target_vcpu; /* The VCPU the host should respond to */
|
||||
u64 interrupt_page;
|
||||
u64 monitor_page1;
|
||||
u64 monitor_page2;
|
||||
|
|
|
|||
|
|
@ -239,7 +239,40 @@ static inline int check_wakeup_irqs(void) { return 0; }
|
|||
|
||||
extern cpumask_var_t irq_default_affinity;
|
||||
|
||||
extern int irq_set_affinity(unsigned int irq, const struct cpumask *cpumask);
|
||||
/* Internal implementation. Use the helpers below */
|
||||
extern int __irq_set_affinity(unsigned int irq, const struct cpumask *cpumask,
|
||||
bool force);
|
||||
|
||||
/**
|
||||
* irq_set_affinity - Set the irq affinity of a given irq
|
||||
* @irq: Interrupt to set affinity
|
||||
* @mask: cpumask
|
||||
*
|
||||
* Fails if cpumask does not contain an online CPU
|
||||
*/
|
||||
static inline int
|
||||
irq_set_affinity(unsigned int irq, const struct cpumask *cpumask)
|
||||
{
|
||||
return __irq_set_affinity(irq, cpumask, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* irq_force_affinity - Force the irq affinity of a given irq
|
||||
* @irq: Interrupt to set affinity
|
||||
* @mask: cpumask
|
||||
*
|
||||
* Same as irq_set_affinity, but without checking the mask against
|
||||
* online cpus.
|
||||
*
|
||||
* Solely for low level cpu hotplug code, where we need to make per
|
||||
* cpu interrupts affine before the cpu becomes online.
|
||||
*/
|
||||
static inline int
|
||||
irq_force_affinity(unsigned int irq, const struct cpumask *cpumask)
|
||||
{
|
||||
return __irq_set_affinity(irq, cpumask, true);
|
||||
}
|
||||
|
||||
extern int irq_can_set_affinity(unsigned int irq);
|
||||
extern int irq_select_affinity(unsigned int irq);
|
||||
|
||||
|
|
@ -275,6 +308,11 @@ static inline int irq_set_affinity(unsigned int irq, const struct cpumask *m)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
static inline int irq_force_affinity(unsigned int irq, const struct cpumask *cpumask)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int irq_can_set_affinity(unsigned int irq)
|
||||
{
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -375,7 +375,8 @@ extern void remove_percpu_irq(unsigned int irq, struct irqaction *act);
|
|||
|
||||
extern void irq_cpu_online(void);
|
||||
extern void irq_cpu_offline(void);
|
||||
extern int __irq_set_affinity_locked(struct irq_data *data, const struct cpumask *cpumask);
|
||||
extern int irq_set_affinity_locked(struct irq_data *data,
|
||||
const struct cpumask *cpumask, bool force);
|
||||
|
||||
#ifdef CONFIG_GENERIC_HARDIRQS
|
||||
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ DECLARE_EVENT_CLASS(module_refcnt,
|
|||
|
||||
TP_fast_assign(
|
||||
__entry->ip = ip;
|
||||
__entry->refcnt = __this_cpu_read(mod->refptr->incs) + __this_cpu_read(mod->refptr->decs);
|
||||
__entry->refcnt = __this_cpu_read(mod->refptr->incs) - __this_cpu_read(mod->refptr->decs);
|
||||
__assign_str(name, mod->name);
|
||||
),
|
||||
|
||||
|
|
|
|||
|
|
@ -103,7 +103,6 @@ struct drm_tegra_submit {
|
|||
__u32 num_waitchks;
|
||||
__u32 waitchk_mask;
|
||||
__u32 timeout;
|
||||
__u32 pad;
|
||||
__u64 syncpts;
|
||||
__u64 cmdbufs;
|
||||
__u64 relocs;
|
||||
|
|
|
|||
239
kernel/futex.c
239
kernel/futex.c
|
|
@ -593,6 +593,55 @@ void exit_pi_state_list(struct task_struct *curr)
|
|||
raw_spin_unlock_irq(&curr->pi_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
* We need to check the following states:
|
||||
*
|
||||
* Waiter | pi_state | pi->owner | uTID | uODIED | ?
|
||||
*
|
||||
* [1] NULL | --- | --- | 0 | 0/1 | Valid
|
||||
* [2] NULL | --- | --- | >0 | 0/1 | Valid
|
||||
*
|
||||
* [3] Found | NULL | -- | Any | 0/1 | Invalid
|
||||
*
|
||||
* [4] Found | Found | NULL | 0 | 1 | Valid
|
||||
* [5] Found | Found | NULL | >0 | 1 | Invalid
|
||||
*
|
||||
* [6] Found | Found | task | 0 | 1 | Valid
|
||||
*
|
||||
* [7] Found | Found | NULL | Any | 0 | Invalid
|
||||
*
|
||||
* [8] Found | Found | task | ==taskTID | 0/1 | Valid
|
||||
* [9] Found | Found | task | 0 | 0 | Invalid
|
||||
* [10] Found | Found | task | !=taskTID | 0/1 | Invalid
|
||||
*
|
||||
* [1] Indicates that the kernel can acquire the futex atomically. We
|
||||
* came came here due to a stale FUTEX_WAITERS/FUTEX_OWNER_DIED bit.
|
||||
*
|
||||
* [2] Valid, if TID does not belong to a kernel thread. If no matching
|
||||
* thread is found then it indicates that the owner TID has died.
|
||||
*
|
||||
* [3] Invalid. The waiter is queued on a non PI futex
|
||||
*
|
||||
* [4] Valid state after exit_robust_list(), which sets the user space
|
||||
* value to FUTEX_WAITERS | FUTEX_OWNER_DIED.
|
||||
*
|
||||
* [5] The user space value got manipulated between exit_robust_list()
|
||||
* and exit_pi_state_list()
|
||||
*
|
||||
* [6] Valid state after exit_pi_state_list() which sets the new owner in
|
||||
* the pi_state but cannot access the user space value.
|
||||
*
|
||||
* [7] pi_state->owner can only be NULL when the OWNER_DIED bit is set.
|
||||
*
|
||||
* [8] Owner and user space value match
|
||||
*
|
||||
* [9] There is no transient state which sets the user space TID to 0
|
||||
* except exit_robust_list(), but this is indicated by the
|
||||
* FUTEX_OWNER_DIED bit. See [4]
|
||||
*
|
||||
* [10] There is no transient state which leaves owner and user space
|
||||
* TID out of sync.
|
||||
*/
|
||||
static int
|
||||
lookup_pi_state(u32 uval, struct futex_hash_bucket *hb,
|
||||
union futex_key *key, struct futex_pi_state **ps)
|
||||
|
|
@ -608,12 +657,13 @@ lookup_pi_state(u32 uval, struct futex_hash_bucket *hb,
|
|||
plist_for_each_entry_safe(this, next, head, list) {
|
||||
if (match_futex(&this->key, key)) {
|
||||
/*
|
||||
* Another waiter already exists - bump up
|
||||
* the refcount and return its pi_state:
|
||||
* Sanity check the waiter before increasing
|
||||
* the refcount and attaching to it.
|
||||
*/
|
||||
pi_state = this->pi_state;
|
||||
/*
|
||||
* Userspace might have messed up non-PI and PI futexes
|
||||
* Userspace might have messed up non-PI and
|
||||
* PI futexes [3]
|
||||
*/
|
||||
if (unlikely(!pi_state))
|
||||
return -EINVAL;
|
||||
|
|
@ -621,34 +671,70 @@ lookup_pi_state(u32 uval, struct futex_hash_bucket *hb,
|
|||
WARN_ON(!atomic_read(&pi_state->refcount));
|
||||
|
||||
/*
|
||||
* When pi_state->owner is NULL then the owner died
|
||||
* and another waiter is on the fly. pi_state->owner
|
||||
* is fixed up by the task which acquires
|
||||
* pi_state->rt_mutex.
|
||||
*
|
||||
* We do not check for pid == 0 which can happen when
|
||||
* the owner died and robust_list_exit() cleared the
|
||||
* TID.
|
||||
* Handle the owner died case:
|
||||
*/
|
||||
if (pid && pi_state->owner) {
|
||||
if (uval & FUTEX_OWNER_DIED) {
|
||||
/*
|
||||
* Bail out if user space manipulated the
|
||||
* futex value.
|
||||
* exit_pi_state_list sets owner to NULL and
|
||||
* wakes the topmost waiter. The task which
|
||||
* acquires the pi_state->rt_mutex will fixup
|
||||
* owner.
|
||||
*/
|
||||
if (pid != task_pid_vnr(pi_state->owner))
|
||||
if (!pi_state->owner) {
|
||||
/*
|
||||
* No pi state owner, but the user
|
||||
* space TID is not 0. Inconsistent
|
||||
* state. [5]
|
||||
*/
|
||||
if (pid)
|
||||
return -EINVAL;
|
||||
/*
|
||||
* Take a ref on the state and
|
||||
* return. [4]
|
||||
*/
|
||||
goto out_state;
|
||||
}
|
||||
|
||||
/*
|
||||
* If TID is 0, then either the dying owner
|
||||
* has not yet executed exit_pi_state_list()
|
||||
* or some waiter acquired the rtmutex in the
|
||||
* pi state, but did not yet fixup the TID in
|
||||
* user space.
|
||||
*
|
||||
* Take a ref on the state and return. [6]
|
||||
*/
|
||||
if (!pid)
|
||||
goto out_state;
|
||||
} else {
|
||||
/*
|
||||
* If the owner died bit is not set,
|
||||
* then the pi_state must have an
|
||||
* owner. [7]
|
||||
*/
|
||||
if (!pi_state->owner)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Bail out if user space manipulated the
|
||||
* futex value. If pi state exists then the
|
||||
* owner TID must be the same as the user
|
||||
* space TID. [9/10]
|
||||
*/
|
||||
if (pid != task_pid_vnr(pi_state->owner))
|
||||
return -EINVAL;
|
||||
|
||||
out_state:
|
||||
atomic_inc(&pi_state->refcount);
|
||||
*ps = pi_state;
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* We are the first waiter - try to look up the real owner and attach
|
||||
* the new pi_state to it, but bail out when TID = 0
|
||||
* the new pi_state to it, but bail out when TID = 0 [1]
|
||||
*/
|
||||
if (!pid)
|
||||
return -ESRCH;
|
||||
|
|
@ -656,6 +742,11 @@ lookup_pi_state(u32 uval, struct futex_hash_bucket *hb,
|
|||
if (!p)
|
||||
return -ESRCH;
|
||||
|
||||
if (!p->mm) {
|
||||
put_task_struct(p);
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
/*
|
||||
* We need to look at the task state flags to figure out,
|
||||
* whether the task is exiting. To protect against the do_exit
|
||||
|
|
@ -676,6 +767,9 @@ lookup_pi_state(u32 uval, struct futex_hash_bucket *hb,
|
|||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* No existing pi state. First waiter. [2]
|
||||
*/
|
||||
pi_state = alloc_pi_state();
|
||||
|
||||
/*
|
||||
|
|
@ -747,10 +841,18 @@ retry:
|
|||
return -EDEADLK;
|
||||
|
||||
/*
|
||||
* Surprise - we got the lock. Just return to userspace:
|
||||
* Surprise - we got the lock, but we do not trust user space at all.
|
||||
*/
|
||||
if (unlikely(!curval))
|
||||
return 1;
|
||||
if (unlikely(!curval)) {
|
||||
/*
|
||||
* We verify whether there is kernel state for this
|
||||
* futex. If not, we can safely assume, that the 0 ->
|
||||
* TID transition is correct. If state exists, we do
|
||||
* not bother to fixup the user space state as it was
|
||||
* corrupted already.
|
||||
*/
|
||||
return futex_top_waiter(hb, key) ? -EINVAL : 1;
|
||||
}
|
||||
|
||||
uval = curval;
|
||||
|
||||
|
|
@ -880,6 +982,7 @@ static int wake_futex_pi(u32 __user *uaddr, u32 uval, struct futex_q *this)
|
|||
struct task_struct *new_owner;
|
||||
struct futex_pi_state *pi_state = this->pi_state;
|
||||
u32 uninitialized_var(curval), newval;
|
||||
int ret = 0;
|
||||
|
||||
if (!pi_state)
|
||||
return -EINVAL;
|
||||
|
|
@ -903,23 +1006,19 @@ static int wake_futex_pi(u32 __user *uaddr, u32 uval, struct futex_q *this)
|
|||
new_owner = this->task;
|
||||
|
||||
/*
|
||||
* We pass it to the next owner. (The WAITERS bit is always
|
||||
* kept enabled while there is PI state around. We must also
|
||||
* preserve the owner died bit.)
|
||||
* We pass it to the next owner. The WAITERS bit is always
|
||||
* kept enabled while there is PI state around. We cleanup the
|
||||
* owner died bit, because we are the owner.
|
||||
*/
|
||||
if (!(uval & FUTEX_OWNER_DIED)) {
|
||||
int ret = 0;
|
||||
newval = FUTEX_WAITERS | task_pid_vnr(new_owner);
|
||||
|
||||
newval = FUTEX_WAITERS | task_pid_vnr(new_owner);
|
||||
|
||||
if (cmpxchg_futex_value_locked(&curval, uaddr, uval, newval))
|
||||
ret = -EFAULT;
|
||||
else if (curval != uval)
|
||||
ret = -EINVAL;
|
||||
if (ret) {
|
||||
raw_spin_unlock(&pi_state->pi_mutex.wait_lock);
|
||||
return ret;
|
||||
}
|
||||
if (cmpxchg_futex_value_locked(&curval, uaddr, uval, newval))
|
||||
ret = -EFAULT;
|
||||
else if (curval != uval)
|
||||
ret = -EINVAL;
|
||||
if (ret) {
|
||||
raw_spin_unlock(&pi_state->pi_mutex.wait_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
raw_spin_lock_irq(&pi_state->owner->pi_lock);
|
||||
|
|
@ -1198,7 +1297,7 @@ void requeue_pi_wake_futex(struct futex_q *q, union futex_key *key,
|
|||
*
|
||||
* Return:
|
||||
* 0 - failed to acquire the lock atomically;
|
||||
* 1 - acquired the lock;
|
||||
* >0 - acquired the lock, return value is vpid of the top_waiter
|
||||
* <0 - error
|
||||
*/
|
||||
static int futex_proxy_trylock_atomic(u32 __user *pifutex,
|
||||
|
|
@ -1209,7 +1308,7 @@ static int futex_proxy_trylock_atomic(u32 __user *pifutex,
|
|||
{
|
||||
struct futex_q *top_waiter = NULL;
|
||||
u32 curval;
|
||||
int ret;
|
||||
int ret, vpid;
|
||||
|
||||
if (get_futex_value_locked(&curval, pifutex))
|
||||
return -EFAULT;
|
||||
|
|
@ -1237,11 +1336,13 @@ static int futex_proxy_trylock_atomic(u32 __user *pifutex,
|
|||
* the contended case or if set_waiters is 1. The pi_state is returned
|
||||
* in ps in contended cases.
|
||||
*/
|
||||
vpid = task_pid_vnr(top_waiter->task);
|
||||
ret = futex_lock_pi_atomic(pifutex, hb2, key2, ps, top_waiter->task,
|
||||
set_waiters);
|
||||
if (ret == 1)
|
||||
if (ret == 1) {
|
||||
requeue_pi_wake_futex(top_waiter, key2, hb2);
|
||||
|
||||
return vpid;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -1273,9 +1374,15 @@ static int futex_requeue(u32 __user *uaddr1, unsigned int flags,
|
|||
struct futex_hash_bucket *hb1, *hb2;
|
||||
struct plist_head *head1;
|
||||
struct futex_q *this, *next;
|
||||
u32 curval2;
|
||||
|
||||
if (requeue_pi) {
|
||||
/*
|
||||
* Requeue PI only works on two distinct uaddrs. This
|
||||
* check is only valid for private futexes. See below.
|
||||
*/
|
||||
if (uaddr1 == uaddr2)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* requeue_pi requires a pi_state, try to allocate it now
|
||||
* without any locks in case it fails.
|
||||
|
|
@ -1314,6 +1421,15 @@ retry:
|
|||
if (unlikely(ret != 0))
|
||||
goto out_put_key1;
|
||||
|
||||
/*
|
||||
* The check above which compares uaddrs is not sufficient for
|
||||
* shared futexes. We need to compare the keys:
|
||||
*/
|
||||
if (requeue_pi && match_futex(&key1, &key2)) {
|
||||
ret = -EINVAL;
|
||||
goto out_put_keys;
|
||||
}
|
||||
|
||||
hb1 = hash_futex(&key1);
|
||||
hb2 = hash_futex(&key2);
|
||||
|
||||
|
|
@ -1359,16 +1475,25 @@ retry_private:
|
|||
* At this point the top_waiter has either taken uaddr2 or is
|
||||
* waiting on it. If the former, then the pi_state will not
|
||||
* exist yet, look it up one more time to ensure we have a
|
||||
* reference to it.
|
||||
* reference to it. If the lock was taken, ret contains the
|
||||
* vpid of the top waiter task.
|
||||
*/
|
||||
if (ret == 1) {
|
||||
if (ret > 0) {
|
||||
WARN_ON(pi_state);
|
||||
drop_count++;
|
||||
task_count++;
|
||||
ret = get_futex_value_locked(&curval2, uaddr2);
|
||||
if (!ret)
|
||||
ret = lookup_pi_state(curval2, hb2, &key2,
|
||||
&pi_state);
|
||||
/*
|
||||
* If we acquired the lock, then the user
|
||||
* space value of uaddr2 should be vpid. It
|
||||
* cannot be changed by the top waiter as it
|
||||
* is blocked on hb2 lock if it tries to do
|
||||
* so. If something fiddled with it behind our
|
||||
* back the pi state lookup might unearth
|
||||
* it. So we rather use the known value than
|
||||
* rereading and handing potential crap to
|
||||
* lookup_pi_state.
|
||||
*/
|
||||
ret = lookup_pi_state(ret, hb2, &key2, &pi_state);
|
||||
}
|
||||
|
||||
switch (ret) {
|
||||
|
|
@ -2138,9 +2263,10 @@ retry:
|
|||
/*
|
||||
* To avoid races, try to do the TID -> 0 atomic transition
|
||||
* again. If it succeeds then we can return without waking
|
||||
* anyone else up:
|
||||
* anyone else up. We only try this if neither the waiters nor
|
||||
* the owner died bit are set.
|
||||
*/
|
||||
if (!(uval & FUTEX_OWNER_DIED) &&
|
||||
if (!(uval & ~FUTEX_TID_MASK) &&
|
||||
cmpxchg_futex_value_locked(&uval, uaddr, vpid, 0))
|
||||
goto pi_faulted;
|
||||
/*
|
||||
|
|
@ -2172,11 +2298,9 @@ retry:
|
|||
/*
|
||||
* No waiters - kernel unlocks the futex:
|
||||
*/
|
||||
if (!(uval & FUTEX_OWNER_DIED)) {
|
||||
ret = unlock_futex_pi(uaddr, uval);
|
||||
if (ret == -EFAULT)
|
||||
goto pi_faulted;
|
||||
}
|
||||
ret = unlock_futex_pi(uaddr, uval);
|
||||
if (ret == -EFAULT)
|
||||
goto pi_faulted;
|
||||
|
||||
out_unlock:
|
||||
spin_unlock(&hb->lock);
|
||||
|
|
@ -2335,6 +2459,15 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags,
|
|||
if (ret)
|
||||
goto out_key2;
|
||||
|
||||
/*
|
||||
* The check above which compares uaddrs is not sufficient for
|
||||
* shared futexes. We need to compare the keys:
|
||||
*/
|
||||
if (match_futex(&q.key, &key2)) {
|
||||
ret = -EINVAL;
|
||||
goto out_put_keys;
|
||||
}
|
||||
|
||||
/* Queue the futex_q, drop the hb lock, wait for wakeup. */
|
||||
futex_wait_queue_me(hb, &q, to);
|
||||
|
||||
|
|
|
|||
|
|
@ -246,6 +246,11 @@ again:
|
|||
goto again;
|
||||
}
|
||||
timer->base = new_base;
|
||||
} else {
|
||||
if (cpu != this_cpu && hrtimer_check_target(timer, new_base)) {
|
||||
cpu = this_cpu;
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
return new_base;
|
||||
}
|
||||
|
|
@ -581,6 +586,23 @@ hrtimer_force_reprogram(struct hrtimer_cpu_base *cpu_base, int skip_equal)
|
|||
|
||||
cpu_base->expires_next.tv64 = expires_next.tv64;
|
||||
|
||||
/*
|
||||
* If a hang was detected in the last timer interrupt then we
|
||||
* leave the hang delay active in the hardware. We want the
|
||||
* system to make progress. That also prevents the following
|
||||
* scenario:
|
||||
* T1 expires 50ms from now
|
||||
* T2 expires 5s from now
|
||||
*
|
||||
* T1 is removed, so this code is called and would reprogram
|
||||
* the hardware to 5s from now. Any hrtimer_start after that
|
||||
* will not reprogram the hardware due to hang_detected being
|
||||
* set. So we'd effectivly block all timers until the T2 event
|
||||
* fires.
|
||||
*/
|
||||
if (cpu_base->hang_detected)
|
||||
return;
|
||||
|
||||
if (cpu_base->expires_next.tv64 != KTIME_MAX)
|
||||
tick_program_event(cpu_base->expires_next, 1);
|
||||
}
|
||||
|
|
@ -978,11 +1000,8 @@ int __hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim,
|
|||
/* Remove an active timer from the queue: */
|
||||
ret = remove_hrtimer(timer, base);
|
||||
|
||||
/* Switch the timer base, if necessary: */
|
||||
new_base = switch_hrtimer_base(timer, base, mode & HRTIMER_MODE_PINNED);
|
||||
|
||||
if (mode & HRTIMER_MODE_REL) {
|
||||
tim = ktime_add_safe(tim, new_base->get_time());
|
||||
tim = ktime_add_safe(tim, base->get_time());
|
||||
/*
|
||||
* CONFIG_TIME_LOW_RES is a temporary way for architectures
|
||||
* to signal that they simply return xtime in
|
||||
|
|
@ -997,6 +1016,9 @@ int __hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim,
|
|||
|
||||
hrtimer_set_expires_range_ns(timer, tim, delta_ns);
|
||||
|
||||
/* Switch the timer base, if necessary: */
|
||||
new_base = switch_hrtimer_base(timer, base, mode & HRTIMER_MODE_PINNED);
|
||||
|
||||
timer_stats_hrtimer_set_start_info(timer);
|
||||
|
||||
leftmost = enqueue_hrtimer(timer, new_base);
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue