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;
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to