From: Greg Kroah-Hartman Date: Thu, 6 Apr 2017 07:45:36 +0000 (+0200) Subject: 4.4-stable patches X-Git-Tag: v4.9.21~7 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=92e2fcebadff48906a6e4b92af8468009a1bebad;p=thirdparty%2Fkernel%2Fstable-queue.git 4.4-stable patches added patches: blk-ensure-users-for-current-bio_list-can-see-the-full-list.patch blk-improve-order-of-bio-handling-in-generic_make_request.patch kvm-kvm_io_bus_unregister_dev-should-never-fail.patch mips-lantiq-fix-cascaded-irq-setup.patch power-reset-at91-poweroff-timely-shutdown-lpddr-memories.patch rtc-s35390a-fix-reading-out-alarm.patch rtc-s35390a-implement-reset-routine-as-suggested-by-the-reference.patch rtc-s35390a-improve-irq-handling.patch rtc-s35390a-make-sure-all-members-in-the-output-are-set.patch --- diff --git a/queue-4.4/blk-ensure-users-for-current-bio_list-can-see-the-full-list.patch b/queue-4.4/blk-ensure-users-for-current-bio_list-can-see-the-full-list.patch new file mode 100644 index 00000000000..520ab47ab4a --- /dev/null +++ b/queue-4.4/blk-ensure-users-for-current-bio_list-can-see-the-full-list.patch @@ -0,0 +1,164 @@ +From f5fe1b51905df7cfe4fdfd85c5fb7bc5b71a094f Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Fri, 10 Mar 2017 17:00:47 +1100 +Subject: blk: Ensure users for current->bio_list can see the full list. + +From: NeilBrown + +commit f5fe1b51905df7cfe4fdfd85c5fb7bc5b71a094f upstream. + +Commit 79bd99596b73 ("blk: improve order of bio handling in generic_make_request()") +changed current->bio_list so that it did not contain *all* of the +queued bios, but only those submitted by the currently running +make_request_fn. + +There are two places which walk the list and requeue selected bios, +and others that check if the list is empty. These are no longer +correct. + +So redefine current->bio_list to point to an array of two lists, which +contain all queued bios, and adjust various code to test or walk both +lists. + +Signed-off-by: NeilBrown +Fixes: 79bd99596b73 ("blk: improve order of bio handling in generic_make_request()") +Signed-off-by: Jens Axboe +[jwang: backport to 4.4] +Signed-off-by: Jack Wang +Signed-off-by: Greg Kroah-Hartman +--- + block/bio.c | 12 +++++++++--- + block/blk-core.c | 31 +++++++++++++++++++------------ + drivers/md/raid1.c | 3 ++- + drivers/md/raid10.c | 3 ++- + 4 files changed, 32 insertions(+), 17 deletions(-) + +--- a/block/bio.c ++++ b/block/bio.c +@@ -373,10 +373,14 @@ static void punt_bios_to_rescuer(struct + 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_m + * 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); +--- 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 + * 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,17 +2064,17 @@ blk_qc_t generic_make_request(struct 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, hold; ++ struct bio_list lower, same; + + /* Create a fresh bio_list for all subordinate requests */ +- hold = bio_list_on_stack; +- bio_list_init(&bio_list_on_stack); ++ 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); + +@@ -2077,19 +2084,19 @@ blk_qc_t generic_make_request(struct bio + */ + bio_list_init(&lower); + bio_list_init(&same); +- while ((bio = bio_list_pop(&bio_list_on_stack)) != NULL) ++ 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, &lower); +- bio_list_merge(&bio_list_on_stack, &same); +- bio_list_merge(&bio_list_on_stack, &hold); ++ 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 { + bio_io_error(bio); + } +- bio = bio_list_pop(current->bio_list); ++ bio = bio_list_pop(&bio_list_on_stack[0]); + } while (bio); + current->bio_list = NULL; /* deactivate */ + +--- a/drivers/md/raid1.c ++++ b/drivers/md/raid1.c +@@ -877,7 +877,8 @@ static sector_t wait_barrier(struct r1co + ((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--; + } +--- a/drivers/md/raid10.c ++++ b/drivers/md/raid10.c +@@ -946,7 +946,8 @@ static void wait_barrier(struct r10conf + !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/queue-4.4/blk-improve-order-of-bio-handling-in-generic_make_request.patch b/queue-4.4/blk-improve-order-of-bio-handling-in-generic_make_request.patch new file mode 100644 index 00000000000..30745c295a6 --- /dev/null +++ b/queue-4.4/blk-improve-order-of-bio-handling-in-generic_make_request.patch @@ -0,0 +1,118 @@ +From 79bd99596b7305ab08109a8bf44a6a4511dbf1cd Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Wed, 8 Mar 2017 07:38:05 +1100 +Subject: blk: improve order of bio handling in generic_make_request() + +From: NeilBrown + +commit 79bd99596b7305ab08109a8bf44a6a4511dbf1cd upstream. + +To avoid recursion on the kernel stack when stacked block devices +are in use, generic_make_request() will, when called recursively, +queue new requests for later handling. They will be handled when the +make_request_fn for the current bio completes. + +If any bios are submitted by a make_request_fn, these will ultimately +be handled seqeuntially. If the handling of one of those generates +further requests, they will be added to the end of the queue. + +This strict first-in-first-out behaviour can lead to deadlocks in +various ways, normally because a request might need to wait for a +previous request to the same device to complete. This can happen when +they share a mempool, and can happen due to interdependencies +particular to the device. Both md and dm have examples where this happens. + +These deadlocks can be erradicated by more selective ordering of bios. +Specifically by handling them in depth-first order. That is: when the +handling of one bio generates one or more further bios, they are +handled immediately after the parent, before any siblings of the +parent. That way, when generic_make_request() calls make_request_fn +for some particular device, we can be certain that all previously +submited requests for that device have been completely handled and are +not waiting for anything in the queue of requests maintained in +generic_make_request(). + +An easy way to achieve this would be to use a last-in-first-out stack +instead of a queue. However this will change the order of consecutive +bios submitted by a make_request_fn, which could have unexpected consequences. +Instead we take a slightly more complex approach. +A fresh queue is created for each call to a make_request_fn. After it completes, +any bios for a different device are placed on the front of the main queue, followed +by any bios for the same device, followed by all bios that were already on +the queue before the make_request_fn was called. +This provides the depth-first approach without reordering bios on the same level. + +This, by itself, it not enough to remove all deadlocks. It just makes +it possible for drivers to take the extra step required themselves. + +To avoid deadlocks, drivers must never risk waiting for a request +after submitting one to generic_make_request. This includes never +allocing from a mempool twice in the one call to a make_request_fn. + +A common pattern in drivers is to call bio_split() in a loop, handling +the first part and then looping around to possibly split the next part. +Instead, a driver that finds it needs to split a bio should queue +(with generic_make_request) the second part, handle the first part, +and then return. The new code in generic_make_request will ensure the +requests to underlying bios are processed first, then the second bio +that was split off. If it splits again, the same process happens. In +each case one bio will be completely handled before the next one is attempted. + +With this is place, it should be possible to disable the +punt_bios_to_recover() recovery thread for many block devices, and +eventually it may be possible to remove it completely. + +Ref: http://www.spinics.net/lists/raid/msg54680.html +Tested-by: Jinpu Wang +Inspired-by: Lars Ellenberg +Signed-off-by: NeilBrown +Signed-off-by: Jens Axboe +[jwang: backport to 4.4] +Signed-off-by: Jack Wang +Signed-off-by: Greg Kroah-Hartman + +--- + block/blk-core.c | 25 ++++++++++++++++++++----- + 1 file changed, 20 insertions(+), 5 deletions(-) + +--- a/block/blk-core.c ++++ b/block/blk-core.c +@@ -2063,18 +2063,33 @@ blk_qc_t generic_make_request(struct bio + 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, hold; ++ ++ /* Create a fresh bio_list for all subordinate requests */ ++ hold = bio_list_on_stack; ++ bio_list_init(&bio_list_on_stack); + + 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)) != 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, &lower); ++ bio_list_merge(&bio_list_on_stack, &same); ++ bio_list_merge(&bio_list_on_stack, &hold); + } else { +- struct bio *bio_next = bio_list_pop(current->bio_list); +- + bio_io_error(bio); +- bio = bio_next; + } ++ bio = bio_list_pop(current->bio_list); + } while (bio); + current->bio_list = NULL; /* deactivate */ + diff --git a/queue-4.4/kvm-kvm_io_bus_unregister_dev-should-never-fail.patch b/queue-4.4/kvm-kvm_io_bus_unregister_dev-should-never-fail.patch new file mode 100644 index 00000000000..6f13b3601db --- /dev/null +++ b/queue-4.4/kvm-kvm_io_bus_unregister_dev-should-never-fail.patch @@ -0,0 +1,167 @@ +From 90db10434b163e46da413d34db8d0e77404cc645 Mon Sep 17 00:00:00 2001 +From: David Hildenbrand +Date: Thu, 23 Mar 2017 18:24:19 +0100 +Subject: KVM: kvm_io_bus_unregister_dev() should never fail + +From: David Hildenbrand + +commit 90db10434b163e46da413d34db8d0e77404cc645 upstream. + +No caller currently checks the return value of +kvm_io_bus_unregister_dev(). This is evil, as all callers silently go on +freeing their device. A stale reference will remain in the io_bus, +getting at least used again, when the iobus gets teared down on +kvm_destroy_vm() - leading to use after free errors. + +There is nothing the callers could do, except retrying over and over +again. + +So let's simply remove the bus altogether, print an error and make +sure no one can access this broken bus again (returning -ENOMEM on any +attempt to access it). + +Fixes: e93f8a0f821e ("KVM: convert io_bus to SRCU") +Reported-by: Dmitry Vyukov +Reviewed-by: Cornelia Huck +Signed-off-by: David Hildenbrand +Signed-off-by: Paolo Bonzini +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/kvm_host.h | 4 ++-- + virt/kvm/eventfd.c | 3 ++- + virt/kvm/kvm_main.c | 40 +++++++++++++++++++++++----------------- + 3 files changed, 27 insertions(+), 20 deletions(-) + +--- a/include/linux/kvm_host.h ++++ b/include/linux/kvm_host.h +@@ -182,8 +182,8 @@ int kvm_io_bus_read(struct kvm_vcpu *vcp + 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 { +--- a/virt/kvm/eventfd.c ++++ b/virt/kvm/eventfd.c +@@ -868,7 +868,8 @@ kvm_deassign_ioeventfd_idx(struct kvm *k + 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; +--- a/virt/kvm/kvm_main.c ++++ b/virt/kvm/kvm_main.c +@@ -655,7 +655,8 @@ static void kvm_destroy_vm(struct kvm *k + spin_unlock(&kvm_lock); + kvm_free_irq_routing(kvm); + for (i = 0; i < KVM_NR_BUSES; i++) { +- kvm_io_bus_destroy(kvm->buses[i]); ++ if (kvm->buses[i]) ++ kvm_io_bus_destroy(kvm->buses[i]); + kvm->buses[i] = NULL; + } + kvm_coalesced_mmio_free(kvm); +@@ -3273,6 +3274,8 @@ int kvm_io_bus_write(struct kvm_vcpu *vc + }; + + 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; + } +@@ -3290,6 +3293,8 @@ int kvm_io_bus_write_cookie(struct kvm_v + }; + + 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) && +@@ -3340,6 +3345,8 @@ int kvm_io_bus_read(struct kvm_vcpu *vcp + }; + + 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; + } +@@ -3352,6 +3359,9 @@ int kvm_io_bus_register_dev(struct kvm * + 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; +@@ -3371,45 +3381,41 @@ int kvm_io_bus_register_dev(struct kvm * + } + + /* 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]; +- +- /* +- * It's possible the bus being released before hand. If so, +- * we're done here. +- */ + if (!bus) +- return 0; ++ return; + +- r = -ENOENT; + 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 = { diff --git a/queue-4.4/mips-lantiq-fix-cascaded-irq-setup.patch b/queue-4.4/mips-lantiq-fix-cascaded-irq-setup.patch new file mode 100644 index 00000000000..424efb3f294 --- /dev/null +++ b/queue-4.4/mips-lantiq-fix-cascaded-irq-setup.patch @@ -0,0 +1,104 @@ +From 6c356eda225e3ee134ed4176b9ae3a76f793f4dd Mon Sep 17 00:00:00 2001 +From: Felix Fietkau +Date: Thu, 19 Jan 2017 12:28:22 +0100 +Subject: MIPS: Lantiq: Fix cascaded IRQ setup + +From: Felix Fietkau + +commit 6c356eda225e3ee134ed4176b9ae3a76f793f4dd upstream. + +With the IRQ stack changes integrated, the XRX200 devices started +emitting a constant stream of kernel messages like this: + +[ 565.415310] Spurious IRQ: CAUSE=0x1100c300 + +This is caused by IP0 getting handled by plat_irq_dispatch() rather than +its vectored interrupt handler, which is fixed by commit de856416e714 +("MIPS: IRQ Stack: Fix erroneous jal to plat_irq_dispatch"). + +Fix plat_irq_dispatch() to handle non-vectored IPI interrupts correctly +by setting up IP2-6 as proper chained IRQ handlers and calling do_IRQ +for all MIPS CPU interrupts. + +Signed-off-by: Felix Fietkau +Acked-by: John Crispin +Cc: linux-mips@linux-mips.org +Patchwork: https://patchwork.linux-mips.org/patch/15077/ +[james.hogan@imgtec.com: tweaked commit message] +Signed-off-by: James Hogan +Signed-off-by: Amit Pundir +Signed-off-by: Greg Kroah-Hartman + +--- + arch/mips/lantiq/irq.c | 36 ++++++++++++++++-------------------- + 1 file changed, 16 insertions(+), 20 deletions(-) + +--- 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; ++ int irq; + +- 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; +- } +- } ++ 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_d + .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_nod + 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/queue-4.4/power-reset-at91-poweroff-timely-shutdown-lpddr-memories.patch b/queue-4.4/power-reset-at91-poweroff-timely-shutdown-lpddr-memories.patch new file mode 100644 index 00000000000..f3f683f68d6 --- /dev/null +++ b/queue-4.4/power-reset-at91-poweroff-timely-shutdown-lpddr-memories.patch @@ -0,0 +1,126 @@ +From 0b0408745e7ff24757cbfd571d69026c0ddb803c Mon Sep 17 00:00:00 2001 +From: Alexandre Belloni +Date: Tue, 25 Oct 2016 11:37:59 +0200 +Subject: power: reset: at91-poweroff: timely shutdown LPDDR memories + +From: Alexandre Belloni + +commit 0b0408745e7ff24757cbfd571d69026c0ddb803c upstream. + +LPDDR memories can only handle up to 400 uncontrolled power off. Ensure the +proper power off sequence is used before shutting down the platform. + +Signed-off-by: Alexandre Belloni +Signed-off-by: Sebastian Reichel +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/power/reset/at91-poweroff.c | 54 +++++++++++++++++++++++++++++++++++- + 1 file changed, 53 insertions(+), 1 deletion(-) + +--- a/drivers/power/reset/at91-poweroff.c ++++ b/drivers/power/reset/at91-poweroff.c +@@ -14,9 +14,12 @@ + #include + #include + #include ++#include + #include + #include + ++#include ++ + #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_ + 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(st + + 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(s + 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/queue-4.4/rtc-s35390a-fix-reading-out-alarm.patch b/queue-4.4/rtc-s35390a-fix-reading-out-alarm.patch new file mode 100644 index 00000000000..dfb76a5779c --- /dev/null +++ b/queue-4.4/rtc-s35390a-fix-reading-out-alarm.patch @@ -0,0 +1,98 @@ +From f87e904ddd8f0ef120e46045b0addeb1cc88354e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= +Date: Sat, 2 Jul 2016 17:28:08 +0200 +Subject: rtc: s35390a: fix reading out alarm +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Uwe Kleine-König + +commit f87e904ddd8f0ef120e46045b0addeb1cc88354e upstream. + +There are several issues fixed in this patch: + + - When alarm isn't enabled, set .enabled to zero instead of returning + -EINVAL. + - Ignore how IRQ1 is configured when determining if IRQ2 is on. + - The three alarm registers have an enable flag which must be + evaluated. + - The chip always triggers when the seconds register gets 0. + +Note that the rtc framework however doesn't handle the result correctly +because it doesn't check wday being initialized and so interprets an +alarm being set for 10:00 AM in three days as 10:00 AM tomorrow (or +today if that's not over yet). + +Signed-off-by: Uwe Kleine-König +Signed-off-by: Alexandre Belloni +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/rtc/rtc-s35390a.c | 40 +++++++++++++++++++++++++++++++--------- + 1 file changed, 31 insertions(+), 9 deletions(-) + +--- a/drivers/rtc/rtc-s35390a.c ++++ b/drivers/rtc/rtc-s35390a.c +@@ -242,6 +242,8 @@ static int s35390a_set_alarm(struct i2c_ + + 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; +@@ -269,23 +271,43 @@ static int s35390a_read_alarm(struct i2c + 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, diff --git a/queue-4.4/rtc-s35390a-implement-reset-routine-as-suggested-by-the-reference.patch b/queue-4.4/rtc-s35390a-implement-reset-routine-as-suggested-by-the-reference.patch new file mode 100644 index 00000000000..c2822f14117 --- /dev/null +++ b/queue-4.4/rtc-s35390a-implement-reset-routine-as-suggested-by-the-reference.patch @@ -0,0 +1,133 @@ +From 8e6583f1b5d1f5f129b873f1428b7e414263d847 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= +Date: Sat, 2 Jul 2016 17:28:09 +0200 +Subject: rtc: s35390a: implement reset routine as suggested by the reference +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Uwe Kleine-König + +commit 8e6583f1b5d1f5f129b873f1428b7e414263d847 upstream. + +There were two deviations from the reference manual: you have to wait +half a second when POC is active and you might have to repeat +initialization when POC or BLD are still set after the sequence. + +Note however that as POC and BLD are cleared by read the driver might +not be able to detect that a reset is necessary. I don't have a good +idea how to fix this. + +Additionally report the value read from STATUS1 to the caller. This +prepares the next patch. + +Signed-off-by: Uwe Kleine-König +Signed-off-by: Alexandre Belloni +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/rtc/rtc-s35390a.c | 69 ++++++++++++++++++++++++++++++++++++++-------- + 1 file changed, 57 insertions(+), 12 deletions(-) + +--- a/drivers/rtc/rtc-s35390a.c ++++ b/drivers/rtc/rtc-s35390a.c +@@ -15,6 +15,7 @@ + #include + #include + #include ++#include + + #define S35390A_CMD_STATUS1 0 + #define S35390A_CMD_STATUS2 1 +@@ -94,19 +95,63 @@ static int s35390a_get_reg(struct s35390 + return 0; + } + +-static int s35390a_reset(struct s35390a *s35390a) +-{ +- char buf[1]; +- +- if (s35390a_get_reg(s35390a, S35390A_CMD_STATUS1, buf, sizeof(buf)) < 0) +- return -EIO; ++/* ++ * 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; ++ int ret; ++ unsigned initcount = 0; ++ ++ ret = s35390a_get_reg(s35390a, S35390A_CMD_STATUS1, status1, 1); ++ if (ret < 0) ++ return ret; + +- if (!(buf[0] & (S35390A_FLAG_POC | S35390A_FLAG_BLD))) ++ 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) +@@ -367,7 +412,7 @@ static int s35390a_probe(struct i2c_clie + unsigned int i; + struct s35390a *s35390a; + struct rtc_time tm; +- char buf[1]; ++ char buf[1], status1; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { + err = -ENODEV; +@@ -396,7 +441,7 @@ static int s35390a_probe(struct i2c_clie + } + } + +- err = s35390a_reset(s35390a); ++ err = s35390a_reset(s35390a, &status1); + if (err < 0) { + dev_err(&client->dev, "error resetting chip\n"); + goto exit_dummy; diff --git a/queue-4.4/rtc-s35390a-improve-irq-handling.patch b/queue-4.4/rtc-s35390a-improve-irq-handling.patch new file mode 100644 index 00000000000..feb479a0797 --- /dev/null +++ b/queue-4.4/rtc-s35390a-improve-irq-handling.patch @@ -0,0 +1,127 @@ +From 3bd32722c827d00eafe8e6d5b83e9f3148ea7c7e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= +Date: Sat, 2 Jul 2016 17:28:10 +0200 +Subject: rtc: s35390a: improve irq handling +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Uwe Kleine-König + +commit 3bd32722c827d00eafe8e6d5b83e9f3148ea7c7e upstream. + +On some QNAP NAS devices the rtc can wake the machine. Several people +noticed that once the machine was woken this way it fails to shut down. +That's because the driver fails to acknowledge the interrupt and so it +keeps active and restarts the machine immediatly after shutdown. See +https://bugs.debian.org/794266 for a bug report. + +Doing this correctly requires to interpret the INT2 flag of the first read +of the STATUS1 register because this bit is cleared by read. + +Note this is not maximally robust though because a pending irq isn't +detected when the STATUS1 register was already read (and so INT2 is not +set) but the irq was not disabled. But that is a hardware imposed problem +that cannot easily be fixed by software. + +Signed-off-by: Uwe Kleine-König +Signed-off-by: Alexandre Belloni +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/rtc/rtc-s35390a.c | 48 +++++++++++++++++++++++++++++----------------- + 1 file changed, 31 insertions(+), 17 deletions(-) + +--- a/drivers/rtc/rtc-s35390a.c ++++ b/drivers/rtc/rtc-s35390a.c +@@ -35,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 +@@ -408,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], status1; ++ char buf, status1; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { + err = -ENODEV; +@@ -441,29 +445,35 @@ static int s35390a_probe(struct i2c_clie + } + } + +- err = s35390a_reset(s35390a, &status1); +- 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); +@@ -476,6 +486,10 @@ static int s35390a_probe(struct i2c_clie + 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/queue-4.4/rtc-s35390a-make-sure-all-members-in-the-output-are-set.patch b/queue-4.4/rtc-s35390a-make-sure-all-members-in-the-output-are-set.patch new file mode 100644 index 00000000000..9f73ef1eda7 --- /dev/null +++ b/queue-4.4/rtc-s35390a-make-sure-all-members-in-the-output-are-set.patch @@ -0,0 +1,51 @@ +From uwe@kleine-koenig.org Thu Apr 6 09:35:55 2017 +From: Uwe Kleine-König +Date: Mon, 3 Apr 2017 23:32:38 +0200 +Subject: rtc: s35390a: make sure all members in the output are set +To: stable@vger.kernel.org +Cc: Martin Michlmayr , peter , Alexandre Belloni , debian-kernel@lists.debian.org +Message-ID: <20170403213240.3856-3-uwe@kleine-koenig.org> + +From: Uwe Kleine-König + +The rtc core calls the .read_alarm with all fields initialized to 0. As +the s35390a driver doesn't touch some fields the returned date is +interpreted as a date in January 1900. So make sure all fields are set +to -1; some of them are then overwritten with the right data depending +on the hardware state. + +In mainline this is done by commit d68778b80dd7 ("rtc: initialize output +parameter for read alarm to "uninitialized"") in the core. This is +considered to dangerous for stable as it might have side effects for +other rtc drivers that might for example rely on alarm->time.tm_sec +being initialized to 0. + +Signed-off-by: Uwe Kleine-König +Signed-off-by: Greg Kroah-Hartman +--- + drivers/rtc/rtc-s35390a.c | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +--- a/drivers/rtc/rtc-s35390a.c ++++ b/drivers/rtc/rtc-s35390a.c +@@ -267,6 +267,20 @@ static int s35390a_read_alarm(struct i2c + 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; diff --git a/queue-4.4/series b/queue-4.4/series index dbe3d4f5d77..5b041565e9e 100644 --- a/queue-4.4/series +++ b/queue-4.4/series @@ -14,3 +14,12 @@ usb-fix-linked-list-corruption-in-rh_call_control.patch kvm-x86-clear-bus-pointer-when-destroyed.patch drm-radeon-override-fpfn-for-all-vram-placements-in-radeon_evict_flags.patch mm-hugetlb-use-pte_present-instead-of-pmd_present-in-follow_huge_pmd.patch +mips-lantiq-fix-cascaded-irq-setup.patch +rtc-s35390a-fix-reading-out-alarm.patch +rtc-s35390a-make-sure-all-members-in-the-output-are-set.patch +rtc-s35390a-implement-reset-routine-as-suggested-by-the-reference.patch +rtc-s35390a-improve-irq-handling.patch +kvm-kvm_io_bus_unregister_dev-should-never-fail.patch +power-reset-at91-poweroff-timely-shutdown-lpddr-memories.patch +blk-improve-order-of-bio-handling-in-generic_make_request.patch +blk-ensure-users-for-current-bio_list-can-see-the-full-list.patch