0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051 #include <linux/device.h>
0052 #include <linux/irq.h>
0053 #include <linux/interrupt.h>
0054 #include <linux/io.h>
0055 #include <linux/list.h>
0056 #include <linux/mutex.h>
0057 #include <linux/of.h>
0058 #include <linux/of_address.h>
0059 #include <linux/of_irq.h>
0060 #include <linux/of_platform.h>
0061 #include <linux/of_gpio.h>
0062 #include <linux/kernel.h>
0063 #include <linux/property.h>
0064 #include <linux/slab.h>
0065 #include <linux/fs.h>
0066 #include <linux/watchdog.h>
0067 #include <linux/miscdevice.h>
0068 #include <linux/uaccess.h>
0069 #include <linux/module.h>
0070 #include <asm/div64.h>
0071 #include <asm/mpc52xx.h>
0072
0073 MODULE_DESCRIPTION("Freescale MPC52xx gpt driver");
0074 MODULE_AUTHOR("Sascha Hauer, Grant Likely, Albrecht Dreß");
0075 MODULE_LICENSE("GPL");
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088 struct mpc52xx_gpt_priv {
0089 struct list_head list;
0090 struct device *dev;
0091 struct mpc52xx_gpt __iomem *regs;
0092 raw_spinlock_t lock;
0093 struct irq_domain *irqhost;
0094 u32 ipb_freq;
0095 u8 wdt_mode;
0096
0097 #if defined(CONFIG_GPIOLIB)
0098 struct gpio_chip gc;
0099 #endif
0100 };
0101
0102 LIST_HEAD(mpc52xx_gpt_list);
0103 DEFINE_MUTEX(mpc52xx_gpt_list_mutex);
0104
0105 #define MPC52xx_GPT_MODE_MS_MASK (0x07)
0106 #define MPC52xx_GPT_MODE_MS_IC (0x01)
0107 #define MPC52xx_GPT_MODE_MS_OC (0x02)
0108 #define MPC52xx_GPT_MODE_MS_PWM (0x03)
0109 #define MPC52xx_GPT_MODE_MS_GPIO (0x04)
0110
0111 #define MPC52xx_GPT_MODE_GPIO_MASK (0x30)
0112 #define MPC52xx_GPT_MODE_GPIO_OUT_LOW (0x20)
0113 #define MPC52xx_GPT_MODE_GPIO_OUT_HIGH (0x30)
0114
0115 #define MPC52xx_GPT_MODE_COUNTER_ENABLE (0x1000)
0116 #define MPC52xx_GPT_MODE_CONTINUOUS (0x0400)
0117 #define MPC52xx_GPT_MODE_OPEN_DRAIN (0x0200)
0118 #define MPC52xx_GPT_MODE_IRQ_EN (0x0100)
0119 #define MPC52xx_GPT_MODE_WDT_EN (0x8000)
0120
0121 #define MPC52xx_GPT_MODE_ICT_MASK (0x030000)
0122 #define MPC52xx_GPT_MODE_ICT_RISING (0x010000)
0123 #define MPC52xx_GPT_MODE_ICT_FALLING (0x020000)
0124 #define MPC52xx_GPT_MODE_ICT_TOGGLE (0x030000)
0125
0126 #define MPC52xx_GPT_MODE_WDT_PING (0xa5)
0127
0128 #define MPC52xx_GPT_STATUS_IRQMASK (0x000f)
0129
0130 #define MPC52xx_GPT_CAN_WDT (1 << 0)
0131 #define MPC52xx_GPT_IS_WDT (1 << 1)
0132
0133
0134
0135
0136
0137
0138 static void mpc52xx_gpt_irq_unmask(struct irq_data *d)
0139 {
0140 struct mpc52xx_gpt_priv *gpt = irq_data_get_irq_chip_data(d);
0141 unsigned long flags;
0142
0143 raw_spin_lock_irqsave(&gpt->lock, flags);
0144 setbits32(&gpt->regs->mode, MPC52xx_GPT_MODE_IRQ_EN);
0145 raw_spin_unlock_irqrestore(&gpt->lock, flags);
0146 }
0147
0148 static void mpc52xx_gpt_irq_mask(struct irq_data *d)
0149 {
0150 struct mpc52xx_gpt_priv *gpt = irq_data_get_irq_chip_data(d);
0151 unsigned long flags;
0152
0153 raw_spin_lock_irqsave(&gpt->lock, flags);
0154 clrbits32(&gpt->regs->mode, MPC52xx_GPT_MODE_IRQ_EN);
0155 raw_spin_unlock_irqrestore(&gpt->lock, flags);
0156 }
0157
0158 static void mpc52xx_gpt_irq_ack(struct irq_data *d)
0159 {
0160 struct mpc52xx_gpt_priv *gpt = irq_data_get_irq_chip_data(d);
0161
0162 out_be32(&gpt->regs->status, MPC52xx_GPT_STATUS_IRQMASK);
0163 }
0164
0165 static int mpc52xx_gpt_irq_set_type(struct irq_data *d, unsigned int flow_type)
0166 {
0167 struct mpc52xx_gpt_priv *gpt = irq_data_get_irq_chip_data(d);
0168 unsigned long flags;
0169 u32 reg;
0170
0171 dev_dbg(gpt->dev, "%s: virq=%i type=%x\n", __func__, d->irq, flow_type);
0172
0173 raw_spin_lock_irqsave(&gpt->lock, flags);
0174 reg = in_be32(&gpt->regs->mode) & ~MPC52xx_GPT_MODE_ICT_MASK;
0175 if (flow_type & IRQF_TRIGGER_RISING)
0176 reg |= MPC52xx_GPT_MODE_ICT_RISING;
0177 if (flow_type & IRQF_TRIGGER_FALLING)
0178 reg |= MPC52xx_GPT_MODE_ICT_FALLING;
0179 out_be32(&gpt->regs->mode, reg);
0180 raw_spin_unlock_irqrestore(&gpt->lock, flags);
0181
0182 return 0;
0183 }
0184
0185 static struct irq_chip mpc52xx_gpt_irq_chip = {
0186 .name = "MPC52xx GPT",
0187 .irq_unmask = mpc52xx_gpt_irq_unmask,
0188 .irq_mask = mpc52xx_gpt_irq_mask,
0189 .irq_ack = mpc52xx_gpt_irq_ack,
0190 .irq_set_type = mpc52xx_gpt_irq_set_type,
0191 };
0192
0193 static void mpc52xx_gpt_irq_cascade(struct irq_desc *desc)
0194 {
0195 struct mpc52xx_gpt_priv *gpt = irq_desc_get_handler_data(desc);
0196 u32 status;
0197
0198 status = in_be32(&gpt->regs->status) & MPC52xx_GPT_STATUS_IRQMASK;
0199 if (status)
0200 generic_handle_domain_irq(gpt->irqhost, 0);
0201 }
0202
0203 static int mpc52xx_gpt_irq_map(struct irq_domain *h, unsigned int virq,
0204 irq_hw_number_t hw)
0205 {
0206 struct mpc52xx_gpt_priv *gpt = h->host_data;
0207
0208 dev_dbg(gpt->dev, "%s: h=%p, virq=%i\n", __func__, h, virq);
0209 irq_set_chip_data(virq, gpt);
0210 irq_set_chip_and_handler(virq, &mpc52xx_gpt_irq_chip, handle_edge_irq);
0211
0212 return 0;
0213 }
0214
0215 static int mpc52xx_gpt_irq_xlate(struct irq_domain *h, struct device_node *ct,
0216 const u32 *intspec, unsigned int intsize,
0217 irq_hw_number_t *out_hwirq,
0218 unsigned int *out_flags)
0219 {
0220 struct mpc52xx_gpt_priv *gpt = h->host_data;
0221
0222 dev_dbg(gpt->dev, "%s: flags=%i\n", __func__, intspec[0]);
0223
0224 if ((intsize < 1) || (intspec[0] > 3)) {
0225 dev_err(gpt->dev, "bad irq specifier in %pOF\n", ct);
0226 return -EINVAL;
0227 }
0228
0229 *out_hwirq = 0;
0230 *out_flags = intspec[0];
0231
0232 return 0;
0233 }
0234
0235 static const struct irq_domain_ops mpc52xx_gpt_irq_ops = {
0236 .map = mpc52xx_gpt_irq_map,
0237 .xlate = mpc52xx_gpt_irq_xlate,
0238 };
0239
0240 static void
0241 mpc52xx_gpt_irq_setup(struct mpc52xx_gpt_priv *gpt, struct device_node *node)
0242 {
0243 int cascade_virq;
0244 unsigned long flags;
0245 u32 mode;
0246
0247 cascade_virq = irq_of_parse_and_map(node, 0);
0248 if (!cascade_virq)
0249 return;
0250
0251 gpt->irqhost = irq_domain_add_linear(node, 1, &mpc52xx_gpt_irq_ops, gpt);
0252 if (!gpt->irqhost) {
0253 dev_err(gpt->dev, "irq_domain_add_linear() failed\n");
0254 return;
0255 }
0256
0257 irq_set_handler_data(cascade_virq, gpt);
0258 irq_set_chained_handler(cascade_virq, mpc52xx_gpt_irq_cascade);
0259
0260
0261
0262
0263 raw_spin_lock_irqsave(&gpt->lock, flags);
0264 mode = in_be32(&gpt->regs->mode);
0265 if ((mode & MPC52xx_GPT_MODE_MS_MASK) == 0)
0266 out_be32(&gpt->regs->mode, mode | MPC52xx_GPT_MODE_MS_IC);
0267 raw_spin_unlock_irqrestore(&gpt->lock, flags);
0268
0269 dev_dbg(gpt->dev, "%s() complete. virq=%i\n", __func__, cascade_virq);
0270 }
0271
0272
0273
0274
0275
0276 #if defined(CONFIG_GPIOLIB)
0277 static int mpc52xx_gpt_gpio_get(struct gpio_chip *gc, unsigned int gpio)
0278 {
0279 struct mpc52xx_gpt_priv *gpt = gpiochip_get_data(gc);
0280
0281 return (in_be32(&gpt->regs->status) >> 8) & 1;
0282 }
0283
0284 static void
0285 mpc52xx_gpt_gpio_set(struct gpio_chip *gc, unsigned int gpio, int v)
0286 {
0287 struct mpc52xx_gpt_priv *gpt = gpiochip_get_data(gc);
0288 unsigned long flags;
0289 u32 r;
0290
0291 dev_dbg(gpt->dev, "%s: gpio:%d v:%d\n", __func__, gpio, v);
0292 r = v ? MPC52xx_GPT_MODE_GPIO_OUT_HIGH : MPC52xx_GPT_MODE_GPIO_OUT_LOW;
0293
0294 raw_spin_lock_irqsave(&gpt->lock, flags);
0295 clrsetbits_be32(&gpt->regs->mode, MPC52xx_GPT_MODE_GPIO_MASK, r);
0296 raw_spin_unlock_irqrestore(&gpt->lock, flags);
0297 }
0298
0299 static int mpc52xx_gpt_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
0300 {
0301 struct mpc52xx_gpt_priv *gpt = gpiochip_get_data(gc);
0302 unsigned long flags;
0303
0304 dev_dbg(gpt->dev, "%s: gpio:%d\n", __func__, gpio);
0305
0306 raw_spin_lock_irqsave(&gpt->lock, flags);
0307 clrbits32(&gpt->regs->mode, MPC52xx_GPT_MODE_GPIO_MASK);
0308 raw_spin_unlock_irqrestore(&gpt->lock, flags);
0309
0310 return 0;
0311 }
0312
0313 static int
0314 mpc52xx_gpt_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
0315 {
0316 mpc52xx_gpt_gpio_set(gc, gpio, val);
0317 return 0;
0318 }
0319
0320 static void mpc52xx_gpt_gpio_setup(struct mpc52xx_gpt_priv *gpt)
0321 {
0322 int rc;
0323
0324
0325 if (!device_property_present(gpt->dev, "gpio-controller"))
0326 return;
0327
0328 gpt->gc.label = kasprintf(GFP_KERNEL, "%pfw", dev_fwnode(gpt->dev));
0329 if (!gpt->gc.label) {
0330 dev_err(gpt->dev, "out of memory\n");
0331 return;
0332 }
0333
0334 gpt->gc.ngpio = 1;
0335 gpt->gc.direction_input = mpc52xx_gpt_gpio_dir_in;
0336 gpt->gc.direction_output = mpc52xx_gpt_gpio_dir_out;
0337 gpt->gc.get = mpc52xx_gpt_gpio_get;
0338 gpt->gc.set = mpc52xx_gpt_gpio_set;
0339 gpt->gc.base = -1;
0340 gpt->gc.parent = gpt->dev;
0341
0342
0343 clrsetbits_be32(&gpt->regs->mode, MPC52xx_GPT_MODE_MS_MASK,
0344 MPC52xx_GPT_MODE_MS_GPIO);
0345
0346 rc = gpiochip_add_data(&gpt->gc, gpt);
0347 if (rc)
0348 dev_err(gpt->dev, "gpiochip_add_data() failed; rc=%i\n", rc);
0349
0350 dev_dbg(gpt->dev, "%s() complete.\n", __func__);
0351 }
0352 #else
0353 static void mpc52xx_gpt_gpio_setup(struct mpc52xx_gpt_priv *gpt) { }
0354 #endif
0355
0356
0357
0358
0359
0360
0361
0362
0363
0364 struct mpc52xx_gpt_priv *mpc52xx_gpt_from_irq(int irq)
0365 {
0366 struct mpc52xx_gpt_priv *gpt;
0367 struct list_head *pos;
0368
0369
0370 mutex_lock(&mpc52xx_gpt_list_mutex);
0371 list_for_each(pos, &mpc52xx_gpt_list) {
0372 gpt = container_of(pos, struct mpc52xx_gpt_priv, list);
0373 if (gpt->irqhost && irq == irq_linear_revmap(gpt->irqhost, 0)) {
0374 mutex_unlock(&mpc52xx_gpt_list_mutex);
0375 return gpt;
0376 }
0377 }
0378 mutex_unlock(&mpc52xx_gpt_list_mutex);
0379
0380 return NULL;
0381 }
0382 EXPORT_SYMBOL(mpc52xx_gpt_from_irq);
0383
0384 static int mpc52xx_gpt_do_start(struct mpc52xx_gpt_priv *gpt, u64 period,
0385 int continuous, int as_wdt)
0386 {
0387 u32 clear, set;
0388 u64 clocks;
0389 u32 prescale;
0390 unsigned long flags;
0391
0392 clear = MPC52xx_GPT_MODE_MS_MASK | MPC52xx_GPT_MODE_CONTINUOUS;
0393 set = MPC52xx_GPT_MODE_MS_GPIO | MPC52xx_GPT_MODE_COUNTER_ENABLE;
0394 if (as_wdt) {
0395 clear |= MPC52xx_GPT_MODE_IRQ_EN;
0396 set |= MPC52xx_GPT_MODE_WDT_EN;
0397 } else if (continuous)
0398 set |= MPC52xx_GPT_MODE_CONTINUOUS;
0399
0400
0401
0402
0403
0404 clocks = period * (u64)gpt->ipb_freq;
0405 do_div(clocks, 1000000000);
0406
0407
0408 if (clocks > 0xffffffff)
0409 return -EINVAL;
0410
0411
0412
0413
0414
0415
0416
0417
0418
0419
0420
0421
0422
0423 prescale = (clocks >> 16) + 1;
0424 do_div(clocks, prescale);
0425 if (clocks > 0xffff) {
0426 pr_err("calculation error; prescale:%x clocks:%llx\n",
0427 prescale, clocks);
0428 return -EINVAL;
0429 }
0430
0431
0432 raw_spin_lock_irqsave(&gpt->lock, flags);
0433 if (as_wdt)
0434 gpt->wdt_mode |= MPC52xx_GPT_IS_WDT;
0435 else if ((gpt->wdt_mode & MPC52xx_GPT_IS_WDT) != 0) {
0436 raw_spin_unlock_irqrestore(&gpt->lock, flags);
0437 return -EBUSY;
0438 }
0439 out_be32(&gpt->regs->count, prescale << 16 | clocks);
0440 clrsetbits_be32(&gpt->regs->mode, clear, set);
0441 raw_spin_unlock_irqrestore(&gpt->lock, flags);
0442
0443 return 0;
0444 }
0445
0446
0447
0448
0449
0450
0451
0452
0453
0454 int mpc52xx_gpt_start_timer(struct mpc52xx_gpt_priv *gpt, u64 period,
0455 int continuous)
0456 {
0457 return mpc52xx_gpt_do_start(gpt, period, continuous, 0);
0458 }
0459 EXPORT_SYMBOL(mpc52xx_gpt_start_timer);
0460
0461
0462
0463
0464
0465
0466
0467 int mpc52xx_gpt_stop_timer(struct mpc52xx_gpt_priv *gpt)
0468 {
0469 unsigned long flags;
0470
0471
0472 raw_spin_lock_irqsave(&gpt->lock, flags);
0473 if ((gpt->wdt_mode & MPC52xx_GPT_IS_WDT) != 0) {
0474 raw_spin_unlock_irqrestore(&gpt->lock, flags);
0475 return -EBUSY;
0476 }
0477
0478 clrbits32(&gpt->regs->mode, MPC52xx_GPT_MODE_COUNTER_ENABLE);
0479 raw_spin_unlock_irqrestore(&gpt->lock, flags);
0480 return 0;
0481 }
0482 EXPORT_SYMBOL(mpc52xx_gpt_stop_timer);
0483
0484
0485
0486
0487
0488
0489
0490 u64 mpc52xx_gpt_timer_period(struct mpc52xx_gpt_priv *gpt)
0491 {
0492 u64 period;
0493 u64 prescale;
0494 unsigned long flags;
0495
0496 raw_spin_lock_irqsave(&gpt->lock, flags);
0497 period = in_be32(&gpt->regs->count);
0498 raw_spin_unlock_irqrestore(&gpt->lock, flags);
0499
0500 prescale = period >> 16;
0501 period &= 0xffff;
0502 if (prescale == 0)
0503 prescale = 0x10000;
0504 period = period * prescale * 1000000000ULL;
0505 do_div(period, gpt->ipb_freq);
0506 return period;
0507 }
0508 EXPORT_SYMBOL(mpc52xx_gpt_timer_period);
0509
0510 #if defined(CONFIG_MPC5200_WDT)
0511
0512
0513
0514
0515 #define WDT_IDENTITY "mpc52xx watchdog on GPT0"
0516
0517
0518 static unsigned long wdt_is_active;
0519
0520
0521 static struct mpc52xx_gpt_priv *mpc52xx_gpt_wdt;
0522
0523
0524 static inline void mpc52xx_gpt_wdt_ping(struct mpc52xx_gpt_priv *gpt_wdt)
0525 {
0526 unsigned long flags;
0527
0528 raw_spin_lock_irqsave(&gpt_wdt->lock, flags);
0529 out_8((u8 *) &gpt_wdt->regs->mode, MPC52xx_GPT_MODE_WDT_PING);
0530 raw_spin_unlock_irqrestore(&gpt_wdt->lock, flags);
0531 }
0532
0533
0534 static ssize_t mpc52xx_wdt_write(struct file *file, const char __user *data,
0535 size_t len, loff_t *ppos)
0536 {
0537 struct mpc52xx_gpt_priv *gpt_wdt = file->private_data;
0538 mpc52xx_gpt_wdt_ping(gpt_wdt);
0539 return 0;
0540 }
0541
0542 static const struct watchdog_info mpc5200_wdt_info = {
0543 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
0544 .identity = WDT_IDENTITY,
0545 };
0546
0547 static long mpc52xx_wdt_ioctl(struct file *file, unsigned int cmd,
0548 unsigned long arg)
0549 {
0550 struct mpc52xx_gpt_priv *gpt_wdt = file->private_data;
0551 int __user *data = (int __user *)arg;
0552 int timeout;
0553 u64 real_timeout;
0554 int ret = 0;
0555
0556 switch (cmd) {
0557 case WDIOC_GETSUPPORT:
0558 ret = copy_to_user(data, &mpc5200_wdt_info,
0559 sizeof(mpc5200_wdt_info));
0560 if (ret)
0561 ret = -EFAULT;
0562 break;
0563
0564 case WDIOC_GETSTATUS:
0565 case WDIOC_GETBOOTSTATUS:
0566 ret = put_user(0, data);
0567 break;
0568
0569 case WDIOC_KEEPALIVE:
0570 mpc52xx_gpt_wdt_ping(gpt_wdt);
0571 break;
0572
0573 case WDIOC_SETTIMEOUT:
0574 ret = get_user(timeout, data);
0575 if (ret)
0576 break;
0577 real_timeout = (u64) timeout * 1000000000ULL;
0578 ret = mpc52xx_gpt_do_start(gpt_wdt, real_timeout, 0, 1);
0579 if (ret)
0580 break;
0581
0582 fallthrough;
0583
0584 case WDIOC_GETTIMEOUT:
0585
0586
0587
0588
0589
0590
0591 real_timeout =
0592 mpc52xx_gpt_timer_period(gpt_wdt) + 500000000ULL;
0593 do_div(real_timeout, 1000000000ULL);
0594 timeout = (int) real_timeout;
0595 ret = put_user(timeout, data);
0596 break;
0597
0598 default:
0599 ret = -ENOTTY;
0600 }
0601 return ret;
0602 }
0603
0604 static int mpc52xx_wdt_open(struct inode *inode, struct file *file)
0605 {
0606 int ret;
0607
0608
0609 if (!mpc52xx_gpt_wdt)
0610 return -ENODEV;
0611
0612
0613 if (test_and_set_bit(0, &wdt_is_active))
0614 return -EBUSY;
0615
0616
0617 ret = mpc52xx_gpt_do_start(mpc52xx_gpt_wdt, 30ULL * 1000000000ULL,
0618 0, 1);
0619 if (ret) {
0620 clear_bit(0, &wdt_is_active);
0621 return ret;
0622 }
0623
0624 file->private_data = mpc52xx_gpt_wdt;
0625 return stream_open(inode, file);
0626 }
0627
0628 static int mpc52xx_wdt_release(struct inode *inode, struct file *file)
0629 {
0630
0631 #if !defined(CONFIG_WATCHDOG_NOWAYOUT)
0632 struct mpc52xx_gpt_priv *gpt_wdt = file->private_data;
0633 unsigned long flags;
0634
0635 raw_spin_lock_irqsave(&gpt_wdt->lock, flags);
0636 clrbits32(&gpt_wdt->regs->mode,
0637 MPC52xx_GPT_MODE_COUNTER_ENABLE | MPC52xx_GPT_MODE_WDT_EN);
0638 gpt_wdt->wdt_mode &= ~MPC52xx_GPT_IS_WDT;
0639 raw_spin_unlock_irqrestore(&gpt_wdt->lock, flags);
0640 #endif
0641 clear_bit(0, &wdt_is_active);
0642 return 0;
0643 }
0644
0645
0646 static const struct file_operations mpc52xx_wdt_fops = {
0647 .owner = THIS_MODULE,
0648 .llseek = no_llseek,
0649 .write = mpc52xx_wdt_write,
0650 .unlocked_ioctl = mpc52xx_wdt_ioctl,
0651 .compat_ioctl = compat_ptr_ioctl,
0652 .open = mpc52xx_wdt_open,
0653 .release = mpc52xx_wdt_release,
0654 };
0655
0656 static struct miscdevice mpc52xx_wdt_miscdev = {
0657 .minor = WATCHDOG_MINOR,
0658 .name = "watchdog",
0659 .fops = &mpc52xx_wdt_fops,
0660 };
0661
0662 static int mpc52xx_gpt_wdt_init(void)
0663 {
0664 int err;
0665
0666
0667 err = misc_register(&mpc52xx_wdt_miscdev);
0668 if (err)
0669 pr_err("%s: cannot register watchdog device\n", WDT_IDENTITY);
0670 else
0671 pr_info("%s: watchdog device registered\n", WDT_IDENTITY);
0672 return err;
0673 }
0674
0675 static int mpc52xx_gpt_wdt_setup(struct mpc52xx_gpt_priv *gpt,
0676 const u32 *period)
0677 {
0678 u64 real_timeout;
0679
0680
0681 mpc52xx_gpt_wdt = gpt;
0682
0683
0684 if (!period || *period == 0)
0685 return 0;
0686
0687 real_timeout = (u64) *period * 1000000000ULL;
0688 if (mpc52xx_gpt_do_start(gpt, real_timeout, 0, 1))
0689 dev_warn(gpt->dev, "starting as wdt failed\n");
0690 else
0691 dev_info(gpt->dev, "watchdog set to %us timeout\n", *period);
0692 return 0;
0693 }
0694
0695 #else
0696
0697 static int mpc52xx_gpt_wdt_init(void)
0698 {
0699 return 0;
0700 }
0701
0702 static inline int mpc52xx_gpt_wdt_setup(struct mpc52xx_gpt_priv *gpt,
0703 const u32 *period)
0704 {
0705 return 0;
0706 }
0707
0708 #endif
0709
0710
0711
0712
0713 static int mpc52xx_gpt_probe(struct platform_device *ofdev)
0714 {
0715 struct mpc52xx_gpt_priv *gpt;
0716
0717 gpt = devm_kzalloc(&ofdev->dev, sizeof *gpt, GFP_KERNEL);
0718 if (!gpt)
0719 return -ENOMEM;
0720
0721 raw_spin_lock_init(&gpt->lock);
0722 gpt->dev = &ofdev->dev;
0723 gpt->ipb_freq = mpc5xxx_get_bus_frequency(&ofdev->dev);
0724 gpt->regs = of_iomap(ofdev->dev.of_node, 0);
0725 if (!gpt->regs)
0726 return -ENOMEM;
0727
0728 dev_set_drvdata(&ofdev->dev, gpt);
0729
0730 mpc52xx_gpt_gpio_setup(gpt);
0731 mpc52xx_gpt_irq_setup(gpt, ofdev->dev.of_node);
0732
0733 mutex_lock(&mpc52xx_gpt_list_mutex);
0734 list_add(&gpt->list, &mpc52xx_gpt_list);
0735 mutex_unlock(&mpc52xx_gpt_list_mutex);
0736
0737
0738 if (of_get_property(ofdev->dev.of_node, "fsl,has-wdt", NULL) ||
0739 of_get_property(ofdev->dev.of_node, "has-wdt", NULL)) {
0740 const u32 *on_boot_wdt;
0741
0742 gpt->wdt_mode = MPC52xx_GPT_CAN_WDT;
0743 on_boot_wdt = of_get_property(ofdev->dev.of_node,
0744 "fsl,wdt-on-boot", NULL);
0745 if (on_boot_wdt) {
0746 dev_info(gpt->dev, "used as watchdog\n");
0747 gpt->wdt_mode |= MPC52xx_GPT_IS_WDT;
0748 } else
0749 dev_info(gpt->dev, "can function as watchdog\n");
0750 mpc52xx_gpt_wdt_setup(gpt, on_boot_wdt);
0751 }
0752
0753 return 0;
0754 }
0755
0756 static const struct of_device_id mpc52xx_gpt_match[] = {
0757 { .compatible = "fsl,mpc5200-gpt", },
0758
0759
0760 { .compatible = "fsl,mpc5200-gpt-gpio", },
0761 { .compatible = "mpc5200-gpt", },
0762 {}
0763 };
0764
0765 static struct platform_driver mpc52xx_gpt_driver = {
0766 .driver = {
0767 .name = "mpc52xx-gpt",
0768 .suppress_bind_attrs = true,
0769 .of_match_table = mpc52xx_gpt_match,
0770 },
0771 .probe = mpc52xx_gpt_probe,
0772 };
0773
0774 static int __init mpc52xx_gpt_init(void)
0775 {
0776 return platform_driver_register(&mpc52xx_gpt_driver);
0777 }
0778
0779
0780 subsys_initcall(mpc52xx_gpt_init);
0781 device_initcall(mpc52xx_gpt_wdt_init);