Hi,
I've been running voyage 0.9.5 & kernel 3.14.12 on PCEngines APU board
for a long time
without any problem.
Last week I got my first APU-2 board and I migrated my system to it.
I experienced system freezings at the end of the boot process some
times, and many
kernel (3.14.12) crashes during the reboot and halt,
---
[ 352.370331] INFO: rcu_sched self-detected stall on CPU { 3} (t=60000
jiffies g=6765 c=6764 q=3054)
[ 352.379509] sending NMI to all CPUs:
[ 352.383105] NMI backtrace for cpu 3
[ 352.386626] CPU: 3 PID: 5664 Comm: postdrop Not tainted
3.14.12-iGetech #1
[ 352.393571] Hardware name: PC Engines apu2/apu2, BIOS 88a4f96 03/07/2016
[ 352.400298] task: ffff8800d81020d0 ti: ffff8800d819c000 task.ti:
ffff8800d819c000
[ 352.407807] RIP: 0010:[<ffffffff811d863b>] [<ffffffff811d863b>]
delay_tsc+0xf/0x4b
[ 352.415532] RSP: 0018:ffff88011ed83ae0 EFLAGS: 00000807
...
I updated my voyage 0.9.5 to kernel 4.1.6 version. Now there is NO
crashes during reboot and halt
but I still have freezings at the end of the boot process few times.
Is it going to help migrating to voyage 0.10.0? does anyone have long
experience using APU-2 and
any version of voyage linux and kernel?
PD: I'm running on a mSATA drive.
BTW: I've created a patch for the kernel 4.1.6 to use the 3 front LEDs
on top of a GPIO driver (also included)
for the front LEDs and the front PUSH BUTTON, which replaces the
existing LED driver in the 4.1.6 that, I think, only
works for the 3 LEDs.
--
Jordi Ferrer
Cap Àrea I+D+i
Mòbil: 634 631 625 | Ext. 2005
iGetech Innova SL | C/Bòsnia, 6-8 | 17800 - Olot, Girona
Tel. (+34) 972 264 667 | http://www.igetech.com
--- config-4.1.6 2016-09-30 16:11:43.365420541 +0200
+++ config-4.1.6-gpio-leds-apu2 2016-09-30 16:17:00.717407464 +0200
@@ -2652,6 +2652,7 @@
# CONFIG_GPIO_IT8761E is not set
# CONFIG_GPIO_LYNXPOINT is not set
CONFIG_GPIO_FCH=y
+CONFIG_GPIO_APU2=y
# CONFIG_GPIO_SCH is not set
# CONFIG_GPIO_SCH311X is not set
# CONFIG_GPIO_VX855 is not set
@@ -4178,7 +4179,7 @@
# CONFIG_LEDS_BLINKM is not set
# CONFIG_LEDS_PM8941_WLED is not set
CONFIG_LEDS_APU=y
-CONFIG_LEDS_APU2=m
+CONFIG_LEDS_APU2=y
#
# LED Triggers
diff -Naur linux-source-4.1.6-voyage/drivers/gpio/Kconfig linux-source-4.1.6-iGetech/drivers/gpio/Kconfig
--- linux-source-4.1.6-voyage/drivers/gpio/Kconfig 2015-11-02 08:48:44.000000000 +0100
+++ linux-source-4.1.6-iGetech/drivers/gpio/Kconfig 2016-09-28 18:21:54.374434660 +0200
@@ -256,6 +256,18 @@
use them with care. For instance, PC Engines APU board users
should only use GPIO 187 (in), 189 (out), 190 (out), 191 (out).
+config GPIO_APU2
+ tristate "PC Engines APU2 AMD FCH GPIO"
+ depends on PCI && X86
+ default m
+ help
+ GPIO interface for PC Engines APU2 AMD FCH Controller.
+ Available GPIOs are 32, 57-59.
+
+ Part of GPIOs is usually occupied by BIOS for it's internal needs, so
+ use them with care. For instance, PC Engines APU2 board users
+ should only use GPIO 32 (in), 57 (out), 58 (out), 59 (out).
+
config GPIO_MM_LANTIQ
bool "Lantiq Memory mapped GPIOs"
depends on LANTIQ && SOC_XWAY
diff -Naur linux-source-4.1.6-voyage/drivers/gpio/Makefile linux-source-4.1.6-iGetech/drivers/gpio/Makefile
--- linux-source-4.1.6-voyage/drivers/gpio/Makefile 2015-11-02 08:48:44.000000000 +0100
+++ linux-source-4.1.6-iGetech/drivers/gpio/Makefile 2016-09-28 18:23:24.707435453 +0200
@@ -33,6 +33,7 @@
obj-$(CONFIG_GPIO_EM) += gpio-em.o
obj-$(CONFIG_GPIO_EP93XX) += gpio-ep93xx.o
obj-$(CONFIG_GPIO_FCH) += gpio-fch.o
+obj-$(CONFIG_GPIO_APU2) += gpio-apu2.o
obj-$(CONFIG_GPIO_F7188X) += gpio-f7188x.o
obj-$(CONFIG_GPIO_GE_FPGA) += gpio-ge.o
obj-$(CONFIG_GPIO_GRGPIO) += gpio-grgpio.o
diff -Naur linux-source-4.1.6-voyage/drivers/gpio/gpio-apu2.c linux-source-4.1.6-iGetech/drivers/gpio/gpio-apu2.c
--- linux-source-4.1.6-voyage/drivers/gpio/gpio-apu2.c 1970-01-01 01:00:00.000000000 +0100
+++ linux-source-4.1.6-iGetech/drivers/gpio/gpio-apu2.c 2016-09-28 18:20:51.334434106 +0200
@@ -0,0 +1,253 @@
+/*
+ * gpio-apu2.c - AMD FCH GPIO support for PC-Engines APU2 board
+ *
+ * Copyright (c) 2015 Carsten Spiess <fli4l at carsten-spiess.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/miscdevice.h>
+#include <linux/gpio.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
+#include <linux/uaccess.h>
+#include <linux/io.h>
+#include <linux/version.h>
+
+#define DEVNAME "gpio-apu2"
+
+#define FCH_ACPI_MMIO_BASE 0xFED80000
+#define FCH_GPIO_BASE (FCH_ACPI_MMIO_BASE + 0x1500)
+#define FCH_GPIO_SIZE 0x300
+
+#define APU2_NUM_GPIO 4
+
+#define GPIO_BIT_DIR 23
+#define GPIO_BIT_WRITE 22
+#define GPIO_BIT_READ 16
+
+/* internal variables */
+static struct pci_dev *gpio_apu2_pci;
+static DEFINE_SPINLOCK ( gpio_lock);
+
+/* the watchdog platform device */
+static struct platform_device *gpio_apu2_platform_device;
+
+static const struct pci_device_id gpio_apu2_pci_tbl[] ={
+ {PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_HUDSON2_SMBUS, PCI_ANY_ID, PCI_ANY_ID},
+ { 0, } /* End of list */
+};
+MODULE_DEVICE_TABLE ( pci, gpio_apu2_pci_tbl);
+
+/* EGPIO89=GPIO32, AGPIO68=GPIO57, AGPIO69=GPIO58, AGPIO70=GPIO59 */
+static u8 gpio_offset[APU2_NUM_GPIO] = {89, 68, 69, 70};
+
+static void __iomem *gpio_addr[APU2_NUM_GPIO] = {NULL, NULL, NULL, NULL};
+
+static int gpio_apu2_get_dir (struct gpio_chip *chip, unsigned offset)
+{
+ u32 val;
+
+ val = ~ioread32 (gpio_addr[offset]);
+
+ return (val >> GPIO_BIT_DIR) & 1;
+}
+
+static int gpio_apu2_dir_in (struct gpio_chip *gc, unsigned offset)
+{
+ u32 val;
+
+ spin_lock_bh (&gpio_lock);
+
+ val = ioread32 (gpio_addr[offset]);
+ val &= ~BIT(GPIO_BIT_DIR);
+ iowrite32 (val, gpio_addr[offset]);
+
+ spin_unlock_bh (&gpio_lock);
+
+ return 0;
+}
+
+static int gpio_apu2_dir_out (struct gpio_chip *chip, unsigned offset,
+ int value)
+{
+ u32 val;
+
+ spin_lock_bh (&gpio_lock);
+
+ val = ioread32 (gpio_addr[offset]);
+ val |= BIT(GPIO_BIT_DIR);
+ iowrite32 (val, gpio_addr[offset]);
+
+ spin_unlock_bh (&gpio_lock);
+
+ return 0;
+}
+
+static int gpio_apu2_get_data (struct gpio_chip *chip, unsigned offset)
+{
+ u32 val;
+
+ val = ioread32 (gpio_addr[offset]);
+
+ return (val >> GPIO_BIT_READ) & 1;
+}
+
+static void gpio_apu2_set_data (struct gpio_chip *chip, unsigned offset, int value)
+{
+ u32 val;
+
+ spin_lock_bh (&gpio_lock);
+
+ val = ioread32 (gpio_addr[offset]);
+
+ if (value)
+ val |= BIT(GPIO_BIT_WRITE);
+ else
+ val &= ~BIT(GPIO_BIT_WRITE);
+
+ iowrite32 (val, gpio_addr[offset]);
+
+ spin_unlock_bh (&gpio_lock);
+}
+
+static struct gpio_chip gpio_apu2_chip = {
+ .label = DEVNAME,
+ .owner = THIS_MODULE,
+ .base = -1,
+ .ngpio = APU2_NUM_GPIO,
+ .get_direction = gpio_apu2_get_dir,
+ .direction_input = gpio_apu2_dir_in,
+ .direction_output = gpio_apu2_dir_out,
+ .get = gpio_apu2_get_data,
+ .set = gpio_apu2_set_data,
+};
+
+/*
+ *
+ */
+static int gpio_apu2_probe (struct platform_device *dev)
+{
+ int ret = 0;
+ int i;
+ struct pci_dev *pci_dev = NULL;
+ u32 pmval;
+
+ /* Match the PCI device */
+ for_each_pci_dev (pci_dev) {
+ if (pci_match_id (gpio_apu2_pci_tbl, pci_dev) != NULL) {
+ gpio_apu2_pci = pci_dev;
+ break;
+ }
+ }
+
+ if (!gpio_apu2_pci)
+ return -ENODEV;
+
+ pr_info ("PCI Revision ID: 0x%x\n", gpio_apu2_pci->revision);
+
+ /* Determine type of southbridge chipset */
+ if (gpio_apu2_pci->revision < 0x40) {
+ return -EACCES;
+ }
+
+ /* Request memory region for GPIO's */
+ if (!devm_request_mem_region (&dev->dev, FCH_GPIO_BASE,
+ FCH_GPIO_SIZE, DEVNAME)){
+ pr_err ("request GPIO mem region failed\n");
+ return -ENXIO;
+ }
+
+ /* Map IO's for GPIO's */
+ for (i = 0; i < APU2_NUM_GPIO; i++) {
+ gpio_addr[i] = devm_ioremap (&dev->dev,
+ FCH_GPIO_BASE + (gpio_offset[i] * sizeof (u32)), sizeof (u32));
+ if (!gpio_addr[i]) {
+ pr_err ("map GPIO%d address failed\n", gpio_offset[i]);
+ return -ENXIO;
+ }
+ }
+
+ gpio_apu2_chip.dev = &dev->dev;
+ ret = gpiochip_add (&gpio_apu2_chip);
+ if (ret) {
+ pr_err ("adding gpiochip failed\n");
+ }
+
+ return ret;
+}
+
+static int gpio_apu2_remove (struct platform_device *dev)
+{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,18,0)
+ int ret;
+ ret = gpiochip_remove (&gpio_apu2_chip);
+#else /* LINUX_VERSION_CODE < KERNEL_VERSION(3,18,0) */
+ gpiochip_remove (&gpio_apu2_chip);
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3,18,0) */
+ return 0;
+}
+
+static struct platform_driver gpio_apu2_driver = {
+ .probe = gpio_apu2_probe,
+ .remove = gpio_apu2_remove,
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = DEVNAME
+ }
+};
+
+static int __init gpio_apu2_init (void)
+{
+ int err;
+
+ pr_info ("load APU2 GPIO driver module\n");
+
+ err = platform_driver_register (&gpio_apu2_driver);
+ if (err)
+ goto exit;
+
+ gpio_apu2_platform_device = platform_device_register_simple (DEVNAME, -1, NULL, 0);
+ if (IS_ERR(gpio_apu2_platform_device)) {
+ err = PTR_ERR(gpio_apu2_platform_device);
+ goto exit_driver;
+ }
+
+ pr_info ("APU2 GPIO driver module loaded\n");
+ return 0;
+
+exit_driver:
+ platform_driver_unregister (&gpio_apu2_driver);
+exit:
+ return err;
+}
+
+static void __exit gpio_apu2_exit (void)
+{
+ platform_device_unregister (gpio_apu2_platform_device);
+ platform_driver_unregister (&gpio_apu2_driver);
+ pr_info ("APU2 GPIO driver module unloaded\n");
+}
+
+MODULE_AUTHOR ("Carsten Spiess <fli4l at carsten-spiess.de>");
+MODULE_DESCRIPTION("GPIO driver for AMD FCH on PC-Engines APU2");
+MODULE_LICENSE("GPL");
+
+module_init (gpio_apu2_init);
+module_exit (gpio_apu2_exit);
diff -Naur linux-source-4.1.6-voyage/drivers/leds/Kconfig linux-source-4.1.6-iGetech/drivers/leds/Kconfig
--- linux-source-4.1.6-voyage/drivers/leds/Kconfig 2016-06-01 12:55:11.000000000 +0200
+++ linux-source-4.1.6-iGetech/drivers/leds/Kconfig 2016-09-28 18:26:24.576437032 +0200
@@ -547,10 +547,16 @@
(GPIO_FCH & LEDS_GPIO) to actually use the LEDs
config LEDS_APU2
- tristate "LED Support for the PC Engines APU2 series LEDs"
+ bool "PC Engines APU2 GPIO-based LED Driver"
depends on LEDS_CLASS
- help
- This option enables support for the PCEngines APU programmable LEDs.
+ depends on GPIOLIB
+ select GPIO_APU2
+ select LEDS_GPIO
+ ---help---
+ This option sets up LEDs using GPIO control on PC Engines APU2 board.
+
+ Note: You must still enable the drivers for GPIO and LED support
+ (GPIO_APU2 & LEDS_GPIO) to actually use the LEDs
comment "LED Triggers"
source "drivers/leds/trigger/Kconfig"
diff -Naur linux-source-4.1.6-voyage/drivers/leds/leds-apu2.c linux-source-4.1.6-iGetech/drivers/leds/leds-apu2.c
--- linux-source-4.1.6-voyage/drivers/leds/leds-apu2.c 2016-06-01 12:55:11.000000000 +0200
+++ linux-source-4.1.6-iGetech/drivers/leds/leds-apu2.c 2016-09-28 18:21:10.802434277 +0200
@@ -1,201 +1,139 @@
/*
- * LEDs driver for PCEngines apu2
+ * Set up PC Engines APU2 board front LEDs using GPIOLIB and GPIO-APU2
+ * drivers. This driver is based on the leds-apu.
*
- * Copyright (C) 2016 Christian Herzog <dad...@daduke.org>, based on
- * Petr Leibman's leds-alix
- * Based on leds-wrap.c
+ * Copyright (C) 2016 Jordi Ferrer Plana <jfer...@igetech.com>
*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License 2 as published
+ * by the Free Software Foundation.
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/kernel.h>
-#include <linux/module.h>
#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/leds.h>
-#include <linux/err.h>
-#include <asm/io.h>
#include <linux/io.h>
+#include <linux/string.h>
+#include <linux/module.h>
+#include <linux/leds.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/input.h>
+#include <linux/gpio_keys.h>
+#include <linux/dmi.h>
+
+/* Module Information */
+#define APU2_MODULE_NAME "leds-apu2"
+#define APU2_MODULE_VER "0.1"
+#define APU2_DRIVER_NAME (APU2_MODULE_NAME " (v" APU2_MODULE_VER ")")
-#define DRVNAME "apu2-led"
-
-#define FCH_ACPI_MMIO_BASE 0xFED80000
-#define FCH_GPIO_BASE (FCH_ACPI_MMIO_BASE + 0x1500)
-#define FCH_GPIO_SIZE 0x300
-#define GPIO_BIT_WRITE 22
-static DEFINE_SPINLOCK ( gpio_lock);
-
-#define APU2_NUM_GPIO 4
-static u8 gpio_offset[APU2_NUM_GPIO] = {89, 68, 69, 70};
-
-static void __iomem *gpio_addr[APU2_NUM_GPIO] = {NULL, NULL, NULL, NULL};
-
-static struct platform_device *pdev;
-
-static void apu2_led_set_1(struct led_classdev *led_cdev, enum led_brightness value) {
- u32 val;
-
- spin_lock_bh (&gpio_lock);
-
- val = ioread32 (gpio_addr[1]);
-
- if (value)
- val &= ~BIT(GPIO_BIT_WRITE);
- else
- val |= BIT(GPIO_BIT_WRITE);
-
- iowrite32 (val, gpio_addr[1]);
-
- spin_unlock_bh (&gpio_lock);
-}
-
-static void apu2_led_set_2(struct led_classdev *led_cdev, enum led_brightness value) {
- u32 val;
-
- spin_lock_bh (&gpio_lock);
-
- val = ioread32 (gpio_addr[2]);
-
- if (value)
- val &= ~BIT(GPIO_BIT_WRITE);
- else
- val |= BIT(GPIO_BIT_WRITE);
-
- iowrite32 (val, gpio_addr[2]);
-
- spin_unlock_bh (&gpio_lock);
-}
-
-static void apu2_led_set_3(struct led_classdev *led_cdev, enum led_brightness value) {
- u32 val;
-
- spin_lock_bh (&gpio_lock);
-
- val = ioread32 (gpio_addr[3]);
-
- if (value)
- val &= ~BIT(GPIO_BIT_WRITE);
- else
- val |= BIT(GPIO_BIT_WRITE);
-
- iowrite32 (val, gpio_addr[3]);
-
- spin_unlock_bh (&gpio_lock);
-}
+static struct gpio_keys_button apu2_gpio_buttons[] = {
+ {
+ .code = KEY_RESTART,
+ .gpio = 508,
+ .active_low = 1,
+ .desc = "Reset button",
+ .type = EV_KEY,
+ .wakeup = 0,
+ .debounce_interval = 100,
+ .can_disable = 0,
+ }
+};
+static struct gpio_keys_platform_data apu2_buttons_data = {
+ .buttons = apu2_gpio_buttons,
+ .nbuttons = ARRAY_SIZE(apu2_gpio_buttons),
+ .poll_interval = 20,
+};
-static struct led_classdev apu2_led_1 = {
- .name = "apu2:1",
- .brightness_set = apu2_led_set_1,
+static struct platform_device apu2_buttons_dev = {
+ .name = "gpio-keys-polled",
+ .id = 1,
+ .dev = {
+ .platform_data = &apu2_buttons_data,
+ }
};
-static struct led_classdev apu2_led_2 = {
- .name = "apu2:2",
- .brightness_set = apu2_led_set_2,
+static struct gpio_led apu2_leds[] = {
+ {
+ .name = "apu2:1",
+ .gpio = 509,
+ .default_trigger = "default-on",
+ .active_low = 1,
+ },
+ {
+ .name = "apu2:2",
+ .gpio = 510,
+ .default_trigger = "default-off",
+ .active_low = 1,
+ },
+ {
+ .name = "apu2:3",
+ .gpio = 511,
+ .default_trigger = "default-off",
+ .active_low = 1,
+ },
};
-static struct led_classdev apu2_led_3 = {
- .name = "apu2:3",
- .brightness_set = apu2_led_set_3,
+static struct gpio_led_platform_data apu2_leds_data = {
+ .num_leds = ARRAY_SIZE(apu2_leds),
+ .leds = apu2_leds,
};
-#ifdef CONFIG_PM
-static int apu2_led_suspend(struct platform_device *dev,
- pm_message_t state)
-{
- led_classdev_suspend(&apu2_led_1);
- led_classdev_suspend(&apu2_led_2);
- led_classdev_suspend(&apu2_led_3);
- return 0;
-}
+static struct platform_device apu2_leds_dev = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev.platform_data = &apu2_leds_data,
+};
-static int apu2_led_resume(struct platform_device *dev)
-{
- led_classdev_resume(&apu2_led_1);
- led_classdev_resume(&apu2_led_2);
- led_classdev_resume(&apu2_led_3);
- return 0;
-}
-#else
-#define apu2_led_suspend NULL
-#define apu2_led_resume NULL
-#endif
+static struct __initdata platform_device *apu2_devs[] = {
+ &apu2_buttons_dev,
+ &apu2_leds_dev,
+};
-static int apu2_led_probe(struct platform_device *pdev)
+static void __init register_apu2(void)
{
- int ret;
-
- ret = led_classdev_register(&pdev->dev, &apu2_led_1);
- if (ret == 0)
- {
- ret = led_classdev_register(&pdev->dev, &apu2_led_2);
- if (ret >= 0)
- {
- ret = led_classdev_register(&pdev->dev, &apu2_led_3);
- if (ret < 0)
- led_classdev_unregister(&apu2_led_2);
- }
- if (ret < 0)
- led_classdev_unregister(&apu2_led_1);
- }
- return ret;
+ /* Setup LED control through leds-gpio driver */
+ platform_add_devices(apu2_devs, ARRAY_SIZE(apu2_devs));
}
-static int apu2_led_remove(struct platform_device *pdev)
+static bool __init apu2_present_dmi(void)
{
- led_classdev_unregister(&apu2_led_1);
- led_classdev_unregister(&apu2_led_2);
- led_classdev_unregister(&apu2_led_3);
-
- return 0;
-}
+ const char *vendor, *product;
-static struct platform_driver apu2_led_driver = {
- .probe = apu2_led_probe,
- .remove = apu2_led_remove,
- .suspend = apu2_led_suspend,
- .resume = apu2_led_resume,
- .driver = {
- .name = DRVNAME,
- .owner = THIS_MODULE,
- },
-};
-
-static int __init apu2_led_init(void)
-{
- int ret;
- int i;
+ vendor = dmi_get_system_info(DMI_SYS_VENDOR);
+ if (!vendor || strcmp(vendor, "PC Engines"))
+ return false;
- ret = platform_driver_register(&apu2_led_driver);
- if (ret < 0)
- goto out;
-
- pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0);
- if (IS_ERR(pdev)) {
- ret = PTR_ERR(pdev);
- platform_driver_unregister(&apu2_led_driver);
- goto out;
- }
+ product = dmi_get_system_info(DMI_PRODUCT_NAME);
+ if (!product || (strcmp(product, "apu2")))
+ return false;
- for (i = 0; i < APU2_NUM_GPIO; i++) {
- gpio_addr[i] = ioremap ( FCH_GPIO_BASE + (gpio_offset[i] * sizeof (u32)), sizeof (u32));
- }
+ printk(KERN_INFO "%s: System is recognized as \"%s %s\"\n",
+ APU2_DRIVER_NAME, vendor, product);
-out:
- return ret;
+ return true;
}
-static void __exit apu2_led_exit(void)
+static int __init apu2_init(void)
{
- platform_device_unregister(pdev);
- platform_driver_unregister(&apu2_led_driver);
+ /* Check for APU2 board */
+ printk(KERN_INFO "Loading driver %s.\n", APU2_DRIVER_NAME);
+ if (apu2_present_dmi())
+ register_apu2();
+
+ return 0;
}
-module_init(apu2_led_init);
-module_exit(apu2_led_exit);
+module_init(apu2_init);
-MODULE_AUTHOR("Christian Herzog");
-MODULE_DESCRIPTION("PCEngines apu2 LED driver");
+MODULE_AUTHOR("Jordi Ferrer Plana <jfer...@igetech.com>");
+MODULE_DESCRIPTION("PC Engines APU2 GPIO-based LED Driver");
MODULE_LICENSE("GPL");
_______________________________________________
Voyage-linux mailing list
Voyage-linux@list.voyage.hk
http://list.voyage.hk/mailman/listinfo/voyage-linux