All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/6] Implement event capture for OMAP (draft)
@ 2018-02-23 10:12 ` Ladislav Michl
  0 siblings, 0 replies; 30+ messages in thread
From: Ladislav Michl @ 2018-02-23 10:12 UTC (permalink / raw)
  To: linux-omap, linux-arm-kernel, linux-pwm
  Cc: t-kristo, grygorii.strashko, aaro.koskinen, tony, Keerthy,
	daniel.lezcano, robh+dt, narmstrong, thierry.reding,
	Brecht Neyrinck, sebastian.reichel, Thomas Gleixner,
	Claudiu.Beznea

Hi,

this patchset based on next-20180223 first cleans up playground (patches
1-4 which I'd appreciate to be reviewed and merged eventually) and then
adds event capture functionality which is just good for doing:
$ echo 0 > /sys/class/pwm/pwmchip4/export
$ cat /sys/class/pwm/pwmchip4/pwm0/capture 
1000000 500000
$ cat /sys/class/pwm/pwmchip4/pwm0/capture 
100000 50000
$ cat /sys/class/pwm/pwmchip4/pwm0/capture 
100000 75000

Above measured frequencies are 1kHz and 10kHz with 50% duty cycle,
the last one is with 75% duty cycle. However with 100kHz it sometimes
ends with:
$ cat /sys/class/pwm/pwmchip4/pwm0/capture 
omap_dm_timer_read_status: timer not available or enabled.
12462 6231

So locking is probably not done right, therefore patches 5 and 6 are sent
only for reference, as there's also another fundamental problem:

Hardware can be told to capture both edges, but there's no way to tell it
which one should be captured first. Other posibility would be first
configure for rising edge and reconfigure in interrupt for falling one.
Here we meet latency problem again:
https://www.spinics.net/lists/linux-omap/msg140081.html
Attached test patch shows average diff around 150us (sometimes over 300us)
which pretty much limits maximum measurable frequency.

I tried to misuse PM_QOS_CPU_DMA_LATENCY to overcome latency issue, but
with no luck.

Ladislav Michl (6):
  clocksource: timer-ti-dm: Make unexported functions static
  clocksource: timer-ti-dm: Consolidate set source
  clocksource: timer-ti-dm: Check prescaler value
  pwm: pwm-omap-dmtimer: Fix frequency when using prescaler
  clocksource: timer-ti-dm: Add event capture
  pwm: pwm-omap-dmtimer: Add capture functionality

 drivers/clocksource/timer-ti-dm.c          | 263 ++++++++++++++++-------------
 drivers/pwm/pwm-omap-dmtimer.c             | 220 +++++++++++++++++++-----
 include/clocksource/timer-ti-dm.h          |  33 ----
 include/linux/platform_data/dmtimer-omap.h |   8 +
 4 files changed, 340 insertions(+), 184 deletions(-)

Latency test patch:

diff --git a/drivers/pwm/pwm-omap-dmtimer.c b/drivers/pwm/pwm-omap-dmtimer.c
index 5a2fc0e0a1c5..c1a94740079a 100644
--- a/drivers/pwm/pwm-omap-dmtimer.c
+++ b/drivers/pwm/pwm-omap-dmtimer.c
@@ -46,7 +46,7 @@ struct pwm_omap_dmtimer_chip {
 	const struct omap_dm_timer_ops *pdata;
 	struct platform_device *dm_timer_pdev;
 	unsigned long freq;
-	unsigned int ev_cnt, overflow, width;
+	unsigned int ev_cnt, overflow, width, counter_irq, counter_captured;
 };
 
 static inline struct pwm_omap_dmtimer_chip *
@@ -280,6 +280,8 @@ static int pwm_omap_dmtimer_capture(struct pwm_chip *chip,
 		omap->ev_cnt = omap->width = 0;
 		spin_unlock_irqrestore(&omap->lock, flags);
 
+		printk("diff: %d\n", pwm_omap_dmtimer_ticks_to_ns(omap, omap->counter_irq - omap->counter_captured));
+
 		res = wait_event_interruptible_timeout(omap->wait,
 						       omap->width > 0,
 						       timeout);
@@ -317,6 +319,8 @@ static irqreturn_t pwm_omap_dmtimer_irq(int irq, void *dev_id)
 	if (l & OMAP_TIMER_INT_CAPTURE) {
 		if (!omap->width && omap->ev_cnt == 1) {
 			omap->pdata->read_capture(omap->dm_timer, &c1, &c2);
+			omap->counter_irq = omap->pdata->read_counter(omap->dm_timer);
+			omap->counter_captured = c2;
 			omap->width = pwm_omap_dmtimer_get_width(omap, c1, c2);
 			wake_up(&omap->wait);
 		}

-- 
2.16.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 0/6] Implement event capture for OMAP (draft)
@ 2018-02-23 10:12 ` Ladislav Michl
  0 siblings, 0 replies; 30+ messages in thread
From: Ladislav Michl @ 2018-02-23 10:12 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

this patchset based on next-20180223 first cleans up playground (patches
1-4 which I'd appreciate to be reviewed and merged eventually) and then
adds event capture functionality which is just good for doing:
$ echo 0 > /sys/class/pwm/pwmchip4/export
$ cat /sys/class/pwm/pwmchip4/pwm0/capture 
1000000 500000
$ cat /sys/class/pwm/pwmchip4/pwm0/capture 
100000 50000
$ cat /sys/class/pwm/pwmchip4/pwm0/capture 
100000 75000

Above measured frequencies are 1kHz and 10kHz with 50% duty cycle,
the last one is with 75% duty cycle. However with 100kHz it sometimes
ends with:
$ cat /sys/class/pwm/pwmchip4/pwm0/capture 
omap_dm_timer_read_status: timer not available or enabled.
12462 6231

So locking is probably not done right, therefore patches 5 and 6 are sent
only for reference, as there's also another fundamental problem:

Hardware can be told to capture both edges, but there's no way to tell it
which one should be captured first. Other posibility would be first
configure for rising edge and reconfigure in interrupt for falling one.
Here we meet latency problem again:
https://www.spinics.net/lists/linux-omap/msg140081.html
Attached test patch shows average diff around 150us (sometimes over 300us)
which pretty much limits maximum measurable frequency.

I tried to misuse PM_QOS_CPU_DMA_LATENCY to overcome latency issue, but
with no luck.

Ladislav Michl (6):
  clocksource: timer-ti-dm: Make unexported functions static
  clocksource: timer-ti-dm: Consolidate set source
  clocksource: timer-ti-dm: Check prescaler value
  pwm: pwm-omap-dmtimer: Fix frequency when using prescaler
  clocksource: timer-ti-dm: Add event capture
  pwm: pwm-omap-dmtimer: Add capture functionality

 drivers/clocksource/timer-ti-dm.c          | 263 ++++++++++++++++-------------
 drivers/pwm/pwm-omap-dmtimer.c             | 220 +++++++++++++++++++-----
 include/clocksource/timer-ti-dm.h          |  33 ----
 include/linux/platform_data/dmtimer-omap.h |   8 +
 4 files changed, 340 insertions(+), 184 deletions(-)

Latency test patch:

diff --git a/drivers/pwm/pwm-omap-dmtimer.c b/drivers/pwm/pwm-omap-dmtimer.c
index 5a2fc0e0a1c5..c1a94740079a 100644
--- a/drivers/pwm/pwm-omap-dmtimer.c
+++ b/drivers/pwm/pwm-omap-dmtimer.c
@@ -46,7 +46,7 @@ struct pwm_omap_dmtimer_chip {
 	const struct omap_dm_timer_ops *pdata;
 	struct platform_device *dm_timer_pdev;
 	unsigned long freq;
-	unsigned int ev_cnt, overflow, width;
+	unsigned int ev_cnt, overflow, width, counter_irq, counter_captured;
 };
 
 static inline struct pwm_omap_dmtimer_chip *
@@ -280,6 +280,8 @@ static int pwm_omap_dmtimer_capture(struct pwm_chip *chip,
 		omap->ev_cnt = omap->width = 0;
 		spin_unlock_irqrestore(&omap->lock, flags);
 
+		printk("diff: %d\n", pwm_omap_dmtimer_ticks_to_ns(omap, omap->counter_irq - omap->counter_captured));
+
 		res = wait_event_interruptible_timeout(omap->wait,
 						       omap->width > 0,
 						       timeout);
@@ -317,6 +319,8 @@ static irqreturn_t pwm_omap_dmtimer_irq(int irq, void *dev_id)
 	if (l & OMAP_TIMER_INT_CAPTURE) {
 		if (!omap->width && omap->ev_cnt == 1) {
 			omap->pdata->read_capture(omap->dm_timer, &c1, &c2);
+			omap->counter_irq = omap->pdata->read_counter(omap->dm_timer);
+			omap->counter_captured = c2;
 			omap->width = pwm_omap_dmtimer_get_width(omap, c1, c2);
 			wake_up(&omap->wait);
 		}

-- 
2.16.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 1/6] clocksource: timer-ti-dm: Make unexported functions static
  2018-02-23 10:12 ` Ladislav Michl
@ 2018-02-23 10:13   ` Ladislav Michl
  -1 siblings, 0 replies; 30+ messages in thread
From: Ladislav Michl @ 2018-02-23 10:13 UTC (permalink / raw)
  To: linux-omap, linux-arm-kernel, linux-pwm
  Cc: t-kristo, grygorii.strashko, aaro.koskinen, tony, Keerthy,
	daniel.lezcano, robh+dt, narmstrong, thierry.reding,
	Brecht Neyrinck, sebastian.reichel, Thomas Gleixner,
	Claudiu.Beznea

As dmtimer no longer exports functions, make those previously
exported static (this requires few functions to be moved around
as their prototypes were deleted).

Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
---
 drivers/clocksource/timer-ti-dm.c | 218 +++++++++++++++++++-------------------
 include/clocksource/timer-ti-dm.h |  33 ------
 2 files changed, 109 insertions(+), 142 deletions(-)

diff --git a/drivers/clocksource/timer-ti-dm.c b/drivers/clocksource/timer-ti-dm.c
index 70782a41c493..e4d75a8eaa91 100644
--- a/drivers/clocksource/timer-ti-dm.c
+++ b/drivers/clocksource/timer-ti-dm.c
@@ -163,6 +163,92 @@ static int omap_dm_timer_of_set_source(struct omap_dm_timer *timer)
 	return ret;
 }
 
+static int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
+{
+	int ret;
+	char *parent_name = NULL;
+	struct clk *parent;
+	struct dmtimer_platform_data *pdata;
+
+	if (unlikely(!timer))
+		return -EINVAL;
+
+	pdata = timer->pdev->dev.platform_data;
+
+	if (source < 0 || source >= 3)
+		return -EINVAL;
+
+	/*
+	 * FIXME: Used for OMAP1 devices only because they do not currently
+	 * use the clock framework to set the parent clock. To be removed
+	 * once OMAP1 migrated to using clock framework for dmtimers
+	 */
+	if (pdata && pdata->set_timer_src)
+		return pdata->set_timer_src(timer->pdev, source);
+
+	if (IS_ERR(timer->fclk))
+		return -EINVAL;
+
+#if defined(CONFIG_COMMON_CLK)
+	/* Check if the clock has configurable parents */
+	if (clk_hw_get_num_parents(__clk_get_hw(timer->fclk)) < 2)
+		return 0;
+#endif
+
+	switch (source) {
+	case OMAP_TIMER_SRC_SYS_CLK:
+		parent_name = "timer_sys_ck";
+		break;
+
+	case OMAP_TIMER_SRC_32_KHZ:
+		parent_name = "timer_32k_ck";
+		break;
+
+	case OMAP_TIMER_SRC_EXT_CLK:
+		parent_name = "timer_ext_ck";
+		break;
+	}
+
+	parent = clk_get(&timer->pdev->dev, parent_name);
+	if (IS_ERR(parent)) {
+		pr_err("%s: %s not found\n", __func__, parent_name);
+		return -EINVAL;
+	}
+
+	ret = clk_set_parent(timer->fclk, parent);
+	if (ret < 0)
+		pr_err("%s: failed to set %s as parent\n", __func__,
+			parent_name);
+
+	clk_put(parent);
+
+	return ret;
+}
+
+static void omap_dm_timer_enable(struct omap_dm_timer *timer)
+{
+	int c;
+
+	pm_runtime_get_sync(&timer->pdev->dev);
+
+	if (!(timer->capability & OMAP_TIMER_ALWON)) {
+		if (timer->get_context_loss_count) {
+			c = timer->get_context_loss_count(&timer->pdev->dev);
+			if (c != timer->ctx_loss_count) {
+				omap_timer_restore_context(timer);
+				timer->ctx_loss_count = c;
+			}
+		} else {
+			omap_timer_restore_context(timer);
+		}
+	}
+}
+
+static void omap_dm_timer_disable(struct omap_dm_timer *timer)
+{
+	pm_runtime_put_sync(&timer->pdev->dev);
+}
+
 static int omap_dm_timer_prepare(struct omap_dm_timer *timer)
 {
 	int rc;
@@ -298,16 +384,16 @@ static struct omap_dm_timer *_omap_dm_timer_request(int req_type, void *data)
 	return timer;
 }
 
-struct omap_dm_timer *omap_dm_timer_request(void)
+static struct omap_dm_timer *omap_dm_timer_request(void)
 {
 	return _omap_dm_timer_request(REQUEST_ANY, NULL);
 }
 
-struct omap_dm_timer *omap_dm_timer_request_specific(int id)
+static struct omap_dm_timer *omap_dm_timer_request_specific(int id)
 {
 	/* Requesting timer by ID is not supported when device tree is used */
 	if (of_have_populated_dt()) {
-		pr_warn("%s: Please use omap_dm_timer_request_by_cap/node()\n",
+		pr_warn("%s: Please use omap_dm_timer_request_by_node()\n",
 			__func__);
 		return NULL;
 	}
@@ -336,7 +422,7 @@ struct omap_dm_timer *omap_dm_timer_request_by_cap(u32 cap)
  * Request a timer based upon a device node pointer. Returns pointer to
  * timer handle on success and a NULL pointer on failure.
  */
-struct omap_dm_timer *omap_dm_timer_request_by_node(struct device_node *np)
+static struct omap_dm_timer *omap_dm_timer_request_by_node(struct device_node *np)
 {
 	if (!np)
 		return NULL;
@@ -344,7 +430,7 @@ struct omap_dm_timer *omap_dm_timer_request_by_node(struct device_node *np)
 	return _omap_dm_timer_request(REQUEST_BY_NODE, np);
 }
 
-int omap_dm_timer_free(struct omap_dm_timer *timer)
+static int omap_dm_timer_free(struct omap_dm_timer *timer)
 {
 	if (unlikely(!timer))
 		return -EINVAL;
@@ -356,30 +442,6 @@ int omap_dm_timer_free(struct omap_dm_timer *timer)
 	return 0;
 }
 
-void omap_dm_timer_enable(struct omap_dm_timer *timer)
-{
-	int c;
-
-	pm_runtime_get_sync(&timer->pdev->dev);
-
-	if (!(timer->capability & OMAP_TIMER_ALWON)) {
-		if (timer->get_context_loss_count) {
-			c = timer->get_context_loss_count(&timer->pdev->dev);
-			if (c != timer->ctx_loss_count) {
-				omap_timer_restore_context(timer);
-				timer->ctx_loss_count = c;
-			}
-		} else {
-			omap_timer_restore_context(timer);
-		}
-	}
-}
-
-void omap_dm_timer_disable(struct omap_dm_timer *timer)
-{
-	pm_runtime_put_sync(&timer->pdev->dev);
-}
-
 int omap_dm_timer_get_irq(struct omap_dm_timer *timer)
 {
 	if (timer)
@@ -424,7 +486,7 @@ __u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask)
 
 #else
 
-struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer)
+static struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer)
 {
 	if (timer && !IS_ERR(timer->fclk))
 		return timer->fclk;
@@ -451,7 +513,7 @@ int omap_dm_timer_trigger(struct omap_dm_timer *timer)
 	return 0;
 }
 
-int omap_dm_timer_start(struct omap_dm_timer *timer)
+static int omap_dm_timer_start(struct omap_dm_timer *timer)
 {
 	u32 l;
 
@@ -471,7 +533,7 @@ int omap_dm_timer_start(struct omap_dm_timer *timer)
 	return 0;
 }
 
-int omap_dm_timer_stop(struct omap_dm_timer *timer)
+static int omap_dm_timer_stop(struct omap_dm_timer *timer)
 {
 	unsigned long rate = 0;
 
@@ -494,70 +556,8 @@ int omap_dm_timer_stop(struct omap_dm_timer *timer)
 	return 0;
 }
 
-int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
-{
-	int ret;
-	char *parent_name = NULL;
-	struct clk *parent;
-	struct dmtimer_platform_data *pdata;
-
-	if (unlikely(!timer))
-		return -EINVAL;
-
-	pdata = timer->pdev->dev.platform_data;
-
-	if (source < 0 || source >= 3)
-		return -EINVAL;
-
-	/*
-	 * FIXME: Used for OMAP1 devices only because they do not currently
-	 * use the clock framework to set the parent clock. To be removed
-	 * once OMAP1 migrated to using clock framework for dmtimers
-	 */
-	if (pdata && pdata->set_timer_src)
-		return pdata->set_timer_src(timer->pdev, source);
-
-	if (IS_ERR(timer->fclk))
-		return -EINVAL;
-
-#if defined(CONFIG_COMMON_CLK)
-	/* Check if the clock has configurable parents */
-	if (clk_hw_get_num_parents(__clk_get_hw(timer->fclk)) < 2)
-		return 0;
-#endif
-
-	switch (source) {
-	case OMAP_TIMER_SRC_SYS_CLK:
-		parent_name = "timer_sys_ck";
-		break;
-
-	case OMAP_TIMER_SRC_32_KHZ:
-		parent_name = "timer_32k_ck";
-		break;
-
-	case OMAP_TIMER_SRC_EXT_CLK:
-		parent_name = "timer_ext_ck";
-		break;
-	}
-
-	parent = clk_get(&timer->pdev->dev, parent_name);
-	if (IS_ERR(parent)) {
-		pr_err("%s: %s not found\n", __func__, parent_name);
-		return -EINVAL;
-	}
-
-	ret = clk_set_parent(timer->fclk, parent);
-	if (ret < 0)
-		pr_err("%s: failed to set %s as parent\n", __func__,
-			parent_name);
-
-	clk_put(parent);
-
-	return ret;
-}
-
-int omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload,
-			    unsigned int load)
+static int omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload,
+				  unsigned int load)
 {
 	u32 l;
 
@@ -609,9 +609,8 @@ int omap_dm_timer_set_load_start(struct omap_dm_timer *timer, int autoreload,
 	timer->context.tcrr = load;
 	return 0;
 }
-
-int omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable,
-			     unsigned int match)
+static int omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable,
+				   unsigned int match)
 {
 	u32 l;
 
@@ -634,8 +633,8 @@ int omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable,
 	return 0;
 }
 
