aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio/gpio-ml-ioh.c
diff options
context:
space:
mode:
authorAxel Lin <axel.lin@gmail.com>2012-07-28 22:54:42 -0400
committerLinus Walleij <linus.walleij@linaro.org>2012-08-17 01:35:42 -0400
commit02a6794d57ce54b96b13db80831f35d66e0caf31 (patch)
treea395f2a69060931c3d6e3c4c43a38f5c45baa431 /drivers/gpio/gpio-ml-ioh.c
parentf9c4a31f61501d25f0a45faae6a5cd701ad5694a (diff)
gpio: gpio-ml-ioh: Use spinlock for register access protection
gpio_chip.can_sleep is 0, but current code uses mutex in ioh_gpio_set, ioh_gpio_get and ioh_gpio_direction_input functions. Thus those functions are not callable from interrupt context. This patch converts mutex into spinlock. Signed-off-by: Axel Lin <axel.lin@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/gpio/gpio-ml-ioh.c')
-rw-r--r--drivers/gpio/gpio-ml-ioh.c20
1 files changed, 10 insertions, 10 deletions
diff --git a/drivers/gpio/gpio-ml-ioh.c b/drivers/gpio/gpio-ml-ioh.c
index db01f151d41c..6a29ee1847be 100644
--- a/drivers/gpio/gpio-ml-ioh.c
+++ b/drivers/gpio/gpio-ml-ioh.c
@@ -87,8 +87,7 @@ struct ioh_gpio_reg_data {
87 * @gpio_use_sel: Save GPIO_USE_SEL1~4 register for PM 87 * @gpio_use_sel: Save GPIO_USE_SEL1~4 register for PM
88 * @ch: Indicate GPIO channel 88 * @ch: Indicate GPIO channel
89 * @irq_base: Save base of IRQ number for interrupt 89 * @irq_base: Save base of IRQ number for interrupt
90 * @spinlock: Used for register access protection in 90 * @spinlock: Used for register access protection
91 * interrupt context ioh_irq_type and PM;
92 */ 91 */
93struct ioh_gpio { 92struct ioh_gpio {
94 void __iomem *base; 93 void __iomem *base;
@@ -97,7 +96,6 @@ struct ioh_gpio {
97 struct gpio_chip gpio; 96 struct gpio_chip gpio;
98 struct ioh_gpio_reg_data ioh_gpio_reg; 97 struct ioh_gpio_reg_data ioh_gpio_reg;
99 u32 gpio_use_sel; 98 u32 gpio_use_sel;
100 struct mutex lock;
101 int ch; 99 int ch;
102 int irq_base; 100 int irq_base;
103 spinlock_t spinlock; 101 spinlock_t spinlock;
@@ -109,8 +107,9 @@ static void ioh_gpio_set(struct gpio_chip *gpio, unsigned nr, int val)
109{ 107{
110 u32 reg_val; 108 u32 reg_val;
111 struct ioh_gpio *chip = container_of(gpio, struct ioh_gpio, gpio); 109 struct ioh_gpio *chip = container_of(gpio, struct ioh_gpio, gpio);
110 unsigned long flags;
112 111
113 mutex_lock(&chip->lock); 112 spin_lock_irqsave(&chip->spinlock, flags);
114 reg_val = ioread32(&chip->reg->regs[chip->ch].po); 113 reg_val = ioread32(&chip->reg->regs[chip->ch].po);
115 if (val) 114 if (val)
116 reg_val |= (1 << nr); 115 reg_val |= (1 << nr);
@@ -118,7 +117,7 @@ static void ioh_gpio_set(struct gpio_chip *gpio, unsigned nr, int val)
118 reg_val &= ~(1 << nr); 117 reg_val &= ~(1 << nr);
119 118
120 iowrite32(reg_val, &chip->reg->regs[chip->ch].po); 119 iowrite32(reg_val, &chip->reg->regs[chip->ch].po);
121 mutex_unlock(&chip->lock); 120 spin_unlock_irqrestore(&chip->spinlock, flags);
122} 121}
123 122
124static int ioh_gpio_get(struct gpio_chip *gpio, unsigned nr) 123static int ioh_gpio_get(struct gpio_chip *gpio, unsigned nr)
@@ -134,8 +133,9 @@ static int ioh_gpio_direction_output(struct gpio_chip *gpio, unsigned nr,
134 struct ioh_gpio *chip = container_of(gpio, struct ioh_gpio, gpio); 133 struct ioh_gpio *chip = container_of(gpio, struct ioh_gpio, gpio);
135 u32 pm; 134 u32 pm;
136 u32 reg_val; 135 u32 reg_val;
136 unsigned long flags;
137 137
138 mutex_lock(&chip->lock); 138 spin_lock_irqsave(&chip->spinlock, flags);
139 pm = ioread32(&chip->reg->regs[chip->ch].pm) & 139 pm = ioread32(&chip->reg->regs[chip->ch].pm) &
140 ((1 << num_ports[chip->ch]) - 1); 140 ((1 << num_ports[chip->ch]) - 1);
141 pm |= (1 << nr); 141 pm |= (1 << nr);
@@ -148,7 +148,7 @@ static int ioh_gpio_direction_output(struct gpio_chip *gpio, unsigned nr,
148 reg_val &= ~(1 << nr); 148 reg_val &= ~(1 << nr);
149 iowrite32(reg_val, &chip->reg->regs[chip->ch].po); 149 iowrite32(reg_val, &chip->reg->regs[chip->ch].po);
150 150
151 mutex_unlock(&chip->lock); 151 spin_unlock_irqrestore(&chip->spinlock, flags);
152 152
153 return 0; 153 return 0;
154} 154}
@@ -157,13 +157,14 @@ static int ioh_gpio_direction_input(struct gpio_chip *gpio, unsigned nr)
157{ 157{
158 struct ioh_gpio *chip = container_of(gpio, struct ioh_gpio, gpio); 158 struct ioh_gpio *chip = container_of(gpio, struct ioh_gpio, gpio);
159 u32 pm; 159 u32 pm;
160 unsigned long flags;
160 161
161 mutex_lock(&chip->lock); 162 spin_lock_irqsave(&chip->spinlock, flags);
162 pm = ioread32(&chip->reg->regs[chip->ch].pm) & 163 pm = ioread32(&chip->reg->regs[chip->ch].pm) &
163 ((1 << num_ports[chip->ch]) - 1); 164 ((1 << num_ports[chip->ch]) - 1);
164 pm &= ~(1 << nr); 165 pm &= ~(1 << nr);
165 iowrite32(pm, &chip->reg->regs[chip->ch].pm); 166 iowrite32(pm, &chip->reg->regs[chip->ch].pm);
166 mutex_unlock(&chip->lock); 167 spin_unlock_irqrestore(&chip->spinlock, flags);
167 168
168 return 0; 169 return 0;
169} 170}
@@ -447,7 +448,6 @@ static int __devinit ioh_gpio_probe(struct pci_dev *pdev,
447 chip->base = base; 448 chip->base = base;
448 chip->reg = chip->base; 449 chip->reg = chip->base;
449 chip->ch = i; 450 chip->ch = i;
450 mutex_init(&chip->lock);
451 spin_lock_init(&chip->spinlock); 451 spin_lock_init(&chip->spinlock);
452 ioh_gpio_setup(chip, num_ports[i]); 452 ioh_gpio_setup(chip, num_ports[i]);
453 ret = gpiochip_add(&chip->gpio); 453 ret = gpiochip_add(&chip->gpio);