Allow PIC drivers to translate firmware sense codes for themselves. This
is designed to replace the tables in dev/fdt/fdt_ARCH.c, but will not happen quite yet.
This commit is contained in:
parent
6495f64998
commit
544234026d
@ -56,5 +56,6 @@ int powerpc_setup_intr(const char *, u_int, driver_filter_t, driver_intr_t,
|
||||
int powerpc_teardown_intr(void *);
|
||||
int powerpc_bind_intr(u_int irq, u_char cpu);
|
||||
int powerpc_config_intr(int, enum intr_trigger, enum intr_polarity);
|
||||
int powerpc_fw_config_intr(int irq, int sense_code);
|
||||
|
||||
#endif /* _MACHINE_INTR_MACHDEP_H_ */
|
||||
|
@ -79,6 +79,9 @@ static void atpic_ipi(device_t, u_int);
|
||||
static void atpic_mask(device_t, u_int);
|
||||
static void atpic_unmask(device_t, u_int);
|
||||
|
||||
static void atpic_ofw_translate_code(device_t, u_int irq, int code,
|
||||
enum intr_trigger *trig, enum intr_polarity *pol);
|
||||
|
||||
static device_method_t atpic_isa_methods[] = {
|
||||
/* Device interface */
|
||||
DEVMETHOD(device_identify, atpic_isa_identify),
|
||||
@ -94,6 +97,8 @@ static device_method_t atpic_isa_methods[] = {
|
||||
DEVMETHOD(pic_mask, atpic_mask),
|
||||
DEVMETHOD(pic_unmask, atpic_unmask),
|
||||
|
||||
DEVMETHOD(pic_translate_code, atpic_ofw_translate_code),
|
||||
|
||||
{ 0, 0 },
|
||||
};
|
||||
|
||||
@ -325,3 +330,35 @@ atpic_unmask(device_t dev, u_int irq)
|
||||
atpic_write(sc, ATPIC_MASTER, 1, sc->sc_mask[ATPIC_MASTER]);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
atpic_ofw_translate_code(device_t dev, u_int irq, int code,
|
||||
enum intr_trigger *trig, enum intr_polarity *pol)
|
||||
{
|
||||
switch (code) {
|
||||
case 0:
|
||||
/* Active L level */
|
||||
*trig = INTR_TRIGGER_LEVEL;
|
||||
*pol = INTR_POLARITY_LOW;
|
||||
break;
|
||||
case 1:
|
||||
/* Active H level */
|
||||
*trig = INTR_TRIGGER_LEVEL;
|
||||
*pol = INTR_POLARITY_HIGH;
|
||||
break;
|
||||
case 2:
|
||||
/* H to L edge */
|
||||
*trig = INTR_TRIGGER_EDGE;
|
||||
*pol = INTR_POLARITY_LOW;
|
||||
break;
|
||||
case 3:
|
||||
/* L to H edge */
|
||||
*trig = INTR_TRIGGER_EDGE;
|
||||
*pol = INTR_POLARITY_HIGH;
|
||||
break;
|
||||
default:
|
||||
*trig = INTR_TRIGGER_CONFORM;
|
||||
*pol = INTR_POLARITY_CONFORM;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -61,6 +61,9 @@ __FBSDID("$FreeBSD$");
|
||||
static int openpic_ofw_probe(device_t);
|
||||
static int openpic_ofw_attach(device_t);
|
||||
|
||||
static void openpic_ofw_translate_code(device_t, u_int irq, int code,
|
||||
enum intr_trigger *trig, enum intr_polarity *pol);
|
||||
|
||||
static device_method_t openpic_ofw_methods[] = {
|
||||
/* Device interface */
|
||||
DEVMETHOD(device_probe, openpic_ofw_probe),
|
||||
@ -76,6 +79,8 @@ static device_method_t openpic_ofw_methods[] = {
|
||||
DEVMETHOD(pic_mask, openpic_mask),
|
||||
DEVMETHOD(pic_unmask, openpic_unmask),
|
||||
|
||||
DEVMETHOD(pic_translate_code, openpic_ofw_translate_code),
|
||||
|
||||
DEVMETHOD_END
|
||||
};
|
||||
|
||||
@ -127,3 +132,34 @@ openpic_ofw_attach(device_t dev)
|
||||
return (openpic_common_attach(dev, xref));
|
||||
}
|
||||
|
||||
static void
|
||||
openpic_ofw_translate_code(device_t dev, u_int irq, int code,
|
||||
enum intr_trigger *trig, enum intr_polarity *pol)
|
||||
{
|
||||
switch (code) {
|
||||
case 0:
|
||||
/* L to H edge */
|
||||
*trig = INTR_TRIGGER_EDGE;
|
||||
*pol = INTR_POLARITY_HIGH;
|
||||
break;
|
||||
case 1:
|
||||
/* Active L level */
|
||||
*trig = INTR_TRIGGER_LEVEL;
|
||||
*pol = INTR_POLARITY_LOW;
|
||||
break;
|
||||
case 2:
|
||||
/* Active H level */
|
||||
*trig = INTR_TRIGGER_LEVEL;
|
||||
*pol = INTR_POLARITY_HIGH;
|
||||
break;
|
||||
case 3:
|
||||
/* H to L edge */
|
||||
*trig = INTR_TRIGGER_EDGE;
|
||||
*pol = INTR_POLARITY_LOW;
|
||||
break;
|
||||
default:
|
||||
*trig = INTR_TRIGGER_CONFORM;
|
||||
*pol = INTR_POLARITY_CONFORM;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -102,6 +102,7 @@ struct powerpc_intr {
|
||||
cpuset_t cpu;
|
||||
enum intr_trigger trig;
|
||||
enum intr_polarity pol;
|
||||
int fwcode;
|
||||
};
|
||||
|
||||
struct pic {
|
||||
@ -427,6 +428,9 @@ powerpc_enable_intr(void)
|
||||
if (error)
|
||||
continue;
|
||||
|
||||
if (i->trig == -1)
|
||||
PIC_TRANSLATE_CODE(i->pic, i->intline, i->fwcode,
|
||||
&i->trig, &i->pol);
|
||||
if (i->trig != INTR_TRIGGER_CONFORM ||
|
||||
i->pol != INTR_POLARITY_CONFORM)
|
||||
PIC_CONFIG(i->pic, i->intline, i->trig, i->pol);
|
||||
@ -469,15 +473,21 @@ powerpc_setup_intr(const char *name, u_int irq, driver_filter_t filter,
|
||||
if (!cold) {
|
||||
error = powerpc_map_irq(i);
|
||||
|
||||
if (!error && (i->trig != INTR_TRIGGER_CONFORM ||
|
||||
i->pol != INTR_POLARITY_CONFORM))
|
||||
PIC_CONFIG(i->pic, i->intline, i->trig, i->pol);
|
||||
if (!error) {
|
||||
if (i->trig == -1)
|
||||
PIC_TRANSLATE_CODE(i->pic, i->intline,
|
||||
i->fwcode, &i->trig, &i->pol);
|
||||
|
||||
if (i->trig != INTR_TRIGGER_CONFORM ||
|
||||
i->pol != INTR_POLARITY_CONFORM)
|
||||
PIC_CONFIG(i->pic, i->intline, i->trig, i->pol);
|
||||
|
||||
if (!error && i->pic == root_pic)
|
||||
PIC_BIND(i->pic, i->intline, i->cpu);
|
||||
if (i->pic == root_pic)
|
||||
PIC_BIND(i->pic, i->intline, i->cpu);
|
||||
|
||||
if (!error && enable)
|
||||
PIC_ENABLE(i->pic, i->intline, i->vector);
|
||||
if (enable)
|
||||
PIC_ENABLE(i->pic, i->intline, i->vector);
|
||||
}
|
||||
}
|
||||
return (error);
|
||||
}
|
||||
@ -503,6 +513,28 @@ powerpc_bind_intr(u_int irq, u_char cpu)
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
powerpc_fw_config_intr(int irq, int sense_code)
|
||||
{
|
||||
struct powerpc_intr *i;
|
||||
|
||||
i = intr_lookup(irq);
|
||||
if (i == NULL)
|
||||
return (ENOMEM);
|
||||
|
||||
i->trig = -1;
|
||||
i->pol = INTR_POLARITY_CONFORM;
|
||||
i->fwcode = sense_code;
|
||||
|
||||
if (!cold && i->pic != NULL) {
|
||||
PIC_TRANSLATE_CODE(i->pic, i->intline, i->fwcode, &i->trig,
|
||||
&i->pol);
|
||||
PIC_CONFIG(i->pic, i->intline, i->trig, i->pol);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
powerpc_config_intr(int irq, enum intr_trigger trig, enum intr_polarity pol)
|
||||
{
|
||||
|
@ -166,9 +166,7 @@ static int
|
||||
nexus_ofw_config_intr(device_t dev, device_t child, int irq, int sense)
|
||||
{
|
||||
|
||||
return (bus_generic_config_intr(child, irq, (sense & 1) ?
|
||||
INTR_TRIGGER_LEVEL : INTR_TRIGGER_EDGE,
|
||||
INTR_POLARITY_LOW));
|
||||
return (powerpc_fw_config_intr(irq, sense));
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -33,12 +33,31 @@
|
||||
|
||||
INTERFACE pic;
|
||||
|
||||
CODE {
|
||||
static pic_translate_code_t pic_translate_code_default;
|
||||
|
||||
static void pic_translate_code_default(device_t dev, u_int irq,
|
||||
int code, enum intr_trigger *trig, enum intr_polarity *pol)
|
||||
{
|
||||
*trig = INTR_TRIGGER_CONFORM;
|
||||
*pol = INTR_POLARITY_CONFORM;
|
||||
}
|
||||
};
|
||||
|
||||
METHOD void bind {
|
||||
device_t dev;
|
||||
u_int irq;
|
||||
cpuset_t cpumask;
|
||||
};
|
||||
|
||||
METHOD void translate_code {
|
||||
device_t dev;
|
||||
u_int irq;
|
||||
int code;
|
||||
enum intr_trigger *trig;
|
||||
enum intr_polarity *pol;
|
||||
} DEFAULT pic_translate_code_default;
|
||||
|
||||
METHOD void config {
|
||||
device_t dev;
|
||||
u_int irq;
|
||||
|
Loading…
Reference in New Issue
Block a user