-int omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on,
-			   int toggle, int trigger)
+static int omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on,
+				 int toggle, int trigger)
 {
 	u32 l;
 
@@ -659,7 +658,8 @@ int omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on,
 	return 0;
 }
 
-int omap_dm_timer_set_prescaler(struct omap_dm_timer *timer, int prescaler)
+static int omap_dm_timer_set_prescaler(struct omap_dm_timer *timer,
+					int prescaler)
 {
 	u32 l;
 
@@ -681,8 +681,8 @@ int omap_dm_timer_set_prescaler(struct omap_dm_timer *timer, int prescaler)
 	return 0;
 }
 
-int omap_dm_timer_set_int_enable(struct omap_dm_timer *timer,
-				  unsigned int value)
+static int omap_dm_timer_set_int_enable(struct omap_dm_timer *timer,
+					unsigned int value)
 {
 	if (unlikely(!timer))
 		return -EINVAL;
@@ -704,7 +704,7 @@ int omap_dm_timer_set_int_enable(struct omap_dm_timer *timer,
  *
  * Disables the specified timer interrupts for a timer.
  */
-int omap_dm_timer_set_int_disable(struct omap_dm_timer *timer, u32 mask)
+static int omap_dm_timer_set_int_disable(struct omap_dm_timer *timer, u32 mask)
 {
 	u32 l = mask;
 
@@ -727,7 +727,7 @@ int omap_dm_timer_set_int_disable(struct omap_dm_timer *timer, u32 mask)
 	return 0;
 }
 
-unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer)
+static unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer)
 {
 	unsigned int l;
 
@@ -741,7 +741,7 @@ unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer)
 	return l;
 }
 
-int omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value)
+static int omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value)
 {
 	if (unlikely(!timer || pm_runtime_suspended(&timer->pdev->dev)))
 		return -EINVAL;
@@ -751,7 +751,7 @@ int omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value)
 	return 0;
 }
 
-unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer)
+static unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer)
 {
 	if (unlikely(!timer || pm_runtime_suspended(&timer->pdev->dev))) {
 		pr_err("%s: timer not iavailable or enabled.\n", __func__);
@@ -761,7 +761,7 @@ unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer)
 	return __omap_dm_timer_read_counter(timer, timer->posted);
 }
 
-int omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value)
+static int omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value)
 {
 	if (unlikely(!timer || pm_runtime_suspended(&timer->pdev->dev))) {
 		pr_err("%s: timer not available or enabled.\n", __func__);
diff --git a/include/clocksource/timer-ti-dm.h b/include/clocksource/timer-ti-dm.h
index 4f310957c21b..7d9598dc578d 100644
--- a/include/clocksource/timer-ti-dm.h
+++ b/include/clocksource/timer-ti-dm.h
@@ -119,46 +119,13 @@ struct omap_dm_timer {
 };
 
 int omap_dm_timer_reserve_systimer(int id);
-struct omap_dm_timer *omap_dm_timer_request(void);
-struct omap_dm_timer *omap_dm_timer_request_specific(int timer_id);
 struct omap_dm_timer *omap_dm_timer_request_by_cap(u32 cap);
-struct omap_dm_timer *omap_dm_timer_request_by_node(struct device_node *np);
-int omap_dm_timer_free(struct omap_dm_timer *timer);
-void omap_dm_timer_enable(struct omap_dm_timer *timer);
-void omap_dm_timer_disable(struct omap_dm_timer *timer);
 
 int omap_dm_timer_get_irq(struct omap_dm_timer *timer);
 
 u32 omap_dm_timer_modify_idlect_mask(u32 inputmask);
 
-#ifndef CONFIG_ARCH_OMAP1
-struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer);
-#else
-static inline
-struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer)
-{
-	return NULL;
-}
-#endif
-
 int omap_dm_timer_trigger(struct omap_dm_timer *timer);
-int omap_dm_timer_start(struct omap_dm_timer *timer);
-int omap_dm_timer_stop(struct omap_dm_timer *timer);
-
-int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source);
-int omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload, unsigned int value);
-int omap_dm_timer_set_load_start(struct omap_dm_timer *timer, int autoreload, unsigned int value);
-int omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable, unsigned int match);
-int omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on, int toggle, int trigger);
-int omap_dm_timer_set_prescaler(struct omap_dm_timer *timer, int prescaler);
-
-int omap_dm_timer_set_int_enable(struct omap_dm_timer *timer, unsigned int value);
-int omap_dm_timer_set_int_disable(struct omap_dm_timer *timer, u32 mask);
-
-unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer);
-int omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value);
-unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer);
-int omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value);
 
 int omap_dm_timers_active(void);
 
