Some architectures (as PXA 27x for example) may define GPIO IRQ lines
as outputs since internal circuitry supports such configuration.
This patch simply detects if a GPIO is a IRQ line or not just looking
for IRQ line number, "desc" and "desc->action" fields.
Signed-off-by: Rodolfo Giometti <[email protected]>
Cc: [email protected]
---
drivers/gpio/gpiolib.c | 82 ++++++++++++++++++++++++------------------------
1 files changed, 41 insertions(+), 41 deletions(-)
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 50de0f5..298b66f 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -1381,6 +1381,8 @@ static void gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip)
unsigned gpio = chip->base;
struct gpio_desc *gdesc = &gpio_desc[gpio];
int is_out;
+ int irq;
+ struct irq_desc *desc;
for (i = 0; i < chip->ngpio; i++, gpio++, gdesc++) {
if (!test_bit(FLAG_REQUESTED, &gdesc->flags))
@@ -1394,48 +1396,46 @@ static void gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip)
? (chip->get(chip, i) ? "hi" : "lo")
: "? ");
- if (!is_out) {
- int irq = gpio_to_irq(gpio);
- struct irq_desc *desc = irq_to_desc(irq);
-
- /* This races with request_irq(), set_irq_type(),
- * and set_irq_wake() ... but those are "rare".
- *
- * More significantly, trigger type flags aren't
- * currently maintained by genirq.
- */
- if (irq >= 0 && desc->action) {
- char *trigger;
-
- switch (desc->status & IRQ_TYPE_SENSE_MASK) {
- case IRQ_TYPE_NONE:
- trigger = "(default)";
- break;
- case IRQ_TYPE_EDGE_FALLING:
- trigger = "edge-falling";
- break;
- case IRQ_TYPE_EDGE_RISING:
- trigger = "edge-rising";
- break;
- case IRQ_TYPE_EDGE_BOTH:
- trigger = "edge-both";
- break;
- case IRQ_TYPE_LEVEL_HIGH:
- trigger = "level-high";
- break;
- case IRQ_TYPE_LEVEL_LOW:
- trigger = "level-low";
- break;
- default:
- trigger = "?trigger?";
- break;
- }
-
- seq_printf(s, " irq-%d %s%s",
- irq, trigger,
- (desc->status & IRQ_WAKEUP)
- ? " wakeup" : "");
+ irq = gpio_to_irq(gpio);
+ desc = irq_to_desc(irq);
+
+ /* This races with request_irq(), set_irq_type(),
+ * and set_irq_wake() ... but those are "rare".
+ *
+ * More significantly, trigger type flags aren't
+ * currently maintained by genirq.
+ */
+ if (irq >= 0 && desc && desc->action) {
+ char *trigger;
+
+ switch (desc->status & IRQ_TYPE_SENSE_MASK) {
+ case IRQ_TYPE_NONE:
+ trigger = "(default)";
+ break;
+ case IRQ_TYPE_EDGE_FALLING:
+ trigger = "edge-falling";
+ break;
+ case IRQ_TYPE_EDGE_RISING:
+ trigger = "edge-rising";
+ break;
+ case IRQ_TYPE_EDGE_BOTH:
+ trigger = "edge-both";
+ break;
+ case IRQ_TYPE_LEVEL_HIGH:
+ trigger = "level-high";
+ break;
+ case IRQ_TYPE_LEVEL_LOW:
+ trigger = "level-low";
+ break;
+ default:
+ trigger = "?trigger?";
+ break;
}
+
+ seq_printf(s, " irq-%d %s%s",
+ irq, trigger,
+ (desc->status & IRQ_WAKEUP)
+ ? " wakeup" : "");
}
seq_printf(s, "\n");
--
1.6.3.3
On Tue, Nov 17, 2009 at 5:01 PM, Rodolfo Giometti <[email protected]> wrote:> Some architectures (as PXA 27x for example) may define GPIO IRQ lines> as outputs since internal circuitry supports such configuration.>> This patch simply detects if a GPIO is a IRQ line or not just looking> for IRQ line number, "desc" and "desc->action" fields.>> Signed-off-by: Rodolfo Giometti <[email protected]>> Cc: [email protected]> ---> ?drivers/gpio/gpiolib.c | ? 82 ++++++++++++++++++++++++------------------------> ?1 files changed, 41 insertions(+), 41 deletions(-)>> diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c> index 50de0f5..298b66f 100644> --- a/drivers/gpio/gpiolib.c> +++ b/drivers/gpio/gpiolib.c> @@ -1381,6 +1381,8 @@ static void gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip)> ? ? ? ?unsigned ? ? ? ? ? ? ? ?gpio = chip->base;> ? ? ? ?struct gpio_desc ? ? ? ?*gdesc = &gpio_desc[gpio];> ? ? ? ?int ? ? ? ? ? ? ? ? ? ? is_out;> + ? ? ? int ? ? ? ? ? ? ? ? ? ? irq;> + ? ? ? struct irq_desc ? ? ? ? *desc;>> ? ? ? ?for (i = 0; i < chip->ngpio; i++, gpio++, gdesc++) {> ? ? ? ? ? ? ? ?if (!test_bit(FLAG_REQUESTED, &gdesc->flags))> @@ -1394,48 +1396,46 @@ static void gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip)> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? (chip->get(chip, i) ? "hi" : "lo")> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?: "? ?");>> - ? ? ? ? ? ? ? if (!is_out) {> - ? ? ? ? ? ? ? ? ? ? ? int ? ? ? ? ? ? irq = gpio_to_irq(gpio);> - ? ? ? ? ? ? ? ? ? ? ? struct irq_desc *desc = irq_to_desc(irq);> -> - ? ? ? ? ? ? ? ? ? ? ? /* This races with request_irq(), set_irq_type(),> - ? ? ? ? ? ? ? ? ? ? ? ?* and set_irq_wake() ... but those are "rare".> - ? ? ? ? ? ? ? ? ? ? ? ?*> - ? ? ? ? ? ? ? ? ? ? ? ?* More significantly, trigger type flags aren't> - ? ? ? ? ? ? ? ? ? ? ? ?* currently maintained by genirq.> - ? ? ? ? ? ? ? ? ? ? ? ?*/> - ? ? ? ? ? ? ? ? ? ? ? if (irq >= 0 && desc->action) {> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? char *trigger;> -> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? switch (desc->status & IRQ_TYPE_SENSE_MASK) {> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? case IRQ_TYPE_NONE:> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? trigger = "(default)";> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? case IRQ_TYPE_EDGE_FALLING:> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? trigger = "edge-falling";> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? case IRQ_TYPE_EDGE_RISING:> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? trigger = "edge-rising";> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? case IRQ_TYPE_EDGE_BOTH:> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? trigger = "edge-both";> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? case IRQ_TYPE_LEVEL_HIGH:> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? trigger = "level-high";> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? case IRQ_TYPE_LEVEL_LOW:> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? trigger = "level-low";> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? default:> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? trigger = "?trigger?";> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }> -> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? seq_printf(s, " irq-%d %s%s",> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? irq, trigger,> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (desc->status & IRQ_WAKEUP)> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? " wakeup" : "");> + ? ? ? ? ? ? ? irq = gpio_to_irq(gpio);> + ? ? ? ? ? ? ? desc = irq_to_desc(irq);> +> + ? ? ? ? ? ? ? /* This races with request_irq(), set_irq_type(),> + ? ? ? ? ? ? ? ?* and set_irq_wake() ... but those are "rare".> + ? ? ? ? ? ? ? ?*> + ? ? ? ? ? ? ? ?* More significantly, trigger type flags aren't> + ? ? ? ? ? ? ? ?* currently maintained by genirq.> + ? ? ? ? ? ? ? ?*/> + ? ? ? ? ? ? ? if (irq >= 0 && desc && desc->action) {> + ? ? ? ? ? ? ? ? ? ? ? char *trigger;> +> + ? ? ? ? ? ? ? ? ? ? ? switch (desc->status & IRQ_TYPE_SENSE_MASK) {> + ? ? ? ? ? ? ? ? ? ? ? case IRQ_TYPE_NONE:> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? trigger = "(default)";> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;> + ? ? ? ? ? ? ? ? ? ? ? case IRQ_TYPE_EDGE_FALLING:> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? trigger = "edge-falling";> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;> + ? ? ? ? ? ? ? ? ? ? ? case IRQ_TYPE_EDGE_RISING:> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? trigger = "edge-rising";> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;> + ? ? ? ? ? ? ? ? ? ? ? case IRQ_TYPE_EDGE_BOTH:> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? trigger = "edge-both";> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;> + ? ? ? ? ? ? ? ? ? ? ? case IRQ_TYPE_LEVEL_HIGH:> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? trigger = "level-high";> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;> + ? ? ? ? ? ? ? ? ? ? ? case IRQ_TYPE_LEVEL_LOW:> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? trigger = "level-low";> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;> + ? ? ? ? ? ? ? ? ? ? ? default:> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? trigger = "?trigger?";> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;> ? ? ? ? ? ? ? ? ? ? ? ?}> +> + ? ? ? ? ? ? ? ? ? ? ? seq_printf(s, " irq-%d %s%s",> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? irq, trigger,> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (desc->status & IRQ_WAKEUP)> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? " wakeup" : "");> ? ? ? ? ? ? ? ?}>> ? ? ? ? ? ? ? ?seq_printf(s, "\n");> --> 1.6.3.3
Is there any valid test scenario that makes use of thispatch???Detecting GPIO if it is IRQ in kernel what is the advantage?
Regards,Ram.????{.n?+???????+%?????ݶ??w??{.n?+????{??G?????{ay?ʇڙ?,j??f???h?????????z_??(?階?ݢj"???m??????G????????????&???~???iO???z??v?^?m????????????I?
On Tue, Nov 17, 2009 at 05:15:49PM +0530, Janakiram Sistla wrote:
> On Tue, Nov 17, 2009 at 5:01 PM, Rodolfo Giometti <[email protected]> wrote:
> > Some architectures (as PXA 27x for example) may define GPIO IRQ lines
> > as outputs since internal circuitry supports such configuration.
> >
> > This patch simply detects if a GPIO is a IRQ line or not just looking
> > for IRQ line number, "desc" and "desc->action" fields.
> >
> > Signed-off-by: Rodolfo Giometti <[email protected]>
> > Cc: [email protected]
> > ---
> > ?drivers/gpio/gpiolib.c | ? 82 ++++++++++++++++++++++++------------------------
> > ?1 files changed, 41 insertions(+), 41 deletions(-)
> >
> > diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
> > index 50de0f5..298b66f 100644
> > --- a/drivers/gpio/gpiolib.c
> > +++ b/drivers/gpio/gpiolib.c
> > @@ -1381,6 +1381,8 @@ static void gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip)
> > ? ? ? ?unsigned ? ? ? ? ? ? ? ?gpio = chip->base;
> > ? ? ? ?struct gpio_desc ? ? ? ?*gdesc = &gpio_desc[gpio];
> > ? ? ? ?int ? ? ? ? ? ? ? ? ? ? is_out;
> > + ? ? ? int ? ? ? ? ? ? ? ? ? ? irq;
> > + ? ? ? struct irq_desc ? ? ? ? *desc;
> >
> > ? ? ? ?for (i = 0; i < chip->ngpio; i++, gpio++, gdesc++) {
> > ? ? ? ? ? ? ? ?if (!test_bit(FLAG_REQUESTED, &gdesc->flags))
> > @@ -1394,48 +1396,46 @@ static void gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip)
> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? (chip->get(chip, i) ? "hi" : "lo")
> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?: "? ?");
> >
> > - ? ? ? ? ? ? ? if (!is_out) {
> > - ? ? ? ? ? ? ? ? ? ? ? int ? ? ? ? ? ? irq = gpio_to_irq(gpio);
> > - ? ? ? ? ? ? ? ? ? ? ? struct irq_desc *desc = irq_to_desc(irq);
> > -
> > - ? ? ? ? ? ? ? ? ? ? ? /* This races with request_irq(), set_irq_type(),
> > - ? ? ? ? ? ? ? ? ? ? ? ?* and set_irq_wake() ... but those are "rare".
> > - ? ? ? ? ? ? ? ? ? ? ? ?*
> > - ? ? ? ? ? ? ? ? ? ? ? ?* More significantly, trigger type flags aren't
> > - ? ? ? ? ? ? ? ? ? ? ? ?* currently maintained by genirq.
> > - ? ? ? ? ? ? ? ? ? ? ? ?*/
> > - ? ? ? ? ? ? ? ? ? ? ? if (irq >= 0 && desc->action) {
> > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? char *trigger;
> > -
> > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? switch (desc->status & IRQ_TYPE_SENSE_MASK) {
> > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? case IRQ_TYPE_NONE:
> > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? trigger = "(default)";
> > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
> > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? case IRQ_TYPE_EDGE_FALLING:
> > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? trigger = "edge-falling";
> > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
> > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? case IRQ_TYPE_EDGE_RISING:
> > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? trigger = "edge-rising";
> > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
> > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? case IRQ_TYPE_EDGE_BOTH:
> > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? trigger = "edge-both";
> > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
> > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? case IRQ_TYPE_LEVEL_HIGH:
> > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? trigger = "level-high";
> > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
> > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? case IRQ_TYPE_LEVEL_LOW:
> > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? trigger = "level-low";
> > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
> > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? default:
> > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? trigger = "?trigger?";
> > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
> > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }
> > -
> > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? seq_printf(s, " irq-%d %s%s",
> > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? irq, trigger,
> > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (desc->status & IRQ_WAKEUP)
> > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? " wakeup" : "");
> > + ? ? ? ? ? ? ? irq = gpio_to_irq(gpio);
> > + ? ? ? ? ? ? ? desc = irq_to_desc(irq);
> > +
> > + ? ? ? ? ? ? ? /* This races with request_irq(), set_irq_type(),
> > + ? ? ? ? ? ? ? ?* and set_irq_wake() ... but those are "rare".
> > + ? ? ? ? ? ? ? ?*
> > + ? ? ? ? ? ? ? ?* More significantly, trigger type flags aren't
> > + ? ? ? ? ? ? ? ?* currently maintained by genirq.
> > + ? ? ? ? ? ? ? ?*/
> > + ? ? ? ? ? ? ? if (irq >= 0 && desc && desc->action) {
> > + ? ? ? ? ? ? ? ? ? ? ? char *trigger;
> > +
> > + ? ? ? ? ? ? ? ? ? ? ? switch (desc->status & IRQ_TYPE_SENSE_MASK) {
> > + ? ? ? ? ? ? ? ? ? ? ? case IRQ_TYPE_NONE:
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? trigger = "(default)";
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
> > + ? ? ? ? ? ? ? ? ? ? ? case IRQ_TYPE_EDGE_FALLING:
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? trigger = "edge-falling";
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
> > + ? ? ? ? ? ? ? ? ? ? ? case IRQ_TYPE_EDGE_RISING:
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? trigger = "edge-rising";
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
> > + ? ? ? ? ? ? ? ? ? ? ? case IRQ_TYPE_EDGE_BOTH:
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? trigger = "edge-both";
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
> > + ? ? ? ? ? ? ? ? ? ? ? case IRQ_TYPE_LEVEL_HIGH:
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? trigger = "level-high";
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
> > + ? ? ? ? ? ? ? ? ? ? ? case IRQ_TYPE_LEVEL_LOW:
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? trigger = "level-low";
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
> > + ? ? ? ? ? ? ? ? ? ? ? default:
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? trigger = "?trigger?";
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
> > ? ? ? ? ? ? ? ? ? ? ? ?}
> > +
> > + ? ? ? ? ? ? ? ? ? ? ? seq_printf(s, " irq-%d %s%s",
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? irq, trigger,
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (desc->status & IRQ_WAKEUP)
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? " wakeup" : "");
> > ? ? ? ? ? ? ? ?}
> >
> > ? ? ? ? ? ? ? ?seq_printf(s, "\n");
> > --
> > 1.6.3.3
>
> Is there any valid test scenario that makes use of this
> patch???Detecting GPIO if it is IRQ in kernel what is the advantage?
My PXA270 based board uses a passive electrical circuit to detect a
CARD insert supplied by GPIO output current, so, in order to work, I
need to setup the GPIO as OUTPUT high level and then, thanks to a pull
down, I can read the CARD insert/removal event.
My solution is more generic then current one and applyes to those
architectures whose support such kind of GPIOs (as PXA27x does) with
no drawbacks for others.
Ciao,
Rodolfo
--
GNU/Linux Solutions e-mail: [email protected]
Linux Device Driver [email protected]
Embedded Systems phone: +39 349 2432127
UNIX programming skype: rodolfo.giometti
Freelance ICT Italia - Consulente ICT Italia - http://www.consulenti-ict.it