I would take the approach that I would follow DDD principles, building a domain layer that contains all the domain logic for the application. The domain layer would be common between all platforms.
I would probably write individual GUI implementation for each platform. When you talk about the controllers, I consider these to be part of the GUI implementation, because different GUI frameworks tend to advocate different design architectures. E.g. the controller you would write for a WPF application would be very different from the controller you would write for an iPhone application. And since I believe that you would be using WPF for Windows Phone 7, then I think that reusing the controllers between these two platforms will be more pain than pleasure.
Also, the controllers often reflect how the view is build, and you would build completely different views for mobile devices than you would for desktop computers due to the size of the screen, and the means of input (touch vs. mouse/keyboard)
In regards to data access, then I would say, it depends. If it doesn't feel awkward to reuse the same data access code between a Windows phone implementation and an OS-X implementation, then by all means do it. But if it starts feeling awkward, don't.
The key here is to have solid IOC principles in place, allowing you to easily change the data access implementation without affecting the implementation of the domain layer.