Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1223397 > unrolled thread

[PATCH v2 1/3] net: irda: pxaficp_ir: use sched_clock() for time management

Started byRobert Jarzmik <robert.jarzmik@free.fr>
First post2015-09-12 14:30 +0200
Last post2015-09-22 01:20 +0200
Articles 7 — 2 participants

Back to article view | Back to linux.kernel


Contents

  [PATCH v2 1/3] net: irda: pxaficp_ir: use sched_clock() for time management Robert Jarzmik <robert.jarzmik@free.fr> - 2015-09-12 14:30 +0200
    [PATCH v2 3/3] net: irda: pxaficp_ir: dmaengine conversion Robert Jarzmik <robert.jarzmik@free.fr> - 2015-09-12 14:30 +0200
    Re: [PATCH v2 1/3] net: irda: pxaficp_ir: use sched_clock() for  time management David Miller <davem@davemloft.net> - 2015-09-16 01:50 +0200
      Re: [PATCH v2 1/3] net: irda: pxaficp_ir: use sched_clock() for time management Robert Jarzmik <robert.jarzmik@free.fr> - 2015-09-16 11:40 +0200
        Re: [PATCH v2 1/3] net: irda: pxaficp_ir: use sched_clock() for  time management David Miller <davem@davemloft.net> - 2015-09-18 00:00 +0200
          Re: [PATCH v2 1/3] net: irda: pxaficp_ir: use sched_clock() for time management Robert Jarzmik <robert.jarzmik@free.fr> - 2015-09-18 18:50 +0200
            Re: [PATCH v2 1/3] net: irda: pxaficp_ir: use sched_clock() for  time management David Miller <davem@davemloft.net> - 2015-09-22 01:20 +0200

#1223397 — [PATCH v2 1/3] net: irda: pxaficp_ir: use sched_clock() for time management

FromRobert Jarzmik <robert.jarzmik@free.fr>
Date2015-09-12 14:30 +0200
Subject[PATCH v2 1/3] net: irda: pxaficp_ir: use sched_clock() for time management
Message-ID<q7S6l-oH-3@gated-at.bofh.it>
Instead of using directly the OS timer through direct register access,
use the standard sched_clock(), which will end up in OSCR reading
anyway.

This is a first step for direct access register removal and machine
specific code removal from this driver.

Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
---
 drivers/net/irda/pxaficp_ir.c | 15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/drivers/net/irda/pxaficp_ir.c b/drivers/net/irda/pxaficp_ir.c
index 100454662e4b..b1794998c68e 100644
--- a/drivers/net/irda/pxaficp_ir.c
+++ b/drivers/net/irda/pxaficp_ir.c
@@ -29,7 +29,6 @@
 
 #include <mach/dma.h>
 #include <linux/platform_data/irda-pxaficp.h>
-#include <mach/regs-ost.h>
 #include <mach/regs-uart.h>
 
 #define FICP		__REG(0x40800000)  /* Start of FICP area */
@@ -102,7 +101,7 @@
 struct pxa_irda {
 	int			speed;
 	int			newspeed;
-	unsigned long		last_oscr;
+	unsigned long long	last_clk;
 
 	unsigned char		*dma_rx_buff;
 	unsigned char		*dma_tx_buff;
@@ -292,7 +291,7 @@ static irqreturn_t pxa_irda_sir_irq(int irq, void *dev_id)
 			}
 			lsr = STLSR;
 		}
-		si->last_oscr = readl_relaxed(OSCR);
+		si->last_clk = sched_clock();
 		break;
 
 	case 0x04: /* Received Data Available */
@@ -303,7 +302,7 @@ static irqreturn_t pxa_irda_sir_irq(int irq, void *dev_id)
 		    dev->stats.rx_bytes++;
 	            async_unwrap_char(dev, &dev->stats, &si->rx_buff, STRBR);
 	  	} while (STLSR & LSR_DR);
