Small tweak to get ACPI watchdog working (iTCO)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



I'm developing an embedded Linux device with an x86 CPU.

I need to start the Intel watchdog timer running before I boot my main
operating system (just in case my OS freezes before it fully loads
up).

I have taken a look at the iTCO branch in the github repository,
however I don't think this driver will work on my own device because
of how the BIOS is configured. (I can't change the BIOS settings).

So what I've done is to take the code for the Linux kernel driver that
can control the Intel watchdog driver via ACPI. This code is found in
the main Linux kernel github repository inside "wdat_wdt.c".

I have taken the code for the Linux kernel ACPI iTCO driver and
littered it with "printk" statements to find out what's happening at
each step. From these printk's, I've been able to reduce my own
Barebox ACPI driver to 8 lines of code. I have used the code in the
Barebox respository file "acpi-test.c" as a guide, and here's what
I've got so far for my driver.

#include <common.h>
#include <init.h>
#include <acpi.h>
#include <restart.h>
#include <watchdog.h>
#include <linux/ioport.h>  /* IORESOURCE_IO, IORESOURCE_MEM */

static int wdat_wdt_probe_GREATLY_SIMPLIFIED(struct device_d *const pdev)
{
    /* This code is adapted from the following printk's
      taken from the Linux kernel driver wdat_wdt:

    Wrote 0x20000 to 0x00000464, Access_with=32bit, pointer=0x00010464
    Wrote 0x1000 to 0x00000468, Access_with=32bit, pointer=0x00010468
    Wrote 0x4 to 0x00000460, Access_with=32bit, pointer=0x00010460
    Wrote 0x640000 to 0x00000470, Access_with=32bit, pointer=0x00010470
    Wrote 0x4 to 0x00000460, Access_with=32bit, pointer=0x00010460
    Wrote 0x4 to 0x00000460, Access_with=32bit, pointer=0x00010460

    Resource=0 : IORESOURCE_IO, start=0x00000460, len=1, reg=0x00010460
    Resource=1 : IORESOURCE_IO, start=0x00000470, len=1, reg=0x00010470
    Resource=2 : IORESOURCE_IO, start=0x00000468, len=1, reg=0x00010468
    Resource=3 : IORESOURCE_IO, start=0x00000464, len=1, reg=0x00010464
    */

    request_ioport_region(dev_name(pdev), 0x460,0x470);

    long long unsigned const base = 0x10460; //For x86, just add
0x10000 to 0x460

    iowrite32(0x20000, (volatile void __iomem *)(base + 4u));
    iowrite32(0x1000, (volatile void __iomem *)(base + 8u));
    iowrite32(0x4, (volatile void __iomem *)(base + 0u));
    iowrite32(0x640000, (volatile void __iomem *)(base + 10u));
    iowrite32(0x4, (volatile void __iomem *)(base + 0u));  // This is a kick
    iowrite32(0x4, (volatile void __iomem *)(base + 0u));  // This is a kick

    return 0;
}

static void Cameron_Remove(struct device_d *const pdev)
{
    printk("Cameron : FADT driver removed\n");
}

static struct acpi_driver Cameron_itco_watchdog_acpi_driver = {
    .signature = "FACP",
    .driver = {
        .name = "Cameron_itco_watchdog_acpi_driver",
        .probe = wdat_wdt_probe_GREATLY_SIMPLIFIED,
        .remove = Cameron_Remove,
    }
};

This code doesn't work and I'm trying to figure out why. The original
Linux kernel driver uses the function "devm_ioport_map", which doesn't
exist in Barebox, and so I've tried to replace it with
"request_ioport_region" but I'm not sure if I'm doing this right --
and I suspect that this is where my driver is failing.

Can anyone please help?

Cameron

_______________________________________________
barebox mailing list
barebox@xxxxxxxxxxxxxxxxxxx
http://lists.infradead.org/mailman/listinfo/barebox



[Index of Archives]     [Linux Embedded]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux