]> Git Repo - J-linux.git/commitdiff
Merge tag 'tty-6.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty
authorLinus Torvalds <[email protected]>
Wed, 22 May 2024 18:53:02 +0000 (11:53 -0700)
committerLinus Torvalds <[email protected]>
Wed, 22 May 2024 18:53:02 +0000 (11:53 -0700)
Pull tty / serial updates from Greg KH:
 "Here is the big set of tty/serial driver changes for 6.10-rc1.
  Included in here are:

   - Usual good set of api cleanups and evolution by Jiri Slaby to make
     the serial interfaces move out of the 1990's by using kfifos
     instead of hand-rolling their own logic.

   - 8250_exar driver updates

   - max3100 driver updates

   - sc16is7xx driver updates

   - exar driver updates

   - sh-sci driver updates

   - tty ldisc api addition to help refuse bindings

   - other smaller serial driver updates

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

* tag 'tty-6.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: (113 commits)
  serial: Clear UPF_DEAD before calling tty_port_register_device_attr_serdev()
  serial: imx: Raise TX trigger level to 8
  serial: 8250_pnp: Simplify "line" related code
  serial: sh-sci: simplify locking when re-issuing RXDMA fails
  serial: sh-sci: let timeout timer only run when DMA is scheduled
  serial: sh-sci: describe locking requirements for invalidating RXDMA
  serial: sh-sci: protect invalidating RXDMA on shutdown
  tty: add the option to have a tty reject a new ldisc
  serial: core: Call device_set_awake_path() for console port
  dt-bindings: serial: brcm,bcm2835-aux-uart: convert to dtschema
  tty: serial: uartps: Add support for uartps controller reset
  arm64: zynqmp: Add resets property for UART nodes
  dt-bindings: serial: cdns,uart: Add optional reset property
  serial: 8250_pnp: Switch to DEFINE_SIMPLE_DEV_PM_OPS()
  serial: 8250_exar: Keep the includes sorted
  serial: 8250_exar: Make type of bit the same in exar_ee_*_bit()
  serial: 8250_exar: Use BIT() in exar_ee_read()
  serial: 8250_exar: Switch to use dev_err_probe()
  serial: 8250_exar: Return directly from switch-cases
  serial: 8250_exar: Decrease indentation level
  ...

1  2 
Documentation/admin-guide/kernel-parameters.txt
arch/arm64/boot/dts/xilinx/zynqmp.dtsi
drivers/tty/serial/8250/8250_core.c
include/linux/kfifo.h
include/linux/printk.h
kernel/printk/printk.c
lib/kfifo.c

index ef25e06ec08cc88763cd92fb1ce3a898c78b5591,23a41000d173476cbd30cf27211c92fc61ebb594..500cfa7762257cafc3bef374935759e1c7d9984c
        arcrimi=        [HW,NET] ARCnet - "RIM I" (entirely mem-mapped) cards
                        Format: <io>,<irq>,<nodeID>
  
 +      arm64.no32bit_el0 [ARM64] Unconditionally disable the execution of
 +                      32 bit applications.
 +
        arm64.nobti     [ARM64] Unconditionally disable Branch Target
                        Identification support
  
                        Documentation/networking/netconsole.rst for an
                        alternative.
  
