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:
parent
863bcbff3b
commit
27fbb8428c
6 changed files with 143 additions and 50 deletions
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue