commit: 9b93b6b322f2a3c33538c6122c9070ca0ff60adf Author: Mike Pagano <mpagano <AT> gentoo <DOT> org> AuthorDate: Thu Mar 11 14:05:35 2021 +0000 Commit: Mike Pagano <mpagano <AT> gentoo <DOT> org> CommitDate: Thu Mar 11 14:05:35 2021 +0000 URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=9b93b6b3
Linux patch 4.19.180 Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org> 0000_README | 4 + 1179_linux-4.19.180.patch | 2354 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 2358 insertions(+) diff --git a/0000_README b/0000_README index 340b3da..c965714 100644 --- a/0000_README +++ b/0000_README @@ -755,6 +755,10 @@ Patch: 1178_linux-4.19.179.patch From: https://www.kernel.org Desc: Linux 4.19.179 +Patch: 1179_linux-4.19.180.patch +From: https://www.kernel.org +Desc: Linux 4.19.180 + Patch: 1500_XATTR_USER_PREFIX.patch From: https://bugs.gentoo.org/show_bug.cgi?id=470644 Desc: Support for namespace user.pax.* on tmpfs. diff --git a/1179_linux-4.19.180.patch b/1179_linux-4.19.180.patch new file mode 100644 index 0000000..6ffc129 --- /dev/null +++ b/1179_linux-4.19.180.patch @@ -0,0 +1,2354 @@ +diff --git a/Makefile b/Makefile +index 040b3cd699b01..48cdfe5ce9921 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 4 + PATCHLEVEL = 19 +-SUBLEVEL = 179 ++SUBLEVEL = 180 + EXTRAVERSION = + NAME = "People's Front" + +diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c +index 748bd0921dfff..788c80abff5d3 100644 +--- a/arch/um/drivers/ubd_kern.c ++++ b/arch/um/drivers/ubd_kern.c +@@ -891,7 +891,7 @@ static int ubd_disk_register(int major, u64 size, int unit, + + disk->private_data = &ubd_devs[unit]; + disk->queue = ubd_devs[unit].queue; +- device_add_disk(parent, disk); ++ device_add_disk(parent, disk, NULL); + + *disk_out = disk; + return 0; +diff --git a/block/genhd.c b/block/genhd.c +index 6965dde963736..aee2fa9de1a7d 100644 +--- a/block/genhd.c ++++ b/block/genhd.c +@@ -582,7 +582,8 @@ static int exact_lock(dev_t devt, void *data) + return 0; + } + +-static void register_disk(struct device *parent, struct gendisk *disk) ++static void register_disk(struct device *parent, struct gendisk *disk, ++ const struct attribute_group **groups) + { + struct device *ddev = disk_to_dev(disk); + struct block_device *bdev; +@@ -597,6 +598,10 @@ static void register_disk(struct device *parent, struct gendisk *disk) + /* delay uevents, until we scanned partition table */ + dev_set_uevent_suppress(ddev, 1); + ++ if (groups) { ++ WARN_ON(ddev->groups); ++ ddev->groups = groups; ++ } + if (device_add(ddev)) + return; + if (!sysfs_deprecated) { +@@ -664,6 +669,7 @@ exit: + * __device_add_disk - add disk information to kernel list + * @parent: parent device for the disk + * @disk: per-device partitioning information ++ * @groups: Additional per-device sysfs groups + * @register_queue: register the queue if set to true + * + * This function registers the partitioning information in @disk +@@ -672,6 +678,7 @@ exit: + * FIXME: error handling + */ + static void __device_add_disk(struct device *parent, struct gendisk *disk, ++ const struct attribute_group **groups, + bool register_queue) + { + dev_t devt; +@@ -715,7 +722,7 @@ static void __device_add_disk(struct device *parent, struct gendisk *disk, + blk_register_region(disk_devt(disk), disk->minors, NULL, + exact_match, exact_lock, disk); + } +- register_disk(parent, disk); ++ register_disk(parent, disk, groups); + if (register_queue) + blk_register_queue(disk); + +@@ -729,15 +736,17 @@ static void __device_add_disk(struct device *parent, struct gendisk *disk, + blk_integrity_add(disk); + } + +-void device_add_disk(struct device *parent, struct gendisk *disk) ++void device_add_disk(struct device *parent, struct gendisk *disk, ++ const struct attribute_group **groups) ++ + { +- __device_add_disk(parent, disk, true); ++ __device_add_disk(parent, disk, groups, true); + } + EXPORT_SYMBOL(device_add_disk); + + void device_add_disk_no_queue_reg(struct device *parent, struct gendisk *disk) + { +- __device_add_disk(parent, disk, false); ++ __device_add_disk(parent, disk, NULL, false); + } + EXPORT_SYMBOL(device_add_disk_no_queue_reg); + +diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c +index 2c99f93020bc9..b118b5a500c9a 100644 +--- a/drivers/base/power/runtime.c ++++ b/drivers/base/power/runtime.c +@@ -304,22 +304,22 @@ static void rpm_put_suppliers(struct device *dev) + static int __rpm_callback(int (*cb)(struct device *), struct device *dev) + __releases(&dev->power.lock) __acquires(&dev->power.lock) + { +- int retval, idx; + bool use_links = dev->power.links_count > 0; ++ bool get = false; ++ int retval, idx; ++ bool put; + + if (dev->power.irq_safe) { + spin_unlock(&dev->power.lock); ++ } else if (!use_links) { ++ spin_unlock_irq(&dev->power.lock); + } else { ++ get = dev->power.runtime_status == RPM_RESUMING; ++ + spin_unlock_irq(&dev->power.lock); + +- /* +- * Resume suppliers if necessary. +- * +- * The device's runtime PM status cannot change until this +- * routine returns, so it is safe to read the status outside of +- * the lock. +- */ +- if (use_links && dev->power.runtime_status == RPM_RESUMING) { ++ /* Resume suppliers if necessary. */ ++ if (get) { + idx = device_links_read_lock(); + + retval = rpm_get_suppliers(dev); +@@ -334,24 +334,36 @@ static int __rpm_callback(int (*cb)(struct device *), struct device *dev) + + if (dev->power.irq_safe) { + spin_lock(&dev->power.lock); +- } else { +- /* +- * If the device is suspending and the callback has returned +- * success, drop the usage counters of the suppliers that have +- * been reference counted on its resume. +- * +- * Do that if resume fails too. +- */ +- if (use_links +- && ((dev->power.runtime_status == RPM_SUSPENDING && !retval) +- || (dev->power.runtime_status == RPM_RESUMING && retval))) { +- idx = device_links_read_lock(); ++ return retval; ++ } + +- fail: +- rpm_put_suppliers(dev); ++ spin_lock_irq(&dev->power.lock); + +- device_links_read_unlock(idx); +- } ++ if (!use_links) ++ return retval; ++ ++ /* ++ * If the device is suspending and the callback has returned success, ++ * drop the usage counters of the suppliers that have been reference ++ * counted on its resume. ++ * ++ * Do that if the resume fails too. ++ */ ++ put = dev->power.runtime_status == RPM_SUSPENDING && !retval; ++ if (put) ++ __update_runtime_status(dev, RPM_SUSPENDED); ++ else ++ put = get && retval; ++ ++ if (put) { ++ spin_unlock_irq(&dev->power.lock); ++ ++ idx = device_links_read_lock(); ++ ++fail: ++ rpm_put_suppliers(dev); ++ ++ device_links_read_unlock(idx); + + spin_lock_irq(&dev->power.lock); + } +diff --git a/drivers/block/aoe/aoe.h b/drivers/block/aoe/aoe.h +index c0ebda1283cca..015c68017a1c9 100644 +--- a/drivers/block/aoe/aoe.h ++++ b/drivers/block/aoe/aoe.h +@@ -201,7 +201,6 @@ int aoeblk_init(void); + void aoeblk_exit(void); + void aoeblk_gdalloc(void *); + void aoedisk_rm_debugfs(struct aoedev *d); +-void aoedisk_rm_sysfs(struct aoedev *d); + + int aoechr_init(void); + void aoechr_exit(void); +diff --git a/drivers/block/aoe/aoeblk.c b/drivers/block/aoe/aoeblk.c +index 429ebb84b5926..ff770e7d9e528 100644 +--- a/drivers/block/aoe/aoeblk.c ++++ b/drivers/block/aoe/aoeblk.c +@@ -177,10 +177,15 @@ static struct attribute *aoe_attrs[] = { + NULL, + }; + +-static const struct attribute_group attr_group = { ++static const struct attribute_group aoe_attr_group = { + .attrs = aoe_attrs, + }; + ++static const struct attribute_group *aoe_attr_groups[] = { ++ &aoe_attr_group, ++ NULL, ++}; ++ + static const struct file_operations aoe_debugfs_fops = { + .open = aoe_debugfs_open, + .read = seq_read, +@@ -219,17 +224,6 @@ aoedisk_rm_debugfs(struct aoedev *d) + d->debugfs = NULL; + } + +-static int +-aoedisk_add_sysfs(struct aoedev *d) +-{ +- return sysfs_create_group(&disk_to_dev(d->gd)->kobj, &attr_group); +-} +-void +-aoedisk_rm_sysfs(struct aoedev *d) +-{ +- sysfs_remove_group(&disk_to_dev(d->gd)->kobj, &attr_group); +-} +- + static int + aoeblk_open(struct block_device *bdev, fmode_t mode) + { +@@ -417,8 +411,7 @@ aoeblk_gdalloc(void *vp) + + spin_unlock_irqrestore(&d->lock, flags); + +- add_disk(gd); +- aoedisk_add_sysfs(d); ++ device_add_disk(NULL, gd, aoe_attr_groups); + aoedisk_add_debugfs(d); + + spin_lock_irqsave(&d->lock, flags); +diff --git a/drivers/block/aoe/aoedev.c b/drivers/block/aoe/aoedev.c +index 41060e9cedf20..f29a140cdbc13 100644 +--- a/drivers/block/aoe/aoedev.c ++++ b/drivers/block/aoe/aoedev.c +@@ -275,7 +275,6 @@ freedev(struct aoedev *d) + del_timer_sync(&d->timer); + if (d->gd) { + aoedisk_rm_debugfs(d); +- aoedisk_rm_sysfs(d); + del_gendisk(d->gd); + put_disk(d->gd); + blk_cleanup_queue(d->blkq); +diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c +index 56d4c7df91857..04383f14c74a9 100644 +--- a/drivers/block/floppy.c ++++ b/drivers/block/floppy.c +@@ -4714,7 +4714,7 @@ static int __init do_floppy_init(void) + /* to be cleaned up... */ + disks[drive]->private_data = (void *)(long)drive; + disks[drive]->flags |= GENHD_FL_REMOVABLE; +- device_add_disk(&floppy_device[drive].dev, disks[drive]); ++ device_add_disk(&floppy_device[drive].dev, disks[drive], NULL); + } + + return 0; +diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c +index d0666f5ce0036..1d7d48d8a2050 100644 +--- a/drivers/block/mtip32xx/mtip32xx.c ++++ b/drivers/block/mtip32xx/mtip32xx.c +@@ -3861,7 +3861,7 @@ skip_create_disk: + set_capacity(dd->disk, capacity); + + /* Enable the block device and add it to /dev */ +- device_add_disk(&dd->pdev->dev, dd->disk); ++ device_add_disk(&dd->pdev->dev, dd->disk, NULL); + + dd->bdev = bdget_disk(dd->disk, 0); + /* +diff --git a/drivers/block/ps3disk.c b/drivers/block/ps3disk.c +index bd1c66f5631a5..42bff6b1d6a89 100644 +--- a/drivers/block/ps3disk.c ++++ b/drivers/block/ps3disk.c +@@ -499,7 +499,7 @@ static int ps3disk_probe(struct ps3_system_bus_device *_dev) + gendisk->disk_name, priv->model, priv->raw_capacity >> 11, + get_capacity(gendisk) >> 11); + +- device_add_disk(&dev->sbd.core, gendisk); ++ device_add_disk(&dev->sbd.core, gendisk, NULL); + return 0; + + fail_cleanup_queue: +diff --git a/drivers/block/ps3vram.c b/drivers/block/ps3vram.c +index 1e3d5de9d8387..c0c50816a10bb 100644 +--- a/drivers/block/ps3vram.c ++++ b/drivers/block/ps3vram.c +@@ -769,7 +769,7 @@ static int ps3vram_probe(struct ps3_system_bus_device *dev) + dev_info(&dev->core, "%s: Using %lu MiB of GPU memory\n", + gendisk->disk_name, get_capacity(gendisk) >> 11); + +- device_add_disk(&dev->core, gendisk); ++ device_add_disk(&dev->core, gendisk, NULL); + return 0; + + fail_cleanup_queue: +diff --git a/drivers/block/rsxx/core.c b/drivers/block/rsxx/core.c +index 14056dc450642..d8ef8b16fb2e9 100644 +--- a/drivers/block/rsxx/core.c ++++ b/drivers/block/rsxx/core.c +@@ -179,15 +179,17 @@ static ssize_t rsxx_cram_read(struct file *fp, char __user *ubuf, + { + struct rsxx_cardinfo *card = file_inode(fp)->i_private; + char *buf; +- ssize_t st; ++ int st; + + buf = kzalloc(cnt, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + st = rsxx_creg_read(card, CREG_ADD_CRAM + (u32)*ppos, cnt, buf, 1); +- if (!st) +- st = copy_to_user(ubuf, buf, cnt); ++ if (!st) { ++ if (copy_to_user(ubuf, buf, cnt)) ++ st = -EFAULT; ++ } + kfree(buf); + if (st) + return st; +diff --git a/drivers/block/rsxx/dev.c b/drivers/block/rsxx/dev.c +index 1a92f9e659374..3894aa0f350b7 100644 +--- a/drivers/block/rsxx/dev.c ++++ b/drivers/block/rsxx/dev.c +@@ -226,7 +226,7 @@ int rsxx_attach_dev(struct rsxx_cardinfo *card) + set_capacity(card->gendisk, card->size8 >> 9); + else + set_capacity(card->gendisk, 0); +- device_add_disk(CARD_TO_DEV(card), card->gendisk); ++ device_add_disk(CARD_TO_DEV(card), card->gendisk, NULL); + card->bdev_attached = 1; + } + +diff --git a/drivers/block/skd_main.c b/drivers/block/skd_main.c +index 27323fa23997d..80a5806ede039 100644 +--- a/drivers/block/skd_main.c ++++ b/drivers/block/skd_main.c +@@ -3104,7 +3104,7 @@ static int skd_bdev_getgeo(struct block_device *bdev, struct hd_geometry *geo) + static int skd_bdev_attach(struct device *parent, struct skd_device *skdev) + { + dev_dbg(&skdev->pdev->dev, "add_disk\n"); +- device_add_disk(parent, skdev->disk); ++ device_add_disk(parent, skdev->disk, NULL); + return 0; + } + +diff --git a/drivers/block/sunvdc.c b/drivers/block/sunvdc.c +index 5d7024057540a..6b7b0d8a2acbc 100644 +--- a/drivers/block/sunvdc.c ++++ b/drivers/block/sunvdc.c +@@ -862,7 +862,7 @@ static int probe_disk(struct vdc_port *port) + port->vdisk_size, (port->vdisk_size >> (20 - 9)), + port->vio.ver.major, port->vio.ver.minor); + +- device_add_disk(&port->vio.vdev->dev, g); ++ device_add_disk(&port->vio.vdev->dev, g, NULL); + + return 0; + } +diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c +index 075523777a4a9..c2d9459ec5d12 100644 +--- a/drivers/block/virtio_blk.c ++++ b/drivers/block/virtio_blk.c +@@ -423,8 +423,8 @@ static int minor_to_index(int minor) + return minor >> PART_BITS; + } + +-static ssize_t virtblk_serial_show(struct device *dev, +- struct device_attribute *attr, char *buf) ++static ssize_t serial_show(struct device *dev, ++ struct device_attribute *attr, char *buf) + { + struct gendisk *disk = dev_to_disk(dev); + int err; +@@ -443,7 +443,7 @@ static ssize_t virtblk_serial_show(struct device *dev, + return err; + } + +-static DEVICE_ATTR(serial, 0444, virtblk_serial_show, NULL); ++static DEVICE_ATTR_RO(serial); + + /* The queue's logical block size must be set before calling this */ + static void virtblk_update_capacity(struct virtio_blk *vblk, bool resize) +@@ -619,8 +619,8 @@ static const char *const virtblk_cache_types[] = { + }; + + static ssize_t +-virtblk_cache_type_store(struct device *dev, struct device_attribute *attr, +- const char *buf, size_t count) ++cache_type_store(struct device *dev, struct device_attribute *attr, ++ const char *buf, size_t count) + { + struct gendisk *disk = dev_to_disk(dev); + struct virtio_blk *vblk = disk->private_data; +@@ -638,8 +638,7 @@ virtblk_cache_type_store(struct device *dev, struct device_attribute *attr, + } + + static ssize_t +-virtblk_cache_type_show(struct device *dev, struct device_attribute *attr, +- char *buf) ++cache_type_show(struct device *dev, struct device_attribute *attr, char *buf) + { + struct gendisk *disk = dev_to_disk(dev); + struct virtio_blk *vblk = disk->private_data; +@@ -649,12 +648,38 @@ virtblk_cache_type_show(struct device *dev, struct device_attribute *attr, + return snprintf(buf, 40, "%s\n", virtblk_cache_types[writeback]); + } + +-static const struct device_attribute dev_attr_cache_type_ro = +- __ATTR(cache_type, 0444, +- virtblk_cache_type_show, NULL); +-static const struct device_attribute dev_attr_cache_type_rw = +- __ATTR(cache_type, 0644, +- virtblk_cache_type_show, virtblk_cache_type_store); ++static DEVICE_ATTR_RW(cache_type); ++ ++static struct attribute *virtblk_attrs[] = { ++ &dev_attr_serial.attr, ++ &dev_attr_cache_type.attr, ++ NULL, ++}; ++ ++static umode_t virtblk_attrs_are_visible(struct kobject *kobj, ++ struct attribute *a, int n) ++{ ++ struct device *dev = container_of(kobj, struct device, kobj); ++ struct gendisk *disk = dev_to_disk(dev); ++ struct virtio_blk *vblk = disk->private_data; ++ struct virtio_device *vdev = vblk->vdev; ++ ++ if (a == &dev_attr_cache_type.attr && ++ !virtio_has_feature(vdev, VIRTIO_BLK_F_CONFIG_WCE)) ++ return S_IRUGO; ++ ++ return a->mode; ++} ++ ++static const struct attribute_group virtblk_attr_group = { ++ .attrs = virtblk_attrs, ++ .is_visible = virtblk_attrs_are_visible, ++}; ++ ++static const struct attribute_group *virtblk_attr_groups[] = { ++ &virtblk_attr_group, ++ NULL, ++}; + + static int virtblk_init_request(struct blk_mq_tag_set *set, struct request *rq, + unsigned int hctx_idx, unsigned int numa_node) +@@ -858,24 +883,9 @@ static int virtblk_probe(struct virtio_device *vdev) + virtblk_update_capacity(vblk, false); + virtio_device_ready(vdev); + +- device_add_disk(&vdev->dev, vblk->disk); +- err = device_create_file(disk_to_dev(vblk->disk), &dev_attr_serial); +- if (err) +- goto out_del_disk; +- +- if (virtio_has_feature(vdev, VIRTIO_BLK_F_CONFIG_WCE)) +- err = device_create_file(disk_to_dev(vblk->disk), +- &dev_attr_cache_type_rw); +- else +- err = device_create_file(disk_to_dev(vblk->disk), +- &dev_attr_cache_type_ro); +- if (err) +- goto out_del_disk; ++ device_add_disk(&vdev->dev, vblk->disk, virtblk_attr_groups); + return 0; + +-out_del_disk: +- del_gendisk(vblk->disk); +- blk_cleanup_queue(vblk->disk->queue); + out_free_tags: + blk_mq_free_tag_set(&vblk->tag_set); + out_put_disk: +diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c +index d4ceee3825f8d..1b06c8e46ffa4 100644 +--- a/drivers/block/xen-blkfront.c ++++ b/drivers/block/xen-blkfront.c +@@ -2422,7 +2422,7 @@ static void blkfront_connect(struct blkfront_info *info) + for (i = 0; i < info->nr_rings; i++) + kick_pending_request_queues(&info->rinfo[i]); + +- device_add_disk(&info->xbdev->dev, info->gd); ++ device_add_disk(&info->xbdev->dev, info->gd, NULL); + + info->is_ready = 1; + return; +diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c +index 2c7f412df2eb3..104206a795015 100644 +--- a/drivers/block/zram/zram_drv.c ++++ b/drivers/block/zram/zram_drv.c +@@ -1729,8 +1729,7 @@ static int zram_add(void) + + zram->disk->queue->backing_dev_info->capabilities |= + (BDI_CAP_STABLE_WRITES | BDI_CAP_SYNCHRONOUS_IO); +- disk_to_dev(zram->disk)->groups = zram_disk_attr_groups; +- add_disk(zram->disk); ++ device_add_disk(NULL, zram->disk, zram_disk_attr_groups); + + strlcpy(zram->compressor, default_compressor, sizeof(zram->compressor)); + +@@ -1766,6 +1765,7 @@ static int zram_remove(struct zram *zram) + mutex_unlock(&bdev->bd_mutex); + + zram_debugfs_unregister(zram); ++ + /* Make sure all the pending I/O are finished */ + fsync_bdev(bdev); + zram_reset_device(zram); +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c +index a90e83e5ab575..ee4a0b7cb452f 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c +@@ -239,7 +239,7 @@ static ssize_t amdgpu_debugfs_regs_pcie_read(struct file *f, char __user *buf, + while (size) { + uint32_t value; + +- value = RREG32_PCIE(*pos >> 2); ++ value = RREG32_PCIE(*pos); + r = put_user(value, (uint32_t *)buf); + if (r) + return r; +@@ -282,7 +282,7 @@ static ssize_t amdgpu_debugfs_regs_pcie_write(struct file *f, const char __user + if (r) + return r; + +- WREG32_PCIE(*pos >> 2, value); ++ WREG32_PCIE(*pos, value); + + result += 4; + buf += 4; +diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +index d29a58bd2f7a3..776bbe9775e9d 100644 +--- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c ++++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +@@ -681,8 +681,6 @@ static int a5xx_hw_init(struct msm_gpu *gpu) + if (adreno_gpu->info->quirks & ADRENO_QUIRK_TWO_PASS_USE_WFI) + gpu_rmw(gpu, REG_A5XX_PC_DBG_ECO_CNTL, 0, (1 << 8)); + +- gpu_write(gpu, REG_A5XX_PC_DBG_ECO_CNTL, 0xc0200100); +- + /* Enable USE_RETENTION_FLOPS */ + gpu_write(gpu, REG_A5XX_CP_CHICKEN_DBG, 0x02000000); + +diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h +index ab2be7a115d8f..2f1516b328372 100644 +--- a/drivers/hid/hid-ids.h ++++ b/drivers/hid/hid-ids.h +@@ -358,6 +358,7 @@ + #define USB_DEVICE_ID_DRAGONRISE_DOLPHINBAR 0x1803 + #define USB_DEVICE_ID_DRAGONRISE_GAMECUBE1 0x1843 + #define USB_DEVICE_ID_DRAGONRISE_GAMECUBE2 0x1844 ++#define USB_DEVICE_ID_DRAGONRISE_GAMECUBE3 0x1846 + + #define USB_VENDOR_ID_DWAV 0x0eef + #define USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER 0x0001 +diff --git a/drivers/hid/hid-mf.c b/drivers/hid/hid-mf.c +index 03f10516131df..a41202d385096 100644 +--- a/drivers/hid/hid-mf.c ++++ b/drivers/hid/hid-mf.c +@@ -161,6 +161,8 @@ static const struct hid_device_id mf_devices[] = { + .driver_data = HID_QUIRK_MULTI_INPUT }, + { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_GAMECUBE2), + .driver_data = 0 }, /* No quirk required */ ++ { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_GAMECUBE3), ++ .driver_data = HID_QUIRK_MULTI_INPUT }, + { } + }; + MODULE_DEVICE_TABLE(hid, mf_devices); +diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c +index 10cb42a00fe87..8fbe7b9cd84a3 100644 +--- a/drivers/hid/hid-quirks.c ++++ b/drivers/hid/hid-quirks.c +@@ -74,6 +74,7 @@ static const struct hid_device_id hid_quirks[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_REDRAGON_SEYMUR2), HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE }, + { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_DOLPHINBAR), HID_QUIRK_MULTI_INPUT }, + { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_GAMECUBE1), HID_QUIRK_MULTI_INPUT }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_GAMECUBE3), HID_QUIRK_MULTI_INPUT }, + { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_PS3), HID_QUIRK_MULTI_INPUT }, + { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_WIIU), HID_QUIRK_MULTI_INPUT }, + { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER), HID_QUIRK_MULTI_INPUT | HID_QUIRK_NOGET }, +@@ -498,6 +499,7 @@ static const struct hid_device_id hid_have_special_driver[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_DOLPHINBAR) }, + { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_GAMECUBE1) }, + { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_GAMECUBE2) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_GAMECUBE3) }, + #endif + #if IS_ENABLED(CONFIG_HID_MICROSOFT) + { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_COMFORT_MOUSE_4500) }, +diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c +index 44a7a255ef74a..f9b59d41813f9 100644 +--- a/drivers/ide/ide-cd.c ++++ b/drivers/ide/ide-cd.c +@@ -1784,7 +1784,7 @@ static int ide_cd_probe(ide_drive_t *drive) + ide_cd_read_toc(drive); + g->fops = &idecd_ops; + g->flags |= GENHD_FL_REMOVABLE | GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE; +- device_add_disk(&drive->gendev, g); ++ device_add_disk(&drive->gendev, g, NULL); + return 0; + + out_free_disk: +diff --git a/drivers/ide/ide-gd.c b/drivers/ide/ide-gd.c +index e823394ed5434..04e008e8f6f9d 100644 +--- a/drivers/ide/ide-gd.c ++++ b/drivers/ide/ide-gd.c +@@ -416,7 +416,7 @@ static int ide_gd_probe(ide_drive_t *drive) + if (drive->dev_flags & IDE_DFLAG_REMOVABLE) + g->flags = GENHD_FL_REMOVABLE; + g->fops = &ide_gd_ops; +- device_add_disk(&drive->gendev, g); ++ device_add_disk(&drive->gendev, g, NULL); + return 0; + + out_free_disk: +diff --git a/drivers/infiniband/sw/rxe/Kconfig b/drivers/infiniband/sw/rxe/Kconfig +index 67ae960ab523b..1fa19a77583ea 100644 +--- a/drivers/infiniband/sw/rxe/Kconfig ++++ b/drivers/infiniband/sw/rxe/Kconfig +@@ -3,6 +3,7 @@ config RDMA_RXE + depends on INET && PCI && INFINIBAND + depends on !64BIT || ARCH_DMA_ADDR_T_64BIT + select NET_UDP_TUNNEL ++ select CRYPTO + select CRYPTO_CRC32 + select DMA_VIRT_OPS + ---help--- +diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c +index d0cbe910ee9db..5d5941aca16ad 100644 +--- a/drivers/iommu/amd_iommu.c ++++ b/drivers/iommu/amd_iommu.c +@@ -1348,24 +1348,26 @@ static void increase_address_space(struct protection_domain *domain, + unsigned long flags; + u64 *pte; + ++ pte = (void *)get_zeroed_page(gfp); ++ if (!pte) ++ return; ++ + spin_lock_irqsave(&domain->lock, flags); + + if (WARN_ON_ONCE(domain->mode == PAGE_MODE_6_LEVEL)) + /* address space already 64 bit large */ + goto out; + +- pte = (void *)get_zeroed_page(gfp); +- if (!pte) +- goto out; +- + *pte = PM_LEVEL_PDE(domain->mode, + iommu_virt_to_phys(domain->pt_root)); + domain->pt_root = pte; + domain->mode += 1; + domain->updated = true; ++ pte = NULL; + + out: + spin_unlock_irqrestore(&domain->lock, flags); ++ free_page((unsigned long)pte); + + return; + } +diff --git a/drivers/md/dm-bufio.c b/drivers/md/dm-bufio.c +index b6e4ab67ae449..b3b799f84dcc6 100644 +--- a/drivers/md/dm-bufio.c ++++ b/drivers/md/dm-bufio.c +@@ -1463,6 +1463,10 @@ EXPORT_SYMBOL_GPL(dm_bufio_get_block_size); + sector_t dm_bufio_get_device_size(struct dm_bufio_client *c) + { + sector_t s = i_size_read(c->bdev->bd_inode) >> SECTOR_SHIFT; ++ if (s >= c->start) ++ s -= c->start; ++ else ++ s = 0; + if (likely(c->sectors_per_block_bits >= 0)) + s >>= c->sectors_per_block_bits; + else +diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c +index 9164337424856..71d3fdbce50a3 100644 +--- a/drivers/md/dm-table.c ++++ b/drivers/md/dm-table.c +@@ -891,10 +891,10 @@ void dm_table_set_type(struct dm_table *t, enum dm_queue_mode type) + } + EXPORT_SYMBOL_GPL(dm_table_set_type); + +-static int device_supports_dax(struct dm_target *ti, struct dm_dev *dev, ++static int device_not_dax_capable(struct dm_target *ti, struct dm_dev *dev, + sector_t start, sector_t len, void *data) + { +- return bdev_dax_supported(dev->bdev, PAGE_SIZE); ++ return !bdev_dax_supported(dev->bdev, PAGE_SIZE); + } + + static bool dm_table_supports_dax(struct dm_table *t) +@@ -910,7 +910,7 @@ static bool dm_table_supports_dax(struct dm_table *t) + return false; + + if (!ti->type->iterate_devices || +- !ti->type->iterate_devices(ti, device_supports_dax, NULL)) ++ ti->type->iterate_devices(ti, device_not_dax_capable, NULL)) + return false; + } + +@@ -1392,6 +1392,46 @@ struct dm_target *dm_table_find_target(struct dm_table *t, sector_t sector) + return &t->targets[(KEYS_PER_NODE * n) + k]; + } + ++/* ++ * type->iterate_devices() should be called when the sanity check needs to ++ * iterate and check all underlying data devices. iterate_devices() will ++ * iterate all underlying data devices until it encounters a non-zero return ++ * code, returned by whether the input iterate_devices_callout_fn, or ++ * iterate_devices() itself internally. ++ * ++ * For some target type (e.g. dm-stripe), one call of iterate_devices() may ++ * iterate multiple underlying devices internally, in which case a non-zero ++ * return code returned by iterate_devices_callout_fn will stop the iteration ++ * in advance. ++ * ++ * Cases requiring _any_ underlying device supporting some kind of attribute, ++ * should use the iteration structure like dm_table_any_dev_attr(), or call ++ * it directly. @func should handle semantics of positive examples, e.g. ++ * capable of something. ++ * ++ * Cases requiring _all_ underlying devices supporting some kind of attribute, ++ * should use the iteration structure like dm_table_supports_nowait() or ++ * dm_table_supports_discards(). Or introduce dm_table_all_devs_attr() that ++ * uses an @anti_func that handle semantics of counter examples, e.g. not ++ * capable of something. So: return !dm_table_any_dev_attr(t, anti_func, data); ++ */ ++static bool dm_table_any_dev_attr(struct dm_table *t, ++ iterate_devices_callout_fn func, void *data) ++{ ++ struct dm_target *ti; ++ unsigned int i; ++ ++ for (i = 0; i < dm_table_get_num_targets(t); i++) { ++ ti = dm_table_get_target(t, i); ++ ++ if (ti->type->iterate_devices && ++ ti->type->iterate_devices(ti, func, data)) ++ return true; ++ } ++ ++ return false; ++} ++ + static int count_device(struct dm_target *ti, struct dm_dev *dev, + sector_t start, sector_t len, void *data) + { +@@ -1428,13 +1468,13 @@ bool dm_table_has_no_data_devices(struct dm_table *table) + return true; + } + +-static int device_is_zoned_model(struct dm_target *ti, struct dm_dev *dev, +- sector_t start, sector_t len, void *data) ++static int device_not_zoned_model(struct dm_target *ti, struct dm_dev *dev, ++ sector_t start, sector_t len, void *data) + { + struct request_queue *q = bdev_get_queue(dev->bdev); + enum blk_zoned_model *zoned_model = data; + +- return q && blk_queue_zoned_model(q) == *zoned_model; ++ return !q || blk_queue_zoned_model(q) != *zoned_model; + } + + static bool dm_table_supports_zoned_model(struct dm_table *t, +@@ -1451,37 +1491,20 @@ static bool dm_table_supports_zoned_model(struct dm_table *t, + return false; + + if (!ti->type->iterate_devices || +- !ti->type->iterate_devices(ti, device_is_zoned_model, &zoned_model)) ++ ti->type->iterate_devices(ti, device_not_zoned_model, &zoned_model)) + return false; + } + + return true; + } + +-static int device_matches_zone_sectors(struct dm_target *ti, struct dm_dev *dev, +- sector_t start, sector_t len, void *data) ++static int device_not_matches_zone_sectors(struct dm_target *ti, struct dm_dev *dev, ++ sector_t start, sector_t len, void *data) + { + struct request_queue *q = bdev_get_queue(dev->bdev); + unsigned int *zone_sectors = data; + +- return q && blk_queue_zone_sectors(q) == *zone_sectors; +-} +- +-static bool dm_table_matches_zone_sectors(struct dm_table *t, +- unsigned int zone_sectors) +-{ +- struct dm_target *ti; +- unsigned i; +- +- for (i = 0; i < dm_table_get_num_targets(t); i++) { +- ti = dm_table_get_target(t, i); +- +- if (!ti->type->iterate_devices || +- !ti->type->iterate_devices(ti, device_matches_zone_sectors, &zone_sectors)) +- return false; +- } +- +- return true; ++ return !q || blk_queue_zone_sectors(q) != *zone_sectors; + } + + static int validate_hardware_zoned_model(struct dm_table *table, +@@ -1501,7 +1524,7 @@ static int validate_hardware_zoned_model(struct dm_table *table, + if (!zone_sectors || !is_power_of_2(zone_sectors)) + return -EINVAL; + +- if (!dm_table_matches_zone_sectors(table, zone_sectors)) { ++ if (dm_table_any_dev_attr(table, device_not_matches_zone_sectors, &zone_sectors)) { + DMERR("%s: zone sectors is not consistent across all devices", + dm_device_name(table->md)); + return -EINVAL; +@@ -1691,29 +1714,12 @@ static int device_dax_write_cache_enabled(struct dm_target *ti, + return false; + } + +-static int dm_table_supports_dax_write_cache(struct dm_table *t) +-{ +- struct dm_target *ti; +- unsigned i; +- +- for (i = 0; i < dm_table_get_num_targets(t); i++) { +- ti = dm_table_get_target(t, i); +- +- if (ti->type->iterate_devices && +- ti->type->iterate_devices(ti, +- device_dax_write_cache_enabled, NULL)) +- return true; +- } +- +- return false; +-} +- +-static int device_is_nonrot(struct dm_target *ti, struct dm_dev *dev, +- sector_t start, sector_t len, void *data) ++static int device_is_rotational(struct dm_target *ti, struct dm_dev *dev, ++ sector_t start, sector_t len, void *data) + { + struct request_queue *q = bdev_get_queue(dev->bdev); + +- return q && blk_queue_nonrot(q); ++ return q && !blk_queue_nonrot(q); + } + + static int device_is_not_random(struct dm_target *ti, struct dm_dev *dev, +@@ -1724,43 +1730,26 @@ static int device_is_not_random(struct dm_target *ti, struct dm_dev *dev, + return q && !blk_queue_add_random(q); + } + +-static int queue_supports_sg_merge(struct dm_target *ti, struct dm_dev *dev, +- sector_t start, sector_t len, void *data) ++static int queue_no_sg_merge(struct dm_target *ti, struct dm_dev *dev, ++ sector_t start, sector_t len, void *data) + { + struct request_queue *q = bdev_get_queue(dev->bdev); + +- return q && !test_bit(QUEUE_FLAG_NO_SG_MERGE, &q->queue_flags); +-} +- +-static bool dm_table_all_devices_attribute(struct dm_table *t, +- iterate_devices_callout_fn func) +-{ +- struct dm_target *ti; +- unsigned i; +- +- for (i = 0; i < dm_table_get_num_targets(t); i++) { +- ti = dm_table_get_target(t, i); +- +- if (!ti->type->iterate_devices || +- !ti->type->iterate_devices(ti, func, NULL)) +- return false; +- } +- +- return true; ++ return q && test_bit(QUEUE_FLAG_NO_SG_MERGE, &q->queue_flags); + } + +-static int device_no_partial_completion(struct dm_target *ti, struct dm_dev *dev, ++static int device_is_partial_completion(struct dm_target *ti, struct dm_dev *dev, + sector_t start, sector_t len, void *data) + { + char b[BDEVNAME_SIZE]; + + /* For now, NVMe devices are the only devices of this class */ +- return (strncmp(bdevname(dev->bdev, b), "nvme", 4) == 0); ++ return (strncmp(bdevname(dev->bdev, b), "nvme", 4) != 0); + } + + static bool dm_table_does_not_support_partial_completion(struct dm_table *t) + { +- return dm_table_all_devices_attribute(t, device_no_partial_completion); ++ return !dm_table_any_dev_attr(t, device_is_partial_completion, NULL); + } + + static int device_not_write_same_capable(struct dm_target *ti, struct dm_dev *dev, +@@ -1887,27 +1876,6 @@ static int device_requires_stable_pages(struct dm_target *ti, + return q && bdi_cap_stable_pages_required(q->backing_dev_info); + } + +-/* +- * If any underlying device requires stable pages, a table must require +- * them as well. Only targets that support iterate_devices are considered: +- * don't want error, zero, etc to require stable pages. +- */ +-static bool dm_table_requires_stable_pages(struct dm_table *t) +-{ +- struct dm_target *ti; +- unsigned i; +- +- for (i = 0; i < dm_table_get_num_targets(t); i++) { +- ti = dm_table_get_target(t, i); +- +- if (ti->type->iterate_devices && +- ti->type->iterate_devices(ti, device_requires_stable_pages, NULL)) +- return true; +- } +- +- return false; +-} +- + void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q, + struct queue_limits *limits) + { +@@ -1944,32 +1912,35 @@ void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q, + else + blk_queue_flag_clear(QUEUE_FLAG_DAX, q); + +- if (dm_table_supports_dax_write_cache(t)) ++ if (dm_table_any_dev_attr(t, device_dax_write_cache_enabled, NULL)) + dax_write_cache(t->md->dax_dev, true); + + /* Ensure that all underlying devices are non-rotational. */ +- if (dm_table_all_devices_attribute(t, device_is_nonrot)) +- blk_queue_flag_set(QUEUE_FLAG_NONROT, q); +- else ++ if (dm_table_any_dev_attr(t, device_is_rotational, NULL)) + blk_queue_flag_clear(QUEUE_FLAG_NONROT, q); ++ else ++ blk_queue_flag_set(QUEUE_FLAG_NONROT, q); + + if (!dm_table_supports_write_same(t)) + q->limits.max_write_same_sectors = 0; + if (!dm_table_supports_write_zeroes(t)) + q->limits.max_write_zeroes_sectors = 0; + +- if (dm_table_all_devices_attribute(t, queue_supports_sg_merge)) +- blk_queue_flag_clear(QUEUE_FLAG_NO_SG_MERGE, q); +- else ++ if (dm_table_any_dev_attr(t, queue_no_sg_merge, NULL)) + blk_queue_flag_set(QUEUE_FLAG_NO_SG_MERGE, q); ++ else ++ blk_queue_flag_clear(QUEUE_FLAG_NO_SG_MERGE, q); + + dm_table_verify_integrity(t); + + /* + * Some devices don't use blk_integrity but still want stable pages + * because they do their own checksumming. ++ * If any underlying device requires stable pages, a table must require ++ * them as well. Only targets that support iterate_devices are considered: ++ * don't want error, zero, etc to require stable pages. + */ +- if (dm_table_requires_stable_pages(t)) ++ if (dm_table_any_dev_attr(t, device_requires_stable_pages, NULL)) + q->backing_dev_info->capabilities |= BDI_CAP_STABLE_WRITES; + else + q->backing_dev_info->capabilities &= ~BDI_CAP_STABLE_WRITES; +@@ -1980,7 +1951,8 @@ void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q, + * Clear QUEUE_FLAG_ADD_RANDOM if any underlying device does not + * have it set. + */ +- if (blk_queue_add_random(q) && dm_table_all_devices_attribute(t, device_is_not_random)) ++ if (blk_queue_add_random(q) && ++ dm_table_any_dev_attr(t, device_is_not_random, NULL)) + blk_queue_flag_clear(QUEUE_FLAG_ADD_RANDOM, q); + } + +diff --git a/drivers/md/dm-verity-fec.c b/drivers/md/dm-verity-fec.c +index bb8327999705e..dd7684333d90a 100644 +--- a/drivers/md/dm-verity-fec.c ++++ b/drivers/md/dm-verity-fec.c +@@ -65,19 +65,18 @@ static int fec_decode_rs8(struct dm_verity *v, struct dm_verity_fec_io *fio, + static u8 *fec_read_parity(struct dm_verity *v, u64 rsb, int index, + unsigned *offset, struct dm_buffer **buf) + { +- u64 position, block; ++ u64 position, block, rem; + u8 *res; + + position = (index + rsb) * v->fec->roots; +- block = position >> v->data_dev_block_bits; +- *offset = (unsigned)(position - (block << v->data_dev_block_bits)); ++ block = div64_u64_rem(position, v->fec->roots << SECTOR_SHIFT, &rem); ++ *offset = (unsigned)rem; + +- res = dm_bufio_read(v->fec->bufio, v->fec->start + block, buf); ++ res = dm_bufio_read(v->fec->bufio, block, buf); + if (unlikely(IS_ERR(res))) { + DMERR("%s: FEC %llu: parity read failed (block %llu): %ld", + v->data_dev->name, (unsigned long long)rsb, +- (unsigned long long)(v->fec->start + block), +- PTR_ERR(res)); ++ (unsigned long long)block, PTR_ERR(res)); + *buf = NULL; + } + +@@ -159,7 +158,7 @@ static int fec_decode_bufs(struct dm_verity *v, struct dm_verity_fec_io *fio, + + /* read the next block when we run out of parity bytes */ + offset += v->fec->roots; +- if (offset >= 1 << v->data_dev_block_bits) { ++ if (offset >= v->fec->roots << SECTOR_SHIFT) { + dm_bufio_release(buf); + + par = fec_read_parity(v, rsb, block_offset, &offset, &buf); +@@ -675,7 +674,7 @@ int verity_fec_ctr(struct dm_verity *v) + { + struct dm_verity_fec *f = v->fec; + struct dm_target *ti = v->ti; +- u64 hash_blocks; ++ u64 hash_blocks, fec_blocks; + int ret; + + if (!verity_fec_is_enabled(v)) { +@@ -745,15 +744,17 @@ int verity_fec_ctr(struct dm_verity *v) + } + + f->bufio = dm_bufio_client_create(f->dev->bdev, +- 1 << v->data_dev_block_bits, ++ f->roots << SECTOR_SHIFT, + 1, 0, NULL, NULL); + if (IS_ERR(f->bufio)) { + ti->error = "Cannot initialize FEC bufio client"; + return PTR_ERR(f->bufio); + } + +- if (dm_bufio_get_device_size(f->bufio) < +- ((f->start + f->rounds * f->roots) >> v->data_dev_block_bits)) { ++ dm_bufio_set_sector_offset(f->bufio, f->start << (v->data_dev_block_bits - SECTOR_SHIFT)); ++ ++ fec_blocks = div64_u64(f->rounds * f->roots, v->fec->roots << SECTOR_SHIFT); ++ if (dm_bufio_get_device_size(f->bufio) < fec_blocks) { + ti->error = "FEC device is too small"; + return -E2BIG; + } +diff --git a/drivers/media/pci/cx23885/cx23885-core.c b/drivers/media/pci/cx23885/cx23885-core.c +index fd5c52b21436b..a1d738969d7b1 100644 +--- a/drivers/media/pci/cx23885/cx23885-core.c ++++ b/drivers/media/pci/cx23885/cx23885-core.c +@@ -2084,6 +2084,10 @@ static struct { + * 0x1451 is PCI ID for the IOMMU found on Ryzen + */ + { PCI_VENDOR_ID_AMD, 0x1451 }, ++ /* According to sudo lspci -nn, ++ * 0x1423 is the PCI ID for the IOMMU found on Kaveri ++ */ ++ { PCI_VENDOR_ID_AMD, 0x1423 }, + }; + + static bool cx23885_does_need_dma_reset(void) +diff --git a/drivers/memstick/core/ms_block.c b/drivers/memstick/core/ms_block.c +index 716fc8ed31d32..8a02f11076f9a 100644 +--- a/drivers/memstick/core/ms_block.c ++++ b/drivers/memstick/core/ms_block.c +@@ -2146,7 +2146,7 @@ static int msb_init_disk(struct memstick_dev *card) + set_disk_ro(msb->disk, 1); + + msb_start(card); +- device_add_disk(&card->dev, msb->disk); ++ device_add_disk(&card->dev, msb->disk, NULL); + dbg("Disk added"); + return 0; + +diff --git a/drivers/memstick/core/mspro_block.c b/drivers/memstick/core/mspro_block.c +index 5ee932631faed..0cd30dcb68017 100644 +--- a/drivers/memstick/core/mspro_block.c ++++ b/drivers/memstick/core/mspro_block.c +@@ -1236,7 +1236,7 @@ static int mspro_block_init_disk(struct memstick_dev *card) + set_capacity(msb->disk, capacity); + dev_dbg(&card->dev, "capacity set %ld\n", capacity); + +- device_add_disk(&card->dev, msb->disk); ++ device_add_disk(&card->dev, msb->disk, NULL); + msb->active = 1; + return 0; + +diff --git a/drivers/misc/eeprom/eeprom_93xx46.c b/drivers/misc/eeprom/eeprom_93xx46.c +index a3248ebd28c62..182feab6da25b 100644 +--- a/drivers/misc/eeprom/eeprom_93xx46.c ++++ b/drivers/misc/eeprom/eeprom_93xx46.c +@@ -38,6 +38,10 @@ static const struct eeprom_93xx46_devtype_data atmel_at93c46d_data = { + EEPROM_93XX46_QUIRK_INSTRUCTION_LENGTH, + }; + ++static const struct eeprom_93xx46_devtype_data microchip_93lc46b_data = { ++ .quirks = EEPROM_93XX46_QUIRK_EXTRA_READ_CYCLE, ++}; ++ + struct eeprom_93xx46_dev { + struct spi_device *spi; + struct eeprom_93xx46_platform_data *pdata; +@@ -58,6 +62,11 @@ static inline bool has_quirk_instruction_length(struct eeprom_93xx46_dev *edev) + return edev->pdata->quirks & EEPROM_93XX46_QUIRK_INSTRUCTION_LENGTH; + } + ++static inline bool has_quirk_extra_read_cycle(struct eeprom_93xx46_dev *edev) ++{ ++ return edev->pdata->quirks & EEPROM_93XX46_QUIRK_EXTRA_READ_CYCLE; ++} ++ + static int eeprom_93xx46_read(void *priv, unsigned int off, + void *val, size_t count) + { +@@ -99,6 +108,11 @@ static int eeprom_93xx46_read(void *priv, unsigned int off, + dev_dbg(&edev->spi->dev, "read cmd 0x%x, %d Hz\n", + cmd_addr, edev->spi->max_speed_hz); + ++ if (has_quirk_extra_read_cycle(edev)) { ++ cmd_addr <<= 1; ++ bits += 1; ++ } ++ + spi_message_init(&m); + + t[0].tx_buf = (char *)&cmd_addr; +@@ -366,6 +380,7 @@ static void select_deassert(void *context) + static const struct of_device_id eeprom_93xx46_of_table[] = { + { .compatible = "eeprom-93xx46", }, + { .compatible = "atmel,at93c46d", .data = &atmel_at93c46d_data, }, ++ { .compatible = "microchip,93lc46b", .data = µchip_93lc46b_data, }, + {} + }; + MODULE_DEVICE_TABLE(of, eeprom_93xx46_of_table); +diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c +index 90656b625b9a6..77324ea4eb93e 100644 +--- a/drivers/mmc/core/block.c ++++ b/drivers/mmc/core/block.c +@@ -2671,7 +2671,7 @@ static int mmc_add_disk(struct mmc_blk_data *md) + int ret; + struct mmc_card *card = md->queue.card; + +- device_add_disk(md->parent, md->disk); ++ device_add_disk(md->parent, md->disk, NULL); + md->force_ro.show = force_ro_show; + md->force_ro.store = force_ro_store; + sysfs_attr_init(&md->force_ro.attr); +diff --git a/drivers/mmc/host/sdhci-of-dwcmshc.c b/drivers/mmc/host/sdhci-of-dwcmshc.c +index 1b7cd144fb01a..a34b17b284a53 100644 +--- a/drivers/mmc/host/sdhci-of-dwcmshc.c ++++ b/drivers/mmc/host/sdhci-of-dwcmshc.c +@@ -28,6 +28,7 @@ static const struct sdhci_ops sdhci_dwcmshc_ops = { + static const struct sdhci_pltfm_data sdhci_dwcmshc_pdata = { + .ops = &sdhci_dwcmshc_ops, + .quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN, ++ .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN, + }; + + static int dwcmshc_probe(struct platform_device *pdev) +diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c +index 29c0bfd74e8a1..6a41dfa3c36ba 100644 +--- a/drivers/mtd/mtd_blkdevs.c ++++ b/drivers/mtd/mtd_blkdevs.c +@@ -447,7 +447,7 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new) + if (new->readonly) + set_disk_ro(gd, 1); + +- device_add_disk(&new->mtd->dev, gd); ++ device_add_disk(&new->mtd->dev, gd, NULL); + + if (new->disk_attributes) { + ret = sysfs_create_group(&disk_to_dev(gd)->kobj, +diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c +index 6fd1a639ec533..0c9e6cb0e3418 100644 +--- a/drivers/net/ethernet/realtek/r8169.c ++++ b/drivers/net/ethernet/realtek/r8169.c +@@ -4238,6 +4238,7 @@ static void r8168_pll_power_down(struct rtl8169_private *tp) + + switch (tp->mac_version) { + case RTL_GIGA_MAC_VER_25 ... RTL_GIGA_MAC_VER_26: ++ case RTL_GIGA_MAC_VER_29 ... RTL_GIGA_MAC_VER_30: + case RTL_GIGA_MAC_VER_32 ... RTL_GIGA_MAC_VER_33: + case RTL_GIGA_MAC_VER_37: + case RTL_GIGA_MAC_VER_39: +@@ -4265,6 +4266,7 @@ static void r8168_pll_power_up(struct rtl8169_private *tp) + { + switch (tp->mac_version) { + case RTL_GIGA_MAC_VER_25 ... RTL_GIGA_MAC_VER_26: ++ case RTL_GIGA_MAC_VER_29 ... RTL_GIGA_MAC_VER_30: + case RTL_GIGA_MAC_VER_32 ... RTL_GIGA_MAC_VER_33: + case RTL_GIGA_MAC_VER_37: + case RTL_GIGA_MAC_VER_39: +diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c +index 991b9cc180006..5907b34037c24 100644 +--- a/drivers/net/wireless/marvell/mwifiex/pcie.c ++++ b/drivers/net/wireless/marvell/mwifiex/pcie.c +@@ -381,6 +381,8 @@ static void mwifiex_pcie_reset_prepare(struct pci_dev *pdev) + clear_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP, &card->work_flags); + clear_bit(MWIFIEX_IFACE_WORK_CARD_RESET, &card->work_flags); + mwifiex_dbg(adapter, INFO, "%s, successful\n", __func__); ++ ++ card->pci_reset_ongoing = true; + } + + /* +@@ -409,6 +411,8 @@ static void mwifiex_pcie_reset_done(struct pci_dev *pdev) + dev_err(&pdev->dev, "reinit failed: %d\n", ret); + else + mwifiex_dbg(adapter, INFO, "%s, successful\n", __func__); ++ ++ card->pci_reset_ongoing = false; + } + + static const struct pci_error_handlers mwifiex_pcie_err_handler = { +@@ -3000,7 +3004,19 @@ static void mwifiex_cleanup_pcie(struct mwifiex_adapter *adapter) + int ret; + u32 fw_status; + +- cancel_work_sync(&card->work); ++ /* Perform the cancel_work_sync() only when we're not resetting ++ * the card. It's because that function never returns if we're ++ * in reset path. If we're here when resetting the card, it means ++ * that we failed to reset the card (reset failure path). ++ */ ++ if (!card->pci_reset_ongoing) { ++ mwifiex_dbg(adapter, MSG, "performing cancel_work_sync()...\n"); ++ cancel_work_sync(&card->work); ++ mwifiex_dbg(adapter, MSG, "cancel_work_sync() done\n"); ++ } else { ++ mwifiex_dbg(adapter, MSG, ++ "skipped cancel_work_sync() because we're in card reset failure path\n"); ++ } + + ret = mwifiex_read_reg(adapter, reg->fw_status, &fw_status); + if (fw_status == FIRMWARE_READY_PCIE) { +diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.h b/drivers/net/wireless/marvell/mwifiex/pcie.h +index f7ce9b6db6b41..72d0c01ff3592 100644 +--- a/drivers/net/wireless/marvell/mwifiex/pcie.h ++++ b/drivers/net/wireless/marvell/mwifiex/pcie.h +@@ -391,6 +391,8 @@ struct pcie_service_card { + struct mwifiex_msix_context share_irq_ctx; + struct work_struct work; + unsigned long work_flags; ++ ++ bool pci_reset_ongoing; + }; + + static inline int +diff --git a/drivers/nvdimm/blk.c b/drivers/nvdimm/blk.c +index 62e9cb167aad5..db45c6bbb7bb1 100644 +--- a/drivers/nvdimm/blk.c ++++ b/drivers/nvdimm/blk.c +@@ -290,7 +290,7 @@ static int nsblk_attach_disk(struct nd_namespace_blk *nsblk) + } + + set_capacity(disk, available_disk_size >> SECTOR_SHIFT); +- device_add_disk(dev, disk); ++ device_add_disk(dev, disk, NULL); + revalidate_disk(disk); + return 0; + } +diff --git a/drivers/nvdimm/btt.c b/drivers/nvdimm/btt.c +index 853edc649ed41..b6823e66af13c 100644 +--- a/drivers/nvdimm/btt.c ++++ b/drivers/nvdimm/btt.c +@@ -1565,7 +1565,7 @@ static int btt_blk_init(struct btt *btt) + } + } + set_capacity(btt->btt_disk, btt->nlba * btt->sector_size >> 9); +- device_add_disk(&btt->nd_btt->dev, btt->btt_disk); ++ device_add_disk(&btt->nd_btt->dev, btt->btt_disk, NULL); + btt->nd_btt->size = btt->nlba * (u64)btt->sector_size; + revalidate_disk(btt->btt_disk); + +diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c +index a7ce2f1761a2c..d6f981f6ef592 100644 +--- a/drivers/nvdimm/pmem.c ++++ b/drivers/nvdimm/pmem.c +@@ -479,7 +479,7 @@ static int pmem_attach_disk(struct device *dev, + gendev = disk_to_dev(disk); + gendev->groups = pmem_attribute_groups; + +- device_add_disk(dev, disk); ++ device_add_disk(dev, disk, NULL); + if (devm_add_action_or_reset(dev, pmem_release_disk, pmem)) + return -ENOMEM; + +diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c +index b633ea40430ee..513dd1e2aac76 100644 +--- a/drivers/nvme/host/core.c ++++ b/drivers/nvme/host/core.c +@@ -2842,6 +2842,14 @@ const struct attribute_group nvme_ns_id_attr_group = { + .is_visible = nvme_ns_id_attrs_are_visible, + }; + ++const struct attribute_group *nvme_ns_id_attr_groups[] = { ++ &nvme_ns_id_attr_group, ++#ifdef CONFIG_NVM ++ &nvme_nvm_attr_group, ++#endif ++ NULL, ++}; ++ + #define nvme_show_str_function(field) \ + static ssize_t field##_show(struct device *dev, \ + struct device_attribute *attr, char *buf) \ +@@ -3211,14 +3219,7 @@ static void nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid) + + nvme_get_ctrl(ctrl); + +- device_add_disk(ctrl->device, ns->disk); +- if (sysfs_create_group(&disk_to_dev(ns->disk)->kobj, +- &nvme_ns_id_attr_group)) +- pr_warn("%s: failed to create sysfs group for identification\n", +- ns->disk->disk_name); +- if (ns->ndev && nvme_nvm_register_sysfs(ns)) +- pr_warn("%s: failed to register lightnvm sysfs group for identification\n", +- ns->disk->disk_name); ++ device_add_disk(ctrl->device, ns->disk, nvme_ns_id_attr_groups); + + nvme_mpath_add_disk(ns, id); + nvme_fault_inject_init(ns); +@@ -3252,10 +3253,6 @@ static void nvme_ns_remove(struct nvme_ns *ns) + synchronize_srcu(&ns->head->srcu); /* wait for concurrent submissions */ + + if (ns->disk && ns->disk->flags & GENHD_FL_UP) { +- sysfs_remove_group(&disk_to_dev(ns->disk)->kobj, +- &nvme_ns_id_attr_group); +- if (ns->ndev) +- nvme_nvm_unregister_sysfs(ns); + del_gendisk(ns->disk); + blk_cleanup_queue(ns->queue); + if (blk_get_integrity(ns->disk)) +diff --git a/drivers/nvme/host/lightnvm.c b/drivers/nvme/host/lightnvm.c +index a69553e75f38e..d10257b9c5236 100644 +--- a/drivers/nvme/host/lightnvm.c ++++ b/drivers/nvme/host/lightnvm.c +@@ -1193,10 +1193,29 @@ static NVM_DEV_ATTR_12_RO(multiplane_modes); + static NVM_DEV_ATTR_12_RO(media_capabilities); + static NVM_DEV_ATTR_12_RO(max_phys_secs); + +-static struct attribute *nvm_dev_attrs_12[] = { ++/* 2.0 values */ ++static NVM_DEV_ATTR_20_RO(groups); ++static NVM_DEV_ATTR_20_RO(punits); ++static NVM_DEV_ATTR_20_RO(chunks); ++static NVM_DEV_ATTR_20_RO(clba); ++static NVM_DEV_ATTR_20_RO(ws_min); ++static NVM_DEV_ATTR_20_RO(ws_opt); ++static NVM_DEV_ATTR_20_RO(maxoc); ++static NVM_DEV_ATTR_20_RO(maxocpu); ++static NVM_DEV_ATTR_20_RO(mw_cunits); ++static NVM_DEV_ATTR_20_RO(write_typ); ++static NVM_DEV_ATTR_20_RO(write_max); ++static NVM_DEV_ATTR_20_RO(reset_typ); ++static NVM_DEV_ATTR_20_RO(reset_max); ++ ++static struct attribute *nvm_dev_attrs[] = { ++ /* version agnostic attrs */ + &dev_attr_version.attr, + &dev_attr_capabilities.attr, ++ &dev_attr_read_typ.attr, ++ &dev_attr_read_max.attr, + ++ /* 1.2 attrs */ + &dev_attr_vendor_opcode.attr, + &dev_attr_device_mode.attr, + &dev_attr_media_manager.attr, +@@ -1211,8 +1230,6 @@ static struct attribute *nvm_dev_attrs_12[] = { + &dev_attr_page_size.attr, + &dev_attr_hw_sector_size.attr, + &dev_attr_oob_sector_size.attr, +- &dev_attr_read_typ.attr, +- &dev_attr_read_max.attr, + &dev_attr_prog_typ.attr, + &dev_attr_prog_max.attr, + &dev_attr_erase_typ.attr, +@@ -1221,33 +1238,7 @@ static struct attribute *nvm_dev_attrs_12[] = { + &dev_attr_media_capabilities.attr, + &dev_attr_max_phys_secs.attr, + +- NULL, +-}; +- +-static const struct attribute_group nvm_dev_attr_group_12 = { +- .name = "lightnvm", +- .attrs = nvm_dev_attrs_12, +-}; +- +-/* 2.0 values */ +-static NVM_DEV_ATTR_20_RO(groups); +-static NVM_DEV_ATTR_20_RO(punits); +-static NVM_DEV_ATTR_20_RO(chunks); +-static NVM_DEV_ATTR_20_RO(clba); +-static NVM_DEV_ATTR_20_RO(ws_min); +-static NVM_DEV_ATTR_20_RO(ws_opt); +-static NVM_DEV_ATTR_20_RO(maxoc); +-static NVM_DEV_ATTR_20_RO(maxocpu); +-static NVM_DEV_ATTR_20_RO(mw_cunits); +-static NVM_DEV_ATTR_20_RO(write_typ); +-static NVM_DEV_ATTR_20_RO(write_max); +-static NVM_DEV_ATTR_20_RO(reset_typ); +-static NVM_DEV_ATTR_20_RO(reset_max); +- +-static struct attribute *nvm_dev_attrs_20[] = { +- &dev_attr_version.attr, +- &dev_attr_capabilities.attr, +- ++ /* 2.0 attrs */ + &dev_attr_groups.attr, + &dev_attr_punits.attr, + &dev_attr_chunks.attr, +@@ -1258,8 +1249,6 @@ static struct attribute *nvm_dev_attrs_20[] = { + &dev_attr_maxocpu.attr, + &dev_attr_mw_cunits.attr, + +- &dev_attr_read_typ.attr, +- &dev_attr_read_max.attr, + &dev_attr_write_typ.attr, + &dev_attr_write_max.attr, + &dev_attr_reset_typ.attr, +@@ -1268,44 +1257,38 @@ static struct attribute *nvm_dev_attrs_20[] = { + NULL, + }; + +-static const struct attribute_group nvm_dev_attr_group_20 = { +- .name = "lightnvm", +- .attrs = nvm_dev_attrs_20, +-}; +- +-int nvme_nvm_register_sysfs(struct nvme_ns *ns) ++static umode_t nvm_dev_attrs_visible(struct kobject *kobj, ++ struct attribute *attr, int index) + { ++ struct device *dev = container_of(kobj, struct device, kobj); ++ struct gendisk *disk = dev_to_disk(dev); ++ struct nvme_ns *ns = disk->private_data; + struct nvm_dev *ndev = ns->ndev; +- struct nvm_geo *geo = &ndev->geo; ++ struct device_attribute *dev_attr = ++ container_of(attr, typeof(*dev_attr), attr); + + if (!ndev) +- return -EINVAL; +- +- switch (geo->major_ver_id) { +- case 1: +- return sysfs_create_group(&disk_to_dev(ns->disk)->kobj, +- &nvm_dev_attr_group_12); +- case 2: +- return sysfs_create_group(&disk_to_dev(ns->disk)->kobj, +- &nvm_dev_attr_group_20); +- } +- +- return -EINVAL; +-} ++ return 0; + +-void nvme_nvm_unregister_sysfs(struct nvme_ns *ns) +-{ +- struct nvm_dev *ndev = ns->ndev; +- struct nvm_geo *geo = &ndev->geo; ++ if (dev_attr->show == nvm_dev_attr_show) ++ return attr->mode; + +- switch (geo->major_ver_id) { ++ switch (ndev->geo.major_ver_id) { + case 1: +- sysfs_remove_group(&disk_to_dev(ns->disk)->kobj, +- &nvm_dev_attr_group_12); ++ if (dev_attr->show == nvm_dev_attr_show_12) ++ return attr->mode; + break; + case 2: +- sysfs_remove_group(&disk_to_dev(ns->disk)->kobj, +- &nvm_dev_attr_group_20); ++ if (dev_attr->show == nvm_dev_attr_show_20) ++ return attr->mode; + break; + } ++ ++ return 0; + } ++ ++const struct attribute_group nvme_nvm_attr_group = { ++ .name = "lightnvm", ++ .attrs = nvm_dev_attrs, ++ .is_visible = nvm_dev_attrs_visible, ++}; +diff --git a/drivers/nvme/host/multipath.c b/drivers/nvme/host/multipath.c +index e71075338ff5c..4ef05fe00dace 100644 +--- a/drivers/nvme/host/multipath.c ++++ b/drivers/nvme/host/multipath.c +@@ -313,13 +313,9 @@ static void nvme_mpath_set_live(struct nvme_ns *ns) + if (!head->disk) + return; + +- if (!(head->disk->flags & GENHD_FL_UP)) { +- device_add_disk(&head->subsys->dev, head->disk); +- if (sysfs_create_group(&disk_to_dev(head->disk)->kobj, +- &nvme_ns_id_attr_group)) +- dev_warn(&head->subsys->dev, +- "failed to create id group.\n"); +- } ++ if (!(head->disk->flags & GENHD_FL_UP)) ++ device_add_disk(&head->subsys->dev, head->disk, ++ nvme_ns_id_attr_groups); + + synchronize_srcu(&ns->head->srcu); + kblockd_schedule_work(&ns->head->requeue_work); +@@ -541,11 +537,8 @@ void nvme_mpath_remove_disk(struct nvme_ns_head *head) + { + if (!head->disk) + return; +- if (head->disk->flags & GENHD_FL_UP) { +- sysfs_remove_group(&disk_to_dev(head->disk)->kobj, +- &nvme_ns_id_attr_group); ++ if (head->disk->flags & GENHD_FL_UP) + del_gendisk(head->disk); +- } + blk_set_queue_dying(head->disk->queue); + /* make sure all pending bios are cleaned up */ + kblockd_schedule_work(&head->requeue_work); +diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h +index 9c2e7a151e400..2769755067093 100644 +--- a/drivers/nvme/host/nvme.h ++++ b/drivers/nvme/host/nvme.h +@@ -464,7 +464,7 @@ int nvme_delete_ctrl_sync(struct nvme_ctrl *ctrl); + int nvme_get_log(struct nvme_ctrl *ctrl, u32 nsid, u8 log_page, u8 lsp, + void *log, size_t size, u64 offset); + +-extern const struct attribute_group nvme_ns_id_attr_group; ++extern const struct attribute_group *nvme_ns_id_attr_groups[]; + extern const struct block_device_operations nvme_ns_head_ops; + + #ifdef CONFIG_NVME_MULTIPATH +@@ -589,8 +589,7 @@ static inline void nvme_mpath_update_disk_size(struct gendisk *disk) + void nvme_nvm_update_nvm_info(struct nvme_ns *ns); + int nvme_nvm_register(struct nvme_ns *ns, char *disk_name, int node); + void nvme_nvm_unregister(struct nvme_ns *ns); +-int nvme_nvm_register_sysfs(struct nvme_ns *ns); +-void nvme_nvm_unregister_sysfs(struct nvme_ns *ns); ++extern const struct attribute_group nvme_nvm_attr_group; + int nvme_nvm_ioctl(struct nvme_ns *ns, unsigned int cmd, unsigned long arg); + #else + static inline void nvme_nvm_update_nvm_info(struct nvme_ns *ns) {}; +@@ -601,11 +600,6 @@ static inline int nvme_nvm_register(struct nvme_ns *ns, char *disk_name, + } + + static inline void nvme_nvm_unregister(struct nvme_ns *ns) {}; +-static inline int nvme_nvm_register_sysfs(struct nvme_ns *ns) +-{ +- return 0; +-} +-static inline void nvme_nvm_unregister_sysfs(struct nvme_ns *ns) {}; + static inline int nvme_nvm_ioctl(struct nvme_ns *ns, unsigned int cmd, + unsigned long arg) + { +diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c +index af2149632102a..70f05595da60d 100644 +--- a/drivers/pci/quirks.c ++++ b/drivers/pci/quirks.c +@@ -3961,6 +3961,9 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9183, + /* https://bugzilla.kernel.org/show_bug.cgi?id=42679#c46 */ + DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x91a0, + quirk_dma_func1_alias); ++/* https://bugzilla.kernel.org/show_bug.cgi?id=42679#c135 */ ++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9215, ++ quirk_dma_func1_alias); + /* https://bugzilla.kernel.org/show_bug.cgi?id=42679#c127 */ + DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9220, + quirk_dma_func1_alias); +diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c +index 92400abe35520..bd25c8a156d24 100644 +--- a/drivers/platform/x86/acer-wmi.c ++++ b/drivers/platform/x86/acer-wmi.c +@@ -43,6 +43,7 @@ + #include <linux/input/sparse-keymap.h> + #include <acpi/video.h> + ++ACPI_MODULE_NAME(KBUILD_MODNAME); + MODULE_AUTHOR("Carlos Corbacho"); + MODULE_DESCRIPTION("Acer Laptop WMI Extras Driver"); + MODULE_LICENSE("GPL"); +@@ -93,7 +94,7 @@ MODULE_ALIAS("wmi:676AA15E-6A47-4D9F-A2CC-1E6D18D14026"); + + enum acer_wmi_event_ids { + WMID_HOTKEY_EVENT = 0x1, +- WMID_ACCEL_EVENT = 0x5, ++ WMID_ACCEL_OR_KBD_DOCK_EVENT = 0x5, + }; + + static const struct key_entry acer_wmi_keymap[] __initconst = { +@@ -141,7 +142,9 @@ struct event_return_value { + u8 function; + u8 key_num; + u16 device_state; +- u32 reserved; ++ u16 reserved1; ++ u8 kbd_dock_state; ++ u8 reserved2; + } __attribute__((packed)); + + /* +@@ -219,14 +222,13 @@ struct hotkey_function_type_aa { + /* + * Interface capability flags + */ +-#define ACER_CAP_MAILLED (1<<0) +-#define ACER_CAP_WIRELESS (1<<1) +-#define ACER_CAP_BLUETOOTH (1<<2) +-#define ACER_CAP_BRIGHTNESS (1<<3) +-#define ACER_CAP_THREEG (1<<4) +-#define ACER_CAP_ACCEL (1<<5) +-#define ACER_CAP_RFBTN (1<<6) +-#define ACER_CAP_ANY (0xFFFFFFFF) ++#define ACER_CAP_MAILLED BIT(0) ++#define ACER_CAP_WIRELESS BIT(1) ++#define ACER_CAP_BLUETOOTH BIT(2) ++#define ACER_CAP_BRIGHTNESS BIT(3) ++#define ACER_CAP_THREEG BIT(4) ++#define ACER_CAP_SET_FUNCTION_MODE BIT(5) ++#define ACER_CAP_KBD_DOCK BIT(6) + + /* + * Interface type flags +@@ -249,6 +251,7 @@ static int mailled = -1; + static int brightness = -1; + static int threeg = -1; + static int force_series; ++static int force_caps = -1; + static bool ec_raw_mode; + static bool has_type_aa; + static u16 commun_func_bitmap; +@@ -258,11 +261,13 @@ module_param(mailled, int, 0444); + module_param(brightness, int, 0444); + module_param(threeg, int, 0444); + module_param(force_series, int, 0444); ++module_param(force_caps, int, 0444); + module_param(ec_raw_mode, bool, 0444); + MODULE_PARM_DESC(mailled, "Set initial state of Mail LED"); + MODULE_PARM_DESC(brightness, "Set initial LCD backlight brightness"); + MODULE_PARM_DESC(threeg, "Set initial state of 3G hardware"); + MODULE_PARM_DESC(force_series, "Force a different laptop series"); ++MODULE_PARM_DESC(force_caps, "Force the capability bitmask to this value"); + MODULE_PARM_DESC(ec_raw_mode, "Enable EC raw mode"); + + struct acer_data { +@@ -333,6 +338,15 @@ static int __init dmi_matched(const struct dmi_system_id *dmi) + return 1; + } + ++static int __init set_force_caps(const struct dmi_system_id *dmi) ++{ ++ if (force_caps == -1) { ++ force_caps = (uintptr_t)dmi->driver_data; ++ pr_info("Found %s, set force_caps to 0x%x\n", dmi->ident, force_caps); ++ } ++ return 1; ++} ++ + static struct quirk_entry quirk_unknown = { + }; + +@@ -511,6 +525,33 @@ static const struct dmi_system_id acer_quirks[] __initconst = { + }, + .driver_data = &quirk_acer_travelmate_2490, + }, ++ { ++ .callback = set_force_caps, ++ .ident = "Acer Aspire Switch 10E SW3-016", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Acer"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Aspire SW3-016"), ++ }, ++ .driver_data = (void *)ACER_CAP_KBD_DOCK, ++ }, ++ { ++ .callback = set_force_caps, ++ .ident = "Acer Aspire Switch 10 SW5-012", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Acer"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Aspire SW5-012"), ++ }, ++ .driver_data = (void *)ACER_CAP_KBD_DOCK, ++ }, ++ { ++ .callback = set_force_caps, ++ .ident = "Acer One 10 (S1003)", ++ .matches = { ++ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Acer"), ++ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "One S1003"), ++ }, ++ .driver_data = (void *)ACER_CAP_KBD_DOCK, ++ }, + {} + }; + +@@ -1266,10 +1307,8 @@ static void __init type_aa_dmi_decode(const struct dmi_header *header, void *d) + interface->capability |= ACER_CAP_THREEG; + if (type_aa->commun_func_bitmap & ACER_WMID3_GDS_BLUETOOTH) + interface->capability |= ACER_CAP_BLUETOOTH; +- if (type_aa->commun_func_bitmap & ACER_WMID3_GDS_RFBTN) { +- interface->capability |= ACER_CAP_RFBTN; ++ if (type_aa->commun_func_bitmap & ACER_WMID3_GDS_RFBTN) + commun_func_bitmap &= ~ACER_WMID3_GDS_RFBTN; +- } + + commun_fn_key_number = type_aa->commun_fn_key_number; + } +@@ -1530,7 +1569,7 @@ static int acer_gsensor_event(void) + struct acpi_buffer output; + union acpi_object out_obj[5]; + +- if (!has_cap(ACER_CAP_ACCEL)) ++ if (!acer_wmi_accel_dev) + return -1; + + output.length = sizeof(out_obj); +@@ -1553,6 +1592,71 @@ static int acer_gsensor_event(void) + return 0; + } + ++/* ++ * Switch series keyboard dock status ++ */ ++static int acer_kbd_dock_state_to_sw_tablet_mode(u8 kbd_dock_state) ++{ ++ switch (kbd_dock_state) { ++ case 0x01: /* Docked, traditional clamshell laptop mode */ ++ return 0; ++ case 0x04: /* Stand-alone tablet */ ++ case 0x40: /* Docked, tent mode, keyboard not usable */ ++ return 1; ++ default: ++ pr_warn("Unknown kbd_dock_state 0x%02x\n", kbd_dock_state); ++ } ++ ++ return 0; ++} ++ ++static void acer_kbd_dock_get_initial_state(void) ++{ ++ u8 *output, input[8] = { 0x05, 0x00, }; ++ struct acpi_buffer input_buf = { sizeof(input), input }; ++ struct acpi_buffer output_buf = { ACPI_ALLOCATE_BUFFER, NULL }; ++ union acpi_object *obj; ++ acpi_status status; ++ int sw_tablet_mode; ++ ++ status = wmi_evaluate_method(WMID_GUID3, 0, 0x2, &input_buf, &output_buf); ++ if (ACPI_FAILURE(status)) { ++ ACPI_EXCEPTION((AE_INFO, status, "Error getting keyboard-dock initial status")); ++ return; ++ } ++ ++ obj = output_buf.pointer; ++ if (!obj || obj->type != ACPI_TYPE_BUFFER || obj->buffer.length != 8) { ++ pr_err("Unexpected output format getting keyboard-dock initial status\n"); ++ goto out_free_obj; ++ } ++ ++ output = obj->buffer.pointer; ++ if (output[0] != 0x00 || (output[3] != 0x05 && output[3] != 0x45)) { ++ pr_err("Unexpected output [0]=0x%02x [3]=0x%02x getting keyboard-dock initial status\n", ++ output[0], output[3]); ++ goto out_free_obj; ++ } ++ ++ sw_tablet_mode = acer_kbd_dock_state_to_sw_tablet_mode(output[4]); ++ input_report_switch(acer_wmi_input_dev, SW_TABLET_MODE, sw_tablet_mode); ++ ++out_free_obj: ++ kfree(obj); ++} ++ ++static void acer_kbd_dock_event(const struct event_return_value *event) ++{ ++ int sw_tablet_mode; ++ ++ if (!has_cap(ACER_CAP_KBD_DOCK)) ++ return; ++ ++ sw_tablet_mode = acer_kbd_dock_state_to_sw_tablet_mode(event->kbd_dock_state); ++ input_report_switch(acer_wmi_input_dev, SW_TABLET_MODE, sw_tablet_mode); ++ input_sync(acer_wmi_input_dev); ++} ++ + /* + * Rfkill devices + */ +@@ -1780,8 +1884,9 @@ static void acer_wmi_notify(u32 value, void *context) + sparse_keymap_report_event(acer_wmi_input_dev, scancode, 1, true); + } + break; +- case WMID_ACCEL_EVENT: ++ case WMID_ACCEL_OR_KBD_DOCK_EVENT: + acer_gsensor_event(); ++ acer_kbd_dock_event(&return_value); + break; + default: + pr_warn("Unknown function number - %d - %d\n", +@@ -1939,8 +2044,6 @@ static int __init acer_wmi_accel_setup(void) + if (err) + return err; + +- interface->capability |= ACER_CAP_ACCEL; +- + acer_wmi_accel_dev = input_allocate_device(); + if (!acer_wmi_accel_dev) + return -ENOMEM; +@@ -1966,11 +2069,6 @@ err_free_dev: + return err; + } + +-static void acer_wmi_accel_destroy(void) +-{ +- input_unregister_device(acer_wmi_accel_dev); +-} +- + static int __init acer_wmi_input_setup(void) + { + acpi_status status; +@@ -1988,6 +2086,9 @@ static int __init acer_wmi_input_setup(void) + if (err) + goto err_free_dev; + ++ if (has_cap(ACER_CAP_KBD_DOCK)) ++ input_set_capability(acer_wmi_input_dev, EV_SW, SW_TABLET_MODE); ++ + status = wmi_install_notify_handler(ACERWMID_EVENT_GUID, + acer_wmi_notify, NULL); + if (ACPI_FAILURE(status)) { +@@ -1995,6 +2096,9 @@ static int __init acer_wmi_input_setup(void) + goto err_free_dev; + } + ++ if (has_cap(ACER_CAP_KBD_DOCK)) ++ acer_kbd_dock_get_initial_state(); ++ + err = input_register_device(acer_wmi_input_dev); + if (err) + goto err_uninstall_notifier; +@@ -2125,7 +2229,7 @@ static int acer_resume(struct device *dev) + if (has_cap(ACER_CAP_BRIGHTNESS)) + set_u32(data->brightness, ACER_CAP_BRIGHTNESS); + +- if (has_cap(ACER_CAP_ACCEL)) ++ if (acer_wmi_accel_dev) + acer_gsensor_init(); + + return 0; +@@ -2240,7 +2344,7 @@ static int __init acer_wmi_init(void) + } + /* WMID always provides brightness methods */ + interface->capability |= ACER_CAP_BRIGHTNESS; +- } else if (!wmi_has_guid(WMID_GUID2) && interface && !has_type_aa) { ++ } else if (!wmi_has_guid(WMID_GUID2) && interface && !has_type_aa && force_caps == -1) { + pr_err("No WMID device detection method found\n"); + return -ENODEV; + } +@@ -2270,7 +2374,14 @@ static int __init acer_wmi_init(void) + if (acpi_video_get_backlight_type() != acpi_backlight_vendor) + interface->capability &= ~ACER_CAP_BRIGHTNESS; + +- if (wmi_has_guid(WMID_GUID3)) { ++ if (wmi_has_guid(WMID_GUID3)) ++ interface->capability |= ACER_CAP_SET_FUNCTION_MODE; ++ ++ if (force_caps != -1) ++ interface->capability = force_caps; ++ ++ if (wmi_has_guid(WMID_GUID3) && ++ (interface->capability & ACER_CAP_SET_FUNCTION_MODE)) { + if (ACPI_FAILURE(acer_wmi_enable_rf_button())) + pr_warn("Cannot enable RF Button Driver\n"); + +@@ -2333,8 +2444,8 @@ error_device_alloc: + error_platform_register: + if (wmi_has_guid(ACERWMID_EVENT_GUID)) + acer_wmi_input_destroy(); +- if (has_cap(ACER_CAP_ACCEL)) +- acer_wmi_accel_destroy(); ++ if (acer_wmi_accel_dev) ++ input_unregister_device(acer_wmi_accel_dev); + + return err; + } +@@ -2344,8 +2455,8 @@ static void __exit acer_wmi_exit(void) + if (wmi_has_guid(ACERWMID_EVENT_GUID)) + acer_wmi_input_destroy(); + +- if (has_cap(ACER_CAP_ACCEL)) +- acer_wmi_accel_destroy(); ++ if (acer_wmi_accel_dev) ++ input_unregister_device(acer_wmi_accel_dev); + + remove_debugfs(); + platform_device_unregister(acer_platform_device); +diff --git a/drivers/s390/block/dasd_genhd.c b/drivers/s390/block/dasd_genhd.c +index 7036a6c6f86ff..5542d9eadfe0e 100644 +--- a/drivers/s390/block/dasd_genhd.c ++++ b/drivers/s390/block/dasd_genhd.c +@@ -76,7 +76,7 @@ int dasd_gendisk_alloc(struct dasd_block *block) + gdp->queue = block->request_queue; + block->gdp = gdp; + set_capacity(block->gdp, 0); +- device_add_disk(&base->cdev->dev, block->gdp); ++ device_add_disk(&base->cdev->dev, block->gdp, NULL); + return 0; + } + +diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c +index 23e526cda5c10..4e8aedd50cb0d 100644 +--- a/drivers/s390/block/dcssblk.c ++++ b/drivers/s390/block/dcssblk.c +@@ -685,7 +685,7 @@ dcssblk_add_store(struct device *dev, struct device_attribute *attr, const char + } + + get_device(&dev_info->dev); +- device_add_disk(&dev_info->dev, dev_info->gd); ++ device_add_disk(&dev_info->dev, dev_info->gd, NULL); + + switch (dev_info->segment_type) { + case SEG_TYPE_SR: +diff --git a/drivers/s390/block/scm_blk.c b/drivers/s390/block/scm_blk.c +index 98f66b7b67945..e01889394c841 100644 +--- a/drivers/s390/block/scm_blk.c ++++ b/drivers/s390/block/scm_blk.c +@@ -500,7 +500,7 @@ int scm_blk_dev_setup(struct scm_blk_dev *bdev, struct scm_device *scmdev) + + /* 512 byte sectors */ + set_capacity(bdev->gendisk, scmdev->size >> 9); +- device_add_disk(&scmdev->dev, bdev->gendisk); ++ device_add_disk(&scmdev->dev, bdev->gendisk, NULL); + return 0; + + out_queue: +diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c +index f2f14d8d59432..342352d8e7bf9 100644 +--- a/drivers/scsi/sd.c ++++ b/drivers/scsi/sd.c +@@ -3348,7 +3348,7 @@ static void sd_probe_async(void *data, async_cookie_t cookie) + } + + blk_pm_runtime_init(sdp->request_queue, dev); +- device_add_disk(dev, gd); ++ device_add_disk(dev, gd, NULL); + if (sdkp->capacity) + sd_dif_config_host(sdkp); + +diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c +index 5be3d6b7991b4..45c8bf39ad238 100644 +--- a/drivers/scsi/sr.c ++++ b/drivers/scsi/sr.c +@@ -758,7 +758,7 @@ static int sr_probe(struct device *dev) + + dev_set_drvdata(dev, cd); + disk->flags |= GENHD_FL_REMOVABLE; +- device_add_disk(&sdev->sdev_gendev, disk); ++ device_add_disk(&sdev->sdev_gendev, disk, NULL); + + sdev_printk(KERN_DEBUG, sdev, + "Attached scsi CD-ROM %s\n", cd->cdi.name); +diff --git a/fs/btrfs/delayed-inode.c b/fs/btrfs/delayed-inode.c +index 14855972dee30..fea5ccfade5c6 100644 +--- a/fs/btrfs/delayed-inode.c ++++ b/fs/btrfs/delayed-inode.c +@@ -642,7 +642,7 @@ static int btrfs_delayed_inode_reserve_metadata( + btrfs_ino(inode), + num_bytes, 1); + } else { +- btrfs_qgroup_free_meta_prealloc(root, fs_info->nodesize); ++ btrfs_qgroup_free_meta_prealloc(root, num_bytes); + } + return ret; + } +diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c +index 646152f305843..a202f2f12b1c0 100644 +--- a/fs/btrfs/file.c ++++ b/fs/btrfs/file.c +@@ -3016,8 +3016,11 @@ reserve_space: + goto out; + ret = btrfs_qgroup_reserve_data(inode, &data_reserved, + alloc_start, bytes_to_reserve); +- if (ret) ++ if (ret) { ++ unlock_extent_cached(&BTRFS_I(inode)->io_tree, lockstart, ++ lockend, &cached_state); + goto out; ++ } + ret = btrfs_prealloc_file_range(inode, mode, alloc_start, + alloc_end - alloc_start, + i_blocksize(inode), +diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c +index f3658d6ea6571..1c053e10b33ba 100644 +--- a/fs/btrfs/ioctl.c ++++ b/fs/btrfs/ioctl.c +@@ -1842,7 +1842,10 @@ static noinline int btrfs_ioctl_snap_create_v2(struct file *file, + if (vol_args->flags & BTRFS_SUBVOL_RDONLY) + readonly = true; + if (vol_args->flags & BTRFS_SUBVOL_QGROUP_INHERIT) { +- if (vol_args->size > PAGE_SIZE) { ++ u64 nums; ++ ++ if (vol_args->size < sizeof(*inherit) || ++ vol_args->size > PAGE_SIZE) { + ret = -EINVAL; + goto free_args; + } +@@ -1851,6 +1854,20 @@ static noinline int btrfs_ioctl_snap_create_v2(struct file *file, + ret = PTR_ERR(inherit); + goto free_args; + } ++ ++ if (inherit->num_qgroups > PAGE_SIZE || ++ inherit->num_ref_copies > PAGE_SIZE || ++ inherit->num_excl_copies > PAGE_SIZE) { ++ ret = -EINVAL; ++ goto free_inherit; ++ } ++ ++ nums = inherit->num_qgroups + 2 * inherit->num_ref_copies + ++ 2 * inherit->num_excl_copies; ++ if (vol_args->size != struct_size(inherit, qgroups, nums)) { ++ ret = -EINVAL; ++ goto free_inherit; ++ } + } + + ret = btrfs_ioctl_snap_create_transid(file, vol_args->name, +diff --git a/fs/btrfs/raid56.c b/fs/btrfs/raid56.c +index 927f9f3daddbf..a91f74cf5cd18 100644 +--- a/fs/btrfs/raid56.c ++++ b/fs/btrfs/raid56.c +@@ -1182,22 +1182,19 @@ static noinline void finish_rmw(struct btrfs_raid_bio *rbio) + int nr_data = rbio->nr_data; + int stripe; + int pagenr; +- int p_stripe = -1; +- int q_stripe = -1; ++ bool has_qstripe; + struct bio_list bio_list; + struct bio *bio; + int ret; + + bio_list_init(&bio_list); + +- if (rbio->real_stripes - rbio->nr_data == 1) { +- p_stripe = rbio->real_stripes - 1; +- } else if (rbio->real_stripes - rbio->nr_data == 2) { +- p_stripe = rbio->real_stripes - 2; +- q_stripe = rbio->real_stripes - 1; +- } else { ++ if (rbio->real_stripes - rbio->nr_data == 1) ++ has_qstripe = false; ++ else if (rbio->real_stripes - rbio->nr_data == 2) ++ has_qstripe = true; ++ else + BUG(); +- } + + /* at this point we either have a full stripe, + * or we've read the full stripe from the drive. +@@ -1241,7 +1238,7 @@ static noinline void finish_rmw(struct btrfs_raid_bio *rbio) + SetPageUptodate(p); + pointers[stripe++] = kmap(p); + +- if (q_stripe != -1) { ++ if (has_qstripe) { + + /* + * raid6, add the qstripe and call the +@@ -2340,8 +2337,7 @@ static noinline void finish_parity_scrub(struct btrfs_raid_bio *rbio, + int nr_data = rbio->nr_data; + int stripe; + int pagenr; +- int p_stripe = -1; +- int q_stripe = -1; ++ bool has_qstripe; + struct page *p_page = NULL; + struct page *q_page = NULL; + struct bio_list bio_list; +@@ -2351,14 +2347,12 @@ static noinline void finish_parity_scrub(struct btrfs_raid_bio *rbio, + + bio_list_init(&bio_list); + +- if (rbio->real_stripes - rbio->nr_data == 1) { +- p_stripe = rbio->real_stripes - 1; +- } else if (rbio->real_stripes - rbio->nr_data == 2) { +- p_stripe = rbio->real_stripes - 2; +- q_stripe = rbio->real_stripes - 1; +- } else { ++ if (rbio->real_stripes - rbio->nr_data == 1) ++ has_qstripe = false; ++ else if (rbio->real_stripes - rbio->nr_data == 2) ++ has_qstripe = true; ++ else + BUG(); +- } + + if (bbio->num_tgtdevs && bbio->tgtdev_map[rbio->scrubp]) { + is_replace = 1; +@@ -2380,17 +2374,22 @@ static noinline void finish_parity_scrub(struct btrfs_raid_bio *rbio, + goto cleanup; + SetPageUptodate(p_page); + +- if (q_stripe != -1) { ++ if (has_qstripe) { ++ /* RAID6, allocate and map temp space for the Q stripe */ + q_page = alloc_page(GFP_NOFS | __GFP_HIGHMEM); + if (!q_page) { + __free_page(p_page); + goto cleanup; + } + SetPageUptodate(q_page); ++ pointers[rbio->real_stripes - 1] = kmap(q_page); + } + + atomic_set(&rbio->error, 0); + ++ /* Map the parity stripe just once */ ++ pointers[nr_data] = kmap(p_page); ++ + for_each_set_bit(pagenr, rbio->dbitmap, rbio->stripe_npages) { + struct page *p; + void *parity; +@@ -2400,17 +2399,8 @@ static noinline void finish_parity_scrub(struct btrfs_raid_bio *rbio, + pointers[stripe] = kmap(p); + } + +- /* then add the parity stripe */ +- pointers[stripe++] = kmap(p_page); +- +- if (q_stripe != -1) { +- +- /* +- * raid6, add the qstripe and call the +- * library function to fill in our p/q +- */ +- pointers[stripe++] = kmap(q_page); +- ++ if (has_qstripe) { ++ /* RAID6, call the library function to fill in our P/Q */ + raid6_call.gen_syndrome(rbio->real_stripes, PAGE_SIZE, + pointers); + } else { +@@ -2431,12 +2421,14 @@ static noinline void finish_parity_scrub(struct btrfs_raid_bio *rbio, + + for (stripe = 0; stripe < nr_data; stripe++) + kunmap(page_in_rbio(rbio, stripe, pagenr, 0)); +- kunmap(p_page); + } + ++ kunmap(p_page); + __free_page(p_page); +- if (q_page) ++ if (q_page) { ++ kunmap(q_page); + __free_page(q_page); ++ } + + writeback: + /* +diff --git a/include/linux/eeprom_93xx46.h b/include/linux/eeprom_93xx46.h +index eec7928ff8fe0..99580c22f91a4 100644 +--- a/include/linux/eeprom_93xx46.h ++++ b/include/linux/eeprom_93xx46.h +@@ -16,6 +16,8 @@ struct eeprom_93xx46_platform_data { + #define EEPROM_93XX46_QUIRK_SINGLE_WORD_READ (1 << 0) + /* Instructions such as EWEN are (addrlen + 2) in length. */ + #define EEPROM_93XX46_QUIRK_INSTRUCTION_LENGTH (1 << 1) ++/* Add extra cycle after address during a read */ ++#define EEPROM_93XX46_QUIRK_EXTRA_READ_CYCLE BIT(2) + + /* + * optional hooks to control additional logic +diff --git a/include/linux/genhd.h b/include/linux/genhd.h +index f993bc86f3bac..a488098f8638d 100644 +--- a/include/linux/genhd.h ++++ b/include/linux/genhd.h +@@ -402,10 +402,11 @@ static inline void free_part_info(struct hd_struct *part) + extern void part_round_stats(struct request_queue *q, int cpu, struct hd_struct *part); + + /* block/genhd.c */ +-extern void device_add_disk(struct device *parent, struct gendisk *disk); ++extern void device_add_disk(struct device *parent, struct gendisk *disk, ++ const struct attribute_group **groups); + static inline void add_disk(struct gendisk *disk) + { +- device_add_disk(NULL, disk); ++ device_add_disk(NULL, disk, NULL); + } + extern void device_add_disk_no_queue_reg(struct device *parent, struct gendisk *disk); + static inline void add_disk_no_queue_reg(struct gendisk *disk) +diff --git a/net/dsa/Kconfig b/net/dsa/Kconfig +index 4183e4ba27a50..81f620a3c32b1 100644 +--- a/net/dsa/Kconfig ++++ b/net/dsa/Kconfig +@@ -8,6 +8,7 @@ config NET_DSA + tristate "Distributed Switch Architecture" + depends on HAVE_NET_DSA && MAY_USE_DEVLINK + depends on BRIDGE || BRIDGE=n ++ select GRO_CELLS + select NET_SWITCHDEV + select PHYLINK + ---help--- +diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c +index 601534a5bfe8c..598200e9d5226 100644 +--- a/net/dsa/dsa.c ++++ b/net/dsa/dsa.c +@@ -191,7 +191,7 @@ static int dsa_switch_rcv(struct sk_buff *skb, struct net_device *dev, + if (dsa_skb_defer_rx_timestamp(p, skb)) + return 0; + +- netif_receive_skb(skb); ++ gro_cells_receive(&p->gcells, skb); + + return 0; + } +diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h +index 3964c6f7a7c0d..79d17507609ab 100644 +--- a/net/dsa/dsa_priv.h ++++ b/net/dsa/dsa_priv.h +@@ -15,6 +15,7 @@ + #include <linux/netdevice.h> + #include <linux/netpoll.h> + #include <net/dsa.h> ++#include <net/gro_cells.h> + + enum { + DSA_NOTIFIER_AGEING_TIME, +@@ -72,6 +73,8 @@ struct dsa_slave_priv { + + struct pcpu_sw_netstats *stats64; + ++ struct gro_cells gcells; ++ + /* DSA port data, such as switch, port index, etc. */ + struct dsa_port *dp; + +diff --git a/net/dsa/slave.c b/net/dsa/slave.c +index d03c67e761dfa..11f1560de6391 100644 +--- a/net/dsa/slave.c ++++ b/net/dsa/slave.c +@@ -1337,6 +1337,11 @@ int dsa_slave_create(struct dsa_port *port) + free_netdev(slave_dev); + return -ENOMEM; + } ++ ++ ret = gro_cells_init(&p->gcells, slave_dev); ++ if (ret) ++ goto out_free; ++ + p->dp = port; + INIT_LIST_HEAD(&p->mall_tc_list); + p->xmit = cpu_dp->tag_ops->xmit; +@@ -1347,7 +1352,7 @@ int dsa_slave_create(struct dsa_port *port) + ret = dsa_slave_phy_setup(slave_dev); + if (ret) { + netdev_err(master, "error %d setting up slave phy\n", ret); +- goto out_free; ++ goto out_gcells; + } + + dsa_slave_notify(slave_dev, DSA_PORT_REGISTER); +@@ -1366,6 +1371,8 @@ out_phy: + phylink_disconnect_phy(p->dp->pl); + rtnl_unlock(); + phylink_destroy(p->dp->pl); ++out_gcells: ++ gro_cells_destroy(&p->gcells); + out_free: + free_percpu(p->stats64); + free_netdev(slave_dev); +@@ -1386,6 +1393,7 @@ void dsa_slave_destroy(struct net_device *slave_dev) + dsa_slave_notify(slave_dev, DSA_PORT_UNREGISTER); + unregister_netdev(slave_dev); + phylink_destroy(dp->pl); ++ gro_cells_destroy(&p->gcells); + free_percpu(p->stats64); + free_netdev(slave_dev); + } +diff --git a/sound/pci/ctxfi/cthw20k2.c b/sound/pci/ctxfi/cthw20k2.c +index 3c966fafc754a..6c9ab602212ea 100644 +--- a/sound/pci/ctxfi/cthw20k2.c ++++ b/sound/pci/ctxfi/cthw20k2.c +@@ -995,7 +995,7 @@ static int daio_mgr_dao_init(void *blk, unsigned int idx, unsigned int conf) + + if (idx < 4) { + /* S/PDIF output */ +- switch ((conf & 0x7)) { ++ switch ((conf & 0xf)) { + case 1: + set_field(&ctl->txctl[idx], ATXCTL_NUC, 0); + break; +diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c +index 8a943de1e5b55..d63d997763845 100644 +--- a/sound/soc/intel/boards/bytcr_rt5640.c ++++ b/sound/soc/intel/boards/bytcr_rt5640.c +@@ -444,6 +444,18 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = { + BYT_RT5640_SSP0_AIF1 | + BYT_RT5640_MCLK_EN), + }, ++ { ++ .matches = { ++ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ARCHOS"), ++ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "ARCHOS 140 CESIUM"), ++ }, ++ .driver_data = (void *)(BYT_RT5640_IN1_MAP | ++ BYT_RT5640_JD_SRC_JD2_IN4N | ++ BYT_RT5640_OVCD_TH_2000UA | ++ BYT_RT5640_OVCD_SF_0P75 | ++ BYT_RT5640_SSP0_AIF1 | ++ BYT_RT5640_MCLK_EN), ++ }, + { + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), +diff --git a/tools/usb/usbip/libsrc/usbip_host_common.c b/tools/usb/usbip/libsrc/usbip_host_common.c +index b0f7489d069d0..84d0fa85939ed 100644 +--- a/tools/usb/usbip/libsrc/usbip_host_common.c ++++ b/tools/usb/usbip/libsrc/usbip_host_common.c +@@ -35,7 +35,7 @@ + #include "list.h" + #include "sysfs_utils.h" + +-struct udev *udev_context; ++extern struct udev *udev_context; + + static int32_t read_attr_usbip_status(struct usbip_usb_device *udev) + {