+               <DEVNAME>:<n>.<n>[,options]
+                       Use the specified serial port on the serial core bus.
+                       The addressing uses DEVNAME of the physical serial port
+                       device, followed by the serial core controller instance,
+                       and the serial port instance. The options are the same
+                       as documented for the ttyS addressing above.
+                       The mapping of the serial ports to the tty instances
+                       can be viewed with:
+                       $ ls -d /sys/bus/serial-base/devices/*:*.*/tty/*
+                       /sys/bus/serial-base/devices/00:04:0.0/tty/ttyS0
+                       In the above example, the console can be addressed with
+                       console=00:04:0.0. Note that a console addressed this
+                       way will only get added when the related device driver
+                       is ready. The use of an earlycon parameter in addition to
+                       the console may be desired for console output early on.
                uart[8250],io,<addr>[,options]
                uart[8250],mmio,<addr>[,options]
                uart[8250],mmio16,<addr>[,options]
                        Format: 0 | 1
                        Default set by CONFIG_INIT_ON_FREE_DEFAULT_ON.
  
 +      init_mlocked_on_free=   [MM] Fill freed userspace memory with zeroes if
 +                              it was mlock'ed and not explicitly munlock'ed
 +                              afterwards.
 +                              Format: 0 | 1
 +                              Default set by CONFIG_INIT_MLOCKED_ON_FREE_DEFAULT_ON
 +
        init_pkru=      [X86] Specify the default memory protection keys rights
                        register contents for all processes.  0x55555554 by
                        default (disallow access to all but pkey 0).  Can
                        no_x2apic_optout
                                BIOS x2APIC opt-out request will be ignored
                        nopost  disable Interrupt Posting
 +                      posted_msi
 +                              enable MSIs delivered as posted interrupts
  
        iomem=          Disable strict checking of access to MMIO memory
                strict  regions from userspace.
                        arch-independent options, each of which is an
                        aggregation of existing arch-specific options.
  
 +                      Note, "mitigations" is supported if and only if the
 +                      kernel was built with CPU_MITIGATIONS=y.
 +
                        off
                                Disable all optional CPU mitigations.  This
                                improves system performance, but it may also
                        Format: [state][,regs][,debounce][,die]
  
        nmi_watchdog=   [KNL,BUGS=X86] Debugging features for SMP kernels
 -                      Format: [panic,][nopanic,][num]
 +                      Format: [panic,][nopanic,][rNNN,][num]
                        Valid num: 0 or 1
                        0 - turn hardlockup detector in nmi_watchdog off
                        1 - turn hardlockup detector in nmi_watchdog on
 +                      rNNN - configure the watchdog with raw perf event 0xNNN
 +
                        When panic is specified, panic when an NMI watchdog
                        timeout occurs (or 'nopanic' to not panic on an NMI
                        watchdog, if CONFIG_BOOTPARAM_HARDLOCKUP_PANIC is set)
  
        page_alloc.shuffle=
                        [KNL] Boolean flag to control whether the page allocator
 -                      should randomize its free lists. The randomization may
 -                      be automatically enabled if the kernel detects it is
 -                      running on a platform with a direct-mapped memory-side
 -                      cache, and this parameter can be used to
 -                      override/disable that behavior. The state of the flag
 -                      can be read from sysfs at:
 +                      should randomize its free lists. This parameter can be
 +                      used to enable/disable page randomization. The state of
 +                      the flag can be read from sysfs at:
                        /sys/module/page_alloc/parameters/shuffle.
 +                      This parameter is only available if CONFIG_SHUFFLE_PAGE_ALLOCATOR=y.
  
        page_owner=     [KNL,EARLY] Boot-time page_owner enabling option.
                        Storage of the information about who allocated
                norid           [S390] ignore the RID field and force use of
                                one PCI domain per PCI function
  
 -      pcie_aspm=      [PCIE] Forcibly enable or disable PCIe Active State Power
 +      pcie_aspm=      [PCIE] Forcibly enable or ignore PCIe Active State Power
                        Management.
 -              off     Disable ASPM.
 +              off     Don't touch ASPM configuration at all.  Leave any
 +                      configuration done by firmware unchanged.
                force   Enable ASPM even on devices that claim not to support it.
                        WARNING: Forcing ASPM on may cause system lockups.
  
  
        prot_virt=      [S390] enable hosting protected virtual machines
                        isolated from the hypervisor (if hardware supports
 -                      that).
 +                      that). If enabled, the default kernel base address
 +                      might be overridden even when Kernel Address Space
 +                      Layout Randomization is disabled.
                        Format: <bool>
  
        psi=            [KNL] Enable or disable pressure stall information
                        delay, memory pressure or callback list growing too
                        big.
  
 +      rcutree.rcu_normal_wake_from_gp= [KNL]
 +                      Reduces a latency of synchronize_rcu() call. This approach
 +                      maintains its own track of synchronize_rcu() callers, so it
 +                      does not interact with regular callbacks because it does not
 +                      use a call_rcu[_hurry]() path. Please note, this is for a
 +                      normal grace period.
 +
 +                      How to enable it:
 +
 +                      echo 1 > /sys/module/rcutree/parameters/rcu_normal_wake_from_gp
 +                      or pass a boot parameter "rcutree.rcu_normal_wake_from_gp=1"
 +
 +                      Default is 0.
 +
        rcuscale.gp_async= [KNL]
                        Measure performance of asynchronous
                        grace-period primitives such as call_rcu().
                        but is useful for debugging and performance tuning.
  
        sched_thermal_decay_shift=
 +                      [Deprecated]
                        [KNL, SMP] Set a decay shift for scheduler thermal
                        pressure signal. Thermal pressure signal follows the
                        default decay period of other scheduler pelt
                        - "tpm"
                        - "tee"
                        - "caam"
 +                      - "dcp"
                        If not specified then it defaults to iterating through
                        the trust source list starting with TPM and assigns the
                        first trust source as a backend which is initialized
                        If not specified, "default" is used. In this case,
                        the RNG's choice is left to each individual trust source.
  
 +      trusted.dcp_use_otp_key
 +                      This is intended to be used in combination with
 +                      trusted.source=dcp and will select the DCP OTP key
 +                      instead of the DCP UNIQUE key blob encryption.
 +
 +      trusted.dcp_skip_zk_test
 +                      This is intended to be used in combination with
 +                      trusted.source=dcp and will disable the check if the
 +                      blob key is all zeros. This is helpful for situations where
 +                      having this key zero'ed is acceptable. E.g. in testing
 +                      scenarios.
 +
        tsc=            Disable clocksource stability checks for TSC.
                        Format: <string>
                        [x86] reliable: mark tsc clocksource as reliable, this
                        This can be changed after boot by writing to the
                        matching /sys/module/workqueue/parameters file. All
                        workqueues with the "default" affinity scope will be
 -                      updated accordignly.
 +                      updated accordingly.
  
        workqueue.debug_force_rr_cpu
                        Workqueue used to implicitly guarantee that work
                                memory, and other data can't be written using
                                xmon commands.
                        off     xmon is disabled.
 -
index 34d0e0be3fe61de5d45628bdb50660cde2df4538,935504424ec6bcbc79b20a3b4fdde809bf338f31..d99830c9b85f9df1097ba1de819c0565a67454bd
        };
  
        pmu {
 -              compatible = "arm,armv8-pmuv3";
 +              compatible = "arm,cortex-a53-pmu";
                interrupt-parent = <&gic>;
                interrupts = <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>,
                             <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>,
                        reg = <0x0 0xff000000 0x0 0x1000>;
                        clock-names = "uart_clk", "pclk";
                        power-domains = <&zynqmp_firmware PD_UART_0>;
+                       resets = <&zynqmp_reset ZYNQMP_RESET_UART0>;
                };
  
                uart1: serial@ff010000 {
                        reg = <0x0 0xff010000 0x0 0x1000>;
                        clock-names = "uart_clk", "pclk";
                        power-domains = <&zynqmp_firmware PD_UART_1>;
+                       resets = <&zynqmp_reset ZYNQMP_RESET_UART1>;
                };
  
                usb0: usb@ff9d0000 {
index 2504e0455875817438e177582f2eb987d24f1e5d,43824a174a51560c1d1ae95cb363919e58d4c09c..ff15022369e45917278b3807e73f62c679bf0c9c
@@@ -15,6 -15,7 +15,7 @@@
   */
  
  #include <linux/acpi.h>
