]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/commitdiff
Merge Linus' tree to be be to apply submitted patches to newer code than
authorJiri Kosina <jkosina@suse.cz>
Thu, 20 Nov 2014 13:42:02 +0000 (14:42 +0100)
committerJiri Kosina <jkosina@suse.cz>
Thu, 20 Nov 2014 13:42:02 +0000 (14:42 +0100)
current trivial.git base

12 files changed:
1  2 
arch/powerpc/platforms/44x/Kconfig
drivers/clk/Kconfig
drivers/net/ethernet/atheros/atl1c/atl1c_main.c
drivers/pci/pci-driver.c
drivers/pinctrl/spear/pinctrl-plgpio.c
drivers/scsi/mpt2sas/mpt2sas_ctl.h
drivers/usb/gadget/legacy/zero.c
drivers/usb/serial/usb-serial-simple.c
include/scsi/scsi_host.h
kernel/trace/trace.c
mm/zbud.c
mm/zswap.c

index 54835e61997b81d6f8a4aec3a1efaa7026294452,82f2da28cd2775c4051a60d3f4014e25148f892c..d2ac1c1164546c20fe252f3ebe045aa40b84308d
@@@ -215,11 -215,12 +215,11 @@@ config AKEBON
        select NET_VENDOR_IBM
        select IBM_EMAC_EMAC4
        select IBM_EMAC_RGMII_WOL
-       select USB
-       select USB_OHCI_HCD_PLATFORM
-       select USB_EHCI_HCD_PLATFORM
+       select USB if USB_SUPPORT
+       select USB_OHCI_HCD_PLATFORM if USB_OHCI_HCD
+       select USB_EHCI_HCD_PLATFORM if USB_EHCI_HCD
        select MMC_SDHCI
        select MMC_SDHCI_PLTFM
 -      select MMC_SDHCI_OF_476GTR
        select ATA
        select SATA_AHCI_PLATFORM
        help
diff --combined drivers/clk/Kconfig
index 01abbbe49babf230b3629b2a402040bc0811f0e2,455fd17d938eaa6525f4af01e0d0d2f786bd08d8..3f44f292d066f03c2bd3029f4631d3a5183a70de
@@@ -28,16 -28,36 +28,36 @@@ config COMMON_CLK_WM831
        depends on MFD_WM831X
        ---help---
            Supports the clocking subsystem of the WM831x/2x series of
 -        PMICs from Wolfson Microlectronics.
 +        PMICs from Wolfson Microelectronics.
  
  source "drivers/clk/versatile/Kconfig"
  
+ config COMMON_CLK_MAX_GEN
+         bool
  config COMMON_CLK_MAX77686
        tristate "Clock driver for Maxim 77686 MFD"
        depends on MFD_MAX77686
+       select COMMON_CLK_MAX_GEN
        ---help---
          This driver supports Maxim 77686 crystal oscillator clock. 
  
+ config COMMON_CLK_MAX77802
+       tristate "Clock driver for Maxim 77802 PMIC"
+       depends on MFD_MAX77686
+       select COMMON_CLK_MAX_GEN
+       ---help---
+         This driver supports Maxim 77802 crystal oscillator clock.
+ config COMMON_CLK_RK808
+       tristate "Clock driver for RK808"
+       depends on MFD_RK808
+       ---help---
+         This driver supports RK808 crystal oscillator clock. These
+         multi-function devices have two fixed-rate oscillators,
+         clocked at 32KHz each. Clkout1 is always on, Clkout2 can off
+         by control register.
  config COMMON_CLK_SI5351
        tristate "Clock driver for SiLabs 5351A/B/C"
        depends on I2C
@@@ -109,6 -129,11 +129,11 @@@ config COMMON_CLK_PALMA
          This driver supports TI Palmas devices 32KHz output KG and KG_AUDIO
          using common clock framework.
  
+ config COMMON_CLK_PXA
+       def_bool COMMON_CLK && ARCH_PXA
+       ---help---
+         Sypport for the Marvell PXA SoC.
  source "drivers/clk/qcom/Kconfig"
  
  endmenu
index 9915a273cb003df154f923f2e3bd27d1669738d8,72fb86b9aa2480a50146a94095964f2bf7d8aaad..c9946c6c119e31f24b50a4337bdb770826ae8cae
@@@ -34,7 -34,7 +34,7 @@@ char atl1c_driver_version[] = ATL1C_DRV
   * { Vendor ID, Device ID, SubVendor ID, SubDevice ID,
   *   Class, Class Mask, private data (not used) }
   */
- static DEFINE_PCI_DEVICE_TABLE(atl1c_pci_tbl) = {
+ static const struct pci_device_id atl1c_pci_tbl[] = {
        {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATTANSIC_L1C)},
        {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATTANSIC_L2C)},
        {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATHEROS_L2C_B)},
@@@ -48,7 -48,7 +48,7 @@@ MODULE_DEVICE_TABLE(pci, atl1c_pci_tbl)
  
  MODULE_AUTHOR("Jie Yang");
  MODULE_AUTHOR("Qualcomm Atheros Inc., <nic-devel@qualcomm.com>");
 -MODULE_DESCRIPTION("Qualcom Atheros 100/1000M Ethernet Network Driver");
 +MODULE_DESCRIPTION("Qualcomm Atheros 100/1000M Ethernet Network Driver");
  MODULE_LICENSE("GPL");
  MODULE_VERSION(ATL1C_DRV_VERSION);
  
diff --combined drivers/pci/pci-driver.c
index 0f369d7326de9322deda8ba1dc87ae5ee713e58d,2b3c89425bb5d03296ceb7d5fa71213fdf5f8025..3c6ba623c32587b5e292e51575d64db632a783df
@@@ -55,7 -55,6 +55,6 @@@ int pci_add_dynid(struct pci_driver *dr
                  unsigned long driver_data)
  {
        struct pci_dynid *dynid;
-       int retval;
  
        dynid = kzalloc(sizeof(*dynid), GFP_KERNEL);
        if (!dynid)
@@@ -73,9 -72,7 +72,7 @@@
        list_add_tail(&dynid->node, &drv->dynids.list);
        spin_unlock(&drv->dynids.lock);
  
-       retval = driver_attach(&drv->driver);
-       return retval;
+       return driver_attach(&drv->driver);
  }
  EXPORT_SYMBOL_GPL(pci_add_dynid);
  
@@@ -1234,11 -1231,11 +1231,11 @@@ static const struct dev_pm_ops pci_dev_
  
  #define PCI_PM_OPS_PTR        (&pci_dev_pm_ops)
  
 -#else /* !COMFIG_PM_OPS */
 +#else /* !CONFIG_PM */
  
  #define PCI_PM_OPS_PTR        NULL
  
 -#endif /* !COMFIG_PM_OPS */
 +#endif /* !CONFIG_PM */
  
  /**
   * __pci_register_driver - register a new pci driver
index ecfc6aacf270b7d39315967fe0a4aea3fd90ced3,bddb79105d67fa31118033f985412c70fca15cea..ce5f22c4151d3a9053289f8bf4569dec24459f86
  
  #include <linux/clk.h>
  #include <linux/err.h>
- #include <linux/gpio.h>
+ #include <linux/gpio/driver.h>
  #include <linux/io.h>
- #include <linux/irq.h>
- #include <linux/irqdomain.h>
- #include <linux/irqchip/chained_irq.h>
  #include <linux/module.h>
+ #include <linux/of.h>
+ #include <linux/of_platform.h>
  #include <linux/pinctrl/consumer.h>
  #include <linux/platform_device.h>
  #include <linux/pm.h>
@@@ -54,7 -53,6 +53,6 @@@ struct plgpio_regs 
   *
   * lock: lock for guarding gpio registers
   * base: base address of plgpio block
-  * irq_base: irq number of plgpio0
   * chip: gpio framework specific chip information structure
   * p2o: function ptr for pin to offset conversion. This is required only for
   *    machines where mapping b/w pin and offset is not 1-to-1.
@@@ -68,8 -66,6 +66,6 @@@ struct plgpio 
        spinlock_t              lock;
        void __iomem            *base;
        struct clk              *clk;
-       unsigned                irq_base;
-       struct irq_domain       *irq_domain;
        struct gpio_chip        chip;
        int                     (*p2o)(int pin);        /* pin_to_offset */
        int                     (*o2p)(int offset);     /* offset_to_pin */
@@@ -280,21 -276,12 +276,12 @@@ disable_clk
        pinctrl_free_gpio(gpio);
  }
  
- static int plgpio_to_irq(struct gpio_chip *chip, unsigned offset)
- {
-       struct plgpio *plgpio = container_of(chip, struct plgpio, chip);
-       if (IS_ERR_VALUE(plgpio->irq_base))
-               return -EINVAL;
-       return irq_find_mapping(plgpio->irq_domain, offset);
- }
  /* PLGPIO IRQ */
  static void plgpio_irq_disable(struct irq_data *d)
  {
-       struct plgpio *plgpio = irq_data_get_irq_chip_data(d);
-       int offset = d->irq - plgpio->irq_base;
+       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+       struct plgpio *plgpio = container_of(gc, struct plgpio, chip);
+       int offset = d->hwirq;
        unsigned long flags;
  
        /* get correct offset for "offset" pin */
  
  static void plgpio_irq_enable(struct irq_data *d)
  {
-       struct plgpio *plgpio = irq_data_get_irq_chip_data(d);
-       int offset = d->irq - plgpio->irq_base;
+       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+       struct plgpio *plgpio = container_of(gc, struct plgpio, chip);
+       int offset = d->hwirq;
        unsigned long flags;
  
        /* get correct offset for "offset" pin */
  
  static int plgpio_irq_set_type(struct irq_data *d, unsigned trigger)
  {
-       struct plgpio *plgpio = irq_data_get_irq_chip_data(d);
-       int offset = d->irq - plgpio->irq_base;
+       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+       struct plgpio *plgpio = container_of(gc, struct plgpio, chip);
+       int offset = d->hwirq;
        void __iomem *reg_off;
        unsigned int supported_type = 0, val;
  
@@@ -369,7 -358,8 +358,8 @@@ static struct irq_chip plgpio_irqchip 
  
  static void plgpio_irq_handler(unsigned irq, struct irq_desc *desc)
  {
-       struct plgpio *plgpio = irq_get_handler_data(irq);
+       struct gpio_chip *gc = irq_desc_get_handler_data(desc);
+       struct plgpio *plgpio = container_of(gc, struct plgpio, chip);
        struct irq_chip *irqchip = irq_desc_get_chip(desc);
        int regs_count, count, pin, offset, i = 0;
        unsigned long pending;
  
                        /* get correct irq line number */
                        pin = i * MAX_GPIO_PER_REG + pin;
-                       generic_handle_irq(plgpio_to_irq(&plgpio->chip, pin));
+                       generic_handle_irq(
+                               irq_find_mapping(gc->irqdomain, pin));
                }
        }
        chained_irq_exit(irqchip, desc);
@@@ -523,10 -514,9 +514,9 @@@ end
  }
  static int plgpio_probe(struct platform_device *pdev)
  {
-       struct device_node *np = pdev->dev.of_node;
        struct plgpio *plgpio;
        struct resource *res;
-       int ret, irq, i;
+       int ret, irq;
  
        plgpio = devm_kzalloc(&pdev->dev, sizeof(*plgpio), GFP_KERNEL);
        if (!plgpio) {
        platform_set_drvdata(pdev, plgpio);
        spin_lock_init(&plgpio->lock);
  
-       plgpio->irq_base = -1;
        plgpio->chip.base = -1;
        plgpio->chip.request = plgpio_request;
        plgpio->chip.free = plgpio_free;
        plgpio->chip.direction_output = plgpio_direction_output;
        plgpio->chip.get = plgpio_get_value;
        plgpio->chip.set = plgpio_set_value;
-       plgpio->chip.to_irq = plgpio_to_irq;
        plgpio->chip.label = dev_name(&pdev->dev);
        plgpio->chip.dev = &pdev->dev;
        plgpio->chip.owner = THIS_MODULE;
+       plgpio->chip.of_node = pdev->dev.of_node;
  
        if (!IS_ERR(plgpio->clk)) {
                ret = clk_prepare(plgpio->clk);
  
        irq = platform_get_irq(pdev, 0);
        if (irq < 0) {
-               dev_info(&pdev->dev, "irqs not supported\n");
-               return 0;
-       }
-       plgpio->irq_base = irq_alloc_descs(-1, 0, plgpio->chip.ngpio, 0);
-       if (IS_ERR_VALUE(plgpio->irq_base)) {
-               /* we would not support irq for gpio */
-               dev_warn(&pdev->dev, "couldn't allocate irq base\n");
+               dev_info(&pdev->dev, "PLGPIO registered without IRQs\n");
                return 0;
        }
  
-       plgpio->irq_domain = irq_domain_add_legacy(np, plgpio->chip.ngpio,
-                       plgpio->irq_base, 0, &irq_domain_simple_ops, NULL);
-       if (WARN_ON(!plgpio->irq_domain)) {
-               dev_err(&pdev->dev, "irq domain init failed\n");
-               irq_free_descs(plgpio->irq_base, plgpio->chip.ngpio);
-               ret = -ENXIO;
+       ret = gpiochip_irqchip_add(&plgpio->chip,
+                                  &plgpio_irqchip,
+                                  0,
+                                  handle_simple_irq,
+                                  IRQ_TYPE_NONE);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to add irqchip to gpiochip\n");
                goto remove_gpiochip;
        }
  
-       irq_set_chained_handler(irq, plgpio_irq_handler);
-       for (i = 0; i < plgpio->chip.ngpio; i++) {
-               irq_set_chip_and_handler(i + plgpio->irq_base, &plgpio_irqchip,
-                               handle_simple_irq);
-               set_irq_flags(i + plgpio->irq_base, IRQF_VALID);
-               irq_set_chip_data(i + plgpio->irq_base, plgpio);
-       }
+       gpiochip_set_chained_irqchip(&plgpio->chip,
+                                    &plgpio_irqchip,
+                                    irq,
+                                    plgpio_irq_handler);
  
-       irq_set_handler_data(irq, plgpio);
        dev_info(&pdev->dev, "PLGPIO registered with IRQs\n");
  
        return 0;
  
  remove_gpiochip:
        dev_info(&pdev->dev, "Remove gpiochip\n");
-       if (gpiochip_remove(&plgpio->chip))
-               dev_err(&pdev->dev, "unable to remove gpiochip\n");
+       gpiochip_remove(&plgpio->chip);
  unprepare_clk:
        if (!IS_ERR(plgpio->clk))
                clk_unprepare(plgpio->clk);
@@@ -746,5 -724,5 +724,5 @@@ static int __init plgpio_init(void
  subsys_initcall(plgpio_init);
  
  MODULE_AUTHOR("Viresh Kumar <viresh.kumar@linaro.org>");
 -MODULE_DESCRIPTION("ST Microlectronics SPEAr PLGPIO driver");
 +MODULE_DESCRIPTION("STMicroelectronics SPEAr PLGPIO driver");
  MODULE_LICENSE("GPL");
index 60d76f435a689e54e8076d3db1153a3152126d52,fa0567c96050f5854cee97cac3dff5f2896f5adb..7f842c88abd274d037d4dd63a2d8e19181f6daac
@@@ -3,7 -3,7 +3,7 @@@
   * controllers
   *
   * This code is based on drivers/scsi/mpt2sas/mpt2_ctl.h
-  * Copyright (C) 2007-2013  LSI Corporation
+  * Copyright (C) 2007-2014  LSI Corporation
   *  (mailto:DL-MPTFusionLinux@lsi.com)
   *
   * This program is free software; you can redistribute it and/or
@@@ -224,7 -224,7 +224,7 @@@ struct mpt2_ioctl_eventreport 
  };
  
  /**
 - * struct mpt2_ioctl_command - generic mpt firmware passthru ioclt
 + * struct mpt2_ioctl_command - generic mpt firmware passthru ioctl
   * @hdr - generic header
   * @timeout - command timeout in seconds. (if zero then use driver default
   *  value).
index 5ee95152493c2b6b0be74257cc437bdb560f250b,ebf09f439f3aaf13a78d149d3231dcbc272a02f8..ff97ac93ac03d0add447f3e3ed49301403386b53
@@@ -28,7 -28,7 +28,7 @@@
   *
   * Why is *this* driver using two configurations, rather than setting up
   * two interfaces with different functions?  To help verify that multiple
 - * configuration infrastucture is working correctly; also, so that it can
 + * configuration infrastructure is working correctly; also, so that it can
   * work with low capability USB controllers without four bulk endpoints.
   */
  
@@@ -68,6 -68,8 +68,8 @@@ static struct usb_zero_options gzero_op
        .isoc_maxpacket = GZERO_ISOC_MAXPACKET,
        .bulk_buflen = GZERO_BULK_BUFLEN,
        .qlen = GZERO_QLEN,
+       .int_interval = GZERO_INT_INTERVAL,
+       .int_maxpacket = GZERO_INT_MAXPACKET,
  };
  
  /*-------------------------------------------------------------------------*/
@@@ -266,6 -268,21 +268,21 @@@ module_param_named(isoc_maxburst, gzero
                S_IRUGO|S_IWUSR);
  MODULE_PARM_DESC(isoc_maxburst, "0 - 15 (ss only)");
  
+ module_param_named(int_interval, gzero_options.int_interval, uint,
+               S_IRUGO|S_IWUSR);
+ MODULE_PARM_DESC(int_interval, "1 - 16");
+ module_param_named(int_maxpacket, gzero_options.int_maxpacket, uint,
+               S_IRUGO|S_IWUSR);
+ MODULE_PARM_DESC(int_maxpacket, "0 - 1023 (fs), 0 - 1024 (hs/ss)");
+ module_param_named(int_mult, gzero_options.int_mult, uint, S_IRUGO|S_IWUSR);
+ MODULE_PARM_DESC(int_mult, "0 - 2 (hs/ss only)");
+ module_param_named(int_maxburst, gzero_options.int_maxburst, uint,
+               S_IRUGO|S_IWUSR);
+ MODULE_PARM_DESC(int_maxburst, "0 - 15 (ss only)");
  static struct usb_function *func_lb;
  static struct usb_function_instance *func_inst_lb;
  
@@@ -301,6 -318,10 +318,10 @@@ static int __init zero_bind(struct usb_
        ss_opts->isoc_maxpacket = gzero_options.isoc_maxpacket;
        ss_opts->isoc_mult = gzero_options.isoc_mult;
        ss_opts->isoc_maxburst = gzero_options.isoc_maxburst;
+       ss_opts->int_interval = gzero_options.int_interval;
+       ss_opts->int_maxpacket = gzero_options.int_maxpacket;
+       ss_opts->int_mult = gzero_options.int_mult;
+       ss_opts->int_maxburst = gzero_options.int_maxburst;
        ss_opts->bulk_buflen = gzero_options.bulk_buflen;
  
        func_ss = usb_get_function(func_inst_ss);
index 675f9fae9cf2acfd698571ada6a18cfc47cfec08,7064eb8d6142aa5169ac81bf83fb3795c09b5542..8bfc47c2982872691eec85e1c44f182b0a18e13d
@@@ -20,7 -20,7 +20,7 @@@
  #include <linux/usb.h>
  #include <linux/usb/serial.h>
  
- #define DEVICE(vendor, IDS)                                   \
+ #define DEVICE_N(vendor, IDS, nport)                          \
  static const struct usb_device_id vendor##_id_table[] = {     \
        IDS(),                                                  \
        { },                                                    \
@@@ -31,9 -31,15 +31,15 @@@ static struct usb_serial_driver vendor#
                .name =         #vendor,                        \
        },                                                      \
        .id_table =             vendor##_id_table,              \
-       .num_ports =            1,                              \
+       .num_ports =            nport,                          \
  };
  
+ #define DEVICE(vendor, IDS)   DEVICE_N(vendor, IDS, 1)
+ /* Medtronic CareLink USB driver */
+ #define CARELINK_IDS()                        \
+       { USB_DEVICE(0x0a21, 0x8001) }  /* MMT-7305WW */
+ DEVICE(carelink, CARELINK_IDS);
  
  /* ZIO Motherboard USB driver */
  #define ZIO_IDS()                     \
@@@ -58,12 -64,17 +64,17 @@@ DEVICE(vivopay, VIVOPAY_IDS)
  /* Motorola USB Phone driver */
  #define MOTO_IDS()                    \
        { USB_DEVICE(0x05c6, 0x3197) }, /* unknown Motorola phone */    \
 -      { USB_DEVICE(0x0c44, 0x0022) }, /* unknown Mororola phone */    \
 +      { USB_DEVICE(0x0c44, 0x0022) }, /* unknown Motorola phone */    \
        { USB_DEVICE(0x22b8, 0x2a64) }, /* Motorola KRZR K1m */         \
        { USB_DEVICE(0x22b8, 0x2c84) }, /* Motorola VE240 phone */      \
        { USB_DEVICE(0x22b8, 0x2c64) }  /* Motorola V950 phone */
  DEVICE(moto_modem, MOTO_IDS);
  
+ /* Novatel Wireless GPS driver */
+ #define NOVATEL_IDS()                 \
+       { USB_DEVICE(0x09d7, 0x0100) }  /* NovAtel FlexPack GPS */
+ DEVICE_N(novatel_gps, NOVATEL_IDS, 3);
  /* HP4x (48/49) Generic Serial driver */
  #define HP4X_IDS()                    \
        { USB_DEVICE(0x03f0, 0x0121) }
@@@ -82,11 -93,13 +93,13 @@@ DEVICE(siemens_mpi, SIEMENS_IDS)
  
  /* All of the above structures mushed into two lists */
  static struct usb_serial_driver * const serial_drivers[] = {
+       &carelink_device,
        &zio_device,
        &funsoft_device,
        &flashloader_device,
        &vivopay_device,
        &moto_modem_device,
+       &novatel_gps_device,
        &hp4x_device,
        &suunto_device,
        &siemens_mpi_device,
  };
  
  static const struct usb_device_id id_table[] = {
+       CARELINK_IDS(),
        ZIO_IDS(),
        FUNSOFT_IDS(),
        FLASHLOADER_IDS(),
        VIVOPAY_IDS(),
        MOTO_IDS(),
+       NOVATEL_IDS(),
        HP4X_IDS(),
        SUUNTO_IDS(),
        SIEMENS_IDS(),
diff --combined include/scsi/scsi_host.h
index b286b5787c853d0a81c05ed19426d8052b7fc621,5e362489ee88a024d8216c1740fa0b424e723bb2..00859c288bee3c790e8c155b9379491e184a0046
@@@ -555,7 -555,7 +555,7 @@@ struct Scsi_Host 
         * __devices is protected by the host_lock, but you should
         * usually use scsi_device_lookup / shost_for_each_device
         * to access it and don't care about locking yourself.
 -       * In the rare case of beeing in irq context you can use
 +       * In the rare case of being in irq context you can use
         * their __ prefixed variants with the lock held. NEVER
         * access this list directly from a driver.
         */
        /*
         * These three parameters can be used to allow for wide scsi,
         * and for host adapters that support multiple busses
-        * The first two should be set to 1 more than the actual max id
+        * The last two should be set to 1 more than the actual max id
         * or lun (e.g. 8 for SCSI parallel systems).
         */
        unsigned int max_channel;
        unsigned no_write_same:1;
  
        unsigned use_blk_mq:1;
+       unsigned use_cmd_list:1;
  
        /*
         * Optional work queue to be utilized by the transport
         */
        struct workqueue_struct *tmf_work_q;
  
+       /* The transport requires the LUN bits NOT to be stored in CDB[1] */
+       unsigned no_scsi2_lun_in_cdb:1;
        /*
         * Value host_blocked counts down from
         */
diff --combined kernel/trace/trace.c
index f3ef80c8914c4a2a1c7f341048bb7c9820894ad2,92f4a6cee1727360ff9d739a126f168a6cacd980..0fa2d2070bd4b04bc94211ed74becb07de32478e
@@@ -1076,13 -1076,14 +1076,14 @@@ update_max_tr_single(struct trace_arra
  }
  #endif /* CONFIG_TRACER_MAX_TRACE */
  
- static int wait_on_pipe(struct trace_iterator *iter)
+ static int wait_on_pipe(struct trace_iterator *iter, bool full)
  {
        /* Iterators are static, they should be filled or empty */
        if (trace_buffer_iter(iter, iter->cpu_file))
                return 0;
  
-       return ring_buffer_wait(iter->trace_buffer->buffer, iter->cpu_file);
+       return ring_buffer_wait(iter->trace_buffer->buffer, iter->cpu_file,
+                               full);
  }
  
  #ifdef CONFIG_FTRACE_STARTUP_TEST
@@@ -2028,7 -2029,7 +2029,7 @@@ void trace_printk_init_buffers(void
        pr_warning("** trace_printk() being used. Allocating extra memory.  **\n");
        pr_warning("**                                                      **\n");
        pr_warning("** This means that this is a DEBUG kernel and it is     **\n");
 -      pr_warning("** unsafe for produciton use.                           **\n");
 +      pr_warning("** unsafe for production use.                           **\n");
        pr_warning("**                                                      **\n");
        pr_warning("** If you see this message and you are not debugging    **\n");
        pr_warning("** the kernel, report this immediately to your vendor!  **\n");
@@@ -4434,15 -4435,12 +4435,12 @@@ static int tracing_wait_pipe(struct fil
  
                mutex_unlock(&iter->mutex);
  
-               ret = wait_on_pipe(iter);
+               ret = wait_on_pipe(iter, false);
  
                mutex_lock(&iter->mutex);
  
                if (ret)
                        return ret;
-               if (signal_pending(current))
-                       return -EINTR;
        }
  
        return 1;
@@@ -5372,16 -5370,12 +5370,12 @@@ tracing_buffers_read(struct file *filp
                                goto out_unlock;
                        }
                        mutex_unlock(&trace_types_lock);
-                       ret = wait_on_pipe(iter);
+                       ret = wait_on_pipe(iter, false);
                        mutex_lock(&trace_types_lock);
                        if (ret) {
                                size = ret;
                                goto out_unlock;
                        }
-                       if (signal_pending(current)) {
-                               size = -EINTR;
-                               goto out_unlock;
-                       }
                        goto again;
                }
                size = 0;
@@@ -5500,7 -5494,7 +5494,7 @@@ tracing_buffers_splice_read(struct fil
        };
        struct buffer_ref *ref;
        int entries, size, i;
-       ssize_t ret;
+       ssize_t ret = 0;
  
        mutex_lock(&trace_types_lock);
  
                int r;
  
                ref = kzalloc(sizeof(*ref), GFP_KERNEL);
-               if (!ref)
+               if (!ref) {
+                       ret = -ENOMEM;
                        break;
+               }
  
                ref->ref = 1;
                ref->buffer = iter->trace_buffer->buffer;
                ref->page = ring_buffer_alloc_read_page(ref->buffer, iter->cpu_file);
                if (!ref->page) {
+                       ret = -ENOMEM;
                        kfree(ref);
                        break;
                }
  
        /* did we read anything? */
        if (!spd.nr_pages) {
+               if (ret)
+                       goto out;
                if ((file->f_flags & O_NONBLOCK) || (flags & SPLICE_F_NONBLOCK)) {
                        ret = -EAGAIN;
                        goto out;
                }
                mutex_unlock(&trace_types_lock);
-               ret = wait_on_pipe(iter);
+               ret = wait_on_pipe(iter, true);
                mutex_lock(&trace_types_lock);
                if (ret)
                        goto out;
-               if (signal_pending(current)) {
-                       ret = -EINTR;
-                       goto out;
-               }
                goto again;
        }
  
diff --combined mm/zbud.c
index bf424047060fee5847a71c7ab584a4acc5a3379f,ecf1dbef69833f56fbde1c0e2cb167e8e7b1eff7..ec71b37fb06cc9b9707314857bd8ba0addbb8394
+++ b/mm/zbud.c
@@@ -51,6 -51,7 +51,7 @@@
  #include <linux/slab.h>
  #include <linux/spinlock.h>
  #include <linux/zbud.h>
+ #include <linux/zpool.h>
  
  /*****************
   * Structures
   * NCHUNKS_ORDER determines the internal allocation granularity, effectively
   * adjusting internal fragmentation.  It also determines the number of
   * freelists maintained in each pool. NCHUNKS_ORDER of 6 means that the
-  * allocation granularity will be in chunks of size PAGE_SIZE/64, and there
-  * will be 64 freelists per pool.
+  * allocation granularity will be in chunks of size PAGE_SIZE/64. As one chunk
+  * in allocated page is occupied by zbud header, NCHUNKS will be calculated to
+  * 63 which shows the max number of free chunks in zbud page, also there will be
+  * 63 freelists per pool.
   */
  #define NCHUNKS_ORDER 6
  
  #define CHUNK_SHIFT   (PAGE_SHIFT - NCHUNKS_ORDER)
  #define CHUNK_SIZE    (1 << CHUNK_SHIFT)
- #define NCHUNKS               (PAGE_SIZE >> CHUNK_SHIFT)
  #define ZHDR_SIZE_ALIGNED CHUNK_SIZE
+ #define NCHUNKS               ((PAGE_SIZE - ZHDR_SIZE_ALIGNED) >> CHUNK_SHIFT)
  
  /**
   * struct zbud_pool - stores metadata for each zbud pool
@@@ -112,6 -115,91 +115,91 @@@ struct zbud_header 
        bool under_reclaim;
  };
  
+ /*****************
+  * zpool
+  ****************/
+ #ifdef CONFIG_ZPOOL
+ static int zbud_zpool_evict(struct zbud_pool *pool, unsigned long handle)
+ {
+       return zpool_evict(pool, handle);
+ }
+ static struct zbud_ops zbud_zpool_ops = {
+       .evict =        zbud_zpool_evict
+ };
+ static void *zbud_zpool_create(gfp_t gfp, struct zpool_ops *zpool_ops)
+ {
+       return zbud_create_pool(gfp, &zbud_zpool_ops);
+ }
+ static void zbud_zpool_destroy(void *pool)
+ {
+       zbud_destroy_pool(pool);
+ }
+ static int zbud_zpool_malloc(void *pool, size_t size, gfp_t gfp,
+                       unsigned long *handle)
+ {
+       return zbud_alloc(pool, size, gfp, handle);
+ }
+ static void zbud_zpool_free(void *pool, unsigned long handle)
+ {
+       zbud_free(pool, handle);
+ }
+ static int zbud_zpool_shrink(void *pool, unsigned int pages,
+                       unsigned int *reclaimed)
+ {
+       unsigned int total = 0;
+       int ret = -EINVAL;
+       while (total < pages) {
+               ret = zbud_reclaim_page(pool, 8);
+               if (ret < 0)
+                       break;
+               total++;
+       }
+       if (reclaimed)
+               *reclaimed = total;
+       return ret;
+ }
+ static void *zbud_zpool_map(void *pool, unsigned long handle,
+                       enum zpool_mapmode mm)
+ {
+       return zbud_map(pool, handle);
+ }
+ static void zbud_zpool_unmap(void *pool, unsigned long handle)
+ {
+       zbud_unmap(pool, handle);
+ }
+ static u64 zbud_zpool_total_size(void *pool)
+ {
+       return zbud_get_pool_size(pool) * PAGE_SIZE;
+ }
+ static struct zpool_driver zbud_zpool_driver = {
+       .type =         "zbud",
+       .owner =        THIS_MODULE,
+       .create =       zbud_zpool_create,
+       .destroy =      zbud_zpool_destroy,
+       .malloc =       zbud_zpool_malloc,
+       .free =         zbud_zpool_free,
+       .shrink =       zbud_zpool_shrink,
+       .map =          zbud_zpool_map,
+       .unmap =        zbud_zpool_unmap,
+       .total_size =   zbud_zpool_total_size,
+ };
+ MODULE_ALIAS("zpool-zbud");
+ #endif /* CONFIG_ZPOOL */
  /*****************
   * Helpers
  *****************/
@@@ -122,7 -210,7 +210,7 @@@ enum buddy 
  };
  
  /* Converts an allocation size in bytes to size in zbud chunks */
- static int size_to_chunks(int size)
+ static int size_to_chunks(size_t size)
  {
        return (size + CHUNK_SIZE - 1) >> CHUNK_SHIFT;
  }
@@@ -182,10 -270,9 +270,9 @@@ static int num_free_chunks(struct zbud_
  {
        /*
         * Rather than branch for different situations, just use the fact that
-        * free buddies have a length of zero to simplify everything. -1 at the
-        * end for the zbud header.
+        * free buddies have a length of zero to simplify everything.
         */
-       return NCHUNKS - zhdr->first_chunks - zhdr->last_chunks - 1;
+       return NCHUNKS - zhdr->first_chunks - zhdr->last_chunks;
  }
  
  /*****************
@@@ -247,7 -334,7 +334,7 @@@ void zbud_destroy_pool(struct zbud_poo
   * gfp arguments are invalid or -ENOMEM if the pool was unable to allocate
   * a new page.
   */
- int zbud_alloc(struct zbud_pool *pool, unsigned int size, gfp_t gfp,
+ int zbud_alloc(struct zbud_pool *pool, size_t size, gfp_t gfp,
                        unsigned long *handle)
  {
        int chunks, i, freechunks;
@@@ -511,11 -598,20 +598,20 @@@ static int __init init_zbud(void
        /* Make sure the zbud header will fit in one chunk */
        BUILD_BUG_ON(sizeof(struct zbud_header) > ZHDR_SIZE_ALIGNED);
        pr_info("loaded\n");
+ #ifdef CONFIG_ZPOOL
+       zpool_register_driver(&zbud_zpool_driver);
+ #endif
        return 0;
  }
  
  static void __exit exit_zbud(void)
  {
+ #ifdef CONFIG_ZPOOL
+       zpool_unregister_driver(&zbud_zpool_driver);
+ #endif
        pr_info("unloaded\n");
  }
  
@@@ -523,5 -619,5 +619,5 @@@ module_init(init_zbud)
  module_exit(exit_zbud);
  
  MODULE_LICENSE("GPL");
 -MODULE_AUTHOR("Seth Jennings <sjenning@linux.vnet.ibm.com>");
 +MODULE_AUTHOR("Seth Jennings <sjennings@variantweb.net>");
  MODULE_DESCRIPTION("Buddy Allocator for Compressed Pages");
diff --combined mm/zswap.c
index 642ec859d93d0c56fa70869e3111557a9a583fdf,ea064c1a09ba79003a5ed5e8990d1ce44f2e6122..c1543061a192df68c0620079635f77989b8ab89b
@@@ -34,7 -34,7 +34,7 @@@
  #include <linux/swap.h>
  #include <linux/crypto.h>
  #include <linux/mempool.h>
- #include <linux/zbud.h>
+ #include <linux/zpool.h>
  
  #include <linux/mm_types.h>
  #include <linux/page-flags.h>
@@@ -45,8 -45,8 +45,8 @@@
  /*********************************
  * statistics
  **********************************/
- /* Number of memory pages used by the compressed pool */
- static u64 zswap_pool_pages;
+ /* Total bytes used by the compressed storage */
+ static u64 zswap_pool_total_size;
  /* The number of compressed pages currently stored in zswap */
  static atomic_t zswap_stored_pages = ATOMIC_INIT(0);
  
@@@ -89,8 -89,13 +89,13 @@@ static unsigned int zswap_max_pool_perc
  module_param_named(max_pool_percent,
                        zswap_max_pool_percent, uint, 0644);
  
- /* zbud_pool is shared by all of zswap backend  */
- static struct zbud_pool *zswap_pool;
+ /* Compressed storage to use */
+ #define ZSWAP_ZPOOL_DEFAULT "zbud"
+ static char *zswap_zpool_type = ZSWAP_ZPOOL_DEFAULT;
+ module_param_named(zpool, zswap_zpool_type, charp, 0444);
+ /* zpool is shared by all of zswap backend  */
+ static struct zpool *zswap_pool;
  
  /*********************************
  * compression functions
@@@ -168,7 -173,7 +173,7 @@@ static void zswap_comp_exit(void
   *            be held while changing the refcount.  Since the lock must
   *            be held, there is no reason to also make refcount atomic.
   * offset - the swap offset for the entry.  Index into the red-black tree.
-  * handle - zbud allocation handle that stores the compressed page data
+  * handle - zpool allocation handle that stores the compressed page data
   * length - the length in bytes of the compressed page data.  Needed during
   *          decompression
   */
@@@ -207,7 -212,7 +212,7 @@@ static int zswap_entry_cache_create(voi
        return zswap_entry_cache == NULL;
  }
  
- static void zswap_entry_cache_destory(void)
+ static void __init zswap_entry_cache_destroy(void)
  {
        kmem_cache_destroy(zswap_entry_cache);
  }
@@@ -284,15 -289,15 +289,15 @@@ static void zswap_rb_erase(struct rb_ro
  }
  
  /*
-  * Carries out the common pattern of freeing and entry's zbud allocation,
+  * Carries out the common pattern of freeing and entry's zpool allocation,
   * freeing the entry itself, and decrementing the number of stored pages.
   */
  static void zswap_free_entry(struct zswap_entry *entry)
  {
-       zbud_free(zswap_pool, entry->handle);
+       zpool_free(zswap_pool, entry->handle);
        zswap_entry_cache_free(entry);
        atomic_dec(&zswap_stored_pages);
-       zswap_pool_pages = zbud_get_pool_size(zswap_pool);
+       zswap_pool_total_size = zpool_get_total_size(zswap_pool);
  }
  
  /* caller must hold the tree lock */
@@@ -409,7 -414,7 +414,7 @@@ cleanup
  static bool zswap_is_full(void)
  {
        return totalram_pages * zswap_max_pool_percent / 100 <
-               zswap_pool_pages;
+               DIV_ROUND_UP(zswap_pool_total_size, PAGE_SIZE);
  }
  
  /*********************************
@@@ -502,7 -507,7 +507,7 @@@ static int zswap_get_swap_cache_page(sw
                 * add_to_swap_cache() doesn't return -EEXIST, so we can safely
                 * clear SWAP_HAS_CACHE flag.
                 */
-               swapcache_free(entry, NULL);
+               swapcache_free(entry);
        } while (err != -ENOMEM);
  
        if (new_page)
   * the swap cache, the compressed version stored by zswap can be
   * freed.
   */
- static int zswap_writeback_entry(struct zbud_pool *pool, unsigned long handle)
+ static int zswap_writeback_entry(struct zpool *pool, unsigned long handle)
  {
        struct zswap_header *zhdr;
        swp_entry_t swpentry;
        };
  
        /* extract swpentry from data */
-       zhdr = zbud_map(pool, handle);
+       zhdr = zpool_map_handle(pool, handle, ZPOOL_MM_RO);
        swpentry = zhdr->swpentry; /* here */
-       zbud_unmap(pool, handle);
+       zpool_unmap_handle(pool, handle);
        tree = zswap_trees[swp_type(swpentry)];
        offset = swp_offset(swpentry);
  
        case ZSWAP_SWAPCACHE_NEW: /* page is locked */
                /* decompress */
                dlen = PAGE_SIZE;
-               src = (u8 *)zbud_map(zswap_pool, entry->handle) +
-                       sizeof(struct zswap_header);
+               src = (u8 *)zpool_map_handle(zswap_pool, entry->handle,
+                               ZPOOL_MM_RO) + sizeof(struct zswap_header);
                dst = kmap_atomic(page);
                ret = zswap_comp_op(ZSWAP_COMPOP_DECOMPRESS, src,
                                entry->length, dst, &dlen);
                kunmap_atomic(dst);
-               zbud_unmap(zswap_pool, entry->handle);
+               zpool_unmap_handle(zswap_pool, entry->handle);
                BUG_ON(ret);
                BUG_ON(dlen != PAGE_SIZE);
  
@@@ -652,7 -657,7 +657,7 @@@ static int zswap_frontswap_store(unsign
        /* reclaim space if needed */
        if (zswap_is_full()) {
                zswap_pool_limit_hit++;
-               if (zbud_reclaim_page(zswap_pool, 8)) {
+               if (zpool_shrink(zswap_pool, 1, NULL)) {
                        zswap_reject_reclaim_fail++;
                        ret = -ENOMEM;
                        goto reject;
  
        /* store */
        len = dlen + sizeof(struct zswap_header);
-       ret = zbud_alloc(zswap_pool, len, __GFP_NORETRY | __GFP_NOWARN,
+       ret = zpool_malloc(zswap_pool, len, __GFP_NORETRY | __GFP_NOWARN,
                &handle);
        if (ret == -ENOSPC) {
                zswap_reject_compress_poor++;
                zswap_reject_alloc_fail++;
                goto freepage;
        }
-       zhdr = zbud_map(zswap_pool, handle);
+       zhdr = zpool_map_handle(zswap_pool, handle, ZPOOL_MM_RW);
        zhdr->swpentry = swp_entry(type, offset);
        buf = (u8 *)(zhdr + 1);
        memcpy(buf, dst, dlen);
-       zbud_unmap(zswap_pool, handle);
+       zpool_unmap_handle(zswap_pool, handle);
        put_cpu_var(zswap_dstmem);
  
        /* populate entry */
  
        /* update stats */
        atomic_inc(&zswap_stored_pages);
-       zswap_pool_pages = zbud_get_pool_size(zswap_pool);
+       zswap_pool_total_size = zpool_get_total_size(zswap_pool);
  
        return 0;
  
@@@ -752,13 -757,13 +757,13 @@@ static int zswap_frontswap_load(unsigne
  
        /* decompress */
        dlen = PAGE_SIZE;
-       src = (u8 *)zbud_map(zswap_pool, entry->handle) +
-                       sizeof(struct zswap_header);
+       src = (u8 *)zpool_map_handle(zswap_pool, entry->handle,
+                       ZPOOL_MM_RO) + sizeof(struct zswap_header);
        dst = kmap_atomic(page);
        ret = zswap_comp_op(ZSWAP_COMPOP_DECOMPRESS, src, entry->length,
                dst, &dlen);
        kunmap_atomic(dst);
-       zbud_unmap(zswap_pool, entry->handle);
+       zpool_unmap_handle(zswap_pool, entry->handle);
        BUG_ON(ret);
  
        spin_lock(&tree->lock);
@@@ -811,7 -816,7 +816,7 @@@ static void zswap_frontswap_invalidate_
        zswap_trees[type] = NULL;
  }
  
- static struct zbud_ops zswap_zbud_ops = {
+ static struct zpool_ops zswap_zpool_ops = {
        .evict = zswap_writeback_entry
  };
  
@@@ -869,8 -874,8 +874,8 @@@ static int __init zswap_debugfs_init(vo
                        zswap_debugfs_root, &zswap_written_back_pages);
        debugfs_create_u64("duplicate_entry", S_IRUGO,
                        zswap_debugfs_root, &zswap_duplicate_entry);
-       debugfs_create_u64("pool_pages", S_IRUGO,
-                       zswap_debugfs_root, &zswap_pool_pages);
+       debugfs_create_u64("pool_total_size", S_IRUGO,
+                       zswap_debugfs_root, &zswap_pool_total_size);
        debugfs_create_atomic_t("stored_pages", S_IRUGO,
                        zswap_debugfs_root, &zswap_stored_pages);
  
@@@ -895,16 -900,26 +900,26 @@@ static void __exit zswap_debugfs_exit(v
  **********************************/
  static int __init init_zswap(void)
  {
+       gfp_t gfp = __GFP_NORETRY | __GFP_NOWARN;
        if (!zswap_enabled)
                return 0;
  
        pr_info("loading zswap\n");
  
-       zswap_pool = zbud_create_pool(GFP_KERNEL, &zswap_zbud_ops);
+       zswap_pool = zpool_create_pool(zswap_zpool_type, gfp, &zswap_zpool_ops);
+       if (!zswap_pool && strcmp(zswap_zpool_type, ZSWAP_ZPOOL_DEFAULT)) {
+               pr_info("%s zpool not available\n", zswap_zpool_type);
+               zswap_zpool_type = ZSWAP_ZPOOL_DEFAULT;
+               zswap_pool = zpool_create_pool(zswap_zpool_type, gfp,
+                                       &zswap_zpool_ops);
+       }
        if (!zswap_pool) {
-               pr_err("zbud pool creation failed\n");
+               pr_err("%s zpool not available\n", zswap_zpool_type);
+               pr_err("zpool creation failed\n");
                goto error;
        }
+       pr_info("using %s pool\n", zswap_zpool_type);
  
        if (zswap_entry_cache_create()) {
                pr_err("entry cache creation failed\n");
  pcpufail:
        zswap_comp_exit();
  compfail:
-       zswap_entry_cache_destory();
+       zswap_entry_cache_destroy();
  cachefail:
-       zbud_destroy_pool(zswap_pool);
+       zpool_destroy_pool(zswap_pool);
  error:
        return -ENOMEM;
  }
  late_initcall(init_zswap);
  
  MODULE_LICENSE("GPL");
 -MODULE_AUTHOR("Seth Jennings <sjenning@linux.vnet.ibm.com>");
 +MODULE_AUTHOR("Seth Jennings <sjennings@variantweb.net>");
  MODULE_DESCRIPTION("Compressed cache for swap pages");