diff options
Diffstat (limited to 'Documentation/DocBook/uio-howto.tmpl')
-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"> |