-- 
2.16.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 1/6] clocksource: timer-ti-dm: Make unexported functions static
@ 2018-02-23 10:13   ` Ladislav Michl
  0 siblings, 0 replies; 30+ messages in thread
From: Ladislav Michl @ 2018-02-23 10:13 UTC (permalink / raw)
  To: linux-arm-kernel

As dmtimer no longer exports functions, make those previously
exported static (this requires few functions to be moved around
as their prototypes were deleted).

Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
---
 drivers/clocksource/timer-ti-dm.c | 218 +++++++++++++++++++-------------------
 include/clocksource/timer-ti-dm.h |  33 ------
 2 files changed, 109 insertions(+), 142 deletions(-)

diff --git a/drivers/clocksource/timer-ti-dm.c b/drivers/clocksource/timer-ti-dm.c
index 70782a41c493..e4d75a8eaa91 100644
--- a/drivers/clocksource/timer-ti-dm.c
+++ b/drivers/clocksource/timer-ti-dm.c
@@ -163,6 +163,92 @@ static int omap_dm_timer_of_set_source(struct omap_dm_timer *timer)
 	return ret;
 }
 
+static int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
+{
+	int ret;
+	char *parent_name = NULL;
+	struct clk *parent;
+	struct dmtimer_platform_data *pdata;
+
+	if (unlikely(!timer))
+		return -EINVAL;
+
+	pdata = timer->pdev->dev.platform_data;
+
+	if (source < 0 || source >= 3)
+		return -EINVAL;
+
+	/*
+	 * FIXME: Used for OMAP1 devices only because they do not currently
+	 * use the clock framework to set the parent clock. To be removed
+	 * once OMAP1 migrated to using clock framework for dmtimers
+	 */
+	if (pdata && pdata->set_timer_src)
+		return pdata->set_timer_src(timer->pdev, source);
+
+	if (IS_ERR(timer->fclk))
+		return -EINVAL;
+
+#if defined(CONFIG_COMMON_CLK)
+	/* Check if the clock has configurable parents */
+	if (clk_hw_get_num_parents(__clk_get_hw(timer->fclk)) < 2)
+		return 0;
+#endif
+
+	switch (source) {
+	case OMAP_TIMER_SRC_SYS_CLK:
+		parent_name = "timer_sys_ck";
+		break;
+
+	case OMAP_TIMER_SRC_32_KHZ:
+		parent_name = "timer_32k_ck";
+		break;
+
+	case OMAP_TIMER_SRC_EXT_CLK:
+		parent_name = "timer_ext_ck";
+		break;
+	}
+
+	parent = clk_get(&timer->pdev->dev, parent_name);
+	if (IS_ERR(parent)) {
+		pr_err("%s: %s not found\n", __func__, parent_name);
+		return -EINVAL;
+	}
+
+	ret = clk_set_parent(timer->fclk, parent);
+	if (ret < 0)
+		pr_err("%s: failed to set %s as parent\n", __func__,
+			parent_name);
+
+	clk_put(parent);
+
+	return ret;
+}
+
+static void omap_dm_timer_enable(struct omap_dm_timer *timer)
+{
+	int c;
+
+	pm_runtime_get_sync(&timer->pdev->dev);
+
+	if (!(timer->capability & OMAP_TIMER_ALWON)) {
+		if (timer->get_context_loss_count) {
+			c = timer->get_context_loss_count(&timer->pdev->dev);
+			if (c != timer->ctx_loss_count) {
+				omap_timer_restore_context(timer);
+				timer->ctx_loss_count = c;
+			}
+		} else {
+			omap_timer_restore_context(timer);
+		}
+	}
+}
+
+static void omap_dm_timer_disable(struct omap_dm_timer *timer)
+{
+	pm_runtime_put_sync(&timer->pdev->dev);
+}
+
 static int omap_dm_timer_prepare(struct omap_dm_timer *timer)
 {
 	int rc;
@@ -298,16 +384,16 @@ static struct omap_dm_timer *_omap_dm_timer_request(int req_type, void *data)
 	return timer;
 }
 
-struct omap_dm_timer *omap_dm_timer_request(void)
+static struct omap_dm_timer *omap_dm_timer_request(void)
 {
 	return _omap_dm_timer_request(REQUEST_ANY, NULL);
 }
 
-struct omap_dm_timer *omap_dm_timer_request_specific(int id)
+static struct omap_dm_timer *omap_dm_timer_request_specific(int id)
 {
 	/* Requesting timer by ID is not supported when device tree is used */
 	if (of_have_populated_dt()) {
-		pr_warn("%s: Please use omap_dm_timer_request_by_cap/node()\n",
+		pr_warn("%s: Please use omap_dm_timer_request_by_node()\n",
 			__func__);
 		return NULL;
 	}
@@ -336,7 +422,7 @@ struct omap_dm_timer *omap_dm_timer_request_by_cap(u32 cap)
  * Request a timer based upon a device node pointer. Returns pointer to
  * timer handle on success and a NULL pointer on failure.
  */
-struct omap_dm_timer *omap_dm_timer_request_by_node(struct device_node *np)
+static struct omap_dm_timer *omap_dm_timer_request_by_node(struct device_node *np)
 {
 	if (!np)
 		return NULL;
@@ -344,7 +430,7 @@ struct omap_dm_timer *omap_dm_timer_request_by_node(struct device_node *np)
 	return _omap_dm_timer_request(REQUEST_BY_NODE, np);
 }
 
-int omap_dm_timer_free(struct omap_dm_timer *timer)
+static int omap_dm_timer_free(struct omap_dm_timer *timer)
 {
 	if (unlikely(!timer))
 		return -EINVAL;
@@ -356,30 +442,6 @@ int omap_dm_timer_free(struct omap_dm_timer *timer)
 	return 0;
 }
 
-void omap_dm_timer_enable(struct omap_dm_timer *timer)
-{
-	int c;
-
-	pm_runtime_get_sync(&timer->pdev->dev);
-
-	if (!(timer->capability & OMAP_TIMER_ALWON)) {
-		if (timer->get_context_loss_count) {
-			c = timer->get_context_loss_count(&timer->pdev->dev);
-			if (c != timer->ctx_loss_count) {
-				omap_timer_restore_context(timer);
-				timer->ctx_loss_count = c;
-			}
-		} else {
-			omap_timer_restore_context(timer);
-		}
-	}
-}
-
-void omap_dm_timer_disable(struct omap_dm_timer *timer)
-{
-	pm_runtime_put_sync(&timer->pdev->dev);
-}
-
 int omap_dm_timer_get_irq(struct omap_dm_timer *timer)
 {
 	if (timer)
@@ -424,7 +486,7 @@ __u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask)
 
 #else
 
-struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer)
+static struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer)
 {
 	if (timer && !IS_ERR(timer->fclk))
 		return timer->fclk;
@@ -451,7 +513,7 @@ int omap_dm_timer_trigger(struct omap_dm_timer *timer)
 	return 0;
 }
 
-int omap_dm_timer_start(struct omap_dm_timer *timer)
+static int omap_dm_timer_start(struct omap_dm_timer *timer)
 {
 	u32 l;
 
@@ -471,7 +533,7 @@ int omap_dm_timer_start(struct omap_dm_timer *timer)
 	return 0;
 }
 
-int omap_dm_timer_stop(struct omap_dm_timer *timer)
+static int omap_dm_timer_stop(struct omap_dm_timer *timer)
 {
 	unsigned long rate = 0;
 
@@ -494,70 +556,8 @@ int omap_dm_timer_stop(struct omap_dm_timer *timer)
 	return 0;
 }
 
-int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
-{
-	int ret;
-	char *parent_name = NULL;
-	struct clk *parent;
-	struct dmtimer_platform_data *pdata;
-
-	if (unlikely(!timer))
-		return -EINVAL;
-
-	pdata = timer->pdev->dev.platform_data;
-
-	if (source < 0 || source >= 3)
-		return -EINVAL;
-
-	/*
-	 * FIXME: Used for OMAP1 devices only because they do not currently
-	 * use the clock framework to set the parent clock. To be removed
-	 * once OMAP1 migrated to using clock framework for dmtimers
-	 */
-	if (pdata && pdata->set_timer_src)
-		return pdata->set_timer_src(timer->pdev, source);
-
-	if (IS_ERR(timer->fclk))
-		return -EINVAL;
-
-#if defined(CONFIG_COMMON_CLK)
-	/* Check if the clock has configurable parents */
-	if (clk_hw_get_num_parents(__clk_get_hw(timer->fclk)) < 2)
-		return 0;
-#endif
-
-	switch (source) {
-	case OMAP_TIMER_SRC_SYS_CLK:
-		parent_name = "timer_sys_ck";
-		break;
-
-	case OMAP_TIMER_SRC_32_KHZ:
-		parent_name = "timer_32k_ck";
-		break;
-
-	case OMAP_TIMER_SRC_EXT_CLK:
-		parent_name = "timer_ext_ck";
-		break;
-	}
-
-	parent = clk_get(&timer->pdev->dev, parent_name);
-	if (IS_ERR(parent)) {
-		pr_err("%s: %s not found\n", __func__, parent_name);
-		return -EINVAL;
-	}
-
-	ret = clk_set_parent(timer->fclk, parent);
-	if (ret < 0)
-		pr_err("%s: failed to set %s as parent\n", __func__,
-			parent_name);
-
-	clk_put(parent);
-
-	return ret;
-}
-
-int omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload,
-			    unsigned int load)
+static int omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload,
+				  unsigned int load)
 {
 	u32 l;
 
@@ -609,9 +609,8 @@ int omap_dm_timer_set_load_start(struct omap_dm_timer *timer, int autoreload,
 	timer->context.tcrr = load;
 	return 0;
 }
-
-int omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable,
-			     unsigned int match)
+static int omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable,
+				   unsigned int match)
 {
 	u32 l;
 
@@ -634,8 +633,8 @@ int omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable,
 	return 0;
 }
 
-int omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on,
-			   int toggle, int trigger)
+static int omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on,
+				 int toggle, int trigger)
 {
 	u32 l;
 
@@ -659,7 +658,8 @@ int omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on,
 	return 0;
 }
 
-int omap_dm_timer_set_prescaler(struct omap_dm_timer *timer, int prescaler)
+static int omap_dm_timer_set_prescaler(struct omap_dm_timer *timer,
+					int prescaler)
 {
 	u32 l;
 
@@ -681,8 +681,8 @@ int omap_dm_timer_set_prescaler(struct omap_dm_timer *timer, int prescaler)
 	return 0;
 }
 
-int omap_dm_timer_set_int_enable(struct omap_dm_timer *timer,
-				  unsigned int value)
+static int omap_dm_timer_set_int_enable(struct omap_dm_timer *timer,
+					unsigned int value)
 {
 	if (unlikely(!timer))
 		return -EINVAL;
@@ -704,7 +704,7 @@ int omap_dm_timer_set_int_enable(struct omap_dm_timer *timer,
  *
  * Disables the specified timer interrupts for a timer.
  */
-int omap_dm_timer_set_int_disable(struct omap_dm_timer *timer, u32 mask)
+static int omap_dm_timer_set_int_disable(struct omap_dm_timer *timer, u32 mask)
 {
 	u32 l = mask;
 
@@ -727,7 +727,7 @@ int omap_dm_timer_set_int_disable(struct omap_dm_timer *timer, u32 mask)
 	return 0;
 }
 
-unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer)
+static unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer)
 {
 	unsigned int l;
 
@@ -741,7 +741,7 @@ unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer)
 	return l;
 }
 
-int omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value)
+static int omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value)
 {
 	if (unlikely(!timer || pm_runtime_suspended(&timer->pdev->dev)))
 		return -EINVAL;
@@ -751,7 +751,7 @@ int omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value)
 	return 0;
 }
 
-unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer)
+static unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer)
 {
 	if (unlikely(!timer || pm_runtime_suspended(&timer->pdev->dev))) {
 		pr_err("%s: timer not iavailable or enabled.\n", __func__);
@@ -761,7 +761,7 @@ unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer)
 	return __omap_dm_timer_read_counter(timer, timer->posted);
 }
 
-int omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value)
+static int omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value)
 {
 	if (unlikely(!timer || pm_runtime_suspended(&timer->pdev->dev))) {
 		pr_err("%s: timer not available or enabled.\n", __func__);
diff --git a/include/clocksource/timer-ti-dm.h b/include/clocksource/timer-ti-dm.h
index 4f310957c21b..7d9598dc578d 100644
--- a/include/clocksource/timer-ti-dm.h
+++ b/include/clocksource/timer-ti-dm.h
@@ -119,46 +119,13 @@ struct omap_dm_timer {
 };
 
 int omap_dm_timer_reserve_systimer(int id);
-struct omap_dm_timer *omap_dm_timer_request(void);
-struct omap_dm_timer *omap_dm_timer_request_specific(int timer_id);
 struct omap_dm_timer *omap_dm_timer_request_by_cap(u32 cap);
-struct omap_dm_timer *omap_dm_timer_request_by_node(struct device_node *np);
-int omap_dm_timer_free(struct omap_dm_timer *timer);
-void omap_dm_timer_enable(struct omap_dm_timer *timer);
-void omap_dm_timer_disable(struct omap_dm_timer *timer);
 
 int omap_dm_timer_get_irq(struct omap_dm_timer *timer);
 
 u32 omap_dm_timer_modify_idlect_mask(u32 inputmask);
 
-#ifndef CONFIG_ARCH_OMAP1
-struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer);
-#else
-static inline
-struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer)
-{
-	return NULL;
-}
-#endif
-
 int omap_dm_timer_trigger(struct omap_dm_timer *timer);
-int omap_dm_timer_start(struct omap_dm_timer *timer);
-int omap_dm_timer_stop(struct omap_dm_timer *timer);
-
-int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source);
-int omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload, unsigned int value);
-int omap_dm_timer_set_load_start(struct omap_dm_timer *timer, int autoreload, unsigned int value);
-int omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable, unsigned int match);
-int omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on, int toggle, int trigger);
-int omap_dm_timer_set_prescaler(struct omap_dm_timer *timer, int prescaler);
-
-int omap_dm_timer_set_int_enable(struct omap_dm_timer *timer, unsigned int value);
-int omap_dm_timer_set_int_disable(struct omap_dm_timer *timer, u32 mask);
-
-unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer);
-int omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value);
-unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer);
-int omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value);
 
 int omap_dm_timers_active(void);
 
-- 
2.16.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 2/6] clocksource: timer-ti-dm: Consolidate set source
  2018-02-23 10:12 ` Ladislav Michl
@ 2018-02-23 10:14   ` Ladislav Michl
  -1 siblings, 0 replies; 30+ messages in thread
From: Ladislav Michl @ 2018-02-23 10:14 UTC (permalink / raw)
  To: linux-omap, linux-arm-kernel, linux-pwm
  Cc: t-kristo, grygorii.strashko, aaro.koskinen, tony, Keerthy,
	daniel.lezcano, robh+dt, narmstrong, thierry.reding,
	Brecht Neyrinck, sebastian.reichel, Thomas Gleixner,
	Claudiu.Beznea

Reorder omap_dm_timer_set_source internals to get
source verification more straightforward.

Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
---
 drivers/clocksource/timer-ti-dm.c | 38 ++++++++++++++++----------------------
 1 file changed, 16 insertions(+), 22 deletions(-)

diff --git a/drivers/clocksource/timer-ti-dm.c b/drivers/clocksource/timer-ti-dm.c
index e4d75a8eaa91..4d645d6c6c31 100644
--- a/drivers/clocksource/timer-ti-dm.c
+++ b/drivers/clocksource/timer-ti-dm.c
@@ -166,17 +166,28 @@ static int omap_dm_timer_of_set_source(struct omap_dm_timer *timer)
 static int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
 {
 	int ret;
-	char *parent_name = NULL;
+	const char *parent_name;
 	struct clk *parent;
 	struct dmtimer_platform_data *pdata;
 
-	if (unlikely(!timer))
+	if (unlikely(!timer) || IS_ERR(timer->fclk))
 		return -EINVAL;
 
-	pdata = timer->pdev->dev.platform_data;
-
-	if (source < 0 || source >= 3)
+	switch (source) {
+	case OMAP_TIMER_SRC_SYS_CLK:
+		parent_name = "timer_sys_ck";
+		break;
+	case OMAP_TIMER_SRC_32_KHZ:
+		parent_name = "timer_32k_ck";
+		break;
+	case OMAP_TIMER_SRC_EXT_CLK:
+		parent_name = "timer_ext_ck";
+		break;
+	default:
 		return -EINVAL;
+	}
+
+	pdata = timer->pdev->dev.platform_data;
 
 	/*
 	 * FIXME: Used for OMAP1 devices only because they do not currently
@@ -186,29 +197,12 @@ static int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
 	if (pdata && pdata->set_timer_src)
 		return pdata->set_timer_src(timer->pdev, source);
 
-	if (IS_ERR(timer->fclk))
-		return -EINVAL;
-
 #if defined(CONFIG_COMMON_CLK)
 	/* Check if the clock has configurable parents */
 	if (clk_hw_get_num_parents(__clk_get_hw(timer->fclk)) < 2)
 		return 0;
 #endif
 
-	switch (source) {
-	case OMAP_TIMER_SRC_SYS_CLK:
-		parent_name = "timer_sys_ck";
-		break;
-
-	case OMAP_TIMER_SRC_32_KHZ:
-		parent_name = "timer_32k_ck";
-		break;
-
-	case OMAP_TIMER_SRC_EXT_CLK:
-		parent_name = "timer_ext_ck";
-		break;
-	}
-
 	parent = clk_get(&timer->pdev->dev, parent_name);
 	if (IS_ERR(parent)) {
 		pr_err("%s: %s not found\n", __func__, parent_name);
-- 
2.16.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 2/6] clocksource: timer-ti-dm: Consolidate set source
@ 2018-02-23 10:14   ` Ladislav Michl
  0 siblings, 0 replies; 30+ messages in thread
From: Ladislav Michl @ 2018-02-23 10:14 UTC (permalink / raw)
  To: linux-arm-kernel

Reorder omap_dm_timer_set_source internals to get
source verification more straightforward.

Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
---
 drivers/clocksource/timer-ti-dm.c | 38 ++++++++++++++++----------------------
 1 file changed, 16 insertions(+), 22 deletions(-)

