title: Changing Linux kernel module boot order
body: <p>I am experimenting with boot optimization on my Raspberry Pi 4 - Yocto based embedded Linux system and would like to set when vc4-drm kernel module is loaded. </p>
  
  <p>I would like to  make vc4-drm kernel module loaded earlier so that /dev/fb0 is ready earlier. Now, it exceeds my user space boot time, therefore I am not able to display anything on it for about 9 seconds. However, if I move it so that it is initialized earlier, I'm thinking it will be better. </p>
  
  <p>Below is an image that shows major kernel modules that are loaded on my system, in a complete debug mode (bootchart+initcall_debug+serial+printk enabled). You will see that vc4_drm_register is almost at the end.</p>
  
  <p><a href="https://i.stack.imgur.com/YR0I5.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/YR0I5.png" alt="enter image description here"></a></p>
  
  <p>In order to approach the issue, I found these: <a href="https://stackoverflow.com/questions/11642330/what-is-the-linux-built-in-driver-load-order">What is the Linux built-in driver load order?</a> and <a href="https://stackoverflow.com/questions/10368837/how-does-linux-determine-the-order-of-module-init-calls">How does Linux determine the order of module init calls?</a>. Yasushi Shoji states;</p>
  
  <blockquote>
    <p>put your init function in the higher level, or
      put your device driver at the higher position in Makefile</p>
  </blockquote>
  
  <p>For the <strong>first method</strong>, in the kernel that I'm compiling, I found the module in <code>drivers/gpu/drm/vc4</code>, then replaced <code>module_init(vc4_drm_register)</code> with both <code>early_initcall(vc4_drm_register)</code> and <code>subsys_initcall(vc4_drm_register)</code>. Both attempts made absolutely no difference, vc4 still loads at around ~9th second. Either I'm missing something here, or this is being handled differently.</p>
  
  <p><strong>Second method</strong> suggested is to adjust the order in drivers/Makefile. However, to me gpu/ drivers seems already pretty early stage.</p>
  
  <pre><code>obj-y               += irqchip/
  obj-y               += bus/
  
  obj-$(CONFIG_GENERIC_PHY)   += phy/
  
  # GPIO must come after pinctrl as gpios may need to mux pins etc
  obj-$(CONFIG_PINCTRL)       += pinctrl/
  obj-$(CONFIG_GPIOLIB)       += gpio/
  obj-y               += pwm/
  
  obj-y               += pci/
  
  obj-$(CONFIG_PARISC)        += parisc/
  obj-$(CONFIG_RAPIDIO)       += rapidio/
  obj-y               += video/
  obj-y               += idle/
  
  # IPMI must come before ACPI in order to provide IPMI opregion support
  obj-y               += char/ipmi/
  
  obj-$(CONFIG_ACPI)      += acpi/
  obj-$(CONFIG_SFI)       += sfi/
  # PnP must come after ACPI since it will eventually need to check if acpi
  # was used and do nothing if so
  obj-$(CONFIG_PNP)       += pnp/
  obj-y               += amba/
  
  obj-y               += clk/
  # Many drivers will want to use DMA so this has to be made available
  # really early.
  obj-$(CONFIG_DMADEVICES)    += dma/
  
  # SOC specific infrastructure drivers.
  obj-y               += soc/
  
  obj-$(CONFIG_VIRTIO)        += virtio/
  obj-$(CONFIG_XEN)       += xen/
  
  # regulators early, since some subsystems rely on them to initialize
  obj-$(CONFIG_REGULATOR)     += regulator/
  
  # reset controllers early, since gpu drivers might rely on them to initialize
  obj-$(CONFIG_RESET_CONTROLLER)  += reset/
  
  # tty/ comes before char/ so that the VT console is the boot-time
  # default.
  obj-y               += tty/
  obj-y               += char/
  
  # iommu/ comes before gpu as gpu are using iommu controllers
  obj-$(CONFIG_IOMMU_SUPPORT) += iommu/
  
  # gpu/ comes after char for AGP vs DRM startup and after iommu
  obj-y               += gpu/
  # ...
  # ...
  # ...
  # Continues with a lot more drivers here...
  </code></pre>
  
  <p>Therefore, I am in need of help to figure this out. How do I make sure that vc4 is loaded earlier than it is now? If I am missing anything, please let me know. Thank you very much.</p>
  
  <p><strong>NOTE:</strong> vc4-drm dmesg</p>
  
  <pre><code>root@raspberrypi4-64:~# dmesg | grep vc4                                            
  [    9.123494] calling  vc4_drm_register+0x0/0x1000 [vc4] @ 299                     
  [    9.184440] vc4-drm soc:gpu: bound fe600000.firmwarekms (ops vc4_fkms_ops [vc4]) 
  [    9.192810] [drm] Initialized vc4 0.0.0 20140616 for soc:gpu on minor 1          
  [    9.380513] vc4-drm soc:gpu: fb0: DRM emulated frame buffer device               
  [    9.393112] initcall vc4_drm_register+0x0/0x1000 [vc4] returned 0 after 187677 us
  ecs 
  </code></pre>