-		si->last_oscr = readl_relaxed(OSCR);
+		si->last_clk = sched_clock();
 	  	break;
 
 	case 0x02: /* Transmit FIFO Data Request */
@@ -319,7 +318,7 @@ static irqreturn_t pxa_irda_sir_irq(int irq, void *dev_id)
                         /* We need to ensure that the transmitter has finished. */
 			while ((STLSR & LSR_TEMT) == 0)
 				cpu_relax();
-			si->last_oscr = readl_relaxed(OSCR);
+			si->last_clk = sched_clock();
 
 			/*
 		 	* Ok, we've finished transmitting.  Now enable
@@ -373,7 +372,7 @@ static void pxa_irda_fir_dma_tx_irq(int channel, void *data)
 
 	while (ICSR1 & ICSR1_TBY)
 		cpu_relax();
-	si->last_oscr = readl_relaxed(OSCR);
+	si->last_clk = sched_clock();
 
 	/*
 	 * HACK: It looks like the TBY bit is dropped too soon.
@@ -473,8 +472,8 @@ static irqreturn_t pxa_irda_fir_irq(int irq, void *dev_id)
 
 	/* stop RX DMA */
 	DCSR(si->rxdma) &= ~DCSR_RUN;
-	si->last_oscr = readl_relaxed(OSCR);
 	icsr0 = ICSR0;