diff --git a/drivers/clocksource/timer-ti-dm.c b/drivers/clocksource/timer-ti-dm.c
index e4d75a8eaa91..4d645d6c6c31 100644
--- a/drivers/clocksource/timer-ti-dm.c
+++ b/drivers/clocksource/timer-ti-dm.c
@@ -166,17 +166,28 @@ static int omap_dm_timer_of_set_source(struct omap_dm_timer *timer)
 static int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
 {
 	int ret;
-	char *parent_name = NULL;
+	const char *parent_name;
 	struct clk *parent;
 	struct dmtimer_platform_data *pdata;
 
-	if (unlikely(!timer))
+	if (unlikely(!timer) || IS_ERR(timer->fclk))
 		return -EINVAL;
 
-	pdata = timer->pdev->dev.platform_data;
-
-	if (source < 0 || source >= 3)
+	switch (source) {
+	case OMAP_TIMER_SRC_SYS_CLK:
+		parent_name = "timer_sys_ck";
+		break;
+	case OMAP_TIMER_SRC_32_KHZ:
+		parent_name = "timer_32k_ck";
+		break;
+	case OMAP_TIMER_SRC_EXT_CLK:
+		parent_name = "timer_ext_ck";
+		break;
+	default:
 		return -EINVAL;
+	}
+
+	pdata = timer->pdev->dev.platform_data;
 
 	/*
 	 * FIXME: Used for OMAP1 devices only because they do not currently
@@ -186,29 +197,12 @@ static int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
 	if (pdata && pdata->set_timer_src)
 		return pdata->set_timer_src(timer->pdev, source);
 
-	if (IS_ERR(timer->fclk))
-		return -EINVAL;
-
 #if defined(CONFIG_COMMON_CLK)
 	/* Check if the clock has configurable parents */
 	if (clk_hw_get_num_parents(__clk_get_hw(timer->fclk)) < 2)
 		return 0;
 #endif
 
-	switch (source) {
-	case OMAP_TIMER_SRC_SYS_CLK:
-		parent_name = "timer_sys_ck";
-		break;
-
-	case OMAP_TIMER_SRC_32_KHZ:
-		parent_name = "timer_32k_ck";
-		break;
-
-	case OMAP_TIMER_SRC_EXT_CLK:
-		parent_name = "timer_ext_ck";
-		break;
-	}
-
 	parent = clk_get(&timer->pdev->dev, parent_name);
 	if (IS_ERR(parent)) {
 		pr_err("%s: %s not found\n", __func__, parent_name);
-- 
2.16.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 3/6] clocksource: timer-ti-dm: Check prescaler value
  2018-02-23 10:12 ` Ladislav Michl
@ 2018-02-23 10:15   ` Ladislav Michl
  -1 siblings, 0 replies; 30+ messages in thread
From: Ladislav Michl @ 2018-02-23 10:15 UTC (permalink / raw)
  To: linux-omap, linux-arm-kernel, linux-pwm
  Cc: t-kristo, grygorii.strashko, aaro.koskinen, tony, Keerthy,
	daniel.lezcano, robh+dt, narmstrong, thierry.reding,
	Brecht Neyrinck, sebastian.reichel, Thomas Gleixner,
	Claudiu.Beznea

Invalid value silently disables use of the prescaler.
Use -1 explicitely for that purpose and error out on
invalid value.

Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
---
 drivers/clocksource/timer-ti-dm.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/clocksource/timer-ti-dm.c b/drivers/clocksource/timer-ti-dm.c
index 4d645d6c6c31..b57e875b74ca 100644
--- a/drivers/clocksource/timer-ti-dm.c
+++ b/drivers/clocksource/timer-ti-dm.c
@@ -657,13 +657,13 @@ static int omap_dm_timer_set_prescaler(struct omap_dm_timer *timer,
 {
 	u32 l;
 
-	if (unlikely(!timer))
+	if (unlikely(!timer) || prescaler < -1 || prescaler > 7)
 		return -EINVAL;
 
 	omap_dm_timer_enable(timer);
 	l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
 	l &= ~(OMAP_TIMER_CTRL_PRE | (0x07 << 2));
-	if (prescaler >= 0x00 && prescaler <= 0x07) {
+	if (prescaler >= 0) {
 		l |= OMAP_TIMER_CTRL_PRE;
 		l |= prescaler << 2;
 	}
-- 
2.16.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 3/6] clocksource: timer-ti-dm: Check prescaler value
@ 2018-02-23 10:15   ` Ladislav Michl
  0 siblings, 0 replies; 30+ messages in thread
From: Ladislav Michl @ 2018-02-23 10:15 UTC (permalink / raw)
  To: linux-arm-kernel

Invalid value silently disables use of the prescaler.
Use -1 explicitely for that purpose and error out on
invalid value.

Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
---
 drivers/clocksource/timer-ti-dm.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/clocksource/timer-ti-dm.c b/drivers/clocksource/timer-ti-dm.c
index 4d645d6c6c31..b57e875b74ca 100644
--- a/drivers/clocksource/timer-ti-dm.c
+++ b/drivers/clocksource/timer-ti-dm.c
@@ -657,13 +657,13 @@ static int omap_dm_timer_set_prescaler(struct omap_dm_timer *timer,
 {
 	u32 l;
 
-	if (unlikely(!timer))
+	if (unlikely(!timer) || prescaler < -1 || prescaler > 7)
 		return -EINVAL;
 
 	omap_dm_timer_enable(timer);
 	l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
 	l &= ~(OMAP_TIMER_CTRL_PRE | (0x07 << 2));
-	if (prescaler >= 0x00 && prescaler <= 0x07) {
+	if (prescaler >= 0) {
 		l |= OMAP_TIMER_CTRL_PRE;
 		l |= prescaler << 2;
 	}
-- 
2.16.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 4/6] pwm: pwm-omap-dmtimer: Fix frequency when using prescaler
  2018-02-23 10:12 ` Ladislav Michl
@ 2018-02-23 10:15   ` Ladislav Michl
  -1 siblings, 0 replies; 30+ messages in thread
From: Ladislav Michl @ 2018-02-23 10:15 UTC (permalink / raw)
  To: linux-omap, linux-arm-kernel, linux-pwm
  Cc: t-kristo, grygorii.strashko, aaro.koskinen, tony, Keerthy,
	daniel.lezcano, robh+dt, narmstrong, thierry.reding,
	Brecht Neyrinck, sebastian.reichel, Thomas Gleixner,
	Claudiu.Beznea

Prescaler setting is currently not taken into account.
Fix that by introducing freq member variable and initialize
it at device probe time. This also avoids frequency
recomputing at each pwm configure time.

Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
---
 drivers/pwm/pwm-omap-dmtimer.c | 93 +++++++++++++++++++++++++-----------------
 1 file changed, 55 insertions(+), 38 deletions(-)

diff --git a/drivers/pwm/pwm-omap-dmtimer.c b/drivers/pwm/pwm-omap-dmtimer.c
index 665da3c8fbce..48342285c953 100644
--- a/drivers/pwm/pwm-omap-dmtimer.c
+++ b/drivers/pwm/pwm-omap-dmtimer.c
@@ -40,6 +40,7 @@ struct pwm_omap_dmtimer_chip {
 	pwm_omap_dmtimer *dm_timer;
 	const struct omap_dm_timer_ops *pdata;
 	struct platform_device *dm_timer_pdev;
+	unsigned long freq;
 };
 
 static inline struct pwm_omap_dmtimer_chip *
@@ -48,9 +49,10 @@ to_pwm_omap_dmtimer_chip(struct pwm_chip *chip)
 	return container_of(chip, struct pwm_omap_dmtimer_chip, chip);
 }
 
-static u32 pwm_omap_dmtimer_get_clock_cycles(unsigned long clk_rate, int ns)
+static inline u32
+pwm_omap_dmtimer_get_clock_cycles(struct pwm_omap_dmtimer_chip *omap, int ns)
 {
-	return DIV_ROUND_CLOSEST_ULL((u64)clk_rate * ns, NSEC_PER_SEC);
+	return DIV_ROUND_CLOSEST_ULL((u64)omap->freq * ns, NSEC_PER_SEC);
 }
 
 static void pwm_omap_dmtimer_start(struct pwm_omap_dmtimer_chip *omap)
@@ -99,8 +101,6 @@ static int pwm_omap_dmtimer_config(struct pwm_chip *chip,
 	struct pwm_omap_dmtimer_chip *omap = to_pwm_omap_dmtimer_chip(chip);
 	u32 period_cycles, duty_cycles;
 	u32 load_value, match_value;
-	struct clk *fclk;
-	unsigned long clk_rate;
 	bool timer_active;
 
 	dev_dbg(chip->dev, "requested duty cycle: %d ns, period: %d ns\n",
@@ -114,19 +114,6 @@ static int pwm_omap_dmtimer_config(struct pwm_chip *chip,
 		return 0;
 	}
 
-	fclk = omap->pdata->get_fclk(omap->dm_timer);
-	if (!fclk) {
-		dev_err(chip->dev, "invalid pmtimer fclk\n");
-		goto err_einval;
-	}
-
-	clk_rate = clk_get_rate(fclk);
-	if (!clk_rate) {
-		dev_err(chip->dev, "invalid pmtimer fclk rate\n");
-		goto err_einval;
-	}
-
-	dev_dbg(chip->dev, "clk rate: %luHz\n", clk_rate);
 
 	/*
 	 * Calculate the appropriate load and match values based on the
@@ -144,35 +131,35 @@ static int pwm_omap_dmtimer_config(struct pwm_chip *chip,
 	 *   OMAP4430/60/70 TRM sections 22.2.4.10 and 22.2.4.11
 	 *   AM335x Sitara TRM sections 20.1.3.5 and 20.1.3.6
 	 */
-	period_cycles = pwm_omap_dmtimer_get_clock_cycles(clk_rate, period_ns);
-	duty_cycles = pwm_omap_dmtimer_get_clock_cycles(clk_rate, duty_ns);
+	period_cycles = pwm_omap_dmtimer_get_clock_cycles(omap, period_ns);
+	duty_cycles = pwm_omap_dmtimer_get_clock_cycles(omap, duty_ns);
 
 	if (period_cycles < 2) {
 		dev_info(chip->dev,
 			 "period %d ns too short for clock rate %lu Hz\n",
-			 period_ns, clk_rate);
+			 period_ns, omap->freq);
 		goto err_einval;
 	}
 
 	if (duty_cycles < 1) {
 		dev_dbg(chip->dev,
 			"duty cycle %d ns is too short for clock rate %lu Hz\n",
-			duty_ns, clk_rate);
+			duty_ns, omap->freq);
 		dev_dbg(chip->dev, "using minimum of 1 clock cycle\n");
 		duty_cycles = 1;
 	} else if (duty_cycles >= period_cycles) {
 		dev_dbg(chip->dev,
 			"duty cycle %d ns is too long for period %d ns at clock rate %lu Hz\n",
-			duty_ns, period_ns, clk_rate);
+			duty_ns, period_ns, omap->freq);
 		dev_dbg(chip->dev, "using maximum of 1 clock cycle less than period\n");
 		duty_cycles = period_cycles - 1;
 	}
 
 	dev_dbg(chip->dev, "effective duty cycle: %lld ns, period: %lld ns\n",
 		DIV_ROUND_CLOSEST_ULL((u64)NSEC_PER_SEC * duty_cycles,
-				      clk_rate),
+				      omap->freq),
 		DIV_ROUND_CLOSEST_ULL((u64)NSEC_PER_SEC * period_cycles,
-				      clk_rate));
+				      omap->freq));
 
 	load_value = (DM_TIMER_MAX - period_cycles) + 1;
 	match_value = load_value + duty_cycles - 1;
@@ -248,6 +235,7 @@ static int pwm_omap_dmtimer_probe(struct platform_device *pdev)
 	struct dmtimer_platform_data *timer_pdata;
 	const struct omap_dm_timer_ops *pdata;
 	pwm_omap_dmtimer *dm_timer;
+	struct clk *fclk;
 	u32 v;
 	int ret = 0;
 
@@ -295,10 +283,8 @@ static int pwm_omap_dmtimer_probe(struct platform_device *pdev)
 	}
 
 	dm_timer = pdata->request_by_node(timer);
-	if (!dm_timer) {
+	if (!dm_timer)
 		ret = -EPROBE_DEFER;
-		goto put;
-	}
 
 put:
 	of_node_put(timer);
@@ -307,8 +293,8 @@ static int pwm_omap_dmtimer_probe(struct platform_device *pdev)
 
 	omap = devm_kzalloc(&pdev->dev, sizeof(*omap), GFP_KERNEL);
 	if (!omap) {
-		pdata->free(dm_timer);
-		return -ENOMEM;
+		ret = -ENOMEM;
+		goto free_dm_timer;
 	}
 
 	omap->pdata = pdata;
@@ -319,15 +305,42 @@ static int pwm_omap_dmtimer_probe(struct platform_device *pdev)
 	 * Ensure that the timer is stopped before we allow PWM core to call
 	 * pwm_enable.
 	 */
-	if (pm_runtime_active(&omap->dm_timer_pdev->dev))
-		omap->pdata->stop(omap->dm_timer);
-
-	if (!of_property_read_u32(pdev->dev.of_node, "ti,prescaler", &v))
-		omap->pdata->set_prescaler(omap->dm_timer, v);
+	if (pm_runtime_active(&timer_pdev->dev))
+		pdata->stop(dm_timer);
 
 	/* setup dmtimer clock source */
-	if (!of_property_read_u32(pdev->dev.of_node, "ti,clock-source", &v))
-		omap->pdata->set_source(omap->dm_timer, v);
+	if (!of_property_read_u32(pdev->dev.of_node, "ti,clock-source", &v)) {
+		ret = pdata->set_source(dm_timer, v);
+		if (ret) {
+			dev_err(&pdev->dev, "invalid clock-source\n");
+			goto free_dm_timer;
+		}
+	}
+
+	fclk = pdata->get_fclk(dm_timer);
+	if (!fclk) {
+		dev_err(&pdev->dev, "invalid fclk\n");
+		ret = -EINVAL;
+		goto free_dm_timer;
+	}
+
+	omap->freq = clk_get_rate(fclk);
+	if (!omap->freq) {
+		dev_err(&pdev->dev, "invalid fclk rate\n");
+		ret = -EINVAL;
+		goto free_dm_timer;
+	}
+
+	if (!of_property_read_u32(pdev->dev.of_node, "ti,prescaler", &v)) {
+		ret = pdata->set_prescaler(dm_timer, v);
+		if (ret) {
+			dev_err(&pdev->dev, "invalid prescaler\n");
+			goto free_dm_timer;
+		}
+		omap->freq >>= v + 1;
+	}
+
+	dev_dbg(&pdev->dev, "clk rate: %luHz\n", omap->freq);
 
 	omap->chip.dev = &pdev->dev;
 	omap->chip.ops = &pwm_omap_dmtimer_ops;
@@ -341,13 +354,17 @@ static int pwm_omap_dmtimer_probe(struct platform_device *pdev)
 	ret = pwmchip_add(&omap->chip);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "failed to register PWM\n");
-		omap->pdata->free(omap->dm_timer);
-		return ret;
+		goto free_dm_timer;
 	}
 
 	platform_set_drvdata(pdev, omap);
 
 	return 0;
+
+free_dm_timer:
+	pdata->free(dm_timer);
+
+	return ret;
 }
 
 static int pwm_omap_dmtimer_remove(struct platform_device *pdev)
-- 
2.16.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 4/6] pwm: pwm-omap-dmtimer: Fix frequency when using prescaler
@ 2018-02-23 10:15   ` Ladislav Michl
  0 siblings, 0 replies; 30+ messages in thread
From: Ladislav Michl @ 2018-02-23 10:15 UTC (permalink / raw)
  To: linux-arm-kernel

Prescaler setting is currently not taken into account.
Fix that by introducing freq member variable and initialize
it at device probe time. This also avoids frequency
recomputing at each pwm configure time.

Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
---
 drivers/pwm/pwm-omap-dmtimer.c | 93 +++++++++++++++++++++++++-----------------
 1 file changed, 55 insertions(+), 38 deletions(-)

diff --git a/drivers/pwm/pwm-omap-dmtimer.c b/drivers/pwm/pwm-omap-dmtimer.c
index 665da3c8fbce..48342285c953 100644
--- a/drivers/pwm/pwm-omap-dmtimer.c
+++ b/drivers/pwm/pwm-omap-dmtimer.c
@@ -40,6 +40,7 @@ struct pwm_omap_dmtimer_chip {
 	pwm_omap_dmtimer *dm_timer;
 	const struct omap_dm_timer_ops *pdata;
 	struct platform_device *dm_timer_pdev;
+	unsigned long freq;
 };
 
 static inline struct pwm_omap_dmtimer_chip *
@@ -48,9 +49,10 @@ to_pwm_omap_dmtimer_chip(struct pwm_chip *chip)
 	return container_of(chip, struct pwm_omap_dmtimer_chip, chip);
 }
 
-static u32 pwm_omap_dmtimer_get_clock_cycles(unsigned long clk_rate, int ns)
+static inline u32
+pwm_omap_dmtimer_get_clock_cycles(struct pwm_omap_dmtimer_chip *omap, int ns)
 {
-	return DIV_ROUND_CLOSEST_ULL((u64)clk_rate * ns, NSEC_PER_SEC);
+	return DIV_ROUND_CLOSEST_ULL((u64)omap->freq * ns, NSEC_PER_SEC);
 }
 
 static void pwm_omap_dmtimer_start(struct pwm_omap_dmtimer_chip *omap)
@@ -99,8 +101,6 @@ static int pwm_omap_dmtimer_config(struct pwm_chip *chip,
 	struct pwm_omap_dmtimer_chip *omap = to_pwm_omap_dmtimer_chip(chip);
 	u32 period_cycles, duty_cycles;
 	u32 load_value, match_value;
-	struct clk *fclk;
-	unsigned long clk_rate;
 	bool timer_active;
 
 	dev_dbg(chip->dev, "requested duty cycle: %d ns, period: %d ns\n",
@@ -114,19 +114,6 @@ static int pwm_omap_dmtimer_config(struct pwm_chip *chip,
 		return 0;
 	}
 
-	fclk = omap->pdata->get_fclk(omap->dm_timer);
-	if (!fclk) {
-		dev_err(chip->dev, "invalid pmtimer fclk\n");
-		goto err_einval;
-	}
-
-	clk_rate = clk_get_rate(fclk);
-	if (!clk_rate) {
-		dev_err(chip->dev, "invalid pmtimer fclk rate\n");
-		goto err_einval;
-	}
-
-	dev_dbg(chip->dev, "clk rate: %luHz\n", clk_rate);
 
 	/*
 	 * Calculate the appropriate load and match values based on the
@@ -144,35 +131,35 @@ static int pwm_omap_dmtimer_config(struct pwm_chip *chip,
 	 *   OMAP4430/60/70 TRM sections 22.2.4.10 and 22.2.4.11
 	 *   AM335x Sitara TRM sections 20.1.3.5 and 20.1.3.6
 	 */
-	period_cycles = pwm_omap_dmtimer_get_clock_cycles(clk_rate, period_ns);
-	duty_cycles = pwm_omap_dmtimer_get_clock_cycles(clk_rate, duty_ns);
+	period_cycles = pwm_omap_dmtimer_get_clock_cycles(omap, period_ns);
+	duty_cycles = pwm_omap_dmtimer_get_clock_cycles(omap, duty_ns);
 
 	if (period_cycles < 2) {
 		dev_info(chip->dev,
 			 "period %d ns too short for clock rate %lu Hz\n",
-			 period_ns, clk_rate);
+			 period_ns, omap->freq);
 		goto err_einval;
 	}
 
 	if (duty_cycles < 1) {
 		dev_dbg(chip->dev,
 			"duty cycle %d ns is too short for clock rate %lu Hz\n",
-			duty_ns, clk_rate);
+			duty_ns, omap->freq);
 		dev_dbg(chip->dev, "using minimum of 1 clock cycle\n");
 		duty_cycles = 1;
 	} else if (duty_cycles >= period_cycles) {
 		dev_dbg(chip->dev,
 			"duty cycle %d ns is too long for period %d ns at clock rate %lu Hz\n",
-			duty_ns, period_ns, clk_rate);
+			duty_ns, period_ns, omap->freq);
 		dev_dbg(chip->dev, "using maximum of 1 clock cycle less than period\n");
 		duty_cycles = period_cycles - 1;
 	}
 
 	dev_dbg(chip->dev, "effective duty cycle: %lld ns, period: %lld ns\n",
 		DIV_ROUND_CLOSEST_ULL((u64)NSEC_PER_SEC * duty_cycles,
-				      clk_rate),
+				      omap->freq),
 		DIV_ROUND_CLOSEST_ULL((u64)NSEC_PER_SEC * period_cycles,
-				      clk_rate));
+				      omap->freq));
 
 	load_value = (DM_TIMER_MAX - period_cycles) + 1;
 	match_value = load_value + duty_cycles - 1;
