forked from skristiansson/linux
-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
gpio: Loongson1: add Loongson1 GPIO driver
This patch adds GPIO driver for Loongson1B. Signed-off-by: Kelvin Cheung <keguang.zhang@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
- Loading branch information
1 parent
6b5029d
commit bd37c99
Showing
3 changed files
with
110 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
/* | ||
* GPIO Driver for Loongson 1 SoC | ||
* | ||
* Copyright (C) 2015-2016 Zhang, Keguang <keguang.zhang@gmail.com> | ||
* | ||
* This file is licensed under the terms of the GNU General Public | ||
* License version 2. This program is licensed "as is" without any | ||
* warranty of any kind, whether express or implied. | ||
*/ | ||
|
||
#include <linux/gpio/driver.h> | ||
#include <linux/platform_device.h> | ||
|
||
/* Loongson 1 GPIO Register Definitions */ | ||
#define GPIO_CFG 0x0 | ||
#define GPIO_DIR 0x10 | ||
#define GPIO_DATA 0x20 | ||
#define GPIO_OUTPUT 0x30 | ||
|
||
static void __iomem *gpio_reg_base; | ||
|
||
static int ls1x_gpio_request(struct gpio_chip *gc, unsigned int offset) | ||
{ | ||
unsigned long pinmask = gc->pin2mask(gc, offset); | ||
unsigned long flags; | ||
|
||
spin_lock_irqsave(&gc->bgpio_lock, flags); | ||
__raw_writel(__raw_readl(gpio_reg_base + GPIO_CFG) | pinmask, | ||
gpio_reg_base + GPIO_CFG); | ||
spin_unlock_irqrestore(&gc->bgpio_lock, flags); | ||
|
||
return 0; | ||
} | ||
|
||
static void ls1x_gpio_free(struct gpio_chip *gc, unsigned int offset) | ||
{ | ||
unsigned long pinmask = gc->pin2mask(gc, offset); | ||
unsigned long flags; | ||
|
||
spin_lock_irqsave(&gc->bgpio_lock, flags); | ||
__raw_writel(__raw_readl(gpio_reg_base + GPIO_CFG) & ~pinmask, | ||
gpio_reg_base + GPIO_CFG); | ||
spin_unlock_irqrestore(&gc->bgpio_lock, flags); | ||
} | ||
|
||
static int ls1x_gpio_probe(struct platform_device *pdev) | ||
{ | ||
struct device *dev = &pdev->dev; | ||
struct gpio_chip *gc; | ||
struct resource *res; | ||
int ret; | ||
|
||
gc = devm_kzalloc(dev, sizeof(*gc), GFP_KERNEL); | ||
if (!gc) | ||
return -ENOMEM; | ||
|
||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
if (!res) { | ||
dev_err(dev, "failed to get I/O memory\n"); | ||
return -EINVAL; | ||
} | ||
|
||
gpio_reg_base = devm_ioremap_resource(dev, res); | ||
if (IS_ERR(gpio_reg_base)) | ||
return PTR_ERR(gpio_reg_base); | ||
|
||
ret = bgpio_init(gc, dev, 4, gpio_reg_base + GPIO_DATA, | ||
gpio_reg_base + GPIO_OUTPUT, NULL, | ||
NULL, gpio_reg_base + GPIO_DIR, 0); | ||
if (ret) | ||
goto err; | ||
|
||
gc->owner = THIS_MODULE; | ||
gc->request = ls1x_gpio_request; | ||
gc->free = ls1x_gpio_free; | ||
gc->base = pdev->id * 32; | ||
|
||
ret = devm_gpiochip_add_data(dev, gc, NULL); | ||
if (ret) | ||
goto err; | ||
|
||
platform_set_drvdata(pdev, gc); | ||
dev_info(dev, "Loongson1 GPIO driver registered\n"); | ||
|
||
return 0; | ||
err: | ||
dev_err(dev, "failed to register GPIO device\n"); | ||
return ret; | ||
} | ||
|
||
static struct platform_driver ls1x_gpio_driver = { | ||
.probe = ls1x_gpio_probe, | ||
.driver = { | ||
.name = "ls1x-gpio", | ||
}, | ||
}; | ||
|
||
module_platform_driver(ls1x_gpio_driver); | ||
|
||
MODULE_AUTHOR("Kelvin Cheung <keguang.zhang@gmail.com>"); | ||
MODULE_DESCRIPTION("Loongson1 GPIO driver"); | ||
MODULE_LICENSE("GPL"); |