Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dd5b295f authored by Jon Ringle's avatar Jon Ringle Committed by Russell King
Browse files

[ARM] 2921/1: Support for the RTC / nvram on the Comdial MP1000



Patch from Jon Ringle

This adds support for the RTC and nvram on the Comdial MP1000

Signed-off-by: Jon Ringle
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent d9e29649
Loading
Loading
Loading
Loading
+109 −1
Original line number Original line Diff line number Diff line
@@ -32,9 +32,11 @@
 * 		added changelog
 * 		added changelog
 * 	1.2	Erik Gilling: Cobalt Networks support
 * 	1.2	Erik Gilling: Cobalt Networks support
 * 		Tim Hockin: general cleanup, Cobalt support
 * 		Tim Hockin: general cleanup, Cobalt support
 * 	1.3	Jon Ringle: Comdial MP1000 support
 *
 */
 */


#define NVRAM_VERSION	"1.2"
#define NVRAM_VERSION	"1.3"


#include <linux/module.h>
#include <linux/module.h>
#include <linux/config.h>
#include <linux/config.h>
@@ -45,6 +47,7 @@
#define PC		1
#define PC		1
#define ATARI		2
#define ATARI		2
#define COBALT		3
#define COBALT		3
#define MP1000		4


/* select machine configuration */
/* select machine configuration */
#if defined(CONFIG_ATARI)
#if defined(CONFIG_ATARI)
@@ -54,6 +57,9 @@
#  if defined(CONFIG_COBALT)
#  if defined(CONFIG_COBALT)
#    include <linux/cobalt-nvram.h>
#    include <linux/cobalt-nvram.h>
#    define MACH COBALT
#    define MACH COBALT
#  elif defined(CONFIG_MACH_MP1000)
#    undef MACH
#    define MACH MP1000
#  else
#  else
#    define MACH PC
#    define MACH PC
#  endif
#  endif
@@ -112,6 +118,23 @@


#endif
#endif


#if MACH == MP1000

/* RTC in a MP1000 */
#define CHECK_DRIVER_INIT()	1

#define MP1000_CKS_RANGE_START	0
#define MP1000_CKS_RANGE_END	111
#define MP1000_CKS_LOC		112

#define NVRAM_BYTES		(128-NVRAM_FIRST_BYTE)

#define mach_check_checksum	mp1000_check_checksum
#define mach_set_checksum	mp1000_set_checksum
#define mach_proc_infos		mp1000_proc_infos

#endif

/* Note that *all* calls to CMOS_READ and CMOS_WRITE must be done with
/* Note that *all* calls to CMOS_READ and CMOS_WRITE must be done with
 * rtc_lock held. Due to the index-port/data-port design of the RTC, we
 * rtc_lock held. Due to the index-port/data-port design of the RTC, we
 * don't want two different things trying to get to it at once. (e.g. the
 * don't want two different things trying to get to it at once. (e.g. the
@@ -915,6 +938,91 @@ atari_proc_infos(unsigned char *nvram, char *buffer, int *len,


#endif /* MACH == ATARI */
#endif /* MACH == ATARI */


#if MACH == MP1000

static int
mp1000_check_checksum(void)
{
	int i;
	unsigned short sum = 0;
	unsigned short expect;

	for (i = MP1000_CKS_RANGE_START; i <= MP1000_CKS_RANGE_END; ++i)
		sum += __nvram_read_byte(i);

        expect = __nvram_read_byte(MP1000_CKS_LOC+1)<<8 |
	    __nvram_read_byte(MP1000_CKS_LOC);
	return ((sum & 0xffff) == expect);
}

static void
mp1000_set_checksum(void)
{
	int i;
	unsigned short sum = 0;

	for (i = MP1000_CKS_RANGE_START; i <= MP1000_CKS_RANGE_END; ++i)
		sum += __nvram_read_byte(i);
	__nvram_write_byte(sum >> 8, MP1000_CKS_LOC + 1);
	__nvram_write_byte(sum & 0xff, MP1000_CKS_LOC);
}

#ifdef CONFIG_PROC_FS

#define         SERVER_N_LEN         32
#define         PATH_N_LEN           32
#define         FILE_N_LEN           32
#define         NVRAM_MAGIC_SIG      0xdead

typedef struct NvRamImage
{
	unsigned short int    magic;
	unsigned short int    mode;
	char                  fname[FILE_N_LEN];
	char                  path[PATH_N_LEN];
	char                  server[SERVER_N_LEN];
	char                  pad[12];
} NvRam;

static int
mp1000_proc_infos(unsigned char *nvram, char *buffer, int *len,
    off_t *begin, off_t offset, int size)
{
	int checksum;
        NvRam* nv = (NvRam*)nvram;

	spin_lock_irq(&rtc_lock);
	checksum = __nvram_check_checksum();
	spin_unlock_irq(&rtc_lock);

	PRINT_PROC("Checksum status: %svalid\n", checksum ? "" : "not ");

        switch( nv->mode )
        {
           case 0 :
                    PRINT_PROC( "\tMode 0, tftp prompt\n" );
                    break;
           case 1 :
                    PRINT_PROC( "\tMode 1, booting from disk\n" );
                    break;
           case 2 :
                    PRINT_PROC( "\tMode 2, Alternate boot from disk /boot/%s\n", nv->fname );
                    break;
           case 3 :
                    PRINT_PROC( "\tMode 3, Booting from net:\n" );
                    PRINT_PROC( "\t\t%s:%s%s\n",nv->server, nv->path, nv->fname );
                    break;
           default:
                    PRINT_PROC( "\tInconsistant nvram?\n" );
                    break;
        }

	return 1;
}
#endif

#endif /* MACH == MP1000 */

MODULE_LICENSE("GPL");
MODULE_LICENSE("GPL");


EXPORT_SYMBOL(__nvram_read_byte);
EXPORT_SYMBOL(__nvram_read_byte);