aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio/gpio-ich.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpio/gpio-ich.c')
-rw-r--r--drivers/gpio/gpio-ich.c21
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
83static struct { 89static 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
94static int modparam_gpiobase = -1; /* dynamic */ 101static 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;