aboutsummaryrefslogtreecommitdiffstats
path: root/recipes/linux/linux-2.6.34/ts72xx/0008-ts72xx_ts_eth100.patch
diff options
context:
space:
mode:
Diffstat (limited to 'recipes/linux/linux-2.6.34/ts72xx/0008-ts72xx_ts_eth100.patch')
-rw-r--r--recipes/linux/linux-2.6.34/ts72xx/0008-ts72xx_ts_eth100.patch273
1 files changed, 273 insertions, 0 deletions
diff --git a/recipes/linux/linux-2.6.34/ts72xx/0008-ts72xx_ts_eth100.patch b/recipes/linux/linux-2.6.34/ts72xx/0008-ts72xx_ts_eth100.patch
new file mode 100644
index 0000000000..75d53039da
--- /dev/null
+++ b/recipes/linux/linux-2.6.34/ts72xx/0008-ts72xx_ts_eth100.patch
@@ -0,0 +1,273 @@
+From 9a9465369f2fdbd22b68e545b4744b8dca1608ff Mon Sep 17 00:00:00 2001
+From: Matthieu Crapet <mcrapet@gmail.com>
+Date: Fri, 18 Jun 2010 17:39:09 +0200
+Subject: [PATCH 08/18] ts72xx_ts_eth100
+
+TS-ETH100 - 10/100 Ethernet PC/104 peripheral
+---
+ drivers/net/Kconfig | 10 ++
+ drivers/net/Makefile | 1 +
+ drivers/net/ax88796.c | 8 ++-
+ drivers/net/ax88796_ts_eth100.c | 190 +++++++++++++++++++++++++++++++++++++++
+ 4 files changed, 208 insertions(+), 1 deletions(-)
+ create mode 100644 drivers/net/ax88796_ts_eth100.c
+
+diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
+index 7b832c7..f812332 100644
+--- a/drivers/net/Kconfig
++++ b/drivers/net/Kconfig
+@@ -248,6 +248,16 @@ config AX88796_93CX6
+ help
+ Select this if your platform comes with an external 93CX6 eeprom.
+
++config AX88796_TS_ETH100
++ tristate "Support for TS-ETH100 (TS-72XX SBC)"
++ depends on AX88796 && MACH_TS72XX
++ help
++ Say Y here if you have a TS-ETH100 PC/104 peripheral.
++ IRQ numbers and I/O address will be configurated automatically.
++
++ To compile this driver as a module, choose M here: the module
++ will be called ax88796_ts_eth100.
++
+ config MACE
+ tristate "MACE (Power Mac ethernet) support"
+ depends on PPC_PMAC && PPC32
+diff --git a/drivers/net/Makefile b/drivers/net/Makefile
+index 12b280a..cb448fa 100644
+--- a/drivers/net/Makefile
++++ b/drivers/net/Makefile
+@@ -143,6 +143,7 @@ obj-$(CONFIG_B44) += b44.o
+ obj-$(CONFIG_FORCEDETH) += forcedeth.o
+ obj-$(CONFIG_NE_H8300) += ne-h8300.o 8390.o
+ obj-$(CONFIG_AX88796) += ax88796.o
++obj-$(CONFIG_AX88796_TS_ETH100) += ax88796_ts_eth100.o
+ obj-$(CONFIG_BCM63XX_ENET) += bcm63xx_enet.o
+
+ obj-$(CONFIG_TSI108_ETH) += tsi108_eth.o
+diff --git a/drivers/net/ax88796.c b/drivers/net/ax88796.c
+index b718dc6..282fd8e 100644
+--- a/drivers/net/ax88796.c
++++ b/drivers/net/ax88796.c
+@@ -809,7 +809,9 @@ static int ax_remove(struct platform_device *_dev)
+ ax = to_ax_dev(dev);
+
+ unregister_netdev(dev);
+- free_irq(dev->irq, dev);
++ if (ax->running) { // already freed in ax_close?
++ free_irq(dev->irq, dev);
++ }
+
+ iounmap(ei_status.mem);
+ release_resource(ax->mem);
+@@ -935,7 +937,11 @@ static int ax_probe(struct platform_device *pdev)
+ goto exit_mem2;
+ }
+
++ #if defined(CONFIG_AX88796_TS_ETH100) || defined(CONFIG_AX88796_TS_ETH100_MODULE)
++ ei_status.reg_offset[0x10] = ax->map2 - ei_status.mem + 0x10; /* don't know why, but +0x20 works too */
++ #else
+ ei_status.reg_offset[0x1f] = ax->map2 - ei_status.mem;
++ #endif
+ }
+
+ /* got resources, now initialise and register device */
+diff --git a/drivers/net/ax88796_ts_eth100.c b/drivers/net/ax88796_ts_eth100.c
+new file mode 100644
+index 0000000..448b3e3
+--- /dev/null
++++ b/drivers/net/ax88796_ts_eth100.c
+@@ -0,0 +1,190 @@
++/*
++ * linux/drivers/net/ax88796_ts_eth100.c
++ * Technologic Systems TS-ETH100 support.
++ *
++ * (c) Copyright 2008 Matthieu Crapet <mcrapet@gmail.com>
++ *
++ * 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.
++ */
++
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/platform_device.h>
++#include <linux/irq.h>
++#include <linux/io.h>
++#include <net/ax88796.h>
++#include <mach/ts72xx.h>
++#include <mach/gpio.h>
++
++#define TS72XX_ETH100_IO8_PHYS_BASE (TS72XX_PC104_8BIT_IO_PHYS_BASE)
++#define TS72XX_ETH100_IO8_SIZE (TS72XX_PC104_8BIT_IO_SIZE)
++#define TS72XX_ETH100_IO16_PHYS_BASE (TS72XX_PC104_16BIT_IO_PHYS_BASE)
++#define TS72XX_ETH100_IO16_SIZE (TS72XX_PC104_16BIT_IO_SIZE)
++
++/* Technologic systems I/O space */
++#define TS_ETH100_PLD_0 0x100
++#define TS_ETH100_PLD_1 0x110
++#define TS_ETH100_PLD_2 0x120
++#define TS_ETH100_PLD_3 0x130
++
++/* NE2000 I/O space */
++#define TS_ETH100_MAC_0 0x200
++#define TS_ETH100_MAC_1 0x240
++#define TS_ETH100_MAC_2 0x300
++#define TS_ETH100_MAC_3 0x340
++
++/* Board identifier must be 5 ; PLD revision should be 1 */
++#define is_eth100_present(__iomem, __offset) \
++ (((__raw_readb(__iomem + __offset) & 0xF) == 0x5) && \
++ ((__raw_readb(__iomem + __offset + 4) & 0xF) == 0x1))
++
++/* Jumpers status (SRAM control register) */
++#define read_irq(__iomem, __offset) \
++ (__raw_readb(__iomem + __offset + 8) & 0xE)
++
++
++static u32 offsets[0x20] = {
++ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
++ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
++ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
++ 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F
++};
++
++static struct ax_plat_data ts72xx_eth100_asix_data = {
++ .flags = AXFLG_HAS_93CX6,
++ .wordlength = 2,
++ .dcr_val = 0x48,
++ .rcr_val = 0x40,
++ .reg_offsets = offsets,
++};
++
++static struct resource ts72xx_eth100_resource[] = {
++ [0] = {
++ .start = TS72XX_ETH100_IO8_PHYS_BASE,
++ .end = TS72XX_ETH100_IO8_PHYS_BASE + 0x40 - 1,
++ .flags = IORESOURCE_MEM
++ },
++ [1] = { /* 0x10 is NE_DATAPORT is 16-bit access */
++ .start = TS72XX_ETH100_IO16_PHYS_BASE,
++ .end = TS72XX_ETH100_IO16_PHYS_BASE + 0x40 - 1,
++ .flags = IORESOURCE_MEM
++ },
++ [2] = {
++ .start = IRQ_EP93XX_EXT1,
++ .end = IRQ_EP93XX_EXT1,
++ .flags = IORESOURCE_IRQ
++ }
++};
++
++static int ts_eth100_irq; // 2 [IRQ 5], 4 [IRQ 6] or 8 [IRQ 7] (jumper configuration)
++
++
++static void ts72xx_eth100_release(struct device *dev)
++{
++ /* nothing to do (no kfree) because we have static struct */
++}
++
++static struct platform_device ts72xx_eth100_device_asix = {
++ .name = "ax88796",
++ .id = 0,
++ .num_resources = ARRAY_SIZE(ts72xx_eth100_resource),
++ .resource = ts72xx_eth100_resource,
++ .dev = {
++ .platform_data = &ts72xx_eth100_asix_data,
++ .release = ts72xx_eth100_release,
++ }
++};
++
++static int __init ts_eth100_init(void)
++{
++ void __iomem *iomem;
++ struct platform_device *ethX = NULL;
++
++ iomem = ioremap(TS72XX_ETH100_IO8_PHYS_BASE, TS72XX_ETH100_IO8_SIZE);
++ if (iomem != NULL) {
++ ethX = &ts72xx_eth100_device_asix;
++
++ if (is_eth100_present(iomem, TS_ETH100_PLD_0)) {
++ ethX->resource[0].start += TS_ETH100_MAC_0;
++ ethX->resource[0].end += TS_ETH100_MAC_0;
++ ethX->resource[1].start += TS_ETH100_MAC_0;
++ ethX->resource[1].end += TS_ETH100_MAC_0;
++ ts_eth100_irq = read_irq(iomem, TS_ETH100_PLD_0);
++ } else if(is_eth100_present(iomem, TS_ETH100_PLD_1)) {
++ ethX->resource[0].start += TS_ETH100_MAC_1;
++ ethX->resource[0].end += TS_ETH100_MAC_1;
++ ethX->resource[1].start += TS_ETH100_MAC_1;
++ ethX->resource[1].end += TS_ETH100_MAC_1;
++ ts_eth100_irq = read_irq(iomem, TS_ETH100_PLD_1);
++ } else if(is_eth100_present(iomem, TS_ETH100_PLD_2)) {
++ ethX->resource[0].start += TS_ETH100_MAC_2;
++ ethX->resource[0].end += TS_ETH100_MAC_2;
++ ethX->resource[1].start += TS_ETH100_MAC_2;
++ ethX->resource[1].end += TS_ETH100_MAC_2;
++ ts_eth100_irq = read_irq(iomem, TS_ETH100_PLD_2);
++ } else if(is_eth100_present(iomem, TS_ETH100_PLD_3)) {
++ ethX->resource[0].start += TS_ETH100_MAC_3;
++ ethX->resource[0].end += TS_ETH100_MAC_3;
++ ethX->resource[1].start += TS_ETH100_MAC_3;
++ ethX->resource[1].end += TS_ETH100_MAC_3;
++ ts_eth100_irq = read_irq(iomem, TS_ETH100_PLD_3);
++ } else {
++ ethX = NULL;
++ }
++
++ /* Translate IRQ number */
++ if (ethX != NULL) {
++ int ret, irq = 0;
++ switch (ts_eth100_irq) {
++ case 0x2: /* IRQ5 */
++ irq = gpio_to_irq(EP93XX_GPIO_LINE_F(3));
++ ret = gpio_request(irq, "TS-ETH100");
++ if (ret < 0) {
++ ethX = NULL;
++ goto init_error;
++ } else {
++ gpio_direction_input(irq);
++ set_irq_type(irq, IRQ_TYPE_EDGE_RISING);
++ }
++ break;
++ case 0x4: /* IRQ6 */
++ irq = IRQ_EP93XX_EXT1;
++ break;
++ case 0x8: /* IRQ7 */
++ default:
++ irq = IRQ_EP93XX_EXT3;
++ }
++ ethX->resource[2].start = irq;
++ ethX->resource[2].end = irq;
++ }
++init_error:
++ iounmap(iomem);
++ }
++
++ return ((ethX == NULL) ? -ENODEV :
++ platform_device_register(&ts72xx_eth100_device_asix));
++}
++
++
++static void __exit ts_eth100_exit(void)
++{
++ platform_device_unregister(&ts72xx_eth100_device_asix);
++ if (ts_eth100_irq == 2)
++ gpio_free(EP93XX_GPIO_LINE_F(3));
++}
++
++module_init(ts_eth100_init);
++module_exit(ts_eth100_exit);
++
++MODULE_AUTHOR("Matthieu Crapet <mcrapet@gmail.com>");
++MODULE_DESCRIPTION("Asix 88796 ethernet probe module for TS-ETH100 (TS-72xx)");
++MODULE_LICENSE("GPL");
++MODULE_VERSION("0.21");
+--
+1.7.1
+