@@ -248,6 +235,7 @@ static int pwm_omap_dmtimer_probe(struct platform_device *pdev)
 	struct dmtimer_platform_data *timer_pdata;
 	const struct omap_dm_timer_ops *pdata;
 	pwm_omap_dmtimer *dm_timer;
+	struct clk *fclk;
 	u32 v;
 	int ret = 0;
 
@@ -295,10 +283,8 @@ static int pwm_omap_dmtimer_probe(struct platform_device *pdev)
 	}
 
 	dm_timer = pdata->request_by_node(timer);
-	if (!dm_timer) {
+	if (!dm_timer)
 		ret = -EPROBE_DEFER;
-		goto put;
-	}
 
 put:
 	of_node_put(timer);
@@ -307,8 +293,8 @@ static int pwm_omap_dmtimer_probe(struct platform_device *pdev)
 
 	omap = devm_kzalloc(&pdev->dev, sizeof(*omap), GFP_KERNEL);
 	if (!omap) {
-		pdata->free(dm_timer);
-		return -ENOMEM;
+		ret = -ENOMEM;
+		goto free_dm_timer;
 	}
 
 	omap->pdata = pdata;
@@ -319,15 +305,42 @@ static int pwm_omap_dmtimer_probe(struct platform_device *pdev)
 	 * Ensure that the timer is stopped before we allow PWM core to call
 	 * pwm_enable.
 	 */
-	if (pm_runtime_active(&omap->dm_timer_pdev->dev))
-		omap->pdata->stop(omap->dm_timer);
-
-	if (!of_property_read_u32(pdev->dev.of_node, "ti,prescaler", &v))
-		omap->pdata->set_prescaler(omap->dm_timer, v);
+	if (pm_runtime_active(&timer_pdev->dev))
+		pdata->stop(dm_timer);
 
 	/* setup dmtimer clock source */
-	if (!of_property_read_u32(pdev->dev.of_node, "ti,clock-source", &v))
-		omap->pdata->set_source(omap->dm_timer, v);
+	if (!of_property_read_u32(pdev->dev.of_node, "ti,clock-source", &v)) {
+		ret = pdata->set_source(dm_timer, v);
+		if (ret) {
+			dev_err(&pdev->dev, "invalid clock-source\n");
+			goto free_dm_timer;
+		}
+	}
+
+	fclk = pdata->get_fclk(dm_timer);
+	if (!fclk) {
+		dev_err(&pdev->dev, "invalid fclk\n");
+		ret = -EINVAL;
+		goto free_dm_timer;
+	}
+
+	omap->freq = clk_get_rate(fclk);
+	if (!omap->freq) {
+		dev_err(&pdev->dev, "invalid fclk rate\n");
+		ret = -EINVAL;
+		goto free_dm_timer;
+	}
+
+	if (!of_property_read_u32(pdev->dev.of_node, "ti,prescaler", &v)) {
+		ret = pdata->set_prescaler(dm_timer, v);
+		if (ret) {
+			dev_err(&pdev->dev, "invalid prescaler\n");
+			goto free_dm_timer;
+		}
+		omap->freq >>= v + 1;
+	}
+
+	dev_dbg(&pdev->dev, "clk rate: %luHz\n", omap->freq);
 
 	omap->chip.dev = &pdev->dev;
 	omap->chip.ops = &pwm_omap_dmtimer_ops;
@@ -341,13 +354,17 @@ static int pwm_omap_dmtimer_probe(struct platform_device *pdev)
 	ret = pwmchip_add(&omap->chip);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "failed to register PWM\n");
-		omap->pdata->free(omap->dm_timer);
-		return ret;
+		goto free_dm_timer;
 	}
 
 	platform_set_drvdata(pdev, omap);
 
 	return 0;
+
+free_dm_timer:
+	pdata->free(dm_timer);
+
+	return ret;
 }
 
 static int pwm_omap_dmtimer_remove(struct platform_device *pdev)
-- 
2.16.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 5/6] clocksource: timer-ti-dm: Add event capture
  2018-02-23 10:12 ` Ladislav Michl
@ 2018-02-23 10:16   ` Ladislav Michl
  -1 siblings, 0 replies; 30+ messages in thread
From: Ladislav Michl @ 2018-02-23 10:16 UTC (permalink / raw)
  To: linux-omap, linux-arm-kernel, linux-pwm
  Cc: t-kristo, grygorii.strashko, aaro.koskinen, tony, Keerthy,
	daniel.lezcano, robh+dt, narmstrong, thierry.reding,
	Brecht Neyrinck, sebastian.reichel, Thomas Gleixner,
	Claudiu.Beznea

Implement event capture functions.

Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
---
 drivers/clocksource/timer-ti-dm.c          | 47 ++++++++++++++++++++++++++++--
 include/linux/platform_data/dmtimer-omap.h |  8 +++++
 2 files changed, 53 insertions(+), 2 deletions(-)

diff --git a/drivers/clocksource/timer-ti-dm.c b/drivers/clocksource/timer-ti-dm.c
index b57e875b74ca..c227d62794a0 100644
--- a/drivers/clocksource/timer-ti-dm.c
+++ b/drivers/clocksource/timer-ti-dm.c
@@ -576,8 +576,8 @@ static int omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload,
 }
 
 /* Optimized set_load which removes costly spin wait in timer_start */
-int omap_dm_timer_set_load_start(struct omap_dm_timer *timer, int autoreload,
-                            unsigned int load)
+static int omap_dm_timer_set_load_start(struct omap_dm_timer *timer,
+					int autoreload, unsigned int load)
 {
 	u32 l;
 
@@ -627,6 +627,30 @@ static int omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable,
 	return 0;
 }
 
+static int omap_dm_timer_set_capture(struct omap_dm_timer *timer,
+				     int captmode, int edges)
+{
+	u32 l;
+
+	if (unlikely(!timer))
+		return -EINVAL;
+
+	omap_dm_timer_enable(timer);
+	l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
+	l &= ~(OMAP_TIMER_CTRL_CAPTMODE | OMAP_TIMER_CTRL_SCPWM |
+	       OMAP_TIMER_CTRL_PT | OMAP_TIMER_CTRL_TCM_BOTHEDGES);
+	l |= OMAP_TIMER_CTRL_GPOCFG;
+	if (captmode)
+		l |= OMAP_TIMER_CTRL_CAPTMODE;
+	l |= edges << 8;
+	omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
+
+	/* Save the context */
+	timer->context.tclr = l;
+	omap_dm_timer_disable(timer);
+	return 0;
+}
+
 static int omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on,
 				 int toggle, int trigger)
 {
@@ -785,6 +809,22 @@ int omap_dm_timers_active(void)
 	return 0;
 }
 
+static int omap_dm_timer_read_capture(struct omap_dm_timer *timer,
+					unsigned int *reg,
+					unsigned int *reg2)
+{
+	if (unlikely(!timer || pm_runtime_suspended(&timer->pdev->dev))) {
+		pr_err("%s: timer not available or enabled.\n", __func__);
+		return -EINVAL;
+	}
+
+	*reg = omap_dm_timer_read_reg(timer, OMAP_TIMER_CAPTURE_REG);
+	if (reg2)
+		*reg2 = omap_dm_timer_read_reg(timer, OMAP_TIMER_CAPTURE2_REG);
+
+	return 0;
+}
+
 static const struct of_device_id omap_timer_match[];
 
 /**
@@ -930,11 +970,14 @@ const static struct omap_dm_timer_ops dmtimer_ops = {
 	.start = omap_dm_timer_start,
 	.stop = omap_dm_timer_stop,
 	.set_load = omap_dm_timer_set_load,
+	.set_load_start = omap_dm_timer_set_load_start,
 	.set_match = omap_dm_timer_set_match,
+	.set_capture = omap_dm_timer_set_capture,
 	.set_pwm = omap_dm_timer_set_pwm,
 	.set_prescaler = omap_dm_timer_set_prescaler,
 	.read_counter = omap_dm_timer_read_counter,
 	.write_counter = omap_dm_timer_write_counter,
+	.read_capture = omap_dm_timer_read_capture,
 	.read_status = omap_dm_timer_read_status,
 	.write_status = omap_dm_timer_write_status,
 };
diff --git a/include/linux/platform_data/dmtimer-omap.h b/include/linux/platform_data/dmtimer-omap.h
index 757a0f9e26f9..7502f130b213 100644
--- a/include/linux/platform_data/dmtimer-omap.h
+++ b/include/linux/platform_data/dmtimer-omap.h
@@ -43,8 +43,12 @@ struct omap_dm_timer_ops {
 
 	int	(*set_load)(struct omap_dm_timer *timer, int autoreload,
 			    unsigned int value);
+	int	(*set_load_start)(struct omap_dm_timer *timer, int autoreload,
+				  unsigned int value);
 	int	(*set_match)(struct omap_dm_timer *timer, int enable,
 			     unsigned int match);
+	int	(*set_capture)(struct omap_dm_timer *timer, int captmode,
+			       int edges);
 	int	(*set_pwm)(struct omap_dm_timer *timer, int def_on,
 			   int toggle, int trigger);
 	int	(*set_prescaler)(struct omap_dm_timer *timer, int prescaler);
@@ -52,6 +56,10 @@ struct omap_dm_timer_ops {
 	unsigned int (*read_counter)(struct omap_dm_timer *timer);
 	int	(*write_counter)(struct omap_dm_timer *timer,
 				 unsigned int value);
+
+	int	(*read_capture)(struct omap_dm_timer *timer, unsigned int *reg,
+				unsigned int *reg2);
+
 	unsigned int (*read_status)(struct omap_dm_timer *timer);
 	int	(*write_status)(struct omap_dm_timer *timer,
 				unsigned int value);
-- 
2.16.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 5/6] clocksource: timer-ti-dm: Add event capture
@ 2018-02-23 10:16   ` Ladislav Michl
  0 siblings, 0 replies; 30+ messages in thread
From: Ladislav Michl @ 2018-02-23 10:16 UTC (permalink / raw)
  To: linux-arm-kernel

Implement event capture functions.

Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
---
 drivers/clocksource/timer-ti-dm.c          | 47 ++++++++++++++++++++++++++++--
 include/linux/platform_data/dmtimer-omap.h |  8 +++++
 2 files changed, 53 insertions(+), 2 deletions(-)

diff --git a/drivers/clocksource/timer-ti-dm.c b/drivers/clocksource/timer-ti-dm.c
index b57e875b74ca..c227d62794a0 100644
--- a/drivers/clocksource/timer-ti-dm.c
+++ b/drivers/clocksource/timer-ti-dm.c
@@ -576,8 +576,8 @@ static int omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload,
 }
 
 /* Optimized set_load which removes costly spin wait in timer_start */
-int omap_dm_timer_set_load_start(struct omap_dm_timer *timer, int autoreload,
-                            unsigned int load)
+static int omap_dm_timer_set_load_start(struct omap_dm_timer *timer,
+					int autoreload, unsigned int load)
 {
 	u32 l;
 
@@ -627,6 +627,30 @@ static int omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable,
 	return 0;
 }
 
+static int omap_dm_timer_set_capture(struct omap_dm_timer *timer,
+				     int captmode, int edges)
+{
+	u32 l;
+
+	if (unlikely(!timer))
+		return -EINVAL;
+
+	omap_dm_timer_enable(timer);
+	l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
+	l &= ~(OMAP_TIMER_CTRL_CAPTMODE | OMAP_TIMER_CTRL_SCPWM |
+	       OMAP_TIMER_CTRL_PT | OMAP_TIMER_CTRL_TCM_BOTHEDGES);
+	l |= OMAP_TIMER_CTRL_GPOCFG;
+	if (captmode)
+		l |= OMAP_TIMER_CTRL_CAPTMODE;
+	l |= edges << 8;
+	omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
+
+	/* Save the context */
+	timer->context.tclr = l;
+	omap_dm_timer_disable(timer);
+	return 0;
+}
+
 static int omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on,
 				 int toggle, int trigger)
 {
@@ -785,6 +809,22 @@ int omap_dm_timers_active(void)
 	return 0;
 }
 
