[linux-yocto] [PATCH 01/12] gpio: gpio-octeon: Add preliminary cn78XX support.
Chandrakala Chavva
cchavva.cavm at gmail.com
Thu Jan 29 07:32:00 PST 2015
From: Abhishek Paliwal <abhishek.paliwal at aricent.com>
From: David Daney <david.daney at cavium.com>
The addresses of the GPIO_BIT_CFG registers have a different layout on
cn78XX.
Define OF_GPIO_OPEN_DRAIN flag for Open Drain outputs.
Signed-off-by: David Daney <david.daney at cavium.com>
Signed-off-by: Abhishek Paliwal <abhishek.paliwal at aricent.com>
---
drivers/gpio/gpio-octeon.c | 50 +++++++++++++++++++++++++++++++---------------
include/linux/of_gpio.h | 1 +
2 files changed, 35 insertions(+), 16 deletions(-)
diff --git a/drivers/gpio/gpio-octeon.c b/drivers/gpio/gpio-octeon.c
index dbb0854..3fd5837 100644
--- a/drivers/gpio/gpio-octeon.c
+++ b/drivers/gpio/gpio-octeon.c
@@ -6,7 +6,7 @@
* Copyright (C) 2011, 2012 Cavium Inc.
*/
-#include <linux/platform_device.h>
+#include <linux/of_device.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/gpio.h>
@@ -18,11 +18,18 @@
#define RX_DAT 0x80
#define TX_SET 0x88
#define TX_CLEAR 0x90
+
+struct octeon_gpio {
+ struct gpio_chip chip;
+ u64 register_base;
+ unsigned int (*cfg_reg)(unsigned int);
+};
+
/*
* The address offset of the GPIO configuration register for a given
* line.
*/
-static unsigned int bit_cfg_reg(unsigned int offset)
+static unsigned int bit_cfg_reg38(unsigned int offset)
{
/*
* The register stride is 8, with a discontinuity after the
@@ -34,16 +41,16 @@ static unsigned int bit_cfg_reg(unsigned int offset)
return 8 * (offset - 16) + 0x100;
}
-struct octeon_gpio {
- struct gpio_chip chip;
- u64 register_base;
-};
+static unsigned int bit_cfg_reg78(unsigned int gpio)
+{
+ return (8 * gpio) + 0x100;
+}
static int octeon_gpio_dir_in(struct gpio_chip *chip, unsigned offset)
{
struct octeon_gpio *gpio = container_of(chip, struct octeon_gpio, chip);
- cvmx_write_csr(gpio->register_base + bit_cfg_reg(offset), 0);
+ cvmx_write_csr(gpio->register_base + gpio->cfg_reg(offset), 0);
return 0;
}
@@ -66,7 +73,7 @@ static int octeon_gpio_dir_out(struct gpio_chip *chip, unsigned offset,
cfgx.u64 = 0;
cfgx.s.tx_oe = 1;
- cvmx_write_csr(gpio->register_base + bit_cfg_reg(offset), cfgx.u64);
+ cvmx_write_csr(gpio->register_base + gpio->cfg_reg(offset), cfgx.u64);
return 0;
}
@@ -78,17 +85,36 @@ static int octeon_gpio_get(struct gpio_chip *chip, unsigned offset)
return ((1ull << offset) & read_bits) != 0;
}
+static struct of_device_id octeon_gpio_match[] = {
+ {
+ .compatible = "cavium,octeon-3860-gpio",
+ .data = bit_cfg_reg38,
+ },
+ {
+ .compatible = "cavium,octeon-7890-gpio",
+ .data = bit_cfg_reg78,
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(of, octeon_gpio_match);
+
static int octeon_gpio_probe(struct platform_device *pdev)
{
struct octeon_gpio *gpio;
struct gpio_chip *chip;
struct resource *res_mem;
+ const struct of_device_id *of_id;
int err = 0;
+ of_id = of_match_device(octeon_gpio_match, &pdev->dev);
+ if (!of_id)
+ return -EINVAL;
+
gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL);
if (!gpio)
return -ENOMEM;
chip = &gpio->chip;
+ gpio->cfg_reg = of_id->data;
res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (res_mem == NULL) {
@@ -132,14 +158,6 @@ static int octeon_gpio_remove(struct platform_device *pdev)
return gpiochip_remove(chip);
}
-static struct of_device_id octeon_gpio_match[] = {
- {
- .compatible = "cavium,octeon-3860-gpio",
- },
- {},
-};
-MODULE_DEVICE_TABLE(of, octeon_gpio_match);
-
static struct platform_driver octeon_gpio_driver = {
.driver = {
.name = "octeon_gpio",
diff --git a/include/linux/of_gpio.h b/include/linux/of_gpio.h
index f14123a..0e37477 100644
--- a/include/linux/of_gpio.h
+++ b/include/linux/of_gpio.h
@@ -30,6 +30,7 @@ struct device_node;
*/
enum of_gpio_flags {
OF_GPIO_ACTIVE_LOW = 0x1,
+ OF_GPIO_OPEN_DRAIN = 0x2,
};
#ifdef CONFIG_OF_GPIO
--
1.8.1.4
More information about the linux-yocto
mailing list