diff options
author | John Voltz <john.voltz@gmail.com> | 2008-05-01 17:15:35 +0000 |
---|---|---|
committer | John Voltz <john.voltz@gmail.com> | 2008-05-01 17:15:35 +0000 |
commit | 4037d581631f9bb308e3430105dccc300b4c30c0 (patch) | |
tree | b7f9395f0c1eedc1ae4d9f7e31ab1ec2df5c414e /target/device/Atmel/atngw100-expanded/kernel-patches/linux-2.6.24-300-avr32-psif-2.patch | |
parent | 804e373d06f78ab38a73979c5b72d4342358ea2f (diff) | |
download | buildroot-novena-4037d581631f9bb308e3430105dccc300b4c30c0.tar.gz buildroot-novena-4037d581631f9bb308e3430105dccc300b4c30c0.zip |
update patches for atngw100_expanded
Diffstat (limited to 'target/device/Atmel/atngw100-expanded/kernel-patches/linux-2.6.24-300-avr32-psif-2.patch')
-rw-r--r-- | target/device/Atmel/atngw100-expanded/kernel-patches/linux-2.6.24-300-avr32-psif-2.patch | 671 |
1 files changed, 0 insertions, 671 deletions
diff --git a/target/device/Atmel/atngw100-expanded/kernel-patches/linux-2.6.24-300-avr32-psif-2.patch b/target/device/Atmel/atngw100-expanded/kernel-patches/linux-2.6.24-300-avr32-psif-2.patch deleted file mode 100644 index 4f9d652a5..000000000 --- a/target/device/Atmel/atngw100-expanded/kernel-patches/linux-2.6.24-300-avr32-psif-2.patch +++ /dev/null @@ -1,671 +0,0 @@ -diff --git a/drivers/input/serio/Kconfig b/drivers/input/serio/Kconfig -index b88569e..2df47ed 100644 ---- a/drivers/input/serio/Kconfig -+++ b/drivers/input/serio/Kconfig -@@ -88,6 +88,17 @@ config SERIO_RPCKBD - To compile this driver as a module, choose M here: the - module will be called rpckbd. - -+config SERIO_AT32PSIF -+ tristate "AVR32 PSIF PS/2 keyboard and mouse controller" -+ depends on AVR32 -+ default n -+ help -+ Say Y here if you want to use the PSIF peripheral on AVR32 devices -+ and connect a PS/2 keyboard and/or mouse to it. -+ -+ To compile this driver as a module, choose M here: the module will -+ be called at32psif. -+ - config SERIO_AMBAKMI - tristate "AMBA KMI keyboard controller" - depends on ARM_AMBA -diff --git a/drivers/input/serio/Makefile b/drivers/input/serio/Makefile -index 4155197..38b8868 100644 ---- a/drivers/input/serio/Makefile -+++ b/drivers/input/serio/Makefile -@@ -12,6 +12,7 @@ obj-$(CONFIG_SERIO_CT82C710) += ct82c710.o - obj-$(CONFIG_SERIO_RPCKBD) += rpckbd.o - obj-$(CONFIG_SERIO_SA1111) += sa1111ps2.o - obj-$(CONFIG_SERIO_AMBAKMI) += ambakmi.o -+obj-$(CONFIG_SERIO_AT32PSIF) += at32psif.o - obj-$(CONFIG_SERIO_Q40KBD) += q40kbd.o - obj-$(CONFIG_SERIO_GSCPS2) += gscps2.o - obj-$(CONFIG_HP_SDC) += hp_sdc.o -diff --git a/drivers/input/serio/at32psif.c b/drivers/input/serio/at32psif.c -new file mode 100644 -index 0000000..228ab15 ---- /dev/null -+++ b/drivers/input/serio/at32psif.c -@@ -0,0 +1,342 @@ -+/* -+ * Copyright (C) 2007 Atmel Corporation -+ * -+ * Driver for the AT32AP700X PS/2 controller (PSIF). -+ * -+ * 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. -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/device.h> -+#include <linux/init.h> -+#include <linux/serio.h> -+#include <linux/interrupt.h> -+#include <linux/err.h> -+#include <linux/io.h> -+#include <linux/clk.h> -+#include <linux/platform_device.h> -+#include <linux/delay.h> -+ -+#include "at32psif.h" -+ -+#define PSIF_BUF_SIZE 16 -+ -+#define ring_is_empty(_psif) (_psif->head == _psif->tail) -+#define ring_next_head(_psif) ((_psif->head + 1) & (PSIF_BUF_SIZE - 1)) -+#define ring_next_tail(_psif) ((_psif->tail + 1) & (PSIF_BUF_SIZE - 1)) -+ -+struct psif { -+ struct platform_device *pdev; -+ struct clk *pclk; -+ struct serio *io; -+ void __iomem *regs; -+ unsigned int irq; -+ unsigned int open; -+ /* Prevent concurrent writes to circular buffer. */ -+ spinlock_t lock; -+ unsigned int head; -+ unsigned int tail; -+ unsigned char buffer[PSIF_BUF_SIZE]; -+}; -+ -+static irqreturn_t psif_interrupt(int irq, void *_ptr) -+{ -+ struct psif *psif = _ptr; -+ int retval = IRQ_NONE; -+ unsigned int io_flags = 0; -+ unsigned long lock_flags; -+ unsigned long status; -+ -+ status = psif_readl(psif, SR); -+ -+ if (status & PSIF_BIT(RXRDY)) { -+ unsigned char val = (unsigned char) psif_readl(psif, RHR); -+ -+ if (status & PSIF_BIT(PARITY)) -+ io_flags |= SERIO_PARITY; -+ if (status & PSIF_BIT(OVRUN)) -+ dev_err(&psif->pdev->dev, "overrun read error\n"); -+ -+ /* TODO: why do we have to wait? Are we too fast for serio? */ -+ udelay(100); -+ -+ serio_interrupt(psif->io, val, io_flags); -+ -+ retval = IRQ_HANDLED; -+ } -+ -+ spin_lock_irqsave(&psif->lock, lock_flags); -+ -+ if (status & PSIF_BIT(TXEMPTY)) { -+ if (status & PSIF_BIT(NACK)) -+ dev_err(&psif->pdev->dev, "NACK error\n"); -+ if (ring_is_empty(psif)) { -+ psif_writel(psif, IDR, PSIF_BIT(TXEMPTY)); -+ } else { -+ psif_writel(psif, THR, psif->buffer[psif->tail]); -+ psif->tail = ring_next_tail(psif); -+ } -+ -+ retval = IRQ_HANDLED; -+ } -+ -+ spin_unlock_irqrestore(&psif->lock, lock_flags); -+ -+ return retval; -+} -+ -+static int psif_write(struct serio *io, unsigned char val) -+{ -+ struct psif *psif = io->port_data; -+ unsigned long flags; -+ unsigned int head; -+ -+ spin_lock_irqsave(&psif->lock, flags); -+ -+ /* Write directly if TX is ready. */ -+ if (psif_readl(psif, SR) & PSIF_BIT(TXEMPTY)) { -+ psif_writel(psif, THR, val); -+ } else { -+ head = ring_next_head(psif); -+ -+ if (head != psif->tail) { -+ psif->buffer[psif->head] = val; -+ psif->head = head; -+ } else { -+ dev_err(&psif->pdev->dev, "underrun write error\n"); -+ } -+ -+ /* Make sure TXEMPTY interrupt is enabled. */ -+ psif_writel(psif, IER, PSIF_BIT(TXEMPTY)); -+ } -+ -+ spin_unlock_irqrestore(&psif->lock, flags); -+ -+ return 0; -+} -+ -+static int psif_open(struct serio *io) -+{ -+ struct psif *psif = io->port_data; -+ int retval; -+ -+ retval = clk_enable(psif->pclk); -+ if (retval) -+ goto out; -+ -+ psif_writel(psif, CR, PSIF_BIT(CR_TXEN) | PSIF_BIT(CR_RXEN)); -+ psif_writel(psif, IER, PSIF_BIT(RXRDY)); -+ -+ psif->open = 1; -+out: -+ return retval; -+} -+ -+static void psif_close(struct serio *io) -+{ -+ struct psif *psif = io->port_data; -+ -+ psif->open = 0; -+ -+ psif_writel(psif, IDR, ~0UL); -+ psif_writel(psif, CR, PSIF_BIT(CR_TXDIS) | PSIF_BIT(CR_RXDIS)); -+ -+ clk_disable(psif->pclk); -+} -+ -+static void psif_set_prescaler(struct psif *psif) -+{ -+ unsigned long prscv; -+ unsigned long rate = clk_get_rate(psif->pclk); -+ -+ /* PRSCV = Pulse length (100 uS) * PSIF module frequency. */ -+ prscv = 100 * (rate / 1000000); -+ -+ if (prscv > ((1<<PSIF_PSR_PRSCV_SIZE) - 1)) { -+ prscv = (1<<PSIF_PSR_PRSCV_SIZE) - 1; -+ dev_dbg(&psif->pdev->dev, "pclk too fast, " -+ "prescaler set to max\n"); -+ } -+ -+ clk_enable(psif->pclk); -+ psif_writel(psif, PSR, prscv); -+ clk_disable(psif->pclk); -+} -+ -+static int __init psif_probe(struct platform_device *pdev) -+{ -+ struct resource *regs; -+ struct psif *psif; -+ struct serio *io; -+ struct clk *pclk; -+ int irq; -+ int ret; -+ -+ psif = kzalloc(sizeof(struct psif), GFP_KERNEL); -+ if (!psif) { -+ dev_dbg(&pdev->dev, "out of memory\n"); -+ ret = -ENOMEM; -+ goto out; -+ } -+ psif->pdev = pdev; -+ -+ io = kzalloc(sizeof(struct serio), GFP_KERNEL); -+ if (!io) { -+ dev_dbg(&pdev->dev, "out of memory\n"); -+ ret = -ENOMEM; -+ goto out_free_psif; -+ } -+ psif->io = io; -+ -+ regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (!regs) { -+ dev_dbg(&pdev->dev, "no mmio resources defined\n"); -+ ret = -ENOMEM; -+ goto out_free_io; -+ } -+ -+ psif->regs = ioremap(regs->start, regs->end - regs->start + 1); -+ if (!psif->regs) { -+ ret = -ENOMEM; -+ dev_dbg(&pdev->dev, "could not map I/O memory\n"); -+ goto out_free_io; -+ } -+ -+ pclk = clk_get(&pdev->dev, "pclk"); -+ if (IS_ERR(pclk)) { -+ dev_dbg(&pdev->dev, "could not get peripheral clock\n"); -+ ret = PTR_ERR(pclk); -+ goto out_iounmap; -+ } -+ psif->pclk = pclk; -+ -+ /* Reset the PSIF to enter at a known state. */ -+ ret = clk_enable(pclk); -+ if (ret) { -+ dev_dbg(&pdev->dev, "could not enable pclk\n"); -+ goto out_put_clk; -+ } -+ psif_writel(psif, CR, PSIF_BIT(CR_SWRST)); -+ clk_disable(pclk); -+ -+ irq = platform_get_irq(pdev, 0); -+ if (irq < 0) { -+ dev_dbg(&pdev->dev, "could not get irq\n"); -+ ret = -ENXIO; -+ goto out_put_clk; -+ } -+ ret = request_irq(irq, psif_interrupt, IRQF_SHARED, "at32psif", psif); -+ if (ret) { -+ dev_dbg(&pdev->dev, "could not request irq %d\n", irq); -+ goto out_put_clk; -+ } -+ psif->irq = irq; -+ -+ io->id.type = SERIO_8042; -+ io->write = psif_write; -+ io->open = psif_open; -+ io->close = psif_close; -+ strlcpy(io->name, pdev->dev.bus_id, sizeof(io->name)); -+ strlcpy(io->phys, pdev->dev.bus_id, sizeof(io->phys)); -+ io->port_data = psif; -+ io->dev.parent = &pdev->dev; -+ -+ psif_set_prescaler(psif); -+ -+ spin_lock_init(&psif->lock); -+ serio_register_port(psif->io); -+ platform_set_drvdata(pdev, psif); -+ -+ dev_info(&pdev->dev, "Atmel AVR32 PSIF PS/2 driver on 0x%08x irq %d\n", -+ (int)psif->regs, psif->irq); -+ -+ return 0; -+ -+out_put_clk: -+ clk_put(psif->pclk); -+out_iounmap: -+ iounmap(psif->regs); -+out_free_io: -+ kfree(io); -+out_free_psif: -+ kfree(psif); -+out: -+ return ret; -+} -+ -+static int __exit psif_remove(struct platform_device *pdev) -+{ -+ struct psif *psif = platform_get_drvdata(pdev); -+ -+ psif_writel(psif, IDR, ~0UL); -+ psif_writel(psif, CR, PSIF_BIT(CR_TXDIS) | PSIF_BIT(CR_RXDIS)); -+ -+ serio_unregister_port(psif->io); -+ iounmap(psif->regs); -+ free_irq(psif->irq, psif); -+ clk_put(psif->pclk); -+ kfree(psif); -+ -+ platform_set_drvdata(pdev, NULL); -+ -+ return 0; -+} -+ -+#ifdef CONFIG_PM -+static int psif_suspend(struct platform_device *pdev, pm_message_t state) -+{ -+ struct psif *psif = platform_get_drvdata(pdev); -+ -+ if (psif->open) { -+ psif_writel(psif, CR, PSIF_BIT(CR_RXDIS) | PSIF_BIT(CR_TXDIS)); -+ clk_disable(psif->pclk); -+ } -+ -+ return 0; -+} -+ -+static int psif_resume(struct platform_device *pdev) -+{ -+ struct psif *psif = platform_get_drvdata(pdev); -+ -+ if (psif->open) { -+ clk_enable(psif->pclk); -+ psif_set_prescaler(psif); -+ psif_writel(psif, CR, PSIF_BIT(CR_RXEN) | PSIF_BIT(CR_TXEN)); -+ } -+ -+ return 0; -+} -+#else -+#define psif_suspend NULL -+#define psif_resume NULL -+#endif -+ -+static struct platform_driver psif_driver = { -+ .remove = __exit_p(psif_remove), -+ .driver = { -+ .name = "atmel_psif", -+ }, -+ .suspend = psif_suspend, -+ .resume = psif_resume, -+}; -+ -+static int __init psif_init(void) -+{ -+ return platform_driver_probe(&psif_driver, psif_probe); -+} -+ -+static void __exit psif_exit(void) -+{ -+ platform_driver_unregister(&psif_driver); -+} -+ -+module_init(psif_init); -+module_exit(psif_exit); -+ -+MODULE_AUTHOR("Hans-Christian Egtvedt <hcegtvedt@atmel.com>"); -+MODULE_DESCRIPTION("Atmel AVR32 PSIF PS/2 driver"); -+MODULE_LICENSE("GPL"); -diff --git a/drivers/input/serio/at32psif.h b/drivers/input/serio/at32psif.h -new file mode 100644 -index 0000000..b0cc5e4 ---- /dev/null -+++ b/drivers/input/serio/at32psif.h -@@ -0,0 +1,82 @@ -+/* -+ * Copyright (C) 2007 Atmel Corporation -+ * -+ * Driver for the AT32AP700X PS/2 controller (PSIF). -+ * -+ * 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. -+ */ -+ -+#ifndef _AT32PSIF_H -+#define _AT32PSIF_H -+ -+/* PSIF register offsets */ -+#define PSIF_CR 0x00 -+#define PSIF_RHR 0x04 -+#define PSIF_THR 0x08 -+#define PSIF_SR 0x10 -+#define PSIF_IER 0x14 -+#define PSIF_IDR 0x18 -+#define PSIF_IMR 0x1c -+#define PSIF_PSR 0x20 -+ -+/* Bitfields in control register. */ -+#define PSIF_CR_RXDIS_OFFSET 1 -+#define PSIF_CR_RXDIS_SIZE 1 -+#define PSIF_CR_RXEN_OFFSET 0 -+#define PSIF_CR_RXEN_SIZE 1 -+#define PSIF_CR_SWRST_OFFSET 15 -+#define PSIF_CR_SWRST_SIZE 1 -+#define PSIF_CR_TXDIS_OFFSET 9 -+#define PSIF_CR_TXDIS_SIZE 1 -+#define PSIF_CR_TXEN_OFFSET 8 -+#define PSIF_CR_TXEN_SIZE 1 -+ -+/* Bitfields in interrupt disable, enable, mask and status register. */ -+#define PSIF_NACK_OFFSET 8 -+#define PSIF_NACK_SIZE 1 -+#define PSIF_OVRUN_OFFSET 5 -+#define PSIF_OVRUN_SIZE 1 -+#define PSIF_PARITY_OFFSET 9 -+#define PSIF_PARITY_SIZE 1 -+#define PSIF_RXRDY_OFFSET 4 -+#define PSIF_RXRDY_SIZE 1 -+#define PSIF_TXEMPTY_OFFSET 1 -+#define PSIF_TXEMPTY_SIZE 1 -+#define PSIF_TXRDY_OFFSET 0 -+#define PSIF_TXRDY_SIZE 1 -+ -+/* Bitfields in prescale register. */ -+#define PSIF_PSR_PRSCV_OFFSET 0 -+#define PSIF_PSR_PRSCV_SIZE 13 -+ -+/* Bitfields in receive hold register. */ -+#define PSIF_RHR_RXDATA_OFFSET 0 -+#define PSIF_RHR_RXDATA_SIZE 8 -+ -+/* Bitfields in transmit hold register. */ -+#define PSIF_THR_TXDATA_OFFSET 0 -+#define PSIF_THR_TXDATA_SIZE 8 -+ -+/* Bit manipulation macros */ -+#define PSIF_BIT(name) \ -+ (1 << PSIF_##name##_OFFSET) -+#define PSIF_BF(name, value) \ -+ (((value) & ((1 << PSIF_##name##_SIZE) - 1)) \ -+ << PSIF_##name##_OFFSET) -+#define PSIF_BFEXT(name, value)\ -+ (((value) >> PSIF_##name##_OFFSET) \ -+ & ((1 << PSIF_##name##_SIZE) - 1)) -+#define PSIF_BFINS(name, value, old) \ -+ (((old) & ~(((1 << PSIF_##name##_SIZE) - 1) \ -+ << PSIF_##name##_OFFSET)) \ -+ | PSIF_BF(name, value)) -+ -+/* Register access macros */ -+#define psif_readl(port, reg) \ -+ __raw_readl((port)->regs + PSIF_##reg) -+#define psif_writel(port, reg, value) \ -+ __raw_writel((value), (port)->regs + PSIF_##reg) -+ -+#endif /* _AT32PSIF_H */ -diff --git a/arch/avr32/boards/atstk1000/Kconfig b/arch/avr32/boards/atstk1000/Kconfig -index 56a8d8e..e125205 100644 ---- a/arch/avr32/boards/atstk1000/Kconfig -+++ b/arch/avr32/boards/atstk1000/Kconfig -@@ -145,4 +145,17 @@ config BOARD_ATSTK1000_CF_DETECT_PIN - - The default is 0x3e, which is pin 30 on PIOB, aka GPIO15. - -+config BOARD_ATSTK100X_ENABLE_PSIF -+ bool "Enable PSIF peripheral (PS/2 support)" -+ default n -+ help -+ Select this if you want to use the PSIF peripheral to hook up PS/2 -+ devices to your STK1000. This will require a hardware modification to -+ work correctly, since PS/2 devices require 5 volt power and signals, -+ while the STK1000 only provides 3.3 volt. -+ -+ Say N if you have not modified the hardware to boost the voltage, say -+ Y if you have level convertion hardware or a PS/2 device capable of -+ operating on 3.3 volt. -+ - endif # stk 1000 -diff --git a/arch/avr32/boards/atstk1000/atstk1002.c b/arch/avr32/boards/atstk1000/atstk1002.c -index f19f54d..2ba37d5 100644 ---- a/arch/avr32/boards/atstk1000/atstk1002.c -+++ b/arch/avr32/boards/atstk1000/atstk1002.c -@@ -261,6 +261,10 @@ static int __init atstk1002_init(void) - at32_add_device_ssc(0, ATMEL_SSC_TX); - #endif - at32_add_device_cf(0, 2, &cf0_data); -+#ifdef CONFIG_BOARD_ATSTK100X_ENABLE_PSIF -+ at32_add_device_psif(0); -+ at32_add_device_psif(1); -+#endif - - atstk1000_setup_j2_leds(); - atstk1002_setup_extdac(); -diff --git a/arch/avr32/boards/atstk1000/atstk1003.c b/arch/avr32/boards/atstk1000/atstk1003.c -index 768d204..2cc0bbc 100644 ---- a/arch/avr32/boards/atstk1000/atstk1003.c -+++ b/arch/avr32/boards/atstk1000/atstk1003.c -@@ -172,6 +172,10 @@ static int __init atstk1003_init(void) - at32_add_device_ssc(0, ATMEL_SSC_TX); - #endif - at32_add_device_cf(0, 2, &cf0_data); -+#ifdef CONFIG_BOARD_ATSTK100X_ENABLE_PSIF -+ at32_add_device_psif(0); -+ at32_add_device_psif(1); -+#endif - - atstk1000_setup_j2_leds(); - atstk1003_setup_extdac(); -diff --git a/arch/avr32/boards/atstk1000/atstk1004.c b/arch/avr32/boards/atstk1000/atstk1004.c -index 96015dd..9e8c293 100644 ---- a/arch/avr32/boards/atstk1000/atstk1004.c -+++ b/arch/avr32/boards/atstk1000/atstk1004.c -@@ -143,6 +143,10 @@ static int __init atstk1004_init(void) - #ifndef CONFIG_BOARD_ATSTK100X_SW3_CUSTOM - at32_add_device_ssc(0, ATMEL_SSC_TX); - #endif -+#ifdef CONFIG_BOARD_ATSTK100X_ENABLE_PSIF -+ at32_add_device_psif(0); -+ at32_add_device_psif(1); -+#endif - - atstk1000_setup_j2_leds(); - atstk1004_setup_extdac(); -diff --git a/arch/avr32/mach-at32ap/at32ap700x.c b/arch/avr32/mach-at32ap/at32ap700x.c -index 3300944..cfec920 100644 ---- a/arch/avr32/mach-at32ap/at32ap700x.c -+++ b/arch/avr32/mach-at32ap/at32ap700x.c -@@ -679,6 +679,81 @@ void __init at32_add_system_devices(void) - } - - /* -------------------------------------------------------------------- -+ * PSIF -+ * -------------------------------------------------------------------- */ -+static struct resource atmel_psif0_resource[] __initdata = { -+ { -+ .start = 0xffe03c00, -+ .end = 0xffe03cff, -+ .flags = IORESOURCE_MEM, -+ }, -+ IRQ(18), -+}; -+static struct clk atmel_psif0_pclk = { -+ .name = "pclk", -+ .parent = &pba_clk, -+ .mode = pba_clk_mode, -+ .get_rate = pba_clk_get_rate, -+ .index = 15, -+}; -+ -+static struct resource atmel_psif1_resource[] __initdata = { -+ { -+ .start = 0xffe03d00, -+ .end = 0xffe03dff, -+ .flags = IORESOURCE_MEM, -+ }, -+ IRQ(18), -+}; -+static struct clk atmel_psif1_pclk = { -+ .name = "pclk", -+ .parent = &pba_clk, -+ .mode = pba_clk_mode, -+ .get_rate = pba_clk_get_rate, -+ .index = 15, -+}; -+ -+struct platform_device *__init at32_add_device_psif(unsigned int id) -+{ -+ struct platform_device *pdev; -+ -+ if (!(id == 0 || id == 1)) -+ return NULL; -+ -+ pdev = platform_device_alloc("atmel_psif", id); -+ if (!pdev) -+ return NULL; -+ -+ switch (id) { -+ case 0: -+ if (platform_device_add_resources(pdev, atmel_psif0_resource, -+ ARRAY_SIZE(atmel_psif0_resource))) -+ goto err_add_resources; -+ atmel_psif0_pclk.dev = &pdev->dev; -+ select_peripheral(PA(8), PERIPH_A, 0); /* CLOCK */ -+ select_peripheral(PA(9), PERIPH_A, 0); /* DATA */ -+ break; -+ case 1: -+ if (platform_device_add_resources(pdev, atmel_psif1_resource, -+ ARRAY_SIZE(atmel_psif1_resource))) -+ goto err_add_resources; -+ atmel_psif1_pclk.dev = &pdev->dev; -+ select_peripheral(PB(11), PERIPH_A, 0); /* CLOCK */ -+ select_peripheral(PB(12), PERIPH_A, 0); /* DATA */ -+ break; -+ default: -+ return NULL; -+ } -+ -+ platform_device_add(pdev); -+ return pdev; -+ -+err_add_resources: -+ platform_device_put(pdev); -+ return NULL; -+} -+ -+/* -------------------------------------------------------------------- - * USART - * -------------------------------------------------------------------- */ - -@@ -1712,6 +1787,8 @@ struct clk *at32_clock_list[] = { - &pio3_mck, - &pio4_mck, - &at32_systc0_pclk, -+ &atmel_psif0_pclk, -+ &atmel_psif1_pclk, - &atmel_usart0_usart, - &atmel_usart1_usart, - &atmel_usart2_usart, -diff --git a/include/asm-avr32/arch-at32ap/board.h b/include/asm-avr32/arch-at32ap/board.h -index 1a6e02c..19cfec7 100644 ---- a/include/asm-avr32/arch-at32ap/board.h -+++ b/include/asm-avr32/arch-at32ap/board.h -@@ -93,4 +93,7 @@ struct platform_device * - at32_add_device_cf(unsigned int id, unsigned int extint, - struct cf_platform_data *data); - -+struct platform_device * -+at32_add_device_psif(unsigned int id); -+ - #endif /* __ASM_ARCH_BOARD_H */ -diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c -index d95f316..20a7193 100644 ---- a/drivers/char/keyboard.c -+++ b/drivers/char/keyboard.c -@@ -1000,7 +1000,8 @@ DECLARE_TASKLET_DISABLED(keyboard_tasklet, kbd_bh, 0); - #if defined(CONFIG_X86) || defined(CONFIG_IA64) || defined(CONFIG_ALPHA) ||\ - defined(CONFIG_MIPS) || defined(CONFIG_PPC) || defined(CONFIG_SPARC) ||\ - defined(CONFIG_PARISC) || defined(CONFIG_SUPERH) ||\ -- (defined(CONFIG_ARM) && defined(CONFIG_KEYBOARD_ATKBD) && !defined(CONFIG_ARCH_RPC)) -+ (defined(CONFIG_ARM) && defined(CONFIG_KEYBOARD_ATKBD) && !defined(CONFIG_ARCH_RPC)) ||\ -+ defined(CONFIG_AVR32) - - #define HW_RAW(dev) (test_bit(EV_MSC, dev->evbit) && test_bit(MSC_RAW, dev->mscbit) &&\ - ((dev)->id.bustype == BUS_I8042) && ((dev)->id.vendor == 0x0001) && ((dev)->id.product == 0x0001)) -diff --git a/arch/avr32/boards/atngw100/setup.c b/arch/avr32/boards/atngw100/setup.c ---- a/arch/avr32/boards/atngw100/setup.c 2008-01-31 13:38:32.000000000 -0500 -+++ b/arch/avr32/boards/atngw100/setup.c 2008-01-31 13:44:09.000000000 -0500 -@@ -224,6 +224,9 @@ static int __init atngw100_init(void) - at32_add_device_usba(0, NULL); - at32_add_device_ac97c(0); - -+ at32_add_device_psif(0); -+ at32_add_device_psif(1); -+ - for (i = 0; i < ARRAY_SIZE(ngw_leds); i++) { - at32_select_gpio(ngw_leds[i].gpio, - AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH); |