+static int omap_dm_timer_read_capture(struct omap_dm_timer *timer,
+					unsigned int *reg,
+					unsigned int *reg2)
+{
+	if (unlikely(!timer || pm_runtime_suspended(&timer->pdev->dev))) {
+		pr_err("%s: timer not available or enabled.\n", __func__);
+		return -EINVAL;
+	}
+
+	*reg = omap_dm_timer_read_reg(timer, OMAP_TIMER_CAPTURE_REG);
+	if (reg2)
+		*reg2 = omap_dm_timer_read_reg(timer, OMAP_TIMER_CAPTURE2_REG);
+
+	return 0;
+}
+
 static const struct of_device_id omap_timer_match[];
 
 /**
@@ -930,11 +970,14 @@ const static struct omap_dm_timer_ops dmtimer_ops = {
 	.start = omap_dm_timer_start,
 	.stop = omap_dm_timer_stop,
 	.set_load = omap_dm_timer_set_load,
+	.set_load_start = omap_dm_timer_set_load_start,
 	.set_match = omap_dm_timer_set_match,
+	.set_capture = omap_dm_timer_set_capture,
 	.set_pwm = omap_dm_timer_set_pwm,
 	.set_prescaler = omap_dm_timer_set_prescaler,
 	.read_counter = omap_dm_timer_read_counter,
 	.write_counter = omap_dm_timer_write_counter,
+	.read_capture = omap_dm_timer_read_capture,
 	.read_status = omap_dm_timer_read_status,
 	.write_status = omap_dm_timer_write_status,
 };
diff --git a/include/linux/platform_data/dmtimer-omap.h b/include/linux/platform_data/dmtimer-omap.h
index 757a0f9e26f9..7502f130b213 100644
--- a/include/linux/platform_data/dmtimer-omap.h
+++ b/include/linux/platform_data/dmtimer-omap.h
@@ -43,8 +43,12 @@ struct omap_dm_timer_ops {
 
 	int	(*set_load)(struct omap_dm_timer *timer, int autoreload,
 			    unsigned int value);
+	int	(*set_load_start)(struct omap_dm_timer *timer, int autoreload,
+				  unsigned int value);
 	int	(*set_match)(struct omap_dm_timer *timer, int enable,
 			     unsigned int match);
+	int	(*set_capture)(struct omap_dm_timer *timer, int captmode,
+			       int edges);
 	int	(*set_pwm)(struct omap_dm_timer *timer, int def_on,
 			   int toggle, int trigger);
 	int	(*set_prescaler)(struct omap_dm_timer *timer, int prescaler);
@@ -52,6 +56,10 @@ struct omap_dm_timer_ops {
 	unsigned int (*read_counter)(struct omap_dm_timer *timer);
 	int	(*write_counter)(struct omap_dm_timer *timer,
 				 unsigned int value);
+
+	int	(*read_capture)(struct omap_dm_timer *timer, unsigned int *reg,
+				unsigned int *reg2);
+
 	unsigned int (*read_status)(struct omap_dm_timer *timer);
 	int	(*write_status)(struct omap_dm_timer *timer,
 				unsigned int value);
-- 
2.16.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 6/6] pwm: pwm-omap-dmtimer: Add capture functionality
  2018-02-23 10:12 ` Ladislav Michl
@ 2018-02-23 10:17   ` Ladislav Michl
  -1 siblings, 0 replies; 30+ messages in thread
From: Ladislav Michl @ 2018-02-23 10:17 UTC (permalink / raw)
  To: linux-omap, linux-arm-kernel, linux-pwm
  Cc: t-kristo, grygorii.strashko, aaro.koskinen, tony, Keerthy,
	daniel.lezcano, robh+dt, narmstrong, thierry.reding,
	Brecht Neyrinck, sebastian.reichel, Thomas Gleixner,
	Claudiu.Beznea

Implement event capture.

Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
---
 Note: Please see cover letter

 drivers/pwm/pwm-omap-dmtimer.c | 127 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 127 insertions(+)

diff --git a/drivers/pwm/pwm-omap-dmtimer.c b/drivers/pwm/pwm-omap-dmtimer.c
index 48342285c953..5a2fc0e0a1c5 100644
--- a/drivers/pwm/pwm-omap-dmtimer.c
+++ b/drivers/pwm/pwm-omap-dmtimer.c
@@ -16,8 +16,10 @@
  *   PWM driver / controller, using the OMAP's dual-mode timers.
  */
 
+#include <clocksource/timer-ti-dm.h>
 #include <linux/clk.h>
 #include <linux/err.h>
+#include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/mutex.h>
@@ -30,17 +32,21 @@
 #include <linux/pwm.h>
 #include <linux/slab.h>
 #include <linux/time.h>
+#include <linux/wait.h>
 
 #define DM_TIMER_LOAD_MIN 0xfffffffe
 #define DM_TIMER_MAX      0xffffffff
 
 struct pwm_omap_dmtimer_chip {
 	struct pwm_chip chip;
+	spinlock_t lock;
 	struct mutex mutex;
+	wait_queue_head_t wait;
 	pwm_omap_dmtimer *dm_timer;
 	const struct omap_dm_timer_ops *pdata;
 	struct platform_device *dm_timer_pdev;
 	unsigned long freq;
+	unsigned int ev_cnt, overflow, width;
 };
 
 static inline struct pwm_omap_dmtimer_chip *
@@ -55,6 +61,22 @@ pwm_omap_dmtimer_get_clock_cycles(struct pwm_omap_dmtimer_chip *omap, int ns)
 	return DIV_ROUND_CLOSEST_ULL((u64)omap->freq * ns, NSEC_PER_SEC);
 }
 
+static inline unsigned int
+pwm_omap_dmtimer_ticks_to_ns(struct pwm_omap_dmtimer_chip *omap,
+			     unsigned int ticks)
+{
+	return DIV_ROUND_CLOSEST_ULL((u64)ticks * NSEC_PER_SEC, omap->freq);
+}
+
+static unsigned int pwm_omap_dmtimer_get_width(struct pwm_omap_dmtimer_chip *omap,
+					       unsigned int c1, unsigned int c2)
+{
+	if (c1 <= c2)
+		return c2 - c1;
+
+	return (c2 - omap->overflow) + (DM_TIMER_MAX - c1);
+}
+
 static void pwm_omap_dmtimer_start(struct pwm_omap_dmtimer_chip *omap)
 {
 	/*
@@ -218,7 +240,101 @@ static int pwm_omap_dmtimer_set_polarity(struct pwm_chip *chip,
 	return 0;
 }
 
+static int pwm_omap_dmtimer_capture(struct pwm_chip *chip,
+				    struct pwm_device *pwm,
+				    struct pwm_capture *result,
+				    unsigned long timeout)
+
+{
+	int res;
+	unsigned long flags;
+	struct pwm_omap_dmtimer_chip *omap = to_pwm_omap_dmtimer_chip(chip);
+
+	mutex_lock(&omap->mutex);
+
+	if (pm_runtime_active(&omap->dm_timer_pdev->dev))
+		omap->pdata->stop(omap->dm_timer);
+
+	/* Let timer overflow every 1 second */
+	omap->overflow = DM_TIMER_MAX - (1 * omap->freq);
+	timeout = msecs_to_jiffies(timeout);
+	result->period = result->duty_cycle = 0;
+
+	spin_lock_irqsave(&omap->lock, flags);
+	omap->pdata->set_int_enable(omap->dm_timer, OMAP_TIMER_INT_CAPTURE |
+				    OMAP_TIMER_INT_OVERFLOW);
+	omap->pdata->set_capture(omap->dm_timer, 1, 1);
+	omap->pdata->set_load_start(omap->dm_timer, true, omap->overflow);
+	omap->ev_cnt = omap->width = 0;
+	spin_unlock_irqrestore(&omap->lock, flags);
+
+	res = wait_event_interruptible_timeout(omap->wait,
+					       omap->width > 0, timeout);
+	if (res > 0) {
+		spin_lock_irqsave(&omap->lock, flags);
+		result->period =
+			pwm_omap_dmtimer_ticks_to_ns(omap, omap->width);
+		omap->pdata->stop(omap->dm_timer);
+		omap->pdata->set_capture(omap->dm_timer, 1, 3);
+		omap->pdata->start(omap->dm_timer);
+		omap->ev_cnt = omap->width = 0;
+		spin_unlock_irqrestore(&omap->lock, flags);
+
+		res = wait_event_interruptible_timeout(omap->wait,
+						       omap->width > 0,
+						       timeout);
+	}
+
+	spin_lock_irqsave(&omap->lock, flags);
+	omap->pdata->stop(omap->dm_timer);
+	omap->pdata->set_int_disable(omap->dm_timer, OMAP_TIMER_INT_CAPTURE |
+				     OMAP_TIMER_INT_OVERFLOW);
+	spin_unlock_irqrestore(&omap->lock, flags);
+
+	if (res == 0) {
+		res = -ETIMEDOUT;
+	} else if (res > 0) {
+		result->duty_cycle =
+			pwm_omap_dmtimer_ticks_to_ns(omap, omap->width);
+		res = 0;
+	}
+
+	mutex_unlock(&omap->mutex);
+
+	return res;
+}
+
+static irqreturn_t pwm_omap_dmtimer_irq(int irq, void *dev_id)
+{
+	u32 l;
+	unsigned int c1, c2;
+	unsigned long flags;
+        struct pwm_omap_dmtimer_chip *omap = dev_id;
+
+	spin_lock_irqsave(&omap->lock, flags);
+
+	l = omap->pdata->read_status(omap->dm_timer);
+	if (l & OMAP_TIMER_INT_CAPTURE) {
+		if (!omap->width && omap->ev_cnt == 1) {
+			omap->pdata->read_capture(omap->dm_timer, &c1, &c2);
+			omap->width = pwm_omap_dmtimer_get_width(omap, c1, c2);
+			wake_up(&omap->wait);
+		}
+		omap->ev_cnt++;
+	}
+	/* TODO: handle overflow as well
+	if (l & OMAP_TIMER_INT_OVERFLOW)
+		overflow++;
+	*/
+	omap->pdata->write_status(omap->dm_timer, l);
+
+	spin_unlock_irqrestore(&omap->lock, flags);
+
+	return IRQ_HANDLED;
+}
+
 static const struct pwm_ops pwm_omap_dmtimer_ops = {
+	.capture = pwm_omap_dmtimer_capture,
 	.enable	= pwm_omap_dmtimer_enable,
 	.disable = pwm_omap_dmtimer_disable,
 	.config	= pwm_omap_dmtimer_config,
@@ -349,7 +465,18 @@ static int pwm_omap_dmtimer_probe(struct platform_device *pdev)
 	omap->chip.of_xlate = of_pwm_xlate_with_flags;
 	omap->chip.of_pwm_n_cells = 3;
 
+	spin_lock_init(&omap->lock);
 	mutex_init(&omap->mutex);
+	init_waitqueue_head(&omap->wait);
+
+	ret = omap->pdata->get_irq(omap->dm_timer);
+	if (ret < 0)
+		goto free_dm_timer;
+
+	ret = devm_request_irq(&pdev->dev, ret, pwm_omap_dmtimer_irq, 0,
+				"event_capture", omap);
+	if (ret)
+		goto free_dm_timer;
 
 	ret = pwmchip_add(&omap->chip);
 	if (ret < 0) {
-- 
2.16.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 6/6] pwm: pwm-omap-dmtimer: Add capture functionality
@ 2018-02-23 10:17   ` Ladislav Michl
  0 siblings, 0 replies; 30+ messages in thread
From: Ladislav Michl @ 2018-02-23 10:17 UTC (permalink / raw)
  To: linux-arm-kernel

Implement event capture.

Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
---
 Note: Please see cover letter

 drivers/pwm/pwm-omap-dmtimer.c | 127 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 127 insertions(+)

diff --git a/drivers/pwm/pwm-omap-dmtimer.c b/drivers/pwm/pwm-omap-dmtimer.c
index 48342285c953..5a2fc0e0a1c5 100644
--- a/drivers/pwm/pwm-omap-dmtimer.c
+++ b/drivers/pwm/pwm-omap-dmtimer.c
@@ -16,8 +16,10 @@
  *   PWM driver / controller, using the OMAP's dual-mode timers.
  */
 
+#include <clocksource/timer-ti-dm.h>
 #include <linux/clk.h>
 #include <linux/err.h>
+#include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/mutex.h>
@@ -30,17 +32,21 @@
 #include <linux/pwm.h>
 #include <linux/slab.h>
 #include <linux/time.h>
+#include <linux/wait.h>
 
 #define DM_TIMER_LOAD_MIN 0xfffffffe
 #define DM_TIMER_MAX      0xffffffff
 
 struct pwm_omap_dmtimer_chip {
 	struct pwm_chip chip;
+	spinlock_t lock;
 	struct mutex mutex;
+	wait_queue_head_t wait;
 	pwm_omap_dmtimer *dm_timer;
 	const struct omap_dm_timer_ops *pdata;
 	struct platform_device *dm_timer_pdev;
 	unsigned long freq;
+	unsigned int ev_cnt, overflow, width;
 };
 
 static inline struct pwm_omap_dmtimer_chip *
@@ -55,6 +61,22 @@ pwm_omap_dmtimer_get_clock_cycles(struct pwm_omap_dmtimer_chip *omap, int ns)
 	return DIV_ROUND_CLOSEST_ULL((u64)omap->freq * ns, NSEC_PER_SEC);
 }
 
+static inline unsigned int
+pwm_omap_dmtimer_ticks_to_ns(struct pwm_omap_dmtimer_chip *omap,
+			     unsigned int ticks)
+{
+	return DIV_ROUND_CLOSEST_ULL((u64)ticks * NSEC_PER_SEC, omap->freq);
+}
+
+static unsigned int pwm_omap_dmtimer_get_width(struct pwm_omap_dmtimer_chip *omap,
+					       unsigned int c1, unsigned int c2)
+{
+	if (c1 <= c2)
+		return c2 - c1;
+
+	return (c2 - omap->overflow) + (DM_TIMER_MAX - c1);
+}
+
 static void pwm_omap_dmtimer_start(struct pwm_omap_dmtimer_chip *omap)
 {
 	/*
@@ -218,7 +240,101 @@ static int pwm_omap_dmtimer_set_polarity(struct pwm_chip *chip,
 	return 0;
 }
 
+static int pwm_omap_dmtimer_capture(struct pwm_chip *chip,
+				    struct pwm_device *pwm,
+				    struct pwm_capture *result,
+				    unsigned long timeout)
+
+{
+	int res;
+	unsigned long flags;
+	struct pwm_omap_dmtimer_chip *omap = to_pwm_omap_dmtimer_chip(chip);
+
+	mutex_lock(&omap->mutex);
+
+	if (pm_runtime_active(&omap->dm_timer_pdev->dev))
+		omap->pdata->stop(omap->dm_timer);
+
+	/* Let timer overflow every 1 second */
+	omap->overflow = DM_TIMER_MAX - (1 * omap->freq);
+	timeout = msecs_to_jiffies(timeout);
+	result->period = result->duty_cycle = 0;
+
+	spin_lock_irqsave(&omap->lock, flags);
+	omap->pdata->set_int_enable(omap->dm_timer, OMAP_TIMER_INT_CAPTURE |
+				    OMAP_TIMER_INT_OVERFLOW);
+	omap->pdata->set_capture(omap->dm_timer, 1, 1);
+	omap->pdata->set_load_start(omap->dm_timer, true, omap->overflow);
+	omap->ev_cnt = omap->width = 0;
+	spin_unlock_irqrestore(&omap->lock, flags);
+
+	res = wait_event_interruptible_timeout(omap->wait,
+					       omap->width > 0, timeout);
+	if (res > 0) {
+		spin_lock_irqsave(&omap->lock, flags);
+		result->period =
+			pwm_omap_dmtimer_ticks_to_ns(omap, omap->width);
+		omap->pdata->stop(omap->dm_timer);
+		omap->pdata->set_capture(omap->dm_timer, 1, 3);
+		omap->pdata->start(omap->dm_timer);
+		omap->ev_cnt = omap->width = 0;
+		spin_unlock_irqrestore(&omap->lock, flags);
+
+		res = wait_event_interruptible_timeout(omap->wait,
+						       omap->width > 0,
+						       timeout);
+	}
+
+	spin_lock_irqsave(&omap->lock, flags);
+	omap->pdata->stop(omap->dm_timer);
+	omap->pdata->set_int_disable(omap->dm_timer, OMAP_TIMER_INT_CAPTURE |
+				     OMAP_TIMER_INT_OVERFLOW);
+	spin_unlock_irqrestore(&omap->lock, flags);
+
+	if (res == 0) {
+		res = -ETIMEDOUT;
+	} else if (res > 0) {
+		result->duty_cycle =
+			pwm_omap_dmtimer_ticks_to_ns(omap, omap->width);
+		res = 0;
+	}
+
+	mutex_unlock(&omap->mutex);
+
+	return res;
+}
+
+static irqreturn_t pwm_omap_dmtimer_irq(int irq, void *dev_id)
+{
+	u32 l;
+	unsigned int c1, c2;
+	unsigned long flags;
+        struct pwm_omap_dmtimer_chip *omap = dev_id;
+
+	spin_lock_irqsave(&omap->lock, flags);
+
+	l = omap->pdata->read_status(omap->dm_timer);
+	if (l & OMAP_TIMER_INT_CAPTURE) {
+		if (!omap->width && omap->ev_cnt == 1) {
+			omap->pdata->read_capture(omap->dm_timer, &c1, &c2);
+			omap->width = pwm_omap_dmtimer_get_width(omap, c1, c2);
+			wake_up(&omap->wait);
+		}
+		omap->ev_cnt++;
+	}
+	/* TODO: handle overflow as well
+	if (l & OMAP_TIMER_INT_OVERFLOW)
+		overflow++;
+	*/
+	omap->pdata->write_status(omap->dm_timer, l);
+
+	spin_unlock_irqrestore(&omap->lock, flags);
+
+	return IRQ_HANDLED;
+}
+
 static const struct pwm_ops pwm_omap_dmtimer_ops = {
+	.capture = pwm_omap_dmtimer_capture,
 	.enable	= pwm_omap_dmtimer_enable,
 	.disable = pwm_omap_dmtimer_disable,
 	.config	= pwm_omap_dmtimer_config,
@@ -349,7 +465,18 @@ static int pwm_omap_dmtimer_probe(struct platform_device *pdev)
 	omap->chip.of_xlate = of_pwm_xlate_with_flags;
 	omap->chip.of_pwm_n_cells = 3;
 
+	spin_lock_init(&omap->lock);
 	mutex_init(&omap->mutex);
+	init_waitqueue_head(&omap->wait);
+
+	ret = omap->pdata->get_irq(omap->dm_timer);
+	if (ret < 0)
+		goto free_dm_timer;
+
+	ret = devm_request_irq(&pdev->dev, ret, pwm_omap_dmtimer_irq, 0,
+				"event_capture", omap);
+	if (ret)
+		goto free_dm_timer;
 
 	ret = pwmchip_add(&omap->chip);
 	if (ret < 0) {
-- 
2.16.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* Re: [PATCH 1/6] clocksource: timer-ti-dm: Make unexported functions static
  2018-02-23 10:13   ` Ladislav Michl
@ 2018-02-27 18:06     ` Tony Lindgren
  -1 siblings, 0 replies; 30+ messages in thread
From: Tony Lindgren @ 2018-02-27 18:06 UTC (permalink / raw)
  To: Ladislav Michl
  Cc: linux-pwm, aaro.koskinen, Keerthy, daniel.lezcano, t-kristo,
	robh+dt, narmstrong, thierry.reding, Thomas Gleixner,
	Brecht Neyrinck, sebastian.reichel, grygorii.strashko,
	linux-omap, Claudiu.Beznea, linux-arm-kernel

* Ladislav Michl <ladis@linux-mips.org> [180223 10:14]:
> As dmtimer no longer exports functions, make those previously
> exported static (this requires few functions to be moved around
> as their prototypes were deleted).

Looks like this one fails to build with omap1_defconfig:

drivers/clocksource/timer-ti-dm.c:935:14: error:
'omap_dm_timer_get_fclk' undeclared here 

Other than that the first three patches seem like nice
clean-up :)

Regards,

Tony

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 1/6] clocksource: timer-ti-dm: Make unexported functions static
@ 2018-02-27 18:06     ` Tony Lindgren
  0 siblings, 0 replies; 30+ messages in thread
From: Tony Lindgren @ 2018-02-27 18:06 UTC (permalink / raw)
  To: linux-arm-kernel

* Ladislav Michl <ladis@linux-mips.org> [180223 10:14]:
> As dmtimer no longer exports functions, make those previously
> exported static (this requires few functions to be moved around
> as their prototypes were deleted).

Looks like this one fails to build with omap1_defconfig:

drivers/clocksource/timer-ti-dm.c:935:14: error:
'omap_dm_timer_get_fclk' undeclared here 

Other than that the first three patches seem like nice
clean-up :)

Regards,

Tony

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 1/6] clocksource: timer-ti-dm: Make unexported functions static
  2018-02-27 18:06     ` Tony Lindgren
@ 2018-02-27 19:07       ` Ladislav Michl
  -1 siblings, 0 replies; 30+ messages in thread
From: Ladislav Michl @ 2018-02-27 19:07 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: linux-pwm, aaro.koskinen, Keerthy, daniel.lezcano, t-kristo,
	robh+dt, narmstrong, thierry.reding, Thomas Gleixner,
	Brecht Neyrinck, sebastian.reichel, grygorii.strashko,
	linux-omap, Claudiu.Beznea, linux-arm-kernel

On Tue, Feb 27, 2018 at 10:06:41AM -0800, Tony Lindgren wrote:
> * Ladislav Michl <ladis@linux-mips.org> [180223 10:14]:
> > As dmtimer no longer exports functions, make those previously
> > exported static (this requires few functions to be moved around
> > as their prototypes were deleted).
> 
> Looks like this one fails to build with omap1_defconfig:
> 
> drivers/clocksource/timer-ti-dm.c:935:14: error:
> 'omap_dm_timer_get_fclk' undeclared here 

Umm, it compiled fine on top of previous versions, so I didn't bother
to retest. I'm sorry about it.

> Other than that the first three patches seem like nice
> clean-up :)

So are you okay with sending those separately as cleanup with above
issue fixed?

But to be honest, I'm more interested how to do the last two patches
right ;-)

> Regards,
> 
> Tony

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 1/6] clocksource: timer-ti-dm: Make unexported functions static
@ 2018-02-27 19:07       ` Ladislav Michl
  0 siblings, 0 replies; 30+ messages in thread
From: Ladislav Michl @ 2018-02-27 19:07 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Feb 27, 2018 at 10:06:41AM -0800, Tony Lindgren wrote:
> * Ladislav Michl <ladis@linux-mips.org> [180223 10:14]:
> > As dmtimer no longer exports functions, make those previously
> > exported static (this requires few functions to be moved around
> > as their prototypes were deleted).
> 
> Looks like this one fails to build with omap1_defconfig:
> 
> drivers/clocksource/timer-ti-dm.c:935:14: error:
> 'omap_dm_timer_get_fclk' undeclared here 

Umm, it compiled fine on top of previous versions, so I didn't bother
to retest. I'm sorry about it.

> Other than that the first three patches seem like nice
> clean-up :)

So are you okay with sending those separately as cleanup with above
issue fixed?

But to be honest, I'm more interested how to do the last two patches
right ;-)

> Regards,
> 
> Tony

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 1/6] clocksource: timer-ti-dm: Make unexported functions static
  2018-02-27 19:07       ` Ladislav Michl
@ 2018-02-27 19:23         ` Tony Lindgren
  -1 siblings, 0 replies; 30+ messages in thread
From: Tony Lindgren @ 2018-02-27 19:23 UTC (permalink / raw)
  To: Ladislav Michl
  Cc: linux-pwm, aaro.koskinen, Keerthy, daniel.lezcano, t-kristo,
	robh+dt, narmstrong, thierry.reding, Thomas Gleixner,
	Brecht Neyrinck, sebastian.reichel, grygorii.strashko,
	linux-omap, Claudiu.Beznea, linux-arm-kernel

* Ladislav Michl <ladis@linux-mips.org> [180227 19:09]:
> On Tue, Feb 27, 2018 at 10:06:41AM -0800, Tony Lindgren wrote:
> > * Ladislav Michl <ladis@linux-mips.org> [180223 10:14]:
> > > As dmtimer no longer exports functions, make those previously
> > > exported static (this requires few functions to be moved around
> > > as their prototypes were deleted).
> > 
> > Looks like this one fails to build with omap1_defconfig:
> > 
> > drivers/clocksource/timer-ti-dm.c:935:14: error:
> > 'omap_dm_timer_get_fclk' undeclared here 
> 
> Umm, it compiled fine on top of previous versions, so I didn't bother
> to retest. I'm sorry about it.
> 
> > Other than that the first three patches seem like nice
> > clean-up :)
> 
> So are you okay with sending those separately as cleanup with above
> issue fixed?

Yeah seems like those first three are suitable for applying
on top of the patches in omap-for-v4.17/timer :)

> But to be honest, I'm more interested how to do the last two patches
> right ;-)

Yeah well if patch 4 can be sent separately as a fix, then
send that separately to Thierry?

Then you're just left with the pending pwm changes that
still need work it seems.

Regards,

Tony

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 1/6] clocksource: timer-ti-dm: Make unexported functions static
@ 2018-02-27 19:23         ` Tony Lindgren
  0 siblings, 0 replies; 30+ messages in thread
From: Tony Lindgren @ 2018-02-27 19:23 UTC (permalink / raw)
  To: linux-arm-kernel

* Ladislav Michl <ladis@linux-mips.org> [180227 19:09]:
> On Tue, Feb 27, 2018 at 10:06:41AM -0800, Tony Lindgren wrote:
> > * Ladislav Michl <ladis@linux-mips.org> [180223 10:14]:
> > > As dmtimer no longer exports functions, make those previously
> > > exported static (this requires few functions to be moved around
> > > as their prototypes were deleted).
> > 
> > Looks like this one fails to build with omap1_defconfig:
> > 
> > drivers/clocksource/timer-ti-dm.c:935:14: error:
> > 'omap_dm_timer_get_fclk' undeclared here 
> 
> Umm, it compiled fine on top of previous versions, so I didn't bother
> to retest. I'm sorry about it.
> 
> > Other than that the first three patches seem like nice
> > clean-up :)
> 
> So are you okay with sending those separately as cleanup with above
> issue fixed?

Yeah seems like those first three are suitable for applying
on top of the patches in omap-for-v4.17/timer :)

> But to be honest, I'm more interested how to do the last two patches
> right ;-)

Yeah well if patch 4 can be sent separately as a fix, then
send that separately to Thierry?

Then you're just left with the pending pwm changes that
still need work it seems.

Regards,

Tony

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 1/6] clocksource: timer-ti-dm: Make unexported functions static
  2018-02-27 19:23         ` Tony Lindgren
@ 2018-02-28 22:11           ` Tony Lindgren
  -1 siblings, 0 replies; 30+ messages in thread
From: Tony Lindgren @ 2018-02-28 22:11 UTC (permalink / raw)
  To: Ladislav Michl
  Cc: linux-pwm, aaro.koskinen, Keerthy, daniel.lezcano, t-kristo,
	robh+dt, narmstrong, thierry.reding, Thomas Gleixner,
	Brecht Neyrinck, sebastian.reichel, grygorii.strashko,
	linux-omap, Claudiu.Beznea, linux-arm-kernel

* Tony Lindgren <tony@atomide.com> [180227 19:24]:
> * Ladislav Michl <ladis@linux-mips.org> [180227 19:09]:
> > On Tue, Feb 27, 2018 at 10:06:41AM -0800, Tony Lindgren wrote:
> > > * Ladislav Michl <ladis@linux-mips.org> [180223 10:14]:
> > > > As dmtimer no longer exports functions, make those previously
> > > > exported static (this requires few functions to be moved around
> > > > as their prototypes were deleted).
> > > 
> > > Looks like this one fails to build with omap1_defconfig:
> > > 
> > > drivers/clocksource/timer-ti-dm.c:935:14: error:
> > > 'omap_dm_timer_get_fclk' undeclared here 
> > 
> > Umm, it compiled fine on top of previous versions, so I didn't bother
> > to retest. I'm sorry about it.
> > 
> > > Other than that the first three patches seem like nice
> > > clean-up :)
> > 
> > So are you okay with sending those separately as cleanup with above
> > issue fixed?
> 
> Yeah seems like those first three are suitable for applying
> on top of the patches in omap-for-v4.17/timer :)

I've now applied your v2 of patch 1 and patches 2 and 3 of
this series into omap-for-v4.17/timer.

Thanks,

Tony

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 1/6] clocksource: timer-ti-dm: Make unexported functions static
@ 2018-02-28 22:11           ` Tony Lindgren
  0 siblings, 0 replies; 30+ messages in thread
From: Tony Lindgren @ 2018-02-28 22:11 UTC (permalink / raw)
  To: linux-arm-kernel

* Tony Lindgren <tony@atomide.com> [180227 19:24]:
> * Ladislav Michl <ladis@linux-mips.org> [180227 19:09]:
> > On Tue, Feb 27, 2018 at 10:06:41AM -0800, Tony Lindgren wrote:
> > > * Ladislav Michl <ladis@linux-mips.org> [180223 10:14]:
> > > > As dmtimer no longer exports functions, make those previously
> > > > exported static (this requires few functions to be moved around
> > > > as their prototypes were deleted).
> > > 
> > > Looks like this one fails to build with omap1_defconfig:
> > > 
> > > drivers/clocksource/timer-ti-dm.c:935:14: error:
> > > 'omap_dm_timer_get_fclk' undeclared here 
> > 
> > Umm, it compiled fine on top of previous versions, so I didn't bother
> > to retest. I'm sorry about it.
> > 
> > > Other than that the first three patches seem like nice
> > > clean-up :)
> > 
> > So are you okay with sending those separately as cleanup with above
> > issue fixed?
> 
> Yeah seems like those first three are suitable for applying
> on top of the patches in omap-for-v4.17/timer :)

I've now applied your v2 of patch 1 and patches 2 and 3 of
this series into omap-for-v4.17/timer.

Thanks,

Tony

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 4/6] pwm: pwm-omap-dmtimer: Fix frequency when using prescaler
  2018-02-23 10:15   ` Ladislav Michl
@ 2018-03-27 21:53     ` Thierry Reding
  -1 siblings, 0 replies; 30+ messages in thread
From: Thierry Reding @ 2018-03-27 21:53 UTC (permalink / raw)
  To: Ladislav Michl
  Cc: linux-pwm, aaro.koskinen, tony, Keerthy, daniel.lezcano,
	t-kristo, narmstrong, robh+dt, Thomas Gleixner, Brecht Neyrinck,
	sebastian.reichel, grygorii.strashko, linux-omap, Claudiu.Beznea,
	linux-arm-kernel


[-- Attachment #1.1: Type: text/plain, Size: 519 bytes --]

On Fri, Feb 23, 2018 at 11:15:53AM +0100, Ladislav Michl wrote:
> Prescaler setting is currently not taken into account.
> Fix that by introducing freq member variable and initialize
> it at device probe time. This also avoids frequency
> recomputing at each pwm configure time.
> 
> Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
> ---
>  drivers/pwm/pwm-omap-dmtimer.c | 93 +++++++++++++++++++++++++-----------------
>  1 file changed, 55 insertions(+), 38 deletions(-)

Applied, thanks.

Thierry

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 176 bytes --]

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 4/6] pwm: pwm-omap-dmtimer: Fix frequency when using prescaler
@ 2018-03-27 21:53     ` Thierry Reding
  0 siblings, 0 replies; 30+ messages in thread
From: Thierry Reding @ 2018-03-27 21:53 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Feb 23, 2018 at 11:15:53AM +0100, Ladislav Michl wrote:
> Prescaler setting is currently not taken into account.
> Fix that by introducing freq member variable and initialize
> it at device probe time. This also avoids frequency
> recomputing at each pwm configure time.
> 
> Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
> ---
>  drivers/pwm/pwm-omap-dmtimer.c | 93 +++++++++++++++++++++++++-----------------
>  1 file changed, 55 insertions(+), 38 deletions(-)

Applied, thanks.

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20180327/ab6ece91/attachment.sig>

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 4/6] pwm: pwm-omap-dmtimer: Fix frequency when using prescaler
  2018-03-27 21:53     ` Thierry Reding
@ 2018-03-27 22:14       ` Thierry Reding
  -1 siblings, 0 replies; 30+ messages in thread
From: Thierry Reding @ 2018-03-27 22:14 UTC (permalink / raw)
  To: Ladislav Michl, Tony Lindgren
  Cc: linux-pwm, aaro.koskinen, Keerthy, daniel.lezcano, t-kristo,
	narmstrong, robh+dt, Thomas Gleixner, Brecht Neyrinck,
	sebastian.reichel, grygorii.strashko, linux-omap, Claudiu.Beznea,
	linux-arm-kernel


[-- Attachment #1.1: Type: text/plain, Size: 1121 bytes --]

On Tue, Mar 27, 2018 at 11:53:33PM +0200, Thierry Reding wrote:
> On Fri, Feb 23, 2018 at 11:15:53AM +0100, Ladislav Michl wrote:
> > Prescaler setting is currently not taken into account.
> > Fix that by introducing freq member variable and initialize
> > it at device probe time. This also avoids frequency
> > recomputing at each pwm configure time.
> > 
> > Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
> > ---
> >  drivers/pwm/pwm-omap-dmtimer.c | 93 +++++++++++++++++++++++++-----------------
> >  1 file changed, 55 insertions(+), 38 deletions(-)
> 
> Applied, thanks.

Actually, that was a little premature. It seems like this conflicts with
a patch series by Keerthy that Tony merged into his tree and that you've
based this on.

I think it'd be easiest if Tony merged this through the TI tree, or we
wait until v4.17-rc1 to resolve the dependency. Given how late we are in
the release cycle, I think it'd have to be the latter.

Tony, if you think you can find a way to still take this in for
v4.17-rc1, feel free to do so:

Acked-by: Thierry Reding <thierry.reding@gmail.com>

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 176 bytes --]

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 4/6] pwm: pwm-omap-dmtimer: Fix frequency when using prescaler
@ 2018-03-27 22:14       ` Thierry Reding
  0 siblings, 0 replies; 30+ messages in thread
From: Thierry Reding @ 2018-03-27 22:14 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Mar 27, 2018 at 11:53:33PM +0200, Thierry Reding wrote:
> On Fri, Feb 23, 2018 at 11:15:53AM +0100, Ladislav Michl wrote:
> > Prescaler setting is currently not taken into account.
> > Fix that by introducing freq member variable and initialize
> > it at device probe time. This also avoids frequency
> > recomputing at each pwm configure time.
> > 
> > Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
> > ---
> >  drivers/pwm/pwm-omap-dmtimer.c | 93 +++++++++++++++++++++++++-----------------
> >  1 file changed, 55 insertions(+), 38 deletions(-)
> 
> Applied, thanks.

Actually, that was a little premature. It seems like this conflicts with
a patch series by Keerthy that Tony merged into his tree and that you've
based this on.

I think it'd be easiest if Tony merged this through the TI tree, or we
wait until v4.17-rc1 to resolve the dependency. Given how late we are in
the release cycle, I think it'd have to be the latter.

Tony, if you think you can find a way to still take this in for
v4.17-rc1, feel free to do so:

Acked-by: Thierry Reding <thierry.reding@gmail.com>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20180328/c2b783c6/attachment.sig>

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 4/6] pwm: pwm-omap-dmtimer: Fix frequency when using prescaler
  2018-03-27 22:14       ` Thierry Reding
@ 2018-03-27 22:23         ` Tony Lindgren
  -1 siblings, 0 replies; 30+ messages in thread
From: Tony Lindgren @ 2018-03-27 22:23 UTC (permalink / raw)
  To: Thierry Reding
  Cc: linux-pwm, Ladislav Michl, aaro.koskinen, Keerthy,
	daniel.lezcano, t-kristo, narmstrong, sebastian.reichel, robh+dt,
	Thomas Gleixner, Brecht Neyrinck, grygorii.strashko, linux-omap,
	Claudiu.Beznea, linux-arm-kernel

* Thierry Reding <thierry.reding@gmail.com> [180327 22:15]:
> On Tue, Mar 27, 2018 at 11:53:33PM +0200, Thierry Reding wrote:
> > On Fri, Feb 23, 2018 at 11:15:53AM +0100, Ladislav Michl wrote:
> > > Prescaler setting is currently not taken into account.
> > > Fix that by introducing freq member variable and initialize
> > > it at device probe time. This also avoids frequency
> > > recomputing at each pwm configure time.
> > > 
> > > Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
> > > ---
> > >  drivers/pwm/pwm-omap-dmtimer.c | 93 +++++++++++++++++++++++++-----------------
> > >  1 file changed, 55 insertions(+), 38 deletions(-)
> > 
> > Applied, thanks.
> 
> Actually, that was a little premature. It seems like this conflicts with
> a patch series by Keerthy that Tony merged into his tree and that you've
> based this on.
> 
> I think it'd be easiest if Tony merged this through the TI tree, or we
> wait until v4.17-rc1 to resolve the dependency. Given how late we are in
> the release cycle, I think it'd have to be the latter.

Sorry about the extra hassle caused by the timer move to drivers.

> Tony, if you think you can find a way to still take this in for
> v4.17-rc1, feel free to do so:
> 
> Acked-by: Thierry Reding <thierry.reding@gmail.com>

I pretty much only apply fixes after -rc6. So let's wait for the
dependencies to clear at this point. This seems like a "fix for
a feature that never worked" so might be hard to justify it as
a fix :)

Ladis, can you please resend the pending patches again to
Thierry after v4.17-rc? Then Thierry can queue it as a fix or
for v4.18.

Regards,

Tony

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 4/6] pwm: pwm-omap-dmtimer: Fix frequency when using prescaler
@ 2018-03-27 22:23         ` Tony Lindgren
  0 siblings, 0 replies; 30+ messages in thread
From: Tony Lindgren @ 2018-03-27 22:23 UTC (permalink / raw)
  To: linux-arm-kernel

* Thierry Reding <thierry.reding@gmail.com> [180327 22:15]:
> On Tue, Mar 27, 2018 at 11:53:33PM +0200, Thierry Reding wrote:
> > On Fri, Feb 23, 2018 at 11:15:53AM +0100, Ladislav Michl wrote:
> > > Prescaler setting is currently not taken into account.
> > > Fix that by introducing freq member variable and initialize
> > > it at device probe time. This also avoids frequency
> > > recomputing at each pwm configure time.
> > > 
> > > Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
> > > ---
> > >  drivers/pwm/pwm-omap-dmtimer.c | 93 +++++++++++++++++++++++++-----------------
> > >  1 file changed, 55 insertions(+), 38 deletions(-)
> > 
> > Applied, thanks.
> 
> Actually, that was a little premature. It seems like this conflicts with
> a patch series by Keerthy that Tony merged into his tree and that you've
> based this on.
> 
> I think it'd be easiest if Tony merged this through the TI tree, or we
> wait until v4.17-rc1 to resolve the dependency. Given how late we are in
> the release cycle, I think it'd have to be the latter.

Sorry about the extra hassle caused by the timer move to drivers.

> Tony, if you think you can find a way to still take this in for
> v4.17-rc1, feel free to do so:
> 
> Acked-by: Thierry Reding <thierry.reding@gmail.com>

I pretty much only apply fixes after -rc6. So let's wait for the
dependencies to clear at this point. This seems like a "fix for
a feature that never worked" so might be hard to justify it as
a fix :)

Ladis, can you please resend the pending patches again to
Thierry after v4.17-rc? Then Thierry can queue it as a fix or
for v4.18.

Regards,

Tony

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 4/6] pwm: pwm-omap-dmtimer: Fix frequency when using prescaler
  2018-03-27 22:23         ` Tony Lindgren
@ 2018-03-28  0:34           ` Ladislav Michl
  -1 siblings, 0 replies; 30+ messages in thread
From: Ladislav Michl @ 2018-03-28  0:34 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: linux-pwm, aaro.koskinen, Keerthy, daniel.lezcano, t-kristo,
	robh+dt, narmstrong, Thierry Reding, Thomas Gleixner,
	Brecht Neyrinck, sebastian.reichel, grygorii.strashko,
	linux-omap, Claudiu.Beznea, linux-arm-kernel

On Tue, Mar 27, 2018 at 03:23:49PM -0700, Tony Lindgren wrote:
> * Thierry Reding <thierry.reding@gmail.com> [180327 22:15]:
> > On Tue, Mar 27, 2018 at 11:53:33PM +0200, Thierry Reding wrote:
> > > On Fri, Feb 23, 2018 at 11:15:53AM +0100, Ladislav Michl wrote:
> > > > Prescaler setting is currently not taken into account.
> > > > Fix that by introducing freq member variable and initialize
> > > > it at device probe time. This also avoids frequency
> > > > recomputing at each pwm configure time.
> > > > 
> > > > Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
> > > > ---
> > > >  drivers/pwm/pwm-omap-dmtimer.c | 93 +++++++++++++++++++++++++-----------------
> > > >  1 file changed, 55 insertions(+), 38 deletions(-)
> > > 
> > > Applied, thanks.
> > 
> > Actually, that was a little premature. It seems like this conflicts with
> > a patch series by Keerthy that Tony merged into his tree and that you've
> > based this on.
> > 
> > I think it'd be easiest if Tony merged this through the TI tree, or we
> > wait until v4.17-rc1 to resolve the dependency. Given how late we are in
> > the release cycle, I think it'd have to be the latter.
> 
> Sorry about the extra hassle caused by the timer move to drivers.
> 
> > Tony, if you think you can find a way to still take this in for
> > v4.17-rc1, feel free to do so:
> > 
> > Acked-by: Thierry Reding <thierry.reding@gmail.com>
> 
> I pretty much only apply fixes after -rc6. So let's wait for the
> dependencies to clear at this point. This seems like a "fix for
> a feature that never worked" so might be hard to justify it as
> a fix :)

Well, DT bindings already contain prescaler, so technically it is
a fix which also optimizes code a bit ;-) But of course, I can keep
this patch localy and resend for 4.18 merge window.

> Ladis, can you please resend the pending patches again to
> Thierry after v4.17-rc? Then Thierry can queue it as a fix or
> for v4.18.

In fact, there is the only one patch ready to be applied - this one - and
The others (event capture) needs to be yet sorted out. Unfortunately I do
not have time for that at the moment.

Best regards,
	ladis

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 4/6] pwm: pwm-omap-dmtimer: Fix frequency when using prescaler
@ 2018-03-28  0:34           ` Ladislav Michl
  0 siblings, 0 replies; 30+ messages in thread
From: Ladislav Michl @ 2018-03-28  0:34 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Mar 27, 2018 at 03:23:49PM -0700, Tony Lindgren wrote:
> * Thierry Reding <thierry.reding@gmail.com> [180327 22:15]:
> > On Tue, Mar 27, 2018 at 11:53:33PM +0200, Thierry Reding wrote:
> > > On Fri, Feb 23, 2018 at 11:15:53AM +0100, Ladislav Michl wrote:
> > > > Prescaler setting is currently not taken into account.
> > > > Fix that by introducing freq member variable and initialize
> > > > it at device probe time. This also avoids frequency
> > > > recomputing at each pwm configure time.
> > > > 
> > > > Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
> > > > ---
> > > >  drivers/pwm/pwm-omap-dmtimer.c | 93 +++++++++++++++++++++++++-----------------
> > > >  1 file changed, 55 insertions(+), 38 deletions(-)
> > > 
> > > Applied, thanks.
> > 
> > Actually, that was a little premature. It seems like this conflicts with
> > a patch series by Keerthy that Tony merged into his tree and that you've
> > based this on.
> > 
> > I think it'd be easiest if Tony merged this through the TI tree, or we
> > wait until v4.17-rc1 to resolve the dependency. Given how late we are in
> > the release cycle, I think it'd have to be the latter.
> 
> Sorry about the extra hassle caused by the timer move to drivers.
> 
> > Tony, if you think you can find a way to still take this in for
> > v4.17-rc1, feel free to do so:
> > 
> > Acked-by: Thierry Reding <thierry.reding@gmail.com>
> 
> I pretty much only apply fixes after -rc6. So let's wait for the
> dependencies to clear at this point. This seems like a "fix for
> a feature that never worked" so might be hard to justify it as
> a fix :)

Well, DT bindings already contain prescaler, so technically it is
a fix which also optimizes code a bit ;-) But of course, I can keep
this patch localy and resend for 4.18 merge window.

> Ladis, can you please resend the pending patches again to
> Thierry after v4.17-rc? Then Thierry can queue it as a fix or
> for v4.18.

In fact, there is the only one patch ready to be applied - this one - and
The others (event capture) needs to be yet sorted out. Unfortunately I do
not have time for that at the moment.

Best regards,
	ladis

^ permalink raw reply	[flat|nested] 30+ messages in thread

end of thread, other threads:[~2018-03-28  0:34 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-02-23 10:12 [PATCH 0/6] Implement event capture for OMAP (draft) Ladislav Michl
2018-02-23 10:12 ` Ladislav Michl
2018-02-23 10:13 ` [PATCH 1/6] clocksource: timer-ti-dm: Make unexported functions static Ladislav Michl
2018-02-23 10:13   ` Ladislav Michl
2018-02-27 18:06   ` Tony Lindgren
2018-02-27 18:06     ` Tony Lindgren
2018-02-27 19:07     ` Ladislav Michl
2018-02-27 19:07       ` Ladislav Michl
2018-02-27 19:23       ` Tony Lindgren
2018-02-27 19:23         ` Tony Lindgren
2018-02-28 22:11         ` Tony Lindgren
2018-02-28 22:11           ` Tony Lindgren
2018-02-23 10:14 ` [PATCH 2/6] clocksource: timer-ti-dm: Consolidate set source Ladislav Michl
2018-02-23 10:14   ` Ladislav Michl
2018-02-23 10:15 ` [PATCH 3/6] clocksource: timer-ti-dm: Check prescaler value Ladislav Michl
2018-02-23 10:15   ` Ladislav Michl
2018-02-23 10:15 ` [PATCH 4/6] pwm: pwm-omap-dmtimer: Fix frequency when using prescaler Ladislav Michl
2018-02-23 10:15   ` Ladislav Michl
2018-03-27 21:53   ` Thierry Reding
2018-03-27 21:53     ` Thierry Reding
2018-03-27 22:14     ` Thierry Reding
2018-03-27 22:14       ` Thierry Reding
2018-03-27 22:23       ` Tony Lindgren
2018-03-27 22:23         ` Tony Lindgren
2018-03-28  0:34         ` Ladislav Michl
2018-03-28  0:34           ` Ladislav Michl
2018-02-23 10:16 ` [PATCH 5/6] clocksource: timer-ti-dm: Add event capture Ladislav Michl
2018-02-23 10:16   ` Ladislav Michl
2018-02-23 10:17 ` [PATCH 6/6] pwm: pwm-omap-dmtimer: Add capture functionality Ladislav Michl
2018-02-23 10:17   ` Ladislav Michl

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.