diff options
Diffstat (limited to 'drivers/spi/spi-omap2-mcspi.c')
-rw-r--r-- | drivers/spi/spi-omap2-mcspi.c | 373 |
1 files changed, 159 insertions, 214 deletions
diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c index bb9274c2526d..46ef5fe51db5 100644 --- a/drivers/spi/spi-omap2-mcspi.c +++ b/drivers/spi/spi-omap2-mcspi.c | |||
@@ -44,9 +44,7 @@ | |||
44 | #include <plat/mcspi.h> | 44 | #include <plat/mcspi.h> |
45 | 45 | ||
46 | #define OMAP2_MCSPI_MAX_FREQ 48000000 | 46 | #define OMAP2_MCSPI_MAX_FREQ 48000000 |
47 | 47 | #define SPI_AUTOSUSPEND_TIMEOUT 2000 | |
48 | /* OMAP2 has 3 SPI controllers, while OMAP3 has 4 */ | ||
49 | #define OMAP2_MCSPI_MAX_CTRL 4 | ||
50 | 48 | ||
51 | #define OMAP2_MCSPI_REVISION 0x00 | 49 | #define OMAP2_MCSPI_REVISION 0x00 |
52 | #define OMAP2_MCSPI_SYSSTATUS 0x14 | 50 | #define OMAP2_MCSPI_SYSSTATUS 0x14 |
@@ -111,19 +109,25 @@ struct omap2_mcspi_dma { | |||
111 | #define DMA_MIN_BYTES 160 | 109 | #define DMA_MIN_BYTES 160 |
112 | 110 | ||
113 | 111 | ||
112 | /* | ||
113 | * Used for context save and restore, structure members to be updated whenever | ||
114 | * corresponding registers are modified. | ||
115 | */ | ||
116 | struct omap2_mcspi_regs { | ||
117 | u32 modulctrl; | ||
118 | u32 wakeupenable; | ||
119 | struct list_head cs; | ||
120 | }; | ||
121 | |||
114 | struct omap2_mcspi { | 122 | struct omap2_mcspi { |
115 | struct work_struct work; | ||
116 | /* lock protects queue and registers */ | ||
117 | spinlock_t lock; | ||
118 | struct list_head msg_queue; | ||
119 | struct spi_master *master; | 123 | struct spi_master *master; |
120 | /* Virtual base address of the controller */ | 124 | /* Virtual base address of the controller */ |
121 | void __iomem *base; | 125 | void __iomem *base; |
122 | unsigned long phys; | 126 | unsigned long phys; |
123 | /* SPI1 has 4 channels, while SPI2 has 2 */ | 127 | /* SPI1 has 4 channels, while SPI2 has 2 */ |
124 | struct omap2_mcspi_dma *dma_channels; | 128 | struct omap2_mcspi_dma *dma_channels; |
125 | struct device *dev; | 129 | struct device *dev; |
126 | struct workqueue_struct *wq; | 130 | struct omap2_mcspi_regs ctx; |
127 | }; | 131 | }; |
128 | 132 | ||
129 | struct omap2_mcspi_cs { | 133 | struct omap2_mcspi_cs { |
@@ -135,17 +139,6 @@ struct omap2_mcspi_cs { | |||
135 | u32 chconf0; | 139 | u32 chconf0; |
136 | }; | 140 | }; |
137 | 141 | ||
138 | /* used for context save and restore, structure members to be updated whenever | ||
139 | * corresponding registers are modified. | ||
140 | */ | ||
141 | struct omap2_mcspi_regs { | ||
142 | u32 modulctrl; | ||
143 | u32 wakeupenable; | ||
144 | struct list_head cs; | ||
145 | }; | ||
146 | |||
147 | static struct omap2_mcspi_regs omap2_mcspi_ctx[OMAP2_MCSPI_MAX_CTRL]; | ||
148 | |||
149 | #define MOD_REG_BIT(val, mask, set) do { \ | 142 | #define MOD_REG_BIT(val, mask, set) do { \ |
150 | if (set) \ | 143 | if (set) \ |
151 | val |= mask; \ | 144 | val |= mask; \ |
@@ -236,9 +229,12 @@ static void omap2_mcspi_force_cs(struct spi_device *spi, int cs_active) | |||
236 | 229 | ||
237 | static void omap2_mcspi_set_master_mode(struct spi_master *master) | 230 | static void omap2_mcspi_set_master_mode(struct spi_master *master) |
238 | { | 231 | { |
232 | struct omap2_mcspi *mcspi = spi_master_get_devdata(master); | ||
233 | struct omap2_mcspi_regs *ctx = &mcspi->ctx; | ||
239 | u32 l; | 234 | u32 l; |
240 | 235 | ||
241 | /* setup when switching from (reset default) slave mode | 236 | /* |
237 | * Setup when switching from (reset default) slave mode | ||
242 | * to single-channel master mode | 238 | * to single-channel master mode |
243 | */ | 239 | */ |
244 | l = mcspi_read_reg(master, OMAP2_MCSPI_MODULCTRL); | 240 | l = mcspi_read_reg(master, OMAP2_MCSPI_MODULCTRL); |
@@ -247,29 +243,26 @@ static void omap2_mcspi_set_master_mode(struct spi_master *master) | |||
247 | MOD_REG_BIT(l, OMAP2_MCSPI_MODULCTRL_SINGLE, 1); | 243 | MOD_REG_BIT(l, OMAP2_MCSPI_MODULCTRL_SINGLE, 1); |
248 | mcspi_write_reg(master, OMAP2_MCSPI_MODULCTRL, l); | 244 | mcspi_write_reg(master, OMAP2_MCSPI_MODULCTRL, l); |
249 | 245 | ||
250 | omap2_mcspi_ctx[master->bus_num - 1].modulctrl = l; | 246 | ctx->modulctrl = l; |
251 | } | 247 | } |
252 | 248 | ||
253 | static void omap2_mcspi_restore_ctx(struct omap2_mcspi *mcspi) | 249 | static void omap2_mcspi_restore_ctx(struct omap2_mcspi *mcspi) |
254 | { | 250 | { |
255 | struct spi_master *spi_cntrl; | 251 | struct spi_master *spi_cntrl = mcspi->master; |
256 | struct omap2_mcspi_cs *cs; | 252 | struct omap2_mcspi_regs *ctx = &mcspi->ctx; |
257 | spi_cntrl = mcspi->master; | 253 | struct omap2_mcspi_cs *cs; |
258 | 254 | ||
259 | /* McSPI: context restore */ | 255 | /* McSPI: context restore */ |
260 | mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_MODULCTRL, | 256 | mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_MODULCTRL, ctx->modulctrl); |
261 | omap2_mcspi_ctx[spi_cntrl->bus_num - 1].modulctrl); | 257 | mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_WAKEUPENABLE, ctx->wakeupenable); |
262 | |||
263 | mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_WAKEUPENABLE, | ||
264 | omap2_mcspi_ctx[spi_cntrl->bus_num - 1].wakeupenable); | ||
265 | 258 | ||
266 | list_for_each_entry(cs, &omap2_mcspi_ctx[spi_cntrl->bus_num - 1].cs, | 259 | list_for_each_entry(cs, &ctx->cs, node) |
267 | node) | ||
268 | __raw_writel(cs->chconf0, cs->base + OMAP2_MCSPI_CHCONF0); | 260 | __raw_writel(cs->chconf0, cs->base + OMAP2_MCSPI_CHCONF0); |
269 | } | 261 | } |
270 | static void omap2_mcspi_disable_clocks(struct omap2_mcspi *mcspi) | 262 | static void omap2_mcspi_disable_clocks(struct omap2_mcspi *mcspi) |
271 | { | 263 | { |
272 | pm_runtime_put_sync(mcspi->dev); | 264 | pm_runtime_mark_last_busy(mcspi->dev); |
265 | pm_runtime_put_autosuspend(mcspi->dev); | ||
273 | } | 266 | } |
274 | 267 | ||
275 | static int omap2_mcspi_enable_clocks(struct omap2_mcspi *mcspi) | 268 | static int omap2_mcspi_enable_clocks(struct omap2_mcspi *mcspi) |
@@ -277,6 +270,23 @@ static int omap2_mcspi_enable_clocks(struct omap2_mcspi *mcspi) | |||
277 | return pm_runtime_get_sync(mcspi->dev); | 270 | return pm_runtime_get_sync(mcspi->dev); |
278 | } | 271 | } |
279 | 272 | ||
273 | static int omap2_prepare_transfer(struct spi_master *master) | ||
274 | { | ||
275 | struct omap2_mcspi *mcspi = spi_master_get_devdata(master); | ||
276 | |||
277 | pm_runtime_get_sync(mcspi->dev); | ||
278 | return 0; | ||
279 | } | ||
280 | |||
281 | static int omap2_unprepare_transfer(struct spi_master *master) | ||
282 | { | ||
283 | struct omap2_mcspi *mcspi = spi_master_get_devdata(master); | ||
284 | |||
285 | pm_runtime_mark_last_busy(mcspi->dev); | ||
286 | pm_runtime_put_autosuspend(mcspi->dev); | ||
287 | return 0; | ||
288 | } | ||
289 | |||
280 | static int mcspi_wait_for_reg_bit(void __iomem *reg, unsigned long bit) | 290 | static int mcspi_wait_for_reg_bit(void __iomem *reg, unsigned long bit) |
281 | { | 291 | { |
282 | unsigned long timeout; | 292 | unsigned long timeout; |
@@ -777,7 +787,8 @@ static int omap2_mcspi_request_dma(struct spi_device *spi) | |||
777 | static int omap2_mcspi_setup(struct spi_device *spi) | 787 | static int omap2_mcspi_setup(struct spi_device *spi) |
778 | { | 788 | { |
779 | int ret; | 789 | int ret; |
780 | struct omap2_mcspi *mcspi; | 790 | struct omap2_mcspi *mcspi = spi_master_get_devdata(spi->master); |
791 | struct omap2_mcspi_regs *ctx = &mcspi->ctx; | ||
781 | struct omap2_mcspi_dma *mcspi_dma; | 792 | struct omap2_mcspi_dma *mcspi_dma; |
782 | struct omap2_mcspi_cs *cs = spi->controller_state; | 793 | struct omap2_mcspi_cs *cs = spi->controller_state; |
783 | 794 | ||
@@ -787,11 +798,10 @@ static int omap2_mcspi_setup(struct spi_device *spi) | |||
787 | return -EINVAL; | 798 | return -EINVAL; |
788 | } | 799 | } |
789 | 800 | ||
790 | mcspi = spi_master_get_devdata(spi->master); | ||
791 | mcspi_dma = &mcspi->dma_channels[spi->chip_select]; | 801 | mcspi_dma = &mcspi->dma_channels[spi->chip_select]; |
792 | 802 | ||
793 | if (!cs) { | 803 | if (!cs) { |
794 | cs = kzalloc(sizeof *cs, GFP_KERNEL); | 804 | cs = devm_kzalloc(&spi->dev , sizeof *cs, GFP_KERNEL); |
795 | if (!cs) | 805 | if (!cs) |
796 | return -ENOMEM; | 806 | return -ENOMEM; |
797 | cs->base = mcspi->base + spi->chip_select * 0x14; | 807 | cs->base = mcspi->base + spi->chip_select * 0x14; |
@@ -799,8 +809,7 @@ static int omap2_mcspi_setup(struct spi_device *spi) | |||
799 | cs->chconf0 = 0; | 809 | cs->chconf0 = 0; |
800 | spi->controller_state = cs; | 810 | spi->controller_state = cs; |
801 | /* Link this to context save list */ | 811 | /* Link this to context save list */ |
802 | list_add_tail(&cs->node, | 812 | list_add_tail(&cs->node, &ctx->cs); |
803 | &omap2_mcspi_ctx[mcspi->master->bus_num - 1].cs); | ||
804 | } | 813 | } |
805 | 814 | ||
806 | if (mcspi_dma->dma_rx_channel == -1 | 815 | if (mcspi_dma->dma_rx_channel == -1 |
@@ -833,7 +842,6 @@ static void omap2_mcspi_cleanup(struct spi_device *spi) | |||
833 | cs = spi->controller_state; | 842 | cs = spi->controller_state; |
834 | list_del(&cs->node); | 843 | list_del(&cs->node); |
835 | 844 | ||
836 | kfree(spi->controller_state); | ||
837 | } | 845 | } |
838 | 846 | ||
839 | if (spi->chip_select < spi->master->num_chipselect) { | 847 | if (spi->chip_select < spi->master->num_chipselect) { |
@@ -850,144 +858,122 @@ static void omap2_mcspi_cleanup(struct spi_device *spi) | |||
850 | } | 858 | } |
851 | } | 859 | } |
852 | 860 | ||
853 | static void omap2_mcspi_work(struct work_struct *work) | 861 | static void omap2_mcspi_work(struct omap2_mcspi *mcspi, struct spi_message *m) |
854 | { | 862 | { |
855 | struct omap2_mcspi *mcspi; | ||
856 | |||
857 | mcspi = container_of(work, struct omap2_mcspi, work); | ||
858 | |||
859 | if (omap2_mcspi_enable_clocks(mcspi) < 0) | ||
860 | return; | ||
861 | |||
862 | spin_lock_irq(&mcspi->lock); | ||
863 | 863 | ||
864 | /* We only enable one channel at a time -- the one whose message is | 864 | /* We only enable one channel at a time -- the one whose message is |
865 | * at the head of the queue -- although this controller would gladly | 865 | * -- although this controller would gladly |
866 | * arbitrate among multiple channels. This corresponds to "single | 866 | * arbitrate among multiple channels. This corresponds to "single |
867 | * channel" master mode. As a side effect, we need to manage the | 867 | * channel" master mode. As a side effect, we need to manage the |
868 | * chipselect with the FORCE bit ... CS != channel enable. | 868 | * chipselect with the FORCE bit ... CS != channel enable. |
869 | */ | 869 | */ |
870 | while (!list_empty(&mcspi->msg_queue)) { | ||
871 | struct spi_message *m; | ||
872 | struct spi_device *spi; | ||
873 | struct spi_transfer *t = NULL; | ||
874 | int cs_active = 0; | ||
875 | struct omap2_mcspi_cs *cs; | ||
876 | struct omap2_mcspi_device_config *cd; | ||
877 | int par_override = 0; | ||
878 | int status = 0; | ||
879 | u32 chconf; | ||
880 | |||
881 | m = container_of(mcspi->msg_queue.next, struct spi_message, | ||
882 | queue); | ||
883 | |||
884 | list_del_init(&m->queue); | ||
885 | spin_unlock_irq(&mcspi->lock); | ||
886 | |||
887 | spi = m->spi; | ||
888 | cs = spi->controller_state; | ||
889 | cd = spi->controller_data; | ||
890 | 870 | ||
891 | omap2_mcspi_set_enable(spi, 1); | 871 | struct spi_device *spi; |
892 | list_for_each_entry(t, &m->transfers, transfer_list) { | 872 | struct spi_transfer *t = NULL; |
893 | if (t->tx_buf == NULL && t->rx_buf == NULL && t->len) { | 873 | int cs_active = 0; |
894 | status = -EINVAL; | 874 | struct omap2_mcspi_cs *cs; |
895 | break; | 875 | struct omap2_mcspi_device_config *cd; |
896 | } | 876 | int par_override = 0; |
897 | if (par_override || t->speed_hz || t->bits_per_word) { | 877 | int status = 0; |
898 | par_override = 1; | 878 | u32 chconf; |
899 | status = omap2_mcspi_setup_transfer(spi, t); | ||
900 | if (status < 0) | ||
901 | break; | ||
902 | if (!t->speed_hz && !t->bits_per_word) | ||
903 | par_override = 0; | ||
904 | } | ||
905 | 879 | ||
906 | if (!cs_active) { | 880 | spi = m->spi; |
907 | omap2_mcspi_force_cs(spi, 1); | 881 | cs = spi->controller_state; |
908 | cs_active = 1; | 882 | cd = spi->controller_data; |
909 | } | ||
910 | 883 | ||
911 | chconf = mcspi_cached_chconf0(spi); | 884 | omap2_mcspi_set_enable(spi, 1); |
912 | chconf &= ~OMAP2_MCSPI_CHCONF_TRM_MASK; | 885 | list_for_each_entry(t, &m->transfers, transfer_list) { |
913 | chconf &= ~OMAP2_MCSPI_CHCONF_TURBO; | 886 | if (t->tx_buf == NULL && t->rx_buf == NULL && t->len) { |
887 | status = -EINVAL; | ||
888 | break; | ||
889 | } | ||
890 | if (par_override || t->speed_hz || t->bits_per_word) { | ||
891 | par_override = 1; | ||
892 | status = omap2_mcspi_setup_transfer(spi, t); | ||
893 | if (status < 0) | ||
894 | break; | ||
895 | if (!t->speed_hz && !t->bits_per_word) | ||
896 | par_override = 0; | ||
897 | } | ||
914 | 898 | ||
915 | if (t->tx_buf == NULL) | 899 | if (!cs_active) { |
916 | chconf |= OMAP2_MCSPI_CHCONF_TRM_RX_ONLY; | 900 | omap2_mcspi_force_cs(spi, 1); |
917 | else if (t->rx_buf == NULL) | 901 | cs_active = 1; |
918 | chconf |= OMAP2_MCSPI_CHCONF_TRM_TX_ONLY; | 902 | } |
919 | |||
920 | if (cd && cd->turbo_mode && t->tx_buf == NULL) { | ||
921 | /* Turbo mode is for more than one word */ | ||
922 | if (t->len > ((cs->word_len + 7) >> 3)) | ||
923 | chconf |= OMAP2_MCSPI_CHCONF_TURBO; | ||
924 | } | ||
925 | 903 | ||
926 | mcspi_write_chconf0(spi, chconf); | 904 | chconf = mcspi_cached_chconf0(spi); |
905 | chconf &= ~OMAP2_MCSPI_CHCONF_TRM_MASK; | ||
906 | chconf &= ~OMAP2_MCSPI_CHCONF_TURBO; | ||
927 | 907 | ||
928 | if (t->len) { | 908 | if (t->tx_buf == NULL) |
929 | unsigned count; | 909 | chconf |= OMAP2_MCSPI_CHCONF_TRM_RX_ONLY; |
910 | else if (t->rx_buf == NULL) | ||
911 | chconf |= OMAP2_MCSPI_CHCONF_TRM_TX_ONLY; | ||
930 | 912 | ||
931 | /* RX_ONLY mode needs dummy data in TX reg */ | 913 | if (cd && cd->turbo_mode && t->tx_buf == NULL) { |
932 | if (t->tx_buf == NULL) | 914 | /* Turbo mode is for more than one word */ |
933 | __raw_writel(0, cs->base | 915 | if (t->len > ((cs->word_len + 7) >> 3)) |
934 | + OMAP2_MCSPI_TX0); | 916 | chconf |= OMAP2_MCSPI_CHCONF_TURBO; |
917 | } | ||
935 | 918 | ||
936 | if (m->is_dma_mapped || t->len >= DMA_MIN_BYTES) | 919 | mcspi_write_chconf0(spi, chconf); |
937 | count = omap2_mcspi_txrx_dma(spi, t); | ||
938 | else | ||
939 | count = omap2_mcspi_txrx_pio(spi, t); | ||
940 | m->actual_length += count; | ||
941 | 920 | ||
942 | if (count != t->len) { | 921 | if (t->len) { |
943 | status = -EIO; | 922 | unsigned count; |
944 | break; | ||
945 | } | ||
946 | } | ||
947 | 923 | ||
948 | if (t->delay_usecs) | 924 | /* RX_ONLY mode needs dummy data in TX reg */ |
949 | udelay(t->delay_usecs); | 925 | if (t->tx_buf == NULL) |
926 | __raw_writel(0, cs->base | ||
927 | + OMAP2_MCSPI_TX0); | ||
928 | |||
929 | if (m->is_dma_mapped || t->len >= DMA_MIN_BYTES) | ||
930 | count = omap2_mcspi_txrx_dma(spi, t); | ||
931 | else | ||
932 | count = omap2_mcspi_txrx_pio(spi, t); | ||
933 | m->actual_length += count; | ||
950 | 934 | ||
951 | /* ignore the "leave it on after last xfer" hint */ | 935 | if (count != t->len) { |
952 | if (t->cs_change) { | 936 | status = -EIO; |
953 | omap2_mcspi_force_cs(spi, 0); | 937 | break; |
954 | cs_active = 0; | ||
955 | } | 938 | } |
956 | } | 939 | } |
957 | 940 | ||
958 | /* Restore defaults if they were overriden */ | 941 | if (t->delay_usecs) |
959 | if (par_override) { | 942 | udelay(t->delay_usecs); |
960 | par_override = 0; | ||
961 | status = omap2_mcspi_setup_transfer(spi, NULL); | ||
962 | } | ||
963 | 943 | ||
964 | if (cs_active) | 944 | /* ignore the "leave it on after last xfer" hint */ |
945 | if (t->cs_change) { | ||
965 | omap2_mcspi_force_cs(spi, 0); | 946 | omap2_mcspi_force_cs(spi, 0); |
947 | cs_active = 0; | ||
948 | } | ||
949 | } | ||
950 | /* Restore defaults if they were overriden */ | ||
951 | if (par_override) { | ||
952 | par_override = 0; | ||
953 | status = omap2_mcspi_setup_transfer(spi, NULL); | ||
954 | } | ||
966 | 955 | ||
967 | omap2_mcspi_set_enable(spi, 0); | 956 | if (cs_active) |
968 | 957 | omap2_mcspi_force_cs(spi, 0); | |
969 | m->status = status; | ||
970 | m->complete(m->context); | ||
971 | 958 | ||
972 | spin_lock_irq(&mcspi->lock); | 959 | omap2_mcspi_set_enable(spi, 0); |
973 | } | ||
974 | 960 | ||
975 | spin_unlock_irq(&mcspi->lock); | 961 | m->status = status; |
976 | 962 | ||
977 | omap2_mcspi_disable_clocks(mcspi); | ||
978 | } | 963 | } |
979 | 964 | ||
980 | static int omap2_mcspi_transfer(struct spi_device *spi, struct spi_message *m) | 965 | static int omap2_mcspi_transfer_one_message(struct spi_master *master, |
966 | struct spi_message *m) | ||
981 | { | 967 | { |
982 | struct omap2_mcspi *mcspi; | 968 | struct omap2_mcspi *mcspi; |
983 | unsigned long flags; | ||
984 | struct spi_transfer *t; | 969 | struct spi_transfer *t; |
985 | 970 | ||
971 | mcspi = spi_master_get_devdata(master); | ||
986 | m->actual_length = 0; | 972 | m->actual_length = 0; |
987 | m->status = 0; | 973 | m->status = 0; |
988 | 974 | ||
989 | /* reject invalid messages and transfers */ | 975 | /* reject invalid messages and transfers */ |
990 | if (list_empty(&m->transfers) || !m->complete) | 976 | if (list_empty(&m->transfers)) |
991 | return -EINVAL; | 977 | return -EINVAL; |
992 | list_for_each_entry(t, &m->transfers, transfer_list) { | 978 | list_for_each_entry(t, &m->transfers, transfer_list) { |
993 | const void *tx_buf = t->tx_buf; | 979 | const void *tx_buf = t->tx_buf; |
@@ -999,7 +985,7 @@ static int omap2_mcspi_transfer(struct spi_device *spi, struct spi_message *m) | |||
999 | || (t->bits_per_word && | 985 | || (t->bits_per_word && |
1000 | ( t->bits_per_word < 4 | 986 | ( t->bits_per_word < 4 |
1001 | || t->bits_per_word > 32))) { | 987 | || t->bits_per_word > 32))) { |
1002 | dev_dbg(&spi->dev, "transfer: %d Hz, %d %s%s, %d bpw\n", | 988 | dev_dbg(mcspi->dev, "transfer: %d Hz, %d %s%s, %d bpw\n", |
1003 | t->speed_hz, | 989 | t->speed_hz, |
1004 | len, | 990 | len, |
1005 | tx_buf ? "tx" : "", | 991 | tx_buf ? "tx" : "", |
@@ -1008,7 +994,7 @@ static int omap2_mcspi_transfer(struct spi_device *spi, struct spi_message *m) | |||
1008 | return -EINVAL; | 994 | return -EINVAL; |
1009 | } | 995 | } |
1010 | if (t->speed_hz && t->speed_hz < (OMAP2_MCSPI_MAX_FREQ >> 15)) { | 996 | if (t->speed_hz && t->speed_hz < (OMAP2_MCSPI_MAX_FREQ >> 15)) { |
1011 | dev_dbg(&spi->dev, "speed_hz %d below minimum %d Hz\n", | 997 | dev_dbg(mcspi->dev, "speed_hz %d below minimum %d Hz\n", |
1012 | t->speed_hz, | 998 | t->speed_hz, |
1013 | OMAP2_MCSPI_MAX_FREQ >> 15); | 999 | OMAP2_MCSPI_MAX_FREQ >> 15); |
1014 | return -EINVAL; | 1000 | return -EINVAL; |
@@ -1018,51 +1004,46 @@ static int omap2_mcspi_transfer(struct spi_device *spi, struct spi_message *m) | |||
1018 | continue; | 1004 | continue; |
1019 | 1005 | ||
1020 | if (tx_buf != NULL) { | 1006 | if (tx_buf != NULL) { |
1021 | t->tx_dma = dma_map_single(&spi->dev, (void *) tx_buf, | 1007 | t->tx_dma = dma_map_single(mcspi->dev, (void *) tx_buf, |
1022 | len, DMA_TO_DEVICE); | 1008 | len, DMA_TO_DEVICE); |
1023 | if (dma_mapping_error(&spi->dev, t->tx_dma)) { | 1009 | if (dma_mapping_error(mcspi->dev, t->tx_dma)) { |
1024 | dev_dbg(&spi->dev, "dma %cX %d bytes error\n", | 1010 | dev_dbg(mcspi->dev, "dma %cX %d bytes error\n", |
1025 | 'T', len); | 1011 | 'T', len); |
1026 | return -EINVAL; | 1012 | return -EINVAL; |
1027 | } | 1013 | } |
1028 | } | 1014 | } |
1029 | if (rx_buf != NULL) { | 1015 | if (rx_buf != NULL) { |
1030 | t->rx_dma = dma_map_single(&spi->dev, rx_buf, t->len, | 1016 | t->rx_dma = dma_map_single(mcspi->dev, rx_buf, t->len, |
1031 | DMA_FROM_DEVICE); | 1017 | DMA_FROM_DEVICE); |
1032 | if (dma_mapping_error(&spi->dev, t->rx_dma)) { | 1018 | if (dma_mapping_error(mcspi->dev, t->rx_dma)) { |
1033 | dev_dbg(&spi->dev, "dma %cX %d bytes error\n", | 1019 | dev_dbg(mcspi->dev, "dma %cX %d bytes error\n", |
1034 | 'R', len); | 1020 | 'R', len); |
1035 | if (tx_buf != NULL) | 1021 | if (tx_buf != NULL) |
1036 | dma_unmap_single(&spi->dev, t->tx_dma, | 1022 | dma_unmap_single(mcspi->dev, t->tx_dma, |
1037 | len, DMA_TO_DEVICE); | 1023 | len, DMA_TO_DEVICE); |
1038 | return -EINVAL; | 1024 | return -EINVAL; |
1039 | } | 1025 | } |
1040 | } | 1026 | } |
1041 | } | 1027 | } |
1042 | 1028 | ||
1043 | mcspi = spi_master_get_devdata(spi->master); | 1029 | omap2_mcspi_work(mcspi, m); |
1044 | 1030 | spi_finalize_current_message(master); | |
1045 | spin_lock_irqsave(&mcspi->lock, flags); | ||
1046 | list_add_tail(&m->queue, &mcspi->msg_queue); | ||
1047 | queue_work(mcspi->wq, &mcspi->work); | ||
1048 | spin_unlock_irqrestore(&mcspi->lock, flags); | ||
1049 | |||
1050 | return 0; | 1031 | return 0; |
1051 | } | 1032 | } |
1052 | 1033 | ||
1053 | static int __init omap2_mcspi_master_setup(struct omap2_mcspi *mcspi) | 1034 | static int __init omap2_mcspi_master_setup(struct omap2_mcspi *mcspi) |
1054 | { | 1035 | { |
1055 | struct spi_master *master = mcspi->master; | 1036 | struct spi_master *master = mcspi->master; |
1056 | u32 tmp; | 1037 | struct omap2_mcspi_regs *ctx = &mcspi->ctx; |
1057 | int ret = 0; | 1038 | int ret = 0; |
1058 | 1039 | ||
1059 | ret = omap2_mcspi_enable_clocks(mcspi); | 1040 | ret = omap2_mcspi_enable_clocks(mcspi); |
1060 | if (ret < 0) | 1041 | if (ret < 0) |
1061 | return ret; | 1042 | return ret; |
1062 | 1043 | ||
1063 | tmp = OMAP2_MCSPI_WAKEUPENABLE_WKEN; | 1044 | mcspi_write_reg(master, OMAP2_MCSPI_WAKEUPENABLE, |
1064 | mcspi_write_reg(master, OMAP2_MCSPI_WAKEUPENABLE, tmp); | 1045 | OMAP2_MCSPI_WAKEUPENABLE_WKEN); |
1065 | omap2_mcspi_ctx[master->bus_num - 1].wakeupenable = tmp; | 1046 | ctx->wakeupenable = OMAP2_MCSPI_WAKEUPENABLE_WKEN; |
1066 | 1047 | ||
1067 | omap2_mcspi_set_master_mode(master); | 1048 | omap2_mcspi_set_master_mode(master); |
1068 | omap2_mcspi_disable_clocks(mcspi); | 1049 | omap2_mcspi_disable_clocks(mcspi); |
@@ -1102,14 +1083,13 @@ static const struct of_device_id omap_mcspi_of_match[] = { | |||
1102 | }; | 1083 | }; |
1103 | MODULE_DEVICE_TABLE(of, omap_mcspi_of_match); | 1084 | MODULE_DEVICE_TABLE(of, omap_mcspi_of_match); |
1104 | 1085 | ||
1105 | static int __init omap2_mcspi_probe(struct platform_device *pdev) | 1086 | static int __devinit omap2_mcspi_probe(struct platform_device *pdev) |
1106 | { | 1087 | { |
1107 | struct spi_master *master; | 1088 | struct spi_master *master; |
1108 | struct omap2_mcspi_platform_config *pdata; | 1089 | struct omap2_mcspi_platform_config *pdata; |
1109 | struct omap2_mcspi *mcspi; | 1090 | struct omap2_mcspi *mcspi; |
1110 | struct resource *r; | 1091 | struct resource *r; |
1111 | int status = 0, i; | 1092 | int status = 0, i; |
1112 | char wq_name[20]; | ||
1113 | u32 regs_offset = 0; | 1093 | u32 regs_offset = 0; |
1114 | static int bus_num = 1; | 1094 | static int bus_num = 1; |
1115 | struct device_node *node = pdev->dev.of_node; | 1095 | struct device_node *node = pdev->dev.of_node; |
@@ -1125,7 +1105,9 @@ static int __init omap2_mcspi_probe(struct platform_device *pdev) | |||
1125 | master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; | 1105 | master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; |
1126 | 1106 | ||
1127 | master->setup = omap2_mcspi_setup; | 1107 | master->setup = omap2_mcspi_setup; |
1128 | master->transfer = omap2_mcspi_transfer; | 1108 | master->prepare_transfer_hardware = omap2_prepare_transfer; |
1109 | master->unprepare_transfer_hardware = omap2_unprepare_transfer; | ||
1110 | master->transfer_one_message = omap2_mcspi_transfer_one_message; | ||
1129 | master->cleanup = omap2_mcspi_cleanup; | 1111 | master->cleanup = omap2_mcspi_cleanup; |
1130 | master->dev.of_node = node; | 1112 | master->dev.of_node = node; |
1131 | 1113 | ||
@@ -1150,13 +1132,6 @@ static int __init omap2_mcspi_probe(struct platform_device *pdev) | |||
1150 | mcspi = spi_master_get_devdata(master); | 1132 | mcspi = spi_master_get_devdata(master); |
1151 | mcspi->master = master; | 1133 | mcspi->master = master; |
1152 | 1134 | ||
1153 | sprintf(wq_name, "omap2_mcspi/%d", master->bus_num); | ||
1154 | mcspi->wq = alloc_workqueue(wq_name, WQ_MEM_RECLAIM, 1); | ||
1155 | if (mcspi->wq == NULL) { | ||
1156 | status = -ENOMEM; | ||
1157 | goto free_master; | ||
1158 | } | ||
1159 | |||
1160 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1135 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1161 | if (r == NULL) { | 1136 | if (r == NULL) { |
1162 | status = -ENODEV; | 1137 | status = -ENODEV; |
@@ -1166,32 +1141,24 @@ static int __init omap2_mcspi_probe(struct platform_device *pdev) | |||
1166 | r->start += regs_offset; | 1141 | r->start += regs_offset; |
1167 | r->end += regs_offset; | 1142 | r->end += regs_offset; |
1168 | mcspi->phys = r->start; | 1143 | mcspi->phys = r->start; |
1169 | if (!request_mem_region(r->start, resource_size(r), | ||
1170 | dev_name(&pdev->dev))) { | ||
1171 | status = -EBUSY; | ||
1172 | goto free_master; | ||
1173 | } | ||
1174 | 1144 | ||
1175 | mcspi->base = ioremap(r->start, resource_size(r)); | 1145 | mcspi->base = devm_request_and_ioremap(&pdev->dev, r); |
1176 | if (!mcspi->base) { | 1146 | if (!mcspi->base) { |
1177 | dev_dbg(&pdev->dev, "can't ioremap MCSPI\n"); | 1147 | dev_dbg(&pdev->dev, "can't ioremap MCSPI\n"); |
1178 | status = -ENOMEM; | 1148 | status = -ENOMEM; |
1179 | goto release_region; | 1149 | goto free_master; |
1180 | } | 1150 | } |
1181 | 1151 | ||
1182 | mcspi->dev = &pdev->dev; | 1152 | mcspi->dev = &pdev->dev; |
1183 | INIT_WORK(&mcspi->work, omap2_mcspi_work); | ||
1184 | 1153 | ||
1185 | spin_lock_init(&mcspi->lock); | 1154 | INIT_LIST_HEAD(&mcspi->ctx.cs); |
1186 | INIT_LIST_HEAD(&mcspi->msg_queue); | ||
1187 | INIT_LIST_HEAD(&omap2_mcspi_ctx[master->bus_num - 1].cs); | ||
1188 | 1155 | ||
1189 | mcspi->dma_channels = kcalloc(master->num_chipselect, | 1156 | mcspi->dma_channels = kcalloc(master->num_chipselect, |
1190 | sizeof(struct omap2_mcspi_dma), | 1157 | sizeof(struct omap2_mcspi_dma), |
1191 | GFP_KERNEL); | 1158 | GFP_KERNEL); |
1192 | 1159 | ||
1193 | if (mcspi->dma_channels == NULL) | 1160 | if (mcspi->dma_channels == NULL) |
1194 | goto unmap_io; | 1161 | goto free_master; |
1195 | 1162 | ||
1196 | for (i = 0; i < master->num_chipselect; i++) { | 1163 | for (i = 0; i < master->num_chipselect; i++) { |
1197 | char dma_ch_name[14]; | 1164 | char dma_ch_name[14]; |
@@ -1224,6 +1191,8 @@ static int __init omap2_mcspi_probe(struct platform_device *pdev) | |||
1224 | if (status < 0) | 1191 | if (status < 0) |
1225 | goto dma_chnl_free; | 1192 | goto dma_chnl_free; |
1226 | 1193 | ||
1194 | pm_runtime_use_autosuspend(&pdev->dev); | ||
1195 | pm_runtime_set_autosuspend_delay(&pdev->dev, SPI_AUTOSUSPEND_TIMEOUT); | ||
1227 | pm_runtime_enable(&pdev->dev); | 1196 | pm_runtime_enable(&pdev->dev); |
1228 | 1197 | ||
1229 | if (status || omap2_mcspi_master_setup(mcspi) < 0) | 1198 | if (status || omap2_mcspi_master_setup(mcspi) < 0) |
@@ -1241,23 +1210,17 @@ disable_pm: | |||
1241 | pm_runtime_disable(&pdev->dev); | 1210 | pm_runtime_disable(&pdev->dev); |
1242 | dma_chnl_free: | 1211 | dma_chnl_free: |
1243 | kfree(mcspi->dma_channels); | 1212 | kfree(mcspi->dma_channels); |
1244 | unmap_io: | ||
1245 | iounmap(mcspi->base); | ||
1246 | release_region: | ||
1247 | release_mem_region(r->start, resource_size(r)); | ||
1248 | free_master: | 1213 | free_master: |
1249 | kfree(master); | 1214 | kfree(master); |
1250 | platform_set_drvdata(pdev, NULL); | 1215 | platform_set_drvdata(pdev, NULL); |
1251 | return status; | 1216 | return status; |
1252 | } | 1217 | } |
1253 | 1218 | ||
1254 | static int __exit omap2_mcspi_remove(struct platform_device *pdev) | 1219 | static int __devexit omap2_mcspi_remove(struct platform_device *pdev) |
1255 | { | 1220 | { |
1256 | struct spi_master *master; | 1221 | struct spi_master *master; |
1257 | struct omap2_mcspi *mcspi; | 1222 | struct omap2_mcspi *mcspi; |
1258 | struct omap2_mcspi_dma *dma_channels; | 1223 | struct omap2_mcspi_dma *dma_channels; |
1259 | struct resource *r; | ||
1260 | void __iomem *base; | ||
1261 | 1224 | ||
1262 | master = dev_get_drvdata(&pdev->dev); | 1225 | master = dev_get_drvdata(&pdev->dev); |
1263 | mcspi = spi_master_get_devdata(master); | 1226 | mcspi = spi_master_get_devdata(master); |
@@ -1265,14 +1228,9 @@ static int __exit omap2_mcspi_remove(struct platform_device *pdev) | |||
1265 | 1228 | ||
1266 | omap2_mcspi_disable_clocks(mcspi); | 1229 | omap2_mcspi_disable_clocks(mcspi); |
1267 | pm_runtime_disable(&pdev->dev); | 1230 | pm_runtime_disable(&pdev->dev); |
1268 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
1269 | release_mem_region(r->start, resource_size(r)); | ||
1270 | 1231 | ||
1271 | base = mcspi->base; | ||
1272 | spi_unregister_master(master); | 1232 | spi_unregister_master(master); |
1273 | iounmap(base); | ||
1274 | kfree(dma_channels); | 1233 | kfree(dma_channels); |
1275 | destroy_workqueue(mcspi->wq); | ||
1276 | platform_set_drvdata(pdev, NULL); | 1234 | platform_set_drvdata(pdev, NULL); |
1277 | 1235 | ||
1278 | return 0; | 1236 | return 0; |
@@ -1291,13 +1249,12 @@ static int omap2_mcspi_resume(struct device *dev) | |||
1291 | { | 1249 | { |
1292 | struct spi_master *master = dev_get_drvdata(dev); | 1250 | struct spi_master *master = dev_get_drvdata(dev); |
1293 | struct omap2_mcspi *mcspi = spi_master_get_devdata(master); | 1251 | struct omap2_mcspi *mcspi = spi_master_get_devdata(master); |
1294 | struct omap2_mcspi_cs *cs; | 1252 | struct omap2_mcspi_regs *ctx = &mcspi->ctx; |
1253 | struct omap2_mcspi_cs *cs; | ||
1295 | 1254 | ||
1296 | omap2_mcspi_enable_clocks(mcspi); | 1255 | omap2_mcspi_enable_clocks(mcspi); |
1297 | list_for_each_entry(cs, &omap2_mcspi_ctx[master->bus_num - 1].cs, | 1256 | list_for_each_entry(cs, &ctx->cs, node) { |
1298 | node) { | ||
1299 | if ((cs->chconf0 & OMAP2_MCSPI_CHCONF_FORCE) == 0) { | 1257 | if ((cs->chconf0 & OMAP2_MCSPI_CHCONF_FORCE) == 0) { |
1300 | |||
1301 | /* | 1258 | /* |
1302 | * We need to toggle CS state for OMAP take this | 1259 | * We need to toggle CS state for OMAP take this |
1303 | * change in account. | 1260 | * change in account. |
@@ -1327,21 +1284,9 @@ static struct platform_driver omap2_mcspi_driver = { | |||
1327 | .pm = &omap2_mcspi_pm_ops, | 1284 | .pm = &omap2_mcspi_pm_ops, |
1328 | .of_match_table = omap_mcspi_of_match, | 1285 | .of_match_table = omap_mcspi_of_match, |
1329 | }, | 1286 | }, |
1330 | .remove = __exit_p(omap2_mcspi_remove), | 1287 | .probe = omap2_mcspi_probe, |
1288 | .remove = __devexit_p(omap2_mcspi_remove), | ||
1331 | }; | 1289 | }; |
1332 | 1290 | ||
1333 | 1291 | module_platform_driver(omap2_mcspi_driver); | |
1334 | static int __init omap2_mcspi_init(void) | ||
1335 | { | ||
1336 | return platform_driver_probe(&omap2_mcspi_driver, omap2_mcspi_probe); | ||
1337 | } | ||
1338 | subsys_initcall(omap2_mcspi_init); | ||
1339 | |||
1340 | static void __exit omap2_mcspi_exit(void) | ||
1341 | { | ||
1342 | platform_driver_unregister(&omap2_mcspi_driver); | ||
1343 | |||
1344 | } | ||
1345 | module_exit(omap2_mcspi_exit); | ||
1346 | |||
1347 | MODULE_LICENSE("GPL"); | 1292 | MODULE_LICENSE("GPL"); |