2003-07-21 01:28:01 +02:00
|
|
|
/* chips are arbitrary chips (superio, southbridge, etc.)
|
|
|
|
* They have private structures that define chip resources and default
|
|
|
|
* settings. They have four externally visible functions for control.
|
|
|
|
* They have a generic component which applies to all chips for
|
|
|
|
* path, etc.
|
|
|
|
*/
|
|
|
|
|
2003-09-02 05:36:25 +02:00
|
|
|
#include <console/console.h>
|
2003-07-21 01:28:01 +02:00
|
|
|
#include <device/chip.h>
|
2003-09-02 05:36:25 +02:00
|
|
|
#include <device/pci.h>
|
2003-07-21 01:28:01 +02:00
|
|
|
|
|
|
|
void
|
|
|
|
chip_configure(struct chip *root, enum chip_pass pass)
|
|
|
|
{
|
2003-07-21 06:20:08 +02:00
|
|
|
struct chip *c;
|
|
|
|
|
|
|
|
for (c = root; c; c = c->next) {
|
2003-07-23 23:34:46 +02:00
|
|
|
if (c->control && c->control->enable)
|
|
|
|
c->control->enable(c, pass);
|
2003-07-21 06:20:08 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
for (c = root; c; c = c->next) {
|
2003-07-23 23:34:46 +02:00
|
|
|
if (c->children)
|
|
|
|
chip_configure(c->children, pass);
|
2003-07-21 01:28:01 +02:00
|
|
|
}
|
|
|
|
}
|
2003-09-02 05:36:25 +02:00
|
|
|
|
|
|
|
/** Convert a static struct chip structure to a set of dynamic device structures.
|
|
|
|
* @param chip Static chip structure to start with.
|
|
|
|
*/
|
|
|
|
|
|
|
|
void chip_enumerate(struct chip *chip)
|
|
|
|
{
|
|
|
|
struct chip *child;
|
|
|
|
device_t dev;
|
|
|
|
int link;
|
|
|
|
int i;
|
|
|
|
dev = 0;
|
|
|
|
link = 0;
|
|
|
|
#if 1
|
|
|
|
if (chip->control && chip->control->name) {
|
|
|
|
printk_debug("Enumerating: %s\n", chip->control->name);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
for(i = 0; i < MAX_CHIP_PATHS; i++) {
|
|
|
|
int identical_paths;
|
|
|
|
identical_paths =
|
|
|
|
(i > 0) &&
|
2003-10-11 08:20:25 +02:00
|
|
|
(path_eq(&chip->path[i - 1].path, &chip->path[i].path));
|
2003-09-02 05:36:25 +02:00
|
|
|
if (!identical_paths) {
|
2003-10-11 08:20:25 +02:00
|
|
|
struct bus *parent;
|
|
|
|
int bus;
|
2003-09-02 05:36:25 +02:00
|
|
|
link = 0;
|
|
|
|
dev = 0;
|
2003-10-11 08:20:25 +02:00
|
|
|
parent = chip->bus;
|
2003-09-02 05:36:25 +02:00
|
|
|
switch(chip->path[i].path.type) {
|
|
|
|
case DEVICE_PATH_NONE:
|
|
|
|
break;
|
2003-10-11 08:20:25 +02:00
|
|
|
case DEVICE_PATH_PCI:
|
|
|
|
bus = chip->path[i].path.u.pci.bus;
|
|
|
|
if (bus != 0) {
|
|
|
|
device_t dev;
|
|
|
|
int i = 1;
|
|
|
|
dev = chip->dev;
|
|
|
|
while(dev && (i != bus)) {
|
|
|
|
dev = dev->next;
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
if ((i == bus) && dev) {
|
|
|
|
parent = &dev->link[0];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* Fall through */
|
2003-09-02 05:36:25 +02:00
|
|
|
default:
|
2003-10-11 08:20:25 +02:00
|
|
|
dev = alloc_dev(parent, &chip->path[i].path);
|
2003-09-02 05:36:25 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
link += 1;
|
|
|
|
}
|
|
|
|
if (dev) {
|
2004-03-11 16:01:31 +01:00
|
|
|
struct chip_resource *res, *res_limit;
|
2003-10-11 08:20:25 +02:00
|
|
|
printk_spew("path (%p) %s %s", dev, dev_path(dev), identical_paths?"identical":"");
|
|
|
|
printk_spew(" parent: (%p) %s\n",dev->bus->dev, dev_path(dev->bus->dev));
|
|
|
|
dev->chip = chip;
|
2003-09-02 05:36:25 +02:00
|
|
|
dev->enable = chip->path[i].enable;
|
|
|
|
dev->links = link + 1;
|
|
|
|
for(child = chip->children; child; child = child->next) {
|
2003-10-11 08:20:25 +02:00
|
|
|
if (!child->bus && child->link == i) {
|
2003-09-02 05:36:25 +02:00
|
|
|
child->bus = &dev->link[link];
|
|
|
|
}
|
|
|
|
}
|
2004-03-11 16:01:31 +01:00
|
|
|
res = &chip->path[i].resource[0];
|
|
|
|
res_limit = &chip->path[i].resource[MAX_RESOURCES];
|
|
|
|
for(; res < res_limit; res++) {
|
|
|
|
if (res->flags) {
|
|
|
|
struct resource *resource;
|
|
|
|
resource = get_resource(dev, res->index);
|
|
|
|
resource->flags = res->flags | IORESOURCE_FIXED | IORESOURCE_ASSIGNED;
|
|
|
|
resource->base = res->base;
|
|
|
|
}
|
|
|
|
}
|
2003-09-02 05:36:25 +02:00
|
|
|
}
|
|
|
|
if (dev && !chip->dev) {
|
|
|
|
chip->dev = dev;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for(child = chip->children; child; child = child->next) {
|
|
|
|
if (!child->bus) {
|
|
|
|
child->bus = &chip->dev->link[0];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void enumerate_static_device_chain(struct chip *root)
|
|
|
|
{
|
|
|
|
struct chip *chip;
|
|
|
|
for(chip = root; chip; chip = chip->next) {
|
|
|
|
void (*enumerate)(struct chip *chip);
|
|
|
|
enumerate = chip_enumerate;
|
|
|
|
if (chip->control && chip->control->enumerate) {
|
|
|
|
enumerate = chip->control->enumerate;
|
|
|
|
}
|
|
|
|
enumerate(chip);
|
|
|
|
}
|
|
|
|
|
|
|
|
for(chip = root; chip; chip = chip->next) {
|
|
|
|
if (chip->children) {
|
|
|
|
enumerate_static_device_chain(chip->children);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void enumerate_static_devices(void)
|
|
|
|
{
|
|
|
|
enumerate_static_device_chain(&static_root);
|
|
|
|
}
|