summaryrefslogtreecommitdiff
path: root/drivers/gpio
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpio')
-rw-r--r--drivers/gpio/74x164_gpio.c3
-rw-r--r--drivers/gpio/Kconfig8
-rw-r--r--drivers/gpio/intel_ich6_gpio.c30
-rw-r--r--drivers/gpio/sh_pfc.c17
4 files changed, 45 insertions, 13 deletions
diff --git a/drivers/gpio/74x164_gpio.c b/drivers/gpio/74x164_gpio.c
index 750eedfffd..53a639ae65 100644
--- a/drivers/gpio/74x164_gpio.c
+++ b/drivers/gpio/74x164_gpio.c
@@ -156,8 +156,7 @@ static int gen_74x164_probe(struct udevice *dev)
ret = gpio_request_by_name(dev, "oe-gpios", 0, &priv->oe,
GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
if (ret) {
- dev_err(dev, "No oe-pins property\n");
- goto free_buf;
+ dev_dbg(dev, "No oe-pins property\n");
}
uc_priv->bank_name = str;
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 325d053931..15135e538d 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -95,6 +95,14 @@ config MSM_GPIO
- APQ8016
- MSM8916
+config OMAP_GPIO
+ bool "TI OMAP GPIO driver"
+ depends on ARCH_OMAP2PLUS
+ default y
+ help
+ Support GPIO controllers on the TI OMAP3/4/5 and related (such as
+ AM335x/AM43xx/AM57xx/DRA7xx/etc) families of SoCs.
+
config PM8916_GPIO
bool "Qualcomm PM8916 PMIC GPIO/keypad driver"
depends on DM_GPIO && PMIC_PM8916
diff --git a/drivers/gpio/intel_ich6_gpio.c b/drivers/gpio/intel_ich6_gpio.c
index 8b782260bc..0a9eb03fd0 100644
--- a/drivers/gpio/intel_ich6_gpio.c
+++ b/drivers/gpio/intel_ich6_gpio.c
@@ -46,22 +46,31 @@ struct ich6_bank_priv {
uint16_t use_sel;
uint16_t io_sel;
uint16_t lvl;
+ u32 lvl_write_cache;
+ bool use_lvl_write_cache;
};
#define GPIO_USESEL_OFFSET(x) (x)
#define GPIO_IOSEL_OFFSET(x) (x + 4)
#define GPIO_LVL_OFFSET(x) (x + 8)
-static int _ich6_gpio_set_value(uint16_t base, unsigned offset, int value)
+static int _ich6_gpio_set_value(struct ich6_bank_priv *bank, unsigned offset,
+ int value)
{
u32 val;
- val = inl(base);
+ if (bank->use_lvl_write_cache)
+ val = bank->lvl_write_cache;
+ else
+ val = inl(bank->lvl);
+
if (value)
val |= (1UL << offset);
else
val &= ~(1UL << offset);
- outl(val, base);
+ outl(val, bank->lvl);
+ if (bank->use_lvl_write_cache)
+ bank->lvl_write_cache = val;
return 0;
}
@@ -112,6 +121,7 @@ static int ich6_gpio_probe(struct udevice *dev)
struct ich6_bank_platdata *plat = dev_get_platdata(dev);
struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
struct ich6_bank_priv *bank = dev_get_priv(dev);
+ const void *prop;
uc_priv->gpio_count = GPIO_PER_BANK;
uc_priv->bank_name = plat->bank_name;
@@ -119,6 +129,14 @@ static int ich6_gpio_probe(struct udevice *dev)
bank->io_sel = plat->base_addr + 4;
bank->lvl = plat->base_addr + 8;
+ prop = fdt_getprop(gd->fdt_blob, dev->of_offset,
+ "use-lvl-write-cache", NULL);
+ if (prop)
+ bank->use_lvl_write_cache = true;
+ else
+ bank->use_lvl_write_cache = false;
+ bank->lvl_write_cache = 0;
+
return 0;
}
@@ -160,7 +178,7 @@ static int ich6_gpio_direction_output(struct udevice *dev, unsigned offset,
if (ret)
return ret;
- return _ich6_gpio_set_value(bank->lvl, offset, value);
+ return _ich6_gpio_set_value(bank, offset, value);
}
static int ich6_gpio_get_value(struct udevice *dev, unsigned offset)
@@ -170,6 +188,8 @@ static int ich6_gpio_get_value(struct udevice *dev, unsigned offset)
int r;
tmplong = inl(bank->lvl);
+ if (bank->use_lvl_write_cache)
+ tmplong |= bank->lvl_write_cache;
r = (tmplong & (1UL << offset)) ? 1 : 0;
return r;
}
@@ -178,7 +198,7 @@ static int ich6_gpio_set_value(struct udevice *dev, unsigned offset,
int value)
{
struct ich6_bank_priv *bank = dev_get_priv(dev);
- return _ich6_gpio_set_value(bank->lvl, offset, value);
+ return _ich6_gpio_set_value(bank, offset, value);
}
static int ich6_gpio_get_function(struct udevice *dev, unsigned offset)
diff --git a/drivers/gpio/sh_pfc.c b/drivers/gpio/sh_pfc.c
index a0eac137c2..ad8da9ef28 100644
--- a/drivers/gpio/sh_pfc.c
+++ b/drivers/gpio/sh_pfc.c
@@ -66,17 +66,18 @@ static void gpio_write_raw_reg(void *mapped_reg,
}
static int gpio_read_bit(struct pinmux_data_reg *dr,
+ unsigned long offset,
unsigned long in_pos)
{
unsigned long pos;
pos = dr->reg_width - (in_pos + 1);
- debug("read_bit: addr = %lx, pos = %ld, "
- "r_width = %ld\n", dr->reg, pos, dr->reg_width);
+ debug("read_bit: addr = %lx, pos = %ld, r_width = %ld\n",
+ dr->reg + offset, pos, dr->reg_width);
- return
- (gpio_read_raw_reg(dr->mapped_reg + 0x4, dr->reg_width) >> pos) & 1;
+ return (gpio_read_raw_reg(dr->mapped_reg + offset,
+ dr->reg_width) >> pos) & 1;
}
static void gpio_write_bit(struct pinmux_data_reg *dr,
@@ -559,12 +560,16 @@ static int sh_gpio_direction_output(unsigned offset, int value)
static int sh_gpio_get_value(struct pinmux_info *gpioc, unsigned gpio)
{
struct pinmux_data_reg *dr = NULL;
- int bit = 0;
+ int bit = 0, offset = 0;
if (!gpioc || get_data_reg(gpioc, gpio, &dr, &bit) != 0)
return -1;
+#if defined(CONFIG_RCAR_GEN3)
+ if ((gpioc->gpios[gpio].flags & PINMUX_FLAG_TYPE) == PINMUX_TYPE_INPUT)
+ offset += 4;
+#endif
- return gpio_read_bit(dr, bit);
+ return gpio_read_bit(dr, offset, bit);
}
static int sh_gpio_get(unsigned offset)