From: Greg Kroah-Hartman Date: Wed, 3 Jun 2015 01:14:59 +0000 (+0900) Subject: 4.0-stable patches X-Git-Tag: v3.10.80~24 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=da37615330f3e1b6379857ace3cd8979ccd078c2;p=thirdparty%2Fkernel%2Fstable-queue.git 4.0-stable patches added patches: btrfs-fix-racy-system-chunk-allocation-when-setting-block-group-ro.patch clk-add-missing-lock-when-call-clk_core_enable-in-clk_set_parent.patch clk-exynos5420-restore-gate_bus_top-on-suspend.patch fs-omfs-add-null-terminator-in-the-end-up-the-token-list.patch hwmon-nct6683-add-missing-sysfs-attribute-initialization.patch hwmon-nct6775-add-missing-sysfs-attribute-initialization.patch hwmon-ntc_thermistor-ensure-iio-channel-is-of-type-iio_voltage.patch hwmon-tmp401-do-not-auto-detect-chip-on-i2c-address-0x37.patch iio-adc-cc10001-add-delay-before-setting-start-bit.patch iio-adc-cc10001-fix-incorrect-use-of-power-up-power-down-register.patch iio-adc-cc10001-fix-regulator_get_voltage-return-value-check.patch iio-adc-cc10001-fix-the-channel-number-mapping.patch iio-adc-spmi-vadc-fix-overflow-in-output-value.patch iio-adc-xilinx-fix-register-addresses.patch iio-adc-xilinx-fix-vccaux-channel-.address.patch iio-adc-xilinx-fix-vrefn-sign.patch iio-adc-xilinx-fix-vrefp-scale.patch iio-axp288_adc-add-missing-channel-info-mask.patch iio-light-hid-sensor-prox-fix-modifier.patch iio-pressure-hid-sensor-press-fix-modifier.patch iio-st_sensors-fix-oops-when-probing-spi-devices.patch lguest-fix-out-by-one-error-in-address-checking.patch libceph-request-a-new-osdmap-if-lingering-request-maps-to-no-osd.patch mfd-da9052-fix-broken-regulator-probe.patch omfs-fix-sign-confusion-for-bitmap-loop-counter.patch ovl-don-t-remove-non-empty-opaque-directory.patch ovl-mount-read-only-if-workdir-can-t-be-created.patch revert-libceph-clear-r_req_lru_item-in-__unregister_linger_request.patch xen-events-don-t-bind-non-percpu-virqs-with-percpu-chip.patch xfs-xfs_attr_inactive-leaves-inconsistent-attr-fork-state-behind.patch xfs-xfs_iozero-can-return-positive-errno.patch --- diff --git a/queue-4.0/btrfs-fix-racy-system-chunk-allocation-when-setting-block-group-ro.patch b/queue-4.0/btrfs-fix-racy-system-chunk-allocation-when-setting-block-group-ro.patch new file mode 100644 index 00000000000..b03971fb747 --- /dev/null +++ b/queue-4.0/btrfs-fix-racy-system-chunk-allocation-when-setting-block-group-ro.patch @@ -0,0 +1,50 @@ +From a96295965b600f2dc6ad661c4803c86e87db3d7b Mon Sep 17 00:00:00 2001 +From: Filipe Manana +Date: Mon, 18 May 2015 19:11:40 +0100 +Subject: Btrfs: fix racy system chunk allocation when setting block group ro + +From: Filipe Manana + +commit a96295965b600f2dc6ad661c4803c86e87db3d7b upstream. + +If while setting a block group read-only we end up allocating a system +chunk, through check_system_chunk(), we were not doing it while holding +the chunk mutex which is a problem if a concurrent chunk allocation is +happening, through do_chunk_alloc(), as it means both block groups can +end up using the same logical addresses and physical regions in the +device(s). So make sure we hold the chunk mutex. + +Fixes: 2f0810880f08 ("btrfs: delete chunk allocation attemp when + setting block group ro") + +Signed-off-by: Filipe Manana +Signed-off-by: Chris Mason +Signed-off-by: Greg Kroah-Hartman + +--- + fs/btrfs/extent-tree.c | 2 ++ + fs/btrfs/volumes.c | 1 + + 2 files changed, 3 insertions(+) + +--- a/fs/btrfs/extent-tree.c ++++ b/fs/btrfs/extent-tree.c +@@ -8548,7 +8548,9 @@ int btrfs_set_block_group_ro(struct btrf + out: + if (cache->flags & BTRFS_BLOCK_GROUP_SYSTEM) { + alloc_flags = update_block_group_flags(root, cache->flags); ++ lock_chunks(root->fs_info->chunk_root); + check_system_chunk(trans, root, alloc_flags); ++ unlock_chunks(root->fs_info->chunk_root); + } + + btrfs_end_transaction(trans, root); +--- a/fs/btrfs/volumes.c ++++ b/fs/btrfs/volumes.c +@@ -4626,6 +4626,7 @@ int btrfs_alloc_chunk(struct btrfs_trans + { + u64 chunk_offset; + ++ ASSERT(mutex_is_locked(&extent_root->fs_info->chunk_mutex)); + chunk_offset = find_next_chunk(extent_root->fs_info); + return __btrfs_alloc_chunk(trans, extent_root, chunk_offset, type); + } diff --git a/queue-4.0/clk-add-missing-lock-when-call-clk_core_enable-in-clk_set_parent.patch b/queue-4.0/clk-add-missing-lock-when-call-clk_core_enable-in-clk_set_parent.patch new file mode 100644 index 00000000000..d3932a770ec --- /dev/null +++ b/queue-4.0/clk-add-missing-lock-when-call-clk_core_enable-in-clk_set_parent.patch @@ -0,0 +1,70 @@ +From d2a5d46b167a9a8231264daf80165b739aecf1d7 Mon Sep 17 00:00:00 2001 +From: Dong Aisheng +Date: Wed, 15 Apr 2015 22:26:36 +0800 +Subject: clk: add missing lock when call clk_core_enable in clk_set_parent + +From: Dong Aisheng + +commit d2a5d46b167a9a8231264daf80165b739aecf1d7 upstream. + +Before commit 035a61c314eb ("clk: Make clk API return per-user +struct clk instances") we acquired the enable_lock in +__clk_set_parent_{before,after}() by means of calling +clk_enable(). After commit 035a61c314eb we use clk_core_enable() +in place of the clk_enable(), and clk_core_enable() doesn't +acquire the enable_lock. This opens up a race condition between +clk_set_parent() and clk_enable(). Fix it. + +Fixes: 035a61c314eb ("clk: Make clk API return per-user struct clk instances") +Cc: Mike Turquette +Cc: Stephen Boyd +Signed-off-by: Dong Aisheng +Signed-off-by: Stephen Boyd +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/clk/clk.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/drivers/clk/clk.c ++++ b/drivers/clk/clk.c +@@ -1443,8 +1443,10 @@ static struct clk_core *__clk_set_parent + */ + if (clk->prepare_count) { + clk_core_prepare(parent); ++ flags = clk_enable_lock(); + clk_core_enable(parent); + clk_core_enable(clk); ++ clk_enable_unlock(flags); + } + + /* update the clk tree topology */ +@@ -1459,13 +1461,17 @@ static void __clk_set_parent_after(struc + struct clk_core *parent, + struct clk_core *old_parent) + { ++ unsigned long flags; ++ + /* + * Finish the migration of prepare state and undo the changes done + * for preventing a race with clk_enable(). + */ + if (core->prepare_count) { ++ flags = clk_enable_lock(); + clk_core_disable(core); + clk_core_disable(old_parent); ++ clk_enable_unlock(flags); + clk_core_unprepare(old_parent); + } + } +@@ -1489,8 +1495,10 @@ static int __clk_set_parent(struct clk_c + clk_enable_unlock(flags); + + if (clk->prepare_count) { ++ flags = clk_enable_lock(); + clk_core_disable(clk); + clk_core_disable(parent); ++ clk_enable_unlock(flags); + clk_core_unprepare(parent); + } + return ret; diff --git a/queue-4.0/clk-exynos5420-restore-gate_bus_top-on-suspend.patch b/queue-4.0/clk-exynos5420-restore-gate_bus_top-on-suspend.patch new file mode 100644 index 00000000000..a5d81605ab3 --- /dev/null +++ b/queue-4.0/clk-exynos5420-restore-gate_bus_top-on-suspend.patch @@ -0,0 +1,43 @@ +From 97372e5a99449b4fffa824a382ad6358066a9918 Mon Sep 17 00:00:00 2001 +From: Javier Martinez Canillas +Date: Wed, 8 Apr 2015 07:34:12 +0200 +Subject: clk: exynos5420: Restore GATE_BUS_TOP on suspend + +From: Javier Martinez Canillas + +commit 97372e5a99449b4fffa824a382ad6358066a9918 upstream. + +Commit ae43b3289186 ("ARM: 8202/1: dmaengine: pl330: Add runtime Power +Management support v12") added pm support for the pl330 dma driver but +it makes the clock for the Exynos5420 MDMA0 DMA controller to be gated +during suspend and this in turn makes its parent clock aclk266_g2d to +be gated. But the clock needs to be ungated prior suspend to allow the +system to be suspend and resumed correctly. + +Add GATE_BUS_TOP register to the list of registers to be restored when +the system enters into a suspend state so aclk266_g2d will be ungated. + +Thanks to Abhilash Kesavan for figuring out that this was the issue. + +Fixes: ae43b32 ("ARM: 8202/1: dmaengine: pl330: Add runtime Power Management support v12") +Signed-off-by: Javier Martinez Canillas +Tested-by: Kevin Hilman +Tested-by: Abhilash Kesavan +Acked-by: Tomasz Figa +Signed-off-by: Sylwester Nawrocki +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/clk/samsung/clk-exynos5420.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/clk/samsung/clk-exynos5420.c ++++ b/drivers/clk/samsung/clk-exynos5420.c +@@ -271,6 +271,7 @@ static const struct samsung_clk_reg_dump + { .offset = SRC_MASK_PERIC0, .value = 0x11111110, }, + { .offset = SRC_MASK_PERIC1, .value = 0x11111100, }, + { .offset = SRC_MASK_ISP, .value = 0x11111000, }, ++ { .offset = GATE_BUS_TOP, .value = 0xffffffff, }, + { .offset = GATE_BUS_DISP1, .value = 0xffffffff, }, + { .offset = GATE_IP_PERIC, .value = 0xffffffff, }, + }; diff --git a/queue-4.0/fs-omfs-add-null-terminator-in-the-end-up-the-token-list.patch b/queue-4.0/fs-omfs-add-null-terminator-in-the-end-up-the-token-list.patch new file mode 100644 index 00000000000..fbc7548ccd5 --- /dev/null +++ b/queue-4.0/fs-omfs-add-null-terminator-in-the-end-up-the-token-list.patch @@ -0,0 +1,45 @@ +From dcbff39da3d815f08750552fdd04f96b51751129 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 28 May 2015 15:44:29 -0700 +Subject: fs, omfs: add NULL terminator in the end up the token list + +From: Sasha Levin + +commit dcbff39da3d815f08750552fdd04f96b51751129 upstream. + +match_token() expects a NULL terminator at the end of the token list so +that it would know where to stop. Not having one causes it to overrun +to invalid memory. + +In practice, passing a mount option that omfs didn't recognize would +sometimes panic the system. + +Signed-off-by: Sasha Levin +Signed-off-by: Bob Copeland +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + fs/omfs/inode.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/fs/omfs/inode.c ++++ b/fs/omfs/inode.c +@@ -359,7 +359,7 @@ nomem: + } + + enum { +- Opt_uid, Opt_gid, Opt_umask, Opt_dmask, Opt_fmask ++ Opt_uid, Opt_gid, Opt_umask, Opt_dmask, Opt_fmask, Opt_err + }; + + static const match_table_t tokens = { +@@ -368,6 +368,7 @@ static const match_table_t tokens = { + {Opt_umask, "umask=%o"}, + {Opt_dmask, "dmask=%o"}, + {Opt_fmask, "fmask=%o"}, ++ {Opt_err, NULL}, + }; + + static int parse_options(char *options, struct omfs_sb_info *sbi) diff --git a/queue-4.0/hwmon-nct6683-add-missing-sysfs-attribute-initialization.patch b/queue-4.0/hwmon-nct6683-add-missing-sysfs-attribute-initialization.patch new file mode 100644 index 00000000000..37dae021a55 --- /dev/null +++ b/queue-4.0/hwmon-nct6683-add-missing-sysfs-attribute-initialization.patch @@ -0,0 +1,48 @@ +From c7bd6dc320b85445b6b36a0aff41f929210027c7 Mon Sep 17 00:00:00 2001 +From: Guenter Roeck +Date: Thu, 28 May 2015 09:12:23 -0700 +Subject: hwmon: (nct6683) Add missing sysfs attribute initialization + +From: Guenter Roeck + +commit c7bd6dc320b85445b6b36a0aff41f929210027c7 upstream. + +The following error message is seen when loading the nct6683 driver +with DEBUG_LOCK_ALLOC enabled. + +BUG: key ffff88040b2f0030 not in .data! +------------[ cut here ]------------ +WARNING: CPU: 0 PID: 186 at kernel/locking/lockdep.c:2988 + lockdep_init_map+0x469/0x630() +DEBUG_LOCKS_WARN_ON(1) + +Caused by a missing call to sysfs_attr_init() when initializing +sysfs attributes. + +Reported-by: Alexey Orishko +Reviewed-by: Jean Delvare +Signed-off-by: Guenter Roeck +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/hwmon/nct6683.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/hwmon/nct6683.c ++++ b/drivers/hwmon/nct6683.c +@@ -439,6 +439,7 @@ nct6683_create_attr_group(struct device + (*t)->dev_attr.attr.name, tg->base + i); + if ((*t)->s2) { + a2 = &su->u.a2; ++ sysfs_attr_init(&a2->dev_attr.attr); + a2->dev_attr.attr.name = su->name; + a2->nr = (*t)->u.s.nr + i; + a2->index = (*t)->u.s.index; +@@ -449,6 +450,7 @@ nct6683_create_attr_group(struct device + *attrs = &a2->dev_attr.attr; + } else { + a = &su->u.a1; ++ sysfs_attr_init(&a->dev_attr.attr); + a->dev_attr.attr.name = su->name; + a->index = (*t)->u.index + i; + a->dev_attr.attr.mode = diff --git a/queue-4.0/hwmon-nct6775-add-missing-sysfs-attribute-initialization.patch b/queue-4.0/hwmon-nct6775-add-missing-sysfs-attribute-initialization.patch new file mode 100644 index 00000000000..ff38e90e014 --- /dev/null +++ b/queue-4.0/hwmon-nct6775-add-missing-sysfs-attribute-initialization.patch @@ -0,0 +1,48 @@ +From 1b63bf617206ff35b93c57c67bbe067ac735a85a Mon Sep 17 00:00:00 2001 +From: Guenter Roeck +Date: Thu, 28 May 2015 09:08:09 -0700 +Subject: hwmon: (nct6775) Add missing sysfs attribute initialization + +From: Guenter Roeck + +commit 1b63bf617206ff35b93c57c67bbe067ac735a85a upstream. + +The following error message is seen when loading the nct6775 driver +with DEBUG_LOCK_ALLOC enabled. + +BUG: key ffff88040b2f0030 not in .data! +------------[ cut here ]------------ +WARNING: CPU: 0 PID: 186 at kernel/locking/lockdep.c:2988 + lockdep_init_map+0x469/0x630() +DEBUG_LOCKS_WARN_ON(1) + +Caused by a missing call to sysfs_attr_init() when initializing +sysfs attributes. + +Reported-by: Alexey Orishko +Reviewed-by: Jean Delvare +Signed-off-by: Guenter Roeck +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/hwmon/nct6775.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/hwmon/nct6775.c ++++ b/drivers/hwmon/nct6775.c +@@ -994,6 +994,7 @@ nct6775_create_attr_group(struct device + (*t)->dev_attr.attr.name, tg->base + i); + if ((*t)->s2) { + a2 = &su->u.a2; ++ sysfs_attr_init(&a2->dev_attr.attr); + a2->dev_attr.attr.name = su->name; + a2->nr = (*t)->u.s.nr + i; + a2->index = (*t)->u.s.index; +@@ -1004,6 +1005,7 @@ nct6775_create_attr_group(struct device + *attrs = &a2->dev_attr.attr; + } else { + a = &su->u.a1; ++ sysfs_attr_init(&a->dev_attr.attr); + a->dev_attr.attr.name = su->name; + a->index = (*t)->u.index + i; + a->dev_attr.attr.mode = diff --git a/queue-4.0/hwmon-ntc_thermistor-ensure-iio-channel-is-of-type-iio_voltage.patch b/queue-4.0/hwmon-ntc_thermistor-ensure-iio-channel-is-of-type-iio_voltage.patch new file mode 100644 index 00000000000..d78042c1779 --- /dev/null +++ b/queue-4.0/hwmon-ntc_thermistor-ensure-iio-channel-is-of-type-iio_voltage.patch @@ -0,0 +1,48 @@ +From adba657533bdd255f7b78bc8a324091f46b294cd Mon Sep 17 00:00:00 2001 +From: Chris Lesiak +Date: Tue, 26 May 2015 15:40:44 -0500 +Subject: hwmon: (ntc_thermistor) Ensure iio channel is of type IIO_VOLTAGE + +From: Chris Lesiak + +commit adba657533bdd255f7b78bc8a324091f46b294cd upstream. + +When configured via device tree, the associated iio device needs to be +measuring voltage for the conversion to resistance to be correct. +Return -EINVAL if that is not the case. + +Signed-off-by: Chris Lesiak +Signed-off-by: Guenter Roeck +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/hwmon/ntc_thermistor.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +--- a/drivers/hwmon/ntc_thermistor.c ++++ b/drivers/hwmon/ntc_thermistor.c +@@ -239,8 +239,10 @@ static struct ntc_thermistor_platform_da + ntc_thermistor_parse_dt(struct platform_device *pdev) + { + struct iio_channel *chan; ++ enum iio_chan_type type; + struct device_node *np = pdev->dev.of_node; + struct ntc_thermistor_platform_data *pdata; ++ int ret; + + if (!np) + return NULL; +@@ -253,6 +255,13 @@ ntc_thermistor_parse_dt(struct platform_ + if (IS_ERR(chan)) + return ERR_CAST(chan); + ++ ret = iio_get_channel_type(chan, &type); ++ if (ret < 0) ++ return ERR_PTR(ret); ++ ++ if (type != IIO_VOLTAGE) ++ return ERR_PTR(-EINVAL); ++ + if (of_property_read_u32(np, "pullup-uv", &pdata->pullup_uv)) + return ERR_PTR(-ENODEV); + if (of_property_read_u32(np, "pullup-ohm", &pdata->pullup_ohm)) diff --git a/queue-4.0/hwmon-tmp401-do-not-auto-detect-chip-on-i2c-address-0x37.patch b/queue-4.0/hwmon-tmp401-do-not-auto-detect-chip-on-i2c-address-0x37.patch new file mode 100644 index 00000000000..257f53ac2aa --- /dev/null +++ b/queue-4.0/hwmon-tmp401-do-not-auto-detect-chip-on-i2c-address-0x37.patch @@ -0,0 +1,43 @@ +From 9aecac04d8d89e730ae362a748113b19c06a9d39 Mon Sep 17 00:00:00 2001 +From: Guenter Roeck +Date: Wed, 27 May 2015 16:11:48 -0700 +Subject: hwmon: (tmp401) Do not auto-detect chip on I2C address 0x37 + +From: Guenter Roeck + +commit 9aecac04d8d89e730ae362a748113b19c06a9d39 upstream. + +I2C address 0x37 may be used by EEPROMs, which can result in false +positives. Do not attempt to detect a chip at this address. + +Reviewed-by: Jean Delvare +Signed-off-by: Guenter Roeck +Signed-off-by: Greg Kroah-Hartman + +--- + Documentation/hwmon/tmp401 | 2 +- + drivers/hwmon/tmp401.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +--- a/Documentation/hwmon/tmp401 ++++ b/Documentation/hwmon/tmp401 +@@ -20,7 +20,7 @@ Supported chips: + Datasheet: http://focus.ti.com/docs/prod/folders/print/tmp432.html + * Texas Instruments TMP435 + Prefix: 'tmp435' +- Addresses scanned: I2C 0x37, 0x48 - 0x4f ++ Addresses scanned: I2C 0x48 - 0x4f + Datasheet: http://focus.ti.com/docs/prod/folders/print/tmp435.html + + Authors: +--- a/drivers/hwmon/tmp401.c ++++ b/drivers/hwmon/tmp401.c +@@ -44,7 +44,7 @@ + #include + + /* Addresses to scan */ +-static const unsigned short normal_i2c[] = { 0x37, 0x48, 0x49, 0x4a, 0x4c, 0x4d, ++static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4c, 0x4d, + 0x4e, 0x4f, I2C_CLIENT_END }; + + enum chips { tmp401, tmp411, tmp431, tmp432, tmp435 }; diff --git a/queue-4.0/iio-adc-cc10001-add-delay-before-setting-start-bit.patch b/queue-4.0/iio-adc-cc10001-add-delay-before-setting-start-bit.patch new file mode 100644 index 00000000000..c055e36a61d --- /dev/null +++ b/queue-4.0/iio-adc-cc10001-add-delay-before-setting-start-bit.patch @@ -0,0 +1,33 @@ +From f29b212edb9e253cafcb4a2ab7842a890989f1a5 Mon Sep 17 00:00:00 2001 +From: Naidu Tellapati +Date: Thu, 7 May 2015 18:22:20 -0300 +Subject: iio: adc: cc10001: Add delay before setting START bit + +From: Naidu Tellapati + +commit f29b212edb9e253cafcb4a2ab7842a890989f1a5 upstream. + +According to hardware team there should be some delay after +setting channel number, start mode and before setting START. +Add a one microsecond delay for this purpose. + +Fixes: 1664f6a5b0c8 ("iio: adc: Cosmic Circuits 10001 ADC driver") +Signed-off-by: Naidu Tellapati +Signed-off-by: Ezequiel Garcia +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/iio/adc/cc10001_adc.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/iio/adc/cc10001_adc.c ++++ b/drivers/iio/adc/cc10001_adc.c +@@ -100,6 +100,7 @@ static void cc10001_adc_start(struct cc1 + val = (channel & CC10001_ADC_CH_MASK) | CC10001_ADC_MODE_SINGLE_CONV; + cc10001_adc_write_reg(adc_dev, CC10001_ADC_CONFIG, val); + ++ udelay(1); + val = cc10001_adc_read_reg(adc_dev, CC10001_ADC_CONFIG); + val = val | CC10001_ADC_START_CONV; + cc10001_adc_write_reg(adc_dev, CC10001_ADC_CONFIG, val); diff --git a/queue-4.0/iio-adc-cc10001-fix-incorrect-use-of-power-up-power-down-register.patch b/queue-4.0/iio-adc-cc10001-fix-incorrect-use-of-power-up-power-down-register.patch new file mode 100644 index 00000000000..502c1f83652 --- /dev/null +++ b/queue-4.0/iio-adc-cc10001-fix-incorrect-use-of-power-up-power-down-register.patch @@ -0,0 +1,104 @@ +From 713276ea88a295a79aa6633ba639ed47692a8de4 Mon Sep 17 00:00:00 2001 +From: Naidu Tellapati +Date: Thu, 7 May 2015 18:22:18 -0300 +Subject: iio: adc: cc10001: Fix incorrect use of power-up/power-down register + +From: Naidu Tellapati + +commit 713276ea88a295a79aa6633ba639ed47692a8de4 upstream. + +At present we are incorrectly setting the register to 0x1 to power up +the ADC. Since it is an active high power down register, we need to set +the register to 0x0 to actually power up. Conversely, writing 0x1 to the +register powers it down. + +This commit adds a couple of helpers to make the code clearer and then +use them to do the power-up/power-down properly. + +Fixes: 1664f6a5b0c8 ("iio: adc: Cosmic Circuits 10001 ADC driver") +Signed-off-by: Naidu Tellapati +Signed-off-by: Ezequiel Garcia +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/iio/adc/cc10001_adc.c | 33 +++++++++++++++++++-------------- + 1 file changed, 19 insertions(+), 14 deletions(-) + +--- a/drivers/iio/adc/cc10001_adc.c ++++ b/drivers/iio/adc/cc10001_adc.c +@@ -35,8 +35,9 @@ + #define CC10001_ADC_EOC_SET BIT(0) + + #define CC10001_ADC_CHSEL_SAMPLED 0x0c +-#define CC10001_ADC_POWER_UP 0x10 +-#define CC10001_ADC_POWER_UP_SET BIT(0) ++#define CC10001_ADC_POWER_DOWN 0x10 ++#define CC10001_ADC_POWER_DOWN_SET BIT(0) ++ + #define CC10001_ADC_DEBUG 0x14 + #define CC10001_ADC_DATA_COUNT 0x20 + +@@ -78,6 +79,18 @@ static inline u32 cc10001_adc_read_reg(s + return readl(adc_dev->reg_base + reg); + } + ++static void cc10001_adc_power_up(struct cc10001_adc_device *adc_dev) ++{ ++ cc10001_adc_write_reg(adc_dev, CC10001_ADC_POWER_DOWN, 0); ++ ndelay(adc_dev->start_delay_ns); ++} ++ ++static void cc10001_adc_power_down(struct cc10001_adc_device *adc_dev) ++{ ++ cc10001_adc_write_reg(adc_dev, CC10001_ADC_POWER_DOWN, ++ CC10001_ADC_POWER_DOWN_SET); ++} ++ + static void cc10001_adc_start(struct cc10001_adc_device *adc_dev, + unsigned int channel) + { +@@ -139,11 +152,7 @@ static irqreturn_t cc10001_adc_trigger_h + + mutex_lock(&adc_dev->lock); + +- cc10001_adc_write_reg(adc_dev, CC10001_ADC_POWER_UP, +- CC10001_ADC_POWER_UP_SET); +- +- /* Wait for 8 (6+2) clock cycles before activating START */ +- ndelay(adc_dev->start_delay_ns); ++ cc10001_adc_power_up(adc_dev); + + /* Calculate delay step for eoc and sampled data */ + delay_ns = adc_dev->eoc_delay_ns / CC10001_MAX_POLL_COUNT; +@@ -167,7 +176,7 @@ static irqreturn_t cc10001_adc_trigger_h + } + + done: +- cc10001_adc_write_reg(adc_dev, CC10001_ADC_POWER_UP, 0); ++ cc10001_adc_power_down(adc_dev); + + mutex_unlock(&adc_dev->lock); + +@@ -186,11 +195,7 @@ static u16 cc10001_adc_read_raw_voltage( + unsigned int delay_ns; + u16 val; + +- cc10001_adc_write_reg(adc_dev, CC10001_ADC_POWER_UP, +- CC10001_ADC_POWER_UP_SET); +- +- /* Wait for 8 (6+2) clock cycles before activating START */ +- ndelay(adc_dev->start_delay_ns); ++ cc10001_adc_power_up(adc_dev); + + /* Calculate delay step for eoc and sampled data */ + delay_ns = adc_dev->eoc_delay_ns / CC10001_MAX_POLL_COUNT; +@@ -199,7 +204,7 @@ static u16 cc10001_adc_read_raw_voltage( + + val = cc10001_adc_poll_done(indio_dev, chan->channel, delay_ns); + +- cc10001_adc_write_reg(adc_dev, CC10001_ADC_POWER_UP, 0); ++ cc10001_adc_power_down(adc_dev); + + return val; + } diff --git a/queue-4.0/iio-adc-cc10001-fix-regulator_get_voltage-return-value-check.patch b/queue-4.0/iio-adc-cc10001-fix-regulator_get_voltage-return-value-check.patch new file mode 100644 index 00000000000..3834799647a --- /dev/null +++ b/queue-4.0/iio-adc-cc10001-fix-regulator_get_voltage-return-value-check.patch @@ -0,0 +1,33 @@ +From 65a761bf8d55fdcf8ecc4642382a4e76c086e44c Mon Sep 17 00:00:00 2001 +From: Naidu Tellapati +Date: Thu, 7 May 2015 18:22:19 -0300 +Subject: iio: adc: cc10001: Fix regulator_get_voltage() return value check + +From: Naidu Tellapati + +commit 65a761bf8d55fdcf8ecc4642382a4e76c086e44c upstream. + +regulator_get_voltage() returns a non-negative value in case of success, +and a negative error in case of error. Let's fix this. + +Fixes: 1664f6a5b0c8 ("iio: adc: Cosmic Circuits 10001 ADC driver") +Signed-off-by: Naidu Tellapati +Signed-off-by: Ezequiel Garcia +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/iio/adc/cc10001_adc.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/iio/adc/cc10001_adc.c ++++ b/drivers/iio/adc/cc10001_adc.c +@@ -231,7 +231,7 @@ static int cc10001_adc_read_raw(struct i + + case IIO_CHAN_INFO_SCALE: + ret = regulator_get_voltage(adc_dev->reg); +- if (ret) ++ if (ret < 0) + return ret; + + *val = ret / 1000; diff --git a/queue-4.0/iio-adc-cc10001-fix-the-channel-number-mapping.patch b/queue-4.0/iio-adc-cc10001-fix-the-channel-number-mapping.patch new file mode 100644 index 00000000000..3f99015d1c9 --- /dev/null +++ b/queue-4.0/iio-adc-cc10001-fix-the-channel-number-mapping.patch @@ -0,0 +1,122 @@ +From 13415a998adb1802b5bd6bd5a336331589e866a1 Mon Sep 17 00:00:00 2001 +From: Naidu Tellapati +Date: Thu, 7 May 2015 18:22:17 -0300 +Subject: iio: adc: cc10001: Fix the channel number mapping + +From: Naidu Tellapati + +commit 13415a998adb1802b5bd6bd5a336331589e866a1 upstream. + +When some of the ADC channels are reserved for remote CPUs, +the scan index and the corresponding channel number doesn't +match. This leads to convesion on the incorrect channel during +triggered capture. + +Fix this by using a scan index to channel mapping encoded +in the iio_chan_spec for this purpose while starting conversion +on a particular ADC channel in trigger handler. + +Also, the channel_map is not really used anywhere but in probe(), so +no need to keep track of it. Remove it from device structure. + +While here, add 1 to number of channels to register timestamp channel +with the IIO core. + +Fixes: 1664f6a5b0c8 ("iio: adc: Cosmic Circuits 10001 ADC driver") +Signed-off-by: Naidu Tellapati +Signed-off-by: Ezequiel Garcia +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/iio/adc/cc10001_adc.c | 24 +++++++++++++----------- + 1 file changed, 13 insertions(+), 11 deletions(-) + +--- a/drivers/iio/adc/cc10001_adc.c ++++ b/drivers/iio/adc/cc10001_adc.c +@@ -62,7 +62,6 @@ struct cc10001_adc_device { + u16 *buf; + + struct mutex lock; +- unsigned long channel_map; + unsigned int start_delay_ns; + unsigned int eoc_delay_ns; + }; +@@ -129,6 +128,7 @@ static irqreturn_t cc10001_adc_trigger_h + struct iio_dev *indio_dev; + unsigned int delay_ns; + unsigned int channel; ++ unsigned int scan_idx; + bool sample_invalid; + u16 *data; + int i; +@@ -150,9 +150,10 @@ static irqreturn_t cc10001_adc_trigger_h + + i = 0; + sample_invalid = false; +- for_each_set_bit(channel, indio_dev->active_scan_mask, ++ for_each_set_bit(scan_idx, indio_dev->active_scan_mask, + indio_dev->masklength) { + ++ channel = indio_dev->channels[scan_idx].channel; + cc10001_adc_start(adc_dev, channel); + + data[i] = cc10001_adc_poll_done(indio_dev, channel, delay_ns); +@@ -255,22 +256,22 @@ static const struct iio_info cc10001_adc + .update_scan_mode = &cc10001_update_scan_mode, + }; + +-static int cc10001_adc_channel_init(struct iio_dev *indio_dev) ++static int cc10001_adc_channel_init(struct iio_dev *indio_dev, ++ unsigned long channel_map) + { +- struct cc10001_adc_device *adc_dev = iio_priv(indio_dev); + struct iio_chan_spec *chan_array, *timestamp; + unsigned int bit, idx = 0; + +- indio_dev->num_channels = bitmap_weight(&adc_dev->channel_map, +- CC10001_ADC_NUM_CHANNELS); ++ indio_dev->num_channels = bitmap_weight(&channel_map, ++ CC10001_ADC_NUM_CHANNELS) + 1; + +- chan_array = devm_kcalloc(&indio_dev->dev, indio_dev->num_channels + 1, ++ chan_array = devm_kcalloc(&indio_dev->dev, indio_dev->num_channels, + sizeof(struct iio_chan_spec), + GFP_KERNEL); + if (!chan_array) + return -ENOMEM; + +- for_each_set_bit(bit, &adc_dev->channel_map, CC10001_ADC_NUM_CHANNELS) { ++ for_each_set_bit(bit, &channel_map, CC10001_ADC_NUM_CHANNELS) { + struct iio_chan_spec *chan = &chan_array[idx]; + + chan->type = IIO_VOLTAGE; +@@ -305,6 +306,7 @@ static int cc10001_adc_probe(struct plat + unsigned long adc_clk_rate; + struct resource *res; + struct iio_dev *indio_dev; ++ unsigned long channel_map; + int ret; + + indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*adc_dev)); +@@ -313,9 +315,9 @@ static int cc10001_adc_probe(struct plat + + adc_dev = iio_priv(indio_dev); + +- adc_dev->channel_map = GENMASK(CC10001_ADC_NUM_CHANNELS - 1, 0); ++ channel_map = GENMASK(CC10001_ADC_NUM_CHANNELS - 1, 0); + if (!of_property_read_u32(node, "adc-reserved-channels", &ret)) +- adc_dev->channel_map &= ~ret; ++ channel_map &= ~ret; + + adc_dev->reg = devm_regulator_get(&pdev->dev, "vref"); + if (IS_ERR(adc_dev->reg)) +@@ -361,7 +363,7 @@ static int cc10001_adc_probe(struct plat + adc_dev->start_delay_ns = adc_dev->eoc_delay_ns * CC10001_WAIT_CYCLES; + + /* Setup the ADC channels available on the device */ +- ret = cc10001_adc_channel_init(indio_dev); ++ ret = cc10001_adc_channel_init(indio_dev, channel_map); + if (ret < 0) + goto err_disable_clk; + diff --git a/queue-4.0/iio-adc-spmi-vadc-fix-overflow-in-output-value.patch b/queue-4.0/iio-adc-spmi-vadc-fix-overflow-in-output-value.patch new file mode 100644 index 00000000000..c68ce6f7861 --- /dev/null +++ b/queue-4.0/iio-adc-spmi-vadc-fix-overflow-in-output-value.patch @@ -0,0 +1,54 @@ +From 937125aca00e0478c4024afe58bc620a7bbe2a93 Mon Sep 17 00:00:00 2001 +From: "Ivan T. Ivanov" +Date: Fri, 17 Apr 2015 17:51:08 +0300 +Subject: iio: adc: spmi-vadc: Fix overflow in output value + normalization + +From: "Ivan T. Ivanov" + +commit 937125aca00e0478c4024afe58bc620a7bbe2a93 upstream. + +With 'dx' equal to 0.625V and 15 bit ADC, calculations overflow +when difference against GND is ~20% of the ADC range. Fix this. + +Signed-off-by: Ivan T. Ivanov +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/iio/adc/qcom-spmi-vadc.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +--- a/drivers/iio/adc/qcom-spmi-vadc.c ++++ b/drivers/iio/adc/qcom-spmi-vadc.c +@@ -18,6 +18,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -471,11 +472,11 @@ static s32 vadc_calibrate(struct vadc_pr + const struct vadc_channel_prop *prop, u16 adc_code) + { + const struct vadc_prescale_ratio *prescale; +- s32 voltage; ++ s64 voltage; + + voltage = adc_code - vadc->graph[prop->calibration].gnd; + voltage *= vadc->graph[prop->calibration].dx; +- voltage = voltage / vadc->graph[prop->calibration].dy; ++ voltage = div64_s64(voltage, vadc->graph[prop->calibration].dy); + + if (prop->calibration == VADC_CALIB_ABSOLUTE) + voltage += vadc->graph[prop->calibration].dx; +@@ -487,7 +488,7 @@ static s32 vadc_calibrate(struct vadc_pr + + voltage = voltage * prescale->den; + +- return voltage / prescale->num; ++ return div64_s64(voltage, prescale->num); + } + + static int vadc_decimation_from_dt(u32 value) diff --git a/queue-4.0/iio-adc-xilinx-fix-register-addresses.patch b/queue-4.0/iio-adc-xilinx-fix-register-addresses.patch new file mode 100644 index 00000000000..da7564c9fdc --- /dev/null +++ b/queue-4.0/iio-adc-xilinx-fix-register-addresses.patch @@ -0,0 +1,35 @@ +From 3960d2c0c4aafe98da47a4a2eb64dfa8e88d8df5 Mon Sep 17 00:00:00 2001 +From: Thomas Betker +Date: Wed, 15 Apr 2015 21:11:47 +0200 +Subject: iio: adc: xilinx: Fix register addresses + +From: Thomas Betker + +commit 3960d2c0c4aafe98da47a4a2eb64dfa8e88d8df5 upstream. + +Define the register addresses for MIN_VCCPINT, MIN_VCCPAUX, MIN_VCCO_DDR +correctly. + +Signed-off-by: Thomas Betker +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/iio/adc/xilinx-xadc.h | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/iio/adc/xilinx-xadc.h ++++ b/drivers/iio/adc/xilinx-xadc.h +@@ -145,9 +145,9 @@ static inline int xadc_write_adc_reg(str + #define XADC_REG_MAX_VCCPINT 0x28 + #define XADC_REG_MAX_VCCPAUX 0x29 + #define XADC_REG_MAX_VCCO_DDR 0x2a +-#define XADC_REG_MIN_VCCPINT 0x2b +-#define XADC_REG_MIN_VCCPAUX 0x2c +-#define XADC_REG_MIN_VCCO_DDR 0x2d ++#define XADC_REG_MIN_VCCPINT 0x2c ++#define XADC_REG_MIN_VCCPAUX 0x2d ++#define XADC_REG_MIN_VCCO_DDR 0x2e + + #define XADC_REG_CONF0 0x40 + #define XADC_REG_CONF1 0x41 diff --git a/queue-4.0/iio-adc-xilinx-fix-vccaux-channel-.address.patch b/queue-4.0/iio-adc-xilinx-fix-vccaux-channel-.address.patch new file mode 100644 index 00000000000..4fc730af69f --- /dev/null +++ b/queue-4.0/iio-adc-xilinx-fix-vccaux-channel-.address.patch @@ -0,0 +1,30 @@ +From d6c96c42283601e311a7a1a3d7e51cde9d7fdb6e Mon Sep 17 00:00:00 2001 +From: Thomas Betker +Date: Wed, 15 Apr 2015 21:11:48 +0200 +Subject: iio: adc: xilinx: Fix "vccaux" channel .address + +From: Thomas Betker + +commit d6c96c42283601e311a7a1a3d7e51cde9d7fdb6e upstream. + +For the "vccaux" channel, read the VCCAUX register, not VCCINT. + +Signed-off-by: Thomas Betker +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/iio/adc/xilinx-xadc-core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/iio/adc/xilinx-xadc-core.c ++++ b/drivers/iio/adc/xilinx-xadc-core.c +@@ -1008,7 +1008,7 @@ static const struct iio_event_spec xadc_ + static const struct iio_chan_spec xadc_channels[] = { + XADC_CHAN_TEMP(0, 8, XADC_REG_TEMP), + XADC_CHAN_VOLTAGE(0, 9, XADC_REG_VCCINT, "vccint", true), +- XADC_CHAN_VOLTAGE(1, 10, XADC_REG_VCCINT, "vccaux", true), ++ XADC_CHAN_VOLTAGE(1, 10, XADC_REG_VCCAUX, "vccaux", true), + XADC_CHAN_VOLTAGE(2, 14, XADC_REG_VCCBRAM, "vccbram", true), + XADC_CHAN_VOLTAGE(3, 5, XADC_REG_VCCPINT, "vccpint", true), + XADC_CHAN_VOLTAGE(4, 6, XADC_REG_VCCPAUX, "vccpaux", true), diff --git a/queue-4.0/iio-adc-xilinx-fix-vrefn-sign.patch b/queue-4.0/iio-adc-xilinx-fix-vrefn-sign.patch new file mode 100644 index 00000000000..d12e630f131 --- /dev/null +++ b/queue-4.0/iio-adc-xilinx-fix-vrefn-sign.patch @@ -0,0 +1,32 @@ +From 97ffae1d30c3f6ceee67d5b0d3e540c08c13c744 Mon Sep 17 00:00:00 2001 +From: Thomas Betker +Date: Wed, 15 Apr 2015 21:11:50 +0200 +Subject: iio: adc: xilinx: Fix VREFN sign + +From: Thomas Betker + +commit 97ffae1d30c3f6ceee67d5b0d3e540c08c13c744 upstream. + +The VREFN channel is bipolar, not unipolar. Small negative values do +occur (e.g., -1mV), and unsigned conversion maps them incorrectly to +large positive values (about +1V), so fix this. + +Signed-off-by: Thomas Betker +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/iio/adc/xilinx-xadc-core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/iio/adc/xilinx-xadc-core.c ++++ b/drivers/iio/adc/xilinx-xadc-core.c +@@ -997,7 +997,7 @@ static const struct iio_event_spec xadc_ + .num_event_specs = (_alarm) ? ARRAY_SIZE(xadc_voltage_events) : 0, \ + .scan_index = (_scan_index), \ + .scan_type = { \ +- .sign = 'u', \ ++ .sign = ((_addr) == XADC_REG_VREFN) ? 's' : 'u', \ + .realbits = 12, \ + .storagebits = 16, \ + .shift = 4, \ diff --git a/queue-4.0/iio-adc-xilinx-fix-vrefp-scale.patch b/queue-4.0/iio-adc-xilinx-fix-vrefp-scale.patch new file mode 100644 index 00000000000..2f9c62dae95 --- /dev/null +++ b/queue-4.0/iio-adc-xilinx-fix-vrefp-scale.patch @@ -0,0 +1,30 @@ +From 00db4e52f4541965f7fda225eb458a75f892017b Mon Sep 17 00:00:00 2001 +From: Thomas Betker +Date: Wed, 15 Apr 2015 21:11:49 +0200 +Subject: iio: adc: xilinx: Fix VREFP scale + +From: Thomas Betker + +commit 00db4e52f4541965f7fda225eb458a75f892017b upstream. + +The scaling factor for VREFP is 3.0/4096, not 1.0/4096; fix this to get +correct readings. + +Signed-off-by: Thomas Betker +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/iio/adc/xilinx-xadc-core.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/iio/adc/xilinx-xadc-core.c ++++ b/drivers/iio/adc/xilinx-xadc-core.c +@@ -856,6 +856,7 @@ static int xadc_read_raw(struct iio_dev + switch (chan->address) { + case XADC_REG_VCCINT: + case XADC_REG_VCCAUX: ++ case XADC_REG_VREFP: + case XADC_REG_VCCBRAM: + case XADC_REG_VCCPINT: + case XADC_REG_VCCPAUX: diff --git a/queue-4.0/iio-axp288_adc-add-missing-channel-info-mask.patch b/queue-4.0/iio-axp288_adc-add-missing-channel-info-mask.patch new file mode 100644 index 00000000000..c6266afa995 --- /dev/null +++ b/queue-4.0/iio-axp288_adc-add-missing-channel-info-mask.patch @@ -0,0 +1,86 @@ +From d0716b0ea4ce11a13477163c14b26e180922ba51 Mon Sep 17 00:00:00 2001 +From: Jacob Pan +Date: Mon, 6 Apr 2015 11:38:20 -0700 +Subject: iio/axp288_adc: add missing channel info mask + +From: Jacob Pan + +commit d0716b0ea4ce11a13477163c14b26e180922ba51 upstream. + +Commit 65de7654d39c70c2b ("iio: iio: Fix iio_channel_read return if +channel havn't info") added a check for valid info masks. + +This patch adds missing channel info masks for all ADC channels. +Otherwise, iio_read_channel_raw() would return -EINVAL when called +by consumer drivers. + +Note that the change of _processed to _raw actually fixes an ABI abuse +in the original driver where it was used to avoid some special handling +rather than because it was correct. + +Signed-off-by: Jacob Pan +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/iio/adc/axp288_adc.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +--- a/drivers/iio/adc/axp288_adc.c ++++ b/drivers/iio/adc/axp288_adc.c +@@ -53,39 +53,42 @@ static const struct iio_chan_spec const + .channel = 0, + .address = AXP288_TS_ADC_H, + .datasheet_name = "TS_PIN", ++ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + }, { + .indexed = 1, + .type = IIO_TEMP, + .channel = 1, + .address = AXP288_PMIC_ADC_H, + .datasheet_name = "PMIC_TEMP", ++ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + }, { + .indexed = 1, + .type = IIO_TEMP, + .channel = 2, + .address = AXP288_GP_ADC_H, + .datasheet_name = "GPADC", ++ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + }, { + .indexed = 1, + .type = IIO_CURRENT, + .channel = 3, + .address = AXP20X_BATT_CHRG_I_H, + .datasheet_name = "BATT_CHG_I", +- .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), ++ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + }, { + .indexed = 1, + .type = IIO_CURRENT, + .channel = 4, + .address = AXP20X_BATT_DISCHRG_I_H, + .datasheet_name = "BATT_DISCHRG_I", +- .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), ++ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + }, { + .indexed = 1, + .type = IIO_VOLTAGE, + .channel = 5, + .address = AXP20X_BATT_V_H, + .datasheet_name = "BATT_V", +- .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), ++ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + }, + }; + +@@ -151,9 +154,6 @@ static int axp288_adc_read_raw(struct ii + chan->address)) + dev_err(&indio_dev->dev, "TS pin restore\n"); + break; +- case IIO_CHAN_INFO_PROCESSED: +- ret = axp288_adc_read_channel(val, chan->address, info->regmap); +- break; + default: + ret = -EINVAL; + } diff --git a/queue-4.0/iio-light-hid-sensor-prox-fix-modifier.patch b/queue-4.0/iio-light-hid-sensor-prox-fix-modifier.patch new file mode 100644 index 00000000000..eea435174a8 --- /dev/null +++ b/queue-4.0/iio-light-hid-sensor-prox-fix-modifier.patch @@ -0,0 +1,32 @@ +From c2aab3d58b96002555a3e70004f593b043830248 Mon Sep 17 00:00:00 2001 +From: Srinivas Pandruvada +Date: Tue, 14 Apr 2015 14:53:22 -0700 +Subject: iio: light: hid-sensor-prox: Fix modifier + +From: Srinivas Pandruvada + +commit c2aab3d58b96002555a3e70004f593b043830248 upstream. + +Currently in_proximity_(null)_raw is getting presented as raw sysfs +attribute. Same with the scan_elements. +The modifier doesn't apply to this channel. + +Signed-off-by: Srinivas Pandruvada +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/iio/light/hid-sensor-prox.c | 2 -- + 1 file changed, 2 deletions(-) + +--- a/drivers/iio/light/hid-sensor-prox.c ++++ b/drivers/iio/light/hid-sensor-prox.c +@@ -43,8 +43,6 @@ struct prox_state { + static const struct iio_chan_spec prox_channels[] = { + { + .type = IIO_PROXIMITY, +- .modified = 1, +- .channel2 = IIO_NO_MOD, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) | + BIT(IIO_CHAN_INFO_SCALE) | diff --git a/queue-4.0/iio-pressure-hid-sensor-press-fix-modifier.patch b/queue-4.0/iio-pressure-hid-sensor-press-fix-modifier.patch new file mode 100644 index 00000000000..cc55f719671 --- /dev/null +++ b/queue-4.0/iio-pressure-hid-sensor-press-fix-modifier.patch @@ -0,0 +1,30 @@ +From 964e2255f1d73fc0136bc206a78a1f86bdad72a7 Mon Sep 17 00:00:00 2001 +From: Srinivas Pandruvada +Date: Tue, 14 Apr 2015 14:54:18 -0700 +Subject: iio: pressure: hid-sensor-press: Fix modifier + +From: Srinivas Pandruvada + +commit 964e2255f1d73fc0136bc206a78a1f86bdad72a7 upstream. + +Fix "null" in the raw attribute and scan elements. + +Signed-off-by: Srinivas Pandruvada +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/iio/pressure/hid-sensor-press.c | 2 -- + 1 file changed, 2 deletions(-) + +--- a/drivers/iio/pressure/hid-sensor-press.c ++++ b/drivers/iio/pressure/hid-sensor-press.c +@@ -47,8 +47,6 @@ struct press_state { + static const struct iio_chan_spec press_channels[] = { + { + .type = IIO_PRESSURE, +- .modified = 1, +- .channel2 = IIO_NO_MOD, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) | + BIT(IIO_CHAN_INFO_SCALE) | diff --git a/queue-4.0/iio-st_sensors-fix-oops-when-probing-spi-devices.patch b/queue-4.0/iio-st_sensors-fix-oops-when-probing-spi-devices.patch new file mode 100644 index 00000000000..82c4a9ee493 --- /dev/null +++ b/queue-4.0/iio-st_sensors-fix-oops-when-probing-spi-devices.patch @@ -0,0 +1,80 @@ +From 8e71c04f863a1754f21b27fb8ecb773d680a0a80 Mon Sep 17 00:00:00 2001 +From: Alban Bedel +Date: Mon, 20 Apr 2015 13:57:18 +0200 +Subject: iio:st_sensors: Fix oops when probing SPI devices + +From: Alban Bedel + +commit 8e71c04f863a1754f21b27fb8ecb773d680a0a80 upstream. + +In SPI mode the transfer buffer is locked with a mutex. However this +mutex is only initilized after the probe, but some transfer needs to +be done in the probe. + +To fix this bug we move the mutex initialization at the beginning of +the device probe. + +Signed-off-by: Alban Bedel +Acked-by: Denis Ciocca +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/iio/accel/st_accel_core.c | 1 + + drivers/iio/common/st_sensors/st_sensors_core.c | 2 -- + drivers/iio/gyro/st_gyro_core.c | 1 + + drivers/iio/magnetometer/st_magn_core.c | 1 + + drivers/iio/pressure/st_pressure_core.c | 1 + + 5 files changed, 4 insertions(+), 2 deletions(-) + +--- a/drivers/iio/accel/st_accel_core.c ++++ b/drivers/iio/accel/st_accel_core.c +@@ -465,6 +465,7 @@ int st_accel_common_probe(struct iio_dev + + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->info = &accel_info; ++ mutex_init(&adata->tb.buf_lock); + + st_sensors_power_enable(indio_dev); + +--- a/drivers/iio/common/st_sensors/st_sensors_core.c ++++ b/drivers/iio/common/st_sensors/st_sensors_core.c +@@ -304,8 +304,6 @@ int st_sensors_init_sensor(struct iio_de + struct st_sensors_platform_data *of_pdata; + int err = 0; + +- mutex_init(&sdata->tb.buf_lock); +- + /* If OF/DT pdata exists, it will take precedence of anything else */ + of_pdata = st_sensors_of_probe(indio_dev->dev.parent, pdata); + if (of_pdata) +--- a/drivers/iio/gyro/st_gyro_core.c ++++ b/drivers/iio/gyro/st_gyro_core.c +@@ -317,6 +317,7 @@ int st_gyro_common_probe(struct iio_dev + + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->info = &gyro_info; ++ mutex_init(&gdata->tb.buf_lock); + + st_sensors_power_enable(indio_dev); + +--- a/drivers/iio/magnetometer/st_magn_core.c ++++ b/drivers/iio/magnetometer/st_magn_core.c +@@ -369,6 +369,7 @@ int st_magn_common_probe(struct iio_dev + + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->info = &magn_info; ++ mutex_init(&mdata->tb.buf_lock); + + st_sensors_power_enable(indio_dev); + +--- a/drivers/iio/pressure/st_pressure_core.c ++++ b/drivers/iio/pressure/st_pressure_core.c +@@ -417,6 +417,7 @@ int st_press_common_probe(struct iio_dev + + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->info = &press_info; ++ mutex_init(&press_data->tb.buf_lock); + + st_sensors_power_enable(indio_dev); + diff --git a/queue-4.0/lguest-fix-out-by-one-error-in-address-checking.patch b/queue-4.0/lguest-fix-out-by-one-error-in-address-checking.patch new file mode 100644 index 00000000000..34a4f636aef --- /dev/null +++ b/queue-4.0/lguest-fix-out-by-one-error-in-address-checking.patch @@ -0,0 +1,33 @@ +From 83a35114d0e4583e6b0ca39502e68b6a92e2910c Mon Sep 17 00:00:00 2001 +From: Rusty Russell +Date: Wed, 27 May 2015 10:59:26 +0930 +Subject: lguest: fix out-by-one error in address checking. + +From: Rusty Russell + +commit 83a35114d0e4583e6b0ca39502e68b6a92e2910c upstream. + +This bug has been there since day 1; addresses in the top guest physical +page weren't considered valid. You could map that page (the check in +check_gpte() is correct), but if a guest tried to put a pagetable there +we'd check that address manually when walking it, and kill the guest. + +Signed-off-by: Rusty Russell +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/lguest/core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/lguest/core.c ++++ b/drivers/lguest/core.c +@@ -173,7 +173,7 @@ static void unmap_switcher(void) + bool lguest_address_ok(const struct lguest *lg, + unsigned long addr, unsigned long len) + { +- return (addr+len) / PAGE_SIZE < lg->pfn_limit && (addr+len >= addr); ++ return addr+len <= lg->pfn_limit * PAGE_SIZE && (addr+len >= addr); + } + + /* diff --git a/queue-4.0/libceph-request-a-new-osdmap-if-lingering-request-maps-to-no-osd.patch b/queue-4.0/libceph-request-a-new-osdmap-if-lingering-request-maps-to-no-osd.patch new file mode 100644 index 00000000000..c80ccf1bbaf --- /dev/null +++ b/queue-4.0/libceph-request-a-new-osdmap-if-lingering-request-maps-to-no-osd.patch @@ -0,0 +1,94 @@ +From b0494532214bdfbf241e94fabab5dd46f7b82631 Mon Sep 17 00:00:00 2001 +From: Ilya Dryomov +Date: Mon, 11 May 2015 17:53:10 +0300 +Subject: libceph: request a new osdmap if lingering request maps to no osd + +From: Ilya Dryomov + +commit b0494532214bdfbf241e94fabab5dd46f7b82631 upstream. + +This commit does two things. First, if there are any homeless +lingering requests, we now request a new osdmap even if the osdmap that +is being processed brought no changes, i.e. if a given lingering +request turned homeless in one of the previous epochs and remained +homeless in the current epoch. Not doing so leaves us with a stale +osdmap and as a result we may miss our window for reestablishing the +watch and lose notifies. + +MON=1 OSD=1: + + # cat linger-needmap.sh + #!/bin/bash + rbd create --size 1 test + DEV=$(rbd map test) + ceph osd out 0 + rbd map dne/dne # obtain a new osdmap as a side effect (!) + sleep 1 + ceph osd in 0 + rbd resize --size 2 test + # rbd info test | grep size -> 2M + # blockdev --getsize $DEV -> 1M + +N.B.: Not obtaining a new osdmap in between "osd out" and "osd in" +above is enough to make it miss that resize notify, but that is a +bug^Wlimitation of ceph watch/notify v1. + +Second, homeless lingering requests are now kicked just like those +lingering requests whose mapping has changed. This is mainly to +recognize that a homeless lingering request makes no sense and to +preserve the invariant that a registered lingering request is not +sitting on any of r_req_lru_item lists. This spares us a WARN_ON, +which commit ba9d114ec557 ("libceph: clear r_req_lru_item in +__unregister_linger_request()") tried to fix the _wrong_ way. + +Signed-off-by: Ilya Dryomov +Reviewed-by: Sage Weil +Signed-off-by: Greg Kroah-Hartman + +--- + net/ceph/osd_client.c | 31 ++++++++++++++++++++----------- + 1 file changed, 20 insertions(+), 11 deletions(-) + +--- a/net/ceph/osd_client.c ++++ b/net/ceph/osd_client.c +@@ -2017,20 +2017,29 @@ static void kick_requests(struct ceph_os + err = __map_request(osdc, req, + force_resend || force_resend_writes); + dout("__map_request returned %d\n", err); +- if (err == 0) +- continue; /* no change and no osd was specified */ + if (err < 0) + continue; /* hrm! */ +- if (req->r_osd == NULL) { +- dout("tid %llu maps to no valid osd\n", req->r_tid); +- needmap++; /* request a newer map */ +- continue; +- } ++ if (req->r_osd == NULL || err > 0) { ++ if (req->r_osd == NULL) { ++ dout("lingering %p tid %llu maps to no osd\n", ++ req, req->r_tid); ++ /* ++ * A homeless lingering request makes ++ * no sense, as it's job is to keep ++ * a particular OSD connection open. ++ * Request a newer map and kick the ++ * request, knowing that it won't be ++ * resent until we actually get a map ++ * that can tell us where to send it. ++ */ ++ needmap++; ++ } + +- dout("kicking lingering %p tid %llu osd%d\n", req, req->r_tid, +- req->r_osd ? req->r_osd->o_osd : -1); +- __register_request(osdc, req); +- __unregister_linger_request(osdc, req); ++ dout("kicking lingering %p tid %llu osd%d\n", req, ++ req->r_tid, req->r_osd ? req->r_osd->o_osd : -1); ++ __register_request(osdc, req); ++ __unregister_linger_request(osdc, req); ++ } + } + reset_changed_osds(osdc); + mutex_unlock(&osdc->request_mutex); diff --git a/queue-4.0/mfd-da9052-fix-broken-regulator-probe.patch b/queue-4.0/mfd-da9052-fix-broken-regulator-probe.patch new file mode 100644 index 00000000000..2a8d4a44922 --- /dev/null +++ b/queue-4.0/mfd-da9052-fix-broken-regulator-probe.patch @@ -0,0 +1,82 @@ +From e0c21530fa91f119bfca19640a67380c6b14f12a Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Fri, 15 May 2015 16:27:40 +0200 +Subject: mfd: da9052: Fix broken regulator probe + +From: Johan Hovold + +commit e0c21530fa91f119bfca19640a67380c6b14f12a upstream. + +Fix broken probe of da9052 regulators, which since commit b3f6c73db732 +("mfd: da9052-core: Fix platform-device id collision") use a +non-deterministic platform-device id to retrieve static regulator +information. Fortunately, adequate error handling was in place so probe +would simply fail with an error message. + +Update the mfd-cell ids to be zero-based and use those to identify the +cells when probing the regulator devices. + +Fixes: b3f6c73db732 ("mfd: da9052-core: Fix platform-device id collision") +Signed-off-by: Johan Hovold +Acked-by: Bartlomiej Zolnierkiewicz +Reviewed-by: Mark Brown +Signed-off-by: Lee Jones +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/mfd/da9052-core.c | 8 ++++---- + drivers/regulator/da9052-regulator.c | 5 +++-- + 2 files changed, 7 insertions(+), 6 deletions(-) + +--- a/drivers/mfd/da9052-core.c ++++ b/drivers/mfd/da9052-core.c +@@ -433,6 +433,10 @@ EXPORT_SYMBOL_GPL(da9052_adc_read_temp); + static const struct mfd_cell da9052_subdev_info[] = { + { + .name = "da9052-regulator", ++ .id = 0, ++ }, ++ { ++ .name = "da9052-regulator", + .id = 1, + }, + { +@@ -484,10 +488,6 @@ static const struct mfd_cell da9052_subd + .id = 13, + }, + { +- .name = "da9052-regulator", +- .id = 14, +- }, +- { + .name = "da9052-onkey", + }, + { +--- a/drivers/regulator/da9052-regulator.c ++++ b/drivers/regulator/da9052-regulator.c +@@ -394,6 +394,7 @@ static inline struct da9052_regulator_in + + static int da9052_regulator_probe(struct platform_device *pdev) + { ++ const struct mfd_cell *cell = mfd_get_cell(pdev); + struct regulator_config config = { }; + struct da9052_regulator *regulator; + struct da9052 *da9052; +@@ -409,7 +410,7 @@ static int da9052_regulator_probe(struct + regulator->da9052 = da9052; + + regulator->info = find_regulator_info(regulator->da9052->chip_id, +- pdev->id); ++ cell->id); + if (regulator->info == NULL) { + dev_err(&pdev->dev, "invalid regulator ID specified\n"); + return -EINVAL; +@@ -419,7 +420,7 @@ static int da9052_regulator_probe(struct + config.driver_data = regulator; + config.regmap = da9052->regmap; + if (pdata && pdata->regulators) { +- config.init_data = pdata->regulators[pdev->id]; ++ config.init_data = pdata->regulators[cell->id]; + } else { + #ifdef CONFIG_OF + struct device_node *nproot = da9052->dev->of_node; diff --git a/queue-4.0/omfs-fix-sign-confusion-for-bitmap-loop-counter.patch b/queue-4.0/omfs-fix-sign-confusion-for-bitmap-loop-counter.patch new file mode 100644 index 00000000000..4300209658a --- /dev/null +++ b/queue-4.0/omfs-fix-sign-confusion-for-bitmap-loop-counter.patch @@ -0,0 +1,45 @@ +From c0345ee57d461343586b5e1e2f9c3c3766d07fe6 Mon Sep 17 00:00:00 2001 +From: Bob Copeland +Date: Thu, 28 May 2015 15:44:35 -0700 +Subject: omfs: fix sign confusion for bitmap loop counter + +From: Bob Copeland + +commit c0345ee57d461343586b5e1e2f9c3c3766d07fe6 upstream. + +The count variable is used to iterate down to (below) zero from the size +of the bitmap and handle the one-filling the remainder of the last +partial bitmap block. The loop conditional expects count to be signed +in order to detect when the final block is processed, after which count +goes negative. + +Unfortunately, a recent change made this unsigned along with some other +related fields. The result of is this is that during mount, +omfs_get_imap will overrun the bitmap array and corrupt memory unless +number of blocks happens to be a multiple of 8 * blocksize. + +Fix by changing count back to signed: it is guaranteed to fit in an s32 +without overflow due to an enforced limit on the number of blocks in the +filesystem. + +Signed-off-by: Bob Copeland +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + fs/omfs/inode.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/fs/omfs/inode.c ++++ b/fs/omfs/inode.c +@@ -306,7 +306,8 @@ static const struct super_operations omf + */ + static int omfs_get_imap(struct super_block *sb) + { +- unsigned int bitmap_size, count, array_size; ++ unsigned int bitmap_size, array_size; ++ int count; + struct omfs_sb_info *sbi = OMFS_SB(sb); + struct buffer_head *bh; + unsigned long **ptr; diff --git a/queue-4.0/ovl-don-t-remove-non-empty-opaque-directory.patch b/queue-4.0/ovl-don-t-remove-non-empty-opaque-directory.patch new file mode 100644 index 00000000000..419f35ec8a4 --- /dev/null +++ b/queue-4.0/ovl-don-t-remove-non-empty-opaque-directory.patch @@ -0,0 +1,61 @@ +From d377c5eb54dd05aeb3094b7740252d19ba7791f7 Mon Sep 17 00:00:00 2001 +From: Miklos Szeredi +Date: Thu, 14 May 2015 10:04:44 +0200 +Subject: ovl: don't remove non-empty opaque directory + +From: Miklos Szeredi + +commit d377c5eb54dd05aeb3094b7740252d19ba7791f7 upstream. + +When removing an opaque directory we can't just call rmdir() to check for +emptiness, because the directory will need to be replaced with a whiteout. +The replacement is done with RENAME_EXCHANGE, which doesn't check +emptiness. + +Solution is just to check emptiness by reading the directory. In the +future we could add a new rename flag to check for emptiness even for +RENAME_EXCHANGE to optimize this case. + +Reported-by: Vincent Batts +Signed-off-by: Miklos Szeredi +Tested-by: Jordi Pujol Palomer +Fixes: 263b4a0fee43 ("ovl: dont replace opaque dir") +Signed-off-by: Greg Kroah-Hartman + +--- + fs/overlayfs/dir.c | 24 +++++++++++++++++++----- + 1 file changed, 19 insertions(+), 5 deletions(-) + +--- a/fs/overlayfs/dir.c ++++ b/fs/overlayfs/dir.c +@@ -506,11 +506,25 @@ static int ovl_remove_and_whiteout(struc + struct dentry *opaquedir = NULL; + int err; + +- if (is_dir && OVL_TYPE_MERGE_OR_LOWER(ovl_path_type(dentry))) { +- opaquedir = ovl_check_empty_and_clear(dentry); +- err = PTR_ERR(opaquedir); +- if (IS_ERR(opaquedir)) +- goto out; ++ if (is_dir) { ++ if (OVL_TYPE_MERGE_OR_LOWER(ovl_path_type(dentry))) { ++ opaquedir = ovl_check_empty_and_clear(dentry); ++ err = PTR_ERR(opaquedir); ++ if (IS_ERR(opaquedir)) ++ goto out; ++ } else { ++ LIST_HEAD(list); ++ ++ /* ++ * When removing an empty opaque directory, then it ++ * makes no sense to replace it with an exact replica of ++ * itself. But emptiness still needs to be checked. ++ */ ++ err = ovl_check_empty_dir(dentry, &list); ++ ovl_cache_free(&list); ++ if (err) ++ goto out; ++ } + } + + err = ovl_lock_rename_workdir(workdir, upperdir); diff --git a/queue-4.0/ovl-mount-read-only-if-workdir-can-t-be-created.patch b/queue-4.0/ovl-mount-read-only-if-workdir-can-t-be-created.patch new file mode 100644 index 00000000000..9e5bcb9b478 --- /dev/null +++ b/queue-4.0/ovl-mount-read-only-if-workdir-can-t-be-created.patch @@ -0,0 +1,108 @@ +From cc6f67bcafcb6bbbb2d1be1603dcd95125a52800 Mon Sep 17 00:00:00 2001 +From: Miklos Szeredi +Date: Tue, 19 May 2015 14:30:12 +0200 +Subject: ovl: mount read-only if workdir can't be created + +From: Miklos Szeredi + +commit cc6f67bcafcb6bbbb2d1be1603dcd95125a52800 upstream. + +OpenWRT folks reported that overlayfs fails to mount if upper fs is full, +because workdir can't be created. Wordir creation can fail for various +other reasons too. + +There's no reason that the mount itself should fail, overlayfs can work +fine without a workdir, as long as the overlay isn't modified. + +So mount it read-only and don't allow remounting read-write. + +Add a couple of WARN_ON()s for the impossible case of workdir being used +despite being read-only. + +Reported-by: Bastian Bittorf +Signed-off-by: Miklos Szeredi +Signed-off-by: Greg Kroah-Hartman + +--- + fs/overlayfs/copy_up.c | 3 +++ + fs/overlayfs/dir.c | 9 +++++++++ + fs/overlayfs/super.c | 10 +++++----- + 3 files changed, 17 insertions(+), 5 deletions(-) + +--- a/fs/overlayfs/copy_up.c ++++ b/fs/overlayfs/copy_up.c +@@ -299,6 +299,9 @@ int ovl_copy_up_one(struct dentry *paren + struct cred *override_cred; + char *link = NULL; + ++ if (WARN_ON(!workdir)) ++ return -EROFS; ++ + ovl_path_upper(parent, &parentpath); + upperdir = parentpath.dentry; + +--- a/fs/overlayfs/dir.c ++++ b/fs/overlayfs/dir.c +@@ -222,6 +222,9 @@ static struct dentry *ovl_clear_empty(st + struct kstat stat; + int err; + ++ if (WARN_ON(!workdir)) ++ return ERR_PTR(-EROFS); ++ + err = ovl_lock_rename_workdir(workdir, upperdir); + if (err) + goto out; +@@ -322,6 +325,9 @@ static int ovl_create_over_whiteout(stru + struct dentry *newdentry; + int err; + ++ if (WARN_ON(!workdir)) ++ return -EROFS; ++ + err = ovl_lock_rename_workdir(workdir, upperdir); + if (err) + goto out; +@@ -506,6 +512,9 @@ static int ovl_remove_and_whiteout(struc + struct dentry *opaquedir = NULL; + int err; + ++ if (WARN_ON(!workdir)) ++ return -EROFS; ++ + if (is_dir) { + if (OVL_TYPE_MERGE_OR_LOWER(ovl_path_type(dentry))) { + opaquedir = ovl_check_empty_and_clear(dentry); +--- a/fs/overlayfs/super.c ++++ b/fs/overlayfs/super.c +@@ -529,7 +529,7 @@ static int ovl_remount(struct super_bloc + { + struct ovl_fs *ufs = sb->s_fs_info; + +- if (!(*flags & MS_RDONLY) && !ufs->upper_mnt) ++ if (!(*flags & MS_RDONLY) && (!ufs->upper_mnt || !ufs->workdir)) + return -EROFS; + + return 0; +@@ -925,9 +925,10 @@ static int ovl_fill_super(struct super_b + ufs->workdir = ovl_workdir_create(ufs->upper_mnt, workpath.dentry); + err = PTR_ERR(ufs->workdir); + if (IS_ERR(ufs->workdir)) { +- pr_err("overlayfs: failed to create directory %s/%s\n", +- ufs->config.workdir, OVL_WORKDIR_NAME); +- goto out_put_upper_mnt; ++ pr_warn("overlayfs: failed to create directory %s/%s (errno: %i); mounting read-only\n", ++ ufs->config.workdir, OVL_WORKDIR_NAME, -err); ++ sb->s_flags |= MS_RDONLY; ++ ufs->workdir = NULL; + } + } + +@@ -997,7 +998,6 @@ out_put_lower_mnt: + kfree(ufs->lower_mnt); + out_put_workdir: + dput(ufs->workdir); +-out_put_upper_mnt: + mntput(ufs->upper_mnt); + out_put_lowerpath: + for (i = 0; i < numlower; i++) diff --git a/queue-4.0/revert-libceph-clear-r_req_lru_item-in-__unregister_linger_request.patch b/queue-4.0/revert-libceph-clear-r_req_lru_item-in-__unregister_linger_request.patch new file mode 100644 index 00000000000..64940ebed5f --- /dev/null +++ b/queue-4.0/revert-libceph-clear-r_req_lru_item-in-__unregister_linger_request.patch @@ -0,0 +1,43 @@ +From 521a04d06a729e5971cdee7f84080387ed320527 Mon Sep 17 00:00:00 2001 +From: Ilya Dryomov +Date: Mon, 11 May 2015 17:53:34 +0300 +Subject: Revert "libceph: clear r_req_lru_item in __unregister_linger_request()" + +From: Ilya Dryomov + +commit 521a04d06a729e5971cdee7f84080387ed320527 upstream. + +This reverts commit ba9d114ec5578e6e99a4dfa37ff8ae688040fd64. + +.. which introduced a regression that prevented all lingering requests +requeued in kick_requests() from ever being sent to the OSDs, resulting +in a lot of missed notifies. In retrospect it's pretty obvious that +r_req_lru_item item in the case of lingering requests can be used not +only for notarget, but also for unsent linkage due to how tightly +actual map and enqueue operations are coupled in __map_request(). + +The assertion that was being silenced is taken care of in the previous +("libceph: request a new osdmap if lingering request maps to no osd") +commit: by always kicking homeless lingering requests we ensure that +none of them ends up on the notarget list outside of the critical +section guarded by request_mutex. + +Signed-off-by: Ilya Dryomov +Reviewed-by: Sage Weil +Signed-off-by: Greg Kroah-Hartman + +--- + net/ceph/osd_client.c | 2 -- + 1 file changed, 2 deletions(-) + +--- a/net/ceph/osd_client.c ++++ b/net/ceph/osd_client.c +@@ -1306,8 +1306,6 @@ static void __unregister_linger_request( + if (list_empty(&req->r_osd_item)) + req->r_osd = NULL; + } +- +- list_del_init(&req->r_req_lru_item); /* can be on notarget */ + ceph_osdc_put_request(req); + } + diff --git a/queue-4.0/series b/queue-4.0/series index ea061f51ede..bd6416f6c6c 100644 --- a/queue-4.0/series +++ b/queue-4.0/series @@ -11,3 +11,34 @@ kvm-fix-crash-in-kvm_vcpu_reload_apic_access_page.patch kvm-mmu-fix-smap-virtualization.patch kvm-fpu-enable-eager-restore-kvm-fpu-for-mpx.patch ktime-fix-ktime_divns-to-do-signed-division.patch +fs-omfs-add-null-terminator-in-the-end-up-the-token-list.patch +omfs-fix-sign-confusion-for-bitmap-loop-counter.patch +xfs-xfs_attr_inactive-leaves-inconsistent-attr-fork-state-behind.patch +xfs-xfs_iozero-can-return-positive-errno.patch +lguest-fix-out-by-one-error-in-address-checking.patch +ovl-don-t-remove-non-empty-opaque-directory.patch +ovl-mount-read-only-if-workdir-can-t-be-created.patch +mfd-da9052-fix-broken-regulator-probe.patch +libceph-request-a-new-osdmap-if-lingering-request-maps-to-no-osd.patch +revert-libceph-clear-r_req_lru_item-in-__unregister_linger_request.patch +btrfs-fix-racy-system-chunk-allocation-when-setting-block-group-ro.patch +xen-events-don-t-bind-non-percpu-virqs-with-percpu-chip.patch +hwmon-ntc_thermistor-ensure-iio-channel-is-of-type-iio_voltage.patch +iio-axp288_adc-add-missing-channel-info-mask.patch +iio-st_sensors-fix-oops-when-probing-spi-devices.patch +iio-light-hid-sensor-prox-fix-modifier.patch +iio-pressure-hid-sensor-press-fix-modifier.patch +iio-adc-spmi-vadc-fix-overflow-in-output-value.patch +iio-adc-cc10001-fix-the-channel-number-mapping.patch +iio-adc-cc10001-fix-incorrect-use-of-power-up-power-down-register.patch +iio-adc-cc10001-add-delay-before-setting-start-bit.patch +iio-adc-cc10001-fix-regulator_get_voltage-return-value-check.patch +iio-adc-xilinx-fix-register-addresses.patch +iio-adc-xilinx-fix-vccaux-channel-.address.patch +iio-adc-xilinx-fix-vrefp-scale.patch +iio-adc-xilinx-fix-vrefn-sign.patch +hwmon-tmp401-do-not-auto-detect-chip-on-i2c-address-0x37.patch +hwmon-nct6775-add-missing-sysfs-attribute-initialization.patch +hwmon-nct6683-add-missing-sysfs-attribute-initialization.patch +clk-exynos5420-restore-gate_bus_top-on-suspend.patch +clk-add-missing-lock-when-call-clk_core_enable-in-clk_set_parent.patch diff --git a/queue-4.0/xen-events-don-t-bind-non-percpu-virqs-with-percpu-chip.patch b/queue-4.0/xen-events-don-t-bind-non-percpu-virqs-with-percpu-chip.patch new file mode 100644 index 00000000000..44a9ef6a230 --- /dev/null +++ b/queue-4.0/xen-events-don-t-bind-non-percpu-virqs-with-percpu-chip.patch @@ -0,0 +1,92 @@ +From 77bb3dfdc0d554befad58fdefbc41be5bc3ed38a Mon Sep 17 00:00:00 2001 +From: David Vrabel +Date: Tue, 19 May 2015 18:40:49 +0100 +Subject: xen/events: don't bind non-percpu VIRQs with percpu chip + +From: David Vrabel + +commit 77bb3dfdc0d554befad58fdefbc41be5bc3ed38a upstream. + +A non-percpu VIRQ (e.g., VIRQ_CONSOLE) may be freed on a different +VCPU than it is bound to. This can result in a race between +handle_percpu_irq() and removing the action in __free_irq() because +handle_percpu_irq() does not take desc->lock. The interrupt handler +sees a NULL action and oopses. + +Only use the percpu chip/handler for per-CPU VIRQs (like VIRQ_TIMER). + + # cat /proc/interrupts | grep virq + 40: 87246 0 xen-percpu-virq timer0 + 44: 0 0 xen-percpu-virq debug0 + 47: 0 20995 xen-percpu-virq timer1 + 51: 0 0 xen-percpu-virq debug1 + 69: 0 0 xen-dyn-virq xen-pcpu + 74: 0 0 xen-dyn-virq mce + 75: 29 0 xen-dyn-virq hvc_console + +Signed-off-by: David Vrabel +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/tty/hvc/hvc_xen.c | 2 +- + drivers/xen/events/events_base.c | 12 ++++++++---- + include/xen/events.h | 2 +- + 3 files changed, 10 insertions(+), 6 deletions(-) + +--- a/drivers/tty/hvc/hvc_xen.c ++++ b/drivers/tty/hvc/hvc_xen.c +@@ -289,7 +289,7 @@ static int xen_initial_domain_console_in + return -ENOMEM; + } + +- info->irq = bind_virq_to_irq(VIRQ_CONSOLE, 0); ++ info->irq = bind_virq_to_irq(VIRQ_CONSOLE, 0, false); + info->vtermno = HVC_COOKIE; + + spin_lock(&xencons_lock); +--- a/drivers/xen/events/events_base.c ++++ b/drivers/xen/events/events_base.c +@@ -957,7 +957,7 @@ unsigned xen_evtchn_nr_channels(void) + } + EXPORT_SYMBOL_GPL(xen_evtchn_nr_channels); + +-int bind_virq_to_irq(unsigned int virq, unsigned int cpu) ++int bind_virq_to_irq(unsigned int virq, unsigned int cpu, bool percpu) + { + struct evtchn_bind_virq bind_virq; + int evtchn, irq, ret; +@@ -971,8 +971,12 @@ int bind_virq_to_irq(unsigned int virq, + if (irq < 0) + goto out; + +- irq_set_chip_and_handler_name(irq, &xen_percpu_chip, +- handle_percpu_irq, "virq"); ++ if (percpu) ++ irq_set_chip_and_handler_name(irq, &xen_percpu_chip, ++ handle_percpu_irq, "virq"); ++ else ++ irq_set_chip_and_handler_name(irq, &xen_dynamic_chip, ++ handle_edge_irq, "virq"); + + bind_virq.virq = virq; + bind_virq.vcpu = cpu; +@@ -1062,7 +1066,7 @@ int bind_virq_to_irqhandler(unsigned int + { + int irq, retval; + +- irq = bind_virq_to_irq(virq, cpu); ++ irq = bind_virq_to_irq(virq, cpu, irqflags & IRQF_PERCPU); + if (irq < 0) + return irq; + retval = request_irq(irq, handler, irqflags, devname, dev_id); +--- a/include/xen/events.h ++++ b/include/xen/events.h +@@ -17,7 +17,7 @@ int bind_evtchn_to_irqhandler(unsigned i + irq_handler_t handler, + unsigned long irqflags, const char *devname, + void *dev_id); +-int bind_virq_to_irq(unsigned int virq, unsigned int cpu); ++int bind_virq_to_irq(unsigned int virq, unsigned int cpu, bool percpu); + int bind_virq_to_irqhandler(unsigned int virq, unsigned int cpu, + irq_handler_t handler, + unsigned long irqflags, const char *devname, diff --git a/queue-4.0/xfs-xfs_attr_inactive-leaves-inconsistent-attr-fork-state-behind.patch b/queue-4.0/xfs-xfs_attr_inactive-leaves-inconsistent-attr-fork-state-behind.patch new file mode 100644 index 00000000000..2ed98d0138d --- /dev/null +++ b/queue-4.0/xfs-xfs_attr_inactive-leaves-inconsistent-attr-fork-state-behind.patch @@ -0,0 +1,235 @@ +From 6dfe5a049f2d48582050339d2a6b6fda36dfd14c Mon Sep 17 00:00:00 2001 +From: Dave Chinner +Date: Fri, 29 May 2015 07:40:08 +1000 +Subject: xfs: xfs_attr_inactive leaves inconsistent attr fork state behind + +From: Dave Chinner + +commit 6dfe5a049f2d48582050339d2a6b6fda36dfd14c upstream. + +xfs_attr_inactive() is supposed to clean up the attribute fork when +the inode is being freed. While it removes attribute fork extents, +it completely ignores attributes in local format, which means that +there can still be active attributes on the inode after +xfs_attr_inactive() has run. + +This leads to problems with concurrent inode writeback - the in-core +inode attribute fork is removed without locking on the assumption +that nothing will be attempting to access the attribute fork after a +call to xfs_attr_inactive() because it isn't supposed to exist on +disk any more. + +To fix this, make xfs_attr_inactive() completely remove all traces +of the attribute fork from the inode, regardless of it's state. +Further, also remove the in-core attribute fork structure safely so +that there is nothing further that needs to be done by callers to +clean up the attribute fork. This means we can remove the in-core +and on-disk attribute forks atomically. + +Also, on error simply remove the in-memory attribute fork. There's +nothing that can be done with it once we have failed to remove the +on-disk attribute fork, so we may as well just blow it away here +anyway. + +Reported-by: Waiman Long +Signed-off-by: Dave Chinner +Reviewed-by: Brian Foster +Signed-off-by: Dave Chinner +Signed-off-by: Greg Kroah-Hartman + +--- + fs/xfs/libxfs/xfs_attr_leaf.c | 8 ++-- + fs/xfs/libxfs/xfs_attr_leaf.h | 2 - + fs/xfs/xfs_attr_inactive.c | 83 ++++++++++++++++++++++++------------------ + fs/xfs/xfs_inode.c | 12 ++---- + 4 files changed, 58 insertions(+), 47 deletions(-) + +--- a/fs/xfs/libxfs/xfs_attr_leaf.c ++++ b/fs/xfs/libxfs/xfs_attr_leaf.c +@@ -498,8 +498,8 @@ xfs_attr_shortform_add(xfs_da_args_t *ar + * After the last attribute is removed revert to original inode format, + * making all literal area available to the data fork once more. + */ +-STATIC void +-xfs_attr_fork_reset( ++void ++xfs_attr_fork_remove( + struct xfs_inode *ip, + struct xfs_trans *tp) + { +@@ -565,7 +565,7 @@ xfs_attr_shortform_remove(xfs_da_args_t + (mp->m_flags & XFS_MOUNT_ATTR2) && + (dp->i_d.di_format != XFS_DINODE_FMT_BTREE) && + !(args->op_flags & XFS_DA_OP_ADDNAME)) { +- xfs_attr_fork_reset(dp, args->trans); ++ xfs_attr_fork_remove(dp, args->trans); + } else { + xfs_idata_realloc(dp, -size, XFS_ATTR_FORK); + dp->i_d.di_forkoff = xfs_attr_shortform_bytesfit(dp, totsize); +@@ -828,7 +828,7 @@ xfs_attr3_leaf_to_shortform( + if (forkoff == -1) { + ASSERT(dp->i_mount->m_flags & XFS_MOUNT_ATTR2); + ASSERT(dp->i_d.di_format != XFS_DINODE_FMT_BTREE); +- xfs_attr_fork_reset(dp, args->trans); ++ xfs_attr_fork_remove(dp, args->trans); + goto out; + } + +--- a/fs/xfs/libxfs/xfs_attr_leaf.h ++++ b/fs/xfs/libxfs/xfs_attr_leaf.h +@@ -53,7 +53,7 @@ int xfs_attr_shortform_remove(struct xfs + int xfs_attr_shortform_list(struct xfs_attr_list_context *context); + int xfs_attr_shortform_allfit(struct xfs_buf *bp, struct xfs_inode *dp); + int xfs_attr_shortform_bytesfit(xfs_inode_t *dp, int bytes); +- ++void xfs_attr_fork_remove(struct xfs_inode *ip, struct xfs_trans *tp); + + /* + * Internal routines when attribute fork size == XFS_LBSIZE(mp). +--- a/fs/xfs/xfs_attr_inactive.c ++++ b/fs/xfs/xfs_attr_inactive.c +@@ -379,23 +379,31 @@ xfs_attr3_root_inactive( + return error; + } + ++/* ++ * xfs_attr_inactive kills all traces of an attribute fork on an inode. It ++ * removes both the on-disk and in-memory inode fork. Note that this also has to ++ * handle the condition of inodes without attributes but with an attribute fork ++ * configured, so we can't use xfs_inode_hasattr() here. ++ * ++ * The in-memory attribute fork is removed even on error. ++ */ + int +-xfs_attr_inactive(xfs_inode_t *dp) ++xfs_attr_inactive( ++ struct xfs_inode *dp) + { +- xfs_trans_t *trans; +- xfs_mount_t *mp; +- int error; ++ struct xfs_trans *trans; ++ struct xfs_mount *mp; ++ int cancel_flags = 0; ++ int lock_mode = XFS_ILOCK_SHARED; ++ int error = 0; + + mp = dp->i_mount; + ASSERT(! XFS_NOT_DQATTACHED(mp, dp)); + +- xfs_ilock(dp, XFS_ILOCK_SHARED); +- if (!xfs_inode_hasattr(dp) || +- dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) { +- xfs_iunlock(dp, XFS_ILOCK_SHARED); +- return 0; +- } +- xfs_iunlock(dp, XFS_ILOCK_SHARED); ++ xfs_ilock(dp, lock_mode); ++ if (!XFS_IFORK_Q(dp)) ++ goto out_destroy_fork; ++ xfs_iunlock(dp, lock_mode); + + /* + * Start our first transaction of the day. +@@ -407,13 +415,18 @@ xfs_attr_inactive(xfs_inode_t *dp) + * the inode in every transaction to let it float upward through + * the log. + */ ++ lock_mode = 0; + trans = xfs_trans_alloc(mp, XFS_TRANS_ATTRINVAL); + error = xfs_trans_reserve(trans, &M_RES(mp)->tr_attrinval, 0, 0); +- if (error) { +- xfs_trans_cancel(trans, 0); +- return error; +- } +- xfs_ilock(dp, XFS_ILOCK_EXCL); ++ if (error) ++ goto out_cancel; ++ ++ lock_mode = XFS_ILOCK_EXCL; ++ cancel_flags = XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT; ++ xfs_ilock(dp, lock_mode); ++ ++ if (!XFS_IFORK_Q(dp)) ++ goto out_cancel; + + /* + * No need to make quota reservations here. We expect to release some +@@ -421,29 +434,31 @@ xfs_attr_inactive(xfs_inode_t *dp) + */ + xfs_trans_ijoin(trans, dp, 0); + +- /* +- * Decide on what work routines to call based on the inode size. +- */ +- if (!xfs_inode_hasattr(dp) || +- dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) { +- error = 0; +- goto out; ++ /* invalidate and truncate the attribute fork extents */ ++ if (dp->i_d.di_aformat != XFS_DINODE_FMT_LOCAL) { ++ error = xfs_attr3_root_inactive(&trans, dp); ++ if (error) ++ goto out_cancel; ++ ++ error = xfs_itruncate_extents(&trans, dp, XFS_ATTR_FORK, 0); ++ if (error) ++ goto out_cancel; + } +- error = xfs_attr3_root_inactive(&trans, dp); +- if (error) +- goto out; + +- error = xfs_itruncate_extents(&trans, dp, XFS_ATTR_FORK, 0); +- if (error) +- goto out; ++ /* Reset the attribute fork - this also destroys the in-core fork */ ++ xfs_attr_fork_remove(dp, trans); + + error = xfs_trans_commit(trans, XFS_TRANS_RELEASE_LOG_RES); +- xfs_iunlock(dp, XFS_ILOCK_EXCL); +- ++ xfs_iunlock(dp, lock_mode); + return error; + +-out: +- xfs_trans_cancel(trans, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_ABORT); +- xfs_iunlock(dp, XFS_ILOCK_EXCL); ++out_cancel: ++ xfs_trans_cancel(trans, cancel_flags); ++out_destroy_fork: ++ /* kill the in-core attr fork before we drop the inode lock */ ++ if (dp->i_afp) ++ xfs_idestroy_fork(dp, XFS_ATTR_FORK); ++ if (lock_mode) ++ xfs_iunlock(dp, lock_mode); + return error; + } +--- a/fs/xfs/xfs_inode.c ++++ b/fs/xfs/xfs_inode.c +@@ -1889,21 +1889,17 @@ xfs_inactive( + /* + * If there are attributes associated with the file then blow them away + * now. The code calls a routine that recursively deconstructs the +- * attribute fork. We need to just commit the current transaction +- * because we can't use it for xfs_attr_inactive(). ++ * attribute fork. If also blows away the in-core attribute fork. + */ +- if (ip->i_d.di_anextents > 0) { +- ASSERT(ip->i_d.di_forkoff != 0); +- ++ if (XFS_IFORK_Q(ip)) { + error = xfs_attr_inactive(ip); + if (error) + return; + } + +- if (ip->i_afp) +- xfs_idestroy_fork(ip, XFS_ATTR_FORK); +- ++ ASSERT(!ip->i_afp); + ASSERT(ip->i_d.di_anextents == 0); ++ ASSERT(ip->i_d.di_forkoff == 0); + + /* + * Free the inode. diff --git a/queue-4.0/xfs-xfs_iozero-can-return-positive-errno.patch b/queue-4.0/xfs-xfs_iozero-can-return-positive-errno.patch new file mode 100644 index 00000000000..21ecd378572 --- /dev/null +++ b/queue-4.0/xfs-xfs_iozero-can-return-positive-errno.patch @@ -0,0 +1,35 @@ +From cddc116228cb9d51d3224d23ba3e61fbbc3ec3d2 Mon Sep 17 00:00:00 2001 +From: Dave Chinner +Date: Fri, 29 May 2015 07:40:32 +1000 +Subject: xfs: xfs_iozero can return positive errno + +From: Dave Chinner + +commit cddc116228cb9d51d3224d23ba3e61fbbc3ec3d2 upstream. + +It was missed when we converted everything in XFs to use negative error +numbers, so fix it now. Bug introduced in 3.17 by commit 2451337 ("xfs: global +error sign conversion"), and should go back to stable kernels. + +Thanks to Brian Foster for noticing it. + +Signed-off-by: Dave Chinner +Reviewed-by: Brian Foster +Signed-off-by: Dave Chinner +Signed-off-by: Greg Kroah-Hartman + +--- + fs/xfs/xfs_file.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/xfs/xfs_file.c ++++ b/fs/xfs/xfs_file.c +@@ -125,7 +125,7 @@ xfs_iozero( + status = 0; + } while (count); + +- return (-status); ++ return status; + } + + int