diff options
author | Gupta Pekon <pekon@ti.com> | 2013-05-31 08:01:30 -0400 |
---|---|---|
committer | Tony Lindgren <tony@atomide.com> | 2013-06-12 12:54:28 -0400 |
commit | f34f37160c2960a763ed05d1e13b2ea75a48d0fb (patch) | |
tree | 62afbbc1a3b12c9d7ec4fb346d98da6732fb41b2 /arch/arm/mach-omap2/gpmc.c | |
parent | f40739faba8e804cf46505869ab98ad7c4a88833 (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.c | 38 |
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]; | |||
155 | static DEFINE_SPINLOCK(gpmc_mem_lock); | 155 | static 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 */ |
157 | static unsigned int gpmc_cs_map = ((1 << GPMC_CS_NUM) - 1); | 157 | static unsigned int gpmc_cs_map = ((1 << GPMC_CS_NUM) - 1); |
158 | static unsigned int gpmc_cs_num = GPMC_CS_NUM; | ||
158 | static unsigned int gpmc_nr_waitpins; | 159 | static unsigned int gpmc_nr_waitpins; |
159 | static struct device *gpmc_dev; | 160 | static struct device *gpmc_dev; |
160 | static int gpmc_irq; | 161 | static 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); | |||
582 | void gpmc_cs_free(int cs) | 586 | void 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); |