Looks really good! Just a few minor comments. With them addressed, Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzweig@xxxxxxxxxxxxx> > + Say Y here if you are using an Apple SoC with a DART IOMMU. Nit: Do we need to spell out "with a DART IOMMU"? Don't all the apple socs need DART? > +/* > + * This structure is used to identify a single stream attached to a domain. > + * It's used as a list inside that domain to be able to attach multiple > + * streams to a single domain. Since multiple devices can use a single stream > + * it additionally keeps track of how many devices are represented by this > + * stream. Once that number reaches zero it is detached from the IOMMU domain > + * and all translations from this stream are disabled. > + * > + * @dart: DART instance to which this stream belongs > + * @sid: stream id within the DART instance > + * @num_devices: count of devices attached to this stream > + * @stream_head: list head for the next stream > + */ > +struct apple_dart_stream { > + struct apple_dart *dart; > + u32 sid; > + > + u32 num_devices; > + > + struct list_head stream_head; > +}; It wasn't obvious to me why we can get away without reference counting. Looking ahead it looks like we assert locks in each case. Maybe add that to the comment? ``` > +static void apple_dart_hw_set_ttbr(struct apple_dart *dart, u16 sid, u16 idx, > + phys_addr_t paddr) > +{ > + writel(DART_TTBR_VALID | (paddr >> DART_TTBR_SHIFT), > + dart->regs + DART_TTBR(sid, idx)); > +} ``` Should we be checking alignment here? Something like BUG_ON(paddr & ((1 << DART_TTBR_SHIFT) - 1));