1//
2//  AppleARMIO.cpp
3//  AppleARMPlatform
4//
5//  Created by rms on 5/22/13.
6//  Copyright (c) 2013 rms. All rights reserved.
7//
8
9#include "AppleARMIO.h"
10#include <IOKit/IOLib.h>
11#include <IOKit/IODeviceTreeSupport.h>
12#include <IOKit/IODeviceMemory.h>
13
14/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15
16#define super IOService
17
18OSDefineMetaClassAndAbstractStructors(AppleARMIOBus, IOService);
19OSMetaClassDefineReservedUnused(AppleARMIOBus, 0);
20OSMetaClassDefineReservedUnused(AppleARMIOBus, 1);
21OSMetaClassDefineReservedUnused(AppleARMIOBus, 2);
22OSMetaClassDefineReservedUnused(AppleARMIOBus, 3);
23
24/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
25
26extern const IORegistryPlane *gIODTPlane;
27
28bool AppleARMIOBus::start(IOService * provider)
29{
30    if (!super::start(provider))
31        return (false);
32
33    fNub = provider;
34    fMemory = provider->mapDeviceMemoryWithIndex(0);
35    if (0 == fMemory)
36        IOLog("%s: unexpected ranges\n", getName());
37
38    PMinit();                   // initialize for power management
39    temporaryPowerClampOn();    // hold power on till we get children
40    return (true);
41}
42
43IOService *AppleARMIOBus::createNub(IORegistryEntry * from)
44{
45    IOService *nub;
46
47    nub = new ARMIODevice;
48
49    if (nub && !nub->init(from, gIODTPlane)) {
50        nub->free();
51        nub = 0;
52    }
53
54    return (nub);
55}
56
57void AppleARMIOBus::processNub(IOService * /*nub */ )
58{
59}
60
61const char *AppleARMIOBus::deleteList(void)
62{
63    return ("('sd', 'st', 'disk', 'tape', 'pram', 'rtc', 'mouse')");
64}
65
66const char *AppleARMIOBus::excludeList(void)
67{
68    return (0);
69}
70
71void AppleARMIOBus::publishBelow(IORegistryEntry * root)
72{
73    OSCollectionIterator *kids;
74    IORegistryEntry *next;
75    IOService *nub;
76
77    // infanticide
78    kids = IODTFindMatchingEntries(root, kIODTRecursive, deleteList());
79    if (kids) {
80        while ((next = (IORegistryEntry *) kids->getNextObject())) {
81            next->detachAll(gIODTPlane);
82        }
83        kids->release();
84    }
85    // publish everything below, minus excludeList
86    kids = IODTFindMatchingEntries(root, kIODTRecursive | kIODTExclusive, excludeList());
87    if (kids) {
88        while ((next = (IORegistryEntry *) kids->getNextObject())) {
89
90            if (0 == (nub = createNub(next)))
91                continue;
92
93            nub->attach(this);
94
95            processNub(nub);
96
97            nub->registerService();
98        }
99        kids->release();
100    }
101}
102
103bool AppleARMIOBus::compareNubName(const IOService * nub, OSString * name, OSString ** matched) const const
104{
105    return (IODTCompareNubName(nub, name, matched)
106            || nub->IORegistryEntry::compareName(name, matched));
107}
108
109IOReturn AppleARMIOBus::getNubResources(IOService * nub)
110{
111    if (nub->getDeviceMemory())
112        return (kIOReturnSuccess);
113
114    IODTResolveAddressing(nub, "reg", fNub->getDeviceMemoryWithIndex(0));
115
116    return (kIOReturnSuccess);
117}
118
119/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
120
121#undef super
122#define super IOService
123
124OSDefineMetaClassAndStructors(AppleARMIODevice, IOService);
125OSMetaClassDefineReservedUnused(AppleARMIODevice, 0);
126OSMetaClassDefineReservedUnused(AppleARMIODevice, 1);
127OSMetaClassDefineReservedUnused(AppleARMIODevice, 2);
128OSMetaClassDefineReservedUnused(AppleARMIODevice, 3);
129
130/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
131
132bool AppleARMIODevice::compareName(OSString * name, OSString ** matched) const const
133{
134    return (IODTCompareNubName(this, name, matched) || IORegistryEntry::compareName(name, matched));
135}
136
137IOService *AppleARMIODevice::matchLocation(IOService * /* client */ )
138{
139    return this;
140}
141
142IOReturn AppleARMIODevice::getResources(void)
143{
144    IOService *macIO = this;
145
146    if (getDeviceMemory() != 0)
147        return kIOReturnSuccess;
148
149    while (macIO && ((macIO = macIO->getProvider()) != 0))
150        if (strcmp("arm-io", macIO->getName()) == 0)
151            break;
152
153    if (macIO == 0)
154        return kIOReturnError;
155
156    IODTResolveAddressing(this, "reg", macIO->getDeviceMemoryWithIndex(0));
157
158    return kIOReturnSuccess;
159}
160