Back to home page

OSCL-LXR

 
 

    


0001 =========================
0002 Writing a MUSB Glue Layer
0003 =========================
0004 
0005 :Author: Apelete Seketeli
0006 
0007 Introduction
0008 ============
0009 
0010 The Linux MUSB subsystem is part of the larger Linux USB subsystem. It
0011 provides support for embedded USB Device Controllers (UDC) that do not
0012 use Universal Host Controller Interface (UHCI) or Open Host Controller
0013 Interface (OHCI).
0014 
0015 Instead, these embedded UDC rely on the USB On-the-Go (OTG)
0016 specification which they implement at least partially. The silicon
0017 reference design used in most cases is the Multipoint USB Highspeed
0018 Dual-Role Controller (MUSB HDRC) found in the Mentor Graphics Inventra™
0019 design.
0020 
0021 As a self-taught exercise I have written an MUSB glue layer for the
0022 Ingenic JZ4740 SoC, modelled after the many MUSB glue layers in the
0023 kernel source tree. This layer can be found at
0024 ``drivers/usb/musb/jz4740.c``. In this documentation I will walk through the
0025 basics of the ``jz4740.c`` glue layer, explaining the different pieces and
0026 what needs to be done in order to write your own device glue layer.
0027 
0028 .. _musb-basics:
0029 
0030 Linux MUSB Basics
0031 =================
0032 
0033 To get started on the topic, please read USB On-the-Go Basics (see
0034 Resources) which provides an introduction of USB OTG operation at the
0035 hardware level. A couple of wiki pages by Texas Instruments and Analog
0036 Devices also provide an overview of the Linux kernel MUSB configuration,
0037 albeit focused on some specific devices provided by these companies.
0038 Finally, getting acquainted with the USB specification at USB home page
0039 may come in handy, with practical instance provided through the Writing
0040 USB Device Drivers documentation (again, see Resources).
0041 
0042 Linux USB stack is a layered architecture in which the MUSB controller
0043 hardware sits at the lowest. The MUSB controller driver abstract the
0044 MUSB controller hardware to the Linux USB stack::
0045 
0046           ------------------------
0047           |                      | <------- drivers/usb/gadget
0048           | Linux USB Core Stack | <------- drivers/usb/host
0049           |                      | <------- drivers/usb/core
0050           ------------------------
00510052          --------------------------
0053          |                        | <------ drivers/usb/musb/musb_gadget.c
0054          | MUSB Controller driver | <------ drivers/usb/musb/musb_host.c
0055          |                        | <------ drivers/usb/musb/musb_core.c
0056          --------------------------
00570058       ---------------------------------
0059       | MUSB Platform Specific Driver |
0060       |                               | <-- drivers/usb/musb/jz4740.c
0061       |       aka "Glue Layer"        |
0062       ---------------------------------
00630064       ---------------------------------
0065       |   MUSB Controller Hardware    |
0066       ---------------------------------
0067 
0068 As outlined above, the glue layer is actually the platform specific code
0069 sitting in between the controller driver and the controller hardware.
0070 
0071 Just like a Linux USB driver needs to register itself with the Linux USB
0072 subsystem, the MUSB glue layer needs first to register itself with the
0073 MUSB controller driver. This will allow the controller driver to know
0074 about which device the glue layer supports and which functions to call
0075 when a supported device is detected or released; remember we are talking
0076 about an embedded controller chip here, so no insertion or removal at
0077 run-time.
0078 
0079 All of this information is passed to the MUSB controller driver through
0080 a :c:type:`platform_driver` structure defined in the glue layer as::
0081 
0082     static struct platform_driver jz4740_driver = {
0083         .probe      = jz4740_probe,
0084         .remove     = jz4740_remove,
0085         .driver     = {
0086             .name   = "musb-jz4740",
0087         },
0088     };
0089 
0090 The probe and remove function pointers are called when a matching device
0091 is detected and, respectively, released. The name string describes the
0092 device supported by this glue layer. In the current case it matches a
0093 platform_device structure declared in ``arch/mips/jz4740/platform.c``. Note
0094 that we are not using device tree bindings here.
0095 
0096 In order to register itself to the controller driver, the glue layer
0097 goes through a few steps, basically allocating the controller hardware
0098 resources and initialising a couple of circuits. To do so, it needs to
0099 keep track of the information used throughout these steps. This is done
0100 by defining a private ``jz4740_glue`` structure::
0101 
0102     struct jz4740_glue {
0103         struct device           *dev;
0104         struct platform_device  *musb;
0105         struct clk      *clk;
0106     };
0107 
0108 
0109 The dev and musb members are both device structure variables. The first
0110 one holds generic information about the device, since it's the basic
0111 device structure, and the latter holds information more closely related
0112 to the subsystem the device is registered to. The clk variable keeps
0113 information related to the device clock operation.
0114 
0115 Let's go through the steps of the probe function that leads the glue
0116 layer to register itself to the controller driver.
0117 
0118 .. note::
0119 
0120    For the sake of readability each function will be split in logical
0121    parts, each part being shown as if it was independent from the others.
0122 
0123 .. code-block:: c
0124     :emphasize-lines: 8,12,18
0125 
0126     static int jz4740_probe(struct platform_device *pdev)
0127     {
0128         struct platform_device      *musb;
0129         struct jz4740_glue      *glue;
0130         struct clk                      *clk;
0131         int             ret;
0132 
0133         glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL);
0134         if (!glue)
0135             return -ENOMEM;
0136 
0137         musb = platform_device_alloc("musb-hdrc", PLATFORM_DEVID_AUTO);
0138         if (!musb) {
0139             dev_err(&pdev->dev, "failed to allocate musb device\n");
0140             return -ENOMEM;
0141         }
0142 
0143         clk = devm_clk_get(&pdev->dev, "udc");
0144         if (IS_ERR(clk)) {
0145             dev_err(&pdev->dev, "failed to get clock\n");
0146             ret = PTR_ERR(clk);
0147             goto err_platform_device_put;
0148         }
0149 
0150         ret = clk_prepare_enable(clk);
0151         if (ret) {
0152             dev_err(&pdev->dev, "failed to enable clock\n");
0153             goto err_platform_device_put;
0154         }
0155 
0156         musb->dev.parent        = &pdev->dev;
0157 
0158         glue->dev           = &pdev->dev;
0159         glue->musb          = musb;
0160         glue->clk           = clk;
0161 
0162         return 0;
0163 
0164     err_platform_device_put:
0165         platform_device_put(musb);
0166         return ret;
0167     }
0168 
0169 The first few lines of the probe function allocate and assign the glue,
0170 musb and clk variables. The ``GFP_KERNEL`` flag (line 8) allows the
0171 allocation process to sleep and wait for memory, thus being usable in a
0172 locking situation. The ``PLATFORM_DEVID_AUTO`` flag (line 12) allows
0173 automatic allocation and management of device IDs in order to avoid
0174 device namespace collisions with explicit IDs. With :c:func:`devm_clk_get`
0175 (line 18) the glue layer allocates the clock -- the ``devm_`` prefix
0176 indicates that :c:func:`clk_get` is managed: it automatically frees the
0177 allocated clock resource data when the device is released -- and enable
0178 it.
0179 
0180 
0181 
0182 Then comes the registration steps:
0183 
0184 .. code-block:: c
0185     :emphasize-lines: 3,5,7,9,16
0186 
0187     static int jz4740_probe(struct platform_device *pdev)
0188     {
0189         struct musb_hdrc_platform_data  *pdata = &jz4740_musb_platform_data;
0190 
0191         pdata->platform_ops     = &jz4740_musb_ops;
0192 
0193         platform_set_drvdata(pdev, glue);
0194 
0195         ret = platform_device_add_resources(musb, pdev->resource,
0196                             pdev->num_resources);
0197         if (ret) {
0198             dev_err(&pdev->dev, "failed to add resources\n");
0199             goto err_clk_disable;
0200         }
0201 
0202         ret = platform_device_add_data(musb, pdata, sizeof(*pdata));
0203         if (ret) {
0204             dev_err(&pdev->dev, "failed to add platform_data\n");
0205             goto err_clk_disable;
0206         }
0207 
0208         return 0;
0209 
0210     err_clk_disable:
0211         clk_disable_unprepare(clk);
0212     err_platform_device_put:
0213         platform_device_put(musb);
0214         return ret;
0215     }
0216 
0217 The first step is to pass the device data privately held by the glue
0218 layer on to the controller driver through :c:func:`platform_set_drvdata`
0219 (line 7). Next is passing on the device resources information, also privately
0220 held at that point, through :c:func:`platform_device_add_resources` (line 9).
0221 
0222 Finally comes passing on the platform specific data to the controller
0223 driver (line 16). Platform data will be discussed in
0224 :ref:`musb-dev-platform-data`, but here we are looking at the
0225 ``platform_ops`` function pointer (line 5) in ``musb_hdrc_platform_data``
0226 structure (line 3). This function pointer allows the MUSB controller
0227 driver to know which function to call for device operation::
0228 
0229     static const struct musb_platform_ops jz4740_musb_ops = {
0230         .init       = jz4740_musb_init,
0231         .exit       = jz4740_musb_exit,
0232     };
0233 
0234 Here we have the minimal case where only init and exit functions are
0235 called by the controller driver when needed. Fact is the JZ4740 MUSB
0236 controller is a basic controller, lacking some features found in other
0237 controllers, otherwise we may also have pointers to a few other
0238 functions like a power management function or a function to switch
0239 between OTG and non-OTG modes, for instance.
0240 
0241 At that point of the registration process, the controller driver
0242 actually calls the init function:
0243 
0244    .. code-block:: c
0245     :emphasize-lines: 12,14
0246 
0247     static int jz4740_musb_init(struct musb *musb)
0248     {
0249         musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2);
0250         if (!musb->xceiv) {
0251             pr_err("HS UDC: no transceiver configured\n");
0252             return -ENODEV;
0253         }
0254 
0255         /* Silicon does not implement ConfigData register.
0256          * Set dyn_fifo to avoid reading EP config from hardware.
0257          */
0258         musb->dyn_fifo = true;
0259 
0260         musb->isr = jz4740_musb_interrupt;
0261 
0262         return 0;
0263     }
0264 
0265 The goal of ``jz4740_musb_init()`` is to get hold of the transceiver
0266 driver data of the MUSB controller hardware and pass it on to the MUSB
0267 controller driver, as usual. The transceiver is the circuitry inside the
0268 controller hardware responsible for sending/receiving the USB data.
0269 Since it is an implementation of the physical layer of the OSI model,
0270 the transceiver is also referred to as PHY.
0271 
0272 Getting hold of the ``MUSB PHY`` driver data is done with ``usb_get_phy()``
0273 which returns a pointer to the structure containing the driver instance
0274 data. The next couple of instructions (line 12 and 14) are used as a
0275 quirk and to setup IRQ handling respectively. Quirks and IRQ handling
0276 will be discussed later in :ref:`musb-dev-quirks` and
0277 :ref:`musb-handling-irqs`\ ::
0278 
0279     static int jz4740_musb_exit(struct musb *musb)
0280     {
0281         usb_put_phy(musb->xceiv);
0282 
0283         return 0;
0284     }
0285 
0286 Acting as the counterpart of init, the exit function releases the MUSB
0287 PHY driver when the controller hardware itself is about to be released.
0288 
0289 Again, note that init and exit are fairly simple in this case due to the
0290 basic set of features of the JZ4740 controller hardware. When writing an
0291 musb glue layer for a more complex controller hardware, you might need
0292 to take care of more processing in those two functions.
0293 
0294 Returning from the init function, the MUSB controller driver jumps back
0295 into the probe function::
0296 
0297     static int jz4740_probe(struct platform_device *pdev)
0298     {
0299         ret = platform_device_add(musb);
0300         if (ret) {
0301             dev_err(&pdev->dev, "failed to register musb device\n");
0302             goto err_clk_disable;
0303         }
0304 
0305         return 0;
0306 
0307     err_clk_disable:
0308         clk_disable_unprepare(clk);
0309     err_platform_device_put:
0310         platform_device_put(musb);
0311         return ret;
0312     }
0313 
0314 This is the last part of the device registration process where the glue
0315 layer adds the controller hardware device to Linux kernel device
0316 hierarchy: at this stage, all known information about the device is
0317 passed on to the Linux USB core stack:
0318 
0319    .. code-block:: c
0320     :emphasize-lines: 5,6
0321 
0322     static int jz4740_remove(struct platform_device *pdev)
0323     {
0324         struct jz4740_glue  *glue = platform_get_drvdata(pdev);
0325 
0326         platform_device_unregister(glue->musb);
0327         clk_disable_unprepare(glue->clk);
0328 
0329         return 0;
0330     }
0331 
0332 Acting as the counterpart of probe, the remove function unregister the
0333 MUSB controller hardware (line 5) and disable the clock (line 6),
0334 allowing it to be gated.
0335 
0336 .. _musb-handling-irqs:
0337 
0338 Handling IRQs
0339 =============
0340 
0341 Additionally to the MUSB controller hardware basic setup and
0342 registration, the glue layer is also responsible for handling the IRQs:
0343 
0344    .. code-block:: c
0345     :emphasize-lines: 7,9-11,14,24
0346 
0347     static irqreturn_t jz4740_musb_interrupt(int irq, void *__hci)
0348     {
0349         unsigned long   flags;
0350         irqreturn_t     retval = IRQ_NONE;
0351         struct musb     *musb = __hci;
0352 
0353         spin_lock_irqsave(&musb->lock, flags);
0354 
0355         musb->int_usb = musb_readb(musb->mregs, MUSB_INTRUSB);
0356         musb->int_tx = musb_readw(musb->mregs, MUSB_INTRTX);
0357         musb->int_rx = musb_readw(musb->mregs, MUSB_INTRRX);
0358 
0359         /*
0360          * The controller is gadget only, the state of the host mode IRQ bits is
0361          * undefined. Mask them to make sure that the musb driver core will
0362          * never see them set
0363          */
0364         musb->int_usb &= MUSB_INTR_SUSPEND | MUSB_INTR_RESUME |
0365             MUSB_INTR_RESET | MUSB_INTR_SOF;
0366 
0367         if (musb->int_usb || musb->int_tx || musb->int_rx)
0368             retval = musb_interrupt(musb);
0369 
0370         spin_unlock_irqrestore(&musb->lock, flags);
0371 
0372         return retval;
0373     }
0374 
0375 Here the glue layer mostly has to read the relevant hardware registers
0376 and pass their values on to the controller driver which will handle the
0377 actual event that triggered the IRQ.
0378 
0379 The interrupt handler critical section is protected by the
0380 :c:func:`spin_lock_irqsave` and counterpart :c:func:`spin_unlock_irqrestore`
0381 functions (line 7 and 24 respectively), which prevent the interrupt
0382 handler code to be run by two different threads at the same time.
0383 
0384 Then the relevant interrupt registers are read (line 9 to 11):
0385 
0386 -  ``MUSB_INTRUSB``: indicates which USB interrupts are currently active,
0387 
0388 -  ``MUSB_INTRTX``: indicates which of the interrupts for TX endpoints are
0389    currently active,
0390 
0391 -  ``MUSB_INTRRX``: indicates which of the interrupts for TX endpoints are
0392    currently active.
0393 
0394 Note that :c:func:`musb_readb` is used to read 8-bit registers at most, while
0395 :c:func:`musb_readw` allows us to read at most 16-bit registers. There are
0396 other functions that can be used depending on the size of your device
0397 registers. See ``musb_io.h`` for more information.
0398 
0399 Instruction on line 18 is another quirk specific to the JZ4740 USB
0400 device controller, which will be discussed later in :ref:`musb-dev-quirks`.
0401 
0402 The glue layer still needs to register the IRQ handler though. Remember
0403 the instruction on line 14 of the init function::
0404 
0405     static int jz4740_musb_init(struct musb *musb)
0406     {
0407         musb->isr = jz4740_musb_interrupt;
0408 
0409         return 0;
0410     }
0411 
0412 This instruction sets a pointer to the glue layer IRQ handler function,
0413 in order for the controller hardware to call the handler back when an
0414 IRQ comes from the controller hardware. The interrupt handler is now
0415 implemented and registered.
0416 
0417 .. _musb-dev-platform-data:
0418 
0419 Device Platform Data
0420 ====================
0421 
0422 In order to write an MUSB glue layer, you need to have some data
0423 describing the hardware capabilities of your controller hardware, which
0424 is called the platform data.
0425 
0426 Platform data is specific to your hardware, though it may cover a broad
0427 range of devices, and is generally found somewhere in the ``arch/``
0428 directory, depending on your device architecture.
0429 
0430 For instance, platform data for the JZ4740 SoC is found in
0431 ``arch/mips/jz4740/platform.c``. In the ``platform.c`` file each device of the
0432 JZ4740 SoC is described through a set of structures.
0433 
0434 Here is the part of ``arch/mips/jz4740/platform.c`` that covers the USB
0435 Device Controller (UDC):
0436 
0437    .. code-block:: c
0438     :emphasize-lines: 2,7,14-17,21,22,25,26,28,29
0439 
0440     /* USB Device Controller */
0441     struct platform_device jz4740_udc_xceiv_device = {
0442         .name = "usb_phy_gen_xceiv",
0443         .id   = 0,
0444     };
0445 
0446     static struct resource jz4740_udc_resources[] = {
0447         [0] = {
0448             .start = JZ4740_UDC_BASE_ADDR,
0449             .end   = JZ4740_UDC_BASE_ADDR + 0x10000 - 1,
0450             .flags = IORESOURCE_MEM,
0451         },
0452         [1] = {
0453             .start = JZ4740_IRQ_UDC,
0454             .end   = JZ4740_IRQ_UDC,
0455             .flags = IORESOURCE_IRQ,
0456             .name  = "mc",
0457         },
0458     };
0459 
0460     struct platform_device jz4740_udc_device = {
0461         .name = "musb-jz4740",
0462         .id   = -1,
0463         .dev  = {
0464             .dma_mask          = &jz4740_udc_device.dev.coherent_dma_mask,
0465             .coherent_dma_mask = DMA_BIT_MASK(32),
0466         },
0467         .num_resources = ARRAY_SIZE(jz4740_udc_resources),
0468         .resource      = jz4740_udc_resources,
0469     };
0470 
0471 The ``jz4740_udc_xceiv_device`` platform device structure (line 2)
0472 describes the UDC transceiver with a name and id number.
0473 
0474 At the time of this writing, note that ``usb_phy_gen_xceiv`` is the
0475 specific name to be used for all transceivers that are either built-in
0476 with reference USB IP or autonomous and doesn't require any PHY
0477 programming. You will need to set ``CONFIG_NOP_USB_XCEIV=y`` in the
0478 kernel configuration to make use of the corresponding transceiver
0479 driver. The id field could be set to -1 (equivalent to
0480 ``PLATFORM_DEVID_NONE``), -2 (equivalent to ``PLATFORM_DEVID_AUTO``) or
0481 start with 0 for the first device of this kind if we want a specific id
0482 number.
0483 
0484 The ``jz4740_udc_resources`` resource structure (line 7) defines the UDC
0485 registers base addresses.
0486 
0487 The first array (line 9 to 11) defines the UDC registers base memory
0488 addresses: start points to the first register memory address, end points
0489 to the last register memory address and the flags member defines the
0490 type of resource we are dealing with. So ``IORESOURCE_MEM`` is used to
0491 define the registers memory addresses. The second array (line 14 to 17)
0492 defines the UDC IRQ registers addresses. Since there is only one IRQ
0493 register available for the JZ4740 UDC, start and end point at the same
0494 address. The ``IORESOURCE_IRQ`` flag tells that we are dealing with IRQ
0495 resources, and the name ``mc`` is in fact hard-coded in the MUSB core in
0496 order for the controller driver to retrieve this IRQ resource by
0497 querying it by its name.
0498 
0499 Finally, the ``jz4740_udc_device`` platform device structure (line 21)
0500 describes the UDC itself.
0501 
0502 The ``musb-jz4740`` name (line 22) defines the MUSB driver that is used
0503 for this device; remember this is in fact the name that we used in the
0504 ``jz4740_driver`` platform driver structure in :ref:`musb-basics`.
0505 The id field (line 23) is set to -1 (equivalent to ``PLATFORM_DEVID_NONE``)
0506 since we do not need an id for the device: the MUSB controller driver was
0507 already set to allocate an automatic id in :ref:`musb-basics`. In the dev field
0508 we care for DMA related information here. The ``dma_mask`` field (line 25)
0509 defines the width of the DMA mask that is going to be used, and
0510 ``coherent_dma_mask`` (line 26) has the same purpose but for the
0511 ``alloc_coherent`` DMA mappings: in both cases we are using a 32 bits mask.
0512 Then the resource field (line 29) is simply a pointer to the resource
0513 structure defined before, while the ``num_resources`` field (line 28) keeps
0514 track of the number of arrays defined in the resource structure (in this
0515 case there were two resource arrays defined before).
0516 
0517 With this quick overview of the UDC platform data at the ``arch/`` level now
0518 done, let's get back to the MUSB glue layer specific platform data in
0519 ``drivers/usb/musb/jz4740.c``:
0520 
0521    .. code-block:: c
0522     :emphasize-lines: 3,5,7-9,11
0523 
0524     static struct musb_hdrc_config jz4740_musb_config = {
0525         /* Silicon does not implement USB OTG. */
0526         .multipoint = 0,
0527         /* Max EPs scanned, driver will decide which EP can be used. */
0528         .num_eps    = 4,
0529         /* RAMbits needed to configure EPs from table */
0530         .ram_bits   = 9,
0531         .fifo_cfg = jz4740_musb_fifo_cfg,
0532         .fifo_cfg_size = ARRAY_SIZE(jz4740_musb_fifo_cfg),
0533     };
0534 
0535     static struct musb_hdrc_platform_data jz4740_musb_platform_data = {
0536         .mode   = MUSB_PERIPHERAL,
0537         .config = &jz4740_musb_config,
0538     };
0539 
0540 First the glue layer configures some aspects of the controller driver
0541 operation related to the controller hardware specifics. This is done
0542 through the ``jz4740_musb_config`` :c:type:`musb_hdrc_config` structure.
0543 
0544 Defining the OTG capability of the controller hardware, the multipoint
0545 member (line 3) is set to 0 (equivalent to false) since the JZ4740 UDC
0546 is not OTG compatible. Then ``num_eps`` (line 5) defines the number of USB
0547 endpoints of the controller hardware, including endpoint 0: here we have
0548 3 endpoints + endpoint 0. Next is ``ram_bits`` (line 7) which is the width
0549 of the RAM address bus for the MUSB controller hardware. This
0550 information is needed when the controller driver cannot automatically
0551 configure endpoints by reading the relevant controller hardware
0552 registers. This issue will be discussed when we get to device quirks in
0553 :ref:`musb-dev-quirks`. Last two fields (line 8 and 9) are also
0554 about device quirks: ``fifo_cfg`` points to the USB endpoints configuration
0555 table and ``fifo_cfg_size`` keeps track of the size of the number of
0556 entries in that configuration table. More on that later in
0557 :ref:`musb-dev-quirks`.
0558 
0559 Then this configuration is embedded inside ``jz4740_musb_platform_data``
0560 :c:type:`musb_hdrc_platform_data` structure (line 11): config is a pointer to
0561 the configuration structure itself, and mode tells the controller driver
0562 if the controller hardware may be used as ``MUSB_HOST`` only,
0563 ``MUSB_PERIPHERAL`` only or ``MUSB_OTG`` which is a dual mode.
0564 
0565 Remember that ``jz4740_musb_platform_data`` is then used to convey
0566 platform data information as we have seen in the probe function in
0567 :ref:`musb-basics`.
0568 
0569 .. _musb-dev-quirks:
0570 
0571 Device Quirks
0572 =============
0573 
0574 Completing the platform data specific to your device, you may also need
0575 to write some code in the glue layer to work around some device specific
0576 limitations. These quirks may be due to some hardware bugs, or simply be
0577 the result of an incomplete implementation of the USB On-the-Go
0578 specification.
0579 
0580 The JZ4740 UDC exhibits such quirks, some of which we will discuss here
0581 for the sake of insight even though these might not be found in the
0582 controller hardware you are working on.
0583 
0584 Let's get back to the init function first:
0585 
0586    .. code-block:: c
0587     :emphasize-lines: 12
0588 
0589     static int jz4740_musb_init(struct musb *musb)
0590     {
0591         musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2);
0592         if (!musb->xceiv) {
0593             pr_err("HS UDC: no transceiver configured\n");
0594             return -ENODEV;
0595         }
0596 
0597         /* Silicon does not implement ConfigData register.
0598          * Set dyn_fifo to avoid reading EP config from hardware.
0599          */
0600         musb->dyn_fifo = true;
0601 
0602         musb->isr = jz4740_musb_interrupt;
0603 
0604         return 0;
0605     }
0606 
0607 Instruction on line 12 helps the MUSB controller driver to work around
0608 the fact that the controller hardware is missing registers that are used
0609 for USB endpoints configuration.
0610 
0611 Without these registers, the controller driver is unable to read the
0612 endpoints configuration from the hardware, so we use line 12 instruction
0613 to bypass reading the configuration from silicon, and rely on a
0614 hard-coded table that describes the endpoints configuration instead::
0615 
0616     static struct musb_fifo_cfg jz4740_musb_fifo_cfg[] = {
0617         { .hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512, },
0618         { .hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, },
0619         { .hw_ep_num = 2, .style = FIFO_TX, .maxpacket = 64, },
0620     };
0621 
0622 Looking at the configuration table above, we see that each endpoints is
0623 described by three fields: ``hw_ep_num`` is the endpoint number, style is
0624 its direction (either ``FIFO_TX`` for the controller driver to send packets
0625 in the controller hardware, or ``FIFO_RX`` to receive packets from
0626 hardware), and maxpacket defines the maximum size of each data packet
0627 that can be transmitted over that endpoint. Reading from the table, the
0628 controller driver knows that endpoint 1 can be used to send and receive
0629 USB data packets of 512 bytes at once (this is in fact a bulk in/out
0630 endpoint), and endpoint 2 can be used to send data packets of 64 bytes
0631 at once (this is in fact an interrupt endpoint).
0632 
0633 Note that there is no information about endpoint 0 here: that one is
0634 implemented by default in every silicon design, with a predefined
0635 configuration according to the USB specification. For more examples of
0636 endpoint configuration tables, see ``musb_core.c``.
0637 
0638 Let's now get back to the interrupt handler function:
0639 
0640    .. code-block:: c
0641     :emphasize-lines: 18-19
0642 
0643     static irqreturn_t jz4740_musb_interrupt(int irq, void *__hci)
0644     {
0645         unsigned long   flags;
0646         irqreturn_t     retval = IRQ_NONE;
0647         struct musb     *musb = __hci;
0648 
0649         spin_lock_irqsave(&musb->lock, flags);
0650 
0651         musb->int_usb = musb_readb(musb->mregs, MUSB_INTRUSB);
0652         musb->int_tx = musb_readw(musb->mregs, MUSB_INTRTX);
0653         musb->int_rx = musb_readw(musb->mregs, MUSB_INTRRX);
0654 
0655         /*
0656          * The controller is gadget only, the state of the host mode IRQ bits is
0657          * undefined. Mask them to make sure that the musb driver core will
0658          * never see them set
0659          */
0660         musb->int_usb &= MUSB_INTR_SUSPEND | MUSB_INTR_RESUME |
0661             MUSB_INTR_RESET | MUSB_INTR_SOF;
0662 
0663         if (musb->int_usb || musb->int_tx || musb->int_rx)
0664             retval = musb_interrupt(musb);
0665 
0666         spin_unlock_irqrestore(&musb->lock, flags);
0667 
0668         return retval;
0669     }
0670 
0671 Instruction on line 18 above is a way for the controller driver to work
0672 around the fact that some interrupt bits used for USB host mode
0673 operation are missing in the ``MUSB_INTRUSB`` register, thus left in an
0674 undefined hardware state, since this MUSB controller hardware is used in
0675 peripheral mode only. As a consequence, the glue layer masks these
0676 missing bits out to avoid parasite interrupts by doing a logical AND
0677 operation between the value read from ``MUSB_INTRUSB`` and the bits that
0678 are actually implemented in the register.
0679 
0680 These are only a couple of the quirks found in the JZ4740 USB device
0681 controller. Some others were directly addressed in the MUSB core since
0682 the fixes were generic enough to provide a better handling of the issues
0683 for others controller hardware eventually.
0684 
0685 Conclusion
0686 ==========
0687 
0688 Writing a Linux MUSB glue layer should be a more accessible task, as
0689 this documentation tries to show the ins and outs of this exercise.
0690 
0691 The JZ4740 USB device controller being fairly simple, I hope its glue
0692 layer serves as a good example for the curious mind. Used with the
0693 current MUSB glue layers, this documentation should provide enough
0694 guidance to get started; should anything gets out of hand, the linux-usb
0695 mailing list archive is another helpful resource to browse through.
0696 
0697 Acknowledgements
0698 ================
0699 
0700 Many thanks to Lars-Peter Clausen and Maarten ter Huurne for answering
0701 my questions while I was writing the JZ4740 glue layer and for helping
0702 me out getting the code in good shape.
0703 
0704 I would also like to thank the Qi-Hardware community at large for its
0705 cheerful guidance and support.
0706 
0707 Resources
0708 =========
0709 
0710 USB Home Page: https://www.usb.org
0711 
0712 linux-usb Mailing List Archives: https://marc.info/?l=linux-usb
0713 
0714 USB On-the-Go Basics:
0715 https://www.maximintegrated.com/app-notes/index.mvp/id/1822
0716 
0717 :ref:`Writing USB Device Drivers <writing-usb-driver>`
0718 
0719 Texas Instruments USB Configuration Wiki Page:
0720 http://processors.wiki.ti.com/index.php/Usbgeneralpage