linux/arch/arm/mach-ks8695/board-og.c
<<
>>
Prefs
   1/*
   2 * board-og.c -- support for the OpenGear KS8695 based boards.
   3 *
   4 * This program is free software; you can redistribute it and/or modify
   5 * it under the terms of the GNU General Public License version 2 as
   6 * published by the Free Software Foundation.
   7 */
   8
   9#include <linux/kernel.h>
  10#include <linux/types.h>
  11#include <linux/interrupt.h>
  12#include <linux/init.h>
  13#include <linux/delay.h>
  14#include <linux/platform_device.h>
  15#include <linux/serial_8250.h>
  16#include <linux/gpio.h>
  17#include <linux/irq.h>
  18#include <asm/mach-types.h>
  19#include <asm/mach/arch.h>
  20#include <asm/mach/map.h>
  21#include "devices.h"
  22#include <mach/regs-gpio.h>
  23#include <mach/gpio-ks8695.h>
  24#include "generic.h"
  25
  26static int og_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
  27{
  28        if (machine_is_im4004() && (slot == 8))
  29                return KS8695_IRQ_EXTERN1;
  30        return KS8695_IRQ_EXTERN0;
  31}
  32
  33static struct ks8695_pci_cfg __initdata og_pci = {
  34        .mode           = KS8695_MODE_PCI,
  35        .map_irq        = og_pci_map_irq,
  36};
  37
  38static void __init og_register_pci(void)
  39{
  40        /* Initialize the GPIO lines for interrupt mode */
  41        ks8695_gpio_interrupt(KS8695_GPIO_0, IRQ_TYPE_LEVEL_LOW);
  42
  43        /* Cardbus Slot */
  44        if (machine_is_im4004())
  45                ks8695_gpio_interrupt(KS8695_GPIO_1, IRQ_TYPE_LEVEL_LOW);
  46
  47        if (IS_ENABLED(CONFIG_PCI))
  48                ks8695_init_pci(&og_pci);
  49}
  50
  51/*
  52 * The PCI bus reset is driven by a dedicated GPIO line. Toggle it here
  53 * and bring the PCI bus out of reset.
  54 */
  55static void __init og_pci_bus_reset(void)
  56{
  57        unsigned int rstline = 1;
  58
  59        /* Some boards use a different GPIO as the PCI reset line */
  60        if (machine_is_im4004())
  61                rstline = 2;
  62        else if (machine_is_im42xx())
  63                rstline = 0;
  64
  65        gpio_request(rstline, "PCI reset");
  66        gpio_direction_output(rstline, 0);
  67
  68        /* Drive a reset on the PCI reset line */
  69        gpio_set_value(rstline, 1);
  70        gpio_set_value(rstline, 0);
  71        mdelay(100);
  72        gpio_set_value(rstline, 1);
  73        mdelay(100);
  74}
  75
  76/*
  77 * Direct connect serial ports (non-PCI that is).
  78 */
  79#define S8250_PHYS      0x03800000
  80#define S8250_VIRT      0xf4000000
  81#define S8250_SIZE      0x00100000
  82
  83static struct map_desc og_io_desc[] __initdata = {
  84        {
  85                .virtual        = S8250_VIRT,
  86                .pfn            = __phys_to_pfn(S8250_PHYS),
  87                .length         = S8250_SIZE,
  88                .type           = MT_DEVICE,
  89        }
  90};
  91
  92static struct resource og_uart_resources[] = {
  93        {
  94                .start          = S8250_VIRT,
  95                .end            = S8250_VIRT + S8250_SIZE,
  96                .flags          = IORESOURCE_MEM
  97        },
  98};
  99
 100static struct plat_serial8250_port og_uart_data[] = {
 101        {
 102                .mapbase        = S8250_VIRT,
 103                .membase        = (char *) S8250_VIRT,
 104                .irq            = 3,
 105                .flags          = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
 106                .iotype         = UPIO_MEM,
 107                .regshift       = 2,
 108                .uartclk        = 115200 * 16,
 109        },
 110        { },
 111};
 112
 113static struct platform_device og_uart = {
 114        .name                   = "serial8250",
 115        .id                     = 0,
 116        .dev.platform_data      = og_uart_data,
 117        .num_resources          = 1,
 118        .resource               = og_uart_resources
 119};
 120
 121static struct platform_device *og_devices[] __initdata = {
 122        &og_uart
 123};
 124
 125static void __init og_init(void)
 126{
 127        ks8695_register_gpios();
 128
 129        if (machine_is_cm4002()) {
 130                ks8695_gpio_interrupt(KS8695_GPIO_1, IRQ_TYPE_LEVEL_HIGH);
 131                iotable_init(og_io_desc, ARRAY_SIZE(og_io_desc));
 132                platform_add_devices(og_devices, ARRAY_SIZE(og_devices));
 133        } else {
 134                og_pci_bus_reset();
 135                og_register_pci();
 136        }
 137
 138        ks8695_add_device_lan();
 139        ks8695_add_device_wan();
 140}
 141
 142#ifdef CONFIG_MACH_CM4002
 143MACHINE_START(CM4002, "OpenGear/CM4002")
 144        /* OpenGear Inc. */
 145        .atag_offset    = 0x100,
 146        .map_io         = ks8695_map_io,
 147        .init_irq       = ks8695_init_irq,
 148        .init_machine   = og_init,
 149        .init_time      = ks8695_timer_init,
 150        .restart        = ks8695_restart,
 151MACHINE_END
 152#endif
 153
 154#ifdef CONFIG_MACH_CM4008
 155MACHINE_START(CM4008, "OpenGear/CM4008")
 156        /* OpenGear Inc. */
 157        .atag_offset    = 0x100,
 158        .map_io         = ks8695_map_io,
 159        .init_irq       = ks8695_init_irq,
 160        .init_machine   = og_init,
 161        .init_time      = ks8695_timer_init,
 162        .restart        = ks8695_restart,
 163MACHINE_END
 164#endif
 165
 166#ifdef CONFIG_MACH_CM41xx
 167MACHINE_START(CM41XX, "OpenGear/CM41xx")
 168        /* OpenGear Inc. */
 169        .atag_offset    = 0x100,
 170        .map_io         = ks8695_map_io,
 171        .init_irq       = ks8695_init_irq,
 172        .init_machine   = og_init,
 173        .init_time      = ks8695_timer_init,
 174        .restart        = ks8695_restart,
 175MACHINE_END
 176#endif
 177
 178#ifdef CONFIG_MACH_IM4004
 179MACHINE_START(IM4004, "OpenGear/IM4004")
 180        /* OpenGear Inc. */
 181        .atag_offset    = 0x100,
 182        .map_io         = ks8695_map_io,
 183        .init_irq       = ks8695_init_irq,
 184        .init_machine   = og_init,
 185        .init_time      = ks8695_timer_init,
 186        .restart        = ks8695_restart,
 187MACHINE_END
 188#endif
 189
 190#ifdef CONFIG_MACH_IM42xx
 191MACHINE_START(IM42XX, "OpenGear/IM42xx")
 192        /* OpenGear Inc. */
 193        .atag_offset    = 0x100,
 194        .map_io         = ks8695_map_io,
 195        .init_irq       = ks8695_init_irq,
 196        .init_machine   = og_init,
 197        .init_time      = ks8695_timer_init,
 198        .restart        = ks8695_restart,
 199MACHINE_END
 200#endif
 201