185-mi424wr_support.patch 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507
  1. --- a/arch/arm/configs/ixp4xx_defconfig
  2. +++ b/arch/arm/configs/ixp4xx_defconfig
  3. @@ -26,6 +26,7 @@ CONFIG_MACH_NAS100D=y
  4. CONFIG_MACH_DSMG600=y
  5. CONFIG_MACH_FSG=y
  6. CONFIG_MACH_GTWX5715=y
  7. +CONFIG_MACH_MI424WR=y
  8. CONFIG_IXP4XX_QMGR=y
  9. CONFIG_IXP4XX_NPE=y
  10. # CONFIG_ARM_THUMB is not set
  11. --- a/arch/arm/mach-ixp4xx/Kconfig
  12. +++ b/arch/arm/mach-ixp4xx/Kconfig
  13. @@ -258,6 +258,13 @@ config MACH_MIC256
  14. Say 'Y' here if you want your kernel to support the MIC256
  15. board from OMICRON electronics GmbH.
  16. +config MACH_MI424WR
  17. + bool "Actiontec MI424WR"
  18. + depends on ARCH_IXP4XX
  19. + select PCI
  20. + help
  21. + Add support for the Actiontec MI424-WR.
  22. +
  23. comment "IXP4xx Options"
  24. config IXP4XX_INDIRECT_PCI
  25. --- a/arch/arm/mach-ixp4xx/Makefile
  26. +++ b/arch/arm/mach-ixp4xx/Makefile
  27. @@ -25,6 +25,7 @@ obj-pci-$(CONFIG_MACH_COMPEXWP18) += ixd
  28. obj-pci-$(CONFIG_MACH_WRT300NV2) += wrt300nv2-pci.o
  29. obj-pci-$(CONFIG_MACH_AP1000) += ixdp425-pci.o
  30. obj-pci-$(CONFIG_MACH_TW5334) += tw5334-pci.o
  31. +obj-pci-$(CONFIG_MACH_MI424WR) += mi424wr-pci.o
  32. obj-y += common.o
  33. @@ -51,6 +52,7 @@ obj-$(CONFIG_MACH_COMPEXWP18) += compex4
  34. obj-$(CONFIG_MACH_WRT300NV2) += wrt300nv2-setup.o
  35. obj-$(CONFIG_MACH_AP1000) += ap1000-setup.o
  36. obj-$(CONFIG_MACH_TW5334) += tw5334-setup.o
  37. +obj-$(CONFIG_MACH_MI424WR) += mi424wr-setup.o
  38. obj-$(CONFIG_PCI) += $(obj-pci-$(CONFIG_PCI)) common-pci.o
  39. obj-$(CONFIG_IXP4XX_QMGR) += ixp4xx_qmgr.o
  40. --- /dev/null
  41. +++ b/arch/arm/mach-ixp4xx/mi424wr-pci.c
  42. @@ -0,0 +1,70 @@
  43. +/*
  44. + * arch/arm/mach-ixp4xx/mi424wr-pci.c
  45. + *
  46. + * Actiontec MI424WR board-level PCI initialization
  47. + *
  48. + * Copyright (C) 2008 Jose Vasconcellos
  49. + *
  50. + * Maintainer: Jose Vasconcellos <jvasco@verizon.net>
  51. + *
  52. + * This program is free software; you can redistribute it and/or modify
  53. + * it under the terms of the GNU General Public License version 2 as
  54. + * published by the Free Software Foundation.
  55. + *
  56. + */
  57. +
  58. +#include <linux/kernel.h>
  59. +#include <linux/pci.h>
  60. +#include <linux/init.h>
  61. +#include <linux/irq.h>
  62. +
  63. +#include <asm/mach-types.h>
  64. +#include <asm/mach/pci.h>
  65. +
  66. +/* PCI controller GPIO to IRQ pin mappings
  67. + * This information was obtained from Actiontec's GPL release.
  68. + *
  69. + * INTA INTB
  70. + * SLOT 13 8 6
  71. + * SLOT 14 7 8
  72. + * SLOT 15 6 7
  73. + */
  74. +
  75. +void __init mi424wr_pci_preinit(void)
  76. +{
  77. + irq_set_irq_type(IRQ_IXP4XX_GPIO6, IRQ_TYPE_LEVEL_LOW);
  78. + irq_set_irq_type(IRQ_IXP4XX_GPIO7, IRQ_TYPE_LEVEL_LOW);
  79. + irq_set_irq_type(IRQ_IXP4XX_GPIO8, IRQ_TYPE_LEVEL_LOW);
  80. +
  81. + ixp4xx_pci_preinit();
  82. +}
  83. +
  84. +static int __init mi424wr_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
  85. +{
  86. + if (slot == 13)
  87. + return IRQ_IXP4XX_GPIO8;
  88. + if (slot == 14)
  89. + return IRQ_IXP4XX_GPIO7;
  90. + if (slot == 15)
  91. + return IRQ_IXP4XX_GPIO6;
  92. +
  93. + return -1;
  94. +}
  95. +
  96. +struct hw_pci mi424wr_pci __initdata = {
  97. + .nr_controllers = 1,
  98. + .preinit = mi424wr_pci_preinit,
  99. + .ops = &ixp4xx_ops,
  100. + .setup = ixp4xx_setup,
  101. + .map_irq = mi424wr_map_irq,
  102. +};
  103. +
  104. +int __init mi424wr_pci_init(void)
  105. +{
  106. + if (machine_is_mi424wr())
  107. + pci_common_init(&mi424wr_pci);
  108. + return 0;
  109. +}
  110. +
  111. +subsys_initcall(mi424wr_pci_init);
  112. +
  113. --- /dev/null
  114. +++ b/arch/arm/mach-ixp4xx/mi424wr-setup.c
  115. @@ -0,0 +1,387 @@
  116. +/*
  117. + * arch/arm/mach-ixp4xx/mi424wr-setup.c
  118. + *
  119. + * Actiontec MI424-WR board setup
  120. + * Copyright (c) 2008 Jose Vasconcellos
  121. + *
  122. + * Based on Gemtek GTWX5715 by
  123. + * Copyright (C) 2004 George T. Joseph
  124. + * Derived from Coyote
  125. + *
  126. + * This program is free software; you can redistribute it and/or
  127. + * modify it under the terms of the GNU General Public License
  128. + * as published by the Free Software Foundation; either version 2
  129. + * of the License, or (at your option) any later version.
  130. + *
  131. + * This program is distributed in the hope that it will be useful,
  132. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  133. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  134. + * GNU General Public License for more details.
  135. + *
  136. + * You should have received a copy of the GNU General Public License
  137. + * along with this program; if not, write to the Free Software
  138. + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  139. + *
  140. + */
  141. +
  142. +#include <linux/init.h>
  143. +#include <linux/device.h>
  144. +#include <linux/serial.h>
  145. +#include <linux/serial_8250.h>
  146. +#include <linux/types.h>
  147. +#include <linux/memory.h>
  148. +#include <linux/leds.h>
  149. +#include <linux/spi/spi_gpio_old.h>
  150. +#include <linux/dma-mapping.h>
  151. +
  152. +#include <asm/setup.h>
  153. +#include <asm/system_info.h>
  154. +#include <asm/irq.h>
  155. +#include <asm/io.h>
  156. +#include <asm/mach-types.h>
  157. +#include <asm/mach/arch.h>
  158. +#include <asm/mach/flash.h>
  159. +
  160. +/*
  161. + * GPIO 2,3,4 and 9 are hard wired to the Micrel/Kendin KS8995M Switch
  162. + * and operate as an SPI type interface. The details of the interface
  163. + * are available on Kendin/Micrel's web site.
  164. + */
  165. +
  166. +#define MI424WR_KSSPI_SELECT 9
  167. +#define MI424WR_KSSPI_TXD 4
  168. +#define MI424WR_KSSPI_CLOCK 2
  169. +#define MI424WR_KSSPI_RXD 3
  170. +
  171. +/*
  172. + * The "reset" button is wired to GPIO 10.
  173. + * The GPIO is brought "low" when the button is pushed.
  174. + */
  175. +
  176. +#define MI424WR_BUTTON_GPIO 10
  177. +#define MI424WR_BUTTON_IRQ IRQ_IXP4XX_GPIO10
  178. +
  179. +#define MI424WR_MOCA_WAN_LED 11
  180. +
  181. +/* Latch on CS1 - taken from Actiontec's 2.4 source code
  182. + *
  183. + * default latch value
  184. + * 0 - power alarm led (red) 0 (off)
  185. + * 1 - power led (green) 0 (off)
  186. + * 2 - wireless led (green) 1 (off)
  187. + * 3 - no internet led (red) 0 (off)
  188. + * 4 - internet ok led (green) 0 (off)
  189. + * 5 - moca LAN 0 (off)
  190. + * 6 - WAN alarm led (red) 0 (off)
  191. + * 7 - PCI reset 1 (not reset)
  192. + * 8 - IP phone 1 led (green) 1 (off)
  193. + * 9 - IP phone 2 led (green) 1 (off)
  194. + * 10 - VOIP ready led (green) 1 (off)
  195. + * 11 - PSTN relay 1 control 0 (PSTN)
  196. + * 12 - PSTN relay 1 control 0 (PSTN)
  197. + * 13 - N/A
  198. + * 14 - N/A
  199. + * 15 - N/A
  200. + */
  201. +
  202. +#define MI424WR_LATCH_MASK 0x04
  203. +#define MI424WR_LATCH_DEFAULT 0x1f86
  204. +
  205. +#define MI424WR_LATCH_ALARM_LED 0x00
  206. +#define MI424WR_LATCH_POWER_LED 0x01
  207. +#define MI424WR_LATCH_WIRELESS_LED 0x02
  208. +#define MI424WR_LATCH_INET_DOWN_LED 0x03
  209. +#define MI424WR_LATCH_INET_OK_LED 0x04
  210. +#define MI424WR_LATCH_MOCA_LAN_LED 0x05
  211. +#define MI424WR_LATCH_WAN_ALARM_LED 0x06
  212. +#define MI424WR_LATCH_PCI_RESET 0x07
  213. +#define MI424WR_LATCH_PHONE1_LED 0x08
  214. +#define MI424WR_LATCH_PHONE2_LED 0x09
  215. +#define MI424WR_LATCH_VOIP_LED 0x10
  216. +#define MI424WR_LATCH_PSTN_RELAY1 0x11
  217. +#define MI424WR_LATCH_PSTN_RELAY2 0x12
  218. +
  219. +/* initialize CS1 to default timings, Intel style, 16-bit bus */
  220. +#define MI424WR_CS1_CONFIG 0x80000002
  221. +
  222. +/* Define both UARTs but they are not easily accessible.
  223. + */
  224. +
  225. +static struct resource mi424wr_uart_resources[] = {
  226. + {
  227. + .start = IXP4XX_UART1_BASE_PHYS,
  228. + .end = IXP4XX_UART1_BASE_PHYS + 0x0fff,
  229. + .flags = IORESOURCE_MEM,
  230. + },
  231. + {
  232. + .start = IXP4XX_UART2_BASE_PHYS,
  233. + .end = IXP4XX_UART2_BASE_PHYS + 0x0fff,
  234. + .flags = IORESOURCE_MEM,
  235. + }
  236. +};
  237. +
  238. +
  239. +static struct plat_serial8250_port mi424wr_uart_platform_data[] = {
  240. + {
  241. + .mapbase = IXP4XX_UART1_BASE_PHYS,
  242. + .membase = (char *)IXP4XX_UART1_BASE_VIRT + REG_OFFSET,
  243. + .irq = IRQ_IXP4XX_UART1,
  244. + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
  245. + .iotype = UPIO_MEM,
  246. + .regshift = 2,
  247. + .uartclk = IXP4XX_UART_XTAL,
  248. + },
  249. + {
  250. + .mapbase = IXP4XX_UART2_BASE_PHYS,
  251. + .membase = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET,
  252. + .irq = IRQ_IXP4XX_UART2,
  253. + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
  254. + .iotype = UPIO_MEM,
  255. + .regshift = 2,
  256. + .uartclk = IXP4XX_UART_XTAL,
  257. + },
  258. + { },
  259. +};
  260. +
  261. +static struct platform_device mi424wr_uart_device = {
  262. + .name = "serial8250",
  263. + .id = PLAT8250_DEV_PLATFORM,
  264. + .dev.platform_data = mi424wr_uart_platform_data,
  265. + .num_resources = ARRAY_SIZE(mi424wr_uart_resources),
  266. + .resource = mi424wr_uart_resources,
  267. +};
  268. +
  269. +static struct flash_platform_data mi424wr_flash_data = {
  270. + .map_name = "cfi_probe",
  271. + .width = 2,
  272. +};
  273. +
  274. +static struct resource mi424wr_flash_resource = {
  275. + .flags = IORESOURCE_MEM,
  276. +};
  277. +
  278. +static struct platform_device mi424wr_flash = {
  279. + .name = "IXP4XX-Flash",
  280. + .id = 0,
  281. + .dev.platform_data = &mi424wr_flash_data,
  282. + .num_resources = 1,
  283. + .resource = &mi424wr_flash_resource,
  284. +};
  285. +
  286. +static int mi424wr_spi_boardinfo_setup(struct spi_board_info *bi,
  287. + struct spi_master *master, void *data)
  288. +{
  289. +
  290. + strlcpy(bi->modalias, "spi-ks8995", sizeof(bi->modalias));
  291. +
  292. + bi->max_speed_hz = 5000000 /* Hz */;
  293. + bi->bus_num = master->bus_num;
  294. + bi->mode = SPI_MODE_0;
  295. +
  296. + return 0;
  297. +}
  298. +
  299. +static struct spi_gpio_platform_data mi424wr_spi_bus_data = {
  300. + .pin_cs = MI424WR_KSSPI_SELECT,
  301. + .pin_clk = MI424WR_KSSPI_CLOCK,
  302. + .pin_miso = MI424WR_KSSPI_RXD,
  303. + .pin_mosi = MI424WR_KSSPI_TXD,
  304. + .cs_activelow = 1,
  305. + .no_spi_delay = 1,
  306. + .boardinfo_setup = mi424wr_spi_boardinfo_setup,
  307. +};
  308. +
  309. +static struct gpio_led mi424wr_gpio_led[] = {
  310. + {
  311. + .name = "moca-wan", /* green led */
  312. + .gpio = MI424WR_MOCA_WAN_LED,
  313. + .active_low = 0,
  314. + }
  315. +};
  316. +
  317. +static struct gpio_led_platform_data mi424wr_gpio_leds_data = {
  318. + .num_leds = 1,
  319. + .leds = mi424wr_gpio_led,
  320. +};
  321. +
  322. +static struct platform_device mi424wr_gpio_leds = {
  323. + .name = "leds-gpio",
  324. + .id = -1,
  325. + .dev.platform_data = &mi424wr_gpio_leds_data,
  326. +};
  327. +
  328. +static uint16_t latch_value = MI424WR_LATCH_DEFAULT;
  329. +static uint16_t __iomem *iobase;
  330. +
  331. +static void mi424wr_latch_set_led(u8 bit, enum led_brightness value)
  332. +{
  333. +
  334. + if (((MI424WR_LATCH_MASK >> bit) & 1) ^ (value == LED_OFF))
  335. + latch_value &= ~(0x1 << bit);
  336. + else
  337. + latch_value |= (0x1 << bit);
  338. +
  339. + __raw_writew(latch_value, iobase);
  340. +
  341. +}
  342. +
  343. +static struct latch_led mi424wr_latch_led[] = {
  344. + {
  345. + .name = "power-alarm",
  346. + .bit = MI424WR_LATCH_ALARM_LED,
  347. + },
  348. + {
  349. + .name = "power-ok",
  350. + .bit = MI424WR_LATCH_POWER_LED,
  351. + },
  352. + {
  353. + .name = "wireless", /* green led */
  354. + .bit = MI424WR_LATCH_WIRELESS_LED,
  355. + },
  356. + {
  357. + .name = "inet-down", /* red led */
  358. + .bit = MI424WR_LATCH_INET_DOWN_LED,
  359. + },
  360. + {
  361. + .name = "inet-up", /* green led */
  362. + .bit = MI424WR_LATCH_INET_OK_LED,
  363. + },
  364. + {
  365. + .name = "moca-lan", /* green led */
  366. + .bit = MI424WR_LATCH_MOCA_LAN_LED,
  367. + },
  368. + {
  369. + .name = "wan-alarm", /* red led */
  370. + .bit = MI424WR_LATCH_WAN_ALARM_LED,
  371. + }
  372. +};
  373. +
  374. +static struct latch_led_platform_data mi424wr_latch_leds_data = {
  375. + .num_leds = ARRAY_SIZE(mi424wr_latch_led),
  376. + .mem = 0x51000000,
  377. + .leds = mi424wr_latch_led,
  378. + .set_led = mi424wr_latch_set_led,
  379. +};
  380. +
  381. +static struct platform_device mi424wr_latch_leds = {
  382. + .name = "leds-latch",
  383. + .id = -1,
  384. + .dev.platform_data = &mi424wr_latch_leds_data,
  385. +};
  386. +
  387. +static struct platform_device mi424wr_spi_bus = {
  388. + .name = "spi-gpio",
  389. + .id = 0,
  390. + .dev.platform_data = &mi424wr_spi_bus_data,
  391. +};
  392. +
  393. +static struct eth_plat_info mi424wr_wan_data = {
  394. + .phy = 17, /* KS8721 */
  395. + .rxq = 3,
  396. + .txreadyq = 20,
  397. +};
  398. +
  399. +static struct eth_plat_info mi424wr_lan_data = {
  400. + .phy = IXP4XX_ETH_PHY_MAX_ADDR,
  401. + .phy_mask = 0x1e, /* ports 1-4 of the KS8995 switch */
  402. + .rxq = 4,
  403. + .txreadyq = 21,
  404. +};
  405. +
  406. +static struct platform_device mi424wr_npe_devices[] = {
  407. + {
  408. + .name = "ixp4xx_eth",
  409. + .id = IXP4XX_ETH_NPEC,
  410. + .dev.platform_data = &mi424wr_lan_data,
  411. + .dev.coherent_dma_mask = DMA_BIT_MASK(32),
  412. + }, {
  413. + .name = "ixp4xx_eth",
  414. + .id = IXP4XX_ETH_NPEB,
  415. + .dev.platform_data = &mi424wr_wan_data,
  416. + .dev.coherent_dma_mask = DMA_BIT_MASK(32),
  417. + }
  418. +};
  419. +
  420. +static struct eth_plat_info mi424wr_wanD_data = {
  421. + .phy = 5,
  422. + .rxq = 4,
  423. + .txreadyq = 21,
  424. +};
  425. +
  426. +static struct eth_plat_info mi424wr_lanD_data = {
  427. + .phy = IXP4XX_ETH_PHY_MAX_ADDR,
  428. + .phy_mask = 0x1e, /* ports 1-4 of the KS8995 switch */
  429. + .rxq = 3,
  430. + .txreadyq = 20,
  431. +};
  432. +
  433. +static struct platform_device mi424wr_npeD_devices[] = {
  434. + {
  435. + .name = "ixp4xx_eth",
  436. + .id = IXP4XX_ETH_NPEB,
  437. + .dev.platform_data = &mi424wr_lanD_data,
  438. + .dev.coherent_dma_mask = DMA_BIT_MASK(32),
  439. + }, {
  440. + .name = "ixp4xx_eth",
  441. + .id = IXP4XX_ETH_NPEC,
  442. + .dev.platform_data = &mi424wr_wanD_data,
  443. + .dev.coherent_dma_mask = DMA_BIT_MASK(32),
  444. + }
  445. +};
  446. +
  447. +static struct platform_device *mi424wr_devices[] __initdata = {
  448. + &mi424wr_uart_device,
  449. + &mi424wr_flash,
  450. + &mi424wr_gpio_leds,
  451. + &mi424wr_latch_leds,
  452. + &mi424wr_spi_bus,
  453. +};
  454. +
  455. +static void __init mi424wr_init(void)
  456. +{
  457. + ixp4xx_sys_init();
  458. +
  459. + mi424wr_flash_resource.start = IXP4XX_EXP_BUS_BASE(0);
  460. + mi424wr_flash_resource.end = IXP4XX_EXP_BUS_BASE(0) + SZ_8M - 1;
  461. +
  462. + *IXP4XX_EXP_CS0 |= IXP4XX_FLASH_WRITABLE;
  463. + *IXP4XX_EXP_CS1 = MI424WR_CS1_CONFIG;
  464. +
  465. + /* configure button as input
  466. + */
  467. + gpio_line_config(MI424WR_BUTTON_GPIO, IXP4XX_GPIO_IN);
  468. +
  469. + /* Initialize LEDs and enables PCI bus.
  470. + */
  471. + iobase = ioremap_nocache(IXP4XX_EXP_BUS_BASE(1), 0x1000);
  472. + __raw_writew(latch_value, iobase);
  473. +
  474. + platform_add_devices(mi424wr_devices, ARRAY_SIZE(mi424wr_devices));
  475. +
  476. + /* Need to figure out how to detect revD.
  477. + * Look for a revision argument sent by redboot.
  478. + */
  479. +#define revD 4
  480. + if (system_rev == revD) {
  481. + platform_device_register(&mi424wr_npeD_devices[0]);
  482. + platform_device_register(&mi424wr_npeD_devices[1]);
  483. + } else {
  484. + platform_device_register(&mi424wr_npe_devices[0]);
  485. + platform_device_register(&mi424wr_npe_devices[1]);
  486. + }
  487. +}
  488. +
  489. +
  490. +MACHINE_START(MI424WR, "Actiontec MI424WR")
  491. + /* Maintainer: Jose Vasconcellos */
  492. + .map_io = ixp4xx_map_io,
  493. + .init_irq = ixp4xx_init_irq,
  494. + .init_time = ixp4xx_timer_init,
  495. + .atag_offset = 0x0100,
  496. + .init_machine = mi424wr_init,
  497. +#if defined(CONFIG_PCI)
  498. + .dma_zone_size = SZ_64M,
  499. +#endif
  500. + .restart = ixp4xx_restart,
  501. +MACHINE_END
  502. +