aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio/gpio-sch.c
diff options
context:
space:
mode:
authorChang Rebecca Swee Fun <rebecca.swee.fun.chang@intel.com>2015-01-21 05:32:21 -0500
committerLinus Walleij <linus.walleij@linaro.org>2015-01-29 07:46:29 -0500
commit920dfd824789b4058e91d26e2c6dd01a00ab28ec (patch)
tree238a4284152f85fae62b79463d6f4c0eb1d59da8 /drivers/gpio/gpio-sch.c
parent68d77d5168bdb922e0f100d0ee5e5e78aa0989af (diff)
gpio: sch: Consolidate similar algorithms
Consolidating similar algorithms into common functions to make GPIO SCH simpler and manageable. Signed-off-by: Chang Rebecca Swee Fun <rebecca.swee.fun.chang@intel.com> Reviewed-by: Alexandre Courbot <acourbot@nvidia.com> Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/gpio/gpio-sch.c')
-rw-r--r--drivers/gpio/gpio-sch.c83
1 files changed, 29 insertions, 54 deletions
diff --git a/drivers/gpio/gpio-sch.c b/drivers/gpio/gpio-sch.c
index 0271022a66f6..b72906f5b999 100644
--- a/drivers/gpio/gpio-sch.c
+++ b/drivers/gpio/gpio-sch.c
@@ -41,7 +41,7 @@ struct sch_gpio {
41 unsigned short resume_base; 41 unsigned short resume_base;
42}; 42};
43 43
44#define to_sch_gpio(c) container_of(c, struct sch_gpio, chip) 44#define to_sch_gpio(gc) container_of(gc, struct sch_gpio, chip)
45 45
46static unsigned sch_gpio_offset(struct sch_gpio *sch, unsigned gpio, 46static unsigned sch_gpio_offset(struct sch_gpio *sch, unsigned gpio,
47 unsigned reg) 47 unsigned reg)
@@ -63,75 +63,59 @@ static unsigned sch_gpio_bit(struct sch_gpio *sch, unsigned gpio)
63 return gpio % 8; 63 return gpio % 8;
64} 64}
65 65
66static void sch_gpio_enable(struct sch_gpio *sch, unsigned gpio) 66static int sch_gpio_reg_get(struct gpio_chip *gc, unsigned gpio, unsigned reg)
67{ 67{
68 struct sch_gpio *sch = to_sch_gpio(gc);
68 unsigned short offset, bit; 69 unsigned short offset, bit;
69 u8 enable; 70 u8 reg_val;
70
71 spin_lock(&sch->lock);
72 71
73 offset = sch_gpio_offset(sch, gpio, GEN); 72 offset = sch_gpio_offset(sch, gpio, reg);
74 bit = sch_gpio_bit(sch, gpio); 73 bit = sch_gpio_bit(sch, gpio);
75 74
76 enable = inb(sch->iobase + offset); 75 reg_val = !!(inb(sch->iobase + offset) & BIT(bit));
77 if (!(enable & (1 << bit)))
78 outb(enable | (1 << bit), sch->iobase + offset);
79 76
80 spin_unlock(&sch->lock); 77 return reg_val;
81} 78}
82 79
83static int sch_gpio_direction_in(struct gpio_chip *gc, unsigned gpio_num) 80static void sch_gpio_reg_set(struct gpio_chip *gc, unsigned gpio, unsigned reg,
81 int val)
84{ 82{
85 struct sch_gpio *sch = to_sch_gpio(gc); 83 struct sch_gpio *sch = to_sch_gpio(gc);
86 u8 curr_dirs;
87 unsigned short offset, bit; 84 unsigned short offset, bit;
85 u8 reg_val;
88 86
89 spin_lock(&sch->lock); 87 offset = sch_gpio_offset(sch, gpio, reg);
88 bit = sch_gpio_bit(sch, gpio);
90 89
91 offset = sch_gpio_offset(sch, gpio_num, GIO); 90 reg_val = inb(sch->iobase + offset);
92 bit = sch_gpio_bit(sch, gpio_num);
93 91
94 curr_dirs = inb(sch->iobase + offset); 92 if (val)
93 outb(reg_val | BIT(bit), sch->iobase + offset);
94 else
95 outb((reg_val & ~BIT(bit)), sch->iobase + offset);
96}
95 97
96 if (!(curr_dirs & (1 << bit))) 98static int sch_gpio_direction_in(struct gpio_chip *gc, unsigned gpio_num)
97 outb(curr_dirs | (1 << bit), sch->iobase + offset); 99{
100 struct sch_gpio *sch = to_sch_gpio(gc);
98 101
102 spin_lock(&sch->lock);
103 sch_gpio_reg_set(gc, gpio_num, GIO, 1);
99 spin_unlock(&sch->lock); 104 spin_unlock(&sch->lock);
100 return 0; 105 return 0;
101} 106}
102 107
103static int sch_gpio_get(struct gpio_chip *gc, unsigned gpio_num) 108static int sch_gpio_get(struct gpio_chip *gc, unsigned gpio_num)
104{ 109{
105 struct sch_gpio *sch = to_sch_gpio(gc); 110 return sch_gpio_reg_get(gc, gpio_num, GLV);
106 int res;
107 unsigned short offset, bit;
108
109 offset = sch_gpio_offset(sch, gpio_num, GLV);
110 bit = sch_gpio_bit(sch, gpio_num);
111
112 res = !!(inb(sch->iobase + offset) & (1 << bit));
113
114 return res;
115} 111}
116 112
117static void sch_gpio_set(struct gpio_chip *gc, unsigned gpio_num, int val) 113static void sch_gpio_set(struct gpio_chip *gc, unsigned gpio_num, int val)
118{ 114{
119 struct sch_gpio *sch = to_sch_gpio(gc); 115 struct sch_gpio *sch = to_sch_gpio(gc);
120 u8 curr_vals;
121 unsigned short offset, bit;
122 116
123 spin_lock(&sch->lock); 117 spin_lock(&sch->lock);
124 118 sch_gpio_reg_set(gc, gpio_num, GLV, val);
125 offset = sch_gpio_offset(sch, gpio_num, GLV);
126 bit = sch_gpio_bit(sch, gpio_num);
127
128 curr_vals = inb(sch->iobase + offset);
129
130 if (val)
131 outb(curr_vals | (1 << bit), sch->iobase + offset);
132 else
133 outb((curr_vals & ~(1 << bit)), sch->iobase + offset);
134
135 spin_unlock(&sch->lock); 119 spin_unlock(&sch->lock);
136} 120}
137 121
@@ -139,18 +123,9 @@ static int sch_gpio_direction_out(struct gpio_chip *gc, unsigned gpio_num,
139 int val) 123 int val)
140{ 124{
141 struct sch_gpio *sch = to_sch_gpio(gc); 125 struct sch_gpio *sch = to_sch_gpio(gc);
142 u8 curr_dirs;
143 unsigned short offset, bit;
144 126
145 spin_lock(&sch->lock); 127 spin_lock(&sch->lock);
146 128 sch_gpio_reg_set(gc, gpio_num, GIO, 0);
147 offset = sch_gpio_offset(sch, gpio_num, GIO);
148 bit = sch_gpio_bit(sch, gpio_num);
149
150 curr_dirs = inb(sch->iobase + offset);
151 if (curr_dirs & (1 << bit))
152 outb(curr_dirs & ~(1 << bit), sch->iobase + offset);
153
154 spin_unlock(&sch->lock); 129 spin_unlock(&sch->lock);
155 130
156 /* 131 /*
@@ -209,13 +184,13 @@ static int sch_gpio_probe(struct platform_device *pdev)
209 * GPIO7 is configured by the CMC as SLPIOVR 184 * GPIO7 is configured by the CMC as SLPIOVR
210 * Enable GPIO[9:8] core powered gpios explicitly 185 * Enable GPIO[9:8] core powered gpios explicitly
211 */ 186 */
212 sch_gpio_enable(sch, 8); 187 sch_gpio_reg_set(&sch->chip, 8, GEN, 1);
213 sch_gpio_enable(sch, 9); 188 sch_gpio_reg_set(&sch->chip, 9, GEN, 1);
214 /* 189 /*
215 * SUS_GPIO[2:0] enabled by default 190 * SUS_GPIO[2:0] enabled by default
216 * Enable SUS_GPIO3 resume powered gpio explicitly 191 * Enable SUS_GPIO3 resume powered gpio explicitly
217 */ 192 */
218 sch_gpio_enable(sch, 13); 193 sch_gpio_reg_set(&sch->chip, 13, GEN, 1);
219 break; 194 break;
220 195
221 case PCI_DEVICE_ID_INTEL_ITC_LPC: 196 case PCI_DEVICE_ID_INTEL_ITC_LPC: