]> git.karo-electronics.de Git - linux-beck.git/commitdiff
davinci: edma: provide ability to detect insufficient CC info data
authorSekhar Nori <nsekhar@ti.com>
Tue, 29 Jun 2010 06:05:12 +0000 (11:35 +0530)
committerKevin Hilman <khilman@deeprootsystems.com>
Thu, 5 Aug 2010 16:58:24 +0000 (09:58 -0700)
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>
arch/arm/mach-davinci/devices-da8xx.c
arch/arm/mach-davinci/devices-tnetv107x.c
arch/arm/mach-davinci/dm355.c
arch/arm/mach-davinci/dm365.c
arch/arm/mach-davinci/dm644x.c
arch/arm/mach-davinci/dm646x.c
arch/arm/mach-davinci/dma.c
arch/arm/mach-davinci/include/mach/edma.h

index 8cda729be273c1af3e00747650260519c97a9c87..1d956bfa9cf08c7b87982d901d4ff491081891d5 100644 (file)
@@ -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 *da830_edma_info[EDMA_MAX_CC] = {
+       &da830_edma_cc0_info,
 };
 
-static struct edma_soc_info da850_edma_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",
index 4eef6ccdc73ed9a7632f83da3c2881536c134b2b..2718a3a90dff7931c038f9e625aec69a83956f18 100644 (file)
@@ -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[] = {
index 383478116ef54ddfddfd2cabf86fa6477d85472d..3d996b659ff41e43d794d93c167b409afb90c355 100644 (file)
@@ -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[] = {
index 652f4b6ee1cda27aff35513c6035e03f78476357..6b6f4c643709c7d14a4b2baf168464ad772be4ce 100644 (file)
@@ -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[] = {
index 7ad15208b841fece3d50823a2d9be687ccc5aa14..40fec315c99a192826d7530d43c6406726ecbcff 100644 (file)
@@ -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[] = {
index 94045656cff6f28a3b9eb4eeb033a009677c9200..bfc887e9f11821b6e2a0fe4eb4979a1b50b3f6b5 100644 (file)
@@ -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[] = {
index d33827aadda76a01240cf659f35b6bf737cd05de..0b6c01fbedd593d6546edac86bc7c6dba14f2852 100644 (file)
@@ -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);
index ced3092af5ba71dad30fa25e00373d0418e95e10..9a3bcc6f26020051556c5a9395d37a2b91ab5491 100644 (file)
@@ -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),