From: Sasha Levin Date: Tue, 18 Feb 2020 18:17:21 +0000 (-0500) Subject: fixes for 5.4 X-Git-Tag: v4.19.105~6 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c9cf24f379c07d5f55b6385fd51574587b4d2d97;p=thirdparty%2Fkernel%2Fstable-queue.git fixes for 5.4 Signed-off-by: Sasha Levin --- diff --git a/queue-5.4/ext4-choose-hardlimit-when-softlimit-is-larger-than-.patch b/queue-5.4/ext4-choose-hardlimit-when-softlimit-is-larger-than-.patch new file mode 100644 index 00000000000..ea0c6b70e60 --- /dev/null +++ b/queue-5.4/ext4-choose-hardlimit-when-softlimit-is-larger-than-.patch @@ -0,0 +1,96 @@ +From d3797aa162a00f8cf1c65c714d9dd26489310cd7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 16 Oct 2019 10:25:01 +0800 +Subject: ext4: choose hardlimit when softlimit is larger than hardlimit in + ext4_statfs_project() + +From: Chengguang Xu + +[ Upstream commit 57c32ea42f8e802bda47010418e25043e0c9337f ] + +Setting softlimit larger than hardlimit seems meaningless +for disk quota but currently it is allowed. In this case, +there may be a bit of comfusion for users when they run +df comamnd to directory which has project quota. + +For example, we set 20M softlimit and 10M hardlimit of +block usage limit for project quota of test_dir(project id 123). + +[root@hades mnt_ext4]# repquota -P -a +*** Report for project quotas on device /dev/loop0 +Block grace time: 7days; Inode grace time: 7days + Block limits File limits +Project used soft hard grace used soft hard grace +---------------------------------------------------------------------- + 0 -- 13 0 0 2 0 0 + 123 -- 10237 20480 10240 5 200 100 + +The result of df command as below: + +[root@hades mnt_ext4]# df -h test_dir +Filesystem Size Used Avail Use% Mounted on +/dev/loop0 20M 10M 10M 50% /home/cgxu/test/mnt_ext4 + +Even though it looks like there is another 10M free space to use, +if we write new data to diretory test_dir(inherit project id), +the write will fail with errno(-EDQUOT). + +After this patch, the df result looks like below. + +[root@hades mnt_ext4]# df -h test_dir +Filesystem Size Used Avail Use% Mounted on +/dev/loop0 10M 10M 3.0K 100% /home/cgxu/test/mnt_ext4 + +Signed-off-by: Chengguang Xu +Reviewed-by: Jan Kara +Link: https://lore.kernel.org/r/20191016022501.760-1-cgxu519@mykernel.net +Signed-off-by: Theodore Ts'o +Signed-off-by: Sasha Levin +--- + fs/ext4/super.c | 23 +++++++++++++++++------ + 1 file changed, 17 insertions(+), 6 deletions(-) + +diff --git a/fs/ext4/super.c b/fs/ext4/super.c +index 95826bde9025b..914230e630544 100644 +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -5540,9 +5540,15 @@ static int ext4_statfs_project(struct super_block *sb, + return PTR_ERR(dquot); + spin_lock(&dquot->dq_dqb_lock); + +- limit = (dquot->dq_dqb.dqb_bsoftlimit ? +- dquot->dq_dqb.dqb_bsoftlimit : +- dquot->dq_dqb.dqb_bhardlimit) >> sb->s_blocksize_bits; ++ limit = 0; ++ if (dquot->dq_dqb.dqb_bsoftlimit && ++ (!limit || dquot->dq_dqb.dqb_bsoftlimit < limit)) ++ limit = dquot->dq_dqb.dqb_bsoftlimit; ++ if (dquot->dq_dqb.dqb_bhardlimit && ++ (!limit || dquot->dq_dqb.dqb_bhardlimit < limit)) ++ limit = dquot->dq_dqb.dqb_bhardlimit; ++ limit >>= sb->s_blocksize_bits; ++ + if (limit && buf->f_blocks > limit) { + curblock = (dquot->dq_dqb.dqb_curspace + + dquot->dq_dqb.dqb_rsvspace) >> sb->s_blocksize_bits; +@@ -5552,9 +5558,14 @@ static int ext4_statfs_project(struct super_block *sb, + (buf->f_blocks - curblock) : 0; + } + +- limit = dquot->dq_dqb.dqb_isoftlimit ? +- dquot->dq_dqb.dqb_isoftlimit : +- dquot->dq_dqb.dqb_ihardlimit; ++ limit = 0; ++ if (dquot->dq_dqb.dqb_isoftlimit && ++ (!limit || dquot->dq_dqb.dqb_isoftlimit < limit)) ++ limit = dquot->dq_dqb.dqb_isoftlimit; ++ if (dquot->dq_dqb.dqb_ihardlimit && ++ (!limit || dquot->dq_dqb.dqb_ihardlimit < limit)) ++ limit = dquot->dq_dqb.dqb_ihardlimit; ++ + if (limit && buf->f_files > limit) { + buf->f_files = limit; + buf->f_ffree = +-- +2.20.1 + diff --git a/queue-5.4/ext4-simplify-checking-quota-limits-in-ext4_statfs.patch b/queue-5.4/ext4-simplify-checking-quota-limits-in-ext4_statfs.patch new file mode 100644 index 00000000000..da6f5d9b869 --- /dev/null +++ b/queue-5.4/ext4-simplify-checking-quota-limits-in-ext4_statfs.patch @@ -0,0 +1,54 @@ +From c8a2e05d5eb251c73fac79569cabd68cb1348fd8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 30 Jan 2020 12:11:48 +0100 +Subject: ext4: simplify checking quota limits in ext4_statfs() + +From: Jan Kara + +[ Upstream commit 46d36880d1c6f9b9a0cbaf90235355ea1f4cab96 ] + +Coverity reports that conditions checking quota limits in ext4_statfs() +contain dead code. Indeed it is right and current conditions can be +simplified. + +Link: https://lore.kernel.org/r/20200130111148.10766-1-jack@suse.cz +Reported-by: Coverity +Signed-off-by: Jan Kara +Signed-off-by: Theodore Ts'o +Cc: stable@kernel.org +Signed-off-by: Sasha Levin +--- + fs/ext4/super.c | 10 ++-------- + 1 file changed, 2 insertions(+), 8 deletions(-) + +diff --git a/fs/ext4/super.c b/fs/ext4/super.c +index 914230e630544..c7a037db49326 100644 +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -5540,10 +5540,7 @@ static int ext4_statfs_project(struct super_block *sb, + return PTR_ERR(dquot); + spin_lock(&dquot->dq_dqb_lock); + +- limit = 0; +- if (dquot->dq_dqb.dqb_bsoftlimit && +- (!limit || dquot->dq_dqb.dqb_bsoftlimit < limit)) +- limit = dquot->dq_dqb.dqb_bsoftlimit; ++ limit = dquot->dq_dqb.dqb_bsoftlimit; + if (dquot->dq_dqb.dqb_bhardlimit && + (!limit || dquot->dq_dqb.dqb_bhardlimit < limit)) + limit = dquot->dq_dqb.dqb_bhardlimit; +@@ -5558,10 +5555,7 @@ static int ext4_statfs_project(struct super_block *sb, + (buf->f_blocks - curblock) : 0; + } + +- limit = 0; +- if (dquot->dq_dqb.dqb_isoftlimit && +- (!limit || dquot->dq_dqb.dqb_isoftlimit < limit)) +- limit = dquot->dq_dqb.dqb_isoftlimit; ++ limit = dquot->dq_dqb.dqb_isoftlimit; + if (dquot->dq_dqb.dqb_ihardlimit && + (!limit || dquot->dq_dqb.dqb_ihardlimit < limit)) + limit = dquot->dq_dqb.dqb_ihardlimit; +-- +2.20.1 + diff --git a/queue-5.4/gpio-add-gpiod_toggle_active_low.patch b/queue-5.4/gpio-add-gpiod_toggle_active_low.patch new file mode 100644 index 00000000000..9dea3059db4 --- /dev/null +++ b/queue-5.4/gpio-add-gpiod_toggle_active_low.patch @@ -0,0 +1,76 @@ +From 63c67d997fc018b853f82e466894e2371ff23a9b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Dec 2019 03:40:55 +0100 +Subject: gpio: add gpiod_toggle_active_low() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Michał Mirosław + +[ Upstream commit d3a5bcb4a17f1ad072484bb92c42519ff3aba6e1 ] + +Add possibility to toggle active-low flag of a gpio descriptor. This is +useful for compatibility code, where defaults are inverted vs DT gpio +flags or the active-low flag is taken from elsewhere. + +Acked-by: Linus Walleij +Signed-off-by: Michał Mirosław +Link: https://lore.kernel.org/r/7ce0338e01ad17fa5a227176813941b41a7c35c1.1576031637.git.mirq-linux@rere.qmqm.pl +Signed-off-by: Ulf Hansson +Signed-off-by: Sasha Levin +--- + drivers/gpio/gpiolib.c | 11 +++++++++++ + include/linux/gpio/consumer.h | 7 +++++++ + 2 files changed, 18 insertions(+) + +diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c +index 2476306e7030e..22506e4614b3f 100644 +--- a/drivers/gpio/gpiolib.c ++++ b/drivers/gpio/gpiolib.c +@@ -3220,6 +3220,17 @@ int gpiod_is_active_low(const struct gpio_desc *desc) + } + EXPORT_SYMBOL_GPL(gpiod_is_active_low); + ++/** ++ * gpiod_toggle_active_low - toggle whether a GPIO is active-low or not ++ * @desc: the gpio descriptor to change ++ */ ++void gpiod_toggle_active_low(struct gpio_desc *desc) ++{ ++ VALIDATE_DESC_VOID(desc); ++ change_bit(FLAG_ACTIVE_LOW, &desc->flags); ++} ++EXPORT_SYMBOL_GPL(gpiod_toggle_active_low); ++ + /* I/O calls are only valid after configuration completed; the relevant + * "is this a valid GPIO" error checks should already have been done. + * +diff --git a/include/linux/gpio/consumer.h b/include/linux/gpio/consumer.h +index b70af921c6145..803bb63dd5ffb 100644 +--- a/include/linux/gpio/consumer.h ++++ b/include/linux/gpio/consumer.h +@@ -158,6 +158,7 @@ int gpiod_set_raw_array_value_cansleep(unsigned int array_size, + + int gpiod_set_debounce(struct gpio_desc *desc, unsigned debounce); + int gpiod_set_transitory(struct gpio_desc *desc, bool transitory); ++void gpiod_toggle_active_low(struct gpio_desc *desc); + + int gpiod_is_active_low(const struct gpio_desc *desc); + int gpiod_cansleep(const struct gpio_desc *desc); +@@ -479,6 +480,12 @@ static inline int gpiod_set_transitory(struct gpio_desc *desc, bool transitory) + return -ENOSYS; + } + ++static inline void gpiod_toggle_active_low(struct gpio_desc *desc) ++{ ++ /* GPIO can never have been requested */ ++ WARN_ON(desc); ++} ++ + static inline int gpiod_is_active_low(const struct gpio_desc *desc) + { + /* GPIO can never have been requested */ +-- +2.20.1 + diff --git a/queue-5.4/jbd2-do-not-clear-the-bh_mapped-flag-when-forgetting.patch b/queue-5.4/jbd2-do-not-clear-the-bh_mapped-flag-when-forgetting.patch new file mode 100644 index 00000000000..8bf996d68ac --- /dev/null +++ b/queue-5.4/jbd2-do-not-clear-the-bh_mapped-flag-when-forgetting.patch @@ -0,0 +1,95 @@ +From 5834bcd2c5d2130ceccb145afc595e100e2e7bc5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 18 Feb 2020 18:59:53 +0800 +Subject: jbd2: do not clear the BH_Mapped flag when forgetting a metadata + buffer + +From: zhangyi (F) + +[ Upstream commit c96dceeabf765d0b1b1f29c3bf50a5c01315b820 ] + +Commit 904cdbd41d74 ("jbd2: clear dirty flag when revoking a buffer from +an older transaction") set the BH_Freed flag when forgetting a metadata +buffer which belongs to the committing transaction, it indicate the +committing process clear dirty bits when it is done with the buffer. But +it also clear the BH_Mapped flag at the same time, which may trigger +below NULL pointer oops when block_size < PAGE_SIZE. + +rmdir 1 kjournald2 mkdir 2 + jbd2_journal_commit_transaction + commit transaction N +jbd2_journal_forget +set_buffer_freed(bh1) + jbd2_journal_commit_transaction + commit transaction N+1 + ... + clear_buffer_mapped(bh1) + ext4_getblk(bh2 ummapped) + ... + grow_dev_page + init_page_buffers + bh1->b_private=NULL + bh2->b_private=NULL + jbd2_journal_put_journal_head(jh1) + __journal_remove_journal_head(hb1) + jh1 is NULL and trigger oops + +*) Dir entry block bh1 and bh2 belongs to one page, and the bh2 has + already been unmapped. + +For the metadata buffer we forgetting, we should always keep the mapped +flag and clear the dirty flags is enough, so this patch pick out the +these buffers and keep their BH_Mapped flag. + +Link: https://lore.kernel.org/r/20200213063821.30455-3-yi.zhang@huawei.com +Fixes: 904cdbd41d74 ("jbd2: clear dirty flag when revoking a buffer from an older transaction") +Reviewed-by: Jan Kara +Signed-off-by: zhangyi (F) +Signed-off-by: Theodore Ts'o +Cc: stable@kernel.org +Signed-off-by: Sasha Levin +--- + fs/jbd2/commit.c | 25 +++++++++++++++++++++---- + 1 file changed, 21 insertions(+), 4 deletions(-) + +diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c +index 7fdb5f130f642..2a42904bcd62c 100644 +--- a/fs/jbd2/commit.c ++++ b/fs/jbd2/commit.c +@@ -983,12 +983,29 @@ void jbd2_journal_commit_transaction(journal_t *journal) + * pagesize and it is attached to the last partial page. + */ + if (buffer_freed(bh) && !jh->b_next_transaction) { ++ struct address_space *mapping; ++ + clear_buffer_freed(bh); + clear_buffer_jbddirty(bh); +- clear_buffer_mapped(bh); +- clear_buffer_new(bh); +- clear_buffer_req(bh); +- bh->b_bdev = NULL; ++ ++ /* ++ * Block device buffers need to stay mapped all the ++ * time, so it is enough to clear buffer_jbddirty and ++ * buffer_freed bits. For the file mapping buffers (i.e. ++ * journalled data) we need to unmap buffer and clear ++ * more bits. We also need to be careful about the check ++ * because the data page mapping can get cleared under ++ * out hands, which alse need not to clear more bits ++ * because the page and buffers will be freed and can ++ * never be reused once we are done with them. ++ */ ++ mapping = READ_ONCE(bh->b_page->mapping); ++ if (mapping && !sb_is_blkdev_sb(mapping->host->i_sb)) { ++ clear_buffer_mapped(bh); ++ clear_buffer_new(bh); ++ clear_buffer_req(bh); ++ bh->b_bdev = NULL; ++ } + } + + if (buffer_jbddirty(bh)) { +-- +2.20.1 + diff --git a/queue-5.4/jbd2-move-the-clearing-of-b_modified-flag-to-the-jou.patch b/queue-5.4/jbd2-move-the-clearing-of-b_modified-flag-to-the-jou.patch new file mode 100644 index 00000000000..49562ee94db --- /dev/null +++ b/queue-5.4/jbd2-move-the-clearing-of-b_modified-flag-to-the-jou.patch @@ -0,0 +1,107 @@ +From cdfb9834382934c7c94ba8f31e1a8ab1f44218b8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 18 Feb 2020 18:59:52 +0800 +Subject: jbd2: move the clearing of b_modified flag to the + journal_unmap_buffer() + +From: zhangyi (F) + +[ Upstream commit 6a66a7ded12baa6ebbb2e3e82f8cb91382814839 ] + +There is no need to delay the clearing of b_modified flag to the +transaction committing time when unmapping the journalled buffer, so +just move it to the journal_unmap_buffer(). + +Link: https://lore.kernel.org/r/20200213063821.30455-2-yi.zhang@huawei.com +Reviewed-by: Jan Kara +Signed-off-by: zhangyi (F) +Signed-off-by: Theodore Ts'o +Cc: stable@kernel.org +Signed-off-by: Sasha Levin +--- + fs/jbd2/commit.c | 43 +++++++++++++++---------------------------- + fs/jbd2/transaction.c | 10 ++++++---- + 2 files changed, 21 insertions(+), 32 deletions(-) + +diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c +index c43591cd70f1c..7fdb5f130f642 100644 +--- a/fs/jbd2/commit.c ++++ b/fs/jbd2/commit.c +@@ -974,34 +974,21 @@ void jbd2_journal_commit_transaction(journal_t *journal) + * it. */ + + /* +- * A buffer which has been freed while still being journaled by +- * a previous transaction. +- */ +- if (buffer_freed(bh)) { +- /* +- * If the running transaction is the one containing +- * "add to orphan" operation (b_next_transaction != +- * NULL), we have to wait for that transaction to +- * commit before we can really get rid of the buffer. +- * So just clear b_modified to not confuse transaction +- * credit accounting and refile the buffer to +- * BJ_Forget of the running transaction. If the just +- * committed transaction contains "add to orphan" +- * operation, we can completely invalidate the buffer +- * now. We are rather through in that since the +- * buffer may be still accessible when blocksize < +- * pagesize and it is attached to the last partial +- * page. +- */ +- jh->b_modified = 0; +- if (!jh->b_next_transaction) { +- clear_buffer_freed(bh); +- clear_buffer_jbddirty(bh); +- clear_buffer_mapped(bh); +- clear_buffer_new(bh); +- clear_buffer_req(bh); +- bh->b_bdev = NULL; +- } ++ * A buffer which has been freed while still being journaled ++ * by a previous transaction, refile the buffer to BJ_Forget of ++ * the running transaction. If the just committed transaction ++ * contains "add to orphan" operation, we can completely ++ * invalidate the buffer now. We are rather through in that ++ * since the buffer may be still accessible when blocksize < ++ * pagesize and it is attached to the last partial page. ++ */ ++ if (buffer_freed(bh) && !jh->b_next_transaction) { ++ clear_buffer_freed(bh); ++ clear_buffer_jbddirty(bh); ++ clear_buffer_mapped(bh); ++ clear_buffer_new(bh); ++ clear_buffer_req(bh); ++ bh->b_bdev = NULL; + } + + if (buffer_jbddirty(bh)) { +diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c +index bee8498d77929..3930c68a9c204 100644 +--- a/fs/jbd2/transaction.c ++++ b/fs/jbd2/transaction.c +@@ -2296,14 +2296,16 @@ static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh, + return -EBUSY; + } + /* +- * OK, buffer won't be reachable after truncate. We just set +- * j_next_transaction to the running transaction (if there is +- * one) and mark buffer as freed so that commit code knows it +- * should clear dirty bits when it is done with the buffer. ++ * OK, buffer won't be reachable after truncate. We just clear ++ * b_modified to not confuse transaction credit accounting, and ++ * set j_next_transaction to the running transaction (if there ++ * is one) and mark buffer as freed so that commit code knows ++ * it should clear dirty bits when it is done with the buffer. + */ + set_buffer_freed(bh); + if (journal->j_running_transaction && buffer_jbddirty(bh)) + jh->b_next_transaction = journal->j_running_transaction; ++ jh->b_modified = 0; + jbd2_journal_put_journal_head(jh); + spin_unlock(&journal->j_list_lock); + jbd_unlock_bh_state(bh); +-- +2.20.1 + diff --git a/queue-5.4/kvm-x86-mmu-fix-struct-guest_walker-arrays-for-5-lev.patch b/queue-5.4/kvm-x86-mmu-fix-struct-guest_walker-arrays-for-5-lev.patch new file mode 100644 index 00000000000..38dc8fb95ed --- /dev/null +++ b/queue-5.4/kvm-x86-mmu-fix-struct-guest_walker-arrays-for-5-lev.patch @@ -0,0 +1,46 @@ +From c4434d15e509b0d902224e45d6e72737adbd0789 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 7 Feb 2020 09:37:42 -0800 +Subject: KVM: x86/mmu: Fix struct guest_walker arrays for 5-level paging + +From: Sean Christopherson + +[ Upstream commit f6ab0107a4942dbf9a5cf0cca3f37e184870a360 ] + +Define PT_MAX_FULL_LEVELS as PT64_ROOT_MAX_LEVEL, i.e. 5, to fix shadow +paging for 5-level guest page tables. PT_MAX_FULL_LEVELS is used to +size the arrays that track guest pages table information, i.e. using a +"max levels" of 4 causes KVM to access garbage beyond the end of an +array when querying state for level 5 entries. E.g. FNAME(gpte_changed) +will read garbage and most likely return %true for a level 5 entry, +soft-hanging the guest because FNAME(fetch) will restart the guest +instead of creating SPTEs because it thinks the guest PTE has changed. + +Note, KVM doesn't yet support 5-level nested EPT, so PT_MAX_FULL_LEVELS +gets to stay "4" for the PTTYPE_EPT case. + +Fixes: 855feb673640 ("KVM: MMU: Add 5 level EPT & Shadow page table support.") +Cc: stable@vger.kernel.org +Signed-off-by: Sean Christopherson +Signed-off-by: Paolo Bonzini +Signed-off-by: Sasha Levin +--- + arch/x86/kvm/paging_tmpl.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h +index c1d7b866a03fa..4e3f137ffa8c8 100644 +--- a/arch/x86/kvm/paging_tmpl.h ++++ b/arch/x86/kvm/paging_tmpl.h +@@ -33,7 +33,7 @@ + #define PT_GUEST_ACCESSED_SHIFT PT_ACCESSED_SHIFT + #define PT_HAVE_ACCESSED_DIRTY(mmu) true + #ifdef CONFIG_X86_64 +- #define PT_MAX_FULL_LEVELS 4 ++ #define PT_MAX_FULL_LEVELS PT64_ROOT_MAX_LEVEL + #define CMPXCHG cmpxchg + #else + #define CMPXCHG cmpxchg64 +-- +2.20.1 + diff --git a/queue-5.4/mmc-core-rework-wp-gpio-handling.patch b/queue-5.4/mmc-core-rework-wp-gpio-handling.patch new file mode 100644 index 00000000000..5bdac64a6cf --- /dev/null +++ b/queue-5.4/mmc-core-rework-wp-gpio-handling.patch @@ -0,0 +1,142 @@ +From e895ee0850308323e70251b8341c5c54ec67be19 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Dec 2019 03:40:55 +0100 +Subject: mmc: core: Rework wp-gpio handling +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Michał Mirosław + +[ Upstream commit 9073d10b098973519044f5fcdc25586810b435da ] + +Use MMC_CAP2_RO_ACTIVE_HIGH flag as indicator if GPIO line is to be +inverted compared to DT/platform-specified polarity. The flag is not used +after init in GPIO mode anyway. No functional changes intended. + +Signed-off-by: Michał Mirosław +Link: https://lore.kernel.org/r/a60f563f11bbff821da2fa2949ca82922b144860.1576031637.git.mirq-linux@rere.qmqm.pl +Signed-off-by: Ulf Hansson +Signed-off-by: Sasha Levin +--- + drivers/gpio/gpiolib-of.c | 4 ---- + drivers/mmc/core/host.c | 11 ++++------- + drivers/mmc/core/slot-gpio.c | 3 +++ + drivers/mmc/host/pxamci.c | 8 ++++---- + drivers/mmc/host/sdhci-esdhc-imx.c | 3 ++- + 5 files changed, 13 insertions(+), 16 deletions(-) + +diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c +index 7ee5b7f53aebe..3ece59185d372 100644 +--- a/drivers/gpio/gpiolib-of.c ++++ b/drivers/gpio/gpiolib-of.c +@@ -146,10 +146,6 @@ static void of_gpio_flags_quirks(struct device_node *np, + if (of_property_read_bool(np, "cd-inverted")) + *flags ^= OF_GPIO_ACTIVE_LOW; + } +- if (!strcmp(propname, "wp-gpios")) { +- if (of_property_read_bool(np, "wp-inverted")) +- *flags ^= OF_GPIO_ACTIVE_LOW; +- } + } + /* + * Some GPIO fixed regulator quirks. +diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c +index 105b7a7c02513..b3484def0a8b0 100644 +--- a/drivers/mmc/core/host.c ++++ b/drivers/mmc/core/host.c +@@ -176,7 +176,6 @@ int mmc_of_parse(struct mmc_host *host) + u32 bus_width, drv_type, cd_debounce_delay_ms; + int ret; + bool cd_cap_invert, cd_gpio_invert = false; +- bool ro_cap_invert, ro_gpio_invert = false; + + if (!dev || !dev_fwnode(dev)) + return 0; +@@ -255,9 +254,11 @@ int mmc_of_parse(struct mmc_host *host) + } + + /* Parse Write Protection */ +- ro_cap_invert = device_property_read_bool(dev, "wp-inverted"); + +- ret = mmc_gpiod_request_ro(host, "wp", 0, 0, &ro_gpio_invert); ++ if (device_property_read_bool(dev, "wp-inverted")) ++ host->caps2 |= MMC_CAP2_RO_ACTIVE_HIGH; ++ ++ ret = mmc_gpiod_request_ro(host, "wp", 0, 0, NULL); + if (!ret) + dev_info(host->parent, "Got WP GPIO\n"); + else if (ret != -ENOENT && ret != -ENOSYS) +@@ -266,10 +267,6 @@ int mmc_of_parse(struct mmc_host *host) + if (device_property_read_bool(dev, "disable-wp")) + host->caps2 |= MMC_CAP2_NO_WRITE_PROTECT; + +- /* See the comment on CD inversion above */ +- if (ro_cap_invert ^ ro_gpio_invert) +- host->caps2 |= MMC_CAP2_RO_ACTIVE_HIGH; +- + if (device_property_read_bool(dev, "cap-sd-highspeed")) + host->caps |= MMC_CAP_SD_HIGHSPEED; + if (device_property_read_bool(dev, "cap-mmc-highspeed")) +diff --git a/drivers/mmc/core/slot-gpio.c b/drivers/mmc/core/slot-gpio.c +index da2596c5fa28d..582ec3d720f64 100644 +--- a/drivers/mmc/core/slot-gpio.c ++++ b/drivers/mmc/core/slot-gpio.c +@@ -241,6 +241,9 @@ int mmc_gpiod_request_ro(struct mmc_host *host, const char *con_id, + return ret; + } + ++ if (host->caps2 & MMC_CAP2_RO_ACTIVE_HIGH) ++ gpiod_toggle_active_low(desc); ++ + if (gpio_invert) + *gpio_invert = !gpiod_is_active_low(desc); + +diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c +index 024acc1b0a2ea..b2bbcb09a49e6 100644 +--- a/drivers/mmc/host/pxamci.c ++++ b/drivers/mmc/host/pxamci.c +@@ -740,16 +740,16 @@ static int pxamci_probe(struct platform_device *pdev) + goto out; + } + ++ if (!host->pdata->gpio_card_ro_invert) ++ mmc->caps2 |= MMC_CAP2_RO_ACTIVE_HIGH; ++ + ret = mmc_gpiod_request_ro(mmc, "wp", 0, 0, NULL); + if (ret && ret != -ENOENT) { + dev_err(dev, "Failed requesting gpio_ro\n"); + goto out; + } +- if (!ret) { ++ if (!ret) + host->use_ro_gpio = true; +- mmc->caps2 |= host->pdata->gpio_card_ro_invert ? +- 0 : MMC_CAP2_RO_ACTIVE_HIGH; +- } + + if (host->pdata->init) + host->pdata->init(dev, pxamci_detect_irq, mmc); +diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c +index 1c988d6a24330..dccb4df465126 100644 +--- a/drivers/mmc/host/sdhci-esdhc-imx.c ++++ b/drivers/mmc/host/sdhci-esdhc-imx.c +@@ -1381,13 +1381,14 @@ static int sdhci_esdhc_imx_probe_nondt(struct platform_device *pdev, + host->mmc->parent->platform_data); + /* write_protect */ + if (boarddata->wp_type == ESDHC_WP_GPIO) { ++ host->mmc->caps2 |= MMC_CAP2_RO_ACTIVE_HIGH; ++ + err = mmc_gpiod_request_ro(host->mmc, "wp", 0, 0, NULL); + if (err) { + dev_err(mmc_dev(host->mmc), + "failed to request write-protect gpio!\n"); + return err; + } +- host->mmc->caps2 |= MMC_CAP2_RO_ACTIVE_HIGH; + } + + /* card_detect */ +-- +2.20.1 + diff --git a/queue-5.4/series b/queue-5.4/series index 20176aadd84..0ca428f9b8b 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -58,3 +58,10 @@ kvm-x86-mask-off-reserved-bit-from-db-exception-payload.patch perf-stat-don-t-report-a-null-stalled-cycles-per-insn-metric.patch nfsv4.1-make-cachethis-no-for-writes.patch revert-drm-sun4i-drv-allow-framebuffer-modifiers-in-mode-config.patch +jbd2-move-the-clearing-of-b_modified-flag-to-the-jou.patch +jbd2-do-not-clear-the-bh_mapped-flag-when-forgetting.patch +ext4-choose-hardlimit-when-softlimit-is-larger-than-.patch +ext4-simplify-checking-quota-limits-in-ext4_statfs.patch +kvm-x86-mmu-fix-struct-guest_walker-arrays-for-5-lev.patch +gpio-add-gpiod_toggle_active_low.patch +mmc-core-rework-wp-gpio-handling.patch