svn commit: r257059 - in head/sys/powerpc: include mpc85xx ofw powerpc
Nathan Whitehorn
nwhitehorn at FreeBSD.org
Thu Oct 24 15:37:33 UTC 2013
Author: nwhitehorn
Date: Thu Oct 24 15:37:32 2013
New Revision: 257059
URL: http://svnweb.freebsd.org/changeset/base/257059
Log:
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.
Modified:
head/sys/powerpc/include/intr_machdep.h
head/sys/powerpc/mpc85xx/atpic.c
head/sys/powerpc/ofw/openpic_ofw.c
head/sys/powerpc/powerpc/intr_machdep.c
head/sys/powerpc/powerpc/nexus.c
head/sys/powerpc/powerpc/pic_if.m
Modified: head/sys/powerpc/include/intr_machdep.h
==============================================================================
--- head/sys/powerpc/include/intr_machdep.h Thu Oct 24 15:21:20 2013 (r257058)
+++ head/sys/powerpc/include/intr_machdep.h Thu Oct 24 15:37:32 2013 (r257059)
@@ -56,5 +56,6 @@ int powerpc_setup_intr(const char *, u_i
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_ */
Modified: head/sys/powerpc/mpc85xx/atpic.c
==============================================================================
--- head/sys/powerpc/mpc85xx/atpic.c Thu Oct 24 15:21:20 2013 (r257058)
+++ head/sys/powerpc/mpc85xx/atpic.c Thu Oct 24 15:37:32 2013 (r257059)
@@ -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;
+ }
+}
+
Modified: head/sys/powerpc/ofw/openpic_ofw.c
==============================================================================
--- head/sys/powerpc/ofw/openpic_ofw.c Thu Oct 24 15:21:20 2013 (r257058)
+++ head/sys/powerpc/ofw/openpic_ofw.c Thu Oct 24 15:37:32 2013 (r257059)
@@ -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_meth
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;
+ }
+}
+
Modified: head/sys/powerpc/powerpc/intr_machdep.c
==============================================================================
--- head/sys/powerpc/powerpc/intr_machdep.c Thu Oct 24 15:21:20 2013 (r257058)
+++ head/sys/powerpc/powerpc/intr_machdep.c Thu Oct 24 15:37:32 2013 (r257059)
@@ -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_i
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);
}
@@ -504,6 +514,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)
{
struct powerpc_intr *i;
Modified: head/sys/powerpc/powerpc/nexus.c
==============================================================================
--- head/sys/powerpc/powerpc/nexus.c Thu Oct 24 15:21:20 2013 (r257058)
+++ head/sys/powerpc/powerpc/nexus.c Thu Oct 24 15:37:32 2013 (r257059)
@@ -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
Modified: head/sys/powerpc/powerpc/pic_if.m
==============================================================================
--- head/sys/powerpc/powerpc/pic_if.m Thu Oct 24 15:21:20 2013 (r257058)
+++ head/sys/powerpc/powerpc/pic_if.m Thu Oct 24 15:37:32 2013 (r257059)
@@ -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;
More information about the svn-src-head
mailing list