diff options
| -rw-r--r-- | Documentation/DocBook/uio-howto.tmpl | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/Documentation/DocBook/uio-howto.tmpl b/Documentation/DocBook/uio-howto.tmpl index b787e4721c90..52e1b79ce0e6 100644 --- a/Documentation/DocBook/uio-howto.tmpl +++ b/Documentation/DocBook/uio-howto.tmpl | |||
| @@ -42,6 +42,12 @@ GPL version 2. | |||
| 42 | 42 | ||
| 43 | <revhistory> | 43 | <revhistory> |
| 44 | <revision> | 44 | <revision> |
| 45 | <revnumber>0.7</revnumber> | ||
| 46 | <date>2008-12-23</date> | ||
| 47 | <authorinitials>hjk</authorinitials> | ||
| 48 | <revremark>Added generic platform drivers and offset attribute.</revremark> | ||
| 49 | </revision> | ||
| 50 | <revision> | ||
| 45 | <revnumber>0.6</revnumber> | 51 | <revnumber>0.6</revnumber> |
| 46 | <date>2008-12-05</date> | 52 | <date>2008-12-05</date> |
| 47 | <authorinitials>hjk</authorinitials> | 53 | <authorinitials>hjk</authorinitials> |
| @@ -312,6 +318,16 @@ interested in translating it, please email me | |||
| 312 | pointed to by addr. | 318 | pointed to by addr. |
| 313 | </para> | 319 | </para> |
| 314 | </listitem> | 320 | </listitem> |
| 321 | <listitem> | ||
| 322 | <para> | ||
| 323 | <filename>offset</filename>: The offset, in bytes, that has to be | ||
| 324 | added to the pointer returned by <function>mmap()</function> to get | ||
| 325 | to the actual device memory. This is important if the device's memory | ||
| 326 | is not page aligned. Remember that pointers returned by | ||
| 327 | <function>mmap()</function> are always page aligned, so it is good | ||
| 328 | style to always add this offset. | ||
| 329 | </para> | ||
| 330 | </listitem> | ||
| 315 | </itemizedlist> | 331 | </itemizedlist> |
| 316 | 332 | ||
| 317 | <para> | 333 | <para> |
| @@ -594,6 +610,78 @@ framework to set up sysfs files for this region. Simply leave it alone. | |||
| 594 | </para> | 610 | </para> |
| 595 | </sect1> | 611 | </sect1> |
| 596 | 612 | ||
| 613 | <sect1 id="using_uio_pdrv"> | ||
| 614 | <title>Using uio_pdrv for platform devices</title> | ||
| 615 | <para> | ||
| 616 | In many cases, UIO drivers for platform devices can be handled in a | ||
| 617 | generic way. In the same place where you define your | ||
| 618 | <varname>struct platform_device</varname>, you simply also implement | ||
| 619 | your interrupt handler and fill your | ||
| 620 | <varname>struct uio_info</varname>. A pointer to this | ||
| 621 | <varname>struct uio_info</varname> is then used as | ||
| 622 | <varname>platform_data</varname> for your platform device. | ||
| 623 | </para> | ||
| 624 | <para> | ||
| 625 | You also need to set up an array of <varname>struct resource</varname> | ||
| 626 | containing addresses and sizes of your memory mappings. This | ||
| 627 | information is passed to the driver using the | ||
| 628 | <varname>.resource</varname> and <varname>.num_resources</varname> | ||
| 629 | elements of <varname>struct platform_device</varname>. | ||
| 630 | </para> | ||
| 631 | <para> | ||
| 632 | You now have to set the <varname>.name</varname> element of | ||
| 633 | <varname>struct platform_device</varname> to | ||
| 634 | <varname>"uio_pdrv"</varname> to use the generic UIO platform device | ||
| 635 | driver. This driver will fill the <varname>mem[]</varname> array | ||
| 636 | according to the resources given, and register the device. | ||
| 637 | </para> | ||
| 638 | <para> | ||
| 639 | The advantage of this approach is that you only have to edit a file | ||
| 640 | you need to edit anyway. You do not have to create an extra driver. | ||
| 641 | </para> | ||
| 642 | </sect1> | ||
| 643 | |||
| 644 | <sect1 id="using_uio_pdrv_genirq"> | ||
| 645 | <title>Using uio_pdrv_genirq for platform devices</title> | ||
| 646 | <para> | ||
| 647 | Especially in embedded devices, you frequently find chips where the | ||
| 648 | irq pin is tied to its own dedicated interrupt line. In such cases, | ||
| 649 | where you can be really sure the interrupt is not shared, we can take | ||
| 650 | the concept of <varname>uio_pdrv</varname> one step further and use a | ||
| 651 | generic interrupt handler. That's what | ||
| 652 | <varname>uio_pdrv_genirq</varname> does. | ||
| 653 | </para> | ||
| 654 | <para> | ||
| 655 | The setup for this driver is the same as described above for | ||
| 656 | <varname>uio_pdrv</varname>, except that you do not implement an | ||
| 657 | interrupt handler. The <varname>.handler</varname> element of | ||
| 658 | <varname>struct uio_info</varname> must remain | ||
| 659 | <varname>NULL</varname>. The <varname>.irq_flags</varname> element | ||
| 660 | must not contain <varname>IRQF_SHARED</varname>. | ||
| 661 | </para> | ||
| 662 | <para> | ||
| 663 | You will set the <varname>.name</varname> element of | ||
| 664 | <varname>struct platform_device</varname> to | ||
| 665 | <varname>"uio_pdrv_genirq"</varname> to use this driver. | ||
| 666 | </para> | ||
| 667 | <para> | ||
| 668 | The generic interrupt handler of <varname>uio_pdrv_genirq</varname> | ||
| 669 | will simply disable the interrupt line using | ||
| 670 | <function>disable_irq_nosync()</function>. After doing its work, | ||
| 671 | userspace can reenable the interrupt by writing 0x00000001 to the UIO | ||
| 672 | device file. The driver already implements an | ||
| 673 | <function>irq_control()</function> to make this possible, you must not | ||
| 674 | implement your own. | ||
| 675 | </para> | ||
| 676 | <para> | ||
| 677 | Using <varname>uio_pdrv_genirq</varname> not only saves a few lines of | ||
| 678 | interrupt handler code. You also do not need to know anything about | ||
| 679 | the chip's internal registers to create the kernel part of the driver. | ||
| 680 | All you need to know is the irq number of the pin the chip is | ||
| 681 | connected to. | ||
| 682 | </para> | ||
| 683 | </sect1> | ||
| 684 | |||
| 597 | </chapter> | 685 | </chapter> |
| 598 | 686 | ||
| 599 | <chapter id="userspace_driver" xreflabel="Writing a driver in user space"> | 687 | <chapter id="userspace_driver" xreflabel="Writing a driver in user space"> |
