<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic iMX6 PWM Interrupt in i.MX Processors</title>
    <link>https://community.nxp.com/t5/i-MX-Processors/iMX6-PWM-Interrupt/m-p/470996#M74549</link>
    <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Hello all.&lt;/P&gt;&lt;P&gt;In iMX6 datasheet chapter 51 PWM&lt;/P&gt;&lt;P&gt;51.4.1.1 FIFO&lt;/P&gt;&lt;P&gt;Digital sample values can be loaded into the pulse-width modulator as 16-bit words. The&lt;/P&gt;&lt;P&gt;endianess can be changed using the BCTR and HCTR bits of the control register. A 4-&lt;/P&gt;&lt;P&gt;word (16-bit) FIFO minimizes interrupt overhead. &lt;SPAN style="color: #e23d39;"&gt;A maskable interrupt is generated&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="color: #e23d39;"&gt;when the number of data words&lt;/SPAN&gt; fall below the water level set by the FWM field in the&lt;/P&gt;&lt;P&gt;control register.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Give please an example how to request this interrupt in linux 3.10.53.&lt;/P&gt;&lt;P&gt;Thank you.&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
    <pubDate>Thu, 28 Jan 2016 09:19:45 GMT</pubDate>
    <dc:creator>evgenymolchanov</dc:creator>
    <dc:date>2016-01-28T09:19:45Z</dc:date>
    <item>
      <title>iMX6 PWM Interrupt</title>
      <link>https://community.nxp.com/t5/i-MX-Processors/iMX6-PWM-Interrupt/m-p/470996#M74549</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Hello all.&lt;/P&gt;&lt;P&gt;In iMX6 datasheet chapter 51 PWM&lt;/P&gt;&lt;P&gt;51.4.1.1 FIFO&lt;/P&gt;&lt;P&gt;Digital sample values can be loaded into the pulse-width modulator as 16-bit words. The&lt;/P&gt;&lt;P&gt;endianess can be changed using the BCTR and HCTR bits of the control register. A 4-&lt;/P&gt;&lt;P&gt;word (16-bit) FIFO minimizes interrupt overhead. &lt;SPAN style="color: #e23d39;"&gt;A maskable interrupt is generated&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="color: #e23d39;"&gt;when the number of data words&lt;/SPAN&gt; fall below the water level set by the FWM field in the&lt;/P&gt;&lt;P&gt;control register.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Give please an example how to request this interrupt in linux 3.10.53.&lt;/P&gt;&lt;P&gt;Thank you.&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Thu, 28 Jan 2016 09:19:45 GMT</pubDate>
      <guid>https://community.nxp.com/t5/i-MX-Processors/iMX6-PWM-Interrupt/m-p/470996#M74549</guid>
      <dc:creator>evgenymolchanov</dc:creator>
      <dc:date>2016-01-28T09:19:45Z</dc:date>
    </item>
    <item>
      <title>Re: iMX6 PWM Interrupt</title>
      <link>https://community.nxp.com/t5/i-MX-Processors/iMX6-PWM-Interrupt/m-p/470997#M74550</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Hi Evgeny&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;one can look at pwm driver (working on interrupts), it is decribed&lt;/P&gt;&lt;P&gt;in attached Linux Manual&amp;nbsp; Chapter 49 Pulse-Width Modulator (PWM) Driver&lt;/P&gt;&lt;P&gt;and below links&lt;/P&gt;&lt;P&gt;&lt;A class="jive-link-external-small" href="http://git.freescale.com/git/cgit.cgi/imx/linux-2.6-imx.git/tree/Documentation/devicetree/bindings/pwm/imx-pwm.txt?h=imx_3.14.52_1.1.0_ga" rel="nofollow"&gt;http://git.freescale.com/git/cgit.cgi/imx/linux-2.6-imx.git/tree/Documentation/devicetree/bindings/pwm/imx-pwm.txt?h=imx_3.14.52_1.1.0_ga&lt;/A&gt;&lt;/P&gt;&lt;P&gt;&lt;A class="jive-link-external-small" href="http://git.freescale.com/git/cgit.cgi/imx/linux-2.6-imx.git/tree/arch/arm/mach-imx/devices/platform-mxc_pwm.c?h=imx_3.14.52_1.1.0_ga" rel="nofollow"&gt;http://git.freescale.com/git/cgit.cgi/imx/linux-2.6-imx.git/tree/arch/arm/mach-imx/devices/platform-mxc_pwm.c?h=imx_3.14.52_1.1.0_ga&lt;/A&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Best regards&lt;/P&gt;&lt;P&gt;igor&lt;/P&gt;&lt;P&gt;-----------------------------------------------------------------------------------------------------------------------&lt;/P&gt;&lt;P&gt;Note: If this post answers your question, please click the Correct Answer button. Thank you!&lt;/P&gt;&lt;P&gt;-----------------------------------------------------------------------------------------------------------------------&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Thu, 28 Jan 2016 10:53:19 GMT</pubDate>
      <guid>https://community.nxp.com/t5/i-MX-Processors/iMX6-PWM-Interrupt/m-p/470997#M74550</guid>
      <dc:creator>igorpadykov</dc:creator>
      <dc:date>2016-01-28T10:53:19Z</dc:date>
    </item>
    <item>
      <title>Re: iMX6 PWM Interrupt</title>
      <link>https://community.nxp.com/t5/i-MX-Processors/iMX6-PWM-Interrupt/m-p/470998#M74551</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Hi Igor.&lt;/P&gt;&lt;P&gt;Sorry, I must to correct my question.&lt;/P&gt;&lt;P&gt;I use Android 4.4.3 with kernel 3.10.53.&lt;/P&gt;&lt;P&gt;I need periodical timer without any jitter.&lt;/P&gt;&lt;P&gt;I &lt;A _jive_internal="true" href="https://community.nxp.com/thread/340520#475673"&gt;found &lt;/A&gt;​what GPT timer used by kernel.&lt;/P&gt;&lt;P&gt;I try to use hrtimer, but it not so accurate as i need.&lt;/P&gt;&lt;P&gt;EPIT too very depends on CPU load.&lt;/P&gt;&lt;P&gt;Now I want to use PWM, but without GPIO, only interrupt. Because in my custom board appropriate pins not allowed.&lt;/P&gt;&lt;P&gt;In kernel sources drivers/pwm/pwm-imx.c in probe function there is no any parsing of dts and request interrupt.&lt;/P&gt;&lt;P&gt;arch/arm/mach-imx/epit.c probe function parse dts and call request irq.&lt;/P&gt;&lt;P&gt;I can add parsing of dts and add irq request in pwm-imx.c, but is anybody tested working interrupt from PWM?&lt;/P&gt;&lt;P&gt;Or maybe you can give me another way to get periodic events?&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Thu, 28 Jan 2016 13:04:04 GMT</pubDate>
      <guid>https://community.nxp.com/t5/i-MX-Processors/iMX6-PWM-Interrupt/m-p/470998#M74551</guid>
      <dc:creator>evgenymolchanov</dc:creator>
      <dc:date>2016-01-28T13:04:04Z</dc:date>
    </item>
    <item>
      <title>Re: iMX6 PWM Interrupt</title>
      <link>https://community.nxp.com/t5/i-MX-Processors/iMX6-PWM-Interrupt/m-p/470999#M74552</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;I have added functions to pwm-imx.c for enable compare, rollover interrupts and got interrupts from PWM1 in my driver.&lt;/P&gt;&lt;P&gt;Then I reset interrupt flags in my driver.&lt;/P&gt;&lt;P&gt;Also I have changed irq affinity to CPU3.&lt;/P&gt;&lt;P&gt;So I got more accuracy, than while using EPIT.&lt;/P&gt;&lt;P&gt;But I still need more accuracy...&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Fri, 29 Jan 2016 10:29:32 GMT</pubDate>
      <guid>https://community.nxp.com/t5/i-MX-Processors/iMX6-PWM-Interrupt/m-p/470999#M74552</guid>
      <dc:creator>evgenymolchanov</dc:creator>
      <dc:date>2016-01-29T10:29:32Z</dc:date>
    </item>
    <item>
      <title>Re: iMX6 PWM Interrupt</title>
      <link>https://community.nxp.com/t5/i-MX-Processors/iMX6-PWM-Interrupt/m-p/471000#M74553</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Hi Evgeny,&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Can you please share steps for enabling and handling interrupt in PWM. Currently i am also stucked&amp;nbsp;with similar problem.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Regards&lt;/P&gt;&lt;P&gt;Sandeep S&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Mon, 17 Oct 2016 08:45:27 GMT</pubDate>
      <guid>https://community.nxp.com/t5/i-MX-Processors/iMX6-PWM-Interrupt/m-p/471000#M74553</guid>
      <dc:creator>sandeepajesh</dc:creator>
      <dc:date>2016-10-17T08:45:27Z</dc:date>
    </item>
    <item>
      <title>Re: iMX6 PWM Interrupt</title>
      <link>https://community.nxp.com/t5/i-MX-Processors/iMX6-PWM-Interrupt/m-p/471001#M74554</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;&lt;STRONG&gt;Hi Sandeep.&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;I have wrote some driver for setup PWMs via dtsi for start PWMs:&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;#include &amp;lt;linux/init.h&amp;gt;&lt;BR /&gt;#include &amp;lt;linux/interrupt.h&amp;gt;&lt;BR /&gt;#include &amp;lt;linux/sched.h&amp;gt;&lt;BR /&gt;#include &amp;lt;linux/module.h&amp;gt;&lt;BR /&gt;#include &amp;lt;linux/kernel.h&amp;gt;&lt;BR /&gt;#include &amp;lt;linux/platform_device.h&amp;gt;&lt;BR /&gt;#include &amp;lt;linux/slab.h&amp;gt;&lt;BR /&gt;#include &amp;lt;linux/err.h&amp;gt;&lt;BR /&gt;#include &amp;lt;linux/clk.h&amp;gt;&lt;BR /&gt;#include &amp;lt;linux/io.h&amp;gt;&lt;BR /&gt;#include &amp;lt;linux/pwm.h&amp;gt;&lt;BR /&gt;#include &amp;lt;linux/fsl_devices.h&amp;gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;enum PwmDevs{DEVSTEP=0,DEVSERVO,DEVNUM};&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;struct tvh_pwm {&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;struct pwm_device&amp;nbsp;&amp;nbsp; &amp;nbsp;*pwm;&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;bool&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;enabled;&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;unsigned int&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;period;&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;unsigned int&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;irq;&lt;BR /&gt;};&lt;BR /&gt;struct tvh_pwm_device {&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;struct device&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;*dev;&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;struct tvh_pwm&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;*tvh[DEVNUM];&lt;BR /&gt;};&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;struct tvh_pwm_device *pb;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;#if defined(CONFIG_OF)&lt;BR /&gt;static const struct of_device_id tvh_pwm_dt_ids[] = {&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;{ .compatible = "tvh,pwm"},&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;{ /* sentinel */ }&lt;BR /&gt;};&lt;BR /&gt;MODULE_DEVICE_TABLE(of, tvh_pwm_dt_ids);&lt;BR /&gt;#endif&lt;BR /&gt;/*&lt;BR /&gt;int tvh_pwm_freq(int dev, int freq)&lt;BR /&gt;{&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;unsigned int period_ns;&lt;BR /&gt;//&amp;nbsp;&amp;nbsp; &amp;nbsp;printk("%s dev %d freq %d\n",__func__, dev, freq);&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;if(dev &amp;lt; 0 || dev &amp;gt;= DEVNUM) return -EINVAL;&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;if(!freq) return -EINVAL;&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;if(!pb) return -ENODEV;&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;if(!pb-&amp;gt;tvh[dev]-&amp;gt;pwm) return -ENODEV;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;period_ns = 1000000000;&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;do_div(period_ns, freq);&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;pwm_config(pb-&amp;gt;tvh[dev]-&amp;gt;pwm, (period_ns &amp;gt;&amp;gt; 1), period_ns);&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;return 0;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;}&lt;BR /&gt;EXPORT_SYMBOL(tvh_pwm_freq);&lt;BR /&gt;*/&lt;BR /&gt;static int tvh_pwm_probe(struct platform_device *pdev)&lt;BR /&gt;{&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;int ret = 0;&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;struct tvh_pwm *step;&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;struct tvh_pwm *servo;&lt;BR /&gt;//&amp;nbsp;&amp;nbsp; &amp;nbsp;struct device_node *np = pdev-&amp;gt;dev.of_node;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;printk("%s\n",__func__);&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;step = kzalloc(sizeof(*step), GFP_KERNEL);&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;if (!step) {&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;dev_err(&amp;amp;pdev-&amp;gt;dev, "no memory for state\n");&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;ret = -ENOMEM;&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;goto err_alloc;&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;servo = kzalloc(sizeof(*servo), GFP_KERNEL);&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;if (!servo) {&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;dev_err(&amp;amp;pdev-&amp;gt;dev, "no memory for state\n");&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;ret = -ENOMEM;&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;goto err_alloc;&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;pb = kzalloc(sizeof(*pb), GFP_KERNEL);&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;if (!pb) {&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;dev_err(&amp;amp;pdev-&amp;gt;dev, "no memory for state\n");&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;ret = -ENOMEM;&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;goto err_alloc;&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;pb-&amp;gt;dev = &amp;amp;pdev-&amp;gt;dev;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;/*STEPPER*/&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;step-&amp;gt;pwm = devm_pwm_get(&amp;amp;pdev-&amp;gt;dev, "tvh-step");&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;if (IS_ERR(step-&amp;gt;pwm)) {&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;dev_err(&amp;amp;pdev-&amp;gt;dev, "unable to request PWM for stepper.\n");&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;ret = (PTR_ERR)(step-&amp;gt;pwm);&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;kfree(step);&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;else&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;step-&amp;gt;period = pwm_get_period(step-&amp;gt;pwm);&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;printk("DEVSTEP period %d\n",step-&amp;gt;period);&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;pwm_config(step-&amp;gt;pwm, (step-&amp;gt;period &amp;gt;&amp;gt; 1), step-&amp;gt;period);&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;pwm_out_enable(step-&amp;gt;pwm, 1);&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;pwm_enable(step-&amp;gt;pwm);&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;step-&amp;gt;enabled = true;&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;pb-&amp;gt;tvh[DEVSTEP] = step;&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;BR /&gt;/*SERVO*/&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;servo-&amp;gt;pwm = devm_pwm_get(&amp;amp;pdev-&amp;gt;dev, "tvh-servo");&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;if (IS_ERR(servo-&amp;gt;pwm)) {&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;dev_err(&amp;amp;pdev-&amp;gt;dev, "unable to request PWM for servo\n");&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;ret = (PTR_ERR)(servo-&amp;gt;pwm);&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;kfree(servo);&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;else&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;servo-&amp;gt;period = pwm_get_period(servo-&amp;gt;pwm);&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;printk("DEVSERVO period %d\n",servo-&amp;gt;period);&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;pwm_config(servo-&amp;gt;pwm, (servo-&amp;gt;period &amp;gt;&amp;gt; 1), servo-&amp;gt;period);&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;pwm_out_enable(servo-&amp;gt;pwm, 1);&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;pwm_enable(servo-&amp;gt;pwm);&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;servo-&amp;gt;enabled = true;&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;pb-&amp;gt;tvh[DEVSERVO] = servo;&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;platform_set_drvdata(pdev, pb);&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;return 0;&lt;BR /&gt;//err_pwm:&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;kfree(pb);&lt;BR /&gt;err_alloc:&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;return ret;&lt;BR /&gt;}&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;static int tvh_pwm_remove(struct platform_device *pdev)&lt;BR /&gt;{&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;struct tvh_pwm_device *pb = platform_get_drvdata(pdev);&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;pwm_disable(pb-&amp;gt;tvh[DEVSTEP]-&amp;gt;pwm);&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;devm_pwm_put(&amp;amp;pdev-&amp;gt;dev, pb-&amp;gt;tvh[DEVSTEP]-&amp;gt;pwm);&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;pwm_disable(pb-&amp;gt;tvh[DEVSERVO]-&amp;gt;pwm);&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;devm_pwm_put(&amp;amp;pdev-&amp;gt;dev, pb-&amp;gt;tvh[DEVSERVO]-&amp;gt;pwm);&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;kfree(pb);&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;return 0;&lt;BR /&gt;}&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;static struct platform_driver tvh_pwm_driver = {&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;.probe&amp;nbsp;&amp;nbsp; &amp;nbsp;= tvh_pwm_probe,&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;.remove&amp;nbsp;&amp;nbsp; &amp;nbsp;= tvh_pwm_remove,&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;.driver = {&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;.name&amp;nbsp;&amp;nbsp; &amp;nbsp;= "tvh_pwm",&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;.owner&amp;nbsp;&amp;nbsp; &amp;nbsp;= THIS_MODULE,&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;.of_match_table = tvh_pwm_dt_ids,&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;},&lt;BR /&gt;};&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;module_platform_driver(tvh_pwm_driver)&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;MODULE_LICENSE("GPL");&lt;BR /&gt;MODULE_AUTHOR("TvHelp, Ltd.");&lt;BR /&gt;MODULE_DESCRIPTION("Manage Servo and Stepper motors via PWM");&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;and add to my dtsi following lines:&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;...&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; pwm-tvh {&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;compatible = "tvh,pwm";&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;pwms = &amp;lt;&amp;amp;pwm1 0 5000000&amp;gt;, &amp;lt;&amp;amp;pwm2 0 1000000&amp;gt;;//period in nanosec&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;pwm-names = "tvh-servo", "tvh-step";&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;};&lt;/P&gt;&lt;P&gt;...&lt;/P&gt;&lt;P&gt;&amp;amp;pwm2 {&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;pinctrl-names = "default";&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;pinctrl-0 = &amp;lt;&amp;amp;pinctrl_pwm2_2&amp;gt;;&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;status = "okay";&lt;BR /&gt;};&lt;/P&gt;&lt;P&gt;&lt;BR /&gt;add to imx6qdl.dtsi:&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;pinctrl_pwm2_2: pwm2grp-2 {&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;fsl,pins = &amp;lt;&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;MX6QDL_PAD_GPIO_1__PWM2_OUT 0x1b0b1&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;gt;;&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;};&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;In application I call this:&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;#define MHZ&amp;nbsp;&amp;nbsp; &amp;nbsp;1000000&lt;BR /&gt;#define CLK 66*MHZ&lt;BR /&gt;#define PCLK 2*MHZ&lt;BR /&gt;#define PRESCALE (CLK)/(PCLK)&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;#define STEP_PWM2_IRQ 116&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;#define PWM1_BASE_ADDRESS 0xc09b0000&lt;BR /&gt;#define PWM2_BASE_ADDRESS 0xc09b8000&lt;BR /&gt;#define MX3_PWMCR&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;0x00&amp;nbsp;&amp;nbsp;&amp;nbsp; /* PWM Control Register */&lt;BR /&gt;#define MX3_PWMSR&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;0x04&amp;nbsp;&amp;nbsp;&amp;nbsp; /* PWM Status Register */&lt;BR /&gt;#define MX3_PWMIR&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;0x08&amp;nbsp;&amp;nbsp;&amp;nbsp; /* PWM Interrupt Register */&lt;BR /&gt;#define MX3_PWMSAR&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;0x0C&amp;nbsp;&amp;nbsp;&amp;nbsp; /* PWM Sample Register */&lt;BR /&gt;#define MX3_PWMPR&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;0x10&amp;nbsp;&amp;nbsp;&amp;nbsp; /* PWM Period Register */&lt;BR /&gt;#define MX3_PWMCR_PRESCALER(x)&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;((((x) - 1) &amp;amp; 0xFFF) &amp;lt;&amp;lt; 4)&lt;BR /&gt;#define MX3_PWMCR_DOZEEN&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;(1 &amp;lt;&amp;lt; 24)&lt;BR /&gt;#define MX3_PWMCR_WAITEN&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;(1 &amp;lt;&amp;lt; 23)&lt;BR /&gt;#define MX3_PWMCR_DBGEN&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;(1 &amp;lt;&amp;lt; 22)&lt;BR /&gt;#define MX3_PWMCR_CLKSRC_IPG_HIGH&amp;nbsp;&amp;nbsp; &amp;nbsp;(2 &amp;lt;&amp;lt; 16)&lt;BR /&gt;#define MX3_PWMCR_CLKSRC_IPG&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;(1 &amp;lt;&amp;lt; 16)&lt;BR /&gt;#define MX3_PWMCR_SWR&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;(1 &amp;lt;&amp;lt; 3)&lt;BR /&gt;#define MX3_PWMCR_EN&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;(1 &amp;lt;&amp;lt; 0)&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;#define MX3_PWMIR_COMPAREIE&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;(1&amp;lt;&amp;lt;2)&lt;BR /&gt;#define MX3_PWMIR_ROLLOVERIE&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;(1&amp;lt;&amp;lt;1)&lt;BR /&gt;#define MX3_PWMIR_FIFOEMPTYIE&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;(1&amp;lt;&amp;lt;0)&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;#define MX3_PWMSR_ROLLOVER_STATUS&amp;nbsp;&amp;nbsp; &amp;nbsp;(1&amp;lt;&amp;lt;4)&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;irqreturn_t step_pwm_handler(int irq, void *handle)&lt;BR /&gt;{&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;//Clear rollover interrupt flag&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;writel(MX3_PWMSR_ROLLOVER_STATUS, (void volatile*)(PWM2_BASE_ADDRESS + MX3_PWMSR));&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;//set period&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;writel(pwm_per[period_cnt], (void volatile*)(PWM2_BASE_ADDRESS + MX3_PWMPR));&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;//set sample&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;writel(pwm_sam[period_cnt], (void volatile*)(PWM2_BASE_ADDRESS + MX3_PWMSAR));&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //Do what you need&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;return IRQ_HANDLED;&lt;BR /&gt;}&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;/*&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;Init PWM2 of iMX6&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;Setup Control Register with prescale calculated above in defines&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;Request irq. Rollover interrupt enable set in drivers/pwm/pwm-imx.c&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;in imx_pwm_enable function:&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;...&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;imx-&amp;gt;rei_enable(chip, true); &lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;...&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;imx_pwm_enable calls in drivers/tvhelp/pwm.pwm.c probe function.&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;params:&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;cb - callback function which call in interrupt handler&lt;BR /&gt;*/&lt;BR /&gt;int step_pwm_init(void *cb)&lt;BR /&gt;{&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;int ret;&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;u32 cr;&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;if(opened) return EALREADY;&lt;BR /&gt;&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;DBG("%s %s\n",TAG, __func__);&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;cr = MX3_PWMCR_PRESCALER(PRESCALE) |&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;MX3_PWMCR_DOZEEN | MX3_PWMCR_WAITEN |&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;MX3_PWMCR_DBGEN | MX3_PWMCR_CLKSRC_IPG_HIGH | MX3_PWMCR_EN;&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;writel(cr,(void volatile*)(PWM2_BASE_ADDRESS + MX3_PWMCR));&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;ret = request_irq(STEP_PWM2_IRQ, step_pwm_handler, IRQF_DISABLED, "step pwm irq", NULL);&lt;BR /&gt;&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;DBG("%s request step pwm irq %d return %d\n", TAG, STEP_PWM2_IRQ, ret);&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;if(cb) callback = cb;&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;if(ret == 0)&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;opened = 1;&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;return ret;&lt;BR /&gt;}&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;/*&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;Free PWM2 irq.&lt;BR /&gt;*/&lt;BR /&gt;int step_pwm_exit(void)&lt;BR /&gt;{&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;if(!opened) return 0;&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;free_irq(STEP_PWM2_IRQ, NULL);&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;DBG("%s free step pwm irq %d\n", TAG, STEP_PWM2_IRQ);&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;opened = 0;&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;return 0;&lt;BR /&gt;}&lt;/P&gt;&lt;P&gt;Good luck)&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Mon, 17 Oct 2016 09:39:42 GMT</pubDate>
      <guid>https://community.nxp.com/t5/i-MX-Processors/iMX6-PWM-Interrupt/m-p/471001#M74554</guid>
      <dc:creator>evgenymolchanov</dc:creator>
      <dc:date>2016-10-17T09:39:42Z</dc:date>
    </item>
    <item>
      <title>Re: iMX6 PWM Interrupt</title>
      <link>https://community.nxp.com/t5/i-MX-Processors/iMX6-PWM-Interrupt/m-p/471002#M74555</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Thanks Evgeny....It was really helpful.&lt;/P&gt;&lt;P&gt;Thanks a lot. (y)&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Thu, 27 Oct 2016 04:00:10 GMT</pubDate>
      <guid>https://community.nxp.com/t5/i-MX-Processors/iMX6-PWM-Interrupt/m-p/471002#M74555</guid>
      <dc:creator>sandeepajesh</dc:creator>
      <dc:date>2016-10-27T04:00:10Z</dc:date>
    </item>
  </channel>
</rss>

