9
0
Fork 0

svn_rev_121

implement device parameters
This commit is contained in:
Sascha Hauer 2007-07-05 18:01:25 +02:00 committed by Sascha Hauer
parent 55ebf67d3e
commit a0b0cfc5ed
11 changed files with 361 additions and 58 deletions

View File

@ -704,11 +704,6 @@ int do_mem_crc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
}
#endif /* CONFIG_CRC32_VERIFY */
int mem_probe(struct device_d *dev)
{
return 0;
}
static void memcpy_sz(void *_dst, void *_src, ulong count, ulong rwsize)
{
ulong dst = (ulong)_dst;
@ -759,14 +754,14 @@ struct device_d mem_dev = {
struct driver_d mem_drv = {
.name = "mem",
.probe = mem_probe,
.probe = dummy_probe,
.read = mem_read,
.write = mem_write,
};
struct driver_d ram_drv = {
.name = "ram",
.probe = mem_probe,
.probe = dummy_probe,
.read = mem_read,
.write = mem_write,
};

View File

@ -23,9 +23,9 @@
#include <common.h>
#if defined (CONFIG_IMX)
#include <asm/arch/imx-regs.h>
#include <init.h>
#include <driver.h>
/* ------------------------------------------------------------------------- */
/* NOTE: This describes the proper use of this file.
@ -70,15 +70,12 @@ ulong get_FCLK(void)
return (( CSCR>>15)&1) ? get_mcuPLLCLK()>>1 : get_mcuPLLCLK();
}
/* return HCLK frequency */
ulong get_HCLK(void)
{
u32 bclkdiv = (( CSCR >> 10 ) & 0xf) + 1;
printf("bclkdiv: %d\n", bclkdiv);
return get_systemPLLCLK() / bclkdiv;
}
/* return BCLK frequency */
ulong get_BCLK(void)
{
return get_HCLK();
@ -99,4 +96,93 @@ ulong get_PERCLK3(void)
return get_systemPLLCLK() / (((PCDR>>16) & 0x7f)+1);
}
#endif /* defined (CONFIG_IMX) */
typedef enum imx_cookies {
PARAM_SYSCLOCK,
PARAM_PERCLK1,
PARAM_PERCLK2,
PARAM_PERCLK3,
PARAM_BCLK,
PARAM_HCLK,
PARAM_FCLK,
PARAM_CPUCLK,
PARAM_ARCH_NUMBER,
PARAM_LAST,
} imx_cookies_t;
char *clk_get(struct device_d* dev, ulong cookie)
{
ulong clock = 0;
static char buf[11];
switch (cookie) {
case PARAM_SYSCLOCK:
clock = get_systemPLLCLK();
break;
case PARAM_PERCLK1:
clock = get_PERCLK1();
break;
case PARAM_PERCLK2:
clock = get_PERCLK2();
break;
case PARAM_PERCLK3:
clock = get_PERCLK3();
break;
case PARAM_BCLK:
clock = get_BCLK();
break;
case PARAM_HCLK:
clock = get_HCLK();
break;
case PARAM_FCLK:
clock = get_FCLK();
break;
case PARAM_CPUCLK:
clock = get_mcuPLLCLK();
break;
}
sprintf(buf, "%ld",clock);
return buf;
}
static int arch_number = CONFIG_ARCH_NUMBER;
static char *arch_number_get(struct device_d* dev, ulong cookie)
{
static char buf[5];
sprintf(buf, "%d", arch_number);
return buf;
}
static int arch_number_set(struct device_d* dev, ulong cookie, char *newval)
{
arch_number = simple_strtoul(newval, NULL, 10);
return 0;
}
static struct param_d imx_params[] = {
{ .name = "imx_system_clk", .cookie = PARAM_SYSCLOCK, .get = clk_get},
{ .name = "imx_perclk1", .cookie = PARAM_PERCLK1, .get = clk_get},
{ .name = "imx_perclk2", .cookie = PARAM_PERCLK2, .get = clk_get},
{ .name = "imx_perclk3", .cookie = PARAM_PERCLK3, .get = clk_get},
{ .name = "imx_bclk", .cookie = PARAM_BCLK, .get = clk_get},
{ .name = "imx_hclk", .cookie = PARAM_HCLK, .get = clk_get},
{ .name = "imx_fclk", .cookie = PARAM_FCLK, .get = clk_get},
{ .name = "imx_cpuclk", .cookie = PARAM_CPUCLK, .get = clk_get},
{ .name = "arch_number", .cookie = PARAM_CPUCLK, .get = arch_number_get, .set = arch_number_set},
};
static int imx_clk_init(void)
{
int i;
for (i = 0; i < PARAM_LAST; i++)
global_add_parameter(&imx_params[i]);
return 0;
}
device_initcall(imx_clk_init);

View File

@ -38,8 +38,6 @@
typedef struct bd_info {
int bi_baudrate; /* serial console baudrate */
// unsigned long bi_ip_addr; /* IP Address */
// unsigned char bi_enetaddr[6]; /* Ethernet adress */
struct environment_s *bi_env;
ulong bi_arch_number; /* unique id for this board */
ulong bi_boot_params; /* where this board expects params */
@ -48,10 +46,6 @@ typedef struct bd_info {
ulong start;
ulong size;
} bi_dram[CONFIG_NR_DRAM_BANKS];
#ifdef CONFIG_HAS_ETH1
/* second onboard ethernet port */
unsigned char bi_enet1addr[6];
#endif
} bd_t;
#define bi_env_data bi_env->data

View File

@ -6,7 +6,13 @@
#define MAP_READ 1
#define MAP_WRITE 2
struct memarea_info;
struct param_d {
char *(*get)(struct device_d *, ulong cookie);
int (*set)(struct device_d *, ulong cookie, char *val);
char *name;
ulong cookie;
struct param_d *next;
};
#define DEVICE_TYPE_UNKNOWN 0
#define DEVICE_TYPE_ETHER 1
@ -33,6 +39,8 @@ struct device_d {
struct device_d *next;
unsigned long type;
struct param_d *param;
};
struct driver_d {
@ -48,6 +56,9 @@ struct driver_d {
void (*info) (struct device_d *);
void (*shortinfo) (struct device_d *);
struct param_d* (*get) (struct device_d*, int no);
int (*set) (struct device_d*, struct param_d *, char *val);
unsigned long type;
void *type_data;
};
@ -65,6 +76,10 @@ struct device_d *get_device_by_name(char *name);
ssize_t read(struct device_d *dev, void *buf, size_t count, ulong offset, ulong flags);
ssize_t write(struct device_d *dev, void *buf, size_t count, ulong offset, ulong flags);
ssize_t erase(struct device_d *dev, size_t count, unsigned long offset);
char *dev_get_param(struct device_d *dev, char *name);
int dev_set_param(struct device_d *dev, char *name, char *val);
int dev_add_parameter(struct device_d *dev, struct param_d *par);
ssize_t mem_read(struct device_d *dev, void *buf, size_t count, ulong offset, ulong flags);
ssize_t mem_write(struct device_d *dev, void *buf, size_t count, ulong offset, ulong flags);
@ -72,5 +87,9 @@ ssize_t mem_write(struct device_d *dev, void *buf, size_t count, ulong offset, u
int register_device_type_handler(int(*handle)(struct device_d *), ulong device_type);
//void unregister_device_type_handler(struct device_d *);
int dummy_probe(struct device_d *);
int global_add_parameter(struct param_d *param);
#endif /* DRIVER_H */

View File

@ -9,6 +9,7 @@ typedef int (*initcall_t)(void);
#define core_initcall(fn) __define_initcall("0",fn,0)
#define coredevice_initcall(fn) __define_initcall("4",fn,4)
#define device_initcall(fn) __define_initcall("5",fn,5)
#define late_initcall(fn) __define_initcall("6",fn,6)

View File

@ -108,8 +108,13 @@ struct eth_device {
struct eth_device *next;
void *priv;
char *param[4];
};
struct param_d *eth_param_get(struct device_d* dev, int no);
int eth_param_set(struct device_d* dev, struct param_d *param, char *val);
extern int eth_register(struct eth_device* dev);/* Register network device */
extern void eth_try_another(int first_restart); /* Change the device */
extern struct eth_device *eth_get_dev(void); /* get the current device MAC */

View File

@ -12,3 +12,5 @@ obj-y += vsprintf.o
obj-$(CONFIG_ZLIB) += zlib.o
obj-y += div64.o
obj-y += misc.o
obj-y += global.o

96
lib_generic/global.c Normal file
View File

@ -0,0 +1,96 @@
#include <common.h>
#include <command.h>
#include <init.h>
#include <driver.h>
#include <malloc.h>
#include <asm-generic/errno.h>
struct device_d global_dev;
int global_add_parameter(struct param_d *param)
{
return dev_add_parameter(&global_dev, param);
}
struct device_d global_dev = {
.name = "global",
.id = "env",
.map_base = 0,
.size = 0,
};
struct driver_d global_driver = {
.name = "global",
.probe = dummy_probe,
};
static int global_init(void)
{
register_device(&global_dev);
register_driver(&global_driver);
return 0;
}
coredevice_initcall(global_init);
static int do_get( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
struct device_d *dev;
char *endp, *str;
if (argc < 3) {
printf ("Usage:\n%s\n", cmdtp->usage);
return 1;
}
dev = device_from_spec_str(argv[1], &endp);
if (!dev) {
printf("no such device: %s\n", argv[1]);
return 1;
}
str = dev_get_param(dev, argv[2]);
printf("%s\n",str);
return 0;
}
U_BOOT_CMD(
get, 3, 0, do_get,
"get - get device variables\n",
"\n"
);
static int do_set( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
struct device_d *dev;
char *endp, *val;
int ret;
if (argc < 4) {
printf ("Usage:\n%s\n", cmdtp->usage);
return 1;
}
dev = device_from_spec_str(argv[1], &endp);
if (!dev) {
printf("no such device: %s\n", argv[1]);
return 1;
}
val = malloc(strlen(argv[3] + 1));
if (!val)
return -ENOMEM;
strcpy(val, argv[3]);
ret = dev_set_param(dev, argv[2], val);
if (ret)
printf("failed\n");
return ret;
}
U_BOOT_CMD(
set, 4, 0, do_set,
"set - set device variables\n",
"\n"
);

View File

@ -55,43 +55,6 @@ struct device_d *get_device_by_id(char *id)
return d;
}
int do_devinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
struct device_d *dev = first_device;
struct driver_d *drv = first_driver;
if (argc == 1) {
printf("devices:\n");
while(dev) {
printf("%10s: base=0x%08x size=0x%08x (driver %s)\n",dev->id, dev->map_base, dev->size, dev->name);
dev = dev->next;
}
printf("drivers:\n");
while(drv) {
printf("%10s\n",drv->name);
drv = drv->next;
}
} else {
struct device_d *dev = get_device_by_id(argv[1]);
if (!dev) {
printf("no such device: %s\n",argv[1]);
return -1;
}
dev->driver->info(dev);
}
return 0;
}
U_BOOT_CMD(
devinfo, 2, 0, do_devinfo,
"devinfo - display info about devices and drivers\n",
""
);
static int match(struct driver_d *drv, struct device_d *dev)
{
int(*handler)(struct device_d *);
@ -397,3 +360,106 @@ ssize_t erase(struct device_d *dev, size_t count, unsigned long offset)
return -1;
}
int dummy_probe(struct device_d *dev)
{
return 0;
}
static struct param_d *get_param_by_name(struct device_d *dev, char *name)
{
struct param_d *param = dev->param;
while (param) {
if (!strcmp(param->name, name))
return param;
param = param->next;
}
return NULL;
}
char *dev_get_param(struct device_d *dev, char *name)
{
struct param_d *param = get_param_by_name(dev, name);
if (param && param->get)
return param->get(dev, param->cookie);
return NULL;
}
int dev_set_param(struct device_d *dev, char *name, char *val)
{
struct param_d *param = get_param_by_name(dev, name);
if (param && param->set)
return param->set(dev, param->cookie, val);
return -1;
}
int dev_add_parameter(struct device_d *dev, struct param_d *newparam)
{
struct param_d *param = dev->param;
newparam->next = 0;
if (param) {
while (param->next)
param = param->next;
param->next = newparam;
} else {
dev->param = newparam;
}
return 0;
}
int do_devinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
struct device_d *dev = first_device;
struct driver_d *drv = first_driver;
struct param_d *param;
if (argc == 1) {
printf("devices:\n");
while(dev) {
printf("%10s: base=0x%08x size=0x%08x (driver %s)\n",dev->id, dev->map_base, dev->size, dev->name);
dev = dev->next;
}
printf("drivers:\n");
while(drv) {
printf("%10s\n",drv->name);
drv = drv->next;
}
} else {
struct device_d *dev = get_device_by_id(argv[1]);
if (!dev) {
printf("no such device: %s\n",argv[1]);
return -1;
}
dev->driver->info(dev);
param = dev->param;
printf("%s\n", param ? "Parameters:" : "no parameters available");
while (param) {
printf("%16s = %s\n", param->name, param->get(dev, param->cookie));
param = param->next;
}
}
return 0;
}
U_BOOT_CMD(
devinfo, 2, 0, do_devinfo,
"devinfo - display info about devices and drivers\n",
""
);

View File

@ -27,6 +27,43 @@
#include <init.h>
#include <net.h>
#include <miiphy.h>
#include <malloc.h>
typedef enum eth_cookies {
PARAM_IP,
PARAM_MAC,
PARAM_GW,
PARAM_NM,
} eth_cookies_t;
static char *eth_get(struct device_d* dev, ulong cookie)
{
struct eth_device *ndev = dev->driver->type_data;
if (cookie >= 4)
return 0;
return ndev->param[cookie];
}
static int eth_set(struct device_d* dev, ulong cookie, char *newval)
{
struct eth_device *ndev = dev->driver->type_data;
char **val = &ndev->param[cookie];
if (*val)
free(*val);
*val = newval;
return 0;
}
static struct param_d eth_params[] = {
{ .name = "ip", .cookie = PARAM_IP, .set = eth_set, .get = eth_get},
{ .name = "mac", .cookie = PARAM_MAC, .set = eth_set, .get = eth_get},
{ .name = "gateway", .cookie = PARAM_GW, .set = eth_set, .get = eth_get},
{ .name = "netmask", .cookie = PARAM_NM, .set = eth_set, .get = eth_get},
};
static struct eth_device *eth_current;
@ -85,12 +122,14 @@ static int eth_handle(struct device_d *dev)
char *e = NULL;
int i;
printf("%s: %s\n",__FUNCTION__, dev->id);
if (!ndev->get_mac_address) {
printf("no get_mac_address found for current eth device\n");
return -1;
}
for (i = 0; i < 4; i++)
dev_add_parameter(dev, &eth_params[i]);
ethaddr = ndev->enetaddr;
/* Try to get a MAC address from the eeprom set 'ethaddr' to it.