diff options
Diffstat (limited to 'drivers/gpio/gpio-ich.c')
-rw-r--r-- | drivers/gpio/gpio-ich.c | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/drivers/gpio/gpio-ich.c b/drivers/gpio/gpio-ich.c index f3eb1c52f97b..bfef20f8ab48 100644 --- a/drivers/gpio/gpio-ich.c +++ b/drivers/gpio/gpio-ich.c | |||
@@ -78,6 +78,12 @@ struct ichx_desc { | |||
78 | /* Some chipsets have quirks, let these use their own request/get */ | 78 | /* Some chipsets have quirks, let these use their own request/get */ |
79 | int (*request)(struct gpio_chip *chip, unsigned offset); | 79 | int (*request)(struct gpio_chip *chip, unsigned offset); |
80 | int (*get)(struct gpio_chip *chip, unsigned offset); | 80 | int (*get)(struct gpio_chip *chip, unsigned offset); |
81 | |||
82 | /* | ||
83 | * Some chipsets don't let reading output values on GPIO_LVL register | ||
84 | * this option allows driver caching written output values | ||
85 | */ | ||
86 | bool use_outlvl_cache; | ||
81 | }; | 87 | }; |
82 | 88 | ||
83 | static struct { | 89 | static struct { |
@@ -89,6 +95,7 @@ static struct { | |||
89 | struct ichx_desc *desc; /* Pointer to chipset-specific description */ | 95 | struct ichx_desc *desc; /* Pointer to chipset-specific description */ |
90 | u32 orig_gpio_ctrl; /* Orig CTRL value, used to restore on exit */ | 96 | u32 orig_gpio_ctrl; /* Orig CTRL value, used to restore on exit */ |
91 | u8 use_gpio; /* Which GPIO groups are usable */ | 97 | u8 use_gpio; /* Which GPIO groups are usable */ |
98 | int outlvl_cache[3]; /* cached output values */ | ||
92 | } ichx_priv; | 99 | } ichx_priv; |
93 | 100 | ||
94 | static int modparam_gpiobase = -1; /* dynamic */ | 101 | static int modparam_gpiobase = -1; /* dynamic */ |
@@ -106,14 +113,21 @@ static int ichx_write_bit(int reg, unsigned nr, int val, int verify) | |||
106 | 113 | ||
107 | spin_lock_irqsave(&ichx_priv.lock, flags); | 114 | spin_lock_irqsave(&ichx_priv.lock, flags); |
108 | 115 | ||
109 | data = ICHX_READ(ichx_priv.desc->regs[reg][reg_nr], | 116 | if (reg == GPIO_LVL && ichx_priv.desc->use_outlvl_cache) |
110 | ichx_priv.gpio_base); | 117 | data = ichx_priv.outlvl_cache[reg_nr]; |
118 | else | ||
119 | data = ICHX_READ(ichx_priv.desc->regs[reg][reg_nr], | ||
120 | ichx_priv.gpio_base); | ||
121 | |||
111 | if (val) | 122 | if (val) |
112 | data |= 1 << bit; | 123 | data |= 1 << bit; |
113 | else | 124 | else |
114 | data &= ~(1 << bit); | 125 | data &= ~(1 << bit); |
115 | ICHX_WRITE(data, ichx_priv.desc->regs[reg][reg_nr], | 126 | ICHX_WRITE(data, ichx_priv.desc->regs[reg][reg_nr], |
116 | ichx_priv.gpio_base); | 127 | ichx_priv.gpio_base); |
128 | if (reg == GPIO_LVL && ichx_priv.desc->use_outlvl_cache) | ||
129 | ichx_priv.outlvl_cache[reg_nr] = data; | ||
130 | |||
117 | tmp = ICHX_READ(ichx_priv.desc->regs[reg][reg_nr], | 131 | tmp = ICHX_READ(ichx_priv.desc->regs[reg][reg_nr], |
118 | ichx_priv.gpio_base); | 132 | ichx_priv.gpio_base); |
119 | if (verify && data != tmp) | 133 | if (verify && data != tmp) |
@@ -136,6 +150,9 @@ static int ichx_read_bit(int reg, unsigned nr) | |||
136 | data = ICHX_READ(ichx_priv.desc->regs[reg][reg_nr], | 150 | data = ICHX_READ(ichx_priv.desc->regs[reg][reg_nr], |
137 | ichx_priv.gpio_base); | 151 | ichx_priv.gpio_base); |
138 | 152 | ||
153 | if (reg == GPIO_LVL && ichx_priv.desc->use_outlvl_cache) | ||
154 | data = ichx_priv.outlvl_cache[reg_nr] | data; | ||
155 | |||
139 | spin_unlock_irqrestore(&ichx_priv.lock, flags); | 156 | spin_unlock_irqrestore(&ichx_priv.lock, flags); |
140 | 157 | ||
141 | return data & (1 << bit) ? 1 : 0; | 158 | return data & (1 << bit) ? 1 : 0; |