aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/gpmc.c
diff options
context:
space:
mode:
authorGupta Pekon <pekon@ti.com>2013-05-31 08:01:30 -0400
committerTony Lindgren <tony@atomide.com>2013-06-12 12:54:28 -0400
commitf34f37160c2960a763ed05d1e13b2ea75a48d0fb (patch)
tree62afbbc1a3b12c9d7ec4fb346d98da6732fb41b2 /arch/arm/mach-omap2/gpmc.c
parentf40739faba8e804cf46505869ab98ad7c4a88833 (diff)
ARM: OMAP2+: gpmc: get number of useable GPMC chip-selects via DT
This patch enables usage of DT property 'gpmc,num-cs' as already documented in Documentation/devicetree/bindings/bus/ti-gpmc.txt Though GPMC hardware supports upto 8 chip-selects, but all chip-selects may not be available for use because: - chip-select pin may not be bonded out at SoC device boundary. - chip-select pin-mux may conflict with other pins usage. - board level constrains. gpmc,num-cs allows user to configure maximum number of GPMC chip-selects available for use on any given platform. This ensures: - GPMC child nodes having chip-selects within allowed range are only probed. - And un-used GPMC chip-selects remain blocked.(may be for security reasons). Signed-off-by: Gupta, Pekon <pekon@ti.com> Signed-off-by: Tony Lindgren <tony@atomide.com>
Diffstat (limited to 'arch/arm/mach-omap2/gpmc.c')
-rw-r--r--arch/arm/mach-omap2/gpmc.c38
1 files changed, 29 insertions, 9 deletions
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 70d11ceec0d7..21b963604430 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -155,6 +155,7 @@ static struct resource gpmc_cs_mem[GPMC_CS_NUM];
155static DEFINE_SPINLOCK(gpmc_mem_lock); 155static DEFINE_SPINLOCK(gpmc_mem_lock);
156/* Define chip-selects as reserved by default until probe completes */ 156/* Define chip-selects as reserved by default until probe completes */
157static unsigned int gpmc_cs_map = ((1 << GPMC_CS_NUM) - 1); 157static unsigned int gpmc_cs_map = ((1 << GPMC_CS_NUM) - 1);
158static unsigned int gpmc_cs_num = GPMC_CS_NUM;
158static unsigned int gpmc_nr_waitpins; 159static unsigned int gpmc_nr_waitpins;
159static struct device *gpmc_dev; 160static struct device *gpmc_dev;
160static int gpmc_irq; 161static int gpmc_irq;
@@ -521,8 +522,10 @@ static int gpmc_cs_remap(int cs, u32 base)
521 int ret; 522 int ret;
522 u32 old_base, size; 523 u32 old_base, size;
523 524
524 if (cs > GPMC_CS_NUM) 525 if (cs > gpmc_cs_num) {
526 pr_err("%s: requested chip-select is disabled\n", __func__);
525 return -ENODEV; 527 return -ENODEV;
528 }
526 gpmc_cs_get_memconf(cs, &old_base, &size); 529 gpmc_cs_get_memconf(cs, &old_base, &size);
527 if (base == old_base) 530 if (base == old_base)
528 return 0; 531 return 0;
@@ -545,9 +548,10 @@ int gpmc_cs_request(int cs, unsigned long size, unsigned long *base)
545 struct resource *res = &gpmc_cs_mem[cs]; 548 struct resource *res = &gpmc_cs_mem[cs];
546 int r = -1; 549 int r = -1;
547 550
548 if (cs > GPMC_CS_NUM) 551 if (cs > gpmc_cs_num) {
552 pr_err("%s: requested chip-select is disabled\n", __func__);
549 return -ENODEV; 553 return -ENODEV;
550 554 }
551 size = gpmc_mem_align(size); 555 size = gpmc_mem_align(size);
552 if (size > (1 << GPMC_SECTION_SHIFT)) 556 if (size > (1 << GPMC_SECTION_SHIFT))
553 return -ENOMEM; 557 return -ENOMEM;
@@ -582,7 +586,7 @@ EXPORT_SYMBOL(gpmc_cs_request);
582void gpmc_cs_free(int cs) 586void gpmc_cs_free(int cs)
583{ 587{
584 spin_lock(&gpmc_mem_lock); 588 spin_lock(&gpmc_mem_lock);
585 if (cs >= GPMC_CS_NUM || cs < 0 || !gpmc_cs_reserved(cs)) { 589 if (cs >= gpmc_cs_num || cs < 0 || !gpmc_cs_reserved(cs)) {
586 printk(KERN_ERR "Trying to free non-reserved GPMC CS%d\n", cs); 590 printk(KERN_ERR "Trying to free non-reserved GPMC CS%d\n", cs);
587 BUG(); 591 BUG();
588 spin_unlock(&gpmc_mem_lock); 592 spin_unlock(&gpmc_mem_lock);
@@ -777,7 +781,7 @@ static void gpmc_mem_exit(void)
777{ 781{
778 int cs; 782 int cs;
779 783
780 for (cs = 0; cs < GPMC_CS_NUM; cs++) { 784 for (cs = 0; cs < gpmc_cs_num; cs++) {
781 if (!gpmc_cs_mem_enabled(cs)) 785 if (!gpmc_cs_mem_enabled(cs))
782 continue; 786 continue;
783 gpmc_cs_delete_mem(cs); 787 gpmc_cs_delete_mem(cs);
@@ -798,7 +802,7 @@ static void gpmc_mem_init(void)
798 gpmc_mem_root.end = GPMC_MEM_END; 802 gpmc_mem_root.end = GPMC_MEM_END;
799 803
800 /* Reserve all regions that has been set up by bootloader */ 804 /* Reserve all regions that has been set up by bootloader */
801 for (cs = 0; cs < GPMC_CS_NUM; cs++) { 805 for (cs = 0; cs < gpmc_cs_num; cs++) {
802 u32 base, size; 806 u32 base, size;
803 807
804 if (!gpmc_cs_mem_enabled(cs)) 808 if (!gpmc_cs_mem_enabled(cs))
@@ -1526,6 +1530,20 @@ static int gpmc_probe_dt(struct platform_device *pdev)
1526 if (!of_id) 1530 if (!of_id)
1527 return 0; 1531 return 0;
1528 1532
1533 ret = of_property_read_u32(pdev->dev.of_node, "gpmc,num-cs",
1534 &gpmc_cs_num);
1535 if (ret < 0) {
1536 pr_err("%s: number of chip-selects not defined\n", __func__);
1537 return ret;
1538 } else if (gpmc_cs_num < 1) {
1539 pr_err("%s: all chip-selects are disabled\n", __func__);
1540 return -EINVAL;
1541 } else if (gpmc_cs_num > GPMC_CS_NUM) {
1542 pr_err("%s: number of supported chip-selects cannot be > %d\n",
1543 __func__, GPMC_CS_NUM);
1544 return -EINVAL;
1545 }
1546
1529 ret = of_property_read_u32(pdev->dev.of_node, "gpmc,num-waitpins", 1547 ret = of_property_read_u32(pdev->dev.of_node, "gpmc,num-waitpins",
1530 &gpmc_nr_waitpins); 1548 &gpmc_nr_waitpins);
1531 if (ret < 0) { 1549 if (ret < 0) {
@@ -1623,8 +1641,10 @@ static int gpmc_probe(struct platform_device *pdev)
1623 /* Now the GPMC is initialised, unreserve the chip-selects */ 1641 /* Now the GPMC is initialised, unreserve the chip-selects */
1624 gpmc_cs_map = 0; 1642 gpmc_cs_map = 0;
1625 1643
1626 if (!pdev->dev.of_node) 1644 if (!pdev->dev.of_node) {
1645 gpmc_cs_num = GPMC_CS_NUM;
1627 gpmc_nr_waitpins = GPMC_NR_WAITPINS; 1646 gpmc_nr_waitpins = GPMC_NR_WAITPINS;
1647 }
1628 1648
1629 rc = gpmc_probe_dt(pdev); 1649 rc = gpmc_probe_dt(pdev);
1630 if (rc < 0) { 1650 if (rc < 0) {
@@ -1728,7 +1748,7 @@ void omap3_gpmc_save_context(void)
1728 gpmc_context.prefetch_config1 = gpmc_read_reg(GPMC_PREFETCH_CONFIG1); 1748 gpmc_context.prefetch_config1 = gpmc_read_reg(GPMC_PREFETCH_CONFIG1);
1729 gpmc_context.prefetch_config2 = gpmc_read_reg(GPMC_PREFETCH_CONFIG2); 1749 gpmc_context.prefetch_config2 = gpmc_read_reg(GPMC_PREFETCH_CONFIG2);
1730 gpmc_context.prefetch_control = gpmc_read_reg(GPMC_PREFETCH_CONTROL); 1750 gpmc_context.prefetch_control = gpmc_read_reg(GPMC_PREFETCH_CONTROL);
1731 for (i = 0; i < GPMC_CS_NUM; i++) { 1751 for (i = 0; i < gpmc_cs_num; i++) {
1732 gpmc_context.cs_context[i].is_valid = gpmc_cs_mem_enabled(i); 1752 gpmc_context.cs_context[i].is_valid = gpmc_cs_mem_enabled(i);
1733 if (gpmc_context.cs_context[i].is_valid) { 1753 if (gpmc_context.cs_context[i].is_valid) {
1734 gpmc_context.cs_context[i].config1 = 1754 gpmc_context.cs_context[i].config1 =
@@ -1760,7 +1780,7 @@ void omap3_gpmc_restore_context(void)
1760 gpmc_write_reg(GPMC_PREFETCH_CONFIG1, gpmc_context.prefetch_config1); 1780 gpmc_write_reg(GPMC_PREFETCH_CONFIG1, gpmc_context.prefetch_config1);
1761 gpmc_write_reg(GPMC_PREFETCH_CONFIG2, gpmc_context.prefetch_config2); 1781 gpmc_write_reg(GPMC_PREFETCH_CONFIG2, gpmc_context.prefetch_config2);
1762 gpmc_write_reg(GPMC_PREFETCH_CONTROL, gpmc_context.prefetch_control); 1782 gpmc_write_reg(GPMC_PREFETCH_CONTROL, gpmc_context.prefetch_control);
1763 for (i = 0; i < GPMC_CS_NUM; i++) { 1783 for (i = 0; i < gpmc_cs_num; i++) {
1764 if (gpmc_context.cs_context[i].is_valid) { 1784 if (gpmc_context.cs_context[i].is_valid) {
1765 gpmc_cs_write_reg(i, GPMC_CS_CONFIG1, 1785 gpmc_cs_write_reg(i, GPMC_CS_CONFIG1,
1766 gpmc_context.cs_context[i].config1); 1786 gpmc_context.cs_context[i].config1);