Commit c501d0b1 authored by Cristina Ciocan's avatar Cristina Ciocan Committed by Linus Walleij

pinctrl: baytrail: Add pin control operations

Add implementation for:
- pin control, group information retrieval: count, name and pins
- pin muxing:
  - function information (count, name and groups)
  - mux setting
  - gpio control (enable, disable, set direction)
- pin configuration:
  - pull disable
  - pull up/down and pull strength
  - debounce
  - any other option is treated as not supported.
Signed-off-by: default avatarCristina Ciocan <cristina.ciocan@intel.com>
Acked-by: default avatarMika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
parent c8f5c4c7
......@@ -6,6 +6,9 @@ config PINCTRL_BAYTRAIL
bool "Intel Baytrail GPIO pin control"
depends on GPIOLIB && ACPI
select GPIOLIB_IRQCHIP
select PINMUX
select PINCONF
select GENERIC_PINCONF
help
driver for memory mapped GPIO functionality on Intel Baytrail
platforms. Supports 3 banks with 102, 28 and 44 gpios.
......
......@@ -27,6 +27,9 @@
#include <linux/io.h>
#include <linux/pm_runtime.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
#include <linux/pinctrl/pinconf.h>
#include <linux/pinctrl/pinconf-generic.h>
/* memory mapped register offsets */
#define BYT_CONF0_REG 0x000
......@@ -73,6 +76,14 @@
#define BYT_NCORE_ACPI_UID "2"
#define BYT_SUS_ACPI_UID "3"
/*
* This is the function value most pins have for GPIO muxing. If the value
* differs from the default one, it must be explicitly mentioned. Otherwise, the
* pin control implementation will set the muxing value to default GPIO if it
* does not find a match for the requested function.
*/
#define BYT_DEFAULT_GPIO_MUX 0
struct byt_gpio_pin_context {
u32 conf0;
u32 val;
......@@ -722,6 +733,8 @@ struct byt_gpio {
void __iomem *reg_base;
struct pinctrl_gpio_range *range;
struct byt_gpio_pin_context *saved_context;
const struct byt_pinctrl_soc_data *soc_data;
struct byt_community *communities_copy;
};
static const struct byt_pinctrl_soc_data *byt_soc_data[] = {
......@@ -731,52 +744,252 @@ static const struct byt_pinctrl_soc_data *byt_soc_data[] = {
NULL,
};
static void __iomem *byt_gpio_reg(struct gpio_chip *chip, unsigned offset,
int reg)
static struct byt_community *byt_get_community(struct byt_gpio *vg,
unsigned int pin)
{
struct byt_gpio *vg = gpiochip_get_data(chip);
u32 reg_offset;
struct byt_community *comm;
int i;
for (i = 0; i < vg->soc_data->ncommunities; i++) {
comm = vg->communities_copy + i;
if (pin < comm->pin_base + comm->npins && pin >= comm->pin_base)
return comm;
}
return NULL;
}
static void __iomem *byt_gpio_reg(struct byt_gpio *vg, unsigned int offset,
int reg)
{
struct byt_community *comm = byt_get_community(vg, offset);
u32 reg_offset = 0;
if (!comm)
return NULL;
offset -= comm->pin_base;
if (reg == BYT_INT_STAT_REG)
reg_offset = (offset / 32) * 4;
else
reg_offset = vg->range->pins[offset] * 16;
reg_offset = comm->pad_map[offset] * 16;
return comm->reg_base + reg_offset + reg;
}
static int byt_get_groups_count(struct pinctrl_dev *pctldev)
{
struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev);
return vg->soc_data->ngroups;
}
static const char *byt_get_group_name(struct pinctrl_dev *pctldev,
unsigned int selector)
{
struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev);
return vg->soc_data->groups[selector].name;
}
static int byt_get_group_pins(struct pinctrl_dev *pctldev,
unsigned int selector,
const unsigned int **pins,
unsigned int *num_pins)
{
struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev);
*pins = vg->soc_data->groups[selector].pins;
*num_pins = vg->soc_data->groups[selector].npins;
return 0;
}
static const struct pinctrl_ops byt_pinctrl_ops = {
.get_groups_count = byt_get_groups_count,
.get_group_name = byt_get_group_name,
.get_group_pins = byt_get_group_pins,
};
static int byt_get_functions_count(struct pinctrl_dev *pctldev)
{
struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev);
return vg->soc_data->nfunctions;
}
static const char *byt_get_function_name(struct pinctrl_dev *pctldev,
unsigned int selector)
{
struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev);
return vg->soc_data->functions[selector].name;
}
static int byt_get_function_groups(struct pinctrl_dev *pctldev,
unsigned int selector,
const char * const **groups,
unsigned int *num_groups)
{
struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev);
*groups = vg->soc_data->functions[selector].groups;
*num_groups = vg->soc_data->functions[selector].ngroups;
return 0;
}
static int byt_get_group_simple_mux(const struct byt_pingroup group,
const char *func_name,
unsigned short *func)
{
int i;
for (i = 0; i < group.nfuncs; i++) {
if (!strcmp(group.simple_funcs[i].name, func_name)) {
*func = group.simple_funcs[i].func;
return 0;
}
}
return 1;
}
static int byt_get_group_mixed_mux(const struct byt_pingroup group,
const char *func_name,
const unsigned short **func)
{
int i;
for (i = 0; i < group.nfuncs; i++) {
if (!strcmp(group.mixed_funcs[i].name, func_name)) {
*func = group.mixed_funcs[i].func_values;
return 0;
}
}
return vg->reg_base + reg_offset + reg;
return 1;
}
static void byt_gpio_clear_triggering(struct byt_gpio *vg, unsigned offset)
static void byt_set_group_simple_mux(struct byt_gpio *vg,
const struct byt_pingroup group,
unsigned short func)
{
void __iomem *reg = byt_gpio_reg(&vg->chip, offset, BYT_CONF0_REG);
unsigned long flags;
u32 value;
int i;
raw_spin_lock_irqsave(&vg->lock, flags);
value = readl(reg);
value &= ~(BYT_TRIG_POS | BYT_TRIG_NEG | BYT_TRIG_LVL);
writel(value, reg);
for (i = 0; i < group.npins; i++) {
void __iomem *padcfg0;
u32 value;
padcfg0 = byt_gpio_reg(vg, group.pins[i], BYT_CONF0_REG);
if (!padcfg0) {
dev_warn(&vg->pdev->dev,
"Group %s, pin %i not muxed (no padcfg0)\n",
group.name, i);
continue;
}
value = readl(padcfg0);
value &= ~BYT_PIN_MUX;
value |= func;
writel(value, padcfg0);
}
raw_spin_unlock_irqrestore(&vg->lock, flags);
}
static void byt_set_group_mixed_mux(struct byt_gpio *vg,
const struct byt_pingroup group,
const unsigned short *func)
{
unsigned long flags;
int i;
raw_spin_lock_irqsave(&vg->lock, flags);
for (i = 0; i < group.npins; i++) {
void __iomem *padcfg0;
u32 value;
padcfg0 = byt_gpio_reg(vg, group.pins[i], BYT_CONF0_REG);
if (!padcfg0) {
dev_warn(&vg->pdev->dev,
"Group %s, pin %i not muxed (no padcfg0)\n",
group.name, i);
continue;
}
value = readl(padcfg0);
value &= ~BYT_PIN_MUX;
value |= func[i];
writel(value, padcfg0);
}
raw_spin_unlock_irqrestore(&vg->lock, flags);
}
static int byt_set_mux(struct pinctrl_dev *pctldev, unsigned int func_selector,
unsigned int group_selector)
{
struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev);
const struct byt_function func = vg->soc_data->functions[func_selector];
const struct byt_pingroup group = vg->soc_data->groups[group_selector];
const unsigned short *mixed_func;
unsigned short simple_func;
int ret = 1;
if (group.has_simple_funcs)
ret = byt_get_group_simple_mux(group, func.name, &simple_func);
else
ret = byt_get_group_mixed_mux(group, func.name, &mixed_func);
if (ret)
byt_set_group_simple_mux(vg, group, BYT_DEFAULT_GPIO_MUX);
else if (group.has_simple_funcs)
byt_set_group_simple_mux(vg, group, simple_func);
else
byt_set_group_mixed_mux(vg, group, mixed_func);
return 0;
}
static u32 byt_get_gpio_mux(struct byt_gpio *vg, unsigned offset)
{
/* SCORE pin 92-93 */
if (!strcmp(vg->range->name, BYT_SCORE_ACPI_UID) &&
offset >= 92 && offset <= 93)
if (!strcmp(vg->soc_data->uid, BYT_SCORE_ACPI_UID) &&
offset >= 92 && offset <= 93)
return 1;
/* SUS pin 11-21 */
if (!strcmp(vg->range->name, BYT_SUS_ACPI_UID) &&
offset >= 11 && offset <= 21)
if (!strcmp(vg->soc_data->uid, BYT_SUS_ACPI_UID) &&
offset >= 11 && offset <= 21)
return 1;
return 0;
}
static int byt_gpio_request(struct gpio_chip *chip, unsigned offset)
static void byt_gpio_clear_triggering(struct byt_gpio *vg, unsigned int offset)
{
struct byt_gpio *vg = gpiochip_get_data(chip);
void __iomem *reg = byt_gpio_reg(chip, offset, BYT_CONF0_REG);
void __iomem *reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
unsigned long flags;
u32 value;
raw_spin_lock_irqsave(&vg->lock, flags);
value = readl(reg);
value &= ~(BYT_TRIG_POS | BYT_TRIG_NEG | BYT_TRIG_LVL);
writel(value, reg);
raw_spin_unlock_irqrestore(&vg->lock, flags);
}
static int byt_gpio_request_enable(struct pinctrl_dev *pctl_dev,
struct pinctrl_gpio_range *range,
unsigned int offset)
{
struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctl_dev);
void __iomem *reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
u32 value, gpio_mux;
unsigned long flags;
......@@ -817,13 +1030,102 @@ static void byt_gpio_free(struct gpio_chip *chip, unsigned offset)
pm_runtime_put(&vg->pdev->dev);
}
static void byt_gpio_disable_free(struct pinctrl_dev *pctl_dev,
struct pinctrl_gpio_range *range,
unsigned int offset)
{
struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctl_dev);
byt_gpio_clear_triggering(vg, offset);
pm_runtime_put(&vg->pdev->dev);
}
static int byt_gpio_set_direction(struct pinctrl_dev *pctl_dev,
struct pinctrl_gpio_range *range,
unsigned int offset,
bool input)
{
struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctl_dev);
void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
unsigned long flags;
u32 value;
raw_spin_lock_irqsave(&vg->lock, flags);
value = readl(val_reg);
value &= ~BYT_DIR_MASK;
if (input)
value |= BYT_OUTPUT_EN;
else
/*
* Before making any direction modifications, do a check if gpio
* is set for direct IRQ. On baytrail, setting GPIO to output
* does not make sense, so let's at least warn the caller before
* they shoot themselves in the foot.
*/
WARN(readl(conf_reg) & BYT_DIRECT_IRQ_EN,
"Potential Error: Setting GPIO with direct_irq_en to output");
writel(value, val_reg);
raw_spin_unlock_irqrestore(&vg->lock, flags);
return 0;
}
static const struct pinmux_ops byt_pinmux_ops = {
.get_functions_count = byt_get_functions_count,
.get_function_name = byt_get_function_name,
.get_function_groups = byt_get_function_groups,
.set_mux = byt_set_mux,
.gpio_request_enable = byt_gpio_request_enable,
.gpio_disable_free = byt_gpio_disable_free,
.gpio_set_direction = byt_gpio_set_direction,
};
static int byt_gpio_request(struct gpio_chip *chip, unsigned int offset)
{
struct byt_gpio *vg = gpiochip_get_data(chip);
void __iomem *reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
u32 value, gpio_mux;
unsigned long flags;
raw_spin_lock_irqsave(&vg->lock, flags);
/*
* In most cases, func pin mux 000 means GPIO function.
* But, some pins may have func pin mux 001 represents
* GPIO function.
*
* Because there are devices out there where some pins were not
* configured correctly we allow changing the mux value from
* request (but print out warning about that).
*/
value = readl(reg) & BYT_PIN_MUX;
gpio_mux = byt_get_gpio_mux(vg, offset);
if (WARN_ON(gpio_mux != value)) {
value = readl(reg) & ~BYT_PIN_MUX;
value |= gpio_mux;
writel(value, reg);
dev_warn(&vg->pdev->dev,
"pin %u forcibly re-configured as GPIO\n", offset);
}
raw_spin_unlock_irqrestore(&vg->lock, flags);
pm_runtime_get(&vg->pdev->dev);
return 0;
}
static int byt_irq_type(struct irq_data *d, unsigned type)
{
struct byt_gpio *vg = gpiochip_get_data(irq_data_get_irq_chip_data(d));
u32 offset = irqd_to_hwirq(d);
u32 value;
unsigned long flags;
void __iomem *reg = byt_gpio_reg(&vg->chip, offset, BYT_CONF0_REG);
void __iomem *reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
if (offset >= vg->chip.ngpio)
return -EINVAL;
......@@ -832,7 +1134,7 @@ static int byt_irq_type(struct irq_data *d, unsigned type)
value = readl(reg);
WARN(value & BYT_DIRECT_IRQ_EN,
"Bad pad config for io mode, force direct_irq_en bit clearing");
"Bad pad config for io mode, force direct_irq_en bit clearing");
/* For level trigges the BYT_TRIG_POS and BYT_TRIG_NEG bits
* are used to indicate high and low level triggering
......@@ -852,10 +1154,198 @@ static int byt_irq_type(struct irq_data *d, unsigned type)
return 0;
}
static void byt_get_pull_strength(u32 reg, u16 *strength)
{
switch (reg & BYT_PULL_STR_MASK) {
case BYT_PULL_STR_2K:
*strength = 2000;
break;
case BYT_PULL_STR_10K:
*strength = 10000;
break;
case BYT_PULL_STR_20K:
*strength = 20000;
break;
case BYT_PULL_STR_40K:
*strength = 40000;
break;
}
}
static int byt_set_pull_strength(u32 *reg, u16 strength)
{
*reg &= ~BYT_PULL_STR_MASK;
switch (strength) {
case 2000:
*reg |= BYT_PULL_STR_2K;
break;
case 10000:
*reg |= BYT_PULL_STR_10K;
break;
case 20000:
*reg |= BYT_PULL_STR_20K;
break;
case 40000:
*reg |= BYT_PULL_STR_40K;
break;
default:
return -EINVAL;
}
return 0;
}
static int byt_pin_config_get(struct pinctrl_dev *pctl_dev, unsigned int offset,
unsigned long *config)
{
struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctl_dev);
enum pin_config_param param = pinconf_to_config_param(*config);
void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
unsigned long flags;
u32 conf, pull, val;
u16 arg = 0;
raw_spin_lock_irqsave(&vg->lock, flags);
conf = readl(conf_reg);
pull = conf & BYT_PULL_ASSIGN_MASK;
val = readl(val_reg);
raw_spin_unlock_irqrestore(&vg->lock, flags);
switch (param) {
case PIN_CONFIG_BIAS_DISABLE:
if (pull)
return -EINVAL;
break;
case PIN_CONFIG_BIAS_PULL_DOWN:
/* Pull assignment is only applicable in input mode */
if ((val & BYT_INPUT_EN) || pull != BYT_PULL_ASSIGN_DOWN)
return -EINVAL;
byt_get_pull_strength(conf, &arg);
break;
case PIN_CONFIG_BIAS_PULL_UP:
/* Pull assignment is only applicable in input mode */
if ((val & BYT_INPUT_EN) || pull != BYT_PULL_ASSIGN_UP)
return -EINVAL;
byt_get_pull_strength(conf, &arg);
break;
default:
return -ENOTSUPP;
}
*config = pinconf_to_config_packed(param, arg);
return 0;
}
static int byt_pin_config_set(struct pinctrl_dev *pctl_dev,
unsigned int offset,
unsigned long *configs,
unsigned int num_configs)
{
struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctl_dev);
unsigned int param, arg;
void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
unsigned long flags;
u32 conf, val;
int i, ret = 0;
raw_spin_lock_irqsave(&vg->lock, flags);
conf = readl(conf_reg);
val = readl(val_reg);
for (i = 0; i < num_configs; i++) {
param = pinconf_to_config_param(configs[i]);
arg = pinconf_to_config_argument(configs[i]);
switch (param) {
case PIN_CONFIG_BIAS_DISABLE:
conf &= ~BYT_PULL_ASSIGN_MASK;
break;
case PIN_CONFIG_BIAS_PULL_DOWN:
/* Set default strength value in case none is given */
if (arg == 1)
arg = 2000;
/*
* Pull assignment is only applicable in input mode. If
* chip is not in input mode, set it and warn about it.
*/
if (val & BYT_INPUT_EN) {
val &= ~BYT_INPUT_EN;
writel(val, val_reg);
dev_warn(&vg->pdev->dev,
"pin %u forcibly set to input mode\n",
offset);
}
conf &= ~BYT_PULL_ASSIGN_MASK;
conf |= BYT_PULL_ASSIGN_DOWN;
ret = byt_set_pull_strength(&conf, arg);
break;
case PIN_CONFIG_BIAS_PULL_UP:
/* Set default strength value in case none is given */
if (arg == 1)
arg = 2000;
/*
* Pull assignment is only applicable in input mode. If
* chip is not in input mode, set it and warn about it.
*/
if (val & BYT_INPUT_EN) {
val &= ~BYT_INPUT_EN;
writel(val, val_reg);
dev_warn(&vg->pdev->dev,
"pin %u forcibly set to input mode\n",
offset);
}
conf &= ~BYT_PULL_ASSIGN_MASK;
conf |= BYT_PULL_ASSIGN_UP;
ret = byt_set_pull_strength(&conf, arg);
break;
default:
ret = -ENOTSUPP;
}
if (ret)
break;
}
if (!ret)
writel(conf, conf_reg);
raw_spin_unlock_irqrestore(&vg->lock, flags);
return ret;
}
static const struct pinconf_ops byt_pinconf_ops = {
.is_generic = true,
.pin_config_get = byt_pin_config_get,
.pin_config_set = byt_pin_config_set,
};
static const struct pinctrl_desc byt_pinctrl_desc = {
.pctlops = &byt_pinctrl_ops,
.pmxops = &byt_pinmux_ops,
.confops = &byt_pinconf_ops,
.owner = THIS_MODULE,
};
static int byt_gpio_get(struct gpio_chip *chip, unsigned offset)
{
void __iomem *reg = byt_gpio_reg(chip, offset, BYT_VAL_REG);
struct byt_gpio *vg = gpiochip_get_data(chip);
void __iomem *reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
unsigned long flags;
u32 val;
......@@ -869,7 +1359,7 @@ static int byt_gpio_get(struct gpio_chip *chip, unsigned offset)
static void byt_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
{
struct byt_gpio *vg = gpiochip_get_data(chip);
void __iomem *reg = byt_gpio_reg(chip, offset, BYT_VAL_REG);
void __iomem *reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
unsigned long flags;
u32 old_val;
......@@ -888,7 +1378,7 @@ static void byt_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
static int byt_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
{
struct byt_gpio *vg = gpiochip_get_data(chip);
void __iomem *reg = byt_gpio_reg(chip, offset, BYT_VAL_REG);
void __iomem *reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
unsigned long flags;
u32 value;
......@@ -907,8 +1397,8 @@ static int byt_gpio_direction_output(struct gpio_chip *chip,
unsigned gpio, int value)
{
struct byt_gpio *vg = gpiochip_get_data(chip);
void __iomem *conf_reg = byt_gpio_reg(chip, gpio, BYT_CONF0_REG);
void __iomem *reg = byt_gpio_reg(chip, gpio, BYT_VAL_REG);
void __iomem *conf_reg = byt_gpio_reg(vg, gpio, BYT_CONF0_REG);
void __iomem *reg = byt_gpio_reg(vg, gpio, BYT_VAL_REG);
unsigned long flags;
u32 reg_val;
......@@ -1019,7 +1509,7 @@ static void byt_gpio_irq_handler(struct irq_desc *desc)
/* check from GPIO controller which pin triggered the interrupt */
for (base = 0; base < vg->chip.ngpio; base += 32) {
reg = byt_gpio_reg(&vg->chip, base, BYT_INT_STAT_REG);
reg = byt_gpio_reg(vg, base, BYT_INT_STAT_REG);
pending = readl(reg);
for_each_set_bit(pin, &pending, 32) {
virq = irq_find_mapping(vg->chip.irqdomain, base + pin);
......@@ -1037,7 +1527,7 @@ static void byt_irq_ack(struct irq_data *d)
void __iomem *reg;
raw_spin_lock(&vg->lock);
reg = byt_gpio_reg(&vg->chip, offset, BYT_INT_STAT_REG);
reg = byt_gpio_reg(vg, offset, BYT_INT_STAT_REG);
writel(BIT(offset % 32), reg);
raw_spin_unlock(&vg->lock);
}
......@@ -1051,7 +1541,7 @@ static void byt_irq_unmask(struct irq_data *d)
void __iomem *reg;
u32 value;
reg = byt_gpio_reg(&vg->chip, offset, BYT_CONF0_REG);
reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
raw_spin_lock_irqsave(&vg->lock, flags);
value = readl(reg);
......@@ -1106,7 +1596,7 @@ static void byt_gpio_irq_init_hw(struct byt_gpio *vg)
* interrupts from misconfigured pins.
*/
for (i = 0; i < vg->chip.ngpio; i++) {
value = readl(byt_gpio_reg(&vg->chip, i, BYT_CONF0_REG));
value = readl(byt_gpio_reg(vg, i, BYT_CONF0_REG));
if ((value & BYT_PIN_MUX) == byt_get_gpio_mux(vg, i) &&
!(value & BYT_DIRECT_IRQ_EN)) {
byt_gpio_clear_triggering(vg, i);
......@@ -1116,7 +1606,7 @@ static void byt_gpio_irq_init_hw(struct byt_gpio *vg)
/* clear interrupt status trigger registers */
for (base = 0; base < vg->chip.ngpio; base += 32) {
reg = byt_gpio_reg(&vg->chip, base, BYT_INT_STAT_REG);
reg = byt_gpio_reg(vg, base, BYT_INT_STAT_REG);
writel(0xffffffff, reg);
/* make sure trigger bits are cleared, if not then a pin
might be misconfigured in bios */
......@@ -1226,11 +1716,11 @@ static int byt_gpio_suspend(struct device *dev)
void __iomem *reg;
u32 value;
reg = byt_gpio_reg(&vg->chip, i, BYT_CONF0_REG);
reg = byt_gpio_reg(vg, i, BYT_CONF0_REG);
value = readl(reg) & BYT_CONF0_RESTORE_MASK;
vg->saved_context[i].conf0 = value;
reg = byt_gpio_reg(&vg->chip, i, BYT_VAL_REG);
reg = byt_gpio_reg(vg, i, BYT_VAL_REG);
value = readl(reg) & BYT_VAL_RESTORE_MASK;
vg->saved_context[i].val = value;
}
......@@ -1248,7 +1738,7 @@ static int byt_gpio_resume(struct device *dev)
void __iomem *reg;
u32 value;
reg = byt_gpio_reg(&vg->chip, i, BYT_CONF0_REG);
reg = byt_gpio_reg(vg, i, BYT_CONF0_REG);
value = readl(reg);
if ((value & BYT_CONF0_RESTORE_MASK) !=
vg->saved_context[i].conf0) {
......@@ -1258,7 +1748,7 @@ static int byt_gpio_resume(struct device *dev)
dev_info(dev, "restored pin %d conf0 %#08x", i, value);
}
reg = byt_gpio_reg(&vg->chip, i, BYT_VAL_REG);
reg = byt_gpio_reg(vg, i, BYT_VAL_REG);
value = readl(reg);
if ((value & BYT_VAL_RESTORE_MASK) !=
vg->saved_context[i].val) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment