1
0
mirror of git://projects.qi-hardware.com/openwrt-xburst.git synced 2024-07-01 00:53:50 +03:00

[lantiq] 3.2 R.I.P.

git-svn-id: svn://svn.openwrt.org/openwrt/trunk@31911 3c298f89-4303-0410-b956-a3cf2f4a3e73
This commit is contained in:
blogic 2012-05-27 16:12:59 +00:00
parent c8e24ec13e
commit c9e0ccf07c
111 changed files with 0 additions and 70773 deletions

View File

@ -1,103 +0,0 @@
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_ARCH_REQUIRE_GPIOLIB=y
CONFIG_ARCH_SUPPORTS_OPROFILE=y
CONFIG_ARCH_SUSPEND_POSSIBLE=y
# CONFIG_ATH79 is not set
CONFIG_BCMA_POSSIBLE=y
# CONFIG_BRCMUTIL is not set
CONFIG_CEVT_R4K=y
CONFIG_CEVT_R4K_LIB=y
CONFIG_CPU_BIG_ENDIAN=y
CONFIG_CPU_HAS_PREFETCH=y
CONFIG_CPU_HAS_SYNC=y
CONFIG_CPU_MIPS32=y
# CONFIG_CPU_MIPS32_R1 is not set
CONFIG_CPU_MIPS32_R2=y
CONFIG_CPU_MIPSR2=y
CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
CONFIG_CPU_SUPPORTS_HIGHMEM=y
CONFIG_CSRC_R4K=y
CONFIG_CSRC_R4K_LIB=y
CONFIG_DECOMPRESS_LZMA=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_EARLY_PRINTK=y
# CONFIG_FSNOTIFY is not set
CONFIG_GENERIC_ATOMIC64=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
CONFIG_GENERIC_CMOS_UPDATE=y
CONFIG_GENERIC_GPIO=y
CONFIG_GENERIC_IRQ_SHOW=y
CONFIG_GPIOLIB=y
CONFIG_GPIO_SYSFS=y
CONFIG_HARDWARE_WATCHPOINTS=y
CONFIG_HAS_DMA=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAVE_ARCH_JUMP_LABEL=y
CONFIG_HAVE_ARCH_KGDB=y
CONFIG_HAVE_CLK=y
CONFIG_HAVE_C_RECORDMCOUNT=y
CONFIG_HAVE_DMA_API_DEBUG=y
CONFIG_HAVE_DMA_ATTRS=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_HAVE_GENERIC_HARDIRQS=y
CONFIG_HAVE_IDE=y
CONFIG_HAVE_IRQ_WORK=y
CONFIG_HAVE_OPROFILE=y
CONFIG_HAVE_PERF_EVENTS=y
CONFIG_HW_RANDOM=y
CONFIG_HZ=250
# CONFIG_HZ_100 is not set
CONFIG_HZ_250=y
CONFIG_IFX_UDP_REDIRECT=y
CONFIG_IMAGE_CMDLINE_HACK=y
CONFIG_INITRAMFS_SOURCE=""
CONFIG_IRQ_CPU=y
CONFIG_LANTIQ=y
CONFIG_LANTIQ_MACH_95C3AM1=y
CONFIG_LANTIQ_MACH_EASY98000=y
CONFIG_LANTIQ_MACH_EASY98020=y
CONFIG_LANTIQ_WDT=y
CONFIG_LEDS_GPIO=y
CONFIG_MACH_NO_WESTBRIDGE=y
CONFIG_MIPS=y
CONFIG_MIPS_L1_CACHE_SHIFT=5
CONFIG_MIPS_MACHINE=y
CONFIG_MIPS_MT_DISABLED=y
# CONFIG_MIPS_MT_SMP is not set
# CONFIG_MIPS_MT_SMTC is not set
# CONFIG_MIPS_VPE_LOADER is not set
CONFIG_MTD_CFI_ADV_OPTIONS=y
CONFIG_MTD_CFI_GEOMETRY=y
CONFIG_MTD_CMDLINE_PARTS=y
CONFIG_MTD_LANTIQ=y
CONFIG_MTD_UIMAGE_SPLIT=y
CONFIG_NEED_DMA_MAP_STATE=y
CONFIG_NEED_PER_CPU_KM=y
CONFIG_PAGEFLAGS_EXTENDED=y
CONFIG_PERF_USE_VMALLOC=y
CONFIG_PHYLIB=y
# CONFIG_PREEMPT_RCU is not set
CONFIG_RTL8366RB_PHY=y
CONFIG_RTL8366_SMI=y
# CONFIG_SCSI_DMA is not set
# CONFIG_SERIAL_8250 is not set
CONFIG_SERIAL_LANTIQ=y
CONFIG_SWAP_IO_SPACE=y
CONFIG_SWCONFIG=y
CONFIG_SYS_HAS_CPU_MIPS32_R1=y
CONFIG_SYS_HAS_CPU_MIPS32_R2=y
CONFIG_SYS_HAS_EARLY_PRINTK=y
CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
CONFIG_SYS_SUPPORTS_MULTITHREADING=y
CONFIG_XZ_DEC=y
CONFIG_ZONE_DMA_FLAG=0

View File

@ -1,26 +0,0 @@
/*
* Lantiq GPIO button support
*
* Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
* Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
*
* 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 _LANTIQ_DEV_GPIO_BUTTONS_H
#define _LANTIQ_DEV_GPIO_BUTTONS_H
#include <linux/input.h>
#include <linux/gpio_keys.h>
#define LTQ_KEYS_POLL_INTERVAL 20 /* msecs */
#define LTQ_KEYS_DEBOUNCE_INTERVAL (3 * LTQ_KEYS_POLL_INTERVAL)
void ltq_register_gpio_keys_polled(int id,
unsigned poll_interval,
unsigned nbuttons,
struct gpio_keys_button *buttons);
#endif /* _LANTIQ_DEV_GPIO_BUTTONS_H */

View File

@ -1,21 +0,0 @@
/*
* Lantiq GPIO LED device support
*
* Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
* Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
*
* 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 _LANTIQ_DEV_LEDS_GPIO_H
#define _LANTIQ_DEV_LEDS_GPIO_H
#include <linux/leds.h>
void ltq_add_device_gpio_leds(int id,
unsigned num_leds,
struct gpio_led *leds) __init;
#endif /* _LANTIQ_DEV_LEDS_GPIO_H */

View File

@ -1,58 +0,0 @@
/*
* Lantiq GPIO button support
*
* Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
* Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
*
* 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/init.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <dev-gpio-buttons.h>
void __init ltq_register_gpio_keys_polled(int id,
unsigned poll_interval,
unsigned nbuttons,
struct gpio_keys_button *buttons)
{
struct platform_device *pdev;
struct gpio_keys_platform_data pdata;
struct gpio_keys_button *p;
int err;
p = kmalloc(nbuttons * sizeof(*p), GFP_KERNEL);
if (!p)
return;
memcpy(p, buttons, nbuttons * sizeof(*p));
pdev = platform_device_alloc("gpio-keys-polled", id);
if (!pdev)
goto err_free_buttons;
memset(&pdata, 0, sizeof(pdata));
pdata.poll_interval = poll_interval;
pdata.nbuttons = nbuttons;
pdata.buttons = p;
err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
if (err)
goto err_put_pdev;
err = platform_device_add(pdev);
if (err)
goto err_put_pdev;
return;
err_put_pdev:
platform_device_put(pdev);
err_free_buttons:
kfree(p);
}

View File

@ -1,57 +0,0 @@
/*
* Lantiq GPIO LED device support
*
* Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
* Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
*
* Parts of this file are based on Atheros' 2.6.15 BSP
*
* 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/init.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <dev-gpio-leds.h>
void __init ltq_add_device_gpio_leds(int id, unsigned num_leds,
struct gpio_led *leds)
{
struct platform_device *pdev;
struct gpio_led_platform_data pdata;
struct gpio_led *p;
int err;
p = kmalloc(num_leds * sizeof(*p), GFP_KERNEL);
if (!p)
return;
memcpy(p, leds, num_leds * sizeof(*p));
pdev = platform_device_alloc("leds-gpio", id);
if (!pdev)
goto err_free_leds;
memset(&pdata, 0, sizeof(pdata));
pdata.num_leds = num_leds;
pdata.leds = p;
err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
if (err)
goto err_put_pdev;
err = platform_device_add(pdev);
if (err)
goto err_put_pdev;
return;
err_put_pdev:
platform_device_put(pdev);
err_free_leds:
kfree(p);
}

View File

@ -1,213 +0,0 @@
/*
* EASY98000 CPLD Addon driver
*
* Copyright (C) 2011 Thomas Langer <thomas.langer@lantiq.com>
*
* 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/version.h>
#include <linux/types.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
struct easy98000_reg_cpld {
u16 cmdreg1; /* 0x1 */
u16 cmdreg0; /* 0x0 */
u16 idreg0; /* 0x3 */
u16 resreg; /* 0x2 */
u16 intreg; /* 0x5 */
u16 idreg1; /* 0x4 */
u16 ledreg; /* 0x7 */
u16 pcmconconfig; /* 0x6 */
u16 res0; /* 0x9 */
u16 ethledreg; /* 0x8 */
u16 res1[4]; /* 0xa-0xd */
u16 cpld1v; /* 0xf */
u16 cpld2v; /* 0xe */
};
static struct easy98000_reg_cpld * const cpld =
(struct easy98000_reg_cpld *)(KSEG1 | 0x17c00000);
#define cpld_r8(reg) (__raw_readw(&cpld->reg) & 0xFF)
#define cpld_w8(val, reg) __raw_writew((val) & 0xFF, &cpld->reg)
int easy98000_addon_has_dm9000(void)
{
if ((cpld_r8(idreg0) & 0xF) == 1)
return 1;
return 0;
}
#if defined(CONFIG_PROC_FS)
typedef void (*cpld_dump) (struct seq_file *s);
struct proc_entry {
char *name;
void *callback;
};
static int cpld_proc_show ( struct seq_file *s, void *p )
{
cpld_dump dump = s->private;
if ( dump != NULL )
dump(s);
return 0;
}
static int cpld_proc_open ( struct inode *inode, struct file *file )
{
return single_open ( file, cpld_proc_show, PDE(inode)->data );
}
static void cpld_versions_get ( struct seq_file *s )
{
seq_printf(s, "CPLD1: V%d\n", cpld_r8(cpld1v));
seq_printf(s, "CPLD2: V%d\n", cpld_r8(cpld2v));
}
static void cpld_ebu_module_get ( struct seq_file *s )
{
u8 addon_id;
addon_id = cpld_r8(idreg0) & 0xF;
switch (addon_id) {
case 0xF: /* nothing connected */
break;
case 1:
seq_printf(s, "Ethernet Controller module (dm9000)\n");
break;
default:
seq_printf(s, "Unknown EBU module (EBU_ID=0x%02X)\n", addon_id);
break;
}
}
static void cpld_xmii_module_get ( struct seq_file *s )
{
u8 addon_id;
char *mod = NULL;
addon_id = cpld_r8(idreg1) & 0xF;
switch (addon_id) {
case 0xF:
mod = "no module";
break;
case 0x1:
mod = "RGMII module";
break;
case 0x4:
mod = "GMII MAC Mode (XWAY TANTOS-3G)";
break;
case 0x6:
mod = "TMII MAC Mode (XWAY TANTOS-3G)";
break;
case 0x8:
mod = "GMII PHY module";
break;
case 0x9:
mod = "MII PHY module";
break;
case 0xA:
mod = "RMII PHY module";
break;
default:
break;
}
if (mod)
seq_printf(s, "%s\n", mod);
else
seq_printf(s, "unknown xMII module (xMII_ID=0x%02X)\n", addon_id);
}
static struct proc_entry proc_entries[] = {
{"versions", cpld_versions_get},
{"ebu", cpld_ebu_module_get},
{"xmii", cpld_xmii_module_get},
};
static struct file_operations ops = {
.owner = THIS_MODULE,
.open = cpld_proc_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static void cpld_proc_entry_create(struct proc_dir_entry *parent_node,
struct proc_entry *proc_entry)
{
proc_create_data ( proc_entry->name, (S_IFREG | S_IRUGO), parent_node,
&ops, proc_entry->callback);
}
static int cpld_proc_install(void)
{
struct proc_dir_entry *driver_proc_node;
driver_proc_node = proc_mkdir("cpld", NULL);
if (driver_proc_node != NULL) {
int i;
for (i = 0; i < ARRAY_SIZE(proc_entries); i++)
cpld_proc_entry_create(driver_proc_node,
&proc_entries[i]);
} else {
printk("cannot create proc entry");
return -1;
}
return 0;
}
#else
static inline int cpld_proc_install(void) {}
#endif
static int easy98000_addon_probe(struct platform_device *pdev)
{
return cpld_proc_install();
}
static int easy98000_addon_remove(struct platform_device *pdev)
{
#if defined(CONFIG_PROC_FS)
char buf[64];
int i;
for (i = 0; i < sizeof(proc_entries) / sizeof(proc_entries[0]); i++) {
sprintf(buf, "cpld/%s", proc_entries[i].name);
remove_proc_entry(buf, 0);
}
remove_proc_entry("cpld", 0);
#endif
return 0;
}
static struct platform_driver easy98000_addon_driver = {
.probe = easy98000_addon_probe,
.remove = __devexit_p(easy98000_addon_remove),
.driver = {
.name = "easy98000_addon",
.owner = THIS_MODULE,
},
};
int __init easy98000_addon_init(void)
{
return platform_driver_register(&easy98000_addon_driver);
}
void __exit easy98000_addon_exit(void)
{
platform_driver_unregister(&easy98000_addon_driver);
}
module_init(easy98000_addon_init);
module_exit(easy98000_addon_exit);

View File

@ -1,161 +0,0 @@
/*
* EASY98000 CPLD LED driver
*
* Copyright (C) 2010 Ralph Hempel <ralph.hempel@lantiq.com>
*
* 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/version.h>
#include <linux/types.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/leds.h>
#include <linux/slab.h>
#include "dev-leds-easy98000-cpld.h"
const char *led_name[8] = {
"ge0_act",
"ge0_link",
"ge1_act",
"ge1_link",
"fe2_act",
"fe2_link",
"fe3_act",
"fe3_link"
};
#define cpld_base7 ((u16 *)(KSEG1 | 0x17c0000c))
#define cpld_base8 ((u16 *)(KSEG1 | 0x17c00012))
#define ltq_r16(reg) __raw_readw(reg)
#define ltq_w16(val, reg) __raw_writew(val, reg)
struct cpld_led_dev {
struct led_classdev cdev;
u8 mask;
u16 *base;
};
struct cpld_led_drvdata {
struct cpld_led_dev *led_devs;
int num_leds;
};
void led_set(u8 mask, u16 *base)
{
ltq_w16(ltq_r16(base) | mask, base);
}
void led_clear(u8 mask, u16 *base)
{
ltq_w16(ltq_r16(base) & (~mask), base);
}
void led_blink_clear(u8 mask, u16 *base)
{
led_clear(mask, base);
}
static void led_brightness(struct led_classdev *led_cdev,
enum led_brightness value)
{
struct cpld_led_dev *led_dev =
container_of(led_cdev, struct cpld_led_dev, cdev);
if (value)
led_set(led_dev->mask, led_dev->base);
else
led_clear(led_dev->mask, led_dev->base);
}
static int led_probe(struct platform_device *pdev)
{
int i;
char name[32];
struct cpld_led_drvdata *drvdata;
int ret = 0;
drvdata = kzalloc(sizeof(struct cpld_led_drvdata) +
sizeof(struct cpld_led_dev) * MAX_LED,
GFP_KERNEL);
if (!drvdata)
return -ENOMEM;
drvdata->led_devs = (struct cpld_led_dev *) &drvdata[1];
for (i = 0; i < MAX_LED; i++) {
struct cpld_led_dev *led_dev = &drvdata->led_devs[i];
led_dev->cdev.brightness_set = led_brightness;
led_dev->cdev.default_trigger = NULL;
led_dev->mask = 1 << (i % 8);
if(i < 8) {
sprintf(name, "easy98000-cpld:%s", led_name[i]);
led_dev->base = cpld_base8;
} else {
sprintf(name, "easy98000-cpld:red:%d", i-8);
led_dev->base = cpld_base7;
}
led_dev->cdev.name = name;
ret = led_classdev_register(&pdev->dev, &led_dev->cdev);
if (ret)
goto err;
}
platform_set_drvdata(pdev, drvdata);
return 0;
err:
printk("led_probe: 3\n");
for (i = i - 1; i >= 0; i--)
led_classdev_unregister(&drvdata->led_devs[i].cdev);
kfree(drvdata);
return ret;
}
static int led_remove(struct platform_device *pdev)
{
int i;
struct cpld_led_drvdata *drvdata = platform_get_drvdata(pdev);
for (i = 0; i < MAX_LED; i++)
led_classdev_unregister(&drvdata->led_devs[i].cdev);
kfree(drvdata);
return 0;
}
static struct platform_driver led_driver = {
.probe = led_probe,
.remove = __devexit_p(led_remove),
.driver = {
.name = LED_NAME,
.owner = THIS_MODULE,
},
};
int __init easy98000_cpld_led_init(void)
{
pr_info(LED_DESC ", Version " LED_VERSION
" (c) Copyright 2011, Lantiq Deutschland GmbH\n");
return platform_driver_register(&led_driver);
}
void __exit easy98000_cpld_led_exit(void)
{
platform_driver_unregister(&led_driver);
}
module_init(easy98000_cpld_led_init);
module_exit(easy98000_cpld_led_exit);
MODULE_DESCRIPTION(LED_NAME);
MODULE_DESCRIPTION(LED_DESC);
MODULE_AUTHOR("Ralph Hempel <ralph.hempel@lantiq.com>");
MODULE_LICENSE("GPL v2");

View File

@ -1,20 +0,0 @@
/*
* EASY98000 CPLD LED driver
*
* Copyright (C) 2010 Ralph Hempel <ralph.hempel@lantiq.com>
*
* 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 _INCLUDE_EASY98000_CPLD_LED_H_
#define _INCLUDE_EASY98000_CPLD_LED_H_
#define LED_NAME "easy98000_cpld_led"
#define LED_DESC "EASY98000 LED driver"
#define LED_VERSION "1.0.0"
#define MAX_LED 16
#endif /* _INCLUDE_EASY98000_CPLD_LED_H_ */

View File

@ -1,94 +0,0 @@
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/i2c-gpio.h>
#include <dev-gpio-leds.h>
#include "../machtypes.h"
#include "devices.h"
#define BOARD_95C3AM1_GPIO_LED_0 10
#define BOARD_95C3AM1_GPIO_LED_1 11
#define BOARD_95C3AM1_GPIO_LED_2 12
#define BOARD_95C3AM1_GPIO_LED_3 13
static struct mtd_partition board_95C3AM1_partitions[] =
{
{
.name = "uboot",
.offset = 0x0,
.size = 0x40000,
},
{
.name = "uboot_env",
.offset = 0x40000,
.size = 0x40000, /* 2 sectors for redundant env. */
},
{
.name = "linux",
.offset = 0x80000,
.size = 0xF80000, /* map only 16 MiB */
},
};
static struct flash_platform_data board_95C3AM1_flash_platform_data = {
.name = "sflash",
.parts = board_95C3AM1_partitions,
.nr_parts = ARRAY_SIZE(board_95C3AM1_partitions)
};
static struct spi_board_info board_95C3AM1_flash_data __initdata = {
.modalias = "m25p80",
.bus_num = 0,
.chip_select = 0,
.max_speed_hz = 10 * 1000 * 1000,
.mode = SPI_MODE_3,
.platform_data = &board_95C3AM1_flash_platform_data
};
static struct gpio_led board_95C3AM1_gpio_leds[] __initdata = {
{
.name = "power",
.gpio = BOARD_95C3AM1_GPIO_LED_0,
.active_low = 0,
}, {
.name = "optical",
.gpio = BOARD_95C3AM1_GPIO_LED_1,
.active_low = 0,
}, {
.name = "lan",
.gpio = BOARD_95C3AM1_GPIO_LED_2,
.active_low = 0,
}, {
.name = "update",
.gpio = BOARD_95C3AM1_GPIO_LED_3,
.active_low = 0,
}
};
static struct i2c_gpio_platform_data board_95C3AM1_i2c_gpio_data = {
.sda_pin = 107,
.scl_pin = 108,
};
static struct platform_device board_95C3AM1_i2c_gpio_device = {
.name = "i2c-gpio",
.id = 0,
.dev = {
.platform_data = &board_95C3AM1_i2c_gpio_data,
}
};
static void __init board_95C3AM1_init(void)
{
falcon_register_i2c();
falcon_register_spi_flash(&board_95C3AM1_flash_data);
platform_device_register(&board_95C3AM1_i2c_gpio_device);
ltq_add_device_gpio_leds(-1, ARRAY_SIZE(board_95C3AM1_gpio_leds),
board_95C3AM1_gpio_leds);
}
MIPS_MACHINE(LANTIQ_MACH_95C3AM1,
"95C3AM1",
"95C3AM1 Board",
board_95C3AM1_init);

View File

@ -1,118 +0,0 @@
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/leds.h>
#include <linux/gpio.h>
#include <linux/gpio_buttons.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/input.h>
#include <linux/interrupt.h>
#include <linux/spi/spi.h>
#include <linux/spi/flash.h>
#include <dev-gpio-leds.h>
#include "../machtypes.h"
#include "devices.h"
#define EASY98020_GPIO_LED_0 9
#define EASY98020_GPIO_LED_1 10
#define EASY98020_GPIO_LED_2 11
#define EASY98020_GPIO_LED_3 12
#define EASY98020_GPIO_LED_GE0_ACT 110
#define EASY98020_GPIO_LED_GE0_LINK 109
#define EASY98020_GPIO_LED_GE1_ACT 106
#define EASY98020_GPIO_LED_GE1_LINK 105
static struct mtd_partition easy98020_spi_partitions[] =
{
{
.name = "uboot",
.offset = 0x0,
.size = 0x40000,
},
{
.name = "uboot_env",
.offset = 0x40000,
.size = 0x40000, /* 2 sectors for redundant env. */
},
{
.name = "linux",
.offset = 0x80000,
.size = 0xF80000, /* map only 16 MiB */
},
};
static struct flash_platform_data easy98020_spi_flash_platform_data = {
.name = "sflash",
.parts = easy98020_spi_partitions,
.nr_parts = ARRAY_SIZE(easy98020_spi_partitions)
};
static struct spi_board_info easy98020_spi_flash_data __initdata = {
.modalias = "m25p80",
.bus_num = 0,
.chip_select = 0,
.max_speed_hz = 10 * 1000 * 1000,
.mode = SPI_MODE_3,
.platform_data = &easy98020_spi_flash_platform_data
};
static struct gpio_led easy98020_gpio_leds[] __initdata = {
{
.name = "easy98020:green:0",
.gpio = EASY98020_GPIO_LED_0,
.active_low = 0,
}, {
.name = "easy98020:green:1",
.gpio = EASY98020_GPIO_LED_1,
.active_low = 0,
}, {
.name = "easy98020:green:2",
.gpio = EASY98020_GPIO_LED_2,
.active_low = 0,
}, {
.name = "easy98020:green:3",
.gpio = EASY98020_GPIO_LED_3,
.active_low = 0,
}, {
.name = "easy98020:ge0_act",
.gpio = EASY98020_GPIO_LED_GE0_ACT,
.active_low = 0,
}, {
.name = "easy98020:ge0_link",
.gpio = EASY98020_GPIO_LED_GE0_LINK,
.active_low = 0,
}, {
.name = "easy98020:ge1_act",
.gpio = EASY98020_GPIO_LED_GE1_ACT,
.active_low = 0,
}, {
.name = "easy98020:ge1_link",
.gpio = EASY98020_GPIO_LED_GE1_LINK,
.active_low = 0,
}
};
static void __init easy98020_init(void)
{
falcon_register_i2c();
falcon_register_spi_flash(&easy98020_spi_flash_data);
ltq_add_device_gpio_leds(-1, ARRAY_SIZE(easy98020_gpio_leds),
easy98020_gpio_leds);
}
MIPS_MACHINE(LANTIQ_MACH_EASY98020,
"EASY98020",
"EASY98020 Eval Board",
easy98020_init);
MIPS_MACHINE(LANTIQ_MACH_EASY98020_1LAN,
"EASY98020_1LAN",
"EASY98020 Eval Board (1 LAN port)",
easy98020_init);
MIPS_MACHINE(LANTIQ_MACH_EASY98020_2LAN,
"EASY98020_2LAN",
"EASY98020 Eval Board (2 LAN ports)",
easy98020_init);

View File

@ -1,70 +0,0 @@
/*
* 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.
*
* Copyright (C) 2010 John Crispin <blogic@openwrt.org>
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/string.h>
#include <linux/mtd/physmap.h>
#include <linux/kernel.h>
#include <linux/reboot.h>
#include <linux/platform_device.h>
#include <linux/leds.h>
#include <linux/etherdevice.h>
#include <linux/reboot.h>
#include <linux/time.h>
#include <linux/io.h>
#include <linux/gpio.h>
#include <linux/leds.h>
#include <asm/bootinfo.h>
#include <asm/irq.h>
#include <lantiq_soc.h>
#include <lantiq_irq.h>
#include <lantiq_platform.h>
#define LTQ_USB_IOMEM_BASE 0x1e101000
#define LTQ_USB_IOMEM_SIZE 0x00001000
static struct resource resources[] =
{
[0] = {
.name = "dwc_otg_membase",
.start = LTQ_USB_IOMEM_BASE,
.end = LTQ_USB_IOMEM_BASE + LTQ_USB_IOMEM_SIZE - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.name = "dwc_otg_irq",
.flags = IORESOURCE_IRQ,
},
};
static u64 dwc_dmamask = (u32)0x1fffffff;
static struct platform_device platform_dev = {
.name = "dwc_otg",
.dev = {
.dma_mask = &dwc_dmamask,
},
.resource = resources,
.num_resources = ARRAY_SIZE(resources),
};
int __init
xway_register_dwc(int pin)
{
struct irq_data d;
d.irq = resources[1].start;
ltq_enable_irq(&d);
resources[1].start = ltq_is_ase() ? LTQ_USB_ASE_INT : LTQ_USB_INT;
platform_dev.dev.platform_data = (void*) pin;
return platform_device_register(&platform_dev);
}

View File

@ -1,17 +0,0 @@
/*
* 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.
*
* Copyright (C) 2010 John Crispin <blogic@openwrt.org>
*/
#ifndef _LTQ_DEV_DWC_H__
#define _LTQ_DEV_DWC_H__
#include <lantiq_platform.h>
extern void __init xway_register_dwc(int pin);
#endif

View File

@ -1,53 +0,0 @@
/*
* Copyright (C) 2011 John Crispin <blogic@openwrt.org>
* Copyright (C) 2011 Andrej Vlašić <andrej.vlasic0@gmail.com>
*
* 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/init.h>
#include <linux/platform_device.h>
#include <linux/ath5k_platform.h>
#include <linux/ath9k_platform.h>
#include <linux/pci.h>
#include "dev-wifi-athxk.h"
extern int (*ltqpci_plat_dev_init)(struct pci_dev *dev);
struct ath5k_platform_data ath5k_pdata;
struct ath9k_platform_data ath9k_pdata = {
.led_pin = -1,
.endian_check = true,
};
static int
ath5k_pci_plat_dev_init(struct pci_dev *dev)
{
dev->dev.platform_data = &ath5k_pdata;
return 0;
}
static int
ath9k_pci_plat_dev_init(struct pci_dev *dev)
{
dev->dev.platform_data = &ath9k_pdata;
return 0;
}
void __init
ltq_register_ath5k(u16 *eeprom_data, u8 *macaddr)
{
ath5k_pdata.eeprom_data = eeprom_data;
ath5k_pdata.macaddr = macaddr;
ltqpci_plat_dev_init = ath5k_pci_plat_dev_init;
}
void __init
ltq_register_ath9k(u16 *eeprom_data, u8 *macaddr)
{
memcpy(ath9k_pdata.eeprom_data, eeprom_data, sizeof(ath9k_pdata.eeprom_data));
ath9k_pdata.macaddr = macaddr;
ltqpci_plat_dev_init = ath9k_pci_plat_dev_init;
}

View File

@ -1,16 +0,0 @@
/*
* Copyright (C) 2011 John Crispin <blogic@openwrt.org>
* Copyright (C) 2011 Andrej Vlašić <andrej.vlasic0@gmail.com>
*
* 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 _DEV_WIFI_ATHXK_H__
#define _DEV_WIFI_ATHXK_H__
extern void ltq_register_ath5k(u16 *eeprom_data, u8 *macaddr);
extern void ltq_register_ath9k(u16 *eeprom_data, u8 *macaddr);
#endif

View File

@ -1,31 +0,0 @@
/*
* Copyright (C) 2011 John Crispin <blogic@openwrt.org>
*
* 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/init.h>
#include <linux/platform_device.h>
#include <linux/rt2x00_platform.h>
#include <linux/pci.h>
#include "dev-wifi-rt2x00.h"
extern int (*ltqpci_plat_dev_init)(struct pci_dev *dev);
struct rt2x00_platform_data rt2x00_pdata;
static int
rt2x00_pci_plat_dev_init(struct pci_dev *dev)
{
dev->dev.platform_data = &rt2x00_pdata;
return 0;
}
void __init
ltq_register_rt2x00(const char *firmware)
{
rt2x00_pdata.eeprom_file_name = kstrdup(firmware, GFP_KERNEL);
ltqpci_plat_dev_init = rt2x00_pci_plat_dev_init;
}

View File

@ -1,14 +0,0 @@
/*
* Copyright (C) 2011 John Crispin <blogic@openwrt.org>
*
* 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 _DEV_WIFI_RT2X00_H__
#define _DEV_WIFI_RT2X00_H__
extern void ltq_register_rt2x00(const char *firmware);
#endif

View File

@ -1,785 +0,0 @@
/*
* 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.
*
* Copyright (C) 2010 John Crispin <blogic@openwrt.org>
*/
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/leds.h>
#include <linux/gpio.h>
#include <linux/gpio_buttons.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/physmap.h>
#include <linux/input.h>
#include <linux/etherdevice.h>
#include <linux/ath5k_platform.h>
#include <linux/ath9k_platform.h>
#include <linux/pci.h>
#include <lantiq_soc.h>
#include <lantiq_platform.h>
#include <dev-gpio-leds.h>
#include <dev-gpio-buttons.h>
#include "../machtypes.h"
#include "dev-wifi-rt2x00.h"
#include "dev-wifi-athxk.h"
#include "devices.h"
#include "dev-dwc_otg.h"
#include "pci-ath-fixup.h"
static struct mtd_partition arv45xx_brnboot_partitions[] =
{
{
.name = "brn-boot",
.offset = 0x0,
.size = 0x20000,
},
{
.name = "config",
.offset = 0x20000,
.size = 0x30000,
},
{
.name = "linux",
.offset = 0x50000,
.size = 0x390000,
},
{
.name = "reserved", /* 12-byte signature at 0x3efff4 :/ */
.offset = 0x3e0000,
.size = 0x010000,
},
{
.name = "eeprom",
.offset = 0x3f0000,
.size = 0x10000,
},
};
static struct mtd_partition arv75xx_brnboot_partitions[] =
{
{
.name = "brn-boot",
.offset = 0x0,
.size = 0x20000,
},
{
.name = "config",
.offset = 0x20000,
.size = 0x40000,
},
{
.name = "linux",
.offset = 0x440000,
.size = 0x3a0000,
},
{
.name = "reserved", /* 12-byte signature at 0x7efff4 :/ */
.offset = 0x7e0000,
.size = 0x010000,
},
{
.name = "board_config",
.offset = 0x7f0000,
.size = 0x10000,
},
};
/*
* this is generic configuration for all arv based boards, note that it can be
* rewriten in arv_load_nor()
*/
static struct mtd_partition arv_partitions[] =
{
{
.name = "uboot",
.offset = 0x0,
.size = 0x20000,
},
{
.name = "uboot_env",
.offset = 0x20000,
.size = 0x10000,
},
{
.name = "linux",
.offset = 0x30000,
.size = 0x3c0000,
},
{
.name = "board_config",
.offset = 0x3f0000,
.size = 0x10000,
},
};
static struct physmap_flash_data arv45xx_brnboot_flash_data = {
.nr_parts = ARRAY_SIZE(arv45xx_brnboot_partitions),
.parts = arv45xx_brnboot_partitions,
};
static struct physmap_flash_data arv75xx_brnboot_flash_data = {
.nr_parts = ARRAY_SIZE(arv75xx_brnboot_partitions),
.parts = arv75xx_brnboot_partitions,
};
static struct physmap_flash_data arv_flash_data = {
.nr_parts = ARRAY_SIZE(arv_partitions),
.parts = arv_partitions,
};
static void arv_load_nor(unsigned int max)
{
#define UBOOT_MAGIC 0x27051956
int i;
int sector = -1;
if (ltq_brn_boot) {
if (max == 0x800000)
ltq_register_nor(&arv75xx_brnboot_flash_data);
else
ltq_register_nor(&arv45xx_brnboot_flash_data);
return;
}
for (i = 1; i < 4 && sector < 0; i++) {
unsigned int uboot_magic;
memcpy_fromio(&uboot_magic, (void *)KSEG1ADDR(LTQ_FLASH_START) + (i * 0x10000), 4);
if (uboot_magic == UBOOT_MAGIC)
sector = i;
}
if (sector < 0)
return;
arv_partitions[0].size = arv_partitions[1].offset = (sector - 1) * 0x10000;
arv_partitions[2].offset = arv_partitions[0].size + 0x10000;
arv_partitions[2].size = max - arv_partitions[2].offset - 0x10000;
arv_partitions[3].offset = max - 0x10000;
ltq_register_nor(&arv_flash_data);
}
static struct ltq_pci_data ltq_pci_data = {
.clock = PCI_CLOCK_EXT,
.gpio = PCI_GNT1 | PCI_REQ1,
.irq = {
[14] = INT_NUM_IM0_IRL0 + 22,
},
};
static struct ltq_eth_data ltq_eth_data = {
.mii_mode = PHY_INTERFACE_MODE_RMII,
};
static struct gpio_led
arv4510pw_gpio_leds[] __initdata = {
{ .name = "soc:green:foo", .gpio = 4, .active_low = 1, },
};
static struct gpio_led
arv4518pw_gpio_leds[] __initdata = {
{ .name = "soc:green:power", .gpio = 3, .active_low = 1, .default_trigger = "default-on" },
{ .name = "soc:green:adsl", .gpio = 4, .active_low = 1, .default_trigger = "default-on" },
{ .name = "soc:green:internet", .gpio = 5, .active_low = 1, .default_trigger = "default-on" },
{ .name = "soc:green:wifi", .gpio = 6, .active_low = 1, .default_trigger = "default-on" },
{ .name = "soc:yellow:wps", .gpio = 7, .active_low = 1, .default_trigger = "default-on" },
{ .name = "soc:red:fail", .gpio = 8, .active_low = 1, .default_trigger = "default-on" },
{ .name = "soc:green:usb", .gpio = 19, .active_low = 1, .default_trigger = "default-on" },
{ .name = "soc:green:voip", .gpio = 100, .active_low = 1, .default_trigger = "default-on" },
{ .name = "soc:green:fxs1", .gpio = 101, .active_low = 1, .default_trigger = "default-on" },
{ .name = "soc:green:fxs2", .gpio = 102, .active_low = 1, .default_trigger = "default-on" },
{ .name = "soc:green:fxo", .gpio = 103, .active_low = 1, .default_trigger = "default-on" },
};
static struct gpio_keys_button
arv4518pw_gpio_keys[] __initdata = {
{
.desc = "wifi",
.type = EV_KEY,
.code = BTN_0,
.debounce_interval = LTQ_KEYS_DEBOUNCE_INTERVAL,
.gpio = 28,
.active_low = 1,
},
{
.desc = "reset",
.type = EV_KEY,
.code = BTN_1,
.debounce_interval = LTQ_KEYS_DEBOUNCE_INTERVAL,
.gpio = 30,
.active_low = 1,
},
{
.desc = "wps",
.type = EV_KEY,
.code = BTN_2,
.debounce_interval = LTQ_KEYS_DEBOUNCE_INTERVAL,
.gpio = 29,
.active_low = 1,
},
};
static struct gpio_led
arv4519pw_gpio_leds[] __initdata = {
{ .name = "soc:red:power", .gpio = 7, .active_low = 1, },
{ .name = "soc:green:power", .gpio = 2, .active_low = 1, .default_trigger = "default-on" },
{ .name = "soc:green:wifi", .gpio = 6, .active_low = 1, },
{ .name = "soc:green:adsl", .gpio = 4, .active_low = 1, },
{ .name = "soc:green:internet", .gpio = 5, .active_low = 1, },
{ .name = "soc:red:internet", .gpio = 8, .active_low = 1, },
{ .name = "soc:green:voip", .gpio = 100, .active_low = 1, },
{ .name = "soc:green:phone1", .gpio = 101, .active_low = 1, },
{ .name = "soc:green:phone2", .gpio = 102, .active_low = 1, },
{ .name = "soc:green:fxo", .gpio = 103, .active_low = 1, },
{ .name = "soc:green:usb", .gpio = 19, .active_low = 1, },
{ .name = "soc:orange:wps", .gpio = 104, .active_low = 1, },
{ .name = "soc:green:wps", .gpio = 105, .active_low = 1, },
{ .name = "soc:red:wps", .gpio = 106, .active_low = 1, },
};
static struct gpio_keys_button
arv4519pw_gpio_keys[] __initdata = {
{
.desc = "reset",
.type = EV_KEY,
.code = BTN_1,
.debounce_interval = LTQ_KEYS_DEBOUNCE_INTERVAL,
.gpio = 30,
.active_low = 1,
},
{
.desc = "wlan",
.type = EV_KEY,
.code = BTN_2,
.debounce_interval = LTQ_KEYS_DEBOUNCE_INTERVAL,
.gpio = 28,
.active_low = 1,
},
};
static struct gpio_led
arv4520pw_gpio_leds[] __initdata = {
{ .name = "soc:blue:power", .gpio = 3, .active_low = 1, },
{ .name = "soc:blue:adsl", .gpio = 4, .active_low = 1, },
{ .name = "soc:blue:internet", .gpio = 5, .active_low = 1, },
{ .name = "soc:red:power", .gpio = 6, .active_low = 1, },
{ .name = "soc:yellow:wps", .gpio = 7, .active_low = 1, },
{ .name = "soc:red:wps", .gpio = 9, .active_low = 1, },
{ .name = "soc:blue:voip", .gpio = 100, .active_low = 1, },
{ .name = "soc:blue:fxs1", .gpio = 101, .active_low = 1, },
{ .name = "soc:blue:fxs2", .gpio = 102, .active_low = 1, },
{ .name = "soc:blue:fxo", .gpio = 103, .active_low = 1, },
{ .name = "soc:blue:voice", .gpio = 104, .active_low = 1, },
{ .name = "soc:blue:usb", .gpio = 105, .active_low = 1, },
{ .name = "soc:blue:wifi", .gpio = 106, .active_low = 1, },
};
static struct gpio_led
arv452cpw_gpio_leds[] __initdata = {
{ .name = "soc:blue:power", .gpio = 3, .active_low = 1, .default_trigger = "default-on" },
{ .name = "soc:blue:adsl", .gpio = 4, .active_low = 1, .default_trigger = "default-on" },
{ .name = "soc:blue:isdn", .gpio = 5, .active_low = 1, .default_trigger = "default-on" },
{ .name = "soc:red:power", .gpio = 6, .active_low = 1, .default_trigger = "default-on" },
{ .name = "soc:yellow:wps", .gpio = 7, .active_low = 1, .default_trigger = "default-on" },
{ .name = "soc:red:wps", .gpio = 9, .active_low = 1, .default_trigger = "default-on" },
{ .name = "soc:blue:fxs1", .gpio = 100, .active_low = 1, .default_trigger = "default-on" },
{ .name = "soc:blue:fxs2", .gpio = 101, .active_low = 1, .default_trigger = "default-on" },
{ .name = "soc:blue:wps", .gpio = 102, .active_low = 1, .default_trigger = "default-on" },
{ .name = "soc:blue:fxo", .gpio = 103, .active_low = 1, .default_trigger = "default-on" },
{ .name = "soc:blue:voice", .gpio = 104, .active_low = 1, .default_trigger = "default-on" },
{ .name = "soc:blue:usb", .gpio = 105, .active_low = 1, .default_trigger = "default-on" },
{ .name = "soc:blue:wifi", .gpio = 106, .active_low = 1, .default_trigger = "default-on" },
{ .name = "soc:blue:internet", .gpio = 108, .active_low = 1, .default_trigger = "default-on" },
{ .name = "soc:red:internet", .gpio = 109, .active_low = 1, .default_trigger = "default-on" },
};
static struct gpio_led
arv4525pw_gpio_leds[] __initdata = {
{ .name = "soc:green:dsl", .gpio = 6, .active_low = 1, .default_trigger = "default-on" },
{ .name = "soc:green:wifi", .gpio = 8, .active_low = 1, .default_trigger = "default-on" },
{ .name = "soc:green:online", .gpio = 9, .active_low = 1, .default_trigger = "default-on" },
{ .name = "soc:green:fxs-internet", .gpio = 5, .active_low = 1, .default_trigger = "default-on" },
{ .name = "soc:green:fxs-festnetz", .gpio = 4, .active_low = 1, .default_trigger = "default-on" },
};
#define ARV4525PW_PHYRESET 13
#define ARV4525PW_RELAY 31
static struct gpio arv4525pw_gpios[] __initdata = {
{ ARV4525PW_PHYRESET, GPIOF_OUT_INIT_HIGH, "phyreset" },
{ ARV4525PW_RELAY, GPIOF_OUT_INIT_HIGH, "relay" },
};
static struct gpio_led
arv752dpw22_gpio_leds[] __initdata = {
{ .name = "soc:blue:power", .gpio = 3, .active_low = 1, .default_trigger = "default-on" },
{ .name = "soc:red:internet", .gpio = 5, .active_low = 1, .default_trigger = "default-on" },
{ .name = "soc:red:power", .gpio = 6, .active_low = 1, .default_trigger = "default-on" },
{ .name = "soc:red:wps", .gpio = 8, .active_low = 1, .default_trigger = "default-on" },
{ .name = "soc:red:fxo", .gpio = 103, .active_low = 1, .default_trigger = "default-on" },
{ .name = "soc:red:voice", .gpio = 104, .active_low = 1, .default_trigger = "default-on" },
{ .name = "soc:green:usb", .gpio = 105, .active_low = 1, .default_trigger = "default-on" },
{ .name = "soc:green:wifi", .gpio = 106, .active_low = 1, .default_trigger = "default-on" },
{ .name = "soc:green:wifi1", .gpio = 107, .active_low = 1, .default_trigger = "default-on" },
{ .name = "soc:blue:wifi", .gpio = 108, .active_low = 1, .default_trigger = "default-on" },
{ .name = "soc:blue:wifi1", .gpio = 109, .active_low = 1, .default_trigger = "default-on" },
{ .name = "soc:green:eth1", .gpio = 111, .active_low = 1, .default_trigger = "default-on" },
{ .name = "soc:green:eth2", .gpio = 112, .active_low = 1, .default_trigger = "default-on" },
{ .name = "soc:green:eth3", .gpio = 113, .active_low = 1, .default_trigger = "default-on" },
{ .name = "soc:green:eth4", .gpio = 114, .active_low = 1, .default_trigger = "default-on", },
};
static struct gpio_keys_button
arv752dpw22_gpio_keys[] __initdata = {
{
.desc = "btn0",
.type = EV_KEY,
.code = BTN_0,
.debounce_interval = LTQ_KEYS_DEBOUNCE_INTERVAL,
.gpio = 12,
.active_low = 1,
},
{
.desc = "btn1",
.type = EV_KEY,
.code = BTN_1,
.debounce_interval = LTQ_KEYS_DEBOUNCE_INTERVAL,
.gpio = 13,
.active_low = 1,
},
{
.desc = "btn2",
.type = EV_KEY,
.code = BTN_2,
.debounce_interval = LTQ_KEYS_DEBOUNCE_INTERVAL,
.gpio = 28,
.active_low = 1,
},
};
static struct gpio_led
arv7518pw_gpio_leds[] __initdata = {
{ .name = "soc:red:power", .gpio = 7, .active_low = 1, },
{ .name = "soc:green:power", .gpio = 2, .active_low = 1, .default_trigger = "default-on" },
{ .name = "soc:green:wifi", .gpio = 6, .active_low = 1, },
{ .name = "soc:green:adsl", .gpio = 4, .active_low = 1, },
{ .name = "soc:green:internet", .gpio = 5, .active_low = 1, },
{ .name = "soc:red:internet", .gpio = 8, .active_low = 1, },
{ .name = "soc:green:voip", .gpio = 100, .active_low = 1, },
{ .name = "soc:green:phone1", .gpio = 101, .active_low = 1, },
{ .name = "soc:green:phone2", .gpio = 102, .active_low = 1, },
{ .name = "soc:orange:fail", .gpio = 103, .active_low = 1, },
{ .name = "soc:green:usb", .gpio = 19, .active_low = 1, },
{ .name = "soc:orange:wps", .gpio = 104, .active_low = 1, },
{ .name = "soc:green:wps", .gpio = 105, .active_low = 1, },
{ .name = "soc:red:wps", .gpio = 106, .active_low = 1, },
};
static struct gpio_keys_button
arv7518pw_gpio_keys[] __initdata = {
/*{
.desc = "reset",
.type = EV_KEY,
.code = BTN_1,
.debounce_interval = LTQ_KEYS_DEBOUNCE_INTERVAL,
.gpio = 23,
.active_low = 1,
},*/
{
.desc = "wifi",
.type = EV_KEY,
.code = BTN_2,
.debounce_interval = LTQ_KEYS_DEBOUNCE_INTERVAL,
.gpio = 25,
.active_low = 1,
},
};
static struct gpio_keys_button
arv7525pw_gpio_keys[] __initdata = {
{
.desc = "restart",
.type = EV_KEY,
.code = BTN_0,
.debounce_interval = LTQ_KEYS_DEBOUNCE_INTERVAL,
.gpio = 29,
.active_low = 1,
},
};
static void
arv_register_ethernet(unsigned int mac_addr)
{
memcpy_fromio(&ltq_eth_data.mac.sa_data,
(void *)KSEG1ADDR(LTQ_FLASH_START + mac_addr), 6);
ltq_register_etop(&ltq_eth_data);
}
static u16 arv_ath5k_eeprom_data[ATH5K_PLAT_EEP_MAX_WORDS];
static u16 arv_ath9k_eeprom_data[ATH9K_PLAT_EEP_MAX_WORDS];
static u8 arv_athxk_eeprom_mac[6];
void __init
arv_register_ath5k(unsigned int ath_addr, unsigned int mac_addr)
{
int i;
memcpy_fromio(arv_athxk_eeprom_mac,
(void *)KSEG1ADDR(LTQ_FLASH_START + mac_addr), 6);
arv_athxk_eeprom_mac[5]++;
memcpy_fromio(arv_ath5k_eeprom_data,
(void *)KSEG1ADDR(LTQ_FLASH_START + ath_addr), ATH5K_PLAT_EEP_MAX_WORDS);
// swap eeprom bytes
for (i = 0; i < ATH5K_PLAT_EEP_MAX_WORDS>>1; i++) {
arv_ath5k_eeprom_data[i] = swab16(arv_ath5k_eeprom_data[i]);
if (i == 0x17e>>1) {
/*
* regdomain is invalid. it's unknown how did original
* fw convered value to 0x82d4 so for now force to 0x67
*/
arv_ath5k_eeprom_data[i] &= 0x0000;
arv_ath5k_eeprom_data[i] |= 0x67;
}
}
}
void __init
arv_register_ath9k(unsigned int ath_addr, unsigned int mac_addr)
{
int i;
u16 *eepdata, sum, el;
memcpy_fromio(arv_athxk_eeprom_mac,
(void *)KSEG1ADDR(LTQ_FLASH_START + mac_addr), 6);
arv_athxk_eeprom_mac[5]++;
memcpy_fromio(arv_ath9k_eeprom_data,
(void *)KSEG1ADDR(LTQ_FLASH_START + ath_addr), ATH9K_PLAT_EEP_MAX_WORDS);
// force regdomain to 0x67
arv_ath9k_eeprom_data[0x208>>1] = 0x67;
// calculate new checksum
sum = arv_ath9k_eeprom_data[0x200>>1];
el = sum / sizeof(u16) - 2; /* skip length and (old) checksum */
eepdata = (u16 *) (&arv_ath9k_eeprom_data[0x204>>1]); /* after checksum */
for (i = 0; i < el; i++)
sum ^= *eepdata++;
sum ^= 0xffff;
arv_ath9k_eeprom_data[0x202>>1] = sum;
}
static void __init
arv3527p_init(void)
{
#define ARV3527P_MAC_ADDR 0x3f0016
ltq_register_gpio_stp();
//ltq_add_device_gpio_leds(arv3527p_gpio_leds, ARRAY_SIZE(arv3527p_gpio_leds));
arv_load_nor(0x400000);
arv_register_ethernet(ARV3527P_MAC_ADDR);
}
MIPS_MACHINE(LANTIQ_MACH_ARV3527P,
"ARV3527P",
"ARV3527P - Arcor Easybox 401",
arv3527p_init);
static void __init
arv4510pw_init(void)
{
#define ARV4510PW_MAC_ADDR 0x3f0014
ltq_register_gpio_stp();
ltq_add_device_gpio_leds(-1, ARRAY_SIZE(arv4510pw_gpio_leds), arv4510pw_gpio_leds);
arv_load_nor(0x400000);
ltq_pci_data.irq[12] = (INT_NUM_IM2_IRL0 + 31);
ltq_pci_data.irq[15] = (INT_NUM_IM0_IRL0 + 26);
ltq_pci_data.gpio |= PCI_EXIN2 | PCI_REQ2;
ltq_register_pci(&ltq_pci_data);
arv_register_ethernet(ARV4510PW_MAC_ADDR);
}
MIPS_MACHINE(LANTIQ_MACH_ARV4510PW,
"ARV4510PW",
"ARV4510PW - Wippies Homebox",
arv4510pw_init);
static void __init
arv4518pw_init(void)
{
#define ARV4518PW_EBU 0
#define ARV4518PW_USB 14
#define ARV4518PW_SWITCH_RESET 13
#define ARV4518PW_ATH_ADDR 0x3f0400
#define ARV4518PW_MADWIFI_ADDR 0xb03f0400
#define ARV4518PW_MAC_ADDR 0x3f0016
ltq_register_gpio_ebu(ARV4518PW_EBU);
ltq_add_device_gpio_leds(-1, ARRAY_SIZE(arv4518pw_gpio_leds), arv4518pw_gpio_leds);
ltq_register_gpio_keys_polled(-1, LTQ_KEYS_POLL_INTERVAL,
ARRAY_SIZE(arv4518pw_gpio_keys), arv4518pw_gpio_keys);
arv_load_nor(0x400000);
ltq_pci_data.gpio = PCI_GNT2 | PCI_REQ2;
ltq_register_pci(&ltq_pci_data);
xway_register_dwc(ARV4518PW_USB);
arv_register_ethernet(ARV4518PW_MAC_ADDR);
arv_register_ath5k(ARV4518PW_ATH_ADDR, ARV4518PW_MAC_ADDR);
ltq_register_ath5k(arv_ath5k_eeprom_data, arv_athxk_eeprom_mac);
gpio_request(ARV4518PW_SWITCH_RESET, "switch");
gpio_direction_output(ARV4518PW_SWITCH_RESET, 1);
gpio_export(ARV4518PW_SWITCH_RESET, 0);
}
MIPS_MACHINE(LANTIQ_MACH_ARV4518PW,
"ARV4518PW",
"ARV4518PW - SMC7908A-ISP, Airties WAV-221",
arv4518pw_init);
static void __init
arv4519pw_init(void)
{
#define ARV4519PW_EBU 0
#define ARV4519PW_USB 14
#define ARV4519PW_RELAY 31
#define ARV4519PW_SWITCH_RESET 13
#define ARV4519PW_ATH_ADDR 0x3f0400
#define ARV4519PW_MAC_ADDR 0x3f0016
arv_load_nor(0x400000);
ltq_register_gpio_ebu(ARV4519PW_EBU);
ltq_add_device_gpio_leds(-1, ARRAY_SIZE(arv4519pw_gpio_leds), arv4519pw_gpio_leds);
ltq_register_gpio_keys_polled(-1, LTQ_KEYS_POLL_INTERVAL,
ARRAY_SIZE(arv4519pw_gpio_keys), arv4519pw_gpio_keys);
ltq_pci_data.gpio = PCI_GNT2 | PCI_REQ1;
ltq_register_pci(&ltq_pci_data);
xway_register_dwc(ARV4519PW_USB);
arv_register_ethernet(ARV4519PW_MAC_ADDR);
arv_register_ath5k(ARV4519PW_ATH_ADDR, ARV4519PW_MAC_ADDR);
ltq_register_ath5k(arv_ath5k_eeprom_data, arv_athxk_eeprom_mac);
gpio_request(ARV4519PW_RELAY, "relay");
gpio_direction_output(ARV4519PW_RELAY, 1);
gpio_export(ARV4519PW_RELAY, 0);
gpio_request(ARV4519PW_SWITCH_RESET, "switch");
gpio_set_value(ARV4519PW_SWITCH_RESET, 1);
gpio_export(ARV4519PW_SWITCH_RESET, 0);
}
MIPS_MACHINE(LANTIQ_MACH_ARV4519PW,
"ARV4519PW",
"ARV4519PW - Vodafone, Pirelli",
arv4519pw_init);
static void __init
arv4520pw_init(void)
{
#define ARV4520PW_EBU 0x400
#define ARV4520PW_USB 28
#define ARV4520PW_SWITCH_RESET 110
#define ARV4520PW_MAC_ADDR 0x3f0016
ltq_register_gpio_ebu(ARV4520PW_EBU);
ltq_add_device_gpio_leds(-1, ARRAY_SIZE(arv4520pw_gpio_leds), arv4520pw_gpio_leds);
arv_load_nor(0x400000);
ltq_register_pci(&ltq_pci_data);
ltq_register_tapi();
arv_register_ethernet(ARV4520PW_MAC_ADDR);
xway_register_dwc(ARV4520PW_USB);
gpio_request(ARV4520PW_SWITCH_RESET, "switch");
gpio_set_value(ARV4520PW_SWITCH_RESET, 1);
}
MIPS_MACHINE(LANTIQ_MACH_ARV4520PW,
"ARV4520PW",
"ARV4520PW - Airties WAV-281, Arcor A800",
arv4520pw_init);
static void __init
arv452Cpw_init(void)
{
#define ARV452CPW_EBU 0x77f
#define ARV452CPW_USB 28
#define ARV452CPW_RELAY1 31
#define ARV452CPW_RELAY2 107
#define ARV452CPW_SWITCH_RESET 110
#define ARV452CPW_ATH_ADDR 0x3f0400
#define ARV452CPW_MADWIFI_ADDR 0xb03f0400
#define ARV452CPW_MAC_ADDR 0x3f0016
ltq_register_gpio_ebu(ARV452CPW_EBU);
ltq_add_device_gpio_leds(-1, ARRAY_SIZE(arv452cpw_gpio_leds), arv452cpw_gpio_leds);
arv_load_nor(0x400000);
ltq_register_pci(&ltq_pci_data);
xway_register_dwc(ARV452CPW_USB);
arv_register_ethernet(ARV452CPW_MAC_ADDR);
arv_register_ath5k(ARV452CPW_ATH_ADDR, ARV452CPW_MAC_ADDR);
ltq_register_ath5k(arv_ath5k_eeprom_data, arv_athxk_eeprom_mac);
gpio_request(ARV452CPW_SWITCH_RESET, "switch");
gpio_set_value(ARV452CPW_SWITCH_RESET, 1);
gpio_export(ARV452CPW_SWITCH_RESET, 0);
gpio_request(ARV452CPW_RELAY1, "relay1");
gpio_direction_output(ARV452CPW_RELAY1, 1);
gpio_export(ARV452CPW_RELAY1, 0);
gpio_request(ARV452CPW_RELAY2, "relay2");
gpio_set_value(ARV452CPW_RELAY2, 1);
gpio_export(ARV452CPW_RELAY2, 0);
}
MIPS_MACHINE(LANTIQ_MACH_ARV452CPW,
"ARV452CPW",
"ARV452CPW - Arcor A801",
arv452Cpw_init);
static void __init
arv4525pw_init(void)
{
#define ARV4525PW_ATH_ADDR 0x3f0400
#define ARV4525PW_MADWIFI_ADDR 0xb03f0400
#define ARV4525PW_MAC_ADDR 0x3f0016
arv_load_nor(0x400000);
ltq_add_device_gpio_leds(-1, ARRAY_SIZE(arv4525pw_gpio_leds), arv4525pw_gpio_leds);
gpio_request_array(arv4525pw_gpios, ARRAY_SIZE(arv4525pw_gpios));
gpio_export(ARV4525PW_RELAY, false);
gpio_export(ARV4525PW_PHYRESET, false);
ltq_pci_data.clock = PCI_CLOCK_INT;
ltq_register_pci(&ltq_pci_data);
arv_register_ath5k(ARV4525PW_ATH_ADDR, ARV4525PW_MADWIFI_ADDR);
ltq_register_ath5k(arv_ath5k_eeprom_data, arv_athxk_eeprom_mac);
ltq_eth_data.mii_mode = PHY_INTERFACE_MODE_MII;
arv_register_ethernet(ARV4525PW_MAC_ADDR);
}
MIPS_MACHINE(LANTIQ_MACH_ARV4525PW,
"ARV4525PW",
"ARV4525PW - Speedport W502V",
arv4525pw_init);
static void __init
arv7525pw_init(void)
{
#define ARV7525P_MAC_ADDR 0x3f0016
arv_load_nor(0x400000);
ltq_add_device_gpio_leds(-1, ARRAY_SIZE(arv4525pw_gpio_leds), arv4525pw_gpio_leds);
ltq_register_gpio_keys_polled(-1, LTQ_KEYS_POLL_INTERVAL,
ARRAY_SIZE(arv7525pw_gpio_keys), arv7525pw_gpio_keys);
ltq_pci_data.clock = PCI_CLOCK_INT;
ltq_pci_data.gpio = PCI_GNT1 | PCI_EXIN1;
ltq_pci_data.irq[14] = (INT_NUM_IM3_IRL0 + 31);
ltq_register_pci(&ltq_pci_data);
ltq_eth_data.mii_mode = PHY_INTERFACE_MODE_MII;
ltq_register_rt2x00("RT2860.eeprom");
ltq_register_tapi();
arv_register_ethernet(ARV7525P_MAC_ADDR);
}
MIPS_MACHINE(LANTIQ_MACH_ARV7525PW,
"ARV7525PW",
"ARV7525PW - Speedport W303V",
arv7525pw_init);
static void __init
arv7518pw_init(void)
{
#define ARV7518PW_EBU 0x2
#define ARV7518PW_USB 14
#define ARV7518PW_SWITCH_RESET 13
#define ARV7518PW_ATH_ADDR 0x7f0400
#define ARV7518PW_MAC_ADDR 0x7f0016
arv_load_nor(0x800000);
ltq_register_gpio_ebu(ARV7518PW_EBU);
ltq_add_device_gpio_leds(-1, ARRAY_SIZE(arv7518pw_gpio_leds), arv7518pw_gpio_leds);
ltq_register_gpio_keys_polled(-1, LTQ_KEYS_POLL_INTERVAL,
ARRAY_SIZE(arv7518pw_gpio_keys), arv7518pw_gpio_keys);
ltq_register_pci(&ltq_pci_data);
ltq_register_tapi();
xway_register_dwc(ARV7518PW_USB);
arv_register_ethernet(ARV7518PW_MAC_ADDR);
arv_register_ath9k(ARV7518PW_ATH_ADDR, ARV7518PW_MAC_ADDR);
ltq_register_ath9k(arv_ath9k_eeprom_data, arv_athxk_eeprom_mac);
ltq_pci_ath_fixup(14, arv_ath9k_eeprom_data);
gpio_request(ARV7518PW_SWITCH_RESET, "switch");
gpio_direction_output(ARV7518PW_SWITCH_RESET, 1);
gpio_export(ARV7518PW_SWITCH_RESET, 0);
}
MIPS_MACHINE(LANTIQ_MACH_ARV7518PW,
"ARV7518PW",
"ARV7518PW - ASTORIA",
arv7518pw_init);
static void __init
arv752dpw22_init(void)
{
#define ARV752DPW22_EBU 0x2
#define ARV752DPW22_USB 100
#define ARV752DPW22_RELAY 101
#define ARV752DPW22_MAC_ADDR 0x7f0016
arv_load_nor(0x800000);
ltq_register_gpio_ebu(ARV752DPW22_EBU);
ltq_add_device_gpio_leds(-1, ARRAY_SIZE(arv752dpw22_gpio_leds), arv752dpw22_gpio_leds);
ltq_register_gpio_keys_polled(-1, LTQ_KEYS_POLL_INTERVAL,
ARRAY_SIZE(arv752dpw22_gpio_keys), arv752dpw22_gpio_keys);
ltq_pci_data.irq[15] = (INT_NUM_IM3_IRL0 + 31);
ltq_pci_data.gpio |= PCI_EXIN1 | PCI_REQ2;
ltq_register_pci(&ltq_pci_data);
xway_register_dwc(ARV752DPW22_USB);
arv_register_ethernet(ARV752DPW22_MAC_ADDR);
gpio_request(ARV752DPW22_RELAY, "relay");
gpio_set_value(ARV752DPW22_RELAY, 1);
gpio_export(ARV752DPW22_RELAY, 0);
}
MIPS_MACHINE(LANTIQ_MACH_ARV752DPW22,
"ARV752DPW22",
"ARV752DPW22 - Arcor A803",
arv752dpw22_init);
static void __init
arv752dpw_init(void)
{
#define ARV752DPW22_EBU 0x2
#define ARV752DPW22_USB 100
#define ARV752DPW22_RELAY 101
#define ARV752DPW22_MAC_ADDR 0x7f0016
arv_load_nor(0x800000);
ltq_register_gpio_ebu(ARV752DPW22_EBU);
ltq_add_device_gpio_leds(-1, ARRAY_SIZE(arv752dpw22_gpio_leds), arv752dpw22_gpio_leds);
ltq_register_gpio_keys_polled(-1, LTQ_KEYS_POLL_INTERVAL, ARRAY_SIZE(arv752dpw22_gpio_keys), arv752dpw22_gpio_keys);
ltq_pci_data.irq[14] = (INT_NUM_IM3_IRL0 + 31);
ltq_pci_data.gpio |= PCI_EXIN1 | PCI_REQ2;
ltq_register_pci(&ltq_pci_data);
xway_register_dwc(ARV752DPW22_USB);
ltq_register_rt2x00("RT2860.eeprom");
arv_register_ethernet(ARV752DPW22_MAC_ADDR);
gpio_request(ARV752DPW22_RELAY, "relay");
gpio_set_value(ARV752DPW22_RELAY, 1);
gpio_export(ARV752DPW22_RELAY, 0);
}
MIPS_MACHINE(LANTIQ_MACH_ARV752DPW,
"ARV752DPW",
"ARV752DPW - Arcor A802",
arv752dpw_init);

View File

@ -1,542 +0,0 @@
/*
* 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.
*
* Copyright (C) 2011 Andrej Vlašić
* Copyright (C) 2011 Luka Perkov
*
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/leds.h>
#include <linux/gpio.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/physmap.h>
#include <linux/input.h>
#include <linux/ath5k_platform.h>
#include <linux/ath9k_platform.h>
#include <linux/pci.h>
#include <linux/phy.h>
#include <linux/io.h>
#include <linux/string.h>
#include <linux/delay.h>
#include <linux/module.h>
#include <irq.h>
#include <lantiq_soc.h>
#include <lantiq_platform.h>
#include <dev-gpio-leds.h>
#include <dev-gpio-buttons.h>
#include "../machtypes.h"
//#include "dev-wifi-ath9k.h"
#include "devices.h"
#include "dev-dwc_otg.h"
#undef USE_BTHH_GPIO_INIT
// this reads certain data from u-boot if it's there
#define USE_UBOOT_ENV_DATA
#define UBOOT_ENV_OFFSET 0x040000
#define UBOOT_ENV_SIZE 0x010000
#ifdef NAND_ORGLAYOUT
// this is only here for reference
// definition of NAND flash area
static struct mtd_partition bthomehubv2b_nand_partitions[] =
{
{
.name = "ART",
.offset = 0x0000000,
.size = 0x0004000,
},
{
.name = "image1",
.offset = 0x0004000,
.size = 0x0E00000,
},
{
.name = "unknown1",
.offset = 0x0E04000,
.size = 0x00FC000,
},
{
.name = "image2",
.offset = 0x0F00000,
.size = 0x0E00000,
},
{
.name = "unknown2",
.offset = 0x1D00000,
.size = 0x0300000,
},
};
#endif
#ifdef NAND_KEEPOPENRG
// this allows both firmwares to co-exist
static struct mtd_partition bthomehubv2b_nand_partitions[] =
{
{
.name = "art",
.offset = 0x0000000,
.size = 0x0004000,
},
{
.name = "Image1",
.offset = 0x0004000,
.size = 0x0E00000,
},
{
.name = "linux",
.offset = 0x0E04000,
.size = 0x11fC000,
},
{
.name = "wholeflash",
.offset = 0x0000000,
.size = 0x2000000,
},
};
#endif
// this gives more jffs2 by overwriting openrg
static struct mtd_partition bthomehubv2b_nand_partitions[] =
{
{
.name = "art",
.offset = 0x0000000,
.size = 0x0004000,
},
{
.name = "linux",
.offset = 0x0004000,
.size = 0x1ffC000,
},
{
.name = "wholeflash",
.offset = 0x0000000,
.size = 0x2000000,
},
};
extern void __init xway_register_nand(struct mtd_partition *parts, int count);
// end BTHH_USE_NAND
static struct gpio_led
bthomehubv2b_gpio_leds[] __initdata = {
{ .name = "soc:orange:upgrading", .gpio = 213, },
{ .name = "soc:orange:phone", .gpio = 214, },
{ .name = "soc:blue:phone", .gpio = 215, },
{ .name = "soc:orange:wireless", .gpio = 216, },
{ .name = "soc:blue:wireless", .gpio = 217, },
{ .name = "soc:red:broadband", .gpio = 218, },
{ .name = "soc:orange:broadband", .gpio = 219, },
{ .name = "soc:blue:broadband", .gpio = 220, },
{ .name = "soc:red:power", .gpio = 221, },
{ .name = "soc:orange:power", .gpio = 222, },
{ .name = "soc:blue:power", .gpio = 223, },
};
static struct gpio_keys_button
bthomehubv2b_gpio_keys[] __initdata = {
{
.desc = "restart",
.type = EV_KEY,
.code = BTN_0,
.debounce_interval = LTQ_KEYS_DEBOUNCE_INTERVAL,
.gpio = 2,
.active_low = 1,
},
{
.desc = "findhandset",
.type = EV_KEY,
.code = BTN_1,
.debounce_interval = LTQ_KEYS_DEBOUNCE_INTERVAL,
.gpio = 15,
.active_low = 1,
},
{
.desc = "wps",
.type = EV_KEY,
.code = BTN_2,
.debounce_interval = LTQ_KEYS_DEBOUNCE_INTERVAL,
.gpio = 22,
.active_low = 1,
},
};
// definition of NOR flash area - as per original.
static struct mtd_partition bthomehubv2b_partitions[] =
{
{
.name = "uboot",
.offset = 0x000000,
.size = 0x040000,
},
{
.name = "uboot_env",
.offset = UBOOT_ENV_OFFSET,
.size = UBOOT_ENV_SIZE,
},
{
.name = "rg_conf_1",
.offset = 0x050000,
.size = 0x010000,
},
{
.name = "rg_conf_2",
.offset = 0x060000,
.size = 0x010000,
},
{
.name = "rg_conf_factory",
.offset = 0x070000,
.size = 0x010000,
},
};
/* nor flash */
/* bt homehubv2b has a very small nor flash */
/* so make it look for a small one, else we get a lot of alias chips identified - */
/* not a bug problem, but fills the logs. */
static struct resource bthhv2b_nor_resource =
MEM_RES("nor", LTQ_FLASH_START, 0x80000);
static struct platform_device ltq_nor = {
.name = "ltq_nor",
.resource = &bthhv2b_nor_resource,
.num_resources = 1,
};
static void __init bthhv2b_register_nor(struct physmap_flash_data *data)
{
ltq_nor.dev.platform_data = data;
platform_device_register(&ltq_nor);
}
static struct physmap_flash_data bthomehubv2b_flash_data = {
.nr_parts = ARRAY_SIZE(bthomehubv2b_partitions),
.parts = bthomehubv2b_partitions,
};
static struct ltq_pci_data ltq_pci_data = {
.clock = PCI_CLOCK_INT,
.gpio = PCI_GNT1 | PCI_REQ1,
.irq = { [14] = INT_NUM_IM0_IRL0 + 22, },
};
static struct ltq_eth_data ltq_eth_data = {
.mii_mode = PHY_INTERFACE_MODE_MII,
};
static char __init *get_uboot_env_var(char *haystack, int haystack_len, char *needle, int needle_len) {
int i;
for (i = 0; i <= haystack_len - needle_len; i++) {
if (memcmp(haystack + i, needle, needle_len) == 0) {
return haystack + i + needle_len;
}
}
return NULL;
}
/*
* bthomehubv2b_parse_hex_* are not uniq. in arm/orion there are also duplicates:
* dns323_parse_hex_*
* TODO: one day write a patch for this :)
*/
static int __init bthomehubv2b_parse_hex_nibble(char n) {
if (n >= '0' && n <= '9')
return n - '0';
if (n >= 'A' && n <= 'F')
return n - 'A' + 10;
if (n >= 'a' && n <= 'f')
return n - 'a' + 10;
return -1;
}
static int __init bthomehubv2b_parse_hex_byte(const char *b) {
int hi;
int lo;
hi = bthomehubv2b_parse_hex_nibble(b[0]);
lo = bthomehubv2b_parse_hex_nibble(b[1]);
if (hi < 0 || lo < 0)
return -1;
return (hi << 4) | lo;
}
static int __init bthomehubv2b_register_ethernet(void) {
u_int8_t addr[6];
int i;
char *mac = "01:02:03:04:05:06";
int gotmac = 0;
char *boardid = "BTHHV2B";
int gotboardid = 0;
char *uboot_env_page;
uboot_env_page = ioremap(LTQ_FLASH_START + UBOOT_ENV_OFFSET, UBOOT_ENV_SIZE);
if (uboot_env_page)
{
char *Data = NULL;
Data = get_uboot_env_var(uboot_env_page, UBOOT_ENV_SIZE, "\0ethaddr=", 9);
if (Data)
{
mac = Data;
}
Data = get_uboot_env_var(uboot_env_page, UBOOT_ENV_SIZE, "\0boardid=", 9);
if (Data)
boardid = Data;
}
else
{
printk("bthomehubv2b: Failed to get uboot_env_page");
}
if (!mac) {
goto error_fail;
}
if (!boardid) {
goto error_fail;
}
/* Sanity check the string we're looking at */
for (i = 0; i < 5; i++) {
if (*(mac + (i * 3) + 2) != ':') {
goto error_fail;
}
}
for (i = 0; i < 6; i++) {
int byte;
byte = bthomehubv2b_parse_hex_byte(mac + (i * 3));
if (byte < 0) {
goto error_fail;
}
addr[i] = byte;
}
if (gotmac)
printk("bthomehubv2b: Found ethernet MAC address: ");
else
printk("bthomehubv2b: using default MAC (pls set ethaddr in u-boot): ");
for (i = 0; i < 6; i++)
printk("%.2x%s", addr[i], (i < 5) ? ":" : ".\n");
memcpy(&ltq_eth_data.mac.sa_data, addr, 6);
ltq_register_etop(&ltq_eth_data);
//memcpy(&bthomehubv2b_ath5k_eeprom_mac, addr, 6);
//bthomehubv2b_ath5k_eeprom_mac[5]++;
if (gotboardid)
printk("bthomehubv2b: Board id is %s.", boardid);
else
printk("bthomehubv2b: Default Board id is %s.", boardid);
if (strncmp(boardid, "BTHHV2B", 7) == 0) {
// read in dev-wifi-ath9k
//memcpy(&bthomehubv2b_ath5k_eeprom_data, sx763_eeprom_data, ATH5K_PLAT_EEP_MAX_WORDS);
}
else {
printk("bthomehubv2b: Board id is unknown, fix uboot_env data.");
}
// should not unmap while we are using the ram?
if (uboot_env_page)
iounmap(uboot_env_page);
return 0;
error_fail:
if (uboot_env_page)
iounmap(uboot_env_page);
return -EINVAL;
}
#define PORTA2_HW_PASS1 0
#define PORTA2_HW_PASS1_SC14480 1
#define PORTA2_HW_PASS2 2
int porta2_hw_revision = -1;
EXPORT_SYMBOL(porta2_hw_revision);
#define LTQ_GPIO_OUT 0x00
#define LTQ_GPIO_IN 0x04
#define LTQ_GPIO_DIR 0x08
#define LTQ_GPIO_ALTSEL0 0x0C
#define LTQ_GPIO_ALTSEL1 0x10
#define LTQ_GPIO_OD 0x14
#define LTQ_GPIO_PUDSEL 0x1C
#define LTQ_GPIO_PUDEN 0x20
#ifdef USE_BTHH_GPIO_INIT
static void bthomehubv2b_board_prom_init(void)
{
int revision = 0;
unsigned int gpio = 0;
void __iomem *mem = ioremap(LTQ_GPIO0_BASE_ADDR, LTQ_GPIO_SIZE*2);
#define DANUBE_GPIO_P0_OUT (unsigned short *)(mem + LTQ_GPIO_OUT)
#define DANUBE_GPIO_P0_IN (unsigned short *)(mem + LTQ_GPIO_IN)
#define DANUBE_GPIO_P0_DIR (unsigned short *)(mem + LTQ_GPIO_DIR)
#define DANUBE_GPIO_P0_ALTSEL0 (unsigned short *)(mem + LTQ_GPIO_ALTSEL0)
#define DANUBE_GPIO_P0_ALTSEL1 (unsigned short *)(mem + LTQ_GPIO_ALTSEL1)
#define DANUBE_GPIO_P1_OUT (unsigned short *)(mem + LTQ_GPIO_SIZE + LTQ_GPIO_OUT)
#define DANUBE_GPIO_P1_IN (unsigned short *)(mem + LTQ_GPIO_SIZE + LTQ_GPIO_IN)
#define DANUBE_GPIO_P1_DIR (unsigned short *)(mem + LTQ_GPIO_SIZE + LTQ_GPIO_DIR)
#define DANUBE_GPIO_P1_ALTSEL0 (unsigned short *)(mem + LTQ_GPIO_SIZE + LTQ_GPIO_ALTSEL0)
#define DANUBE_GPIO_P1_ALTSEL1 (unsigned short *)(mem + LTQ_GPIO_SIZE + LTQ_GPIO_ALTSEL1)
#define DANUBE_GPIO_P1_OD (unsigned short *)(mem + LTQ_GPIO_SIZE + LTQ_GPIO_OD)
printk("About to sense board using GPIOs at %8.8X\n", (unsigned int)mem);
/* First detect HW revision of the board. For that we need to set the GPIO
* lines according to table 7.2.1/7.2.2 in HSI */
*DANUBE_GPIO_P0_OUT = 0x0200;
*DANUBE_GPIO_P0_DIR = 0x2610;
*DANUBE_GPIO_P0_ALTSEL0 = 0x7812;
*DANUBE_GPIO_P0_ALTSEL1 = 0x0000;
*DANUBE_GPIO_P1_OUT = 0x7008;
*DANUBE_GPIO_P1_DIR = 0xF3AE;
*DANUBE_GPIO_P1_ALTSEL0 = 0x83A7;
*DANUBE_GPIO_P1_ALTSEL1 = 0x0400;
gpio = (*DANUBE_GPIO_P0_IN & 0xFFFF) |
((*DANUBE_GPIO_P1_IN & 0xFFFF) << 16);
revision |= (gpio & (1 << 27)) ? (1 << 0) : 0;
revision |= (gpio & (1 << 20)) ? (1 << 1) : 0;
revision |= (gpio & (1 << 8)) ? (1 << 2) : 0;
revision |= (gpio & (1 << 6)) ? (1 << 3) : 0;
revision |= (gpio & (1 << 5)) ? (1 << 4) : 0;
revision |= (gpio & (1 << 0)) ? (1 << 5) : 0;
porta2_hw_revision = revision;
printk("PORTA2: detected HW revision %d\n", revision);
/* Set GPIO lines according to HW revision. */
/* !!! Note that we are setting SPI_CS5 (GPIO 9) to be GPIO out with value
* of HIGH since the FXO does not use the SPI CS mechanism, it does it
* manually by controlling the GPIO line. We need the CS line to be disabled
* (HIGH) until needed since it will intefere with other devices on the SPI
* bus. */
*DANUBE_GPIO_P0_OUT = 0x0200;
/*
* During the manufacturing process a different machine takes over uart0
* so set it as input (so it wouldn't drive the line)
*/
#define cCONFIG_SHC_BT_MFG_TEST 0
*DANUBE_GPIO_P0_DIR = 0x2671 | (cCONFIG_SHC_BT_MFG_TEST ? 0 : (1 << 12));
if (revision == PORTA2_HW_PASS1_SC14480 || revision == PORTA2_HW_PASS2)
*DANUBE_GPIO_P0_ALTSEL0 = 0x7873;
else
*DANUBE_GPIO_P0_ALTSEL0 = 0x3873;
*DANUBE_GPIO_P0_ALTSEL1 = 0x0001;
//###################################################################################
// Register values before patch
// P1_ALTSEL0 = 0x83A7
// P1_ALTSEL1 = 0x0400
// P1_OU T = 0x7008
// P1_DIR = 0xF3AE
// P1_OD = 0xE3Fc
printk("\nApplying Patch for CPU1 IRQ Issue\n");
*DANUBE_GPIO_P1_ALTSEL0 &= ~(1<<12); // switch P1.12 (GPIO28) to GPIO functionality
*DANUBE_GPIO_P1_ALTSEL1 &= ~(1<<12); // switch P1.12 (GPIO28) to GPIO functionality
*DANUBE_GPIO_P1_OUT &= ~(1<<12); // set P1.12 (GPIO28) to 0
*DANUBE_GPIO_P1_DIR |= (1<<12); // configure P1.12 (GPIO28) as output
*DANUBE_GPIO_P1_OD |= (1<<12); // activate Push/Pull mode
udelay(100); // wait a little bit (100us)
*DANUBE_GPIO_P1_OD &= ~(1<<12); // switch back from Push/Pull to Open Drain
// important: before! setting output to 1 (3,3V) the mode must be switched
// back to Open Drain because the reset pin of the SC14488 is internally
// pulled to 1,8V
*DANUBE_GPIO_P1_OUT |= (1<<12); // set output P1.12 (GPIO28) to 1
// Register values after patch, should be the same as before
// P1_ALTSEL0 = 0x83A7
// P1_ALTSEL1 = 0x0400
// P1_OUT = 0x7008
// P1_DIR = 0xF3AE
// P1_OD = 0xE3Fc
//###################################################################################
*DANUBE_GPIO_P1_OUT = 0x7008;
*DANUBE_GPIO_P1_DIR = 0xEBAE | (revision == PORTA2_HW_PASS2 ? 0x1000 : 0);
*DANUBE_GPIO_P1_ALTSEL0 = 0x8BA7;
*DANUBE_GPIO_P1_ALTSEL1 = 0x0400;
iounmap(mem);
}
#endif
static void __init bthomehubv2b_init(void) {
#define bthomehubv2b_USB 13
// read the board version
#ifdef USE_BTHH_GPIO_INIT
bthomehubv2b_board_prom_init();
#endif
// register extra GPPOs used by LEDs as GPO 0x200+
ltq_register_gpio_stp();
ltq_add_device_gpio_leds(-1, ARRAY_SIZE(bthomehubv2b_gpio_leds), bthomehubv2b_gpio_leds);
bthhv2b_register_nor(&bthomehubv2b_flash_data);
xway_register_nand(bthomehubv2b_nand_partitions, ARRAY_SIZE(bthomehubv2b_nand_partitions));
ltq_register_pci(&ltq_pci_data);
ltq_register_tapi();
ltq_register_gpio_keys_polled(-1, LTQ_KEYS_POLL_INTERVAL, ARRAY_SIZE(bthomehubv2b_gpio_keys), bthomehubv2b_gpio_keys);
// ltq_register_ath9k();
xway_register_dwc(bthomehubv2b_USB);
bthomehubv2b_register_ethernet();
}
MIPS_MACHINE(LANTIQ_MACH_BTHOMEHUBV2BOPENRG,
"BTHOMEHUBV2BOPENRG",
"BTHOMEHUBV2B - BT Homehub V2.0 Type B with OpenRG image retained",
bthomehubv2b_init);
MIPS_MACHINE(LANTIQ_MACH_BTHOMEHUBV2B,
"BTHOMEHUBV2B",
"BTHOMEHUBV2B - BT Homehub V2.0 Type B",
bthomehubv2b_init);

View File

@ -1,57 +0,0 @@
/*
* 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.
*
* Copyright (C) 2010 John Crispin <blogic@openwrt.org>
*/
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/physmap.h>
#include <linux/input.h>
#include <lantiq.h>
#include "../machtypes.h"
#include "devices.h"
static struct mtd_partition easy50601_partitions[] = {
{
.name = "uboot",
.offset = 0x0,
.size = 0x10000,
},
{
.name = "uboot_env",
.offset = 0x10000,
.size = 0x10000,
},
{
.name = "linux",
.offset = 0x20000,
.size = 0x3d0000,
},
};
static struct physmap_flash_data easy50601_flash_data = {
.nr_parts = ARRAY_SIZE(easy50601_partitions),
.parts = easy50601_partitions,
};
static struct ltq_eth_data ltq_eth_data = {
.mii_mode = -1, /* use EPHY */
};
static void __init easy50601_init(void)
{
ltq_register_nor(&easy50601_flash_data);
ltq_register_etop(&ltq_eth_data);
}
MIPS_MACHINE(LTQ_MACH_EASY50601,
"EASY50601",
"EASY50601 Eval Board",
easy50601_init);

View File

@ -1,70 +0,0 @@
/*
* 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.
*
* Copyright (C) 2010 John Crispin <blogic@openwrt.org>
*/
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/physmap.h>
#include <linux/input.h>
#include <linux/phy.h>
#include <lantiq_soc.h>
#include <irq.h>
#include "../machtypes.h"
#include "devices.h"
static struct mtd_partition easy50712_partitions[] = {
{
.name = "uboot",
.offset = 0x0,
.size = 0x10000,
},
{
.name = "uboot_env",
.offset = 0x10000,
.size = 0x10000,
},
{
.name = "linux",
.offset = 0x20000,
.size = 0x3d0000,
},
};
static struct physmap_flash_data easy50712_flash_data = {
.nr_parts = ARRAY_SIZE(easy50712_partitions),
.parts = easy50712_partitions,
};
static struct ltq_pci_data ltq_pci_data = {
.clock = PCI_CLOCK_INT,
.gpio = PCI_GNT1 | PCI_REQ1,
.irq = {
[14] = INT_NUM_IM0_IRL0 + 22,
},
};
static struct ltq_eth_data ltq_eth_data = {
.mii_mode = PHY_INTERFACE_MODE_MII,
};
static void __init easy50712_init(void)
{
ltq_register_gpio_stp();
ltq_register_nor(&easy50712_flash_data);
ltq_register_pci(&ltq_pci_data);
ltq_register_etop(&ltq_eth_data);
ltq_register_tapi();
}
MIPS_MACHINE(LTQ_MACH_EASY50712,
"EASY50712",
"EASY50712 Eval Board",
easy50712_init);

View File

@ -1,114 +0,0 @@
/*
* 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.
*
* Copyright (C) 2010 John Crispin <blogic@openwrt.org>
*/
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/physmap.h>
#include <linux/input.h>
#include <linux/phy.h>
#include <linux/spi/spi_gpio.h>
#include <linux/spi/flash.h>
#include <lantiq_soc.h>
#include <irq.h>
#include "../machtypes.h"
#include "devices.h"
#include "dev-ifxhcd.h"
#include "dev-gpio-leds.h"
#include "dev-gpio-buttons.h"
static struct mtd_partition fritz7320_partitions[] = {
{
.name = "urlader",
.offset = 0x0,
.size = 0x20000,
},
{
.name = "linux",
.offset = 0x20000,
.size = 0xf60000,
},
{
.name = "tffs (1)",
.offset = 0xf80000,
.size = 0x40000,
},
{
.name = "tffs (2)",
.offset = 0xfc0000,
.size = 0x40000,
},
};
static struct physmap_flash_data fritz7320_flash_data = {
.nr_parts = ARRAY_SIZE(fritz7320_partitions),
.parts = fritz7320_partitions,
};
static struct gpio_led
fritz7320_gpio_leds[] __initdata = {
{ .name = "soc:green:power", .gpio = 44, .active_low = 1, .default_trigger = "default-on" },
{ .name = "soc:green:internet", .gpio = 47, .active_low = 1, .default_trigger = "default-on" },
{ .name = "soc:green:dect", .gpio = 38, .active_low = 1, .default_trigger = "default-on" },
{ .name = "soc:green:wlan", .gpio = 37, .active_low = 1, .default_trigger = "default-on" },
{ .name = "soc:green:dual1", .gpio = 35, .active_low = 1, .default_trigger = "default-on" },
{ .name = "soc:red:dual2", .gpio = 45, .active_low = 1, .default_trigger = "default-on" },
};
static struct gpio_keys_button
fritz7320_gpio_keys[] __initdata = {
{
.desc = "wifi",
.type = EV_KEY,
.code = BTN_0,
.debounce_interval = LTQ_KEYS_DEBOUNCE_INTERVAL,
.gpio = 1,
.active_low = 1,
},
{
.desc = "dect",
.type = EV_KEY,
.code = BTN_1,
.debounce_interval = LTQ_KEYS_DEBOUNCE_INTERVAL,
.gpio = 2,
.active_low = 1,
},
};
static struct ltq_pci_data ltq_pci_data = {
.clock = PCI_CLOCK_INT,
.gpio = PCI_GNT1 | PCI_REQ1,
.irq = {
[14] = INT_NUM_IM0_IRL0 + 22,
},
};
static struct ltq_eth_data ltq_eth_data = {
.mii_mode = PHY_INTERFACE_MODE_RMII,
};
static int usb_pins[2] = { 50, 51 };
static void __init fritz7320_init(void)
{
ltq_register_gpio_keys_polled(-1, LTQ_KEYS_POLL_INTERVAL,
ARRAY_SIZE(fritz7320_gpio_keys), fritz7320_gpio_keys);
ltq_add_device_gpio_leds(-1, ARRAY_SIZE(fritz7320_gpio_leds), fritz7320_gpio_leds);
ltq_register_pci(&ltq_pci_data);
ltq_register_etop(&ltq_eth_data);
ltq_register_nor(&fritz7320_flash_data);
xway_register_hcd(usb_pins);
}
MIPS_MACHINE(LANTIQ_MACH_FRITZ7320,
"FRITZ7320",
"FRITZ!BOX 7320",
fritz7320_init);

View File

@ -1,163 +0,0 @@
/*
* 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.
*
* Copyright (C) 2010 John Crispin <blogic@openwrt.org>
*/
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/physmap.h>
#include <linux/input.h>
#include <linux/phy.h>
#include <linux/spi/spi_gpio.h>
#include <linux/spi/flash.h>
#include <lantiq_soc.h>
#include <irq.h>
#include "../machtypes.h"
#include "devices.h"
#include "dev-ifxhcd.h"
#include "dev-gpio-leds.h"
#include "dev-gpio-buttons.h"
static struct mtd_partition fritz3370_partitions[] = {
{
.name = "linux",
.offset = 0x0,
.size = 0x400000,
},
{
.name = "filesystem",
.offset = 0x400000,
.size = 0x3000000,
},
{
.name = "reserved-kernel",
.offset = 0x3400000,
.size = 0x400000,
},
{
.name = "reserved",
.offset = 0x3800000,
.size = 0x3000000,
},
{
.name = "config",
.offset = 0x6800000,
.size = 0x200000,
},
{
.name = "nand-filesystem",
.offset = 0x6a00000,
.size = 0x1600000,
},
};
static struct mtd_partition spi_flash_partitions[] = {
{
.name = "urlader",
.offset = 0x0,
.size = 0x20000,
},
{
.name = "tffs",
.offset = 0x20000,
.size = 0x10000,
},
{
.name = "tffs",
.offset = 0x30000,
.size = 0x10000,
},
};
static struct gpio_led
fritz3370_gpio_leds[] __initdata = {
{ .name = "soc:green:1", .gpio = 32, .active_low = 1, .default_trigger = "default-on" },
{ .name = "soc:red:2", .gpio = 33, .active_low = 1, .default_trigger = "default-on" },
{ .name = "soc:red:3", .gpio = 34, .active_low = 1, .default_trigger = "default-on" },
{ .name = "soc:green:4", .gpio = 35, .active_low = 1, .default_trigger = "default-on" },
{ .name = "soc:green:5", .gpio = 36, .active_low = 1, .default_trigger = "default-on" },
{ .name = "soc:green:6", .gpio = 47, .active_low = 1, .default_trigger = "default-on" },
};
static struct gpio_keys_button
fritz3370_gpio_keys[] __initdata = {
{
.desc = "wifi",
.type = EV_KEY,
.code = BTN_0,
.debounce_interval = LTQ_KEYS_DEBOUNCE_INTERVAL,
.gpio = 29,
.active_low = 1,
},
};
static struct ltq_eth_data ltq_eth_data = {
.mii_mode = PHY_INTERFACE_MODE_RMII,
};
static int usb_pins[2] = { 5, 14 };
#define SPI_GPIO_MRST 16
#define SPI_GPIO_MTSR 17
#define SPI_GPIO_CLK 18
#define SPI_GPIO_CS0 10
static struct spi_gpio_platform_data spi_gpio_data = {
.sck = SPI_GPIO_CLK,
.mosi = SPI_GPIO_MTSR,
.miso = SPI_GPIO_MRST,
.num_chipselect = 2,
};
static struct platform_device spi_gpio_device = {
.name = "spi_gpio",
.dev.platform_data = &spi_gpio_data,
};
static struct flash_platform_data spi_flash_data = {
.name = "SPL",
.parts = spi_flash_partitions,
.nr_parts = ARRAY_SIZE(spi_flash_partitions),
};
static struct spi_board_info spi_flash __initdata = {
.modalias = "m25p80",
.bus_num = 0,
.chip_select = 0,
.max_speed_hz = 10 * 1000 * 1000,
.mode = SPI_MODE_3,
.chip_select = 0,
.controller_data = (void *) SPI_GPIO_CS0,
.platform_data = &spi_flash_data
};
static void __init
spi_gpio_init(void)
{
spi_register_board_info(&spi_flash, 1);
platform_device_register(&spi_gpio_device);
}
static void __init fritz3370_init(void)
{
spi_gpio_init();
platform_device_register_simple("pcie-xway", 0, NULL, 0);
xway_register_nand(fritz3370_partitions, ARRAY_SIZE(fritz3370_partitions));
xway_register_hcd(usb_pins);
ltq_add_device_gpio_leds(-1, ARRAY_SIZE(fritz3370_gpio_leds), fritz3370_gpio_leds);
ltq_register_gpio_keys_polled(-1, LTQ_KEYS_POLL_INTERVAL,
ARRAY_SIZE(fritz3370_gpio_keys), fritz3370_gpio_keys);
ltq_register_vrx200(&ltq_eth_data);
}
MIPS_MACHINE(LANTIQ_MACH_FRITZ3370,
"FRITZ3370",
"FRITZ!BOX 3370",
fritz3370_init);

View File

@ -1,166 +0,0 @@
/*
* 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.
*
* Copyright (C) 2011 Andrej Vlašić
* Copyright (C) 2011 Luka Perkov
*
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/leds.h>
#include <linux/gpio.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/physmap.h>
#include <linux/input.h>
#include <linux/ath5k_platform.h>
#include <linux/pci.h>
#include <linux/phy.h>
#include <linux/io.h>
#include <linux/if_ether.h>
#include <linux/etherdevice.h>
#include <linux/string.h>
#include <irq.h>
#include <lantiq_soc.h>
#include <lantiq_platform.h>
#include <dev-gpio-leds.h>
#include <dev-gpio-buttons.h>
#include "../machtypes.h"
#include "dev-wifi-athxk.h"
#include "devices.h"
#include "dev-dwc_otg.h"
#include "mach-gigasx76x.h"
static u8 ltq_ethaddr[6] = { 0 };
static int __init setup_ethaddr(char *str)
{
if (!mac_pton(str, ltq_ethaddr))
memset(ltq_ethaddr, 0, 6);
return 0;
}
__setup("ethaddr=", setup_ethaddr);
enum {
UNKNOWN = 0,
SX761,
SX762,
SX763,
};
static u8 board = SX763;
static int __init setup_board(char *str)
{
if (!strcmp(str, "sx761"))
board = SX761;
else if (!strcmp(str, "sx762"))
board = SX762;
else if (!strcmp(str, "sx763"))
board = SX763;
else
board = UNKNOWN;
return 0;
}
__setup("board=", setup_board);
static struct mtd_partition gigasx76x_partitions[] =
{
{
.name = "uboot",
.offset = 0x0,
.size = 0x10000,
},
{
.name = "uboot_env",
.offset = 0x10000,
.size = 0x10000,
},
{
.name = "linux",
.offset = 0x20000,
.size = 0x7e0000,
},
};
static struct gpio_led
gigasx76x_gpio_leds[] __initdata = {
{ .name = "soc:green:voip", .gpio = 216, },
{ .name = "soc:green:adsl", .gpio = 217, },
{ .name = "soc:green:usb", .gpio = 218, },
{ .name = "soc:green:wifi", .gpio = 219, },
{ .name = "soc:green:phone2", .gpio = 220, },
{ .name = "soc:green:phone1", .gpio = 221, },
{ .name = "soc:green:line", .gpio = 222, },
{ .name = "soc:green:online", .gpio = 223, },
};
static struct gpio_keys_button
gigasx76x_gpio_keys[] __initdata = {
{
.desc = "wps",
.type = EV_KEY,
.code = KEY_WPS_BUTTON,
.debounce_interval = LTQ_KEYS_DEBOUNCE_INTERVAL,
.gpio = 22,
.active_low = 1,
},
{
.desc = "reset",
.type = EV_KEY,
.code = BTN_0,
.debounce_interval = LTQ_KEYS_DEBOUNCE_INTERVAL,
.gpio = 14,
.active_low = 0,
},
};
static struct physmap_flash_data gigasx76x_flash_data = {
.nr_parts = ARRAY_SIZE(gigasx76x_partitions),
.parts = gigasx76x_partitions,
};
static struct ltq_pci_data ltq_pci_data = {
.clock = PCI_CLOCK_INT,
.gpio = PCI_GNT1 | PCI_REQ1,
.irq = { [14] = INT_NUM_IM0_IRL0 + 22, },
};
static struct ltq_eth_data ltq_eth_data = {
.mii_mode = PHY_INTERFACE_MODE_MII,
};
static void __init gigasx76x_init(void)
{
#define GIGASX76X_USB 29
ltq_register_gpio_stp();
ltq_register_nor(&gigasx76x_flash_data);
ltq_register_pci(&ltq_pci_data);
ltq_register_tapi();
ltq_add_device_gpio_leds(-1, ARRAY_SIZE(gigasx76x_gpio_leds), gigasx76x_gpio_leds);
ltq_register_gpio_keys_polled(-1, LTQ_KEYS_POLL_INTERVAL, ARRAY_SIZE(gigasx76x_gpio_keys), gigasx76x_gpio_keys);
xway_register_dwc(GIGASX76X_USB);
if (!is_valid_ether_addr(ltq_ethaddr))
random_ether_addr(ltq_ethaddr);
memcpy(&ltq_eth_data.mac.sa_data, ltq_ethaddr, 6);
ltq_register_etop(&ltq_eth_data);
if (board == SX762)
ltq_register_ath5k(sx762_eeprom_data, ltq_ethaddr);
else
ltq_register_ath5k(sx763_eeprom_data, ltq_ethaddr);
}
MIPS_MACHINE(LANTIQ_MACH_GIGASX76X,
"GIGASX76X",
"GIGASX76X - Gigaset SX761,SX762,SX763",
gigasx76x_init);

View File

@ -1,208 +0,0 @@
/*
* 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.
*
* Copyright (C) 2011 Andrej Vlašić
* Copyright (C) 2011 Luka Perkov
*
*/
#ifndef _MACH_GIGASX76X_H__
#define _MACH_GIGASX76X_H__
static u16 sx763_eeprom_data[ATH5K_PLAT_EEP_MAX_WORDS]=
{
0x0013,0x168c,0x0200,0x0001,0x0000,0x5001,0x0000,0x2051,0x2051,0x1c0a,0x0100,
0x0000,0x01c2,0x0002,0xc606,0x0001,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf165,0x7fbe,0x0003,0x0000,
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x5aa5,0x0000,0x0000,0x0313,0x4943,
0x2053,0x7104,0x1202,0x0400,0x0306,0x0001,0x0000,0x0500,0x410e,0x39b1,0x1eb5,
0x4e2d,0x3056,0xffff,0xe902,0x0700,0x0106,0x0000,0x0100,0x1500,0x0752,0x4101,
0x6874,0x7265,0x736f,0x4320,0x6d6f,0x756d,0x696e,0x6163,0x6974,0x6e6f,0x2c73,
0x4920,0x636e,0x002e,0x5241,0x3035,0x3130,0x302d,0x3030,0x2d30,0x3030,0x3030,
0x5700,0x7269,0x6c65,0x7365,0x2073,0x414c,0x204e,0x6552,0x6566,0x6572,0x636e,
0x2065,0x6143,0x6472,0x3000,0x0030,0x00ff,0x2100,0x0602,0x2201,0x0205,0x8d80,
0x005b,0x0522,0x4002,0x8954,0x2200,0x0205,0x1b00,0x00b7,0x0522,0x8002,0x12a8,
0x2201,0x0205,0x3600,0x016e,0x0522,0x0002,0x2551,0x2202,0x0205,0x6c00,0x02dc,
0x0522,0x8002,0x37f9,0x2203,0x0205,0xa200,0x044a,0x0222,0x0803,0x0822,0x0604,
0x0300,0xbe7f,0x65f1,0x0222,0x0105,0x00ff,0x0000,0x0000,0x0000,0x0000,0x0000,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0x0037,0x971f,0x5003,0x9a66,0x0001,0x81c4,0x016a,
0x02ff,0x84ff,0x15a3,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,0x2d2c,0x0000,0x0000,0x0000,0x0000,0xe028,0xa492,0x1c00,
0x000e,0xb8ca,0x0013,0x0000,0x0000,0x6b4b,0xc059,0x1571,0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
0x2370,0x00a5,0x9618,0x419a,0x68a2,0xda35,0x001c,0x0007,0xb0ff,0x01b5,0x0000,
0x0000,0xff70,0x19ff,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,0x0000,0x0000,0x3170,0x00a5,0x9618,0x419a,0x68a2,0xda35,
0x001c,0x000e,0xb0ff,0x21b5,0x0000,0x2fd8,0xff70,0x1226,0x19ff,0x07be,0x6201,
0x032e,0x0587,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1112,
0x1441,0x4231,0x3234,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,0x0000,0x8000,0x0000,0x0000,0x0000,0x0000,0x8000,0x0000,
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4d31,0x7f54,0x3c93,0x1205,0x1931,
0x492d,0x7f50,0x3c93,0x0e01,0x192d,0x0070,0x0000,0x8140,0x724b,0x2ba9,0x3a09,
0x99d9,0x1949,0x0070,0x0000,0x80e0,0x624a,0x2af8,0x35c7,0x9d47,0x1938,0x0000,
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,0x0000,0x7082,0x0820,0xb882,0x0820,0x7092,0x28a0,0x8992,
0x28a0,0xa292,0x28a0,0x70a2,0xa7ac,0x0000,0x0000,0x2464,0x6424,0x0000,0x0000,
0x70a2,0xa7ac,0x0000,0x0000,0x2464,0x6424,0x0000,0x0000,0x8989,0x0000,0x0000,
0x0000,0x2424,0x0000,0x0000,0x0000,0x7075,0xa2ac,0xb800,0x0000,0x2464,0x2424,
0x2400,0x0000,0x7075,0xa2ac,0x0000,0x0000,0x2464,0x2424,0x0000,0x0000,0x7075,
0xa7ac,0x0000,0x0000,0x2464,0x6424,0x0000,0x0000,0x7075,0xa7ac,0x0000,0x0000,
0x2464,0x6424,0x0000,0x0000,0x8989,0x0000,0x0000,0x0000,0x2424,0x0000,0x0000,
0x0000,0x0000,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff};
static u16 sx762_eeprom_data[ATH5K_PLAT_EEP_MAX_WORDS]=
{
0x001a,0x168c,0x0200,0x0001,0x0000,0x5001,0x0000,0x2051,0x2051,0x1c0a,0x0100,
0x0000,0x01c2,0x0002,0xc606,0x0001,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf165,0x7fbe,0x0003,0x0000,
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x5aa5,0x0000,0x0000,0x0313,0x4943,
0x2053,0x7104,0x1202,0x0400,0x0306,0x0001,0x0000,0x0500,0x410e,0x39b1,0x1eb5,
0x4e2d,0x3056,0xffff,0xe902,0x0700,0x0106,0x0000,0x0100,0x1500,0x0752,0x4101,
0x6874,0x7265,0x736f,0x4320,0x6d6f,0x756d,0x696e,0x6163,0x6974,0x6e6f,0x2c73,
0x4920,0x636e,0x002e,0x5241,0x3035,0x3130,0x302d,0x3030,0x2d30,0x3030,0x3030,
0x5700,0x7269,0x6c65,0x7365,0x2073,0x414c,0x204e,0x6552,0x6566,0x6572,0x636e,
0x2065,0x6143,0x6472,0x3000,0x0030,0x00ff,0x2100,0x0602,0x2201,0x0205,0x8d80,
0x005b,0x0522,0x4002,0x8954,0x2200,0x0205,0x1b00,0x00b7,0x0522,0x8002,0x12a8,
0x2201,0x0205,0x3600,0x016e,0x0522,0x0002,0x2551,0x2202,0x0205,0x6c00,0x02dc,
0x0522,0x8002,0x37f9,0x2203,0x0205,0xa200,0x044a,0x0222,0x0803,0x0822,0x0604,
0x0300,0xbe7f,0x65f1,0x0222,0x0105,0x00ff,0x0000,0x0000,0x0000,0x0000,0x0000,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0x0037,0x6aaa,0x5003,0x9a66,0x0001,0x81c4,0x016a,
0x02ff,0x84ff,0x15a3,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,0x2d2c,0x0000,0x0000,0x0000,0x0000,0xe028,0xa492,0x1c00,
0x000e,0xb8ca,0x0013,0x0000,0x0000,0x6b4b,0xc059,0x1571,0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
0x2370,0x00a5,0x9618,0x419a,0x68a2,0xda35,0x001c,0x0007,0xb0ff,0x01b5,0x0000,
0x0000,0xff70,0x19ff,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,0x0000,0x0000,0x3170,0x00a5,0x9618,0x419a,0x68a2,0xda35,
0x001c,0x000e,0xb0ff,0x21b5,0x0000,0x2fd8,0xff70,0x1226,0x19ff,0x07fa,0x6201,
0x032e,0x0587,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1112,
0x1441,0x4231,0x3234,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,0x0000,0x8000,0x0000,0x0000,0x0000,0x0000,0x8000,0x0000,
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4d31,0x7f54,0x3c93,0x1205,0x1931,
0x492d,0x7f50,0x3c93,0x0e01,0x192d,0x0070,0x0000,0x8180,0x724d,0xab59,0x3a08,
0xdd79,0x2559,0x0070,0x0000,0x81a0,0x6e4d,0x2b99,0x3a09,0x9989,0x2157,0x0000,
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,0x0000,0x7092,0x4924,0xb892,0x4924,0x7092,0x289e,0x8992,
0x289e,0xa292,0x289e,0x70a2,0xa7ac,0x0000,0x0000,0x2462,0x5e13,0x0000,0x0000,
0x70a2,0xa7ac,0x0000,0x0000,0x1e5c,0x5713,0x0000,0x0000,0x8989,0x0000,0x0000,
0x0000,0x2424,0x0000,0x0000,0x0000,0x7075,0xa2ac,0xb800,0x0000,0x2868,0x2828,
0x2800,0x0000,0x7075,0xa2ac,0x0000,0x0000,0x2868,0x2828,0x0000,0x0000,0x7075,
0xac00,0x0000,0x0000,0x2161,0x2100,0x0000,0x0000,0x7075,0xac00,0x0000,0x0000,
0x1b5b,0x1b00,0x0000,0x0000,0x8989,0x0000,0x0000,0x0000,0x2121,0x0000,0x0000,
0x0000,0x0000,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff};
#endif

View File

@ -1,88 +0,0 @@
/*
* 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.
*
* Copyright (C) 2010 John Crispin <blogic@openwrt.org>
*/
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/physmap.h>
#include <linux/input.h>
#include <linux/phy.h>
#include <linux/spi/spi.h>
#include <linux/spi/flash.h>
#include <lantiq_soc.h>
#include <irq.h>
#include "../machtypes.h"
#include "devices.h"
#include "dev-dwc_otg.h"
static struct ltq_pci_data ltq_pci_data = {
.clock = PCI_CLOCK_INT,
.gpio = PCI_GNT1 | PCI_REQ1,
.irq = {
[14] = INT_NUM_IM0_IRL0 + 22,
},
};
static struct ltq_eth_data ltq_eth_data = {
.mii_mode = PHY_INTERFACE_MODE_MII,
};
static struct mtd_partition easy98000_nor_partitions[] =
{
{
.name = "uboot",
.offset = 0x0,
.size = 0x40000,
},
{
.name = "uboot_env",
.offset = 0x40000,
.size = 0x40000, /* 2 sectors for redundant env. */
},
{
.name = "linux",
.offset = 0x80000,
.size = 0xF80000, /* map only 16 MiB */
},
};
static struct flash_platform_data easy98000_spi_flash_platform_data = {
.name = "sflash",
.parts = easy98000_nor_partitions,
.nr_parts = ARRAY_SIZE(easy98000_nor_partitions)
};
static struct spi_board_info spi_info __initdata = {
.modalias = "m25p80",
.bus_num = 0,
.chip_select = 3,
.max_speed_hz = 10 * 1000 * 1000,
.mode = SPI_MODE_3,
.platform_data = &easy98000_spi_flash_platform_data
};
struct ltq_spi_platform_data ltq_spi_data = {
.num_chipselect = 4,
};
static void __init dgn3500_init(void)
{
ltq_register_pci(&ltq_pci_data);
ltq_register_etop(&ltq_eth_data);
ltq_register_spi(&ltq_spi_data, &spi_info, 1);
/* The usb power is always enabled, protected by a fuse */
xway_register_dwc(-1);
}
MIPS_MACHINE(LANTIQ_MACH_DGN3500B,
"DGN3500B",
"Netgear DGN3500B",
dgn3500_init);

View File

@ -1,106 +0,0 @@
/*
* 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.
*
* Copyright (C) 2010 John Crispin <blogic@openwrt.org>
*/
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/leds.h>
#include <linux/gpio.h>
#include <linux/gpio_buttons.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/physmap.h>
#include <linux/input.h>
#include <linux/etherdevice.h>
#include <linux/mdio-gpio.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <lantiq_soc.h>
#include <lantiq_platform.h>
#include "../machtypes.h"
#include "devices.h"
#include "../dev-gpio-leds.h"
#include "dev-dwc_otg.h"
static struct mtd_partition p2601hnf1_partitions[] __initdata =
{
{
.name = "uboot",
.offset = 0x0,
.size = 0x20000,
},
/* {
.name = "uboot_env",
.offset = 0x20000,
.size = 0x20000,
},
*/ {
.name = "linux",
.offset = 0x020000,
.size = 0xfc0000,
},
{
.name = "board_config",
.offset = 0xfe0000,
.size = 0x20000,
},
};
static struct physmap_flash_data p2601hnf1_flash_data __initdata = {
.nr_parts = ARRAY_SIZE(p2601hnf1_partitions),
.parts = p2601hnf1_partitions,
};
static struct gpio_led p2601hnf1_leds_gpio[] __initdata = {
{ .name = "soc:red:power", .gpio = 29, .active_low = 1, .default_trigger = "default-off" },
{ .name = "soc:yellow:phone", .gpio = 64, .active_low = 1, .default_trigger = "default-off" },
{ .name = "soc:green:phone", .gpio = 65, .active_low = 1, .default_trigger = "default-off" },
{ .name = "soc:yellow:wlan", .gpio = 66, .active_low = 1, .default_trigger = "default-off" },
{ .name = "soc:green:power", .gpio = 67, .active_low = 1, .default_trigger = "default-on" },
{ .name = "soc:red:internet", .gpio = 68, .active_low = 1, .default_trigger = "default-off" },
{ .name = "soc:green:internet", .gpio = 69, .active_low = 1, .default_trigger = "default-off" },
{ .name = "soc:green:dsl", .gpio = 70, .active_low = 1, .default_trigger = "default-off" },
{ .name = "soc:green:wlan", .gpio = 71, .active_low = 1, .default_trigger = "default-off" },
};
static struct gpio_button
p2601hnf1_gpio_buttons[] /*__initdata*/ = {
{ .desc = "reset", .type = EV_KEY, .code = BTN_0, .threshold = 3, .gpio = 53, .active_low = 1, },
{ .desc = "wlan", .type = EV_KEY, .code = BTN_1, .threshold = 1, .gpio = 54, .active_low = 1, },
};
static struct ltq_eth_data ltq_eth_data = {
.mii_mode = PHY_INTERFACE_MODE_RMII,
};
static void __init
p2601hnf1_init(void)
{
#define P2601HNF1_USB 9
ltq_register_gpio_stp();
ltq_add_device_gpio_leds(-1, ARRAY_SIZE(p2601hnf1_leds_gpio), p2601hnf1_leds_gpio);
ltq_register_gpio_buttons(p2601hnf1_gpio_buttons, ARRAY_SIZE(p2601hnf1_gpio_buttons));
ltq_register_nor(&p2601hnf1_flash_data);
ltq_register_etop(&ltq_eth_data);
xway_register_dwc(P2601HNF1_USB);
// enable the ethernet ports on the SoC
// ltq_w32((ltq_r32(LTQ_GPORT_P0_CTL) & ~(1 << 17)) | (1 << 18), LTQ_GPORT_P0_CTL);
// ltq_w32((ltq_r32(LTQ_GPORT_P1_CTL) & ~(1 << 17)) | (1 << 18), LTQ_GPORT_P1_CTL);
// ltq_w32((ltq_r32(LTQ_GPORT_P2_CTL) & ~(1 << 17)) | (1 << 18), LTQ_GPORT_P2_CTL);
}
MIPS_MACHINE(LANTIQ_MACH_P2601HNF1,
"P2601HNF1",
"ZyXEL P-2601HN-F1",
p2601hnf1_init);

View File

@ -1,120 +0,0 @@
/*
* 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.
*
* Copyright (C) 2010 John Crispin <blogic@openwrt.org>
*/
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/leds.h>
#include <linux/gpio.h>
#include <linux/gpio_buttons.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/physmap.h>
#include <linux/input.h>
#include <lantiq_soc.h>
#include <irq.h>
#include <dev-gpio-leds.h>
#include <dev-gpio-buttons.h>
#include "../machtypes.h"
#include "devices.h"
#include "dev-dwc_otg.h"
static struct mtd_partition wbmr_partitions[] =
{
{
.name = "uboot",
.offset = 0x0,
.size = 0x40000,
},
{
.name = "uboot-env",
.offset = 0x40000,
.size = 0x20000,
},
{
.name = "linux",
.offset = 0x60000,
.size = 0x1f20000,
},
{
.name = "calibration",
.offset = 0x1fe0000,
.size = 0x20000,
},
};
static struct physmap_flash_data wbmr_flash_data = {
.nr_parts = ARRAY_SIZE(wbmr_partitions),
.parts = wbmr_partitions,
};
static struct gpio_led
wbmr_gpio_leds[] __initdata = {
{ .name = "soc:blue:movie", .gpio = 20, .active_low = 1, },
{ .name = "soc:red:internet", .gpio = 18, .active_low = 1, },
{ .name = "soc:green:internet", .gpio = 17, .active_low = 1, },
{ .name = "soc:green:adsl", .gpio = 16, .active_low = 1, },
{ .name = "soc:green:wlan", .gpio = 15, .active_low = 1, },
{ .name = "soc:red:security", .gpio = 14, .active_low = 1, },
{ .name = "soc:green:power", .gpio = 1, .active_low = 1, },
{ .name = "soc:red:power", .gpio = 5, .active_low = 1, },
{ .name = "soc:green:usb", .gpio = 28, .active_low = 1, },
};
static struct gpio_keys_button
wbmr_gpio_keys[] __initdata = {
{
.desc = "aoss",
.type = EV_KEY,
.code = BTN_0,
.debounce_interval = LTQ_KEYS_DEBOUNCE_INTERVAL,
.gpio = 0,
.active_low = 1,
},
{
.desc = "reset",
.type = EV_KEY,
.code = BTN_1,
.debounce_interval = LTQ_KEYS_DEBOUNCE_INTERVAL,
.gpio = 37,
.active_low = 1,
},
};
static struct ltq_pci_data ltq_pci_data = {
.clock = PCI_CLOCK_INT,
.gpio = PCI_GNT1 | PCI_REQ1,
.irq = {
[14] = INT_NUM_IM0_IRL0 + 22,
},
};
static struct ltq_eth_data ltq_eth_data = {
.mii_mode = PHY_INTERFACE_MODE_RGMII,
};
static void __init
wbmr_init(void)
{
#define WMBR_BRN_MAC 0x1fd0024
ltq_add_device_gpio_leds(-1, ARRAY_SIZE(wbmr_gpio_leds), wbmr_gpio_leds);
ltq_register_gpio_keys_polled(-1, LTQ_KEYS_POLL_INTERVAL, ARRAY_SIZE(wbmr_gpio_keys), wbmr_gpio_keys);
ltq_register_nor(&wbmr_flash_data);
ltq_register_pci(&ltq_pci_data);
memcpy_fromio(&ltq_eth_data.mac.sa_data,
(void *)KSEG1ADDR(LTQ_FLASH_START + WMBR_BRN_MAC), 6);
ltq_register_etop(&ltq_eth_data);
xway_register_dwc(36);
}
MIPS_MACHINE(LANTIQ_MACH_WBMR,
"WBMR",
"WBMR",
wbmr_init);

View File

@ -1,109 +0,0 @@
/*
* Atheros AP94 reference board PCI initialization
*
* Copyright (C) 2009-2010 Gabor Juhos <juhosg@openwrt.org>
*
* 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/pci.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <lantiq_soc.h>
#define LTQ_PCI_MEM_BASE 0x18000000
struct ath_fixup {
u16 *cal_data;
unsigned slot;
};
static int ath_num_fixups;
static struct ath_fixup ath_fixups[2];
static void ath_pci_fixup(struct pci_dev *dev)
{
void __iomem *mem;
u16 *cal_data = NULL;
u16 cmd;
u32 bar0;
u32 val;
unsigned i;
for (i = 0; i < ath_num_fixups; i++) {
if (ath_fixups[i].cal_data == NULL)
continue;
if (ath_fixups[i].slot != PCI_SLOT(dev->devfn))
continue;
cal_data = ath_fixups[i].cal_data;
break;
}
if (cal_data == NULL)
return;
if (*cal_data != 0xa55a) {
pr_err("pci %s: invalid calibration data\n", pci_name(dev));
return;
}
pr_info("pci %s: fixup device configuration\n", pci_name(dev));
mem = ioremap(LTQ_PCI_MEM_BASE, 0x10000);
if (!mem) {
pr_err("pci %s: ioremap error\n", pci_name(dev));
return;
}
pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &bar0);
pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, LTQ_PCI_MEM_BASE);
pci_read_config_word(dev, PCI_COMMAND, &cmd);
cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
pci_write_config_word(dev, PCI_COMMAND, cmd);
/* set pointer to first reg address */
cal_data += 3;
while (*cal_data != 0xffff) {
u32 reg;
reg = *cal_data++;
val = *cal_data++;
val |= (*cal_data++) << 16;
ltq_w32(swab32(val), mem + reg);
udelay(100);
}
pci_read_config_dword(dev, PCI_VENDOR_ID, &val);
dev->vendor = val & 0xffff;
dev->device = (val >> 16) & 0xffff;
pci_read_config_dword(dev, PCI_CLASS_REVISION, &val);
dev->revision = val & 0xff;
dev->class = val >> 8; /* upper 3 bytes */
pr_info("pci %s: fixup info: [%04x:%04x] revision %02x class %#08x\n",
pci_name(dev), dev->vendor, dev->device, dev->revision, dev->class);
pci_read_config_word(dev, PCI_COMMAND, &cmd);
cmd &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
pci_write_config_word(dev, PCI_COMMAND, cmd);
pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, bar0);
iounmap(mem);
}
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATHEROS, PCI_ANY_ID, ath_pci_fixup);
void __init ltq_pci_ath_fixup(unsigned slot, u16 *cal_data)
{
if (ath_num_fixups >= ARRAY_SIZE(ath_fixups))
return;
ath_fixups[ath_num_fixups].slot = slot;
ath_fixups[ath_num_fixups].cal_data = cal_data;
ath_num_fixups++;
}

View File

@ -1,6 +0,0 @@
#ifndef _PCI_ATH_FIXUP
#define _PCI_ATH_FIXUP
void ltq_pci_ath_fixup(unsigned slot, u16 *cal_data) __init;
#endif /* _PCI_ATH_FIXUP */

View File

@ -1,134 +0,0 @@
From 8817c547f92016b9276ffec88b708c2c16d1f0f1 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Thu, 8 Mar 2012 13:23:53 +0100
Subject: [PATCH 01/73] GPIO: add bindings for managed devices
This patch adds 2 functions that allow managed devices to request GPIOs.
These GPIOs will then be managed by drivers/base/devres.c.
Signed-off-by: John Crispin <blogic@openwrt.org>
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---
drivers/gpio/Makefile | 2 +-
drivers/gpio/devres.c | 90 ++++++++++++++++++++++++++++++++++++++++++++
include/asm-generic/gpio.h | 4 ++
3 files changed, 95 insertions(+), 1 deletions(-)
create mode 100644 drivers/gpio/devres.c
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -2,7 +2,7 @@
ccflags-$(CONFIG_DEBUG_GPIO) += -DDEBUG
-obj-$(CONFIG_GPIOLIB) += gpiolib.o
+obj-$(CONFIG_GPIOLIB) += gpiolib.o devres.o
# Device drivers. Generally keep list sorted alphabetically
obj-$(CONFIG_GPIO_GENERIC) += gpio-generic.o
--- /dev/null
+++ b/drivers/gpio/devres.c
@@ -0,0 +1,90 @@
+/*
+ * drivers/gpio/devres.c - managed gpio resources
+ *
+ * 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.
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * This file is based on kernel/irq/devres.c
+ *
+ * Copyright (c) 2011 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/module.h>
+#include <linux/gpio.h>
+#include <linux/device.h>
+#include <linux/gfp.h>
+
+static void devm_gpio_release(struct device *dev, void *res)
+{
+ unsigned *gpio = res;
+
+ gpio_free(*gpio);
+}
+
+static int devm_gpio_match(struct device *dev, void *res, void *data)
+{
+ unsigned *this = res, *gpio = data;
+
+ return *this == *gpio;
+}
+
+/**
+ * devm_gpio_request - request a gpio for a managed device
+ * @dev: device to request the gpio for
+ * @gpio: gpio to allocate
+ * @label: the name of the requested gpio
+ *
+ * Except for the extra @dev argument, this function takes the
+ * same arguments and performs the same function as
+ * gpio_request(). GPIOs requested with this function will be
+ * automatically freed on driver detach.
+ *
+ * If an GPIO allocated with this function needs to be freed
+ * separately, devm_gpio_free() must be used.
+ */
+
+int devm_gpio_request(struct device *dev, unsigned gpio, const char *label)
+{
+ unsigned *dr;
+ int rc;
+
+ dr = devres_alloc(devm_gpio_release, sizeof(unsigned), GFP_KERNEL);
+ if (!dr)
+ return -ENOMEM;
+
+ rc = gpio_request(gpio, label);
+ if (rc) {
+ devres_free(dr);
+ return rc;
+ }
+
+ *dr = gpio;
+ devres_add(dev, dr);
+
+ return 0;
+}
+EXPORT_SYMBOL(devm_gpio_request);
+
+/**
+ * devm_gpio_free - free an interrupt
+ * @dev: device to free gpio for
+ * @gpio: gpio to free
+ *
+ * Except for the extra @dev argument, this function takes the
+ * same arguments and performs the same function as gpio_free().
+ * This function instead of gpio_free() should be used to manually
+ * free GPIOs allocated with devm_gpio_request().
+ */
+void devm_gpio_free(struct device *dev, unsigned int gpio)
+{
+
+ WARN_ON(devres_destroy(dev, devm_gpio_release, devm_gpio_match,
+ &gpio));
+ gpio_free(gpio);
+}
+EXPORT_SYMBOL(devm_gpio_free);
--- a/include/asm-generic/gpio.h
+++ b/include/asm-generic/gpio.h
@@ -175,6 +175,10 @@ extern int gpio_request_one(unsigned gpi
extern int gpio_request_array(const struct gpio *array, size_t num);
extern void gpio_free_array(const struct gpio *array, size_t num);
+/* bindings for managed devices that want to request gpios */
+int devm_gpio_request(struct device *dev, unsigned gpio, const char *label);
+void devm_gpio_free(struct device *dev, unsigned int gpio);
+
#ifdef CONFIG_GPIO_SYSFS
/*

View File

@ -1,20 +0,0 @@
From 770d7934edcc0b4125cd1ef1ad102ae2c2e02bca Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Fri, 16 Mar 2012 16:27:35 +0100
Subject: [PATCH 02/73] MIPS: remove unused prototype kgdb_config
---
arch/mips/include/asm/mips-boards/generic.h | 4 ----
1 files changed, 0 insertions(+), 4 deletions(-)
--- a/arch/mips/include/asm/mips-boards/generic.h
+++ b/arch/mips/include/asm/mips-boards/generic.h
@@ -93,8 +93,4 @@ extern void mips_pcibios_init(void);
#define mips_pcibios_init() do { } while (0)
#endif
-#ifdef CONFIG_KGDB
-extern void kgdb_config(void);
-#endif
-
#endif /* __ASM_MIPS_BOARDS_GENERIC_H */

View File

@ -1,19 +0,0 @@
From 3778c58845f39b145b80ca357ca22a3095a8dfb1 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Tue, 13 Mar 2012 18:03:33 +0100
Subject: [PATCH 04/73] MTD: add m25p80 id for mx25l2005a
---
drivers/mtd/devices/m25p80.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -684,6 +684,7 @@ static const struct spi_device_id m25p_i
{ "640s33b", INFO(0x898913, 0, 64 * 1024, 128, 0) },
/* Macronix */
+ { "mx25l2005a", INFO(0xc22012, 0, 64 * 1024, 8, SECT_4K) },
{ "mx25l4005a", INFO(0xc22013, 0, 64 * 1024, 8, SECT_4K) },
{ "mx25l8005", INFO(0xc22014, 0, 64 * 1024, 16, 0) },
{ "mx25l1606e", INFO(0xc22015, 0, 64 * 1024, 32, SECT_4K) },

View File

@ -1,835 +0,0 @@
From 222ee25fab35b3c3a4c63903b6af4eb0d0556750 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Wed, 10 Aug 2011 14:57:04 +0200
Subject: [PATCH 05/73] MIPS: lantiq: reorganize xway code
Inside the folder arch/mips/lantiq/xway, there were alot of small files with
lots of duplicated code. This patch adds a wrapper function for inserting and
requesting resources and unifies the small files into one bigger file.
This patch makes the xway code consistent with the falcon support added later
in this series.
Signed-off-by: John Crispin <blogic@openwrt.org>
---
arch/mips/include/asm/mach-lantiq/lantiq.h | 14 +---
.../mips/include/asm/mach-lantiq/xway/lantiq_soc.h | 14 ++++
arch/mips/lantiq/clk.c | 25 +------
arch/mips/lantiq/devices.c | 30 ++------
arch/mips/lantiq/devices.h | 4 +
arch/mips/lantiq/prom.c | 51 +++++++++++--
arch/mips/lantiq/prom.h | 4 +
arch/mips/lantiq/xway/Makefile | 6 +-
arch/mips/lantiq/xway/devices.c | 42 ++---------
arch/mips/lantiq/xway/dma.c | 21 +----
arch/mips/lantiq/xway/ebu.c | 52 -------------
arch/mips/lantiq/xway/pmu.c | 69 -----------------
arch/mips/lantiq/xway/prom-ase.c | 9 ++
arch/mips/lantiq/xway/prom-xway.c | 10 +++
arch/mips/lantiq/xway/reset.c | 21 +----
arch/mips/lantiq/xway/setup-ase.c | 19 -----
arch/mips/lantiq/xway/setup-xway.c | 20 -----
arch/mips/lantiq/xway/sysctrl.c | 78 ++++++++++++++++++++
drivers/watchdog/lantiq_wdt.c | 2 +-
19 files changed, 199 insertions(+), 292 deletions(-)
delete mode 100644 arch/mips/lantiq/xway/ebu.c
delete mode 100644 arch/mips/lantiq/xway/pmu.c
delete mode 100644 arch/mips/lantiq/xway/setup-ase.c
delete mode 100644 arch/mips/lantiq/xway/setup-xway.c
create mode 100644 arch/mips/lantiq/xway/sysctrl.c
--- a/arch/mips/include/asm/mach-lantiq/lantiq.h
+++ b/arch/mips/include/asm/mach-lantiq/lantiq.h
@@ -9,6 +9,7 @@
#define _LANTIQ_H__
#include <linux/irq.h>
+#include <linux/ioport.h>
/* generic reg access functions */
#define ltq_r32(reg) __raw_readl(reg)
@@ -18,15 +19,6 @@
#define ltq_r8(reg) __raw_readb(reg)
#define ltq_w8(val, reg) __raw_writeb(val, reg)
-/* register access macros for EBU and CGU */
-#define ltq_ebu_w32(x, y) ltq_w32((x), ltq_ebu_membase + (y))
-#define ltq_ebu_r32(x) ltq_r32(ltq_ebu_membase + (x))
-#define ltq_cgu_w32(x, y) ltq_w32((x), ltq_cgu_membase + (y))
-#define ltq_cgu_r32(x) ltq_r32(ltq_cgu_membase + (x))
-
-extern __iomem void *ltq_ebu_membase;
-extern __iomem void *ltq_cgu_membase;
-
extern unsigned int ltq_get_cpu_ver(void);
extern unsigned int ltq_get_soc_type(void);
@@ -51,7 +43,9 @@ extern void ltq_enable_irq(struct irq_da
/* find out what caused the last cpu reset */
extern int ltq_reset_cause(void);
-#define LTQ_RST_CAUSE_WDTRST 0x20
+
+/* helper for requesting and remapping resources */
+extern void __iomem *ltq_remap_resource(struct resource *res);
#define IOPORT_RESOURCE_START 0x10000000
#define IOPORT_RESOURCE_END 0xffffffff
--- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
+++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
@@ -61,6 +61,8 @@
#define LTQ_CGU_BASE_ADDR 0x1F103000
#define LTQ_CGU_SIZE 0x1000
+#define CGU_EPHY 0x10
+
/* ICU - interrupt control unit */
#define LTQ_ICU_BASE_ADDR 0x1F880200
#define LTQ_ICU_SIZE 0x100
@@ -97,6 +99,8 @@
#define LTQ_WDT_BASE_ADDR 0x1F8803F0
#define LTQ_WDT_SIZE 0x10
+#define LTQ_RST_CAUSE_WDTRST 0x20
+
/* STP - serial to parallel conversion unit */
#define LTQ_STP_BASE_ADDR 0x1E100BB0
#define LTQ_STP_SIZE 0x40
@@ -121,11 +125,21 @@
#define LTQ_MPS_BASE_ADDR (KSEG1 + 0x1F107000)
#define LTQ_MPS_CHIPID ((u32 *)(LTQ_MPS_BASE_ADDR + 0x0344))
+/* register access macros for EBU and CGU */
+#define ltq_ebu_w32(x, y) ltq_w32((x), ltq_ebu_membase + (y))
+#define ltq_ebu_r32(x) ltq_r32(ltq_ebu_membase + (x))
+#define ltq_cgu_w32(x, y) ltq_w32((x), ltq_cgu_membase + (y))
+#define ltq_cgu_r32(x) ltq_r32(ltq_cgu_membase + (x))
+
+extern __iomem void *ltq_ebu_membase;
+extern __iomem void *ltq_cgu_membase;
+
/* request a non-gpio and set the PIO config */
extern int ltq_gpio_request(unsigned int pin, unsigned int alt0,
unsigned int alt1, unsigned int dir, const char *name);
extern void ltq_pmu_enable(unsigned int module);
extern void ltq_pmu_disable(unsigned int module);
+extern void ltq_cgu_enable(unsigned int clk);
static inline int ltq_is_ar9(void)
{
--- a/arch/mips/lantiq/clk.c
+++ b/arch/mips/lantiq/clk.c
@@ -22,6 +22,7 @@
#include <lantiq_soc.h>
#include "clk.h"
+#include "prom.h"
struct clk {
const char *name;
@@ -46,16 +47,6 @@ static struct clk cpu_clk_generic[] = {
},
};
-static struct resource ltq_cgu_resource = {
- .name = "cgu",
- .start = LTQ_CGU_BASE_ADDR,
- .end = LTQ_CGU_BASE_ADDR + LTQ_CGU_SIZE - 1,
- .flags = IORESOURCE_MEM,
-};
-
-/* remapped clock register range */
-void __iomem *ltq_cgu_membase;
-
void clk_init(void)
{
cpu_clk = cpu_clk_generic;
@@ -133,21 +124,11 @@ void __init plat_time_init(void)
{
struct clk *clk;
- if (insert_resource(&iomem_resource, &ltq_cgu_resource) < 0)
- panic("Failed to insert cgu memory\n");
+ ltq_soc_init();
- if (request_mem_region(ltq_cgu_resource.start,
- resource_size(&ltq_cgu_resource), "cgu") < 0)
- panic("Failed to request cgu memory\n");
-
- ltq_cgu_membase = ioremap_nocache(ltq_cgu_resource.start,
- resource_size(&ltq_cgu_resource));
- if (!ltq_cgu_membase) {
- pr_err("Failed to remap cgu memory\n");
- unreachable();
- }
clk = clk_get(0, "cpu");
mips_hpt_frequency = clk_get_rate(clk) / ltq_get_counter_resolution();
write_c0_compare(read_c0_count());
+ pr_info("CPU Clock: %ldMHz\n", clk_get_rate(clk) / 1000000);
clk_put(clk);
}
--- a/arch/mips/lantiq/devices.c
+++ b/arch/mips/lantiq/devices.c
@@ -27,12 +27,8 @@
#include "devices.h"
/* nor flash */
-static struct resource ltq_nor_resource = {
- .name = "nor",
- .start = LTQ_FLASH_START,
- .end = LTQ_FLASH_START + LTQ_FLASH_MAX - 1,
- .flags = IORESOURCE_MEM,
-};
+static struct resource ltq_nor_resource =
+ MEM_RES("nor", LTQ_FLASH_START, LTQ_FLASH_MAX);
static struct platform_device ltq_nor = {
.name = "ltq_nor",
@@ -47,12 +43,8 @@ void __init ltq_register_nor(struct phys
}
/* watchdog */
-static struct resource ltq_wdt_resource = {
- .name = "watchdog",
- .start = LTQ_WDT_BASE_ADDR,
- .end = LTQ_WDT_BASE_ADDR + LTQ_WDT_SIZE - 1,
- .flags = IORESOURCE_MEM,
-};
+static struct resource ltq_wdt_resource =
+ MEM_RES("watchdog", LTQ_WDT_BASE_ADDR, LTQ_WDT_SIZE);
void __init ltq_register_wdt(void)
{
@@ -61,24 +53,14 @@ void __init ltq_register_wdt(void)
/* asc ports */
static struct resource ltq_asc0_resources[] = {
- {
- .name = "asc0",
- .start = LTQ_ASC0_BASE_ADDR,
- .end = LTQ_ASC0_BASE_ADDR + LTQ_ASC_SIZE - 1,
- .flags = IORESOURCE_MEM,
- },
+ MEM_RES("asc0", LTQ_ASC0_BASE_ADDR, LTQ_ASC_SIZE),
IRQ_RES(tx, LTQ_ASC_TIR(0)),
IRQ_RES(rx, LTQ_ASC_RIR(0)),
IRQ_RES(err, LTQ_ASC_EIR(0)),
};
static struct resource ltq_asc1_resources[] = {
- {
- .name = "asc1",
- .start = LTQ_ASC1_BASE_ADDR,
- .end = LTQ_ASC1_BASE_ADDR + LTQ_ASC_SIZE - 1,
- .flags = IORESOURCE_MEM,
- },
+ MEM_RES("asc1", LTQ_ASC1_BASE_ADDR, LTQ_ASC_SIZE),
IRQ_RES(tx, LTQ_ASC_TIR(1)),
IRQ_RES(rx, LTQ_ASC_RIR(1)),
IRQ_RES(err, LTQ_ASC_EIR(1)),
--- a/arch/mips/lantiq/devices.h
+++ b/arch/mips/lantiq/devices.h
@@ -14,6 +14,10 @@
#define IRQ_RES(resname, irq) \
{.name = #resname, .start = (irq), .flags = IORESOURCE_IRQ}
+#define MEM_RES(resname, adr_start, adr_size) \
+ { .name = resname, .flags = IORESOURCE_MEM, \
+ .start = ((adr_start) & ~KSEG1), \
+ .end = ((adr_start + adr_size - 1) & ~KSEG1) }
extern void ltq_register_nor(struct physmap_flash_data *data);
extern void ltq_register_wdt(void);
--- a/arch/mips/lantiq/prom.c
+++ b/arch/mips/lantiq/prom.c
@@ -16,6 +16,10 @@
#include "prom.h"
#include "clk.h"
+/* access to the ebu needs to be locked between different drivers */
+DEFINE_SPINLOCK(ebu_lock);
+EXPORT_SYMBOL_GPL(ebu_lock);
+
static struct ltq_soc_info soc_info;
unsigned int ltq_get_cpu_ver(void)
@@ -55,16 +59,51 @@ static void __init prom_init_cmdline(voi
}
}
-void __init prom_init(void)
+void __iomem *ltq_remap_resource(struct resource *res)
{
- struct clk *clk;
+ __iomem void *ret = NULL;
+ struct resource *lookup = lookup_resource(&iomem_resource, res->start);
+ if (lookup && strcmp(lookup->name, res->name)) {
+ pr_err("conflicting memory range %s\n", res->name);
+ return NULL;
+ }
+ if (!lookup) {
+ if (insert_resource(&iomem_resource, res) < 0) {
+ pr_err("Failed to insert %s memory\n", res->name);
+ return NULL;
+ }
+ }
+ if (request_mem_region(res->start,
+ resource_size(res), res->name) < 0) {
+ pr_err("Failed to request %s memory\n", res->name);
+ goto err_res;
+ }
+
+ ret = ioremap_nocache(res->start, resource_size(res));
+ if (!ret)
+ goto err_mem;
+
+ pr_debug("remap: 0x%08X-0x%08X : \"%s\"\n",
+ res->start, res->end, res->name);
+ return ret;
+
+err_mem:
+ panic("Failed to remap %s memory\n", res->name);
+ release_mem_region(res->start, resource_size(res));
+
+err_res:
+ release_resource(res);
+ return NULL;
+}
+EXPORT_SYMBOL(ltq_remap_resource);
+
+void __init prom_init(void)
+{
ltq_soc_detect(&soc_info);
clk_init();
- clk = clk_get(0, "cpu");
- snprintf(soc_info.sys_type, LTQ_SYS_TYPE_LEN - 1, "%s rev1.%d",
- soc_info.name, soc_info.rev);
- clk_put(clk);
+ snprintf(soc_info.sys_type, LTQ_SYS_TYPE_LEN - 1, "%s rev %s",
+ soc_info.name, soc_info.rev_type);
soc_info.sys_type[LTQ_SYS_TYPE_LEN - 1] = '\0';
pr_info("SoC: %s\n", soc_info.sys_type);
prom_init_cmdline();
--- a/arch/mips/lantiq/prom.h
+++ b/arch/mips/lantiq/prom.h
@@ -9,17 +9,21 @@
#ifndef _LTQ_PROM_H__
#define _LTQ_PROM_H__
+#define LTQ_SYS_REV_LEN 0x10
#define LTQ_SYS_TYPE_LEN 0x100
struct ltq_soc_info {
unsigned char *name;
unsigned int rev;
+ unsigned char rev_type[LTQ_SYS_REV_LEN];
+ unsigned int srev;
unsigned int partnum;
unsigned int type;
unsigned char sys_type[LTQ_SYS_TYPE_LEN];
};
extern void ltq_soc_detect(struct ltq_soc_info *i);
+extern void ltq_soc_init(void);
extern void ltq_soc_setup(void);
#endif
--- a/arch/mips/lantiq/xway/Makefile
+++ b/arch/mips/lantiq/xway/Makefile
@@ -1,7 +1,7 @@
-obj-y := pmu.o ebu.o reset.o gpio.o gpio_stp.o gpio_ebu.o devices.o dma.o
+obj-y := sysctrl.o reset.o gpio.o gpio_stp.o gpio_ebu.o devices.o dma.o
-obj-$(CONFIG_SOC_XWAY) += clk-xway.o prom-xway.o setup-xway.o
-obj-$(CONFIG_SOC_AMAZON_SE) += clk-ase.o prom-ase.o setup-ase.o
+obj-$(CONFIG_SOC_XWAY) += clk-xway.o prom-xway.o
+obj-$(CONFIG_SOC_AMAZON_SE) += clk-ase.o prom-ase.o
obj-$(CONFIG_LANTIQ_MACH_EASY50712) += mach-easy50712.o
obj-$(CONFIG_LANTIQ_MACH_EASY50601) += mach-easy50601.o
--- a/arch/mips/lantiq/xway/devices.c
+++ b/arch/mips/lantiq/xway/devices.c
@@ -31,22 +31,9 @@
/* gpio */
static struct resource ltq_gpio_resource[] = {
- {
- .name = "gpio0",
- .start = LTQ_GPIO0_BASE_ADDR,
- .end = LTQ_GPIO0_BASE_ADDR + LTQ_GPIO_SIZE - 1,
- .flags = IORESOURCE_MEM,
- }, {
- .name = "gpio1",
- .start = LTQ_GPIO1_BASE_ADDR,
- .end = LTQ_GPIO1_BASE_ADDR + LTQ_GPIO_SIZE - 1,
- .flags = IORESOURCE_MEM,
- }, {
- .name = "gpio2",
- .start = LTQ_GPIO2_BASE_ADDR,
- .end = LTQ_GPIO2_BASE_ADDR + LTQ_GPIO_SIZE - 1,
- .flags = IORESOURCE_MEM,
- }
+ MEM_RES("gpio0", LTQ_GPIO0_BASE_ADDR, LTQ_GPIO_SIZE),
+ MEM_RES("gpio1", LTQ_GPIO1_BASE_ADDR, LTQ_GPIO_SIZE),
+ MEM_RES("gpio2", LTQ_GPIO2_BASE_ADDR, LTQ_GPIO_SIZE),
};
void __init ltq_register_gpio(void)
@@ -64,12 +51,8 @@ void __init ltq_register_gpio(void)
}
/* serial to parallel conversion */
-static struct resource ltq_stp_resource = {
- .name = "stp",
- .start = LTQ_STP_BASE_ADDR,
- .end = LTQ_STP_BASE_ADDR + LTQ_STP_SIZE - 1,
- .flags = IORESOURCE_MEM,
-};
+static struct resource ltq_stp_resource =
+ MEM_RES("stp", LTQ_STP_BASE_ADDR, LTQ_STP_SIZE);
void __init ltq_register_gpio_stp(void)
{
@@ -78,12 +61,7 @@ void __init ltq_register_gpio_stp(void)
/* asc ports - amazon se has its own serial mapping */
static struct resource ltq_ase_asc_resources[] = {
- {
- .name = "asc0",
- .start = LTQ_ASC1_BASE_ADDR,
- .end = LTQ_ASC1_BASE_ADDR + LTQ_ASC_SIZE - 1,
- .flags = IORESOURCE_MEM,
- },
+ MEM_RES("asc0", LTQ_ASC1_BASE_ADDR, LTQ_ASC_SIZE),
IRQ_RES(tx, LTQ_ASC_ASE_TIR),
IRQ_RES(rx, LTQ_ASC_ASE_RIR),
IRQ_RES(err, LTQ_ASC_ASE_EIR),
@@ -96,12 +74,8 @@ void __init ltq_register_ase_asc(void)
}
/* ethernet */
-static struct resource ltq_etop_resources = {
- .name = "etop",
- .start = LTQ_ETOP_BASE_ADDR,
- .end = LTQ_ETOP_BASE_ADDR + LTQ_ETOP_SIZE - 1,
- .flags = IORESOURCE_MEM,
-};
+static struct resource ltq_etop_resources =
+ MEM_RES("etop", LTQ_ETOP_BASE_ADDR, LTQ_ETOP_SIZE);
static struct platform_device ltq_etop = {
.name = "ltq_etop",
--- a/arch/mips/lantiq/xway/dma.c
+++ b/arch/mips/lantiq/xway/dma.c
@@ -24,6 +24,8 @@
#include <lantiq_soc.h>
#include <xway_dma.h>
+#include "../devices.h"
+
#define LTQ_DMA_CTRL 0x10
#define LTQ_DMA_CPOLL 0x14
#define LTQ_DMA_CS 0x18
@@ -55,12 +57,8 @@
#define ltq_dma_w32_mask(x, y, z) ltq_w32_mask(x, y, \
ltq_dma_membase + (z))
-static struct resource ltq_dma_resource = {
- .name = "dma",
- .start = LTQ_DMA_BASE_ADDR,
- .end = LTQ_DMA_BASE_ADDR + LTQ_DMA_SIZE - 1,
- .flags = IORESOURCE_MEM,
-};
+static struct resource ltq_dma_resource =
+ MEM_RES("dma", LTQ_DMA_BASE_ADDR, LTQ_DMA_SIZE);
static void __iomem *ltq_dma_membase;
@@ -220,17 +218,8 @@ ltq_dma_init(void)
{
int i;
- /* insert and request the memory region */
- if (insert_resource(&iomem_resource, &ltq_dma_resource) < 0)
- panic("Failed to insert dma memory\n");
-
- if (request_mem_region(ltq_dma_resource.start,
- resource_size(&ltq_dma_resource), "dma") < 0)
- panic("Failed to request dma memory\n");
-
/* remap dma register range */
- ltq_dma_membase = ioremap_nocache(ltq_dma_resource.start,
- resource_size(&ltq_dma_resource));
+ ltq_dma_membase = ltq_remap_resource(&ltq_dma_resource);
if (!ltq_dma_membase)
panic("Failed to remap dma memory\n");
--- a/arch/mips/lantiq/xway/ebu.c
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * 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.
- *
- * EBU - the external bus unit attaches PCI, NOR and NAND
- *
- * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/ioport.h>
-
-#include <lantiq_soc.h>
-
-/* all access to the ebu must be locked */
-DEFINE_SPINLOCK(ebu_lock);
-EXPORT_SYMBOL_GPL(ebu_lock);
-
-static struct resource ltq_ebu_resource = {
- .name = "ebu",
- .start = LTQ_EBU_BASE_ADDR,
- .end = LTQ_EBU_BASE_ADDR + LTQ_EBU_SIZE - 1,
- .flags = IORESOURCE_MEM,
-};
-
-/* remapped base addr of the clock unit and external bus unit */
-void __iomem *ltq_ebu_membase;
-
-static int __init lantiq_ebu_init(void)
-{
- /* insert and request the memory region */
- if (insert_resource(&iomem_resource, &ltq_ebu_resource) < 0)
- panic("Failed to insert ebu memory\n");
-
- if (request_mem_region(ltq_ebu_resource.start,
- resource_size(&ltq_ebu_resource), "ebu") < 0)
- panic("Failed to request ebu memory\n");
-
- /* remap ebu register range */
- ltq_ebu_membase = ioremap_nocache(ltq_ebu_resource.start,
- resource_size(&ltq_ebu_resource));
- if (!ltq_ebu_membase)
- panic("Failed to remap ebu memory\n");
-
- /* make sure to unprotect the memory region where flash is located */
- ltq_ebu_w32(ltq_ebu_r32(LTQ_EBU_BUSCON0) & ~EBU_WRDIS, LTQ_EBU_BUSCON0);
- return 0;
-}
-
-postcore_initcall(lantiq_ebu_init);
--- a/arch/mips/lantiq/xway/pmu.c
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * 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.
- *
- * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/ioport.h>
-
-#include <lantiq_soc.h>
-
-/* PMU - the power management unit allows us to turn part of the core
- * on and off
- */
-
-/* the enable / disable registers */
-#define LTQ_PMU_PWDCR 0x1C
-#define LTQ_PMU_PWDSR 0x20
-
-#define ltq_pmu_w32(x, y) ltq_w32((x), ltq_pmu_membase + (y))
-#define ltq_pmu_r32(x) ltq_r32(ltq_pmu_membase + (x))
-
-static struct resource ltq_pmu_resource = {
- .name = "pmu",
- .start = LTQ_PMU_BASE_ADDR,
- .end = LTQ_PMU_BASE_ADDR + LTQ_PMU_SIZE - 1,
- .flags = IORESOURCE_MEM,
-};
-
-static void __iomem *ltq_pmu_membase;
-
-void ltq_pmu_enable(unsigned int module)
-{
- int err = 1000000;
-
- ltq_pmu_w32(ltq_pmu_r32(LTQ_PMU_PWDCR) & ~module, LTQ_PMU_PWDCR);
- do {} while (--err && (ltq_pmu_r32(LTQ_PMU_PWDSR) & module));
-
- if (!err)
- panic("activating PMU module failed!\n");
-}
-EXPORT_SYMBOL(ltq_pmu_enable);
-
-void ltq_pmu_disable(unsigned int module)
-{
- ltq_pmu_w32(ltq_pmu_r32(LTQ_PMU_PWDCR) | module, LTQ_PMU_PWDCR);
-}
-EXPORT_SYMBOL(ltq_pmu_disable);
-
-int __init ltq_pmu_init(void)
-{
- if (insert_resource(&iomem_resource, &ltq_pmu_resource) < 0)
- panic("Failed to insert pmu memory\n");
-
- if (request_mem_region(ltq_pmu_resource.start,
- resource_size(&ltq_pmu_resource), "pmu") < 0)
- panic("Failed to request pmu memory\n");
-
- ltq_pmu_membase = ioremap_nocache(ltq_pmu_resource.start,
- resource_size(&ltq_pmu_resource));
- if (!ltq_pmu_membase)
- panic("Failed to remap pmu memory\n");
- return 0;
-}
-
-core_initcall(ltq_pmu_init);
--- a/arch/mips/lantiq/xway/prom-ase.c
+++ b/arch/mips/lantiq/xway/prom-ase.c
@@ -13,6 +13,7 @@
#include <lantiq_soc.h>
+#include "devices.h"
#include "../prom.h"
#define SOC_AMAZON_SE "Amazon_SE"
@@ -26,6 +27,7 @@ void __init ltq_soc_detect(struct ltq_so
{
i->partnum = (ltq_r32(LTQ_MPS_CHIPID) & PART_MASK) >> PART_SHIFT;
i->rev = (ltq_r32(LTQ_MPS_CHIPID) & REV_MASK) >> REV_SHIFT;
+ sprintf(i->rev_type, "1.%d", i->rev);
switch (i->partnum) {
case SOC_ID_AMAZON_SE:
i->name = SOC_AMAZON_SE;
@@ -37,3 +39,10 @@ void __init ltq_soc_detect(struct ltq_so
break;
}
}
+
+void __init ltq_soc_setup(void)
+{
+ ltq_register_ase_asc();
+ ltq_register_gpio();
+ ltq_register_wdt();
+}
--- a/arch/mips/lantiq/xway/prom-xway.c
+++ b/arch/mips/lantiq/xway/prom-xway.c
@@ -13,6 +13,7 @@
#include <lantiq_soc.h>
+#include "devices.h"
#include "../prom.h"
#define SOC_DANUBE "Danube"
@@ -28,6 +29,7 @@ void __init ltq_soc_detect(struct ltq_so
{
i->partnum = (ltq_r32(LTQ_MPS_CHIPID) & PART_MASK) >> PART_SHIFT;
i->rev = (ltq_r32(LTQ_MPS_CHIPID) & REV_MASK) >> REV_SHIFT;
+ sprintf(i->rev_type, "1.%d", i->rev);
switch (i->partnum) {
case SOC_ID_DANUBE1:
case SOC_ID_DANUBE2:
@@ -52,3 +54,11 @@ void __init ltq_soc_detect(struct ltq_so
break;
}
}
+
+void __init ltq_soc_setup(void)
+{
+ ltq_register_asc(0);
+ ltq_register_asc(1);
+ ltq_register_gpio();
+ ltq_register_wdt();
+}
--- a/arch/mips/lantiq/xway/reset.c
+++ b/arch/mips/lantiq/xway/reset.c
@@ -15,6 +15,8 @@
#include <lantiq_soc.h>
+#include "../devices.h"
+
#define ltq_rcu_w32(x, y) ltq_w32((x), ltq_rcu_membase + (y))
#define ltq_rcu_r32(x) ltq_r32(ltq_rcu_membase + (x))
@@ -25,12 +27,8 @@
#define LTQ_RCU_RST_STAT 0x0014
#define LTQ_RCU_STAT_SHIFT 26
-static struct resource ltq_rcu_resource = {
- .name = "rcu",
- .start = LTQ_RCU_BASE_ADDR,
- .end = LTQ_RCU_BASE_ADDR + LTQ_RCU_SIZE - 1,
- .flags = IORESOURCE_MEM,
-};
+static struct resource ltq_rcu_resource =
+ MEM_RES("rcu", LTQ_RCU_BASE_ADDR, LTQ_RCU_SIZE);
/* remapped base addr of the reset control unit */
static void __iomem *ltq_rcu_membase;
@@ -67,17 +65,8 @@ static void ltq_machine_power_off(void)
static int __init mips_reboot_setup(void)
{
- /* insert and request the memory region */
- if (insert_resource(&iomem_resource, &ltq_rcu_resource) < 0)
- panic("Failed to insert rcu memory\n");
-
- if (request_mem_region(ltq_rcu_resource.start,
- resource_size(&ltq_rcu_resource), "rcu") < 0)
- panic("Failed to request rcu memory\n");
-
/* remap rcu register range */
- ltq_rcu_membase = ioremap_nocache(ltq_rcu_resource.start,
- resource_size(&ltq_rcu_resource));
+ ltq_rcu_membase = ltq_remap_resource(&ltq_rcu_resource);
if (!ltq_rcu_membase)
panic("Failed to remap rcu memory\n");
--- a/arch/mips/lantiq/xway/setup-ase.c
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * 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.
- *
- * Copyright (C) 2011 John Crispin <blogic@openwrt.org>
- */
-
-#include <lantiq_soc.h>
-
-#include "../prom.h"
-#include "devices.h"
-
-void __init ltq_soc_setup(void)
-{
- ltq_register_ase_asc();
- ltq_register_gpio();
- ltq_register_wdt();
-}
--- a/arch/mips/lantiq/xway/setup-xway.c
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * 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.
- *
- * Copyright (C) 2011 John Crispin <blogic@openwrt.org>
- */
-
-#include <lantiq_soc.h>
-
-#include "../prom.h"
-#include "devices.h"
-
-void __init ltq_soc_setup(void)
-{
- ltq_register_asc(0);
- ltq_register_asc(1);
- ltq_register_gpio();
- ltq_register_wdt();
-}
--- /dev/null
+++ b/arch/mips/lantiq/xway/sysctrl.c
@@ -0,0 +1,78 @@
+/*
+ * 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.
+ *
+ * Copyright (C) 2011 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/ioport.h>
+#include <linux/export.h>
+
+#include <lantiq_soc.h>
+
+#include "../devices.h"
+
+/* clock control register */
+#define LTQ_CGU_IFCCR 0x0018
+
+/* the enable / disable registers */
+#define LTQ_PMU_PWDCR 0x1C
+#define LTQ_PMU_PWDSR 0x20
+
+#define ltq_pmu_w32(x, y) ltq_w32((x), ltq_pmu_membase + (y))
+#define ltq_pmu_r32(x) ltq_r32(ltq_pmu_membase + (x))
+
+static struct resource ltq_cgu_resource =
+ MEM_RES("cgu", LTQ_CGU_BASE_ADDR, LTQ_CGU_SIZE);
+
+static struct resource ltq_pmu_resource =
+ MEM_RES("pmu", LTQ_PMU_BASE_ADDR, LTQ_PMU_SIZE);
+
+static struct resource ltq_ebu_resource =
+ MEM_RES("ebu", LTQ_EBU_BASE_ADDR, LTQ_EBU_SIZE);
+
+void __iomem *ltq_cgu_membase;
+void __iomem *ltq_ebu_membase;
+static void __iomem *ltq_pmu_membase;
+
+void ltq_cgu_enable(unsigned int clk)
+{
+ ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) | clk, LTQ_CGU_IFCCR);
+}
+
+void ltq_pmu_enable(unsigned int module)
+{
+ int err = 1000000;
+
+ ltq_pmu_w32(ltq_pmu_r32(LTQ_PMU_PWDCR) & ~module, LTQ_PMU_PWDCR);
+ do {} while (--err && (ltq_pmu_r32(LTQ_PMU_PWDSR) & module));
+
+ if (!err)
+ panic("activating PMU module failed!\n");
+}
+EXPORT_SYMBOL(ltq_pmu_enable);
+
+void ltq_pmu_disable(unsigned int module)
+{
+ ltq_pmu_w32(ltq_pmu_r32(LTQ_PMU_PWDCR) | module, LTQ_PMU_PWDCR);
+}
+EXPORT_SYMBOL(ltq_pmu_disable);
+
+void __init ltq_soc_init(void)
+{
+ ltq_pmu_membase = ltq_remap_resource(&ltq_pmu_resource);
+ if (!ltq_pmu_membase)
+ panic("Failed to remap pmu memory\n");
+
+ ltq_cgu_membase = ltq_remap_resource(&ltq_cgu_resource);
+ if (!ltq_cgu_membase)
+ panic("Failed to remap cgu memory\n");
+
+ ltq_ebu_membase = ltq_remap_resource(&ltq_ebu_resource);
+ if (!ltq_ebu_membase)
+ panic("Failed to remap ebu memory\n");
+
+ /* make sure to unprotect the memory region where flash is located */
+ ltq_ebu_w32(ltq_ebu_r32(LTQ_EBU_BUSCON0) & ~EBU_WRDIS, LTQ_EBU_BUSCON0);
+}
--- a/drivers/watchdog/lantiq_wdt.c
+++ b/drivers/watchdog/lantiq_wdt.c
@@ -16,7 +16,7 @@
#include <linux/clk.h>
#include <linux/io.h>
-#include <lantiq.h>
+#include <lantiq_soc.h>
/* Section 3.4 of the datasheet
* The password sequence protects the WDT control register from unintended

View File

@ -1,138 +0,0 @@
From 2daf93364658fd26bf583b7a46b81c08fddaf1e4 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Fri, 11 Nov 2011 12:45:24 +0100
Subject: [PATCH 06/73] MIPS: lantiq: change ltq_request_gpio() call signature
ltq_request_gpio() was using alt0/1 to multiplex the function of GPIO pins.
This was XWAY specific. In order to also accomodate SoCs that require more bits
we use a 32bit mask instead. This way the call signature is consistent between
XWAY and FALC-ON.
Signed-off-by: John Crispin <blogic@openwrt.org>
Signed-off-by: Thomas Langer <thomas.langer@lantiq.com>
---
.../mips/include/asm/mach-lantiq/xway/lantiq_soc.h | 4 +-
arch/mips/lantiq/xway/gpio.c | 8 ++--
arch/mips/lantiq/xway/gpio_stp.c | 6 ++--
arch/mips/pci/pci-lantiq.c | 36 +++++++++----------
4 files changed, 26 insertions(+), 28 deletions(-)
--- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
+++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
@@ -135,8 +135,8 @@ extern __iomem void *ltq_ebu_membase;
extern __iomem void *ltq_cgu_membase;
/* request a non-gpio and set the PIO config */
-extern int ltq_gpio_request(unsigned int pin, unsigned int alt0,
- unsigned int alt1, unsigned int dir, const char *name);
+extern int ltq_gpio_request(unsigned int pin, unsigned int mux,
+ unsigned int dir, const char *name);
extern void ltq_pmu_enable(unsigned int module);
extern void ltq_pmu_disable(unsigned int module);
extern void ltq_cgu_enable(unsigned int clk);
--- a/arch/mips/lantiq/xway/gpio.c
+++ b/arch/mips/lantiq/xway/gpio.c
@@ -48,8 +48,8 @@ int irq_to_gpio(unsigned int gpio)
}
EXPORT_SYMBOL(irq_to_gpio);
-int ltq_gpio_request(unsigned int pin, unsigned int alt0,
- unsigned int alt1, unsigned int dir, const char *name)
+int ltq_gpio_request(unsigned int pin, unsigned int mux,
+ unsigned int dir, const char *name)
{
int id = 0;
@@ -67,13 +67,13 @@ int ltq_gpio_request(unsigned int pin, u
pin -= PINS_PER_PORT;
id++;
}
- if (alt0)
+ if (mux & 0x2)
ltq_gpio_setbit(ltq_gpio_port[id].membase,
LTQ_GPIO_ALTSEL0, pin);
else
ltq_gpio_clearbit(ltq_gpio_port[id].membase,
LTQ_GPIO_ALTSEL0, pin);
- if (alt1)
+ if (mux & 0x1)
ltq_gpio_setbit(ltq_gpio_port[id].membase,
LTQ_GPIO_ALTSEL1, pin);
else
--- a/arch/mips/lantiq/xway/gpio_stp.c
+++ b/arch/mips/lantiq/xway/gpio_stp.c
@@ -79,9 +79,9 @@ static struct gpio_chip ltq_stp_chip = {
static int ltq_stp_hw_init(void)
{
/* the 3 pins used to control the external stp */
- ltq_gpio_request(4, 1, 0, 1, "stp-st");
- ltq_gpio_request(5, 1, 0, 1, "stp-d");
- ltq_gpio_request(6, 1, 0, 1, "stp-sh");
+ ltq_gpio_request(4, 2, 1, "stp-st");
+ ltq_gpio_request(5, 2, 1, "stp-d");
+ ltq_gpio_request(6, 2, 1, "stp-sh");
/* sane defaults */
ltq_stp_w32(0, LTQ_STP_AR);
--- a/arch/mips/pci/pci-lantiq.c
+++ b/arch/mips/pci/pci-lantiq.c
@@ -70,28 +70,27 @@
struct ltq_pci_gpio_map {
int pin;
- int alt0;
- int alt1;
+ int mux;
int dir;
char *name;
};
/* the pci core can make use of the following gpios */
static struct ltq_pci_gpio_map ltq_pci_gpio_map[] = {
- { 0, 1, 0, 0, "pci-exin0" },
- { 1, 1, 0, 0, "pci-exin1" },
- { 2, 1, 0, 0, "pci-exin2" },
- { 39, 1, 0, 0, "pci-exin3" },
- { 10, 1, 0, 0, "pci-exin4" },
- { 9, 1, 0, 0, "pci-exin5" },
- { 30, 1, 0, 1, "pci-gnt1" },
- { 23, 1, 0, 1, "pci-gnt2" },
- { 19, 1, 0, 1, "pci-gnt3" },
- { 38, 1, 0, 1, "pci-gnt4" },
- { 29, 1, 0, 0, "pci-req1" },
- { 31, 1, 0, 0, "pci-req2" },
- { 3, 1, 0, 0, "pci-req3" },
- { 37, 1, 0, 0, "pci-req4" },
+ { 0, 2, 0, "pci-exin0" },
+ { 1, 2, 0, "pci-exin1" },
+ { 2, 2, 0, "pci-exin2" },
+ { 39, 2, 0, "pci-exin3" },
+ { 10, 2, 0, "pci-exin4" },
+ { 9, 2, 0, "pci-exin5" },
+ { 30, 2, 1, "pci-gnt1" },
+ { 23, 2, 1, "pci-gnt2" },
+ { 19, 2, 1, "pci-gnt3" },
+ { 38, 2, 1, "pci-gnt4" },
+ { 29, 2, 0, "pci-req1" },
+ { 31, 2, 0, "pci-req2" },
+ { 3, 2, 0, "pci-req3" },
+ { 37, 2, 0, "pci-req4" },
};
__iomem void *ltq_pci_mapped_cfg;
@@ -157,13 +156,12 @@ static void ltq_pci_setup_gpio(int gpio)
for (i = 0; i < ARRAY_SIZE(ltq_pci_gpio_map); i++) {
if (gpio & (1 << i)) {
ltq_gpio_request(ltq_pci_gpio_map[i].pin,
- ltq_pci_gpio_map[i].alt0,
- ltq_pci_gpio_map[i].alt1,
+ ltq_pci_gpio_map[i].mux,
ltq_pci_gpio_map[i].dir,
ltq_pci_gpio_map[i].name);
}
}
- ltq_gpio_request(21, 0, 0, 1, "pci-reset");
+ ltq_gpio_request(21, 0, 1, "pci-reset");
ltq_pci_req_mask = (gpio >> PCI_REQ_SHIFT) & PCI_REQ_MASK;
}

View File

@ -1,69 +0,0 @@
From 318b9c6242418e1568430c7768371d2bd556109a Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Thu, 11 Aug 2011 12:25:55 +0200
Subject: [PATCH 07/73] MIPS: lantiq: make irq.c support the FALC-ON
There are minor differences in how irqs work on xway and falcon socs.
Xway needs 2 quirks that we need to disable for falcon to also work with
this code.
* EBU irq does not need to send a special ack to the EBU
* The EIU does not exist
Signed-off-by: Thomas Langer <thomas.langer@lantiq.com>
Signed-off-by: John Crispin <blogic@openwrt.org>
---
arch/mips/lantiq/irq.c | 24 +++++++++++++-----------
1 files changed, 13 insertions(+), 11 deletions(-)
--- a/arch/mips/lantiq/irq.c
+++ b/arch/mips/lantiq/irq.c
@@ -195,7 +195,7 @@ static void ltq_hw_irqdispatch(int modul
do_IRQ((int)irq + INT_NUM_IM0_IRL0 + (INT_NUM_IM_OFFSET * module));
/* if this is a EBU irq, we need to ack it or get a deadlock */
- if ((irq == LTQ_ICU_EBU_IRQ) && (module == 0))
+ if ((irq == LTQ_ICU_EBU_IRQ) && (module == 0) && LTQ_EBU_PCC_ISTAT)
ltq_ebu_w32(ltq_ebu_r32(LTQ_EBU_PCC_ISTAT) | 0x10,
LTQ_EBU_PCC_ISTAT);
}
@@ -260,17 +260,19 @@ void __init arch_init_irq(void)
if (!ltq_icu_membase)
panic("Failed to remap icu memory\n");
- if (insert_resource(&iomem_resource, &ltq_eiu_resource) < 0)
- panic("Failed to insert eiu memory\n");
+ if (LTQ_EIU_BASE_ADDR) {
+ if (insert_resource(&iomem_resource, &ltq_eiu_resource) < 0)
+ panic("Failed to insert eiu memory\n");
+
+ if (request_mem_region(ltq_eiu_resource.start,
+ resource_size(&ltq_eiu_resource), "eiu") < 0)
+ panic("Failed to request eiu memory\n");
- if (request_mem_region(ltq_eiu_resource.start,
- resource_size(&ltq_eiu_resource), "eiu") < 0)
- panic("Failed to request eiu memory\n");
-
- ltq_eiu_membase = ioremap_nocache(ltq_eiu_resource.start,
+ ltq_eiu_membase = ioremap_nocache(ltq_eiu_resource.start,
resource_size(&ltq_eiu_resource));
- if (!ltq_eiu_membase)
- panic("Failed to remap eiu memory\n");
+ if (!ltq_eiu_membase)
+ panic("Failed to remap eiu memory\n");
+ }
/* make sure all irqs are turned off by default */
for (i = 0; i < 5; i++)
@@ -296,8 +298,8 @@ void __init arch_init_irq(void)
for (i = INT_NUM_IRQ0;
i <= (INT_NUM_IRQ0 + (5 * INT_NUM_IM_OFFSET)); i++)
- if ((i == LTQ_EIU_IR0) || (i == LTQ_EIU_IR1) ||
- (i == LTQ_EIU_IR2))
+ if (((i == LTQ_EIU_IR0) || (i == LTQ_EIU_IR1) ||
+ (i == LTQ_EIU_IR2)) && LTQ_EIU_BASE_ADDR)
irq_set_chip_and_handler(i, &ltq_eiu_type,
handle_level_irq);
/* EIU3-5 only exist on ar9 and vr9 */

View File

@ -1,489 +0,0 @@
From 61cbe7fcc29f439740e004ca967da852fda58b62 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Thu, 11 Aug 2011 14:35:02 +0200
Subject: [PATCH 09/73] MIPS: lantiq: add support for FALC-ON GPIOs
FALC-ON uses a different GPIO core than the other Lantiq SoCs. This patch adds
the new driver.
Signed-off-by: Thomas Langer <thomas.langer@lantiq.com>
Signed-off-by: John Crispin <blogic@openwrt.org>
---
arch/mips/lantiq/falcon/Makefile | 2 +-
arch/mips/lantiq/falcon/devices.c | 41 ++++
arch/mips/lantiq/falcon/devices.h | 2 +
arch/mips/lantiq/falcon/gpio.c | 399 +++++++++++++++++++++++++++++++++++++
4 files changed, 443 insertions(+), 1 deletions(-)
create mode 100644 arch/mips/lantiq/falcon/gpio.c
--- a/arch/mips/lantiq/falcon/Makefile
+++ b/arch/mips/lantiq/falcon/Makefile
@@ -1 +1 @@
-obj-y := clk.o prom.o reset.o sysctrl.o devices.o
+obj-y := clk.o prom.o reset.o sysctrl.o devices.o gpio.o
--- a/arch/mips/lantiq/falcon/devices.c
+++ b/arch/mips/lantiq/falcon/devices.c
@@ -9,6 +9,7 @@
#include <linux/platform_device.h>
#include <linux/mtd/nand.h>
+#include <linux/gpio.h>
#include <lantiq_soc.h>
@@ -85,3 +86,43 @@ falcon_register_nand(void)
{
platform_device_register(&ltq_flash_nand);
}
+
+/* gpio */
+#define DECLARE_GPIO_RES(port) \
+static struct resource falcon_gpio ## port ## _res[] = { \
+ MEM_RES("gpio"#port, LTQ_GPIO ## port ## _BASE_ADDR, \
+ LTQ_GPIO ## port ## _SIZE), \
+ MEM_RES("padctrl"#port, LTQ_PADCTRL ## port ## _BASE_ADDR, \
+ LTQ_PADCTRL ## port ## _SIZE), \
+ IRQ_RES("gpio_mux"#port, FALCON_IRQ_GPIO_P ## port) \
+}
+DECLARE_GPIO_RES(0);
+DECLARE_GPIO_RES(1);
+DECLARE_GPIO_RES(2);
+DECLARE_GPIO_RES(3);
+DECLARE_GPIO_RES(4);
+
+void __init
+falcon_register_gpio(void)
+{
+ platform_device_register_simple("falcon_gpio", 0,
+ falcon_gpio0_res, ARRAY_SIZE(falcon_gpio0_res));
+ platform_device_register_simple("falcon_gpio", 1,
+ falcon_gpio1_res, ARRAY_SIZE(falcon_gpio1_res));
+ platform_device_register_simple("falcon_gpio", 2,
+ falcon_gpio2_res, ARRAY_SIZE(falcon_gpio2_res));
+ ltq_sysctl_activate(SYSCTL_SYS1, ACTS_PADCTRL1 | ACTS_P1);
+ ltq_sysctl_activate(SYSCTL_SYSETH, ACTS_PADCTRL0 |
+ ACTS_PADCTRL2 | ACTS_P0 | ACTS_P2);
+}
+
+void __init
+falcon_register_gpio_extra(void)
+{
+ platform_device_register_simple("falcon_gpio", 3,
+ falcon_gpio3_res, ARRAY_SIZE(falcon_gpio3_res));
+ platform_device_register_simple("falcon_gpio", 4,
+ falcon_gpio4_res, ARRAY_SIZE(falcon_gpio4_res));
+ ltq_sysctl_activate(SYSCTL_SYS1,
+ ACTS_PADCTRL3 | ACTS_PADCTRL4 | ACTS_P3 | ACTS_P4);
+}
--- a/arch/mips/lantiq/falcon/devices.h
+++ b/arch/mips/lantiq/falcon/devices.h
@@ -14,5 +14,7 @@
#include "../devices.h"
extern void falcon_register_nand(void);
+extern void falcon_register_gpio(void);
+extern void falcon_register_gpio_extra(void);
#endif
--- /dev/null
+++ b/arch/mips/lantiq/falcon/gpio.c
@@ -0,0 +1,399 @@
+/*
+ * 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.
+ *
+ * Copyright (C) 2011 Thomas Langer <thomas.langer@lantiq.com>
+ * Copyright (C) 2011 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+#include <linux/export.h>
+#include <linux/platform_device.h>
+
+#include <lantiq_soc.h>
+
+/* Multiplexer Control Register */
+#define LTQ_PADC_MUX(x) (x * 0x4)
+/* Pad Control Availability Register */
+#define LTQ_PADC_AVAIL 0x000000F0
+
+/* Data Output Register */
+#define LTQ_GPIO_OUT 0x00000000
+/* Data Input Register */
+#define LTQ_GPIO_IN 0x00000004
+/* Direction Register */
+#define LTQ_GPIO_DIR 0x00000008
+/* External Interrupt Control Register 0 */
+#define LTQ_GPIO_EXINTCR0 0x00000018
+/* External Interrupt Control Register 1 */
+#define LTQ_GPIO_EXINTCR1 0x0000001C
+/* IRN Capture Register */
+#define LTQ_GPIO_IRNCR 0x00000020
+/* IRN Interrupt Configuration Register */
+#define LTQ_GPIO_IRNCFG 0x0000002C
+/* IRN Interrupt Enable Set Register */
+#define LTQ_GPIO_IRNRNSET 0x00000030
+/* IRN Interrupt Enable Clear Register */
+#define LTQ_GPIO_IRNENCLR 0x00000034
+/* Output Set Register */
+#define LTQ_GPIO_OUTSET 0x00000040
+/* Output Cler Register */
+#define LTQ_GPIO_OUTCLR 0x00000044
+/* Direction Clear Register */
+#define LTQ_GPIO_DIRSET 0x00000048
+/* Direction Set Register */
+#define LTQ_GPIO_DIRCLR 0x0000004C
+
+/* turn a gpio_chip into a falcon_gpio_port */
+#define ctop(c) container_of(c, struct falcon_gpio_port, gpio_chip)
+/* turn a irq_data into a falcon_gpio_port */
+#define itop(i) ((struct falcon_gpio_port *) irq_get_chip_data(i->irq))
+
+#define ltq_pad_r32(p, reg) ltq_r32(p->pad + reg)
+#define ltq_pad_w32(p, val, reg) ltq_w32(val, p->pad + reg)
+#define ltq_pad_w32_mask(c, clear, set, reg) \
+ ltq_pad_w32(c, (ltq_pad_r32(c, reg) & ~(clear)) | (set), reg)
+
+#define ltq_port_r32(p, reg) ltq_r32(p->port + reg)
+#define ltq_port_w32(p, val, reg) ltq_w32(val, p->port + reg)
+#define ltq_port_w32_mask(p, clear, set, reg) \
+ ltq_port_w32(p, (ltq_port_r32(p, reg) & ~(clear)) | (set), reg)
+
+#define MAX_PORTS 5
+#define PINS_PER_PORT 32
+
+struct falcon_gpio_port {
+ struct gpio_chip gpio_chip;
+ void __iomem *pad;
+ void __iomem *port;
+ unsigned int irq_base;
+ unsigned int chained_irq;
+};
+
+static struct falcon_gpio_port ltq_gpio_port[MAX_PORTS];
+
+int gpio_to_irq(unsigned int gpio)
+{
+ return __gpio_to_irq(gpio);
+}
+EXPORT_SYMBOL(gpio_to_irq);
+
+int ltq_gpio_mux_set(unsigned int pin, unsigned int mux)
+{
+ int port = pin / 100;
+ int offset = pin % 100;
+ struct falcon_gpio_port *gpio_port;
+
+ if ((offset >= PINS_PER_PORT) || (port >= MAX_PORTS))
+ return -EINVAL;
+
+ gpio_port = &ltq_gpio_port[port];
+ ltq_pad_w32(gpio_port, mux & 0x3, LTQ_PADC_MUX(offset));
+
+ return 0;
+}
+EXPORT_SYMBOL(ltq_gpio_mux_set);
+
+int ltq_gpio_request(unsigned int pin, unsigned int mux,
+ unsigned int dir, const char *name)
+{
+ int port = pin / 100;
+ int offset = pin % 100;
+
+ if (offset >= PINS_PER_PORT || port >= MAX_PORTS)
+ return -EINVAL;
+
+ if (gpio_request(pin, name)) {
+ pr_err("failed to setup lantiq gpio: %s\n", name);
+ return -EBUSY;
+ }
+
+ if (dir)
+ gpio_direction_output(pin, 1);
+ else
+ gpio_direction_input(pin);
+
+ return ltq_gpio_mux_set(pin, mux);
+}
+EXPORT_SYMBOL(ltq_gpio_request);
+
+static int
+falcon_gpio_direction_input(struct gpio_chip *chip, unsigned int offset)
+{
+ ltq_port_w32(ctop(chip), 1 << offset, LTQ_GPIO_DIRCLR);
+
+ return 0;
+}
+
+static void
+falcon_gpio_set(struct gpio_chip *chip, unsigned int offset, int value)
+{
+ if (value)
+ ltq_port_w32(ctop(chip), 1 << offset, LTQ_GPIO_OUTSET);
+ else
+ ltq_port_w32(ctop(chip), 1 << offset, LTQ_GPIO_OUTCLR);
+}
+
+static int
+falcon_gpio_direction_output(struct gpio_chip *chip,
+ unsigned int offset, int value)
+{
+ falcon_gpio_set(chip, offset, value);
+ ltq_port_w32(ctop(chip), 1 << offset, LTQ_GPIO_DIRSET);
+
+ return 0;
+}
+
+static int
+falcon_gpio_get(struct gpio_chip *chip, unsigned int offset)
+{
+ if ((ltq_port_r32(ctop(chip), LTQ_GPIO_DIR) >> offset) & 1)
+ return (ltq_port_r32(ctop(chip), LTQ_GPIO_OUT) >> offset) & 1;
+ else
+ return (ltq_port_r32(ctop(chip), LTQ_GPIO_IN) >> offset) & 1;
+}
+
+static int
+falcon_gpio_request(struct gpio_chip *chip, unsigned offset)
+{
+ if ((ltq_pad_r32(ctop(chip), LTQ_PADC_AVAIL) >> offset) & 1) {
+ if (ltq_pad_r32(ctop(chip), LTQ_PADC_MUX(offset)) > 1)
+ return -EBUSY;
+ /* switch on gpio function */
+ ltq_pad_w32(ctop(chip), 1, LTQ_PADC_MUX(offset));
+ return 0;
+ }
+
+ return -ENODEV;
+}
+
+static void
+falcon_gpio_free(struct gpio_chip *chip, unsigned offset)
+{
+ if ((ltq_pad_r32(ctop(chip), LTQ_PADC_AVAIL) >> offset) & 1) {
+ if (ltq_pad_r32(ctop(chip), LTQ_PADC_MUX(offset)) > 1)
+ return;
+ /* switch off gpio function */
+ ltq_pad_w32(ctop(chip), 0, LTQ_PADC_MUX(offset));
+ }
+}
+
+static int
+falcon_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
+{
+ return ctop(chip)->irq_base + offset;
+}
+
+static void
+falcon_gpio_disable_irq(struct irq_data *d)
+{
+ unsigned int offset = d->irq - itop(d)->irq_base;
+
+ ltq_port_w32(itop(d), 1 << offset, LTQ_GPIO_IRNENCLR);
+}
+
+static void
+falcon_gpio_enable_irq(struct irq_data *d)
+{
+ unsigned int offset = d->irq - itop(d)->irq_base;
+
+ if (!ltq_pad_r32(itop(d), LTQ_PADC_MUX(offset)) < 1)
+ /* switch on gpio function */
+ ltq_pad_w32(itop(d), 1, LTQ_PADC_MUX(offset));
+
+ ltq_port_w32(itop(d), 1 << offset, LTQ_GPIO_IRNRNSET);
+}
+
+static void
+falcon_gpio_ack_irq(struct irq_data *d)
+{
+ unsigned int offset = d->irq - itop(d)->irq_base;
+
+ ltq_port_w32(itop(d), 1 << offset, LTQ_GPIO_IRNCR);
+}
+
+static void
+falcon_gpio_mask_and_ack_irq(struct irq_data *d)
+{
+ unsigned int offset = d->irq - itop(d)->irq_base;
+
+ ltq_port_w32(itop(d), 1 << offset, LTQ_GPIO_IRNENCLR);
+ ltq_port_w32(itop(d), 1 << offset, LTQ_GPIO_IRNCR);
+}
+
+static struct irq_chip falcon_gpio_irq_chip;
+static int
+falcon_gpio_irq_type(struct irq_data *d, unsigned int type)
+{
+ unsigned int offset = d->irq - itop(d)->irq_base;
+ unsigned int mask = 1 << offset;
+
+ if ((type & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_NONE)
+ return 0;
+
+ if ((type & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) != 0) {
+ /* level triggered */
+ ltq_port_w32_mask(itop(d), 0, mask, LTQ_GPIO_IRNCFG);
+ irq_set_chip_and_handler_name(d->irq,
+ &falcon_gpio_irq_chip, handle_level_irq, "mux");
+ } else {
+ /* edge triggered */
+ ltq_port_w32_mask(itop(d), mask, 0, LTQ_GPIO_IRNCFG);
+ irq_set_chip_and_handler_name(d->irq,
+ &falcon_gpio_irq_chip, handle_simple_irq, "mux");
+ }
+
+ if ((type & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH) {
+ ltq_port_w32_mask(itop(d), mask, 0, LTQ_GPIO_EXINTCR0);
+ ltq_port_w32_mask(itop(d), 0, mask, LTQ_GPIO_EXINTCR1);
+ } else {
+ if ((type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_LEVEL_HIGH)) != 0)
+ /* positive logic: rising edge, high level */
+ ltq_port_w32_mask(itop(d), mask, 0, LTQ_GPIO_EXINTCR0);
+ else
+ /* negative logic: falling edge, low level */
+ ltq_port_w32_mask(itop(d), 0, mask, LTQ_GPIO_EXINTCR0);
+ ltq_port_w32_mask(itop(d), mask, 0, LTQ_GPIO_EXINTCR1);
+ }
+
+ return gpio_direction_input(itop(d)->gpio_chip.base + offset);
+}
+
+static void
+falcon_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+ struct falcon_gpio_port *gpio_port = irq_desc_get_handler_data(desc);
+ unsigned long irncr;
+ int offset;
+
+ /* acknowledge interrupt */
+ irncr = ltq_port_r32(gpio_port, LTQ_GPIO_IRNCR);
+ ltq_port_w32(gpio_port, irncr, LTQ_GPIO_IRNCR);
+
+ desc->irq_data.chip->irq_ack(&desc->irq_data);
+
+ for_each_set_bit(offset, &irncr, gpio_port->gpio_chip.ngpio)
+ generic_handle_irq(gpio_port->irq_base + offset);
+}
+
+static struct irq_chip falcon_gpio_irq_chip = {
+ .name = "gpio_irq_mux",
+ .irq_mask = falcon_gpio_disable_irq,
+ .irq_unmask = falcon_gpio_enable_irq,
+ .irq_ack = falcon_gpio_ack_irq,
+ .irq_mask_ack = falcon_gpio_mask_and_ack_irq,
+ .irq_set_type = falcon_gpio_irq_type,
+};
+
+static struct irqaction gpio_cascade = {
+ .handler = no_action,
+ .flags = IRQF_DISABLED,
+ .name = "gpio_cascade",
+};
+
+static int
+falcon_gpio_probe(struct platform_device *pdev)
+{
+ struct falcon_gpio_port *gpio_port;
+ int ret, i;
+ struct resource *gpiores, *padres;
+ int irq;
+
+ if (pdev->id >= MAX_PORTS)
+ return -ENODEV;
+
+ gpiores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ padres = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ irq = platform_get_irq(pdev, 0);
+ if (!gpiores || !padres)
+ return -ENODEV;
+
+ gpio_port = &ltq_gpio_port[pdev->id];
+ gpio_port->gpio_chip.label = "falcon-gpio";
+ gpio_port->gpio_chip.direction_input = falcon_gpio_direction_input;
+ gpio_port->gpio_chip.direction_output = falcon_gpio_direction_output;
+ gpio_port->gpio_chip.get = falcon_gpio_get;
+ gpio_port->gpio_chip.set = falcon_gpio_set;
+ gpio_port->gpio_chip.request = falcon_gpio_request;
+ gpio_port->gpio_chip.free = falcon_gpio_free;
+ gpio_port->gpio_chip.base = 100 * pdev->id;
+ gpio_port->gpio_chip.ngpio = 32;
+ gpio_port->gpio_chip.dev = &pdev->dev;
+
+ gpio_port->port = ltq_remap_resource(gpiores);
+ gpio_port->pad = ltq_remap_resource(padres);
+
+ if (!gpio_port->port || !gpio_port->pad) {
+ dev_err(&pdev->dev, "Could not map io ranges\n");
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ if (irq > 0) {
+ /* irq_chip support */
+ gpio_port->gpio_chip.to_irq = falcon_gpio_to_irq;
+ gpio_port->irq_base = INT_NUM_EXTRA_START + (32 * pdev->id);
+
+ for (i = 0; i < 32; i++) {
+ irq_set_chip_and_handler_name(gpio_port->irq_base + i,
+ &falcon_gpio_irq_chip, handle_simple_irq,
+ "mux");
+ irq_set_chip_data(gpio_port->irq_base + i, gpio_port);
+ /* set to negative logic (falling edge, low level) */
+ ltq_port_w32_mask(gpio_port, 0, 1 << i,
+ LTQ_GPIO_EXINTCR0);
+ }
+
+ gpio_port->chained_irq = irq;
+ setup_irq(irq, &gpio_cascade);
+ irq_set_handler_data(irq, gpio_port);
+ irq_set_chained_handler(irq, falcon_gpio_irq_handler);
+ }
+
+ ret = gpiochip_add(&gpio_port->gpio_chip);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "Could not register gpiochip %d, %d\n",
+ pdev->id, ret);
+ goto err;
+ }
+ platform_set_drvdata(pdev, gpio_port);
+ return ret;
+
+err:
+ dev_err(&pdev->dev, "Error in gpio_probe %d, %d\n", pdev->id, ret);
+ if (gpiores)
+ release_resource(gpiores);
+ if (padres)
+ release_resource(padres);
+
+ if (gpio_port->port)
+ iounmap(gpio_port->port);
+ if (gpio_port->pad)
+ iounmap(gpio_port->pad);
+ return ret;
+}
+
+static struct platform_driver falcon_gpio_driver = {
+ .probe = falcon_gpio_probe,
+ .driver = {
+ .name = "falcon_gpio",
+ .owner = THIS_MODULE,
+ },
+};
+
+int __init
+falcon_gpio_init(void)
+{
+ int ret;
+
+ pr_info("FALC(tm) ON GPIO Driver, (C) 2011 Lantiq Deutschland Gmbh\n");
+ ret = platform_driver_register(&falcon_gpio_driver);
+ if (ret)
+ pr_err("falcon_gpio: Error registering platform driver!");
+ return ret;
+}
+
+postcore_initcall(falcon_gpio_init);

View File

@ -1,165 +0,0 @@
From ce27aac6ea9503ae4be0f65423424d92a714d9da Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Thu, 11 Aug 2011 14:09:35 +0200
Subject: [PATCH 10/73] MIPS: lantiq: add support for the EASY98000 evaluation
board
This patch adds the machine code for the EASY9800 evaluation board.
Signed-off-by: Thomas Langer <thomas.langer@lantiq.com>
Signed-off-by: John Crispin <blogic@openwrt.org>
---
arch/mips/lantiq/falcon/Kconfig | 11 +++
arch/mips/lantiq/falcon/Makefile | 1 +
arch/mips/lantiq/falcon/mach-easy98000.c | 110 ++++++++++++++++++++++++++++++
arch/mips/lantiq/machtypes.h | 5 ++
4 files changed, 127 insertions(+), 0 deletions(-)
create mode 100644 arch/mips/lantiq/falcon/Kconfig
create mode 100644 arch/mips/lantiq/falcon/mach-easy98000.c
--- /dev/null
+++ b/arch/mips/lantiq/falcon/Kconfig
@@ -0,0 +1,11 @@
+if SOC_FALCON
+
+menu "MIPS Machine"
+
+config LANTIQ_MACH_EASY98000
+ bool "Easy98000"
+ default y
+
+endmenu
+
+endif
--- a/arch/mips/lantiq/falcon/Makefile
+++ b/arch/mips/lantiq/falcon/Makefile
@@ -1 +1,2 @@
obj-y := clk.o prom.o reset.o sysctrl.o devices.o gpio.o
+obj-$(CONFIG_LANTIQ_MACH_EASY98000) += mach-easy98000.o
--- /dev/null
+++ b/arch/mips/lantiq/falcon/mach-easy98000.c
@@ -0,0 +1,110 @@
+/*
+ * 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.
+ *
+ * Copyright (C) 2011 Thomas Langer <thomas.langer@lantiq.com>
+ * Copyright (C) 2011 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/platform_device.h>
+#include <linux/mtd/partitions.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/spi_gpio.h>
+#include <linux/spi/eeprom.h>
+
+#include "../machtypes.h"
+
+#include "devices.h"
+
+static struct mtd_partition easy98000_nor_partitions[] = {
+ {
+ .name = "uboot",
+ .offset = 0x0,
+ .size = 0x40000,
+ },
+ {
+ .name = "uboot_env",
+ .offset = 0x40000,
+ .size = 0x40000, /* 2 sectors for redundant env. */
+ },
+ {
+ .name = "linux",
+ .offset = 0x80000,
+ .size = 0xF80000, /* map only 16 MiB */
+ },
+};
+
+struct physmap_flash_data easy98000_nor_flash_data = {
+ .nr_parts = ARRAY_SIZE(easy98000_nor_partitions),
+ .parts = easy98000_nor_partitions,
+};
+
+/* setup gpio based spi bus/device for access to the eeprom on the board */
+#define SPI_GPIO_MRST 102
+#define SPI_GPIO_MTSR 103
+#define SPI_GPIO_CLK 104
+#define SPI_GPIO_CS0 105
+#define SPI_GPIO_CS1 106
+#define SPI_GPIO_BUS_NUM 1
+
+static struct spi_gpio_platform_data easy98000_spi_gpio_data = {
+ .sck = SPI_GPIO_CLK,
+ .mosi = SPI_GPIO_MTSR,
+ .miso = SPI_GPIO_MRST,
+ .num_chipselect = 2,
+};
+
+static struct platform_device easy98000_spi_gpio_device = {
+ .name = "spi_gpio",
+ .id = SPI_GPIO_BUS_NUM,
+ .dev.platform_data = &easy98000_spi_gpio_data,
+};
+
+static struct spi_eeprom at25160n = {
+ .byte_len = 16 * 1024 / 8,
+ .name = "at25160n",
+ .page_size = 32,
+ .flags = EE_ADDR2,
+};
+
+static struct spi_board_info easy98000_spi_gpio_devices __initdata = {
+ .modalias = "at25",
+ .bus_num = SPI_GPIO_BUS_NUM,
+ .max_speed_hz = 1000 * 1000,
+ .mode = SPI_MODE_3,
+ .chip_select = 1,
+ .controller_data = (void *) SPI_GPIO_CS1,
+ .platform_data = &at25160n,
+};
+
+static void __init
+easy98000_init_common(void)
+{
+ spi_register_board_info(&easy98000_spi_gpio_devices, 1);
+ platform_device_register(&easy98000_spi_gpio_device);
+}
+
+static void __init
+easy98000_init(void)
+{
+ easy98000_init_common();
+ ltq_register_nor(&easy98000_nor_flash_data);
+}
+
+static void __init
+easy98000nand_init(void)
+{
+ easy98000_init_common();
+ falcon_register_nand();
+}
+
+MIPS_MACHINE(LANTIQ_MACH_EASY98000,
+ "EASY98000",
+ "EASY98000 Eval Board",
+ easy98000_init);
+
+MIPS_MACHINE(LANTIQ_MACH_EASY98000NAND,
+ "EASY98000NAND",
+ "EASY98000 Eval Board (NAND Flash)",
+ easy98000nand_init);
--- a/arch/mips/lantiq/machtypes.h
+++ b/arch/mips/lantiq/machtypes.h
@@ -15,6 +15,11 @@ enum lantiq_mach_type {
LTQ_MACH_GENERIC = 0,
LTQ_MACH_EASY50712, /* Danube evaluation board */
LTQ_MACH_EASY50601, /* Amazon SE evaluation board */
+
+ /* FALCON */
+ LANTIQ_MACH_EASY98000, /* Falcon Eval Board, NOR Flash */
+ LANTIQ_MACH_EASY98000SF, /* Falcon Eval Board, Serial Flash */
+ LANTIQ_MACH_EASY98000NAND, /* Falcon Eval Board, NAND Flash */
};
#endif

View File

@ -1,61 +0,0 @@
From 993160b530efe9b0d3f0bc4551954a4c3344beeb Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Sat, 20 Aug 2011 18:55:13 +0200
Subject: [PATCH 11/73] MIPS: lantiq: fix early printk
The code was using a 32bit write operations in the early_printk code. This
resulted in 3 zero bytes also being written to the serial port. This patch
changes the memory access to 8bit.
Signed-off-by: Thomas Langer <thomas.langer@lantiq.com>
Signed-off-by: John Crispin <blogic@openwrt.org>
---
.../mips/include/asm/mach-lantiq/xway/lantiq_soc.h | 6 ++++++
arch/mips/lantiq/early_printk.c | 14 ++++++++------
2 files changed, 14 insertions(+), 6 deletions(-)
--- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
+++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
@@ -34,6 +34,12 @@
#define LTQ_ASC1_BASE_ADDR 0x1E100C00
#define LTQ_ASC_SIZE 0x400
+/*
+ * during early_printk no ioremap is possible
+ * lets use KSEG1 instead
+ */
+#define LTQ_EARLY_ASC KSEG1ADDR(LTQ_ASC1_BASE_ADDR)
+
/* RCU - reset control unit */
#define LTQ_RCU_BASE_ADDR 0x1F203000
#define LTQ_RCU_SIZE 0x1000
--- a/arch/mips/lantiq/early_printk.c
+++ b/arch/mips/lantiq/early_printk.c
@@ -12,11 +12,13 @@
#include <lantiq.h>
#include <lantiq_soc.h>
-/* no ioremap possible at this early stage, lets use KSEG1 instead */
-#define LTQ_ASC_BASE KSEG1ADDR(LTQ_ASC1_BASE_ADDR)
#define ASC_BUF 1024
-#define LTQ_ASC_FSTAT ((u32 *)(LTQ_ASC_BASE + 0x0048))
-#define LTQ_ASC_TBUF ((u32 *)(LTQ_ASC_BASE + 0x0020))
+#define LTQ_ASC_FSTAT ((u32 *)(LTQ_EARLY_ASC + 0x0048))
+#ifdef __BIG_ENDIAN
+#define LTQ_ASC_TBUF ((u32 *)(LTQ_EARLY_ASC + 0x0020 + 3))
+#else
+#define LTQ_ASC_TBUF ((u32 *)(LTQ_EARLY_ASC + 0x0020))
+#endif
#define TXMASK 0x3F00
#define TXOFFSET 8
@@ -27,7 +29,7 @@ void prom_putchar(char c)
local_irq_save(flags);
do { } while ((ltq_r32(LTQ_ASC_FSTAT) & TXMASK) >> TXOFFSET);
if (c == '\n')
- ltq_w32('\r', LTQ_ASC_TBUF);
- ltq_w32(c, LTQ_ASC_TBUF);
+ ltq_w8('\r', LTQ_ASC_TBUF);
+ ltq_w8(c, LTQ_ASC_TBUF);
local_irq_restore(flags);
}

View File

@ -1,31 +0,0 @@
From 9c1b1cde50b09dd3679d74cde07694cee32c8b19 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Fri, 12 Aug 2011 16:27:38 +0200
Subject: [PATCH 12/73] MIPS: lantiq: fix cmdline parsing
The code tested if the KSEG1 mapped address of argv was != 0. We need to use
CPHYSADDR instead to make the conditional actually work.
Signed-off-by: Thomas Langer <thomas.langer@lantiq.com>
Signed-off-by: John Crispin <blogic@openwrt.org>
---
arch/mips/lantiq/prom.c | 6 ++++--
1 files changed, 4 insertions(+), 2 deletions(-)
--- a/arch/mips/lantiq/prom.c
+++ b/arch/mips/lantiq/prom.c
@@ -49,10 +49,12 @@ static void __init prom_init_cmdline(voi
char **argv = (char **) KSEG1ADDR(fw_arg1);
int i;
+ arcs_cmdline[0] = '\0';
+
for (i = 0; i < argc; i++) {
- char *p = (char *) KSEG1ADDR(argv[i]);
+ char *p = (char *) KSEG1ADDR(argv[i]);
- if (p && *p) {
+ if (CPHYSADDR(p) && *p) {
strlcat(arcs_cmdline, p, sizeof(arcs_cmdline));
strlcat(arcs_cmdline, " ", sizeof(arcs_cmdline));
}

View File

@ -1,37 +0,0 @@
From 1314356c316e79f9887ac12b9cdf2ddba24d34a5 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Thu, 27 Oct 2011 20:06:05 +0200
Subject: [PATCH 13/73] MIPS: lantiq: fix STP gpio groups
The STP engine has 3 groups of 8 pins. Only the first was activated by default.
This patch activates the 2 missing groups.
Signed-off-by: Matti Laakso <malaakso@elisanet.fi>
Signed-off-by: John Crispin <blogic@openwrt.org>
---
arch/mips/lantiq/xway/gpio_stp.c | 7 +++++--
1 files changed, 5 insertions(+), 2 deletions(-)
--- a/arch/mips/lantiq/xway/gpio_stp.c
+++ b/arch/mips/lantiq/xway/gpio_stp.c
@@ -35,6 +35,8 @@
#define LTQ_STP_ADSL_SRC (3 << 24)
#define LTQ_STP_GROUP0 (1 << 0)
+#define LTQ_STP_GROUP1 (1 << 1)
+#define LTQ_STP_GROUP2 (1 << 2)
#define LTQ_STP_RISING 0
#define LTQ_STP_FALLING (1 << 26)
@@ -93,8 +95,9 @@ static int ltq_stp_hw_init(void)
/* rising or falling edge */
ltq_stp_w32_mask(LTQ_STP_EDGE_MASK, LTQ_STP_FALLING, LTQ_STP_CON0);
- /* per default stp 15-0 are set */
- ltq_stp_w32_mask(0, LTQ_STP_GROUP0, LTQ_STP_CON1);
+ /* enable all three led groups */
+ ltq_stp_w32_mask(0, LTQ_STP_GROUP0 | LTQ_STP_GROUP1 | LTQ_STP_GROUP2,
+ LTQ_STP_CON1);
/* stp are update periodically by the FPI bus */
ltq_stp_w32_mask(LTQ_STP_UPD_MASK, LTQ_STP_UPD_FPI, LTQ_STP_CON1);

View File

@ -1,43 +0,0 @@
From cf06a3358f752a7d1247498f1e9409b66b23a603 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Thu, 27 Oct 2011 20:06:30 +0200
Subject: [PATCH 14/73] MIPS: lantiq: fix pull gpio up resistors usage
The register that enables a gpios internal pullups was not used. This patch
makes sure the pullups are activated correctly.
Signed-off-by: Matti Laakso <malaakso@elisanet.fi>
Signed-off-by: John Crispin <blogic@openwrt.org>
---
arch/mips/lantiq/xway/gpio.c | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
--- a/arch/mips/lantiq/xway/gpio.c
+++ b/arch/mips/lantiq/xway/gpio.c
@@ -21,6 +21,8 @@
#define LTQ_GPIO_ALTSEL0 0x0C
#define LTQ_GPIO_ALTSEL1 0x10
#define LTQ_GPIO_OD 0x14
+#define LTQ_GPIO_PUDSEL 0x1C
+#define LTQ_GPIO_PUDEN 0x20
#define PINS_PER_PORT 16
#define MAX_PORTS 3
@@ -106,6 +108,8 @@ static int ltq_gpio_direction_input(stru
ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_OD, offset);
ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_DIR, offset);
+ ltq_gpio_setbit(ltq_gpio->membase, LTQ_GPIO_PUDSEL, offset);
+ ltq_gpio_setbit(ltq_gpio->membase, LTQ_GPIO_PUDEN, offset);
return 0;
}
@@ -117,6 +121,8 @@ static int ltq_gpio_direction_output(str
ltq_gpio_setbit(ltq_gpio->membase, LTQ_GPIO_OD, offset);
ltq_gpio_setbit(ltq_gpio->membase, LTQ_GPIO_DIR, offset);
+ ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_PUDSEL, offset);
+ ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_PUDEN, offset);
ltq_gpio_set(chip, offset, value);
return 0;

View File

@ -1,235 +0,0 @@
From 1b9ea6ce42ae06a5f746b6f1aaa039037b2d71a3 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Fri, 11 Nov 2011 22:02:27 +0100
Subject: [PATCH 15/73] MIPS: lantiq: add default configs
This patch adds the default config for 3 Lantiq SoCs
* Danube/AR9 (xway)
* Amazon-SE
* Falc-ON
Signed-off-by: John Crispin <blogic@openwrt.org>
---
arch/mips/configs/ase_defconfig | 67 +++++++++++++++++++++++++++++++++
arch/mips/configs/falcon_defconfig | 72 ++++++++++++++++++++++++++++++++++++
arch/mips/configs/xway_defconfig | 66 +++++++++++++++++++++++++++++++++
3 files changed, 205 insertions(+), 0 deletions(-)
create mode 100644 arch/mips/configs/ase_defconfig
create mode 100644 arch/mips/configs/falcon_defconfig
create mode 100644 arch/mips/configs/xway_defconfig
--- /dev/null
+++ b/arch/mips/configs/ase_defconfig
@@ -0,0 +1,67 @@
+CONFIG_LANTIQ=y
+CONFIG_SOC_AMAZON_SE=y
+CONFIG_CPU_MIPS32_R2=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_EXPERIMENTAL=y
+CONFIG_DEFAULT_HOSTNAME="amazon_se"
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE="../root-lantiq/ ../root-lantiq/initramfs-base-files.txt"
+CONFIG_INITRAMFS_ROOT_UID=1000
+CONFIG_INITRAMFS_ROOT_GID=1000
++# CONFIG_RD_GZIP is not set
+CONFIG_RD_LZMA=y
+CONFIG_EMBEDDED=y
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_DEFAULT_DEADLINE=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_MROUTE_MULTIPLE_TABLES=y
+CONFIG_ARPD=y
+CONFIG_SYN_COOKIES=y
+CONFIG_NETFILTER=y
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=y
+CONFIG_NET_SCHED=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_GEOMETRY=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+CONFIG_MTD_LANTIQ=y
+CONFIG_MISC_DEVICES=y
+CONFIG_NETDEVICES=y
+CONFIG_MII=y
+CONFIG_LANTIQ_ETOP=y
+CONFIG_PHYLIB=y
+CONFIG_SERIAL_LANTIQ=y
+CONFIG_PINCTRL=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_WATCHDOG=y
+CONFIG_LANTIQ_WDT=y
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_SUMMARY=y
+CONFIG_JFFS2_FS_XATTR=y
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_SQUASHFS=y
+CONFIG_SQUASHFS_XZ=y
+CONFIG_STRIP_ASM_SYMS=y
+CONFIG_DEBUG_FS=y
--- /dev/null
+++ b/arch/mips/configs/falcon_defconfig
@@ -0,0 +1,72 @@
+CONFIG_LANTIQ=y
+CONFIG_SOC_FALCON=y
+CONFIG_CPU_MIPS32_R2=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_EXPERIMENTAL=y
+CONFIG_DEFAULT_HOSTNAME="falcon"
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE="../root-lantiq/ ../root-lantiq/initramfs-base-files.txt"
+CONFIG_INITRAMFS_ROOT_UID=1000
+CONFIG_INITRAMFS_ROOT_GID=1000
++# CONFIG_RD_GZIP is not set
+CONFIG_RD_LZMA=y
+CONFIG_EMBEDDED=y
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_DEFAULT_DEADLINE=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_MROUTE_MULTIPLE_TABLES=y
+CONFIG_ARPD=y
+CONFIG_SYN_COOKIES=y
+CONFIG_NETFILTER=y
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=y
+CONFIG_NET_SCHED=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_GEOMETRY=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+CONFIG_MTD_LANTIQ=y
+CONFIG_MTD_M25P80=y
+CONFIG_MISC_DEVICES=y
+CONFIG_EEPROM_AT24=y
+CONFIG_NETDEVICES=y
+CONFIG_MII=y
+CONFIG_PHYLIB=y
+CONFIG_SERIAL_LANTIQ=y
+CONFIG_I2C=y
+CONFIG_I2C_FALCON=y
+CONFIG_SPI=y
+CONFIG_SPI_FALCON=y
+CONFIG_PINCTRL=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_WATCHDOG=y
+CONFIG_LANTIQ_WDT=y
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_SUMMARY=y
+CONFIG_JFFS2_FS_XATTR=y
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_SQUASHFS=y
+CONFIG_SQUASHFS_XZ=y
+CONFIG_STRIP_ASM_SYMS=y
+CONFIG_DEBUG_FS=y
--- /dev/null
+++ b/arch/mips/configs/xway_defconfig
@@ -0,0 +1,66 @@
+CONFIG_LANTIQ=y
+CONFIG_CPU_MIPS32_R2=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_EXPERIMENTAL=y
+CONFIG_DEFAULT_HOSTNAME="danube"
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE="../root-lantiq/ ../root-lantiq/initramfs-base-files.txt"
+CONFIG_INITRAMFS_ROOT_UID=1000
+CONFIG_INITRAMFS_ROOT_GID=1000
+# CONFIG_RD_GZIP is not set
+CONFIG_RD_LZMA=y
+CONFIG_EMBEDDED=y
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_DEFAULT_DEADLINE=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_MROUTE_MULTIPLE_TABLES=y
+CONFIG_ARPD=y
+CONFIG_SYN_COOKIES=y
+CONFIG_NETFILTER=y
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=y
+CONFIG_NET_SCHED=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_GEOMETRY=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+CONFIG_MTD_LANTIQ=y
+CONFIG_MISC_DEVICES=y
+CONFIG_NETDEVICES=y
+CONFIG_MII=y
+CONFIG_LANTIQ_ETOP=y
+CONFIG_PHYLIB=y
+CONFIG_SERIAL_LANTIQ=y
+CONFIG_PINCTRL=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_WATCHDOG=y
+CONFIG_LANTIQ_WDT=y
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_SUMMARY=y
+CONFIG_JFFS2_FS_XATTR=y
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_SQUASHFS=y
+CONFIG_SQUASHFS_XZ=y
+CONFIG_STRIP_ASM_SYMS=y
+CONFIG_DEBUG_FS=y

View File

@ -1,33 +0,0 @@
From ae4a7211739412c5f9ddd85d1437cab182fe428f Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Thu, 10 Nov 2011 19:32:37 +0100
Subject: [PATCH 16/73] MAINTAINERS: add entry for Lantiq related files
Adds new entry to MAINTAINERS file for Lantiq SoC related code.
Signed-off-by: John Crispin <blogic@openwrt.org>
---
MAINTAINERS | 12 ++++++++++++
1 files changed, 12 insertions(+), 0 deletions(-)
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4353,6 +4353,18 @@ S: Supported
F: Documentation/mips/
F: arch/mips/
+MIPS/LANTIQ
+M: John Crispin <blogic@openwrt.org>
+M: Thomas Langer <thomas.langer@lantiq.com>
+S: Maintained
+F: arch/mips/lantiq/*
+F: drivers/i2c/busses/i2c-falcon.c
+F: drivers/mtd/maps/lantiq-flash.c
+F: drivers/net/ethernet/lantiq_etop.c
+F: drivers/spi/spi-falcon.c
+F: drivers/tty/serial/lantiq.c
+F: drivers/watchdog/lantiq_wdt.c
+
MISCELLANEOUS MCA-SUPPORT
M: James Bottomley <James.Bottomley@HansenPartnership.com>
S: Maintained

View File

@ -1,46 +0,0 @@
From 476a5cd7924926236c2356654da639fea90a8fea Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Wed, 24 Aug 2011 13:28:55 +0200
Subject: [PATCH 17/73] MIPS: lantiq: enable oprofile support on lantiq
targets
This patch sets the performance counters irq and HAVE_OPROFILE flag for Lantiq
SoCs.
Signed-off-by: John Crispin <blogic@openwrt.org>
---
arch/mips/Kconfig | 1 +
arch/mips/lantiq/irq.c | 5 +++++
2 files changed, 6 insertions(+), 0 deletions(-)
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -226,6 +226,7 @@ config LANTIQ
select SWAP_IO_SPACE
select BOOT_RAW
select HAVE_CLK
+ select HAVE_OPROFILE
select MIPS_MACHINE
config LASAT
--- a/arch/mips/lantiq/irq.c
+++ b/arch/mips/lantiq/irq.c
@@ -40,6 +40,9 @@
#define MAX_EIU 6
+/* the performance counter */
+#define LTQ_PERF_IRQ (INT_NUM_IM4_IRL0 + 31)
+
/* irqs generated by device attached to the EBU need to be acked in
* a special manner
*/
@@ -318,6 +321,8 @@ void __init arch_init_irq(void)
set_c0_status(IE_SW0 | IE_SW1 | IE_IRQ0 | IE_IRQ1 |
IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5);
#endif
+
+ cp0_perfcount_irq = LTQ_PERF_IRQ;
}
unsigned int __cpuinit get_c0_compare_int(void)

View File

@ -1,396 +0,0 @@
From a1a9dcf7554df9bbf23ca0933e645b2327abbb8b Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Wed, 10 Aug 2011 15:32:16 +0200
Subject: [PATCH 18/73] NET: MIPS: lantiq: make etop ethernet work on ase/ar9
Extend the driver to handle the different DMA channel layout for AR9 and
Amazon-SE SoCs. The patch also adds support for the integrated PHY found
on Amazon-SE and the gigabit switch found inside the AR9.
Signed-off-by: John Crispin <blogic@openwrt.org>
Cc: netdev@vger.kernel.org
---
.../mips/include/asm/mach-lantiq/xway/lantiq_irq.h | 22 +---
.../mips/include/asm/mach-lantiq/xway/lantiq_soc.h | 10 ++
arch/mips/lantiq/xway/devices.c | 11 +-
drivers/net/ethernet/lantiq_etop.c | 171 ++++++++++++++++++--
4 files changed, 174 insertions(+), 40 deletions(-)
--- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h
+++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h
@@ -38,26 +38,8 @@
#define MIPS_CPU_TIMER_IRQ 7
-#define LTQ_DMA_CH0_INT (INT_NUM_IM2_IRL0)
-#define LTQ_DMA_CH1_INT (INT_NUM_IM2_IRL0 + 1)
-#define LTQ_DMA_CH2_INT (INT_NUM_IM2_IRL0 + 2)
-#define LTQ_DMA_CH3_INT (INT_NUM_IM2_IRL0 + 3)
-#define LTQ_DMA_CH4_INT (INT_NUM_IM2_IRL0 + 4)
-#define LTQ_DMA_CH5_INT (INT_NUM_IM2_IRL0 + 5)
-#define LTQ_DMA_CH6_INT (INT_NUM_IM2_IRL0 + 6)
-#define LTQ_DMA_CH7_INT (INT_NUM_IM2_IRL0 + 7)
-#define LTQ_DMA_CH8_INT (INT_NUM_IM2_IRL0 + 8)
-#define LTQ_DMA_CH9_INT (INT_NUM_IM2_IRL0 + 9)
-#define LTQ_DMA_CH10_INT (INT_NUM_IM2_IRL0 + 10)
-#define LTQ_DMA_CH11_INT (INT_NUM_IM2_IRL0 + 11)
-#define LTQ_DMA_CH12_INT (INT_NUM_IM2_IRL0 + 25)
-#define LTQ_DMA_CH13_INT (INT_NUM_IM2_IRL0 + 26)
-#define LTQ_DMA_CH14_INT (INT_NUM_IM2_IRL0 + 27)
-#define LTQ_DMA_CH15_INT (INT_NUM_IM2_IRL0 + 28)
-#define LTQ_DMA_CH16_INT (INT_NUM_IM2_IRL0 + 29)
-#define LTQ_DMA_CH17_INT (INT_NUM_IM2_IRL0 + 30)
-#define LTQ_DMA_CH18_INT (INT_NUM_IM2_IRL0 + 16)
-#define LTQ_DMA_CH19_INT (INT_NUM_IM2_IRL0 + 21)
+#define LTQ_DMA_ETOP ((ltq_is_ase()) ? \
+ (INT_NUM_IM3_IRL0) : (INT_NUM_IM2_IRL0))
#define LTQ_PPE_MBOX_INT (INT_NUM_IM2_IRL0 + 24)
--- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
+++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
@@ -82,6 +82,7 @@
#define LTQ_PMU_SIZE 0x1000
#define PMU_DMA 0x0020
+#define PMU_EPHY 0x0080
#define PMU_USB 0x8041
#define PMU_LED 0x0800
#define PMU_GPT 0x1000
@@ -93,6 +94,10 @@
#define LTQ_ETOP_BASE_ADDR 0x1E180000
#define LTQ_ETOP_SIZE 0x40000
+/* GBIT - gigabit switch */
+#define LTQ_GBIT_BASE_ADDR 0x1E108000
+#define LTQ_GBIT_SIZE 0x200
+
/* DMA */
#define LTQ_DMA_BASE_ADDR 0x1E104100
#define LTQ_DMA_SIZE 0x800
@@ -147,6 +152,11 @@ extern void ltq_pmu_enable(unsigned int
extern void ltq_pmu_disable(unsigned int module);
extern void ltq_cgu_enable(unsigned int clk);
+static inline int ltq_is_ase(void)
+{
+ return (ltq_get_soc_type() == SOC_TYPE_AMAZON_SE);
+}
+
static inline int ltq_is_ar9(void)
{
return (ltq_get_soc_type() == SOC_TYPE_AR9);
--- a/arch/mips/lantiq/xway/devices.c
+++ b/arch/mips/lantiq/xway/devices.c
@@ -74,18 +74,23 @@ void __init ltq_register_ase_asc(void)
}
/* ethernet */
-static struct resource ltq_etop_resources =
- MEM_RES("etop", LTQ_ETOP_BASE_ADDR, LTQ_ETOP_SIZE);
+static struct resource ltq_etop_resources[] = {
+ MEM_RES("etop", LTQ_ETOP_BASE_ADDR, LTQ_ETOP_SIZE),
+ MEM_RES("gbit", LTQ_GBIT_BASE_ADDR, LTQ_GBIT_SIZE),
+};
static struct platform_device ltq_etop = {
.name = "ltq_etop",
- .resource = &ltq_etop_resources,
+ .resource = ltq_etop_resources,
.num_resources = 1,
};
void __init
ltq_register_etop(struct ltq_eth_data *eth)
{
+ /* only register the gphy on socs that have one */
+ if (ltq_is_ar9() | ltq_is_vr9())
+ ltq_etop.num_resources = 2;
if (eth) {
ltq_etop.dev.platform_data = eth;
platform_device_register(&ltq_etop);
--- a/drivers/net/ethernet/lantiq_etop.c
+++ b/drivers/net/ethernet/lantiq_etop.c
@@ -71,10 +71,43 @@
#define ETOP_MII_REVERSE 0xe
#define ETOP_PLEN_UNDER 0x40
#define ETOP_CGEN 0x800
+#define ETOP_CFG_MII0 0x01
-/* use 2 static channels for TX/RX */
+#define LTQ_GBIT_MDIO_CTL 0xCC
+#define LTQ_GBIT_MDIO_DATA 0xd0
+#define LTQ_GBIT_GCTL0 0x68
+#define LTQ_GBIT_PMAC_HD_CTL 0x8c
+#define LTQ_GBIT_P0_CTL 0x4
+#define LTQ_GBIT_PMAC_RX_IPG 0xa8
+
+#define PMAC_HD_CTL_AS (1 << 19)
+#define PMAC_HD_CTL_RXSH (1 << 22)
+
+/* Switch Enable (0=disable, 1=enable) */
+#define GCTL0_SE 0x80000000
+/* Disable MDIO auto polling (0=disable, 1=enable) */
+#define PX_CTL_DMDIO 0x00400000
+
+/* register information for the gbit's MDIO bus */
+#define MDIO_XR9_REQUEST 0x00008000
+#define MDIO_XR9_READ 0x00000800
+#define MDIO_XR9_WRITE 0x00000400
+#define MDIO_XR9_REG_MASK 0x1f
+#define MDIO_XR9_ADDR_MASK 0x1f
+#define MDIO_XR9_RD_MASK 0xffff
+#define MDIO_XR9_REG_OFFSET 0
+#define MDIO_XR9_ADDR_OFFSET 5
+#define MDIO_XR9_WR_OFFSET 16
+
+/* the newer xway socks have a embedded 3/7 port gbit multiplexer */
+#define ltq_has_gbit() (ltq_is_ar9() || ltq_is_vr9())
+
+/* use 2 static channels for TX/RX
+ depending on the SoC we need to use different DMA channels for ethernet */
#define LTQ_ETOP_TX_CHANNEL 1
-#define LTQ_ETOP_RX_CHANNEL 6
+#define LTQ_ETOP_RX_CHANNEL ((ltq_is_ase()) ? (5) : \
+ ((ltq_has_gbit()) ? (0) : (6)))
+
#define IS_TX(x) (x == LTQ_ETOP_TX_CHANNEL)
#define IS_RX(x) (x == LTQ_ETOP_RX_CHANNEL)
@@ -83,9 +116,15 @@
#define ltq_etop_w32_mask(x, y, z) \
ltq_w32_mask(x, y, ltq_etop_membase + (z))
+#define ltq_gbit_r32(x) ltq_r32(ltq_gbit_membase + (x))
+#define ltq_gbit_w32(x, y) ltq_w32(x, ltq_gbit_membase + (y))
+#define ltq_gbit_w32_mask(x, y, z) \
+ ltq_w32_mask(x, y, ltq_gbit_membase + (z))
+
#define DRV_VERSION "1.0"
static void __iomem *ltq_etop_membase;
+static void __iomem *ltq_gbit_membase;
struct ltq_etop_chan {
int idx;
@@ -110,6 +149,9 @@ struct ltq_etop_priv {
spinlock_t lock;
};
+static int ltq_etop_mdio_wr(struct mii_bus *bus, int phy_addr,
+ int phy_reg, u16 phy_data);
+
static int
ltq_etop_alloc_skb(struct ltq_etop_chan *ch)
{
@@ -211,7 +253,7 @@ static irqreturn_t
ltq_etop_dma_irq(int irq, void *_priv)
{
struct ltq_etop_priv *priv = _priv;
- int ch = irq - LTQ_DMA_CH0_INT;
+ int ch = irq - LTQ_DMA_ETOP;
napi_schedule(&priv->ch[ch].napi);
return IRQ_HANDLED;
@@ -244,15 +286,43 @@ ltq_etop_hw_exit(struct net_device *dev)
ltq_etop_free_channel(dev, &priv->ch[i]);
}
+static void
+ltq_etop_gbit_init(void)
+{
+ ltq_pmu_enable(PMU_SWITCH);
+
+ ltq_gpio_request(42, 2, 1, "MDIO");
+ ltq_gpio_request(43, 2, 1, "MDC");
+
+ ltq_gbit_w32_mask(0, GCTL0_SE, LTQ_GBIT_GCTL0);
+ /** Disable MDIO auto polling mode */
+ ltq_gbit_w32_mask(0, PX_CTL_DMDIO, LTQ_GBIT_P0_CTL);
+ /* set 1522 packet size */
+ ltq_gbit_w32_mask(0x300, 0, LTQ_GBIT_GCTL0);
+ /* disable pmac & dmac headers */
+ ltq_gbit_w32_mask(PMAC_HD_CTL_AS | PMAC_HD_CTL_RXSH, 0,
+ LTQ_GBIT_PMAC_HD_CTL);
+ /* Due to traffic halt when burst length 8,
+ replace default IPG value with 0x3B */
+ ltq_gbit_w32(0x3B, LTQ_GBIT_PMAC_RX_IPG);
+}
+
static int
ltq_etop_hw_init(struct net_device *dev)
{
struct ltq_etop_priv *priv = netdev_priv(dev);
+ unsigned int mii_mode = priv->pldata->mii_mode;
int i;
ltq_pmu_enable(PMU_PPE);
- switch (priv->pldata->mii_mode) {
+ if (ltq_has_gbit()) {
+ ltq_etop_gbit_init();
+ /* force the etops link to the gbit to MII */
+ mii_mode = PHY_INTERFACE_MODE_MII;
+ }
+
+ switch (mii_mode) {
case PHY_INTERFACE_MODE_RMII:
ltq_etop_w32_mask(ETOP_MII_MASK,
ETOP_MII_REVERSE, LTQ_ETOP_CFG);
@@ -264,6 +334,18 @@ ltq_etop_hw_init(struct net_device *dev)
break;
default:
+ if (ltq_is_ase()) {
+ ltq_pmu_enable(PMU_EPHY);
+ /* disable external MII */
+ ltq_etop_w32_mask(0, ETOP_CFG_MII0, LTQ_ETOP_CFG);
+ /* enable clock for internal PHY */
+ ltq_cgu_enable(CGU_EPHY);
+ /* we need to write this magic to the internal phy to
+ make it work */
+ ltq_etop_mdio_wr(NULL, 0x8, 0x12, 0xC020);
+ pr_info("Selected EPHY mode\n");
+ break;
+ }
netdev_err(dev, "unknown mii mode %d\n",
priv->pldata->mii_mode);
return -ENOTSUPP;
@@ -275,7 +357,7 @@ ltq_etop_hw_init(struct net_device *dev)
ltq_dma_init_port(DMA_PORT_ETOP);
for (i = 0; i < MAX_DMA_CHAN; i++) {
- int irq = LTQ_DMA_CH0_INT + i;
+ int irq = LTQ_DMA_ETOP + i;
struct ltq_etop_chan *ch = &priv->ch[i];
ch->idx = ch->dma.nr = i;
@@ -339,6 +421,39 @@ static const struct ethtool_ops ltq_etop
};
static int
+ltq_etop_mdio_wr_xr9(struct mii_bus *bus, int phy_addr,
+ int phy_reg, u16 phy_data)
+{
+ u32 val = MDIO_XR9_REQUEST | MDIO_XR9_WRITE |
+ (phy_data << MDIO_XR9_WR_OFFSET) |
+ ((phy_addr & MDIO_XR9_ADDR_MASK) << MDIO_XR9_ADDR_OFFSET) |
+ ((phy_reg & MDIO_XR9_REG_MASK) << MDIO_XR9_REG_OFFSET);
+
+ while (ltq_gbit_r32(LTQ_GBIT_MDIO_CTL) & MDIO_XR9_REQUEST)
+ ;
+ ltq_gbit_w32(val, LTQ_GBIT_MDIO_CTL);
+ while (ltq_gbit_r32(LTQ_GBIT_MDIO_CTL) & MDIO_XR9_REQUEST)
+ ;
+ return 0;
+}
+
+static int
+ltq_etop_mdio_rd_xr9(struct mii_bus *bus, int phy_addr, int phy_reg)
+{
+ u32 val = MDIO_XR9_REQUEST | MDIO_XR9_READ |
+ ((phy_addr & MDIO_XR9_ADDR_MASK) << MDIO_XR9_ADDR_OFFSET) |
+ ((phy_reg & MDIO_XR9_REG_MASK) << MDIO_XR9_REG_OFFSET);
+
+ while (ltq_gbit_r32(LTQ_GBIT_MDIO_CTL) & MDIO_XR9_REQUEST)
+ ;
+ ltq_gbit_w32(val, LTQ_GBIT_MDIO_CTL);
+ while (ltq_gbit_r32(LTQ_GBIT_MDIO_CTL) & MDIO_XR9_REQUEST)
+ ;
+ val = ltq_gbit_r32(LTQ_GBIT_MDIO_DATA) & MDIO_XR9_RD_MASK;
+ return val;
+}
+
+static int
ltq_etop_mdio_wr(struct mii_bus *bus, int phy_addr, int phy_reg, u16 phy_data)
{
u32 val = MDIO_REQUEST |
@@ -379,14 +494,11 @@ ltq_etop_mdio_probe(struct net_device *d
{
struct ltq_etop_priv *priv = netdev_priv(dev);
struct phy_device *phydev = NULL;
- int phy_addr;
- for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) {
- if (priv->mii_bus->phy_map[phy_addr]) {
- phydev = priv->mii_bus->phy_map[phy_addr];
- break;
- }
- }
+ if (ltq_is_ase())
+ phydev = priv->mii_bus->phy_map[8];
+ else
+ phydev = priv->mii_bus->phy_map[0];
if (!phydev) {
netdev_err(dev, "no PHY found\n");
@@ -408,6 +520,9 @@ ltq_etop_mdio_probe(struct net_device *d
| SUPPORTED_Autoneg
| SUPPORTED_MII
| SUPPORTED_TP);
+ if (ltq_has_gbit())
+ phydev->supported &= SUPPORTED_1000baseT_Half
+ | SUPPORTED_1000baseT_Full;
phydev->advertising = phydev->supported;
priv->phydev = phydev;
@@ -433,8 +548,13 @@ ltq_etop_mdio_init(struct net_device *de
}
priv->mii_bus->priv = dev;
- priv->mii_bus->read = ltq_etop_mdio_rd;
- priv->mii_bus->write = ltq_etop_mdio_wr;
+ if (ltq_has_gbit()) {
+ priv->mii_bus->read = ltq_etop_mdio_rd_xr9;
+ priv->mii_bus->write = ltq_etop_mdio_wr_xr9;
+ } else {
+ priv->mii_bus->read = ltq_etop_mdio_rd;
+ priv->mii_bus->write = ltq_etop_mdio_wr;
+ }
priv->mii_bus->name = "ltq_mii";
snprintf(priv->mii_bus->id, MII_BUS_ID_SIZE, "%x", 0);
priv->mii_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
@@ -524,9 +644,9 @@ ltq_etop_tx(struct sk_buff *skb, struct
struct ltq_etop_priv *priv = netdev_priv(dev);
struct ltq_etop_chan *ch = &priv->ch[(queue << 1) | 1];
struct ltq_dma_desc *desc = &ch->dma.desc_base[ch->dma.desc];
- int len;
unsigned long flags;
u32 byte_offset;
+ int len;
len = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len;
@@ -700,7 +820,7 @@ ltq_etop_probe(struct platform_device *p
{
struct net_device *dev;
struct ltq_etop_priv *priv;
- struct resource *res;
+ struct resource *res, *gbit_res;
int err;
int i;
@@ -728,6 +848,23 @@ ltq_etop_probe(struct platform_device *p
goto err_out;
}
+ if (ltq_has_gbit()) {
+ gbit_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ if (!gbit_res) {
+ dev_err(&pdev->dev, "failed to get gbit resource\n");
+ err = -ENOENT;
+ goto err_out;
+ }
+ ltq_gbit_membase = devm_ioremap_nocache(&pdev->dev,
+ gbit_res->start, resource_size(gbit_res));
+ if (!ltq_gbit_membase) {
+ dev_err(&pdev->dev, "failed to remap gigabit switch %d\n",
+ pdev->id);
+ err = -ENOMEM;
+ goto err_out;
+ }
+ }
+
dev = alloc_etherdev_mq(sizeof(struct ltq_etop_priv), 4);
strcpy(dev->name, "eth%d");
dev->netdev_ops = &ltq_eth_netdev_ops;

View File

@ -1,62 +0,0 @@
From 2bad6512b242b3b5f41414a830d7224d504d0825 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Tue, 15 Nov 2011 14:52:21 +0100
Subject: [PATCH 19/73] NET: MIPS: lantiq: non existing phy was not handled
gracefully
The code blindly assumed that that a PHY device was present causing a BadVA.
In addition the driver should not fail to load incase no PHY was found.
Instead we print the following line and continue with no attached PHY.
etop: mdio probe failed
Signed-off-by: John Crispin <blogic@openwrt.org>
Cc: netdev@vger.kernel.org
---
drivers/net/ethernet/lantiq_etop.c | 14 ++++++++------
1 files changed, 8 insertions(+), 6 deletions(-)
--- a/drivers/net/ethernet/lantiq_etop.c
+++ b/drivers/net/ethernet/lantiq_etop.c
@@ -612,7 +612,8 @@ ltq_etop_open(struct net_device *dev)
ltq_dma_open(&ch->dma);
napi_enable(&ch->napi);
}
- phy_start(priv->phydev);
+ if (priv->phydev)
+ phy_start(priv->phydev);
netif_tx_start_all_queues(dev);
return 0;
}
@@ -624,7 +625,8 @@ ltq_etop_stop(struct net_device *dev)
int i;
netif_tx_stop_all_queues(dev);
- phy_stop(priv->phydev);
+ if (priv->phydev)
+ phy_stop(priv->phydev);
for (i = 0; i < MAX_DMA_CHAN; i++) {
struct ltq_etop_chan *ch = &priv->ch[i];
@@ -770,9 +772,10 @@ ltq_etop_init(struct net_device *dev)
if (err)
goto err_netdev;
ltq_etop_set_multicast_list(dev);
- err = ltq_etop_mdio_init(dev);
- if (err)
- goto err_netdev;
+ if (!ltq_etop_mdio_init(dev))
+ dev->ethtool_ops = &ltq_etop_ethtool_ops;
+ else
+ pr_warn("etop: mdio probe failed\n");;
return 0;
err_netdev:
@@ -868,7 +871,6 @@ ltq_etop_probe(struct platform_device *p
dev = alloc_etherdev_mq(sizeof(struct ltq_etop_priv), 4);
strcpy(dev->name, "eth%d");
dev->netdev_ops = &ltq_eth_netdev_ops;
- dev->ethtool_ops = &ltq_etop_ethtool_ops;
priv = netdev_priv(dev);
priv->res = res;
priv->pldata = dev_get_platdata(&pdev->dev);

View File

@ -1,66 +0,0 @@
From 641dd8688489331068ff4a3f35ee0ad3ca02dbd2 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Tue, 15 Nov 2011 15:56:06 +0100
Subject: [PATCH 20/73] NET: MIPS: lantiq: return value of request_irq was not
handled gracefully
The return values of request_irq() were not checked leading to the following
error message.
drivers/net/ethernet/lantiq_etop.c: In function 'ltq_etop_hw_init':
drivers/net/ethernet/lantiq_etop.c:368:15: warning: ignoring return value of 'request_irq', declared with attribute warn_unused_result
drivers/net/ethernet/lantiq_etop.c:377:15: warning: ignoring return value of 'request_irq', declared with attribute warn_unused_result
Signed-off-by: John Crispin <blogic@openwrt.org>
Cc: netdev@vger.kernel.org
---
drivers/net/ethernet/lantiq_etop.c | 14 ++++++++------
1 files changed, 8 insertions(+), 6 deletions(-)
--- a/drivers/net/ethernet/lantiq_etop.c
+++ b/drivers/net/ethernet/lantiq_etop.c
@@ -312,6 +312,7 @@ ltq_etop_hw_init(struct net_device *dev)
{
struct ltq_etop_priv *priv = netdev_priv(dev);
unsigned int mii_mode = priv->pldata->mii_mode;
+ int err = 0;
int i;
ltq_pmu_enable(PMU_PPE);
@@ -356,7 +357,7 @@ ltq_etop_hw_init(struct net_device *dev)
ltq_dma_init_port(DMA_PORT_ETOP);
- for (i = 0; i < MAX_DMA_CHAN; i++) {
+ for (i = 0; i < MAX_DMA_CHAN && !err; i++) {
int irq = LTQ_DMA_ETOP + i;
struct ltq_etop_chan *ch = &priv->ch[i];
@@ -364,21 +365,22 @@ ltq_etop_hw_init(struct net_device *dev)
if (IS_TX(i)) {
ltq_dma_alloc_tx(&ch->dma);
- request_irq(irq, ltq_etop_dma_irq, IRQF_DISABLED,
+ err = request_irq(irq, ltq_etop_dma_irq, IRQF_DISABLED,
"etop_tx", priv);
} else if (IS_RX(i)) {
ltq_dma_alloc_rx(&ch->dma);
for (ch->dma.desc = 0; ch->dma.desc < LTQ_DESC_NUM;
ch->dma.desc++)
if (ltq_etop_alloc_skb(ch))
- return -ENOMEM;
+ err = -ENOMEM;
ch->dma.desc = 0;
- request_irq(irq, ltq_etop_dma_irq, IRQF_DISABLED,
+ err = request_irq(irq, ltq_etop_dma_irq, IRQF_DISABLED,
"etop_rx", priv);
}
- ch->dma.irq = irq;
+ if (!err)
+ ch->dma.irq = irq;
}
- return 0;
+ return err;
}
static void

View File

@ -1,259 +0,0 @@
From 20ed991ce59030544426dc3422da7ee76667537b Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Thu, 8 Mar 2012 08:37:25 +0100
Subject: [PATCH 21/73] MIPS: lantiq: use devres managed gpios
3.2 introduced devm_request_gpio() to allow managed gpios.
The devres api requires a struct device pointer to work. Add a parameter to ltq_gpio_request()
so that managed gpios can work.
Signed-off-by: John Crispin <blogic@openwrt.org>
---
.../include/asm/mach-lantiq/falcon/lantiq_soc.h | 4 +---
arch/mips/include/asm/mach-lantiq/lantiq.h | 4 ++++
.../mips/include/asm/mach-lantiq/xway/lantiq_soc.h | 3 ---
arch/mips/lantiq/falcon/gpio.c | 4 ++--
arch/mips/lantiq/falcon/prom.c | 7 -------
arch/mips/lantiq/xway/gpio.c | 4 ++--
arch/mips/lantiq/xway/gpio_stp.c | 13 ++++++++-----
arch/mips/pci/pci-lantiq.c | 18 ++++++++++--------
drivers/net/ethernet/lantiq_etop.c | 9 ++++++---
drivers/tty/serial/lantiq.c | 12 ++++++++++++
10 files changed, 45 insertions(+), 33 deletions(-)
--- a/arch/mips/include/asm/mach-lantiq/falcon/lantiq_soc.h
+++ b/arch/mips/include/asm/mach-lantiq/falcon/lantiq_soc.h
@@ -126,9 +126,7 @@ extern __iomem void *ltq_sys1_membase;
#define ltq_sys1_w32_mask(clear, set, reg) \
ltq_sys1_w32((ltq_sys1_r32(reg) & ~(clear)) | (set), reg)
-/* gpio_request wrapper to help configure the pin */
-extern int ltq_gpio_request(unsigned int pin, unsigned int mux,
- unsigned int dir, const char *name);
+/* gpio wrapper to help configure the pin muxing */
extern int ltq_gpio_mux_set(unsigned int pin, unsigned int mux);
/* to keep the irq code generic we need to define these to 0 as falcon
--- a/arch/mips/include/asm/mach-lantiq/lantiq.h
+++ b/arch/mips/include/asm/mach-lantiq/lantiq.h
@@ -37,6 +37,10 @@ extern unsigned int ltq_get_soc_type(voi
/* spinlock all ebu i/o */
extern spinlock_t ebu_lock;
+/* request a non-gpio and set the PIO config */
+extern int ltq_gpio_request(struct device *dev, unsigned int pin,
+ unsigned int mux, unsigned int dir, const char *name);
+
/* some irq helpers */
extern void ltq_disable_irq(struct irq_data *data);
extern void ltq_mask_and_ack_irq(struct irq_data *data);
--- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
+++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
@@ -145,9 +145,6 @@
extern __iomem void *ltq_ebu_membase;
extern __iomem void *ltq_cgu_membase;
-/* request a non-gpio and set the PIO config */
-extern int ltq_gpio_request(unsigned int pin, unsigned int mux,
- unsigned int dir, const char *name);
extern void ltq_pmu_enable(unsigned int module);
extern void ltq_pmu_disable(unsigned int module);
extern void ltq_cgu_enable(unsigned int clk);
--- a/arch/mips/lantiq/falcon/gpio.c
+++ b/arch/mips/lantiq/falcon/gpio.c
@@ -97,7 +97,7 @@ int ltq_gpio_mux_set(unsigned int pin, u
}
EXPORT_SYMBOL(ltq_gpio_mux_set);
-int ltq_gpio_request(unsigned int pin, unsigned int mux,
+int ltq_gpio_request(struct device *dev, unsigned int pin, unsigned int mux,
unsigned int dir, const char *name)
{
int port = pin / 100;
@@ -106,7 +106,7 @@ int ltq_gpio_request(unsigned int pin, u
if (offset >= PINS_PER_PORT || port >= MAX_PORTS)
return -EINVAL;
- if (gpio_request(pin, name)) {
+ if (devm_gpio_request(dev, pin, name)) {
pr_err("failed to setup lantiq gpio: %s\n", name);
return -EBUSY;
}
--- a/arch/mips/lantiq/falcon/prom.c
+++ b/arch/mips/lantiq/falcon/prom.c
@@ -27,9 +27,6 @@
#define TYPE_SHIFT 26
#define TYPE_MASK 0x3C000000
-#define MUXC_SIF_RX_PIN 112
-#define MUXC_SIF_TX_PIN 113
-
/* this parameter allows us enable/disable asc1 via commandline */
static int register_asc1;
static int __init
@@ -48,10 +45,6 @@ ltq_soc_setup(void)
falcon_register_gpio();
if (register_asc1) {
ltq_register_asc(1);
- if (ltq_gpio_request(MUXC_SIF_RX_PIN, 3, 0, "asc1-rx"))
- pr_err("failed to request asc1-rx");
- if (ltq_gpio_request(MUXC_SIF_TX_PIN, 3, 1, "asc1-tx"))
- pr_err("failed to request asc1-tx");
ltq_sysctl_activate(SYSCTL_SYS1, ACTS_ASC1_ACT);
}
}
--- a/arch/mips/lantiq/xway/gpio.c
+++ b/arch/mips/lantiq/xway/gpio.c
@@ -50,14 +50,14 @@ int irq_to_gpio(unsigned int gpio)
}
EXPORT_SYMBOL(irq_to_gpio);
-int ltq_gpio_request(unsigned int pin, unsigned int mux,
+int ltq_gpio_request(struct device *dev, unsigned int pin, unsigned int mux,
unsigned int dir, const char *name)
{
int id = 0;
if (pin >= (MAX_PORTS * PINS_PER_PORT))
return -EINVAL;
- if (gpio_request(pin, name)) {
+ if (devm_gpio_request(dev, pin, name)) {
pr_err("failed to setup lantiq gpio: %s\n", name);
return -EBUSY;
}
--- a/arch/mips/lantiq/xway/gpio_stp.c
+++ b/arch/mips/lantiq/xway/gpio_stp.c
@@ -80,11 +80,6 @@ static struct gpio_chip ltq_stp_chip = {
static int ltq_stp_hw_init(void)
{
- /* the 3 pins used to control the external stp */
- ltq_gpio_request(4, 2, 1, "stp-st");
- ltq_gpio_request(5, 2, 1, "stp-d");
- ltq_gpio_request(6, 2, 1, "stp-sh");
-
/* sane defaults */
ltq_stp_w32(0, LTQ_STP_AR);
ltq_stp_w32(0, LTQ_STP_CPU0);
@@ -133,6 +128,14 @@ static int __devinit ltq_stp_probe(struc
dev_err(&pdev->dev, "failed to remap STP memory\n");
return -ENOMEM;
}
+
+ /* the 3 pins used to control the external stp */
+ if (ltq_gpio_request(&pdev->dev, 4, 2, 1, "stp-st") ||
+ ltq_gpio_request(&pdev->dev, 5, 2, 1, "stp-d") ||
+ ltq_gpio_request(&pdev->dev, 6, 2, 1, "stp-sh")) {
+ dev_err(&pdev->dev, "failed to request needed gpios\n");
+ return -EBUSY;
+ }
ret = gpiochip_add(&ltq_stp_chip);
if (!ret)
ret = ltq_stp_hw_init();
--- a/arch/mips/pci/pci-lantiq.c
+++ b/arch/mips/pci/pci-lantiq.c
@@ -150,24 +150,26 @@ static u32 ltq_calc_bar11mask(void)
return bar11mask;
}
-static void ltq_pci_setup_gpio(int gpio)
+static void ltq_pci_setup_gpio(struct device *dev)
{
+ struct ltq_pci_data *conf = (struct ltq_pci_data *) dev->platform_data;
int i;
for (i = 0; i < ARRAY_SIZE(ltq_pci_gpio_map); i++) {
- if (gpio & (1 << i)) {
- ltq_gpio_request(ltq_pci_gpio_map[i].pin,
+ if (conf->gpio & (1 << i)) {
+ ltq_gpio_request(dev, ltq_pci_gpio_map[i].pin,
ltq_pci_gpio_map[i].mux,
ltq_pci_gpio_map[i].dir,
ltq_pci_gpio_map[i].name);
}
}
- ltq_gpio_request(21, 0, 1, "pci-reset");
- ltq_pci_req_mask = (gpio >> PCI_REQ_SHIFT) & PCI_REQ_MASK;
+ ltq_gpio_request(dev, 21, 0, 1, "pci-reset");
+ ltq_pci_req_mask = (conf->gpio >> PCI_REQ_SHIFT) & PCI_REQ_MASK;
}
-static int __devinit ltq_pci_startup(struct ltq_pci_data *conf)
+static int __devinit ltq_pci_startup(struct device *dev)
{
u32 temp_buffer;
+ struct ltq_pci_data *conf = (struct ltq_pci_data *) dev->platform_data;
/* set clock to 33Mhz */
if (ltq_is_ar9()) {
@@ -190,7 +192,7 @@ static int __devinit ltq_pci_startup(str
}
/* setup pci clock and gpis used by pci */
- ltq_pci_setup_gpio(conf->gpio);
+ ltq_pci_setup_gpio(dev);
/* enable auto-switching between PCI and EBU */
ltq_pci_w32(0xa, PCI_CR_CLK_CTRL);
@@ -275,7 +277,7 @@ static int __devinit ltq_pci_probe(struc
ioremap_nocache(LTQ_PCI_CFG_BASE, LTQ_PCI_CFG_BASE);
ltq_pci_controller.io_map_base =
(unsigned long)ioremap(LTQ_PCI_IO_BASE, LTQ_PCI_IO_SIZE - 1);
- ltq_pci_startup(ltq_pci_data);
+ ltq_pci_startup(&pdev->dev);
register_pci_controller(&ltq_pci_controller);
return 0;
--- a/drivers/net/ethernet/lantiq_etop.c
+++ b/drivers/net/ethernet/lantiq_etop.c
@@ -291,9 +291,6 @@ ltq_etop_gbit_init(void)
{
ltq_pmu_enable(PMU_SWITCH);
- ltq_gpio_request(42, 2, 1, "MDIO");
- ltq_gpio_request(43, 2, 1, "MDC");
-
ltq_gbit_w32_mask(0, GCTL0_SE, LTQ_GBIT_GCTL0);
/** Disable MDIO auto polling mode */
ltq_gbit_w32_mask(0, PX_CTL_DMDIO, LTQ_GBIT_P0_CTL);
@@ -868,6 +865,12 @@ ltq_etop_probe(struct platform_device *p
err = -ENOMEM;
goto err_out;
}
+ if (ltq_gpio_request(&pdev->dev, 42, 2, 1, "MDIO") ||
+ ltq_gpio_request(&pdev->dev, 43, 2, 1, "MDC")) {
+ dev_err(&pdev->dev, "failed to request MDIO gpios\n");
+ err = -EBUSY;
+ goto err_out;
+ }
}
dev = alloc_etherdev_mq(sizeof(struct ltq_etop_priv), 4);
--- a/drivers/tty/serial/lantiq.c
+++ b/drivers/tty/serial/lantiq.c
@@ -107,6 +107,9 @@
#define ASCFSTAT_TXFREEMASK 0x3F000000
#define ASCFSTAT_TXFREEOFF 24
+#define MUXC_SIF_RX_PIN 112
+#define MUXC_SIF_TX_PIN 113
+
static void lqasc_tx_chars(struct uart_port *port);
static struct ltq_uart_port *lqasc_port[MAXPORTS];
static struct uart_driver lqasc_reg;
@@ -529,6 +532,15 @@ lqasc_request_port(struct uart_port *por
if (port->membase == NULL)
return -ENOMEM;
}
+ if (ltq_is_falcon() && (port->line == 1)) {
+ struct ltq_uart_port *ltq_port = lqasc_port[pdev->id];
+ if (ltq_gpio_request(&pdev->dev, MUXC_SIF_RX_PIN,
+ 3, 0, "asc1-rx"))
+ return -EBUSY;
+ if (ltq_gpio_request(&pdev->dev, MUXC_SIF_TX_PIN,
+ 3, 1, "asc1-tx"))
+ return -EBUSY;
+ }
return 0;
}

View File

@ -1,43 +0,0 @@
From 98f3072e25ba8b7552e51309b05b8c643725dec9 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Thu, 16 Feb 2012 20:23:36 +0100
Subject: [PATCH 22/73] MIPS: add clkdev.h
For clkdev to work on MIPS we need this file
include/linux/clkdev.h:#include <asm/clkdev.h>
Signed-off-by: John Crispin <blogic@openwrt.org>
---
arch/mips/include/asm/clkdev.h | 25 +++++++++++++++++++++++++
1 files changed, 25 insertions(+), 0 deletions(-)
create mode 100644 arch/mips/include/asm/clkdev.h
--- /dev/null
+++ b/arch/mips/include/asm/clkdev.h
@@ -0,0 +1,25 @@
+/*
+ * based on arch/arm/include/asm/clkdev.h
+ *
+ * Copyright (C) 2008 Russell King.
+ *
+ * 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.
+ *
+ * Helper for the clk API to assist looking up a struct clk.
+ */
+#ifndef __ASM_CLKDEV_H
+#define __ASM_CLKDEV_H
+
+#include <linux/slab.h>
+
+#define __clk_get(clk) ({ 1; })
+#define __clk_put(clk) do { } while (0)
+
+static inline struct clk_lookup_alloc *__clkdev_alloc(size_t size)
+{
+ return kzalloc(size, GFP_KERNEL);
+}
+
+#endif

View File

@ -1,52 +0,0 @@
From ba0e580e5af68726cea08990891fc4abf1cfcde4 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Tue, 21 Feb 2012 14:25:03 +0100
Subject: [PATCH 23/73] MIPS: lantiq: helper functions for SoC detection
Add additional functions for runtime soc detection. We need these for the
serial driver.
Signed-off-by: John Crispin <blogic@openwrt.org>
---
.../include/asm/mach-lantiq/falcon/lantiq_soc.h | 16 ++++++++++++++--
.../mips/include/asm/mach-lantiq/xway/lantiq_soc.h | 5 +++++
2 files changed, 19 insertions(+), 2 deletions(-)
--- a/arch/mips/include/asm/mach-lantiq/falcon/lantiq_soc.h
+++ b/arch/mips/include/asm/mach-lantiq/falcon/lantiq_soc.h
@@ -134,8 +134,20 @@ extern int ltq_gpio_mux_set(unsigned int
#define LTQ_EIU_BASE_ADDR 0
#define LTQ_EBU_PCC_ISTAT 0
-#define ltq_is_ar9() 0
-#define ltq_is_vr9() 0
+static inline int ltq_is_ar9(void)
+{
+ return 0;
+}
+
+static inline int ltq_is_vr9(void)
+{
+ return 0;
+}
+
+static inline int ltq_is_falcon(void)
+{
+ return 1;
+}
#endif /* CONFIG_SOC_FALCON */
#endif /* _LTQ_XWAY_H__ */
--- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
+++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
@@ -164,5 +164,10 @@ static inline int ltq_is_vr9(void)
return (ltq_get_soc_type() == SOC_TYPE_VR9);
}
+static inline int ltq_is_falcon(void)
+{
+ return 0;
+}
+
#endif /* CONFIG_SOC_TYPE_XWAY */
#endif /* _LTQ_XWAY_H__ */

View File

@ -1,285 +0,0 @@
From a5124da58605e1717b57953bce56301ea0b33d25 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Thu, 8 Mar 2012 08:39:06 +0100
Subject: [PATCH 24/73] MIPS: lantiq: convert to clkdev api
* Change setup from HAVE_CLK -> HAVE_MACH_CLKDEV/CLKDEV_LOOKUP
* Add clk_activate/clk_deactivate
* Add better error paths to the clk_*() functions
* Change the way our static clocks are referenced
Signed-off-by: John Crispin <blogic@openwrt.org>
---
arch/mips/Kconfig | 3 +-
arch/mips/include/asm/mach-lantiq/lantiq.h | 20 ++----
arch/mips/lantiq/clk.c | 96 +++++++++++++++------------
arch/mips/lantiq/clk.h | 52 ++++++++++++++-
arch/mips/lantiq/prom.c | 1 -
5 files changed, 111 insertions(+), 61 deletions(-)
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -225,7 +225,8 @@ config LANTIQ
select ARCH_REQUIRE_GPIOLIB
select SWAP_IO_SPACE
select BOOT_RAW
- select HAVE_CLK
+ select HAVE_MACH_CLKDEV
+ select CLKDEV_LOOKUP
select HAVE_OPROFILE
select MIPS_MACHINE
--- a/arch/mips/include/asm/mach-lantiq/lantiq.h
+++ b/arch/mips/include/asm/mach-lantiq/lantiq.h
@@ -9,6 +9,7 @@
#define _LANTIQ_H__
#include <linux/irq.h>
+#include <linux/clk.h>
#include <linux/ioport.h>
/* generic reg access functions */
@@ -22,18 +23,6 @@
extern unsigned int ltq_get_cpu_ver(void);
extern unsigned int ltq_get_soc_type(void);
-/* clock speeds */
-#define CLOCK_60M 60000000
-#define CLOCK_83M 83333333
-#define CLOCK_100M 100000000
-#define CLOCK_111M 111111111
-#define CLOCK_133M 133333333
-#define CLOCK_167M 166666667
-#define CLOCK_200M 200000000
-#define CLOCK_266M 266666666
-#define CLOCK_333M 333333333
-#define CLOCK_400M 400000000
-
/* spinlock all ebu i/o */
extern spinlock_t ebu_lock;
@@ -46,6 +35,13 @@ extern void ltq_disable_irq(struct irq_d
extern void ltq_mask_and_ack_irq(struct irq_data *data);
extern void ltq_enable_irq(struct irq_data *data);
+/* clock handling */
+extern int clk_activate(struct clk *clk);
+extern void clk_deactivate(struct clk *clk);
+extern struct clk *clk_get_cpu(void);
+extern struct clk *clk_get_fpi(void);
+extern struct clk *clk_get_io(void);
+
/* find out what caused the last cpu reset */
extern int ltq_reset_cause(void);
--- a/arch/mips/lantiq/clk.c
+++ b/arch/mips/lantiq/clk.c
@@ -12,6 +12,7 @@
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/clk.h>
+#include <linux/clkdev.h>
#include <linux/err.h>
#include <linux/list.h>
@@ -24,33 +25,29 @@
#include "clk.h"
#include "prom.h"
-struct clk {
- const char *name;
- unsigned long rate;
- unsigned long (*get_rate) (void);
-};
+/* lantiq socs have 3 static clocks */
+static struct clk cpu_clk_generic[3];
-static struct clk *cpu_clk;
-static int cpu_clk_cnt;
+void clkdev_add_static(unsigned long cpu, unsigned long fpi, unsigned long io)
+{
+ cpu_clk_generic[0].rate = cpu;
+ cpu_clk_generic[1].rate = fpi;
+ cpu_clk_generic[2].rate = io;
+}
-/* lantiq socs have 3 static clocks */
-static struct clk cpu_clk_generic[] = {
- {
- .name = "cpu",
- .get_rate = ltq_get_cpu_hz,
- }, {
- .name = "fpi",
- .get_rate = ltq_get_fpi_hz,
- }, {
- .name = "io",
- .get_rate = ltq_get_io_region_clock,
- },
-};
+struct clk *clk_get_cpu(void)
+{
+ return &cpu_clk_generic[0];
+}
+
+struct clk *clk_get_fpi(void)
+{
+ return &cpu_clk_generic[1];
+}
-void clk_init(void)
+struct clk *clk_get_io(void)
{
- cpu_clk = cpu_clk_generic;
- cpu_clk_cnt = ARRAY_SIZE(cpu_clk_generic);
+ return &cpu_clk_generic[2];
}
static inline int clk_good(struct clk *clk)
@@ -73,36 +70,49 @@ unsigned long clk_get_rate(struct clk *c
}
EXPORT_SYMBOL(clk_get_rate);
-struct clk *clk_get(struct device *dev, const char *id)
+int clk_enable(struct clk *clk)
{
- int i;
+ if (unlikely(!clk_good(clk)))
+ return -1;
- for (i = 0; i < cpu_clk_cnt; i++)
- if (!strcmp(id, cpu_clk[i].name))
- return &cpu_clk[i];
- BUG();
- return ERR_PTR(-ENOENT);
+ if (clk->enable)
+ return clk->enable(clk);
+
+ return -1;
}
-EXPORT_SYMBOL(clk_get);
+EXPORT_SYMBOL(clk_enable);
-void clk_put(struct clk *clk)
+void clk_disable(struct clk *clk)
{
- /* not used */
+ if (unlikely(!clk_good(clk)))
+ return;
+
+ if (clk->disable)
+ clk->disable(clk);
}
-EXPORT_SYMBOL(clk_put);
+EXPORT_SYMBOL(clk_disable);
-int clk_enable(struct clk *clk)
+int clk_activate(struct clk *clk)
{
- /* not used */
- return 0;
+ if (unlikely(!clk_good(clk)))
+ return -1;
+
+ if (clk->activate)
+ return clk->activate(clk);
+
+ return -1;
}
-EXPORT_SYMBOL(clk_enable);
+EXPORT_SYMBOL(clk_activate);
-void clk_disable(struct clk *clk)
+void clk_deactivate(struct clk *clk)
{
- /* not used */
+ if (unlikely(!clk_good(clk)))
+ return;
+
+ if (clk->deactivate)
+ clk->deactivate(clk);
}
-EXPORT_SYMBOL(clk_disable);
+EXPORT_SYMBOL(clk_deactivate);
static inline u32 ltq_get_counter_resolution(void)
{
@@ -126,7 +136,7 @@ void __init plat_time_init(void)
ltq_soc_init();
- clk = clk_get(0, "cpu");
+ clk = clk_get_cpu();
mips_hpt_frequency = clk_get_rate(clk) / ltq_get_counter_resolution();
write_c0_compare(read_c0_count());
pr_info("CPU Clock: %ldMHz\n", clk_get_rate(clk) / 1000000);
--- a/arch/mips/lantiq/clk.h
+++ b/arch/mips/lantiq/clk.h
@@ -9,10 +9,54 @@
#ifndef _LTQ_CLK_H__
#define _LTQ_CLK_H__
-extern void clk_init(void);
+#include <linux/clkdev.h>
-extern unsigned long ltq_get_cpu_hz(void);
-extern unsigned long ltq_get_fpi_hz(void);
-extern unsigned long ltq_get_io_region_clock(void);
+/* clock speeds */
+#define CLOCK_60M 60000000
+#define CLOCK_62_5M 62500000
+#define CLOCK_83M 83333333
+#define CLOCK_83_5M 83500000
+#define CLOCK_98_304M 98304000
+#define CLOCK_100M 100000000
+#define CLOCK_111M 111111111
+#define CLOCK_125M 125000000
+#define CLOCK_133M 133333333
+#define CLOCK_150M 150000000
+#define CLOCK_166M 166666666
+#define CLOCK_167M 166666667
+#define CLOCK_196_608M 196608000
+#define CLOCK_200M 200000000
+#define CLOCK_250M 250000000
+#define CLOCK_266M 266666666
+#define CLOCK_300M 300000000
+#define CLOCK_333M 333333333
+#define CLOCK_393M 393215332
+#define CLOCK_400M 400000000
+#define CLOCK_500M 500000000
+#define CLOCK_600M 600000000
+
+struct clk {
+ struct clk_lookup cl;
+ unsigned long rate;
+ unsigned long (*get_rate) (void);
+ unsigned int module;
+ unsigned int bits;
+ int (*enable) (struct clk *clk);
+ void (*disable) (struct clk *clk);
+ int (*activate) (struct clk *clk);
+ void (*deactivate) (struct clk *clk);
+ void (*reboot) (struct clk *clk);
+};
+
+extern void clkdev_add_static(unsigned long cpu, unsigned long fpi,
+ unsigned long io);
+
+extern unsigned long ltq_danube_cpu_hz(void);
+extern unsigned long ltq_danube_fpi_hz(void);
+extern unsigned long ltq_danube_io_region_clock(void);
+
+extern unsigned long ltq_vr9_cpu_hz(void);
+extern unsigned long ltq_vr9_fpi_hz(void);
+extern unsigned long ltq_vr9_io_region_clock(void);
#endif
--- a/arch/mips/lantiq/prom.c
+++ b/arch/mips/lantiq/prom.c
@@ -103,7 +103,6 @@ EXPORT_SYMBOL(ltq_remap_resource);
void __init prom_init(void)
{
ltq_soc_detect(&soc_info);
- clk_init();
snprintf(soc_info.sys_type, LTQ_SYS_TYPE_LEN - 1, "%s rev %s",
soc_info.name, soc_info.rev_type);
soc_info.sys_type[LTQ_SYS_TYPE_LEN - 1] = '\0';

View File

@ -1,718 +0,0 @@
From b6a73eaeb10726bb30584aa8aa4620061db653ba Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Thu, 8 Mar 2012 11:18:22 +0100
Subject: [PATCH 25/73] MIPS: lantiq: convert xway to clkdev api
Unify xway/ase clock code and add clkdev hooks to sysctrl.c
Signed-off-by: John Crispin <blogic@openwrt.org>
---
.../mips/include/asm/mach-lantiq/xway/lantiq_soc.h | 13 --
arch/mips/lantiq/xway/Makefile | 6 +-
arch/mips/lantiq/xway/clk-ase.c | 48 ----
arch/mips/lantiq/xway/clk-xway.c | 223 -------------------
arch/mips/lantiq/xway/clk.c | 227 ++++++++++++++++++++
arch/mips/lantiq/xway/sysctrl.c | 104 ++++++++-
6 files changed, 325 insertions(+), 296 deletions(-)
delete mode 100644 arch/mips/lantiq/xway/clk-ase.c
delete mode 100644 arch/mips/lantiq/xway/clk-xway.c
create mode 100644 arch/mips/lantiq/xway/clk.c
--- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
+++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
@@ -81,15 +81,6 @@
#define LTQ_PMU_BASE_ADDR 0x1F102000
#define LTQ_PMU_SIZE 0x1000
-#define PMU_DMA 0x0020
-#define PMU_EPHY 0x0080
-#define PMU_USB 0x8041
-#define PMU_LED 0x0800
-#define PMU_GPT 0x1000
-#define PMU_PPE 0x2000
-#define PMU_FPI 0x4000
-#define PMU_SWITCH 0x10000000
-
/* ETOP - ethernet */
#define LTQ_ETOP_BASE_ADDR 0x1E180000
#define LTQ_ETOP_SIZE 0x40000
@@ -145,10 +136,6 @@
extern __iomem void *ltq_ebu_membase;
extern __iomem void *ltq_cgu_membase;
-extern void ltq_pmu_enable(unsigned int module);
-extern void ltq_pmu_disable(unsigned int module);
-extern void ltq_cgu_enable(unsigned int clk);
-
static inline int ltq_is_ase(void)
{
return (ltq_get_soc_type() == SOC_TYPE_AMAZON_SE);
--- a/arch/mips/lantiq/xway/Makefile
+++ b/arch/mips/lantiq/xway/Makefile
@@ -1,7 +1,7 @@
-obj-y := sysctrl.o reset.o gpio.o gpio_stp.o gpio_ebu.o devices.o dma.o
+obj-y := sysctrl.o reset.o gpio.o gpio_stp.o gpio_ebu.o devices.o dma.o clk.o
-obj-$(CONFIG_SOC_XWAY) += clk-xway.o prom-xway.o
-obj-$(CONFIG_SOC_AMAZON_SE) += clk-ase.o prom-ase.o
+obj-$(CONFIG_SOC_XWAY) += prom-xway.o
+obj-$(CONFIG_SOC_AMAZON_SE) += prom-ase.o
obj-$(CONFIG_LANTIQ_MACH_EASY50712) += mach-easy50712.o
obj-$(CONFIG_LANTIQ_MACH_EASY50601) += mach-easy50601.o
--- a/arch/mips/lantiq/xway/clk-ase.c
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * 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.
- *
- * Copyright (C) 2011 John Crispin <blogic@openwrt.org>
- */
-
-#include <linux/io.h>
-#include <linux/export.h>
-#include <linux/init.h>
-#include <linux/clk.h>
-
-#include <asm/time.h>
-#include <asm/irq.h>
-#include <asm/div64.h>
-
-#include <lantiq_soc.h>
-
-/* cgu registers */
-#define LTQ_CGU_SYS 0x0010
-
-unsigned int ltq_get_io_region_clock(void)
-{
- return CLOCK_133M;
-}
-EXPORT_SYMBOL(ltq_get_io_region_clock);
-
-unsigned int ltq_get_fpi_bus_clock(int fpi)
-{
- return CLOCK_133M;
-}
-EXPORT_SYMBOL(ltq_get_fpi_bus_clock);
-
-unsigned int ltq_get_cpu_hz(void)
-{
- if (ltq_cgu_r32(LTQ_CGU_SYS) & (1 << 5))
- return CLOCK_266M;
- else
- return CLOCK_133M;
-}
-EXPORT_SYMBOL(ltq_get_cpu_hz);
-
-unsigned int ltq_get_fpi_hz(void)
-{
- return CLOCK_133M;
-}
-EXPORT_SYMBOL(ltq_get_fpi_hz);
--- a/arch/mips/lantiq/xway/clk-xway.c
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * 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.
- *
- * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
- */
-
-#include <linux/io.h>
-#include <linux/export.h>
-#include <linux/init.h>
-#include <linux/clk.h>
-
-#include <asm/time.h>
-#include <asm/irq.h>
-#include <asm/div64.h>
-
-#include <lantiq_soc.h>
-
-static unsigned int ltq_ram_clocks[] = {
- CLOCK_167M, CLOCK_133M, CLOCK_111M, CLOCK_83M };
-#define DDR_HZ ltq_ram_clocks[ltq_cgu_r32(LTQ_CGU_SYS) & 0x3]
-
-#define BASIC_FREQUENCY_1 35328000
-#define BASIC_FREQUENCY_2 36000000
-#define BASIS_REQUENCY_USB 12000000
-
-#define GET_BITS(x, msb, lsb) \
- (((x) & ((1 << ((msb) + 1)) - 1)) >> (lsb))
-
-#define LTQ_CGU_PLL0_CFG 0x0004
-#define LTQ_CGU_PLL1_CFG 0x0008
-#define LTQ_CGU_PLL2_CFG 0x000C
-#define LTQ_CGU_SYS 0x0010
-#define LTQ_CGU_UPDATE 0x0014
-#define LTQ_CGU_IF_CLK 0x0018
-#define LTQ_CGU_OSC_CON 0x001C
-#define LTQ_CGU_SMD 0x0020
-#define LTQ_CGU_CT1SR 0x0028
-#define LTQ_CGU_CT2SR 0x002C
-#define LTQ_CGU_PCMCR 0x0030
-#define LTQ_CGU_PCI_CR 0x0034
-#define LTQ_CGU_PD_PC 0x0038
-#define LTQ_CGU_FMR 0x003C
-
-#define CGU_PLL0_PHASE_DIVIDER_ENABLE \
- (ltq_cgu_r32(LTQ_CGU_PLL0_CFG) & (1 << 31))
-#define CGU_PLL0_BYPASS \
- (ltq_cgu_r32(LTQ_CGU_PLL0_CFG) & (1 << 30))
-#define CGU_PLL0_CFG_DSMSEL \
- (ltq_cgu_r32(LTQ_CGU_PLL0_CFG) & (1 << 28))
-#define CGU_PLL0_CFG_FRAC_EN \
- (ltq_cgu_r32(LTQ_CGU_PLL0_CFG) & (1 << 27))
-#define CGU_PLL1_SRC \
- (ltq_cgu_r32(LTQ_CGU_PLL1_CFG) & (1 << 31))
-#define CGU_PLL2_PHASE_DIVIDER_ENABLE \
- (ltq_cgu_r32(LTQ_CGU_PLL2_CFG) & (1 << 20))
-#define CGU_SYS_FPI_SEL (1 << 6)
-#define CGU_SYS_DDR_SEL 0x3
-#define CGU_PLL0_SRC (1 << 29)
-
-#define CGU_PLL0_CFG_PLLK GET_BITS(ltq_cgu_r32(LTQ_CGU_PLL0_CFG), 26, 17)
-#define CGU_PLL0_CFG_PLLN GET_BITS(ltq_cgu_r32(LTQ_CGU_PLL0_CFG), 12, 6)
-#define CGU_PLL0_CFG_PLLM GET_BITS(ltq_cgu_r32(LTQ_CGU_PLL0_CFG), 5, 2)
-#define CGU_PLL2_SRC GET_BITS(ltq_cgu_r32(LTQ_CGU_PLL2_CFG), 18, 17)
-#define CGU_PLL2_CFG_INPUT_DIV GET_BITS(ltq_cgu_r32(LTQ_CGU_PLL2_CFG), 16, 13)
-
-static unsigned int ltq_get_pll0_fdiv(void);
-
-static inline unsigned int get_input_clock(int pll)
-{
- switch (pll) {
- case 0:
- if (ltq_cgu_r32(LTQ_CGU_PLL0_CFG) & CGU_PLL0_SRC)
- return BASIS_REQUENCY_USB;
- else if (CGU_PLL0_PHASE_DIVIDER_ENABLE)
- return BASIC_FREQUENCY_1;
- else
- return BASIC_FREQUENCY_2;
- case 1:
- if (CGU_PLL1_SRC)
- return BASIS_REQUENCY_USB;
- else if (CGU_PLL0_PHASE_DIVIDER_ENABLE)
- return BASIC_FREQUENCY_1;
- else
- return BASIC_FREQUENCY_2;
- case 2:
- switch (CGU_PLL2_SRC) {
- case 0:
- return ltq_get_pll0_fdiv();
- case 1:
- return CGU_PLL2_PHASE_DIVIDER_ENABLE ?
- BASIC_FREQUENCY_1 :
- BASIC_FREQUENCY_2;
- case 2:
- return BASIS_REQUENCY_USB;
- }
- default:
- return 0;
- }
-}
-
-static inline unsigned int cal_dsm(int pll, unsigned int num, unsigned int den)
-{
- u64 res, clock = get_input_clock(pll);
-
- res = num * clock;
- do_div(res, den);
- return res;
-}
-
-static inline unsigned int mash_dsm(int pll, unsigned int M, unsigned int N,
- unsigned int K)
-{
- unsigned int num = ((N + 1) << 10) + K;
- unsigned int den = (M + 1) << 10;
-
- return cal_dsm(pll, num, den);
-}
-
-static inline unsigned int ssff_dsm_1(int pll, unsigned int M, unsigned int N,
- unsigned int K)
-{
- unsigned int num = ((N + 1) << 11) + K + 512;
- unsigned int den = (M + 1) << 11;
-
- return cal_dsm(pll, num, den);
-}
-
-static inline unsigned int ssff_dsm_2(int pll, unsigned int M, unsigned int N,
- unsigned int K)
-{
- unsigned int num = K >= 512 ?
- ((N + 1) << 12) + K - 512 : ((N + 1) << 12) + K + 3584;
- unsigned int den = (M + 1) << 12;
-
- return cal_dsm(pll, num, den);
-}
-
-static inline unsigned int dsm(int pll, unsigned int M, unsigned int N,
- unsigned int K, unsigned int dsmsel, unsigned int phase_div_en)
-{
- if (!dsmsel)
- return mash_dsm(pll, M, N, K);
- else if (!phase_div_en)
- return mash_dsm(pll, M, N, K);
- else
- return ssff_dsm_2(pll, M, N, K);
-}
-
-static inline unsigned int ltq_get_pll0_fosc(void)
-{
- if (CGU_PLL0_BYPASS)
- return get_input_clock(0);
- else
- return !CGU_PLL0_CFG_FRAC_EN
- ? dsm(0, CGU_PLL0_CFG_PLLM, CGU_PLL0_CFG_PLLN, 0,
- CGU_PLL0_CFG_DSMSEL,
- CGU_PLL0_PHASE_DIVIDER_ENABLE)
- : dsm(0, CGU_PLL0_CFG_PLLM, CGU_PLL0_CFG_PLLN,
- CGU_PLL0_CFG_PLLK, CGU_PLL0_CFG_DSMSEL,
- CGU_PLL0_PHASE_DIVIDER_ENABLE);
-}
-
-static unsigned int ltq_get_pll0_fdiv(void)
-{
- unsigned int div = CGU_PLL2_CFG_INPUT_DIV + 1;
-
- return (ltq_get_pll0_fosc() + (div >> 1)) / div;
-}
-
-unsigned int ltq_get_io_region_clock(void)
-{
- unsigned int ret = ltq_get_pll0_fosc();
-
- switch (ltq_cgu_r32(LTQ_CGU_PLL2_CFG) & CGU_SYS_DDR_SEL) {
- default:
- case 0:
- return (ret + 1) / 2;
- case 1:
- return (ret * 2 + 2) / 5;
- case 2:
- return (ret + 1) / 3;
- case 3:
- return (ret + 2) / 4;
- }
-}
-EXPORT_SYMBOL(ltq_get_io_region_clock);
-
-unsigned int ltq_get_fpi_bus_clock(int fpi)
-{
- unsigned int ret = ltq_get_io_region_clock();
-
- if ((fpi == 2) && (ltq_cgu_r32(LTQ_CGU_SYS) & CGU_SYS_FPI_SEL))
- ret >>= 1;
- return ret;
-}
-EXPORT_SYMBOL(ltq_get_fpi_bus_clock);
-
-unsigned int ltq_get_cpu_hz(void)
-{
- switch (ltq_cgu_r32(LTQ_CGU_SYS) & 0xc) {
- case 0:
- return CLOCK_333M;
- case 4:
- return DDR_HZ;
- case 8:
- return DDR_HZ << 1;
- default:
- return DDR_HZ >> 1;
- }
-}
-EXPORT_SYMBOL(ltq_get_cpu_hz);
-
-unsigned int ltq_get_fpi_hz(void)
-{
- unsigned int ddr_clock = DDR_HZ;
-
- if (ltq_cgu_r32(LTQ_CGU_SYS) & 0x40)
- return ddr_clock >> 1;
- return ddr_clock;
-}
-EXPORT_SYMBOL(ltq_get_fpi_hz);
--- /dev/null
+++ b/arch/mips/lantiq/xway/clk.c
@@ -0,0 +1,227 @@
+/*
+ * 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.
+ *
+ * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/io.h>
+#include <linux/export.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+
+#include <asm/time.h>
+#include <asm/irq.h>
+#include <asm/div64.h>
+
+#include <lantiq_soc.h>
+
+#include "../clk.h"
+
+static unsigned int ltq_ram_clocks[] = {
+ CLOCK_167M, CLOCK_133M, CLOCK_111M, CLOCK_83M };
+#define DDR_HZ ltq_ram_clocks[ltq_cgu_r32(LTQ_CGU_SYS) & 0x3]
+
+#define BASIC_FREQUENCY_1 35328000
+#define BASIC_FREQUENCY_2 36000000
+#define BASIS_REQUENCY_USB 12000000
+
+#define GET_BITS(x, msb, lsb) \
+ (((x) & ((1 << ((msb) + 1)) - 1)) >> (lsb))
+
+/* legacy xway clock */
+#define LTQ_CGU_PLL0_CFG 0x0004
+#define LTQ_CGU_PLL1_CFG 0x0008
+#define LTQ_CGU_PLL2_CFG 0x000C
+#define LTQ_CGU_SYS 0x0010
+#define LTQ_CGU_UPDATE 0x0014
+#define LTQ_CGU_IF_CLK 0x0018
+#define LTQ_CGU_OSC_CON 0x001C
+#define LTQ_CGU_SMD 0x0020
+#define LTQ_CGU_CT1SR 0x0028
+#define LTQ_CGU_CT2SR 0x002C
+#define LTQ_CGU_PCMCR 0x0030
+#define LTQ_CGU_PCI_CR 0x0034
+#define LTQ_CGU_PD_PC 0x0038
+#define LTQ_CGU_FMR 0x003C
+
+#define CGU_PLL0_PHASE_DIVIDER_ENABLE \
+ (ltq_cgu_r32(LTQ_CGU_PLL0_CFG) & (1 << 31))
+#define CGU_PLL0_BYPASS \
+ (ltq_cgu_r32(LTQ_CGU_PLL0_CFG) & (1 << 30))
+#define CGU_PLL0_CFG_DSMSEL \
+ (ltq_cgu_r32(LTQ_CGU_PLL0_CFG) & (1 << 28))
+#define CGU_PLL0_CFG_FRAC_EN \
+ (ltq_cgu_r32(LTQ_CGU_PLL0_CFG) & (1 << 27))
+#define CGU_PLL1_SRC \
+ (ltq_cgu_r32(LTQ_CGU_PLL1_CFG) & (1 << 31))
+#define CGU_PLL2_PHASE_DIVIDER_ENABLE \
+ (ltq_cgu_r32(LTQ_CGU_PLL2_CFG) & (1 << 20))
+#define CGU_SYS_FPI_SEL (1 << 6)
+#define CGU_SYS_DDR_SEL 0x3
+#define CGU_PLL0_SRC (1 << 29)
+
+#define CGU_PLL0_CFG_PLLK GET_BITS(ltq_cgu_r32(LTQ_CGU_PLL0_CFG), 26, 17)
+#define CGU_PLL0_CFG_PLLN GET_BITS(ltq_cgu_r32(LTQ_CGU_PLL0_CFG), 12, 6)
+#define CGU_PLL0_CFG_PLLM GET_BITS(ltq_cgu_r32(LTQ_CGU_PLL0_CFG), 5, 2)
+#define CGU_PLL2_SRC GET_BITS(ltq_cgu_r32(LTQ_CGU_PLL2_CFG), 18, 17)
+#define CGU_PLL2_CFG_INPUT_DIV GET_BITS(ltq_cgu_r32(LTQ_CGU_PLL2_CFG), 16, 13)
+
+/* vr9 clock */
+#define LTQ_CGU_SYS_VR9 0x0c
+#define LTQ_CGU_IF_CLK_VR9 0x24
+
+
+static unsigned int ltq_get_pll0_fdiv(void);
+
+static inline unsigned int get_input_clock(int pll)
+{
+ switch (pll) {
+ case 0:
+ if (ltq_cgu_r32(LTQ_CGU_PLL0_CFG) & CGU_PLL0_SRC)
+ return BASIS_REQUENCY_USB;
+ else if (CGU_PLL0_PHASE_DIVIDER_ENABLE)
+ return BASIC_FREQUENCY_1;
+ else
+ return BASIC_FREQUENCY_2;
+ case 1:
+ if (CGU_PLL1_SRC)
+ return BASIS_REQUENCY_USB;
+ else if (CGU_PLL0_PHASE_DIVIDER_ENABLE)
+ return BASIC_FREQUENCY_1;
+ else
+ return BASIC_FREQUENCY_2;
+ case 2:
+ switch (CGU_PLL2_SRC) {
+ case 0:
+ return ltq_get_pll0_fdiv();
+ case 1:
+ return CGU_PLL2_PHASE_DIVIDER_ENABLE ?
+ BASIC_FREQUENCY_1 :
+ BASIC_FREQUENCY_2;
+ case 2:
+ return BASIS_REQUENCY_USB;
+ }
+ default:
+ return 0;
+ }
+}
+
+static inline unsigned int cal_dsm(int pll, unsigned int num, unsigned int den)
+{
+ u64 res, clock = get_input_clock(pll);
+
+ res = num * clock;
+ do_div(res, den);
+ return res;
+}
+
+static inline unsigned int mash_dsm(int pll, unsigned int M, unsigned int N,
+ unsigned int K)
+{
+ unsigned int num = ((N + 1) << 10) + K;
+ unsigned int den = (M + 1) << 10;
+
+ return cal_dsm(pll, num, den);
+}
+
+static inline unsigned int ssff_dsm_1(int pll, unsigned int M, unsigned int N,
+ unsigned int K)
+{
+ unsigned int num = ((N + 1) << 11) + K + 512;
+ unsigned int den = (M + 1) << 11;
+
+ return cal_dsm(pll, num, den);
+}
+
+static inline unsigned int ssff_dsm_2(int pll, unsigned int M, unsigned int N,
+ unsigned int K)
+{
+ unsigned int num = K >= 512 ?
+ ((N + 1) << 12) + K - 512 : ((N + 1) << 12) + K + 3584;
+ unsigned int den = (M + 1) << 12;
+
+ return cal_dsm(pll, num, den);
+}
+
+static inline unsigned int dsm(int pll, unsigned int M, unsigned int N,
+ unsigned int K, unsigned int dsmsel, unsigned int phase_div_en)
+{
+ if (!dsmsel)
+ return mash_dsm(pll, M, N, K);
+ else if (!phase_div_en)
+ return mash_dsm(pll, M, N, K);
+ else
+ return ssff_dsm_2(pll, M, N, K);
+}
+
+static inline unsigned int ltq_get_pll0_fosc(void)
+{
+ if (CGU_PLL0_BYPASS)
+ return get_input_clock(0);
+ else
+ return !CGU_PLL0_CFG_FRAC_EN
+ ? dsm(0, CGU_PLL0_CFG_PLLM, CGU_PLL0_CFG_PLLN, 0,
+ CGU_PLL0_CFG_DSMSEL,
+ CGU_PLL0_PHASE_DIVIDER_ENABLE)
+ : dsm(0, CGU_PLL0_CFG_PLLM, CGU_PLL0_CFG_PLLN,
+ CGU_PLL0_CFG_PLLK, CGU_PLL0_CFG_DSMSEL,
+ CGU_PLL0_PHASE_DIVIDER_ENABLE);
+}
+
+static unsigned int ltq_get_pll0_fdiv(void)
+{
+ unsigned int div = CGU_PLL2_CFG_INPUT_DIV + 1;
+
+ return (ltq_get_pll0_fosc() + (div >> 1)) / div;
+}
+
+unsigned long ltq_danube_io_region_clock(void)
+{
+ unsigned int ret = ltq_get_pll0_fosc();
+
+ switch (ltq_cgu_r32(LTQ_CGU_PLL2_CFG) & CGU_SYS_DDR_SEL) {
+ default:
+ case 0:
+ return (ret + 1) / 2;
+ case 1:
+ return (ret * 2 + 2) / 5;
+ case 2:
+ return (ret + 1) / 3;
+ case 3:
+ return (ret + 2) / 4;
+ }
+}
+
+unsigned long ltq_danube_fpi_bus_clock(int fpi)
+{
+ unsigned long ret = ltq_danube_io_region_clock();
+
+ if ((fpi == 2) && (ltq_cgu_r32(LTQ_CGU_SYS) & CGU_SYS_FPI_SEL))
+ ret >>= 1;
+ return ret;
+}
+
+unsigned long ltq_danube_cpu_hz(void)
+{
+ switch (ltq_cgu_r32(LTQ_CGU_SYS) & 0xc) {
+ case 0:
+ return CLOCK_333M;
+ case 4:
+ return DDR_HZ;
+ case 8:
+ return DDR_HZ << 1;
+ default:
+ return DDR_HZ >> 1;
+ }
+}
+
+unsigned long ltq_danube_fpi_hz(void)
+{
+ unsigned long ddr_clock = DDR_HZ;
+
+ if (ltq_cgu_r32(LTQ_CGU_SYS) & 0x40)
+ return ddr_clock >> 1;
+ return ddr_clock;
+}
--- a/arch/mips/lantiq/xway/sysctrl.c
+++ b/arch/mips/lantiq/xway/sysctrl.c
@@ -8,17 +8,48 @@
#include <linux/ioport.h>
#include <linux/export.h>
+#include <linux/clkdev.h>
#include <lantiq_soc.h>
+#include "../clk.h"
#include "../devices.h"
/* clock control register */
#define LTQ_CGU_IFCCR 0x0018
+/* system clock register */
+#define LTQ_CGU_SYS 0x0010
/* the enable / disable registers */
#define LTQ_PMU_PWDCR 0x1C
#define LTQ_PMU_PWDSR 0x20
+#define LTQ_PMU_PWDCR1 0x24
+#define LTQ_PMU_PWDSR1 0x28
+
+#define PWDCR(x) ((x) ? (LTQ_PMU_PWDCR1) : (LTQ_PMU_PWDCR))
+#define PWDSR(x) ((x) ? (LTQ_PMU_PWDSR1) : (LTQ_PMU_PWDSR))
+
+/* CGU - clock generation unit */
+#define CGU_EPHY 0x10
+
+/* PMU - power management unit */
+#define PMU_DMA 0x0020
+#define PMU_SPI 0x0100
+#define PMU_EPHY 0x0080
+#define PMU_USB 0x8041
+#define PMU_STP 0x0800
+#define PMU_GPT 0x1000
+#define PMU_PPE 0x2000
+#define PMU_FPI 0x4000
+#define PMU_SWITCH 0x10000000
+#define PMU_AHBS 0x2000
+#define PMU_AHBM 0x8000
+#define PMU_PCIE_CLK 0x80000000
+
+#define PMU1_PCIE_PHY 0x0001
+#define PMU1_PCIE_CTL 0x0002
+#define PMU1_PCIE_MSI 0x0020
+#define PMU1_PCIE_PDI 0x0010
#define ltq_pmu_w32(x, y) ltq_w32((x), ltq_pmu_membase + (y))
#define ltq_pmu_r32(x) ltq_r32(ltq_pmu_membase + (x))
@@ -36,28 +67,64 @@ void __iomem *ltq_cgu_membase;
void __iomem *ltq_ebu_membase;
static void __iomem *ltq_pmu_membase;
-void ltq_cgu_enable(unsigned int clk)
+static int ltq_cgu_enable(struct clk *clk)
+{
+ ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) | clk->bits, LTQ_CGU_IFCCR);
+ return 0;
+}
+
+static void ltq_cgu_disable(struct clk *clk)
{
- ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) | clk, LTQ_CGU_IFCCR);
+ ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) & ~clk->bits, LTQ_CGU_IFCCR);
}
-void ltq_pmu_enable(unsigned int module)
+static int ltq_pmu_enable(struct clk *clk)
{
int err = 1000000;
- ltq_pmu_w32(ltq_pmu_r32(LTQ_PMU_PWDCR) & ~module, LTQ_PMU_PWDCR);
- do {} while (--err && (ltq_pmu_r32(LTQ_PMU_PWDSR) & module));
+ ltq_pmu_w32(ltq_pmu_r32(PWDCR(clk->module)) & ~clk->bits,
+ PWDCR(clk->module));
+ do {} while (--err && (ltq_pmu_r32(PWDSR(clk->module)) & clk->bits));
if (!err)
panic("activating PMU module failed!\n");
+
+ return 0;
+}
+
+static void ltq_pmu_disable(struct clk *clk)
+{
+ ltq_pmu_w32(ltq_pmu_r32(LTQ_PMU_PWDCR) | clk->bits, LTQ_PMU_PWDCR);
+}
+
+static inline void clkdev_add_pmu(const char *dev, const char *con,
+ unsigned int module, unsigned int bits)
+{
+ struct clk *clk = kzalloc(sizeof(struct clk), GFP_KERNEL);
+
+ clk->cl.dev_id = dev;
+ clk->cl.con_id = con;
+ clk->cl.clk = clk;
+ clk->enable = ltq_pmu_enable;
+ clk->disable = ltq_pmu_disable;
+ clk->module = module;
+ clk->bits = bits;
+ clkdev_add(&clk->cl);
}
-EXPORT_SYMBOL(ltq_pmu_enable);
-void ltq_pmu_disable(unsigned int module)
+static inline void clkdev_add_cgu(const char *dev, const char *con,
+ unsigned int bits)
{
- ltq_pmu_w32(ltq_pmu_r32(LTQ_PMU_PWDCR) | module, LTQ_PMU_PWDCR);
+ struct clk *clk = kzalloc(sizeof(struct clk), GFP_KERNEL);
+
+ clk->cl.dev_id = dev;
+ clk->cl.con_id = con;
+ clk->cl.clk = clk;
+ clk->enable = ltq_cgu_enable;
+ clk->disable = ltq_cgu_disable;
+ clk->bits = bits;
+ clkdev_add(&clk->cl);
}
-EXPORT_SYMBOL(ltq_pmu_disable);
void __init ltq_soc_init(void)
{
@@ -75,4 +142,23 @@ void __init ltq_soc_init(void)
/* make sure to unprotect the memory region where flash is located */
ltq_ebu_w32(ltq_ebu_r32(LTQ_EBU_BUSCON0) & ~EBU_WRDIS, LTQ_EBU_BUSCON0);
+
+ /* add our clocks */
+ clkdev_add_pmu("ltq_dma", NULL, 0, PMU_DMA);
+ clkdev_add_pmu("ltq_stp", NULL, 0, PMU_STP);
+ clkdev_add_pmu("ltq_spi", NULL, 0, PMU_SPI);
+ clkdev_add_pmu("ltq_etop", NULL, 0, PMU_PPE);
+ if (ltq_is_ase()) {
+ if (ltq_cgu_r32(LTQ_CGU_SYS) & (1 << 5))
+ clkdev_add_static(CLOCK_266M, CLOCK_133M, CLOCK_133M);
+ else
+ clkdev_add_static(CLOCK_133M, CLOCK_133M, CLOCK_133M);
+ clkdev_add_cgu("ltq_etop", "ephycgu", CGU_EPHY),
+ clkdev_add_pmu("ltq_etop", "ephy", 0, PMU_EPHY);
+ } else {
+ clkdev_add_static(ltq_danube_cpu_hz(), ltq_danube_fpi_hz(),
+ ltq_danube_io_region_clock());
+ if (ltq_is_ar9())
+ clkdev_add_pmu("ltq_etop", "switch", 0, PMU_SWITCH);
+ }
}

View File

@ -1,235 +0,0 @@
From 3a20e2b3471baf86765747b0e194400d3d74b6d8 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Thu, 8 Mar 2012 11:19:11 +0100
Subject: [PATCH 26/73] MIPS: lantiq: convert falcon to clkdev api
Unify sysctrl/clock code and add clkdev hooks to sysctrl.c
Signed-off-by: John Crispin <blogic@openwrt.org>
---
.../include/asm/mach-lantiq/falcon/lantiq_soc.h | 8 +-
arch/mips/lantiq/falcon/Makefile | 2 +-
arch/mips/lantiq/falcon/sysctrl.c | 129 ++++++++++++--------
3 files changed, 80 insertions(+), 59 deletions(-)
--- a/arch/mips/include/asm/mach-lantiq/falcon/lantiq_soc.h
+++ b/arch/mips/include/asm/mach-lantiq/falcon/lantiq_soc.h
@@ -95,6 +95,7 @@
/* Activation Status Register */
#define ACTS_ASC1_ACT 0x00000800
+#define ACTS_I2C_ACT 0x00004000
#define ACTS_P0 0x00010000
#define ACTS_P1 0x00010000
#define ACTS_P2 0x00020000
@@ -106,13 +107,6 @@
#define ACTS_PADCTRL3 0x00200000
#define ACTS_PADCTRL4 0x00400000
-extern void ltq_sysctl_activate(int module, unsigned int mask);
-extern void ltq_sysctl_deactivate(int module, unsigned int mask);
-extern void ltq_sysctl_clken(int module, unsigned int mask);
-extern void ltq_sysctl_clkdis(int module, unsigned int mask);
-extern void ltq_sysctl_reboot(int module, unsigned int mask);
-extern int ltq_gpe_is_activated(unsigned int mask);
-
/* global register ranges */
extern __iomem void *ltq_ebu_membase;
extern __iomem void *ltq_sys1_membase;
--- a/arch/mips/lantiq/falcon/Makefile
+++ b/arch/mips/lantiq/falcon/Makefile
@@ -1,2 +1,2 @@
-obj-y := clk.o prom.o reset.o sysctrl.o devices.o gpio.o
+obj-y := prom.o reset.o sysctrl.o devices.o gpio.o
obj-$(CONFIG_LANTIQ_MACH_EASY98000) += mach-easy98000.o
--- a/arch/mips/lantiq/falcon/sysctrl.c
+++ b/arch/mips/lantiq/falcon/sysctrl.c
@@ -9,11 +9,13 @@
#include <linux/ioport.h>
#include <linux/export.h>
+#include <linux/clkdev.h>
#include <asm/delay.h>
#include <lantiq_soc.h>
#include "devices.h"
+#include "../clk.h"
/* infrastructure control register */
#define SYS1_INFRAC 0x00bc
@@ -38,6 +40,10 @@
#define LTQ_SYSCTL_DEACT 0x0028
/* reboot Register */
#define LTQ_SYSCTL_RBT 0x002c
+/* CPU0 Clock Control Register */
+#define LTQ_SYS1_CPU0CC 0x0040
+/* clock divider bit */
+#define LTQ_CPU0CC_CPUDIV 0x0001
static struct resource ltq_sysctl_res[] = {
MEM_RES("sys1", LTQ_SYS1_BASE_ADDR, LTQ_SYS1_SIZE),
@@ -64,79 +70,67 @@ void __iomem *ltq_ebu_membase;
#define ltq_status_r32(x) ltq_r32(ltq_status_membase + (x))
static inline void
-ltq_sysctl_wait(int module, unsigned int mask,
+ltq_sysctl_wait(struct clk *clk,
unsigned int test, unsigned int reg)
{
int err = 1000000;
- do {} while (--err && ((ltq_reg_r32(module, reg)
- & mask) != test));
+ do {} while (--err && ((ltq_reg_r32(clk->module, reg)
+ & clk->bits) != test));
if (!err)
- pr_err("module de/activation failed %d %08X %08X\n",
- module, mask, test);
+ pr_err("module de/activation failed %d %08X %08X %08X\n",
+ clk->module, clk->bits, test,
+ ltq_reg_r32(clk->module, reg) & clk->bits);
}
-void
-ltq_sysctl_activate(int module, unsigned int mask)
-{
- if (module > SYSCTL_SYSGPE)
- return;
-
- ltq_reg_w32(module, mask, LTQ_SYSCTL_CLKEN);
- ltq_reg_w32(module, mask, LTQ_SYSCTL_ACT);
- ltq_sysctl_wait(module, mask, mask, LTQ_SYSCTL_ACTS);
+static int
+ltq_sysctl_activate(struct clk *clk)
+{
+ ltq_reg_w32(clk->module, clk->bits, LTQ_SYSCTL_CLKEN);
+ ltq_reg_w32(clk->module, clk->bits, LTQ_SYSCTL_ACT);
+ ltq_sysctl_wait(clk, clk->bits, LTQ_SYSCTL_ACTS);
+ return 0;
}
-EXPORT_SYMBOL(ltq_sysctl_activate);
-void
-ltq_sysctl_deactivate(int module, unsigned int mask)
+static void
+ltq_sysctl_deactivate(struct clk *clk)
{
- if (module > SYSCTL_SYSGPE)
- return;
-
- ltq_reg_w32(module, mask, LTQ_SYSCTL_CLKCLR);
- ltq_reg_w32(module, mask, LTQ_SYSCTL_DEACT);
- ltq_sysctl_wait(module, mask, 0, LTQ_SYSCTL_ACTS);
+ ltq_reg_w32(clk->module, clk->bits, LTQ_SYSCTL_CLKCLR);
+ ltq_reg_w32(clk->module, clk->bits, LTQ_SYSCTL_DEACT);
+ ltq_sysctl_wait(clk, 0, LTQ_SYSCTL_ACTS);
}
-EXPORT_SYMBOL(ltq_sysctl_deactivate);
-void
-ltq_sysctl_clken(int module, unsigned int mask)
+static int
+ltq_sysctl_clken(struct clk *clk)
{
- if (module > SYSCTL_SYSGPE)
- return;
-
- ltq_reg_w32(module, mask, LTQ_SYSCTL_CLKEN);
- ltq_sysctl_wait(module, mask, mask, LTQ_SYSCTL_CLKS);
+ ltq_reg_w32(clk->module, clk->bits, LTQ_SYSCTL_CLKEN);
+ ltq_sysctl_wait(clk, clk->bits, LTQ_SYSCTL_CLKS);
+ return 0;
}
-EXPORT_SYMBOL(ltq_sysctl_clken);
-void
-ltq_sysctl_clkdis(int module, unsigned int mask)
+static void
+ltq_sysctl_clkdis(struct clk *clk)
{
- if (module > SYSCTL_SYSGPE)
- return;
-
- ltq_reg_w32(module, mask, LTQ_SYSCTL_CLKCLR);
- ltq_sysctl_wait(module, mask, 0, LTQ_SYSCTL_CLKS);
+ ltq_reg_w32(clk->module, clk->bits, LTQ_SYSCTL_CLKCLR);
+ ltq_sysctl_wait(clk, 0, LTQ_SYSCTL_CLKS);
}
-EXPORT_SYMBOL(ltq_sysctl_clkdis);
-void
-ltq_sysctl_reboot(int module, unsigned int mask)
+static void
+ltq_sysctl_reboot(struct clk *clk)
{
unsigned int act;
+ unsigned int bits;
- if (module > SYSCTL_SYSGPE)
- return;
-
- act = ltq_reg_r32(module, LTQ_SYSCTL_ACT);
- if ((~act & mask) != 0)
- ltq_sysctl_activate(module, ~act & mask);
- ltq_reg_w32(module, act & mask, LTQ_SYSCTL_RBT);
- ltq_sysctl_wait(module, mask, mask, LTQ_SYSCTL_ACTS);
+ act = ltq_reg_r32(clk->module, LTQ_SYSCTL_ACT);
+ bits = ~act & clk->bits;
+ if (bits != 0) {
+ ltq_reg_w32(clk->module, bits, LTQ_SYSCTL_CLKEN);
+ ltq_reg_w32(clk->module, bits, LTQ_SYSCTL_ACT);
+ ltq_sysctl_wait(clk, bits, LTQ_SYSCTL_ACTS);
+ }
+ ltq_reg_w32(clk->module, act & clk->bits, LTQ_SYSCTL_RBT);
+ ltq_sysctl_wait(clk, clk->bits, LTQ_SYSCTL_ACTS);
}
-EXPORT_SYMBOL(ltq_sysctl_reboot);
/* enable the ONU core */
static void
@@ -167,6 +161,24 @@ ltq_gpe_enable(void)
udelay(1);
}
+static inline void
+clkdev_add_sys(const char *dev, unsigned int module,
+ unsigned int bits)
+{
+ struct clk *clk = kzalloc(sizeof(struct clk), GFP_KERNEL);
+
+ clk->cl.dev_id = dev;
+ clk->cl.con_id = NULL;
+ clk->cl.clk = clk;
+ clk->module = module;
+ clk->activate = ltq_sysctl_activate;
+ clk->deactivate = ltq_sysctl_deactivate;
+ clk->enable = ltq_sysctl_clken;
+ clk->disable = ltq_sysctl_clkdis;
+ clk->reboot = ltq_sysctl_reboot;
+ clkdev_add(&clk->cl);
+}
+
void __init
ltq_soc_init(void)
{
@@ -180,4 +192,19 @@ ltq_soc_init(void)
ltq_ebu_membase = ltq_remap_resource(&ltq_ebu_res);
ltq_gpe_enable();
+
+ /* get our 3 static rates for cpu, fpi and io clocks */
+ if (ltq_sys1_r32(LTQ_SYS1_CPU0CC) & LTQ_CPU0CC_CPUDIV)
+ clkdev_add_static(CLOCK_200M, CLOCK_100M, CLOCK_200M);
+ else
+ clkdev_add_static(CLOCK_400M, CLOCK_100M, CLOCK_200M);
+
+ /* add our clock domains */
+ clkdev_add_sys("falcon_gpio.0", SYSCTL_SYSETH, ACTS_PADCTRL0 | ACTS_P0);
+ clkdev_add_sys("falcon_gpio.1", SYSCTL_SYS1, ACTS_PADCTRL1 | ACTS_P1);
+ clkdev_add_sys("falcon_gpio.2", SYSCTL_SYSETH, ACTS_PADCTRL2 | ACTS_P2);
+ clkdev_add_sys("falcon_gpio.3", SYSCTL_SYS1, ACTS_PADCTRL3 | ACTS_P3);
+ clkdev_add_sys("falcon_gpio.4", SYSCTL_SYS1, ACTS_PADCTRL4 | ACTS_P4);
+ clkdev_add_sys("ltq_asc.1", SYSCTL_SYS1, ACTS_ASC1_ACT);
+ clkdev_add_sys("falcon_i2c", SYSCTL_SYS1, ACTS_I2C_ACT);
}

View File

@ -1,57 +0,0 @@
From 56b484094fed84e4e76532895c5a692f896a9492 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Thu, 8 Mar 2012 11:21:08 +0100
Subject: [PATCH 27/73] MIPS: lantiq: convert dma driver to clkdev api
Update from old pmu_{dis,en}able() to ckldev api.
Signed-off-by: John Crispin <blogic@openwrt.org>
---
arch/mips/lantiq/xway/Makefile.rej | 11 +++++++++++
arch/mips/lantiq/xway/dma.c | 6 +++++-
2 files changed, 16 insertions(+), 1 deletions(-)
create mode 100644 arch/mips/lantiq/xway/Makefile.rej
--- /dev/null
+++ b/arch/mips/lantiq/xway/Makefile.rej
@@ -0,0 +1,11 @@
+--- arch/mips/lantiq/xway/Makefile
++++ arch/mips/lantiq/xway/Makefile
+@@ -1,7 +1,4 @@
+-obj-y := sysctrl.o reset.o gpio.o gpio_stp.o gpio_ebu.o devices.o dma.o clk.o
+-
+-obj-$(CONFIG_SOC_XWAY) += prom-xway.o
+-obj-$(CONFIG_SOC_AMAZON_SE) += prom-ase.o
++obj-y := prom.o sysctrl.o reset.o gpio.o gpio_stp.o gpio_ebu.o devices.o dma.o clk.o
+
+ obj-$(CONFIG_LANTIQ_MACH_EASY50712) += mach-easy50712.o
+ obj-$(CONFIG_LANTIQ_MACH_EASY50601) += mach-easy50601.o
--- a/arch/mips/lantiq/xway/dma.c
+++ b/arch/mips/lantiq/xway/dma.c
@@ -20,6 +20,7 @@
#include <linux/io.h>
#include <linux/dma-mapping.h>
#include <linux/export.h>
+#include <linux/clk.h>
#include <lantiq_soc.h>
#include <xway_dma.h>
@@ -216,6 +217,7 @@ EXPORT_SYMBOL_GPL(ltq_dma_init_port);
int __init
ltq_dma_init(void)
{
+ struct clk *clk;
int i;
/* remap dma register range */
@@ -224,7 +226,9 @@ ltq_dma_init(void)
panic("Failed to remap dma memory\n");
/* power up and reset the dma engine */
- ltq_pmu_enable(PMU_DMA);
+ clk = clk_get_sys("ltq_dma", NULL);
+ WARN_ON(!clk);
+ clk_enable(clk);
ltq_dma_w32_mask(0, DMA_RESET, LTQ_DMA_CTRL);
/* disable all interrupts */

View File

@ -1,55 +0,0 @@
From a76818770adabc7afdf3bef07f9f30d061c10082 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Thu, 8 Mar 2012 11:21:33 +0100
Subject: [PATCH 28/73] MIPS: lantiq: convert gpio_stp driver to clkdev api
Update from old pmu_{dis,en}able() to ckldev api.
Signed-off-by: John Crispin <blogic@openwrt.org>
---
arch/mips/lantiq/xway/gpio_stp.c | 12 +++++++++---
1 files changed, 9 insertions(+), 3 deletions(-)
--- a/arch/mips/lantiq/xway/gpio_stp.c
+++ b/arch/mips/lantiq/xway/gpio_stp.c
@@ -15,6 +15,8 @@
#include <linux/mutex.h>
#include <linux/io.h>
#include <linux/gpio.h>
+#include <linux/clk.h>
+#include <linux/err.h>
#include <lantiq_soc.h>
@@ -78,8 +80,10 @@ static struct gpio_chip ltq_stp_chip = {
.owner = THIS_MODULE,
};
-static int ltq_stp_hw_init(void)
+static int ltq_stp_hw_init(struct device *dev)
{
+ struct clk *clk;
+
/* sane defaults */
ltq_stp_w32(0, LTQ_STP_AR);
ltq_stp_w32(0, LTQ_STP_CPU0);
@@ -105,7 +109,9 @@ static int ltq_stp_hw_init(void)
*/
ltq_stp_w32_mask(0, LTQ_STP_ADSL_SRC, LTQ_STP_CON0);
- ltq_pmu_enable(PMU_LED);
+ clk = clk_get(dev, NULL);
+ WARN_ON(IS_ERR(clk));
+ clk_enable(clk);
return 0;
}
@@ -138,7 +144,7 @@ static int __devinit ltq_stp_probe(struc
}
ret = gpiochip_add(&ltq_stp_chip);
if (!ret)
- ret = ltq_stp_hw_init();
+ ret = ltq_stp_hw_init(&pdev->dev);
return ret;
}

View File

@ -1,66 +0,0 @@
From 509bc67e8e365c8f1a0cb91abcac7c7772cf8335 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Thu, 8 Mar 2012 11:22:03 +0100
Subject: [PATCH 29/73] MIPS: lantiq: convert falcon gpio to clkdev api
The falcon gpio clocks used to be enabled when registering the platform device.
Move this code into the driver and use clkdev api.
Signed-off-by: John Crispin <blogic@openwrt.org>
---
arch/mips/lantiq/falcon/devices.c | 5 -----
arch/mips/lantiq/falcon/gpio.c | 10 ++++++++++
2 files changed, 10 insertions(+), 5 deletions(-)
--- a/arch/mips/lantiq/falcon/devices.c
+++ b/arch/mips/lantiq/falcon/devices.c
@@ -111,9 +111,6 @@ falcon_register_gpio(void)
falcon_gpio1_res, ARRAY_SIZE(falcon_gpio1_res));
platform_device_register_simple("falcon_gpio", 2,
falcon_gpio2_res, ARRAY_SIZE(falcon_gpio2_res));
- ltq_sysctl_activate(SYSCTL_SYS1, ACTS_PADCTRL1 | ACTS_P1);
- ltq_sysctl_activate(SYSCTL_SYSETH, ACTS_PADCTRL0 |
- ACTS_PADCTRL2 | ACTS_P0 | ACTS_P2);
}
void __init
@@ -123,6 +120,4 @@ falcon_register_gpio_extra(void)
falcon_gpio3_res, ARRAY_SIZE(falcon_gpio3_res));
platform_device_register_simple("falcon_gpio", 4,
falcon_gpio4_res, ARRAY_SIZE(falcon_gpio4_res));
- ltq_sysctl_activate(SYSCTL_SYS1,
- ACTS_PADCTRL3 | ACTS_PADCTRL4 | ACTS_P3 | ACTS_P4);
}
--- a/arch/mips/lantiq/falcon/gpio.c
+++ b/arch/mips/lantiq/falcon/gpio.c
@@ -11,6 +11,7 @@
#include <linux/interrupt.h>
#include <linux/slab.h>
#include <linux/export.h>
+#include <linux/err.h>
#include <linux/platform_device.h>
#include <lantiq_soc.h>
@@ -71,6 +72,7 @@ struct falcon_gpio_port {
void __iomem *port;
unsigned int irq_base;
unsigned int chained_irq;
+ struct clk *clk;
};
static struct falcon_gpio_port ltq_gpio_port[MAX_PORTS];
@@ -332,6 +334,14 @@ falcon_gpio_probe(struct platform_device
goto err;
}
+ gpio_port->clk = clk_get(&pdev->dev, NULL);
+ if (IS_ERR(gpio_port->clk)) {
+ dev_err(&pdev->dev, "Could not get clock\n");
+ ret = PTR_ERR(gpio_port->clk);;
+ goto err;
+ }
+ clk_enable(gpio_port->clk);
+
if (irq > 0) {
/* irq_chip support */
gpio_port->gpio_chip.to_irq = falcon_gpio_to_irq;

View File

@ -1,36 +0,0 @@
From da5f76f9eb0563597855f6b89894443d30a62d4f Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Thu, 16 Feb 2012 20:17:16 +0100
Subject: [PATCH 30/73] SERIAL: MIPS: lantiq: convert serial driver to clkdev
api
Reference the FPI clock via its new access function.
Signed-off-by: John Crispin <blogic@openwrt.org>
Cc: linux-serial@vger.kernel.org
---
drivers/tty/serial/lantiq.c | 6 +++++-
1 files changed, 5 insertions(+), 1 deletions(-)
--- a/drivers/tty/serial/lantiq.c
+++ b/drivers/tty/serial/lantiq.c
@@ -540,6 +540,10 @@ lqasc_request_port(struct uart_port *por
if (ltq_gpio_request(&pdev->dev, MUXC_SIF_TX_PIN,
3, 1, "asc1-tx"))
return -EBUSY;
+ ltq_port->clk = clk_get(&pdev->dev, NULL);
+ if (IS_ERR(ltq_port->clk))
+ return PTR_ERR(ltq_port->clk);
+ clk_enable(ltq_port->clk);
}
return 0;
}
@@ -698,7 +702,7 @@ lqasc_probe(struct platform_device *pdev
if (lqasc_port[pdev->id] != NULL)
return -EBUSY;
- clk = clk_get(&pdev->dev, "fpi");
+ clk = clk_get_fpi();
if (IS_ERR(clk)) {
pr_err("failed to get fpi clk\n");
return -ENOENT;

View File

@ -1,66 +0,0 @@
From 96cc1d1baabe7bc6df02e90bcd78e6dde542d384 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Tue, 21 Feb 2012 14:25:21 +0100
Subject: [PATCH 31/73] MIPS: lantiq: convert falcon debug uart to clkdev api
On Falcon SoCs we have a secondary serial port that can be used to help
debug the voice core. For the port to work several clocking bits need to
be activated. We convert the code to clkdev api.
Signed-off-by: John Crispin <blogic@openwrt.org>
---
arch/mips/lantiq/falcon/prom.c | 4 +---
drivers/tty/serial/lantiq.c | 7 ++++---
2 files changed, 5 insertions(+), 6 deletions(-)
--- a/arch/mips/lantiq/falcon/prom.c
+++ b/arch/mips/lantiq/falcon/prom.c
@@ -43,10 +43,8 @@ ltq_soc_setup(void)
ltq_register_asc(0);
ltq_register_wdt();
falcon_register_gpio();
- if (register_asc1) {
+ if (register_asc1)
ltq_register_asc(1);
- ltq_sysctl_activate(SYSCTL_SYS1, ACTS_ASC1_ACT);
- }
}
void __init
--- a/drivers/tty/serial/lantiq.c
+++ b/drivers/tty/serial/lantiq.c
@@ -117,6 +117,7 @@ static DEFINE_SPINLOCK(ltq_asc_lock);
struct ltq_uart_port {
struct uart_port port;
+ struct clk *fpiclk;
struct clk *clk;
unsigned int tx_irq;
unsigned int rx_irq;
@@ -319,7 +320,7 @@ lqasc_startup(struct uart_port *port)
struct ltq_uart_port *ltq_port = to_ltq_uart_port(port);
int retval;
- port->uartclk = clk_get_rate(ltq_port->clk);
+ port->uartclk = clk_get_rate(ltq_port->fpiclk);
ltq_w32_mask(ASCCLC_DISS | ASCCLC_RMCMASK, (1 << ASCCLC_RMCOFFSET),
port->membase + LTQ_ASC_CLC);
@@ -646,7 +647,7 @@ lqasc_console_setup(struct console *co,
port = &ltq_port->port;
- port->uartclk = clk_get_rate(ltq_port->clk);
+ port->uartclk = clk_get_rate(ltq_port->fpiclk);
if (options)
uart_parse_options(options, &baud, &parity, &bits, &flow);
@@ -731,7 +732,7 @@ lqasc_probe(struct platform_device *pdev
port->irq = tx_irq; /* unused, just to be backward-compatibe */
port->mapbase = mmres->start;
- ltq_port->clk = clk;
+ ltq_port->fpiclk = clk;
ltq_port->tx_irq = tx_irq;
ltq_port->rx_irq = rx_irq;

View File

@ -1,118 +0,0 @@
From e3b7883bacd449a22e262cc359dc923c78eb32f6 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Thu, 8 Mar 2012 11:23:00 +0100
Subject: [PATCH 32/73] NET: MIPS: lantiq: convert etop driver to clkdev api
Update from old pmu_{dis,en}able() to ckldev api.
Signed-off-by: John Crispin <blogic@openwrt.org>
Cc: netdev@vger.kernel.org
---
drivers/net/ethernet/lantiq_etop.c | 49 ++++++++++++++++++++++++++++++-----
1 files changed, 42 insertions(+), 7 deletions(-)
--- a/drivers/net/ethernet/lantiq_etop.c
+++ b/drivers/net/ethernet/lantiq_etop.c
@@ -36,6 +36,7 @@
#include <linux/io.h>
#include <linux/dma-mapping.h>
#include <linux/module.h>
+#include <linux/clk.h>
#include <asm/checksum.h>
@@ -147,6 +148,11 @@ struct ltq_etop_priv {
int tx_free[MAX_DMA_CHAN >> 1];
spinlock_t lock;
+
+ struct clk *clk_ppe;
+ struct clk *clk_switch;
+ struct clk *clk_ephy;
+ struct clk *clk_ephycgu;
};
static int ltq_etop_mdio_wr(struct mii_bus *bus, int phy_addr,
@@ -280,16 +286,27 @@ ltq_etop_hw_exit(struct net_device *dev)
struct ltq_etop_priv *priv = netdev_priv(dev);
int i;
- ltq_pmu_disable(PMU_PPE);
+ clk_disable(priv->clk_ppe);
+
+ if (ltq_has_gbit())
+ clk_disable(priv->clk_switch);
+
+ if (ltq_is_ase()) {
+ clk_disable(priv->clk_ephy);
+ clk_disable(priv->clk_ephycgu);
+ }
+
for (i = 0; i < MAX_DMA_CHAN; i++)
if (IS_TX(i) || IS_RX(i))
ltq_etop_free_channel(dev, &priv->ch[i]);
}
static void
-ltq_etop_gbit_init(void)
+ltq_etop_gbit_init(struct net_device *dev)
{
- ltq_pmu_enable(PMU_SWITCH);
+ struct ltq_etop_priv *priv = netdev_priv(dev);
+
+ clk_enable(priv->clk_switch);
ltq_gbit_w32_mask(0, GCTL0_SE, LTQ_GBIT_GCTL0);
/** Disable MDIO auto polling mode */
@@ -312,10 +329,10 @@ ltq_etop_hw_init(struct net_device *dev)
int err = 0;
int i;
- ltq_pmu_enable(PMU_PPE);
+ clk_enable(priv->clk_ppe);
if (ltq_has_gbit()) {
- ltq_etop_gbit_init();
+ ltq_etop_gbit_init(dev);
/* force the etops link to the gbit to MII */
mii_mode = PHY_INTERFACE_MODE_MII;
}
@@ -333,11 +350,11 @@ ltq_etop_hw_init(struct net_device *dev)
default:
if (ltq_is_ase()) {
- ltq_pmu_enable(PMU_EPHY);
+ clk_enable(priv->clk_ephy);
/* disable external MII */
ltq_etop_w32_mask(0, ETOP_CFG_MII0, LTQ_ETOP_CFG);
/* enable clock for internal PHY */
- ltq_cgu_enable(CGU_EPHY);
+ clk_enable(priv->clk_ephycgu);
/* we need to write this magic to the internal phy to
make it work */
ltq_etop_mdio_wr(NULL, 0x8, 0x12, 0xC020);
@@ -880,6 +897,24 @@ ltq_etop_probe(struct platform_device *p
priv->res = res;
priv->pldata = dev_get_platdata(&pdev->dev);
priv->netdev = dev;
+
+ priv->clk_ppe = clk_get(&pdev->dev, NULL);
+ if (IS_ERR(priv->clk_ppe))
+ return PTR_ERR(priv->clk_ppe);
+ if (ltq_has_gbit()) {
+ priv->clk_switch = clk_get(&pdev->dev, "switch");
+ if (IS_ERR(priv->clk_switch))
+ return PTR_ERR(priv->clk_switch);
+ }
+ if (ltq_is_ase()) {
+ priv->clk_ephy = clk_get(&pdev->dev, "ephy");
+ if (IS_ERR(priv->clk_ephy))
+ return PTR_ERR(priv->clk_ephy);
+ priv->clk_ephycgu = clk_get(&pdev->dev, "ephycgu");
+ if (IS_ERR(priv->clk_ephycgu))
+ return PTR_ERR(priv->clk_ephycgu);
+ }
+
spin_lock_init(&priv->lock);
for (i = 0; i < MAX_DMA_CHAN; i++) {

View File

@ -1,25 +0,0 @@
From f2a29d33abb24184f84533e2c6032d4b1c3fd346 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Thu, 16 Feb 2012 20:17:50 +0100
Subject: [PATCH 33/73] WDT: MIPS: lantiq: convert watchdog driver to clkdev
api
Refrence the IO region clock via its new access function.
Signed-off-by: John Crispin <blogic@openwrt.org>
Cc: linux-watchdog@vger.kernel.org
---
drivers/watchdog/lantiq_wdt.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
--- a/drivers/watchdog/lantiq_wdt.c
+++ b/drivers/watchdog/lantiq_wdt.c
@@ -206,7 +206,7 @@ ltq_wdt_probe(struct platform_device *pd
}
/* we do not need to enable the clock as it is always running */
- clk = clk_get(&pdev->dev, "io");
+ clk = clk_get_io();
WARN_ON(!clk);
ltq_io_region_clk_rate = clk_get_rate(clk);
clk_put(clk);

View File

@ -1,245 +0,0 @@
From f2c407ca7b975f979b0d73d2e52a73991de13dd9 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Thu, 8 Mar 2012 11:44:55 +0100
Subject: [PATCH 34/73] MIPS: lantiq: unify xway prom code
The xway prom-ase.c and prom-xway.c files are redundant. Unify the 2 files.
Signed-off-by: John Crispin <blogic@openwrt.org>
---
arch/mips/lantiq/xway/Makefile | 5 +--
arch/mips/lantiq/xway/Makefile.rej | 11 -----
arch/mips/lantiq/xway/prom-ase.c | 48 ----------------------
arch/mips/lantiq/xway/prom-xway.c | 64 -----------------------------
arch/mips/lantiq/xway/prom.c | 79 ++++++++++++++++++++++++++++++++++++
5 files changed, 80 insertions(+), 127 deletions(-)
delete mode 100644 arch/mips/lantiq/xway/Makefile.rej
delete mode 100644 arch/mips/lantiq/xway/prom-ase.c
delete mode 100644 arch/mips/lantiq/xway/prom-xway.c
create mode 100644 arch/mips/lantiq/xway/prom.c
--- a/arch/mips/lantiq/xway/Makefile
+++ b/arch/mips/lantiq/xway/Makefile
@@ -1,7 +1,4 @@
-obj-y := sysctrl.o reset.o gpio.o gpio_stp.o gpio_ebu.o devices.o dma.o clk.o
-
-obj-$(CONFIG_SOC_XWAY) += prom-xway.o
-obj-$(CONFIG_SOC_AMAZON_SE) += prom-ase.o
+obj-y := sysctrl.o reset.o gpio.o gpio_stp.o gpio_ebu.o devices.o dma.o clk.o prom.o
obj-$(CONFIG_LANTIQ_MACH_EASY50712) += mach-easy50712.o
obj-$(CONFIG_LANTIQ_MACH_EASY50601) += mach-easy50601.o
--- a/arch/mips/lantiq/xway/Makefile.rej
+++ /dev/null
@@ -1,11 +0,0 @@
---- arch/mips/lantiq/xway/Makefile
-+++ arch/mips/lantiq/xway/Makefile
-@@ -1,7 +1,4 @@
--obj-y := sysctrl.o reset.o gpio.o gpio_stp.o gpio_ebu.o devices.o dma.o clk.o
--
--obj-$(CONFIG_SOC_XWAY) += prom-xway.o
--obj-$(CONFIG_SOC_AMAZON_SE) += prom-ase.o
-+obj-y := prom.o sysctrl.o reset.o gpio.o gpio_stp.o gpio_ebu.o devices.o dma.o clk.o
-
- obj-$(CONFIG_LANTIQ_MACH_EASY50712) += mach-easy50712.o
- obj-$(CONFIG_LANTIQ_MACH_EASY50601) += mach-easy50601.o
--- a/arch/mips/lantiq/xway/prom-ase.c
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * 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.
- *
- * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
- */
-
-#include <linux/export.h>
-#include <linux/clk.h>
-#include <asm/bootinfo.h>
-#include <asm/time.h>
-
-#include <lantiq_soc.h>
-
-#include "devices.h"
-#include "../prom.h"
-
-#define SOC_AMAZON_SE "Amazon_SE"
-
-#define PART_SHIFT 12
-#define PART_MASK 0x0FFFFFFF
-#define REV_SHIFT 28
-#define REV_MASK 0xF0000000
-
-void __init ltq_soc_detect(struct ltq_soc_info *i)
-{
- i->partnum = (ltq_r32(LTQ_MPS_CHIPID) & PART_MASK) >> PART_SHIFT;
- i->rev = (ltq_r32(LTQ_MPS_CHIPID) & REV_MASK) >> REV_SHIFT;
- sprintf(i->rev_type, "1.%d", i->rev);
- switch (i->partnum) {
- case SOC_ID_AMAZON_SE:
- i->name = SOC_AMAZON_SE;
- i->type = SOC_TYPE_AMAZON_SE;
- break;
-
- default:
- unreachable();
- break;
- }
-}
-
-void __init ltq_soc_setup(void)
-{
- ltq_register_ase_asc();
- ltq_register_gpio();
- ltq_register_wdt();
-}
--- a/arch/mips/lantiq/xway/prom-xway.c
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * 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.
- *
- * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
- */
-
-#include <linux/export.h>
-#include <linux/clk.h>
-#include <asm/bootinfo.h>
-#include <asm/time.h>
-
-#include <lantiq_soc.h>
-
-#include "devices.h"
-#include "../prom.h"
-
-#define SOC_DANUBE "Danube"
-#define SOC_TWINPASS "Twinpass"
-#define SOC_AR9 "AR9"
-
-#define PART_SHIFT 12
-#define PART_MASK 0x0FFFFFFF
-#define REV_SHIFT 28
-#define REV_MASK 0xF0000000
-
-void __init ltq_soc_detect(struct ltq_soc_info *i)
-{
- i->partnum = (ltq_r32(LTQ_MPS_CHIPID) & PART_MASK) >> PART_SHIFT;
- i->rev = (ltq_r32(LTQ_MPS_CHIPID) & REV_MASK) >> REV_SHIFT;
- sprintf(i->rev_type, "1.%d", i->rev);
- switch (i->partnum) {
- case SOC_ID_DANUBE1:
- case SOC_ID_DANUBE2:
- i->name = SOC_DANUBE;
- i->type = SOC_TYPE_DANUBE;
- break;
-
- case SOC_ID_TWINPASS:
- i->name = SOC_TWINPASS;
- i->type = SOC_TYPE_DANUBE;
- break;
-
- case SOC_ID_ARX188:
- case SOC_ID_ARX168:
- case SOC_ID_ARX182:
- i->name = SOC_AR9;
- i->type = SOC_TYPE_AR9;
- break;
-
- default:
- unreachable();
- break;
- }
-}
-
-void __init ltq_soc_setup(void)
-{
- ltq_register_asc(0);
- ltq_register_asc(1);
- ltq_register_gpio();
- ltq_register_wdt();
-}
--- /dev/null
+++ b/arch/mips/lantiq/xway/prom.c
@@ -0,0 +1,79 @@
+/*
+ * 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.
+ *
+ * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/export.h>
+#include <linux/clk.h>
+#include <asm/bootinfo.h>
+#include <asm/time.h>
+
+#include <lantiq_soc.h>
+
+#include "../prom.h"
+#include "devices.h"
+
+#define SOC_DANUBE "Danube"
+#define SOC_TWINPASS "Twinpass"
+#define SOC_AR9 "AR9"
+#define SOC_VR9 "VR9"
+
+#define PART_SHIFT 12
+#define PART_MASK 0x0FFFFFFF
+#define REV_SHIFT 28
+#define REV_MASK 0xF0000000
+
+#define SOC_AMAZON_SE "Amazon_SE"
+
+void __init ltq_soc_detect(struct ltq_soc_info *i)
+{
+ i->partnum = (ltq_r32(LTQ_MPS_CHIPID) & PART_MASK) >> PART_SHIFT;
+ i->rev = (ltq_r32(LTQ_MPS_CHIPID) & REV_MASK) >> REV_SHIFT;
+ sprintf(i->rev_type, "1.%d", i->rev);
+ switch (i->partnum) {
+ case SOC_ID_DANUBE1:
+ case SOC_ID_DANUBE2:
+ i->name = SOC_DANUBE;
+ i->type = SOC_TYPE_DANUBE;
+ break;
+
+ case SOC_ID_TWINPASS:
+ i->name = SOC_TWINPASS;
+ i->type = SOC_TYPE_DANUBE;
+ break;
+
+ case SOC_ID_ARX188:
+ case SOC_ID_ARX168:
+ case SOC_ID_ARX182:
+ i->name = SOC_AR9;
+ i->type = SOC_TYPE_AR9;
+ break;
+
+ case SOC_ID_AMAZON_SE:
+ i->name = SOC_AMAZON_SE;
+ i->type = SOC_TYPE_AMAZON_SE;
+#ifdef CONFIG_PCI
+ panic("ase is only supported for non pci kernels");
+#endif
+ break;
+
+ default:
+ unreachable();
+ break;
+ }
+}
+
+void __init ltq_soc_setup(void)
+{
+ if (ltq_is_ase()) {
+ ltq_register_ase_asc();
+ } else {
+ ltq_register_asc(0);
+ ltq_register_asc(1);
+ }
+ ltq_register_gpio();
+ ltq_register_wdt();
+}

View File

@ -1,161 +0,0 @@
From 958d1d653fe13627d13907e61ae201fe62ddd99f Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Tue, 21 Feb 2012 09:48:11 +0100
Subject: [PATCH 35/73] MIPS: lantiq: add vr9 support
VR9 is a VDSL SoC made by Lantiq. It is very similar to the AR9.
This patch adds the clkdev init code and SoC detection for the VR9.
Signed-off-by: John Crispin <blogic@openwrt.org>
Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@googlemail.com>
---
.../mips/include/asm/mach-lantiq/xway/lantiq_soc.h | 3 +
arch/mips/lantiq/xway/clk.c | 83 ++++++++++++++++++++
arch/mips/lantiq/xway/prom.c | 6 ++
arch/mips/lantiq/xway/sysctrl.c | 12 +++-
4 files changed, 103 insertions(+), 1 deletions(-)
--- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
+++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
@@ -21,6 +21,9 @@
#define SOC_ID_ARX188 0x16C
#define SOC_ID_ARX168 0x16D
#define SOC_ID_ARX182 0x16F
+#define SOC_ID_VRX288 0x1C0 /* VRX288 v1.1 */
+#define SOC_ID_VRX268 0x1C2 /* VRX268 v1.1 */
+#define SOC_ID_GRX288 0x1C9 /* GRX288 v1.1 */
/* SoC Types */
#define SOC_TYPE_DANUBE 0x01
--- a/arch/mips/lantiq/xway/clk.c
+++ b/arch/mips/lantiq/xway/clk.c
@@ -225,3 +225,86 @@ unsigned long ltq_danube_fpi_hz(void)
return ddr_clock >> 1;
return ddr_clock;
}
+
+unsigned long ltq_vr9_cpu_hz(void)
+{
+ unsigned int cpu_sel;
+ unsigned long clk;
+
+ cpu_sel = (ltq_cgu_r32(LTQ_CGU_SYS_VR9) >> 4) & 0xf;
+
+ switch (cpu_sel) {
+ case 0:
+ clk = CLOCK_600M;
+ break;
+ case 1:
+ clk = CLOCK_500M;
+ break;
+ case 2:
+ clk = CLOCK_393M;
+ break;
+ case 3:
+ clk = CLOCK_333M;
+ break;
+ case 5:
+ case 6:
+ clk = CLOCK_196_608M;
+ break;
+ case 7:
+ clk = CLOCK_167M;
+ break;
+ case 4:
+ case 8:
+ case 9:
+ clk = CLOCK_125M;
+ break;
+ default:
+ clk = 0;
+ break;
+ }
+
+ return clk;
+}
+
+unsigned long ltq_vr9_fpi_hz(void)
+{
+ unsigned int ocp_sel, cpu_clk;
+ unsigned long clk;
+
+ cpu_clk = ltq_vr9_cpu_hz();
+ ocp_sel = ltq_cgu_r32(LTQ_CGU_SYS_VR9) & 0x3;
+
+ switch (ocp_sel) {
+ case 0:
+ /* OCP ratio 1 */
+ clk = cpu_clk;
+ break;
+ case 2:
+ /* OCP ratio 2 */
+ clk = cpu_clk / 2;
+ break;
+ case 3:
+ /* OCP ratio 2.5 */
+ clk = (cpu_clk * 2) / 5;
+ break;
+ case 4:
+ /* OCP ratio 3 */
+ clk = cpu_clk / 3;
+ break;
+ default:
+ clk = 0;
+ break;
+ }
+
+ return clk;
+}
+
+unsigned long ltq_vr9_io_region_clock(void)
+{
+ return ltq_vr9_fpi_hz();
+}
+
+unsigned long ltq_vr9_fpi_bus_clock(int fpi)
+{
+ return ltq_vr9_fpi_hz();
+}
--- a/arch/mips/lantiq/xway/prom.c
+++ b/arch/mips/lantiq/xway/prom.c
@@ -60,6 +60,12 @@ void __init ltq_soc_detect(struct ltq_so
#endif
break;
+ case SOC_ID_VRX268:
+ case SOC_ID_VRX288:
+ i->name = SOC_VR9;
+ i->type = SOC_TYPE_VR9;
+ break;
+
default:
unreachable();
break;
--- a/arch/mips/lantiq/xway/sysctrl.c
+++ b/arch/mips/lantiq/xway/sysctrl.c
@@ -147,7 +147,8 @@ void __init ltq_soc_init(void)
clkdev_add_pmu("ltq_dma", NULL, 0, PMU_DMA);
clkdev_add_pmu("ltq_stp", NULL, 0, PMU_STP);
clkdev_add_pmu("ltq_spi", NULL, 0, PMU_SPI);
- clkdev_add_pmu("ltq_etop", NULL, 0, PMU_PPE);
+ if (!ltq_is_vr9())
+ clkdev_add_pmu("ltq_etop", NULL, 0, PMU_PPE);
if (ltq_is_ase()) {
if (ltq_cgu_r32(LTQ_CGU_SYS) & (1 << 5))
clkdev_add_static(CLOCK_266M, CLOCK_133M, CLOCK_133M);
@@ -155,6 +156,15 @@ void __init ltq_soc_init(void)
clkdev_add_static(CLOCK_133M, CLOCK_133M, CLOCK_133M);
clkdev_add_cgu("ltq_etop", "ephycgu", CGU_EPHY),
clkdev_add_pmu("ltq_etop", "ephy", 0, PMU_EPHY);
+ } else if (ltq_is_vr9()) {
+ clkdev_add_static(ltq_vr9_cpu_hz(), ltq_vr9_fpi_hz(),
+ ltq_vr9_io_region_clock());
+ clkdev_add_pmu("ltq_pcie", "phy", 1, PMU1_PCIE_PHY);
+ clkdev_add_pmu("ltq_pcie", "bus", 0, PMU_PCIE_CLK);
+ clkdev_add_pmu("ltq_pcie", "msi", 1, PMU1_PCIE_MSI);
+ clkdev_add_pmu("ltq_pcie", "pdi", 1, PMU1_PCIE_PDI);
+ clkdev_add_pmu("ltq_pcie", "ctl", 1, PMU1_PCIE_CTL);
+ clkdev_add_pmu("ltq_pcie", "ahb", 0, PMU_AHBM | PMU_AHBS);
} else {
clkdev_add_static(ltq_danube_cpu_hz(), ltq_danube_fpi_hz(),
ltq_danube_io_region_clock());

View File

@ -1,117 +0,0 @@
From da466512e536083352dcefd9ddbfd95a9c60b464 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Tue, 21 Feb 2012 21:09:01 +0100
Subject: [PATCH 36/73] MIPS: lantiq: add ipi handlers to make vsmp work
Add IPI handlers to the interrupt code. This patch makes MIPS_MT_SMP work
on lantiq SoCs.
Signed-off-by: John Crispin <blogic@openwrt.org>
---
arch/mips/lantiq/irq.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++
arch/mips/lantiq/prom.c | 5 ++++
2 files changed, 66 insertions(+), 0 deletions(-)
--- a/arch/mips/lantiq/irq.c
+++ b/arch/mips/lantiq/irq.c
@@ -9,6 +9,7 @@
#include <linux/interrupt.h>
#include <linux/ioport.h>
+#include <linux/sched.h>
#include <asm/bootinfo.h>
#include <asm/irq_cpu.h>
@@ -54,6 +55,14 @@
#define ltq_eiu_w32(x, y) ltq_w32((x), ltq_eiu_membase + (y))
#define ltq_eiu_r32(x) ltq_r32(ltq_eiu_membase + (x))
+/* our 2 ipi interrupts for VSMP */
+#define MIPS_CPU_IPI_RESCHED_IRQ 0
+#define MIPS_CPU_IPI_CALL_IRQ 1
+
+#if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_MIPS_MT_SMTC)
+int gic_present;
+#endif
+
static unsigned short ltq_eiu_irq[MAX_EIU] = {
LTQ_EIU_IR0,
LTQ_EIU_IR1,
@@ -219,6 +228,47 @@ static void ltq_hw5_irqdispatch(void)
do_IRQ(MIPS_CPU_TIMER_IRQ);
}
+#ifdef CONFIG_MIPS_MT_SMP
+void __init arch_init_ipiirq(int irq, struct irqaction *action)
+{
+ setup_irq(irq, action);
+ irq_set_handler(irq, handle_percpu_irq);
+}
+
+static void ltq_sw0_irqdispatch(void)
+{
+ do_IRQ(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_RESCHED_IRQ);
+}
+
+static void ltq_sw1_irqdispatch(void)
+{
+ do_IRQ(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ);
+}
+static irqreturn_t ipi_resched_interrupt(int irq, void *dev_id)
+{
+ scheduler_ipi();
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t ipi_call_interrupt(int irq, void *dev_id)
+{
+ smp_call_function_interrupt();
+ return IRQ_HANDLED;
+}
+
+static struct irqaction irq_resched = {
+ .handler = ipi_resched_interrupt,
+ .flags = IRQF_PERCPU,
+ .name = "IPI_resched"
+};
+
+static struct irqaction irq_call = {
+ .handler = ipi_call_interrupt,
+ .flags = IRQF_PERCPU,
+ .name = "IPI_call"
+};
+#endif
+
asmlinkage void plat_irq_dispatch(void)
{
unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM;
@@ -314,6 +364,17 @@ void __init arch_init_irq(void)
irq_set_chip_and_handler(i, &ltq_irq_type,
handle_level_irq);
+#if defined(CONFIG_MIPS_MT_SMP)
+ if (cpu_has_vint) {
+ pr_info("Setting up IPI vectored interrupts\n");
+ set_vi_handler(MIPS_CPU_IPI_RESCHED_IRQ, ltq_sw0_irqdispatch);
+ set_vi_handler(MIPS_CPU_IPI_CALL_IRQ, ltq_sw1_irqdispatch);
+ }
+ arch_init_ipiirq(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_RESCHED_IRQ,
+ &irq_resched);
+ arch_init_ipiirq(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ, &irq_call);
+#endif
+
#if !defined(CONFIG_MIPS_MT_SMP) && !defined(CONFIG_MIPS_MT_SMTC)
set_c0_status(IE_IRQ0 | IE_IRQ1 | IE_IRQ2 |
IE_IRQ3 | IE_IRQ4 | IE_IRQ5);
--- a/arch/mips/lantiq/prom.c
+++ b/arch/mips/lantiq/prom.c
@@ -108,4 +108,9 @@ void __init prom_init(void)
soc_info.sys_type[LTQ_SYS_TYPE_LEN - 1] = '\0';
pr_info("SoC: %s\n", soc_info.sys_type);
prom_init_cmdline();
+
+#if defined(CONFIG_MIPS_MT_SMP)
+ if (register_vsmp_smp_ops())
+ panic("failed to register_vsmp_smp_ops()");
+#endif
}

View File

@ -1,149 +0,0 @@
From 5585147ea9462778decc7146667ac54413acd91f Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Mon, 12 Mar 2012 15:23:39 +0100
Subject: [PATCH 37/73] MIPS: lantiq: add additional soc ids
---
.../mips/include/asm/mach-lantiq/xway/lantiq_soc.h | 38 +++++++++++++++----
arch/mips/lantiq/xway/prom.c | 35 ++++++++++++++++--
2 files changed, 61 insertions(+), 12 deletions(-)
--- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
+++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
@@ -17,20 +17,32 @@
#define SOC_ID_DANUBE1 0x129
#define SOC_ID_DANUBE2 0x12B
#define SOC_ID_TWINPASS 0x12D
-#define SOC_ID_AMAZON_SE 0x152
+#define SOC_ID_AMAZON_SE_1 0x152 /* 50601 */
+#define SOC_ID_AMAZON_SE_2 0x153 /* 50600 */
#define SOC_ID_ARX188 0x16C
-#define SOC_ID_ARX168 0x16D
+#define SOC_ID_ARX168_1 0x16D
+#define SOC_ID_ARX168_2 0x16E
#define SOC_ID_ARX182 0x16F
-#define SOC_ID_VRX288 0x1C0 /* VRX288 v1.1 */
-#define SOC_ID_VRX268 0x1C2 /* VRX268 v1.1 */
-#define SOC_ID_GRX288 0x1C9 /* GRX288 v1.1 */
+#define SOC_ID_GRX188 0x170
+#define SOC_ID_GRX168 0x171
+
+#define SOC_ID_VRX288 0x1C0 /* v1.1 */
+#define SOC_ID_VRX282 0x1C1 /* v1.1 */
+#define SOC_ID_VRX268 0x1C2 /* v1.1 */
+#define SOC_ID_GRX268 0x1C8 /* v1.1 */
+#define SOC_ID_GRX288 0x1C9 /* v1.1 */
+#define SOC_ID_VRX288_2 0x00B /* v1.2 */
+#define SOC_ID_VRX268_2 0x00C /* v1.2 */
+#define SOC_ID_GRX288_2 0x00D /* v1.2 */
+#define SOC_ID_GRX282_2 0x00E /* v1.2 */
/* SoC Types */
#define SOC_TYPE_DANUBE 0x01
#define SOC_TYPE_TWINPASS 0x02
#define SOC_TYPE_AR9 0x03
-#define SOC_TYPE_VR9 0x04
-#define SOC_TYPE_AMAZON_SE 0x05
+#define SOC_TYPE_VR9_1 0x04 /* v1.1 */
+#define SOC_TYPE_VR9_2 0x05 /* v1.2 */
+#define SOC_TYPE_AMAZON_SE 0x06
/* ASC0/1 - serial port */
#define LTQ_ASC0_BASE_ADDR 0x1E100400
@@ -149,9 +161,19 @@ static inline int ltq_is_ar9(void)
return (ltq_get_soc_type() == SOC_TYPE_AR9);
}
+static inline int ltq_is_vr9_1(void)
+{
+ return (ltq_get_soc_type() == SOC_TYPE_VR9_1);
+}
+
+static inline int ltq_is_vr9_2(void)
+{
+ return (ltq_get_soc_type() == SOC_TYPE_VR9_2);
+}
+
static inline int ltq_is_vr9(void)
{
- return (ltq_get_soc_type() == SOC_TYPE_VR9);
+ return (ltq_is_vr9_1() || ltq_is_vr9_2());
}
static inline int ltq_is_falcon(void)
--- a/arch/mips/lantiq/xway/prom.c
+++ b/arch/mips/lantiq/xway/prom.c
@@ -18,7 +18,9 @@
#define SOC_DANUBE "Danube"
#define SOC_TWINPASS "Twinpass"
+#define SOC_AMAZON_SE "Amazon_SE"
#define SOC_AR9 "AR9"
+#define SOC_GR9 "GR9"
#define SOC_VR9 "VR9"
#define PART_SHIFT 12
@@ -26,7 +28,6 @@
#define REV_SHIFT 28
#define REV_MASK 0xF0000000
-#define SOC_AMAZON_SE "Amazon_SE"
void __init ltq_soc_detect(struct ltq_soc_info *i)
{
@@ -46,13 +47,21 @@ void __init ltq_soc_detect(struct ltq_so
break;
case SOC_ID_ARX188:
- case SOC_ID_ARX168:
+ case SOC_ID_ARX168_1:
+ case SOC_ID_ARX168_2:
case SOC_ID_ARX182:
i->name = SOC_AR9;
i->type = SOC_TYPE_AR9;
break;
- case SOC_ID_AMAZON_SE:
+ case SOC_ID_GRX188:
+ case SOC_ID_GRX168:
+ i->name = SOC_GR9;
+ i->type = SOC_TYPE_AR9;
+ break;
+
+ case SOC_ID_AMAZON_SE_1:
+ case SOC_ID_AMAZON_SE_2:
i->name = SOC_AMAZON_SE;
i->type = SOC_TYPE_AMAZON_SE;
#ifdef CONFIG_PCI
@@ -60,12 +69,30 @@ void __init ltq_soc_detect(struct ltq_so
#endif
break;
+ case SOC_ID_VRX282:
case SOC_ID_VRX268:
case SOC_ID_VRX288:
i->name = SOC_VR9;
- i->type = SOC_TYPE_VR9;
+ i->type = SOC_TYPE_VR9_1;
break;
+ case SOC_ID_GRX268:
+ case SOC_ID_GRX288:
+ i->name = SOC_GR9;
+ i->type = SOC_TYPE_VR9_1;
+ break;
+
+ case SOC_ID_VRX268_2:
+ case SOC_ID_VRX288_2:
+ i->name = SOC_VR9;
+ i->type = SOC_TYPE_VR9_2;
+ break;
+
+ case SOC_ID_GRX282_2:
+ case SOC_ID_GRX288_2:
+ i->name = SOC_GR9;
+ i->type = SOC_TYPE_VR9_2;
+
default:
unreachable();
break;

View File

@ -1,617 +0,0 @@
From addbb26930d41b35e329d0ad6413cc8d087aa4cc Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Sat, 27 Aug 2011 18:12:26 +0200
Subject: [PATCH 38/73] SPI: MIPS: lantiq: add FALC-ON spi driver
The external bus unit (EBU) found on the FALC-ON SoC has spi emulation that is
designed for serial flash access. This driver has only been tested with m25p80
type chips. The hardware has no support for other types of spi peripherals.
Signed-off-by: Thomas Langer <thomas.langer@lantiq.com>
Signed-off-by: John Crispin <blogic@openwrt.org>
Cc: spi-devel-general@lists.sourceforge.net
---
arch/mips/lantiq/falcon/devices.c | 13 +
arch/mips/lantiq/falcon/devices.h | 4 +
arch/mips/lantiq/falcon/mach-easy98000.c | 27 ++
drivers/spi/Kconfig | 4 +
drivers/spi/Makefile | 1 +
drivers/spi/spi-falcon.c | 483 ++++++++++++++++++++++++++++++
6 files changed, 532 insertions(+), 0 deletions(-)
create mode 100644 drivers/spi/spi-falcon.c
--- a/arch/mips/lantiq/falcon/devices.c
+++ b/arch/mips/lantiq/falcon/devices.c
@@ -121,3 +121,16 @@ falcon_register_gpio_extra(void)
platform_device_register_simple("falcon_gpio", 4,
falcon_gpio4_res, ARRAY_SIZE(falcon_gpio4_res));
}
+
+/* spi flash */
+static struct platform_device ltq_spi = {
+ .name = "falcon_spi",
+ .num_resources = 0,
+};
+
+void __init
+falcon_register_spi_flash(struct spi_board_info *data)
+{
+ spi_register_board_info(data, 1);
+ platform_device_register(&ltq_spi);
+}
--- a/arch/mips/lantiq/falcon/devices.h
+++ b/arch/mips/lantiq/falcon/devices.h
@@ -11,10 +11,14 @@
#ifndef _FALCON_DEVICES_H__
#define _FALCON_DEVICES_H__
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+
#include "../devices.h"
extern void falcon_register_nand(void);
extern void falcon_register_gpio(void);
extern void falcon_register_gpio_extra(void);
+extern void falcon_register_spi_flash(struct spi_board_info *data);
#endif
--- a/arch/mips/lantiq/falcon/mach-easy98000.c
+++ b/arch/mips/lantiq/falcon/mach-easy98000.c
@@ -40,6 +40,21 @@ struct physmap_flash_data easy98000_nor_
.parts = easy98000_nor_partitions,
};
+static struct flash_platform_data easy98000_spi_flash_platform_data = {
+ .name = "sflash",
+ .parts = easy98000_nor_partitions,
+ .nr_parts = ARRAY_SIZE(easy98000_nor_partitions)
+};
+
+static struct spi_board_info easy98000_spi_flash_data __initdata = {
+ .modalias = "m25p80",
+ .bus_num = 0,
+ .chip_select = 0,
+ .max_speed_hz = 10 * 1000 * 1000,
+ .mode = SPI_MODE_3,
+ .platform_data = &easy98000_spi_flash_platform_data
+};
+
/* setup gpio based spi bus/device for access to the eeprom on the board */
#define SPI_GPIO_MRST 102
#define SPI_GPIO_MTSR 103
@@ -93,6 +108,13 @@ easy98000_init(void)
}
static void __init
+easy98000sf_init(void)
+{
+ easy98000_init_common();
+ falcon_register_spi_flash(&easy98000_spi_flash_data);
+}
+
+static void __init
easy98000nand_init(void)
{
easy98000_init_common();
@@ -104,6 +126,11 @@ MIPS_MACHINE(LANTIQ_MACH_EASY98000,
"EASY98000 Eval Board",
easy98000_init);
+MIPS_MACHINE(LANTIQ_MACH_EASY98000SF,
+ "EASY98000SF",
+ "EASY98000 Eval Board (Serial Flash)",
+ easy98000sf_init);
+
MIPS_MACHINE(LANTIQ_MACH_EASY98000NAND,
"EASY98000NAND",
"EASY98000 Eval Board (NAND Flash)",
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -189,6 +189,10 @@ config SPI_MPC52xx
This drivers supports the MPC52xx SPI controller in master SPI
mode.
+config SPI_FALCON
+ tristate "Falcon SPI controller support"
+ depends on SOC_FALCON
+
config SPI_MPC52xx_PSC
tristate "Freescale MPC52xx PSC SPI controller"
depends on PPC_MPC52xx && EXPERIMENTAL
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -25,6 +25,7 @@ obj-$(CONFIG_SPI_DW_MMIO) += spi-dw-mmi
obj-$(CONFIG_SPI_DW_PCI) += spi-dw-midpci.o
spi-dw-midpci-objs := spi-dw-pci.o spi-dw-mid.o
obj-$(CONFIG_SPI_EP93XX) += spi-ep93xx.o
+obj-$(CONFIG_SPI_FALCON) += spi-falcon.o
obj-$(CONFIG_SPI_FSL_LIB) += spi-fsl-lib.o
obj-$(CONFIG_SPI_FSL_ESPI) += spi-fsl-espi.o
obj-$(CONFIG_SPI_FSL_SPI) += spi-fsl-spi.o
--- /dev/null
+++ b/drivers/spi/spi-falcon.c
@@ -0,0 +1,483 @@
+/*
+ * 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.
+ *
+ * Copyright (C) 2010 Thomas Langer <thomas.langer@lantiq.com>
+ */
+
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/delay.h>
+#include <linux/workqueue.h>
+
+#include <lantiq_soc.h>
+
+#define DRV_NAME "falcon_spi"
+
+#define FALCON_SPI_XFER_BEGIN (1 << 0)
+#define FALCON_SPI_XFER_END (1 << 1)
+
+/* Bus Read Configuration Register0 */
+#define LTQ_BUSRCON0 0x00000010
+/* Bus Write Configuration Register0 */
+#define LTQ_BUSWCON0 0x00000018
+/* Serial Flash Configuration Register */
+#define LTQ_SFCON 0x00000080
+/* Serial Flash Time Register */
+#define LTQ_SFTIME 0x00000084
+/* Serial Flash Status Register */
+#define LTQ_SFSTAT 0x00000088
+/* Serial Flash Command Register */
+#define LTQ_SFCMD 0x0000008C
+/* Serial Flash Address Register */
+#define LTQ_SFADDR 0x00000090
+/* Serial Flash Data Register */
+#define LTQ_SFDATA 0x00000094
+/* Serial Flash I/O Control Register */
+#define LTQ_SFIO 0x00000098
+/* EBU Clock Control Register */
+#define LTQ_EBUCC 0x000000C4
+
+/* Dummy Phase Length */
+#define SFCMD_DUMLEN_OFFSET 16
+#define SFCMD_DUMLEN_MASK 0x000F0000
+/* Chip Select */
+#define SFCMD_CS_OFFSET 24
+#define SFCMD_CS_MASK 0x07000000
+/* field offset */
+#define SFCMD_ALEN_OFFSET 20
+#define SFCMD_ALEN_MASK 0x00700000
+/* SCK Rise-edge Position */
+#define SFTIME_SCKR_POS_OFFSET 8
+#define SFTIME_SCKR_POS_MASK 0x00000F00
+/* SCK Period */
+#define SFTIME_SCK_PER_OFFSET 0
+#define SFTIME_SCK_PER_MASK 0x0000000F
+/* SCK Fall-edge Position */
+#define SFTIME_SCKF_POS_OFFSET 12
+#define SFTIME_SCKF_POS_MASK 0x0000F000
+/* Device Size */
+#define SFCON_DEV_SIZE_A23_0 0x03000000
+#define SFCON_DEV_SIZE_MASK 0x0F000000
+/* Read Data Position */
+#define SFTIME_RD_POS_MASK 0x000F0000
+/* Data Output */
+#define SFIO_UNUSED_WD_MASK 0x0000000F
+/* Command Opcode mask */
+#define SFCMD_OPC_MASK 0x000000FF
+/* dlen bytes of data to write */
+#define SFCMD_DIR_WRITE 0x00000100
+/* Data Length offset */
+#define SFCMD_DLEN_OFFSET 9
+/* Command Error */
+#define SFSTAT_CMD_ERR 0x20000000
+/* Access Command Pending */
+#define SFSTAT_CMD_PEND 0x00400000
+/* Frequency set to 100MHz. */
+#define EBUCC_EBUDIV_SELF100 0x00000001
+/* Serial Flash */
+#define BUSRCON0_AGEN_SERIAL_FLASH 0xF0000000
+/* 8-bit multiplexed */
+#define BUSRCON0_PORTW_8_BIT_MUX 0x00000000
+/* Serial Flash */
+#define BUSWCON0_AGEN_SERIAL_FLASH 0xF0000000
+/* Chip Select after opcode */
+#define SFCMD_KEEP_CS_KEEP_SELECTED 0x00008000
+
+struct falcon_spi {
+ u32 sfcmd; /* for caching of opcode, direction, ... */
+ struct spi_master *master;
+};
+
+int
+falcon_spi_xfer(struct spi_device *spi,
+ struct spi_transfer *t,
+ unsigned long flags)
+{
+ struct device *dev = &spi->dev;
+ struct falcon_spi *priv = spi_master_get_devdata(spi->master);
+ const u8 *txp = t->tx_buf;
+ u8 *rxp = t->rx_buf;
+ unsigned int bytelen = ((8 * t->len + 7) / 8);
+ unsigned int len, alen, dumlen;
+ u32 val;
+ enum {
+ state_init,
+ state_command_prepare,
+ state_write,
+ state_read,
+ state_disable_cs,
+ state_end
+ } state = state_init;
+
+ do {
+ switch (state) {
+ case state_init: /* detect phase of upper layer sequence */
+ {
+ /* initial write ? */
+ if (flags & FALCON_SPI_XFER_BEGIN) {
+ if (!txp) {
+ dev_err(dev,
+ "BEGIN without tx data!\n");
+ return -1;
+ }
+ /*
+ * Prepare the parts of the sfcmd register,
+ * which should not
+ * change during a sequence!
+ * Only exception are the length fields,
+ * especially alen and dumlen.
+ */
+
+ priv->sfcmd = ((spi->chip_select
+ << SFCMD_CS_OFFSET)
+ & SFCMD_CS_MASK);
+ priv->sfcmd |= SFCMD_KEEP_CS_KEEP_SELECTED;
+ priv->sfcmd |= *txp;
+ txp++;
+ bytelen--;
+ if (bytelen) {
+ /*
+ * more data:
+ * maybe address and/or dummy
+ */
+ state = state_command_prepare;
+ break;
+ } else {
+ dev_dbg(dev, "write cmd %02X\n",
+ priv->sfcmd & SFCMD_OPC_MASK);
+ }
+ }
+ /* continued write ? */
+ if (txp && bytelen) {
+ state = state_write;
+ break;
+ }
+ /* read data? */
+ if (rxp && bytelen) {
+ state = state_read;
+ break;
+ }
+ /* end of sequence? */
+ if (flags & FALCON_SPI_XFER_END)
+ state = state_disable_cs;
+ else
+ state = state_end;
+ break;
+ }
+ /* collect tx data for address and dummy phase */
+ case state_command_prepare:
+ {
+ /* txp is valid, already checked */
+ val = 0;
+ alen = 0;
+ dumlen = 0;
+ while (bytelen > 0) {
+ if (alen < 3) {
+ val = (val<<8)|(*txp++);
+ alen++;
+ } else if ((dumlen < 15) && (*txp == 0)) {
+ /*
+ * assume dummy bytes are set to 0
+ * from upper layer
+ */
+ dumlen++;
+ txp++;
+ } else
+ break;
+ bytelen--;
+ }
+ priv->sfcmd &= ~(SFCMD_ALEN_MASK | SFCMD_DUMLEN_MASK);
+ priv->sfcmd |= (alen << SFCMD_ALEN_OFFSET) |
+ (dumlen << SFCMD_DUMLEN_OFFSET);
+ if (alen > 0)
+ ltq_ebu_w32(val, LTQ_SFADDR);
+
+ dev_dbg(dev, "write cmd %02X, alen=%d "
+ "(addr=%06X) dumlen=%d\n",
+ priv->sfcmd & SFCMD_OPC_MASK,
+ alen, val, dumlen);
+
+ if (bytelen > 0) {
+ /* continue with write */
+ state = state_write;
+ } else if (flags & FALCON_SPI_XFER_END) {
+ /* end of sequence? */
+ state = state_disable_cs;
+ } else {
+ /*
+ * go to end and expect another
+ * call (read or write)
+ */
+ state = state_end;
+ }
+ break;
+ }
+ case state_write:
+ {
+ /* txp still valid */
+ priv->sfcmd |= SFCMD_DIR_WRITE;
+ len = 0;
+ val = 0;
+ do {
+ if (bytelen--)
+ val |= (*txp++) << (8 * len++);
+ if ((flags & FALCON_SPI_XFER_END)
+ && (bytelen == 0)) {
+ priv->sfcmd &=
+ ~SFCMD_KEEP_CS_KEEP_SELECTED;
+ }
+ if ((len == 4) || (bytelen == 0)) {
+ ltq_ebu_w32(val, LTQ_SFDATA);
+ ltq_ebu_w32(priv->sfcmd
+ | (len<<SFCMD_DLEN_OFFSET),
+ LTQ_SFCMD);
+ len = 0;
+ val = 0;
+ priv->sfcmd &= ~(SFCMD_ALEN_MASK
+ | SFCMD_DUMLEN_MASK);
+ }
+ } while (bytelen);
+ state = state_end;
+ break;
+ }
+ case state_read:
+ {
+ /* read data */
+ priv->sfcmd &= ~SFCMD_DIR_WRITE;
+ do {
+ if ((flags & FALCON_SPI_XFER_END)
+ && (bytelen <= 4)) {
+ priv->sfcmd &=
+ ~SFCMD_KEEP_CS_KEEP_SELECTED;
+ }
+ len = (bytelen > 4) ? 4 : bytelen;
+ bytelen -= len;
+ ltq_ebu_w32(priv->sfcmd
+ |(len<<SFCMD_DLEN_OFFSET), LTQ_SFCMD);
+ priv->sfcmd &= ~(SFCMD_ALEN_MASK
+ | SFCMD_DUMLEN_MASK);
+ do {
+ val = ltq_ebu_r32(LTQ_SFSTAT);
+ if (val & SFSTAT_CMD_ERR) {
+ /* reset error status */
+ dev_err(dev, "SFSTAT: CMD_ERR "
+ "(%x)\n", val);
+ ltq_ebu_w32(SFSTAT_CMD_ERR,
+ LTQ_SFSTAT);
+ return -1;
+ }
+ } while (val & SFSTAT_CMD_PEND);
+ val = ltq_ebu_r32(LTQ_SFDATA);
+ do {
+ *rxp = (val & 0xFF);
+ rxp++;
+ val >>= 8;
+ len--;
+ } while (len);
+ } while (bytelen);
+ state = state_end;
+ break;
+ }
+ case state_disable_cs:
+ {
+ priv->sfcmd &= ~SFCMD_KEEP_CS_KEEP_SELECTED;
+ ltq_ebu_w32(priv->sfcmd | (0 << SFCMD_DLEN_OFFSET),
+ LTQ_SFCMD);
+ val = ltq_ebu_r32(LTQ_SFSTAT);
+ if (val & SFSTAT_CMD_ERR) {
+ /* reset error status */
+ dev_err(dev, "SFSTAT: CMD_ERR (%x)\n", val);
+ ltq_ebu_w32(SFSTAT_CMD_ERR, LTQ_SFSTAT);
+ return -1;
+ }
+ state = state_end;
+ break;
+ }
+ case state_end:
+ break;
+ }
+ } while (state != state_end);
+
+ return 0;
+}
+
+static int
+falcon_spi_setup(struct spi_device *spi)
+{
+ struct device *dev = &spi->dev;
+ const u32 ebuclk = 100000000;
+ unsigned int i;
+ unsigned long flags;
+
+ dev_dbg(dev, "setup\n");
+
+ if (spi->master->bus_num > 0 || spi->chip_select > 0)
+ return -ENODEV;
+
+ spin_lock_irqsave(&ebu_lock, flags);
+
+ if (ebuclk < spi->max_speed_hz) {
+ /* set EBU clock to 100 MHz */
+ ltq_sys1_w32_mask(0, EBUCC_EBUDIV_SELF100, LTQ_EBUCC);
+ i = 1; /* divider */
+ } else {
+ /* set EBU clock to 50 MHz */
+ ltq_sys1_w32_mask(EBUCC_EBUDIV_SELF100, 0, LTQ_EBUCC);
+
+ /* search for suitable divider */
+ for (i = 1; i < 7; i++) {
+ if (ebuclk / i <= spi->max_speed_hz)
+ break;
+ }
+ }
+
+ /* setup period of serial clock */
+ ltq_ebu_w32_mask(SFTIME_SCKF_POS_MASK
+ | SFTIME_SCKR_POS_MASK
+ | SFTIME_SCK_PER_MASK,
+ (i << SFTIME_SCKR_POS_OFFSET)
+ | (i << (SFTIME_SCK_PER_OFFSET + 1)),
+ LTQ_SFTIME);
+
+ /*
+ * set some bits of unused_wd, to not trigger HOLD/WP
+ * signals on non QUAD flashes
+ */
+ ltq_ebu_w32((SFIO_UNUSED_WD_MASK & (0x8 | 0x4)), LTQ_SFIO);
+
+ ltq_ebu_w32(BUSRCON0_AGEN_SERIAL_FLASH | BUSRCON0_PORTW_8_BIT_MUX,
+ LTQ_BUSRCON0);
+ ltq_ebu_w32(BUSWCON0_AGEN_SERIAL_FLASH, LTQ_BUSWCON0);
+ /* set address wrap around to maximum for 24-bit addresses */
+ ltq_ebu_w32_mask(SFCON_DEV_SIZE_MASK, SFCON_DEV_SIZE_A23_0, LTQ_SFCON);
+
+ spin_unlock_irqrestore(&ebu_lock, flags);
+
+ return 0;
+}
+
+static int
+falcon_spi_transfer(struct spi_device *spi, struct spi_message *m)
+{
+ struct falcon_spi *priv = spi_master_get_devdata(spi->master);
+ struct spi_transfer *t;
+ unsigned long spi_flags;
+ unsigned long flags;
+ int ret = 0;
+
+ priv->sfcmd = 0;
+ m->actual_length = 0;
+
+ spi_flags = FALCON_SPI_XFER_BEGIN;
+ list_for_each_entry(t, &m->transfers, transfer_list) {
+ if (list_is_last(&t->transfer_list, &m->transfers))
+ spi_flags |= FALCON_SPI_XFER_END;
+
+ spin_lock_irqsave(&ebu_lock, flags);
+ ret = falcon_spi_xfer(spi, t, spi_flags);
+ spin_unlock_irqrestore(&ebu_lock, flags);
+
+ if (ret)
+ break;
+
+ m->actual_length += t->len;
+
+ if (t->delay_usecs || t->cs_change)
+ BUG();
+
+ spi_flags = 0;
+ }
+
+ m->status = ret;
+ m->complete(m->context);
+
+ return 0;
+}
+
+static void
+falcon_spi_cleanup(struct spi_device *spi)
+{
+ struct device *dev = &spi->dev;
+
+ dev_dbg(dev, "cleanup\n");
+}
+
+static int __devinit
+falcon_spi_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct falcon_spi *priv;
+ struct spi_master *master;
+ int ret;
+
+ dev_dbg(dev, "probing\n");
+
+ master = spi_alloc_master(&pdev->dev, sizeof(*priv));
+ if (!master) {
+ dev_err(dev, "no memory for spi_master\n");
+ return -ENOMEM;
+ }
+
+ priv = spi_master_get_devdata(master);
+ priv->master = master;
+
+ master->mode_bits = SPI_MODE_3;
+ master->num_chipselect = 1;
+ master->bus_num = 0;
+
+ master->setup = falcon_spi_setup;
+ master->transfer = falcon_spi_transfer;
+ master->cleanup = falcon_spi_cleanup;
+
+ platform_set_drvdata(pdev, priv);
+
+ ret = spi_register_master(master);
+ if (ret)
+ spi_master_put(master);
+
+ return ret;
+}
+
+static int __devexit
+falcon_spi_remove(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct falcon_spi *priv = platform_get_drvdata(pdev);
+
+ dev_dbg(dev, "removed\n");
+
+ spi_unregister_master(priv->master);
+
+ return 0;
+}
+
+static struct platform_driver falcon_spi_driver = {
+ .probe = falcon_spi_probe,
+ .remove = __devexit_p(falcon_spi_remove),
+ .driver = {
+ .name = DRV_NAME,
+ .owner = THIS_MODULE
+ }
+};
+
+static int __init
+falcon_spi_init(void)
+{
+ return platform_driver_register(&falcon_spi_driver);
+}
+
+static void __exit
+falcon_spi_exit(void)
+{
+ platform_driver_unregister(&falcon_spi_driver);
+}
+
+module_init(falcon_spi_init);
+module_exit(falcon_spi_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Lantiq Falcon SPI controller driver");

View File

@ -1,294 +0,0 @@
From e125a83872c5b400852efbd451786c42bd395f11 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Sat, 27 Aug 2011 20:08:14 +0200
Subject: [PATCH 40/73] MIPS: lantiq: add xway nand driver
This patch adds a nand driver for XWAY SoCs. The patch makes use of the
plat_nand driver. As with the EBU NOR driver merged in 3.0, we have the
endianess swap problem on read. To workaround this problem we make the
read_byte() callback available via the plat_nand driver causing the nand
layer to do byte reads.
Signed-off-by: John Crispin <blogic@openwrt.org>
TODO : memory ranges
cs lines
plat dev
ebu2 and not ebu1 ?
---
.../mips/include/asm/mach-lantiq/xway/lantiq_soc.h | 2 +
arch/mips/lantiq/xway/Makefile | 2 +-
arch/mips/lantiq/xway/devices.h | 1 +
arch/mips/lantiq/xway/nand.c | 216 ++++++++++++++++++++
drivers/mtd/nand/plat_nand.c | 1 +
include/linux/mtd/nand.h | 1 +
6 files changed, 222 insertions(+), 1 deletions(-)
create mode 100644 arch/mips/lantiq/xway/nand.c
--- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
+++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
@@ -145,6 +145,8 @@
/* register access macros for EBU and CGU */
#define ltq_ebu_w32(x, y) ltq_w32((x), ltq_ebu_membase + (y))
#define ltq_ebu_r32(x) ltq_r32(ltq_ebu_membase + (x))
+#define ltq_ebu_w32_mask(x, y, z) \
+ ltq_w32_mask(x, y, ltq_ebu_membase + (z))
#define ltq_cgu_w32(x, y) ltq_w32((x), ltq_cgu_membase + (y))
#define ltq_cgu_r32(x) ltq_r32(ltq_cgu_membase + (x))
--- a/arch/mips/lantiq/xway/Makefile
+++ b/arch/mips/lantiq/xway/Makefile
@@ -1,4 +1,4 @@
-obj-y := sysctrl.o reset.o gpio.o gpio_stp.o gpio_ebu.o devices.o dma.o clk.o prom.o
+obj-y := sysctrl.o reset.o gpio.o gpio_stp.o gpio_ebu.o devices.o dma.o clk.o prom.o nand.o
obj-$(CONFIG_LANTIQ_MACH_EASY50712) += mach-easy50712.o
obj-$(CONFIG_LANTIQ_MACH_EASY50601) += mach-easy50601.o
--- a/arch/mips/lantiq/xway/devices.h
+++ b/arch/mips/lantiq/xway/devices.h
@@ -16,5 +16,6 @@ extern void ltq_register_gpio(void);
extern void ltq_register_gpio_stp(void);
extern void ltq_register_ase_asc(void);
extern void ltq_register_etop(struct ltq_eth_data *eth);
+extern void xway_register_nand(struct mtd_partition *parts, int count);
#endif
--- /dev/null
+++ b/arch/mips/lantiq/xway/nand.c
@@ -0,0 +1,216 @@
+/*
+ * 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.
+ *
+ * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/nand.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#include <lantiq_soc.h>
+#include <lantiq_irq.h>
+#include <lantiq_platform.h>
+
+#include "devices.h"
+
+/* nand registers */
+#define LTQ_EBU_NAND_WAIT 0xB4
+#define LTQ_EBU_NAND_ECC0 0xB8
+#define LTQ_EBU_NAND_ECC_AC 0xBC
+#define LTQ_EBU_NAND_CON 0xB0
+#define LTQ_EBU_ADDSEL1 0x24
+
+/* gpio definitions */
+#define PIN_ALE 13
+#define PIN_CLE 24
+#define PIN_CS1 23
+#define PIN_RDY 48 /* NFLASH_READY */
+#define PIN_RD 49 /* NFLASH_READ_N */
+
+#define NAND_CMD_ALE (1 << 2)
+#define NAND_CMD_CLE (1 << 3)
+#define NAND_CMD_CS (1 << 4)
+#define NAND_WRITE_CMD_RESET 0xff
+#define NAND_WRITE_CMD (NAND_CMD_CS | NAND_CMD_CLE)
+#define NAND_WRITE_ADDR (NAND_CMD_CS | NAND_CMD_ALE)
+#define NAND_WRITE_DATA (NAND_CMD_CS)
+#define NAND_READ_DATA (NAND_CMD_CS)
+#define NAND_WAIT_WR_C (1 << 3)
+#define NAND_WAIT_RD (0x1)
+
+#define ADDSEL1_MASK(x) (x << 4)
+#define ADDSEL1_REGEN 1
+#define BUSCON1_SETUP (1 << 22)
+#define BUSCON1_BCGEN_RES (0x3 << 12)
+#define BUSCON1_WAITWRC2 (2 << 8)
+#define BUSCON1_WAITRDC2 (2 << 6)
+#define BUSCON1_HOLDC1 (1 << 4)
+#define BUSCON1_RECOVC1 (1 << 2)
+#define BUSCON1_CMULT4 1
+#define NAND_CON_NANDM 1
+#define NAND_CON_CSMUX (1 << 1)
+#define NAND_CON_CS_P (1 << 4)
+#define NAND_CON_SE_P (1 << 5)
+#define NAND_CON_WP_P (1 << 6)
+#define NAND_CON_PRE_P (1 << 7)
+#define NAND_CON_IN_CS0 0
+#define NAND_CON_OUT_CS0 0
+#define NAND_CON_IN_CS1 (1 << 8)
+#define NAND_CON_OUT_CS1 (1 << 10)
+#define NAND_CON_CE (1 << 20)
+
+#define NAND_BASE_ADDRESS (KSEG1 | 0x14000000)
+
+static const char *part_probes[] = { "cmdlinepart", NULL };
+
+static void xway_select_chip(struct mtd_info *mtd, int chip)
+{
+ switch (chip) {
+ case -1:
+ ltq_ebu_w32_mask(NAND_CON_CE, 0, LTQ_EBU_NAND_CON);
+ ltq_ebu_w32_mask(NAND_CON_NANDM, 0, LTQ_EBU_NAND_CON);
+ break;
+ case 0:
+ ltq_ebu_w32_mask(0, NAND_CON_NANDM, LTQ_EBU_NAND_CON);
+ ltq_ebu_w32_mask(0, NAND_CON_CE, LTQ_EBU_NAND_CON);
+ /* reset the nand chip */
+ while ((ltq_ebu_r32(LTQ_EBU_NAND_WAIT) & NAND_WAIT_WR_C) == 0)
+ ;
+ ltq_w32(NAND_WRITE_CMD_RESET,
+ ((u32 *) (NAND_BASE_ADDRESS | NAND_WRITE_CMD)));
+ break;
+ default:
+ BUG();
+ }
+}
+
+static void xway_cmd_ctrl(struct mtd_info *mtd, int data, unsigned int ctrl)
+{
+ struct nand_chip *this = mtd->priv;
+
+ if (ctrl & NAND_CTRL_CHANGE) {
+ if (ctrl & NAND_CLE)
+ this->IO_ADDR_W = (void __iomem *)
+ (NAND_BASE_ADDRESS | NAND_WRITE_CMD);
+ else if (ctrl & NAND_ALE)
+ this->IO_ADDR_W = (void __iomem *)
+ (NAND_BASE_ADDRESS | NAND_WRITE_ADDR);
+ }
+
+ if (data != NAND_CMD_NONE) {
+ *(volatile u8*) ((u32) this->IO_ADDR_W) = data;
+ while ((ltq_ebu_r32(LTQ_EBU_NAND_WAIT) & NAND_WAIT_WR_C) == 0)
+ ;
+ }
+}
+
+static int xway_dev_ready(struct mtd_info *mtd)
+{
+ return ltq_ebu_r32(LTQ_EBU_NAND_WAIT) & NAND_WAIT_RD;
+}
+
+void nand_write(unsigned int addr, unsigned int val)
+{
+ ltq_w32(val, ((u32 *) (NAND_BASE_ADDRESS | addr)));
+ while ((ltq_ebu_r32(LTQ_EBU_NAND_WAIT) & NAND_WAIT_WR_C) == 0)
+ ;
+}
+
+unsigned char xway_read_byte(struct mtd_info *mtd)
+{
+ return ltq_r8((void __iomem *)(NAND_BASE_ADDRESS | (NAND_READ_DATA)));
+}
+
+static void xway_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
+{
+ int i;
+
+ for (i = 0; i < len; i++)
+ {
+ unsigned char res8 = ltq_r8((void __iomem *)(NAND_BASE_ADDRESS | (NAND_READ_DATA)));
+ buf[i] = res8;
+ }
+}
+
+static void xway_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
+{
+ int i;
+
+ for (i = 0; i < len; i++)
+ {
+ ltq_w8(buf[i], ((u32*)(NAND_BASE_ADDRESS | (NAND_WRITE_DATA))));
+ while((ltq_ebu_r32(LTQ_EBU_NAND_WAIT) & NAND_WAIT_WR_C) == 0);
+ }
+}
+
+int xway_probe(struct platform_device *pdev)
+{
+ /* might need this later ?
+ ltq_gpio_request(PIN_CS1, 2, 1, "NAND_CS1");
+ */
+ ltq_gpio_request(&pdev->dev, PIN_CLE, 2, 1, "NAND_CLE");
+ ltq_gpio_request(&pdev->dev, PIN_ALE, 2, 1, "NAND_ALE");
+ if (ltq_is_ar9() || ltq_is_vr9()) {
+ ltq_gpio_request(&pdev->dev, PIN_RDY, 2, 0, "NAND_BSY");
+ ltq_gpio_request(&pdev->dev, PIN_RD, 2, 1, "NAND_RD");
+ }
+
+ ltq_ebu_w32((NAND_BASE_ADDRESS & 0x1fffff00)
+ | ADDSEL1_MASK(3) | ADDSEL1_REGEN, LTQ_EBU_ADDSEL1);
+
+ ltq_ebu_w32(BUSCON1_SETUP | BUSCON1_BCGEN_RES | BUSCON1_WAITWRC2
+ | BUSCON1_WAITRDC2 | BUSCON1_HOLDC1 | BUSCON1_RECOVC1
+ | BUSCON1_CMULT4, LTQ_EBU_BUSCON1);
+
+ ltq_ebu_w32(NAND_CON_NANDM | NAND_CON_CSMUX | NAND_CON_CS_P
+ | NAND_CON_SE_P | NAND_CON_WP_P | NAND_CON_PRE_P
+ | NAND_CON_IN_CS0 | NAND_CON_OUT_CS0, LTQ_EBU_NAND_CON);
+
+ ltq_w32(NAND_WRITE_CMD_RESET,
+ ((u32 *) (NAND_BASE_ADDRESS | NAND_WRITE_CMD)));
+ while ((ltq_ebu_r32(LTQ_EBU_NAND_WAIT) & NAND_WAIT_WR_C) == 0)
+ ;
+
+ return 0;
+}
+
+static struct platform_nand_data falcon_flash_nand_data = {
+ .chip = {
+ .nr_chips = 1,
+ .chip_delay = 30,
+ .part_probe_types = part_probes,
+ },
+ .ctrl = {
+ .probe = xway_probe,
+ .cmd_ctrl = xway_cmd_ctrl,
+ .dev_ready = xway_dev_ready,
+ .select_chip = xway_select_chip,
+ .read_byte = xway_read_byte,
+ .read_buf = xway_read_buf,
+ .write_buf = xway_write_buf,
+ }
+};
+
+static struct resource ltq_nand_res =
+ MEM_RES("nand", 0x14000000, 0x7ffffff);
+
+static struct platform_device ltq_flash_nand = {
+ .name = "gen_nand",
+ .id = -1,
+ .num_resources = 1,
+ .resource = &ltq_nand_res,
+ .dev = {
+ .platform_data = &falcon_flash_nand_data,
+ },
+};
+
+void __init xway_register_nand(struct mtd_partition *parts, int count)
+{
+ falcon_flash_nand_data.chip.partitions = parts;
+ falcon_flash_nand_data.chip.nr_partitions = count;
+ platform_device_register(&ltq_flash_nand);
+}
--- a/drivers/mtd/nand/plat_nand.c
+++ b/drivers/mtd/nand/plat_nand.c
@@ -75,6 +75,7 @@ static int __devinit plat_nand_probe(str
data->chip.select_chip = pdata->ctrl.select_chip;
data->chip.write_buf = pdata->ctrl.write_buf;
data->chip.read_buf = pdata->ctrl.read_buf;
+ data->chip.read_byte = pdata->ctrl.read_byte;
data->chip.chip_delay = pdata->chip.chip_delay;
data->chip.options |= pdata->chip.options;
data->chip.bbt_options |= pdata->chip.bbt_options;
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -651,6 +651,7 @@ struct platform_nand_ctrl {
void (*cmd_ctrl)(struct mtd_info *mtd, int dat, unsigned int ctrl);
void (*write_buf)(struct mtd_info *mtd, const uint8_t *buf, int len);
void (*read_buf)(struct mtd_info *mtd, uint8_t *buf, int len);
+ unsigned char (*read_byte)(struct mtd_info *mtd);
void *priv;
};

View File

@ -1,440 +0,0 @@
From 7fd67cfebce500eaeaf209c303d7c1edf1aa34db Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Wed, 21 Mar 2012 18:14:06 +0100
Subject: [PATCH 43/73] MIPS: NET: several fixes to etop driver
---
drivers/net/ethernet/lantiq_etop.c | 208 +++++++++++++++++++-----------------
1 files changed, 108 insertions(+), 100 deletions(-)
--- a/drivers/net/ethernet/lantiq_etop.c
+++ b/drivers/net/ethernet/lantiq_etop.c
@@ -103,15 +103,6 @@
/* the newer xway socks have a embedded 3/7 port gbit multiplexer */
#define ltq_has_gbit() (ltq_is_ar9() || ltq_is_vr9())
-/* use 2 static channels for TX/RX
- depending on the SoC we need to use different DMA channels for ethernet */
-#define LTQ_ETOP_TX_CHANNEL 1
-#define LTQ_ETOP_RX_CHANNEL ((ltq_is_ase()) ? (5) : \
- ((ltq_has_gbit()) ? (0) : (6)))
-
-#define IS_TX(x) (x == LTQ_ETOP_TX_CHANNEL)
-#define IS_RX(x) (x == LTQ_ETOP_RX_CHANNEL)
-
#define ltq_etop_r32(x) ltq_r32(ltq_etop_membase + (x))
#define ltq_etop_w32(x, y) ltq_w32(x, ltq_etop_membase + (y))
#define ltq_etop_w32_mask(x, y, z) \
@@ -128,8 +119,8 @@ static void __iomem *ltq_etop_membase;
static void __iomem *ltq_gbit_membase;
struct ltq_etop_chan {
- int idx;
int tx_free;
+ int irq;
struct net_device *netdev;
struct napi_struct napi;
struct ltq_dma_channel dma;
@@ -144,8 +135,8 @@ struct ltq_etop_priv {
struct mii_bus *mii_bus;
struct phy_device *phydev;
- struct ltq_etop_chan ch[MAX_DMA_CHAN];
- int tx_free[MAX_DMA_CHAN >> 1];
+ struct ltq_etop_chan txch;
+ struct ltq_etop_chan rxch;
spinlock_t lock;
@@ -206,8 +197,10 @@ ltq_etop_poll_rx(struct napi_struct *nap
{
struct ltq_etop_chan *ch = container_of(napi,
struct ltq_etop_chan, napi);
+ struct ltq_etop_priv *priv = netdev_priv(ch->netdev);
int rx = 0;
int complete = 0;
+ unsigned long flags;
while ((rx < budget) && !complete) {
struct ltq_dma_desc *desc = &ch->dma.desc_base[ch->dma.desc];
@@ -221,7 +214,9 @@ ltq_etop_poll_rx(struct napi_struct *nap
}
if (complete || !rx) {
napi_complete(&ch->napi);
+ spin_lock_irqsave(&priv->lock, flags);
ltq_dma_ack_irq(&ch->dma);
+ spin_unlock_irqrestore(&priv->lock, flags);
}
return rx;
}
@@ -233,7 +228,7 @@ ltq_etop_poll_tx(struct napi_struct *nap
container_of(napi, struct ltq_etop_chan, napi);
struct ltq_etop_priv *priv = netdev_priv(ch->netdev);
struct netdev_queue *txq =
- netdev_get_tx_queue(ch->netdev, ch->idx >> 1);
+ netdev_get_tx_queue(ch->netdev, ch->dma.nr >> 1);
unsigned long flags;
spin_lock_irqsave(&priv->lock, flags);
@@ -251,7 +246,9 @@ ltq_etop_poll_tx(struct napi_struct *nap
if (netif_tx_queue_stopped(txq))
netif_tx_start_queue(txq);
napi_complete(&ch->napi);
+ spin_lock_irqsave(&priv->lock, flags);
ltq_dma_ack_irq(&ch->dma);
+ spin_unlock_irqrestore(&priv->lock, flags);
return 1;
}
@@ -259,9 +256,10 @@ static irqreturn_t
ltq_etop_dma_irq(int irq, void *_priv)
{
struct ltq_etop_priv *priv = _priv;
- int ch = irq - LTQ_DMA_ETOP;
-
- napi_schedule(&priv->ch[ch].napi);
+ if (irq == priv->txch.dma.irq)
+ napi_schedule(&priv->txch.napi);
+ else
+ napi_schedule(&priv->rxch.napi);
return IRQ_HANDLED;
}
@@ -273,7 +271,7 @@ ltq_etop_free_channel(struct net_device
ltq_dma_free(&ch->dma);
if (ch->dma.irq)
free_irq(ch->dma.irq, priv);
- if (IS_RX(ch->idx)) {
+ if (ch == &priv->txch) {
int desc;
for (desc = 0; desc < LTQ_DESC_NUM; desc++)
dev_kfree_skb_any(ch->skb[ch->dma.desc]);
@@ -284,7 +282,6 @@ static void
ltq_etop_hw_exit(struct net_device *dev)
{
struct ltq_etop_priv *priv = netdev_priv(dev);
- int i;
clk_disable(priv->clk_ppe);
@@ -296,9 +293,8 @@ ltq_etop_hw_exit(struct net_device *dev)
clk_disable(priv->clk_ephycgu);
}
- for (i = 0; i < MAX_DMA_CHAN; i++)
- if (IS_TX(i) || IS_RX(i))
- ltq_etop_free_channel(dev, &priv->ch[i]);
+ ltq_etop_free_channel(dev, &priv->txch);
+ ltq_etop_free_channel(dev, &priv->rxch);
}
static void
@@ -326,8 +322,6 @@ ltq_etop_hw_init(struct net_device *dev)
{
struct ltq_etop_priv *priv = netdev_priv(dev);
unsigned int mii_mode = priv->pldata->mii_mode;
- int err = 0;
- int i;
clk_enable(priv->clk_ppe);
@@ -369,31 +363,50 @@ ltq_etop_hw_init(struct net_device *dev)
/* enable crc generation */
ltq_etop_w32(PPE32_CGEN, LQ_PPE32_ENET_MAC_CFG);
+ return 0;
+}
+
+static int
+ltq_etop_dma_init(struct net_device *dev)
+{
+ struct ltq_etop_priv *priv = netdev_priv(dev);
+ int tx = 1;
+ int rx = ((ltq_is_ase()) ? (5) : \
+ ((ltq_is_ar9()) ? (0) : (6)));
+ int tx_irq = LTQ_DMA_ETOP + tx;
+ int rx_irq = LTQ_DMA_ETOP + rx;
+ int err;
+
ltq_dma_init_port(DMA_PORT_ETOP);
- for (i = 0; i < MAX_DMA_CHAN && !err; i++) {
- int irq = LTQ_DMA_ETOP + i;
- struct ltq_etop_chan *ch = &priv->ch[i];
-
- ch->idx = ch->dma.nr = i;
-
- if (IS_TX(i)) {
- ltq_dma_alloc_tx(&ch->dma);
- err = request_irq(irq, ltq_etop_dma_irq, IRQF_DISABLED,
- "etop_tx", priv);
- } else if (IS_RX(i)) {
- ltq_dma_alloc_rx(&ch->dma);
- for (ch->dma.desc = 0; ch->dma.desc < LTQ_DESC_NUM;
- ch->dma.desc++)
- if (ltq_etop_alloc_skb(ch))
- err = -ENOMEM;
- ch->dma.desc = 0;
- err = request_irq(irq, ltq_etop_dma_irq, IRQF_DISABLED,
- "etop_rx", priv);
+ priv->txch.dma.nr = tx;
+ ltq_dma_alloc_tx(&priv->txch.dma);
+ err = request_irq(tx_irq, ltq_etop_dma_irq, IRQF_DISABLED,
+ "eth_tx", priv);
+ if (err) {
+ netdev_err(dev, "failed to allocate tx irq\n");
+ goto err_out;
+ }
+ priv->txch.dma.irq = tx_irq;
+
+ priv->rxch.dma.nr = rx;
+ ltq_dma_alloc_rx(&priv->rxch.dma);
+ for (priv->rxch.dma.desc = 0; priv->rxch.dma.desc < LTQ_DESC_NUM;
+ priv->rxch.dma.desc++) {
+ if (ltq_etop_alloc_skb(&priv->rxch)) {
+ netdev_err(dev, "failed to allocate skbs\n");
+ err = -ENOMEM;
+ goto err_out;
}
- if (!err)
- ch->dma.irq = irq;
}
+ priv->rxch.dma.desc = 0;
+ err = request_irq(rx_irq, ltq_etop_dma_irq, IRQF_DISABLED,
+ "eth_rx", priv);
+ if (err)
+ netdev_err(dev, "failed to allocate rx irq\n");
+ else
+ priv->rxch.dma.irq = rx_irq;
+err_out:
return err;
}
@@ -410,7 +423,10 @@ ltq_etop_get_settings(struct net_device
{
struct ltq_etop_priv *priv = netdev_priv(dev);
- return phy_ethtool_gset(priv->phydev, cmd);
+ if (priv->phydev)
+ return phy_ethtool_gset(priv->phydev, cmd);
+ else
+ return 0;
}
static int
@@ -418,7 +434,10 @@ ltq_etop_set_settings(struct net_device
{
struct ltq_etop_priv *priv = netdev_priv(dev);
- return phy_ethtool_sset(priv->phydev, cmd);
+ if (priv->phydev)
+ return phy_ethtool_sset(priv->phydev, cmd);
+ else
+ return 0;
}
static int
@@ -426,7 +445,10 @@ ltq_etop_nway_reset(struct net_device *d
{
struct ltq_etop_priv *priv = netdev_priv(dev);
- return phy_start_aneg(priv->phydev);
+ if (priv->phydev)
+ return phy_start_aneg(priv->phydev);
+ else
+ return 0;
}
static const struct ethtool_ops ltq_etop_ethtool_ops = {
@@ -618,18 +640,19 @@ static int
ltq_etop_open(struct net_device *dev)
{
struct ltq_etop_priv *priv = netdev_priv(dev);
- int i;
+ unsigned long flags;
- for (i = 0; i < MAX_DMA_CHAN; i++) {
- struct ltq_etop_chan *ch = &priv->ch[i];
+ napi_enable(&priv->txch.napi);
+ napi_enable(&priv->rxch.napi);
+
+ spin_lock_irqsave(&priv->lock, flags);
+ ltq_dma_open(&priv->txch.dma);
+ ltq_dma_open(&priv->rxch.dma);
+ spin_unlock_irqrestore(&priv->lock, flags);
- if (!IS_TX(i) && (!IS_RX(i)))
- continue;
- ltq_dma_open(&ch->dma);
- napi_enable(&ch->napi);
- }
if (priv->phydev)
phy_start(priv->phydev);
+
netif_tx_start_all_queues(dev);
return 0;
}
@@ -638,19 +661,19 @@ static int
ltq_etop_stop(struct net_device *dev)
{
struct ltq_etop_priv *priv = netdev_priv(dev);
- int i;
+ unsigned long flags;
netif_tx_stop_all_queues(dev);
if (priv->phydev)
phy_stop(priv->phydev);
- for (i = 0; i < MAX_DMA_CHAN; i++) {
- struct ltq_etop_chan *ch = &priv->ch[i];
+ napi_disable(&priv->txch.napi);
+ napi_disable(&priv->rxch.napi);
+
+ spin_lock_irqsave(&priv->lock, flags);
+ ltq_dma_close(&priv->txch.dma);
+ ltq_dma_close(&priv->rxch.dma);
+ spin_unlock_irqrestore(&priv->lock, flags);
- if (!IS_RX(i) && !IS_TX(i))
- continue;
- napi_disable(&ch->napi);
- ltq_dma_close(&ch->dma);
- }
return 0;
}
@@ -660,16 +683,16 @@ ltq_etop_tx(struct sk_buff *skb, struct
int queue = skb_get_queue_mapping(skb);
struct netdev_queue *txq = netdev_get_tx_queue(dev, queue);
struct ltq_etop_priv *priv = netdev_priv(dev);
- struct ltq_etop_chan *ch = &priv->ch[(queue << 1) | 1];
- struct ltq_dma_desc *desc = &ch->dma.desc_base[ch->dma.desc];
+ struct ltq_dma_desc *desc =
+ &priv->txch.dma.desc_base[priv->txch.dma.desc];
unsigned long flags;
u32 byte_offset;
int len;
len = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len;
- if ((desc->ctl & (LTQ_DMA_OWN | LTQ_DMA_C)) || ch->skb[ch->dma.desc]) {
- dev_kfree_skb_any(skb);
+ if ((desc->ctl & (LTQ_DMA_OWN | LTQ_DMA_C)) ||
+ priv->txch.skb[priv->txch.dma.desc]) {
netdev_err(dev, "tx ring full\n");
netif_tx_stop_queue(txq);
return NETDEV_TX_BUSY;
@@ -677,7 +700,7 @@ ltq_etop_tx(struct sk_buff *skb, struct
/* dma needs to start on a 16 byte aligned address */
byte_offset = CPHYSADDR(skb->data) % 16;
- ch->skb[ch->dma.desc] = skb;
+ priv->txch.skb[priv->txch.dma.desc] = skb;
dev->trans_start = jiffies;
@@ -687,11 +710,11 @@ ltq_etop_tx(struct sk_buff *skb, struct
wmb();
desc->ctl = LTQ_DMA_OWN | LTQ_DMA_SOP | LTQ_DMA_EOP |
LTQ_DMA_TX_OFFSET(byte_offset) | (len & LTQ_DMA_SIZE_MASK);
- ch->dma.desc++;
- ch->dma.desc %= LTQ_DESC_NUM;
+ priv->txch.dma.desc++;
+ priv->txch.dma.desc %= LTQ_DESC_NUM;
spin_unlock_irqrestore(&priv->lock, flags);
- if (ch->dma.desc_base[ch->dma.desc].ctl & LTQ_DMA_OWN)
+ if (priv->txch.dma.desc_base[priv->txch.dma.desc].ctl & LTQ_DMA_OWN)
netif_tx_stop_queue(txq);
return NETDEV_TX_OK;
@@ -776,6 +799,10 @@ ltq_etop_init(struct net_device *dev)
err = ltq_etop_hw_init(dev);
if (err)
goto err_hw;
+ err = ltq_etop_dma_init(dev);
+ if (err)
+ goto err_hw;
+
ltq_etop_change_mtu(dev, 1500);
memcpy(&mac, &priv->pldata->mac, sizeof(struct sockaddr));
@@ -811,6 +838,9 @@ ltq_etop_tx_timeout(struct net_device *d
err = ltq_etop_hw_init(dev);
if (err)
goto err_hw;
+ err = ltq_etop_dma_init(dev);
+ if (err)
+ goto err_hw;
dev->trans_start = jiffies;
netif_wake_queue(dev);
return;
@@ -834,14 +864,13 @@ static const struct net_device_ops ltq_e
.ndo_tx_timeout = ltq_etop_tx_timeout,
};
-static int __init
+static int __devinit
ltq_etop_probe(struct platform_device *pdev)
{
struct net_device *dev;
struct ltq_etop_priv *priv;
struct resource *res, *gbit_res;
int err;
- int i;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
@@ -917,15 +946,10 @@ ltq_etop_probe(struct platform_device *p
spin_lock_init(&priv->lock);
- for (i = 0; i < MAX_DMA_CHAN; i++) {
- if (IS_TX(i))
- netif_napi_add(dev, &priv->ch[i].napi,
- ltq_etop_poll_tx, 8);
- else if (IS_RX(i))
- netif_napi_add(dev, &priv->ch[i].napi,
- ltq_etop_poll_rx, 32);
- priv->ch[i].netdev = dev;
- }
+ netif_napi_add(dev, &priv->txch.napi, ltq_etop_poll_tx, 8);
+ netif_napi_add(dev, &priv->rxch.napi, ltq_etop_poll_rx, 32);
+ priv->txch.netdev = dev;
+ priv->rxch.netdev = dev;
err = register_netdev(dev);
if (err)
@@ -955,6 +979,7 @@ ltq_etop_remove(struct platform_device *
}
static struct platform_driver ltq_mii_driver = {
+ .probe = ltq_etop_probe,
.remove = __devexit_p(ltq_etop_remove),
.driver = {
.name = "ltq_etop",
@@ -962,24 +987,7 @@ static struct platform_driver ltq_mii_dr
},
};
-int __init
-init_ltq_etop(void)
-{
- int ret = platform_driver_probe(&ltq_mii_driver, ltq_etop_probe);
-
- if (ret)
- pr_err("ltq_etop: Error registering platfom driver!");
- return ret;
-}
-
-static void __exit
-exit_ltq_etop(void)
-{
- platform_driver_unregister(&ltq_mii_driver);
-}
-
-module_init(init_ltq_etop);
-module_exit(exit_ltq_etop);
+module_platform_driver(ltq_mii_driver);
MODULE_AUTHOR("John Crispin <blogic@openwrt.org>");
MODULE_DESCRIPTION("Lantiq SoC ETOP");

View File

@ -1,59 +0,0 @@
From 8757ae55b11c87d75078b44384b27aadc52f2f22 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Mon, 20 Feb 2012 12:15:25 +0100
Subject: [PATCH 44/73] MTD: MIPS: lantiq: use module_platform_driver inside
lantiq map driver
Reduce boilerplate code by converting driver to module_platform_driver.
Signed-off-by: John Crispin <blogic@openwrt.org>
Cc: linux-mtd@lists.infradead.org
---
drivers/mtd/maps/lantiq-flash.c | 22 +++-------------------
1 files changed, 3 insertions(+), 19 deletions(-)
--- a/drivers/mtd/maps/lantiq-flash.c
+++ b/drivers/mtd/maps/lantiq-flash.c
@@ -108,7 +108,7 @@ ltq_copy_to(struct map_info *map, unsign
spin_unlock_irqrestore(&ebu_lock, flags);
}
-static int __init
+static int __devinit
ltq_mtd_probe(struct platform_device *pdev)
{
struct physmap_flash_data *ltq_mtd_data = dev_get_platdata(&pdev->dev);
@@ -208,6 +208,7 @@ ltq_mtd_remove(struct platform_device *p
}
static struct platform_driver ltq_mtd_driver = {
+ .probe = ltq_mtd_probe,
.remove = __devexit_p(ltq_mtd_remove),
.driver = {
.name = "ltq_nor",
@@ -215,24 +216,7 @@ static struct platform_driver ltq_mtd_dr
},
};
-static int __init
-init_ltq_mtd(void)
-{
- int ret = platform_driver_probe(&ltq_mtd_driver, ltq_mtd_probe);
-
- if (ret)
- pr_err("ltq_nor: error registering platform driver");
- return ret;
-}
-
-static void __exit
-exit_ltq_mtd(void)
-{
- platform_driver_unregister(&ltq_mtd_driver);
-}
-
-module_init(init_ltq_mtd);
-module_exit(exit_ltq_mtd);
+module_platform_driver(ltq_mtd_driver);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("John Crispin <blogic@openwrt.org>");

View File

@ -1,56 +0,0 @@
From 3b8b06b76d01136fa4e195a10c5ee12b2352616e Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Mon, 20 Feb 2012 12:16:31 +0100
Subject: [PATCH 45/73] WDT: MIPS: lantiq: use module_platform_driver inside
lantiq watchdog driver
Reduce boilerplate code by converting driver to module_platform_driver.
Signed-off-by: John Crispin <blogic@openwrt.org>
Cc: linux-watchdog@vger.kernel.org
---
drivers/watchdog/lantiq_wdt.c | 19 +++----------------
1 files changed, 3 insertions(+), 16 deletions(-)
--- a/drivers/watchdog/lantiq_wdt.c
+++ b/drivers/watchdog/lantiq_wdt.c
@@ -182,7 +182,7 @@ static struct miscdevice ltq_wdt_miscdev
.fops = &ltq_wdt_fops,
};
-static int __init
+static int __devinit
ltq_wdt_probe(struct platform_device *pdev)
{
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -230,6 +230,7 @@ ltq_wdt_remove(struct platform_device *p
static struct platform_driver ltq_wdt_driver = {
+ .probe = ltq_wdt_probe,
.remove = __devexit_p(ltq_wdt_remove),
.driver = {
.name = "ltq_wdt",
@@ -237,21 +238,7 @@ static struct platform_driver ltq_wdt_dr
},
};
-static int __init
-init_ltq_wdt(void)
-{
- return platform_driver_probe(&ltq_wdt_driver, ltq_wdt_probe);
-}
-
-static void __exit
-exit_ltq_wdt(void)
-{
- return platform_driver_unregister(&ltq_wdt_driver);
-}
-
-module_init(init_ltq_wdt);
-module_exit(exit_ltq_wdt);
-
+module_platform_driver(ltq_wdt_driver);
module_param(nowayout, int, 0);
MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started");

View File

@ -1,21 +0,0 @@
From 604835c84e9854d347a43b736b047d9789f19a00 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Fri, 23 Mar 2012 16:14:33 +0100
Subject: [PATCH 48/73] dwc_otg: remove bogus halt_channel
https://lists.openwrt.org/pipermail/openwrt-devel/2012-March/014524.html
---
drivers/usb/dwc_otg/dwc_otg_hcd_intr.c | 2 --
1 files changed, 0 insertions(+), 2 deletions(-)
--- a/drivers/usb/dwc_otg/dwc_otg_hcd_intr.c
+++ b/drivers/usb/dwc_otg/dwc_otg_hcd_intr.c
@@ -1278,8 +1278,6 @@ static int32_t handle_hc_ack_intr(dwc_ot
* automatically executes the PING, then the transfer.
*/
halt_channel(_hcd, _hc, _qtd, DWC_OTG_HC_XFER_ACK, must_free);
- } else {
- halt_channel(_hcd, _hc, _qtd, _hc->halt_status, must_free);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,189 +0,0 @@
From ce8fccecad845349cc5f6783b3812a17a074d39c Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Wed, 14 Mar 2012 15:37:19 +0100
Subject: [PATCH 50/73] MIPS: adds gptu driver
---
arch/mips/lantiq/xway/gptu.c | 176 ++++++++++++++++++++++++++++++++++++++++++
1 files changed, 176 insertions(+), 0 deletions(-)
create mode 100644 arch/mips/lantiq/xway/gptu.c
--- /dev/null
+++ b/arch/mips/lantiq/xway/gptu.c
@@ -0,0 +1,176 @@
+/*
+ * 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.
+ *
+ * Copyright (C) 2012 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/pm.h>
+#include <linux/export.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <asm/reboot.h>
+
+#include <lantiq_soc.h>
+#include "../clk.h"
+
+#include "../devices.h"
+
+#define ltq_gptu_w32(x, y) ltq_w32((x), ltq_gptu_membase + (y))
+#define ltq_gptu_r32(x) ltq_r32(ltq_gptu_membase + (x))
+
+
+/* the magic ID byte of the core */
+#define GPTU_MAGIC 0x59
+/* clock control register */
+#define GPTU_CLC 0x00
+/* id register */
+#define GPTU_ID 0x08
+/* interrupt node enable */
+#define GPTU_IRNEN 0xf4
+/* interrupt control register */
+#define GPTU_IRCR 0xf8
+/* interrupt capture register */
+#define GPTU_IRNCR 0xfc
+/* there are 3 identical blocks of 2 timers. calculate register offsets */
+#define GPTU_SHIFT(x) (x % 2 ? 4 : 0)
+#define GPTU_BASE(x) (((x >> 1) * 0x20) + 0x10)
+/* timer control register */
+#define GPTU_CON(x) (GPTU_BASE(x) + GPTU_SHIFT(x) + 0x00)
+/* timer auto reload register */
+#define GPTU_RUN(x) (GPTU_BASE(x) + GPTU_SHIFT(x) + 0x08)
+/* timer manual reload register */
+#define GPTU_RLD(x) (GPTU_BASE(x) + GPTU_SHIFT(x) + 0x10)
+/* timer count register */
+#define GPTU_CNT(x) (GPTU_BASE(x) + GPTU_SHIFT(x) + 0x18)
+
+/* GPTU_CON(x) */
+#define CON_CNT BIT(2)
+#define CON_EDGE_FALL BIT(7)
+#define CON_SYNC BIT(8)
+#define CON_CLK_INT BIT(10)
+
+/* GPTU_RUN(x) */
+#define RUN_SEN BIT(0)
+#define RUN_RL BIT(2)
+
+/* set clock to runmode */
+#define CLC_RMC BIT(8)
+/* bring core out of suspend */
+#define CLC_SUSPEND BIT(4)
+/* the disable bit */
+#define CLC_DISABLE BIT(0)
+
+#define TIMER_INTERRUPT (INT_NUM_IM3_IRL0 + 22)
+
+enum gptu_timer {
+ TIMER1A = 0,
+ TIMER1B,
+ TIMER2A,
+ TIMER2B,
+ TIMER3A,
+ TIMER3B
+};
+
+static struct resource ltq_gptu_resource =
+ MEM_RES("GPTU", LTQ_GPTU_BASE_ADDR, LTQ_GPTU_SIZE);
+
+static void __iomem *ltq_gptu_membase;
+
+static irqreturn_t timer_irq_handler(int irq, void *priv)
+{
+ int timer = irq - TIMER_INTERRUPT;
+ ltq_gptu_w32(1 << timer, GPTU_IRNCR);
+ return IRQ_HANDLED;
+}
+
+static void gptu_hwinit(void)
+{
+ struct clk *clk = clk_get_sys("ltq_gptu", NULL);
+ clk_enable(clk);
+ ltq_gptu_w32(0x00, GPTU_IRNEN);
+ ltq_gptu_w32(0xff, GPTU_IRNCR);
+ ltq_gptu_w32(CLC_RMC | CLC_SUSPEND, GPTU_CLC);
+}
+
+static void gptu_hwexit(void)
+{
+ ltq_gptu_w32(0x00, GPTU_IRNEN);
+ ltq_gptu_w32(0xff, GPTU_IRNCR);
+ ltq_gptu_w32(CLC_DISABLE, GPTU_CLC);
+}
+
+static int ltq_gptu_enable(struct clk *clk)
+{
+ int ret = request_irq(TIMER_INTERRUPT + clk->bits, timer_irq_handler,
+ IRQF_TIMER, "timer", NULL);
+ if (ret) {
+ pr_err("gptu: failed to request irq\n");
+ return ret;
+ }
+
+ ltq_gptu_w32(CON_CNT | CON_EDGE_FALL | CON_SYNC | CON_CLK_INT,
+ GPTU_CON(clk->bits));
+ ltq_gptu_w32(1, GPTU_RLD(clk->bits));
+ ltq_gptu_w32(ltq_gptu_r32(GPTU_IRNEN) | clk->bits, GPTU_IRNEN);
+ ltq_gptu_w32(RUN_SEN | RUN_RL, GPTU_RUN(clk->bits));
+ return 0;
+}
+
+static void ltq_gptu_disable(struct clk *clk)
+{
+ ltq_gptu_w32(0, GPTU_RUN(clk->bits));
+ ltq_gptu_w32(0, GPTU_CON(clk->bits));
+ ltq_gptu_w32(0, GPTU_RLD(clk->bits));
+ ltq_gptu_w32(ltq_gptu_r32(GPTU_IRNEN) & ~clk->bits, GPTU_IRNEN);
+ free_irq(TIMER_INTERRUPT + clk->bits, NULL);
+}
+
+static inline void clkdev_add_gptu(const char *con, unsigned int timer)
+{
+ struct clk *clk = kzalloc(sizeof(struct clk), GFP_KERNEL);
+
+ clk->cl.dev_id = "ltq_gptu";
+ clk->cl.con_id = con;
+ clk->cl.clk = clk;
+ clk->enable = ltq_gptu_enable;
+ clk->disable = ltq_gptu_disable;
+ clk->bits = timer;
+ clkdev_add(&clk->cl);
+}
+
+static int __init gptu_setup(void)
+{
+ /* remap gptu register range */
+ ltq_gptu_membase = ltq_remap_resource(&ltq_gptu_resource);
+ if (!ltq_gptu_membase)
+ panic("Failed to remap gptu memory");
+
+ /* power up the core */
+ gptu_hwinit();
+
+ /* the gptu has a ID register */
+ if (((ltq_gptu_r32(GPTU_ID) >> 8) & 0xff) != GPTU_MAGIC) {
+ pr_err("gptu: failed to find magic\n");
+ gptu_hwexit();
+ return -ENAVAIL;
+ }
+
+ /* register the clocks */
+ clkdev_add_gptu("timer1a", TIMER1A);
+ clkdev_add_gptu("timer1b", TIMER1B);
+ clkdev_add_gptu("timer2a", TIMER2A);
+ clkdev_add_gptu("timer2b", TIMER2B);
+ clkdev_add_gptu("timer3a", TIMER3A);
+ clkdev_add_gptu("timer3b", TIMER3B);
+
+ pr_info("gptu: 6 timers loaded\n");
+
+ return 0;
+}
+
+arch_initcall(gptu_setup);

View File

@ -1,70 +0,0 @@
From 6a3a89057dbb65c67be80641f13f34c599ee3863 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Thu, 8 Mar 2012 12:00:17 +0100
Subject: [PATCH 51/73] MIPS: lantiq: pci: rename variable inside
* rename a global var inside the pci code
---
arch/mips/pci/ops-lantiq.c | 6 +++---
arch/mips/pci/pci-lantiq.c | 6 +++---
arch/mips/pci/pci-lantiq.h | 2 +-
3 files changed, 7 insertions(+), 7 deletions(-)
--- a/arch/mips/pci/ops-lantiq.c
+++ b/arch/mips/pci/ops-lantiq.c
@@ -41,7 +41,7 @@ static int ltq_pci_config_access(unsigne
spin_lock_irqsave(&ebu_lock, flags);
- cfg_base = (unsigned long) ltq_pci_mapped_cfg;
+ cfg_base = (unsigned long) ltq_pci_cfgbase;
cfg_base |= (bus->number << LTQ_PCI_CFG_BUSNUM_SHF) | (devfn <<
LTQ_PCI_CFG_FUNNUM_SHF) | (where & ~0x3);
@@ -55,11 +55,11 @@ static int ltq_pci_config_access(unsigne
wmb();
/* clean possible Master abort */
- cfg_base = (unsigned long) ltq_pci_mapped_cfg;
+ cfg_base = (unsigned long) ltq_pci_cfgbase;
cfg_base |= (0x0 << LTQ_PCI_CFG_FUNNUM_SHF) + 4;
temp = ltq_r32(((u32 *)(cfg_base)));
temp = swab32(temp);
- cfg_base = (unsigned long) ltq_pci_mapped_cfg;
+ cfg_base = (unsigned long) ltq_pci_cfgbase;
cfg_base |= (0x68 << LTQ_PCI_CFG_FUNNUM_SHF) + 4;
ltq_w32(temp, ((u32 *)cfg_base));
--- a/arch/mips/pci/pci-lantiq.c
+++ b/arch/mips/pci/pci-lantiq.c
@@ -65,8 +65,8 @@
#define ltq_pci_w32(x, y) ltq_w32((x), ltq_pci_membase + (y))
#define ltq_pci_r32(x) ltq_r32(ltq_pci_membase + (x))
-#define ltq_pci_cfg_w32(x, y) ltq_w32((x), ltq_pci_mapped_cfg + (y))
-#define ltq_pci_cfg_r32(x) ltq_r32(ltq_pci_mapped_cfg + (x))
+#define ltq_pci_cfg_w32(x, y) ltq_w32((x), ltq_pci_cfgbase + (y))
+#define ltq_pci_cfg_r32(x) ltq_r32(ltq_pci_cfgbase + (x))
struct ltq_pci_gpio_map {
int pin;
@@ -273,7 +273,7 @@ static int __devinit ltq_pci_probe(struc
pci_probe_only = 0;
ltq_pci_irq_map = ltq_pci_data->irq;
ltq_pci_membase = ioremap_nocache(PCI_CR_BASE_ADDR, PCI_CR_SIZE);
- ltq_pci_mapped_cfg =
+ ltq_pci_cfgbase =
ioremap_nocache(LTQ_PCI_CFG_BASE, LTQ_PCI_CFG_BASE);
ltq_pci_controller.io_map_base =
(unsigned long)ioremap(LTQ_PCI_IO_BASE, LTQ_PCI_IO_SIZE - 1);
--- a/arch/mips/pci/pci-lantiq.h
+++ b/arch/mips/pci/pci-lantiq.h
@@ -9,7 +9,7 @@
#ifndef _LTQ_PCI_H__
#define _LTQ_PCI_H__
-extern __iomem void *ltq_pci_mapped_cfg;
+extern __iomem void *ltq_pci_cfgbase;
extern int ltq_pci_read_config_dword(struct pci_bus *bus,
unsigned int devfn, int where, int size, u32 *val);
extern int ltq_pci_write_config_dword(struct pci_bus *bus,

View File

@ -1,38 +0,0 @@
From 3ea2b94a6721ebdde4508ef7d35521f1b8f06351 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Thu, 8 Mar 2012 13:13:31 +0100
Subject: [PATCH 52/73] MIPS: lantiq: pci: give xway pci support its own
kbuild symbol
---
arch/mips/lantiq/Kconfig | 5 +++++
arch/mips/pci/Makefile | 2 +-
2 files changed, 6 insertions(+), 1 deletions(-)
--- a/arch/mips/lantiq/Kconfig
+++ b/arch/mips/lantiq/Kconfig
@@ -19,8 +19,13 @@ config SOC_XWAY
config SOC_FALCON
bool "FALCON"
+
endchoice
+config PCI_LANTIQ
+ bool "PCI Support"
+ depends on SOC_XWAY && PCI
+
source "arch/mips/lantiq/xway/Kconfig"
source "arch/mips/lantiq/falcon/Kconfig"
--- a/arch/mips/pci/Makefile
+++ b/arch/mips/pci/Makefile
@@ -40,7 +40,7 @@ obj-$(CONFIG_SIBYTE_SB1250) += fixup-sb1
obj-$(CONFIG_SIBYTE_BCM112X) += fixup-sb1250.o pci-sb1250.o
obj-$(CONFIG_SIBYTE_BCM1x80) += pci-bcm1480.o pci-bcm1480ht.o
obj-$(CONFIG_SNI_RM) += fixup-sni.o ops-sni.o
-obj-$(CONFIG_SOC_XWAY) += pci-lantiq.o ops-lantiq.o
+obj-$(CONFIG_PCI_LANTIQ) += pci-lantiq.o ops-lantiq.o
obj-$(CONFIG_TANBAC_TB0219) += fixup-tb0219.o
obj-$(CONFIG_TANBAC_TB0226) += fixup-tb0226.o
obj-$(CONFIG_TANBAC_TB0287) += fixup-tb0287.o

View File

@ -1,121 +0,0 @@
From e6b9f3ea5f2f3f8a66d6650c16f3537288806c0b Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Thu, 8 Mar 2012 15:53:10 +0100
Subject: [PATCH 53/73] MIPS: lantiq: pci: move pcibios code into
fixup-lantiq.c
---
arch/mips/pci/Makefile | 1 +
arch/mips/pci/fixup-lantiq.c | 42 ++++++++++++++++++++++++++++++++++++++++++
arch/mips/pci/pci-lantiq.c | 24 ++----------------------
3 files changed, 45 insertions(+), 22 deletions(-)
create mode 100644 arch/mips/pci/fixup-lantiq.c
--- a/arch/mips/pci/Makefile
+++ b/arch/mips/pci/Makefile
@@ -40,6 +40,7 @@ obj-$(CONFIG_SIBYTE_SB1250) += fixup-sb1
obj-$(CONFIG_SIBYTE_BCM112X) += fixup-sb1250.o pci-sb1250.o
obj-$(CONFIG_SIBYTE_BCM1x80) += pci-bcm1480.o pci-bcm1480ht.o
obj-$(CONFIG_SNI_RM) += fixup-sni.o ops-sni.o
+obj-$(CONFIG_LANTIQ) += fixup-lantiq.o
obj-$(CONFIG_PCI_LANTIQ) += pci-lantiq.o ops-lantiq.o
obj-$(CONFIG_TANBAC_TB0219) += fixup-tb0219.o
obj-$(CONFIG_TANBAC_TB0226) += fixup-tb0226.o
--- /dev/null
+++ b/arch/mips/pci/fixup-lantiq.c
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ *
+ * Copyright (C) 2012 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/of_irq.h>
+#include <linux/of_pci.h>
+
+int (*ltqpci_map_irq)(const struct pci_dev *dev, u8 slot, u8 pin) = NULL;
+int (*ltqpci_plat_arch_init)(struct pci_dev *dev) = NULL;
+int (*ltqpci_plat_dev_init)(struct pci_dev *dev) = NULL;
+int *ltq_pci_irq_map;
+
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+ if (ltqpci_plat_arch_init)
+ return ltqpci_plat_arch_init(dev);
+
+ if (ltqpci_plat_dev_init)
+ return ltqpci_plat_dev_init(dev);
+
+ return 0;
+}
+
+int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+ if (ltqpci_map_irq)
+ return ltqpci_map_irq(dev, slot, pin);
+ if (ltq_pci_irq_map[slot]) {
+ dev_info(&dev->dev, "SLOT:%d PIN:%d IRQ:%d\n", slot, pin, ltq_pci_irq_map[slot]);
+ return ltq_pci_irq_map[slot];
+ }
+ printk(KERN_ERR "lq_pci: trying to map irq for unknown slot %d\n",
+ slot);
+
+ return 0;
+}
+
+
--- a/arch/mips/pci/pci-lantiq.c
+++ b/arch/mips/pci/pci-lantiq.c
@@ -93,16 +93,14 @@ static struct ltq_pci_gpio_map ltq_pci_g
{ 37, 2, 0, "pci-req4" },
};
-__iomem void *ltq_pci_mapped_cfg;
+__iomem void *ltq_pci_cfgbase;
static __iomem void *ltq_pci_membase;
-int (*ltqpci_plat_dev_init)(struct pci_dev *dev) = NULL;
-
/* Since the PCI REQ pins can be reused for other functionality, make it
possible to exclude those from interpretation by the PCI controller */
static int ltq_pci_req_mask = 0xf;
-static int *ltq_pci_irq_map;
+extern int *ltq_pci_irq_map;
struct pci_ops ltq_pci_ops = {
.read = ltq_pci_read_config_dword,
@@ -131,14 +129,6 @@ static struct pci_controller ltq_pci_con
.io_offset = 0x00000000UL,
};
-int pcibios_plat_dev_init(struct pci_dev *dev)
-{
- if (ltqpci_plat_dev_init)
- return ltqpci_plat_dev_init(dev);
-
- return 0;
-}
-
static u32 ltq_calc_bar11mask(void)
{
u32 mem, bar11mask;
@@ -256,16 +246,6 @@ static int __devinit ltq_pci_startup(str
return 0;
}
-int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
-{
- if (ltq_pci_irq_map[slot])
- return ltq_pci_irq_map[slot];
- printk(KERN_ERR "lq_pci: trying to map irq for unknown slot %d\n",
- slot);
-
- return 0;
-}
-
static int __devinit ltq_pci_probe(struct platform_device *pdev)
{
struct ltq_pci_data *ltq_pci_data =

View File

@ -1,223 +0,0 @@
From bc45b5c61ffb156eb01515bf56efc5ae8d2bc3b2 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Sat, 13 Aug 2011 13:59:50 +0200
Subject: [PATCH 55/73] MIPS: lantiq: make GPIO3 work on AR9
There are 3 16bit and 1 8bit gpio ports on AR9. The gpio driver needs a hack
at 2 places to make the different register layout of the GPIO3 work properly
with the driver. Before only GPIO0-2 were supported. As the GPIO number scheme
clashes with the new size, we also move the other gpio chips to new offsets.
Signed-off-by: John Crispin <blogic@openwrt.org>
Signed-off-by: Thomas Langer <thomas.langer@lantiq.com>
---
.../mips/include/asm/mach-lantiq/xway/lantiq_soc.h | 2 +
arch/mips/lantiq/xway/devices.c | 3 +
arch/mips/lantiq/xway/gpio.c | 84 ++++++++++++++++----
arch/mips/lantiq/xway/gpio_ebu.c | 3 +-
arch/mips/lantiq/xway/gpio_stp.c | 3 +-
5 files changed, 75 insertions(+), 20 deletions(-)
--- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
+++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
@@ -126,7 +126,9 @@
#define LTQ_GPIO0_BASE_ADDR 0x1E100B10
#define LTQ_GPIO1_BASE_ADDR 0x1E100B40
#define LTQ_GPIO2_BASE_ADDR 0x1E100B70
+#define LTQ_GPIO3_BASE_ADDR 0x1E100BA0
#define LTQ_GPIO_SIZE 0x30
+#define LTQ_GPIO3_SIZE 0x10
/* SSC */
#define LTQ_SSC_BASE_ADDR 0x1e100800
--- a/arch/mips/lantiq/xway/devices.c
+++ b/arch/mips/lantiq/xway/devices.c
@@ -34,6 +34,7 @@ static struct resource ltq_gpio_resource
MEM_RES("gpio0", LTQ_GPIO0_BASE_ADDR, LTQ_GPIO_SIZE),
MEM_RES("gpio1", LTQ_GPIO1_BASE_ADDR, LTQ_GPIO_SIZE),
MEM_RES("gpio2", LTQ_GPIO2_BASE_ADDR, LTQ_GPIO_SIZE),
+ MEM_RES("gpio3", LTQ_GPIO3_BASE_ADDR, LTQ_GPIO3_SIZE),
};
void __init ltq_register_gpio(void)
@@ -47,6 +48,8 @@ void __init ltq_register_gpio(void)
if (ltq_is_ar9() || ltq_is_vr9()) {
platform_device_register_simple("ltq_gpio", 2,
&ltq_gpio_resource[2], 1);
+ platform_device_register_simple("ltq_gpio", 3,
+ &ltq_gpio_resource[3], 1);
}
}
--- a/arch/mips/lantiq/xway/gpio.c
+++ b/arch/mips/lantiq/xway/gpio.c
@@ -23,9 +23,17 @@
#define LTQ_GPIO_OD 0x14
#define LTQ_GPIO_PUDSEL 0x1C
#define LTQ_GPIO_PUDEN 0x20
+#define LTQ_GPIO3_OD 0x24
+#define LTQ_GPIO3_ALTSEL1 0x24
+#define LTQ_GPIO3_PUDSEL 0x28
+#define LTQ_GPIO3_PUDEN 0x2C
+/* PORT3 only has 8 pins and its register layout
+ is slightly different */
#define PINS_PER_PORT 16
-#define MAX_PORTS 3
+#define PINS_PORT3 8
+#define MAX_PORTS 4
+#define MAX_PIN 56
#define ltq_gpio_getbit(m, r, p) (!!(ltq_r32(m + r) & (1 << p)))
#define ltq_gpio_setbit(m, r, p) ltq_w32_mask(0, (1 << p), m + r)
@@ -55,7 +63,7 @@ int ltq_gpio_request(struct device *dev,
{
int id = 0;
- if (pin >= (MAX_PORTS * PINS_PER_PORT))
+ if (pin >= MAX_PIN)
return -EINVAL;
if (devm_gpio_request(dev, pin, name)) {
pr_err("failed to setup lantiq gpio: %s\n", name);
@@ -75,12 +83,21 @@ int ltq_gpio_request(struct device *dev,
else
ltq_gpio_clearbit(ltq_gpio_port[id].membase,
LTQ_GPIO_ALTSEL0, pin);
- if (mux & 0x1)
- ltq_gpio_setbit(ltq_gpio_port[id].membase,
- LTQ_GPIO_ALTSEL1, pin);
- else
- ltq_gpio_clearbit(ltq_gpio_port[id].membase,
- LTQ_GPIO_ALTSEL1, pin);
+ if (id == 3) {
+ if (mux & 0x1)
+ ltq_gpio_setbit(ltq_gpio_port[1].membase,
+ LTQ_GPIO3_ALTSEL1, pin);
+ else
+ ltq_gpio_clearbit(ltq_gpio_port[1].membase,
+ LTQ_GPIO3_ALTSEL1, pin);
+ } else {
+ if (mux & 0x1)
+ ltq_gpio_setbit(ltq_gpio_port[id].membase,
+ LTQ_GPIO_ALTSEL1, pin);
+ else
+ ltq_gpio_clearbit(ltq_gpio_port[id].membase,
+ LTQ_GPIO_ALTSEL1, pin);
+ }
return 0;
}
EXPORT_SYMBOL(ltq_gpio_request);
@@ -106,10 +123,19 @@ static int ltq_gpio_direction_input(stru
{
struct ltq_gpio *ltq_gpio = container_of(chip, struct ltq_gpio, chip);
- ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_OD, offset);
+ if (chip->ngpio == PINS_PORT3) {
+ ltq_gpio_clearbit(ltq_gpio_port[0].membase,
+ LTQ_GPIO3_OD, offset);
+ ltq_gpio_setbit(ltq_gpio_port[0].membase,
+ LTQ_GPIO3_PUDSEL, offset);
+ ltq_gpio_setbit(ltq_gpio_port[0].membase,
+ LTQ_GPIO3_PUDEN, offset);
+ } else {
+ ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_OD, offset);
+ ltq_gpio_setbit(ltq_gpio->membase, LTQ_GPIO_PUDSEL, offset);
+ ltq_gpio_setbit(ltq_gpio->membase, LTQ_GPIO_PUDEN, offset);
+ }
ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_DIR, offset);
- ltq_gpio_setbit(ltq_gpio->membase, LTQ_GPIO_PUDSEL, offset);
- ltq_gpio_setbit(ltq_gpio->membase, LTQ_GPIO_PUDEN, offset);
return 0;
}
@@ -119,10 +145,19 @@ static int ltq_gpio_direction_output(str
{
struct ltq_gpio *ltq_gpio = container_of(chip, struct ltq_gpio, chip);
- ltq_gpio_setbit(ltq_gpio->membase, LTQ_GPIO_OD, offset);
+ if (chip->ngpio == PINS_PORT3) {
+ ltq_gpio_setbit(ltq_gpio_port[0].membase,
+ LTQ_GPIO3_OD, offset);
+ ltq_gpio_clearbit(ltq_gpio_port[0].membase,
+ LTQ_GPIO3_PUDSEL, offset);
+ ltq_gpio_clearbit(ltq_gpio_port[0].membase,
+ LTQ_GPIO3_PUDEN, offset);
+ } else {
+ ltq_gpio_setbit(ltq_gpio->membase, LTQ_GPIO_OD, offset);
+ ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_PUDSEL, offset);
+ ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_PUDEN, offset);
+ }
ltq_gpio_setbit(ltq_gpio->membase, LTQ_GPIO_DIR, offset);
- ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_PUDSEL, offset);
- ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_PUDEN, offset);
ltq_gpio_set(chip, offset, value);
return 0;
@@ -133,7 +168,11 @@ static int ltq_gpio_req(struct gpio_chip
struct ltq_gpio *ltq_gpio = container_of(chip, struct ltq_gpio, chip);
ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_ALTSEL0, offset);
- ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_ALTSEL1, offset);
+ if (chip->ngpio == PINS_PORT3)
+ ltq_gpio_clearbit(ltq_gpio_port[1].membase,
+ LTQ_GPIO3_ALTSEL1, offset);
+ else
+ ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_ALTSEL1, offset);
return 0;
}
@@ -146,6 +185,16 @@ static int ltq_gpio_probe(struct platfor
pdev->id);
return -EINVAL;
}
+
+ /* dirty hack - The registers of port3 are not mapped linearly.
+ Port 3 may only load if Port 1/2 are mapped */
+ if ((pdev->id == 3) && (!ltq_gpio_port[1].membase
+ || !ltq_gpio_port[2].membase)) {
+ dev_err(&pdev->dev,
+ "ports 1/2 need to be loaded before port 3 works\n");
+ return -ENOMEM;
+ }
+
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
dev_err(&pdev->dev, "failed to get memory for gpio port %d\n",
@@ -175,7 +224,10 @@ static int ltq_gpio_probe(struct platfor
ltq_gpio_port[pdev->id].chip.set = ltq_gpio_set;
ltq_gpio_port[pdev->id].chip.request = ltq_gpio_req;
ltq_gpio_port[pdev->id].chip.base = PINS_PER_PORT * pdev->id;
- ltq_gpio_port[pdev->id].chip.ngpio = PINS_PER_PORT;
+ if (pdev->id == 3)
+ ltq_gpio_port[pdev->id].chip.ngpio = PINS_PORT3;
+ else
+ ltq_gpio_port[pdev->id].chip.ngpio = PINS_PER_PORT;
platform_set_drvdata(pdev, &ltq_gpio_port[pdev->id]);
return gpiochip_add(&ltq_gpio_port[pdev->id].chip);
}
--- a/arch/mips/lantiq/xway/gpio_ebu.c
+++ b/arch/mips/lantiq/xway/gpio_ebu.c
@@ -61,9 +61,8 @@ static struct gpio_chip ltq_ebu_chip = {
.label = "ltq_ebu",
.direction_output = ltq_ebu_direction_output,
.set = ltq_ebu_set,
- .base = 72,
+ .base = 100,
.ngpio = 16,
- .can_sleep = 1,
.owner = THIS_MODULE,
};
--- a/arch/mips/lantiq/xway/gpio_stp.c
+++ b/arch/mips/lantiq/xway/gpio_stp.c
@@ -74,9 +74,8 @@ static struct gpio_chip ltq_stp_chip = {
.label = "ltq_stp",
.direction_output = ltq_stp_direction_output,
.set = ltq_stp_set,
- .base = 48,
+ .base = 200,
.ngpio = 24,
- .can_sleep = 1,
.owner = THIS_MODULE,
};

View File

@ -1,171 +0,0 @@
From 7ee92edb5569c1cdc676a2635a40b53e8d9d647d Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Thu, 29 Sep 2011 21:29:14 +0200
Subject: [PATCH 57/73] MIPS: lantiq: falcon VPE softdog
---
arch/mips/include/asm/mach-lantiq/falcon/vpe.h | 44 ++++++++++
arch/mips/lantiq/falcon/softdog_vpe.c | 109 ++++++++++++++++++++++++
2 files changed, 153 insertions(+), 0 deletions(-)
create mode 100644 arch/mips/include/asm/mach-lantiq/falcon/vpe.h
create mode 100644 arch/mips/lantiq/falcon/softdog_vpe.c
--- /dev/null
+++ b/arch/mips/include/asm/mach-lantiq/falcon/vpe.h
@@ -0,0 +1,44 @@
+/*
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) 2005 infineon
+ * Copyright (C) 2007 John Crispin <blogic@openwrt.org>
+ *
+ */
+#ifndef _IFXMIPS_VPE_H__
+#define _IFXMIPS_VPE_H__
+
+/* For the explanation of the APIs please refer the section "MT APRP Kernel
+ * Programming" in AR9 SW Architecture Specification
+ */
+int32_t vpe1_sw_start(void* sw_start_addr, uint32_t tcmask, uint32_t flags);
+int32_t vpe1_sw_stop(uint32_t flags);
+uint32_t vpe1_get_load_addr (uint32_t flags);
+uint32_t vpe1_get_max_mem (uint32_t flags);
+
+int32_t vpe1_set_boot_param(char *field, char *value, char flags);
+int32_t vpe1_get_boot_param(char *field, char **value, char flags);
+
+/* Watchdog APIs */
+extern unsigned long vpe1_wdog_ctr;
+extern unsigned long vpe1_wdog_timeout;
+
+unsigned long vpe1_sw_wdog_start(unsigned long);
+unsigned long vpe1_sw_wdog_stop(unsigned long);
+
+typedef int (*VPE_SW_WDOG_RESET)(unsigned long wdog_cleared_ok_count);
+int32_t vpe1_sw_wdog_register_reset_handler(VPE_SW_WDOG_RESET reset_fn);
+
+#endif
--- /dev/null
+++ b/arch/mips/lantiq/falcon/softdog_vpe.c
@@ -0,0 +1,109 @@
+/*
+** =============================================================================
+** FILE NAME : softdog_vpe.c
+** MODULES : LXDB
+** DATE : 24-03-2008
+** AUTHOR : LXDB Team
+** DESCRIPTION : This header file contains the code for the watchdog
+** implentation on vpe1 side.
+** REFERENCES :
+** COPYRIGHT : Copyright (c) 2008
+** Am Campeon 1-12, 85579 Neubiberg, Germany
+** Any use of this software is subject to the conclusion of a respective
+** License agreement. Without such a License agreement no rights to the
+** software are granted
+**
+** HISTORY :
+** $Date $Author $Comment
+** 24-03-2008 LXDB Initial version
+** ============================================================================
+*/
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/types.h>
+#include <linux/timer.h>
+#include <linux/reboot.h>
+#include <linux/init.h>
+#include <linux/jiffies.h>
+
+#include <falcon/vpe.h>
+
+static unsigned long last_wdog_value;
+static unsigned long vpe1_wdog_cleared;
+
+static unsigned long vpe1_wdog_dead;
+static void watchdog_vpe0_fire(unsigned long); /* Called when vpe0 timer expires */
+static void keep_alive_vpe0(unsigned long);
+VPE_SW_WDOG_RESET reset_local_fn;
+
+
+static struct timer_list watchdog_vpe0_ticktock =
+ TIMER_INITIALIZER(watchdog_vpe0_fire, 0, 0);
+
+static void watchdog_vpe0_fire (unsigned long flags)
+{
+ volatile unsigned long *wdog_ctr_value;
+ wdog_ctr_value = (void*)vpe1_wdog_ctr;
+ if (*wdog_ctr_value == last_wdog_value) { /* VPE1 watchdog expiry handling */
+ vpe1_sw_wdog_stop(flags);
+ vpe1_wdog_dead++;
+ printk(KERN_DEBUG "VPE1 watchdog reset handler called\n");
+ /* Call the reset handler function */
+ reset_local_fn(flags);
+ } else { /* Everything is OK on vpe1 side. Continue. */
+ last_wdog_value = *wdog_ctr_value;
+ vpe1_wdog_cleared++;
+ keep_alive_vpe0(flags);
+ }
+}
+
+int32_t vpe1_sw_wdog_register_reset_handler (VPE_SW_WDOG_RESET reset_fn)
+{
+ reset_local_fn = (VPE_SW_WDOG_RESET)reset_fn;
+ return 0;
+}
+
+static void keep_alive_vpe0(unsigned long flags)
+{
+ mod_timer(&watchdog_vpe0_ticktock, jiffies+ vpe1_wdog_timeout );
+}
+
+unsigned long vpe1_sw_wdog_start(unsigned long flags)
+{
+ volatile unsigned long *wdog_ctr_value;
+ wdog_ctr_value = (void*)vpe1_wdog_ctr;
+ *wdog_ctr_value = 0;
+ last_wdog_value = 0;
+ keep_alive_vpe0(flags);
+ return 0;
+}
+
+unsigned long vpe1_sw_wdog_stop(unsigned long flags)
+{
+ del_timer(&watchdog_vpe0_ticktock);
+ return 0;
+}
+
+static int __init watchdog_vpe1_init(void)
+{
+ /* Nothing to be done here */
+ return 0;
+}
+
+static void __exit watchdog_vpe1_exit(void)
+{
+ unsigned long flags=0;
+ vpe1_sw_wdog_stop(flags);
+}
+
+module_init(watchdog_vpe1_init);
+module_exit(watchdog_vpe1_exit);
+
+EXPORT_SYMBOL(vpe1_sw_wdog_register_reset_handler);
+EXPORT_SYMBOL(vpe1_sw_wdog_start);
+EXPORT_SYMBOL(vpe1_sw_wdog_stop);
+
+MODULE_AUTHOR("LXDB");
+MODULE_DESCRIPTION("Software Watchdog For VPE1");
+MODULE_LICENSE("GPL");

View File

@ -1,363 +0,0 @@
From 8bf74990542ad73bc633332f716a5edc76f858a2 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Thu, 29 Sep 2011 20:29:54 +0200
Subject: [PATCH 58/73] MIPS: lantiq: udp in-kernel redirect
---
include/linux/udp_redirect.h | 57 +++++++++++++
net/Kconfig | 6 ++
net/ipv4/Makefile | 3 +
net/ipv4/udp.c | 28 ++++++-
net/ipv4/udp_redirect_symb.c | 186 ++++++++++++++++++++++++++++++++++++++++++
5 files changed, 276 insertions(+), 4 deletions(-)
create mode 100644 include/linux/udp_redirect.h
create mode 100644 net/ipv4/udp_redirect_symb.c
--- /dev/null
+++ b/include/linux/udp_redirect.h
@@ -0,0 +1,57 @@
+#ifndef _UDP_REDIRECT_H
+#define _UDP_REDIRECT_H
+
+/******************************************************************************
+
+ Copyright (c) 2006
+ Infineon Technologies AG
+ Am Campeon 1-12; 81726 Munich, Germany
+
+ THE DELIVERY OF THIS SOFTWARE AS WELL AS THE HEREBY GRANTED NON-EXCLUSIVE,
+ WORLDWIDE LICENSE TO USE, COPY, MODIFY, DISTRIBUTE AND SUBLICENSE THIS
+ SOFTWARE IS FREE OF CHARGE.
+
+ THE LICENSED SOFTWARE IS PROVIDED "AS IS" AND INFINEON EXPRESSLY DISCLAIMS
+ ALL REPRESENTATIONS AND WARRANTIES, WHETHER EXPRESS OR IMPLIED, INCLUDING
+ WITHOUT LIMITATION, WARRANTIES OR REPRESENTATIONS OF WORKMANSHIP,
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, DURABILITY, THAT THE
+ OPERATING OF THE LICENSED SOFTWARE WILL BE ERROR FREE OR FREE OF ANY THIRD
+ PARTY CLAIMS, INCLUDING WITHOUT LIMITATION CLAIMS OF THIRD PARTY INTELLECTUAL
+ PROPERTY INFRINGEMENT.
+
+ EXCEPT FOR ANY LIABILITY DUE TO WILFUL ACTS OR GROSS NEGLIGENCE AND EXCEPT
+ FOR ANY PERSONAL INJURY INFINEON SHALL IN NO EVENT BE LIABLE FOR ANY CLAIM
+ OR DAMAGES OF ANY KIND, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
+
+******************************************************************************/
+
+/* ============================= */
+/* Includes */
+/* ============================= */
+#ifndef _LINUX_TYPES_H
+#include <linux/types.h>
+#endif
+
+
+/* ============================= */
+/* Definitions */
+/* ============================= */
+#define UDP_REDIRECT_MAGIC (void*)0x55445052L
+
+
+/* ============================= */
+/* Global variable declaration */
+/* ============================= */
+extern int (*udp_do_redirect_fn)(struct sock *sk, struct sk_buff *skb);
+extern int (*udpredirect_getfrag_fn)(void *p, char * to,
+ int offset, int fraglen, int odd,
+ struct sk_buff *skb);
+/* ============================= */
+/* Global function declaration */
+/* ============================= */
+
+extern int udpredirect_getfrag(void *p, char * to, int offset,
+ int fraglen, int odd, struct sk_buff *skb);
+#endif
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -72,6 +72,12 @@ config INET
Short answer: say Y.
+config IFX_UDP_REDIRECT
+ bool "IFX Kernel Packet Interface for UDP redirection"
+ help
+ You can say Y here if you want to use hooks from kernel for
+ UDP redirection.
+
if INET
source "net/ipv4/Kconfig"
source "net/ipv6/Kconfig"
--- a/net/ipv4/Makefile
+++ b/net/ipv4/Makefile
@@ -14,6 +14,9 @@ obj-y := route.o inetpeer.o protocol
inet_fragment.o ping.o
obj-$(CONFIG_SYSCTL) += sysctl_net_ipv4.o
+ifneq ($(CONFIG_IFX_UDP_REDIRECT),)
+obj-$(CONFIG_IFX_UDP_REDIRECT) += udp_redirect_symb.o
+endif
obj-$(CONFIG_PROC_FS) += proc.o
obj-$(CONFIG_IP_MULTIPLE_TABLES) += fib_rules.o
obj-$(CONFIG_IP_MROUTE) += ipmr.o
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -108,6 +108,10 @@
#include <trace/events/udp.h>
#include "udp_impl.h"
+#if defined(CONFIG_IFX_UDP_REDIRECT) || defined(CONFIG_IFX_UDP_REDIRECT_MODULE)
+#include <linux/udp_redirect.h>
+#endif
+
struct udp_table udp_table __read_mostly;
EXPORT_SYMBOL(udp_table);
@@ -803,7 +807,7 @@ int udp_sendmsg(struct kiocb *iocb, stru
u8 tos;
int err, is_udplite = IS_UDPLITE(sk);
int corkreq = up->corkflag || msg->msg_flags&MSG_MORE;
- int (*getfrag)(void *, char *, int, int, int, struct sk_buff *);
+ int (*getfrag)(void *, char *, int, int, int, struct sk_buff *) = NULL;
struct sk_buff *skb;
struct ip_options_data opt_copy;
@@ -820,7 +824,13 @@ int udp_sendmsg(struct kiocb *iocb, stru
ipc.opt = NULL;
ipc.tx_flags = 0;
- getfrag = is_udplite ? udplite_getfrag : ip_generic_getfrag;
+/* UDPREDIRECT */
+#if defined(CONFIG_IFX_UDP_REDIRECT) || defined(CONFIG_IFX_UDP_REDIRECT_MODULE)
+ if(udpredirect_getfrag_fn && sk->sk_user_data == UDP_REDIRECT_MAGIC)
+ getfrag = udpredirect_getfrag_fn;
+ else
+#endif /* IFX_UDP_REDIRECT */
+ getfrag = is_udplite ? udplite_getfrag : ip_generic_getfrag;
fl4 = &inet->cork.fl.u.ip4;
if (up->pending) {
@@ -1623,6 +1633,7 @@ int __udp4_lib_rcv(struct sk_buff *skb,
struct rtable *rt = skb_rtable(skb);
__be32 saddr, daddr;
struct net *net = dev_net(skb->dev);
+ int ret = 0;
/*
* Validate the packet.
@@ -1655,7 +1666,16 @@ int __udp4_lib_rcv(struct sk_buff *skb,
sk = __udp4_lib_lookup_skb(skb, uh->source, uh->dest, udptable);
if (sk != NULL) {
- int ret = udp_queue_rcv_skb(sk, skb);
+ /* UDPREDIRECT */
+#if defined(CONFIG_IFX_UDP_REDIRECT) || defined(CONFIG_IFX_UDP_REDIRECT_MODULE)
+ if(udp_do_redirect_fn && sk->sk_user_data == UDP_REDIRECT_MAGIC)
+ {
+ udp_do_redirect_fn(sk,skb);
+ kfree_skb(skb);
+ return(0);
+ }
+#endif
+ ret = udp_queue_rcv_skb(sk, skb);
sock_put(sk);
/* a return value > 0 means to resubmit the input, but
@@ -1952,7 +1972,7 @@ struct proto udp_prot = {
.clear_sk = sk_prot_clear_portaddr_nulls,
};
EXPORT_SYMBOL(udp_prot);
-
+EXPORT_SYMBOL(udp_rcv);
/* ------------------------------------------------------------------------ */
#ifdef CONFIG_PROC_FS
--- /dev/null
+++ b/net/ipv4/udp_redirect_symb.c
@@ -0,0 +1,186 @@
+/******************************************************************************
+
+ Copyright (c) 2006
+ Infineon Technologies AG
+ Am Campeon 1-12; 81726 Munich, Germany
+
+ THE DELIVERY OF THIS SOFTWARE AS WELL AS THE HEREBY GRANTED NON-EXCLUSIVE,
+ WORLDWIDE LICENSE TO USE, COPY, MODIFY, DISTRIBUTE AND SUBLICENSE THIS
+ SOFTWARE IS FREE OF CHARGE.
+
+ THE LICENSED SOFTWARE IS PROVIDED "AS IS" AND INFINEON EXPRESSLY DISCLAIMS
+ ALL REPRESENTATIONS AND WARRANTIES, WHETHER EXPRESS OR IMPLIED, INCLUDING
+ WITHOUT LIMITATION, WARRANTIES OR REPRESENTATIONS OF WORKMANSHIP,
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, DURABILITY, THAT THE
+ OPERATING OF THE LICENSED SOFTWARE WILL BE ERROR FREE OR FREE OF ANY THIRD
+ PARTY CLAIMS, INCLUDING WITHOUT LIMITATION CLAIMS OF THIRD PARTY INTELLECTUAL
+ PROPERTY INFRINGEMENT.
+
+ EXCEPT FOR ANY LIABILITY DUE TO WILFUL ACTS OR GROSS NEGLIGENCE AND EXCEPT
+ FOR ANY PERSONAL INJURY INFINEON SHALL IN NO EVENT BE LIABLE FOR ANY CLAIM
+ OR DAMAGES OF ANY KIND, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
+
+******************************************************************************/
+#if defined(CONFIG_IFX_UDP_REDIRECT) || defined(CONFIG_IFX_UDP_REDIRECT_MODULE)
+/* ============================= */
+/* Includes */
+/* ============================= */
+#include <net/checksum.h>
+#include <net/udp.h>
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/udp_redirect.h>
+
+/* ============================= */
+/* Global variable definition */
+/* ============================= */
+int (*udpredirect_getfrag_fn) (void *p, char * to, int offset,
+ int fraglen, int odd, struct sk_buff *skb) = NULL;
+int (*udp_do_redirect_fn)(struct sock *sk, struct sk_buff *skb) = NULL;
+
+/* ============================= */
+/* Local type definitions */
+/* ============================= */
+struct udpfakehdr
+{
+ struct udphdr uh;
+ u32 saddr;
+ u32 daddr;
+ struct iovec *iov;
+ u32 wcheck;
+};
+
+/* ============================= */
+/* Local function declaration */
+/* ============================= */
+static int udpredirect_csum_partial_copy_fromiovecend(unsigned char *kdata,
+ struct iovec *iov, int offset, unsigned int len, __wsum *csump);
+
+static int udpredirect_memcpy_fromiovecend(unsigned char *kdata, struct iovec *iov, int offset,
+ int len);
+
+/* ============================= */
+/* Global function definition */
+/* ============================= */
+
+/*
+ Copy of udp_getfrag() from udp.c
+ This function exists because no copy_from_user() is needed for udpredirect.
+*/
+
+int
+udpredirect_getfrag(void *from, char *to, int offset, int len, int odd, struct sk_buff *skb)
+{
+ struct iovec *iov = from;
+
+ if (skb->ip_summed == CHECKSUM_PARTIAL) {
+ if (udpredirect_memcpy_fromiovecend(to, iov, offset, len) < 0)
+ return -EFAULT;
+ } else {
+ __wsum csum = 0;
+ if (udpredirect_csum_partial_copy_fromiovecend(to, iov, offset, len, &csum) < 0)
+ return -EFAULT;
+ skb->csum = csum_block_add(skb->csum, csum, odd);
+ }
+ return 0;
+}
+
+static int udpredirect_memcpy_fromiovecend(unsigned char *kdata, struct iovec *iov, int offset,
+ int len)
+{
+ /* Skip over the finished iovecs */
+ while (offset >= iov->iov_len) {
+ offset -= iov->iov_len;
+ iov++;
+ }
+
+ while (len > 0) {
+ u8 __user *base = iov->iov_base + offset;
+ int copy = min_t(unsigned int, len, iov->iov_len - offset);
+
+ offset = 0;
+ memcpy(kdata, base, copy);
+ len -= copy;
+ kdata += copy;
+ iov++;
+ }
+
+ return 0;
+}
+
+/*
+ Copy of csum_partial_copy_fromiovecend() from iovec.c
+ This function exists because no copy_from_user() is needed for udpredirect.
+*/
+
+int udpredirect_csum_partial_copy_fromiovecend(unsigned char *kdata, struct iovec *iov,
+ int offset, unsigned int len, __wsum *csump)
+{
+ __wsum csum = *csump;
+ int partial_cnt = 0, err = 0;
+
+ /* Skip over the finished iovecs */
+ while (offset >= iov->iov_len) {
+ offset -= iov->iov_len;
+ iov++;
+ }
+
+ while (len > 0) {
+ u8 __user *base = iov->iov_base + offset;
+ int copy = min_t(unsigned int, len, iov->iov_len - offset);
+
+ offset = 0;
+
+ /* There is a remnant from previous iov. */
+ if (partial_cnt) {
+ int par_len = 4 - partial_cnt;
+
+ /* iov component is too short ... */
+ if (par_len > copy) {
+ memcpy(kdata, base, copy);
+ kdata += copy;
+ base += copy;
+ partial_cnt += copy;
+ len -= copy;
+ iov++;
+ if (len)
+ continue;
+ *csump = csum_partial(kdata - partial_cnt,
+ partial_cnt, csum);
+ goto out;
+ }
+ memcpy(kdata, base, par_len);
+ csum = csum_partial(kdata - partial_cnt, 4, csum);
+ kdata += par_len;
+ base += par_len;
+ copy -= par_len;
+ len -= par_len;
+ partial_cnt = 0;
+ }
+
+ if (len > copy) {
+ partial_cnt = copy % 4;
+ if (partial_cnt) {
+ copy -= partial_cnt;
+ memcpy(kdata + copy, base + copy, partial_cnt);
+ }
+ }
+
+ if (copy) {
+ csum = csum_partial_copy_nocheck(base, kdata, copy, csum);
+ }
+ len -= copy + partial_cnt;
+ kdata += copy + partial_cnt;
+ iov++;
+ }
+ *csump = csum;
+out:
+ return err;
+}
+
+EXPORT_SYMBOL(udpredirect_getfrag);
+EXPORT_SYMBOL(udp_do_redirect_fn);
+EXPORT_SYMBOL(udpredirect_getfrag_fn);
+#endif /* CONFIG_IFX_UDP_REDIRECT* */

View File

@ -1,312 +0,0 @@
From bd865269f0a339d575ac9f0b768d1168b9865f85 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Thu, 29 Sep 2011 20:31:54 +0200
Subject: [PATCH 59/73] MIPS: lantiq: cache split
---
arch/mips/Kconfig | 22 ++++++
arch/mips/kernel/vpe.c | 66 ++++++++++++++++++
arch/mips/mm/c-r4k.c | 172 ++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 260 insertions(+), 0 deletions(-)
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -1916,6 +1916,28 @@ config IFX_VPE_EXT
help
IFX included extensions in APRP
+config IFX_VPE_CACHE_SPLIT
+ bool "IFX Cache Split Ways"
+ depends on IFX_VPE_EXT
+ help
+ IFX extension for reserving (splitting) cache ways among VPEs. You must
+ give kernel command line arguments vpe_icache_shared=0 or
+ vpe_dcache_shared=0 to enable splitting of icache or dcache
+ respectively. Then you can specify which cache ways should be
+ assigned to which VPE. There are total 8 cache ways, 4 each
+ for dcache and icache: dcache_way0, dcache_way1,dcache_way2,
+ dcache_way3 and icache_way0,icache_way1, icache_way2,icache_way3.
+
+ For example, if you specify vpe_icache_shared=0 and icache_way2=1,
+ then the 3rd icache way will be assigned to VPE0 and denied in VPE1.
+
+ For icache, software is required to make at least one cache way available
+ for a VPE at all times i.e., one can't assign all the icache ways to one
+ VPE.
+
+ By default, vpe_dcache_shared and vpe_icache_shared are set to 1
+ (i.e., both icache and dcache are shared among VPEs)
+
config PERFCTRS
bool "34K Performance counters"
depends on MIPS_MT && PROC_FS
--- a/arch/mips/kernel/vpe.c
+++ b/arch/mips/kernel/vpe.c
@@ -127,6 +127,13 @@ __setup("vpe1_wdog_timeout=", wdog_timeo
EXPORT_SYMBOL(vpe1_wdog_timeout);
#endif
+
+#ifdef CONFIG_IFX_VPE_CACHE_SPLIT /* Code for splitting the cache ways among VPEs. */
+extern int vpe_icache_shared,vpe_dcache_shared;
+extern int icache_way0,icache_way1,icache_way2,icache_way3;
+extern int dcache_way0,dcache_way1,dcache_way2,dcache_way3;
+#endif
+
/* grab the likely amount of memory we will need. */
#ifdef CONFIG_MIPS_VPE_LOADER_TOM
#define P_SIZE (2 * 1024 * 1024)
@@ -865,6 +872,65 @@ static int vpe_run(struct vpe * v)
/* enable this VPE */
write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() | VPECONF0_VPA);
+#ifdef CONFIG_IFX_VPE_CACHE_SPLIT
+ if ( (!vpe_icache_shared) || (!vpe_dcache_shared) ) {
+
+ /* PCP bit must be 1 to split the cache */
+ if(read_c0_mvpconf0() & MVPCONF0_PCP) {
+
+ if ( !vpe_icache_shared ){
+ write_vpe_c0_vpeconf0((read_vpe_c0_vpeconf0()) & ~VPECONF0_ICS);
+
+ /*
+ * If any cache way is 1, then that way is denied
+ * in VPE1. Otherwise assign that way to VPE1.
+ */
+ if (!icache_way0)
+ write_vpe_c0_vpeopt(read_vpe_c0_vpeopt() | VPEOPT_IWX0 );
+ else
+ write_vpe_c0_vpeopt(read_vpe_c0_vpeopt() & ~VPEOPT_IWX0 );
+ if (!icache_way1)
+ write_vpe_c0_vpeopt(read_vpe_c0_vpeopt() | VPEOPT_IWX1 );
+ else
+ write_vpe_c0_vpeopt(read_vpe_c0_vpeopt() & ~VPEOPT_IWX1 );
+ if (!icache_way2)
+ write_vpe_c0_vpeopt(read_vpe_c0_vpeopt() | VPEOPT_IWX2 );
+ else
+ write_vpe_c0_vpeopt(read_vpe_c0_vpeopt() & ~VPEOPT_IWX2 );
+ if (!icache_way3)
+ write_vpe_c0_vpeopt(read_vpe_c0_vpeopt() | VPEOPT_IWX3 );
+ else
+ write_vpe_c0_vpeopt(read_vpe_c0_vpeopt() & ~VPEOPT_IWX3 );
+ }
+
+ if ( !vpe_dcache_shared ) {
+ write_vpe_c0_vpeconf0((read_vpe_c0_vpeconf0()) & ~VPECONF0_DCS);
+
+ /*
+ * If any cache way is 1, then that way is denied
+ * in VPE1. Otherwise assign that way to VPE1.
+ */
+ if (!dcache_way0)
+ write_vpe_c0_vpeopt(read_vpe_c0_vpeopt() | VPEOPT_DWX0 );
+ else
+ write_vpe_c0_vpeopt(read_vpe_c0_vpeopt() & ~VPEOPT_DWX0 );
+ if (!dcache_way1)
+ write_vpe_c0_vpeopt(read_vpe_c0_vpeopt() | VPEOPT_DWX1 );
+ else
+ write_vpe_c0_vpeopt(read_vpe_c0_vpeopt() & ~VPEOPT_DWX1 );
+ if (!dcache_way2)
+ write_vpe_c0_vpeopt(read_vpe_c0_vpeopt() | VPEOPT_DWX2 );
+ else
+ write_vpe_c0_vpeopt(read_vpe_c0_vpeopt() & ~VPEOPT_DWX2 );
+ if (!dcache_way3)
+ write_vpe_c0_vpeopt(read_vpe_c0_vpeopt() | VPEOPT_DWX3 );
+ else
+ write_vpe_c0_vpeopt(read_vpe_c0_vpeopt() & ~VPEOPT_DWX3 );
+ }
+ }
+ }
+#endif /* endif CONFIG_IFX_VPE_CACHE_SPLIT */
+
/* clear out any left overs from a previous program */
write_vpe_c0_status(0);
write_vpe_c0_cause(0);
--- a/arch/mips/mm/c-r4k.c
+++ b/arch/mips/mm/c-r4k.c
@@ -1383,6 +1383,106 @@ static int __init setcoherentio(char *st
__setup("coherentio", setcoherentio);
#endif
+#ifdef CONFIG_IFX_VPE_CACHE_SPLIT /* Code for splitting the cache ways among VPEs. */
+
+#include <asm/mipsmtregs.h>
+
+/*
+ * By default, vpe_icache_shared and vpe_dcache_shared
+ * values are 1 i.e., both icache and dcache are shared
+ * among the VPEs.
+ */
+
+int vpe_icache_shared = 1;
+static int __init vpe_icache_shared_val(char *str)
+{
+ get_option(&str, &vpe_icache_shared);
+ return 1;
+}
+__setup("vpe_icache_shared=", vpe_icache_shared_val);
+EXPORT_SYMBOL(vpe_icache_shared);
+
+int vpe_dcache_shared = 1;
+static int __init vpe_dcache_shared_val(char *str)
+{
+ get_option(&str, &vpe_dcache_shared);
+ return 1;
+}
+__setup("vpe_dcache_shared=", vpe_dcache_shared_val);
+EXPORT_SYMBOL(vpe_dcache_shared);
+
+/*
+ * Software is required to make atleast one icache
+ * way available for a VPE at all times i.e., one
+ * can't assign all the icache ways to one VPE.
+ */
+
+int icache_way0 = 0;
+static int __init icache_way0_val(char *str)
+{
+ get_option(&str, &icache_way0);
+ return 1;
+}
+__setup("icache_way0=", icache_way0_val);
+
+int icache_way1 = 0;
+static int __init icache_way1_val(char *str)
+{
+ get_option(&str, &icache_way1);
+ return 1;
+}
+__setup("icache_way1=", icache_way1_val);
+
+int icache_way2 = 0;
+static int __init icache_way2_val(char *str)
+{
+ get_option(&str, &icache_way2);
+ return 1;
+}
+__setup("icache_way2=", icache_way2_val);
+
+int icache_way3 = 0;
+static int __init icache_way3_val(char *str)
+{
+ get_option(&str, &icache_way3);
+ return 1;
+}
+__setup("icache_way3=", icache_way3_val);
+
+int dcache_way0 = 0;
+static int __init dcache_way0_val(char *str)
+{
+ get_option(&str, &dcache_way0);
+ return 1;
+}
+__setup("dcache_way0=", dcache_way0_val);
+
+int dcache_way1 = 0;
+static int __init dcache_way1_val(char *str)
+{
+ get_option(&str, &dcache_way1);
+ return 1;
+}
+__setup("dcache_way1=", dcache_way1_val);
+
+int dcache_way2 = 0;
+static int __init dcache_way2_val(char *str)
+{
+ get_option(&str, &dcache_way2);
+ return 1;
+}
+__setup("dcache_way2=", dcache_way2_val);
+
+int dcache_way3 = 0;
+static int __init dcache_way3_val(char *str)
+{
+ get_option(&str, &dcache_way3);
+ return 1;
+}
+__setup("dcache_way3=", dcache_way3_val);
+
+#endif /* endif CONFIG_IFX_VPE_CACHE_SPLIT */
+
void __cpuinit r4k_cache_init(void)
{
extern void build_clear_page(void);
@@ -1402,6 +1502,78 @@ void __cpuinit r4k_cache_init(void)
break;
}
+#ifdef CONFIG_IFX_VPE_CACHE_SPLIT
+ /*
+ * We split the cache ways appropriately among the VPEs
+ * based on cache ways values we received as command line
+ * arguments
+ */
+ if ( (!vpe_icache_shared) || (!vpe_dcache_shared) ){
+
+ /* PCP bit must be 1 to split the cache */
+ if(read_c0_mvpconf0() & MVPCONF0_PCP) {
+
+ /* Set CPA bit which enables us to modify VPEOpt register */
+ write_c0_mvpcontrol((read_c0_mvpcontrol()) | MVPCONTROL_CPA);
+
+ if ( !vpe_icache_shared ){
+ write_c0_vpeconf0((read_c0_vpeconf0()) & ~VPECONF0_ICS);
+ /*
+ * If any cache way is 1, then that way is denied
+ * in VPE0. Otherwise assign that way to VPE0.
+ */
+ printk(KERN_DEBUG "icache is split\n");
+ printk(KERN_DEBUG "icache_way0=%d icache_way1=%d icache_way2=%d icache_way3=%d\n",
+ icache_way0, icache_way1,icache_way2, icache_way3);
+ if (icache_way0)
+ write_c0_vpeopt(read_c0_vpeopt() | VPEOPT_IWX0 );
+ else
+ write_c0_vpeopt(read_c0_vpeopt() & ~VPEOPT_IWX0 );
+ if (icache_way1)
+ write_c0_vpeopt(read_c0_vpeopt() | VPEOPT_IWX1 );
+ else
+ write_c0_vpeopt(read_c0_vpeopt() & ~VPEOPT_IWX1 );
+ if (icache_way2)
+ write_c0_vpeopt(read_c0_vpeopt() | VPEOPT_IWX2 );
+ else
+ write_c0_vpeopt(read_c0_vpeopt() & ~VPEOPT_IWX2 );
+ if (icache_way3)
+ write_c0_vpeopt(read_c0_vpeopt() | VPEOPT_IWX3 );
+ else
+ write_c0_vpeopt(read_c0_vpeopt() & ~VPEOPT_IWX3 );
+ }
+
+ if ( !vpe_dcache_shared ) {
+ /*
+ * If any cache way is 1, then that way is denied
+ * in VPE0. Otherwise assign that way to VPE0.
+ */
+ printk(KERN_DEBUG "dcache is split\n");
+ printk(KERN_DEBUG "dcache_way0=%d dcache_way1=%d dcache_way2=%d dcache_way3=%d\n",
+ dcache_way0, dcache_way1, dcache_way2, dcache_way3);
+ write_c0_vpeconf0((read_c0_vpeconf0()) & ~VPECONF0_DCS);
+ if (dcache_way0)
+ write_c0_vpeopt(read_c0_vpeopt() | VPEOPT_DWX0 );
+ else
+ write_c0_vpeopt(read_c0_vpeopt() & ~VPEOPT_DWX0 );
+ if (dcache_way1)
+ write_c0_vpeopt(read_c0_vpeopt() | VPEOPT_DWX1 );
+ else
+ write_c0_vpeopt(read_c0_vpeopt() & ~VPEOPT_DWX1 );
+ if (dcache_way2)
+ write_c0_vpeopt(read_c0_vpeopt() | VPEOPT_DWX2 );
+ else
+ write_c0_vpeopt(read_c0_vpeopt() & ~VPEOPT_DWX2 );
+ if (dcache_way3)
+ write_c0_vpeopt(read_c0_vpeopt() | VPEOPT_DWX3 );
+ else
+ write_c0_vpeopt(read_c0_vpeopt() & ~VPEOPT_DWX3 );
+ }
+ }
+ }
+
+#endif /* endif CONFIG_IFX_VPE_CACHE_SPLIT */
+
probe_pcache();
setup_scache();

View File

@ -1,308 +0,0 @@
From 720f8d0381c60af85f049353464a12fbed903edb Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Tue, 20 Mar 2012 08:26:04 +0100
Subject: [PATCH 60/73] MIPS: clean up clock code
---
arch/mips/lantiq/clk.c | 11 +++
arch/mips/lantiq/clk.h | 3 +-
arch/mips/lantiq/xway/devices.c | 2 +-
arch/mips/lantiq/xway/sysctrl.c | 166 ++++++++++++++++++++++++++++++---------
4 files changed, 143 insertions(+), 39 deletions(-)
--- a/arch/mips/lantiq/clk.c
+++ b/arch/mips/lantiq/clk.c
@@ -44,6 +44,7 @@ struct clk *clk_get_fpi(void)
{
return &cpu_clk_generic[1];
}
+EXPORT_SYMBOL_GPL(clk_get_fpi);
struct clk *clk_get_io(void)
{
@@ -70,6 +71,16 @@ unsigned long clk_get_rate(struct clk *c
}
EXPORT_SYMBOL(clk_get_rate);
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+ if (unlikely(!clk_good(clk)))
+ return 0;
+
+ clk->rate = rate;
+ return 0;
+}
+EXPORT_SYMBOL(clk_set_rate);
+
int clk_enable(struct clk *clk)
{
if (unlikely(!clk_good(clk)))
--- a/arch/mips/lantiq/clk.h
+++ b/arch/mips/lantiq/clk.h
@@ -12,6 +12,7 @@
#include <linux/clkdev.h>
/* clock speeds */
+#define CLOCK_33M 33333333
#define CLOCK_60M 60000000
#define CLOCK_62_5M 62500000
#define CLOCK_83M 83333333
@@ -38,9 +39,9 @@
struct clk {
struct clk_lookup cl;
unsigned long rate;
- unsigned long (*get_rate) (void);
unsigned int module;
unsigned int bits;
+ unsigned long (*get_rate) (void);
int (*enable) (struct clk *clk);
void (*disable) (struct clk *clk);
int (*activate) (struct clk *clk);
--- a/arch/mips/lantiq/xway/devices.c
+++ b/arch/mips/lantiq/xway/devices.c
@@ -59,7 +59,7 @@ static struct resource ltq_stp_resource
void __init ltq_register_gpio_stp(void)
{
- platform_device_register_simple("ltq_stp", 0, &ltq_stp_resource, 1);
+ platform_device_register_simple("ltq_stp", -1, &ltq_stp_resource, 1);
}
/* asc ports - amazon se has its own serial mapping */
--- a/arch/mips/lantiq/xway/sysctrl.c
+++ b/arch/mips/lantiq/xway/sysctrl.c
@@ -16,40 +16,57 @@
#include "../devices.h"
/* clock control register */
-#define LTQ_CGU_IFCCR 0x0018
+#define CGU_IFCCR 0x0018
/* system clock register */
-#define LTQ_CGU_SYS 0x0010
-
-/* the enable / disable registers */
-#define LTQ_PMU_PWDCR 0x1C
-#define LTQ_PMU_PWDSR 0x20
-#define LTQ_PMU_PWDCR1 0x24
-#define LTQ_PMU_PWDSR1 0x28
-
-#define PWDCR(x) ((x) ? (LTQ_PMU_PWDCR1) : (LTQ_PMU_PWDCR))
-#define PWDSR(x) ((x) ? (LTQ_PMU_PWDSR1) : (LTQ_PMU_PWDSR))
-
-/* CGU - clock generation unit */
-#define CGU_EPHY 0x10
+#define CGU_SYS 0x0010
+/* pci control register */
+#define CGU_PCICR 0x0034
+/* ephy configuration register */
+#define CGU_EPHY 0x10
+/* power control register */
+#define PMU_PWDCR 0x1C
+/* power status register */
+#define PMU_PWDSR 0x20
+/* power control register */
+#define PMU_PWDCR1 0x24
+/* power status register */
+#define PMU_PWDSR1 0x28
+/* power control register */
+#define PWDCR(x) ((x) ? (PMU_PWDCR1) : (PMU_PWDCR))
+/* power status register */
+#define PWDSR(x) ((x) ? (PMU_PWDSR1) : (PMU_PWDSR))
/* PMU - power management unit */
-#define PMU_DMA 0x0020
-#define PMU_SPI 0x0100
-#define PMU_EPHY 0x0080
-#define PMU_USB 0x8041
-#define PMU_STP 0x0800
-#define PMU_GPT 0x1000
-#define PMU_PPE 0x2000
-#define PMU_FPI 0x4000
-#define PMU_SWITCH 0x10000000
-#define PMU_AHBS 0x2000
-#define PMU_AHBM 0x8000
-#define PMU_PCIE_CLK 0x80000000
-
-#define PMU1_PCIE_PHY 0x0001
-#define PMU1_PCIE_CTL 0x0002
-#define PMU1_PCIE_MSI 0x0020
-#define PMU1_PCIE_PDI 0x0010
+#define PMU_USB0_P BIT(0)
+#define PMU_PCI BIT(4)
+#define PMU_DMA BIT(5)
+#define PMU_USB0 BIT(5)
+#define PMU_SPI BIT(8)
+#define PMU_EPHY BIT(7)
+#define PMU_EBU BIT(10)
+#define PMU_STP BIT(11)
+#define PMU_GPT BIT(12)
+#define PMU_PPE BIT(13)
+#define PMU_AHBS BIT(13) /* vr9 */
+#define PMU_FPI BIT(14)
+#define PMU_AHBM BIT(15)
+#define PMU_PPE_QSB BIT(18)
+#define PMU_PPE_SLL01 BIT(19)
+#define PMU_PPE_TC BIT(21)
+#define PMU_PPE_EMA BIT(22)
+#define PMU_PPE_DPLUM BIT(23)
+#define PMU_PPE_DPLUS BIT(24)
+#define PMU_USB1_P BIT(26)
+#define PMU_USB1 BIT(27)
+#define PMU_SWITCH BIT(28)
+#define PMU_PPE_TOP BIT(29)
+#define PMU_GPHY BIT(30)
+#define PMU_PCIE_CLK BIT(31)
+
+#define PMU1_PCIE_PHY BIT(0)
+#define PMU1_PCIE_CTL BIT(1)
+#define PMU1_PCIE_PDI BIT(4)
+#define PMU1_PCIE_MSI BIT(5)
#define ltq_pmu_w32(x, y) ltq_w32((x), ltq_pmu_membase + (y))
#define ltq_pmu_r32(x) ltq_r32(ltq_pmu_membase + (x))
@@ -69,13 +86,13 @@ static void __iomem *ltq_pmu_membase;
static int ltq_cgu_enable(struct clk *clk)
{
- ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) | clk->bits, LTQ_CGU_IFCCR);
+ ltq_cgu_w32(ltq_cgu_r32(CGU_IFCCR) | clk->bits, CGU_IFCCR);
return 0;
}
static void ltq_cgu_disable(struct clk *clk)
{
- ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) & ~clk->bits, LTQ_CGU_IFCCR);
+ ltq_cgu_w32(ltq_cgu_r32(CGU_IFCCR) & ~clk->bits, CGU_IFCCR);
}
static int ltq_pmu_enable(struct clk *clk)
@@ -94,9 +111,49 @@ static int ltq_pmu_enable(struct clk *cl
static void ltq_pmu_disable(struct clk *clk)
{
- ltq_pmu_w32(ltq_pmu_r32(LTQ_PMU_PWDCR) | clk->bits, LTQ_PMU_PWDCR);
+ ltq_pmu_w32(ltq_pmu_r32(PWDCR(clk->module)) | clk->bits,
+ PWDCR(clk->module));
}
+static int ltq_pci_enable(struct clk *clk)
+{
+ unsigned int ifccr = ltq_cgu_r32(CGU_IFCCR);
+ /* set clock bus speed */
+ if (ltq_is_ar9()) {
+ ifccr &= ~0x1f00000;
+ if (clk->rate == CLOCK_33M)
+ ifccr |= 0xe00000;
+ else
+ ifccr |= 0x700000; /* 62.5M */
+ } else {
+ ifccr &= ~0xf00000;
+ if (clk->rate == CLOCK_33M)
+ ifccr |= 0x800000;
+ else
+ ifccr |= 0x400000; /* 62.5M */
+ }
+ ltq_cgu_w32(ifccr, CGU_IFCCR);
+ return 0;
+}
+
+static int ltq_pci_ext_enable(struct clk *clk)
+{
+ /* enable external pci clock */
+ ltq_cgu_w32(ltq_cgu_r32(CGU_IFCCR) & ~(1 << 16),
+ CGU_IFCCR);
+ ltq_cgu_w32((1 << 30), CGU_PCICR);
+ return 0;
+}
+
+static void ltq_pci_ext_disable(struct clk *clk)
+{
+ /* enable external pci clock */
+ ltq_cgu_w32(ltq_cgu_r32(CGU_IFCCR) | (1 << 16),
+ CGU_IFCCR);
+ ltq_cgu_w32((1 << 31) | (1 << 30), CGU_PCICR);
+}
+
+/* manage the clock gates via PMU */
static inline void clkdev_add_pmu(const char *dev, const char *con,
unsigned int module, unsigned int bits)
{
@@ -112,6 +169,7 @@ static inline void clkdev_add_pmu(const
clkdev_add(&clk->cl);
}
+/* manage the clock generator */
static inline void clkdev_add_cgu(const char *dev, const char *con,
unsigned int bits)
{
@@ -126,6 +184,33 @@ static inline void clkdev_add_cgu(const
clkdev_add(&clk->cl);
}
+/* pci needs its own enable function */
+static inline void clkdev_add_pci(void)
+{
+ struct clk *clk = kzalloc(sizeof(struct clk), GFP_KERNEL);
+ struct clk *clk_ext = kzalloc(sizeof(struct clk), GFP_KERNEL);
+
+ /* main pci clock */
+ clk->cl.dev_id = "ltq_pci";
+ clk->cl.con_id = NULL;
+ clk->cl.clk = clk;
+ clk->rate = CLOCK_33M;
+ clk->enable = ltq_pci_enable;
+ clk->disable = ltq_pmu_disable;
+ clk->module = 0;
+ clk->bits = PMU_PCI;
+ clkdev_add(&clk->cl);
+
+ /* use internal/external bus clock */
+ clk_ext->cl.dev_id = "ltq_pci";
+ clk_ext->cl.con_id = "external";
+ clk_ext->cl.clk = clk_ext;
+ clk_ext->enable = ltq_pci_ext_enable;
+ clk_ext->disable = ltq_pci_ext_disable;
+ clkdev_add(&clk_ext->cl);
+
+}
+
void __init ltq_soc_init(void)
{
ltq_pmu_membase = ltq_remap_resource(&ltq_pmu_resource);
@@ -144,14 +229,16 @@ void __init ltq_soc_init(void)
ltq_ebu_w32(ltq_ebu_r32(LTQ_EBU_BUSCON0) & ~EBU_WRDIS, LTQ_EBU_BUSCON0);
/* add our clocks */
+ clkdev_add_pmu("ltq_fpi", NULL, 0, PMU_FPI);
clkdev_add_pmu("ltq_dma", NULL, 0, PMU_DMA);
clkdev_add_pmu("ltq_stp", NULL, 0, PMU_STP);
clkdev_add_pmu("ltq_spi", NULL, 0, PMU_SPI);
clkdev_add_pmu("ltq_gptu", NULL, 0, PMU_GPT);
+ clkdev_add_pmu("ltq_ebu", NULL, 0, PMU_EBU);
if (!ltq_is_vr9())
clkdev_add_pmu("ltq_etop", NULL, 0, PMU_PPE);
if (ltq_is_ase()) {
- if (ltq_cgu_r32(LTQ_CGU_SYS) & (1 << 5))
+ if (ltq_cgu_r32(CGU_SYS) & (1 << 5))
clkdev_add_static(CLOCK_266M, CLOCK_133M, CLOCK_133M);
else
clkdev_add_static(CLOCK_133M, CLOCK_133M, CLOCK_133M);
@@ -166,11 +253,16 @@ void __init ltq_soc_init(void)
clkdev_add_pmu("ltq_pcie", "pdi", 1, PMU1_PCIE_PDI);
clkdev_add_pmu("ltq_pcie", "ctl", 1, PMU1_PCIE_CTL);
clkdev_add_pmu("ltq_pcie", "ahb", 0, PMU_AHBM | PMU_AHBS);
- clkdev_add_pmu("usb0", NULL, 0, (1<<6) | 1);
- clkdev_add_pmu("usb1", NULL, 0, (1<<26) | (1<<27));
+ clkdev_add_pmu("usb0", NULL, 0, PMU_USB0 | PMU_USB0_P);
+ clkdev_add_pmu("usb1", NULL, 0, PMU_USB1 | PMU_USB1_P);
+ clkdev_add_pmu("ltq_vrx200", NULL, 0,
+ PMU_SWITCH | PMU_PPE_DPLUS | PMU_PPE_DPLUM |
+ PMU_PPE_EMA | PMU_PPE_TC | PMU_PPE_SLL01 |
+ PMU_PPE_QSB);
} else {
clkdev_add_static(ltq_danube_cpu_hz(), ltq_danube_fpi_hz(),
ltq_danube_io_region_clock());
+ clkdev_add_pci();
if (ltq_is_ar9())
clkdev_add_pmu("ltq_etop", "switch", 0, PMU_SWITCH);
}

View File

@ -1,98 +0,0 @@
From 5e04db198bbad2dc345262e838965332826eb37c Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Fri, 16 Mar 2012 15:49:32 +0100
Subject: [PATCH 61/73] MIPS: cleanup reset code
---
arch/mips/lantiq/xway/reset.c | 59 ++++++++++++++++++++++++++++++++++------
1 files changed, 50 insertions(+), 9 deletions(-)
--- a/arch/mips/lantiq/xway/reset.c
+++ b/arch/mips/lantiq/xway/reset.c
@@ -11,6 +11,7 @@
#include <linux/ioport.h>
#include <linux/pm.h>
#include <linux/export.h>
+#include <linux/delay.h>
#include <asm/reboot.h>
#include <lantiq_soc.h>
@@ -20,12 +21,45 @@
#define ltq_rcu_w32(x, y) ltq_w32((x), ltq_rcu_membase + (y))
#define ltq_rcu_r32(x) ltq_r32(ltq_rcu_membase + (x))
-/* register definitions */
-#define LTQ_RCU_RST 0x0010
-#define LTQ_RCU_RST_ALL 0x40000000
-
-#define LTQ_RCU_RST_STAT 0x0014
-#define LTQ_RCU_STAT_SHIFT 26
+/* reset request register */
+#define RCU_RST_REQ 0x0010
+/* reset status register */
+#define RCU_RST_STAT 0x0014
+
+/* reset cause */
+#define RCU_STAT_SHIFT 26
+/* Global SW Reset */
+#define RCU_RD_SRST BIT(30)
+/* Memory Controller */
+#define RCU_RD_MC BIT(14)
+/* PCI core */
+#define RCU_RD_PCI BIT(13)
+/* Voice DFE/AFE */
+#define RCU_RD_DFE_AFE BIT(12)
+/* DSL AFE */
+#define RCU_RD_DSL_AFE BIT(11)
+/* SDIO core */
+#define RCU_RD_SDIO BIT(10)
+/* DMA core */
+#define RCU_RD_DMA BIT(9)
+/* PPE core */
+#define RCU_RD_PPE BIT(8)
+/* ARC/DFE core */
+#define RCU_RD_ARC_DFE BIT(7)
+/* AHB bus */
+#define RCU_RD_AHB BIT(6)
+/* Ethernet MAC1 */
+#define RCU_RD_ENET_MAC1 BIT(5)
+/* USB and Phy core */
+#define RCU_RD_USB BIT(4)
+/* CPU1 subsystem */
+#define RCU_RD_CPU1 BIT(3)
+/* FPI bus */
+#define RCU_RD_FPI BIT(2)
+/* CPU0 subsystem */
+#define RCU_RD_CPU0 BIT(1)
+/* HW reset via HRST pin */
+#define RCU_RD_HRST BIT(0)
static struct resource ltq_rcu_resource =
MEM_RES("rcu", LTQ_RCU_BASE_ADDR, LTQ_RCU_SIZE);
@@ -36,16 +70,23 @@ static void __iomem *ltq_rcu_membase;
/* This function is used by the watchdog driver */
int ltq_reset_cause(void)
{
- u32 val = ltq_rcu_r32(LTQ_RCU_RST_STAT);
- return val >> LTQ_RCU_STAT_SHIFT;
+ u32 val = ltq_rcu_r32(RCU_RST_STAT);
+ return val >> RCU_STAT_SHIFT;
}
EXPORT_SYMBOL_GPL(ltq_reset_cause);
+void ltq_reset_once(unsigned int module, ulong usec)
+{
+ ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) | module, RCU_RST_REQ);
+ udelay(usec);
+ ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) & ~module, RCU_RST_REQ);
+}
+
static void ltq_machine_restart(char *command)
{
pr_notice("System restart\n");
local_irq_disable();
- ltq_rcu_w32(ltq_rcu_r32(LTQ_RCU_RST) | LTQ_RCU_RST_ALL, LTQ_RCU_RST);
+ ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) | RCU_RD_SRST, RCU_RST_REQ);
unreachable();
}

View File

@ -1,107 +0,0 @@
From 42cfda7eaf263248257cef40b88e06b7a0666eb4 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Sat, 17 Mar 2012 09:58:07 +0100
Subject: [PATCH 62/73] MIPS: lantiq: fixes ar9/vr9 clock
---
arch/mips/lantiq/clk.h | 4 +++-
arch/mips/lantiq/xway/clk.c | 29 ++++++++++++++++++++++++-----
arch/mips/lantiq/xway/sysctrl.c | 13 ++++++++-----
3 files changed, 35 insertions(+), 11 deletions(-)
--- a/arch/mips/lantiq/clk.h
+++ b/arch/mips/lantiq/clk.h
@@ -56,8 +56,10 @@ extern unsigned long ltq_danube_cpu_hz(v
extern unsigned long ltq_danube_fpi_hz(void);
extern unsigned long ltq_danube_io_region_clock(void);
+extern unsigned long ltq_ar9_cpu_hz(void);
+extern unsigned long ltq_ar9_fpi_hz(void);
+
extern unsigned long ltq_vr9_cpu_hz(void);
extern unsigned long ltq_vr9_fpi_hz(void);
-extern unsigned long ltq_vr9_io_region_clock(void);
#endif
--- a/arch/mips/lantiq/xway/clk.c
+++ b/arch/mips/lantiq/xway/clk.c
@@ -217,6 +217,30 @@ unsigned long ltq_danube_cpu_hz(void)
}
}
+unsigned long ltq_ar9_sys_hz(void)
+{
+ if (((ltq_cgu_r32(LTQ_CGU_SYS) >> 3) & 0x3) == 0x2)
+ return CLOCK_393M;
+ return CLOCK_333M;
+}
+
+unsigned long ltq_ar9_fpi_hz(void)
+{
+ unsigned long sys = ltq_ar9_sys_hz();
+
+ if (ltq_cgu_r32(LTQ_CGU_SYS) & BIT(0))
+ return sys;
+ return sys >> 1;
+}
+
+unsigned long ltq_ar9_cpu_hz(void)
+{
+ if (ltq_cgu_r32(LTQ_CGU_SYS) & BIT(2))
+ return ltq_ar9_fpi_hz();
+ else
+ return ltq_ar9_sys_hz();
+}
+
unsigned long ltq_danube_fpi_hz(void)
{
unsigned long ddr_clock = DDR_HZ;
@@ -299,11 +323,6 @@ unsigned long ltq_vr9_fpi_hz(void)
return clk;
}
-unsigned long ltq_vr9_io_region_clock(void)
-{
- return ltq_vr9_fpi_hz();
-}
-
unsigned long ltq_vr9_fpi_bus_clock(int fpi)
{
return ltq_vr9_fpi_hz();
--- a/arch/mips/lantiq/xway/sysctrl.c
+++ b/arch/mips/lantiq/xway/sysctrl.c
@@ -237,6 +237,8 @@ void __init ltq_soc_init(void)
clkdev_add_pmu("ltq_ebu", NULL, 0, PMU_EBU);
if (!ltq_is_vr9())
clkdev_add_pmu("ltq_etop", NULL, 0, PMU_PPE);
+ if (!ltq_is_ase())
+ clkdev_add_pci();
if (ltq_is_ase()) {
if (ltq_cgu_r32(CGU_SYS) & (1 << 5))
clkdev_add_static(CLOCK_266M, CLOCK_133M, CLOCK_133M);
@@ -246,7 +248,7 @@ void __init ltq_soc_init(void)
clkdev_add_pmu("ltq_etop", "ephy", 0, PMU_EPHY);
} else if (ltq_is_vr9()) {
clkdev_add_static(ltq_vr9_cpu_hz(), ltq_vr9_fpi_hz(),
- ltq_vr9_io_region_clock());
+ ltq_vr9_fpi_hz());
clkdev_add_pmu("ltq_pcie", "phy", 1, PMU1_PCIE_PHY);
clkdev_add_pmu("ltq_pcie", "bus", 0, PMU_PCIE_CLK);
clkdev_add_pmu("ltq_pcie", "msi", 1, PMU1_PCIE_MSI);
@@ -259,11 +261,12 @@ void __init ltq_soc_init(void)
PMU_SWITCH | PMU_PPE_DPLUS | PMU_PPE_DPLUM |
PMU_PPE_EMA | PMU_PPE_TC | PMU_PPE_SLL01 |
PMU_PPE_QSB);
+ } else if (ltq_is_ar9()) {
+ clkdev_add_static(ltq_ar9_cpu_hz(), ltq_ar9_fpi_hz(),
+ ltq_ar9_fpi_hz());
+ clkdev_add_pmu("ltq_etop", "switch", 0, PMU_SWITCH);
} else {
clkdev_add_static(ltq_danube_cpu_hz(), ltq_danube_fpi_hz(),
- ltq_danube_io_region_clock());
- clkdev_add_pci();
- if (ltq_is_ar9())
- clkdev_add_pmu("ltq_etop", "switch", 0, PMU_SWITCH);
+ ltq_danube_io_region_clock());
}
}

View File

@ -1,52 +0,0 @@
From 08d0c1d1f42f6bc6d446763dafe5338b0963cf58 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Mon, 19 Mar 2012 15:53:37 +0100
Subject: [PATCH 63/73] MIPS: lantiq: fixes danube clock
---
arch/mips/lantiq/xway/clk.c | 20 ++++++++++----------
1 files changed, 10 insertions(+), 10 deletions(-)
--- a/arch/mips/lantiq/xway/clk.c
+++ b/arch/mips/lantiq/xway/clk.c
@@ -181,7 +181,7 @@ unsigned long ltq_danube_io_region_clock
{
unsigned int ret = ltq_get_pll0_fosc();
- switch (ltq_cgu_r32(LTQ_CGU_PLL2_CFG) & CGU_SYS_DDR_SEL) {
+ switch (ltq_cgu_r32(LTQ_CGU_SYS) & 0x3) {
default:
case 0:
return (ret + 1) / 2;
@@ -203,6 +203,15 @@ unsigned long ltq_danube_fpi_bus_clock(i
return ret;
}
+unsigned long ltq_danube_fpi_hz(void)
+{
+ unsigned long ddr_clock = DDR_HZ;
+
+ if (ltq_cgu_r32(LTQ_CGU_SYS) & 0x40)
+ return ddr_clock >> 1;
+ return ddr_clock;
+}
+
unsigned long ltq_danube_cpu_hz(void)
{
switch (ltq_cgu_r32(LTQ_CGU_SYS) & 0xc) {
@@ -241,15 +250,6 @@ unsigned long ltq_ar9_cpu_hz(void)
return ltq_ar9_sys_hz();
}
-unsigned long ltq_danube_fpi_hz(void)
-{
- unsigned long ddr_clock = DDR_HZ;
-
- if (ltq_cgu_r32(LTQ_CGU_SYS) & 0x40)
- return ddr_clock >> 1;
- return ddr_clock;
-}
-
unsigned long ltq_vr9_cpu_hz(void)
{
unsigned int cpu_sel;

View File

@ -1,61 +0,0 @@
From 76d01e1bc369026d9ec47d2c8355871c083134d2 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Tue, 20 Mar 2012 13:05:11 +0100
Subject: [PATCH 64/73] MIPS: adds dsl clocks
---
arch/mips/lantiq/xway/sysctrl.c | 15 +++++++++++++--
1 files changed, 13 insertions(+), 2 deletions(-)
--- a/arch/mips/lantiq/xway/sysctrl.c
+++ b/arch/mips/lantiq/xway/sysctrl.c
@@ -41,8 +41,9 @@
#define PMU_PCI BIT(4)
#define PMU_DMA BIT(5)
#define PMU_USB0 BIT(5)
+#define PMU_EPHY BIT(7) /* ase */
#define PMU_SPI BIT(8)
-#define PMU_EPHY BIT(7)
+#define PMU_DFE BIT(9)
#define PMU_EBU BIT(10)
#define PMU_STP BIT(11)
#define PMU_GPT BIT(12)
@@ -147,7 +148,7 @@ static int ltq_pci_ext_enable(struct clk
static void ltq_pci_ext_disable(struct clk *clk)
{
- /* enable external pci clock */
+ /* disable external pci clock (internal) */
ltq_cgu_w32(ltq_cgu_r32(CGU_IFCCR) | (1 << 16),
CGU_IFCCR);
ltq_cgu_w32((1 << 31) | (1 << 30), CGU_PCICR);
@@ -246,6 +247,9 @@ void __init ltq_soc_init(void)
clkdev_add_static(CLOCK_133M, CLOCK_133M, CLOCK_133M);
clkdev_add_cgu("ltq_etop", "ephycgu", CGU_EPHY),
clkdev_add_pmu("ltq_etop", "ephy", 0, PMU_EPHY);
+ clkdev_add_pmu("ltq_dsl", NULL, 0,
+ PMU_PPE_EMA | PMU_PPE_TC | PMU_PPE_SLL01 |
+ PMU_AHBS | PMU_DFE);
} else if (ltq_is_vr9()) {
clkdev_add_static(ltq_vr9_cpu_hz(), ltq_vr9_fpi_hz(),
ltq_vr9_fpi_hz());
@@ -261,12 +265,19 @@ void __init ltq_soc_init(void)
PMU_SWITCH | PMU_PPE_DPLUS | PMU_PPE_DPLUM |
PMU_PPE_EMA | PMU_PPE_TC | PMU_PPE_SLL01 |
PMU_PPE_QSB);
+ clkdev_add_pmu("ltq_dsl", NULL, 0, PMU_DFE | PMU_AHBS);
} else if (ltq_is_ar9()) {
clkdev_add_static(ltq_ar9_cpu_hz(), ltq_ar9_fpi_hz(),
ltq_ar9_fpi_hz());
clkdev_add_pmu("ltq_etop", "switch", 0, PMU_SWITCH);
+ clkdev_add_pmu("ltq_dsl", NULL, 0,
+ PMU_PPE_EMA | PMU_PPE_TC | PMU_PPE_SLL01 |
+ PMU_PPE_QSB | PMU_AHBS | PMU_DFE);
} else {
clkdev_add_static(ltq_danube_cpu_hz(), ltq_danube_fpi_hz(),
ltq_danube_io_region_clock());
+ clkdev_add_pmu("ltq_dsl", NULL, 0,
+ PMU_PPE_EMA | PMU_PPE_TC | PMU_PPE_SLL01 |
+ PMU_PPE_QSB | PMU_AHBS | PMU_DFE);
}
}

View File

@ -1,26 +0,0 @@
From 75ecc8a55268df4eee6c97f8236a42c82fde44b2 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Tue, 20 Mar 2012 08:22:11 +0100
Subject: [PATCH 65/73] MIPS: lantiq: dont always register asc0
---
arch/mips/lantiq/xway/prom.c | 6 ++----
1 files changed, 2 insertions(+), 4 deletions(-)
--- a/arch/mips/lantiq/xway/prom.c
+++ b/arch/mips/lantiq/xway/prom.c
@@ -101,12 +101,10 @@ void __init ltq_soc_detect(struct ltq_so
void __init ltq_soc_setup(void)
{
- if (ltq_is_ase()) {
+ if (ltq_is_ase())
ltq_register_ase_asc();
- } else {
- ltq_register_asc(0);
+ else
ltq_register_asc(1);
- }
ltq_register_gpio();
ltq_register_wdt();
}

View File

@ -1,29 +0,0 @@
From 88ac424363e7d5d0a9301bd163877f8b442cc865 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Tue, 20 Mar 2012 09:44:27 +0100
Subject: [PATCH 66/73] MIPS: lantiq: irqs were not cleared properly on boot
---
arch/mips/lantiq/irq.c | 10 +++++-----
1 files changed, 5 insertions(+), 5 deletions(-)
--- a/arch/mips/lantiq/irq.c
+++ b/arch/mips/lantiq/irq.c
@@ -327,12 +327,12 @@ void __init arch_init_irq(void)
panic("Failed to remap eiu memory\n");
}
- /* make sure all irqs are turned off by default */
- for (i = 0; i < 5; i++)
+ for (i = 0; i < 5; i++) {
+ /* make sure all irqs are turned off by default */
ltq_icu_w32(0, LTQ_ICU_IM0_IER + (i * LTQ_ICU_OFFSET));
-
- /* clear all possibly pending interrupts */
- ltq_icu_w32(~0, LTQ_ICU_IM0_ISR + (i * LTQ_ICU_OFFSET));
+ /* clear all possibly pending interrupts */
+ ltq_icu_w32(~0, LTQ_ICU_IM0_ISR + (i * LTQ_ICU_OFFSET));
+ }
mips_cpu_irq_init();

View File

@ -1,59 +0,0 @@
From 5e679bb5e0ba948e5a1aa52ab50b6b60d175348d Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Wed, 21 Mar 2012 14:17:37 +0100
Subject: [PATCH 67/73] MIPS: lantiq: adds bootsel helper
---
.../mips/include/asm/mach-lantiq/xway/lantiq_soc.h | 12 ++++++++++++
arch/mips/lantiq/xway/reset.c | 12 +++++++++++-
2 files changed, 23 insertions(+), 1 deletions(-)
--- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
+++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
@@ -144,6 +144,18 @@
#define LTQ_MPS_BASE_ADDR (KSEG1 + 0x1F107000)
#define LTQ_MPS_CHIPID ((u32 *)(LTQ_MPS_BASE_ADDR + 0x0344))
+/* BOOT_SEL - find what boot media we have */
+#define BS_EXT_ROM 0x0
+#define BS_FLASH 0x1
+#define BS_MII0 0x2
+#define BS_PCI 0x3
+#define BS_UART1 0x4
+#define BS_SPI 0x5
+#define BS_NAND 0x6
+#define BS_RMII0 0x7
+
+extern unsigned char ltq_boot_select(void);
+
/* register access macros for EBU and CGU */
#define ltq_ebu_w32(x, y) ltq_w32((x), ltq_ebu_membase + (y))
#define ltq_ebu_r32(x) ltq_r32(ltq_ebu_membase + (x))
--- a/arch/mips/lantiq/xway/reset.c
+++ b/arch/mips/lantiq/xway/reset.c
@@ -27,7 +27,11 @@
#define RCU_RST_STAT 0x0014
/* reset cause */
-#define RCU_STAT_SHIFT 26
+#define RCU_STAT_SHIFT 26
+/* boot selection */
+#define RCU_BOOT_SEL_SHIFT 26
+#define RCU_BOOT_SEL_MASK 0x7
+
/* Global SW Reset */
#define RCU_RD_SRST BIT(30)
/* Memory Controller */
@@ -75,6 +79,12 @@ int ltq_reset_cause(void)
}
EXPORT_SYMBOL_GPL(ltq_reset_cause);
+unsigned char ltq_boot_select(void)
+{
+ u32 val = ltq_rcu_r32(RCU_RST_STAT);
+ return (val >> RCU_BOOT_SEL_SHIFT) & RCU_BOOT_SEL_MASK;
+}
+
void ltq_reset_once(unsigned int module, ulong usec)
{
ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) | module, RCU_RST_REQ);

View File

@ -1,19 +0,0 @@
From a843a038cefffbad99e2fc3e95b0f72e6cd28124 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Fri, 23 Mar 2012 11:28:22 +0100
Subject: [PATCH 68/73] MIPS: lantiq: adds USB_ARCH_HAS_HCD to CONFIG_LANTIQ
---
arch/mips/Kconfig | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -229,6 +229,7 @@ config LANTIQ
select CLKDEV_LOOKUP
select HAVE_OPROFILE
select MIPS_MACHINE
+ select USB_ARCH_HAS_HCD
config LASAT
bool "LASAT Networks platforms"

View File

@ -1,20 +0,0 @@
From 2690917f28c385dd3edf0e2b92dc6b44a1b3dd12 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Thu, 5 Apr 2012 21:51:05 +0200
Subject: [PATCH 69/73] MIPS: lantiq: fixes bad PMU_USB0(0) define
---
arch/mips/lantiq/xway/sysctrl.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
--- a/arch/mips/lantiq/xway/sysctrl.c
+++ b/arch/mips/lantiq/xway/sysctrl.c
@@ -40,7 +40,7 @@
#define PMU_USB0_P BIT(0)
#define PMU_PCI BIT(4)
#define PMU_DMA BIT(5)
-#define PMU_USB0 BIT(5)
+#define PMU_USB0 BIT(6)
#define PMU_EPHY BIT(7) /* ase */
#define PMU_SPI BIT(8)
#define PMU_DFE BIT(9)

View File

@ -1,51 +0,0 @@
From 6c2374c768e0eacba197e242e8793d93846dc762 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Wed, 11 Apr 2012 18:43:50 +0200
Subject: [PATCH 70/73] MIPS: lantiq: fix dwc_otg usb for ase
changed irq number and pmu settings. little bit of fiddling to get the now variable
irq into resources.
Signed-off-by: Conor O'Gorman <i@conorogorman.net>
---
.../mips/include/asm/mach-lantiq/xway/lantiq_irq.h | 1 +
drivers/usb/dwc_otg/dwc_otg_driver.c | 3 +++
drivers/usb/dwc_otg/dwc_otg_ifx.c | 5 ++++-
3 files changed, 8 insertions(+), 1 deletions(-)
--- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h
+++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h
@@ -36,6 +36,7 @@
#define LTQ_TIMER6_INT (INT_NUM_IM1_IRL0 + 23)
#define LTQ_USB_INT (INT_NUM_IM1_IRL0 + 22)
+#define LTQ_USB_ASE_INT (INT_NUM_IM0_IRL0 + 31)
#define LTQ_USB_OC_INT (INT_NUM_IM4_IRL0 + 23)
#define MIPS_CPU_TIMER_IRQ 7
--- a/drivers/usb/dwc_otg/dwc_otg_driver.c
+++ b/drivers/usb/dwc_otg/dwc_otg_driver.c
@@ -860,6 +860,9 @@ static int __init dwc_otg_init(void)
printk(KERN_INFO "%s: version %s\n", dwc_driver_name, DWC_DRIVER_VERSION);
+ if (ltq_is_ase())
+ dwc_irq = LTQ_USB_ASE_INT;
+
// ifxmips setup
retval = ifx_usb_hc_init(dwc_iomem_base, dwc_irq);
if (retval < 0)
--- a/drivers/usb/dwc_otg/dwc_otg_ifx.c
+++ b/drivers/usb/dwc_otg/dwc_otg_ifx.c
@@ -61,7 +61,10 @@ void dwc_otg_power_on (void)
// clear power
writel(readl(DANUBE_PMU_PWDCR) | 0x41, DANUBE_PMU_PWDCR);
// set clock gating
- writel(readl(DANUBE_CGU_IFCCR) | 0x30, DANUBE_CGU_IFCCR);
+ if (ltq_is_ase())
+ writel(readl(DANUBE_CGU_IFCCR) & ~0x20, DANUBE_CGU_IFCCR);
+ else
+ writel(readl(DANUBE_CGU_IFCCR) | 0x30, DANUBE_CGU_IFCCR);
// set power
writel(readl(DANUBE_PMU_PWDCR) & ~0x1, DANUBE_PMU_PWDCR);
writel(readl(DANUBE_PMU_PWDCR) & ~0x40, DANUBE_PMU_PWDCR);

View File

@ -1,83 +0,0 @@
From d8e3038c520ea6c7619d3f5339c47ca0c2aa7fe3 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Wed, 11 Apr 2012 18:47:53 +0200
Subject: [PATCH 71/73] MIPS: lantiq: stp, fix for ase, add get, clock
disabled
Lantiq serial-to-parallel hardware gpio module
Added gpio pins as used for amazon se (ase)
Added get to enable reporting of gpio status
Changed to use software update, as hw clock was not running on ase. Clock
really only needed if hw flashing was implemented.
Signed-off-by: Conor O'Gorman <i@conorogorman.net>
---
arch/mips/lantiq/xway/gpio_stp.c | 22 +++++++++++++---------
1 files changed, 13 insertions(+), 9 deletions(-)
--- a/arch/mips/lantiq/xway/gpio_stp.c
+++ b/arch/mips/lantiq/xway/gpio_stp.c
@@ -27,6 +27,7 @@
#define LTQ_STP_AR 0x10
#define LTQ_STP_CON_SWU (1 << 31)
+#define LTQ_STP_SWU_MASK (1 << 31)
#define LTQ_STP_2HZ 0
#define LTQ_STP_4HZ (1 << 23)
#define LTQ_STP_8HZ (2 << 23)
@@ -60,6 +61,12 @@ static void ltq_stp_set(struct gpio_chip
else
ltq_stp_shadow &= ~(1 << offset);
ltq_stp_w32(ltq_stp_shadow, LTQ_STP_CPU0);
+ ltq_stp_w32_mask(LTQ_STP_SWU_MASK, LTQ_STP_CON_SWU, LTQ_STP_CON0);
+}
+
+static int ltq_stp_get(struct gpio_chip *chip, unsigned offset)
+{
+ return !!(ltq_stp_r32(LTQ_STP_CPU0) & (1<<offset));
}
static int ltq_stp_direction_output(struct gpio_chip *chip, unsigned offset,
@@ -74,6 +81,7 @@ static struct gpio_chip ltq_stp_chip = {
.label = "ltq_stp",
.direction_output = ltq_stp_direction_output,
.set = ltq_stp_set,
+ .get = ltq_stp_get,
.base = 200,
.ngpio = 24,
.owner = THIS_MODULE,
@@ -97,12 +105,6 @@ static int ltq_stp_hw_init(struct device
ltq_stp_w32_mask(0, LTQ_STP_GROUP0 | LTQ_STP_GROUP1 | LTQ_STP_GROUP2,
LTQ_STP_CON1);
- /* stp are update periodically by the FPI bus */
- ltq_stp_w32_mask(LTQ_STP_UPD_MASK, LTQ_STP_UPD_FPI, LTQ_STP_CON1);
-
- /* set stp update speed */
- ltq_stp_w32_mask(LTQ_STP_SPEED_MASK, LTQ_STP_8HZ, LTQ_STP_CON1);
-
/* tell the hardware that pin (led) 0 and 1 are controlled
* by the dsl arc
*/
@@ -118,6 +120,7 @@ static int __devinit ltq_stp_probe(struc
{
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
int ret = 0;
+ int pin;
if (!res)
return -ENOENT;
@@ -135,9 +138,10 @@ static int __devinit ltq_stp_probe(struc
}
/* the 3 pins used to control the external stp */
- if (ltq_gpio_request(&pdev->dev, 4, 2, 1, "stp-st") ||
- ltq_gpio_request(&pdev->dev, 5, 2, 1, "stp-d") ||
- ltq_gpio_request(&pdev->dev, 6, 2, 1, "stp-sh")) {
+ pin = ltq_is_ase() ? 1 : 4;
+ if (ltq_gpio_request(&pdev->dev, pin, 2, 1, "stp-st") ||
+ ltq_gpio_request(&pdev->dev, pin+1, 2, 1, "stp-d") ||
+ ltq_gpio_request(&pdev->dev, pin+2, 2, 1, "stp-sh")) {
dev_err(&pdev->dev, "failed to request needed gpios\n");
return -EBUSY;
}

View File

@ -1,188 +0,0 @@
From d1cd860adbd87c42c90db1c5658cf10ed1dbdd3e Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Thu, 12 Apr 2012 13:25:42 +0200
Subject: [PATCH 72/73] MIPS: lantiq: fix spi for ase, update for clkdev and
platform driver
irqs, gpios, chipselects
updated to use module_platform_driver()
clkdev is a bit hacky, using ltq_spi.0, as specifying no device numbering led to
the mtd driver not hooking up to an spi flash.
Signed-off-by: Conor O'Gorman <i@conorogorman.net>
---
.../mips/include/asm/mach-lantiq/xway/lantiq_irq.h | 4 ++
arch/mips/lantiq/xway/sysctrl.c | 2 +-
drivers/spi/spi-xway.c | 58 ++++++++++----------
3 files changed, 35 insertions(+), 29 deletions(-)
--- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h
+++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h
@@ -30,6 +30,10 @@
#define LTQ_SSC_TIR_AR9 (INT_NUM_IM0_IRL0 + 14)
#define LTQ_SSC_RIR_AR9 (INT_NUM_IM0_IRL0 + 15)
#define LTQ_SSC_EIR (INT_NUM_IM0_IRL0 + 16)
+#define LTQ_SSC_RIR_ASE (INT_NUM_IM0_IRL0 + 16)
+#define LTQ_SSC_TIR_ASE (INT_NUM_IM0_IRL0 + 17)
+#define LTQ_SSC_EIR_ASE (INT_NUM_IM0_IRL0 + 18)
+#define LTQ_SSC_FIR_ASE (INT_NUM_IM0_IRL0 + 19)
#define LTQ_MEI_DYING_GASP_INT (INT_NUM_IM1_IRL0 + 21)
#define LTQ_MEI_INT (INT_NUM_IM1_IRL0 + 23)
--- a/arch/mips/lantiq/xway/sysctrl.c
+++ b/arch/mips/lantiq/xway/sysctrl.c
@@ -233,7 +233,7 @@ void __init ltq_soc_init(void)
clkdev_add_pmu("ltq_fpi", NULL, 0, PMU_FPI);
clkdev_add_pmu("ltq_dma", NULL, 0, PMU_DMA);
clkdev_add_pmu("ltq_stp", NULL, 0, PMU_STP);
- clkdev_add_pmu("ltq_spi", NULL, 0, PMU_SPI);
+ clkdev_add_pmu("ltq_spi.0", NULL, 0, PMU_SPI);
clkdev_add_pmu("ltq_gptu", NULL, 0, PMU_GPT);
clkdev_add_pmu("ltq_ebu", NULL, 0, PMU_EBU);
if (!ltq_is_vr9())
--- a/drivers/spi/spi-xway.c
+++ b/drivers/spi/spi-xway.c
@@ -143,9 +143,9 @@
#define LTQ_SPI_IRNEN_ALL 0xF
/* Hard-wired GPIOs used by SPI controller */
-#define LTQ_SPI_GPIO_DI 16
-#define LTQ_SPI_GPIO_DO 17
-#define LTQ_SPI_GPIO_CLK 18
+#define LTQ_SPI_GPIO_DI (ltq_is_ase()? 8 : 16)
+#define LTQ_SPI_GPIO_DO (ltq_is_ase()? 9 : 17)
+#define LTQ_SPI_GPIO_CLK (ltq_is_ase()? 10 : 18)
struct ltq_spi {
struct spi_bitbang bitbang;
@@ -229,7 +229,7 @@ static void ltq_spi_hw_enable(struct ltq
u32 clc;
/* Power-up mdule */
- clk_enable(hw->spiclk);
+ clk_enable(hw->spiclk);
/*
* Set clock divider for run mode to 1 to
@@ -245,7 +245,7 @@ static void ltq_spi_hw_disable(struct lt
ltq_spi_reg_write(hw, LTQ_SPI_CLC_DISS, LTQ_SPI_CLC);
/* Power-down mdule */
- clk_disable(hw->spiclk);
+ clk_disable(hw->spiclk);
}
static void ltq_spi_reset_fifos(struct ltq_spi *hw)
@@ -284,7 +284,7 @@ static inline int ltq_spi_wait_ready(str
cond_resched();
} while (!time_after_eq(jiffies, timeout));
- dev_err(hw->dev, "SPI wait ready timed out\n");
+ dev_err(hw->dev, "SPI wait ready timed out stat: %x\n", stat);
return -ETIMEDOUT;
}
@@ -556,6 +556,12 @@ static const struct ltq_spi_cs_gpio_map
{ 11, 3 },
};
+static const struct ltq_spi_cs_gpio_map ltq_spi_cs_ase[] = {
+ { 7, 2 },
+ { 15, 1 },
+ { 14, 1 },
+};
+
static int ltq_spi_setup(struct spi_device *spi)
{
struct ltq_spi *hw = ltq_spi_to_hw(spi);
@@ -600,8 +606,10 @@ static int ltq_spi_setup(struct spi_devi
cstate->cs_activate = ltq_spi_gpio_cs_activate;
cstate->cs_deactivate = ltq_spi_gpio_cs_deactivate;
} else {
- ret = ltq_gpio_request(&spi->dev, ltq_spi_cs[spi->chip_select].gpio,
- ltq_spi_cs[spi->chip_select].mux,
+ struct ltq_spi_cs_gpio_map *cs_map =
+ ltq_is_ase() ? ltq_spi_cs_ase : ltq_spi_cs;
+ ret = ltq_gpio_request(&spi->dev, cs_map[spi->chip_select].gpio,
+ cs_map[spi->chip_select].mux,
1, "spi-cs");
if (ret)
return -EBUSY;
@@ -633,7 +641,8 @@ static void ltq_spi_cleanup(struct spi_d
if (cdata && cdata->gpio)
gpio = cdata->gpio;
else
- gpio = ltq_spi_cs[spi->chip_select].gpio;
+ gpio = ltq_is_ase() ? ltq_spi_cs_ase[spi->chip_select].gpio :
+ ltq_spi_cs[spi->chip_select].gpio;
gpio_free(gpio);
kfree(cstate);
@@ -868,7 +877,8 @@ static const struct ltq_spi_irq_map ltq_
{ "spi_err", ltq_spi_err_irq },
};
-static int __init ltq_spi_probe(struct platform_device *pdev)
+static int __devinit
+ltq_spi_probe(struct platform_device *pdev)
{
struct spi_master *master;
struct resource *r;
@@ -910,14 +920,14 @@ static int __init ltq_spi_probe(struct p
hw->fpiclk = clk_get_fpi();
if (IS_ERR(hw->fpiclk)) {
- dev_err(&pdev->dev, "clk_get\n");
+ dev_err(&pdev->dev, "fpi clk\n");
ret = PTR_ERR(hw->fpiclk);
goto err_master;
}
hw->spiclk = clk_get(&pdev->dev, NULL);
if (IS_ERR(hw->spiclk)) {
- dev_err(&pdev->dev, "clk_get\n");
+ dev_err(&pdev->dev, "spi clk\n");
ret = PTR_ERR(hw->spiclk);
goto err_master;
}
@@ -1014,7 +1024,8 @@ err:
return ret;
}
-static int __exit ltq_spi_remove(struct platform_device *pdev)
+static int __devexit
+ltq_spi_remove(struct platform_device *pdev)
{
struct ltq_spi *hw = platform_get_drvdata(pdev);
int ret, i;
@@ -1043,24 +1054,15 @@ static int __exit ltq_spi_remove(struct
}
static struct platform_driver ltq_spi_driver = {
+ .probe = ltq_spi_probe,
+ .remove = __devexit_p(ltq_spi_remove),
.driver = {
- .name = "ltq_spi",
- .owner = THIS_MODULE,
- },
- .remove = __exit_p(ltq_spi_remove),
+ .name = "ltq_spi",
+ .owner = THIS_MODULE,
+ },
};
-static int __init ltq_spi_init(void)
-{
- return platform_driver_probe(&ltq_spi_driver, ltq_spi_probe);
-}
-module_init(ltq_spi_init);
-
-static void __exit ltq_spi_exit(void)
-{
- platform_driver_unregister(&ltq_spi_driver);
-}
-module_exit(ltq_spi_exit);
+module_platform_driver(ltq_spi_driver);
MODULE_DESCRIPTION("Lantiq SoC SPI controller driver");
MODULE_AUTHOR("Daniel Schwierzeck <daniel.schwierzeck@googlemail.com>");

Some files were not shown because too many files have changed in this diff Show More