diff options
author | Hans-Christian Noren Egtvedt <egtvedt@samfundet.no> | 2017-02-26 12:56:39 +0100 |
---|---|---|
committer | Hans-Christian Noren Egtvedt <egtvedt@samfundet.no> | 2017-05-01 09:27:15 +0200 |
commit | 26202873bb51fafdaa51be3e8de7aab9beb49f70 (patch) | |
tree | c3ba9451f8fa93e6bd6347318375a7348ecb522f /arch/avr32/mach-at32ap/pio.c | |
parent | Linux 4.11 (diff) | |
download | linux-26202873bb51fafdaa51be3e8de7aab9beb49f70.tar.xz linux-26202873bb51fafdaa51be3e8de7aab9beb49f70.zip |
avr32: remove support for AVR32 architecture
This patch drops support for AVR32 architecture from the Linux kernel.
The AVR32 architecture is not keeping up with the development of the
kernel, and since it shares so much of the drivers with Atmel ARM SoC,
it is starting to hinder these drivers to develop swiftly.
Also, all AVR32 AP7 SoC processors are end of lifed from Atmel (now
Microchip).
Finally, the GCC toolchain is stuck at version 4.2.x, and has not
received any patches since the last release from Atmel;
4.2.4-atmel.1.1.3.avr32linux.1. When building kernel v4.10, this
toolchain is no longer able to properly link the network stack.
Haavard and I have came to the conclusion that we feel keeping AVR32 on
life support offers more obstacles for Atmel ARMs, than it gives joy to
AVR32 users. I also suspect there are very few AVR32 users left today,
if anybody at all.
Signed-off-by: Hans-Christian Noren Egtvedt <egtvedt@samfundet.no>
Signed-off-by: HÃ¥vard Skinnemoen <hskinnemoen@gmail.com>
Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com>
Acked-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Acked-by: Boris Brezillon <boris.brezillon@free-electrons.com>
Diffstat (limited to 'arch/avr32/mach-at32ap/pio.c')
-rw-r--r-- | arch/avr32/mach-at32ap/pio.c | 470 |
1 files changed, 0 insertions, 470 deletions
diff --git a/arch/avr32/mach-at32ap/pio.c b/arch/avr32/mach-at32ap/pio.c deleted file mode 100644 index 7fae6ec7e8ec..000000000000 --- a/arch/avr32/mach-at32ap/pio.c +++ /dev/null @@ -1,470 +0,0 @@ -/* - * Atmel PIO2 Port Multiplexer support - * - * Copyright (C) 2004-2006 Atmel Corporation - * - * 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/clk.h> -#include <linux/debugfs.h> -#include <linux/export.h> -#include <linux/fs.h> -#include <linux/platform_device.h> -#include <linux/irq.h> -#include <linux/gpio.h> - -#include <asm/io.h> - -#include <mach/portmux.h> - -#include "pio.h" - -#define MAX_NR_PIO_DEVICES 8 - -struct pio_device { - struct gpio_chip chip; - void __iomem *regs; - const struct platform_device *pdev; - struct clk *clk; - u32 pinmux_mask; - char name[8]; -}; - -static struct pio_device pio_dev[MAX_NR_PIO_DEVICES]; - -static struct pio_device *gpio_to_pio(unsigned int gpio) -{ - struct pio_device *pio; - unsigned int index; - - index = gpio >> 5; - if (index >= MAX_NR_PIO_DEVICES) - return NULL; - pio = &pio_dev[index]; - if (!pio->regs) - return NULL; - - return pio; -} - -/* Pin multiplexing API */ -static DEFINE_SPINLOCK(pio_lock); - -void __init at32_select_periph(unsigned int port, u32 pin_mask, - unsigned int periph, unsigned long flags) -{ - struct pio_device *pio; - - /* assign and verify pio */ - pio = gpio_to_pio(port); - if (unlikely(!pio)) { - printk(KERN_WARNING "pio: invalid port %u\n", port); - goto fail; - } - - /* Test if any of the requested pins is already muxed */ - spin_lock(&pio_lock); - if (unlikely(pio->pinmux_mask & pin_mask)) { - printk(KERN_WARNING "%s: pin(s) busy (requested 0x%x, busy 0x%x)\n", - pio->name, pin_mask, pio->pinmux_mask & pin_mask); - spin_unlock(&pio_lock); - goto fail; - } - - pio->pinmux_mask |= pin_mask; - - /* enable pull ups */ - pio_writel(pio, PUER, pin_mask); - - /* select either peripheral A or B */ - if (periph) - pio_writel(pio, BSR, pin_mask); - else - pio_writel(pio, ASR, pin_mask); - - /* enable peripheral control */ - pio_writel(pio, PDR, pin_mask); - - /* Disable pull ups if not requested. */ - if (!(flags & AT32_GPIOF_PULLUP)) - pio_writel(pio, PUDR, pin_mask); - - spin_unlock(&pio_lock); - - return; - -fail: - dump_stack(); -} - -void __init at32_select_gpio(unsigned int pin, unsigned long flags) -{ - struct pio_device *pio; - unsigned int pin_index = pin & 0x1f; - u32 mask = 1 << pin_index; - - pio = gpio_to_pio(pin); - if (unlikely(!pio)) { - printk("pio: invalid pin %u\n", pin); - goto fail; - } - - if (unlikely(test_and_set_bit(pin_index, &pio->pinmux_mask))) { - printk("%s: pin %u is busy\n", pio->name, pin_index); - goto fail; - } - - if (flags & AT32_GPIOF_OUTPUT) { - if (flags & AT32_GPIOF_HIGH) - pio_writel(pio, SODR, mask); - else - pio_writel(pio, CODR, mask); - if (flags & AT32_GPIOF_MULTIDRV) - pio_writel(pio, MDER, mask); - else - pio_writel(pio, MDDR, mask); - pio_writel(pio, PUDR, mask); - pio_writel(pio, OER, mask); - } else { - if (flags & AT32_GPIOF_PULLUP) - pio_writel(pio, PUER, mask); - else - pio_writel(pio, PUDR, mask); - if (flags & AT32_GPIOF_DEGLITCH) - pio_writel(pio, IFER, mask); - else - pio_writel(pio, IFDR, mask); - pio_writel(pio, ODR, mask); - } - - pio_writel(pio, PER, mask); - - return; - -fail: - dump_stack(); -} - -/* - * Undo a previous pin reservation. Will not affect the hardware - * configuration. - */ -void at32_deselect_pin(unsigned int pin) -{ - struct pio_device *pio; - unsigned int pin_index = pin & 0x1f; - - pio = gpio_to_pio(pin); - if (unlikely(!pio)) { - printk("pio: invalid pin %u\n", pin); - dump_stack(); - return; - } - - clear_bit(pin_index, &pio->pinmux_mask); -} - -/* Reserve a pin, preventing anyone else from changing its configuration. */ -void __init at32_reserve_pin(unsigned int port, u32 pin_mask) -{ - struct pio_device *pio; - - /* assign and verify pio */ - pio = gpio_to_pio(port); - if (unlikely(!pio)) { - printk(KERN_WARNING "pio: invalid port %u\n", port); - goto fail; - } - - /* Test if any of the requested pins is already muxed */ - spin_lock(&pio_lock); - if (unlikely(pio->pinmux_mask & pin_mask)) { - printk(KERN_WARNING "%s: pin(s) busy (req. 0x%x, busy 0x%x)\n", - pio->name, pin_mask, pio->pinmux_mask & pin_mask); - spin_unlock(&pio_lock); - goto fail; - } - - /* Reserve pins */ - pio->pinmux_mask |= pin_mask; - spin_unlock(&pio_lock); - return; - -fail: - dump_stack(); -} - -/*--------------------------------------------------------------------------*/ - -/* GPIO API */ - -static int direction_input(struct gpio_chip *chip, unsigned offset) -{ - struct pio_device *pio = gpiochip_get_data(chip); - u32 mask = 1 << offset; - - if (!(pio_readl(pio, PSR) & mask)) - return -EINVAL; - - pio_writel(pio, ODR, mask); - return 0; -} - -static int gpio_get(struct gpio_chip *chip, unsigned offset) -{ - struct pio_device *pio = gpiochip_get_data(chip); - - return (pio_readl(pio, PDSR) >> offset) & 1; -} - -static void gpio_set(struct gpio_chip *chip, unsigned offset, int value); - -static int direction_output(struct gpio_chip *chip, unsigned offset, int value) -{ - struct pio_device *pio = gpiochip_get_data(chip); - u32 mask = 1 << offset; - - if (!(pio_readl(pio, PSR) & mask)) - return -EINVAL; - - gpio_set(chip, offset, value); - pio_writel(pio, OER, mask); - return 0; -} - -static void gpio_set(struct gpio_chip *chip, unsigned offset, int value) -{ - struct pio_device *pio = gpiochip_get_data(chip); - u32 mask = 1 << offset; - - if (value) - pio_writel(pio, SODR, mask); - else - pio_writel(pio, CODR, mask); -} - -/*--------------------------------------------------------------------------*/ - -/* GPIO IRQ support */ - -static void gpio_irq_mask(struct irq_data *d) -{ - unsigned gpio = irq_to_gpio(d->irq); - struct pio_device *pio = &pio_dev[gpio >> 5]; - - pio_writel(pio, IDR, 1 << (gpio & 0x1f)); -} - -static void gpio_irq_unmask(struct irq_data *d) -{ - unsigned gpio = irq_to_gpio(d->irq); - struct pio_device *pio = &pio_dev[gpio >> 5]; - - pio_writel(pio, IER, 1 << (gpio & 0x1f)); -} - -static int gpio_irq_type(struct irq_data *d, unsigned type) -{ - if (type != IRQ_TYPE_EDGE_BOTH && type != IRQ_TYPE_NONE) - return -EINVAL; - - return 0; -} - -static struct irq_chip gpio_irqchip = { - .name = "gpio", - .irq_mask = gpio_irq_mask, - .irq_unmask = gpio_irq_unmask, - .irq_set_type = gpio_irq_type, -}; - -static void gpio_irq_handler(struct irq_desc *desc) -{ - struct pio_device *pio = irq_desc_get_chip_data(desc); - unsigned gpio_irq; - - gpio_irq = (unsigned) irq_desc_get_handler_data(desc); - for (;;) { - u32 isr; - - /* ack pending GPIO interrupts */ - isr = pio_readl(pio, ISR) & pio_readl(pio, IMR); - if (!isr) - break; - do { - int i; - - i = ffs(isr) - 1; - isr &= ~(1 << i); - - i += gpio_irq; - generic_handle_irq(i); - } while (isr); - } -} - -static void __init -gpio_irq_setup(struct pio_device *pio, int irq, int gpio_irq) -{ - unsigned i; - - irq_set_chip_data(irq, pio); - - for (i = 0; i < 32; i++, gpio_irq++) { - irq_set_chip_data(gpio_irq, pio); - irq_set_chip_and_handler(gpio_irq, &gpio_irqchip, - handle_simple_irq); - } - - irq_set_chained_handler_and_data(irq, gpio_irq_handler, - (void *)gpio_irq); -} - -/*--------------------------------------------------------------------------*/ - -#ifdef CONFIG_DEBUG_FS - -#include <linux/seq_file.h> - -/* - * This shows more info than the generic gpio dump code: - * pullups, deglitching, open drain drive. - */ -static void pio_bank_show(struct seq_file *s, struct gpio_chip *chip) -{ - struct pio_device *pio = gpiochip_get_data(chip); - u32 psr, osr, imr, pdsr, pusr, ifsr, mdsr; - unsigned i; - u32 mask; - char bank; - - psr = pio_readl(pio, PSR); - osr = pio_readl(pio, OSR); - imr = pio_readl(pio, IMR); - pdsr = pio_readl(pio, PDSR); - pusr = pio_readl(pio, PUSR); - ifsr = pio_readl(pio, IFSR); - mdsr = pio_readl(pio, MDSR); - - bank = 'A' + pio->pdev->id; - - for (i = 0, mask = 1; i < 32; i++, mask <<= 1) { - const char *label; - - label = gpiochip_is_requested(chip, i); - if (!label && (imr & mask)) - label = "[irq]"; - if (!label) - continue; - - seq_printf(s, " gpio-%-3d P%c%-2d (%-12s) %s %s %s", - chip->base + i, bank, i, - label, - (osr & mask) ? "out" : "in ", - (mask & pdsr) ? "hi" : "lo", - (mask & pusr) ? " " : "up"); - if (ifsr & mask) - seq_puts(s, " deglitch"); - if ((osr & mdsr) & mask) - seq_puts(s, " open-drain"); - if (imr & mask) - seq_printf(s, " irq-%d edge-both", - gpio_to_irq(chip->base + i)); - seq_putc(s, '\n'); - } -} - -#else -#define pio_bank_show NULL -#endif - - -/*--------------------------------------------------------------------------*/ - -static int __init pio_probe(struct platform_device *pdev) -{ - struct pio_device *pio = NULL; - int irq = platform_get_irq(pdev, 0); - int gpio_irq_base = GPIO_IRQ_BASE + pdev->id * 32; - - BUG_ON(pdev->id >= MAX_NR_PIO_DEVICES); - pio = &pio_dev[pdev->id]; - BUG_ON(!pio->regs); - - pio->chip.label = pio->name; - pio->chip.base = pdev->id * 32; - pio->chip.ngpio = 32; - pio->chip.parent = &pdev->dev; - pio->chip.owner = THIS_MODULE; - - pio->chip.direction_input = direction_input; - pio->chip.get = gpio_get; - pio->chip.direction_output = direction_output; - pio->chip.set = gpio_set; - pio->chip.dbg_show = pio_bank_show; - - gpiochip_add_data(&pio->chip, pio); - - gpio_irq_setup(pio, irq, gpio_irq_base); - - platform_set_drvdata(pdev, pio); - - printk(KERN_DEBUG "%s: base 0x%p, irq %d chains %d..%d\n", - pio->name, pio->regs, irq, gpio_irq_base, gpio_irq_base + 31); - - return 0; -} - -static struct platform_driver pio_driver = { - .driver = { - .name = "pio", - }, -}; - -static int __init pio_init(void) -{ - return platform_driver_probe(&pio_driver, pio_probe); -} -postcore_initcall(pio_init); - -void __init at32_init_pio(struct platform_device *pdev) -{ - struct resource *regs; - struct pio_device *pio; - - if (pdev->id >= MAX_NR_PIO_DEVICES) { - dev_err(&pdev->dev, "only %d PIO devices supported\n", - MAX_NR_PIO_DEVICES); - return; - } - - pio = &pio_dev[pdev->id]; - snprintf(pio->name, sizeof(pio->name), "pio%d", pdev->id); - - regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!regs) { - dev_err(&pdev->dev, "no mmio resource defined\n"); - return; - } - - pio->clk = clk_get(&pdev->dev, "mck"); - if (IS_ERR(pio->clk)) - /* - * This is a fatal error, but if we continue we might - * be so lucky that we manage to initialize the - * console and display this message... - */ - dev_err(&pdev->dev, "no mck clock defined\n"); - else - clk_enable(pio->clk); - - pio->pdev = pdev; - pio->regs = ioremap(regs->start, resource_size(regs)); - - /* start with irqs disabled and acked */ - pio_writel(pio, IDR, ~0UL); - (void) pio_readl(pio, ISR); -} |