]> git.baikalelectronics.ru Git - kernel.git/commitdiff
Merge tag 'char-misc-4.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregk...
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 5 May 2017 02:07:10 +0000 (19:07 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 5 May 2017 02:15:35 +0000 (19:15 -0700)
Pull char/misc driver updates from Greg KH:
 "Here is the big set of new char/misc driver drivers and features for
  4.12-rc1.

  There's lots of new drivers added this time around, new firmware
  drivers from Google, more auxdisplay drivers, extcon drivers, fpga
  drivers, and a bunch of other driver updates. Nothing major, except if
  you happen to have the hardware for these drivers, and then you will
  be happy :)

  All of these have been in linux-next for a while with no reported
  issues"

* tag 'char-misc-4.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (136 commits)
  firmware: google memconsole: Fix return value check in platform_memconsole_init()
  firmware: Google VPD: Fix return value check in vpd_platform_init()
  goldfish_pipe: fix build warning about using too much stack.
  goldfish_pipe: An implementation of more parallel pipe
  fpga fr br: update supported version numbers
  fpga: region: release FPGA region reference in error path
  fpga altera-hps2fpga: disable/unprepare clock on error in alt_fpga_bridge_probe()
  mei: drop the TODO from samples
  firmware: Google VPD sysfs driver
  firmware: Google VPD: import lib_vpd source files
  misc: lkdtm: Add volatile to intentional NULL pointer reference
  eeprom: idt_89hpesx: Add OF device ID table
  misc: ds1682: Add OF device ID table
  misc: tsl2550: Add OF device ID table
  w1: Remove unneeded use of assert() and remove w1_log.h
  w1: Use kernel common min() implementation
  uio_mf624: Align memory regions to page size and set correct offsets
  uio_mf624: Refactor memory info initialization
  uio: Allow handling of non page-aligned memory regions
  hangcheck-timer: Fix typo in comment
  ...

14 files changed:
1  2 
MAINTAINERS
arch/x86/hyperv/hv_init.c
drivers/char/tpm/tpm-chip.c
drivers/char/virtio_console.c
drivers/dax/dax.c
drivers/firmware/google/memconsole-x86-legacy.c
drivers/gpio/gpiolib.c
drivers/hv/ring_buffer.c
drivers/iio/industrialio-core.c
drivers/infiniband/core/ucm.c
drivers/infiniband/core/user_mad.c
drivers/infiniband/core/uverbs_main.c
drivers/scsi/osd/osd_uld.c
include/linux/hyperv.h

diff --cc MAINTAINERS
Simple merge
index 2b01421f7d0ff0fb49e8fedbb8764b6fd6be04f4,ecaa3f3b1923db4b1d8a274559e0b3ee8494f757..5b882cc0c0e9a96e1bd8beeec260ef657a439de4
@@@ -25,9 -25,9 +25,9 @@@
  #include <linux/vmalloc.h>
  #include <linux/mm.h>
  #include <linux/clockchips.h>
+ #include <linux/hyperv.h>
  
 -#ifdef CONFIG_X86_64
 +#ifdef CONFIG_HYPERV_TSCPAGE
  
  static struct ms_hyperv_tsc_page *tsc_pg;
  
index 9dec9f551b831496024b98eb8f6e1bff7ed4958b,935f0e92ad6155d7a37358271f4e33e121f2627d..322b8a51ffc67d5d9df216c55503b04ebfc08072
@@@ -215,24 -186,8 +215,22 @@@ struct tpm_chip *tpm_chip_alloc(struct 
                chip->flags |= TPM_CHIP_FLAG_VIRTUAL;
  
        cdev_init(&chip->cdev, &tpm_fops);
 +      cdev_init(&chip->cdevs, &tpmrm_fops);
        chip->cdev.owner = THIS_MODULE;
-       chip->cdev.kobj.parent = &chip->dev.kobj;
-       chip->cdevs.kobj.parent = &chip->devs.kobj;
 +      chip->cdevs.owner = THIS_MODULE;
 +
 +      chip->work_space.context_buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
 +      if (!chip->work_space.context_buf) {
 +              rc = -ENOMEM;
 +              goto out;
 +      }
 +      chip->work_space.session_buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
 +      if (!chip->work_space.session_buf) {
 +              rc = -ENOMEM;
 +              goto out;
 +      }
  
 +      chip->locality = -1;
        return chip;
  
  out:
@@@ -275,47 -229,16 +273,26 @@@ static int tpm_add_char_device(struct t
  {
        int rc;
  
-       rc = cdev_add(&chip->cdev, chip->dev.devt, 1);
+       rc = cdev_device_add(&chip->cdev, &chip->dev);
        if (rc) {
                dev_err(&chip->dev,
-                       "unable to cdev_add() %s, major %d, minor %d, err=%d\n",
+                       "unable to cdev_device_add() %s, major %d, minor %d, err=%d\n",
                        dev_name(&chip->dev), MAJOR(chip->dev.devt),
                        MINOR(chip->dev.devt), rc);
 -
                return rc;
        }
  
-       rc = device_add(&chip->dev);
-       if (rc) {
-               dev_err(&chip->dev,
-                       "unable to device_register() %s, major %d, minor %d, err=%d\n",
-                       dev_name(&chip->dev), MAJOR(chip->dev.devt),
-                       MINOR(chip->dev.devt), rc);
-               cdev_del(&chip->cdev);
-               return rc;
-       }
-       if (chip->flags & TPM_CHIP_FLAG_TPM2)
-               rc = cdev_add(&chip->cdevs, chip->devs.devt, 1);
-       if (rc) {
-               dev_err(&chip->dev,
-                       "unable to cdev_add() %s, major %d, minor %d, err=%d\n",
-                       dev_name(&chip->devs), MAJOR(chip->devs.devt),
-                       MINOR(chip->devs.devt), rc);
-               return rc;
-       }
-       if (chip->flags & TPM_CHIP_FLAG_TPM2)
-               rc = device_add(&chip->devs);
-       if (rc) {
-               dev_err(&chip->dev,
-                       "unable to device_register() %s, major %d, minor %d, err=%d\n",
-                       dev_name(&chip->devs), MAJOR(chip->devs.devt),
-                       MINOR(chip->devs.devt), rc);
-               cdev_del(&chip->cdevs);
-               return rc;
++      if (chip->flags & TPM_CHIP_FLAG_TPM2) {
++              rc = cdev_device_add(&chip->cdevs, &chip->devs);
++              if (rc) {
++                      dev_err(&chip->devs,
++                              "unable to cdev_device_add() %s, major %d, minor %d, err=%d\n",
++                              dev_name(&chip->devs), MAJOR(chip->devs.devt),
++                              MINOR(chip->devs.devt), rc);
++                      return rc;
++              }
 +      }
 +
        /* Make the chip available. */
        mutex_lock(&idr_lock);
        idr_replace(&dev_nums_idr, chip, chip->dev_num);
@@@ -449,10 -371,6 +425,8 @@@ void tpm_chip_unregister(struct tpm_chi
  {
        tpm_del_legacy_sysfs(chip);
        tpm_bios_log_teardown(chip);
-       if (chip->flags & TPM_CHIP_FLAG_TPM2) {
-               cdev_del(&chip->cdevs);
-               device_del(&chip->devs);
-       }
++      if (chip->flags & TPM_CHIP_FLAG_TPM2)
++              cdev_device_del(&chip->cdevs, &chip->devs);
        tpm_del_char_device(chip);
  }
  EXPORT_SYMBOL_GPL(tpm_chip_unregister);
Simple merge
index 806f180c80d816b313319f960479a7ad2848c672,0d1ca246f257e0ec81b0eb2c8df9d21f3e9c920d..19795eb35579bae72617377b07e91abbabff30e4
@@@ -718,10 -712,19 +713,19 @@@ static void kill_dax_dev(struct dax_de
         * upon seeing dax_dev->alive == false.
         */
        dax_dev->alive = false;
 -      synchronize_rcu();
 +      synchronize_srcu(&dax_srcu);
        unmap_mapping_range(dax_dev->inode->i_mapping, 0, 0, 1);
-       cdev_del(cdev);
-       device_unregister(dev);
+ }
+ static void unregister_dax_dev(void *dev)
+ {
+       struct dax_dev *dax_dev = to_dax_dev(dev);
+       dev_dbg(dev, "%s\n", __func__);
+       kill_dax_dev(dax_dev);
+       cdev_device_del(&dax_dev->cdev, dev);
+       put_device(dev);
  }
  
  struct dax_dev *devm_create_dax_dev(struct dax_region *dax_region,
index 0000000000000000000000000000000000000000,529078c6248858496b63fe72b235d989ea84a9f7..1f279ee883b9ae26812813a8fdc74ee338161b5f
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,154 +1,153 @@@
 -#include <asm/e820.h>
+ /*
+  * memconsole-x86-legacy.c
+  *
+  * EBDA specific parts of the memory based BIOS console.
+  *
+  * Copyright 2017 Google Inc.
+  *
+  * This program is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License v2.0 as published by
+  * the Free Software Foundation.
+  *
+  * This program is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  * GNU General Public License for more details.
+  */
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+ #include <linux/dmi.h>
+ #include <linux/mm.h>
+ #include <asm/bios_ebda.h>
+ #include <linux/acpi.h>
+ #include "memconsole.h"
+ #define BIOS_MEMCONSOLE_V1_MAGIC      0xDEADBABE
+ #define BIOS_MEMCONSOLE_V2_MAGIC      (('M')|('C'<<8)|('O'<<16)|('N'<<24))
+ struct biosmemcon_ebda {
+       u32 signature;
+       union {
+               struct {
+                       u8  enabled;
+                       u32 buffer_addr;
+                       u16 start;
+                       u16 end;
+                       u16 num_chars;
+                       u8  wrapped;
+               } __packed v1;
+               struct {
+                       u32 buffer_addr;
+                       /* Misdocumented as number of pages! */
+                       u16 num_bytes;
+                       u16 start;
+                       u16 end;
+               } __packed v2;
+       };
+ } __packed;
+ static void found_v1_header(struct biosmemcon_ebda *hdr)
+ {
+       pr_info("memconsole: BIOS console v1 EBDA structure found at %p\n",
+               hdr);
+       pr_info("memconsole: BIOS console buffer at 0x%.8x, start = %d, end = %d, num = %d\n",
+               hdr->v1.buffer_addr, hdr->v1.start,
+               hdr->v1.end, hdr->v1.num_chars);
+       memconsole_setup(phys_to_virt(hdr->v1.buffer_addr), hdr->v1.num_chars);
+ }
+ static void found_v2_header(struct biosmemcon_ebda *hdr)
+ {
+       pr_info("memconsole: BIOS console v2 EBDA structure found at %p\n",
+               hdr);
+       pr_info("memconsole: BIOS console buffer at 0x%.8x, start = %d, end = %d, num_bytes = %d\n",
+               hdr->v2.buffer_addr, hdr->v2.start,
+               hdr->v2.end, hdr->v2.num_bytes);
+       memconsole_setup(phys_to_virt(hdr->v2.buffer_addr + hdr->v2.start),
+                        hdr->v2.end - hdr->v2.start);
+ }
+ /*
+  * Search through the EBDA for the BIOS Memory Console, and
+  * set the global variables to point to it.  Return true if found.
+  */
+ static bool memconsole_ebda_init(void)
+ {
+       unsigned int address;
+       size_t length, cur;
+       address = get_bios_ebda();
+       if (!address) {
+               pr_info("memconsole: BIOS EBDA non-existent.\n");
+               return false;
+       }
+       /* EBDA length is byte 0 of EBDA (in KB) */
+       length = *(u8 *)phys_to_virt(address);
+       length <<= 10; /* convert to bytes */
+       /*
+        * Search through EBDA for BIOS memory console structure
+        * note: signature is not necessarily dword-aligned
+        */
+       for (cur = 0; cur < length; cur++) {
+               struct biosmemcon_ebda *hdr = phys_to_virt(address + cur);
+               /* memconsole v1 */
+               if (hdr->signature == BIOS_MEMCONSOLE_V1_MAGIC) {
+                       found_v1_header(hdr);
+                       return true;
+               }
+               /* memconsole v2 */
+               if (hdr->signature == BIOS_MEMCONSOLE_V2_MAGIC) {
+                       found_v2_header(hdr);
+                       return true;
+               }
+       }
+       pr_info("memconsole: BIOS console EBDA structure not found!\n");
+       return false;
+ }
+ static struct dmi_system_id memconsole_dmi_table[] __initdata = {
+       {
+               .ident = "Google Board",
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_VENDOR, "Google, Inc."),
+               },
+       },
+       {}
+ };
+ MODULE_DEVICE_TABLE(dmi, memconsole_dmi_table);
+ static bool __init memconsole_find(void)
+ {
+       if (!dmi_check_system(memconsole_dmi_table))
+               return false;
+       return memconsole_ebda_init();
+ }
+ static int __init memconsole_x86_init(void)
+ {
+       if (!memconsole_find())
+               return -ENODEV;
+       return memconsole_sysfs_init();
+ }
+ static void __exit memconsole_x86_exit(void)
+ {
+       memconsole_exit();
+ }
+ module_init(memconsole_x86_init);
+ module_exit(memconsole_x86_exit);
+ MODULE_AUTHOR("Google, Inc.");
+ MODULE_LICENSE("GPL");
Simple merge
index c3f1a9e33cef0852a947295fefcb765ffed80a88,cfacca566e3fba2035de4f93defb0da005c05466..1f450c39a9b0830f68611c0a11ee90c9f77ab2a3
@@@ -371,11 -357,10 +365,11 @@@ int hv_ringbuffer_read(struct vmbus_cha
                 * No error is set when there is even no header, drivers are
                 * supposed to analyze buffer_actual_len.
                 */
-               return ret;
+               return 0;
        }
  
 -      init_cached_read_index(channel);
 +      init_cached_read_index(inring_info);
 +
        next_read_location = hv_get_next_read_location(inring_info);
        next_read_location = hv_copyfrom_ringbuffer(inring_info, &desc,
                                                    sizeof(desc),
  
        hv_signal_on_read(channel);
  
-       return ret;
+       return 0;
  }
 +
 +/*
 + * Determine number of bytes available in ring buffer after
 + * the current iterator (priv_read_index) location.
 + *
 + * This is similar to hv_get_bytes_to_read but with private
 + * read index instead.
 + */
 +static u32 hv_pkt_iter_avail(const struct hv_ring_buffer_info *rbi)
 +{
 +      u32 priv_read_loc = rbi->priv_read_index;
 +      u32 write_loc = READ_ONCE(rbi->ring_buffer->write_index);
 +
 +      if (write_loc >= priv_read_loc)
 +              return write_loc - priv_read_loc;
 +      else
 +              return (rbi->ring_datasize - priv_read_loc) + write_loc;
 +}
 +
 +/*
 + * Get first vmbus packet from ring buffer after read_index
 + *
 + * If ring buffer is empty, returns NULL and no other action needed.
 + */
 +struct vmpacket_descriptor *hv_pkt_iter_first(struct vmbus_channel *channel)
 +{
 +      struct hv_ring_buffer_info *rbi = &channel->inbound;
 +
 +      /* set state for later hv_signal_on_read() */
 +      init_cached_read_index(rbi);
 +
 +      if (hv_pkt_iter_avail(rbi) < sizeof(struct vmpacket_descriptor))
 +              return NULL;
 +
 +      return hv_get_ring_buffer(rbi) + rbi->priv_read_index;
 +}
 +EXPORT_SYMBOL_GPL(hv_pkt_iter_first);
 +
 +/*
 + * Get next vmbus packet from ring buffer.
 + *
 + * Advances the current location (priv_read_index) and checks for more
 + * data. If the end of the ring buffer is reached, then return NULL.
 + */
 +struct vmpacket_descriptor *
 +__hv_pkt_iter_next(struct vmbus_channel *channel,
 +                 const struct vmpacket_descriptor *desc)
 +{
 +      struct hv_ring_buffer_info *rbi = &channel->inbound;
 +      u32 packetlen = desc->len8 << 3;
 +      u32 dsize = rbi->ring_datasize;
 +
 +      /* bump offset to next potential packet */
 +      rbi->priv_read_index += packetlen + VMBUS_PKT_TRAILER;
 +      if (rbi->priv_read_index >= dsize)
 +              rbi->priv_read_index -= dsize;
 +
 +      /* more data? */
 +      if (hv_pkt_iter_avail(rbi) < sizeof(struct vmpacket_descriptor))
 +              return NULL;
 +      else
 +              return hv_get_ring_buffer(rbi) + rbi->priv_read_index;
 +}
 +EXPORT_SYMBOL_GPL(__hv_pkt_iter_next);
 +
 +/*
 + * Update host ring buffer after iterating over packets.
 + */
 +void hv_pkt_iter_close(struct vmbus_channel *channel)
 +{
 +      struct hv_ring_buffer_info *rbi = &channel->inbound;
 +
 +      /*
 +       * Make sure all reads are done before we update the read index since
 +       * the writer may start writing to the read area once the read index
 +       * is updated.
 +       */
 +      virt_rmb();
 +      rbi->ring_buffer->read_index = rbi->priv_read_index;
 +
 +      hv_signal_on_read(channel);
 +}
 +EXPORT_SYMBOL_GPL(hv_pkt_iter_close);
Simple merge
Simple merge
Simple merge
Simple merge
index ed948025112cf719955a75a7d9be5ebc6b7e3ab1,4101c3178411f2c188401a62487740e93530ea96..0e56f1eb05dc5caa711360dab68fcb7584d71b71
@@@ -446,8 -442,20 +442,21 @@@ static int osd_probe(struct device *dev
        if (NULL == oud)
                goto err_retract_minor;
  
+       /* class device member */
+       device_initialize(&oud->class_dev);
        dev_set_drvdata(dev, oud);
        oud->minor = minor;
 -      scsi_device_get(scsi_device);
+       oud->class_dev.devt = MKDEV(SCSI_OSD_MAJOR, oud->minor);
+       oud->class_dev.class = &osd_uld_class;
+       oud->class_dev.parent = dev;
+       oud->class_dev.release = __remove;
+       /* hold one more reference to the scsi_device that will get released
+        * in __release, in case a logout is happening while fs is mounted
+        */
++      if (scsi_device_get(scsi_device))
++              goto err_retract_minor;
+       osd_dev_init(&oud->od, scsi_device);
  
        /* allocate a disk and set it up */
        /* FIXME: do we need this since sg has already done that */
@@@ -526,14 -507,16 +508,15 @@@ static int osd_remove(struct device *de
        struct scsi_device *scsi_device = to_scsi_device(dev);
        struct osd_uld_device *oud = dev_get_drvdata(dev);
  
 -      if (!oud || (oud->od.scsi_device != scsi_device)) {
 -              OSD_ERR("Half cooked osd-device %p,%p || %p!=%p",
 -                      dev, oud, oud ? oud->od.scsi_device : NULL,
 -                      scsi_device);
 +      if (oud->od.scsi_device != scsi_device) {
 +              OSD_ERR("Half cooked osd-device %p, || %p!=%p",
 +                      dev, oud->od.scsi_device, scsi_device);
        }
  
-       device_unregister(&oud->class_dev);
+       cdev_device_del(&oud->cdev, &oud->class_dev);
+       ida_remove(&osd_minor_ida, oud->minor);
        put_device(&oud->class_dev);
        return 0;
  }
  
index 0c170a3f0d8b0653b97d598c2a0c61d6b9abe1d2,f681f7bc9b43b38393b334b813bedd8cb78afeea..e09fc8290c2f02d92689f4499bcf2a22ae8ce8be
@@@ -1504,10 -1521,16 +1521,8 @@@ static inline  void hv_signal_on_read(s
        cached_write_sz = hv_get_cached_bytes_to_write(rbi);
        if (cached_write_sz < pending_sz)
                vmbus_setevent(channel);
-       return;
  }
  
 -static inline void
 -init_cached_read_index(struct vmbus_channel *channel)
 -{
 -      struct hv_ring_buffer_info *rbi = &channel->inbound;
 -
 -      rbi->cached_read_index = rbi->ring_buffer->read_index;
 -}
 -
  /*
   * Mask off host interrupt callback notifications
   */