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
Kirill Smelkov
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
Hide 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
;
if
((
irr
&
(
PT_IRR_LAN
|
PT_IRR_SA1111
))
==
0
)
break
;
DPRINTK
(
"%s
\n
"
,
"START"
);
/*
* 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
);
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 /* no SSP yet on system 4 */
if (irr & IRR_USAR) {
d = irq_desc + IRQ_NEPONSET_USAR;
d->handle(IRQ_NEPONSET_USAR, d, regs);
}
#endif
/* SA1111 IRQ not routed to a GPIO. */
sa1111_init_irq
(
-
1
);
desc
->
chip
->
unmask
(
irq
);
}
/* setup extra IRQs */
irq
=
IRQ_SYSTEM3_SMC9196
;
irq_desc
[
irq
].
valid
=
1
;
irq_desc
[
irq
].
probe_ok
=
1
;
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
);
}
}
}
#if 0
/* Highspeed Serial Bus not yet used */
irq = PT_USAR_IRQ;
irq_desc[irq].valid = 1;
irq_desc[irq].probe_ok = 1;
#endif
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
);
/* IRQ by CPLD */
set_GPIO_IRQ_edge
(
GPIO_GPIO
(
25
),
GPIO_RISING_EDGE
);
setup_arm_irq
(
IRQ_GPIO25
,
&
system3_irq
);
/*
* 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
;
unsigned
int
pa_dwr_mask
,
pa_dwr_set
;
int
ret
;
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
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
;
default:
return
-
1
;
}
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
;
pa_dwr_mask
=
GPIO_GPIO0
|
GPIO_GPIO1
;
switch
(
conf
->
vcc
)
{
default:
printk
(
KERN_ERR
"%s(): unrecognized Vcc %u
\n
"
,
__FUNCTION__
,
configure
->
vcc
)
;
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
;
}
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
;
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
;
}
if
(
configure
->
vpp
!=
configure
->
vcc
&&
configure
->
vpp
!=
0
){
printk
(
KERN_ERR
"%s(): CF slot cannot support Vpp %u
\n
"
,
__FUNCTION__
,
configure
->
vpp
);
return
-
1
;
}
pccr
=
(
configure
->
reset
)
?
(
pccr
|
PCCR_S1_RST
)
:
(
pccr
&
~
PCCR_S1_RST
);
break
;
default:
return
-
1
;
}
PCCR
=
pccr
;
PA_DWR
=
gpio
;
if
(
conf
->
vpp
!=
conf
->
vcc
&&
conf
->
vpp
!=
0
)
{
printk
(
KERN_ERR
"%s(): CF slot cannot support VPP %u
\n
"
,
__FUNCTION__
,
conf
->
vpp
);
return
-
1
;
}
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
;
local_irq_restore
(
flags
);
}
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,146 +4,221 @@
* 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"
},
};
static
int
assabet_pcmcia_init
(
struct
pcmcia_init
*
init
)
{
int
i
,
res
;
/* Set transition detect */
set_irq_type
(
ASSABET_IRQ_GPIO_CF_IRQ
,
IRQT_FALLING
);
/* All those are inputs */
GPDR
&=
~
(
ASSABET_GPIO_CF_CD
|
ASSABET_GPIO_CF_BVD2
|
ASSABET_GPIO_CF_BVD1
|
ASSABET_GPIO_CF_IRQ
);
/* 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
;
}
/* 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
);
/* There's only one slot, but it's "Slot 1": */
return
2
;
/* 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
;
irq_err:
printk
(
KERN_ERR
"%s: request for IRQ%d failed (%d)
\n
"
,
__FUNCTION__
,
irqs
[
i
].
irq
,
res
);
/* There's only one slot, but it's "Slot 1": */
return
2
;
while
(
i
--
)
free_irq
(
irqs
[
i
].
irq
,
NULL
)
;
irq_err:
printk
(
KERN_ERR
"%s: Request for IRQ %u failed
\n
"
,
__FUNCTION__
,
irq
);
return
-
1
;
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
);
/* Disable CF bus: */
ASSABET_BCR_set
(
ASSABET_BCR_CF_BUS_OFF
);
int
i
;
return
0
;
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
){
unsigned
long
levels
;
static
int
assabet_pcmcia_socket_state
(
struct
pcmcia_state_array
*
state_array
)
{
unsigned
long
levels
;
if
(
state_array
->
size
<
2
)
return
-
1
;
if
(
state_array
->
size
<
2
)
return
-
1
;
memset
(
state_array
->
state
,
0
,
(
state_array
->
size
)
*
sizeof
(
struct
pcmcia_state
));
levels
=
GPLR
;
levels
=
GPLR
;
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
;
state_array
->
state
[
1
].
detect
=
((
levels
&
ASSABET_GPIO_CF_CD
)
==
0
)
?
1
:
0
;
return
1
;
}
state_array
->
state
[
1
].
ready
=
(
levels
&
ASSABET_GPIO_CF_IRQ
)
?
1
:
0
;
static
int
assabet_pcmcia_get_irq_info
(
struct
pcmcia_irq_info
*
info
)
{
if
(
info
->
sock
>
1
)
return
-
1
;
state_array
->
state
[
1
].
bvd1
=
(
levels
&
ASSABET_GPIO_CF_BVD1
)
?
1
:
0
;
if
(
info
->
sock
==
1
)
info
->
irq
=
ASSABET_IRQ_GPIO_CF_IRQ
;
state_array
->
state
[
1
].
bvd2
=
(
levels
&
ASSABET_GPIO_CF_BVD2
)
?
1
:
0
;
return
0
;
}
state_array
->
state
[
1
].
wrprot
=
0
;
/* Not available on Assabet. */
static
int
assabet_pcmcia_configure_socket
(
const
struct
pcmcia_configure
*
configure
)
{
unsigned
int
mask
;
state_array
->
state
[
1
].
vs_3v
=
1
;
/* Can only apply 3.3V on Assabet. */
if
(
configure
->
sock
>
1
)
return
-
1
;
state_array
->
state
[
1
].
vs_Xv
=
0
;
if
(
configure
->
sock
==
0
)
return
0
;
return
1
;
}
switch
(
configure
->
vcc
)
{
case
0
:
mask
=
0
;
break
;
static
int
assabet_pcmcia_get_irq_info
(
struct
pcmcia_irq_info
*
info
){
case
50
:
printk
(
KERN_WARNING
"%s(): CS asked for 5V, applying 3.3V...
\n
"
,
__FUNCTION__
);
if
(
info
->
sock
>
1
)
return
-
1
;
case
33
:
/* Can only apply 3.3V to the CF slot. */
mask
=
ASSABET_BCR_CF_PWR
;
break
;
if
(
info
->
sock
==
1
)
info
->
irq
=
ASSABET_IRQ_GPIO_CF_IRQ
;
default:
printk
(
KERN_ERR
"%s(): unrecognized Vcc %u
\n
"
,
__FUNCTION__
,
configure
->
vcc
);
return
-
1
;
}
return
0
;
}
/* Silently ignore Vpp, output enable, speaker enable. */
static
int
assabet_pcmcia_configure_socket
(
const
struct
pcmcia_configure
*
configure
)
{
unsigned
long
value
,
flags
;
if
(
configure
->
reset
)
mask
|=
ASSABET_BCR_CF_RST
;
if
(
configure
->
sock
>
1
)
return
-
1
;
ASSABET_BCR_frob
(
ASSABET_BCR_CF_RST
|
ASSABET_BCR_CF_PWR
,
mask
)
;
if
(
configure
->
sock
==
0
)
return
0
;
/*
* 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
);
save_flags_cli
(
flags
);
return
0
;
}
value
=
BCR_value
;
/*
* 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
;
switch
(
configure
->
vcc
){
case
0
:
value
&=
~
ASSABET_BCR_CF_PWR
;
break
;
if
(
sock
==
1
)
{
/*
* Enable CF bus
*/
ASSABET_BCR_clear
(
ASSABET_BCR_CF_BUS_OFF
);
case
50
:
printk
(
KERN_WARNING
"%s(): CS asked for 5V, applying 3.3V...
\n
"
,
__FUNCTION__
);
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
irqs
);
i
++
)
set_irq_type
(
irqs
[
i
].
irq
,
IRQT_BOTHEDGE
);
}
case
33
:
/* Can only apply 3.3V to the CF slot. */
value
|=
ASSABET_BCR_CF_PWR
;
break
;
return
0
;
}
default:
printk
(
KERN_ERR
"%s(): unrecognized Vcc %u
\n
"
,
__FUNCTION__
,
configure
->
vcc
);
restore_flags
(
flags
);
return
-
1
;
}
/*
* Disable card status IRQs on suspend.
*/
static
int
assabet_pcmcia_socket_suspend
(
int
sock
)
{
int
i
;
value
=
(
configure
->
reset
)
?
(
value
|
ASSABET_BCR_CF_RST
)
:
(
value
&
~
ASSABET_BCR_CF_RST
);
if
(
sock
==
1
)
{
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
irqs
);
i
++
)
set_irq_type
(
irqs
[
i
].
irq
,
IRQT_NOEDGE
);
/* Silently ignore Vpp, output enable, speaker enable. */
/*
* 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
);
}
ASSABET_BCR
=
BCR_value
=
value
;
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
,
restore_flags
(
flags
);
socket_init:
assabet_pcmcia_socket_init
,
socket_suspend:
assabet_pcmcia_socket_suspend
,
};
return
0
;
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
;
}
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
};
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
){
return
-
1
;
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
){
return
-
1
;
/* 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
)
{
return
-
1
;
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
;
}
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
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
;
}
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:
/*
* sa1100_pcmcia_state_to_config
* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
*
* Convert PCMCIA socket state to our socket configure structure.
*/
static
struct
pcmcia_configure
sa1100_pcmcia_state_to_config
(
unsigned
int
sock
,
socket_state_t
*
state
)
{
struct
pcmcia_configure
conf
;
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
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
;
}
/* sa1100_pcmcia_driver_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.
/* sa1100_pcmcia_sock_init()
* ^^^^^^^^^^^^^^^^^^^^^^^^^
*
* Please see linux/Documentation/arm/SA1100/PCMCIA for more information
* on the low-level kernel interface.
* (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 on success, -1 on error
*/
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.
* Returns: 0
*/
static
void
__exit
sa1100_pcmcia_driver_shutdown
(
void
){
static
int
sa1100_pcmcia_sock_init
(
unsigned
int
sock
)
{
struct
sa1100_pcmcia_socket
*
skt
=
PCMCIA_SOCKET
(
sock
);
struct
pcmcia_configure
conf
;
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
();
DEBUG
(
2
,
"%s(): initializing socket %u
\n
"
,
__FUNCTION__
,
sock
);
DEBUG
(
1
,
"sa1100: shutdown complete
\n
"
);
}
skt
->
cs_state
=
dead_socket
;
module_exit
(
sa1100_pcmcia_driver_shutdown
);
conf
=
sa1100_pcmcia_state_to_config
(
sock
,
&
dead_socket
);
pcmcia_low_level
->
configure_socket
(
&
conf
);
/* sa1100_pcmcia_init()
* ^^^^^^^^^^^^^^^^^^^^
* We perform all of the interesting initialization tasks in
* sa1100_pcmcia_driver_init().
*
* Returns: 0
*/
static
int
sa1100_pcmcia_init
(
unsigned
int
sock
){
DEBUG
(
2
,
"%s(): initializing socket %u
\n
"
,
__FUNCTION__
,
sock
);
return
0
;
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
,
struct
pcmcia_state
*
prev_state
,
unsigned
int
mask
,
unsigned
int
flags
){
unsigned
int
events
=
0
;
if
(
state
->
detect
!=
prev_state
->
detect
){
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
;
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
){
DEBUG
(
2
,
"%s(): card BVD1 value %u
\n
"
,
__FUNCTION__
,
state
->
bvd1
);
if
(
state
->
bvd1
!=
prev_state
->
bvd1
)
{
DEBUG
(
3
,
"%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
){
if
(
state
->
bvd2
!=
prev_state
->
bvd2
)
{
DEBUG
(
3
,
"%s(): card BVD2 value %u
\n
"
,
__FUNCTION__
,
state
->
bvd2
);
DEBUG
(
2
,
"%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,51 +348,41 @@ 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'
* 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
* undesirable.
*
* SS_CAP_STATIC_MAP: don't bother with the (user-configured) memory
* resource database; we instead pass up physical address ranges
* and allow other parts of Card Services to deal with remapping.
*
* 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.
*/
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
;
}
static
int
sa1100_pcmcia_inquire_socket
(
unsigned
int
sock
,
socket_cap_t
*
cap
)
{
struct
sa1100_pcmcia_socket
*
skt
=
PCMCIA_SOCKET
(
sock
);
int
ret
=
-
1
;
/* 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
* undesirable.
*
* SS_CAP_STATIC_MAP: don't bother with the (user-configured) memory
* resource database; we instead pass up physical address ranges
* and allow other parts of Card Services to deal with remapping.
*
* SS_CAP_PCCARD: we can deal with 16-bit PCMCIA & CF cards, but
* not 32-bit CardBus devices.
*/
cap
->
features
=
(
SS_CAP_PAGE_REGS
|
SS_CAP_STATIC_MAP
|
SS_CAP_PCCARD
);
DEBUG
(
2
,
"%s() for sock %u
\n
"
,
__FUNCTION__
,
sock
);
irq_info
.
sock
=
sock
;
irq_info
.
irq
=-
1
;
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
;
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
;
ret
=
0
;
}
cap
->
irq_mask
=
0
;
cap
->
map_size
=
PAGE_SIZE
;
cap
->
pci_irq
=
irq_info
.
irq
;
cap
->
io_offset
=
sa1100_pcmcia_socket
[
sock
].
virt_io
;
return
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
->
start
=
sa1100_pcmcia_socket
[
sock
].
virt_io
;
map
->
stop
=
map
->
start
+
(
map
->
stop
-
start
);
map
->
stop
-=
map
->
start
;
map
->
stop
+=
(
unsigned
long
)
skt
->
virt_io
;
map
->
start
=
(
unsigned
long
)
skt
->
virt_io
;
s
a1100_pcmcia_socket
[
sock
].
io_map
[
map
->
map
]
=
*
map
;
s
kt
->
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,177 +676,175 @@ 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
;
if
(
map
->
flags
&
MAP_ATTRIB
){
clock
=
cpufreq_get
(
0
);
MECR_BSA_SET
(
mecr
,
sock
,
sa1100_pcmcia_mecr_bs
(
speed
,
clock
));
sa1100_pcmcia_socket
[
sock
].
speed_attr
=
speed
;
/* 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
));
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
"
,
__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
->
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
);
p
+=
sprintf
(
p
,
"Vpp : %d
\n
"
,
sa1100_pcmcia_socket
[
sock
].
cs_state
.
Vpp
);
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
,
"irq : %d
\n
"
,
sa1100_pcmcia_socket
[
sock
].
cs_state
.
io_irq
);
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
,
"I/O : %u (%u)
\n
"
,
s
a1100_pcmcia_socket
[
sock
].
speed_io
,
p
+=
sprintf
(
p
,
"I/O : %u (%u)
\n
"
,
s
kt
->
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
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
;
}
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
int
gcplus_pcmcia_socket_init
(
int
sock
)
{
return
0
;
}
static
int
gcplus_pcmcia_socket_suspend
(
int
sock
)
{
return
0
;
}
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
;
}
static
int
graphicsmaster_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
;
return
sa1111_pcmcia_init
(
init
);
}
static
int
graphicsmaster_pcmcia_configure_socket
(
const
struct
pcmcia_configure
*
configure
)
static
int
graphicsmaster_pcmcia_configure_socket
(
const
struct
pcmcia_configure
*
conf
)
{
unsigned
long
pccr
=
PCCR
,
gpio
=
PA_DWR
;
unsigned
int
pa_dwr_mask
,
pa_dwr_set
;
int
ret
;
switch
(
configure
->
sock
)
{
switch
(
conf
->
sock
)
{
case
0
:
pa_dwr_mask
=
GPIO_GPIO0
|
GPIO_GPIO1
;
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
;
switch
(
conf
->
vcc
)
{
default:
printk
(
KERN_ERR
"%s(): unrecognized Vcc %u
\n
"
,
__FUNCTION__
,
configure
->
vcc
)
;
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
;
}
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
;
}
if
(
configure
->
vpp
!=
configure
->
vcc
&&
configure
->
vpp
!=
0
){
printk
(
KERN_ERR
"%s(): CF slot cannot support Vpp %u
\n
"
,
__FUNCTION__
,
configure
->
vpp
);
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
;
}
}
pccr
=
(
configure
->
reset
)
?
(
pccr
|
PCCR_S1_RST
)
:
(
pccr
&
~
PCCR_S1_RST
);
break
;
default:
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
=
pccr
;
PA_DWR
=
gpio
;
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
;
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,142 +6,192 @@
*/
#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
;
/* Enable CF bus: */
set_h3600_egpio
(
EGPIO_H3600_OPT_NVRAM_ON
);
clr_h3600_egpio
(
EGPIO_H3600_OPT_RESET
);
/* 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_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 */
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
;
return
2
;
#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"
}
};
irq_err:
printk
(
KERN_ERR
__FUNCTION__
": Request for IRQ %u failed
\n
"
,
irq
);
return
-
1
;
static
int
h3600_pcmcia_init
(
struct
pcmcia_init
*
init
)
{
int
i
,
res
;
/*
* Set transition detect
*/
set_irq_type
(
IRQ_GPIO_H3600_PCMCIA_IRQ0
,
IRQT_FALLING
);
set_irq_type
(
IRQ_GPIO_H3600_PCMCIA_IRQ1
,
IRQT_FALLING
);
/*
* 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
;
}
if
(
res
)
{
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
?
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
);
/* Disable CF bus: */
clr_h3600_egpio
(
IPAQ_EGPIO_OPT_NVRAM_ON
);
clr_h3600_egpio
(
IPAQ_EGPIO_OPT_ON
);
set_h3600_egpio
(
IPAQ_EGPIO_OPT_RESET
);
return
0
;
return
0
;
}
static
int
h3600_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
[
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_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
;
return
1
;
static
int
h3600_pcmcia_socket_state
(
struct
pcmcia_state_array
*
state
)
{
unsigned
long
levels
;
if
(
state
->
size
<
2
)
return
-
1
;
levels
=
GPLR
;
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
->
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
)
{
switch
(
info
->
sock
)
{
case
0
:
info
->
irq
=
IRQ_GPIO_H3600_PCMCIA_IRQ0
;
break
;
case
1
:
info
->
irq
=
IRQ_GPIO_H3600_PCMCIA_IRQ1
;
break
;
default:
return
-
1
;
}
return
0
;
static
int
h3600_pcmcia_get_irq_info
(
struct
pcmcia_irq_info
*
info
)
{
switch
(
info
->
sock
)
{
case
0
:
info
->
irq
=
IRQ_GPIO_H3600_PCMCIA_IRQ0
;
break
;
case
1
:
info
->
irq
=
IRQ_GPIO_H3600_PCMCIA_IRQ1
;
break
;
default:
return
-
1
;
}
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
(
configure
->
sock
>
1
)
return
-
1
;
if
(
conf
->
sock
>
1
)
return
-
1
;
save_flags_cli
(
flags
);
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
;
}
switch
(
configure
->
vcc
)
{
case
0
:
clr_h3600_egpio
(
EGPIO_H3600_OPT_ON
);
break
;
if
(
conf
->
reset
)
set_h3600_egpio
(
IPAQ_EGPIO_CARD_RESET
);
else
clr_h3600_egpio
(
IPAQ_EGPIO_CARD_RESET
)
;
case
33
:
case
50
:
set_h3600_egpio
(
EGPIO_H3600_OPT_ON
);
break
;
/* Silently ignore Vpp, output enable, speaker enable. */
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
);
/* Silently ignore Vpp, output enable, speaker enable. */
return
0
;
}
restore_flags
(
flags
);
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
);
set_current_state
(
TASK_UNINTERRUPTIBLE
);
schedule_timeout
(
10
*
HZ
/
1000
);
switch
(
sock
)
{
case
0
:
set_irq_type
(
IRQ_GPIO_H3600_PCMCIA_CD0
,
IRQT_BOTHEDGE
);
break
;
case
1
:
set_irq_type
(
IRQ_GPIO_H3600_PCMCIA_CD1
,
IRQT_BOTHEDGE
);
break
;
}
return
0
;
}
return
0
;
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
;
}
/*
* 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)
#define SOCKET1_3V 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
;
}
static
int
jornada720_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
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
;
}
static
int
jornada720_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
;
return
sa1111_pcmcia_init
(
init
);
}
static
int
jornada720_pcmcia_configure_socket
(
const
struct
pcmcia_configure
*
configure
)
static
int
jornada720_pcmcia_configure_socket
(
const
struct
pcmcia_configure
*
conf
)
{
unsigned
long
pccr
=
PCCR
,
gpio
=
PA_DWR
;
unsigned
int
pa_dwr_mask
,
pa_dwr_set
;
int
ret
;
printk
(
"%s(): config socket %d vcc %d vpp %d
\n
"
,
__FUNCTION__
,
configure
->
sock
,
configure
->
vcc
,
configure
->
vpp
);
switch
(
configure
->
sock
){
conf
->
sock
,
conf
->
vcc
,
conf
->
vpp
);
switch
(
conf
->
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
;
pa_dwr_mask
=
SOCKET0_POWER
|
SOCKET0_3V
;
switch
(
conf
->
vcc
)
{
default:
printk
(
KERN_ERR
"%s(): unrecognized Vcc %u
\n
"
,
__FUNCTION__
,
configure
->
vcc
);
return
-
1
;
}
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
;
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
;
}
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
;
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
;
}
if
(
configure
->
vpp
!=
configure
->
vcc
&&
configure
->
vpp
!=
0
){
printk
(
KERN_ERR
"%s(): CF slot cannot support Vpp %u
\n
"
,
__FUNCTION__
,
configure
->
vpp
);
return
-
1
;
}
pccr
=
(
configure
->
reset
)
?
(
pccr
|
PCCR_S1_RST
)
:
(
pccr
&
~
PCCR_S1_RST
);
break
;
default:
}
if
(
conf
->
vpp
!=
conf
->
vcc
&&
conf
->
vpp
!=
0
)
{
printk
(
KERN_ERR
"%s(): slot cannot support VPP %u
\n
"
,
__FUNCTION__
,
conf
->
vpp
);
return
-
1
;
}
PCCR
=
pccr
;
PA_DWR
=
gpio
;
return
0
;
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
);
}
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
;
/* 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
);
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
){
#include "sa1100_generic.h"
#include "sa1111_generic.h"
free_irq
(
S0_CD_VALID
,
NULL
);
free_irq
(
S1_CD_VALID
,
NULL
);
free_irq
(
S0_BVD1_STSCHG
,
NULL
);
free_irq
(
S1_BVD1_STSCHG
,
NULL
);
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
);
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
))));
/* MAX1600 to standby mode: */
PA_DWR
&=
~
(
GPIO_GPIO0
|
GPIO_GPIO1
|
GPIO_GPIO2
|
GPIO_GPIO3
);
NCR_0
&=
~
(
NCR_A0VPP
|
NCR_A1VPP
);
return
0
;
return
sa1111_pcmcia_init
(
init
)
;
}
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
;
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>
* A1VCC SA-1111 GPIO A<0>
* A0VPP CPLD NCR A0VPP
* A1VPP CPLD NCR A1VPP
* B0VCC SA-1111 GPIO A<2>
* B1VCC SA-1111 GPIO A<3>
* B0VPP ground (slot B is CF)
* B1VPP ground (slot B is CF)
*
* VX VCC (5V)
* VY VCC3_3 (3.3V)
* 12INA 12V
* 12INB ground (slot B is CF)
*
* The MAX1600 CODE pin is tied to ground, placing the device in
* "Standard Intel code" mode. Refer to the Maxim data sheet for
* the corresponding truth table.
*/
switch
(
conf
->
sock
)
{
case
0
:
pa_dwr_mask
=
GPIO_GPIO0
|
GPIO_GPIO1
;
ncr_mask
=
NCR_A0VPP
|
NCR_A1VPP
;
switch
(
conf
->
vcc
)
{
default:
case
0
:
pa_dwr_set
=
0
;
break
;
case
33
:
pa_dwr_set
=
GPIO_GPIO1
;
break
;
case
50
:
pa_dwr_set
=
GPIO_GPIO0
;
break
;
}
switch
(
conf
->
vpp
)
{
case
0
:
ncr_set
=
0
;
break
;
case
120
:
ncr_set
=
NCR_A1VPP
;
break
;
default:
if
(
conf
->
vpp
==
conf
->
vcc
)
ncr_set
=
NCR_A0VPP
;
else
{
printk
(
KERN_ERR
"%s(): unrecognized VPP %u
\n
"
,
__FUNCTION__
,
conf
->
vpp
);
return
-
1
;
}
}
break
;
case
1
:
pa_dwr_mask
=
GPIO_GPIO2
|
GPIO_GPIO3
;
ncr_mask
=
0
;
ncr_set
=
0
;
switch
(
conf
->
vcc
)
{
default:
case
0
:
pa_dwr_set
=
0
;
break
;
case
33
:
pa_dwr_set
=
GPIO_GPIO2
;
break
;
case
50
:
pa_dwr_set
=
GPIO_GPIO3
;
break
;
}
if
(
conf
->
vpp
!=
conf
->
vcc
&&
conf
->
vpp
!=
0
)
{
printk
(
KERN_ERR
"%s(): CF slot cannot support VPP %u
\n
"
,
__FUNCTION__
,
conf
->
vpp
);
return
-
1
;
}
break
;
default:
return
-
1
;
}
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
;
}
static
int
neponset_pcmcia_get_irq_info
(
struct
pcmcia_irq_info
*
info
){
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
,
switch
(
info
->
sock
){
case
0
:
info
->
irq
=
S0_READY_NINT
;
break
;
socket_init:
sa1111_pcmcia_socket_init
,
socket_suspend:
sa1111_pcmcia_socket_suspend
,
};
case
1
:
info
->
irq
=
S1_READY_NINT
;
break
;
int
__init
pcmcia_neponset_init
(
void
)
{
int
ret
=
-
ENODEV
;
default:
return
-
1
;
}
if
(
machine_is_assabet
()
&&
machine_has_neponset
())
ret
=
sa1100_register_pcmcia
(
&
neponset_pcmcia_ops
);
return
0
;
return
ret
;
}
static
int
neponset_pcmcia_configure_socket
(
const
struct
pcmcia_configure
*
configure
){
unsigned
long
pccr
=
PCCR
,
ncr
=
NCR_0
,
gpio
=
PA_DWR
;
/* Neponset uses the Maxim MAX1600, with the following connections:
*
* MAX1600 Neponset
*
* A0VCC SA-1111 GPIO A<1>
* A1VCC SA-1111 GPIO A<0>
* A0VPP CPLD NCR A0VPP
* A1VPP CPLD NCR A1VPP
* B0VCC SA-1111 GPIO A<2>
* B1VCC SA-1111 GPIO A<3>
* B0VPP ground (slot B is CF)
* B1VPP ground (slot B is CF)
*
* VX VCC (5V)
* VY VCC3_3 (3.3V)
* 12INA 12V
* 12INB ground (slot B is CF)
*
* The MAX1600 CODE pin is tied to ground, placing the device in
* "Standard Intel code" mode. Refer to the Maxim data sheet for
* the corresponding truth table.
*/
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
&
~
(
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
;
default:
printk
(
KERN_ERR
"%s(): unrecognized Vcc %u
\n
"
,
__FUNCTION__
,
configure
->
vcc
);
return
-
1
;
}
switch
(
configure
->
vpp
){
case
0
:
ncr
&=~
(
NCR_A0VPP
|
NCR_A1VPP
);
break
;
case
120
:
ncr
=
(
ncr
&
~
(
NCR_A0VPP
|
NCR_A1VPP
))
|
NCR_A1VPP
;
break
;
default:
if
(
configure
->
vpp
==
configure
->
vcc
)
ncr
=
(
ncr
&
~
(
NCR_A0VPP
|
NCR_A1VPP
))
|
NCR_A0VPP
;
else
{
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
&=~
(
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
;
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
);
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
;
return
0
;
void
__exit
pcmcia_neponset_exit
(
void
)
{
sa1100_unregister_pcmcia
(
&
neponset_pcmcia_ops
);
}
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
};
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
;
/* There's only one slot, but it's "Slot 1": */
return
2
;
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
;
}
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
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
;
}
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
;
}
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
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
;
}
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
);
int
irq
,
res
;
/* 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
;
}
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
;
return
sa1111_pcmcia_init
(
init
);
}
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
)
{
switch
(
conf
->
sock
)
{
case
0
:
switch
(
configure
->
vcc
){
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
;
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
0
;
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