diff options
author | Axel Lin <axel.lin@ingics.com> | 2014-02-18 04:15:54 -0500 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2014-02-19 18:37:51 -0500 |
commit | bf5c2e27036cffda6e20f445391a4d4e1ccc232e (patch) | |
tree | ca66006b7dd2fed4a384d620fce38e2988eb472c | |
parent | 3e9ea4b4d51d6fce449427bb411debaa4d52397d (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.c | 82 |
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 | ||
27 | struct spi_clps711x_data { | 27 | struct 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 | ||
47 | static 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 | |||
56 | static void spi_clps711x_setup_xfer(struct spi_device *spi, | 45 | static 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 | ||
77 | static int spi_clps711x_transfer_one_message(struct spi_master *master, | 66 | static 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 || | 80 | static 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 | ||
123 | static irqreturn_t spi_clps711x_isr(int irq, void *dev_id) | 100 | static 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; |