You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge tag 'tty-4.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty
Pull tty and serial updates from Greg KH: "Here is the big tty and serial patch set for 4.9-rc1. It also includes some drivers/dma/ changes, as those were needed by some serial drivers, and they were all acked by the DMA maintainer. Also in here is the long-suffering ACPI SPCR patchset, which was passed around from maintainer to maintainer like a hot-potato. Seems I was the sucker^Wlucky one. All of those patches have been acked by the various subsystem maintainers as well. All of this has been in linux-next with no reported issues" * tag 'tty-4.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: (111 commits) Revert "serial: pl011: add console matching function" MAINTAINERS: update entry for atmel_serial driver serial: pl011: add console matching function ARM64: ACPI: enable ACPI_SPCR_TABLE ACPI: parse SPCR and enable matching console of/serial: move earlycon early_param handling to serial Revert "drivers/tty: Explicitly pass current to show_stack" tty: amba-pl011: Don't complain on -EPROBE_DEFER when no irq nios2: dts: 10m50: Add tx-threshold parameter serial: 8250: Set Altera 16550 TX FIFO Threshold serial: 8250: of: Load TX FIFO Threshold from DT Documentation: dt: serial: Add TX FIFO threshold parameter drivers/tty: Explicitly pass current to show_stack serial: imx: Fix DCD reading serial: stm32: mark symbols static where possible serial: xuartps: Add some register initialisation to cdns_early_console_setup() serial: xuartps: Removed unwanted checks while reading the error conditions serial: xuartps: Rewrite the interrupt handling logic serial: stm32: use mapbase instead of membase for DMA tty/serial: atmel: fix fractional baud rate computation ...
This commit is contained in:
@@ -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:
|
||||
|
||||
@@ -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";
|
||||
};
|
||||
@@ -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]
|
||||
|
||||
+6
-5
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -83,6 +83,7 @@
|
||||
fifo-size = <32>;
|
||||
reg-io-width = <4>;
|
||||
reg-shift = <2>;
|
||||
tx-threshold = <16>;
|
||||
};
|
||||
|
||||
sysid: sysid@18001528 {
|
||||
|
||||
@@ -77,6 +77,9 @@ config ACPI_DEBUGGER_USER
|
||||
|
||||
endif
|
||||
|
||||
config ACPI_SPCR_TABLE
|
||||
bool
|
||||
|
||||
config ACPI_SLEEP
|
||||
bool
|
||||
depends on SUSPEND || HIBERNATION
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
+15
-24
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
+34
-22
@@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
* We use bd->mode.count to calculate the residue, since contains
|
||||
* the number of bytes present in the current buffer descriptor.
|
||||
*/
|
||||
|
||||
sdmac->chn_real_count = bd->mode.count;
|
||||
bd->mode.status |= BD_DONE;
|
||||
bd->mode.count = sdmac->period_len;
|
||||
|
||||
/*
|
||||
* The callback is called from the interrupt context in order
|
||||
* to reduce latency and to avoid the risk of altering the
|
||||
* SDMA transaction status by the time the client tasklet is
|
||||
* executed.
|
||||
*/
|
||||
|
||||
if (sdmac->desc.callback)
|
||||
sdmac->desc.callback(sdmac->desc.callback_param);
|
||||
|
||||
sdmac->buf_tail++;
|
||||
sdmac->buf_tail %= sdmac->num_bd;
|
||||
|
||||
if (error)
|
||||
sdmac->status = old_status;
|
||||
}
|
||||
}
|
||||
|
||||
static void mxc_sdma_handle_channel_normal(struct sdma_channel *sdmac)
|
||||
static void mxc_sdma_handle_channel_normal(unsigned long data)
|
||||
{
|
||||
struct sdma_channel *sdmac = (struct sdma_channel *) data;
|
||||
struct sdma_buffer_descriptor *bd;
|
||||
int i, error = 0;
|
||||
|
||||
@@ -705,16 +726,6 @@ static void mxc_sdma_handle_channel_normal(struct sdma_channel *sdmac)
|
||||
sdmac->desc.callback(sdmac->desc.callback_param);
|
||||
}
|
||||
|
||||
static void sdma_tasklet(unsigned long data)
|
||||
{
|
||||
struct sdma_channel *sdmac = (struct sdma_channel *) data;
|
||||
|
||||
if (sdmac->flags & IMX_DMA_SG_LOOP)
|
||||
sdma_handle_channel_loop(sdmac);
|
||||
else
|
||||
mxc_sdma_handle_channel_normal(sdmac);
|
||||
}
|
||||
|
||||
static irqreturn_t sdma_int_handler(int irq, void *dev_id)
|
||||
{
|
||||
struct sdma_engine *sdma = dev_id;
|
||||
@@ -731,8 +742,8 @@ static irqreturn_t sdma_int_handler(int irq, void *dev_id)
|
||||
|
||||
if (sdmac->flags & IMX_DMA_SG_LOOP)
|
||||
sdma_update_channel_loop(sdmac);
|
||||
|
||||
tasklet_schedule(&sdmac->tasklet);
|
||||
else
|
||||
tasklet_schedule(&sdmac->tasklet);
|
||||
|
||||
__clear_bit(channel, &stat);
|
||||
}
|
||||
@@ -1353,7 +1364,8 @@ static enum dma_status sdma_tx_status(struct dma_chan *chan,
|
||||
u32 residue;
|
||||
|
||||
if (sdmac->flags & IMX_DMA_SG_LOOP)
|
||||
residue = (sdmac->num_bd - sdmac->buf_tail) * sdmac->period_len;
|
||||
residue = (sdmac->num_bd - sdmac->buf_tail) *
|
||||
sdmac->period_len - sdmac->chn_real_count;
|
||||
else
|
||||
residue = sdmac->chn_count - sdmac->chn_real_count;
|
||||
|
||||
@@ -1732,7 +1744,7 @@ static int sdma_probe(struct platform_device *pdev)
|
||||
dma_cookie_init(&sdmac->chan);
|
||||
sdmac->channel = i;
|
||||
|
||||
tasklet_init(&sdmac->tasklet, sdma_tasklet,
|
||||
tasklet_init(&sdmac->tasklet, mxc_sdma_handle_channel_normal,
|
||||
(unsigned long) sdmac);
|
||||
/*
|
||||
* Add the channel to the DMAC list. Do not add channel 0 though
|
||||
|
||||
+1
-10
@@ -924,7 +924,7 @@ static inline void early_init_dt_check_for_initrd(unsigned long node)
|
||||
|
||||
#ifdef CONFIG_SERIAL_EARLYCON
|
||||
|
||||
static int __init early_init_dt_scan_chosen_serial(void)
|
||||
int __init early_init_dt_scan_chosen_stdout(void)
|
||||
{
|
||||
int offset;
|
||||
const char *p, *q, *options = NULL;
|
||||
@@ -968,15 +968,6 @@ static int __init early_init_dt_scan_chosen_serial(void)
|
||||
}
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static int __init setup_of_earlycon(char *buf)
|
||||
{
|
||||
if (buf)
|
||||
return 0;
|
||||
|
||||
return early_init_dt_scan_chosen_serial();
|
||||
}
|
||||
early_param("earlycon", setup_of_earlycon);
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
||||
+1
-1
@@ -800,7 +800,7 @@ out_free_file:
|
||||
return retval;
|
||||
}
|
||||
|
||||
static struct file_operations ptmx_fops;
|
||||
static struct file_operations ptmx_fops __ro_after_init;
|
||||
|
||||
static void __init unix98_pty_init(void)
|
||||
{
|
||||
|
||||
@@ -31,6 +31,11 @@ struct uart_8250_dma {
|
||||
struct dma_chan *rxchan;
|
||||
struct dma_chan *txchan;
|
||||
|
||||
/* Device address base for DMA operations */
|
||||
phys_addr_t rx_dma_addr;
|
||||
phys_addr_t tx_dma_addr;
|
||||
|
||||
/* DMA address of the buffer in memory */
|
||||
dma_addr_t rx_addr;
|
||||
dma_addr_t tx_addr;
|
||||
|
||||
|
||||
@@ -639,7 +639,7 @@ static int univ8250_console_match(struct console *co, char *name, int idx,
|
||||
{
|
||||
char match[] = "uart"; /* 8250-specific earlycon name */
|
||||
unsigned char iotype;
|
||||
unsigned long addr;
|
||||
resource_size_t addr;
|
||||
int i;
|
||||
|
||||
if (strncmp(name, match, 4) != 0)
|
||||
|
||||
@@ -142,7 +142,7 @@ void serial8250_rx_dma_flush(struct uart_8250_port *p)
|
||||
if (dma->rx_running) {
|
||||
dmaengine_pause(dma->rxchan);
|
||||
__dma_rx_complete(p);
|
||||
dmaengine_terminate_all(dma->rxchan);
|
||||
dmaengine_terminate_async(dma->rxchan);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(serial8250_rx_dma_flush);
|
||||
@@ -150,6 +150,10 @@ EXPORT_SYMBOL_GPL(serial8250_rx_dma_flush);
|
||||
int serial8250_request_dma(struct uart_8250_port *p)
|
||||
{
|
||||
struct uart_8250_dma *dma = p->dma;
|
||||
phys_addr_t rx_dma_addr = dma->rx_dma_addr ?
|
||||
dma->rx_dma_addr : p->port.mapbase;
|
||||
phys_addr_t tx_dma_addr = dma->tx_dma_addr ?
|
||||
dma->tx_dma_addr : p->port.mapbase;
|
||||
dma_cap_mask_t mask;
|
||||
struct dma_slave_caps caps;
|
||||
int ret;
|
||||
@@ -157,11 +161,11 @@ int serial8250_request_dma(struct uart_8250_port *p)
|
||||
/* Default slave configuration parameters */
|
||||
dma->rxconf.direction = DMA_DEV_TO_MEM;
|
||||
dma->rxconf.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
|
||||
dma->rxconf.src_addr = p->port.mapbase + UART_RX;
|
||||
dma->rxconf.src_addr = rx_dma_addr + UART_RX;
|
||||
|
||||
dma->txconf.direction = DMA_MEM_TO_DEV;
|
||||
dma->txconf.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
|
||||
dma->txconf.dst_addr = p->port.mapbase + UART_TX;
|
||||
dma->txconf.dst_addr = tx_dma_addr + UART_TX;
|
||||
|
||||
dma_cap_zero(mask);
|
||||
dma_cap_set(DMA_SLAVE, mask);
|
||||
@@ -247,14 +251,14 @@ void serial8250_release_dma(struct uart_8250_port *p)
|
||||
return;
|
||||
|
||||
/* Release RX resources */
|
||||
dmaengine_terminate_all(dma->rxchan);
|
||||
dmaengine_terminate_sync(dma->rxchan);
|
||||
dma_free_coherent(dma->rxchan->device->dev, dma->rx_size, dma->rx_buf,
|
||||
dma->rx_addr);
|
||||
dma_release_channel(dma->rxchan);
|
||||
dma->rxchan = NULL;
|
||||
|
||||
/* Release TX resources */
|
||||
dmaengine_terminate_all(dma->txchan);
|
||||
dmaengine_terminate_sync(dma->txchan);
|
||||
dma_unmap_single(dma->txchan->device->dev, dma->tx_addr,
|
||||
UART_XMIT_SIZE, DMA_TO_DEVICE);
|
||||
dma_release_channel(dma->txchan);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user