mirror of
https://github.com/torvalds/linux.git
synced 2024-12-02 09:01:34 +00:00
davinci: edma: provide ability to detect insufficient CC info data
This patch modifies the EDMA driver to expect the channel controller (CC) infomation passed on by the platform as a fixed size (EDMA_MAX_CC) array of pointers to structures. Doing so helps catch errors of the sort where the resource structure has information for more channel controllers than the number channel controller info structures defined. Such insufficient platform data would lead to illegal memory accesses. Signed-off-by: Sekhar Nori <nsekhar@ti.com> Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
This commit is contained in:
parent
f027512db7
commit
bc3ac9f316
@ -111,19 +111,21 @@ static const s8 da850_queue_priority_mapping[][2] = {
|
||||
{-1, -1}
|
||||
};
|
||||
|
||||
static struct edma_soc_info da830_edma_info[] = {
|
||||
{
|
||||
.n_channel = 32,
|
||||
.n_region = 4,
|
||||
.n_slot = 128,
|
||||
.n_tc = 2,
|
||||
.n_cc = 1,
|
||||
.queue_tc_mapping = da8xx_queue_tc_mapping,
|
||||
.queue_priority_mapping = da8xx_queue_priority_mapping,
|
||||
},
|
||||
static struct edma_soc_info da830_edma_cc0_info = {
|
||||
.n_channel = 32,
|
||||
.n_region = 4,
|
||||
.n_slot = 128,
|
||||
.n_tc = 2,
|
||||
.n_cc = 1,
|
||||
.queue_tc_mapping = da8xx_queue_tc_mapping,
|
||||
.queue_priority_mapping = da8xx_queue_priority_mapping,
|
||||
};
|
||||
|
||||
static struct edma_soc_info da850_edma_info[] = {
|
||||
static struct edma_soc_info *da830_edma_info[EDMA_MAX_CC] = {
|
||||
&da830_edma_cc0_info,
|
||||
};
|
||||
|
||||
static struct edma_soc_info da850_edma_cc_info[] = {
|
||||
{
|
||||
.n_channel = 32,
|
||||
.n_region = 4,
|
||||
@ -144,6 +146,11 @@ static struct edma_soc_info da850_edma_info[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct edma_soc_info *da850_edma_info[EDMA_MAX_CC] = {
|
||||
&da850_edma_cc_info[0],
|
||||
&da850_edma_cc_info[1],
|
||||
};
|
||||
|
||||
static struct resource da830_edma_resources[] = {
|
||||
{
|
||||
.name = "edma_cc0",
|
||||
|
@ -69,16 +69,18 @@ static const s8 edma_priority_mapping[][2] = {
|
||||
{ -1, -1 }
|
||||
};
|
||||
|
||||
static struct edma_soc_info edma_info[] = {
|
||||
{
|
||||
.n_channel = EDMA_TNETV107X_NUM_DMACH,
|
||||
.n_region = EDMA_TNETV107X_NUM_REGIONS,
|
||||
.n_slot = EDMA_TNETV107X_NUM_PARAMENTRY,
|
||||
.n_tc = EDMA_TNETV107X_NUM_TC,
|
||||
.n_cc = 1,
|
||||
.queue_tc_mapping = edma_tc_mapping,
|
||||
.queue_priority_mapping = edma_priority_mapping,
|
||||
},
|
||||
static struct edma_soc_info edma_cc0_info = {
|
||||
.n_channel = EDMA_TNETV107X_NUM_DMACH,
|
||||
.n_region = EDMA_TNETV107X_NUM_REGIONS,
|
||||
.n_slot = EDMA_TNETV107X_NUM_PARAMENTRY,
|
||||
.n_tc = EDMA_TNETV107X_NUM_TC,
|
||||
.n_cc = 1,
|
||||
.queue_tc_mapping = edma_tc_mapping,
|
||||
.queue_priority_mapping = edma_priority_mapping,
|
||||
};
|
||||
|
||||
static struct edma_soc_info *tnetv107x_edma_info[EDMA_MAX_CC] = {
|
||||
&edma_cc0_info,
|
||||
};
|
||||
|
||||
static struct resource edma_resources[] = {
|
||||
@ -117,7 +119,7 @@ static struct platform_device edma_device = {
|
||||
.id = -1,
|
||||
.num_resources = ARRAY_SIZE(edma_resources),
|
||||
.resource = edma_resources,
|
||||
.dev.platform_data = edma_info,
|
||||
.dev.platform_data = tnetv107x_edma_info,
|
||||
};
|
||||
|
||||
static struct plat_serial8250_port serial_data[] = {
|
||||
|
@ -591,16 +591,18 @@ queue_priority_mapping[][2] = {
|
||||
{-1, -1},
|
||||
};
|
||||
|
||||
static struct edma_soc_info dm355_edma_info[] = {
|
||||
{
|
||||
.n_channel = 64,
|
||||
.n_region = 4,
|
||||
.n_slot = 128,
|
||||
.n_tc = 2,
|
||||
.n_cc = 1,
|
||||
.queue_tc_mapping = queue_tc_mapping,
|
||||
.queue_priority_mapping = queue_priority_mapping,
|
||||
},
|
||||
static struct edma_soc_info edma_cc0_info = {
|
||||
.n_channel = 64,
|
||||
.n_region = 4,
|
||||
.n_slot = 128,
|
||||
.n_tc = 2,
|
||||
.n_cc = 1,
|
||||
.queue_tc_mapping = queue_tc_mapping,
|
||||
.queue_priority_mapping = queue_priority_mapping,
|
||||
};
|
||||
|
||||
static struct edma_soc_info *dm355_edma_info[EDMA_MAX_CC] = {
|
||||
&edma_cc0_info,
|
||||
};
|
||||
|
||||
static struct resource edma_resources[] = {
|
||||
|
@ -822,17 +822,19 @@ dm365_queue_priority_mapping[][2] = {
|
||||
{-1, -1},
|
||||
};
|
||||
|
||||
static struct edma_soc_info dm365_edma_info[] = {
|
||||
{
|
||||
.n_channel = 64,
|
||||
.n_region = 4,
|
||||
.n_slot = 256,
|
||||
.n_tc = 4,
|
||||
.n_cc = 1,
|
||||
.queue_tc_mapping = dm365_queue_tc_mapping,
|
||||
.queue_priority_mapping = dm365_queue_priority_mapping,
|
||||
.default_queue = EVENTQ_3,
|
||||
},
|
||||
static struct edma_soc_info edma_cc0_info = {
|
||||
.n_channel = 64,
|
||||
.n_region = 4,
|
||||
.n_slot = 256,
|
||||
.n_tc = 4,
|
||||
.n_cc = 1,
|
||||
.queue_tc_mapping = dm365_queue_tc_mapping,
|
||||
.queue_priority_mapping = dm365_queue_priority_mapping,
|
||||
.default_queue = EVENTQ_3,
|
||||
};
|
||||
|
||||
static struct edma_soc_info *dm365_edma_info[EDMA_MAX_CC] = {
|
||||
&edma_cc0_info,
|
||||
};
|
||||
|
||||
static struct resource edma_resources[] = {
|
||||
|
@ -492,16 +492,18 @@ queue_priority_mapping[][2] = {
|
||||
{-1, -1},
|
||||
};
|
||||
|
||||
static struct edma_soc_info dm644x_edma_info[] = {
|
||||
{
|
||||
.n_channel = 64,
|
||||
.n_region = 4,
|
||||
.n_slot = 128,
|
||||
.n_tc = 2,
|
||||
.n_cc = 1,
|
||||
.queue_tc_mapping = queue_tc_mapping,
|
||||
.queue_priority_mapping = queue_priority_mapping,
|
||||
},
|
||||
static struct edma_soc_info edma_cc0_info = {
|
||||
.n_channel = 64,
|
||||
.n_region = 4,
|
||||
.n_slot = 128,
|
||||
.n_tc = 2,
|
||||
.n_cc = 1,
|
||||
.queue_tc_mapping = queue_tc_mapping,
|
||||
.queue_priority_mapping = queue_priority_mapping,
|
||||
};
|
||||
|
||||
static struct edma_soc_info *dm644x_edma_info[EDMA_MAX_CC] = {
|
||||
&edma_cc0_info,
|
||||
};
|
||||
|
||||
static struct resource edma_resources[] = {
|
||||
|
@ -529,16 +529,18 @@ dm646x_queue_priority_mapping[][2] = {
|
||||
{-1, -1},
|
||||
};
|
||||
|
||||
static struct edma_soc_info dm646x_edma_info[] = {
|
||||
{
|
||||
.n_channel = 64,
|
||||
.n_region = 6, /* 0-1, 4-7 */
|
||||
.n_slot = 512,
|
||||
.n_tc = 4,
|
||||
.n_cc = 1,
|
||||
.queue_tc_mapping = dm646x_queue_tc_mapping,
|
||||
.queue_priority_mapping = dm646x_queue_priority_mapping,
|
||||
},
|
||||
static struct edma_soc_info edma_cc0_info = {
|
||||
.n_channel = 64,
|
||||
.n_region = 6, /* 0-1, 4-7 */
|
||||
.n_slot = 512,
|
||||
.n_tc = 4,
|
||||
.n_cc = 1,
|
||||
.queue_tc_mapping = dm646x_queue_tc_mapping,
|
||||
.queue_priority_mapping = dm646x_queue_priority_mapping,
|
||||
};
|
||||
|
||||
static struct edma_soc_info *dm646x_edma_info[EDMA_MAX_CC] = {
|
||||
&edma_cc0_info,
|
||||
};
|
||||
|
||||
static struct resource edma_resources[] = {
|
||||
|
@ -99,8 +99,6 @@
|
||||
|
||||
#define EDMA_MAX_DMACH 64
|
||||
#define EDMA_MAX_PARAMENTRY 512
|
||||
#define EDMA_MAX_CC 2
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
@ -1376,7 +1374,7 @@ EXPORT_SYMBOL(edma_clear_event);
|
||||
|
||||
static int __init edma_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct edma_soc_info *info = pdev->dev.platform_data;
|
||||
struct edma_soc_info **info = pdev->dev.platform_data;
|
||||
const s8 (*queue_priority_mapping)[2];
|
||||
const s8 (*queue_tc_mapping)[2];
|
||||
int i, j, found = 0;
|
||||
@ -1395,7 +1393,7 @@ static int __init edma_probe(struct platform_device *pdev)
|
||||
sprintf(res_name, "edma_cc%d", j);
|
||||
r[j] = platform_get_resource_byname(pdev, IORESOURCE_MEM,
|
||||
res_name);
|
||||
if (!r[j]) {
|
||||
if (!r[j] || !info[j]) {
|
||||
if (found)
|
||||
break;
|
||||
else
|
||||
@ -1426,13 +1424,14 @@ static int __init edma_probe(struct platform_device *pdev)
|
||||
}
|
||||
memset(edma_cc[j], 0, sizeof(struct edma));
|
||||
|
||||
edma_cc[j]->num_channels = min_t(unsigned, info[j].n_channel,
|
||||
edma_cc[j]->num_channels = min_t(unsigned, info[j]->n_channel,
|
||||
EDMA_MAX_DMACH);
|
||||
edma_cc[j]->num_slots = min_t(unsigned, info[j].n_slot,
|
||||
edma_cc[j]->num_slots = min_t(unsigned, info[j]->n_slot,
|
||||
EDMA_MAX_PARAMENTRY);
|
||||
edma_cc[j]->num_cc = min_t(unsigned, info[j].n_cc, EDMA_MAX_CC);
|
||||
edma_cc[j]->num_cc = min_t(unsigned, info[j]->n_cc,
|
||||
EDMA_MAX_CC);
|
||||
|
||||
edma_cc[j]->default_queue = info[j].default_queue;
|
||||
edma_cc[j]->default_queue = info[j]->default_queue;
|
||||
if (!edma_cc[j]->default_queue)
|
||||
edma_cc[j]->default_queue = EVENTQ_1;
|
||||
|
||||
@ -1476,8 +1475,8 @@ static int __init edma_probe(struct platform_device *pdev)
|
||||
for (i = 0; i < edma_cc[j]->num_channels; i++)
|
||||
map_dmach_queue(j, i, EVENTQ_1);
|
||||
|
||||
queue_tc_mapping = info[j].queue_tc_mapping;
|
||||
queue_priority_mapping = info[j].queue_priority_mapping;
|
||||
queue_tc_mapping = info[j]->queue_tc_mapping;
|
||||
queue_priority_mapping = info[j]->queue_priority_mapping;
|
||||
|
||||
/* Event queue to TC mapping */
|
||||
for (i = 0; queue_tc_mapping[i][0] != -1; i++)
|
||||
@ -1496,7 +1495,7 @@ static int __init edma_probe(struct platform_device *pdev)
|
||||
if (edma_read(j, EDMA_CCCFG) & CHMAP_EXIST)
|
||||
map_dmach_param(j);
|
||||
|
||||
for (i = 0; i < info[j].n_region; i++) {
|
||||
for (i = 0; i < info[j]->n_region; i++) {
|
||||
edma_write_array2(j, EDMA_DRAE, i, 0, 0x0);
|
||||
edma_write_array2(j, EDMA_DRAE, i, 1, 0x0);
|
||||
edma_write_array(j, EDMA_QRAE, i, 0x0);
|
||||
|
@ -230,6 +230,8 @@ enum sync_dimension {
|
||||
#define EDMA_CONT_PARAMS_FIXED_EXACT 1002
|
||||
#define EDMA_CONT_PARAMS_FIXED_NOT_EXACT 1003
|
||||
|
||||
#define EDMA_MAX_CC 2
|
||||
|
||||
/* alloc/free DMA channels and their dedicated parameter RAM slots */
|
||||
int edma_alloc_channel(int channel,
|
||||
void (*callback)(unsigned channel, u16 ch_status, void *data),
|
||||
|
Loading…
Reference in New Issue
Block a user