--- a/arch/arm/mach-cns21xx/Kconfig +++ b/arch/arm/mach-cns21xx/Kconfig @@ -3,6 +3,9 @@ if ARCH_CNS21XX menu "Cavium Networks CNS21xx based machines" endmenu +config CNS21XX_DEV_GEC + def_bool n + config CNS21XX_DEV_USB def_bool n --- a/arch/arm/mach-cns21xx/Makefile +++ b/arch/arm/mach-cns21xx/Makefile @@ -7,6 +7,7 @@ obj-y := core.o irq.o gpio.o mm.o time.o idle.o devices.o # devices +obj-$(CONFIG_CNS21XX_DEV_GEC) += dev-gec.o obj-$(CONFIG_CNS21XX_DEV_USB) += dev-usb.o obj-$(CONFIG_CNS21XX_DEV_SPI_MASTER) += dev-spi-master.o --- /dev/null +++ b/arch/arm/mach-cns21xx/dev-gec.c @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2010-2012 Gabor Juhos <juhosg@openwrt.org> + * + * This file 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/dma-mapping.h> +#include <linux/platform_device.h> +#include <linux/etherdevice.h> + +#include <asm/sizes.h> +#include <mach/cns21xx.h> +#include <mach/irqs.h> + +#include "dev-gec.h" + +static u8 cns21xx_ethaddr[ETH_ALEN]; +struct cns21xx_gec_plat_data cns21xx_gec_data; + +static struct resource cns21xx_gec_resources[] = { + { + .start = CNS21XX_NIC_BASE, + .end = CNS21XX_NIC_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, { + .name = CNS21XX_GEC_STATUS_IRQ_NAME, + .start = CNS21XX_IRQ_NIC_STATUS, + .end = CNS21XX_IRQ_NIC_STATUS, + .flags = IORESOURCE_IRQ, + }, { + .name = CNS21XX_GEC_RXRC_IRQ_NAME, + .start = CNS21XX_IRQ_NIC_RXRC, + .end = CNS21XX_IRQ_NIC_RXRC, + .flags = IORESOURCE_IRQ, + }, { + .name = CNS21XX_GEC_RXQF_IRQ_NAME, + .start = CNS21XX_IRQ_NIC_RXQF, + .end = CNS21XX_IRQ_NIC_RXQF, + .flags = IORESOURCE_IRQ, + }, { + .name = CNS21XX_GEC_TXTC_IRQ_NAME, + .start = CNS21XX_IRQ_NIC_TXTC, + .end = CNS21XX_IRQ_NIC_TXTC, + .flags = IORESOURCE_IRQ, + }, { + .name = CNS21XX_GEC_TXQE_IRQ_NAME, + .start = CNS21XX_IRQ_NIC_TXQE, + .end = CNS21XX_IRQ_NIC_TXQE, + .flags = IORESOURCE_IRQ, + } +}; + +static u64 cns21xx_gec_dmamask = DMA_BIT_MASK(32); +static struct platform_device cns21xx_gec_device = { + .name = "cns21xx-gec", + .id = -1, + .resource = cns21xx_gec_resources, + .num_resources = ARRAY_SIZE(cns21xx_gec_resources), + .dev = { + .dma_mask = &cns21xx_gec_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &cns21xx_gec_data, + }, +}; + +static int __init cns21xx_ethaddr_setup(char *str) +{ + int t; + + t = sscanf(str, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", + &cns21xx_ethaddr[0], &cns21xx_ethaddr[1], + &cns21xx_ethaddr[2], &cns21xx_ethaddr[3], + &cns21xx_ethaddr[4], &cns21xx_ethaddr[5]); + + if (t != ETH_ALEN) + pr_err("cns21xx: failed to parse mac address \"%s\"\n", str); + + return 1; +} + +__setup("ethaddr=", cns21xx_ethaddr_setup); + +__init int cns21xx_register_gec(void) +{ + if (cns21xx_gec_data.mac_addr == NULL) + cns21xx_gec_data.mac_addr = cns21xx_ethaddr; + + if (!is_valid_ether_addr(cns21xx_gec_data.mac_addr)) { + random_ether_addr(cns21xx_gec_data.mac_addr); + pr_debug("cns21xx: using random MAC address \"%s\"\n", + cns21xx_gec_data.mac_addr); + } + + return platform_device_register(&cns21xx_gec_device); +} --- /dev/null +++ b/arch/arm/mach-cns21xx/dev-gec.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2010-2012 Gabor Juhos <juhosg@openwrt.org> + * + * This file 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 _CNS21XX_DEV_GEC_H +#define _CNS21XX_DEV_GEC_H + +#include <mach/cns21xx_gec_platform.h> + +extern struct cns21xx_gec_plat_data cns21xx_gec_data; + +__init int cns21xx_register_gec(void); + +#endif /* _CNS21XX_DEV_GEC_H */ --- /dev/null +++ b/arch/arm/mach-cns21xx/include/mach/cns21xx_gec_platform.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2010-2012 Gabor Juhos <juhosg@openwrt.org> + * + * This file 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 _CNS21XX_GEC_PLATFORM_H +#define _CNS21XX_GEC_PLATFORM_H + +#define CNS21XX_GEC_STATUS_IRQ_NAME "status" +#define CNS21XX_GEC_RXRC_IRQ_NAME "rxrc" +#define CNS21XX_GEC_RXQF_IRQ_NAME "rxqf" +#define CNS21XX_GEC_TXTC_IRQ_NAME "txtc" +#define CNS21XX_GEC_TXQE_IRQ_NAME "txqe" + +enum cns21xx_gec_phy_type { + CNS21XX_GEC_PHY_TYPE_INTERNAL = 0, + CNS21XX_GEC_PHY_TYPE_VSC8601, + CNS21XX_GEC_PHY_TYPE_IP101A, + CNS21XX_GEC_PHY_TYPE_IP1001, +}; + +struct cns21xx_gec_plat_data { + u8 *mac_addr; + enum cns21xx_gec_phy_type phy_type; + u8 phy_addr; +}; + +#endif /* _CNS21XX_GEC_PLATFORM_H */