Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
linux-elphel
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Commits
Open sidebar
Elphel
linux-elphel
Commits
f6ed5ab4
Commit
f6ed5ab4
authored
Mar 16, 2016
by
Oleg Dzhimiev
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
for cleanup
parent
ac0f3775
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
150 additions
and
56 deletions
+150
-56
elphel393-init.c
src/drivers/elphel/elphel393-init.c
+150
-56
No files found.
src/drivers/elphel/elphel393-init.c
View file @
f6ed5ab4
...
@@ -29,11 +29,13 @@
...
@@ -29,11 +29,13 @@
#include <asm/page.h>
#include <asm/page.h>
#include <linux/init.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/module.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/mtd.h>
#include <linux/of.h>
#include <linux/of.h>
#include <linux/of_fdt.h>
#include <linux/of_fdt.h>
#include <linux/of_net.h>
#include <linux/platform_device.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/string.h>
...
@@ -46,6 +48,8 @@
...
@@ -46,6 +48,8 @@
#define SYSFS_READONLY 0444
#define SYSFS_READONLY 0444
#define SYSFS_WRITEONLY 0222
#define SYSFS_WRITEONLY 0222
#define xemacps_write(base, reg, val) writel_relaxed((val), ((void __iomem *)(base)) + (reg))
/*
/*
* Read and parse bootargs parameter in the device tree
* Read and parse bootargs parameter in the device tree
* This driver is run in the last place - at least after NAND driver is probed
* This driver is run in the last place - at least after NAND driver is probed
...
@@ -100,13 +104,51 @@ static ssize_t get_serial(struct device *dev, struct device_attribute *attr, cha
...
@@ -100,13 +104,51 @@ static ssize_t get_serial(struct device *dev, struct device_attribute *attr, cha
return
sprintf
(
buf
,
"%s
\n
"
,
serial
);
return
sprintf
(
buf
,
"%s
\n
"
,
serial
);
}
}
static
int
get_factory_info
(
void
);
static
ssize_t
set_boardinfo
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
const
char
*
buf
,
size_t
count
)
static
ssize_t
set_boardinfo
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
const
char
*
buf
,
size_t
count
)
{
{
pr_info
(
"write board info
\n
"
);
int
ret
;
if
(
!
boardinfo
){
loff_t
pos
=
0
;
//second page
pr_info
(
"Boardinfo is empty, let's proceed
\n
"
);
loff_t
*
ppos
=&
pos
;
size_t
retlen
;
char
wbuf
[
2048
];
memset
(
wbuf
,
0xff
,
2048
);
if
(
!
mtd
){
pr_err
(
"Get MTD device error
\n
"
);
return
mtd
;
}
//too much of a trouble to read from flash again
if
(
!
strnstr
(
boardinfo
,
"<board>"
,
sizeof
(
boardinfo
))){
pr_info
(
"Factory Info record is clean.
\n
"
);
pr_info
(
"Data to be written: %s"
,
buf
);
// I got some buf, unknown size- should be limited to 2048? ok
if
(
strlen
(
buf
)
>
2048
)
{
pr_err
(
"Data > 2KiB. Abort.
\n
"
);
return
-
1
;
}
// Not too strict check, just look for opening tags.
if
(
!
strnstr
(
buf
,
"<board>"
,
2048
)
||!
strnstr
(
buf
,
"<serial>"
,
2048
)
||!
strnstr
(
buf
,
"<rev>"
,
2048
)){
pr_err
(
"Bad data format
\n
"
);
return
-
2
;
}
//tmp disabled.
//ret = mtd_write_user_prot_reg(mtd, *ppos+4*2048, 2048, &retlen, buf);
//copy to buf
strncpy
(
wbuf
,
buf
,
strlen
(
buf
));
pr_info
(
"BUFFER: %s
\n
"
,
wbuf
);
ret
=
mtd_write_user_prot_reg
(
mtd
,
*
ppos
+
4
*
2048
,
2048
,
&
retlen
,
wbuf
);
if
(
ret
){
pr_err
(
"Flash page write, code %d"
,
ret
);
return
ret
;
}
pr_info
(
"Data is successfully written and cannot be overwritten anymore, record size: %d B
\n
"
,
strlen
(
wbuf
));
get_factory_info
();
}
else
{
}
else
{
pr_info
(
"
Boardinfo is there, do nothing
\n
"
);
pr_info
(
"
Factory Info record (serial='%s' revision='%s') can not be overwritten
\n
"
,
serial
,
revision
);
}
}
return
count
;
return
count
;
}
}
...
@@ -150,20 +192,15 @@ static int elphel393_init_probe(struct platform_device *pdev)
...
@@ -150,20 +192,15 @@ static int elphel393_init_probe(struct platform_device *pdev)
char
*
value
;
char
*
value
;
//mtd device number to unlock
//mtd device number to unlock
u8
devnum
=
-
1
;
u8
devnum
=
0
;
u8
unlock
=
0
;
u8
unlock
=
0
;
size_t
retlen
;
/*
//size of nand flash page
const u8 *mac_address;
char
kbuf
[
2048
];
u16 hwaddrh;
int
page_limit
=
3
;
u32 hwaddrl;
size_t
count
;
struct device_node *node;
size_t
size
;
*/
int
len
;
loff_t
*
ppos
;
loff_t
pos
;
int
ret
;
char
*
ps
,
*
pe
;
pr_debug
(
"Probing"
);
pr_debug
(
"Probing"
);
//copy bootargs string
//copy bootargs string
...
@@ -195,19 +232,17 @@ static int elphel393_init_probe(struct platform_device *pdev)
...
@@ -195,19 +232,17 @@ static int elphel393_init_probe(struct platform_device *pdev)
// unlock /dev/mtdN partition
// unlock /dev/mtdN partition
// if there's no need to unlock, get /dev/mtd0
// if there's no need to unlock, get /dev/mtd0
if
(
unlock
&&
(
devnum
>=
0
)
){
if
(
devnum
>=
0
){
mtd
=
get_mtd_device
(
NULL
,
devnum
);
mtd
=
get_mtd_device
(
NULL
,
devnum
);
mtd_unlock
(
mtd
,
0
,
mtd
->
size
);
if
(
!
mtd
){
pr_info
(
"/dev/mtd%d: unlocked"
,
devnum
);
pr_err
(
"Get MTD device error
\n
"
);
}
else
{
return
mtd
;
mtd
=
get_mtd_device
(
NULL
,
0
);
}
}
if
(
unlock
){
mtd_unlock
(
mtd
,
0
,
mtd
->
size
);
if
(
!
mtd
){
pr_info
(
"/dev/mtd%d: unlocked"
,
devnum
);
pr_err
(
"Get mtd device error
\n
"
);
}
return
mtd
;
}
}
// read boardinfo record
// read boardinfo record
// * device number is not important
// * device number is not important
// * no need to unlock
// * no need to unlock
...
@@ -215,40 +250,99 @@ static int elphel393_init_probe(struct platform_device *pdev)
...
@@ -215,40 +250,99 @@ static int elphel393_init_probe(struct platform_device *pdev)
// page size
// page size
BUG_ON
(
mtd
->
writesize
>
2048
);
BUG_ON
(
mtd
->
writesize
>
2048
);
size
=
mtd
->
writesize
;
/*
// search within page_limit pages area
node = of_find_node_by_name(NULL, "ps7_ethernet_0");
count
=
page_limit
*
(
mtd
->
writesize
);
if (!node){
// starting offset
pr_err("Device tree node 'ps7_ethernet_0' not found.");
pos
=
0
;
return -ENODEV;
ppos
=
&
pos
;
while
(
count
){
len
=
min_t
(
size_t
,
count
,
size
);
ret
=
mtd_read_user_prot_reg
(
mtd
,
*
ppos
,
len
,
&
retlen
,
kbuf
);
if
(
ret
){
pr_err
(
"flash page read, code %d"
,
ret
);
}
// do whatever we like with the kbuf
// search for "<board>"
// expecting to find it somewhere...
if
(
strnstr
(
kbuf
,
"<board>"
,
size
)){
//...right in the beginning or error
ps
=
strnstr
(
kbuf
,
"<serial>"
,
size
);
pe
=
strnstr
(
kbuf
,
"</serial>"
,
size
);
strncpy
(
serial
,
ps
+
sizeof
(
"<serial>"
)
-
1
,
pe
-
ps
-
(
sizeof
(
"<serial>"
)
-
1
));
ps
=
strnstr
(
kbuf
,
"<rev>"
,
size
);
pe
=
strnstr
(
kbuf
,
"</rev>"
,
size
);
strncpy
(
revision
,
ps
+
sizeof
(
"<rev>"
)
-
1
,
pe
-
ps
-
(
sizeof
(
"<rev>"
)
-
1
));
strncpy
(
boardinfo
,
kbuf
,
retlen
);
break
;
}
*
ppos
+=
retlen
;
count
-=
retlen
;
}
}
mac_address = of_get_mac_address(node);
hwaddrl = cpu_to_le32(*((u32 *)mac_address));
hwaddrh = cpu_to_le16(*((u16 *)(mac_address + 4)));
pr_info("MY_MAC_FROM_DT: 0x%08x, 0x%08x, %02x:%02x:%02x:%02x:%02x:%02x\n",
hwaddrl, hwaddrh,
(hwaddrl & 0xff), ((hwaddrl >> 8) & 0xff),
((hwaddrl >> 16) & 0xff), (hwaddrl >> 24),
(hwaddrh & 0xff), (hwaddrh >> 8));
*/
get_factory_info
();
elphel393_init_sysfs_register
(
pdev
);
elphel393_init_sysfs_register
(
pdev
);
return
0
;
return
0
;
}
}
static
int
get_factory_info
(
void
){
char
regvalh
[
5
];
char
regvall
[
9
];
u16
hwaddrh
;
u32
hwaddrl
;
size_t
retlen
;
//size of nand flash page
char
kbuf
[
2048
];
size_t
size
=
mtd
->
writesize
;
loff_t
pos
=
0
;
loff_t
*
ppos
=&
pos
;
int
ret
;
char
*
ps
,
*
pe
;
const
u8
*
mac_address
;
// I expected to have null terminated strings
// but cannot get it from the declaration. Don't know.
memset
(
regvalh
,
0x00
,
5
);
memset
(
regvall
,
0x00
,
9
);
pr_info
(
"reading back: 0x%08x 0x%08x
\n
"
,
readl
(
0xE000B08C
),
readl
(
0xE000B088
));
ret
=
mtd_read_user_prot_reg
(
mtd
,
*
ppos
+
4
*
2048
,
size
,
&
retlen
,
kbuf
);
if
(
ret
){
pr_err
(
"Flash page read, code %d"
,
ret
);
return
ret
;
}
// do whatever we like with the kbuf
// search for "<board>"
// expecting to find it somewhere...
if
(
strnstr
(
kbuf
,
"<board>"
,
size
)){
//...right in the beginning or error
ps
=
strnstr
(
kbuf
,
"<serial>"
,
size
);
pe
=
strnstr
(
kbuf
,
"</serial>"
,
size
);
strncpy
(
serial
,
ps
+
sizeof
(
"<serial>"
)
-
1
,
pe
-
ps
-
(
sizeof
(
"<serial>"
)
-
1
));
strncpy
(
regvalh
,
serial
,
4
);
strncpy
(
regvall
,
serial
+
4
,
8
);
//there is kstrtou64 but it doesn't work?
kstrtou16
(
regvalh
,
16
,
&
hwaddrh
);
kstrtou32
(
regvall
,
16
,
&
hwaddrl
);
//xemacps_write(0xE000B000,0x88,hwaddrl);
//xemacps_write(0xE000B000,0x8C,hwaddrh);
//get mac address from device tree
writel
(
hwaddrl
,
0xE000B088
);
writel
(
hwaddrh
,
0xE000B08C
);
pr_info
(
"Wrote to hwaddr reg: 0x%08x 0x%08x
\n
"
,
hwaddrh
,
hwaddrl
);
pr_info
(
"read back: 0x%08x 0x%08x
\n
"
,
readl
(
0xE000B08C
),
readl
(
0xE000B088
));
//write hwaddr to zynq reg
//kstrtou16(serial,16,®valh);
//serial
ps
=
strnstr
(
kbuf
,
"<rev>"
,
size
);
pe
=
strnstr
(
kbuf
,
"</rev>"
,
size
);
strncpy
(
revision
,
ps
+
sizeof
(
"<rev>"
)
-
1
,
pe
-
ps
-
(
sizeof
(
"<rev>"
)
-
1
));
ps
=
strnstr
(
kbuf
,
"<board>"
,
size
);
pe
=
strnstr
(
kbuf
,
"</board>"
,
size
);
strncpy
(
boardinfo
,
ps
,
pe
-
ps
+
(
sizeof
(
"</board>"
)
-
1
));
}
return
0
;
}
static
int
elphel393_init_remove
(
struct
platform_device
*
pdev
)
static
int
elphel393_init_remove
(
struct
platform_device
*
pdev
)
{
{
pr_info
(
"Remove"
);
pr_info
(
"Remove"
);
...
...
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