aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/tx4938
diff options
context:
space:
mode:
authorAtsushi Nemoto <anemo@mba.ocn.ne.jp>2007-06-22 10:22:06 -0400
committerRalf Baechle <ralf@linux-mips.org>2007-07-10 12:33:03 -0400
commitf74cf6ff99a49741b0f243996b621777b2d610d4 (patch)
tree5812f82646aadcbd451e528379548866c5ca790d /arch/mips/tx4938
parent3896b05418b9b8548a678231db754206b3ebe56e (diff)
[MIPS] rbtx4938: Convert SPI codes to use generic SPI drivers
Use rtc-rs5c348 and at25 spi protocol driver and spi_txx9 spi controller driver instead of platform dependent codes. This patch also removes dependencies to old RTC interfaces such as rtc_mips_get_time, etc. Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp> Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/tx4938')
-rw-r--r--arch/mips/tx4938/common/Makefile2
-rw-r--r--arch/mips/tx4938/common/rtc_rx5c348.c192
-rw-r--r--arch/mips/tx4938/toshiba_rbtx4938/Makefile2
-rw-r--r--arch/mips/tx4938/toshiba_rbtx4938/irq.c6
-rw-r--r--arch/mips/tx4938/toshiba_rbtx4938/setup.c171
-rw-r--r--arch/mips/tx4938/toshiba_rbtx4938/spi_eeprom.c261
-rw-r--r--arch/mips/tx4938/toshiba_rbtx4938/spi_txx9.c164
7 files changed, 167 insertions, 631 deletions
diff --git a/arch/mips/tx4938/common/Makefile b/arch/mips/tx4938/common/Makefile
index 2033ae77f632..83cda518f204 100644
--- a/arch/mips/tx4938/common/Makefile
+++ b/arch/mips/tx4938/common/Makefile
@@ -6,6 +6,6 @@
6# unless it's something special (ie not a .c file). 6# unless it's something special (ie not a .c file).
7# 7#
8 8
9obj-y += prom.o setup.o irq.o rtc_rx5c348.o 9obj-y += prom.o setup.o irq.o
10obj-$(CONFIG_KGDB) += dbgio.o 10obj-$(CONFIG_KGDB) += dbgio.o
11 11
diff --git a/arch/mips/tx4938/common/rtc_rx5c348.c b/arch/mips/tx4938/common/rtc_rx5c348.c
deleted file mode 100644
index 07f782fc0725..000000000000
--- a/arch/mips/tx4938/common/rtc_rx5c348.c
+++ /dev/null
@@ -1,192 +0,0 @@
1/*
2 * RTC routines for RICOH Rx5C348 SPI chip.
3 * Copyright (C) 2000-2001 Toshiba Corporation
4 *
5 * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
6 * terms of the GNU General Public License version 2. This program is
7 * licensed "as is" without any warranty of any kind, whether express
8 * or implied.
9 *
10 * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
11 */
12#include <linux/init.h>
13#include <linux/kernel.h>
14#include <linux/string.h>
15#include <linux/rtc.h>
16#include <linux/time.h>
17#include <linux/bcd.h>
18#include <asm/time.h>
19#include <asm/tx4938/spi.h>
20
21#define EPOCH 2000
22
23/* registers */
24#define Rx5C348_REG_SECOND 0
25#define Rx5C348_REG_MINUTE 1
26#define Rx5C348_REG_HOUR 2
27#define Rx5C348_REG_WEEK 3
28#define Rx5C348_REG_DAY 4
29#define Rx5C348_REG_MONTH 5
30#define Rx5C348_REG_YEAR 6
31#define Rx5C348_REG_ADJUST 7
32#define Rx5C348_REG_ALARM_W_MIN 8
33#define Rx5C348_REG_ALARM_W_HOUR 9
34#define Rx5C348_REG_ALARM_W_WEEK 10
35#define Rx5C348_REG_ALARM_D_MIN 11
36#define Rx5C348_REG_ALARM_D_HOUR 12
37#define Rx5C348_REG_CTL1 14
38#define Rx5C348_REG_CTL2 15
39
40/* register bits */
41#define Rx5C348_BIT_PM 0x20 /* REG_HOUR */
42#define Rx5C348_BIT_Y2K 0x80 /* REG_MONTH */
43#define Rx5C348_BIT_24H 0x20 /* REG_CTL1 */
44#define Rx5C348_BIT_XSTP 0x10 /* REG_CTL2 */
45
46/* commands */
47#define Rx5C348_CMD_W(addr) (((addr) << 4) | 0x08) /* single write */
48#define Rx5C348_CMD_R(addr) (((addr) << 4) | 0x0c) /* single read */
49#define Rx5C348_CMD_MW(addr) (((addr) << 4) | 0x00) /* burst write */
50#define Rx5C348_CMD_MR(addr) (((addr) << 4) | 0x04) /* burst read */
51
52static struct spi_dev_desc srtc_dev_desc = {
53 .baud = 1000000, /* 1.0Mbps @ Vdd 2.0V */
54 .tcss = 31,
55 .tcsh = 1,
56 .tcsr = 62,
57 /* 31us for Tcss (62us for Tcsr) is required for carry operation) */
58 .byteorder = 1, /* MSB-First */
59 .polarity = 0, /* High-Active */
60 .phase = 1, /* Shift-Then-Sample */
61
62};
63static int srtc_chipid;
64static int srtc_24h;
65
66static inline int
67spi_rtc_io(unsigned char *inbuf, unsigned char *outbuf, unsigned int count)
68{
69 unsigned char *inbufs[1], *outbufs[1];
70 unsigned int incounts[2], outcounts[2];
71 inbufs[0] = inbuf;
72 incounts[0] = count;
73 incounts[1] = 0;
74 outbufs[0] = outbuf;
75 outcounts[0] = count;
76 outcounts[1] = 0;
77 return txx9_spi_io(srtc_chipid, &srtc_dev_desc,
78 inbufs, incounts, outbufs, outcounts, 0);
79}
80
81/* RTC-dependent code for time.c */
82
83static int
84rtc_rx5c348_set_time(unsigned long t)
85{
86 unsigned char inbuf[8];
87 struct rtc_time tm;
88 u8 year, month, day, hour, minute, second, century;
89
90 /* convert */
91 to_tm(t, &tm);
92
93 year = tm.tm_year % 100;
94 month = tm.tm_mon+1; /* tm_mon starts from 0 to 11 */
95 day = tm.tm_mday;
96 hour = tm.tm_hour;
97 minute = tm.tm_min;
98 second = tm.tm_sec;
99 century = tm.tm_year / 100;
100
101 inbuf[0] = Rx5C348_CMD_MW(Rx5C348_REG_SECOND);
102 BIN_TO_BCD(second);
103 inbuf[1] = second;
104 BIN_TO_BCD(minute);
105 inbuf[2] = minute;
106
107 if (srtc_24h) {
108 BIN_TO_BCD(hour);
109 inbuf[3] = hour;
110 } else {
111 /* hour 0 is AM12, noon is PM12 */
112 inbuf[3] = 0;
113 if (hour >= 12)
114 inbuf[3] = Rx5C348_BIT_PM;
115 hour = (hour + 11) % 12 + 1;
116 BIN_TO_BCD(hour);
117 inbuf[3] |= hour;
118 }
119 inbuf[4] = 0; /* ignore week */
120 BIN_TO_BCD(day);
121 inbuf[5] = day;
122 BIN_TO_BCD(month);
123 inbuf[6] = month;
124 if (century >= 20)
125 inbuf[6] |= Rx5C348_BIT_Y2K;
126 BIN_TO_BCD(year);
127 inbuf[7] = year;
128 /* write in one transfer to avoid data inconsistency */
129 return spi_rtc_io(inbuf, NULL, 8);
130}
131
132static unsigned long
133rtc_rx5c348_get_time(void)
134{
135 unsigned char inbuf[8], outbuf[8];
136 unsigned int year, month, day, hour, minute, second;
137
138 inbuf[0] = Rx5C348_CMD_MR(Rx5C348_REG_SECOND);
139 memset(inbuf + 1, 0, 7);
140 /* read in one transfer to avoid data inconsistency */
141 if (spi_rtc_io(inbuf, outbuf, 8))
142 return 0;
143 second = outbuf[1];
144 BCD_TO_BIN(second);
145 minute = outbuf[2];
146 BCD_TO_BIN(minute);
147 if (srtc_24h) {
148 hour = outbuf[3];
149 BCD_TO_BIN(hour);
150 } else {
151 hour = outbuf[3] & ~Rx5C348_BIT_PM;
152 BCD_TO_BIN(hour);
153 hour %= 12;
154 if (outbuf[3] & Rx5C348_BIT_PM)
155 hour += 12;
156 }
157 day = outbuf[5];
158 BCD_TO_BIN(day);
159 month = outbuf[6] & ~Rx5C348_BIT_Y2K;
160 BCD_TO_BIN(month);
161 year = outbuf[7];
162 BCD_TO_BIN(year);
163 year += EPOCH;
164
165 return mktime(year, month, day, hour, minute, second);
166}
167
168void __init
169rtc_rx5c348_init(int chipid)
170{
171 unsigned char inbuf[2], outbuf[2];
172 srtc_chipid = chipid;
173 /* turn on RTC if it is not on */
174 inbuf[0] = Rx5C348_CMD_R(Rx5C348_REG_CTL2);
175 inbuf[1] = 0;
176 spi_rtc_io(inbuf, outbuf, 2);
177 if (outbuf[1] & Rx5C348_BIT_XSTP) {
178 inbuf[0] = Rx5C348_CMD_W(Rx5C348_REG_CTL2);
179 inbuf[1] = 0;
180 spi_rtc_io(inbuf, NULL, 2);
181 }
182
183 inbuf[0] = Rx5C348_CMD_R(Rx5C348_REG_CTL1);
184 inbuf[1] = 0;
185 spi_rtc_io(inbuf, outbuf, 2);
186 if (outbuf[1] & Rx5C348_BIT_24H)
187 srtc_24h = 1;
188
189 /* set the function pointers */
190 rtc_mips_get_time = rtc_rx5c348_get_time;
191 rtc_mips_set_time = rtc_rx5c348_set_time;
192}
diff --git a/arch/mips/tx4938/toshiba_rbtx4938/Makefile b/arch/mips/tx4938/toshiba_rbtx4938/Makefile
index 226941279d75..10c94e62bf5b 100644
--- a/arch/mips/tx4938/toshiba_rbtx4938/Makefile
+++ b/arch/mips/tx4938/toshiba_rbtx4938/Makefile
@@ -6,4 +6,4 @@
6# unless it's something special (ie not a .c file). 6# unless it's something special (ie not a .c file).
7# 7#
8 8
9obj-y += prom.o setup.o irq.o spi_eeprom.o spi_txx9.o 9obj-y += prom.o setup.o irq.o spi_eeprom.o
diff --git a/arch/mips/tx4938/toshiba_rbtx4938/irq.c b/arch/mips/tx4938/toshiba_rbtx4938/irq.c
index 2e96dbb248b1..91aea7aff515 100644
--- a/arch/mips/tx4938/toshiba_rbtx4938/irq.c
+++ b/arch/mips/tx4938/toshiba_rbtx4938/irq.c
@@ -165,8 +165,6 @@ toshiba_rbtx4938_irq_ioc_disable(unsigned int irq)
165 TX4938_RD08(TOSHIBA_RBTX4938_IOC_INTR_ENAB); 165 TX4938_RD08(TOSHIBA_RBTX4938_IOC_INTR_ENAB);
166} 166}
167 167
168extern void __init txx9_spi_irqinit(int irc_irq);
169
170void __init arch_init_irq(void) 168void __init arch_init_irq(void)
171{ 169{
172 extern void tx4938_irq_init(void); 170 extern void tx4938_irq_init(void);
@@ -185,9 +183,5 @@ void __init arch_init_irq(void)
185 /* Onboard 10M Ether: High Active */ 183 /* Onboard 10M Ether: High Active */
186 TX4938_WR(TX4938_MKA(TX4938_IRC_IRDM0), 0x00000040); 184 TX4938_WR(TX4938_MKA(TX4938_IRC_IRDM0), 0x00000040);
187 185
188 if (tx4938_ccfgptr->pcfg & TX4938_PCFG_SPI_SEL) {
189 txx9_spi_irqinit(RBTX4938_IRQ_IRC_SPI);
190 }
191
192 wbflush(); 186 wbflush();
193} 187}
diff --git a/arch/mips/tx4938/toshiba_rbtx4938/setup.c b/arch/mips/tx4938/toshiba_rbtx4938/setup.c
index 12b9f4f9c3a2..361d89a81175 100644
--- a/arch/mips/tx4938/toshiba_rbtx4938/setup.c
+++ b/arch/mips/tx4938/toshiba_rbtx4938/setup.c
@@ -14,13 +14,13 @@
14#include <linux/init.h> 14#include <linux/init.h>
15#include <linux/types.h> 15#include <linux/types.h>
16#include <linux/ioport.h> 16#include <linux/ioport.h>
17#include <linux/proc_fs.h>
18#include <linux/delay.h> 17#include <linux/delay.h>
19#include <linux/interrupt.h> 18#include <linux/interrupt.h>
20#include <linux/console.h> 19#include <linux/console.h>
21#include <linux/pci.h> 20#include <linux/pci.h>
22#include <linux/pm.h> 21#include <linux/pm.h>
23#include <linux/platform_device.h> 22#include <linux/platform_device.h>
23#include <linux/clk.h>
24 24
25#include <asm/wbflush.h> 25#include <asm/wbflush.h>
26#include <asm/reboot.h> 26#include <asm/reboot.h>
@@ -29,13 +29,15 @@
29#include <asm/uaccess.h> 29#include <asm/uaccess.h>
30#include <asm/io.h> 30#include <asm/io.h>
31#include <asm/bootinfo.h> 31#include <asm/bootinfo.h>
32#include <asm/gpio.h>
33#include <asm/tx4938/rbtx4938.h> 32#include <asm/tx4938/rbtx4938.h>
34#ifdef CONFIG_SERIAL_TXX9 33#ifdef CONFIG_SERIAL_TXX9
35#include <linux/tty.h> 34#include <linux/tty.h>
36#include <linux/serial.h> 35#include <linux/serial.h>
37#include <linux/serial_core.h> 36#include <linux/serial_core.h>
38#endif 37#endif
38#include <linux/spi/spi.h>
39#include <asm/tx4938/spi.h>
40#include <asm/gpio.h>
39 41
40extern void rbtx4938_time_init(void) __init; 42extern void rbtx4938_time_init(void) __init;
41extern char * __init prom_getcmdline(void); 43extern char * __init prom_getcmdline(void);
@@ -575,44 +577,33 @@ arch_initcall(tx4938_pcibios_init);
575#define SEEPROM3_CS 1 /* IOC */ 577#define SEEPROM3_CS 1 /* IOC */
576#define SRTC_CS 2 /* IOC */ 578#define SRTC_CS 2 /* IOC */
577 579
578static int rbtx4938_spi_cs_func(int chipid, int on) 580#ifdef CONFIG_PCI
581static unsigned char rbtx4938_ethaddr[17];
582static int __init rbtx4938_ethaddr_init(void)
579{ 583{
580 unsigned char bit; 584 unsigned char sum;
581 switch (chipid) { 585 int i;
582 case RBTX4938_SEEPROM1_CHIPID: 586
583 if (on) 587 /* 0-3: "MAC\0", 4-9:eth0, 10-15:eth1, 16:sum */
584 tx4938_pioptr->dout &= ~(1 << SEEPROM1_CS); 588 if (spi_eeprom_read(SEEPROM1_CS, 0,
585 else 589 rbtx4938_ethaddr, sizeof(rbtx4938_ethaddr)))
586 tx4938_pioptr->dout |= (1 << SEEPROM1_CS); 590 printk(KERN_ERR "seeprom: read error.\n");
587 return 0; 591 else {
588 break; 592 unsigned char *dat = rbtx4938_ethaddr;
589 case RBTX4938_SEEPROM2_CHIPID: 593 if (strcmp(dat, "MAC") != 0)
590 bit = (1 << SEEPROM2_CS); 594 printk(KERN_WARNING "seeprom: bad signature.\n");
591 break; 595 for (i = 0, sum = 0; i < sizeof(dat); i++)
592 case RBTX4938_SEEPROM3_CHIPID: 596 sum += dat[i];
593 bit = (1 << SEEPROM3_CS); 597 if (sum)
594 break; 598 printk(KERN_WARNING "seeprom: bad checksum.\n");
595 case RBTX4938_SRTC_CHIPID:
596 bit = (1 << SRTC_CS);
597 break;
598 default:
599 return -ENODEV;
600 } 599 }
601 /* bit1,2,4 are low active, bit3 is high active */
602 *rbtx4938_spics_ptr =
603 (*rbtx4938_spics_ptr & ~bit) |
604 ((on ? (bit ^ 0x0b) : ~(bit ^ 0x0b)) & bit);
605 return 0; 600 return 0;
606} 601}
607 602device_initcall(rbtx4938_ethaddr_init);
608#ifdef CONFIG_PCI
609extern int spi_eeprom_read(int chipid, int address, unsigned char *buf, int len);
610 603
611int rbtx4938_get_tx4938_ethaddr(struct pci_dev *dev, unsigned char *addr) 604int rbtx4938_get_tx4938_ethaddr(struct pci_dev *dev, unsigned char *addr)
612{ 605{
613 struct pci_controller *channel = (struct pci_controller *)dev->bus->sysdata; 606 struct pci_controller *channel = (struct pci_controller *)dev->bus->sysdata;
614 static unsigned char dat[17];
615 static int read_dat = 0;
616 int ch = 0; 607 int ch = 0;
617 608
618 if (channel != &tx4938_pci_controller[1]) 609 if (channel != &tx4938_pci_controller[1])
@@ -628,29 +619,11 @@ int rbtx4938_get_tx4938_ethaddr(struct pci_dev *dev, unsigned char *addr)
628 default: 619 default:
629 return -ENODEV; 620 return -ENODEV;
630 } 621 }
631 if (!read_dat) { 622 memcpy(addr, &rbtx4938_ethaddr[4 + 6 * ch], 6);
632 unsigned char sum;
633 int i;
634 read_dat = 1;
635 /* 0-3: "MAC\0", 4-9:eth0, 10-15:eth1, 16:sum */
636 if (spi_eeprom_read(RBTX4938_SEEPROM1_CHIPID,
637 0, dat, sizeof(dat))) {
638 printk(KERN_ERR "seeprom: read error.\n");
639 } else {
640 if (strcmp(dat, "MAC") != 0)
641 printk(KERN_WARNING "seeprom: bad signature.\n");
642 for (i = 0, sum = 0; i < sizeof(dat); i++)
643 sum += dat[i];
644 if (sum)
645 printk(KERN_WARNING "seeprom: bad checksum.\n");
646 }
647 }
648 memcpy(addr, &dat[4 + 6 * ch], 6);
649 return 0; 623 return 0;
650} 624}
651#endif /* CONFIG_PCI */ 625#endif /* CONFIG_PCI */
652 626
653extern void __init txx9_spi_init(unsigned long base, int (*cs_func)(int chipid, int on));
654static void __init rbtx4938_spi_setup(void) 627static void __init rbtx4938_spi_setup(void)
655{ 628{
656 /* set SPI_SEL */ 629 /* set SPI_SEL */
@@ -658,7 +631,6 @@ static void __init rbtx4938_spi_setup(void)
658 /* chip selects for SPI devices */ 631 /* chip selects for SPI devices */
659 tx4938_pioptr->dout |= (1 << SEEPROM1_CS); 632 tx4938_pioptr->dout |= (1 << SEEPROM1_CS);
660 tx4938_pioptr->dir |= (1 << SEEPROM1_CS); 633 tx4938_pioptr->dir |= (1 << SEEPROM1_CS);
661 txx9_spi_init(TX4938_SPI_REG, rbtx4938_spi_cs_func);
662} 634}
663 635
664static struct resource rbtx4938_fpga_resource; 636static struct resource rbtx4938_fpga_resource;
@@ -897,10 +869,8 @@ void tx4938_report_pcic_status(void)
897/* We use onchip r4k counter or TMR timer as our system wide timer 869/* We use onchip r4k counter or TMR timer as our system wide timer
898 * interrupt running at 100HZ. */ 870 * interrupt running at 100HZ. */
899 871
900extern void __init rtc_rx5c348_init(int chipid);
901void __init rbtx4938_time_init(void) 872void __init rbtx4938_time_init(void)
902{ 873{
903 rtc_rx5c348_init(RBTX4938_SRTC_CHIPID);
904 mips_hpt_frequency = txx9_cpu_clock / 2; 874 mips_hpt_frequency = txx9_cpu_clock / 2;
905} 875}
906 876
@@ -1017,29 +987,6 @@ void __init toshiba_rbtx4938_setup(void)
1017 *rbtx4938_dipsw_ptr, *rbtx4938_bdipsw_ptr); 987 *rbtx4938_dipsw_ptr, *rbtx4938_bdipsw_ptr);
1018} 988}
1019 989
1020#ifdef CONFIG_PROC_FS
1021extern void spi_eeprom_proc_create(struct proc_dir_entry *dir, int chipid);
1022static int __init tx4938_spi_proc_setup(void)
1023{
1024 struct proc_dir_entry *tx4938_spi_eeprom_dir;
1025
1026 tx4938_spi_eeprom_dir = proc_mkdir("spi_eeprom", 0);
1027
1028 if (!tx4938_spi_eeprom_dir)
1029 return -ENOMEM;
1030
1031 /* don't allow user access to RBTX4938_SEEPROM1_CHIPID
1032 * as it contains eth0 and eth1 MAC addresses
1033 */
1034 spi_eeprom_proc_create(tx4938_spi_eeprom_dir, RBTX4938_SEEPROM2_CHIPID);
1035 spi_eeprom_proc_create(tx4938_spi_eeprom_dir, RBTX4938_SEEPROM3_CHIPID);
1036
1037 return 0;
1038}
1039
1040__initcall(tx4938_spi_proc_setup);
1041#endif
1042
1043static int __init rbtx4938_ne_init(void) 990static int __init rbtx4938_ne_init(void)
1044{ 991{
1045 struct resource res[] = { 992 struct resource res[] = {
@@ -1161,3 +1108,73 @@ void gpio_set_value(unsigned gpio, int value)
1161 else 1108 else
1162 rbtx4938_spi_gpio_set(gpio, value); 1109 rbtx4938_spi_gpio_set(gpio, value);
1163} 1110}
1111
1112/* SPI support */
1113
1114static void __init txx9_spi_init(unsigned long base, int irq)
1115{
1116 struct resource res[] = {
1117 {
1118 .start = base,
1119 .end = base + 0x20 - 1,
1120 .flags = IORESOURCE_MEM,
1121 .parent = &tx4938_reg_resource,
1122 }, {
1123 .start = irq,
1124 .flags = IORESOURCE_IRQ,
1125 },
1126 };
1127 platform_device_register_simple("txx9spi", 0,
1128 res, ARRAY_SIZE(res));
1129}
1130
1131static int __init rbtx4938_spi_init(void)
1132{
1133 struct spi_board_info srtc_info = {
1134 .modalias = "rs5c348",
1135 .max_speed_hz = 1000000, /* 1.0Mbps @ Vdd 2.0V */
1136 .bus_num = 0,
1137 .chip_select = 16 + SRTC_CS,
1138 /* Mode 1 (High-Active, Shift-Then-Sample), High Avtive CS */
1139 .mode = SPI_MODE_1 | SPI_CS_HIGH,
1140 };
1141 spi_register_board_info(&srtc_info, 1);
1142 spi_eeprom_register(SEEPROM1_CS);
1143 spi_eeprom_register(16 + SEEPROM2_CS);
1144 spi_eeprom_register(16 + SEEPROM3_CS);
1145 txx9_spi_init(TX4938_SPI_REG & 0xfffffffffULL, RBTX4938_IRQ_IRC_SPI);
1146 return 0;
1147}
1148arch_initcall(rbtx4938_spi_init);
1149
1150/* Minimum CLK support */
1151
1152struct clk *clk_get(struct device *dev, const char *id)
1153{
1154 if (!strcmp(id, "spi-baseclk"))
1155 return (struct clk *)(txx9_gbus_clock / 2 / 4);
1156 return ERR_PTR(-ENOENT);
1157}
1158EXPORT_SYMBOL(clk_get);
1159
1160int clk_enable(struct clk *clk)
1161{
1162 return 0;
1163}
1164EXPORT_SYMBOL(clk_enable);
1165
1166void clk_disable(struct clk *clk)
1167{
1168}
1169EXPORT_SYMBOL(clk_disable);
1170
1171unsigned long clk_get_rate(struct clk *clk)
1172{
1173 return (unsigned long)clk;
1174}
1175EXPORT_SYMBOL(clk_get_rate);
1176
1177void clk_put(struct clk *clk)
1178{
1179}
1180EXPORT_SYMBOL(clk_put);
diff --git a/arch/mips/tx4938/toshiba_rbtx4938/spi_eeprom.c b/arch/mips/tx4938/toshiba_rbtx4938/spi_eeprom.c
index 89596e62f909..4d6b4ade5e8c 100644
--- a/arch/mips/tx4938/toshiba_rbtx4938/spi_eeprom.c
+++ b/arch/mips/tx4938/toshiba_rbtx4938/spi_eeprom.c
@@ -10,209 +10,90 @@
10 * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com) 10 * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
11 */ 11 */
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/delay.h> 13#include <linux/device.h>
14#include <linux/proc_fs.h> 14#include <linux/spi/spi.h>
15#include <linux/spinlock.h> 15#include <linux/spi/eeprom.h>
16#include <asm/tx4938/spi.h> 16#include <asm/tx4938/spi.h>
17#include <asm/tx4938/tx4938.h>
18 17
19/* ATMEL 250x0 instructions */ 18#define AT250X0_PAGE_SIZE 8
20#define ATMEL_WREN 0x06
21#define ATMEL_WRDI 0x04
22#define ATMEL_RDSR 0x05
23#define ATMEL_WRSR 0x01
24#define ATMEL_READ 0x03
25#define ATMEL_WRITE 0x02
26 19
27#define ATMEL_SR_BSY 0x01 20/* register board information for at25 driver */
28#define ATMEL_SR_WEN 0x02 21int __init spi_eeprom_register(int chipid)
29#define ATMEL_SR_BP0 0x04
30#define ATMEL_SR_BP1 0x08
31
32DEFINE_SPINLOCK(spi_eeprom_lock);
33
34static struct spi_dev_desc seeprom_dev_desc = {
35 .baud = 1500000, /* 1.5Mbps */
36 .tcss = 1,
37 .tcsh = 1,
38 .tcsr = 1,
39 .byteorder = 1, /* MSB-First */
40 .polarity = 0, /* High-Active */
41 .phase = 0, /* Sample-Then-Shift */
42
43};
44static inline int
45spi_eeprom_io(int chipid,
46 unsigned char **inbufs, unsigned int *incounts,
47 unsigned char **outbufs, unsigned int *outcounts)
48{
49 return txx9_spi_io(chipid, &seeprom_dev_desc,
50 inbufs, incounts, outbufs, outcounts, 0);
51}
52
53int spi_eeprom_write_enable(int chipid, int enable)
54{ 22{
55 unsigned char inbuf[1]; 23 static struct spi_eeprom eeprom = {
56 unsigned char *inbufs[1]; 24 .name = "at250x0",
57 unsigned int incounts[2]; 25 .byte_len = 128,
58 unsigned long flags; 26 .page_size = AT250X0_PAGE_SIZE,
59 int stat; 27 .flags = EE_ADDR1,
60 inbuf[0] = enable ? ATMEL_WREN : ATMEL_WRDI; 28 };
61 inbufs[0] = inbuf; 29 struct spi_board_info info = {
62 incounts[0] = sizeof(inbuf); 30 .modalias = "at25",
63 incounts[1] = 0; 31 .max_speed_hz = 1500000, /* 1.5Mbps */
64 spin_lock_irqsave(&spi_eeprom_lock, flags); 32 .bus_num = 0,
65 stat = spi_eeprom_io(chipid, inbufs, incounts, NULL, NULL); 33 .chip_select = chipid,
66 spin_unlock_irqrestore(&spi_eeprom_lock, flags); 34 .platform_data = &eeprom,
67 return stat; 35 /* Mode 0: High-Active, Sample-Then-Shift */
68} 36 };
69 37
70static int spi_eeprom_read_status_nolock(int chipid) 38 return spi_register_board_info(&info, 1);
71{
72 unsigned char inbuf[2], outbuf[2];
73 unsigned char *inbufs[1], *outbufs[1];
74 unsigned int incounts[2], outcounts[2];
75 int stat;
76 inbuf[0] = ATMEL_RDSR;
77 inbuf[1] = 0;
78 inbufs[0] = inbuf;
79 incounts[0] = sizeof(inbuf);
80 incounts[1] = 0;
81 outbufs[0] = outbuf;
82 outcounts[0] = sizeof(outbuf);
83 outcounts[1] = 0;
84 stat = spi_eeprom_io(chipid, inbufs, incounts, outbufs, outcounts);
85 if (stat < 0)
86 return stat;
87 return outbuf[1];
88} 39}
89 40
90int spi_eeprom_read_status(int chipid) 41/* simple temporary spi driver to provide early access to seeprom. */
91{
92 unsigned long flags;
93 int stat;
94 spin_lock_irqsave(&spi_eeprom_lock, flags);
95 stat = spi_eeprom_read_status_nolock(chipid);
96 spin_unlock_irqrestore(&spi_eeprom_lock, flags);
97 return stat;
98}
99 42
100int spi_eeprom_read(int chipid, int address, unsigned char *buf, int len) 43static struct read_param {
101{ 44 int chipid;
102 unsigned char inbuf[2]; 45 int address;
103 unsigned char *inbufs[2], *outbufs[2]; 46 unsigned char *buf;
104 unsigned int incounts[2], outcounts[3]; 47 int len;
105 unsigned long flags; 48} *read_param;
106 int stat;
107 inbuf[0] = ATMEL_READ;
108 inbuf[1] = address;
109 inbufs[0] = inbuf;
110 inbufs[1] = NULL;
111 incounts[0] = sizeof(inbuf);
112 incounts[1] = 0;
113 outbufs[0] = NULL;
114 outbufs[1] = buf;
115 outcounts[0] = 2;
116 outcounts[1] = len;
117 outcounts[2] = 0;
118 spin_lock_irqsave(&spi_eeprom_lock, flags);
119 stat = spi_eeprom_io(chipid, inbufs, incounts, outbufs, outcounts);
120 spin_unlock_irqrestore(&spi_eeprom_lock, flags);
121 return stat;
122}
123 49
124int spi_eeprom_write(int chipid, int address, unsigned char *buf, int len) 50static int __init early_seeprom_probe(struct spi_device *spi)
125{ 51{
126 unsigned char inbuf[2]; 52 int stat = 0;
127 unsigned char *inbufs[2]; 53 u8 cmd[2];
128 unsigned int incounts[3]; 54 int len = read_param->len;
129 unsigned long flags; 55 char *buf = read_param->buf;
130 int i, stat; 56 int address = read_param->address;
131 57
132 if (address / 8 != (address + len - 1) / 8) 58 dev_info(&spi->dev, "spiclk %u KHz.\n",
133 return -EINVAL; 59 (spi->max_speed_hz + 500) / 1000);
134 stat = spi_eeprom_write_enable(chipid, 1); 60 if (read_param->chipid != spi->chip_select)
135 if (stat < 0) 61 return -ENODEV;
136 return stat; 62 while (len > 0) {
137 stat = spi_eeprom_read_status(chipid); 63 /* spi_write_then_read can only work with small chunk */
138 if (stat < 0) 64 int c = len < AT250X0_PAGE_SIZE ? len : AT250X0_PAGE_SIZE;
139 return stat; 65 cmd[0] = 0x03; /* AT25_READ */
140 if (!(stat & ATMEL_SR_WEN)) 66 cmd[1] = address;
141 return -EPERM; 67 stat = spi_write_then_read(spi, cmd, sizeof(cmd), buf, c);
142 68 buf += c;
143 inbuf[0] = ATMEL_WRITE; 69 len -= c;
144 inbuf[1] = address; 70 address += c;
145 inbufs[0] = inbuf;
146 inbufs[1] = buf;
147 incounts[0] = sizeof(inbuf);
148 incounts[1] = len;
149 incounts[2] = 0;
150 spin_lock_irqsave(&spi_eeprom_lock, flags);
151 stat = spi_eeprom_io(chipid, inbufs, incounts, NULL, NULL);
152 if (stat < 0)
153 goto unlock_return;
154
155 /* write start. max 10ms */
156 for (i = 10; i > 0; i--) {
157 int stat = spi_eeprom_read_status_nolock(chipid);
158 if (stat < 0)
159 goto unlock_return;
160 if (!(stat & ATMEL_SR_BSY))
161 break;
162 mdelay(1);
163 } 71 }
164 spin_unlock_irqrestore(&spi_eeprom_lock, flags);
165 if (i == 0)
166 return -EIO;
167 return len;
168 unlock_return:
169 spin_unlock_irqrestore(&spi_eeprom_lock, flags);
170 return stat; 72 return stat;
171} 73}
172 74
173#ifdef CONFIG_PROC_FS 75static struct spi_driver early_seeprom_driver __initdata = {
174#define MAX_SIZE 0x80 /* for ATMEL 25010 */ 76 .driver = {
175static int spi_eeprom_read_proc(char *page, char **start, off_t off, 77 .name = "at25",
176 int count, int *eof, void *data) 78 .owner = THIS_MODULE,
177{ 79 },
178 unsigned int size = MAX_SIZE; 80 .probe = early_seeprom_probe,
179 if (spi_eeprom_read((int)data, 0, (unsigned char *)page, size) < 0) 81};
180 size = 0;
181 return size;
182}
183
184static int spi_eeprom_write_proc(struct file *file, const char *buffer,
185 unsigned long count, void *data)
186{
187 unsigned int size = MAX_SIZE;
188 int i;
189 if (file->f_pos >= size)
190 return -EIO;
191 if (file->f_pos + count > size)
192 count = size - file->f_pos;
193 for (i = 0; i < count; i += 8) {
194 int len = count - i < 8 ? count - i : 8;
195 if (spi_eeprom_write((int)data, file->f_pos,
196 (unsigned char *)buffer, len) < 0) {
197 count = -EIO;
198 break;
199 }
200 buffer += len;
201 file->f_pos += len;
202 }
203 return count;
204}
205 82
206__init void spi_eeprom_proc_create(struct proc_dir_entry *dir, int chipid) 83int __init spi_eeprom_read(int chipid, int address,
84 unsigned char *buf, int len)
207{ 85{
208 struct proc_dir_entry *entry; 86 int ret;
209 char name[128]; 87 struct read_param param = {
210 sprintf(name, "seeprom-%d", chipid); 88 .chipid = chipid,
211 entry = create_proc_entry(name, 0600, dir); 89 .address = address,
212 if (entry) { 90 .buf = buf,
213 entry->read_proc = spi_eeprom_read_proc; 91 .len = len
214 entry->write_proc = spi_eeprom_write_proc; 92 };
215 entry->data = (void *)chipid; 93
216 } 94 read_param = &param;
95 ret = spi_register_driver(&early_seeprom_driver);
96 if (!ret)
97 spi_unregister_driver(&early_seeprom_driver);
98 return ret;
217} 99}
218#endif /* CONFIG_PROC_FS */
diff --git a/arch/mips/tx4938/toshiba_rbtx4938/spi_txx9.c b/arch/mips/tx4938/toshiba_rbtx4938/spi_txx9.c
deleted file mode 100644
index 08b20cdfd7b3..000000000000
--- a/arch/mips/tx4938/toshiba_rbtx4938/spi_txx9.c
+++ /dev/null
@@ -1,164 +0,0 @@
1/*
2 * linux/arch/mips/tx4938/toshiba_rbtx4938/spi_txx9.c
3 * Copyright (C) 2000-2001 Toshiba Corporation
4 *
5 * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
6 * terms of the GNU General Public License version 2. This program is
7 * licensed "as is" without any warranty of any kind, whether express
8 * or implied.
9 *
10 * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
11 */
12#include <linux/init.h>
13#include <linux/delay.h>
14#include <linux/errno.h>
15#include <linux/interrupt.h>
16#include <linux/module.h>
17#include <linux/sched.h>
18#include <linux/spinlock.h>
19#include <linux/wait.h>
20#include <asm/tx4938/spi.h>
21#include <asm/tx4938/tx4938.h>
22
23static int (*txx9_spi_cs_func)(int chipid, int on);
24static DEFINE_SPINLOCK(txx9_spi_lock);
25
26extern unsigned int txx9_gbus_clock;
27
28#define SPI_FIFO_SIZE 4
29
30void __init txx9_spi_init(unsigned long base, int (*cs_func)(int chipid, int on))
31{
32 txx9_spi_cs_func = cs_func;
33 /* enter config mode */
34 tx4938_spiptr->mcr = TXx9_SPMCR_CONFIG | TXx9_SPMCR_BCLR;
35}
36
37static DECLARE_WAIT_QUEUE_HEAD(txx9_spi_wait);
38
39static irqreturn_t txx9_spi_interrupt(int irq, void *dev_id)
40{
41 /* disable rx intr */
42 tx4938_spiptr->cr0 &= ~TXx9_SPCR0_RBSIE;
43 wake_up(&txx9_spi_wait);
44
45 return IRQ_HANDLED;
46}
47
48static struct irqaction txx9_spi_action = {
49 .handler = txx9_spi_interrupt,
50 .name = "spi",
51};
52
53void __init txx9_spi_irqinit(int irc_irq)
54{
55 setup_irq(irc_irq, &txx9_spi_action);
56}
57
58int txx9_spi_io(int chipid, struct spi_dev_desc *desc,
59 unsigned char **inbufs, unsigned int *incounts,
60 unsigned char **outbufs, unsigned int *outcounts,
61 int cansleep)
62{
63 unsigned int incount, outcount;
64 unsigned char *inp, *outp;
65 int ret;
66 unsigned long flags;
67
68 spin_lock_irqsave(&txx9_spi_lock, flags);
69 if ((tx4938_spiptr->mcr & TXx9_SPMCR_OPMODE) == TXx9_SPMCR_ACTIVE) {
70 spin_unlock_irqrestore(&txx9_spi_lock, flags);
71 return -EBUSY;
72 }
73 /* enter config mode */
74 tx4938_spiptr->mcr = TXx9_SPMCR_CONFIG | TXx9_SPMCR_BCLR;
75 tx4938_spiptr->cr0 =
76 (desc->byteorder ? TXx9_SPCR0_SBOS : 0) |
77 (desc->polarity ? TXx9_SPCR0_SPOL : 0) |
78 (desc->phase ? TXx9_SPCR0_SPHA : 0) |
79 0x08;
80 tx4938_spiptr->cr1 =
81 (((TXX9_IMCLK + desc->baud) / (2 * desc->baud) - 1) << 8) |
82 0x08 /* 8 bit only */;
83 /* enter active mode */
84 tx4938_spiptr->mcr = TXx9_SPMCR_ACTIVE;
85 spin_unlock_irqrestore(&txx9_spi_lock, flags);
86
87 /* CS ON */
88 if ((ret = txx9_spi_cs_func(chipid, 1)) < 0) {
89 spin_unlock_irqrestore(&txx9_spi_lock, flags);
90 return ret;
91 }
92 udelay(desc->tcss);
93
94 /* do scatter IO */
95 inp = inbufs ? *inbufs : NULL;
96 outp = outbufs ? *outbufs : NULL;
97 incount = 0;
98 outcount = 0;
99 while (1) {
100 unsigned char data;
101 unsigned int count;
102 int i;
103 if (!incount) {
104 incount = incounts ? *incounts++ : 0;
105 inp = (incount && inbufs) ? *inbufs++ : NULL;
106 }
107 if (!outcount) {
108 outcount = outcounts ? *outcounts++ : 0;
109 outp = (outcount && outbufs) ? *outbufs++ : NULL;
110 }
111 if (!inp && !outp)
112 break;
113 count = SPI_FIFO_SIZE;
114 if (incount)
115 count = min(count, incount);
116 if (outcount)
117 count = min(count, outcount);
118
119 /* now tx must be idle... */
120 while (!(tx4938_spiptr->sr & TXx9_SPSR_SIDLE))
121 ;
122
123 tx4938_spiptr->cr0 =
124 (tx4938_spiptr->cr0 & ~TXx9_SPCR0_RXIFL_MASK) |
125 ((count - 1) << 12);
126 if (cansleep) {
127 /* enable rx intr */
128 tx4938_spiptr->cr0 |= TXx9_SPCR0_RBSIE;
129 }
130 /* send */
131 for (i = 0; i < count; i++)
132 tx4938_spiptr->dr = inp ? *inp++ : 0;
133 /* wait all rx data */
134 if (cansleep) {
135 wait_event(txx9_spi_wait,
136 tx4938_spiptr->sr & TXx9_SPSR_SRRDY);
137 } else {
138 while (!(tx4938_spiptr->sr & TXx9_SPSR_RBSI))
139 ;
140 }
141 /* receive */
142 for (i = 0; i < count; i++) {
143 data = tx4938_spiptr->dr;
144 if (outp)
145 *outp++ = data;
146 }
147 if (incount)
148 incount -= count;
149 if (outcount)
150 outcount -= count;
151 }
152
153 /* CS OFF */
154 udelay(desc->tcsh);
155 txx9_spi_cs_func(chipid, 0);
156 udelay(desc->tcsr);
157
158 spin_lock_irqsave(&txx9_spi_lock, flags);
159 /* enter config mode */
160 tx4938_spiptr->mcr = TXx9_SPMCR_CONFIG | TXx9_SPMCR_BCLR;
161 spin_unlock_irqrestore(&txx9_spi_lock, flags);
162
163 return 0;
164}