summaryrefslogtreecommitdiffstats
path: root/drivers/gpio
diff options
context:
space:
mode:
authorAnson Huang <Anson.Huang@nxp.com>2018-05-22 11:05:40 +0800
committerLinus Walleij <linus.walleij@linaro.org>2018-05-24 10:09:46 +0200
commit2808801aab8a595b5bb66c43e2f8b3f3a025cf79 (patch)
treea69b5e1f5a352c688099511d03426e3f25766efe /drivers/gpio
parent3027743f83f867d85662f5134e835c2e199cb9be (diff)
downloadlinux-2808801aab8a595b5bb66c43e2f8b3f3a025cf79.tar.bz2
gpio: mxc: add clock operation
Some i.MX SoCs have GPIO clock gates in CCM CCGR, such as i.MX6SLL, need to enable clocks before accessing GPIO registers, add optional clock operation for GPIO driver. Signed-off-by: Anson Huang <Anson.Huang@nxp.com> Reviewed-by: Fabio Estevam <fabio.estevam@nxp.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/gpio')
-rw-r--r--drivers/gpio/gpio-mxc.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/drivers/gpio/gpio-mxc.c b/drivers/gpio/gpio-mxc.c
index 11ec7228ab08..f4dc31d88a04 100644
--- a/drivers/gpio/gpio-mxc.c
+++ b/drivers/gpio/gpio-mxc.c
@@ -20,6 +20,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+#include <linux/clk.h>
#include <linux/err.h>
#include <linux/init.h>
#include <linux/interrupt.h>
@@ -60,6 +61,7 @@ struct mxc_gpio_hwdata {
struct mxc_gpio_port {
struct list_head node;
void __iomem *base;
+ struct clk *clk;
int irq;
int irq_high;
struct irq_domain *domain;
@@ -434,6 +436,17 @@ static int mxc_gpio_probe(struct platform_device *pdev)
if (port->irq < 0)
return port->irq;
+ /* the controller clock is optional */
+ port->clk = devm_clk_get(&pdev->dev, NULL);
+ if (IS_ERR(port->clk))
+ port->clk = NULL;
+
+ err = clk_prepare_enable(port->clk);
+ if (err) {
+ dev_err(&pdev->dev, "Unable to enable clock.\n");
+ return err;
+ }
+
/* disable the interrupt and clear the status */
writel(0, port->base + GPIO_IMR);
writel(~0, port->base + GPIO_ISR);
@@ -502,6 +515,7 @@ static int mxc_gpio_probe(struct platform_device *pdev)
out_irqdomain_remove:
irq_domain_remove(port->domain);
out_bgio:
+ clk_disable_unprepare(port->clk);
dev_info(&pdev->dev, "%s failed with errno %d\n", __func__, err);
return err;
}