aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAxel Lin <axel.lin@ingics.com>2014-02-18 04:15:54 -0500
committerMark Brown <broonie@linaro.org>2014-02-19 18:37:51 -0500
commitbf5c2e27036cffda6e20f445391a4d4e1ccc232e (patch)
treeca66006b7dd2fed4a384d620fce38e2988eb472c
parent3e9ea4b4d51d6fce449427bb411debaa4d52397d (diff)
spi: clps711x: Refactor to use core message parsing
Convert to use default implementation of transfer_one_message() which provides standard handling of delays and chip select management. Signed-off-by: Axel Lin <axel.lin@ingics.com> Tested-by: Alexander Shiyan <shc_work@mail.ru> Signed-off-by: Mark Brown <broonie@linaro.org>
-rw-r--r--drivers/spi/spi-clps711x.c82
1 files changed, 30 insertions, 52 deletions
diff --git a/drivers/spi/spi-clps711x.c b/drivers/spi/spi-clps711x.c
index df086ee4cdaa..eda7472ceefa 100644
--- a/drivers/spi/spi-clps711x.c
+++ b/drivers/spi/spi-clps711x.c
@@ -25,8 +25,6 @@
25#define DRIVER_NAME "spi-clps711x" 25#define DRIVER_NAME "spi-clps711x"
26 26
27struct spi_clps711x_data { 27struct spi_clps711x_data {
28 struct completion done;
29
30 struct clk *spi_clk; 28 struct clk *spi_clk;
31 u32 max_speed_hz; 29 u32 max_speed_hz;
32 30
@@ -44,15 +42,6 @@ static int spi_clps711x_setup(struct spi_device *spi)
44 return 0; 42 return 0;
45} 43}
46 44
47static void spi_clps711x_setup_mode(struct spi_device *spi)
48{
49 /* Setup edge for transfer */
50 if (spi->mode & SPI_CPHA)
51 clps_writew(clps_readw(SYSCON3) | SYSCON3_ADCCKNSEN, SYSCON3);
52 else
53 clps_writew(clps_readw(SYSCON3) & ~SYSCON3_ADCCKNSEN, SYSCON3);
54}
55
56static void spi_clps711x_setup_xfer(struct spi_device *spi, 45static void spi_clps711x_setup_xfer(struct spi_device *spi,
57 struct spi_transfer *xfer) 46 struct spi_transfer *xfer)
58{ 47{
@@ -74,55 +63,44 @@ static void spi_clps711x_setup_xfer(struct spi_device *spi,
74 SYSCON1_ADCKSEL(0), SYSCON1); 63 SYSCON1_ADCKSEL(0), SYSCON1);
75} 64}
76 65
77static int spi_clps711x_transfer_one_message(struct spi_master *master, 66static int spi_clps711x_prepare_message(struct spi_master *master,
78 struct spi_message *msg) 67 struct spi_message *msg)
79{ 68{
80 struct spi_clps711x_data *hw = spi_master_get_devdata(master);
81 struct spi_device *spi = msg->spi; 69 struct spi_device *spi = msg->spi;
82 struct spi_transfer *xfer;
83
84 spi_clps711x_setup_mode(spi);
85
86 list_for_each_entry(xfer, &msg->transfers, transfer_list) {
87 u8 data;
88
89 spi_clps711x_setup_xfer(spi, xfer);
90 70
91 gpio_set_value(spi->cs_gpio, !!(spi->mode & SPI_CS_HIGH)); 71 /* Setup edge for transfer */
92 72 if (spi->mode & SPI_CPHA)
93 reinit_completion(&hw->done); 73 clps_writew(clps_readw(SYSCON3) | SYSCON3_ADCCKNSEN, SYSCON3);
94 74 else
95 hw->len = xfer->len; 75 clps_writew(clps_readw(SYSCON3) & ~SYSCON3_ADCCKNSEN, SYSCON3);
96 hw->bpw = xfer->bits_per_word ? : spi->bits_per_word;
97 hw->tx_buf = (u8 *)xfer->tx_buf;
98 hw->rx_buf = (u8 *)xfer->rx_buf;
99
100 /* Initiate transfer */
101 data = hw->tx_buf ? *hw->tx_buf++ : 0;
102 clps_writel(data | SYNCIO_FRMLEN(hw->bpw) | SYNCIO_TXFRMEN,
103 SYNCIO);
104
105 wait_for_completion(&hw->done);
106 76
107 if (xfer->delay_usecs) 77 return 0;
108 udelay(xfer->delay_usecs); 78}
109 79
110 if (xfer->cs_change || 80static int spi_clps711x_transfer_one(struct spi_master *master,
111 list_is_last(&xfer->transfer_list, &msg->transfers)) 81 struct spi_device *spi,
112 gpio_set_value(spi->cs_gpio, !(spi->mode & SPI_CS_HIGH)); 82 struct spi_transfer *xfer)
83{
84 struct spi_clps711x_data *hw = spi_master_get_devdata(master);
85 u8 data;
113 86
114 msg->actual_length += xfer->len; 87 spi_clps711x_setup_xfer(spi, xfer);
115 }
116 88
117 msg->status = 0; 89 hw->len = xfer->len;
118 spi_finalize_current_message(master); 90 hw->bpw = xfer->bits_per_word ? : spi->bits_per_word;
91 hw->tx_buf = (u8 *)xfer->tx_buf;
92 hw->rx_buf = (u8 *)xfer->rx_buf;
119 93
120 return 0; 94 /* Initiate transfer */
95 data = hw->tx_buf ? *hw->tx_buf++ : 0;
96 clps_writel(data | SYNCIO_FRMLEN(hw->bpw) | SYNCIO_TXFRMEN, SYNCIO);
97 return 1;
121} 98}
122 99
123static irqreturn_t spi_clps711x_isr(int irq, void *dev_id) 100static irqreturn_t spi_clps711x_isr(int irq, void *dev_id)
124{ 101{
125 struct spi_clps711x_data *hw = (struct spi_clps711x_data *)dev_id; 102 struct spi_master *master = dev_id;
103 struct spi_clps711x_data *hw = spi_master_get_devdata(master);
126 u8 data; 104 u8 data;
127 105
128 /* Handle RX */ 106 /* Handle RX */
@@ -136,7 +114,7 @@ static irqreturn_t spi_clps711x_isr(int irq, void *dev_id)
136 clps_writel(data | SYNCIO_FRMLEN(hw->bpw) | SYNCIO_TXFRMEN, 114 clps_writel(data | SYNCIO_FRMLEN(hw->bpw) | SYNCIO_TXFRMEN,
137 SYNCIO); 115 SYNCIO);
138 } else 116 } else
139 complete(&hw->done); 117 spi_finalize_current_transfer(master);
140 118
141 return IRQ_HANDLED; 119 return IRQ_HANDLED;
142} 120}
@@ -174,7 +152,8 @@ static int spi_clps711x_probe(struct platform_device *pdev)
174 master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 8); 152 master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 8);
175 master->num_chipselect = pdata->num_chipselect; 153 master->num_chipselect = pdata->num_chipselect;
176 master->setup = spi_clps711x_setup; 154 master->setup = spi_clps711x_setup;
177 master->transfer_one_message = spi_clps711x_transfer_one_message; 155 master->prepare_message = spi_clps711x_prepare_message;
156 master->transfer_one = spi_clps711x_transfer_one;
178 157
179 hw = spi_master_get_devdata(master); 158 hw = spi_master_get_devdata(master);
180 159
@@ -200,7 +179,6 @@ static int spi_clps711x_probe(struct platform_device *pdev)
200 } 179 }
201 hw->max_speed_hz = clk_get_rate(hw->spi_clk); 180 hw->max_speed_hz = clk_get_rate(hw->spi_clk);
202 181
203 init_completion(&hw->done);
204 platform_set_drvdata(pdev, master); 182 platform_set_drvdata(pdev, master);
205 183
206 /* Disable extended mode due hardware problems */ 184 /* Disable extended mode due hardware problems */
@@ -210,7 +188,7 @@ static int spi_clps711x_probe(struct platform_device *pdev)
210 clps_readl(SYNCIO); 188 clps_readl(SYNCIO);
211 189
212 ret = devm_request_irq(&pdev->dev, IRQ_SSEOTI, spi_clps711x_isr, 0, 190 ret = devm_request_irq(&pdev->dev, IRQ_SSEOTI, spi_clps711x_isr, 0,
213 dev_name(&pdev->dev), hw); 191 dev_name(&pdev->dev), master);
214 if (ret) { 192 if (ret) {
215 dev_err(&pdev->dev, "Can't request IRQ\n"); 193 dev_err(&pdev->dev, "Can't request IRQ\n");
216 goto err_out; 194 goto err_out;