diff options
69 files changed, 2610 insertions, 1269 deletions
diff --git a/Documentation/devicetree/bindings/serial/8250.txt b/Documentation/devicetree/bindings/serial/8250.txt index 936ab5b87324..f86bb06c39e9 100644 --- a/Documentation/devicetree/bindings/serial/8250.txt +++ b/Documentation/devicetree/bindings/serial/8250.txt @@ -42,6 +42,8 @@ Optional properties: - auto-flow-control: one way to enable automatic flow control support. The driver is allowed to detect support for the capability even without this property. +- tx-threshold: Specify the TX FIFO low water indication for parts with + programmable TX FIFO thresholds. Note: * fsl,ns16550: diff --git a/Documentation/devicetree/bindings/serial/st,stm32-usart.txt b/Documentation/devicetree/bindings/serial/st,stm32-usart.txt new file mode 100644 index 000000000000..85ec5f2b1996 --- /dev/null +++ b/Documentation/devicetree/bindings/serial/st,stm32-usart.txt @@ -0,0 +1,46 @@ +* STMicroelectronics STM32 USART + +Required properties: +- compatible: Can be either "st,stm32-usart", "st,stm32-uart", +"st,stm32f7-usart" or "st,stm32f7-uart" depending on whether +the device supports synchronous mode and is compatible with +stm32(f4) or stm32f7. +- reg: The address and length of the peripheral registers space +- interrupts: The interrupt line of the USART instance +- clocks: The input clock of the USART instance + +Optional properties: +- pinctrl: The reference on the pins configuration +- st,hw-flow-ctrl: bool flag to enable hardware flow control. +- dmas: phandle(s) to DMA controller node(s). Refer to stm32-dma.txt +- dma-names: "rx" and/or "tx" + +Examples: +usart4: serial@40004c00 { + compatible = "st,stm32-uart"; + reg = <0x40004c00 0x400>; + interrupts = <52>; + clocks = <&clk_pclk1>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usart4>; +}; + +usart2: serial@40004400 { + compatible = "st,stm32-usart", "st,stm32-uart"; + reg = <0x40004400 0x400>; + interrupts = <38>; + clocks = <&clk_pclk1>; + st,hw-flow-ctrl; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usart2 &pinctrl_usart2_rtscts>; +}; + +usart1: serial@40011000 { + compatible = "st,stm32-usart", "st,stm32-uart"; + reg = <0x40011000 0x400>; + interrupts = <37>; + clocks = <&rcc 0 164>; + dmas = <&dma2 2 4 0x414 0x0>, + <&dma2 7 4 0x414 0x0>; + dma-names = "rx", "tx"; +}; diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 25037ded3683..0e285941e3c7 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -1054,11 +1054,12 @@ bytes respectively. Such letter suffixes can also be entirely omitted. determined by the stdout-path property in device tree's chosen node. - cdns,<addr> - Start an early, polled-mode console on a cadence serial - port at the specified address. The cadence serial port - must already be setup and configured. Options are not - yet supported. + cdns,<addr>[,options] + Start an early, polled-mode console on a Cadence + (xuartps) serial port at the specified address. Only + supported option is baud rate. If baud rate is not + specified, the serial port must already be setup and + configured. uart[8250],io,<addr>[,options] uart[8250],mmio,<addr>[,options] diff --git a/MAINTAINERS b/MAINTAINERS index d52eae7c0755..434a43d3864d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2121,11 +2121,6 @@ M: Ludovic Desroches <ludovic.desroches@atmel.com> S: Maintained F: drivers/mmc/host/atmel-mci.c -ATMEL AT91 / AT32 SERIAL DRIVER -M: Nicolas Ferre <nicolas.ferre@atmel.com> -S: Supported -F: drivers/tty/serial/atmel_serial.c - ATMEL AT91 SAMA5D2-Compatible Shutdown Controller M: Nicolas Ferre <nicolas.ferre@atmel.com> S: Supported @@ -7774,6 +7769,12 @@ T: git git://git.monstr.eu/linux-2.6-microblaze.git S: Supported F: arch/microblaze/ +MICROCHIP / ATMEL AT91 / AT32 SERIAL DRIVER +M: Richard Genoud <richard.genoud@gmail.com> +S: Maintained +F: drivers/tty/serial/atmel_serial.c +F: include/linux/atmel_serial.h + MICROSOFT SURFACE PRO 3 BUTTON DRIVER M: Chen Yu <yu.c.chen@intel.com> L: platform-driver-x86@vger.kernel.org diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 17c14a1d9112..7d6bcf6339e1 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -4,6 +4,7 @@ config ARM64 select ACPI_GENERIC_GSI if ACPI select ACPI_REDUCED_HARDWARE_ONLY if ACPI select ACPI_MCFG if ACPI + select ACPI_SPCR_TABLE if ACPI select ARCH_CLOCKSOURCE_DATA select ARCH_HAS_DEVMEM_IS_ALLOWED select ARCH_HAS_ACPI_TABLE_UPGRADE if ACPI diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c index 3e4f1a45b125..252a6d9c1da5 100644 --- a/arch/arm64/kernel/acpi.c +++ b/arch/arm64/kernel/acpi.c @@ -24,6 +24,7 @@ #include <linux/memblock.h> #include <linux/of_fdt.h> #include <linux/smp.h> +#include <linux/serial_core.h> #include <asm/cputype.h> #include <asm/cpu_ops.h> @@ -206,7 +207,7 @@ void __init acpi_boot_table_init(void) if (param_acpi_off || (!param_acpi_on && !param_acpi_force && of_scan_flat_dt(dt_scan_depth1_nodes, NULL))) - return; + goto done; /* * ACPI is disabled at this point. Enable it in order to parse @@ -226,6 +227,14 @@ void __init acpi_boot_table_init(void) if (!param_acpi_force) disable_acpi(); } + +done: + if (acpi_disabled) { + if (earlycon_init_is_deferred) + early_init_dt_scan_chosen_stdout(); + } else { + parse_spcr(earlycon_init_is_deferred); + } } #ifdef CONFIG_ACPI_APEI diff --git a/arch/nios2/boot/dts/10m50_devboard.dts b/arch/nios2/boot/dts/10m50_devboard.dts index 3e411c644824..f362b2224ee7 100755 --- a/arch/nios2/boot/dts/10m50_devboard.dts +++ b/arch/nios2/boot/dts/10m50_devboard.dts @@ -83,6 +83,7 @@ fifo-size = <32>; reg-io-width = <4>; reg-shift = <2>; + tx-threshold = <16>; }; sysid: sysid@18001528 { diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 33201d4de633..535e7828445a 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -77,6 +77,9 @@ config ACPI_DEBUGGER_USER endif +config ACPI_SPCR_TABLE + bool + config ACPI_SLEEP bool depends on SUSPEND || HIBERNATION diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index 313f970888e4..9ed087853dee 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile @@ -82,6 +82,7 @@ obj-$(CONFIG_ACPI_EC_DEBUGFS) += ec_sys.o obj-$(CONFIG_ACPI_CUSTOM_METHOD)+= custom_method.o obj-$(CONFIG_ACPI_BGRT) += bgrt.o obj-$(CONFIG_ACPI_CPPC_LIB) += cppc_acpi.o +obj-$(CONFIG_ACPI_SPCR_TABLE) += spcr.o obj-$(CONFIG_ACPI_DEBUGGER_USER) += acpi_dbg.o # processor has its own "processor." module_param namespace diff --git a/drivers/acpi/spcr.c b/drivers/acpi/spcr.c new file mode 100644 index 000000000000..e8d7bc7d4da8 --- /dev/null +++ b/drivers/acpi/spcr.c @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2012, Intel Corporation + * Copyright (c) 2015, Red Hat, Inc. + * Copyright (c) 2015, 2016 Linaro Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#define pr_fmt(fmt) "ACPI: SPCR: " fmt + +#include <linux/acpi.h> +#include <linux/console.h> +#include <linux/kernel.h> +#include <linux/serial_core.h> + +/** + * parse_spcr() - parse ACPI SPCR table and add preferred console + * + * @earlycon: set up earlycon for the console specified by the table + * + * For the architectures with support for ACPI, CONFIG_ACPI_SPCR_TABLE may be + * defined to parse ACPI SPCR table. As a result of the parsing preferred + * console is registered and if @earlycon is true, earlycon is set up. + * + * When CONFIG_ACPI_SPCR_TABLE is defined, this function should be called + * from arch inintialization code as soon as the DT/ACPI decision is made. + * + */ +int __init parse_spcr(bool earlycon) +{ + static char opts[64]; + struct acpi_table_spcr *table; + acpi_size table_size; + acpi_status status; + char *uart; + char *iotype; + int baud_rate; + int err; + + if (acpi_disabled) + return -ENODEV; + + status = acpi_get_table_with_size(ACPI_SIG_SPCR, 0, + (struct acpi_table_header **)&table, + &table_size); + + if (ACPI_FAILURE(status)) + return -ENOENT; + + if (table->header.revision < 2) { + err = -ENOENT; + pr_err("wrong table version\n"); + goto done; + } + + iotype = table->serial_port.space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY ? + "mmio" : "io"; + + switch (table->interface_type) { + case ACPI_DBG2_ARM_SBSA_32BIT: + iotype = "mmio32"; + /* fall through */ + case ACPI_DBG2_ARM_PL011: + case ACPI_DBG2_ARM_SBSA_GENERIC: + case ACPI_DBG2_BCM2835: + uart = "pl011"; + break; + case ACPI_DBG2_16550_COMPATIBLE: + case ACPI_DBG2_16550_SUBSET: + uart = "uart"; + break; + default: + err = -ENOENT; + goto done; + } + + switch (table->baud_rate) { + case 3: + baud_rate = 9600; + break; + case 4: + baud_rate = 19200; + break; + case 6: + baud_rate = 57600; + break; + case 7: + baud_rate = 115200; + break; + default: + err = -ENOENT; + goto done; + } + + snprintf(opts, sizeof(opts), "%s,%s,0x%llx,%d", uart, iotype, + table->serial_port.address, baud_rate); + + pr_info("console: %s\n", opts); + + if (earlycon) + setup_earlycon(opts); + + err = add_preferred_console(uart, 0, opts + strlen(uart) + 1); + +done: + early_acpi_os_unmap_memory((void __iomem *)table, table_size); + return err; +} diff --git a/drivers/dma/dw/core.c b/drivers/dma/dw/core.c index edf053f73a49..da18b18561c4 100644 --- a/drivers/dma/dw/core.c +++ b/drivers/dma/dw/core.c @@ -46,9 +46,9 @@ u8 _dmsize = _is_slave ? _sconfig->dst_maxburst : \ DW_DMA_MSIZE_16; \ u8 _dms = (_dwc->direction == DMA_MEM_TO_DEV) ? \ - _dwc->p_master : _dwc->m_master; \ + _dwc->dws.p_master : _dwc->dws.m_master; \ u8 _sms = (_dwc->direction == DMA_DEV_TO_MEM) ? \ - _dwc->p_master : _dwc->m_master; \ + _dwc->dws.p_master : _dwc->dws.m_master; \ \ (DWC_CTLL_DST_MSIZE(_dmsize) \ | DWC_CTLL_SRC_MSIZE(_smsize) \ @@ -143,12 +143,16 @@ static void dwc_initialize(struct dw_dma_chan *dwc) struct dw_dma *dw = to_dw_dma(dwc->chan.device); u32 cfghi = DWC_CFGH_FIFO_MODE; u32 cfglo = DWC_CFGL_CH_PRIOR(dwc->priority); + bool hs_polarity = dwc->dws.hs_polarity; if (test_bit(DW_DMA_IS_INITIALIZED, &dwc->flags)) return; - cfghi |= DWC_CFGH_DST_PER(dwc->dst_id); - cfghi |= DWC_CFGH_SRC_PER(dwc->src_id); + cfghi |= DWC_CFGH_DST_PER(dwc->dws.dst_id); + cfghi |= DWC_CFGH_SRC_PER(dwc->dws.src_id); + + /* Set polarity of handshake interface */ + cfglo |= hs_polarity ? DWC_CFGL_HS_DST_POL | DWC_CFGL_HS_SRC_POL : 0; channel_writel(dwc, CFG_LO, cfglo); channel_writel(dwc, CFG_HI, cfghi); @@ -209,7 +213,7 @@ static inline void dwc_do_single_block(struct dw_dma_chan *dwc, static void dwc_dostart(struct dw_dma_chan *dwc, struct dw_desc *first) { struct dw_dma *dw = to_dw_dma(dwc->chan.device); - u8 lms = DWC_LLP_LMS(dwc->m_master); + u8 lms = DWC_LLP_LMS(dwc->dws.m_master); unsigned long was_soft_llp; /* ASSERT: channel is idle */ @@ -662,7 +666,7 @@ dwc_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src, struct dw_desc *prev; size_t xfer_count; size_t offset; - u8 m_master = dwc->m_master; + u8 m_master = dwc->dws.m_master; unsigned int src_width; unsigned int dst_width; unsigned int data_width = dw->pdata->data_width[m_master]; @@ -740,7 +744,7 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, struct dw_desc *prev; struct dw_desc *first; u32 ctllo; - u8 m_master = dwc->m_master; + u8 m_master = dwc->dws.m_master; u8 lms = DWC_LLP_LMS(m_master); dma_addr_t reg; unsigned int reg_width; @@ -895,12 +899,7 @@ bool dw_dma_filter(struct dma_chan *chan, void *param) return false; /* We have to copy data since dws can be temporary storage */ - - dwc->src_id = dws->src_id; - dwc->dst_id = dws->dst_id; - - dwc->m_master = dws->m_master; - dwc->p_master = dws->p_master; + memcpy(&dwc->dws, dws, sizeof(struct dw_dma_slave)); return true; } @@ -1167,11 +1166,7 @@ static void dwc_free_chan_resources(struct dma_chan *chan) spin_lock_irqsave(&dwc->lock, flags); /* Clear custom channel configuration */ - dwc->src_id = 0; - dwc->dst_id = 0; - - dwc->m_master = 0; - dwc->p_master = 0; + memset(&dwc->dws, 0, sizeof(struct dw_dma_slave)); clear_bit(DW_DMA_IS_INITIALIZED, &dwc->flags); @@ -1264,7 +1259,7 @@ struct dw_cyclic_desc *dw_dma_cyclic_prep(struct dma_chan *chan, struct dw_cyclic_desc *retval = NULL; struct dw_desc *desc; struct dw_desc *last = NULL; - u8 lms = DWC_LLP_LMS(dwc->m_master); + u8 lms = DWC_LLP_LMS(dwc->dws.m_master); unsigned long was_cyclic; unsigned int reg_width; unsigned int periods; @@ -1576,11 +1571,7 @@ int dw_dma_probe(struct dw_dma_chip *chip) (dwc_params >> DWC_PARAMS_MBLK_EN & 0x1) == 0; } else { dwc->block_size = pdata->block_size; - - /* Check if channel supports multi block transfer */ - channel_writel(dwc, LLP, DWC_LLP_LOC(0xffffffff)); - dwc->nollp = DWC_LLP_LOC(channel_readl(dwc, LLP)) == 0; - channel_writel(dwc, LLP, 0); + dwc->nollp = pdata->is_nollp; } } diff --git a/drivers/dma/dw/regs.h b/drivers/dma/dw/regs.h index 4b7bd7834046..f65dd104479f 100644 --- a/drivers/dma/dw/regs.h +++ b/drivers/dma/dw/regs.h @@ -245,10 +245,7 @@ struct dw_dma_chan { bool nollp; /* custom slave configuration */ - u8 src_id; - u8 dst_id; - u8 m_master; - u8 p_master; + struct dw_dma_slave dws; /* configuration passed via .device_config */ struct dma_slave_config dma_sconfig; diff --git a/drivers/dma/hsu/hsu.c b/drivers/dma/hsu/hsu.c index c5f21efd6090..29d04ca71d52 100644 --- a/drivers/dma/hsu/hsu.c +++ b/drivers/dma/hsu/hsu.c @@ -200,10 +200,9 @@ EXPORT_SYMBOL_GPL(hsu_dma_get_status); * is not a normal timeout interrupt, ie. hsu_dma_get_status() returned 0. * * Return: - * IRQ_NONE for invalid channel number, IRQ_HANDLED otherwise. + * 0 for invalid channel number, 1 otherwise. */ -irqreturn_t hsu_dma_do_irq(struct hsu_dma_chip *chip, unsigned short nr, - u32 status) +int hsu_dma_do_irq(struct hsu_dma_chip *chip, unsigned short nr, u32 status) { struct hsu_dma_chan *hsuc; struct hsu_dma_desc *desc; @@ -211,7 +210,7 @@ irqreturn_t hsu_dma_do_irq(struct hsu_dma_chip *chip, unsigned short nr, /* Sanity check */ if (nr >= chip->hsu->nr_channels) - return IRQ_NONE; + return 0; hsuc = &chip->hsu->chan[nr]; @@ -230,7 +229,7 @@ irqreturn_t hsu_dma_do_irq(struct hsu_dma_chip *chip, unsigned short nr, } spin_unlock_irqrestore(&hsuc->vchan.lock, flags); - return IRQ_HANDLED; + return 1; } EXPORT_SYMBOL_GPL(hsu_dma_do_irq); diff --git a/drivers/dma/hsu/pci.c b/drivers/dma/hsu/pci.c index 9916058531d9..b51639f045ed 100644 --- a/drivers/dma/hsu/pci.c +++ b/drivers/dma/hsu/pci.c @@ -29,7 +29,7 @@ static irqreturn_t hsu_pci_irq(int irq, void *dev) u32 dmaisr; u32 status; unsigned short i; - irqreturn_t ret = IRQ_NONE; + int ret = 0; int err; dmaisr = readl(chip->regs + HSU_PCI_DMAISR); @@ -37,14 +37,14 @@ static irqreturn_t hsu_pci_irq(int irq, void *dev) if (dmaisr & 0x1) { err = hsu_dma_get_status(chip, i, &status); if (err > 0) - ret |= IRQ_HANDLED; + ret |= 1; else if (err == 0) ret |= hsu_dma_do_irq(chip, i, status); } dmaisr >>= 1; } - return ret; + return IRQ_RETVAL(ret); } static int hsu_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index 03ec76fc22ff..3cb47386fbb9 100644 --- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c @@ -648,15 +648,11 @@ static void sdma_event_disable(struct sdma_channel *sdmac, unsigned int event) writel_relaxed(val, sdma->regs + chnenbl); } -static void sdma_handle_channel_loop(struct sdma_channel *sdmac) -{ - if (sdmac->desc.callback) - sdmac->desc.callback(sdmac->desc.callback_param); -} - static void sdma_update_channel_loop(struct sdma_channel *sdmac) { struct sdma_buffer_descriptor *bd; + int error = 0; + enum dma_status old_status = sdmac->status; /* * loop mode. Iterate over descriptors, re-setup them and @@ -668,17 +664,42 @@ static void sdma_update_channel_loop(struct sdma_channel *sdmac) if (bd->mode.status & BD_DONE) break; - if (bd->mode.status & BD_RROR) + if (bd->mode.status & BD_RROR) { + bd->mode.status &= ~BD_RROR; sdmac->status = DMA_ERROR; + error = -EIO; + } + < |
