diff options
author | Axel Lin <axel.lin@gmail.com> | 2012-07-28 22:54:42 -0400 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2012-08-17 01:35:42 -0400 |
commit | 02a6794d57ce54b96b13db80831f35d66e0caf31 (patch) | |
tree | a395f2a69060931c3d6e3c4c43a38f5c45baa431 /drivers/gpio/gpio-ml-ioh.c | |
parent | f9c4a31f61501d25f0a45faae6a5cd701ad5694a (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.c | 20 |
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 | */ |
93 | struct ioh_gpio { | 92 | struct 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 | ||
124 | static int ioh_gpio_get(struct gpio_chip *gpio, unsigned nr) | 123 | static 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); |