]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
Merge tag 'hwparam-20170420' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowell...
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 11 May 2017 02:13:03 +0000 (19:13 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 11 May 2017 02:13:03 +0000 (19:13 -0700)
Pull hw lockdown support from David Howells:
 "Annotation of module parameters that configure hardware resources
  including ioports, iomem addresses, irq lines and dma channels.

  This allows a future patch to prohibit the use of such module
  parameters to prevent that hardware from being abused to gain access
  to the running kernel image as part of locking the kernel down under
  UEFI secure boot conditions.

  Annotations are made by changing:

        module_param(n, t, p)
        module_param_named(n, v, t, p)
        module_param_array(n, t, m, p)

  to:

        module_param_hw(n, t, hwtype, p)
        module_param_hw_named(n, v, t, hwtype, p)
        module_param_hw_array(n, t, hwtype, m, p)

  where the module parameter refers to a hardware setting

  hwtype specifies the type of the resource being configured. This can
  be one of:

        ioport          Module parameter configures an I/O port
        iomem           Module parameter configures an I/O mem address
        ioport_or_iomem Module parameter could be either (runtime set)
        irq             Module parameter configures an I/O port
        dma             Module parameter configures a DMA channel
        dma_addr        Module parameter configures a DMA buffer address
        other           Module parameter configures some other value

  Note that the hwtype is compile checked, but not currently stored (the
  lockdown code probably won't require it). It is, however, there for
  future use.

  A bonus is that the hwtype can also be used for grepping.

  The intention is for the kernel to ignore or reject attempts to set
  annotated module parameters if lockdown is enabled. This applies to
  options passed on the boot command line, passed to insmod/modprobe or
  direct twiddling in /sys/module/ parameter files.

  The module initialisation then needs to handle the parameter not being
  set, by (1) giving an error, (2) probing for a value or (3) using a
  reasonable default.

  What I can't do is just reject a module out of hand because it may
  take a hardware setting in the module parameters. Some important
  modules, some ipmi stuff for instance, both probe for hardware and
  allow hardware to be manually specified; if the driver is aborts with
  any error, you don't get any ipmi hardware.

  Further, trying to do this entirely in the module initialisation code
  doesn't protect against sysfs twiddling.

  [!] Note that in and of itself, this series of patches should have no
      effect on the the size of the kernel or code execution - that is
      left to a patch in the next series to effect. It does mark
      annotated kernel parameters with a KERNEL_PARAM_FL_HWPARAM flag in
      an already existing field"

* tag 'hwparam-20170420' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs: (38 commits)
  Annotate hardware config module parameters in sound/pci/
  Annotate hardware config module parameters in sound/oss/
  Annotate hardware config module parameters in sound/isa/
  Annotate hardware config module parameters in sound/drivers/
  Annotate hardware config module parameters in fs/pstore/
  Annotate hardware config module parameters in drivers/watchdog/
  Annotate hardware config module parameters in drivers/video/
  Annotate hardware config module parameters in drivers/tty/
  Annotate hardware config module parameters in drivers/staging/vme/
  Annotate hardware config module parameters in drivers/staging/speakup/
  Annotate hardware config module parameters in drivers/staging/media/
  Annotate hardware config module parameters in drivers/scsi/
  Annotate hardware config module parameters in drivers/pcmcia/
  Annotate hardware config module parameters in drivers/pci/hotplug/
  Annotate hardware config module parameters in drivers/parport/
  Annotate hardware config module parameters in drivers/net/wireless/
  Annotate hardware config module parameters in drivers/net/wan/
  Annotate hardware config module parameters in drivers/net/irda/
  Annotate hardware config module parameters in drivers/net/hamradio/
  Annotate hardware config module parameters in drivers/net/ethernet/
  ...

17 files changed:
1  2 
drivers/char/ipmi/ipmi_si_intf.c
drivers/gpio/gpio-104-dio-48e.c
drivers/gpio/gpio-104-idi-48.c
drivers/gpio/gpio-104-idio-16.c
drivers/gpio/gpio-ws16c48.c
drivers/iio/adc/stx104.c
drivers/iio/dac/cio-dac.c
drivers/media/rc/serial_ir.c
drivers/net/ethernet/cirrus/cs89x0.c
drivers/staging/speakup/speakup_acntpc.c
drivers/staging/speakup/speakup_dtlk.c
drivers/staging/speakup/speakup_keypc.c
drivers/tty/serial/8250/8250_core.c
fs/pstore/ram.c
sound/pci/cmipci.c
sound/pci/ens1370.c
sound/pci/via82xx.c

index b2b618f066e02b85c185ba3a17cd1a4ca9e8eaf8,e2f34eb599984f133fe1b5788c9332bedc662b3d..59ee93ea84ebe8807ee3bcf1084f95cd53d5e4f8
@@@ -1375,39 -1375,39 +1375,39 @@@ MODULE_PARM_DESC(type, "Defines the typ
                 " interface separated by commas.  The types are 'kcs',"
                 " 'smic', and 'bt'.  For example si_type=kcs,bt will set"
                 " the first interface to kcs and the second to bt");
- module_param_array(addrs, ulong, &num_addrs, 0);
+ module_param_hw_array(addrs, ulong, iomem, &num_addrs, 0);
  MODULE_PARM_DESC(addrs, "Sets the memory address of each interface, the"
                 " addresses separated by commas.  Only use if an interface"
                 " is in memory.  Otherwise, set it to zero or leave"
                 " it blank.");
- module_param_array(ports, uint, &num_ports, 0);
+ module_param_hw_array(ports, uint, ioport, &num_ports, 0);
  MODULE_PARM_DESC(ports, "Sets the port address of each interface, the"
                 " addresses separated by commas.  Only use if an interface"
                 " is a port.  Otherwise, set it to zero or leave"
                 " it blank.");
- module_param_array(irqs, int, &num_irqs, 0);
+ module_param_hw_array(irqs, int, irq, &num_irqs, 0);
  MODULE_PARM_DESC(irqs, "Sets the interrupt of each interface, the"
                 " addresses separated by commas.  Only use if an interface"
                 " has an interrupt.  Otherwise, set it to zero or leave"
                 " it blank.");
- module_param_array(regspacings, int, &num_regspacings, 0);
+ module_param_hw_array(regspacings, int, other, &num_regspacings, 0);
  MODULE_PARM_DESC(regspacings, "The number of bytes between the start address"
                 " and each successive register used by the interface.  For"
                 " instance, if the start address is 0xca2 and the spacing"
                 " is 2, then the second address is at 0xca4.  Defaults"
                 " to 1.");
- module_param_array(regsizes, int, &num_regsizes, 0);
+ module_param_hw_array(regsizes, int, other, &num_regsizes, 0);
  MODULE_PARM_DESC(regsizes, "The size of the specific IPMI register in bytes."
                 " This should generally be 1, 2, 4, or 8 for an 8-bit,"
                 " 16-bit, 32-bit, or 64-bit register.  Use this if you"
                 " the 8-bit IPMI register has to be read from a larger"
                 " register.");
- module_param_array(regshifts, int, &num_regshifts, 0);
+ module_param_hw_array(regshifts, int, other, &num_regshifts, 0);
  MODULE_PARM_DESC(regshifts, "The amount to shift the data read from the."
                 " IPMI register, in bits.  For instance, if the data"
                 " is read from a 32-bit word and the IPMI data is in"
                 " bit 8-15, then the shift would be 8");
- module_param_array(slave_addrs, int, &num_slave_addrs, 0);
+ module_param_hw_array(slave_addrs, int, other, &num_slave_addrs, 0);
  MODULE_PARM_DESC(slave_addrs, "Set the default IPMB slave address for"
                 " the controller.  Normally this is 0x20, but can be"
                 " overridden by this parm.  This is an array indexed"
@@@ -1954,9 -1954,7 +1954,9 @@@ static int hotmod_handler(const char *v
                                kfree(info);
                                goto out;
                        }
 +                      mutex_lock(&smi_infos_lock);
                        rv = try_smi_init(info);
 +                      mutex_unlock(&smi_infos_lock);
                        if (rv) {
                                cleanup_one_si(info);
                                goto out;
@@@ -2044,10 -2042,8 +2044,10 @@@ static int hardcode_find_bmc(void
                info->slave_addr = slave_addrs[i];
  
                if (!add_smi(info)) {
 +                      mutex_lock(&smi_infos_lock);
                        if (try_smi_init(info))
                                cleanup_one_si(info);
 +                      mutex_unlock(&smi_infos_lock);
                        ret = 0;
                } else {
                        kfree(info);
@@@ -3496,11 -3492,6 +3496,11 @@@ out_err
        return rv;
  }
  
 +/*
 + * Try to start up an interface.  Must be called with smi_infos_lock
 + * held, primarily to keep smi_num consistent, we only one to do these
 + * one at a time.
 + */
  static int try_smi_init(struct smi_info *new_smi)
  {
        int rv = 0;
                goto out_err;
        }
  
 +      new_smi->intf_num = smi_num;
 +
        /* Do this early so it's available for logs. */
        if (!new_smi->dev) {
 -              init_name = kasprintf(GFP_KERNEL, "ipmi_si.%d", 0);
 +              init_name = kasprintf(GFP_KERNEL, "ipmi_si.%d",
 +                                    new_smi->intf_num);
  
                /*
                 * If we don't already have a device from something
  
        new_smi->interrupt_disabled = true;
        atomic_set(&new_smi->need_watch, 0);
 -      new_smi->intf_num = smi_num;
 -      smi_num++;
  
        rv = try_enable_event_buffer(new_smi);
        if (rv == 0)
                goto out_err_stop_timer;
        }
  
 +      /* Don't increment till we know we have succeeded. */
 +      smi_num++;
 +
        dev_info(new_smi->dev, "IPMI %s interface initialized\n",
                 si_to_str[new_smi->si_type]);
  
index 61b50c40b87bba9469fa650a4fd6858607312092,dfa1a298e4f686241c4f7c415ebcf77cf596e8c4..598e209efa2de9d923d86a37b43958e0c1b5dcd3
  
  static unsigned int base[MAX_NUM_DIO48E];
  static unsigned int num_dio48e;
- module_param_array(base, uint, &num_dio48e, 0);
+ module_param_hw_array(base, uint, ioport, &num_dio48e, 0);
  MODULE_PARM_DESC(base, "ACCES 104-DIO-48E base addresses");
  
  static unsigned int irq[MAX_NUM_DIO48E];
- module_param_array(irq, uint, NULL, 0);
+ module_param_hw_array(irq, uint, irq, NULL, 0);
  MODULE_PARM_DESC(irq, "ACCES 104-DIO-48E interrupt line numbers");
  
  /**
@@@ -55,7 -55,7 +55,7 @@@ struct dio48e_gpio 
        unsigned char io_state[6];
        unsigned char out_state[6];
        unsigned char control[2];
 -      spinlock_t lock;
 +      raw_spinlock_t lock;
        unsigned base;
        unsigned char irq_mask;
  };
@@@ -78,7 -78,7 +78,7 @@@ static int dio48e_gpio_direction_input(
        unsigned long flags;
        unsigned control;
  
 -      spin_lock_irqsave(&dio48egpio->lock, flags);
 +      raw_spin_lock_irqsave(&dio48egpio->lock, flags);
  
        /* Check if configuring Port C */
        if (io_port == 2 || io_port == 5) {
        control &= ~BIT(7);
        outb(control, control_addr);
  
 -      spin_unlock_irqrestore(&dio48egpio->lock, flags);
 +      raw_spin_unlock_irqrestore(&dio48egpio->lock, flags);
  
        return 0;
  }
@@@ -120,7 -120,7 +120,7 @@@ static int dio48e_gpio_direction_output
        unsigned long flags;
        unsigned control;
  
 -      spin_lock_irqsave(&dio48egpio->lock, flags);
 +      raw_spin_lock_irqsave(&dio48egpio->lock, flags);
  
        /* Check if configuring Port C */
        if (io_port == 2 || io_port == 5) {
        control &= ~BIT(7);
        outb(control, control_addr);
  
 -      spin_unlock_irqrestore(&dio48egpio->lock, flags);
 +      raw_spin_unlock_irqrestore(&dio48egpio->lock, flags);
  
        return 0;
  }
@@@ -167,17 -167,17 +167,17 @@@ static int dio48e_gpio_get(struct gpio_
        unsigned long flags;
        unsigned port_state;
  
 -      spin_lock_irqsave(&dio48egpio->lock, flags);
 +      raw_spin_lock_irqsave(&dio48egpio->lock, flags);
  
        /* ensure that GPIO is set for input */
        if (!(dio48egpio->io_state[port] & mask)) {
 -              spin_unlock_irqrestore(&dio48egpio->lock, flags);
 +              raw_spin_unlock_irqrestore(&dio48egpio->lock, flags);
                return -EINVAL;
        }
  
        port_state = inb(dio48egpio->base + in_port);
  
 -      spin_unlock_irqrestore(&dio48egpio->lock, flags);
 +      raw_spin_unlock_irqrestore(&dio48egpio->lock, flags);
  
        return !!(port_state & mask);
  }
@@@ -190,7 -190,7 +190,7 @@@ static void dio48e_gpio_set(struct gpio
        const unsigned out_port = (port > 2) ? port + 1 : port;
        unsigned long flags;
  
 -      spin_lock_irqsave(&dio48egpio->lock, flags);
 +      raw_spin_lock_irqsave(&dio48egpio->lock, flags);
  
        if (value)
                dio48egpio->out_state[port] |= mask;
  
        outb(dio48egpio->out_state[port], dio48egpio->base + out_port);
  
 -      spin_unlock_irqrestore(&dio48egpio->lock, flags);
 +      raw_spin_unlock_irqrestore(&dio48egpio->lock, flags);
  }
  
  static void dio48e_gpio_set_multiple(struct gpio_chip *chip,
                out_port = (port > 2) ? port + 1 : port;
                bitmask = mask[BIT_WORD(i)] & bits[BIT_WORD(i)];
  
 -              spin_lock_irqsave(&dio48egpio->lock, flags);
 +              raw_spin_lock_irqsave(&dio48egpio->lock, flags);
  
                /* update output state data and set device gpio register */
                dio48egpio->out_state[port] &= ~mask[BIT_WORD(i)];
                dio48egpio->out_state[port] |= bitmask;
                outb(dio48egpio->out_state[port], dio48egpio->base + out_port);
  
 -              spin_unlock_irqrestore(&dio48egpio->lock, flags);
 +              raw_spin_unlock_irqrestore(&dio48egpio->lock, flags);
  
                /* prepare for next gpio register set */
                mask[BIT_WORD(i)] >>= gpio_reg_size;
@@@ -255,7 -255,7 +255,7 @@@ static void dio48e_irq_mask(struct irq_
        if (offset != 19 && offset != 43)
                return;
  
 -      spin_lock_irqsave(&dio48egpio->lock, flags);
 +      raw_spin_lock_irqsave(&dio48egpio->lock, flags);
  
        if (offset == 19)
                dio48egpio->irq_mask &= ~BIT(0);
                /* disable interrupts */
                inb(dio48egpio->base + 0xB);
  
 -      spin_unlock_irqrestore(&dio48egpio->lock, flags);
 +      raw_spin_unlock_irqrestore(&dio48egpio->lock, flags);
  }
  
  static void dio48e_irq_unmask(struct irq_data *data)
        if (offset != 19 && offset != 43)
                return;
  
 -      spin_lock_irqsave(&dio48egpio->lock, flags);
 +      raw_spin_lock_irqsave(&dio48egpio->lock, flags);
  
        if (!dio48egpio->irq_mask) {
                /* enable interrupts */
        else
                dio48egpio->irq_mask |= BIT(1);
  
 -      spin_unlock_irqrestore(&dio48egpio->lock, flags);
 +      raw_spin_unlock_irqrestore(&dio48egpio->lock, flags);
  }
  
  static int dio48e_irq_set_type(struct irq_data *data, unsigned flow_type)
@@@ -329,11 -329,11 +329,11 @@@ static irqreturn_t dio48e_irq_handler(i
                generic_handle_irq(irq_find_mapping(chip->irqdomain,
                        19 + gpio*24));
  
 -      spin_lock(&dio48egpio->lock);
 +      raw_spin_lock(&dio48egpio->lock);
  
        outb(0x00, dio48egpio->base + 0xF);
  
 -      spin_unlock(&dio48egpio->lock);
 +      raw_spin_unlock(&dio48egpio->lock);
  
        return IRQ_HANDLED;
  }
@@@ -388,7 -388,7 +388,7 @@@ static int dio48e_probe(struct device *
        dio48egpio->chip.set_multiple = dio48e_gpio_set_multiple;
        dio48egpio->base = base[id];
  
 -      spin_lock_init(&dio48egpio->lock);
 +      raw_spin_lock_init(&dio48egpio->lock);
  
        err = devm_gpiochip_add_data(dev, &dio48egpio->chip, dio48egpio);
        if (err) {
index 337c048168d82d90c68f2da6425621763a993146,c369b208387651618417cd1277050fa6775feb01..51f046e29ff79873c21497f1dfa8a5cd8cfdeb09
  
  static unsigned int base[MAX_NUM_IDI_48];
  static unsigned int num_idi_48;
- module_param_array(base, uint, &num_idi_48, 0);
+ module_param_hw_array(base, uint, ioport, &num_idi_48, 0);
  MODULE_PARM_DESC(base, "ACCES 104-IDI-48 base addresses");
  
  static unsigned int irq[MAX_NUM_IDI_48];
- module_param_array(irq, uint, NULL, 0);
+ module_param_hw_array(irq, uint, irq, NULL, 0);
  MODULE_PARM_DESC(irq, "ACCES 104-IDI-48 interrupt line numbers");
  
  /**
@@@ -51,7 -51,7 +51,7 @@@
   */
  struct idi_48_gpio {
        struct gpio_chip chip;
 -      spinlock_t lock;
 +      raw_spinlock_t lock;
        spinlock_t ack_lock;
        unsigned char irq_mask[6];
        unsigned base;
@@@ -112,12 -112,11 +112,12 @@@ static void idi_48_irq_mask(struct irq_
                        if (!idi48gpio->irq_mask[boundary]) {
                                idi48gpio->cos_enb &= ~BIT(boundary);
  
 -                              spin_lock_irqsave(&idi48gpio->lock, flags);
 +                              raw_spin_lock_irqsave(&idi48gpio->lock, flags);
  
                                outb(idi48gpio->cos_enb, idi48gpio->base + 7);
  
 -                              spin_unlock_irqrestore(&idi48gpio->lock, flags);
 +                              raw_spin_unlock_irqrestore(&idi48gpio->lock,
 +                                                         flags);
                        }
  
                        return;
@@@ -146,12 -145,11 +146,12 @@@ static void idi_48_irq_unmask(struct ir
                        if (!prev_irq_mask) {
                                idi48gpio->cos_enb |= BIT(boundary);
  
 -                              spin_lock_irqsave(&idi48gpio->lock, flags);
 +                              raw_spin_lock_irqsave(&idi48gpio->lock, flags);
  
                                outb(idi48gpio->cos_enb, idi48gpio->base + 7);
  
 -                              spin_unlock_irqrestore(&idi48gpio->lock, flags);
 +                              raw_spin_unlock_irqrestore(&idi48gpio->lock,
 +                                                         flags);
                        }
  
                        return;
@@@ -188,11 -186,11 +188,11 @@@ static irqreturn_t idi_48_irq_handler(i
  
        spin_lock(&idi48gpio->ack_lock);
  
 -      spin_lock(&idi48gpio->lock);
 +      raw_spin_lock(&idi48gpio->lock);
  
        cos_status = inb(idi48gpio->base + 7);
  
 -      spin_unlock(&idi48gpio->lock);
 +      raw_spin_unlock(&idi48gpio->lock);
  
        /* IRQ Status (bit 6) is active low (0 = IRQ generated by device) */
        if (cos_status & BIT(6)) {
@@@ -258,7 -256,7 +258,7 @@@ static int idi_48_probe(struct device *
        idi48gpio->chip.get = idi_48_gpio_get;
        idi48gpio->base = base[id];
  
 -      spin_lock_init(&idi48gpio->lock);
 +      raw_spin_lock_init(&idi48gpio->lock);
        spin_lock_init(&idi48gpio->ack_lock);
  
        err = devm_gpiochip_add_data(dev, &idi48gpio->chip, idi48gpio);
index 5281e1cedb01d8937373cdda3c804c25f3f342e1,5949123986f205502a060674909a8365ef253773..ec2ce34ff47371d877385c48c9209dc3ce57f9dc
  
  static unsigned int base[MAX_NUM_IDIO_16];
  static unsigned int num_idio_16;
- module_param_array(base, uint, &num_idio_16, 0);
+ module_param_hw_array(base, uint, ioport, &num_idio_16, 0);
  MODULE_PARM_DESC(base, "ACCES 104-IDIO-16 base addresses");
  
  static unsigned int irq[MAX_NUM_IDIO_16];
- module_param_array(irq, uint, NULL, 0);
+ module_param_hw_array(irq, uint, irq, NULL, 0);
  MODULE_PARM_DESC(irq, "ACCES 104-IDIO-16 interrupt line numbers");
  
  /**
@@@ -50,7 -50,7 +50,7 @@@
   */
  struct idio_16_gpio {
        struct gpio_chip chip;
 -      spinlock_t lock;
 +      raw_spinlock_t lock;
        unsigned long irq_mask;
        unsigned base;
        unsigned out_state;
@@@ -99,7 -99,7 +99,7 @@@ static void idio_16_gpio_set(struct gpi
        if (offset > 15)
                return;
  
 -      spin_lock_irqsave(&idio16gpio->lock, flags);
 +      raw_spin_lock_irqsave(&idio16gpio->lock, flags);
  
        if (value)
                idio16gpio->out_state |= mask;
        else
                outb(idio16gpio->out_state, idio16gpio->base);
  
 -      spin_unlock_irqrestore(&idio16gpio->lock, flags);
 +      raw_spin_unlock_irqrestore(&idio16gpio->lock, flags);
  }
  
  static void idio_16_gpio_set_multiple(struct gpio_chip *chip,
        struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
        unsigned long flags;
  
 -      spin_lock_irqsave(&idio16gpio->lock, flags);
 +      raw_spin_lock_irqsave(&idio16gpio->lock, flags);
  
        idio16gpio->out_state &= ~*mask;
        idio16gpio->out_state |= *mask & *bits;
        if ((*mask >> 8) & 0xFF)
                outb(idio16gpio->out_state >> 8, idio16gpio->base + 4);
  
 -      spin_unlock_irqrestore(&idio16gpio->lock, flags);
 +      raw_spin_unlock_irqrestore(&idio16gpio->lock, flags);
  }
  
  static void idio_16_irq_ack(struct irq_data *data)
@@@ -147,11 -147,11 +147,11 @@@ static void idio_16_irq_mask(struct irq
        idio16gpio->irq_mask &= ~mask;
  
        if (!idio16gpio->irq_mask) {
 -              spin_lock_irqsave(&idio16gpio->lock, flags);
 +              raw_spin_lock_irqsave(&idio16gpio->lock, flags);
  
                outb(0, idio16gpio->base + 2);
  
 -              spin_unlock_irqrestore(&idio16gpio->lock, flags);
 +              raw_spin_unlock_irqrestore(&idio16gpio->lock, flags);
        }
  }
  
@@@ -166,11 -166,11 +166,11 @@@ static void idio_16_irq_unmask(struct i
        idio16gpio->irq_mask |= mask;
  
        if (!prev_irq_mask) {
 -              spin_lock_irqsave(&idio16gpio->lock, flags);
 +              raw_spin_lock_irqsave(&idio16gpio->lock, flags);
  
                inb(idio16gpio->base + 2);
  
 -              spin_unlock_irqrestore(&idio16gpio->lock, flags);
 +              raw_spin_unlock_irqrestore(&idio16gpio->lock, flags);
        }
  }
  
@@@ -201,11 -201,11 +201,11 @@@ static irqreturn_t idio_16_irq_handler(
        for_each_set_bit(gpio, &idio16gpio->irq_mask, chip->ngpio)
                generic_handle_irq(irq_find_mapping(chip->irqdomain, gpio));
  
 -      spin_lock(&idio16gpio->lock);
 +      raw_spin_lock(&idio16gpio->lock);
  
        outb(0, idio16gpio->base + 1);
  
 -      spin_unlock(&idio16gpio->lock);
 +      raw_spin_unlock(&idio16gpio->lock);
  
        return IRQ_HANDLED;
  }
@@@ -249,7 -249,7 +249,7 @@@ static int idio_16_probe(struct device 
        idio16gpio->base = base[id];
        idio16gpio->out_state = 0xFFFF;
  
 -      spin_lock_init(&idio16gpio->lock);
 +      raw_spin_lock_init(&idio16gpio->lock);
  
        err = devm_gpiochip_add_data(dev, &idio16gpio->chip, idio16gpio);
        if (err) {
index 87d63695dfcf796d73c04c795ab2eaf17d2acb74,f8a4f91f36c78ced7c078db8caf08d8813a94316..5037974ac06356d0e4cba43f99923860f53b4706
  
  static unsigned int base[MAX_NUM_WS16C48];
  static unsigned int num_ws16c48;
- module_param_array(base, uint, &num_ws16c48, 0);
+ module_param_hw_array(base, uint, ioport, &num_ws16c48, 0);
  MODULE_PARM_DESC(base, "WinSystems WS16C48 base addresses");
  
  static unsigned int irq[MAX_NUM_WS16C48];
- module_param_array(irq, uint, NULL, 0);
+ module_param_hw_array(irq, uint, irq, NULL, 0);
  MODULE_PARM_DESC(irq, "WinSystems WS16C48 interrupt line numbers");
  
  /**
@@@ -51,7 -51,7 +51,7 @@@ struct ws16c48_gpio 
        struct gpio_chip chip;
        unsigned char io_state[6];
        unsigned char out_state[6];
 -      spinlock_t lock;
 +      raw_spinlock_t lock;
        unsigned long irq_mask;
        unsigned long flow_mask;
        unsigned base;
@@@ -73,13 -73,13 +73,13 @@@ static int ws16c48_gpio_direction_input
        const unsigned mask = BIT(offset % 8);
        unsigned long flags;
  
 -      spin_lock_irqsave(&ws16c48gpio->lock, flags);
 +      raw_spin_lock_irqsave(&ws16c48gpio->lock, flags);
  
        ws16c48gpio->io_state[port] |= mask;
        ws16c48gpio->out_state[port] &= ~mask;
        outb(ws16c48gpio->out_state[port], ws16c48gpio->base + port);
  
 -      spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
 +      raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
  
        return 0;
  }
@@@ -92,7 -92,7 +92,7 @@@ static int ws16c48_gpio_direction_outpu
        const unsigned mask = BIT(offset % 8);
        unsigned long flags;
  
 -      spin_lock_irqsave(&ws16c48gpio->lock, flags);
 +      raw_spin_lock_irqsave(&ws16c48gpio->lock, flags);
  
        ws16c48gpio->io_state[port] &= ~mask;
        if (value)
                ws16c48gpio->out_state[port] &= ~mask;
        outb(ws16c48gpio->out_state[port], ws16c48gpio->base + port);
  
 -      spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
 +      raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
  
        return 0;
  }
@@@ -114,17 -114,17 +114,17 @@@ static int ws16c48_gpio_get(struct gpio
        unsigned long flags;
        unsigned port_state;
  
 -      spin_lock_irqsave(&ws16c48gpio->lock, flags);
 +      raw_spin_lock_irqsave(&ws16c48gpio->lock, flags);
  
        /* ensure that GPIO is set for input */
        if (!(ws16c48gpio->io_state[port] & mask)) {
 -              spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
 +              raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
                return -EINVAL;
        }
  
        port_state = inb(ws16c48gpio->base + port);
  
 -      spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
 +      raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
  
        return !!(port_state & mask);
  }
@@@ -136,11 -136,11 +136,11 @@@ static void ws16c48_gpio_set(struct gpi
        const unsigned mask = BIT(offset % 8);
        unsigned long flags;
  
 -      spin_lock_irqsave(&ws16c48gpio->lock, flags);
 +      raw_spin_lock_irqsave(&ws16c48gpio->lock, flags);
  
        /* ensure that GPIO is set for output */
        if (ws16c48gpio->io_state[port] & mask) {
 -              spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
 +              raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
                return;
        }
  
                ws16c48gpio->out_state[port] &= ~mask;
        outb(ws16c48gpio->out_state[port], ws16c48gpio->base + port);
  
 -      spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
 +      raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
  }
  
  static void ws16c48_gpio_set_multiple(struct gpio_chip *chip,
                iomask = mask[BIT_WORD(i)] & ~ws16c48gpio->io_state[port];
                bitmask = iomask & bits[BIT_WORD(i)];
  
 -              spin_lock_irqsave(&ws16c48gpio->lock, flags);
 +              raw_spin_lock_irqsave(&ws16c48gpio->lock, flags);
  
                /* update output state data and set device gpio register */
                ws16c48gpio->out_state[port] &= ~iomask;
                ws16c48gpio->out_state[port] |= bitmask;
                outb(ws16c48gpio->out_state[port], ws16c48gpio->base + port);
  
 -              spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
 +              raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
  
                /* prepare for next gpio register set */
                mask[BIT_WORD(i)] >>= gpio_reg_size;
@@@ -207,7 -207,7 +207,7 @@@ static void ws16c48_irq_ack(struct irq_
        if (port > 2)
                return;
  
 -      spin_lock_irqsave(&ws16c48gpio->lock, flags);
 +      raw_spin_lock_irqsave(&ws16c48gpio->lock, flags);
  
        port_state = ws16c48gpio->irq_mask >> (8*port);
  
        outb(port_state | mask, ws16c48gpio->base + 8 + port);
        outb(0xC0, ws16c48gpio->base + 7);
  
 -      spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
 +      raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
  }
  
  static void ws16c48_irq_mask(struct irq_data *data)
        if (port > 2)
                return;
  
 -      spin_lock_irqsave(&ws16c48gpio->lock, flags);
 +      raw_spin_lock_irqsave(&ws16c48gpio->lock, flags);
  
        ws16c48gpio->irq_mask &= ~mask;
  
        outb(ws16c48gpio->irq_mask >> (8*port), ws16c48gpio->base + 8 + port);
        outb(0xC0, ws16c48gpio->base + 7);
  
 -      spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
 +      raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
  }
  
  static void ws16c48_irq_unmask(struct irq_data *data)
        if (port > 2)
                return;
  
 -      spin_lock_irqsave(&ws16c48gpio->lock, flags);
 +      raw_spin_lock_irqsave(&ws16c48gpio->lock, flags);
  
        ws16c48gpio->irq_mask |= mask;
  
        outb(ws16c48gpio->irq_mask >> (8*port), ws16c48gpio->base + 8 + port);
        outb(0xC0, ws16c48gpio->base + 7);
  
 -      spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
 +      raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
  }
  
  static int ws16c48_irq_set_type(struct irq_data *data, unsigned flow_type)
        if (port > 2)
                return -EINVAL;
  
 -      spin_lock_irqsave(&ws16c48gpio->lock, flags);
 +      raw_spin_lock_irqsave(&ws16c48gpio->lock, flags);
  
        switch (flow_type) {
        case IRQ_TYPE_NONE:
                ws16c48gpio->flow_mask &= ~mask;
                break;
        default:
 -              spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
 +              raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
                return -EINVAL;
        }
  
        outb(ws16c48gpio->flow_mask >> (8*port), ws16c48gpio->base + 8 + port);
        outb(0xC0, ws16c48gpio->base + 7);
  
 -      spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
 +      raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
  
        return 0;
  }
@@@ -387,7 -387,7 +387,7 @@@ static int ws16c48_probe(struct device 
        ws16c48gpio->chip.set_multiple = ws16c48_gpio_set_multiple;
        ws16c48gpio->base = base[id];
  
 -      spin_lock_init(&ws16c48gpio->lock);
 +      raw_spin_lock_init(&ws16c48gpio->lock);
  
        err = devm_gpiochip_add_data(dev, &ws16c48gpio->chip, ws16c48gpio);
        if (err) {
diff --combined drivers/iio/adc/stx104.c
index 2df84fa5e3fcd3d9fd89de1790979fbdd1633435,7dd396f88f6bdd355234758d4914c9cdffc58046..2da741d27540f8369f19534f872cc3a846c3d2b6
@@@ -49,7 -49,7 +49,7 @@@
  
  static unsigned int base[max_num_isa_dev(STX104_EXTENT)];
  static unsigned int num_stx104;
- module_param_array(base, uint, &num_stx104, 0);
+ module_param_hw_array(base, uint, ioport, &num_stx104, 0);
  MODULE_PARM_DESC(base, "Apex Embedded Systems STX104 base addresses");
  
  /**
@@@ -318,7 -318,6 +318,7 @@@ static int stx104_probe(struct device *
        }
  
        indio_dev->name = dev_name(dev);
 +      indio_dev->dev.parent = dev;
  
        priv = iio_priv(indio_dev);
        priv->base = base[id];
index a0464227a3a0dfb9153f8c285332587f8c2c395f,dac086129edf8d50b2cf59eeb5e43ff2a06aed7d..a8dffd9386153f0aa13d7eed8f3f80ab64d52938
@@@ -39,7 -39,7 +39,7 @@@
  
  static unsigned int base[max_num_isa_dev(CIO_DAC_EXTENT)];
  static unsigned int num_cio_dac;
- module_param_array(base, uint, &num_cio_dac, 0);
+ module_param_hw_array(base, uint, ioport, &num_cio_dac, 0);
  MODULE_PARM_DESC(base, "Measurement Computing CIO-DAC base addresses");
  
  /**
@@@ -119,7 -119,6 +119,7 @@@ static int cio_dac_probe(struct device 
        indio_dev->channels = cio_dac_channels;
        indio_dev->num_channels = CIO_DAC_NUM_CHAN;
        indio_dev->name = dev_name(dev);
 +      indio_dev->dev.parent = dev;
  
        priv = iio_priv(indio_dev);
        priv->base = base[id];
index 2f0a0d24893651c97f7a469a1b92a3a4a653ec93,40d305842a9b29e1e220f6e8420d4f14a44f4c09..77d5d4cbed0a06fcb316c0fb2d6c59a470c3f585
@@@ -56,7 -56,7 +56,7 @@@ struct serial_ir_hw 
  static int type;
  static int io;
  static int irq;
 -static bool iommap;
 +static ulong iommap;
  static int ioshift;
  static bool softcarrier = true;
  static bool share_irq;
@@@ -833,11 -833,11 +833,11 @@@ MODULE_LICENSE("GPL")
  module_param(type, int, 0444);
  MODULE_PARM_DESC(type, "Hardware type (0 = home-brew, 1 = IRdeo, 2 = IRdeo Remote, 3 = AnimaX, 4 = IgorPlug");
  
- module_param(io, int, 0444);
+ module_param_hw(io, int, ioport, 0444);
  MODULE_PARM_DESC(io, "I/O address base (0x3f8 or 0x2f8)");
  
  /* some architectures (e.g. intel xscale) have memory mapped registers */
- module_param(iommap, ulong, 0444);
 -module_param_hw(iommap, bool, other, 0444);
++module_param_hw(iommap, ulong, other, 0444);
  MODULE_PARM_DESC(iommap, "physical base for memory mapped I/O (0 = no memory mapped io)");
  
  /*
   * on 32bit word boundaries.
   * See linux-kernel/drivers/tty/serial/8250/8250.c serial_in()/out()
   */
- module_param(ioshift, int, 0444);
+ module_param_hw(ioshift, int, other, 0444);
  MODULE_PARM_DESC(ioshift, "shift I/O register offset (0 = no shift)");
  
- module_param(irq, int, 0444);
+ module_param_hw(irq, int, irq, 0444);
  MODULE_PARM_DESC(irq, "Interrupt (4 or 3)");
  
- module_param(share_irq, bool, 0444);
+ module_param_hw(share_irq, bool, other, 0444);
  MODULE_PARM_DESC(share_irq, "Share interrupts (0 = off, 1 = on)");
  
  module_param(sense, int, 0444);
index 47384f7323acb974eba4beb2f7de29ebd34ff953,8f660d9761cc01b7bfba6105f0fcc2b8495a6ed3..da5b58b853e2947258551ebb962f30b2005746d0
@@@ -1704,12 -1704,12 +1704,12 @@@ static int use_dma;                  /* These generat
  static int dma;
  static int dmasize = 16;              /* or 64 */
  
- module_param(io, int, 0);
- module_param(irq, int, 0);
+ module_param_hw(io, int, ioport, 0);
+ module_param_hw(irq, int, irq, 0);
  module_param(debug, int, 0);
  module_param_string(media, media, sizeof(media), 0);
  module_param(duplex, int, 0);
- module_param(dma , int, 0);
+ module_param_hw(dma , int, dma, 0);
  module_param(dmasize , int, 0);
  module_param(use_dma , int, 0);
  MODULE_PARM_DESC(io, "cs89x0 I/O base address");
@@@ -1896,7 -1896,7 +1896,7 @@@ static int cs89x0_platform_remove(struc
        return 0;
  }
  
 -static const struct __maybe_unused of_device_id cs89x0_match[] = {
 +static const struct of_device_id __maybe_unused cs89x0_match[] = {
        { .compatible = "cirrus,cs8900", },
        { .compatible = "cirrus,cs8920", },
        { },
index ad72f8e883fc4a5425c0b23f0f91e049b43295f2,b6fbf9de1f85d3155672b8c32ea915ffea3c5385..a041441766aa4df2f1943d681140c30379ddd9b3
@@@ -113,7 -113,6 +113,7 @@@ static struct spk_synth synth_acntpc = 
        .startup = SYNTH_START,
        .checkval = SYNTH_CHECK,
        .vars = vars,
 +      .io_ops = &spk_serial_io_ops,
        .probe = synth_probe,
        .release = accent_release,
        .synth_immediate = synth_immediate,
@@@ -197,7 -196,6 +197,7 @@@ static void do_catch_up(struct spk_synt
                        synth->flush(synth);
                        continue;
                }
 +              synth_buffer_skip_nonlatin1();
                if (synth_buffer_empty()) {
                        spin_unlock_irqrestore(&speakup_info.spinlock, flags);
                        break;
                        delay_time_val = delay_time->u.n.value;
                        spin_unlock_irqrestore(&speakup_info.spinlock, flags);
                        schedule_timeout(msecs_to_jiffies(delay_time_val));
 -                      jiff_max = jiffies+jiffy_delta_val;
 +                      jiff_max = jiffies + jiffy_delta_val;
                }
        }
        timeout = SPK_XMITR_TIMEOUT;
@@@ -261,18 -259,18 +261,18 @@@ static int synth_probe(struct spk_synt
        if (port_forced) {
                speakup_info.port_tts = port_forced;
                pr_info("probe forced to %x by kernel command line\n",
 -                              speakup_info.port_tts);
 -              if (synth_request_region(speakup_info.port_tts-1,
 -                                      SYNTH_IO_EXTENT)) {
 +                      speakup_info.port_tts);
 +              if (synth_request_region(speakup_info.port_tts - 1,
 +                                       SYNTH_IO_EXTENT)) {
                        pr_warn("sorry, port already reserved\n");
                        return -EBUSY;
                }
 -              port_val = inw(speakup_info.port_tts-1);
 -              synth_port_control = speakup_info.port_tts-1;
 +              port_val = inw(speakup_info.port_tts - 1);
 +              synth_port_control = speakup_info.port_tts - 1;
        } else {
                for (i = 0; synth_portlist[i]; i++) {
                        if (synth_request_region(synth_portlist[i],
 -                                              SYNTH_IO_EXTENT)) {
 +                                               SYNTH_IO_EXTENT)) {
                                pr_warn
                                    ("request_region: failed with 0x%x, %d\n",
                                     synth_portlist[i], SYNTH_IO_EXTENT);
                        if (port_val == 0x53fc) {
                                /* 'S' and out&input bits */
                                synth_port_control = synth_portlist[i];
 -                              speakup_info.port_tts = synth_port_control+1;
 +                              speakup_info.port_tts = synth_port_control + 1;
                                break;
                        }
                }
                return -ENODEV;
        }
        pr_info("%s: %03x-%03x, driver version %s,\n", synth->long_name,
 -              synth_port_control, synth_port_control+SYNTH_IO_EXTENT-1,
 +              synth_port_control, synth_port_control + SYNTH_IO_EXTENT - 1,
                synth->version);
        synth->alive = 1;
        return 0;
  
  static void accent_release(void)
  {
 +      spk_stop_serial_interrupt();
        if (speakup_info.port_tts)
                synth_release_region(speakup_info.port_tts-1, SYNTH_IO_EXTENT);
        speakup_info.port_tts = 0;
  }
  
- module_param_named(port, port_forced, int, 0444);
+ module_param_hw_named(port, port_forced, int, ioport, 0444);
  module_param_named(start, synth_acntpc.startup, short, 0444);
  
  MODULE_PARM_DESC(port, "Set the port for the synthesizer (override probing).");
index 5973acc0a00654806afdb6345069b69d426a389c,9c097fda07b08db44a786117edb41b1e148cd03f..33180937222d1a930eba0d79a4a4197606aca548
@@@ -43,7 -43,6 +43,7 @@@ static int port_forced
  static unsigned int synth_portlist[] = {
                 0x25e, 0x29e, 0x2de, 0x31e, 0x35e, 0x39e, 0
  };
 +
  static u_char synth_status;
  
  static struct var_t vars[] = {
@@@ -129,7 -128,6 +129,7 @@@ static struct spk_synth synth_dtlk = 
        .startup = SYNTH_START,
        .checkval = SYNTH_CHECK,
        .vars = vars,
 +      .io_ops = &spk_serial_io_ops,
        .probe = synth_probe,
        .release = dtlk_release,
        .synth_immediate = synth_immediate,
@@@ -211,7 -209,6 +211,7 @@@ static void do_catch_up(struct spk_synt
                        synth->flush(synth);
                        continue;
                }
 +              synth_buffer_skip_nonlatin1();
                if (synth_buffer_empty()) {
                        spin_unlock_irqrestore(&speakup_info.spinlock, flags);
                        break;
@@@ -300,7 -297,7 +300,7 @@@ static struct synth_settings *synth_int
        t += 2;
        for (i = 0; *t != '\r'; t++) {
                status.rom_version[i] = *t;
 -              if (i < sizeof(status.rom_version)-1)
 +              if (i < sizeof(status.rom_version) - 1)
                        i++;
        }
        status.rom_version[i] = 0;
@@@ -376,13 -373,12 +376,13 @@@ static int synth_probe(struct spk_synt
  
  static void dtlk_release(void)
  {
 +      spk_stop_serial_interrupt();
        if (speakup_info.port_tts)
                synth_release_region(speakup_info.port_tts-1, SYNTH_IO_EXTENT);
        speakup_info.port_tts = 0;
  }
  
- module_param_named(port, port_forced, int, 0444);
+ module_param_hw_named(port, port_forced, int, ioport, 0444);
  module_param_named(start, synth_dtlk.startup, short, 0444);
  
  MODULE_PARM_DESC(port, "Set the port for the synthesizer (override probing).");
index ba7901178e0b5eaaed04dd546874614ca974da31,e653b52175b88cf332ff4b0b998da99cd2a730a2..d3203f8fc3d04ca8666a65fb5e44e956b86f31aa
@@@ -105,7 -105,6 +105,7 @@@ static struct spk_synth synth_keypc = 
        .startup = SYNTH_START,
        .checkval = SYNTH_CHECK,
        .vars = vars,
 +      .io_ops = &spk_serial_io_ops,
        .probe = synth_probe,
        .release = keynote_release,
        .synth_immediate = synth_immediate,
@@@ -142,9 -141,9 +142,9 @@@ static char *oops(void
        int s1, s2, s3, s4;
  
        s1 = inb_p(synth_port);
 -      s2 = inb_p(synth_port+1);
 -      s3 = inb_p(synth_port+2);
 -      s4 = inb_p(synth_port+3);
 +      s2 = inb_p(synth_port + 1);
 +      s3 = inb_p(synth_port + 2);
 +      s4 = inb_p(synth_port + 3);
        pr_warn("synth timeout %d %d %d %d\n", s1, s2, s3, s4);
        return NULL;
  }
@@@ -199,7 -198,6 +199,7 @@@ spin_lock_irqsave(&speakup_info.spinloc
                        synth->flush(synth);
                        continue;
                }
 +              synth_buffer_skip_nonlatin1();
                if (synth_buffer_empty()) {
                        spin_unlock_irqrestore(&speakup_info.spinlock, flags);
                        break;
@@@ -306,13 -304,12 +306,13 @@@ static int synth_probe(struct spk_synt
  
  static void keynote_release(void)
  {
 +      spk_stop_serial_interrupt();
        if (synth_port)
                synth_release_region(synth_port, SYNTH_IO_EXTENT);
        synth_port = 0;
  }
  
- module_param_named(port, port_forced, int, 0444);
+ module_param_hw_named(port, port_forced, int, ioport, 0444);
  module_param_named(start, synth_keypc.startup, short, 0444);
  
  MODULE_PARM_DESC(port, "Set the port for the synthesizer (override probing).");
index 48a07e2f617fb69dbcd55cd03205e7abcde8a39b,89fde17d96175abf3bd41c823bb70855285059d2..1aab3010fbfae76e2c25cb60085f21051a1f24cf
@@@ -218,7 -218,7 +218,7 @@@ static int serial_link_irq_chain(struc
                spin_unlock_irq(&i->lock);
                irq_flags |= up->port.irqflags;
                ret = request_irq(up->port.irq, serial8250_interrupt,
 -                                irq_flags, "serial", i);
 +                                irq_flags, up->port.name, i);
                if (ret < 0)
                        serial_do_unlink(i, up);
        }
@@@ -1191,7 -1191,7 +1191,7 @@@ module_exit(serial8250_exit)
  MODULE_LICENSE("GPL");
  MODULE_DESCRIPTION("Generic 8250/16x50 serial driver");
  
- module_param(share_irqs, uint, 0644);
+ module_param_hw(share_irqs, uint, other, 0644);
  MODULE_PARM_DESC(share_irqs, "Share IRQs with other non-8250/16x50 devices (unsafe)");
  
  module_param(nr_uarts, uint, 0644);
@@@ -1201,7 -1201,7 +1201,7 @@@ module_param(skip_txen_test, uint, 0644
  MODULE_PARM_DESC(skip_txen_test, "Skip checking for the TXEN bug at init time");
  
  #ifdef CONFIG_SERIAL_8250_RSA
- module_param_array(probe_rsa, ulong, &probe_rsa_count, 0444);
+ module_param_hw_array(probe_rsa, ulong, ioport, &probe_rsa_count, 0444);
  MODULE_PARM_DESC(probe_rsa, "Probe I/O ports for RSA");
  #endif
  MODULE_ALIAS_CHARDEV_MAJOR(TTY_MAJOR);
diff --combined fs/pstore/ram.c
index 5523df7f17ef05818d2c444c682e66579c38742d,cce1d38417ca5591e5a8e62dedcbbad5aa9ac683..5cb022c8cd33f23b566721627dc25dd0263da3a8
@@@ -58,7 -58,7 +58,7 @@@ module_param_named(pmsg_size, ramoops_p
  MODULE_PARM_DESC(pmsg_size, "size of user space message log");
  
  static unsigned long long mem_address;
- module_param(mem_address, ullong, 0400);
+ module_param_hw(mem_address, ullong, other, 0400);
  MODULE_PARM_DESC(mem_address,
                "start of reserved RAM used to store oops/panic logs");
  
@@@ -235,34 -235,35 +235,34 @@@ static ssize_t ftrace_log_combine(struc
        return 0;
  }
  
 -static ssize_t ramoops_pstore_read(u64 *id, enum pstore_type_id *type,
 -                                 int *count, struct timespec *time,
 -                                 char **buf, bool *compressed,
 -                                 ssize_t *ecc_notice_size,
 -                                 struct pstore_info *psi)
 +static ssize_t ramoops_pstore_read(struct pstore_record *record)
  {
        ssize_t size = 0;
 -      struct ramoops_context *cxt = psi->data;
 +      struct ramoops_context *cxt = record->psi->data;
        struct persistent_ram_zone *prz = NULL;
        int header_length = 0;
        bool free_prz = false;
  
 -      /* Ramoops headers provide time stamps for PSTORE_TYPE_DMESG, but
 +      /*
 +       * Ramoops headers provide time stamps for PSTORE_TYPE_DMESG, but
         * PSTORE_TYPE_CONSOLE and PSTORE_TYPE_FTRACE don't currently have
         * valid time stamps, so it is initialized to zero.
         */
 -      time->tv_sec = 0;
 -      time->tv_nsec = 0;
 -      *compressed = false;
 +      record->time.tv_sec = 0;
 +      record->time.tv_nsec = 0;
 +      record->compressed = false;
  
        /* Find the next valid persistent_ram_zone for DMESG */
        while (cxt->dump_read_cnt < cxt->max_dump_cnt && !prz) {
                prz = ramoops_get_next_prz(cxt->dprzs, &cxt->dump_read_cnt,
 -                                         cxt->max_dump_cnt, id, type,
 +                                         cxt->max_dump_cnt, &record->id,
 +                                         &record->type,
                                           PSTORE_TYPE_DMESG, 1);
                if (!prz_ok(prz))
                        continue;
                header_length = ramoops_read_kmsg_hdr(persistent_ram_old(prz),
 -                                                    time, compressed);
 +                                                    &record->time,
 +                                                    &record->compressed);
                /* Clear and skip this DMESG record if it has no valid header */
                if (!header_length) {
                        persistent_ram_free_old(prz);
  
        if (!prz_ok(prz))
                prz = ramoops_get_next_prz(&cxt->cprz, &cxt->console_read_cnt,
 -                                         1, id, type, PSTORE_TYPE_CONSOLE, 0);
 +                                         1, &record->id, &record->type,
 +                                         PSTORE_TYPE_CONSOLE, 0);
  
        if (!prz_ok(prz))
                prz = ramoops_get_next_prz(&cxt->mprz, &cxt->pmsg_read_cnt,
 -                                         1, id, type, PSTORE_TYPE_PMSG, 0);
 +                                         1, &record->id, &record->type,
 +                                         PSTORE_TYPE_PMSG, 0);
  
        /* ftrace is last since it may want to dynamically allocate memory. */
        if (!prz_ok(prz)) {
                if (!(cxt->flags & RAMOOPS_FLAG_FTRACE_PER_CPU)) {
                        prz = ramoops_get_next_prz(cxt->fprzs,
 -                                      &cxt->ftrace_read_cnt, 1, id, type,
 -                                      PSTORE_TYPE_FTRACE, 0);
 +                                      &cxt->ftrace_read_cnt, 1, &record->id,
 +                                      &record->type, PSTORE_TYPE_FTRACE, 0);
                } else {
                        /*
                         * Build a new dummy record which combines all the
                        while (cxt->ftrace_read_cnt < cxt->max_ftrace_cnt) {
                                prz_next = ramoops_get_next_prz(cxt->fprzs,
                                                &cxt->ftrace_read_cnt,
 -                                              cxt->max_ftrace_cnt, id,
 -                                              type, PSTORE_TYPE_FTRACE, 0);
 +                                              cxt->max_ftrace_cnt,
 +                                              &record->id,
 +                                              &record->type,
 +                                              PSTORE_TYPE_FTRACE, 0);
  
                                if (!prz_ok(prz_next))
                                        continue;
                                if (size)
                                        goto out;
                        }
 -                      *id = 0;
 +                      record->id = 0;
                        prz = tmp_prz;
                }
        }
        size = persistent_ram_old_size(prz) - header_length;
  
        /* ECC correction notice */
 -      *ecc_notice_size = persistent_ram_ecc_string(prz, NULL, 0);
 +      record->ecc_notice_size = persistent_ram_ecc_string(prz, NULL, 0);
  
 -      *buf = kmalloc(size + *ecc_notice_size + 1, GFP_KERNEL);
 -      if (*buf == NULL) {
 +      record->buf = kmalloc(size + record->ecc_notice_size + 1, GFP_KERNEL);
 +      if (record->buf == NULL) {
                size = -ENOMEM;
                goto out;
        }
  
 -      memcpy(*buf, (char *)persistent_ram_old(prz) + header_length, size);
 +      memcpy(record->buf, (char *)persistent_ram_old(prz) + header_length,
 +             size);
  
 -      persistent_ram_ecc_string(prz, *buf + size, *ecc_notice_size + 1);
 +      persistent_ram_ecc_string(prz, record->buf + size,
 +                                record->ecc_notice_size + 1);
  
  out:
        if (free_prz) {
@@@ -378,18 -373,23 +378,18 @@@ static size_t ramoops_write_kmsg_hdr(st
        return len;
  }
  
 -static int notrace ramoops_pstore_write_buf(enum pstore_type_id type,
 -                                          enum kmsg_dump_reason reason,
 -                                          u64 *id, unsigned int part,
 -                                          const char *buf,
 -                                          bool compressed, size_t size,
 -                                          struct pstore_info *psi)
 +static int notrace ramoops_pstore_write(struct pstore_record *record)
  {
 -      struct ramoops_context *cxt = psi->data;
 +      struct ramoops_context *cxt = record->psi->data;
        struct persistent_ram_zone *prz;
 -      size_t hlen;
 +      size_t size, hlen;
  
 -      if (type == PSTORE_TYPE_CONSOLE) {
 +      if (record->type == PSTORE_TYPE_CONSOLE) {
                if (!cxt->cprz)
                        return -ENOMEM;
 -              persistent_ram_write(cxt->cprz, buf, size);
 +              persistent_ram_write(cxt->cprz, record->buf, record->size);
                return 0;
 -      } else if (type == PSTORE_TYPE_FTRACE) {
 +      } else if (record->type == PSTORE_TYPE_FTRACE) {
                int zonenum;
  
                if (!cxt->fprzs)
                else
                        zonenum = 0;
  
 -              persistent_ram_write(cxt->fprzs[zonenum], buf, size);
 +              persistent_ram_write(cxt->fprzs[zonenum], record->buf,
 +                                   record->size);
                return 0;
 -      } else if (type == PSTORE_TYPE_PMSG) {
 +      } else if (record->type == PSTORE_TYPE_PMSG) {
                pr_warn_ratelimited("PMSG shouldn't call %s\n", __func__);
                return -EINVAL;
        }
  
 -      if (type != PSTORE_TYPE_DMESG)
 +      if (record->type != PSTORE_TYPE_DMESG)
                return -EINVAL;
  
 -      /* Out of the various dmesg dump types, ramoops is currently designed
 +      /*
 +       * Out of the various dmesg dump types, ramoops is currently designed
         * to only store crash logs, rather than storing general kernel logs.
         */
 -      if (reason != KMSG_DUMP_OOPS &&
 -          reason != KMSG_DUMP_PANIC)
 +      if (record->reason != KMSG_DUMP_OOPS &&
 +          record->reason != KMSG_DUMP_PANIC)
                return -EINVAL;
  
        /* Skip Oopes when configured to do so. */
 -      if (reason == KMSG_DUMP_OOPS && !cxt->dump_oops)
 +      if (record->reason == KMSG_DUMP_OOPS && !cxt->dump_oops)
                return -EINVAL;
  
 -      /* Explicitly only take the first part of any new crash.
 +      /*
 +       * Explicitly only take the first part of any new crash.
         * If our buffer is larger than kmsg_bytes, this can never happen,
         * and if our buffer is smaller than kmsg_bytes, we don't want the
         * report split across multiple records.
         */
 -      if (part != 1)
 +      if (record->part != 1)
                return -ENOSPC;
  
        if (!cxt->dprzs)
  
        prz = cxt->dprzs[cxt->dump_write_cnt];
  
 -      hlen = ramoops_write_kmsg_hdr(prz, compressed);
 +      /* Build header and append record contents. */
 +      hlen = ramoops_write_kmsg_hdr(prz, record->compressed);
 +      size = record->size;
        if (size + hlen > prz->buffer_size)
                size = prz->buffer_size - hlen;
 -      persistent_ram_write(prz, buf, size);
 +      persistent_ram_write(prz, record->buf, size);
  
        cxt->dump_write_cnt = (cxt->dump_write_cnt + 1) % cxt->max_dump_cnt;
  
        return 0;
  }
  
 -static int notrace ramoops_pstore_write_buf_user(enum pstore_type_id type,
 -                                               enum kmsg_dump_reason reason,
 -                                               u64 *id, unsigned int part,
 -                                               const char __user *buf,
 -                                               bool compressed, size_t size,
 -                                               struct pstore_info *psi)
 +static int notrace ramoops_pstore_write_user(struct pstore_record *record,
 +                                           const char __user *buf)
  {
 -      if (type == PSTORE_TYPE_PMSG) {
 -              struct ramoops_context *cxt = psi->data;
 +      if (record->type == PSTORE_TYPE_PMSG) {
 +              struct ramoops_context *cxt = record->psi->data;
  
                if (!cxt->mprz)
                        return -ENOMEM;
 -              return persistent_ram_write_user(cxt->mprz, buf, size);
 +              return persistent_ram_write_user(cxt->mprz, buf, record->size);
        }
  
        return -EINVAL;
  }
  
 -static int ramoops_pstore_erase(enum pstore_type_id type, u64 id, int count,
 -                              struct timespec time, struct pstore_info *psi)
 +static int ramoops_pstore_erase(struct pstore_record *record)
  {
 -      struct ramoops_context *cxt = psi->data;
 +      struct ramoops_context *cxt = record->psi->data;
        struct persistent_ram_zone *prz;
  
 -      switch (type) {
 +      switch (record->type) {
        case PSTORE_TYPE_DMESG:
 -              if (id >= cxt->max_dump_cnt)
 +              if (record->id >= cxt->max_dump_cnt)
                        return -EINVAL;
 -              prz = cxt->dprzs[id];
 +              prz = cxt->dprzs[record->id];
                break;
        case PSTORE_TYPE_CONSOLE:
                prz = cxt->cprz;
                break;
        case PSTORE_TYPE_FTRACE:
 -              if (id >= cxt->max_ftrace_cnt)
 +              if (record->id >= cxt->max_ftrace_cnt)
                        return -EINVAL;
 -              prz = cxt->fprzs[id];
 +              prz = cxt->fprzs[record->id];
                break;
        case PSTORE_TYPE_PMSG:
                prz = cxt->mprz;
@@@ -503,8 -503,8 +503,8 @@@ static struct ramoops_context oops_cxt 
                .name   = "ramoops",
                .open   = ramoops_pstore_open,
                .read   = ramoops_pstore_read,
 -              .write_buf      = ramoops_pstore_write_buf,
 -              .write_buf_user = ramoops_pstore_write_buf_user,
 +              .write  = ramoops_pstore_write,
 +              .write_user     = ramoops_pstore_write_user,
                .erase  = ramoops_pstore_erase,
        },
  };
diff --combined sound/pci/cmipci.c
index 227c9d3802b80b2f74281c4ad6d277a0259aef50,430f064c64da654c00b4bdcd49ec83101117e6c5..745a0a3743b479cd9e8bd846fbec7e53f1b9eb53
@@@ -68,14 -68,14 +68,14 @@@ module_param_array(id, charp, NULL, 044
  MODULE_PARM_DESC(id, "ID string for C-Media PCI soundcard.");
  module_param_array(enable, bool, NULL, 0444);
  MODULE_PARM_DESC(enable, "Enable C-Media PCI soundcard.");
- module_param_array(mpu_port, long, NULL, 0444);
+ module_param_hw_array(mpu_port, long, ioport, NULL, 0444);
  MODULE_PARM_DESC(mpu_port, "MPU-401 port.");
- module_param_array(fm_port, long, NULL, 0444);
+ module_param_hw_array(fm_port, long, ioport, NULL, 0444);
  MODULE_PARM_DESC(fm_port, "FM port.");
  module_param_array(soft_ac3, bool, NULL, 0444);
  MODULE_PARM_DESC(soft_ac3, "Software-conversion of raw SPDIF packets (model 033 only).");
  #ifdef SUPPORT_JOYSTICK
- module_param_array(joystick_port, int, NULL, 0444);
+ module_param_hw_array(joystick_port, int, ioport, NULL, 0444);
  MODULE_PARM_DESC(joystick_port, "Joystick port address.");
  #endif
  
@@@ -1045,7 -1045,7 +1045,7 @@@ static int snd_cmipci_spdif_default_put
        return change;
  }
  
 -static struct snd_kcontrol_new snd_cmipci_spdif_default =
 +static const struct snd_kcontrol_new snd_cmipci_spdif_default =
  {
        .iface =        SNDRV_CTL_ELEM_IFACE_PCM,
        .name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
@@@ -1072,7 -1072,7 +1072,7 @@@ static int snd_cmipci_spdif_mask_get(st
        return 0;
  }
  
 -static struct snd_kcontrol_new snd_cmipci_spdif_mask =
 +static const struct snd_kcontrol_new snd_cmipci_spdif_mask =
  {
        .access =       SNDRV_CTL_ELEM_ACCESS_READ,
        .iface =        SNDRV_CTL_ELEM_IFACE_PCM,
@@@ -1119,7 -1119,7 +1119,7 @@@ static int snd_cmipci_spdif_stream_put(
        return change;
  }
  
 -static struct snd_kcontrol_new snd_cmipci_spdif_stream =
 +static const struct snd_kcontrol_new snd_cmipci_spdif_stream =
  {
        .access =       SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
        .iface =        SNDRV_CTL_ELEM_IFACE_PCM,
diff --combined sound/pci/ens1370.c
index 5d10349d11ce5118d237dd451d71eacdee2c98e4,90376739c5e158de315f6531e6b442a33cb3965f..09a63ef41ef2ec56eca7c679fde580d968e906d7
@@@ -106,7 -106,7 +106,7 @@@ module_param_array(enable, bool, NULL, 
  MODULE_PARM_DESC(enable, "Enable Ensoniq AudioPCI soundcard.");
  #ifdef SUPPORT_JOYSTICK
  #ifdef CHIP1371
- module_param_array(joystick_port, int, NULL, 0444);
+ module_param_hw_array(joystick_port, int, ioport, NULL, 0444);
  MODULE_PARM_DESC(joystick_port, "Joystick port address.");
  #else
  module_param_array(joystick, bool, NULL, 0444);
@@@ -1530,7 -1530,7 +1530,7 @@@ static int snd_es1373_rear_put(struct s
        return change;
  }
  
 -static struct snd_kcontrol_new snd_ens1373_rear =
 +static const struct snd_kcontrol_new snd_ens1373_rear =
  {
        .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
        .name =         "AC97 2ch->4ch Copy Switch",
@@@ -1575,7 -1575,7 +1575,7 @@@ static int snd_es1373_line_put(struct s
        return changed;
  }
  
 -static struct snd_kcontrol_new snd_ens1373_line =
 +static const struct snd_kcontrol_new snd_ens1373_line =
  {
        .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
        .name =         "Line In->Rear Out Switch",
diff --combined sound/pci/via82xx.c
index d078e86414c2798a1580e45d8b7e5856e34948c7,12783402117586f62000c6d0003701ec1f21219f..b6c84d15b10bbdcbb26ce71dbdd2d895f7a961a0
@@@ -92,7 -92,7 +92,7 @@@ module_param(index, int, 0444)
  MODULE_PARM_DESC(index, "Index value for VIA 82xx bridge.");
  module_param(id, charp, 0444);
  MODULE_PARM_DESC(id, "ID string for VIA 82xx bridge.");
- module_param(mpu_port, long, 0444);
+ module_param_hw(mpu_port, long, ioport, 0444);
  MODULE_PARM_DESC(mpu_port, "MPU-401 port. (VT82C686x only)");
  #ifdef SUPPORT_JOYSTICK
  module_param(joystick, bool, 0444);
@@@ -1683,7 -1683,7 +1683,7 @@@ static int snd_via8233_dxs3_spdif_put(s
        return 0;
  }
  
 -static struct snd_kcontrol_new snd_via8233_dxs3_spdif_control = {
 +static const struct snd_kcontrol_new snd_via8233_dxs3_spdif_control = {
        .name = SNDRV_CTL_NAME_IEC958("Output ",NONE,SWITCH),
        .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
        .info = snd_via8233_dxs3_spdif_info,
@@@ -1772,7 -1772,7 +1772,7 @@@ static int snd_via8233_pcmdxs_volume_pu
  
  static const DECLARE_TLV_DB_SCALE(db_scale_dxs, -4650, 150, 1);
  
 -static struct snd_kcontrol_new snd_via8233_pcmdxs_volume_control = {
 +static const struct snd_kcontrol_new snd_via8233_pcmdxs_volume_control = {
        .name = "PCM Playback Volume",
        .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
        .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
        .tlv = { .p = db_scale_dxs }
  };
  
 -static struct snd_kcontrol_new snd_via8233_dxs_volume_control = {
 +static const struct snd_kcontrol_new snd_via8233_dxs_volume_control = {
        .iface = SNDRV_CTL_ELEM_IFACE_PCM,
        .device = 0,
        /* .subdevice set later */