Eric Biederman | e9a271e3 | 2003-09-02 03:36:25 +0000 | [diff] [blame] | 1 | #include <console/console.h> |
| 2 | #include <device/device.h> |
| 3 | #include <device/pci.h> |
Yinghai Lu | 13f1c2a | 2005-07-08 02:49:49 +0000 | [diff] [blame] | 4 | #include <part/hard_reset.h> |
Eric Biederman | e9a271e3 | 2003-09-02 03:36:25 +0000 | [diff] [blame] | 5 | |
| 6 | /** |
| 7 | * Read the resources for the root device, |
Li-Ta Lo | 9782f75 | 2004-05-05 21:15:42 +0000 | [diff] [blame] | 8 | * that encompass the resources for the entire system. |
Eric Biederman | e9a271e3 | 2003-09-02 03:36:25 +0000 | [diff] [blame] | 9 | * @param root Pointer to the device structure for the system root device |
| 10 | */ |
| 11 | void root_dev_read_resources(device_t root) |
| 12 | { |
Eric Biederman | 03acab6 | 2004-10-14 21:25:53 +0000 | [diff] [blame] | 13 | struct resource *resource; |
Eric Biederman | e9a271e3 | 2003-09-02 03:36:25 +0000 | [diff] [blame] | 14 | |
| 15 | /* Initialize the system wide io space constraints */ |
Eric Biederman | 03acab6 | 2004-10-14 21:25:53 +0000 | [diff] [blame] | 16 | resource = new_resource(root, 0); |
| 17 | resource->base = 0x400; |
| 18 | resource->size = 0; |
| 19 | resource->align = 0; |
| 20 | resource->gran = 0; |
| 21 | resource->limit = 0xffffUL; |
| 22 | resource->flags = IORESOURCE_IO; |
| 23 | compute_allocate_resource(&root->link[0], resource, |
Eric Biederman | b78c197 | 2004-10-14 20:54:17 +0000 | [diff] [blame] | 24 | IORESOURCE_IO, IORESOURCE_IO); |
Eric Biederman | e9a271e3 | 2003-09-02 03:36:25 +0000 | [diff] [blame] | 25 | |
| 26 | /* Initialize the system wide memory resources constraints */ |
Eric Biederman | 03acab6 | 2004-10-14 21:25:53 +0000 | [diff] [blame] | 27 | resource = new_resource(root, 1); |
| 28 | resource->base = 0; |
| 29 | resource->size = 0; |
| 30 | resource->align = 0; |
| 31 | resource->gran = 0; |
| 32 | resource->limit = 0xffffffffUL; |
| 33 | resource->flags = IORESOURCE_MEM; |
| 34 | compute_allocate_resource(&root->link[0], resource, |
Eric Biederman | b78c197 | 2004-10-14 20:54:17 +0000 | [diff] [blame] | 35 | IORESOURCE_MEM, IORESOURCE_MEM); |
Eric Biederman | e9a271e3 | 2003-09-02 03:36:25 +0000 | [diff] [blame] | 36 | } |
| 37 | |
| 38 | /** |
Yinghai Lu | 13f1c2a | 2005-07-08 02:49:49 +0000 | [diff] [blame] | 39 | * @brief Write the resources for every device |
Li-Ta Lo | 0493069 | 2004-11-25 17:37:19 +0000 | [diff] [blame] | 40 | * |
Yinghai Lu | 13f1c2a | 2005-07-08 02:49:49 +0000 | [diff] [blame] | 41 | * Write the resources for the root device, |
Eric Biederman | e9a271e3 | 2003-09-02 03:36:25 +0000 | [diff] [blame] | 42 | * and every device under it which are all of the devices. |
| 43 | * @param root Pointer to the device structure for the system root device |
| 44 | */ |
| 45 | void root_dev_set_resources(device_t root) |
| 46 | { |
Eric Biederman | b78c197 | 2004-10-14 20:54:17 +0000 | [diff] [blame] | 47 | struct bus *bus; |
Li-Ta Lo | e526669 | 2004-03-23 21:28:05 +0000 | [diff] [blame] | 48 | |
Eric Biederman | b78c197 | 2004-10-14 20:54:17 +0000 | [diff] [blame] | 49 | bus = &root->link[0]; |
Yinghai Lu | 13f1c2a | 2005-07-08 02:49:49 +0000 | [diff] [blame] | 50 | compute_allocate_resource(bus, |
| 51 | &root->resource[0], IORESOURCE_IO, IORESOURCE_IO); |
| 52 | compute_allocate_resource(bus, |
| 53 | &root->resource[1], IORESOURCE_MEM, IORESOURCE_MEM); |
Eric Biederman | e9a271e3 | 2003-09-02 03:36:25 +0000 | [diff] [blame] | 54 | assign_resources(bus); |
| 55 | } |
| 56 | |
| 57 | /** |
Li-Ta Lo | fb4c50f | 2004-05-07 21:52:47 +0000 | [diff] [blame] | 58 | * @brief Scan devices on static buses. |
| 59 | * |
Li-Ta Lo | 9f0d0f9 | 2004-05-10 16:05:16 +0000 | [diff] [blame] | 60 | * The enumeration of certain buses is purely static. The existence of |
| 61 | * devices on those buses can be completely determined at compile time |
Yinghai Lu | 13f1c2a | 2005-07-08 02:49:49 +0000 | [diff] [blame] | 62 | * and is specified in the config file. Typical examples are the 'PNP' |
| 63 | * devices on a legacy ISA/LPC bus. There is no need of probing of any kind, |
| 64 | * the only thing we have to do is to walk through the bus and |
Li-Ta Lo | 0493069 | 2004-11-25 17:37:19 +0000 | [diff] [blame] | 65 | * enable or disable devices as indicated in the config file. |
Li-Ta Lo | fb4c50f | 2004-05-07 21:52:47 +0000 | [diff] [blame] | 66 | * |
Li-Ta Lo | 0493069 | 2004-11-25 17:37:19 +0000 | [diff] [blame] | 67 | * On the other hand, some devices are virtual and their existence is |
| 68 | * artificial. They can not be probed at run time. One example is the |
| 69 | * debug device. Those virtual devices have to be listed in the config |
| 70 | * file under some static bus in order to be enumerated at run time. |
Li-Ta Lo | fb4c50f | 2004-05-07 21:52:47 +0000 | [diff] [blame] | 71 | * |
Li-Ta Lo | 0493069 | 2004-11-25 17:37:19 +0000 | [diff] [blame] | 72 | * This function is the default scan_bus() method for the root device and |
| 73 | * LPC bridges. |
| 74 | * |
Yinghai Lu | 13f1c2a | 2005-07-08 02:49:49 +0000 | [diff] [blame] | 75 | * @param bus Pointer to the device structure which the static buses are attached |
Li-Ta Lo | 0493069 | 2004-11-25 17:37:19 +0000 | [diff] [blame] | 76 | * @param max Maximum bus number currently used before scanning. |
Yinghai Lu | 13f1c2a | 2005-07-08 02:49:49 +0000 | [diff] [blame] | 77 | * @return Largest bus number used. |
Eric Biederman | e9a271e3 | 2003-09-02 03:36:25 +0000 | [diff] [blame] | 78 | */ |
arch import user (historical) | 98d0d30 | 2005-07-06 17:13:46 +0000 | [diff] [blame] | 79 | static int smbus_max = 0; |
Yinghai Lu | 13f1c2a | 2005-07-08 02:49:49 +0000 | [diff] [blame] | 80 | unsigned int scan_static_bus(device_t bus, unsigned int max) |
Eric Biederman | e9a271e3 | 2003-09-02 03:36:25 +0000 | [diff] [blame] | 81 | { |
| 82 | device_t child; |
| 83 | unsigned link; |
Li-Ta Lo | e526669 | 2004-03-23 21:28:05 +0000 | [diff] [blame] | 84 | |
Yinghai Lu | 13f1c2a | 2005-07-08 02:49:49 +0000 | [diff] [blame] | 85 | printk_spew("%s for %s\n", __func__, dev_path(bus)); |
Li-Ta Lo | 0493069 | 2004-11-25 17:37:19 +0000 | [diff] [blame] | 86 | |
Yinghai Lu | 13f1c2a | 2005-07-08 02:49:49 +0000 | [diff] [blame] | 87 | for(link = 0; link < bus->links; link++) { |
| 88 | /* for smbus bus enumerate */ |
| 89 | child = bus->link[link].children; |
| 90 | if(child && child->path.type == DEVICE_PATH_I2C) { |
| 91 | bus->link[link].secondary = ++smbus_max; |
| 92 | } |
| 93 | for(child = bus->link[link].children; child; child = child->sibling) { |
Eric Biederman | 7003ba4 | 2004-10-16 06:20:29 +0000 | [diff] [blame] | 94 | if (child->chip_ops && child->chip_ops->enable_dev) { |
| 95 | child->chip_ops->enable_dev(child); |
| 96 | } |
Eric Biederman | e9a271e3 | 2003-09-02 03:36:25 +0000 | [diff] [blame] | 97 | if (child->ops && child->ops->enable) { |
| 98 | child->ops->enable(child); |
| 99 | } |
Yinghai Lu | 13f1c2a | 2005-07-08 02:49:49 +0000 | [diff] [blame] | 100 | if (child->path.type == DEVICE_PATH_I2C) { |
| 101 | printk_debug("smbus: %s[%d]->", |
| 102 | dev_path(child->bus->dev), child->bus->link ); |
| 103 | } |
| 104 | printk_debug("%s %s\n", |
| 105 | dev_path(child), |
| 106 | child->enabled?"enabled": "disabled"); |
Eric Biederman | e9a271e3 | 2003-09-02 03:36:25 +0000 | [diff] [blame] | 107 | } |
| 108 | } |
Yinghai Lu | 13f1c2a | 2005-07-08 02:49:49 +0000 | [diff] [blame] | 109 | for(link = 0; link < bus->links; link++) { |
| 110 | for(child = bus->link[link].children; child; child = child->sibling) { |
Eric Biederman | e9a271e3 | 2003-09-02 03:36:25 +0000 | [diff] [blame] | 111 | if (!child->ops || !child->ops->scan_bus) |
| 112 | continue; |
Eric Biederman | f8a2ddd | 2004-10-30 08:05:41 +0000 | [diff] [blame] | 113 | printk_spew("%s scanning...\n", dev_path(child)); |
Yinghai Lu | 13f1c2a | 2005-07-08 02:49:49 +0000 | [diff] [blame] | 114 | max = scan_bus(child, max); |
Eric Biederman | e9a271e3 | 2003-09-02 03:36:25 +0000 | [diff] [blame] | 115 | } |
| 116 | } |
Li-Ta Lo | fb4c50f | 2004-05-07 21:52:47 +0000 | [diff] [blame] | 117 | |
Yinghai Lu | 13f1c2a | 2005-07-08 02:49:49 +0000 | [diff] [blame] | 118 | printk_spew("%s for %s done\n", __func__, dev_path(bus)); |
Li-Ta Lo | fb4c50f | 2004-05-07 21:52:47 +0000 | [diff] [blame] | 119 | |
Eric Biederman | e9a271e3 | 2003-09-02 03:36:25 +0000 | [diff] [blame] | 120 | return max; |
| 121 | } |
| 122 | |
Li-Ta Lo | 9782f75 | 2004-05-05 21:15:42 +0000 | [diff] [blame] | 123 | /** |
| 124 | * @brief Enable resources for children devices |
| 125 | * |
Li-Ta Lo | fb4c50f | 2004-05-07 21:52:47 +0000 | [diff] [blame] | 126 | * @param dev the device whos children's resources are to be enabled |
Li-Ta Lo | 9782f75 | 2004-05-05 21:15:42 +0000 | [diff] [blame] | 127 | * |
Yinghai Lu | 13f1c2a | 2005-07-08 02:49:49 +0000 | [diff] [blame] | 128 | * This function is called by the global enable_resource() indirectly via the |
Li-Ta Lo | 0493069 | 2004-11-25 17:37:19 +0000 | [diff] [blame] | 129 | * device_operation::enable_resources() method of devices. |
Li-Ta Lo | 9f0d0f9 | 2004-05-10 16:05:16 +0000 | [diff] [blame] | 130 | * |
| 131 | * Indirect mutual recursion: |
Li-Ta Lo | 0493069 | 2004-11-25 17:37:19 +0000 | [diff] [blame] | 132 | * enable_childrens_resources() -> enable_resources() |
| 133 | * enable_resources() -> device_operation::enable_resources() |
| 134 | * device_operation::enable_resources() -> enable_children_resources() |
Li-Ta Lo | 9782f75 | 2004-05-05 21:15:42 +0000 | [diff] [blame] | 135 | */ |
Eric Biederman | e9a271e3 | 2003-09-02 03:36:25 +0000 | [diff] [blame] | 136 | void enable_childrens_resources(device_t dev) |
| 137 | { |
| 138 | unsigned link; |
Yinghai Lu | 13f1c2a | 2005-07-08 02:49:49 +0000 | [diff] [blame] | 139 | for(link = 0; link < dev->links; link++) { |
Eric Biederman | e9a271e3 | 2003-09-02 03:36:25 +0000 | [diff] [blame] | 140 | device_t child; |
Yinghai Lu | 13f1c2a | 2005-07-08 02:49:49 +0000 | [diff] [blame] | 141 | for(child = dev->link[link].children; child; child = child->sibling) { |
Eric Biederman | e9a271e3 | 2003-09-02 03:36:25 +0000 | [diff] [blame] | 142 | enable_resources(child); |
| 143 | } |
| 144 | } |
| 145 | } |
| 146 | |
Eric Biederman | 03acab6 | 2004-10-14 21:25:53 +0000 | [diff] [blame] | 147 | void root_dev_enable_resources(device_t dev) |
| 148 | { |
| 149 | enable_childrens_resources(dev); |
| 150 | } |
| 151 | |
Li-Ta Lo | 9782f75 | 2004-05-05 21:15:42 +0000 | [diff] [blame] | 152 | /** |
Eric Biederman | 03acab6 | 2004-10-14 21:25:53 +0000 | [diff] [blame] | 153 | * @brief Scan root bus for generic systems |
Li-Ta Lo | 9782f75 | 2004-05-05 21:15:42 +0000 | [diff] [blame] | 154 | * |
Li-Ta Lo | fb4c50f | 2004-05-07 21:52:47 +0000 | [diff] [blame] | 155 | * @param root The root device structure |
Li-Ta Lo | 0493069 | 2004-11-25 17:37:19 +0000 | [diff] [blame] | 156 | * @param max The current bus number scanned so far, usually 0x00 |
Li-Ta Lo | 9782f75 | 2004-05-05 21:15:42 +0000 | [diff] [blame] | 157 | * |
Li-Ta Lo | 0493069 | 2004-11-25 17:37:19 +0000 | [diff] [blame] | 158 | * This function is the default scan_bus() method of the root device. |
Li-Ta Lo | 9782f75 | 2004-05-05 21:15:42 +0000 | [diff] [blame] | 159 | */ |
Eric Biederman | 03acab6 | 2004-10-14 21:25:53 +0000 | [diff] [blame] | 160 | unsigned int root_dev_scan_bus(device_t root, unsigned int max) |
Eric Biederman | e9a271e3 | 2003-09-02 03:36:25 +0000 | [diff] [blame] | 161 | { |
Eric Biederman | 03acab6 | 2004-10-14 21:25:53 +0000 | [diff] [blame] | 162 | return scan_static_bus(root, max); |
| 163 | } |
| 164 | |
| 165 | void root_dev_init(device_t root) |
| 166 | { |
Eric Biederman | e9a271e3 | 2003-09-02 03:36:25 +0000 | [diff] [blame] | 167 | } |
| 168 | |
Yinghai Lu | 13f1c2a | 2005-07-08 02:49:49 +0000 | [diff] [blame] | 169 | void root_dev_reset(struct bus *bus) |
| 170 | { |
| 171 | printk_info("Reseting board...\n"); |
| 172 | hard_reset(); |
| 173 | } |
| 174 | |
Li-Ta Lo | 9782f75 | 2004-05-05 21:15:42 +0000 | [diff] [blame] | 175 | /** |
| 176 | * @brief Default device operation for root device |
| 177 | * |
Li-Ta Lo | 0493069 | 2004-11-25 17:37:19 +0000 | [diff] [blame] | 178 | * This is the default device operation for root devices. These operations |
| 179 | * should be fully usable as is. However the chip_operations::enable_dev() |
| 180 | * of a motherboard can override this if you want non-default behavior. |
Li-Ta Lo | 9782f75 | 2004-05-05 21:15:42 +0000 | [diff] [blame] | 181 | */ |
Eric Biederman | e9a271e3 | 2003-09-02 03:36:25 +0000 | [diff] [blame] | 182 | struct device_operations default_dev_ops_root = { |
| 183 | .read_resources = root_dev_read_resources, |
| 184 | .set_resources = root_dev_set_resources, |
Eric Biederman | 03acab6 | 2004-10-14 21:25:53 +0000 | [diff] [blame] | 185 | .enable_resources = root_dev_enable_resources, |
| 186 | .init = root_dev_init, |
| 187 | .scan_bus = root_dev_scan_bus, |
Yinghai Lu | 13f1c2a | 2005-07-08 02:49:49 +0000 | [diff] [blame] | 188 | .reset_bus = root_dev_reset, |
Eric Biederman | e9a271e3 | 2003-09-02 03:36:25 +0000 | [diff] [blame] | 189 | }; |
| 190 | |
| 191 | /** |
Li-Ta Lo | 0493069 | 2004-11-25 17:37:19 +0000 | [diff] [blame] | 192 | * @brief The root of device tree. |
Li-Ta Lo | fb4c50f | 2004-05-07 21:52:47 +0000 | [diff] [blame] | 193 | * |
Li-Ta Lo | 0493069 | 2004-11-25 17:37:19 +0000 | [diff] [blame] | 194 | * This is the root of the device tree. The device tree is defined in the |
| 195 | * static.c file and is generated by config tool during compile time. |
Eric Biederman | e9a271e3 | 2003-09-02 03:36:25 +0000 | [diff] [blame] | 196 | */ |
Eric Biederman | 7003ba4 | 2004-10-16 06:20:29 +0000 | [diff] [blame] | 197 | extern struct device dev_root; |