aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJulia Cartwright <julia@ni.com>2017-03-21 18:43:03 -0400
committerMichael Ellerman <mpe@ellerman.id.au>2018-01-27 05:12:04 -0500
commit77720c82915a8b7797e0041af95707d7485b4a40 (patch)
tree7157efd278a769a3691adf125fb12df89ed227a2
parentf2be6295684b0fe879a824ac97479799e760b7e9 (diff)
powerpc/mpc52xx_gpt: make use of raw_spinlock variants
The mpc52xx_gpt code currently implements an irq_chip for handling interrupts; due to how irq_chip handling is done, it's necessary for the irq_chip methods to be invoked from hardirq context, even on a a real-time kernel. Because the spinlock_t type becomes a "sleeping" spinlock w/ RT kernels, it is not suitable to be used with irq_chips. A quick audit of the operations under the lock reveal that they do only minimal, bounded work, and are therefore safe to do under a raw spinlock. Signed-off-by: Julia Cartwright <julia@ni.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
-rw-r--r--arch/powerpc/platforms/52xx/mpc52xx_gpt.c52
1 files changed, 26 insertions, 26 deletions
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
index 9e974b1e1697..17cf249b18ee 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
@@ -90,7 +90,7 @@ struct mpc52xx_gpt_priv {
90 struct list_head list; /* List of all GPT devices */ 90 struct list_head list; /* List of all GPT devices */
91 struct device *dev; 91 struct device *dev;
92 struct mpc52xx_gpt __iomem *regs; 92 struct mpc52xx_gpt __iomem *regs;
93 spinlock_t lock; 93 raw_spinlock_t lock;
94 struct irq_domain *irqhost; 94 struct irq_domain *irqhost;
95 u32 ipb_freq; 95 u32 ipb_freq;
96 u8 wdt_mode; 96 u8 wdt_mode;
@@ -141,9 +141,9 @@ static void mpc52xx_gpt_irq_unmask(struct irq_data *d)
141 struct mpc52xx_gpt_priv *gpt = irq_data_get_irq_chip_data(d); 141 struct mpc52xx_gpt_priv *gpt = irq_data_get_irq_chip_data(d);
142 unsigned long flags; 142 unsigned long flags;
143 143
144 spin_lock_irqsave(&gpt->lock, flags); 144 raw_spin_lock_irqsave(&gpt->lock, flags);
145 setbits32(&gpt->regs->mode, MPC52xx_GPT_MODE_IRQ_EN); 145 setbits32(&gpt->regs->mode, MPC52xx_GPT_MODE_IRQ_EN);
146 spin_unlock_irqrestore(&gpt->lock, flags); 146 raw_spin_unlock_irqrestore(&gpt->lock, flags);
147} 147}
148 148
149static void mpc52xx_gpt_irq_mask(struct irq_data *d) 149static void mpc52xx_gpt_irq_mask(struct irq_data *d)
@@ -151,9 +151,9 @@ static void mpc52xx_gpt_irq_mask(struct irq_data *d)
151 struct mpc52xx_gpt_priv *gpt = irq_data_get_irq_chip_data(d); 151 struct mpc52xx_gpt_priv *gpt = irq_data_get_irq_chip_data(d);
152 unsigned long flags; 152 unsigned long flags;
153 153
154 spin_lock_irqsave(&gpt->lock, flags); 154 raw_spin_lock_irqsave(&gpt->lock, flags);
155 clrbits32(&gpt->regs->mode, MPC52xx_GPT_MODE_IRQ_EN); 155 clrbits32(&gpt->regs->mode, MPC52xx_GPT_MODE_IRQ_EN);
156 spin_unlock_irqrestore(&gpt->lock, flags); 156 raw_spin_unlock_irqrestore(&gpt->lock, flags);
157} 157}
158 158
159static void mpc52xx_gpt_irq_ack(struct irq_data *d) 159static void mpc52xx_gpt_irq_ack(struct irq_data *d)
@@ -171,14 +171,14 @@ static int mpc52xx_gpt_irq_set_type(struct irq_data *d, unsigned int flow_type)
171 171
172 dev_dbg(gpt->dev, "%s: virq=%i type=%x\n", __func__, d->irq, flow_type); 172 dev_dbg(gpt->dev, "%s: virq=%i type=%x\n", __func__, d->irq, flow_type);
173 173
174 spin_lock_irqsave(&gpt->lock, flags); 174 raw_spin_lock_irqsave(&gpt->lock, flags);
175 reg = in_be32(&gpt->regs->mode) & ~MPC52xx_GPT_MODE_ICT_MASK; 175 reg = in_be32(&gpt->regs->mode) & ~MPC52xx_GPT_MODE_ICT_MASK;
176 if (flow_type & IRQF_TRIGGER_RISING) 176 if (flow_type & IRQF_TRIGGER_RISING)
177 reg |= MPC52xx_GPT_MODE_ICT_RISING; 177 reg |= MPC52xx_GPT_MODE_ICT_RISING;
178 if (flow_type & IRQF_TRIGGER_FALLING) 178 if (flow_type & IRQF_TRIGGER_FALLING)
179 reg |= MPC52xx_GPT_MODE_ICT_FALLING; 179 reg |= MPC52xx_GPT_MODE_ICT_FALLING;
180 out_be32(&gpt->regs->mode, reg); 180 out_be32(&gpt->regs->mode, reg);
181 spin_unlock_irqrestore(&gpt->lock, flags); 181 raw_spin_unlock_irqrestore(&gpt->lock, flags);
182 182
183 return 0; 183 return 0;
184} 184}
@@ -264,11 +264,11 @@ mpc52xx_gpt_irq_setup(struct mpc52xx_gpt_priv *gpt, struct device_node *node)
264 /* If the GPT is currently disabled, then change it to be in Input 264 /* If the GPT is currently disabled, then change it to be in Input
265 * Capture mode. If the mode is non-zero, then the pin could be 265 * Capture mode. If the mode is non-zero, then the pin could be
266 * already in use for something. */ 266 * already in use for something. */
267 spin_lock_irqsave(&gpt->lock, flags); 267 raw_spin_lock_irqsave(&gpt->lock, flags);
268 mode = in_be32(&gpt->regs->mode); 268 mode = in_be32(&gpt->regs->mode);
269 if ((mode & MPC52xx_GPT_MODE_MS_MASK) == 0) 269 if ((mode & MPC52xx_GPT_MODE_MS_MASK) == 0)
270 out_be32(&gpt->regs->mode, mode | MPC52xx_GPT_MODE_MS_IC); 270 out_be32(&gpt->regs->mode, mode | MPC52xx_GPT_MODE_MS_IC);
271 spin_unlock_irqrestore(&gpt->lock, flags); 271 raw_spin_unlock_irqrestore(&gpt->lock, flags);
272 272
273 dev_dbg(gpt->dev, "%s() complete. virq=%i\n", __func__, cascade_virq); 273 dev_dbg(gpt->dev, "%s() complete. virq=%i\n", __func__, cascade_virq);
274} 274}
@@ -295,9 +295,9 @@ mpc52xx_gpt_gpio_set(struct gpio_chip *gc, unsigned int gpio, int v)
295 dev_dbg(gpt->dev, "%s: gpio:%d v:%d\n", __func__, gpio, v); 295 dev_dbg(gpt->dev, "%s: gpio:%d v:%d\n", __func__, gpio, v);
296 r = v ? MPC52xx_GPT_MODE_GPIO_OUT_HIGH : MPC52xx_GPT_MODE_GPIO_OUT_LOW; 296 r = v ? MPC52xx_GPT_MODE_GPIO_OUT_HIGH : MPC52xx_GPT_MODE_GPIO_OUT_LOW;
297 297
298 spin_lock_irqsave(&gpt->lock, flags); 298 raw_spin_lock_irqsave(&gpt->lock, flags);
299 clrsetbits_be32(&gpt->regs->mode, MPC52xx_GPT_MODE_GPIO_MASK, r); 299 clrsetbits_be32(&gpt->regs->mode, MPC52xx_GPT_MODE_GPIO_MASK, r);
300 spin_unlock_irqrestore(&gpt->lock, flags); 300 raw_spin_unlock_irqrestore(&gpt->lock, flags);
301} 301}
302 302
303static int mpc52xx_gpt_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio) 303static int mpc52xx_gpt_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
@@ -307,9 +307,9 @@ static int mpc52xx_gpt_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
307 307
308 dev_dbg(gpt->dev, "%s: gpio:%d\n", __func__, gpio); 308 dev_dbg(gpt->dev, "%s: gpio:%d\n", __func__, gpio);
309 309
310 spin_lock_irqsave(&gpt->lock, flags); 310 raw_spin_lock_irqsave(&gpt->lock, flags);
311 clrbits32(&gpt->regs->mode, MPC52xx_GPT_MODE_GPIO_MASK); 311 clrbits32(&gpt->regs->mode, MPC52xx_GPT_MODE_GPIO_MASK);
312 spin_unlock_irqrestore(&gpt->lock, flags); 312 raw_spin_unlock_irqrestore(&gpt->lock, flags);
313 313
314 return 0; 314 return 0;
315} 315}
@@ -436,16 +436,16 @@ static int mpc52xx_gpt_do_start(struct mpc52xx_gpt_priv *gpt, u64 period,
436 } 436 }
437 437
438 /* Set and enable the timer, reject an attempt to use a wdt as gpt */ 438 /* Set and enable the timer, reject an attempt to use a wdt as gpt */
439 spin_lock_irqsave(&gpt->lock, flags); 439 raw_spin_lock_irqsave(&gpt->lock, flags);
440 if (as_wdt) 440 if (as_wdt)
441 gpt->wdt_mode |= MPC52xx_GPT_IS_WDT; 441 gpt->wdt_mode |= MPC52xx_GPT_IS_WDT;
442 else if ((gpt->wdt_mode & MPC52xx_GPT_IS_WDT) != 0) { 442 else if ((gpt->wdt_mode & MPC52xx_GPT_IS_WDT) != 0) {
443 spin_unlock_irqrestore(&gpt->lock, flags); 443 raw_spin_unlock_irqrestore(&gpt->lock, flags);
444 return -EBUSY; 444 return -EBUSY;
445 } 445 }
446 out_be32(&gpt->regs->count, prescale << 16 | clocks); 446 out_be32(&gpt->regs->count, prescale << 16 | clocks);
447 clrsetbits_be32(&gpt->regs->mode, clear, set); 447 clrsetbits_be32(&gpt->regs->mode, clear, set);
448 spin_unlock_irqrestore(&gpt->lock, flags); 448 raw_spin_unlock_irqrestore(&gpt->lock, flags);
449 449
450 return 0; 450 return 0;
451} 451}
@@ -476,14 +476,14 @@ int mpc52xx_gpt_stop_timer(struct mpc52xx_gpt_priv *gpt)
476 unsigned long flags; 476 unsigned long flags;
477 477
478 /* reject the operation if the timer is used as watchdog (gpt 0 only) */ 478 /* reject the operation if the timer is used as watchdog (gpt 0 only) */
479 spin_lock_irqsave(&gpt->lock, flags); 479 raw_spin_lock_irqsave(&gpt->lock, flags);
480 if ((gpt->wdt_mode & MPC52xx_GPT_IS_WDT) != 0) { 480 if ((gpt->wdt_mode & MPC52xx_GPT_IS_WDT) != 0) {
481 spin_unlock_irqrestore(&gpt->lock, flags); 481 raw_spin_unlock_irqrestore(&gpt->lock, flags);
482 return -EBUSY; 482 return -EBUSY;
483 } 483 }
484 484
485 clrbits32(&gpt->regs->mode, MPC52xx_GPT_MODE_COUNTER_ENABLE); 485 clrbits32(&gpt->regs->mode, MPC52xx_GPT_MODE_COUNTER_ENABLE);
486 spin_unlock_irqrestore(&gpt->lock, flags); 486 raw_spin_unlock_irqrestore(&gpt->lock, flags);
487 return 0; 487 return 0;
488} 488}
489EXPORT_SYMBOL(mpc52xx_gpt_stop_timer); 489EXPORT_SYMBOL(mpc52xx_gpt_stop_timer);
@@ -500,9 +500,9 @@ u64 mpc52xx_gpt_timer_period(struct mpc52xx_gpt_priv *gpt)
500 u64 prescale; 500 u64 prescale;
501 unsigned long flags; 501 unsigned long flags;
502 502
503 spin_lock_irqsave(&gpt->lock, flags); 503 raw_spin_lock_irqsave(&gpt->lock, flags);
504 period = in_be32(&gpt->regs->count); 504 period = in_be32(&gpt->regs->count);
505 spin_unlock_irqrestore(&gpt->lock, flags); 505 raw_spin_unlock_irqrestore(&gpt->lock, flags);
506 506
507 prescale = period >> 16; 507 prescale = period >> 16;
508 period &= 0xffff; 508 period &= 0xffff;
@@ -532,9 +532,9 @@ static inline void mpc52xx_gpt_wdt_ping(struct mpc52xx_gpt_priv *gpt_wdt)
532{ 532{
533 unsigned long flags; 533 unsigned long flags;
534 534
535 spin_lock_irqsave(&gpt_wdt->lock, flags); 535 raw_spin_lock_irqsave(&gpt_wdt->lock, flags);
536 out_8((u8 *) &gpt_wdt->regs->mode, MPC52xx_GPT_MODE_WDT_PING); 536 out_8((u8 *) &gpt_wdt->regs->mode, MPC52xx_GPT_MODE_WDT_PING);
537 spin_unlock_irqrestore(&gpt_wdt->lock, flags); 537 raw_spin_unlock_irqrestore(&gpt_wdt->lock, flags);
538} 538}
539 539
540/* wdt misc device api */ 540/* wdt misc device api */
@@ -638,11 +638,11 @@ static int mpc52xx_wdt_release(struct inode *inode, struct file *file)
638 struct mpc52xx_gpt_priv *gpt_wdt = file->private_data; 638 struct mpc52xx_gpt_priv *gpt_wdt = file->private_data;
639 unsigned long flags; 639 unsigned long flags;
640 640
641 spin_lock_irqsave(&gpt_wdt->lock, flags); 641 raw_spin_lock_irqsave(&gpt_wdt->lock, flags);
642 clrbits32(&gpt_wdt->regs->mode, 642 clrbits32(&gpt_wdt->regs->mode,
643 MPC52xx_GPT_MODE_COUNTER_ENABLE | MPC52xx_GPT_MODE_WDT_EN); 643 MPC52xx_GPT_MODE_COUNTER_ENABLE | MPC52xx_GPT_MODE_WDT_EN);
644 gpt_wdt->wdt_mode &= ~MPC52xx_GPT_IS_WDT; 644 gpt_wdt->wdt_mode &= ~MPC52xx_GPT_IS_WDT;
645 spin_unlock_irqrestore(&gpt_wdt->lock, flags); 645 raw_spin_unlock_irqrestore(&gpt_wdt->lock, flags);
646#endif 646#endif
647 clear_bit(0, &wdt_is_active); 647 clear_bit(0, &wdt_is_active);
648 return 0; 648 return 0;
@@ -723,7 +723,7 @@ static int mpc52xx_gpt_probe(struct platform_device *ofdev)
723 if (!gpt) 723 if (!gpt)
724 return -ENOMEM; 724 return -ENOMEM;
725 725
726 spin_lock_init(&gpt->lock); 726 raw_spin_lock_init(&gpt->lock);
727 gpt->dev = &ofdev->dev; 727 gpt->dev = &ofdev->dev;
728 gpt->ipb_freq = mpc5xxx_get_bus_frequency(ofdev->dev.of_node); 728 gpt->ipb_freq = mpc5xxx_get_bus_frequency(ofdev->dev.of_node);
729 gpt->regs = of_iomap(ofdev->dev.of_node, 0); 729 gpt->regs = of_iomap(ofdev->dev.of_node, 0);