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
82521de5
Commit
82521de5
authored
Sep 17, 2003
by
Russell King
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[ARM] Dynamically allocate SA1111 component devices.
parent
a7ce9341
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
146 additions
and
119 deletions
+146
-119
arch/arm/common/sa1111.c
arch/arm/common/sa1111.c
+146
-119
No files found.
arch/arm/common/sa1111.c
View file @
82521de5
...
...
@@ -54,87 +54,74 @@ struct sa1111 {
*/
static
struct
sa1111
*
g_sa1111
;
static
struct
sa1111_dev
usb_dev
=
{
.
skpcr_mask
=
SKPCR_UCLKEN
,
.
devid
=
SA1111_DEVID_USB
,
.
irq
=
{
IRQ_USBPWR
,
IRQ_HCIM
,
IRQ_HCIBUFFACC
,
IRQ_HCIRMTWKP
,
IRQ_NHCIMFCIR
,
IRQ_USB_PORT_RESUME
},
struct
sa1111_dev_info
{
unsigned
long
offset
;
unsigned
long
skpcr_mask
;
unsigned
int
devid
;
unsigned
int
irq
[
6
];
};
static
struct
sa1111_dev
sac_dev
=
{
.
skpcr_mask
=
SKPCR_I2SCLKEN
|
SKPCR_L3CLKEN
,
.
devid
=
SA1111_DEVID_SAC
,
.
irq
=
{
AUDXMTDMADONEA
,
AUDXMTDMADONEB
,
AUDRCVDMADONEA
,
AUDRCVDMADONEB
static
struct
sa1111_dev_info
sa1111_devices
[]
=
{
{
.
offset
=
SA1111_USB
,
.
skpcr_mask
=
SKPCR_UCLKEN
,
.
devid
=
SA1111_DEVID_USB
,
.
irq
=
{
IRQ_USBPWR
,
IRQ_HCIM
,
IRQ_HCIBUFFACC
,
IRQ_HCIRMTWKP
,
IRQ_NHCIMFCIR
,
IRQ_USB_PORT_RESUME
},
},
};
static
struct
sa1111_dev
ssp_dev
=
{
.
skpcr_mask
=
SKPCR_SCLKEN
,
.
devid
=
SA1111_DEVID_SSP
,
};
static
struct
sa1111_dev
kbd_dev
=
{
.
skpcr_mask
=
SKPCR_PTCLKEN
,
.
devid
=
SA1111_DEVID_PS2
,
.
irq
=
{
IRQ_TPRXINT
,
IRQ_TPTXINT
{
.
offset
=
0x0600
,
.
skpcr_mask
=
SKPCR_I2SCLKEN
|
SKPCR_L3CLKEN
,
.
devid
=
SA1111_DEVID_SAC
,
.
irq
=
{
AUDXMTDMADONEA
,
AUDXMTDMADONEB
,
AUDRCVDMADONEA
,
AUDRCVDMADONEB
},
},
};
static
struct
sa1111_dev
mse_dev
=
{
.
skpcr_mask
=
SKPCR_PMCLKEN
,
.
devid
=
SA1111_DEVID_PS2
,
.
irq
=
{
IRQ_MSRXINT
,
IRQ_MSTXINT
{
.
offset
=
0x0800
,
.
skpcr_mask
=
SKPCR_SCLKEN
,
.
devid
=
SA1111_DEVID_SSP
,
},
};
static
struct
sa1111_dev
int_dev
=
{
.
skpcr_mask
=
0
,
.
devid
=
SA1111_DEVID_INT
,
};
static
struct
sa1111_dev
pcmcia_dev
=
{
.
skpcr_mask
=
0
,
.
devid
=
SA1111_DEVID_PCMCIA
,
.
irq
=
{
IRQ_S0_READY_NINT
,
IRQ_S0_CD_VALID
,
IRQ_S0_BVD1_STSCHG
,
IRQ_S1_READY_NINT
,
IRQ_S1_CD_VALID
,
IRQ_S1_BVD1_STSCHG
,
{
.
offset
=
SA1111_KBD
,
.
skpcr_mask
=
SKPCR_PTCLKEN
,
.
devid
=
SA1111_DEVID_PS2
,
.
irq
=
{
IRQ_TPRXINT
,
IRQ_TPTXINT
},
},
{
.
offset
=
SA1111_MSE
,
.
skpcr_mask
=
SKPCR_PMCLKEN
,
.
devid
=
SA1111_DEVID_PS2
,
.
irq
=
{
IRQ_MSRXINT
,
IRQ_MSTXINT
},
},
{
.
offset
=
0x1800
,
.
skpcr_mask
=
0
,
.
devid
=
SA1111_DEVID_PCMCIA
,
.
irq
=
{
IRQ_S0_READY_NINT
,
IRQ_S0_CD_VALID
,
IRQ_S0_BVD1_STSCHG
,
IRQ_S1_READY_NINT
,
IRQ_S1_CD_VALID
,
IRQ_S1_BVD1_STSCHG
,
},
},
};
static
struct
sa1111_dev
*
devs
[]
=
{
&
usb_dev
,
&
sac_dev
,
&
ssp_dev
,
&
kbd_dev
,
&
mse_dev
,
&
pcmcia_dev
,
};
static
unsigned
int
dev_offset
[]
=
{
SA1111_USB
,
0x0600
,
0x0800
,
SA1111_KBD
,
SA1111_MSE
,
0x1800
,
};
/*
...
...
@@ -372,44 +359,45 @@ static struct irqchip sa1111_high_chip = {
.
wake
=
sa1111_wake_highirq
,
};
static
void
__init
sa1111_init_irq
(
struct
sa1111_dev
*
sadev
)
static
void
sa1111_setup_irq
(
struct
sa1111
*
sachip
)
{
void
*
irqbase
=
sachip
->
base
+
SA1111_INTC
;
unsigned
int
irq
;
/*
* We're guaranteed that this region hasn't been taken.
*/
request_mem_region
(
sa
dev
->
res
.
start
,
512
,
"irqs
"
);
request_mem_region
(
sa
chip
->
phys
+
SA1111_INTC
,
512
,
"irq
"
);
/* disable all IRQs */
sa1111_writel
(
0
,
sadev
->
map
base
+
SA1111_INTEN0
);
sa1111_writel
(
0
,
sadev
->
map
base
+
SA1111_INTEN1
);
sa1111_writel
(
0
,
sadev
->
map
base
+
SA1111_WAKEEN0
);
sa1111_writel
(
0
,
sadev
->
map
base
+
SA1111_WAKEEN1
);
sa1111_writel
(
0
,
irq
base
+
SA1111_INTEN0
);
sa1111_writel
(
0
,
irq
base
+
SA1111_INTEN1
);
sa1111_writel
(
0
,
irq
base
+
SA1111_WAKEEN0
);
sa1111_writel
(
0
,
irq
base
+
SA1111_WAKEEN1
);
/*
* detect on rising edge. Note: Feb 2001 Errata for SA1111
* specifies that S0ReadyInt and S1ReadyInt should be '1'.
*/
sa1111_writel
(
0
,
sadev
->
map
base
+
SA1111_INTPOL0
);
sa1111_writel
(
0
,
irq
base
+
SA1111_INTPOL0
);
sa1111_writel
(
SA1111_IRQMASK_HI
(
IRQ_S0_READY_NINT
)
|
SA1111_IRQMASK_HI
(
IRQ_S1_READY_NINT
),
sadev
->
map
base
+
SA1111_INTPOL1
);
irq
base
+
SA1111_INTPOL1
);
/* clear all IRQs */
sa1111_writel
(
~
0
,
sadev
->
map
base
+
SA1111_INTSTATCLR0
);
sa1111_writel
(
~
0
,
sadev
->
map
base
+
SA1111_INTSTATCLR1
);
sa1111_writel
(
~
0
,
irq
base
+
SA1111_INTSTATCLR0
);
sa1111_writel
(
~
0
,
irq
base
+
SA1111_INTSTATCLR1
);
for
(
irq
=
IRQ_GPAIN0
;
irq
<=
SSPROR
;
irq
++
)
{
set_irq_chip
(
irq
,
&
sa1111_low_chip
);
set_irq_chipdata
(
irq
,
sadev
->
map
base
);
set_irq_chipdata
(
irq
,
irq
base
);
set_irq_handler
(
irq
,
do_edge_IRQ
);
set_irq_flags
(
irq
,
IRQF_VALID
|
IRQF_PROBE
);
}
for
(
irq
=
AUDXMTDMADONEA
;
irq
<=
IRQ_S1_BVD1_STSCHG
;
irq
++
)
{
set_irq_chip
(
irq
,
&
sa1111_high_chip
);
set_irq_chipdata
(
irq
,
sadev
->
map
base
);
set_irq_chipdata
(
irq
,
irq
base
);
set_irq_handler
(
irq
,
do_edge_IRQ
);
set_irq_flags
(
irq
,
IRQF_VALID
|
IRQF_PROBE
);
}
...
...
@@ -417,9 +405,9 @@ static void __init sa1111_init_irq(struct sa1111_dev *sadev)
/*
* Register SA1111 interrupt
*/
set_irq_type
(
sa
dev
->
irq
[
0
]
,
IRQT_RISING
);
set_irq_data
(
sa
dev
->
irq
[
0
],
sadev
->
map
base
);
set_irq_chained_handler
(
sa
dev
->
irq
[
0
]
,
sa1111_irq_handler
);
set_irq_type
(
sa
chip
->
irq
,
IRQT_RISING
);
set_irq_data
(
sa
chip
->
irq
,
irq
base
);
set_irq_chained_handler
(
sa
chip
->
irq
,
sa1111_irq_handler
);
}
/*
...
...
@@ -529,37 +517,64 @@ sa1111_configure_smc(struct sa1111 *sachip, int sdram, unsigned int drac,
#endif
static
void
static
void
sa1111_dev_release
(
struct
device
*
_dev
)
{
struct
sa1111_dev
*
dev
=
SA1111_DEV
(
_dev
);
release_resource
(
&
dev
->
res
);
kfree
(
dev
);
}
static
int
sa1111_init_one_child
(
struct
sa1111
*
sachip
,
struct
resource
*
parent
,
struct
sa1111_dev
*
sadev
,
unsigned
int
offset
)
struct
sa1111_dev
_info
*
info
)
{
snprintf
(
sadev
->
dev
.
bus_id
,
sizeof
(
sadev
->
dev
.
bus_id
),
"%4.4x"
,
offset
);
struct
sa1111_dev
*
dev
;
int
ret
;
dev
=
kmalloc
(
sizeof
(
struct
sa1111_dev
),
GFP_KERNEL
);
if
(
!
dev
)
{
ret
=
-
ENOMEM
;
goto
out
;
}
memset
(
dev
,
0
,
sizeof
(
struct
sa1111_dev
));
snprintf
(
dev
->
dev
.
bus_id
,
sizeof
(
dev
->
dev
.
bus_id
),
"%4.4lx"
,
info
->
offset
);
/*
* If the parent device has a DMA mask associated with it,
* propagate it down to the children.
*/
if
(
sachip
->
dev
->
dma_mask
)
{
sa
dev
->
dma_mask
=
*
sachip
->
dev
->
dma_mask
;
sadev
->
dev
.
dma_mask
=
&
sa
dev
->
dma_mask
;
dev
->
dma_mask
=
*
sachip
->
dev
->
dma_mask
;
dev
->
dev
.
dma_mask
=
&
dev
->
dma_mask
;
}
sadev
->
dev
.
parent
=
sachip
->
dev
;
sadev
->
dev
.
bus
=
&
sa1111_bus_type
;
sadev
->
res
.
start
=
sachip
->
phys
+
offset
;
sadev
->
res
.
end
=
sadev
->
res
.
start
+
511
;
sadev
->
res
.
name
=
sadev
->
dev
.
bus_id
;
sadev
->
res
.
flags
=
IORESOURCE_MEM
;
sadev
->
mapbase
=
sachip
->
base
+
offset
;
if
(
request_resource
(
parent
,
&
sadev
->
res
))
{
dev
->
devid
=
info
->
devid
;
dev
->
dev
.
parent
=
sachip
->
dev
;
dev
->
dev
.
bus
=
&
sa1111_bus_type
;
dev
->
dev
.
release
=
sa1111_dev_release
;
dev
->
res
.
start
=
sachip
->
phys
+
info
->
offset
;
dev
->
res
.
end
=
dev
->
res
.
start
+
511
;
dev
->
res
.
name
=
dev
->
dev
.
bus_id
;
dev
->
res
.
flags
=
IORESOURCE_MEM
;
dev
->
mapbase
=
sachip
->
base
+
info
->
offset
;
ret
=
request_resource
(
parent
,
&
dev
->
res
);
if
(
ret
)
{
printk
(
"SA1111: failed to allocate resource for %s
\n
"
,
sa
dev
->
res
.
name
);
return
;
dev
->
res
.
name
);
goto
out
;
}
device_register
(
&
sadev
->
dev
);
ret
=
device_register
(
&
dev
->
dev
);
if
(
ret
)
{
release_resource
(
&
dev
->
res
);
out:
kfree
(
dev
);
}
return
ret
;
}
/**
...
...
@@ -655,11 +670,8 @@ __sa1111_probe(struct device *me, struct resource *mem, int irq)
* The interrupt controller must be initialised before any
* other device to ensure that the interrupts are available.
*/
if
(
irq
!=
NO_IRQ
)
{
int_dev
.
irq
[
0
]
=
irq
;
sa1111_init_one_child
(
sachip
,
mem
,
&
int_dev
,
SA1111_INTC
);
sa1111_init_irq
(
&
int_dev
);
}
if
(
sachip
->
irq
!=
NO_IRQ
)
sa1111_setup_irq
(
sachip
);
g_sa1111
=
sachip
;
...
...
@@ -670,9 +682,9 @@ __sa1111_probe(struct device *me, struct resource *mem, int irq)
else
has_devs
&=
~
(
1
<<
1
);
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
dev
s
);
i
++
)
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
sa1111_device
s
);
i
++
)
if
(
has_devs
&
(
1
<<
i
))
sa1111_init_one_child
(
sachip
,
mem
,
devs
[
i
],
dev_offset
[
i
]);
sa1111_init_one_child
(
sachip
,
mem
,
&
sa1111_devices
[
i
]);
return
0
;
...
...
@@ -685,11 +697,26 @@ __sa1111_probe(struct device *me, struct resource *mem, int irq)
static
void
__sa1111_remove
(
struct
sa1111
*
sachip
)
{
int
i
;
struct
list_head
*
l
,
*
n
;
void
*
irqbase
=
sachip
->
base
+
SA1111_INTC
;
list_for_each_safe
(
l
,
n
,
&
sachip
->
dev
->
children
)
{
struct
device
*
d
=
list_to_dev
(
l
);
device_unregister
(
d
);
}
/* disable all IRQs */
sa1111_writel
(
0
,
irqbase
+
SA1111_INTEN0
);
sa1111_writel
(
0
,
irqbase
+
SA1111_INTEN1
);
sa1111_writel
(
0
,
irqbase
+
SA1111_WAKEEN0
);
sa1111_writel
(
0
,
irqbase
+
SA1111_WAKEEN1
);
if
(
sachip
->
irq
!=
NO_IRQ
)
{
set_irq_chained_handler
(
sachip
->
irq
,
NULL
);
set_irq_data
(
sachip
->
irq
,
NULL
);
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
devs
);
i
++
)
{
put_device
(
&
devs
[
i
]
->
dev
);
release_resource
(
&
devs
[
i
]
->
res
);
release_mem_region
(
sachip
->
phys
+
SA1111_INTC
,
512
);
}
iounmap
(
sachip
->
base
);
...
...
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