ir-rx51: use hrtimer instead of dmtimer
authorIvaylo Dimitrov <ivo.g.dimitrov.75@gmail.com>
Wed, 22 Jun 2016 19:22:21 +0000 (22:22 +0300)
committerTony Lindgren <tony@atomide.com>
Thu, 30 Jun 2016 04:54:35 +0000 (21:54 -0700)
Drop dmtimer usage for pulse timer in favor of hrtimer. That allows
removing PWM dmitimer platform data usage.

Signed-off-by: Ivaylo Dimitrov <ivo.g.dimitrov.75@gmail.com>
Acked-by: Pali Rohár <pali.rohar@gmail.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>
arch/arm/mach-omap2/board-rx51-peripherals.c
arch/arm/mach-omap2/pdata-quirks.c
drivers/media/rc/ir-rx51.c
include/linux/platform_data/media/ir-rx51.h

index e487575a86ca64b3650a511d926d9c590784e9f7..a5ab712c1a59785db07431f1089899ea04bf6053 100644 (file)
@@ -1242,10 +1242,6 @@ static struct pwm_omap_dmtimer_pdata __maybe_unused pwm_dmtimer_pdata = {
 #if defined(CONFIG_IR_RX51) || defined(CONFIG_IR_RX51_MODULE)
 static struct lirc_rx51_platform_data rx51_lirc_data = {
        .set_max_mpu_wakeup_lat = omap_pm_set_max_mpu_wakeup_lat,
-#if IS_ENABLED(CONFIG_OMAP_DM_TIMER)
-       .dmtimer = &pwm_dmtimer_pdata,
-#endif
-
 };
 
 static struct platform_device rx51_lirc_device = {
index 0d7b05a36b99a4347987adfad51df1ec37cccd85..7cc672b33e0c26822f1140a4d07ab9e938c66d94 100644 (file)
@@ -486,9 +486,6 @@ static struct pwm_omap_dmtimer_pdata pwm_dmtimer_pdata = {
 
 static struct lirc_rx51_platform_data __maybe_unused rx51_lirc_data = {
        .set_max_mpu_wakeup_lat = omap_pm_set_max_mpu_wakeup_lat,
-#if IS_ENABLED(CONFIG_OMAP_DM_TIMER)
-       .dmtimer = &pwm_dmtimer_pdata,
-#endif
 };
 
 static struct platform_device __maybe_unused rx51_lirc_device = {
index 1cbb43d0a35089c78b97dce9115af7f076b6a13c..82fb6f2ca01194f3ad593059fa7c84d13481f590 100644 (file)
 #include <linux/wait.h>
 #include <linux/pwm.h>
 #include <linux/of.h>
+#include <linux/hrtimer.h>
 
 #include <media/lirc.h>
 #include <media/lirc_dev.h>
-#include <linux/platform_data/pwm_omap_dmtimer.h>
 #include <linux/platform_data/media/ir-rx51.h>
 
 #define LIRC_RX51_DRIVER_FEATURES (LIRC_CAN_SET_SEND_DUTY_CYCLE |      \
 
 #define WBUF_LEN 256
 
-#define TIMER_MAX_VALUE 0xffffffff
-
 struct lirc_rx51 {
        struct pwm_device *pwm;
-       pwm_omap_dmtimer *pulse_timer;
-       struct pwm_omap_dmtimer_pdata *dmtimer;
+       struct hrtimer timer;
        struct device        *dev;
        struct lirc_rx51_platform_data *pdata;
        wait_queue_head_t     wqueue;
 
-       unsigned long   fclk_khz;
        unsigned int    freq;           /* carrier frequency */
        unsigned int    duty_cycle;     /* carrier duty cycle */
-       unsigned int    irq_num;
-       unsigned int    match;
        int             wbuf[WBUF_LEN];
        int             wbuf_index;
        unsigned long   device_is_open;
 };
 
-static void lirc_rx51_on(struct lirc_rx51 *lirc_rx51)
+static inline void lirc_rx51_on(struct lirc_rx51 *lirc_rx51)
 {
        pwm_enable(lirc_rx51->pwm);
 }
 
-static void lirc_rx51_off(struct lirc_rx51 *lirc_rx51)
+static inline void lirc_rx51_off(struct lirc_rx51 *lirc_rx51)
 {
        pwm_disable(lirc_rx51->pwm);
 }
@@ -72,61 +66,21 @@ static int init_timing_params(struct lirc_rx51 *lirc_rx51)
        int duty, period = DIV_ROUND_CLOSEST(NSEC_PER_SEC, lirc_rx51->freq);
 
        duty = DIV_ROUND_CLOSEST(lirc_rx51->duty_cycle * period, 100);
-       lirc_rx51->dmtimer->set_int_enable(lirc_rx51->pulse_timer, 0);
 
        pwm_config(pwm, duty, period);
 
-       lirc_rx51->dmtimer->start(lirc_rx51->pulse_timer);
-
-       lirc_rx51->match = 0;
-
        return 0;
 }
 
-#define tics_after(a, b) ((long)(b) - (long)(a) < 0)
-
-static int pulse_timer_set_timeout(struct lirc_rx51 *lirc_rx51, int usec)
+static enum hrtimer_restart lirc_rx51_timer_cb(struct hrtimer *timer)
 {
-       int counter;
-
-       BUG_ON(usec < 0);
-
-       if (lirc_rx51->match == 0)
-               counter = lirc_rx51->dmtimer->read_counter(lirc_rx51->pulse_timer);
-       else
-               counter = lirc_rx51->match;
-
-       counter += (u32)(lirc_rx51->fclk_khz * usec / (1000));
-       lirc_rx51->dmtimer->set_match(lirc_rx51->pulse_timer, 1, counter);
-       lirc_rx51->dmtimer->set_int_enable(lirc_rx51->pulse_timer,
-                                          PWM_OMAP_DMTIMER_INT_MATCH);
-       if (tics_after(lirc_rx51->dmtimer->read_counter(lirc_rx51->pulse_timer),
-                      counter)) {
-               return 1;
-       }
-       return 0;
-}
+       struct lirc_rx51 *lirc_rx51 =
+                       container_of(timer, struct lirc_rx51, timer);
+       ktime_t now;
 
-static irqreturn_t lirc_rx51_interrupt_handler(int irq, void *ptr)
-{
-       unsigned int retval;
-       struct lirc_rx51 *lirc_rx51 = ptr;
-
-       retval = lirc_rx51->dmtimer->read_status(lirc_rx51->pulse_timer);
-       if (!retval)
-               return IRQ_NONE;
-
-       if (retval & ~PWM_OMAP_DMTIMER_INT_MATCH)
-               dev_err_ratelimited(lirc_rx51->dev,
-                               ": Unexpected interrupt source: %x\n", retval);
-
-       lirc_rx51->dmtimer->write_status(lirc_rx51->pulse_timer,
-                                        PWM_OMAP_DMTIMER_INT_MATCH |
-                                        PWM_OMAP_DMTIMER_INT_OVERFLOW |
-                                        PWM_OMAP_DMTIMER_INT_CAPTURE);
        if (lirc_rx51->wbuf_index < 0) {
                dev_err_ratelimited(lirc_rx51->dev,
-                               "BUG wbuf_index has value of %i\n",
+                               "BUG wbuf_index has value of %i\n",
                                lirc_rx51->wbuf_index);
                goto end;
        }
@@ -136,6 +90,8 @@ static irqreturn_t lirc_rx51_interrupt_handler(int irq, void *ptr)
         * pulses until we catch up.
         */
        do {
+               u64 ns;
+
                if (lirc_rx51->wbuf_index >= WBUF_LEN)
                        goto end;
                if (lirc_rx51->wbuf[lirc_rx51->wbuf_index] == -1)
@@ -146,80 +102,24 @@ static irqreturn_t lirc_rx51_interrupt_handler(int irq, void *ptr)
                else
                        lirc_rx51_on(lirc_rx51);
 
-               retval = pulse_timer_set_timeout(lirc_rx51,
-                                       lirc_rx51->wbuf[lirc_rx51->wbuf_index]);
+               ns = 1000 * lirc_rx51->wbuf[lirc_rx51->wbuf_index];
+               hrtimer_add_expires_ns(timer, ns);
+
                lirc_rx51->wbuf_index++;
 
-       } while (retval);
+               now = timer->base->get_time();
+
+       } while (hrtimer_get_expires_tv64(timer) < now.tv64);
 
-       return IRQ_HANDLED;
+       return HRTIMER_RESTART;
 end:
        /* Stop TX here */
        lirc_rx51_off(lirc_rx51);
        lirc_rx51->wbuf_index = -1;
 
-       lirc_rx51->dmtimer->stop(lirc_rx51->pulse_timer);
-       lirc_rx51->dmtimer->set_int_enable(lirc_rx51->pulse_timer, 0);
        wake_up_interruptible(&lirc_rx51->wqueue);
 
-       return IRQ_HANDLED;
-}
-
-static int lirc_rx51_init_port(struct lirc_rx51 *lirc_rx51)
-{
-       struct clk *clk_fclk;
-       int retval;
-
-       lirc_rx51->pwm = pwm_get(lirc_rx51->dev, NULL);
-       if (IS_ERR(lirc_rx51->pwm)) {
-               retval = PTR_ERR(lirc_rx51->pwm);
-               dev_err(lirc_rx51->dev, ": pwm_get failed: %d\n", retval);
-               return retval;
-       }
-
-       lirc_rx51->pulse_timer = lirc_rx51->dmtimer->request();
-       if (lirc_rx51->pulse_timer == NULL) {
-               dev_err(lirc_rx51->dev, ": Error requesting pulse timer\n");
-               retval = -EBUSY;
-               goto err1;
-       }
-
-       lirc_rx51->dmtimer->set_source(lirc_rx51->pulse_timer,
-                                      PWM_OMAP_DMTIMER_SRC_SYS_CLK);
-       lirc_rx51->dmtimer->enable(lirc_rx51->pulse_timer);
-       lirc_rx51->irq_num =
-                       lirc_rx51->dmtimer->get_irq(lirc_rx51->pulse_timer);
-       retval = request_irq(lirc_rx51->irq_num, lirc_rx51_interrupt_handler,
-                            IRQF_SHARED, "lirc_pulse_timer", lirc_rx51);
-       if (retval) {
-               dev_err(lirc_rx51->dev, ": Failed to request interrupt line\n");
-               goto err2;
-       }
-
-       clk_fclk = lirc_rx51->dmtimer->get_fclk(lirc_rx51->pulse_timer);
-       lirc_rx51->fclk_khz = clk_get_rate(clk_fclk) / 1000;
-
-       return 0;
-
-err2:
-       lirc_rx51->dmtimer->free(lirc_rx51->pulse_timer);
-err1:
-       pwm_put(lirc_rx51->pwm);
-
-       return retval;
-}
-
-static int lirc_rx51_free_port(struct lirc_rx51 *lirc_rx51)
-{
-       lirc_rx51->dmtimer->set_int_enable(lirc_rx51->pulse_timer, 0);
-       free_irq(lirc_rx51->irq_num, lirc_rx51);
-       lirc_rx51_off(lirc_rx51);
-       lirc_rx51->dmtimer->disable(lirc_rx51->pulse_timer);
-       lirc_rx51->dmtimer->free(lirc_rx51->pulse_timer);
-       lirc_rx51->wbuf_index = -1;
-       pwm_put(lirc_rx51->pwm);
-
-       return 0;
+       return HRTIMER_NORESTART;
 }
 
 static ssize_t lirc_rx51_write(struct file *file, const char *buf,
@@ -258,8 +158,9 @@ static ssize_t lirc_rx51_write(struct file *file, const char *buf,
 
        lirc_rx51_on(lirc_rx51);
        lirc_rx51->wbuf_index = 1;
-       pulse_timer_set_timeout(lirc_rx51, lirc_rx51->wbuf[0]);
-
+       hrtimer_start(&lirc_rx51->timer,
+                     ns_to_ktime(1000 * lirc_rx51->wbuf[0]),
+                     HRTIMER_MODE_REL);
        /*
         * Don't return back to the userspace until the transfer has
         * finished
@@ -359,14 +260,24 @@ static int lirc_rx51_open(struct inode *inode, struct file *file)
        if (test_and_set_bit(1, &lirc_rx51->device_is_open))
                return -EBUSY;
 
-       return lirc_rx51_init_port(lirc_rx51);
+       lirc_rx51->pwm = pwm_get(lirc_rx51->dev, NULL);
+       if (IS_ERR(lirc_rx51->pwm)) {
+               int res = PTR_ERR(lirc_rx51->pwm);
+
+               dev_err(lirc_rx51->dev, "pwm_get failed: %d\n", res);
+               return res;
+       }
+
+       return 0;
 }
 
 static int lirc_rx51_release(struct inode *inode, struct file *file)
 {
        struct lirc_rx51 *lirc_rx51 = file->private_data;
 
-       lirc_rx51_free_port(lirc_rx51);
+       hrtimer_cancel(&lirc_rx51->timer);
+       lirc_rx51_off(lirc_rx51);
+       pwm_put(lirc_rx51->pwm);
 
        clear_bit(1, &lirc_rx51->device_is_open);
 
@@ -441,11 +352,6 @@ static int lirc_rx51_probe(struct platform_device *dev)
                return -ENXIO;
        }
 
-       if (!lirc_rx51.pdata->dmtimer) {
-               dev_err(&dev->dev, "no dmtimer?\n");
-               return -ENODEV;
-       }
-
        pwm = pwm_get(&dev->dev, NULL);
        if (IS_ERR(pwm)) {
                int err = PTR_ERR(pwm);
@@ -459,7 +365,9 @@ static int lirc_rx51_probe(struct platform_device *dev)
        lirc_rx51.freq = DIV_ROUND_CLOSEST(pwm_get_period(pwm), NSEC_PER_SEC);
        pwm_put(pwm);
 
-       lirc_rx51.dmtimer = lirc_rx51.pdata->dmtimer;
+       hrtimer_init(&lirc_rx51.timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+       lirc_rx51.timer.function = lirc_rx51_timer_cb;
+
        lirc_rx51.dev = &dev->dev;
        lirc_rx51_driver.dev = &dev->dev;
        lirc_rx51_driver.minor = lirc_register_driver(&lirc_rx51_driver);
index 6acf22d497f7f59046cd55bcb0d0d793e82810a4..812d8730787735d15dbc273ff4bd922bbe899ca2 100644 (file)
@@ -3,7 +3,6 @@
 
 struct lirc_rx51_platform_data {
        int(*set_max_mpu_wakeup_lat)(struct device *dev, long t);
-       struct pwm_omap_dmtimer_pdata *dmtimer;
 };
 
 #endif