+	si->last_clk = sched_clock();
 
 	if (icsr0 & (ICSR0_FRE | ICSR0_RAB)) {
 		if (icsr0 & ICSR0_FRE) {
@@ -549,7 +548,7 @@ static int pxa_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev)
 		skb_copy_from_linear_data(skb, si->dma_tx_buff, skb->len);
 
 		if (mtt)
-			while ((unsigned)(readl_relaxed(OSCR) - si->last_oscr)/4 < mtt)
+			while ((sched_clock() - si->last_clk) / 4 < mtt)
 				cpu_relax();
 
 		/* stop RX DMA,  disable FICP */
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [next] | [standalone]


#1223399 — [PATCH v2 3/3] net: irda: pxaficp_ir: dmaengine conversion

FromRobert Jarzmik <robert.jarzmik@free.fr>
Date2015-09-12 14:30 +0200
Subject[PATCH v2 3/3] net: irda: pxaficp_ir: dmaengine conversion
Message-ID<q7S6l-oH-5@gated-at.bofh.it>
In reply to#1223397
Convert pxaficp_ir to dmaengine. As pxa architecture is shifting from
raw DMA registers access to pxa_dma dmaengine driver, convert this
driver to dmaengine.

Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
---
Since v1: removed mach/dma.h include, which is the goal
---
 drivers/net/irda/pxaficp_ir.c | 149 +++++++++++++++++++++++++++++-------------
 1 file changed, 102 insertions(+), 47 deletions(-)

diff --git a/drivers/net/irda/pxaficp_ir.c b/drivers/net/irda/pxaficp_ir.c
index 4a2b3f71e4a8..c0b80548a43d 100644
--- a/drivers/net/irda/pxaficp_ir.c
+++ b/drivers/net/irda/pxaficp_ir.c
@@ -19,6 +19,9 @@
 #include <linux/etherdevice.h>
 #include <linux/platform_device.h>
 #include <linux/clk.h>
+#include <linux/dmaengine.h>
+#include <linux/dma-mapping.h>
+#include <linux/dma/pxa-dma.h>
 #include <linux/gpio.h>
 #include <linux/slab.h>
 
@@ -27,7 +30,6 @@
 #include <net/irda/wrapper.h>
 #include <net/irda/irda_device.h>
 
-#include <mach/dma.h>
 #include <linux/platform_data/irda-pxaficp.h>
 #undef __REG
 #define __REG(x) ((x) & 0xffff)
@@ -146,8 +148,12 @@ struct pxa_irda {
 	dma_addr_t		dma_rx_buff_phy;
 	dma_addr_t		dma_tx_buff_phy;
 	unsigned int		dma_tx_buff_len;
-	int			txdma;
-	int			rxdma;
+	struct dma_chan		*txdma;
+	struct dma_chan		*rxdma;
+	dma_cookie_t		rx_cookie;
+	dma_cookie_t		tx_cookie;
+	int			drcmr_rx;
+	int			drcmr_tx;
 
 	int			uart_irq;
 	int			icp_irq;
@@ -165,6 +171,8 @@ struct pxa_irda {
 	struct clk		*cur_clk;
 };
 
+static int pxa_irda_set_speed(struct pxa_irda *si, int speed);
+
 static inline void pxa_irda_disable_clk(struct pxa_irda *si)
 {
 	if (si->cur_clk)
@@ -188,22 +196,41 @@ static inline void pxa_irda_enable_sirclk(struct pxa_irda *si)
 #define IS_FIR(si)		((si)->speed >= 4000000)
 #define IRDA_FRAME_SIZE_LIMIT	2047
 
+static void pxa_irda_fir_dma_rx_irq(void *data);
+static void pxa_irda_fir_dma_tx_irq(void *data);
+
 inline static void pxa_irda_fir_dma_rx_start(struct pxa_irda *si)
 {
-	DCSR(si->rxdma)  = DCSR_NODESC;
-	DSADR(si->rxdma) = (unsigned long)si->irda_base + ICDR;
-	DTADR(si->rxdma) = si->dma_rx_buff_phy;
-	DCMD(si->rxdma) = DCMD_INCTRGADDR | DCMD_FLOWSRC |  DCMD_WIDTH1 | DCMD_BURST32 | IRDA_FRAME_SIZE_LIMIT;
-	DCSR(si->rxdma) |= DCSR_RUN;
+	struct dma_async_tx_descriptor *tx;
+
+	tx = dmaengine_prep_slave_single(si->rxdma, si->dma_rx_buff_phy,
+					 IRDA_FRAME_SIZE_LIMIT, DMA_FROM_DEVICE,
+					 DMA_PREP_INTERRUPT);
+	if (!tx) {
+		dev_err(si->dev, "prep_slave_sg() failed\n");
+		return;
+	}
+	tx->callback = pxa_irda_fir_dma_rx_irq;
+	tx->callback_param = si;
+	si->rx_cookie = dmaengine_submit(tx);
+	dma_async_issue_pending(si->rxdma);
 }
 
 inline static void pxa_irda_fir_dma_tx_start(struct pxa_irda *si)
 {
-	DCSR(si->txdma)  = DCSR_NODESC;
-	DSADR(si->txdma) = si->dma_tx_buff_phy;
-	DTADR(si->txdma) = (unsigned long)si->irda_base + ICDR;
-	DCMD(si->txdma) = DCMD_INCSRCADDR | DCMD_FLOWTRG |  DCMD_ENDIRQEN | DCMD_WIDTH1 | DCMD_BURST32 | si->dma_tx_buff_len;
-	DCSR(si->txdma) |= DCSR_RUN;
+	struct dma_async_tx_descriptor *tx;
+
+	tx = dmaengine_prep_slave_single(si->txdma, si->dma_tx_buff_phy,
+					 si->dma_tx_buff_len, DMA_TO_DEVICE,
+					 DMA_PREP_INTERRUPT);
+	if (!tx) {
+		dev_err(si->dev, "prep_slave_sg() failed\n");
+		return;
+	}
+	tx->callback = pxa_irda_fir_dma_tx_irq;
+	tx->callback_param = si;
+	si->tx_cookie = dmaengine_submit(tx);
+	dma_async_issue_pending(si->rxdma);
 }
 
 /*
@@ -242,7 +269,7 @@ static int pxa_irda_set_speed(struct pxa_irda *si, int speed)
 
 		if (IS_FIR(si)) {
 			/* stop RX DMA */
-			DCSR(si->rxdma) &= ~DCSR_RUN;
+			dmaengine_terminate_all(si->rxdma);
 			/* disable FICP */
 			ficp_writel(si, 0, ICCR0);
 			pxa_irda_disable_clk(si);
@@ -388,30 +415,27 @@ static irqreturn_t pxa_irda_sir_irq(int irq, void *dev_id)
 }
 
 /* FIR Receive DMA interrupt handler */
-static void pxa_irda_fir_dma_rx_irq(int channel, void *data)
+static void pxa_irda_fir_dma_rx_irq(void *data)
 {
-	int dcsr = DCSR(channel);
-
-	DCSR(channel) = dcsr & ~DCSR_RUN;
+	struct net_device *dev = data;
+	struct pxa_irda *si = netdev_priv(dev);
 
-	printk(KERN_DEBUG "pxa_ir: fir rx dma bus error %#x\n", dcsr);
+	dmaengine_terminate_all(si->rxdma);
+	netdev_dbg(dev, "pxa_ir: fir rx dma bus error\n");
 }
 
 /* FIR Transmit DMA interrupt handler */
-static void pxa_irda_fir_dma_tx_irq(int channel, void *data)
+static void pxa_irda_fir_dma_tx_irq(void *data)
 {
 	struct net_device *dev = data;
 	struct pxa_irda *si = netdev_priv(dev);
-	int dcsr;
-
-	dcsr = DCSR(channel);
-	DCSR(channel) = dcsr & ~DCSR_RUN;
 
-	if (dcsr & DCSR_ENDINTR)  {
+	dmaengine_terminate_all(si->txdma);
+	if (dmaengine_tx_status(si->txdma, si->tx_cookie, NULL) == DMA_ERROR) {
+		dev->stats.tx_errors++;
+	} else {
 		dev->stats.tx_packets++;
 		dev->stats.tx_bytes += si->dma_tx_buff_len;
-	} else {
-		dev->stats.tx_errors++;
 	}
 
 	while (ficp_readl(si, ICSR1) & ICSR1_TBY)
@@ -446,9 +470,12 @@ static void pxa_irda_fir_dma_tx_irq(int channel, void *data)
 static void pxa_irda_fir_irq_eif(struct pxa_irda *si, struct net_device *dev, int icsr0)
 {
 	unsigned int len, stat, data;
+	struct dma_tx_state state;
 
 	/* Get the current data position. */
-	len = DTADR(si->rxdma) - si->dma_rx_buff_phy;
+
+	dmaengine_tx_status(si->rxdma, si->rx_cookie, &state);
+	len = IRDA_FRAME_SIZE_LIMIT - state.residue;
 
 	do {
 		/* Read Status, and then Data. 	 */
@@ -515,7 +542,7 @@ static irqreturn_t pxa_irda_fir_irq(int irq, void *dev_id)
 	int icsr0, i = 64;
 
 	/* stop RX DMA */
-	DCSR(si->rxdma) &= ~DCSR_RUN;
+	dmaengine_terminate_all(si->rxdma);
 	si->last_clk = sched_clock();
 	icsr0 = ficp_readl(si, ICSR0);
 
@@ -597,7 +624,7 @@ static int pxa_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev)
 				cpu_relax();
 
 		/* stop RX DMA,  disable FICP */
-		DCSR(si->rxdma) &= ~DCSR_RUN;
+		dmaengine_terminate_all(si->rxdma);
 		ficp_writel(si, 0, ICCR0);
 
 		pxa_irda_fir_dma_tx_start(si);
@@ -670,10 +697,6 @@ static void pxa_irda_startup(struct pxa_irda *si)
 	/* configure FICP ICCR2 */
 	ficp_writel(si, ICCR2_TXP | ICCR2_TRIG_32, ICCR2);
 
-	/* configure DMAC */
-	DRCMR(17) = si->rxdma | DRCMR_MAPVLD;
-	DRCMR(18) = si->txdma | DRCMR_MAPVLD;
-
 	/* force SIR reinitialization */
 	si->speed = 4000000;
 	pxa_irda_set_speed(si, 9600);
@@ -693,17 +716,14 @@ static void pxa_irda_shutdown(struct pxa_irda *si)
 	stuart_writel(si, 0, STISR);
 
 	/* disable DMA */
-	DCSR(si->txdma) &= ~DCSR_RUN;
-	DCSR(si->rxdma) &= ~DCSR_RUN;
+	dmaengine_terminate_all(si->rxdma);
+	dmaengine_terminate_all(si->txdma);
 	/* disable FICP */
 	ficp_writel(si, 0, ICCR0);
 
 	/* disable the STUART or FICP clocks */
 	pxa_irda_disable_clk(si);
 
-	DRCMR(17) = 0;
-	DRCMR(18) = 0;
-
 	local_irq_restore(flags);
 
 	/* power off board transceiver */
@@ -715,6 +735,9 @@ static void pxa_irda_shutdown(struct pxa_irda *si)
 static int pxa_irda_start(struct net_device *dev)
 {
 	struct pxa_irda *si = netdev_priv(dev);
+	dma_cap_mask_t mask;
+	struct dma_slave_config	config;
+	struct pxad_param param;
 	int err;
 
 	si->speed = 9600;
@@ -734,14 +757,37 @@ static int pxa_irda_start(struct net_device *dev)
 	disable_irq(si->icp_irq);
 
 	err = -EBUSY;
-	si->rxdma = pxa_request_dma("FICP_RX",DMA_PRIO_LOW, pxa_irda_fir_dma_rx_irq, dev);
-	if (si->rxdma < 0)
+	dma_cap_zero(mask);
+	dma_cap_set(DMA_SLAVE, mask);
+	param.prio = PXAD_PRIO_LOWEST;
+
+	memset(&config, 0, sizeof(config));
+	config.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
+	config.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
+	config.src_addr = (dma_addr_t)si->irda_base + ICDR;
+	config.dst_addr = (dma_addr_t)si->irda_base + ICDR;
+	config.src_maxburst = 32;
+	config.dst_maxburst = 32;
+
+	param.drcmr = si->drcmr_rx;
+	si->rxdma = dma_request_slave_channel_compat(mask, pxad_filter_fn,
+						     &param, &dev->dev, "rx");
+	if (!si->rxdma)
 		goto err_rx_dma;
 
-	si->txdma = pxa_request_dma("FICP_TX",DMA_PRIO_LOW, pxa_irda_fir_dma_tx_irq, dev);
-	if (si->txdma < 0)
+	param.drcmr = si->drcmr_tx;
+	si->txdma = dma_request_slave_channel_compat(mask, pxad_filter_fn,
+						     &param, &dev->dev, "tx");
+	if (!si->txdma)
 		goto err_tx_dma;
 
+	err = dmaengine_slave_config(si->rxdma, &config);
+	if (err)
+		goto err_dma_rx_buff;
+	err = dmaengine_slave_config(si->txdma, &config);
+	if (err)
+		goto err_dma_rx_buff;
+
 	err = -ENOMEM;
 	si->dma_rx_buff = dma_alloc_coherent(si->dev, IRDA_FRAME_SIZE_LIMIT,
 					     &si->dma_rx_buff_phy, GFP_KERNEL);
@@ -781,9 +827,9 @@ err_irlap:
 err_dma_tx_buff:
 	dma_free_coherent(si->dev, IRDA_FRAME_SIZE_LIMIT, si->dma_rx_buff, si->dma_rx_buff_phy);
 err_dma_rx_buff:
-	pxa_free_dma(si->txdma);
+	dma_release_channel(si->txdma);
 err_tx_dma:
-	pxa_free_dma(si->rxdma);
+	dma_release_channel(si->rxdma);
 err_rx_dma:
 	free_irq(si->icp_irq, dev);
 err_irq2:
@@ -810,8 +856,10 @@ static int pxa_irda_stop(struct net_device *dev)
 	free_irq(si->uart_irq, dev);
 	free_irq(si->icp_irq, dev);
 
-	pxa_free_dma(si->rxdma);
-	pxa_free_dma(si->txdma);
+	dmaengine_terminate_all(si->rxdma);
+	dmaengine_terminate_all(si->txdma);
+	dma_release_channel(si->rxdma);
+	dma_release_channel(si->txdma);
 
 	if (si->dma_rx_buff)
 		dma_free_coherent(si->dev, IRDA_FRAME_SIZE_LIMIT, si->dma_tx_buff, si->dma_tx_buff_phy);
@@ -920,6 +968,13 @@ static int pxa_irda_probe(struct platform_device *pdev)
 		goto err_mem_4;
 	}
 
+	res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
+	if (res)
+		si->drcmr_rx = res->start;
+	res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
+	if (res)
+		si->drcmr_tx = res->start;
+
 	/*
 	 * Initialise the SIR buffers
 	 */
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1225590 — Re: [PATCH v2 1/3] net: irda: pxaficp_ir: use sched_clock() for time management

FromDavid Miller <davem@davemloft.net>
Date2015-09-16 01:50 +0200
SubjectRe: [PATCH v2 1/3] net: irda: pxaficp_ir: use sched_clock() for time management
Message-ID<q9894-40S-3@gated-at.bofh.it>
In reply to#1223397
From: Robert Jarzmik <robert.jarzmik@free.fr>
Date: Sat, 12 Sep 2015 13:45:22 +0200

> Instead of using directly the OS timer through direct register access,
> use the standard sched_clock(), which will end up in OSCR reading
> anyway.
> 
> This is a first step for direct access register removal and machine
> specific code removal from this driver.
> 
> Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>

What is the granularity of the OSCR register?

If it is not nanoseconds, then you need to adjust calculations
such as this one:

> @@ -549,7 +548,7 @@ static int pxa_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev)
>  		skb_copy_from_linear_data(skb, si->dma_tx_buff, skb->len);
>  
>  		if (mtt)
> -			while ((unsigned)(readl_relaxed(OSCR) - si->last_oscr)/4 < mtt)
> +			while ((sched_clock() - si->last_clk) / 4 < mtt)
>  				cpu_relax();
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1225896

FromRobert Jarzmik <robert.jarzmik@free.fr>
Date2015-09-16 11:40 +0200
Message-ID<q9hm4-uy-35@gated-at.bofh.it>
In reply to#1225590
David Miller <davem@davemloft.net> writes:

> From: Robert Jarzmik <robert.jarzmik@free.fr>
> Date: Sat, 12 Sep 2015 13:45:22 +0200
>
>> Instead of using directly the OS timer through direct register access,
>> use the standard sched_clock(), which will end up in OSCR reading
>> anyway.
>> 
>> This is a first step for direct access register removal and machine
>> specific code removal from this driver.
>> 
>> Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
>
> What is the granularity of the OSCR register?
It's 307ns (ie. 3.25MHz clock).

> If it is not nanoseconds, then you need to adjust calculations
> such as this one:
Tell me if the 307ns requires something I should adjust.

My understanding is that the flow will be :
 sched_clock()
   rd->read_sched_clock() (cyc_to_ns() transformed for return)
     pxa_read_sched_clock()
       readl_relaxed(OSCR)

I didn't see any timings issue, as the flow looks equivalent to the readl(OSCR),
but I might have overlooked something.

Cheers.

-- 
Robert
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1227430 — Re: [PATCH v2 1/3] net: irda: pxaficp_ir: use sched_clock() for time management

FromDavid Miller <davem@davemloft.net>
Date2015-09-18 00:00 +0200
SubjectRe: [PATCH v2 1/3] net: irda: pxaficp_ir: use sched_clock() for time management
Message-ID<q9PnH-85q-7@gated-at.bofh.it>
In reply to#1225896
From: Robert Jarzmik <robert.jarzmik@free.fr>
Date: Wed, 16 Sep 2015 11:34:01 +0200

> David Miller <davem@davemloft.net> writes:
> 
>> From: Robert Jarzmik <robert.jarzmik@free.fr>
>> Date: Sat, 12 Sep 2015 13:45:22 +0200
>>
>>> Instead of using directly the OS timer through direct register access,
>>> use the standard sched_clock(), which will end up in OSCR reading
>>> anyway.
>>> 
>>> This is a first step for direct access register removal and machine
>>> specific code removal from this driver.
>>> 
>>> Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
>>
>> What is the granularity of the OSCR register?
> It's 307ns (ie. 3.25MHz clock).
> 
>> If it is not nanoseconds, then you need to adjust calculations
>> such as this one:
> Tell me if the 307ns requires something I should adjust.
> 
> My understanding is that the flow will be :
>  sched_clock()
>    rd->read_sched_clock() (cyc_to_ns() transformed for return)
>      pxa_read_sched_clock()
>        readl_relaxed(OSCR)
> 
> I didn't see any timings issue, as the flow looks equivalent to the readl(OSCR),
> but I might have overlooked something.

Of course it's different, because sched_clock() converts the value read
from OSCR into nanoseconds, which is obviously different from using the
OSCR register value directly.

You're therefore feeding different values into this IRDA code.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1228164

FromRobert Jarzmik <robert.jarzmik@free.fr>
Date2015-09-18 18:50 +0200
Message-ID<qa71f-8fE-3@gated-at.bofh.it>
In reply to#1227430
David Miller <davem@davemloft.net> writes:

>> My understanding is that the flow will be :
>>  sched_clock()
>>    rd->read_sched_clock() (cyc_to_ns() transformed for return)
>>      pxa_read_sched_clock()
>>        readl_relaxed(OSCR)
>> 
>> I didn't see any timings issue, as the flow looks equivalent to the readl(OSCR),
>> but I might have overlooked something.
>
> Of course it's different, because sched_clock() converts the value read
> from OSCR into nanoseconds, which is obviously different from using the
> OSCR register value directly.
>
> You're therefore feeding different values into this IRDA code.
Ah yes, I see it.
Which brings me to wonder which is the more correct :
 (a) replace to reproduce the same calculation
     Previously mtt was compared to a difference of 76ns steps (as 307ns / 4 =
     76ns):
     while ((sched_clock() - si->last_clk) * 76 < mtt)

 (b) change the calculation assuming mtt is in microseconds :
     while ((sched_clock() - si->last_clk) * 1000 < mtt)

I have no IRDA protocol knowledge so unless someone points me to the correct
calculation I'll try my luck with (b).

Cheers.

-- 
Robert
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1229821 — Re: [PATCH v2 1/3] net: irda: pxaficp_ir: use sched_clock() for time management

FromDavid Miller <davem@davemloft.net>
Date2015-09-22 01:20 +0200
SubjectRe: [PATCH v2 1/3] net: irda: pxaficp_ir: use sched_clock() for time management
Message-ID<qbixk-4oB-7@gated-at.bofh.it>
In reply to#1228164
From: Robert Jarzmik <robert.jarzmik@free.fr>
Date: Fri, 18 Sep 2015 18:36:56 +0200

> Which brings me to wonder which is the more correct :
>  (a) replace to reproduce the same calculation
>      Previously mtt was compared to a difference of 76ns steps (as 307ns / 4 =
>      76ns):
>      while ((sched_clock() - si->last_clk) * 76 < mtt)
> 
>  (b) change the calculation assuming mtt is in microseconds :
>      while ((sched_clock() - si->last_clk) * 1000 < mtt)
> 
> I have no IRDA protocol knowledge so unless someone points me to the correct
> calculation I'll try my luck with (b).

"a" would be "safer" and less likely to break anything, although as
you say "b" might be more correct.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web