aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTony Lindgren <tony@atomide.com>2014-11-03 20:45:01 -0500
committerTony Lindgren <tony@atomide.com>2014-11-03 20:45:01 -0500
commit9ed7a776eb50de2284dd053c719f2f6481af9027 (patch)
treef9c6f08f6ae8400a480c4381ad5c6fb68b3ae0e6
parent24f284af1a64a1a073b064428cafb447aff19a21 (diff)
ARM: OMAP2+: Fix support for multiple devices on a GPMC chip select
There are cases where we have multiple device instances connected to a single GPMC chip select. For example, there are four UARTs on the Zoom debug boards that all share a single chip select and a GPIO interrupt. We do have support for this already in theory, but it's broken because we're bailing out if the chip select is already taken. To be able to provide checks on the chip select usage, let's add new struct gpmc_cs_data so we can start using already registered device names for checks. Later on we probably want to start using struct gpmc_cs_data as a wrapper for all the GPMC chipselect related data. Acked-by: Roger Quadros <rogerq@ti.com> Signed-off-by: Tony Lindgren <tony@atomide.com>
-rw-r--r--arch/arm/mach-omap2/gpmc.c61
1 files changed, 49 insertions, 12 deletions
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 5fa3755261ce..2c5f3485e44c 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -118,6 +118,15 @@
118 */ 118 */
119#define GPMC_NR_IRQ 2 119#define GPMC_NR_IRQ 2
120 120
121struct gpmc_cs_data {
122 const char *name;
123
124#define GPMC_CS_RESERVED (1 << 0)
125 u32 flags;
126
127 struct resource mem;
128};
129
121struct gpmc_client_irq { 130struct gpmc_client_irq {
122 unsigned irq; 131 unsigned irq;
123 u32 bitmask; 132 u32 bitmask;
@@ -155,10 +164,9 @@ static struct irq_chip gpmc_irq_chip;
155static int gpmc_irq_start; 164static int gpmc_irq_start;
156 165
157static struct resource gpmc_mem_root; 166static struct resource gpmc_mem_root;
158static struct resource gpmc_cs_mem[GPMC_CS_NUM]; 167static struct gpmc_cs_data gpmc_cs[GPMC_CS_NUM];
159static DEFINE_SPINLOCK(gpmc_mem_lock); 168static DEFINE_SPINLOCK(gpmc_mem_lock);
160/* Define chip-selects as reserved by default until probe completes */ 169/* Define chip-selects as reserved by default until probe completes */
161static unsigned int gpmc_cs_map = ((1 << GPMC_CS_NUM) - 1);
162static unsigned int gpmc_cs_num = GPMC_CS_NUM; 170static unsigned int gpmc_cs_num = GPMC_CS_NUM;
163static unsigned int gpmc_nr_waitpins; 171static unsigned int gpmc_nr_waitpins;
164static struct device *gpmc_dev; 172static struct device *gpmc_dev;
@@ -460,13 +468,30 @@ static int gpmc_cs_mem_enabled(int cs)
460 468
461static void gpmc_cs_set_reserved(int cs, int reserved) 469static void gpmc_cs_set_reserved(int cs, int reserved)
462{ 470{
463 gpmc_cs_map &= ~(1 << cs); 471 struct gpmc_cs_data *gpmc = &gpmc_cs[cs];
464 gpmc_cs_map |= (reserved ? 1 : 0) << cs; 472
473 gpmc->flags |= GPMC_CS_RESERVED;
465} 474}
466 475
467static bool gpmc_cs_reserved(int cs) 476static bool gpmc_cs_reserved(int cs)
468{ 477{
469 return gpmc_cs_map & (1 << cs); 478 struct gpmc_cs_data *gpmc = &gpmc_cs[cs];
479
480 return gpmc->flags & GPMC_CS_RESERVED;
481}
482
483static void gpmc_cs_set_name(int cs, const char *name)
484{
485 struct gpmc_cs_data *gpmc = &gpmc_cs[cs];
486
487 gpmc->name = name;
488}
489
490const char *gpmc_cs_get_name(int cs)
491{
492 struct gpmc_cs_data *gpmc = &gpmc_cs[cs];
493
494 return gpmc->name;
470} 495}
471 496
472static unsigned long gpmc_mem_align(unsigned long size) 497static unsigned long gpmc_mem_align(unsigned long size)
@@ -485,7 +510,8 @@ static unsigned long gpmc_mem_align(unsigned long size)
485 510
486static int gpmc_cs_insert_mem(int cs, unsigned long base, unsigned long size) 511static int gpmc_cs_insert_mem(int cs, unsigned long base, unsigned long size)
487{ 512{
488 struct resource *res = &gpmc_cs_mem[cs]; 513 struct gpmc_cs_data *gpmc = &gpmc_cs[cs];
514 struct resource *res = &gpmc->mem;
489 int r; 515 int r;
490 516
491 size = gpmc_mem_align(size); 517 size = gpmc_mem_align(size);
@@ -500,7 +526,8 @@ static int gpmc_cs_insert_mem(int cs, unsigned long base, unsigned long size)
500 526
501static int gpmc_cs_delete_mem(int cs) 527static int gpmc_cs_delete_mem(int cs)
502{ 528{
503 struct resource *res = &gpmc_cs_mem[cs]; 529 struct gpmc_cs_data *gpmc = &gpmc_cs[cs];
530 struct resource *res = &gpmc->mem;
504 int r; 531 int r;
505 532
506 spin_lock(&gpmc_mem_lock); 533 spin_lock(&gpmc_mem_lock);
@@ -557,7 +584,8 @@ static int gpmc_cs_remap(int cs, u32 base)
557 584
558int gpmc_cs_request(int cs, unsigned long size, unsigned long *base) 585int gpmc_cs_request(int cs, unsigned long size, unsigned long *base)
559{ 586{
560 struct resource *res = &gpmc_cs_mem[cs]; 587 struct gpmc_cs_data *gpmc = &gpmc_cs[cs];
588 struct resource *res = &gpmc->mem;
561 int r = -1; 589 int r = -1;
562 590
563 if (cs > gpmc_cs_num) { 591 if (cs > gpmc_cs_num) {
@@ -597,7 +625,8 @@ EXPORT_SYMBOL(gpmc_cs_request);
597 625
598void gpmc_cs_free(int cs) 626void gpmc_cs_free(int cs)
599{ 627{
600 struct resource *res = &gpmc_cs_mem[cs]; 628 struct gpmc_cs_data *gpmc = &gpmc_cs[cs];
629 struct resource *res = &gpmc->mem;
601 630
602 spin_lock(&gpmc_mem_lock); 631 spin_lock(&gpmc_mem_lock);
603 if (cs >= gpmc_cs_num || cs < 0 || !gpmc_cs_reserved(cs)) { 632 if (cs >= gpmc_cs_num || cs < 0 || !gpmc_cs_reserved(cs)) {
@@ -1511,6 +1540,7 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
1511 struct gpmc_timings gpmc_t; 1540 struct gpmc_timings gpmc_t;
1512 struct resource res; 1541 struct resource res;
1513 unsigned long base; 1542 unsigned long base;
1543 const char *name;
1514 int ret, cs; 1544 int ret, cs;
1515 1545
1516 if (of_property_read_u32(child, "reg", &cs) < 0) { 1546 if (of_property_read_u32(child, "reg", &cs) < 0) {
@@ -1525,11 +1555,21 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
1525 return -ENODEV; 1555 return -ENODEV;
1526 } 1556 }
1527 1557
1558 /*
1559 * Check if we have multiple instances of the same device
1560 * on a single chip select. If so, use the already initialized
1561 * timings.
1562 */
1563 name = gpmc_cs_get_name(cs);
1564 if (name && child->name && of_node_cmp(child->name, name) == 0)
1565 goto no_timings;
1566
1528 ret = gpmc_cs_request(cs, resource_size(&res), &base); 1567 ret = gpmc_cs_request(cs, resource_size(&res), &base);
1529 if (ret < 0) { 1568 if (ret < 0) {
1530 dev_err(&pdev->dev, "cannot request GPMC CS %d\n", cs); 1569 dev_err(&pdev->dev, "cannot request GPMC CS %d\n", cs);
1531 return ret; 1570 return ret;
1532 } 1571 }
1572 gpmc_cs_set_name(cs, child->name);
1533 1573
1534 /* 1574 /*
1535 * For some GPMC devices we still need to rely on the bootloader 1575 * For some GPMC devices we still need to rely on the bootloader
@@ -1708,9 +1748,6 @@ static int gpmc_probe(struct platform_device *pdev)
1708 if (gpmc_setup_irq() < 0) 1748 if (gpmc_setup_irq() < 0)
1709 dev_warn(gpmc_dev, "gpmc_setup_irq failed\n"); 1749 dev_warn(gpmc_dev, "gpmc_setup_irq failed\n");
1710 1750
1711 /* Now the GPMC is initialised, unreserve the chip-selects */
1712 gpmc_cs_map = 0;
1713
1714 if (!pdev->dev.of_node) { 1751 if (!pdev->dev.of_node) {
1715 gpmc_cs_num = GPMC_CS_NUM; 1752 gpmc_cs_num = GPMC_CS_NUM;
1716 gpmc_nr_waitpins = GPMC_NR_WAITPINS; 1753 gpmc_nr_waitpins = GPMC_NR_WAITPINS;