Merge remote-tracking branch 'tty/tty-next'
authorStephen Rothwell <sfr@canb.auug.org.au>
Tue, 13 Sep 2016 02:39:35 +0000 (12:39 +1000)
committerStephen Rothwell <sfr@canb.auug.org.au>
Tue, 13 Sep 2016 02:39:35 +0000 (12:39 +1000)
1  2 
drivers/dma/dw/core.c
drivers/dma/imx-sdma.c
drivers/tty/serial/8250/8250_dw.c

diff --combined drivers/dma/dw/core.c
index 12eedd45719399734b48e7b6b08cfa658c0698a9,da18b18561c447b5c6aa7d9c43fa350faf5b62d5..c2c0a613cb7aab53ac5f8e85c6c7441ecc7ef3fc
@@@ -46,9 -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 +143,16 @@@ static void dwc_initialize(struct dw_dm
        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 +213,7 @@@ static inline void dwc_do_single_block(
  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 */
@@@ -270,19 -274,20 +274,19 @@@ static voi
  dwc_descriptor_complete(struct dw_dma_chan *dwc, struct dw_desc *desc,
                bool callback_required)
  {
 -      dma_async_tx_callback           callback = NULL;
 -      void                            *param = NULL;
        struct dma_async_tx_descriptor  *txd = &desc->txd;
        struct dw_desc                  *child;
        unsigned long                   flags;
 +      struct dmaengine_desc_callback  cb;
  
        dev_vdbg(chan2dev(&dwc->chan), "descriptor %u complete\n", txd->cookie);
  
        spin_lock_irqsave(&dwc->lock, flags);
        dma_cookie_complete(txd);
 -      if (callback_required) {
 -              callback = txd->callback;
 -              param = txd->callback_param;
 -      }
 +      if (callback_required)
 +              dmaengine_desc_get_callback(txd, &cb);
 +      else
 +              memset(&cb, 0, sizeof(cb));
  
        /* async_tx_ack */
        list_for_each_entry(child, &desc->tx_list, desc_node)
        dwc_desc_put(dwc, desc);
        spin_unlock_irqrestore(&dwc->lock, flags);
  
 -      if (callback)
 -              callback(param);
 +      dmaengine_desc_callback_invoke(&cb, NULL);
  }
  
  static void dwc_complete_all(struct dw_dma *dw, struct dw_dma_chan *dwc)
@@@ -660,7 -666,7 +664,7 @@@ dwc_prep_dma_memcpy(struct dma_chan *ch
        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];
@@@ -738,7 -744,7 +742,7 @@@ dwc_prep_slave_sg(struct dma_chan *chan
        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;
@@@ -893,12 -899,7 +897,7 @@@ bool dw_dma_filter(struct dma_chan *cha
                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;
  }
@@@ -1165,11 -1166,7 +1164,7 @@@ static void dwc_free_chan_resources(str
        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);
  
@@@ -1262,7 -1259,7 +1257,7 @@@ struct dw_cyclic_desc *dw_dma_cyclic_pr
        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;
@@@ -1574,11 -1571,7 +1569,7 @@@ int dw_dma_probe(struct dw_dma_chip *ch
                                (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 --combined drivers/dma/imx-sdma.c
index a6bffbc47ee2e6d7ca3649de7f37af38fb9d7e0d,3cb47386fbb9b33e618459a5ebfa69565f2f3467..b9629b2bfc050b3c6cd4db691da49f99c7d85232
  struct sdma_mode_count {
        u32 count   : 16; /* size of the buffer pointed by this BD */
        u32 status  :  8; /* E,R,I,C,W,D status bits stored here */
 -      u32 command :  8; /* command mostlky used for channel 0 */
 +      u32 command :  8; /* command mostly used for channel 0 */
  };
  
  /*
@@@ -479,24 -479,6 +479,24 @@@ static struct sdma_driver_data sdma_imx
        .script_addrs = &sdma_script_imx6q,
  };
  
 +static struct sdma_script_start_addrs sdma_script_imx7d = {
 +      .ap_2_ap_addr = 644,
 +      .uart_2_mcu_addr = 819,
 +      .mcu_2_app_addr = 749,
 +      .uartsh_2_mcu_addr = 1034,
 +      .mcu_2_shp_addr = 962,
 +      .app_2_mcu_addr = 685,
 +      .shp_2_mcu_addr = 893,
 +      .spdif_2_mcu_addr = 1102,
 +      .mcu_2_spdif_addr = 1136,
 +};
 +
 +static struct sdma_driver_data sdma_imx7d = {
 +      .chnenbl0 = SDMA_CHNENBL0_IMX35,
 +      .num_events = 48,
 +      .script_addrs = &sdma_script_imx7d,
 +};
 +
  static const struct platform_device_id sdma_devtypes[] = {
        {
                .name = "imx25-sdma",
        }, {
                .name = "imx6q-sdma",
                .driver_data = (unsigned long)&sdma_imx6q,
 +      }, {
 +              .name = "imx7d-sdma",
 +              .driver_data = (unsigned long)&sdma_imx7d,
        }, {
                /* sentinel */
        }
@@@ -532,7 -511,6 +532,7 @@@ static const struct of_device_id sdma_d
        { .compatible = "fsl,imx35-sdma", .data = &sdma_imx35, },
        { .compatible = "fsl,imx31-sdma", .data = &sdma_imx31, },
        { .compatible = "fsl,imx25-sdma", .data = &sdma_imx25, },
 +      { .compatible = "fsl,imx7d-sdma", .data = &sdma_imx7d, },
        { /* sentinel */ }
  };
  MODULE_DEVICE_TABLE(of, sdma_dt_ids);
@@@ -670,14 -648,11 +670,11 @@@ static void sdma_event_disable(struct s
        writel_relaxed(val, sdma->regs + chnenbl);
  }
  
- static void sdma_handle_channel_loop(struct sdma_channel *sdmac)
- {
-       dmaengine_desc_get_callback_invoke(&sdmac->desc, NULL);
- }
  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
                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;
 -              if (sdmac->desc.callback)
 -                      sdmac->desc.callback(sdmac->desc.callback_param);
+               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.
+                */
++              dmaengine_desc_get_callback_invoke(&sdmac->desc, NULL);
                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;
  
                sdmac->status = DMA_COMPLETE;
  
        dma_cookie_complete(&sdmac->desc);
 -      if (sdmac->desc.callback)
 -              sdmac->desc.callback(sdmac->desc.callback_param);
 +
 +      dmaengine_desc_get_callback_invoke(&sdmac->desc, NULL);
  }
  
- 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;
  
                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);
        }
@@@ -1374,7 -1364,8 +1385,8 @@@ static enum dma_status sdma_tx_status(s
        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;
  
@@@ -1396,7 -1387,6 +1408,7 @@@ static void sdma_issue_pending(struct d
  #define SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V1       34
  #define SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V2       38
  #define SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V3       41
 +#define SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V4       42
  
  static void sdma_add_scripts(struct sdma_engine *sdma,
                const struct sdma_script_start_addrs *addr)
@@@ -1446,9 -1436,6 +1458,9 @@@ static void sdma_load_firmware(const st
        case 3:
                sdma->script_number = SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V3;
                break;
 +      case 4:
 +              sdma->script_number = SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V4;
 +              break;
        default:
                dev_err(sdma->dev, "unknown firmware version\n");
                goto err_firmware;
@@@ -1757,7 -1744,7 +1769,7 @@@ static int sdma_probe(struct platform_d
                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
index 5c0c123565ad8077cfbed0b9bd4b178006588dcb,5e4b80ecb88302c37187a1684abf853c7b75201d..459d726f9d59bc709a889163964f775866e7adb4
@@@ -298,17 -298,12 +298,17 @@@ static void dw8250_quirks(struct uart_p
                        p->serial_out = dw8250_serial_out32be;
                }
        } else if (has_acpi_companion(p->dev)) {
 -              p->iotype = UPIO_MEM32;
 -              p->regshift = 2;
 -              p->serial_in = dw8250_serial_in32;
 +              const struct acpi_device_id *id;
 +
 +              id = acpi_match_device(p->dev->driver->acpi_match_table,
 +                                     p->dev);
 +              if (id && !strcmp(id->id, "APMC0D08")) {
 +                      p->iotype = UPIO_MEM32;
 +                      p->regshift = 2;
 +                      p->serial_in = dw8250_serial_in32;
 +                      data->uart_16550_compatible = true;
 +              }
                p->set_termios = dw8250_set_termios;
 -              /* So far none of there implement the Busy Functionality */
 -              data->uart_16550_compatible = true;
        }
  
        /* Platforms with iDMA */
@@@ -365,18 -360,19 +365,19 @@@ static int dw8250_probe(struct platform
        struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        int irq = platform_get_irq(pdev, 0);
        struct uart_port *p = &uart.port;
+       struct device *dev = &pdev->dev;
        struct dw8250_data *data;
        int err;
        u32 val;
  
        if (!regs) {
-               dev_err(&pdev->dev, "no registers defined\n");
+               dev_err(dev, "no registers defined\n");
                return -EINVAL;
        }
  
        if (irq < 0) {
                if (irq != -EPROBE_DEFER)
-                       dev_err(&pdev->dev, "cannot get irq\n");
+                       dev_err(dev, "cannot get irq\n");
                return irq;
        }
  
        p->pm           = dw8250_do_pm;
        p->type         = PORT_8250;
        p->flags        = UPF_SHARE_IRQ | UPF_FIXED_PORT;
-       p->dev          = &pdev->dev;
+       p->dev          = dev;
        p->iotype       = UPIO_MEM;
        p->serial_in    = dw8250_serial_in;
        p->serial_out   = dw8250_serial_out;
  
-       p->membase = devm_ioremap(&pdev->dev, regs->start, resource_size(regs));
+       p->membase = devm_ioremap(dev, regs->start, resource_size(regs));
        if (!p->membase)
                return -ENOMEM;
  
-       data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+       data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
        if (!data)
                return -ENOMEM;
  
        data->usr_reg = DW_UART_USR;
        p->private_data = data;
  
-       data->uart_16550_compatible = device_property_read_bool(p->dev,
+       data->uart_16550_compatible = device_property_read_bool(dev,
                                                "snps,uart-16550-compatible");
  
-       err = device_property_read_u32(p->dev, "reg-shift", &val);
+       err = device_property_read_u32(dev, "reg-shift", &val);
        if (!err)
                p->regshift = val;
  
-       err = device_property_read_u32(p->dev, "reg-io-width", &val);
+       err = device_property_read_u32(dev, "reg-io-width", &val);
        if (!err && val == 4) {
                p->iotype = UPIO_MEM32;
                p->serial_in = dw8250_serial_in32;
                p->serial_out = dw8250_serial_out32;
        }
  
-       if (device_property_read_bool(p->dev, "dcd-override")) {
+       if (device_property_read_bool(dev, "dcd-override")) {
                /* Always report DCD as active */
                data->msr_mask_on |= UART_MSR_DCD;
                data->msr_mask_off |= UART_MSR_DDCD;
        }
  
-       if (device_property_read_bool(p->dev, "dsr-override")) {
+       if (device_property_read_bool(dev, "dsr-override")) {
                /* Always report DSR as active */
                data->msr_mask_on |= UART_MSR_DSR;
                data->msr_mask_off |= UART_MSR_DDSR;
        }
  
-       if (device_property_read_bool(p->dev, "cts-override")) {
+       if (device_property_read_bool(dev, "cts-override")) {
                /* Always report CTS as active */
                data->msr_mask_on |= UART_MSR_CTS;
                data->msr_mask_off |= UART_MSR_DCTS;
        }
  
-       if (device_property_read_bool(p->dev, "ri-override")) {
+       if (device_property_read_bool(dev, "ri-override")) {
                /* Always report Ring indicator as inactive */
                data->msr_mask_off |= UART_MSR_RI;
                data->msr_mask_off |= UART_MSR_TERI;
        }
  
        /* Always ask for fixed clock rate from a property. */
-       device_property_read_u32(p->dev, "clock-frequency", &p->uartclk);
+       device_property_read_u32(dev, "clock-frequency", &p->uartclk);
  
        /* If there is separate baudclk, get the rate from it. */
-       data->clk = devm_clk_get(&pdev->dev, "baudclk");
+       data->clk = devm_clk_get(dev, "baudclk");
        if (IS_ERR(data->clk) && PTR_ERR(data->clk) != -EPROBE_DEFER)
-               data->clk = devm_clk_get(&pdev->dev, NULL);
+               data->clk = devm_clk_get(dev, NULL);
        if (IS_ERR(data->clk) && PTR_ERR(data->clk) == -EPROBE_DEFER)
                return -EPROBE_DEFER;
        if (!IS_ERR_OR_NULL(data->clk)) {
                err = clk_prepare_enable(data->clk);
                if (err)
-                       dev_warn(&pdev->dev, "could not enable optional baudclk: %d\n",
+                       dev_warn(dev, "could not enable optional baudclk: %d\n",
                                 err);
                else
                        p->uartclk = clk_get_rate(data->clk);
  
        /* If no clock rate is defined, fail. */
        if (!p->uartclk) {
-               dev_err(&pdev->dev, "clock rate not defined\n");
+               dev_err(dev, "clock rate not defined\n");
                return -EINVAL;
        }
  
-       data->pclk = devm_clk_get(&pdev->dev, "apb_pclk");
-       if (IS_ERR(data->clk) && PTR_ERR(data->clk) == -EPROBE_DEFER) {
+       data->pclk = devm_clk_get(dev, "apb_pclk");
+       if (IS_ERR(data->pclk) && PTR_ERR(data->pclk) == -EPROBE_DEFER) {
                err = -EPROBE_DEFER;
                goto err_clk;
        }
        if (!IS_ERR(data->pclk)) {
                err = clk_prepare_enable(data->pclk);
                if (err) {
-                       dev_err(&pdev->dev, "could not enable apb_pclk\n");
+                       dev_err(dev, "could not enable apb_pclk\n");
                        goto err_clk;
                }
        }
  
-       data->rst = devm_reset_control_get_optional(&pdev->dev, NULL);
+       data->rst = devm_reset_control_get_optional(dev, NULL);
        if (IS_ERR(data->rst) && PTR_ERR(data->rst) == -EPROBE_DEFER) {
                err = -EPROBE_DEFER;
                goto err_pclk;
  
        platform_set_drvdata(pdev, data);
  
-       pm_runtime_set_active(&pdev->dev);
-       pm_runtime_enable(&pdev->dev);
+       pm_runtime_set_active(dev);
+       pm_runtime_enable(dev);
  
        return 0;
  
@@@ -624,6 -620,7 +625,7 @@@ static const struct acpi_device_id dw82
        { "APMC0D08", 0},
        { "AMD0020", 0 },
        { "AMDI0020", 0 },
+       { "HISI0031", 0 },
        { },
  };
  MODULE_DEVICE_TABLE(acpi, dw8250_acpi_match);
This page took 0.037241 seconds and 5 git commands to generate.