This is an automatic generated email to let you know that the following patch were queued:
Subject: media: em28xx: use a default format if TRY_FMT fails
Author: Mauro Carvalho Chehab <mchehab+samsung(a)kernel.org>
Date: Thu Sep 13 23:22:40 2018 -0400
Follow the V4L2 spec, as warned by v4l2-compliance:
warn: v4l2-test-formats.cpp(732): TRY_FMT cannot handle an invalid pixelformat.
warn: v4l2-test-formats.cpp(733): This may or may not be a problem. For more information see:
warn: v4l2-test-formats.cpp(734): http://www.mail-archive.com/linux-media@vger.kernel.org/msg56550.html
Cc: stable(a)vger.kernel.org
Fixes: bddcf63313c6 ("V4L/DVB (9927): em28xx: use a more standard way to specify video formats")
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung(a)kernel.org>
drivers/media/usb/em28xx/em28xx-video.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
---
diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c
index fbdfe6762cb2..4b08da45032d 100644
--- a/drivers/media/usb/em28xx/em28xx-video.c
+++ b/drivers/media/usb/em28xx/em28xx-video.c
@@ -1471,9 +1471,9 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
fmt = format_by_fourcc(f->fmt.pix.pixelformat);
if (!fmt) {
- em28xx_videodbg("Fourcc format (%08x) invalid.\n",
- f->fmt.pix.pixelformat);
- return -EINVAL;
+ fmt = &format[0];
+ em28xx_videodbg("Fourcc format (%08x) invalid. Using default (%08x).\n",
+ f->fmt.pix.pixelformat, fmt->fourcc);
}
if (dev->board.is_em2800) {
This is an automatic generated email to let you know that the following patch were queued:
Subject: media: em28xx: fix handler for vidioc_s_input()
Author: Mauro Carvalho Chehab <mchehab+samsung(a)kernel.org>
Date: Fri Sep 14 13:13:15 2018 -0400
The a->index is not the name of the internal amux entry,
but, instead a value from zero to the maximum number
of audio inputs.
As the actual available inputs depend on each board, build
it dynamically.
This is broken for a really long time. On a quick check,
since at least commit 195a4ef627e1 ("V4L/DVB (6585): Convert
em28xx to video_ioctl2") this was not implemented right.
Fixes: 195a4ef627e1 ("V4L/DVB (6585): Convert em28xx to video_ioctl2")
Cc: stable(a)vger.kernel.org
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung(a)kernel.org>
drivers/media/usb/em28xx/em28xx-cards.c | 29 ++++++++++++
drivers/media/usb/em28xx/em28xx-video.c | 84 +++++++++++++++++++++++++++++----
drivers/media/usb/em28xx/em28xx.h | 8 +++-
3 files changed, 112 insertions(+), 9 deletions(-)
---
diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c
index 71c829f31d3b..06a7e09ded6e 100644
--- a/drivers/media/usb/em28xx/em28xx-cards.c
+++ b/drivers/media/usb/em28xx/em28xx-cards.c
@@ -3039,6 +3039,9 @@ static int em28xx_hint_board(struct em28xx *dev)
static void em28xx_card_setup(struct em28xx *dev)
{
+ int i, j, idx;
+ bool duplicate_entry;
+
/*
* If the device can be a webcam, seek for a sensor.
* If sensor is not found, then it isn't a webcam.
@@ -3195,6 +3198,32 @@ static void em28xx_card_setup(struct em28xx *dev)
/* Allow override tuner type by a module parameter */
if (tuner >= 0)
dev->tuner_type = tuner;
+
+ /*
+ * Dynamically generate a list of valid audio inputs for this
+ * specific board, mapping them via enum em28xx_amux.
+ */
+
+ idx = 0;
+ for (i = 0; i < MAX_EM28XX_INPUT; i++) {
+ if (!INPUT(i)->type)
+ continue;
+
+ /* Skip already mapped audio inputs */
+ duplicate_entry = false;
+ for (j = 0; j < idx; j++) {
+ if (INPUT(i)->amux == dev->amux_map[j]) {
+ duplicate_entry = true;
+ break;
+ }
+ }
+ if (duplicate_entry)
+ continue;
+
+ dev->amux_map[idx++] = INPUT(i)->amux;
+ }
+ for (; idx < MAX_EM28XX_INPUT; idx++)
+ dev->amux_map[idx] = EM28XX_AMUX_UNUSED;
}
void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl)
diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c
index 917602954bfb..fbdfe6762cb2 100644
--- a/drivers/media/usb/em28xx/em28xx-video.c
+++ b/drivers/media/usb/em28xx/em28xx-video.c
@@ -1666,6 +1666,7 @@ static int vidioc_enum_input(struct file *file, void *priv,
{
struct em28xx *dev = video_drvdata(file);
unsigned int n;
+ int j;
n = i->index;
if (n >= MAX_EM28XX_INPUT)
@@ -1685,6 +1686,12 @@ static int vidioc_enum_input(struct file *file, void *priv,
if (dev->is_webcam)
i->capabilities = 0;
+ /* Dynamically generates an audioset bitmask */
+ i->audioset = 0;
+ for (j = 0; j < MAX_EM28XX_INPUT; j++)
+ if (dev->amux_map[j] != EM28XX_AMUX_UNUSED)
+ i->audioset |= 1 << j;
+
return 0;
}
@@ -1710,11 +1717,24 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
return 0;
}
-static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
+static int em28xx_fill_audio_input(struct em28xx *dev,
+ const char *s,
+ struct v4l2_audio *a,
+ unsigned int index)
{
- struct em28xx *dev = video_drvdata(file);
+ unsigned int idx = dev->amux_map[index];
- switch (a->index) {
+ /*
+ * With msp3400, almost all mappings use the default (amux = 0).
+ * The only one may use a different value is WinTV USB2, where it
+ * can also be SCART1 input.
+ * As it is very doubtful that we would see new boards with msp3400,
+ * let's just reuse the existing switch.
+ */
+ if (dev->has_msp34xx && idx != EM28XX_AMUX_UNUSED)
+ idx = EM28XX_AMUX_LINE_IN;
+
+ switch (idx) {
case EM28XX_AMUX_VIDEO:
strscpy(a->name, "Television", sizeof(a->name));
break;
@@ -1739,32 +1759,79 @@ static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
case EM28XX_AMUX_PCM_OUT:
strscpy(a->name, "PCM", sizeof(a->name));
break;
+ case EM28XX_AMUX_UNUSED:
default:
return -EINVAL;
}
-
- a->index = dev->ctl_ainput;
+ a->index = index;
a->capability = V4L2_AUDCAP_STEREO;
+ em28xx_videodbg("%s: audio input index %d is '%s'\n",
+ s, a->index, a->name);
+
return 0;
}
+static int vidioc_enumaudio(struct file *file, void *fh, struct v4l2_audio *a)
+{
+ struct em28xx *dev = video_drvdata(file);
+
+ if (a->index >= MAX_EM28XX_INPUT)
+ return -EINVAL;
+
+ return em28xx_fill_audio_input(dev, __func__, a, a->index);
+}
+
+static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
+{
+ struct em28xx *dev = video_drvdata(file);
+ int i;
+
+ for (i = 0; i < MAX_EM28XX_INPUT; i++)
+ if (dev->ctl_ainput == dev->amux_map[i])
+ return em28xx_fill_audio_input(dev, __func__, a, i);
+
+ /* Should never happen! */
+ return -EINVAL;
+}
+
static int vidioc_s_audio(struct file *file, void *priv,
const struct v4l2_audio *a)
{
struct em28xx *dev = video_drvdata(file);
+ int idx, i;
if (a->index >= MAX_EM28XX_INPUT)
return -EINVAL;
- if (!INPUT(a->index)->type)
+
+ idx = dev->amux_map[a->index];
+
+ if (idx == EM28XX_AMUX_UNUSED)
+ return -EINVAL;
+
+ dev->ctl_ainput = idx;
+
+ /*
+ * FIXME: This is wrong, as different inputs at em28xx_cards
+ * may have different audio outputs. So, the right thing
+ * to do is to implement VIDIOC_G_AUDOUT/VIDIOC_S_AUDOUT.
+ * With the current board definitions, this would work fine,
+ * as, currently, all boards fit.
+ */
+ for (i = 0; i < MAX_EM28XX_INPUT; i++)
+ if (idx == dev->amux_map[i])
+ break;
+ if (i == MAX_EM28XX_INPUT)
return -EINVAL;
- dev->ctl_ainput = INPUT(a->index)->amux;
- dev->ctl_aoutput = INPUT(a->index)->aout;
+ dev->ctl_aoutput = INPUT(i)->aout;
if (!dev->ctl_aoutput)
dev->ctl_aoutput = EM28XX_AOUT_MASTER;
+ em28xx_videodbg("%s: set audio input to %d\n", __func__,
+ dev->ctl_ainput);
+
return 0;
}
@@ -2302,6 +2369,7 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
.vidioc_try_fmt_vbi_cap = vidioc_g_fmt_vbi_cap,
.vidioc_s_fmt_vbi_cap = vidioc_g_fmt_vbi_cap,
.vidioc_enum_framesizes = vidioc_enum_framesizes,
+ .vidioc_enumaudio = vidioc_enumaudio,
.vidioc_g_audio = vidioc_g_audio,
.vidioc_s_audio = vidioc_s_audio,
diff --git a/drivers/media/usb/em28xx/em28xx.h b/drivers/media/usb/em28xx/em28xx.h
index 953caac025f2..a551072e62ed 100644
--- a/drivers/media/usb/em28xx/em28xx.h
+++ b/drivers/media/usb/em28xx/em28xx.h
@@ -335,6 +335,9 @@ enum em28xx_usb_audio_type {
/**
* em28xx_amux - describes the type of audio input used by em28xx
*
+ * @EM28XX_AMUX_UNUSED:
+ * Used only on em28xx dev->map field, in order to mark an entry
+ * as unused.
* @EM28XX_AMUX_VIDEO:
* On devices without AC97, this is the only value that it is currently
* allowed.
@@ -369,7 +372,8 @@ enum em28xx_usb_audio_type {
* same time, via the alsa mux.
*/
enum em28xx_amux {
- EM28XX_AMUX_VIDEO,
+ EM28XX_AMUX_UNUSED = -1,
+ EM28XX_AMUX_VIDEO = 0,
EM28XX_AMUX_LINE_IN,
/* Some less-common mixer setups */
@@ -692,6 +696,8 @@ struct em28xx {
unsigned int ctl_input; // selected input
unsigned int ctl_ainput;// selected audio input
unsigned int ctl_aoutput;// selected audio output
+ enum em28xx_amux amux_map[MAX_EM28XX_INPUT];
+
int mute;
int volume;
Sync syscall to DAX file needs to flush processor cache, but it
currently does not flush to existing DAX files. This is because
'ext2_da_aops' is set to address_space_operations of existing DAX
files, instead of 'ext2_dax_aops', since S_DAX flag is set after
ext2_set_aops() in the open path.
Similar to ext4, change ext2_iget() to initialize i_flags before
ext2_set_aops().
Fixes: fb094c90748f ("ext2, dax: introduce ext2_dax_aops")
Signed-off-by: Toshi Kani <toshi.kani(a)hpe.com>
Suggested-by: Jan Kara <jack(a)suse.cz>
Cc: Jan Kara <jack(a)suse.cz>
Cc: Dan Williams <dan.j.williams(a)intel.com>
Cc: "Theodore Ts'o" <tytso(a)mit.edu>
Cc: Andreas Dilger <adilger.kernel(a)dilger.ca>
Cc: <stable(a)vger.kernel.org>
---
fs/ext2/inode.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c
index 7f7ee18fe179..e4bb9386c045 100644
--- a/fs/ext2/inode.c
+++ b/fs/ext2/inode.c
@@ -1448,6 +1448,7 @@ struct inode *ext2_iget (struct super_block *sb, unsigned long ino)
}
inode->i_blocks = le32_to_cpu(raw_inode->i_blocks);
ei->i_flags = le32_to_cpu(raw_inode->i_flags);
+ ext2_set_inode_flags(inode);
ei->i_faddr = le32_to_cpu(raw_inode->i_faddr);
ei->i_frag_no = raw_inode->i_frag;
ei->i_frag_size = raw_inode->i_fsize;
@@ -1517,7 +1518,6 @@ struct inode *ext2_iget (struct super_block *sb, unsigned long ino)
new_decode_dev(le32_to_cpu(raw_inode->i_block[1])));
}
brelse (bh);
- ext2_set_inode_flags(inode);
unlock_new_inode(inode);
return inode;
The current code only frees N-1 gpios if an error occurs during
gpiod_set_transitory, gpiod_direction_output or gpiod_direction_input.
Leading to gpios that cannot be used by userspace nor other drivers.
Cc: Timur Tabi <timur(a)codeaurora.org>
Cc: stable(a)vger.kernel.org
Fixes: ab3dbcf78f60f46d ("gpioib: do not free unrequested descriptors)
Signed-off-by: Ricardo Ribalda Delgado <ricardo.ribalda(a)gmail.com>
---
drivers/gpio/gpiolib.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index e8f8a1999393..a57300c1d649 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -571,7 +571,7 @@ static int linehandle_create(struct gpio_device *gdev, void __user *ip)
if (ret)
goto out_free_descs;
lh->descs[i] = desc;
- count = i;
+ count = i + 1;
if (lflags & GPIOHANDLE_REQUEST_ACTIVE_LOW)
set_bit(FLAG_ACTIVE_LOW, &desc->flags);
--
2.18.0
While at first mtd_part_of_parse() would just call
of_get_chil_by_name(), it has been edited to first try to get the OF
node thanks to mtd_get_of_node() and fallback on
of_get_child_by_name().
A of_node_put() was a bit below in the code, to balance the
of_get_child_by_name(). However, despite its name, mtd_get_of_node()
does not take a reference on the OF node. It is a simple helper hiding
some pointer logic to retrieve the OF node related to an MTD
device. People often used it this way:
of_node_put(mtd_get_of_node(<mtd>)).
The direct effect of such unbalanced reference counting is visible by
rmmod'ing any module that would have added MTD partitions:
OF: ERROR: Bad of_node_put() on <of_path_to_partition>
As it seems normal to get a reference on the OF node during the
of_property_for_each_string() that follows, add a call to
of_node_get() when relevant.
Fixes: 76a832254ab0 ("mtd: partitions: use DT info for parsing partitions with "compatible" prop")
Cc: stable(a)vger.kernel.org
Signed-off-by: Miquel Raynal <miquel.raynal(a)bootlin.com>
---
drivers/mtd/mtdpart.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index 52e2cb35fc79..99c460facd5e 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -873,8 +873,11 @@ static int mtd_part_of_parse(struct mtd_info *master,
int ret, err = 0;
np = mtd_get_of_node(master);
- if (!mtd_is_partition(master))
+ if (mtd_is_partition(master))
+ of_node_get(np);
+ else
np = of_get_child_by_name(np, "partitions");
+
of_property_for_each_string(np, "compatible", prop, compat) {
parser = mtd_part_get_compatible_parser(compat);
if (!parser)
--
2.17.1
As documented in spi-mem.h, spi_mem_op->data.buf.{in,out} must be
DMA-able, and commit 4120f8d158ef ("mtd: spi-nor: Use the spi_mem_xx()
API") failed to follow this rule as buffers passed to
->{read,write}_reg() are usually placed on the stack.
Fix that by allocating a scratch buffer and copying the data in there
before passing it to the spi-mem layer.
Fixes: 4120f8d158ef ("mtd: spi-nor: Use the spi_mem_xx() API")
Reported-by: Jarkko Nikula <jarkko.nikula(a)linux.intel.com>
Cc: <stable(a)vger.kernel.org>
Signed-off-by: Boris Brezillon <boris.brezillon(a)bootlin.com>
---
Note that the ->{read,write}() path is still buggy since nothing
guarantees that buffers passed by the MTD layer to the SPI NOR layer
are DMA-able, but this is a long-standing issue which we'll have to
address at the spi-nor level (this layer can choose the bounce buffer
size based on nor->page_size).
---
drivers/mtd/devices/m25p80.c | 24 +++++++++++++++++++++---
1 file changed, 21 insertions(+), 3 deletions(-)
diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index cbfafc453274..3b7fafa4bbd6 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -39,14 +39,22 @@ static int m25p80_read_reg(struct spi_nor *nor, u8 code, u8 *val, int len)
struct spi_mem_op op = SPI_MEM_OP(SPI_MEM_OP_CMD(code, 1),
SPI_MEM_OP_NO_ADDR,
SPI_MEM_OP_NO_DUMMY,
- SPI_MEM_OP_DATA_IN(len, val, 1));
+ SPI_MEM_OP_DATA_IN(len, NULL, 1));
+ void *scratchbuf;
int ret;
+ scratchbuf = kmemdup(val, len, GFP_KERNEL);
+ if (!scratchbuf)
+ return -ENOMEM;
+
+ op.data.buf.in = scratchbuf;
ret = spi_mem_exec_op(flash->spimem, &op);
if (ret < 0)
dev_err(&flash->spimem->spi->dev, "error %d reading %x\n", ret,
code);
+ kfree(scratchbuf);
+
return ret;
}
@@ -56,9 +64,19 @@ static int m25p80_write_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len)
struct spi_mem_op op = SPI_MEM_OP(SPI_MEM_OP_CMD(opcode, 1),
SPI_MEM_OP_NO_ADDR,
SPI_MEM_OP_NO_DUMMY,
- SPI_MEM_OP_DATA_OUT(len, buf, 1));
+ SPI_MEM_OP_DATA_OUT(len, NULL, 1));
+ void *scratchbuf;
+ int ret;
- return spi_mem_exec_op(flash->spimem, &op);
+ scratchbuf = kmemdup(buf, len, GFP_KERNEL);
+ if (!scratchbuf)
+ return -ENOMEM;
+
+ op.data.buf.out = scratchbuf;
+ ret = spi_mem_exec_op(flash->spimem, &op);
+ kfree(scratchbuf);
+
+ return ret;
}
static ssize_t m25p80_write(struct spi_nor *nor, loff_t to, size_t len,
--
2.14.1
A transparent huge page is represented by a single entry on an LRU list.
Therefore, we can only make unevictable an entire compound page, not
individual subpages.
If a user tries to mlock() part of a huge page, we want the rest of the
page to be reclaimable.
We handle this by keeping PTE-mapped huge pages on normal LRU lists: the
PMD on border of VM_LOCKED VMA will be split into PTE table.
Introduction of THP migration breaks[1] the rules around mlocking THP
pages. If we had a single PMD mapping of the page in mlocked VMA, the
page will get mlocked, regardless of PTE mappings of the page.
For tmpfs/shmem it's easy to fix by checking PageDoubleMap() in
remove_migration_pmd().
Anon THP pages can only be shared between processes via fork(). Mlocked
page can only be shared if parent mlocked it before forking, otherwise
CoW will be triggered on mlock().
For Anon-THP, we can fix the issue by munlocking the page on removing PTE
migration entry for the page. PTEs for the page will always come after
mlocked PMD: rmap walks VMAs from oldest to newest.
Test-case:
#include <unistd.h>
#include <sys/mman.h>
#include <sys/wait.h>
#include <linux/mempolicy.h>
#include <numaif.h>
int main(void)
{
unsigned long nodemask = 4;
void *addr;
addr = mmap((void *)0x20000000UL, 2UL << 20, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS | MAP_LOCKED, -1, 0);
if (fork()) {
wait(NULL);
return 0;
}
mlock(addr, 4UL << 10);
mbind(addr, 2UL << 20, MPOL_PREFERRED | MPOL_F_RELATIVE_NODES,
&nodemask, 4, MPOL_MF_MOVE);
return 0;
}
[1] https://lkml.kernel.org/r/CAOMGZ=G52R-30rZvhGxEbkTw7rLLwBGadVYeo--iizcD3upL…
Signed-off-by: Kirill A. Shutemov <kirill.shutemov(a)linux.intel.com>
Reported-by: Vegard Nossum <vegard.nossum(a)oracle.com>
Fixes: 616b8371539a ("mm: thp: enable thp migration in generic path")
Cc: <stable(a)vger.kernel.org> [v4.14+]
Cc: Zi Yan <zi.yan(a)cs.rutgers.edu>
Cc: Naoya Horiguchi <n-horiguchi(a)ah.jp.nec.com>
Cc: Vlastimil Babka <vbabka(a)suse.cz>
Cc: Andrea Arcangeli <aarcange(a)redhat.com>
---
mm/huge_memory.c | 2 +-
mm/migrate.c | 3 +++
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index 533f9b00147d..00704060b7f7 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -2931,7 +2931,7 @@ void remove_migration_pmd(struct page_vma_mapped_walk *pvmw, struct page *new)
else
page_add_file_rmap(new, true);
set_pmd_at(mm, mmun_start, pvmw->pmd, pmde);
- if (vma->vm_flags & VM_LOCKED)
+ if ((vma->vm_flags & VM_LOCKED) && !PageDoubleMap(new))
mlock_vma_page(new);
update_mmu_cache_pmd(vma, address, pvmw->pmd);
}
diff --git a/mm/migrate.c b/mm/migrate.c
index d6a2e89b086a..9d374011c244 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -275,6 +275,9 @@ static bool remove_migration_pte(struct page *page, struct vm_area_struct *vma,
if (vma->vm_flags & VM_LOCKED && !PageTransCompound(new))
mlock_vma_page(new);
+ if (PageTransHuge(page) && PageMlocked(page))
+ clear_page_mlock(page);
+
/* No need to invalidate - it was non-present before */
update_mmu_cache(vma, pvmw.address, pvmw.pte);
}
--
2.18.0