drm/rockchip: rga: fix potential buffer overflow
[firefly-linux-kernel-4.4.55.git] / drivers / spi / spi-pl022.c
index a6f0878d9bf1fef057105fe4345d03432c3f65eb..5e5fd77e27119d6ceb8d64f657884ab4ef9f3759 100644 (file)
@@ -82,6 +82,7 @@
 #define SSP_MIS(r)     (r + 0x01C)
 #define SSP_ICR(r)     (r + 0x020)
 #define SSP_DMACR(r)   (r + 0x024)
+#define SSP_CSR(r)     (r + 0x030) /* vendor extension */
 #define SSP_ITCR(r)    (r + 0x080)
 #define SSP_ITIP(r)    (r + 0x084)
 #define SSP_ITOP(r)    (r + 0x088)
 /* Transmit DMA Enable bit */
 #define SSP_DMACR_MASK_TXDMAE          (0x1UL << 1)
 
+/*
+ * SSP Chip Select Control Register - SSP_CSR
+ * (vendor extension)
+ */
+#define SSP_CSR_CSVALUE_MASK           (0x1FUL << 0)
+
 /*
  * SSP Integration Test control Register - SSP_ITCR
  */
  */
 #define DEFAULT_SSP_REG_IMSC  0x0UL
 #define DISABLE_ALL_INTERRUPTS DEFAULT_SSP_REG_IMSC
-#define ENABLE_ALL_INTERRUPTS (~DEFAULT_SSP_REG_IMSC)
+#define ENABLE_ALL_INTERRUPTS ( \
+       SSP_IMSC_MASK_RORIM | \
+       SSP_IMSC_MASK_RTIM | \
+       SSP_IMSC_MASK_RXIM | \
+       SSP_IMSC_MASK_TXIM \
+)
 
 #define CLEAR_ALL_INTERRUPTS  0x3
 
@@ -313,6 +325,7 @@ enum ssp_writing {
  * @extended_cr: 32 bit wide control register 0 with extra
  * features and extra features in CR1 as found in the ST variants
  * @pl023: supports a subset of the ST extensions called "PL023"
+ * @internal_cs_ctrl: supports chip select control register
  */
 struct vendor_data {
        int fifodepth;
@@ -321,6 +334,7 @@ struct vendor_data {
        bool extended_cr;
        bool pl023;
        bool loopback;
+       bool internal_cs_ctrl;
 };
 
 /**
@@ -368,11 +382,6 @@ struct pl022 {
        resource_size_t                 phybase;
        void __iomem                    *virtbase;
        struct clk                      *clk;
-       /* Two optional pin states - default & sleep */
-       struct pinctrl                  *pinctrl;
-       struct pinctrl_state            *pins_default;
-       struct pinctrl_state            *pins_idle;
-       struct pinctrl_state            *pins_sleep;
        struct spi_master               *master;
        struct pl022_ssp_controller     *master_info;
        /* Message per-transfer pump */
@@ -445,9 +454,32 @@ static void null_cs_control(u32 command)
        pr_debug("pl022: dummy chip select control, CS=0x%x\n", command);
 }
 
+/**
+ * internal_cs_control - Control chip select signals via SSP_CSR.
+ * @pl022: SSP driver private data structure
+ * @command: select/delect the chip
+ *
+ * Used on controller with internal chip select control via SSP_CSR register
+ * (vendor extension). Each of the 5 LSB in the register controls one chip
+ * select signal.
+ */
+static void internal_cs_control(struct pl022 *pl022, u32 command)
+{
+       u32 tmp;
+
+       tmp = readw(SSP_CSR(pl022->virtbase));
+       if (command == SSP_CHIP_SELECT)
+               tmp &= ~BIT(pl022->cur_cs);
+       else
+               tmp |= BIT(pl022->cur_cs);
+       writew(tmp, SSP_CSR(pl022->virtbase));
+}
+
 static void pl022_cs_control(struct pl022 *pl022, u32 command)
 {
-       if (gpio_is_valid(pl022->cur_cs))
+       if (pl022->vendor->internal_cs_ctrl)
+               internal_cs_control(pl022, command);
+       else if (gpio_is_valid(pl022->cur_cs))
                gpio_set_value(pl022->cur_cs, command);
        else
                pl022->cur_chip->cs_control(command);
@@ -464,9 +496,8 @@ static void giveback(struct pl022 *pl022)
        struct spi_transfer *last_transfer;
        pl022->next_msg_cs_active = false;
 
-       last_transfer = list_entry(pl022->cur_msg->transfers.prev,
-                                       struct spi_transfer,
-                                       transfer_list);
+       last_transfer = list_last_entry(&pl022->cur_msg->transfers,
+                                       struct spi_transfer, transfer_list);
 
        /* Delay if requested before any change in chip select */
        if (last_transfer->delay_usecs)
@@ -1117,10 +1148,8 @@ static int pl022_dma_probe(struct pl022 *pl022)
        }
 
        pl022->dummypage = kmalloc(PAGE_SIZE, GFP_KERNEL);
-       if (!pl022->dummypage) {
-               dev_dbg(&pl022->adev->dev, "no DMA dummypage!\n");
+       if (!pl022->dummypage)
                goto err_no_dummypage;
-       }
 
        dev_info(&pl022->adev->dev, "setup for DMA on RX %s, TX %s\n",
                 dma_chan_name(pl022->dma_rx_channel),
@@ -1142,19 +1171,31 @@ err_no_rxchan:
 static int pl022_dma_autoprobe(struct pl022 *pl022)
 {
        struct device *dev = &pl022->adev->dev;
+       struct dma_chan *chan;
+       int err;
 
        /* automatically configure DMA channels from platform, normally using DT */
-       pl022->dma_rx_channel = dma_request_slave_channel(dev, "rx");
-       if (!pl022->dma_rx_channel)
+       chan = dma_request_slave_channel_reason(dev, "rx");
+       if (IS_ERR(chan)) {
+               err = PTR_ERR(chan);
                goto err_no_rxchan;
+       }
+
+       pl022->dma_rx_channel = chan;
 
-       pl022->dma_tx_channel = dma_request_slave_channel(dev, "tx");
-       if (!pl022->dma_tx_channel)
+       chan = dma_request_slave_channel_reason(dev, "tx");
+       if (IS_ERR(chan)) {
+               err = PTR_ERR(chan);
                goto err_no_txchan;
+       }
+
+       pl022->dma_tx_channel = chan;
 
        pl022->dummypage = kmalloc(PAGE_SIZE, GFP_KERNEL);
-       if (!pl022->dummypage)
+       if (!pl022->dummypage) {
+               err = -ENOMEM;
                goto err_no_dummypage;
+       }
 
        return 0;
 
@@ -1165,7 +1206,7 @@ err_no_txchan:
        dma_release_channel(pl022->dma_rx_channel);
        pl022->dma_rx_channel = NULL;
 err_no_rxchan:
-       return -ENODEV;
+       return err;
 }
                
 static void terminate_dma(struct pl022 *pl022)
@@ -1227,7 +1268,6 @@ static irqreturn_t pl022_interrupt_handler(int irq, void *dev_id)
        struct pl022 *pl022 = dev_id;
        struct spi_message *msg = pl022->cur_msg;
        u16 irq_status = 0;
-       u16 flag = 0;
 
        if (unlikely(!msg)) {
                dev_err(&pl022->adev->dev,
@@ -1256,9 +1296,6 @@ static irqreturn_t pl022_interrupt_handler(int irq, void *dev_id)
                if (readw(SSP_SR(pl022->virtbase)) & SSP_SR_MASK_RFF)
                        dev_err(&pl022->adev->dev,
                                "RXFIFO is full\n");
-               if (readw(SSP_SR(pl022->virtbase)) & SSP_SR_MASK_TNF)
-                       dev_err(&pl022->adev->dev,
-                               "TXFIFO is full\n");
 
                /*
                 * Disable and clear interrupts, disable SSP,
@@ -1279,8 +1316,7 @@ static irqreturn_t pl022_interrupt_handler(int irq, void *dev_id)
 
        readwriter(pl022);
 
-       if ((pl022->tx == pl022->tx_end) && (flag == 0)) {
-               flag = 1;
+       if (pl022->tx == pl022->tx_end) {
                /* Disable Transmit interrupt, enable receive interrupt */
                writew((readw(SSP_IMSC(pl022->virtbase)) &
                       ~SSP_IMSC_MASK_TXIM) | SSP_IMSC_MASK_RXIM,
@@ -1425,7 +1461,7 @@ static void do_interrupt_dma_transfer(struct pl022 *pl022)
         * Default is to enable all interrupts except RX -
         * this will be enabled once TX is complete
         */
-       u32 irqflags = ENABLE_ALL_INTERRUPTS & ~SSP_IMSC_MASK_RXIM;
+       u32 irqflags = (u32)(ENABLE_ALL_INTERRUPTS & ~SSP_IMSC_MASK_RXIM);
 
        /* Enable target chip, if not already active */
        if (!pl022->next_msg_cs_active)
@@ -1560,18 +1596,6 @@ static int pl022_transfer_one_message(struct spi_master *master,
        return 0;
 }
 
-static int pl022_prepare_transfer_hardware(struct spi_master *master)
-{
-       struct pl022 *pl022 = spi_master_get_devdata(master);
-
-       /*
-        * Just make sure we have all we need to run the transfer by syncing
-        * with the runtime PM framework.
-        */
-       pm_runtime_get_sync(&pl022->adev->dev);
-       return 0;
-}
-
 static int pl022_unprepare_transfer_hardware(struct spi_master *master)
 {
        struct pl022 *pl022 = spi_master_get_devdata(master);
@@ -1580,13 +1604,6 @@ static int pl022_unprepare_transfer_hardware(struct spi_master *master)
        writew((readw(SSP_CR1(pl022->virtbase)) &
                (~SSP_CR1_MASK_SSE)), SSP_CR1(pl022->virtbase));
 
-       if (pl022->master_info->autosuspend_delay > 0) {
-               pm_runtime_mark_last_busy(&pl022->adev->dev);
-               pm_runtime_put_autosuspend(&pl022->adev->dev);
-       } else {
-               pm_runtime_put(&pl022->adev->dev);
-       }
-
        return 0;
 }
 
@@ -1643,7 +1660,6 @@ static int verify_controller_parameters(struct pl022 *pl022,
                dev_err(&pl022->adev->dev,
                        "RX FIFO Trigger Level is configured incorrectly\n");
                return -EINVAL;
-               break;
        }
        switch (chip_info->tx_lev_trig) {
        case SSP_TX_1_OR_MORE_EMPTY_LOC:
@@ -1669,7 +1685,6 @@ static int verify_controller_parameters(struct pl022 *pl022,
                dev_err(&pl022->adev->dev,
                        "TX FIFO Trigger Level is configured incorrectly\n");
                return -EINVAL;
-               break;
        }
        if (chip_info->iface == SSP_INTERFACE_NATIONAL_MICROWIRE) {
                if ((chip_info->ctrl_len < SSP_BITS_4)
@@ -1836,11 +1851,8 @@ static int pl022_setup(struct spi_device *spi)
 
        if (chip == NULL) {
                chip = kzalloc(sizeof(struct chip_data), GFP_KERNEL);
-               if (!chip) {
-                       dev_err(&spi->dev,
-                               "cannot allocate controller state\n");
+               if (!chip)
                        return -ENOMEM;
-               }
                dev_dbg(&spi->dev,
                        "allocated memory for controller's runtime state\n");
        }
@@ -2077,12 +2089,11 @@ pl022_platform_data_dt_get(struct device *dev)
        }
 
        pd = devm_kzalloc(dev, sizeof(struct pl022_ssp_controller), GFP_KERNEL);
-       if (!pd) {
-               dev_err(dev, "cannot allocate platform data memory\n");
+       if (!pd)
                return NULL;
-       }
 
        pd->bus_id = -1;
+       pd->enable_dma = 1;
        of_property_read_u32(np, "num-cs", &tmp);
        pd->num_chipselect = tmp;
        of_property_read_u32(np, "pl022,autosuspend-delay",
@@ -2095,7 +2106,8 @@ pl022_platform_data_dt_get(struct device *dev)
 static int pl022_probe(struct amba_device *adev, const struct amba_id *id)
 {
        struct device *dev = &adev->dev;
-       struct pl022_ssp_controller *platform_info = adev->dev.platform_data;
+       struct pl022_ssp_controller *platform_info =
+                       dev_get_platdata(&adev->dev);
        struct spi_master *master;
        struct pl022 *pl022 = NULL;     /*Data for this driver */
        struct device_node *np = adev->dev.of_node;
@@ -2132,34 +2144,11 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id)
        pl022->vendor = id->data;
        pl022->chipselects = devm_kzalloc(dev, num_cs * sizeof(int),
                                          GFP_KERNEL);
-
-       pl022->pinctrl = devm_pinctrl_get(dev);
-       if (IS_ERR(pl022->pinctrl)) {
-               status = PTR_ERR(pl022->pinctrl);
-               goto err_no_pinctrl;
+       if (!pl022->chipselects) {
+               status = -ENOMEM;
+               goto err_no_mem;
        }
 
-       pl022->pins_default = pinctrl_lookup_state(pl022->pinctrl,
-                                                PINCTRL_STATE_DEFAULT);
-       /* enable pins to be muxed in and configured */
-       if (!IS_ERR(pl022->pins_default)) {
-               status = pinctrl_select_state(pl022->pinctrl,
-                               pl022->pins_default);
-               if (status)
-                       dev_err(dev, "could not set default pins\n");
-       } else
-               dev_err(dev, "could not get default pinstate\n");
-
-       pl022->pins_idle = pinctrl_lookup_state(pl022->pinctrl,
-                                             PINCTRL_STATE_IDLE);
-       if (IS_ERR(pl022->pins_idle))
-               dev_dbg(dev, "could not get idle pinstate\n");
-
-       pl022->pins_sleep = pinctrl_lookup_state(pl022->pinctrl,
-                                              PINCTRL_STATE_SLEEP);
-       if (IS_ERR(pl022->pins_sleep))
-               dev_dbg(dev, "could not get sleep pinstate\n");
-
        /*
         * Bus Number Which has been Assigned to this SSP controller
         * on this board
@@ -2168,7 +2157,7 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id)
        master->num_chipselect = num_cs;
        master->cleanup = pl022_cleanup;
        master->setup = pl022_setup;
-       master->prepare_transfer_hardware = pl022_prepare_transfer_hardware;
+       master->auto_runtime_pm = true;
        master->transfer_one_message = pl022_transfer_one_message;
        master->unprepare_transfer_hardware = pl022_unprepare_transfer_hardware;
        master->rt = platform_info->rt;
@@ -2177,6 +2166,9 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id)
        if (platform_info->num_chipselect && platform_info->chipselects) {
                for (i = 0; i < num_cs; i++)
                        pl022->chipselects[i] = platform_info->chipselects[i];
+       } else if (pl022->vendor->internal_cs_ctrl) {
+               for (i = 0; i < num_cs; i++)
+                       pl022->chipselects[i] = i;
        } else if (IS_ENABLED(CONFIG_OF)) {
                for (i = 0; i < num_cs; i++) {
                        int cs_gpio = of_get_named_gpio(np, "cs-gpios", i);
@@ -2195,7 +2187,7 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id)
                                                cs_gpio);
                                else if (gpio_direction_output(cs_gpio, 1))
                                        dev_err(&adev->dev,
-                                               "could set gpio %d as output\n",
+                                               "could not set gpio %d as output\n",
                                                cs_gpio);
                        }
                }
@@ -2222,8 +2214,8 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id)
                status = -ENOMEM;
                goto err_no_ioremap;
        }
-       printk(KERN_INFO "pl022: mapped registers from 0x%08x to %p\n",
-              adev->res.start, pl022->virtbase);
+       dev_info(&adev->dev, "mapped registers from %pa to %p\n",
+               &adev->res.start, pl022->virtbase);
 
        pl022->clk = devm_clk_get(&adev->dev, NULL);
        if (IS_ERR(pl022->clk)) {
@@ -2232,13 +2224,7 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id)
                goto err_no_clk;
        }
 
-       status = clk_prepare(pl022->clk);
-       if (status) {
-               dev_err(&adev->dev, "could not prepare SSP/SPI bus clock\n");
-               goto  err_clk_prep;
-       }
-
-       status = clk_enable(pl022->clk);
+       status = clk_prepare_enable(pl022->clk);
        if (status) {
                dev_err(&adev->dev, "could not enable SSP/SPI bus clock\n");
                goto err_no_clk_en;
@@ -2262,6 +2248,10 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id)
 
        /* Get DMA channels, try autoconfiguration first */
        status = pl022_dma_autoprobe(pl022);
+       if (status == -EPROBE_DEFER) {
+               dev_dbg(dev, "deferring probe to get DMA channel\n");
+               goto err_no_irq;
+       }
 
        /* If that failed, use channels from platform_info */
        if (status == 0)
@@ -2274,7 +2264,7 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id)
 
        /* Register with the SPI framework */
        amba_set_drvdata(adev, pl022);
-       status = spi_register_master(master);
+       status = devm_spi_register_master(&adev->dev, master);
        if (status != 0) {
                dev_err(&adev->dev,
                        "probe - problem registering spi master\n");
@@ -2299,16 +2289,14 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id)
        if (platform_info->enable_dma)
                pl022_dma_remove(pl022);
  err_no_irq:
-       clk_disable(pl022->clk);
+       clk_disable_unprepare(pl022->clk);
  err_no_clk_en:
-       clk_unprepare(pl022->clk);
- err_clk_prep:
  err_no_clk:
  err_no_ioremap:
        amba_release_regions(adev);
  err_no_ioregion:
  err_no_gpio:
- err_no_pinctrl:
+ err_no_mem:
        spi_master_put(master);
        return status;
 }
@@ -2331,67 +2319,13 @@ pl022_remove(struct amba_device *adev)
        if (pl022->master_info->enable_dma)
                pl022_dma_remove(pl022);
 
-       clk_disable(pl022->clk);
-       clk_unprepare(pl022->clk);
+       clk_disable_unprepare(pl022->clk);
        amba_release_regions(adev);
        tasklet_disable(&pl022->pump_transfers);
-       spi_unregister_master(pl022->master);
-       amba_set_drvdata(adev, NULL);
        return 0;
 }
 
-#if defined(CONFIG_SUSPEND) || defined(CONFIG_PM_RUNTIME)
-/*
- * These two functions are used from both suspend/resume and
- * the runtime counterparts to handle external resources like
- * clocks, pins and regulators when going to sleep.
- */
-static void pl022_suspend_resources(struct pl022 *pl022, bool runtime)
-{
-       int ret;
-       struct pinctrl_state *pins_state;
-
-       clk_disable(pl022->clk);
-
-       pins_state = runtime ? pl022->pins_idle : pl022->pins_sleep;
-       /* Optionally let pins go into sleep states */
-       if (!IS_ERR(pins_state)) {
-               ret = pinctrl_select_state(pl022->pinctrl, pins_state);
-               if (ret)
-                       dev_err(&pl022->adev->dev, "could not set %s pins\n",
-                               runtime ? "idle" : "sleep");
-       }
-}
-
-static void pl022_resume_resources(struct pl022 *pl022, bool runtime)
-{
-       int ret;
-
-       /* Optionaly enable pins to be muxed in and configured */
-       /* First go to the default state */
-       if (!IS_ERR(pl022->pins_default)) {
-               ret = pinctrl_select_state(pl022->pinctrl, pl022->pins_default);
-               if (ret)
-                       dev_err(&pl022->adev->dev,
-                               "could not set default pins\n");
-       }
-
-       if (!runtime) {
-               /* Then let's idle the pins until the next transfer happens */
-               if (!IS_ERR(pl022->pins_idle)) {
-                       ret = pinctrl_select_state(pl022->pinctrl,
-                                       pl022->pins_idle);
-               if (ret)
-                       dev_err(&pl022->adev->dev,
-                               "could not set idle pins\n");
-               }
-       }
-
-       clk_enable(pl022->clk);
-}
-#endif
-
-#ifdef CONFIG_SUSPEND
+#ifdef CONFIG_PM_SLEEP
 static int pl022_suspend(struct device *dev)
 {
        struct pl022 *pl022 = dev_get_drvdata(dev);
@@ -2403,8 +2337,13 @@ static int pl022_suspend(struct device *dev)
                return ret;
        }
 
-       pm_runtime_get_sync(dev);
-       pl022_suspend_resources(pl022, false);
+       ret = pm_runtime_force_suspend(dev);
+       if (ret) {
+               spi_master_resume(pl022->master);
+               return ret;
+       }
+
+       pinctrl_pm_select_sleep_state(dev);
 
        dev_dbg(dev, "suspended\n");
        return 0;
@@ -2415,8 +2354,9 @@ static int pl022_resume(struct device *dev)
        struct pl022 *pl022 = dev_get_drvdata(dev);
        int ret;
 
-       pl022_resume_resources(pl022, false);
-       pm_runtime_put(dev);
+       ret = pm_runtime_force_resume(dev);
+       if (ret)
+               dev_err(dev, "problem resuming\n");
 
        /* Start the queue running */
        ret = spi_master_resume(pl022->master);
@@ -2427,14 +2367,16 @@ static int pl022_resume(struct device *dev)
 
        return ret;
 }
-#endif /* CONFIG_PM */
+#endif
 
-#ifdef CONFIG_PM_RUNTIME
+#ifdef CONFIG_PM
 static int pl022_runtime_suspend(struct device *dev)
 {
        struct pl022 *pl022 = dev_get_drvdata(dev);
 
-       pl022_suspend_resources(pl022, true);
+       clk_disable_unprepare(pl022->clk);
+       pinctrl_pm_select_idle_state(dev);
+
        return 0;
 }
 
@@ -2442,7 +2384,9 @@ static int pl022_runtime_resume(struct device *dev)
 {
        struct pl022 *pl022 = dev_get_drvdata(dev);
 
-       pl022_resume_resources(pl022, true);
+       pinctrl_pm_select_default_state(dev);
+       clk_prepare_enable(pl022->clk);
+
        return 0;
 }
 #endif
@@ -2459,6 +2403,7 @@ static struct vendor_data vendor_arm = {
        .extended_cr = false,
        .pl023 = false,
        .loopback = true,
+       .internal_cs_ctrl = false,
 };
 
 static struct vendor_data vendor_st = {
@@ -2468,6 +2413,7 @@ static struct vendor_data vendor_st = {
        .extended_cr = true,
        .pl023 = false,
        .loopback = true,
+       .internal_cs_ctrl = false,
 };
 
 static struct vendor_data vendor_st_pl023 = {
@@ -2477,6 +2423,17 @@ static struct vendor_data vendor_st_pl023 = {
        .extended_cr = true,
        .pl023 = true,
        .loopback = false,
+       .internal_cs_ctrl = false,
+};
+
+static struct vendor_data vendor_lsi = {
+       .fifodepth = 8,
+       .max_bpw = 16,
+       .unidir = false,
+       .extended_cr = false,
+       .pl023 = false,
+       .loopback = true,
+       .internal_cs_ctrl = true,
 };
 
 static struct amba_id pl022_ids[] = {
@@ -2510,6 +2467,15 @@ static struct amba_id pl022_ids[] = {
                .mask   = 0xffffffff,
                .data   = &vendor_st_pl023,
        },
+       {
+               /*
+                * PL022 variant that has a chip select control register whih
+                * allows control of 5 output signals nCS[0:4].
+                */
+               .id     = 0x000b6022,
+               .mask   = 0x000fffff,
+               .data   = &vendor_lsi,
+       },
        { 0, 0 },
 };