mirror of
https://github.com/Fishwaldo/build.git
synced 2025-03-26 16:51:48 +00:00
1175 lines
35 KiB
Diff
1175 lines
35 KiB
Diff
diff --git a/Makefile b/Makefile
|
|
index 083724c6ca4d..fb7c2b40753d 100644
|
|
--- a/Makefile
|
|
+++ b/Makefile
|
|
@@ -1,6 +1,6 @@
|
|
VERSION = 4
|
|
PATCHLEVEL = 4
|
|
-SUBLEVEL = 59
|
|
+SUBLEVEL = 60
|
|
EXTRAVERSION =
|
|
NAME = Blurry Fish Butt
|
|
|
|
diff --git a/arch/mips/lantiq/irq.c b/arch/mips/lantiq/irq.c
|
|
index 2e7f60c9fc5d..51cdc46a87e2 100644
|
|
--- a/arch/mips/lantiq/irq.c
|
|
+++ b/arch/mips/lantiq/irq.c
|
|
@@ -269,6 +269,11 @@ static void ltq_hw5_irqdispatch(void)
|
|
DEFINE_HWx_IRQDISPATCH(5)
|
|
#endif
|
|
|
|
+static void ltq_hw_irq_handler(struct irq_desc *desc)
|
|
+{
|
|
+ ltq_hw_irqdispatch(irq_desc_get_irq(desc) - 2);
|
|
+}
|
|
+
|
|
#ifdef CONFIG_MIPS_MT_SMP
|
|
void __init arch_init_ipiirq(int irq, struct irqaction *action)
|
|
{
|
|
@@ -313,23 +318,19 @@ static struct irqaction irq_call = {
|
|
asmlinkage void plat_irq_dispatch(void)
|
|
{
|
|
unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM;
|
|
- unsigned int i;
|
|
-
|
|
- if ((MIPS_CPU_TIMER_IRQ == 7) && (pending & CAUSEF_IP7)) {
|
|
- do_IRQ(MIPS_CPU_TIMER_IRQ);
|
|
- goto out;
|
|
- } else {
|
|
- for (i = 0; i < MAX_IM; i++) {
|
|
- if (pending & (CAUSEF_IP2 << i)) {
|
|
- ltq_hw_irqdispatch(i);
|
|
- goto out;
|
|
- }
|
|
- }
|
|
+ int irq;
|
|
+
|
|
+ if (!pending) {
|
|
+ spurious_interrupt();
|
|
+ return;
|
|
}
|
|
- pr_alert("Spurious IRQ: CAUSE=0x%08x\n", read_c0_status());
|
|
|
|
-out:
|
|
- return;
|
|
+ pending >>= CAUSEB_IP;
|
|
+ while (pending) {
|
|
+ irq = fls(pending) - 1;
|
|
+ do_IRQ(MIPS_CPU_IRQ_BASE + irq);
|
|
+ pending &= ~BIT(irq);
|
|
+ }
|
|
}
|
|
|
|
static int icu_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
|
|
@@ -354,11 +355,6 @@ static const struct irq_domain_ops irq_domain_ops = {
|
|
.map = icu_map,
|
|
};
|
|
|
|
-static struct irqaction cascade = {
|
|
- .handler = no_action,
|
|
- .name = "cascade",
|
|
-};
|
|
-
|
|
int __init icu_of_init(struct device_node *node, struct device_node *parent)
|
|
{
|
|
struct device_node *eiu_node;
|
|
@@ -390,7 +386,7 @@ int __init icu_of_init(struct device_node *node, struct device_node *parent)
|
|
mips_cpu_irq_init();
|
|
|
|
for (i = 0; i < MAX_IM; i++)
|
|
- setup_irq(i + 2, &cascade);
|
|
+ irq_set_chained_handler(i + 2, ltq_hw_irq_handler);
|
|
|
|
if (cpu_has_vint) {
|
|
pr_info("Setting up vectored interrupts\n");
|
|
diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c
|
|
index e345891450c3..df8844a1853a 100644
|
|
--- a/arch/x86/xen/setup.c
|
|
+++ b/arch/x86/xen/setup.c
|
|
@@ -713,10 +713,9 @@ static void __init xen_reserve_xen_mfnlist(void)
|
|
size = PFN_PHYS(xen_start_info->nr_p2m_frames);
|
|
}
|
|
|
|
- if (!xen_is_e820_reserved(start, size)) {
|
|
- memblock_reserve(start, size);
|
|
+ memblock_reserve(start, size);
|
|
+ if (!xen_is_e820_reserved(start, size))
|
|
return;
|
|
- }
|
|
|
|
#ifdef CONFIG_X86_32
|
|
/*
|
|
@@ -727,6 +726,7 @@ static void __init xen_reserve_xen_mfnlist(void)
|
|
BUG();
|
|
#else
|
|
xen_relocate_p2m();
|
|
+ memblock_free(start, size);
|
|
#endif
|
|
}
|
|
|
|
diff --git a/block/bio.c b/block/bio.c
|
|
index 46e2cc1d4016..14263fab94d3 100644
|
|
--- a/block/bio.c
|
|
+++ b/block/bio.c
|
|
@@ -373,10 +373,14 @@ static void punt_bios_to_rescuer(struct bio_set *bs)
|
|
bio_list_init(&punt);
|
|
bio_list_init(&nopunt);
|
|
|
|
- while ((bio = bio_list_pop(current->bio_list)))
|
|
+ while ((bio = bio_list_pop(¤t->bio_list[0])))
|
|
bio_list_add(bio->bi_pool == bs ? &punt : &nopunt, bio);
|
|
+ current->bio_list[0] = nopunt;
|
|
|
|
- *current->bio_list = nopunt;
|
|
+ bio_list_init(&nopunt);
|
|
+ while ((bio = bio_list_pop(¤t->bio_list[1])))
|
|
+ bio_list_add(bio->bi_pool == bs ? &punt : &nopunt, bio);
|
|
+ current->bio_list[1] = nopunt;
|
|
|
|
spin_lock(&bs->rescue_lock);
|
|
bio_list_merge(&bs->rescue_list, &punt);
|
|
@@ -464,7 +468,9 @@ struct bio *bio_alloc_bioset(gfp_t gfp_mask, int nr_iovecs, struct bio_set *bs)
|
|
* we retry with the original gfp_flags.
|
|
*/
|
|
|
|
- if (current->bio_list && !bio_list_empty(current->bio_list))
|
|
+ if (current->bio_list &&
|
|
+ (!bio_list_empty(¤t->bio_list[0]) ||
|
|
+ !bio_list_empty(¤t->bio_list[1])))
|
|
gfp_mask &= ~__GFP_DIRECT_RECLAIM;
|
|
|
|
p = mempool_alloc(bs->bio_pool, gfp_mask);
|
|
diff --git a/block/blk-core.c b/block/blk-core.c
|
|
index 4fab5d610805..ef083e7a37c5 100644
|
|
--- a/block/blk-core.c
|
|
+++ b/block/blk-core.c
|
|
@@ -2021,7 +2021,14 @@ end_io:
|
|
*/
|
|
blk_qc_t generic_make_request(struct bio *bio)
|
|
{
|
|
- struct bio_list bio_list_on_stack;
|
|
+ /*
|
|
+ * bio_list_on_stack[0] contains bios submitted by the current
|
|
+ * make_request_fn.
|
|
+ * bio_list_on_stack[1] contains bios that were submitted before
|
|
+ * the current make_request_fn, but that haven't been processed
|
|
+ * yet.
|
|
+ */
|
|
+ struct bio_list bio_list_on_stack[2];
|
|
blk_qc_t ret = BLK_QC_T_NONE;
|
|
|
|
if (!generic_make_request_checks(bio))
|
|
@@ -2038,7 +2045,7 @@ blk_qc_t generic_make_request(struct bio *bio)
|
|
* should be added at the tail
|
|
*/
|
|
if (current->bio_list) {
|
|
- bio_list_add(current->bio_list, bio);
|
|
+ bio_list_add(¤t->bio_list[0], bio);
|
|
goto out;
|
|
}
|
|
|
|
@@ -2057,24 +2064,39 @@ blk_qc_t generic_make_request(struct bio *bio)
|
|
* bio_list, and call into ->make_request() again.
|
|
*/
|
|
BUG_ON(bio->bi_next);
|
|
- bio_list_init(&bio_list_on_stack);
|
|
- current->bio_list = &bio_list_on_stack;
|
|
+ bio_list_init(&bio_list_on_stack[0]);
|
|
+ current->bio_list = bio_list_on_stack;
|
|
do {
|
|
struct request_queue *q = bdev_get_queue(bio->bi_bdev);
|
|
|
|
if (likely(blk_queue_enter(q, __GFP_DIRECT_RECLAIM) == 0)) {
|
|
+ struct bio_list lower, same;
|
|
+
|
|
+ /* Create a fresh bio_list for all subordinate requests */
|
|
+ bio_list_on_stack[1] = bio_list_on_stack[0];
|
|
+ bio_list_init(&bio_list_on_stack[0]);
|
|
|
|
ret = q->make_request_fn(q, bio);
|
|
|
|
blk_queue_exit(q);
|
|
-
|
|
- bio = bio_list_pop(current->bio_list);
|
|
+ /* sort new bios into those for a lower level
|
|
+ * and those for the same level
|
|
+ */
|
|
+ bio_list_init(&lower);
|
|
+ bio_list_init(&same);
|
|
+ while ((bio = bio_list_pop(&bio_list_on_stack[0])) != NULL)
|
|
+ if (q == bdev_get_queue(bio->bi_bdev))
|
|
+ bio_list_add(&same, bio);
|
|
+ else
|
|
+ bio_list_add(&lower, bio);
|
|
+ /* now assemble so we handle the lowest level first */
|
|
+ bio_list_merge(&bio_list_on_stack[0], &lower);
|
|
+ bio_list_merge(&bio_list_on_stack[0], &same);
|
|
+ bio_list_merge(&bio_list_on_stack[0], &bio_list_on_stack[1]);
|
|
} else {
|
|
- struct bio *bio_next = bio_list_pop(current->bio_list);
|
|
-
|
|
bio_io_error(bio);
|
|
- bio = bio_next;
|
|
}
|
|
+ bio = bio_list_pop(&bio_list_on_stack[0]);
|
|
} while (bio);
|
|
current->bio_list = NULL; /* deactivate */
|
|
|
|
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
|
|
index 675eaf337178..b9cebca376f9 100644
|
|
--- a/drivers/acpi/Makefile
|
|
+++ b/drivers/acpi/Makefile
|
|
@@ -2,7 +2,6 @@
|
|
# Makefile for the Linux ACPI interpreter
|
|
#
|
|
|
|
-ccflags-y := -Os
|
|
ccflags-$(CONFIG_ACPI_DEBUG) += -DACPI_DEBUG_OUTPUT
|
|
|
|
#
|
|
diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c
|
|
index 296b7a14893a..5365ff6e69c1 100644
|
|
--- a/drivers/acpi/acpi_platform.c
|
|
+++ b/drivers/acpi/acpi_platform.c
|
|
@@ -24,9 +24,11 @@
|
|
ACPI_MODULE_NAME("platform");
|
|
|
|
static const struct acpi_device_id forbidden_id_list[] = {
|
|
- {"PNP0000", 0}, /* PIC */
|
|
- {"PNP0100", 0}, /* Timer */
|
|
- {"PNP0200", 0}, /* AT DMA Controller */
|
|
+ {"PNP0000", 0}, /* PIC */
|
|
+ {"PNP0100", 0}, /* Timer */
|
|
+ {"PNP0200", 0}, /* AT DMA Controller */
|
|
+ {"ACPI0009", 0}, /* IOxAPIC */
|
|
+ {"ACPI000A", 0}, /* IOAPIC */
|
|
{"", 0},
|
|
};
|
|
|
|
diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c
|
|
index 35310336dd0a..d684e2b79d2b 100644
|
|
--- a/drivers/gpu/drm/radeon/radeon_ttm.c
|
|
+++ b/drivers/gpu/drm/radeon/radeon_ttm.c
|
|
@@ -213,8 +213,8 @@ static void radeon_evict_flags(struct ttm_buffer_object *bo,
|
|
rbo->placement.num_busy_placement = 0;
|
|
for (i = 0; i < rbo->placement.num_placement; i++) {
|
|
if (rbo->placements[i].flags & TTM_PL_FLAG_VRAM) {
|
|
- if (rbo->placements[0].fpfn < fpfn)
|
|
- rbo->placements[0].fpfn = fpfn;
|
|
+ if (rbo->placements[i].fpfn < fpfn)
|
|
+ rbo->placements[i].fpfn = fpfn;
|
|
} else {
|
|
rbo->placement.busy_placement =
|
|
&rbo->placements[i];
|
|
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
|
|
index 397f0454100b..320eb3c4bb6b 100644
|
|
--- a/drivers/md/dm.c
|
|
+++ b/drivers/md/dm.c
|
|
@@ -1481,26 +1481,29 @@ static void flush_current_bio_list(struct blk_plug_cb *cb, bool from_schedule)
|
|
struct dm_offload *o = container_of(cb, struct dm_offload, cb);
|
|
struct bio_list list;
|
|
struct bio *bio;
|
|
+ int i;
|
|
|
|
INIT_LIST_HEAD(&o->cb.list);
|
|
|
|
if (unlikely(!current->bio_list))
|
|
return;
|
|
|
|
- list = *current->bio_list;
|
|
- bio_list_init(current->bio_list);
|
|
-
|
|
- while ((bio = bio_list_pop(&list))) {
|
|
- struct bio_set *bs = bio->bi_pool;
|
|
- if (unlikely(!bs) || bs == fs_bio_set) {
|
|
- bio_list_add(current->bio_list, bio);
|
|
- continue;
|
|
+ for (i = 0; i < 2; i++) {
|
|
+ list = current->bio_list[i];
|
|
+ bio_list_init(¤t->bio_list[i]);
|
|
+
|
|
+ while ((bio = bio_list_pop(&list))) {
|
|
+ struct bio_set *bs = bio->bi_pool;
|
|
+ if (unlikely(!bs) || bs == fs_bio_set) {
|
|
+ bio_list_add(¤t->bio_list[i], bio);
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ spin_lock(&bs->rescue_lock);
|
|
+ bio_list_add(&bs->rescue_list, bio);
|
|
+ queue_work(bs->rescue_workqueue, &bs->rescue_work);
|
|
+ spin_unlock(&bs->rescue_lock);
|
|
}
|
|
-
|
|
- spin_lock(&bs->rescue_lock);
|
|
- bio_list_add(&bs->rescue_list, bio);
|
|
- queue_work(bs->rescue_workqueue, &bs->rescue_work);
|
|
- spin_unlock(&bs->rescue_lock);
|
|
}
|
|
}
|
|
|
|
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
|
|
index 515554c7365b..9be39988bf06 100644
|
|
--- a/drivers/md/raid1.c
|
|
+++ b/drivers/md/raid1.c
|
|
@@ -877,7 +877,8 @@ static sector_t wait_barrier(struct r1conf *conf, struct bio *bio)
|
|
((conf->start_next_window <
|
|
conf->next_resync + RESYNC_SECTORS) &&
|
|
current->bio_list &&
|
|
- !bio_list_empty(current->bio_list))),
|
|
+ (!bio_list_empty(¤t->bio_list[0]) ||
|
|
+ !bio_list_empty(¤t->bio_list[1])))),
|
|
conf->resync_lock);
|
|
conf->nr_waiting--;
|
|
}
|
|
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
|
|
index a92979e704e3..e5ee4e9e0ea5 100644
|
|
--- a/drivers/md/raid10.c
|
|
+++ b/drivers/md/raid10.c
|
|
@@ -946,7 +946,8 @@ static void wait_barrier(struct r10conf *conf)
|
|
!conf->barrier ||
|
|
(conf->nr_pending &&
|
|
current->bio_list &&
|
|
- !bio_list_empty(current->bio_list)),
|
|
+ (!bio_list_empty(¤t->bio_list[0]) ||
|
|
+ !bio_list_empty(¤t->bio_list[1]))),
|
|
conf->resync_lock);
|
|
conf->nr_waiting--;
|
|
}
|
|
diff --git a/drivers/power/reset/at91-poweroff.c b/drivers/power/reset/at91-poweroff.c
|
|
index e9e24df35f26..2579f025b90b 100644
|
|
--- a/drivers/power/reset/at91-poweroff.c
|
|
+++ b/drivers/power/reset/at91-poweroff.c
|
|
@@ -14,9 +14,12 @@
|
|
#include <linux/io.h>
|
|
#include <linux/module.h>
|
|
#include <linux/of.h>
|
|
+#include <linux/of_address.h>
|
|
#include <linux/platform_device.h>
|
|
#include <linux/printk.h>
|
|
|
|
+#include <soc/at91/at91sam9_ddrsdr.h>
|
|
+
|
|
#define AT91_SHDW_CR 0x00 /* Shut Down Control Register */
|
|
#define AT91_SHDW_SHDW BIT(0) /* Shut Down command */
|
|
#define AT91_SHDW_KEY (0xa5 << 24) /* KEY Password */
|
|
@@ -50,6 +53,7 @@ static const char *shdwc_wakeup_modes[] = {
|
|
|
|
static void __iomem *at91_shdwc_base;
|
|
static struct clk *sclk;
|
|
+static void __iomem *mpddrc_base;
|
|
|
|
static void __init at91_wakeup_status(void)
|
|
{
|
|
@@ -73,6 +77,29 @@ static void at91_poweroff(void)
|
|
writel(AT91_SHDW_KEY | AT91_SHDW_SHDW, at91_shdwc_base + AT91_SHDW_CR);
|
|
}
|
|
|
|
+static void at91_lpddr_poweroff(void)
|
|
+{
|
|
+ asm volatile(
|
|
+ /* Align to cache lines */
|
|
+ ".balign 32\n\t"
|
|
+
|
|
+ /* Ensure AT91_SHDW_CR is in the TLB by reading it */
|
|
+ " ldr r6, [%2, #" __stringify(AT91_SHDW_CR) "]\n\t"
|
|
+
|
|
+ /* Power down SDRAM0 */
|
|
+ " str %1, [%0, #" __stringify(AT91_DDRSDRC_LPR) "]\n\t"
|
|
+ /* Shutdown CPU */
|
|
+ " str %3, [%2, #" __stringify(AT91_SHDW_CR) "]\n\t"
|
|
+
|
|
+ " b .\n\t"
|
|
+ :
|
|
+ : "r" (mpddrc_base),
|
|
+ "r" cpu_to_le32(AT91_DDRSDRC_LPDDR2_PWOFF),
|
|
+ "r" (at91_shdwc_base),
|
|
+ "r" cpu_to_le32(AT91_SHDW_KEY | AT91_SHDW_SHDW)
|
|
+ : "r0");
|
|
+}
|
|
+
|
|
static int at91_poweroff_get_wakeup_mode(struct device_node *np)
|
|
{
|
|
const char *pm;
|
|
@@ -124,6 +151,8 @@ static void at91_poweroff_dt_set_wakeup_mode(struct platform_device *pdev)
|
|
static int __init at91_poweroff_probe(struct platform_device *pdev)
|
|
{
|
|
struct resource *res;
|
|
+ struct device_node *np;
|
|
+ u32 ddr_type;
|
|
int ret;
|
|
|
|
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
|
@@ -150,12 +179,30 @@ static int __init at91_poweroff_probe(struct platform_device *pdev)
|
|
|
|
pm_power_off = at91_poweroff;
|
|
|
|
+ np = of_find_compatible_node(NULL, NULL, "atmel,sama5d3-ddramc");
|
|
+ if (!np)
|
|
+ return 0;
|
|
+
|
|
+ mpddrc_base = of_iomap(np, 0);
|
|
+ of_node_put(np);
|
|
+
|
|
+ if (!mpddrc_base)
|
|
+ return 0;
|
|
+
|
|
+ ddr_type = readl(mpddrc_base + AT91_DDRSDRC_MDR) & AT91_DDRSDRC_MD;
|
|
+ if ((ddr_type == AT91_DDRSDRC_MD_LPDDR2) ||
|
|
+ (ddr_type == AT91_DDRSDRC_MD_LPDDR3))
|
|
+ pm_power_off = at91_lpddr_poweroff;
|
|
+ else
|
|
+ iounmap(mpddrc_base);
|
|
+
|
|
return 0;
|
|
}
|
|
|
|
static int __exit at91_poweroff_remove(struct platform_device *pdev)
|
|
{
|
|
- if (pm_power_off == at91_poweroff)
|
|
+ if (pm_power_off == at91_poweroff ||
|
|
+ pm_power_off == at91_lpddr_poweroff)
|
|
pm_power_off = NULL;
|
|
|
|
clk_disable_unprepare(sclk);
|
|
@@ -163,6 +210,11 @@ static int __exit at91_poweroff_remove(struct platform_device *pdev)
|
|
return 0;
|
|
}
|
|
|
|
+static const struct of_device_id at91_ramc_of_match[] = {
|
|
+ { .compatible = "atmel,sama5d3-ddramc", },
|
|
+ { /* sentinel */ }
|
|
+};
|
|
+
|
|
static const struct of_device_id at91_poweroff_of_match[] = {
|
|
{ .compatible = "atmel,at91sam9260-shdwc", },
|
|
{ .compatible = "atmel,at91sam9rl-shdwc", },
|
|
diff --git a/drivers/rtc/rtc-s35390a.c b/drivers/rtc/rtc-s35390a.c
|
|
index f40afdd0e5f5..00662dd28d66 100644
|
|
--- a/drivers/rtc/rtc-s35390a.c
|
|
+++ b/drivers/rtc/rtc-s35390a.c
|
|
@@ -15,6 +15,7 @@
|
|
#include <linux/bitrev.h>
|
|
#include <linux/bcd.h>
|
|
#include <linux/slab.h>
|
|
+#include <linux/delay.h>
|
|
|
|
#define S35390A_CMD_STATUS1 0
|
|
#define S35390A_CMD_STATUS2 1
|
|
@@ -34,10 +35,14 @@
|
|
#define S35390A_ALRM_BYTE_HOURS 1
|
|
#define S35390A_ALRM_BYTE_MINS 2
|
|
|
|
+/* flags for STATUS1 */
|
|
#define S35390A_FLAG_POC 0x01
|
|
#define S35390A_FLAG_BLD 0x02
|
|
+#define S35390A_FLAG_INT2 0x04
|
|
#define S35390A_FLAG_24H 0x40
|
|
#define S35390A_FLAG_RESET 0x80
|
|
+
|
|
+/* flag for STATUS2 */
|
|
#define S35390A_FLAG_TEST 0x01
|
|
|
|
#define S35390A_INT2_MODE_MASK 0xF0
|
|
@@ -94,19 +99,63 @@ static int s35390a_get_reg(struct s35390a *s35390a, int reg, char *buf, int len)
|
|
return 0;
|
|
}
|
|
|
|
-static int s35390a_reset(struct s35390a *s35390a)
|
|
+/*
|
|
+ * Returns <0 on error, 0 if rtc is setup fine and 1 if the chip was reset.
|
|
+ * To keep the information if an irq is pending, pass the value read from
|
|
+ * STATUS1 to the caller.
|
|
+ */
|
|
+static int s35390a_reset(struct s35390a *s35390a, char *status1)
|
|
{
|
|
- char buf[1];
|
|
-
|
|
- if (s35390a_get_reg(s35390a, S35390A_CMD_STATUS1, buf, sizeof(buf)) < 0)
|
|
- return -EIO;
|
|
-
|
|
- if (!(buf[0] & (S35390A_FLAG_POC | S35390A_FLAG_BLD)))
|
|
+ char buf;
|
|
+ int ret;
|
|
+ unsigned initcount = 0;
|
|
+
|
|
+ ret = s35390a_get_reg(s35390a, S35390A_CMD_STATUS1, status1, 1);
|
|
+ if (ret < 0)
|
|
+ return ret;
|
|
+
|
|
+ if (*status1 & S35390A_FLAG_POC)
|
|
+ /*
|
|
+ * Do not communicate for 0.5 seconds since the power-on
|
|
+ * detection circuit is in operation.
|
|
+ */
|
|
+ msleep(500);
|
|
+ else if (!(*status1 & S35390A_FLAG_BLD))
|
|
+ /*
|
|
+ * If both POC and BLD are unset everything is fine.
|
|
+ */
|
|
return 0;
|
|
|
|
- buf[0] |= (S35390A_FLAG_RESET | S35390A_FLAG_24H);
|
|
- buf[0] &= 0xf0;
|
|
- return s35390a_set_reg(s35390a, S35390A_CMD_STATUS1, buf, sizeof(buf));
|
|
+ /*
|
|
+ * At least one of POC and BLD are set, so reinitialise chip. Keeping
|
|
+ * this information in the hardware to know later that the time isn't
|
|
+ * valid is unfortunately not possible because POC and BLD are cleared
|
|
+ * on read. So the reset is best done now.
|
|
+ *
|
|
+ * The 24H bit is kept over reset, so set it already here.
|
|
+ */
|
|
+initialize:
|
|
+ *status1 = S35390A_FLAG_24H;
|
|
+ buf = S35390A_FLAG_RESET | S35390A_FLAG_24H;
|
|
+ ret = s35390a_set_reg(s35390a, S35390A_CMD_STATUS1, &buf, 1);
|
|
+
|
|
+ if (ret < 0)
|
|
+ return ret;
|
|
+
|
|
+ ret = s35390a_get_reg(s35390a, S35390A_CMD_STATUS1, &buf, 1);
|
|
+ if (ret < 0)
|
|
+ return ret;
|
|
+
|
|
+ if (buf & (S35390A_FLAG_POC | S35390A_FLAG_BLD)) {
|
|
+ /* Try up to five times to reset the chip */
|
|
+ if (initcount < 5) {
|
|
+ ++initcount;
|
|
+ goto initialize;
|
|
+ } else
|
|
+ return -EIO;
|
|
+ }
|
|
+
|
|
+ return 1;
|
|
}
|
|
|
|
static int s35390a_disable_test_mode(struct s35390a *s35390a)
|
|
@@ -242,6 +291,8 @@ static int s35390a_set_alarm(struct i2c_client *client, struct rtc_wkalrm *alm)
|
|
|
|
if (alm->time.tm_wday != -1)
|
|
buf[S35390A_ALRM_BYTE_WDAY] = bin2bcd(alm->time.tm_wday) | 0x80;
|
|
+ else
|
|
+ buf[S35390A_ALRM_BYTE_WDAY] = 0;
|
|
|
|
buf[S35390A_ALRM_BYTE_HOURS] = s35390a_hr2reg(s35390a,
|
|
alm->time.tm_hour) | 0x80;
|
|
@@ -265,27 +316,61 @@ static int s35390a_read_alarm(struct i2c_client *client, struct rtc_wkalrm *alm)
|
|
char buf[3], sts;
|
|
int i, err;
|
|
|
|
+ /*
|
|
+ * initialize all members to -1 to signal the core that they are not
|
|
+ * defined by the hardware.
|
|
+ */
|
|
+ alm->time.tm_sec = -1;
|
|
+ alm->time.tm_min = -1;
|
|
+ alm->time.tm_hour = -1;
|
|
+ alm->time.tm_mday = -1;
|
|
+ alm->time.tm_mon = -1;
|
|
+ alm->time.tm_year = -1;
|
|
+ alm->time.tm_wday = -1;
|
|
+ alm->time.tm_yday = -1;
|
|
+ alm->time.tm_isdst = -1;
|
|
+
|
|
err = s35390a_get_reg(s35390a, S35390A_CMD_STATUS2, &sts, sizeof(sts));
|
|
if (err < 0)
|
|
return err;
|
|
|
|
- if (bitrev8(sts) != S35390A_INT2_MODE_ALARM)
|
|
- return -EINVAL;
|
|
+ if ((bitrev8(sts) & S35390A_INT2_MODE_MASK) != S35390A_INT2_MODE_ALARM) {
|
|
+ /*
|
|
+ * When the alarm isn't enabled, the register to configure
|
|
+ * the alarm time isn't accessible.
|
|
+ */
|
|
+ alm->enabled = 0;
|
|
+ return 0;
|
|
+ } else {
|
|
+ alm->enabled = 1;
|
|
+ }
|
|
|
|
err = s35390a_get_reg(s35390a, S35390A_CMD_INT2_REG1, buf, sizeof(buf));
|
|
if (err < 0)
|
|
return err;
|
|
|
|
/* This chip returns the bits of each byte in reverse order */
|
|
- for (i = 0; i < 3; ++i) {
|
|
+ for (i = 0; i < 3; ++i)
|
|
buf[i] = bitrev8(buf[i]);
|
|
- buf[i] &= ~0x80;
|
|
- }
|
|
|
|
- alm->time.tm_wday = bcd2bin(buf[S35390A_ALRM_BYTE_WDAY]);
|
|
- alm->time.tm_hour = s35390a_reg2hr(s35390a,
|
|
- buf[S35390A_ALRM_BYTE_HOURS]);
|
|
- alm->time.tm_min = bcd2bin(buf[S35390A_ALRM_BYTE_MINS]);
|
|
+ /*
|
|
+ * B0 of the three matching registers is an enable flag. Iff it is set
|
|
+ * the configured value is used for matching.
|
|
+ */
|
|
+ if (buf[S35390A_ALRM_BYTE_WDAY] & 0x80)
|
|
+ alm->time.tm_wday =
|
|
+ bcd2bin(buf[S35390A_ALRM_BYTE_WDAY] & ~0x80);
|
|
+
|
|
+ if (buf[S35390A_ALRM_BYTE_HOURS] & 0x80)
|
|
+ alm->time.tm_hour =
|
|
+ s35390a_reg2hr(s35390a,
|
|
+ buf[S35390A_ALRM_BYTE_HOURS] & ~0x80);
|
|
+
|
|
+ if (buf[S35390A_ALRM_BYTE_MINS] & 0x80)
|
|
+ alm->time.tm_min = bcd2bin(buf[S35390A_ALRM_BYTE_MINS] & ~0x80);
|
|
+
|
|
+ /* alarm triggers always at s=0 */
|
|
+ alm->time.tm_sec = 0;
|
|
|
|
dev_dbg(&client->dev, "%s: alm is mins=%d, hours=%d, wday=%d\n",
|
|
__func__, alm->time.tm_min, alm->time.tm_hour,
|
|
@@ -327,11 +412,11 @@ static struct i2c_driver s35390a_driver;
|
|
static int s35390a_probe(struct i2c_client *client,
|
|
const struct i2c_device_id *id)
|
|
{
|
|
- int err;
|
|
+ int err, err_reset;
|
|
unsigned int i;
|
|
struct s35390a *s35390a;
|
|
struct rtc_time tm;
|
|
- char buf[1];
|
|
+ char buf, status1;
|
|
|
|
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
|
|
err = -ENODEV;
|
|
@@ -360,29 +445,35 @@ static int s35390a_probe(struct i2c_client *client,
|
|
}
|
|
}
|
|
|
|
- err = s35390a_reset(s35390a);
|
|
- if (err < 0) {
|
|
+ err_reset = s35390a_reset(s35390a, &status1);
|
|
+ if (err_reset < 0) {
|
|
+ err = err_reset;
|
|
dev_err(&client->dev, "error resetting chip\n");
|
|
goto exit_dummy;
|
|
}
|
|
|
|
- err = s35390a_disable_test_mode(s35390a);
|
|
- if (err < 0) {
|
|
- dev_err(&client->dev, "error disabling test mode\n");
|
|
- goto exit_dummy;
|
|
- }
|
|
-
|
|
- err = s35390a_get_reg(s35390a, S35390A_CMD_STATUS1, buf, sizeof(buf));
|
|
- if (err < 0) {
|
|
- dev_err(&client->dev, "error checking 12/24 hour mode\n");
|
|
- goto exit_dummy;
|
|
- }
|
|
- if (buf[0] & S35390A_FLAG_24H)
|
|
+ if (status1 & S35390A_FLAG_24H)
|
|
s35390a->twentyfourhour = 1;
|
|
else
|
|
s35390a->twentyfourhour = 0;
|
|
|
|
- if (s35390a_get_datetime(client, &tm) < 0)
|
|
+ if (status1 & S35390A_FLAG_INT2) {
|
|
+ /* disable alarm (and maybe test mode) */
|
|
+ buf = 0;
|
|
+ err = s35390a_set_reg(s35390a, S35390A_CMD_STATUS2, &buf, 1);
|
|
+ if (err < 0) {
|
|
+ dev_err(&client->dev, "error disabling alarm");
|
|
+ goto exit_dummy;
|
|
+ }
|
|
+ } else {
|
|
+ err = s35390a_disable_test_mode(s35390a);
|
|
+ if (err < 0) {
|
|
+ dev_err(&client->dev, "error disabling test mode\n");
|
|
+ goto exit_dummy;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (err_reset > 0 || s35390a_get_datetime(client, &tm) < 0)
|
|
dev_warn(&client->dev, "clock needs to be set\n");
|
|
|
|
device_set_wakeup_capable(&client->dev, 1);
|
|
@@ -395,6 +486,10 @@ static int s35390a_probe(struct i2c_client *client,
|
|
err = PTR_ERR(s35390a->rtc);
|
|
goto exit_dummy;
|
|
}
|
|
+
|
|
+ if (status1 & S35390A_FLAG_INT2)
|
|
+ rtc_update_irq(s35390a->rtc, 1, RTC_AF);
|
|
+
|
|
return 0;
|
|
|
|
exit_dummy:
|
|
diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c
|
|
index 9c706d8c1441..6f5e2720ffad 100644
|
|
--- a/drivers/scsi/libsas/sas_ata.c
|
|
+++ b/drivers/scsi/libsas/sas_ata.c
|
|
@@ -218,7 +218,7 @@ static unsigned int sas_ata_qc_issue(struct ata_queued_cmd *qc)
|
|
task->num_scatter = qc->n_elem;
|
|
} else {
|
|
for_each_sg(qc->sg, sg, qc->n_elem, si)
|
|
- xfer += sg->length;
|
|
+ xfer += sg_dma_len(sg);
|
|
|
|
task->total_xfer_len = xfer;
|
|
task->num_scatter = si;
|
|
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h
|
|
index 92648a5ea2d2..63f5965acc89 100644
|
|
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
|
|
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
|
|
@@ -390,6 +390,7 @@ struct MPT3SAS_TARGET {
|
|
* @eedp_enable: eedp support enable bit
|
|
* @eedp_type: 0(type_1), 1(type_2), 2(type_3)
|
|
* @eedp_block_length: block size
|
|
+ * @ata_command_pending: SATL passthrough outstanding for device
|
|
*/
|
|
struct MPT3SAS_DEVICE {
|
|
struct MPT3SAS_TARGET *sas_target;
|
|
@@ -398,6 +399,17 @@ struct MPT3SAS_DEVICE {
|
|
u8 configured_lun;
|
|
u8 block;
|
|
u8 tlr_snoop_check;
|
|
+ /*
|
|
+ * Bug workaround for SATL handling: the mpt2/3sas firmware
|
|
+ * doesn't return BUSY or TASK_SET_FULL for subsequent
|
|
+ * commands while a SATL pass through is in operation as the
|
|
+ * spec requires, it simply does nothing with them until the
|
|
+ * pass through completes, causing them possibly to timeout if
|
|
+ * the passthrough is a long executing command (like format or
|
|
+ * secure erase). This variable allows us to do the right
|
|
+ * thing while a SATL command is pending.
|
|
+ */
|
|
+ unsigned long ata_command_pending;
|
|
};
|
|
|
|
#define MPT3_CMD_NOT_USED 0x8000 /* free */
|
|
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
|
|
index f6a8e9958e75..8a5fbdb45cfd 100644
|
|
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
|
|
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
|
|
@@ -3707,9 +3707,18 @@ _scsih_temp_threshold_events(struct MPT3SAS_ADAPTER *ioc,
|
|
}
|
|
}
|
|
|
|
-static inline bool ata_12_16_cmd(struct scsi_cmnd *scmd)
|
|
+static int _scsih_set_satl_pending(struct scsi_cmnd *scmd, bool pending)
|
|
{
|
|
- return (scmd->cmnd[0] == ATA_12 || scmd->cmnd[0] == ATA_16);
|
|
+ struct MPT3SAS_DEVICE *priv = scmd->device->hostdata;
|
|
+
|
|
+ if (scmd->cmnd[0] != ATA_12 && scmd->cmnd[0] != ATA_16)
|
|
+ return 0;
|
|
+
|
|
+ if (pending)
|
|
+ return test_and_set_bit(0, &priv->ata_command_pending);
|
|
+
|
|
+ clear_bit(0, &priv->ata_command_pending);
|
|
+ return 0;
|
|
}
|
|
|
|
/**
|
|
@@ -3733,9 +3742,7 @@ _scsih_flush_running_cmds(struct MPT3SAS_ADAPTER *ioc)
|
|
if (!scmd)
|
|
continue;
|
|
count++;
|
|
- if (ata_12_16_cmd(scmd))
|
|
- scsi_internal_device_unblock(scmd->device,
|
|
- SDEV_RUNNING);
|
|
+ _scsih_set_satl_pending(scmd, false);
|
|
mpt3sas_base_free_smid(ioc, smid);
|
|
scsi_dma_unmap(scmd);
|
|
if (ioc->pci_error_recovery)
|
|
@@ -3866,13 +3873,6 @@ scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *scmd)
|
|
if (ioc->logging_level & MPT_DEBUG_SCSI)
|
|
scsi_print_command(scmd);
|
|
|
|
- /*
|
|
- * Lock the device for any subsequent command until command is
|
|
- * done.
|
|
- */
|
|
- if (ata_12_16_cmd(scmd))
|
|
- scsi_internal_device_block(scmd->device);
|
|
-
|
|
sas_device_priv_data = scmd->device->hostdata;
|
|
if (!sas_device_priv_data || !sas_device_priv_data->sas_target) {
|
|
scmd->result = DID_NO_CONNECT << 16;
|
|
@@ -3886,6 +3886,19 @@ scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *scmd)
|
|
return 0;
|
|
}
|
|
|
|
+ /*
|
|
+ * Bug work around for firmware SATL handling. The loop
|
|
+ * is based on atomic operations and ensures consistency
|
|
+ * since we're lockless at this point
|
|
+ */
|
|
+ do {
|
|
+ if (test_bit(0, &sas_device_priv_data->ata_command_pending)) {
|
|
+ scmd->result = SAM_STAT_BUSY;
|
|
+ scmd->scsi_done(scmd);
|
|
+ return 0;
|
|
+ }
|
|
+ } while (_scsih_set_satl_pending(scmd, true));
|
|
+
|
|
sas_target_priv_data = sas_device_priv_data->sas_target;
|
|
|
|
/* invalid device handle */
|
|
@@ -4445,8 +4458,7 @@ _scsih_io_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
|
|
if (scmd == NULL)
|
|
return 1;
|
|
|
|
- if (ata_12_16_cmd(scmd))
|
|
- scsi_internal_device_unblock(scmd->device, SDEV_RUNNING);
|
|
+ _scsih_set_satl_pending(scmd, false);
|
|
|
|
mpi_request = mpt3sas_base_get_msg_frame(ioc, smid);
|
|
|
|
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
|
|
index dedcff9cabb5..6514636431ab 100644
|
|
--- a/drivers/scsi/sg.c
|
|
+++ b/drivers/scsi/sg.c
|
|
@@ -1008,6 +1008,8 @@ sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg)
|
|
result = get_user(val, ip);
|
|
if (result)
|
|
return result;
|
|
+ if (val > SG_MAX_CDB_SIZE)
|
|
+ return -ENOMEM;
|
|
sfp->next_cmd_len = (val > 0) ? val : 0;
|
|
return 0;
|
|
case SG_GET_VERSION_NUM:
|
|
diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c
|
|
index a0f911641b04..a15070a7fcd6 100644
|
|
--- a/drivers/tty/serial/atmel_serial.c
|
|
+++ b/drivers/tty/serial/atmel_serial.c
|
|
@@ -1987,6 +1987,11 @@ static void atmel_flush_buffer(struct uart_port *port)
|
|
atmel_uart_writel(port, ATMEL_PDC_TCR, 0);
|
|
atmel_port->pdc_tx.ofs = 0;
|
|
}
|
|
+ /*
|
|
+ * in uart_flush_buffer(), the xmit circular buffer has just
|
|
+ * been cleared, so we have to reset tx_len accordingly.
|
|
+ */
|
|
+ atmel_port->tx_len = 0;
|
|
}
|
|
|
|
/*
|
|
@@ -2499,6 +2504,9 @@ static void atmel_console_write(struct console *co, const char *s, u_int count)
|
|
pdc_tx = atmel_uart_readl(port, ATMEL_PDC_PTSR) & ATMEL_PDC_TXTEN;
|
|
atmel_uart_writel(port, ATMEL_PDC_PTCR, ATMEL_PDC_TXTDIS);
|
|
|
|
+ /* Make sure that tx path is actually able to send characters */
|
|
+ atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_TXEN);
|
|
+
|
|
uart_console_write(port, s, count, atmel_console_putchar);
|
|
|
|
/*
|
|
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
|
|
index 5724d7c41e29..ca2cbdb3aa67 100644
|
|
--- a/drivers/usb/core/hcd.c
|
|
+++ b/drivers/usb/core/hcd.c
|
|
@@ -499,8 +499,10 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb)
|
|
*/
|
|
tbuf_size = max_t(u16, sizeof(struct usb_hub_descriptor), wLength);
|
|
tbuf = kzalloc(tbuf_size, GFP_KERNEL);
|
|
- if (!tbuf)
|
|
- return -ENOMEM;
|
|
+ if (!tbuf) {
|
|
+ status = -ENOMEM;
|
|
+ goto err_alloc;
|
|
+ }
|
|
|
|
bufp = tbuf;
|
|
|
|
@@ -705,6 +707,7 @@ error:
|
|
}
|
|
|
|
kfree(tbuf);
|
|
+ err_alloc:
|
|
|
|
/* any errors get returned through the urb completion */
|
|
spin_lock_irq(&hcd_root_hub_lock);
|
|
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
|
|
index c923350ca20a..d7ce4e3280db 100644
|
|
--- a/include/linux/kvm_host.h
|
|
+++ b/include/linux/kvm_host.h
|
|
@@ -182,8 +182,8 @@ int kvm_io_bus_read(struct kvm_vcpu *vcpu, enum kvm_bus bus_idx, gpa_t addr,
|
|
int len, void *val);
|
|
int kvm_io_bus_register_dev(struct kvm *kvm, enum kvm_bus bus_idx, gpa_t addr,
|
|
int len, struct kvm_io_device *dev);
|
|
-int kvm_io_bus_unregister_dev(struct kvm *kvm, enum kvm_bus bus_idx,
|
|
- struct kvm_io_device *dev);
|
|
+void kvm_io_bus_unregister_dev(struct kvm *kvm, enum kvm_bus bus_idx,
|
|
+ struct kvm_io_device *dev);
|
|
|
|
#ifdef CONFIG_KVM_ASYNC_PF
|
|
struct kvm_async_pf {
|
|
diff --git a/kernel/padata.c b/kernel/padata.c
|
|
index b38bea9c466a..401227e3967c 100644
|
|
--- a/kernel/padata.c
|
|
+++ b/kernel/padata.c
|
|
@@ -189,19 +189,20 @@ static struct padata_priv *padata_get_next(struct parallel_data *pd)
|
|
|
|
reorder = &next_queue->reorder;
|
|
|
|
+ spin_lock(&reorder->lock);
|
|
if (!list_empty(&reorder->list)) {
|
|
padata = list_entry(reorder->list.next,
|
|
struct padata_priv, list);
|
|
|
|
- spin_lock(&reorder->lock);
|
|
list_del_init(&padata->list);
|
|
atomic_dec(&pd->reorder_objects);
|
|
- spin_unlock(&reorder->lock);
|
|
|
|
pd->processed++;
|
|
|
|
+ spin_unlock(&reorder->lock);
|
|
goto out;
|
|
}
|
|
+ spin_unlock(&reorder->lock);
|
|
|
|
if (__this_cpu_read(pd->pqueue->cpu_index) == next_queue->cpu_index) {
|
|
padata = ERR_PTR(-ENODATA);
|
|
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
|
|
index ea11123a9249..7294301d8495 100644
|
|
--- a/mm/hugetlb.c
|
|
+++ b/mm/hugetlb.c
|
|
@@ -4362,6 +4362,7 @@ follow_huge_pmd(struct mm_struct *mm, unsigned long address,
|
|
{
|
|
struct page *page = NULL;
|
|
spinlock_t *ptl;
|
|
+ pte_t pte;
|
|
retry:
|
|
ptl = pmd_lockptr(mm, pmd);
|
|
spin_lock(ptl);
|
|
@@ -4371,12 +4372,13 @@ retry:
|
|
*/
|
|
if (!pmd_huge(*pmd))
|
|
goto out;
|
|
- if (pmd_present(*pmd)) {
|
|
+ pte = huge_ptep_get((pte_t *)pmd);
|
|
+ if (pte_present(pte)) {
|
|
page = pmd_page(*pmd) + ((address & ~PMD_MASK) >> PAGE_SHIFT);
|
|
if (flags & FOLL_GET)
|
|
get_page(page);
|
|
} else {
|
|
- if (is_hugetlb_entry_migration(huge_ptep_get((pte_t *)pmd))) {
|
|
+ if (is_hugetlb_entry_migration(pte)) {
|
|
spin_unlock(ptl);
|
|
__migration_entry_wait(mm, (pte_t *)pmd, ptl);
|
|
goto retry;
|
|
diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c
|
|
index b8d927c56494..a6b2f2138c9d 100644
|
|
--- a/net/ceph/messenger.c
|
|
+++ b/net/ceph/messenger.c
|
|
@@ -7,6 +7,7 @@
|
|
#include <linux/kthread.h>
|
|
#include <linux/net.h>
|
|
#include <linux/nsproxy.h>
|
|
+#include <linux/sched.h>
|
|
#include <linux/slab.h>
|
|
#include <linux/socket.h>
|
|
#include <linux/string.h>
|
|
@@ -478,11 +479,16 @@ static int ceph_tcp_connect(struct ceph_connection *con)
|
|
{
|
|
struct sockaddr_storage *paddr = &con->peer_addr.in_addr;
|
|
struct socket *sock;
|
|
+ unsigned int noio_flag;
|
|
int ret;
|
|
|
|
BUG_ON(con->sock);
|
|
+
|
|
+ /* sock_create_kern() allocates with GFP_KERNEL */
|
|
+ noio_flag = memalloc_noio_save();
|
|
ret = sock_create_kern(read_pnet(&con->msgr->net), paddr->ss_family,
|
|
SOCK_STREAM, IPPROTO_TCP, &sock);
|
|
+ memalloc_noio_restore(noio_flag);
|
|
if (ret)
|
|
return ret;
|
|
sock->sk->sk_allocation = GFP_NOFS;
|
|
diff --git a/sound/core/seq/seq_fifo.c b/sound/core/seq/seq_fifo.c
|
|
index 3f4efcb85df5..3490d21ab9e7 100644
|
|
--- a/sound/core/seq/seq_fifo.c
|
|
+++ b/sound/core/seq/seq_fifo.c
|
|
@@ -265,6 +265,10 @@ int snd_seq_fifo_resize(struct snd_seq_fifo *f, int poolsize)
|
|
/* NOTE: overflow flag is not cleared */
|
|
spin_unlock_irqrestore(&f->lock, flags);
|
|
|
|
+ /* close the old pool and wait until all users are gone */
|
|
+ snd_seq_pool_mark_closing(oldpool);
|
|
+ snd_use_lock_sync(&f->use_lock);
|
|
+
|
|
/* release cells in old pool */
|
|
for (cell = oldhead; cell; cell = next) {
|
|
next = cell->next;
|
|
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
|
|
index 1d4f34379f56..46a34039ecdc 100644
|
|
--- a/sound/pci/hda/patch_realtek.c
|
|
+++ b/sound/pci/hda/patch_realtek.c
|
|
@@ -4831,6 +4831,7 @@ enum {
|
|
ALC292_FIXUP_DISABLE_AAMIX,
|
|
ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK,
|
|
ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
|
|
+ ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE,
|
|
ALC275_FIXUP_DELL_XPS,
|
|
ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE,
|
|
ALC293_FIXUP_LENOVO_SPK_NOISE,
|
|
@@ -5429,6 +5430,15 @@ static const struct hda_fixup alc269_fixups[] = {
|
|
.chained = true,
|
|
.chain_id = ALC269_FIXUP_HEADSET_MODE
|
|
},
|
|
+ [ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE] = {
|
|
+ .type = HDA_FIXUP_PINS,
|
|
+ .v.pins = (const struct hda_pintbl[]) {
|
|
+ { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
|
|
+ { }
|
|
+ },
|
|
+ .chained = true,
|
|
+ .chain_id = ALC269_FIXUP_HEADSET_MODE
|
|
+ },
|
|
[ALC275_FIXUP_DELL_XPS] = {
|
|
.type = HDA_FIXUP_VERBS,
|
|
.v.verbs = (const struct hda_verb[]) {
|
|
@@ -5501,7 +5511,7 @@ static const struct hda_fixup alc269_fixups[] = {
|
|
.type = HDA_FIXUP_FUNC,
|
|
.v.func = alc298_fixup_speaker_volume,
|
|
.chained = true,
|
|
- .chain_id = ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
|
|
+ .chain_id = ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE,
|
|
},
|
|
[ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER] = {
|
|
.type = HDA_FIXUP_PINS,
|
|
diff --git a/sound/soc/atmel/atmel-classd.c b/sound/soc/atmel/atmel-classd.c
|
|
index 8276675730ef..78a985629607 100644
|
|
--- a/sound/soc/atmel/atmel-classd.c
|
|
+++ b/sound/soc/atmel/atmel-classd.c
|
|
@@ -343,7 +343,7 @@ static int atmel_classd_codec_dai_digital_mute(struct snd_soc_dai *codec_dai,
|
|
}
|
|
|
|
#define CLASSD_ACLK_RATE_11M2896_MPY_8 (112896 * 100 * 8)
|
|
-#define CLASSD_ACLK_RATE_12M288_MPY_8 (12228 * 1000 * 8)
|
|
+#define CLASSD_ACLK_RATE_12M288_MPY_8 (12288 * 1000 * 8)
|
|
|
|
static struct {
|
|
int rate;
|
|
diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c
|
|
index 46dbc0a7dfc1..49001fa84ead 100644
|
|
--- a/virt/kvm/eventfd.c
|
|
+++ b/virt/kvm/eventfd.c
|
|
@@ -868,7 +868,8 @@ kvm_deassign_ioeventfd_idx(struct kvm *kvm, enum kvm_bus bus_idx,
|
|
continue;
|
|
|
|
kvm_io_bus_unregister_dev(kvm, bus_idx, &p->dev);
|
|
- kvm->buses[bus_idx]->ioeventfd_count--;
|
|
+ if (kvm->buses[bus_idx])
|
|
+ kvm->buses[bus_idx]->ioeventfd_count--;
|
|
ioeventfd_release(p);
|
|
ret = 0;
|
|
break;
|
|
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
|
|
index 336ed267c407..cb092bd9965b 100644
|
|
--- a/virt/kvm/kvm_main.c
|
|
+++ b/virt/kvm/kvm_main.c
|
|
@@ -654,8 +654,11 @@ static void kvm_destroy_vm(struct kvm *kvm)
|
|
list_del(&kvm->vm_list);
|
|
spin_unlock(&kvm_lock);
|
|
kvm_free_irq_routing(kvm);
|
|
- for (i = 0; i < KVM_NR_BUSES; i++)
|
|
- kvm_io_bus_destroy(kvm->buses[i]);
|
|
+ for (i = 0; i < KVM_NR_BUSES; i++) {
|
|
+ if (kvm->buses[i])
|
|
+ kvm_io_bus_destroy(kvm->buses[i]);
|
|
+ kvm->buses[i] = NULL;
|
|
+ }
|
|
kvm_coalesced_mmio_free(kvm);
|
|
#if defined(CONFIG_MMU_NOTIFIER) && defined(KVM_ARCH_WANT_MMU_NOTIFIER)
|
|
mmu_notifier_unregister(&kvm->mmu_notifier, kvm->mm);
|
|
@@ -3271,6 +3274,8 @@ int kvm_io_bus_write(struct kvm_vcpu *vcpu, enum kvm_bus bus_idx, gpa_t addr,
|
|
};
|
|
|
|
bus = srcu_dereference(vcpu->kvm->buses[bus_idx], &vcpu->kvm->srcu);
|
|
+ if (!bus)
|
|
+ return -ENOMEM;
|
|
r = __kvm_io_bus_write(vcpu, bus, &range, val);
|
|
return r < 0 ? r : 0;
|
|
}
|
|
@@ -3288,6 +3293,8 @@ int kvm_io_bus_write_cookie(struct kvm_vcpu *vcpu, enum kvm_bus bus_idx,
|
|
};
|
|
|
|
bus = srcu_dereference(vcpu->kvm->buses[bus_idx], &vcpu->kvm->srcu);
|
|
+ if (!bus)
|
|
+ return -ENOMEM;
|
|
|
|
/* First try the device referenced by cookie. */
|
|
if ((cookie >= 0) && (cookie < bus->dev_count) &&
|
|
@@ -3338,6 +3345,8 @@ int kvm_io_bus_read(struct kvm_vcpu *vcpu, enum kvm_bus bus_idx, gpa_t addr,
|
|
};
|
|
|
|
bus = srcu_dereference(vcpu->kvm->buses[bus_idx], &vcpu->kvm->srcu);
|
|
+ if (!bus)
|
|
+ return -ENOMEM;
|
|
r = __kvm_io_bus_read(vcpu, bus, &range, val);
|
|
return r < 0 ? r : 0;
|
|
}
|
|
@@ -3350,6 +3359,9 @@ int kvm_io_bus_register_dev(struct kvm *kvm, enum kvm_bus bus_idx, gpa_t addr,
|
|
struct kvm_io_bus *new_bus, *bus;
|
|
|
|
bus = kvm->buses[bus_idx];
|
|
+ if (!bus)
|
|
+ return -ENOMEM;
|
|
+
|
|
/* exclude ioeventfd which is limited by maximum fd */
|
|
if (bus->dev_count - bus->ioeventfd_count > NR_IOBUS_DEVS - 1)
|
|
return -ENOSPC;
|
|
@@ -3369,37 +3381,41 @@ int kvm_io_bus_register_dev(struct kvm *kvm, enum kvm_bus bus_idx, gpa_t addr,
|
|
}
|
|
|
|
/* Caller must hold slots_lock. */
|
|
-int kvm_io_bus_unregister_dev(struct kvm *kvm, enum kvm_bus bus_idx,
|
|
- struct kvm_io_device *dev)
|
|
+void kvm_io_bus_unregister_dev(struct kvm *kvm, enum kvm_bus bus_idx,
|
|
+ struct kvm_io_device *dev)
|
|
{
|
|
- int i, r;
|
|
+ int i;
|
|
struct kvm_io_bus *new_bus, *bus;
|
|
|
|
bus = kvm->buses[bus_idx];
|
|
- r = -ENOENT;
|
|
+ if (!bus)
|
|
+ return;
|
|
+
|
|
for (i = 0; i < bus->dev_count; i++)
|
|
if (bus->range[i].dev == dev) {
|
|
- r = 0;
|
|
break;
|
|
}
|
|
|
|
- if (r)
|
|
- return r;
|
|
+ if (i == bus->dev_count)
|
|
+ return;
|
|
|
|
new_bus = kmalloc(sizeof(*bus) + ((bus->dev_count - 1) *
|
|
sizeof(struct kvm_io_range)), GFP_KERNEL);
|
|
- if (!new_bus)
|
|
- return -ENOMEM;
|
|
+ if (!new_bus) {
|
|
+ pr_err("kvm: failed to shrink bus, removing it completely\n");
|
|
+ goto broken;
|
|
+ }
|
|
|
|
memcpy(new_bus, bus, sizeof(*bus) + i * sizeof(struct kvm_io_range));
|
|
new_bus->dev_count--;
|
|
memcpy(new_bus->range + i, bus->range + i + 1,
|
|
(new_bus->dev_count - i) * sizeof(struct kvm_io_range));
|
|
|
|
+broken:
|
|
rcu_assign_pointer(kvm->buses[bus_idx], new_bus);
|
|
synchronize_srcu_expedited(&kvm->srcu);
|
|
kfree(bus);
|
|
- return r;
|
|
+ return;
|
|
}
|
|
|
|
static struct notifier_block kvm_cpu_notifier = {
|