aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2011-01-21 06:04:45 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2011-01-24 14:05:19 -0500
commit82e6923e1862428b755ec306b3dbccf926849314 (patch)
treee0be095c30c7cbfeff2a2096cf53e9c2f92fed13
parent1bae4ce27c9c90344f23c65ea6966c50ffeae2f5 (diff)
ARM: lh7a40x: remove unmaintained platform support
lh7a40x has only been receiving updates for updates to generic code. The last involvement from the maintainer according to the git logs was in 2006. As such, it is a maintainence burden with no benefit. This gets rid of two defconfigs. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r--Documentation/arm/Sharp-LH/ADC-LH7-Touchscreen61
-rw-r--r--Documentation/arm/Sharp-LH/CompactFlash32
-rw-r--r--Documentation/arm/Sharp-LH/IOBarrier45
-rw-r--r--Documentation/arm/Sharp-LH/KEV7A4008
-rw-r--r--Documentation/arm/Sharp-LH/LCDPanels59
-rw-r--r--Documentation/arm/Sharp-LH/LPD7A40015
-rw-r--r--Documentation/arm/Sharp-LH/LPD7A40X16
-rw-r--r--Documentation/arm/Sharp-LH/SDRAM51
-rw-r--r--Documentation/arm/Sharp-LH/VectoredInterruptController80
-rw-r--r--arch/arm/Kconfig13
-rw-r--r--arch/arm/Makefile1
-rw-r--r--arch/arm/configs/lpd7a400_defconfig68
-rw-r--r--arch/arm/configs/lpd7a404_defconfig81
-rw-r--r--arch/arm/include/asm/setup.h6
-rw-r--r--arch/arm/mach-lh7a40x/Kconfig74
-rw-r--r--arch/arm/mach-lh7a40x/Makefile17
-rw-r--r--arch/arm/mach-lh7a40x/Makefile.boot4
-rw-r--r--arch/arm/mach-lh7a40x/arch-kev7a400.c118
-rw-r--r--arch/arm/mach-lh7a40x/arch-lpd7a40x.c422
-rw-r--r--arch/arm/mach-lh7a40x/clcd.c241
-rw-r--r--arch/arm/mach-lh7a40x/clocks.c108
-rw-r--r--arch/arm/mach-lh7a40x/common.h17
-rw-r--r--arch/arm/mach-lh7a40x/include/mach/clocks.h18
-rw-r--r--arch/arm/mach-lh7a40x/include/mach/constants.h91
-rw-r--r--arch/arm/mach-lh7a40x/include/mach/debug-macro.S37
-rw-r--r--arch/arm/mach-lh7a40x/include/mach/dma.h86
-rw-r--r--arch/arm/mach-lh7a40x/include/mach/entry-macro.S149
-rw-r--r--arch/arm/mach-lh7a40x/include/mach/hardware.h62
-rw-r--r--arch/arm/mach-lh7a40x/include/mach/io.h20
-rw-r--r--arch/arm/mach-lh7a40x/include/mach/irqs.h200
-rw-r--r--arch/arm/mach-lh7a40x/include/mach/memory.h28
-rw-r--r--arch/arm/mach-lh7a40x/include/mach/registers.h224
-rw-r--r--arch/arm/mach-lh7a40x/include/mach/ssp.h70
-rw-r--r--arch/arm/mach-lh7a40x/include/mach/system.h19
-rw-r--r--arch/arm/mach-lh7a40x/include/mach/timex.h17
-rw-r--r--arch/arm/mach-lh7a40x/include/mach/uncompress.h38
-rw-r--r--arch/arm/mach-lh7a40x/include/mach/vmalloc.h10
-rw-r--r--arch/arm/mach-lh7a40x/irq-kev7a400.c93
-rw-r--r--arch/arm/mach-lh7a40x/irq-lh7a400.c91
-rw-r--r--arch/arm/mach-lh7a40x/irq-lh7a404.c175
-rw-r--r--arch/arm/mach-lh7a40x/irq-lpd7a40x.c128
-rw-r--r--arch/arm/mach-lh7a40x/lcd-panel.h345
-rw-r--r--arch/arm/mach-lh7a40x/ssp-cpld.c343
-rw-r--r--arch/arm/mach-lh7a40x/time.c71
-rw-r--r--drivers/net/smc91x.h62
-rw-r--r--drivers/tty/serial/Kconfig23
-rw-r--r--drivers/tty/serial/Makefile1
-rw-r--r--drivers/tty/serial/serial_lh7a40x.c682
-rw-r--r--drivers/usb/Kconfig1
-rw-r--r--drivers/usb/gadget/Kconfig12
-rw-r--r--drivers/usb/gadget/Makefile1
-rw-r--r--drivers/usb/gadget/gadget_chips.h8
-rw-r--r--drivers/usb/gadget/lh7a40x_udc.c2152
-rw-r--r--drivers/usb/gadget/lh7a40x_udc.h259
-rw-r--r--drivers/usb/host/ohci-hcd.c5
-rw-r--r--drivers/usb/host/ohci-lh7a404.c252
-rw-r--r--drivers/usb/host/ohci.h10
-rw-r--r--drivers/video/Kconfig63
58 files changed, 1 insertions, 7382 deletions
diff --git a/Documentation/arm/Sharp-LH/ADC-LH7-Touchscreen b/Documentation/arm/Sharp-LH/ADC-LH7-Touchscreen
deleted file mode 100644
index dc460f055647..000000000000
--- a/Documentation/arm/Sharp-LH/ADC-LH7-Touchscreen
+++ /dev/null
@@ -1,61 +0,0 @@
1README on the ADC/Touchscreen Controller
2========================================
3
4The LH79524 and LH7A404 include a built-in Analog to Digital
5controller (ADC) that is used to process input from a touchscreen.
6The driver only implements a four-wire touch panel protocol.
7
8The touchscreen driver is maintenance free except for the pen-down or
9touch threshold. Some resistive displays and board combinations may
10require tuning of this threshold. The driver exposes some of its
11internal state in the sys filesystem. If the kernel is configured
12with it, CONFIG_SYSFS, and sysfs is mounted at /sys, there will be a
13directory
14
15 /sys/devices/platform/adc-lh7.0
16
17containing these files.
18
19 -r--r--r-- 1 root root 4096 Jan 1 00:00 samples
20 -rw-r--r-- 1 root root 4096 Jan 1 00:00 threshold
21 -r--r--r-- 1 root root 4096 Jan 1 00:00 threshold_range
22
23The threshold is the current touch threshold. It defaults to 750 on
24most targets.
25
26 # cat threshold
27 750
28
29The threshold_range contains the range of valid values for the
30threshold. Values outside of this range will be silently ignored.
31
32 # cat threshold_range
33 0 1023
34
35To change the threshold, write a value to the threshold file.
36
37 # echo 500 > threshold
38 # cat threshold
39 500
40
41The samples file contains the most recently sampled values from the
42ADC. There are 12. Below are typical of the last sampled values when
43the pen has been released. The first two and last two samples are for
44detecting whether or not the pen is down. The third through sixth are
45X coordinate samples. The seventh through tenth are Y coordinate
46samples.
47
48 # cat samples
49 1023 1023 0 0 0 0 530 529 530 529 1023 1023
50
51To determine a reasonable threshold, press on the touch panel with an
52appropriate stylus and read the values from samples.
53
54 # cat samples
55 1023 676 92 103 101 102 855 919 922 922 1023 679
56
57The first and eleventh samples are discarded. Thus, the important
58values are the second and twelfth which are used to determine if the
59pen is down. When both are below the threshold, the driver registers
60that the pen is down. When either is above the threshold, it
61registers then pen is up.
diff --git a/Documentation/arm/Sharp-LH/CompactFlash b/Documentation/arm/Sharp-LH/CompactFlash
deleted file mode 100644
index 8616d877df9e..000000000000
--- a/Documentation/arm/Sharp-LH/CompactFlash
+++ /dev/null
@@ -1,32 +0,0 @@
1README on the Compact Flash for Card Engines
2============================================
3
4There are three challenges in supporting the CF interface of the Card
5Engines. First, every IO operation must be followed with IO to
6another memory region. Second, the slot is wired for one-to-one
7address mapping *and* it is wired for 16 bit access only. Second, the
8interrupt request line from the CF device isn't wired.
9
10The IOBARRIER issue is covered in README.IOBARRIER. This isn't an
11onerous problem. Enough said here.
12
13The addressing issue is solved in the
14arch/arm/mach-lh7a40x/ide-lpd7a40x.c file with some awkward
15work-arounds. We implement a special SELECT_DRIVE routine that is
16called before the IDE driver performs its own SELECT_DRIVE. Our code
17recognizes that the SELECT register cannot be modified without also
18writing a command. It send an IDLE_IMMEDIATE command on selecting a
19drive. The function also prevents drive select to the slave drive
20since there can be only one. The awkward part is that the IDE driver,
21even though we have a select procedure, also attempts to change the
22drive by writing directly the SELECT register. This attempt is
23explicitly blocked by the OUTB function--not pretty, but effective.
24
25The lack of interrupts is a more serious problem. Even though the CF
26card is fast when compared to a normal IDE device, we don't know that
27the CF is really flash. A user could use one of the very small hard
28drives being shipped with a CF interface. The IDE code includes a
29check for interfaces that lack an IRQ. In these cases, submitting a
30command to the IDE controller is followed by a call to poll for
31completion. If the device isn't immediately ready, it schedules a
32timer to poll again later.
diff --git a/Documentation/arm/Sharp-LH/IOBarrier b/Documentation/arm/Sharp-LH/IOBarrier
deleted file mode 100644
index 2e953e228f4d..000000000000
--- a/Documentation/arm/Sharp-LH/IOBarrier
+++ /dev/null
@@ -1,45 +0,0 @@
1README on the IOBARRIER for CardEngine IO
2=========================================
3
4Due to an unfortunate oversight when the Card Engines were designed,
5the signals that control access to some peripherals, most notably the
6SMC91C9111 ethernet controller, are not properly handled.
7
8The symptom is that some back to back IO with the peripheral returns
9unreliable data. With the SMC chip, you'll see errors about the bank
10register being 'screwed'.
11
12The cause is that the AEN signal to the SMC chip does not transition
13for every memory access. It is driven through the CPLD from the CS7
14line of the CPU's static memory controller which is optimized to
15eliminate unnecessary transitions. Yet, the SMC requires a transition
16for every write access. The Sharp website has more information about
17the effect this power-conserving feature has on peripheral
18interfacing.
19
20The solution is to follow every write access to the SMC chip with an
21access to another memory region that will force the CPU to release the
22chip select line. It is important to guarantee that this access
23forces the CPU off-chip. We map a page of SDRAM as if it were an
24uncacheable IO device and read from it after every SMC IO write
25operation.
26
27 SMC IO
28 BARRIER IO
29
30Only this sequence is important. It does not matter that there is no
31BARRIER IO before the access to the SMC chip because the AEN latch
32only needs occurs after the SMC IO write cycle. The routines that
33implement this work-around make an additional concession which is to
34disable interrupts during the IO sequence. Other hardware devices
35(the LogicPD CPLD) have registers in the same physical memory
36region as the SMC chip. An interrupt might allow an access to one of
37those registers while SMC IO is being performed.
38
39You might be tempted to think that we have to access another device
40attached to the static memory controller, but the empirical evidence
41indicates that this is not so. Mapping 0x00000000 (flash) and
420xc0000000 (SDRAM) appear to have the same effect. Using SDRAM seems
43to be faster. Choosing to access an undecoded memory region is not
44desirable as there is no way to know how that chip select will be used
45in the future.
diff --git a/Documentation/arm/Sharp-LH/KEV7A400 b/Documentation/arm/Sharp-LH/KEV7A400
deleted file mode 100644
index be32b14cd535..000000000000
--- a/Documentation/arm/Sharp-LH/KEV7A400
+++ /dev/null
@@ -1,8 +0,0 @@
1README on Implementing Linux for Sharp's KEV7a400
2=================================================
3
4This product has been discontinued by Sharp. For the time being, the
5partially implemented code remains in the kernel. At some point in
6the future, either the code will be finished or it will be removed
7completely. This depends primarily on how many of the development
8boards are in the field.
diff --git a/Documentation/arm/Sharp-LH/LCDPanels b/Documentation/arm/Sharp-LH/LCDPanels
deleted file mode 100644
index fb1b21c2f2f4..000000000000
--- a/Documentation/arm/Sharp-LH/LCDPanels
+++ /dev/null
@@ -1,59 +0,0 @@
1README on the LCD Panels
2========================
3
4Configuration options for several LCD panels, available from Logic PD,
5are included in the kernel source. This README will help you
6understand the configuration data and give you some guidance for
7adding support for other panels if you wish.
8
9
10lcd-panels.h
11------------
12
13There is no way, at present, to detect which panel is attached to the
14system at runtime. Thus the kernel configuration is static. The file
15arch/arm/mach-ld7a40x/lcd-panels.h (or similar) defines all of the
16panel specific parameters.
17
18It should be possible for this data to be shared among several device
19families. The current layout may be insufficiently general, but it is
20amenable to improvement.
21
22
23PIXEL_CLOCK
24-----------
25
26The panel data sheets will give a range of acceptable pixel clocks.
27The fundamental LCDCLK input frequency is divided down by a PCD
28constant in field '.tim2'. It may happen that it is impossible to set
29the pixel clock within this range. A clock which is too slow will
30tend to flicker. For the highest quality image, set the clock as high
31as possible.
32
33
34MARGINS
35-------
36
37These values may be difficult to glean from the panel data sheet. In
38the case of the Sharp panels, the upper margin is explicitly called
39out as a specific number of lines from the top of the frame. The
40other values may not matter as much as the panels tend to
41automatically center the image.
42
43
44Sync Sense
45----------
46
47The sense of the hsync and vsync pulses may be called out in the data
48sheet. On one panel, the sense of these pulses determine the height
49of the visible region on the panel. Most of the Sharp panels use
50negative sense sync pulses set by the TIM2_IHS and TIM2_IVS bits in
51'.tim2'.
52
53
54Pel Layout
55----------
56
57The Sharp color TFT panels are all configured for 16 bit direct color
58modes. The amba-lcd driver sets the pel mode to 565 for 5 bits of
59each red and blue and 6 bits of green.
diff --git a/Documentation/arm/Sharp-LH/LPD7A400 b/Documentation/arm/Sharp-LH/LPD7A400
deleted file mode 100644
index 3275b453bfdf..000000000000
--- a/Documentation/arm/Sharp-LH/LPD7A400
+++ /dev/null
@@ -1,15 +0,0 @@
1README on Implementing Linux for the Logic PD LPD7A400-10
2=========================================================
3
4- CPLD memory mapping
5
6 The board designers chose to use high address lines for controlling
7 access to the CPLD registers. It turns out to be a big waste
8 because we're using an MMU and must map IO space into virtual
9 memory. The result is that we have to make a mapping for every
10 register.
11
12- Serial Console
13
14 It may be OK not to use the serial console option if the user passes
15 the console device name to the kernel. This deserves some exploration.
diff --git a/Documentation/arm/Sharp-LH/LPD7A40X b/Documentation/arm/Sharp-LH/LPD7A40X
deleted file mode 100644
index 8c29a27e208f..000000000000
--- a/Documentation/arm/Sharp-LH/LPD7A40X
+++ /dev/null
@@ -1,16 +0,0 @@
1README on Implementing Linux for the Logic PD LPD7A40X-10
2=========================================================
3
4- CPLD memory mapping
5
6 The board designers chose to use high address lines for controlling
7 access to the CPLD registers. It turns out to be a big waste
8 because we're using an MMU and must map IO space into virtual
9 memory. The result is that we have to make a mapping for every
10 register.
11
12- Serial Console
13
14 It may be OK not to use the serial console option if the user passes
15 the console device name to the kernel. This deserves some exploration.
16
diff --git a/Documentation/arm/Sharp-LH/SDRAM b/Documentation/arm/Sharp-LH/SDRAM
deleted file mode 100644
index 93ddc23c2faa..000000000000
--- a/Documentation/arm/Sharp-LH/SDRAM
+++ /dev/null
@@ -1,51 +0,0 @@
1README on the SDRAM Controller for the LH7a40X
2==============================================
3
4The standard configuration for the SDRAM controller generates a sparse
5memory array. The precise layout is determined by the SDRAM chips. A
6default kernel configuration assembles the discontiguous memory
7regions into separate memory nodes via the NUMA (Non-Uniform Memory
8Architecture) facilities. In this default configuration, the kernel
9is forgiving about the precise layout. As long as it is given an
10accurate picture of available memory by the bootloader the kernel will
11execute correctly.
12
13The SDRC supports a mode where some of the chip select lines are
14swapped in order to make SDRAM look like a synchronous ROM. Setting
15this bit means that the RAM will present as a contiguous array. Some
16programmers prefer this to the discontiguous layout. Be aware that
17may be a penalty for this feature where some some configurations of
18memory are significantly reduced; i.e. 64MiB of RAM appears as only 32
19MiB.
20
21There are a couple of configuration options to override the default
22behavior. When the SROMLL bit is set and memory appears as a
23contiguous array, there is no reason to support NUMA.
24CONFIG_LH7A40X_CONTIGMEM disables NUMA support. When physical memory
25is discontiguous, the memory tables are organized such that there are
26two banks per nodes with a small gap between them. This layout wastes
27some kernel memory for page tables representing non-existent memory.
28CONFIG_LH7A40X_ONE_BANK_PER_NODE optimizes the node tables such that
29there are no gaps. These options control the low level organization
30of the memory management tables in ways that may prevent the kernel
31from booting or may cause the kernel to allocated excessively large
32page tables. Be warned. Only change these options if you know what
33you are doing. The default behavior is a reasonable compromise that
34will suit all users.
35
36--
37
38A typical 32MiB system with the default configuration options will
39find physical memory managed as follows.
40
41 node 0: 0xc0000000 4MiB
42 0xc1000000 4MiB
43 node 1: 0xc4000000 4MiB
44 0xc5000000 4MiB
45 node 2: 0xc8000000 4MiB
46 0xc9000000 4MiB
47 node 3: 0xcc000000 4MiB
48 0xcd000000 4MiB
49
50Setting CONFIG_LH7A40X_ONE_BANK_PER_NODE will put each bank into a
51separate node.
diff --git a/Documentation/arm/Sharp-LH/VectoredInterruptController b/Documentation/arm/Sharp-LH/VectoredInterruptController
deleted file mode 100644
index 23047e9861ee..000000000000
--- a/Documentation/arm/Sharp-LH/VectoredInterruptController
+++ /dev/null
@@ -1,80 +0,0 @@
1README on the Vectored Interrupt Controller of the LH7A404
2==========================================================
3
4The 404 revision of the LH7A40X series comes with two vectored
5interrupts controllers. While the kernel does use some of the
6features of these devices, it is far from the purpose for which they
7were designed.
8
9When this README was written, the implementation of the VICs was in
10flux. It is possible that some details, especially with priorities,
11will change.
12
13The VIC support code is inspired by routines written by Sharp.
14
15
16Priority Control
17----------------
18
19The significant reason for using the VIC's vectoring is to control
20interrupt priorities. There are two tables in
21arch/arm/mach-lh7a40x/irq-lh7a404.c that look something like this.
22
23 static unsigned char irq_pri_vic1[] = { IRQ_GPIO3INTR, };
24 static unsigned char irq_pri_vic2[] = {
25 IRQ_T3UI, IRQ_GPIO7INTR,
26 IRQ_UART1INTR, IRQ_UART2INTR, IRQ_UART3INTR, };
27
28The initialization code reads these tables and inserts a vector
29address and enable for each indicated IRQ. Vectored interrupts have
30higher priority than non-vectored interrupts. So, on VIC1,
31IRQ_GPIO3INTR will be served before any other non-FIQ interrupt. Due
32to the way that the vectoring works, IRQ_T3UI is the next highest
33priority followed by the other vectored interrupts on VIC2. After
34that, the non-vectored interrupts are scanned in VIC1 then in VIC2.
35
36
37ISR
38---
39
40The interrupt service routine macro get_irqnr() in
41arch/arm/kernel/entry-armv.S scans the VICs for the next active
42interrupt. The vectoring makes this code somewhat larger than it was
43before using vectoring (refer to the LH7A400 implementation). In the
44case where an interrupt is vectored, the implementation will tend to
45be faster than the non-vectored version. However, the worst-case path
46is longer.
47
48It is worth noting that at present, there is no need to read
49VIC2_VECTADDR because the register appears to be shared between the
50controllers. The code is written such that if this changes, it ought
51to still work properly.
52
53
54Vector Addresses
55----------------
56
57The proper use of the vectoring hardware would jump to the ISR
58specified by the vectoring address. Linux isn't structured to take
59advantage of this feature, though it might be possible to change
60things to support it.
61
62In this implementation, the vectoring address is used to speed the
63search for the active IRQ. The address is coded such that the lowest
646 bits store the IRQ number for vectored interrupts. These numbers
65correspond to the bits in the interrupt status registers. IRQ zero is
66the lowest interrupt bit in VIC1. IRQ 32 is the lowest interrupt bit
67in VIC2. Because zero is a valid IRQ number and because we cannot
68detect whether or not there is a valid vectoring address if that
69address is zero, the eigth bit (0x100) is set for vectored interrupts.
70The address for IRQ 0x18 (VIC2) is 0x118. Only the ninth bit is set
71for the default handler on VIC1 and only the tenth bit is set for the
72default handler on VIC2.
73
74In other words.
75
76 0x000 - no active interrupt
77 0x1ii - vectored interrupt 0xii
78 0x2xx - unvectored interrupt on VIC1 (xx is don't care)
79 0x4xx - unvectored interrupt on VIC2 (xx is don't care)
80
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 5cff165b7eb0..18a1eb93fd72 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -795,17 +795,6 @@ config ARCH_TCC_926
795 help 795 help
796 Support for Telechips TCC ARM926-based systems. 796 Support for Telechips TCC ARM926-based systems.
797 797
798config ARCH_LH7A40X
799 bool "Sharp LH7A40X"
800 select CPU_ARM922T
801 select ARCH_SPARSEMEM_ENABLE if !LH7A40X_CONTIGMEM
802 select ARCH_USES_GETTIMEOFFSET
803 help
804 Say Y here for systems based on one of the Sharp LH7A40X
805 System on a Chip processors. These CPUs include an ARM922T
806 core with a wide array of integrated devices for
807 hand-held and low-power applications.
808
809config ARCH_U300 798config ARCH_U300
810 bool "ST-Ericsson U300 Series" 799 bool "ST-Ericsson U300 Series"
811 depends on MMU 800 depends on MMU
@@ -922,8 +911,6 @@ source "arch/arm/mach-kirkwood/Kconfig"
922 911
923source "arch/arm/mach-ks8695/Kconfig" 912source "arch/arm/mach-ks8695/Kconfig"
924 913
925source "arch/arm/mach-lh7a40x/Kconfig"
926
927source "arch/arm/mach-loki/Kconfig" 914source "arch/arm/mach-loki/Kconfig"
928 915
929source "arch/arm/mach-lpc32xx/Kconfig" 916source "arch/arm/mach-lpc32xx/Kconfig"
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index c22c1adfedd6..aa18cb9da57b 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -146,7 +146,6 @@ machine-$(CONFIG_ARCH_IXP23XX) := ixp23xx
146machine-$(CONFIG_ARCH_IXP4XX) := ixp4xx 146machine-$(CONFIG_ARCH_IXP4XX) := ixp4xx
147machine-$(CONFIG_ARCH_KIRKWOOD) := kirkwood 147machine-$(CONFIG_ARCH_KIRKWOOD) := kirkwood
148machine-$(CONFIG_ARCH_KS8695) := ks8695 148machine-$(CONFIG_ARCH_KS8695) := ks8695
149machine-$(CONFIG_ARCH_LH7A40X) := lh7a40x
150machine-$(CONFIG_ARCH_LOKI) := loki 149machine-$(CONFIG_ARCH_LOKI) := loki
151machine-$(CONFIG_ARCH_LPC32XX) := lpc32xx 150machine-$(CONFIG_ARCH_LPC32XX) := lpc32xx
152machine-$(CONFIG_ARCH_MMP) := mmp 151machine-$(CONFIG_ARCH_MMP) := mmp
diff --git a/arch/arm/configs/lpd7a400_defconfig b/arch/arm/configs/lpd7a400_defconfig
deleted file mode 100644
index 5a48f171204c..000000000000
--- a/arch/arm/configs/lpd7a400_defconfig
+++ /dev/null
@@ -1,68 +0,0 @@
1CONFIG_EXPERIMENTAL=y
2# CONFIG_SWAP is not set
3CONFIG_SYSVIPC=y
4CONFIG_IKCONFIG=y
5CONFIG_LOG_BUF_SHIFT=14
6CONFIG_EXPERT=y
7# CONFIG_HOTPLUG is not set
8# CONFIG_EPOLL is not set
9# CONFIG_IOSCHED_DEADLINE is not set
10CONFIG_ARCH_LH7A40X=y
11CONFIG_MACH_LPD7A400=y
12CONFIG_PREEMPT=y
13CONFIG_ZBOOT_ROM_TEXT=0x0
14CONFIG_ZBOOT_ROM_BSS=0x0
15CONFIG_FPE_NWFPE=y
16CONFIG_NET=y
17CONFIG_PACKET=y
18CONFIG_UNIX=y
19CONFIG_INET=y
20CONFIG_IP_PNP=y
21CONFIG_IP_PNP_DHCP=y
22CONFIG_IP_PNP_BOOTP=y
23CONFIG_IP_PNP_RARP=y
24# CONFIG_IPV6 is not set
25CONFIG_MTD=y
26CONFIG_MTD_PARTITIONS=y
27CONFIG_MTD_CMDLINE_PARTS=y
28CONFIG_MTD_CHAR=y
29CONFIG_MTD_BLOCK=y
30CONFIG_MTD_CFI=y
31CONFIG_MTD_CFI_INTELEXT=y
32CONFIG_MTD_PHYSMAP=y
33CONFIG_BLK_DEV_LOOP=y
34CONFIG_IDE=y
35CONFIG_SCSI=y
36# CONFIG_SCSI_PROC_FS is not set
37CONFIG_NETDEVICES=y
38CONFIG_NET_ETHERNET=y
39CONFIG_SMC91X=y
40# CONFIG_INPUT_MOUSEDEV is not set
41CONFIG_INPUT_EVDEV=y
42# CONFIG_INPUT_KEYBOARD is not set
43# CONFIG_INPUT_MOUSE is not set
44CONFIG_INPUT_TOUCHSCREEN=y
45# CONFIG_SERIO is not set
46CONFIG_SERIAL_LH7A40X=y
47CONFIG_SERIAL_LH7A40X_CONSOLE=y
48CONFIG_FB=y
49# CONFIG_VGA_CONSOLE is not set
50CONFIG_SOUND=y
51CONFIG_SND=y
52CONFIG_SND_MIXER_OSS=y
53CONFIG_SND_PCM_OSS=y
54CONFIG_EXT2_FS=y
55CONFIG_EXT3_FS=y
56CONFIG_VFAT_FS=y
57CONFIG_TMPFS=y
58CONFIG_JFFS2_FS=y
59CONFIG_CRAMFS=y
60CONFIG_NFS_FS=y
61CONFIG_NFS_V3=y
62CONFIG_ROOT_NFS=y
63CONFIG_PARTITION_ADVANCED=y
64CONFIG_MAGIC_SYSRQ=y
65CONFIG_DEBUG_KERNEL=y
66CONFIG_DEBUG_INFO=y
67CONFIG_DEBUG_USER=y
68CONFIG_DEBUG_ERRORS=y
diff --git a/arch/arm/configs/lpd7a404_defconfig b/arch/arm/configs/lpd7a404_defconfig
deleted file mode 100644
index 22d0631de009..000000000000
--- a/arch/arm/configs/lpd7a404_defconfig
+++ /dev/null
@@ -1,81 +0,0 @@
1CONFIG_EXPERIMENTAL=y
2# CONFIG_SWAP is not set
3CONFIG_SYSVIPC=y
4CONFIG_IKCONFIG=y
5CONFIG_LOG_BUF_SHIFT=16
6CONFIG_EXPERT=y
7# CONFIG_HOTPLUG is not set
8# CONFIG_EPOLL is not set
9CONFIG_SLAB=y
10# CONFIG_IOSCHED_DEADLINE is not set
11CONFIG_ARCH_LH7A40X=y
12CONFIG_MACH_LPD7A404=y
13CONFIG_PREEMPT=y
14CONFIG_DISCONTIGMEM_MANUAL=y
15CONFIG_ZBOOT_ROM_TEXT=0x0
16CONFIG_ZBOOT_ROM_BSS=0x0
17CONFIG_FPE_NWFPE=y
18CONFIG_NET=y
19CONFIG_PACKET=y
20CONFIG_UNIX=y
21CONFIG_INET=y
22CONFIG_IP_PNP=y
23CONFIG_IP_PNP_DHCP=y
24CONFIG_IP_PNP_BOOTP=y
25CONFIG_IP_PNP_RARP=y
26# CONFIG_IPV6 is not set
27CONFIG_MTD=y
28CONFIG_MTD_PARTITIONS=y
29CONFIG_MTD_CMDLINE_PARTS=y
30CONFIG_MTD_CHAR=y
31CONFIG_MTD_BLOCK=y
32CONFIG_MTD_CFI=y
33CONFIG_MTD_CFI_INTELEXT=y
34CONFIG_MTD_PHYSMAP=y
35CONFIG_BLK_DEV_LOOP=y
36CONFIG_IDE=y
37CONFIG_SCSI=y
38# CONFIG_SCSI_PROC_FS is not set
39CONFIG_NETDEVICES=y
40CONFIG_NET_ETHERNET=y
41CONFIG_SMC91X=y
42# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
43CONFIG_INPUT_EVDEV=y
44# CONFIG_INPUT_KEYBOARD is not set
45# CONFIG_INPUT_MOUSE is not set
46CONFIG_INPUT_TOUCHSCREEN=y
47# CONFIG_SERIO is not set
48CONFIG_SERIAL_LH7A40X=y
49CONFIG_SERIAL_LH7A40X_CONSOLE=y
50CONFIG_FB=y
51# CONFIG_VGA_CONSOLE is not set
52CONFIG_SOUND=y
53CONFIG_SND=y
54CONFIG_SND_MIXER_OSS=y
55CONFIG_SND_PCM_OSS=y
56CONFIG_USB=y
57CONFIG_USB_DEVICEFS=y
58CONFIG_USB_MON=y
59CONFIG_USB_OHCI_HCD=y
60CONFIG_USB_STORAGE=y
61CONFIG_USB_STORAGE_DEBUG=y
62CONFIG_USB_STORAGE_DATAFAB=y
63CONFIG_USB_GADGET=y
64CONFIG_USB_ZERO=y
65CONFIG_EXT2_FS=y
66CONFIG_EXT3_FS=y
67CONFIG_INOTIFY=y
68CONFIG_VFAT_FS=y
69CONFIG_TMPFS=y
70CONFIG_JFFS2_FS=y
71CONFIG_CRAMFS=y
72CONFIG_NFS_FS=y
73CONFIG_NFS_V3=y
74CONFIG_ROOT_NFS=y
75CONFIG_PARTITION_ADVANCED=y
76CONFIG_MAGIC_SYSRQ=y
77CONFIG_DEBUG_KERNEL=y
78CONFIG_DEBUG_MUTEXES=y
79CONFIG_DEBUG_INFO=y
80CONFIG_DEBUG_USER=y
81CONFIG_DEBUG_ERRORS=y
diff --git a/arch/arm/include/asm/setup.h b/arch/arm/include/asm/setup.h
index f1e5a9bca249..da8b52ec49cf 100644
--- a/arch/arm/include/asm/setup.h
+++ b/arch/arm/include/asm/setup.h
@@ -192,11 +192,7 @@ static struct tagtable __tagtable_##fn __tag = { tag, fn }
192/* 192/*
193 * Memory map description 193 * Memory map description
194 */ 194 */
195#ifdef CONFIG_ARCH_LH7A40X 195#define NR_BANKS 8
196# define NR_BANKS 16
197#else
198# define NR_BANKS 8
199#endif
200 196
201struct membank { 197struct membank {
202 unsigned long start; 198 unsigned long start;
diff --git a/arch/arm/mach-lh7a40x/Kconfig b/arch/arm/mach-lh7a40x/Kconfig
deleted file mode 100644
index 9be7466e346c..000000000000
--- a/arch/arm/mach-lh7a40x/Kconfig
+++ /dev/null
@@ -1,74 +0,0 @@
1if ARCH_LH7A40X
2
3menu "LH7A40X Implementations"
4
5config MACH_KEV7A400
6 bool "KEV7A400"
7 select ARCH_LH7A400
8 help
9 Say Y here if you are using the Sharp KEV7A400 development
10 board. This hardware is discontinued, so I'd be very
11 surprised if you wanted this option.
12
13config MACH_LPD7A400
14 bool "LPD7A400 Card Engine"
15 select ARCH_LH7A400
16# select IDE_POLL
17# select HAS_TOUCHSCREEN_ADS7843_LH7
18 help
19 Say Y here if you are using Logic Product Development's
20 LPD7A400 CardEngine. For the time being, the LPD7A400 and
21 LPD7A404 options are mutually exclusive.
22
23config MACH_LPD7A404
24 bool "LPD7A404 Card Engine"
25 select ARCH_LH7A404
26# select IDE_POLL
27# select HAS_TOUCHSCREEN_ADC_LH7
28 help
29 Say Y here if you are using Logic Product Development's
30 LPD7A404 CardEngine. For the time being, the LPD7A400 and
31 LPD7A404 options are mutually exclusive.
32
33config ARCH_LH7A400
34 bool
35
36config ARCH_LH7A404
37 bool
38
39config LPD7A40X_CPLD_SSP
40 bool
41
42config LH7A40X_CONTIGMEM
43 bool "Disable NUMA/SparseMEM Support"
44 help
45 Say Y here if your bootloader sets the SROMLL bit(s) in
46 the SDRAM controller, organizing memory as a contiguous
47 array. This option will disable sparse memory support
48 and force the kernel to manage all memory in one node.
49
50 Setting this option incorrectly may prevent the kernel
51 from booting. It is OK to leave it N.
52
53 For more information, consult
54 <file:Documentation/arm/Sharp-LH/SDRAM>.
55
56config LH7A40X_ONE_BANK_PER_NODE
57 bool "Optimize NUMA Node Tables for Size"
58 depends on !LH7A40X_CONTIGMEM
59 help
60 Say Y here to produce compact memory node tables. By
61 default pairs of adjacent physical RAM banks are managed
62 together in a single node, incurring some wasted overhead
63 in the node tables, however also maintaining compatibility
64 with systems where physical memory is truly contiguous.
65
66 Setting this option incorrectly may prevent the kernel from
67 booting. It is OK to leave it N.
68
69 For more information, consult
70 <file:Documentation/arm/Sharp-LH/SDRAM>.
71
72endmenu
73
74endif
diff --git a/arch/arm/mach-lh7a40x/Makefile b/arch/arm/mach-lh7a40x/Makefile
deleted file mode 100644
index 94b8615fb3c3..000000000000
--- a/arch/arm/mach-lh7a40x/Makefile
+++ /dev/null
@@ -1,17 +0,0 @@
1#
2# Makefile for the linux kernel.
3#
4
5# Object file lists.
6
7obj-y := time.o clocks.o
8obj-m :=
9obj-n :=
10obj- :=
11
12obj-$(CONFIG_MACH_KEV7A400) += arch-kev7a400.o irq-lh7a400.o
13obj-$(CONFIG_MACH_LPD7A400) += arch-lpd7a40x.o irq-lh7a400.o
14obj-$(CONFIG_MACH_LPD7A404) += arch-lpd7a40x.o irq-lh7a404.o
15obj-$(CONFIG_LPD7A40X_CPLD_SSP) += ssp-cpld.o
16obj-$(CONFIG_FB_ARMCLCD) += clcd.o
17
diff --git a/arch/arm/mach-lh7a40x/Makefile.boot b/arch/arm/mach-lh7a40x/Makefile.boot
deleted file mode 100644
index af941be076eb..000000000000
--- a/arch/arm/mach-lh7a40x/Makefile.boot
+++ /dev/null
@@ -1,4 +0,0 @@
1 zreladdr-y := 0xc0008000
2params_phys-y := 0xc0000100
3initrd_phys-y := 0xc4000000
4
diff --git a/arch/arm/mach-lh7a40x/arch-kev7a400.c b/arch/arm/mach-lh7a40x/arch-kev7a400.c
deleted file mode 100644
index 71129c33c7d2..000000000000
--- a/arch/arm/mach-lh7a40x/arch-kev7a400.c
+++ /dev/null
@@ -1,118 +0,0 @@
1/* arch/arm/mach-lh7a40x/arch-kev7a400.c
2 *
3 * Copyright (C) 2004 Logic Product Development
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * version 2 as published by the Free Software Foundation.
8 *
9 */
10
11#include <linux/tty.h>
12#include <linux/init.h>
13#include <linux/device.h>
14#include <linux/interrupt.h>
15
16#include <mach/hardware.h>
17#include <asm/setup.h>
18#include <asm/mach-types.h>
19#include <asm/mach/arch.h>
20#include <asm/irq.h>
21#include <asm/mach/irq.h>
22#include <asm/mach/map.h>
23
24#include "common.h"
25
26 /* This function calls the board specific IRQ initialization function. */
27
28static struct map_desc kev7a400_io_desc[] __initdata = {
29 {
30 .virtual = IO_VIRT,
31 .pfn = __phys_to_pfn(IO_PHYS),
32 .length = IO_SIZE,
33 .type = MT_DEVICE
34 }, {
35 .virtual = CPLD_VIRT,
36 .pfn = __phys_to_pfn(CPLD_PHYS),
37 .length = CPLD_SIZE,
38 .type = MT_DEVICE
39 }
40};
41
42void __init kev7a400_map_io(void)
43{
44 iotable_init (kev7a400_io_desc, ARRAY_SIZE (kev7a400_io_desc));
45}
46
47static u16 CPLD_IRQ_mask; /* Mask for CPLD IRQs, 1 == unmasked */
48
49static void kev7a400_ack_cpld_irq(struct irq_data *d)
50{
51 CPLD_CL_INT = 1 << (d->irq - IRQ_KEV7A400_CPLD);
52}
53
54static void kev7a400_mask_cpld_irq(struct irq_data *d)
55{
56 CPLD_IRQ_mask &= ~(1 << (d->irq - IRQ_KEV7A400_CPLD));
57 CPLD_WR_PB_INT_MASK = CPLD_IRQ_mask;
58}
59
60static void kev7a400_unmask_cpld_irq(struct irq_data *d)
61{
62 CPLD_IRQ_mask |= 1 << (d->irq - IRQ_KEV7A400_CPLD);
63 CPLD_WR_PB_INT_MASK = CPLD_IRQ_mask;
64}
65
66static struct irq_chip kev7a400_cpld_chip = {
67 .name = "CPLD",
68 .irq_ack = kev7a400_ack_cpld_irq,
69 .irq_mask = kev7a400_mask_cpld_irq,
70 .irq_unmask = kev7a400_unmask_cpld_irq,
71};
72
73
74static void kev7a400_cpld_handler (unsigned int irq, struct irq_desc *desc)
75{
76 u32 mask = CPLD_LATCHED_INTS;
77 irq = IRQ_KEV7A400_CPLD;
78 for (; mask; mask >>= 1, ++irq)
79 if (mask & 1)
80 generic_handle_irq(irq);
81}
82
83void __init lh7a40x_init_board_irq (void)
84{
85 int irq;
86
87 for (irq = IRQ_KEV7A400_CPLD;
88 irq < IRQ_KEV7A400_CPLD + NR_IRQ_BOARD; ++irq) {
89 set_irq_chip (irq, &kev7a400_cpld_chip);
90 set_irq_handler (irq, handle_edge_irq);
91 set_irq_flags (irq, IRQF_VALID);
92 }
93 set_irq_chained_handler (IRQ_CPLD, kev7a400_cpld_handler);
94
95 /* Clear all CPLD interrupts */
96 CPLD_CL_INT = 0xff; /* CPLD_INTR_MMC_CD | CPLD_INTR_ETH_INT; */
97
98 GPIO_GPIOINTEN = 0; /* Disable all GPIO interrupts */
99 barrier();
100
101#if 0
102 GPIO_INTTYPE1
103 = (GPIO_INTR_PCC1_CD | GPIO_INTR_PCC1_CD); /* Edge trig. */
104 GPIO_INTTYPE2 = 0; /* Falling edge & low-level */
105 GPIO_GPIOFEOI = 0xff; /* Clear all GPIO interrupts */
106 GPIO_GPIOINTEN = 0xff; /* Enable all GPIO interrupts */
107
108 init_FIQ();
109#endif
110}
111
112MACHINE_START (KEV7A400, "Sharp KEV7a400")
113 /* Maintainer: Marc Singer */
114 .boot_params = 0xc0000100,
115 .map_io = kev7a400_map_io,
116 .init_irq = lh7a400_init_irq,
117 .timer = &lh7a40x_timer,
118MACHINE_END
diff --git a/arch/arm/mach-lh7a40x/arch-lpd7a40x.c b/arch/arm/mach-lh7a40x/arch-lpd7a40x.c
deleted file mode 100644
index e735546181ad..000000000000
--- a/arch/arm/mach-lh7a40x/arch-lpd7a40x.c
+++ /dev/null
@@ -1,422 +0,0 @@
1/* arch/arm/mach-lh7a40x/arch-lpd7a40x.c
2 *
3 * Copyright (C) 2004 Logic Product Development
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * version 2 as published by the Free Software Foundation.
8 *
9 */
10
11#include <linux/tty.h>
12#include <linux/init.h>
13#include <linux/platform_device.h>
14#include <linux/interrupt.h>
15#include <linux/irq.h>
16
17#include <mach/hardware.h>
18#include <asm/setup.h>
19#include <asm/mach-types.h>
20#include <asm/mach/arch.h>
21#include <asm/irq.h>
22#include <asm/mach/irq.h>
23#include <asm/mach/map.h>
24
25#include "common.h"
26
27#define CPLD_INT_NETHERNET (1<<0)
28#define CPLD_INTMASK_ETHERNET (1<<2)
29#if defined (CONFIG_MACH_LPD7A400)
30# define CPLD_INT_NTOUCH (1<<1)
31# define CPLD_INTMASK_TOUCH (1<<3)
32# define CPLD_INT_PEN (1<<4)
33# define CPLD_INTMASK_PEN (1<<4)
34# define CPLD_INT_PIRQ (1<<4)
35#endif
36#define CPLD_INTMASK_CPLD (1<<7)
37#define CPLD_INT_CPLD (1<<6)
38
39#define CPLD_CONTROL_SWINT (1<<7) /* Disable all CPLD IRQs */
40#define CPLD_CONTROL_OCMSK (1<<6) /* Mask USB1 connect IRQ */
41#define CPLD_CONTROL_PDRV (1<<5) /* PCC_nDRV high */
42#define CPLD_CONTROL_USB1C (1<<4) /* USB1 connect IRQ active */
43#define CPLD_CONTROL_USB1P (1<<3) /* USB1 power disable */
44#define CPLD_CONTROL_AWKP (1<<2) /* Auto-wakeup disabled */
45#define CPLD_CONTROL_LCD_ENABLE (1<<1) /* LCD Vee enable */
46#define CPLD_CONTROL_WRLAN_NENABLE (1<<0) /* SMC91x power disable */
47
48
49static struct resource smc91x_resources[] = {
50 [0] = {
51 .start = CPLD00_PHYS,
52 .end = CPLD00_PHYS + CPLD00_SIZE - 1, /* Only needs 16B */
53 .flags = IORESOURCE_MEM,
54 },
55
56 [1] = {
57 .start = IRQ_LPD7A40X_ETH_INT,
58 .end = IRQ_LPD7A40X_ETH_INT,
59 .flags = IORESOURCE_IRQ,
60 },
61
62};
63
64static struct platform_device smc91x_device = {
65 .name = "smc91x",
66 .id = 0,
67 .num_resources = ARRAY_SIZE(smc91x_resources),
68 .resource = smc91x_resources,
69};
70
71static struct resource lh7a40x_usbclient_resources[] = {
72 [0] = {
73 .start = USB_PHYS,
74 .end = (USB_PHYS + PAGE_SIZE),
75 .flags = IORESOURCE_MEM,
76 },
77 [1] = {
78 .start = IRQ_USB,
79 .end = IRQ_USB,
80 .flags = IORESOURCE_IRQ,
81 },
82};
83
84static u64 lh7a40x_usbclient_dma_mask = 0xffffffffUL;
85
86static struct platform_device lh7a40x_usbclient_device = {
87// .name = "lh7a40x_udc",
88 .name = "lh7-udc",
89 .id = 0,
90 .dev = {
91 .dma_mask = &lh7a40x_usbclient_dma_mask,
92 .coherent_dma_mask = 0xffffffffUL,
93 },
94 .num_resources = ARRAY_SIZE (lh7a40x_usbclient_resources),
95 .resource = lh7a40x_usbclient_resources,
96};
97
98#if defined (CONFIG_ARCH_LH7A404)
99
100static struct resource lh7a404_usbhost_resources [] = {
101 [0] = {
102 .start = USBH_PHYS,
103 .end = (USBH_PHYS + 0xFF),
104 .flags = IORESOURCE_MEM,
105 },
106 [1] = {
107 .start = IRQ_USHINTR,
108 .end = IRQ_USHINTR,
109 .flags = IORESOURCE_IRQ,
110 },
111};
112
113static u64 lh7a404_usbhost_dma_mask = 0xffffffffUL;
114
115static struct platform_device lh7a404_usbhost_device = {
116 .name = "lh7a404-ohci",
117 .id = 0,
118 .dev = {
119 .dma_mask = &lh7a404_usbhost_dma_mask,
120 .coherent_dma_mask = 0xffffffffUL,
121 },
122 .num_resources = ARRAY_SIZE (lh7a404_usbhost_resources),
123 .resource = lh7a404_usbhost_resources,
124};
125
126#endif
127
128static struct platform_device* lpd7a40x_devs[] __initdata = {
129 &smc91x_device,
130 &lh7a40x_usbclient_device,
131#if defined (CONFIG_ARCH_LH7A404)
132 &lh7a404_usbhost_device,
133#endif
134};
135
136extern void lpd7a400_map_io (void);
137
138static void __init lpd7a40x_init (void)
139{
140#if defined (CONFIG_MACH_LPD7A400)
141 CPLD_CONTROL |= 0
142 | CPLD_CONTROL_SWINT /* Disable software interrupt */
143 | CPLD_CONTROL_OCMSK; /* Mask USB1 connection IRQ */
144 CPLD_CONTROL &= ~(0
145 | CPLD_CONTROL_LCD_ENABLE /* Disable LCD */
146 | CPLD_CONTROL_WRLAN_NENABLE /* Enable SMC91x */
147 );
148#endif
149
150#if defined (CONFIG_MACH_LPD7A404)
151 CPLD_CONTROL &= ~(0
152 | CPLD_CONTROL_WRLAN_NENABLE /* Enable SMC91x */
153 );
154#endif
155
156 platform_add_devices (lpd7a40x_devs, ARRAY_SIZE (lpd7a40x_devs));
157#if defined (CONFIG_FB_ARMCLCD)
158 lh7a40x_clcd_init ();
159#endif
160}
161
162static void lh7a40x_ack_cpld_irq(struct irq_data *d)
163{
164 /* CPLD doesn't have ack capability, but some devices may */
165
166#if defined (CPLD_INTMASK_TOUCH)
167 /* The touch control *must* mask the interrupt because the
168 * interrupt bit is read by the driver to determine if the pen
169 * is still down. */
170 if (d->irq == IRQ_TOUCH)
171 CPLD_INTERRUPTS |= CPLD_INTMASK_TOUCH;
172#endif
173}
174
175static void lh7a40x_mask_cpld_irq(struct irq_data *d)
176{
177 switch (d->irq) {
178 case IRQ_LPD7A40X_ETH_INT:
179 CPLD_INTERRUPTS |= CPLD_INTMASK_ETHERNET;
180 break;
181#if defined (IRQ_TOUCH)
182 case IRQ_TOUCH:
183 CPLD_INTERRUPTS |= CPLD_INTMASK_TOUCH;
184 break;
185#endif
186 }
187}
188
189static void lh7a40x_unmask_cpld_irq(struct irq_data *d)
190{
191 switch (d->irq) {
192 case IRQ_LPD7A40X_ETH_INT:
193 CPLD_INTERRUPTS &= ~CPLD_INTMASK_ETHERNET;
194 break;
195#if defined (IRQ_TOUCH)
196 case IRQ_TOUCH:
197 CPLD_INTERRUPTS &= ~CPLD_INTMASK_TOUCH;
198 break;
199#endif
200 }
201}
202
203static struct irq_chip lpd7a40x_cpld_chip = {
204 .name = "CPLD",
205 .irq_ack = lh7a40x_ack_cpld_irq,
206 .irq_mask = lh7a40x_mask_cpld_irq,
207 .irq_unmask = lh7a40x_unmask_cpld_irq,
208};
209
210static void lpd7a40x_cpld_handler (unsigned int irq, struct irq_desc *desc)
211{
212 unsigned int mask = CPLD_INTERRUPTS;
213
214 desc->irq_data.chip->irq_ack(&desc->irq_data);
215
216 if ((mask & (1<<0)) == 0) /* WLAN */
217 generic_handle_irq(IRQ_LPD7A40X_ETH_INT);
218
219#if defined (IRQ_TOUCH)
220 if ((mask & (1<<1)) == 0) /* Touch */
221 generic_handle_irq(IRQ_TOUCH);
222#endif
223
224 /* Level-triggered need this */
225 desc->irq_data.chip->irq_unmask(&desc->irq_data);
226}
227
228
229void __init lh7a40x_init_board_irq (void)
230{
231 int irq;
232
233 /* Rev A (v2.8): PF0, PF1, PF2, and PF3 are available IRQs.
234 PF7 supports the CPLD.
235 Rev B (v3.4): PF0, PF1, and PF2 are available IRQs.
236 PF3 supports the CPLD.
237 (Some) LPD7A404 prerelease boards report a version
238 number of 0x16, but we force an override since the
239 hardware is of the newer variety.
240 */
241
242 unsigned char cpld_version = CPLD_REVISION;
243 int pinCPLD = (cpld_version == 0x28) ? 7 : 3;
244
245#if defined CONFIG_MACH_LPD7A404
246 cpld_version = 0x34; /* Coerce LPD7A404 to RevB */
247#endif
248
249 /* First, configure user controlled GPIOF interrupts */
250
251 GPIO_PFDD &= ~0x0f; /* PF0-3 are inputs */
252 GPIO_INTTYPE1 &= ~0x0f; /* PF0-3 are level triggered */
253 GPIO_INTTYPE2 &= ~0x0f; /* PF0-3 are active low */
254 barrier ();
255 GPIO_GPIOFINTEN |= 0x0f; /* Enable PF0, PF1, PF2, and PF3 IRQs */
256
257 /* Then, configure CPLD interrupt */
258
259 /* Disable all CPLD interrupts */
260#if defined (CONFIG_MACH_LPD7A400)
261 CPLD_INTERRUPTS = CPLD_INTMASK_TOUCH | CPLD_INTMASK_PEN
262 | CPLD_INTMASK_ETHERNET;
263 /* *** FIXME: don't know why we need 7 and 4. 7 is way wrong
264 and 4 is uncefined. */
265 // (1<<7)|(1<<4)|(1<<3)|(1<<2);
266#endif
267#if defined (CONFIG_MACH_LPD7A404)
268 CPLD_INTERRUPTS = CPLD_INTMASK_ETHERNET;
269 /* *** FIXME: don't know why we need 6 and 5, neither is defined. */
270 // (1<<6)|(1<<5)|(1<<3);
271#endif
272 GPIO_PFDD &= ~(1 << pinCPLD); /* Make input */
273 GPIO_INTTYPE1 &= ~(1 << pinCPLD); /* Level triggered */
274 GPIO_INTTYPE2 &= ~(1 << pinCPLD); /* Active low */
275 barrier ();
276 GPIO_GPIOFINTEN |= (1 << pinCPLD); /* Enable */
277
278 /* Cascade CPLD interrupts */
279
280 for (irq = IRQ_BOARD_START;
281 irq < IRQ_BOARD_START + NR_IRQ_BOARD; ++irq) {
282 set_irq_chip (irq, &lpd7a40x_cpld_chip);
283 set_irq_handler (irq, handle_level_irq);
284 set_irq_flags (irq, IRQF_VALID);
285 }
286
287 set_irq_chained_handler ((cpld_version == 0x28)
288 ? IRQ_CPLD_V28
289 : IRQ_CPLD_V34,
290 lpd7a40x_cpld_handler);
291}
292
293static struct map_desc lpd7a40x_io_desc[] __initdata = {
294 {
295 .virtual = IO_VIRT,
296 .pfn = __phys_to_pfn(IO_PHYS),
297 .length = IO_SIZE,
298 .type = MT_DEVICE
299 },
300 { /* Mapping added to work around chip select problems */
301 .virtual = IOBARRIER_VIRT,
302 .pfn = __phys_to_pfn(IOBARRIER_PHYS),
303 .length = IOBARRIER_SIZE,
304 .type = MT_DEVICE
305 },
306 {
307 .virtual = CF_VIRT,
308 .pfn = __phys_to_pfn(CF_PHYS),
309 .length = CF_SIZE,
310 .type = MT_DEVICE
311 },
312 {
313 .virtual = CPLD02_VIRT,
314 .pfn = __phys_to_pfn(CPLD02_PHYS),
315 .length = CPLD02_SIZE,
316 .type = MT_DEVICE
317 },
318 {
319 .virtual = CPLD06_VIRT,
320 .pfn = __phys_to_pfn(CPLD06_PHYS),
321 .length = CPLD06_SIZE,
322 .type = MT_DEVICE
323 },
324 {
325 .virtual = CPLD08_VIRT,
326 .pfn = __phys_to_pfn(CPLD08_PHYS),
327 .length = CPLD08_SIZE,
328 .type = MT_DEVICE
329 },
330 {
331 .virtual = CPLD08_VIRT,
332 .pfn = __phys_to_pfn(CPLD08_PHYS),
333 .length = CPLD08_SIZE,
334 .type = MT_DEVICE
335 },
336 {
337 .virtual = CPLD0A_VIRT,
338 .pfn = __phys_to_pfn(CPLD0A_PHYS),
339 .length = CPLD0A_SIZE,
340 .type = MT_DEVICE
341 },
342 {
343 .virtual = CPLD0C_VIRT,
344 .pfn = __phys_to_pfn(CPLD0C_PHYS),
345 .length = CPLD0C_SIZE,
346 .type = MT_DEVICE
347 },
348 {
349 .virtual = CPLD0E_VIRT,
350 .pfn = __phys_to_pfn(CPLD0E_PHYS),
351 .length = CPLD0E_SIZE,
352 .type = MT_DEVICE
353 },
354 {
355 .virtual = CPLD10_VIRT,
356 .pfn = __phys_to_pfn(CPLD10_PHYS),
357 .length = CPLD10_SIZE,
358 .type = MT_DEVICE
359 },
360 {
361 .virtual = CPLD12_VIRT,
362 .pfn = __phys_to_pfn(CPLD12_PHYS),
363 .length = CPLD12_SIZE,
364 .type = MT_DEVICE
365 },
366 {
367 .virtual = CPLD14_VIRT,
368 .pfn = __phys_to_pfn(CPLD14_PHYS),
369 .length = CPLD14_SIZE,
370 .type = MT_DEVICE
371 },
372 {
373 .virtual = CPLD16_VIRT,
374 .pfn = __phys_to_pfn(CPLD16_PHYS),
375 .length = CPLD16_SIZE,
376 .type = MT_DEVICE
377 },
378 {
379 .virtual = CPLD18_VIRT,
380 .pfn = __phys_to_pfn(CPLD18_PHYS),
381 .length = CPLD18_SIZE,
382 .type = MT_DEVICE
383 },
384 {
385 .virtual = CPLD1A_VIRT,
386 .pfn = __phys_to_pfn(CPLD1A_PHYS),
387 .length = CPLD1A_SIZE,
388 .type = MT_DEVICE
389 },
390};
391
392void __init
393lpd7a40x_map_io(void)
394{
395 iotable_init (lpd7a40x_io_desc, ARRAY_SIZE (lpd7a40x_io_desc));
396}
397
398#ifdef CONFIG_MACH_LPD7A400
399
400MACHINE_START (LPD7A400, "Logic Product Development LPD7A400-10")
401 /* Maintainer: Marc Singer */
402 .boot_params = 0xc0000100,
403 .map_io = lpd7a40x_map_io,
404 .init_irq = lh7a400_init_irq,
405 .timer = &lh7a40x_timer,
406 .init_machine = lpd7a40x_init,
407MACHINE_END
408
409#endif
410
411#ifdef CONFIG_MACH_LPD7A404
412
413MACHINE_START (LPD7A404, "Logic Product Development LPD7A404-10")
414 /* Maintainer: Marc Singer */
415 .boot_params = 0xc0000100,
416 .map_io = lpd7a40x_map_io,
417 .init_irq = lh7a404_init_irq,
418 .timer = &lh7a40x_timer,
419 .init_machine = lpd7a40x_init,
420MACHINE_END
421
422#endif
diff --git a/arch/arm/mach-lh7a40x/clcd.c b/arch/arm/mach-lh7a40x/clcd.c
deleted file mode 100644
index 7fe4fd347c82..000000000000
--- a/arch/arm/mach-lh7a40x/clcd.c
+++ /dev/null
@@ -1,241 +0,0 @@
1/*
2 * arch/arm/mach-lh7a40x/clcd.c
3 *
4 * Copyright (C) 2004 Marc Singer
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
9 *
10 */
11
12#include <linux/init.h>
13#include <linux/gfp.h>
14#include <linux/device.h>
15#include <linux/dma-mapping.h>
16#include <linux/sysdev.h>
17#include <linux/interrupt.h>
18
19//#include <linux/module.h>
20//#include <linux/time.h>
21
22//#include <asm/mach/time.h>
23#include <asm/irq.h>
24#include <asm/mach/irq.h>
25
26#include <asm/system.h>
27#include <mach/hardware.h>
28#include <linux/amba/bus.h>
29#include <linux/amba/clcd.h>
30
31#define HRTFTC_HRSETUP __REG(HRTFTC_PHYS + 0x00)
32#define HRTFTC_HRCON __REG(HRTFTC_PHYS + 0x04)
33#define HRTFTC_HRTIMING1 __REG(HRTFTC_PHYS + 0x08)
34#define HRTFTC_HRTIMING2 __REG(HRTFTC_PHYS + 0x0c)
35
36#define ALI_SETUP __REG(ALI_PHYS + 0x00)
37#define ALI_CONTROL __REG(ALI_PHYS + 0x04)
38#define ALI_TIMING1 __REG(ALI_PHYS + 0x08)
39#define ALI_TIMING2 __REG(ALI_PHYS + 0x0c)
40
41#include "lcd-panel.h"
42
43static void lh7a40x_clcd_disable (struct clcd_fb *fb)
44{
45#if defined (CONFIG_MACH_LPD7A400)
46 CPLD_CONTROL &= ~(1<<1); /* Disable LCD Vee */
47#endif
48
49#if defined (CONFIG_MACH_LPD7A404)
50 GPIO_PCD &= ~(1<<3); /* Disable LCD Vee */
51#endif
52
53#if defined (CONFIG_ARCH_LH7A400)
54 HRTFTC_HRSETUP &= ~(1<<13); /* Disable HRTFT controller */
55#endif
56
57#if defined (CONFIG_ARCH_LH7A404)
58 ALI_SETUP &= ~(1<<13); /* Disable ALI */
59#endif
60}
61
62static void lh7a40x_clcd_enable (struct clcd_fb *fb)
63{
64 struct clcd_panel_extra* extra
65 = (struct clcd_panel_extra*) fb->board_data;
66
67#if defined (CONFIG_MACH_LPD7A400)
68 CPLD_CONTROL |= (1<<1); /* Enable LCD Vee */
69#endif
70
71#if defined (CONFIG_MACH_LPD7A404)
72 GPIO_PCDD &= ~(1<<3); /* Enable LCD Vee */
73 GPIO_PCD |= (1<<3);
74#endif
75
76#if defined (CONFIG_ARCH_LH7A400)
77
78 if (extra) {
79 HRTFTC_HRSETUP
80 = (1 << 13)
81 | ((fb->fb.var.xres - 1) << 4)
82 | 0xc
83 | (extra->hrmode ? 1 : 0);
84 HRTFTC_HRCON
85 = ((extra->clsen ? 1 : 0) << 1)
86 | ((extra->spsen ? 1 : 0) << 0);
87 HRTFTC_HRTIMING1
88 = (extra->pcdel << 8)
89 | (extra->revdel << 4)
90 | (extra->lpdel << 0);
91 HRTFTC_HRTIMING2
92 = (extra->spldel << 9)
93 | (extra->pc2del << 0);
94 }
95 else
96 HRTFTC_HRSETUP
97 = (1 << 13)
98 | 0xc;
99#endif
100
101#if defined (CONFIG_ARCH_LH7A404)
102
103 if (extra) {
104 ALI_SETUP
105 = (1 << 13)
106 | ((fb->fb.var.xres - 1) << 4)
107 | 0xc
108 | (extra->hrmode ? 1 : 0);
109 ALI_CONTROL
110 = ((extra->clsen ? 1 : 0) << 1)
111 | ((extra->spsen ? 1 : 0) << 0);
112 ALI_TIMING1
113 = (extra->pcdel << 8)
114 | (extra->revdel << 4)
115 | (extra->lpdel << 0);
116 ALI_TIMING2
117 = (extra->spldel << 9)
118 | (extra->pc2del << 0);
119 }
120 else
121 ALI_SETUP
122 = (1 << 13)
123 | 0xc;
124#endif
125
126}
127
128#define FRAMESIZE(s) (((s) + PAGE_SIZE - 1)&PAGE_MASK)
129
130static int lh7a40x_clcd_setup (struct clcd_fb *fb)
131{
132 dma_addr_t dma;
133 u32 len = FRAMESIZE (lcd_panel.mode.xres*lcd_panel.mode.yres
134 *(lcd_panel.bpp/8));
135
136 fb->panel = &lcd_panel;
137
138 /* Enforce the sync polarity defaults */
139 if (!(fb->panel->tim2 & TIM2_IHS))
140 fb->fb.var.sync |= FB_SYNC_HOR_HIGH_ACT;
141 if (!(fb->panel->tim2 & TIM2_IVS))
142 fb->fb.var.sync |= FB_SYNC_VERT_HIGH_ACT;
143
144#if defined (HAS_LCD_PANEL_EXTRA)
145 fb->board_data = &lcd_panel_extra;
146#endif
147
148 fb->fb.screen_base
149 = dma_alloc_writecombine (&fb->dev->dev, len,
150 &dma, GFP_KERNEL);
151 printk ("CLCD: LCD setup fb virt 0x%p phys 0x%p l %x io 0x%p \n",
152 fb->fb.screen_base, (void*) dma, len,
153 (void*) io_p2v (CLCDC_PHYS));
154 printk ("CLCD: pixclock %d\n", lcd_panel.mode.pixclock);
155
156 if (!fb->fb.screen_base) {
157 printk(KERN_ERR "CLCD: unable to map framebuffer\n");
158 return -ENOMEM;
159 }
160
161#if defined (USE_RGB555)
162 fb->fb.var.green.length = 5; /* Panel uses RGB 5:5:5 */
163#endif
164
165 fb->fb.fix.smem_start = dma;
166 fb->fb.fix.smem_len = len;
167
168 /* Drive PE4 high to prevent CPLD crash */
169 GPIO_PEDD |= (1<<4);
170 GPIO_PED |= (1<<4);
171
172 GPIO_PINMUX |= (1<<1) | (1<<0); /* LCDVD[15:4] */
173
174// fb->fb.fbops->fb_check_var (&fb->fb.var, &fb->fb);
175// fb->fb.fbops->fb_set_par (&fb->fb);
176
177 return 0;
178}
179
180static int lh7a40x_clcd_mmap (struct clcd_fb *fb, struct vm_area_struct *vma)
181{
182 return dma_mmap_writecombine(&fb->dev->dev, vma,
183 fb->fb.screen_base,
184 fb->fb.fix.smem_start,
185 fb->fb.fix.smem_len);
186}
187
188static void lh7a40x_clcd_remove (struct clcd_fb *fb)
189{
190 dma_free_writecombine (&fb->dev->dev, fb->fb.fix.smem_len,
191 fb->fb.screen_base, fb->fb.fix.smem_start);
192}
193
194static struct clcd_board clcd_platform_data = {
195 .name = "lh7a40x FB",
196 .check = clcdfb_check,
197 .decode = clcdfb_decode,
198 .enable = lh7a40x_clcd_enable,
199 .setup = lh7a40x_clcd_setup,
200 .mmap = lh7a40x_clcd_mmap,
201 .remove = lh7a40x_clcd_remove,
202 .disable = lh7a40x_clcd_disable,
203};
204
205#define IRQ_CLCDC (IRQ_LCDINTR)
206
207#define AMBA_DEVICE(name,busid,base,plat,pid) \
208static struct amba_device name##_device = { \
209 .dev = { \
210 .coherent_dma_mask = ~0, \
211 .init_name = busid, \
212 .platform_data = plat, \
213 }, \
214 .res = { \
215 .start = base##_PHYS, \
216 .end = (base##_PHYS) + (4*1024) - 1, \
217 .flags = IORESOURCE_MEM, \
218 }, \
219 .dma_mask = ~0, \
220 .irq = { IRQ_##base, }, \
221 /* .dma = base##_DMA,*/ \
222 .periphid = pid, \
223}
224
225AMBA_DEVICE(clcd, "cldc-lh7a40x", CLCDC, &clcd_platform_data, 0x41110);
226
227static struct amba_device *amba_devs[] __initdata = {
228 &clcd_device,
229};
230
231void __init lh7a40x_clcd_init (void)
232{
233 int i;
234 int result;
235 printk ("CLCD: registering amba devices\n");
236 for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
237 struct amba_device *d = amba_devs[i];
238 result = amba_device_register(d, &iomem_resource);
239 printk (" %d -> %d\n", i ,result);
240 }
241}
diff --git a/arch/arm/mach-lh7a40x/clocks.c b/arch/arm/mach-lh7a40x/clocks.c
deleted file mode 100644
index 0651f96653f9..000000000000
--- a/arch/arm/mach-lh7a40x/clocks.c
+++ /dev/null
@@ -1,108 +0,0 @@
1/* arch/arm/mach-lh7a40x/clocks.c
2 *
3 * Copyright (C) 2004 Marc Singer
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * version 2 as published by the Free Software Foundation.
8 *
9 */
10#include <mach/hardware.h>
11#include <mach/clocks.h>
12#include <linux/err.h>
13#include <linux/device.h>
14#include <linux/string.h>
15
16struct module;
17
18struct clk {
19 struct list_head node;
20 unsigned long rate;
21 struct module *owner;
22 const char *name;
23};
24
25/* ----- */
26
27#define MAINDIV1(c) (((c) >> 7) & 0x0f)
28#define MAINDIV2(c) (((c) >> 11) & 0x1f)
29#define PS(c) (((c) >> 18) & 0x03)
30#define PREDIV(c) (((c) >> 2) & 0x1f)
31#define HCLKDIV(c) (((c) >> 0) & 0x02)
32#define PCLKDIV(c) (((c) >> 16) & 0x03)
33
34unsigned int fclkfreq_get (void)
35{
36 unsigned int clkset = CSC_CLKSET;
37 unsigned int gclk
38 = XTAL_IN
39 / (1 << PS(clkset))
40 * (MAINDIV1(clkset) + 2)
41 / (PREDIV(clkset) + 2)
42 * (MAINDIV2(clkset) + 2)
43 ;
44 return gclk;
45}
46
47unsigned int hclkfreq_get (void)
48{
49 unsigned int clkset = CSC_CLKSET;
50 unsigned int hclk = fclkfreq_get () / (HCLKDIV(clkset) + 1);
51
52 return hclk;
53}
54
55unsigned int pclkfreq_get (void)
56{
57 unsigned int clkset = CSC_CLKSET;
58 int pclkdiv = PCLKDIV(clkset);
59 unsigned int pclk;
60 if (pclkdiv == 0x3)
61 pclkdiv = 0x2;
62 pclk = hclkfreq_get () / (1 << pclkdiv);
63
64 return pclk;
65}
66
67/* ----- */
68
69struct clk *clk_get (struct device *dev, const char *id)
70{
71 return dev && strcmp(dev_name(dev), "cldc-lh7a40x") == 0
72 ? NULL : ERR_PTR(-ENOENT);
73}
74EXPORT_SYMBOL(clk_get);
75
76void clk_put (struct clk *clk)
77{
78}
79EXPORT_SYMBOL(clk_put);
80
81int clk_enable (struct clk *clk)
82{
83 return 0;
84}
85EXPORT_SYMBOL(clk_enable);
86
87void clk_disable (struct clk *clk)
88{
89}
90EXPORT_SYMBOL(clk_disable);
91
92unsigned long clk_get_rate (struct clk *clk)
93{
94 return 0;
95}
96EXPORT_SYMBOL(clk_get_rate);
97
98long clk_round_rate (struct clk *clk, unsigned long rate)
99{
100 return rate;
101}
102EXPORT_SYMBOL(clk_round_rate);
103
104int clk_set_rate (struct clk *clk, unsigned long rate)
105{
106 return -EIO;
107}
108EXPORT_SYMBOL(clk_set_rate);
diff --git a/arch/arm/mach-lh7a40x/common.h b/arch/arm/mach-lh7a40x/common.h
deleted file mode 100644
index 6ed3f6b6db76..000000000000
--- a/arch/arm/mach-lh7a40x/common.h
+++ /dev/null
@@ -1,17 +0,0 @@
1/* arch/arm/mach-lh7a40x/common.h
2 *
3 * Copyright (C) 2004 Marc Singer
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * version 2 as published by the Free Software Foundation.
8 *
9 */
10
11extern struct sys_timer lh7a40x_timer;
12
13extern void lh7a400_init_irq (void);
14extern void lh7a404_init_irq (void);
15extern void lh7a40x_clcd_init (void);
16extern void lh7a40x_init_board_irq (void);
17
diff --git a/arch/arm/mach-lh7a40x/include/mach/clocks.h b/arch/arm/mach-lh7a40x/include/mach/clocks.h
deleted file mode 100644
index fe2e0255c084..000000000000
--- a/arch/arm/mach-lh7a40x/include/mach/clocks.h
+++ /dev/null
@@ -1,18 +0,0 @@
1/* arch/arm/mach-lh7a40x/include/mach/clocks.h
2 *
3 * Copyright (C) 2004 Marc Singer
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * version 2 as published by the Free Software Foundation.
8 *
9 */
10
11#ifndef __ASM_ARCH_CLOCKS_H
12#define __ASM_ARCH_CLOCKS_H
13
14unsigned int fclkfreq_get (void);
15unsigned int hclkfreq_get (void);
16unsigned int pclkfreq_get (void);
17
18#endif /* _ASM_ARCH_CLOCKS_H */
diff --git a/arch/arm/mach-lh7a40x/include/mach/constants.h b/arch/arm/mach-lh7a40x/include/mach/constants.h
deleted file mode 100644
index 55c6edbc2dfd..000000000000
--- a/arch/arm/mach-lh7a40x/include/mach/constants.h
+++ /dev/null
@@ -1,91 +0,0 @@
1/* arch/arm/mach-lh7a40x/include/mach/constants.h
2 *
3 * Copyright (C) 2004 Coastal Environmental Systems
4 * Copyright (C) 2004 Logic Product Development
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
9 *
10 */
11
12#ifndef __ASM_ARCH_CONSTANTS_H
13#define __ASM_ARCH_CONSTANTS_H
14
15
16/* Addressing constants */
17
18 /* SoC CPU IO addressing */
19#define IO_PHYS (0x80000000)
20#define IO_VIRT (0xf8000000)
21#define IO_SIZE (0x0000B000)
22
23#ifdef CONFIG_MACH_KEV7A400
24# define CPLD_PHYS (0x20000000)
25# define CPLD_VIRT (0xf2000000)
26# define CPLD_SIZE PAGE_SIZE
27#endif
28
29#if defined (CONFIG_MACH_LPD7A400) || defined (CONFIG_MACH_LPD7A404)
30
31# define IOBARRIER_PHYS 0x10000000 /* Second bank, fastest timing */
32# define IOBARRIER_VIRT 0xf0000000
33# define IOBARRIER_SIZE PAGE_SIZE
34
35# define CF_PHYS 0x60200000
36# define CF_VIRT 0xf6020000
37# define CF_SIZE (8*1024)
38
39 /* The IO mappings for the LPD CPLD are, unfortunately, sparse. */
40# define CPLDX_PHYS(x) (0x70000000 | ((x) << 20))
41# define CPLDX_VIRT(x) (0xf7000000 | ((x) << 16))
42# define CPLD00_PHYS CPLDX_PHYS (0x00) /* Wired LAN */
43# define CPLD00_VIRT CPLDX_VIRT (0x00)
44# define CPLD00_SIZE PAGE_SIZE
45# define CPLD02_PHYS CPLDX_PHYS (0x02)
46# define CPLD02_VIRT CPLDX_VIRT (0x02)
47# define CPLD02_SIZE PAGE_SIZE
48# define CPLD06_PHYS CPLDX_PHYS (0x06)
49# define CPLD06_VIRT CPLDX_VIRT (0x06)
50# define CPLD06_SIZE PAGE_SIZE
51# define CPLD08_PHYS CPLDX_PHYS (0x08)
52# define CPLD08_VIRT CPLDX_VIRT (0x08)
53# define CPLD08_SIZE PAGE_SIZE
54# define CPLD0A_PHYS CPLDX_PHYS (0x0a)
55# define CPLD0A_VIRT CPLDX_VIRT (0x0a)
56# define CPLD0A_SIZE PAGE_SIZE
57# define CPLD0C_PHYS CPLDX_PHYS (0x0c)
58# define CPLD0C_VIRT CPLDX_VIRT (0x0c)
59# define CPLD0C_SIZE PAGE_SIZE
60# define CPLD0E_PHYS CPLDX_PHYS (0x0e)
61# define CPLD0E_VIRT CPLDX_VIRT (0x0e)
62# define CPLD0E_SIZE PAGE_SIZE
63# define CPLD10_PHYS CPLDX_PHYS (0x10)
64# define CPLD10_VIRT CPLDX_VIRT (0x10)
65# define CPLD10_SIZE PAGE_SIZE
66# define CPLD12_PHYS CPLDX_PHYS (0x12)
67# define CPLD12_VIRT CPLDX_VIRT (0x12)
68# define CPLD12_SIZE PAGE_SIZE
69# define CPLD14_PHYS CPLDX_PHYS (0x14)
70# define CPLD14_VIRT CPLDX_VIRT (0x14)
71# define CPLD14_SIZE PAGE_SIZE
72# define CPLD16_PHYS CPLDX_PHYS (0x16)
73# define CPLD16_VIRT CPLDX_VIRT (0x16)
74# define CPLD16_SIZE PAGE_SIZE
75# define CPLD18_PHYS CPLDX_PHYS (0x18)
76# define CPLD18_VIRT CPLDX_VIRT (0x18)
77# define CPLD18_SIZE PAGE_SIZE
78# define CPLD1A_PHYS CPLDX_PHYS (0x1a)
79# define CPLD1A_VIRT CPLDX_VIRT (0x1a)
80# define CPLD1A_SIZE PAGE_SIZE
81#endif
82
83 /* Timing constants */
84
85#define XTAL_IN 14745600 /* 14.7456 MHz crystal */
86#define PLL_CLOCK (XTAL_IN * 21) /* 309 MHz PLL clock */
87#define MAX_HCLK_KHZ 100000 /* HCLK max limit ~100MHz */
88#define HCLK (99993600)
89//#define HCLK (119808000)
90
91#endif /* __ASM_ARCH_CONSTANTS_H */
diff --git a/arch/arm/mach-lh7a40x/include/mach/debug-macro.S b/arch/arm/mach-lh7a40x/include/mach/debug-macro.S
deleted file mode 100644
index cff33625276f..000000000000
--- a/arch/arm/mach-lh7a40x/include/mach/debug-macro.S
+++ /dev/null
@@ -1,37 +0,0 @@
1/* arch/arm/mach-lh7a40x/include/mach/debug-macro.S
2 *
3 * Debugging macro include header
4 *
5 * Copyright (C) 1994-1999 Russell King
6 * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12*/
13
14 @ It is not known if this will be appropriate for every 40x
15 @ board.
16
17 .macro addruart, rp, rv
18 mov \rp, #0x00000700 @ offset from base
19 orr \rv, \rp, #0xf8000000 @ virtual base
20 orr \rp, \rp, #0x80000000 @ physical base
21 .endm
22
23 .macro senduart,rd,rx
24 strb \rd, [\rx] @ DATA
25 .endm
26
27 .macro busyuart,rd,rx @ spin while busy
281001: ldr \rd, [\rx, #0x10] @ STATUS
29 tst \rd, #1 << 3 @ BUSY (TX FIFO not empty)
30 bne 1001b @ yes, spin
31 .endm
32
33 .macro waituart,rd,rx @ wait for Tx FIFO room
341001: ldrb \rd, [\rx, #0x10] @ STATUS
35 tst \rd, #1 << 5 @ TXFF (TX FIFO full)
36 bne 1001b @ yes, spin
37 .endm
diff --git a/arch/arm/mach-lh7a40x/include/mach/dma.h b/arch/arm/mach-lh7a40x/include/mach/dma.h
deleted file mode 100644
index baa3f8dbd04b..000000000000
--- a/arch/arm/mach-lh7a40x/include/mach/dma.h
+++ /dev/null
@@ -1,86 +0,0 @@
1/* arch/arm/mach-lh7a40x/include/mach/dma.h
2 *
3 * Copyright (C) 2005 Marc Singer
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * version 2 as published by the Free Software Foundation.
8 *
9 */
10
11typedef enum {
12 DMA_M2M0 = 0,
13 DMA_M2M1 = 1,
14 DMA_M2P0 = 2, /* Tx */
15 DMA_M2P1 = 3, /* Rx */
16 DMA_M2P2 = 4, /* Tx */
17 DMA_M2P3 = 5, /* Rx */
18 DMA_M2P4 = 6, /* Tx - AC97 */
19 DMA_M2P5 = 7, /* Rx - AC97 */
20 DMA_M2P6 = 8, /* Tx */
21 DMA_M2P7 = 9, /* Rx */
22} dma_device_t;
23
24#define DMA_LENGTH_MAX ((64*1024) - 4) /* bytes */
25
26#define DMAC_GCA __REG(DMAC_PHYS + 0x2b80)
27#define DMAC_GIR __REG(DMAC_PHYS + 0x2bc0)
28
29#define DMAC_GIR_MMI1 (1<<11)
30#define DMAC_GIR_MMI0 (1<<10)
31#define DMAC_GIR_MPI8 (1<<9)
32#define DMAC_GIR_MPI9 (1<<8)
33#define DMAC_GIR_MPI6 (1<<7)
34#define DMAC_GIR_MPI7 (1<<6)
35#define DMAC_GIR_MPI4 (1<<5)
36#define DMAC_GIR_MPI5 (1<<4)
37#define DMAC_GIR_MPI2 (1<<3)
38#define DMAC_GIR_MPI3 (1<<2)
39#define DMAC_GIR_MPI0 (1<<1)
40#define DMAC_GIR_MPI1 (1<<0)
41
42#define DMAC_M2P0 0x0000
43#define DMAC_M2P1 0x0040
44#define DMAC_M2P2 0x0080
45#define DMAC_M2P3 0x00c0
46#define DMAC_M2P4 0x0240
47#define DMAC_M2P5 0x0200
48#define DMAC_M2P6 0x02c0
49#define DMAC_M2P7 0x0280
50#define DMAC_M2P8 0x0340
51#define DMAC_M2P9 0x0300
52#define DMAC_M2M0 0x0100
53#define DMAC_M2M1 0x0140
54
55#define DMAC_P_PCONTROL(c) __REG(DMAC_PHYS + (c) + 0x00)
56#define DMAC_P_PINTERRUPT(c) __REG(DMAC_PHYS + (c) + 0x04)
57#define DMAC_P_PPALLOC(c) __REG(DMAC_PHYS + (c) + 0x08)
58#define DMAC_P_PSTATUS(c) __REG(DMAC_PHYS + (c) + 0x0c)
59#define DMAC_P_REMAIN(c) __REG(DMAC_PHYS + (c) + 0x14)
60#define DMAC_P_MAXCNT0(c) __REG(DMAC_PHYS + (c) + 0x20)
61#define DMAC_P_BASE0(c) __REG(DMAC_PHYS + (c) + 0x24)
62#define DMAC_P_CURRENT0(c) __REG(DMAC_PHYS + (c) + 0x28)
63#define DMAC_P_MAXCNT1(c) __REG(DMAC_PHYS + (c) + 0x30)
64#define DMAC_P_BASE1(c) __REG(DMAC_PHYS + (c) + 0x34)
65#define DMAC_P_CURRENT1(c) __REG(DMAC_PHYS + (c) + 0x38)
66
67#define DMAC_PCONTROL_ENABLE (1<<4)
68
69#define DMAC_PORT_USB 0
70#define DMAC_PORT_SDMMC 1
71#define DMAC_PORT_AC97_1 2
72#define DMAC_PORT_AC97_2 3
73#define DMAC_PORT_AC97_3 4
74#define DMAC_PORT_UART1 6
75#define DMAC_PORT_UART2 7
76#define DMAC_PORT_UART3 8
77
78#define DMAC_PSTATUS_CURRSTATE_SHIFT 4
79#define DMAC_PSTATUS_CURRSTATE_MASK 0x3
80
81#define DMAC_PSTATUS_NEXTBUF (1<<6)
82#define DMAC_PSTATUS_STALLRINT (1<<0)
83
84#define DMAC_INT_CHE (1<<3)
85#define DMAC_INT_NFB (1<<1)
86#define DMAC_INT_STALL (1<<0)
diff --git a/arch/arm/mach-lh7a40x/include/mach/entry-macro.S b/arch/arm/mach-lh7a40x/include/mach/entry-macro.S
deleted file mode 100644
index 069bb4cefff7..000000000000
--- a/arch/arm/mach-lh7a40x/include/mach/entry-macro.S
+++ /dev/null
@@ -1,149 +0,0 @@
1/*
2 * arch/arm/mach-lh7a40x/include/mach/entry-macro.S
3 *
4 * Low-level IRQ helper macros for LH7A40x platforms
5 *
6 * This file is licensed under the terms of the GNU General Public
7 * License version 2. This program is licensed "as is" without any
8 * warranty of any kind, whether express or implied.
9 */
10#include <mach/hardware.h>
11#include <mach/irqs.h>
12
13/* In order to allow there to be support for both of the processor
14 classes at the same time, we make a hack here that isn't very
15 pretty. At startup, the link pointed to with the
16 branch_irq_lh7a400 symbol is replaced with a NOP when the CPU is
17 detected as a lh7a404.
18
19 *** FIXME: we should clean this up so that there is only one
20 implementation for each CPU's design.
21
22*/
23
24#if defined (CONFIG_ARCH_LH7A400) && defined (CONFIG_ARCH_LH7A404)
25
26 .macro disable_fiq
27 .endm
28
29 .macro get_irqnr_preamble, base, tmp
30 .endm
31
32 .macro arch_ret_to_user, tmp1, tmp2
33 .endm
34
35 .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
36
37branch_irq_lh7a400: b 1000f
38
39@ Implementation of the LH7A404 get_irqnr_and_base.
40
41 mov \irqnr, #0 @ VIC1 irq base
42 mov \base, #io_p2v(0x80000000) @ APB registers
43 add \base, \base, #0x8000
44 ldr \tmp, [\base, #0x0030] @ VIC1_VECTADDR
45 tst \tmp, #VA_VECTORED @ Direct vectored
46 bne 1002f
47 tst \tmp, #VA_VIC1DEFAULT @ Default vectored VIC1
48 ldrne \irqstat, [\base, #0] @ VIC1_IRQSTATUS
49 bne 1001f
50 add \base, \base, #(0xa000 - 0x8000)
51 ldr \tmp, [\base, #0x0030] @ VIC2_VECTADDR
52 tst \tmp, #VA_VECTORED @ Direct vectored
53 bne 1002f
54 ldr \irqstat, [\base, #0] @ VIC2_IRQSTATUS
55 mov \irqnr, #32 @ VIC2 irq base
56
571001: movs \irqstat, \irqstat, lsr #1 @ Shift into carry
58 bcs 1008f @ Bit set; irq found
59 add \irqnr, \irqnr, #1
60 bne 1001b @ Until no bits
61 b 1009f @ Nothing? Hmm.
621002: and \irqnr, \tmp, #0x3f @ Mask for valid bits
631008: movs \irqstat, #1 @ Force !Z
64 str \tmp, [\base, #0x0030] @ Clear vector
65 b 1009f
66
67@ Implementation of the LH7A400 get_irqnr_and_base.
68
691000: mov \irqnr, #0
70 mov \base, #io_p2v(0x80000000) @ APB registers
71 ldr \irqstat, [\base, #0x500] @ PIC INTSR
72
731001: movs \irqstat, \irqstat, lsr #1 @ Shift into carry
74 bcs 1008f @ Bit set; irq found
75 add \irqnr, \irqnr, #1
76 bne 1001b @ Until no bits
77 b 1009f @ Nothing? Hmm.
781008: movs \irqstat, #1 @ Force !Z
79
801009:
81 .endm
82
83
84
85#elif defined (CONFIG_ARCH_LH7A400)
86 .macro disable_fiq
87 .endm
88
89 .macro get_irqnr_preamble, base, tmp
90 .endm
91
92 .macro arch_ret_to_user, tmp1, tmp2
93 .endm
94
95 .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
96 mov \irqnr, #0
97 mov \base, #io_p2v(0x80000000) @ APB registers
98 ldr \irqstat, [\base, #0x500] @ PIC INTSR
99
1001001: movs \irqstat, \irqstat, lsr #1 @ Shift into carry
101 bcs 1008f @ Bit set; irq found
102 add \irqnr, \irqnr, #1
103 bne 1001b @ Until no bits
104 b 1009f @ Nothing? Hmm.
1051008: movs \irqstat, #1 @ Force !Z
1061009:
107 .endm
108
109#elif defined(CONFIG_ARCH_LH7A404)
110
111 .macro disable_fiq
112 .endm
113
114 .macro get_irqnr_preamble, base, tmp
115 .endm
116
117 .macro arch_ret_to_user, tmp1, tmp2
118 .endm
119
120 .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
121 mov \irqnr, #0 @ VIC1 irq base
122 mov \base, #io_p2v(0x80000000) @ APB registers
123 add \base, \base, #0x8000
124 ldr \tmp, [\base, #0x0030] @ VIC1_VECTADDR
125 tst \tmp, #VA_VECTORED @ Direct vectored
126 bne 1002f
127 tst \tmp, #VA_VIC1DEFAULT @ Default vectored VIC1
128 ldrne \irqstat, [\base, #0] @ VIC1_IRQSTATUS
129 bne 1001f
130 add \base, \base, #(0xa000 - 0x8000)
131 ldr \tmp, [\base, #0x0030] @ VIC2_VECTADDR
132 tst \tmp, #VA_VECTORED @ Direct vectored
133 bne 1002f
134 ldr \irqstat, [\base, #0] @ VIC2_IRQSTATUS
135 mov \irqnr, #32 @ VIC2 irq base
136
1371001: movs \irqstat, \irqstat, lsr #1 @ Shift into carry
138 bcs 1008f @ Bit set; irq found
139 add \irqnr, \irqnr, #1
140 bne 1001b @ Until no bits
141 b 1009f @ Nothing? Hmm.
1421002: and \irqnr, \tmp, #0x3f @ Mask for valid bits
1431008: movs \irqstat, #1 @ Force !Z
144 str \tmp, [\base, #0x0030] @ Clear vector
1451009:
146 .endm
147#endif
148
149
diff --git a/arch/arm/mach-lh7a40x/include/mach/hardware.h b/arch/arm/mach-lh7a40x/include/mach/hardware.h
deleted file mode 100644
index 59d2ace35217..000000000000
--- a/arch/arm/mach-lh7a40x/include/mach/hardware.h
+++ /dev/null
@@ -1,62 +0,0 @@
1/* arch/arm/mach-lh7a40x/include/mach/hardware.h
2 *
3 * Copyright (C) 2004 Coastal Environmental Systems
4 *
5 * [ Substantially cribbed from arch/arm/mach-pxa/include/mach/hardware.h ]
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * version 2 as published by the Free Software Foundation.
10 *
11 */
12
13#ifndef __ASM_ARCH_HARDWARE_H
14#define __ASM_ARCH_HARDWARE_H
15
16#include <asm/sizes.h> /* Added for the sake of amba-clcd driver */
17
18#define io_p2v(x) (0xf0000000 | (((x) & 0xfff00000) >> 4) | ((x) & 0x0000ffff))
19#define io_v2p(x) ( (((x) & 0x0fff0000) << 4) | ((x) & 0x0000ffff))
20
21#ifdef __ASSEMBLY__
22
23# define __REG(x) io_p2v(x)
24# define __PREG(x) io_v2p(x)
25
26#else
27
28# if 0
29# define __REG(x) (*((volatile u32 *)io_p2v(x)))
30# else
31/*
32 * This __REG() version gives the same results as the one above, except
33 * that we are fooling gcc somehow so it generates far better and smaller
34 * assembly code for access to contiguous registers. It's a shame that gcc
35 * doesn't guess this by itself.
36 */
37#include <asm/types.h>
38typedef struct { volatile u32 offset[4096]; } __regbase;
39# define __REGP(x) ((__regbase *)((x)&~4095))->offset[((x)&4095)>>2]
40# define __REG(x) __REGP(io_p2v(x))
41typedef struct { volatile u16 offset[4096]; } __regbase16;
42# define __REGP16(x) ((__regbase16 *)((x)&~4095))->offset[((x)&4095)>>1]
43# define __REG16(x) __REGP16(io_p2v(x))
44typedef struct { volatile u8 offset[4096]; } __regbase8;
45# define __REGP8(x) ((__regbase8 *)((x)&~4095))->offset[(x)&4095]
46# define __REG8(x) __REGP8(io_p2v(x))
47#endif
48
49/* Let's kick gcc's ass again... */
50# define __REG2(x,y) \
51 ( __builtin_constant_p(y) ? (__REG((x) + (y))) \
52 : (*(volatile u32 *)((u32)&__REG(x) + (y))) )
53
54# define __PREG(x) (io_v2p((u32)&(x)))
55
56#endif
57
58#define MASK_AND_SET(v,m,s) (v) = ((v)&~(m))|(s)
59
60#include "registers.h"
61
62#endif /* _ASM_ARCH_HARDWARE_H */
diff --git a/arch/arm/mach-lh7a40x/include/mach/io.h b/arch/arm/mach-lh7a40x/include/mach/io.h
deleted file mode 100644
index 6ece45911cbc..000000000000
--- a/arch/arm/mach-lh7a40x/include/mach/io.h
+++ /dev/null
@@ -1,20 +0,0 @@
1/* arch/arm/mach-lh7a40x/include/mach/io.h
2 *
3 * Copyright (C) 2004 Coastal Environmental Systems
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * version 2 as published by the Free Software Foundation.
8 *
9 */
10
11#ifndef __ASM_ARCH_IO_H
12#define __ASM_ARCH_IO_H
13
14#define IO_SPACE_LIMIT 0xffffffff
15
16/* No ISA or PCI bus on this machine. */
17#define __io(a) __typesafe_io(a)
18#define __mem_pci(a) (a)
19
20#endif /* __ASM_ARCH_IO_H */
diff --git a/arch/arm/mach-lh7a40x/include/mach/irqs.h b/arch/arm/mach-lh7a40x/include/mach/irqs.h
deleted file mode 100644
index 0f9b83675935..000000000000
--- a/arch/arm/mach-lh7a40x/include/mach/irqs.h
+++ /dev/null
@@ -1,200 +0,0 @@
1/* arch/arm/mach-lh7a40x/include/mach/irqs.h
2 *
3 * Copyright (C) 2004 Coastal Environmental Systems
4 * Copyright (C) 2004 Logic Product Development
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
9 *
10 */
11
12/* It is to be seen whether or not we can build a kernel for more than
13 * one board. For the time being, these macros assume that we cannot.
14 * Thus, it is OK to ifdef machine/board specific IRQ assignments.
15 */
16
17
18#ifndef __ASM_ARCH_IRQS_H
19#define __ASM_ARCH_IRQS_H
20
21
22#define FIQ_START 80
23
24#if defined (CONFIG_ARCH_LH7A400)
25
26 /* FIQs */
27
28# define IRQ_GPIO0FIQ 0 /* GPIO External FIQ Interrupt on F0 */
29# define IRQ_BLINT 1 /* Battery Low */
30# define IRQ_WEINT 2 /* Watchdog Timer, WDT overflow */
31# define IRQ_MCINT 3 /* Media Change, MEDCHG pin rising */
32
33 /* IRQs */
34
35# define IRQ_CSINT 4 /* Audio Codec (ACI) */
36# define IRQ_GPIO1INTR 5 /* GPIO External IRQ Interrupt on F1 */
37# define IRQ_GPIO2INTR 6 /* GPIO External IRQ Interrupt on F2 */
38# define IRQ_GPIO3INTR 7 /* GPIO External IRQ Interrupt on F3 */
39# define IRQ_T1UI 8 /* Timer 1 underflow */
40# define IRQ_T2UI 9 /* Timer 2 underflow */
41# define IRQ_RTCMI 10
42# define IRQ_TINTR 11 /* Clock State Controller 64 Hz tick (CSC) */
43# define IRQ_UART1INTR 12
44# define IRQ_UART2INTR 13
45# define IRQ_LCDINTR 14
46# define IRQ_SSIEOT 15 /* Synchronous Serial Interface (SSI) */
47# define IRQ_UART3INTR 16
48# define IRQ_SCIINTR 17 /* Smart Card Interface (SCI) */
49# define IRQ_AACINTR 18 /* Advanced Audio Codec (AAC) */
50# define IRQ_MMCINTR 19 /* Multimedia Card (MMC) */
51# define IRQ_USBINTR 20
52# define IRQ_DMAINTR 21
53# define IRQ_T3UI 22 /* Timer 3 underflow */
54# define IRQ_GPIO4INTR 23 /* GPIO External IRQ Interrupt on F4 */
55# define IRQ_GPIO5INTR 24 /* GPIO External IRQ Interrupt on F5 */
56# define IRQ_GPIO6INTR 25 /* GPIO External IRQ Interrupt on F6 */
57# define IRQ_GPIO7INTR 26 /* GPIO External IRQ Interrupt on F7 */
58# define IRQ_BMIINTR 27 /* Battery Monitor Interface (BMI) */
59
60# define NR_IRQ_CPU 28 /* IRQs directly recognized by CPU */
61
62 /* Given IRQ, return GPIO interrupt number 0-7 */
63# define IRQ_TO_GPIO(i) ((i) \
64 - (((i) > IRQ_GPIO3INTR) ? IRQ_GPIO4INTR - IRQ_GPIO3INTR - 1 : 0)\
65 - (((i) > IRQ_GPIO0INTR) ? IRQ_GPIO1INTR - IRQ_GPIO0INTR - 1 : 0))
66
67#endif
68
69#if defined (CONFIG_ARCH_LH7A404)
70
71# define IRQ_BROWN 0 /* Brownout */
72# define IRQ_WDTINTR 1 /* Watchdog Timer */
73# define IRQ_COMMRX 2 /* ARM Comm Rx for Debug */
74# define IRQ_COMMTX 3 /* ARM Comm Tx for Debug */
75# define IRQ_T1UI 4 /* Timer 1 underflow */
76# define IRQ_T2UI 5 /* Timer 2 underflow */
77# define IRQ_CSINT 6 /* Codec Interrupt (shared by AAC on 404) */
78# define IRQ_DMAM2P0 7 /* -- DMA Memory to Peripheral */
79# define IRQ_DMAM2P1 8
80# define IRQ_DMAM2P2 9
81# define IRQ_DMAM2P3 10
82# define IRQ_DMAM2P4 11
83# define IRQ_DMAM2P5 12
84# define IRQ_DMAM2P6 13
85# define IRQ_DMAM2P7 14
86# define IRQ_DMAM2P8 15
87# define IRQ_DMAM2P9 16
88# define IRQ_DMAM2M0 17 /* -- DMA Memory to Memory */
89# define IRQ_DMAM2M1 18
90# define IRQ_GPIO0INTR 19 /* -- GPIOF Interrupt */
91# define IRQ_GPIO1INTR 20
92# define IRQ_GPIO2INTR 21
93# define IRQ_GPIO3INTR 22
94# define IRQ_SOFT_V1_23 23 /* -- Unassigned */
95# define IRQ_SOFT_V1_24 24
96# define IRQ_SOFT_V1_25 25
97# define IRQ_SOFT_V1_26 26
98# define IRQ_SOFT_V1_27 27
99# define IRQ_SOFT_V1_28 28
100# define IRQ_SOFT_V1_29 29
101# define IRQ_SOFT_V1_30 30
102# define IRQ_SOFT_V1_31 31
103
104# define IRQ_BLINT 32 /* Battery Low */
105# define IRQ_BMIINTR 33 /* Battery Monitor */
106# define IRQ_MCINTR 34 /* Media Change */
107# define IRQ_TINTR 35 /* 64Hz Tick */
108# define IRQ_WEINT 36 /* Watchdog Expired */
109# define IRQ_RTCMI 37 /* Real-time Clock Match */
110# define IRQ_UART1INTR 38 /* UART1 Interrupt (including error) */
111# define IRQ_UART1ERR 39 /* UART1 Error */
112# define IRQ_UART2INTR 40 /* UART2 Interrupt (including error) */
113# define IRQ_UART2ERR 41 /* UART2 Error */
114# define IRQ_UART3INTR 42 /* UART3 Interrupt (including error) */
115# define IRQ_UART3ERR 43 /* UART3 Error */
116# define IRQ_SCIINTR 44 /* Smart Card */
117# define IRQ_TSCINTR 45 /* Touchscreen */
118# define IRQ_KMIINTR 46 /* Keyboard/Mouse (PS/2) */
119# define IRQ_GPIO4INTR 47 /* -- GPIOF Interrupt */
120# define IRQ_GPIO5INTR 48
121# define IRQ_GPIO6INTR 49
122# define IRQ_GPIO7INTR 50
123# define IRQ_T3UI 51 /* Timer 3 underflow */
124# define IRQ_LCDINTR 52 /* LCD Controller */
125# define IRQ_SSPINTR 53 /* Synchronous Serial Port */
126# define IRQ_SDINTR 54 /* Secure Digital Port (MMC) */
127# define IRQ_USBINTR 55 /* USB Device Port */
128# define IRQ_USHINTR 56 /* USB Host Port */
129# define IRQ_SOFT_V2_25 57 /* -- Unassigned */
130# define IRQ_SOFT_V2_26 58
131# define IRQ_SOFT_V2_27 59
132# define IRQ_SOFT_V2_28 60
133# define IRQ_SOFT_V2_29 61
134# define IRQ_SOFT_V2_30 62
135# define IRQ_SOFT_V2_31 63
136
137# define NR_IRQ_CPU 64 /* IRQs directly recognized by CPU */
138
139 /* Given IRQ, return GPIO interrupt number 0-7 */
140# define IRQ_TO_GPIO(i) ((i) \
141 - (((i) > IRQ_GPIO3INTR) ? IRQ_GPIO4INTR - IRQ_GPIO3INTR - 1 : 0)\
142 - IRQ_GPIO0INTR)
143
144 /* Vector Address constants */
145# define VA_VECTORED 0x100 /* Set for vectored interrupt */
146# define VA_VIC1DEFAULT 0x200 /* Set as default VECTADDR for VIC1 */
147# define VA_VIC2DEFAULT 0x400 /* Set as default VECTADDR for VIC2 */
148
149#endif
150
151 /* IRQ aliases */
152
153#if !defined (IRQ_GPIO0INTR)
154# define IRQ_GPIO0INTR IRQ_GPIO0FIQ
155#endif
156#define IRQ_TICK IRQ_TINTR
157#define IRQ_PCC1_RDY IRQ_GPIO6INTR /* PCCard 1 ready */
158#define IRQ_PCC2_RDY IRQ_GPIO7INTR /* PCCard 2 ready */
159#define IRQ_USB IRQ_USBINTR /* USB device */
160
161#ifdef CONFIG_MACH_KEV7A400
162# define IRQ_TS IRQ_GPIOFIQ /* Touchscreen */
163# define IRQ_CPLD IRQ_GPIO1INTR /* CPLD cascade */
164# define IRQ_PCC1_CD IRQ_GPIO_F2 /* PCCard 1 card detect */
165# define IRQ_PCC2_CD IRQ_GPIO_F3 /* PCCard 2 card detect */
166#endif
167
168#if defined (CONFIG_MACH_LPD7A400) || defined (CONFIG_MACH_LPD7A404)
169# define IRQ_CPLD_V28 IRQ_GPIO7INTR /* CPLD cascade through GPIO_PF7 */
170# define IRQ_CPLD_V34 IRQ_GPIO3INTR /* CPLD cascade through GPIO_PF3 */
171#endif
172
173 /* System specific IRQs */
174
175#define IRQ_BOARD_START NR_IRQ_CPU
176
177#ifdef CONFIG_MACH_KEV7A400
178# define IRQ_KEV7A400_CPLD IRQ_BOARD_START
179# define NR_IRQ_BOARD 5
180# define IRQ_KEV7A400_MMC_CD IRQ_KEV7A400_CPLD + 0 /* MMC Card Detect */
181# define IRQ_KEV7A400_RI2 IRQ_KEV7A400_CPLD + 1 /* Ring Indicator 2 */
182# define IRQ_KEV7A400_IDE_CF IRQ_KEV7A400_CPLD + 2 /* Compact Flash (?) */
183# define IRQ_KEV7A400_ETH_INT IRQ_KEV7A400_CPLD + 3 /* Ethernet chip */
184# define IRQ_KEV7A400_INT IRQ_KEV7A400_CPLD + 4
185#endif
186
187#if defined (CONFIG_MACH_LPD7A400) || defined (CONFIG_MACH_LPD7A404)
188# define IRQ_LPD7A40X_CPLD IRQ_BOARD_START
189# define NR_IRQ_BOARD 2
190# define IRQ_LPD7A40X_ETH_INT IRQ_LPD7A40X_CPLD + 0 /* Ethernet chip */
191# define IRQ_LPD7A400_TS IRQ_LPD7A40X_CPLD + 1 /* Touch screen */
192#endif
193
194#if defined (CONFIG_MACH_LPD7A400)
195# define IRQ_TOUCH IRQ_LPD7A400_TS
196#endif
197
198#define NR_IRQS (NR_IRQ_CPU + NR_IRQ_BOARD)
199
200#endif
diff --git a/arch/arm/mach-lh7a40x/include/mach/memory.h b/arch/arm/mach-lh7a40x/include/mach/memory.h
deleted file mode 100644
index edb8f5faf5d5..000000000000
--- a/arch/arm/mach-lh7a40x/include/mach/memory.h
+++ /dev/null
@@ -1,28 +0,0 @@
1/* arch/arm/mach-lh7a40x/include/mach/memory.h
2 *
3 * Copyright (C) 2004 Coastal Environmental Systems
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * version 2 as published by the Free Software Foundation.
8 *
9 *
10 * Refer to <file:Documentation/arm/Sharp-LH/SDRAM> for more information.
11 *
12 */
13
14#ifndef __ASM_ARCH_MEMORY_H
15#define __ASM_ARCH_MEMORY_H
16
17/*
18 * Physical DRAM offset.
19 */
20#define PHYS_OFFSET UL(0xc0000000)
21
22/*
23 * Sparsemem version of the above
24 */
25#define MAX_PHYSMEM_BITS 32
26#define SECTION_SIZE_BITS 24
27
28#endif
diff --git a/arch/arm/mach-lh7a40x/include/mach/registers.h b/arch/arm/mach-lh7a40x/include/mach/registers.h
deleted file mode 100644
index ea44396383a7..000000000000
--- a/arch/arm/mach-lh7a40x/include/mach/registers.h
+++ /dev/null
@@ -1,224 +0,0 @@
1/* arch/arm/mach-lh7a40x/include/mach/registers.h
2 *
3 * Copyright (C) 2004 Coastal Environmental Systems
4 * Copyright (C) 2004 Logic Product Development
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
9 *
10 */
11
12#include <mach/constants.h>
13
14#ifndef __ASM_ARCH_REGISTERS_H
15#define __ASM_ARCH_REGISTERS_H
16
17
18 /* Physical register base addresses */
19
20#define AC97C_PHYS (0x80000000) /* AC97 Controller */
21#define MMC_PHYS (0x80000100) /* Multimedia Card Controller */
22#define USB_PHYS (0x80000200) /* USB Client */
23#define SCI_PHYS (0x80000300) /* Secure Card Interface */
24#define CSC_PHYS (0x80000400) /* Clock/State Controller */
25#define INTC_PHYS (0x80000500) /* Interrupt Controller */
26#define UART1_PHYS (0x80000600) /* UART1 Controller */
27#define SIR_PHYS (0x80000600) /* IR Controller, same are UART1 */
28#define UART2_PHYS (0x80000700) /* UART2 Controller */
29#define UART3_PHYS (0x80000800) /* UART3 Controller */
30#define DCDC_PHYS (0x80000900) /* DC to DC Controller */
31#define ACI_PHYS (0x80000a00) /* Audio Codec Interface */
32#define SSP_PHYS (0x80000b00) /* Synchronous ... */
33#define TIMER_PHYS (0x80000c00) /* Timer Controller */
34#define RTC_PHYS (0x80000d00) /* Real-time Clock */
35#define GPIO_PHYS (0x80000e00) /* General Purpose IO */
36#define BMI_PHYS (0x80000f00) /* Battery Monitor Interface */
37#define HRTFTC_PHYS (0x80001000) /* High-res TFT Controller (LH7A400) */
38#define ALI_PHYS (0x80001000) /* Advanced LCD Interface (LH7A404) */
39#define WDT_PHYS (0x80001400) /* Watchdog Timer */
40#define SMC_PHYS (0x80002000) /* Static Memory Controller */
41#define SDRC_PHYS (0x80002400) /* SDRAM Controller */
42#define DMAC_PHYS (0x80002800) /* DMA Controller */
43#define CLCDC_PHYS (0x80003000) /* Color LCD Controller */
44
45 /* Physical registers of the LH7A404 */
46
47#define ADC_PHYS (0x80001300) /* A/D & Touchscreen Controller */
48#define VIC1_PHYS (0x80008000) /* Vectored Interrupt Controller 1 */
49#define USBH_PHYS (0x80009000) /* USB OHCI host controller */
50#define VIC2_PHYS (0x8000a000) /* Vectored Interrupt Controller 2 */
51
52/*#define KBD_PHYS (0x80000e00) */
53/*#define LCDICP_PHYS (0x80001000) */
54
55
56 /* Clock/State Controller register */
57
58#define CSC_PWRSR __REG(CSC_PHYS + 0x00) /* Reset register & ID */
59#define CSC_PWRCNT __REG(CSC_PHYS + 0x04) /* Power control */
60#define CSC_CLKSET __REG(CSC_PHYS + 0x20) /* Clock speed control */
61#define CSC_USBDRESET __REG(CSC_PHYS + 0x4c) /* USB Device resets */
62
63#define CSC_PWRCNT_USBH_EN (1<<28) /* USB Host power enable */
64#define CSC_PWRCNT_DMAC_M2M1_EN (1<<27)
65#define CSC_PWRCNT_DMAC_M2M0_EN (1<<26)
66#define CSC_PWRCNT_DMAC_M2P8_EN (1<<25)
67#define CSC_PWRCNT_DMAC_M2P9_EN (1<<24)
68#define CSC_PWRCNT_DMAC_M2P6_EN (1<<23)
69#define CSC_PWRCNT_DMAC_M2P7_EN (1<<22)
70#define CSC_PWRCNT_DMAC_M2P4_EN (1<<21)
71#define CSC_PWRCNT_DMAC_M2P5_EN (1<<20)
72#define CSC_PWRCNT_DMAC_M2P2_EN (1<<19)
73#define CSC_PWRCNT_DMAC_M2P3_EN (1<<18)
74#define CSC_PWRCNT_DMAC_M2P0_EN (1<<17)
75#define CSC_PWRCNT_DMAC_M2P1_EN (1<<16)
76
77#define CSC_PWRSR_CHIPMAN_SHIFT (24)
78#define CSC_PWRSR_CHIPMAN_MASK (0xff)
79#define CSC_PWRSR_CHIPID_SHIFT (16)
80#define CSC_PWRSR_CHIPID_MASK (0xff)
81
82#define CSC_USBDRESET_APBRESETREG (1<<1)
83#define CSC_USBDRESET_IORESETREG (1<<0)
84
85 /* Interrupt Controller registers */
86
87#define INTC_INTSR __REG(INTC_PHYS + 0x00) /* Status */
88#define INTC_INTRSR __REG(INTC_PHYS + 0x04) /* Raw Status */
89#define INTC_INTENS __REG(INTC_PHYS + 0x08) /* Enable Set */
90#define INTC_INTENC __REG(INTC_PHYS + 0x0c) /* Enable Clear */
91
92
93 /* Vectored Interrupted Controller registers */
94
95#define VIC1_IRQSTATUS __REG(VIC1_PHYS + 0x00)
96#define VIC1_FIQSTATUS __REG(VIC1_PHYS + 0x04)
97#define VIC1_RAWINTR __REG(VIC1_PHYS + 0x08)
98#define VIC1_INTSEL __REG(VIC1_PHYS + 0x0c)
99#define VIC1_INTEN __REG(VIC1_PHYS + 0x10)
100#define VIC1_INTENCLR __REG(VIC1_PHYS + 0x14)
101#define VIC1_SOFTINT __REG(VIC1_PHYS + 0x18)
102#define VIC1_SOFTINTCLR __REG(VIC1_PHYS + 0x1c)
103#define VIC1_PROTECT __REG(VIC1_PHYS + 0x20)
104#define VIC1_VECTADDR __REG(VIC1_PHYS + 0x30)
105#define VIC1_NVADDR __REG(VIC1_PHYS + 0x34)
106#define VIC1_VAD0 __REG(VIC1_PHYS + 0x100)
107#define VIC1_VECTCNTL0 __REG(VIC1_PHYS + 0x200)
108#define VIC2_IRQSTATUS __REG(VIC2_PHYS + 0x00)
109#define VIC2_FIQSTATUS __REG(VIC2_PHYS + 0x04)
110#define VIC2_RAWINTR __REG(VIC2_PHYS + 0x08)
111#define VIC2_INTSEL __REG(VIC2_PHYS + 0x0c)
112#define VIC2_INTEN __REG(VIC2_PHYS + 0x10)
113#define VIC2_INTENCLR __REG(VIC2_PHYS + 0x14)
114#define VIC2_SOFTINT __REG(VIC2_PHYS + 0x18)
115#define VIC2_SOFTINTCLR __REG(VIC2_PHYS + 0x1c)
116#define VIC2_PROTECT __REG(VIC2_PHYS + 0x20)
117#define VIC2_VECTADDR __REG(VIC2_PHYS + 0x30)
118#define VIC2_NVADDR __REG(VIC2_PHYS + 0x34)
119#define VIC2_VAD0 __REG(VIC2_PHYS + 0x100)
120#define VIC2_VECTCNTL0 __REG(VIC2_PHYS + 0x200)
121
122#define VIC_CNTL_ENABLE (0x20)
123
124 /* USB Host registers (Open HCI compatible) */
125
126#define USBH_CMDSTATUS __REG(USBH_PHYS + 0x08)
127
128
129 /* GPIO registers */
130
131#define GPIO_INTTYPE1 __REG(GPIO_PHYS + 0x4c) /* Interrupt Type 1 (Edge) */
132#define GPIO_INTTYPE2 __REG(GPIO_PHYS + 0x50) /* Interrupt Type 2 */
133#define GPIO_GPIOFEOI __REG(GPIO_PHYS + 0x54) /* GPIO End-of-Interrupt */
134#define GPIO_GPIOINTEN __REG(GPIO_PHYS + 0x58) /* GPIO Interrupt Enable */
135#define GPIO_INTSTATUS __REG(GPIO_PHYS + 0x5c) /* GPIO Interrupt Status */
136#define GPIO_PINMUX __REG(GPIO_PHYS + 0x2c)
137#define GPIO_PADD __REG(GPIO_PHYS + 0x10)
138#define GPIO_PAD __REG(GPIO_PHYS + 0x00)
139#define GPIO_PCD __REG(GPIO_PHYS + 0x08)
140#define GPIO_PCDD __REG(GPIO_PHYS + 0x18)
141#define GPIO_PEDD __REG(GPIO_PHYS + 0x24)
142#define GPIO_PED __REG(GPIO_PHYS + 0x20)
143
144
145 /* Static Memory Controller registers */
146
147#define SMC_BCR0 __REG(SMC_PHYS + 0x00) /* Bank 0 Configuration */
148#define SMC_BCR1 __REG(SMC_PHYS + 0x04) /* Bank 1 Configuration */
149#define SMC_BCR2 __REG(SMC_PHYS + 0x08) /* Bank 2 Configuration */
150#define SMC_BCR3 __REG(SMC_PHYS + 0x0C) /* Bank 3 Configuration */
151#define SMC_BCR6 __REG(SMC_PHYS + 0x18) /* Bank 6 Configuration */
152#define SMC_BCR7 __REG(SMC_PHYS + 0x1c) /* Bank 7 Configuration */
153
154
155#ifdef CONFIG_MACH_KEV7A400
156# define CPLD_RD_OPT_DIP_SW __REG16(CPLD_PHYS + 0x00) /* Read Option SW */
157# define CPLD_WR_IO_BRD_CTL __REG16(CPLD_PHYS + 0x00) /* Write Control */
158# define CPLD_RD_PB_KEYS __REG16(CPLD_PHYS + 0x02) /* Read Btn Keys */
159# define CPLD_LATCHED_INTS __REG16(CPLD_PHYS + 0x04) /* Read INTR stat. */
160# define CPLD_CL_INT __REG16(CPLD_PHYS + 0x04) /* Clear INTR stat */
161# define CPLD_BOOT_MMC_STATUS __REG16(CPLD_PHYS + 0x06) /* R/O */
162# define CPLD_RD_KPD_ROW_SENSE __REG16(CPLD_PHYS + 0x08)
163# define CPLD_WR_PB_INT_MASK __REG16(CPLD_PHYS + 0x08)
164# define CPLD_RD_BRD_DISP_SW __REG16(CPLD_PHYS + 0x0a)
165# define CPLD_WR_EXT_INT_MASK __REG16(CPLD_PHYS + 0x0a)
166# define CPLD_LCD_PWR_CNTL __REG16(CPLD_PHYS + 0x0c)
167# define CPLD_SEVEN_SEG __REG16(CPLD_PHYS + 0x0e) /* 7 seg. LED mask */
168
169#endif
170
171#if defined (CONFIG_MACH_LPD7A400) || defined (CONFIG_MACH_LPD7A404)
172
173# define CPLD_CONTROL __REG16(CPLD02_PHYS)
174# define CPLD_SPI_DATA __REG16(CPLD06_PHYS)
175# define CPLD_SPI_CONTROL __REG16(CPLD08_PHYS)
176# define CPLD_SPI_EEPROM __REG16(CPLD0A_PHYS)
177# define CPLD_INTERRUPTS __REG16(CPLD0C_PHYS) /* IRQ mask/status */
178# define CPLD_BOOT_MODE __REG16(CPLD0E_PHYS)
179# define CPLD_FLASH __REG16(CPLD10_PHYS)
180# define CPLD_POWER_MGMT __REG16(CPLD12_PHYS)
181# define CPLD_REVISION __REG16(CPLD14_PHYS)
182# define CPLD_GPIO_EXT __REG16(CPLD16_PHYS)
183# define CPLD_GPIO_DATA __REG16(CPLD18_PHYS)
184# define CPLD_GPIO_DIR __REG16(CPLD1A_PHYS)
185
186#endif
187
188 /* Timer registers */
189
190#define TIMER_LOAD1 __REG(TIMER_PHYS + 0x00) /* Timer 1 initial value */
191#define TIMER_VALUE1 __REG(TIMER_PHYS + 0x04) /* Timer 1 current value */
192#define TIMER_CONTROL1 __REG(TIMER_PHYS + 0x08) /* Timer 1 control word */
193#define TIMER_EOI1 __REG(TIMER_PHYS + 0x0c) /* Timer 1 interrupt clear */
194
195#define TIMER_LOAD2 __REG(TIMER_PHYS + 0x20) /* Timer 2 initial value */
196#define TIMER_VALUE2 __REG(TIMER_PHYS + 0x24) /* Timer 2 current value */
197#define TIMER_CONTROL2 __REG(TIMER_PHYS + 0x28) /* Timer 2 control word */
198#define TIMER_EOI2 __REG(TIMER_PHYS + 0x2c) /* Timer 2 interrupt clear */
199
200#define TIMER_BUZZCON __REG(TIMER_PHYS + 0x40) /* Buzzer configuration */
201
202#define TIMER_LOAD3 __REG(TIMER_PHYS + 0x80) /* Timer 3 initial value */
203#define TIMER_VALUE3 __REG(TIMER_PHYS + 0x84) /* Timer 3 current value */
204#define TIMER_CONTROL3 __REG(TIMER_PHYS + 0x88) /* Timer 3 control word */
205#define TIMER_EOI3 __REG(TIMER_PHYS + 0x8c) /* Timer 3 interrupt clear */
206
207#define TIMER_C_ENABLE (1<<7)
208#define TIMER_C_PERIODIC (1<<6)
209#define TIMER_C_FREERUNNING (0)
210#define TIMER_C_2KHZ (0x00) /* 1.986 kHz */
211#define TIMER_C_508KHZ (0x08)
212
213 /* GPIO registers */
214
215#define GPIO_PFDD __REG(GPIO_PHYS + 0x34) /* PF direction */
216#define GPIO_INTTYPE1 __REG(GPIO_PHYS + 0x4c) /* IRQ edge or lvl */
217#define GPIO_INTTYPE2 __REG(GPIO_PHYS + 0x50) /* IRQ activ hi/lo */
218#define GPIO_GPIOFEOI __REG(GPIO_PHYS + 0x54) /* GPIOF end of IRQ */
219#define GPIO_GPIOFINTEN __REG(GPIO_PHYS + 0x58) /* GPIOF IRQ enable */
220#define GPIO_INTSTATUS __REG(GPIO_PHYS + 0x5c) /* GPIOF IRQ latch */
221#define GPIO_RAWINTSTATUS __REG(GPIO_PHYS + 0x60) /* GPIOF IRQ raw */
222
223
224#endif /* _ASM_ARCH_REGISTERS_H */
diff --git a/arch/arm/mach-lh7a40x/include/mach/ssp.h b/arch/arm/mach-lh7a40x/include/mach/ssp.h
deleted file mode 100644
index 509916182e34..000000000000
--- a/arch/arm/mach-lh7a40x/include/mach/ssp.h
+++ /dev/null
@@ -1,70 +0,0 @@
1/* ssp.h
2
3 written by Marc Singer
4 6 Dec 2004
5
6 Copyright (C) 2004 Marc Singer
7
8 -----------
9 DESCRIPTION
10 -----------
11
12 This SSP header is available throughout the kernel, for this
13 machine/architecture, because drivers that use it may be dispersed.
14
15 This file was cloned from the 7952x implementation. It would be
16 better to share them, but we're taking an easier approach for the
17 time being.
18
19*/
20
21#if !defined (__SSP_H__)
22# define __SSP_H__
23
24/* ----- Includes */
25
26/* ----- Types */
27
28struct ssp_driver {
29 int (*init) (void);
30 void (*exit) (void);
31 void (*acquire) (void);
32 void (*release) (void);
33 int (*configure) (int device, int mode, int speed,
34 int frame_size_write, int frame_size_read);
35 void (*chip_select) (int enable);
36 void (*set_callbacks) (void* handle,
37 irqreturn_t (*callback_tx)(void*),
38 irqreturn_t (*callback_rx)(void*));
39 void (*enable) (void);
40 void (*disable) (void);
41// int (*save_state) (void*);
42// void (*restore_state) (void*);
43 int (*read) (void);
44 int (*write) (u16 data);
45 int (*write_read) (u16 data);
46 void (*flush) (void);
47 void (*write_async) (void* pv, size_t cb);
48 size_t (*write_pos) (void);
49};
50
51 /* These modes are only available on the LH79524 */
52#define SSP_MODE_SPI (1)
53#define SSP_MODE_SSI (2)
54#define SSP_MODE_MICROWIRE (3)
55#define SSP_MODE_I2S (4)
56
57 /* CPLD SPI devices */
58#define DEVICE_EEPROM 0 /* Configuration eeprom */
59#define DEVICE_MAC 1 /* MAC eeprom (LPD79524) */
60#define DEVICE_CODEC 2 /* Audio codec */
61#define DEVICE_TOUCH 3 /* Touch screen (LPD79520) */
62
63/* ----- Globals */
64
65/* ----- Prototypes */
66
67//extern struct ssp_driver lh79520_i2s_driver;
68extern struct ssp_driver lh7a400_cpld_ssp_driver;
69
70#endif /* __SSP_H__ */
diff --git a/arch/arm/mach-lh7a40x/include/mach/system.h b/arch/arm/mach-lh7a40x/include/mach/system.h
deleted file mode 100644
index 45a56d3b93d7..000000000000
--- a/arch/arm/mach-lh7a40x/include/mach/system.h
+++ /dev/null
@@ -1,19 +0,0 @@
1/* arch/arm/mach-lh7a40x/include/mach/system.h
2 *
3 * Copyright (C) 2004 Coastal Environmental Systems
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * version 2 as published by the Free Software Foundation.
8 *
9 */
10
11static inline void arch_idle(void)
12{
13 cpu_do_idle ();
14}
15
16static inline void arch_reset(char mode, const char *cmd)
17{
18 cpu_reset (0);
19}
diff --git a/arch/arm/mach-lh7a40x/include/mach/timex.h b/arch/arm/mach-lh7a40x/include/mach/timex.h
deleted file mode 100644
index 08028cef1b3b..000000000000
--- a/arch/arm/mach-lh7a40x/include/mach/timex.h
+++ /dev/null
@@ -1,17 +0,0 @@
1/* arch/arm/mach-lh7a40x/include/mach/timex.h
2 *
3 * Copyright (C) 2004 Coastal Environmental Systems
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * version 2 as published by the Free Software Foundation.
8 *
9 */
10
11#include <mach/constants.h>
12
13#define CLOCK_TICK_RATE (PLL_CLOCK/6/16)
14
15/*
16#define CLOCK_TICK_RATE 3686400
17*/
diff --git a/arch/arm/mach-lh7a40x/include/mach/uncompress.h b/arch/arm/mach-lh7a40x/include/mach/uncompress.h
deleted file mode 100644
index 55b80d479eb4..000000000000
--- a/arch/arm/mach-lh7a40x/include/mach/uncompress.h
+++ /dev/null
@@ -1,38 +0,0 @@
1/* arch/arm/mach-lh7a40x/include/mach/uncompress.h
2 *
3 * Copyright (C) 2004 Coastal Environmental Systems
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * version 2 as published by the Free Software Foundation.
8 *
9 */
10
11#include <mach/registers.h>
12
13#ifndef UART_R_DATA
14# define UART_R_DATA (0x00)
15#endif
16#ifndef UART_R_STATUS
17# define UART_R_STATUS (0x10)
18#endif
19#define nTxRdy (0x20) /* Not TxReady (literally Tx FIFO full) */
20
21 /* Access UART with physical addresses before MMU is setup */
22#define UART_STATUS (*(volatile unsigned long*) (UART2_PHYS + UART_R_STATUS))
23#define UART_DATA (*(volatile unsigned long*) (UART2_PHYS + UART_R_DATA))
24
25static inline void putc(int ch)
26{
27 while (UART_STATUS & nTxRdy)
28 barrier();
29 UART_DATA = ch;
30}
31
32static inline void flush(void)
33{
34}
35
36 /* NULL functions; we don't presently need them */
37#define arch_decomp_setup()
38#define arch_decomp_wdog()
diff --git a/arch/arm/mach-lh7a40x/include/mach/vmalloc.h b/arch/arm/mach-lh7a40x/include/mach/vmalloc.h
deleted file mode 100644
index d62da7358b16..000000000000
--- a/arch/arm/mach-lh7a40x/include/mach/vmalloc.h
+++ /dev/null
@@ -1,10 +0,0 @@
1/* arch/arm/mach-lh7a40x/include/mach/vmalloc.h
2 *
3 * Copyright (C) 2004 Coastal Environmental Systems
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * version 2 as published by the Free Software Foundation.
8 *
9 */
10#define VMALLOC_END (0xe8000000UL)
diff --git a/arch/arm/mach-lh7a40x/irq-kev7a400.c b/arch/arm/mach-lh7a40x/irq-kev7a400.c
deleted file mode 100644
index c7433b3c5812..000000000000
--- a/arch/arm/mach-lh7a40x/irq-kev7a400.c
+++ /dev/null
@@ -1,93 +0,0 @@
1/* arch/arm/mach-lh7a40x/irq-kev7a400.c
2 *
3 * Copyright (C) 2004 Coastal Environmental Systems
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * version 2 as published by the Free Software Foundation.
8 *
9 */
10
11#include <linux/interrupt.h>
12#include <linux/init.h>
13
14#include <asm/irq.h>
15#include <asm/mach/irq.h>
16#include <asm/mach/hardware.h>
17#include <asm/mach/irqs.h>
18
19#include "common.h"
20
21 /* KEV7a400 CPLD IRQ handling */
22
23static u16 CPLD_IRQ_mask; /* Mask for CPLD IRQs, 1 == unmasked */
24
25static void
26lh7a400_ack_cpld_irq (u32 irq)
27{
28 CPLD_CL_INT = 1 << (irq - IRQ_KEV7A400_CPLD);
29}
30
31static void
32lh7a400_mask_cpld_irq (u32 irq)
33{
34 CPLD_IRQ_mask &= ~(1 << (irq - IRQ_KEV7A400_CPLD));
35 CPLD_WR_PB_INT_MASK = CPLD_IRQ_mask;
36}
37
38static void
39lh7a400_unmask_cpld_irq (u32 irq)
40{
41 CPLD_IRQ_mask |= 1 << (irq - IRQ_KEV7A400_CPLD);
42 CPLD_WR_PB_INT_MASK = CPLD_IRQ_mask;
43}
44
45static struct
46irq_chip lh7a400_cpld_chip = {
47 .name = "CPLD",
48 .ack = lh7a400_ack_cpld_irq,
49 .mask = lh7a400_mask_cpld_irq,
50 .unmask = lh7a400_unmask_cpld_irq,
51};
52
53static void
54lh7a400_cpld_handler (unsigned int irq, struct irq_desc *desc)
55{
56 u32 mask = CPLD_LATCHED_INTS;
57 irq = IRQ_KEV_7A400_CPLD;
58 for (; mask; mask >>= 1, ++irq) {
59 if (mask & 1)
60 desc[irq].handle (irq, desc);
61 }
62}
63
64 /* IRQ initialization */
65
66void __init
67lh7a400_init_board_irq (void)
68{
69 int irq;
70
71 for (irq = IRQ_KEV7A400_CPLD;
72 irq < IRQ_KEV7A400_CPLD + NR_IRQ_KEV7A400_CPLD; ++irq) {
73 set_irq_chip (irq, &lh7a400_cpld_chip);
74 set_irq_handler (irq, handle_edge_irq);
75 set_irq_flags (irq, IRQF_VALID);
76 }
77 set_irq_chained_handler (IRQ_CPLD, kev7a400_cpld_handler);
78
79 /* Clear all CPLD interrupts */
80 CPLD_CL_INT = 0xff; /* CPLD_INTR_MMC_CD | CPLD_INTR_ETH_INT; */
81
82 /* *** FIXME CF enabled in ide-probe.c */
83
84 GPIO_GPIOINTEN = 0; /* Disable all GPIO interrupts */
85 barrier();
86 GPIO_INTTYPE1
87 = (GPIO_INTR_PCC1_CD | GPIO_INTR_PCC1_CD); /* Edge trig. */
88 GPIO_INTTYPE2 = 0; /* Falling edge & low-level */
89 GPIO_GPIOFEOI = 0xff; /* Clear all GPIO interrupts */
90 GPIO_GPIOINTEN = 0xff; /* Enable all GPIO interrupts */
91
92 init_FIQ();
93}
diff --git a/arch/arm/mach-lh7a40x/irq-lh7a400.c b/arch/arm/mach-lh7a40x/irq-lh7a400.c
deleted file mode 100644
index f2e7e655ca35..000000000000
--- a/arch/arm/mach-lh7a40x/irq-lh7a400.c
+++ /dev/null
@@ -1,91 +0,0 @@
1/* arch/arm/mach-lh7a40x/irq-lh7a400.c
2 *
3 * Copyright (C) 2004 Coastal Environmental Systems
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * version 2 as published by the Free Software Foundation.
8 *
9 */
10
11#include <linux/init.h>
12#include <linux/module.h>
13#include <linux/interrupt.h>
14
15#include <mach/hardware.h>
16#include <asm/irq.h>
17#include <asm/mach/irq.h>
18#include <mach/irqs.h>
19
20#include "common.h"
21
22 /* CPU IRQ handling */
23
24static void lh7a400_mask_irq(struct irq_data *d)
25{
26 INTC_INTENC = (1 << d->irq);
27}
28
29static void lh7a400_unmask_irq(struct irq_data *d)
30{
31 INTC_INTENS = (1 << d->irq);
32}
33
34static void lh7a400_ack_gpio_irq(struct irq_data *d)
35{
36 GPIO_GPIOFEOI = (1 << IRQ_TO_GPIO (d->irq));
37 INTC_INTENC = (1 << d->irq);
38}
39
40static struct irq_chip lh7a400_internal_chip = {
41 .name = "MPU",
42 .irq_ack = lh7a400_mask_irq, /* Level triggering -> mask is ack */
43 .irq_mask = lh7a400_mask_irq,
44 .irq_unmask = lh7a400_unmask_irq,
45};
46
47static struct irq_chip lh7a400_gpio_chip = {
48 .name = "GPIO",
49 .irq_ack = lh7a400_ack_gpio_irq,
50 .irq_mask = lh7a400_mask_irq,
51 .irq_unmask = lh7a400_unmask_irq,
52};
53
54
55 /* IRQ initialization */
56
57void __init lh7a400_init_irq (void)
58{
59 int irq;
60
61 INTC_INTENC = 0xffffffff; /* Disable all interrupts */
62 GPIO_GPIOFINTEN = 0x00; /* Disable all GPIOF interrupts */
63 barrier ();
64
65 for (irq = 0; irq < NR_IRQS; ++irq) {
66 switch (irq) {
67 case IRQ_GPIO0INTR:
68 case IRQ_GPIO1INTR:
69 case IRQ_GPIO2INTR:
70 case IRQ_GPIO3INTR:
71 case IRQ_GPIO4INTR:
72 case IRQ_GPIO5INTR:
73 case IRQ_GPIO6INTR:
74 case IRQ_GPIO7INTR:
75 set_irq_chip (irq, &lh7a400_gpio_chip);
76 set_irq_handler (irq, handle_level_irq); /* OK default */
77 break;
78 default:
79 set_irq_chip (irq, &lh7a400_internal_chip);
80 set_irq_handler (irq, handle_level_irq);
81 }
82 set_irq_flags (irq, IRQF_VALID);
83 }
84
85 lh7a40x_init_board_irq ();
86
87/* *** FIXME: the LH7a400 does use FIQ interrupts in some cases. For
88 the time being, these are not initialized. */
89
90/* init_FIQ(); */
91}
diff --git a/arch/arm/mach-lh7a40x/irq-lh7a404.c b/arch/arm/mach-lh7a40x/irq-lh7a404.c
deleted file mode 100644
index 14b173389573..000000000000
--- a/arch/arm/mach-lh7a40x/irq-lh7a404.c
+++ /dev/null
@@ -1,175 +0,0 @@
1/* arch/arm/mach-lh7a40x/irq-lh7a404.c
2 *
3 * Copyright (C) 2004 Logic Product Development
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * version 2 as published by the Free Software Foundation.
8 *
9 */
10
11#include <linux/init.h>
12#include <linux/module.h>
13#include <linux/interrupt.h>
14
15#include <mach/hardware.h>
16#include <asm/irq.h>
17#include <asm/mach/irq.h>
18#include <mach/irqs.h>
19
20#include "common.h"
21
22#define USE_PRIORITIES
23
24/* See Documentation/arm/Sharp-LH/VectoredInterruptController for more
25 * information on using the vectored interrupt controller's
26 * prioritizing feature. */
27
28static unsigned char irq_pri_vic1[] = {
29#if defined (USE_PRIORITIES)
30 IRQ_GPIO3INTR, /* CPLD */
31 IRQ_DMAM2P4, IRQ_DMAM2P5, /* AC97 */
32#endif
33};
34static unsigned char irq_pri_vic2[] = {
35#if defined (USE_PRIORITIES)
36 IRQ_T3UI, /* Timer */
37 IRQ_GPIO7INTR, /* CPLD */
38 IRQ_UART1INTR, IRQ_UART2INTR, IRQ_UART3INTR,
39 IRQ_LCDINTR, /* LCD */
40 IRQ_TSCINTR, /* ADC/Touchscreen */
41#endif
42};
43
44 /* CPU IRQ handling */
45
46static void lh7a404_vic1_mask_irq(struct irq_data *d)
47{
48 VIC1_INTENCLR = (1 << d->irq);
49}
50
51static void lh7a404_vic1_unmask_irq(struct irq_data *d)
52{
53 VIC1_INTEN = (1 << d->irq);
54}
55
56static void lh7a404_vic2_mask_irq(struct irq_data *d)
57{
58 VIC2_INTENCLR = (1 << (d->irq - 32));
59}
60
61static void lh7a404_vic2_unmask_irq(struct irq_data *d)
62{
63 VIC2_INTEN = (1 << (d->irq - 32));
64}
65
66static void lh7a404_vic1_ack_gpio_irq(struct irq_data *d)
67{
68 GPIO_GPIOFEOI = (1 << IRQ_TO_GPIO (d->irq));
69 VIC1_INTENCLR = (1 << d->irq);
70}
71
72static void lh7a404_vic2_ack_gpio_irq(struct irq_data *d)
73{
74 GPIO_GPIOFEOI = (1 << IRQ_TO_GPIO (d->irq));
75 VIC2_INTENCLR = (1 << d->irq);
76}
77
78static struct irq_chip lh7a404_vic1_chip = {
79 .name = "VIC1",
80 .irq_ack = lh7a404_vic1_mask_irq, /* Because level-triggered */
81 .irq_mask = lh7a404_vic1_mask_irq,
82 .irq_unmask = lh7a404_vic1_unmask_irq,
83};
84
85static struct irq_chip lh7a404_vic2_chip = {
86 .name = "VIC2",
87 .irq_ack = lh7a404_vic2_mask_irq, /* Because level-triggered */
88 .irq_mask = lh7a404_vic2_mask_irq,
89 .irq_unmask = lh7a404_vic2_unmask_irq,
90};
91
92static struct irq_chip lh7a404_gpio_vic1_chip = {
93 .name = "GPIO-VIC1",
94 .irq_ack = lh7a404_vic1_ack_gpio_irq,
95 .irq_mask = lh7a404_vic1_mask_irq,
96 .irq_unmask = lh7a404_vic1_unmask_irq,
97};
98
99static struct irq_chip lh7a404_gpio_vic2_chip = {
100 .name = "GPIO-VIC2",
101 .irq_ack = lh7a404_vic2_ack_gpio_irq,
102 .irq_mask = lh7a404_vic2_mask_irq,
103 .irq_unmask = lh7a404_vic2_unmask_irq,
104};
105
106 /* IRQ initialization */
107
108#if defined (CONFIG_ARCH_LH7A400) && defined (CONFIG_ARCH_LH7A404)
109extern void* branch_irq_lh7a400;
110#endif
111
112void __init lh7a404_init_irq (void)
113{
114 int irq;
115
116#if defined (CONFIG_ARCH_LH7A400) && defined (CONFIG_ARCH_LH7A404)
117#define NOP 0xe1a00000 /* mov r0, r0 */
118 branch_irq_lh7a400 = NOP;
119#endif
120
121 VIC1_INTENCLR = 0xffffffff;
122 VIC2_INTENCLR = 0xffffffff;
123 VIC1_INTSEL = 0; /* All IRQs */
124 VIC2_INTSEL = 0; /* All IRQs */
125 VIC1_NVADDR = VA_VIC1DEFAULT;
126 VIC2_NVADDR = VA_VIC2DEFAULT;
127 VIC1_VECTADDR = 0;
128 VIC2_VECTADDR = 0;
129
130 GPIO_GPIOFINTEN = 0x00; /* Disable all GPIOF interrupts */
131 barrier ();
132
133 /* Install prioritized interrupts, if there are any. */
134 /* The | 0x20*/
135 for (irq = 0; irq < 16; ++irq) {
136 (&VIC1_VAD0)[irq]
137 = (irq < ARRAY_SIZE (irq_pri_vic1))
138 ? (irq_pri_vic1[irq] | VA_VECTORED) : 0;
139 (&VIC1_VECTCNTL0)[irq]
140 = (irq < ARRAY_SIZE (irq_pri_vic1))
141 ? (irq_pri_vic1[irq] | VIC_CNTL_ENABLE) : 0;
142 (&VIC2_VAD0)[irq]
143 = (irq < ARRAY_SIZE (irq_pri_vic2))
144 ? (irq_pri_vic2[irq] | VA_VECTORED) : 0;
145 (&VIC2_VECTCNTL0)[irq]
146 = (irq < ARRAY_SIZE (irq_pri_vic2))
147 ? (irq_pri_vic2[irq] | VIC_CNTL_ENABLE) : 0;
148 }
149
150 for (irq = 0; irq < NR_IRQS; ++irq) {
151 switch (irq) {
152 case IRQ_GPIO0INTR:
153 case IRQ_GPIO1INTR:
154 case IRQ_GPIO2INTR:
155 case IRQ_GPIO3INTR:
156 case IRQ_GPIO4INTR:
157 case IRQ_GPIO5INTR:
158 case IRQ_GPIO6INTR:
159 case IRQ_GPIO7INTR:
160 set_irq_chip (irq, irq < 32
161 ? &lh7a404_gpio_vic1_chip
162 : &lh7a404_gpio_vic2_chip);
163 set_irq_handler (irq, handle_level_irq); /* OK default */
164 break;
165 default:
166 set_irq_chip (irq, irq < 32
167 ? &lh7a404_vic1_chip
168 : &lh7a404_vic2_chip);
169 set_irq_handler (irq, handle_level_irq);
170 }
171 set_irq_flags (irq, IRQF_VALID);
172 }
173
174 lh7a40x_init_board_irq ();
175}
diff --git a/arch/arm/mach-lh7a40x/irq-lpd7a40x.c b/arch/arm/mach-lh7a40x/irq-lpd7a40x.c
deleted file mode 100644
index 1bfdcddcb93e..000000000000
--- a/arch/arm/mach-lh7a40x/irq-lpd7a40x.c
+++ /dev/null
@@ -1,128 +0,0 @@
1/* arch/arm/mach-lh7a40x/irq-lpd7a40x.c
2 *
3 * Copyright (C) 2004 Coastal Environmental Systems
4 * Copyright (C) 2004 Logic Product Development
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
9 *
10 */
11
12#include <linux/init.h>
13#include <linux/module.h>
14#include <linux/interrupt.h>
15
16#include <mach/hardware.h>
17#include <asm/irq.h>
18#include <asm/mach/irq.h>
19#include <mach/irqs.h>
20
21#include "common.h"
22
23static void lh7a40x_ack_cpld_irq(struct irq_data *d)
24{
25 /* CPLD doesn't have ack capability */
26}
27
28static void lh7a40x_mask_cpld_irq(struct irq_data *d)
29{
30 switch (d->irq) {
31 case IRQ_LPD7A40X_ETH_INT:
32 CPLD_INTERRUPTS = CPLD_INTERRUPTS | 0x4;
33 break;
34 case IRQ_LPD7A400_TS:
35 CPLD_INTERRUPTS = CPLD_INTERRUPTS | 0x8;
36 break;
37 }
38}
39
40static void lh7a40x_unmask_cpld_irq(struct irq_data *d)
41{
42 switch (d->irq) {
43 case IRQ_LPD7A40X_ETH_INT:
44 CPLD_INTERRUPTS = CPLD_INTERRUPTS & ~ 0x4;
45 break;
46 case IRQ_LPD7A400_TS:
47 CPLD_INTERRUPTS = CPLD_INTERRUPTS & ~ 0x8;
48 break;
49 }
50}
51
52static struct irq_chip lh7a40x_cpld_chip = {
53 .name = "CPLD",
54 .irq_ack = lh7a40x_ack_cpld_irq,
55 .irq_mask = lh7a40x_mask_cpld_irq,
56 .irq_unmask = lh7a40x_unmask_cpld_irq,
57};
58
59static void lh7a40x_cpld_handler (unsigned int irq, struct irq_desc *desc)
60{
61 unsigned int mask = CPLD_INTERRUPTS;
62
63 desc->irq_data.chip->ack (irq);
64
65 if ((mask & 0x1) == 0) /* WLAN */
66 generic_handle_irq(IRQ_LPD7A40X_ETH_INT);
67
68 if ((mask & 0x2) == 0) /* Touch */
69 generic_handle_irq(IRQ_LPD7A400_TS);
70
71 desc->irq_data.chip->unmask (irq); /* Level-triggered need this */
72}
73
74
75 /* IRQ initialization */
76
77void __init lh7a40x_init_board_irq (void)
78{
79 int irq;
80
81 /* Rev A (v2.8): PF0, PF1, PF2, and PF3 are available IRQs.
82 PF7 supports the CPLD.
83 Rev B (v3.4): PF0, PF1, and PF2 are available IRQs.
84 PF3 supports the CPLD.
85 (Some) LPD7A404 prerelease boards report a version
86 number of 0x16, but we force an override since the
87 hardware is of the newer variety.
88 */
89
90 unsigned char cpld_version = CPLD_REVISION;
91 int pinCPLD;
92
93#if defined CONFIG_MACH_LPD7A404
94 cpld_version = 0x34; /* Override, for now */
95#endif
96 pinCPLD = (cpld_version == 0x28) ? 7 : 3;
97
98 /* First, configure user controlled GPIOF interrupts */
99
100 GPIO_PFDD &= ~0x0f; /* PF0-3 are inputs */
101 GPIO_INTTYPE1 &= ~0x0f; /* PF0-3 are level triggered */
102 GPIO_INTTYPE2 &= ~0x0f; /* PF0-3 are active low */
103 barrier ();
104 GPIO_GPIOFINTEN |= 0x0f; /* Enable PF0, PF1, PF2, and PF3 IRQs */
105
106 /* Then, configure CPLD interrupt */
107
108 CPLD_INTERRUPTS = 0x0c; /* Disable all CPLD interrupts */
109 GPIO_PFDD &= ~(1 << pinCPLD); /* Make input */
110 GPIO_INTTYPE1 |= (1 << pinCPLD); /* Edge triggered */
111 GPIO_INTTYPE2 &= ~(1 << pinCPLD); /* Active low */
112 barrier ();
113 GPIO_GPIOFINTEN |= (1 << pinCPLD); /* Enable */
114
115 /* Cascade CPLD interrupts */
116
117 for (irq = IRQ_BOARD_START;
118 irq < IRQ_BOARD_START + NR_IRQ_BOARD; ++irq) {
119 set_irq_chip (irq, &lh7a40x_cpld_chip);
120 set_irq_handler (irq, handle_edge_irq);
121 set_irq_flags (irq, IRQF_VALID);
122 }
123
124 set_irq_chained_handler ((cpld_version == 0x28)
125 ? IRQ_CPLD_V28
126 : IRQ_CPLD_V34,
127 lh7a40x_cpld_handler);
128}
diff --git a/arch/arm/mach-lh7a40x/lcd-panel.h b/arch/arm/mach-lh7a40x/lcd-panel.h
deleted file mode 100644
index a7f5027b2f78..000000000000
--- a/arch/arm/mach-lh7a40x/lcd-panel.h
+++ /dev/null
@@ -1,345 +0,0 @@
1/* lcd-panel.h
2
3 written by Marc Singer
4 18 Jul 2005
5
6 Copyright (C) 2005 Marc Singer
7
8 -----------
9 DESCRIPTION
10 -----------
11
12 Only one panel may be defined at a time.
13
14 The pixel clock is calculated to be no greater than the target.
15
16 Each timing value is accompanied by a specification comment.
17
18 UNITS/MIN/TYP/MAX
19
20 Most of the units will be in clocks.
21
22 USE_RGB555
23
24 Define this macro to configure the AMBA LCD controller to use an
25 RGB555 encoding for the pels instead of the normal RGB565.
26
27 LPD9520, LPD79524, LPD7A400, LPD7A404-10, LPD7A404-11
28
29 These boards are best approximated by 555 for all panels. Some
30 can use an extra low-order bit of blue in bit 16 of the color
31 value, but we don't have a way to communicate this non-linear
32 mapping to the kernel.
33
34*/
35
36#if !defined (__LCD_PANEL_H__)
37# define __LCD_PANEL_H__
38
39#if defined (MACH_LPD79520)\
40 || defined (MACH_LPD79524)\
41 || defined (MACH_LPD7A400)\
42 || defined (MACH_LPD7A404)
43# define USE_RGB555
44#endif
45
46struct clcd_panel_extra {
47 unsigned int hrmode;
48 unsigned int clsen;
49 unsigned int spsen;
50 unsigned int pcdel;
51 unsigned int revdel;
52 unsigned int lpdel;
53 unsigned int spldel;
54 unsigned int pc2del;
55};
56
57#define NS_TO_CLOCK(ns,c) ((((ns)*((c)/1000) + (1000000 - 1))/1000000))
58#define CLOCK_TO_DIV(e,c) (((c) + (e) - 1)/(e))
59
60#if defined CONFIG_FB_ARMCLCD_SHARP_LQ035Q7DB02_HRTFT
61
62 /* Logic Product Development LCD 3.5" QVGA HRTFT -10 */
63 /* Sharp PN LQ035Q7DB02 w/HRTFT controller chip */
64
65#define PIX_CLOCK_TARGET (6800000)
66#define PIX_CLOCK_DIVIDER CLOCK_TO_DIV (PIX_CLOCK_TARGET, HCLK)
67#define PIX_CLOCK (HCLK/PIX_CLOCK_DIVIDER)
68
69static struct clcd_panel lcd_panel = {
70 .mode = {
71 .name = "3.5in QVGA (LQ035Q7DB02)",
72 .xres = 240,
73 .yres = 320,
74 .pixclock = PIX_CLOCK,
75 .left_margin = 16,
76 .right_margin = 21,
77 .upper_margin = 8, // line/8/8/8
78 .lower_margin = 5,
79 .hsync_len = 61,
80 .vsync_len = NS_TO_CLOCK (60, PIX_CLOCK),
81 .vmode = FB_VMODE_NONINTERLACED,
82 },
83 .width = -1,
84 .height = -1,
85 .tim2 = TIM2_IPC | (PIX_CLOCK_DIVIDER - 2),
86 .cntl = CNTL_LCDTFT | CNTL_WATERMARK,
87 .bpp = 16,
88};
89
90#define HAS_LCD_PANEL_EXTRA
91
92static struct clcd_panel_extra lcd_panel_extra = {
93 .hrmode = 1,
94 .clsen = 1,
95 .spsen = 1,
96 .pcdel = 8,
97 .revdel = 7,
98 .lpdel = 13,
99 .spldel = 77,
100 .pc2del = 208,
101};
102
103#endif
104
105#if defined CONFIG_FB_ARMCLCD_SHARP_LQ057Q3DC02
106
107 /* Logic Product Development LCD 5.7" QVGA -10 */
108 /* Sharp PN LQ057Q3DC02 */
109 /* QVGA mode, V/Q=LOW */
110
111/* From Sharp on 2006.1.3. I believe some of the values are incorrect
112 * based on the datasheet.
113
114 Timing0 TIMING1 TIMING2 CONTROL
115 0x140A0C4C 0x080504EF 0x013F380D 0x00000829
116 HBP= 20 VBP= 8 BCD= 0
117 HFP= 10 VFP= 5 CPL=319
118 HSW= 12 VSW= 1 IOE= 0
119 PPL= 19 LPP=239 IPC= 1
120 IHS= 1
121 IVS= 1
122 ACB= 0
123 CSEL= 0
124 PCD= 13
125
126 */
127
128/* The full horizontal cycle (Th) is clock/360/400/450. */
129/* The full vertical cycle (Tv) is line/251/262/280. */
130
131#define PIX_CLOCK_TARGET (6300000) /* -/6.3/7 MHz */
132#define PIX_CLOCK_DIVIDER CLOCK_TO_DIV (PIX_CLOCK_TARGET, HCLK)
133#define PIX_CLOCK (HCLK/PIX_CLOCK_DIVIDER)
134
135static struct clcd_panel lcd_panel = {
136 .mode = {
137 .name = "5.7in QVGA (LQ057Q3DC02)",
138 .xres = 320,
139 .yres = 240,
140 .pixclock = PIX_CLOCK,
141 .left_margin = 11,
142 .right_margin = 400-11-320-2,
143 .upper_margin = 7, // line/7/7/7
144 .lower_margin = 262-7-240-2,
145 .hsync_len = 2, // clk/2/96/200
146 .vsync_len = 2, // line/2/-/34
147 .vmode = FB_VMODE_NONINTERLACED,
148 },
149 .width = -1,
150 .height = -1,
151 .tim2 = TIM2_IHS | TIM2_IVS
152 | (PIX_CLOCK_DIVIDER - 2),
153 .cntl = CNTL_LCDTFT | CNTL_WATERMARK,
154 .bpp = 16,
155};
156
157#endif
158
159#if defined CONFIG_FB_ARMCLCD_SHARP_LQ64D343
160
161 /* Logic Product Development LCD 6.4" VGA -10 */
162 /* Sharp PN LQ64D343 */
163
164/* The full horizontal cycle (Th) is clock/750/800/900. */
165/* The full vertical cycle (Tv) is line/515/525/560. */
166
167#define PIX_CLOCK_TARGET (28330000)
168#define PIX_CLOCK_DIVIDER CLOCK_TO_DIV (PIX_CLOCK_TARGET, HCLK)
169#define PIX_CLOCK (HCLK/PIX_CLOCK_DIVIDER)
170
171static struct clcd_panel lcd_panel = {
172 .mode = {
173 .name = "6.4in QVGA (LQ64D343)",
174 .xres = 640,
175 .yres = 480,
176 .pixclock = PIX_CLOCK,
177 .left_margin = 32,
178 .right_margin = 800-32-640-96,
179 .upper_margin = 32, // line/34/34/34
180 .lower_margin = 540-32-480-2,
181 .hsync_len = 96, // clk/2/96/200
182 .vsync_len = 2, // line/2/-/34
183 .vmode = FB_VMODE_NONINTERLACED,
184 },
185 .width = -1,
186 .height = -1,
187 .tim2 = TIM2_IHS | TIM2_IVS
188 | (PIX_CLOCK_DIVIDER - 2),
189 .cntl = CNTL_LCDTFT | CNTL_WATERMARK,
190 .bpp = 16,
191};
192
193#endif
194
195#if defined CONFIG_FB_ARMCLCD_SHARP_LQ10D368
196
197 /* Logic Product Development LCD 10.4" VGA -10 */
198 /* Sharp PN LQ10D368 */
199
200#define PIX_CLOCK_TARGET (28330000)
201#define PIX_CLOCK_DIVIDER CLOCK_TO_DIV (PIX_CLOCK_TARGET, HCLK)
202#define PIX_CLOCK (HCLK/PIX_CLOCK_DIVIDER)
203
204static struct clcd_panel lcd_panel = {
205 .mode = {
206 .name = "10.4in VGA (LQ10D368)",
207 .xres = 640,
208 .yres = 480,
209 .pixclock = PIX_CLOCK,
210 .left_margin = 21,
211 .right_margin = 15,
212 .upper_margin = 34,
213 .lower_margin = 5,
214 .hsync_len = 96,
215 .vsync_len = 16,
216 .vmode = FB_VMODE_NONINTERLACED,
217 },
218 .width = -1,
219 .height = -1,
220 .tim2 = TIM2_IHS | TIM2_IVS
221 | (PIX_CLOCK_DIVIDER - 2),
222 .cntl = CNTL_LCDTFT | CNTL_WATERMARK,
223 .bpp = 16,
224};
225
226#endif
227
228#if defined CONFIG_FB_ARMCLCD_SHARP_LQ121S1DG41
229
230 /* Logic Product Development LCD 12.1" SVGA -10 */
231 /* Sharp PN LQ121S1DG41, was LQ121S1DG31 */
232
233/* Note that with a 99993900 Hz HCLK, it is not possible to hit the
234 * target clock frequency range of 35MHz to 42MHz. */
235
236/* If the target pixel clock is substantially lower than the panel
237 * spec, this is done to prevent the LCD display from glitching when
238 * the CPU is under load. A pixel clock higher than 25MHz
239 * (empirically determined) will compete with the CPU for bus cycles
240 * for the Ethernet chip. However, even a pixel clock of 10MHz
241 * competes with Compact Flash interface during some operations
242 * (fdisk, e2fsck). And, at that speed the display may have a visible
243 * flicker. */
244
245/* The full horizontal cycle (Th) is clock/832/1056/1395. */
246
247#define PIX_CLOCK_TARGET (20000000)
248#define PIX_CLOCK_DIVIDER CLOCK_TO_DIV (PIX_CLOCK_TARGET, HCLK)
249#define PIX_CLOCK (HCLK/PIX_CLOCK_DIVIDER)
250
251static struct clcd_panel lcd_panel = {
252 .mode = {
253 .name = "12.1in SVGA (LQ121S1DG41)",
254 .xres = 800,
255 .yres = 600,
256 .pixclock = PIX_CLOCK,
257 .left_margin = 89, // ns/5/-/(1/PIX_CLOCK)-10
258 .right_margin = 1056-800-89-128,
259 .upper_margin = 23, // line/23/23/23
260 .lower_margin = 44,
261 .hsync_len = 128, // clk/2/128/200
262 .vsync_len = 4, // line/2/4/6
263 .vmode = FB_VMODE_NONINTERLACED,
264 },
265 .width = -1,
266 .height = -1,
267 .tim2 = TIM2_IHS | TIM2_IVS
268 | (PIX_CLOCK_DIVIDER - 2),
269 .cntl = CNTL_LCDTFT | CNTL_WATERMARK,
270 .bpp = 16,
271};
272
273#endif
274
275#if defined CONFIG_FB_ARMCLCD_HITACHI
276
277 /* Hitachi*/
278 /* Submitted by Michele Da Rold <michele.darold@ecsproject.com> */
279
280#define PIX_CLOCK_TARGET (49000000)
281#define PIX_CLOCK_DIVIDER CLOCK_TO_DIV (PIX_CLOCK_TARGET, HCLK)
282#define PIX_CLOCK (HCLK/PIX_CLOCK_DIVIDER)
283
284static struct clcd_panel lcd_panel = {
285 .mode = {
286 .name = "Hitachi 800x480",
287 .xres = 800,
288 .yres = 480,
289 .pixclock = PIX_CLOCK,
290 .left_margin = 88,
291 .right_margin = 40,
292 .upper_margin = 32,
293 .lower_margin = 11,
294 .hsync_len = 128,
295 .vsync_len = 2,
296 .vmode = FB_VMODE_NONINTERLACED,
297 },
298 .width = -1,
299 .height = -1,
300 .tim2 = TIM2_IPC | TIM2_IHS | TIM2_IVS
301 | (PIX_CLOCK_DIVIDER - 2),
302 .cntl = CNTL_LCDTFT | CNTL_WATERMARK,
303 .bpp = 16,
304};
305
306#endif
307
308
309#if defined CONFIG_FB_ARMCLCD_AUO_A070VW01_WIDE
310
311 /* AU Optotronics A070VW01 7.0 Wide Screen color Display*/
312 /* Submitted by Michele Da Rold <michele.darold@ecsproject.com> */
313
314#define PIX_CLOCK_TARGET (10000000)
315#define PIX_CLOCK_DIVIDER CLOCK_TO_DIV (PIX_CLOCK_TARGET, HCLK)
316#define PIX_CLOCK (HCLK/PIX_CLOCK_DIVIDER)
317
318static struct clcd_panel lcd_panel = {
319 .mode = {
320 .name = "7.0in Wide (A070VW01)",
321 .xres = 480,
322 .yres = 234,
323 .pixclock = PIX_CLOCK,
324 .left_margin = 30,
325 .right_margin = 25,
326 .upper_margin = 14,
327 .lower_margin = 12,
328 .hsync_len = 100,
329 .vsync_len = 1,
330 .vmode = FB_VMODE_NONINTERLACED,
331 },
332 .width = -1,
333 .height = -1,
334 .tim2 = TIM2_IPC | TIM2_IHS | TIM2_IVS
335 | (PIX_CLOCK_DIVIDER - 2),
336 .cntl = CNTL_LCDTFT | CNTL_WATERMARK,
337 .bpp = 16,
338};
339
340#endif
341
342#undef NS_TO_CLOCK
343#undef CLOCK_TO_DIV
344
345#endif /* __LCD_PANEL_H__ */
diff --git a/arch/arm/mach-lh7a40x/ssp-cpld.c b/arch/arm/mach-lh7a40x/ssp-cpld.c
deleted file mode 100644
index 2901d49d1484..000000000000
--- a/arch/arm/mach-lh7a40x/ssp-cpld.c
+++ /dev/null
@@ -1,343 +0,0 @@
1/* arch/arm/mach-lh7a40x/ssp-cpld.c
2 *
3 * Copyright (C) 2004,2005 Marc Singer
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * version 2 as published by the Free Software Foundation.
8 *
9 * SSP/SPI driver for the CardEngine CPLD.
10 *
11 */
12
13/* NOTES
14 -----
15
16 o *** This driver is cribbed from the 7952x implementation.
17 Some comments may not apply.
18
19 o This driver contains sufficient logic to control either the
20 serial EEPROMs or the audio codec. It is included in the kernel
21 to support the codec. The EEPROMs are really the responsibility
22 of the boot loader and should probably be left alone.
23
24 o The code must be augmented to cope with multiple, simultaneous
25 clients.
26 o The audio codec writes to the codec chip whenever playback
27 starts.
28 o The touchscreen driver writes to the ads chip every time it
29 samples.
30 o The audio codec must write 16 bits, but the touch chip writes
31 are 8 bits long.
32 o We need to be able to keep these configurations separate while
33 simultaneously active.
34
35 */
36
37#include <linux/module.h>
38#include <linux/kernel.h>
39//#include <linux/sched.h>
40#include <linux/errno.h>
41#include <linux/interrupt.h>
42//#include <linux/ioport.h>
43#include <linux/init.h>
44#include <linux/delay.h>
45#include <linux/spinlock.h>
46#include <linux/io.h>
47
48#include <asm/irq.h>
49#include <mach/hardware.h>
50
51#include <mach/ssp.h>
52
53//#define TALK
54
55#if defined (TALK)
56#define PRINTK(f...) printk (f)
57#else
58#define PRINTK(f...) do {} while (0)
59#endif
60
61#if defined (CONFIG_ARCH_LH7A400)
62# define CPLD_SPID __REGP16(CPLD06_VIRT) /* SPI data */
63# define CPLD_SPIC __REGP16(CPLD08_VIRT) /* SPI control */
64# define CPLD_SPIC_CS_CODEC (1<<0)
65# define CPLD_SPIC_CS_TOUCH (1<<1)
66# define CPLD_SPIC_WRITE (0<<2)
67# define CPLD_SPIC_READ (1<<2)
68# define CPLD_SPIC_DONE (1<<3) /* r/o */
69# define CPLD_SPIC_LOAD (1<<4)
70# define CPLD_SPIC_START (1<<4)
71# define CPLD_SPIC_LOADED (1<<5) /* r/o */
72#endif
73
74#define CPLD_SPI __REGP16(CPLD0A_VIRT) /* SPI operation */
75#define CPLD_SPI_CS_EEPROM (1<<3)
76#define CPLD_SPI_SCLK (1<<2)
77#define CPLD_SPI_TX_SHIFT (1)
78#define CPLD_SPI_TX (1<<CPLD_SPI_TX_SHIFT)
79#define CPLD_SPI_RX_SHIFT (0)
80#define CPLD_SPI_RX (1<<CPLD_SPI_RX_SHIFT)
81
82/* *** FIXME: these timing values are substantially larger than the
83 *** chip requires. We may implement an nsleep () function. */
84#define T_SKH 1 /* Clock time high (us) */
85#define T_SKL 1 /* Clock time low (us) */
86#define T_CS 1 /* Minimum chip select low time (us) */
87#define T_CSS 1 /* Minimum chip select setup time (us) */
88#define T_DIS 1 /* Data setup time (us) */
89
90 /* EEPROM SPI bits */
91#define P_START (1<<9)
92#define P_WRITE (1<<7)
93#define P_READ (2<<7)
94#define P_ERASE (3<<7)
95#define P_EWDS (0<<7)
96#define P_WRAL (0<<7)
97#define P_ERAL (0<<7)
98#define P_EWEN (0<<7)
99#define P_A_EWDS (0<<5)
100#define P_A_WRAL (1<<5)
101#define P_A_ERAL (2<<5)
102#define P_A_EWEN (3<<5)
103
104struct ssp_configuration {
105 int device;
106 int mode;
107 int speed;
108 int frame_size_write;
109 int frame_size_read;
110};
111
112static struct ssp_configuration ssp_configuration;
113static spinlock_t ssp_lock;
114
115static void enable_cs (void)
116{
117 switch (ssp_configuration.device) {
118 case DEVICE_EEPROM:
119 CPLD_SPI |= CPLD_SPI_CS_EEPROM;
120 break;
121 }
122 udelay (T_CSS);
123}
124
125static void disable_cs (void)
126{
127 switch (ssp_configuration.device) {
128 case DEVICE_EEPROM:
129 CPLD_SPI &= ~CPLD_SPI_CS_EEPROM;
130 break;
131 }
132 udelay (T_CS);
133}
134
135static void pulse_clock (void)
136{
137 CPLD_SPI |= CPLD_SPI_SCLK;
138 udelay (T_SKH);
139 CPLD_SPI &= ~CPLD_SPI_SCLK;
140 udelay (T_SKL);
141}
142
143
144/* execute_spi_command
145
146 sends an spi command to a device. It first sends cwrite bits from
147 v. If cread is greater than zero it will read cread bits
148 (discarding the leading 0 bit) and return them. If cread is less
149 than zero it will check for completetion status and return 0 on
150 success or -1 on timeout. If cread is zero it does nothing other
151 than sending the command.
152
153 On the LPD7A400, we can only read or write multiples of 8 bits on
154 the codec and the touch screen device. Here, we round up.
155
156*/
157
158static int execute_spi_command (int v, int cwrite, int cread)
159{
160 unsigned long l = 0;
161
162#if defined (CONFIG_MACH_LPD7A400)
163 /* The codec and touch devices cannot be bit-banged. Instead,
164 * the CPLD provides an eight-bit shift register and a crude
165 * interface. */
166 if ( ssp_configuration.device == DEVICE_CODEC
167 || ssp_configuration.device == DEVICE_TOUCH) {
168 int select = 0;
169
170 PRINTK ("spi(%d %d.%d) 0x%04x",
171 ssp_configuration.device, cwrite, cread,
172 v);
173#if defined (TALK)
174 if (ssp_configuration.device == DEVICE_CODEC)
175 PRINTK (" 0x%03x -> %2d", v & 0x1ff, (v >> 9) & 0x7f);
176#endif
177 PRINTK ("\n");
178
179 if (ssp_configuration.device == DEVICE_CODEC)
180 select = CPLD_SPIC_CS_CODEC;
181 if (ssp_configuration.device == DEVICE_TOUCH)
182 select = CPLD_SPIC_CS_TOUCH;
183 if (cwrite) {
184 for (cwrite = (cwrite + 7)/8; cwrite-- > 0; ) {
185 CPLD_SPID = (v >> (8*cwrite)) & 0xff;
186 CPLD_SPIC = select | CPLD_SPIC_LOAD;
187 while (!(CPLD_SPIC & CPLD_SPIC_LOADED))
188 ;
189 CPLD_SPIC = select;
190 while (!(CPLD_SPIC & CPLD_SPIC_DONE))
191 ;
192 }
193 v = 0;
194 }
195 if (cread) {
196 mdelay (2); /* *** FIXME: required by ads7843? */
197 v = 0;
198 for (cread = (cread + 7)/8; cread-- > 0;) {
199 CPLD_SPID = 0;
200 CPLD_SPIC = select | CPLD_SPIC_READ
201 | CPLD_SPIC_START;
202 while (!(CPLD_SPIC & CPLD_SPIC_LOADED))
203 ;
204 CPLD_SPIC = select | CPLD_SPIC_READ;
205 while (!(CPLD_SPIC & CPLD_SPIC_DONE))
206 ;
207 v = (v << 8) | CPLD_SPID;
208 }
209 }
210 return v;
211 }
212#endif
213
214 PRINTK ("spi(%d) 0x%04x -> 0x%x\r\n", ssp_configuration.device,
215 v & 0x1ff, (v >> 9) & 0x7f);
216
217 enable_cs ();
218
219 v <<= CPLD_SPI_TX_SHIFT; /* Correction for position of SPI_TX bit */
220 while (cwrite--) {
221 CPLD_SPI
222 = (CPLD_SPI & ~CPLD_SPI_TX)
223 | ((v >> cwrite) & CPLD_SPI_TX);
224 udelay (T_DIS);
225 pulse_clock ();
226 }
227
228 if (cread < 0) {
229 int delay = 10;
230 disable_cs ();
231 udelay (1);
232 enable_cs ();
233
234 l = -1;
235 do {
236 if (CPLD_SPI & CPLD_SPI_RX) {
237 l = 0;
238 break;
239 }
240 } while (udelay (1), --delay);
241 }
242 else
243 /* We pulse the clock before the data to skip the leading zero. */
244 while (cread-- > 0) {
245 pulse_clock ();
246 l = (l<<1)
247 | (((CPLD_SPI & CPLD_SPI_RX)
248 >> CPLD_SPI_RX_SHIFT) & 0x1);
249 }
250
251 disable_cs ();
252 return l;
253}
254
255static int ssp_init (void)
256{
257 spin_lock_init (&ssp_lock);
258 memset (&ssp_configuration, 0, sizeof (ssp_configuration));
259 return 0;
260}
261
262
263/* ssp_chip_select
264
265 drops the chip select line for the CPLD shift-register controlled
266 devices. It doesn't enable chip
267
268*/
269
270static void ssp_chip_select (int enable)
271{
272#if defined (CONFIG_MACH_LPD7A400)
273 int select;
274
275 if (ssp_configuration.device == DEVICE_CODEC)
276 select = CPLD_SPIC_CS_CODEC;
277 else if (ssp_configuration.device == DEVICE_TOUCH)
278 select = CPLD_SPIC_CS_TOUCH;
279 else
280 return;
281
282 if (enable)
283 CPLD_SPIC = select;
284 else
285 CPLD_SPIC = 0;
286#endif
287}
288
289static void ssp_acquire (void)
290{
291 spin_lock (&ssp_lock);
292}
293
294static void ssp_release (void)
295{
296 ssp_chip_select (0); /* just in case */
297 spin_unlock (&ssp_lock);
298}
299
300static int ssp_configure (int device, int mode, int speed,
301 int frame_size_write, int frame_size_read)
302{
303 ssp_configuration.device = device;
304 ssp_configuration.mode = mode;
305 ssp_configuration.speed = speed;
306 ssp_configuration.frame_size_write = frame_size_write;
307 ssp_configuration.frame_size_read = frame_size_read;
308
309 return 0;
310}
311
312static int ssp_read (void)
313{
314 return execute_spi_command (0, 0, ssp_configuration.frame_size_read);
315}
316
317static int ssp_write (u16 data)
318{
319 execute_spi_command (data, ssp_configuration.frame_size_write, 0);
320 return 0;
321}
322
323static int ssp_write_read (u16 data)
324{
325 return execute_spi_command (data, ssp_configuration.frame_size_write,
326 ssp_configuration.frame_size_read);
327}
328
329struct ssp_driver lh7a40x_cpld_ssp_driver = {
330 .init = ssp_init,
331 .acquire = ssp_acquire,
332 .release = ssp_release,
333 .configure = ssp_configure,
334 .chip_select = ssp_chip_select,
335 .read = ssp_read,
336 .write = ssp_write,
337 .write_read = ssp_write_read,
338};
339
340
341MODULE_AUTHOR("Marc Singer");
342MODULE_DESCRIPTION("LPD7A40X CPLD SPI driver");
343MODULE_LICENSE("GPL");
diff --git a/arch/arm/mach-lh7a40x/time.c b/arch/arm/mach-lh7a40x/time.c
deleted file mode 100644
index 4601e425bae3..000000000000
--- a/arch/arm/mach-lh7a40x/time.c
+++ /dev/null
@@ -1,71 +0,0 @@
1/*
2 * arch/arm/mach-lh7a40x/time.c
3 *
4 * Copyright (C) 2004 Logic Product Development
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
9 *
10 */
11#include <linux/module.h>
12#include <linux/kernel.h>
13#include <linux/interrupt.h>
14#include <linux/irq.h>
15#include <linux/time.h>
16#include <linux/io.h>
17
18#include <mach/hardware.h>
19#include <asm/irq.h>
20#include <asm/leds.h>
21
22#include <asm/mach/time.h>
23#include "common.h"
24
25#if HZ < 100
26# define TIMER_CONTROL TIMER_CONTROL2
27# define TIMER_LOAD TIMER_LOAD2
28# define TIMER_CONSTANT (508469/HZ)
29# define TIMER_MODE (TIMER_C_ENABLE | TIMER_C_PERIODIC | TIMER_C_508KHZ)
30# define TIMER_EOI TIMER_EOI2
31# define TIMER_IRQ IRQ_T2UI
32#else
33# define TIMER_CONTROL TIMER_CONTROL3
34# define TIMER_LOAD TIMER_LOAD3
35# define TIMER_CONSTANT (3686400/HZ)
36# define TIMER_MODE (TIMER_C_ENABLE | TIMER_C_PERIODIC)
37# define TIMER_EOI TIMER_EOI3
38# define TIMER_IRQ IRQ_T3UI
39#endif
40
41static irqreturn_t
42lh7a40x_timer_interrupt(int irq, void *dev_id)
43{
44 TIMER_EOI = 0;
45 timer_tick();
46
47 return IRQ_HANDLED;
48}
49
50static struct irqaction lh7a40x_timer_irq = {
51 .name = "LHA740x Timer Tick",
52 .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
53 .handler = lh7a40x_timer_interrupt,
54};
55
56static void __init lh7a40x_timer_init (void)
57{
58 /* Stop/disable all timers */
59 TIMER_CONTROL1 = 0;
60 TIMER_CONTROL2 = 0;
61 TIMER_CONTROL3 = 0;
62
63 setup_irq (TIMER_IRQ, &lh7a40x_timer_irq);
64
65 TIMER_LOAD = TIMER_CONSTANT;
66 TIMER_CONTROL = TIMER_MODE;
67}
68
69struct sys_timer lh7a40x_timer = {
70 .init = &lh7a40x_timer_init,
71};
diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h
index ee747919a766..68d48ab6eacf 100644
--- a/drivers/net/smc91x.h
+++ b/drivers/net/smc91x.h
@@ -206,68 +206,6 @@ SMC_outw(u16 val, void __iomem *ioaddr, int reg)
206#define RPC_LSA_DEFAULT RPC_LED_TX_RX 206#define RPC_LSA_DEFAULT RPC_LED_TX_RX
207#define RPC_LSB_DEFAULT RPC_LED_100_10 207#define RPC_LSB_DEFAULT RPC_LED_100_10
208 208
209#elif defined(CONFIG_MACH_LPD79520) || \
210 defined(CONFIG_MACH_LPD7A400) || \
211 defined(CONFIG_MACH_LPD7A404)
212
213/* The LPD7X_IOBARRIER is necessary to overcome a mismatch between the
214 * way that the CPU handles chip selects and the way that the SMC chip
215 * expects the chip select to operate. Refer to
216 * Documentation/arm/Sharp-LH/IOBarrier for details. The read from
217 * IOBARRIER is a byte, in order that we read the least-common
218 * denominator. It would be wasteful to read 32 bits from an 8-bit
219 * accessible region.
220 *
221 * There is no explicit protection against interrupts intervening
222 * between the writew and the IOBARRIER. In SMC ISR there is a
223 * preamble that performs an IOBARRIER in the extremely unlikely event
224 * that the driver interrupts itself between a writew to the chip an
225 * the IOBARRIER that follows *and* the cache is large enough that the
226 * first off-chip access while handing the interrupt is to the SMC
227 * chip. Other devices in the same address space as the SMC chip must
228 * be aware of the potential for trouble and perform a similar
229 * IOBARRIER on entry to their ISR.
230 */
231
232#include <mach/constants.h> /* IOBARRIER_VIRT */
233
234#define SMC_CAN_USE_8BIT 0
235#define SMC_CAN_USE_16BIT 1
236#define SMC_CAN_USE_32BIT 0
237#define SMC_NOWAIT 0
238#define LPD7X_IOBARRIER readb (IOBARRIER_VIRT)
239
240#define SMC_inw(a,r)\
241 ({ unsigned short v = readw ((void*) ((a) + (r))); LPD7X_IOBARRIER; v; })
242#define SMC_outw(v,a,r) ({ writew ((v), (a) + (r)); LPD7X_IOBARRIER; })
243
244#define SMC_insw LPD7_SMC_insw
245static inline void LPD7_SMC_insw (unsigned char* a, int r,
246 unsigned char* p, int l)
247{
248 unsigned short* ps = (unsigned short*) p;
249 while (l-- > 0) {
250 *ps++ = readw (a + r);
251 LPD7X_IOBARRIER;
252 }
253}
254
255#define SMC_outsw LPD7_SMC_outsw
256static inline void LPD7_SMC_outsw (unsigned char* a, int r,
257 unsigned char* p, int l)
258{
259 unsigned short* ps = (unsigned short*) p;
260 while (l-- > 0) {
261 writew (*ps++, a + r);
262 LPD7X_IOBARRIER;
263 }
264}
265
266#define SMC_INTERRUPT_PREAMBLE LPD7X_IOBARRIER
267
268#define RPC_LSA_DEFAULT RPC_LED_TX_RX
269#define RPC_LSB_DEFAULT RPC_LED_100_10
270
271#elif defined(CONFIG_ARCH_VERSATILE) 209#elif defined(CONFIG_ARCH_VERSATILE)
272 210
273#define SMC_CAN_USE_8BIT 1 211#define SMC_CAN_USE_8BIT 1
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
index b1682d7f1d8a..1174d4d90407 100644
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -1110,29 +1110,6 @@ config SERIAL_PMACZILOG_CONSOLE
1110 on your (Power)Mac as the console, you can do so by answering 1110 on your (Power)Mac as the console, you can do so by answering
1111 Y to this option. 1111 Y to this option.
1112 1112
1113config SERIAL_LH7A40X
1114 tristate "Sharp LH7A40X embedded UART support"
1115 depends on ARM && ARCH_LH7A40X
1116 select SERIAL_CORE
1117 help
1118 This enables support for the three on-board UARTs of the
1119 Sharp LH7A40X series CPUs. Choose Y or M.
1120
1121config SERIAL_LH7A40X_CONSOLE
1122 bool "Support for console on Sharp LH7A40X serial port"
1123 depends on SERIAL_LH7A40X=y
1124 select SERIAL_CORE_CONSOLE
1125 help
1126 Say Y here if you wish to use one of the serial ports as the
1127 system console--the system console is the device which
1128 receives all kernel messages and warnings and which allows
1129 logins in single user mode.
1130
1131 Even if you say Y here, the currently visible framebuffer console
1132 (/dev/tty0) will still be used as the default system console, but
1133 you can alter that using a kernel command line, for example
1134 "console=ttyAM1".
1135
1136config SERIAL_CPM 1113config SERIAL_CPM
1137 tristate "CPM SCC/SMC serial port support" 1114 tristate "CPM SCC/SMC serial port support"
1138 depends on CPM2 || 8xx 1115 depends on CPM2 || 8xx
diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile
index 8ea92e9c73b0..8e325408b1a6 100644
--- a/drivers/tty/serial/Makefile
+++ b/drivers/tty/serial/Makefile
@@ -54,7 +54,6 @@ obj-$(CONFIG_SERIAL_68328) += 68328serial.o
54obj-$(CONFIG_SERIAL_68360) += 68360serial.o 54obj-$(CONFIG_SERIAL_68360) += 68360serial.o
55obj-$(CONFIG_SERIAL_MCF) += mcf.o 55obj-$(CONFIG_SERIAL_MCF) += mcf.o
56obj-$(CONFIG_SERIAL_PMACZILOG) += pmac_zilog.o 56obj-$(CONFIG_SERIAL_PMACZILOG) += pmac_zilog.o
57obj-$(CONFIG_SERIAL_LH7A40X) += serial_lh7a40x.o
58obj-$(CONFIG_SERIAL_DZ) += dz.o 57obj-$(CONFIG_SERIAL_DZ) += dz.o
59obj-$(CONFIG_SERIAL_ZS) += zs.o 58obj-$(CONFIG_SERIAL_ZS) += zs.o
60obj-$(CONFIG_SERIAL_SH_SCI) += sh-sci.o 59obj-$(CONFIG_SERIAL_SH_SCI) += sh-sci.o
diff --git a/drivers/tty/serial/serial_lh7a40x.c b/drivers/tty/serial/serial_lh7a40x.c
deleted file mode 100644
index ea744707c4d6..000000000000
--- a/drivers/tty/serial/serial_lh7a40x.c
+++ /dev/null
@@ -1,682 +0,0 @@
1/* drivers/serial/serial_lh7a40x.c
2 *
3 * Copyright (C) 2004 Coastal Environmental Systems
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * version 2 as published by the Free Software Foundation.
8 *
9 */
10
11/* Driver for Sharp LH7A40X embedded serial ports
12 *
13 * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
14 * Based on drivers/serial/amba.c, by Deep Blue Solutions Ltd.
15 *
16 * ---
17 *
18 * This driver supports the embedded UARTs of the Sharp LH7A40X series
19 * CPUs. While similar to the 16550 and other UART chips, there is
20 * nothing close to register compatibility. Moreover, some of the
21 * modem control lines are not available, either in the chip or they
22 * are lacking in the board-level implementation.
23 *
24 * - Use of SIRDIS
25 * For simplicity, we disable the IR functions of any UART whenever
26 * we enable it.
27 *
28 */
29
30
31#if defined(CONFIG_SERIAL_LH7A40X_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
32#define SUPPORT_SYSRQ
33#endif
34
35#include <linux/module.h>
36#include <linux/ioport.h>
37#include <linux/init.h>
38#include <linux/console.h>
39#include <linux/sysrq.h>
40#include <linux/tty.h>
41#include <linux/tty_flip.h>
42#include <linux/serial_core.h>
43#include <linux/serial.h>
44#include <linux/io.h>
45
46#include <asm/irq.h>
47#include <mach/hardware.h>
48
49#define DEV_MAJOR 204
50#define DEV_MINOR 16
51#define DEV_NR 3
52
53#define ISR_LOOP_LIMIT 256
54
55#define UR(p,o) _UR ((p)->membase, o)
56#define _UR(b,o) (*((volatile unsigned int*)(((unsigned char*) b) + (o))))
57#define BIT_CLR(p,o,m) UR(p,o) = UR(p,o) & (~(unsigned int)m)
58#define BIT_SET(p,o,m) UR(p,o) = UR(p,o) | ( (unsigned int)m)
59
60#define UART_REG_SIZE 32
61
62#define UART_R_DATA (0x00)
63#define UART_R_FCON (0x04)
64#define UART_R_BRCON (0x08)
65#define UART_R_CON (0x0c)
66#define UART_R_STATUS (0x10)
67#define UART_R_RAWISR (0x14)
68#define UART_R_INTEN (0x18)
69#define UART_R_ISR (0x1c)
70
71#define UARTEN (0x01) /* UART enable */
72#define SIRDIS (0x02) /* Serial IR disable (UART1 only) */
73
74#define RxEmpty (0x10)
75#define TxEmpty (0x80)
76#define TxFull (0x20)
77#define nRxRdy RxEmpty
78#define nTxRdy TxFull
79#define TxBusy (0x08)
80
81#define RxBreak (0x0800)
82#define RxOverrunError (0x0400)
83#define RxParityError (0x0200)
84#define RxFramingError (0x0100)
85#define RxError (RxBreak | RxOverrunError | RxParityError | RxFramingError)
86
87#define DCD (0x04)
88#define DSR (0x02)
89#define CTS (0x01)
90
91#define RxInt (0x01)
92#define TxInt (0x02)
93#define ModemInt (0x04)
94#define RxTimeoutInt (0x08)
95
96#define MSEOI (0x10)
97
98#define WLEN_8 (0x60)
99#define WLEN_7 (0x40)
100#define WLEN_6 (0x20)
101#define WLEN_5 (0x00)
102#define WLEN (0x60) /* Mask for all word-length bits */
103#define STP2 (0x08)
104#define PEN (0x02) /* Parity Enable */
105#define EPS (0x04) /* Even Parity Set */
106#define FEN (0x10) /* FIFO Enable */
107#define BRK (0x01) /* Send Break */
108
109
110struct uart_port_lh7a40x {
111 struct uart_port port;
112 unsigned int statusPrev; /* Most recently read modem status */
113};
114
115static void lh7a40xuart_stop_tx (struct uart_port* port)
116{
117 BIT_CLR (port, UART_R_INTEN, TxInt);
118}
119
120static void lh7a40xuart_start_tx (struct uart_port* port)
121{
122 BIT_SET (port, UART_R_INTEN, TxInt);
123
124 /* *** FIXME: do I need to check for startup of the
125 transmitter? The old driver did, but AMBA
126 doesn't . */
127}
128
129static void lh7a40xuart_stop_rx (struct uart_port* port)
130{
131 BIT_SET (port, UART_R_INTEN, RxTimeoutInt | RxInt);
132}
133
134static void lh7a40xuart_enable_ms (struct uart_port* port)
135{
136 BIT_SET (port, UART_R_INTEN, ModemInt);
137}
138
139static void lh7a40xuart_rx_chars (struct uart_port* port)
140{
141 struct tty_struct* tty = port->state->port.tty;
142 int cbRxMax = 256; /* (Gross) limit on receive */
143 unsigned int data; /* Received data and status */
144 unsigned int flag;
145
146 while (!(UR (port, UART_R_STATUS) & nRxRdy) && --cbRxMax) {
147 data = UR (port, UART_R_DATA);
148 flag = TTY_NORMAL;
149 ++port->icount.rx;
150
151 if (unlikely(data & RxError)) {
152 if (data & RxBreak) {
153 data &= ~(RxFramingError | RxParityError);
154 ++port->icount.brk;
155 if (uart_handle_break (port))
156 continue;
157 }
158 else if (data & RxParityError)
159 ++port->icount.parity;
160 else if (data & RxFramingError)
161 ++port->icount.frame;
162 if (data & RxOverrunError)
163 ++port->icount.overrun;
164
165 /* Mask by termios, leave Rx'd byte */
166 data &= port->read_status_mask | 0xff;
167
168 if (data & RxBreak)
169 flag = TTY_BREAK;
170 else if (data & RxParityError)
171 flag = TTY_PARITY;
172 else if (data & RxFramingError)
173 flag = TTY_FRAME;
174 }
175
176 if (uart_handle_sysrq_char (port, (unsigned char) data))
177 continue;
178
179 uart_insert_char(port, data, RxOverrunError, data, flag);
180 }
181 tty_flip_buffer_push (tty);
182 return;
183}
184
185static void lh7a40xuart_tx_chars (struct uart_port* port)
186{
187 struct circ_buf* xmit = &port->state->xmit;
188 int cbTxMax = port->fifosize;
189
190 if (port->x_char) {
191 UR (port, UART_R_DATA) = port->x_char;
192 ++port->icount.tx;
193 port->x_char = 0;
194 return;
195 }
196 if (uart_circ_empty (xmit) || uart_tx_stopped (port)) {
197 lh7a40xuart_stop_tx (port);
198 return;
199 }
200
201 /* Unlike the AMBA UART, the lh7a40x UART does not guarantee
202 that at least half of the FIFO is empty. Instead, we check
203 status for every character. Using the AMBA method causes
204 the transmitter to drop characters. */
205
206 do {
207 UR (port, UART_R_DATA) = xmit->buf[xmit->tail];
208 xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
209 ++port->icount.tx;
210 if (uart_circ_empty(xmit))
211 break;
212 } while (!(UR (port, UART_R_STATUS) & nTxRdy)
213 && cbTxMax--);
214
215 if (uart_circ_chars_pending (xmit) < WAKEUP_CHARS)
216 uart_write_wakeup (port);
217
218 if (uart_circ_empty (xmit))
219 lh7a40xuart_stop_tx (port);
220}
221
222static void lh7a40xuart_modem_status (struct uart_port* port)
223{
224 unsigned int status = UR (port, UART_R_STATUS);
225 unsigned int delta
226 = status ^ ((struct uart_port_lh7a40x*) port)->statusPrev;
227
228 BIT_SET (port, UART_R_RAWISR, MSEOI); /* Clear modem status intr */
229
230 if (!delta) /* Only happens if we missed 2 transitions */
231 return;
232
233 ((struct uart_port_lh7a40x*) port)->statusPrev = status;
234
235 if (delta & DCD)
236 uart_handle_dcd_change (port, status & DCD);
237
238 if (delta & DSR)
239 ++port->icount.dsr;
240
241 if (delta & CTS)
242 uart_handle_cts_change (port, status & CTS);
243
244 wake_up_interruptible (&port->state->port.delta_msr_wait);
245}
246
247static irqreturn_t lh7a40xuart_int (int irq, void* dev_id)
248{
249 struct uart_port* port = dev_id;
250 unsigned int cLoopLimit = ISR_LOOP_LIMIT;
251 unsigned int isr = UR (port, UART_R_ISR);
252
253
254 do {
255 if (isr & (RxInt | RxTimeoutInt))
256 lh7a40xuart_rx_chars(port);
257 if (isr & ModemInt)
258 lh7a40xuart_modem_status (port);
259 if (isr & TxInt)
260 lh7a40xuart_tx_chars (port);
261
262 if (--cLoopLimit == 0)
263 break;
264
265 isr = UR (port, UART_R_ISR);
266 } while (isr & (RxInt | TxInt | RxTimeoutInt));
267
268 return IRQ_HANDLED;
269}
270
271static unsigned int lh7a40xuart_tx_empty (struct uart_port* port)
272{
273 return (UR (port, UART_R_STATUS) & TxEmpty) ? TIOCSER_TEMT : 0;
274}
275
276static unsigned int lh7a40xuart_get_mctrl (struct uart_port* port)
277{
278 unsigned int result = 0;
279 unsigned int status = UR (port, UART_R_STATUS);
280
281 if (status & DCD)
282 result |= TIOCM_CAR;
283 if (status & DSR)
284 result |= TIOCM_DSR;
285 if (status & CTS)
286 result |= TIOCM_CTS;
287
288 return result;
289}
290
291static void lh7a40xuart_set_mctrl (struct uart_port* port, unsigned int mctrl)
292{
293 /* None of the ports supports DTR. UART1 supports RTS through GPIO. */
294 /* Note, kernel appears to be setting DTR and RTS on console. */
295
296 /* *** FIXME: this deserves more work. There's some work in
297 tracing all of the IO pins. */
298#if 0
299 if( port->mapbase == UART1_PHYS) {
300 gpioRegs_t *gpio = (gpioRegs_t *)IO_ADDRESS(GPIO_PHYS);
301
302 if (mctrl & TIOCM_RTS)
303 gpio->pbdr &= ~GPIOB_UART1_RTS;
304 else
305 gpio->pbdr |= GPIOB_UART1_RTS;
306 }
307#endif
308}
309
310static void lh7a40xuart_break_ctl (struct uart_port* port, int break_state)
311{
312 unsigned long flags;
313
314 spin_lock_irqsave(&port->lock, flags);
315 if (break_state == -1)
316 BIT_SET (port, UART_R_FCON, BRK); /* Assert break */
317 else
318 BIT_CLR (port, UART_R_FCON, BRK); /* Deassert break */
319 spin_unlock_irqrestore(&port->lock, flags);
320}
321
322static int lh7a40xuart_startup (struct uart_port* port)
323{
324 int retval;
325
326 retval = request_irq (port->irq, lh7a40xuart_int, 0,
327 "serial_lh7a40x", port);
328 if (retval)
329 return retval;
330
331 /* Initial modem control-line settings */
332 ((struct uart_port_lh7a40x*) port)->statusPrev
333 = UR (port, UART_R_STATUS);
334
335 /* There is presently no configuration option to enable IR.
336 Thus, we always disable it. */
337
338 BIT_SET (port, UART_R_CON, UARTEN | SIRDIS);
339 BIT_SET (port, UART_R_INTEN, RxTimeoutInt | RxInt);
340
341 return 0;
342}
343
344static void lh7a40xuart_shutdown (struct uart_port* port)
345{
346 free_irq (port->irq, port);
347 BIT_CLR (port, UART_R_FCON, BRK | FEN);
348 BIT_CLR (port, UART_R_CON, UARTEN);
349}
350
351static void lh7a40xuart_set_termios (struct uart_port* port,
352 struct ktermios* termios,
353 struct ktermios* old)
354{
355 unsigned int con;
356 unsigned int inten;
357 unsigned int fcon;
358 unsigned long flags;
359 unsigned int baud;
360 unsigned int quot;
361
362 baud = uart_get_baud_rate (port, termios, old, 8, port->uartclk/16);
363 quot = uart_get_divisor (port, baud); /* -1 performed elsewhere */
364
365 switch (termios->c_cflag & CSIZE) {
366 case CS5:
367 fcon = WLEN_5;
368 break;
369 case CS6:
370 fcon = WLEN_6;
371 break;
372 case CS7:
373 fcon = WLEN_7;
374 break;
375 case CS8:
376 default:
377 fcon = WLEN_8;
378 break;
379 }
380 if (termios->c_cflag & CSTOPB)
381 fcon |= STP2;
382 if (termios->c_cflag & PARENB) {
383 fcon |= PEN;
384 if (!(termios->c_cflag & PARODD))
385 fcon |= EPS;
386 }
387 if (port->fifosize > 1)
388 fcon |= FEN;
389
390 spin_lock_irqsave (&port->lock, flags);
391
392 uart_update_timeout (port, termios->c_cflag, baud);
393
394 port->read_status_mask = RxOverrunError;
395 if (termios->c_iflag & INPCK)
396 port->read_status_mask |= RxFramingError | RxParityError;
397 if (termios->c_iflag & (BRKINT | PARMRK))
398 port->read_status_mask |= RxBreak;
399
400 /* Figure mask for status we ignore */
401 port->ignore_status_mask = 0;
402 if (termios->c_iflag & IGNPAR)
403 port->ignore_status_mask |= RxFramingError | RxParityError;
404 if (termios->c_iflag & IGNBRK) {
405 port->ignore_status_mask |= RxBreak;
406 /* Ignore overrun when ignorning parity */
407 /* *** FIXME: is this in the right place? */
408 if (termios->c_iflag & IGNPAR)
409 port->ignore_status_mask |= RxOverrunError;
410 }
411
412 /* Ignore all receive errors when receive disabled */
413 if ((termios->c_cflag & CREAD) == 0)
414 port->ignore_status_mask |= RxError;
415
416 con = UR (port, UART_R_CON);
417 inten = (UR (port, UART_R_INTEN) & ~ModemInt);
418
419 if (UART_ENABLE_MS (port, termios->c_cflag))
420 inten |= ModemInt;
421
422 BIT_CLR (port, UART_R_CON, UARTEN); /* Disable UART */
423 UR (port, UART_R_INTEN) = 0; /* Disable interrupts */
424 UR (port, UART_R_BRCON) = quot - 1; /* Set baud rate divisor */
425 UR (port, UART_R_FCON) = fcon; /* Set FIFO and frame ctrl */
426 UR (port, UART_R_INTEN) = inten; /* Enable interrupts */
427 UR (port, UART_R_CON) = con; /* Restore UART mode */
428
429 spin_unlock_irqrestore(&port->lock, flags);
430}
431
432static const char* lh7a40xuart_type (struct uart_port* port)
433{
434 return port->type == PORT_LH7A40X ? "LH7A40X" : NULL;
435}
436
437static void lh7a40xuart_release_port (struct uart_port* port)
438{
439 release_mem_region (port->mapbase, UART_REG_SIZE);
440}
441
442static int lh7a40xuart_request_port (struct uart_port* port)
443{
444 return request_mem_region (port->mapbase, UART_REG_SIZE,
445 "serial_lh7a40x") != NULL
446 ? 0 : -EBUSY;
447}
448
449static void lh7a40xuart_config_port (struct uart_port* port, int flags)
450{
451 if (flags & UART_CONFIG_TYPE) {
452 port->type = PORT_LH7A40X;
453 lh7a40xuart_request_port (port);
454 }
455}
456
457static int lh7a40xuart_verify_port (struct uart_port* port,
458 struct serial_struct* ser)
459{
460 int ret = 0;
461
462 if (ser->type != PORT_UNKNOWN && ser->type != PORT_LH7A40X)
463 ret = -EINVAL;
464 if (ser->irq < 0 || ser->irq >= nr_irqs)
465 ret = -EINVAL;
466 if (ser->baud_base < 9600) /* *** FIXME: is this true? */
467 ret = -EINVAL;
468 return ret;
469}
470
471static struct uart_ops lh7a40x_uart_ops = {
472 .tx_empty = lh7a40xuart_tx_empty,
473 .set_mctrl = lh7a40xuart_set_mctrl,
474 .get_mctrl = lh7a40xuart_get_mctrl,
475 .stop_tx = lh7a40xuart_stop_tx,
476 .start_tx = lh7a40xuart_start_tx,
477 .stop_rx = lh7a40xuart_stop_rx,
478 .enable_ms = lh7a40xuart_enable_ms,
479 .break_ctl = lh7a40xuart_break_ctl,
480 .startup = lh7a40xuart_startup,
481 .shutdown = lh7a40xuart_shutdown,
482 .set_termios = lh7a40xuart_set_termios,
483 .type = lh7a40xuart_type,
484 .release_port = lh7a40xuart_release_port,
485 .request_port = lh7a40xuart_request_port,
486 .config_port = lh7a40xuart_config_port,
487 .verify_port = lh7a40xuart_verify_port,
488};
489
490static struct uart_port_lh7a40x lh7a40x_ports[DEV_NR] = {
491 {
492 .port = {
493 .membase = (void*) io_p2v (UART1_PHYS),
494 .mapbase = UART1_PHYS,
495 .iotype = UPIO_MEM,
496 .irq = IRQ_UART1INTR,
497 .uartclk = 14745600/2,
498 .fifosize = 16,
499 .ops = &lh7a40x_uart_ops,
500 .flags = UPF_BOOT_AUTOCONF,
501 .line = 0,
502 },
503 },
504 {
505 .port = {
506 .membase = (void*) io_p2v (UART2_PHYS),
507 .mapbase = UART2_PHYS,
508 .iotype = UPIO_MEM,
509 .irq = IRQ_UART2INTR,
510 .uartclk = 14745600/2,
511 .fifosize = 16,
512 .ops = &lh7a40x_uart_ops,
513 .flags = UPF_BOOT_AUTOCONF,
514 .line = 1,
515 },
516 },
517 {
518 .port = {
519 .membase = (void*) io_p2v (UART3_PHYS),
520 .mapbase = UART3_PHYS,
521 .iotype = UPIO_MEM,
522 .irq = IRQ_UART3INTR,
523 .uartclk = 14745600/2,
524 .fifosize = 16,
525 .ops = &lh7a40x_uart_ops,
526 .flags = UPF_BOOT_AUTOCONF,
527 .line = 2,
528 },
529 },
530};
531
532#ifndef CONFIG_SERIAL_LH7A40X_CONSOLE
533# define LH7A40X_CONSOLE NULL
534#else
535# define LH7A40X_CONSOLE &lh7a40x_console
536
537static void lh7a40xuart_console_putchar(struct uart_port *port, int ch)
538{
539 while (UR(port, UART_R_STATUS) & nTxRdy)
540 ;
541 UR(port, UART_R_DATA) = ch;
542}
543
544static void lh7a40xuart_console_write (struct console* co,
545 const char* s,
546 unsigned int count)
547{
548 struct uart_port* port = &lh7a40x_ports[co->index].port;
549 unsigned int con = UR (port, UART_R_CON);
550 unsigned int inten = UR (port, UART_R_INTEN);
551
552
553 UR (port, UART_R_INTEN) = 0; /* Disable all interrupts */
554 BIT_SET (port, UART_R_CON, UARTEN | SIRDIS); /* Enable UART */
555
556 uart_console_write(port, s, count, lh7a40xuart_console_putchar);
557
558 /* Wait until all characters are sent */
559 while (UR (port, UART_R_STATUS) & TxBusy)
560 ;
561
562 /* Restore control and interrupt mask */
563 UR (port, UART_R_CON) = con;
564 UR (port, UART_R_INTEN) = inten;
565}
566
567static void __init lh7a40xuart_console_get_options (struct uart_port* port,
568 int* baud,
569 int* parity,
570 int* bits)
571{
572 if (UR (port, UART_R_CON) & UARTEN) {
573 unsigned int fcon = UR (port, UART_R_FCON);
574 unsigned int quot = UR (port, UART_R_BRCON) + 1;
575
576 switch (fcon & (PEN | EPS)) {
577 default: *parity = 'n'; break;
578 case PEN: *parity = 'o'; break;
579 case PEN | EPS: *parity = 'e'; break;
580 }
581
582 switch (fcon & WLEN) {
583 default:
584 case WLEN_8: *bits = 8; break;
585 case WLEN_7: *bits = 7; break;
586 case WLEN_6: *bits = 6; break;
587 case WLEN_5: *bits = 5; break;
588 }
589
590 *baud = port->uartclk/(16*quot);
591 }
592}
593
594static int __init lh7a40xuart_console_setup (struct console* co, char* options)
595{
596 struct uart_port* port;
597 int baud = 38400;
598 int bits = 8;
599 int parity = 'n';
600 int flow = 'n';
601
602 if (co->index >= DEV_NR) /* Bounds check on device number */
603 co->index = 0;
604 port = &lh7a40x_ports[co->index].port;
605
606 if (options)
607 uart_parse_options (options, &baud, &parity, &bits, &flow);
608 else
609 lh7a40xuart_console_get_options (port, &baud, &parity, &bits);
610
611 return uart_set_options (port, co, baud, parity, bits, flow);
612}
613
614static struct uart_driver lh7a40x_reg;
615static struct console lh7a40x_console = {
616 .name = "ttyAM",
617 .write = lh7a40xuart_console_write,
618 .device = uart_console_device,
619 .setup = lh7a40xuart_console_setup,
620 .flags = CON_PRINTBUFFER,
621 .index = -1,
622 .data = &lh7a40x_reg,
623};
624
625static int __init lh7a40xuart_console_init(void)
626{
627 register_console (&lh7a40x_console);
628 return 0;
629}
630
631console_initcall (lh7a40xuart_console_init);
632
633#endif
634
635static struct uart_driver lh7a40x_reg = {
636 .owner = THIS_MODULE,
637 .driver_name = "ttyAM",
638 .dev_name = "ttyAM",
639 .major = DEV_MAJOR,
640 .minor = DEV_MINOR,
641 .nr = DEV_NR,
642 .cons = LH7A40X_CONSOLE,
643};
644
645static int __init lh7a40xuart_init(void)
646{
647 int ret;
648
649 printk (KERN_INFO "serial: LH7A40X serial driver\n");
650
651 ret = uart_register_driver (&lh7a40x_reg);
652
653 if (ret == 0) {
654 int i;
655
656 for (i = 0; i < DEV_NR; i++) {
657 /* UART3, when used, requires GPIO pin reallocation */
658 if (lh7a40x_ports[i].port.mapbase == UART3_PHYS)
659 GPIO_PINMUX |= 1<<3;
660 uart_add_one_port (&lh7a40x_reg,
661 &lh7a40x_ports[i].port);
662 }
663 }
664 return ret;
665}
666
667static void __exit lh7a40xuart_exit(void)
668{
669 int i;
670
671 for (i = 0; i < DEV_NR; i++)
672 uart_remove_one_port (&lh7a40x_reg, &lh7a40x_ports[i].port);
673
674 uart_unregister_driver (&lh7a40x_reg);
675}
676
677module_init (lh7a40xuart_init);
678module_exit (lh7a40xuart_exit);
679
680MODULE_AUTHOR ("Marc Singer");
681MODULE_DESCRIPTION ("Sharp LH7A40X serial port driver");
682MODULE_LICENSE ("GPL");
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig
index fceea5e4e02f..41b6e51188e4 100644
--- a/drivers/usb/Kconfig
+++ b/drivers/usb/Kconfig
@@ -31,7 +31,6 @@ config USB_ARCH_HAS_OHCI
31 # ARM: 31 # ARM:
32 default y if SA1111 32 default y if SA1111
33 default y if ARCH_OMAP 33 default y if ARCH_OMAP
34 default y if ARCH_LH7A404
35 default y if ARCH_S3C2410 34 default y if ARCH_S3C2410
36 default y if PXA27x 35 default y if PXA27x
37 default y if PXA3xx 36 default y if PXA3xx
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index 1dc9739277b4..08a48ae23745 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -176,18 +176,6 @@ config USB_FSL_USB2
176 default USB_GADGET 176 default USB_GADGET
177 select USB_GADGET_SELECTED 177 select USB_GADGET_SELECTED
178 178
179config USB_GADGET_LH7A40X
180 boolean "LH7A40X"
181 depends on ARCH_LH7A40X
182 help
183 This driver provides USB Device Controller driver for LH7A40x
184
185config USB_LH7A40X
186 tristate
187 depends on USB_GADGET_LH7A40X
188 default USB_GADGET
189 select USB_GADGET_SELECTED
190
191config USB_GADGET_OMAP 179config USB_GADGET_OMAP
192 boolean "OMAP USB Device Controller" 180 boolean "OMAP USB Device Controller"
193 depends on ARCH_OMAP 181 depends on ARCH_OMAP
diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
index 55f5e8ae5924..a2f7f9a4f4a8 100644
--- a/drivers/usb/gadget/Makefile
+++ b/drivers/usb/gadget/Makefile
@@ -11,7 +11,6 @@ obj-$(CONFIG_USB_PXA27X) += pxa27x_udc.o
11obj-$(CONFIG_USB_IMX) += imx_udc.o 11obj-$(CONFIG_USB_IMX) += imx_udc.o
12obj-$(CONFIG_USB_GOKU) += goku_udc.o 12obj-$(CONFIG_USB_GOKU) += goku_udc.o
13obj-$(CONFIG_USB_OMAP) += omap_udc.o 13obj-$(CONFIG_USB_OMAP) += omap_udc.o
14obj-$(CONFIG_USB_LH7A40X) += lh7a40x_udc.o
15obj-$(CONFIG_USB_S3C2410) += s3c2410_udc.o 14obj-$(CONFIG_USB_S3C2410) += s3c2410_udc.o
16obj-$(CONFIG_USB_AT91) += at91_udc.o 15obj-$(CONFIG_USB_AT91) += at91_udc.o
17obj-$(CONFIG_USB_ATMEL_USBA) += atmel_usba_udc.o 16obj-$(CONFIG_USB_ATMEL_USBA) += atmel_usba_udc.o
diff --git a/drivers/usb/gadget/gadget_chips.h b/drivers/usb/gadget/gadget_chips.h
index 5c2720d64ffa..e896f6359dfe 100644
--- a/drivers/usb/gadget/gadget_chips.h
+++ b/drivers/usb/gadget/gadget_chips.h
@@ -45,12 +45,6 @@
45#define gadget_is_goku(g) 0 45#define gadget_is_goku(g) 0
46#endif 46#endif
47 47
48#ifdef CONFIG_USB_GADGET_LH7A40X
49#define gadget_is_lh7a40x(g) !strcmp("lh7a40x_udc", (g)->name)
50#else
51#define gadget_is_lh7a40x(g) 0
52#endif
53
54#ifdef CONFIG_USB_GADGET_OMAP 48#ifdef CONFIG_USB_GADGET_OMAP
55#define gadget_is_omap(g) !strcmp("omap_udc", (g)->name) 49#define gadget_is_omap(g) !strcmp("omap_udc", (g)->name)
56#else 50#else
@@ -181,8 +175,6 @@ static inline int usb_gadget_controller_number(struct usb_gadget *gadget)
181 return 0x06; 175 return 0x06;
182 else if (gadget_is_omap(gadget)) 176 else if (gadget_is_omap(gadget))
183 return 0x08; 177 return 0x08;
184 else if (gadget_is_lh7a40x(gadget))
185 return 0x09;
186 else if (gadget_is_pxa27x(gadget)) 178 else if (gadget_is_pxa27x(gadget))
187 return 0x11; 179 return 0x11;
188 else if (gadget_is_s3c2410(gadget)) 180 else if (gadget_is_s3c2410(gadget))
diff --git a/drivers/usb/gadget/lh7a40x_udc.c b/drivers/usb/gadget/lh7a40x_udc.c
deleted file mode 100644
index 6b58bd8ce623..000000000000
--- a/drivers/usb/gadget/lh7a40x_udc.c
+++ /dev/null
@@ -1,2152 +0,0 @@
1/*
2 * linux/drivers/usb/gadget/lh7a40x_udc.c
3 * Sharp LH7A40x on-chip full speed USB device controllers
4 *
5 * Copyright (C) 2004 Mikko Lahteenmaki, Nordic ID
6 * Copyright (C) 2004 Bo Henriksen, Nordic ID
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22 */
23
24#include <linux/platform_device.h>
25#include <linux/slab.h>
26
27#include "lh7a40x_udc.h"
28
29//#define DEBUG printk
30//#define DEBUG_EP0 printk
31//#define DEBUG_SETUP printk
32
33#ifndef DEBUG_EP0
34# define DEBUG_EP0(fmt,args...)
35#endif
36#ifndef DEBUG_SETUP
37# define DEBUG_SETUP(fmt,args...)
38#endif
39#ifndef DEBUG
40# define NO_STATES
41# define DEBUG(fmt,args...)
42#endif
43
44#define DRIVER_DESC "LH7A40x USB Device Controller"
45#define DRIVER_VERSION __DATE__
46
47#ifndef _BIT /* FIXME - what happended to _BIT in 2.6.7bk18? */
48#define _BIT(x) (1<<(x))
49#endif
50
51struct lh7a40x_udc *the_controller;
52
53static const char driver_name[] = "lh7a40x_udc";
54static const char driver_desc[] = DRIVER_DESC;
55static const char ep0name[] = "ep0-control";
56
57/*
58 Local definintions.
59*/
60
61#ifndef NO_STATES
62static char *state_names[] = {
63 "WAIT_FOR_SETUP",
64 "DATA_STATE_XMIT",
65 "DATA_STATE_NEED_ZLP",
66 "WAIT_FOR_OUT_STATUS",
67 "DATA_STATE_RECV"
68};
69#endif
70
71/*
72 Local declarations.
73*/
74static int lh7a40x_ep_enable(struct usb_ep *ep,
75 const struct usb_endpoint_descriptor *);
76static int lh7a40x_ep_disable(struct usb_ep *ep);
77static struct usb_request *lh7a40x_alloc_request(struct usb_ep *ep, gfp_t);
78static void lh7a40x_free_request(struct usb_ep *ep, struct usb_request *);
79static int lh7a40x_queue(struct usb_ep *ep, struct usb_request *, gfp_t);
80static int lh7a40x_dequeue(struct usb_ep *ep, struct usb_request *);
81static int lh7a40x_set_halt(struct usb_ep *ep, int);
82static int lh7a40x_fifo_status(struct usb_ep *ep);
83static void lh7a40x_fifo_flush(struct usb_ep *ep);
84static void lh7a40x_ep0_kick(struct lh7a40x_udc *dev, struct lh7a40x_ep *ep);
85static void lh7a40x_handle_ep0(struct lh7a40x_udc *dev, u32 intr);
86
87static void done(struct lh7a40x_ep *ep, struct lh7a40x_request *req,
88 int status);
89static void pio_irq_enable(int bEndpointAddress);
90static void pio_irq_disable(int bEndpointAddress);
91static void stop_activity(struct lh7a40x_udc *dev,
92 struct usb_gadget_driver *driver);
93static void flush(struct lh7a40x_ep *ep);
94static void udc_enable(struct lh7a40x_udc *dev);
95static void udc_set_address(struct lh7a40x_udc *dev, unsigned char address);
96
97static struct usb_ep_ops lh7a40x_ep_ops = {
98 .enable = lh7a40x_ep_enable,
99 .disable = lh7a40x_ep_disable,
100
101 .alloc_request = lh7a40x_alloc_request,
102 .free_request = lh7a40x_free_request,
103
104 .queue = lh7a40x_queue,
105 .dequeue = lh7a40x_dequeue,
106
107 .set_halt = lh7a40x_set_halt,
108 .fifo_status = lh7a40x_fifo_status,
109 .fifo_flush = lh7a40x_fifo_flush,
110};
111
112/* Inline code */
113
114static __inline__ int write_packet(struct lh7a40x_ep *ep,
115 struct lh7a40x_request *req, int max)
116{
117 u8 *buf;
118 int length, count;
119 volatile u32 *fifo = (volatile u32 *)ep->fifo;
120
121 buf = req->req.buf + req->req.actual;
122 prefetch(buf);
123
124 length = req->req.length - req->req.actual;
125 length = min(length, max);
126 req->req.actual += length;
127
128 DEBUG("Write %d (max %d), fifo %p\n", length, max, fifo);
129
130 count = length;
131 while (count--) {
132 *fifo = *buf++;
133 }
134
135 return length;
136}
137
138static __inline__ void usb_set_index(u32 ep)
139{
140 *(volatile u32 *)io_p2v(USB_INDEX) = ep;
141}
142
143static __inline__ u32 usb_read(u32 port)
144{
145 return *(volatile u32 *)io_p2v(port);
146}
147
148static __inline__ void usb_write(u32 val, u32 port)
149{
150 *(volatile u32 *)io_p2v(port) = val;
151}
152
153static __inline__ void usb_set(u32 val, u32 port)
154{
155 volatile u32 *ioport = (volatile u32 *)io_p2v(port);
156 u32 after = (*ioport) | val;
157 *ioport = after;
158}
159
160static __inline__ void usb_clear(u32 val, u32 port)
161{
162 volatile u32 *ioport = (volatile u32 *)io_p2v(port);
163 u32 after = (*ioport) & ~val;
164 *ioport = after;
165}
166
167/*-------------------------------------------------------------------------*/
168
169#define GPIO_PORTC_DR (0x80000E08)
170#define GPIO_PORTC_DDR (0x80000E18)
171#define GPIO_PORTC_PDR (0x80000E70)
172
173/* get port C pin data register */
174#define get_portc_pdr(bit) ((usb_read(GPIO_PORTC_PDR) & _BIT(bit)) != 0)
175/* get port C data direction register */
176#define get_portc_ddr(bit) ((usb_read(GPIO_PORTC_DDR) & _BIT(bit)) != 0)
177/* set port C data register */
178#define set_portc_dr(bit, val) (val ? usb_set(_BIT(bit), GPIO_PORTC_DR) : usb_clear(_BIT(bit), GPIO_PORTC_DR))
179/* set port C data direction register */
180#define set_portc_ddr(bit, val) (val ? usb_set(_BIT(bit), GPIO_PORTC_DDR) : usb_clear(_BIT(bit), GPIO_PORTC_DDR))
181
182/*
183 * LPD7A404 GPIO's:
184 * Port C bit 1 = USB Port 1 Power Enable
185 * Port C bit 2 = USB Port 1 Data Carrier Detect
186 */
187#define is_usb_connected() get_portc_pdr(2)
188
189#ifdef CONFIG_USB_GADGET_DEBUG_FILES
190
191static const char proc_node_name[] = "driver/udc";
192
193static int
194udc_proc_read(char *page, char **start, off_t off, int count,
195 int *eof, void *_dev)
196{
197 char *buf = page;
198 struct lh7a40x_udc *dev = _dev;
199 char *next = buf;
200 unsigned size = count;
201 unsigned long flags;
202 int t;
203
204 if (off != 0)
205 return 0;
206
207 local_irq_save(flags);
208
209 /* basic device status */
210 t = scnprintf(next, size,
211 DRIVER_DESC "\n"
212 "%s version: %s\n"
213 "Gadget driver: %s\n"
214 "Host: %s\n\n",
215 driver_name, DRIVER_VERSION,
216 dev->driver ? dev->driver->driver.name : "(none)",
217 is_usb_connected()? "full speed" : "disconnected");
218 size -= t;
219 next += t;
220
221 t = scnprintf(next, size,
222 "GPIO:\n"
223 " Port C bit 1: %d, dir %d\n"
224 " Port C bit 2: %d, dir %d\n\n",
225 get_portc_pdr(1), get_portc_ddr(1),
226 get_portc_pdr(2), get_portc_ddr(2)
227 );
228 size -= t;
229 next += t;
230
231 t = scnprintf(next, size,
232 "DCP pullup: %d\n\n",
233 (usb_read(USB_PM) & PM_USB_DCP) != 0);
234 size -= t;
235 next += t;
236
237 local_irq_restore(flags);
238 *eof = 1;
239 return count - size;
240}
241
242#define create_proc_files() create_proc_read_entry(proc_node_name, 0, NULL, udc_proc_read, dev)
243#define remove_proc_files() remove_proc_entry(proc_node_name, NULL)
244
245#else /* !CONFIG_USB_GADGET_DEBUG_FILES */
246
247#define create_proc_files() do {} while (0)
248#define remove_proc_files() do {} while (0)
249
250#endif /* CONFIG_USB_GADGET_DEBUG_FILES */
251
252/*
253 * udc_disable - disable USB device controller
254 */
255static void udc_disable(struct lh7a40x_udc *dev)
256{
257 DEBUG("%s, %p\n", __func__, dev);
258
259 udc_set_address(dev, 0);
260
261 /* Disable interrupts */
262 usb_write(0, USB_IN_INT_EN);
263 usb_write(0, USB_OUT_INT_EN);
264 usb_write(0, USB_INT_EN);
265
266 /* Disable the USB */
267 usb_write(0, USB_PM);
268
269#ifdef CONFIG_ARCH_LH7A404
270 /* Disable USB power */
271 set_portc_dr(1, 0);
272#endif
273
274 /* if hardware supports it, disconnect from usb */
275 /* make_usb_disappear(); */
276
277 dev->ep0state = WAIT_FOR_SETUP;
278 dev->gadget.speed = USB_SPEED_UNKNOWN;
279 dev->usb_address = 0;
280}
281
282/*
283 * udc_reinit - initialize software state
284 */
285static void udc_reinit(struct lh7a40x_udc *dev)
286{
287 u32 i;
288
289 DEBUG("%s, %p\n", __func__, dev);
290
291 /* device/ep0 records init */
292 INIT_LIST_HEAD(&dev->gadget.ep_list);
293 INIT_LIST_HEAD(&dev->gadget.ep0->ep_list);
294 dev->ep0state = WAIT_FOR_SETUP;
295
296 /* basic endpoint records init */
297 for (i = 0; i < UDC_MAX_ENDPOINTS; i++) {
298 struct lh7a40x_ep *ep = &dev->ep[i];
299
300 if (i != 0)
301 list_add_tail(&ep->ep.ep_list, &dev->gadget.ep_list);
302
303 ep->desc = 0;
304 ep->stopped = 0;
305 INIT_LIST_HEAD(&ep->queue);
306 ep->pio_irqs = 0;
307 }
308
309 /* the rest was statically initialized, and is read-only */
310}
311
312#define BYTES2MAXP(x) (x / 8)
313#define MAXP2BYTES(x) (x * 8)
314
315/* until it's enabled, this UDC should be completely invisible
316 * to any USB host.
317 */
318static void udc_enable(struct lh7a40x_udc *dev)
319{
320 int ep;
321
322 DEBUG("%s, %p\n", __func__, dev);
323
324 dev->gadget.speed = USB_SPEED_UNKNOWN;
325
326#ifdef CONFIG_ARCH_LH7A404
327 /* Set Port C bit 1 & 2 as output */
328 set_portc_ddr(1, 1);
329 set_portc_ddr(2, 1);
330
331 /* Enable USB power */
332 set_portc_dr(1, 0);
333#endif
334
335 /*
336 * C.f Chapter 18.1.3.1 Initializing the USB
337 */
338
339 /* Disable the USB */
340 usb_clear(PM_USB_ENABLE, USB_PM);
341
342 /* Reset APB & I/O sides of the USB */
343 usb_set(USB_RESET_APB | USB_RESET_IO, USB_RESET);
344 mdelay(5);
345 usb_clear(USB_RESET_APB | USB_RESET_IO, USB_RESET);
346
347 /* Set MAXP values for each */
348 for (ep = 0; ep < UDC_MAX_ENDPOINTS; ep++) {
349 struct lh7a40x_ep *ep_reg = &dev->ep[ep];
350 u32 csr;
351
352 usb_set_index(ep);
353
354 switch (ep_reg->ep_type) {
355 case ep_bulk_in:
356 case ep_interrupt:
357 usb_clear(USB_IN_CSR2_USB_DMA_EN | USB_IN_CSR2_AUTO_SET,
358 ep_reg->csr2);
359 /* Fall through */
360 case ep_control:
361 usb_write(BYTES2MAXP(ep_maxpacket(ep_reg)),
362 USB_IN_MAXP);
363 break;
364 case ep_bulk_out:
365 usb_clear(USB_OUT_CSR2_USB_DMA_EN |
366 USB_OUT_CSR2_AUTO_CLR, ep_reg->csr2);
367 usb_write(BYTES2MAXP(ep_maxpacket(ep_reg)),
368 USB_OUT_MAXP);
369 break;
370 }
371
372 /* Read & Write CSR1, just in case */
373 csr = usb_read(ep_reg->csr1);
374 usb_write(csr, ep_reg->csr1);
375
376 flush(ep_reg);
377 }
378
379 /* Disable interrupts */
380 usb_write(0, USB_IN_INT_EN);
381 usb_write(0, USB_OUT_INT_EN);
382 usb_write(0, USB_INT_EN);
383
384 /* Enable interrupts */
385 usb_set(USB_IN_INT_EP0, USB_IN_INT_EN);
386 usb_set(USB_INT_RESET_INT | USB_INT_RESUME_INT, USB_INT_EN);
387 /* Dont enable rest of the interrupts */
388 /* usb_set(USB_IN_INT_EP3 | USB_IN_INT_EP1 | USB_IN_INT_EP0, USB_IN_INT_EN);
389 usb_set(USB_OUT_INT_EP2, USB_OUT_INT_EN); */
390
391 /* Enable SUSPEND */
392 usb_set(PM_ENABLE_SUSPEND, USB_PM);
393
394 /* Enable the USB */
395 usb_set(PM_USB_ENABLE, USB_PM);
396
397#ifdef CONFIG_ARCH_LH7A404
398 /* NOTE: DOES NOT WORK! */
399 /* Let host detect UDC:
400 * Software must write a 0 to the PMR:DCP_CTRL bit to turn this
401 * transistor on and pull the USBDP pin HIGH.
402 */
403 /* usb_clear(PM_USB_DCP, USB_PM);
404 usb_set(PM_USB_DCP, USB_PM); */
405#endif
406}
407
408/*
409 Register entry point for the peripheral controller driver.
410*/
411int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
412 int (*bind)(struct usb_gadget *))
413{
414 struct lh7a40x_udc *dev = the_controller;
415 int retval;
416
417 DEBUG("%s: %s\n", __func__, driver->driver.name);
418
419 if (!driver
420 || driver->speed != USB_SPEED_FULL
421 || !bind
422 || !driver->disconnect
423 || !driver->setup)
424 return -EINVAL;
425 if (!dev)
426 return -ENODEV;
427 if (dev->driver)
428 return -EBUSY;
429
430 /* first hook up the driver ... */
431 dev->driver = driver;
432 dev->gadget.dev.driver = &driver->driver;
433
434 device_add(&dev->gadget.dev);
435 retval = bind(&dev->gadget);
436 if (retval) {
437 printk(KERN_WARNING "%s: bind to driver %s --> error %d\n",
438 dev->gadget.name, driver->driver.name, retval);
439 device_del(&dev->gadget.dev);
440
441 dev->driver = 0;
442 dev->gadget.dev.driver = 0;
443 return retval;
444 }
445
446 /* ... then enable host detection and ep0; and we're ready
447 * for set_configuration as well as eventual disconnect.
448 * NOTE: this shouldn't power up until later.
449 */
450 printk(KERN_WARNING "%s: registered gadget driver '%s'\n",
451 dev->gadget.name, driver->driver.name);
452
453 udc_enable(dev);
454
455 return 0;
456}
457EXPORT_SYMBOL(usb_gadget_probe_driver);
458
459/*
460 Unregister entry point for the peripheral controller driver.
461*/
462int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
463{
464 struct lh7a40x_udc *dev = the_controller;
465 unsigned long flags;
466
467 if (!dev)
468 return -ENODEV;
469 if (!driver || driver != dev->driver || !driver->unbind)
470 return -EINVAL;
471
472 spin_lock_irqsave(&dev->lock, flags);
473 dev->driver = 0;
474 stop_activity(dev, driver);
475 spin_unlock_irqrestore(&dev->lock, flags);
476
477 driver->unbind(&dev->gadget);
478 dev->gadget.dev.driver = NULL;
479 device_del(&dev->gadget.dev);
480
481 udc_disable(dev);
482
483 DEBUG("unregistered gadget driver '%s'\n", driver->driver.name);
484 return 0;
485}
486
487EXPORT_SYMBOL(usb_gadget_unregister_driver);
488
489/*-------------------------------------------------------------------------*/
490
491/** Write request to FIFO (max write == maxp size)
492 * Return: 0 = still running, 1 = completed, negative = errno
493 * NOTE: INDEX register must be set for EP
494 */
495static int write_fifo(struct lh7a40x_ep *ep, struct lh7a40x_request *req)
496{
497 u32 max;
498 u32 csr;
499
500 max = le16_to_cpu(ep->desc->wMaxPacketSize);
501
502 csr = usb_read(ep->csr1);
503 DEBUG("CSR: %x %d\n", csr, csr & USB_IN_CSR1_FIFO_NOT_EMPTY);
504
505 if (!(csr & USB_IN_CSR1_FIFO_NOT_EMPTY)) {
506 unsigned count;
507 int is_last, is_short;
508
509 count = write_packet(ep, req, max);
510 usb_set(USB_IN_CSR1_IN_PKT_RDY, ep->csr1);
511
512 /* last packet is usually short (or a zlp) */
513 if (unlikely(count != max))
514 is_last = is_short = 1;
515 else {
516 if (likely(req->req.length != req->req.actual)
517 || req->req.zero)
518 is_last = 0;
519 else
520 is_last = 1;
521 /* interrupt/iso maxpacket may not fill the fifo */
522 is_short = unlikely(max < ep_maxpacket(ep));
523 }
524
525 DEBUG("%s: wrote %s %d bytes%s%s %d left %p\n", __func__,
526 ep->ep.name, count,
527 is_last ? "/L" : "", is_short ? "/S" : "",
528 req->req.length - req->req.actual, req);
529
530 /* requests complete when all IN data is in the FIFO */
531 if (is_last) {
532 done(ep, req, 0);
533 if (list_empty(&ep->queue)) {
534 pio_irq_disable(ep_index(ep));
535 }
536 return 1;
537 }
538 } else {
539 DEBUG("Hmm.. %d ep FIFO is not empty!\n", ep_index(ep));
540 }
541
542 return 0;
543}
544
545/** Read to request from FIFO (max read == bytes in fifo)
546 * Return: 0 = still running, 1 = completed, negative = errno
547 * NOTE: INDEX register must be set for EP
548 */
549static int read_fifo(struct lh7a40x_ep *ep, struct lh7a40x_request *req)
550{
551 u32 csr;
552 u8 *buf;
553 unsigned bufferspace, count, is_short;
554 volatile u32 *fifo = (volatile u32 *)ep->fifo;
555
556 /* make sure there's a packet in the FIFO. */
557 csr = usb_read(ep->csr1);
558 if (!(csr & USB_OUT_CSR1_OUT_PKT_RDY)) {
559 DEBUG("%s: Packet NOT ready!\n", __func__);
560 return -EINVAL;
561 }
562
563 buf = req->req.buf + req->req.actual;
564 prefetchw(buf);
565 bufferspace = req->req.length - req->req.actual;
566
567 /* read all bytes from this packet */
568 count = usb_read(USB_OUT_FIFO_WC1);
569 req->req.actual += min(count, bufferspace);
570
571 is_short = (count < ep->ep.maxpacket);
572 DEBUG("read %s %02x, %d bytes%s req %p %d/%d\n",
573 ep->ep.name, csr, count,
574 is_short ? "/S" : "", req, req->req.actual, req->req.length);
575
576 while (likely(count-- != 0)) {
577 u8 byte = (u8) (*fifo & 0xff);
578
579 if (unlikely(bufferspace == 0)) {
580 /* this happens when the driver's buffer
581 * is smaller than what the host sent.
582 * discard the extra data.
583 */
584 if (req->req.status != -EOVERFLOW)
585 printk(KERN_WARNING "%s overflow %d\n",
586 ep->ep.name, count);
587 req->req.status = -EOVERFLOW;
588 } else {
589 *buf++ = byte;
590 bufferspace--;
591 }
592 }
593
594 usb_clear(USB_OUT_CSR1_OUT_PKT_RDY, ep->csr1);
595
596 /* completion */
597 if (is_short || req->req.actual == req->req.length) {
598 done(ep, req, 0);
599 usb_set(USB_OUT_CSR1_FIFO_FLUSH, ep->csr1);
600
601 if (list_empty(&ep->queue))
602 pio_irq_disable(ep_index(ep));
603 return 1;
604 }
605
606 /* finished that packet. the next one may be waiting... */
607 return 0;
608}
609
610/*
611 * done - retire a request; caller blocked irqs
612 * INDEX register is preserved to keep same
613 */
614static void done(struct lh7a40x_ep *ep, struct lh7a40x_request *req, int status)
615{
616 unsigned int stopped = ep->stopped;
617 u32 index;
618
619 DEBUG("%s, %p\n", __func__, ep);
620 list_del_init(&req->queue);
621
622 if (likely(req->req.status == -EINPROGRESS))
623 req->req.status = status;
624 else
625 status = req->req.status;
626
627 if (status && status != -ESHUTDOWN)
628 DEBUG("complete %s req %p stat %d len %u/%u\n",
629 ep->ep.name, &req->req, status,
630 req->req.actual, req->req.length);
631
632 /* don't modify queue heads during completion callback */
633 ep->stopped = 1;
634 /* Read current index (completion may modify it) */
635 index = usb_read(USB_INDEX);
636
637 spin_unlock(&ep->dev->lock);
638 req->req.complete(&ep->ep, &req->req);
639 spin_lock(&ep->dev->lock);
640
641 /* Restore index */
642 usb_set_index(index);
643 ep->stopped = stopped;
644}
645
646/** Enable EP interrupt */
647static void pio_irq_enable(int ep)
648{
649 DEBUG("%s: %d\n", __func__, ep);
650
651 switch (ep) {
652 case 1:
653 usb_set(USB_IN_INT_EP1, USB_IN_INT_EN);
654 break;
655 case 2:
656 usb_set(USB_OUT_INT_EP2, USB_OUT_INT_EN);
657 break;
658 case 3:
659 usb_set(USB_IN_INT_EP3, USB_IN_INT_EN);
660 break;
661 default:
662 DEBUG("Unknown endpoint: %d\n", ep);
663 break;
664 }
665}
666
667/** Disable EP interrupt */
668static void pio_irq_disable(int ep)
669{
670 DEBUG("%s: %d\n", __func__, ep);
671
672 switch (ep) {
673 case 1:
674 usb_clear(USB_IN_INT_EP1, USB_IN_INT_EN);
675 break;
676 case 2:
677 usb_clear(USB_OUT_INT_EP2, USB_OUT_INT_EN);
678 break;
679 case 3:
680 usb_clear(USB_IN_INT_EP3, USB_IN_INT_EN);
681 break;
682 default:
683 DEBUG("Unknown endpoint: %d\n", ep);
684 break;
685 }
686}
687
688/*
689 * nuke - dequeue ALL requests
690 */
691void nuke(struct lh7a40x_ep *ep, int status)
692{
693 struct lh7a40x_request *req;
694
695 DEBUG("%s, %p\n", __func__, ep);
696
697 /* Flush FIFO */
698 flush(ep);
699
700 /* called with irqs blocked */
701 while (!list_empty(&ep->queue)) {
702 req = list_entry(ep->queue.next, struct lh7a40x_request, queue);
703 done(ep, req, status);
704 }
705
706 /* Disable IRQ if EP is enabled (has descriptor) */
707 if (ep->desc)
708 pio_irq_disable(ep_index(ep));
709}
710
711/*
712void nuke_all(struct lh7a40x_udc *dev)
713{
714 int n;
715 for(n=0; n<UDC_MAX_ENDPOINTS; n++) {
716 struct lh7a40x_ep *ep = &dev->ep[n];
717 usb_set_index(n);
718 nuke(ep, 0);
719 }
720}*/
721
722/*
723static void flush_all(struct lh7a40x_udc *dev)
724{
725 int n;
726 for (n = 0; n < UDC_MAX_ENDPOINTS; n++)
727 {
728 struct lh7a40x_ep *ep = &dev->ep[n];
729 flush(ep);
730 }
731}
732*/
733
734/** Flush EP
735 * NOTE: INDEX register must be set before this call
736 */
737static void flush(struct lh7a40x_ep *ep)
738{
739 DEBUG("%s, %p\n", __func__, ep);
740
741 switch (ep->ep_type) {
742 case ep_control:
743 /* check, by implication c.f. 15.1.2.11 */
744 break;
745
746 case ep_bulk_in:
747 case ep_interrupt:
748 /* if(csr & USB_IN_CSR1_IN_PKT_RDY) */
749 usb_set(USB_IN_CSR1_FIFO_FLUSH, ep->csr1);
750 break;
751
752 case ep_bulk_out:
753 /* if(csr & USB_OUT_CSR1_OUT_PKT_RDY) */
754 usb_set(USB_OUT_CSR1_FIFO_FLUSH, ep->csr1);
755 break;
756 }
757}
758
759/**
760 * lh7a40x_in_epn - handle IN interrupt
761 */
762static void lh7a40x_in_epn(struct lh7a40x_udc *dev, u32 ep_idx, u32 intr)
763{
764 u32 csr;
765 struct lh7a40x_ep *ep = &dev->ep[ep_idx];
766 struct lh7a40x_request *req;
767
768 usb_set_index(ep_idx);
769
770 csr = usb_read(ep->csr1);
771 DEBUG("%s: %d, csr %x\n", __func__, ep_idx, csr);
772
773 if (csr & USB_IN_CSR1_SENT_STALL) {
774 DEBUG("USB_IN_CSR1_SENT_STALL\n");
775 usb_set(USB_IN_CSR1_SENT_STALL /*|USB_IN_CSR1_SEND_STALL */ ,
776 ep->csr1);
777 return;
778 }
779
780 if (!ep->desc) {
781 DEBUG("%s: NO EP DESC\n", __func__);
782 return;
783 }
784
785 if (list_empty(&ep->queue))
786 req = 0;
787 else
788 req = list_entry(ep->queue.next, struct lh7a40x_request, queue);
789
790 DEBUG("req: %p\n", req);
791
792 if (!req)
793 return;
794
795 write_fifo(ep, req);
796}
797
798/* ********************************************************************************************* */
799/* Bulk OUT (recv)
800 */
801
802static void lh7a40x_out_epn(struct lh7a40x_udc *dev, u32 ep_idx, u32 intr)
803{
804 struct lh7a40x_ep *ep = &dev->ep[ep_idx];
805 struct lh7a40x_request *req;
806
807 DEBUG("%s: %d\n", __func__, ep_idx);
808
809 usb_set_index(ep_idx);
810
811 if (ep->desc) {
812 u32 csr;
813 csr = usb_read(ep->csr1);
814
815 while ((csr =
816 usb_read(ep->
817 csr1)) & (USB_OUT_CSR1_OUT_PKT_RDY |
818 USB_OUT_CSR1_SENT_STALL)) {
819 DEBUG("%s: %x\n", __func__, csr);
820
821 if (csr & USB_OUT_CSR1_SENT_STALL) {
822 DEBUG("%s: stall sent, flush fifo\n",
823 __func__);
824 /* usb_set(USB_OUT_CSR1_FIFO_FLUSH, ep->csr1); */
825 flush(ep);
826 } else if (csr & USB_OUT_CSR1_OUT_PKT_RDY) {
827 if (list_empty(&ep->queue))
828 req = 0;
829 else
830 req =
831 list_entry(ep->queue.next,
832 struct lh7a40x_request,
833 queue);
834
835 if (!req) {
836 printk(KERN_WARNING
837 "%s: NULL REQ %d\n",
838 __func__, ep_idx);
839 flush(ep);
840 break;
841 } else {
842 read_fifo(ep, req);
843 }
844 }
845
846 }
847
848 } else {
849 /* Throw packet away.. */
850 printk(KERN_WARNING "%s: No descriptor?!?\n", __func__);
851 flush(ep);
852 }
853}
854
855static void stop_activity(struct lh7a40x_udc *dev,
856 struct usb_gadget_driver *driver)
857{
858 int i;
859
860 /* don't disconnect drivers more than once */
861 if (dev->gadget.speed == USB_SPEED_UNKNOWN)
862 driver = 0;
863 dev->gadget.speed = USB_SPEED_UNKNOWN;
864
865 /* prevent new request submissions, kill any outstanding requests */
866 for (i = 0; i < UDC_MAX_ENDPOINTS; i++) {
867 struct lh7a40x_ep *ep = &dev->ep[i];
868 ep->stopped = 1;
869
870 usb_set_index(i);
871 nuke(ep, -ESHUTDOWN);
872 }
873
874 /* report disconnect; the driver is already quiesced */
875 if (driver) {
876 spin_unlock(&dev->lock);
877 driver->disconnect(&dev->gadget);
878 spin_lock(&dev->lock);
879 }
880
881 /* re-init driver-visible data structures */
882 udc_reinit(dev);
883}
884
885/** Handle USB RESET interrupt
886 */
887static void lh7a40x_reset_intr(struct lh7a40x_udc *dev)
888{
889#if 0 /* def CONFIG_ARCH_LH7A404 */
890 /* Does not work always... */
891
892 DEBUG("%s: %d\n", __func__, dev->usb_address);
893
894 if (!dev->usb_address) {
895 /*usb_set(USB_RESET_IO, USB_RESET);
896 mdelay(5);
897 usb_clear(USB_RESET_IO, USB_RESET); */
898 return;
899 }
900 /* Put the USB controller into reset. */
901 usb_set(USB_RESET_IO, USB_RESET);
902
903 /* Set Device ID to 0 */
904 udc_set_address(dev, 0);
905
906 /* Let PLL2 settle down */
907 mdelay(5);
908
909 /* Release the USB controller from reset */
910 usb_clear(USB_RESET_IO, USB_RESET);
911
912 /* Re-enable UDC */
913 udc_enable(dev);
914
915#endif
916 dev->gadget.speed = USB_SPEED_FULL;
917}
918
919/*
920 * lh7a40x usb client interrupt handler.
921 */
922static irqreturn_t lh7a40x_udc_irq(int irq, void *_dev)
923{
924 struct lh7a40x_udc *dev = _dev;
925
926 DEBUG("\n\n");
927
928 spin_lock(&dev->lock);
929
930 for (;;) {
931 u32 intr_in = usb_read(USB_IN_INT);
932 u32 intr_out = usb_read(USB_OUT_INT);
933 u32 intr_int = usb_read(USB_INT);
934
935 /* Test also against enable bits.. (lh7a40x errata).. Sigh.. */
936 u32 in_en = usb_read(USB_IN_INT_EN);
937 u32 out_en = usb_read(USB_OUT_INT_EN);
938
939 if (!intr_out && !intr_in && !intr_int)
940 break;
941
942 DEBUG("%s (on state %s)\n", __func__,
943 state_names[dev->ep0state]);
944 DEBUG("intr_out = %x\n", intr_out);
945 DEBUG("intr_in = %x\n", intr_in);
946 DEBUG("intr_int = %x\n", intr_int);
947
948 if (intr_in) {
949 usb_write(intr_in, USB_IN_INT);
950
951 if ((intr_in & USB_IN_INT_EP1)
952 && (in_en & USB_IN_INT_EP1)) {
953 DEBUG("USB_IN_INT_EP1\n");
954 lh7a40x_in_epn(dev, 1, intr_in);
955 }
956 if ((intr_in & USB_IN_INT_EP3)
957 && (in_en & USB_IN_INT_EP3)) {
958 DEBUG("USB_IN_INT_EP3\n");
959 lh7a40x_in_epn(dev, 3, intr_in);
960 }
961 if (intr_in & USB_IN_INT_EP0) {
962 DEBUG("USB_IN_INT_EP0 (control)\n");
963 lh7a40x_handle_ep0(dev, intr_in);
964 }
965 }
966
967 if (intr_out) {
968 usb_write(intr_out, USB_OUT_INT);
969
970 if ((intr_out & USB_OUT_INT_EP2)
971 && (out_en & USB_OUT_INT_EP2)) {
972 DEBUG("USB_OUT_INT_EP2\n");
973 lh7a40x_out_epn(dev, 2, intr_out);
974 }
975 }
976
977 if (intr_int) {
978 usb_write(intr_int, USB_INT);
979
980 if (intr_int & USB_INT_RESET_INT) {
981 lh7a40x_reset_intr(dev);
982 }
983
984 if (intr_int & USB_INT_RESUME_INT) {
985 DEBUG("USB resume\n");
986
987 if (dev->gadget.speed != USB_SPEED_UNKNOWN
988 && dev->driver
989 && dev->driver->resume
990 && is_usb_connected()) {
991 dev->driver->resume(&dev->gadget);
992 }
993 }
994
995 if (intr_int & USB_INT_SUSPEND_INT) {
996 DEBUG("USB suspend%s\n",
997 is_usb_connected()? "" : "+disconnect");
998 if (!is_usb_connected()) {
999 stop_activity(dev, dev->driver);
1000 } else if (dev->gadget.speed !=
1001 USB_SPEED_UNKNOWN && dev->driver
1002 && dev->driver->suspend) {
1003 dev->driver->suspend(&dev->gadget);
1004 }
1005 }
1006
1007 }
1008 }
1009
1010 spin_unlock(&dev->lock);
1011
1012 return IRQ_HANDLED;
1013}
1014
1015static int lh7a40x_ep_enable(struct usb_ep *_ep,
1016 const struct usb_endpoint_descriptor *desc)
1017{
1018 struct lh7a40x_ep *ep;
1019 struct lh7a40x_udc *dev;
1020 unsigned long flags;
1021
1022 DEBUG("%s, %p\n", __func__, _ep);
1023
1024 ep = container_of(_ep, struct lh7a40x_ep, ep);
1025 if (!_ep || !desc || ep->desc || _ep->name == ep0name
1026 || desc->bDescriptorType != USB_DT_ENDPOINT
1027 || ep->bEndpointAddress != desc->bEndpointAddress
1028 || ep_maxpacket(ep) < le16_to_cpu(desc->wMaxPacketSize)) {
1029 DEBUG("%s, bad ep or descriptor\n", __func__);
1030 return -EINVAL;
1031 }
1032
1033 /* xfer types must match, except that interrupt ~= bulk */
1034 if (ep->bmAttributes != desc->bmAttributes
1035 && ep->bmAttributes != USB_ENDPOINT_XFER_BULK
1036 && desc->bmAttributes != USB_ENDPOINT_XFER_INT) {
1037 DEBUG("%s, %s type mismatch\n", __func__, _ep->name);
1038 return -EINVAL;
1039 }
1040
1041 /* hardware _could_ do smaller, but driver doesn't */
1042 if ((desc->bmAttributes == USB_ENDPOINT_XFER_BULK
1043 && le16_to_cpu(desc->wMaxPacketSize) != ep_maxpacket(ep))
1044 || !desc->wMaxPacketSize) {
1045 DEBUG("%s, bad %s maxpacket\n", __func__, _ep->name);
1046 return -ERANGE;
1047 }
1048
1049 dev = ep->dev;
1050 if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) {
1051 DEBUG("%s, bogus device state\n", __func__);
1052 return -ESHUTDOWN;
1053 }
1054
1055 spin_lock_irqsave(&ep->dev->lock, flags);
1056
1057 ep->stopped = 0;
1058 ep->desc = desc;
1059 ep->pio_irqs = 0;
1060 ep->ep.maxpacket = le16_to_cpu(desc->wMaxPacketSize);
1061
1062 spin_unlock_irqrestore(&ep->dev->lock, flags);
1063
1064 /* Reset halt state (does flush) */
1065 lh7a40x_set_halt(_ep, 0);
1066
1067 DEBUG("%s: enabled %s\n", __func__, _ep->name);
1068 return 0;
1069}
1070
1071/** Disable EP
1072 * NOTE: Sets INDEX register
1073 */
1074static int lh7a40x_ep_disable(struct usb_ep *_ep)
1075{
1076 struct lh7a40x_ep *ep;
1077 unsigned long flags;
1078
1079 DEBUG("%s, %p\n", __func__, _ep);
1080
1081 ep = container_of(_ep, struct lh7a40x_ep, ep);
1082 if (!_ep || !ep->desc) {
1083 DEBUG("%s, %s not enabled\n", __func__,
1084 _ep ? ep->ep.name : NULL);
1085 return -EINVAL;
1086 }
1087
1088 spin_lock_irqsave(&ep->dev->lock, flags);
1089
1090 usb_set_index(ep_index(ep));
1091
1092 /* Nuke all pending requests (does flush) */
1093 nuke(ep, -ESHUTDOWN);
1094
1095 /* Disable ep IRQ */
1096 pio_irq_disable(ep_index(ep));
1097
1098 ep->desc = 0;
1099 ep->stopped = 1;
1100
1101 spin_unlock_irqrestore(&ep->dev->lock, flags);
1102
1103 DEBUG("%s: disabled %s\n", __func__, _ep->name);
1104 return 0;
1105}
1106
1107static struct usb_request *lh7a40x_alloc_request(struct usb_ep *ep,
1108 gfp_t gfp_flags)
1109{
1110 struct lh7a40x_request *req;
1111
1112 DEBUG("%s, %p\n", __func__, ep);
1113
1114 req = kzalloc(sizeof(*req), gfp_flags);
1115 if (!req)
1116 return 0;
1117
1118 INIT_LIST_HEAD(&req->queue);
1119
1120 return &req->req;
1121}
1122
1123static void lh7a40x_free_request(struct usb_ep *ep, struct usb_request *_req)
1124{
1125 struct lh7a40x_request *req;
1126
1127 DEBUG("%s, %p\n", __func__, ep);
1128
1129 req = container_of(_req, struct lh7a40x_request, req);
1130 WARN_ON(!list_empty(&req->queue));
1131 kfree(req);
1132}
1133
1134/** Queue one request
1135 * Kickstart transfer if needed
1136 * NOTE: Sets INDEX register
1137 */
1138static int lh7a40x_queue(struct usb_ep *_ep, struct usb_request *_req,
1139 gfp_t gfp_flags)
1140{
1141 struct lh7a40x_request *req;
1142 struct lh7a40x_ep *ep;
1143 struct lh7a40x_udc *dev;
1144 unsigned long flags;
1145
1146 DEBUG("\n\n\n%s, %p\n", __func__, _ep);
1147
1148 req = container_of(_req, struct lh7a40x_request, req);
1149 if (unlikely
1150 (!_req || !_req->complete || !_req->buf
1151 || !list_empty(&req->queue))) {
1152 DEBUG("%s, bad params\n", __func__);
1153 return -EINVAL;
1154 }
1155
1156 ep = container_of(_ep, struct lh7a40x_ep, ep);
1157 if (unlikely(!_ep || (!ep->desc && ep->ep.name != ep0name))) {
1158 DEBUG("%s, bad ep\n", __func__);
1159 return -EINVAL;
1160 }
1161
1162 dev = ep->dev;
1163 if (unlikely(!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN)) {
1164 DEBUG("%s, bogus device state %p\n", __func__, dev->driver);
1165 return -ESHUTDOWN;
1166 }
1167
1168 DEBUG("%s queue req %p, len %d buf %p\n", _ep->name, _req, _req->length,
1169 _req->buf);
1170
1171 spin_lock_irqsave(&dev->lock, flags);
1172
1173 _req->status = -EINPROGRESS;
1174 _req->actual = 0;
1175
1176 /* kickstart this i/o queue? */
1177 DEBUG("Add to %d Q %d %d\n", ep_index(ep), list_empty(&ep->queue),
1178 ep->stopped);
1179 if (list_empty(&ep->queue) && likely(!ep->stopped)) {
1180 u32 csr;
1181
1182 if (unlikely(ep_index(ep) == 0)) {
1183 /* EP0 */
1184 list_add_tail(&req->queue, &ep->queue);
1185 lh7a40x_ep0_kick(dev, ep);
1186 req = 0;
1187 } else if (ep_is_in(ep)) {
1188 /* EP1 & EP3 */
1189 usb_set_index(ep_index(ep));
1190 csr = usb_read(ep->csr1);
1191 pio_irq_enable(ep_index(ep));
1192 if ((csr & USB_IN_CSR1_FIFO_NOT_EMPTY) == 0) {
1193 if (write_fifo(ep, req) == 1)
1194 req = 0;
1195 }
1196 } else {
1197 /* EP2 */
1198 usb_set_index(ep_index(ep));
1199 csr = usb_read(ep->csr1);
1200 pio_irq_enable(ep_index(ep));
1201 if (!(csr & USB_OUT_CSR1_FIFO_FULL)) {
1202 if (read_fifo(ep, req) == 1)
1203 req = 0;
1204 }
1205 }
1206 }
1207
1208 /* pio or dma irq handler advances the queue. */
1209 if (likely(req != 0))
1210 list_add_tail(&req->queue, &ep->queue);
1211
1212 spin_unlock_irqrestore(&dev->lock, flags);
1213
1214 return 0;
1215}
1216
1217/* dequeue JUST ONE request */
1218static int lh7a40x_dequeue(struct usb_ep *_ep, struct usb_request *_req)
1219{
1220 struct lh7a40x_ep *ep;
1221 struct lh7a40x_request *req;
1222 unsigned long flags;
1223
1224 DEBUG("%s, %p\n", __func__, _ep);
1225
1226 ep = container_of(_ep, struct lh7a40x_ep, ep);
1227 if (!_ep || ep->ep.name == ep0name)
1228 return -EINVAL;
1229
1230 spin_lock_irqsave(&ep->dev->lock, flags);
1231
1232 /* make sure it's actually queued on this endpoint */
1233 list_for_each_entry(req, &ep->queue, queue) {
1234 if (&req->req == _req)
1235 break;
1236 }
1237 if (&req->req != _req) {
1238 spin_unlock_irqrestore(&ep->dev->lock, flags);
1239 return -EINVAL;
1240 }
1241
1242 done(ep, req, -ECONNRESET);
1243
1244 spin_unlock_irqrestore(&ep->dev->lock, flags);
1245 return 0;
1246}
1247
1248/** Halt specific EP
1249 * Return 0 if success
1250 * NOTE: Sets INDEX register to EP !
1251 */
1252static int lh7a40x_set_halt(struct usb_ep *_ep, int value)
1253{
1254 struct lh7a40x_ep *ep;
1255 unsigned long flags;
1256
1257 ep = container_of(_ep, struct lh7a40x_ep, ep);
1258 if (unlikely(!_ep || (!ep->desc && ep->ep.name != ep0name))) {
1259 DEBUG("%s, bad ep\n", __func__);
1260 return -EINVAL;
1261 }
1262
1263 usb_set_index(ep_index(ep));
1264
1265 DEBUG("%s, ep %d, val %d\n", __func__, ep_index(ep), value);
1266
1267 spin_lock_irqsave(&ep->dev->lock, flags);
1268
1269 if (ep_index(ep) == 0) {
1270 /* EP0 */
1271 usb_set(EP0_SEND_STALL, ep->csr1);
1272 } else if (ep_is_in(ep)) {
1273 u32 csr = usb_read(ep->csr1);
1274 if (value && ((csr & USB_IN_CSR1_FIFO_NOT_EMPTY)
1275 || !list_empty(&ep->queue))) {
1276 /*
1277 * Attempts to halt IN endpoints will fail (returning -EAGAIN)
1278 * if any transfer requests are still queued, or if the controller
1279 * FIFO still holds bytes that the host hasn't collected.
1280 */
1281 spin_unlock_irqrestore(&ep->dev->lock, flags);
1282 DEBUG
1283 ("Attempt to halt IN endpoint failed (returning -EAGAIN) %d %d\n",
1284 (csr & USB_IN_CSR1_FIFO_NOT_EMPTY),
1285 !list_empty(&ep->queue));
1286 return -EAGAIN;
1287 }
1288 flush(ep);
1289 if (value)
1290 usb_set(USB_IN_CSR1_SEND_STALL, ep->csr1);
1291 else {
1292 usb_clear(USB_IN_CSR1_SEND_STALL, ep->csr1);
1293 usb_set(USB_IN_CSR1_CLR_DATA_TOGGLE, ep->csr1);
1294 }
1295
1296 } else {
1297
1298 flush(ep);
1299 if (value)
1300 usb_set(USB_OUT_CSR1_SEND_STALL, ep->csr1);
1301 else {
1302 usb_clear(USB_OUT_CSR1_SEND_STALL, ep->csr1);
1303 usb_set(USB_OUT_CSR1_CLR_DATA_REG, ep->csr1);
1304 }
1305 }
1306
1307 if (value) {
1308 ep->stopped = 1;
1309 } else {
1310 ep->stopped = 0;
1311 }
1312
1313 spin_unlock_irqrestore(&ep->dev->lock, flags);
1314
1315 DEBUG("%s %s halted\n", _ep->name, value == 0 ? "NOT" : "IS");
1316
1317 return 0;
1318}
1319
1320/** Return bytes in EP FIFO
1321 * NOTE: Sets INDEX register to EP
1322 */
1323static int lh7a40x_fifo_status(struct usb_ep *_ep)
1324{
1325 u32 csr;
1326 int count = 0;
1327 struct lh7a40x_ep *ep;
1328
1329 ep = container_of(_ep, struct lh7a40x_ep, ep);
1330 if (!_ep) {
1331 DEBUG("%s, bad ep\n", __func__);
1332 return -ENODEV;
1333 }
1334
1335 DEBUG("%s, %d\n", __func__, ep_index(ep));
1336
1337 /* LPD can't report unclaimed bytes from IN fifos */
1338 if (ep_is_in(ep))
1339 return -EOPNOTSUPP;
1340
1341 usb_set_index(ep_index(ep));
1342
1343 csr = usb_read(ep->csr1);
1344 if (ep->dev->gadget.speed != USB_SPEED_UNKNOWN ||
1345 csr & USB_OUT_CSR1_OUT_PKT_RDY) {
1346 count = usb_read(USB_OUT_FIFO_WC1);
1347 }
1348
1349 return count;
1350}
1351
1352/** Flush EP FIFO
1353 * NOTE: Sets INDEX register to EP
1354 */
1355static void lh7a40x_fifo_flush(struct usb_ep *_ep)
1356{
1357 struct lh7a40x_ep *ep;
1358
1359 ep = container_of(_ep, struct lh7a40x_ep, ep);
1360 if (unlikely(!_ep || (!ep->desc && ep->ep.name != ep0name))) {
1361 DEBUG("%s, bad ep\n", __func__);
1362 return;
1363 }
1364
1365 usb_set_index(ep_index(ep));
1366 flush(ep);
1367}
1368
1369/****************************************************************/
1370/* End Point 0 related functions */
1371/****************************************************************/
1372
1373/* return: 0 = still running, 1 = completed, negative = errno */
1374static int write_fifo_ep0(struct lh7a40x_ep *ep, struct lh7a40x_request *req)
1375{
1376 u32 max;
1377 unsigned count;
1378 int is_last;
1379
1380 max = ep_maxpacket(ep);
1381
1382 DEBUG_EP0("%s\n", __func__);
1383
1384 count = write_packet(ep, req, max);
1385
1386 /* last packet is usually short (or a zlp) */
1387 if (unlikely(count != max))
1388 is_last = 1;
1389 else {
1390 if (likely(req->req.length != req->req.actual) || req->req.zero)
1391 is_last = 0;
1392 else
1393 is_last = 1;
1394 }
1395
1396 DEBUG_EP0("%s: wrote %s %d bytes%s %d left %p\n", __func__,
1397 ep->ep.name, count,
1398 is_last ? "/L" : "", req->req.length - req->req.actual, req);
1399
1400 /* requests complete when all IN data is in the FIFO */
1401 if (is_last) {
1402 done(ep, req, 0);
1403 return 1;
1404 }
1405
1406 return 0;
1407}
1408
1409static __inline__ int lh7a40x_fifo_read(struct lh7a40x_ep *ep,
1410 unsigned char *cp, int max)
1411{
1412 int bytes;
1413 int count = usb_read(USB_OUT_FIFO_WC1);
1414 volatile u32 *fifo = (volatile u32 *)ep->fifo;
1415
1416 if (count > max)
1417 count = max;
1418 bytes = count;
1419 while (count--)
1420 *cp++ = *fifo & 0xFF;
1421 return bytes;
1422}
1423
1424static __inline__ void lh7a40x_fifo_write(struct lh7a40x_ep *ep,
1425 unsigned char *cp, int count)
1426{
1427 volatile u32 *fifo = (volatile u32 *)ep->fifo;
1428 DEBUG_EP0("fifo_write: %d %d\n", ep_index(ep), count);
1429 while (count--)
1430 *fifo = *cp++;
1431}
1432
1433static int read_fifo_ep0(struct lh7a40x_ep *ep, struct lh7a40x_request *req)
1434{
1435 u32 csr;
1436 u8 *buf;
1437 unsigned bufferspace, count, is_short;
1438 volatile u32 *fifo = (volatile u32 *)ep->fifo;
1439
1440 DEBUG_EP0("%s\n", __func__);
1441
1442 csr = usb_read(USB_EP0_CSR);
1443 if (!(csr & USB_OUT_CSR1_OUT_PKT_RDY))
1444 return 0;
1445
1446 buf = req->req.buf + req->req.actual;
1447 prefetchw(buf);
1448 bufferspace = req->req.length - req->req.actual;
1449
1450 /* read all bytes from this packet */
1451 if (likely(csr & EP0_OUT_PKT_RDY)) {
1452 count = usb_read(USB_OUT_FIFO_WC1);
1453 req->req.actual += min(count, bufferspace);
1454 } else /* zlp */
1455 count = 0;
1456
1457 is_short = (count < ep->ep.maxpacket);
1458 DEBUG_EP0("read %s %02x, %d bytes%s req %p %d/%d\n",
1459 ep->ep.name, csr, count,
1460 is_short ? "/S" : "", req, req->req.actual, req->req.length);
1461
1462 while (likely(count-- != 0)) {
1463 u8 byte = (u8) (*fifo & 0xff);
1464
1465 if (unlikely(bufferspace == 0)) {
1466 /* this happens when the driver's buffer
1467 * is smaller than what the host sent.
1468 * discard the extra data.
1469 */
1470 if (req->req.status != -EOVERFLOW)
1471 DEBUG_EP0("%s overflow %d\n", ep->ep.name,
1472 count);
1473 req->req.status = -EOVERFLOW;
1474 } else {
1475 *buf++ = byte;
1476 bufferspace--;
1477 }
1478 }
1479
1480 /* completion */
1481 if (is_short || req->req.actual == req->req.length) {
1482 done(ep, req, 0);
1483 return 1;
1484 }
1485
1486 /* finished that packet. the next one may be waiting... */
1487 return 0;
1488}
1489
1490/**
1491 * udc_set_address - set the USB address for this device
1492 * @address:
1493 *
1494 * Called from control endpoint function after it decodes a set address setup packet.
1495 */
1496static void udc_set_address(struct lh7a40x_udc *dev, unsigned char address)
1497{
1498 DEBUG_EP0("%s: %d\n", __func__, address);
1499 /* c.f. 15.1.2.2 Table 15-4 address will be used after DATA_END is set */
1500 dev->usb_address = address;
1501 usb_set((address & USB_FA_FUNCTION_ADDR), USB_FA);
1502 usb_set(USB_FA_ADDR_UPDATE | (address & USB_FA_FUNCTION_ADDR), USB_FA);
1503 /* usb_read(USB_FA); */
1504}
1505
1506/*
1507 * DATA_STATE_RECV (OUT_PKT_RDY)
1508 * - if error
1509 * set EP0_CLR_OUT | EP0_DATA_END | EP0_SEND_STALL bits
1510 * - else
1511 * set EP0_CLR_OUT bit
1512 if last set EP0_DATA_END bit
1513 */
1514static void lh7a40x_ep0_out(struct lh7a40x_udc *dev, u32 csr)
1515{
1516 struct lh7a40x_request *req;
1517 struct lh7a40x_ep *ep = &dev->ep[0];
1518 int ret;
1519
1520 DEBUG_EP0("%s: %x\n", __func__, csr);
1521
1522 if (list_empty(&ep->queue))
1523 req = 0;
1524 else
1525 req = list_entry(ep->queue.next, struct lh7a40x_request, queue);
1526
1527 if (req) {
1528
1529 if (req->req.length == 0) {
1530 DEBUG_EP0("ZERO LENGTH OUT!\n");
1531 usb_set((EP0_CLR_OUT | EP0_DATA_END), USB_EP0_CSR);
1532 dev->ep0state = WAIT_FOR_SETUP;
1533 return;
1534 }
1535 ret = read_fifo_ep0(ep, req);
1536 if (ret) {
1537 /* Done! */
1538 DEBUG_EP0("%s: finished, waiting for status\n",
1539 __func__);
1540
1541 usb_set((EP0_CLR_OUT | EP0_DATA_END), USB_EP0_CSR);
1542 dev->ep0state = WAIT_FOR_SETUP;
1543 } else {
1544 /* Not done yet.. */
1545 DEBUG_EP0("%s: not finished\n", __func__);
1546 usb_set(EP0_CLR_OUT, USB_EP0_CSR);
1547 }
1548 } else {
1549 DEBUG_EP0("NO REQ??!\n");
1550 }
1551}
1552
1553/*
1554 * DATA_STATE_XMIT
1555 */
1556static int lh7a40x_ep0_in(struct lh7a40x_udc *dev, u32 csr)
1557{
1558 struct lh7a40x_request *req;
1559 struct lh7a40x_ep *ep = &dev->ep[0];
1560 int ret, need_zlp = 0;
1561
1562 DEBUG_EP0("%s: %x\n", __func__, csr);
1563
1564 if (list_empty(&ep->queue))
1565 req = 0;
1566 else
1567 req = list_entry(ep->queue.next, struct lh7a40x_request, queue);
1568
1569 if (!req) {
1570 DEBUG_EP0("%s: NULL REQ\n", __func__);
1571 return 0;
1572 }
1573
1574 if (req->req.length == 0) {
1575
1576 usb_set((EP0_IN_PKT_RDY | EP0_DATA_END), USB_EP0_CSR);
1577 dev->ep0state = WAIT_FOR_SETUP;
1578 return 1;
1579 }
1580
1581 if (req->req.length - req->req.actual == EP0_PACKETSIZE) {
1582 /* Next write will end with the packet size, */
1583 /* so we need Zero-length-packet */
1584 need_zlp = 1;
1585 }
1586
1587 ret = write_fifo_ep0(ep, req);
1588
1589 if (ret == 1 && !need_zlp) {
1590 /* Last packet */
1591 DEBUG_EP0("%s: finished, waiting for status\n", __func__);
1592
1593 usb_set((EP0_IN_PKT_RDY | EP0_DATA_END), USB_EP0_CSR);
1594 dev->ep0state = WAIT_FOR_SETUP;
1595 } else {
1596 DEBUG_EP0("%s: not finished\n", __func__);
1597 usb_set(EP0_IN_PKT_RDY, USB_EP0_CSR);
1598 }
1599
1600 if (need_zlp) {
1601 DEBUG_EP0("%s: Need ZLP!\n", __func__);
1602 usb_set(EP0_IN_PKT_RDY, USB_EP0_CSR);
1603 dev->ep0state = DATA_STATE_NEED_ZLP;
1604 }
1605
1606 return 1;
1607}
1608
1609static int lh7a40x_handle_get_status(struct lh7a40x_udc *dev,
1610 struct usb_ctrlrequest *ctrl)
1611{
1612 struct lh7a40x_ep *ep0 = &dev->ep[0];
1613 struct lh7a40x_ep *qep;
1614 int reqtype = (ctrl->bRequestType & USB_RECIP_MASK);
1615 u16 val = 0;
1616
1617 if (reqtype == USB_RECIP_INTERFACE) {
1618 /* This is not supported.
1619 * And according to the USB spec, this one does nothing..
1620 * Just return 0
1621 */
1622 DEBUG_SETUP("GET_STATUS: USB_RECIP_INTERFACE\n");
1623 } else if (reqtype == USB_RECIP_DEVICE) {
1624 DEBUG_SETUP("GET_STATUS: USB_RECIP_DEVICE\n");
1625 val |= (1 << 0); /* Self powered */
1626 /*val |= (1<<1); *//* Remote wakeup */
1627 } else if (reqtype == USB_RECIP_ENDPOINT) {
1628 int ep_num = (ctrl->wIndex & ~USB_DIR_IN);
1629
1630 DEBUG_SETUP
1631 ("GET_STATUS: USB_RECIP_ENDPOINT (%d), ctrl->wLength = %d\n",
1632 ep_num, ctrl->wLength);
1633
1634 if (ctrl->wLength > 2 || ep_num > 3)
1635 return -EOPNOTSUPP;
1636
1637 qep = &dev->ep[ep_num];
1638 if (ep_is_in(qep) != ((ctrl->wIndex & USB_DIR_IN) ? 1 : 0)
1639 && ep_index(qep) != 0) {
1640 return -EOPNOTSUPP;
1641 }
1642
1643 usb_set_index(ep_index(qep));
1644
1645 /* Return status on next IN token */
1646 switch (qep->ep_type) {
1647 case ep_control:
1648 val =
1649 (usb_read(qep->csr1) & EP0_SEND_STALL) ==
1650 EP0_SEND_STALL;
1651 break;
1652 case ep_bulk_in:
1653 case ep_interrupt:
1654 val =
1655 (usb_read(qep->csr1) & USB_IN_CSR1_SEND_STALL) ==
1656 USB_IN_CSR1_SEND_STALL;
1657 break;
1658 case ep_bulk_out:
1659 val =
1660 (usb_read(qep->csr1) & USB_OUT_CSR1_SEND_STALL) ==
1661 USB_OUT_CSR1_SEND_STALL;
1662 break;
1663 }
1664
1665 /* Back to EP0 index */
1666 usb_set_index(0);
1667
1668 DEBUG_SETUP("GET_STATUS, ep: %d (%x), val = %d\n", ep_num,
1669 ctrl->wIndex, val);
1670 } else {
1671 DEBUG_SETUP("Unknown REQ TYPE: %d\n", reqtype);
1672 return -EOPNOTSUPP;
1673 }
1674
1675 /* Clear "out packet ready" */
1676 usb_set((EP0_CLR_OUT), USB_EP0_CSR);
1677 /* Put status to FIFO */
1678 lh7a40x_fifo_write(ep0, (u8 *) & val, sizeof(val));
1679 /* Issue "In packet ready" */
1680 usb_set((EP0_IN_PKT_RDY | EP0_DATA_END), USB_EP0_CSR);
1681
1682 return 0;
1683}
1684
1685/*
1686 * WAIT_FOR_SETUP (OUT_PKT_RDY)
1687 * - read data packet from EP0 FIFO
1688 * - decode command
1689 * - if error
1690 * set EP0_CLR_OUT | EP0_DATA_END | EP0_SEND_STALL bits
1691 * - else
1692 * set EP0_CLR_OUT | EP0_DATA_END bits
1693 */
1694static void lh7a40x_ep0_setup(struct lh7a40x_udc *dev, u32 csr)
1695{
1696 struct lh7a40x_ep *ep = &dev->ep[0];
1697 struct usb_ctrlrequest ctrl;
1698 int i, bytes, is_in;
1699
1700 DEBUG_SETUP("%s: %x\n", __func__, csr);
1701
1702 /* Nuke all previous transfers */
1703 nuke(ep, -EPROTO);
1704
1705 /* read control req from fifo (8 bytes) */
1706 bytes = lh7a40x_fifo_read(ep, (unsigned char *)&ctrl, 8);
1707
1708 DEBUG_SETUP("Read CTRL REQ %d bytes\n", bytes);
1709 DEBUG_SETUP("CTRL.bRequestType = %d (is_in %d)\n", ctrl.bRequestType,
1710 ctrl.bRequestType == USB_DIR_IN);
1711 DEBUG_SETUP("CTRL.bRequest = %d\n", ctrl.bRequest);
1712 DEBUG_SETUP("CTRL.wLength = %d\n", ctrl.wLength);
1713 DEBUG_SETUP("CTRL.wValue = %d (%d)\n", ctrl.wValue, ctrl.wValue >> 8);
1714 DEBUG_SETUP("CTRL.wIndex = %d\n", ctrl.wIndex);
1715
1716 /* Set direction of EP0 */
1717 if (likely(ctrl.bRequestType & USB_DIR_IN)) {
1718 ep->bEndpointAddress |= USB_DIR_IN;
1719 is_in = 1;
1720 } else {
1721 ep->bEndpointAddress &= ~USB_DIR_IN;
1722 is_in = 0;
1723 }
1724
1725 dev->req_pending = 1;
1726
1727 /* Handle some SETUP packets ourselves */
1728 switch (ctrl.bRequest) {
1729 case USB_REQ_SET_ADDRESS:
1730 if (ctrl.bRequestType != (USB_TYPE_STANDARD | USB_RECIP_DEVICE))
1731 break;
1732
1733 DEBUG_SETUP("USB_REQ_SET_ADDRESS (%d)\n", ctrl.wValue);
1734 udc_set_address(dev, ctrl.wValue);
1735 usb_set((EP0_CLR_OUT | EP0_DATA_END), USB_EP0_CSR);
1736 return;
1737
1738 case USB_REQ_GET_STATUS:{
1739 if (lh7a40x_handle_get_status(dev, &ctrl) == 0)
1740 return;
1741
1742 case USB_REQ_CLEAR_FEATURE:
1743 case USB_REQ_SET_FEATURE:
1744 if (ctrl.bRequestType == USB_RECIP_ENDPOINT) {
1745 struct lh7a40x_ep *qep;
1746 int ep_num = (ctrl.wIndex & 0x0f);
1747
1748 /* Support only HALT feature */
1749 if (ctrl.wValue != 0 || ctrl.wLength != 0
1750 || ep_num > 3 || ep_num < 1)
1751 break;
1752
1753 qep = &dev->ep[ep_num];
1754 spin_unlock(&dev->lock);
1755 if (ctrl.bRequest == USB_REQ_SET_FEATURE) {
1756 DEBUG_SETUP("SET_FEATURE (%d)\n",
1757 ep_num);
1758 lh7a40x_set_halt(&qep->ep, 1);
1759 } else {
1760 DEBUG_SETUP("CLR_FEATURE (%d)\n",
1761 ep_num);
1762 lh7a40x_set_halt(&qep->ep, 0);
1763 }
1764 spin_lock(&dev->lock);
1765 usb_set_index(0);
1766
1767 /* Reply with a ZLP on next IN token */
1768 usb_set((EP0_CLR_OUT | EP0_DATA_END),
1769 USB_EP0_CSR);
1770 return;
1771 }
1772 break;
1773 }
1774
1775 default:
1776 break;
1777 }
1778
1779 if (likely(dev->driver)) {
1780 /* device-2-host (IN) or no data setup command, process immediately */
1781 spin_unlock(&dev->lock);
1782 i = dev->driver->setup(&dev->gadget, &ctrl);
1783 spin_lock(&dev->lock);
1784
1785 if (i < 0) {
1786 /* setup processing failed, force stall */
1787 DEBUG_SETUP
1788 (" --> ERROR: gadget setup FAILED (stalling), setup returned %d\n",
1789 i);
1790 usb_set_index(0);
1791 usb_set((EP0_CLR_OUT | EP0_DATA_END | EP0_SEND_STALL),
1792 USB_EP0_CSR);
1793
1794 /* ep->stopped = 1; */
1795 dev->ep0state = WAIT_FOR_SETUP;
1796 }
1797 }
1798}
1799
1800/*
1801 * DATA_STATE_NEED_ZLP
1802 */
1803static void lh7a40x_ep0_in_zlp(struct lh7a40x_udc *dev, u32 csr)
1804{
1805 DEBUG_EP0("%s: %x\n", __func__, csr);
1806
1807 /* c.f. Table 15-14 */
1808 usb_set((EP0_IN_PKT_RDY | EP0_DATA_END), USB_EP0_CSR);
1809 dev->ep0state = WAIT_FOR_SETUP;
1810}
1811
1812/*
1813 * handle ep0 interrupt
1814 */
1815static void lh7a40x_handle_ep0(struct lh7a40x_udc *dev, u32 intr)
1816{
1817 struct lh7a40x_ep *ep = &dev->ep[0];
1818 u32 csr;
1819
1820 /* Set index 0 */
1821 usb_set_index(0);
1822 csr = usb_read(USB_EP0_CSR);
1823
1824 DEBUG_EP0("%s: csr = %x\n", __func__, csr);
1825
1826 /*
1827 * For overview of what we should be doing see c.f. Chapter 18.1.2.4
1828 * We will follow that outline here modified by our own global state
1829 * indication which provides hints as to what we think should be
1830 * happening..
1831 */
1832
1833 /*
1834 * if SENT_STALL is set
1835 * - clear the SENT_STALL bit
1836 */
1837 if (csr & EP0_SENT_STALL) {
1838 DEBUG_EP0("%s: EP0_SENT_STALL is set: %x\n", __func__, csr);
1839 usb_clear((EP0_SENT_STALL | EP0_SEND_STALL), USB_EP0_CSR);
1840 nuke(ep, -ECONNABORTED);
1841 dev->ep0state = WAIT_FOR_SETUP;
1842 return;
1843 }
1844
1845 /*
1846 * if a transfer is in progress && IN_PKT_RDY and OUT_PKT_RDY are clear
1847 * - fill EP0 FIFO
1848 * - if last packet
1849 * - set IN_PKT_RDY | DATA_END
1850 * - else
1851 * set IN_PKT_RDY
1852 */
1853 if (!(csr & (EP0_IN_PKT_RDY | EP0_OUT_PKT_RDY))) {
1854 DEBUG_EP0("%s: IN_PKT_RDY and OUT_PKT_RDY are clear\n",
1855 __func__);
1856
1857 switch (dev->ep0state) {
1858 case DATA_STATE_XMIT:
1859 DEBUG_EP0("continue with DATA_STATE_XMIT\n");
1860 lh7a40x_ep0_in(dev, csr);
1861 return;
1862 case DATA_STATE_NEED_ZLP:
1863 DEBUG_EP0("continue with DATA_STATE_NEED_ZLP\n");
1864 lh7a40x_ep0_in_zlp(dev, csr);
1865 return;
1866 default:
1867 /* Stall? */
1868 DEBUG_EP0("Odd state!! state = %s\n",
1869 state_names[dev->ep0state]);
1870 dev->ep0state = WAIT_FOR_SETUP;
1871 /* nuke(ep, 0); */
1872 /* usb_set(EP0_SEND_STALL, ep->csr1); */
1873 break;
1874 }
1875 }
1876
1877 /*
1878 * if SETUP_END is set
1879 * - abort the last transfer
1880 * - set SERVICED_SETUP_END_BIT
1881 */
1882 if (csr & EP0_SETUP_END) {
1883 DEBUG_EP0("%s: EP0_SETUP_END is set: %x\n", __func__, csr);
1884
1885 usb_set(EP0_CLR_SETUP_END, USB_EP0_CSR);
1886
1887 nuke(ep, 0);
1888 dev->ep0state = WAIT_FOR_SETUP;
1889 }
1890
1891 /*
1892 * if EP0_OUT_PKT_RDY is set
1893 * - read data packet from EP0 FIFO
1894 * - decode command
1895 * - if error
1896 * set SERVICED_OUT_PKT_RDY | DATA_END bits | SEND_STALL
1897 * - else
1898 * set SERVICED_OUT_PKT_RDY | DATA_END bits
1899 */
1900 if (csr & EP0_OUT_PKT_RDY) {
1901
1902 DEBUG_EP0("%s: EP0_OUT_PKT_RDY is set: %x\n", __func__,
1903 csr);
1904
1905 switch (dev->ep0state) {
1906 case WAIT_FOR_SETUP:
1907 DEBUG_EP0("WAIT_FOR_SETUP\n");
1908 lh7a40x_ep0_setup(dev, csr);
1909 break;
1910
1911 case DATA_STATE_RECV:
1912 DEBUG_EP0("DATA_STATE_RECV\n");
1913 lh7a40x_ep0_out(dev, csr);
1914 break;
1915
1916 default:
1917 /* send stall? */
1918 DEBUG_EP0("strange state!! 2. send stall? state = %d\n",
1919 dev->ep0state);
1920 break;
1921 }
1922 }
1923}
1924
1925static void lh7a40x_ep0_kick(struct lh7a40x_udc *dev, struct lh7a40x_ep *ep)
1926{
1927 u32 csr;
1928
1929 usb_set_index(0);
1930 csr = usb_read(USB_EP0_CSR);
1931
1932 DEBUG_EP0("%s: %x\n", __func__, csr);
1933
1934 /* Clear "out packet ready" */
1935 usb_set(EP0_CLR_OUT, USB_EP0_CSR);
1936
1937 if (ep_is_in(ep)) {
1938 dev->ep0state = DATA_STATE_XMIT;
1939 lh7a40x_ep0_in(dev, csr);
1940 } else {
1941 dev->ep0state = DATA_STATE_RECV;
1942 lh7a40x_ep0_out(dev, csr);
1943 }
1944}
1945
1946/* ---------------------------------------------------------------------------
1947 * device-scoped parts of the api to the usb controller hardware
1948 * ---------------------------------------------------------------------------
1949 */
1950
1951static int lh7a40x_udc_get_frame(struct usb_gadget *_gadget)
1952{
1953 u32 frame1 = usb_read(USB_FRM_NUM1); /* Least significant 8 bits */
1954 u32 frame2 = usb_read(USB_FRM_NUM2); /* Most significant 3 bits */
1955 DEBUG("%s, %p\n", __func__, _gadget);
1956 return ((frame2 & 0x07) << 8) | (frame1 & 0xff);
1957}
1958
1959static int lh7a40x_udc_wakeup(struct usb_gadget *_gadget)
1960{
1961 /* host may not have enabled remote wakeup */
1962 /*if ((UDCCS0 & UDCCS0_DRWF) == 0)
1963 return -EHOSTUNREACH;
1964 udc_set_mask_UDCCR(UDCCR_RSM); */
1965 return -ENOTSUPP;
1966}
1967
1968static const struct usb_gadget_ops lh7a40x_udc_ops = {
1969 .get_frame = lh7a40x_udc_get_frame,
1970 .wakeup = lh7a40x_udc_wakeup,
1971 /* current versions must always be self-powered */
1972};
1973
1974static void nop_release(struct device *dev)
1975{
1976 DEBUG("%s %s\n", __func__, dev_name(dev));
1977}
1978
1979static struct lh7a40x_udc memory = {
1980 .usb_address = 0,
1981
1982 .gadget = {
1983 .ops = &lh7a40x_udc_ops,
1984 .ep0 = &memory.ep[0].ep,
1985 .name = driver_name,
1986 .dev = {
1987 .init_name = "gadget",
1988 .release = nop_release,
1989 },
1990 },
1991
1992 /* control endpoint */
1993 .ep[0] = {
1994 .ep = {
1995 .name = ep0name,
1996 .ops = &lh7a40x_ep_ops,
1997 .maxpacket = EP0_PACKETSIZE,
1998 },
1999 .dev = &memory,
2000
2001 .bEndpointAddress = 0,
2002 .bmAttributes = 0,
2003
2004 .ep_type = ep_control,
2005 .fifo = io_p2v(USB_EP0_FIFO),
2006 .csr1 = USB_EP0_CSR,
2007 .csr2 = USB_EP0_CSR,
2008 },
2009
2010 /* first group of endpoints */
2011 .ep[1] = {
2012 .ep = {
2013 .name = "ep1in-bulk",
2014 .ops = &lh7a40x_ep_ops,
2015 .maxpacket = 64,
2016 },
2017 .dev = &memory,
2018
2019 .bEndpointAddress = USB_DIR_IN | 1,
2020 .bmAttributes = USB_ENDPOINT_XFER_BULK,
2021
2022 .ep_type = ep_bulk_in,
2023 .fifo = io_p2v(USB_EP1_FIFO),
2024 .csr1 = USB_IN_CSR1,
2025 .csr2 = USB_IN_CSR2,
2026 },
2027
2028 .ep[2] = {
2029 .ep = {
2030 .name = "ep2out-bulk",
2031 .ops = &lh7a40x_ep_ops,
2032 .maxpacket = 64,
2033 },
2034 .dev = &memory,
2035
2036 .bEndpointAddress = 2,
2037 .bmAttributes = USB_ENDPOINT_XFER_BULK,
2038
2039 .ep_type = ep_bulk_out,
2040 .fifo = io_p2v(USB_EP2_FIFO),
2041 .csr1 = USB_OUT_CSR1,
2042 .csr2 = USB_OUT_CSR2,
2043 },
2044
2045 .ep[3] = {
2046 .ep = {
2047 .name = "ep3in-int",
2048 .ops = &lh7a40x_ep_ops,
2049 .maxpacket = 64,
2050 },
2051 .dev = &memory,
2052
2053 .bEndpointAddress = USB_DIR_IN | 3,
2054 .bmAttributes = USB_ENDPOINT_XFER_INT,
2055
2056 .ep_type = ep_interrupt,
2057 .fifo = io_p2v(USB_EP3_FIFO),
2058 .csr1 = USB_IN_CSR1,
2059 .csr2 = USB_IN_CSR2,
2060 },
2061};
2062
2063/*
2064 * probe - binds to the platform device
2065 */
2066static int lh7a40x_udc_probe(struct platform_device *pdev)
2067{
2068 struct lh7a40x_udc *dev = &memory;
2069 int retval;
2070
2071 DEBUG("%s: %p\n", __func__, pdev);
2072
2073 spin_lock_init(&dev->lock);
2074 dev->dev = &pdev->dev;
2075
2076 device_initialize(&dev->gadget.dev);
2077 dev->gadget.dev.parent = &pdev->dev;
2078
2079 the_controller = dev;
2080 platform_set_drvdata(pdev, dev);
2081
2082 udc_disable(dev);
2083 udc_reinit(dev);
2084
2085 /* irq setup after old hardware state is cleaned up */
2086 retval =
2087 request_irq(IRQ_USBINTR, lh7a40x_udc_irq, IRQF_DISABLED, driver_name,
2088 dev);
2089 if (retval != 0) {
2090 DEBUG(KERN_ERR "%s: can't get irq %i, err %d\n", driver_name,
2091 IRQ_USBINTR, retval);
2092 return -EBUSY;
2093 }
2094
2095 create_proc_files();
2096
2097 return retval;
2098}
2099
2100static int lh7a40x_udc_remove(struct platform_device *pdev)
2101{
2102 struct lh7a40x_udc *dev = platform_get_drvdata(pdev);
2103
2104 DEBUG("%s: %p\n", __func__, pdev);
2105
2106 if (dev->driver)
2107 return -EBUSY;
2108
2109 udc_disable(dev);
2110 remove_proc_files();
2111
2112 free_irq(IRQ_USBINTR, dev);
2113
2114 platform_set_drvdata(pdev, 0);
2115
2116 the_controller = 0;
2117
2118 return 0;
2119}
2120
2121/*-------------------------------------------------------------------------*/
2122
2123static struct platform_driver udc_driver = {
2124 .probe = lh7a40x_udc_probe,
2125 .remove = lh7a40x_udc_remove,
2126 /* FIXME power management support */
2127 /* .suspend = ... disable UDC */
2128 /* .resume = ... re-enable UDC */
2129 .driver = {
2130 .name = (char *)driver_name,
2131 .owner = THIS_MODULE,
2132 },
2133};
2134
2135static int __init udc_init(void)
2136{
2137 DEBUG("%s: %s version %s\n", __func__, driver_name, DRIVER_VERSION);
2138 return platform_driver_register(&udc_driver);
2139}
2140
2141static void __exit udc_exit(void)
2142{
2143 platform_driver_unregister(&udc_driver);
2144}
2145
2146module_init(udc_init);
2147module_exit(udc_exit);
2148
2149MODULE_DESCRIPTION(DRIVER_DESC);
2150MODULE_AUTHOR("Mikko Lahteenmaki, Bo Henriksen");
2151MODULE_LICENSE("GPL");
2152MODULE_ALIAS("platform:lh7a40x_udc");
diff --git a/drivers/usb/gadget/lh7a40x_udc.h b/drivers/usb/gadget/lh7a40x_udc.h
deleted file mode 100644
index ca861203a301..000000000000
--- a/drivers/usb/gadget/lh7a40x_udc.h
+++ /dev/null
@@ -1,259 +0,0 @@
1/*
2 * linux/drivers/usb/gadget/lh7a40x_udc.h
3 * Sharp LH7A40x on-chip full speed USB device controllers
4 *
5 * Copyright (C) 2004 Mikko Lahteenmaki, Nordic ID
6 * Copyright (C) 2004 Bo Henriksen, Nordic ID
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22 */
23
24#ifndef __LH7A40X_H_
25#define __LH7A40X_H_
26
27#include <linux/module.h>
28#include <linux/kernel.h>
29#include <linux/ioport.h>
30#include <linux/types.h>
31#include <linux/errno.h>
32#include <linux/delay.h>
33#include <linux/sched.h>
34#include <linux/slab.h>
35#include <linux/init.h>
36#include <linux/timer.h>
37#include <linux/list.h>
38#include <linux/interrupt.h>
39#include <linux/proc_fs.h>
40#include <linux/mm.h>
41#include <linux/device.h>
42#include <linux/dma-mapping.h>
43
44#include <asm/byteorder.h>
45#include <asm/dma.h>
46#include <asm/io.h>
47#include <asm/irq.h>
48#include <asm/system.h>
49#include <asm/unaligned.h>
50#include <mach/hardware.h>
51
52#include <linux/usb/ch9.h>
53#include <linux/usb/gadget.h>
54
55/*
56 * Memory map
57 */
58
59#define USB_FA 0x80000200 // function address register
60#define USB_PM 0x80000204 // power management register
61
62#define USB_IN_INT 0x80000208 // IN interrupt register bank (EP0-EP3)
63#define USB_OUT_INT 0x80000210 // OUT interrupt register bank (EP2)
64#define USB_INT 0x80000218 // interrupt register bank
65
66#define USB_IN_INT_EN 0x8000021C // IN interrupt enable register bank
67#define USB_OUT_INT_EN 0x80000224 // OUT interrupt enable register bank
68#define USB_INT_EN 0x8000022C // USB interrupt enable register bank
69
70#define USB_FRM_NUM1 0x80000230 // Frame number1 register
71#define USB_FRM_NUM2 0x80000234 // Frame number2 register
72#define USB_INDEX 0x80000238 // index register
73
74#define USB_IN_MAXP 0x80000240 // IN MAXP register
75#define USB_IN_CSR1 0x80000244 // IN CSR1 register/EP0 CSR register
76#define USB_EP0_CSR 0x80000244 // IN CSR1 register/EP0 CSR register
77#define USB_IN_CSR2 0x80000248 // IN CSR2 register
78#define USB_OUT_MAXP 0x8000024C // OUT MAXP register
79
80#define USB_OUT_CSR1 0x80000250 // OUT CSR1 register
81#define USB_OUT_CSR2 0x80000254 // OUT CSR2 register
82#define USB_OUT_FIFO_WC1 0x80000258 // OUT FIFO write count1 register
83#define USB_OUT_FIFO_WC2 0x8000025C // OUT FIFO write count2 register
84
85#define USB_RESET 0x8000044C // USB reset register
86
87#define USB_EP0_FIFO 0x80000280
88#define USB_EP1_FIFO 0x80000284
89#define USB_EP2_FIFO 0x80000288
90#define USB_EP3_FIFO 0x8000028c
91
92/*
93 * USB reset register
94 */
95#define USB_RESET_APB (1<<1) //resets USB APB control side WRITE
96#define USB_RESET_IO (1<<0) //resets USB IO side WRITE
97
98/*
99 * USB function address register
100 */
101#define USB_FA_ADDR_UPDATE (1<<7)
102#define USB_FA_FUNCTION_ADDR (0x7F)
103
104/*
105 * Power Management register
106 */
107#define PM_USB_DCP (1<<5)
108#define PM_USB_ENABLE (1<<4)
109#define PM_USB_RESET (1<<3)
110#define PM_UC_RESUME (1<<2)
111#define PM_SUSPEND_MODE (1<<1)
112#define PM_ENABLE_SUSPEND (1<<0)
113
114/*
115 * IN interrupt register
116 */
117#define USB_IN_INT_EP3 (1<<3)
118#define USB_IN_INT_EP1 (1<<1)
119#define USB_IN_INT_EP0 (1<<0)
120
121/*
122 * OUT interrupt register
123 */
124#define USB_OUT_INT_EP2 (1<<2)
125
126/*
127 * USB interrupt register
128 */
129#define USB_INT_RESET_INT (1<<2)
130#define USB_INT_RESUME_INT (1<<1)
131#define USB_INT_SUSPEND_INT (1<<0)
132
133/*
134 * USB interrupt enable register
135 */
136#define USB_INT_EN_USB_RESET_INTER (1<<2)
137#define USB_INT_EN_RESUME_INTER (1<<1)
138#define USB_INT_EN_SUSPEND_INTER (1<<0)
139
140/*
141 * INCSR1 register
142 */
143#define USB_IN_CSR1_CLR_DATA_TOGGLE (1<<6)
144#define USB_IN_CSR1_SENT_STALL (1<<5)
145#define USB_IN_CSR1_SEND_STALL (1<<4)
146#define USB_IN_CSR1_FIFO_FLUSH (1<<3)
147#define USB_IN_CSR1_FIFO_NOT_EMPTY (1<<1)
148#define USB_IN_CSR1_IN_PKT_RDY (1<<0)
149
150/*
151 * INCSR2 register
152 */
153#define USB_IN_CSR2_AUTO_SET (1<<7)
154#define USB_IN_CSR2_USB_DMA_EN (1<<4)
155
156/*
157 * OUT CSR1 register
158 */
159#define USB_OUT_CSR1_CLR_DATA_REG (1<<7)
160#define USB_OUT_CSR1_SENT_STALL (1<<6)
161#define USB_OUT_CSR1_SEND_STALL (1<<5)
162#define USB_OUT_CSR1_FIFO_FLUSH (1<<4)
163#define USB_OUT_CSR1_FIFO_FULL (1<<1)
164#define USB_OUT_CSR1_OUT_PKT_RDY (1<<0)
165
166/*
167 * OUT CSR2 register
168 */
169#define USB_OUT_CSR2_AUTO_CLR (1<<7)
170#define USB_OUT_CSR2_USB_DMA_EN (1<<4)
171
172/*
173 * EP0 CSR
174 */
175#define EP0_CLR_SETUP_END (1<<7) /* Clear "Setup Ends" Bit (w) */
176#define EP0_CLR_OUT (1<<6) /* Clear "Out packet ready" Bit (w) */
177#define EP0_SEND_STALL (1<<5) /* Send STALL Handshake (rw) */
178#define EP0_SETUP_END (1<<4) /* Setup Ends (r) */
179
180#define EP0_DATA_END (1<<3) /* Data end (rw) */
181#define EP0_SENT_STALL (1<<2) /* Sent Stall Handshake (r) */
182#define EP0_IN_PKT_RDY (1<<1) /* In packet ready (rw) */
183#define EP0_OUT_PKT_RDY (1<<0) /* Out packet ready (r) */
184
185/* general CSR */
186#define OUT_PKT_RDY (1<<0)
187#define IN_PKT_RDY (1<<0)
188
189/*
190 * IN/OUT MAXP register
191 */
192#define USB_OUT_MAXP_MAXP (0xF)
193#define USB_IN_MAXP_MAXP (0xF)
194
195// Max packet size
196//#define EP0_PACKETSIZE 0x10
197#define EP0_PACKETSIZE 0x8
198#define EP0_MAXPACKETSIZE 0x10
199
200#define UDC_MAX_ENDPOINTS 4
201
202#define WAIT_FOR_SETUP 0
203#define DATA_STATE_XMIT 1
204#define DATA_STATE_NEED_ZLP 2
205#define WAIT_FOR_OUT_STATUS 3
206#define DATA_STATE_RECV 4
207
208/* ********************************************************************************************* */
209/* IO
210 */
211
212typedef enum ep_type {
213 ep_control, ep_bulk_in, ep_bulk_out, ep_interrupt
214} ep_type_t;
215
216struct lh7a40x_ep {
217 struct usb_ep ep;
218 struct lh7a40x_udc *dev;
219
220 const struct usb_endpoint_descriptor *desc;
221 struct list_head queue;
222 unsigned long pio_irqs;
223
224 u8 stopped;
225 u8 bEndpointAddress;
226 u8 bmAttributes;
227
228 ep_type_t ep_type;
229 u32 fifo;
230 u32 csr1;
231 u32 csr2;
232};
233
234struct lh7a40x_request {
235 struct usb_request req;
236 struct list_head queue;
237};
238
239struct lh7a40x_udc {
240 struct usb_gadget gadget;
241 struct usb_gadget_driver *driver;
242 struct device *dev;
243 spinlock_t lock;
244
245 int ep0state;
246 struct lh7a40x_ep ep[UDC_MAX_ENDPOINTS];
247
248 unsigned char usb_address;
249
250 unsigned req_pending:1, req_std:1, req_config:1;
251};
252
253extern struct lh7a40x_udc *the_controller;
254
255#define ep_is_in(EP) (((EP)->bEndpointAddress&USB_DIR_IN)==USB_DIR_IN)
256#define ep_index(EP) ((EP)->bEndpointAddress&0xF)
257#define ep_maxpacket(EP) ((EP)->ep.maxpacket)
258
259#endif
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 759a12ff8048..b426c1e8a679 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1023,11 +1023,6 @@ MODULE_LICENSE ("GPL");
1023#define OMAP3_PLATFORM_DRIVER ohci_hcd_omap3_driver 1023#define OMAP3_PLATFORM_DRIVER ohci_hcd_omap3_driver
1024#endif 1024#endif
1025 1025
1026#ifdef CONFIG_ARCH_LH7A404
1027#include "ohci-lh7a404.c"
1028#define PLATFORM_DRIVER ohci_hcd_lh7a404_driver
1029#endif
1030
1031#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx) 1026#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
1032#include "ohci-pxa27x.c" 1027#include "ohci-pxa27x.c"
1033#define PLATFORM_DRIVER ohci_hcd_pxa27x_driver 1028#define PLATFORM_DRIVER ohci_hcd_pxa27x_driver
diff --git a/drivers/usb/host/ohci-lh7a404.c b/drivers/usb/host/ohci-lh7a404.c
deleted file mode 100644
index 18d39f0463ee..000000000000
--- a/drivers/usb/host/ohci-lh7a404.c
+++ /dev/null
@@ -1,252 +0,0 @@
1/*
2 * OHCI HCD (Host Controller Driver) for USB.
3 *
4 * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
5 * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net>
6 * (C) Copyright 2002 Hewlett-Packard Company
7 *
8 * Bus Glue for Sharp LH7A404
9 *
10 * Written by Christopher Hoover <ch@hpl.hp.com>
11 * Based on fragments of previous driver by Russell King et al.
12 *
13 * Modified for LH7A404 from ohci-sa1111.c
14 * by Durgesh Pattamatta <pattamattad@sharpsec.com>
15 *
16 * This file is licenced under the GPL.
17 */
18
19#include <linux/platform_device.h>
20#include <linux/signal.h>
21
22#include <mach/hardware.h>
23
24
25extern int usb_disabled(void);
26
27/*-------------------------------------------------------------------------*/
28
29static void lh7a404_start_hc(struct platform_device *dev)
30{
31 printk(KERN_DEBUG "%s: starting LH7A404 OHCI USB Controller\n",
32 __FILE__);
33
34 /*
35 * Now, carefully enable the USB clock, and take
36 * the USB host controller out of reset.
37 */
38 CSC_PWRCNT |= CSC_PWRCNT_USBH_EN; /* Enable clock */
39 udelay(1000);
40 USBH_CMDSTATUS = OHCI_HCR;
41
42 printk(KERN_DEBUG "%s: Clock to USB host has been enabled \n", __FILE__);
43}
44
45static void lh7a404_stop_hc(struct platform_device *dev)
46{
47 printk(KERN_DEBUG "%s: stopping LH7A404 OHCI USB Controller\n",
48 __FILE__);
49
50 CSC_PWRCNT &= ~CSC_PWRCNT_USBH_EN; /* Disable clock */
51}
52
53
54/*-------------------------------------------------------------------------*/
55
56/* configure so an HC device and id are always provided */
57/* always called with process context; sleeping is OK */
58
59
60/**
61 * usb_hcd_lh7a404_probe - initialize LH7A404-based HCDs
62 * Context: !in_interrupt()
63 *
64 * Allocates basic resources for this USB host controller, and
65 * then invokes the start() method for the HCD associated with it
66 * through the hotplug entry's driver_data.
67 *
68 */
69int usb_hcd_lh7a404_probe (const struct hc_driver *driver,
70 struct platform_device *dev)
71{
72 int retval;
73 struct usb_hcd *hcd;
74
75 if (dev->resource[1].flags != IORESOURCE_IRQ) {
76 pr_debug("resource[1] is not IORESOURCE_IRQ");
77 return -ENOMEM;
78 }
79
80 hcd = usb_create_hcd(driver, &dev->dev, "lh7a404");
81 if (!hcd)
82 return -ENOMEM;
83 hcd->rsrc_start = dev->resource[0].start;
84 hcd->rsrc_len = dev->resource[0].end - dev->resource[0].start + 1;
85
86 if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
87 pr_debug("request_mem_region failed");
88 retval = -EBUSY;
89 goto err1;
90 }
91
92 hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
93 if (!hcd->regs) {
94 pr_debug("ioremap failed");
95 retval = -ENOMEM;
96 goto err2;
97 }
98
99 lh7a404_start_hc(dev);
100 ohci_hcd_init(hcd_to_ohci(hcd));
101
102 retval = usb_add_hcd(hcd, dev->resource[1].start, IRQF_DISABLED);
103 if (retval == 0)
104 return retval;
105
106 lh7a404_stop_hc(dev);
107 iounmap(hcd->regs);
108 err2:
109 release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
110 err1:
111 usb_put_hcd(hcd);
112 return retval;
113}
114
115
116/* may be called without controller electrically present */
117/* may be called with controller, bus, and devices active */
118
119/**
120 * usb_hcd_lh7a404_remove - shutdown processing for LH7A404-based HCDs
121 * @dev: USB Host Controller being removed
122 * Context: !in_interrupt()
123 *
124 * Reverses the effect of usb_hcd_lh7a404_probe(), first invoking
125 * the HCD's stop() method. It is always called from a thread
126 * context, normally "rmmod", "apmd", or something similar.
127 *
128 */
129void usb_hcd_lh7a404_remove (struct usb_hcd *hcd, struct platform_device *dev)
130{
131 usb_remove_hcd(hcd);
132 lh7a404_stop_hc(dev);
133 iounmap(hcd->regs);
134 release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
135 usb_put_hcd(hcd);
136}
137
138/*-------------------------------------------------------------------------*/
139
140static int __devinit
141ohci_lh7a404_start (struct usb_hcd *hcd)
142{
143 struct ohci_hcd *ohci = hcd_to_ohci (hcd);
144 int ret;
145
146 ohci_dbg (ohci, "ohci_lh7a404_start, ohci:%p", ohci);
147 if ((ret = ohci_init(ohci)) < 0)
148 return ret;
149
150 if ((ret = ohci_run (ohci)) < 0) {
151 err ("can't start %s", hcd->self.bus_name);
152 ohci_stop (hcd);
153 return ret;
154 }
155 return 0;
156}
157
158/*-------------------------------------------------------------------------*/
159
160static const struct hc_driver ohci_lh7a404_hc_driver = {
161 .description = hcd_name,
162 .product_desc = "LH7A404 OHCI",
163 .hcd_priv_size = sizeof(struct ohci_hcd),
164
165 /*
166 * generic hardware linkage
167 */
168 .irq = ohci_irq,
169 .flags = HCD_USB11 | HCD_MEMORY,
170
171 /*
172 * basic lifecycle operations
173 */
174 .start = ohci_lh7a404_start,
175 .stop = ohci_stop,
176 .shutdown = ohci_shutdown,
177
178 /*
179 * managing i/o requests and associated device resources
180 */
181 .urb_enqueue = ohci_urb_enqueue,
182 .urb_dequeue = ohci_urb_dequeue,
183 .endpoint_disable = ohci_endpoint_disable,
184
185 /*
186 * scheduling support
187 */
188 .get_frame_number = ohci_get_frame,
189
190 /*
191 * root hub support
192 */
193 .hub_status_data = ohci_hub_status_data,
194 .hub_control = ohci_hub_control,
195#ifdef CONFIG_PM
196 .bus_suspend = ohci_bus_suspend,
197 .bus_resume = ohci_bus_resume,
198#endif
199 .start_port_reset = ohci_start_port_reset,
200};
201
202/*-------------------------------------------------------------------------*/
203
204static int ohci_hcd_lh7a404_drv_probe(struct platform_device *pdev)
205{
206 int ret;
207
208 pr_debug ("In ohci_hcd_lh7a404_drv_probe");
209
210 if (usb_disabled())
211 return -ENODEV;
212
213 ret = usb_hcd_lh7a404_probe(&ohci_lh7a404_hc_driver, pdev);
214 return ret;
215}
216
217static int ohci_hcd_lh7a404_drv_remove(struct platform_device *pdev)
218{
219 struct usb_hcd *hcd = platform_get_drvdata(pdev);
220
221 usb_hcd_lh7a404_remove(hcd, pdev);
222 return 0;
223}
224 /*TBD*/
225/*static int ohci_hcd_lh7a404_drv_suspend(struct platform_device *dev)
226{
227 struct usb_hcd *hcd = platform_get_drvdata(dev);
228
229 return 0;
230}
231static int ohci_hcd_lh7a404_drv_resume(struct platform_device *dev)
232{
233 struct usb_hcd *hcd = platform_get_drvdata(dev);
234
235
236 return 0;
237}
238*/
239
240static struct platform_driver ohci_hcd_lh7a404_driver = {
241 .probe = ohci_hcd_lh7a404_drv_probe,
242 .remove = ohci_hcd_lh7a404_drv_remove,
243 .shutdown = usb_hcd_platform_shutdown,
244 /*.suspend = ohci_hcd_lh7a404_drv_suspend, */
245 /*.resume = ohci_hcd_lh7a404_drv_resume, */
246 .driver = {
247 .name = "lh7a404-ohci",
248 .owner = THIS_MODULE,
249 },
250};
251
252MODULE_ALIAS("platform:lh7a404-ohci");
diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h
index 51facb985c84..04812b42fe6f 100644
--- a/drivers/usb/host/ohci.h
+++ b/drivers/usb/host/ohci.h
@@ -575,18 +575,8 @@ static inline void _ohci_writel (const struct ohci_hcd *ohci,
575#endif 575#endif
576} 576}
577 577
578#ifdef CONFIG_ARCH_LH7A404
579/* Marc Singer: at the time this code was written, the LH7A404
580 * had a problem reading the USB host registers. This
581 * implementation of the ohci_readl function performs the read
582 * twice as a work-around.
583 */
584#define ohci_readl(o,r) (_ohci_readl(o,r),_ohci_readl(o,r))
585#define ohci_writel(o,v,r) _ohci_writel(o,v,r)
586#else
587#define ohci_readl(o,r) _ohci_readl(o,r) 578#define ohci_readl(o,r) _ohci_readl(o,r)
588#define ohci_writel(o,v,r) _ohci_writel(o,v,r) 579#define ohci_writel(o,v,r) _ohci_writel(o,v,r)
589#endif
590 580
591 581
592/*-------------------------------------------------------------------------*/ 582/*-------------------------------------------------------------------------*/
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 6bafb51bb437..b57bc273b184 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -322,69 +322,6 @@ config FB_ARMCLCD
322 here and read <file:Documentation/kbuild/modules.txt>. The module 322 here and read <file:Documentation/kbuild/modules.txt>. The module
323 will be called amba-clcd. 323 will be called amba-clcd.
324 324
325choice
326
327 depends on FB_ARMCLCD && (ARCH_LH7A40X || ARCH_LH7952X)
328 prompt "LCD Panel"
329 default FB_ARMCLCD_SHARP_LQ035Q7DB02
330
331config FB_ARMCLCD_SHARP_LQ035Q7DB02_HRTFT
332 bool "LogicPD LCD 3.5\" QVGA w/HRTFT IC"
333 help
334 This is an implementation of the Sharp LQ035Q7DB02, a 3.5"
335 color QVGA, HRTFT panel. The LogicPD device includes
336 an integrated HRTFT controller IC.
337 The native resolution is 240x320.
338
339config FB_ARMCLCD_SHARP_LQ057Q3DC02
340 bool "LogicPD LCD 5.7\" QVGA"
341 help
342 This is an implementation of the Sharp LQ057Q3DC02, a 5.7"
343 color QVGA, TFT panel. The LogicPD device includes an
344 The native resolution is 320x240.
345
346config FB_ARMCLCD_SHARP_LQ64D343
347 bool "LogicPD LCD 6.4\" VGA"
348 help
349 This is an implementation of the Sharp LQ64D343, a 6.4"
350 color VGA, TFT panel. The LogicPD device includes an
351 The native resolution is 640x480.
352
353config FB_ARMCLCD_SHARP_LQ10D368
354 bool "LogicPD LCD 10.4\" VGA"
355 help
356 This is an implementation of the Sharp LQ10D368, a 10.4"
357 color VGA, TFT panel. The LogicPD device includes an
358 The native resolution is 640x480.
359
360
361config FB_ARMCLCD_SHARP_LQ121S1DG41
362 bool "LogicPD LCD 12.1\" SVGA"
363 help
364 This is an implementation of the Sharp LQ121S1DG41, a 12.1"
365 color SVGA, TFT panel. The LogicPD device includes an
366 The native resolution is 800x600.
367
368 This panel requires a clock rate may be an integer fraction
369 of the base LCDCLK frequency. The driver will select the
370 highest frequency available that is lower than the maximum
371 allowed. The panel may flicker if the clock rate is
372 slower than the recommended minimum.
373
374config FB_ARMCLCD_AUO_A070VW01_WIDE
375 bool "AU Optronics A070VW01 LCD 7.0\" WIDE"
376 help
377 This is an implementation of the AU Optronics, a 7.0"
378 WIDE Color. The native resolution is 234x480.
379
380config FB_ARMCLCD_HITACHI
381 bool "Hitachi Wide Screen 800x480"
382 help
383 This is an implementation of the Hitachi 800x480.
384
385endchoice
386
387
388config FB_ACORN 325config FB_ACORN
389 bool "Acorn VIDC support" 326 bool "Acorn VIDC support"
390 depends on (FB = y) && ARM && ARCH_ACORN 327 depends on (FB = y) && ARM && ARCH_ACORN