The pointer to the struct is a reference to the hardware module. Therefore, if your MCU has 5 moduli of the same kind, your code can access any of them without knowing which one of the modules it is accessing. This gives you an opportunity to switch to a different module if needed - either within your project, or in the next project, or even dynamically at the run time. You can even use dynamic allocation - such as allocating DMA moduli on demand.
Manufacturers do love to ruin that fun by making every instantiation of the peripheral slightly different. Different field widths in timers, different FIFO sizes, some instances lack some of the features. Or just have completely different peripherals which really do the same thing. Think about STM32H7 series, they have three (3!) different DMAs: MDMA, DMA and BDMA, and specifically some peripherals can only use BDMA, and some can only use DMA. Besides, DMA and BDMA are very similar and both are just design reuse from older ST devices (BDMA is the F0 series DMA renamed, DMA from higher-up devices), so why not have DMA1, DMA2, DMA3 all of the same design, instead of DMA1, DMA2 and BDMA. Maybe they saved 100 transistors. Probably not even that.
Some manufacturers indeed love making programmer's job as difficult as possible. On the other hand, now I'm writing firmware for Nordic Semiconductor devices and I struggle in the opposite way, the peripheral design is just so clean and easy to use I need to concentrate in the actual application code, and the mental quality bar is now set higher. With STM32 for example, significant part of effort goes to working around broken mess ST gave us to handle, and code that works around it simply can't look beautiful.
I can see my workflow totally changed: with ST devices it's "read documentation for hours, write code, test, doesn't work, read more, modify, test, find HW bugs, work around, test, read more, modify, test, modify, need more coffee, it seems to work, repeat 5 times, verify it actually works". With nRF parts it's "read documentation quickly, write code SLOOWLY and painfully because you need to actually concentrate, test -> works perfectly the first time".