Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
f60852d2
Commit
f60852d2
authored
Mar 04, 2002
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Plain Diff
Merge
bk://bk.arm.linux.org.uk
into penguin.transmeta.com:/home/penguin/torvalds/repositories/kernel/linux
parents
a22655dc
ed78e24b
Changes
73
Show whitespace changes
Inline
Side-by-side
Showing
73 changed files
with
3300 additions
and
2685 deletions
+3300
-2685
arch/arm/config.in
arch/arm/config.in
+0
-1
arch/arm/kernel/armksyms.c
arch/arm/kernel/armksyms.c
+0
-4
arch/arm/kernel/process.c
arch/arm/kernel/process.c
+0
-3
arch/arm/mach-adifcc/mm.c
arch/arm/mach-adifcc/mm.c
+1
-1
arch/arm/mach-anakin/mm.c
arch/arm/mach-anakin/mm.c
+1
-1
arch/arm/mach-arc/mm.c
arch/arm/mach-arc/mm.c
+4
-3
arch/arm/mach-clps711x/autcpu12.c
arch/arm/mach-clps711x/autcpu12.c
+1
-1
arch/arm/mach-clps711x/edb7211-mm.c
arch/arm/mach-clps711x/edb7211-mm.c
+4
-4
arch/arm/mach-sa1100/adsbitsy.c
arch/arm/mach-sa1100/adsbitsy.c
+1
-1
arch/arm/mach-sa1100/assabet.c
arch/arm/mach-sa1100/assabet.c
+2
-2
arch/arm/mach-sa1100/cerf.c
arch/arm/mach-sa1100/cerf.c
+4
-4
arch/arm/mach-sa1100/empeg.c
arch/arm/mach-sa1100/empeg.c
+1
-1
arch/arm/mach-sa1100/flexanet.c
arch/arm/mach-sa1100/flexanet.c
+4
-4
arch/arm/mach-sa1100/freebird.c
arch/arm/mach-sa1100/freebird.c
+2
-2
arch/arm/mach-sa1100/graphicsclient.c
arch/arm/mach-sa1100/graphicsclient.c
+34
-143
arch/arm/mach-sa1100/graphicsmaster.c
arch/arm/mach-sa1100/graphicsmaster.c
+38
-43
arch/arm/mach-sa1100/h3600.c
arch/arm/mach-sa1100/h3600.c
+3
-3
arch/arm/mach-sa1100/huw_webpanel.c
arch/arm/mach-sa1100/huw_webpanel.c
+1
-1
arch/arm/mach-sa1100/itsy.c
arch/arm/mach-sa1100/itsy.c
+2
-2
arch/arm/mach-sa1100/jornada720.c
arch/arm/mach-sa1100/jornada720.c
+3
-3
arch/arm/mach-sa1100/lart.c
arch/arm/mach-sa1100/lart.c
+2
-2
arch/arm/mach-sa1100/nanoengine.c
arch/arm/mach-sa1100/nanoengine.c
+3
-3
arch/arm/mach-sa1100/neponset.c
arch/arm/mach-sa1100/neponset.c
+2
-2
arch/arm/mach-sa1100/omnimeter.c
arch/arm/mach-sa1100/omnimeter.c
+1
-1
arch/arm/mach-sa1100/pangolin.c
arch/arm/mach-sa1100/pangolin.c
+1
-1
arch/arm/mach-sa1100/pfs168.c
arch/arm/mach-sa1100/pfs168.c
+14
-14
arch/arm/mach-sa1100/pleb.c
arch/arm/mach-sa1100/pleb.c
+2
-2
arch/arm/mach-sa1100/simpad.c
arch/arm/mach-sa1100/simpad.c
+1
-1
arch/arm/mach-sa1100/stork.c
arch/arm/mach-sa1100/stork.c
+4
-4
arch/arm/mach-sa1100/system3.c
arch/arm/mach-sa1100/system3.c
+79
-57
arch/arm/mach-sa1100/victor.c
arch/arm/mach-sa1100/victor.c
+1
-1
arch/arm/mach-sa1100/xp860.c
arch/arm/mach-sa1100/xp860.c
+3
-3
arch/arm/mach-sa1100/yopy.c
arch/arm/mach-sa1100/yopy.c
+3
-3
arch/arm/mm/fault-armv.c
arch/arm/mm/fault-armv.c
+2
-1
arch/arm/mm/fault-common.c
arch/arm/mm/fault-common.c
+5
-1
arch/arm/mm/init.c
arch/arm/mm/init.c
+0
-35
arch/arm/mm/minicache.c
arch/arm/mm/minicache.c
+1
-1
arch/arm/mm/mm-armv.c
arch/arm/mm/mm-armv.c
+22
-4
arch/arm/mm/proc-xscale.S
arch/arm/mm/proc-xscale.S
+10
-9
drivers/pcmcia/Config.in
drivers/pcmcia/Config.in
+1
-0
drivers/pcmcia/Makefile
drivers/pcmcia/Makefile
+14
-11
drivers/pcmcia/sa1100.h
drivers/pcmcia/sa1100.h
+69
-25
drivers/pcmcia/sa1100_adsbitsy.c
drivers/pcmcia/sa1100_adsbitsy.c
+57
-166
drivers/pcmcia/sa1100_assabet.c
drivers/pcmcia/sa1100_assabet.c
+166
-91
drivers/pcmcia/sa1100_badge4.c
drivers/pcmcia/sa1100_badge4.c
+186
-0
drivers/pcmcia/sa1100_cerf.c
drivers/pcmcia/sa1100_cerf.c
+89
-64
drivers/pcmcia/sa1100_flexanet.c
drivers/pcmcia/sa1100_flexanet.c
+179
-15
drivers/pcmcia/sa1100_freebird.c
drivers/pcmcia/sa1100_freebird.c
+75
-31
drivers/pcmcia/sa1100_generic.c
drivers/pcmcia/sa1100_generic.c
+709
-640
drivers/pcmcia/sa1100_generic.h
drivers/pcmcia/sa1100_generic.h
+77
-0
drivers/pcmcia/sa1100_graphicsclient.c
drivers/pcmcia/sa1100_graphicsclient.c
+44
-12
drivers/pcmcia/sa1100_graphicsmaster.c
drivers/pcmcia/sa1100_graphicsmaster.c
+58
-165
drivers/pcmcia/sa1100_h3600.c
drivers/pcmcia/sa1100_h3600.c
+161
-111
drivers/pcmcia/sa1100_jornada720.c
drivers/pcmcia/sa1100_jornada720.c
+66
-159
drivers/pcmcia/sa1100_neponset.c
drivers/pcmcia/sa1100_neponset.c
+121
-225
drivers/pcmcia/sa1100_pangolin.c
drivers/pcmcia/sa1100_pangolin.c
+58
-29
drivers/pcmcia/sa1100_pfs168.c
drivers/pcmcia/sa1100_pfs168.c
+67
-160
drivers/pcmcia/sa1100_shannon.c
drivers/pcmcia/sa1100_shannon.c
+177
-0
drivers/pcmcia/sa1100_simpad.c
drivers/pcmcia/sa1100_simpad.c
+45
-17
drivers/pcmcia/sa1100_stork.c
drivers/pcmcia/sa1100_stork.c
+86
-34
drivers/pcmcia/sa1100_system3.c
drivers/pcmcia/sa1100_system3.c
+131
-0
drivers/pcmcia/sa1100_xp860.c
drivers/pcmcia/sa1100_xp860.c
+80
-177
drivers/pcmcia/sa1100_yopy.c
drivers/pcmcia/sa1100_yopy.c
+79
-31
drivers/pcmcia/sa1111_generic.c
drivers/pcmcia/sa1111_generic.c
+180
-0
drivers/pcmcia/sa1111_generic.h
drivers/pcmcia/sa1111_generic.h
+7
-0
fs/partitions/Config.in
fs/partitions/Config.in
+1
-1
include/asm-arm/arch-sa1100/graphicsclient.h
include/asm-arm/arch-sa1100/graphicsclient.h
+0
-9
include/asm-arm/arch-sa1100/irqs.h
include/asm-arm/arch-sa1100/irqs.h
+2
-1
include/asm-arm/arch-sa1100/system3.h
include/asm-arm/arch-sa1100/system3.h
+9
-9
include/asm-arm/pgalloc.h
include/asm-arm/pgalloc.h
+2
-118
include/asm-arm/pgtable.h
include/asm-arm/pgtable.h
+10
-3
include/asm-arm/proc-armv/pgalloc.h
include/asm-arm/proc-armv/pgalloc.h
+31
-8
include/asm-arm/proc-armv/pgtable.h
include/asm-arm/proc-armv/pgtable.h
+1
-1
No files found.
arch/arm/config.in
View file @
f60852d2
...
...
@@ -682,7 +682,6 @@ comment 'Kernel hacking'
bool 'Compile kernel without frame pointer' CONFIG_NO_FRAME_POINTER
bool 'Verbose user fault messages' CONFIG_DEBUG_USER
bool 'Include debugging information in kernel binary' CONFIG_DEBUG_INFO
dep_bool 'Disable pgtable cache' CONFIG_NO_PGT_CACHE $CONFIG_CPU_26
bool 'Kernel debugging' CONFIG_DEBUG_KERNEL
dep_bool ' Debug memory allocations' CONFIG_DEBUG_SLAB $CONFIG_DEBUG_KERNEL
...
...
arch/arm/kernel/armksyms.c
View file @
f60852d2
...
...
@@ -167,10 +167,6 @@ EXPORT_SYMBOL(__virt_to_bus);
#endif
#ifndef __bus_to_virt__is_a_macro
EXPORT_SYMBOL
(
__bus_to_virt
);
#endif
#ifndef CONFIG_NO_PGT_CACHE
EXPORT_SYMBOL
(
quicklists
);
#endif
/* string / mem functions */
...
...
arch/arm/kernel/process.c
View file @
f60852d2
...
...
@@ -95,9 +95,6 @@ void cpu_idle(void)
idle
();
leds_event
(
led_idle_end
);
schedule
();
#ifndef CONFIG_NO_PGT_CACHE
check_pgt_cache
();
#endif
}
}
...
...
arch/arm/mach-adifcc/mm.c
View file @
f60852d2
...
...
@@ -14,7 +14,7 @@
static
struct
map_desc
adifcc_io_desc
[]
__initdata
=
{
/* on-board devices */
{
0xff400000
,
0x00400000
,
0x00300000
,
DOMAIN_IO
,
1
,
1
,
0
,
0
},
{
0xff400000
,
0x00400000
,
0x00300000
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
LAST_DESC
};
...
...
arch/arm/mach-anakin/mm.c
View file @
f60852d2
...
...
@@ -20,7 +20,7 @@
static
struct
map_desc
anakin_io_desc
[]
__initdata
=
{
{
IO_BASE
,
IO_START
,
IO_SIZE
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
{
FLASH_BASE
,
FLASH_START
,
FLASH_SIZE
,
DOMAIN_IO
,
1
,
1
,
0
,
0
},
{
FLASH_BASE
,
FLASH_START
,
FLASH_SIZE
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
{
VGA_BASE
,
VGA_START
,
VGA_SIZE
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
LAST_DESC
};
...
...
arch/arm/mach-arc/mm.c
View file @
f60852d2
...
...
@@ -78,15 +78,16 @@ pgd_t *get_pgd_slow(struct mm_struct *mm)
if
(
!
new_pmd
)
goto
no_pmd
;
new_pte
=
pte_alloc
(
mm
,
new_pmd
,
0
);
new_pte
=
pte_alloc
_map
(
mm
,
new_pmd
,
0
);
if
(
!
new_pte
)
goto
no_pte
;
init_pgd
=
pgd_offset_k
(
0
);
init_pmd
=
pmd_offset
(
init_pgd
,
0
);
init_pte
=
pte_offset
(
init_pmd
,
0
);
init_pte
=
pte_offset_map_nested
(
init_pmd
,
0
);
set_pte
(
new_pte
,
*
init_pte
);
pte_unmap_nested
(
init_pte
);
pte_unmap
(
new_pte
);
/*
* most of the page table entries are zeroed
...
...
arch/arm/mach-clps711x/autcpu12.c
View file @
f60852d2
...
...
@@ -51,7 +51,7 @@ static struct map_desc autcpu12_io_desc[] __initdata = {
/* virtual, physical, length, domain, r, w, c, b */
/* memory-mapped extra io and CS8900A Ethernet chip */
/* ethernet chip */
{
AUTCPU12_VIRT_CS8900A
,
AUTCPU12_PHYS_CS8900A
,
SZ_1M
,
DOMAIN_IO
,
1
,
1
,
0
,
0
},
{
AUTCPU12_VIRT_CS8900A
,
AUTCPU12_PHYS_CS8900A
,
SZ_1M
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
LAST_DESC
};
...
...
arch/arm/mach-clps711x/edb7211-mm.c
View file @
f60852d2
...
...
@@ -56,12 +56,12 @@ static struct map_desc edb7211_io_desc[] __initdata = {
/* virtual, physical, length, domain, r, w, c, b */
/* memory-mapped extra keyboard row and CS8900A Ethernet chip */
{
EP7211_VIRT_EXTKBD
,
EP7211_PHYS_EXTKBD
,
MB1
,
DOMAIN_IO
,
1
,
1
,
0
,
0
},
{
EP7211_VIRT_CS8900A
,
EP7211_PHYS_CS8900A
,
MB1
,
DOMAIN_IO
,
1
,
1
,
0
,
0
},
{
EP7211_VIRT_EXTKBD
,
EP7211_PHYS_EXTKBD
,
MB1
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
{
EP7211_VIRT_CS8900A
,
EP7211_PHYS_CS8900A
,
MB1
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
/* flash banks */
{
EP7211_VIRT_FLASH1
,
EP7211_PHYS_FLASH1
,
MB1
*
8
,
DOMAIN_KERNEL
,
1
,
1
,
0
,
0
},
{
EP7211_VIRT_FLASH2
,
EP7211_PHYS_FLASH2
,
MB1
*
8
,
DOMAIN_KERNEL
,
1
,
1
,
0
,
0
},
{
EP7211_VIRT_FLASH1
,
EP7211_PHYS_FLASH1
,
MB1
*
8
,
DOMAIN_KERNEL
,
0
,
1
,
0
,
0
},
{
EP7211_VIRT_FLASH2
,
EP7211_PHYS_FLASH2
,
MB1
*
8
,
DOMAIN_KERNEL
,
0
,
1
,
0
,
0
},
LAST_DESC
};
...
...
arch/arm/mach-sa1100/adsbitsy.c
View file @
f60852d2
...
...
@@ -125,7 +125,7 @@ fixup_adsbitsy(struct machine_desc *desc, struct param_struct *params,
static
struct
map_desc
adsbitsy_io_desc
[]
__initdata
=
{
/* virtual physical length domain r w c b */
{
0xf4000000
,
0x18000000
,
0x00800000
,
DOMAIN_IO
,
1
,
1
,
0
,
0
},
/* SA1111 */
{
0xf4000000
,
0x18000000
,
0x00800000
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
/* SA1111 */
LAST_DESC
};
...
...
arch/arm/mach-sa1100/assabet.c
View file @
f60852d2
...
...
@@ -230,8 +230,8 @@ fixup_assabet(struct machine_desc *desc, struct param_struct *params,
static
struct
map_desc
assabet_io_desc
[]
__initdata
=
{
/* virtual physical length domain r w c b */
{
0xf1000000
,
0x12000000
,
0x00100000
,
DOMAIN_IO
,
1
,
1
,
0
,
0
},
/* Board Control Register */
{
0xf2800000
,
0x4b800000
,
0x00800000
,
DOMAIN_IO
,
1
,
1
,
0
,
0
},
/* MQ200 */
{
0xf1000000
,
0x12000000
,
0x00100000
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
/* Board Control Register */
{
0xf2800000
,
0x4b800000
,
0x00800000
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
/* MQ200 */
/* f3000000 - neponset system registers */
/* f4000000 - neponset SA1111 registers */
LAST_DESC
...
...
arch/arm/mach-sa1100/cerf.c
View file @
f60852d2
...
...
@@ -64,11 +64,11 @@ fixup_cerf(struct machine_desc *desc, struct param_struct *params,
static
struct
map_desc
cerf_io_desc
[]
__initdata
=
{
/* virtual physical length domain r w c b */
{
0xf0000000
,
0x08000000
,
0x00100000
,
DOMAIN_IO
,
1
,
1
,
0
,
0
},
/* Crystal Ethernet Chip */
{
0xf0000000
,
0x08000000
,
0x00100000
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
/* Crystal Ethernet Chip */
#ifdef CONFIG_SA1100_CERF_CPLD
{
0xf1000000
,
0x40000000
,
0x00100000
,
DOMAIN_IO
,
1
,
1
,
0
,
0
},
/* CPLD Chip */
{
0xf2000000
,
0x10000000
,
0x00100000
,
DOMAIN_IO
,
1
,
1
,
0
,
0
},
/* CerfPDA Bluetooth */
{
0xf3000000
,
0x18000000
,
0x00100000
,
DOMAIN_IO
,
1
,
1
,
0
,
0
},
/* CerfPDA Serial */
{
0xf1000000
,
0x40000000
,
0x00100000
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
/* CPLD Chip */
{
0xf2000000
,
0x10000000
,
0x00100000
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
/* CerfPDA Bluetooth */
{
0xf3000000
,
0x18000000
,
0x00100000
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
/* CerfPDA Serial */
#endif
LAST_DESC
};
...
...
arch/arm/mach-sa1100/empeg.c
View file @
f60852d2
...
...
@@ -31,7 +31,7 @@ fixup_empeg(struct machine_desc *desc, struct param_struct *params,
static
struct
map_desc
empeg_io_desc
[]
__initdata
=
{
/* virtual physical length domain r w c b */
{
EMPEG_FLASHBASE
,
0x00000000
,
0x00200000
,
DOMAIN_IO
,
1
,
1
,
0
,
0
},
/* Flash */
{
EMPEG_FLASHBASE
,
0x00000000
,
0x00200000
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
/* Flash */
LAST_DESC
};
...
...
arch/arm/mach-sa1100/flexanet.c
View file @
f60852d2
...
...
@@ -172,10 +172,10 @@ fixup_flexanet(struct machine_desc *desc, struct param_struct *params,
static
struct
map_desc
flexanet_io_desc
[]
__initdata
=
{
/* virtual physical length domain r w c b */
{
0xf0000000
,
0x10000000
,
0x00001000
,
DOMAIN_IO
,
1
,
1
,
0
,
0
},
/* Board Control Register */
{
0xf1000000
,
0x18000000
,
0x01000000
,
DOMAIN_IO
,
1
,
1
,
0
,
0
},
/* Ethernet controller */
{
0xD0000000
,
0x40000000
,
0x01000000
,
DOMAIN_IO
,
1
,
1
,
0
,
0
},
/* Instrument boards */
{
0xD8000000
,
0x48000000
,
0x01000000
,
DOMAIN_IO
,
1
,
1
,
0
,
0
},
/* External peripherals */
{
0xf0000000
,
0x10000000
,
0x00001000
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
/* Board Control Register */
{
0xf1000000
,
0x18000000
,
0x01000000
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
/* Ethernet controller */
{
0xD0000000
,
0x40000000
,
0x01000000
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
/* Instrument boards */
{
0xD8000000
,
0x48000000
,
0x01000000
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
/* External peripherals */
LAST_DESC
};
...
...
arch/arm/mach-sa1100/freebird.c
View file @
f60852d2
...
...
@@ -66,8 +66,8 @@ fixup_freebird(struct machine_desc *desc, struct param_struct *params,
static
struct
map_desc
freebird_io_desc
[]
__initdata
=
{
/* virtual physical length domain r w c b */
{
0xf0000000
,
0x12000000
,
0x00100000
,
DOMAIN_IO
,
1
,
1
,
0
,
0
},
/* Board Control Register */
{
0xf2000000
,
0x19000000
,
0x00100000
,
DOMAIN_IO
,
1
,
1
,
0
,
0
},
{
0xf0000000
,
0x12000000
,
0x00100000
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
/* Board Control Register */
{
0xf2000000
,
0x19000000
,
0x00100000
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
LAST_DESC
};
...
...
arch/arm/mach-sa1100/graphicsclient.c
View file @
f60852d2
...
...
@@ -32,67 +32,62 @@
* Handlers for GraphicsClient's external IRQ logic
*/
static
void
ADS_IRQ_demux
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
)
static
void
gc_irq_handler
(
unsigned
int
irq
,
struct
irqdesc
*
desc
,
struct
pt_regs
*
regs
)
{
int
i
;
unsigned
int
mask
;
while
((
mask
=
ADS_INT_ST1
|
(
ADS_INT_ST2
<<
8
)))
{
/* clear the parent IRQ */
GEDR
=
GPIO_GPIO0
;
while
(
(
irq
=
ADS_INT_ST1
|
(
ADS_INT_ST2
<<
8
))
){
for
(
i
=
0
;
i
<
16
;
i
++
)
if
(
irq
&
(
1
<<
i
)
)
do_IRQ
(
ADS_EXT_IRQ
(
i
),
regs
);
irq
=
ADS_EXT_IRQ
(
0
);
desc
=
irq_desc
+
irq
;
do
{
if
(
mask
&
1
)
desc
->
handle
(
irq
,
desc
,
regs
);
mask
>>=
1
;
irq
++
;
desc
++
;
}
while
(
mask
);
}
}
static
struct
irqaction
ADS_ext_irq
=
{
name:
"ADS_ext_IRQ"
,
handler:
ADS_IRQ_demux
,
flags:
SA_INTERRUPT
};
static
void
ADS_mask_and_ack_irq0
(
unsigned
int
irq
)
static
void
gc_mask_irq1
(
unsigned
int
irq
)
{
int
mask
=
(
1
<<
(
irq
-
ADS_EXT_IRQ
(
0
)));
ADS_INT_EN1
&=
~
mask
;
ADS_INT_ST1
=
mask
;
}
static
void
ADS_mask_irq0
(
unsigned
int
irq
)
{
ADS_INT_ST1
=
(
1
<<
(
irq
-
ADS_EXT_IRQ
(
0
)));
}
static
void
ADS_unmask_irq0
(
unsigned
int
irq
)
static
void
gc_unmask_irq1
(
unsigned
int
irq
)
{
ADS_INT_EN1
|=
(
1
<<
(
irq
-
ADS_EXT_IRQ
(
0
)));
}
static
struct
irqchip
ADS0
_chip
=
{
ack:
ADS_mask_and_ack_irq0
,
mask:
ADS_mask_irq0
,
unmask:
ADS_unmask_irq0
,
static
struct
irqchip
gc_irq1
_chip
=
{
ack:
gc_mask_irq1
,
mask:
gc_mask_irq1
,
unmask:
gc_unmask_irq1
,
};
static
void
ADS_mask_and_ack_irq1
(
unsigned
int
irq
)
static
void
gc_mask_irq2
(
unsigned
int
irq
)
{
int
mask
=
(
1
<<
(
irq
-
ADS_EXT_IRQ
(
8
)));
ADS_INT_EN2
&=
~
mask
;
ADS_INT_ST2
=
mask
;
}
static
void
ADS_mask_irq1
(
unsigned
int
irq
)
{
ADS_INT_ST2
=
(
1
<<
(
irq
-
ADS_EXT_IRQ
(
8
)));
}
static
void
ADS_unmask_irq1
(
unsigned
int
irq
)
static
void
gc_unmask_irq2
(
unsigned
int
irq
)
{
ADS_INT_EN2
|=
(
1
<<
(
irq
-
ADS_EXT_IRQ
(
8
)));
}
static
struct
irqchip
ADS1
_chip
=
{
ack:
ADS_mask_and_ack_irq1
,
mask:
ADS_mask_irq1
,
unmask:
ADS_unmask_irq1
,
static
struct
irqchip
gc_irq2
_chip
=
{
ack:
gc_mask_irq2
,
mask:
gc_mask_irq2
,
unmask:
gc_unmask_irq2
,
};
static
void
__init
graphicsclient_init_irq
(
void
)
...
...
@@ -105,22 +100,23 @@ static void __init graphicsclient_init_irq(void)
/* disable all IRQs */
ADS_INT_EN1
=
0
;
ADS_INT_EN2
=
0
;
/* clear all IRQs */
ADS_INT_ST1
=
0xff
;
ADS_INT_ST2
=
0xff
;
for
(
irq
=
ADS_EXT_IRQ
(
0
);
irq
<=
ADS_EXT_IRQ
(
7
);
irq
++
)
{
set_irq_chip
(
irq
,
&
ADS0
_chip
);
set_irq_chip
(
irq
,
&
gc_irq1
_chip
);
set_irq_handler
(
irq
,
do_level_IRQ
);
set_irq_flags
(
irq
,
IRQF_VALID
|
IRQF_PROBE
);
}
for
(
irq
=
ADS_EXT_IRQ
(
8
);
irq
<=
ADS_EXT_IRQ
(
15
);
irq
++
)
{
set_irq_chip
(
irq
,
&
ADS1
_chip
);
set_irq_chip
(
irq
,
&
gc_irq2
_chip
);
set_irq_handler
(
irq
,
do_level_IRQ
);
set_irq_flags
(
irq
,
IRQF_VALID
|
IRQF_PROBE
);
}
set_
GPIO_IRQ_edge
(
GPIO_GPIO0
,
GPIO_FALLING_EDGE
);
set
up_arm_irq
(
IRQ_GPIO0
,
&
ADS_ext_irq
);
set_
irq_type
(
IRQ_GPIO0
,
IRQT_FALLING
);
set
_irq_chained_handler
(
IRQ_GPIO0
,
gc_irq_handler
);
}
...
...
@@ -148,111 +144,6 @@ static struct map_desc graphicsclient_io_desc[] __initdata = {
LAST_DESC
};
static
struct
gc_uart_ctrl_data_t
gc_uart_ctrl_data
[]
=
{
{
GPIO_GC_UART0_CTS
,
0
,
NULL
,
NULL
},
{
GPIO_GC_UART1_CTS
,
0
,
NULL
,
NULL
},
{
GPIO_GC_UART2_CTS
,
0
,
NULL
,
NULL
}
};
#error Old code. Someone needs to decide what to do with this
#if 0
static void
graphicsclient_cts_intr(int irq, void *dev_id, struct pt_regs *regs)
{
struct gc_uart_ctrl_data_t * uart_data = (struct gc_uart_ctrl_data_t *)dev_id;
int cts = !(GPLR & uart_data->cts_gpio);
/* NOTE: I supose that we will no get any interrupt
if the GPIO is not changed, so maybe
the cts_prev_state can be removed ... */
if (cts != uart_data->cts_prev_state) {
uart_data->cts_prev_state = cts;
uart_handle_cts_change(uart_data->info, cts);
}
}
static int
graphicsclient_register_cts_intr(int gpio, int irq,
struct gc_uart_ctrl_data_t *uart_data)
{
int ret = 0;
set_GPIO_IRQ_edge(gpio, GPIO_BOTH_EDGES);
ret = request_irq(irq, graphicsclient_cts_intr,
0, "GC RS232 CTS", uart_data);
if (ret) {
printk(KERN_ERR "uart_open: failed to register CTS irq (%d)\n",
ret);
free_irq(irq, uart_data);
}
return ret;
}
static int
graphicsclient_uart_open(struct uart_port *port, struct uart_info *info)
{
int ret = 0;
if (port->mapbase == _Ser1UTCR0) {
Ser1SDCR0 |= SDCR0_UART;
/* Set RTS Output */
GPSR = GPIO_GC_UART0_RTS;
gc_uart_ctrl_data[0].cts_prev_state = 0;
gc_uart_ctrl_data[0].info = info;
gc_uart_ctrl_data[0].port = port;
/* register uart0 CTS irq */
ret = graphicsclient_register_cts_intr(GPIO_GC_UART0_CTS,
IRQ_GC_UART0_CTS,
&gc_uart_ctrl_data[0]);
} else if (port->mapbase == _Ser2UTCR0) {
Ser2UTCR4 = Ser2HSCR0 = 0;
/* Set RTS Output */
GPSR = GPIO_GC_UART1_RTS;
gc_uart_ctrl_data[1].cts_prev_state = 0;
gc_uart_ctrl_data[1].info = info;
gc_uart_ctrl_data[1].port = port;
/* register uart1 CTS irq */
ret = graphicsclient_register_cts_intr(GPIO_GC_UART1_CTS,
IRQ_GC_UART1_CTS,
&gc_uart_ctrl_data[1]);
} else if (port->mapbase == _Ser3UTCR0) {
/* Set RTS Output */
GPSR = GPIO_GC_UART2_RTS;
gc_uart_ctrl_data[2].cts_prev_state = 0;
gc_uart_ctrl_data[2].info = info;
gc_uart_ctrl_data[2].port = port;
/* register uart2 CTS irq */
ret = graphicsclient_register_cts_intr(GPIO_GC_UART2_CTS,
IRQ_GC_UART2_CTS,
&gc_uart_ctrl_data[2]);
}
return ret;
}
static int
graphicsclient_uart_close(struct uart_port *port, struct uart_info *info)
{
if (port->mapbase == _Ser1UTCR0) {
free_irq(IRQ_GC_UART0_CTS, &gc_uart_ctrl_data[0]);
} else if (port->mapbase == _Ser2UTCR0) {
free_irq(IRQ_GC_UART1_CTS, &gc_uart_ctrl_data[1]);
} else if (port->mapbase == _Ser3UTCR0) {
free_irq(IRQ_GC_UART2_CTS, &gc_uart_ctrl_data[2]);
}
return 0;
}
#endif
static
u_int
graphicsclient_get_mctrl
(
struct
uart_port
*
port
)
{
u_int
result
=
TIOCM_CD
|
TIOCM_DSR
;
...
...
arch/arm/mach-sa1100/graphicsmaster.c
View file @
f60852d2
...
...
@@ -93,68 +93,62 @@ __initcall(graphicsmaster_init);
* Handlers for GraphicsMaster's external IRQ logic
*/
static
void
ADS_IRQ_demux
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
)
static
void
gm_irq_handler
(
unsigned
int
irq
,
struct
irqdesc
*
desc
,
struct
pt_regs
*
regs
)
{
int
i
;
while
(
(
irq
=
ADS_INT_ST1
|
(
ADS_INT_ST2
<<
8
))
){
for
(
i
=
0
;
i
<
16
;
i
++
)
if
(
irq
&
(
1
<<
i
)
)
{
do_IRQ
(
ADS_EXT_IRQ
(
i
),
regs
);
}
unsigned
int
mask
;
while
((
mask
=
ADS_INT_ST1
|
(
ADS_INT_ST2
<<
8
)))
{
/* clear the parent IRQ */
GEDR
=
GPIO_GPIO0
;
irq
=
ADS_EXT_IRQ
(
0
);
desc
=
irq_desc
+
irq
;
do
{
if
(
mask
&
1
)
desc
->
handle
(
irq
,
desc
,
regs
);
mask
>>=
1
;
irq
++
;
desc
++
;
}
while
(
mask
);
}
}
static
struct
irqaction
ADS_ext_irq
=
{
name:
"ADS_ext_IRQ"
,
handler:
ADS_IRQ_demux
,
flags:
SA_INTERRUPT
};
static
void
ADS_mask_and_ack_irq0
(
unsigned
int
irq
)
static
void
gm_mask_irq1
(
unsigned
int
irq
)
{
int
mask
=
(
1
<<
(
irq
-
ADS_EXT_IRQ
(
0
)));
ADS_INT_EN1
&=
~
mask
;
ADS_INT_ST1
=
mask
;
}
static
void
ADS_mask_irq0
(
unsigned
int
irq
)
{
ADS_INT_ST1
=
(
1
<<
(
irq
-
ADS_EXT_IRQ
(
0
)));
}
static
void
ADS_unmask_irq0
(
unsigned
int
irq
)
static
void
gm_unmask_irq1
(
unsigned
int
irq
)
{
ADS_INT_EN1
|=
(
1
<<
(
irq
-
ADS_EXT_IRQ
(
0
)));
}
static
struct
irqchip
ADS0
_chip
=
{
ack:
ADS_mask_and_ack_irq0
,
mask:
ADS_mask_irq0
,
unmask:
ADS_unmask_irq0
,
static
struct
irqchip
gm_irq1
_chip
=
{
ack:
gm_mask_irq1
,
mask:
gm_mask_irq1
,
unmask:
gm_unmask_irq1
,
};
static
void
ADS_mask_and_ack_irq1
(
unsigned
int
irq
)
static
void
gm_mask_irq2
(
unsigned
int
irq
)
{
int
mask
=
(
1
<<
(
irq
-
ADS_EXT_IRQ
(
8
)));
ADS_INT_EN2
&=
~
mask
;
ADS_INT_ST2
=
mask
;
}
static
void
ADS_mask_irq1
(
unsigned
int
irq
)
{
ADS_INT_ST2
=
(
1
<<
(
irq
-
ADS_EXT_IRQ
(
8
)));
}
static
void
ADS_unmask_irq1
(
unsigned
int
irq
)
static
void
gm_unmask_irq2
(
unsigned
int
irq
)
{
ADS_INT_EN2
|=
(
1
<<
(
irq
-
ADS_EXT_IRQ
(
8
)));
}
static
struct
irqchip
ADS1
_chip
=
{
ack:
ADS_mask_irq1
,
mask:
ADS_mask_irq1
,
unmask:
ADS_mask_irq1
,
static
struct
irqchip
gm_irq2
_chip
=
{
ack:
gm_mask_irq2
,
mask:
gm_mask_irq2
,
unmask:
gm_unmask_irq2
,
};
static
void
__init
graphicsmaster_init_irq
(
void
)
...
...
@@ -167,22 +161,23 @@ static void __init graphicsmaster_init_irq(void)
/* disable all IRQs */
ADS_INT_EN1
=
0
;
ADS_INT_EN2
=
0
;
/* clear all IRQs */
ADS_INT_ST1
=
0xff
;
ADS_INT_ST2
=
0xff
;
for
(
irq
=
ADS_EXT_IRQ
(
0
);
irq
<=
ADS_EXT_IRQ
(
7
);
irq
++
)
{
set_irq_chip
(
irq
,
&
ADS0
_chip
);
set_irq_chip
(
irq
,
&
gm_irq1
_chip
);
set_irq_handler
(
irq
,
do_level_IRQ
);
set_irq_flags
(
irq
,
IRQF_PROBE
|
IRQF_VALID
);
}
for
(
irq
=
ADS_EXT_IRQ
(
8
);
irq
<=
ADS_EXT_IRQ
(
15
);
irq
++
)
{
set_irq_chip
(
irq
,
&
ADS1
_chip
);
set_irq_chip
(
irq
,
&
gm_irq2
_chip
);
set_irq_handler
(
irq
,
do_level_IRQ
);
set_irq_flags
(
irq
,
IRQF_PROBE
|
IRQF_VALID
);
}
set_
GPIO_IRQ_edge
(
GPIO_GPIO0
,
GPIO_FALLING_EDGE
);
set
up_arm_irq
(
IRQ_GPIO0
,
&
ADS_ext_irq
);
set_
irq_type
(
IRQ_GPIO0
,
IRQT_FALLING
);
set
_irq_chained_handler
(
IRQ_GPIO0
,
gm_irq_handler
);
}
...
...
@@ -206,9 +201,9 @@ fixup_graphicsmaster(struct machine_desc *desc, struct param_struct *params,
static
struct
map_desc
graphicsmaster_io_desc
[]
__initdata
=
{
/* virtual physical length domain r w c b */
{
0xf0000000
,
0x10000000
,
0x00400000
,
DOMAIN_IO
,
1
,
1
,
0
,
0
},
/* CPLD */
{
0xf1000000
,
0x40000000
,
0x00400000
,
DOMAIN_IO
,
1
,
1
,
0
,
0
},
/* CAN */
{
0xf4000000
,
0x18000000
,
0x00800000
,
DOMAIN_IO
,
1
,
1
,
0
,
0
},
/* SA-1111 */
{
0xf0000000
,
0x10000000
,
0x00400000
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
/* CPLD */
{
0xf1000000
,
0x40000000
,
0x00400000
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
/* CAN */
{
0xf4000000
,
0x18000000
,
0x00800000
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
/* SA-1111 */
LAST_DESC
};
...
...
arch/arm/mach-sa1100/h3600.c
View file @
f60852d2
...
...
@@ -489,9 +489,9 @@ static struct sa1100_port_fns h3600_port_fns __initdata = {
static
struct
map_desc
h3600_io_desc
[]
__initdata
=
{
/* virtual physical length domain r w c b */
{
H3600_EGPIO_VIRT
,
0x49000000
,
0x01000000
,
DOMAIN_IO
,
1
,
1
,
0
,
0
},
/* EGPIO 0 CS#5 */
{
H3600_BANK_2_VIRT
,
0x10000000
,
0x02800000
,
DOMAIN_IO
,
1
,
1
,
0
,
0
},
/* static memory bank 2 CS#2 */
{
H3600_BANK_4_VIRT
,
0x40000000
,
0x00800000
,
DOMAIN_IO
,
1
,
1
,
0
,
0
},
/* static memory bank 4 CS#4 */
{
H3600_EGPIO_VIRT
,
0x49000000
,
0x01000000
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
/* EGPIO 0 CS#5 */
{
H3600_BANK_2_VIRT
,
0x10000000
,
0x02800000
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
/* static memory bank 2 CS#2 */
{
H3600_BANK_4_VIRT
,
0x40000000
,
0x00800000
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
/* static memory bank 4 CS#4 */
LAST_DESC
};
...
...
arch/arm/mach-sa1100/huw_webpanel.c
View file @
f60852d2
...
...
@@ -77,7 +77,7 @@ fixup_huw_webpanel(struct machine_desc *desc, struct param_struct *params,
**/
static
struct
map_desc
huw_webpanel_io_desc
[]
__initdata
=
{
/* virtual physical length domain r w c b */
{
0xf0000000
,
0xc1fb8000
,
0x00048000
,
DOMAIN_IO
,
1
,
1
,
0
,
0
},
/* Parameter */
{
0xf0000000
,
0xc1fb8000
,
0x00048000
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
/* Parameter */
{
0xf1000000
,
0x18000000
,
0x00100000
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
/* Paules CS3, write only */
LAST_DESC
};
...
...
arch/arm/mach-sa1100/itsy.c
View file @
f60852d2
...
...
@@ -31,8 +31,8 @@ fixup_itsy(struct machine_desc *desc, struct param_struct *params,
likely wrong. */
static
struct
map_desc
itsy_io_desc
[]
__initdata
=
{
/* virtual physical length domain r w c b */
{
0xe8000000
,
0x00000000
,
0x02000000
,
DOMAIN_IO
,
1
,
1
,
0
,
0
},
/* Flash bank 0 */
{
0xf0000000
,
0x49000000
,
0x01000000
,
DOMAIN_IO
,
1
,
1
,
0
,
0
},
/* EGPIO 0 */
{
0xe8000000
,
0x00000000
,
0x02000000
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
/* Flash bank 0 */
{
0xf0000000
,
0x49000000
,
0x01000000
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
/* EGPIO 0 */
LAST_DESC
};
...
...
arch/arm/mach-sa1100/jornada720.c
View file @
f60852d2
...
...
@@ -66,9 +66,9 @@ fixup_jornada720(struct machine_desc *desc, struct param_struct *params,
static
struct
map_desc
jornada720_io_desc
[]
__initdata
=
{
/* virtual physical length domain r w c b */
{
0xf0000000
,
0x48000000
,
0x00100000
,
DOMAIN_IO
,
1
,
1
,
0
,
0
},
/* Epson registers */
{
0xf1000000
,
0x48200000
,
0x00100000
,
DOMAIN_IO
,
1
,
1
,
0
,
0
},
/* Epson frame buffer */
{
0xf4000000
,
0x40000000
,
0x00100000
,
DOMAIN_IO
,
1
,
1
,
0
,
0
},
/* SA-1111 */
{
0xf0000000
,
0x48000000
,
0x00100000
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
/* Epson registers */
{
0xf1000000
,
0x48200000
,
0x00100000
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
/* Epson frame buffer */
{
0xf4000000
,
0x40000000
,
0x00100000
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
/* SA-1111 */
LAST_DESC
};
...
...
arch/arm/mach-sa1100/lart.c
View file @
f60852d2
...
...
@@ -18,8 +18,8 @@
static
struct
map_desc
lart_io_desc
[]
__initdata
=
{
/* virtual physical length domain r w c b */
{
0xe8000000
,
0x00000000
,
0x00400000
,
DOMAIN_IO
,
1
,
1
,
0
,
0
},
/* main flash memory */
{
0xec000000
,
0x08000000
,
0x00400000
,
DOMAIN_IO
,
1
,
1
,
0
,
0
},
/* main flash, alternative location */
{
0xe8000000
,
0x00000000
,
0x00400000
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
/* main flash memory */
{
0xec000000
,
0x08000000
,
0x00400000
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
/* main flash, alternative location */
LAST_DESC
};
...
...
arch/arm/mach-sa1100/nanoengine.c
View file @
f60852d2
...
...
@@ -34,9 +34,9 @@ fixup_nanoengine(struct machine_desc *desc, struct param_struct *params,
static
struct
map_desc
nanoengine_io_desc
[]
__initdata
=
{
/* virtual physical length domain r w c b */
{
0xe8000000
,
0x00000000
,
0x02000000
,
DOMAIN_IO
,
1
,
1
,
0
,
0
},
/* Flash bank 0 */
{
0xf0000000
,
0x10000000
,
0x00100000
,
DOMAIN_IO
,
1
,
1
,
0
,
0
},
/* System Registers */
{
0xf1000000
,
0x18A00000
,
0x00100000
,
DOMAIN_IO
,
1
,
1
,
0
,
0
},
/* Internal PCI Config Space */
{
0xe8000000
,
0x00000000
,
0x02000000
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
/* Flash bank 0 */
{
0xf0000000
,
0x10000000
,
0x00100000
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
/* System Registers */
{
0xf1000000
,
0x18A00000
,
0x00100000
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
/* Internal PCI Config Space */
LAST_DESC
};
...
...
arch/arm/mach-sa1100/neponset.c
View file @
f60852d2
...
...
@@ -184,8 +184,8 @@ __initcall(neponset_init);
static
struct
map_desc
neponset_io_desc
[]
__initdata
=
{
/* virtual physical length domain r w c b */
{
0xf3000000
,
0x10000000
,
0x00100000
,
DOMAIN_IO
,
1
,
1
,
0
,
0
},
/* System Registers */
{
0xf4000000
,
0x40000000
,
0x00100000
,
DOMAIN_IO
,
1
,
1
,
0
,
0
},
/* SA-1111 */
{
0xf3000000
,
0x10000000
,
0x00100000
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
/* System Registers */
{
0xf4000000
,
0x40000000
,
0x00100000
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
/* SA-1111 */
LAST_DESC
};
...
...
arch/arm/mach-sa1100/omnimeter.c
View file @
f60852d2
...
...
@@ -54,7 +54,7 @@ fixup_omnimeter(struct machine_desc *desc, struct param_struct *params,
static
struct
map_desc
omnimeter_io_desc
[]
__initdata
=
{
/* virtual physical length domain r w c b */
{
0xd2000000
,
0x10000000
,
0x02000000
,
DOMAIN_IO
,
1
,
1
,
0
,
0
},
/* TS */
{
0xd2000000
,
0x10000000
,
0x02000000
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
/* TS */
LAST_DESC
};
...
...
arch/arm/mach-sa1100/pangolin.c
View file @
f60852d2
...
...
@@ -30,7 +30,7 @@ fixup_pangolin(struct machine_desc *desc, struct param_struct *params,
static
struct
map_desc
pangolin_io_desc
[]
__initdata
=
{
/* virtual physical length domain r w c b */
{
0xf2800000
,
0x4b800000
,
0x00800000
,
DOMAIN_IO
,
1
,
1
,
0
,
0
},
/* MQ200 */
{
0xf2800000
,
0x4b800000
,
0x00800000
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
/* MQ200 */
LAST_DESC
};
...
...
arch/arm/mach-sa1100/pfs168.c
View file @
f60852d2
...
...
@@ -103,20 +103,20 @@ fixup_pfs168(struct machine_desc *desc, struct param_struct *params,
static
struct
map_desc
pfs168_io_desc
[]
__initdata
=
{
/* virtual physical length domain r w c b */
{
0xe8000000
,
0x00000000
,
0x02000000
,
DOMAIN_IO
,
1
,
1
,
0
,
0
},
/* Flash bank 0 */
{
0xf0000000
,
0x10000000
,
0x00001000
,
DOMAIN_IO
,
1
,
1
,
0
,
0
},
/* 16C752 DUART port A (COM5) */
{
0xf0001000
,
0x10800000
,
0x00001000
,
DOMAIN_IO
,
1
,
1
,
0
,
0
},
/* 16C752 DUART port B (COM6) */
{
0xf0002000
,
0x11000000
,
0x00001000
,
DOMAIN_IO
,
1
,
1
,
0
,
0
},
/* COM1 RTS control (SYSC1RTS) */
{
0xf0003000
,
0x11400000
,
0x00001000
,
DOMAIN_IO
,
1
,
1
,
0
,
0
},
/* Status LED control (SYSLED) */
{
0xf0004000
,
0x11800000
,
0x00001000
,
DOMAIN_IO
,
1
,
1
,
0
,
0
},
/* DTMF code read (SYSDTMF) */
{
0xf0005000
,
0x11c00000
,
0x00001000
,
DOMAIN_IO
,
1
,
1
,
0
,
0
},
/* LCD configure, enable (SYSLCDDE) */
{
0xf0006000
,
0x12000000
,
0x00001000
,
DOMAIN_IO
,
1
,
1
,
0
,
0
},
/* COM1 DSR and motion sense (SYSC1DSR) */
{
0xf0007000
,
0x12800000
,
0x00001000
,
DOMAIN_IO
,
1
,
1
,
0
,
0
},
/* COM3 xmit enable (SYSC3TEN) */
{
0xf0008000
,
0x13000000
,
0x00001000
,
DOMAIN_IO
,
1
,
1
,
0
,
0
},
/* Control register A (SYSCTLA) */
{
0xf0009000
,
0x13800000
,
0x00001000
,
DOMAIN_IO
,
1
,
1
,
0
,
0
},
/* Control register B (SYSCTLB) */
{
0xf000a000
,
0x18000000
,
0x00001000
,
DOMAIN_IO
,
1
,
1
,
0
,
0
},
/* SMC91C96 */
{
0xf2800000
,
0x4b800000
,
0x00800000
,
DOMAIN_IO
,
1
,
1
,
0
,
0
},
/* MQ200 */
{
0xf4000000
,
0x40000000
,
0x00100000
,
DOMAIN_IO
,
1
,
1
,
0
,
0
},
/* SA-1111 */
{
0xe8000000
,
0x00000000
,
0x02000000
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
/* Flash bank 0 */
{
0xf0000000
,
0x10000000
,
0x00001000
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
/* 16C752 DUART port A (COM5) */
{
0xf0001000
,
0x10800000
,
0x00001000
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
/* 16C752 DUART port B (COM6) */
{
0xf0002000
,
0x11000000
,
0x00001000
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
/* COM1 RTS control (SYSC1RTS) */
{
0xf0003000
,
0x11400000
,
0x00001000
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
/* Status LED control (SYSLED) */
{
0xf0004000
,
0x11800000
,
0x00001000
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
/* DTMF code read (SYSDTMF) */
{
0xf0005000
,
0x11c00000
,
0x00001000
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
/* LCD configure, enable (SYSLCDDE) */
{
0xf0006000
,
0x12000000
,
0x00001000
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
/* COM1 DSR and motion sense (SYSC1DSR) */
{
0xf0007000
,
0x12800000
,
0x00001000
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
/* COM3 xmit enable (SYSC3TEN) */
{
0xf0008000
,
0x13000000
,
0x00001000
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
/* Control register A (SYSCTLA) */
{
0xf0009000
,
0x13800000
,
0x00001000
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
/* Control register B (SYSCTLB) */
{
0xf000a000
,
0x18000000
,
0x00001000
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
/* SMC91C96 */
{
0xf2800000
,
0x4b800000
,
0x00800000
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
/* MQ200 */
{
0xf4000000
,
0x40000000
,
0x00100000
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
/* SA-1111 */
LAST_DESC
};
...
...
arch/arm/mach-sa1100/pleb.c
View file @
f60852d2
...
...
@@ -35,8 +35,8 @@ fixup_pleb(struct machine_desc *desc, struct param_struct *params,
static
struct
map_desc
pleb_io_desc
[]
__initdata
=
{
/* virtual physical length domain r w c b */
{
0xe8000000
,
0x00000000
,
0x00400000
,
DOMAIN_IO
,
1
,
1
,
0
,
0
},
/* main flash memory */
{
0xe8400000
,
0x08000000
,
0x00400000
,
DOMAIN_IO
,
1
,
1
,
0
,
0
},
/* main flash, alternative location */
{
0xe8000000
,
0x00000000
,
0x00400000
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
/* main flash memory */
{
0xe8400000
,
0x08000000
,
0x00400000
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
/* main flash, alternative location */
LAST_DESC
};
...
...
arch/arm/mach-sa1100/simpad.c
View file @
f60852d2
...
...
@@ -58,7 +58,7 @@ fixup_simpad(struct machine_desc *desc, struct param_struct *params,
static
struct
map_desc
simpad_io_desc
[]
__initdata
=
{
/* virtual physical length domain r w c b */
{
0xf2800000
,
0x4b800000
,
0x00800000
,
DOMAIN_IO
,
1
,
1
,
0
,
0
},
/* MQ200 */
{
0xf2800000
,
0x4b800000
,
0x00800000
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
/* MQ200 */
{
0xf1000000
,
0x18000000
,
0x00100000
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
/* Paules CS3, write only */
LAST_DESC
};
...
...
arch/arm/mach-sa1100/stork.c
View file @
f60852d2
...
...
@@ -305,10 +305,10 @@ stork_kbd_unexpected_up(unsigned char code)
struct
map_desc
stork_io_desc
[]
__initdata
=
{
/* virtual physical length domain r w c b */
{
0xe8000000
,
0x00000000
,
0x02000000
,
DOMAIN_IO
,
1
,
1
,
0
,
0
},
/* Flash bank 0 */
{
STORK_VM_BASE_CS1
,
STORK_VM_OFF_CS1
,
0x01000000
,
DOMAIN_IO
,
1
,
1
,
0
,
0
},
/* EGPIO 0 */
{
0xf1000000
,
0x10000000
,
0x02800000
,
DOMAIN_IO
,
1
,
1
,
0
,
0
},
/* static memory bank 2 */
{
0xf3800000
,
0x40000000
,
0x00800000
,
DOMAIN_IO
,
1
,
1
,
0
,
0
},
/* static memory bank 4 */
{
0xe8000000
,
0x00000000
,
0x02000000
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
/* Flash bank 0 */
{
STORK_VM_BASE_CS1
,
STORK_VM_OFF_CS1
,
0x01000000
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
/* EGPIO 0 */
{
0xf1000000
,
0x10000000
,
0x02800000
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
/* static memory bank 2 */
{
0xf3800000
,
0x40000000
,
0x00800000
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
/* static memory bank 4 */
LAST_DESC
};
...
...
arch/arm/mach-sa1100/system3.c
View file @
f60852d2
...
...
@@ -58,6 +58,7 @@
#include "generic.h"
#include "sa1111.h"
#include <asm/hardware/sa1111.h>
#define DEBUG 1
...
...
@@ -74,19 +75,17 @@
/* init funcs */
static
void
__init
fixup_system3
(
struct
machine_desc
*
desc
,
struct
param_struct
*
params
,
char
**
cmdline
,
struct
meminfo
*
mi
);
static
void
__init
get_system3_scr
(
void
);
static
int
__init
system3_init
(
void
);
static
void
__init
system3_init_irq
(
void
);
static
void
__init
system3_map_io
(
void
);
static
void
system3_IRQ_demux
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
);
static
int
system3_get_mctrl
(
struct
uart_port
*
port
);
static
u_int
system3_get_mctrl
(
struct
uart_port
*
port
);
static
void
system3_set_mctrl
(
struct
uart_port
*
port
,
u_int
mctrl
);
static
void
system3_uart_pm
(
struct
uart_port
*
port
,
u_int
state
,
u_int
oldstate
);
static
int
sdram_notifier
(
struct
notifier_block
*
nb
,
unsigned
long
event
,
void
*
data
);
static
int
system3_lcd_power
(
int
on
);
static
int
system3_backlight_power
(
int
on
);
static
void
system3_lcd_power
(
int
on
);
static
void
system3_backlight_power
(
int
on
);
extern
void
convert_to_tag_list
(
struct
param_struct
*
params
,
int
mem_init
);
...
...
@@ -101,9 +100,9 @@ extern void convert_to_tag_list(struct param_struct *params, int mem_init);
static
struct
map_desc
system3_io_desc
[]
__initdata
=
{
/* virtual physical length domain r w c b */
{
0xe8000000
,
0x00000000
,
0x01000000
,
DOMAIN_IO
,
1
,
1
,
0
,
0
},
/* Flash bank 0 */
{
0xf3000000
,
0x10000000
,
0x00100000
,
DOMAIN_IO
,
1
,
1
,
0
,
0
},
/* System Registers */
{
0xf4000000
,
0x40000000
,
0x00100000
,
DOMAIN_IO
,
1
,
1
,
0
,
0
},
/* SA-1111 */
{
0xe8000000
,
0x00000000
,
0x01000000
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
/* Flash bank 0 */
{
0xf3000000
,
PT_CPLD_BASE
,
0x00100000
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
/* System Registers */
{
0xf4000000
,
PT_SA1111_BASE
,
0x00100000
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
/* SA-1111 */
LAST_DESC
};
...
...
@@ -113,12 +112,6 @@ static struct sa1100_port_fns system3_port_fns __initdata = {
pm:
system3_uart_pm
,
};
static
struct
irqaction
system3_irq
=
{
name:
"PT Digital Board SA1111 IRQ"
,
handler:
system3_IRQ_demux
,
flags:
SA_INTERRUPT
};
static
struct
notifier_block
system3_clkchg_block
=
{
notifier_call:
sdram_notifier
,
};
...
...
@@ -145,56 +138,82 @@ static void __init system3_map_io(void)
/*********************************************************************
* Install IRQ handler
*/
static
void
system3_IRQ_demux
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
)
static
void
system3_irq_handler
(
unsigned
int
irq
,
struct
irqdesc
*
desc
,
struct
pt_regs
*
regs
)
{
u_char
irr
;
for
(;;){
//irr = PTCPLD_REG_IRQSR & (PT_IRQ_LAN | PT_IRQ_USAR | PT_IRQ_SA1111);
irr
=
PT_IRQSR
&
(
PT_IRQ_LAN
|
PT_IRQ_SA1111
);
//DPRINTK( "irq=%d, desc=%p, regs=%p\n", irq, desc, regs );
irr
^=
(
PT_IRQ_LAN
);
if
(
!
irr
)
break
;
while
(
1
)
{
struct
irqdesc
*
d
;
if
(
irr
&
PT_IRQ_LAN
)
do_IRQ
(
IRQ_SYSTEM3_SMC9196
,
regs
);
/*
* Acknowledge the parent IRQ.
*/
desc
->
chip
->
ack
(
irq
);
#if 0
/* Highspeed Serial Bus not yet used */
if( irr & PT_IRQ_USAR )
do_IRQ(PT_USAR_IRQ, regs);
#endif
/*
* Read the interrupt reason register. Let's have all
* active IRQ bits high. Note: there is a typo in the
* Neponset user's guide for the SA1111 IRR level.
*/
//irr = PT_IRQSR & (PT_IRR_LAN | PT_IRR_SA1111);
irr
=
PT_IRQSR
&
(
PT_IRR_SA1111
);
if
(
irr
&
PT_IRQ_SA1111
)
sa1111_IRQ_demux
(
irq
,
dev_id
,
regs
);
}
}
/* SMC IRQ is low-active, so "switch" bit over */
//irr ^= (PT_IRR_LAN);
//DPRINTK( "irr=0x%02x\n", irr );
static
void
__init
system3_init_irq
(
void
)
{
int
irq
;
DPRINTK
(
"%s
\n
"
,
"START"
);
if
((
irr
&
(
PT_IRR_LAN
|
PT_IRR_SA1111
))
==
0
)
break
;
/* SA1111 IRQ not routed to a GPIO. */
sa1111_init_irq
(
-
1
);
/*
* Since there is no individual mask, we have to
* mask the parent IRQ. This is safe, since we'll
* recheck the register for any pending IRQs.
*/
if
(
irr
&
(
PT_IRR_LAN
))
{
desc
->
chip
->
mask
(
irq
);
/* setup extra IRQs */
irq
=
IRQ_SYSTEM3_SMC9196
;
irq_desc
[
irq
].
valid
=
1
;
irq_desc
[
irq
].
probe_ok
=
1
;
if
(
irr
&
PT_IRR_LAN
)
{
//DPRINTK( "SMC9196, irq=%d\n", IRQ_SYSTEM3_SMC9196 );
d
=
irq_desc
+
IRQ_SYSTEM3_SMC9196
;
d
->
handle
(
IRQ_SYSTEM3_SMC9196
,
d
,
regs
);
}
#if 0
/* Highspeed Serial Bus not yet used */
irq = PT_USAR_IRQ
;
irq_desc[irq].valid = 1
;
irq_desc[irq].probe_ok = 1;
#if 0
/* no SSP yet on system 4 */
if (irr & IRR_USAR) {
d = irq_desc + IRQ_NEPONSET_USAR
;
d->handle(IRQ_NEPONSET_USAR, d, regs)
;
}
#endif
/* IRQ by CPLD */
set_GPIO_IRQ_edge
(
GPIO_GPIO
(
25
),
GPIO_RISING_EDGE
);
setup_arm_irq
(
IRQ_GPIO25
,
&
system3_irq
);
desc
->
chip
->
unmask
(
irq
);
}
if
(
irr
&
PT_IRR_SA1111
)
{
//DPRINTK( "SA1111, irq=%d\n", IRQ_SYSTEM3_SA1111 );
d
=
irq_desc
+
IRQ_SYSTEM3_SA1111
;
d
->
handle
(
IRQ_SYSTEM3_SA1111
,
d
,
regs
);
}
}
}
static
void
__init
system3_init_irq
(
void
)
{
/*
* Install handler for GPIO25.
*/
set_irq_type
(
IRQ_GPIO25
,
IRQT_RISING
);
set_irq_chained_handler
(
IRQ_GPIO25
,
system3_irq_handler
);
/*
* install eth irq
*/
set_irq_handler
(
IRQ_SYSTEM3_SMC9196
,
do_simple_IRQ
);
set_irq_flags
(
IRQ_SYSTEM3_SMC9196
,
IRQF_VALID
|
IRQF_PROBE
);
}
/**********************************************************************
...
...
@@ -270,7 +289,7 @@ static void system3_set_mctrl(struct uart_port *port, u_int mctrl)
}
}
static
int
system3_get_mctrl
(
struct
uart_port
*
port
)
static
u_
int
system3_get_mctrl
(
struct
uart_port
*
port
)
{
u_int
ret
=
0
;
u_int
irqsr
=
PT_IRQSR
;
...
...
@@ -358,12 +377,8 @@ static void system3_lcd_brightness(unsigned char value)
static
void
system3_lcd_power
(
int
on
)
{
#error why is backlight stuff here???
if
(
on
)
{
system3_lcd_on
();
system3_lcd_backlight_on
();
system3_lcd_contrast
(
0x95
);
system3_lcd_brightness
(
240
);
}
else
{
system3_lcd_off
();
}
...
...
@@ -407,10 +422,12 @@ static int __init system3_init(void)
*/
sa1110_mb_disable
();
system3_init_irq
();
/*
* Probe for a SA1111.
*/
ret
=
sa1111_probe
(
0x40000000
);
ret
=
sa1111_probe
(
PT_SA1111_BASE
);
if
(
ret
<
0
)
{
printk
(
KERN_WARNING
"PT Digital Board: no SA1111 found!
\n
"
);
goto
DONE
;
...
...
@@ -443,7 +460,11 @@ static int __init system3_init(void)
*/
sa1110_mb_enable
();
system3_init_irq
();
/*
* Initialise SA1111 IRQs
*/
sa1111_init_irq
(
IRQ_SYSTEM3_SA1111
);
#if defined( CONFIG_CPU_FREQ )
ret
=
cpufreq_register_notifier
(
&
system3_clkchg_block
);
...
...
@@ -453,6 +474,7 @@ static int __init system3_init(void)
}
#endif
ret
=
0
;
DONE:
DPRINTK
(
"ret=%d
\n
"
,
ret
);
...
...
arch/arm/mach-sa1100/victor.c
View file @
f60852d2
...
...
@@ -60,7 +60,7 @@ fixup_victor(struct machine_desc *desc, struct param_struct *params,
static
struct
map_desc
victor_io_desc
[]
__initdata
=
{
/* virtual physical length domain r w c b */
{
0xe8000000
,
0x00000000
,
0x00200000
,
DOMAIN_IO
,
1
,
1
,
0
,
0
},
/* Flash */
{
0xe8000000
,
0x00000000
,
0x00200000
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
/* Flash */
LAST_DESC
};
...
...
arch/arm/mach-sa1100/xp860.c
View file @
f60852d2
...
...
@@ -67,9 +67,9 @@ fixup_xp860(struct machine_desc *desc, struct param_struct *params,
static
struct
map_desc
xp860_io_desc
[]
__initdata
=
{
/* virtual physical length domain r w c b */
{
0xf0000000
,
0x10000000
,
0x00100000
,
DOMAIN_IO
,
1
,
1
,
0
,
0
},
/* SCSI */
{
0xf1000000
,
0x18000000
,
0x00100000
,
DOMAIN_IO
,
1
,
1
,
0
,
0
},
/* LAN */
{
0xf4000000
,
0x40000000
,
0x00800000
,
DOMAIN_IO
,
1
,
1
,
0
,
0
},
/* SA-1111 */
{
0xf0000000
,
0x10000000
,
0x00100000
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
/* SCSI */
{
0xf1000000
,
0x18000000
,
0x00100000
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
/* LAN */
{
0xf4000000
,
0x40000000
,
0x00800000
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
/* SA-1111 */
LAST_DESC
};
...
...
arch/arm/mach-sa1100/yopy.c
View file @
f60852d2
...
...
@@ -69,9 +69,9 @@ __initcall(yopy_hw_init);
static
struct
map_desc
yopy_io_desc
[]
__initdata
=
{
/* virtual physical length domain r w c b */
{
0xe8000000
,
0x00000000
,
0x04000000
,
DOMAIN_IO
,
1
,
1
,
0
,
0
},
/* Flash 0 */
{
0xec000000
,
0x08000000
,
0x04000000
,
DOMAIN_IO
,
1
,
1
,
0
,
0
},
/* Flash 1 */
{
0xf0000000
,
0x48000000
,
0x00300000
,
DOMAIN_IO
,
1
,
1
,
0
,
0
},
/* LCD */
{
0xe8000000
,
0x00000000
,
0x04000000
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
/* Flash 0 */
{
0xec000000
,
0x08000000
,
0x04000000
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
/* Flash 1 */
{
0xf0000000
,
0x48000000
,
0x00300000
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
/* LCD */
{
0xf1000000
,
0x10000000
,
0x00100000
,
DOMAIN_IO
,
0
,
1
,
0
,
0
},
/* EGPIO */
LAST_DESC
};
...
...
arch/arm/mm/fault-armv.c
View file @
f60852d2
...
...
@@ -151,7 +151,7 @@ static void adjust_pte(struct vm_area_struct *vma, unsigned long address)
if
(
pmd_bad
(
*
pmd
))
goto
bad_pmd
;
pte
=
pte_offset
(
pmd
,
address
);
pte
=
pte_offset
_map
(
pmd
,
address
);
entry
=
*
pte
;
/*
...
...
@@ -164,6 +164,7 @@ static void adjust_pte(struct vm_area_struct *vma, unsigned long address)
set_pte
(
pte
,
entry
);
flush_tlb_page
(
vma
,
address
);
}
pte_unmap
(
pte
);
return
;
bad_pgd:
...
...
arch/arm/mm/fault-common.c
View file @
f60852d2
...
...
@@ -83,10 +83,14 @@ void show_pte(struct mm_struct *mm, unsigned long addr)
break
;
}
pte
=
pte_offset
(
pmd
,
addr
);
#ifndef CONFIG_HIGHMEM
/* We must not map this if we have highmem enabled */
pte
=
pte_offset_map
(
pmd
,
addr
);
printk
(
", *pte = %08lx"
,
pte_val
(
*
pte
));
#ifdef CONFIG_CPU_32
printk
(
", *ppte = %08lx"
,
pte_val
(
pte
[
-
PTRS_PER_PTE
]));
#endif
pte_unmap
(
pte
);
#endif
}
while
(
0
);
...
...
arch/arm/mm/init.c
View file @
f60852d2
...
...
@@ -64,38 +64,6 @@ static struct meminfo meminfo __initdata = { 0, };
*/
struct
page
*
empty_zero_page
;
#ifndef CONFIG_NO_PGT_CACHE
struct
pgtable_cache_struct
quicklists
;
int
do_check_pgt_cache
(
int
low
,
int
high
)
{
int
freed
=
0
;
if
(
pgtable_cache_size
>
high
)
{
do
{
if
(
pgd_quicklist
)
{
free_pgd_slow
(
get_pgd_fast
());
freed
++
;
}
if
(
pmd_quicklist
)
{
pmd_free_slow
(
pmd_alloc_one_fast
(
NULL
,
0
));
freed
++
;
}
if
(
pte_quicklist
)
{
pte_free_slow
(
pte_alloc_one_fast
(
NULL
,
0
));
freed
++
;
}
}
while
(
pgtable_cache_size
>
low
);
}
return
freed
;
}
#else
int
do_check_pgt_cache
(
int
low
,
int
high
)
{
return
0
;
}
#endif
/* This is currently broken
* PG_skip is used on sparc/sparc64 architectures to "skip" certain
* parts of the address space.
...
...
@@ -145,9 +113,6 @@ void show_mem(void)
printk
(
"%d slab pages
\n
"
,
slab
);
printk
(
"%d pages shared
\n
"
,
shared
);
printk
(
"%d pages swap cached
\n
"
,
cached
);
#ifndef CONFIG_NO_PGT_CACHE
printk
(
"%ld page tables cached
\n
"
,
pgtable_cache_size
);
#endif
show_buffers
();
}
...
...
arch/arm/mm/minicache.c
View file @
f60852d2
...
...
@@ -58,7 +58,7 @@ static int __init minicache_init(void)
pmd
=
pmd_alloc
(
&
init_mm
,
pgd
,
minicache_address
);
if
(
!
pmd
)
BUG
();
minicache_pte
=
pte_alloc
(
&
init_mm
,
pmd
,
minicache_address
);
minicache_pte
=
pte_alloc
_kernel
(
&
init_mm
,
pmd
,
minicache_address
);
if
(
!
minicache_pte
)
BUG
();
...
...
arch/arm/mm/mm-armv.c
View file @
f60852d2
...
...
@@ -98,11 +98,15 @@ pgd_t *get_pgd_slow(struct mm_struct *mm)
if
(
!
new_pmd
)
goto
no_pmd
;
new_pte
=
pte_alloc
(
mm
,
new_pmd
,
0
);
new_pte
=
pte_alloc
_map
(
mm
,
new_pmd
,
0
);
if
(
!
new_pte
)
goto
no_pte
;
init_pmd
=
pmd_offset
(
init_pgd
,
0
);
init_pte
=
pte_offset_map_nested
(
init_pmd
,
0
);
set_pte
(
new_pte
,
*
init_pte
);
pte_unmap_nested
(
init_pte
);
pte_unmap
(
new_pte
);
spin_unlock
(
&
mm
->
page_table_lock
);
}
...
...
@@ -138,7 +142,7 @@ pgd_t *get_pgd_slow(struct mm_struct *mm)
void
free_pgd_slow
(
pgd_t
*
pgd
)
{
pmd_t
*
pmd
;
pte_t
*
pte
;
struct
page
*
pte
;
if
(
!
pgd
)
return
;
...
...
@@ -153,7 +157,7 @@ void free_pgd_slow(pgd_t *pgd)
goto
free
;
}
pte
=
p
te_offset
(
pmd
,
0
);
pte
=
p
md_page
(
*
pmd
);
pmd_clear
(
pmd
);
pte_free
(
pte
);
pmd_free
(
pmd
);
...
...
@@ -198,7 +202,7 @@ alloc_init_page(unsigned long virt, unsigned long phys, int domain, int prot)
set_pmd
(
pmdp
,
__mk_pmd
(
ptep
,
PMD_TYPE_TABLE
|
PMD_DOMAIN
(
domain
)));
}
ptep
=
pte_offset
(
pmdp
,
virt
);
ptep
=
pte_offset
_kernel
(
pmdp
,
virt
);
set_pte
(
ptep
,
mk_pte_phys
(
phys
,
__pgprot
(
prot
)));
}
...
...
@@ -225,6 +229,20 @@ static void __init create_mapping(struct map_desc *md)
int
prot_sect
,
prot_pte
;
long
off
;
if
(
md
->
prot_read
&&
md
->
prot_write
&&
!
md
->
cacheable
&&
!
md
->
bufferable
)
{
printk
(
KERN_WARNING
"Security risk: creating user "
"accessible mapping for 0x%08lx at 0x%08lx
\n
"
,
md
->
physical
,
md
->
virtual
);
}
if
(
md
->
virtual
!=
vectors_base
()
&&
md
->
virtual
<
PAGE_OFFSET
)
{
printk
(
KERN_WARNING
"MM: not creating mapping for "
"0x%08lx at 0x%08lx in user region
\n
"
,
md
->
physical
,
md
->
virtual
);
return
;
}
prot_pte
=
L_PTE_PRESENT
|
L_PTE_YOUNG
|
L_PTE_DIRTY
|
(
md
->
prot_read
?
L_PTE_USER
:
0
)
|
(
md
->
prot_write
?
L_PTE_WRITE
:
0
)
|
...
...
arch/arm/mm/proc-xscale.S
View file @
f60852d2
...
...
@@ -663,8 +663,8 @@ cpu_manu_name:
cpu_80200_name
:
.
asciz
"XScale-80200"
cpu_
cotulla
_name
:
.
asciz
"XScale-
Cotulla
"
cpu_
pxa250
_name
:
.
asciz
"XScale-
PXA250
"
.
align
...
...
@@ -734,11 +734,11 @@ cpu_80200_info:
.
long
cpu_80200_name
.
size
cpu_80200_info
,
.
-
cpu_80200_info
.
type
cpu_
cotulla
_info
,
#
object
cpu_
cotulla
_info
:
.
type
cpu_
pxa250
_info
,
#
object
cpu_
pxa250
_info
:
.
long
cpu_manu_name
.
long
cpu_
cotulla
_name
.
size
cpu_
cotulla_info
,
.
-
cpu_cotulla
_info
.
long
cpu_
pxa250
_name
.
size
cpu_
pxa250_info
,
.
-
cpu_pxa250
_info
.
type
cpu_arch_name
,
#
object
cpu_arch_name
:
...
...
@@ -767,8 +767,8 @@ __80200_proc_info:
.
long
v4wbi_tlb_fns
.
size
__80200_proc_info
,
.
-
__80200_proc_info
.
type
__
cotulla
_proc_info
,#
object
__
cotulla
_proc_info
:
.
type
__
pxa250
_proc_info
,#
object
__
pxa250
_proc_info
:
.
long
0x69052100
.
long
0xfffffff0
.
long
0x00000c0e
...
...
@@ -776,8 +776,9 @@ __cotulla_proc_info:
.
long
cpu_arch_name
.
long
cpu_elf_name
.
long
HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
.
long
cpu_
cotulla
_info
.
long
cpu_
pxa250
_info
.
long
xscale_processor_functions
.
long
v4wbi_tlb_fns
.
size
__cotulla_proc_info
,
.
-
__cotulla_proc_info
.
size
__pxa250_proc_info
,
.
-
__pxa250_proc_info
drivers/pcmcia/Config.in
View file @
f60852d2
...
...
@@ -24,5 +24,6 @@ if [ "$CONFIG_PCMCIA" != "n" ]; then
dep_tristate ' HD64465 host bridge support' CONFIG_HD64465_PCMCIA $CONFIG_PCMCIA
fi
fi
dep_tristate ' SA1100 support' CONFIG_PCMCIA_SA1100 $CONFIG_ARCH_SA1100 $CONFIG_PCMCIA
endmenu
drivers/pcmcia/Makefile
View file @
f60852d2
...
...
@@ -62,22 +62,25 @@ endif
obj-$(CONFIG_PCMCIA_SA1100)
+=
sa1100_cs.o
sa1100_cs-objs-y
:=
sa1100_generic.o
sa1100_cs-objs-$(CONFIG_SA1100_ADSBITSY)
+=
sa1100_adsbitsy.o sa1111_generic.o
sa1100_cs-objs-$(CONFIG_SA1100_ASSABET)
+=
sa1100_assabet.o
sa1100_cs-objs-$(CONFIG_ASSABET_NEPONSET)
+=
sa1100_neponset.o
sa1100_cs-objs-$(CONFIG_SA1100_
H3600)
+=
sa1100_h3600
.o
sa1100_cs-objs-$(CONFIG_ASSABET_NEPONSET)
+=
sa1100_neponset.o
sa1111_generic.o
sa1100_cs-objs-$(CONFIG_SA1100_
BADGE4)
+=
sa1100_badge4.o sa1111_generic
.o
sa1100_cs-objs-$(CONFIG_SA1100_CERF)
+=
sa1100_cerf.o
sa1100_cs-objs-$(CONFIG_SA1100_FLEXANET)
+=
sa1100_flexanet.o
sa1100_cs-objs-$(CONFIG_SA1100_FREEBIRD)
+=
sa1100_freebird.o
sa1100_cs-objs-$(CONFIG_SA1100_GRAPHICSMASTER)
+=
sa1100_graphicsmaster.o sa1111_generic.o
sa1100_cs-objs-$(CONFIG_SA1100_GRAPHICSCLIENT)
+=
sa1100_graphicsclient.o
sa1100_cs-objs-$(CONFIG_SA1100_XP860)
+=
sa1100_xp860.o
sa1100_cs-objs-$(CONFIG_SA1100_H3600)
+=
sa1100_h3600.o
sa1100_cs-objs-$(CONFIG_SA1100_JORNADA720)
+=
sa1100_jornada720.o sa1111_generic.o
sa1100_cs-objs-$(CONFIG_SA1100_PANGOLIN)
+=
sa1100_pangolin.o
sa1100_cs-objs-$(CONFIG_SA1100_YOPY)
+=
sa1100_yopy.o
sa1100_cs-objs-$(CONFIG_SA1100_FREEBIRD)
+=
sa1100_freebird.o
sa1100_cs-objs-$(CONFIG_SA1100_PFS168)
+=
sa1100_pfs168.o
sa1100_cs-objs-$(CONFIG_SA1100_JORNADA720)
+=
sa1100_jornada720.o
sa1100_cs-objs-$(CONFIG_SA1100_FLEXANET)
+=
sa1100_flexanet.o
sa1100_cs-objs-$(CONFIG_SA1100_PFS168)
+=
sa1100_pfs168.o sa1111_generic.o
sa1100_cs-objs-$(CONFIG_SA1100_PT_SYSTEM3)
+=
sa1100_system3.o sa1111_generic.o
sa1100_cs-objs-$(CONFIG_SA1100_SHANNON)
+=
sa1100_shannon.o
sa1100_cs-objs-$(CONFIG_SA1100_SIMPAD)
+=
sa1100_simpad.o
sa1100_cs-objs-$(CONFIG_SA1100_GRAPHICSMASTER)
+=
sa1100_graphicsmaster.o
sa1100_cs-objs-$(CONFIG_SA1100_ADSBITSY)
+=
sa1100_adsbitsy.o
sa1100_cs-objs-$(CONFIG_SA1100_STORK)
+=
sa1100_stork.o
sa1100_cs-objs-$(CONFIG_SA1100_XP860)
+=
sa1100_xp860.o sa1111_generic.o
sa1100_cs-objs-$(CONFIG_SA1100_YOPY)
+=
sa1100_yopy.o
include
$(TOPDIR)/Rules.make
...
...
@@ -85,7 +88,7 @@ pcmcia_core.o: $(pcmcia_core-objs)
$(LD)
$(LD_RFLAG)
-r
-o
$@
$
(
pcmcia_core-objs
)
sa1100_cs.o
:
$(sa1100_cs-objs-y)
$(LD)
-r
-o
$@
$
(
s
a1100_cs-objs-y
)
$(LD)
-r
-o
$@
$(
s
ort
$
(
sa1100_cs-objs-y
)
)
yenta_socket.o
:
$(yenta_socket-objs)
$(LD)
$(LD_RFLAG)
-r
-o
$@
$
(
yenta_socket-objs
)
drivers/pcmcia/sa1100.h
View file @
f60852d2
...
...
@@ -38,9 +38,7 @@
#include <pcmcia/bulkmem.h>
#include <pcmcia/cistpl.h>
#include "cs_internal.h"
#include <asm/arch/pcmcia.h>
#include "sa1100_generic.h"
/* MECR: Expansion Memory Configuration Register
* (SA-1100 Developers Manual, p.10-13; SA-1110 Developers Manual, p.10-24)
...
...
@@ -157,15 +155,24 @@ static inline unsigned int sa1100_pcmcia_cmd_time(unsigned int cpu_clock_khz,
* use when responding to a Card Services query of some kind.
*/
struct
sa1100_pcmcia_socket
{
/*
* Core PCMCIA state
*/
socket_state_t
cs_state
;
struct
pcmcia_state
k_state
;
unsigned
int
irq
;
void
(
*
handler
)(
void
*
,
unsigned
int
);
void
*
handler_info
;
pccard_io_map
io_map
[
MAX_IO_WIN
];
pccard_mem_map
mem_map
[
MAX_WIN
];
ioaddr_t
virt_io
,
phys_attr
,
phys_mem
;
void
(
*
handler
)(
void
*
,
unsigned
int
);
void
*
handler_info
;
struct
pcmcia_state
k_state
;
ioaddr_t
phys_attr
,
phys_mem
;
void
*
virt_io
;
unsigned
short
speed_io
,
speed_attr
,
speed_mem
;
/*
* Info from low level handler
*/
unsigned
int
irq
;
};
...
...
@@ -180,23 +187,60 @@ struct sa1100_pcmcia_socket {
/*
* Declaration for all
implementation specific low_level opera
tions.
* Declaration for all
machine specific init/exit func
tions.
*/
extern
struct
pcmcia_low_level
assabet_pcmcia_ops
;
extern
struct
pcmcia_low_level
neponset_pcmcia_ops
;
extern
struct
pcmcia_low_level
h3600_pcmcia_ops
;
extern
struct
pcmcia_low_level
cerf_pcmcia_ops
;
extern
struct
pcmcia_low_level
gcplus_pcmcia_ops
;
extern
struct
pcmcia_low_level
xp860_pcmcia_ops
;
extern
struct
pcmcia_low_level
yopy_pcmcia_ops
;
extern
struct
pcmcia_low_level
pangolin_pcmcia_ops
;
extern
struct
pcmcia_low_level
freebird_pcmcia_ops
;
extern
struct
pcmcia_low_level
pfs168_pcmcia_ops
;
extern
struct
pcmcia_low_level
jornada720_pcmcia_ops
;
extern
struct
pcmcia_low_level
flexanet_pcmcia_ops
;
extern
struct
pcmcia_low_level
simpad_pcmcia_ops
;
extern
struct
pcmcia_low_level
graphicsmaster_pcmcia_ops
;
extern
struct
pcmcia_low_level
adsbitsy_pcmcia_ops
;
extern
struct
pcmcia_low_level
stork_pcmcia_ops
;
extern
int
pcmcia_adsbitsy_init
(
void
);
extern
void
pcmcia_adsbitsy_exit
(
void
);
extern
int
pcmcia_assabet_init
(
void
);
extern
void
pcmcia_assabet_exit
(
void
);
extern
int
pcmcia_badge4_init
(
void
);
extern
void
pcmcia_badge4_exit
(
void
);
extern
int
pcmcia_cerf_init
(
void
);
extern
void
pcmcia_cerf_exit
(
void
);
extern
int
pcmcia_flexanet_init
(
void
);
extern
void
pcmcia_flexanet_exit
(
void
);
extern
int
pcmcia_freebird_init
(
void
);
extern
void
pcmcia_freebird_exit
(
void
);
extern
int
pcmcia_gcplus_init
(
void
);
extern
void
pcmcia_gcplus_exit
(
void
);
extern
int
pcmcia_graphicsmaster_init
(
void
);
extern
void
pcmcia_graphicsmaster_exit
(
void
);
extern
int
pcmcia_jornada720_init
(
void
);
extern
void
pcmcia_jornada720_exit
(
void
);
extern
int
pcmcia_neponset_init
(
void
);
extern
void
pcmcia_neponset_exit
(
void
);
extern
int
pcmcia_pangolin_init
(
void
);
extern
void
pcmcia_pangolin_exit
(
void
);
extern
int
pcmcia_pfs168_init
(
void
);
extern
void
pcmcia_pfs168_exit
(
void
);
extern
int
pcmcia_shannon_init
(
void
);
extern
void
pcmcia_shannon_exit
(
void
);
extern
int
pcmcia_simpad_init
(
void
);
extern
void
pcmcia_simpad_exit
(
void
);
extern
int
pcmcia_stork_init
(
void
);
extern
void
pcmcia_stork_exit
(
void
);
extern
int
pcmcia_system3_init
(
void
);
extern
void
pcmcia_system3_exit
(
void
);
extern
int
pcmcia_xp860_init
(
void
);
extern
void
pcmcia_xp860_exit
(
void
);
extern
int
pcmcia_yopy_init
(
void
);
extern
void
pcmcia_yopy_exit
(
void
);
#endif
/* !defined(_PCMCIA_SA1100_H) */
drivers/pcmcia/sa1100_adsbitsy.c
View file @
f60852d2
...
...
@@ -11,206 +11,97 @@
*/
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <asm/delay.h>
#include <asm/hardware.h>
#include <asm/irq.h>
#include <asm/arch/pcmcia.h>
#include "sa1100_generic.h"
#include "sa1111_generic.h"
static
int
adsbitsy_pcmcia_init
(
struct
pcmcia_init
*
init
)
{
int
return_val
=
0
;
/* Set GPIO_A<3:0> to be outputs for PCMCIA/CF power controller: */
PA_DDR
&=
~
(
GPIO_GPIO0
|
GPIO_GPIO1
|
GPIO_GPIO2
|
GPIO_GPIO3
);
/* Disable Power 3.3V/5V for PCMCIA/CF */
PA_DWR
|=
GPIO_GPIO0
|
GPIO_GPIO1
|
GPIO_GPIO2
|
GPIO_GPIO3
;
INTPOL1
|=
(
1
<<
(
S0_READY_NINT
-
SA1111_IRQ
(
32
)))
|
(
1
<<
(
S1_READY_NINT
-
SA1111_IRQ
(
32
)))
|
(
1
<<
(
S0_CD_VALID
-
SA1111_IRQ
(
32
)))
|
(
1
<<
(
S1_CD_VALID
-
SA1111_IRQ
(
32
)))
|
(
1
<<
(
S0_BVD1_STSCHG
-
SA1111_IRQ
(
32
)))
|
(
1
<<
(
S1_BVD1_STSCHG
-
SA1111_IRQ
(
32
)));
return_val
+=
request_irq
(
S0_CD_VALID
,
init
->
handler
,
SA_INTERRUPT
,
"GC Master PCMCIA (0) CD"
,
NULL
);
return_val
+=
request_irq
(
S1_CD_VALID
,
init
->
handler
,
SA_INTERRUPT
,
"GC Master CF (1) CD"
,
NULL
);
return_val
+=
request_irq
(
S0_BVD1_STSCHG
,
init
->
handler
,
SA_INTERRUPT
,
"GC Master PCMCIA (0) BVD1"
,
NULL
);
return_val
+=
request_irq
(
S1_BVD1_STSCHG
,
init
->
handler
,
SA_INTERRUPT
,
"GC Master CF (1) BVD1"
,
NULL
);
/* Why? */
MECR
=
0x09430943
;
return
(
return_val
<
0
)
?
-
1
:
2
;
}
static
int
adsbitsy_pcmcia_shutdown
(
void
)
{
free_irq
(
S0_CD_VALID
,
NULL
);
free_irq
(
S1_CD_VALID
,
NULL
);
free_irq
(
S0_BVD1_STSCHG
,
NULL
);
free_irq
(
S1_BVD1_STSCHG
,
NULL
);
INTPOL1
&=
~
((
1
<<
(
S0_CD_VALID
-
SA1111_IRQ
(
32
)))
|
(
1
<<
(
S1_CD_VALID
-
SA1111_IRQ
(
32
)))
|
(
1
<<
(
S0_BVD1_STSCHG
-
SA1111_IRQ
(
32
)))
|
(
1
<<
(
S1_BVD1_STSCHG
-
SA1111_IRQ
(
32
))));
return
0
;
return
sa1111_pcmcia_init
(
init
);
}
static
int
adsbitsy_pcmcia_socket_state
(
struct
pcmcia_state_array
*
state_array
)
static
int
adsbitsy_pcmcia_configure_socket
(
const
struct
pcmcia_configure
*
conf
)
{
unsigned
long
status
;
int
return_val
=
1
;
if
(
state_array
->
size
<
2
)
return
-
1
;
memset
(
state_array
->
state
,
0
,
(
state_array
->
size
)
*
sizeof
(
struct
pcmcia_state
));
status
=
PCSR
;
state_array
->
state
[
0
].
detect
=
((
status
&
PCSR_S0_DETECT
)
==
0
)
?
1
:
0
;
state_array
->
state
[
0
].
ready
=
((
status
&
PCSR_S0_READY
)
==
0
)
?
0
:
1
;
state_array
->
state
[
0
].
bvd1
=
((
status
&
PCSR_S0_BVD1
)
==
0
)
?
0
:
1
;
state_array
->
state
[
0
].
bvd2
=
((
status
&
PCSR_S0_BVD2
)
==
0
)
?
0
:
1
;
state_array
->
state
[
0
].
wrprot
=
((
status
&
PCSR_S0_WP
)
==
0
)
?
0
:
1
;
state_array
->
state
[
0
].
vs_3v
=
((
status
&
PCSR_S0_VS1
)
==
0
)
?
1
:
0
;
unsigned
int
pa_dwr_mask
,
pa_dwr_set
;
int
ret
;
state_array
->
state
[
0
].
vs_Xv
=
((
status
&
PCSR_S0_VS2
)
==
0
)
?
1
:
0
;
state_array
->
state
[
1
].
detect
=
((
status
&
PCSR_S1_DETECT
)
==
0
)
?
1
:
0
;
state_array
->
state
[
1
].
ready
=
((
status
&
PCSR_S1_READY
)
==
0
)
?
0
:
1
;
state_array
->
state
[
1
].
bvd1
=
((
status
&
PCSR_S1_BVD1
)
==
0
)
?
0
:
1
;
state_array
->
state
[
1
].
bvd2
=
((
status
&
PCSR_S1_BVD2
)
==
0
)
?
0
:
1
;
state_array
->
state
[
1
].
wrprot
=
((
status
&
PCSR_S1_WP
)
==
0
)
?
0
:
1
;
state_array
->
state
[
1
].
vs_3v
=
((
status
&
PCSR_S1_VS1
)
==
0
)
?
1
:
0
;
state_array
->
state
[
1
].
vs_Xv
=
((
status
&
PCSR_S1_VS2
)
==
0
)
?
1
:
0
;
return
return_val
;
}
static
int
adsbitsy_pcmcia_get_irq_info
(
struct
pcmcia_irq_info
*
info
)
{
switch
(
info
->
sock
){
switch
(
conf
->
sock
)
{
case
0
:
info
->
irq
=
S0_READY_NINT
;
break
;
case
1
:
info
->
irq
=
S1_READY_NINT
;
break
;
pa_dwr_mask
=
GPIO_GPIO0
|
GPIO_GPIO1
;
switch
(
conf
->
vcc
)
{
default:
return
-
1
;
case
0
:
pa_dwr_set
=
GPIO_GPIO0
|
GPIO_GPIO1
;
break
;
case
33
:
pa_dwr_set
=
GPIO_GPIO1
;
break
;
case
50
:
pa_dwr_set
=
GPIO_GPIO0
;
break
;
}
return
0
;
}
static
int
adsbitsy_pcmcia_configure_socket
(
const
struct
pcmcia_configure
*
configure
)
{
unsigned
long
pccr
=
PCCR
,
gpio
=
PA_DWR
;
switch
(
configure
->
sock
){
case
0
:
switch
(
configure
->
vcc
){
case
0
:
pccr
=
(
pccr
&
~
PCCR_S0_FLT
);
gpio
|=
GPIO_GPIO0
|
GPIO_GPIO1
;
break
;
case
33
:
pccr
=
(
pccr
&
~
PCCR_S0_PSE
)
|
PCCR_S0_FLT
|
PCCR_S0_PWAITEN
;
gpio
&=
~
(
GPIO_GPIO0
|
GPIO_GPIO1
);
gpio
&=
~
GPIO_GPIO0
;
break
;
case
50
:
pccr
=
(
pccr
|
PCCR_S0_PSE
|
PCCR_S0_FLT
|
PCCR_S0_PWAITEN
);
gpio
&=
~
(
GPIO_GPIO0
|
GPIO_GPIO1
);
gpio
|=
GPIO_GPIO0
;
break
;
case
1
:
pa_dwr_mask
=
GPIO_GPIO2
|
GPIO_GPIO3
;
switch
(
conf
->
vcc
)
{
default:
printk
(
KERN_ERR
"%s(): unrecognized Vcc %u
\n
"
,
__FUNCTION__
,
configure
->
vcc
)
;
return
-
1
;
case
0
:
pa_dwr_set
=
0
;
break
;
case
33
:
pa_dwr_set
=
GPIO_GPIO2
;
break
;
case
50
:
pa_dwr_set
=
GPIO_GPIO3
;
break
;
}
pccr
=
(
configure
->
reset
)
?
(
pccr
|
PCCR_S0_RST
)
:
(
pccr
&
~
PCCR_S0_RST
);
break
;
case
1
:
switch
(
configure
->
vcc
){
case
0
:
pccr
=
(
pccr
&
~
PCCR_S1_FLT
);
gpio
&=
~
(
GPIO_GPIO2
|
GPIO_GPIO3
);
break
;
case
33
:
pccr
=
(
pccr
&
~
PCCR_S1_PSE
)
|
PCCR_S1_FLT
|
PCCR_S1_PWAITEN
;
gpio
&=
~
(
GPIO_GPIO2
|
GPIO_GPIO3
);
gpio
|=
GPIO_GPIO2
;
break
;
case
50
:
pccr
=
(
pccr
|
PCCR_S1_PSE
|
PCCR_S1_FLT
|
PCCR_S1_PWAITEN
);
gpio
&=
~
(
GPIO_GPIO2
|
GPIO_GPIO3
);
gpio
|=
GPIO_GPIO3
;
break
;
default:
printk
(
KERN_ERR
"%s(): unrecognized Vcc %u
\n
"
,
__FUNCTION__
,
configure
->
vcc
);
return
-
1
;
}
if
(
configure
->
vpp
!=
configure
->
vcc
&&
configure
->
vpp
!=
0
)
{
printk
(
KERN_ERR
"%s(): CF slot cannot support Vpp %u
\n
"
,
__FUNCTION__
,
configure
->
vpp
);
if
(
conf
->
vpp
!=
conf
->
vcc
&&
conf
->
vpp
!=
0
)
{
printk
(
KERN_ERR
"%s(): CF slot cannot support VPP %u
\n
"
,
__FUNCTION__
,
conf
->
vpp
);
return
-
1
;
}
pccr
=
(
configure
->
reset
)
?
(
pccr
|
PCCR_S1_RST
)
:
(
pccr
&
~
PCCR_S1_RST
);
break
;
ret
=
sa1111_pcmcia_configure_socket
(
conf
);
if
(
ret
==
0
)
{
unsigned
long
flags
;
default:
return
-
1
;
local_irq_save
(
flags
);
PA_DWR
=
(
PA_DWR
&
~
pa_dwr_mask
)
|
pa_dwr_set
;
local_irq_restore
(
flags
);
}
PCCR
=
pccr
;
PA_DWR
=
gpio
;
return
0
;
return
ret
;
}
struct
pcmcia_low_level
adsbitsy_pcmcia_ops
=
{
adsbitsy_pcmcia_init
,
adsbitsy_pcmcia_shutdown
,
adsbitsy_pcmcia_socket_state
,
adsbitsy_pcmcia_get_irq_info
,
adsbitsy_pcmcia_configure_socket
static
struct
pcmcia_low_level
adsbitsy_pcmcia_ops
=
{
init:
adsbitsy_pcmcia_init
,
shutdown:
sa1111_pcmcia_shutdown
,
socket_state:
sa1111_pcmcia_socket_state
,
get_irq_info:
sa1111_pcmcia_get_irq_info
,
configure_socket:
adsbitsy_pcmcia_configure_socket
,
socket_init:
sa1111_pcmcia_socket_init
,
socket_suspend:
sa1111_pcmcia_socket_suspend
,
};
int
__init
pcmcia_adsbitsy_init
(
void
)
{
int
ret
=
-
ENODEV
;
if
(
machine_is_adsbitsy
())
ret
=
sa1100_register_pcmcia
(
&
adsbitsy_pcmcia_ops
);
return
ret
;
}
void
__exit
pcmcia_adsbitsy_exit
(
void
)
{
sa1100_unregister_pcmcia
(
&
adsbitsy_pcmcia_ops
);
}
drivers/pcmcia/sa1100_assabet.c
View file @
f60852d2
...
...
@@ -4,113 +4,114 @@
* PCMCIA implementation routines for Assabet
*
*/
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <asm/hardware.h>
#include <asm/irq.h>
#include <asm/arch/pcmcia.h>
#include <asm/arch/assabet.h>
static
int
assabet_pcmcia_init
(
struct
pcmcia_init
*
init
){
int
irq
,
res
;
#include "sa1100_generic.h"
/* Enable CF bus: */
ASSABET_BCR_clear
(
ASSABET_BCR_CF_BUS_OFF
);
static
struct
irqs
{
int
irq
;
const
char
*
str
;
}
irqs
[]
=
{
{
ASSABET_IRQ_GPIO_CF_CD
,
"CF_CD"
},
{
ASSABET_IRQ_GPIO_CF_BVD2
,
"CF_BVD2"
},
{
ASSABET_IRQ_GPIO_CF_BVD1
,
"CF_BVD1"
},
};
/* All those are inputs */
GPDR
&=
~
(
ASSABET_GPIO_CF_CD
|
ASSABET_GPIO_CF_BVD2
|
ASSABET_GPIO_CF_BVD1
|
ASSABET_GPIO_CF_IRQ
);
static
int
assabet_pcmcia_init
(
struct
pcmcia_init
*
init
)
{
int
i
,
res
;
/* Set transition detect */
set_GPIO_IRQ_edge
(
ASSABET_GPIO_CF_CD
|
ASSABET_GPIO_CF_BVD2
|
ASSABET_GPIO_CF_BVD1
,
GPIO_BOTH_EDGES
);
set_GPIO_IRQ_edge
(
ASSABET_GPIO_CF_IRQ
,
GPIO_FALLING_EDGE
);
set_irq_type
(
ASSABET_IRQ_GPIO_CF_IRQ
,
IRQT_FALLING
);
/* Register interrupts */
irq
=
ASSABET_IRQ_GPIO_CF_CD
;
res
=
request_irq
(
irq
,
init
->
handler
,
SA_INTERRUPT
,
"CF_CD"
,
NULL
);
if
(
res
<
0
)
goto
irq_err
;
irq
=
ASSABET_IRQ_GPIO_CF_BVD2
;
res
=
request_irq
(
irq
,
init
->
handler
,
SA_INTERRUPT
,
"CF_BVD2"
,
NULL
);
if
(
res
<
0
)
goto
irq_err
;
irq
=
ASSABET_IRQ_GPIO_CF_BVD1
;
res
=
request_irq
(
irq
,
init
->
handler
,
SA_INTERRUPT
,
"CF_BVD1"
,
NULL
);
if
(
res
<
0
)
goto
irq_err
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
irqs
);
i
++
)
{
set_irq_type
(
irqs
[
i
].
irq
,
IRQT_NOEDGE
);
res
=
request_irq
(
irqs
[
i
].
irq
,
init
->
handler
,
SA_INTERRUPT
,
irqs
[
i
].
str
,
NULL
);
if
(
res
)
goto
irq_err
;
}
/* There's only one slot, but it's "Slot 1": */
return
2
;
irq_err:
printk
(
KERN_ERR
"%s: Request for IRQ %u failed
\n
"
,
__FUNCTION__
,
irq
);
return
-
1
;
irq_err:
printk
(
KERN_ERR
"%s: request for IRQ%d failed (%d)
\n
"
,
__FUNCTION__
,
irqs
[
i
].
irq
,
res
);
while
(
i
--
)
free_irq
(
irqs
[
i
].
irq
,
NULL
);
return
res
;
}
/*
* Release all resources.
*/
static
int
assabet_pcmcia_shutdown
(
void
)
{
/* disable IRQs */
free_irq
(
ASSABET_IRQ_GPIO_CF_CD
,
NULL
);
free_irq
(
ASSABET_IRQ_GPIO_CF_BVD2
,
NULL
);
free_irq
(
ASSABET_IRQ_GPIO_CF_BVD1
,
NULL
);
int
i
;
/* Disable CF bus: */
ASSABET_BCR_set
(
ASSABET_BCR_CF_BUS_OFF
);
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
irqs
);
i
++
)
free_irq
(
irqs
[
i
].
irq
,
NULL
);
return
0
;
}
static
int
assabet_pcmcia_socket_state
(
struct
pcmcia_state_array
*
state_array
){
static
int
assabet_pcmcia_socket_state
(
struct
pcmcia_state_array
*
state_array
)
{
unsigned
long
levels
;
if
(
state_array
->
size
<
2
)
return
-
1
;
memset
(
state_array
->
state
,
0
,
(
state_array
->
size
)
*
sizeof
(
struct
pcmcia_state
));
levels
=
GPLR
;
state_array
->
state
[
1
].
detect
=
((
levels
&
ASSABET_GPIO_CF_CD
)
==
0
)
?
1
:
0
;
state_array
->
state
[
1
].
ready
=
(
levels
&
ASSABET_GPIO_CF_IRQ
)
?
1
:
0
;
state_array
->
state
[
1
].
bvd1
=
(
levels
&
ASSABET_GPIO_CF_BVD1
)
?
1
:
0
;
state_array
->
state
[
1
].
bvd2
=
(
levels
&
ASSABET_GPIO_CF_BVD2
)
?
1
:
0
;
state_array
->
state
[
1
].
wrprot
=
0
;
/* Not available on Assabet. */
if
(
state_array
->
size
<
2
)
return
-
1
;
state_array
->
state
[
1
].
vs_3v
=
1
;
/* Can only apply 3.3V on Assabet. */
levels
=
GPLR
;
state_array
->
state
[
1
].
vs_Xv
=
0
;
state_array
->
state
[
1
].
detect
=
(
levels
&
ASSABET_GPIO_CF_CD
)
?
0
:
1
;
state_array
->
state
[
1
].
ready
=
(
levels
&
ASSABET_GPIO_CF_IRQ
)
?
1
:
0
;
state_array
->
state
[
1
].
bvd1
=
(
levels
&
ASSABET_GPIO_CF_BVD1
)
?
1
:
0
;
state_array
->
state
[
1
].
bvd2
=
(
levels
&
ASSABET_GPIO_CF_BVD2
)
?
1
:
0
;
state_array
->
state
[
1
].
wrprot
=
0
;
/* Not available on Assabet. */
state_array
->
state
[
1
].
vs_3v
=
1
;
/* Can only apply 3.3V on Assabet. */
state_array
->
state
[
1
].
vs_Xv
=
0
;
return
1
;
}
static
int
assabet_pcmcia_get_irq_info
(
struct
pcmcia_irq_info
*
info
){
if
(
info
->
sock
>
1
)
return
-
1
;
static
int
assabet_pcmcia_get_irq_info
(
struct
pcmcia_irq_info
*
info
)
{
if
(
info
->
sock
>
1
)
return
-
1
;
if
(
info
->
sock
==
1
)
info
->
irq
=
ASSABET_IRQ_GPIO_CF_IRQ
;
if
(
info
->
sock
==
1
)
info
->
irq
=
ASSABET_IRQ_GPIO_CF_IRQ
;
return
0
;
}
static
int
assabet_pcmcia_configure_socket
(
const
struct
pcmcia_configure
*
configure
)
static
int
assabet_pcmcia_configure_socket
(
const
struct
pcmcia_configure
*
configure
)
{
unsigned
long
value
,
flags
;
if
(
configure
->
sock
>
1
)
return
-
1
;
if
(
configure
->
sock
==
0
)
return
0
;
unsigned
int
mask
;
save_flags_cli
(
flags
);
if
(
configure
->
sock
>
1
)
return
-
1
;
value
=
BCR_value
;
if
(
configure
->
sock
==
0
)
return
0
;
switch
(
configure
->
vcc
)
{
switch
(
configure
->
vcc
)
{
case
0
:
value
&=
~
ASSABET_BCR_CF_PWR
;
mask
=
0
;
break
;
case
50
:
...
...
@@ -118,32 +119,106 @@ static int assabet_pcmcia_configure_socket(const struct pcmcia_configure
__FUNCTION__
);
case
33
:
/* Can only apply 3.3V to the CF slot. */
value
|
=
ASSABET_BCR_CF_PWR
;
mask
=
ASSABET_BCR_CF_PWR
;
break
;
default:
printk
(
KERN_ERR
"%s(): unrecognized Vcc %u
\n
"
,
__FUNCTION__
,
configure
->
vcc
);
restore_flags
(
flags
);
return
-
1
;
}
value
=
(
configure
->
reset
)
?
(
value
|
ASSABET_BCR_CF_RST
)
:
(
value
&
~
ASSABET_BCR_CF_RST
);
/* Silently ignore Vpp, output enable, speaker enable. */
ASSABET_BCR
=
BCR_value
=
value
;
if
(
configure
->
reset
)
mask
|=
ASSABET_BCR_CF_RST
;
restore_flags
(
flags
);
ASSABET_BCR_frob
(
ASSABET_BCR_CF_RST
|
ASSABET_BCR_CF_PWR
,
mask
);
/*
* Handle suspend mode properly. This prevents a
* flood of IRQs from the CF device.
*/
if
(
configure
->
irq
)
enable_irq
(
ASSABET_IRQ_GPIO_CF_IRQ
);
else
disable_irq
(
ASSABET_IRQ_GPIO_CF_IRQ
);
return
0
;
}
struct
pcmcia_low_level
assabet_pcmcia_ops
=
{
assabet_pcmcia_init
,
assabet_pcmcia_shutdown
,
assabet_pcmcia_socket_state
,
assabet_pcmcia_get_irq_info
,
assabet_pcmcia_configure_socket
/*
* Enable card status IRQs on (re-)initialisation. This can
* be called at initialisation, power management event, or
* pcmcia event.
*/
static
int
assabet_pcmcia_socket_init
(
int
sock
)
{
int
i
;
if
(
sock
==
1
)
{
/*
* Enable CF bus
*/
ASSABET_BCR_clear
(
ASSABET_BCR_CF_BUS_OFF
);
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
irqs
);
i
++
)
set_irq_type
(
irqs
[
i
].
irq
,
IRQT_BOTHEDGE
);
}
return
0
;
}
/*
* Disable card status IRQs on suspend.
*/
static
int
assabet_pcmcia_socket_suspend
(
int
sock
)
{
int
i
;
if
(
sock
==
1
)
{
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
irqs
);
i
++
)
set_irq_type
(
irqs
[
i
].
irq
,
IRQT_NOEDGE
);
/*
* Tristate the CF bus signals. Also assert CF
* reset as per user guide page 4-11.
*/
ASSABET_BCR_set
(
ASSABET_BCR_CF_BUS_OFF
|
ASSABET_BCR_CF_RST
);
}
return
0
;
}
static
struct
pcmcia_low_level
assabet_pcmcia_ops
=
{
init:
assabet_pcmcia_init
,
shutdown:
assabet_pcmcia_shutdown
,
socket_state:
assabet_pcmcia_socket_state
,
get_irq_info:
assabet_pcmcia_get_irq_info
,
configure_socket:
assabet_pcmcia_configure_socket
,
socket_init:
assabet_pcmcia_socket_init
,
socket_suspend:
assabet_pcmcia_socket_suspend
,
};
int
__init
pcmcia_assabet_init
(
void
)
{
int
ret
=
-
ENODEV
;
if
(
machine_is_assabet
())
{
if
(
!
machine_has_neponset
())
ret
=
sa1100_register_pcmcia
(
&
assabet_pcmcia_ops
);
#ifndef CONFIG_ASSABET_NEPONSET
else
printk
(
KERN_ERR
"Card Services disabled: missing "
"Neponset support
\n
"
);
#endif
}
return
ret
;
}
void
__exit
pcmcia_assabet_exit
(
void
)
{
sa1100_unregister_pcmcia
(
&
assabet_pcmcia_ops
);
}
drivers/pcmcia/sa1100_badge4.c
0 → 100644
View file @
f60852d2
/*
* linux/drivers/pcmcia/sa1100_badge4.c
*
* BadgePAD 4 PCMCIA specific routines
*
* Christopher Hoover <ch@hpl.hp.com>
*
* Copyright (C) 2002 Hewlett-Packard Company
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
*/
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <asm/hardware.h>
#include <asm/arch/badge4.h>
#include <asm/hardware/sa1111.h>
#include "sa1100_generic.h"
#include "sa1111_generic.h"
/*
* BadgePAD 4 Details
*
* PCM Vcc:
*
* PCM Vcc on BadgePAD 4 can be jumpered for 3.3V (short pins 1 and 3
* on JP6) or 5V (short pins 3 and 5 on JP6). N.B., 5V supply rail
* is enabled by the SA-1110's BADGE4_GPIO_PCMEN5V (GPIO 24).
*
* PCM Vpp:
*
* PCM Vpp on BadgePAD 4 can be jumpered for 12V (short pins 2 and 4
* on JP6) or tied to PCM Vcc (short pins 4 and 6 on JP6). N.B., 12V
* operation requires that the power supply actually supply 12V.
*
* CF Vcc:
*
* CF Vcc on BadgePAD 4 can be jumpered either for 3.3V (short pins 1
* and 2 on JP10) or 5V (short pins 2 and 3 on JP10). The note above
* about the 5V supply rail applies.
*
* There's no way programmatically to determine how a given board is
* jumpered. This code assumes a default jumpering: 5V PCM Vcc (pins
* 3 and 5 shorted) and PCM Vpp = PCM Vcc (pins 4 and 6 shorted) and
* no jumpering for CF Vcc. If this isn't correct, Override these
* defaults with a pcmv setup argument: pcmv=<pcm vcc>,<pcm vpp>,<cf
* vcc>. E.g. pcmv=33,120,50 indicates 3.3V PCM Vcc, 12.0V PCM Vpp,
* and 5.0V CF Vcc.
*
*/
static
int
badge4_pcmvcc
=
50
;
static
int
badge4_pcmvpp
=
50
;
static
int
badge4_cfvcc
=
0
;
static
int
badge4_pcmcia_init
(
struct
pcmcia_init
*
init
)
{
printk
(
KERN_INFO
__FUNCTION__
": badge4_pcmvcc=%d, badge4_pcmvpp=%d, badge4_cfvcc=%d
\n
"
,
badge4_pcmvcc
,
badge4_pcmvpp
,
badge4_cfvcc
);
return
sa1111_pcmcia_init
(
init
);
}
static
int
badge4_pcmcia_shutdown
(
void
)
{
int
rc
=
sa1111_pcmcia_shutdown
();
/* be sure to disable 5V use */
badge4_set_5V
(
BADGE4_5V_PCMCIA_SOCK0
,
0
);
badge4_set_5V
(
BADGE4_5V_PCMCIA_SOCK1
,
0
);
return
rc
;
}
static
void
complain_about_jumpering
(
const
char
*
whom
,
const
char
*
supply
,
int
given
,
int
wanted
)
{
printk
(
KERN_ERR
"%s: %s %d.%dV wanted but board is jumpered for %s %d.%dV operation"
"; re-jumper the board and/or use pcmv=xx,xx,xx
\n
"
,
whom
,
supply
,
wanted
/
10
,
wanted
%
10
,
supply
,
given
/
10
,
given
%
10
);
}
static
unsigned
badge4_need_5V_bitmap
=
0
;
static
int
badge4_pcmcia_configure_socket
(
const
struct
pcmcia_configure
*
conf
)
{
int
ret
;
switch
(
conf
->
sock
)
{
case
0
:
if
((
conf
->
vcc
!=
0
)
&&
(
conf
->
vcc
!=
badge4_pcmvcc
))
{
complain_about_jumpering
(
__FUNCTION__
,
"pcmvcc"
,
badge4_pcmvcc
,
conf
->
vcc
);
return
-
1
;
}
if
((
conf
->
vpp
!=
0
)
&&
(
conf
->
vpp
!=
badge4_pcmvpp
))
{
complain_about_jumpering
(
__FUNCTION__
,
"pcmvpp"
,
badge4_pcmvpp
,
conf
->
vpp
);
return
-
1
;
}
break
;
case
1
:
if
((
conf
->
vcc
!=
0
)
&&
(
conf
->
vcc
!=
badge4_cfvcc
))
{
complain_about_jumpering
(
__FUNCTION__
,
"cfvcc"
,
badge4_cfvcc
,
conf
->
vcc
);
return
-
1
;
}
break
;
default:
return
-
1
;
}
ret
=
sa1111_pcmcia_configure_socket
(
conf
);
if
(
ret
==
0
)
{
unsigned
long
flags
;
int
need5V
;
local_irq_save
(
flags
);
need5V
=
((
conf
->
vcc
==
50
)
||
(
conf
->
vpp
==
50
));
badge4_set_5V
(
BADGE4_5V_PCMCIA_SOCK
(
conf
->
sock
),
need5V
);
local_irq_restore
(
flags
);
}
return
0
;
}
static
struct
pcmcia_low_level
badge4_pcmcia_ops
=
{
init:
badge4_pcmcia_init
,
shutdown:
badge4_pcmcia_shutdown
,
socket_state:
sa1111_pcmcia_socket_state
,
get_irq_info:
sa1111_pcmcia_get_irq_info
,
configure_socket:
badge4_pcmcia_configure_socket
,
socket_init:
sa1111_pcmcia_socket_init
,
socket_suspend:
sa1111_pcmcia_socket_suspend
,
};
int
__init
pcmcia_badge4_init
(
void
)
{
int
ret
=
-
ENODEV
;
if
(
machine_is_badge4
())
ret
=
sa1100_register_pcmcia
(
&
badge4_pcmcia_ops
);
return
ret
;
}
void
__exit
pcmcia_badge4_exit
(
void
)
{
sa1100_unregister_pcmcia
(
&
badge4_pcmcia_ops
);
}
static
int
__init
pcmv_setup
(
char
*
s
)
{
int
v
[
4
];
s
=
get_options
(
s
,
ARRAY_SIZE
(
v
),
v
);
if
(
v
[
0
]
>=
1
)
badge4_pcmvcc
=
v
[
1
];
if
(
v
[
0
]
>=
2
)
badge4_pcmvpp
=
v
[
2
];
if
(
v
[
0
]
>=
3
)
badge4_cfvcc
=
v
[
3
];
return
1
;
}
__setup
(
"pcmv="
,
pcmv_setup
);
drivers/pcmcia/sa1100_cerf.c
View file @
f60852d2
...
...
@@ -5,45 +5,62 @@
* Based off the Assabet.
*
*/
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <asm/hardware.h>
#include <asm/irq.h>
#include
<asm/arch/pcmcia.h>
#include
"sa1100_generic.h"
#ifdef CONFIG_SA1100_CERF_CPLD
#define CERF_SOCKET 0
#else
#define CERF_SOCKET 1
#endif
static
int
cerf_pcmcia_init
(
struct
pcmcia_init
*
init
){
int
irq
,
res
;
static
struct
irqs
{
int
irq
;
const
char
*
str
;
}
irqs
[]
=
{
{
IRQ_GPIO_CF_CD
,
"CF_CD"
},
{
IRQ_GPIO_CF_BVD2
,
"CF_BVD2"
},
{
IRQ_GPIO_CF_BVD1
,
"CF_BVD1"
}
};
GPDR
&=
~
(
GPIO_CF_CD
|
GPIO_CF_BVD2
|
GPIO_CF_BVD1
|
GPIO_CF_IRQ
);
GPDR
|=
(
GPIO_CF_RESET
);
static
int
cerf_pcmcia_init
(
struct
pcmcia_init
*
init
)
{
int
i
,
res
;
set_GPIO_IRQ_edge
(
GPIO_CF_CD
|
GPIO_CF_BVD2
|
GPIO_CF_BVD1
,
GPIO_BOTH_EDGES
);
set_GPIO_IRQ_edge
(
GPIO_CF_IRQ
,
GPIO_FALLING_EDGE
);
set_irq_type
(
IRQ_GPIO_CF_IRQ
,
IRQT_FALLING
);
irq
=
IRQ_GPIO_CF_CD
;
res
=
request_irq
(
irq
,
init
->
handler
,
SA_INTERRUPT
,
"CF_CD"
,
NULL
);
if
(
res
<
0
)
goto
irq_err
;
irq
=
IRQ_GPIO_CF_BVD2
;
res
=
request_irq
(
irq
,
init
->
handler
,
SA_INTERRUPT
,
"CF_BVD2"
,
NULL
);
if
(
res
<
0
)
goto
irq_err
;
irq
=
IRQ_GPIO_CF_BVD1
;
res
=
request_irq
(
irq
,
init
->
handler
,
SA_INTERRUPT
,
"CF_BVD1"
,
NULL
);
if
(
res
<
0
)
goto
irq_err
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
irqs
);
i
++
)
{
set_irq_type
(
irqs
[
i
].
irq
,
IRQT_NOEDGE
);
res
=
request_irq
(
irqs
[
i
].
irq
,
init
->
handler
,
SA_INTERRUPT
,
irqs
[
i
].
str
,
NULL
);
if
(
res
)
goto
irq_err
;
}
return
2
;
irq_err:
printk
(
KERN_ERR
"%s: Request for IRQ %lu failed
\n
"
,
__FUNCTION__
,
irq
);
return
-
1
;
irq_err:
printk
(
KERN_ERR
"%s: request for IRQ%d failed (%d)
\n
"
,
__FUNCTION__
,
irqs
[
i
].
irq
,
res
);
while
(
i
--
)
free_irq
(
irqs
[
i
].
irq
,
NULL
);
return
res
;
}
static
int
cerf_pcmcia_shutdown
(
void
)
{
free_irq
(
IRQ_GPIO_CF_CD
,
NULL
);
free_irq
(
IRQ_GPIO_CF_BVD2
,
NULL
);
free_irq
(
IRQ_GPIO_CF_BVD1
,
NULL
);
int
i
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
irqs
);
i
++
)
free_irq
(
irqs
[
i
].
irq
,
NULL
);
return
0
;
}
...
...
@@ -51,31 +68,18 @@ static int cerf_pcmcia_shutdown(void)
static
int
cerf_pcmcia_socket_state
(
struct
pcmcia_state_array
*
state_array
){
unsigned
long
levels
;
#ifdef CONFIG_SA1100_CERF_CPLD
int
i
=
0
;
#else
int
i
=
1
;
#endif
int
i
=
CERF_SOCKET
;
if
(
state_array
->
size
<
2
)
return
-
1
;
memset
(
state_array
->
state
,
0
,
(
state_array
->
size
)
*
sizeof
(
struct
pcmcia_state
));
levels
=
GPLR
;
state_array
->
state
[
i
].
detect
=
((
levels
&
GPIO_CF_CD
)
==
0
)
?
1
:
0
;
state_array
->
state
[
i
].
ready
=
(
levels
&
GPIO_CF_IRQ
)
?
1
:
0
;
state_array
->
state
[
i
].
bvd1
=
(
levels
&
GPIO_CF_BVD1
)
?
1
:
0
;
state_array
->
state
[
i
].
bvd2
=
(
levels
&
GPIO_CF_BVD2
)
?
1
:
0
;
state_array
->
state
[
i
].
wrprot
=
0
;
state_array
->
state
[
i
].
vs_3v
=
1
;
state_array
->
state
[
i
].
vs_Xv
=
0
;
return
1
;
...
...
@@ -85,11 +89,7 @@ static int cerf_pcmcia_get_irq_info(struct pcmcia_irq_info *info){
if
(
info
->
sock
>
1
)
return
-
1
;
#ifdef CONFIG_SA1100_CERF_CPLD
if
(
info
->
sock
==
0
)
#else
if
(
info
->
sock
==
1
)
#endif
if
(
info
->
sock
==
CERF_SOCKET
)
info
->
irq
=
IRQ_GPIO_CF_IRQ
;
return
0
;
...
...
@@ -98,20 +98,12 @@ static int cerf_pcmcia_get_irq_info(struct pcmcia_irq_info *info){
static
int
cerf_pcmcia_configure_socket
(
const
struct
pcmcia_configure
*
configure
)
{
unsigned
long
flags
;
if
(
configure
->
sock
>
1
)
return
-
1
;
#ifdef CONFIG_SA1100_CERF_CPLD
if
(
configure
->
sock
==
1
)
#else
if
(
configure
->
sock
==
0
)
#endif
if
(
configure
->
sock
!=
CERF_SOCKET
)
return
0
;
save_flags_cli
(
flags
);
switch
(
configure
->
vcc
){
case
0
:
break
;
...
...
@@ -119,43 +111,76 @@ static int cerf_pcmcia_configure_socket(const struct pcmcia_configure
case
50
:
case
33
:
#ifdef CONFIG_SA1100_CERF_CPLD
GPDR
|=
GPIO_PWR_SHUTDOWN
;
GPCR
|=
GPIO_PWR_SHUTDOWN
;
GPCR
=
GPIO_PWR_SHUTDOWN
;
#endif
break
;
default:
printk
(
KERN_ERR
"%s(): unrecognized Vcc %u
\n
"
,
__FUNCTION__
,
configure
->
vcc
);
restore_flags
(
flags
);
return
-
1
;
}
if
(
configure
->
reset
)
{
#ifdef CONFIG_SA1100_CERF_CPLD
GPDR
|=
GPIO_CF_RESET
;
GPSR
|=
GPIO_CF_RESET
;
GPSR
=
GPIO_CF_RESET
;
#endif
}
else
{
#ifdef CONFIG_SA1100_CERF_CPLD
GPDR
|=
GPIO_CF_RESET
;
GPCR
|=
GPIO_CF_RESET
;
GPCR
=
GPIO_CF_RESET
;
#endif
}
restore_flags
(
flags
);
return
0
;
}
static
int
cerf_pcmcia_socket_init
(
int
sock
)
{
int
i
;
if
(
sock
==
CERF_SOCKET
)
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
irqs
);
i
++
)
set_irq_type
(
irqs
[
i
].
irq
,
IRQT_BOTHEDGE
);
return
0
;
}
struct
pcmcia_low_level
cerf_pcmcia_ops
=
{
cerf_pcmcia_init
,
cerf_pcmcia_shutdown
,
cerf_pcmcia_socket_state
,
cerf_pcmcia_get_irq_info
,
cerf_pcmcia_configure_socket
static
int
cerf_pcmcia_socket_suspend
(
int
sock
)
{
int
i
;
if
(
sock
==
CERF_SOCKET
)
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
irqs
);
i
++
)
set_irq_type
(
irqs
[
i
].
irq
,
IRQT_NOEDGE
);
return
0
;
}
static
struct
pcmcia_low_level
cerf_pcmcia_ops
=
{
init:
cerf_pcmcia_init
,
shutdown:
cerf_pcmcia_shutdown
,
socket_state:
cerf_pcmcia_socket_state
,
get_irq_info:
cerf_pcmcia_get_irq_info
,
configure_socket:
cerf_pcmcia_configure_socket
,
socket_init:
cerf_pcmcia_socket_init
,
socket_suspend:
cerf_pcmcia_socket_suspend
,
};
int
__init
pcmcia_cerf_init
(
void
)
{
int
ret
=
-
ENODEV
;
if
(
machine_is_cerf
())
ret
=
sa1100_register_pcmcia
(
&
cerf_pcmcia_ops
);
return
ret
;
}
void
__exit
pcmcia_cerf_exit
(
void
)
{
sa1100_unregister_pcmcia
(
&
cerf_pcmcia_ops
);
}
drivers/pcmcia/sa1100_flexanet.c
View file @
f60852d2
...
...
@@ -4,16 +4,25 @@
* PCMCIA implementation routines for Flexanet.
* by Jordi Colomer, 09/05/2001
*
* Yet to be defined.
*/
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <asm/hardware.h>
#include <asm/irq.h>
#include <asm/arch/pcmcia.h>
#include "sa1100_generic.h"
static
struct
{
int
irq
;
const
char
*
name
;
}
irqs
[]
=
{
{
IRQ_GPIO_CF1_CD
,
"CF1_CD"
},
{
IRQ_GPIO_CF1_BVD1
,
"CF1_BVD1"
},
{
IRQ_GPIO_CF2_CD
,
"CF2_CD"
},
{
IRQ_GPIO_CF2_BVD1
,
"CF2_BVD1"
}
};
/*
* Socket initialization.
...
...
@@ -22,9 +31,37 @@
* Must return the number of slots.
*
*/
static
int
flexanet_pcmcia_init
(
struct
pcmcia_init
*
init
){
return
0
;
static
int
flexanet_pcmcia_init
(
struct
pcmcia_init
*
init
)
{
int
i
,
res
;
/* Configure the GPIOs as inputs (BVD2 is not implemented) */
GPDR
&=
~
(
GPIO_CF1_NCD
|
GPIO_CF1_BVD1
|
GPIO_CF1_IRQ
|
GPIO_CF2_NCD
|
GPIO_CF2_BVD1
|
GPIO_CF2_IRQ
);
/* Set IRQ edge */
set_irq_type
(
IRQ_GPIO_CF1_IRQ
,
IRQT_FALLING
);
set_irq_type
(
IRQ_GPIO_CF2_IRQ
,
IRQT_FALLING
);
/* Register the socket interrupts (not the card interrupts) */
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
irqs
);
i
++
)
{
set_irq_type
(
irqs
[
i
].
irq
,
IRQT_NOEDGE
);
res
=
request_irq
(
irqs
[
i
].
irq
,
init
->
handler
,
SA_INTERRUPT
,
irqs
[
i
].
name
,
NULL
);
if
(
res
<
0
)
break
;
}
/* If we failed, then free all interrupts requested thus far. */
if
(
res
<
0
)
{
printk
(
KERN_ERR
"%s: request for IRQ%d failed: %d
\n
"
,
__FUNCTION__
,
irqs
[
i
].
irq
,
res
);
while
(
i
--
)
free_irq
(
irqs
[
i
].
irq
,
NULL
);
return
res
;
}
return
2
;
}
...
...
@@ -34,6 +71,12 @@ static int flexanet_pcmcia_init(struct pcmcia_init *init){
*/
static
int
flexanet_pcmcia_shutdown
(
void
)
{
int
i
;
/* disable IRQs */
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
irqs
);
i
++
)
free_irq
(
irqs
[
i
].
irq
,
NULL
);
return
0
;
}
...
...
@@ -46,7 +89,33 @@ static int flexanet_pcmcia_shutdown(void)
*/
static
int
flexanet_pcmcia_socket_state
(
struct
pcmcia_state_array
*
state_array
){
unsigned
long
levels
;
if
(
state_array
->
size
<
2
)
return
-
1
;
/* Sense the GPIOs, asynchronously */
levels
=
GPLR
;
/* Socket 0 */
state_array
->
state
[
0
].
detect
=
((
levels
&
GPIO_CF1_NCD
)
==
0
)
?
1
:
0
;
state_array
->
state
[
0
].
ready
=
(
levels
&
GPIO_CF1_IRQ
)
?
1
:
0
;
state_array
->
state
[
0
].
bvd1
=
(
levels
&
GPIO_CF1_BVD1
)
?
1
:
0
;
state_array
->
state
[
0
].
bvd2
=
1
;
state_array
->
state
[
0
].
wrprot
=
0
;
state_array
->
state
[
0
].
vs_3v
=
1
;
state_array
->
state
[
0
].
vs_Xv
=
0
;
/* Socket 1 */
state_array
->
state
[
1
].
detect
=
((
levels
&
GPIO_CF2_NCD
)
==
0
)
?
1
:
0
;
state_array
->
state
[
1
].
ready
=
(
levels
&
GPIO_CF2_IRQ
)
?
1
:
0
;
state_array
->
state
[
1
].
bvd1
=
(
levels
&
GPIO_CF2_BVD1
)
?
1
:
0
;
state_array
->
state
[
1
].
bvd2
=
1
;
state_array
->
state
[
1
].
wrprot
=
0
;
state_array
->
state
[
1
].
vs_3v
=
1
;
state_array
->
state
[
1
].
vs_Xv
=
0
;
return
1
;
}
...
...
@@ -56,7 +125,16 @@ static int flexanet_pcmcia_socket_state(struct pcmcia_state_array
*/
static
int
flexanet_pcmcia_get_irq_info
(
struct
pcmcia_irq_info
*
info
){
/* check the socket index */
if
(
info
->
sock
>
1
)
return
-
1
;
if
(
info
->
sock
==
0
)
info
->
irq
=
IRQ_GPIO_CF1_IRQ
;
else
if
(
info
->
sock
==
1
)
info
->
irq
=
IRQ_GPIO_CF2_IRQ
;
return
0
;
}
...
...
@@ -66,19 +144,105 @@ static int flexanet_pcmcia_get_irq_info(struct pcmcia_irq_info *info){
static
int
flexanet_pcmcia_configure_socket
(
const
struct
pcmcia_configure
*
configure
)
{
unsigned
long
value
,
flags
,
mask
;
if
(
configure
->
sock
>
1
)
return
-
1
;
/* Ignore the VCC level since it is 3.3V and always on */
switch
(
configure
->
vcc
)
{
case
0
:
printk
(
KERN_WARNING
"%s(): CS asked to power off.
\n
"
,
__FUNCTION__
);
break
;
case
50
:
printk
(
KERN_WARNING
"%s(): CS asked for 5V, applying 3.3V...
\n
"
,
__FUNCTION__
);
case
33
:
break
;
default:
printk
(
KERN_ERR
"%s(): unrecognized Vcc %u
\n
"
,
__FUNCTION__
,
configure
->
vcc
);
return
-
1
;
}
/* Reset the slot(s) using the controls in the BCR */
mask
=
0
;
switch
(
configure
->
sock
)
{
case
0
:
mask
=
FHH_BCR_CF1_RST
;
break
;
case
1
:
mask
=
FHH_BCR_CF2_RST
;
break
;
}
local_irq_save
(
flags
);
value
=
flexanet_BCR
;
value
=
(
configure
->
reset
)
?
(
value
|
mask
)
:
(
value
&
~
mask
);
FHH_BCR
=
flexanet_BCR
=
value
;
local_irq_restore
(
flags
);
return
0
;
}
static
int
flexanet_pcmcia_socket_init
(
int
sock
)
{
if
(
sock
==
0
)
{
set_irq_type
(
IRQ_GPIO_CF1_CD
,
IRQT_BOTHEDGE
);
set_irq_type
(
IRQ_GPIO_CF1_BVD1
,
IRQT_BOTHEDGE
);
}
else
if
(
sock
==
1
)
{
set_irq_type
(
IRQ_GPIO_CF2_CD
,
IRQT_BOTHEDGE
);
set_irq_type
(
IRQ_GPIO_CF2_BVD1
,
IRQT_BOTHEDGE
);
}
return
0
;
}
static
int
flexanet_pcmcia_socket_suspend
(
int
sock
)
{
if
(
sock
==
0
)
{
set_irq_type
(
IRQ_GPIO_CF1_CD
,
IRQT_NOEDGE
);
set_irq_type
(
IRQ_GPIO_CF1_BVD1
,
IRQT_NOEDGE
);
}
else
if
(
sock
==
1
)
{
set_irq_type
(
IRQ_GPIO_CF2_CD
,
IRQT_NOEDGE
);
set_irq_type
(
IRQ_GPIO_CF2_BVD1
,
IRQT_NOEDGE
);
}
return
0
;
}
/*
* The set of socket operations
*
*/
struct
pcmcia_low_level
flexanet_pcmcia_ops
=
{
flexanet_pcmcia_init
,
flexanet_pcmcia_shutdown
,
flexanet_pcmcia_socket_state
,
flexanet_pcmcia_get_irq_info
,
flexanet_pcmcia_configure_socket
static
struct
pcmcia_low_level
flexanet_pcmcia_ops
=
{
init:
flexanet_pcmcia_init
,
shutdown:
flexanet_pcmcia_shutdown
,
socket_state:
flexanet_pcmcia_socket_state
,
get_irq_info:
flexanet_pcmcia_get_irq_info
,
configure_socket:
flexanet_pcmcia_configure_socket
,
socket_init:
flexanet_pcmcia_socket_init
,
socket_suspend:
flexanet_pcmcia_socket_suspend
,
};
int
__init
pcmcia_flexanet_init
(
void
)
{
int
ret
=
-
ENODEV
;
if
(
machine_is_flexanet
())
ret
=
sa1100_register_pcmcia
(
&
flexanet_pcmcia_ops
);
return
ret
;
}
void
__exit
pcmcia_flexanet_exit
(
void
)
{
sa1100_unregister_pcmcia
(
&
flexanet_pcmcia_ops
);
}
drivers/pcmcia/sa1100_freebird.c
View file @
f60852d2
...
...
@@ -6,14 +6,22 @@
*/
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <asm/hardware.h>
#include <asm/irq.h>
#include <asm/arch/pcmcia.h>
#include "sa1100_generic.h"
static
struct
irqs
{
int
irq
;
const
char
*
str
;
}
irqs
[]
=
{
{
IRQ_GPIO_FREEBIRD_CF_CD
,
"CF_CD"
},
{
IRQ_GPIO_FREEBIRD_CF_BVD
,
"CF_BVD1"
},
};
static
int
freebird_pcmcia_init
(
struct
pcmcia_init
*
init
){
int
i
rq
,
res
;
int
i
,
res
;
/* Enable Linkup CF card */
LINKUP_PRC
=
0xc0
;
...
...
@@ -26,37 +34,38 @@ static int freebird_pcmcia_init(struct pcmcia_init *init){
mdelay
(
100
);
LINKUP_PRC
=
0xc0
;
/* All those are inputs */
////GPDR &= ~(GPIO_CF_CD | GPIO_CF_BVD2 | GPIO_CF_BVD1 | GPIO_CF_IRQ);
GPDR
&=
~
(
GPIO_FREEBIRD_CF_CD
|
GPIO_FREEBIRD_CF_IRQ
|
GPIO_FREEBIRD_CF_BVD
);
/* Set transition detect */
//set_GPIO_IRQ_edge( GPIO_CF_CD|GPIO_CF_BVD2|GPIO_CF_BVD1, GPIO_BOTH_EDGES );
//set_GPIO_IRQ_edge( GPIO_CF_IRQ, GPIO_FALLING_EDGE );
set_GPIO_IRQ_edge
(
GPIO_FREEBIRD_CF_CD
|
GPIO_FREEBIRD_CF_BVD
,
GPIO_BOTH_EDGES
);
set_GPIO_IRQ_edge
(
GPIO_FREEBIRD_CF_IRQ
,
GPIO_FALLING_EDGE
);
set_irq_type
(
IRQ_GPIO_FREEBIRD_CF_IRQ
,
IRQT_FALLING
);
/* Register interrupts */
irq
=
IRQ_GPIO_FREEBIRD_CF_CD
;
res
=
request_irq
(
irq
,
init
->
handler
,
SA_INTERRUPT
,
"CF_CD"
,
NULL
);
if
(
res
<
0
)
goto
irq_err
;
irq
=
IRQ_GPIO_FREEBIRD_CF_BVD
;
res
=
request_irq
(
irq
,
init
->
handler
,
SA_INTERRUPT
,
"CF_BVD1"
,
NULL
);
if
(
res
<
0
)
goto
irq_err
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
irqs
);
i
++
)
{
set_irq_type
(
irqs
[
i
].
irq
,
IRQT_NOEDGE
);
res
=
request_irq
(
irqs
[
i
].
irq
,
init
->
handler
,
SA_INTERRUPT
,
irqs
[
i
].
str
,
NULL
);
if
(
res
)
goto
irq_err
;
}
/* There's only one slot, but it's "Slot 1": */
return
2
;
irq_err:
printk
(
KERN_ERR
"%s: Request for IRQ %lu failed
\n
"
,
__FUNCTION__
,
irq
);
return
-
1
;
printk
(
KERN_ERR
"%s: request for IRQ%d failed (%d)
\n
"
,
__FUNCTION__
,
irqs
[
i
].
irq
,
res
);
while
(
i
--
)
free_irq
(
irqs
[
i
].
irq
,
NULL
);
return
res
;
}
static
int
freebird_pcmcia_shutdown
(
void
)
{
int
i
;
/* disable IRQs */
f
ree_irq
(
IRQ_GPIO_FREEBIRD_CF_CD
,
NULL
);
free_irq
(
IRQ_GPIO_FREEBIRD_CF_BVD
,
NULL
);
f
or
(
i
=
0
;
i
<
ARRAY_SIZE
(
irqs
);
i
++
)
free_irq
(
irqs
[
i
].
irq
,
NULL
);
/* Disable CF card */
LINKUP_PRC
=
0x40
;
/* SSP=1 SOE=0 */
...
...
@@ -75,7 +84,7 @@ static int freebird_pcmcia_socket_state(struct pcmcia_state_array
(
state_array
->
size
)
*
sizeof
(
struct
pcmcia_state
));
levels
=
LINKUP_PRS
;
//printk("LINKUP_PRS=%x
\n",levels);
//printk("LINKUP_PRS=%x\n",levels);
state_array
->
state
[
0
].
detect
=
((
levels
&
(
LINKUP_CD1
|
LINKUP_CD2
))
==
0
)
?
1
:
0
;
...
...
@@ -114,7 +123,7 @@ static int freebird_pcmcia_configure_socket(const struct pcmcia_configure
if
(
configure
->
sock
==
1
)
return
0
;
save_flags_cli
(
flags
);
local_irq_save
(
flags
);
value
=
0xc0
;
/* SSP=1 SOE=1 CFE=1 */
...
...
@@ -134,7 +143,7 @@ static int freebird_pcmcia_configure_socket(const struct pcmcia_configure
default:
printk
(
KERN_ERR
"%s(): unrecognized Vcc %u
\n
"
,
__FUNCTION__
,
configure
->
vcc
);
restore_flags
(
flags
);
local_irq_restore
(
flags
);
return
-
1
;
}
...
...
@@ -145,16 +154,51 @@ static int freebird_pcmcia_configure_socket(const struct pcmcia_configure
LINKUP_PRC
=
value
;
//printk("LINKUP_PRC=%x\n",value);
restore_flags
(
flags
);
local_irq_restore
(
flags
);
return
0
;
}
static
int
freebird_pcmcia_socket_init
(
int
sock
)
{
if
(
sock
==
1
)
{
set_irq_type
(
IRQ_GPIO_FREEBIRD_CF_CD
,
IRQT_BOTHEDGE
);
set_irq_type
(
IRQ_GPIO_FREEBIRD_CF_BVD
,
IRQT_BOTHEDGE
);
}
return
0
;
}
static
int
freebird_pcmcia_socket_suspend
(
int
sock
)
{
if
(
sock
==
1
)
{
set_irq_type
(
IRQ_GPIO_FREEBIRD_CF_CD
,
IRQT_NOEDGE
);
set_irq_type
(
IRQ_GPIO_FREEBIRD_CF_BVD
,
IRQT_NOEDGE
);
}
return
0
;
}
struct
pcmcia_low_level
freebird_pcmcia_ops
=
{
freebird_pcmcia_init
,
freebird_pcmcia_shutdown
,
freebird_pcmcia_socket_state
,
freebird_pcmcia_get_irq_info
,
freebird_pcmcia_configure_socket
static
struct
pcmcia_low_level
freebird_pcmcia_ops
=
{
init:
freebird_pcmcia_init
,
shutdown:
freebird_pcmcia_shutdown
,
socket_state:
freebird_pcmcia_socket_state
,
get_irq_info:
freebird_pcmcia_get_irq_info
,
configure_socket:
freebird_pcmcia_configure_socket
,
socket_init:
freebird_pcmcia_socket_init
,
socket_suspend:
freebird_pcmcia_socket_suspend
,
};
int
__init
pcmcia_freebird_init
(
void
)
{
int
ret
=
-
ENODEV
;
if
(
machine_is_freebird
())
ret
=
sa1100_register_pcmcia
(
&
freebird_pcmcia_ops
);
return
ret
;
}
void
__exit
pcmcia_freebird_exit
(
void
)
{
sa1100_unregister_pcmcia
(
&
freebird_pcmcia_ops
);
}
drivers/pcmcia/sa1100_generic.c
View file @
f60852d2
...
...
@@ -29,6 +29,10 @@
file under either the MPL or the GPL.
======================================================================*/
/*
* Please see linux/Documentation/arm/SA1100/PCMCIA for more information
* on the low-level kernel interface.
*/
#include <linux/module.h>
#include <linux/init.h>
...
...
@@ -43,6 +47,7 @@
#include <linux/notifier.h>
#include <linux/proc_fs.h>
#include <linux/version.h>
#include <linux/cpufreq.h>
#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
...
...
@@ -62,338 +67,94 @@
static
int
pc_debug
;
#endif
MODULE_AUTHOR
(
"John Dorsey <john+@cs.cmu.edu>"
);
MODULE_DESCRIPTION
(
"Linux PCMCIA Card Services: SA-1100 Socket Controller"
);
/* This structure maintains housekeeping state for each socket, such
* as the last known values of the card detect pins, or the Card Services
* callback value associated with the socket:
*/
static
struct
sa1100_pcmcia_socket
sa1100_pcmcia_socket
[
SA1100_PCMCIA_MAX_SOCK
];
static
int
sa1100_pcmcia_socket_count
;
static
struct
sa1100_pcmcia_socket
sa1100_pcmcia_socket
[
SA1100_PCMCIA_MAX_SOCK
];
#define PCMCIA_SOCKET(x) (sa1100_pcmcia_socket + (x))
/* Returned by the low-level PCMCIA interface: */
static
struct
pcmcia_low_level
*
pcmcia_low_level
;
/* Event poll timer structure */
static
struct
timer_list
poll_timer
;
/* Prototypes for routines which are used internally: */
static
int
sa1100_pcmcia_driver_init
(
void
);
static
void
sa1100_pcmcia_driver_shutdown
(
void
);
static
void
sa1100_pcmcia_task_handler
(
void
*
data
);
static
void
sa1100_pcmcia_poll_event
(
unsigned
long
data
);
static
void
sa1100_pcmcia_interrupt
(
int
irq
,
void
*
dev
,
struct
pt_regs
*
regs
);
static
struct
tq_struct
sa1100_pcmcia_task
;
#ifdef CONFIG_PROC_FS
static
int
sa1100_pcmcia_proc_status
(
char
*
buf
,
char
**
start
,
off_t
pos
,
int
count
,
int
*
eof
,
void
*
data
);
#endif
/* Prototypes for operations which are exported to the
* new-and-impr^H^H^H^H^H^H^H^H^H^H in-kernel PCMCIA core:
*/
static
int
sa1100_pcmcia_init
(
unsigned
int
sock
);
static
int
sa1100_pcmcia_suspend
(
unsigned
int
sock
);
static
int
sa1100_pcmcia_register_callback
(
unsigned
int
sock
,
void
(
*
handler
)(
void
*
,
unsigned
int
),
void
*
info
);
static
int
sa1100_pcmcia_inquire_socket
(
unsigned
int
sock
,
socket_cap_t
*
cap
);
static
int
sa1100_pcmcia_get_status
(
unsigned
int
sock
,
u_int
*
value
);
static
int
sa1100_pcmcia_get_socket
(
unsigned
int
sock
,
socket_state_t
*
state
);
static
int
sa1100_pcmcia_set_socket
(
unsigned
int
sock
,
socket_state_t
*
state
);
static
int
sa1100_pcmcia_get_io_map
(
unsigned
int
sock
,
struct
pccard_io_map
*
io
);
static
int
sa1100_pcmcia_set_io_map
(
unsigned
int
sock
,
struct
pccard_io_map
*
io
);
static
int
sa1100_pcmcia_get_mem_map
(
unsigned
int
sock
,
struct
pccard_mem_map
*
mem
);
static
int
sa1100_pcmcia_set_mem_map
(
unsigned
int
sock
,
struct
pccard_mem_map
*
mem
);
#ifdef CONFIG_PROC_FS
static
void
sa1100_pcmcia_proc_setup
(
unsigned
int
sock
,
struct
proc_dir_entry
*
base
);
#endif
static
struct
pccard_operations
sa1100_pcmcia_operations
=
{
sa1100_pcmcia_init
,
sa1100_pcmcia_suspend
,
sa1100_pcmcia_register_callback
,
sa1100_pcmcia_inquire_socket
,
sa1100_pcmcia_get_status
,
sa1100_pcmcia_get_socket
,
sa1100_pcmcia_set_socket
,
sa1100_pcmcia_get_io_map
,
sa1100_pcmcia_set_io_map
,
sa1100_pcmcia_get_mem_map
,
sa1100_pcmcia_set_mem_map
,
#ifdef CONFIG_PROC_FS
sa1100_pcmcia_proc_setup
#endif
};
#ifdef CONFIG_CPU_FREQ
/* forward declaration */
static
struct
notifier_block
sa1100_pcmcia_notifier_block
;
#endif
/* sa1100_pcmcia_driver_init()
* ^^^^^^^^^^^^^^^^^^^^^^^^^^^
/*
* sa1100_pcmcia_state_to_config
* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
*
* This routine performs a basic sanity check to ensure that this
* kernel has been built with the appropriate board-specific low-level
* PCMCIA support, performs low-level PCMCIA initialization, registers
* this socket driver with Card Services, and then spawns the daemon
* thread which is the real workhorse of the socket driver.
*
* Please see linux/Documentation/arm/SA1100/PCMCIA for more information
* on the low-level kernel interface.
*
* Returns: 0 on success, -1 on error
* Convert PCMCIA socket state to our socket configure structure.
*/
static
int
__init
sa1100_pcmcia_driver_init
(
void
){
servinfo_t
info
;
struct
pcmcia_init
pcmcia_init
;
struct
pcmcia_state
state
[
SA1100_PCMCIA_MAX_SOCK
];
struct
pcmcia_state_array
state_array
;
unsigned
int
i
,
clock
;
unsigned
long
mecr
;
printk
(
KERN_INFO
"SA-1100 PCMCIA (CS release %s)
\n
"
,
CS_RELEASE
);
CardServices
(
GetCardServicesInfo
,
&
info
);
if
(
info
.
Revision
!=
CS_RELEASE_CODE
){
printk
(
KERN_ERR
"Card Services release codes do not match
\n
"
);
return
-
1
;
}
if
(
machine_is_assabet
()){
#ifdef CONFIG_SA1100_ASSABET
if
(
machine_has_neponset
()){
#ifdef CONFIG_ASSABET_NEPONSET
pcmcia_low_level
=&
neponset_pcmcia_ops
;
#else
printk
(
KERN_ERR
"Card Services disabled: missing Neponset support
\n
"
);
return
-
1
;
#endif
}
else
{
pcmcia_low_level
=&
assabet_pcmcia_ops
;
}
#endif
}
else
if
(
machine_is_freebird
())
{
#ifdef CONFIG_SA1100_FREEBIRD
pcmcia_low_level
=
&
freebird_pcmcia_ops
;
#endif
}
else
if
(
machine_is_h3600
())
{
#ifdef CONFIG_SA1100_H3600
pcmcia_low_level
=
&
h3600_pcmcia_ops
;
#endif
}
else
if
(
machine_is_cerf
())
{
#ifdef CONFIG_SA1100_CERF
pcmcia_low_level
=
&
cerf_pcmcia_ops
;
#endif
}
else
if
(
machine_is_graphicsclient
())
{
#ifdef CONFIG_SA1100_GRAPHICSCLIENT
pcmcia_low_level
=
&
gcplus_pcmcia_ops
;
#endif
}
else
if
(
machine_is_xp860
())
{
#ifdef CONFIG_SA1100_XP860
pcmcia_low_level
=
&
xp860_pcmcia_ops
;
#endif
}
else
if
(
machine_is_yopy
())
{
#ifdef CONFIG_SA1100_YOPY
pcmcia_low_level
=
&
yopy_pcmcia_ops
;
#endif
}
else
if
(
machine_is_pangolin
())
{
#ifdef CONFIG_SA1100_PANGOLIN
pcmcia_low_level
=
&
pangolin_pcmcia_ops
;
#endif
}
else
if
(
machine_is_jornada720
())
{
#ifdef CONFIG_SA1100_JORNADA720
pcmcia_low_level
=
&
jornada720_pcmcia_ops
;
#endif
}
else
if
(
machine_is_pfs168
()){
#ifdef CONFIG_SA1100_PFS168
pcmcia_low_level
=&
pfs168_pcmcia_ops
;
#endif
}
else
if
(
machine_is_flexanet
()){
#ifdef CONFIG_SA1100_FLEXANET
pcmcia_low_level
=&
flexanet_pcmcia_ops
;
#endif
}
else
if
(
machine_is_simpad
()){
#ifdef CONFIG_SA1100_SIMPAD
pcmcia_low_level
=&
simpad_pcmcia_ops
;
#endif
}
else
if
(
machine_is_graphicsmaster
())
{
#ifdef CONFIG_SA1100_GRAPHICSMASTER
pcmcia_low_level
=&
graphicsmaster_pcmcia_ops
;
#endif
}
else
if
(
machine_is_adsbitsy
())
{
#ifdef CONFIG_SA1100_ADSBITSY
pcmcia_low_level
=&
adsbitsy_pcmcia_ops
;
#endif
}
else
if
(
machine_is_stork
())
{
#ifdef CONFIG_SA1100_STORK
pcmcia_low_level
=&
stork_pcmcia_ops
;
#endif
}
if
(
!
pcmcia_low_level
)
{
printk
(
KERN_ERR
"This hardware is not supported by the SA1100 Card Service driver
\n
"
);
return
-
ENODEV
;
}
pcmcia_init
.
handler
=
sa1100_pcmcia_interrupt
;
if
((
sa1100_pcmcia_socket_count
=
pcmcia_low_level
->
init
(
&
pcmcia_init
))
<
0
){
printk
(
KERN_ERR
"Unable to initialize kernel PCMCIA service.
\n
"
);
return
-
EIO
;
}
state_array
.
size
=
sa1100_pcmcia_socket_count
;
state_array
.
state
=
state
;
if
(
pcmcia_low_level
->
socket_state
(
&
state_array
)
<
0
){
printk
(
KERN_ERR
"Unable to get PCMCIA status from kernel.
\n
"
);
return
-
EIO
;
}
/* We initialize the MECR to default values here, because we are
* not guaranteed to see a SetIOMap operation at runtime.
*/
mecr
=
0
;
clock
=
get_cclk_frequency
()
*
100
;
for
(
i
=
0
;
i
<
sa1100_pcmcia_socket_count
;
++
i
){
sa1100_pcmcia_socket
[
i
].
k_state
=
state
[
i
];
/* This is an interim fix. Apparently, SetSocket is no longer
* called to initialize each socket (prior to the first detect
* event). For now, we'll just manually set up the mask.
*/
sa1100_pcmcia_socket
[
i
].
cs_state
.
csc_mask
=
SS_DETECT
;
sa1100_pcmcia_socket
[
i
].
virt_io
=
(
i
==
0
)
?
PCMCIA_IO_0_BASE
:
PCMCIA_IO_1_BASE
;
sa1100_pcmcia_socket
[
i
].
phys_attr
=
_PCMCIAAttr
(
i
);
sa1100_pcmcia_socket
[
i
].
phys_mem
=
_PCMCIAMem
(
i
);
MECR_FAST_SET
(
mecr
,
i
,
0
);
MECR_BSIO_SET
(
mecr
,
i
,
sa1100_pcmcia_mecr_bs
(
SA1100_PCMCIA_IO_ACCESS
,
clock
));
MECR_BSA_SET
(
mecr
,
i
,
sa1100_pcmcia_mecr_bs
(
SA1100_PCMCIA_5V_MEM_ACCESS
,
clock
));
MECR_BSM_SET
(
mecr
,
i
,
sa1100_pcmcia_mecr_bs
(
SA1100_PCMCIA_5V_MEM_ACCESS
,
clock
));
sa1100_pcmcia_socket
[
i
].
speed_io
=
SA1100_PCMCIA_IO_ACCESS
;
sa1100_pcmcia_socket
[
i
].
speed_attr
=
SA1100_PCMCIA_5V_MEM_ACCESS
;
sa1100_pcmcia_socket
[
i
].
speed_mem
=
SA1100_PCMCIA_5V_MEM_ACCESS
;
}
MECR
=
mecr
;
#ifdef CONFIG_CPU_FREQ
if
(
cpufreq_register_notifier
(
&
sa1100_pcmcia_notifier_block
)
<
0
){
printk
(
KERN_ERR
"Unable to register CPU frequency change notifier
\n
"
);
return
-
ENXIO
;
}
#endif
/* Only advertise as many sockets as we can detect: */
if
(
register_ss_entry
(
sa1100_pcmcia_socket_count
,
&
sa1100_pcmcia_operations
)
<
0
){
printk
(
KERN_ERR
"Unable to register socket service routine
\n
"
);
return
-
ENXIO
;
}
/* Start the event poll timer. It will reschedule by itself afterwards. */
sa1100_pcmcia_poll_event
(
0
);
DEBUG
(
1
,
"sa1100: initialization complete
\n
"
);
return
0
;
}
/* sa1100_pcmcia_driver_init() */
module_init
(
sa1100_pcmcia_driver_init
);
/* sa1100_pcmcia_driver_shutdown()
* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
* Invokes the low-level kernel service to free IRQs associated with this
* socket controller and reset GPIO edge detection.
*/
static
void
__exit
sa1100_pcmcia_driver_shutdown
(
void
){
del_timer_sync
(
&
poll_timer
);
unregister_ss_entry
(
&
sa1100_pcmcia_operations
);
#ifdef CONFIG_CPU_FREQ
cpufreq_unregister_notifier
(
&
sa1100_pcmcia_notifier_block
);
#endif
pcmcia_low_level
->
shutdown
();
flush_scheduled_tasks
();
static
struct
pcmcia_configure
sa1100_pcmcia_state_to_config
(
unsigned
int
sock
,
socket_state_t
*
state
)
{
struct
pcmcia_configure
conf
;
DEBUG
(
1
,
"sa1100: shutdown complete
\n
"
);
conf
.
sock
=
sock
;
conf
.
vcc
=
state
->
Vcc
;
conf
.
vpp
=
state
->
Vpp
;
conf
.
output
=
state
->
flags
&
SS_OUTPUT_ENA
?
1
:
0
;
conf
.
speaker
=
state
->
flags
&
SS_SPKR_ENA
?
1
:
0
;
conf
.
reset
=
state
->
flags
&
SS_RESET
?
1
:
0
;
conf
.
irq
=
state
->
io_irq
!=
0
;
return
conf
;
}
module_exit
(
sa1100_pcmcia_driver_shutdown
);
/* sa1100_pcmcia_init()
* ^^^^^^^^^^^^^^^^^^^^
* We perform all of the interesting initialization tasks in
* sa1100_pcmcia_driver_init().
/* sa1100_pcmcia_sock_init()
* ^^^^^^^^^^^^^^^^^^^^^^^^^
*
* (Re-)Initialise the socket, turning on status interrupts
* and PCMCIA bus. This must wait for power to stabilise
* so that the card status signals report correctly.
*
* Returns: 0
*/
static
int
sa1100_pcmcia_init
(
unsigned
int
sock
){
static
int
sa1100_pcmcia_sock_init
(
unsigned
int
sock
)
{
struct
sa1100_pcmcia_socket
*
skt
=
PCMCIA_SOCKET
(
sock
);
struct
pcmcia_configure
conf
;
DEBUG
(
2
,
"%s(): initializing socket %u
\n
"
,
__FUNCTION__
,
sock
);
return
0
;
skt
->
cs_state
=
dead_socket
;
conf
=
sa1100_pcmcia_state_to_config
(
sock
,
&
dead_socket
);
pcmcia_low_level
->
configure_socket
(
&
conf
);
return
pcmcia_low_level
->
socket_init
(
sock
);
}
/* sa1100_pcmcia_suspend()
/*
* sa1100_pcmcia_suspend()
* ^^^^^^^^^^^^^^^^^^^^^^^
* We don't currently perform any actions on a suspend.
*
* Remove power on the socket, disable IRQs from the card.
* Turn off status interrupts, and disable the PCMCIA bus.
*
* Returns: 0
*/
static
int
sa1100_pcmcia_suspend
(
unsigned
int
sock
)
{
struct
sa1100_pcmcia_socket
*
skt
=
PCMCIA_SOCKET
(
sock
);
struct
pcmcia_configure
conf
;
int
ret
;
DEBUG
(
2
,
"%s(): suspending socket %u
\n
"
,
__FUNCTION__
,
sock
);
conf
.
sock
=
sock
;
conf
.
vcc
=
0
;
conf
.
vpp
=
0
;
conf
.
output
=
0
;
conf
.
speaker
=
0
;
conf
.
reset
=
1
;
conf
=
sa1100_pcmcia_state_to_config
(
sock
,
&
dead_socket
);
ret
=
pcmcia_low_level
->
configure_socket
(
&
conf
);
if
(
ret
==
0
)
sa1100_pcmcia_socket
[
sock
].
cs_state
=
dead_socket
;
if
(
ret
==
0
)
{
skt
->
cs_state
=
dead_socket
;
ret
=
pcmcia_low_level
->
socket_suspend
(
sock
);
}
return
ret
;
}
...
...
@@ -407,52 +168,50 @@ static int sa1100_pcmcia_suspend(unsigned int sock)
*
* Returns: an event mask for the given socket state.
*/
static
inline
unsigned
sa1100_pcmcia_events
(
struct
pcmcia_state
*
state
,
static
inline
unsigned
int
sa1100_pcmcia_events
(
struct
pcmcia_state
*
state
,
struct
pcmcia_state
*
prev_state
,
unsigned
int
mask
,
unsigned
int
flags
){
unsigned
int
events
=
0
;
if
(
state
->
detect
!=
prev_state
->
detect
){
unsigned
int
mask
,
unsigned
int
flags
)
{
unsigned
int
events
=
0
;
DEBUG
(
2
,
"%s(): card detect value %u
\n
"
,
__FUNCTION__
,
state
->
detect
);
if
(
state
->
detect
!=
prev_state
->
detect
)
{
DEBUG
(
3
,
"%s(): card detect value %u
\n
"
,
__FUNCTION__
,
state
->
detect
);
events
|=
mask
&
SS_DETECT
;
events
|=
SS_DETECT
;
}
if
(
state
->
ready
!=
prev_state
->
ready
){
DEBUG
(
2
,
"%s(): card ready value %u
\n
"
,
__FUNCTION__
,
state
->
ready
);
if
(
state
->
ready
!=
prev_state
->
ready
)
{
DEBUG
(
3
,
"%s(): card ready value %u
\n
"
,
__FUNCTION__
,
state
->
ready
);
events
|=
mask
&
((
flags
&
SS_IOCARD
)
?
0
:
SS_READY
)
;
events
|=
flags
&
SS_IOCARD
?
0
:
SS_READY
;
}
if
(
state
->
bvd1
!=
prev_state
->
bvd1
){
if
(
state
->
bvd1
!=
prev_state
->
bvd1
)
{
DEBUG
(
3
,
"%s(): card BVD1 value %u
\n
"
,
__FUNCTION__
,
state
->
bvd1
);
DEBUG
(
2
,
"%s(): card BVD1 value %u
\n
"
,
__FUNCTION__
,
state
->
bvd1
);
events
|=
mask
&
(
flags
&
SS_IOCARD
)
?
SS_STSCHG
:
SS_BATDEAD
;
events
|=
flags
&
SS_IOCARD
?
SS_STSCHG
:
SS_BATDEAD
;
}
if
(
state
->
bvd2
!=
prev_state
->
bvd2
){
DEBUG
(
2
,
"%s(): card BVD2 value %u
\n
"
,
__FUNCTION__
,
state
->
bvd2
);
if
(
state
->
bvd2
!=
prev_state
->
bvd2
)
{
DEBUG
(
3
,
"%s(): card BVD2 value %u
\n
"
,
__FUNCTION__
,
state
->
bvd2
);
events
|=
mask
&
(
flags
&
SS_IOCARD
)
?
0
:
SS_BATWARN
;
events
|=
flags
&
SS_IOCARD
?
0
:
SS_BATWARN
;
}
DEBUG
(
2
,
"events: %s%s%s%s%s%s
\n
"
,
(
events
==
0
)
?
"<NONE>"
:
""
,
(
events
&
SS_DETECT
)
?
"DETECT "
:
""
,
(
events
&
SS_READY
)
?
"READY "
:
""
,
(
events
&
SS_BATDEAD
)
?
"BATDEAD "
:
""
,
(
events
&
SS_BATWARN
)
?
"BATWARN "
:
""
,
(
events
&
SS_STSCHG
)
?
"STSCHG "
:
""
);
*
prev_state
=
*
state
;
*
prev_state
=*
state
;
events
&=
mask
;
return
events
;
DEBUG
(
2
,
"events: %s%s%s%s%s%s
\n
"
,
events
==
0
?
"<NONE>"
:
""
,
events
&
SS_DETECT
?
"DETECT "
:
""
,
events
&
SS_READY
?
"READY "
:
""
,
events
&
SS_BATDEAD
?
"BATDEAD "
:
""
,
events
&
SS_BATWARN
?
"BATWARN "
:
""
,
events
&
SS_STSCHG
?
"STSCHG "
:
""
);
return
events
;
}
/* sa1100_pcmcia_events() */
...
...
@@ -464,38 +223,43 @@ static inline unsigned sa1100_pcmcia_events(struct pcmcia_state *state,
* callback) occurs in this thread rather than in the actual interrupt
* handler due to the use of scheduling operations in the PCMCIA core.
*/
static
void
sa1100_pcmcia_task_handler
(
void
*
data
)
{
static
void
sa1100_pcmcia_task_handler
(
void
*
data
)
{
struct
pcmcia_state
state
[
SA1100_PCMCIA_MAX_SOCK
];
struct
pcmcia_state_array
state_array
;
int
i
,
events
,
all_events
,
irq_statu
s
;
unsigned
int
all_event
s
;
DEBUG
(
2
,
"%s(): entering PCMCIA monitoring thread
\n
"
,
__FUNCTION__
);
DEBUG
(
4
,
"%s(): entering PCMCIA monitoring thread
\n
"
,
__FUNCTION__
);
state_array
.
size
=
sa1100_pcmcia_socket_count
;
state_array
.
state
=
state
;
state_array
.
size
=
sa1100_pcmcia_socket_count
;
state_array
.
state
=
state
;
do
{
unsigned
int
events
;
int
ret
,
i
;
DEBUG
(
3
,
"%s(): interrogating low-level PCMCIA service
\n
"
,
__FUNCTION__
);
memset
(
state
,
0
,
sizeof
(
state
)
);
if
((
irq_status
=
pcmcia_low_level
->
socket_state
(
&
state_array
))
<
0
)
printk
(
KERN_ERR
"Error in kernel low-level PCMCIA service.
\n
"
);
DEBUG
(
4
,
"%s(): interrogating low-level PCMCIA service
\n
"
,
__FUNCTION__
);
all_events
=
0
;
ret
=
pcmcia_low_level
->
socket_state
(
&
state_array
);
if
(
ret
<
0
)
{
printk
(
KERN_ERR
"sa1100_pcmcia: unable to read socket status
\n
"
);
break
;
}
if
(
irq_status
>
0
){
all_events
=
0
;
for
(
i
=
0
;
i
<
state_array
.
size
;
++
i
,
all_events
|=
events
)
if
((
events
=
sa1100_pcmcia_events
(
&
state
[
i
],
&
sa1100_pcmcia_socket
[
i
].
k_state
,
sa1100_pcmcia_socket
[
i
].
cs_state
.
csc_mask
,
sa1100_pcmcia_socket
[
i
].
cs_state
.
flags
)))
if
(
sa1100_pcmcia_socket
[
i
].
handler
!=
NULL
)
sa1100_pcmcia_socket
[
i
].
handler
(
sa1100_pcmcia_socket
[
i
].
handler_info
,
events
);
}
for
(
i
=
0
;
i
<
state_array
.
size
;
i
++
,
all_events
|=
events
)
{
struct
sa1100_pcmcia_socket
*
skt
=
PCMCIA_SOCKET
(
i
);
events
=
sa1100_pcmcia_events
(
&
state
[
i
],
&
skt
->
k_state
,
skt
->
cs_state
.
csc_mask
,
skt
->
cs_state
.
flags
);
if
(
events
&&
sa1100_pcmcia_socket
[
i
].
handler
!=
NULL
)
skt
->
handler
(
skt
->
handler_info
,
events
);
}
}
while
(
all_events
);
}
/* sa1100_pcmcia_task_handler() */
...
...
@@ -510,7 +274,7 @@ static struct tq_struct sa1100_pcmcia_task = {
*/
static
void
sa1100_pcmcia_poll_event
(
unsigned
long
dummy
)
{
DEBUG
(
3
,
"%s(): polling for events
\n
"
,
__FUNCTION__
);
DEBUG
(
4
,
"%s(): polling for events
\n
"
,
__FUNCTION__
);
poll_timer
.
function
=
sa1100_pcmcia_poll_event
;
poll_timer
.
expires
=
jiffies
+
SA1100_PCMCIA_POLL_PERIOD
;
add_timer
(
&
poll_timer
);
...
...
@@ -527,7 +291,8 @@ static void sa1100_pcmcia_poll_event(unsigned long dummy)
* handling code performs scheduling operations which cannot be
* executed from within an interrupt context.
*/
static
void
sa1100_pcmcia_interrupt
(
int
irq
,
void
*
dev
,
struct
pt_regs
*
regs
){
static
void
sa1100_pcmcia_interrupt
(
int
irq
,
void
*
dev
,
struct
pt_regs
*
regs
)
{
DEBUG
(
3
,
"%s(): servicing IRQ %d
\n
"
,
__FUNCTION__
,
irq
);
schedule_task
(
&
sa1100_pcmcia_task
);
}
...
...
@@ -546,17 +311,20 @@ static void sa1100_pcmcia_interrupt(int irq, void *dev, struct pt_regs *regs){
*
* Returns: 0
*/
static
int
sa1100_pcmcia_register_callback
(
unsigned
int
sock
,
void
(
*
handler
)(
void
*
,
unsigned
int
),
void
*
info
){
if
(
handler
==
NULL
){
sa1100_pcmcia_socket
[
sock
].
handler
=
NULL
;
static
int
sa1100_pcmcia_register_callback
(
unsigned
int
sock
,
void
(
*
handler
)(
void
*
,
unsigned
int
),
void
*
info
)
{
struct
sa1100_pcmcia_socket
*
skt
=
PCMCIA_SOCKET
(
sock
);
if
(
handler
==
NULL
)
{
skt
->
handler
=
NULL
;
MOD_DEC_USE_COUNT
;
}
else
{
MOD_INC_USE_COUNT
;
s
a1100_pcmcia_socket
[
sock
].
handler
=
handler
;
s
a1100_pcmcia_socket
[
sock
].
handler_info
=
info
;
s
kt
->
handler_info
=
info
;
s
kt
->
handler
=
handler
;
}
return
0
;
...
...
@@ -580,20 +348,7 @@ static int sa1100_pcmcia_register_callback(unsigned int sock,
* an offset which is applied to client-requested base I/O addresses
* in alloc_io_space().
*
* Returns: 0 on success, -1 if no pin has been configured for `sock'
*/
static
int
sa1100_pcmcia_inquire_socket
(
unsigned
int
sock
,
socket_cap_t
*
cap
){
struct
pcmcia_irq_info
irq_info
;
DEBUG
(
3
,
"%s() for sock %u
\n
"
,
__FUNCTION__
,
sock
);
if
(
sock
>=
sa1100_pcmcia_socket_count
){
printk
(
KERN_ERR
"sa1100: socket %u not configured
\n
"
,
sock
);
return
-
1
;
}
/* SS_CAP_PAGE_REGS: used by setup_cis_mem() in cistpl.c to set the
* SS_CAP_PAGE_REGS: used by setup_cis_mem() in cistpl.c to set the
* force_low argument to validate_mem() in rsrc_mgr.c -- since in
* general, the mapped * addresses of the PCMCIA memory regions
* will not be within 0xffff, setting force_low would be
...
...
@@ -605,26 +360,29 @@ static int sa1100_pcmcia_inquire_socket(unsigned int sock,
*
* SS_CAP_PCCARD: we can deal with 16-bit PCMCIA & CF cards, but
* not 32-bit CardBus devices.
*
* Return value is irrelevant; the pcmcia subsystem ignores it.
*/
cap
->
features
=
(
SS_CAP_PAGE_REGS
|
SS_CAP_STATIC_MAP
|
SS_CAP_PCCARD
);
irq_info
.
sock
=
sock
;
irq_info
.
irq
=-
1
;
static
int
sa1100_pcmcia_inquire_socket
(
unsigned
int
sock
,
socket_cap_t
*
cap
)
{
struct
sa1100_pcmcia_socket
*
skt
=
PCMCIA_SOCKET
(
sock
);
int
ret
=
-
1
;
if
(
pcmcia_low_level
->
get_irq_info
(
&
irq_info
)
<
0
){
printk
(
KERN_ERR
"Error obtaining IRQ info from kernel for socket %u
\n
"
,
sock
);
return
-
1
;
}
DEBUG
(
2
,
"%s() for sock %u
\n
"
,
__FUNCTION__
,
sock
);
cap
->
irq_mask
=
0
;
cap
->
map_size
=
PAGE_SIZE
;
cap
->
pci_irq
=
irq_info
.
irq
;
cap
->
io_offset
=
sa1100_pcmcia_socket
[
sock
].
virt_io
;
if
(
sock
<
sa1100_pcmcia_socket_count
)
{
cap
->
features
=
SS_CAP_PAGE_REGS
|
SS_CAP_STATIC_MAP
|
SS_CAP_PCCARD
;
cap
->
irq_mask
=
0
;
cap
->
map_size
=
PAGE_SIZE
;
cap
->
pci_irq
=
skt
->
irq
;
cap
->
io_offset
=
(
unsigned
long
)
skt
->
virt_io
;
return
0
;
ret
=
0
;
}
}
/* sa1100_pcmcia_inquire_socket() */
return
ret
;
}
/* sa1100_pcmcia_get_status()
...
...
@@ -643,58 +401,61 @@ static int sa1100_pcmcia_inquire_socket(unsigned int sock,
*
* Returns: 0
*/
static
int
sa1100_pcmcia_get_status
(
unsigned
int
sock
,
unsigned
int
*
status
){
static
int
sa1100_pcmcia_get_status
(
unsigned
int
sock
,
unsigned
int
*
status
)
{
struct
sa1100_pcmcia_socket
*
skt
=
PCMCIA_SOCKET
(
sock
);
struct
pcmcia_state
state
[
SA1100_PCMCIA_MAX_SOCK
];
struct
pcmcia_state_array
state_array
;
unsigned
int
stat
;
DEBUG
(
2
,
"%s() for sock %u
\n
"
,
__FUNCTION__
,
sock
);
DEBUG
(
3
,
"%s() for sock %u
\n
"
,
__FUNCTION__
,
sock
);
state_array
.
size
=
sa1100_pcmcia_socket_count
;
state_array
.
state
=
state
;
state_array
.
size
=
sa1100_pcmcia_socket_count
;
state_array
.
state
=
state
;
memset
(
state
,
0
,
sizeof
(
state
));
if
((
pcmcia_low_level
->
socket_state
(
&
state_array
))
<
0
)
{
printk
(
KERN_ERR
"
Unable to get PCMCIA status from kernel.
\n
"
);
if
((
pcmcia_low_level
->
socket_state
(
&
state_array
))
<
0
)
{
printk
(
KERN_ERR
"
sa1100_pcmcia: unable to get socket status
\n
"
);
return
-
1
;
}
s
a1100_pcmcia_socket
[
sock
].
k_state
=
state
[
sock
];
s
kt
->
k_state
=
state
[
sock
];
*
status
=
state
[
sock
].
detect
?
SS_DETECT
:
0
;
*
status
|=
state
[
sock
].
ready
?
SS_READY
:
0
;
stat
=
state
[
sock
].
detect
?
SS_DETECT
:
0
;
stat
|=
state
[
sock
].
ready
?
SS_READY
:
0
;
stat
|=
state
[
sock
].
vs_3v
?
SS_3VCARD
:
0
;
stat
|=
state
[
sock
].
vs_Xv
?
SS_XVCARD
:
0
;
/* The power status of individual sockets is not available
* explicitly from the hardware, so we just remember the state
* and regurgitate it upon request:
*/
*
status
|=
sa1100_pcmcia_socket
[
sock
].
cs_state
.
Vcc
?
SS_POWERON
:
0
;
stat
|=
skt
->
cs_state
.
Vcc
?
SS_POWERON
:
0
;
if
(
sa1100_pcmcia_socket
[
sock
].
cs_state
.
flags
&
SS_IOCARD
)
*
status
|=
state
[
sock
].
bvd1
?
SS_STSCHG
:
0
;
if
(
skt
->
cs_state
.
flags
&
SS_IOCARD
)
stat
|=
state
[
sock
].
bvd1
?
SS_STSCHG
:
0
;
else
{
if
(
state
[
sock
].
bvd1
==
0
)
*
status
|=
SS_BATDEAD
;
else
if
(
state
[
sock
].
bvd2
==
0
)
*
status
|=
SS_BATWARN
;
if
(
state
[
sock
].
bvd1
==
0
)
stat
|=
SS_BATDEAD
;
else
if
(
state
[
sock
].
bvd2
==
0
)
stat
|=
SS_BATWARN
;
}
*
status
|=
state
[
sock
].
vs_3v
?
SS_3VCARD
:
0
;
*
status
|=
state
[
sock
].
vs_Xv
?
SS_XVCARD
:
0
;
DEBUG
(
3
,
"
\t
status: %s%s%s%s%s%s%s%s
\n
"
,
(
*
status
&
SS_DETECT
)
?
"DETECT "
:
""
,
(
*
status
&
SS_READY
)
?
"READY "
:
""
,
(
*
status
&
SS_BATDEAD
)
?
"BATDEAD "
:
""
,
(
*
status
&
SS_BATWARN
)
?
"BATWARN "
:
""
,
(
*
status
&
SS_POWERON
)
?
"POWERON "
:
""
,
(
*
status
&
SS_STSCHG
)
?
"STSCHG "
:
""
,
(
*
status
&
SS_3VCARD
)
?
"3VCARD "
:
""
,
(
*
status
&
SS_XVCARD
)
?
"XVCARD "
:
""
);
stat
&
SS_DETECT
?
"DETECT "
:
""
,
stat
&
SS_READY
?
"READY "
:
""
,
stat
&
SS_BATDEAD
?
"BATDEAD "
:
""
,
stat
&
SS_BATWARN
?
"BATWARN "
:
""
,
stat
&
SS_POWERON
?
"POWERON "
:
""
,
stat
&
SS_STSCHG
?
"STSCHG "
:
""
,
stat
&
SS_3VCARD
?
"3VCARD "
:
""
,
stat
&
SS_XVCARD
?
"XVCARD "
:
""
);
return
0
;
*
status
=
stat
;
return
0
;
}
/* sa1100_pcmcia_get_status() */
...
...
@@ -706,20 +467,18 @@ static int sa1100_pcmcia_get_status(unsigned int sock,
*
* Returns: 0
*/
static
int
sa1100_pcmcia_get_socket
(
unsigned
int
sock
,
socket_state_t
*
state
){
static
int
sa1100_pcmcia_get_socket
(
unsigned
int
sock
,
socket_state_t
*
state
)
{
struct
sa1100_pcmcia_socket
*
skt
=
PCMCIA_SOCKET
(
sock
);
DEBUG
(
3
,
"%s() for sock %u
\n
"
,
__FUNCTION__
,
sock
);
DEBUG
(
2
,
"%s() for sock %u
\n
"
,
__FUNCTION__
,
sock
);
/* This information was given to us in an earlier call to set_socket(),
* so we're just regurgitating it here:
*/
*
state
=
sa1100_pcmcia_socket
[
sock
].
cs_state
;
*
state
=
skt
->
cs_state
;
return
0
;
}
/* sa1100_pcmcia_set_socket()
* ^^^^^^^^^^^^^^^^^^^^^^^^^^
* Implements the set_socket() operation for the in-kernel PCMCIA
...
...
@@ -730,14 +489,15 @@ static int sa1100_pcmcia_get_socket(unsigned int sock,
*
* Returns: 0
*/
static
int
sa1100_pcmcia_set_socket
(
unsigned
int
sock
,
socket_state_t
*
state
){
struct
pcmcia_configure
configure
;
static
int
sa1100_pcmcia_set_socket
(
unsigned
int
sock
,
socket_state_t
*
state
)
{
struct
sa1100_pcmcia_socket
*
skt
=
PCMCIA_SOCKET
(
sock
);
struct
pcmcia_configure
conf
;
DEBUG
(
3
,
"%s() for sock %u
\n
"
,
__FUNCTION__
,
sock
);
DEBUG
(
2
,
"%s() for sock %u
\n
"
,
__FUNCTION__
,
sock
);
DEBUG
(
3
,
"
\t
mask: %s%s%s%s%s%s
\n\t
flags: %s%s%s%s%s%s
\n
"
"
\t
Vcc %d Vpp %d irq %d
\n
"
,
DEBUG
(
3
,
"
\t
mask: %s%s%s%s%s%s
\n\t
flags: %s%s%s%s%s%s
\n
"
,
(
state
->
csc_mask
==
0
)
?
"<NONE>"
:
""
,
(
state
->
csc_mask
&
SS_DETECT
)
?
"DETECT "
:
""
,
(
state
->
csc_mask
&
SS_READY
)
?
"READY "
:
""
,
...
...
@@ -749,25 +509,20 @@ static int sa1100_pcmcia_set_socket(unsigned int sock,
(
state
->
flags
&
SS_IOCARD
)
?
"IOCARD "
:
""
,
(
state
->
flags
&
SS_RESET
)
?
"RESET "
:
""
,
(
state
->
flags
&
SS_SPKR_ENA
)
?
"SPKR_ENA "
:
""
,
(
state
->
flags
&
SS_OUTPUT_ENA
)
?
"OUTPUT_ENA "
:
""
,
(
state
->
flags
&
SS_OUTPUT_ENA
)
?
"OUTPUT_ENA "
:
""
);
DEBUG
(
3
,
"
\t
Vcc %d Vpp %d irq %d
\n
"
,
state
->
Vcc
,
state
->
Vpp
,
state
->
io_irq
);
configure
.
sock
=
sock
;
configure
.
vcc
=
state
->
Vcc
;
configure
.
vpp
=
state
->
Vpp
;
configure
.
output
=
(
state
->
flags
&
SS_OUTPUT_ENA
)
?
1
:
0
;
configure
.
speaker
=
(
state
->
flags
&
SS_SPKR_ENA
)
?
1
:
0
;
configure
.
reset
=
(
state
->
flags
&
SS_RESET
)
?
1
:
0
;
conf
=
sa1100_pcmcia_state_to_config
(
sock
,
state
);
if
(
pcmcia_low_level
->
configure_socket
(
&
configure
)
<
0
)
{
printk
(
KERN_ERR
"
Unable to configure socket %u
\n
"
,
sock
);
if
(
pcmcia_low_level
->
configure_socket
(
&
conf
)
<
0
)
{
printk
(
KERN_ERR
"
sa1100_pcmcia: unable to configure socket %d
\n
"
,
sock
);
return
-
1
;
}
s
a1100_pcmcia_socket
[
sock
].
cs_state
=
*
state
;
s
kt
->
cs_state
=
*
state
;
return
0
;
}
/* sa1100_pcmcia_set_socket() */
...
...
@@ -779,20 +534,20 @@ static int sa1100_pcmcia_set_socket(unsigned int sock,
*
* Returns: 0 on success, -1 if the map index was out of range
*/
static
int
sa1100_pcmcia_get_io_map
(
unsigned
int
sock
,
struct
pccard_io_map
*
map
){
static
int
sa1100_pcmcia_get_io_map
(
unsigned
int
sock
,
struct
pccard_io_map
*
map
)
{
struct
sa1100_pcmcia_socket
*
skt
=
PCMCIA_SOCKET
(
sock
);
int
ret
=
-
1
;
DEBUG
(
4
,
"%s() for sock %u
\n
"
,
__FUNCTION__
,
sock
);
DEBUG
(
2
,
"%s() for sock %u
\n
"
,
__FUNCTION__
,
sock
);
if
(
map
->
map
>=
MAX_IO_WIN
){
printk
(
KERN_ERR
"%s(): map (%d) out of range
\n
"
,
__FUNCTION__
,
map
->
map
);
return
-
1
;
if
(
map
->
map
<
MAX_IO_WIN
)
{
*
map
=
skt
->
io_map
[
map
->
map
];
ret
=
0
;
}
*
map
=
sa1100_pcmcia_socket
[
sock
].
io_map
[
map
->
map
];
return
0
;
return
ret
;
}
...
...
@@ -805,16 +560,16 @@ static int sa1100_pcmcia_get_io_map(unsigned int sock,
*
* Returns: 0 on success, -1 on error
*/
static
int
sa1100_pcmcia_set_io_map
(
unsigned
int
sock
,
struct
pccard_io_map
*
map
){
unsigned
int
clock
,
speed
;
unsigned
long
mecr
,
start
;
static
int
sa1100_pcmcia_set_io_map
(
unsigned
int
sock
,
struct
pccard_io_map
*
map
)
{
struct
sa1100_pcmcia_socket
*
skt
=
PCMCIA_SOCKET
(
sock
)
;
DEBUG
(
4
,
"%s() for sock %u
\n
"
,
__FUNCTION__
,
sock
);
DEBUG
(
2
,
"%s() for sock %u
\n
"
,
__FUNCTION__
,
sock
);
DEBUG
(
4
,
"
\t
map %u speed %u
\n\t
start 0x%08lx stop 0x%08lx
\n
"
"
\t
flags: %s%s%s%s%s%s%s%s
\n
"
,
map
->
map
,
map
->
speed
,
map
->
start
,
map
->
stop
,
DEBUG
(
3
,
"
\t
map %u speed %u
\n\t
start 0x%08x stop 0x%08x
\n
"
,
map
->
map
,
map
->
speed
,
map
->
start
,
map
->
stop
);
DEBUG
(
3
,
"
\t
flags: %s%s%s%s%s%s%s%s
\n
"
,
(
map
->
flags
==
0
)
?
"<NONE>"
:
""
,
(
map
->
flags
&
MAP_ACTIVE
)
?
"ACTIVE "
:
""
,
(
map
->
flags
&
MAP_16BIT
)
?
"16BIT "
:
""
,
...
...
@@ -824,45 +579,45 @@ static int sa1100_pcmcia_set_io_map(unsigned int sock,
(
map
->
flags
&
MAP_USE_WAIT
)
?
"USE_WAIT "
:
""
,
(
map
->
flags
&
MAP_PREFETCH
)
?
"PREFETCH "
:
""
);
if
(
map
->
map
>=
MAX_IO_WIN
)
{
if
(
map
->
map
>=
MAX_IO_WIN
)
{
printk
(
KERN_ERR
"%s(): map (%d) out of range
\n
"
,
__FUNCTION__
,
map
->
map
);
return
-
1
;
}
if
(
map
->
flags
&
MAP_ACTIVE
){
if
(
map
->
flags
&
MAP_ACTIVE
)
{
unsigned
int
clock
,
speed
=
map
->
speed
;
unsigned
long
mecr
;
speed
=
(
map
->
speed
>
0
)
?
map
->
speed
:
SA1100_PCMCIA_IO_ACCESS
;
if
(
speed
==
0
)
speed
=
SA1100_PCMCIA_IO_ACCESS
;
clock
=
get_cclk_frequency
()
*
100
;
clock
=
cpufreq_get
(
0
)
;
mecr
=
MECR
;
mecr
=
MECR
;
MECR_BSIO_SET
(
mecr
,
sock
,
sa1100_pcmcia_mecr_bs
(
speed
,
clock
));
s
a1100_pcmcia_socket
[
sock
].
speed_io
=
speed
;
s
kt
->
speed_io
=
speed
;
DEBUG
(
4
,
"%s(): FAST%u %lx BSM%u %lx BSA%u %lx BSIO%u %lx
\n
"
,
__FUNCTION__
,
sock
,
MECR_FAST_GET
(
mecr
,
sock
),
sock
,
MECR_BSM_GET
(
mecr
,
sock
),
sock
,
MECR_BSA_GET
(
mecr
,
sock
),
sock
,
MECR_BSIO_GET
(
mecr
,
sock
));
MECR
=
mecr
;
MECR
=
mecr
;
}
start
=
map
->
start
;
if
(
map
->
stop
==
1
)
map
->
stop
=
PAGE_SIZE
-
1
;
if
(
map
->
stop
==
1
)
map
->
stop
=
PAGE_SIZE
-
1
;
map
->
stop
-=
map
->
start
;
map
->
stop
+=
(
unsigned
long
)
skt
->
virt_io
;
map
->
start
=
(
unsigned
long
)
skt
->
virt_io
;
map
->
start
=
sa1100_pcmcia_socket
[
sock
].
virt_io
;
map
->
stop
=
map
->
start
+
(
map
->
stop
-
start
);
sa1100_pcmcia_socket
[
sock
].
io_map
[
map
->
map
]
=*
map
;
skt
->
io_map
[
map
->
map
]
=
*
map
;
return
0
;
}
/* sa1100_pcmcia_set_io_map() */
...
...
@@ -875,20 +630,20 @@ static int sa1100_pcmcia_set_io_map(unsigned int sock,
*
* Returns: 0 on success, -1 if the map index was out of range
*/
static
int
sa1100_pcmcia_get_mem_map
(
unsigned
int
sock
,
struct
pccard_mem_map
*
map
){
static
int
sa1100_pcmcia_get_mem_map
(
unsigned
int
sock
,
struct
pccard_mem_map
*
map
)
{
struct
sa1100_pcmcia_socket
*
skt
=
PCMCIA_SOCKET
(
sock
);
int
ret
=
-
1
;
DEBUG
(
4
,
"%s() for sock %u
\n
"
,
__FUNCTION__
,
sock
);
DEBUG
(
2
,
"%s() for sock %u
\n
"
,
__FUNCTION__
,
sock
);
if
(
map
->
map
>=
MAX_WIN
){
printk
(
KERN_ERR
"%s(): map (%d) out of range
\n
"
,
__FUNCTION__
,
map
->
map
);
return
-
1
;
if
(
map
->
map
<
MAX_WIN
)
{
*
map
=
skt
->
mem_map
[
map
->
map
];
ret
=
0
;
}
*
map
=
sa1100_pcmcia_socket
[
sock
].
mem_map
[
map
->
map
];
return
0
;
return
ret
;
}
...
...
@@ -901,18 +656,18 @@ static int sa1100_pcmcia_get_mem_map(unsigned int sock,
*
* Returns: 0 on success, -1 on error
*/
static
int
sa1100_pcmcia_set_mem_map
(
unsigned
int
sock
,
struct
pccard_mem_map
*
map
){
unsigned
int
clock
,
speed
;
unsigned
long
mecr
,
start
;
static
int
sa1100_pcmcia_set_mem_map
(
unsigned
int
sock
,
struct
pccard_mem_map
*
map
)
{
struct
sa1100_pcmcia_socket
*
skt
=
PCMCIA_SOCKET
(
sock
);
unsigned
long
start
;
DEBUG
(
4
,
"%s() for sock %u
\n
"
,
__FUNCTION__
,
sock
);
DEBUG
(
2
,
"%s() for sock %u
\n
"
,
__FUNCTION__
,
sock
);
DEBUG
(
4
,
"
\t
map %u speed %u
\n\t
sys_start %#lx
\n
"
"
\t
sys_stop %#lx
\n\t
card_start %#x
\n
"
"
\t
flags: %s%s%s%s%s%s%s%s
\n
"
,
map
->
map
,
map
->
speed
,
map
->
sys_start
,
map
->
sys_stop
,
map
->
card_start
,
(
map
->
flags
==
0
)
?
"<NONE>"
:
""
,
DEBUG
(
3
,
"
\t
map %u speed %u sys_start %08lx sys_stop %08lx card_start %08x
\n
"
,
map
->
map
,
map
->
speed
,
map
->
sys_start
,
map
->
sys_stop
,
map
->
card_start
);
DEBUG
(
3
,
"
\t
flags: %s%s%s%s%s%s%s%s
\n
"
,
(
map
->
flags
==
0
)
?
"<NONE>"
:
""
,
(
map
->
flags
&
MAP_ACTIVE
)
?
"ACTIVE "
:
""
,
(
map
->
flags
&
MAP_16BIT
)
?
"16BIT "
:
""
,
(
map
->
flags
&
MAP_AUTOSZ
)
?
"AUTOSZ "
:
""
,
...
...
@@ -921,42 +676,38 @@ static int sa1100_pcmcia_set_mem_map(unsigned int sock,
(
map
->
flags
&
MAP_ATTRIB
)
?
"ATTRIB "
:
""
,
(
map
->
flags
&
MAP_USE_WAIT
)
?
"USE_WAIT "
:
""
);
if
(
map
->
map
>=
MAX_WIN
){
if
(
map
->
map
>=
MAX_WIN
){
printk
(
KERN_ERR
"%s(): map (%d) out of range
\n
"
,
__FUNCTION__
,
map
->
map
);
return
-
1
;
}
if
(
map
->
flags
&
MAP_ACTIVE
){
if
(
map
->
flags
&
MAP_ACTIVE
)
{
unsigned
int
clock
,
speed
=
map
->
speed
;
unsigned
long
mecr
;
/* When clients issue RequestMap, the access speed is not always
* properly configured:
/*
* When clients issue RequestMap, the access speed is not always
* properly configured. Choose some sensible defaults.
*/
if
(
map
->
speed
>
0
)
speed
=
map
->
speed
;
else
switch
(
sa1100_pcmcia_socket
[
sock
].
cs_state
.
Vcc
){
case
33
:
if
(
speed
==
0
)
{
if
(
skt
->
cs_state
.
Vcc
==
33
)
speed
=
SA1100_PCMCIA_3V_MEM_ACCESS
;
break
;
default:
else
speed
=
SA1100_PCMCIA_5V_MEM_ACCESS
;
}
clock
=
get_cclk_frequency
()
*
100
;
mecr
=
MECR
;
clock
=
cpufreq_get
(
0
);
if
(
map
->
flags
&
MAP_ATTRIB
){
/* Fixme: MECR is not pre-empt safe. */
mecr
=
MECR
;
if
(
map
->
flags
&
MAP_ATTRIB
)
{
MECR_BSA_SET
(
mecr
,
sock
,
sa1100_pcmcia_mecr_bs
(
speed
,
clock
));
sa1100_pcmcia_socket
[
sock
].
speed_attr
=
speed
;
skt
->
speed_attr
=
speed
;
}
else
{
MECR_BSM_SET
(
mecr
,
sock
,
sa1100_pcmcia_mecr_bs
(
speed
,
clock
));
sa1100_pcmcia_socket
[
sock
].
speed_mem
=
speed
;
skt
->
speed_mem
=
speed
;
}
DEBUG
(
4
,
"%s(): FAST%u %lx BSM%u %lx BSA%u %lx BSIO%u %lx
\n
"
,
...
...
@@ -964,134 +715,136 @@ static int sa1100_pcmcia_set_mem_map(unsigned int sock,
MECR_BSM_GET
(
mecr
,
sock
),
sock
,
MECR_BSA_GET
(
mecr
,
sock
),
sock
,
MECR_BSIO_GET
(
mecr
,
sock
));
MECR
=
mecr
;
MECR
=
mecr
;
}
start
=
map
->
sys_start
;
if
(
map
->
sys_stop
==
0
)
map
->
sys_stop
=
PAGE_SIZE
-
1
;
start
=
(
map
->
flags
&
MAP_ATTRIB
)
?
skt
->
phys_attr
:
skt
->
phys_mem
;
map
->
sys_start
=
(
map
->
flags
&
MAP_ATTRIB
)
?
\
sa1100_pcmcia_socket
[
sock
].
phys_attr
:
\
sa1100_pcmcia_socket
[
sock
].
phys_mem
;
if
(
map
->
sys_stop
==
0
)
map
->
sys_stop
=
PAGE_SIZE
-
1
;
map
->
sys_stop
=
map
->
sys_start
+
(
map
->
sys_stop
-
start
);
map
->
sys_stop
-=
map
->
sys_start
;
map
->
sys_stop
+=
start
;
map
->
sys_start
=
start
;
s
a1100_pcmcia_socket
[
sock
].
mem_map
[
map
->
map
]
=
*
map
;
s
kt
->
mem_map
[
map
->
map
]
=
*
map
;
return
0
;
}
/* sa1100_pcmcia_set_mem_map() */
#if defined(CONFIG_PROC_FS)
/* sa1100_pcmcia_proc_setup()
* ^^^^^^^^^^^^^^^^^^^^^^^^^^
* Implements the proc_setup() operation for the in-kernel PCMCIA
* service (formerly SS_ProcSetup in Card Services).
*
* Returns: 0 on success, -1 on error
*/
static
void
sa1100_pcmcia_proc_setup
(
unsigned
int
sock
,
struct
proc_dir_entry
*
base
){
struct
proc_dir_entry
*
entry
;
DEBUG
(
4
,
"%s() for sock %u
\n
"
,
__FUNCTION__
,
sock
);
if
((
entry
=
create_proc_entry
(
"status"
,
0
,
base
))
==
NULL
){
printk
(
KERN_ERR
"Unable to install
\"
status
\"
procfs entry
\n
"
);
return
;
}
entry
->
read_proc
=
sa1100_pcmcia_proc_status
;
entry
->
data
=
(
void
*
)
sock
;
}
/* sa1100_pcmcia_proc_status()
* ^^^^^^^^^^^^^^^^^^^^^^^^^^^
* Implements the /proc/bus/pccard/??/status file.
*
* Returns: the number of characters added to the buffer
*/
static
int
sa1100_pcmcia_proc_status
(
char
*
buf
,
char
**
start
,
off_t
pos
,
int
count
,
int
*
eof
,
void
*
data
){
char
*
p
=
buf
;
unsigned
int
sock
=
(
unsigned
int
)
data
;
unsigned
int
clock
=
get_cclk_frequency
()
*
100
;
static
int
sa1100_pcmcia_proc_status
(
char
*
buf
,
char
**
start
,
off_t
pos
,
int
count
,
int
*
eof
,
void
*
data
)
{
unsigned
int
sock
=
(
unsigned
int
)
data
;
unsigned
int
clock
=
cpufreq_get
(
0
);
struct
sa1100_pcmcia_socket
*
skt
=
PCMCIA_SOCKET
(
sock
);
unsigned
long
mecr
=
MECR
;
char
*
p
=
buf
;
p
+=
sprintf
(
p
,
"k_
flags
: %s%s%s%s%s%s%s
\n
"
,
s
a1100_pcmcia_socket
[
sock
].
k_state
.
detect
?
"detect "
:
""
,
s
a1100_pcmcia_socket
[
sock
].
k_state
.
ready
?
"ready "
:
""
,
s
a1100_pcmcia_socket
[
sock
].
k_state
.
bvd1
?
"bvd1 "
:
""
,
s
a1100_pcmcia_socket
[
sock
].
k_state
.
bvd2
?
"bvd2 "
:
""
,
s
a1100_pcmcia_socket
[
sock
].
k_state
.
wrprot
?
"wrprot "
:
""
,
s
a1100_pcmcia_socket
[
sock
].
k_state
.
vs_3v
?
"vs_3v "
:
""
,
s
a1100_pcmcia_socket
[
sock
].
k_state
.
vs_Xv
?
"vs_Xv "
:
""
);
p
+=
sprintf
(
p
,
"k_
state
: %s%s%s%s%s%s%s
\n
"
,
s
kt
->
k_state
.
detect
?
"detect "
:
""
,
s
kt
->
k_state
.
ready
?
"ready "
:
""
,
s
kt
->
k_state
.
bvd1
?
"bvd1 "
:
""
,
s
kt
->
k_state
.
bvd2
?
"bvd2 "
:
""
,
s
kt
->
k_state
.
wrprot
?
"wrprot "
:
""
,
s
kt
->
k_state
.
vs_3v
?
"vs_3v "
:
""
,
s
kt
->
k_state
.
vs_Xv
?
"vs_Xv "
:
""
);
p
+=
sprintf
(
p
,
"status : %s%s%s%s%s%s%s%s%s
\n
"
,
sa1100_pcmcia_socket
[
sock
].
k_state
.
detect
?
"SS_DETECT "
:
""
,
sa1100_pcmcia_socket
[
sock
].
k_state
.
ready
?
"SS_READY "
:
""
,
sa1100_pcmcia_socket
[
sock
].
cs_state
.
Vcc
?
"SS_POWERON "
:
""
,
sa1100_pcmcia_socket
[
sock
].
cs_state
.
flags
&
SS_IOCARD
?
\
"SS_IOCARD "
:
""
,
(
sa1100_pcmcia_socket
[
sock
].
cs_state
.
flags
&
SS_IOCARD
&&
sa1100_pcmcia_socket
[
sock
].
k_state
.
bvd1
)
?
"SS_STSCHG "
:
""
,
((
sa1100_pcmcia_socket
[
sock
].
cs_state
.
flags
&
SS_IOCARD
)
==
0
&&
(
sa1100_pcmcia_socket
[
sock
].
k_state
.
bvd1
==
0
))
?
"SS_BATDEAD "
:
""
,
((
sa1100_pcmcia_socket
[
sock
].
cs_state
.
flags
&
SS_IOCARD
)
==
0
&&
(
sa1100_pcmcia_socket
[
sock
].
k_state
.
bvd2
==
0
))
?
"SS_BATWARN "
:
""
,
sa1100_pcmcia_socket
[
sock
].
k_state
.
vs_3v
?
"SS_3VCARD "
:
""
,
sa1100_pcmcia_socket
[
sock
].
k_state
.
vs_Xv
?
"SS_XVCARD "
:
""
);
skt
->
k_state
.
detect
?
"SS_DETECT "
:
""
,
skt
->
k_state
.
ready
?
"SS_READY "
:
""
,
skt
->
cs_state
.
Vcc
?
"SS_POWERON "
:
""
,
skt
->
cs_state
.
flags
&
SS_IOCARD
?
"SS_IOCARD "
:
""
,
(
skt
->
cs_state
.
flags
&
SS_IOCARD
&&
skt
->
k_state
.
bvd1
)
?
"SS_STSCHG "
:
""
,
((
skt
->
cs_state
.
flags
&
SS_IOCARD
)
==
0
&&
(
skt
->
k_state
.
bvd1
==
0
))
?
"SS_BATDEAD "
:
""
,
((
skt
->
cs_state
.
flags
&
SS_IOCARD
)
==
0
&&
(
skt
->
k_state
.
bvd2
==
0
))
?
"SS_BATWARN "
:
""
,
skt
->
k_state
.
vs_3v
?
"SS_3VCARD "
:
""
,
skt
->
k_state
.
vs_Xv
?
"SS_XVCARD "
:
""
);
p
+=
sprintf
(
p
,
"mask : %s%s%s%s%s
\n
"
,
sa1100_pcmcia_socket
[
sock
].
cs_state
.
csc_mask
&
SS_DETECT
?
\
"SS_DETECT "
:
""
,
sa1100_pcmcia_socket
[
sock
].
cs_state
.
csc_mask
&
SS_READY
?
\
"SS_READY "
:
""
,
sa1100_pcmcia_socket
[
sock
].
cs_state
.
csc_mask
&
SS_BATDEAD
?
\
"SS_BATDEAD "
:
""
,
sa1100_pcmcia_socket
[
sock
].
cs_state
.
csc_mask
&
SS_BATWARN
?
\
"SS_BATWARN "
:
""
,
sa1100_pcmcia_socket
[
sock
].
cs_state
.
csc_mask
&
SS_STSCHG
?
\
"SS_STSCHG "
:
""
);
skt
->
cs_state
.
csc_mask
&
SS_DETECT
?
"SS_DETECT "
:
""
,
skt
->
cs_state
.
csc_mask
&
SS_READY
?
"SS_READY "
:
""
,
skt
->
cs_state
.
csc_mask
&
SS_BATDEAD
?
"SS_BATDEAD "
:
""
,
skt
->
cs_state
.
csc_mask
&
SS_BATWARN
?
"SS_BATWARN "
:
""
,
skt
->
cs_state
.
csc_mask
&
SS_STSCHG
?
"SS_STSCHG "
:
""
);
p
+=
sprintf
(
p
,
"cs_flags : %s%s%s%s%s
\n
"
,
sa1100_pcmcia_socket
[
sock
].
cs_state
.
flags
&
SS_PWR_AUTO
?
\
"SS_PWR_AUTO "
:
""
,
sa1100_pcmcia_socket
[
sock
].
cs_state
.
flags
&
SS_IOCARD
?
\
"SS_IOCARD "
:
""
,
sa1100_pcmcia_socket
[
sock
].
cs_state
.
flags
&
SS_RESET
?
\
"SS_RESET "
:
""
,
sa1100_pcmcia_socket
[
sock
].
cs_state
.
flags
&
SS_SPKR_ENA
?
\
"SS_SPKR_ENA "
:
""
,
sa1100_pcmcia_socket
[
sock
].
cs_state
.
flags
&
SS_OUTPUT_ENA
?
\
"SS_OUTPUT_ENA "
:
""
);
p
+=
sprintf
(
p
,
"Vcc : %d
\n
"
,
sa1100_pcmcia_socket
[
sock
].
cs_state
.
Vcc
);
skt
->
cs_state
.
flags
&
SS_PWR_AUTO
?
"SS_PWR_AUTO "
:
""
,
skt
->
cs_state
.
flags
&
SS_IOCARD
?
"SS_IOCARD "
:
""
,
skt
->
cs_state
.
flags
&
SS_RESET
?
"SS_RESET "
:
""
,
skt
->
cs_state
.
flags
&
SS_SPKR_ENA
?
"SS_SPKR_ENA "
:
""
,
skt
->
cs_state
.
flags
&
SS_OUTPUT_ENA
?
"SS_OUTPUT_ENA "
:
""
);
p
+=
sprintf
(
p
,
"Vpp : %d
\n
"
,
sa1100_pcmcia_socket
[
sock
].
cs_state
.
Vpp
);
p
+=
sprintf
(
p
,
"Vcc : %d
\n
"
,
skt
->
cs_state
.
Vcc
);
p
+=
sprintf
(
p
,
"Vpp : %d
\n
"
,
skt
->
cs_state
.
Vpp
);
p
+=
sprintf
(
p
,
"IRQ : %d
\n
"
,
skt
->
cs_state
.
io_irq
);
p
+=
sprintf
(
p
,
"irq : %d
\n
"
,
sa1100_pcmcia_socket
[
sock
].
cs_state
.
io_irq
);
p
+=
sprintf
(
p
,
"I/O : %u (%u)
\n
"
,
sa1100_pcmcia_socket
[
sock
].
speed_io
,
p
+=
sprintf
(
p
,
"I/O : %u (%u)
\n
"
,
skt
->
speed_io
,
sa1100_pcmcia_cmd_time
(
clock
,
MECR_BSIO_GET
(
mecr
,
sock
)));
p
+=
sprintf
(
p
,
"attribute: %u (%u)
\n
"
,
s
a1100_pcmcia_socket
[
sock
].
speed_attr
,
p
+=
sprintf
(
p
,
"attribute: %u (%u)
\n
"
,
s
kt
->
speed_attr
,
sa1100_pcmcia_cmd_time
(
clock
,
MECR_BSA_GET
(
mecr
,
sock
)));
p
+=
sprintf
(
p
,
"common : %u (%u)
\n
"
,
s
a1100_pcmcia_socket
[
sock
].
speed_mem
,
p
+=
sprintf
(
p
,
"common : %u (%u)
\n
"
,
s
kt
->
speed_mem
,
sa1100_pcmcia_cmd_time
(
clock
,
MECR_BSM_GET
(
mecr
,
sock
)));
return
p
-
buf
;
}
/* sa1100_pcmcia_proc_setup()
* ^^^^^^^^^^^^^^^^^^^^^^^^^^
* Implements the proc_setup() operation for the in-kernel PCMCIA
* service (formerly SS_ProcSetup in Card Services).
*
* Returns: 0 on success, -1 on error
*/
static
void
sa1100_pcmcia_proc_setup
(
unsigned
int
sock
,
struct
proc_dir_entry
*
base
)
{
struct
proc_dir_entry
*
entry
;
DEBUG
(
4
,
"%s() for sock %u
\n
"
,
__FUNCTION__
,
sock
);
if
((
entry
=
create_proc_entry
(
"status"
,
0
,
base
))
==
NULL
){
printk
(
KERN_ERR
"unable to install
\"
status
\"
procfs entry
\n
"
);
return
;
}
entry
->
read_proc
=
sa1100_pcmcia_proc_status
;
entry
->
data
=
(
void
*
)
sock
;
}
#endif
/* defined(CONFIG_PROC_FS) */
static
struct
pccard_operations
sa1100_pcmcia_operations
=
{
init:
sa1100_pcmcia_sock_init
,
suspend:
sa1100_pcmcia_suspend
,
register_callback:
sa1100_pcmcia_register_callback
,
inquire_socket:
sa1100_pcmcia_inquire_socket
,
get_status:
sa1100_pcmcia_get_status
,
get_socket:
sa1100_pcmcia_get_socket
,
set_socket:
sa1100_pcmcia_set_socket
,
get_io_map:
sa1100_pcmcia_get_io_map
,
set_io_map:
sa1100_pcmcia_set_io_map
,
get_mem_map:
sa1100_pcmcia_get_mem_map
,
set_mem_map:
sa1100_pcmcia_set_mem_map
,
#ifdef CONFIG_PROC_FS
proc_setup:
sa1100_pcmcia_proc_setup
#endif
};
#ifdef CONFIG_CPU_FREQ
...
...
@@ -1101,25 +854,23 @@ static int sa1100_pcmcia_proc_status(char *buf, char **start, off_t pos,
* to a core clock frequency change) is needed, this routine establishes
* new BS_xx values consistent with the clock speed `clock'.
*/
static
void
sa1100_pcmcia_update_mecr
(
unsigned
int
clock
){
static
void
sa1100_pcmcia_update_mecr
(
unsigned
int
clock
)
{
unsigned
int
sock
;
unsigned
long
mecr
=
MECR
;
for
(
sock
=
0
;
sock
<
SA1100_PCMCIA_MAX_SOCK
;
++
sock
){
struct
sa1100_pcmcia_socket
*
skt
=
PCMCIA_SOCKET
(
sock
);
MECR_BSIO_SET
(
mecr
,
sock
,
sa1100_pcmcia_mecr_bs
(
sa1100_pcmcia_socket
[
sock
].
speed_io
,
clock
));
sa1100_pcmcia_mecr_bs
(
skt
->
speed_io
,
clock
));
MECR_BSA_SET
(
mecr
,
sock
,
sa1100_pcmcia_mecr_bs
(
sa1100_pcmcia_socket
[
sock
].
speed_attr
,
clock
));
sa1100_pcmcia_mecr_bs
(
skt
->
speed_attr
,
clock
));
MECR_BSM_SET
(
mecr
,
sock
,
sa1100_pcmcia_mecr_bs
(
sa1100_pcmcia_socket
[
sock
].
speed_mem
,
clock
));
sa1100_pcmcia_mecr_bs
(
skt
->
speed_mem
,
clock
));
}
MECR
=
mecr
;
}
/* sa1100_pcmcia_notifier()
...
...
@@ -1132,53 +883,371 @@ static void sa1100_pcmcia_update_mecr(unsigned int clock){
*
* Returns: 0 on success, -1 on error
*/
static
int
sa1100_pcmcia_notifier
(
struct
notifier_block
*
nb
,
unsigned
long
val
,
void
*
data
){
static
int
sa1100_pcmcia_notifier
(
struct
notifier_block
*
nb
,
unsigned
long
val
,
void
*
data
)
{
struct
cpufreq_info
*
ci
=
data
;
switch
(
val
){
case
CPUFREQ_MINMAX
:
break
;
switch
(
val
)
{
case
CPUFREQ_PRECHANGE
:
if
(
ci
->
new_freq
>
ci
->
old_freq
){
if
(
ci
->
new_freq
>
ci
->
old_freq
)
{
DEBUG
(
2
,
"%s(): new frequency %u.%uMHz > %u.%uMHz, pre-updating
\n
"
,
__FUNCTION__
,
ci
->
new_freq
/
1000
,
(
ci
->
new_freq
/
100
)
%
10
,
ci
->
old_freq
/
1000
,
(
ci
->
old_freq
/
100
)
%
10
);
sa1100_pcmcia_update_mecr
(
ci
->
new_freq
);
}
break
;
case
CPUFREQ_POSTCHANGE
:
if
(
ci
->
new_freq
<
ci
->
old_freq
){
if
(
ci
->
new_freq
<
ci
->
old_freq
)
{
DEBUG
(
2
,
"%s(): new frequency %u.%uMHz < %u.%uMHz, post-updating
\n
"
,
__FUNCTION__
,
ci
->
new_freq
/
1000
,
(
ci
->
new_freq
/
100
)
%
10
,
ci
->
old_freq
/
1000
,
(
ci
->
old_freq
/
100
)
%
10
);
sa1100_pcmcia_update_mecr
(
ci
->
new_freq
);
}
break
;
default:
printk
(
KERN_ERR
"%s(): unknown CPU frequency event %lx
\n
"
,
__FUNCTION__
,
val
);
return
-
1
;
}
return
0
;
}
static
struct
notifier_block
sa1100_pcmcia_notifier_block
=
{
notifier_call:
sa1100_pcmcia_notifier
};
#endif
/* sa1100_register_pcmcia()
* ^^^^^^^^^^^^^^^^^^^^^^^^
*
* Register an SA1100 PCMCIA low level driver with the SA1100 core.
*/
int
sa1100_register_pcmcia
(
struct
pcmcia_low_level
*
ops
)
{
struct
pcmcia_init
pcmcia_init
;
struct
pcmcia_state
state
[
SA1100_PCMCIA_MAX_SOCK
];
struct
pcmcia_state_array
state_array
;
unsigned
int
i
,
clock
;
unsigned
long
mecr
;
int
ret
;
/*
* Refuse to replace an existing driver.
*/
if
(
pcmcia_low_level
)
return
-
EBUSY
;
pcmcia_low_level
=
ops
;
pcmcia_init
.
handler
=
sa1100_pcmcia_interrupt
;
ret
=
ops
->
init
(
&
pcmcia_init
);
if
(
ret
<
0
)
{
printk
(
KERN_ERR
"Unable to initialize kernel PCMCIA service (%d).
\n
"
,
ret
);
if
(
ret
==
-
1
)
ret
=
-
EIO
;
goto
out
;
}
sa1100_pcmcia_socket_count
=
ret
;
state_array
.
size
=
ret
;
state_array
.
state
=
state
;
memset
(
state
,
0
,
sizeof
(
state
));
if
(
ops
->
socket_state
(
&
state_array
)
<
0
)
{
printk
(
KERN_ERR
"Unable to get PCMCIA status driver.
\n
"
);
ret
=
-
EIO
;
goto
shutdown
;
}
/*
* We initialize the MECR to default values here, because we are
* not guaranteed to see a SetIOMap operation at runtime.
*/
mecr
=
0
;
clock
=
cpufreq_get
(
0
);
for
(
i
=
0
;
i
<
sa1100_pcmcia_socket_count
;
i
++
)
{
struct
sa1100_pcmcia_socket
*
skt
=
PCMCIA_SOCKET
(
i
);
struct
pcmcia_irq_info
irq_info
;
if
(
!
request_mem_region
(
_PCMCIA
(
i
),
PCMCIASp
,
"PCMCIA"
))
{
ret
=
-
EBUSY
;
goto
out_err
;
}
irq_info
.
sock
=
i
;
irq_info
.
irq
=
-
1
;
ret
=
ops
->
get_irq_info
(
&
irq_info
);
if
(
ret
<
0
)
printk
(
KERN_ERR
"Unable to get IRQ for socket %u (%d)
\n
"
,
i
,
ret
);
skt
->
irq
=
irq_info
.
irq
;
skt
->
k_state
=
state
[
i
];
skt
->
speed_io
=
SA1100_PCMCIA_IO_ACCESS
;
skt
->
speed_attr
=
SA1100_PCMCIA_5V_MEM_ACCESS
;
skt
->
speed_mem
=
SA1100_PCMCIA_5V_MEM_ACCESS
;
skt
->
phys_attr
=
_PCMCIAAttr
(
i
);
skt
->
phys_mem
=
_PCMCIAMem
(
i
);
skt
->
virt_io
=
ioremap
(
_PCMCIAIO
(
i
),
0x10000
);
if
(
skt
->
virt_io
==
NULL
)
{
ret
=
-
ENOMEM
;
goto
out_err
;
}
MECR_FAST_SET
(
mecr
,
i
,
0
);
MECR_BSIO_SET
(
mecr
,
i
,
sa1100_pcmcia_mecr_bs
(
skt
->
speed_io
,
clock
));
MECR_BSA_SET
(
mecr
,
i
,
sa1100_pcmcia_mecr_bs
(
skt
->
speed_attr
,
clock
));
MECR_BSM_SET
(
mecr
,
i
,
sa1100_pcmcia_mecr_bs
(
skt
->
speed_mem
,
clock
));
}
MECR
=
mecr
;
/* Only advertise as many sockets as we can detect */
ret
=
register_ss_entry
(
sa1100_pcmcia_socket_count
,
&
sa1100_pcmcia_operations
);
if
(
ret
<
0
)
{
printk
(
KERN_ERR
"Unable to register sockets
\n
"
);
goto
out_err
;
}
/*
* Start the event poll timer. It will reschedule by itself afterwards.
*/
sa1100_pcmcia_poll_event
(
0
);
return
0
;
out_err:
for
(
i
=
0
;
i
<
sa1100_pcmcia_socket_count
;
i
++
)
{
struct
sa1100_pcmcia_socket
*
skt
=
PCMCIA_SOCKET
(
i
);
iounmap
(
skt
->
virt_io
);
skt
->
virt_io
=
NULL
;
release_mem_region
(
_PCMCIA
(
i
),
PCMCIASp
);
}
shutdown:
ops
->
shutdown
();
out:
pcmcia_low_level
=
NULL
;
return
ret
;
}
/* sa1100_unregister_pcmcia()
* ^^^^^^^^^^^^^^^^^^^^^^^^^^
*
* Unregister a previously registered pcmcia driver
*/
void
sa1100_unregister_pcmcia
(
struct
pcmcia_low_level
*
ops
)
{
int
i
;
if
(
!
ops
)
return
;
if
(
ops
!=
pcmcia_low_level
)
{
printk
(
KERN_DEBUG
"PCMCIA: Trying to unregister wrong "
"low-level driver (%p != %p)"
,
ops
,
pcmcia_low_level
);
return
;
}
del_timer_sync
(
&
poll_timer
);
unregister_ss_entry
(
&
sa1100_pcmcia_operations
);
for
(
i
=
0
;
i
<
sa1100_pcmcia_socket_count
;
i
++
)
{
struct
sa1100_pcmcia_socket
*
skt
=
PCMCIA_SOCKET
(
i
);
iounmap
(
skt
->
virt_io
);
skt
->
virt_io
=
NULL
;
release_mem_region
(
_PCMCIA
(
i
),
PCMCIASp
);
}
ops
->
shutdown
();
flush_scheduled_tasks
();
pcmcia_low_level
=
NULL
;
}
/* sa1100_pcmcia_init()
* ^^^^^^^^^^^^^^^^^^^^
*
* This routine performs a basic sanity check to ensure that this
* kernel has been built with the appropriate board-specific low-level
* PCMCIA support, performs low-level PCMCIA initialization, registers
* this socket driver with Card Services, and then spawns the daemon
* thread which is the real workhorse of the socket driver.
*
* Returns: 0 on success, -1 on error
*/
static
int
__init
sa1100_pcmcia_init
(
void
)
{
servinfo_t
info
;
int
ret
,
i
;
printk
(
KERN_INFO
"SA-1100 PCMCIA (CS release %s)
\n
"
,
CS_RELEASE
);
CardServices
(
GetCardServicesInfo
,
&
info
);
if
(
info
.
Revision
!=
CS_RELEASE_CODE
)
{
printk
(
KERN_ERR
"Card Services release codes do not match
\n
"
);
return
-
EINVAL
;
}
for
(
i
=
0
;
i
<
SA1100_PCMCIA_MAX_SOCK
;
i
++
)
{
struct
sa1100_pcmcia_socket
*
skt
=
PCMCIA_SOCKET
(
i
);
skt
->
speed_io
=
SA1100_PCMCIA_IO_ACCESS
;
skt
->
speed_attr
=
SA1100_PCMCIA_5V_MEM_ACCESS
;
skt
->
speed_mem
=
SA1100_PCMCIA_5V_MEM_ACCESS
;
}
#ifdef CONFIG_CPU_FREQ
ret
=
cpufreq_register_notifier
(
&
sa1100_pcmcia_notifier_block
);
if
(
ret
<
0
)
{
printk
(
KERN_ERR
"Unable to register CPU frequency change "
"notifier (%d)
\n
"
,
ret
);
return
ret
;
}
#endif
#ifdef CONFIG_SA1100_ADSBITSY
pcmcia_adsbitsy_init
();
#endif
#ifdef CONFIG_SA1100_ASSABET
pcmcia_assabet_init
();
#endif
#ifdef CONFIG_SA1100_BADGE4
pcmcia_badge4_init
();
#endif
#ifdef CONFIG_SA1100_CERF
pcmcia_cerf_init
();
#endif
#ifdef CONFIG_SA1100_FLEXANET
pcmcia_flexanet_init
();
#endif
#ifdef CONFIG_SA1100_FREEBIRD
pcmcia_freebird_init
();
#endif
#ifdef CONFIG_SA1100_GRAPHICSCLIENT
pcmcia_gcplus_init
();
#endif
#ifdef CONFIG_SA1100_GRAPHICSMASTER
pcmcia_graphicsmaster_init
();
#endif
#ifdef CONFIG_SA1100_JORNADA720
pcmcia_jornada720_init
();
#endif
#ifdef CONFIG_ASSABET_NEPONSET
pcmcia_neponset_init
();
#endif
#ifdef CONFIG_SA1100_PANGOLIN
pcmcia_pangolin_init
();
#endif
#ifdef CONFIG_SA1100_PFS168
pcmcia_pfs_init
();
#endif
#ifdef CONFIG_SA1100_PT_SYSTEM3
pcmcia_system3_init
();
#endif
#ifdef CONFIG_SA1100_SHANNON
pcmcia_shannon_init
();
#endif
#ifdef CONFIG_SA1100_SIMPAD
pcmcia_simpad_init
();
#endif
#ifdef CONFIG_SA1100_STORK
pcmcia_stork_init
();
#endif
#ifdef CONFIG_SA1100_XP860
pcmcia_xp860_init
();
#endif
#ifdef CONFIG_SA1100_YOPY
pcmcia_yopy_init
();
#endif
return
0
;
}
/* sa1100_pcmcia_exit()
* ^^^^^^^^^^^^^^^^^^^^
* Invokes the low-level kernel service to free IRQs associated with this
* socket controller and reset GPIO edge detection.
*/
static
void
__exit
sa1100_pcmcia_exit
(
void
)
{
#ifdef CONFIG_SA1100_ADSBITSY
pcmcia_adsbitsy_exit
();
#endif
#ifdef CONFIG_SA1100_ASSABET
pcmcia_assabet_exit
();
#endif
#ifdef CONFIG_SA1100_BADGE4
pcmcia_badge4_exit
();
#endif
#ifdef CONFIG_SA1100_CERF
pcmcia_cerf_exit
();
#endif
#ifdef CONFIG_SA1100_FLEXANET
pcmcia_flexanet_exit
();
#endif
#ifdef CONFIG_SA1100_FREEBIRD
pcmcia_freebird_exit
();
#endif
#ifdef CONFIG_SA1100_GRAPHICSCLIENT
pcmcia_gcplus_exit
();
#endif
#ifdef CONFIG_SA1100_GRAPHICSMASTER
pcmcia_graphicsmaster_exit
();
#endif
#ifdef CONFIG_SA1100_JORNADA720
pcmcia_jornada720_exit
();
#endif
#ifdef CONFIG_ASSABET_NEPONSET
pcmcia_neponset_exit
();
#endif
#ifdef CONFIG_SA1100_PANGOLIN
pcmcia_pangolin_exit
();
#endif
#ifdef CONFIG_SA1100_PFS168
pcmcia_pfs_exit
();
#endif
#ifdef CONFIG_SA1100_SHANNON
pcmcia_shannon_exit
();
#endif
#ifdef CONFIG_SA1100_SIMPAD
pcmcia_simpad_exit
();
#endif
#ifdef CONFIG_SA1100_STORK
pcmcia_stork_exit
();
#endif
#ifdef CONFIG_SA1100_XP860
pcmcia_xp860_exit
();
#endif
#ifdef CONFIG_SA1100_YOPY
pcmcia_yopy_exit
();
#endif
if
(
pcmcia_low_level
)
{
printk
(
KERN_ERR
"PCMCIA: low level driver still registered
\n
"
);
sa1100_unregister_pcmcia
(
pcmcia_low_level
);
}
#ifdef CONFIG_CPU_FREQ
cpufreq_unregister_notifier
(
&
sa1100_pcmcia_notifier_block
);
#endif
}
MODULE_AUTHOR
(
"John Dorsey <john+@cs.cmu.edu>"
);
MODULE_DESCRIPTION
(
"Linux PCMCIA Card Services: SA-1100 Socket Controller"
);
MODULE_LICENSE
(
"Dual MPL/GPL"
);
module_init
(
sa1100_pcmcia_init
);
module_exit
(
sa1100_pcmcia_exit
);
drivers/pcmcia/sa1100_generic.h
0 → 100644
View file @
f60852d2
/*
* linux/include/asm/arch/pcmcia.h
*
* Copyright (C) 2000 John G Dorsey <john+@cs.cmu.edu>
*
* This file contains definitions for the low-level SA-1100 kernel PCMCIA
* interface. Please see linux/Documentation/arm/SA1100/PCMCIA for details.
*/
#ifndef _ASM_ARCH_PCMCIA
#define _ASM_ARCH_PCMCIA
/* Ideally, we'd support up to MAX_SOCK sockets, but the SA-1100 only
* has support for two. This shows up in lots of hardwired ways, such
* as the fact that MECR only has enough bits to configure two sockets.
* Since it's so entrenched in the hardware, limiting the software
* in this way doesn't seem too terrible.
*/
#define SA1100_PCMCIA_MAX_SOCK (2)
struct
pcmcia_init
{
void
(
*
handler
)(
int
irq
,
void
*
dev
,
struct
pt_regs
*
regs
);
};
struct
pcmcia_state
{
unsigned
detect
:
1
,
ready:
1
,
bvd1:
1
,
bvd2:
1
,
wrprot:
1
,
vs_3v:
1
,
vs_Xv:
1
;
};
struct
pcmcia_state_array
{
unsigned
int
size
;
struct
pcmcia_state
*
state
;
};
struct
pcmcia_configure
{
unsigned
sock
:
8
,
vcc:
8
,
vpp:
8
,
output:
1
,
speaker:
1
,
reset:
1
,
irq:
1
;
};
struct
pcmcia_irq_info
{
unsigned
int
sock
;
unsigned
int
irq
;
};
struct
pcmcia_low_level
{
int
(
*
init
)(
struct
pcmcia_init
*
);
int
(
*
shutdown
)(
void
);
int
(
*
socket_state
)(
struct
pcmcia_state_array
*
);
int
(
*
get_irq_info
)(
struct
pcmcia_irq_info
*
);
int
(
*
configure_socket
)(
const
struct
pcmcia_configure
*
);
/*
* Enable card status IRQs on (re-)initialisation. This can
* be called at initialisation, power management event, or
* pcmcia event.
*/
int
(
*
socket_init
)(
int
sock
);
/*
* Disable card status IRQs and PCMCIA bus on suspend.
*/
int
(
*
socket_suspend
)(
int
sock
);
};
extern
int
sa1100_register_pcmcia
(
struct
pcmcia_low_level
*
);
extern
void
sa1100_unregister_pcmcia
(
struct
pcmcia_low_level
*
);
#endif
drivers/pcmcia/sa1100_graphicsclient.c
View file @
f60852d2
...
...
@@ -14,10 +14,13 @@
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <asm/hardware.h>
#include <asm/irq.h>
#include <asm/arch/pcmcia.h>
#include "sa1100_generic.h"
#error This is broken!
#define S0_CD_IRQ 60 // Socket 0 Card Detect IRQ
#define S0_STS_IRQ 55 // Socket 0 PCMCIA IRQ
...
...
@@ -47,8 +50,9 @@ static int gcplus_pcmcia_init(struct pcmcia_init *init)
irq
=
S0_CD_IRQ
;
res
=
request_irq
(
irq
,
init
->
handler
,
SA_INTERRUPT
,
"PCMCIA 0 CD"
,
NULL
);
if
(
res
<
0
)
{
printk
(
KERN_ERR
"%s: Request for IRQ %lu failed
\n
"
,
__FUNCTION__
,
irq
);
return
-
1
;
printk
(
KERN_ERR
"%s: request for IRQ%d failed (%d)
\n
"
,
__FUNCTION__
,
irq
,
res
);
return
res
;
}
return
1
;
// 1 PCMCIA Slot
...
...
@@ -106,7 +110,7 @@ static int gcplus_pcmcia_configure_socket(const struct pcmcia_configure
if
(
configure
->
sock
>
1
)
return
-
1
;
save_flags_cli
(
flags
);
local_irq_save
(
flags
);
switch
(
configure
->
vcc
)
{
case
0
:
...
...
@@ -126,7 +130,7 @@ static int gcplus_pcmcia_configure_socket(const struct pcmcia_configure
default:
printk
(
KERN_ERR
"%s(): unrecognized Vcc %u
\n
"
,
__FUNCTION__
,
configure
->
vcc
);
restore_flags
(
flags
);
local_irq_restore
(
flags
);
return
-
1
;
}
...
...
@@ -139,16 +143,44 @@ static int gcplus_pcmcia_configure_socket(const struct pcmcia_configure
*
PCMCIA_Power
|=
ADS_CS_PR_A_RESET
;
mdelay
(
30
);
restore_flags
(
flags
);
local_irq_restore
(
flags
);
return
0
;
}
static
int
gcplus_pcmcia_socket_init
(
int
sock
)
{
return
0
;
}
static
int
gcplus_pcmcia_socket_suspend
(
int
sock
)
{
return
0
;
}
struct
pcmcia_low_level
gcplus_pcmcia_ops
=
{
gcplus_pcmcia_init
,
gcplus_pcmcia_shutdown
,
gcplus_pcmcia_socket_state
,
gcplus_pcmcia_get_irq_info
,
gcplus_pcmcia_configure_socket
static
struct
pcmcia_low_level
gcplus_pcmcia_ops
=
{
init:
gcplus_pcmcia_init
,
shutdown:
gcplus_pcmcia_shutdown
,
socket_state:
gcplus_pcmcia_socket_state
,
get_irq_info:
gcplus_pcmcia_get_irq_info
,
configure_socket:
gcplus_pcmcia_configure_socket
,
socket_init:
gcplus_pcmcia_socket_init
,
socket_suspend:
gcplus_pcmcia_socket_suspend
,
};
int
__init
pcmcia_gcplus_init
(
void
)
{
int
ret
=
-
ENODEV
;
if
(
machine_is_gcplus
())
ret
=
sa1100_register_pcmcia
(
&
gcplus_pcmcia_ops
);
return
ret
;
}
void
__exit
pcmcia_gcplus_exit
(
void
)
{
sa1100_unregister_pcmcia
(
&
gcplus_pcmcia_ops
);
}
drivers/pcmcia/sa1100_graphicsmaster.c
View file @
f60852d2
...
...
@@ -10,11 +10,12 @@
*/
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <asm/delay.h>
#include <asm/hardware.h>
#include <asm/irq.h>
#include <asm/arch/pcmcia.h>
#include "sa1100_generic.h"
#include "sa1111_generic.h"
static
int
graphicsmaster_pcmcia_init
(
struct
pcmcia_init
*
init
)
{
...
...
@@ -26,190 +27,82 @@ static int graphicsmaster_pcmcia_init(struct pcmcia_init *init)
/* Disable Power 3.3V/5V for PCMCIA/CF */
PA_DWR
|=
GPIO_GPIO0
|
GPIO_GPIO1
|
GPIO_GPIO2
|
GPIO_GPIO3
;
INTPOL1
|=
(
1
<<
(
S0_READY_NINT
-
SA1111_IRQ
(
32
)))
|
(
1
<<
(
S1_READY_NINT
-
SA1111_IRQ
(
32
)))
|
(
1
<<
(
S0_CD_VALID
-
SA1111_IRQ
(
32
)))
|
(
1
<<
(
S1_CD_VALID
-
SA1111_IRQ
(
32
)))
|
(
1
<<
(
S0_BVD1_STSCHG
-
SA1111_IRQ
(
32
)))
|
(
1
<<
(
S1_BVD1_STSCHG
-
SA1111_IRQ
(
32
)));
return_val
+=
request_irq
(
S0_CD_VALID
,
init
->
handler
,
SA_INTERRUPT
,
"GC Master PCMCIA (0) CD"
,
NULL
);
return_val
+=
request_irq
(
S1_CD_VALID
,
init
->
handler
,
SA_INTERRUPT
,
"GC Master CF (1) CD"
,
NULL
);
return_val
+=
request_irq
(
S0_BVD1_STSCHG
,
init
->
handler
,
SA_INTERRUPT
,
"GC Master PCMCIA (0) BVD1"
,
NULL
);
return_val
+=
request_irq
(
S1_BVD1_STSCHG
,
init
->
handler
,
SA_INTERRUPT
,
"GC Master CF (1) BVD1"
,
NULL
);
/* why? */
MECR
=
0x09430943
;
return
(
return_val
<
0
)
?
-
1
:
2
;
}
static
int
graphicsmaster_pcmcia_shutdown
(
void
)
{
free_irq
(
S0_CD_VALID
,
NULL
);
free_irq
(
S1_CD_VALID
,
NULL
);
free_irq
(
S0_BVD1_STSCHG
,
NULL
);
free_irq
(
S1_BVD1_STSCHG
,
NULL
);
INTPOL1
&=
~
((
1
<<
(
S0_CD_VALID
-
SA1111_IRQ
(
32
)))
|
(
1
<<
(
S1_CD_VALID
-
SA1111_IRQ
(
32
)))
|
(
1
<<
(
S0_BVD1_STSCHG
-
SA1111_IRQ
(
32
)))
|
(
1
<<
(
S1_BVD1_STSCHG
-
SA1111_IRQ
(
32
))));
return
0
;
}
static
int
graphicsmaster_pcmcia_socket_state
(
struct
pcmcia_state_array
*
state_array
)
{
unsigned
long
status
;
int
return_val
=
1
;
if
(
state_array
->
size
<
2
)
return
-
1
;
memset
(
state_array
->
state
,
0
,
(
state_array
->
size
)
*
sizeof
(
struct
pcmcia_state
));
status
=
PCSR
;
state_array
->
state
[
0
].
detect
=
((
status
&
PCSR_S0_DETECT
)
==
0
)
?
1
:
0
;
state_array
->
state
[
0
].
ready
=
((
status
&
PCSR_S0_READY
)
==
0
)
?
0
:
1
;
state_array
->
state
[
0
].
bvd1
=
((
status
&
PCSR_S0_BVD1
)
==
0
)
?
0
:
1
;
state_array
->
state
[
0
].
bvd2
=
((
status
&
PCSR_S0_BVD2
)
==
0
)
?
0
:
1
;
state_array
->
state
[
0
].
wrprot
=
((
status
&
PCSR_S0_WP
)
==
0
)
?
0
:
1
;
state_array
->
state
[
0
].
vs_3v
=
((
status
&
PCSR_S0_VS1
)
==
0
)
?
1
:
0
;
state_array
->
state
[
0
].
vs_Xv
=
((
status
&
PCSR_S0_VS2
)
==
0
)
?
1
:
0
;
state_array
->
state
[
1
].
detect
=
((
status
&
PCSR_S1_DETECT
)
==
0
)
?
1
:
0
;
state_array
->
state
[
1
].
ready
=
((
status
&
PCSR_S1_READY
)
==
0
)
?
0
:
1
;
state_array
->
state
[
1
].
bvd1
=
((
status
&
PCSR_S1_BVD1
)
==
0
)
?
0
:
1
;
state_array
->
state
[
1
].
bvd2
=
((
status
&
PCSR_S1_BVD2
)
==
0
)
?
0
:
1
;
state_array
->
state
[
1
].
wrprot
=
((
status
&
PCSR_S1_WP
)
==
0
)
?
0
:
1
;
state_array
->
state
[
1
].
vs_3v
=
((
status
&
PCSR_S1_VS1
)
==
0
)
?
1
:
0
;
state_array
->
state
[
1
].
vs_Xv
=
((
status
&
PCSR_S1_VS2
)
==
0
)
?
1
:
0
;
return
return_val
;
return
sa1111_pcmcia_init
(
init
);
}
static
int
graphicsmaster_pcmcia_get_irq_info
(
struct
pcmcia_irq_info
*
info
)
static
int
graphicsmaster_pcmcia_configure_socket
(
const
struct
pcmcia_configure
*
conf
)
{
unsigned
int
pa_dwr_mask
,
pa_dwr_set
;
int
ret
;
switch
(
info
->
sock
)
{
switch
(
conf
->
sock
)
{
case
0
:
info
->
irq
=
S0_READY_NINT
;
break
;
case
1
:
info
->
irq
=
S1_READY_NINT
;
break
;
pa_dwr_mask
=
GPIO_GPIO0
|
GPIO_GPIO1
;
switch
(
conf
->
vcc
)
{
default:
return
-
1
;
case
0
:
pa_dwr_set
=
GPIO_GPIO0
|
GPIO_GPIO1
;
break
;
case
33
:
pa_dwr_set
=
GPIO_GPIO1
;
break
;
case
50
:
pa_dwr_set
=
GPIO_GPIO0
;
break
;
}
return
0
;
}
static
int
graphicsmaster_pcmcia_configure_socket
(
const
struct
pcmcia_configure
*
configure
)
{
unsigned
long
pccr
=
PCCR
,
gpio
=
PA_DWR
;
switch
(
configure
->
sock
){
case
0
:
switch
(
configure
->
vcc
){
case
0
:
pccr
=
(
pccr
&
~
PCCR_S0_FLT
);
gpio
|=
GPIO_GPIO0
|
GPIO_GPIO1
;
break
;
case
33
:
pccr
=
(
pccr
&
~
PCCR_S0_PSE
)
|
PCCR_S0_FLT
|
PCCR_S0_PWAITEN
;
gpio
&=
~
(
GPIO_GPIO0
|
GPIO_GPIO1
);
gpio
&=
~
GPIO_GPIO0
;
break
;
case
50
:
pccr
=
(
pccr
|
PCCR_S0_PSE
|
PCCR_S0_FLT
|
PCCR_S0_PWAITEN
);
gpio
&=
~
(
GPIO_GPIO0
|
GPIO_GPIO1
);
gpio
|=
GPIO_GPIO0
;
break
;
default:
printk
(
KERN_ERR
"%s(): unrecognized Vcc %u
\n
"
,
__FUNCTION__
,
configure
->
vcc
);
return
-
1
;
}
pccr
=
(
configure
->
reset
)
?
(
pccr
|
PCCR_S0_RST
)
:
(
pccr
&
~
PCCR_S0_RST
);
break
;
case
1
:
switch
(
configure
->
vcc
){
case
0
:
pccr
=
(
pccr
&
~
PCCR_S1_FLT
);
gpio
|=
GPIO_GPIO2
|
GPIO_GPIO3
;
break
;
case
33
:
pccr
=
(
pccr
&
~
PCCR_S1_PSE
)
|
PCCR_S1_FLT
|
PCCR_S1_PWAITEN
;
gpio
&=
~
(
GPIO_GPIO2
|
GPIO_GPIO3
);
gpio
&=
~
GPIO_GPIO2
;
break
;
case
50
:
pccr
=
(
pccr
|
PCCR_S1_PSE
|
PCCR_S1_FLT
|
PCCR_S1_PWAITEN
);
gpio
&=
~
(
GPIO_GPIO2
|
GPIO_GPIO3
);
gpio
|=
GPIO_GPIO2
;
break
;
pa_dwr_mask
=
GPIO_GPIO2
|
GPIO_GPIO3
;
switch
(
conf
->
vcc
)
{
default:
printk
(
KERN_ERR
"%s(): unrecognized Vcc %u
\n
"
,
__FUNCTION__
,
configure
->
vcc
);
return
-
1
;
case
0
:
pa_dwr_set
=
GPIO_GPIO2
|
GPIO_GPIO3
;
break
;
case
33
:
pa_dwr_set
=
GPIO_GPIO3
;
break
;
case
50
:
pa_dwr_set
=
GPIO_GPIO2
;
break
;
}
}
if
(
configure
->
vpp
!=
configure
->
vcc
&&
configure
->
vpp
!=
0
)
{
if
(
conf
->
vpp
!=
conf
->
vcc
&&
conf
->
vpp
!=
0
)
{
printk
(
KERN_ERR
"%s(): CF slot cannot support Vpp %u
\n
"
,
__FUNCTION__
,
configure
->
vpp
);
conf
->
vpp
);
return
-
1
;
}
pccr
=
(
configure
->
reset
)
?
(
pccr
|
PCCR_S1_RST
)
:
(
pccr
&
~
PCCR_S1_RST
);
ret
=
sa1111_pcmcia_configure_socket
(
conf
);
if
(
ret
==
0
)
{
unsigned
long
flags
;
break
;
default:
return
-
1
;
local_irq_save
(
flags
);
PA_DWR
=
(
PA_DWR
&
~
pa_dwr_mask
)
|
pa_dwr_set
;
local_irq_restore
(
flags
);
}
PCCR
=
pccr
;
PA_DWR
=
gpio
;
return
0
;
return
ret
;
}
struct
pcmcia_low_level
graphicsmaster_pcmcia_ops
=
{
graphicsmaster_pcmcia_init
,
graphicsmaster_pcmcia_shutdown
,
graphicsmaster_pcmcia_socket_state
,
graphicsmaster_pcmcia_get_irq_info
,
graphicsmaster_pcmcia_configure_socket
static
struct
pcmcia_low_level
graphicsmaster_pcmcia_ops
=
{
init:
graphicsmaster_pcmcia_init
,
shutdown:
sa1111_pcmcia_shutdown
,
socket_state:
sa1111_pcmcia_socket_state
,
get_irq_info:
sa1111_pcmcia_get_irq_info
,
configure_socket:
graphicsmaster_pcmcia_configure_socket
,
socket_init:
sa1111_pcmcia_socket_init
,
socket_suspend:
sa1111_pcmcia_socket_suspend
,
};
int
__init
pcmcia_graphicsmaster_init
(
void
)
{
int
ret
=
-
ENODEV
;
if
(
machine_is_graphicsmaster
())
ret
=
sa1100_register_pcmcia
(
&
graphicsmaster_pcmcia_ops
);
return
ret
;
}
void
__exit
pcmcia_graphicsmaster_exit
(
void
)
{
sa1100_unregister_pcmcia
(
&
graphicsmaster_pcmcia_ops
);
}
drivers/pcmcia/sa1100_h3600.c
View file @
f60852d2
...
...
@@ -6,92 +6,106 @@
*/
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <asm/hardware.h>
#include <asm/irq.h>
#include <asm/arch/pcmcia.h>
static
int
h3600_pcmcia_init
(
struct
pcmcia_init
*
init
){
int
irq
,
res
;
#include "sa1100_generic.h"
static
struct
irqs
{
int
irq
;
const
char
*
str
;
}
irqs
[]
=
{
{
IRQ_GPIO_H3600_PCMCIA_CD0
,
"PCMCIA CD0"
},
{
IRQ_GPIO_H3600_PCMCIA_CD1
,
"PCMCIA CD1"
}
};
/* Enable CF bus: */
set_h3600_egpio
(
EGPIO_H3600_OPT_NVRAM_ON
);
clr_h3600_egpio
(
EGPIO_H3600_OPT_RESET
)
;
static
int
h3600_pcmcia_init
(
struct
pcmcia_init
*
init
)
{
int
i
,
res
;
/* All those are inputs */
GPDR
&=
~
(
GPIO_H3600_PCMCIA_CD0
|
GPIO_H3600_PCMCIA_CD1
|
GPIO_H3600_PCMCIA_IRQ0
|
GPIO_H3600_PCMCIA_IRQ1
);
/*
* Set transition detect
*/
set_irq_type
(
IRQ_GPIO_H3600_PCMCIA_IRQ0
,
IRQT_FALLING
);
set_irq_type
(
IRQ_GPIO_H3600_PCMCIA_IRQ1
,
IRQT_FALLING
);
/* Set transition detect */
set_GPIO_IRQ_edge
(
GPIO_H3600_PCMCIA_CD0
|
GPIO_H3600_PCMCIA_CD1
,
GPIO_BOTH_EDGES
);
set_GPIO_IRQ_edge
(
GPIO_H3600_PCMCIA_IRQ0
|
GPIO_H3600_PCMCIA_IRQ1
,
GPIO_FALLING_EDGE
);
/*
* Register interrupts
*/
for
(
i
=
res
=
0
;
i
<
ARRAY_SIZE
(
irqs
);
i
++
)
{
res
=
request_irq
(
irqs
[
i
].
irq
,
init
->
handler
,
SA_INTERRUPT
,
irqs
[
i
].
str
,
NULL
);
if
(
res
)
break
;
}
/* Register interrupts */
irq
=
IRQ_GPIO_H3600_PCMCIA_CD0
;
res
=
request_irq
(
irq
,
init
->
handler
,
SA_INTERRUPT
,
"PCMCIA_CD0"
,
NULL
);
if
(
res
<
0
)
goto
irq_err
;
irq
=
IRQ_GPIO_H3600_PCMCIA_CD1
;
res
=
request_irq
(
irq
,
init
->
handler
,
SA_INTERRUPT
,
"PCMCIA_CD1"
,
NULL
);
if
(
res
<
0
)
goto
irq_err
;
if
(
res
)
{
printk
(
KERN_ERR
"%s: request for IRQ%d failed (%d)
\n
"
,
__FUNCTION__
,
irqs
[
i
].
irq
,
res
);
return
2
;
while
(
i
--
)
free_irq
(
irqs
[
i
].
irq
,
NULL
);
}
irq_err:
printk
(
KERN_ERR
__FUNCTION__
": Request for IRQ %u failed
\n
"
,
irq
);
return
-
1
;
return
res
?
res
:
2
;
}
static
int
h3600_pcmcia_shutdown
(
void
)
{
/* disable IRQs */
free_irq
(
IRQ_GPIO_H3600_PCMCIA_CD0
,
NULL
);
free_irq
(
IRQ_GPIO_H3600_PCMCIA_CD1
,
NULL
);
int
i
;
/*
* disable IRQs
*/
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
irqs
);
i
++
)
free_irq
(
irqs
[
i
].
irq
,
NULL
);
/* Disable CF bus: */
clr_h3600_egpio
(
EGPIO_H3600_OPT_NVRAM_ON
|
EGPIO_H3600_OPT_ON
);
set_h3600_egpio
(
EGPIO_H3600_OPT_RESET
);
clr_h3600_egpio
(
IPAQ_EGPIO_OPT_NVRAM_ON
);
clr_h3600_egpio
(
IPAQ_EGPIO_OPT_ON
);
set_h3600_egpio
(
IPAQ_EGPIO_OPT_RESET
);
return
0
;
}
static
int
h3600_pcmcia_socket_state
(
struct
pcmcia_state_array
*
state_array
){
static
int
h3600_pcmcia_socket_state
(
struct
pcmcia_state_array
*
state
)
{
unsigned
long
levels
;
if
(
state_array
->
size
<
2
)
return
-
1
;
memset
(
state_array
->
state
,
0
,
(
state_array
->
size
)
*
sizeof
(
struct
pcmcia_state
));
if
(
state
->
size
<
2
)
return
-
1
;
levels
=
GPLR
;
levels
=
GPLR
;
state_array
->
state
[
0
].
detect
=
((
levels
&
GPIO_H3600_PCMCIA_CD0
)
==
0
)
?
1
:
0
;
state_array
->
state
[
0
].
ready
=
(
levels
&
GPIO_H3600_PCMCIA_IRQ0
)
?
1
:
0
;
state_array
->
state
[
0
].
bvd1
=
0
;
state_array
->
state
[
0
].
bvd2
=
0
;
state_array
->
state
[
0
].
wrprot
=
0
;
/* Not available on H3600. */
state_array
->
state
[
0
].
vs_3v
=
0
;
state_array
->
state
[
0
].
vs_Xv
=
0
;
state
->
state
[
0
].
detect
=
levels
&
GPIO_H3600_PCMCIA_CD0
?
0
:
1
;
state
->
state
[
0
].
ready
=
levels
&
GPIO_H3600_PCMCIA_IRQ0
?
1
:
0
;
state
->
state
[
0
].
bvd1
=
0
;
state
->
state
[
0
].
bvd2
=
0
;
state
->
state
[
0
].
wrprot
=
0
;
/* Not available on H3600. */
state
->
state
[
0
].
vs_3v
=
0
;
state
->
state
[
0
].
vs_Xv
=
0
;
state_array
->
state
[
1
].
detect
=
((
levels
&
GPIO_H3600_PCMCIA_CD1
)
==
0
)
?
1
:
0
;
state_array
->
state
[
1
].
ready
=
(
levels
&
GPIO_H3600_PCMCIA_IRQ1
)
?
1
:
0
;
state_array
->
state
[
1
].
bvd1
=
0
;
state_array
->
state
[
1
].
bvd2
=
0
;
state_array
->
state
[
1
].
wrprot
=
0
;
/* Not available on H3600. */
state_array
->
state
[
1
].
vs_3v
=
0
;
state_array
->
state
[
1
].
vs_Xv
=
0
;
state
->
state
[
1
].
detect
=
levels
&
GPIO_H3600_PCMCIA_CD1
?
0
:
1
;
state
->
state
[
1
].
ready
=
levels
&
GPIO_H3600_PCMCIA_IRQ1
?
1
:
0
;
state
->
state
[
1
].
bvd1
=
0
;
state
->
state
[
1
].
bvd2
=
0
;
state
->
state
[
1
].
wrprot
=
0
;
/* Not available on H3600. */
state
->
state
[
1
].
vs_3v
=
0
;
state
->
state
[
1
].
vs_Xv
=
0
;
return
1
;
}
static
int
h3600_pcmcia_get_irq_info
(
struct
pcmcia_irq_info
*
info
)
{
static
int
h3600_pcmcia_get_irq_info
(
struct
pcmcia_irq_info
*
info
)
{
switch
(
info
->
sock
)
{
case
0
:
info
->
irq
=
IRQ_GPIO_H3600_PCMCIA_IRQ0
;
info
->
irq
=
IRQ_GPIO_H3600_PCMCIA_IRQ0
;
break
;
case
1
:
info
->
irq
=
IRQ_GPIO_H3600_PCMCIA_IRQ1
;
info
->
irq
=
IRQ_GPIO_H3600_PCMCIA_IRQ1
;
break
;
default:
return
-
1
;
...
...
@@ -99,49 +113,85 @@ static int h3600_pcmcia_get_irq_info(struct pcmcia_irq_info *info){
return
0
;
}
static
int
h3600_pcmcia_configure_socket
(
const
struct
pcmcia_configure
*
configure
)
static
int
h3600_pcmcia_configure_socket
(
const
struct
pcmcia_configure
*
conf
)
{
unsigned
long
flags
;
if
(
conf
->
sock
>
1
)
return
-
1
;
if
(
conf
->
vcc
!=
0
&&
conf
->
vcc
!=
33
&&
conf
->
vcc
!=
50
)
{
printk
(
KERN_ERR
"h3600_pcmcia: unrecognized Vcc %u.%uV
\n
"
,
conf
->
vcc
/
10
,
conf
->
vcc
%
10
);
return
-
1
;
}
if
(
conf
->
reset
)
set_h3600_egpio
(
IPAQ_EGPIO_CARD_RESET
);
else
clr_h3600_egpio
(
IPAQ_EGPIO_CARD_RESET
);
if
(
configure
->
sock
>
1
)
return
-
1
;
/* Silently ignore Vpp, output enable, speaker enable. */
return
0
;
}
static
int
h3600_pcmcia_socket_init
(
int
sock
)
{
/* Enable CF bus: */
set_h3600_egpio
(
IPAQ_EGPIO_OPT_NVRAM_ON
);
set_h3600_egpio
(
IPAQ_EGPIO_OPT_ON
);
clr_h3600_egpio
(
IPAQ_EGPIO_OPT_RESET
);
save_flags_cli
(
flags
);
set_current_state
(
TASK_UNINTERRUPTIBLE
);
schedule_timeout
(
10
*
HZ
/
1000
);
switch
(
configure
->
vcc
)
{
switch
(
sock
)
{
case
0
:
clr_h3600_egpio
(
EGPIO_H3600_OPT_ON
);
set_irq_type
(
IRQ_GPIO_H3600_PCMCIA_CD0
,
IRQT_BOTHEDGE
);
break
;
case
33
:
case
50
:
set_h3600_egpio
(
EGPIO_H3600_OPT_ON
);
case
1
:
set_irq_type
(
IRQ_GPIO_H3600_PCMCIA_CD1
,
IRQT_BOTHEDGE
);
break
;
default:
printk
(
KERN_ERR
"%s(): unrecognized Vcc %u
\n
"
,
__FUNCTION__
,
configure
->
vcc
);
restore_flags
(
flags
);
return
-
1
;
}
if
(
configure
->
reset
)
set_h3600_egpio
(
EGPIO_H3600_CARD_RESET
);
else
clr_h3600_egpio
(
EGPIO_H3600_CARD_RESET
);
return
0
;
}
/* Silently ignore Vpp, output enable, speaker enable. */
static
int
h3600_pcmcia_socket_suspend
(
int
sock
)
{
switch
(
sock
)
{
case
0
:
set_irq_type
(
IRQ_GPIO_H3600_PCMCIA_CD0
,
IRQT_NOEDGE
);
break
;
case
1
:
set_irq_type
(
IRQ_GPIO_H3600_PCMCIA_CD1
,
IRQT_NOEDGE
);
break
;
}
restore_flags
(
flags
);
/*
* FIXME: This doesn't fit well. We don't have the mechanism in
* the generic PCMCIA layer to deal with the idea of two sockets
* on one bus. We rely on the cs.c behaviour shutting down
* socket 0 then socket 1.
*/
if
(
sock
==
1
)
{
clr_h3600_egpio
(
IPAQ_EGPIO_OPT_ON
);
clr_h3600_egpio
(
IPAQ_EGPIO_OPT_NVRAM_ON
);
/* hmm, does this suck power? */
set_h3600_egpio
(
IPAQ_EGPIO_OPT_RESET
);
}
return
0
;
}
struct
pcmcia_low_level
h3600_pcmcia_ops
=
{
h3600_pcmcia_init
,
h3600_pcmcia_shutdown
,
h3600_pcmcia_socket_state
,
h3600_pcmcia_get_irq_info
,
h3600_pcmcia_configure_socket
init:
h3600_pcmcia_init
,
shutdown:
h3600_pcmcia_shutdown
,
socket_state:
h3600_pcmcia_socket_state
,
get_irq_info:
h3600_pcmcia_get_irq_info
,
configure_socket:
h3600_pcmcia_configure_socket
,
socket_init:
h3600_pcmcia_socket_init
,
socket_suspend:
h3600_pcmcia_socket_suspend
,
};
drivers/pcmcia/sa1100_jornada720.c
View file @
f60852d2
...
...
@@ -6,21 +6,24 @@
*/
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <asm/delay.h>
#include <asm/hardware.h>
#include <asm/irq.h>
#include <asm/arch/pcmcia.h>
#include "sa1100_generic.h"
#include "sa1111_generic.h"
#define SOCKET0_POWER GPIO_GPIO0
#define SOCKET0_3V GPIO_GPIO2
#define SOCKET1_POWER (GPIO_GPIO1 | GPIO_GPIO3)
#warning *** Does SOCKET1_3V actually do anything?
#define SOCKET1_3V GPIO_GPIO3
static
int
jornada720_pcmcia_init
(
struct
pcmcia_init
*
init
)
{
int
return_val
=
0
;
/*
* What is all this crap for?
*/
GRER
|=
0x00000002
;
/* Set GPIO_A<3:1> to be outputs for PCMCIA/CF power controller: */
PA_DDR
=
0
;
...
...
@@ -38,178 +41,82 @@ static int jornada720_pcmcia_init(struct pcmcia_init *init)
PC_SDR
=
0
;
PC_SSR
=
0
;
INTPOL1
|=
(
1
<<
(
S0_READY_NINT
-
SA1111_IRQ
(
32
)))
|
(
1
<<
(
S1_READY_NINT
-
SA1111_IRQ
(
32
)))
|
(
1
<<
(
S0_CD_VALID
-
SA1111_IRQ
(
32
)))
|
(
1
<<
(
S1_CD_VALID
-
SA1111_IRQ
(
32
)))
|
(
1
<<
(
S0_BVD1_STSCHG
-
SA1111_IRQ
(
32
)))
|
(
1
<<
(
S1_BVD1_STSCHG
-
SA1111_IRQ
(
32
)));
return_val
+=
request_irq
(
S0_CD_VALID
,
init
->
handler
,
SA_INTERRUPT
,
"Jornada720 PCMCIA (0) CD"
,
NULL
);
return_val
+=
request_irq
(
S1_CD_VALID
,
init
->
handler
,
SA_INTERRUPT
,
"Jornada720 CF (1) CD"
,
NULL
);
return_val
+=
request_irq
(
S0_BVD1_STSCHG
,
init
->
handler
,
SA_INTERRUPT
,
"Jornada720 PCMCIA (0) BVD1"
,
NULL
);
return_val
+=
request_irq
(
S1_BVD1_STSCHG
,
init
->
handler
,
SA_INTERRUPT
,
"Jornada720 CF (1) BVD1"
,
NULL
);
return
(
return_val
<
0
)
?
-
1
:
2
;
return
sa1111_pcmcia_init
(
init
);
}
static
int
jornada720_pcmcia_shutdown
(
void
)
static
int
jornada720_pcmcia_configure_socket
(
const
struct
pcmcia_configure
*
conf
)
{
free_irq
(
S0_CD_VALID
,
NULL
);
free_irq
(
S1_CD_VALID
,
NULL
);
free_irq
(
S0_BVD1_STSCHG
,
NULL
);
free_irq
(
S1_BVD1_STSCHG
,
NULL
);
INTPOL1
&=
~
((
1
<<
(
S0_CD_VALID
-
SA1111_IRQ
(
32
)))
|
(
1
<<
(
S1_CD_VALID
-
SA1111_IRQ
(
32
)))
|
(
1
<<
(
S0_BVD1_STSCHG
-
SA1111_IRQ
(
32
)))
|
(
1
<<
(
S1_BVD1_STSCHG
-
SA1111_IRQ
(
32
))));
return
0
;
}
unsigned
int
pa_dwr_mask
,
pa_dwr_set
;
int
ret
;
static
int
jornada720_pcmcia_socket_state
(
struct
pcmcia_state_array
*
state_array
)
{
unsigned
long
status
;
int
return_val
=
1
;
if
(
state_array
->
size
<
2
)
return
-
1
;
memset
(
state_array
->
state
,
0
,
(
state_array
->
size
)
*
sizeof
(
struct
pcmcia_state
));
status
=
PCSR
;
state_array
->
state
[
0
].
detect
=
((
status
&
PCSR_S0_DETECT
)
==
0
)
?
1
:
0
;
state_array
->
state
[
0
].
ready
=
((
status
&
PCSR_S0_READY
)
==
0
)
?
0
:
1
;
state_array
->
state
[
0
].
bvd1
=
((
status
&
PCSR_S0_BVD1
)
==
0
)
?
0
:
1
;
state_array
->
state
[
0
].
bvd2
=
((
status
&
PCSR_S0_BVD2
)
==
0
)
?
0
:
1
;
state_array
->
state
[
0
].
wrprot
=
((
status
&
PCSR_S0_WP
)
==
0
)
?
0
:
1
;
state_array
->
state
[
0
].
vs_3v
=
((
status
&
PCSR_S0_VS1
)
==
0
)
?
1
:
0
;
state_array
->
state
[
0
].
vs_Xv
=
((
status
&
PCSR_S0_VS2
)
==
0
)
?
1
:
0
;
state_array
->
state
[
1
].
detect
=
((
status
&
PCSR_S1_DETECT
)
==
0
)
?
1
:
0
;
state_array
->
state
[
1
].
ready
=
((
status
&
PCSR_S1_READY
)
==
0
)
?
0
:
1
;
state_array
->
state
[
1
].
bvd1
=
((
status
&
PCSR_S1_BVD1
)
==
0
)
?
0
:
1
;
state_array
->
state
[
1
].
bvd2
=
((
status
&
PCSR_S1_BVD2
)
==
0
)
?
0
:
1
;
state_array
->
state
[
1
].
wrprot
=
((
status
&
PCSR_S1_WP
)
==
0
)
?
0
:
1
;
state_array
->
state
[
1
].
vs_3v
=
((
status
&
PCSR_S1_VS1
)
==
0
)
?
1
:
0
;
state_array
->
state
[
1
].
vs_Xv
=
((
status
&
PCSR_S1_VS2
)
==
0
)
?
1
:
0
;
return
return_val
;
}
printk
(
"%s(): config socket %d vcc %d vpp %d
\n
"
,
__FUNCTION__
,
conf
->
sock
,
conf
->
vcc
,
conf
->
vpp
);
static
int
jornada720_pcmcia_get_irq_info
(
struct
pcmcia_irq_info
*
info
)
{
switch
(
info
->
sock
){
switch
(
conf
->
sock
)
{
case
0
:
info
->
irq
=
S0_READY_NINT
;
break
;
case
1
:
info
->
irq
=
S1_READY_NINT
;
break
;
pa_dwr_mask
=
SOCKET0_POWER
|
SOCKET0_3V
;
switch
(
conf
->
vcc
)
{
default:
return
-
1
;
case
0
:
pa_dwr_set
=
0
;
break
;
case
33
:
pa_dwr_set
=
SOCKET0_POWER
|
SOCKET0_3V
;
break
;
case
50
:
pa_dwr_set
=
SOCKET0_POWER
;
break
;
}
return
0
;
}
static
int
jornada720_pcmcia_configure_socket
(
const
struct
pcmcia_configure
*
configure
)
{
unsigned
long
pccr
=
PCCR
,
gpio
=
PA_DWR
;
printk
(
"%s(): config socket %d vcc %d vpp %d
\n
"
,
__FUNCTION__
,
configure
->
sock
,
configure
->
vcc
,
configure
->
vpp
);
switch
(
configure
->
sock
){
case
0
:
switch
(
configure
->
vcc
){
case
0
:
pccr
=
(
pccr
&
~
PCCR_S0_FLT
);
gpio
&=~
(
SOCKET0_POWER
|
SOCKET0_3V
);
break
;
case
33
:
pccr
=
(
pccr
&
~
PCCR_S0_PSE
)
|
PCCR_S0_FLT
|
PCCR_S0_PWAITEN
;
gpio
|=
SOCKET0_POWER
|
SOCKET0_3V
;
break
;
case
50
:
pccr
=
(
pccr
|
PCCR_S0_PSE
|
PCCR_S0_FLT
|
PCCR_S0_PWAITEN
);
gpio
=
(
gpio
&
~
SOCKET0_3V
)
|
SOCKET0_POWER
;
break
;
case
1
:
pa_dwr_mask
=
SOCKET1_POWER
;
switch
(
conf
->
vcc
)
{
default:
printk
(
KERN_ERR
"%s(): unrecognized Vcc %u
\n
"
,
__FUNCTION__
,
configure
->
vcc
)
;
return
-
1
;
case
0
:
pa_dwr_set
=
0
;
break
;
case
33
:
pa_dwr_set
=
SOCKET1_POWER
;
break
;
case
50
:
pa_dwr_set
=
SOCKET1_POWER
;
break
;
}
switch
(
configure
->
vpp
){
case
0
:
break
;
case
50
:
printk
(
KERN_ERR
"%s(): 5.0 Vpp %u
\n
"
,
__FUNCTION__
,
configure
->
vpp
);
break
;
case
120
:
printk
(
KERN_ERR
"%s(): 12 Vpp %u
\n
"
,
__FUNCTION__
,
configure
->
vpp
);
break
;
default:
printk
(
KERN_ERR
"%s(): unrecognized Vpp %u
\n
"
,
__FUNCTION__
,
configure
->
vpp
);
return
-
1
;
}
pccr
=
(
configure
->
reset
)
?
(
pccr
|
PCCR_S0_RST
)
:
(
pccr
&
~
PCCR_S0_RST
);
break
;
case
1
:
switch
(
configure
->
vcc
){
case
0
:
pccr
=
(
pccr
&
~
PCCR_S1_FLT
);
gpio
&=
~
(
SOCKET1_POWER
);
break
;
case
33
:
pccr
=
(
pccr
&
~
PCCR_S1_PSE
)
|
PCCR_S1_FLT
|
PCCR_S1_PWAITEN
;
gpio
|=
SOCKET1_POWER
;
break
;
case
50
:
pccr
=
(
pccr
|
PCCR_S1_PSE
|
PCCR_S1_FLT
|
PCCR_S1_PWAITEN
);
gpio
=
(
gpio
&
~
(
SOCKET1_POWER
))
|
SOCKET1_POWER
;
break
;
default:
printk
(
KERN_ERR
"%s(): unrecognized Vcc %u
\n
"
,
__FUNCTION__
,
configure
->
vcc
);
return
-
1
;
}
if
(
configure
->
vpp
!=
configure
->
vcc
&&
configure
->
vpp
!=
0
){
printk
(
KERN_ERR
"%s(): CF slot cannot support Vpp %u
\n
"
,
__FUNCTION__
,
configure
->
vpp
);
if
(
conf
->
vpp
!=
conf
->
vcc
&&
conf
->
vpp
!=
0
)
{
printk
(
KERN_ERR
"%s(): slot cannot support VPP %u
\n
"
,
__FUNCTION__
,
conf
->
vpp
);
return
-
1
;
}
pccr
=
(
configure
->
reset
)
?
(
pccr
|
PCCR_S1_RST
)
:
(
pccr
&
~
PCCR_S1_RST
);
break
;
default:
return
-
1
;
ret
=
sa1111_pcmcia_configure_socket
(
conf
);
if
(
ret
==
0
)
{
unsigned
long
flags
;
local_irq_save
(
flags
);
PA_DWR
=
(
PA_DWR
&
~
pa_dwr_mask
)
|
pa_dwr_set
;
locla_irq_restore
(
flags
);
}
PCCR
=
pccr
;
PA_DWR
=
gpio
;
return
0
;
return
ret
;
}
struct
pcmcia_low_level
jornada720_pcmcia_ops
=
{
jornada720_pcmcia_init
,
jornada720_pcmcia_shutdown
,
jornada720_pcmcia_socket_state
,
jornada720_pcmcia_get_irq_info
,
jornada720_pcmcia_configure_socket
static
struct
pcmcia_low_level
jornada720_pcmcia_ops
=
{
init:
jornada720_pcmcia_init
,
shutdown:
sa1111_pcmcia_shutdown
,
socket_state:
sa1111_pcmcia_socket_state
,
get_irq_info:
sa1111_pcmcia_get_irq_info
,
configure_socket:
jornada720_pcmcia_configure_socket
,
socket_init:
sa1111_pcmcia_socket_init
,
socket_suspend:
sa1111_pcmcia_socket_suspend
,
};
int
__init
pcmcia_jornada720_init
(
void
)
{
int
ret
=
-
ENODEV
;
if
(
machine_is_jornada720
())
ret
=
sa1100_register_pcmcia
(
&
jornada720_pcmcia_ops
);
return
ret
;
}
void
__exit
pcmcia_jornada720_exit
(
void
)
{
sa1100_unregister_pcmcia
(
&
jornada720_pcmcia_ops
);
}
drivers/pcmcia/sa1100_neponset.c
View file @
f60852d2
/*
* drivers/pcmcia/sa1100_neponset.c
*
linux/
drivers/pcmcia/sa1100_neponset.c
*
* Neponset PCMCIA specific routines
*
*/
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <asm/delay.h>
#include <asm/hardware.h>
#include <asm/irq.h>
#include <asm/arch/pcmcia.h>
#include <asm/arch/assabet.h>
#include <asm/hardware/sa1111.h>
static
int
neponset_pcmcia_init
(
struct
pcmcia_init
*
init
){
int
return_val
=
0
;
#include "sa1100_generic.h"
#include "sa1111_generic.h"
static
int
neponset_pcmcia_init
(
struct
pcmcia_init
*
init
)
{
/* Set GPIO_A<3:0> to be outputs for PCMCIA/CF power controller: */
PA_DDR
&=
~
(
GPIO_GPIO0
|
GPIO_GPIO1
|
GPIO_GPIO2
|
GPIO_GPIO3
);
...
...
@@ -23,109 +23,18 @@ static int neponset_pcmcia_init(struct pcmcia_init *init){
PA_DWR
&=
~
(
GPIO_GPIO0
|
GPIO_GPIO1
|
GPIO_GPIO2
|
GPIO_GPIO3
);
NCR_0
&=
~
(
NCR_A0VPP
|
NCR_A1VPP
);
INTPOL1
|=
(
1
<<
(
S0_READY_NINT
-
SA1111_IRQ
(
32
)))
|
(
1
<<
(
S1_READY_NINT
-
SA1111_IRQ
(
32
)))
|
(
1
<<
(
S0_CD_VALID
-
SA1111_IRQ
(
32
)))
|
(
1
<<
(
S1_CD_VALID
-
SA1111_IRQ
(
32
)))
|
(
1
<<
(
S0_BVD1_STSCHG
-
SA1111_IRQ
(
32
)))
|
(
1
<<
(
S1_BVD1_STSCHG
-
SA1111_IRQ
(
32
)));
return_val
+=
request_irq
(
S0_CD_VALID
,
init
->
handler
,
SA_INTERRUPT
,
"Neponset PCMCIA (0) CD"
,
NULL
);
return_val
+=
request_irq
(
S1_CD_VALID
,
init
->
handler
,
SA_INTERRUPT
,
"Neponset CF (1) CD"
,
NULL
);
return_val
+=
request_irq
(
S0_BVD1_STSCHG
,
init
->
handler
,
SA_INTERRUPT
,
"Neponset PCMCIA (0) BVD1"
,
NULL
);
return_val
+=
request_irq
(
S1_BVD1_STSCHG
,
init
->
handler
,
SA_INTERRUPT
,
"Neponset CF (1) BVD1"
,
NULL
);
return
(
return_val
<
0
)
?
-
1
:
2
;
}
static
int
neponset_pcmcia_shutdown
(
void
){
free_irq
(
S0_CD_VALID
,
NULL
);
free_irq
(
S1_CD_VALID
,
NULL
);
free_irq
(
S0_BVD1_STSCHG
,
NULL
);
free_irq
(
S1_BVD1_STSCHG
,
NULL
);
INTPOL1
&=
~
((
1
<<
(
S0_CD_VALID
-
SA1111_IRQ
(
32
)))
|
(
1
<<
(
S1_CD_VALID
-
SA1111_IRQ
(
32
)))
|
(
1
<<
(
S0_BVD1_STSCHG
-
SA1111_IRQ
(
32
)))
|
(
1
<<
(
S1_BVD1_STSCHG
-
SA1111_IRQ
(
32
))));
return
0
;
}
static
int
neponset_pcmcia_socket_state
(
struct
pcmcia_state_array
*
state_array
){
unsigned
long
status
;
int
return_val
=
1
;
if
(
state_array
->
size
<
2
)
return
-
1
;
memset
(
state_array
->
state
,
0
,
(
state_array
->
size
)
*
sizeof
(
struct
pcmcia_state
));
status
=
PCSR
;
state_array
->
state
[
0
].
detect
=
((
status
&
PCSR_S0_DETECT
)
==
0
)
?
1
:
0
;
state_array
->
state
[
0
].
ready
=
((
status
&
PCSR_S0_READY
)
==
0
)
?
0
:
1
;
state_array
->
state
[
0
].
bvd1
=
((
status
&
PCSR_S0_BVD1
)
==
0
)
?
0
:
1
;
state_array
->
state
[
0
].
bvd2
=
((
status
&
PCSR_S0_BVD2
)
==
0
)
?
0
:
1
;
state_array
->
state
[
0
].
wrprot
=
((
status
&
PCSR_S0_WP
)
==
0
)
?
0
:
1
;
state_array
->
state
[
0
].
vs_3v
=
((
status
&
PCSR_S0_VS1
)
==
0
)
?
1
:
0
;
state_array
->
state
[
0
].
vs_Xv
=
((
status
&
PCSR_S0_VS2
)
==
0
)
?
1
:
0
;
state_array
->
state
[
1
].
detect
=
((
status
&
PCSR_S1_DETECT
)
==
0
)
?
1
:
0
;
state_array
->
state
[
1
].
ready
=
((
status
&
PCSR_S1_READY
)
==
0
)
?
0
:
1
;
state_array
->
state
[
1
].
bvd1
=
((
status
&
PCSR_S1_BVD1
)
==
0
)
?
0
:
1
;
state_array
->
state
[
1
].
bvd2
=
((
status
&
PCSR_S1_BVD2
)
==
0
)
?
0
:
1
;
state_array
->
state
[
1
].
wrprot
=
((
status
&
PCSR_S1_WP
)
==
0
)
?
0
:
1
;
state_array
->
state
[
1
].
vs_3v
=
((
status
&
PCSR_S1_VS1
)
==
0
)
?
1
:
0
;
state_array
->
state
[
1
].
vs_Xv
=
((
status
&
PCSR_S1_VS2
)
==
0
)
?
1
:
0
;
return
return_val
;
return
sa1111_pcmcia_init
(
init
);
}
static
int
neponset_pcmcia_get_irq_info
(
struct
pcmcia_irq_info
*
info
){
switch
(
info
->
sock
){
case
0
:
info
->
irq
=
S0_READY_NINT
;
break
;
case
1
:
info
->
irq
=
S1_READY_NINT
;
break
;
default:
return
-
1
;
}
return
0
;
}
static
int
neponset_pcmcia_configure_socket
(
const
struct
pcmcia_configure
*
configure
){
unsigned
long
pccr
=
PCCR
,
ncr
=
NCR_0
,
gpio
=
PA_DWR
;
static
int
neponset_pcmcia_configure_socket
(
const
struct
pcmcia_configure
*
conf
)
{
unsigned
int
ncr_mask
,
pa_dwr_mask
;
unsigned
int
ncr_set
,
pa_dwr_set
;
int
ret
;
/* Neponset uses the Maxim MAX1600, with the following connections:
*
* MAX1600 Neponset
*
* A0VCC SA-1111 GPIO A<1>
...
...
@@ -147,103 +56,90 @@ static int neponset_pcmcia_configure_socket(const struct pcmcia_configure
* the corresponding truth table.
*/
switch
(
configure
->
sock
)
{
switch
(
conf
->
sock
)
{
case
0
:
pa_dwr_mask
=
GPIO_GPIO0
|
GPIO_GPIO1
;
ncr_mask
=
NCR_A0VPP
|
NCR_A1VPP
;
switch
(
configure
->
vcc
){
case
0
:
pccr
=
(
pccr
&
~
PCCR_S0_FLT
);
gpio
&=~
(
GPIO_GPIO0
|
GPIO_GPIO1
);
break
;
case
33
:
pccr
=
(
pccr
&
~
PCCR_S0_PSE
)
|
PCCR_S0_FLT
|
PCCR_S0_PWAITEN
;
gpio
=
(
gpio
&
~
(
GPIO_GPIO0
|
GPIO_GPIO1
))
|
GPIO_GPIO1
;
break
;
case
50
:
pccr
=
(
pccr
|
PCCR_S0_PSE
|
PCCR_S0_FLT
|
PCCR_S0_PWAITEN
);
gpio
=
(
gpio
&
~
(
GPIO_GPIO0
|
GPIO_GPIO1
))
|
GPIO_GPIO0
;
break
;
switch
(
conf
->
vcc
)
{
default:
printk
(
KERN_ERR
"%s(): unrecognized Vcc %u
\n
"
,
__FUNCTION__
,
configure
->
vcc
)
;
return
-
1
;
case
0
:
pa_dwr_set
=
0
;
break
;
case
33
:
pa_dwr_set
=
GPIO_GPIO1
;
break
;
case
50
:
pa_dwr_set
=
GPIO_GPIO0
;
break
;
}
switch
(
configure
->
vpp
){
case
0
:
ncr
&=~
(
NCR_A0VPP
|
NCR_A1VPP
);
break
;
case
120
:
ncr
=
(
ncr
&
~
(
NCR_A0VPP
|
NCR_A1VPP
))
|
NCR_A1VPP
;
break
;
switch
(
conf
->
vpp
)
{
case
0
:
ncr_set
=
0
;
break
;
case
120
:
ncr_set
=
NCR_A1VPP
;
break
;
default:
if
(
configure
->
vpp
==
configure
->
vcc
)
ncr
=
(
ncr
&
~
(
NCR_A0VPP
|
NCR_A1VPP
))
|
NCR_A0VPP
;
if
(
conf
->
vpp
==
conf
->
vcc
)
ncr_set
=
NCR_A0VPP
;
else
{
printk
(
KERN_ERR
"%s(): unrecognized Vpp %u
\n
"
,
__FUNCTION__
,
configure
->
vpp
);
printk
(
KERN_ERR
"%s(): unrecognized VPP %u
\n
"
,
__FUNCTION__
,
conf
->
vpp
);
return
-
1
;
}
}
pccr
=
(
configure
->
reset
)
?
(
pccr
|
PCCR_S0_RST
)
:
(
pccr
&
~
PCCR_S0_RST
);
break
;
case
1
:
switch
(
configure
->
vcc
){
case
0
:
pccr
=
(
pccr
&
~
PCCR_S1_FLT
);
gpio
&=~
(
GPIO_GPIO2
|
GPIO_GPIO3
);
break
;
case
33
:
pccr
=
(
pccr
&
~
PCCR_S1_PSE
)
|
PCCR_S1_FLT
|
PCCR_S1_PWAITEN
;
gpio
=
(
gpio
&
~
(
GPIO_GPIO2
|
GPIO_GPIO3
))
|
GPIO_GPIO2
;
break
;
case
50
:
pccr
=
(
pccr
|
PCCR_S1_PSE
|
PCCR_S1_FLT
|
PCCR_S1_PWAITEN
);
gpio
=
(
gpio
&
~
(
GPIO_GPIO2
|
GPIO_GPIO3
))
|
GPIO_GPIO3
;
break
;
pa_dwr_mask
=
GPIO_GPIO2
|
GPIO_GPIO3
;
ncr_mask
=
0
;
ncr_set
=
0
;
switch
(
conf
->
vcc
)
{
default:
printk
(
KERN_ERR
"%s(): unrecognized Vcc %u
\n
"
,
__FUNCTION__
,
configure
->
vcc
)
;
return
-
1
;
case
0
:
pa_dwr_set
=
0
;
break
;
case
33
:
pa_dwr_set
=
GPIO_GPIO2
;
break
;
case
50
:
pa_dwr_set
=
GPIO_GPIO3
;
break
;
}
if
(
configure
->
vpp
!=
configure
->
vcc
&&
configure
->
vpp
!=
0
)
{
printk
(
KERN_ERR
"%s(): CF slot cannot support Vpp %u
\n
"
,
__FUNCTION__
,
configure
->
vpp
);
if
(
conf
->
vpp
!=
conf
->
vcc
&&
conf
->
vpp
!=
0
)
{
printk
(
KERN_ERR
"%s(): CF slot cannot support VPP %u
\n
"
,
__FUNCTION__
,
conf
->
vpp
);
return
-
1
;
}
pccr
=
(
configure
->
reset
)
?
(
pccr
|
PCCR_S1_RST
)
:
(
pccr
&
~
PCCR_S1_RST
);
break
;
default:
return
-
1
;
}
PCCR
=
pccr
;
NCR_0
=
ncr
;
PA_DWR
=
gpio
;
ret
=
sa1111_pcmcia_configure_socket
(
conf
);
if
(
ret
==
0
)
{
unsigned
long
flags
;
local_irq_save
(
flags
);
NCR_0
=
(
NCR_0
&
~
ncr_mask
)
|
ncr_set
;
PA_DWR
=
(
PA_DWR
&
~
pa_dwr_mask
)
|
pa_dwr_set
;
local_irq_restore
(
flags
);
}
return
0
;
}
struct
pcmcia_low_level
neponset_pcmcia_ops
=
{
neponset_pcmcia_init
,
neponset_pcmcia_shutdown
,
neponset_pcmcia_socket_state
,
neponset_pcmcia_get_irq_info
,
neponset_pcmcia_configure_socket
static
struct
pcmcia_low_level
neponset_pcmcia_ops
=
{
init:
neponset_pcmcia_init
,
shutdown:
sa1111_pcmcia_shutdown
,
socket_state:
sa1111_pcmcia_socket_state
,
get_irq_info:
sa1111_pcmcia_get_irq_info
,
configure_socket:
neponset_pcmcia_configure_socket
,
socket_init:
sa1111_pcmcia_socket_init
,
socket_suspend:
sa1111_pcmcia_socket_suspend
,
};
int
__init
pcmcia_neponset_init
(
void
)
{
int
ret
=
-
ENODEV
;
if
(
machine_is_assabet
()
&&
machine_has_neponset
())
ret
=
sa1100_register_pcmcia
(
&
neponset_pcmcia_ops
);
return
ret
;
}
void
__exit
pcmcia_neponset_exit
(
void
)
{
sa1100_unregister_pcmcia
(
&
neponset_pcmcia_ops
);
}
drivers/pcmcia/sa1100_pangolin.c
View file @
f60852d2
...
...
@@ -4,48 +4,45 @@
* PCMCIA implementation routines for Pangolin
*
*/
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <asm/hardware.h>
#include <asm/irq.h>
#include
<asm/arch/pcmcia.h>
#include
"sa1100_generic.h"
static
int
pangolin_pcmcia_init
(
struct
pcmcia_init
*
init
){
int
irq
,
res
;
int
res
;
/* set GPIO_PCMCIA_CD & GPIO_PCMCIA_IRQ as inputs */
GPDR
&=
~
(
GPIO_PCMCIA_CD
|
GPIO_PCMCIA_IRQ
);
#ifndef CONFIG_SA1100_PANGOLIN_PCMCIA_IDE
/* set GPIO pins GPIO_PCMCIA_BUS_ON & GPIO_PCMCIA_RESET as output */
GPDR
|=
(
GPIO_PCMCIA_BUS_ON
|
GPIO_PCMCIA_RESET
);
/* Enable PCMCIA bus: */
GPCR
=
GPIO_PCMCIA_BUS_ON
;
#else
/* set GPIO pin GPIO_PCMCIA_RESET as output */
GPDR
|=
GPIO_PCMCIA_RESET
;
#endif
/* Set transition detect */
set_
GPIO_IRQ_edge
(
GPIO_PCMCIA_CD
,
GPIO_BOTH_EDGES
);
set_
GPIO_IRQ_edge
(
GPIO_PCMCIA_IRQ
,
GPIO_FALLING_EDGE
);
set_
irq_type
(
IRQ_PCMCIA_CD
,
IRQT_NOEDGE
);
set_
irq_type
(
IRQ_PCMCIA_IRQ
,
IRQT_FALLING
);
/* Register interrupts */
irq
=
IRQ_PCMCIA_CD
;
res
=
request_irq
(
irq
,
init
->
handler
,
SA_INTERRUPT
,
"PCMCIA_CD"
,
NULL
);
if
(
res
<
0
)
goto
irq_err
;
res
=
request_irq
(
IRQ_PCMCIA_CD
,
init
->
handler
,
SA_INTERRUPT
,
"PCMCIA_CD"
,
NULL
);
if
(
res
>=
0
)
/* There's only one slot, but it's "Slot 1": */
return
2
;
irq_err:
printk
(
KERN_ERR
"%s: Request for IRQ %lu failed
\n
"
,
__FUNCTION__
,
irq
);
return
-
1
;
printk
(
KERN_ERR
"%s: request for IRQ%d failed (%d)
\n
"
,
__FUNCTION__
,
IRQ_PCMCIA_CD
,
res
);
return
res
;
}
static
int
pangolin_pcmcia_shutdown
(
void
)
{
/* disable IRQs */
free_irq
(
IRQ_PCMCIA_CD
,
NULL
);
free_irq
(
IRQ_PCMCIA_CD
,
NULL
);
#ifndef CONFIG_SA1100_PANGOLIN_PCMCIA_IDE
/* Disable PCMCIA bus: */
GPSR
=
GPIO_PCMCIA_BUS_ON
;
...
...
@@ -105,7 +102,7 @@ static int pangolin_pcmcia_configure_socket(const struct pcmcia_configure
#ifndef CONFIG_SA1100_PANGOLIN_PCMCIA_IDE
if
(
configure
->
sock
==
0
)
return
0
;
#endif
save_flags_cli
(
flags
);
local_irq_save
(
flags
);
/* Murphy: BUS_ON different from POWER ? */
...
...
@@ -129,7 +126,7 @@ static int pangolin_pcmcia_configure_socket(const struct pcmcia_configure
default:
printk
(
KERN_ERR
"%s(): unrecognized Vcc %u
\n
"
,
__FUNCTION__
,
configure
->
vcc
);
restore_flags
(
flags
);
local_irq_restore
(
flags
);
return
-
1
;
}
#ifdef CONFIG_SA1100_PANGOLIN_PCMCIA_IDE
...
...
@@ -143,15 +140,47 @@ static int pangolin_pcmcia_configure_socket(const struct pcmcia_configure
}
#endif
/* Silently ignore Vpp, output enable, speaker enable. */
restore_flags
(
flags
);
local_irq_restore
(
flags
);
return
0
;
}
static
int
pangolin_pcmcia_socket_init
(
int
sock
)
{
if
(
sock
==
1
)
set_irq_type
(
IRQ_PCmCIA_CD
,
IRQT_BOTHEDGE
);
return
0
;
}
static
int
pangolin_pcmcia_socket_suspend
(
int
sock
)
{
if
(
sock
==
1
)
set_irq_type
(
IRQ_PCmCIA_CD
,
IRQT_NOEDGE
);
return
0
;
}
struct
pcmcia_low_level
pangolin_pcmcia_ops
=
{
pangolin_pcmcia_init
,
pangolin_pcmcia_shutdown
,
pangolin_pcmcia_socket_state
,
pangolin_pcmcia_get_irq_info
,
pangolin_pcmcia_configure_socket
static
struct
pcmcia_low_level
pangolin_pcmcia_ops
=
{
init:
pangolin_pcmcia_init
,
shutdown:
pangolin_pcmcia_shutdown
,
socket_state:
pangolin_pcmcia_socket_state
,
get_irq_info:
pangolin_pcmcia_get_irq_info
,
configure_socket:
pangolin_pcmcia_configure_socket
,
socket_init:
pangolin_pcmcia_socket_init
,
socket_suspend
,
pangolin_pcmcia_socket_suspend
,
};
int
__init
pcmcia_pangolin_init
(
void
)
{
int
ret
=
-
ENODEV
;
if
(
machine_is_pangolin
())
ret
=
sa1100_register_pcmcia
(
&
pangolin_pcmcia_ops
);
return
ret
;
}
void
__exit
pcmcia_pangolin_exit
(
void
)
{
sa1100_unregister_pcmcia
(
&
pangolin_pcmcia_ops
);
}
drivers/pcmcia/sa1100_pfs168.c
View file @
f60852d2
...
...
@@ -7,121 +7,31 @@
*/
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <asm/delay.h>
#include <asm/hardware.h>
#include <asm/irq.h>
#include <asm/arch/pcmcia.h>
static
int
pfs168_pcmcia_init
(
struct
pcmcia_init
*
init
){
int
return_val
=
0
;
#include "sa1100_generic.h"
#include "sa1111_generic.h"
static
int
pfs168_pcmcia_init
(
struct
pcmcia_init
*
init
)
{
/* TPS2211 to standby mode: */
PA_DWR
&=
~
(
GPIO_GPIO0
|
GPIO_GPIO1
|
GPIO_GPIO2
|
GPIO_GPIO3
);
/* Set GPIO_A<3:0> to be outputs for PCMCIA (socket 0) power controller: */
PA_DDR
&=
~
(
GPIO_GPIO0
|
GPIO_GPIO1
|
GPIO_GPIO2
|
GPIO_GPIO3
);
INTPOL1
|=
(
1
<<
(
S0_READY_NINT
-
SA1111_IRQ
(
32
)))
|
(
1
<<
(
S1_READY_NINT
-
SA1111_IRQ
(
32
)))
|
(
1
<<
(
S0_CD_VALID
-
SA1111_IRQ
(
32
)))
|
(
1
<<
(
S1_CD_VALID
-
SA1111_IRQ
(
32
)))
|
(
1
<<
(
S0_BVD1_STSCHG
-
SA1111_IRQ
(
32
)))
|
(
1
<<
(
S1_BVD1_STSCHG
-
SA1111_IRQ
(
32
)));
return_val
+=
request_irq
(
S0_CD_VALID
,
init
->
handler
,
SA_INTERRUPT
,
"PFS168 PCMCIA (0) CD"
,
NULL
);
return_val
+=
request_irq
(
S1_CD_VALID
,
init
->
handler
,
SA_INTERRUPT
,
"PFS168 CF (1) CD"
,
NULL
);
return_val
+=
request_irq
(
S0_BVD1_STSCHG
,
init
->
handler
,
SA_INTERRUPT
,
"PFS168 PCMCIA (0) BVD1"
,
NULL
);
return_val
+=
request_irq
(
S1_BVD1_STSCHG
,
init
->
handler
,
SA_INTERRUPT
,
"PFS168 CF (1) BVD1"
,
NULL
);
return
(
return_val
<
0
)
?
-
1
:
2
;
return
sa1111_pcmcia_init
(
init
);
}
static
int
pfs168_pcmcia_shutdown
(
void
){
free_irq
(
S0_CD_VALID
,
NULL
);
free_irq
(
S1_CD_VALID
,
NULL
);
free_irq
(
S0_BVD1_STSCHG
,
NULL
);
free_irq
(
S1_BVD1_STSCHG
,
NULL
);
INTPOL1
&=
~
((
1
<<
(
S0_CD_VALID
-
SA1111_IRQ
(
32
)))
|
(
1
<<
(
S1_CD_VALID
-
SA1111_IRQ
(
32
)))
|
(
1
<<
(
S0_BVD1_STSCHG
-
SA1111_IRQ
(
32
)))
|
(
1
<<
(
S1_BVD1_STSCHG
-
SA1111_IRQ
(
32
))));
return
0
;
}
static
int
pfs168_pcmcia_socket_state
(
struct
pcmcia_state_array
*
state_array
){
unsigned
long
status
;
int
return_val
=
1
;
if
(
state_array
->
size
<
2
)
return
-
1
;
memset
(
state_array
->
state
,
0
,
(
state_array
->
size
)
*
sizeof
(
struct
pcmcia_state
));
status
=
PCSR
;
state_array
->
state
[
0
].
detect
=
((
status
&
PCSR_S0_DETECT
)
==
0
)
?
1
:
0
;
state_array
->
state
[
0
].
ready
=
((
status
&
PCSR_S0_READY
)
==
0
)
?
0
:
1
;
state_array
->
state
[
0
].
bvd1
=
((
status
&
PCSR_S0_BVD1
)
==
0
)
?
0
:
1
;
state_array
->
state
[
0
].
bvd2
=
((
status
&
PCSR_S0_BVD2
)
==
0
)
?
0
:
1
;
state_array
->
state
[
0
].
wrprot
=
((
status
&
PCSR_S0_WP
)
==
0
)
?
0
:
1
;
state_array
->
state
[
0
].
vs_3v
=
((
status
&
PCSR_S0_VS1
)
==
0
)
?
1
:
0
;
state_array
->
state
[
0
].
vs_Xv
=
((
status
&
PCSR_S0_VS2
)
==
0
)
?
1
:
0
;
state_array
->
state
[
1
].
detect
=
((
status
&
PCSR_S1_DETECT
)
==
0
)
?
1
:
0
;
state_array
->
state
[
1
].
ready
=
((
status
&
PCSR_S1_READY
)
==
0
)
?
0
:
1
;
state_array
->
state
[
1
].
bvd1
=
((
status
&
PCSR_S1_BVD1
)
==
0
)
?
0
:
1
;
state_array
->
state
[
1
].
bvd2
=
((
status
&
PCSR_S1_BVD2
)
==
0
)
?
0
:
1
;
state_array
->
state
[
1
].
wrprot
=
((
status
&
PCSR_S1_WP
)
==
0
)
?
0
:
1
;
state_array
->
state
[
1
].
vs_3v
=
((
status
&
PCSR_S1_VS1
)
==
0
)
?
1
:
0
;
state_array
->
state
[
1
].
vs_Xv
=
((
status
&
PCSR_S1_VS2
)
==
0
)
?
1
:
0
;
return
return_val
;
}
static
int
pfs168_pcmcia_get_irq_info
(
struct
pcmcia_irq_info
*
info
){
switch
(
info
->
sock
){
case
0
:
info
->
irq
=
S0_READY_NINT
;
break
;
case
1
:
info
->
irq
=
S1_READY_NINT
;
break
;
default:
return
-
1
;
}
return
0
;
}
static
int
pfs168_pcmcia_configure_socket
(
const
struct
pcmcia_configure
*
configure
){
unsigned
long
pccr
=
PCCR
,
gpio
=
PA_DWR
;
static
int
pfs168_pcmcia_configure_socket
(
const
struct
pcmcia_configure
*
conf
)
{
unsigned
int
pa_dwr_mask
=
0
,
pa_dwr_set
=
0
;
int
ret
;
/* PFS168 uses the Texas Instruments TPS2211 for PCMCIA (socket 0) voltage control only,
* with the following connections:
...
...
@@ -135,103 +45,100 @@ static int pfs168_pcmcia_configure_socket(const struct pcmcia_configure
*
*/
switch
(
configure
->
sock
)
{
switch
(
conf
->
sock
)
{
case
0
:
pa_dwr_mask
=
GPIO_GPIO0
|
GPIO_GPIO1
|
GPIO_GPIO2
|
GPIO_GPIO3
;
switch
(
configure
->
vcc
){
case
0
:
pccr
=
(
pccr
&
~
PCCR_S0_FLT
);
gpio
&=
~
(
GPIO_GPIO0
|
GPIO_GPIO1
);
break
;
case
33
:
pccr
=
(
pccr
&
~
PCCR_S0_PSE
)
|
PCCR_S0_FLT
|
PCCR_S0_PWAITEN
;
gpio
=
(
gpio
&
~
(
GPIO_GPIO0
|
GPIO_GPIO1
))
|
GPIO_GPIO0
;
break
;
case
50
:
pccr
=
(
pccr
|
PCCR_S0_PSE
|
PCCR_S0_FLT
|
PCCR_S0_PWAITEN
);
gpio
=
(
gpio
&
~
(
GPIO_GPIO0
|
GPIO_GPIO1
))
|
GPIO_GPIO1
;
break
;
switch
(
conf
->
vcc
)
{
default:
printk
(
KERN_ERR
"%s(): unrecognized Vcc %u
\n
"
,
__FUNCTION__
,
configure
->
vcc
)
;
return
-
1
;
case
0
:
pa_dwr_set
=
0
;
break
;
case
33
:
pa_dwr_set
=
GPIO_GPIO0
;
break
;
case
50
:
pa_dwr_set
=
GPIO_GPIO1
;
break
;
}
switch
(
configure
->
vpp
)
{
switch
(
conf
->
vpp
)
{
case
0
:
gpio
&=
~
(
GPIO_GPIO2
|
GPIO_GPIO3
);
break
;
case
120
:
printk
(
KERN_ERR
"%s(): PFS-168 does not support V
pp %uV
\n
"
,
__FUNCTION__
,
configure
->
vpp
/
10
);
printk
(
KERN_ERR
"%s(): PFS-168 does not support V
PP %uV
\n
"
,
__FUNCTION__
,
conf
->
vpp
/
10
);
return
-
1
;
break
;
default:
if
(
configure
->
vpp
==
configure
->
vcc
)
gpio
=
(
gpio
&
~
(
GPIO_GPIO2
|
GPIO_GPIO3
))
|
GPIO_GPIO3
;
if
(
conf
->
vpp
==
conf
->
vcc
)
pa_dwr_set
|=
GPIO_GPIO3
;
else
{
printk
(
KERN_ERR
"%s(): unrecognized V
pp
%u
\n
"
,
__FUNCTION__
,
conf
igure
->
vpp
);
printk
(
KERN_ERR
"%s(): unrecognized V
PP
%u
\n
"
,
__FUNCTION__
,
conf
->
vpp
);
return
-
1
;
}
}
pccr
=
(
configure
->
reset
)
?
(
pccr
|
PCCR_S0_RST
)
:
(
pccr
&
~
PCCR_S0_RST
);
PA_DWR
=
gpio
;
break
;
case
1
:
switch
(
configure
->
vcc
){
case
0
:
pccr
=
(
pccr
&
~
PCCR_S1_FLT
);
break
;
pa_dwr_mask
=
0
;
pa_dwr_set
=
0
;
switch
(
conf
->
vcc
)
{
case
0
:
case
33
:
pccr
=
(
pccr
&
~
PCCR_S1_PSE
)
|
PCCR_S1_FLT
|
PCCR_S1_PWAITEN
;
break
;
case
50
:
printk
(
KERN_ERR
"%s(): PFS-168 CompactFlash socket does not support V
cc %uV
\n
"
,
__FUNCTION__
,
configure
->
vcc
/
10
);
printk
(
KERN_ERR
"%s(): PFS-168 CompactFlash socket does not support V
CC %uV
\n
"
,
__FUNCTION__
,
conf
->
vcc
/
10
);
return
-
1
;
break
;
default:
printk
(
KERN_ERR
"%s(): unrecognized V
cc
%u
\n
"
,
__FUNCTION__
,
conf
igure
->
vcc
);
printk
(
KERN_ERR
"%s(): unrecognized V
CC
%u
\n
"
,
__FUNCTION__
,
conf
->
vcc
);
return
-
1
;
}
if
(
configure
->
vpp
!=
configure
->
vcc
&&
configure
->
vpp
!=
0
)
{
printk
(
KERN_ERR
"%s(): CompactFlash socket does not support V
pp %uV
\n
"
,
__FUNCTION__
,
configure
->
vpp
/
10
);
if
(
conf
->
vpp
!=
conf
->
vcc
&&
conf
->
vpp
!=
0
)
{
printk
(
KERN_ERR
"%s(): CompactFlash socket does not support V
PP %uV
\n
"
__FUNCTION__
,
conf
->
vpp
/
10
);
return
-
1
;
}
pccr
=
(
configure
->
reset
)
?
(
pccr
|
PCCR_S1_RST
)
:
(
pccr
&
~
PCCR_S1_RST
);
break
;
default:
return
-
1
;
}
PCCR
=
pccr
;
ret
=
sa1111_pcmcia_configure_socket
(
conf
);
if
(
ret
==
0
)
{
unsigned
long
flags
;
local_irq_save
(
flags
);
PA_DWR
=
(
PA_DWR
&
~
pa_dwr_mask
)
|
pa_dwr_set
;
local_irq_restore
(
flags
);
}
return
0
;
}
struct
pcmcia_low_level
pfs168_pcmcia_ops
=
{
pfs168_pcmcia_init
,
pfs168_pcmcia_shutdown
,
pfs168_pcmcia_socket_state
,
pfs168_pcmcia_get_irq_info
,
pfs168_pcmcia_configure_socket
static
struct
pcmcia_low_level
pfs168_pcmcia_ops
=
{
init:
pfs168_pcmcia_init
,
shutdown:
sa1111_pcmcia_shutdown
,
socket_state:
sa1111_pcmcia_socket_state
,
get_irq_info:
sa1111_pcmcia_get_irq_info
,
configure_socket:
pfs168_pcmcia_configure_socket
,
socket_init:
sa1111_pcmcia_socket_init
,
socket_suspend:
sa1111_pcmcia_socket_suspend
,
};
int
__init
pcmcia_pfs168_init
(
void
)
{
int
ret
=
-
ENODEV
;
if
(
machine_is_pfs168
())
ret
=
sa1100_register_pcmcia
(
&
pfs168_pcmcia_ops
);
return
ret
;
}
void
__exit
pcmcia_pfs168_exit
(
void
)
{
sa1100_unregister_pcmcia
(
&
pfs168_pcmcia_ops
);
}
drivers/pcmcia/sa1100_shannon.c
0 → 100644
View file @
f60852d2
/*
* drivers/pcmcia/sa1100_shannon.c
*
* PCMCIA implementation routines for Shannon
*
*/
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <asm/hardware.h>
#include <asm/arch/shannon.h>
#include <asm/irq.h>
#include "sa1100_generic.h"
static
struct
irqs
{
int
irq
;
const
char
*
str
;
}
irqs
[]
=
{
{
SHANNON_IRQ_GPIO_EJECT_0
,
"PCMCIA_CD_0"
},
{
SHANNON_IRQ_GPIO_EJECT_1
,
"PCMCIA_CD_1"
},
};
static
int
shannon_pcmcia_init
(
struct
pcmcia_init
*
init
)
{
int
i
,
res
;
/* All those are inputs */
GPDR
&=
~
(
SHANNON_GPIO_EJECT_0
|
SHANNON_GPIO_EJECT_1
|
SHANNON_GPIO_RDY_0
|
SHANNON_GPIO_RDY_1
);
GAFR
&=
~
(
SHANNON_GPIO_EJECT_0
|
SHANNON_GPIO_EJECT_1
|
SHANNON_GPIO_RDY_0
|
SHANNON_GPIO_RDY_1
);
/* Set transition detect */
set_irq_type
(
SHANNON_IRQ_GPIO_RDY_0
,
IRQT_FALLING
);
set_irq_type
(
SHANNON_IRQ_GPIO_RDY_1
,
IRQT_FALLING
);
/* Register interrupts */
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
irqs
);
i
++
)
{
set_irq_type
(
irqs
[
i
].
irq
,
IRQT_NOEDGE
);
res
=
request_irq
(
irqs
[
i
].
irq
,
init
->
handler
,
SA_INTERRUPT
,
irqs
[
i
].
str
,
NULL
);
if
(
res
)
goto
irq_err
;
}
return
2
;
irq_err:
printk
(
KERN_ERR
"%s: request for IRQ%d failed (%d)
\n
"
,
__FUNCTION__
,
irqs
[
i
].
irq
,
res
);
while
(
i
--
)
free_irq
(
irqs
[
i
].
irq
,
NULL
);
return
res
;
}
static
int
shannon_pcmcia_shutdown
(
void
)
{
int
i
;
/* disable IRQs */
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
irqs
);
i
++
)
free_irq
(
irqs
[
i
].
irq
,
NULL
);
return
0
;
}
static
int
shannon_pcmcia_socket_state
(
struct
pcmcia_state_array
*
state_array
)
{
unsigned
long
levels
;
memset
(
state_array
->
state
,
0
,
state_array
->
size
*
sizeof
(
struct
pcmcia_state
));
levels
=
GPLR
;
state_array
->
state
[
0
].
detect
=
(
levels
&
SHANNON_GPIO_EJECT_0
)
?
0
:
1
;
state_array
->
state
[
0
].
ready
=
(
levels
&
SHANNON_GPIO_RDY_0
)
?
1
:
0
;
state_array
->
state
[
0
].
wrprot
=
0
;
/* Not available on Shannon. */
state_array
->
state
[
0
].
bvd1
=
1
;
state_array
->
state
[
0
].
bvd2
=
1
;
state_array
->
state
[
0
].
vs_3v
=
1
;
/* FIXME Can only apply 3.3V on Shannon. */
state_array
->
state
[
0
].
vs_Xv
=
0
;
state_array
->
state
[
1
].
detect
=
(
levels
&
SHANNON_GPIO_EJECT_1
)
?
0
:
1
;
state_array
->
state
[
1
].
ready
=
(
levels
&
SHANNON_GPIO_RDY_1
)
?
1
:
0
;
state_array
->
state
[
1
].
wrprot
=
0
;
/* Not available on Shannon. */
state_array
->
state
[
1
].
bvd1
=
1
;
state_array
->
state
[
1
].
bvd2
=
1
;
state_array
->
state
[
1
].
vs_3v
=
1
;
/* FIXME Can only apply 3.3V on Shannon. */
state_array
->
state
[
1
].
vs_Xv
=
0
;
return
1
;
}
static
int
shannon_pcmcia_get_irq_info
(
struct
pcmcia_irq_info
*
info
)
{
if
(
info
->
sock
==
0
)
info
->
irq
=
SHANNON_IRQ_GPIO_RDY_0
;
else
if
(
info
->
sock
==
1
)
info
->
irq
=
SHANNON_IRQ_GPIO_RDY_1
;
else
return
-
1
;
return
0
;
}
static
int
shannon_pcmcia_configure_socket
(
const
struct
pcmcia_configure
*
configure
)
{
switch
(
configure
->
vcc
)
{
case
0
:
/* power off */
printk
(
KERN_WARNING
__FUNCTION__
"(): CS asked for 0V, still applying 3.3V..
\n
"
);
break
;
case
50
:
printk
(
KERN_WARNING
__FUNCTION__
"(): CS asked for 5V, applying 3.3V..
\n
"
);
case
33
:
break
;
default:
printk
(
KERN_ERR
__FUNCTION__
"(): unrecognized Vcc %u
\n
"
,
configure
->
vcc
);
return
-
1
;
}
printk
(
KERN_WARNING
__FUNCTION__
"(): Warning, Can't perform reset
\n
"
);
/* Silently ignore Vpp, output enable, speaker enable. */
return
0
;
}
static
int
shannon_pcmcia_socket_init
(
int
sock
)
{
if
(
sock
==
0
)
set_irq_type
(
SHANNON_IRQ_GPIO_EJECT_0
,
IRQT_BOTHEDGE
);
else
if
(
sock
==
1
)
set_irq_Type
(
SHANNON_IRQ_GPIO_EJECT_1
,
IRQT_BOTHEDGE
);
return
0
;
}
static
int
shannon_pcmcia_socket_suspend
(
int
sock
)
{
if
(
sock
==
0
)
set_irq_type
(
SHANNON_IRQ_GPIO_EJECT_0
,
IRQT_NOEDGE
);
else
if
(
sock
==
1
)
set_irq_type
(
SHANNON_IRQ_GPIO_EJECT_1
,
IRQT_NOEDGE
);
return
0
;
}
static
struct
pcmcia_low_level
shannon_pcmcia_ops
=
{
init:
shannon_pcmcia_init
,
shutdown:
shannon_pcmcia_shutdown
,
socket_state:
shannon_pcmcia_socket_state
,
get_irq_info:
shannon_pcmcia_get_irq_info
,
configure_socket:
shannon_pcmcia_configure_socket
,
socket_init:
shannon_pcmcia_socket_init
,
socket_suspend:
shannon_pcmcia_socket_suspend
,
};
int
__init
pcmcia_shannon_init
(
void
)
{
int
ret
=
-
ENODEV
;
if
(
machine_is_shannon
())
ret
=
sa1100_register_pcmcia
(
&
shannon_pcmcia_ops
);
return
ret
;
}
void
__exit
pcmcia_shannon_exit
(
void
)
{
sa1100_unregister_pcmcia
(
&
shannon_pcmcia_ops
);
}
drivers/pcmcia/sa1100_simpad.c
View file @
f60852d2
...
...
@@ -6,10 +6,11 @@
*/
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <asm/hardware.h>
#include <asm/irq.h>
#include
<asm/arch/pcmcia.h>
#include
"sa1100_generic.h"
extern
long
get_cs3_shadow
(
void
);
extern
void
set_cs3_bit
(
int
value
);
...
...
@@ -19,9 +20,6 @@ extern void clear_cs3_bit(int value);
static
int
simpad_pcmcia_init
(
struct
pcmcia_init
*
init
){
int
irq
,
res
;
/* set GPIO_CF_CD & GPIO_CF_IRQ as inputs */
GPDR
&=
~
(
GPIO_CF_CD
|
GPIO_CF_IRQ
);
set_cs3_bit
(
PCMCIA_RESET
);
clear_cs3_bit
(
PCMCIA_BUFF_DIS
);
clear_cs3_bit
(
PCMCIA_RESET
);
...
...
@@ -29,8 +27,8 @@ static int simpad_pcmcia_init(struct pcmcia_init *init){
clear_cs3_bit
(
VCC_3V_EN
|
VCC_5V_EN
|
EN0
|
EN1
);
/* Set transition detect */
set_
GPIO_IRQ_edge
(
GPIO_CF_CD
,
GPIO_BOTH_EDGES
);
set_
GPIO_IRQ_edge
(
GPIO_CF_IRQ
,
GPIO_FALLING_EDGE
);
set_
irq_type
(
IRQ_GPIO_CF_CD
,
IRQT_NOEDGE
);
set_
irq_type
(
IRQ_GPIO_CF_IRQ
,
IRQT_FALLING
);
/* Register interrupts */
irq
=
IRQ_GPIO_CF_CD
;
...
...
@@ -41,8 +39,9 @@ static int simpad_pcmcia_init(struct pcmcia_init *init){
return
2
;
irq_err:
printk
(
KERN_ERR
"%s: Request for IRQ %lu failed
\n
"
,
__FUNCTION__
,
irq
);
return
-
1
;
printk
(
KERN_ERR
"%s: request for IRQ%d failed (%d)
\n
"
,
__FUNCTION__
,
irq
,
res
);
return
res
;
}
static
int
simpad_pcmcia_shutdown
(
void
)
...
...
@@ -112,7 +111,7 @@ static int simpad_pcmcia_configure_socket(const struct pcmcia_configure
if
(
configure
->
sock
==
0
)
return
0
;
save_flags_cli
(
flags
);
local_irq_save
(
flags
);
/* Murphy: see table of MIC2562a-1 */
...
...
@@ -135,22 +134,51 @@ static int simpad_pcmcia_configure_socket(const struct pcmcia_configure
printk
(
KERN_ERR
"%s(): unrecognized Vcc %u
\n
"
,
__FUNCTION__
,
configure
->
vcc
);
clear_cs3_bit
(
VCC_3V_EN
|
VCC_5V_EN
|
EN0
|
EN1
);
restore_flags
(
flags
);
local_irq_restore
(
flags
);
return
-
1
;
}
/* Silently ignore Vpp, output enable, speaker enable. */
restore_flags
(
flags
);
local_irq_restore
(
flags
);
return
0
;
}
static
int
simpad_pcmcia_socket_init
(
int
sock
)
{
set_irq_type
(
IRQ_GPIO_CF_CD
,
IRQT_BOTHEDGE
);
return
0
;
}
static
int
simpad_pcmcia_socket_suspend
(
int
sock
)
{
set_irq_type
(
IRQ_GPIO_CF_CD
,
IRQT_NOEDGE
);
return
0
;
}
struct
pcmcia_low_level
simpad_pcmcia_ops
=
{
simpad_pcmcia_init
,
simpad_pcmcia_shutdown
,
simpad_pcmcia_socket_state
,
simpad_pcmcia_get_irq_info
,
simpad_pcmcia_configure_socket
static
struct
pcmcia_low_level
simpad_pcmcia_ops
=
{
init:
simpad_pcmcia_init
,
shutdown:
simpad_pcmcia_shutdown
,
socket_state:
simpad_pcmcia_socket_state
,
get_irq_info:
simpad_pcmcia_get_irq_info
,
configure_socket:
simpad_pcmcia_configure_socket
,
socket_init:
simpad_pcmcia_socket_init
,
socket_suspend:
simpad_pcmcia_socket_suspend
,
};
int
__init
pcmcia_simpad_init
(
void
)
{
int
ret
=
-
ENODEV
;
if
(
machine_is_simpad
())
ret
=
sa1100_register_pcmcia
(
&
simpad_pcmcia_ops
);
return
ret
;
}
void
__exit
pcmcia_simpad_exit
(
void
)
{
sa1100_unregister_pcmcia
(
&
simpad_pcmcia_ops
);
}
drivers/pcmcia/sa1100_stork.c
View file @
f60852d2
...
...
@@ -18,8 +18,6 @@
* PCMCIA implementation routines for stork
*
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
...
...
@@ -28,50 +26,58 @@
#include <asm/hardware.h>
#include <asm/irq.h>
#include
<asm/arch/pcmcia.h>
#include
"sa1100_generic.h"
static
int
debug
=
0
;
static
struct
pcmcia_init
sa1100_stork_pcmcia_init
;
static
struct
irqs
{
int
irq
;
const
char
*
str
;
}
irqs
[]
=
{
{
IRQ_GPIO_STORK_PCMCIA_A_CARD_DETECT
,
"PCMCIA_CD0"
},
{
IRQ_GPIO_STORK_PCMCIA_B_CARD_DETECT
,
"PCMCIA_CD1"
},
};
static
int
stork_pcmcia_init
(
struct
pcmcia_init
*
init
)
{
int
irq
,
res
;
printk
(
"in stork_pcmcia_init
\n
"
);
sa1100_stork_pcmcia_init
=
*
init
;
/* Enable CF bus: */
storkSetLatchA
(
STORK_PCMCIA_PULL_UPS_POWER_ON
);
/* All those are inputs */
GPDR
&=
~
(
GPIO_STORK_PCMCIA_A_CARD_DETECT
|
GPIO_STORK_PCMCIA_B_CARD_DETECT
|
GPIO_STORK_PCMCIA_A_RDY
|
GPIO_STORK_PCMCIA_B_RDY
);
printk
(
"in stork_pcmcia_init
\n
"
);
/* Set transition detect */
set_
GPIO_IRQ_edge
(
GPIO_STORK_PCMCIA_A_CARD_DETECT
|
GPIO_STORK_PCMCIA_B_CARD_DETECT
,
GPIO_BOTH_EDGES
);
set_GPIO_IRQ_edge
(
GPIO_STORK_PCMCIA_A_RDY
|
GPIO_STORK_PCMCIA_B_RDY
,
GPIO_FALLING_EDGE
);
set_
irq_type
(
IRQ_GPIO_STORK_PCMCIA_A_RDY
,
IRQT_FALLING
);
set_irq_type
(
IRQ_GPIO_STORK_PCMCIA_B_RDY
,
IRQT_FALLING
);
/* Register interrupts */
irq
=
IRQ_GPIO_STORK_PCMCIA_A_CARD_DETECT
;
res
=
request_irq
(
irq
,
init
->
handler
,
SA_INTERRUPT
,
"PCMCIA_CD0"
,
NULL
);
if
(
res
<
0
)
goto
irq_err
;
irq
=
IRQ_GPIO_STORK_PCMCIA_B_CARD_DETECT
;
res
=
request_irq
(
irq
,
init
->
handler
,
SA_INTERRUPT
,
"PCMCIA_CD1"
,
NULL
);
if
(
res
<
0
)
goto
irq_err
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
irqs
);
i
++
)
{
set_irq_type
(
irqs
[
i
].
irq
,
IRQT_NOEDGE
);
res
=
request_irq
(
irqs
[
i
].
irq
,
init
->
handler
,
SA_INTERRUPT
,
irqs
[
i
].
str
,
NULL
);
if
(
res
)
goto
irq_err
;
}
return
2
;
irq_err:
printk
(
KERN_ERR
__FUNCTION__
": Request for IRQ %u failed
\n
"
,
irq
);
return
-
1
;
printk
(
KERN_ERR
"%s: request for IRQ%d failed (%d)
\n
"
,
__FUNCTION__
,
irq
,
res
);
while
(
i
--
)
free_irq
(
irqs
[
i
].
irq
,
NULL
);
return
res
;
}
static
int
stork_pcmcia_shutdown
(
void
)
{
int
i
;
printk
(
__FUNCTION__
"
\n
"
);
/* disable IRQs */
f
ree_irq
(
IRQ_GPIO_STORK_PCMCIA_A_CARD_DETECT
,
NULL
);
free_irq
(
IRQ_GPIO_STORK_PCMCIA_B_CARD_DETECT
,
NULL
);
f
or
(
i
=
0
;
i
<
ARRAY_SIZE
(
irqs
);
i
++
)
free_irq
(
irqs
[
i
].
irq
,
NULL
);
/* Disable CF bus: */
storkClearLatchA
(
STORK_PCMCIA_PULL_UPS_POWER_ON
);
...
...
@@ -140,7 +146,7 @@ static int stork_pcmcia_configure_socket(const struct pcmcia_configure *configur
printk
(
__FUNCTION__
": socket=%d vcc=%d vpp=%d reset=%d
\n
"
,
card
,
configure
->
vcc
,
configure
->
vpp
,
configure
->
reset
);
save_flags_cli
(
flags
);
local_irq_save
(
flags
);
if
(
card
==
0
)
{
DETECT
=
GPIO_STORK_PCMCIA_A_CARD_DETECT
;
...
...
@@ -174,7 +180,7 @@ static int stork_pcmcia_configure_socket(const struct pcmcia_configure *configur
default:
printk
(
KERN_ERR
"%s(): unrecognized Vcc %u
\n
"
,
__FUNCTION__
,
configure
->
vcc
);
restore_flags
(
flags
);
local_irq_restore
(
flags
);
return
-
1
;
}
...
...
@@ -183,7 +189,7 @@ static int stork_pcmcia_configure_socket(const struct pcmcia_configure *configur
else
storkClearLatchB
(
RESET
);
restore_flags
(
flags
);
local_irq_restore
(
flags
);
/* silently ignore vpp and speaker enables. */
...
...
@@ -192,11 +198,57 @@ static int stork_pcmcia_configure_socket(const struct pcmcia_configure *configur
return
0
;
}
struct
pcmcia_low_level
stork_pcmcia_ops
=
{
stork_pcmcia_init
,
stork_pcmcia_shutdown
,
stork_pcmcia_socket_state
,
stork_pcmcia_get_irq_info
,
stork_pcmcia_configure_socket
static
int
stork_pcmcia_socket_init
(
int
sock
)
{
storkSetLatchA
(
STORK_PCMCIA_PULL_UPS_POWER_ON
);
if
(
sock
==
0
)
set_irq_type
(
IRQ_GPIO_STORK_PCMCIA_A_CARD_DETECT
,
IRQT_BOTHEDGE
);
else
if
(
sock
==
1
)
set_irq_type
(
IRQ_GPIO_STORK_PCMCIA_B_CARD_DETECT
,
IRQT_BOTHEDGE
);
return
0
;
}
static
int
stork_pcmcia_socket_suspend
(
int
sock
)
{
if
(
sock
==
0
)
set_irq_type
(
IRQ_GPIO_STORK_PCMCIA_A_CARD_DETECT
,
IRQT_NOEDGE
);
else
if
(
sock
==
1
)
{
set_irq_type
(
IRQ_GPIO_STORK_PCMCIA_B_CARD_DETECT
,
IRQT_NOEDGE
);
/*
* Hack!
*/
storkClearLatchA
(
STORK_PCMCIA_PULL_UPS_POWER_ON
);
}
return
0
;
}
static
struct
pcmcia_low_level
stork_pcmcia_ops
=
{
init:
stork_pcmcia_init
,
shutdown:
stork_pcmcia_shutdown
,
socket_state:
stork_pcmcia_socket_state
,
get_irq_info:
stork_pcmcia_get_irq_info
,
configure_socket:
stork_pcmcia_configure_socket
,
socket_init:
stork_pcmcia_socket_init
,
socket_suspend:
stork_pcmcia_socket_suspend
,
};
int
__init
pcmcia_stork_init
(
void
)
{
int
ret
=
-
ENODEV
;
if
(
machine_is_stork
())
ret
=
sa1100_register_pcmcia
(
&
stork_pcmcia_ops
);
return
ret
;
}
void
__exit
pcmcia_stork_exit
(
void
)
{
sa1100_unregister_pcmcia
(
&
stork_pcmcia_ops
);
}
drivers/pcmcia/sa1100_system3.c
0 → 100644
View file @
f60852d2
/*
* drivers/pcmcia/sa1100_system3.c
*
* PT Diagital Board PCMCIA specific routines
*
* Copyright (C) 2001 Stefan Eletzhofer <stefan.eletzhofer@eletztrick.de>
*
* $Id: sa1100_system3.c,v 1.1.4.2 2002/02/25 13:56:45 seletz Exp $
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* $Log: sa1100_system3.c,v $
* Revision 1.1.4.2 2002/02/25 13:56:45 seletz
* - more cleanups
* - setup interrupts for CF card only ATM
*
* Revision 1.1.4.1 2002/02/14 02:23:27 seletz
* - 2.5.2-rmk6 PCMCIA changes
*
* Revision 1.1.2.1 2002/02/13 23:49:33 seletz
* - added from 2.4.16-rmk2
* - cleanups
*
*
*/
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <linux/ioport.h>
#include <asm/hardware.h>
#include <asm/irq.h>
#include <asm/hardware/sa1111.h>
#include "sa1100_generic.h"
#include "sa1111_generic.h"
#define DEBUG 0
#ifdef DEBUG
# define DPRINTK( x, args... ) printk( "%s: line %d: "x, __FUNCTION__, __LINE__, ## args );
#else
# define DPRINTK( x, args... )
/* nix */
#endif
int
system3_pcmcia_init
(
struct
pcmcia_init
*
init
)
{
/* Don't need no CD and BVD* interrupts */
return
2
;
}
int
system3_pcmcia_shutdown
(
void
)
{
return
0
;
}
int
system3_pcmcia_configure_socket
(
const
struct
pcmcia_configure
*
conf
)
{
if
(
!
conf
)
return
-
1
;
/* only CF ATM */
if
(
conf
->
sock
==
0
)
return
-
1
;
return
sa1111_pcmcia_configure_socket
(
conf
);
}
static
int
system3_pcmcia_socket_state
(
struct
pcmcia_state_array
*
state
)
{
unsigned
long
status
=
0
;
if
(
state
->
size
<
2
)
return
-
1
;
memset
(
state
->
state
,
0
,
(
state
->
size
)
*
sizeof
(
struct
pcmcia_state
));
status
=
PCSR
;
#if 0 /* PCMCIA socket not yet connected */
state->state[0].detect = status & PCSR_S0_DETECT ? 0 : 1;
state->state[0].ready = status & PCSR_S0_READY ? 1 : 0;
state->state[0].bvd1 = status & PCSR_S0_BVD1 ? 1 : 0;
state->state[0].bvd2 = 1;
state->state[0].wrprot = status & PCSR_S0_WP ? 1 : 0;
state->state[0].vs_3v = 1;
state->state[0].vs_Xv = 0;
#endif
state
->
state
[
1
].
detect
=
status
&
PCSR_S1_DETECT
?
0
:
1
;
state
->
state
[
1
].
ready
=
status
&
PCSR_S1_READY
?
1
:
0
;
state
->
state
[
1
].
bvd1
=
status
&
PCSR_S1_BVD1
?
1
:
0
;
state
->
state
[
1
].
bvd2
=
1
;
state
->
state
[
1
].
wrprot
=
status
&
PCSR_S1_WP
?
1
:
0
;
state
->
state
[
1
].
vs_3v
=
1
;
state
->
state
[
1
].
vs_Xv
=
0
;
DPRINTK
(
"PCSR=0x%08lx, S1_RDY_nIREQ=%d
\n
"
,
status
,
state
->
state
[
1
].
ready
);
return
1
;
}
struct
pcmcia_low_level
system3_pcmcia_ops
=
{
init:
system3_pcmcia_init
,
shutdown:
system3_pcmcia_shutdown
,
socket_state:
system3_pcmcia_socket_state
,
get_irq_info:
sa1111_pcmcia_get_irq_info
,
configure_socket:
system3_pcmcia_configure_socket
,
socket_init:
sa1111_pcmcia_socket_init
,
socket_suspend:
sa1111_pcmcia_socket_suspend
,
};
int
__init
pcmcia_system3_init
(
void
)
{
int
ret
=
-
ENODEV
;
if
(
machine_is_pt_system3
())
ret
=
sa1100_register_pcmcia
(
&
system3_pcmcia_ops
);
return
ret
;
}
void
__exit
pcmcia_system3_exit
(
void
)
{
sa1100_unregister_pcmcia
(
&
system3_pcmcia_ops
);
}
drivers/pcmcia/sa1100_xp860.c
View file @
f60852d2
...
...
@@ -7,128 +7,46 @@
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <asm/hardware.h>
#include <asm/irq.h>
#include
<asm/arch/pcmcia.h>
#include
"sa1100_generic.h"
#define NCR_A0VPP (1<<16)
#define NCR_A1VPP (1<<17)
static
int
xp860_pcmcia_init
(
struct
pcmcia_init
*
init
){
int
return_val
=
0
;
static
int
xp860_pcmcia_init
(
struct
pcmcia_init
*
init
)
{
/* Set GPIO_A<3:0> to be outputs for PCMCIA/CF power controller: */
PA_DDR
&=
~
(
GPIO_GPIO0
|
GPIO_GPIO1
|
GPIO_GPIO2
|
GPIO_GPIO3
);
/* MAX1600 to standby mode: */
PA_DWR
&=
~
(
GPIO_GPIO0
|
GPIO_GPIO1
|
GPIO_GPIO2
|
GPIO_GPIO3
);
#error Consider the following comment
/*
* 1- Please move GPDR initialisation where it is interrupt or preemption
* safe (like from xp860_map_io).
* 2- The GPCR line is bogus i.e. it will simply have absolutely no effect.
* Please see its definition in the SA1110 manual.
* 3- Please do not use NCR_* values!
*/
GPDR
|=
(
NCR_A0VPP
|
NCR_A1VPP
);
GPCR
&=
~
(
NCR_A0VPP
|
NCR_A1VPP
);
INTPOL1
|=
(
1
<<
(
S0_READY_NINT
-
SA1111_IRQ
(
32
)))
|
(
1
<<
(
S1_READY_NINT
-
SA1111_IRQ
(
32
)))
|
(
1
<<
(
S0_CD_VALID
-
SA1111_IRQ
(
32
)))
|
(
1
<<
(
S1_CD_VALID
-
SA1111_IRQ
(
32
)))
|
(
1
<<
(
S0_BVD1_STSCHG
-
SA1111_IRQ
(
32
)))
|
(
1
<<
(
S1_BVD1_STSCHG
-
SA1111_IRQ
(
32
)));
return_val
+=
request_irq
(
S0_CD_VALID
,
init
->
handler
,
SA_INTERRUPT
,
"XP860 PCMCIA (0) CD"
,
NULL
);
return_val
+=
request_irq
(
S1_CD_VALID
,
init
->
handler
,
SA_INTERRUPT
,
"XP860 CF (1) CD"
,
NULL
);
return_val
+=
request_irq
(
S0_BVD1_STSCHG
,
init
->
handler
,
SA_INTERRUPT
,
"XP860 PCMCIA (0) BVD1"
,
NULL
);
return_val
+=
request_irq
(
S1_BVD1_STSCHG
,
init
->
handler
,
SA_INTERRUPT
,
"XP860 CF (1) BVD1"
,
NULL
);
return
(
return_val
<
0
)
?
-
1
:
2
;
}
static
int
xp860_pcmcia_shutdown
(
void
){
free_irq
(
S0_CD_VALID
,
NULL
);
free_irq
(
S1_CD_VALID
,
NULL
);
free_irq
(
S0_BVD1_STSCHG
,
NULL
);
free_irq
(
S1_BVD1_STSCHG
,
NULL
);
INTPOL1
&=
~
((
1
<<
(
S0_CD_VALID
-
SA1111_IRQ
(
32
)))
|
(
1
<<
(
S1_CD_VALID
-
SA1111_IRQ
(
32
)))
|
(
1
<<
(
S0_BVD1_STSCHG
-
SA1111_IRQ
(
32
)))
|
(
1
<<
(
S1_BVD1_STSCHG
-
SA1111_IRQ
(
32
))));
return
0
;
return
sa1111_pcmcia_init
(
init
);
}
static
int
xp860_pcmcia_socket_state
(
struct
pcmcia_state_array
*
state_array
){
unsigned
long
status
;
int
return_val
=
1
;
if
(
state_array
->
size
<
2
)
return
-
1
;
memset
(
state_array
->
state
,
0
,
(
state_array
->
size
)
*
sizeof
(
struct
pcmcia_state
));
status
=
PCSR
;
state_array
->
state
[
0
].
detect
=
((
status
&
PCSR_S0_DETECT
)
==
0
)
?
1
:
0
;
state_array
->
state
[
0
].
ready
=
((
status
&
PCSR_S0_READY
)
==
0
)
?
0
:
1
;
state_array
->
state
[
0
].
bvd1
=
((
status
&
PCSR_S0_BVD1
)
==
0
)
?
0
:
1
;
state_array
->
state
[
0
].
bvd2
=
((
status
&
PCSR_S0_BVD2
)
==
0
)
?
0
:
1
;
state_array
->
state
[
0
].
wrprot
=
((
status
&
PCSR_S0_WP
)
==
0
)
?
0
:
1
;
state_array
->
state
[
0
].
vs_3v
=
((
status
&
PCSR_S0_VS1
)
==
0
)
?
1
:
0
;
state_array
->
state
[
0
].
vs_Xv
=
((
status
&
PCSR_S0_VS2
)
==
0
)
?
1
:
0
;
state_array
->
state
[
1
].
detect
=
((
status
&
PCSR_S1_DETECT
)
==
0
)
?
1
:
0
;
state_array
->
state
[
1
].
ready
=
((
status
&
PCSR_S1_READY
)
==
0
)
?
0
:
1
;
state_array
->
state
[
1
].
bvd1
=
((
status
&
PCSR_S1_BVD1
)
==
0
)
?
0
:
1
;
state_array
->
state
[
1
].
bvd2
=
((
status
&
PCSR_S1_BVD2
)
==
0
)
?
0
:
1
;
state_array
->
state
[
1
].
wrprot
=
((
status
&
PCSR_S1_WP
)
==
0
)
?
0
:
1
;
state_array
->
state
[
1
].
vs_3v
=
((
status
&
PCSR_S1_VS1
)
==
0
)
?
1
:
0
;
state_array
->
state
[
1
].
vs_Xv
=
((
status
&
PCSR_S1_VS2
)
==
0
)
?
1
:
0
;
return
return_val
;
}
static
int
xp860_pcmcia_get_irq_info
(
struct
pcmcia_irq_info
*
info
){
switch
(
info
->
sock
){
case
0
:
info
->
irq
=
S0_READY_NINT
;
break
;
case
1
:
info
->
irq
=
S1_READY_NINT
;
break
;
default:
return
-
1
;
}
return
0
;
}
static
int
xp860_pcmcia_configure_socket
(
const
struct
pcmcia_configure
*
configure
){
unsigned
long
pccr
=
PCCR
,
ncr
=
GPLR
,
gpio
=
PA_DWR
;
static
int
xp860_pcmcia_configure_socket
(
const
struct
pcmcia_configure
*
conf
)
{
unsigned
int
gpio_mask
,
pa_dwr_mask
;
unsigned
int
gpio_set
,
pa_dwr_set
;
int
ret
;
/* Neponset uses the Maxim MAX1600, with the following connections:
#warning ^^^ This isn't a neponset!
*
* MAX1600 Neponset
*
...
...
@@ -151,105 +69,90 @@ static int xp860_pcmcia_configure_socket(const struct pcmcia_configure
* the corresponding truth table.
*/
switch
(
configure
->
sock
){
case
0
:
switch
(
configure
->
vcc
){
switch
(
conf
->
sock
)
{
case
0
:
gpio
&=~
(
GPIO_GPIO0
|
GPIO_GPIO1
);
break
;
case
33
:
pccr
=
(
pccr
&
~
PCCR_S0_PSE
);
gpio
=
(
gpio
&
~
(
GPIO_GPIO0
|
GPIO_GPIO1
))
|
GPIO_GPIO1
;
break
;
case
50
:
pccr
=
(
pccr
|
PCCR_S0_PSE
);
gpio
=
(
gpio
&
~
(
GPIO_GPIO0
|
GPIO_GPIO1
))
|
GPIO_GPIO0
;
break
;
pa_dwr_mask
=
GPIO_GPIO0
|
GPIO_GPIO1
;
gpio_mask
=
NCR_A0VPP
|
NCR_A1VPP
;
switch
(
conf
->
vcc
)
{
default:
printk
(
KERN_ERR
"%s(): unrecognized Vcc %u
\n
"
,
__FUNCTION__
,
configure
->
vcc
)
;
return
-
1
;
case
0
:
pa_dwr_set
=
0
;
break
;
case
33
:
pa_dwr_set
=
GPIO_GPIO1
;
break
;
case
50
:
pa_dwr_set
=
GPIO_GPIO0
;
break
;
}
switch
(
configure
->
vpp
){
case
0
:
ncr
&=~
(
NCR_A0VPP
|
NCR_A1VPP
);
break
;
case
120
:
ncr
=
(
ncr
&
~
(
NCR_A0VPP
|
NCR_A1VPP
))
|
NCR_A1VPP
;
break
;
switch
(
conf
->
vpp
)
{
case
0
:
gpio_set
=
0
;
break
;
case
120
:
gpio_set
=
NCR_A1VPP
;
break
;
default:
if
(
configure
->
vpp
==
configure
->
vcc
)
ncr
=
(
ncr
&
~
(
NCR_A0VPP
|
NCR_A1VPP
))
|
NCR_A0VPP
;
if
(
conf
->
vpp
==
conf
->
vcc
)
gpio_set
=
NCR_A0VPP
;
else
{
printk
(
KERN_ERR
"%s(): unrecognized Vpp %u
\n
"
,
__FUNCTION__
,
configure
->
vpp
);
printk
(
KERN_ERR
"%s(): unrecognized Vpp %u
\n
"
,
__FUNCTION__
,
conf
->
vpp
);
return
-
1
;
}
}
pccr
=
(
configure
->
reset
)
?
(
pccr
|
PCCR_S0_RST
)
:
(
pccr
&
~
PCCR_S0_RST
);
pccr
=
(
configure
->
output
)
?
(
pccr
|
PCCR_S0_FLT
)
:
(
pccr
&
~
PCCR_S0_FLT
);
break
;
case
1
:
switch
(
configure
->
vcc
){
case
0
:
gpio
&=~
(
GPIO_GPIO2
|
GPIO_GPIO3
);
break
;
case
33
:
pccr
=
(
pccr
&
~
PCCR_S1_PSE
);
gpio
=
(
gpio
&
~
(
GPIO_GPIO2
|
GPIO_GPIO3
))
|
GPIO_GPIO2
;
break
;
case
50
:
pccr
=
(
pccr
|
PCCR_S1_PSE
);
gpio
=
(
gpio
&
~
(
GPIO_GPIO2
|
GPIO_GPIO3
))
|
GPIO_GPIO3
;
break
;
pa_dwr_mask
=
GPIO_GPIO2
|
GPIO_GPIO3
;
gpio_mask
=
0
;
gpio_set
=
0
;
switch
(
conf
->
vcc
)
{
default:
printk
(
KERN_ERR
"%s(): unrecognized Vcc %u
\n
"
,
__FUNCTION__
,
configure
->
vcc
)
;
return
-
1
;
case
0
:
pa_dwr_set
=
0
;
break
;
case
33
:
pa_dwr_set
=
GPIO_GPIO2
;
break
;
case
50
:
pa_dwr_set
=
GPIO_GPIO3
;
break
;
}
if
(
configure
->
vpp
!=
configure
->
vcc
&&
configure
->
vpp
!=
0
)
{
printk
(
KERN_ERR
"%s(): CF slot cannot support Vpp %u
\n
"
,
__FUNCTION__
,
configure
->
vpp
);
if
(
conf
->
vpp
!=
conf
->
vcc
&&
conf
->
vpp
!=
0
)
{
printk
(
KERN_ERR
"%s(): CF slot cannot support Vpp %u
\n
"
,
__FUNCTION__
,
conf
->
vpp
);
return
-
1
;
}
pccr
=
(
configure
->
reset
)
?
(
pccr
|
PCCR_S1_RST
)
:
(
pccr
&
~
PCCR_S1_RST
);
pccr
=
(
configure
->
output
)
?
(
pccr
|
PCCR_S1_FLT
)
:
(
pccr
&
~
PCCR_S1_FLT
);
break
;
default:
return
-
1
;
}
PCCR
=
pccr
;
ncr
&=
NCR_A0VPP
|
NCR_A1VPP
;
GPSR
=
ncr
;
GPCR
=
(
~
ncr
)
&
(
NCR_A0VPP
|
NCR_A1VPP
);
PA_DWR
=
gpio
;
ret
=
sa1111_pcmcia_configure_socket
(
conf
);
if
(
ret
==
0
)
{
unsigned
long
flags
;
return
0
;
local_irq_save
(
flags
);
PA_DWR
=
(
PA_DWR
&
~
pa_dwr_mask
)
|
pa_dwr_set
;
GPSR
=
gpio_set
;
GPCR
=
gpio_set
^
gpio_mask
;
local_irq_restore
(
flags
);
}
return
ret
;
}
struct
pcmcia_low_level
xp860_pcmcia_ops
=
{
xp860_pcmcia_init
,
xp860_pcmcia_shutdown
,
xp860_pcmcia_socket_state
,
xp860_pcmcia_get_irq_info
,
xp860_pcmcia_configure_socket
static
struct
pcmcia_low_level
xp860_pcmcia_ops
=
{
init:
xp860_pcmcia_init
,
shutdown:
sa1111_pcmcia_shutdown
,
socket_state:
sa1111_pcmcia_socket_state
,
get_irq_info:
sa1111_pcmcia_get_irq_info
,
configure_socket:
xp860_pcmcia_configure_socket
,
socket_init:
sa1111_pcmcia_socket_init
,
socket_suspend:
sa1111_pcmcia_socket_suspend
,
};
int
__init
pcmcia_xp860_init
(
void
)
{
int
ret
=
-
ENODEV
;
if
(
machine_is_xp860
())
ret
=
sa1100_register_pcmcia
(
&
xp860_pcmcia_ops
);
return
ret
;
}
void
__exit
pcmcia_xp860_exit
(
void
)
{
sa1100_unregister_pcmcia
(
&
xp860_pcmcia_ops
);
}
drivers/pcmcia/sa1100_yopy.c
View file @
f60852d2
...
...
@@ -6,10 +6,11 @@
*/
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <asm/hardware.h>
#include <asm/irq.h>
#include
<asm/arch/pcmcia.h>
#include
"sa1100_generic.h"
static
inline
void
pcmcia_power
(
int
on
)
{
...
...
@@ -23,45 +24,53 @@ static inline void pcmcia_reset(int reset)
yopy_gpio_set
(
GPIO_CF_RESET
,
reset
);
}
static
struct
irqs
{
int
irq
;
const
char
*
str
;
}
irqs
[]
=
{
{
IRQ_CF_CD
,
"CF_CD"
},
{
IRQ_CF_BVD2
,
"CF_BVD2"
},
{
IRQ_CF_BVD1
,
"CF_BVD1"
},
};
static
int
yopy_pcmcia_init
(
struct
pcmcia_init
*
init
)
{
int
i
rq
,
res
;
int
i
,
res
;
pcmcia_power
(
0
);
pcmcia_reset
(
1
);
/* All those are inputs */
GPDR
&=
~
(
GPIO_CF_CD
|
GPIO_CF_BVD2
|
GPIO_CF_BVD1
|
GPIO_CF_IREQ
);
GAFR
&=
~
(
GPIO_CF_CD
|
GPIO_CF_BVD2
|
GPIO_CF_BVD1
|
GPIO_CF_IREQ
);
/* Set transition detect */
set_GPIO_IRQ_edge
(
GPIO_CF_CD
|
GPIO_CF_BVD2
|
GPIO_CF_BVD1
,
GPIO_BOTH_EDGES
);
set_GPIO_IRQ_edge
(
GPIO_CF_IREQ
,
GPIO_FALLING_EDGE
);
set_irq_type
(
IRQ_CF_IREQ
,
IRQT_FALLING
);
/* Register interrupts */
irq
=
IRQ_CF_CD
;
res
=
request_irq
(
irq
,
init
->
handler
,
SA_INTERRUPT
,
"CF_CD"
,
NULL
);
if
(
res
<
0
)
goto
irq_err
;
irq
=
IRQ_CF_BVD2
;
res
=
request_irq
(
irq
,
init
->
handler
,
SA_INTERRUPT
,
"CF_BVD2"
,
NULL
);
if
(
res
<
0
)
goto
irq_err
;
irq
=
IRQ_CF_BVD1
;
res
=
request_irq
(
irq
,
init
->
handler
,
SA_INTERRUPT
,
"CF_BVD1"
,
NULL
);
if
(
res
<
0
)
goto
irq_err
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
irqs
);
i
++
)
{
set_irq_type
(
irqs
[
i
].
irq
,
IRQT_NOEDGE
);
res
=
request_irq
(
irqs
[
i
].
irq
,
init
->
handler
,
SA_INTERRUPT
,
irqs
[
i
].
str
,
NULL
);
if
(
res
)
goto
irq_err
;
}
return
1
;
irq_err:
printk
(
KERN_ERR
"%s: Request for IRQ %d failed
\n
"
,
__FUNCTION__
,
irq
);
return
-
1
;
irq_err:
printk
(
KERN_ERR
"%s: request for IRQ%d failed (%d)
\n
"
,
__FUNCTION__
,
irqs
[
i
].
irq
,
res
);
while
(
i
--
)
free_irq
(
irqs
[
i
].
irq
,
NULL
);
return
res
;
}
static
int
yopy_pcmcia_shutdown
(
void
)
{
int
i
;
/* disable IRQs */
free_irq
(
IRQ_CF_CD
,
NULL
);
free_irq
(
IRQ_CF_BVD2
,
NULL
);
free_irq
(
IRQ_CF_BVD1
,
NULL
);
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
irqs
);
i
++
)
free_irq
(
irqs
[
i
].
irq
,
NULL
);
/* Disable CF */
pcmcia_reset
(
1
);
...
...
@@ -109,7 +118,7 @@ static int yopy_pcmcia_configure_socket(const struct pcmcia_configure *configure
return
-
1
;
switch
(
configure
->
vcc
)
{
case
0
:
/* power off */
;
case
0
:
/* power off */
pcmcia_power
(
0
);
break
;
case
50
:
...
...
@@ -130,10 +139,49 @@ static int yopy_pcmcia_configure_socket(const struct pcmcia_configure *configure
return
0
;
}
struct
pcmcia_low_level
yopy_pcmcia_ops
=
{
yopy_pcmcia_init
,
yopy_pcmcia_shutdown
,
yopy_pcmcia_socket_state
,
yopy_pcmcia_get_irq_info
,
yopy_pcmcia_configure_socket
static
int
yopy_pcmcia_socket_init
(
int
sock
)
{
int
i
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
irqs
);
i
++
)
set_irq_type
(
irqs
[
i
].
irq
,
IRQT_BOTHEDGE
);
return
0
;
}
static
int
yopy_pcmcia_socket_suspend
(
int
sock
)
{
int
i
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
irqs
);
i
++
)
set_irq_type
(
irqs
[
i
].
irq
,
IRQT_NOEDGE
);
return
0
;
}
static
struct
pcmcia_low_level
yopy_pcmcia_ops
=
{
init:
yopy_pcmcia_init
,
shutdown:
yopy_pcmcia_shutdown
,
socket_state:
yopy_pcmcia_socket_state
,
get_irq_info:
yopy_pcmcia_get_irq_info
,
configure_socket:
yopy_pcmcia_configure_socket
,
socket_init:
yopy_pcmcia_socket_init
,
socket_suspend:
yopy_pcmcia_socket_suspend
,
};
int
__init
pcmcia_yopy_init
(
void
)
{
int
ret
=
-
ENODEV
;
if
(
machine_is_yopy
())
ret
=
sa1100_register_pcmcia
(
&
yopy_pcmcia_ops
);
return
ret
;
}
void
__exit
pcmcia_yopy_exit
(
void
)
{
sa1100_unregister_pcmcia
(
&
yopy_pcmcia_ops
);
}
drivers/pcmcia/sa1111_generic.c
0 → 100644
View file @
f60852d2
/*
* linux/drivers/pcmcia/sa1100_sa1111.c
*
* We implement the generic parts of a SA1111 PCMCIA driver. This
* basically means we handle everything except controlling the
* power. Power is machine specific...
*/
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/ioport.h>
#include <asm/hardware.h>
#include <asm/hardware/sa1111.h>
#include <asm/irq.h>
#include "sa1100_generic.h"
#include "sa1111_generic.h"
static
struct
irqs
{
int
irq
;
const
char
*
str
;
}
irqs
[]
=
{
{
S0_CD_VALID
,
"SA1111 PCMCIA card detect"
},
{
S0_BVD1_STSCHG
,
"SA1111 PCMCIA BVD1"
},
{
S1_CD_VALID
,
"SA1111 CF card detect"
},
{
S1_BVD1_STSCHG
,
"SA1111 CF BVD1"
},
};
int
sa1111_pcmcia_init
(
struct
pcmcia_init
*
init
)
{
int
i
,
ret
;
if
(
!
request_mem_region
(
_PCCR
,
512
,
"PCMCIA"
))
return
-
1
;
for
(
i
=
ret
=
0
;
i
<
ARRAY_SIZE
(
irqs
);
i
++
)
{
set_irq_type
(
irqs
[
i
].
irq
,
IRQT_FALLING
);
ret
=
request_irq
(
irqs
[
i
].
irq
,
init
->
handler
,
SA_INTERRUPT
,
irqs
[
i
].
str
,
NULL
);
if
(
ret
)
break
;
}
if
(
i
<
ARRAY_SIZE
(
irqs
))
{
printk
(
KERN_ERR
"sa1111_pcmcia: unable to grab IRQ%d (%d)
\n
"
,
irqs
[
i
].
irq
,
ret
);
while
(
i
--
)
free_irq
(
irqs
[
i
].
irq
,
NULL
);
release_mem_region
(
_PCCR
,
16
);
}
return
ret
?
-
1
:
2
;
}
int
sa1111_pcmcia_shutdown
(
void
)
{
int
i
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
irqs
);
i
++
)
free_irq
(
irqs
[
i
].
irq
,
NULL
);
release_mem_region
(
_PCCR
,
512
);
return
0
;
}
int
sa1111_pcmcia_socket_state
(
struct
pcmcia_state_array
*
state
)
{
unsigned
long
status
;
if
(
state
->
size
<
2
)
return
-
1
;
status
=
PCSR
;
state
->
state
[
0
].
detect
=
status
&
PCSR_S0_DETECT
?
0
:
1
;
state
->
state
[
0
].
ready
=
status
&
PCSR_S0_READY
?
1
:
0
;
state
->
state
[
0
].
bvd1
=
status
&
PCSR_S0_BVD1
?
1
:
0
;
state
->
state
[
0
].
bvd2
=
status
&
PCSR_S0_BVD2
?
1
:
0
;
state
->
state
[
0
].
wrprot
=
status
&
PCSR_S0_WP
?
1
:
0
;
state
->
state
[
0
].
vs_3v
=
status
&
PCSR_S0_VS1
?
0
:
1
;
state
->
state
[
0
].
vs_Xv
=
status
&
PCSR_S0_VS2
?
0
:
1
;
state
->
state
[
1
].
detect
=
status
&
PCSR_S1_DETECT
?
0
:
1
;
state
->
state
[
1
].
ready
=
status
&
PCSR_S1_READY
?
1
:
0
;
state
->
state
[
1
].
bvd1
=
status
&
PCSR_S1_BVD1
?
1
:
0
;
state
->
state
[
1
].
bvd2
=
status
&
PCSR_S1_BVD2
?
1
:
0
;
state
->
state
[
1
].
wrprot
=
status
&
PCSR_S1_WP
?
1
:
0
;
state
->
state
[
1
].
vs_3v
=
status
&
PCSR_S1_VS1
?
0
:
1
;
state
->
state
[
1
].
vs_Xv
=
status
&
PCSR_S1_VS2
?
0
:
1
;
return
1
;
}
int
sa1111_pcmcia_get_irq_info
(
struct
pcmcia_irq_info
*
info
)
{
int
ret
=
0
;
switch
(
info
->
sock
)
{
case
0
:
info
->
irq
=
S0_READY_NINT
;
break
;
case
1
:
info
->
irq
=
S1_READY_NINT
;
break
;
default:
ret
=
1
;
}
return
ret
;
}
int
sa1111_pcmcia_configure_socket
(
const
struct
pcmcia_configure
*
conf
)
{
unsigned
int
rst
,
flt
,
wait
,
pse
,
irq
,
pccr_mask
;
unsigned
long
flags
;
switch
(
conf
->
sock
)
{
case
0
:
rst
=
PCCR_S0_RST
;
flt
=
PCCR_S0_FLT
;
wait
=
PCCR_S0_PWAITEN
;
pse
=
PCCR_S0_PSE
;
irq
=
S0_READY_NINT
;
break
;
case
1
:
rst
=
PCCR_S1_RST
;
flt
=
PCCR_S1_FLT
;
wait
=
PCCR_S1_PWAITEN
;
pse
=
PCCR_S1_PSE
;
irq
=
S1_READY_NINT
;
break
;
default:
return
-
1
;
}
switch
(
conf
->
vcc
)
{
case
0
:
pccr_mask
=
0
;
break
;
case
33
:
pccr_mask
=
wait
;
break
;
case
50
:
pccr_mask
=
pse
|
wait
;
break
;
default:
printk
(
KERN_ERR
"sa1111_pcmcia: unrecognised VCC %u
\n
"
,
conf
->
vcc
);
return
-
1
;
}
if
(
conf
->
reset
)
pccr_mask
|=
rst
;
if
(
conf
->
output
)
pccr_mask
|=
flt
;
local_irq_save
(
flags
);
PCCR
=
(
PCCR
&
~
(
pse
|
flt
|
wait
|
rst
))
|
pccr_mask
;
local_irq_restore
(
flags
);
if
(
conf
->
irq
)
enable_irq
(
irq
);
else
disable_irq
(
irq
);
return
0
;
}
int
sa1111_pcmcia_socket_init
(
int
sock
)
{
return
0
;
}
int
sa1111_pcmcia_socket_suspend
(
int
sock
)
{
return
0
;
}
drivers/pcmcia/sa1111_generic.h
0 → 100644
View file @
f60852d2
extern
int
sa1111_pcmcia_init
(
struct
pcmcia_init
*
);
extern
int
sa1111_pcmcia_shutdown
(
void
);
extern
int
sa1111_pcmcia_socket_state
(
struct
pcmcia_state_array
*
);
extern
int
sa1111_pcmcia_get_irq_info
(
struct
pcmcia_irq_info
*
);
extern
int
sa1111_pcmcia_configure_socket
(
const
struct
pcmcia_configure
*
);
extern
int
sa1111_pcmcia_socket_init
(
int
);
extern
int
sa1111_pcmcia_socket_suspend
(
int
);
fs/partitions/Config.in
View file @
f60852d2
...
...
@@ -38,7 +38,7 @@ else
fi
if [ "$CONFIG_AMIGA" != "y" -a "$CONFIG_ATARI" != "y" -a \
"$CONFIG_MAC" != "y" -a "$CONFIG_SGI_IP22" != "y" -a \
"$CONFIG_SGI_IP27" != "y" ]; then
"$CONFIG_
ARM" != "y" -a "$CONFIG_
SGI_IP27" != "y" ]; then
define_bool CONFIG_MSDOS_PARTITION y
fi
if [ "$CONFIG_AMIGA" = "y" -o "$CONFIG_AFFS_FS" = "y" ]; then
...
...
include/asm-arm/arch-sa1100/graphicsclient.h
View file @
f60852d2
...
...
@@ -76,15 +76,6 @@
#define IRQ_GC_UART1_CTS IRQ_GPIO16
#define IRQ_GC_UART2_CTS IRQ_GPIO17
#ifndef __ASSEMBLY__
struct
gc_uart_ctrl_data_t
{
int
cts_gpio
;
int
cts_prev_state
;
struct
uart_info
*
info
;
struct
uart_port
*
port
;
};
#endif
/* __ASSEMBLY__ */
/* LEDs */
#define ADS_LED0 GPIO_GPIO20
/* on-board D22 */
...
...
include/asm-arm/arch-sa1100/irqs.h
View file @
f60852d2
...
...
@@ -151,4 +151,5 @@
#define IRQ_NEPONSET_SA1111 (IRQ_BOARD_START + 2)
/* PT Digital Board Interrupts (CONFIG_SA1100_PT_SYSTEM3) */
#define IRQ_SYSTEM3_SMC9196 (IRQ_BOARD_START + 0)
#define IRQ_SYSTEM3_SA1111 (IRQ_BOARD_START + 0)
#define IRQ_SYSTEM3_SMC9196 (IRQ_BOARD_START + 1)
include/asm-arm/arch-sa1100/system3.h
View file @
f60852d2
...
...
@@ -67,17 +67,17 @@
/* System ID register */
/* IRQ Source Register */
#define PT_IR
Q
_LAN ( 1<<0 )
#define PT_IR
Q
_X ( 1<<1 )
#define PT_IR
Q
_SA1111 ( 1<<2 )
#define PT_IR
Q
_RS1 ( 1<<3 )
#define PT_IR
Q
_RS1_RING ( 1<<4 )
#define PT_IR
Q
_RS1_DCD ( 1<<5 )
#define PT_IR
Q
_RS1_DSR ( 1<<6 )
#define PT_IR
Q
_RS2 ( 1<<7 )
#define PT_IR
R
_LAN ( 1<<0 )
#define PT_IR
R
_X ( 1<<1 )
#define PT_IR
R
_SA1111 ( 1<<2 )
#define PT_IR
R
_RS1 ( 1<<3 )
#define PT_IR
R
_RS1_RING ( 1<<4 )
#define PT_IR
R
_RS1_DCD ( 1<<5 )
#define PT_IR
R
_RS1_DSR ( 1<<6 )
#define PT_IR
R
_RS2 ( 1<<7 )
/* FIXME */
#define PT_IR
Q
_USAR ( 1<<1 )
#define PT_IR
R
_USAR ( 1<<1 )
/* CTRL 0 */
#define PT_CTRL0_USBSLAVE ( 1<<0 )
...
...
include/asm-arm/pgalloc.h
View file @
f60852d2
...
...
@@ -14,136 +14,20 @@
#include <asm/processor.h>
/*
* Get the cache handling stuff now.
*/
#include <asm/proc/cache.h>
/*
* ARM processors do not cache TLB tables in RAM.
*/
#define flush_tlb_pgtables(mm,start,end) do { } while (0)
/*
* Processor specific parts...
*/
#include <asm/proc/pgalloc.h>
/*
* Page table cache stuff
*/
#ifndef CONFIG_NO_PGT_CACHE
#ifdef CONFIG_SMP
#error Pgtable caches have to be per-CPU, so that no locking is needed.
#endif
/* CONFIG_SMP */
extern
struct
pgtable_cache_struct
{
unsigned
long
*
pgd_cache
;
unsigned
long
*
pte_cache
;
unsigned
long
pgtable_cache_sz
;
}
quicklists
;
#define pgd_quicklist (quicklists.pgd_cache)
#define pmd_quicklist ((unsigned long *)0)
#define pte_quicklist (quicklists.pte_cache)
#define pgtable_cache_size (quicklists.pgtable_cache_sz)
/* used for quicklists */
#define __pgd_next(pgd) (((unsigned long *)pgd)[1])
#define __pte_next(pte) (((unsigned long *)pte)[0])
static
inline
pgd_t
*
get_pgd_fast
(
void
)
{
unsigned
long
*
ret
;
preempt_disable
();
if
((
ret
=
pgd_quicklist
)
!=
NULL
)
{
pgd_quicklist
=
(
unsigned
long
*
)
__pgd_next
(
ret
);
ret
[
1
]
=
ret
[
2
];
clean_dcache_entry
(
ret
+
1
);
pgtable_cache_size
--
;
}
preempt_enable
();
return
(
pgd_t
*
)
ret
;
}
static
inline
void
free_pgd_fast
(
pgd_t
*
pgd
)
{
preempt_disable
();
__pgd_next
(
pgd
)
=
(
unsigned
long
)
pgd_quicklist
;
pgd_quicklist
=
(
unsigned
long
*
)
pgd
;
pgtable_cache_size
++
;
preempt_enable
();
}
static
inline
pte_t
*
pte_alloc_one_fast
(
struct
mm_struct
*
mm
,
unsigned
long
address
)
{
unsigned
long
*
ret
;
preempt_disable
();
if
((
ret
=
pte_quicklist
)
!=
NULL
)
{
pte_quicklist
=
(
unsigned
long
*
)
__pte_next
(
ret
);
ret
[
0
]
=
0
;
clean_dcache_entry
(
ret
);
pgtable_cache_size
--
;
}
preempt_enable
();
return
(
pte_t
*
)
ret
;
}
static
inline
void
free_pte_fast
(
pte_t
*
pte
)
{
preempt_disable
();
__pte_next
(
pte
)
=
(
unsigned
long
)
pte_quicklist
;
pte_quicklist
=
(
unsigned
long
*
)
pte
;
pgtable_cache_size
++
;
preempt_enable
();
}
#else
/* CONFIG_NO_PGT_CACHE */
#define pgd_quicklist ((unsigned long *)0)
#define pmd_quicklist ((unsigned long *)0)
#define pte_quicklist ((unsigned long *)0)
#define get_pgd_fast() ((pgd_t *)0)
#define pte_alloc_one_fast(mm,addr) ((pte_t *)0)
#define free_pgd_fast(pgd) free_pgd_slow(pgd)
#define free_pte_fast(pte) pte_free_slow(pte)
#endif
/* CONFIG_NO_PGT_CACHE */
#define pte_free(pte) free_pte_fast(pte)
/*
* Since we have only two-level page tables, these are trivial
*/
#define pmd_alloc_one_fast(mm,addr) ({ BUG(); ((pmd_t *)1); })
#define pmd_alloc_one(mm,addr) ({ BUG(); ((pmd_t *)2); })
#define pmd_free_slow(pmd) do { } while (0)
#define pmd_free_fast(pmd) do { } while (0)
#define pmd_free(pmd) do { } while (0)
#define pgd_populate(mm,pmd,pte) BUG()
extern
pgd_t
*
get_pgd_slow
(
struct
mm_struct
*
mm
);
extern
void
free_pgd_slow
(
pgd_t
*
pgd
);
static
inline
pgd_t
*
pgd_alloc
(
struct
mm_struct
*
mm
)
{
pgd_t
*
pgd
;
pgd
=
get_pgd_fast
();
if
(
!
pgd
)
pgd
=
get_pgd_slow
(
mm
);
return
pgd
;
}
#define pgd_free(pgd) free_pgd_fast(pgd)
extern
int
do_check_pgt_cache
(
int
,
int
);
#define pgd_alloc(mm) get_pgd_slow(mm)
#define pgd_free(pgd) free_pgd_slow(pgd)
#endif
include/asm-arm/pgtable.h
View file @
f60852d2
...
...
@@ -13,7 +13,6 @@
#include <linux/config.h>
#include <asm/arch/memory.h>
#include <asm/arch/vmalloc.h>
#include <asm/proc-fns.h>
/*
* PMD_SHIFT determines the size of the area a second-level page table can map
...
...
@@ -146,8 +145,16 @@ static inline pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot)
#define pmd_offset(dir, addr) ((pmd_t *)(dir))
/* Find an entry in the third-level page table.. */
#define __pte_offset(addr) (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
#define pte_offset(dir, addr) ((pte_t *)pmd_page(*(dir)) + __pte_offset(addr))
#define __pte_index(addr) (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
#define pmd_page(dir) ((struct page *)__pmd_page(dir))
#define __pte_offset(dir, addr) ((pte_t *)__pmd_page(*(dir)) + __pte_index(addr))
#define pte_offset_kernel __pte_offset
#define pte_offset_map __pte_offset
#define pte_offset_map_nested __pte_offset
#define pte_unmap(pte) do { } while (0)
#define pte_unmap_nested(pte) do { } while (0)
#include <asm/proc/pgtable.h>
...
...
include/asm-arm/proc-armv/pgalloc.h
View file @
f60852d2
...
...
@@ -18,7 +18,8 @@ extern kmem_cache_t *pte_cache;
* from the Linux copy. The processor copies are offset by -PTRS_PER_PTE
* words from the Linux copy.
*/
static
inline
pte_t
*
pte_alloc_one
(
struct
mm_struct
*
mm
,
unsigned
long
address
)
static
inline
pte_t
*
pte_alloc_one_kernel
(
struct
mm_struct
*
mm
,
unsigned
long
addr
)
{
pte_t
*
pte
;
...
...
@@ -28,10 +29,21 @@ static inline pte_t *pte_alloc_one(struct mm_struct *mm, unsigned long address)
return
pte
;
}
static
inline
struct
page
*
pte_alloc_one
(
struct
mm_struct
*
mm
,
unsigned
long
addr
)
{
pte_t
*
pte
;
pte
=
kmem_cache_alloc
(
pte_cache
,
GFP_KERNEL
);
if
(
pte
)
pte
+=
PTRS_PER_PTE
;
return
(
struct
page
*
)
pte
;
}
/*
* Free one PTE table.
*/
static
inline
void
pte_free_
slow
(
pte_t
*
pte
)
static
inline
void
pte_free_
kernel
(
pte_t
*
pte
)
{
if
(
pte
)
{
pte
-=
PTRS_PER_PTE
;
...
...
@@ -39,6 +51,15 @@ static inline void pte_free_slow(pte_t *pte)
}
}
static
inline
void
pte_free
(
struct
page
*
pte
)
{
pte_t
*
_pte
=
(
pte_t
*
)
pte
;
if
(
pte
)
{
_pte
-=
PTRS_PER_PTE
;
kmem_cache_free
(
pte_cache
,
_pte
);
}
}
/*
* Populate the pmdp entry with a pointer to the pte. This pmd is part
* of the mm address space.
...
...
@@ -46,12 +67,14 @@ static inline void pte_free_slow(pte_t *pte)
* If 'mm' is the init tasks mm, then we are doing a vmalloc, and we
* need to set stuff up correctly for it.
*/
#define pmd_populate_kernel(mm,pmdp,pte) \
do { \
BUG_ON(mm != &init_mm); \
set_pmd(pmdp, __mk_pmd(pte, _PAGE_KERNEL_TABLE));\
} while (0)
#define pmd_populate(mm,pmdp,pte) \
do { \
unsigned long __prot; \
if (mm == &init_mm) \
__prot = _PAGE_KERNEL_TABLE; \
else \
__prot = _PAGE_USER_TABLE; \
set_pmd(pmdp, __mk_pmd(pte, __prot)); \
BUG_ON(mm == &init_mm); \
set_pmd(pmdp, __mk_pmd(pte, _PAGE_USER_TABLE)); \
} while (0)
include/asm-arm/proc-armv/pgtable.h
View file @
f60852d2
...
...
@@ -125,7 +125,7 @@ static inline pmd_t __mk_pmd(pte_t *ptep, unsigned long prot)
return
pmd
;
}
static
inline
unsigned
long
pmd_page
(
pmd_t
pmd
)
static
inline
unsigned
long
__
pmd_page
(
pmd_t
pmd
)
{
unsigned
long
ptr
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment