]> Pileus Git - ~andy/linux/blobdiff - drivers/spi/spi-pl022.c
Merge branches 'sched-urgent-for-linus', 'perf-urgent-for-linus' and 'x86-urgent...
[~andy/linux] / drivers / spi / spi-pl022.c
index 1ab2fa0d37fd7d0d6dea52e0dd801cbd8a4cea52..2f9cb43a239870b6db396b8507fb6a67893f1f37 100644 (file)
 #define SSP_CR0_MASK_CSS_ST    (0x1FUL << 16)
 #define SSP_CR0_MASK_FRF_ST    (0x3UL << 21)
 
-
 /*
  * SSP Control Register 0  - SSP_CR1
  */
 
 #define SPI_POLLING_TIMEOUT 1000
 
-
 /*
  * The type of reading going on on this chip
  */
@@ -342,6 +340,10 @@ struct vendor_data {
  * @cur_msg: Pointer to current spi_message being processed
  * @cur_transfer: Pointer to current spi_transfer
  * @cur_chip: pointer to current clients chip(assigned from controller_state)
+ * @next_msg_cs_active: the next message in the queue has been examined
+ *  and it was found that it uses the same chip select as the previous
+ *  message, so we left it active after the previous transfer, and it's
+ *  active already.
  * @tx: current position in TX buffer to be read
  * @tx_end: end position in TX buffer to be read
  * @rx: current position in RX buffer to be written
@@ -375,6 +377,7 @@ struct pl022 {
        struct spi_message              *cur_msg;
        struct spi_transfer             *cur_transfer;
        struct chip_data                *cur_chip;
+       bool                            next_msg_cs_active;
        void                            *tx;
        void                            *tx_end;
        void                            *rx;
@@ -447,23 +450,9 @@ static void giveback(struct pl022 *pl022)
        struct spi_transfer *last_transfer;
        unsigned long flags;
        struct spi_message *msg;
-       void (*curr_cs_control) (u32 command);
-
-       /*
-        * This local reference to the chip select function
-        * is needed because we set curr_chip to NULL
-        * as a step toward termininating the message.
-        */
-       curr_cs_control = pl022->cur_chip->cs_control;
-       spin_lock_irqsave(&pl022->queue_lock, flags);
-       msg = pl022->cur_msg;
-       pl022->cur_msg = NULL;
-       pl022->cur_transfer = NULL;
-       pl022->cur_chip = NULL;
-       queue_work(pl022->workqueue, &pl022->pump_messages);
-       spin_unlock_irqrestore(&pl022->queue_lock, flags);
+       pl022->next_msg_cs_active = false;
 
-       last_transfer = list_entry(msg->transfers.prev,
+       last_transfer = list_entry(pl022->cur_msg->transfers.prev,
                                        struct spi_transfer,
                                        transfer_list);
 
@@ -475,18 +464,13 @@ static void giveback(struct pl022 *pl022)
                 */
                udelay(last_transfer->delay_usecs);
 
-       /*
-        * Drop chip select UNLESS cs_change is true or we are returning
-        * a message with an error, or next message is for another chip
-        */
-       if (!last_transfer->cs_change)
-               curr_cs_control(SSP_CHIP_DESELECT);
-       else {
+       if (!last_transfer->cs_change) {
                struct spi_message *next_msg;
 
-               /* Holding of cs was hinted, but we need to make sure
-                * the next message is for the same chip.  Don't waste
-                * time with the following tests unless this was hinted.
+               /*
+                * cs_change was not set. We can keep the chip select
+                * enabled if there is message in the queue and it is
+                * for the same spi device.
                 *
                 * We cannot postpone this until pump_messages, because
                 * after calling msg->complete (below) the driver that
@@ -503,19 +487,29 @@ static void giveback(struct pl022 *pl022)
                                        struct spi_message, queue);
                spin_unlock_irqrestore(&pl022->queue_lock, flags);
 
-               /* see if the next and current messages point
-                * to the same chip
+               /*
+                * see if the next and current messages point
+                * to the same spi device.
                 */
-               if (next_msg && next_msg->spi != msg->spi)
+               if (next_msg && next_msg->spi != pl022->cur_msg->spi)
                        next_msg = NULL;
-               if (!next_msg || msg->state == STATE_ERROR)
-                       curr_cs_control(SSP_CHIP_DESELECT);
+               if (!next_msg || pl022->cur_msg->state == STATE_ERROR)
+                       pl022->cur_chip->cs_control(SSP_CHIP_DESELECT);
+               else
+                       pl022->next_msg_cs_active = true;
        }
+
+       spin_lock_irqsave(&pl022->queue_lock, flags);
+       msg = pl022->cur_msg;
+       pl022->cur_msg = NULL;
+       pl022->cur_transfer = NULL;
+       pl022->cur_chip = NULL;
+       queue_work(pl022->workqueue, &pl022->pump_messages);
+       spin_unlock_irqrestore(&pl022->queue_lock, flags);
+
        msg->state = NULL;
        if (msg->complete)
                msg->complete(msg->context);
-       /* This message is completed, so let's turn off the clocks & power */
-       pm_runtime_put(&pl022->adev->dev);
 }
 
 /**
@@ -749,7 +743,6 @@ static void readwriter(struct pl022 *pl022)
         */
 }
 
-
 /**
  * next_transfer - Move to the Next transfer in the current spi message
  * @pl022: SSP driver private data structure
@@ -907,11 +900,11 @@ static int configure_dma(struct pl022 *pl022)
 {
        struct dma_slave_config rx_conf = {
                .src_addr = SSP_DR(pl022->phybase),
-               .direction = DMA_FROM_DEVICE,
+               .direction = DMA_DEV_TO_MEM,
        };
        struct dma_slave_config tx_conf = {
                .dst_addr = SSP_DR(pl022->phybase),
-               .direction = DMA_TO_DEVICE,
+               .direction = DMA_MEM_TO_DEV,
        };
        unsigned int pages;
        int ret;
@@ -1016,14 +1009,14 @@ static int configure_dma(struct pl022 *pl022)
        dmaengine_slave_config(txchan, &tx_conf);
 
        /* Create sglists for the transfers */
-       pages = (pl022->cur_transfer->len >> PAGE_SHIFT) + 1;
+       pages = DIV_ROUND_UP(pl022->cur_transfer->len, PAGE_SIZE);
        dev_dbg(&pl022->adev->dev, "using %d pages for transfer\n", pages);
 
-       ret = sg_alloc_table(&pl022->sgt_rx, pages, GFP_KERNEL);
+       ret = sg_alloc_table(&pl022->sgt_rx, pages, GFP_ATOMIC);
        if (ret)
                goto err_alloc_rx_sg;
 
-       ret = sg_alloc_table(&pl022->sgt_tx, pages, GFP_KERNEL);
+       ret = sg_alloc_table(&pl022->sgt_tx, pages, GFP_ATOMIC);
        if (ret)
                goto err_alloc_tx_sg;
 
@@ -1048,7 +1041,7 @@ static int configure_dma(struct pl022 *pl022)
        rxdesc = rxchan->device->device_prep_slave_sg(rxchan,
                                      pl022->sgt_rx.sgl,
                                      rx_sglen,
-                                     DMA_FROM_DEVICE,
+                                     DMA_DEV_TO_MEM,
                                      DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
        if (!rxdesc)
                goto err_rxdesc;
@@ -1056,7 +1049,7 @@ static int configure_dma(struct pl022 *pl022)
        txdesc = txchan->device->device_prep_slave_sg(txchan,
                                      pl022->sgt_tx.sgl,
                                      tx_sglen,
-                                     DMA_TO_DEVICE,
+                                     DMA_MEM_TO_DEV,
                                      DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
        if (!txdesc)
                goto err_txdesc;
@@ -1247,9 +1240,9 @@ static irqreturn_t pl022_interrupt_handler(int irq, void *dev_id)
 
        if ((pl022->tx == pl022->tx_end) && (flag == 0)) {
                flag = 1;
-               /* Disable Transmit interrupt */
-               writew(readw(SSP_IMSC(pl022->virtbase)) &
-                      (~SSP_IMSC_MASK_TXIM),
+               /* Disable Transmit interrupt, enable receive interrupt */
+               writew((readw(SSP_IMSC(pl022->virtbase)) &
+                      ~SSP_IMSC_MASK_TXIM) | SSP_IMSC_MASK_RXIM,
                       SSP_IMSC(pl022->virtbase));
        }
 
@@ -1355,7 +1348,7 @@ static void pump_transfers(unsigned long data)
                         */
                        udelay(previous->delay_usecs);
 
-               /* Drop chip select only if cs_change is requested */
+               /* Reselect chip select only if cs_change was requested */
                if (previous->cs_change)
                        pl022->cur_chip->cs_control(SSP_CHIP_SELECT);
        } else {
@@ -1382,15 +1375,22 @@ static void pump_transfers(unsigned long data)
        }
 
 err_config_dma:
-       writew(ENABLE_ALL_INTERRUPTS, SSP_IMSC(pl022->virtbase));
+       /* enable all interrupts except RX */
+       writew(ENABLE_ALL_INTERRUPTS & ~SSP_IMSC_MASK_RXIM, SSP_IMSC(pl022->virtbase));
 }
 
 static void do_interrupt_dma_transfer(struct pl022 *pl022)
 {
-       u32 irqflags = ENABLE_ALL_INTERRUPTS;
+       /*
+        * 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;
+
+       /* Enable target chip, if not already active */
+       if (!pl022->next_msg_cs_active)
+               pl022->cur_chip->cs_control(SSP_CHIP_SELECT);
 
-       /* Enable target chip */
-       pl022->cur_chip->cs_control(SSP_CHIP_SELECT);
        if (set_up_next_transfer(pl022, pl022->cur_transfer)) {
                /* Error path */
                pl022->cur_msg->state = STATE_ERROR;
@@ -1445,7 +1445,8 @@ static void do_polling_transfer(struct pl022 *pl022)
                } else {
                        /* STATE_START */
                        message->state = STATE_RUNNING;
-                       pl022->cur_chip->cs_control(SSP_CHIP_SELECT);
+                       if (!pl022->next_msg_cs_active)
+                               pl022->cur_chip->cs_control(SSP_CHIP_SELECT);
                }
 
                /* Configuration Changing Per Transfer */
@@ -1507,14 +1508,28 @@ static void pump_messages(struct work_struct *work)
        struct pl022 *pl022 =
                container_of(work, struct pl022, pump_messages);
        unsigned long flags;
+       bool was_busy = false;
 
        /* Lock queue and check for queue work */
        spin_lock_irqsave(&pl022->queue_lock, flags);
        if (list_empty(&pl022->queue) || !pl022->running) {
+               if (pl022->busy) {
+                       /* nothing more to do - disable spi/ssp and power off */
+                       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);
+                       }
+               }
                pl022->busy = false;
                spin_unlock_irqrestore(&pl022->queue_lock, flags);
                return;
        }
+
        /* Make sure we are not already running a message */
        if (pl022->cur_msg) {
                spin_unlock_irqrestore(&pl022->queue_lock, flags);
@@ -1525,23 +1540,27 @@ static void pump_messages(struct work_struct *work)
            list_entry(pl022->queue.next, struct spi_message, queue);
 
        list_del_init(&pl022->cur_msg->queue);
-       pl022->busy = true;
+       if (pl022->busy)
+               was_busy = true;
+       else
+               pl022->busy = true;
        spin_unlock_irqrestore(&pl022->queue_lock, flags);
 
        /* Initial message state */
        pl022->cur_msg->state = STATE_START;
        pl022->cur_transfer = list_entry(pl022->cur_msg->transfers.next,
-                                           struct spi_transfer,
-                                           transfer_list);
+                                           struct spi_transfer, transfer_list);
 
        /* Setup the SPI using the per chip configuration */
        pl022->cur_chip = spi_get_ctldata(pl022->cur_msg->spi);
-       /*
-        * We enable the core voltage and clocks here, then the clocks
-        * and core will be disabled when giveback() is called in each method
-        * (poll/interrupt/DMA)
-        */
-       pm_runtime_get_sync(&pl022->adev->dev);
+       if (!was_busy)
+               /*
+                * We enable the core voltage and clocks here, then the clocks
+                * and core will be disabled when this workqueue is run again
+                * and there is no more work to be done.
+                */
+               pm_runtime_get_sync(&pl022->adev->dev);
+
        restore_state(pl022);
        flush(pl022);
 
@@ -1551,7 +1570,6 @@ static void pump_messages(struct work_struct *work)
                do_interrupt_dma_transfer(pl022);
 }
 
-
 static int __init init_queue(struct pl022 *pl022)
 {
        INIT_LIST_HEAD(&pl022->queue);
@@ -1560,8 +1578,8 @@ static int __init init_queue(struct pl022 *pl022)
        pl022->running = false;
        pl022->busy = false;
 
-       tasklet_init(&pl022->pump_transfers,
-                       pump_transfers, (unsigned long)pl022);
+       tasklet_init(&pl022->pump_transfers, pump_transfers,
+                       (unsigned long)pl022);
 
        INIT_WORK(&pl022->pump_messages, pump_messages);
        pl022->workqueue = create_singlethread_workqueue(
@@ -1572,7 +1590,6 @@ static int __init init_queue(struct pl022 *pl022)
        return 0;
 }
 
-
 static int start_queue(struct pl022 *pl022)
 {
        unsigned long flags;
@@ -1588,6 +1605,7 @@ static int start_queue(struct pl022 *pl022)
        pl022->cur_msg = NULL;
        pl022->cur_transfer = NULL;
        pl022->cur_chip = NULL;
+       pl022->next_msg_cs_active = false;
        spin_unlock_irqrestore(&pl022->queue_lock, flags);
 
        queue_work(pl022->workqueue, &pl022->pump_messages);
@@ -1595,7 +1613,6 @@ static int start_queue(struct pl022 *pl022)
        return 0;
 }
 
-
 static int stop_queue(struct pl022 *pl022)
 {
        unsigned long flags;
@@ -1791,71 +1808,70 @@ static int pl022_transfer(struct spi_device *spi, struct spi_message *msg)
        return 0;
 }
 
-static int calculate_effective_freq(struct pl022 *pl022,
-                                   int freq,
-                                   struct ssp_clock_params *clk_freq)
+static inline u32 spi_rate(u32 rate, u16 cpsdvsr, u16 scr)
+{
+       return rate / (cpsdvsr * (1 + scr));
+}
+
+static int calculate_effective_freq(struct pl022 *pl022, int freq, struct
+                                   ssp_clock_params * clk_freq)
 {
        /* Lets calculate the frequency parameters */
-       u16 cpsdvsr = 2;
-       u16 scr = 0;
-       bool freq_found = false;
-       u32 rate;
-       u32 max_tclk;
-       u32 min_tclk;
+       u16 cpsdvsr = CPSDVR_MIN, scr = SCR_MIN;
+       u32 rate, max_tclk, min_tclk, best_freq = 0, best_cpsdvsr = 0,
+               best_scr = 0, tmp, found = 0;
 
        rate = clk_get_rate(pl022->clk);
        /* cpsdvscr = 2 & scr 0 */
-       max_tclk = (rate / (CPSDVR_MIN * (1 + SCR_MIN)));
+       max_tclk = spi_rate(rate, CPSDVR_MIN, SCR_MIN);
        /* cpsdvsr = 254 & scr = 255 */
-       min_tclk = (rate / (CPSDVR_MAX * (1 + SCR_MAX)));
-
-       if ((freq <= max_tclk) && (freq >= min_tclk)) {
-               while (cpsdvsr <= CPSDVR_MAX && !freq_found) {
-                       while (scr <= SCR_MAX && !freq_found) {
-                               if ((rate /
-                                    (cpsdvsr * (1 + scr))) > freq)
-                                       scr += 1;
-                               else {
-                                       /*
-                                        * This bool is made true when
-                                        * effective frequency >=
-                                        * target frequency is found
-                                        */
-                                       freq_found = true;
-                                       if ((rate /
-                                            (cpsdvsr * (1 + scr))) != freq) {
-                                               if (scr == SCR_MIN) {
-                                                       cpsdvsr -= 2;
-                                                       scr = SCR_MAX;
-                                               } else
-                                                       scr -= 1;
-                                       }
-                               }
-                       }
-                       if (!freq_found) {
-                               cpsdvsr += 2;
-                               scr = SCR_MIN;
-                       }
-               }
-               if (cpsdvsr != 0) {
-                       dev_dbg(&pl022->adev->dev,
-                               "SSP Effective Frequency is %u\n",
-                               (rate / (cpsdvsr * (1 + scr))));
-                       clk_freq->cpsdvsr = (u8) (cpsdvsr & 0xFF);
-                       clk_freq->scr = (u8) (scr & 0xFF);
-                       dev_dbg(&pl022->adev->dev,
-                               "SSP cpsdvsr = %d, scr = %d\n",
-                               clk_freq->cpsdvsr, clk_freq->scr);
-               }
-       } else {
+       min_tclk = spi_rate(rate, CPSDVR_MAX, SCR_MAX);
+
+       if (!((freq <= max_tclk) && (freq >= min_tclk))) {
                dev_err(&pl022->adev->dev,
                        "controller data is incorrect: out of range frequency");
                return -EINVAL;
        }
+
+       /*
+        * best_freq will give closest possible available rate (<= requested
+        * freq) for all values of scr & cpsdvsr.
+        */
+       while ((cpsdvsr <= CPSDVR_MAX) && !found) {
+               while (scr <= SCR_MAX) {
+                       tmp = spi_rate(rate, cpsdvsr, scr);
+
+                       if (tmp > freq)
+                               scr++;
+                       /*
+                        * If found exact value, update and break.
+                        * If found more closer value, update and continue.
+                        */
+                       else if ((tmp == freq) || (tmp > best_freq)) {
+                               best_freq = tmp;
+                               best_cpsdvsr = cpsdvsr;
+                               best_scr = scr;
+
+                               if (tmp == freq)
+                                       break;
+                       }
+                       scr++;
+               }
+               cpsdvsr += 2;
+               scr = SCR_MIN;
+       }
+
+       clk_freq->cpsdvsr = (u8) (best_cpsdvsr & 0xFF);
+       clk_freq->scr = (u8) (best_scr & 0xFF);
+       dev_dbg(&pl022->adev->dev,
+               "SSP Target Frequency is: %u, Effective Frequency is %u\n",
+               freq, best_freq);
+       dev_dbg(&pl022->adev->dev, "SSP cpsdvsr = %d, scr = %d\n",
+               clk_freq->cpsdvsr, clk_freq->scr);
+
        return 0;
 }
 
-
 /*
  * A piece of default chip info unless the platform
  * supplies it.
@@ -1873,7 +1889,6 @@ static const struct pl022_config_chip pl022_default_chip_info = {
        .cs_control = null_cs_control,
 };
 
-
 /**
  * pl022_setup - setup function registered to SPI master framework
  * @spi: spi device which is requesting setup
@@ -1890,7 +1905,7 @@ static int pl022_setup(struct spi_device *spi)
 {
        struct pl022_config_chip const *chip_info;
        struct chip_data *chip;
-       struct ssp_clock_params clk_freq = {0, };
+       struct ssp_clock_params clk_freq = { .cpsdvsr = 0, .scr = 0};
        int status = 0;
        struct pl022 *pl022 = spi_master_get_devdata(spi->master);
        unsigned int bits = spi->bits_per_word;
@@ -1950,7 +1965,6 @@ static int pl022_setup(struct spi_device *spi)
                goto err_config_params;
        }
 
-
        status = verify_controller_parameters(pl022, chip_info);
        if (status) {
                dev_err(&spi->dev, "controller data is incorrect");
@@ -2090,7 +2104,8 @@ static int pl022_setup(struct spi_device *spi)
        }
        SSP_WRITE_BITS(chip->cr1, SSP_DISABLED, SSP_CR1_MASK_SSE, 1);
        SSP_WRITE_BITS(chip->cr1, chip_info->hierarchy, SSP_CR1_MASK_MS, 2);
-       SSP_WRITE_BITS(chip->cr1, chip_info->slave_tx_disable, SSP_CR1_MASK_SOD, 3);
+       SSP_WRITE_BITS(chip->cr1, chip_info->slave_tx_disable, SSP_CR1_MASK_SOD,
+               3);
 
        /* Save controller_state */
        spi_set_ctldata(spi, chip);
@@ -2116,7 +2131,6 @@ static void pl022_cleanup(struct spi_device *spi)
        kfree(chip);
 }
 
-
 static int __devinit
 pl022_probe(struct amba_device *adev, const struct amba_id *id)
 {
@@ -2194,6 +2208,12 @@ pl022_probe(struct amba_device *adev, const struct amba_id *id)
                goto  err_clk_prep;
        }
 
+       status = clk_enable(pl022->clk);
+       if (status) {
+               dev_err(&adev->dev, "could not enable SSP/SPI bus clock\n");
+               goto err_no_clk_en;
+       }
+
        /* Disable SSP */
        writew((readw(SSP_CR1(pl022->virtbase)) & (~SSP_CR1_MASK_SSE)),
               SSP_CR1(pl022->virtbase));
@@ -2235,16 +2255,30 @@ pl022_probe(struct amba_device *adev, const struct amba_id *id)
        dev_dbg(dev, "probe succeeded\n");
 
        /* let runtime pm put suspend */
-       pm_runtime_put(dev);
+       if (platform_info->autosuspend_delay > 0) {
+               dev_info(&adev->dev,
+                       "will use autosuspend for runtime pm, delay %dms\n",
+                       platform_info->autosuspend_delay);
+               pm_runtime_set_autosuspend_delay(dev,
+                       platform_info->autosuspend_delay);
+               pm_runtime_use_autosuspend(dev);
+               pm_runtime_put_autosuspend(dev);
+       } else {
+               pm_runtime_put(dev);
+       }
        return 0;
 
  err_spi_register:
  err_start_queue:
  err_init_queue:
        destroy_queue(pl022);
-       pl022_dma_remove(pl022);
+       if (platform_info->enable_dma)
+               pl022_dma_remove(pl022);
+
        free_irq(adev->irq[0], pl022);
  err_no_irq:
+       clk_disable(pl022->clk);
+ err_no_clk_en:
        clk_unprepare(pl022->clk);
  err_clk_prep:
        clk_put(pl022->clk);
@@ -2277,7 +2311,9 @@ pl022_remove(struct amba_device *adev)
        if (destroy_queue(pl022) != 0)
                dev_err(&adev->dev, "queue remove failed\n");
        load_ssp_default_config(pl022);
-       pl022_dma_remove(pl022);
+       if (pl022->master_info->enable_dma)
+               pl022_dma_remove(pl022);
+
        free_irq(adev->irq[0], pl022);
        clk_disable(pl022->clk);
        clk_unprepare(pl022->clk);
@@ -2303,11 +2339,6 @@ static int pl022_suspend(struct device *dev)
                return status;
        }
 
-       amba_vcore_enable(pl022->adev);
-       amba_pclk_enable(pl022->adev);
-       load_ssp_default_config(pl022);
-       amba_pclk_disable(pl022->adev);
-       amba_vcore_disable(pl022->adev);
        dev_dbg(dev, "suspended\n");
        return 0;
 }
@@ -2364,7 +2395,6 @@ static struct vendor_data vendor_arm = {
        .loopback = true,
 };
 
-
 static struct vendor_data vendor_st = {
        .fifodepth = 32,
        .max_bpw = 32,
@@ -2419,9 +2449,9 @@ static struct amba_id pl022_ids[] = {
                 * and 32 locations deep TX/RX FIFO but no extended
                 * CR0/CR1 register
                 */
-               .id     = 0x00080023,
-               .mask   = 0xffffffff,
-               .data   = &vendor_st_pl023,
+               .id     = 0x00080023,
+               .mask   = 0xffffffff,
+               .data   = &vendor_st_pl023,
        },
        {
                .id     = 0x10080023,
@@ -2431,6 +2461,8 @@ static struct amba_id pl022_ids[] = {
        { 0, 0 },
 };
 
+MODULE_DEVICE_TABLE(amba, pl022_ids);
+
 static struct amba_driver pl022_driver = {
        .drv = {
                .name   = "ssp-pl022",
@@ -2441,19 +2473,16 @@ static struct amba_driver pl022_driver = {
        .remove         = __devexit_p(pl022_remove),
 };
 
-
 static int __init pl022_init(void)
 {
        return amba_driver_register(&pl022_driver);
 }
-
 subsys_initcall(pl022_init);
 
 static void __exit pl022_exit(void)
 {
        amba_driver_unregister(&pl022_driver);
 }
-
 module_exit(pl022_exit);
 
 MODULE_AUTHOR("Linus Walleij <linus.walleij@stericsson.com>");