summaryrefslogtreecommitdiff
path: root/drivers/usb/musb/ux500_dma.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/musb/ux500_dma.c')
-rw-r--r--drivers/usb/musb/ux500_dma.c59
1 files changed, 33 insertions, 26 deletions
diff --git a/drivers/usb/musb/ux500_dma.c b/drivers/usb/musb/ux500_dma.c
index 63e7c8a6b125..bfb7a65d83cc 100644
--- a/drivers/usb/musb/ux500_dma.c
+++ b/drivers/usb/musb/ux500_dma.c
@@ -34,6 +34,11 @@
#include <linux/platform_data/usb-musb-ux500.h>
#include "musb_core.h"
+static const char *iep_chan_names[] = { "iep_1_9", "iep_2_10", "iep_3_11", "iep_4_12",
+ "iep_5_13", "iep_6_14", "iep_7_15", "iep_8" };
+static const char *oep_chan_names[] = { "oep_1_9", "oep_2_10", "oep_3_11", "oep_4_12",
+ "oep_5_13", "oep_6_14", "oep_7_15", "oep_8" };
+
struct ux500_dma_channel {
struct dma_channel channel;
struct ux500_dma_controller *controller;
@@ -48,10 +53,8 @@ struct ux500_dma_channel {
struct ux500_dma_controller {
struct dma_controller controller;
- struct ux500_dma_channel rx_channel[UX500_MUSB_DMA_NUM_RX_CHANNELS];
- struct ux500_dma_channel tx_channel[UX500_MUSB_DMA_NUM_TX_CHANNELS];
- u32 num_rx_channels;
- u32 num_tx_channels;
+ struct ux500_dma_channel rx_channel[UX500_MUSB_DMA_NUM_RX_TX_CHANNELS];
+ struct ux500_dma_channel tx_channel[UX500_MUSB_DMA_NUM_RX_TX_CHANNELS];
void *private_data;
dma_addr_t phy_base;
};
@@ -143,19 +146,15 @@ static struct dma_channel *ux500_dma_channel_allocate(struct dma_controller *c,
struct ux500_dma_channel *ux500_channel = NULL;
struct musb *musb = controller->private_data;
u8 ch_num = hw_ep->epnum - 1;
- u32 max_ch;
- /* Max 8 DMA channels (0 - 7). Each DMA channel can only be allocated
+ /* 8 DMA channels (0 - 7). Each DMA channel can only be allocated
* to specified hw_ep. For example DMA channel 0 can only be allocated
* to hw_ep 1 and 9.
*/
if (ch_num > 7)
ch_num -= 8;
- max_ch = is_tx ? controller->num_tx_channels :
- controller->num_rx_channels;
-
- if (ch_num >= max_ch)
+ if (ch_num >= UX500_MUSB_DMA_NUM_RX_TX_CHANNELS)
return NULL;
ux500_channel = is_tx ? &(controller->tx_channel[ch_num]) :
@@ -263,7 +262,7 @@ static int ux500_dma_controller_stop(struct dma_controller *c)
struct dma_channel *channel;
u8 ch_num;
- for (ch_num = 0; ch_num < controller->num_rx_channels; ch_num++) {
+ for (ch_num = 0; ch_num < UX500_MUSB_DMA_NUM_RX_TX_CHANNELS; ch_num++) {
channel = &controller->rx_channel[ch_num].channel;
ux500_channel = channel->private_data;
@@ -273,7 +272,7 @@ static int ux500_dma_controller_stop(struct dma_controller *c)
dma_release_channel(ux500_channel->dma_chan);
}
- for (ch_num = 0; ch_num < controller->num_tx_channels; ch_num++) {
+ for (ch_num = 0; ch_num < UX500_MUSB_DMA_NUM_RX_TX_CHANNELS; ch_num++) {
channel = &controller->tx_channel[ch_num].channel;
ux500_channel = channel->private_data;
@@ -294,34 +293,36 @@ static int ux500_dma_controller_start(struct dma_controller *c)
struct musb *musb = controller->private_data;
struct device *dev = musb->controller;
struct musb_hdrc_platform_data *plat = dev->platform_data;
- struct ux500_musb_board_data *data = plat->board_data;
+ struct ux500_musb_board_data *data;
struct dma_channel *dma_channel = NULL;
+ char **chan_names;
u32 ch_num;
u8 dir;
u8 is_tx = 0;
void **param_array;
struct ux500_dma_channel *channel_array;
- u32 ch_count;
dma_cap_mask_t mask;
- if ((data->num_rx_channels > UX500_MUSB_DMA_NUM_RX_CHANNELS) ||
- (data->num_tx_channels > UX500_MUSB_DMA_NUM_TX_CHANNELS))
+ if (!plat) {
+ dev_err(musb->controller, "No platform data\n");
return -EINVAL;
+ }
- controller->num_rx_channels = data->num_rx_channels;
- controller->num_tx_channels = data->num_tx_channels;
+ data = plat->board_data;
dma_cap_zero(mask);
dma_cap_set(DMA_SLAVE, mask);
/* Prepare the loop for RX channels */
channel_array = controller->rx_channel;
- ch_count = data->num_rx_channels;
- param_array = data->dma_rx_param_array;
+ param_array = data ? data->dma_rx_param_array : NULL;
+ chan_names = (char **)iep_chan_names;
for (dir = 0; dir < 2; dir++) {
- for (ch_num = 0; ch_num < ch_count; ch_num++) {
+ for (ch_num = 0;
+ ch_num < UX500_MUSB_DMA_NUM_RX_TX_CHANNELS;
+ ch_num++) {
ux500_channel = &channel_array[ch_num];
ux500_channel->controller = controller;
ux500_channel->ch_num = ch_num;
@@ -332,9 +333,15 @@ static int ux500_dma_controller_start(struct dma_controller *c)
dma_channel->status = MUSB_DMA_STATUS_FREE;
dma_channel->max_len = SZ_16M;
- ux500_channel->dma_chan = dma_request_channel(mask,
- data->dma_filter,
- param_array[ch_num]);
+ ux500_channel->dma_chan =
+ dma_request_slave_channel(dev, chan_names[ch_num]);
+
+ if (!ux500_channel->dma_chan)
+ ux500_channel->dma_chan =
+ dma_request_channel(mask,
+ data->dma_filter,
+ param_array[ch_num]);
+
if (!ux500_channel->dma_chan) {
ERR("Dma pipe allocation error dir=%d ch=%d\n",
dir, ch_num);
@@ -349,8 +356,8 @@ static int ux500_dma_controller_start(struct dma_controller *c)
/* Prepare the loop for TX channels */
channel_array = controller->tx_channel;
- ch_count = data->num_tx_channels;
- param_array = data->dma_tx_param_array;
+ param_array = data ? data->dma_tx_param_array : NULL;
+ chan_names = (char **)oep_chan_names;
is_tx = 1;
}