summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorYe.Li <B37916@freescale.com>2014-06-11 16:21:29 +0800
committerYe Li <ye.li@nxp.com>2017-03-14 21:27:09 +0800
commit7cd5fec7ce6a9ecfdaa1a9c1aaaa0d0ac18a4f86 (patch)
treedfc89ac4939eddc9e0e47de3c404192f64de1577 /drivers
parent5364f297ccbb89c796cc9a67e28fe50d3ee2dad1 (diff)
downloadu-boot-imx-7cd5fec7ce6a9ecfdaa1a9c1aaaa0d0ac18a4f86.zip
u-boot-imx-7cd5fec7ce6a9ecfdaa1a9c1aaaa0d0ac18a4f86.tar.gz
u-boot-imx-7cd5fec7ce6a9ecfdaa1a9c1aaaa0d0ac18a4f86.tar.bz2
ENGR00315894-60 GPIO: Modify driver mxc_gpio to support RDC Semaphores
For GPIO group which shared by multiple masters, it may set in RDC to shared and semaphore required. Before access the GPIO register, the GPIO driver must get the RDC semaphore, and release the semaphore after the GPIO register access. When CONFIG_MXC_RDC is set, the features related to RDC semaphores is enabled in mxc_gpio driver. Signed-off-by: Ye.Li <B37916@freescale.com> (cherry picked from commit 84d63e2e2ce12f714e88baad8b2325684614a7c1) Signed-off-by: Peng Fan <Peng.Fan@freescale.com> Conflicts: drivers/gpio/mxc_gpio.c (cherry picked from commit c9943b9c8a78bb2c9886bfe582e82978387d8dee) Signed-off-by: Peng Fan <Peng.Fan@freescale.com> (cherry picked from commit faf94726cac8316c4342e19936f1e03ef283ace3) (cherry picked from commit 6c0474fe0e4fc543c62b22c05c2702a881f56418)
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpio/mxc_gpio.c53
1 files changed, 53 insertions, 0 deletions
diff --git a/drivers/gpio/mxc_gpio.c b/drivers/gpio/mxc_gpio.c
index 70fe5b6..3631803 100644
--- a/drivers/gpio/mxc_gpio.c
+++ b/drivers/gpio/mxc_gpio.c
@@ -5,6 +5,8 @@
* Copyright (C) 2011
* Stefano Babic, DENX Software Engineering, <sbabic@denx.de>
*
+ * Copyright (C) 2015-2016 Freescale Semiconductor, Inc.
+ *
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
@@ -14,6 +16,11 @@
#include <asm/arch/imx-regs.h>
#include <asm/gpio.h>
#include <asm/io.h>
+#include <errno.h>
+#ifdef CONFIG_IMX_RDC
+#include <asm/imx-common/rdc-sema.h>
+#include <asm/arch/imx-rdc.h>
+#endif
enum mxc_gpio_direction {
MXC_GPIO_DIRECTION_IN,
@@ -58,6 +65,27 @@ static unsigned long gpio_ports[] = {
#endif
};
+#ifdef CONFIG_IMX_RDC
+static unsigned int gpio_rdc[] = {
+ RDC_PER_GPIO1,
+ RDC_PER_GPIO2,
+ RDC_PER_GPIO3,
+ RDC_PER_GPIO4,
+ RDC_PER_GPIO5,
+ RDC_PER_GPIO6,
+ RDC_PER_GPIO7,
+};
+
+#define RDC_CHECK(x) imx_rdc_check_permission(gpio_rdc[x], 0)
+#define RDC_SPINLOCK_UP(x) imx_rdc_sema_lock(gpio_rdc[x])
+#define RDC_SPINLOCK_DOWN(x) imx_rdc_sema_unlock(gpio_rdc[x])
+#else
+#define RDC_CHECK(x) 0
+#define RDC_SPINLOCK_UP(x)
+#define RDC_SPINLOCK_DOWN(x)
+#endif
+
+
static int mxc_gpio_direction(unsigned int gpio,
enum mxc_gpio_direction direction)
{
@@ -68,6 +96,11 @@ static int mxc_gpio_direction(unsigned int gpio,
if (port >= ARRAY_SIZE(gpio_ports))
return -1;
+ if (RDC_CHECK(port))
+ return -1;
+
+ RDC_SPINLOCK_UP(port);
+
gpio &= 0x1f;
regs = (struct gpio_regs *)gpio_ports[port];
@@ -83,6 +116,8 @@ static int mxc_gpio_direction(unsigned int gpio,
}
writel(l, &regs->gpio_dir);
+ RDC_SPINLOCK_DOWN(port);
+
return 0;
}
@@ -95,6 +130,11 @@ int gpio_set_value(unsigned gpio, int value)
if (port >= ARRAY_SIZE(gpio_ports))
return -1;
+ if (RDC_CHECK(port))
+ return -1;
+
+ RDC_SPINLOCK_UP(port);
+
gpio &= 0x1f;
regs = (struct gpio_regs *)gpio_ports[port];
@@ -106,6 +146,8 @@ int gpio_set_value(unsigned gpio, int value)
l &= ~(1 << gpio);
writel(l, &regs->gpio_dr);
+ RDC_SPINLOCK_DOWN(port);
+
return 0;
}
@@ -118,12 +160,19 @@ int gpio_get_value(unsigned gpio)
if (port >= ARRAY_SIZE(gpio_ports))
return -1;
+ if (RDC_CHECK(port))
+ return -1;
+
+ RDC_SPINLOCK_UP(port);
+
gpio &= 0x1f;
regs = (struct gpio_regs *)gpio_ports[port];
val = (readl(&regs->gpio_psr) >> gpio) & 0x01;
+ RDC_SPINLOCK_DOWN(port);
+
return val;
}
@@ -132,6 +181,10 @@ int gpio_request(unsigned gpio, const char *label)
unsigned int port = GPIO_TO_PORT(gpio);
if (port >= ARRAY_SIZE(gpio_ports))
return -1;
+
+ if (RDC_CHECK(port))
+ return -1;
+
return 0;
}