lantiq: bump to 3.1
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@28721 3c298f89-4303-0410-b956-a3cf2f4a3e73master
parent
e4f42228c6
commit
fc4b9802d7
|
@ -12,7 +12,7 @@ BOARDNAME:=Lantiq GPON/XWAY
|
|||
FEATURES:=squashfs jffs2
|
||||
DEFAULT_SUBTARGET:=danube
|
||||
|
||||
LINUX_VERSION:=3.0.3
|
||||
LINUX_VERSION:=3.1
|
||||
|
||||
CFLAGS=-Os -pipe -mips32r2 -mtune=mips32r2 -fno-caller-saves
|
||||
|
||||
|
|
|
@ -68,7 +68,7 @@ define Profile/ARV7525PW
|
|||
kmod-rt2800-pci wpad-mini kmod-ltq-dsl-firmware-b-danube
|
||||
endef
|
||||
|
||||
define Profile/ARV4525PW/Description
|
||||
define Profile/ARV7525PW/Description
|
||||
Package set optimized for the ARV4525PW
|
||||
endef
|
||||
|
||||
|
|
|
@ -1,109 +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/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/ath5k_platform.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/phy.h>
|
||||
|
||||
#include <irq.h>
|
||||
|
||||
#include <lantiq_soc.h>
|
||||
#include <lantiq_platform.h>
|
||||
|
||||
#include "../machtypes.h"
|
||||
#include "../dev-leds-gpio.h"
|
||||
#include "devices.h"
|
||||
#include "dev-dwc_otg.h"
|
||||
|
||||
static struct mtd_partition gigasx76x_partitions[] =
|
||||
{
|
||||
{
|
||||
.name = "secondary_env",
|
||||
.offset = 0xe000,
|
||||
.size = 0x2000,
|
||||
},
|
||||
{
|
||||
.name = "secondary_boot",
|
||||
.offset = 0x10000,
|
||||
.size = 0x10000,
|
||||
},
|
||||
{
|
||||
.name = "uboot",
|
||||
.offset = 0x20000,
|
||||
.size = 0x30000,
|
||||
},
|
||||
{
|
||||
.name = "linux",
|
||||
.offset = 0x50000,
|
||||
.size = 0x7a0000,
|
||||
},
|
||||
{
|
||||
.name = "board_config",
|
||||
.offset = 0x7f0000,
|
||||
.size = 0x10000,
|
||||
},
|
||||
};
|
||||
|
||||
static struct gpio_led
|
||||
gigasx76x_leds_gpio[] __initdata = {
|
||||
{ .name = "soc:green:usb", .gpio = 202, },
|
||||
{ .name = "soc:green:wlan", .gpio = 203, },
|
||||
{ .name = "soc:green:phone2", .gpio = 204, },
|
||||
{ .name = "soc:green:phone1", .gpio = 205, },
|
||||
{ .name = "soc:green:line", .gpio = 206, },
|
||||
{ .name = "soc:green:online", .gpio = 207, },
|
||||
};
|
||||
|
||||
|
||||
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(<q_pci_data);
|
||||
ltq_register_etop(<q_eth_data);
|
||||
xway_register_dwc(GIGASX76X_USB);
|
||||
ltq_register_tapi();
|
||||
ltq_register_madwifi_eep();
|
||||
ltq_add_device_leds_gpio(-1, ARRAY_SIZE(gigasx76x_leds_gpio), gigasx76x_leds_gpio);
|
||||
}
|
||||
|
||||
MIPS_MACHINE(LANTIQ_MACH_GIGASX76X,
|
||||
"GIGASX76X",
|
||||
"GIGASX76X - Gigaset SX761,SX762,SX763",
|
||||
gigasx76x_init);
|
|
@ -14,8 +14,8 @@
|
|||
|
||||
#include <linux/leds.h>
|
||||
|
||||
void ltq_add_device_leds_gpio(int id,
|
||||
unsigned num_leds,
|
||||
struct gpio_led *leds) __init;
|
||||
void ltq_add_device_gpio_leds(int id,
|
||||
unsigned num_leds,
|
||||
struct gpio_led *leds) __init;
|
||||
|
||||
#endif /* _LANTIQ_DEV_LEDS_GPIO_H */
|
|
@ -9,11 +9,11 @@
|
|||
* by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include "linux/init.h"
|
||||
#include "linux/slab.h"
|
||||
#include <linux/init.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include "dev-gpio-buttons.h"
|
||||
#include <dev-gpio-buttons.h>
|
||||
|
||||
void __init ltq_register_gpio_keys_polled(int id,
|
||||
unsigned poll_interval,
|
|
@ -15,9 +15,9 @@
|
|||
#include <linux/slab.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include "dev-leds-gpio.h"
|
||||
#include <dev-gpio-leds.h>
|
||||
|
||||
void __init ltq_add_device_leds_gpio(int id, unsigned num_leds,
|
||||
void __init ltq_add_device_gpio_leds(int id, unsigned num_leds,
|
||||
struct gpio_led *leds)
|
||||
{
|
||||
struct platform_device *pdev;
|
||||
|
@ -31,7 +31,7 @@ void __init ltq_add_device_leds_gpio(int id, unsigned num_leds,
|
|||
|
||||
memcpy(p, leds, num_leds * sizeof(*p));
|
||||
|
||||
pdev = platform_device_alloc("leds-gpio", id);
|
||||
pdev = platform_device_alloc("gpio-leds", id);
|
||||
if (!pdev)
|
||||
goto err_free_leds;
|
||||
|
|
@ -1,10 +1,11 @@
|
|||
#include <linux/init.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/i2c-gpio.h>
|
||||
#include "../machtypes.h"
|
||||
|
||||
#include <dev-gpio-leds.h>
|
||||
|
||||
#include "../machtypes.h"
|
||||
#include "devices.h"
|
||||
#include "dev-leds-gpio.h"
|
||||
|
||||
#define BOARD_95C3AM1_GPIO_LED_0 10
|
||||
#define BOARD_95C3AM1_GPIO_LED_1 11
|
||||
|
@ -47,7 +48,7 @@ static struct spi_board_info board_95C3AM1_flash_data __initdata = {
|
|||
.platform_data = &board_95C3AM1_flash_platform_data
|
||||
};
|
||||
|
||||
static struct gpio_led board_95C3AM1_leds_gpio[] __initdata = {
|
||||
static struct gpio_led board_95C3AM1_gpio_leds[] __initdata = {
|
||||
{
|
||||
.name = "power",
|
||||
.gpio = BOARD_95C3AM1_GPIO_LED_0,
|
||||
|
@ -85,8 +86,8 @@ 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_leds_gpio(-1, ARRAY_SIZE(board_95C3AM1_leds_gpio),
|
||||
board_95C3AM1_leds_gpio);
|
||||
ltq_add_device_gpio_leds(-1, ARRAY_SIZE(board_95C3AM1_gpio_leds),
|
||||
board_95C3AM1_gpio_leds);
|
||||
}
|
||||
|
||||
MIPS_MACHINE(LANTIQ_MACH_95C3AM1,
|
|
@ -10,9 +10,10 @@
|
|||
#include <linux/spi/spi.h>
|
||||
#include <linux/spi/flash.h>
|
||||
|
||||
#include <dev-gpio-leds.h>
|
||||
|
||||
#include "../machtypes.h"
|
||||
#include "devices.h"
|
||||
#include "dev-leds-gpio.h"
|
||||
|
||||
#define EASY98020_GPIO_LED_0 9
|
||||
#define EASY98020_GPIO_LED_1 10
|
||||
|
@ -59,7 +60,7 @@ static struct spi_board_info easy98020_spi_flash_data __initdata = {
|
|||
.platform_data = &easy98020_spi_flash_platform_data
|
||||
};
|
||||
|
||||
static struct gpio_led easy98020_leds_gpio[] __initdata = {
|
||||
static struct gpio_led easy98020_gpio_leds[] __initdata = {
|
||||
{
|
||||
.name = "easy98020:green:0",
|
||||
.gpio = EASY98020_GPIO_LED_0,
|
||||
|
@ -99,8 +100,8 @@ static void __init easy98020_init(void)
|
|||
{
|
||||
falcon_register_i2c();
|
||||
falcon_register_spi_flash(&easy98020_spi_flash_data);
|
||||
ltq_add_device_leds_gpio(-1, ARRAY_SIZE(easy98020_leds_gpio),
|
||||
easy98020_leds_gpio);
|
||||
ltq_add_device_gpio_leds(-1, ARRAY_SIZE(easy98020_gpio_leds),
|
||||
easy98020_gpio_leds);
|
||||
}
|
||||
|
||||
MIPS_MACHINE(LANTIQ_MACH_EASY98020,
|
|
@ -21,9 +21,9 @@
|
|||
|
||||
#include <lantiq_soc.h>
|
||||
#include <lantiq_platform.h>
|
||||
#include <dev-gpio-leds.h>
|
||||
|
||||
#include "../machtypes.h"
|
||||
#include "../dev-leds-gpio.h"
|
||||
#include "devices.h"
|
||||
#include "dev-dwc_otg.h"
|
||||
|
||||
|
@ -75,6 +75,30 @@ static struct mtd_partition arv45xx_partitions[] =
|
|||
},
|
||||
};
|
||||
|
||||
static struct mtd_partition arv7525_partitions[] =
|
||||
{
|
||||
{
|
||||
.name = "uboot",
|
||||
.offset = 0x0,
|
||||
.size = 0x10000,
|
||||
},
|
||||
{
|
||||
.name = "uboot_env",
|
||||
.offset = 0x10000,
|
||||
.size = 0x10000,
|
||||
},
|
||||
{
|
||||
.name = "linux",
|
||||
.offset = 0x20000,
|
||||
.size = 0x3d0000,
|
||||
},
|
||||
{
|
||||
.name = "board_config",
|
||||
.offset = 0x3f0000,
|
||||
.size = 0x10000,
|
||||
},
|
||||
};
|
||||
|
||||
static struct mtd_partition arv75xx_partitions[] =
|
||||
{
|
||||
{
|
||||
|
@ -109,6 +133,11 @@ static struct physmap_flash_data arv45xx_flash_data = {
|
|||
.parts = arv45xx_partitions,
|
||||
};
|
||||
|
||||
static struct physmap_flash_data arv7525_flash_data = {
|
||||
.nr_parts = ARRAY_SIZE(arv7525_partitions),
|
||||
.parts = arv7525_partitions,
|
||||
};
|
||||
|
||||
static struct physmap_flash_data arv75xx_flash_data = {
|
||||
.nr_parts = ARRAY_SIZE(arv75xx_partitions),
|
||||
.parts = arv75xx_partitions,
|
||||
|
@ -127,12 +156,12 @@ static struct ltq_eth_data ltq_eth_data = {
|
|||
};
|
||||
|
||||
static struct gpio_led
|
||||
arv4510pw_leds_gpio[] __initdata = {
|
||||
arv4510pw_gpio_leds[] __initdata = {
|
||||
{ .name = "soc:green:foo", .gpio = 4, .active_low = 1, },
|
||||
};
|
||||
|
||||
static struct gpio_led
|
||||
arv4518pw_leds_gpio[] __initdata = {
|
||||
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" },
|
||||
|
@ -154,7 +183,7 @@ arv4518pw_gpio_buttons[] __initdata = {
|
|||
};
|
||||
|
||||
static struct gpio_led
|
||||
arv4520pw_leds_gpio[] __initdata = {
|
||||
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, },
|
||||
|
@ -171,7 +200,7 @@ arv4520pw_leds_gpio[] __initdata = {
|
|||
};
|
||||
|
||||
static struct gpio_led
|
||||
arv452cpw_leds_gpio[] __initdata = {
|
||||
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" },
|
||||
|
@ -190,7 +219,7 @@ arv452cpw_leds_gpio[] __initdata = {
|
|||
};
|
||||
|
||||
static struct gpio_led
|
||||
arv4525pw_leds_gpio[] __initdata = {
|
||||
arv4525pw_gpio_leds[] __initdata = {
|
||||
{ .name = "soc:green:festnetz", .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:dsl", .gpio = 6, .active_low = 1, .default_trigger = "default-on" },
|
||||
|
@ -199,7 +228,7 @@ arv4525pw_leds_gpio[] __initdata = {
|
|||
};
|
||||
|
||||
static struct gpio_led
|
||||
arv752dpw22_leds_gpio[] __initdata = {
|
||||
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" },
|
||||
|
@ -225,7 +254,7 @@ arv752dpw22_gpio_buttons[] __initdata = {
|
|||
};
|
||||
|
||||
static struct gpio_led
|
||||
arv7518pw_leds_gpio[] __initdata = {
|
||||
arv7518pw_gpio_leds[] __initdata = {
|
||||
{ .name = "soc:green:power", .gpio = 2, .active_low = 1, },
|
||||
{ .name = "soc:green:adsl", .gpio = 4, .active_low = 1, },
|
||||
{ .name = "soc:green:internet", .gpio = 5, .active_low = 1, },
|
||||
|
@ -312,7 +341,7 @@ static void __init
|
|||
arv3527p_init(void)
|
||||
{
|
||||
ltq_register_gpio_stp();
|
||||
//ltq_add_device_leds_gpio(arv3527p_leds_gpio, ARRAY_SIZE(arv3527p_leds_gpio));
|
||||
//ltq_add_device_gpio_leds(arv3527p_gpio_leds, ARRAY_SIZE(arv3527p_gpio_leds));
|
||||
ltq_register_nor(&arv45xx_flash_data);
|
||||
arv45xx_register_ethernet();
|
||||
}
|
||||
|
@ -326,7 +355,7 @@ static void __init
|
|||
arv4510pw_init(void)
|
||||
{
|
||||
ltq_register_gpio_stp();
|
||||
ltq_add_device_leds_gpio(-1, ARRAY_SIZE(arv4510pw_leds_gpio), arv4510pw_leds_gpio);
|
||||
ltq_add_device_gpio_leds(-1, ARRAY_SIZE(arv4510pw_gpio_leds), arv4510pw_gpio_leds);
|
||||
ltq_register_nor(&arv4510_flash_data);
|
||||
ltq_pci_data.irq[12] = (INT_NUM_IM2_IRL0 + 31);
|
||||
ltq_pci_data.irq[15] = (INT_NUM_IM0_IRL0 + 26);
|
||||
|
@ -346,14 +375,15 @@ arv4518pw_init(void)
|
|||
#define ARV4518PW_EBU 0
|
||||
#define ARV4518PW_USB 14
|
||||
#define ARV4518PW_SWITCH_RESET 13
|
||||
#define ARV4518PW_MADWIFI_ADDR 0xb07f0400
|
||||
|
||||
ltq_register_gpio_ebu(ARV4518PW_EBU);
|
||||
ltq_add_device_leds_gpio(-1, ARRAY_SIZE(arv4518pw_leds_gpio), arv4518pw_leds_gpio);
|
||||
ltq_add_device_gpio_leds(-1, ARRAY_SIZE(arv4518pw_gpio_leds), arv4518pw_gpio_leds);
|
||||
ltq_register_gpio_buttons(arv4518pw_gpio_buttons, ARRAY_SIZE(arv4518pw_gpio_buttons));
|
||||
ltq_register_nor(&arv45xx_flash_data);
|
||||
ltq_pci_data.gpio = PCI_GNT2 | PCI_REQ2;
|
||||
ltq_register_pci(<q_pci_data);
|
||||
ltq_register_madwifi_eep();
|
||||
ltq_register_madwifi_eep(ARV4518PW_MADWIFI_ADDR);
|
||||
xway_register_dwc(ARV4518PW_USB);
|
||||
arv45xx_register_ethernet();
|
||||
arv45xx_register_ath5k();
|
||||
|
@ -376,7 +406,7 @@ arv4520pw_init(void)
|
|||
#define ARV4520PW_SWITCH_RESET 110
|
||||
|
||||
ltq_register_gpio_ebu(ARV4520PW_EBU);
|
||||
ltq_add_device_leds_gpio(-1, ARRAY_SIZE(arv4520pw_leds_gpio), arv4520pw_leds_gpio);
|
||||
ltq_add_device_gpio_leds(-1, ARRAY_SIZE(arv4520pw_gpio_leds), arv4520pw_gpio_leds);
|
||||
ltq_register_nor(&arv45xx_flash_data);
|
||||
ltq_register_pci(<q_pci_data);
|
||||
ltq_register_tapi();
|
||||
|
@ -400,12 +430,13 @@ arv452Cpw_init(void)
|
|||
#define ARV452CPW_RELAY1 31
|
||||
#define ARV452CPW_RELAY2 107
|
||||
#define ARV452CPW_SWITCH_RESET 110
|
||||
#define ARV452CPW_MADWIFI_ADDR 0xb07f0400
|
||||
|
||||
ltq_register_gpio_ebu(ARV452CPW_EBU);
|
||||
ltq_add_device_leds_gpio(-1, ARRAY_SIZE(arv452cpw_leds_gpio), arv452cpw_leds_gpio);
|
||||
ltq_add_device_gpio_leds(-1, ARRAY_SIZE(arv452cpw_gpio_leds), arv452cpw_gpio_leds);
|
||||
ltq_register_nor(&arv45xx_flash_data);
|
||||
ltq_register_pci(<q_pci_data);
|
||||
ltq_register_madwifi_eep();
|
||||
ltq_register_madwifi_eep(ARV452CPW_MADWIFI_ADDR);
|
||||
xway_register_dwc(ARV452CPW_USB);
|
||||
arv45xx_register_ethernet();
|
||||
arv45xx_register_ath5k();
|
||||
|
@ -428,14 +459,16 @@ MIPS_MACHINE(LANTIQ_MACH_ARV452CPW,
|
|||
"ARV452CPW - Arcor A801",
|
||||
arv452Cpw_init);
|
||||
|
||||
#define ARV4525PW_MADWIFI_ADDR 0xb07f0400
|
||||
|
||||
static void __init
|
||||
arv4525pw_init(void)
|
||||
{
|
||||
ltq_add_device_leds_gpio(-1, ARRAY_SIZE(arv4525pw_leds_gpio), arv4525pw_leds_gpio);
|
||||
ltq_add_device_gpio_leds(-1, ARRAY_SIZE(arv4525pw_gpio_leds), arv4525pw_gpio_leds);
|
||||
ltq_register_nor(&arv45xx_flash_data);
|
||||
ltq_pci_data.clock = PCI_CLOCK_INT;
|
||||
ltq_register_pci(<q_pci_data);
|
||||
ltq_register_madwifi_eep();
|
||||
ltq_register_madwifi_eep(ARV4525PW_MADWIFI_ADDR);
|
||||
ltq_eth_data.mii_mode = PHY_INTERFACE_MODE_MII;
|
||||
arv45xx_register_ethernet();
|
||||
}
|
||||
|
@ -445,6 +478,22 @@ MIPS_MACHINE(LANTIQ_MACH_ARV4525PW,
|
|||
"ARV4525PW - Speedport W502V",
|
||||
arv4525pw_init);
|
||||
|
||||
static void __init
|
||||
arv7525pw_init(void)
|
||||
{
|
||||
ltq_add_device_gpio_leds(-1, ARRAY_SIZE(arv4525pw_gpio_leds), arv4525pw_gpio_leds);
|
||||
ltq_register_nor(&arv7525_flash_data);
|
||||
ltq_pci_data.clock = PCI_CLOCK_INT;
|
||||
ltq_register_pci(<q_pci_data);
|
||||
ltq_eth_data.mii_mode = PHY_INTERFACE_MODE_MII;
|
||||
arv45xx_register_ethernet();
|
||||
}
|
||||
|
||||
MIPS_MACHINE(LANTIQ_MACH_ARV7525PW,
|
||||
"ARV7525PW",
|
||||
"ARV7525PW - Speedport W303V",
|
||||
arv7525pw_init);
|
||||
|
||||
static void __init
|
||||
arv7518pw_init(void)
|
||||
{
|
||||
|
@ -452,7 +501,7 @@ arv7518pw_init(void)
|
|||
#define ARV7518PW_USB 14
|
||||
|
||||
ltq_register_gpio_ebu(ARV7518PW_EBU);
|
||||
ltq_add_device_leds_gpio(-1, ARRAY_SIZE(arv7518pw_leds_gpio), arv7518pw_leds_gpio);
|
||||
ltq_add_device_gpio_leds(-1, ARRAY_SIZE(arv7518pw_gpio_leds), arv7518pw_gpio_leds);
|
||||
ltq_register_gpio_buttons(arv7518pw_gpio_buttons, ARRAY_SIZE(arv7518pw_gpio_buttons));
|
||||
ltq_register_nor(&arv75xx_flash_data);
|
||||
ltq_register_pci(<q_pci_data);
|
||||
|
@ -475,7 +524,7 @@ arv752dpw22_init(void)
|
|||
#define ARV752DPW22_RELAY 101
|
||||
|
||||
ltq_register_gpio_ebu(ARV752DPW22_EBU);
|
||||
ltq_add_device_leds_gpio(-1, ARRAY_SIZE(arv752dpw22_leds_gpio), arv752dpw22_leds_gpio);
|
||||
ltq_add_device_gpio_leds(-1, ARRAY_SIZE(arv752dpw22_gpio_leds), arv752dpw22_gpio_leds);
|
||||
ltq_register_gpio_buttons(arv752dpw22_gpio_buttons, ARRAY_SIZE(arv752dpw22_gpio_buttons));
|
||||
ltq_register_nor(&arv75xx_flash_data);
|
||||
ltq_pci_data.irq[15] = (INT_NUM_IM3_IRL0 + 31);
|
|
@ -0,0 +1,212 @@
|
|||
/*
|
||||
* 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/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 "devices.h"
|
||||
#include "dev-dwc_otg.h"
|
||||
|
||||
#define UBOOT_ENV_OFFSET 0x010000
|
||||
#define UBOOT_ENV_SIZE 0x010000
|
||||
|
||||
static struct mtd_partition gigasx76x_partitions[] =
|
||||
{
|
||||
{
|
||||
.name = "uboot",
|
||||
.offset = 0x000000,
|
||||
.size = 0x010000,
|
||||
},
|
||||
{
|
||||
.name = "uboot_env",
|
||||
.offset = UBOOT_ENV_OFFSET,
|
||||
.size = UBOOT_ENV_SIZE,
|
||||
},
|
||||
{
|
||||
.name = "linux",
|
||||
.offset = 0x020000,
|
||||
.size = 0x7d0000,
|
||||
},
|
||||
{
|
||||
.name = "board_config",
|
||||
.offset = 0x7f0000,
|
||||
.size = 0x010000,
|
||||
},
|
||||
};
|
||||
|
||||
static struct gpio_led
|
||||
gigasx76x_gpio_leds[] __initdata = {
|
||||
{ .name = "soc:green:usb", .gpio = 202, },
|
||||
{ .name = "soc:green:wlan", .gpio = 203, },
|
||||
{ .name = "soc:green:phone2", .gpio = 204, },
|
||||
{ .name = "soc:green:phone1", .gpio = 205, },
|
||||
{ .name = "soc:green:line", .gpio = 206, },
|
||||
{ .name = "soc:green:online", .gpio = 207, },
|
||||
{ .name = "soc:green:voip", .gpio = 208, },
|
||||
};
|
||||
|
||||
static struct gpio_keys_button
|
||||
gigasx76x_gpio_keys[] __initdata = {
|
||||
{
|
||||
.desc = "restart",
|
||||
.type = EV_KEY,
|
||||
.code = KEY_RESTART,
|
||||
.debounce_interval = LTQ_KEYS_DEBOUNCE_INTERVAL,
|
||||
.gpio = 14,
|
||||
.active_low = 1,
|
||||
},
|
||||
{
|
||||
.desc = "wps",
|
||||
.type = EV_KEY,
|
||||
.code = KEY_WPS_BUTTON,
|
||||
.debounce_interval = LTQ_KEYS_DEBOUNCE_INTERVAL,
|
||||
.gpio = 22,
|
||||
.active_low = 1,
|
||||
},
|
||||
};
|
||||
|
||||
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 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;
|
||||
}
|
||||
|
||||
/*
|
||||
* gigasx76x_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 gigasx76x_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 gigasx76x_parse_hex_byte(const char *b) {
|
||||
int hi;
|
||||
int lo;
|
||||
|
||||
hi = gigasx76x_parse_hex_nibble(b[0]);
|
||||
lo = gigasx76x_parse_hex_nibble(b[1]);
|
||||
|
||||
if (hi < 0 || lo < 0)
|
||||
return -1;
|
||||
|
||||
return (hi << 4) | lo;
|
||||
}
|
||||
|
||||
static int __init gigasx76x_register_ethernet(void) {
|
||||
u_int8_t addr[6];
|
||||
int i;
|
||||
char *uboot_env_page;
|
||||
char *mac;
|
||||
|
||||
uboot_env_page = ioremap(LTQ_FLASH_START + UBOOT_ENV_OFFSET, UBOOT_ENV_SIZE);
|
||||
if (!uboot_env_page)
|
||||
return -ENOMEM;
|
||||
|
||||
mac = get_uboot_env_var(uboot_env_page, UBOOT_ENV_SIZE, "\0ethaddr=", 9);
|
||||
|
||||
if (!mac) {
|
||||
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 = gigasx76x_parse_hex_byte(mac + (i * 3));
|
||||
if (byte < 0) {
|
||||
goto error_fail;
|
||||
}
|
||||
addr[i] = byte;
|
||||
}
|
||||
|
||||
iounmap(uboot_env_page);
|
||||
printk("GIGASX76X: Found ethernet MAC address: ");
|
||||
for (i = 0; i < 6; i++)
|
||||
printk("%.2x%s", addr[i], (i < 5) ? ":" : ".\n");
|
||||
|
||||
memcpy(<q_eth_data.mac.sa_data, addr, 6);
|
||||
ltq_register_etop(<q_eth_data);
|
||||
|
||||
return 0;
|
||||
|
||||
error_fail:
|
||||
iounmap(uboot_env_page);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static void __init gigasx76x_init(void) {
|
||||
#define GIGASX76X_USB 29
|
||||
#define GIGASX76X_MADWIFI_ADDR 0xb07f0000
|
||||
|
||||
ltq_register_gpio_stp();
|
||||
ltq_register_nor(&gigasx76x_flash_data);
|
||||
ltq_register_pci(<q_pci_data);
|
||||
gigasx76x_register_ethernet();
|
||||
xway_register_dwc(GIGASX76X_USB);
|
||||
ltq_register_tapi();
|
||||
ltq_register_madwifi_eep(GIGASX76X_MADWIFI_ADDR);
|
||||
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);
|
||||
}
|
||||
|
||||
MIPS_MACHINE(LANTIQ_MACH_GIGASX76X, "GIGASX76X", "GIGASX76X - Gigaset SX761,SX762,SX763", gigasx76x_init);
|
|
@ -18,10 +18,10 @@
|
|||
|
||||
#include <lantiq_soc.h>
|
||||
#include <irq.h>
|
||||
#include <dev-gpio-leds.h>
|
||||
#include <dev-gpio-buttons.h>
|
||||
|
||||
#include "../machtypes.h"
|
||||
#include "../dev-leds-gpio.h"
|
||||
#include "../dev-gpio-buttons.h"
|
||||
#include "devices.h"
|
||||
#include "dev-dwc_otg.h"
|
||||
|
||||
|
@ -55,7 +55,7 @@ static struct physmap_flash_data wbmr_flash_data = {
|
|||
};
|
||||
|
||||
static struct gpio_led
|
||||
wbmr_leds_gpio[] __initdata = {
|
||||
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, },
|
||||
|
@ -104,7 +104,7 @@ wbmr_init(void)
|
|||
{
|
||||
#define WMBR_BRN_MAC 0x1fd0024
|
||||
|
||||
ltq_add_device_leds_gpio(-1, ARRAY_SIZE(wbmr_leds_gpio), wbmr_leds_gpio);
|
||||
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(<q_pci_data);
|
|
@ -1,894 +0,0 @@
|
|||
From 9e0235e97ea2617beaacaa16ab5f0b9e75f4680e Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Wed, 30 Mar 2011 09:27:47 +0200
|
||||
Subject: [PATCH 01/13] MIPS: Lantiq: Add initial support for Lantiq SoCs
|
||||
|
||||
Add initial support for Mips based SoCs made by Lantiq. This series will add
|
||||
support for the XWAY family.
|
||||
|
||||
The series allows booting a minimal system using a initramfs or NOR. Missing
|
||||
drivers and support for Amazon and GPON family will be provided in a later
|
||||
series.
|
||||
|
||||
[Ralf: Remove some cargo cult programming and fixed formatting.]
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
Signed-off-by: Ralph Hempel <ralph.hempel@lantiq.com>
|
||||
Signed-off-by: David Daney <ddaney@caviumnetworks.com>
|
||||
Cc: linux-mips@linux-mips.org
|
||||
Patchwork: https://patchwork.linux-mips.org/patch/2252/
|
||||
Patchwork: https://patchwork.linux-mips.org/patch/2371/
|
||||
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
|
||||
---
|
||||
arch/mips/Kbuild.platforms | 1 +
|
||||
arch/mips/Kconfig | 17 ++
|
||||
arch/mips/include/asm/mach-lantiq/lantiq.h | 63 ++++++
|
||||
arch/mips/include/asm/mach-lantiq/war.h | 24 ++
|
||||
arch/mips/lantiq/Makefile | 9 +
|
||||
arch/mips/lantiq/Platform | 7 +
|
||||
arch/mips/lantiq/clk.c | 140 ++++++++++++
|
||||
arch/mips/lantiq/clk.h | 18 ++
|
||||
arch/mips/lantiq/early_printk.c | 33 +++
|
||||
arch/mips/lantiq/irq.c | 326 ++++++++++++++++++++++++++++
|
||||
arch/mips/lantiq/prom.c | 71 ++++++
|
||||
arch/mips/lantiq/prom.h | 24 ++
|
||||
arch/mips/lantiq/setup.c | 41 ++++
|
||||
13 files changed, 774 insertions(+), 0 deletions(-)
|
||||
create mode 100644 arch/mips/include/asm/mach-lantiq/lantiq.h
|
||||
create mode 100644 arch/mips/include/asm/mach-lantiq/war.h
|
||||
create mode 100644 arch/mips/lantiq/Makefile
|
||||
create mode 100644 arch/mips/lantiq/Platform
|
||||
create mode 100644 arch/mips/lantiq/clk.c
|
||||
create mode 100644 arch/mips/lantiq/clk.h
|
||||
create mode 100644 arch/mips/lantiq/early_printk.c
|
||||
create mode 100644 arch/mips/lantiq/irq.c
|
||||
create mode 100644 arch/mips/lantiq/prom.c
|
||||
create mode 100644 arch/mips/lantiq/prom.h
|
||||
create mode 100644 arch/mips/lantiq/setup.c
|
||||
|
||||
--- a/arch/mips/Kconfig
|
||||
+++ b/arch/mips/Kconfig
|
||||
@@ -212,6 +212,23 @@ config MACH_JZ4740
|
||||
select HAVE_PWM
|
||||
select HAVE_CLK
|
||||
|
||||
+config LANTIQ
|
||||
+ bool "Lantiq based platforms"
|
||||
+ select DMA_NONCOHERENT
|
||||
+ select IRQ_CPU
|
||||
+ select CEVT_R4K
|
||||
+ select CSRC_R4K
|
||||
+ select SYS_HAS_CPU_MIPS32_R1
|
||||
+ select SYS_HAS_CPU_MIPS32_R2
|
||||
+ select SYS_SUPPORTS_BIG_ENDIAN
|
||||
+ select SYS_SUPPORTS_32BIT_KERNEL
|
||||
+ select SYS_SUPPORTS_MULTITHREADING
|
||||
+ select SYS_HAS_EARLY_PRINTK
|
||||
+ select ARCH_REQUIRE_GPIOLIB
|
||||
+ select SWAP_IO_SPACE
|
||||
+ select BOOT_RAW
|
||||
+ select HAVE_CLK
|
||||
+
|
||||
config LASAT
|
||||
bool "LASAT Networks platforms"
|
||||
select CEVT_R4K
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/include/asm/mach-lantiq/lantiq.h
|
||||
@@ -0,0 +1,63 @@
|
||||
+/*
|
||||
+ * 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>
|
||||
+ */
|
||||
+#ifndef _LANTIQ_H__
|
||||
+#define _LANTIQ_H__
|
||||
+
|
||||
+#include <linux/irq.h>
|
||||
+
|
||||
+/* generic reg access functions */
|
||||
+#define ltq_r32(reg) __raw_readl(reg)
|
||||
+#define ltq_w32(val, reg) __raw_writel(val, reg)
|
||||
+#define ltq_w32_mask(clear, set, reg) \
|
||||
+ ltq_w32((ltq_r32(reg) & ~(clear)) | (set), reg)
|
||||
+#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);
|
||||
+
|
||||
+/* clock speeds */
|
||||
+#define CLOCK_60M 60000000
|
||||
+#define CLOCK_83M 83333333
|
||||
+#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;
|
||||
+
|
||||
+/* some irq helpers */
|
||||
+extern void ltq_disable_irq(struct irq_data *d);
|
||||
+extern void ltq_mask_and_ack_irq(struct irq_data *d);
|
||||
+extern void ltq_enable_irq(struct irq_data *d);
|
||||
+
|
||||
+/* find out what caused the last cpu reset */
|
||||
+extern int ltq_reset_cause(void);
|
||||
+#define LTQ_RST_CAUSE_WDTRST 0x20
|
||||
+
|
||||
+#define IOPORT_RESOURCE_START 0x10000000
|
||||
+#define IOPORT_RESOURCE_END 0xffffffff
|
||||
+#define IOMEM_RESOURCE_START 0x10000000
|
||||
+#define IOMEM_RESOURCE_END 0xffffffff
|
||||
+#define LTQ_FLASH_START 0x10000000
|
||||
+#define LTQ_FLASH_MAX 0x04000000
|
||||
+
|
||||
+#endif
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/include/asm/mach-lantiq/war.h
|
||||
@@ -0,0 +1,24 @@
|
||||
+/*
|
||||
+ * This file is subject to the terms and conditions of the GNU General Public
|
||||
+ * License. See the file "COPYING" in the main directory of this archive
|
||||
+ * for more details.
|
||||
+ *
|
||||
+ */
|
||||
+#ifndef __ASM_MIPS_MACH_LANTIQ_WAR_H
|
||||
+#define __ASM_MIPS_MACH_LANTIQ_WAR_H
|
||||
+
|
||||
+#define R4600_V1_INDEX_ICACHEOP_WAR 0
|
||||
+#define R4600_V1_HIT_CACHEOP_WAR 0
|
||||
+#define R4600_V2_HIT_CACHEOP_WAR 0
|
||||
+#define R5432_CP0_INTERRUPT_WAR 0
|
||||
+#define BCM1250_M3_WAR 0
|
||||
+#define SIBYTE_1956_WAR 0
|
||||
+#define MIPS4K_ICACHE_REFILL_WAR 0
|
||||
+#define MIPS_CACHE_SYNC_WAR 0
|
||||
+#define TX49XX_ICACHE_INDEX_INV_WAR 0
|
||||
+#define RM9000_CDEX_SMP_WAR 0
|
||||
+#define ICACHE_REFILLS_WORKAROUND_WAR 0
|
||||
+#define R10000_LLSC_WAR 0
|
||||
+#define MIPS34K_MISSED_ITLB_WAR 0
|
||||
+
|
||||
+#endif
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/lantiq/Makefile
|
||||
@@ -0,0 +1,9 @@
|
||||
+# Copyright (C) 2010 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.
|
||||
+
|
||||
+obj-y := irq.o setup.o clk.o prom.o
|
||||
+
|
||||
+obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/lantiq/Platform
|
||||
@@ -0,0 +1,7 @@
|
||||
+#
|
||||
+# Lantiq
|
||||
+#
|
||||
+
|
||||
+platform-$(CONFIG_LANTIQ) += lantiq/
|
||||
+cflags-$(CONFIG_LANTIQ) += -I$(srctree)/arch/mips/include/asm/mach-lantiq
|
||||
+load-$(CONFIG_LANTIQ) = 0xffffffff80002000
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/lantiq/clk.c
|
||||
@@ -0,0 +1,144 @@
|
||||
+/*
|
||||
+ * 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>
|
||||
+ * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
|
||||
+ */
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/types.h>
|
||||
+#include <linux/clk.h>
|
||||
+#include <linux/err.h>
|
||||
+#include <linux/list.h>
|
||||
+
|
||||
+#include <asm/time.h>
|
||||
+#include <asm/irq.h>
|
||||
+#include <asm/div64.h>
|
||||
+
|
||||
+#include <lantiq_soc.h>
|
||||
+
|
||||
+#include "clk.h"
|
||||
+
|
||||
+struct clk {
|
||||
+ const char *name;
|
||||
+ unsigned long rate;
|
||||
+ unsigned long (*get_rate) (void);
|
||||
+};
|
||||
+
|
||||
+static struct clk *cpu_clk;
|
||||
+static int cpu_clk_cnt;
|
||||
+
|
||||
+/* 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,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+#ifdef CONFIG_SOC_TYPE_XWAY
|
||||
+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;
|
||||
+#endif
|
||||
+
|
||||
+void clk_init(void)
|
||||
+{
|
||||
+ cpu_clk = cpu_clk_generic;
|
||||
+ cpu_clk_cnt = ARRAY_SIZE(cpu_clk_generic);
|
||||
+}
|
||||
+
|
||||
+static inline int clk_good(struct clk *clk)
|
||||
+{
|
||||
+ return clk && !IS_ERR(clk);
|
||||
+}
|
||||
+
|
||||
+unsigned long clk_get_rate(struct clk *clk)
|
||||
+{
|
||||
+ if (unlikely(!clk_good(clk)))
|
||||
+ return 0;
|
||||
+
|
||||
+ if (clk->rate != 0)
|
||||
+ return clk->rate;
|
||||
+
|
||||
+ if (clk->get_rate != NULL)
|
||||
+ return clk->get_rate();
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+EXPORT_SYMBOL(clk_get_rate);
|
||||
+
|
||||
+struct clk *clk_get(struct device *dev, const char *id)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < cpu_clk_cnt; i++)
|
||||
+ if (!strcmp(id, cpu_clk[i].name))
|
||||
+ return &cpu_clk[i];
|
||||
+ BUG();
|
||||
+ return ERR_PTR(-ENOENT);
|
||||
+}
|
||||
+EXPORT_SYMBOL(clk_get);
|
||||
+
|
||||
+void clk_put(struct clk *clk)
|
||||
+{
|
||||
+ /* not used */
|
||||
+}
|
||||
+EXPORT_SYMBOL(clk_put);
|
||||
+
|
||||
+static inline u32 ltq_get_counter_resolution(void)
|
||||
+{
|
||||
+ u32 res;
|
||||
+
|
||||
+ __asm__ __volatile__(
|
||||
+ ".set push\n"
|
||||
+ ".set mips32r2\n"
|
||||
+ "rdhwr %0, $3\n"
|
||||
+ ".set pop\n"
|
||||
+ : "=&r" (res)
|
||||
+ : /* no input */
|
||||
+ : "memory");
|
||||
+
|
||||
+ return res;
|
||||
+}
|
||||
+
|
||||
+void __init plat_time_init(void)
|
||||
+{
|
||||
+ struct clk *clk;
|
||||
+
|
||||
+#ifdef CONFIG_SOC_TYPE_XWAY
|
||||
+ if (insert_resource(&iomem_resource, <q_cgu_resource) < 0)
|
||||
+ panic("Failed to insert cgu memory\n");
|
||||
+
|
||||
+ if (request_mem_region(ltq_cgu_resource.start,
|
||||
+ resource_size(<q_cgu_resource), "cgu") < 0)
|
||||
+ panic("Failed to request cgu memory\n");
|
||||
+
|
||||
+ ltq_cgu_membase = ioremap_nocache(ltq_cgu_resource.start,
|
||||
+ resource_size(<q_cgu_resource));
|
||||
+ if (!ltq_cgu_membase) {
|
||||
+ pr_err("Failed to remap cgu memory\n");
|
||||
+ unreachable();
|
||||
+ }
|
||||
+#endif
|
||||
+ clk = clk_get(0, "cpu");
|
||||
+ mips_hpt_frequency = clk_get_rate(clk) / ltq_get_counter_resolution();
|
||||
+ write_c0_compare(read_c0_count());
|
||||
+ clk_put(clk);
|
||||
+}
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/lantiq/clk.h
|
||||
@@ -0,0 +1,18 @@
|
||||
+/*
|
||||
+ * 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>
|
||||
+ */
|
||||
+
|
||||
+#ifndef _LTQ_CLK_H__
|
||||
+#define _LTQ_CLK_H__
|
||||
+
|
||||
+extern void clk_init(void);
|
||||
+
|
||||
+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);
|
||||
+
|
||||
+#endif
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/lantiq/early_printk.c
|
||||
@@ -0,0 +1,37 @@
|
||||
+/*
|
||||
+ * 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/cpu.h>
|
||||
+
|
||||
+#include <lantiq.h>
|
||||
+#include <lantiq_soc.h>
|
||||
+
|
||||
+/* no ioremap possible at this early stage, lets use KSEG1 instead */
|
||||
+#ifdef CONFIG_SOC_FALCON
|
||||
+#define LTQ_ASC_BASE KSEG1ADDR(LTQ_ASC0_BASE_ADDR)
|
||||
+#else
|
||||
+#define LTQ_ASC_BASE KSEG1ADDR(LTQ_ASC1_BASE_ADDR)
|
||||
+#endif
|
||||
+#define ASC_BUF 1024
|
||||
+#define LTQ_ASC_FSTAT ((u32 *)(LTQ_ASC_BASE + 0x0048))
|
||||
+#define LTQ_ASC_TBUF ((u32 *)(LTQ_ASC_BASE + 0x0020))
|
||||
+#define TXMASK 0x3F00
|
||||
+#define TXOFFSET 8
|
||||
+
|
||||
+void prom_putchar(char c)
|
||||
+{
|
||||
+ unsigned long flags;
|
||||
+
|
||||
+ 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);
|
||||
+ local_irq_restore(flags);
|
||||
+}
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/lantiq/irq.c
|
||||
@@ -0,0 +1,339 @@
|
||||
+/*
|
||||
+ * 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>
|
||||
+ * Copyright (C) 2010 Thomas Langer <thomas.langer@lantiq.com>
|
||||
+ */
|
||||
+
|
||||
+#include <linux/interrupt.h>
|
||||
+#include <linux/ioport.h>
|
||||
+#include <linux/module.h>
|
||||
+
|
||||
+#include <asm/bootinfo.h>
|
||||
+#include <asm/irq_cpu.h>
|
||||
+
|
||||
+#include <lantiq_soc.h>
|
||||
+#include <irq.h>
|
||||
+
|
||||
+/* register definitions */
|
||||
+#define LTQ_ICU_IM0_ISR 0x0000
|
||||
+#define LTQ_ICU_IM0_IER 0x0008
|
||||
+#define LTQ_ICU_IM0_IOSR 0x0010
|
||||
+#define LTQ_ICU_IM0_IRSR 0x0018
|
||||
+#define LTQ_ICU_IM0_IMR 0x0020
|
||||
+#define LTQ_ICU_IM1_ISR 0x0028
|
||||
+#define LTQ_ICU_OFFSET (LTQ_ICU_IM1_ISR - LTQ_ICU_IM0_ISR)
|
||||
+
|
||||
+#ifdef CONFIG_SOC_TYPE_XWAY
|
||||
+
|
||||
+#define LTQ_EIU_EXIN_C 0x0000
|
||||
+#define LTQ_EIU_EXIN_INIC 0x0004
|
||||
+#define LTQ_EIU_EXIN_INEN 0x000C
|
||||
+
|
||||
+/* irq numbers used by the external interrupt unit (EIU) */
|
||||
+#define LTQ_EIU_IR0 (INT_NUM_IM4_IRL0 + 30)
|
||||
+#define LTQ_EIU_IR1 (INT_NUM_IM3_IRL0 + 31)
|
||||
+#define LTQ_EIU_IR2 (INT_NUM_IM1_IRL0 + 26)
|
||||
+#define LTQ_EIU_IR3 INT_NUM_IM1_IRL0
|
||||
+#define LTQ_EIU_IR4 (INT_NUM_IM1_IRL0 + 1)
|
||||
+#define LTQ_EIU_IR5 (INT_NUM_IM1_IRL0 + 2)
|
||||
+#define LTQ_EIU_IR6 (INT_NUM_IM2_IRL0 + 30)
|
||||
+
|
||||
+#define MAX_EIU 6
|
||||
+
|
||||
+/* irqs generated by device attached to the EBU need to be acked in
|
||||
+ * a special manner
|
||||
+ */
|
||||
+#define LTQ_ICU_EBU_IRQ 22
|
||||
+
|
||||
+#define ltq_eiu_w32(x, y) ltq_w32((x), ltq_eiu_membase + (y))
|
||||
+#define ltq_eiu_r32(x) ltq_r32(ltq_eiu_membase + (x))
|
||||
+
|
||||
+static unsigned short ltq_eiu_irq[MAX_EIU] = {
|
||||
+ LTQ_EIU_IR0,
|
||||
+ LTQ_EIU_IR1,
|
||||
+ LTQ_EIU_IR2,
|
||||
+ LTQ_EIU_IR3,
|
||||
+ LTQ_EIU_IR4,
|
||||
+ LTQ_EIU_IR5,
|
||||
+};
|
||||
+
|
||||
+static void __iomem *ltq_eiu_membase;
|
||||
+
|
||||
+static struct resource ltq_eiu_resource = {
|
||||
+ .name = "eiu",
|
||||
+ .start = LTQ_EIU_BASE_ADDR,
|
||||
+ .end = LTQ_EIU_BASE_ADDR + LTQ_ICU_SIZE - 1,
|
||||
+ .flags = IORESOURCE_MEM,
|
||||
+};
|
||||
+
|
||||
+#endif
|
||||
+
|
||||
+static struct resource ltq_icu_resource = {
|
||||
+ .name = "icu",
|
||||
+ .start = LTQ_ICU_BASE_ADDR,
|
||||
+ .end = LTQ_ICU_BASE_ADDR + LTQ_ICU_SIZE - 1,
|
||||
+ .flags = IORESOURCE_MEM,
|
||||
+};
|
||||
+
|
||||
+#define ltq_icu_w32(x, y) ltq_w32((x), ltq_icu_membase + (y))
|
||||
+#define ltq_icu_r32(x) ltq_r32(ltq_icu_membase + (x))
|
||||
+
|
||||
+static void __iomem *ltq_icu_membase;
|
||||
+
|
||||
+
|
||||
+void ltq_disable_irq(struct irq_data *d)
|
||||
+{
|
||||
+ u32 ier = LTQ_ICU_IM0_IER;
|
||||
+ int irq_nr = d->irq - INT_NUM_IRQ0;
|
||||
+
|
||||
+ ier += LTQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET);
|
||||
+ irq_nr %= INT_NUM_IM_OFFSET;
|
||||
+ ltq_icu_w32(ltq_icu_r32(ier) & ~(1 << irq_nr), ier);
|
||||
+}
|
||||
+
|
||||
+void ltq_mask_and_ack_irq(struct irq_data *d)
|
||||
+{
|
||||
+ u32 ier = LTQ_ICU_IM0_IER;
|
||||
+ u32 isr = LTQ_ICU_IM0_ISR;
|
||||
+ int irq_nr = d->irq - INT_NUM_IRQ0;
|
||||
+
|
||||
+ ier += LTQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET);
|
||||
+ isr += LTQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET);
|
||||
+ irq_nr %= INT_NUM_IM_OFFSET;
|
||||
+ ltq_icu_w32(ltq_icu_r32(ier) & ~(1 << irq_nr), ier);
|
||||
+ ltq_icu_w32((1 << irq_nr), isr);
|
||||
+}
|
||||
+EXPORT_SYMBOL(ltq_mask_and_ack_irq);
|
||||
+
|
||||
+static void ltq_ack_irq(struct irq_data *d)
|
||||
+{
|
||||
+ u32 isr = LTQ_ICU_IM0_ISR;
|
||||
+ int irq_nr = d->irq - INT_NUM_IRQ0;
|
||||
+
|
||||
+ isr += LTQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET);
|
||||
+ irq_nr %= INT_NUM_IM_OFFSET;
|
||||
+ ltq_icu_w32((1 << irq_nr), isr);
|
||||
+}
|
||||
+
|
||||
+void ltq_enable_irq(struct irq_data *d)
|
||||
+{
|
||||
+ u32 ier = LTQ_ICU_IM0_IER;
|
||||
+ int irq_nr = d->irq - INT_NUM_IRQ0;
|
||||
+
|
||||
+ ier += LTQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET);
|
||||
+ irq_nr %= INT_NUM_IM_OFFSET;
|
||||
+ ltq_icu_w32(ltq_icu_r32(ier) | (1 << irq_nr), ier);
|
||||
+}
|
||||
+
|
||||
+#ifdef CONFIG_SOC_TYPE_XWAY
|
||||
+static unsigned int ltq_startup_eiu_irq(struct irq_data *d)
|
||||
+{
|
||||
+ int i;
|
||||
+ int irq_nr = d->irq - INT_NUM_IRQ0;
|
||||
+
|
||||
+ ltq_enable_irq(d);
|
||||
+ for (i = 0; i < MAX_EIU; i++) {
|
||||
+ if (irq_nr == ltq_eiu_irq[i]) {
|
||||
+ /* low level - we should really handle set_type */
|
||||
+ ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_C) |
|
||||
+ (0x6 << (i * 4)), LTQ_EIU_EXIN_C);
|
||||
+ /* clear all pending */
|
||||
+ ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INIC) & ~(1 << i),
|
||||
+ LTQ_EIU_EXIN_INIC);
|
||||
+ /* enable */
|
||||
+ ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INEN) | (1 << i),
|
||||
+ LTQ_EIU_EXIN_INEN);
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void ltq_shutdown_eiu_irq(struct irq_data *d)
|
||||
+{
|
||||
+ int i;
|
||||
+ int irq_nr = d->irq - INT_NUM_IRQ0;
|
||||
+
|
||||
+ ltq_disable_irq(d);
|
||||
+ for (i = 0; i < MAX_EIU; i++) {
|
||||
+ if (irq_nr == ltq_eiu_irq[i]) {
|
||||
+ /* disable */
|
||||
+ ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INEN) & ~(1 << i),
|
||||
+ LTQ_EIU_EXIN_INEN);
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
+static struct irq_chip ltq_irq_type = {
|
||||
+ "icu",
|
||||
+ .irq_enable = ltq_enable_irq,
|
||||
+ .irq_disable = ltq_disable_irq,
|
||||
+ .irq_unmask = ltq_enable_irq,
|
||||
+ .irq_ack = ltq_ack_irq,
|
||||
+ .irq_mask = ltq_disable_irq,
|
||||
+ .irq_mask_ack = ltq_mask_and_ack_irq,
|
||||
+};
|
||||
+
|
||||
+#ifdef CONFIG_SOC_TYPE_XWAY
|
||||
+static struct irq_chip ltq_eiu_type = {
|
||||
+ "eiu",
|
||||
+ .irq_startup = ltq_startup_eiu_irq,
|
||||
+ .irq_shutdown = ltq_shutdown_eiu_irq,
|
||||
+ .irq_enable = ltq_enable_irq,
|
||||
+ .irq_disable = ltq_disable_irq,
|
||||
+ .irq_unmask = ltq_enable_irq,
|
||||
+ .irq_ack = ltq_ack_irq,
|
||||
+ .irq_mask = ltq_disable_irq,
|
||||
+ .irq_mask_ack = ltq_mask_and_ack_irq,
|
||||
+};
|
||||
+#endif
|
||||
+
|
||||
+static void ltq_hw_irqdispatch(int module)
|
||||
+{
|
||||
+ u32 irq;
|
||||
+
|
||||
+ irq = ltq_icu_r32(LTQ_ICU_IM0_IOSR + (module * LTQ_ICU_OFFSET));
|
||||
+ if (irq == 0)
|
||||
+ return;
|
||||
+
|
||||
+ /* silicon bug causes only the msb set to 1 to be valid. all
|
||||
+ * other bits might be bogus
|
||||
+ */
|
||||
+ irq = __fls(irq);
|
||||
+ do_IRQ((int)irq + INT_NUM_IM0_IRL0 + (INT_NUM_IM_OFFSET * module));
|
||||
+
|
||||
+#ifdef CONFIG_SOC_TYPE_XWAY
|
||||
+ /* if this is a EBU irq, we need to ack it or get a deadlock */
|
||||
+ if ((irq == LTQ_ICU_EBU_IRQ) && (module == 0))
|
||||
+ ltq_ebu_w32(ltq_ebu_r32(LTQ_EBU_PCC_ISTAT) | 0x10,
|
||||
+ LTQ_EBU_PCC_ISTAT);
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
+#define DEFINE_HWx_IRQDISPATCH(x) \
|
||||
+ static void ltq_hw ## x ## _irqdispatch(void) \
|
||||
+ { \
|
||||
+ ltq_hw_irqdispatch(x); \
|
||||
+ }
|
||||
+DEFINE_HWx_IRQDISPATCH(0)
|
||||
+DEFINE_HWx_IRQDISPATCH(1)
|
||||
+DEFINE_HWx_IRQDISPATCH(2)
|
||||
+DEFINE_HWx_IRQDISPATCH(3)
|
||||
+DEFINE_HWx_IRQDISPATCH(4)
|
||||
+
|
||||
+static void ltq_hw5_irqdispatch(void)
|
||||
+{
|
||||
+ do_IRQ(MIPS_CPU_TIMER_IRQ);
|
||||
+}
|
||||
+
|
||||
+asmlinkage void plat_irq_dispatch(void)
|
||||
+{
|
||||
+ unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM;
|
||||
+ unsigned int i;
|
||||
+
|
||||
+ if (pending & CAUSEF_IP7) {
|
||||
+ do_IRQ(MIPS_CPU_TIMER_IRQ);
|
||||
+ goto out;
|
||||
+ } else {
|
||||
+ for (i = 0; i < 5; i++) {
|
||||
+ if (pending & (CAUSEF_IP2 << i)) {
|
||||
+ ltq_hw_irqdispatch(i);
|
||||
+ goto out;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ pr_alert("Spurious IRQ: CAUSE=0x%08x\n", read_c0_status());
|
||||
+
|
||||
+out:
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
+static struct irqaction cascade = {
|
||||
+ .handler = no_action,
|
||||
+ .flags = IRQF_DISABLED,
|
||||
+ .name = "cascade",
|
||||
+};
|
||||
+
|
||||
+void __init arch_init_irq(void)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ if (insert_resource(&iomem_resource, <q_icu_resource) < 0)
|
||||
+ panic("Failed to insert icu memory\n");
|
||||
+
|
||||
+ if (request_mem_region(ltq_icu_resource.start,
|
||||
+ resource_size(<q_icu_resource), "icu") < 0)
|
||||
+ panic("Failed to request icu memory\n");
|
||||
+
|
||||
+ ltq_icu_membase = ioremap_nocache(ltq_icu_resource.start,
|
||||
+ resource_size(<q_icu_resource));
|
||||
+ if (!ltq_icu_membase)
|
||||
+ panic("Failed to remap icu memory\n");
|
||||
+
|
||||
+#ifdef CONFIG_SOC_TYPE_XWAY
|
||||
+ if (insert_resource(&iomem_resource, <q_eiu_resource) < 0)
|
||||
+ panic("Failed to insert eiu memory\n");
|
||||
+
|
||||
+ if (request_mem_region(ltq_eiu_resource.start,
|
||||
+ resource_size(<q_eiu_resource), "eiu") < 0)
|
||||
+ panic("Failed to request eiu memory\n");
|
||||
+
|
||||
+ ltq_eiu_membase = ioremap_nocache(ltq_eiu_resource.start,
|
||||
+ resource_size(<q_eiu_resource));
|
||||
+ if (!ltq_eiu_membase)
|
||||
+ panic("Failed to remap eiu memory\n");
|
||||
+#endif
|
||||
+ /* make sure all irqs are turned off by default */
|
||||
+ for (i = 0; i < 5; i++)
|
||||
+ 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));
|
||||
+
|
||||
+ mips_cpu_irq_init();
|
||||
+
|
||||
+ for (i = 2; i <= 6; i++)
|
||||
+ setup_irq(i, &cascade);
|
||||
+
|
||||
+ if (cpu_has_vint) {
|
||||
+ pr_info("Setting up vectored interrupts\n");
|
||||
+ set_vi_handler(2, ltq_hw0_irqdispatch);
|
||||
+ set_vi_handler(3, ltq_hw1_irqdispatch);
|
||||
+ set_vi_handler(4, ltq_hw2_irqdispatch);
|
||||
+ set_vi_handler(5, ltq_hw3_irqdispatch);
|
||||
+ set_vi_handler(6, ltq_hw4_irqdispatch);
|
||||
+ set_vi_handler(7, ltq_hw5_irqdispatch);
|
||||
+ }
|
||||
+
|
||||
+ for (i = INT_NUM_IRQ0;
|
||||
+ i <= (INT_NUM_IRQ0 + (5 * INT_NUM_IM_OFFSET)); i++)
|
||||
+#ifdef CONFIG_SOC_TYPE_XWAY
|
||||
+ if ((i == LTQ_EIU_IR0) || (i == LTQ_EIU_IR1) || (i == LTQ_EIU_IR2))
|
||||
+ irq_set_chip_and_handler(i, <q_eiu_type, handle_level_irq);
|
||||
+ /* EIU3-5 only exist on ar9 and vr9 */
|
||||
+ else if (((i == LTQ_EIU_IR3) || (i == LTQ_EIU_IR4) ||
|
||||
+ (i == LTQ_EIU_IR5)) && (ltq_is_ar9() || ltq_is_vr9()))
|
||||
+ irq_set_chip_and_handler(i, <q_eiu_type, handle_level_irq);
|
||||
+ else
|
||||
+#endif
|
||||
+ irq_set_chip_and_handler(i, <q_irq_type, handle_level_irq);
|
||||
+
|
||||
+#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);
|
||||
+#else
|
||||
+ set_c0_status(IE_SW0 | IE_SW1 | IE_IRQ0 | IE_IRQ1 |
|
||||
+ IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5);
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
+unsigned int __cpuinit get_c0_compare_int(void)
|
||||
+{
|
||||
+ return CP0_LEGACY_COMPARE_IRQ;
|
||||
+}
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/lantiq/prom.c
|
||||
@@ -0,0 +1,71 @@
|
||||
+/*
|
||||
+ * 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/module.h>
|
||||
+#include <linux/clk.h>
|
||||
+#include <asm/bootinfo.h>
|
||||
+#include <asm/time.h>
|
||||
+
|
||||
+#include <lantiq.h>
|
||||
+
|
||||
+#include "prom.h"
|
||||
+#include "clk.h"
|
||||
+
|
||||
+static struct ltq_soc_info soc_info;
|
||||
+
|
||||
+unsigned int ltq_get_cpu_ver(void)
|
||||
+{
|
||||
+ return soc_info.rev;
|
||||
+}
|
||||
+EXPORT_SYMBOL(ltq_get_cpu_ver);
|
||||
+
|
||||
+unsigned int ltq_get_soc_type(void)
|
||||
+{
|
||||
+ return soc_info.type;
|
||||
+}
|
||||
+EXPORT_SYMBOL(ltq_get_soc_type);
|
||||
+
|
||||
+const char *get_system_type(void)
|
||||
+{
|
||||
+ return soc_info.sys_type;
|
||||
+}
|
||||
+
|
||||
+void prom_free_prom_memory(void)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+static void __init prom_init_cmdline(void)
|
||||
+{
|
||||
+ int argc = fw_arg0;
|
||||
+ char **argv = (char **) KSEG1ADDR(fw_arg1);
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < argc; i++) {
|
||||
+ char *p = (char *) KSEG1ADDR(argv[i]);
|
||||
+
|
||||
+ if (p && *p) {
|
||||
+ strlcat(arcs_cmdline, p, sizeof(arcs_cmdline));
|
||||
+ strlcat(arcs_cmdline, " ", sizeof(arcs_cmdline));
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void __init prom_init(void)
|
||||
+{
|
||||
+ struct clk *clk;
|
||||
+
|
||||
+ 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);
|
||||
+ soc_info.sys_type[LTQ_SYS_TYPE_LEN - 1] = '\0';
|
||||
+ pr_info("SoC: %s\n", soc_info.sys_type);
|
||||
+ prom_init_cmdline();
|
||||
+}
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/lantiq/prom.h
|
||||
@@ -0,0 +1,24 @@
|
||||
+/*
|
||||
+ * 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>
|
||||
+ */
|
||||
+
|
||||
+#ifndef _LTQ_PROM_H__
|
||||
+#define _LTQ_PROM_H__
|
||||
+
|
||||
+#define LTQ_SYS_TYPE_LEN 0x100
|
||||
+
|
||||
+struct ltq_soc_info {
|
||||
+ unsigned char *name;
|
||||
+ unsigned int rev;
|
||||
+ unsigned int partnum;
|
||||
+ unsigned int type;
|
||||
+ unsigned char sys_type[LTQ_SYS_TYPE_LEN];
|
||||
+};
|
||||
+
|
||||
+extern void ltq_soc_detect(struct ltq_soc_info *i);
|
||||
+
|
||||
+#endif
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/lantiq/setup.c
|
||||
@@ -0,0 +1,41 @@
|
||||
+/*
|
||||
+ * 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/io.h>
|
||||
+#include <linux/ioport.h>
|
||||
+#include <asm/bootinfo.h>
|
||||
+
|
||||
+#include <lantiq_soc.h>
|
||||
+
|
||||
+void __init plat_mem_setup(void)
|
||||
+{
|
||||
+ /* assume 16M as default incase uboot fails to pass proper ramsize */
|
||||
+ unsigned long memsize = 16;
|
||||
+ char **envp = (char **) KSEG1ADDR(fw_arg2);
|
||||
+
|
||||
+ ioport_resource.start = IOPORT_RESOURCE_START;
|
||||
+ ioport_resource.end = IOPORT_RESOURCE_END;
|
||||
+ iomem_resource.start = IOMEM_RESOURCE_START;
|
||||
+ iomem_resource.end = IOMEM_RESOURCE_END;
|
||||
+
|
||||
+ set_io_port_base((unsigned long) KSEG1);
|
||||
+
|
||||
+ while (*envp) {
|
||||
+ char *e = (char *)KSEG1ADDR(*envp);
|
||||
+ if (!strncmp(e, "memsize=", 8)) {
|
||||
+ e += 8;
|
||||
+ if (strict_strtoul(e, 0, &memsize))
|
||||
+ pr_warn("bad memsize specified\n");
|
||||
+ }
|
||||
+ envp++;
|
||||
+ }
|
||||
+ memsize *= 1024 * 1024;
|
||||
+ add_memory_region(0x00000000, memsize, BOOT_MEM_RAM);
|
||||
+}
|
||||
--- a/arch/mips/Kbuild.platforms
|
||||
+++ b/arch/mips/Kbuild.platforms
|
||||
@@ -11,6 +11,7 @@ platforms += dec
|
||||
platforms += emma
|
||||
platforms += jazz
|
||||
platforms += jz4740
|
||||
+platforms += lantiq
|
||||
platforms += lasat
|
||||
platforms += loongson
|
||||
platforms += mipssim
|
File diff suppressed because it is too large
Load Diff
|
@ -1,529 +0,0 @@
|
|||
From 08127ed36bad367903591bbf0f244179683ccb28 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Wed, 30 Mar 2011 09:27:49 +0200
|
||||
Subject: [PATCH 03/13] MIPS: Lantiq: Add PCI controller support.
|
||||
|
||||
The Lantiq family of SoCs have a EBU (External Bus Unit). This patch adds
|
||||
the driver that allows us to use the EBU as a PCI controller. In order for
|
||||
PCI to work the EBU is set to endianess swap all the data. In addition we
|
||||
need to make use of SWAP_IO_SPACE for device->host DMA to work.
|
||||
|
||||
The clock of the PCI works in several modes (internal/external). If this
|
||||
is not configured correctly the SoC will hang.
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
Signed-off-by: Ralph Hempel <ralph.hempel@lantiq.com>
|
||||
Cc: linux-mips@linux-mips.org
|
||||
Patchwork: https://patchwork.linux-mips.org/patch/2250/
|
||||
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
|
||||
---
|
||||
.../mips/include/asm/mach-lantiq/lantiq_platform.h | 46 +++
|
||||
arch/mips/pci/Makefile | 1 +
|
||||
arch/mips/pci/ops-lantiq.c | 116 ++++++++
|
||||
arch/mips/pci/pci-lantiq.c | 297 ++++++++++++++++++++
|
||||
arch/mips/pci/pci-lantiq.h | 18 ++
|
||||
5 files changed, 478 insertions(+), 0 deletions(-)
|
||||
create mode 100644 arch/mips/include/asm/mach-lantiq/lantiq_platform.h
|
||||
create mode 100644 arch/mips/pci/ops-lantiq.c
|
||||
create mode 100644 arch/mips/pci/pci-lantiq.c
|
||||
create mode 100644 arch/mips/pci/pci-lantiq.h
|
||||
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/include/asm/mach-lantiq/lantiq_platform.h
|
||||
@@ -0,0 +1,46 @@
|
||||
+/*
|
||||
+ * 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>
|
||||
+ */
|
||||
+
|
||||
+#ifndef _LANTIQ_PLATFORM_H__
|
||||
+#define _LANTIQ_PLATFORM_H__
|
||||
+
|
||||
+#include <linux/mtd/partitions.h>
|
||||
+
|
||||
+/* struct used to pass info to the pci core */
|
||||
+enum {
|
||||
+ PCI_CLOCK_INT = 0,
|
||||
+ PCI_CLOCK_EXT
|
||||
+};
|
||||
+
|
||||
+#define PCI_EXIN0 0x0001
|
||||
+#define PCI_EXIN1 0x0002
|
||||
+#define PCI_EXIN2 0x0004
|
||||
+#define PCI_EXIN3 0x0008
|
||||
+#define PCI_EXIN4 0x0010
|
||||
+#define PCI_EXIN5 0x0020
|
||||
+#define PCI_EXIN_MAX 6
|
||||
+
|
||||
+#define PCI_GNT1 0x0040
|
||||
+#define PCI_GNT2 0x0080
|
||||
+#define PCI_GNT3 0x0100
|
||||
+#define PCI_GNT4 0x0200
|
||||
+
|
||||
+#define PCI_REQ1 0x0400
|
||||
+#define PCI_REQ2 0x0800
|
||||
+#define PCI_REQ3 0x1000
|
||||
+#define PCI_REQ4 0x2000
|
||||
+#define PCI_REQ_SHIFT 10
|
||||
+#define PCI_REQ_MASK 0xf
|
||||
+
|
||||
+struct ltq_pci_data {
|
||||
+ int clock;
|
||||
+ int gpio;
|
||||
+ int irq[16];
|
||||
+};
|
||||
+
|
||||
+#endif
|
||||
--- a/arch/mips/pci/Makefile
|
||||
+++ b/arch/mips/pci/Makefile
|
||||
@@ -41,6 +41,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_TANBAC_TB0219) += fixup-tb0219.o
|
||||
obj-$(CONFIG_TANBAC_TB0226) += fixup-tb0226.o
|
||||
obj-$(CONFIG_TANBAC_TB0287) += fixup-tb0287.o
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/pci/ops-lantiq.c
|
||||
@@ -0,0 +1,116 @@
|
||||
+/*
|
||||
+ * 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/types.h>
|
||||
+#include <linux/pci.h>
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/delay.h>
|
||||
+#include <linux/mm.h>
|
||||
+#include <asm/addrspace.h>
|
||||
+#include <linux/vmalloc.h>
|
||||
+
|
||||
+#include <lantiq_soc.h>
|
||||
+
|
||||
+#include "pci-lantiq.h"
|
||||
+
|
||||
+#define LTQ_PCI_CFG_BUSNUM_SHF 16
|
||||
+#define LTQ_PCI_CFG_DEVNUM_SHF 11
|
||||
+#define LTQ_PCI_CFG_FUNNUM_SHF 8
|
||||
+
|
||||
+#define PCI_ACCESS_READ 0
|
||||
+#define PCI_ACCESS_WRITE 1
|
||||
+
|
||||
+static int ltq_pci_config_access(unsigned char access_type, struct pci_bus *bus,
|
||||
+ unsigned int devfn, unsigned int where, u32 *data)
|
||||
+{
|
||||
+ unsigned long cfg_base;
|
||||
+ unsigned long flags;
|
||||
+ u32 temp;
|
||||
+
|
||||
+ /* we support slot from 0 to 15 dev_fn & 0x68 (AD29) is the
|
||||
+ SoC itself */
|
||||
+ if ((bus->number != 0) || ((devfn & 0xf8) > 0x78)
|
||||
+ || ((devfn & 0xf8) == 0) || ((devfn & 0xf8) == 0x68))
|
||||
+ return 1;
|
||||
+
|
||||
+ spin_lock_irqsave(&ebu_lock, flags);
|
||||
+
|
||||
+ cfg_base = (unsigned long) ltq_pci_mapped_cfg;
|
||||
+ cfg_base |= (bus->number << LTQ_PCI_CFG_BUSNUM_SHF) | (devfn <<
|
||||
+ LTQ_PCI_CFG_FUNNUM_SHF) | (where & ~0x3);
|
||||
+
|
||||
+ /* Perform access */
|
||||
+ if (access_type == PCI_ACCESS_WRITE) {
|
||||
+ ltq_w32(swab32(*data), ((u32 *)cfg_base));
|
||||
+ } else {
|
||||
+ *data = ltq_r32(((u32 *)(cfg_base)));
|
||||
+ *data = swab32(*data);
|
||||
+ }
|
||||
+ wmb();
|
||||
+
|
||||
+ /* clean possible Master abort */
|
||||
+ cfg_base = (unsigned long) ltq_pci_mapped_cfg;
|
||||
+ 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 |= (0x68 << LTQ_PCI_CFG_FUNNUM_SHF) + 4;
|
||||
+ ltq_w32(temp, ((u32 *)cfg_base));
|
||||
+
|
||||
+ spin_unlock_irqrestore(&ebu_lock, flags);
|
||||
+
|
||||
+ if (((*data) == 0xffffffff) && (access_type == PCI_ACCESS_READ))
|
||||
+ return 1;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int ltq_pci_read_config_dword(struct pci_bus *bus, unsigned int devfn,
|
||||
+ int where, int size, u32 *val)
|
||||
+{
|
||||
+ u32 data = 0;
|
||||
+
|
||||
+ if (ltq_pci_config_access(PCI_ACCESS_READ, bus, devfn, where, &data))
|
||||
+ return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
+
|
||||
+ if (size == 1)
|
||||
+ *val = (data >> ((where & 3) << 3)) & 0xff;
|
||||
+ else if (size == 2)
|
||||
+ *val = (data >> ((where & 3) << 3)) & 0xffff;
|
||||
+ else
|
||||
+ *val = data;
|
||||
+
|
||||
+ return PCIBIOS_SUCCESSFUL;
|
||||
+}
|
||||
+
|
||||
+int ltq_pci_write_config_dword(struct pci_bus *bus, unsigned int devfn,
|
||||
+ int where, int size, u32 val)
|
||||
+{
|
||||
+ u32 data = 0;
|
||||
+
|
||||
+ if (size == 4) {
|
||||
+ data = val;
|
||||
+ } else {
|
||||
+ if (ltq_pci_config_access(PCI_ACCESS_READ, bus,
|
||||
+ devfn, where, &data))
|
||||
+ return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
+
|
||||
+ if (size == 1)
|
||||
+ data = (data & ~(0xff << ((where & 3) << 3))) |
|
||||
+ (val << ((where & 3) << 3));
|
||||
+ else if (size == 2)
|
||||
+ data = (data & ~(0xffff << ((where & 3) << 3))) |
|
||||
+ (val << ((where & 3) << 3));
|
||||
+ }
|
||||
+
|
||||
+ if (ltq_pci_config_access(PCI_ACCESS_WRITE, bus, devfn, where, &data))
|
||||
+ return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
+
|
||||
+ return PCIBIOS_SUCCESSFUL;
|
||||
+}
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/pci/pci-lantiq.c
|
||||
@@ -0,0 +1,297 @@
|
||||
+/*
|
||||
+ * 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/types.h>
|
||||
+#include <linux/pci.h>
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/delay.h>
|
||||
+#include <linux/mm.h>
|
||||
+#include <linux/vmalloc.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+
|
||||
+#include <asm/pci.h>
|
||||
+#include <asm/gpio.h>
|
||||
+#include <asm/addrspace.h>
|
||||
+
|
||||
+#include <lantiq_soc.h>
|
||||
+#include <lantiq_irq.h>
|
||||
+#include <lantiq_platform.h>
|
||||
+
|
||||
+#include "pci-lantiq.h"
|
||||
+
|
||||
+#define LTQ_PCI_CFG_BASE 0x17000000
|
||||
+#define LTQ_PCI_CFG_SIZE 0x00008000
|
||||
+#define LTQ_PCI_MEM_BASE 0x18000000
|
||||
+#define LTQ_PCI_MEM_SIZE 0x02000000
|
||||
+#define LTQ_PCI_IO_BASE 0x1AE00000
|
||||
+#define LTQ_PCI_IO_SIZE 0x00200000
|
||||
+
|
||||
+#define PCI_CR_FCI_ADDR_MAP0 0x00C0
|
||||
+#define PCI_CR_FCI_ADDR_MAP1 0x00C4
|
||||
+#define PCI_CR_FCI_ADDR_MAP2 0x00C8
|
||||
+#define PCI_CR_FCI_ADDR_MAP3 0x00CC
|
||||
+#define PCI_CR_FCI_ADDR_MAP4 0x00D0
|
||||
+#define PCI_CR_FCI_ADDR_MAP5 0x00D4
|
||||
+#define PCI_CR_FCI_ADDR_MAP6 0x00D8
|
||||
+#define PCI_CR_FCI_ADDR_MAP7 0x00DC
|
||||
+#define PCI_CR_CLK_CTRL 0x0000
|
||||
+#define PCI_CR_PCI_MOD 0x0030
|
||||
+#define PCI_CR_PC_ARB 0x0080
|
||||
+#define PCI_CR_FCI_ADDR_MAP11hg 0x00E4
|
||||
+#define PCI_CR_BAR11MASK 0x0044
|
||||
+#define PCI_CR_BAR12MASK 0x0048
|
||||
+#define PCI_CR_BAR13MASK 0x004C
|
||||
+#define PCI_CS_BASE_ADDR1 0x0010
|
||||
+#define PCI_CR_PCI_ADDR_MAP11 0x0064
|
||||
+#define PCI_CR_FCI_BURST_LENGTH 0x00E8
|
||||
+#define PCI_CR_PCI_EOI 0x002C
|
||||
+#define PCI_CS_STS_CMD 0x0004
|
||||
+
|
||||
+#define PCI_MASTER0_REQ_MASK_2BITS 8
|
||||
+#define PCI_MASTER1_REQ_MASK_2BITS 10
|
||||
+#define PCI_MASTER2_REQ_MASK_2BITS 12
|
||||
+#define INTERNAL_ARB_ENABLE_BIT 0
|
||||
+
|
||||
+#define LTQ_CGU_IFCCR 0x0018
|
||||
+#define LTQ_CGU_PCICR 0x0034
|
||||
+
|
||||
+#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))
|
||||
+
|
||||
+struct ltq_pci_gpio_map {
|
||||
+ int pin;
|
||||
+ int alt0;
|
||||
+ int alt1;
|
||||
+ 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" },
|
||||
+};
|
||||
+
|
||||
+__iomem void *ltq_pci_mapped_cfg;
|
||||
+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;
|
||||
+
|
||||
+struct pci_ops ltq_pci_ops = {
|
||||
+ .read = ltq_pci_read_config_dword,
|
||||
+ .write = ltq_pci_write_config_dword
|
||||
+};
|
||||
+
|
||||
+static struct resource pci_io_resource = {
|
||||
+ .name = "pci io space",
|
||||
+ .start = LTQ_PCI_IO_BASE,
|
||||
+ .end = LTQ_PCI_IO_BASE + LTQ_PCI_IO_SIZE - 1,
|
||||
+ .flags = IORESOURCE_IO
|
||||
+};
|
||||
+
|
||||
+static struct resource pci_mem_resource = {
|
||||
+ .name = "pci memory space",
|
||||
+ .start = LTQ_PCI_MEM_BASE,
|
||||
+ .end = LTQ_PCI_MEM_BASE + LTQ_PCI_MEM_SIZE - 1,
|
||||
+ .flags = IORESOURCE_MEM
|
||||
+};
|
||||
+
|
||||
+static struct pci_controller ltq_pci_controller = {
|
||||
+ .pci_ops = <q_pci_ops,
|
||||
+ .mem_resource = &pci_mem_resource,
|
||||
+ .mem_offset = 0x00000000UL,
|
||||
+ .io_resource = &pci_io_resource,
|
||||
+ .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;
|
||||
+
|
||||
+ /* BAR11MASK value depends on available memory on system. */
|
||||
+ mem = num_physpages * PAGE_SIZE;
|
||||
+ bar11mask = (0x0ffffff0 & ~((1 << (fls(mem) - 1)) - 1)) | 8;
|
||||
+
|
||||
+ return bar11mask;
|
||||
+}
|
||||
+
|
||||
+static void ltq_pci_setup_gpio(int gpio)
|
||||
+{
|
||||
+ 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,
|
||||
+ ltq_pci_gpio_map[i].alt0,
|
||||
+ ltq_pci_gpio_map[i].alt1,
|
||||
+ ltq_pci_gpio_map[i].dir,
|
||||
+ ltq_pci_gpio_map[i].name);
|
||||
+ }
|
||||
+ }
|
||||
+ ltq_gpio_request(21, 0, 0, 1, "pci-reset");
|
||||
+ ltq_pci_req_mask = (gpio >> PCI_REQ_SHIFT) & PCI_REQ_MASK;
|
||||
+}
|
||||
+
|
||||
+static int __devinit ltq_pci_startup(struct ltq_pci_data *conf)
|
||||
+{
|
||||
+ u32 temp_buffer;
|
||||
+
|
||||
+ /* set clock to 33Mhz */
|
||||
+ ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) & ~0xf00000, LTQ_CGU_IFCCR);
|
||||
+ ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) | 0x800000, LTQ_CGU_IFCCR);
|
||||
+
|
||||
+ /* external or internal clock ? */
|
||||
+ if (conf->clock) {
|
||||
+ ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) & ~(1 << 16),
|
||||
+ LTQ_CGU_IFCCR);
|
||||
+ ltq_cgu_w32((1 << 30), LTQ_CGU_PCICR);
|
||||
+ } else {
|
||||
+ ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) | (1 << 16),
|
||||
+ LTQ_CGU_IFCCR);
|
||||
+ ltq_cgu_w32((1 << 31) | (1 << 30), LTQ_CGU_PCICR);
|
||||
+ }
|
||||
+
|
||||
+ /* setup pci clock and gpis used by pci */
|
||||
+ ltq_pci_setup_gpio(conf->gpio);
|
||||
+
|
||||
+ /* enable auto-switching between PCI and EBU */
|
||||
+ ltq_pci_w32(0xa, PCI_CR_CLK_CTRL);
|
||||
+
|
||||
+ /* busy, i.e. configuration is not done, PCI access has to be retried */
|
||||
+ ltq_pci_w32(ltq_pci_r32(PCI_CR_PCI_MOD) & ~(1 << 24), PCI_CR_PCI_MOD);
|
||||
+ wmb();
|
||||
+ /* BUS Master/IO/MEM access */
|
||||
+ ltq_pci_cfg_w32(ltq_pci_cfg_r32(PCI_CS_STS_CMD) | 7, PCI_CS_STS_CMD);
|
||||
+
|
||||
+ /* enable external 2 PCI masters */
|
||||
+ temp_buffer = ltq_pci_r32(PCI_CR_PC_ARB);
|
||||
+ temp_buffer &= (~(ltq_pci_req_mask << 16));
|
||||
+ /* enable internal arbiter */
|
||||
+ temp_buffer |= (1 << INTERNAL_ARB_ENABLE_BIT);
|
||||
+ /* enable internal PCI master reqest */
|
||||
+ temp_buffer &= (~(3 << PCI_MASTER0_REQ_MASK_2BITS));
|
||||
+
|
||||
+ /* enable EBU request */
|
||||
+ temp_buffer &= (~(3 << PCI_MASTER1_REQ_MASK_2BITS));
|
||||
+
|
||||
+ /* enable all external masters request */
|
||||
+ temp_buffer &= (~(3 << PCI_MASTER2_REQ_MASK_2BITS));
|
||||
+ ltq_pci_w32(temp_buffer, PCI_CR_PC_ARB);
|
||||
+ wmb();
|
||||
+
|
||||
+ /* setup BAR memory regions */
|
||||
+ ltq_pci_w32(0x18000000, PCI_CR_FCI_ADDR_MAP0);
|
||||
+ ltq_pci_w32(0x18400000, PCI_CR_FCI_ADDR_MAP1);
|
||||
+ ltq_pci_w32(0x18800000, PCI_CR_FCI_ADDR_MAP2);
|
||||
+ ltq_pci_w32(0x18c00000, PCI_CR_FCI_ADDR_MAP3);
|
||||
+ ltq_pci_w32(0x19000000, PCI_CR_FCI_ADDR_MAP4);
|
||||
+ ltq_pci_w32(0x19400000, PCI_CR_FCI_ADDR_MAP5);
|
||||
+ ltq_pci_w32(0x19800000, PCI_CR_FCI_ADDR_MAP6);
|
||||
+ ltq_pci_w32(0x19c00000, PCI_CR_FCI_ADDR_MAP7);
|
||||
+ ltq_pci_w32(0x1ae00000, PCI_CR_FCI_ADDR_MAP11hg);
|
||||
+ ltq_pci_w32(ltq_calc_bar11mask(), PCI_CR_BAR11MASK);
|
||||
+ ltq_pci_w32(0, PCI_CR_PCI_ADDR_MAP11);
|
||||
+ ltq_pci_w32(0, PCI_CS_BASE_ADDR1);
|
||||
+ /* both TX and RX endian swap are enabled */
|
||||
+ ltq_pci_w32(ltq_pci_r32(PCI_CR_PCI_EOI) | 3, PCI_CR_PCI_EOI);
|
||||
+ wmb();
|
||||
+ ltq_pci_w32(ltq_pci_r32(PCI_CR_BAR12MASK) | 0x80000000,
|
||||
+ PCI_CR_BAR12MASK);
|
||||
+ ltq_pci_w32(ltq_pci_r32(PCI_CR_BAR13MASK) | 0x80000000,
|
||||
+ PCI_CR_BAR13MASK);
|
||||
+ /*use 8 dw burst length */
|
||||
+ ltq_pci_w32(0x303, PCI_CR_FCI_BURST_LENGTH);
|
||||
+ ltq_pci_w32(ltq_pci_r32(PCI_CR_PCI_MOD) | (1 << 24), PCI_CR_PCI_MOD);
|
||||
+ wmb();
|
||||
+
|
||||
+ /* setup irq line */
|
||||
+ ltq_ebu_w32(ltq_ebu_r32(LTQ_EBU_PCC_CON) | 0xc, LTQ_EBU_PCC_CON);
|
||||
+ ltq_ebu_w32(ltq_ebu_r32(LTQ_EBU_PCC_IEN) | 0x10, LTQ_EBU_PCC_IEN);
|
||||
+
|
||||
+ /* toggle reset pin */
|
||||
+ __gpio_set_value(21, 0);
|
||||
+ wmb();
|
||||
+ mdelay(1);
|
||||
+ __gpio_set_value(21, 1);
|
||||
+ 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 "ltq_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 =
|
||||
+ (struct ltq_pci_data *) pdev->dev.platform_data;
|
||||
+ 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 =
|
||||
+ 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);
|
||||
+ register_pci_controller(<q_pci_controller);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct platform_driver
|
||||
+ltq_pci_driver = {
|
||||
+ .probe = ltq_pci_probe,
|
||||
+ .driver = {
|
||||
+ .name = "ltq_pci",
|
||||
+ .owner = THIS_MODULE,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+int __init pcibios_init(void)
|
||||
+{
|
||||
+ int ret = platform_driver_register(<q_pci_driver);
|
||||
+ if (ret)
|
||||
+ printk(KERN_INFO "ltq_pci: Error registering platfom driver!");
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+arch_initcall(pcibios_init);
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/pci/pci-lantiq.h
|
||||
@@ -0,0 +1,18 @@
|
||||
+/*
|
||||
+ * 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>
|
||||
+ */
|
||||
+
|
||||
+#ifndef _LTQ_PCI_H__
|
||||
+#define _LTQ_PCI_H__
|
||||
+
|
||||
+extern __iomem void *ltq_pci_mapped_cfg;
|
||||
+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,
|
||||
+ unsigned int devfn, int where, int size, u32 val);
|
||||
+
|
||||
+#endif
|
|
@ -1,301 +0,0 @@
|
|||
From cd0d53b24ca744295d2cdf69bb2b659571091b75 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Tue, 12 Apr 2011 18:10:01 +0200
|
||||
Subject: [PATCH 04/13] MIPS: Lantiq: Add NOR flash support
|
||||
|
||||
This patch adds the driver/map for NOR devices attached to the SoC via the
|
||||
External Bus Unit (EBU).
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
Signed-off-by: Ralph Hempel <ralph.hempel@lantiq.com>
|
||||
Cc: David Woodhouse <dwmw2@infradead.org>
|
||||
Cc: Daniel Schwierzeck <daniel.schwierzeck@googlemail.com>
|
||||
Cc: linux-mips@linux-mips.org
|
||||
Cc: linux-mtd@lists.infradead.org
|
||||
Acked-by: Artem Bityutskiy <dedekind1@gmail.com>
|
||||
Patchwork: https://patchwork.linux-mips.org/patch/2285/
|
||||
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
|
||||
---
|
||||
drivers/mtd/maps/Kconfig | 7 +
|
||||
drivers/mtd/maps/Makefile | 1 +
|
||||
drivers/mtd/maps/lantiq-flash.c | 251 +++++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 259 insertions(+), 0 deletions(-)
|
||||
create mode 100644 drivers/mtd/maps/lantiq-flash.c
|
||||
|
||||
--- a/drivers/mtd/maps/Kconfig
|
||||
+++ b/drivers/mtd/maps/Kconfig
|
||||
@@ -260,6 +260,13 @@ config MTD_BCM963XX
|
||||
Support for parsing CFE image tag and creating MTD partitions on
|
||||
Broadcom BCM63xx boards.
|
||||
|
||||
+config MTD_LANTIQ
|
||||
+ tristate "Lantiq SoC NOR support"
|
||||
+ depends on LANTIQ
|
||||
+ select MTD_PARTITIONS
|
||||
+ help
|
||||
+ Support for NOR flash attached to the Lantiq SoC's External Bus Unit.
|
||||
+
|
||||
config MTD_DILNETPC
|
||||
tristate "CFI Flash device mapped on DIL/Net PC"
|
||||
depends on X86 && MTD_PARTITIONS && MTD_CFI_INTELEXT && BROKEN
|
||||
--- a/drivers/mtd/maps/Makefile
|
||||
+++ b/drivers/mtd/maps/Makefile
|
||||
@@ -60,3 +60,4 @@ obj-$(CONFIG_MTD_VMU) += vmu-flash.o
|
||||
obj-$(CONFIG_MTD_GPIO_ADDR) += gpio-addr-flash.o
|
||||
obj-$(CONFIG_MTD_BCM963XX) += bcm963xx-flash.o
|
||||
obj-$(CONFIG_MTD_LATCH_ADDR) += latch-addr-flash.o
|
||||
+obj-$(CONFIG_MTD_LANTIQ) += lantiq-flash.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/mtd/maps/lantiq-flash.c
|
||||
@@ -0,0 +1,251 @@
|
||||
+/*
|
||||
+ * 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) 2004 Liu Peng Infineon IFAP DC COM CPE
|
||||
+ * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
|
||||
+ */
|
||||
+
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/types.h>
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/slab.h>
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/mtd/mtd.h>
|
||||
+#include <linux/mtd/map.h>
|
||||
+#include <linux/mtd/partitions.h>
|
||||
+#include <linux/mtd/cfi.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/mtd/physmap.h>
|
||||
+
|
||||
+#include <lantiq_soc.h>
|
||||
+#include <lantiq_platform.h>
|
||||
+
|
||||
+/*
|
||||
+ * The NOR flash is connected to the same external bus unit (EBU) as PCI.
|
||||
+ * To make PCI work we need to enable the endianness swapping for the address
|
||||
+ * written to the EBU. This endianness swapping works for PCI correctly but
|
||||
+ * fails for attached NOR devices. To workaround this we need to use a complex
|
||||
+ * map. The workaround involves swapping all addresses whilst probing the chip.
|
||||
+ * Once probing is complete we stop swapping the addresses but swizzle the
|
||||
+ * unlock addresses to ensure that access to the NOR device works correctly.
|
||||
+ */
|
||||
+
|
||||
+enum {
|
||||
+ LTQ_NOR_PROBING,
|
||||
+ LTQ_NOR_NORMAL
|
||||
+};
|
||||
+
|
||||
+struct ltq_mtd {
|
||||
+ struct resource *res;
|
||||
+ struct mtd_info *mtd;
|
||||
+ struct map_info *map;
|
||||
+};
|
||||
+
|
||||
+static char ltq_map_name[] = "ltq_nor";
|
||||
+
|
||||
+static map_word
|
||||
+ltq_read16(struct map_info *map, unsigned long adr)
|
||||
+{
|
||||
+ unsigned long flags;
|
||||
+ map_word temp;
|
||||
+
|
||||
+ if (map->map_priv_1 == LTQ_NOR_PROBING)
|
||||
+ adr ^= 2;
|
||||
+ spin_lock_irqsave(&ebu_lock, flags);
|
||||
+ temp.x[0] = *(u16 *)(map->virt + adr);
|
||||
+ spin_unlock_irqrestore(&ebu_lock, flags);
|
||||
+ return temp;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+ltq_write16(struct map_info *map, map_word d, unsigned long adr)
|
||||
+{
|
||||
+ unsigned long flags;
|
||||
+
|
||||
+ if (map->map_priv_1 == LTQ_NOR_PROBING)
|
||||
+ adr ^= 2;
|
||||
+ spin_lock_irqsave(&ebu_lock, flags);
|
||||
+ *(u16 *)(map->virt + adr) = d.x[0];
|
||||
+ spin_unlock_irqrestore(&ebu_lock, flags);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * The following 2 functions copy data between iomem and a cached memory
|
||||
+ * section. As memcpy() makes use of pre-fetching we cannot use it here.
|
||||
+ * The normal alternative of using memcpy_{to,from}io also makes use of
|
||||
+ * memcpy() on MIPS so it is not applicable either. We are therefore stuck
|
||||
+ * with having to use our own loop.
|
||||
+ */
|
||||
+static void
|
||||
+ltq_copy_from(struct map_info *map, void *to,
|
||||
+ unsigned long from, ssize_t len)
|
||||
+{
|
||||
+ unsigned char *f = (unsigned char *)map->virt + from;
|
||||
+ unsigned char *t = (unsigned char *)to;
|
||||
+ unsigned long flags;
|
||||
+
|
||||
+ spin_lock_irqsave(&ebu_lock, flags);
|
||||
+ while (len--)
|
||||
+ *t++ = *f++;
|
||||
+ spin_unlock_irqrestore(&ebu_lock, flags);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+ltq_copy_to(struct map_info *map, unsigned long to,
|
||||
+ const void *from, ssize_t len)
|
||||
+{
|
||||
+ unsigned char *f = (unsigned char *)from;
|
||||
+ unsigned char *t = (unsigned char *)map->virt + to;
|
||||
+ unsigned long flags;
|
||||
+
|
||||
+ spin_lock_irqsave(&ebu_lock, flags);
|
||||
+ while (len--)
|
||||
+ *t++ = *f++;
|
||||
+ spin_unlock_irqrestore(&ebu_lock, flags);
|
||||
+}
|
||||
+
|
||||
+static const char const *part_probe_types[] = { "cmdlinepart", NULL };
|
||||
+
|
||||
+static int __init
|
||||
+ltq_mtd_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct physmap_flash_data *ltq_mtd_data = dev_get_platdata(&pdev->dev);
|
||||
+ struct ltq_mtd *ltq_mtd;
|
||||
+ struct mtd_partition *parts;
|
||||
+ struct resource *res;
|
||||
+ int nr_parts = 0;
|
||||
+ struct cfi_private *cfi;
|
||||
+ int err;
|
||||
+
|
||||
+ ltq_mtd = kzalloc(sizeof(struct ltq_mtd), GFP_KERNEL);
|
||||
+ platform_set_drvdata(pdev, ltq_mtd);
|
||||
+
|
||||
+ ltq_mtd->res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
+ if (!ltq_mtd->res) {
|
||||
+ dev_err(&pdev->dev, "failed to get memory resource");
|
||||
+ err = -ENOENT;
|
||||
+ goto err_out;
|
||||
+ }
|
||||
+
|
||||
+ res = devm_request_mem_region(&pdev->dev, ltq_mtd->res->start,
|
||||
+ resource_size(ltq_mtd->res), dev_name(&pdev->dev));
|
||||
+ if (!ltq_mtd->res) {
|
||||
+ dev_err(&pdev->dev, "failed to request mem resource");
|
||||
+ err = -EBUSY;
|
||||
+ goto err_out;
|
||||
+ }
|
||||
+
|
||||
+ ltq_mtd->map = kzalloc(sizeof(struct map_info), GFP_KERNEL);
|
||||
+ ltq_mtd->map->phys = res->start;
|
||||
+ ltq_mtd->map->size = resource_size(res);
|
||||
+ ltq_mtd->map->virt = devm_ioremap_nocache(&pdev->dev,
|
||||
+ ltq_mtd->map->phys, ltq_mtd->map->size);
|
||||
+ if (!ltq_mtd->map->virt) {
|
||||
+ dev_err(&pdev->dev, "failed to ioremap!\n");
|
||||
+ err = -ENOMEM;
|
||||
+ goto err_free;
|
||||
+ }
|
||||
+
|
||||
+ ltq_mtd->map->name = ltq_map_name;
|
||||
+ ltq_mtd->map->bankwidth = 2;
|
||||
+ ltq_mtd->map->read = ltq_read16;
|
||||
+ ltq_mtd->map->write = ltq_write16;
|
||||
+ ltq_mtd->map->copy_from = ltq_copy_from;
|
||||
+ ltq_mtd->map->copy_to = ltq_copy_to;
|
||||
+
|
||||
+ ltq_mtd->map->map_priv_1 = LTQ_NOR_PROBING;
|
||||
+ ltq_mtd->mtd = do_map_probe("cfi_probe", ltq_mtd->map);
|
||||
+ ltq_mtd->map->map_priv_1 = LTQ_NOR_NORMAL;
|
||||
+
|
||||
+ if (!ltq_mtd->mtd) {
|
||||
+ dev_err(&pdev->dev, "probing failed\n");
|
||||
+ err = -ENXIO;
|
||||
+ goto err_unmap;
|
||||
+ }
|
||||
+
|
||||
+ ltq_mtd->mtd->owner = THIS_MODULE;
|
||||
+
|
||||
+ cfi = ltq_mtd->map->fldrv_priv;
|
||||
+ cfi->addr_unlock1 ^= 1;
|
||||
+ cfi->addr_unlock2 ^= 1;
|
||||
+
|
||||
+ nr_parts = parse_mtd_partitions(ltq_mtd->mtd,
|
||||
+ part_probe_types, &parts, 0);
|
||||
+ if (nr_parts > 0) {
|
||||
+ dev_info(&pdev->dev,
|
||||
+ "using %d partitions from cmdline", nr_parts);
|
||||
+ } else {
|
||||
+ nr_parts = ltq_mtd_data->nr_parts;
|
||||
+ parts = ltq_mtd_data->parts;
|
||||
+ }
|
||||
+
|
||||
+ err = add_mtd_partitions(ltq_mtd->mtd, parts, nr_parts);
|
||||
+ if (err) {
|
||||
+ dev_err(&pdev->dev, "failed to add partitions\n");
|
||||
+ goto err_destroy;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+err_destroy:
|
||||
+ map_destroy(ltq_mtd->mtd);
|
||||
+err_unmap:
|
||||
+ iounmap(ltq_mtd->map->virt);
|
||||
+err_free:
|
||||
+ kfree(ltq_mtd->map);
|
||||
+err_out:
|
||||
+ kfree(ltq_mtd);
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+static int __devexit
|
||||
+ltq_mtd_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct ltq_mtd *ltq_mtd = platform_get_drvdata(pdev);
|
||||
+
|
||||
+ if (ltq_mtd) {
|
||||
+ if (ltq_mtd->mtd) {
|
||||
+ del_mtd_partitions(ltq_mtd->mtd);
|
||||
+ map_destroy(ltq_mtd->mtd);
|
||||
+ }
|
||||
+ if (ltq_mtd->map->virt)
|
||||
+ iounmap(ltq_mtd->map->virt);
|
||||
+ kfree(ltq_mtd->map);
|
||||
+ kfree(ltq_mtd);
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct platform_driver ltq_mtd_driver = {
|
||||
+ .remove = __devexit_p(ltq_mtd_remove),
|
||||
+ .driver = {
|
||||
+ .name = "ltq_nor",
|
||||
+ .owner = THIS_MODULE,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static int __init
|
||||
+init_ltq_mtd(void)
|
||||
+{
|
||||
+ int ret = platform_driver_probe(<q_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(<q_mtd_driver);
|
||||
+}
|
||||
+
|
||||
+module_init(init_ltq_mtd);
|
||||
+module_exit(exit_ltq_mtd);
|
||||
+
|
||||
+MODULE_LICENSE("GPL");
|
||||
+MODULE_AUTHOR("John Crispin <blogic@openwrt.org>");
|
||||
+MODULE_DESCRIPTION("Lantiq SoC NOR");
|
|
@ -1,319 +0,0 @@
|
|||
From 09e57348261c1ae0ff89c68679126fc76a28b2a2 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Wed, 30 Mar 2011 09:27:53 +0200
|
||||
Subject: [PATCH 05/13] MIPS: Lantiq: Add platform device support
|
||||
|
||||
This patch adds the wrappers for registering our platform devices.
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
Signed-off-by: Ralph Hempel <ralph.hempel@lantiq.com>
|
||||
Cc: linux-mips@linux-mips.org
|
||||
Patchwork: https://patchwork.linux-mips.org/patch/2254/
|
||||
Patchwork: https://patchwork.linux-mips.org/patch/2360/
|
||||
Patchwork: https://patchwork.linux-mips.org/patch/2359/
|
||||
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
|
||||
---
|
||||
arch/mips/lantiq/Makefile | 2 +-
|
||||
arch/mips/lantiq/devices.c | 122 +++++++++++++++++++++++++++++++++++++++
|
||||
arch/mips/lantiq/devices.h | 23 +++++++
|
||||
arch/mips/lantiq/xway/Makefile | 2 +-
|
||||
arch/mips/lantiq/xway/devices.c | 98 +++++++++++++++++++++++++++++++
|
||||
arch/mips/lantiq/xway/devices.h | 18 ++++++
|
||||
6 files changed, 263 insertions(+), 2 deletions(-)
|
||||
create mode 100644 arch/mips/lantiq/devices.c
|
||||
create mode 100644 arch/mips/lantiq/devices.h
|
||||
create mode 100644 arch/mips/lantiq/xway/devices.c
|
||||
create mode 100644 arch/mips/lantiq/xway/devices.h
|
||||
|
||||
--- a/arch/mips/lantiq/Makefile
|
||||
+++ b/arch/mips/lantiq/Makefile
|
||||
@@ -4,7 +4,7 @@
|
||||
# under the terms of the GNU General Public License version 2 as published
|
||||
# by the Free Software Foundation.
|
||||
|
||||
-obj-y := irq.o setup.o clk.o prom.o
|
||||
+obj-y := irq.o setup.o clk.o prom.o devices.o
|
||||
|
||||
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
|
||||
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/lantiq/devices.c
|
||||
@@ -0,0 +1,122 @@
|
||||
+/*
|
||||
+ * 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/module.h>
|
||||
+#include <linux/types.h>
|
||||
+#include <linux/string.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 "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 platform_device ltq_nor = {
|
||||
+ .name = "ltq_nor",
|
||||
+ .resource = <q_nor_resource,
|
||||
+ .num_resources = 1,
|
||||
+};
|
||||
+
|
||||
+void __init ltq_register_nor(struct physmap_flash_data *data)
|
||||
+{
|
||||
+ ltq_nor.dev.platform_data = data;
|
||||
+ platform_device_register(<q_nor);
|
||||
+}
|
||||
+
|
||||
+/* 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,
|
||||
+};
|
||||
+
|
||||
+void __init ltq_register_wdt(void)
|
||||
+{
|
||||
+ platform_device_register_simple("ltq_wdt", 0, <q_wdt_resource, 1);
|
||||
+}
|
||||
+
|
||||
+/* 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,
|
||||
+ },
|
||||
+ 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,
|
||||
+ },
|
||||
+ IRQ_RES(tx, LTQ_ASC_TIR(1)),
|
||||
+ IRQ_RES(rx, LTQ_ASC_RIR(1)),
|
||||
+ IRQ_RES(err, LTQ_ASC_EIR(1)),
|
||||
+};
|
||||
+
|
||||
+void __init ltq_register_asc(int port)
|
||||
+{
|
||||
+ switch (port) {
|
||||
+ case 0:
|
||||
+ platform_device_register_simple("ltq_asc", 0,
|
||||
+ ltq_asc0_resources, ARRAY_SIZE(ltq_asc0_resources));
|
||||
+ break;
|
||||
+ case 1:
|
||||
+ platform_device_register_simple("ltq_asc", 1,
|
||||
+ ltq_asc1_resources, ARRAY_SIZE(ltq_asc1_resources));
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+#ifdef CONFIG_PCI
|
||||
+/* pci */
|
||||
+static struct platform_device ltq_pci = {
|
||||
+ .name = "ltq_pci",
|
||||
+ .num_resources = 0,
|
||||
+};
|
||||
+
|
||||
+void __init ltq_register_pci(struct ltq_pci_data *data)
|
||||
+{
|
||||
+ ltq_pci.dev.platform_data = data;
|
||||
+ platform_device_register(<q_pci);
|
||||
+}
|
||||
+#else
|
||||
+void __init ltq_register_pci(struct ltq_pci_data *data)
|
||||
+{
|
||||
+ pr_err("kernel is compiled without PCI support\n");
|
||||
+}
|
||||
+#endif
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/lantiq/devices.h
|
||||
@@ -0,0 +1,23 @@
|
||||
+/*
|
||||
+ * 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>
|
||||
+ */
|
||||
+
|
||||
+#ifndef _LTQ_DEVICES_H__
|
||||
+#define _LTQ_DEVICES_H__
|
||||
+
|
||||
+#include <lantiq_platform.h>
|
||||
+#include <linux/mtd/physmap.h>
|
||||
+
|
||||
+#define IRQ_RES(resname, irq) \
|
||||
+ {.name = #resname, .start = (irq), .flags = IORESOURCE_IRQ}
|
||||
+
|
||||
+extern void ltq_register_nor(struct physmap_flash_data *data);
|
||||
+extern void ltq_register_wdt(void);
|
||||
+extern void ltq_register_asc(int port);
|
||||
+extern void ltq_register_pci(struct ltq_pci_data *data);
|
||||
+
|
||||
+#endif
|
||||
--- a/arch/mips/lantiq/xway/Makefile
|
||||
+++ b/arch/mips/lantiq/xway/Makefile
|
||||
@@ -1,4 +1,4 @@
|
||||
-obj-y := pmu.o ebu.o reset.o gpio.o
|
||||
+obj-y := pmu.o ebu.o reset.o gpio.o devices.o
|
||||
|
||||
obj-$(CONFIG_SOC_XWAY) += clk-xway.o prom-xway.o
|
||||
obj-$(CONFIG_SOC_AMAZON_SE) += clk-ase.o prom-ase.o
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/lantiq/xway/devices.c
|
||||
@@ -0,0 +1,98 @@
|
||||
+/*
|
||||
+ * 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/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>
|
||||
+
|
||||
+#include "devices.h"
|
||||
+
|
||||
+/* 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,
|
||||
+ }
|
||||
+};
|
||||
+
|
||||
+void __init ltq_register_gpio(void)
|
||||
+{
|
||||
+ platform_device_register_simple("ltq_gpio", 0,
|
||||
+ <q_gpio_resource[0], 1);
|
||||
+ platform_device_register_simple("ltq_gpio", 1,
|
||||
+ <q_gpio_resource[1], 1);
|
||||
+
|
||||
+ /* AR9 and VR9 have an extra gpio block */
|
||||
+ if (ltq_is_ar9() || ltq_is_vr9()) {
|
||||
+ platform_device_register_simple("ltq_gpio", 2,
|
||||
+ <q_gpio_resource[2], 1);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/* 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,
|
||||
+};
|
||||
+
|
||||
+void __init ltq_register_gpio_stp(void)
|
||||
+{
|
||||
+ platform_device_register_simple("ltq_stp", 0, <q_stp_resource, 1);
|
||||
+}
|
||||
+
|
||||
+/* 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,
|
||||
+ },
|
||||
+ IRQ_RES(tx, LTQ_ASC_ASE_TIR),
|
||||
+ IRQ_RES(rx, LTQ_ASC_ASE_RIR),
|
||||
+ IRQ_RES(err, LTQ_ASC_ASE_EIR),
|
||||
+};
|
||||
+
|
||||
+void __init ltq_register_ase_asc(void)
|
||||
+{
|
||||
+ platform_device_register_simple("ltq_asc", 0,
|
||||
+ ltq_ase_asc_resources, ARRAY_SIZE(ltq_ase_asc_resources));
|
||||
+}
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/lantiq/xway/devices.h
|
||||
@@ -0,0 +1,18 @@
|
||||
+/*
|
||||
+ * 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>
|
||||
+ */
|
||||
+
|
||||
+#ifndef _LTQ_DEVICES_XWAY_H__
|
||||
+#define _LTQ_DEVICES_XWAY_H__
|
||||
+
|
||||
+#include "../devices.h"
|
||||
+
|
||||
+extern void ltq_register_gpio(void);
|
||||
+extern void ltq_register_gpio_stp(void);
|
||||
+extern void ltq_register_ase_asc(void);
|
||||
+
|
||||
+#endif
|
|
@ -1,170 +0,0 @@
|
|||
From 52a5369d1067d4feddbfa7ff4486a77ac9a2971e Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Wed, 30 Mar 2011 09:27:54 +0200
|
||||
Subject: [PATCH 06/13] MIPS: Lantiq: Add mips_machine support
|
||||
|
||||
This patch adds support for Gabor's mips_machine patch.
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
Signed-off-by: Ralph Hempel <ralph.hempel@lantiq.com>
|
||||
Cc: Gabor Juhos <juhosg@openwrt.org>
|
||||
Cc: linux-mips@linux-mips.org
|
||||
Patchwork: https://patchwork.linux-mips.org/patch/2251/
|
||||
Patchwork: https://patchwork.linux-mips.org/patch/2358/
|
||||
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
|
||||
---
|
||||
arch/mips/Kconfig | 1 +
|
||||
arch/mips/lantiq/machtypes.h | 18 ++++++++++++++++++
|
||||
arch/mips/lantiq/prom.h | 1 +
|
||||
arch/mips/lantiq/setup.c | 25 +++++++++++++++++++++++++
|
||||
arch/mips/lantiq/xway/Makefile | 4 ++--
|
||||
arch/mips/lantiq/xway/setup-ase.c | 19 +++++++++++++++++++
|
||||
arch/mips/lantiq/xway/setup-xway.c | 20 ++++++++++++++++++++
|
||||
7 files changed, 86 insertions(+), 2 deletions(-)
|
||||
create mode 100644 arch/mips/lantiq/machtypes.h
|
||||
create mode 100644 arch/mips/lantiq/xway/setup-ase.c
|
||||
create mode 100644 arch/mips/lantiq/xway/setup-xway.c
|
||||
|
||||
--- a/arch/mips/Kconfig
|
||||
+++ b/arch/mips/Kconfig
|
||||
@@ -228,6 +228,7 @@ config LANTIQ
|
||||
select SWAP_IO_SPACE
|
||||
select BOOT_RAW
|
||||
select HAVE_CLK
|
||||
+ select MIPS_MACHINE
|
||||
|
||||
config LASAT
|
||||
bool "LASAT Networks platforms"
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/lantiq/machtypes.h
|
||||
@@ -0,0 +1,18 @@
|
||||
+/*
|
||||
+ * 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>
|
||||
+ */
|
||||
+
|
||||
+#ifndef _LANTIQ_MACH_H__
|
||||
+#define _LANTIQ_MACH_H__
|
||||
+
|
||||
+#include <asm/mips_machine.h>
|
||||
+
|
||||
+enum lantiq_mach_type {
|
||||
+ LTQ_MACH_GENERIC = 0,
|
||||
+};
|
||||
+
|
||||
+#endif
|
||||
--- a/arch/mips/lantiq/prom.h
|
||||
+++ b/arch/mips/lantiq/prom.h
|
||||
@@ -20,5 +20,6 @@ struct ltq_soc_info {
|
||||
};
|
||||
|
||||
extern void ltq_soc_detect(struct ltq_soc_info *i);
|
||||
+extern void ltq_soc_setup(void);
|
||||
|
||||
#endif
|
||||
--- a/arch/mips/lantiq/setup.c
|
||||
+++ b/arch/mips/lantiq/setup.c
|
||||
@@ -14,6 +14,12 @@
|
||||
|
||||
#include <lantiq_soc.h>
|
||||
|
||||
+#include "machtypes.h"
|
||||
+#include "devices.h"
|
||||
+#include "prom.h"
|
||||
+
|
||||
+unsigned long physical_memsize = 0L;
|
||||
+
|
||||
void __init plat_mem_setup(void)
|
||||
{
|
||||
/* assume 16M as default incase uboot fails to pass proper ramsize */
|
||||
@@ -32,10 +38,32 @@ void __init plat_mem_setup(void)
|
||||
if (!strncmp(e, "memsize=", 8)) {
|
||||
e += 8;
|
||||
if (strict_strtoul(e, 0, &memsize))
|
||||
- pr_warn("bad memsize specified\n");
|
||||
+ pr_warning("bad memsize specified\n");
|
||||
}
|
||||
envp++;
|
||||
}
|
||||
memsize *= 1024 * 1024;
|
||||
add_memory_region(0x00000000, memsize, BOOT_MEM_RAM);
|
||||
+ physical_memsize = memsize;
|
||||
+}
|
||||
+
|
||||
+static int __init
|
||||
+lantiq_setup(void)
|
||||
+{
|
||||
+ ltq_soc_setup();
|
||||
+ mips_machine_setup();
|
||||
+ return 0;
|
||||
}
|
||||
+
|
||||
+arch_initcall(lantiq_setup);
|
||||
+
|
||||
+static void __init
|
||||
+lantiq_generic_init(void)
|
||||
+{
|
||||
+ /* Nothing to do */
|
||||
+}
|
||||
+
|
||||
+MIPS_MACHINE(LTQ_MACH_GENERIC,
|
||||
+ "Generic",
|
||||
+ "Generic Lantiq based board",
|
||||
+ lantiq_generic_init);
|
||||
--- a/arch/mips/lantiq/xway/Makefile
|
||||
+++ b/arch/mips/lantiq/xway/Makefile
|
||||
@@ -1,4 +1,4 @@
|
||||
obj-y := pmu.o ebu.o reset.o gpio.o devices.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) += clk-xway.o prom-xway.o setup-xway.o
|
||||
+obj-$(CONFIG_SOC_AMAZON_SE) += clk-ase.o prom-ase.o setup-ase.o
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/lantiq/xway/setup-ase.c
|
||||
@@ -0,0 +1,19 @@
|
||||
+/*
|
||||
+ * 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();
|
||||
+}
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/lantiq/xway/setup-xway.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/*
|
||||
+ * 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();
|
||||
+}
|
|
@ -1,212 +0,0 @@
|
|||
From ab2182fc419548455d03979683eb0e92c372ed79 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Wed, 30 Mar 2011 09:27:55 +0200
|
||||
Subject: [PATCH 07/13] MIPS: Lantiq: Add machtypes for lantiq eval kits
|
||||
|
||||
This patch adds mach specific code for the Lantiq EASY50712/50601 evaluation
|
||||
boards
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
Signed-off-by: Ralph Hempel <ralph.hempel@lantiq.com>
|
||||
Cc: linux-mips@linux-mips.org
|
||||
Patchwork: https://patchwork.linux-mips.org/patch/2255/
|
||||
Patchwork: https://patchwork.linux-mips.org/patch/2361/
|
||||
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
|
||||
---
|
||||
arch/mips/lantiq/Kconfig | 2 +
|
||||
arch/mips/lantiq/machtypes.h | 2 +
|
||||
arch/mips/lantiq/xway/Kconfig | 23 +++++++++++
|
||||
arch/mips/lantiq/xway/Makefile | 3 +
|
||||
arch/mips/lantiq/xway/mach-easy50601.c | 57 ++++++++++++++++++++++++++
|
||||
arch/mips/lantiq/xway/mach-easy50712.c | 68 ++++++++++++++++++++++++++++++++
|
||||
6 files changed, 155 insertions(+), 0 deletions(-)
|
||||
create mode 100644 arch/mips/lantiq/xway/Kconfig
|
||||
create mode 100644 arch/mips/lantiq/xway/mach-easy50601.c
|
||||
create mode 100644 arch/mips/lantiq/xway/mach-easy50712.c
|
||||
|
||||
--- a/arch/mips/lantiq/Kconfig
|
||||
+++ b/arch/mips/lantiq/Kconfig
|
||||
@@ -18,4 +18,6 @@ config SOC_XWAY
|
||||
select HW_HAS_PCI
|
||||
endchoice
|
||||
|
||||
+source "arch/mips/lantiq/xway/Kconfig"
|
||||
+
|
||||
endif
|
||||
--- a/arch/mips/lantiq/machtypes.h
|
||||
+++ b/arch/mips/lantiq/machtypes.h
|
||||
@@ -13,6 +13,8 @@
|
||||
|
||||
enum lantiq_mach_type {
|
||||
LTQ_MACH_GENERIC = 0,
|
||||
+ LTQ_MACH_EASY50712, /* Danube evaluation board */
|
||||
+ LTQ_MACH_EASY50601, /* Amazon SE evaluation board */
|
||||
};
|
||||
|
||||
#endif
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/lantiq/xway/Kconfig
|
||||
@@ -0,0 +1,23 @@
|
||||
+if SOC_XWAY
|
||||
+
|
||||
+menu "MIPS Machine"
|
||||
+
|
||||
+config LANTIQ_MACH_EASY50712
|
||||
+ bool "Easy50712 - Danube"
|
||||
+ default y
|
||||
+
|
||||
+endmenu
|
||||
+
|
||||
+endif
|
||||
+
|
||||
+if SOC_AMAZON_SE
|
||||
+
|
||||
+menu "MIPS Machine"
|
||||
+
|
||||
+config LANTIQ_MACH_EASY50601
|
||||
+ bool "Easy50601 - Amazon SE"
|
||||
+ default y
|
||||
+
|
||||
+endmenu
|
||||
+
|
||||
+endif
|
||||
--- a/arch/mips/lantiq/xway/Makefile
|
||||
+++ b/arch/mips/lantiq/xway/Makefile
|
||||
@@ -2,3 +2,6 @@ obj-y := pmu.o ebu.o reset.o gpio.o devi
|
||||
|
||||
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_LANTIQ_MACH_EASY50712) += mach-easy50712.o
|
||||
+obj-$(CONFIG_LANTIQ_MACH_EASY50601) += mach-easy50601.o
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/lantiq/xway/mach-easy50601.c
|
||||
@@ -0,0 +1,57 @@
|
||||
+/*
|
||||
+ * 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 = 0xE0000,
|
||||
+ },
|
||||
+ {
|
||||
+ .name = "rootfs",
|
||||
+ .offset = 0x100000,
|
||||
+ .size = 0x300000,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static struct physmap_flash_data easy50601_flash_data = {
|
||||
+ .nr_parts = ARRAY_SIZE(easy50601_partitions),
|
||||
+ .parts = easy50601_partitions,
|
||||
+};
|
||||
+
|
||||
+static void __init easy50601_init(void)
|
||||
+{
|
||||
+ ltq_register_nor(&easy50601_flash_data);
|
||||
+}
|
||||
+
|
||||
+MIPS_MACHINE(LTQ_MACH_EASY50601,
|
||||
+ "EASY50601",
|
||||
+ "EASY50601 Eval Board",
|
||||
+ easy50601_init);
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/lantiq/xway/mach-easy50712.c
|
||||
@@ -0,0 +1,68 @@
|
||||
+/*
|
||||
+ * 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_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 = 0xe0000,
|
||||
+ },
|
||||
+ {
|
||||
+ .name = "rootfs",
|
||||
+ .offset = 0x100000,
|
||||
+ .size = 0x300000,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+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 void __init easy50712_init(void)
|
||||
+{
|
||||
+ ltq_register_gpio_stp();
|
||||
+ ltq_register_nor(&easy50712_flash_data);
|
||||
+ ltq_register_pci(<q_pci_data);
|
||||
+}
|
||||
+
|
||||
+MIPS_MACHINE(LTQ_MACH_EASY50712,
|
||||
+ "EASY50712",
|
||||
+ "EASY50712 Eval Board",
|
||||
+ easy50712_init);
|
|
@ -1,319 +0,0 @@
|
|||
From f9391211e47cdcc31f341d710efef4b3b46c333d Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Wed, 30 Mar 2011 09:27:56 +0200
|
||||
Subject: [PATCH 08/13] MIPS: Lantiq: Add more gpio drivers
|
||||
|
||||
The XWAY family allows to extend the number of gpios by using shift registers or latches. This patch adds the 2 drivers needed for this. The extended gpios are output only.
|
||||
|
||||
[ralf@linux-mips.org: Fixed ltq_stp_probe section() attributes.]
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
Signed-off-by: Ralph Hempel <ralph.hempel@lantiq.com>
|
||||
Cc: linux-mips@linux-mips.org
|
||||
Patchwork: https://patchwork.linux-mips.org/patch/2258/
|
||||
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
|
||||
---
|
||||
arch/mips/lantiq/xway/Makefile | 2 +-
|
||||
arch/mips/lantiq/xway/gpio_ebu.c | 126 ++++++++++++++++++++++++++++++
|
||||
arch/mips/lantiq/xway/gpio_stp.c | 157 ++++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 284 insertions(+), 1 deletions(-)
|
||||
create mode 100644 arch/mips/lantiq/xway/gpio_ebu.c
|
||||
create mode 100644 arch/mips/lantiq/xway/gpio_stp.c
|
||||
|
||||
--- a/arch/mips/lantiq/xway/Makefile
|
||||
+++ b/arch/mips/lantiq/xway/Makefile
|
||||
@@ -1,4 +1,4 @@
|
||||
-obj-y := pmu.o ebu.o reset.o gpio.o devices.o
|
||||
+obj-y := pmu.o ebu.o reset.o gpio.o gpio_stp.o gpio_ebu.o devices.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
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/lantiq/xway/gpio_ebu.c
|
||||
@@ -0,0 +1,126 @@
|
||||
+/*
|
||||
+ * 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/module.h>
|
||||
+#include <linux/types.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/mutex.h>
|
||||
+#include <linux/gpio.h>
|
||||
+#include <linux/io.h>
|
||||
+
|
||||
+#include <lantiq_soc.h>
|
||||
+
|
||||
+/*
|
||||
+ * By attaching hardware latches to the EBU it is possible to create output
|
||||
+ * only gpios. This driver configures a special memory address, which when
|
||||
+ * written to outputs 16 bit to the latches.
|
||||
+ */
|
||||
+
|
||||
+#define LTQ_EBU_BUSCON 0x1e7ff /* 16 bit access, slowest timing */
|
||||
+#define LTQ_EBU_WP 0x80000000 /* write protect bit */
|
||||
+
|
||||
+/* we keep a shadow value of the last value written to the ebu */
|
||||
+static int ltq_ebu_gpio_shadow = 0x0;
|
||||
+static void __iomem *ltq_ebu_gpio_membase;
|
||||
+
|
||||
+static void ltq_ebu_apply(void)
|
||||
+{
|
||||
+ unsigned long flags;
|
||||
+
|
||||
+ spin_lock_irqsave(&ebu_lock, flags);
|
||||
+ ltq_ebu_w32(LTQ_EBU_BUSCON, LTQ_EBU_BUSCON1);
|
||||
+ *((__u16 *)ltq_ebu_gpio_membase) = ltq_ebu_gpio_shadow;
|
||||
+ ltq_ebu_w32(LTQ_EBU_BUSCON | LTQ_EBU_WP, LTQ_EBU_BUSCON1);
|
||||
+ spin_unlock_irqrestore(&ebu_lock, flags);
|
||||
+}
|
||||
+
|
||||
+static void ltq_ebu_set(struct gpio_chip *chip, unsigned offset, int value)
|
||||
+{
|
||||
+ if (value)
|
||||
+ ltq_ebu_gpio_shadow |= (1 << offset);
|
||||
+ else
|
||||
+ ltq_ebu_gpio_shadow &= ~(1 << offset);
|
||||
+ ltq_ebu_apply();
|
||||
+}
|
||||
+
|
||||
+static int ltq_ebu_direction_output(struct gpio_chip *chip, unsigned offset,
|
||||
+ int value)
|
||||
+{
|
||||
+ ltq_ebu_set(chip, offset, value);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct gpio_chip ltq_ebu_chip = {
|
||||
+ .label = "ltq_ebu",
|
||||
+ .direction_output = ltq_ebu_direction_output,
|
||||
+ .set = ltq_ebu_set,
|
||||
+ .base = 72,
|
||||
+ .ngpio = 16,
|
||||
+ .can_sleep = 1,
|
||||
+ .owner = THIS_MODULE,
|
||||
+};
|
||||
+
|
||||
+static int ltq_ebu_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ int ret = 0;
|
||||
+ struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
+
|
||||
+ if (!res) {
|
||||
+ dev_err(&pdev->dev, "failed to get memory resource\n");
|
||||
+ return -ENOENT;
|
||||
+ }
|
||||
+
|
||||
+ res = devm_request_mem_region(&pdev->dev, res->start,
|
||||
+ resource_size(res), dev_name(&pdev->dev));
|
||||
+ if (!res) {
|
||||
+ dev_err(&pdev->dev, "failed to request memory resource\n");
|
||||
+ return -EBUSY;
|
||||
+ }
|
||||
+
|
||||
+ ltq_ebu_gpio_membase = devm_ioremap_nocache(&pdev->dev, res->start,
|
||||
+ resource_size(res));
|
||||
+ if (!ltq_ebu_gpio_membase) {
|
||||
+ dev_err(&pdev->dev, "Failed to ioremap mem region\n");
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ /* grab the default shadow value passed form the platform code */
|
||||
+ ltq_ebu_gpio_shadow = (unsigned int) pdev->dev.platform_data;
|
||||
+
|
||||
+ /* tell the ebu controller which memory address we will be using */
|
||||
+ ltq_ebu_w32(pdev->resource->start | 0x1, LTQ_EBU_ADDRSEL1);
|
||||
+
|
||||
+ /* write protect the region */
|
||||
+ ltq_ebu_w32(LTQ_EBU_BUSCON | LTQ_EBU_WP, LTQ_EBU_BUSCON1);
|
||||
+
|
||||
+ ret = gpiochip_add(<q_ebu_chip);
|
||||
+ if (!ret)
|
||||
+ ltq_ebu_apply();
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static struct platform_driver ltq_ebu_driver = {
|
||||
+ .probe = ltq_ebu_probe,
|
||||
+ .driver = {
|
||||
+ .name = "ltq_ebu",
|
||||
+ .owner = THIS_MODULE,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static int __init ltq_ebu_init(void)
|
||||
+{
|
||||
+ int ret = platform_driver_register(<q_ebu_driver);
|
||||
+
|
||||
+ if (ret)
|
||||
+ pr_info("ltq_ebu : Error registering platfom driver!");
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+postcore_initcall(ltq_ebu_init);
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/lantiq/xway/gpio_stp.c
|
||||
@@ -0,0 +1,157 @@
|
||||
+/*
|
||||
+ * 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) 2007 John Crispin <blogic@openwrt.org>
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#include <linux/slab.h>
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/types.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/mutex.h>
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/gpio.h>
|
||||
+
|
||||
+#include <lantiq_soc.h>
|
||||
+
|
||||
+#define LTQ_STP_CON0 0x00
|
||||
+#define LTQ_STP_CON1 0x04
|
||||
+#define LTQ_STP_CPU0 0x08
|
||||
+#define LTQ_STP_CPU1 0x0C
|
||||
+#define LTQ_STP_AR 0x10
|
||||
+
|
||||
+#define LTQ_STP_CON_SWU (1 << 31)
|
||||
+#define LTQ_STP_2HZ 0
|
||||
+#define LTQ_STP_4HZ (1 << 23)
|
||||
+#define LTQ_STP_8HZ (2 << 23)
|
||||
+#define LTQ_STP_10HZ (3 << 23)
|
||||
+#define LTQ_STP_SPEED_MASK (0xf << 23)
|
||||
+#define LTQ_STP_UPD_FPI (1 << 31)
|
||||
+#define LTQ_STP_UPD_MASK (3 << 30)
|
||||
+#define LTQ_STP_ADSL_SRC (3 << 24)
|
||||
+
|
||||
+#define LTQ_STP_GROUP0 (1 << 0)
|
||||
+
|
||||
+#define LTQ_STP_RISING 0
|
||||
+#define LTQ_STP_FALLING (1 << 26)
|
||||
+#define LTQ_STP_EDGE_MASK (1 << 26)
|
||||
+
|
||||
+#define ltq_stp_r32(reg) __raw_readl(ltq_stp_membase + reg)
|
||||
+#define ltq_stp_w32(val, reg) __raw_writel(val, ltq_stp_membase + reg)
|
||||
+#define ltq_stp_w32_mask(clear, set, reg) \
|
||||
+ ltq_w32((ltq_r32(ltq_stp_membase + reg) & ~(clear)) | (set), \
|
||||
+ ltq_stp_membase + (reg))
|
||||
+
|
||||
+static int ltq_stp_shadow = 0xffff;
|
||||
+static void __iomem *ltq_stp_membase;
|
||||
+
|
||||
+static void ltq_stp_set(struct gpio_chip *chip, unsigned offset, int value)
|
||||
+{
|
||||
+ if (value)
|
||||
+ ltq_stp_shadow |= (1 << offset);
|
||||
+ else
|
||||
+ ltq_stp_shadow &= ~(1 << offset);
|
||||
+ ltq_stp_w32(ltq_stp_shadow, LTQ_STP_CPU0);
|
||||
+}
|
||||
+
|
||||
+static int ltq_stp_direction_output(struct gpio_chip *chip, unsigned offset,
|
||||
+ int value)
|
||||
+{
|
||||
+ ltq_stp_set(chip, offset, value);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct gpio_chip ltq_stp_chip = {
|
||||
+ .label = "ltq_stp",
|
||||
+ .direction_output = ltq_stp_direction_output,
|
||||
+ .set = ltq_stp_set,
|
||||
+ .base = 48,
|
||||
+ .ngpio = 24,
|
||||
+ .can_sleep = 1,
|
||||
+ .owner = THIS_MODULE,
|
||||
+};
|
||||
+
|
||||
+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");
|
||||
+
|
||||
+ /* sane defaults */
|
||||
+ ltq_stp_w32(0, LTQ_STP_AR);
|
||||
+ ltq_stp_w32(0, LTQ_STP_CPU0);
|
||||
+ ltq_stp_w32(0, LTQ_STP_CPU1);
|
||||
+ ltq_stp_w32(LTQ_STP_CON_SWU, LTQ_STP_CON0);
|
||||
+ ltq_stp_w32(0, LTQ_STP_CON1);
|
||||
+
|
||||
+ /* 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);
|
||||
+
|
||||
+ /* 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
|
||||
+ */
|
||||
+ ltq_stp_w32_mask(0, LTQ_STP_ADSL_SRC, LTQ_STP_CON0);
|
||||
+
|
||||
+ ltq_pmu_enable(PMU_LED);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int __devinit ltq_stp_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ if (!res)
|
||||
+ return -ENOENT;
|
||||
+ res = devm_request_mem_region(&pdev->dev, res->start,
|
||||
+ resource_size(res), dev_name(&pdev->dev));
|
||||
+ if (!res) {
|
||||
+ dev_err(&pdev->dev, "failed to request STP memory\n");
|
||||
+ return -EBUSY;
|
||||
+ }
|
||||
+ ltq_stp_membase = devm_ioremap_nocache(&pdev->dev, res->start,
|
||||
+ resource_size(res));
|
||||
+ if (!ltq_stp_membase) {
|
||||
+ dev_err(&pdev->dev, "failed to remap STP memory\n");
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
+ ret = gpiochip_add(<q_stp_chip);
|
||||
+ if (!ret)
|
||||
+ ret = ltq_stp_hw_init();
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static struct platform_driver ltq_stp_driver = {
|
||||
+ .probe = ltq_stp_probe,
|
||||
+ .driver = {
|
||||
+ .name = "ltq_stp",
|
||||
+ .owner = THIS_MODULE,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+int __init ltq_stp_init(void)
|
||||
+{
|
||||
+ int ret = platform_driver_register(<q_stp_driver);
|
||||
+
|
||||
+ if (ret)
|
||||
+ pr_info("ltq_stp: error registering platfom driver");
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+postcore_initcall(ltq_stp_init);
|
|
@ -1,804 +0,0 @@
|
|||
From 1d2b44b1afa3ef081cd817dbf947d48eb8f5d21a Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Tue, 5 Apr 2011 14:10:57 +0200
|
||||
Subject: [PATCH 09/13] SERIAL: Lantiq: Add driver for MIPS Lantiq SOCs.
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
Signed-off-by: Ralph Hempel <ralph.hempel@lantiq.com>
|
||||
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
|
||||
Cc: alan@lxorguk.ukuu.org.uk
|
||||
Cc: linux-mips@linux-mips.org
|
||||
Cc: linux-serial@vger.kernel.org
|
||||
Patchwork: https://patchwork.linux-mips.org/patch/2269/
|
||||
Acked-by: Alan Cox <alan@linux.intel.com>
|
||||
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
|
||||
---
|
||||
drivers/tty/serial/Kconfig | 8 +
|
||||
drivers/tty/serial/Makefile | 1 +
|
||||
drivers/tty/serial/lantiq.c | 756 +++++++++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 765 insertions(+), 0 deletions(-)
|
||||
create mode 100644 drivers/tty/serial/lantiq.c
|
||||
|
||||
--- /dev/null
|
||||
+++ b/drivers/tty/serial/lantiq.c
|
||||
@@ -0,0 +1,756 @@
|
||||
+/*
|
||||
+ * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify it
|
||||
+ * under the terms of the GNU General Public License version 2 as published
|
||||
+ * by the Free Software Foundation.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License
|
||||
+ * along with this program; if not, write to the Free Software
|
||||
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
+ *
|
||||
+ * Copyright (C) 2004 Infineon IFAP DC COM CPE
|
||||
+ * Copyright (C) 2007 Felix Fietkau <nbd@openwrt.org>
|
||||
+ * Copyright (C) 2007 John Crispin <blogic@openwrt.org>
|
||||
+ * Copyright (C) 2010 Thomas Langer, <thomas.langer@lantiq.com>
|
||||
+ */
|
||||
+
|
||||
+#include <linux/slab.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/ioport.h>
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/console.h>
|
||||
+#include <linux/sysrq.h>
|
||||
+#include <linux/device.h>
|
||||
+#include <linux/tty.h>
|
||||
+#include <linux/tty_flip.h>
|
||||
+#include <linux/serial_core.h>
|
||||
+#include <linux/serial.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/clk.h>
|
||||
+
|
||||
+#include <lantiq_soc.h>
|
||||
+
|
||||
+#define PORT_LTQ_ASC 111
|
||||
+#define MAXPORTS 2
|
||||
+#define UART_DUMMY_UER_RX 1
|
||||
+#define DRVNAME "ltq_asc"
|
||||
+#ifdef __BIG_ENDIAN
|
||||
+#define LTQ_ASC_TBUF (0x0020 + 3)
|
||||
+#define LTQ_ASC_RBUF (0x0024 + 3)
|
||||
+#else
|
||||
+#define LTQ_ASC_TBUF 0x0020
|
||||
+#define LTQ_ASC_RBUF 0x0024
|
||||
+#endif
|
||||
+#define LTQ_ASC_FSTAT 0x0048
|
||||
+#define LTQ_ASC_WHBSTATE 0x0018
|
||||
+#define LTQ_ASC_STATE 0x0014
|
||||
+#define LTQ_ASC_IRNCR 0x00F8
|
||||
+#define LTQ_ASC_CLC 0x0000
|
||||
+#define LTQ_ASC_ID 0x0008
|
||||
+#define LTQ_ASC_PISEL 0x0004
|
||||
+#define LTQ_ASC_TXFCON 0x0044
|
||||
+#define LTQ_ASC_RXFCON 0x0040
|
||||
+#define LTQ_ASC_CON 0x0010
|
||||
+#define LTQ_ASC_BG 0x0050
|
||||
+#define LTQ_ASC_IRNREN 0x00F4
|
||||
+
|
||||
+#define ASC_IRNREN_TX 0x1
|
||||
+#define ASC_IRNREN_RX 0x2
|
||||
+#define ASC_IRNREN_ERR 0x4
|
||||
+#define ASC_IRNREN_TX_BUF 0x8
|
||||
+#define ASC_IRNCR_TIR 0x1
|
||||
+#define ASC_IRNCR_RIR 0x2
|
||||
+#define ASC_IRNCR_EIR 0x4
|
||||
+
|
||||
+#define ASCOPT_CSIZE 0x3
|
||||
+#define TXFIFO_FL 1
|
||||
+#define RXFIFO_FL 1
|
||||
+#define ASCCLC_DISS 0x2
|
||||
+#define ASCCLC_RMCMASK 0x0000FF00
|
||||
+#define ASCCLC_RMCOFFSET 8
|
||||
+#define ASCCON_M_8ASYNC 0x0
|
||||
+#define ASCCON_M_7ASYNC 0x2
|
||||
+#define ASCCON_ODD 0x00000020
|
||||
+#define ASCCON_STP 0x00000080
|
||||
+#define ASCCON_BRS 0x00000100
|
||||
+#define ASCCON_FDE 0x00000200
|
||||
+#define ASCCON_R 0x00008000
|
||||
+#define ASCCON_FEN 0x00020000
|
||||
+#define ASCCON_ROEN 0x00080000
|
||||
+#define ASCCON_TOEN 0x00100000
|
||||
+#define ASCSTATE_PE 0x00010000
|
||||
+#define ASCSTATE_FE 0x00020000
|
||||
+#define ASCSTATE_ROE 0x00080000
|
||||
+#define ASCSTATE_ANY (ASCSTATE_ROE|ASCSTATE_PE|ASCSTATE_FE)
|
||||
+#define ASCWHBSTATE_CLRREN 0x00000001
|
||||
+#define ASCWHBSTATE_SETREN 0x00000002
|
||||
+#define ASCWHBSTATE_CLRPE 0x00000004
|
||||
+#define ASCWHBSTATE_CLRFE 0x00000008
|
||||
+#define ASCWHBSTATE_CLRROE 0x00000020
|
||||
+#define ASCTXFCON_TXFEN 0x0001
|
||||
+#define ASCTXFCON_TXFFLU 0x0002
|
||||
+#define ASCTXFCON_TXFITLMASK 0x3F00
|
||||
+#define ASCTXFCON_TXFITLOFF 8
|
||||
+#define ASCRXFCON_RXFEN 0x0001
|
||||
+#define ASCRXFCON_RXFFLU 0x0002
|
||||
+#define ASCRXFCON_RXFITLMASK 0x3F00
|
||||
+#define ASCRXFCON_RXFITLOFF 8
|
||||
+#define ASCFSTAT_RXFFLMASK 0x003F
|
||||
+#define ASCFSTAT_TXFFLMASK 0x3F00
|
||||
+#define ASCFSTAT_TXFREEMASK 0x3F000000
|
||||
+#define ASCFSTAT_TXFREEOFF 24
|
||||
+
|
||||
+static void lqasc_tx_chars(struct uart_port *port);
|
||||
+static struct ltq_uart_port *lqasc_port[MAXPORTS];
|
||||
+static struct uart_driver lqasc_reg;
|
||||
+static DEFINE_SPINLOCK(ltq_asc_lock);
|
||||
+
|
||||
+struct ltq_uart_port {
|
||||
+ struct uart_port port;
|
||||
+ struct clk *clk;
|
||||
+ unsigned int tx_irq;
|
||||
+ unsigned int rx_irq;
|
||||
+ unsigned int err_irq;
|
||||
+};
|
||||
+
|
||||
+static inline struct
|
||||
+ltq_uart_port *to_ltq_uart_port(struct uart_port *port)
|
||||
+{
|
||||
+ return container_of(port, struct ltq_uart_port, port);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+lqasc_stop_tx(struct uart_port *port)
|
||||
+{
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+lqasc_start_tx(struct uart_port *port)
|
||||
+{
|
||||
+ unsigned long flags;
|
||||
+ spin_lock_irqsave(<q_asc_lock, flags);
|
||||
+ lqasc_tx_chars(port);
|
||||
+ spin_unlock_irqrestore(<q_asc_lock, flags);
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+lqasc_stop_rx(struct uart_port *port)
|
||||
+{
|
||||
+ ltq_w32(ASCWHBSTATE_CLRREN, port->membase + LTQ_ASC_WHBSTATE);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+lqasc_enable_ms(struct uart_port *port)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+lqasc_rx_chars(struct uart_port *port)
|
||||
+{
|
||||
+ struct tty_struct *tty = tty_port_tty_get(&port->state->port);
|
||||
+ unsigned int ch = 0, rsr = 0, fifocnt;
|
||||
+
|
||||
+ if (!tty) {
|
||||
+ dev_dbg(port->dev, "%s:tty is busy now", __func__);
|
||||
+ return -EBUSY;
|
||||
+ }
|
||||
+ fifocnt =
|
||||
+ ltq_r32(port->membase + LTQ_ASC_FSTAT) & ASCFSTAT_RXFFLMASK;
|
||||
+ while (fifocnt--) {
|
||||
+ u8 flag = TTY_NORMAL;
|
||||
+ ch = ltq_r8(port->membase + LTQ_ASC_RBUF);
|
||||
+ rsr = (ltq_r32(port->membase + LTQ_ASC_STATE)
|
||||
+ & ASCSTATE_ANY) | UART_DUMMY_UER_RX;
|
||||
+ tty_flip_buffer_push(tty);
|
||||
+ port->icount.rx++;
|
||||
+
|
||||
+ /*
|
||||
+ * Note that the error handling code is
|
||||
+ * out of the main execution path
|
||||
+ */
|
||||
+ if (rsr & ASCSTATE_ANY) {
|
||||
+ if (rsr & ASCSTATE_PE) {
|
||||
+ port->icount.parity++;
|
||||
+ ltq_w32_mask(0, ASCWHBSTATE_CLRPE,
|
||||
+ port->membase + LTQ_ASC_WHBSTATE);
|
||||
+ } else if (rsr & ASCSTATE_FE) {
|
||||
+ port->icount.frame++;
|
||||
+ ltq_w32_mask(0, ASCWHBSTATE_CLRFE,
|
||||
+ port->membase + LTQ_ASC_WHBSTATE);
|
||||
+ }
|
||||
+ if (rsr & ASCSTATE_ROE) {
|
||||
+ port->icount.overrun++;
|
||||
+ ltq_w32_mask(0, ASCWHBSTATE_CLRROE,
|
||||
+ port->membase + LTQ_ASC_WHBSTATE);
|
||||
+ }
|
||||
+
|
||||
+ rsr &= port->read_status_mask;
|
||||
+
|
||||
+ if (rsr & ASCSTATE_PE)
|
||||
+ flag = TTY_PARITY;
|
||||
+ else if (rsr & ASCSTATE_FE)
|
||||
+ flag = TTY_FRAME;
|
||||
+ }
|
||||
+
|
||||
+ if ((rsr & port->ignore_status_mask) == 0)
|
||||
+ tty_insert_flip_char(tty, ch, flag);
|
||||
+
|
||||
+ if (rsr & ASCSTATE_ROE)
|
||||
+ /*
|
||||
+ * Overrun is special, since it's reported
|
||||
+ * immediately, and doesn't affect the current
|
||||
+ * character
|
||||
+ */
|
||||
+ tty_insert_flip_char(tty, 0, TTY_OVERRUN);
|
||||
+ }
|
||||
+ if (ch != 0)
|
||||
+ tty_flip_buffer_push(tty);
|
||||
+ tty_kref_put(tty);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+lqasc_tx_chars(struct uart_port *port)
|
||||
+{
|
||||
+ struct circ_buf *xmit = &port->state->xmit;
|
||||
+ if (uart_tx_stopped(port)) {
|
||||
+ lqasc_stop_tx(port);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ while (((ltq_r32(port->membase + LTQ_ASC_FSTAT) &
|
||||
+ ASCFSTAT_TXFREEMASK) >> ASCFSTAT_TXFREEOFF) != 0) {
|
||||
+ if (port->x_char) {
|
||||
+ ltq_w8(port->x_char, port->membase + LTQ_ASC_TBUF);
|
||||
+ port->icount.tx++;
|
||||
+ port->x_char = 0;
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ if (uart_circ_empty(xmit))
|
||||
+ break;
|
||||
+
|
||||
+ ltq_w8(port->state->xmit.buf[port->state->xmit.tail],
|
||||
+ port->membase + LTQ_ASC_TBUF);
|
||||
+ xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
|
||||
+ port->icount.tx++;
|
||||
+ }
|
||||
+
|
||||
+ if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
|
||||
+ uart_write_wakeup(port);
|
||||
+}
|
||||
+
|
||||
+static irqreturn_t
|
||||
+lqasc_tx_int(int irq, void *_port)
|
||||
+{
|
||||
+ unsigned long flags;
|
||||
+ struct uart_port *port = (struct uart_port *)_port;
|
||||
+ spin_lock_irqsave(<q_asc_lock, flags);
|
||||
+ ltq_w32(ASC_IRNCR_TIR, port->membase + LTQ_ASC_IRNCR);
|
||||
+ spin_unlock_irqrestore(<q_asc_lock, flags);
|
||||
+ lqasc_start_tx(port);
|
||||
+ return IRQ_HANDLED;
|
||||
+}
|
||||
+
|
||||
+static irqreturn_t
|
||||
+lqasc_err_int(int irq, void *_port)
|
||||
+{
|
||||
+ unsigned long flags;
|
||||
+ struct uart_port *port = (struct uart_port *)_port;
|
||||
+ spin_lock_irqsave(<q_asc_lock, flags);
|
||||
+ /* clear any pending interrupts */
|
||||
+ ltq_w32_mask(0, ASCWHBSTATE_CLRPE | ASCWHBSTATE_CLRFE |
|
||||
+ ASCWHBSTATE_CLRROE, port->membase + LTQ_ASC_WHBSTATE);
|
||||
+ spin_unlock_irqrestore(<q_asc_lock, flags);
|
||||
+ return IRQ_HANDLED;
|
||||
+}
|
||||
+
|
||||
+static irqreturn_t
|
||||
+lqasc_rx_int(int irq, void *_port)
|
||||
+{
|
||||
+ unsigned long flags;
|
||||
+ struct uart_port *port = (struct uart_port *)_port;
|
||||
+ spin_lock_irqsave(<q_asc_lock, flags);
|
||||
+ ltq_w32(ASC_IRNCR_RIR, port->membase + LTQ_ASC_IRNCR);
|
||||
+ lqasc_rx_chars(port);
|
||||
+ spin_unlock_irqrestore(<q_asc_lock, flags);
|
||||
+ return IRQ_HANDLED;
|
||||
+}
|
||||
+
|
||||
+static unsigned int
|
||||
+lqasc_tx_empty(struct uart_port *port)
|
||||
+{
|
||||
+ int status;
|
||||
+ status = ltq_r32(port->membase + LTQ_ASC_FSTAT) & ASCFSTAT_TXFFLMASK;
|
||||
+ return status ? 0 : TIOCSER_TEMT;
|
||||
+}
|
||||
+
|
||||
+static unsigned int
|
||||
+lqasc_get_mctrl(struct uart_port *port)
|
||||
+{
|
||||
+ return TIOCM_CTS | TIOCM_CAR | TIOCM_DSR;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+lqasc_set_mctrl(struct uart_port *port, u_int mctrl)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+lqasc_break_ctl(struct uart_port *port, int break_state)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+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);
|
||||
+
|
||||
+ ltq_w32_mask(ASCCLC_DISS | ASCCLC_RMCMASK, (1 << ASCCLC_RMCOFFSET),
|
||||
+ port->membase + LTQ_ASC_CLC);
|
||||
+
|
||||
+ ltq_w32(0, port->membase + LTQ_ASC_PISEL);
|
||||
+ ltq_w32(
|
||||
+ ((TXFIFO_FL << ASCTXFCON_TXFITLOFF) & ASCTXFCON_TXFITLMASK) |
|
||||
+ ASCTXFCON_TXFEN | ASCTXFCON_TXFFLU,
|
||||
+ port->membase + LTQ_ASC_TXFCON);
|
||||
+ ltq_w32(
|
||||
+ ((RXFIFO_FL << ASCRXFCON_RXFITLOFF) & ASCRXFCON_RXFITLMASK)
|
||||
+ | ASCRXFCON_RXFEN | ASCRXFCON_RXFFLU,
|
||||
+ port->membase + LTQ_ASC_RXFCON);
|
||||
+ /* make sure other settings are written to hardware before
|
||||
+ * setting enable bits
|
||||
+ */
|
||||
+ wmb();
|
||||
+ ltq_w32_mask(0, ASCCON_M_8ASYNC | ASCCON_FEN | ASCCON_TOEN |
|
||||
+ ASCCON_ROEN, port->membase + LTQ_ASC_CON);
|
||||
+
|
||||
+ retval = request_irq(ltq_port->tx_irq, lqasc_tx_int,
|
||||
+ IRQF_DISABLED, "asc_tx", port);
|
||||
+ if (retval) {
|
||||
+ pr_err("failed to request lqasc_tx_int\n");
|
||||
+ return retval;
|
||||
+ }
|
||||
+
|
||||
+ retval = request_irq(ltq_port->rx_irq, lqasc_rx_int,
|
||||
+ IRQF_DISABLED, "asc_rx", port);
|
||||
+ if (retval) {
|
||||
+ pr_err("failed to request lqasc_rx_int\n");
|
||||
+ goto err1;
|
||||
+ }
|
||||
+
|
||||
+ retval = request_irq(ltq_port->err_irq, lqasc_err_int,
|
||||
+ IRQF_DISABLED, "asc_err", port);
|
||||
+ if (retval) {
|
||||
+ pr_err("failed to request lqasc_err_int\n");
|
||||
+ goto err2;
|
||||
+ }
|
||||
+
|
||||
+ ltq_w32(ASC_IRNREN_RX | ASC_IRNREN_ERR | ASC_IRNREN_TX,
|
||||
+ port->membase + LTQ_ASC_IRNREN);
|
||||
+ return 0;
|
||||
+
|
||||
+err2:
|
||||
+ free_irq(ltq_port->rx_irq, port);
|
||||
+err1:
|
||||
+ free_irq(ltq_port->tx_irq, port);
|
||||
+ return retval;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+lqasc_shutdown(struct uart_port *port)
|
||||
+{
|
||||
+ struct ltq_uart_port *ltq_port = to_ltq_uart_port(port);
|
||||
+ free_irq(ltq_port->tx_irq, port);
|
||||
+ free_irq(ltq_port->rx_irq, port);
|
||||
+ free_irq(ltq_port->err_irq, port);
|
||||
+
|
||||
+ ltq_w32(0, port->membase + LTQ_ASC_CON);
|
||||
+ ltq_w32_mask(ASCRXFCON_RXFEN, ASCRXFCON_RXFFLU,
|
||||
+ port->membase + LTQ_ASC_RXFCON);
|
||||
+ ltq_w32_mask(ASCTXFCON_TXFEN, ASCTXFCON_TXFFLU,
|
||||
+ port->membase + LTQ_ASC_TXFCON);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+lqasc_set_termios(struct uart_port *port,
|
||||
+ struct ktermios *new, struct ktermios *old)
|
||||
+{
|
||||
+ unsigned int cflag;
|
||||
+ unsigned int iflag;
|
||||
+ unsigned int divisor;
|
||||
+ unsigned int baud;
|
||||
+ unsigned int con = 0;
|
||||
+ unsigned long flags;
|
||||
+
|
||||
+ cflag = new->c_cflag;
|
||||
+ iflag = new->c_iflag;
|
||||
+
|
||||
+ switch (cflag & CSIZE) {
|
||||
+ case CS7:
|
||||
+ con = ASCCON_M_7ASYNC;
|
||||
+ break;
|
||||
+
|
||||
+ case CS5:
|
||||
+ case CS6:
|
||||
+ default:
|
||||
+ new->c_cflag &= ~ CSIZE;
|
||||
+ new->c_cflag |= CS8;
|
||||
+ con = ASCCON_M_8ASYNC;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ cflag &= ~CMSPAR; /* Mark/Space parity is not supported */
|
||||
+
|
||||
+ if (cflag & CSTOPB)
|
||||
+ con |= ASCCON_STP;
|
||||
+
|
||||
+ if (cflag & PARENB) {
|
||||
+ if (!(cflag & PARODD))
|
||||
+ con &= ~ASCCON_ODD;
|
||||
+ else
|
||||
+ con |= ASCCON_ODD;
|
||||
+ }
|
||||
+
|
||||
+ port->read_status_mask = ASCSTATE_ROE;
|
||||
+ if (iflag & INPCK)
|
||||
+ port->read_status_mask |= ASCSTATE_FE | ASCSTATE_PE;
|
||||
+
|
||||
+ port->ignore_status_mask = 0;
|
||||
+ if (iflag & IGNPAR)
|
||||
+ port->ignore_status_mask |= ASCSTATE_FE | ASCSTATE_PE;
|
||||
+
|
||||
+ if (iflag & IGNBRK) {
|
||||
+ /*
|
||||
+ * If we're ignoring parity and break indicators,
|
||||
+ * ignore overruns too (for real raw support).
|
||||
+ */
|
||||
+ if (iflag & IGNPAR)
|
||||
+ port->ignore_status_mask |= ASCSTATE_ROE;
|
||||
+ }
|
||||
+
|
||||
+ if ((cflag & CREAD) == 0)
|
||||
+ port->ignore_status_mask |= UART_DUMMY_UER_RX;
|
||||
+
|
||||
+ /* set error signals - framing, parity and overrun, enable receiver */
|
||||
+ con |= ASCCON_FEN | ASCCON_TOEN | ASCCON_ROEN;
|
||||
+
|
||||
+ spin_lock_irqsave(<q_asc_lock, flags);
|
||||
+
|
||||
+ /* set up CON */
|
||||
+ ltq_w32_mask(0, con, port->membase + LTQ_ASC_CON);
|
||||
+
|
||||
+ /* Set baud rate - take a divider of 2 into account */
|
||||
+ baud = uart_get_baud_rate(port, new, old, 0, port->uartclk / 16);
|
||||
+ divisor = uart_get_divisor(port, baud);
|
||||
+ divisor = divisor / 2 - 1;
|
||||
+
|
||||
+ /* disable the baudrate generator */
|
||||
+ ltq_w32_mask(ASCCON_R, 0, port->membase + LTQ_ASC_CON);
|
||||
+
|
||||
+ /* make sure the fractional divider is off */
|
||||
+ ltq_w32_mask(ASCCON_FDE, 0, port->membase + LTQ_ASC_CON);
|
||||
+
|
||||
+ /* set up to use divisor of 2 */
|
||||
+ ltq_w32_mask(ASCCON_BRS, 0, port->membase + LTQ_ASC_CON);
|
||||
+
|
||||
+ /* now we can write the new baudrate into the register */
|
||||
+ ltq_w32(divisor, port->membase + LTQ_ASC_BG);
|
||||
+
|
||||
+ /* turn the baudrate generator back on */
|
||||
+ ltq_w32_mask(0, ASCCON_R, port->membase + LTQ_ASC_CON);
|
||||
+
|
||||
+ /* enable rx */
|
||||
+ ltq_w32(ASCWHBSTATE_SETREN, port->membase + LTQ_ASC_WHBSTATE);
|
||||
+
|
||||
+ spin_unlock_irqrestore(<q_asc_lock, flags);
|
||||
+
|
||||
+ /* Don't rewrite B0 */
|
||||
+ if (tty_termios_baud_rate(new))
|
||||
+ tty_termios_encode_baud_rate(new, baud, baud);
|
||||
+}
|
||||
+
|
||||
+static const char*
|
||||
+lqasc_type(struct uart_port *port)
|
||||
+{
|
||||
+ if (port->type == PORT_LTQ_ASC)
|
||||
+ return DRVNAME;
|
||||
+ else
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+lqasc_release_port(struct uart_port *port)
|
||||
+{
|
||||
+ if (port->flags & UPF_IOREMAP) {
|
||||
+ iounmap(port->membase);
|
||||
+ port->membase = NULL;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+lqasc_request_port(struct uart_port *port)
|
||||
+{
|
||||
+ struct platform_device *pdev = to_platform_device(port->dev);
|
||||
+ struct resource *res;
|
||||
+ int size;
|
||||
+
|
||||
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
+ if (!res) {
|
||||
+ dev_err(&pdev->dev, "cannot obtain I/O memory region");
|
||||
+ return -ENODEV;
|
||||
+ }
|
||||
+ size = resource_size(res);
|
||||
+
|
||||
+ res = devm_request_mem_region(&pdev->dev, res->start,
|
||||
+ size, dev_name(&pdev->dev));
|
||||
+ if (!res) {
|
||||
+ dev_err(&pdev->dev, "cannot request I/O memory region");
|
||||
+ return -EBUSY;
|
||||
+ }
|
||||
+
|
||||
+ if (port->flags & UPF_IOREMAP) {
|
||||
+ port->membase = devm_ioremap_nocache(&pdev->dev,
|
||||
+ port->mapbase, size);
|
||||
+ if (port->membase == NULL)
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+lqasc_config_port(struct uart_port *port, int flags)
|
||||
+{
|
||||
+ if (flags & UART_CONFIG_TYPE) {
|
||||
+ port->type = PORT_LTQ_ASC;
|
||||
+ lqasc_request_port(port);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+lqasc_verify_port(struct uart_port *port,
|
||||
+ struct serial_struct *ser)
|
||||
+{
|
||||
+ int ret = 0;
|
||||
+ if (ser->type != PORT_UNKNOWN && ser->type != PORT_LTQ_ASC)
|
||||
+ ret = -EINVAL;
|
||||
+ if (ser->irq < 0 || ser->irq >= NR_IRQS)
|
||||
+ ret = -EINVAL;
|
||||
+ if (ser->baud_base < 9600)
|
||||
+ ret = -EINVAL;
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static struct uart_ops lqasc_pops = {
|
||||
+ .tx_empty = lqasc_tx_empty,
|
||||
+ .set_mctrl = lqasc_set_mctrl,
|
||||
+ .get_mctrl = lqasc_get_mctrl,
|
||||
+ .stop_tx = lqasc_stop_tx,
|
||||
+ .start_tx = lqasc_start_tx,
|
||||
+ .stop_rx = lqasc_stop_rx,
|
||||
+ .enable_ms = lqasc_enable_ms,
|
||||
+ .break_ctl = lqasc_break_ctl,
|
||||
+ .startup = lqasc_startup,
|
||||
+ .shutdown = lqasc_shutdown,
|
||||
+ .set_termios = lqasc_set_termios,
|
||||
+ .type = lqasc_type,
|
||||
+ .release_port = lqasc_release_port,
|
||||
+ .request_port = lqasc_request_port,
|
||||
+ .config_port = lqasc_config_port,
|
||||
+ .verify_port = lqasc_verify_port,
|
||||
+};
|
||||
+
|
||||
+static void
|
||||
+lqasc_console_putchar(struct uart_port *port, int ch)
|
||||
+{
|
||||
+ int fifofree;
|
||||
+
|
||||
+ if (!port->membase)
|
||||
+ return;
|
||||
+
|
||||
+ do {
|
||||
+ fifofree = (ltq_r32(port->membase + LTQ_ASC_FSTAT)
|
||||
+ & ASCFSTAT_TXFREEMASK) >> ASCFSTAT_TXFREEOFF;
|
||||
+ } while (fifofree == 0);
|
||||
+ ltq_w8(ch, port->membase + LTQ_ASC_TBUF);
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static void
|
||||
+lqasc_console_write(struct console *co, const char *s, u_int count)
|
||||
+{
|
||||
+ struct ltq_uart_port *ltq_port;
|
||||
+ struct uart_port *port;
|
||||
+ unsigned long flags;
|
||||
+
|
||||
+ if (co->index >= MAXPORTS)
|
||||
+ return;
|
||||
+
|
||||
+ ltq_port = lqasc_port[co->index];
|
||||
+ if (!ltq_port)
|
||||
+ return;
|
||||
+
|
||||
+ port = <q_port->port;
|
||||
+
|
||||
+ spin_lock_irqsave(<q_asc_lock, flags);
|
||||
+ uart_console_write(port, s, count, lqasc_console_putchar);
|
||||
+ spin_unlock_irqrestore(<q_asc_lock, flags);
|
||||
+}
|
||||
+
|
||||
+static int __init
|
||||
+lqasc_console_setup(struct console *co, char *options)
|
||||
+{
|
||||
+ struct ltq_uart_port *ltq_port;
|
||||
+ struct uart_port *port;
|
||||
+ int baud = 115200;
|
||||
+ int bits = 8;
|
||||
+ int parity = 'n';
|
||||
+ int flow = 'n';
|
||||
+
|
||||
+ if (co->index >= MAXPORTS)
|
||||
+ return -ENODEV;
|
||||
+
|
||||
+ ltq_port = lqasc_port[co->index];
|
||||
+ if (!ltq_port)
|
||||
+ return -ENODEV;
|
||||
+
|
||||
+ port = <q_port->port;
|
||||
+
|
||||
+ port->uartclk = clk_get_rate(ltq_port->clk);
|
||||
+
|
||||
+ if (options)
|
||||
+ uart_parse_options(options, &baud, &parity, &bits, &flow);
|
||||
+ return uart_set_options(port, co, baud, parity, bits, flow);
|
||||
+}
|
||||
+
|
||||
+static struct console lqasc_console = {
|
||||
+ .name = "ttyLTQ",
|
||||
+ .write = lqasc_console_write,
|
||||
+ .device = uart_console_device,
|
||||
+ .setup = lqasc_console_setup,
|
||||
+ .flags = CON_PRINTBUFFER,
|
||||
+ .index = -1,
|
||||
+ .data = &lqasc_reg,
|
||||
+};
|
||||
+
|
||||
+static int __init
|
||||
+lqasc_console_init(void)
|
||||
+{
|
||||
+ register_console(&lqasc_console);
|
||||
+ return 0;
|
||||
+}
|
||||
+console_initcall(lqasc_console_init);
|
||||
+
|
||||
+static struct uart_driver lqasc_reg = {
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .driver_name = DRVNAME,
|
||||
+ .dev_name = "ttyLTQ",
|
||||
+ .major = 0,
|
||||
+ .minor = 0,
|
||||
+ .nr = MAXPORTS,
|
||||
+ .cons = &lqasc_console,
|
||||
+};
|
||||
+
|
||||
+static int __init
|
||||
+lqasc_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct ltq_uart_port *ltq_port;
|
||||
+ struct uart_port *port;
|
||||
+ struct resource *mmres, *irqres;
|
||||
+ int tx_irq, rx_irq, err_irq;
|
||||
+ struct clk *clk;
|
||||
+ int ret;
|
||||
+
|
||||
+ mmres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
+ irqres = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
|
||||
+ if (!mmres || !irqres)
|
||||
+ return -ENODEV;
|
||||
+
|
||||
+ if (pdev->id >= MAXPORTS)
|
||||
+ return -EBUSY;
|
||||
+
|
||||
+ if (lqasc_port[pdev->id] != NULL)
|
||||
+ return -EBUSY;
|
||||
+
|
||||
+ clk = clk_get(&pdev->dev, "fpi");
|
||||
+ if (IS_ERR(clk)) {
|
||||
+ pr_err("failed to get fpi clk\n");
|
||||
+ return -ENOENT;
|
||||
+ }
|
||||
+
|
||||
+ tx_irq = platform_get_irq_byname(pdev, "tx");
|
||||
+ rx_irq = platform_get_irq_byname(pdev, "rx");
|
||||
+ err_irq = platform_get_irq_byname(pdev, "err");
|
||||
+ if ((tx_irq < 0) | (rx_irq < 0) | (err_irq < 0))
|
||||
+ return -ENODEV;
|
||||
+
|
||||
+ ltq_port = kzalloc(sizeof(struct ltq_uart_port), GFP_KERNEL);
|
||||
+ if (!ltq_port)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ port = <q_port->port;
|
||||
+
|
||||
+ port->iotype = SERIAL_IO_MEM;
|
||||
+ port->flags = ASYNC_BOOT_AUTOCONF | UPF_IOREMAP;
|
||||
+ port->ops = &lqasc_pops;
|
||||
+ port->fifosize = 16;
|
||||
+ port->type = PORT_LTQ_ASC,
|
||||
+ port->line = pdev->id;
|
||||
+ port->dev = &pdev->dev;
|
||||
+
|
||||
+ port->irq = tx_irq; /* unused, just to be backward-compatibe */
|
||||
+ port->mapbase = mmres->start;
|
||||
+
|
||||
+ ltq_port->clk = clk;
|
||||
+
|
||||
+ ltq_port->tx_irq = tx_irq;
|
||||
+ ltq_port->rx_irq = rx_irq;
|
||||
+ ltq_port->err_irq = err_irq;
|
||||
+
|
||||
+ lqasc_port[pdev->id] = ltq_port;
|
||||
+ platform_set_drvdata(pdev, ltq_port);
|
||||
+
|
||||
+ ret = uart_add_one_port(&lqasc_reg, port);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static struct platform_driver lqasc_driver = {
|
||||
+ .driver = {
|
||||
+ .name = DRVNAME,
|
||||
+ .owner = THIS_MODULE,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+int __init
|
||||
+init_lqasc(void)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = uart_register_driver(&lqasc_reg);
|
||||
+ if (ret != 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = platform_driver_probe(&lqasc_driver, lqasc_probe);
|
||||
+ if (ret != 0)
|
||||
+ uart_unregister_driver(&lqasc_reg);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+module_init(init_lqasc);
|
||||
+
|
||||
+MODULE_DESCRIPTION("Lantiq serial port driver");
|
||||
+MODULE_LICENSE("GPL");
|
||||
--- a/drivers/tty/serial/Kconfig
|
||||
+++ b/drivers/tty/serial/Kconfig
|
||||
@@ -1391,6 +1391,14 @@ config SERIAL_OF_PLATFORM_NWPSERIAL_CONS
|
||||
help
|
||||
Support for Console on the NWP serial ports.
|
||||
|
||||
+config SERIAL_LANTIQ
|
||||
+ bool "Lantiq serial driver"
|
||||
+ depends on LANTIQ
|
||||
+ select SERIAL_CORE
|
||||
+ select SERIAL_CORE_CONSOLE
|
||||
+ help
|
||||
+ Support for console and UART on Lantiq SoCs.
|
||||
+
|
||||
config SERIAL_QE
|
||||
tristate "Freescale QUICC Engine serial port support"
|
||||
depends on QUICC_ENGINE
|
||||
--- a/drivers/tty/serial/Makefile
|
||||
+++ b/drivers/tty/serial/Makefile
|
||||
@@ -94,3 +94,4 @@ obj-$(CONFIG_SERIAL_IFX6X60) += ifx6x6
|
||||
obj-$(CONFIG_SERIAL_PCH_UART) += pch_uart.o
|
||||
obj-$(CONFIG_SERIAL_MSM_SMD) += msm_smd_tty.o
|
||||
obj-$(CONFIG_SERIAL_MXS_AUART) += mxs-auart.o
|
||||
+obj-$(CONFIG_SERIAL_LANTIQ) += lantiq.o
|
|
@ -1,372 +0,0 @@
|
|||
From bd620ec1ca053bab8ce2562968700e6f80e4ff83 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Fri, 6 May 2011 00:10:00 +0200
|
||||
Subject: [PATCH 10/13] MIPS: Lantiq: Add DMA support
|
||||
|
||||
This patch adds support for the DMA engine found inside the XWAY family of
|
||||
SoCs. The engine has 5 ports and 20 channels.
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
Signed-off-by: Ralph Hempel <ralph.hempel@lantiq.com>
|
||||
Cc: linux-mips@linux-mips.org
|
||||
Patchwork: https://patchwork.linux-mips.org/patch/2355/
|
||||
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
|
||||
---
|
||||
.../mips/include/asm/mach-lantiq/xway/lantiq_soc.h | 3 +-
|
||||
arch/mips/include/asm/mach-lantiq/xway/xway_dma.h | 60 +++++
|
||||
arch/mips/lantiq/xway/Makefile | 2 +-
|
||||
arch/mips/lantiq/xway/devices.h | 1 +
|
||||
arch/mips/lantiq/xway/dma.c | 253 ++++++++++++++++++++
|
||||
5 files changed, 317 insertions(+), 2 deletions(-)
|
||||
create mode 100644 arch/mips/include/asm/mach-lantiq/xway/xway_dma.h
|
||||
create mode 100644 arch/mips/lantiq/xway/dma.c
|
||||
|
||||
--- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
|
||||
+++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
|
||||
@@ -86,7 +86,8 @@
|
||||
#define LTQ_PPE32_SIZE 0x40000
|
||||
|
||||
/* DMA */
|
||||
-#define LTQ_DMA_BASE_ADDR 0xBE104100
|
||||
+#define LTQ_DMA_BASE_ADDR 0x1E104100
|
||||
+#define LTQ_DMA_SIZE 0x800
|
||||
|
||||
/* PCI */
|
||||
#define PCI_CR_BASE_ADDR 0x1E105400
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/include/asm/mach-lantiq/xway/xway_dma.h
|
||||
@@ -0,0 +1,60 @@
|
||||
+/*
|
||||
+ * This program is free software; you can redistribute it and/or modify it
|
||||
+ * under the terms of the GNU General Public License version 2 as published
|
||||
+ * by the Free Software Foundation.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License
|
||||
+ * along with this program; if not, write to the Free Software
|
||||
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
+ *
|
||||
+ * Copyright (C) 2011 John Crispin <blogic@openwrt.org>
|
||||
+ */
|
||||
+
|
||||
+#ifndef LTQ_DMA_H__
|
||||
+#define LTQ_DMA_H__
|
||||
+
|
||||
+#define LTQ_DESC_SIZE 0x08 /* each descriptor is 64bit */
|
||||
+#define LTQ_DESC_NUM 0x40 /* 64 descriptors / channel */
|
||||
+
|
||||
+#define LTQ_DMA_OWN BIT(31) /* owner bit */
|
||||
+#define LTQ_DMA_C BIT(30) /* complete bit */
|
||||
+#define LTQ_DMA_SOP BIT(29) /* start of packet */
|
||||
+#define LTQ_DMA_EOP BIT(28) /* end of packet */
|
||||
+#define LTQ_DMA_TX_OFFSET(x) ((x & 0x1f) << 23) /* data bytes offset */
|
||||
+#define LTQ_DMA_RX_OFFSET(x) ((x & 0x7) << 23) /* data bytes offset */
|
||||
+#define LTQ_DMA_SIZE_MASK (0xffff) /* the size field is 16 bit */
|
||||
+
|
||||
+struct ltq_dma_desc {
|
||||
+ u32 ctl;
|
||||
+ u32 addr;
|
||||
+};
|
||||
+
|
||||
+struct ltq_dma_channel {
|
||||
+ int nr; /* the channel number */
|
||||
+ int irq; /* the mapped irq */
|
||||
+ int desc; /* the current descriptor */
|
||||
+ struct ltq_dma_desc *desc_base; /* the descriptor base */
|
||||
+ int phys; /* physical addr */
|
||||
+};
|
||||
+
|
||||
+enum {
|
||||
+ DMA_PORT_ETOP = 0,
|
||||
+ DMA_PORT_DEU,
|
||||
+};
|
||||
+
|
||||
+extern void ltq_dma_enable_irq(struct ltq_dma_channel *ch);
|
||||
+extern void ltq_dma_disable_irq(struct ltq_dma_channel *ch);
|
||||
+extern void ltq_dma_ack_irq(struct ltq_dma_channel *ch);
|
||||
+extern void ltq_dma_open(struct ltq_dma_channel *ch);
|
||||
+extern void ltq_dma_close(struct ltq_dma_channel *ch);
|
||||
+extern void ltq_dma_alloc_tx(struct ltq_dma_channel *ch);
|
||||
+extern void ltq_dma_alloc_rx(struct ltq_dma_channel *ch);
|
||||
+extern void ltq_dma_free(struct ltq_dma_channel *ch);
|
||||
+extern void ltq_dma_init_port(int p);
|
||||
+
|
||||
+#endif
|
||||
--- a/arch/mips/lantiq/xway/Makefile
|
||||
+++ b/arch/mips/lantiq/xway/Makefile
|
||||
@@ -1,4 +1,4 @@
|
||||
-obj-y := pmu.o ebu.o reset.o gpio.o gpio_stp.o gpio_ebu.o devices.o
|
||||
+obj-y := pmu.o ebu.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
|
||||
--- a/arch/mips/lantiq/xway/devices.h
|
||||
+++ b/arch/mips/lantiq/xway/devices.h
|
||||
@@ -10,6 +10,7 @@
|
||||
#define _LTQ_DEVICES_XWAY_H__
|
||||
|
||||
#include "../devices.h"
|
||||
+#include <linux/phy.h>
|
||||
|
||||
extern void ltq_register_gpio(void);
|
||||
extern void ltq_register_gpio_stp(void);
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/lantiq/xway/dma.c
|
||||
@@ -0,0 +1,253 @@
|
||||
+/*
|
||||
+ * This program is free software; you can redistribute it and/or modify it
|
||||
+ * under the terms of the GNU General Public License version 2 as published
|
||||
+ * by the Free Software Foundation.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License
|
||||
+ * along with this program; if not, write to the Free Software
|
||||
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
+ *
|
||||
+ * Copyright (C) 2011 John Crispin <blogic@openwrt.org>
|
||||
+ */
|
||||
+
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/dma-mapping.h>
|
||||
+
|
||||
+#include <lantiq_soc.h>
|
||||
+#include <xway_dma.h>
|
||||
+
|
||||
+#define LTQ_DMA_CTRL 0x10
|
||||
+#define LTQ_DMA_CPOLL 0x14
|
||||
+#define LTQ_DMA_CS 0x18
|
||||
+#define LTQ_DMA_CCTRL 0x1C
|
||||
+#define LTQ_DMA_CDBA 0x20
|
||||
+#define LTQ_DMA_CDLEN 0x24
|
||||
+#define LTQ_DMA_CIS 0x28
|
||||
+#define LTQ_DMA_CIE 0x2C
|
||||
+#define LTQ_DMA_PS 0x40
|
||||
+#define LTQ_DMA_PCTRL 0x44
|
||||
+#define LTQ_DMA_IRNEN 0xf4
|
||||
+
|
||||
+#define DMA_DESCPT BIT(3) /* descriptor complete irq */
|
||||
+#define DMA_TX BIT(8) /* TX channel direction */
|
||||
+#define DMA_CHAN_ON BIT(0) /* channel on / off bit */
|
||||
+#define DMA_PDEN BIT(6) /* enable packet drop */
|
||||
+#define DMA_CHAN_RST BIT(1) /* channel on / off bit */
|
||||
+#define DMA_RESET BIT(0) /* channel on / off bit */
|
||||
+#define DMA_IRQ_ACK 0x7e /* IRQ status register */
|
||||
+#define DMA_POLL BIT(31) /* turn on channel polling */
|
||||
+#define DMA_CLK_DIV4 BIT(6) /* polling clock divider */
|
||||
+#define DMA_2W_BURST BIT(1) /* 2 word burst length */
|
||||
+#define DMA_MAX_CHANNEL 20 /* the soc has 20 channels */
|
||||
+#define DMA_ETOP_ENDIANESS (0xf << 8) /* endianess swap etop channels */
|
||||
+#define DMA_WEIGHT (BIT(17) | BIT(16)) /* default channel wheight */
|
||||
+
|
||||
+#define ltq_dma_r32(x) ltq_r32(ltq_dma_membase + (x))
|
||||
+#define ltq_dma_w32(x, y) ltq_w32(x, ltq_dma_membase + (y))
|
||||
+#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 void __iomem *ltq_dma_membase;
|
||||
+
|
||||
+void
|
||||
+ltq_dma_enable_irq(struct ltq_dma_channel *ch)
|
||||
+{
|
||||
+ unsigned long flags;
|
||||
+
|
||||
+ local_irq_save(flags);
|
||||
+ ltq_dma_w32(ch->nr, LTQ_DMA_CS);
|
||||
+ ltq_dma_w32_mask(0, 1 << ch->nr, LTQ_DMA_IRNEN);
|
||||
+ local_irq_restore(flags);
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(ltq_dma_enable_irq);
|
||||
+
|
||||
+void
|
||||
+ltq_dma_disable_irq(struct ltq_dma_channel *ch)
|
||||
+{
|
||||
+ unsigned long flags;
|
||||
+
|
||||
+ local_irq_save(flags);
|
||||
+ ltq_dma_w32(ch->nr, LTQ_DMA_CS);
|
||||
+ ltq_dma_w32_mask(1 << ch->nr, 0, LTQ_DMA_IRNEN);
|
||||
+ local_irq_restore(flags);
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(ltq_dma_disable_irq);
|
||||
+
|
||||
+void
|
||||
+ltq_dma_ack_irq(struct ltq_dma_channel *ch)
|
||||
+{
|
||||
+ unsigned long flags;
|
||||
+
|
||||
+ local_irq_save(flags);
|
||||
+ ltq_dma_w32(ch->nr, LTQ_DMA_CS);
|
||||
+ ltq_dma_w32(DMA_IRQ_ACK, LTQ_DMA_CIS);
|
||||
+ local_irq_restore(flags);
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(ltq_dma_ack_irq);
|
||||
+
|
||||
+void
|
||||
+ltq_dma_open(struct ltq_dma_channel *ch)
|
||||
+{
|
||||
+ unsigned long flag;
|
||||
+
|
||||
+ local_irq_save(flag);
|
||||
+ ltq_dma_w32(ch->nr, LTQ_DMA_CS);
|
||||
+ ltq_dma_w32_mask(0, DMA_CHAN_ON, LTQ_DMA_CCTRL);
|
||||
+ ltq_dma_enable_irq(ch);
|
||||
+ local_irq_restore(flag);
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(ltq_dma_open);
|
||||
+
|
||||
+void
|
||||
+ltq_dma_close(struct ltq_dma_channel *ch)
|
||||
+{
|
||||
+ unsigned long flag;
|
||||
+
|
||||
+ local_irq_save(flag);
|
||||
+ ltq_dma_w32(ch->nr, LTQ_DMA_CS);
|
||||
+ ltq_dma_w32_mask(DMA_CHAN_ON, 0, LTQ_DMA_CCTRL);
|
||||
+ ltq_dma_disable_irq(ch);
|
||||
+ local_irq_restore(flag);
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(ltq_dma_close);
|
||||
+
|
||||
+static void
|
||||
+ltq_dma_alloc(struct ltq_dma_channel *ch)
|
||||
+{
|
||||
+ unsigned long flags;
|
||||
+
|
||||
+ ch->desc = 0;
|
||||
+ ch->desc_base = dma_alloc_coherent(NULL,
|
||||
+ LTQ_DESC_NUM * LTQ_DESC_SIZE,
|
||||
+ &ch->phys, GFP_ATOMIC);
|
||||
+ memset(ch->desc_base, 0, LTQ_DESC_NUM * LTQ_DESC_SIZE);
|
||||
+
|
||||
+ local_irq_save(flags);
|
||||
+ ltq_dma_w32(ch->nr, LTQ_DMA_CS);
|
||||
+ ltq_dma_w32(ch->phys, LTQ_DMA_CDBA);
|
||||
+ ltq_dma_w32(LTQ_DESC_NUM, LTQ_DMA_CDLEN);
|
||||
+ ltq_dma_w32_mask(DMA_CHAN_ON, 0, LTQ_DMA_CCTRL);
|
||||
+ wmb();
|
||||
+ ltq_dma_w32_mask(0, DMA_CHAN_RST, LTQ_DMA_CCTRL);
|
||||
+ while (ltq_dma_r32(LTQ_DMA_CCTRL) & DMA_CHAN_RST)
|
||||
+ ;
|
||||
+ local_irq_restore(flags);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+ltq_dma_alloc_tx(struct ltq_dma_channel *ch)
|
||||
+{
|
||||
+ unsigned long flags;
|
||||
+
|
||||
+ ltq_dma_alloc(ch);
|
||||
+
|
||||
+ local_irq_save(flags);
|
||||
+ ltq_dma_w32(DMA_DESCPT, LTQ_DMA_CIE);
|
||||
+ ltq_dma_w32_mask(0, 1 << ch->nr, LTQ_DMA_IRNEN);
|
||||
+ ltq_dma_w32(DMA_WEIGHT | DMA_TX, LTQ_DMA_CCTRL);
|
||||
+ local_irq_restore(flags);
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(ltq_dma_alloc_tx);
|
||||
+
|
||||
+void
|
||||
+ltq_dma_alloc_rx(struct ltq_dma_channel *ch)
|
||||
+{
|
||||
+ unsigned long flags;
|
||||
+
|
||||
+ ltq_dma_alloc(ch);
|
||||
+
|
||||
+ local_irq_save(flags);
|
||||
+ ltq_dma_w32(DMA_DESCPT, LTQ_DMA_CIE);
|
||||
+ ltq_dma_w32_mask(0, 1 << ch->nr, LTQ_DMA_IRNEN);
|
||||
+ ltq_dma_w32(DMA_WEIGHT, LTQ_DMA_CCTRL);
|
||||
+ local_irq_restore(flags);
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(ltq_dma_alloc_rx);
|
||||
+
|
||||
+void
|
||||
+ltq_dma_free(struct ltq_dma_channel *ch)
|
||||
+{
|
||||
+ if (!ch->desc_base)
|
||||
+ return;
|
||||
+ ltq_dma_close(ch);
|
||||
+ dma_free_coherent(NULL, LTQ_DESC_NUM * LTQ_DESC_SIZE,
|
||||
+ ch->desc_base, ch->phys);
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(ltq_dma_free);
|
||||
+
|
||||
+void
|
||||
+ltq_dma_init_port(int p)
|
||||
+{
|
||||
+ ltq_dma_w32(p, LTQ_DMA_PS);
|
||||
+ switch (p) {
|
||||
+ case DMA_PORT_ETOP:
|
||||
+ /*
|
||||
+ * Tell the DMA engine to swap the endianess of data frames and
|
||||
+ * drop packets if the channel arbitration fails.
|
||||
+ */
|
||||
+ ltq_dma_w32_mask(0, DMA_ETOP_ENDIANESS | DMA_PDEN,
|
||||
+ LTQ_DMA_PCTRL);
|
||||
+ break;
|
||||
+
|
||||
+ case DMA_PORT_DEU:
|
||||
+ ltq_dma_w32((DMA_2W_BURST << 4) | (DMA_2W_BURST << 2),
|
||||
+ LTQ_DMA_PCTRL);
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(ltq_dma_init_port);
|
||||
+
|
||||
+int __init
|
||||
+ltq_dma_init(void)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ /* insert and request the memory region */
|
||||
+ if (insert_resource(&iomem_resource, <q_dma_resource) < 0)
|
||||
+ panic("Failed to insert dma memory\n");
|
||||
+
|
||||
+ if (request_mem_region(ltq_dma_resource.start,
|
||||
+ resource_size(<q_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(<q_dma_resource));
|
||||
+ if (!ltq_dma_membase)
|
||||
+ panic("Failed to remap dma memory\n");
|
||||
+
|
||||
+ /* power up and reset the dma engine */
|
||||
+ ltq_pmu_enable(PMU_DMA);
|
||||
+ ltq_dma_w32_mask(0, DMA_RESET, LTQ_DMA_CTRL);
|
||||
+
|
||||
+ /* disable all interrupts */
|
||||
+ ltq_dma_w32(0, LTQ_DMA_IRNEN);
|
||||
+
|
||||
+ /* reset/configure each channel */
|
||||
+ for (i = 0; i < DMA_MAX_CHANNEL; i++) {
|
||||
+ ltq_dma_w32(i, LTQ_DMA_CS);
|
||||
+ ltq_dma_w32(DMA_CHAN_RST, LTQ_DMA_CCTRL);
|
||||
+ ltq_dma_w32(DMA_POLL | DMA_CLK_DIV4, LTQ_DMA_CPOLL);
|
||||
+ ltq_dma_w32_mask(DMA_CHAN_ON, 0, LTQ_DMA_CCTRL);
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+postcore_initcall(ltq_dma_init);
|
|
@ -1,942 +0,0 @@
|
|||
From 435de86088af82496bcba69165cd7422bb4622ec Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Fri, 6 May 2011 00:10:01 +0200
|
||||
Subject: [PATCH 11/13] MIPS: Lantiq: Add ethernet driver
|
||||
|
||||
This patch adds the driver for the ETOP Packet Processing Engine (PPE32)
|
||||
found inside the XWAY family of Lantiq MIPS SoCs. This driver makes 100MBit
|
||||
ethernet work. Support for all 8 dma channels, gbit and the embedded switch
|
||||
found on the ar9/vr9 still needs to be implemented.
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
Signed-off-by: Ralph Hempel <ralph.hempel@lantiq.com>
|
||||
Cc: linux-mips@linux-mips.org
|
||||
Cc: netdev@vger.kernel.org
|
||||
Patchwork: https://patchwork.linux-mips.org/patch/2357/
|
||||
Acked-by: David S. Miller <davem@davemloft.net>
|
||||
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
|
||||
---
|
||||
.../mips/include/asm/mach-lantiq/lantiq_platform.h | 7 +
|
||||
.../mips/include/asm/mach-lantiq/xway/lantiq_soc.h | 4 +-
|
||||
arch/mips/lantiq/xway/devices.c | 23 +
|
||||
arch/mips/lantiq/xway/devices.h | 1 +
|
||||
drivers/net/Kconfig | 7 +
|
||||
drivers/net/Makefile | 1 +
|
||||
drivers/net/lantiq_etop.c | 805 ++++++++++++++++++++
|
||||
7 files changed, 846 insertions(+), 2 deletions(-)
|
||||
create mode 100644 drivers/net/lantiq_etop.c
|
||||
|
||||
--- a/arch/mips/include/asm/mach-lantiq/lantiq_platform.h
|
||||
+++ b/arch/mips/include/asm/mach-lantiq/lantiq_platform.h
|
||||
@@ -10,6 +10,7 @@
|
||||
#define _LANTIQ_PLATFORM_H__
|
||||
|
||||
#include <linux/mtd/partitions.h>
|
||||
+#include <linux/socket.h>
|
||||
|
||||
/* struct used to pass info to the pci core */
|
||||
enum {
|
||||
@@ -43,4 +44,10 @@ struct ltq_pci_data {
|
||||
int irq[16];
|
||||
};
|
||||
|
||||
+/* struct used to pass info to network drivers */
|
||||
+struct ltq_eth_data {
|
||||
+ struct sockaddr mac;
|
||||
+ int mii_mode;
|
||||
+};
|
||||
+
|
||||
#endif
|
||||
--- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
|
||||
+++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
|
||||
@@ -82,8 +82,8 @@
|
||||
#define PMU_SWITCH 0x10000000
|
||||
|
||||
/* ETOP - ethernet */
|
||||
-#define LTQ_PPE32_BASE_ADDR 0xBE180000
|
||||
-#define LTQ_PPE32_SIZE 0x40000
|
||||
+#define LTQ_ETOP_BASE_ADDR 0x1E180000
|
||||
+#define LTQ_ETOP_SIZE 0x40000
|
||||
|
||||
/* DMA */
|
||||
#define LTQ_DMA_BASE_ADDR 0x1E104100
|
||||
--- a/arch/mips/lantiq/xway/devices.c
|
||||
+++ b/arch/mips/lantiq/xway/devices.c
|
||||
@@ -96,3 +96,26 @@ void __init ltq_register_ase_asc(void)
|
||||
platform_device_register_simple("ltq_asc", 0,
|
||||
ltq_ase_asc_resources, ARRAY_SIZE(ltq_ase_asc_resources));
|
||||
}
|
||||
+
|
||||
+/* 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 platform_device ltq_etop = {
|
||||
+ .name = "ltq_etop",
|
||||
+ .resource = <q_etop_resources,
|
||||
+ .num_resources = 1,
|
||||
+};
|
||||
+
|
||||
+void __init
|
||||
+ltq_register_etop(struct ltq_eth_data *eth)
|
||||
+{
|
||||
+ if (eth) {
|
||||
+ ltq_etop.dev.platform_data = eth;
|
||||
+ platform_device_register(<q_etop);
|
||||
+ }
|
||||
+}
|
||||
--- a/arch/mips/lantiq/xway/devices.h
|
||||
+++ b/arch/mips/lantiq/xway/devices.h
|
||||
@@ -15,5 +15,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);
|
||||
|
||||
#endif
|
||||
--- a/drivers/net/Kconfig
|
||||
+++ b/drivers/net/Kconfig
|
||||
@@ -2017,6 +2017,13 @@ config FTMAC100
|
||||
from Faraday. It is used on Faraday A320, Andes AG101 and some
|
||||
other ARM/NDS32 SoC's.
|
||||
|
||||
+config LANTIQ_ETOP
|
||||
+ tristate "Lantiq SoC ETOP driver"
|
||||
+ depends on SOC_TYPE_XWAY
|
||||
+ help
|
||||
+ Support for the MII0 inside the Lantiq SoC
|
||||
+
|
||||
+
|
||||
source "drivers/net/fs_enet/Kconfig"
|
||||
|
||||
source "drivers/net/octeon/Kconfig"
|
||||
--- a/drivers/net/Makefile
|
||||
+++ b/drivers/net/Makefile
|
||||
@@ -259,6 +259,7 @@ obj-$(CONFIG_MLX4_CORE) += mlx4/
|
||||
obj-$(CONFIG_ENC28J60) += enc28j60.o
|
||||
obj-$(CONFIG_ETHOC) += ethoc.o
|
||||
obj-$(CONFIG_GRETH) += greth.o
|
||||
+obj-$(CONFIG_LANTIQ_ETOP) += lantiq_etop.o
|
||||
|
||||
obj-$(CONFIG_XTENSA_XT2000_SONIC) += xtsonic.o
|
||||
|
||||
--- /dev/null
|
||||
+++ b/drivers/net/lantiq_etop.c
|
||||
@@ -0,0 +1,813 @@
|
||||
+/*
|
||||
+ * This program is free software; you can redistribute it and/or modify it
|
||||
+ * under the terms of the GNU General Public License version 2 as published
|
||||
+ * by the Free Software Foundation.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License
|
||||
+ * along with this program; if not, write to the Free Software
|
||||
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
+ *
|
||||
+ * Copyright (C) 2011 John Crispin <blogic@openwrt.org>
|
||||
+ */
|
||||
+
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/slab.h>
|
||||
+#include <linux/errno.h>
|
||||
+#include <linux/types.h>
|
||||
+#include <linux/interrupt.h>
|
||||
+#include <linux/uaccess.h>
|
||||
+#include <linux/in.h>
|
||||
+#include <linux/netdevice.h>
|
||||
+#include <linux/etherdevice.h>
|
||||
+#include <linux/phy.h>
|
||||
+#include <linux/ip.h>
|
||||
+#include <linux/tcp.h>
|
||||
+#include <linux/skbuff.h>
|
||||
+#include <linux/mm.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/ethtool.h>
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/delay.h>
|
||||
+#include <linux/io.h>
|
||||
+
|
||||
+#include <asm/checksum.h>
|
||||
+
|
||||
+#include <lantiq_soc.h>
|
||||
+#include <xway_dma.h>
|
||||
+#include <lantiq_platform.h>
|
||||
+
|
||||
+#define LTQ_ETOP_MDIO 0x11804
|
||||
+#define MDIO_REQUEST 0x80000000
|
||||
+#define MDIO_READ 0x40000000
|
||||
+#define MDIO_ADDR_MASK 0x1f
|
||||
+#define MDIO_ADDR_OFFSET 0x15
|
||||
+#define MDIO_REG_MASK 0x1f
|
||||
+#define MDIO_REG_OFFSET 0x10
|
||||
+#define MDIO_VAL_MASK 0xffff
|
||||
+
|
||||
+#define PPE32_CGEN 0x800
|
||||
+#define LTQ_PPE32_ENET_MAC_CFG 0x1840
|
||||
+
|
||||
+#define LTQ_ETOP_ENETS0 0x11850
|
||||
+#define LTQ_ETOP_MAC_DA0 0x1186C
|
||||
+#define LTQ_ETOP_MAC_DA1 0x11870
|
||||
+#define LTQ_ETOP_CFG 0x16020
|
||||
+#define LTQ_ETOP_IGPLEN 0x16080
|
||||
+
|
||||
+#define MAX_DMA_CHAN 0x8
|
||||
+#define MAX_DMA_CRC_LEN 0x4
|
||||
+#define MAX_DMA_DATA_LEN 0x600
|
||||
+
|
||||
+#define ETOP_FTCU BIT(28)
|
||||
+#define ETOP_MII_MASK 0xf
|
||||
+#define ETOP_MII_NORMAL 0xd
|
||||
+#define ETOP_MII_REVERSE 0xe
|
||||
+#define ETOP_PLEN_UNDER 0x40
|
||||
+#define ETOP_CGEN 0x800
|
||||
+
|
||||
+/* use 2 static channels for TX/RX */
|
||||
+#define LTQ_ETOP_TX_CHANNEL 1
|
||||
+#define LTQ_ETOP_RX_CHANNEL 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) \
|
||||
+ ltq_w32_mask(x, y, ltq_etop_membase + (z))
|
||||
+
|
||||
+#define DRV_VERSION "1.0"
|
||||
+
|
||||
+#ifndef netdev_err
|
||||
+#define netdev_err(a, b, ...) printk(b, ##__VA_ARGS__)
|
||||
+#endif
|
||||
+
|
||||
+#ifndef pr_warn
|
||||
+#define pr_warn pr_warning
|
||||
+#endif
|
||||
+
|
||||
+static void __iomem *ltq_etop_membase;
|
||||
+
|
||||
+struct ltq_etop_chan {
|
||||
+ int idx;
|
||||
+ int tx_free;
|
||||
+ struct net_device *netdev;
|
||||
+ struct napi_struct napi;
|
||||
+ struct ltq_dma_channel dma;
|
||||
+ struct sk_buff *skb[LTQ_DESC_NUM];
|
||||
+};
|
||||
+
|
||||
+struct ltq_etop_priv {
|
||||
+ struct net_device *netdev;
|
||||
+ struct ltq_eth_data *pldata;
|
||||
+ struct resource *res;
|
||||
+
|
||||
+ struct mii_bus *mii_bus;
|
||||
+ struct phy_device *phydev;
|
||||
+
|
||||
+ struct ltq_etop_chan ch[MAX_DMA_CHAN];
|
||||
+ int tx_free[MAX_DMA_CHAN >> 1];
|
||||
+
|
||||
+ spinlock_t lock;
|
||||
+};
|
||||
+
|
||||
+static int
|
||||
+ltq_etop_alloc_skb(struct ltq_etop_chan *ch)
|
||||
+{
|
||||
+ ch->skb[ch->dma.desc] = dev_alloc_skb(MAX_DMA_DATA_LEN);
|
||||
+ if (!ch->skb[ch->dma.desc])
|
||||
+ return -ENOMEM;
|
||||
+ ch->dma.desc_base[ch->dma.desc].addr = dma_map_single(NULL,
|
||||
+ ch->skb[ch->dma.desc]->data, MAX_DMA_DATA_LEN,
|
||||
+ DMA_FROM_DEVICE);
|
||||
+ ch->dma.desc_base[ch->dma.desc].addr =
|
||||
+ CPHYSADDR(ch->skb[ch->dma.desc]->data);
|
||||
+ ch->dma.desc_base[ch->dma.desc].ctl =
|
||||
+ LTQ_DMA_OWN | LTQ_DMA_RX_OFFSET(NET_IP_ALIGN) |
|
||||
+ MAX_DMA_DATA_LEN;
|
||||
+ skb_reserve(ch->skb[ch->dma.desc], NET_IP_ALIGN);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+ltq_etop_hw_receive(struct ltq_etop_chan *ch)
|
||||
+{
|
||||
+ struct ltq_etop_priv *priv = netdev_priv(ch->netdev);
|
||||
+ struct ltq_dma_desc *desc = &ch->dma.desc_base[ch->dma.desc];
|
||||
+ struct sk_buff *skb = ch->skb[ch->dma.desc];
|
||||
+ int len = (desc->ctl & LTQ_DMA_SIZE_MASK) - MAX_DMA_CRC_LEN;
|
||||
+ unsigned long flags;
|
||||
+
|
||||
+ spin_lock_irqsave(&priv->lock, flags);
|
||||
+ if (ltq_etop_alloc_skb(ch)) {
|
||||
+ netdev_err(ch->netdev,
|
||||
+ "failed to allocate new rx buffer, stopping DMA\n");
|
||||
+ ltq_dma_close(&ch->dma);
|
||||
+ }
|
||||
+ ch->dma.desc++;
|
||||
+ ch->dma.desc %= LTQ_DESC_NUM;
|
||||
+ spin_unlock_irqrestore(&priv->lock, flags);
|
||||
+
|
||||
+ skb_put(skb, len);
|
||||
+ skb->dev = ch->netdev;
|
||||
+ skb->protocol = eth_type_trans(skb, ch->netdev);
|
||||
+ netif_receive_skb(skb);
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+ltq_etop_poll_rx(struct napi_struct *napi, int budget)
|
||||
+{
|
||||
+ struct ltq_etop_chan *ch = container_of(napi,
|
||||
+ struct ltq_etop_chan, napi);
|
||||
+ int rx = 0;
|
||||
+ int complete = 0;
|
||||
+
|
||||
+ while ((rx < budget) && !complete) {
|
||||
+ struct ltq_dma_desc *desc = &ch->dma.desc_base[ch->dma.desc];
|
||||
+
|
||||
+ if ((desc->ctl & (LTQ_DMA_OWN | LTQ_DMA_C)) == LTQ_DMA_C) {
|
||||
+ ltq_etop_hw_receive(ch);
|
||||
+ rx++;
|
||||
+ } else {
|
||||
+ complete = 1;
|
||||
+ }
|
||||
+ }
|
||||
+ if (complete || !rx) {
|
||||
+ napi_complete(&ch->napi);
|
||||
+ ltq_dma_ack_irq(&ch->dma);
|
||||
+ }
|
||||
+ return rx;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+ltq_etop_poll_tx(struct napi_struct *napi, int budget)
|
||||
+{
|
||||
+ struct ltq_etop_chan *ch =
|
||||
+ 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);
|
||||
+ unsigned long flags;
|
||||
+
|
||||
+ spin_lock_irqsave(&priv->lock, flags);
|
||||
+ while ((ch->dma.desc_base[ch->tx_free].ctl &
|
||||
+ (LTQ_DMA_OWN | LTQ_DMA_C)) == LTQ_DMA_C) {
|
||||
+ dev_kfree_skb_any(ch->skb[ch->tx_free]);
|
||||
+ ch->skb[ch->tx_free] = NULL;
|
||||
+ memset(&ch->dma.desc_base[ch->tx_free], 0,
|
||||
+ sizeof(struct ltq_dma_desc));
|
||||
+ ch->tx_free++;
|
||||
+ ch->tx_free %= LTQ_DESC_NUM;
|
||||
+ }
|
||||
+ spin_unlock_irqrestore(&priv->lock, flags);
|
||||
+
|
||||
+ if (netif_tx_queue_stopped(txq))
|
||||
+ netif_tx_start_queue(txq);
|
||||
+ napi_complete(&ch->napi);
|
||||
+ ltq_dma_ack_irq(&ch->dma);
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
+static irqreturn_t
|
||||
+ltq_etop_dma_irq(int irq, void *_priv)
|
||||
+{
|
||||
+ struct ltq_etop_priv *priv = _priv;
|
||||
+ int ch = irq - LTQ_DMA_CH0_INT;
|
||||
+
|
||||
+ napi_schedule(&priv->ch[ch].napi);
|
||||
+ return IRQ_HANDLED;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+ltq_etop_free_channel(struct net_device *dev, struct ltq_etop_chan *ch)
|
||||
+{
|
||||
+ struct ltq_etop_priv *priv = netdev_priv(dev);
|
||||
+
|
||||
+ ltq_dma_free(&ch->dma);
|
||||
+ if (ch->dma.irq)
|
||||
+ free_irq(ch->dma.irq, priv);
|
||||
+ if (IS_RX(ch->idx)) {
|
||||
+ int desc;
|
||||
+ for (desc = 0; desc < LTQ_DESC_NUM; desc++)
|
||||
+ dev_kfree_skb_any(ch->skb[ch->dma.desc]);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+ltq_etop_hw_exit(struct net_device *dev)
|
||||
+{
|
||||
+ struct ltq_etop_priv *priv = netdev_priv(dev);
|
||||
+ int i;
|
||||
+
|
||||
+ ltq_pmu_disable(PMU_PPE);
|
||||
+ for (i = 0; i < MAX_DMA_CHAN; i++)
|
||||
+ if (IS_TX(i) || IS_RX(i))
|
||||
+ ltq_etop_free_channel(dev, &priv->ch[i]);
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+ltq_etop_hw_init(struct net_device *dev)
|
||||
+{
|
||||
+ struct ltq_etop_priv *priv = netdev_priv(dev);
|
||||
+ int i;
|
||||
+
|
||||
+ ltq_pmu_enable(PMU_PPE);
|
||||
+
|
||||
+ switch (priv->pldata->mii_mode) {
|
||||
+ case PHY_INTERFACE_MODE_RMII:
|
||||
+ ltq_etop_w32_mask(ETOP_MII_MASK,
|
||||
+ ETOP_MII_REVERSE, LTQ_ETOP_CFG);
|
||||
+ break;
|
||||
+
|
||||
+ case PHY_INTERFACE_MODE_MII:
|
||||
+ ltq_etop_w32_mask(ETOP_MII_MASK,
|
||||
+ ETOP_MII_NORMAL, LTQ_ETOP_CFG);
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ netdev_err(dev, "unknown mii mode %d\n",
|
||||
+ priv->pldata->mii_mode);
|
||||
+ return -ENOTSUPP;
|
||||
+ }
|
||||
+
|
||||
+ /* enable crc generation */
|
||||
+ ltq_etop_w32(PPE32_CGEN, LTQ_PPE32_ENET_MAC_CFG);
|
||||
+
|
||||
+ ltq_dma_init_port(DMA_PORT_ETOP);
|
||||
+
|
||||
+ for (i = 0; i < MAX_DMA_CHAN; i++) {
|
||||
+ int irq = LTQ_DMA_CH0_INT + 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);
|
||||
+ 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;
|
||||
+ ch->dma.desc = 0;
|
||||
+ request_irq(irq, ltq_etop_dma_irq, IRQF_DISABLED,
|
||||
+ "etop_rx", priv);
|
||||
+ }
|
||||
+ ch->dma.irq = irq;
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+ltq_etop_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
|
||||
+{
|
||||
+ strcpy(info->driver, "Lantiq ETOP");
|
||||
+ strcpy(info->bus_info, "internal");
|
||||
+ strcpy(info->version, DRV_VERSION);
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+ltq_etop_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
|
||||
+{
|
||||
+ struct ltq_etop_priv *priv = netdev_priv(dev);
|
||||
+
|
||||
+ return phy_ethtool_gset(priv->phydev, cmd);
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+ltq_etop_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
|
||||
+{
|
||||
+ struct ltq_etop_priv *priv = netdev_priv(dev);
|
||||
+
|
||||
+ return phy_ethtool_sset(priv->phydev, cmd);
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+ltq_etop_nway_reset(struct net_device *dev)
|
||||
+{
|
||||
+ struct ltq_etop_priv *priv = netdev_priv(dev);
|
||||
+
|
||||
+ return phy_start_aneg(priv->phydev);
|
||||
+}
|
||||
+
|
||||
+static const struct ethtool_ops ltq_etop_ethtool_ops = {
|
||||
+ .get_drvinfo = ltq_etop_get_drvinfo,
|
||||
+ .get_settings = ltq_etop_get_settings,
|
||||
+ .set_settings = ltq_etop_set_settings,
|
||||
+ .nway_reset = ltq_etop_nway_reset,
|
||||
+};
|
||||
+
|
||||
+static int
|
||||
+ltq_etop_mdio_wr(struct mii_bus *bus, int phy_addr, int phy_reg, u16 phy_data)
|
||||
+{
|
||||
+ u32 val = MDIO_REQUEST |
|
||||
+ ((phy_addr & MDIO_ADDR_MASK) << MDIO_ADDR_OFFSET) |
|
||||
+ ((phy_reg & MDIO_REG_MASK) << MDIO_REG_OFFSET) |
|
||||
+ phy_data;
|
||||
+
|
||||
+ while (ltq_etop_r32(LTQ_ETOP_MDIO) & MDIO_REQUEST)
|
||||
+ ;
|
||||
+ ltq_etop_w32(val, LTQ_ETOP_MDIO);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+ltq_etop_mdio_rd(struct mii_bus *bus, int phy_addr, int phy_reg)
|
||||
+{
|
||||
+ u32 val = MDIO_REQUEST | MDIO_READ |
|
||||
+ ((phy_addr & MDIO_ADDR_MASK) << MDIO_ADDR_OFFSET) |
|
||||
+ ((phy_reg & MDIO_REG_MASK) << MDIO_REG_OFFSET);
|
||||
+
|
||||
+ while (ltq_etop_r32(LTQ_ETOP_MDIO) & MDIO_REQUEST)
|
||||
+ ;
|
||||
+ ltq_etop_w32(val, LTQ_ETOP_MDIO);
|
||||
+ while (ltq_etop_r32(LTQ_ETOP_MDIO) & MDIO_REQUEST)
|
||||
+ ;
|
||||
+ val = ltq_etop_r32(LTQ_ETOP_MDIO) & MDIO_VAL_MASK;
|
||||
+ return val;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+ltq_etop_mdio_link(struct net_device *dev)
|
||||
+{
|
||||
+ /* nothing to do */
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+ltq_etop_mdio_probe(struct net_device *dev)
|
||||
+{
|
||||
+ 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 (!phydev) {
|
||||
+ netdev_err(dev, "no PHY found\n");
|
||||
+ return -ENODEV;
|
||||
+ }
|
||||
+
|
||||
+ phydev = phy_connect(dev, dev_name(&phydev->dev), <q_etop_mdio_link,
|
||||
+ 0, priv->pldata->mii_mode);
|
||||
+
|
||||
+ if (IS_ERR(phydev)) {
|
||||
+ netdev_err(dev, "Could not attach to PHY\n");
|
||||
+ return PTR_ERR(phydev);
|
||||
+ }
|
||||
+
|
||||
+ phydev->supported &= (SUPPORTED_10baseT_Half
|
||||
+ | SUPPORTED_10baseT_Full
|
||||
+ | SUPPORTED_100baseT_Half
|
||||
+ | SUPPORTED_100baseT_Full
|
||||
+ | SUPPORTED_Autoneg
|
||||
+ | SUPPORTED_MII
|
||||
+ | SUPPORTED_TP);
|
||||
+
|
||||
+ phydev->advertising = phydev->supported;
|
||||
+ priv->phydev = phydev;
|
||||
+ pr_info("%s: attached PHY [%s] (phy_addr=%s, irq=%d)\n",
|
||||
+ dev->name, phydev->drv->name,
|
||||
+ dev_name(&phydev->dev), phydev->irq);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+ltq_etop_mdio_init(struct net_device *dev)
|
||||
+{
|
||||
+ struct ltq_etop_priv *priv = netdev_priv(dev);
|
||||
+ int i;
|
||||
+ int err;
|
||||
+
|
||||
+ priv->mii_bus = mdiobus_alloc();
|
||||
+ if (!priv->mii_bus) {
|
||||
+ netdev_err(dev, "failed to allocate mii bus\n");
|
||||
+ err = -ENOMEM;
|
||||
+ goto err_out;
|
||||
+ }
|
||||
+
|
||||
+ priv->mii_bus->priv = dev;
|
||||
+ 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);
|
||||
+ if (!priv->mii_bus->irq) {
|
||||
+ err = -ENOMEM;
|
||||
+ goto err_out_free_mdiobus;
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < PHY_MAX_ADDR; ++i)
|
||||
+ priv->mii_bus->irq[i] = PHY_POLL;
|
||||
+
|
||||
+ if (mdiobus_register(priv->mii_bus)) {
|
||||
+ err = -ENXIO;
|
||||
+ goto err_out_free_mdio_irq;
|
||||
+ }
|
||||
+
|
||||
+ if (ltq_etop_mdio_probe(dev)) {
|
||||
+ err = -ENXIO;
|
||||
+ goto err_out_unregister_bus;
|
||||
+ }
|
||||
+ return 0;
|
||||
+
|
||||
+err_out_unregister_bus:
|
||||
+ mdiobus_unregister(priv->mii_bus);
|
||||
+err_out_free_mdio_irq:
|
||||
+ kfree(priv->mii_bus->irq);
|
||||
+err_out_free_mdiobus:
|
||||
+ mdiobus_free(priv->mii_bus);
|
||||
+err_out:
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+ltq_etop_mdio_cleanup(struct net_device *dev)
|
||||
+{
|
||||
+ struct ltq_etop_priv *priv = netdev_priv(dev);
|
||||
+
|
||||
+ phy_disconnect(priv->phydev);
|
||||
+ mdiobus_unregister(priv->mii_bus);
|
||||
+ kfree(priv->mii_bus->irq);
|
||||
+ mdiobus_free(priv->mii_bus);
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+ltq_etop_open(struct net_device *dev)
|
||||
+{
|
||||
+ struct ltq_etop_priv *priv = netdev_priv(dev);
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < MAX_DMA_CHAN; i++) {
|
||||
+ struct ltq_etop_chan *ch = &priv->ch[i];
|
||||
+
|
||||
+ if (!IS_TX(i) && (!IS_RX(i)))
|
||||
+ continue;
|
||||
+ ltq_dma_open(&ch->dma);
|
||||
+ napi_enable(&ch->napi);
|
||||
+ }
|
||||
+ phy_start(priv->phydev);
|
||||
+ netif_tx_start_all_queues(dev);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+ltq_etop_stop(struct net_device *dev)
|
||||
+{
|
||||
+ struct ltq_etop_priv *priv = netdev_priv(dev);
|
||||
+ int i;
|
||||
+
|
||||
+ netif_tx_stop_all_queues(dev);
|
||||
+ phy_stop(priv->phydev);
|
||||
+ for (i = 0; i < MAX_DMA_CHAN; i++) {
|
||||
+ struct ltq_etop_chan *ch = &priv->ch[i];
|
||||
+
|
||||
+ if (!IS_RX(i) && !IS_TX(i))
|
||||
+ continue;
|
||||
+ napi_disable(&ch->napi);
|
||||
+ ltq_dma_close(&ch->dma);
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+ltq_etop_tx(struct sk_buff *skb, struct net_device *dev)
|
||||
+{
|
||||
+ 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];
|
||||
+ int len;
|
||||
+ unsigned long flags;
|
||||
+ u32 byte_offset;
|
||||
+
|
||||
+ 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);
|
||||
+ netdev_err(dev, "tx ring full\n");
|
||||
+ netif_tx_stop_queue(txq);
|
||||
+ return NETDEV_TX_BUSY;
|
||||
+ }
|
||||
+
|
||||
+ /* dma needs to start on a 16 byte aligned address */
|
||||
+ byte_offset = CPHYSADDR(skb->data) % 16;
|
||||
+ ch->skb[ch->dma.desc] = skb;
|
||||
+
|
||||
+ dev->trans_start = jiffies;
|
||||
+
|
||||
+ spin_lock_irqsave(&priv->lock, flags);
|
||||
+ desc->addr = ((unsigned int) dma_map_single(NULL, skb->data, len,
|
||||
+ DMA_TO_DEVICE)) - byte_offset;
|
||||
+ 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;
|
||||
+ spin_unlock_irqrestore(&priv->lock, flags);
|
||||
+
|
||||
+ if (ch->dma.desc_base[ch->dma.desc].ctl & LTQ_DMA_OWN)
|
||||
+ netif_tx_stop_queue(txq);
|
||||
+
|
||||
+ return NETDEV_TX_OK;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+ltq_etop_change_mtu(struct net_device *dev, int new_mtu)
|
||||
+{
|
||||
+ int ret = eth_change_mtu(dev, new_mtu);
|
||||
+
|
||||
+ if (!ret) {
|
||||
+ struct ltq_etop_priv *priv = netdev_priv(dev);
|
||||
+ unsigned long flags;
|
||||
+
|
||||
+ spin_lock_irqsave(&priv->lock, flags);
|
||||
+ ltq_etop_w32((ETOP_PLEN_UNDER << 16) | new_mtu,
|
||||
+ LTQ_ETOP_IGPLEN);
|
||||
+ spin_unlock_irqrestore(&priv->lock, flags);
|
||||
+ }
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+ltq_etop_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
|
||||
+{
|
||||
+ struct ltq_etop_priv *priv = netdev_priv(dev);
|
||||
+
|
||||
+ /* TODO: mii-toll reports "No MII transceiver present!." ?!*/
|
||||
+ return phy_mii_ioctl(priv->phydev, rq, cmd);
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+ltq_etop_set_mac_address(struct net_device *dev, void *p)
|
||||
+{
|
||||
+ int ret = eth_mac_addr(dev, p);
|
||||
+
|
||||
+ if (!ret) {
|
||||
+ struct ltq_etop_priv *priv = netdev_priv(dev);
|
||||
+ unsigned long flags;
|
||||
+
|
||||
+ /* store the mac for the unicast filter */
|
||||
+ spin_lock_irqsave(&priv->lock, flags);
|
||||
+ ltq_etop_w32(*((u32 *)dev->dev_addr), LTQ_ETOP_MAC_DA0);
|
||||
+ ltq_etop_w32(*((u16 *)&dev->dev_addr[4]) << 16,
|
||||
+ LTQ_ETOP_MAC_DA1);
|
||||
+ spin_unlock_irqrestore(&priv->lock, flags);
|
||||
+ }
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+ltq_etop_set_multicast_list(struct net_device *dev)
|
||||
+{
|
||||
+ struct ltq_etop_priv *priv = netdev_priv(dev);
|
||||
+ unsigned long flags;
|
||||
+
|
||||
+ /* ensure that the unicast filter is not enabled in promiscious mode */
|
||||
+ spin_lock_irqsave(&priv->lock, flags);
|
||||
+ if ((dev->flags & IFF_PROMISC) || (dev->flags & IFF_ALLMULTI))
|
||||
+ ltq_etop_w32_mask(ETOP_FTCU, 0, LTQ_ETOP_ENETS0);
|
||||
+ else
|
||||
+ ltq_etop_w32_mask(0, ETOP_FTCU, LTQ_ETOP_ENETS0);
|
||||
+ spin_unlock_irqrestore(&priv->lock, flags);
|
||||
+}
|
||||
+
|
||||
+static u16
|
||||
+ltq_etop_select_queue(struct net_device *dev, struct sk_buff *skb)
|
||||
+{
|
||||
+ /* we are currently only using the first queue */
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+ltq_etop_init(struct net_device *dev)
|
||||
+{
|
||||
+ struct ltq_etop_priv *priv = netdev_priv(dev);
|
||||
+ struct sockaddr mac;
|
||||
+ int err;
|
||||
+
|
||||
+ ether_setup(dev);
|
||||
+ dev->watchdog_timeo = 10 * HZ;
|
||||
+ err = ltq_etop_hw_init(dev);
|
||||
+ if (err)
|
||||
+ goto err_hw;
|
||||
+ ltq_etop_change_mtu(dev, 1500);
|
||||
+
|
||||
+ memcpy(&mac, &priv->pldata->mac, sizeof(struct sockaddr));
|
||||
+ if (!is_valid_ether_addr(mac.sa_data)) {
|
||||
+ pr_warn("etop: invalid MAC, using random\n");
|
||||
+ random_ether_addr(mac.sa_data);
|
||||
+ }
|
||||
+
|
||||
+ err = ltq_etop_set_mac_address(dev, &mac);
|
||||
+ if (err)
|
||||
+ goto err_netdev;
|
||||
+ ltq_etop_set_multicast_list(dev);
|
||||
+ err = ltq_etop_mdio_init(dev);
|
||||
+ if (err)
|
||||
+ goto err_netdev;
|
||||
+ return 0;
|
||||
+
|
||||
+err_netdev:
|
||||
+ unregister_netdev(dev);
|
||||
+ free_netdev(dev);
|
||||
+err_hw:
|
||||
+ ltq_etop_hw_exit(dev);
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+ltq_etop_tx_timeout(struct net_device *dev)
|
||||
+{
|
||||
+ int err;
|
||||
+
|
||||
+ ltq_etop_hw_exit(dev);
|
||||
+ err = ltq_etop_hw_init(dev);
|
||||
+ if (err)
|
||||
+ goto err_hw;
|
||||
+ dev->trans_start = jiffies;
|
||||
+ netif_wake_queue(dev);
|
||||
+ return;
|
||||
+
|
||||
+err_hw:
|
||||
+ ltq_etop_hw_exit(dev);
|
||||
+ netdev_err(dev, "failed to restart etop after TX timeout\n");
|
||||
+}
|
||||
+
|
||||
+static const struct net_device_ops ltq_eth_netdev_ops = {
|
||||
+ .ndo_open = ltq_etop_open,
|
||||
+ .ndo_stop = ltq_etop_stop,
|
||||
+ .ndo_start_xmit = ltq_etop_tx,
|
||||
+ .ndo_change_mtu = ltq_etop_change_mtu,
|
||||
+ .ndo_do_ioctl = ltq_etop_ioctl,
|
||||
+ .ndo_set_mac_address = ltq_etop_set_mac_address,
|
||||
+ .ndo_validate_addr = eth_validate_addr,
|
||||
+ .ndo_set_multicast_list = ltq_etop_set_multicast_list,
|
||||
+ .ndo_select_queue = ltq_etop_select_queue,
|
||||
+ .ndo_init = ltq_etop_init,
|
||||
+ .ndo_tx_timeout = ltq_etop_tx_timeout,
|
||||
+};
|
||||
+
|
||||
+static int __init
|
||||
+ltq_etop_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct net_device *dev;
|
||||
+ struct ltq_etop_priv *priv;
|
||||
+ struct resource *res;
|
||||
+ int err;
|
||||
+ int i;
|
||||
+
|
||||
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
+ if (!res) {
|
||||
+ dev_err(&pdev->dev, "failed to get etop resource\n");
|
||||
+ err = -ENOENT;
|
||||
+ goto err_out;
|
||||
+ }
|
||||
+
|
||||
+ res = devm_request_mem_region(&pdev->dev, res->start,
|
||||
+ resource_size(res), dev_name(&pdev->dev));
|
||||
+ if (!res) {
|
||||
+ dev_err(&pdev->dev, "failed to request etop resource\n");
|
||||
+ err = -EBUSY;
|
||||
+ goto err_out;
|
||||
+ }
|
||||
+
|
||||
+ ltq_etop_membase = devm_ioremap_nocache(&pdev->dev,
|
||||
+ res->start, resource_size(res));
|
||||
+ if (!ltq_etop_membase) {
|
||||
+ dev_err(&pdev->dev, "failed to remap etop engine %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 = <q_eth_netdev_ops;
|
||||
+ dev->ethtool_ops = <q_etop_ethtool_ops;
|
||||
+ priv = netdev_priv(dev);
|
||||
+ priv->res = res;
|
||||
+ priv->pldata = dev_get_platdata(&pdev->dev);
|
||||
+ priv->netdev = dev;
|
||||
+ 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;
|
||||
+ }
|
||||
+
|
||||
+ err = register_netdev(dev);
|
||||
+ if (err)
|
||||
+ goto err_free;
|
||||
+
|
||||
+ platform_set_drvdata(pdev, dev);
|
||||
+ return 0;
|
||||
+
|
||||
+err_free:
|
||||
+ kfree(dev);
|
||||
+err_out:
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+static int __devexit
|
||||
+ltq_etop_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct net_device *dev = platform_get_drvdata(pdev);
|
||||
+
|
||||
+ if (dev) {
|
||||
+ netif_tx_stop_all_queues(dev);
|
||||
+ ltq_etop_hw_exit(dev);
|
||||
+ ltq_etop_mdio_cleanup(dev);
|
||||
+ unregister_netdev(dev);
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct platform_driver ltq_mii_driver = {
|
||||
+ .remove = __devexit_p(ltq_etop_remove),
|
||||
+ .driver = {
|
||||
+ .name = "ltq_etop",
|
||||
+ .owner = THIS_MODULE,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+int __init
|
||||
+init_ltq_etop(void)
|
||||
+{
|
||||
+ int ret = platform_driver_probe(<q_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(<q_mii_driver);
|
||||
+}
|
||||
+
|
||||
+module_init(init_ltq_etop);
|
||||
+module_exit(exit_ltq_etop);
|
||||
+
|
||||
+MODULE_AUTHOR("John Crispin <blogic@openwrt.org>");
|
||||
+MODULE_DESCRIPTION("Lantiq SoC ETOP");
|
||||
+MODULE_LICENSE("GPL");
|
|
@ -1,45 +0,0 @@
|
|||
From 72a9b536ef81f06bb8042abee0410458f5df93d2 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Fri, 6 May 2011 00:10:02 +0200
|
||||
Subject: [PATCH 12/13] MIPS: Lantiq: Add etop board support
|
||||
|
||||
Register the etop platform device inside the machtype specific init code.
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
Signed-off-by: Ralph Hempel <ralph.hempel@lantiq.com>
|
||||
Signed-off-by: David Daney <ddaney@caviumnetworks.com>
|
||||
Cc: linux-mips@linux-mips.org
|
||||
Patchwork: https://patchwork.linux-mips.org/patch/2356/
|
||||
Patchwork: https://patchwork.linux-mips.org/patch/2370/
|
||||
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
|
||||
---
|
||||
arch/mips/lantiq/xway/mach-easy50712.c | 6 ++++++
|
||||
1 files changed, 6 insertions(+), 0 deletions(-)
|
||||
|
||||
--- a/arch/mips/lantiq/xway/mach-easy50712.c
|
||||
+++ b/arch/mips/lantiq/xway/mach-easy50712.c
|
||||
@@ -12,6 +12,7 @@
|
||||
#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>
|
||||
@@ -55,11 +56,16 @@ static struct ltq_pci_data ltq_pci_data
|
||||
},
|
||||
};
|
||||
|
||||
+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(<q_pci_data);
|
||||
+ ltq_register_etop(<q_eth_data);
|
||||
}
|
||||
|
||||
MIPS_MACHINE(LTQ_MACH_EASY50712,
|
|
@ -1,310 +0,0 @@
|
|||
From 3466449c8f455da0cb646231602e6af16190f592 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Thu, 5 May 2011 23:00:23 +0200
|
||||
Subject: [PATCH 13/13] MIPS: Lantiq: Add watchdog support
|
||||
|
||||
This patch adds the driver for the watchdog found inside the Lantiq SoC family.
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
Signed-off-by: Ralph Hempel <ralph.hempel@lantiq.com>
|
||||
Cc: Wim Van Sebroeck <wim@iguana.be>
|
||||
Cc: linux-mips@linux-mips.org
|
||||
Cc: linux-watchdog@vger.kernel.org
|
||||
Patchwork: https://patchwork.linux-mips.org/patch/2327/
|
||||
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
|
||||
---
|
||||
drivers/watchdog/Kconfig | 6 +
|
||||
drivers/watchdog/Makefile | 1 +
|
||||
drivers/watchdog/lantiq_wdt.c | 261 +++++++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 268 insertions(+), 0 deletions(-)
|
||||
create mode 100644 drivers/watchdog/lantiq_wdt.c
|
||||
|
||||
--- a/drivers/watchdog/Kconfig
|
||||
+++ b/drivers/watchdog/Kconfig
|
||||
@@ -990,6 +990,12 @@ config BCM63XX_WDT
|
||||
To compile this driver as a loadable module, choose M here.
|
||||
The module will be called bcm63xx_wdt.
|
||||
|
||||
+config LANTIQ_WDT
|
||||
+ tristate "Lantiq SoC watchdog"
|
||||
+ depends on LANTIQ
|
||||
+ help
|
||||
+ Hardware driver for the Lantiq SoC Watchdog Timer.
|
||||
+
|
||||
# PARISC Architecture
|
||||
|
||||
# POWERPC Architecture
|
||||
--- a/drivers/watchdog/Makefile
|
||||
+++ b/drivers/watchdog/Makefile
|
||||
@@ -123,6 +123,7 @@ obj-$(CONFIG_AR7_WDT) += ar7_wdt.o
|
||||
obj-$(CONFIG_TXX9_WDT) += txx9wdt.o
|
||||
obj-$(CONFIG_OCTEON_WDT) += octeon-wdt.o
|
||||
octeon-wdt-y := octeon-wdt-main.o octeon-wdt-nmi.o
|
||||
+obj-$(CONFIG_LANTIQ_WDT) += lantiq_wdt.o
|
||||
|
||||
# PARISC Architecture
|
||||
|
||||
--- /dev/null
|
||||
+++ b/drivers/watchdog/lantiq_wdt.c
|
||||
@@ -0,0 +1,261 @@
|
||||
+/*
|
||||
+ * 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>
|
||||
+ * Based on EP93xx wdt driver
|
||||
+ */
|
||||
+
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/fs.h>
|
||||
+#include <linux/miscdevice.h>
|
||||
+#include <linux/watchdog.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/uaccess.h>
|
||||
+#include <linux/clk.h>
|
||||
+#include <linux/io.h>
|
||||
+
|
||||
+#include <lantiq.h>
|
||||
+
|
||||
+/* Section 3.4 of the datasheet
|
||||
+ * The password sequence protects the WDT control register from unintended
|
||||
+ * write actions, which might cause malfunction of the WDT.
|
||||
+ *
|
||||
+ * essentially the following two magic passwords need to be written to allow
|
||||
+ * IO access to the WDT core
|
||||
+ */
|
||||
+#define LTQ_WDT_PW1 0x00BE0000
|
||||
+#define LTQ_WDT_PW2 0x00DC0000
|
||||
+
|
||||
+#define LTQ_WDT_CR 0x0 /* watchdog control register */
|
||||
+#define LTQ_WDT_SR 0x8 /* watchdog status register */
|
||||
+
|
||||
+#define LTQ_WDT_SR_EN (0x1 << 31) /* enable bit */
|
||||
+#define LTQ_WDT_SR_PWD (0x3 << 26) /* turn on power */
|
||||
+#define LTQ_WDT_SR_CLKDIV (0x3 << 24) /* turn on clock and set */
|
||||
+ /* divider to 0x40000 */
|
||||
+#define LTQ_WDT_DIVIDER 0x40000
|
||||
+#define LTQ_MAX_TIMEOUT ((1 << 16) - 1) /* the reload field is 16 bit */
|
||||
+
|
||||
+static int nowayout = WATCHDOG_NOWAYOUT;
|
||||
+
|
||||
+static void __iomem *ltq_wdt_membase;
|
||||
+static unsigned long ltq_io_region_clk_rate;
|
||||
+
|
||||
+static unsigned long ltq_wdt_bootstatus;
|
||||
+static unsigned long ltq_wdt_in_use;
|
||||
+static int ltq_wdt_timeout = 30;
|
||||
+static int ltq_wdt_ok_to_close;
|
||||
+
|
||||
+static void
|
||||
+ltq_wdt_enable(void)
|
||||
+{
|
||||
+ ltq_wdt_timeout = ltq_wdt_timeout *
|
||||
+ (ltq_io_region_clk_rate / LTQ_WDT_DIVIDER) + 0x1000;
|
||||
+ if (ltq_wdt_timeout > LTQ_MAX_TIMEOUT)
|
||||
+ ltq_wdt_timeout = LTQ_MAX_TIMEOUT;
|
||||
+
|
||||
+ /* write the first password magic */
|
||||
+ ltq_w32(LTQ_WDT_PW1, ltq_wdt_membase + LTQ_WDT_CR);
|
||||
+ /* write the second magic plus the configuration and new timeout */
|
||||
+ ltq_w32(LTQ_WDT_SR_EN | LTQ_WDT_SR_PWD | LTQ_WDT_SR_CLKDIV |
|
||||
+ LTQ_WDT_PW2 | ltq_wdt_timeout, ltq_wdt_membase + LTQ_WDT_CR);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+ltq_wdt_disable(void)
|
||||
+{
|
||||
+ /* write the first password magic */
|
||||
+ ltq_w32(LTQ_WDT_PW1, ltq_wdt_membase + LTQ_WDT_CR);
|
||||
+ /* write the second password magic with no config
|
||||
+ * this turns the watchdog off
|
||||
+ */
|
||||
+ ltq_w32(LTQ_WDT_PW2, ltq_wdt_membase + LTQ_WDT_CR);
|
||||
+}
|
||||
+
|
||||
+static ssize_t
|
||||
+ltq_wdt_write(struct file *file, const char __user *data,
|
||||
+ size_t len, loff_t *ppos)
|
||||
+{
|
||||
+ if (len) {
|
||||
+ if (!nowayout) {
|
||||
+ size_t i;
|
||||
+
|
||||
+ ltq_wdt_ok_to_close = 0;
|
||||
+ for (i = 0; i != len; i++) {
|
||||
+ char c;
|
||||
+
|
||||
+ if (get_user(c, data + i))
|
||||
+ return -EFAULT;
|
||||
+ if (c == 'V')
|
||||
+ ltq_wdt_ok_to_close = 1;
|
||||
+ else
|
||||
+ ltq_wdt_ok_to_close = 0;
|
||||
+ }
|
||||
+ }
|
||||
+ ltq_wdt_enable();
|
||||
+ }
|
||||
+
|
||||
+ return len;
|
||||
+}
|
||||
+
|
||||
+static struct watchdog_info ident = {
|
||||
+ .options = WDIOF_MAGICCLOSE | WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING |
|
||||
+ WDIOF_CARDRESET,
|
||||
+ .identity = "ltq_wdt",
|
||||
+};
|
||||
+
|
||||
+static long
|
||||
+ltq_wdt_ioctl(struct file *file,
|
||||
+ unsigned int cmd, unsigned long arg)
|
||||
+{
|
||||
+ int ret = -ENOTTY;
|
||||
+
|
||||
+ switch (cmd) {
|
||||
+ case WDIOC_GETSUPPORT:
|
||||
+ ret = copy_to_user((struct watchdog_info __user *)arg, &ident,
|
||||
+ sizeof(ident)) ? -EFAULT : 0;
|
||||
+ break;
|
||||
+
|
||||
+ case WDIOC_GETBOOTSTATUS:
|
||||
+ ret = put_user(ltq_wdt_bootstatus, (int __user *)arg);
|
||||
+ break;
|
||||
+
|
||||
+ case WDIOC_GETSTATUS:
|
||||
+ ret = put_user(0, (int __user *)arg);
|
||||
+ break;
|
||||
+
|
||||
+ case WDIOC_SETTIMEOUT:
|
||||
+ ret = get_user(ltq_wdt_timeout, (int __user *)arg);
|
||||
+ if (!ret)
|
||||
+ ltq_wdt_enable();
|
||||
+ /* intentional drop through */
|
||||
+ case WDIOC_GETTIMEOUT:
|
||||
+ ret = put_user(ltq_wdt_timeout, (int __user *)arg);
|
||||
+ break;
|
||||
+
|
||||
+ case WDIOC_KEEPALIVE:
|
||||
+ ltq_wdt_enable();
|
||||
+ ret = 0;
|
||||
+ break;
|
||||
+ }
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+ltq_wdt_open(struct inode *inode, struct file *file)
|
||||
+{
|
||||
+ if (test_and_set_bit(0, <q_wdt_in_use))
|
||||
+ return -EBUSY;
|
||||
+ ltq_wdt_in_use = 1;
|
||||
+ ltq_wdt_enable();
|
||||
+
|
||||
+ return nonseekable_open(inode, file);
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+ltq_wdt_release(struct inode *inode, struct file *file)
|
||||
+{
|
||||
+ if (ltq_wdt_ok_to_close)
|
||||
+ ltq_wdt_disable();
|
||||
+ else
|
||||
+ pr_err("ltq_wdt: watchdog closed without warning\n");
|
||||
+ ltq_wdt_ok_to_close = 0;
|
||||
+ clear_bit(0, <q_wdt_in_use);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct file_operations ltq_wdt_fops = {
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .write = ltq_wdt_write,
|
||||
+ .unlocked_ioctl = ltq_wdt_ioctl,
|
||||
+ .open = ltq_wdt_open,
|
||||
+ .release = ltq_wdt_release,
|
||||
+ .llseek = no_llseek,
|
||||
+};
|
||||
+
|
||||
+static struct miscdevice ltq_wdt_miscdev = {
|
||||
+ .minor = WATCHDOG_MINOR,
|
||||
+ .name = "watchdog",
|
||||
+ .fops = <q_wdt_fops,
|
||||
+};
|
||||
+
|
||||
+static int __init
|
||||
+ltq_wdt_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
+ struct clk *clk;
|
||||
+
|
||||
+ if (!res) {
|
||||
+ dev_err(&pdev->dev, "cannot obtain I/O memory region");
|
||||
+ return -ENOENT;
|
||||
+ }
|
||||
+ res = devm_request_mem_region(&pdev->dev, res->start,
|
||||
+ resource_size(res), dev_name(&pdev->dev));
|
||||
+ if (!res) {
|
||||
+ dev_err(&pdev->dev, "cannot request I/O memory region");
|
||||
+ return -EBUSY;
|
||||
+ }
|
||||
+ ltq_wdt_membase = devm_ioremap_nocache(&pdev->dev, res->start,
|
||||
+ resource_size(res));
|
||||
+ if (!ltq_wdt_membase) {
|
||||
+ dev_err(&pdev->dev, "cannot remap I/O memory region\n");
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ /* we do not need to enable the clock as it is always running */
|
||||
+ clk = clk_get(&pdev->dev, "io");
|
||||
+ WARN_ON(!clk);
|
||||
+ ltq_io_region_clk_rate = clk_get_rate(clk);
|
||||
+ clk_put(clk);
|
||||
+
|
||||
+ if (ltq_reset_cause() == LTQ_RST_CAUSE_WDTRST)
|
||||
+ ltq_wdt_bootstatus = WDIOF_CARDRESET;
|
||||
+
|
||||
+ return misc_register(<q_wdt_miscdev);
|
||||
+}
|
||||
+
|
||||
+static int __devexit
|
||||
+ltq_wdt_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ misc_deregister(<q_wdt_miscdev);
|
||||
+
|
||||
+ if (ltq_wdt_membase)
|
||||
+ iounmap(ltq_wdt_membase);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static struct platform_driver ltq_wdt_driver = {
|
||||
+ .remove = __devexit_p(ltq_wdt_remove),
|
||||
+ .driver = {
|
||||
+ .name = "ltq_wdt",
|
||||
+ .owner = THIS_MODULE,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static int __init
|
||||
+init_ltq_wdt(void)
|
||||
+{
|
||||
+ return platform_driver_probe(<q_wdt_driver, ltq_wdt_probe);
|
||||
+}
|
||||
+
|
||||
+static void __exit
|
||||
+exit_ltq_wdt(void)
|
||||
+{
|
||||
+ return platform_driver_unregister(<q_wdt_driver);
|
||||
+}
|
||||
+
|
||||
+module_init(init_ltq_wdt);
|
||||
+module_exit(exit_ltq_wdt);
|
||||
+
|
||||
+module_param(nowayout, int, 0);
|
||||
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started");
|
||||
+
|
||||
+MODULE_AUTHOR("John Crispin <blogic@openwrt.org>");
|
||||
+MODULE_DESCRIPTION("Lantiq SoC Watchdog");
|
||||
+MODULE_LICENSE("GPL");
|
||||
+MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
|
|
@ -1,32 +0,0 @@
|
|||
--- a/arch/mips/lantiq/xway/mach-easy50601.c
|
||||
+++ b/arch/mips/lantiq/xway/mach-easy50601.c
|
||||
@@ -32,12 +32,7 @@ static struct mtd_partition easy50601_pa
|
||||
{
|
||||
.name = "linux",
|
||||
.offset = 0x20000,
|
||||
- .size = 0xE0000,
|
||||
- },
|
||||
- {
|
||||
- .name = "rootfs",
|
||||
- .offset = 0x100000,
|
||||
- .size = 0x300000,
|
||||
+ .size = 0x3d0000,
|
||||
},
|
||||
};
|
||||
|
||||
--- a/arch/mips/lantiq/xway/mach-easy50712.c
|
||||
+++ b/arch/mips/lantiq/xway/mach-easy50712.c
|
||||
@@ -34,12 +34,7 @@ static struct mtd_partition easy50712_pa
|
||||
{
|
||||
.name = "linux",
|
||||
.offset = 0x20000,
|
||||
- .size = 0xe0000,
|
||||
- },
|
||||
- {
|
||||
- .name = "rootfs",
|
||||
- .offset = 0x100000,
|
||||
- .size = 0x300000,
|
||||
+ .size = 0x3d0000,
|
||||
},
|
||||
};
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,828 +0,0 @@
|
|||
--- a/drivers/i2c/busses/Makefile
|
||||
+++ b/drivers/i2c/busses/Makefile
|
||||
@@ -82,5 +82,6 @@ obj-$(CONFIG_I2C_SIBYTE) += i2c-sibyte.o
|
||||
obj-$(CONFIG_I2C_STUB) += i2c-stub.o
|
||||
obj-$(CONFIG_SCx200_ACB) += scx200_acb.o
|
||||
obj-$(CONFIG_SCx200_I2C) += scx200_i2c.o
|
||||
+obj-$(CONFIG_I2C_FALCON) += i2c-falcon.o
|
||||
|
||||
ccflags-$(CONFIG_I2C_DEBUG_BUS) := -DDEBUG
|
||||
--- a/drivers/i2c/busses/Kconfig
|
||||
+++ b/drivers/i2c/busses/Kconfig
|
||||
@@ -282,6 +282,10 @@ config I2C_POWERMAC
|
||||
|
||||
comment "I2C system bus drivers (mostly embedded / system-on-chip)"
|
||||
|
||||
+config I2C_FALCON
|
||||
+ tristate "Falcon I2C interface"
|
||||
+# depends on SOC_FALCON
|
||||
+
|
||||
config I2C_AT91
|
||||
tristate "Atmel AT91 I2C Two-Wire interface (TWI)"
|
||||
depends on ARCH_AT91 && EXPERIMENTAL && BROKEN
|
||||
--- /dev/null
|
||||
+++ b/drivers/i2c/busses/i2c-falcon.c
|
||||
@@ -0,0 +1,803 @@
|
||||
+/*
|
||||
+ * 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.
|
||||
+ */
|
||||
+
|
||||
+/* #define DEBUG */
|
||||
+
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/ioport.h>
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/i2c.h>
|
||||
+#include <linux/interrupt.h>
|
||||
+#include <linux/spinlock.h>
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/clk.h>
|
||||
+#include <linux/err.h>
|
||||
+#include <linux/slab.h>
|
||||
+
|
||||
+/* CURRENT ISSUES:
|
||||
+ * - no high speed support
|
||||
+ * - rx issue with "address mode" & "tx end" interrupts
|
||||
+ * - ten bit mode is not tested
|
||||
+ */
|
||||
+
|
||||
+/* mapping for access macros */
|
||||
+#define reg_r32(reg) __raw_readl(reg)
|
||||
+#define reg_w32(val, reg) __raw_writel(val, reg)
|
||||
+#define reg_w32_mask(clear, set, reg) \
|
||||
+ reg_w32((reg_r32(reg) & ~(clear)) | (set), reg)
|
||||
+#define reg_r32_table(reg, idx) reg_r32(&((uint32_t *)®)[idx])
|
||||
+#define reg_w32_table(val, reg, idx) reg_w32(val, &((uint32_t *)®)[idx])
|
||||
+#define i2c (priv->membase)
|
||||
+#include <falcon/i2c_reg.h>
|
||||
+
|
||||
+/* enable hacks to overcome current issue */
|
||||
+#define FALCON_FIX_ME
|
||||
+
|
||||
+#define FALCON_I2C_ADDR 0x00
|
||||
+#define FALCON_I2C_READY_TIMEOUT 1000
|
||||
+#define FALCON_I2C_WAIT_TIMEOUT 10
|
||||
+
|
||||
+#define DRV_NAME "i2c-falcon"
|
||||
+
|
||||
+#if defined(DEBUG)
|
||||
+#define static /* no static functions for better debugging */
|
||||
+#endif
|
||||
+
|
||||
+#define FALCON_I2C_ARB_LOST (1 << 0)
|
||||
+#define FALCON_I2C_NACK (1 << 1)
|
||||
+#define FALCON_I2C_RX_UFL (1 << 2)
|
||||
+#define FALCON_I2C_RX_OFL (1 << 3)
|
||||
+#define FALCON_I2C_TX_UFL (1 << 4)
|
||||
+#define FALCON_I2C_TX_OFL (1 << 5)
|
||||
+#define FALCON_I2C_BURST_REQ (1 << 6)
|
||||
+#define FALCON_I2C_RX (1 << 7)
|
||||
+#define FALCON_I2C_TX_END (1 << 8)
|
||||
+#define FALCON_I2C_ADDR_MATCH (1 << 9) /* doesn't trigger */
|
||||
+
|
||||
+struct falcon_i2c {
|
||||
+ spinlock_t lock;
|
||||
+
|
||||
+ enum {
|
||||
+ FALCON_I2C_MODE_100 = 1,
|
||||
+ FALCON_I2C_MODE_400 = 2,
|
||||
+ FALCON_I2C_MODE_3400 = 3
|
||||
+ } mode; /* current speed mode */
|
||||
+
|
||||
+ int ten_bit; /* current address mode */
|
||||
+ unsigned long status; /* bus events holder */
|
||||
+ struct clk *clk; /* clock input for i2c hardware block */
|
||||
+ struct gpon_reg_i2c __iomem *membase; /* base of mapped registers */
|
||||
+ int irq_lb, irq_b, irq_err, irq_p; /* last burst, burst, error,
|
||||
+ protocol IRQs */
|
||||
+ struct completion done;
|
||||
+ struct i2c_adapter adap;
|
||||
+ struct device *dev;
|
||||
+};
|
||||
+
|
||||
+#define FALCON_I2C_ERROR_MASK (FALCON_I2C_NACK \
|
||||
+ | FALCON_I2C_ARB_LOST \
|
||||
+ | FALCON_I2C_RX_OFL \
|
||||
+ | FALCON_I2C_RX_UFL \
|
||||
+ | FALCON_I2C_TX_OFL \
|
||||
+ | FALCON_I2C_TX_UFL)
|
||||
+
|
||||
+#define FALCON_I2C_ERROR(priv) (priv->status & FALCON_I2C_ERROR_MASK)
|
||||
+#define FALCON_I2C_ERROR_CLEAR(priv) do { \
|
||||
+ priv->status &= \
|
||||
+ ~FALCON_I2C_ERROR_MASK; \
|
||||
+ } while (0)
|
||||
+
|
||||
+static void falcon_addr_configure(struct falcon_i2c *priv, int ten_bit)
|
||||
+{
|
||||
+ u32 ten_bit_mask = ten_bit ? I2C_ADDR_CFG_TBAM_10bit : 0;
|
||||
+
|
||||
+ /* configure address */
|
||||
+ i2c_w32(I2C_ADDR_CFG_SOPE_EN /* generate stop when no more data in the
|
||||
+ fifo */
|
||||
+ | I2C_ADDR_CFG_SONA_EN /* generate stop when NA received */
|
||||
+ | I2C_ADDR_CFG_MnS_EN /* we are master device */
|
||||
+ | ten_bit_mask
|
||||
+ | FALCON_I2C_ADDR, /* our address */
|
||||
+ addr_cfg);
|
||||
+}
|
||||
+
|
||||
+static irqreturn_t falcon_i2c_isr(int irq, void *dev_id)
|
||||
+{
|
||||
+ u32 i_raw, i_pro, i_err;
|
||||
+ struct falcon_i2c *priv = dev_id;
|
||||
+ unsigned long flags;
|
||||
+ unsigned int old_status;
|
||||
+
|
||||
+ spin_lock_irqsave(&priv->lock, flags);
|
||||
+
|
||||
+ old_status = (unsigned int)priv->status;
|
||||
+
|
||||
+ i_raw = i2c_r32(mis);
|
||||
+
|
||||
+ /* protocol interrupt */
|
||||
+ if (i_raw & I2C_RIS_I2C_P_INT_INTOCC) {
|
||||
+ i_pro = i2c_r32(p_irqss);
|
||||
+
|
||||
+ /* tx -> rx switch */
|
||||
+ if (i_pro & I2C_P_IRQSS_RX)
|
||||
+ priv->status |= FALCON_I2C_RX;
|
||||
+
|
||||
+ /* tx end */
|
||||
+ if (i_pro & I2C_P_IRQSS_TX_END)
|
||||
+ priv->status |= FALCON_I2C_TX_END;
|
||||
+
|
||||
+ /* not acknowledge */
|
||||
+ if (i_pro & I2C_P_IRQSS_NACK)
|
||||
+ priv->status |= FALCON_I2C_NACK;
|
||||
+
|
||||
+ /* arbitration lost */
|
||||
+ if (i_pro & I2C_P_IRQSS_AL)
|
||||
+ priv->status |= FALCON_I2C_ARB_LOST;
|
||||
+
|
||||
+ /* address match */
|
||||
+ if (i_pro & I2C_P_IRQSS_AM)
|
||||
+ priv->status |= FALCON_I2C_ADDR_MATCH;
|
||||
+
|
||||
+ i2c_w32(i_pro, p_irqsc);
|
||||
+ }
|
||||
+
|
||||
+ /* error interrupt */
|
||||
+ if (i_raw & I2C_RIS_I2C_ERR_INT_INTOCC) {
|
||||
+ i_err = i2c_r32(err_irqss);
|
||||
+
|
||||
+ /* tx fifo overflow */
|
||||
+ if (i_err & I2C_ERR_IRQSS_TXF_OFL)
|
||||
+ priv->status |= FALCON_I2C_TX_OFL;
|
||||
+
|
||||
+ /* tx fifo underflow */
|
||||
+ if (i_err & I2C_ERR_IRQSS_TXF_UFL)
|
||||
+ priv->status |= FALCON_I2C_TX_UFL;
|
||||
+
|
||||
+ /* rx fifo overflow */
|
||||
+ if (i_err & I2C_ERR_IRQSS_RXF_OFL)
|
||||
+ priv->status |= FALCON_I2C_RX_OFL;
|
||||
+
|
||||
+ /* rx fifo underflow */
|
||||
+ if (i_err & I2C_ERR_IRQSS_RXF_UFL)
|
||||
+ priv->status |= FALCON_I2C_RX_UFL;
|
||||
+
|
||||
+ i2c_w32(i_err, err_irqsc);
|
||||
+ }
|
||||
+
|
||||
+ /* burst request */
|
||||
+ if (i_raw & I2C_RIS_BREQ_INT_INTOCC) {
|
||||
+ i2c_w32_mask(I2C_IMSC_BREQ_INT_EN, 0, imsc);
|
||||
+ i2c_w32_mask(0, I2C_ICR_BREQ_INT_CLR, icr);
|
||||
+
|
||||
+ priv->status |= FALCON_I2C_BURST_REQ;
|
||||
+ }
|
||||
+
|
||||
+ /* last burst request */
|
||||
+ if (i_raw & I2C_RIS_LBREQ_INT_INTOCC) {
|
||||
+ i2c_w32_mask(I2C_IMSC_LBREQ_INT_EN, 0, imsc);
|
||||
+ i2c_w32_mask(0, I2C_ICR_LBREQ_INT_CLR, icr);
|
||||
+
|
||||
+ priv->status |= FALCON_I2C_BURST_REQ;
|
||||
+ }
|
||||
+
|
||||
+ if (old_status != (unsigned int)priv->status)
|
||||
+ complete(&priv->done);
|
||||
+
|
||||
+ spin_unlock_irqrestore(&priv->lock, flags);
|
||||
+
|
||||
+ return IRQ_HANDLED;
|
||||
+}
|
||||
+
|
||||
+static int falcon_i2c_ready(struct falcon_i2c *priv)
|
||||
+{
|
||||
+ int timeout;
|
||||
+ u32 bus_stat;
|
||||
+ unsigned long flags;
|
||||
+ int ret;
|
||||
+
|
||||
+ for (timeout = 0; timeout < FALCON_I2C_READY_TIMEOUT; timeout++) {
|
||||
+ bus_stat = i2c_r32(bus_stat);
|
||||
+
|
||||
+ if (bus_stat & I2C_BUS_STAT_BS_SC) {
|
||||
+ cpu_relax();
|
||||
+ } else {
|
||||
+ spin_lock_irqsave(&priv->lock, flags);
|
||||
+
|
||||
+ if (FALCON_I2C_ERROR(priv)) {
|
||||
+ ret = priv->status;
|
||||
+
|
||||
+ dev_dbg(priv->dev, "bus ready wait error 0x%08lx\n", priv->status);
|
||||
+
|
||||
+ FALCON_I2C_ERROR_CLEAR(priv);
|
||||
+ } else {
|
||||
+ ret = 0;
|
||||
+ }
|
||||
+
|
||||
+ spin_unlock_irqrestore(&priv->lock, flags);
|
||||
+
|
||||
+ return ret;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ dev_dbg(priv->dev, "bus ready wait timeout\n");
|
||||
+
|
||||
+ return -ETIME;
|
||||
+}
|
||||
+
|
||||
+static int falcon_i2c_wait(struct falcon_i2c *priv, unsigned long status)
|
||||
+{
|
||||
+ int ret = 0;
|
||||
+ unsigned long flags;
|
||||
+ unsigned int timeout;
|
||||
+
|
||||
+ spin_lock_irqsave(&priv->lock, flags);
|
||||
+
|
||||
+ priv->status &= FALCON_I2C_BURST_REQ;
|
||||
+
|
||||
+ /* check if the event already occurred */
|
||||
+ if ((priv->status & status) == status) {
|
||||
+ priv->status &= ~status;
|
||||
+ spin_unlock_irqrestore(&priv->lock, flags);
|
||||
+
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ spin_unlock_irqrestore(&priv->lock, flags);
|
||||
+
|
||||
+ /* unmask burst interrupts */
|
||||
+ i2c_w32_mask(0, I2C_IMSC_LBREQ_INT_EN | I2C_IMSC_BREQ_INT_EN, imsc);
|
||||
+
|
||||
+ for (timeout = 0; timeout < FALCON_I2C_WAIT_TIMEOUT; timeout++) {
|
||||
+ /* wait for the data request */
|
||||
+ wait_for_completion_timeout(&priv->done, HZ / 10);
|
||||
+
|
||||
+ /* handle errors */
|
||||
+ spin_lock_irqsave(&priv->lock, flags);
|
||||
+
|
||||
+ if (FALCON_I2C_ERROR(priv)) {
|
||||
+ dev_dbg(priv->dev, "wait error 0x%08lx (waiting for 0x%08lx)\n",
|
||||
+ priv->status,
|
||||
+ status);
|
||||
+
|
||||
+ if (priv->status & FALCON_I2C_NACK)
|
||||
+ ret = -ENXIO;
|
||||
+ else
|
||||
+ ret = -EREMOTEIO;
|
||||
+
|
||||
+ FALCON_I2C_ERROR_CLEAR(priv);
|
||||
+ } else {
|
||||
+ if ((priv->status & status) == status) {
|
||||
+ priv->status &= ~status;
|
||||
+ spin_unlock_irqrestore(&priv->lock, flags);
|
||||
+
|
||||
+ return 0;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ spin_unlock_irqrestore(&priv->lock, flags);
|
||||
+
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ dev_dbg(priv->dev, "wait timeout error 0x%08lx (waiting for 0x%08lx)\n",
|
||||
+ priv->status,
|
||||
+ status);
|
||||
+
|
||||
+ return -ETIME;
|
||||
+}
|
||||
+
|
||||
+static int falcon_i2c_tx(struct falcon_i2c *priv, int ten_bit, u16 addr,
|
||||
+ u8 *buf, int len)
|
||||
+{
|
||||
+ int i;
|
||||
+ int ret;
|
||||
+
|
||||
+ dev_dbg(priv->dev, "%s\n", __func__);
|
||||
+
|
||||
+ /* tell fifo the number of bytes we are going to send */
|
||||
+ i2c_w32(len + (ten_bit ? 2 : 1), tps_ctrl);
|
||||
+
|
||||
+ /* wait for the data request */
|
||||
+ ret = falcon_i2c_wait(priv, FALCON_I2C_BURST_REQ);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* send slave address */
|
||||
+ if (ten_bit) {
|
||||
+ i2c_w32(0x78 | ((addr >> 7) & 0x7), txd);
|
||||
+ i2c_w32(0x78 | ((addr & 0x7f) << 1) | 0, txd);
|
||||
+ } else {
|
||||
+ i2c_w32((addr << 1) | 0, txd);
|
||||
+ }
|
||||
+
|
||||
+ /* fill fifo */
|
||||
+ for (i = 0; i < len; i++) {
|
||||
+ ret = falcon_i2c_wait(priv, FALCON_I2C_BURST_REQ);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ i2c_w32(buf[i], txd);
|
||||
+ }
|
||||
+
|
||||
+ return falcon_i2c_wait(priv, FALCON_I2C_TX_END);
|
||||
+}
|
||||
+
|
||||
+static int falcon_i2c_rx(struct falcon_i2c *priv, int ten_bit, u16 addr,
|
||||
+ u8 *buf, int len)
|
||||
+{
|
||||
+ int i;
|
||||
+ int ret;
|
||||
+
|
||||
+ dev_dbg(priv->dev, "%s\n", __func__);
|
||||
+
|
||||
+ /* we need to transmit address only */
|
||||
+ i2c_w32(ten_bit ? 2 : 1, tps_ctrl);
|
||||
+
|
||||
+ /* set maximum received packet size */
|
||||
+ i2c_w32(len, mrps_ctrl);
|
||||
+
|
||||
+ /* wait for the data request */
|
||||
+ ret = falcon_i2c_wait(priv, FALCON_I2C_BURST_REQ);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* write down the address */
|
||||
+ if (ten_bit) {
|
||||
+ i2c_w32(0x78 | ((addr >> 7) & 0x7), txd);
|
||||
+ i2c_w32(0x78 | ((addr & 0x7f) << 1) | 1, txd);
|
||||
+ } else {
|
||||
+ i2c_w32((addr << 1) | 1, txd);
|
||||
+ }
|
||||
+
|
||||
+ /* wait for the read request */
|
||||
+ ret = falcon_i2c_wait(priv, FALCON_I2C_TX_END
|
||||
+#ifndef FALCON_FIX_ME
|
||||
+ | FALCON_I2C_ADDR_MATCH
|
||||
+#endif
|
||||
+ | FALCON_I2C_RX);
|
||||
+
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* read bytes */
|
||||
+ for (i = 0; i < len; i++) {
|
||||
+#ifdef FALCON_FIX_ME
|
||||
+ while (i2c_r32(rps_stat) == 0)
|
||||
+ cpu_relax();
|
||||
+#else
|
||||
+ ret = falcon_i2c_wait(priv, FALCON_I2C_BURST_REQ);
|
||||
+
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+#endif
|
||||
+
|
||||
+ buf[i] = i2c_r32(rxd);
|
||||
+ }
|
||||
+
|
||||
+#ifndef FALCON_FIX_ME
|
||||
+ /* wait for transmission end */
|
||||
+ return falcon_i2c_wait(priv, FALCON_I2C_TX_END);
|
||||
+#else
|
||||
+ return 0;
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
+static int falcon_i2c_xfer_msg(struct falcon_i2c *priv, struct i2c_msg *msg)
|
||||
+{
|
||||
+ int ret;
|
||||
+ int ten_bit;
|
||||
+ unsigned long flags;
|
||||
+
|
||||
+ dev_dbg(priv->dev, "%s %u byte(s) %s 0x%02x\n",
|
||||
+ (msg->flags & I2C_M_RD) ? "read" : "write", msg->len,
|
||||
+ (msg->flags & I2C_M_RD) ? "from" : "to", msg->addr);
|
||||
+
|
||||
+ if (msg->flags & I2C_M_TEN)
|
||||
+ ten_bit = 1;
|
||||
+ else
|
||||
+ ten_bit = 0;
|
||||
+
|
||||
+ /* reconfigure bus if need to send message in different address mode */
|
||||
+ spin_lock_irqsave(&priv->lock, flags);
|
||||
+ if (ten_bit != priv->ten_bit) {
|
||||
+
|
||||
+ /* disable bus */
|
||||
+ i2c_w32_mask(I2C_RUN_CTRL_RUN_EN, 0, run_ctrl);
|
||||
+
|
||||
+ /* reconfigure address */
|
||||
+ falcon_addr_configure(priv, ten_bit);
|
||||
+
|
||||
+ /* enable bus */
|
||||
+ i2c_w32_mask(0, I2C_RUN_CTRL_RUN_EN, run_ctrl);
|
||||
+
|
||||
+ priv->ten_bit = ten_bit;
|
||||
+ }
|
||||
+ spin_unlock_irqrestore(&priv->lock, flags);
|
||||
+
|
||||
+ /* read/write actual message */
|
||||
+ if (msg->flags & I2C_M_RD)
|
||||
+ ret = falcon_i2c_rx(priv, ten_bit, msg->addr, msg->buf,
|
||||
+ msg->len);
|
||||
+ else
|
||||
+ ret = falcon_i2c_tx(priv, ten_bit, msg->addr, msg->buf,
|
||||
+ msg->len);
|
||||
+
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int falcon_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msg,
|
||||
+ int num)
|
||||
+{
|
||||
+ int i;
|
||||
+ int ret;
|
||||
+ unsigned long flags;
|
||||
+ struct falcon_i2c *priv = i2c_get_adapdata(adap);
|
||||
+
|
||||
+ dev_dbg(priv->dev, "xfer %u messages\n", num);
|
||||
+
|
||||
+ /* transfer each message */
|
||||
+ for (i = 0; i < num; i++) {
|
||||
+#ifdef FALCON_FIX_ME
|
||||
+ /* disable bus */
|
||||
+ i2c_w32_mask(I2C_RUN_CTRL_RUN_EN, 0, run_ctrl);
|
||||
+ /* enable bus */
|
||||
+ i2c_w32_mask(0, I2C_RUN_CTRL_RUN_EN, run_ctrl);
|
||||
+#endif
|
||||
+
|
||||
+ /* clear bus status */
|
||||
+ spin_lock_irqsave(&priv->lock, flags);
|
||||
+ priv->status = 0;
|
||||
+ spin_unlock_irqrestore(&priv->lock, flags);
|
||||
+
|
||||
+ /* wait for the bus to become ready */
|
||||
+ ret = falcon_i2c_ready(priv);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* transfer message */
|
||||
+ ret = falcon_i2c_xfer_msg(priv, &msg[i]);
|
||||
+
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* check for unhandled errors */
|
||||
+ spin_lock_irqsave(&priv->lock, flags);
|
||||
+ if (FALCON_I2C_ERROR(priv))
|
||||
+ ret = priv->status;
|
||||
+ spin_unlock_irqrestore(&priv->lock, flags);
|
||||
+
|
||||
+ if (ret) {
|
||||
+ dev_warn(priv->dev, "message %u unhandled error 0x%x\n",
|
||||
+ i, ret);
|
||||
+
|
||||
+ return ret;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static u32 falcon_i2c_func(struct i2c_adapter *adap)
|
||||
+{
|
||||
+ return I2C_FUNC_I2C | I2C_FUNC_10BIT_ADDR | I2C_FUNC_SMBUS_EMUL;
|
||||
+}
|
||||
+
|
||||
+static struct i2c_algorithm falcon_i2c_algorithm = {
|
||||
+ .master_xfer = falcon_i2c_xfer,
|
||||
+ .functionality = falcon_i2c_func,
|
||||
+};
|
||||
+
|
||||
+static int falcon_i2c_hw_init(struct i2c_adapter *adap)
|
||||
+{
|
||||
+ struct falcon_i2c *priv = i2c_get_adapdata(adap);
|
||||
+
|
||||
+ /* disable bus */
|
||||
+ i2c_w32_mask(I2C_RUN_CTRL_RUN_EN, 0, run_ctrl);
|
||||
+
|
||||
+ /* set normal operation clock divider */
|
||||
+ i2c_w32(1 << I2C_CLC_RMC_OFFSET, clc);
|
||||
+
|
||||
+ /* set frequency */
|
||||
+ if (priv->mode == FALCON_I2C_MODE_100) {
|
||||
+ dev_dbg(priv->dev, "set standard mode (100 kHz)\n");
|
||||
+
|
||||
+ i2c_w32(0, fdiv_high_cfg);
|
||||
+
|
||||
+ i2c_w32((1 << I2C_FDIV_CFG_INC_OFFSET)
|
||||
+ | (499 << I2C_FDIV_CFG_DEC_OFFSET),
|
||||
+ fdiv_cfg);
|
||||
+ } else if (priv->mode == FALCON_I2C_MODE_400) {
|
||||
+ dev_dbg(priv->dev, "set fast mode (400 kHz)\n");
|
||||
+
|
||||
+ i2c_w32(0, fdiv_high_cfg);
|
||||
+
|
||||
+ i2c_w32((1 << I2C_FDIV_CFG_INC_OFFSET)
|
||||
+ | (124 << I2C_FDIV_CFG_DEC_OFFSET),
|
||||
+ fdiv_cfg);
|
||||
+ } else if (priv->mode == FALCON_I2C_MODE_3400) {
|
||||
+ dev_dbg(priv->dev, "set high mode (3.4 MHz)\n");
|
||||
+
|
||||
+ i2c_w32(0, fdiv_cfg);
|
||||
+
|
||||
+ /* TODO recalculate value for 100MHz input */
|
||||
+ i2c_w32((41 << I2C_FDIV_CFG_INC_OFFSET)
|
||||
+ | (152 << I2C_FDIV_CFG_DEC_OFFSET),
|
||||
+ fdiv_high_cfg);
|
||||
+ } else {
|
||||
+ dev_warn(priv->dev, "unknown mode\n");
|
||||
+
|
||||
+ return -ENODEV;
|
||||
+ }
|
||||
+
|
||||
+ /* configure fifo */
|
||||
+ i2c_w32(I2C_FIFO_CFG_TXFC /* tx fifo as flow controller */
|
||||
+ | I2C_FIFO_CFG_RXFC /* rx fifo as flow controller */
|
||||
+ | I2C_FIFO_CFG_TXFA_TXFA2 /* tx fifo 4-byte aligned */
|
||||
+ | I2C_FIFO_CFG_RXFA_RXFA2 /* rx fifo 4-byte aligned */
|
||||
+ | I2C_FIFO_CFG_TXBS_TXBS0 /* tx fifo burst size is 1 word */
|
||||
+ | I2C_FIFO_CFG_RXBS_RXBS0, /* rx fifo burst size is 1 word */
|
||||
+ fifo_cfg);
|
||||
+
|
||||
+ /* configure address */
|
||||
+ falcon_addr_configure(priv, priv->ten_bit);
|
||||
+
|
||||
+ /* enable bus */
|
||||
+ i2c_w32_mask(0, I2C_RUN_CTRL_RUN_EN, run_ctrl);
|
||||
+
|
||||
+ /* mask burst interrupts */
|
||||
+ i2c_w32_mask(I2C_IMSC_LBREQ_INT_EN | I2C_IMSC_BREQ_INT_EN, 0, imsc);
|
||||
+
|
||||
+ /* enable interrupts */
|
||||
+ i2c_w32(I2C_IMSC_LBREQ_INT_EN
|
||||
+ | I2C_IMSC_BREQ_INT_EN
|
||||
+ | I2C_IMSC_I2C_P_INT_EN
|
||||
+ | I2C_IMSC_I2C_ERR_INT_EN,
|
||||
+ imsc);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int __devinit falcon_i2c_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ int ret = 0;
|
||||
+ struct falcon_i2c *priv;
|
||||
+ struct i2c_adapter *adap;
|
||||
+ struct resource *mmres, *ioarea,
|
||||
+ *irqres_lb, *irqres_b, *irqres_err, *irqres_p;
|
||||
+ struct clk *clk;
|
||||
+
|
||||
+ dev_dbg(&pdev->dev, "probing\n");
|
||||
+
|
||||
+ mmres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
+ irqres_lb = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
|
||||
+ "i2c_lb");
|
||||
+ irqres_b = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "i2c_b");
|
||||
+ irqres_err = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
|
||||
+ "i2c_err");
|
||||
+ irqres_p = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "i2c_p");
|
||||
+
|
||||
+ if (!mmres || !irqres_lb || !irqres_b || !irqres_err || !irqres_p) {
|
||||
+ dev_err(&pdev->dev, "no resources\n");
|
||||
+ return -ENODEV;
|
||||
+ }
|
||||
+
|
||||
+ clk = clk_get(&pdev->dev, "fpi");
|
||||
+ if (IS_ERR(clk)) {
|
||||
+ dev_err(&pdev->dev, "failed to get fpi clk\n");
|
||||
+ return -ENOENT;
|
||||
+ }
|
||||
+
|
||||
+ if (clk_get_rate(clk) != 100000000) {
|
||||
+ dev_err(&pdev->dev, "input clock is not 100MHz\n");
|
||||
+ return -ENOENT;
|
||||
+ }
|
||||
+
|
||||
+ /* allocate private data */
|
||||
+ priv = kzalloc(sizeof(*priv), GFP_KERNEL);
|
||||
+ if (!priv) {
|
||||
+ dev_err(&pdev->dev, "can't allocate private data\n");
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ adap = &priv->adap;
|
||||
+ i2c_set_adapdata(adap, priv);
|
||||
+ adap->owner = THIS_MODULE;
|
||||
+ adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
|
||||
+ strlcpy(adap->name, DRV_NAME "-adapter", sizeof(adap->name));
|
||||
+ adap->algo = &falcon_i2c_algorithm;
|
||||
+
|
||||
+ priv->ten_bit = 0;
|
||||
+ priv->mode = FALCON_I2C_MODE_100;
|
||||
+ priv->clk = clk;
|
||||
+ priv->dev = &pdev->dev;
|
||||
+
|
||||
+ spin_lock_init(&priv->lock);
|
||||
+
|
||||
+ ioarea = request_mem_region(mmres->start, resource_size(mmres),
|
||||
+ pdev->name);
|
||||
+
|
||||
+ if (ioarea == NULL) {
|
||||
+ dev_err(&pdev->dev, "I2C region already claimed\n");
|
||||
+ ret = -ENXIO;
|
||||
+ goto err_free_priv;
|
||||
+ }
|
||||
+
|
||||
+ /* map memory */
|
||||
+ priv->membase = ioremap_nocache(mmres->start & ~KSEG1,
|
||||
+ resource_size(mmres));
|
||||
+ if (priv->membase == NULL) {
|
||||
+ ret = -ENOMEM;
|
||||
+ goto err_release_region;
|
||||
+ }
|
||||
+
|
||||
+ priv->irq_lb = irqres_lb->start;
|
||||
+ ret = request_irq(priv->irq_lb, falcon_i2c_isr, IRQF_DISABLED,
|
||||
+ irqres_lb->name, priv);
|
||||
+ if (ret) {
|
||||
+ dev_err(&pdev->dev, "can't get last burst IRQ %d\n", irqres_lb->start);
|
||||
+ ret = -ENODEV;
|
||||
+ goto err_unmap_mem;
|
||||
+ }
|
||||
+
|
||||
+ priv->irq_b = irqres_b->start;
|
||||
+ ret = request_irq(priv->irq_b, falcon_i2c_isr, IRQF_DISABLED,
|
||||
+ irqres_b->name, priv);
|
||||
+ if (ret) {
|
||||
+ dev_err(&pdev->dev, "can't get burst IRQ %d\n", irqres_b->start);
|
||||
+ ret = -ENODEV;
|
||||
+ goto err_free_lb_irq;
|
||||
+ }
|
||||
+
|
||||
+ priv->irq_err = irqres_err->start;
|
||||
+ ret = request_irq(priv->irq_err, falcon_i2c_isr, IRQF_DISABLED,
|
||||
+ irqres_err->name, priv);
|
||||
+ if (ret) {
|
||||
+ dev_err(&pdev->dev, "can't get error IRQ %d\n", irqres_err->start);
|
||||
+ ret = -ENODEV;
|
||||
+ goto err_free_b_irq;
|
||||
+ }
|
||||
+
|
||||
+ priv->irq_p = irqres_p->start;
|
||||
+ ret = request_irq(priv->irq_p, falcon_i2c_isr, IRQF_DISABLED,
|
||||
+ irqres_p->name, priv);
|
||||
+ if (ret) {
|
||||
+ dev_err(&pdev->dev, "can't get protocol IRQ %d\n", irqres_p->start);
|
||||
+ ret = -ENODEV;
|
||||
+ goto err_free_err_irq;
|
||||
+ }
|
||||
+
|
||||
+ dev_dbg(&pdev->dev, "mapped io-space to %p\n", priv->membase);
|
||||
+ dev_dbg(&pdev->dev, "use IRQs %d, %d, %d, %d\n", irqres_lb->start,
|
||||
+ irqres_b->start, irqres_err->start, irqres_p->start);
|
||||
+
|
||||
+ /* add our adapter to the i2c stack */
|
||||
+ ret = i2c_add_numbered_adapter(adap);
|
||||
+ if (ret) {
|
||||
+ dev_err(&pdev->dev, "can't register I2C adapter\n");
|
||||
+ goto err_free_p_irq;
|
||||
+ }
|
||||
+
|
||||
+ platform_set_drvdata(pdev, priv);
|
||||
+ i2c_set_adapdata(adap, priv);
|
||||
+
|
||||
+ /* print module version information */
|
||||
+ dev_dbg(&pdev->dev, "module id=%u revision=%u\n",
|
||||
+ (i2c_r32(id) & I2C_ID_ID_MASK) >> I2C_ID_ID_OFFSET,
|
||||
+ (i2c_r32(id) & I2C_ID_REV_MASK) >> I2C_ID_REV_OFFSET);
|
||||
+
|
||||
+ init_completion(&priv->done);
|
||||
+
|
||||
+ /* initialize HW */
|
||||
+ ret = falcon_i2c_hw_init(adap);
|
||||
+ if (ret) {
|
||||
+ dev_err(&pdev->dev, "can't configure adapter\n");
|
||||
+ goto err_remove_adapter;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+err_remove_adapter:
|
||||
+ i2c_del_adapter(adap);
|
||||
+ platform_set_drvdata(pdev, NULL);
|
||||
+
|
||||
+err_free_p_irq:
|
||||
+ free_irq(priv->irq_p, priv);
|
||||
+
|
||||
+err_free_err_irq:
|
||||
+ free_irq(priv->irq_err, priv);
|
||||
+
|
||||
+err_free_b_irq:
|
||||
+ free_irq(priv->irq_b, priv);
|
||||
+
|
||||
+err_free_lb_irq:
|
||||
+ free_irq(priv->irq_lb, priv);
|
||||
+
|
||||
+err_unmap_mem:
|
||||
+ iounmap(priv->membase);
|
||||
+
|
||||
+err_release_region:
|
||||
+ release_mem_region(mmres->start, resource_size(mmres));
|
||||
+
|
||||
+err_free_priv:
|
||||
+ kfree(priv);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int __devexit falcon_i2c_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct falcon_i2c *priv = platform_get_drvdata(pdev);
|
||||
+ struct resource *mmres;
|
||||
+
|
||||
+ /* disable bus */
|
||||
+ i2c_w32_mask(I2C_RUN_CTRL_RUN_EN, 0, run_ctrl);
|
||||
+
|
||||
+ /* remove driver */
|
||||
+ platform_set_drvdata(pdev, NULL);
|
||||
+ i2c_del_adapter(&priv->adap);
|
||||
+
|
||||
+ free_irq(priv->irq_lb, priv);
|
||||
+ free_irq(priv->irq_b, priv);
|
||||
+ free_irq(priv->irq_err, priv);
|
||||
+ free_irq(priv->irq_p, priv);
|
||||
+
|
||||
+ kfree(priv);
|
||||
+
|
||||
+ mmres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
+ release_mem_region(mmres->start, resource_size(mmres));
|
||||
+
|
||||
+ dev_dbg(&pdev->dev, "removed\n");
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct platform_driver falcon_i2c_driver = {
|
||||
+ .probe = falcon_i2c_probe,
|
||||
+ .remove = __devexit_p(falcon_i2c_remove),
|
||||
+ .driver = {
|
||||
+ .name = DRV_NAME,
|
||||
+ .owner = THIS_MODULE,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static int __init falcon_i2c_init(void)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = platform_driver_register(&falcon_i2c_driver);
|
||||
+
|
||||
+ if (ret)
|
||||
+ printk(KERN_DEBUG DRV_NAME ": can't register platform driver");
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static void __exit falcon_i2c_exit(void)
|
||||
+{
|
||||
+ platform_driver_unregister(&falcon_i2c_driver);
|
||||
+}
|
||||
+
|
||||
+module_init(falcon_i2c_init);
|
||||
+module_exit(falcon_i2c_exit);
|
||||
+
|
||||
+MODULE_DESCRIPTION("Lantiq FALC(tm) ON - I2C bus adapter");
|
||||
+MODULE_ALIAS("platform:i2c_falcon");
|
||||
+MODULE_LICENSE("GPL");
|
|
@ -1,497 +0,0 @@
|
|||
--- a/drivers/spi/Makefile
|
||||
+++ b/drivers/spi/Makefile
|
||||
@@ -55,6 +55,7 @@ obj-$(CONFIG_SPI_SH_SCI) += spi_sh_sci.
|
||||
obj-$(CONFIG_SPI_SH_MSIOF) += spi_sh_msiof.o
|
||||
obj-$(CONFIG_SPI_STMP3XXX) += spi_stmp.o
|
||||
obj-$(CONFIG_SPI_NUC900) += spi_nuc900.o
|
||||
+obj-$(CONFIG_SPI_FALCON) += spi_falcon.o
|
||||
|
||||
# special build for s3c24xx spi driver with fiq support
|
||||
spi_s3c24xx_hw-y := spi_s3c24xx.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/spi/spi_falcon.c
|
||||
@@ -0,0 +1,471 @@
|
||||
+/*
|
||||
+ * 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.
|
||||
+ */
|
||||
+
|
||||
+#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.h> /* ebu_lock */
|
||||
+#include <falcon/ebu_reg.h>
|
||||
+#include <falcon/sys1_reg.h>
|
||||
+
|
||||
+#define DRV_NAME "falcon_spi"
|
||||
+
|
||||
+#define FALCON_SPI_XFER_BEGIN (1 << 0)
|
||||
+#define FALCON_SPI_XFER_END (1 << 1)
|
||||
+
|
||||
+/* mapping for access macros */
|
||||
+#define reg_r32(reg) __raw_readl(reg)
|
||||
+#define reg_w32(val, reg) __raw_writel(val, reg)
|
||||
+#define reg_w32_mask(clear, set, reg) reg_w32((reg_r32(reg) \
|
||||
+ & ~(clear)) | (set), reg)
|
||||
+#define reg_r32_table(reg, idx) reg_r32(&((uint32_t *)®)[idx])
|
||||
+#define reg_w32_table(val, reg, idx) reg_w32(val, &((uint32_t *)®)[idx])
|
||||
+
|
||||
+#define ebu (priv->ebu_membase)
|
||||
+#define sys1 (priv->sys1_membase)
|
||||
+
|
||||
+struct falcon_spi {
|
||||
+ u32 sfcmd; /* for caching of opcode, direction, ... */
|
||||
+
|
||||
+ struct spi_master *master;
|
||||
+
|
||||
+ struct gpon_reg_ebu __iomem *ebu_membase;
|
||||
+ struct gpon_reg_sys1 __iomem *sys1_membase;
|
||||
+};
|
||||
+
|
||||
+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;
|
||||
+ }
|
||||
+ case state_command_prepare: /* collect tx data for
|
||||
+ address and dummy phase */
|
||||
+ {
|
||||
+ /* 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)
|
||||
+ ebu_w32(val, 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)) {
|
||||
+ ebu_w32(val, sfdata);
|
||||
+ ebu_w32(priv->sfcmd
|
||||
+ | (len<<SFCMD_DLEN_OFFSET),
|
||||
+ 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;
|
||||
+ ebu_w32(priv->sfcmd
|
||||
+ |(len<<SFCMD_DLEN_OFFSET), sfcmd);
|
||||
+ priv->sfcmd &= ~(SFCMD_ALEN_MASK
|
||||
+ | SFCMD_DUMLEN_MASK);
|
||||
+ do {
|
||||
+ val = ebu_r32(sfstat);
|
||||
+ if (val & SFSTAT_CMD_ERR) {
|
||||
+ /* reset error status */
|
||||
+ dev_err(dev, "SFSTAT: CMD_ERR "
|
||||
+ "(%x)\n", val);
|
||||
+ ebu_w32(SFSTAT_CMD_ERR, sfstat);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ } while (val & SFSTAT_CMD_PEND);
|
||||
+ val = ebu_r32(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;
|
||||
+ ebu_w32(priv->sfcmd | (0<<SFCMD_DLEN_OFFSET), sfcmd);
|
||||
+ val = ebu_r32(sfstat);
|
||||
+ if (val & SFSTAT_CMD_ERR) {
|
||||
+ /* reset error status */
|
||||
+ dev_err(dev, "SFSTAT: CMD_ERR (%x)\n", val);
|
||||
+ ebu_w32(SFSTAT_CMD_ERR, 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;
|
||||
+ struct falcon_spi *priv = spi_master_get_devdata(spi->master);
|
||||
+ const u32 ebuclk = 100*1000*1000;
|
||||
+ 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 */
|
||||
+ sys1_w32_mask(0, EBUCC_EBUDIV_SELF100, ebucc);
|
||||
+ i = 1; /* divider */
|
||||
+ } else {
|
||||
+ /* set EBU clock to 50 MHz */
|
||||
+ sys1_w32_mask(EBUCC_EBUDIV_SELF100, 0, ebucc);
|
||||
+
|
||||
+ /* search for suitable divider */
|
||||
+ for (i = 1; i < 7; i++) {
|
||||
+ if (ebuclk / i <= spi->max_speed_hz)
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* setup period of serial clock */
|
||||
+ 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)),
|
||||
+ sftime);
|
||||
+
|
||||
+ /* set some bits of unused_wd, to not trigger HOLD/WP
|
||||
+ * signals on non QUAD flashes */
|
||||
+ ebu_w32((SFIO_UNUSED_WD_MASK & (0x8|0x4)), sfio);
|
||||
+
|
||||
+ ebu_w32(BUSRCON0_AGEN_SERIAL_FLASH | BUSRCON0_PORTW_8_BIT_MUX,
|
||||
+ busrcon0);
|
||||
+ ebu_w32(BUSWCON0_AGEN_SERIAL_FLASH, buswcon0);
|
||||
+ /* set address wrap around to maximum for 24-bit addresses */
|
||||
+ ebu_w32_mask(SFCON_DEV_SIZE_MASK, SFCON_DEV_SIZE_A23_0, 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;
|
||||
+ struct resource *memres_ebu, *memres_sys1;
|
||||
+ int ret;
|
||||
+
|
||||
+ dev_dbg(dev, "probing\n");
|
||||
+
|
||||
+ memres_ebu = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ebu");
|
||||
+ memres_sys1 = platform_get_resource_byname(pdev, IORESOURCE_MEM,
|
||||
+ "sys1");
|
||||
+
|
||||
+ if (!memres_ebu || !memres_sys1) {
|
||||
+ dev_err(dev, "no resources\n");
|
||||
+ return -ENODEV;
|
||||
+ }
|
||||
+
|
||||
+ 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->ebu_membase = ioremap_nocache(memres_ebu->start & ~KSEG1,
|
||||
+ resource_size(memres_ebu));
|
||||
+
|
||||
+ if (!priv->ebu_membase) {
|
||||
+ dev_err(dev, "can't map ebu memory\n");
|
||||
+
|
||||
+ ret = -ENOMEM;
|
||||
+ goto free_master;
|
||||
+ }
|
||||
+
|
||||
+ priv->sys1_membase = ioremap_nocache(memres_sys1->start & ~KSEG1,
|
||||
+ resource_size(memres_sys1));
|
||||
+
|
||||
+ if (!priv->sys1_membase) {
|
||||
+ dev_err(dev, "can't map sys1 memory\n");
|
||||
+
|
||||
+ ret = -ENOMEM;
|
||||
+ goto unmap_ebu;
|
||||
+ }
|
||||
+
|
||||
+ 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)
|
||||
+ goto unmap_sys1;
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+unmap_sys1:
|
||||
+ iounmap(priv->sys1_membase);
|
||||
+
|
||||
+unmap_ebu:
|
||||
+ iounmap(priv->ebu_membase);
|
||||
+
|
||||
+free_master:
|
||||
+ 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);
|
||||
+
|
||||
+ iounmap(priv->sys1_membase);
|
||||
+ iounmap(priv->ebu_membase);
|
||||
+
|
||||
+ 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");
|
||||
--- a/drivers/spi/Kconfig
|
||||
+++ b/drivers/spi/Kconfig
|
||||
@@ -210,6 +210,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
|
|
@ -1,193 +0,0 @@
|
|||
--- a/arch/mips/lantiq/falcon/Makefile
|
||||
+++ b/arch/mips/lantiq/falcon/Makefile
|
||||
@@ -2,3 +2,4 @@ obj-y := clk-falcon.o devices.o gpio.o p
|
||||
obj-y += softdog_vpe.o
|
||||
obj-$(CONFIG_LANTIQ_MACH_EASY98000) += addon-easy98000.o
|
||||
obj-$(CONFIG_LANTIQ_MACH_EASY98000) += mach-easy98000.o
|
||||
+obj-$(CONFIG_LANTIQ_MACH_EASY98000) += dev-leds-easy98000-cpld.o
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/lantiq/falcon/dev-leds-easy98000-cpld.c
|
||||
@@ -0,0 +1,160 @@
|
||||
+/*
|
||||
+ * 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/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");
|
||||
+
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/lantiq/falcon/dev-leds-easy98000-cpld.h
|
||||
@@ -0,0 +1,20 @@
|
||||
+/*
|
||||
+ * 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_ */
|
|
@ -1,140 +0,0 @@
|
|||
--- /dev/null
|
||||
+++ b/arch/mips/lantiq/falcon/mach-easy98020.c
|
||||
@@ -0,0 +1,117 @@
|
||||
+#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 "../machtypes.h"
|
||||
+
|
||||
+#include "devices.h"
|
||||
+#include "dev-leds-gpio.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
|
||||
+
|
||||
+extern unsigned char ltq_ethaddr[6];
|
||||
+
|
||||
+#ifdef CONFIG_MTD_PARTITIONS
|
||||
+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)
|
||||
+};
|
||||
+#endif
|
||||
+
|
||||
+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,
|
||||
+#ifdef CONFIG_MTD_PARTITIONS
|
||||
+ .platform_data = &easy98020_spi_flash_platform_data
|
||||
+#endif
|
||||
+};
|
||||
+
|
||||
+static struct gpio_led easy98020_leds_gpio[] __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_asc(0);
|
||||
+ falcon_register_gpio();
|
||||
+ falcon_register_wdt();
|
||||
+ falcon_register_i2c();
|
||||
+ falcon_register_spi_flash(&easy98020_spi_flash_data);
|
||||
+ ltq_add_device_leds_gpio(-1, ARRAY_SIZE(easy98020_leds_gpio),
|
||||
+ easy98020_leds_gpio);
|
||||
+ falcon_register_crypto();
|
||||
+}
|
||||
+
|
||||
+MIPS_MACHINE(LANTIQ_MACH_EASY98020,
|
||||
+ "EASY98020",
|
||||
+ "EASY98020 Eval Board",
|
||||
+ easy98020_init);
|
||||
--- a/arch/mips/lantiq/falcon/Kconfig
|
||||
+++ b/arch/mips/lantiq/falcon/Kconfig
|
||||
@@ -6,6 +6,10 @@ config LANTIQ_MACH_EASY98000
|
||||
bool "Easy98000"
|
||||
default y
|
||||
|
||||
+config LANTIQ_MACH_EASY98020
|
||||
+ bool "Easy98020"
|
||||
+ default y
|
||||
+
|
||||
endmenu
|
||||
|
||||
endif
|
||||
--- a/arch/mips/lantiq/falcon/Makefile
|
||||
+++ b/arch/mips/lantiq/falcon/Makefile
|
||||
@@ -3,3 +3,4 @@ obj-y += softdog_vpe.o
|
||||
obj-$(CONFIG_LANTIQ_MACH_EASY98000) += addon-easy98000.o
|
||||
obj-$(CONFIG_LANTIQ_MACH_EASY98000) += mach-easy98000.o
|
||||
obj-$(CONFIG_LANTIQ_MACH_EASY98000) += dev-leds-easy98000-cpld.o
|
||||
+obj-$(CONFIG_LANTIQ_MACH_EASY98020) += mach-easy98020.o
|
|
@ -1,136 +0,0 @@
|
|||
--- /dev/null
|
||||
+++ b/arch/mips/lantiq/falcon/mach-95C3AM1.c
|
||||
@@ -0,0 +1,103 @@
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/i2c-gpio.h>
|
||||
+#include "../machtypes.h"
|
||||
+
|
||||
+#include "devices.h"
|
||||
+#include "dev-leds-gpio.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
|
||||
+
|
||||
+extern unsigned char ltq_ethaddr[6];
|
||||
+
|
||||
+#ifdef CONFIG_MTD_PARTITIONS
|
||||
+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)
|
||||
+};
|
||||
+#endif
|
||||
+
|
||||
+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,
|
||||
+#ifdef CONFIG_MTD_PARTITIONS
|
||||
+ .platform_data = &board_95C3AM1_flash_platform_data
|
||||
+#endif
|
||||
+};
|
||||
+
|
||||
+static struct gpio_led board_95C3AM1_leds_gpio[] __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_asc(0);
|
||||
+ falcon_register_gpio();
|
||||
+ falcon_register_wdt();
|
||||
+ falcon_register_i2c();
|
||||
+ falcon_register_spi_flash(&board_95C3AM1_flash_data);
|
||||
+ platform_device_register(&board_95C3AM1_i2c_gpio_device);
|
||||
+ ltq_add_device_leds_gpio(-1, ARRAY_SIZE(board_95C3AM1_leds_gpio),
|
||||
+ board_95C3AM1_leds_gpio);
|
||||
+ falcon_register_crypto();
|
||||
+}
|
||||
+
|
||||
+MIPS_MACHINE(LANTIQ_MACH_95C3AM1,
|
||||
+ "95C3AM1",
|
||||
+ "95C3AM1 Board",
|
||||
+ board_95C3AM1_init);
|
||||
--- a/arch/mips/lantiq/falcon/Kconfig
|
||||
+++ b/arch/mips/lantiq/falcon/Kconfig
|
||||
@@ -10,6 +10,10 @@ config LANTIQ_MACH_EASY98020
|
||||
bool "Easy98020"
|
||||
default y
|
||||
|
||||
+config LANTIQ_MACH_95C3AM1
|
||||
+ bool "95C3AM1"
|
||||
+ default y
|
||||
+
|
||||
endmenu
|
||||
|
||||
endif
|
||||
--- a/arch/mips/lantiq/falcon/Makefile
|
||||
+++ b/arch/mips/lantiq/falcon/Makefile
|
||||
@@ -4,3 +4,4 @@ obj-$(CONFIG_LANTIQ_MACH_EASY98000) += a
|
||||
obj-$(CONFIG_LANTIQ_MACH_EASY98000) += mach-easy98000.o
|
||||
obj-$(CONFIG_LANTIQ_MACH_EASY98000) += dev-leds-easy98000-cpld.o
|
||||
obj-$(CONFIG_LANTIQ_MACH_EASY98020) += mach-easy98020.o
|
||||
+obj-$(CONFIG_LANTIQ_MACH_95C3AM1) += mach-95C3AM1.o
|
||||
--- a/arch/mips/lantiq/machtypes.h
|
||||
+++ b/arch/mips/lantiq/machtypes.h
|
||||
@@ -21,6 +21,7 @@ enum lantiq_mach_type {
|
||||
LANTIQ_MACH_EASY98000SF, /* Falcon Eval Board, Serial Flash */
|
||||
LANTIQ_MACH_EASY98000NAND, /* Falcon Eval Board, NAND Flash */
|
||||
LANTIQ_MACH_EASY98020, /* Falcon Reference Board */
|
||||
+ LANTIQ_MACH_95C3AM1, /* Board 95C3AM1 */
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,678 +0,0 @@
|
|||
--- a/arch/mips/lantiq/xway/Kconfig
|
||||
+++ b/arch/mips/lantiq/xway/Kconfig
|
||||
@@ -6,6 +6,10 @@
|
||||
bool "Easy50712 - Danube"
|
||||
default y
|
||||
|
||||
+config LANTIQ_MACH_ARV45XX
|
||||
+ bool "ARV45XX"
|
||||
+ default y
|
||||
+
|
||||
endmenu
|
||||
|
||||
endif
|
||||
--- a/arch/mips/lantiq/xway/Makefile
|
||||
+++ b/arch/mips/lantiq/xway/Makefile
|
||||
@@ -5,3 +5,4 @@
|
||||
|
||||
obj-$(CONFIG_LANTIQ_MACH_EASY50712) += mach-easy50712.o
|
||||
obj-$(CONFIG_LANTIQ_MACH_EASY50601) += mach-easy50601.o
|
||||
+obj-$(CONFIG_LANTIQ_MACH_ARV45XX) += mach-arv45xx.o
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/lantiq/xway/mach-arv45xx.c
|
||||
@@ -0,0 +1,634 @@
|
||||
+/*
|
||||
+ * 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/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/pci.h>
|
||||
+
|
||||
+#include <lantiq_soc.h>
|
||||
+#include <lantiq_platform.h>
|
||||
+
|
||||
+#include "../machtypes.h"
|
||||
+#include "devices.h"
|
||||
+#include "dev-leds-gpio.h"
|
||||
+#include "dev-dwc_otg.h"
|
||||
+#include "../dev-gpio-buttons.h"
|
||||
+
|
||||
+#ifdef CONFIG_MTD_PARTITIONS
|
||||
+static struct mtd_partition arv4510_partitions[] =
|
||||
+{
|
||||
+ {
|
||||
+ .name = "uboot",
|
||||
+ .offset = 0x0,
|
||||
+ .size = 0x20000,
|
||||
+ },
|
||||
+ {
|
||||
+ .name = "uboot_env",
|
||||
+ .offset = 0x20000,
|
||||
+ .size = 0x120000,
|
||||
+ },
|
||||
+ {
|
||||
+ .name = "linux",
|
||||
+ .offset = 0x40000,
|
||||
+ .size = 0xfa0000,
|
||||
+ },
|
||||
+ {
|
||||
+ .name = "board_config",
|
||||
+ .offset = 0xfe0000,
|
||||
+ .size = 0x20000,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static struct mtd_partition arv45xx_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 mtd_partition arv75xx_partitions[] =
|
||||
+{
|
||||
+ {
|
||||
+ .name = "uboot",
|
||||
+ .offset = 0x0,
|
||||
+ .size = 0x10000,
|
||||
+ },
|
||||
+ {
|
||||
+ .name = "uboot_env",
|
||||
+ .offset = 0x10000,
|
||||
+ .size = 0x10000,
|
||||
+ },
|
||||
+ {
|
||||
+ .name = "linux",
|
||||
+ .offset = 0x20000,
|
||||
+ .size = 0x7d0000,
|
||||
+ },
|
||||
+ {
|
||||
+ .name = "board_config",
|
||||
+ .offset = 0x7f0000,
|
||||
+ .size = 0x10000,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static struct mtd_partition arv7525_partitions[] =
|
||||
+{
|
||||
+ {
|
||||
+ .name = "uboot",
|
||||
+ .offset = 0x0,
|
||||
+ .size = 0x10000,
|
||||
+ },
|
||||
+ {
|
||||
+ .name = "uboot_env",
|
||||
+ .offset = 0x10000,
|
||||
+ .size = 0x10000,
|
||||
+ },
|
||||
+ {
|
||||
+ .name = "linux",
|
||||
+ .offset = 0x20000,
|
||||
+ .size = 0x3d0000,
|
||||
+ },
|
||||
+ {
|
||||
+ .name = "board_config",
|
||||
+ .offset = 0x3f0000,
|
||||
+ .size = 0x10000,
|
||||
+ },
|
||||
+};
|
||||
+#endif
|
||||
+
|
||||
+static struct physmap_flash_data arv4510_flash_data = {
|
||||
+#ifdef CONFIG_MTD_PARTITIONS
|
||||
+ .nr_parts = ARRAY_SIZE(arv4510_partitions),
|
||||
+ .parts = arv4510_partitions,
|
||||
+#endif
|
||||
+};
|
||||
+
|
||||
+static struct physmap_flash_data arv45xx_flash_data = {
|
||||
+#ifdef CONFIG_MTD_PARTITIONS
|
||||
+ .nr_parts = ARRAY_SIZE(arv45xx_partitions),
|
||||
+ .parts = arv45xx_partitions,
|
||||
+#endif
|
||||
+};
|
||||
+
|
||||
+static struct physmap_flash_data arv75xx_flash_data = {
|
||||
+#ifdef CONFIG_MTD_PARTITIONS
|
||||
+ .nr_parts = ARRAY_SIZE(arv75xx_partitions),
|
||||
+ .parts = arv75xx_partitions,
|
||||
+#endif
|
||||
+};
|
||||
+
|
||||
+static struct physmap_flash_data arv7525_flash_data = {
|
||||
+#ifdef CONFIG_MTD_PARTITIONS
|
||||
+ .nr_parts = ARRAY_SIZE(arv7525_partitions),
|
||||
+ .parts = arv7525_partitions,
|
||||
+#endif
|
||||
+};
|
||||
+
|
||||
+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_leds_gpio[] __initdata = {
|
||||
+ { .name = "soc:green:foo", .gpio = 4, .active_low = 1, },
|
||||
+};
|
||||
+
|
||||
+static struct gpio_led
|
||||
+arv4518pw_leds_gpio[] __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:wlan", .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 = 72, .active_low = 1, .default_trigger = "default-on" },
|
||||
+ { .name = "soc:green:fxs1", .gpio = 73, .active_low = 1, .default_trigger = "default-on" },
|
||||
+ { .name = "soc:green:fxs2", .gpio = 74, .active_low = 1, .default_trigger = "default-on" },
|
||||
+ { .name = "soc:green:fxo", .gpio = 75, .active_low = 1, .default_trigger = "default-on" },
|
||||
+};
|
||||
+
|
||||
+static struct gpio_keys_button
|
||||
+arv4518pw_gpio_keys[] __initdata = {
|
||||
+ {
|
||||
+ .desc = "wlan",
|
||||
+ .type = EV_KEY,
|
||||
+ .code = BTN_0,
|
||||
+ .debounce_interval = LTQ_KEYS_DEBOUNCE_INTERVAL,
|
||||
+ .gpio = 28,
|
||||
+ .active_low = 1,
|
||||
+ },
|
||||
+ {
|
||||
+ .desc = "wps",
|
||||
+ .type = EV_KEY,
|
||||
+ .code = BTN_1,
|
||||
+ .debounce_interval = LTQ_KEYS_DEBOUNCE_INTERVAL,
|
||||
+ .gpio = 29,
|
||||
+ .active_low = 1,
|
||||
+ },
|
||||
+ {
|
||||
+ .desc = "reset",
|
||||
+ .type = EV_KEY,
|
||||
+ .code = BTN_2,
|
||||
+ .debounce_interval = LTQ_KEYS_DEBOUNCE_INTERVAL,
|
||||
+ .gpio = 30,
|
||||
+ .active_low = 1,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static struct gpio_led
|
||||
+arv4520pw_leds_gpio[] __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 = 72, .active_low = 1, },
|
||||
+ { .name = "soc:blue:fxs1", .gpio = 73, .active_low = 1, },
|
||||
+ { .name = "soc:blue:fxs2", .gpio = 74, .active_low = 1, },
|
||||
+ { .name = "soc:blue:fxo", .gpio = 75, .active_low = 1, },
|
||||
+ { .name = "soc:blue:voice", .gpio = 76, .active_low = 1, },
|
||||
+ { .name = "soc:blue:usb", .gpio = 77, .active_low = 1, },
|
||||
+ { .name = "soc:blue:wlan", .gpio = 78, .active_low = 1, },
|
||||
+};
|
||||
+
|
||||
+static struct gpio_led
|
||||
+arv452cpw_leds_gpio[] __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 = 72, .active_low = 1, .default_trigger = "default-on" },
|
||||
+ { .name = "soc:blue:fxs2", .gpio = 73, .active_low = 1, .default_trigger = "default-on" },
|
||||
+ { .name = "soc:blue:wps", .gpio = 74, .active_low = 1, .default_trigger = "default-on" },
|
||||
+ { .name = "soc:blue:fxo", .gpio = 75, .active_low = 1, .default_trigger = "default-on" },
|
||||
+ { .name = "soc:blue:voice", .gpio = 76, .active_low = 1, .default_trigger = "default-on" },
|
||||
+ { .name = "soc:blue:usb", .gpio = 77, .active_low = 1, .default_trigger = "default-on" },
|
||||
+ { .name = "soc:blue:wlan", .gpio = 78, .active_low = 1, .default_trigger = "default-on" },
|
||||
+ { .name = "soc:blue:internet", .gpio = 80, .active_low = 1, .default_trigger = "default-on" },
|
||||
+ { .name = "soc:red:internet", .gpio = 81, .active_low = 1, .default_trigger = "default-on" },
|
||||
+};
|
||||
+
|
||||
+static struct gpio_led
|
||||
+arv4525pw_leds_gpio[] __initdata = {
|
||||
+ { .name = "soc:green:festnetz", .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:dsl", .gpio = 6, .active_low = 1, .default_trigger = "default-on" },
|
||||
+ { .name = "soc:green:wlan", .gpio = 8, .active_low = 1, .default_trigger = "default-on" },
|
||||
+ { .name = "soc:green:online", .gpio = 9, .active_low = 1, .default_trigger = "default-on" },
|
||||
+};
|
||||
+
|
||||
+static struct gpio_led
|
||||
+arv752dpw22_leds_gpio[] __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 = 75, .active_low = 1, .default_trigger = "default-on" },
|
||||
+ { .name = "soc:red:voice", .gpio = 76, .active_low = 1, .default_trigger = "default-on" },
|
||||
+ { .name = "soc:green:usb", .gpio = 77, .active_low = 1, .default_trigger = "default-on" },
|
||||
+ { .name = "soc:green:wlan", .gpio = 78, .active_low = 1, .default_trigger = "default-on" },
|
||||
+ { .name = "soc:green:wlan1", .gpio = 79, .active_low = 1, .default_trigger = "default-on" },
|
||||
+ { .name = "soc:blue:wlan", .gpio = 80, .active_low = 1, .default_trigger = "default-on" },
|
||||
+ { .name = "soc:blue:wlan1", .gpio = 81, .active_low = 1, .default_trigger = "default-on" },
|
||||
+ { .name = "soc:green:eth1", .gpio = 83, .active_low = 1, .default_trigger = "default-on" },
|
||||
+ { .name = "soc:green:eth2", .gpio = 84, .active_low = 1, .default_trigger = "default-on" },
|
||||
+ { .name = "soc:green:eth3", .gpio = 85, .active_low = 1, .default_trigger = "default-on" },
|
||||
+ { .name = "soc:green:eth4", .gpio = 86, .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_leds_gpio[] __initdata = {
|
||||
+ { .name = "soc:green:power", .gpio = 2, .active_low = 1, },
|
||||
+ { .name = "soc:green:adsl", .gpio = 4, .active_low = 1, },
|
||||
+ { .name = "soc:green:internet", .gpio = 5, .active_low = 1, },
|
||||
+ { .name = "soc:green:wlan", .gpio = 6, .active_low = 1, },
|
||||
+ { .name = "soc:red:internet", .gpio = 8, .active_low = 1, },
|
||||
+ { .name = "soc:green:usb", .gpio = 19, .active_low = 1, },
|
||||
+};
|
||||
+
|
||||
+static struct gpio_keys_button
|
||||
+arv7518pw_gpio_keys[] __initdata = {
|
||||
+ {
|
||||
+ .desc = "reset",
|
||||
+ .type = EV_KEY,
|
||||
+ .code = BTN_0,
|
||||
+ .debounce_interval = LTQ_KEYS_DEBOUNCE_INTERVAL,
|
||||
+ .gpio = 23,
|
||||
+ .active_low = 1,
|
||||
+ },
|
||||
+ {
|
||||
+ .desc = "wlan",
|
||||
+ .type = EV_KEY,
|
||||
+ .code = BTN_1,
|
||||
+ .debounce_interval = LTQ_KEYS_DEBOUNCE_INTERVAL,
|
||||
+ .gpio = 25,
|
||||
+ .active_low = 1,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static void
|
||||
+arv45xx_register_ethernet(void)
|
||||
+{
|
||||
+#define ARV45XX_BRN_MAC 0x3f0016
|
||||
+ memcpy_fromio(<q_eth_data.mac.sa_data,
|
||||
+ (void *)KSEG1ADDR(LTQ_FLASH_START + ARV45XX_BRN_MAC), 6);
|
||||
+ ltq_register_etop(<q_eth_data);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+arv75xx_register_ethernet(void)
|
||||
+{
|
||||
+#define ARV75XX_BRN_MAC 0x7f0016
|
||||
+ memcpy_fromio(<q_eth_data.mac.sa_data,
|
||||
+ (void *)KSEG1ADDR(LTQ_FLASH_START + ARV75XX_BRN_MAC), 6);
|
||||
+ ltq_register_etop(<q_eth_data);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+bewan_register_ethernet(void)
|
||||
+{
|
||||
+#define BEWAN_BRN_MAC 0x3f0014
|
||||
+ memcpy_fromio(<q_eth_data.mac.sa_data,
|
||||
+ (void *)KSEG1ADDR(LTQ_FLASH_START + BEWAN_BRN_MAC), 6);
|
||||
+ ltq_register_etop(<q_eth_data);
|
||||
+}
|
||||
+
|
||||
+static u16 arv45xx_ath5k_eeprom_data[ATH5K_PLAT_EEP_MAX_WORDS];
|
||||
+static struct ath5k_platform_data arv45xx_ath5k_platform_data;
|
||||
+
|
||||
+/*static int arv45xx_pci_plat_dev_init(struct pci_dev *dev)
|
||||
+{
|
||||
+ dev->dev.platform_data = &arv45xx_ath5k_platform_data;
|
||||
+ return 0;
|
||||
+}
|
||||
+*/
|
||||
+void __init
|
||||
+arv45xx_register_ath5k(void)
|
||||
+{
|
||||
+#define ARV45XX_BRN_ATH 0x3f0478
|
||||
+ int i;
|
||||
+ unsigned char eeprom_mac[6];
|
||||
+ static u16 eeprom_data[ATH5K_PLAT_EEP_MAX_WORDS];
|
||||
+ u32 *p = (u32*)arv45xx_ath5k_eeprom_data;
|
||||
+
|
||||
+ memcpy_fromio(eeprom_mac,
|
||||
+ (void *)KSEG1ADDR(LTQ_FLASH_START + ARV45XX_BRN_MAC), 6);
|
||||
+ eeprom_mac[5]++;
|
||||
+ memcpy_fromio(arv45xx_ath5k_eeprom_data,
|
||||
+ (void *)KSEG1ADDR(LTQ_FLASH_START + ARV45XX_BRN_ATH), ATH5K_PLAT_EEP_MAX_WORDS);
|
||||
+ // swap eeprom bytes
|
||||
+ for (i = 0; i < ATH5K_PLAT_EEP_MAX_WORDS>>1; i++){
|
||||
+ //arv4518_ath5k_eeprom_data[i] = ((eeprom_data[i]&0xff)<<8)|((eeprom_data[i]&0xff00)>>8);
|
||||
+ p[i] = ((eeprom_data[(i<<1)+1]&0xff)<<24)|((eeprom_data[(i<<1)+1]&0xff00)<<8)|((eeprom_data[i<<1]&0xff)<<8)|((eeprom_data[i<<1]&0xff00)>>8);
|
||||
+ if (i == 0xbf>>1){
|
||||
+ // printk ("regdomain: 0x%x --> 0x%x\n", p[i], (p[i] & 0xffff0000)|0x67);
|
||||
+ /* regdomain is invalid?? how did original fw convert
|
||||
+ * value to 0x82d4 ??
|
||||
+ * for now, force to 0x67 */
|
||||
+ p[i] &= 0xffff0000;
|
||||
+ p[i] |= 0x67;
|
||||
+ }
|
||||
+ }
|
||||
+ arv45xx_ath5k_platform_data.eeprom_data = arv45xx_ath5k_eeprom_data;
|
||||
+ arv45xx_ath5k_platform_data.macaddr = eeprom_mac;
|
||||
+ //lqpci_plat_dev_init = arv45xx_pci_plat_dev_init;
|
||||
+}
|
||||
+
|
||||
+static void __init
|
||||
+arv3527p_init(void)
|
||||
+{
|
||||
+ ltq_register_gpio_stp();
|
||||
+ //ltq_add_device_leds_gpio(arv3527p_leds_gpio, ARRAY_SIZE(arv3527p_leds_gpio));
|
||||
+ ltq_register_nor(&arv45xx_flash_data);
|
||||
+ arv45xx_register_ethernet();
|
||||
+}
|
||||
+
|
||||
+MIPS_MACHINE(LANTIQ_MACH_ARV3527P,
|
||||
+ "ARV3527P",
|
||||
+ "ARV3527P - Arcor Easybox 401",
|
||||
+ arv3527p_init);
|
||||
+
|
||||
+static void __init
|
||||
+arv4510pw_init(void)
|
||||
+{
|
||||
+ ltq_register_gpio_stp();
|
||||
+ ltq_add_device_leds_gpio(-1, ARRAY_SIZE(arv4510pw_leds_gpio), arv4510pw_leds_gpio);
|
||||
+ ltq_register_nor(&arv4510_flash_data);
|
||||
+ 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(<q_pci_data);
|
||||
+ bewan_register_ethernet();
|
||||
+}
|
||||
+
|
||||
+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_MADWIFI_ADDR 0xb07f0400
|
||||
+
|
||||
+ ltq_register_gpio_ebu(ARV4518PW_EBU);
|
||||
+ ltq_add_device_leds_gpio(-1, ARRAY_SIZE(arv4518pw_leds_gpio), arv4518pw_leds_gpio);
|
||||
+ ltq_register_gpio_keys_polled(-1, LTQ_KEYS_POLL_INTERVAL, ARRAY_SIZE(arv4518pw_gpio_keys), arv4518pw_gpio_keys);
|
||||
+ ltq_register_nor(&arv45xx_flash_data);
|
||||
+ ltq_pci_data.gpio = PCI_GNT2 | PCI_REQ2;
|
||||
+ ltq_register_pci(<q_pci_data);
|
||||
+ ltq_register_madwifi_eep(ARV4518PW_MADWIFI_ADDR);
|
||||
+ xway_register_dwc(ARV4518PW_USB);
|
||||
+ arv45xx_register_ethernet();
|
||||
+ arv45xx_register_ath5k();
|
||||
+
|
||||
+ 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
|
||||
+arv4520pw_init(void)
|
||||
+{
|
||||
+#define ARV4520PW_EBU 0x400
|
||||
+#define ARV4520PW_USB 28
|
||||
+#define ARV4520PW_SWITCH_RESET 82
|
||||
+
|
||||
+ ltq_register_gpio_ebu(ARV4520PW_EBU);
|
||||
+ ltq_add_device_leds_gpio(-1, ARRAY_SIZE(arv4520pw_leds_gpio), arv4520pw_leds_gpio);
|
||||
+ ltq_register_nor(&arv45xx_flash_data);
|
||||
+ ltq_register_pci(<q_pci_data);
|
||||
+ ltq_register_tapi();
|
||||
+ arv45xx_register_ethernet();
|
||||
+ 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 79
|
||||
+#define ARV452CPW_SWITCH_RESET 82
|
||||
+#define ARV452CPW_MADWIFI_ADDR 0xb07f0400
|
||||
+
|
||||
+ ltq_register_gpio_ebu(ARV452CPW_EBU);
|
||||
+ ltq_add_device_leds_gpio(-1, ARRAY_SIZE(arv452cpw_leds_gpio), arv452cpw_leds_gpio);
|
||||
+ ltq_register_nor(&arv45xx_flash_data);
|
||||
+ ltq_register_pci(<q_pci_data);
|
||||
+ ltq_register_madwifi_eep(ARV452CPW_MADWIFI_ADDR);
|
||||
+ xway_register_dwc(ARV452CPW_USB);
|
||||
+ arv45xx_register_ethernet();
|
||||
+ arv45xx_register_ath5k();
|
||||
+
|
||||
+ 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_MADWIFI_ADDR 0xb07f0400
|
||||
+
|
||||
+ ltq_add_device_leds_gpio(-1, ARRAY_SIZE(arv4525pw_leds_gpio), arv4525pw_leds_gpio);
|
||||
+ ltq_register_nor(&arv45xx_flash_data);
|
||||
+ ltq_pci_data.clock = PCI_CLOCK_INT;
|
||||
+ ltq_register_pci(<q_pci_data);
|
||||
+ ltq_register_madwifi_eep(ARV4525PW_MADWIFI_ADDR);
|
||||
+ ltq_eth_data.mii_mode = PHY_INTERFACE_MODE_MII;
|
||||
+ arv45xx_register_ethernet();
|
||||
+}
|
||||
+
|
||||
+MIPS_MACHINE(LANTIQ_MACH_ARV4525PW,
|
||||
+ "ARV4525PW",
|
||||
+ "ARV4525PW - Speedport W502V",
|
||||
+ arv4525pw_init);
|
||||
+
|
||||
+static void __init
|
||||
+arv7525pw_init(void)
|
||||
+{
|
||||
+ ltq_add_device_leds_gpio(-1, ARRAY_SIZE(arv4525pw_leds_gpio), arv4525pw_leds_gpio);
|
||||
+ ltq_register_nor(&arv7525_flash_data);
|
||||
+ ltq_register_pci(<q_pci_data);
|
||||
+ ltq_eth_data.mii_mode = PHY_INTERFACE_MODE_MII;
|
||||
+ ltq_register_tapi();
|
||||
+ arv45xx_register_ethernet();
|
||||
+}
|
||||
+
|
||||
+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
|
||||
+
|
||||
+ ltq_register_gpio_ebu(ARV7518PW_EBU);
|
||||
+ ltq_add_device_leds_gpio(-1, ARRAY_SIZE(arv7518pw_leds_gpio), arv7518pw_leds_gpio);
|
||||
+ ltq_register_gpio_keys_polled(-1, LTQ_KEYS_POLL_INTERVAL, ARRAY_SIZE(arv7518pw_gpio_keys), arv7518pw_gpio_keys);
|
||||
+ ltq_register_nor(&arv75xx_flash_data);
|
||||
+ ltq_register_pci(<q_pci_data);
|
||||
+ ltq_register_tapi();
|
||||
+ xway_register_dwc(ARV7518PW_USB);
|
||||
+ arv75xx_register_ethernet();
|
||||
+ //arv7518_register_ath9k(mac);
|
||||
+}
|
||||
+
|
||||
+MIPS_MACHINE(LANTIQ_MACH_ARV7518PW,
|
||||
+ "ARV7518PW",
|
||||
+ "ARV7518PW - ASTORIA",
|
||||
+ arv7518pw_init);
|
||||
+
|
||||
+
|
||||
+static void __init
|
||||
+arv752dpw_init(void)
|
||||
+{
|
||||
+#define ARV752DPW22_EBU 0x2
|
||||
+#define ARV752DPW22_USB 72
|
||||
+#define ARV752DPW22_RELAY 73
|
||||
+ ltq_register_gpio_ebu(ARV752DPW22_EBU);
|
||||
+ ltq_add_device_leds_gpio(-1, ARRAY_SIZE(arv752dpw22_leds_gpio), arv752dpw22_leds_gpio);
|
||||
+ ltq_register_gpio_keys_polled(-1, LTQ_KEYS_POLL_INTERVAL, ARRAY_SIZE(arv752dpw22_gpio_keys), arv752dpw22_gpio_keys);
|
||||
+ ltq_register_nor(&arv75xx_flash_data);
|
||||
+ ltq_register_pci(<q_pci_data);
|
||||
+ xway_register_dwc(ARV752DPW22_USB);
|
||||
+ arv75xx_register_ethernet();
|
||||
+ 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);
|
||||
+
|
||||
+static void __init
|
||||
+arv752dpw22_init(void)
|
||||
+{
|
||||
+#define ARV752DPW22_EBU 0x2
|
||||
+#define ARV752DPW22_USB 72
|
||||
+#define ARV752DPW22_RELAY 73
|
||||
+
|
||||
+ ltq_register_gpio_ebu(ARV752DPW22_EBU);
|
||||
+ ltq_add_device_leds_gpio(-1, ARRAY_SIZE(arv752dpw22_leds_gpio), arv752dpw22_leds_gpio);
|
||||
+ ltq_register_gpio_keys_polled(-1, LTQ_KEYS_POLL_INTERVAL, ARRAY_SIZE(arv752dpw22_gpio_keys), arv752dpw22_gpio_keys);
|
||||
+ ltq_register_nor(&arv75xx_flash_data);
|
||||
+ ltq_pci_data.irq[15] = (INT_NUM_IM3_IRL0 + 31);
|
||||
+ ltq_pci_data.gpio |= PCI_EXIN1 | PCI_REQ2;
|
||||
+ ltq_register_pci(<q_pci_data);
|
||||
+ xway_register_dwc(ARV752DPW22_USB);
|
||||
+ arv75xx_register_ethernet();
|
||||
+
|
||||
+ 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);
|
||||
--- a/arch/mips/lantiq/machtypes.h
|
||||
+++ b/arch/mips/lantiq/machtypes.h
|
||||
@@ -22,6 +22,18 @@
|
||||
LANTIQ_MACH_EASY98000NAND, /* Falcon Eval Board, NAND Flash */
|
||||
LANTIQ_MACH_EASY98020, /* Falcon Reference Board */
|
||||
LANTIQ_MACH_95C3AM1, /* Board 95C3AM1 */
|
||||
+
|
||||
+ /* Arcadyan */
|
||||
+ LANTIQ_MACH_ARV3527P, /* Arcor easybox a401 */
|
||||
+ LANTIQ_MACH_ARV4510PW, /* Wippies Homebox */
|
||||
+ LANTIQ_MACH_ARV4518PW, /* Airties WAV-221, SMC-7908A-ISP */
|
||||
+ LANTIQ_MACH_ARV4520PW, /* Airties WAV-281, Arcor EasyboxA800 */
|
||||
+ LANTIQ_MACH_ARV452CPW, /* Arcor EasyboxA801 */
|
||||
+ LANTIQ_MACH_ARV4525PW, /* Speedport W502V */
|
||||
+ LANTIQ_MACH_ARV7525PW, /* Speedport W303V Typ A */
|
||||
+ LANTIQ_MACH_ARV752DPW, /* Arcor easybox a802 */
|
||||
+ LANTIQ_MACH_ARV752DPW22, /* Arcor easybox a803 */
|
||||
+ LANTIQ_MACH_ARV7518PW, /* ASTORIA */
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,116 +0,0 @@
|
|||
--- a/drivers/mtd/Kconfig
|
||||
+++ b/drivers/mtd/Kconfig
|
||||
@@ -57,6 +57,10 @@ config MTD_ROOTFS_SPLIT
|
||||
depends on MTD_PARTITIONS
|
||||
default y
|
||||
|
||||
+config MTD_UIMAGE_SPLIT
|
||||
+ bool "Automatically split 'linux' partition into 'kernel' and 'rootfs'"
|
||||
+ default y
|
||||
+
|
||||
config MTD_REDBOOT_PARTS
|
||||
tristate "RedBoot partition table parsing"
|
||||
---help---
|
||||
--- a/drivers/mtd/mtdpart.c
|
||||
+++ b/drivers/mtd/mtdpart.c
|
||||
@@ -860,6 +860,82 @@ static int refresh_rootfs_split(struct m
|
||||
}
|
||||
#endif /* CONFIG_MTD_ROOTFS_SPLIT */
|
||||
|
||||
+
|
||||
+#ifdef CONFIG_MTD_UIMAGE_SPLIT
|
||||
+static unsigned long find_uimage_size(struct mtd_info *mtd,
|
||||
+ unsigned long offset)
|
||||
+{
|
||||
+#define UBOOT_MAGIC 0x56190527
|
||||
+ unsigned long magic = 0;
|
||||
+ unsigned long temp;
|
||||
+ size_t len;
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = mtd->read(mtd, offset, 4, &len, (void *)&magic);
|
||||
+ if (ret || len != sizeof(magic))
|
||||
+ return 0;
|
||||
+
|
||||
+ if (le32_to_cpu(magic) != UBOOT_MAGIC)
|
||||
+ return 0;
|
||||
+
|
||||
+ ret = mtd->read(mtd, offset + 12, 4, &len, (void *)&temp);
|
||||
+ if (ret || len != sizeof(temp))
|
||||
+ return 0;
|
||||
+
|
||||
+ return temp + 0x40;
|
||||
+}
|
||||
+
|
||||
+static int detect_squashfs_partition(struct mtd_info *mtd, unsigned long offset)
|
||||
+{
|
||||
+ unsigned long temp;
|
||||
+ size_t len;
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = mtd->read(mtd, offset, 4, &len, (void *)&temp);
|
||||
+ if (ret || len != sizeof(temp))
|
||||
+ return 0;
|
||||
+
|
||||
+ return le32_to_cpu(temp) == SQUASHFS_MAGIC;
|
||||
+}
|
||||
+
|
||||
+static int split_uimage(struct mtd_info *mtd,
|
||||
+ const struct mtd_partition *part)
|
||||
+{
|
||||
+ static struct mtd_partition split_partitions[] = {
|
||||
+ {
|
||||
+ .name = "kernel",
|
||||
+ .offset = 0x0,
|
||||
+ .size = 0x0,
|
||||
+ }, {
|
||||
+ .name = "rootfs",
|
||||
+ .offset = 0x0,
|
||||
+ .size = 0x0,
|
||||
+ },
|
||||
+ };
|
||||
+
|
||||
+ split_partitions[0].size = find_uimage_size(mtd, part->offset);
|
||||
+ if (!split_partitions[0].size) {
|
||||
+ printk(KERN_NOTICE "no uImage found in linux partition\n");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ if (!detect_squashfs_partition(mtd,
|
||||
+ part->offset
|
||||
+ + split_partitions[0].size)) {
|
||||
+ split_partitions[0].size &= ~(mtd->erasesize - 1);
|
||||
+ split_partitions[0].size += mtd->erasesize;
|
||||
+ }
|
||||
+
|
||||
+ split_partitions[0].offset = part->offset;
|
||||
+ split_partitions[1].offset = part->offset + split_partitions[0].size;
|
||||
+ split_partitions[1].size = part->size - split_partitions[0].size;
|
||||
+
|
||||
+ add_mtd_partitions(mtd, split_partitions, 2);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
/*
|
||||
* This function, given a master MTD object and a partition table, creates
|
||||
* and registers slave MTD objects which are bound to the master according to
|
||||
@@ -893,6 +969,17 @@ int add_mtd_partitions(struct mtd_info *
|
||||
|
||||
add_mtd_device(&slave->mtd);
|
||||
|
||||
+#ifdef CONFIG_MTD_UIMAGE_SPLIT
|
||||
+ if (!strcmp(parts[i].name, "linux")) {
|
||||
+ ret = split_uimage(master, &parts[i]);
|
||||
+
|
||||
+ if (ret) {
|
||||
+ printk(KERN_WARNING
|
||||
+ "Can't split linux partition\n");
|
||||
+ }
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
if (!strcmp(parts[i].name, "rootfs")) {
|
||||
#ifdef CONFIG_MTD_ROOTFS_ROOT_DEV
|
||||
if (ROOT_DEV == 0) {
|
|
@ -1,42 +0,0 @@
|
|||
--- a/arch/mips/mm/cache.c
|
||||
+++ b/arch/mips/mm/cache.c
|
||||
@@ -52,6 +52,8 @@ void (*_dma_cache_wback)(unsigned long s
|
||||
void (*_dma_cache_inv)(unsigned long start, unsigned long size);
|
||||
|
||||
EXPORT_SYMBOL(_dma_cache_wback_inv);
|
||||
+EXPORT_SYMBOL(_dma_cache_wback);
|
||||
+EXPORT_SYMBOL(_dma_cache_inv);
|
||||
|
||||
#endif /* CONFIG_DMA_NONCOHERENT */
|
||||
|
||||
--- a/net/atm/proc.c
|
||||
+++ b/net/atm/proc.c
|
||||
@@ -154,7 +154,7 @@ static void *vcc_seq_next(struct seq_fil
|
||||
static void pvc_info(struct seq_file *seq, struct atm_vcc *vcc)
|
||||
{
|
||||
static const char *const class_name[] = {
|
||||
- "off", "UBR", "CBR", "VBR", "ABR"};
|
||||
+ "off","UBR","CBR","NTR-VBR","ABR","ANY","RT-VBR","UBR+","GFR"};
|
||||
static const char *const aal_name[] = {
|
||||
"---", "1", "2", "3/4", /* 0- 3 */
|
||||
"???", "5", "???", "???", /* 4- 7 */
|
||||
--- a/net/atm/common.c
|
||||
+++ b/net/atm/common.c
|
||||
@@ -62,11 +62,17 @@ static void vcc_remove_socket(struct soc
|
||||
write_unlock_irq(&vcc_sklist_lock);
|
||||
}
|
||||
|
||||
+struct sk_buff* (*ifx_atm_alloc_tx)(struct atm_vcc *, unsigned int) = NULL;
|
||||
+EXPORT_SYMBOL(ifx_atm_alloc_tx);
|
||||
+
|
||||
static struct sk_buff *alloc_tx(struct atm_vcc *vcc, unsigned int size)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
struct sock *sk = sk_atm(vcc);
|
||||
|
||||
+ if (ifx_atm_alloc_tx != NULL)
|
||||
+ return ifx_atm_alloc_tx(vcc, size);
|
||||
+
|
||||
if (sk_wmem_alloc_get(sk) && !atm_may_send(vcc, size)) {
|
||||
pr_debug("Sorry: wmem_alloc = %d, size = %d, sndbuf = %d\n",
|
||||
sk_wmem_alloc_get(sk), size, sk->sk_sndbuf);
|
|
@ -1,348 +0,0 @@
|
|||
--- /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
|
||||
--- /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* */
|
||||
--- a/net/ipv4/Makefile
|
||||
+++ b/net/ipv4/Makefile
|
||||
@@ -14,6 +14,9 @@ obj-y := route.o inetpeer.o protocol
|
||||
inet_fragment.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
|
||||
@@ -107,6 +107,10 @@
|
||||
#include <net/xfrm.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);
|
||||
|
||||
@@ -802,7 +806,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;
|
||||
|
||||
if (len > 0xFFFF)
|
||||
@@ -818,7 +822,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;
|
||||
|
||||
if (up->pending) {
|
||||
/*
|
||||
@@ -1608,6 +1618,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.
|
||||
@@ -1640,7 +1651,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
|
||||
@@ -1937,7 +1957,7 @@ struct proto udp_prot = {
|
||||
.clear_sk = sk_prot_clear_portaddr_nulls,
|
||||
};
|
||||
EXPORT_SYMBOL(udp_prot);
|
||||
-
|
||||
+EXPORT_SYMBOL(udp_rcv);
|
||||
/* ------------------------------------------------------------------------ */
|
||||
#ifdef CONFIG_PROC_FS
|
||||
|
||||
--- 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"
|
|
@ -1,301 +0,0 @@
|
|||
--- a/arch/mips/Kconfig
|
||||
+++ b/arch/mips/Kconfig
|
||||
@@ -1878,6 +1878,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
|
||||
@@ -128,6 +128,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)
|
||||
@@ -866,6 +873,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
|
||||
@@ -1345,6 +1345,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);
|
||||
@@ -1364,6 +1464,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();
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
--- a/drivers/mtd/devices/m25p80.c
|
||||
+++ b/drivers/mtd/devices/m25p80.c
|
||||
@@ -1,3 +1,5 @@
|
||||
+
|
||||
+
|
||||
/*
|
||||
* MTD SPI driver for ST M25Pxx (and similar) serial flash chips
|
||||
*
|
|
@ -1,17 +0,0 @@
|
|||
--- a/drivers/net/lantiq_etop.c
|
||||
+++ b/drivers/net/lantiq_etop.c
|
||||
@@ -155,8 +155,12 @@ ltq_etop_hw_receive(struct ltq_etop_chan
|
||||
|
||||
skb_put(skb, len);
|
||||
skb->dev = ch->netdev;
|
||||
- skb->protocol = eth_type_trans(skb, ch->netdev);
|
||||
- netif_receive_skb(skb);
|
||||
+ if (priv->phydev && priv->phydev->netif_receive_skb) {
|
||||
+ priv->phydev->netif_receive_skb(skb);
|
||||
+ } else {
|
||||
+ skb->protocol = eth_type_trans(skb, ch->netdev);
|
||||
+ netif_receive_skb(skb);
|
||||
+ }
|
||||
}
|
||||
|
||||
static int
|
|
@ -1,116 +0,0 @@
|
|||
--- a/drivers/net/dm9000.c
|
||||
+++ b/drivers/net/dm9000.c
|
||||
@@ -19,6 +19,7 @@
|
||||
* Sascha Hauer <s.hauer@pengutronix.de>
|
||||
*/
|
||||
|
||||
+#define DEBUG
|
||||
#include <linux/module.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/netdevice.h>
|
||||
@@ -125,6 +126,8 @@ typedef struct board_info {
|
||||
struct delayed_work phy_poll;
|
||||
struct net_device *ndev;
|
||||
|
||||
+ struct delayed_work irq_poll; /* for use in irq polling mode */
|
||||
+
|
||||
spinlock_t lock;
|
||||
|
||||
struct mii_if_info mii;
|
||||
@@ -855,6 +858,8 @@ static void dm9000_timeout(struct net_de
|
||||
netif_stop_queue(dev);
|
||||
dm9000_reset(db);
|
||||
dm9000_init_dm9000(dev);
|
||||
+ dm9000_reset(db);
|
||||
+ dm9000_init_dm9000(dev);
|
||||
/* We can accept TX packets again */
|
||||
dev->trans_start = jiffies; /* prevent tx timeout */
|
||||
netif_wake_queue(dev);
|
||||
@@ -926,6 +931,12 @@ dm9000_start_xmit(struct sk_buff *skb, s
|
||||
/* free this SKB */
|
||||
dev_kfree_skb(skb);
|
||||
|
||||
+ /* directly poll afterwards */
|
||||
+ if (dev->irq == -1) {
|
||||
+ cancel_delayed_work(&db->irq_poll);
|
||||
+ schedule_delayed_work(&db->irq_poll, 1);
|
||||
+ }
|
||||
+
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
|
||||
@@ -1167,6 +1178,18 @@ static void dm9000_poll_controller(struc
|
||||
}
|
||||
#endif
|
||||
|
||||
+static void dm9000_poll_irq(struct work_struct *w)
|
||||
+{
|
||||
+ struct delayed_work *dw = to_delayed_work(w);
|
||||
+ board_info_t *db = container_of(dw, board_info_t, irq_poll);
|
||||
+ struct net_device *ndev = db->ndev;
|
||||
+
|
||||
+ dm9000_interrupt(0, ndev);
|
||||
+
|
||||
+ if (netif_running(ndev))
|
||||
+ schedule_delayed_work(&db->irq_poll, HZ /100);
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Open the interface.
|
||||
* The interface is opened whenever "ifconfig" actives it.
|
||||
@@ -1180,17 +1203,18 @@ dm9000_open(struct net_device *dev)
|
||||
if (netif_msg_ifup(db))
|
||||
dev_dbg(db->dev, "enabling %s\n", dev->name);
|
||||
|
||||
- /* If there is no IRQ type specified, default to something that
|
||||
- * may work, and tell the user that this is a problem */
|
||||
+ if (dev->irq != -1) {
|
||||
+ /* If there is no IRQ type specified, default to something that
|
||||
+ * may work, and tell the user that this is a problem */
|
||||
|
||||
- if (irqflags == IRQF_TRIGGER_NONE)
|
||||
- dev_warn(db->dev, "WARNING: no IRQ resource flags set.\n");
|
||||
+ if (irqflags == IRQF_TRIGGER_NONE)
|
||||
+ dev_warn(db->dev, "WARNING: no IRQ resource flags set.\n");
|
||||
|
||||
- irqflags |= IRQF_SHARED;
|
||||
-
|
||||
- if (request_irq(dev->irq, dm9000_interrupt, irqflags, dev->name, dev))
|
||||
- return -EAGAIN;
|
||||
+ irqflags |= IRQF_SHARED;
|
||||
|
||||
+ if (request_irq(dev->irq, dm9000_interrupt, irqflags, dev->name, dev))
|
||||
+ return -EAGAIN;
|
||||
+ }
|
||||
/* GPIO0 on pre-activate PHY, Reg 1F is not set by reset */
|
||||
iow(db, DM9000_GPR, 0); /* REG_1F bit0 activate phyxcer */
|
||||
mdelay(1); /* delay needs by DM9000B */
|
||||
@@ -1198,13 +1222,19 @@ dm9000_open(struct net_device *dev)
|
||||
/* Initialize DM9000 board */
|
||||
dm9000_reset(db);
|
||||
dm9000_init_dm9000(dev);
|
||||
+ /* testing: init a second time */
|
||||
+ dm9000_reset(db);
|
||||
+ dm9000_init_dm9000(dev);
|
||||
|
||||
/* Init driver variable */
|
||||
db->dbug_cnt = 0;
|
||||
|
||||
mii_check_media(&db->mii, netif_msg_link(db), 1);
|
||||
netif_start_queue(dev);
|
||||
-
|
||||
+
|
||||
+ if (dev->irq == -1)
|
||||
+ schedule_delayed_work(&db->irq_poll, HZ / 100);
|
||||
+
|
||||
dm9000_schedule_poll(db);
|
||||
|
||||
return 0;
|
||||
@@ -1401,6 +1431,7 @@ dm9000_probe(struct platform_device *pde
|
||||
mutex_init(&db->addr_lock);
|
||||
|
||||
INIT_DELAYED_WORK(&db->phy_poll, dm9000_poll_work);
|
||||
+ INIT_DELAYED_WORK(&db->irq_poll, dm9000_poll_irq);
|
||||
|
||||
db->addr_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
db->data_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
|
|
@ -1,36 +0,0 @@
|
|||
From: Daniel Schwierzeck <daniel.schwierzeck@googlemail.com>
|
||||
Date: Thu, 3 Mar 2011 17:15:58 +0000 (+0100)
|
||||
Subject: MIPS: lantiq: Add platform data for Lantiq SoC SPI controller driver
|
||||
X-Git-Url: http://nbd.name/gitweb.cgi?p=lantiq.git;a=commitdiff_plain;h=3d21b04682ae8eb1c1965aba39d1796e8c5ad84b;hp=06b420500fe98e37662837e78d8e51aead8aea81
|
||||
|
||||
MIPS: lantiq: Add platform data for Lantiq SoC SPI controller driver
|
||||
|
||||
Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@googlemail.com>
|
||||
---
|
||||
|
||||
--- a/arch/mips/include/asm/mach-lantiq/lantiq_platform.h
|
||||
+++ b/arch/mips/include/asm/mach-lantiq/lantiq_platform.h
|
||||
@@ -50,4 +50,13 @@ struct ltq_eth_data {
|
||||
int mii_mode;
|
||||
};
|
||||
|
||||
+
|
||||
+struct ltq_spi_platform_data {
|
||||
+ u16 num_chipselect;
|
||||
+};
|
||||
+
|
||||
+struct ltq_spi_controller_data {
|
||||
+ unsigned gpio;
|
||||
+};
|
||||
+
|
||||
#endif
|
||||
--- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
|
||||
+++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
|
||||
@@ -75,6 +75,7 @@
|
||||
|
||||
#define PMU_DMA 0x0020
|
||||
#define PMU_USB 0x8041
|
||||
+#define PMU_SPI 0x0100
|
||||
#define PMU_LED 0x0800
|
||||
#define PMU_GPT 0x1000
|
||||
#define PMU_PPE 0x2000
|
File diff suppressed because it is too large
Load Diff
|
@ -1,73 +0,0 @@
|
|||
From: Daniel Schwierzeck <daniel.schwierzeck@googlemail.com>
|
||||
Date: Thu, 3 Mar 2011 20:42:26 +0000 (+0100)
|
||||
Subject: MIPS: lantiq: Add device register helper for SPI controller and devices
|
||||
X-Git-Url: http://nbd.name/gitweb.cgi?p=lantiq.git;a=commitdiff_plain;h=b35b07062b718ece9b9cb7b23b12d83a087eafb0;hp=653c95b8b9066c9c6ac08bd64d0ceee439e9fd90
|
||||
|
||||
MIPS: lantiq: Add device register helper for SPI controller and devices
|
||||
|
||||
Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@googlemail.com>
|
||||
---
|
||||
|
||||
--- a/arch/mips/lantiq/xway/devices.c
|
||||
+++ b/arch/mips/lantiq/xway/devices.c
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <linux/io.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/leds.h>
|
||||
+#include <linux/spi/spi.h>
|
||||
|
||||
#include <asm/bootinfo.h>
|
||||
#include <asm/irq.h>
|
||||
@@ -119,3 +120,41 @@ ltq_register_etop(struct ltq_eth_data *e
|
||||
platform_device_register(<q_etop);
|
||||
}
|
||||
}
|
||||
+
|
||||
+static struct resource ltq_spi_resources[] = {
|
||||
+ {
|
||||
+ .start = LTQ_SSC_BASE_ADDR,
|
||||
+ .end = LTQ_SSC_BASE_ADDR + LTQ_SSC_SIZE - 1,
|
||||
+ .flags = IORESOURCE_MEM,
|
||||
+ },
|
||||
+ IRQ_RES(spi_tx, LTQ_SSC_TIR),
|
||||
+ IRQ_RES(spi_rx, LTQ_SSC_RIR),
|
||||
+ IRQ_RES(spi_err, LTQ_SSC_EIR),
|
||||
+};
|
||||
+
|
||||
+static struct resource ltq_spi_resources_ar9[] = {
|
||||
+ {
|
||||
+ .start = LTQ_SSC_BASE_ADDR,
|
||||
+ .end = LTQ_SSC_BASE_ADDR + LTQ_SSC_SIZE - 1,
|
||||
+ .flags = IORESOURCE_MEM,
|
||||
+ },
|
||||
+ IRQ_RES(spi_tx, LTQ_SSC_TIR_AR9),
|
||||
+ IRQ_RES(spi_rx, LTQ_SSC_RIR_AR9),
|
||||
+ IRQ_RES(spi_err, LTQ_SSC_EIR),
|
||||
+};
|
||||
+
|
||||
+static struct platform_device ltq_spi = {
|
||||
+ .name = "ltq-spi",
|
||||
+ .resource = ltq_spi_resources,
|
||||
+ .num_resources = ARRAY_SIZE(ltq_spi_resources),
|
||||
+};
|
||||
+
|
||||
+void __init ltq_register_spi(struct ltq_spi_platform_data *pdata,
|
||||
+ struct spi_board_info const *info, unsigned n)
|
||||
+{
|
||||
+ if(ltq_is_ar9())
|
||||
+ ltq_spi.resource = ltq_spi_resources_ar9;
|
||||
+ spi_register_board_info(info, n);
|
||||
+ ltq_spi.dev.platform_data = pdata;
|
||||
+ platform_device_register(<q_spi);
|
||||
+}
|
||||
--- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h
|
||||
+++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h
|
||||
@@ -27,6 +27,8 @@
|
||||
|
||||
#define LTQ_SSC_TIR (INT_NUM_IM0_IRL0 + 15)
|
||||
#define LTQ_SSC_RIR (INT_NUM_IM0_IRL0 + 14)
|
||||
+#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_MEI_DYING_GASP_INT (INT_NUM_IM1_IRL0 + 21)
|
|
@ -1,41 +0,0 @@
|
|||
--- a/arch/mips/lantiq/xway/devices.c
|
||||
+++ b/arch/mips/lantiq/xway/devices.c
|
||||
@@ -121,6 +121,29 @@ ltq_register_etop(struct ltq_eth_data *e
|
||||
}
|
||||
}
|
||||
|
||||
+/* ebu */
|
||||
+static struct resource ltq_ebu_resource =
|
||||
+{
|
||||
+ .name = "gpio_ebu",
|
||||
+ .start = LTQ_EBU_GPIO_START,
|
||||
+ .end = LTQ_EBU_GPIO_START + LTQ_EBU_GPIO_SIZE - 1,
|
||||
+ .flags = IORESOURCE_MEM,
|
||||
+};
|
||||
+
|
||||
+static struct platform_device ltq_ebu =
|
||||
+{
|
||||
+ .name = "ltq_ebu",
|
||||
+ .resource = <q_ebu_resource,
|
||||
+ .num_resources = 1,
|
||||
+};
|
||||
+
|
||||
+void __init
|
||||
+ltq_register_gpio_ebu(unsigned int value)
|
||||
+{
|
||||
+ ltq_ebu.dev.platform_data = (void*) value;
|
||||
+ platform_device_register(<q_ebu);
|
||||
+}
|
||||
+
|
||||
static struct resource ltq_spi_resources[] = {
|
||||
{
|
||||
.start = LTQ_SSC_BASE_ADDR,
|
||||
--- 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 ltq_register_gpio_ebu(unsigned int value);
|
||||
|
||||
#endif
|
|
@ -1,31 +0,0 @@
|
|||
--- a/arch/mips/lantiq/xway/devices.c
|
||||
+++ b/arch/mips/lantiq/xway/devices.c
|
||||
@@ -144,6 +144,19 @@ ltq_register_gpio_ebu(unsigned int value
|
||||
platform_device_register(<q_ebu);
|
||||
}
|
||||
|
||||
+/* madwifi */
|
||||
+int lantiq_emulate_madwifi_eep = 0;
|
||||
+unsigned long long lantiq_madwifi_eep_addr = 0;
|
||||
+EXPORT_SYMBOL(lantiq_emulate_madwifi_eep);
|
||||
+EXPORT_SYMBOL(lantiq_madwifi_eep_addr);
|
||||
+
|
||||
+void __init
|
||||
+ltq_register_madwifi_eep(unsigned long long addr)
|
||||
+{
|
||||
+ lantiq_emulate_madwifi_eep = 1;
|
||||
+ lantiq_madwifi_eep_addr = addr;
|
||||
+}
|
||||
+
|
||||
static struct resource ltq_spi_resources[] = {
|
||||
{
|
||||
.start = LTQ_SSC_BASE_ADDR,
|
||||
--- a/arch/mips/lantiq/xway/devices.h
|
||||
+++ b/arch/mips/lantiq/xway/devices.h
|
||||
@@ -17,5 +17,6 @@ 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 ltq_register_gpio_ebu(unsigned int value);
|
||||
+extern void ltq_register_madwifi_eep(unsigned long long addr);
|
||||
|
||||
#endif
|
|
@ -1,101 +0,0 @@
|
|||
--- a/arch/mips/lantiq/Makefile
|
||||
+++ b/arch/mips/lantiq/Makefile
|
||||
@@ -4,7 +4,7 @@
|
||||
# under the terms of the GNU General Public License version 2 as published
|
||||
# by the Free Software Foundation.
|
||||
|
||||
-obj-y := irq.o setup.o clk.o prom.o devices.o
|
||||
+obj-y := irq.o setup.o clk.o prom.o devices.o dev-gpio-buttons.o
|
||||
|
||||
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
|
||||
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/lantiq/dev-gpio-buttons.c
|
||||
@@ -0,0 +1,58 @@
|
||||
+/*
|
||||
+ * 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);
|
||||
+}
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/lantiq/dev-gpio-buttons.h
|
||||
@@ -0,0 +1,26 @@
|
||||
+/*
|
||||
+ * 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 */
|
|
@ -1,42 +0,0 @@
|
|||
--- a/arch/mips/lantiq/devices.c
|
||||
+++ b/arch/mips/lantiq/devices.c
|
||||
@@ -120,3 +120,20 @@ void __init ltq_register_pci(struct ltq_
|
||||
pr_err("kernel is compiled without PCI support\n");
|
||||
}
|
||||
#endif
|
||||
+
|
||||
+static unsigned int *cp1_base = 0;
|
||||
+unsigned int*
|
||||
+ltq_get_cp1_base(void)
|
||||
+{
|
||||
+ return cp1_base;
|
||||
+}
|
||||
+EXPORT_SYMBOL(ltq_get_cp1_base);
|
||||
+
|
||||
+void __init
|
||||
+ltq_register_tapi(void)
|
||||
+{
|
||||
+#define CP1_SIZE (1 << 20)
|
||||
+ dma_addr_t dma;
|
||||
+ cp1_base =
|
||||
+ (void*)CPHYSADDR(dma_alloc_coherent(NULL, CP1_SIZE, &dma, GFP_ATOMIC));
|
||||
+}
|
||||
--- a/arch/mips/lantiq/devices.h
|
||||
+++ b/arch/mips/lantiq/devices.h
|
||||
@@ -19,5 +19,6 @@ extern void ltq_register_nor(struct phys
|
||||
extern void ltq_register_wdt(void);
|
||||
extern void ltq_register_asc(int port);
|
||||
extern void ltq_register_pci(struct ltq_pci_data *data);
|
||||
+extern void ltq_register_tapi(void);
|
||||
|
||||
#endif
|
||||
--- a/arch/mips/lantiq/xway/mach-easy50712.c
|
||||
+++ b/arch/mips/lantiq/xway/mach-easy50712.c
|
||||
@@ -61,6 +61,7 @@ static void __init easy50712_init(void)
|
||||
ltq_register_nor(&easy50712_flash_data);
|
||||
ltq_register_pci(<q_pci_data);
|
||||
ltq_register_etop(<q_eth_data);
|
||||
+ ltq_register_tapi();
|
||||
}
|
||||
|
||||
MIPS_MACHINE(LTQ_MACH_EASY50712,
|
|
@ -1,999 +0,0 @@
|
|||
--- /dev/null
|
||||
+++ b/arch/mips/lantiq/xway/timer.c
|
||||
@@ -0,0 +1,830 @@
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/version.h>
|
||||
+#include <linux/types.h>
|
||||
+#include <linux/fs.h>
|
||||
+#include <linux/miscdevice.h>
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/uaccess.h>
|
||||
+#include <linux/unistd.h>
|
||||
+#include <linux/errno.h>
|
||||
+#include <linux/interrupt.h>
|
||||
+#include <linux/sched.h>
|
||||
+
|
||||
+#include <asm/irq.h>
|
||||
+#include <asm/div64.h>
|
||||
+
|
||||
+#include <lantiq_soc.h>
|
||||
+#include <lantiq_irq.h>
|
||||
+#include <lantiq_timer.h>
|
||||
+
|
||||
+#define MAX_NUM_OF_32BIT_TIMER_BLOCKS 6
|
||||
+
|
||||
+#ifdef TIMER1A
|
||||
+#define FIRST_TIMER TIMER1A
|
||||
+#else
|
||||
+#define FIRST_TIMER 2
|
||||
+#endif
|
||||
+
|
||||
+/*
|
||||
+ * GPTC divider is set or not.
|
||||
+ */
|
||||
+#define GPTU_CLC_RMC_IS_SET 0
|
||||
+
|
||||
+/*
|
||||
+ * Timer Interrupt (IRQ)
|
||||
+ */
|
||||
+/* Must be adjusted when ICU driver is available */
|
||||
+#define TIMER_INTERRUPT (INT_NUM_IM3_IRL0 + 22)
|
||||
+
|
||||
+/*
|
||||
+ * Bits Operation
|
||||
+ */
|
||||
+#define GET_BITS(x, msb, lsb) \
|
||||
+ (((x) & ((1 << ((msb) + 1)) - 1)) >> (lsb))
|
||||
+#define SET_BITS(x, msb, lsb, value) \
|
||||
+ (((x) & ~(((1 << ((msb) + 1)) - 1) ^ ((1 << (lsb)) - 1))) | \
|
||||
+ (((value) & ((1 << (1 + (msb) - (lsb))) - 1)) << (lsb)))
|
||||
+
|
||||
+/*
|
||||
+ * GPTU Register Mapping
|
||||
+ */
|
||||
+#define LQ_GPTU (KSEG1 + 0x1E100A00)
|
||||
+#define LQ_GPTU_CLC ((volatile u32 *)(LQ_GPTU + 0x0000))
|
||||
+#define LQ_GPTU_ID ((volatile u32 *)(LQ_GPTU + 0x0008))
|
||||
+#define LQ_GPTU_CON(n, X) ((volatile u32 *)(LQ_GPTU + 0x0010 + ((X) * 4) + ((n) - 1) * 0x0020)) /* X must be either A or B */
|
||||
+#define LQ_GPTU_RUN(n, X) ((volatile u32 *)(LQ_GPTU + 0x0018 + ((X) * 4) + ((n) - 1) * 0x0020)) /* X must be either A or B */
|
||||
+#define LQ_GPTU_RELOAD(n, X) ((volatile u32 *)(LQ_GPTU + 0x0020 + ((X) * 4) + ((n) - 1) * 0x0020)) /* X must be either A or B */
|
||||
+#define LQ_GPTU_COUNT(n, X) ((volatile u32 *)(LQ_GPTU + 0x0028 + ((X) * 4) + ((n) - 1) * 0x0020)) /* X must be either A or B */
|
||||
+#define LQ_GPTU_IRNEN ((volatile u32 *)(LQ_GPTU + 0x00F4))
|
||||
+#define LQ_GPTU_IRNICR ((volatile u32 *)(LQ_GPTU + 0x00F8))
|
||||
+#define LQ_GPTU_IRNCR ((volatile u32 *)(LQ_GPTU + 0x00FC))
|
||||
+
|
||||
+/*
|
||||
+ * Clock Control Register
|
||||
+ */
|
||||
+#define GPTU_CLC_SMC GET_BITS(*LQ_GPTU_CLC, 23, 16)
|
||||
+#define GPTU_CLC_RMC GET_BITS(*LQ_GPTU_CLC, 15, 8)
|
||||
+#define GPTU_CLC_FSOE (*LQ_GPTU_CLC & (1 << 5))
|
||||
+#define GPTU_CLC_EDIS (*LQ_GPTU_CLC & (1 << 3))
|
||||
+#define GPTU_CLC_SPEN (*LQ_GPTU_CLC & (1 << 2))
|
||||
+#define GPTU_CLC_DISS (*LQ_GPTU_CLC & (1 << 1))
|
||||
+#define GPTU_CLC_DISR (*LQ_GPTU_CLC & (1 << 0))
|
||||
+
|
||||
+#define GPTU_CLC_SMC_SET(value) SET_BITS(0, 23, 16, (value))
|
||||
+#define GPTU_CLC_RMC_SET(value) SET_BITS(0, 15, 8, (value))
|
||||
+#define GPTU_CLC_FSOE_SET(value) ((value) ? (1 << 5) : 0)
|
||||
+#define GPTU_CLC_SBWE_SET(value) ((value) ? (1 << 4) : 0)
|
||||
+#define GPTU_CLC_EDIS_SET(value) ((value) ? (1 << 3) : 0)
|
||||
+#define GPTU_CLC_SPEN_SET(value) ((value) ? (1 << 2) : 0)
|
||||
+#define GPTU_CLC_DISR_SET(value) ((value) ? (1 << 0) : 0)
|
||||
+
|
||||
+/*
|
||||
+ * ID Register
|
||||
+ */
|
||||
+#define GPTU_ID_ID GET_BITS(*LQ_GPTU_ID, 15, 8)
|
||||
+#define GPTU_ID_CFG GET_BITS(*LQ_GPTU_ID, 7, 5)
|
||||
+#define GPTU_ID_REV GET_BITS(*LQ_GPTU_ID, 4, 0)
|
||||
+
|
||||
+/*
|
||||
+ * Control Register of Timer/Counter nX
|
||||
+ * n is the index of block (1 based index)
|
||||
+ * X is either A or B
|
||||
+ */
|
||||
+#define GPTU_CON_SRC_EG(n, X) (*LQ_GPTU_CON(n, X) & (1 << 10))
|
||||
+#define GPTU_CON_SRC_EXT(n, X) (*LQ_GPTU_CON(n, X) & (1 << 9))
|
||||
+#define GPTU_CON_SYNC(n, X) (*LQ_GPTU_CON(n, X) & (1 << 8))
|
||||
+#define GPTU_CON_EDGE(n, X) GET_BITS(*LQ_GPTU_CON(n, X), 7, 6)
|
||||
+#define GPTU_CON_INV(n, X) (*LQ_GPTU_CON(n, X) & (1 << 5))
|
||||
+#define GPTU_CON_EXT(n, X) (*LQ_GPTU_CON(n, A) & (1 << 4)) /* Timer/Counter B does not have this bit */
|
||||
+#define GPTU_CON_STP(n, X) (*LQ_GPTU_CON(n, X) & (1 << 3))
|
||||
+#define GPTU_CON_CNT(n, X) (*LQ_GPTU_CON(n, X) & (1 << 2))
|
||||
+#define GPTU_CON_DIR(n, X) (*LQ_GPTU_CON(n, X) & (1 << 1))
|
||||
+#define GPTU_CON_EN(n, X) (*LQ_GPTU_CON(n, X) & (1 << 0))
|
||||
+
|
||||
+#define GPTU_CON_SRC_EG_SET(value) ((value) ? 0 : (1 << 10))
|
||||
+#define GPTU_CON_SRC_EXT_SET(value) ((value) ? (1 << 9) : 0)
|
||||
+#define GPTU_CON_SYNC_SET(value) ((value) ? (1 << 8) : 0)
|
||||
+#define GPTU_CON_EDGE_SET(value) SET_BITS(0, 7, 6, (value))
|
||||
+#define GPTU_CON_INV_SET(value) ((value) ? (1 << 5) : 0)
|
||||
+#define GPTU_CON_EXT_SET(value) ((value) ? (1 << 4) : 0)
|
||||
+#define GPTU_CON_STP_SET(value) ((value) ? (1 << 3) : 0)
|
||||
+#define GPTU_CON_CNT_SET(value) ((value) ? (1 << 2) : 0)
|
||||
+#define GPTU_CON_DIR_SET(value) ((value) ? (1 << 1) : 0)
|
||||
+
|
||||
+#define GPTU_RUN_RL_SET(value) ((value) ? (1 << 2) : 0)
|
||||
+#define GPTU_RUN_CEN_SET(value) ((value) ? (1 << 1) : 0)
|
||||
+#define GPTU_RUN_SEN_SET(value) ((value) ? (1 << 0) : 0)
|
||||
+
|
||||
+#define GPTU_IRNEN_TC_SET(n, X, value) ((value) ? (1 << (((n) - 1) * 2 + (X))) : 0)
|
||||
+#define GPTU_IRNCR_TC_SET(n, X, value) ((value) ? (1 << (((n) - 1) * 2 + (X))) : 0)
|
||||
+
|
||||
+#define TIMER_FLAG_MASK_SIZE(x) (x & 0x0001)
|
||||
+#define TIMER_FLAG_MASK_TYPE(x) (x & 0x0002)
|
||||
+#define TIMER_FLAG_MASK_STOP(x) (x & 0x0004)
|
||||
+#define TIMER_FLAG_MASK_DIR(x) (x & 0x0008)
|
||||
+#define TIMER_FLAG_NONE_EDGE 0x0000
|
||||
+#define TIMER_FLAG_MASK_EDGE(x) (x & 0x0030)
|
||||
+#define TIMER_FLAG_REAL 0x0000
|
||||
+#define TIMER_FLAG_INVERT 0x0040
|
||||
+#define TIMER_FLAG_MASK_INVERT(x) (x & 0x0040)
|
||||
+#define TIMER_FLAG_MASK_TRIGGER(x) (x & 0x0070)
|
||||
+#define TIMER_FLAG_MASK_SYNC(x) (x & 0x0080)
|
||||
+#define TIMER_FLAG_CALLBACK_IN_HB 0x0200
|
||||
+#define TIMER_FLAG_MASK_HANDLE(x) (x & 0x0300)
|
||||
+#define TIMER_FLAG_MASK_SRC(x) (x & 0x1000)
|
||||
+
|
||||
+struct timer_dev_timer {
|
||||
+ unsigned int f_irq_on;
|
||||
+ unsigned int irq;
|
||||
+ unsigned int flag;
|
||||
+ unsigned long arg1;
|
||||
+ unsigned long arg2;
|
||||
+};
|
||||
+
|
||||
+struct timer_dev {
|
||||
+ struct mutex gptu_mutex;
|
||||
+ unsigned int number_of_timers;
|
||||
+ unsigned int occupation;
|
||||
+ unsigned int f_gptu_on;
|
||||
+ struct timer_dev_timer timer[MAX_NUM_OF_32BIT_TIMER_BLOCKS * 2];
|
||||
+};
|
||||
+
|
||||
+unsigned int ltq_get_fpi_bus_clock(int fpi);
|
||||
+
|
||||
+static long gptu_ioctl(struct file *, unsigned int, unsigned long);
|
||||
+static int gptu_open(struct inode *, struct file *);
|
||||
+static int gptu_release(struct inode *, struct file *);
|
||||
+
|
||||
+static struct file_operations gptu_fops = {
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .unlocked_ioctl = gptu_ioctl,
|
||||
+ .open = gptu_open,
|
||||
+ .release = gptu_release
|
||||
+};
|
||||
+
|
||||
+static struct miscdevice gptu_miscdev = {
|
||||
+ .minor = MISC_DYNAMIC_MINOR,
|
||||
+ .name = "gptu",
|
||||
+ .fops = &gptu_fops,
|
||||
+};
|
||||
+
|
||||
+static struct timer_dev timer_dev;
|
||||
+
|
||||
+static irqreturn_t timer_irq_handler(int irq, void *p)
|
||||
+{
|
||||
+ unsigned int timer;
|
||||
+ unsigned int flag;
|
||||
+ struct timer_dev_timer *dev_timer = (struct timer_dev_timer *)p;
|
||||
+
|
||||
+ timer = irq - TIMER_INTERRUPT;
|
||||
+ if (timer < timer_dev.number_of_timers
|
||||
+ && dev_timer == &timer_dev.timer[timer]) {
|
||||
+ /* Clear interrupt. */
|
||||
+ ltq_w32(1 << timer, LQ_GPTU_IRNCR);
|
||||
+
|
||||
+ /* Call user hanler or signal. */
|
||||
+ flag = dev_timer->flag;
|
||||
+ if (!(timer & 0x01)
|
||||
+ || TIMER_FLAG_MASK_SIZE(flag) == TIMER_FLAG_16BIT) {
|
||||
+ /* 16-bit timer or timer A of 32-bit timer */
|
||||
+ switch (TIMER_FLAG_MASK_HANDLE(flag)) {
|
||||
+ case TIMER_FLAG_CALLBACK_IN_IRQ:
|
||||
+ case TIMER_FLAG_CALLBACK_IN_HB:
|
||||
+ if (dev_timer->arg1)
|
||||
+ (*(timer_callback)dev_timer->arg1)(dev_timer->arg2);
|
||||
+ break;
|
||||
+ case TIMER_FLAG_SIGNAL:
|
||||
+ send_sig((int)dev_timer->arg2, (struct task_struct *)dev_timer->arg1, 0);
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ return IRQ_HANDLED;
|
||||
+}
|
||||
+
|
||||
+static inline void lq_enable_gptu(void)
|
||||
+{
|
||||
+ ltq_pmu_enable(PMU_GPT);
|
||||
+
|
||||
+ /* Set divider as 1, disable write protection for SPEN, enable module. */
|
||||
+ *LQ_GPTU_CLC =
|
||||
+ GPTU_CLC_SMC_SET(0x00) |
|
||||
+ GPTU_CLC_RMC_SET(0x01) |
|
||||
+ GPTU_CLC_FSOE_SET(0) |
|
||||
+ GPTU_CLC_SBWE_SET(1) |
|
||||
+ GPTU_CLC_EDIS_SET(0) |
|
||||
+ GPTU_CLC_SPEN_SET(0) |
|
||||
+ GPTU_CLC_DISR_SET(0);
|
||||
+}
|
||||
+
|
||||
+static inline void lq_disable_gptu(void)
|
||||
+{
|
||||
+ ltq_w32(0x00, LQ_GPTU_IRNEN);
|
||||
+ ltq_w32(0xfff, LQ_GPTU_IRNCR);
|
||||
+
|
||||
+ /* Set divider as 0, enable write protection for SPEN, disable module. */
|
||||
+ *LQ_GPTU_CLC =
|
||||
+ GPTU_CLC_SMC_SET(0x00) |
|
||||
+ GPTU_CLC_RMC_SET(0x00) |
|
||||
+ GPTU_CLC_FSOE_SET(0) |
|
||||
+ GPTU_CLC_SBWE_SET(0) |
|
||||
+ GPTU_CLC_EDIS_SET(0) |
|
||||
+ GPTU_CLC_SPEN_SET(0) |
|
||||
+ GPTU_CLC_DISR_SET(1);
|
||||
+
|
||||
+ ltq_pmu_disable(PMU_GPT);
|
||||
+}
|
||||
+
|
||||
+int lq_request_timer(unsigned int timer, unsigned int flag,
|
||||
+ unsigned long value, unsigned long arg1, unsigned long arg2)
|
||||
+{
|
||||
+ int ret = 0;
|
||||
+ unsigned int con_reg, irnen_reg;
|
||||
+ int n, X;
|
||||
+
|
||||
+ if (timer >= FIRST_TIMER + timer_dev.number_of_timers)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ printk(KERN_INFO "request_timer(%d, 0x%08X, %lu)...",
|
||||
+ timer, flag, value);
|
||||
+
|
||||
+ if (TIMER_FLAG_MASK_SIZE(flag) == TIMER_FLAG_16BIT)
|
||||
+ value &= 0xFFFF;
|
||||
+ else
|
||||
+ timer &= ~0x01;
|
||||
+
|
||||
+ mutex_lock(&timer_dev.gptu_mutex);
|
||||
+
|
||||
+ /*
|
||||
+ * Allocate timer.
|
||||
+ */
|
||||
+ if (timer < FIRST_TIMER) {
|
||||
+ unsigned int mask;
|
||||
+ unsigned int shift;
|
||||
+ /* This takes care of TIMER1B which is the only choice for Voice TAPI system */
|
||||
+ unsigned int offset = TIMER2A;
|
||||
+
|
||||
+ /*
|
||||
+ * Pick up a free timer.
|
||||
+ */
|
||||
+ if (TIMER_FLAG_MASK_SIZE(flag) == TIMER_FLAG_16BIT) {
|
||||
+ mask = 1 << offset;
|
||||
+ shift = 1;
|
||||
+ } else {
|
||||
+ mask = 3 << offset;
|
||||
+ shift = 2;
|
||||
+ }
|
||||
+ for (timer = offset;
|
||||
+ timer < offset + timer_dev.number_of_timers;
|
||||
+ timer += shift, mask <<= shift)
|
||||
+ if (!(timer_dev.occupation & mask)) {
|
||||
+ timer_dev.occupation |= mask;
|
||||
+ break;
|
||||
+ }
|
||||
+ if (timer >= offset + timer_dev.number_of_timers) {
|
||||
+ printk("failed![%d]\n", __LINE__);
|
||||
+ mutex_unlock(&timer_dev.gptu_mutex);
|
||||
+ return -EINVAL;
|
||||
+ } else
|
||||
+ ret = timer;
|
||||
+ } else {
|
||||
+ register unsigned int mask;
|
||||
+
|
||||
+ /*
|
||||
+ * Check if the requested timer is free.
|
||||
+ */
|
||||
+ mask = (TIMER_FLAG_MASK_SIZE(flag) == TIMER_FLAG_16BIT ? 1 : 3) << timer;
|
||||
+ if ((timer_dev.occupation & mask)) {
|
||||
+ printk("failed![%d] mask %#x, timer_dev.occupation %#x\n",
|
||||
+ __LINE__, mask, timer_dev.occupation);
|
||||
+ mutex_unlock(&timer_dev.gptu_mutex);
|
||||
+ return -EBUSY;
|
||||
+ } else {
|
||||
+ timer_dev.occupation |= mask;
|
||||
+ ret = 0;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * Prepare control register value.
|
||||
+ */
|
||||
+ switch (TIMER_FLAG_MASK_EDGE(flag)) {
|
||||
+ default:
|
||||
+ case TIMER_FLAG_NONE_EDGE:
|
||||
+ con_reg = GPTU_CON_EDGE_SET(0x00);
|
||||
+ break;
|
||||
+ case TIMER_FLAG_RISE_EDGE:
|
||||
+ con_reg = GPTU_CON_EDGE_SET(0x01);
|
||||
+ break;
|
||||
+ case TIMER_FLAG_FALL_EDGE:
|
||||
+ con_reg = GPTU_CON_EDGE_SET(0x02);
|
||||
+ break;
|
||||
+ case TIMER_FLAG_ANY_EDGE:
|
||||
+ con_reg = GPTU_CON_EDGE_SET(0x03);
|
||||
+ break;
|
||||
+ }
|
||||
+ if (TIMER_FLAG_MASK_TYPE(flag) == TIMER_FLAG_TIMER)
|
||||
+ con_reg |=
|
||||
+ TIMER_FLAG_MASK_SRC(flag) ==
|
||||
+ TIMER_FLAG_EXT_SRC ? GPTU_CON_SRC_EXT_SET(1) :
|
||||
+ GPTU_CON_SRC_EXT_SET(0);
|
||||
+ else
|
||||
+ con_reg |=
|
||||
+ TIMER_FLAG_MASK_SRC(flag) ==
|
||||
+ TIMER_FLAG_EXT_SRC ? GPTU_CON_SRC_EG_SET(1) :
|
||||
+ GPTU_CON_SRC_EG_SET(0);
|
||||
+ con_reg |=
|
||||
+ TIMER_FLAG_MASK_SYNC(flag) ==
|
||||
+ TIMER_FLAG_UNSYNC ? GPTU_CON_SYNC_SET(0) :
|
||||
+ GPTU_CON_SYNC_SET(1);
|
||||
+ con_reg |=
|
||||
+ TIMER_FLAG_MASK_INVERT(flag) ==
|
||||
+ TIMER_FLAG_REAL ? GPTU_CON_INV_SET(0) : GPTU_CON_INV_SET(1);
|
||||
+ con_reg |=
|
||||
+ TIMER_FLAG_MASK_SIZE(flag) ==
|
||||
+ TIMER_FLAG_16BIT ? GPTU_CON_EXT_SET(0) :
|
||||
+ GPTU_CON_EXT_SET(1);
|
||||
+ con_reg |=
|
||||
+ TIMER_FLAG_MASK_STOP(flag) ==
|
||||
+ TIMER_FLAG_ONCE ? GPTU_CON_STP_SET(1) : GPTU_CON_STP_SET(0);
|
||||
+ con_reg |=
|
||||
+ TIMER_FLAG_MASK_TYPE(flag) ==
|
||||
+ TIMER_FLAG_TIMER ? GPTU_CON_CNT_SET(0) :
|
||||
+ GPTU_CON_CNT_SET(1);
|
||||
+ con_reg |=
|
||||
+ TIMER_FLAG_MASK_DIR(flag) ==
|
||||
+ TIMER_FLAG_UP ? GPTU_CON_DIR_SET(1) : GPTU_CON_DIR_SET(0);
|
||||
+
|
||||
+ /*
|
||||
+ * Fill up running data.
|
||||
+ */
|
||||
+ timer_dev.timer[timer - FIRST_TIMER].flag = flag;
|
||||
+ timer_dev.timer[timer - FIRST_TIMER].arg1 = arg1;
|
||||
+ timer_dev.timer[timer - FIRST_TIMER].arg2 = arg2;
|
||||
+ if (TIMER_FLAG_MASK_SIZE(flag) != TIMER_FLAG_16BIT)
|
||||
+ timer_dev.timer[timer - FIRST_TIMER + 1].flag = flag;
|
||||
+
|
||||
+ /*
|
||||
+ * Enable GPTU module.
|
||||
+ */
|
||||
+ if (!timer_dev.f_gptu_on) {
|
||||
+ lq_enable_gptu();
|
||||
+ timer_dev.f_gptu_on = 1;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * Enable IRQ.
|
||||
+ */
|
||||
+ if (TIMER_FLAG_MASK_HANDLE(flag) != TIMER_FLAG_NO_HANDLE) {
|
||||
+ if (TIMER_FLAG_MASK_HANDLE(flag) == TIMER_FLAG_SIGNAL)
|
||||
+ timer_dev.timer[timer - FIRST_TIMER].arg1 =
|
||||
+ (unsigned long) find_task_by_vpid((int) arg1);
|
||||
+
|
||||
+ irnen_reg = 1 << (timer - FIRST_TIMER);
|
||||
+
|
||||
+ if (TIMER_FLAG_MASK_HANDLE(flag) == TIMER_FLAG_SIGNAL
|
||||
+ || (TIMER_FLAG_MASK_HANDLE(flag) ==
|
||||
+ TIMER_FLAG_CALLBACK_IN_IRQ
|
||||
+ && timer_dev.timer[timer - FIRST_TIMER].arg1)) {
|
||||
+ enable_irq(timer_dev.timer[timer - FIRST_TIMER].irq);
|
||||
+ timer_dev.timer[timer - FIRST_TIMER].f_irq_on = 1;
|
||||
+ }
|
||||
+ } else
|
||||
+ irnen_reg = 0;
|
||||
+
|
||||
+ /*
|
||||
+ * Write config register, reload value and enable interrupt.
|
||||
+ */
|
||||
+ n = timer >> 1;
|
||||
+ X = timer & 0x01;
|
||||
+ *LQ_GPTU_CON(n, X) = con_reg;
|
||||
+ *LQ_GPTU_RELOAD(n, X) = value;
|
||||
+ /* printk("reload value = %d\n", (u32)value); */
|
||||
+ *LQ_GPTU_IRNEN |= irnen_reg;
|
||||
+
|
||||
+ mutex_unlock(&timer_dev.gptu_mutex);
|
||||
+ printk("successful!\n");
|
||||
+ return ret;
|
||||
+}
|
||||
+EXPORT_SYMBOL(lq_request_timer);
|
||||
+
|
||||
+int lq_free_timer(unsigned int timer)
|
||||
+{
|
||||
+ unsigned int flag;
|
||||
+ unsigned int mask;
|
||||
+ int n, X;
|
||||
+
|
||||
+ if (!timer_dev.f_gptu_on)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (timer < FIRST_TIMER || timer >= FIRST_TIMER + timer_dev.number_of_timers)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ mutex_lock(&timer_dev.gptu_mutex);
|
||||
+
|
||||
+ flag = timer_dev.timer[timer - FIRST_TIMER].flag;
|
||||
+ if (TIMER_FLAG_MASK_SIZE(flag) != TIMER_FLAG_16BIT)
|
||||
+ timer &= ~0x01;
|
||||
+
|
||||
+ mask = (TIMER_FLAG_MASK_SIZE(flag) == TIMER_FLAG_16BIT ? 1 : 3) << timer;
|
||||
+ if (((timer_dev.occupation & mask) ^ mask)) {
|
||||
+ mutex_unlock(&timer_dev.gptu_mutex);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ n = timer >> 1;
|
||||
+ X = timer & 0x01;
|
||||
+
|
||||
+ if (GPTU_CON_EN(n, X))
|
||||
+ *LQ_GPTU_RUN(n, X) = GPTU_RUN_CEN_SET(1);
|
||||
+
|
||||
+ *LQ_GPTU_IRNEN &= ~GPTU_IRNEN_TC_SET(n, X, 1);
|
||||
+ *LQ_GPTU_IRNCR |= GPTU_IRNCR_TC_SET(n, X, 1);
|
||||
+
|
||||
+ if (timer_dev.timer[timer - FIRST_TIMER].f_irq_on) {
|
||||
+ disable_irq(timer_dev.timer[timer - FIRST_TIMER].irq);
|
||||
+ timer_dev.timer[timer - FIRST_TIMER].f_irq_on = 0;
|
||||
+ }
|
||||
+
|
||||
+ timer_dev.occupation &= ~mask;
|
||||
+ if (!timer_dev.occupation && timer_dev.f_gptu_on) {
|
||||
+ lq_disable_gptu();
|
||||
+ timer_dev.f_gptu_on = 0;
|
||||
+ }
|
||||
+
|
||||
+ mutex_unlock(&timer_dev.gptu_mutex);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+EXPORT_SYMBOL(lq_free_timer);
|
||||
+
|
||||
+int lq_start_timer(unsigned int timer, int is_resume)
|
||||
+{
|
||||
+ unsigned int flag;
|
||||
+ unsigned int mask;
|
||||
+ int n, X;
|
||||
+
|
||||
+ if (!timer_dev.f_gptu_on)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (timer < FIRST_TIMER || timer >= FIRST_TIMER + timer_dev.number_of_timers)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ mutex_lock(&timer_dev.gptu_mutex);
|
||||
+
|
||||
+ flag = timer_dev.timer[timer - FIRST_TIMER].flag;
|
||||
+ if (TIMER_FLAG_MASK_SIZE(flag) != TIMER_FLAG_16BIT)
|
||||
+ timer &= ~0x01;
|
||||
+
|
||||
+ mask = (TIMER_FLAG_MASK_SIZE(flag) ==
|
||||
+ TIMER_FLAG_16BIT ? 1 : 3) << timer;
|
||||
+ if (((timer_dev.occupation & mask) ^ mask)) {
|
||||
+ mutex_unlock(&timer_dev.gptu_mutex);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ n = timer >> 1;
|
||||
+ X = timer & 0x01;
|
||||
+
|
||||
+ *LQ_GPTU_RUN(n, X) = GPTU_RUN_RL_SET(!is_resume) | GPTU_RUN_SEN_SET(1);
|
||||
+
|
||||
+ mutex_unlock(&timer_dev.gptu_mutex);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+EXPORT_SYMBOL(lq_start_timer);
|
||||
+
|
||||
+int lq_stop_timer(unsigned int timer)
|
||||
+{
|
||||
+ unsigned int flag;
|
||||
+ unsigned int mask;
|
||||
+ int n, X;
|
||||
+
|
||||
+ if (!timer_dev.f_gptu_on)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (timer < FIRST_TIMER
|
||||
+ || timer >= FIRST_TIMER + timer_dev.number_of_timers)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ mutex_lock(&timer_dev.gptu_mutex);
|
||||
+
|
||||
+ flag = timer_dev.timer[timer - FIRST_TIMER].flag;
|
||||
+ if (TIMER_FLAG_MASK_SIZE(flag) != TIMER_FLAG_16BIT)
|
||||
+ timer &= ~0x01;
|
||||
+
|
||||
+ mask = (TIMER_FLAG_MASK_SIZE(flag) == TIMER_FLAG_16BIT ? 1 : 3) << timer;
|
||||
+ if (((timer_dev.occupation & mask) ^ mask)) {
|
||||
+ mutex_unlock(&timer_dev.gptu_mutex);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ n = timer >> 1;
|
||||
+ X = timer & 0x01;
|
||||
+
|
||||
+ *LQ_GPTU_RUN(n, X) = GPTU_RUN_CEN_SET(1);
|
||||
+
|
||||
+ mutex_unlock(&timer_dev.gptu_mutex);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+EXPORT_SYMBOL(lq_stop_timer);
|
||||
+
|
||||
+int lq_reset_counter_flags(u32 timer, u32 flags)
|
||||
+{
|
||||
+ unsigned int oflag;
|
||||
+ unsigned int mask, con_reg;
|
||||
+ int n, X;
|
||||
+
|
||||
+ if (!timer_dev.f_gptu_on)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (timer < FIRST_TIMER || timer >= FIRST_TIMER + timer_dev.number_of_timers)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ mutex_lock(&timer_dev.gptu_mutex);
|
||||
+
|
||||
+ oflag = timer_dev.timer[timer - FIRST_TIMER].flag;
|
||||
+ if (TIMER_FLAG_MASK_SIZE(oflag) != TIMER_FLAG_16BIT)
|
||||
+ timer &= ~0x01;
|
||||
+
|
||||
+ mask = (TIMER_FLAG_MASK_SIZE(oflag) == TIMER_FLAG_16BIT ? 1 : 3) << timer;
|
||||
+ if (((timer_dev.occupation & mask) ^ mask)) {
|
||||
+ mutex_unlock(&timer_dev.gptu_mutex);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ switch (TIMER_FLAG_MASK_EDGE(flags)) {
|
||||
+ default:
|
||||
+ case TIMER_FLAG_NONE_EDGE:
|
||||
+ con_reg = GPTU_CON_EDGE_SET(0x00);
|
||||
+ break;
|
||||
+ case TIMER_FLAG_RISE_EDGE:
|
||||
+ con_reg = GPTU_CON_EDGE_SET(0x01);
|
||||
+ break;
|
||||
+ case TIMER_FLAG_FALL_EDGE:
|
||||
+ con_reg = GPTU_CON_EDGE_SET(0x02);
|
||||
+ break;
|
||||
+ case TIMER_FLAG_ANY_EDGE:
|
||||
+ con_reg = GPTU_CON_EDGE_SET(0x03);
|
||||
+ break;
|
||||
+ }
|
||||
+ if (TIMER_FLAG_MASK_TYPE(flags) == TIMER_FLAG_TIMER)
|
||||
+ con_reg |= TIMER_FLAG_MASK_SRC(flags) == TIMER_FLAG_EXT_SRC ? GPTU_CON_SRC_EXT_SET(1) : GPTU_CON_SRC_EXT_SET(0);
|
||||
+ else
|
||||
+ con_reg |= TIMER_FLAG_MASK_SRC(flags) == TIMER_FLAG_EXT_SRC ? GPTU_CON_SRC_EG_SET(1) : GPTU_CON_SRC_EG_SET(0);
|
||||
+ con_reg |= TIMER_FLAG_MASK_SYNC(flags) == TIMER_FLAG_UNSYNC ? GPTU_CON_SYNC_SET(0) : GPTU_CON_SYNC_SET(1);
|
||||
+ con_reg |= TIMER_FLAG_MASK_INVERT(flags) == TIMER_FLAG_REAL ? GPTU_CON_INV_SET(0) : GPTU_CON_INV_SET(1);
|
||||
+ con_reg |= TIMER_FLAG_MASK_SIZE(flags) == TIMER_FLAG_16BIT ? GPTU_CON_EXT_SET(0) : GPTU_CON_EXT_SET(1);
|
||||
+ con_reg |= TIMER_FLAG_MASK_STOP(flags) == TIMER_FLAG_ONCE ? GPTU_CON_STP_SET(1) : GPTU_CON_STP_SET(0);
|
||||
+ con_reg |= TIMER_FLAG_MASK_TYPE(flags) == TIMER_FLAG_TIMER ? GPTU_CON_CNT_SET(0) : GPTU_CON_CNT_SET(1);
|
||||
+ con_reg |= TIMER_FLAG_MASK_DIR(flags) == TIMER_FLAG_UP ? GPTU_CON_DIR_SET(1) : GPTU_CON_DIR_SET(0);
|
||||
+
|
||||
+ timer_dev.timer[timer - FIRST_TIMER].flag = flags;
|
||||
+ if (TIMER_FLAG_MASK_SIZE(flags) != TIMER_FLAG_16BIT)
|
||||
+ timer_dev.timer[timer - FIRST_TIMER + 1].flag = flags;
|
||||
+
|
||||
+ n = timer >> 1;
|
||||
+ X = timer & 0x01;
|
||||
+
|
||||
+ *LQ_GPTU_CON(n, X) = con_reg;
|
||||
+ smp_wmb();
|
||||
+ printk(KERN_INFO "[%s]: counter%d oflags %#x, nflags %#x, GPTU_CON %#x\n", __func__, timer, oflag, flags, *LQ_GPTU_CON(n, X));
|
||||
+ mutex_unlock(&timer_dev.gptu_mutex);
|
||||
+ return 0;
|
||||
+}
|
||||
+EXPORT_SYMBOL(lq_reset_counter_flags);
|
||||
+
|
||||
+int lq_get_count_value(unsigned int timer, unsigned long *value)
|
||||
+{
|
||||
+ unsigned int flag;
|
||||
+ unsigned int mask;
|
||||
+ int n, X;
|
||||
+
|
||||
+ if (!timer_dev.f_gptu_on)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (timer < FIRST_TIMER
|
||||
+ || timer >= FIRST_TIMER + timer_dev.number_of_timers)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ mutex_lock(&timer_dev.gptu_mutex);
|
||||
+
|
||||
+ flag = timer_dev.timer[timer - FIRST_TIMER].flag;
|
||||
+ if (TIMER_FLAG_MASK_SIZE(flag) != TIMER_FLAG_16BIT)
|
||||
+ timer &= ~0x01;
|
||||
+
|
||||
+ mask = (TIMER_FLAG_MASK_SIZE(flag) == TIMER_FLAG_16BIT ? 1 : 3) << timer;
|
||||
+ if (((timer_dev.occupation & mask) ^ mask)) {
|
||||
+ mutex_unlock(&timer_dev.gptu_mutex);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ n = timer >> 1;
|
||||
+ X = timer & 0x01;
|
||||
+
|
||||
+ *value = *LQ_GPTU_COUNT(n, X);
|
||||
+
|
||||
+ mutex_unlock(&timer_dev.gptu_mutex);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+EXPORT_SYMBOL(lq_get_count_value);
|
||||
+
|
||||
+u32 lq_cal_divider(unsigned long freq)
|
||||
+{
|
||||
+ u64 module_freq, fpi = ltq_get_fpi_bus_clock(2);
|
||||
+ u32 clock_divider = 1;
|
||||
+ module_freq = fpi * 1000;
|
||||
+ do_div(module_freq, clock_divider * freq);
|
||||
+ return module_freq;
|
||||
+}
|
||||
+EXPORT_SYMBOL(lq_cal_divider);
|
||||
+
|
||||
+int lq_set_timer(unsigned int timer, unsigned int freq, int is_cyclic,
|
||||
+ int is_ext_src, unsigned int handle_flag, unsigned long arg1,
|
||||
+ unsigned long arg2)
|
||||
+{
|
||||
+ unsigned long divider;
|
||||
+ unsigned int flag;
|
||||
+
|
||||
+ divider = lq_cal_divider(freq);
|
||||
+ if (divider == 0)
|
||||
+ return -EINVAL;
|
||||
+ flag = ((divider & ~0xFFFF) ? TIMER_FLAG_32BIT : TIMER_FLAG_16BIT)
|
||||
+ | (is_cyclic ? TIMER_FLAG_CYCLIC : TIMER_FLAG_ONCE)
|
||||
+ | (is_ext_src ? TIMER_FLAG_EXT_SRC : TIMER_FLAG_INT_SRC)
|
||||
+ | TIMER_FLAG_TIMER | TIMER_FLAG_DOWN
|
||||
+ | TIMER_FLAG_MASK_HANDLE(handle_flag);
|
||||
+
|
||||
+ printk(KERN_INFO "lq_set_timer(%d, %d), divider = %lu\n",
|
||||
+ timer, freq, divider);
|
||||
+ return lq_request_timer(timer, flag, divider, arg1, arg2);
|
||||
+}
|
||||
+EXPORT_SYMBOL(lq_set_timer);
|
||||
+
|
||||
+int lq_set_counter(unsigned int timer, unsigned int flag, u32 reload,
|
||||
+ unsigned long arg1, unsigned long arg2)
|
||||
+{
|
||||
+ printk(KERN_INFO "lq_set_counter(%d, %#x, %d)\n", timer, flag, reload);
|
||||
+ return lq_request_timer(timer, flag, reload, arg1, arg2);
|
||||
+}
|
||||
+EXPORT_SYMBOL(lq_set_counter);
|
||||
+
|
||||
+static long gptu_ioctl(struct file *file, unsigned int cmd,
|
||||
+ unsigned long arg)
|
||||
+{
|
||||
+ int ret;
|
||||
+ struct gptu_ioctl_param param;
|
||||
+
|
||||
+ if (!access_ok(VERIFY_READ, arg, sizeof(struct gptu_ioctl_param)))
|
||||
+ return -EFAULT;
|
||||
+ copy_from_user(¶m, (void *) arg, sizeof(param));
|
||||
+
|
||||
+ if ((((cmd == GPTU_REQUEST_TIMER || cmd == GPTU_SET_TIMER
|
||||
+ || GPTU_SET_COUNTER) && param.timer < 2)
|
||||
+ || cmd == GPTU_GET_COUNT_VALUE || cmd == GPTU_CALCULATE_DIVIDER)
|
||||
+ && !access_ok(VERIFY_WRITE, arg,
|
||||
+ sizeof(struct gptu_ioctl_param)))
|
||||
+ return -EFAULT;
|
||||
+
|
||||
+ switch (cmd) {
|
||||
+ case GPTU_REQUEST_TIMER:
|
||||
+ ret = lq_request_timer(param.timer, param.flag, param.value,
|
||||
+ (unsigned long) param.pid,
|
||||
+ (unsigned long) param.sig);
|
||||
+ if (ret > 0) {
|
||||
+ copy_to_user(&((struct gptu_ioctl_param *) arg)->
|
||||
+ timer, &ret, sizeof(&ret));
|
||||
+ ret = 0;
|
||||
+ }
|
||||
+ break;
|
||||
+ case GPTU_FREE_TIMER:
|
||||
+ ret = lq_free_timer(param.timer);
|
||||
+ break;
|
||||
+ case GPTU_START_TIMER:
|
||||
+ ret = lq_start_timer(param.timer, param.flag);
|
||||
+ break;
|
||||
+ case GPTU_STOP_TIMER:
|
||||
+ ret = lq_stop_timer(param.timer);
|
||||
+ break;
|
||||
+ case GPTU_GET_COUNT_VALUE:
|
||||
+ ret = lq_get_count_value(param.timer, ¶m.value);
|
||||
+ if (!ret)
|
||||
+ copy_to_user(&((struct gptu_ioctl_param *) arg)->
|
||||
+ value, ¶m.value,
|
||||
+ sizeof(param.value));
|
||||
+ break;
|
||||
+ case GPTU_CALCULATE_DIVIDER:
|
||||
+ param.value = lq_cal_divider(param.value);
|
||||
+ if (param.value == 0)
|
||||
+ ret = -EINVAL;
|
||||
+ else {
|
||||
+ copy_to_user(&((struct gptu_ioctl_param *) arg)->
|
||||
+ value, ¶m.value,
|
||||
+ sizeof(param.value));
|
||||
+ ret = 0;
|
||||
+ }
|
||||
+ break;
|
||||
+ case GPTU_SET_TIMER:
|
||||
+ ret = lq_set_timer(param.timer, param.value,
|
||||
+ TIMER_FLAG_MASK_STOP(param.flag) !=
|
||||
+ TIMER_FLAG_ONCE ? 1 : 0,
|
||||
+ TIMER_FLAG_MASK_SRC(param.flag) ==
|
||||
+ TIMER_FLAG_EXT_SRC ? 1 : 0,
|
||||
+ TIMER_FLAG_MASK_HANDLE(param.flag) ==
|
||||
+ TIMER_FLAG_SIGNAL ? TIMER_FLAG_SIGNAL :
|
||||
+ TIMER_FLAG_NO_HANDLE,
|
||||
+ (unsigned long) param.pid,
|
||||
+ (unsigned long) param.sig);
|
||||
+ if (ret > 0) {
|
||||
+ copy_to_user(&((struct gptu_ioctl_param *) arg)->
|
||||
+ timer, &ret, sizeof(&ret));
|
||||
+ ret = 0;
|
||||
+ }
|
||||
+ break;
|
||||
+ case GPTU_SET_COUNTER:
|
||||
+ lq_set_counter(param.timer, param.flag, param.value, 0, 0);
|
||||
+ if (ret > 0) {
|
||||
+ copy_to_user(&((struct gptu_ioctl_param *) arg)->
|
||||
+ timer, &ret, sizeof(&ret));
|
||||
+ ret = 0;
|
||||
+ }
|
||||
+ break;
|
||||
+ default:
|
||||
+ ret = -ENOTTY;
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int gptu_open(struct inode *inode, struct file *file)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int gptu_release(struct inode *inode, struct file *file)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int __init lq_gptu_init(void)
|
||||
+{
|
||||
+ int ret;
|
||||
+ unsigned int i;
|
||||
+
|
||||
+ ltq_w32(0, LQ_GPTU_IRNEN);
|
||||
+ ltq_w32(0xfff, LQ_GPTU_IRNCR);
|
||||
+
|
||||
+ memset(&timer_dev, 0, sizeof(timer_dev));
|
||||
+ mutex_init(&timer_dev.gptu_mutex);
|
||||
+
|
||||
+ lq_enable_gptu();
|
||||
+ timer_dev.number_of_timers = GPTU_ID_CFG * 2;
|
||||
+ lq_disable_gptu();
|
||||
+ if (timer_dev.number_of_timers > MAX_NUM_OF_32BIT_TIMER_BLOCKS * 2)
|
||||
+ timer_dev.number_of_timers = MAX_NUM_OF_32BIT_TIMER_BLOCKS * 2;
|
||||
+ printk(KERN_INFO "gptu: totally %d 16-bit timers/counters\n", timer_dev.number_of_timers);
|
||||
+
|
||||
+ ret = misc_register(&gptu_miscdev);
|
||||
+ if (ret) {
|
||||
+ printk(KERN_ERR "gptu: can't misc_register, get error %d\n", -ret);
|
||||
+ return ret;
|
||||
+ } else {
|
||||
+ printk(KERN_INFO "gptu: misc_register on minor %d\n", gptu_miscdev.minor);
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < timer_dev.number_of_timers; i++) {
|
||||
+ ret = request_irq(TIMER_INTERRUPT + i, timer_irq_handler, IRQF_TIMER, gptu_miscdev.name, &timer_dev.timer[i]);
|
||||
+ if (ret) {
|
||||
+ for (; i >= 0; i--)
|
||||
+ free_irq(TIMER_INTERRUPT + i, &timer_dev.timer[i]);
|
||||
+ misc_deregister(&gptu_miscdev);
|
||||
+ printk(KERN_ERR "gptu: failed in requesting irq (%d), get error %d\n", i, -ret);
|
||||
+ return ret;
|
||||
+ } else {
|
||||
+ timer_dev.timer[i].irq = TIMER_INTERRUPT + i;
|
||||
+ disable_irq(timer_dev.timer[i].irq);
|
||||
+ printk(KERN_INFO "gptu: succeeded to request irq %d\n", timer_dev.timer[i].irq);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+void __exit lq_gptu_exit(void)
|
||||
+{
|
||||
+ unsigned int i;
|
||||
+
|
||||
+ for (i = 0; i < timer_dev.number_of_timers; i++) {
|
||||
+ if (timer_dev.timer[i].f_irq_on)
|
||||
+ disable_irq(timer_dev.timer[i].irq);
|
||||
+ free_irq(timer_dev.timer[i].irq, &timer_dev.timer[i]);
|
||||
+ }
|
||||
+ lq_disable_gptu();
|
||||
+ misc_deregister(&gptu_miscdev);
|
||||
+}
|
||||
+
|
||||
+module_init(lq_gptu_init);
|
||||
+module_exit(lq_gptu_exit);
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/include/asm/mach-lantiq/lantiq_timer.h
|
||||
@@ -0,0 +1,155 @@
|
||||
+#ifndef __DANUBE_GPTU_DEV_H__2005_07_26__10_19__
|
||||
+#define __DANUBE_GPTU_DEV_H__2005_07_26__10_19__
|
||||
+
|
||||
+
|
||||
+/******************************************************************************
|
||||
+ Copyright (c) 2002, Infineon Technologies. All rights reserved.
|
||||
+
|
||||
+ No Warranty
|
||||
+ Because the program is licensed free of charge, there is no warranty for
|
||||
+ the program, to the extent permitted by applicable law. Except when
|
||||
+ otherwise stated in writing the copyright holders and/or other parties
|
||||
+ provide the program "as is" without warranty of any kind, either
|
||||
+ expressed or implied, including, but not limited to, the implied
|
||||
+ warranties of merchantability and fitness for a particular purpose. The
|
||||
+ entire risk as to the quality and performance of the program is with
|
||||
+ you. should the program prove defective, you assume the cost of all
|
||||
+ necessary servicing, repair or correction.
|
||||
+
|
||||
+ In no event unless required by applicable law or agreed to in writing
|
||||
+ will any copyright holder, or any other party who may modify and/or
|
||||
+ redistribute the program as permitted above, be liable to you for
|
||||
+ damages, including any general, special, incidental or consequential
|
||||
+ damages arising out of the use or inability to use the program
|
||||
+ (including but not limited to loss of data or data being rendered
|
||||
+ inaccurate or losses sustained by you or third parties or a failure of
|
||||
+ the program to operate with any other programs), even if such holder or
|
||||
+ other party has been advised of the possibility of such damages.
|
||||
+******************************************************************************/
|
||||
+
|
||||
+
|
||||
+/*
|
||||
+ * ####################################
|
||||
+ * Definition
|
||||
+ * ####################################
|
||||
+ */
|
||||
+
|
||||
+/*
|
||||
+ * Available Timer/Counter Index
|
||||
+ */
|
||||
+#define TIMER(n, X) (n * 2 + (X ? 1 : 0))
|
||||
+#define TIMER_ANY 0x00
|
||||
+#define TIMER1A TIMER(1, 0)
|
||||
+#define TIMER1B TIMER(1, 1)
|
||||
+#define TIMER2A TIMER(2, 0)
|
||||
+#define TIMER2B TIMER(2, 1)
|
||||
+#define TIMER3A TIMER(3, 0)
|
||||
+#define TIMER3B TIMER(3, 1)
|
||||
+
|
||||
+/*
|
||||
+ * Flag of Timer/Counter
|
||||
+ * These flags specify the way in which timer is configured.
|
||||
+ */
|
||||
+/* Bit size of timer/counter. */
|
||||
+#define TIMER_FLAG_16BIT 0x0000
|
||||
+#define TIMER_FLAG_32BIT 0x0001
|
||||
+/* Switch between timer and counter. */
|
||||
+#define TIMER_FLAG_TIMER 0x0000
|
||||
+#define TIMER_FLAG_COUNTER 0x0002
|
||||
+/* Stop or continue when overflowing/underflowing. */
|
||||
+#define TIMER_FLAG_ONCE 0x0000
|
||||
+#define TIMER_FLAG_CYCLIC 0x0004
|
||||
+/* Count up or counter down. */
|
||||
+#define TIMER_FLAG_UP 0x0000
|
||||
+#define TIMER_FLAG_DOWN 0x0008
|
||||
+/* Count on specific level or edge. */
|
||||
+#define TIMER_FLAG_HIGH_LEVEL_SENSITIVE 0x0000
|
||||
+#define TIMER_FLAG_LOW_LEVEL_SENSITIVE 0x0040
|
||||
+#define TIMER_FLAG_RISE_EDGE 0x0010
|
||||
+#define TIMER_FLAG_FALL_EDGE 0x0020
|
||||
+#define TIMER_FLAG_ANY_EDGE 0x0030
|
||||
+/* Signal is syncronous to module clock or not. */
|
||||
+#define TIMER_FLAG_UNSYNC 0x0000
|
||||
+#define TIMER_FLAG_SYNC 0x0080
|
||||
+/* Different interrupt handle type. */
|
||||
+#define TIMER_FLAG_NO_HANDLE 0x0000
|
||||
+#if defined(__KERNEL__)
|
||||
+ #define TIMER_FLAG_CALLBACK_IN_IRQ 0x0100
|
||||
+#endif // defined(__KERNEL__)
|
||||
+#define TIMER_FLAG_SIGNAL 0x0300
|
||||
+/* Internal clock source or external clock source */
|
||||
+#define TIMER_FLAG_INT_SRC 0x0000
|
||||
+#define TIMER_FLAG_EXT_SRC 0x1000
|
||||
+
|
||||
+
|
||||
+/*
|
||||
+ * ioctl Command
|
||||
+ */
|
||||
+#define GPTU_REQUEST_TIMER 0x01 /* General method to setup timer/counter. */
|
||||
+#define GPTU_FREE_TIMER 0x02 /* Free timer/counter. */
|
||||
+#define GPTU_START_TIMER 0x03 /* Start or resume timer/counter. */
|
||||
+#define GPTU_STOP_TIMER 0x04 /* Suspend timer/counter. */
|
||||
+#define GPTU_GET_COUNT_VALUE 0x05 /* Get current count value. */
|
||||
+#define GPTU_CALCULATE_DIVIDER 0x06 /* Calculate timer divider from given freq.*/
|
||||
+#define GPTU_SET_TIMER 0x07 /* Simplified method to setup timer. */
|
||||
+#define GPTU_SET_COUNTER 0x08 /* Simplified method to setup counter. */
|
||||
+
|
||||
+/*
|
||||
+ * Data Type Used to Call ioctl
|
||||
+ */
|
||||
+struct gptu_ioctl_param {
|
||||
+ unsigned int timer; /* In command GPTU_REQUEST_TIMER, GPTU_SET_TIMER, and *
|
||||
+ * GPTU_SET_COUNTER, this field is ID of expected *
|
||||
+ * timer/counter. If it's zero, a timer/counter would *
|
||||
+ * be dynamically allocated and ID would be stored in *
|
||||
+ * this field. *
|
||||
+ * In command GPTU_GET_COUNT_VALUE, this field is *
|
||||
+ * ignored. *
|
||||
+ * In other command, this field is ID of timer/counter *
|
||||
+ * allocated. */
|
||||
+ unsigned int flag; /* In command GPTU_REQUEST_TIMER, GPTU_SET_TIMER, and *
|
||||
+ * GPTU_SET_COUNTER, this field contains flags to *
|
||||
+ * specify how to configure timer/counter. *
|
||||
+ * In command GPTU_START_TIMER, zero indicate start *
|
||||
+ * and non-zero indicate resume timer/counter. *
|
||||
+ * In other command, this field is ignored. */
|
||||
+ unsigned long value; /* In command GPTU_REQUEST_TIMER, this field contains *
|
||||
+ * init/reload value. *
|
||||
+ * In command GPTU_SET_TIMER, this field contains *
|
||||
+ * frequency (0.001Hz) of timer. *
|
||||
+ * In command GPTU_GET_COUNT_VALUE, current count *
|
||||
+ * value would be stored in this field. *
|
||||
+ * In command GPTU_CALCULATE_DIVIDER, this field *
|
||||
+ * contains frequency wanted, and after calculation, *
|
||||
+ * divider would be stored in this field to overwrite *
|
||||
+ * the frequency. *
|
||||
+ * In other command, this field is ignored. */
|
||||
+ int pid; /* In command GPTU_REQUEST_TIMER and GPTU_SET_TIMER, *
|
||||
+ * if signal is required, this field contains process *
|
||||
+ * ID to which signal would be sent. *
|
||||
+ * In other command, this field is ignored. */
|
||||
+ int sig; /* In command GPTU_REQUEST_TIMER and GPTU_SET_TIMER, *
|
||||
+ * if signal is required, this field contains signal *
|
||||
+ * number which would be sent. *
|
||||
+ * In other command, this field is ignored. */
|
||||
+};
|
||||
+
|
||||
+/*
|
||||
+ * ####################################
|
||||
+ * Data Type
|
||||
+ * ####################################
|
||||
+ */
|
||||
+typedef void (*timer_callback)(unsigned long arg);
|
||||
+
|
||||
+extern int lq_request_timer(unsigned int, unsigned int, unsigned long, unsigned long, unsigned long);
|
||||
+extern int lq_free_timer(unsigned int);
|
||||
+extern int lq_start_timer(unsigned int, int);
|
||||
+extern int lq_stop_timer(unsigned int);
|
||||
+extern int lq_reset_counter_flags(u32 timer, u32 flags);
|
||||
+extern int lq_get_count_value(unsigned int, unsigned long *);
|
||||
+extern u32 lq_cal_divider(unsigned long);
|
||||
+extern int lq_set_timer(unsigned int, unsigned int, int, int, unsigned int, unsigned long, unsigned long);
|
||||
+extern int lq_set_counter(unsigned int timer, unsigned int flag,
|
||||
+ u32 reload, unsigned long arg1, unsigned long arg2);
|
||||
+
|
||||
+#endif /* __DANUBE_GPTU_DEV_H__2005_07_26__10_19__ */
|
||||
--- a/arch/mips/lantiq/xway/Makefile
|
||||
+++ b/arch/mips/lantiq/xway/Makefile
|
||||
@@ -1,4 +1,4 @@
|
||||
-obj-y := pmu.o ebu.o reset.o gpio.o gpio_stp.o gpio_ebu.o devices.o dma.o
|
||||
+obj-y := pmu.o ebu.o reset.o gpio.o gpio_stp.o gpio_ebu.o devices.o dma.o timer.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
|
File diff suppressed because it is too large
Load Diff
|
@ -1,95 +0,0 @@
|
|||
--- /dev/null
|
||||
+++ b/arch/mips/include/asm/mach-lantiq/dev-leds-gpio.h
|
||||
@@ -0,0 +1,21 @@
|
||||
+/*
|
||||
+ * 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_leds_gpio(int id,
|
||||
+ unsigned num_leds,
|
||||
+ struct gpio_led *leds) __init;
|
||||
+
|
||||
+#endif /* _LANTIQ_DEV_LEDS_GPIO_H */
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/lantiq/dev-leds-gpio.c
|
||||
@@ -0,0 +1,57 @@
|
||||
+/*
|
||||
+ * 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-leds-gpio.h"
|
||||
+
|
||||
+void __init ltq_add_device_leds_gpio(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);
|
||||
+}
|
||||
--- a/arch/mips/lantiq/Makefile
|
||||
+++ b/arch/mips/lantiq/Makefile
|
||||
@@ -4,7 +4,7 @@
|
||||
# under the terms of the GNU General Public License version 2 as published
|
||||
# by the Free Software Foundation.
|
||||
|
||||
-obj-y := irq.o setup.o clk.o prom.o devices.o dev-gpio-buttons.o
|
||||
+obj-y := irq.o setup.o clk.o prom.o devices.o dev-gpio-buttons.o dev-leds-gpio.o
|
||||
|
||||
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
--- a/arch/mips/lantiq/xway/gpio_ebu.c
|
||||
+++ b/arch/mips/lantiq/xway/gpio_ebu.c
|
||||
@@ -63,7 +63,6 @@ static struct gpio_chip ltq_ebu_chip = {
|
||||
.set = ltq_ebu_set,
|
||||
.base = 72,
|
||||
.ngpio = 16,
|
||||
- .can_sleep = 1,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
--- a/arch/mips/lantiq/xway/gpio_stp.c
|
||||
+++ b/arch/mips/lantiq/xway/gpio_stp.c
|
||||
@@ -72,7 +72,6 @@ static struct gpio_chip ltq_stp_chip = {
|
||||
.set = ltq_stp_set,
|
||||
.base = 48,
|
||||
.ngpio = 24,
|
||||
- .can_sleep = 1,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
|
@ -1,111 +0,0 @@
|
|||
--- a/arch/mips/lantiq/machtypes.h
|
||||
+++ b/arch/mips/lantiq/machtypes.h
|
||||
@@ -34,6 +34,9 @@ enum lantiq_mach_type {
|
||||
LANTIQ_MACH_ARV752DPW, /* Arcor easybox a802 */
|
||||
LANTIQ_MACH_ARV752DPW22, /* Arcor easybox a803 */
|
||||
LANTIQ_MACH_ARV7518PW, /* ASTORIA */
|
||||
+
|
||||
+ /* Netgear */
|
||||
+ LANTIQ_MACH_DGN3500B, /* Netgear DGN3500 */
|
||||
};
|
||||
|
||||
#endif
|
||||
--- a/arch/mips/lantiq/xway/Kconfig
|
||||
+++ b/arch/mips/lantiq/xway/Kconfig
|
||||
@@ -10,6 +10,10 @@ config LANTIQ_MACH_ARV45XX
|
||||
bool "ARV45XX"
|
||||
default y
|
||||
|
||||
+config LANTIQ_MACH_NETGEAR
|
||||
+ bool "Netgear"
|
||||
+ default y
|
||||
+
|
||||
endmenu
|
||||
|
||||
endif
|
||||
--- a/arch/mips/lantiq/xway/Makefile
|
||||
+++ b/arch/mips/lantiq/xway/Makefile
|
||||
@@ -6,4 +6,5 @@ obj-$(CONFIG_SOC_AMAZON_SE) += clk-ase.o
|
||||
obj-$(CONFIG_LANTIQ_MACH_EASY50712) += mach-easy50712.o
|
||||
obj-$(CONFIG_LANTIQ_MACH_EASY50601) += mach-easy50601.o
|
||||
obj-$(CONFIG_LANTIQ_MACH_ARV45XX) += mach-arv45xx.o
|
||||
+obj-$(CONFIG_LANTIQ_MACH_NETGEAR) += mach-netgear.o
|
||||
obj-y += dev-dwc_otg.o
|
||||
--- a/arch/mips/lantiq/xway/devices.h
|
||||
+++ b/arch/mips/lantiq/xway/devices.h
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
#include "../devices.h"
|
||||
#include <linux/phy.h>
|
||||
+#include <linux/spi/spi.h>
|
||||
|
||||
extern void ltq_register_gpio(void);
|
||||
extern void ltq_register_gpio_stp(void);
|
||||
@@ -18,5 +19,7 @@ extern void ltq_register_ase_asc(void);
|
||||
extern void ltq_register_etop(struct ltq_eth_data *eth);
|
||||
extern void ltq_register_gpio_ebu(unsigned int value);
|
||||
extern void ltq_register_madwifi_eep(unsigned long long addr);
|
||||
+extern void ltq_register_spi(struct ltq_spi_platform_data *pdata,
|
||||
+ struct spi_board_info const *info, unsigned n);
|
||||
|
||||
#endif
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/lantiq/xway/mach-netgear.c
|
||||
@@ -0,0 +1,57 @@
|
||||
+/*
|
||||
+ * 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 <lantiq_soc.h>
|
||||
+#include <irq.h>
|
||||
+
|
||||
+#include "../machtypes.h"
|
||||
+#include "devices.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,
|
||||
+};
|
||||
+
|
||||
+struct spi_board_info spi_info = {
|
||||
+ .bus_num = 0,
|
||||
+ .chip_select = 3,
|
||||
+ .max_speed_hz = 25000000,
|
||||
+ .modalias = "mx25l12805d",
|
||||
+};
|
||||
+
|
||||
+struct ltq_spi_platform_data ltq_spi_data = {
|
||||
+ .num_chipselect = 4,
|
||||
+};
|
||||
+
|
||||
+static void __init dgn3500_init(void)
|
||||
+{
|
||||
+ ltq_register_pci(<q_pci_data);
|
||||
+ ltq_register_etop(<q_eth_data);
|
||||
+ ltq_register_spi(<q_spi_data, &spi_info, 1);
|
||||
+}
|
||||
+
|
||||
+MIPS_MACHINE(LANTIQ_MACH_DGN3500B,
|
||||
+ "DGN3500B",
|
||||
+ "Netgear DGN3500B",
|
||||
+ dgn3500_init);
|
|
@ -1,246 +0,0 @@
|
|||
--- a/arch/mips/lantiq/xway/Kconfig
|
||||
+++ b/arch/mips/lantiq/xway/Kconfig
|
||||
@@ -14,6 +14,11 @@ config LANTIQ_MACH_NETGEAR
|
||||
bool "Netgear"
|
||||
default y
|
||||
|
||||
+config LANTIQ_MACH_GIGASX76X
|
||||
+ bool "GIGASX76X"
|
||||
+ select LTQ_DEV_GPIO_BUTTONS
|
||||
+ default y
|
||||
+
|
||||
endmenu
|
||||
|
||||
endif
|
||||
--- a/arch/mips/lantiq/xway/Makefile
|
||||
+++ b/arch/mips/lantiq/xway/Makefile
|
||||
@@ -7,4 +7,5 @@ obj-$(CONFIG_LANTIQ_MACH_EASY50712) += m
|
||||
obj-$(CONFIG_LANTIQ_MACH_EASY50601) += mach-easy50601.o
|
||||
obj-$(CONFIG_LANTIQ_MACH_ARV45XX) += mach-arv45xx.o
|
||||
obj-$(CONFIG_LANTIQ_MACH_NETGEAR) += mach-netgear.o
|
||||
+obj-$(CONFIG_LANTIQ_MACH_GIGASX76X) += mach-gigasx76x.o
|
||||
obj-y += dev-dwc_otg.o
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/lantiq/xway/mach-gigasx76x.c
|
||||
@@ -0,0 +1,209 @@
|
||||
+/*
|
||||
+ * 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/string.h>
|
||||
+
|
||||
+#include <irq.h>
|
||||
+
|
||||
+#include <lantiq_soc.h>
|
||||
+#include <lantiq_platform.h>
|
||||
+
|
||||
+#include "devices.h"
|
||||
+#include "dev-dwc_otg.h"
|
||||
+#include "../machtypes.h"
|
||||
+#include "../dev-leds-gpio.h"
|
||||
+#include "../dev-gpio-buttons.h"
|
||||
+
|
||||
+#define UBOOT_ENV_OFFSET 0x010000
|
||||
+#define UBOOT_ENV_SIZE 0x010000
|
||||
+
|
||||
+#ifdef CONFIG_MTD_PARTITIONS
|
||||
+static struct mtd_partition gigasx76x_partitions[] =
|
||||
+{
|
||||
+ {
|
||||
+ .name = "uboot",
|
||||
+ .offset = 0x000000,
|
||||
+ .size = 0x010000,
|
||||
+ },
|
||||
+ {
|
||||
+ .name = "uboot_env",
|
||||
+ .offset = UBOOT_ENV_OFFSET,
|
||||
+ .size = UBOOT_ENV_SIZE,
|
||||
+ },
|
||||
+ {
|
||||
+ .name = "linux",
|
||||
+ .offset = 0x020000,
|
||||
+ .size = 0x7d0000,
|
||||
+ },
|
||||
+ {
|
||||
+ .name = "board_config",
|
||||
+ .offset = 0x7f0000,
|
||||
+ .size = 0x010000,
|
||||
+ },
|
||||
+};
|
||||
+#endif
|
||||
+
|
||||
+static struct gpio_led
|
||||
+gigasx76x_gpio_leds[] __initdata = {
|
||||
+ { .name = "soc:green:usb", .gpio = 50, },
|
||||
+ { .name = "soc:green:wlan", .gpio = 51, },
|
||||
+ { .name = "soc:green:phone2", .gpio = 52, },
|
||||
+ { .name = "soc:green:phone1", .gpio = 53, },
|
||||
+ { .name = "soc:green:line", .gpio = 54, },
|
||||
+ { .name = "soc:green:online", .gpio = 55, },
|
||||
+ { .name = "soc:green:voip", .gpio = 56, },
|
||||
+};
|
||||
+
|
||||
+static struct gpio_keys_button
|
||||
+gigasx76x_gpio_keys[] __initdata = {
|
||||
+ {
|
||||
+ .desc = "reset",
|
||||
+ .type = EV_KEY,
|
||||
+ .code = KEY_RESTART,
|
||||
+ .debounce_interval = LTQ_KEYS_DEBOUNCE_INTERVAL,
|
||||
+ .gpio = 14,
|
||||
+ .active_low = 1,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static struct physmap_flash_data gigasx76x_flash_data = {
|
||||
+#ifdef CONFIG_MTD_PARTITIONS
|
||||
+ .nr_parts = ARRAY_SIZE(gigasx76x_partitions),
|
||||
+ .parts = gigasx76x_partitions,
|
||||
+#endif
|
||||
+};
|
||||
+
|
||||
+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;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * gigasx76x_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 gigasx76x_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 gigasx76x_parse_hex_byte(const char *b) {
|
||||
+ int hi;
|
||||
+ int lo;
|
||||
+
|
||||
+ hi = gigasx76x_parse_hex_nibble(b[0]);
|
||||
+ lo = gigasx76x_parse_hex_nibble(b[1]);
|
||||
+
|
||||
+ if (hi < 0 || lo < 0)
|
||||
+ return -1;
|
||||
+
|
||||
+ return (hi << 4) | lo;
|
||||
+}
|
||||
+
|
||||
+static int __init gigasx76x_register_ethernet(void) {
|
||||
+ u_int8_t addr[6];
|
||||
+ int i;
|
||||
+ char *uboot_env_page;
|
||||
+ char *mac;
|
||||
+
|
||||
+ uboot_env_page = ioremap(LTQ_FLASH_START + UBOOT_ENV_OFFSET, UBOOT_ENV_SIZE);
|
||||
+ if (!uboot_env_page)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ mac = get_uboot_env_var(uboot_env_page, UBOOT_ENV_SIZE, "\0ethaddr=", 9);
|
||||
+
|
||||
+ if (!mac) {
|
||||
+ 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 = gigasx76x_parse_hex_byte(mac + (i * 3));
|
||||
+ if (byte < 0) {
|
||||
+ goto error_fail;
|
||||
+ }
|
||||
+ addr[i] = byte;
|
||||
+ }
|
||||
+
|
||||
+ iounmap(uboot_env_page);
|
||||
+ printk("GIGASX76X: Found ethernet MAC address: ");
|
||||
+ for (i = 0; i < 6; i++)
|
||||
+ printk("%.2x%s", addr[i], (i < 5) ? ":" : ".\n");
|
||||
+
|
||||
+ memcpy(<q_eth_data.mac.sa_data, addr, 6);
|
||||
+ ltq_register_etop(<q_eth_data);
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+ error_fail:
|
||||
+ iounmap(uboot_env_page);
|
||||
+ return -EINVAL;
|
||||
+}
|
||||
+
|
||||
+static void __init gigasx76x_init(void) {
|
||||
+#define GIGASX76X_USB 29
|
||||
+#define GIGASX76X_MADWIFI_ADDR 0xb07f0000
|
||||
+
|
||||
+ ltq_register_gpio_stp();
|
||||
+ ltq_register_nor(&gigasx76x_flash_data);
|
||||
+ ltq_register_pci(<q_pci_data);
|
||||
+ gigasx76x_register_ethernet();
|
||||
+ xway_register_dwc(GIGASX76X_USB);
|
||||
+ ltq_register_tapi();
|
||||
+ ltq_register_madwifi_eep(GIGASX76X_MADWIFI_ADDR);
|
||||
+ ltq_add_device_leds_gpio(-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);
|
||||
+}
|
||||
+
|
||||
+MIPS_MACHINE(LANTIQ_MACH_GIGASX76X, "GIGASX76X", "GIGASX76X - Gigaset SX761,SX762,SX763", gigasx76x_init);
|
||||
--- a/arch/mips/lantiq/machtypes.h
|
||||
+++ b/arch/mips/lantiq/machtypes.h
|
||||
@@ -37,6 +37,9 @@ enum lantiq_mach_type {
|
||||
|
||||
/* Netgear */
|
||||
LANTIQ_MACH_DGN3500B, /* Netgear DGN3500 */
|
||||
+
|
||||
+ /* Gigaset */
|
||||
+ LANTIQ_MACH_GIGASX76X, /* Gigaset SX76x */
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,157 +0,0 @@
|
|||
--- a/arch/mips/lantiq/machtypes.h
|
||||
+++ b/arch/mips/lantiq/machtypes.h
|
||||
@@ -40,6 +40,9 @@
|
||||
|
||||
/* Gigaset */
|
||||
LANTIQ_MACH_GIGASX76X, /* Gigaset SX76x */
|
||||
+
|
||||
+ /* Buffalo */
|
||||
+ LANTIQ_MACH_WBMR, /* WBMR-HP-G300H */
|
||||
};
|
||||
|
||||
#endif
|
||||
--- a/arch/mips/lantiq/xway/Kconfig
|
||||
+++ b/arch/mips/lantiq/xway/Kconfig
|
||||
@@ -19,6 +19,11 @@
|
||||
select LTQ_DEV_GPIO_BUTTONS
|
||||
default y
|
||||
|
||||
+config LANTIQ_MACH_WBMR
|
||||
+ bool "WBMR-HP-G300H"
|
||||
+ select LTQ_DEV_GPIO_BUTTONS
|
||||
+ default y
|
||||
+
|
||||
endmenu
|
||||
|
||||
endif
|
||||
--- a/arch/mips/lantiq/xway/Makefile
|
||||
+++ b/arch/mips/lantiq/xway/Makefile
|
||||
@@ -8,4 +8,5 @@
|
||||
obj-$(CONFIG_LANTIQ_MACH_ARV45XX) += mach-arv45xx.o
|
||||
obj-$(CONFIG_LANTIQ_MACH_NETGEAR) += mach-netgear.o
|
||||
obj-$(CONFIG_LANTIQ_MACH_GIGASX76X) += mach-gigasx76x.o
|
||||
+obj-$(CONFIG_LANTIQ_MACH_WBMR) += mach-wbmr.o
|
||||
obj-y += dev-dwc_otg.o
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/lantiq/xway/mach-wbmr.c
|
||||
@@ -0,0 +1,120 @@
|
||||
+/*
|
||||
+ * 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 "../machtypes.h"
|
||||
+#include "devices.h"
|
||||
+#include "dev-leds-gpio.h"
|
||||
+#include "dev-dwc_otg.h"
|
||||
+#include "../dev-gpio-buttons.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_leds_gpio[] __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_MII,
|
||||
+};
|
||||
+
|
||||
+static void __init
|
||||
+wbmr_init(void)
|
||||
+{
|
||||
+#define WMBR_BRN_MAC 0x1fd0024
|
||||
+
|
||||
+ ltq_add_device_leds_gpio(-1, ARRAY_SIZE(wbmr_leds_gpio), wbmr_leds_gpio);
|
||||
+ 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(<q_pci_data);
|
||||
+ memcpy_fromio(<q_eth_data.mac.sa_data,
|
||||
+ (void *)KSEG1ADDR(LTQ_FLASH_START + WMBR_BRN_MAC), 6);
|
||||
+ ltq_register_etop(<q_eth_data);
|
||||
+ xway_register_dwc(36);
|
||||
+}
|
||||
+
|
||||
+MIPS_MACHINE(LANTIQ_MACH_WBMR,
|
||||
+ "WBMR",
|
||||
+ "WBMR",
|
||||
+ wbmr_init);
|
|
@ -1,14 +0,0 @@
|
|||
--- a/drivers/tty/serial/lantiq.c
|
||||
+++ b/drivers/tty/serial/lantiq.c
|
||||
@@ -478,8 +478,10 @@ lqasc_set_termios(struct uart_port *port
|
||||
spin_unlock_irqrestore(<q_asc_lock, flags);
|
||||
|
||||
/* Don't rewrite B0 */
|
||||
- if (tty_termios_baud_rate(new))
|
||||
+ if (tty_termios_baud_rate(new))
|
||||
tty_termios_encode_baud_rate(new, baud, baud);
|
||||
+
|
||||
+ uart_update_timeout(port, cflag, baud);
|
||||
}
|
||||
|
||||
static const char*
|
|
@ -1,26 +0,0 @@
|
|||
--- a/arch/mips/lantiq/early_printk.c
|
||||
+++ b/arch/mips/lantiq/early_printk.c
|
||||
@@ -20,7 +20,12 @@
|
||||
#endif
|
||||
#define ASC_BUF 1024
|
||||
#define LTQ_ASC_FSTAT ((u32 *)(LTQ_ASC_BASE + 0x0048))
|
||||
-#define LTQ_ASC_TBUF ((u32 *)(LTQ_ASC_BASE + 0x0020))
|
||||
+#ifdef __BIG_ENDIAN
|
||||
+#define LTQ_ASC_TBUF ((u8 *)(LTQ_ASC_BASE + 0x0023))
|
||||
+#else
|
||||
+#define LTQ_ASC_TBUF ((u8 *)(LTQ_ASC_BASE + 0x0020))
|
||||
+#endif
|
||||
+
|
||||
#define TXMASK 0x3F00
|
||||
#define TXOFFSET 8
|
||||
|
||||
@@ -30,8 +35,6 @@ 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(c, LTQ_ASC_TBUF);
|
||||
local_irq_restore(flags);
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
--- /dev/null
|
||||
+++ b/arch/mips/include/asm/mach-lantiq/falcon/lantiq_soc.h
|
||||
@@ -0,0 +1,40 @@
|
||||
+/*
|
||||
+ * 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>
|
||||
+ */
|
||||
+
|
||||
+#ifndef _LTQ_FALCON_H__
|
||||
+#define _LTQ_FALCON_H__
|
||||
+
|
||||
+#ifdef CONFIG_SOC_FALCON
|
||||
+
|
||||
+#include <lantiq.h>
|
||||
+
|
||||
+/* Chip IDs */
|
||||
+#define SOC_ID_FALCON 0x01B8
|
||||
+
|
||||
+/* SoC Types */
|
||||
+#define SOC_TYPE_FALCON 0x01
|
||||
+
|
||||
+/* ASC0/1 - serial port */
|
||||
+#define LTQ_ASC0_BASE_ADDR 0x1E100C00
|
||||
+#define LTQ_ASC1_BASE_ADDR 0x1E100B00
|
||||
+#define LTQ_ASC_SIZE 0x100
|
||||
+
|
||||
+#define LTQ_ASC_TIR(x) (INT_NUM_IM3_IRL0 + (x * 8))
|
||||
+#define LTQ_ASC_RIR(x) (INT_NUM_IM3_IRL0 + (x * 8) + 1)
|
||||
+#define LTQ_ASC_EIR(x) (INT_NUM_IM3_IRL0 + (x * 8) + 2)
|
||||
+
|
||||
+/* ICU - interrupt control unit */
|
||||
+#define LTQ_ICU_BASE_ADDR 0x1F880200
|
||||
+#define LTQ_ICU_SIZE 0x100
|
||||
+
|
||||
+/* WDT */
|
||||
+#define LTQ_WDT_BASE_ADDR 0x1F8803F0
|
||||
+#define LTQ_WDT_SIZE 0x10
|
||||
+
|
||||
+#endif /* CONFIG_SOC_FALCON */
|
||||
+#endif /* _LTQ_XWAY_H__ */
|
|
@ -1,98 +0,0 @@
|
|||
--- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h
|
||||
+++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h
|
||||
@@ -40,6 +40,15 @@
|
||||
|
||||
#define MIPS_CPU_TIMER_IRQ 7
|
||||
|
||||
+#ifdef CONFIG_SOC_AMAZON_SE
|
||||
+#define LTQ_DMA_CH0_INT (INT_NUM_IM3_IRL0)
|
||||
+#define LTQ_DMA_CH1_INT (INT_NUM_IM3_IRL0 + 1)
|
||||
+#define LTQ_DMA_CH2_INT (INT_NUM_IM3_IRL0 + 2)
|
||||
+#define LTQ_DMA_CH3_INT (INT_NUM_IM3_IRL0 + 3)
|
||||
+#define LTQ_DMA_CH4_INT (INT_NUM_IM3_IRL0 + 4)
|
||||
+#define LTQ_DMA_CH5_INT (INT_NUM_IM3_IRL0 + 5)
|
||||
+#define LTQ_DMA_CH6_INT (INT_NUM_IM3_IRL0 + 6)
|
||||
+#else
|
||||
#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)
|
||||
@@ -47,6 +56,7 @@
|
||||
#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)
|
||||
+#endif
|
||||
#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)
|
||||
--- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
|
||||
+++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
|
||||
@@ -128,6 +128,11 @@
|
||||
extern void ltq_pmu_enable(unsigned int module);
|
||||
extern void ltq_pmu_disable(unsigned int module);
|
||||
|
||||
+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/mach-easy50601.c
|
||||
+++ b/arch/mips/lantiq/xway/mach-easy50601.c
|
||||
@@ -41,9 +41,14 @@
|
||||
.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(<q_eth_data);
|
||||
}
|
||||
|
||||
MIPS_MACHINE(LTQ_MACH_EASY50601,
|
||||
--- a/drivers/net/lantiq_etop.c
|
||||
+++ b/drivers/net/lantiq_etop.c
|
||||
@@ -72,7 +72,11 @@
|
||||
|
||||
/* use 2 static channels for TX/RX */
|
||||
#define LTQ_ETOP_TX_CHANNEL 1
|
||||
+#ifdef CONFIG_SOC_AMAZON_SE
|
||||
+#define LTQ_ETOP_RX_CHANNEL 5
|
||||
+#else
|
||||
#define LTQ_ETOP_RX_CHANNEL 6
|
||||
+#endif
|
||||
#define IS_TX(x) (x == LTQ_ETOP_TX_CHANNEL)
|
||||
#define IS_RX(x) (x == LTQ_ETOP_RX_CHANNEL)
|
||||
|
||||
@@ -255,6 +259,9 @@
|
||||
}
|
||||
|
||||
static int
|
||||
+ltq_etop_mdio_wr(struct mii_bus *bus, int phy_addr, int phy_reg, u16 phy_data);
|
||||
+
|
||||
+static int
|
||||
ltq_etop_hw_init(struct net_device *dev)
|
||||
{
|
||||
struct ltq_etop_priv *priv = netdev_priv(dev);
|
||||
@@ -274,6 +281,16 @@
|
||||
break;
|
||||
|
||||
default:
|
||||
+ if (ltq_is_ase()) {
|
||||
+#define PMU_EPHY 0x80
|
||||
+#define LTQ_CGU_IFCCR 0x0018
|
||||
+ ltq_pmu_enable(PMU_EPHY);
|
||||
+ ltq_etop_w32_mask(0, 1, LTQ_ETOP_CFG);
|
||||
+ ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) | (0x1 << 4), LTQ_CGU_IFCCR);
|
||||
+ ltq_etop_mdio_wr(NULL, 0x8, 0x12, 0xC020);
|
||||
+ printk("Selected EPHY mode \n");
|
||||
+ break;
|
||||
+ }
|
||||
netdev_err(dev, "unknown mii mode %d\n",
|
||||
priv->pldata->mii_mode);
|
||||
return -ENOTSUPP;
|
|
@ -1,20 +0,0 @@
|
|||
--- a/arch/mips/lantiq/irq.c
|
||||
+++ b/arch/mips/lantiq/irq.c
|
||||
@@ -132,7 +132,7 @@
|
||||
static unsigned int ltq_startup_eiu_irq(struct irq_data *d)
|
||||
{
|
||||
int i;
|
||||
- int irq_nr = d->irq - INT_NUM_IRQ0;
|
||||
+ int irq_nr = d->irq;
|
||||
|
||||
ltq_enable_irq(d);
|
||||
for (i = 0; i < MAX_EIU; i++) {
|
||||
@@ -156,7 +156,7 @@
|
||||
static void ltq_shutdown_eiu_irq(struct irq_data *d)
|
||||
{
|
||||
int i;
|
||||
- int irq_nr = d->irq - INT_NUM_IRQ0;
|
||||
+ int irq_nr = d->irq;
|
||||
|
||||
ltq_disable_irq(d);
|
||||
for (i = 0; i < MAX_EIU; i++) {
|
|
@ -1,18 +0,0 @@
|
|||
--- a/arch/mips/pci/pci-lantiq.c
|
||||
+++ b/arch/mips/pci/pci-lantiq.c
|
||||
@@ -171,8 +171,13 @@
|
||||
u32 temp_buffer;
|
||||
|
||||
/* set clock to 33Mhz */
|
||||
- ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) & ~0xf00000, LTQ_CGU_IFCCR);
|
||||
- ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) | 0x800000, LTQ_CGU_IFCCR);
|
||||
+ if (ltq_is_ar9()) {
|
||||
+ ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) & ~0x1f00000, LTQ_CGU_IFCCR);
|
||||
+ ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) | 0xe00000, LTQ_CGU_IFCCR);
|
||||
+ } else {
|
||||
+ ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) & ~0xf00000, LTQ_CGU_IFCCR);
|
||||
+ ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) | 0x800000, LTQ_CGU_IFCCR);
|
||||
+ }
|
||||
|
||||
/* external or internal clock ? */
|
||||
if (conf->clock) {
|
|
@ -1,45 +0,0 @@
|
|||
From 14ea48a5f5702ddc97425cbe520600e187e14e4a Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Thu, 11 Aug 2011 13:58:39 +0200
|
||||
Subject: [PATCH 03/24] MIPS: lantiq: fix watchdogs timeout handling
|
||||
|
||||
The enable function was using the global timeout variable for local operations.
|
||||
This resulted in the value of the global variable being corrupted, thus
|
||||
breaking the code.
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
Signed-off-by: Thomas Langer <thomas.langer@lantiq.com>
|
||||
Cc: linux-watchdog@vger.kernel.org
|
||||
Cc: linux-mips@linux-mips.org
|
||||
---
|
||||
drivers/watchdog/lantiq_wdt.c | 8 ++++----
|
||||
1 files changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/drivers/watchdog/lantiq_wdt.c b/drivers/watchdog/lantiq_wdt.c
|
||||
index 7d82ada..102aed0 100644
|
||||
--- a/drivers/watchdog/lantiq_wdt.c
|
||||
+++ b/drivers/watchdog/lantiq_wdt.c
|
||||
@@ -51,16 +51,16 @@ static int ltq_wdt_ok_to_close;
|
||||
static void
|
||||
ltq_wdt_enable(void)
|
||||
{
|
||||
- ltq_wdt_timeout = ltq_wdt_timeout *
|
||||
+ unsigned long int timeout = ltq_wdt_timeout *
|
||||
(ltq_io_region_clk_rate / LTQ_WDT_DIVIDER) + 0x1000;
|
||||
- if (ltq_wdt_timeout > LTQ_MAX_TIMEOUT)
|
||||
- ltq_wdt_timeout = LTQ_MAX_TIMEOUT;
|
||||
+ if (timeout > LTQ_MAX_TIMEOUT)
|
||||
+ timeout = LTQ_MAX_TIMEOUT;
|
||||
|
||||
/* write the first password magic */
|
||||
ltq_w32(LTQ_WDT_PW1, ltq_wdt_membase + LTQ_WDT_CR);
|
||||
/* write the second magic plus the configuration and new timeout */
|
||||
ltq_w32(LTQ_WDT_SR_EN | LTQ_WDT_SR_PWD | LTQ_WDT_SR_CLKDIV |
|
||||
- LTQ_WDT_PW2 | ltq_wdt_timeout, ltq_wdt_membase + LTQ_WDT_CR);
|
||||
+ LTQ_WDT_PW2 | timeout, ltq_wdt_membase + LTQ_WDT_CR);
|
||||
}
|
||||
|
||||
static void
|
||||
--
|
||||
1.7.5.4
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -1,47 +0,0 @@
|
|||
Index: linux-3.0.3/arch/mips/lantiq/prom.c
|
||||
===================================================================
|
||||
--- linux-3.0.3.orig/arch/mips/lantiq/prom.c 2011-10-02 15:49:12.000000000 +0200
|
||||
+++ linux-3.0.3/arch/mips/lantiq/prom.c 2011-10-02 15:50:34.614270672 +0200
|
||||
@@ -43,6 +43,34 @@
|
||||
{
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_IMAGE_CMDLINE_HACK
|
||||
+extern char __image_cmdline[];
|
||||
+
|
||||
+static void __init
|
||||
+prom_init_image_cmdline(void)
|
||||
+{
|
||||
+ char *p = __image_cmdline;
|
||||
+ int replace = 0;
|
||||
+
|
||||
+ if (*p == '-') {
|
||||
+ replace = 1;
|
||||
+ p++;
|
||||
+ }
|
||||
+
|
||||
+ if (*p == '\0')
|
||||
+ return;
|
||||
+
|
||||
+ if (replace) {
|
||||
+ strlcpy(arcs_cmdline, p, sizeof(arcs_cmdline));
|
||||
+ } else {
|
||||
+ strlcat(arcs_cmdline, " ", sizeof(arcs_cmdline));
|
||||
+ strlcat(arcs_cmdline, p, sizeof(arcs_cmdline));
|
||||
+ }
|
||||
+}
|
||||
+#else
|
||||
+static void __init prom_init_image_cmdline(void) { return; }
|
||||
+#endif
|
||||
+
|
||||
static void __init prom_init_cmdline(void)
|
||||
{
|
||||
int argc = fw_arg0;
|
||||
@@ -59,6 +87,7 @@
|
||||
strlcat(arcs_cmdline, " ", sizeof(arcs_cmdline));
|
||||
}
|
||||
}
|
||||
+ prom_init_image_cmdline();
|
||||
}
|
||||
|
||||
void __iomem *ltq_remap_resource(struct resource *res)
|
|
@ -1,14 +0,0 @@
|
|||
--- a/drivers/tty/serial/lantiq.c
|
||||
+++ b/drivers/tty/serial/lantiq.c
|
||||
@@ -478,8 +478,10 @@ lqasc_set_termios(struct uart_port *port
|
||||
spin_unlock_irqrestore(<q_asc_lock, flags);
|
||||
|
||||
/* Don't rewrite B0 */
|
||||
- if (tty_termios_baud_rate(new))
|
||||
+ if (tty_termios_baud_rate(new))
|
||||
tty_termios_encode_baud_rate(new, baud, baud);
|
||||
+
|
||||
+ uart_update_timeout(port, cflag, baud);
|
||||
}
|
||||
|
||||
static const char*
|
|
@ -1,20 +0,0 @@
|
|||
--- a/arch/mips/lantiq/irq.c
|
||||
+++ b/arch/mips/lantiq/irq.c
|
||||
@@ -132,7 +132,7 @@
|
||||
static unsigned int ltq_startup_eiu_irq(struct irq_data *d)
|
||||
{
|
||||
int i;
|
||||
- int irq_nr = d->irq - INT_NUM_IRQ0;
|
||||
+ int irq_nr = d->irq;
|
||||
|
||||
ltq_enable_irq(d);
|
||||
for (i = 0; i < MAX_EIU; i++) {
|
||||
@@ -156,7 +156,7 @@
|
||||
static void ltq_shutdown_eiu_irq(struct irq_data *d)
|
||||
{
|
||||
int i;
|
||||
- int irq_nr = d->irq - INT_NUM_IRQ0;
|
||||
+ int irq_nr = d->irq;
|
||||
|
||||
ltq_disable_irq(d);
|
||||
for (i = 0; i < MAX_EIU; i++) {
|
|
@ -1,18 +0,0 @@
|
|||
--- a/arch/mips/pci/pci-lantiq.c
|
||||
+++ b/arch/mips/pci/pci-lantiq.c
|
||||
@@ -171,8 +171,13 @@
|
||||
u32 temp_buffer;
|
||||
|
||||
/* set clock to 33Mhz */
|
||||
- ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) & ~0xf00000, LTQ_CGU_IFCCR);
|
||||
- ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) | 0x800000, LTQ_CGU_IFCCR);
|
||||
+ if (ltq_is_ar9()) {
|
||||
+ ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) & ~0x1f00000, LTQ_CGU_IFCCR);
|
||||
+ ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) | 0xe00000, LTQ_CGU_IFCCR);
|
||||
+ } else {
|
||||
+ ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) & ~0xf00000, LTQ_CGU_IFCCR);
|
||||
+ ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) | 0x800000, LTQ_CGU_IFCCR);
|
||||
+ }
|
||||
|
||||
/* external or internal clock ? */
|
||||
if (conf->clock) {
|
|
@ -1,22 +0,0 @@
|
|||
Index: linux-3.0.3/arch/mips/lantiq/clk.c
|
||||
===================================================================
|
||||
--- linux-3.0.3.orig/arch/mips/lantiq/clk.c 2011-09-29 20:43:07.000000000 +0200
|
||||
+++ linux-3.0.3/arch/mips/lantiq/clk.c 2011-09-29 20:45:14.785132132 +0200
|
||||
@@ -91,6 +91,17 @@
|
||||
}
|
||||
EXPORT_SYMBOL(clk_put);
|
||||
|
||||
+int clk_enable(struct clk *clk)
|
||||
+{
|
||||
+ /* clocks are always enabled*/
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+void clk_disable(struct clk *clk)
|
||||
+{
|
||||
+ /* clocks are always enabled*/
|
||||
+}
|
||||
+
|
||||
static inline u32 ltq_get_counter_resolution(void)
|
||||
{
|
||||
u32 res;
|
|
@ -1,56 +0,0 @@
|
|||
commit 1c388919d89ca35741e9c4d3255adf87f76f0c06
|
||||
Author: Geert Uytterhoeven <geert@linux-m68k.org>
|
||||
Date: Sat May 7 20:53:16 2011 +0200
|
||||
|
||||
resources: Add lookup_resource()
|
||||
|
||||
Add a function to find an existing resource by a resource start address.
|
||||
This allows to implement simple allocators (with a malloc/free-alike API)
|
||||
on top of the resource system.
|
||||
|
||||
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
|
||||
|
||||
diff --git a/include/linux/ioport.h b/include/linux/ioport.h
|
||||
index e9bb22c..63eb429 100644
|
||||
--- a/include/linux/ioport.h
|
||||
+++ b/include/linux/ioport.h
|
||||
@@ -132,6 +132,7 @@ extern int allocate_resource(struct resource *root, struct resource *new,
|
||||
resource_size_t,
|
||||
resource_size_t),
|
||||
void *alignf_data);
|
||||
+struct resource *lookup_resource(struct resource *root, resource_size_t start);
|
||||
int adjust_resource(struct resource *res, resource_size_t start,
|
||||
resource_size_t size);
|
||||
resource_size_t resource_alignment(struct resource *res);
|
||||
diff --git a/kernel/resource.c b/kernel/resource.c
|
||||
index 3ff4017..3b3cedc 100644
|
||||
--- a/kernel/resource.c
|
||||
+++ b/kernel/resource.c
|
||||
@@ -553,6 +553,27 @@ int allocate_resource(struct resource *root, struct resource *new,
|
||||
|
||||
EXPORT_SYMBOL(allocate_resource);
|
||||
|
||||
+/**
|
||||
+ * lookup_resource - find an existing resource by a resource start address
|
||||
+ * @root: root resource descriptor
|
||||
+ * @start: resource start address
|
||||
+ *
|
||||
+ * Returns a pointer to the resource if found, NULL otherwise
|
||||
+ */
|
||||
+struct resource *lookup_resource(struct resource *root, resource_size_t start)
|
||||
+{
|
||||
+ struct resource *res;
|
||||
+
|
||||
+ read_lock(&resource_lock);
|
||||
+ for (res = root->child; res; res = res->sibling) {
|
||||
+ if (res->start == start)
|
||||
+ break;
|
||||
+ }
|
||||
+ read_unlock(&resource_lock);
|
||||
+
|
||||
+ return res;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Insert a resource into the resource tree. If successful, return NULL,
|
||||
* otherwise return the conflicting resource (compare to __request_resource())
|
|
@ -15,8 +15,6 @@ Cc: linux-mips@linux-mips.org
|
|||
arch/mips/lantiq/early_printk.c | 14 ++++++++------
|
||||
2 files changed, 12 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
|
||||
index 8a3c6be..e6d1ca0 100644
|
||||
--- 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,10 @@
|
||||
|
@ -30,8 +28,6 @@ index 8a3c6be..e6d1ca0 100644
|
|||
/* RCU - reset control unit */
|
||||
#define LTQ_RCU_BASE_ADDR 0x1F203000
|
||||
#define LTQ_RCU_SIZE 0x1000
|
||||
diff --git a/arch/mips/lantiq/early_printk.c b/arch/mips/lantiq/early_printk.c
|
||||
index 972e05f..5089075 100644
|
||||
--- a/arch/mips/lantiq/early_printk.c
|
||||
+++ b/arch/mips/lantiq/early_printk.c
|
||||
@@ -12,11 +12,13 @@
|
||||
|
@ -62,6 +58,3 @@ index 972e05f..5089075 100644
|
|||
+ ltq_w8(c, LTQ_ASC_TBUF);
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
--
|
||||
1.7.5.4
|
||||
|
|
@ -13,11 +13,9 @@ Cc: linux-mips@linux-mips.org
|
|||
arch/mips/lantiq/prom.c | 6 ++++--
|
||||
1 files changed, 4 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/arch/mips/lantiq/prom.c b/arch/mips/lantiq/prom.c
|
||||
index 56ba007..5035c10 100644
|
||||
--- a/arch/mips/lantiq/prom.c
|
||||
+++ b/arch/mips/lantiq/prom.c
|
||||
@@ -45,10 +45,12 @@ static void __init prom_init_cmdline(void)
|
||||
@@ -45,10 +45,12 @@ static void __init prom_init_cmdline(voi
|
||||
char **argv = (char **) KSEG1ADDR(fw_arg1);
|
||||
int i;
|
||||
|
||||
|
@ -32,6 +30,3 @@ index 56ba007..5035c10 100644
|
|||
strlcat(arcs_cmdline, p, sizeof(arcs_cmdline));
|
||||
strlcat(arcs_cmdline, " ", sizeof(arcs_cmdline));
|
||||
}
|
||||
--
|
||||
1.7.5.4
|
||||
|
|
@ -40,8 +40,6 @@ Cc: linux-mips@linux-mips.org
|
|||
delete mode 100644 arch/mips/lantiq/xway/setup-xway.c
|
||||
create mode 100644 arch/mips/lantiq/xway/sysctrl.c
|
||||
|
||||
diff --git a/arch/mips/include/asm/mach-lantiq/lantiq.h b/arch/mips/include/asm/mach-lantiq/lantiq.h
|
||||
index ce2f029..66d7300 100644
|
||||
--- a/arch/mips/include/asm/mach-lantiq/lantiq.h
|
||||
+++ b/arch/mips/include/asm/mach-lantiq/lantiq.h
|
||||
@@ -9,6 +9,7 @@
|
||||
|
@ -68,7 +66,7 @@ index ce2f029..66d7300 100644
|
|||
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_data *data);
|
||||
@@ -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);
|
||||
|
@ -79,8 +77,6 @@ index ce2f029..66d7300 100644
|
|||
|
||||
#define IOPORT_RESOURCE_START 0x10000000
|
||||
#define IOPORT_RESOURCE_END 0xffffffff
|
||||
diff --git a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
|
||||
index e6d1ca0..da8ff95 100644
|
||||
--- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
|
||||
+++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
|
||||
@@ -65,6 +65,8 @@
|
||||
|
@ -123,8 +119,6 @@ index e6d1ca0..da8ff95 100644
|
|||
|
||||
static inline int ltq_is_ar9(void)
|
||||
{
|
||||
diff --git a/arch/mips/lantiq/clk.c b/arch/mips/lantiq/clk.c
|
||||
index 7e9c0ff..4254f08 100644
|
||||
--- a/arch/mips/lantiq/clk.c
|
||||
+++ b/arch/mips/lantiq/clk.c
|
||||
@@ -22,6 +22,7 @@
|
||||
|
@ -158,12 +152,12 @@ index 7e9c0ff..4254f08 100644
|
|||
|
||||
- if (insert_resource(&iomem_resource, <q_cgu_resource) < 0)
|
||||
- panic("Failed to insert cgu memory\n");
|
||||
-
|
||||
+ ltq_soc_init();
|
||||
|
||||
- if (request_mem_region(ltq_cgu_resource.start,
|
||||
- resource_size(<q_cgu_resource), "cgu") < 0)
|
||||
- panic("Failed to request cgu memory\n");
|
||||
+ ltq_soc_init();
|
||||
|
||||
-
|
||||
- ltq_cgu_membase = ioremap_nocache(ltq_cgu_resource.start,
|
||||
- resource_size(<q_cgu_resource));
|
||||
- if (!ltq_cgu_membase) {
|
||||
|
@ -176,8 +170,6 @@ index 7e9c0ff..4254f08 100644
|
|||
+ pr_info("CPU Clock: %ldMHz\n", clk_get_rate(clk) / 1000000);
|
||||
clk_put(clk);
|
||||
}
|
||||
diff --git a/arch/mips/lantiq/devices.c b/arch/mips/lantiq/devices.c
|
||||
index 44a3677..81c7aab 100644
|
||||
--- a/arch/mips/lantiq/devices.c
|
||||
+++ b/arch/mips/lantiq/devices.c
|
||||
@@ -27,12 +27,8 @@
|
||||
|
@ -195,7 +187,7 @@ index 44a3677..81c7aab 100644
|
|||
|
||||
static struct platform_device ltq_nor = {
|
||||
.name = "ltq_nor",
|
||||
@@ -47,12 +43,8 @@ void __init ltq_register_nor(struct physmap_flash_data *data)
|
||||
@@ -47,12 +43,8 @@ void __init ltq_register_nor(struct phys
|
||||
}
|
||||
|
||||
/* watchdog */
|
||||
|
@ -237,8 +229,6 @@ index 44a3677..81c7aab 100644
|
|||
IRQ_RES(tx, LTQ_ASC_TIR(1)),
|
||||
IRQ_RES(rx, LTQ_ASC_RIR(1)),
|
||||
IRQ_RES(err, LTQ_ASC_EIR(1)),
|
||||
diff --git a/arch/mips/lantiq/devices.h b/arch/mips/lantiq/devices.h
|
||||
index 2947bb1..a03c23f 100644
|
||||
--- a/arch/mips/lantiq/devices.h
|
||||
+++ b/arch/mips/lantiq/devices.h
|
||||
@@ -14,6 +14,10 @@
|
||||
|
@ -252,8 +242,6 @@ index 2947bb1..a03c23f 100644
|
|||
|
||||
extern void ltq_register_nor(struct physmap_flash_data *data);
|
||||
extern void ltq_register_wdt(void);
|
||||
diff --git a/arch/mips/lantiq/prom.c b/arch/mips/lantiq/prom.c
|
||||
index 5035c10..fead2cc 100644
|
||||
--- a/arch/mips/lantiq/prom.c
|
||||
+++ b/arch/mips/lantiq/prom.c
|
||||
@@ -16,6 +16,10 @@
|
||||
|
@ -267,7 +255,7 @@ index 5035c10..fead2cc 100644
|
|||
static struct ltq_soc_info soc_info;
|
||||
|
||||
unsigned int ltq_get_cpu_ver(void)
|
||||
@@ -57,16 +61,50 @@ static void __init prom_init_cmdline(void)
|
||||
@@ -57,16 +61,50 @@ static void __init prom_init_cmdline(voi
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -277,7 +265,7 @@ index 5035c10..fead2cc 100644
|
|||
- struct clk *clk;
|
||||
+ __iomem void *ret = NULL;
|
||||
+ struct resource *lookup = lookup_resource(&iomem_resource, res->start);
|
||||
+
|
||||
|
||||
+ if (lookup && strcmp(lookup->name, res->name)) {
|
||||
+ panic("conflicting memory range %s\n", res->name);
|
||||
+ return NULL;
|
||||
|
@ -293,7 +281,7 @@ index 5035c10..fead2cc 100644
|
|||
+ panic("Failed to request %s memory\n", res->name);
|
||||
+ goto err_res;
|
||||
+ }
|
||||
|
||||
+
|
||||
+ ret = ioremap_nocache(res->start, resource_size(res));
|
||||
+ if (!ret)
|
||||
+ goto err_mem;
|
||||
|
@ -324,8 +312,6 @@ index 5035c10..fead2cc 100644
|
|||
soc_info.sys_type[LTQ_SYS_TYPE_LEN - 1] = '\0';
|
||||
pr_info("SoC: %s\n", soc_info.sys_type);
|
||||
prom_init_cmdline();
|
||||
diff --git a/arch/mips/lantiq/prom.h b/arch/mips/lantiq/prom.h
|
||||
index b4229d9..51dba1b 100644
|
||||
--- a/arch/mips/lantiq/prom.h
|
||||
+++ b/arch/mips/lantiq/prom.h
|
||||
@@ -9,17 +9,21 @@
|
||||
|
@ -350,8 +336,6 @@ index b4229d9..51dba1b 100644
|
|||
extern void ltq_soc_setup(void);
|
||||
|
||||
#endif
|
||||
diff --git a/arch/mips/lantiq/xway/Makefile b/arch/mips/lantiq/xway/Makefile
|
||||
index c517f2e..6678402 100644
|
||||
--- a/arch/mips/lantiq/xway/Makefile
|
||||
+++ b/arch/mips/lantiq/xway/Makefile
|
||||
@@ -1,7 +1,7 @@
|
||||
|
@ -365,8 +349,6 @@ index c517f2e..6678402 100644
|
|||
|
||||
obj-$(CONFIG_LANTIQ_MACH_EASY50712) += mach-easy50712.o
|
||||
obj-$(CONFIG_LANTIQ_MACH_EASY50601) += mach-easy50601.o
|
||||
diff --git a/arch/mips/lantiq/xway/devices.c b/arch/mips/lantiq/xway/devices.c
|
||||
index d0e32ab..9bacaa8 100644
|
||||
--- a/arch/mips/lantiq/xway/devices.c
|
||||
+++ b/arch/mips/lantiq/xway/devices.c
|
||||
@@ -31,22 +31,9 @@
|
||||
|
@ -439,8 +421,6 @@ index d0e32ab..9bacaa8 100644
|
|||
|
||||
static struct platform_device ltq_etop = {
|
||||
.name = "ltq_etop",
|
||||
diff --git a/arch/mips/lantiq/xway/dma.c b/arch/mips/lantiq/xway/dma.c
|
||||
index 4278a45..af35e62 100644
|
||||
--- a/arch/mips/lantiq/xway/dma.c
|
||||
+++ b/arch/mips/lantiq/xway/dma.c
|
||||
@@ -23,6 +23,8 @@
|
||||
|
@ -486,12 +466,9 @@ index 4278a45..af35e62 100644
|
|||
if (!ltq_dma_membase)
|
||||
panic("Failed to remap dma memory\n");
|
||||
|
||||
diff --git a/arch/mips/lantiq/xway/ebu.c b/arch/mips/lantiq/xway/ebu.c
|
||||
deleted file mode 100644
|
||||
index 66eb52f..0000000
|
||||
--- a/arch/mips/lantiq/xway/ebu.c
|
||||
+++ /dev/null
|
||||
@@ -1,53 +0,0 @@
|
||||
@@ -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
|
||||
|
@ -504,7 +481,6 @@ index 66eb52f..0000000
|
|||
-
|
||||
-#include <linux/kernel.h>
|
||||
-#include <linux/module.h>
|
||||
-#include <linux/version.h>
|
||||
-#include <linux/ioport.h>
|
||||
-
|
||||
-#include <lantiq_soc.h>
|
||||
|
@ -545,12 +521,9 @@ index 66eb52f..0000000
|
|||
-}
|
||||
-
|
||||
-postcore_initcall(lantiq_ebu_init);
|
||||
diff --git a/arch/mips/lantiq/xway/pmu.c b/arch/mips/lantiq/xway/pmu.c
|
||||
deleted file mode 100644
|
||||
index 9d69f01e..0000000
|
||||
--- a/arch/mips/lantiq/xway/pmu.c
|
||||
+++ /dev/null
|
||||
@@ -1,70 +0,0 @@
|
||||
@@ -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
|
||||
|
@ -561,7 +534,6 @@ index 9d69f01e..0000000
|
|||
-
|
||||
-#include <linux/kernel.h>
|
||||
-#include <linux/module.h>
|
||||
-#include <linux/version.h>
|
||||
-#include <linux/ioport.h>
|
||||
-
|
||||
-#include <lantiq_soc.h>
|
||||
|
@ -621,8 +593,6 @@ index 9d69f01e..0000000
|
|||
-}
|
||||
-
|
||||
-core_initcall(ltq_pmu_init);
|
||||
diff --git a/arch/mips/lantiq/xway/prom-ase.c b/arch/mips/lantiq/xway/prom-ase.c
|
||||
index abe49f4..aaccdcb 100644
|
||||
--- a/arch/mips/lantiq/xway/prom-ase.c
|
||||
+++ b/arch/mips/lantiq/xway/prom-ase.c
|
||||
@@ -13,6 +13,7 @@
|
||||
|
@ -633,7 +603,7 @@ index abe49f4..aaccdcb 100644
|
|||
#include "../prom.h"
|
||||
|
||||
#define SOC_AMAZON_SE "Amazon_SE"
|
||||
@@ -26,6 +27,7 @@ void __init ltq_soc_detect(struct ltq_soc_info *i)
|
||||
@@ -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;
|
||||
|
@ -641,7 +611,7 @@ index abe49f4..aaccdcb 100644
|
|||
switch (i->partnum) {
|
||||
case SOC_ID_AMAZON_SE:
|
||||
i->name = SOC_AMAZON_SE;
|
||||
@@ -37,3 +39,10 @@ void __init ltq_soc_detect(struct ltq_soc_info *i)
|
||||
@@ -37,3 +39,10 @@ void __init ltq_soc_detect(struct ltq_so
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -652,8 +622,6 @@ index abe49f4..aaccdcb 100644
|
|||
+ ltq_register_gpio();
|
||||
+ ltq_register_wdt();
|
||||
+}
|
||||
diff --git a/arch/mips/lantiq/xway/prom-xway.c b/arch/mips/lantiq/xway/prom-xway.c
|
||||
index 1686692a..f3d1228 100644
|
||||
--- a/arch/mips/lantiq/xway/prom-xway.c
|
||||
+++ b/arch/mips/lantiq/xway/prom-xway.c
|
||||
@@ -13,6 +13,7 @@
|
||||
|
@ -664,7 +632,7 @@ index 1686692a..f3d1228 100644
|
|||
#include "../prom.h"
|
||||
|
||||
#define SOC_DANUBE "Danube"
|
||||
@@ -28,6 +29,7 @@ void __init ltq_soc_detect(struct ltq_soc_info *i)
|
||||
@@ -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;
|
||||
|
@ -672,7 +640,7 @@ index 1686692a..f3d1228 100644
|
|||
switch (i->partnum) {
|
||||
case SOC_ID_DANUBE1:
|
||||
case SOC_ID_DANUBE2:
|
||||
@@ -52,3 +54,11 @@ void __init ltq_soc_detect(struct ltq_soc_info *i)
|
||||
@@ -52,3 +54,11 @@ void __init ltq_soc_detect(struct ltq_so
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -684,8 +652,6 @@ index 1686692a..f3d1228 100644
|
|||
+ ltq_register_gpio();
|
||||
+ ltq_register_wdt();
|
||||
+}
|
||||
diff --git a/arch/mips/lantiq/xway/reset.c b/arch/mips/lantiq/xway/reset.c
|
||||
index a1be36d..e701a48 100644
|
||||
--- a/arch/mips/lantiq/xway/reset.c
|
||||
+++ b/arch/mips/lantiq/xway/reset.c
|
||||
@@ -15,6 +15,8 @@
|
||||
|
@ -731,9 +697,6 @@ index a1be36d..e701a48 100644
|
|||
if (!ltq_rcu_membase)
|
||||
panic("Failed to remap rcu memory\n");
|
||||
|
||||
diff --git a/arch/mips/lantiq/xway/setup-ase.c b/arch/mips/lantiq/xway/setup-ase.c
|
||||
deleted file mode 100644
|
||||
index f6f3267..0000000
|
||||
--- a/arch/mips/lantiq/xway/setup-ase.c
|
||||
+++ /dev/null
|
||||
@@ -1,19 +0,0 @@
|
||||
|
@ -756,9 +719,6 @@ index f6f3267..0000000
|
|||
- ltq_register_gpio();
|
||||
- ltq_register_wdt();
|
||||
-}
|
||||
diff --git a/arch/mips/lantiq/xway/setup-xway.c b/arch/mips/lantiq/xway/setup-xway.c
|
||||
deleted file mode 100644
|
||||
index c292f64..0000000
|
||||
--- a/arch/mips/lantiq/xway/setup-xway.c
|
||||
+++ /dev/null
|
||||
@@ -1,20 +0,0 @@
|
||||
|
@ -782,9 +742,6 @@ index c292f64..0000000
|
|||
- ltq_register_gpio();
|
||||
- ltq_register_wdt();
|
||||
-}
|
||||
diff --git a/arch/mips/lantiq/xway/sysctrl.c b/arch/mips/lantiq/xway/sysctrl.c
|
||||
new file mode 100644
|
||||
index 0000000..a29944f
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/lantiq/xway/sysctrl.c
|
||||
@@ -0,0 +1,77 @@
|
||||
|
@ -865,8 +822,6 @@ index 0000000..a29944f
|
|||
+ /* 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);
|
||||
+}
|
||||
diff --git a/drivers/watchdog/lantiq_wdt.c b/drivers/watchdog/lantiq_wdt.c
|
||||
index 102aed0..179bf98 100644
|
||||
--- a/drivers/watchdog/lantiq_wdt.c
|
||||
+++ b/drivers/watchdog/lantiq_wdt.c
|
||||
@@ -16,7 +16,7 @@
|
||||
|
@ -878,6 +833,3 @@ index 102aed0..179bf98 100644
|
|||
|
||||
/* Section 3.4 of the datasheet
|
||||
* The password sequence protects the WDT control register from unintended
|
||||
--
|
||||
1.7.5.4
|
||||
|
|
@ -17,11 +17,9 @@ Cc: linux-mips@linux-mips.org
|
|||
arch/mips/lantiq/irq.c | 24 +++++++++++++-----------
|
||||
1 files changed, 13 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/arch/mips/lantiq/irq.c b/arch/mips/lantiq/irq.c
|
||||
index f9737bb..17c057f 100644
|
||||
--- a/arch/mips/lantiq/irq.c
|
||||
+++ b/arch/mips/lantiq/irq.c
|
||||
@@ -195,7 +195,7 @@ static void ltq_hw_irqdispatch(int module)
|
||||
@@ -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 */
|
||||
|
@ -39,14 +37,15 @@ index f9737bb..17c057f 100644
|
|||
+ if (LTQ_EIU_BASE_ADDR) {
|
||||
+ if (insert_resource(&iomem_resource, <q_eiu_resource) < 0)
|
||||
+ panic("Failed to insert eiu memory\n");
|
||||
|
||||
- if (request_mem_region(ltq_eiu_resource.start,
|
||||
- resource_size(<q_eiu_resource), "eiu") < 0)
|
||||
- panic("Failed to request eiu memory\n");
|
||||
+
|
||||
+ if (request_mem_region(ltq_eiu_resource.start,
|
||||
+ resource_size(<q_eiu_resource), "eiu") < 0)
|
||||
+ panic("Failed to request eiu memory\n");
|
||||
|
||||
- if (request_mem_region(ltq_eiu_resource.start,
|
||||
- resource_size(<q_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(<q_eiu_resource));
|
||||
|
@ -69,6 +68,3 @@ index f9737bb..17c057f 100644
|
|||
irq_set_chip_and_handler(i, <q_eiu_type,
|
||||
handle_level_irq);
|
||||
/* EIU3-5 only exist on ar9 and vr9 */
|
||||
--
|
||||
1.7.5.4
|
||||
|
|
@ -36,9 +36,6 @@ Cc: linux-mips@linux-mips.org
|
|||
create mode 100644 arch/mips/lantiq/falcon/reset.c
|
||||
create mode 100644 arch/mips/lantiq/falcon/sysctrl.c
|
||||
|
||||
diff --git a/arch/mips/include/asm/mach-lantiq/falcon/falcon_irq.h b/arch/mips/include/asm/mach-lantiq/falcon/falcon_irq.h
|
||||
new file mode 100644
|
||||
index 0000000..4dc6466
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/include/asm/mach-lantiq/falcon/falcon_irq.h
|
||||
@@ -0,0 +1,268 @@
|
||||
|
@ -310,9 +307,6 @@ index 0000000..4dc6466
|
|||
+#define FALCON_IRQ_VPE0_PMCIR (INT_NUM_IM4_IRL0 + 31)
|
||||
+
|
||||
+#endif /* _FALCON_IRQ__ */
|
||||
diff --git a/arch/mips/include/asm/mach-lantiq/falcon/irq.h b/arch/mips/include/asm/mach-lantiq/falcon/irq.h
|
||||
new file mode 100644
|
||||
index 0000000..2caccd9
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/include/asm/mach-lantiq/falcon/irq.h
|
||||
@@ -0,0 +1,18 @@
|
||||
|
@ -334,9 +328,6 @@ index 0000000..2caccd9
|
|||
+#include_next <irq.h>
|
||||
+
|
||||
+#endif
|
||||
diff --git a/arch/mips/include/asm/mach-lantiq/falcon/lantiq_soc.h b/arch/mips/include/asm/mach-lantiq/falcon/lantiq_soc.h
|
||||
new file mode 100644
|
||||
index 0000000..c092531
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/include/asm/mach-lantiq/falcon/lantiq_soc.h
|
||||
@@ -0,0 +1,140 @@
|
||||
|
@ -480,11 +471,9 @@ index 0000000..c092531
|
|||
+
|
||||
+#endif /* CONFIG_SOC_FALCON */
|
||||
+#endif /* _LTQ_XWAY_H__ */
|
||||
diff --git a/arch/mips/include/asm/mach-lantiq/lantiq.h b/arch/mips/include/asm/mach-lantiq/lantiq.h
|
||||
index 66d7300..188de0f 100644
|
||||
--- a/arch/mips/include/asm/mach-lantiq/lantiq.h
|
||||
+++ b/arch/mips/include/asm/mach-lantiq/lantiq.h
|
||||
@@ -25,6 +25,7 @@ extern unsigned int ltq_get_soc_type(void);
|
||||
@@ -25,6 +25,7 @@ extern unsigned int ltq_get_soc_type(voi
|
||||
/* clock speeds */
|
||||
#define CLOCK_60M 60000000
|
||||
#define CLOCK_83M 83333333
|
||||
|
@ -492,8 +481,6 @@ index 66d7300..188de0f 100644
|
|||
#define CLOCK_111M 111111111
|
||||
#define CLOCK_133M 133333333
|
||||
#define CLOCK_167M 166666667
|
||||
diff --git a/arch/mips/lantiq/Kconfig b/arch/mips/lantiq/Kconfig
|
||||
index 3fccf21..cb6b39f 100644
|
||||
--- a/arch/mips/lantiq/Kconfig
|
||||
+++ b/arch/mips/lantiq/Kconfig
|
||||
@@ -16,8 +16,12 @@ config SOC_XWAY
|
||||
|
@ -509,17 +496,13 @@ index 3fccf21..cb6b39f 100644
|
|||
+source "arch/mips/lantiq/falcon/Kconfig"
|
||||
|
||||
endif
|
||||
diff --git a/arch/mips/lantiq/Makefile b/arch/mips/lantiq/Makefile
|
||||
index e5dae0e..7e9c69e 100644
|
||||
--- a/arch/mips/lantiq/Makefile
|
||||
+++ b/arch/mips/lantiq/Makefile
|
||||
@@ -9,3 +9,4 @@ obj-y := irq.o setup.o clk.o prom.o devices.o
|
||||
@@ -9,3 +9,4 @@ obj-y := irq.o setup.o clk.o prom.o devi
|
||||
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
|
||||
|
||||
obj-$(CONFIG_SOC_TYPE_XWAY) += xway/
|
||||
+obj-$(CONFIG_SOC_FALCON) += falcon/
|
||||
diff --git a/arch/mips/lantiq/Platform b/arch/mips/lantiq/Platform
|
||||
index f3dff05..b3ec498 100644
|
||||
--- a/arch/mips/lantiq/Platform
|
||||
+++ b/arch/mips/lantiq/Platform
|
||||
@@ -6,3 +6,4 @@ platform-$(CONFIG_LANTIQ) += lantiq/
|
||||
|
@ -527,16 +510,10 @@ index f3dff05..b3ec498 100644
|
|||
load-$(CONFIG_LANTIQ) = 0xffffffff80002000
|
||||
cflags-$(CONFIG_SOC_TYPE_XWAY) += -I$(srctree)/arch/mips/include/asm/mach-lantiq/xway
|
||||
+cflags-$(CONFIG_SOC_FALCON) += -I$(srctree)/arch/mips/include/asm/mach-lantiq/falcon
|
||||
diff --git a/arch/mips/lantiq/falcon/Makefile b/arch/mips/lantiq/falcon/Makefile
|
||||
new file mode 100644
|
||||
index 0000000..e9c7455
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/lantiq/falcon/Makefile
|
||||
@@ -0,0 +1 @@
|
||||
+obj-y := clk.o prom.o reset.o sysctrl.o devices.o
|
||||
diff --git a/arch/mips/lantiq/falcon/clk.c b/arch/mips/lantiq/falcon/clk.c
|
||||
new file mode 100644
|
||||
index 0000000..1a550ea
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/lantiq/falcon/clk.c
|
||||
@@ -0,0 +1,44 @@
|
||||
|
@ -584,9 +561,6 @@ index 0000000..1a550ea
|
|||
+ return CLOCK_100M;
|
||||
+}
|
||||
+EXPORT_SYMBOL(ltq_get_fpi_hz);
|
||||
diff --git a/arch/mips/lantiq/falcon/devices.c b/arch/mips/lantiq/falcon/devices.c
|
||||
new file mode 100644
|
||||
index 0000000..c4606f2
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/lantiq/falcon/devices.c
|
||||
@@ -0,0 +1,87 @@
|
||||
|
@ -677,9 +651,6 @@ index 0000000..c4606f2
|
|||
+{
|
||||
+ platform_device_register(<q_flash_nand);
|
||||
+}
|
||||
diff --git a/arch/mips/lantiq/falcon/devices.h b/arch/mips/lantiq/falcon/devices.h
|
||||
new file mode 100644
|
||||
index 0000000..e802a7c
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/lantiq/falcon/devices.h
|
||||
@@ -0,0 +1,18 @@
|
||||
|
@ -701,9 +672,6 @@ index 0000000..e802a7c
|
|||
+extern void falcon_register_nand(void);
|
||||
+
|
||||
+#endif
|
||||
diff --git a/arch/mips/lantiq/falcon/prom.c b/arch/mips/lantiq/falcon/prom.c
|
||||
new file mode 100644
|
||||
index 0000000..89367c4
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/lantiq/falcon/prom.c
|
||||
@@ -0,0 +1,72 @@
|
||||
|
@ -779,9 +747,6 @@ index 0000000..89367c4
|
|||
+ break;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/arch/mips/lantiq/falcon/reset.c b/arch/mips/lantiq/falcon/reset.c
|
||||
new file mode 100644
|
||||
index 0000000..d3289ca
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/lantiq/falcon/reset.c
|
||||
@@ -0,0 +1,87 @@
|
||||
|
@ -872,9 +837,6 @@ index 0000000..d3289ca
|
|||
+}
|
||||
+
|
||||
+arch_initcall(mips_reboot_setup);
|
||||
diff --git a/arch/mips/lantiq/falcon/sysctrl.c b/arch/mips/lantiq/falcon/sysctrl.c
|
||||
new file mode 100644
|
||||
index 0000000..d20b46b
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/lantiq/falcon/sysctrl.c
|
||||
@@ -0,0 +1,181 @@
|
||||
|
@ -1059,6 +1021,3 @@ index 0000000..d20b46b
|
|||
+
|
||||
+ ltq_gpe_enable();
|
||||
+}
|
||||
--
|
||||
1.7.5.4
|
||||
|
|
@ -17,15 +17,11 @@ Cc: linux-mips@linux-mips.org
|
|||
4 files changed, 442 insertions(+), 1 deletions(-)
|
||||
create mode 100644 arch/mips/lantiq/falcon/gpio.c
|
||||
|
||||
diff --git a/arch/mips/lantiq/falcon/Makefile b/arch/mips/lantiq/falcon/Makefile
|
||||
index e9c7455..de72209 100644
|
||||
--- 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
|
||||
diff --git a/arch/mips/lantiq/falcon/devices.c b/arch/mips/lantiq/falcon/devices.c
|
||||
index c4606f2..4f47b44 100644
|
||||
--- a/arch/mips/lantiq/falcon/devices.c
|
||||
+++ b/arch/mips/lantiq/falcon/devices.c
|
||||
@@ -9,6 +9,7 @@
|
||||
|
@ -80,8 +76,6 @@ index c4606f2..4f47b44 100644
|
|||
+ ltq_sysctl_activate(SYSCTL_SYS1,
|
||||
+ ACTS_PADCTRL3 | ACTS_PADCTRL4 | ACTS_P3 | ACTS_P4);
|
||||
+}
|
||||
diff --git a/arch/mips/lantiq/falcon/devices.h b/arch/mips/lantiq/falcon/devices.h
|
||||
index e802a7c..18be8b6 100644
|
||||
--- a/arch/mips/lantiq/falcon/devices.h
|
||||
+++ b/arch/mips/lantiq/falcon/devices.h
|
||||
@@ -14,5 +14,7 @@
|
||||
|
@ -92,9 +86,6 @@ index e802a7c..18be8b6 100644
|
|||
+extern void falcon_register_gpio_extra(void);
|
||||
|
||||
#endif
|
||||
diff --git a/arch/mips/lantiq/falcon/gpio.c b/arch/mips/lantiq/falcon/gpio.c
|
||||
new file mode 100644
|
||||
index 0000000..b87582d
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/lantiq/falcon/gpio.c
|
||||
@@ -0,0 +1,398 @@
|
||||
|
@ -496,6 +487,3 @@ index 0000000..b87582d
|
|||
+}
|
||||
+
|
||||
+postcore_initcall(falcon_gpio_init);
|
||||
--
|
||||
1.7.5.4
|
||||
|
|
@ -18,9 +18,6 @@ Cc: linux-mips@linux-mips.org
|
|||
create mode 100644 arch/mips/lantiq/falcon/Kconfig
|
||||
create mode 100644 arch/mips/lantiq/falcon/mach-easy98000.c
|
||||
|
||||
diff --git a/arch/mips/lantiq/falcon/Kconfig b/arch/mips/lantiq/falcon/Kconfig
|
||||
new file mode 100644
|
||||
index 0000000..03e999d
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/lantiq/falcon/Kconfig
|
||||
@@ -0,0 +1,11 @@
|
||||
|
@ -35,16 +32,11 @@ index 0000000..03e999d
|
|||
+endmenu
|
||||
+
|
||||
+endif
|
||||
diff --git a/arch/mips/lantiq/falcon/Makefile b/arch/mips/lantiq/falcon/Makefile
|
||||
index de72209..56b22eb 100644
|
||||
--- 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
|
||||
diff --git a/arch/mips/lantiq/falcon/mach-easy98000.c b/arch/mips/lantiq/falcon/mach-easy98000.c
|
||||
new file mode 100644
|
||||
index 0000000..361b8f0
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/lantiq/falcon/mach-easy98000.c
|
||||
@@ -0,0 +1,110 @@
|
||||
|
@ -158,8 +150,6 @@ index 0000000..361b8f0
|
|||
+ "EASY98000NAND",
|
||||
+ "EASY98000 Eval Board (NAND Flash)",
|
||||
+ easy98000nand_init);
|
||||
diff --git a/arch/mips/lantiq/machtypes.h b/arch/mips/lantiq/machtypes.h
|
||||
index 7e01b8c..dfc6af7 100644
|
||||
--- a/arch/mips/lantiq/machtypes.h
|
||||
+++ b/arch/mips/lantiq/machtypes.h
|
||||
@@ -15,6 +15,11 @@ enum lantiq_mach_type {
|
||||
|
@ -174,6 +164,3 @@ index 7e01b8c..dfc6af7 100644
|
|||
};
|
||||
|
||||
#endif
|
||||
--
|
||||
1.7.5.4
|
||||
|
|
@ -14,12 +14,10 @@ Cc: linux-mips@linux-mips.org
|
|||
arch/mips/oprofile/op_model_mipsxx.c | 12 ++++++++++++
|
||||
1 files changed, 12 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/arch/mips/oprofile/op_model_mipsxx.c b/arch/mips/oprofile/op_model_mipsxx.c
|
||||
index 54759f1..86cf234 100644
|
||||
--- a/arch/mips/oprofile/op_model_mipsxx.c
|
||||
+++ b/arch/mips/oprofile/op_model_mipsxx.c
|
||||
@@ -298,6 +298,11 @@ static void reset_counters(void *arg)
|
||||
}
|
||||
@@ -303,6 +303,11 @@ static irqreturn_t mipsxx_perfcount_int(
|
||||
return mipsxx_perfcount_handler();
|
||||
}
|
||||
|
||||
+static irqreturn_t mipsxx_perfcount_int(int irq, void *dev_id)
|
||||
|
@ -30,9 +28,9 @@ index 54759f1..86cf234 100644
|
|||
static int __init mipsxx_init(void)
|
||||
{
|
||||
int counters;
|
||||
@@ -374,6 +379,10 @@ static int __init mipsxx_init(void)
|
||||
save_perf_irq = perf_irq;
|
||||
perf_irq = mipsxx_perfcount_handler;
|
||||
@@ -383,6 +388,10 @@ static int __init mipsxx_init(void)
|
||||
return request_irq(cp0_perfcount_irq, mipsxx_perfcount_int,
|
||||
IRQF_SHARED, "Perfcounter", save_perf_irq);
|
||||
|
||||
+ if (cp0_perfcount_irq >= 0)
|
||||
+ return request_irq(cp0_perfcount_irq, mipsxx_perfcount_int,
|
||||
|
@ -41,16 +39,13 @@ index 54759f1..86cf234 100644
|
|||
return 0;
|
||||
}
|
||||
|
||||
@@ -381,6 +390,9 @@ static void mipsxx_exit(void)
|
||||
{
|
||||
int counters = op_model_mipsxx_ops.num_counters;
|
||||
@@ -392,6 +401,9 @@ static void mipsxx_exit(void)
|
||||
|
||||
if (cp0_perfcount_irq >= 0)
|
||||
free_irq(cp0_perfcount_irq, save_perf_irq);
|
||||
+
|
||||
+ if (cp0_perfcount_irq >= 0)
|
||||
+ free_irq(cp0_perfcount_irq, save_perf_irq);
|
||||
+
|
||||
|
||||
counters = counters_per_cpu_to_total(counters);
|
||||
on_each_cpu(reset_counters, (void *)(long)counters, 1);
|
||||
|
||||
--
|
||||
1.7.5.4
|
||||
|
|
@ -12,8 +12,6 @@ Cc: linux-mips@linux-mips.org
|
|||
arch/mips/lantiq/irq.c | 5 +++++
|
||||
2 files changed, 6 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
|
||||
index b122adc..0cf5bbd 100644
|
||||
--- a/arch/mips/Kconfig
|
||||
+++ b/arch/mips/Kconfig
|
||||
@@ -230,6 +230,7 @@ config LANTIQ
|
||||
|
@ -24,8 +22,6 @@ index b122adc..0cf5bbd 100644
|
|||
select MIPS_MACHINE
|
||||
|
||||
config LASAT
|
||||
diff --git a/arch/mips/lantiq/irq.c b/arch/mips/lantiq/irq.c
|
||||
index 17c057f..0b2ed87 100644
|
||||
--- a/arch/mips/lantiq/irq.c
|
||||
+++ b/arch/mips/lantiq/irq.c
|
||||
@@ -40,6 +40,9 @@
|
||||
|
@ -47,6 +43,3 @@ index 17c057f..0b2ed87 100644
|
|||
}
|
||||
|
||||
unsigned int __cpuinit get_c0_compare_int(void)
|
||||
--
|
||||
1.7.5.4
|
||||
|
|
@ -12,8 +12,6 @@ Subject: [PATCH 11/24] MIPS: lantiq: adds falcon I2C
|
|||
5 files changed, 842 insertions(+), 0 deletions(-)
|
||||
create mode 100644 drivers/i2c/busses/i2c-falcon.c
|
||||
|
||||
diff --git a/arch/mips/lantiq/falcon/devices.c b/arch/mips/lantiq/falcon/devices.c
|
||||
index 4f47b44..a998b6b 100644
|
||||
--- a/arch/mips/lantiq/falcon/devices.c
|
||||
+++ b/arch/mips/lantiq/falcon/devices.c
|
||||
@@ -126,3 +126,24 @@ falcon_register_gpio_extra(void)
|
||||
|
@ -41,8 +39,6 @@ index 4f47b44..a998b6b 100644
|
|||
+{
|
||||
+ platform_device_register_simple("ltq_falcon_deu", 0, NULL, 0);
|
||||
+}
|
||||
diff --git a/arch/mips/lantiq/falcon/devices.h b/arch/mips/lantiq/falcon/devices.h
|
||||
index 18be8b6..2fdcb08 100644
|
||||
--- a/arch/mips/lantiq/falcon/devices.h
|
||||
+++ b/arch/mips/lantiq/falcon/devices.h
|
||||
@@ -16,5 +16,6 @@
|
||||
|
@ -52,8 +48,6 @@ index 18be8b6..2fdcb08 100644
|
|||
+extern void falcon_register_i2c(void);
|
||||
|
||||
#endif
|
||||
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
|
||||
index 646068e..e6c3ab6 100644
|
||||
--- a/drivers/i2c/busses/Kconfig
|
||||
+++ b/drivers/i2c/busses/Kconfig
|
||||
@@ -284,6 +284,10 @@ config I2C_POWERMAC
|
||||
|
@ -67,8 +61,6 @@ index 646068e..e6c3ab6 100644
|
|||
config I2C_AT91
|
||||
tristate "Atmel AT91 I2C Two-Wire interface (TWI)"
|
||||
depends on ARCH_AT91 && EXPERIMENTAL && BROKEN
|
||||
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
|
||||
index e6cf294..83e9250 100644
|
||||
--- a/drivers/i2c/busses/Makefile
|
||||
+++ b/drivers/i2c/busses/Makefile
|
||||
@@ -82,5 +82,6 @@ obj-$(CONFIG_I2C_SIBYTE) += i2c-sibyte.o
|
||||
|
@ -78,9 +70,6 @@ index e6cf294..83e9250 100644
|
|||
+obj-$(CONFIG_I2C_FALCON) += i2c-falcon.o
|
||||
|
||||
ccflags-$(CONFIG_I2C_DEBUG_BUS) := -DDEBUG
|
||||
diff --git a/drivers/i2c/busses/i2c-falcon.c b/drivers/i2c/busses/i2c-falcon.c
|
||||
new file mode 100644
|
||||
index 0000000..7bb1253
|
||||
--- /dev/null
|
||||
+++ b/drivers/i2c/busses/i2c-falcon.c
|
||||
@@ -0,0 +1,815 @@
|
||||
|
@ -899,6 +888,3 @@ index 0000000..7bb1253
|
|||
+MODULE_ALIAS("platform:" DRV_NAME);
|
||||
+MODULE_LICENSE("GPL");
|
||||
+MODULE_VERSION(DRV_VERSION);
|
||||
--
|
||||
1.7.5.4
|
||||
|
|
@ -18,11 +18,9 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
|
|||
6 files changed, 523 insertions(+), 2 deletions(-)
|
||||
create mode 100644 drivers/spi/spi-falcon.c
|
||||
|
||||
Index: linux-3.0.3/arch/mips/lantiq/falcon/devices.c
|
||||
===================================================================
|
||||
--- linux-3.0.3.orig/arch/mips/lantiq/falcon/devices.c 2011-10-05 12:30:34.584838403 +0200
|
||||
+++ linux-3.0.3/arch/mips/lantiq/falcon/devices.c 2011-10-05 12:42:58.696870214 +0200
|
||||
@@ -129,7 +129,7 @@
|
||||
--- a/arch/mips/lantiq/falcon/devices.c
|
||||
+++ b/arch/mips/lantiq/falcon/devices.c
|
||||
@@ -129,7 +129,7 @@ falcon_register_gpio_extra(void)
|
||||
|
||||
/* i2c */
|
||||
static struct resource falcon_i2c_resources[] = {
|
||||
|
@ -31,7 +29,7 @@ Index: linux-3.0.3/arch/mips/lantiq/falcon/devices.c
|
|||
IRQ_RES("i2c_lb", FALCON_IRQ_I2C_LBREQ),
|
||||
IRQ_RES("i2c_b", FALCON_IRQ_I2C_BREQ),
|
||||
IRQ_RES("i2c_err", FALCON_IRQ_I2C_I2C_ERR),
|
||||
@@ -140,10 +140,18 @@
|
||||
@@ -140,10 +140,18 @@ void __init falcon_register_i2c(void)
|
||||
{
|
||||
platform_device_register_simple("i2c-falcon", 0,
|
||||
falcon_i2c_resources, ARRAY_SIZE(falcon_i2c_resources));
|
||||
|
@ -53,10 +51,8 @@ Index: linux-3.0.3/arch/mips/lantiq/falcon/devices.c
|
|||
+ spi_register_board_info(data, 1);
|
||||
+ platform_device_register(<q_spi);
|
||||
}
|
||||
Index: linux-3.0.3/arch/mips/lantiq/falcon/devices.h
|
||||
===================================================================
|
||||
--- linux-3.0.3.orig/arch/mips/lantiq/falcon/devices.h 2011-10-05 12:30:34.584838403 +0200
|
||||
+++ linux-3.0.3/arch/mips/lantiq/falcon/devices.h 2011-10-05 12:30:34.600838405 +0200
|
||||
--- a/arch/mips/lantiq/falcon/devices.h
|
||||
+++ b/arch/mips/lantiq/falcon/devices.h
|
||||
@@ -11,11 +11,15 @@
|
||||
#ifndef _FALCON_DEVICES_H__
|
||||
#define _FALCON_DEVICES_H__
|
||||
|
@ -73,11 +69,9 @@ Index: linux-3.0.3/arch/mips/lantiq/falcon/devices.h
|
|||
+extern void falcon_register_spi_flash(struct spi_board_info *data);
|
||||
|
||||
#endif
|
||||
Index: linux-3.0.3/arch/mips/lantiq/falcon/mach-easy98000.c
|
||||
===================================================================
|
||||
--- linux-3.0.3.orig/arch/mips/lantiq/falcon/mach-easy98000.c 2011-10-05 12:30:34.552838402 +0200
|
||||
+++ linux-3.0.3/arch/mips/lantiq/falcon/mach-easy98000.c 2011-10-05 12:30:34.600838405 +0200
|
||||
@@ -40,6 +40,21 @@
|
||||
--- 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,
|
||||
};
|
||||
|
||||
|
@ -99,7 +93,7 @@ Index: linux-3.0.3/arch/mips/lantiq/falcon/mach-easy98000.c
|
|||
/* 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 @@
|
||||
@@ -93,6 +108,13 @@ easy98000_init(void)
|
||||
}
|
||||
|
||||
static void __init
|
||||
|
@ -113,7 +107,7 @@ Index: linux-3.0.3/arch/mips/lantiq/falcon/mach-easy98000.c
|
|||
easy98000nand_init(void)
|
||||
{
|
||||
easy98000_init_common();
|
||||
@@ -104,6 +126,11 @@
|
||||
@@ -104,6 +126,11 @@ MIPS_MACHINE(LANTIQ_MACH_EASY98000,
|
||||
"EASY98000 Eval Board",
|
||||
easy98000_init);
|
||||
|
||||
|
@ -125,11 +119,9 @@ Index: linux-3.0.3/arch/mips/lantiq/falcon/mach-easy98000.c
|
|||
MIPS_MACHINE(LANTIQ_MACH_EASY98000NAND,
|
||||
"EASY98000NAND",
|
||||
"EASY98000 Eval Board (NAND Flash)",
|
||||
Index: linux-3.0.3/drivers/spi/Kconfig
|
||||
===================================================================
|
||||
--- linux-3.0.3.orig/drivers/spi/Kconfig 2011-10-05 12:30:33.608838362 +0200
|
||||
+++ linux-3.0.3/drivers/spi/Kconfig 2011-10-05 12:41:56.864867570 +0200
|
||||
@@ -219,6 +219,10 @@
|
||||
--- 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.
|
||||
|
||||
|
@ -140,22 +132,18 @@ Index: linux-3.0.3/drivers/spi/Kconfig
|
|||
config SPI_MPC52xx_PSC
|
||||
tristate "Freescale MPC52xx PSC SPI controller"
|
||||
depends on PPC_MPC52xx && EXPERIMENTAL
|
||||
Index: linux-3.0.3/drivers/spi/Makefile
|
||||
===================================================================
|
||||
--- linux-3.0.3.orig/drivers/spi/Makefile 2011-10-05 12:30:33.608838362 +0200
|
||||
+++ linux-3.0.3/drivers/spi/Makefile 2011-10-05 12:41:56.884867571 +0200
|
||||
@@ -56,6 +56,7 @@
|
||||
obj-$(CONFIG_SPI_SH_MSIOF) += spi_sh_msiof.o
|
||||
obj-$(CONFIG_SPI_STMP3XXX) += spi_stmp.o
|
||||
obj-$(CONFIG_SPI_NUC900) += spi_nuc900.o
|
||||
--- 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
|
||||
|
||||
# special build for s3c24xx spi driver with fiq support
|
||||
spi_s3c24xx_hw-y := spi_s3c24xx.o
|
||||
Index: linux-3.0.3/drivers/spi/spi-falcon.c
|
||||
===================================================================
|
||||
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
||||
+++ linux-3.0.3/drivers/spi/spi-falcon.c 2011-10-05 12:30:34.600838405 +0200
|
||||
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,477 @@
|
||||
+/*
|
||||
+ * This program is free software; you can redistribute it and/or modify it
|
||||
|
@ -634,10 +622,8 @@ Index: linux-3.0.3/drivers/spi/spi-falcon.c
|
|||
+
|
||||
+MODULE_LICENSE("GPL");
|
||||
+MODULE_DESCRIPTION("Lantiq Falcon SPI controller driver");
|
||||
Index: linux-3.0.3/arch/mips/include/asm/mach-lantiq/falcon/lantiq_soc.h
|
||||
===================================================================
|
||||
--- linux-3.0.3.orig/arch/mips/include/asm/mach-lantiq/falcon/lantiq_soc.h 2011-10-05 12:38:16.176858136 +0200
|
||||
+++ linux-3.0.3/arch/mips/include/asm/mach-lantiq/falcon/lantiq_soc.h 2011-10-05 12:39:54.936862358 +0200
|
||||
--- a/arch/mips/include/asm/mach-lantiq/falcon/lantiq_soc.h
|
||||
+++ b/arch/mips/include/asm/mach-lantiq/falcon/lantiq_soc.h
|
||||
@@ -48,6 +48,10 @@
|
||||
|
||||
#define LTQ_EBU_MODCON 0x000C
|
|
@ -13,11 +13,9 @@ Subject: [PATCH 14/24] MIPS: lantiq: adds xway spi
|
|||
6 files changed, 1083 insertions(+), 1 deletions(-)
|
||||
create mode 100644 drivers/spi/spi-xway.c
|
||||
|
||||
Index: linux-3.0.3/arch/mips/include/asm/mach-lantiq/lantiq_platform.h
|
||||
===================================================================
|
||||
--- linux-3.0.3.orig/arch/mips/include/asm/mach-lantiq/lantiq_platform.h 2011-08-17 19:57:16.000000000 +0200
|
||||
+++ linux-3.0.3/arch/mips/include/asm/mach-lantiq/lantiq_platform.h 2011-10-04 20:05:23.962311503 +0200
|
||||
@@ -50,4 +50,13 @@
|
||||
--- a/arch/mips/include/asm/mach-lantiq/lantiq_platform.h
|
||||
+++ b/arch/mips/include/asm/mach-lantiq/lantiq_platform.h
|
||||
@@ -50,4 +50,13 @@ struct ltq_eth_data {
|
||||
int mii_mode;
|
||||
};
|
||||
|
||||
|
@ -31,10 +29,8 @@ Index: linux-3.0.3/arch/mips/include/asm/mach-lantiq/lantiq_platform.h
|
|||
+};
|
||||
+
|
||||
#endif
|
||||
Index: linux-3.0.3/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h
|
||||
===================================================================
|
||||
--- linux-3.0.3.orig/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h 2011-08-17 19:57:16.000000000 +0200
|
||||
+++ linux-3.0.3/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h 2011-10-04 20:05:23.962311503 +0200
|
||||
--- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h
|
||||
+++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h
|
||||
@@ -27,6 +27,8 @@
|
||||
|
||||
#define LTQ_SSC_TIR (INT_NUM_IM0_IRL0 + 15)
|
||||
|
@ -44,10 +40,8 @@ Index: linux-3.0.3/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h
|
|||
#define LTQ_SSC_EIR (INT_NUM_IM0_IRL0 + 16)
|
||||
|
||||
#define LTQ_MEI_DYING_GASP_INT (INT_NUM_IM1_IRL0 + 21)
|
||||
Index: linux-3.0.3/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
|
||||
===================================================================
|
||||
--- linux-3.0.3.orig/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h 2011-10-04 20:03:54.934307699 +0200
|
||||
+++ linux-3.0.3/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h 2011-10-04 20:05:23.966311504 +0200
|
||||
--- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
|
||||
+++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
|
||||
@@ -81,6 +81,7 @@
|
||||
|
||||
#define PMU_DMA 0x0020
|
||||
|
@ -56,11 +50,9 @@ Index: linux-3.0.3/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
|
|||
#define PMU_LED 0x0800
|
||||
#define PMU_GPT 0x1000
|
||||
#define PMU_PPE 0x2000
|
||||
Index: linux-3.0.3/drivers/spi/Kconfig
|
||||
===================================================================
|
||||
--- linux-3.0.3.orig/drivers/spi/Kconfig 2011-10-04 20:05:07.030310779 +0200
|
||||
+++ linux-3.0.3/drivers/spi/Kconfig 2011-10-04 20:05:23.966311504 +0200
|
||||
@@ -433,6 +433,14 @@
|
||||
--- a/drivers/spi/Kconfig
|
||||
+++ b/drivers/spi/Kconfig
|
||||
@@ -393,6 +393,14 @@ config SPI_NUC900
|
||||
help
|
||||
SPI driver for Nuvoton NUC900 series ARM SoCs
|
||||
|
||||
|
@ -75,22 +67,16 @@ Index: linux-3.0.3/drivers/spi/Kconfig
|
|||
#
|
||||
# Add new SPI master controllers in alphabetical order above this line
|
||||
#
|
||||
Index: linux-3.0.3/drivers/spi/Makefile
|
||||
===================================================================
|
||||
--- linux-3.0.3.orig/drivers/spi/Makefile 2011-10-04 20:05:20.000000000 +0200
|
||||
+++ linux-3.0.3/drivers/spi/Makefile 2011-10-04 20:05:35.802312011 +0200
|
||||
@@ -57,6 +57,7 @@
|
||||
obj-$(CONFIG_SPI_STMP3XXX) += spi_stmp.o
|
||||
obj-$(CONFIG_SPI_NUC900) += spi_nuc900.o
|
||||
obj-$(CONFIG_SPI_FALCON) += spi-falcon.o
|
||||
--- a/drivers/spi/Makefile
|
||||
+++ b/drivers/spi/Makefile
|
||||
@@ -60,4 +60,5 @@ obj-$(CONFIG_SPI_TLE62X0) += spi-tle62x
|
||||
obj-$(CONFIG_SPI_TOPCLIFF_PCH) += spi-topcliff-pch.o
|
||||
obj-$(CONFIG_SPI_TXX9) += spi-txx9.o
|
||||
obj-$(CONFIG_SPI_XILINX) += spi-xilinx.o
|
||||
+obj-$(CONFIG_SPI_XWAY) += spi-xway.o
|
||||
|
||||
# special build for s3c24xx spi driver with fiq support
|
||||
spi_s3c24xx_hw-y := spi_s3c24xx.o
|
||||
Index: linux-3.0.3/drivers/spi/spi-xway.c
|
||||
===================================================================
|
||||
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
||||
+++ linux-3.0.3/drivers/spi/spi-xway.c 2011-10-04 20:05:23.966311504 +0200
|
||||
--- /dev/null
|
||||
+++ b/drivers/spi/spi-xway.c
|
||||
@@ -0,0 +1,1062 @@
|
||||
+/*
|
||||
+ * Lantiq SoC SPI controller
|
|
@ -17,10 +17,8 @@ Signed-off-by: Thomas Langer <thomas.langer@lantiq.com>
|
|||
drivers/net/lantiq_etop.c | 172 ++++++++++++++++++--
|
||||
5 files changed, 180 insertions(+), 40 deletions(-)
|
||||
|
||||
Index: linux-3.0.3/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h
|
||||
===================================================================
|
||||
--- linux-3.0.3.orig/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h 2011-10-04 20:05:23.000000000 +0200
|
||||
+++ linux-3.0.3/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h 2011-10-04 20:05:44.146312365 +0200
|
||||
--- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h
|
||||
+++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h
|
||||
@@ -40,26 +40,8 @@
|
||||
|
||||
#define MIPS_CPU_TIMER_IRQ 7
|
||||
|
@ -50,10 +48,8 @@ Index: linux-3.0.3/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h
|
|||
|
||||
#define LTQ_PPE_MBOX_INT (INT_NUM_IM2_IRL0 + 24)
|
||||
|
||||
Index: linux-3.0.3/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
|
||||
===================================================================
|
||||
--- linux-3.0.3.orig/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h 2011-10-04 20:05:23.000000000 +0200
|
||||
+++ linux-3.0.3/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h 2011-10-04 20:05:44.146312365 +0200
|
||||
--- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
|
||||
+++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
|
||||
@@ -80,6 +80,7 @@
|
||||
#define LTQ_PMU_SIZE 0x1000
|
||||
|
||||
|
@ -73,7 +69,7 @@ Index: linux-3.0.3/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
|
|||
/* DMA */
|
||||
#define LTQ_DMA_BASE_ADDR 0x1E104100
|
||||
#define LTQ_DMA_SIZE 0x800
|
||||
@@ -148,6 +153,11 @@
|
||||
@@ -148,6 +153,11 @@ extern void ltq_pmu_enable(unsigned int
|
||||
extern void ltq_pmu_disable(unsigned int module);
|
||||
extern void ltq_cgu_enable(unsigned int clk);
|
||||
|
||||
|
@ -85,11 +81,9 @@ Index: linux-3.0.3/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
|
|||
static inline int ltq_is_ar9(void)
|
||||
{
|
||||
return (ltq_get_soc_type() == SOC_TYPE_AR9);
|
||||
Index: linux-3.0.3/arch/mips/lantiq/xway/devices.c
|
||||
===================================================================
|
||||
--- linux-3.0.3.orig/arch/mips/lantiq/xway/devices.c 2011-10-04 20:03:54.000000000 +0200
|
||||
+++ linux-3.0.3/arch/mips/lantiq/xway/devices.c 2011-10-04 20:05:44.146312365 +0200
|
||||
@@ -79,18 +79,23 @@
|
||||
--- a/arch/mips/lantiq/xway/devices.c
|
||||
+++ b/arch/mips/lantiq/xway/devices.c
|
||||
@@ -77,18 +77,23 @@ void __init ltq_register_ase_asc(void)
|
||||
}
|
||||
|
||||
/* ethernet */
|
||||
|
@ -116,10 +110,8 @@ Index: linux-3.0.3/arch/mips/lantiq/xway/devices.c
|
|||
if (eth) {
|
||||
ltq_etop.dev.platform_data = eth;
|
||||
platform_device_register(<q_etop);
|
||||
Index: linux-3.0.3/drivers/net/lantiq_etop.c
|
||||
===================================================================
|
||||
--- linux-3.0.3.orig/drivers/net/lantiq_etop.c 2011-08-17 19:57:16.000000000 +0200
|
||||
+++ linux-3.0.3/drivers/net/lantiq_etop.c 2011-10-04 20:05:44.146312365 +0200
|
||||
--- a/drivers/net/lantiq_etop.c
|
||||
+++ b/drivers/net/lantiq_etop.c
|
||||
@@ -34,6 +34,7 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/delay.h>
|
||||
|
@ -190,7 +182,7 @@ Index: linux-3.0.3/drivers/net/lantiq_etop.c
|
|||
|
||||
struct ltq_etop_chan {
|
||||
int idx;
|
||||
@@ -108,6 +148,9 @@
|
||||
@@ -108,6 +148,9 @@ struct ltq_etop_priv {
|
||||
spinlock_t lock;
|
||||
};
|
||||
|
||||
|
@ -200,7 +192,7 @@ Index: linux-3.0.3/drivers/net/lantiq_etop.c
|
|||
static int
|
||||
ltq_etop_alloc_skb(struct ltq_etop_chan *ch)
|
||||
{
|
||||
@@ -209,7 +252,7 @@
|
||||
@@ -209,7 +252,7 @@ static irqreturn_t
|
||||
ltq_etop_dma_irq(int irq, void *_priv)
|
||||
{
|
||||
struct ltq_etop_priv *priv = _priv;
|
||||
|
@ -209,7 +201,7 @@ Index: linux-3.0.3/drivers/net/lantiq_etop.c
|
|||
|
||||
napi_schedule(&priv->ch[ch].napi);
|
||||
return IRQ_HANDLED;
|
||||
@@ -242,26 +285,66 @@
|
||||
@@ -242,26 +285,66 @@ ltq_etop_hw_exit(struct net_device *dev)
|
||||
ltq_etop_free_channel(dev, &priv->ch[i]);
|
||||
}
|
||||
|
||||
|
@ -277,7 +269,7 @@ Index: linux-3.0.3/drivers/net/lantiq_etop.c
|
|||
netdev_err(dev, "unknown mii mode %d\n",
|
||||
priv->pldata->mii_mode);
|
||||
return -ENOTSUPP;
|
||||
@@ -273,7 +356,7 @@
|
||||
@@ -273,7 +356,7 @@ ltq_etop_hw_init(struct net_device *dev)
|
||||
ltq_dma_init_port(DMA_PORT_ETOP);
|
||||
|
||||
for (i = 0; i < MAX_DMA_CHAN; i++) {
|
||||
|
@ -286,7 +278,7 @@ Index: linux-3.0.3/drivers/net/lantiq_etop.c
|
|||
struct ltq_etop_chan *ch = &priv->ch[i];
|
||||
|
||||
ch->idx = ch->dma.nr = i;
|
||||
@@ -337,6 +420,39 @@
|
||||
@@ -337,6 +420,39 @@ static const struct ethtool_ops ltq_etop
|
||||
};
|
||||
|
||||
static int
|
||||
|
@ -326,7 +318,7 @@ Index: linux-3.0.3/drivers/net/lantiq_etop.c
|
|||
ltq_etop_mdio_wr(struct mii_bus *bus, int phy_addr, int phy_reg, u16 phy_data)
|
||||
{
|
||||
u32 val = MDIO_REQUEST |
|
||||
@@ -377,14 +493,11 @@
|
||||
@@ -377,14 +493,11 @@ ltq_etop_mdio_probe(struct net_device *d
|
||||
{
|
||||
struct ltq_etop_priv *priv = netdev_priv(dev);
|
||||
struct phy_device *phydev = NULL;
|
||||
|
@ -345,7 +337,7 @@ Index: linux-3.0.3/drivers/net/lantiq_etop.c
|
|||
|
||||
if (!phydev) {
|
||||
netdev_err(dev, "no PHY found\n");
|
||||
@@ -406,6 +519,9 @@
|
||||
@@ -406,6 +519,9 @@ ltq_etop_mdio_probe(struct net_device *d
|
||||
| SUPPORTED_Autoneg
|
||||
| SUPPORTED_MII
|
||||
| SUPPORTED_TP);
|
||||
|
@ -355,7 +347,7 @@ Index: linux-3.0.3/drivers/net/lantiq_etop.c
|
|||
|
||||
phydev->advertising = phydev->supported;
|
||||
priv->phydev = phydev;
|
||||
@@ -431,8 +547,13 @@
|
||||
@@ -431,8 +547,13 @@ ltq_etop_mdio_init(struct net_device *de
|
||||
}
|
||||
|
||||
priv->mii_bus->priv = dev;
|
||||
|
@ -371,7 +363,7 @@ Index: linux-3.0.3/drivers/net/lantiq_etop.c
|
|||
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);
|
||||
@@ -522,9 +643,9 @@
|
||||
@@ -522,9 +643,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];
|
||||
|
@ -382,7 +374,7 @@ Index: linux-3.0.3/drivers/net/lantiq_etop.c
|
|||
|
||||
len = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len;
|
||||
|
||||
@@ -698,7 +819,7 @@
|
||||
@@ -698,7 +819,7 @@ ltq_etop_probe(struct platform_device *p
|
||||
{
|
||||
struct net_device *dev;
|
||||
struct ltq_etop_priv *priv;
|
||||
|
@ -391,7 +383,7 @@ Index: linux-3.0.3/drivers/net/lantiq_etop.c
|
|||
int err;
|
||||
int i;
|
||||
|
||||
@@ -726,6 +847,23 @@
|
||||
@@ -726,6 +847,23 @@ ltq_etop_probe(struct platform_device *p
|
||||
goto err_out;
|
||||
}
|
||||
|
|
@ -24,8 +24,6 @@ TODO : memory ranges
|
|||
5 files changed, 190 insertions(+), 1 deletions(-)
|
||||
create mode 100644 arch/mips/lantiq/xway/nand.c
|
||||
|
||||
diff --git a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
|
||||
index 86ed0d2..729dfa2 100644
|
||||
--- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
|
||||
+++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
|
||||
@@ -140,6 +140,8 @@
|
||||
|
@ -37,8 +35,6 @@ index 86ed0d2..729dfa2 100644
|
|||
#define ltq_cgu_w32(x, y) ltq_w32((x), ltq_cgu_membase + (y))
|
||||
#define ltq_cgu_r32(x) ltq_r32(ltq_cgu_membase + (x))
|
||||
|
||||
diff --git a/arch/mips/lantiq/xway/Makefile b/arch/mips/lantiq/xway/Makefile
|
||||
index 6678402..ac7cc34 100644
|
||||
--- a/arch/mips/lantiq/xway/Makefile
|
||||
+++ b/arch/mips/lantiq/xway/Makefile
|
||||
@@ -1,4 +1,4 @@
|
||||
|
@ -47,9 +43,6 @@ index 6678402..ac7cc34 100644
|
|||
|
||||
obj-$(CONFIG_SOC_XWAY) += clk-xway.o prom-xway.o
|
||||
obj-$(CONFIG_SOC_AMAZON_SE) += clk-ase.o prom-ase.o
|
||||
diff --git a/arch/mips/lantiq/xway/nand.c b/arch/mips/lantiq/xway/nand.c
|
||||
new file mode 100644
|
||||
index 0000000..ba2443c
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/lantiq/xway/nand.c
|
||||
@@ -0,0 +1,185 @@
|
||||
|
@ -238,11 +231,9 @@ index 0000000..ba2443c
|
|||
+{
|
||||
+ platform_device_register(<q_flash_nand);
|
||||
+}
|
||||
diff --git a/drivers/mtd/nand/plat_nand.c b/drivers/mtd/nand/plat_nand.c
|
||||
index 633c04b..c3e3ef6 100644
|
||||
--- a/drivers/mtd/nand/plat_nand.c
|
||||
+++ b/drivers/mtd/nand/plat_nand.c
|
||||
@@ -77,6 +77,7 @@ static int __devinit plat_nand_probe(struct platform_device *pdev)
|
||||
@@ -77,6 +77,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;
|
||||
|
@ -250,11 +241,9 @@ index 633c04b..c3e3ef6 100644
|
|||
data->chip.chip_delay = pdata->chip.chip_delay;
|
||||
data->chip.options |= pdata->chip.options;
|
||||
|
||||
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
|
||||
index c2b9ac4..597e1a0 100644
|
||||
--- a/include/linux/mtd/nand.h
|
||||
+++ b/include/linux/mtd/nand.h
|
||||
@@ -656,6 +656,7 @@ struct platform_nand_ctrl {
|
||||
@@ -657,6 +657,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);
|
||||
|
@ -262,6 +251,3 @@ index c2b9ac4..597e1a0 100644
|
|||
void *priv;
|
||||
};
|
||||
|
||||
--
|
||||
1.7.5.4
|
||||
|
|
@ -11,9 +11,6 @@ Subject: [PATCH 17/24] MIPS: lantiq: adds GPTU driver
|
|||
create mode 100644 arch/mips/include/asm/mach-lantiq/lantiq_timer.h
|
||||
create mode 100644 arch/mips/lantiq/xway/timer.c
|
||||
|
||||
diff --git a/arch/mips/include/asm/mach-lantiq/lantiq_timer.h b/arch/mips/include/asm/mach-lantiq/lantiq_timer.h
|
||||
new file mode 100644
|
||||
index 0000000..ef564ab
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/include/asm/mach-lantiq/lantiq_timer.h
|
||||
@@ -0,0 +1,155 @@
|
||||
|
@ -172,8 +169,6 @@ index 0000000..ef564ab
|
|||
+ u32 reload, unsigned long arg1, unsigned long arg2);
|
||||
+
|
||||
+#endif /* __DANUBE_GPTU_DEV_H__2005_07_26__10_19__ */
|
||||
diff --git a/arch/mips/lantiq/xway/Makefile b/arch/mips/lantiq/xway/Makefile
|
||||
index ac7cc34..1f41239 100644
|
||||
--- a/arch/mips/lantiq/xway/Makefile
|
||||
+++ b/arch/mips/lantiq/xway/Makefile
|
||||
@@ -1,4 +1,4 @@
|
||||
|
@ -182,9 +177,6 @@ index ac7cc34..1f41239 100644
|
|||
|
||||
obj-$(CONFIG_SOC_XWAY) += clk-xway.o prom-xway.o
|
||||
obj-$(CONFIG_SOC_AMAZON_SE) += clk-ase.o prom-ase.o
|
||||
diff --git a/arch/mips/lantiq/xway/timer.c b/arch/mips/lantiq/xway/timer.c
|
||||
new file mode 100644
|
||||
index 0000000..cac2ea8
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/lantiq/xway/timer.c
|
||||
@@ -0,0 +1,830 @@
|
||||
|
@ -1018,6 +1010,3 @@ index 0000000..cac2ea8
|
|||
+
|
||||
+module_init(lq_gptu_init);
|
||||
+module_exit(lq_gptu_exit);
|
||||
--
|
||||
1.7.5.4
|
||||
|
|
@ -45,8 +45,6 @@ Subject: [PATCH 18/24] MIPS: lantiq: adds dwc_otg
|
|||
create mode 100644 drivers/usb/dwc_otg/dwc_otg_plat.h
|
||||
create mode 100644 drivers/usb/dwc_otg/dwc_otg_regs.h
|
||||
|
||||
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig
|
||||
index 48f1781..b48c1bd 100644
|
||||
--- a/drivers/usb/Kconfig
|
||||
+++ b/drivers/usb/Kconfig
|
||||
@@ -116,6 +116,8 @@ source "drivers/usb/wusbcore/Kconfig"
|
||||
|
@ -58,8 +56,6 @@ index 48f1781..b48c1bd 100644
|
|||
source "drivers/usb/musb/Kconfig"
|
||||
|
||||
source "drivers/usb/renesas_usbhs/Kconfig"
|
||||
diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile
|
||||
index 30ddf8d..ba3b993 100644
|
||||
--- a/drivers/usb/Makefile
|
||||
+++ b/drivers/usb/Makefile
|
||||
@@ -28,6 +28,8 @@ obj-$(CONFIG_USB_C67X00_HCD) += c67x00/
|
||||
|
@ -71,11 +67,9 @@ index 30ddf8d..ba3b993 100644
|
|||
obj-$(CONFIG_USB_ACM) += class/
|
||||
obj-$(CONFIG_USB_PRINTER) += class/
|
||||
obj-$(CONFIG_USB_WDM) += class/
|
||||
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
|
||||
index a428aa0..115ae9a 100644
|
||||
--- a/drivers/usb/core/hub.c
|
||||
+++ b/drivers/usb/core/hub.c
|
||||
@@ -2885,11 +2885,11 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
|
||||
@@ -2885,11 +2885,11 @@ hub_port_init (struct usb_hub *hub, stru
|
||||
udev->ttport = hdev->ttport;
|
||||
} else if (udev->speed != USB_SPEED_HIGH
|
||||
&& hdev->speed == USB_SPEED_HIGH) {
|
||||
|
@ -89,9 +83,6 @@ index a428aa0..115ae9a 100644
|
|||
udev->tt = &hub->tt;
|
||||
udev->ttport = port1;
|
||||
}
|
||||
diff --git a/drivers/usb/dwc_otg/Kconfig b/drivers/usb/dwc_otg/Kconfig
|
||||
new file mode 100644
|
||||
index 0000000..e018490
|
||||
--- /dev/null
|
||||
+++ b/drivers/usb/dwc_otg/Kconfig
|
||||
@@ -0,0 +1,37 @@
|
||||
|
@ -132,9 +123,6 @@ index 0000000..e018490
|
|||
+config DWC_OTG_DEBUG
|
||||
+ bool "Enable debug mode"
|
||||
+ depends on DWC_OTG
|
||||
diff --git a/drivers/usb/dwc_otg/Makefile b/drivers/usb/dwc_otg/Makefile
|
||||
new file mode 100644
|
||||
index 0000000..d4d2355
|
||||
--- /dev/null
|
||||
+++ b/drivers/usb/dwc_otg/Makefile
|
||||
@@ -0,0 +1,39 @@
|
||||
|
@ -177,9 +165,6 @@ index 0000000..d4d2355
|
|||
+
|
||||
+#obj-$(CONFIG_DWC_OTG_IFX) := dwc_otg_ifx.o
|
||||
+#dwc_otg_ifx-objs := dwc_otg_ifx.o
|
||||
diff --git a/drivers/usb/dwc_otg/dwc_otg_attr.c b/drivers/usb/dwc_otg/dwc_otg_attr.c
|
||||
new file mode 100644
|
||||
index 0000000..4675a5c
|
||||
--- /dev/null
|
||||
+++ b/drivers/usb/dwc_otg/dwc_otg_attr.c
|
||||
@@ -0,0 +1,802 @@
|
||||
|
@ -985,9 +970,6 @@ index 0000000..4675a5c
|
|||
+ device_remove_file(_dev, &dev_attr_rd_reg_test);
|
||||
+ device_remove_file(_dev, &dev_attr_wr_reg_test);
|
||||
+}
|
||||
diff --git a/drivers/usb/dwc_otg/dwc_otg_attr.h b/drivers/usb/dwc_otg/dwc_otg_attr.h
|
||||
new file mode 100644
|
||||
index 0000000..4bbf7df
|
||||
--- /dev/null
|
||||
+++ b/drivers/usb/dwc_otg/dwc_otg_attr.h
|
||||
@@ -0,0 +1,67 @@
|
||||
|
@ -1058,9 +1040,6 @@ index 0000000..4bbf7df
|
|||
+void dwc_otg_attr_remove (struct device *_dev);
|
||||
+
|
||||
+#endif
|
||||
diff --git a/drivers/usb/dwc_otg/dwc_otg_cil.c b/drivers/usb/dwc_otg/dwc_otg_cil.c
|
||||
new file mode 100644
|
||||
index 0000000..42c69eb
|
||||
--- /dev/null
|
||||
+++ b/drivers/usb/dwc_otg/dwc_otg_cil.c
|
||||
@@ -0,0 +1,3025 @@
|
||||
|
@ -4089,9 +4068,6 @@ index 0000000..42c69eb
|
|||
+ _cb->p = _p;
|
||||
+}
|
||||
+
|
||||
diff --git a/drivers/usb/dwc_otg/dwc_otg_cil.h b/drivers/usb/dwc_otg/dwc_otg_cil.h
|
||||
new file mode 100644
|
||||
index 0000000..bbb9516
|
||||
--- /dev/null
|
||||
+++ b/drivers/usb/dwc_otg/dwc_otg_cil.h
|
||||
@@ -0,0 +1,911 @@
|
||||
|
@ -5006,9 +4982,6 @@ index 0000000..bbb9516
|
|||
+
|
||||
+
|
||||
+#endif
|
||||
diff --git a/drivers/usb/dwc_otg/dwc_otg_cil_ifx.h b/drivers/usb/dwc_otg/dwc_otg_cil_ifx.h
|
||||
new file mode 100644
|
||||
index 0000000..b0298ec
|
||||
--- /dev/null
|
||||
+++ b/drivers/usb/dwc_otg/dwc_otg_cil_ifx.h
|
||||
@@ -0,0 +1,58 @@
|
||||
|
@ -5070,9 +5043,6 @@ index 0000000..b0298ec
|
|||
+
|
||||
+#endif // __DWC_OTG_CIL_IFX_H__
|
||||
+
|
||||
diff --git a/drivers/usb/dwc_otg/dwc_otg_cil_intr.c b/drivers/usb/dwc_otg/dwc_otg_cil_intr.c
|
||||
new file mode 100644
|
||||
index 0000000..d469ab4
|
||||
--- /dev/null
|
||||
+++ b/drivers/usb/dwc_otg/dwc_otg_cil_intr.c
|
||||
@@ -0,0 +1,708 @@
|
||||
|
@ -5784,9 +5754,6 @@ index 0000000..d469ab4
|
|||
+ }
|
||||
+ return retval;
|
||||
+}
|
||||
diff --git a/drivers/usb/dwc_otg/dwc_otg_driver.c b/drivers/usb/dwc_otg/dwc_otg_driver.c
|
||||
new file mode 100644
|
||||
index 0000000..1b0daab
|
||||
--- /dev/null
|
||||
+++ b/drivers/usb/dwc_otg/dwc_otg_driver.c
|
||||
@@ -0,0 +1,1274 @@
|
||||
|
@ -7064,9 +7031,6 @@ index 0000000..1b0daab
|
|||
+ </td></tr>
|
||||
+
|
||||
+*/
|
||||
diff --git a/drivers/usb/dwc_otg/dwc_otg_driver.h b/drivers/usb/dwc_otg/dwc_otg_driver.h
|
||||
new file mode 100644
|
||||
index 0000000..7e6940d
|
||||
--- /dev/null
|
||||
+++ b/drivers/usb/dwc_otg/dwc_otg_driver.h
|
||||
@@ -0,0 +1,84 @@
|
||||
|
@ -7154,9 +7118,6 @@ index 0000000..7e6940d
|
|||
+//#define dev_dbg(fake, format, arg...) printk(KERN_CRIT __FILE__ ":%d: " format "\n" , __LINE__, ## arg)
|
||||
+
|
||||
+#endif
|
||||
diff --git a/drivers/usb/dwc_otg/dwc_otg_hcd.c b/drivers/usb/dwc_otg/dwc_otg_hcd.c
|
||||
new file mode 100644
|
||||
index 0000000..ad6bc72
|
||||
--- /dev/null
|
||||
+++ b/drivers/usb/dwc_otg/dwc_otg_hcd.c
|
||||
@@ -0,0 +1,2870 @@
|
||||
|
@ -10030,9 +9991,6 @@ index 0000000..ad6bc72
|
|||
+#endif
|
||||
+}
|
||||
+#endif /* DWC_DEVICE_ONLY */
|
||||
diff --git a/drivers/usb/dwc_otg/dwc_otg_hcd.h b/drivers/usb/dwc_otg/dwc_otg_hcd.h
|
||||
new file mode 100644
|
||||
index 0000000..8a20dff
|
||||
--- /dev/null
|
||||
+++ b/drivers/usb/dwc_otg/dwc_otg_hcd.h
|
||||
@@ -0,0 +1,676 @@
|
||||
|
@ -10712,9 +10670,6 @@ index 0000000..8a20dff
|
|||
+#endif // DEBUG
|
||||
+#endif // __DWC_HCD_H__
|
||||
+#endif /* DWC_DEVICE_ONLY */
|
||||
diff --git a/drivers/usb/dwc_otg/dwc_otg_hcd_intr.c b/drivers/usb/dwc_otg/dwc_otg_hcd_intr.c
|
||||
new file mode 100644
|
||||
index 0000000..834b5e0
|
||||
--- /dev/null
|
||||
+++ b/drivers/usb/dwc_otg/dwc_otg_hcd_intr.c
|
||||
@@ -0,0 +1,1841 @@
|
||||
|
@ -12559,9 +12514,6 @@ index 0000000..834b5e0
|
|||
+}
|
||||
+
|
||||
+#endif /* DWC_DEVICE_ONLY */
|
||||
diff --git a/drivers/usb/dwc_otg/dwc_otg_hcd_queue.c b/drivers/usb/dwc_otg/dwc_otg_hcd_queue.c
|
||||
new file mode 100644
|
||||
index 0000000..fcb5ce6
|
||||
--- /dev/null
|
||||
+++ b/drivers/usb/dwc_otg/dwc_otg_hcd_queue.c
|
||||
@@ -0,0 +1,794 @@
|
||||
|
@ -13359,9 +13311,6 @@ index 0000000..fcb5ce6
|
|||
+}
|
||||
+
|
||||
+#endif /* DWC_DEVICE_ONLY */
|
||||
diff --git a/drivers/usb/dwc_otg/dwc_otg_ifx.c b/drivers/usb/dwc_otg/dwc_otg_ifx.c
|
||||
new file mode 100644
|
||||
index 0000000..0a4c209
|
||||
--- /dev/null
|
||||
+++ b/drivers/usb/dwc_otg/dwc_otg_ifx.c
|
||||
@@ -0,0 +1,100 @@
|
||||
|
@ -13465,9 +13414,6 @@ index 0000000..0a4c209
|
|||
+void ifx_usb_hc_remove(void)
|
||||
+{
|
||||
+}
|
||||
diff --git a/drivers/usb/dwc_otg/dwc_otg_ifx.h b/drivers/usb/dwc_otg/dwc_otg_ifx.h
|
||||
new file mode 100644
|
||||
index 0000000..402d7a6
|
||||
--- /dev/null
|
||||
+++ b/drivers/usb/dwc_otg/dwc_otg_ifx.h
|
||||
@@ -0,0 +1,85 @@
|
||||
|
@ -13556,9 +13502,6 @@ index 0000000..402d7a6
|
|||
+ ltq_mask_and_ack_irq(&d);
|
||||
+}
|
||||
+#endif //__DWC_OTG_IFX_H__
|
||||
diff --git a/drivers/usb/dwc_otg/dwc_otg_plat.h b/drivers/usb/dwc_otg/dwc_otg_plat.h
|
||||
new file mode 100644
|
||||
index 0000000..727d0c4
|
||||
--- /dev/null
|
||||
+++ b/drivers/usb/dwc_otg/dwc_otg_plat.h
|
||||
@@ -0,0 +1,269 @@
|
||||
|
@ -13831,9 +13774,6 @@ index 0000000..727d0c4
|
|||
+
|
||||
+#endif
|
||||
+
|
||||
diff --git a/drivers/usb/dwc_otg/dwc_otg_regs.h b/drivers/usb/dwc_otg/dwc_otg_regs.h
|
||||
new file mode 100644
|
||||
index 0000000..397a954
|
||||
--- /dev/null
|
||||
+++ b/drivers/usb/dwc_otg/dwc_otg_regs.h
|
||||
@@ -0,0 +1,1797 @@
|
||||
|
@ -15634,6 +15574,3 @@ index 0000000..397a954
|
|||
+} dwc_otg_host_if_t;
|
||||
+
|
||||
+#endif
|
||||
--
|
||||
1.7.5.4
|
||||
|
|
@ -1,6 +1,25 @@
|
|||
From c6c810d83f0d95f54c3a6b338d219cec7ccef4c9 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Thu, 29 Sep 2011 20:30:40 +0200
|
||||
Subject: [PATCH 19/24] MIPS: lantiq: adds VPE extensions
|
||||
|
||||
---
|
||||
arch/mips/Kconfig | 22 +++
|
||||
arch/mips/include/asm/mipsmtregs.h | 54 +++++++
|
||||
arch/mips/kernel/Makefile | 3 +-
|
||||
arch/mips/kernel/mips-mt.c | 97 +++++++++++--
|
||||
arch/mips/kernel/mtsched_proc.c | 279 ++++++++++++++++++++++++++++++++++++
|
||||
arch/mips/kernel/perf_proc.c | 191 ++++++++++++++++++++++++
|
||||
arch/mips/kernel/proc.c | 17 +++
|
||||
arch/mips/kernel/smtc.c | 7 +
|
||||
arch/mips/kernel/vpe.c | 250 ++++++++++++++++++++++++++++++++-
|
||||
9 files changed, 905 insertions(+), 15 deletions(-)
|
||||
create mode 100644 arch/mips/kernel/mtsched_proc.c
|
||||
create mode 100644 arch/mips/kernel/perf_proc.c
|
||||
|
||||
--- a/arch/mips/Kconfig
|
||||
+++ b/arch/mips/Kconfig
|
||||
@@ -1871,6 +1871,28 @@ config MIPS_VPE_LOADER
|
||||
@@ -1915,6 +1915,28 @@ config MIPS_VPE_LOADER
|
||||
Includes a loader for loading an elf relocatable object
|
||||
onto another VPE and running it.
|
||||
|
||||
|
@ -140,7 +159,7 @@
|
|||
#define read_tc_gpr_sp() mftgpr(29)
|
||||
--- a/arch/mips/kernel/Makefile
|
||||
+++ b/arch/mips/kernel/Makefile
|
||||
@@ -85,7 +85,8 @@ obj-$(CONFIG_MIPS32_O32) += binfmt_elfo3
|
||||
@@ -86,7 +86,8 @@ obj-$(CONFIG_MIPS32_O32) += binfmt_elfo3
|
||||
|
||||
obj-$(CONFIG_KGDB) += kgdb.o
|
||||
obj-$(CONFIG_PROC_FS) += proc.o
|
||||
|
@ -290,417 +309,6 @@
|
|||
}
|
||||
|
||||
/*
|
||||
--- a/arch/mips/kernel/proc.c
|
||||
+++ b/arch/mips/kernel/proc.c
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/seq_file.h>
|
||||
+#include <linux/proc_fs.h>
|
||||
#include <asm/bootinfo.h>
|
||||
#include <asm/cpu.h>
|
||||
#include <asm/cpu-features.h>
|
||||
@@ -110,3 +111,19 @@ const struct seq_operations cpuinfo_op =
|
||||
.stop = c_stop,
|
||||
.show = show_cpuinfo,
|
||||
};
|
||||
+
|
||||
+/*
|
||||
+ * Support for MIPS/local /proc hooks in /proc/mips/
|
||||
+ */
|
||||
+
|
||||
+static struct proc_dir_entry *mips_proc = NULL;
|
||||
+
|
||||
+struct proc_dir_entry *get_mips_proc_dir(void)
|
||||
+{
|
||||
+ /*
|
||||
+ * This ought not to be preemptable.
|
||||
+ */
|
||||
+ if(mips_proc == NULL)
|
||||
+ mips_proc = proc_mkdir("mips", NULL);
|
||||
+ return(mips_proc);
|
||||
+}
|
||||
--- a/arch/mips/kernel/smtc.c
|
||||
+++ b/arch/mips/kernel/smtc.c
|
||||
@@ -1334,6 +1334,13 @@ void smtc_get_new_mmu_context(struct mm_
|
||||
asid = asid_cache(cpu);
|
||||
|
||||
do {
|
||||
+#ifdef CONFIG_IFX_VPE_EXT
|
||||
+ /* If TLB is shared between AP and RP (AP is running SMTC),
|
||||
+ leave out max ASID i.e., ASID_MASK for RP
|
||||
+ */
|
||||
+ if (!nostlb && ((asid & ASID_MASK) == (ASID_MASK - 1)))
|
||||
+ asid++;
|
||||
+#endif
|
||||
if (!((asid += ASID_INC) & ASID_MASK) ) {
|
||||
if (cpu_has_vtag_icache)
|
||||
flush_icache_all();
|
||||
--- a/arch/mips/kernel/vpe.c
|
||||
+++ b/arch/mips/kernel/vpe.c
|
||||
@@ -76,6 +76,58 @@ static struct kspd_notifications kspd_ev
|
||||
static int kspd_events_reqd;
|
||||
#endif
|
||||
|
||||
+#ifdef CONFIG_IFX_VPE_EXT
|
||||
+static int is_sdepgm;
|
||||
+extern int stlb;
|
||||
+extern int vpe0_wired;
|
||||
+extern int vpe1_wired;
|
||||
+unsigned int vpe1_load_addr;
|
||||
+
|
||||
+static int __init load_address(char *str)
|
||||
+{
|
||||
+ get_option(&str, &vpe1_load_addr);
|
||||
+ return 1;
|
||||
+}
|
||||
+__setup("vpe1_load_addr=", load_address);
|
||||
+
|
||||
+#include <asm/mipsmtregs.h>
|
||||
+#define write_vpe_c0_wired(val) mttc0(6, 0, val)
|
||||
+
|
||||
+#ifndef COMMAND_LINE_SIZE
|
||||
+# define COMMAND_LINE_SIZE 512
|
||||
+#endif
|
||||
+
|
||||
+char command_line[COMMAND_LINE_SIZE * 2];
|
||||
+
|
||||
+static unsigned int vpe1_mem;
|
||||
+static int __init vpe1mem(char *str)
|
||||
+{
|
||||
+ vpe1_mem = memparse(str, &str);
|
||||
+ return 1;
|
||||
+}
|
||||
+__setup("vpe1_mem=", vpe1mem);
|
||||
+
|
||||
+uint32_t vpe1_wdog_ctr;
|
||||
+static int __init wdog_ctr(char *str)
|
||||
+{
|
||||
+ get_option(&str, &vpe1_wdog_ctr);
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
+__setup("vpe1_wdog_ctr_addr=", wdog_ctr);
|
||||
+EXPORT_SYMBOL(vpe1_wdog_ctr);
|
||||
+
|
||||
+uint32_t vpe1_wdog_timeout;
|
||||
+static int __init wdog_timeout(char *str)
|
||||
+{
|
||||
+ get_option(&str, &vpe1_wdog_timeout);
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
+__setup("vpe1_wdog_timeout=", wdog_timeout);
|
||||
+EXPORT_SYMBOL(vpe1_wdog_timeout);
|
||||
+
|
||||
+#endif
|
||||
/* grab the likely amount of memory we will need. */
|
||||
#ifdef CONFIG_MIPS_VPE_LOADER_TOM
|
||||
#define P_SIZE (2 * 1024 * 1024)
|
||||
@@ -268,6 +320,13 @@ static void *alloc_progmem(unsigned long
|
||||
void *addr;
|
||||
|
||||
#ifdef CONFIG_MIPS_VPE_LOADER_TOM
|
||||
+#ifdef CONFIG_IFX_VPE_EXT
|
||||
+ if (vpe1_load_addr) {
|
||||
+ memset((void *)vpe1_load_addr, 0, len);
|
||||
+ return (void *)vpe1_load_addr;
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
/*
|
||||
* This means you must tell Linux to use less memory than you
|
||||
* physically have, for example by passing a mem= boot argument.
|
||||
@@ -746,6 +805,12 @@ static int vpe_run(struct vpe * v)
|
||||
}
|
||||
|
||||
/* Write the address we want it to start running from in the TCPC register. */
|
||||
+#if defined(CONFIG_IFX_VPE_EXT) && 0
|
||||
+ if (stlb)
|
||||
+ write_vpe_c0_wired(vpe0_wired + vpe1_wired);
|
||||
+ else
|
||||
+ write_vpe_c0_wired(vpe1_wired);
|
||||
+#endif
|
||||
write_tc_c0_tcrestart((unsigned long)v->__start);
|
||||
write_tc_c0_tccontext((unsigned long)0);
|
||||
|
||||
@@ -759,6 +824,20 @@ static int vpe_run(struct vpe * v)
|
||||
|
||||
write_tc_c0_tchalt(read_tc_c0_tchalt() & ~TCHALT_H);
|
||||
|
||||
+#if defined(CONFIG_IFX_VPE_EXT) && 0
|
||||
+ /*
|
||||
+ * $a2 & $a3 are used to pass command line parameters to VPE1. $a2
|
||||
+ * points to the start of the command line string and $a3 points to
|
||||
+ * the end of the string. This convention is identical to the Linux
|
||||
+ * kernel boot parameter passing mechanism. Please note that $a3 is
|
||||
+ * used to pass physical memory size or 0 in SDE tool kit. So, if you
|
||||
+ * are passing comand line parameters through $a2 & $a3 SDE programs
|
||||
+ * don't work as desired.
|
||||
+ */
|
||||
+ mttgpr(6, command_line);
|
||||
+ mttgpr(7, (command_line + strlen(command_line)));
|
||||
+ if (is_sdepgm)
|
||||
+#endif
|
||||
/*
|
||||
* The sde-kit passes 'memsize' to __start in $a3, so set something
|
||||
* here... Or set $a3 to zero and define DFLT_STACK_SIZE and
|
||||
@@ -833,6 +912,9 @@ static int find_vpe_symbols(struct vpe *
|
||||
if ( (v->__start == 0) || (v->shared_ptr == NULL))
|
||||
return -1;
|
||||
|
||||
+#ifdef CONFIG_IFX_VPE_EXT
|
||||
+ is_sdepgm = 1;
|
||||
+#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -994,6 +1076,15 @@ static int vpe_elfload(struct vpe * v)
|
||||
(unsigned long)v->load_addr + v->len);
|
||||
|
||||
if ((find_vpe_symbols(v, sechdrs, symindex, strtab, &mod)) < 0) {
|
||||
+#ifdef CONFIG_IFX_VPE_EXT
|
||||
+ if (vpe1_load_addr) {
|
||||
+ /* Conversion to KSEG1 is required ??? */
|
||||
+ v->__start = KSEG1ADDR(vpe1_load_addr);
|
||||
+ is_sdepgm = 0;
|
||||
+ return 0;
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
if (v->__start == 0) {
|
||||
printk(KERN_WARNING "VPE loader: program does not contain "
|
||||
"a __start symbol\n");
|
||||
@@ -1064,6 +1155,9 @@ static int vpe_open(struct inode *inode,
|
||||
struct vpe_notifications *not;
|
||||
struct vpe *v;
|
||||
int ret;
|
||||
+#ifdef CONFIG_IFX_VPE_EXT
|
||||
+ int progsize;
|
||||
+#endif
|
||||
|
||||
if (minor != iminor(inode)) {
|
||||
/* assume only 1 device at the moment. */
|
||||
@@ -1089,7 +1183,12 @@ static int vpe_open(struct inode *inode,
|
||||
release_progmem(v->load_addr);
|
||||
cleanup_tc(get_tc(tclimit));
|
||||
}
|
||||
-
|
||||
+#ifdef CONFIG_IFX_VPE_EXT
|
||||
+ progsize = (vpe1_mem != 0) ? vpe1_mem : P_SIZE;
|
||||
+ //printk("progsize = %x\n", progsize);
|
||||
+ v->pbuffer = vmalloc(progsize);
|
||||
+ v->plen = progsize;
|
||||
+#else
|
||||
/* this of-course trashes what was there before... */
|
||||
v->pbuffer = vmalloc(P_SIZE);
|
||||
if (!v->pbuffer) {
|
||||
@@ -1097,11 +1196,14 @@ static int vpe_open(struct inode *inode,
|
||||
return -ENOMEM;
|
||||
}
|
||||
v->plen = P_SIZE;
|
||||
+#endif
|
||||
v->load_addr = NULL;
|
||||
v->len = 0;
|
||||
|
||||
+#if 0
|
||||
v->uid = filp->f_cred->fsuid;
|
||||
v->gid = filp->f_cred->fsgid;
|
||||
+#endif
|
||||
|
||||
#ifdef CONFIG_MIPS_APSP_KSPD
|
||||
/* get kspd to tell us when a syscall_exit happens */
|
||||
@@ -1349,6 +1451,133 @@ static void kspd_sp_exit( int sp_id)
|
||||
cleanup_tc(get_tc(sp_id));
|
||||
}
|
||||
#endif
|
||||
+#ifdef CONFIG_IFX_VPE_EXT
|
||||
+int32_t vpe1_sw_start(void* sw_start_addr, uint32_t tcmask, uint32_t flags)
|
||||
+{
|
||||
+ enum vpe_state state;
|
||||
+ struct vpe *v = get_vpe(tclimit);
|
||||
+ struct vpe_notifications *not;
|
||||
+
|
||||
+ if (tcmask || flags) {
|
||||
+ printk(KERN_WARNING "Currently tcmask and flags should be 0.\
|
||||
+ other values not supported\n");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ state = xchg(&v->state, VPE_STATE_INUSE);
|
||||
+ if (state != VPE_STATE_UNUSED) {
|
||||
+ vpe_stop(v);
|
||||
+
|
||||
+ list_for_each_entry(not, &v->notify, list) {
|
||||
+ not->stop(tclimit);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ v->__start = (unsigned long)sw_start_addr;
|
||||
+ is_sdepgm = 0;
|
||||
+
|
||||
+ if (!vpe_run(v)) {
|
||||
+ printk(KERN_DEBUG "VPE loader: VPE1 running successfully\n");
|
||||
+ return 0;
|
||||
+ }
|
||||
+ return -1;
|
||||
+}
|
||||
+
|
||||
+EXPORT_SYMBOL(vpe1_sw_start);
|
||||
+
|
||||
+int32_t vpe1_sw_stop(uint32_t flags)
|
||||
+{
|
||||
+ struct vpe *v = get_vpe(tclimit);
|
||||
+
|
||||
+ if (!vpe_free(v)) {
|
||||
+ printk(KERN_DEBUG "RP Stopped\n");
|
||||
+ return 0;
|
||||
+ }
|
||||
+ else
|
||||
+ return -1;
|
||||
+}
|
||||
+
|
||||
+EXPORT_SYMBOL(vpe1_sw_stop);
|
||||
+
|
||||
+uint32_t vpe1_get_load_addr (uint32_t flags)
|
||||
+{
|
||||
+ return vpe1_load_addr;
|
||||
+}
|
||||
+
|
||||
+EXPORT_SYMBOL(vpe1_get_load_addr);
|
||||
+
|
||||
+uint32_t vpe1_get_max_mem (uint32_t flags)
|
||||
+{
|
||||
+ if (!vpe1_mem)
|
||||
+ return P_SIZE;
|
||||
+ else
|
||||
+ return vpe1_mem;
|
||||
+}
|
||||
+
|
||||
+EXPORT_SYMBOL(vpe1_get_max_mem);
|
||||
+
|
||||
+void* vpe1_get_cmdline_argument(void)
|
||||
+{
|
||||
+ return saved_command_line;
|
||||
+}
|
||||
+
|
||||
+EXPORT_SYMBOL(vpe1_get_cmdline_argument);
|
||||
+
|
||||
+int32_t vpe1_set_boot_param(char *field, char *value, char flags)
|
||||
+{
|
||||
+ char *ptr, string[64];
|
||||
+ int start_off, end_off;
|
||||
+ if (!field)
|
||||
+ return -1;
|
||||
+ strcpy(string, field);
|
||||
+ if (value) {
|
||||
+ strcat(string, "=");
|
||||
+ strcat(string, value);
|
||||
+ strcat(command_line, " ");
|
||||
+ strcat(command_line, string);
|
||||
+ }
|
||||
+ else {
|
||||
+ ptr = strstr(command_line, string);
|
||||
+ if (ptr) {
|
||||
+ start_off = ptr - command_line;
|
||||
+ ptr += strlen(string);
|
||||
+ while ((*ptr != ' ') && (*ptr != '\0'))
|
||||
+ ptr++;
|
||||
+ end_off = ptr - command_line;
|
||||
+ command_line[start_off] = '\0';
|
||||
+ strcat (command_line, command_line+end_off);
|
||||
+ }
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+EXPORT_SYMBOL(vpe1_set_boot_param);
|
||||
+
|
||||
+int32_t vpe1_get_boot_param(char *field, char **value, char flags)
|
||||
+{
|
||||
+ char *ptr, string[64];
|
||||
+ int i = 0;
|
||||
+ if (!field)
|
||||
+ return -1;
|
||||
+ if ((ptr = strstr(command_line, field))) {
|
||||
+ ptr += strlen(field) + 1; /* including = */
|
||||
+ while ((*ptr != ' ') && (*ptr != '\0'))
|
||||
+ string[i++] = *ptr++;
|
||||
+ string[i] = '\0';
|
||||
+ *value = kmalloc((strlen(string) + 1), GFP_KERNEL);
|
||||
+ if (*value != NULL)
|
||||
+ strcpy(*value, string);
|
||||
+ }
|
||||
+ else
|
||||
+ *value = NULL;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+EXPORT_SYMBOL(vpe1_get_boot_param);
|
||||
+
|
||||
+extern void configure_tlb(void);
|
||||
+#endif
|
||||
|
||||
static ssize_t store_kill(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t len)
|
||||
@@ -1430,6 +1659,18 @@ static int __init vpe_module_init(void)
|
||||
printk("VPE loader: not a MIPS MT capable processor\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
+#ifdef CONFIG_IFX_VPE_EXT
|
||||
+#ifndef CONFIG_MIPS_MT_SMTC
|
||||
+ configure_tlb();
|
||||
+#endif
|
||||
+#endif
|
||||
+
|
||||
+#ifndef CONFIG_MIPS_MT_SMTC
|
||||
+ if (!vpelimit)
|
||||
+ vpelimit = 1;
|
||||
+ if (!tclimit)
|
||||
+ tclimit = 1;
|
||||
+#endif
|
||||
|
||||
if (vpelimit == 0) {
|
||||
printk(KERN_WARNING "No VPEs reserved for AP/SP, not "
|
||||
@@ -1474,10 +1715,12 @@ static int __init vpe_module_init(void)
|
||||
mtflags = dmt();
|
||||
vpflags = dvpe();
|
||||
|
||||
+ back_to_back_c0_hazard();
|
||||
+
|
||||
/* Put MVPE's into 'configuration state' */
|
||||
set_c0_mvpcontrol(MVPCONTROL_VPC);
|
||||
|
||||
- /* dump_mtregs(); */
|
||||
+ dump_mtregs();
|
||||
|
||||
val = read_c0_mvpconf0();
|
||||
hw_tcs = (val & MVPCONF0_PTC) + 1;
|
||||
@@ -1489,6 +1732,7 @@ static int __init vpe_module_init(void)
|
||||
* reschedule send IPIs or similar we might hang.
|
||||
*/
|
||||
clear_c0_mvpcontrol(MVPCONTROL_VPC);
|
||||
+ back_to_back_c0_hazard();
|
||||
evpe(vpflags);
|
||||
emt(mtflags);
|
||||
local_irq_restore(flags);
|
||||
@@ -1514,6 +1758,7 @@ static int __init vpe_module_init(void)
|
||||
}
|
||||
|
||||
v->ntcs = hw_tcs - tclimit;
|
||||
+ write_tc_c0_tcbind((read_tc_c0_tcbind() & ~TCBIND_CURVPE) | 1);
|
||||
|
||||
/* add the tc to the list of this vpe's tc's. */
|
||||
list_add(&t->tc, &v->tc);
|
||||
@@ -1582,6 +1827,7 @@ static int __init vpe_module_init(void)
|
||||
out_reenable:
|
||||
/* release config state */
|
||||
clear_c0_mvpcontrol(MVPCONTROL_VPC);
|
||||
+ back_to_back_c0_hazard();
|
||||
|
||||
evpe(vpflags);
|
||||
emt(mtflags);
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/kernel/mtsched_proc.c
|
||||
@@ -0,0 +1,279 @@
|
||||
|
@ -1177,3 +785,414 @@
|
|||
+
|
||||
+/* Automagically create the entry */
|
||||
+module_init(init_perf_proc);
|
||||
--- a/arch/mips/kernel/proc.c
|
||||
+++ b/arch/mips/kernel/proc.c
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/seq_file.h>
|
||||
+#include <linux/proc_fs.h>
|
||||
#include <asm/bootinfo.h>
|
||||
#include <asm/cpu.h>
|
||||
#include <asm/cpu-features.h>
|
||||
@@ -110,3 +111,19 @@ const struct seq_operations cpuinfo_op =
|
||||
.stop = c_stop,
|
||||
.show = show_cpuinfo,
|
||||
};
|
||||
+
|
||||
+/*
|
||||
+ * Support for MIPS/local /proc hooks in /proc/mips/
|
||||
+ */
|
||||
+
|
||||
+static struct proc_dir_entry *mips_proc = NULL;
|
||||
+
|
||||
+struct proc_dir_entry *get_mips_proc_dir(void)
|
||||
+{
|
||||
+ /*
|
||||
+ * This ought not to be preemptable.
|
||||
+ */
|
||||
+ if(mips_proc == NULL)
|
||||
+ mips_proc = proc_mkdir("mips", NULL);
|
||||
+ return(mips_proc);
|
||||
+}
|
||||
--- a/arch/mips/kernel/smtc.c
|
||||
+++ b/arch/mips/kernel/smtc.c
|
||||
@@ -1334,6 +1334,13 @@ void smtc_get_new_mmu_context(struct mm_
|
||||
asid = asid_cache(cpu);
|
||||
|
||||
do {
|
||||
+#ifdef CONFIG_IFX_VPE_EXT
|
||||
+ /* If TLB is shared between AP and RP (AP is running SMTC),
|
||||
+ leave out max ASID i.e., ASID_MASK for RP
|
||||
+ */
|
||||
+ if (!nostlb && ((asid & ASID_MASK) == (ASID_MASK - 1)))
|
||||
+ asid++;
|
||||
+#endif
|
||||
if (!((asid += ASID_INC) & ASID_MASK) ) {
|
||||
if (cpu_has_vtag_icache)
|
||||
flush_icache_all();
|
||||
--- a/arch/mips/kernel/vpe.c
|
||||
+++ b/arch/mips/kernel/vpe.c
|
||||
@@ -76,6 +76,58 @@ static struct kspd_notifications kspd_ev
|
||||
static int kspd_events_reqd;
|
||||
#endif
|
||||
|
||||
+#ifdef CONFIG_IFX_VPE_EXT
|
||||
+static int is_sdepgm;
|
||||
+extern int stlb;
|
||||
+extern int vpe0_wired;
|
||||
+extern int vpe1_wired;
|
||||
+unsigned int vpe1_load_addr;
|
||||
+
|
||||
+static int __init load_address(char *str)
|
||||
+{
|
||||
+ get_option(&str, &vpe1_load_addr);
|
||||
+ return 1;
|
||||
+}
|
||||
+__setup("vpe1_load_addr=", load_address);
|
||||
+
|
||||
+#include <asm/mipsmtregs.h>
|
||||
+#define write_vpe_c0_wired(val) mttc0(6, 0, val)
|
||||
+
|
||||
+#ifndef COMMAND_LINE_SIZE
|
||||
+# define COMMAND_LINE_SIZE 512
|
||||
+#endif
|
||||
+
|
||||
+char command_line[COMMAND_LINE_SIZE * 2];
|
||||
+
|
||||
+static unsigned int vpe1_mem;
|
||||
+static int __init vpe1mem(char *str)
|
||||
+{
|
||||
+ vpe1_mem = memparse(str, &str);
|
||||
+ return 1;
|
||||
+}
|
||||
+__setup("vpe1_mem=", vpe1mem);
|
||||
+
|
||||
+uint32_t vpe1_wdog_ctr;
|
||||
+static int __init wdog_ctr(char *str)
|
||||
+{
|
||||
+ get_option(&str, &vpe1_wdog_ctr);
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
+__setup("vpe1_wdog_ctr_addr=", wdog_ctr);
|
||||
+EXPORT_SYMBOL(vpe1_wdog_ctr);
|
||||
+
|
||||
+uint32_t vpe1_wdog_timeout;
|
||||
+static int __init wdog_timeout(char *str)
|
||||
+{
|
||||
+ get_option(&str, &vpe1_wdog_timeout);
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
+__setup("vpe1_wdog_timeout=", wdog_timeout);
|
||||
+EXPORT_SYMBOL(vpe1_wdog_timeout);
|
||||
+
|
||||
+#endif
|
||||
/* grab the likely amount of memory we will need. */
|
||||
#ifdef CONFIG_MIPS_VPE_LOADER_TOM
|
||||
#define P_SIZE (2 * 1024 * 1024)
|
||||
@@ -268,6 +320,13 @@ static void *alloc_progmem(unsigned long
|
||||
void *addr;
|
||||
|
||||
#ifdef CONFIG_MIPS_VPE_LOADER_TOM
|
||||
+#ifdef CONFIG_IFX_VPE_EXT
|
||||
+ if (vpe1_load_addr) {
|
||||
+ memset((void *)vpe1_load_addr, 0, len);
|
||||
+ return (void *)vpe1_load_addr;
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
/*
|
||||
* This means you must tell Linux to use less memory than you
|
||||
* physically have, for example by passing a mem= boot argument.
|
||||
@@ -746,6 +805,12 @@ static int vpe_run(struct vpe * v)
|
||||
}
|
||||
|
||||
/* Write the address we want it to start running from in the TCPC register. */
|
||||
+#if defined(CONFIG_IFX_VPE_EXT) && 0
|
||||
+ if (stlb)
|
||||
+ write_vpe_c0_wired(vpe0_wired + vpe1_wired);
|
||||
+ else
|
||||
+ write_vpe_c0_wired(vpe1_wired);
|
||||
+#endif
|
||||
write_tc_c0_tcrestart((unsigned long)v->__start);
|
||||
write_tc_c0_tccontext((unsigned long)0);
|
||||
|
||||
@@ -759,6 +824,20 @@ static int vpe_run(struct vpe * v)
|
||||
|
||||
write_tc_c0_tchalt(read_tc_c0_tchalt() & ~TCHALT_H);
|
||||
|
||||
+#if defined(CONFIG_IFX_VPE_EXT) && 0
|
||||
+ /*
|
||||
+ * $a2 & $a3 are used to pass command line parameters to VPE1. $a2
|
||||
+ * points to the start of the command line string and $a3 points to
|
||||
+ * the end of the string. This convention is identical to the Linux
|
||||
+ * kernel boot parameter passing mechanism. Please note that $a3 is
|
||||
+ * used to pass physical memory size or 0 in SDE tool kit. So, if you
|
||||
+ * are passing comand line parameters through $a2 & $a3 SDE programs
|
||||
+ * don't work as desired.
|
||||
+ */
|
||||
+ mttgpr(6, command_line);
|
||||
+ mttgpr(7, (command_line + strlen(command_line)));
|
||||
+ if (is_sdepgm)
|
||||
+#endif
|
||||
/*
|
||||
* The sde-kit passes 'memsize' to __start in $a3, so set something
|
||||
* here... Or set $a3 to zero and define DFLT_STACK_SIZE and
|
||||
@@ -833,6 +912,9 @@ static int find_vpe_symbols(struct vpe *
|
||||
if ( (v->__start == 0) || (v->shared_ptr == NULL))
|
||||
return -1;
|
||||
|
||||
+#ifdef CONFIG_IFX_VPE_EXT
|
||||
+ is_sdepgm = 1;
|
||||
+#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -994,6 +1076,15 @@ static int vpe_elfload(struct vpe * v)
|
||||
(unsigned long)v->load_addr + v->len);
|
||||
|
||||
if ((find_vpe_symbols(v, sechdrs, symindex, strtab, &mod)) < 0) {
|
||||
+#ifdef CONFIG_IFX_VPE_EXT
|
||||
+ if (vpe1_load_addr) {
|
||||
+ /* Conversion to KSEG1 is required ??? */
|
||||
+ v->__start = KSEG1ADDR(vpe1_load_addr);
|
||||
+ is_sdepgm = 0;
|
||||
+ return 0;
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
if (v->__start == 0) {
|
||||
printk(KERN_WARNING "VPE loader: program does not contain "
|
||||
"a __start symbol\n");
|
||||
@@ -1064,6 +1155,9 @@ static int vpe_open(struct inode *inode,
|
||||
struct vpe_notifications *not;
|
||||
struct vpe *v;
|
||||
int ret;
|
||||
+#ifdef CONFIG_IFX_VPE_EXT
|
||||
+ int progsize;
|
||||
+#endif
|
||||
|
||||
if (minor != iminor(inode)) {
|
||||
/* assume only 1 device at the moment. */
|
||||
@@ -1089,7 +1183,12 @@ static int vpe_open(struct inode *inode,
|
||||
release_progmem(v->load_addr);
|
||||
cleanup_tc(get_tc(tclimit));
|
||||
}
|
||||
-
|
||||
+#ifdef CONFIG_IFX_VPE_EXT
|
||||
+ progsize = (vpe1_mem != 0) ? vpe1_mem : P_SIZE;
|
||||
+ //printk("progsize = %x\n", progsize);
|
||||
+ v->pbuffer = vmalloc(progsize);
|
||||
+ v->plen = progsize;
|
||||
+#else
|
||||
/* this of-course trashes what was there before... */
|
||||
v->pbuffer = vmalloc(P_SIZE);
|
||||
if (!v->pbuffer) {
|
||||
@@ -1097,11 +1196,14 @@ static int vpe_open(struct inode *inode,
|
||||
return -ENOMEM;
|
||||
}
|
||||
v->plen = P_SIZE;
|
||||
+#endif
|
||||
v->load_addr = NULL;
|
||||
v->len = 0;
|
||||
|
||||
+#if 0
|
||||
v->uid = filp->f_cred->fsuid;
|
||||
v->gid = filp->f_cred->fsgid;
|
||||
+#endif
|
||||
|
||||
#ifdef CONFIG_MIPS_APSP_KSPD
|
||||
/* get kspd to tell us when a syscall_exit happens */
|
||||
@@ -1349,6 +1451,133 @@ static void kspd_sp_exit( int sp_id)
|
||||
cleanup_tc(get_tc(sp_id));
|
||||
}
|
||||
#endif
|
||||
+#ifdef CONFIG_IFX_VPE_EXT
|
||||
+int32_t vpe1_sw_start(void* sw_start_addr, uint32_t tcmask, uint32_t flags)
|
||||
+{
|
||||
+ enum vpe_state state;
|
||||
+ struct vpe *v = get_vpe(tclimit);
|
||||
+ struct vpe_notifications *not;
|
||||
+
|
||||
+ if (tcmask || flags) {
|
||||
+ printk(KERN_WARNING "Currently tcmask and flags should be 0.\
|
||||
+ other values not supported\n");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ state = xchg(&v->state, VPE_STATE_INUSE);
|
||||
+ if (state != VPE_STATE_UNUSED) {
|
||||
+ vpe_stop(v);
|
||||
+
|
||||
+ list_for_each_entry(not, &v->notify, list) {
|
||||
+ not->stop(tclimit);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ v->__start = (unsigned long)sw_start_addr;
|
||||
+ is_sdepgm = 0;
|
||||
+
|
||||
+ if (!vpe_run(v)) {
|
||||
+ printk(KERN_DEBUG "VPE loader: VPE1 running successfully\n");
|
||||
+ return 0;
|
||||
+ }
|
||||
+ return -1;
|
||||
+}
|
||||
+
|
||||
+EXPORT_SYMBOL(vpe1_sw_start);
|
||||
+
|
||||
+int32_t vpe1_sw_stop(uint32_t flags)
|
||||
+{
|
||||
+ struct vpe *v = get_vpe(tclimit);
|
||||
+
|
||||
+ if (!vpe_free(v)) {
|
||||
+ printk(KERN_DEBUG "RP Stopped\n");
|
||||
+ return 0;
|
||||
+ }
|
||||
+ else
|
||||
+ return -1;
|
||||
+}
|
||||
+
|
||||
+EXPORT_SYMBOL(vpe1_sw_stop);
|
||||
+
|
||||
+uint32_t vpe1_get_load_addr (uint32_t flags)
|
||||
+{
|
||||
+ return vpe1_load_addr;
|
||||
+}
|
||||
+
|
||||
+EXPORT_SYMBOL(vpe1_get_load_addr);
|
||||
+
|
||||
+uint32_t vpe1_get_max_mem (uint32_t flags)
|
||||
+{
|
||||
+ if (!vpe1_mem)
|
||||
+ return P_SIZE;
|
||||
+ else
|
||||
+ return vpe1_mem;
|
||||
+}
|
||||
+
|
||||
+EXPORT_SYMBOL(vpe1_get_max_mem);
|
||||
+
|
||||
+void* vpe1_get_cmdline_argument(void)
|
||||
+{
|
||||
+ return saved_command_line;
|
||||
+}
|
||||
+
|
||||
+EXPORT_SYMBOL(vpe1_get_cmdline_argument);
|
||||
+
|
||||
+int32_t vpe1_set_boot_param(char *field, char *value, char flags)
|
||||
+{
|
||||
+ char *ptr, string[64];
|
||||
+ int start_off, end_off;
|
||||
+ if (!field)
|
||||
+ return -1;
|
||||
+ strcpy(string, field);
|
||||
+ if (value) {
|
||||
+ strcat(string, "=");
|
||||
+ strcat(string, value);
|
||||
+ strcat(command_line, " ");
|
||||
+ strcat(command_line, string);
|
||||
+ }
|
||||
+ else {
|
||||
+ ptr = strstr(command_line, string);
|
||||
+ if (ptr) {
|
||||
+ start_off = ptr - command_line;
|
||||
+ ptr += strlen(string);
|
||||
+ while ((*ptr != ' ') && (*ptr != '\0'))
|
||||
+ ptr++;
|
||||
+ end_off = ptr - command_line;
|
||||
+ command_line[start_off] = '\0';
|
||||
+ strcat (command_line, command_line+end_off);
|
||||
+ }
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+EXPORT_SYMBOL(vpe1_set_boot_param);
|
||||
+
|
||||
+int32_t vpe1_get_boot_param(char *field, char **value, char flags)
|
||||
+{
|
||||
+ char *ptr, string[64];
|
||||
+ int i = 0;
|
||||
+ if (!field)
|
||||
+ return -1;
|
||||
+ if ((ptr = strstr(command_line, field))) {
|
||||
+ ptr += strlen(field) + 1; /* including = */
|
||||
+ while ((*ptr != ' ') && (*ptr != '\0'))
|
||||
+ string[i++] = *ptr++;
|
||||
+ string[i] = '\0';
|
||||
+ *value = kmalloc((strlen(string) + 1), GFP_KERNEL);
|
||||
+ if (*value != NULL)
|
||||
+ strcpy(*value, string);
|
||||
+ }
|
||||
+ else
|
||||
+ *value = NULL;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+EXPORT_SYMBOL(vpe1_get_boot_param);
|
||||
+
|
||||
+extern void configure_tlb(void);
|
||||
+#endif
|
||||
|
||||
static ssize_t store_kill(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t len)
|
||||
@@ -1430,6 +1659,18 @@ static int __init vpe_module_init(void)
|
||||
printk("VPE loader: not a MIPS MT capable processor\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
+#ifdef CONFIG_IFX_VPE_EXT
|
||||
+#ifndef CONFIG_MIPS_MT_SMTC
|
||||
+ configure_tlb();
|
||||
+#endif
|
||||
+#endif
|
||||
+
|
||||
+#ifndef CONFIG_MIPS_MT_SMTC
|
||||
+ if (!vpelimit)
|
||||
+ vpelimit = 1;
|
||||
+ if (!tclimit)
|
||||
+ tclimit = 1;
|
||||
+#endif
|
||||
|
||||
if (vpelimit == 0) {
|
||||
printk(KERN_WARNING "No VPEs reserved for AP/SP, not "
|
||||
@@ -1474,10 +1715,12 @@ static int __init vpe_module_init(void)
|
||||
mtflags = dmt();
|
||||
vpflags = dvpe();
|
||||
|
||||
+ back_to_back_c0_hazard();
|
||||
+
|
||||
/* Put MVPE's into 'configuration state' */
|
||||
set_c0_mvpcontrol(MVPCONTROL_VPC);
|
||||
|
||||
- /* dump_mtregs(); */
|
||||
+ dump_mtregs();
|
||||
|
||||
val = read_c0_mvpconf0();
|
||||
hw_tcs = (val & MVPCONF0_PTC) + 1;
|
||||
@@ -1489,6 +1732,7 @@ static int __init vpe_module_init(void)
|
||||
* reschedule send IPIs or similar we might hang.
|
||||
*/
|
||||
clear_c0_mvpcontrol(MVPCONTROL_VPC);
|
||||
+ back_to_back_c0_hazard();
|
||||
evpe(vpflags);
|
||||
emt(mtflags);
|
||||
local_irq_restore(flags);
|
||||
@@ -1514,6 +1758,7 @@ static int __init vpe_module_init(void)
|
||||
}
|
||||
|
||||
v->ntcs = hw_tcs - tclimit;
|
||||
+ write_tc_c0_tcbind((read_tc_c0_tcbind() & ~TCBIND_CURVPE) | 1);
|
||||
|
||||
/* add the tc to the list of this vpe's tc's. */
|
||||
list_add(&t->tc, &v->tc);
|
||||
@@ -1582,6 +1827,7 @@ static int __init vpe_module_init(void)
|
||||
out_reenable:
|
||||
/* release config state */
|
||||
clear_c0_mvpcontrol(MVPCONTROL_VPC);
|
||||
+ back_to_back_c0_hazard();
|
||||
|
||||
evpe(vpflags);
|
||||
emt(mtflags);
|
|
@ -10,10 +10,8 @@ Subject: [PATCH 20/24] MIPS: lantiq: adds falcon VPE softdog
|
|||
create mode 100644 arch/mips/include/asm/mach-lantiq/falcon/vpe.h
|
||||
create mode 100644 arch/mips/lantiq/falcon/softdog_vpe.c
|
||||
|
||||
Index: linux-3.0.3/arch/mips/include/asm/mach-lantiq/falcon/vpe.h
|
||||
===================================================================
|
||||
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
||||
+++ linux-3.0.3/arch/mips/include/asm/mach-lantiq/falcon/vpe.h 2011-10-05 13:26:22.732981532 +0200
|
||||
--- /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
|
||||
|
@ -59,10 +57,8 @@ Index: linux-3.0.3/arch/mips/include/asm/mach-lantiq/falcon/vpe.h
|
|||
+int32_t vpe1_sw_wdog_register_reset_handler(VPE_SW_WDOG_RESET reset_fn);
|
||||
+
|
||||
+#endif
|
||||
Index: linux-3.0.3/arch/mips/lantiq/falcon/softdog_vpe.c
|
||||
===================================================================
|
||||
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
||||
+++ linux-3.0.3/arch/mips/lantiq/falcon/softdog_vpe.c 2011-10-05 13:26:22.736981533 +0200
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/lantiq/falcon/softdog_vpe.c
|
||||
@@ -0,0 +1,109 @@
|
||||
+/*
|
||||
+** =============================================================================
|
||||
|
@ -173,10 +169,8 @@ Index: linux-3.0.3/arch/mips/lantiq/falcon/softdog_vpe.c
|
|||
+MODULE_AUTHOR("LXDB");
|
||||
+MODULE_DESCRIPTION("Software Watchdog For VPE1");
|
||||
+MODULE_LICENSE("GPL");
|
||||
Index: linux-3.0.3/arch/mips/lantiq/falcon/Makefile
|
||||
===================================================================
|
||||
--- linux-3.0.3.orig/arch/mips/lantiq/falcon/Makefile 2011-10-05 13:38:41.801013127 +0200
|
||||
+++ linux-3.0.3/arch/mips/lantiq/falcon/Makefile 2011-10-05 13:38:47.341013363 +0200
|
||||
--- 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 := clk.o prom.o reset.o sysctrl.o devices.o gpio.o softdog_vpe.o
|
|
@ -9,11 +9,9 @@ Subject: [PATCH 21/24] MIPS: lantiq: adds cache split
|
|||
arch/mips/mm/c-r4k.c | 172 ++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 260 insertions(+), 0 deletions(-)
|
||||
|
||||
Index: linux-3.0.3/arch/mips/Kconfig
|
||||
===================================================================
|
||||
--- linux-3.0.3.orig/arch/mips/Kconfig 2011-10-05 12:53:54.792898260 +0200
|
||||
+++ linux-3.0.3/arch/mips/Kconfig 2011-10-05 12:53:54.852898263 +0200
|
||||
@@ -1913,6 +1913,28 @@
|
||||
--- a/arch/mips/Kconfig
|
||||
+++ b/arch/mips/Kconfig
|
||||
@@ -1922,6 +1922,28 @@ config IFX_VPE_EXT
|
||||
help
|
||||
IFX included extensions in APRP
|
||||
|
||||
|
@ -42,11 +40,9 @@ Index: linux-3.0.3/arch/mips/Kconfig
|
|||
config PERFCTRS
|
||||
bool "34K Performance counters"
|
||||
depends on MIPS_MT && PROC_FS
|
||||
Index: linux-3.0.3/arch/mips/kernel/vpe.c
|
||||
===================================================================
|
||||
--- linux-3.0.3.orig/arch/mips/kernel/vpe.c 2011-10-05 12:53:54.800898262 +0200
|
||||
+++ linux-3.0.3/arch/mips/kernel/vpe.c 2011-10-05 12:53:54.852898263 +0200
|
||||
@@ -128,6 +128,13 @@
|
||||
--- a/arch/mips/kernel/vpe.c
|
||||
+++ b/arch/mips/kernel/vpe.c
|
||||
@@ -128,6 +128,13 @@ __setup("vpe1_wdog_timeout=", wdog_timeo
|
||||
EXPORT_SYMBOL(vpe1_wdog_timeout);
|
||||
|
||||
#endif
|
||||
|
@ -60,7 +56,7 @@ Index: linux-3.0.3/arch/mips/kernel/vpe.c
|
|||
/* grab the likely amount of memory we will need. */
|
||||
#ifdef CONFIG_MIPS_VPE_LOADER_TOM
|
||||
#define P_SIZE (2 * 1024 * 1024)
|
||||
@@ -866,6 +873,65 @@
|
||||
@@ -866,6 +873,65 @@ static int vpe_run(struct vpe * v)
|
||||
/* enable this VPE */
|
||||
write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() | VPECONF0_VPA);
|
||||
|
||||
|
@ -126,11 +122,9 @@ Index: linux-3.0.3/arch/mips/kernel/vpe.c
|
|||
/* clear out any left overs from a previous program */
|
||||
write_vpe_c0_status(0);
|
||||
write_vpe_c0_cause(0);
|
||||
Index: linux-3.0.3/arch/mips/mm/c-r4k.c
|
||||
===================================================================
|
||||
--- linux-3.0.3.orig/arch/mips/mm/c-r4k.c 2011-08-17 19:57:16.000000000 +0200
|
||||
+++ linux-3.0.3/arch/mips/mm/c-r4k.c 2011-10-05 12:53:54.852898263 +0200
|
||||
@@ -1346,6 +1346,106 @@
|
||||
--- a/arch/mips/mm/c-r4k.c
|
||||
+++ b/arch/mips/mm/c-r4k.c
|
||||
@@ -1350,6 +1350,106 @@ static int __init setcoherentio(char *st
|
||||
__setup("coherentio", setcoherentio);
|
||||
#endif
|
||||
|
||||
|
@ -237,7 +231,7 @@ Index: linux-3.0.3/arch/mips/mm/c-r4k.c
|
|||
void __cpuinit r4k_cache_init(void)
|
||||
{
|
||||
extern void build_clear_page(void);
|
||||
@@ -1365,6 +1465,78 @@
|
||||
@@ -1369,6 +1469,78 @@ void __cpuinit r4k_cache_init(void)
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -316,10 +310,8 @@ Index: linux-3.0.3/arch/mips/mm/c-r4k.c
|
|||
probe_pcache();
|
||||
setup_scache();
|
||||
|
||||
Index: linux-3.0.3/arch/mips/lantiq/setup.c
|
||||
===================================================================
|
||||
--- linux-3.0.3.orig/arch/mips/lantiq/setup.c 2011-10-05 13:20:49.808967301 +0200
|
||||
+++ linux-3.0.3/arch/mips/lantiq/setup.c 2011-10-05 13:23:27.796974054 +0200
|
||||
--- a/arch/mips/lantiq/setup.c
|
||||
+++ b/arch/mips/lantiq/setup.c
|
||||
@@ -18,10 +18,11 @@
|
||||
#include "devices.h"
|
||||
#include "prom.h"
|
||||
|
@ -334,7 +326,7 @@ Index: linux-3.0.3/arch/mips/lantiq/setup.c
|
|||
char **envp = (char **) KSEG1ADDR(fw_arg2);
|
||||
|
||||
ioport_resource.start = IOPORT_RESOURCE_START;
|
||||
@@ -35,13 +36,13 @@
|
||||
@@ -35,13 +36,13 @@ void __init plat_mem_setup(void)
|
||||
char *e = (char *)KSEG1ADDR(*envp);
|
||||
if (!strncmp(e, "memsize=", 8)) {
|
||||
e += 8;
|
|
@ -13,9 +13,6 @@ Subject: [PATCH 22/24] MIPS: lantiq: adds udp in-kernel redirect
|
|||
create mode 100644 include/linux/udp_redirect.h
|
||||
create mode 100644 net/ipv4/udp_redirect_symb.c
|
||||
|
||||
diff --git a/include/linux/udp_redirect.h b/include/linux/udp_redirect.h
|
||||
new file mode 100644
|
||||
index 0000000..de1e64f
|
||||
--- /dev/null
|
||||
+++ b/include/linux/udp_redirect.h
|
||||
@@ -0,0 +1,57 @@
|
||||
|
@ -76,8 +73,6 @@ index 0000000..de1e64f
|
|||
+extern int udpredirect_getfrag(void *p, char * to, int offset,
|
||||
+ int fraglen, int odd, struct sk_buff *skb);
|
||||
+#endif
|
||||
diff --git a/net/Kconfig b/net/Kconfig
|
||||
index a073148..d13e3fa 100644
|
||||
--- a/net/Kconfig
|
||||
+++ b/net/Kconfig
|
||||
@@ -72,6 +72,12 @@ config INET
|
||||
|
@ -93,11 +88,9 @@ index a073148..d13e3fa 100644
|
|||
if INET
|
||||
source "net/ipv4/Kconfig"
|
||||
source "net/ipv6/Kconfig"
|
||||
diff --git a/net/ipv4/Makefile b/net/ipv4/Makefile
|
||||
index f2dc69c..6badd72 100644
|
||||
--- a/net/ipv4/Makefile
|
||||
+++ b/net/ipv4/Makefile
|
||||
@@ -14,6 +14,9 @@ obj-y := route.o inetpeer.o protocol.o \
|
||||
@@ -14,6 +14,9 @@ obj-y := route.o inetpeer.o protocol
|
||||
inet_fragment.o ping.o
|
||||
|
||||
obj-$(CONFIG_SYSCTL) += sysctl_net_ipv4.o
|
||||
|
@ -107,8 +100,6 @@ index f2dc69c..6badd72 100644
|
|||
obj-$(CONFIG_PROC_FS) += proc.o
|
||||
obj-$(CONFIG_IP_MULTIPLE_TABLES) += fib_rules.o
|
||||
obj-$(CONFIG_IP_MROUTE) += ipmr.o
|
||||
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
|
||||
index 1b5a193..4d15cf6 100644
|
||||
--- a/net/ipv4/udp.c
|
||||
+++ b/net/ipv4/udp.c
|
||||
@@ -108,6 +108,10 @@
|
||||
|
@ -122,7 +113,7 @@ index 1b5a193..4d15cf6 100644
|
|||
struct udp_table udp_table __read_mostly;
|
||||
EXPORT_SYMBOL(udp_table);
|
||||
|
||||
@@ -803,7 +807,7 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
|
||||
@@ -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;
|
||||
|
@ -131,7 +122,7 @@ index 1b5a193..4d15cf6 100644
|
|||
struct sk_buff *skb;
|
||||
struct ip_options_data opt_copy;
|
||||
|
||||
@@ -820,7 +824,13 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
|
||||
@@ -820,7 +824,13 @@ int udp_sendmsg(struct kiocb *iocb, stru
|
||||
ipc.opt = NULL;
|
||||
ipc.tx_flags = 0;
|
||||
|
||||
|
@ -146,7 +137,7 @@ index 1b5a193..4d15cf6 100644
|
|||
|
||||
fl4 = &inet->cork.fl.u.ip4;
|
||||
if (up->pending) {
|
||||
@@ -1621,6 +1631,7 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
|
||||
@@ -1621,6 +1631,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);
|
||||
|
@ -154,7 +145,7 @@ index 1b5a193..4d15cf6 100644
|
|||
|
||||
/*
|
||||
* Validate the packet.
|
||||
@@ -1653,7 +1664,16 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
|
||||
@@ -1653,7 +1664,16 @@ int __udp4_lib_rcv(struct sk_buff *skb,
|
||||
sk = __udp4_lib_lookup_skb(skb, uh->source, uh->dest, udptable);
|
||||
|
||||
if (sk != NULL) {
|
||||
|
@ -181,9 +172,6 @@ index 1b5a193..4d15cf6 100644
|
|||
/* ------------------------------------------------------------------------ */
|
||||
#ifdef CONFIG_PROC_FS
|
||||
|
||||
diff --git a/net/ipv4/udp_redirect_symb.c b/net/ipv4/udp_redirect_symb.c
|
||||
new file mode 100644
|
||||
index 0000000..5617e86
|
||||
--- /dev/null
|
||||
+++ b/net/ipv4/udp_redirect_symb.c
|
||||
@@ -0,0 +1,186 @@
|
||||
|
@ -373,6 +361,3 @@ index 0000000..5617e86
|
|||
+EXPORT_SYMBOL(udp_do_redirect_fn);
|
||||
+EXPORT_SYMBOL(udpredirect_getfrag_fn);
|
||||
+#endif /* CONFIG_IFX_UDP_REDIRECT* */
|
||||
--
|
||||
1.7.5.4
|
||||
|
|
@ -19,10 +19,8 @@ Subject: [PATCH 23/24] MIPS: lantiq: adds basic vr9 support
|
|||
create mode 100644 arch/mips/lantiq/xway/mach-fritz.c
|
||||
create mode 100644 arch/mips/lantiq/xway/prom-vr9.c
|
||||
|
||||
Index: linux-3.0.3/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
|
||||
===================================================================
|
||||
--- linux-3.0.3.orig/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h 2011-10-04 20:05:48.000000000 +0200
|
||||
+++ linux-3.0.3/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h 2011-10-04 20:05:54.234312800 +0200
|
||||
--- 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,7 @@
|
||||
#define SOC_ID_ARX188 0x16C
|
||||
#define SOC_ID_ARX168 0x16D
|
||||
|
@ -39,10 +37,8 @@ Index: linux-3.0.3/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
|
|||
#define LTQ_ETOP_SIZE 0x40000
|
||||
|
||||
/* GBIT - gigabit switch */
|
||||
Index: linux-3.0.3/arch/mips/lantiq/Kconfig
|
||||
===================================================================
|
||||
--- linux-3.0.3.orig/arch/mips/lantiq/Kconfig 2011-10-04 20:03:54.000000000 +0200
|
||||
+++ linux-3.0.3/arch/mips/lantiq/Kconfig 2011-10-04 20:05:54.238312800 +0200
|
||||
--- a/arch/mips/lantiq/Kconfig
|
||||
+++ b/arch/mips/lantiq/Kconfig
|
||||
@@ -1,5 +1,8 @@
|
||||
if LANTIQ
|
||||
|
||||
|
@ -52,7 +48,7 @@ Index: linux-3.0.3/arch/mips/lantiq/Kconfig
|
|||
config SOC_TYPE_XWAY
|
||||
bool
|
||||
default n
|
||||
@@ -17,6 +20,12 @@
|
||||
@@ -17,6 +20,12 @@ config SOC_XWAY
|
||||
select SOC_TYPE_XWAY
|
||||
select HW_HAS_PCI
|
||||
|
||||
|
@ -65,21 +61,17 @@ Index: linux-3.0.3/arch/mips/lantiq/Kconfig
|
|||
config SOC_FALCON
|
||||
bool "FALCON"
|
||||
endchoice
|
||||
Index: linux-3.0.3/arch/mips/lantiq/Platform
|
||||
===================================================================
|
||||
--- linux-3.0.3.orig/arch/mips/lantiq/Platform 2011-10-04 20:03:54.000000000 +0200
|
||||
+++ linux-3.0.3/arch/mips/lantiq/Platform 2011-10-04 20:05:54.238312800 +0200
|
||||
@@ -6,4 +6,5 @@
|
||||
--- a/arch/mips/lantiq/Platform
|
||||
+++ b/arch/mips/lantiq/Platform
|
||||
@@ -6,4 +6,5 @@ platform-$(CONFIG_LANTIQ) += lantiq/
|
||||
cflags-$(CONFIG_LANTIQ) += -I$(srctree)/arch/mips/include/asm/mach-lantiq
|
||||
load-$(CONFIG_LANTIQ) = 0xffffffff80002000
|
||||
cflags-$(CONFIG_SOC_TYPE_XWAY) += -I$(srctree)/arch/mips/include/asm/mach-lantiq/xway
|
||||
+cflags-$(CONFIG_SOC_TYPE_VR9) += -I$(srctree)/arch/mips/include/asm/mach-lantiq/xway
|
||||
cflags-$(CONFIG_SOC_FALCON) += -I$(srctree)/arch/mips/include/asm/mach-lantiq/falcon
|
||||
Index: linux-3.0.3/arch/mips/lantiq/machtypes.h
|
||||
===================================================================
|
||||
--- linux-3.0.3.orig/arch/mips/lantiq/machtypes.h 2011-10-04 20:03:54.000000000 +0200
|
||||
+++ linux-3.0.3/arch/mips/lantiq/machtypes.h 2011-10-04 20:05:54.238312800 +0200
|
||||
@@ -20,6 +20,9 @@
|
||||
--- a/arch/mips/lantiq/machtypes.h
|
||||
+++ b/arch/mips/lantiq/machtypes.h
|
||||
@@ -20,6 +20,9 @@ enum lantiq_mach_type {
|
||||
LANTIQ_MACH_EASY98000, /* Falcon Eval Board, NOR Flash */
|
||||
LANTIQ_MACH_EASY98000SF, /* Falcon Eval Board, Serial Flash */
|
||||
LANTIQ_MACH_EASY98000NAND, /* Falcon Eval Board, NAND Flash */
|
||||
|
@ -89,11 +81,9 @@ Index: linux-3.0.3/arch/mips/lantiq/machtypes.h
|
|||
};
|
||||
|
||||
#endif
|
||||
Index: linux-3.0.3/arch/mips/lantiq/xway/Kconfig
|
||||
===================================================================
|
||||
--- linux-3.0.3.orig/arch/mips/lantiq/xway/Kconfig 2011-08-17 19:57:16.000000000 +0200
|
||||
+++ linux-3.0.3/arch/mips/lantiq/xway/Kconfig 2011-10-04 20:05:54.238312800 +0200
|
||||
@@ -21,3 +21,15 @@
|
||||
--- a/arch/mips/lantiq/xway/Kconfig
|
||||
+++ b/arch/mips/lantiq/xway/Kconfig
|
||||
@@ -21,3 +21,15 @@ config LANTIQ_MACH_EASY50601
|
||||
endmenu
|
||||
|
||||
endif
|
||||
|
@ -109,11 +99,9 @@ Index: linux-3.0.3/arch/mips/lantiq/xway/Kconfig
|
|||
+endmenu
|
||||
+
|
||||
+endif
|
||||
Index: linux-3.0.3/arch/mips/lantiq/xway/Makefile
|
||||
===================================================================
|
||||
--- linux-3.0.3.orig/arch/mips/lantiq/xway/Makefile 2011-10-04 20:05:50.000000000 +0200
|
||||
+++ linux-3.0.3/arch/mips/lantiq/xway/Makefile 2011-10-04 20:05:54.238312800 +0200
|
||||
@@ -2,6 +2,8 @@
|
||||
--- a/arch/mips/lantiq/xway/Makefile
|
||||
+++ b/arch/mips/lantiq/xway/Makefile
|
||||
@@ -2,6 +2,8 @@ obj-y := sysctrl.o reset.o gpio.o gpio_s
|
||||
|
||||
obj-$(CONFIG_SOC_XWAY) += clk-xway.o prom-xway.o
|
||||
obj-$(CONFIG_SOC_AMAZON_SE) += clk-ase.o prom-ase.o
|
||||
|
@ -122,10 +110,8 @@ Index: linux-3.0.3/arch/mips/lantiq/xway/Makefile
|
|||
obj-$(CONFIG_LANTIQ_MACH_EASY50712) += mach-easy50712.o
|
||||
obj-$(CONFIG_LANTIQ_MACH_EASY50601) += mach-easy50601.o
|
||||
+obj-$(CONFIG_LANTIQ_MACH_FRITZ3370) += mach-fritz.o
|
||||
Index: linux-3.0.3/arch/mips/lantiq/xway/clk-vr9.c
|
||||
===================================================================
|
||||
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
||||
+++ linux-3.0.3/arch/mips/lantiq/xway/clk-vr9.c 2011-10-04 20:05:54.238312800 +0200
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/lantiq/xway/clk-vr9.c
|
||||
@@ -0,0 +1,78 @@
|
||||
+/*
|
||||
+ * This program is free software; you can redistribute it and/or modify it
|
||||
|
@ -205,10 +191,8 @@ Index: linux-3.0.3/arch/mips/lantiq/xway/clk-vr9.c
|
|||
+ return ltq_get_fpi_hz();
|
||||
+}
|
||||
+EXPORT_SYMBOL(ltq_get_fpi_bus_clock);
|
||||
Index: linux-3.0.3/arch/mips/lantiq/xway/prom-vr9.c
|
||||
===================================================================
|
||||
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
||||
+++ linux-3.0.3/arch/mips/lantiq/xway/prom-vr9.c 2011-10-04 20:05:54.238312800 +0200
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/lantiq/xway/prom-vr9.c
|
||||
@@ -0,0 +1,55 @@
|
||||
+/*
|
||||
+ * This program is free software; you can redistribute it and/or modify it
|
||||
|
@ -265,11 +249,9 @@ Index: linux-3.0.3/arch/mips/lantiq/xway/prom-vr9.c
|
|||
+ ltq_register_gpio();
|
||||
+ ltq_register_wdt();
|
||||
+}
|
||||
Index: linux-3.0.3/arch/mips/pci/Makefile
|
||||
===================================================================
|
||||
--- linux-3.0.3.orig/arch/mips/pci/Makefile 2011-08-17 19:57:16.000000000 +0200
|
||||
+++ linux-3.0.3/arch/mips/pci/Makefile 2011-10-04 20:05:54.238312800 +0200
|
||||
@@ -41,7 +41,7 @@
|
||||
--- a/arch/mips/pci/Makefile
|
||||
+++ b/arch/mips/pci/Makefile
|
||||
@@ -41,7 +41,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
|
|
@ -0,0 +1,36 @@
|
|||
From 2dfa2b3e50c5ac49052233d15fa427a9b9136df8 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Thu, 27 Oct 2011 20:06:05 +0200
|
||||
Subject: [PATCH 10/22] MIPS: lantiq: fixes STP based gpios
|
||||
|
||||
The STP engine has 3 groups of 8 pins. Only the first was activated by default.
|
||||
|
||||
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);
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue