This patch changes PNP support for devices so that the dts values get passed

in.

include/device/pnp.h:
	Add enable, val, and irq & drq structs.

superio/winbond/w83627hf/superio.c:
	Change functions to operate on children.
	Add device ID to ops.
	Add enables to pnp_dev_info table.
	Fill in dts values.

superio/winbond/w83627hf/dts:
	Get rid of device number parameters.
	Add config parameters so we know when they're set.

device/pnp_device.c:
	Allocate devices as children to SuperIO.

mainboard/amd/serengeti/dts:
	Move ioport so it's found. (Not its permanent resting place I hope.)
	Add enables for KBC, SP1, and HWM to show it off.

Signed-off-by: Myles Watson <mylesgw@gmail.com>
Acked-by: Ronald G. Minnich <rminnich@gmail.com>


git-svn-id: svn://coreboot.org/repository/coreboot-v3@1027 f3766cd6-281f-0410-b1cd-43a5c92072e9
This commit is contained in:
Myles Watson 2008-11-14 21:45:10 +00:00
commit 27fbb8428c
6 changed files with 143 additions and 50 deletions

View file

@ -254,7 +254,12 @@ struct device *alloc_dev(struct bus *parent, struct device_path *path,
last_dev_p = &dev->next;
/* Give the device a name. */
sprintf(dev->dtsname, "dynamic %s", dev_path(dev));
if (dev->id.type == DEVICE_ID_PNP &&
parent->dev->id.type == DEVICE_ID_PNP)
sprintf(dev->dtsname, "%s_pnp_child_%d", parent->dev->dtsname,
dev->path.pnp.device);
else
sprintf(dev->dtsname, "dynamic %s", dev_path(dev));
/* Run the device specific constructor as last part of the chain
* so it gets the chance to overwrite the "inherited" values above
@ -1093,7 +1098,8 @@ void show_devs_tree(struct device *dev, int debug_level, int depth, int linknum)
printk(debug_level, "%s%s(%s): enabled %d have_resources %d devfn %x\n",
depth_str, dev->dtsname, dev_path(dev), dev->enabled,
dev->have_resources,
dev->path.type == DEVICE_PATH_PCI ? dev->path.pci.devfn : 0xff);
dev->path.type == DEVICE_PATH_PCI ? dev->path.pci.devfn :
dev->path.type == DEVICE_PATH_PNP ? dev->path.pnp.device : 0xff);
for (i = 0; i < dev->links; i++) {
for (sibling = dev->link[i].children; sibling;
sibling = sibling->sibling)

View file

@ -156,7 +156,6 @@ static void pnp_get_ioresource(struct device *dev, unsigned int index,
resource = new_resource(dev, index);
/* Initialize the resource. */
resource->limit = 0xffff;
resource->flags |= IORESOURCE_IO;
/* Get the resource size. */
@ -189,6 +188,8 @@ static void pnp_get_ioresource(struct device *dev, unsigned int index,
resource->align = gran;
resource->limit = info->mask | (step - 1);
resource->size = 1 << gran;
resource->base = info->val;
resource->flags |= IORESOURCE_FIXED || IORESOURCE_ASSIGNED;
}
static void get_resources(struct device *dev, struct pnp_info *info)
@ -211,21 +212,29 @@ static void get_resources(struct device *dev, struct pnp_info *info)
resource = new_resource(dev, PNP_IDX_IRQ0);
resource->size = 1;
resource->flags |= IORESOURCE_IRQ;
resource->base = info->irq0.val;
resource->flags |= IORESOURCE_FIXED || IORESOURCE_ASSIGNED;
}
if (info->flags & PNP_IRQ1) {
resource = new_resource(dev, PNP_IDX_IRQ1);
resource->size = 1;
resource->flags |= IORESOURCE_IRQ;
resource->base = info->irq1.val;
resource->flags |= IORESOURCE_FIXED || IORESOURCE_ASSIGNED;
}
if (info->flags & PNP_DRQ0) {
resource = new_resource(dev, PNP_IDX_DRQ0);
resource->size = 1;
resource->flags |= IORESOURCE_DRQ;
resource->base = info->drq0.val;
resource->flags |= IORESOURCE_FIXED || IORESOURCE_ASSIGNED;
}
if (info->flags & PNP_DRQ1) {
resource = new_resource(dev, PNP_IDX_DRQ1);
resource->size = 1;
resource->flags |= IORESOURCE_DRQ;
resource->base = info->drq0.val;
resource->flags |= IORESOURCE_FIXED || IORESOURCE_ASSIGNED;
}
}
@ -243,11 +252,22 @@ void pnp_enable_devices(struct device *base_dev, struct device_operations *ops,
/* Setup the ops and resources on the newly allocated devices. */
for (i = 0; i < functions; i++) {
path.pnp.device = info[i].function;
dev = alloc_find_dev(base_dev->bus, &path, &id);
/* Don't initialize a device multiple times. */
if (dev->ops)
dev = find_dev_path(&base_dev->link[0], &path);
if (dev) {
printk(BIOS_DEBUG,"%s: %s is already at %s.\n",
__func__, dev->dtsname, dev_path(dev));
continue;
}
dev = alloc_dev(&base_dev->link[0], &path, &id);
if (!dev)
printk(BIOS_DEBUG,"%s: Couldn't allocate child %d.\n",
__func__, i);
dev->enabled = info[i].enable;
if (info[i].ops == 0) {
dev->ops = ops;

View file

@ -53,12 +53,13 @@ extern struct device_operations pnp_ops;
/* PNP helper operations */
struct io_info {
unsigned mask, set;
unsigned mask, set, val;
};
struct pnp_info {
struct device_operations *ops;
unsigned function;
unsigned enable;
unsigned flags;
#define PNP_IO0 0x01
#define PNP_IO1 0x02
@ -68,7 +69,7 @@ struct pnp_info {
#define PNP_IRQ1 0x20
#define PNP_DRQ0 0x40
#define PNP_DRQ1 0x80
struct io_info io0, io1, io2, io3;
struct io_info io0, io1, io2, io3, irq0, irq1, drq0, drq1;
};
struct resource *pnp_get_resource(struct device * dev, unsigned index);
void pnp_enable_devices(struct device *dev, struct device_operations *ops,

View file

@ -79,9 +79,11 @@
pci@18,1 {};
pci@18,2 {};
pci@18,3 {};
ioport@2e {
/config/("superio/winbond/w83627hf/dts");
com1enable = "1";
};
};
ioport@2e {
/config/("superio/winbond/w83627hf/dts");
kbenable = "1";
com1enable = "1";
hwmenable = "1";
};
};

View file

@ -23,32 +23,27 @@
/* To override any of these, put the over-ride in mainboard dts. */
/* Floppy */
floppydev = "0x0";
floppyenable = "0";
floppyio = "0x3f0";
floppyirq = "0x60";
floppydrq = "0x02";
/* Parallel port */
ppdev = "2";
ppenable = "0";
ppio = "0x378";
ppirq = "7";
/* COM1 */
com1dev = "2";
com1enable = "0";
com1io = "0x3f8";
com1irq = "4";
/* COM2 */
com2dev = "3";
com2enable = "0";
com2io = "0x2f8";
com2irq = "3";
/* Keyboard */
kbdev = "5";
kbenable = "0";
kbio = "0x60";
kbio2 = "0x62";
@ -56,30 +51,24 @@
kbirq2 = "12";
/* Consumer IR */
cirdev = "6";
cirenable = "0";
/* Game port */
gamedev = "7";
gameenable = "0";
gameio = "0x220";
gameio2 = "0x400";
gameirq = "9";
/* GPIO2 */
gpio2dev = "8";
gpio2enable = "0";
/* GPIO3 */
gpio3dev = "9";
gpio3enable = "0";
/* ACPI */
acpidev = "0xa";
acpienable = "0";
/* Hardware Monitor */
hwmdev = "0xb";
hwmenable = "0";
hwmio = "0x290";
hwmirq = "5";

View file

@ -27,10 +27,8 @@
#include <device/pnp.h>
#include <console.h>
#include <string.h>
//#include <bitops.h>
#include <uart8250.h>
#include <keyboard.h>
// #include <pc80/mc146818rtc.h>
#include <statictree.h>
#include "w83627hf.h"
@ -113,36 +111,29 @@ static void init_hwm(u16 base)
}
}
static void w83627hf_init(struct device * dev)
static void w83627hf_init_func(struct device * dev)
{
struct superio_winbond_w83627hf_dts_config *conf;
struct resource *res0, *res1;
struct pc_keyboard keyboard;
#if 1
printk(BIOS_ERR, "dummy init XXXX\n");
#endif
printk(BIOS_DEBUG, "%s: %s dummy init XXXX\n",__func__, dev->dtsname);
if (!dev->enabled) {
return;
}
conf = dev->device_configuration;
switch(dev->path.pnp.device) {
case W83627HF_SP1:
res0 = find_resource(dev, PNP_IDX_IO0);
#warning init_uart8250
printk(BIOS_DEBUG, "%s: Not calling init_uart8250.\n",__func__);
//init_uart8250(res0->base, &conf->com1);
break;
case W83627HF_SP2:
res0 = find_resource(dev, PNP_IDX_IO0);
#warning init_uart8250
printk(BIOS_DEBUG, "%s: Not calling init_uart8250.\n",__func__);
//init_uart8250(res0->base, &conf->com2);
break;
case W83627HF_KBC:
res0 = find_resource(dev, PNP_IDX_IO0);
res1 = find_resource(dev, PNP_IDX_IO1);
init_pc_keyboard(res0->base, res1->base, &keyboard);
init_pc_keyboard(res0->base, res1->base, NULL);
break;
case W83627HF_HWM:
res0 = find_resource(dev, PNP_IDX_IO0);
@ -177,6 +168,14 @@ void w83627hf_pnp_enable_resources(struct device * dev)
}
void w83627hf_enable_resources(struct device * dev)
{
struct device * child;
for(child = dev->link[0].children; child; child = child->sibling)
if (child->path.type == DEVICE_PATH_PNP)
w83627hf_pnp_enable_resources(child);
}
void w83627hf_pnp_enable(struct device * dev)
{
@ -189,10 +188,22 @@ void w83627hf_pnp_enable(struct device * dev)
pnp_exit_ext_func_mode(dev);
}
}
static void w83627hf_init(struct device * dev)
{
struct device * child;
for(child = dev->link[0].children; child; child = child->sibling)
/* All children should be PNP. */
if (child->path.type == DEVICE_PATH_PNP)
w83627hf_init_func(child);
}
static void phase3_chip_setup_dev(struct device *dev);
struct device_operations w83627hf_ops = {
.id = {.type = DEVICE_ID_PNP},
.phase3_chip_setup_dev = phase3_chip_setup_dev,
.phase3_enable = w83627hf_pnp_enable_resources,
.phase3_enable = w83627hf_enable_resources,
.phase4_read_resources = pnp_read_resources,
.phase4_set_resources = w83627hf_pnp_set_resources,
.phase5_enable_resources = w83627hf_pnp_enable,
@ -200,23 +211,87 @@ struct device_operations w83627hf_ops = {
};
static struct pnp_info pnp_dev_info[] = {
{ &w83627hf_ops, W83627HF_FDC, PNP_IO0 | PNP_IRQ0 | PNP_DRQ0, { 0x07f8, 0}, },
{ &w83627hf_ops, W83627HF_PP, PNP_IO0 | PNP_IRQ0 | PNP_DRQ0, { 0x07f8, 0}, },
{ &w83627hf_ops, W83627HF_SP1, PNP_IO0 | PNP_IRQ0, { 0x7f8, 0 }, },
{ &w83627hf_ops, W83627HF_SP2, PNP_IO0 | PNP_IRQ0, { 0x7f8, 0 }, },
// No 4 { 0,},
{ &w83627hf_ops, W83627HF_KBC, PNP_IO0 | PNP_IO1 | PNP_IRQ0 | PNP_IRQ1, { 0x7ff, 0 }, { 0x7ff, 0x4}, },
{ &w83627hf_ops, W83627HF_CIR, PNP_IO0 | PNP_IRQ0, { 0x7f8, 0 }, },
{ &w83627hf_ops, W83627HF_GAME_MIDI_GPIO1, PNP_IO0 | PNP_IO1 | PNP_IRQ0, { 0x7ff, 0 }, {0x7fe, 0x4}, },
{ &w83627hf_ops, W83627HF_GPIO2, },
{ &w83627hf_ops, W83627HF_GPIO3, },
{ &w83627hf_ops, W83627HF_ACPI, },
{ &w83627hf_ops, W83627HF_HWM, PNP_IO0 | PNP_IRQ0, { 0xff8, 0 }, },
/* Enable, All resources need by dev, io_info_structs */
{ &w83627hf_ops, W83627HF_FDC, 0, PNP_IO0 | PNP_IRQ0 | PNP_DRQ0, { 0x07f8, 0}, },
{ &w83627hf_ops, W83627HF_PP, 0, PNP_IO0 | PNP_IRQ0 | PNP_DRQ0, { 0x07f8, 0}, },
{ &w83627hf_ops, W83627HF_SP1, 0, PNP_IO0 | PNP_IRQ0, { 0x7f8, 0 }, },
{ &w83627hf_ops, W83627HF_SP2, 0, PNP_IO0 | PNP_IRQ0, { 0x7f8, 0 }, },
{ 0,},
{ &w83627hf_ops, W83627HF_KBC, 0, PNP_IO0 | PNP_IO1 | PNP_IRQ0 | PNP_IRQ1, { 0x7ff, 0 }, { 0x7ff, 0x4}, },
{ &w83627hf_ops, W83627HF_CIR, 0,PNP_IO0 | PNP_IRQ0, { 0x7f8, 0 }, },
{ &w83627hf_ops, W83627HF_GAME_MIDI_GPIO1, 0,PNP_IO0 | PNP_IO1 | PNP_IRQ0, { 0x7ff, 0 }, {0x7fe, 0x4}, },
{ &w83627hf_ops, W83627HF_GPIO2, 0 },
{ &w83627hf_ops, W83627HF_GPIO3, 0 },
{ &w83627hf_ops, W83627HF_ACPI, 0 },
{ &w83627hf_ops, W83627HF_HWM, 0, PNP_IO0 | PNP_IRQ0, { 0xff8, 0 }, },
};
static void phase3_chip_setup_dev(struct device *dev)
{
/* Get dts values and populate pnp_dev_info. */
const struct superio_winbond_w83627hf_dts_config * const conf = dev->device_configuration;
/* Floppy */
pnp_dev_info[W83627HF_FDC].enable = conf->floppyenable;
pnp_dev_info[W83627HF_FDC].io0.val = conf->floppyio;
pnp_dev_info[W83627HF_FDC].irq0.val = conf->floppyirq;
pnp_dev_info[W83627HF_FDC].drq0.val = conf->floppydrq;
/* Parallel port */
pnp_dev_info[W83627HF_PP].enable = conf->ppenable;
pnp_dev_info[W83627HF_PP].io0.val = conf->ppio;
pnp_dev_info[W83627HF_PP].irq0.val = conf->ppirq;
/* COM1 */
pnp_dev_info[W83627HF_SP1].enable = conf->com1enable;
pnp_dev_info[W83627HF_SP1].io0.val = conf->com1io;
pnp_dev_info[W83627HF_SP1].irq0.val = conf->com1irq;
/* COM2 */
pnp_dev_info[W83627HF_SP2].enable = conf->com2enable;
pnp_dev_info[W83627HF_SP2].io0.val = conf->com2io;
pnp_dev_info[W83627HF_SP2].irq0.val = conf->com2irq;
/* Keyboard */
pnp_dev_info[W83627HF_KBC].enable = conf->kbenable;
pnp_dev_info[W83627HF_KBC].io0.val = conf->kbio;
pnp_dev_info[W83627HF_KBC].io1.val = conf->kbio2;
pnp_dev_info[W83627HF_KBC].irq0.val = conf->kbirq;
pnp_dev_info[W83627HF_KBC].irq1.val = conf->kbirq2;
/* Consumer IR */
pnp_dev_info[W83627HF_CIR].enable = conf->cirenable;
/* Game port */
pnp_dev_info[W83627HF_GAME_MIDI_GPIO1].enable = conf->gameenable;
pnp_dev_info[W83627HF_GAME_MIDI_GPIO1].io0.val = conf->gameio;
pnp_dev_info[W83627HF_GAME_MIDI_GPIO1].io1.val = conf->gameio2;
pnp_dev_info[W83627HF_GAME_MIDI_GPIO1].irq0.val = conf->gameirq;
/* GPIO2 */
pnp_dev_info[W83627HF_GPIO2].enable = conf->gpio2enable;
/* GPIO3 */
pnp_dev_info[W83627HF_GPIO3].enable = conf->gpio3enable;
/* ACPI */
pnp_dev_info[W83627HF_ACPI].enable = conf->acpienable;
/* Hardware Monitor */
pnp_dev_info[W83627HF_HWM].enable = conf->hwmenable;
pnp_dev_info[W83627HF_HWM].io0.val = conf->hwmio;
pnp_dev_info[W83627HF_HWM].irq0.val = conf->hwmirq;
/* Initialize SuperIO for PNP children. */
if (!dev->links) {
dev->links = 1;
dev->link[0].dev = dev;
dev->link[0].children = NULL;
dev->link[0].link = 0;
}
/* Call init with updated tables to create children. */
pnp_enable_devices(dev, &w83627hf_ops, ARRAY_SIZE(pnp_dev_info), pnp_dev_info);
}