+ #include <linux/cleanup.h>
  #include <linux/module.h>
  #include <linux/moduleparam.h>
  #include <linux/ioport.h>
@@@ -41,6 -42,8 +42,8 @@@
  
  #include <asm/irq.h>
  
+ #include "../serial_base.h"   /* For serial_base_add_isa_preferred_console() */
  #include "8250.h"
  
  /*
@@@ -280,7 -283,8 +283,8 @@@ static void serial8250_backup_timeout(s
         */
        lsr = serial_lsr_in(up);
        if ((iir & UART_IIR_NO_INT) && (up->ier & UART_IER_THRI) &&
-           (!uart_circ_empty(&up->port.state->xmit) || up->port.x_char) &&
+           (!kfifo_is_empty(&up->port.state->port.xmit_fifo) ||
+            up->port.x_char) &&
            (lsr & UART_LSR_THRE)) {
                iir &= ~(UART_IIR_ID | UART_IIR_NO_INT);
                iir |= UART_IIR_THRI;
@@@ -508,6 -512,10 +512,6 @@@ static struct uart_8250_port *serial825
  
        up->ops = &univ8250_driver_ops;
  
 -      if (IS_ENABLED(CONFIG_ALPHA_JENSEN) ||
 -          (IS_ENABLED(CONFIG_ALPHA_GENERIC) && alpha_jensen()))
 -              up->port.set_mctrl = alpha_jensen_set_mctrl;
 -
        serial8250_set_defaults(up);
  
        return up;
@@@ -559,6 -567,8 +563,8 @@@ static void __init serial8250_isa_init_
                port->irqflags |= irqflag;
                if (serial8250_isa_config != NULL)
                        serial8250_isa_config(i, &up->port, &up->capabilities);
+               serial_base_add_isa_preferred_console(serial8250_reg.dev_name, i);
        }
  }
  
diff --combined include/linux/kfifo.h
index 6b28d642f3325e0e4efb0699b17afa7f8bba603a,d613748de7ffb5cee1a9b99373cf18e186c20701..564868bdce898b92da33b6b7b8e07128ccb0f972
   * to lock the reader.
   */
  
 -#include <linux/kernel.h>
 +#include <linux/array_size.h>
+ #include <linux/dma-mapping.h>
  #include <linux/spinlock.h>
  #include <linux/stddef.h>
 -#include <linux/scatterlist.h>
 +#include <linux/types.h>
 +
 +#include <asm/barrier.h>
 +#include <asm/errno.h>
 +
 +struct scatterlist;
  
  struct __kfifo {
        unsigned int    in;
@@@ -309,19 -305,25 +310,25 @@@ __kfifo_uint_must_check_helper( 
  )
  
  /**
-  * kfifo_skip - skip output data
+  * kfifo_skip_count - skip output data
   * @fifo: address of the fifo to be used
+  * @count: count of data to skip
   */
- #define       kfifo_skip(fifo) \
- (void)({ \
+ #define       kfifo_skip_count(fifo, count) do { \
        typeof((fifo) + 1) __tmp = (fifo); \
        const size_t __recsize = sizeof(*__tmp->rectype); \
        struct __kfifo *__kfifo = &__tmp->kfifo; \
        if (__recsize) \
                __kfifo_skip_r(__kfifo, __recsize); \
        else \
-               __kfifo->out++; \
- })
+               __kfifo->out += (count); \
+ } while(0)
+ /**
+  * kfifo_skip - skip output data
+  * @fifo: address of the fifo to be used
+  */
+ #define       kfifo_skip(fifo)        kfifo_skip_count(fifo, 1)
  
  /**
   * kfifo_peek_len - gets the size of the next fifo record
@@@ -583,7 -585,7 +590,7 @@@ __kfifo_uint_must_check_helper( 
   * @buf: pointer to the storage buffer
   * @n: max. number of elements to get
   *
-  * This macro get some data from the fifo and return the numbers of elements
+  * This macro gets some data from the fifo and returns the numbers of elements
   * copied.
   *
   * Note that with only one concurrent reader and one concurrent
@@@ -610,7 -612,7 +617,7 @@@ __kfifo_uint_must_check_helper( 
   * @n: max. number of elements to get
   * @lock: pointer to the spinlock to use for locking
   *
-  * This macro get the data from the fifo and return the numbers of elements
+  * This macro gets the data from the fifo and returns the numbers of elements
   * copied.
   */
  #define       kfifo_out_spinlocked(fifo, buf, n, lock) \
@@@ -708,11 -710,12 +715,12 @@@ __kfifo_int_must_check_helper( 
  )
  
  /**
-  * kfifo_dma_in_prepare - setup a scatterlist for DMA input
+  * kfifo_dma_in_prepare_mapped - setup a scatterlist for DMA input
   * @fifo: address of the fifo to be used
   * @sgl: pointer to the scatterlist array
   * @nents: number of entries in the scatterlist array
   * @len: number of elements to transfer
+  * @dma: mapped dma address to fill into @sgl
   *
   * This macro fills a scatterlist for DMA input.
   * It returns the number entries in the scatterlist array.
   * Note that with only one concurrent reader and one concurrent
   * writer, you don't need extra locking to use these macros.
   */
- #define       kfifo_dma_in_prepare(fifo, sgl, nents, len) \
+ #define       kfifo_dma_in_prepare_mapped(fifo, sgl, nents, len, dma) \
  ({ \
        typeof((fifo) + 1) __tmp = (fifo); \
        struct scatterlist *__sgl = (sgl); \
        const size_t __recsize = sizeof(*__tmp->rectype); \
        struct __kfifo *__kfifo = &__tmp->kfifo; \
        (__recsize) ? \
-       __kfifo_dma_in_prepare_r(__kfifo, __sgl, __nents, __len, __recsize) : \
-       __kfifo_dma_in_prepare(__kfifo, __sgl, __nents, __len); \
+       __kfifo_dma_in_prepare_r(__kfifo, __sgl, __nents, __len, __recsize, \
+                                dma) : \
+       __kfifo_dma_in_prepare(__kfifo, __sgl, __nents, __len, dma); \
  })
  
+ #define kfifo_dma_in_prepare(fifo, sgl, nents, len) \
+       kfifo_dma_in_prepare_mapped(fifo, sgl, nents, len, DMA_MAPPING_ERROR)
  /**
   * kfifo_dma_in_finish - finish a DMA IN operation
   * @fifo: address of the fifo to be used
   * @len: number of bytes to received
   *
-  * This macro finish a DMA IN operation. The in counter will be updated by
+  * This macro finishes a DMA IN operation. The in counter will be updated by
   * the len parameter. No error checking will be done.
   *
   * Note that with only one concurrent reader and one concurrent
  })
  
  /**
-  * kfifo_dma_out_prepare - setup a scatterlist for DMA output
+  * kfifo_dma_out_prepare_mapped - setup a scatterlist for DMA output
   * @fifo: address of the fifo to be used
   * @sgl: pointer to the scatterlist array
   * @nents: number of entries in the scatterlist array
   * @len: number of elements to transfer
+  * @dma: mapped dma address to fill into @sgl
   *
   * This macro fills a scatterlist for DMA output which at most @len bytes
   * to transfer.
   * Note that with only one concurrent reader and one concurrent
   * writer, you don't need extra locking to use these macros.
   */
- #define       kfifo_dma_out_prepare(fifo, sgl, nents, len) \
+ #define       kfifo_dma_out_prepare_mapped(fifo, sgl, nents, len, dma) \
  ({ \
        typeof((fifo) + 1) __tmp = (fifo);  \
        struct scatterlist *__sgl = (sgl); \
        const size_t __recsize = sizeof(*__tmp->rectype); \
        struct __kfifo *__kfifo = &__tmp->kfifo; \
        (__recsize) ? \
-       __kfifo_dma_out_prepare_r(__kfifo, __sgl, __nents, __len, __recsize) : \
-       __kfifo_dma_out_prepare(__kfifo, __sgl, __nents, __len); \
+       __kfifo_dma_out_prepare_r(__kfifo, __sgl, __nents, __len, __recsize, \
+                                 dma) : \
+       __kfifo_dma_out_prepare(__kfifo, __sgl, __nents, __len, dma); \
  })
  
+ #define       kfifo_dma_out_prepare(fifo, sgl, nents, len) \
+       kfifo_dma_out_prepare_mapped(fifo, sgl, nents, len, DMA_MAPPING_ERROR)
  /**
   * kfifo_dma_out_finish - finish a DMA OUT operation
   * @fifo: address of the fifo to be used
   * @len: number of bytes transferred
   *
-  * This macro finish a DMA OUT operation. The out counter will be updated by
+  * This macro finishes a DMA OUT operation. The out counter will be updated by
   * the len parameter. No error checking will be done.
   *
   * Note that with only one concurrent reader and one concurrent
   * writer, you don't need extra locking to use these macros.
   */
- #define kfifo_dma_out_finish(fifo, len) \
- (void)({ \
-       typeof((fifo) + 1) __tmp = (fifo); \
-       unsigned int __len = (len); \
-       const size_t __recsize = sizeof(*__tmp->rectype); \
-       struct __kfifo *__kfifo = &__tmp->kfifo; \
-       if (__recsize) \
-               __kfifo_dma_out_finish_r(__kfifo, __recsize); \
-       else \
-               __kfifo->out += __len / sizeof(*__tmp->type); \
- })
+ #define kfifo_dma_out_finish(fifo, len) do { \
+       typeof((fifo) + 1) ___tmp = (fifo); \
+       kfifo_skip_count(___tmp, (len) / sizeof(*___tmp->type)); \
+ } while (0)
  
  /**
   * kfifo_out_peek - gets some data from the fifo
   * @buf: pointer to the storage buffer
   * @n: max. number of elements to get
   *
-  * This macro get the data from the fifo and return the numbers of elements
+  * This macro gets the data from the fifo and returns the numbers of elements
   * copied. The data is not removed from the fifo.
   *
   * Note that with only one concurrent reader and one concurrent
@@@ -833,6 -838,63 +843,63 @@@ __kfifo_uint_must_check_helper( 
  }) \
  )
  
+ /**
+  * kfifo_out_linear - gets a tail of/offset to available data
+  * @fifo: address of the fifo to be used
+  * @tail: pointer to an unsigned int to store the value of tail
+  * @n: max. number of elements to point at
+  *
+  * This macro obtains the offset (tail) to the available data in the fifo
+  * buffer and returns the
+  * numbers of elements available. It returns the available count till the end
+  * of data or till the end of the buffer. So that it can be used for linear
+  * data processing (like memcpy() of (@fifo->data + @tail) with count
+  * returned).
+  *
+  * Note that with only one concurrent reader and one concurrent
+  * writer, you don't need extra locking to use these macro.
+  */
+ #define kfifo_out_linear(fifo, tail, n) \
+ __kfifo_uint_must_check_helper( \
+ ({ \
+       typeof((fifo) + 1) __tmp = (fifo); \
+       unsigned int *__tail = (tail); \
+       unsigned long __n = (n); \
+       const size_t __recsize = sizeof(*__tmp->rectype); \
+       struct __kfifo *__kfifo = &__tmp->kfifo; \
+       (__recsize) ? \
+       __kfifo_out_linear_r(__kfifo, __tail, __n, __recsize) : \
+       __kfifo_out_linear(__kfifo, __tail, __n); \
+ }) \
+ )
+ /**
+  * kfifo_out_linear_ptr - gets a pointer to the available data
+  * @fifo: address of the fifo to be used
+  * @ptr: pointer to data to store the pointer to tail
+  * @n: max. number of elements to point at
+  *
+  * Similarly to kfifo_out_linear(), this macro obtains the pointer to the
+  * available data in the fifo buffer and returns the numbers of elements
+  * available. It returns the available count till the end of available data or
+  * till the end of the buffer. So that it can be used for linear data
+  * processing (like memcpy() of @ptr with count returned).
+  *
+  * Note that with only one concurrent reader and one concurrent
+  * writer, you don't need extra locking to use these macro.
+  */
+ #define kfifo_out_linear_ptr(fifo, ptr, n) \
+ __kfifo_uint_must_check_helper( \
+ ({ \
+       typeof((fifo) + 1) ___tmp = (fifo); \
+       unsigned int ___tail; \
+       unsigned int ___n = kfifo_out_linear(___tmp, &___tail, (n)); \
+       *(ptr) = ___tmp->kfifo.data + ___tail * kfifo_esize(___tmp); \
+       ___n; \
+ }) \
+ )
  extern int __kfifo_alloc(struct __kfifo *fifo, unsigned int size,
        size_t esize, gfp_t gfp_mask);
  
@@@ -854,14 -916,17 +921,17 @@@ extern int __kfifo_to_user(struct __kfi
        void __user *to, unsigned long len, unsigned int *copied);
  
  extern unsigned int __kfifo_dma_in_prepare(struct __kfifo *fifo,
-       struct scatterlist *sgl, int nents, unsigned int len);
+       struct scatterlist *sgl, int nents, unsigned int len, dma_addr_t dma);
  
  extern unsigned int __kfifo_dma_out_prepare(struct __kfifo *fifo,
-       struct scatterlist *sgl, int nents, unsigned int len);
+       struct scatterlist *sgl, int nents, unsigned int len, dma_addr_t dma);
  
  extern unsigned int __kfifo_out_peek(struct __kfifo *fifo,
        void *buf, unsigned int len);
  
+ extern unsigned int __kfifo_out_linear(struct __kfifo *fifo,
+       unsigned int *tail, unsigned int n);
  extern unsigned int __kfifo_in_r(struct __kfifo *fifo,
        const void *buf, unsigned int len, size_t recsize);
  
@@@ -876,15 -941,15 +946,15 @@@ extern int __kfifo_to_user_r(struct __k
        unsigned long len, unsigned int *copied, size_t recsize);
  
  extern unsigned int __kfifo_dma_in_prepare_r(struct __kfifo *fifo,
-       struct scatterlist *sgl, int nents, unsigned int len, size_t recsize);
+       struct scatterlist *sgl, int nents, unsigned int len, size_t recsize,
+       dma_addr_t dma);
  
  extern void __kfifo_dma_in_finish_r(struct __kfifo *fifo,
        unsigned int len, size_t recsize);
  
  extern unsigned int __kfifo_dma_out_prepare_r(struct __kfifo *fifo,
-       struct scatterlist *sgl, int nents, unsigned int len, size_t recsize);
- extern void __kfifo_dma_out_finish_r(struct __kfifo *fifo, size_t recsize);
+       struct scatterlist *sgl, int nents, unsigned int len, size_t recsize,
+       dma_addr_t dma);
  
  extern unsigned int __kfifo_len_r(struct __kfifo *fifo, size_t recsize);
  
@@@ -893,6 -958,9 +963,9 @@@ extern void __kfifo_skip_r(struct __kfi
  extern unsigned int __kfifo_out_peek_r(struct __kfifo *fifo,
        void *buf, unsigned int len, size_t recsize);
  
+ extern unsigned int __kfifo_out_linear_r(struct __kfifo *fifo,
+       unsigned int *tail, unsigned int n, size_t recsize);
  extern unsigned int __kfifo_max_r(unsigned int len, size_t recsize);
  
  #endif
diff --combined include/linux/printk.h
index dbbd202b1cb314d4bfae029bd44db6c4154b5068,1c5936ab991fe70f5d0b407c83d724baf2bdf040..40afab23881a0a63fa68e710cb6c8a0389171146
@@@ -60,6 -60,9 +60,9 @@@ static inline const char *printk_skip_h
  #define CONSOLE_LOGLEVEL_DEFAULT CONFIG_CONSOLE_LOGLEVEL_DEFAULT
  #define CONSOLE_LOGLEVEL_QUIET         CONFIG_CONSOLE_LOGLEVEL_QUIET
  
+ int add_preferred_console_match(const char *match, const char *name,
+                               const short idx);
  extern int console_printk[];
  
  #define console_loglevel (console_printk[0])
@@@ -71,7 -74,7 +74,7 @@@ extern void console_verbose(void)
  
  /* strlen("ratelimit") + 1 */
  #define DEVKMSG_STR_MAX_SIZE 10
 -extern char devkmsg_log_str[];
 +extern char devkmsg_log_str[DEVKMSG_STR_MAX_SIZE];
  struct ctl_table;
  
  extern int suppress_printk;
@@@ -126,7 -129,7 +129,7 @@@ struct va_format 
  #define no_printk(fmt, ...)                           \
  ({                                                    \
        if (0)                                          \
 -              printk(fmt, ##__VA_ARGS__);             \
 +              _printk(fmt, ##__VA_ARGS__);            \
        0;                                              \
  })
  
@@@ -192,6 -195,7 +195,7 @@@ void show_regs_print_info(const char *l
  extern asmlinkage void dump_stack_lvl(const char *log_lvl) __cold;
  extern asmlinkage void dump_stack(void) __cold;
  void printk_trigger_flush(void);
+ void console_replay_all(void);
  #else
  static inline __printf(1, 0)
  int vprintk(const char *s, va_list args)
@@@ -271,6 -275,9 +275,9 @@@ static inline void dump_stack(void
  static inline void printk_trigger_flush(void)
  {
  }
+ static inline void console_replay_all(void)
+ {
+ }
  #endif
  
  bool this_cpu_in_panic(void);
diff --combined kernel/printk/printk.c
index 3160d287d4cfad40aeb11528c98bacb4b0ff60d3,6206804d275bacfc20da441e6021cc7c92f85cff..420fd310129d4b2a05612c57c7c8b4b9605bee99
@@@ -178,9 -178,9 +178,9 @@@ static int __init control_devkmsg(char 
         * Set sysctl string accordingly:
         */
        if (devkmsg_log == DEVKMSG_LOG_MASK_ON)
 -              strcpy(devkmsg_log_str, "on");
 +              strscpy(devkmsg_log_str, "on");
        else if (devkmsg_log == DEVKMSG_LOG_MASK_OFF)
 -              strcpy(devkmsg_log_str, "off");
 +              strscpy(devkmsg_log_str, "off");
        /* else "ratelimit" which is set by default. */
  
        /*
@@@ -209,7 -209,7 +209,7 @@@ int devkmsg_sysctl_set_loglvl(struct ct
                        return -EINVAL;
  
                old = devkmsg_log;
 -              strncpy(old_str, devkmsg_log_str, DEVKMSG_STR_MAX_SIZE);
 +              strscpy(old_str, devkmsg_log_str);
        }
  
        err = proc_dostring(table, write, buffer, lenp, ppos);
  
                        /* ... and restore old setting. */
                        devkmsg_log = old;
 -                      strncpy(devkmsg_log_str, old_str, DEVKMSG_STR_MAX_SIZE);
 +                      strscpy(devkmsg_log_str, old_str);
  
                        return -EINVAL;
                }
@@@ -383,9 -383,6 +383,6 @@@ static int console_locked
  /*
   *    Array of consoles built from command line options (console=)
   */
- #define MAX_CMDLINECONSOLES 8
  static struct console_cmdline console_cmdline[MAX_CMDLINECONSOLES];
  
  static int preferred_console = -1;
@@@ -2503,25 -2500,36 +2500,36 @@@ static int __init console_setup(char *s
        if (_braille_console_setup(&str, &brl_options))
                return 1;
  
+       /* Save the console for driver subsystem use */
+       if (console_opt_save(str, brl_options))
+               return 1;
+       /* Flag register_console() to not call try_enable_default_console() */
+       console_set_on_cmdline = 1;
+       /* Don't attempt to parse a DEVNAME:0.0 style console */
+       if (strchr(str, ':'))
+               return 1;
        /*
         * Decode str into name, index, options.
         */
 -      if (str[0] >= '0' && str[0] <= '9') {
 -              strcpy(buf, "ttyS");
 -              strncpy(buf + 4, str, sizeof(buf) - 5);
 -      } else {
 -              strncpy(buf, str, sizeof(buf) - 1);
 -      }
 -      buf[sizeof(buf) - 1] = 0;
 +      if (isdigit(str[0]))
 +              scnprintf(buf, sizeof(buf), "ttyS%s", str);
 +      else
 +              strscpy(buf, str);
 +
        options = strchr(str, ',');
        if (options)
                *(options++) = 0;
 +
  #ifdef __sparc__
        if (!strcmp(str, "ttya"))
 -              strcpy(buf, "ttyS0");
 +              strscpy(buf, "ttyS0");
        if (!strcmp(str, "ttyb"))
 -              strcpy(buf, "ttyS1");
 +              strscpy(buf, "ttyS1");
  #endif
 +
        for (s = buf; *s; s++)
                if (isdigit(*s) || *s == ',')
                        break;
  }
  __setup("console=", console_setup);
  
+ /* Only called from add_preferred_console_match() */
+ int console_opt_add_preferred_console(const char *name, const short idx,
+                                     char *options, char *brl_options)
+ {
+       return __add_preferred_console(name, idx, options, brl_options, true);
+ }
  /**
   * add_preferred_console - add a device to the list of preferred consoles.
   * @name: device name
@@@ -3146,6 -3161,40 +3161,40 @@@ void console_unblank(void
                pr_flush(1000, true);
  }
  
+ /*
+  * Rewind all consoles to the oldest available record.
+  *
+  * IMPORTANT: The function is safe only when called under
+  *            console_lock(). It is not enforced because
+  *            it is used as a best effort in panic().
+  */
+ static void __console_rewind_all(void)
+ {
+       struct console *c;
+       short flags;
+       int cookie;
+       u64 seq;
+       seq = prb_first_valid_seq(prb);
+       cookie = console_srcu_read_lock();
+       for_each_console_srcu(c) {
+               flags = console_srcu_read_flags(c);
+               if (flags & CON_NBCON) {
+                       nbcon_seq_force(c, seq);
+               } else {
+                       /*
+                        * This assignment is safe only when called under
+                        * console_lock(). On panic, legacy consoles are
+                        * only best effort.
+                        */
+                       c->seq = seq;
+               }
+       }
+       console_srcu_read_unlock(cookie);
+ }
  /**
   * console_flush_on_panic - flush console content on panic
   * @mode: flush all messages in buffer or just the pending ones
@@@ -3174,30 -3223,8 +3223,8 @@@ void console_flush_on_panic(enum con_fl
         */
        console_may_schedule = 0;
  
-       if (mode == CONSOLE_REPLAY_ALL) {
-               struct console *c;
-               short flags;
-               int cookie;
-               u64 seq;
-               seq = prb_first_valid_seq(prb);
-               cookie = console_srcu_read_lock();
-               for_each_console_srcu(c) {
-                       flags = console_srcu_read_flags(c);
-                       if (flags & CON_NBCON) {
-                               nbcon_seq_force(c, seq);
-                       } else {
-                               /*
-                                * This is an unsynchronized assignment. On
-                                * panic legacy consoles are only best effort.
-                                */
-                               c->seq = seq;
-                       }
-               }
-               console_srcu_read_unlock(cookie);
-       }
+       if (mode == CONSOLE_REPLAY_ALL)
+               __console_rewind_all();
  
        console_flush_all(false, &next_seq, &handover);
  }
@@@ -3495,7 -3522,7 +3522,7 @@@ void register_console(struct console *n
         * Note that a console with tty binding will have CON_CONSDEV
         * flag set and will be first in the list.
         */
-       if (preferred_console < 0) {
+       if (preferred_console < 0 && !console_set_on_cmdline) {
                if (hlist_empty(&console_list) || !console_first()->device ||
                    console_first()->flags & CON_BOOT) {
                        try_enable_default_console(newcon);
@@@ -4286,6 -4313,23 +4313,23 @@@ void kmsg_dump_rewind(struct kmsg_dump_
  }
  EXPORT_SYMBOL_GPL(kmsg_dump_rewind);
  
+ /**
+  * console_replay_all - replay kernel log on consoles
+  *
+  * Try to obtain lock on console subsystem and replay all
+  * available records in printk buffer on the consoles.
+  * Does nothing if lock is not obtained.
+  *
+  * Context: Any context.
+  */
+ void console_replay_all(void)
+ {
+       if (console_trylock()) {
+               __console_rewind_all();
+               /* Consoles are flushed as part of console_unlock(). */
+               console_unlock();
+       }
+ }
  #endif
  
  #ifdef CONFIG_SMP
diff --combined lib/kfifo.c
index 15acdee4a8f325ad504b4ac982eb2ef2c39c68ec,75ce9225548aa6a541afdb4751f42d96cc33e3e3..a8b2eed9059924a49a3217f259a46da292b2005f
@@@ -5,13 -5,14 +5,14 @@@
   * Copyright (C) 2009/2010 Stefani Seibold <[email protected]>
   */
  
 -#include <linux/kernel.h>
+ #include <linux/dma-mapping.h>
 -#include <linux/export.h>
 -#include <linux/slab.h>
  #include <linux/err.h>
 +#include <linux/export.h>
 +#include <linux/kfifo.h>
  #include <linux/log2.h>
 +#include <linux/scatterlist.h>
 +#include <linux/slab.h>
  #include <linux/uaccess.h>
 -#include <linux/kfifo.h>
  
  /*
   * internal helper to calculate the unused elements in a fifo
@@@ -163,6 -164,19 +164,19 @@@ unsigned int __kfifo_out_peek(struct __
  }
  EXPORT_SYMBOL(__kfifo_out_peek);
  
+ unsigned int __kfifo_out_linear(struct __kfifo *fifo,
+               unsigned int *tail, unsigned int n)
+ {
+       unsigned int size = fifo->mask + 1;
+       unsigned int off = fifo->out & fifo->mask;
+       if (tail)
+               *tail = off;
+       return min3(n, fifo->in - fifo->out, size - off);
+ }
+ EXPORT_SYMBOL(__kfifo_out_linear);
  unsigned int __kfifo_out(struct __kfifo *fifo,
                void *buf, unsigned int len)
  {
@@@ -292,51 -306,31 +306,31 @@@ int __kfifo_to_user(struct __kfifo *fif
  }
  EXPORT_SYMBOL(__kfifo_to_user);
  
- static int setup_sgl_buf(struct scatterlist *sgl, void *buf,
-               int nents, unsigned int len)
+ static unsigned int setup_sgl_buf(struct __kfifo *fifo, struct scatterlist *sgl,
+                                 unsigned int data_offset, int nents,
+                                 unsigned int len, dma_addr_t dma)
  {
-       int n;
-       unsigned int l;
-       unsigned int off;
-       struct page *page;
+       const void *buf = fifo->data + data_offset;
  
-       if (!nents)
+       if (!nents || !len)
                return 0;
  
-       if (!len)
-               return 0;
+       sg_set_buf(sgl, buf, len);
  
-       n = 0;
-       page = virt_to_page(buf);
-       off = offset_in_page(buf);
-       l = 0;
-       while (len >= l + PAGE_SIZE - off) {
-               struct page *npage;
-               l += PAGE_SIZE;
-               buf += PAGE_SIZE;
-               npage = virt_to_page(buf);
-               if (page_to_phys(page) != page_to_phys(npage) - l) {
-                       sg_set_page(sgl, page, l - off, off);
-                       sgl = sg_next(sgl);
-                       if (++n == nents || sgl == NULL)
-                               return n;
-                       page = npage;
-                       len -= l - off;
-                       l = off = 0;
-               }
+       if (dma != DMA_MAPPING_ERROR) {
+               sg_dma_address(sgl) = dma + data_offset;
+               sg_dma_len(sgl) = len;
        }
-       sg_set_page(sgl, page, len, off);
-       return n + 1;
+       return 1;
  }
  
  static unsigned int setup_sgl(struct __kfifo *fifo, struct scatterlist *sgl,
-               int nents, unsigned int len, unsigned int off)
+               int nents, unsigned int len, unsigned int off, dma_addr_t dma)
  {
        unsigned int size = fifo->mask + 1;
        unsigned int esize = fifo->esize;
-       unsigned int l;
+       unsigned int len_to_end;
        unsigned int n;
  
        off &= fifo->mask;
                size *= esize;
                len *= esize;
        }
-       l = min(len, size - off);
+       len_to_end = min(len, size - off);
  
-       n = setup_sgl_buf(sgl, fifo->data + off, nents, l);
-       n += setup_sgl_buf(sgl + n, fifo->data, nents - n, len - l);
+       n = setup_sgl_buf(fifo, sgl, off, nents, len_to_end, dma);
+       n += setup_sgl_buf(fifo, sgl + n, 0, nents - n, len - len_to_end, dma);
  
        return n;
  }
  
  unsigned int __kfifo_dma_in_prepare(struct __kfifo *fifo,
-               struct scatterlist *sgl, int nents, unsigned int len)
+               struct scatterlist *sgl, int nents, unsigned int len,
+               dma_addr_t dma)
  {
        unsigned int l;
  
        if (len > l)
                len = l;
  
-       return setup_sgl(fifo, sgl, nents, len, fifo->in);
+       return setup_sgl(fifo, sgl, nents, len, fifo->in, dma);
  }
  EXPORT_SYMBOL(__kfifo_dma_in_prepare);
  
  unsigned int __kfifo_dma_out_prepare(struct __kfifo *fifo,
-               struct scatterlist *sgl, int nents, unsigned int len)
+               struct scatterlist *sgl, int nents, unsigned int len,
+               dma_addr_t dma)
  {
        unsigned int l;
  
        if (len > l)
                len = l;
  
-       return setup_sgl(fifo, sgl, nents, len, fifo->out);
+       return setup_sgl(fifo, sgl, nents, len, fifo->out, dma);
  }
  EXPORT_SYMBOL(__kfifo_dma_out_prepare);
  
@@@ -473,6 -469,19 +469,19 @@@ unsigned int __kfifo_out_peek_r(struct 
  }
  EXPORT_SYMBOL(__kfifo_out_peek_r);
  
+ unsigned int __kfifo_out_linear_r(struct __kfifo *fifo,
+               unsigned int *tail, unsigned int n, size_t recsize)
+ {
+       if (fifo->in == fifo->out)
+               return 0;
+       if (tail)
+               *tail = fifo->out + recsize;
+       return min(n, __kfifo_peek_n(fifo, recsize));
+ }
+ EXPORT_SYMBOL(__kfifo_out_linear_r);
  unsigned int __kfifo_out_r(struct __kfifo *fifo, void *buf,
                unsigned int len, size_t recsize)
  {
@@@ -546,7 -555,8 +555,8 @@@ int __kfifo_to_user_r(struct __kfifo *f
  EXPORT_SYMBOL(__kfifo_to_user_r);
  
  unsigned int __kfifo_dma_in_prepare_r(struct __kfifo *fifo,
-       struct scatterlist *sgl, int nents, unsigned int len, size_t recsize)
+       struct scatterlist *sgl, int nents, unsigned int len, size_t recsize,
+       dma_addr_t dma)
  {
        BUG_ON(!nents);
  
        if (len + recsize > kfifo_unused(fifo))
                return 0;
  
-       return setup_sgl(fifo, sgl, nents, len, fifo->in + recsize);
+       return setup_sgl(fifo, sgl, nents, len, fifo->in + recsize, dma);
  }
  EXPORT_SYMBOL(__kfifo_dma_in_prepare_r);
  
@@@ -569,7 -579,8 +579,8 @@@ void __kfifo_dma_in_finish_r(struct __k
  EXPORT_SYMBOL(__kfifo_dma_in_finish_r);
  
  unsigned int __kfifo_dma_out_prepare_r(struct __kfifo *fifo,
-       struct scatterlist *sgl, int nents, unsigned int len, size_t recsize)
+       struct scatterlist *sgl, int nents, unsigned int len, size_t recsize,
+       dma_addr_t dma)
  {
        BUG_ON(!nents);
  
        if (len + recsize > fifo->in - fifo->out)
                return 0;
  
-       return setup_sgl(fifo, sgl, nents, len, fifo->out + recsize);
+       return setup_sgl(fifo, sgl, nents, len, fifo->out + recsize, dma);
  }
  EXPORT_SYMBOL(__kfifo_dma_out_prepare_r);
  
- void __kfifo_dma_out_finish_r(struct __kfifo *fifo, size_t recsize)
- {
-       unsigned int len;
-       len = __kfifo_peek_n(fifo, recsize);
-       fifo->out += len + recsize;
- }
- EXPORT_SYMBOL(__kfifo_dma_out_finish_r);
This page took 0.285833 seconds and 4 git commands to generate.