[RFC 12/24] char/nvram: Add "devname:nvram" module alias

2015-05-30 Thread Finn Thain
Signed-off-by: Finn Thain 

---
 drivers/char/nvram.c |1 +
 1 file changed, 1 insertion(+)

Index: linux/drivers/char/nvram.c
===
--- linux.orig/drivers/char/nvram.c 2015-05-31 11:01:11.0 +1000
+++ linux/drivers/char/nvram.c  2015-05-31 11:01:13.0 +1000
@@ -575,3 +575,4 @@ module_exit(nvram_module_exit);
 
 MODULE_LICENSE("GPL");
 MODULE_ALIAS_MISCDEV(NVRAM_MINOR);
+MODULE_ALIAS("devname:nvram");


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[RFC 13/24] powerpc: Cleanup nvram includes

2015-05-30 Thread Finn Thain
The nvram_read_byte() and nvram_write_byte() definitions in asm/nvram.h
duplicate those in linux/nvram.h. Get rid of the former to prepare for
adoption of struct arch_nvram_ops (which is defined in linux/nvram.h for
general use).

Signed-off-by: Finn Thain 

---
 arch/powerpc/include/asm/nvram.h   |3 ---
 arch/powerpc/kernel/setup_32.c |1 +
 drivers/char/generic_nvram.c   |4 +++-
 drivers/video/fbdev/matrox/matroxfb_base.c |2 +-
 4 files changed, 5 insertions(+), 5 deletions(-)

Index: linux/arch/powerpc/include/asm/nvram.h
===
--- linux.orig/arch/powerpc/include/asm/nvram.h 2015-05-31 11:00:59.0 
+1000
+++ linux/arch/powerpc/include/asm/nvram.h  2015-05-31 11:01:13.0 
+1000
@@ -101,7 +101,4 @@ extern int nvram_write_os_partition(stru
 /* Determine NVRAM size */
 extern ssize_t nvram_get_size(void);
 
-/* Normal access to NVRAM */
-extern unsigned char nvram_read_byte(int i);
-extern void nvram_write_byte(unsigned char c, int i);
 #endif /* _ASM_POWERPC_NVRAM_H */
Index: linux/arch/powerpc/kernel/setup_32.c
===
--- linux.orig/arch/powerpc/kernel/setup_32.c   2015-05-31 11:00:59.0 
+1000
+++ linux/arch/powerpc/kernel/setup_32.c2015-05-31 11:01:13.0 
+1000
@@ -16,6 +16,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
Index: linux/drivers/char/generic_nvram.c
===
--- linux.orig/drivers/char/generic_nvram.c 2015-05-31 11:00:59.0 
+1000
+++ linux/drivers/char/generic_nvram.c  2015-05-31 11:01:13.0 +1000
@@ -20,9 +20,11 @@
 #include 
 #include 
 #include 
+#include 
 #include 
-#include 
+
 #ifdef CONFIG_PPC_PMAC
+#include 
 #include 
 #endif
 
Index: linux/drivers/video/fbdev/matrox/matroxfb_base.c
===
--- linux.orig/drivers/video/fbdev/matrox/matroxfb_base.c   2015-05-31 
11:00:59.0 +1000
+++ linux/drivers/video/fbdev/matrox/matroxfb_base.c2015-05-31 
11:01:13.0 +1000
@@ -111,12 +111,12 @@
 #include "matroxfb_g450.h"
 #include 
 #include 
+#include 
 #include 
 #include 
 
 #ifdef CONFIG_PPC_PMAC
 #include 
-unsigned char nvram_read_byte(int);
 static int default_vmode = VMODE_NVRAM;
 static int default_cmode = CMODE_NVRAM;
 #endif


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[RFC 05/24] char/nvram: Re-order functions to remove forward declarations and #ifdefs

2015-05-30 Thread Finn Thain
Also give functions more sensible names: nvram_misc_* for misc device ops,
nvram_proc_* for proc file ops and nvram_module_* for init and exit
functions. This makes them distict from nvram_ops members.

Signed-off-by: Finn Thain 

---
 drivers/char/nvram.c |  194 ++-
 1 file changed, 86 insertions(+), 108 deletions(-)

Index: linux/drivers/char/nvram.c
===
--- linux.orig/drivers/char/nvram.c 2015-05-31 11:01:01.0 +1000
+++ linux/drivers/char/nvram.c  2015-05-31 11:01:05.0 +1000
@@ -54,11 +54,6 @@ static int nvram_open_mode;  /* special o
 #define NVRAM_WRITE1 /* opened for writing (exclusive) */
 #define NVRAM_EXCL 2 /* opened with O_EXCL */
 
-#ifdef CONFIG_PROC_FS
-static void pc_nvram_proc_read(unsigned char *contents, struct seq_file *seq,
-   void *offset);
-#endif
-
 /*
  * These functions are provided to be called internally or by other parts of
  * the kernel. It's up to the caller to ensure correct checksum before reading
@@ -170,7 +165,7 @@ void nvram_set_checksum(void)
  * The are the file operation function for user access to /dev/nvram
  */
 
-static loff_t nvram_llseek(struct file *file, loff_t offset, int origin)
+static loff_t nvram_misc_llseek(struct file *file, loff_t offset, int origin)
 {
switch (origin) {
case 0:
@@ -189,8 +184,8 @@ static loff_t nvram_llseek(struct file *
return (offset >= 0) ? (file->f_pos = offset) : -EINVAL;
 }
 
-static ssize_t nvram_read(struct file *file, char __user *buf,
-   size_t count, loff_t *ppos)
+static ssize_t nvram_misc_read(struct file *file, char __user *buf,
+   size_t count, loff_t *ppos)
 {
unsigned char contents[NVRAM_BYTES];
unsigned i = *ppos;
@@ -218,8 +213,8 @@ checksum_err:
return -EIO;
 }
 
-static ssize_t nvram_write(struct file *file, const char __user *buf,
-   size_t count, loff_t *ppos)
+static ssize_t nvram_misc_write(struct file *file, const char __user *buf,
+size_t count, loff_t *ppos)
 {
unsigned char contents[NVRAM_BYTES];
unsigned i = *ppos;
@@ -257,8 +252,8 @@ checksum_err:
return -EIO;
 }
 
-static long nvram_ioctl(struct file *file, unsigned int cmd,
-   unsigned long arg)
+static long nvram_misc_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
 {
int i;
 
@@ -298,7 +293,7 @@ static long nvram_ioctl(struct file *fil
}
 }
 
-static int nvram_open(struct inode *inode, struct file *file)
+static int nvram_misc_open(struct inode *inode, struct file *file)
 {
spin_lock(&nvram_state_lock);
 
@@ -320,7 +315,7 @@ static int nvram_open(struct inode *inod
return 0;
 }
 
-static int nvram_release(struct inode *inode, struct file *file)
+static int nvram_misc_release(struct inode *inode, struct file *file)
 {
spin_lock(&nvram_state_lock);
 
@@ -337,100 +332,6 @@ static int nvram_release(struct inode *i
return 0;
 }
 
-#ifndef CONFIG_PROC_FS
-static int nvram_add_proc_fs(void)
-{
-   return 0;
-}
-
-#else
-
-static int nvram_proc_read(struct seq_file *seq, void *offset)
-{
-   unsigned char contents[NVRAM_BYTES];
-   int i = 0;
-
-   spin_lock_irq(&rtc_lock);
-   for (i = 0; i < NVRAM_BYTES; ++i)
-   contents[i] = __nvram_read_byte(i);
-   spin_unlock_irq(&rtc_lock);
-
-   pc_nvram_proc_read(contents, seq, offset);
-
-   return 0;
-}
-
-static int nvram_proc_open(struct inode *inode, struct file *file)
-{
-   return single_open(file, nvram_proc_read, NULL);
-}
-
-static const struct file_operations nvram_proc_fops = {
-   .owner  = THIS_MODULE,
-   .open   = nvram_proc_open,
-   .read   = seq_read,
-   .llseek = seq_lseek,
-   .release= single_release,
-};
-
-static int nvram_add_proc_fs(void)
-{
-   if (!proc_create("driver/nvram", 0, NULL, &nvram_proc_fops))
-   return -ENOMEM;
-   return 0;
-}
-
-#endif /* CONFIG_PROC_FS */
-
-static const struct file_operations nvram_fops = {
-   .owner  = THIS_MODULE,
-   .llseek = nvram_llseek,
-   .read   = nvram_read,
-   .write  = nvram_write,
-   .unlocked_ioctl = nvram_ioctl,
-   .open   = nvram_open,
-   .release= nvram_release,
-};
-
-static struct miscdevice nvram_dev = {
-   NVRAM_MINOR,
-   "nvram",
-   &nvram_fops
-};
-
-static int __init nvram_init(void)
-{
-   int ret;
-
-   ret = misc_register(&nvram_dev);
-   if (ret) {
-   printk(KERN_ERR "nvram: can't misc_register on

[RFC 04/24] m68k/atari: Replace nvram_{read, write}_byte with arch_nvram_ops

2015-05-30 Thread Finn Thain
By implementing an arch_nvram_ops struct, any platform can re-use the
drivers/char/nvram module without needing any arch-specific code
in that module. Atari does so here.

Atari has one user of nvram_check_checksum() whereas the other platforms
(i.e. x86 and ARM platforms) have none at all. Replace this
validate-checksum-and-read-byte sequence with the equivalent
rtc_nvram_ops.read() call and remove the now unused functions.

Signed-off-by: Finn Thain 

---

The advantage of the new ops struct over the old global nvram_* functions
is that the misc device module can be shared by different platforms
without requiring every platform to implement every nvram_* function.
E.g. only RTC "CMOS" NVRAMs have a checksum and only PowerPC platforms
have a "sync" ioctl.

---
 arch/m68k/atari/nvram.c   |   89 --
 drivers/scsi/atari_scsi.c |8 ++--
 include/linux/nvram.h |9 
 3 files changed, 70 insertions(+), 36 deletions(-)

Index: linux/arch/m68k/atari/nvram.c
===
--- linux.orig/arch/m68k/atari/nvram.c  2015-05-31 11:01:01.0 +1000
+++ linux/arch/m68k/atari/nvram.c   2015-05-31 11:01:03.0 +1000
@@ -38,33 +38,12 @@ unsigned char __nvram_read_byte(int i)
return CMOS_READ(NVRAM_FIRST_BYTE + i);
 }
 
-unsigned char nvram_read_byte(int i)
-{
-   unsigned long flags;
-   unsigned char c;
-
-   spin_lock_irqsave(&rtc_lock, flags);
-   c = __nvram_read_byte(i);
-   spin_unlock_irqrestore(&rtc_lock, flags);
-   return c;
-}
-EXPORT_SYMBOL(nvram_read_byte);
-
 /* This races nicely with trying to read with checksum checking */
 void __nvram_write_byte(unsigned char c, int i)
 {
CMOS_WRITE(c, NVRAM_FIRST_BYTE + i);
 }
 
-void nvram_write_byte(unsigned char c, int i)
-{
-   unsigned long flags;
-
-   spin_lock_irqsave(&rtc_lock, flags);
-   __nvram_write_byte(c, i);
-   spin_unlock_irqrestore(&rtc_lock, flags);
-}
-
 /* On Ataris, the checksum is over all bytes except the checksum bytes
  * themselves; these are at the very end.
  */
@@ -83,18 +62,6 @@ int __nvram_check_checksum(void)
   (__nvram_read_byte(ATARI_CKS_LOC + 1) == (sum & 0xff));
 }
 
-int nvram_check_checksum(void)
-{
-   unsigned long flags;
-   int rv;
-
-   spin_lock_irqsave(&rtc_lock, flags);
-   rv = __nvram_check_checksum();
-   spin_unlock_irqrestore(&rtc_lock, flags);
-   return rv;
-}
-EXPORT_SYMBOL(nvram_check_checksum);
-
 static void __nvram_set_checksum(void)
 {
int i;
@@ -106,6 +73,62 @@ static void __nvram_set_checksum(void)
__nvram_write_byte(sum, ATARI_CKS_LOC + 1);
 }
 
+static ssize_t nvram_read(char *buf, size_t count, loff_t *ppos)
+{
+   char *p = buf;
+   loff_t i;
+
+   spin_lock_irq(&rtc_lock);
+
+   if (!__nvram_check_checksum()) {
+   spin_unlock_irq(&rtc_lock);
+   return -EIO;
+   }
+
+   for (i = *ppos; count > 0 && i < NVRAM_BYTES; --count, ++i, ++p)
+   *p = __nvram_read_byte(i);
+
+   spin_unlock_irq(&rtc_lock);
+
+   *ppos = i;
+   return p - buf;
+}
+
+static ssize_t nvram_write(char *buf, size_t count, loff_t *ppos)
+{
+   char *p = buf;
+   loff_t i;
+
+   spin_lock_irq(&rtc_lock);
+
+   if (!__nvram_check_checksum()) {
+   spin_unlock_irq(&rtc_lock);
+   return -EIO;
+   }
+
+   for (i = *ppos; count > 0 && i < NVRAM_BYTES; --count, ++i, ++p)
+   __nvram_write_byte(*p, i);
+
+   __nvram_set_checksum();
+
+   spin_unlock_irq(&rtc_lock);
+
+   *ppos = i;
+   return p - buf;
+}
+
+static ssize_t nvram_get_size(void)
+{
+   return NVRAM_BYTES;
+}
+
+const struct nvram_ops arch_nvram_ops = {
+   .read   = nvram_read,
+   .write  = nvram_write,
+   .get_size   = nvram_get_size,
+};
+EXPORT_SYMBOL(arch_nvram_ops);
+
 #ifdef CONFIG_PROC_FS
 static struct {
unsigned char val;
Index: linux/drivers/scsi/atari_scsi.c
===
--- linux.orig/drivers/scsi/atari_scsi.c2015-05-31 11:01:00.0 
+1000
+++ linux/drivers/scsi/atari_scsi.c 2015-05-31 11:01:03.0 +1000
@@ -880,13 +880,15 @@ static int __init atari_scsi_probe(struc
 #ifdef CONFIG_NVRAM
else
/* Test if a host id is set in the NVRam */
-   if (ATARIHW_PRESENT(TT_CLK) && nvram_check_checksum()) {
-   unsigned char b = nvram_read_byte(14);
+   if (ATARIHW_PRESENT(TT_CLK)) {
+   unsigned char b;
+   loff_t offset = 14;
+   ssize_t count = arch_nvram_ops.read(&b, 1, &offset);
 
/* Arbitration enabled? (for TOS)

[RFC 22/24] m68k/mac: Adopt nvram module

2015-05-30 Thread Finn Thain
Implement arch_nvram_ops and adjust calling conventions of mac_pram_*
functions to match the ops struct methods. Rename via_pram_readbyte and
via_pram_writebyte to avoid confusion and follow the existing
nvram_*_read_byte and nvram_*_write_byte naming convention.

Enable CONFIG_HAVE_ARCH_NVRAM_OPS on Macs.

Signed-off-by: Finn Thain 

---

The arch_nvram_ops struct can only be defined once, of course, so the
Mac and Atari ops structs are mutually exclusive. The final patch will
allow the two implementations to co-exist in a multi-platform kernel binary.

---
 arch/m68k/Kconfig|2 
 arch/m68k/mac/misc.c |  120 +++
 2 files changed, 76 insertions(+), 46 deletions(-)

Index: linux/arch/m68k/Kconfig
===
--- linux.orig/arch/m68k/Kconfig2015-05-31 11:01:11.0 +1000
+++ linux/arch/m68k/Kconfig 2015-05-31 11:01:26.0 +1000
@@ -72,7 +72,7 @@ config PGTABLE_LEVELS
default 3
 
 config HAVE_ARCH_NVRAM_OPS
-   def_bool ATARI
+   def_bool (ATARI && !MAC) || (MAC && !ATARI)
 
 source "init/Kconfig"
 
Index: linux/arch/m68k/mac/misc.c
===
--- linux.orig/arch/m68k/mac/misc.c 2015-05-31 11:00:59.0 +1000
+++ linux/arch/m68k/mac/misc.c  2015-05-31 11:01:26.0 +1000
@@ -11,6 +11,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -61,7 +62,8 @@ static void cuda_write_time(long data)
cuda_poll();
 }
 
-static __u8 cuda_read_pram(int offset)
+#if IS_ENABLED(CONFIG_NVRAM)
+static unsigned char cuda_pram_read_byte(int offset)
 {
struct adb_request req;
if (cuda_request(&req, NULL, 4, CUDA_PACKET, CUDA_GET_PRAM,
@@ -72,7 +74,7 @@ static __u8 cuda_read_pram(int offset)
return req.reply[3];
 }
 
-static void cuda_write_pram(int offset, __u8 data)
+static void cuda_pram_write_byte(unsigned char data, int offset)
 {
struct adb_request req;
if (cuda_request(&req, NULL, 5, CUDA_PACKET, CUDA_SET_PRAM,
@@ -81,11 +83,13 @@ static void cuda_write_pram(int offset,
while (!req.complete)
cuda_poll();
 }
+#endif /* CONFIG_NVRAM */
+
 #else
 #define cuda_read_time() 0
 #define cuda_write_time(n)
-#define cuda_read_pram NULL
-#define cuda_write_pram NULL
+#define cuda_pram_read_byte NULL
+#define cuda_pram_write_byte NULL
 #endif
 
 #ifdef CONFIG_ADB_PMU68K
@@ -116,7 +120,8 @@ static void pmu_write_time(long data)
pmu_poll();
 }
 
-static __u8 pmu_read_pram(int offset)
+#if IS_ENABLED(CONFIG_NVRAM)
+static unsigned char pmu_pram_read_byte(int offset)
 {
struct adb_request req;
if (pmu_request(&req, NULL, 3, PMU_READ_NVRAM,
@@ -127,7 +132,7 @@ static __u8 pmu_read_pram(int offset)
return req.reply[3];
 }
 
-static void pmu_write_pram(int offset, __u8 data)
+static void pmu_pram_write_byte(unsigned char data, int offset)
 {
struct adb_request req;
if (pmu_request(&req, NULL, 4, PMU_WRITE_NVRAM,
@@ -136,11 +141,13 @@ static void pmu_write_pram(int offset, _
while (!req.complete)
pmu_poll();
 }
+#endif /* CONFIG_NVRAM */
+
 #else
 #define pmu_read_time() 0
 #define pmu_write_time(n)
-#define pmu_read_pram NULL
-#define pmu_write_pram NULL
+#define pmu_pram_read_byte NULL
+#define pmu_pram_write_byte NULL
 #endif
 
 #if 0 /* def CONFIG_ADB_MACIISI */
@@ -169,7 +176,8 @@ static void maciisi_write_time(long data
(data >> 8) & 0xFF, data & 0xFF);
 }
 
-static __u8 maciisi_read_pram(int offset)
+#if IS_ENABLED(CONFIG_NVRAM)
+static unsigned char maciisi_pram_read_byte(int offset)
 {
struct adb_request req;
if (maciisi_request(&req, NULL, 4, CUDA_PACKET, CUDA_GET_PRAM,
@@ -178,17 +186,19 @@ static __u8 maciisi_read_pram(int offset
return req.reply[3];
 }
 
-static void maciisi_write_pram(int offset, __u8 data)
+static void maciisi_pram_write_byte(unsigned char data, int offset)
 {
struct adb_request req;
maciisi_request(&req, NULL, 5, CUDA_PACKET, CUDA_SET_PRAM,
(offset >> 8) & 0xFF, offset & 0xFF, data);
 }
+#endif /* CONFIG_NVRAM */
+
 #else
 #define maciisi_read_time() 0
 #define maciisi_write_time(n)
-#define maciisi_read_pram NULL
-#define maciisi_write_pram NULL
+#define maciisi_pram_read_byte NULL
+#define maciisi_pram_write_byte NULL
 #endif
 
 /*
@@ -198,7 +208,7 @@ static void maciisi_write_pram(int offse
  * the RTC should be enabled.
  */
 
-static __u8 via_pram_readbyte(void)
+static __u8 via_pram_recv(void)
 {
int i,reg;
__u8data;
@@ -225,7 +235,7 @@ static __u8 via_pram_readbyte(void)
return data;
 }
 
-static void via_pram_writebyte(__u8 data)
+static void via_pram_send(__u8 data)
 {
int i,reg,bit;
 
@@ -262,17 +

[RFC 23/24] m68k/mac: Fix PRAM accessors

2015-05-30 Thread Finn Thain
Signed-off-by: Finn Thain 

---

Tested on a PowerBook 520 and Quadra 650.

---
 arch/m68k/mac/misc.c |   35 +--
 include/uapi/linux/pmu.h |2 ++
 2 files changed, 31 insertions(+), 6 deletions(-)

Index: linux/arch/m68k/mac/misc.c
===
--- linux.orig/arch/m68k/mac/misc.c 2015-05-31 11:01:26.0 +1000
+++ linux/arch/m68k/mac/misc.c  2015-05-31 11:01:28.0 +1000
@@ -124,19 +124,22 @@ static void pmu_write_time(long data)
 static unsigned char pmu_pram_read_byte(int offset)
 {
struct adb_request req;
-   if (pmu_request(&req, NULL, 3, PMU_READ_NVRAM,
-   (offset >> 8) & 0xFF, offset & 0xFF) < 0)
+
+   if (pmu_request(&req, NULL, 3, PMU_READ_XPRAM,
+   offset & 0xFF, 1) < 0)
return 0;
while (!req.complete)
pmu_poll();
-   return req.reply[3];
+
+   return req.reply[1];
 }
 
 static void pmu_pram_write_byte(unsigned char data, int offset)
 {
struct adb_request req;
-   if (pmu_request(&req, NULL, 4, PMU_WRITE_NVRAM,
-   (offset >> 8) & 0xFF, offset & 0xFF, data) < 0)
+
+   if (pmu_request(&req, NULL, 4, PMU_WRITE_XPRAM,
+   offset & 0xFF, 1, data) < 0)
return;
while (!req.complete)
pmu_poll();
@@ -295,11 +298,31 @@ static void via_pram_command(int command
 #if IS_ENABLED(CONFIG_NVRAM)
 static unsigned char via_pram_read_byte(int offset)
 {
-   return 0;
+   unsigned char temp;
+   int addr = ((offset & 0xE0) << 3) | ((offset & 0x1F) << 2);
+
+   /* Use RTC command 0x38 for XPRAM access, as per MESS source code */
+   via_pram_command(addr | 0x3800 | 0x8001, &temp);
+
+   return temp;
 }
 
 static void via_pram_write_byte(unsigned char data, int offset)
 {
+   unsigned char temp;
+   int addr = ((offset & 0xE0) << 3) | ((offset & 0x1F) << 2);
+
+   /* Clear the write protect bit */
+   temp = 0x55;
+   via_pram_command(0x34 | 0x01, &temp);
+
+   /* Write the byte to XPRAM */
+   temp = data;
+   via_pram_command(0x3800 | 0x0001 | addr, &temp);
+
+   /* Set the write protect bit */
+   temp = 0xD5;
+   via_pram_command(0x34 | 0x01, &temp);
 }
 #endif /* CONFIG_NVRAM */
 
Index: linux/include/uapi/linux/pmu.h
===
--- linux.orig/include/uapi/linux/pmu.h 2015-05-31 11:00:59.0 +1000
+++ linux/include/uapi/linux/pmu.h  2015-05-31 11:01:28.0 +1000
@@ -18,7 +18,9 @@
 #define PMU_POWER_CTRL 0x11/* control power of some devices */
 #define PMU_ADB_CMD0x20/* send ADB packet */
 #define PMU_ADB_POLL_OFF   0x21/* disable ADB auto-poll */
+#define PMU_WRITE_XPRAM0x32/* write eXtended Parameter RAM 
*/
 #define PMU_WRITE_NVRAM0x33/* write non-volatile RAM */
+#define PMU_READ_XPRAM 0x3a/* read eXtended Parameter RAM */
 #define PMU_READ_NVRAM 0x3b/* read non-volatile RAM */
 #define PMU_SET_RTC0x30/* set real-time clock */
 #define PMU_READ_RTC   0x38/* read real-time clock */


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[RFC 14/24] powerpc: Add missing ppc_md.nvram_size for CHRP and PowerMac

2015-05-30 Thread Finn Thain
Add the nvram_size() function to those PowerPC platforms that don't already
have one: CHRP and PowerMac. This means that the ppc_md.nvram_size()
function can be used to implement arch_nvram_ops.get_size()

Since we are addressing inconsistencies here, also rename chrp_nvram_read
and chrp_nvram_write, which break the naming convention used across
PowerPC platforms for NVRAM accessor functions.

Signed-off-by: Finn Thain 

---
 arch/powerpc/platforms/chrp/nvram.c |   14 ++
 arch/powerpc/platforms/powermac/nvram.c |9 +
 2 files changed, 19 insertions(+), 4 deletions(-)

Index: linux/arch/powerpc/platforms/chrp/nvram.c
===
--- linux.orig/arch/powerpc/platforms/chrp/nvram.c  2015-05-31 
11:00:59.0 +1000
+++ linux/arch/powerpc/platforms/chrp/nvram.c   2015-05-31 11:01:15.0 
+1000
@@ -23,7 +23,7 @@ static unsigned int nvram_size;
 static unsigned char nvram_buf[4];
 static DEFINE_SPINLOCK(nvram_lock);
 
-static unsigned char chrp_nvram_read(int addr)
+static unsigned char chrp_nvram_read_byte(int addr)
 {
unsigned int done;
unsigned long flags;
@@ -45,7 +45,7 @@ static unsigned char chrp_nvram_read(int
return ret;
 }
 
-static void chrp_nvram_write(int addr, unsigned char val)
+static void chrp_nvram_write_byte(int addr, unsigned char val)
 {
unsigned int done;
unsigned long flags;
@@ -63,6 +63,11 @@ static void chrp_nvram_write(int addr, u
spin_unlock_irqrestore(&nvram_lock, flags);
 }
 
+static ssize_t chrp_nvram_size(void)
+{
+   return nvram_size;
+}
+
 void __init chrp_nvram_init(void)
 {
struct device_node *nvram;
@@ -84,8 +89,9 @@ void __init chrp_nvram_init(void)
printk(KERN_INFO "CHRP nvram contains %u bytes\n", nvram_size);
of_node_put(nvram);
 
-   ppc_md.nvram_read_val = chrp_nvram_read;
-   ppc_md.nvram_write_val = chrp_nvram_write;
+   ppc_md.nvram_read_val  = chrp_nvram_read_byte;
+   ppc_md.nvram_write_val = chrp_nvram_write_byte;
+   ppc_md.nvram_size  = chrp_nvram_size;
 
return;
 }
Index: linux/arch/powerpc/platforms/powermac/nvram.c
===
--- linux.orig/arch/powerpc/platforms/powermac/nvram.c  2015-05-31 
11:00:59.0 +1000
+++ linux/arch/powerpc/platforms/powermac/nvram.c   2015-05-31 
11:01:15.0 +1000
@@ -147,6 +147,11 @@ static ssize_t core99_nvram_size(void)
 static volatile unsigned char __iomem *nvram_addr;
 static int nvram_mult;
 
+static ssize_t ppc32_nvram_size(void)
+{
+   return NVRAM_SIZE;
+}
+
 static unsigned char direct_nvram_read_byte(int addr)
 {
return in_8(&nvram_data[(addr & (NVRAM_SIZE - 1)) * nvram_mult]);
@@ -590,21 +595,25 @@ int __init pmac_nvram_init(void)
nvram_mult = 1;
ppc_md.nvram_read_val   = direct_nvram_read_byte;
ppc_md.nvram_write_val  = direct_nvram_write_byte;
+   ppc_md.nvram_size   = ppc32_nvram_size;
} else if (nvram_naddrs == 1) {
nvram_data = ioremap(r1.start, s1);
nvram_mult = (s1 + NVRAM_SIZE - 1) / NVRAM_SIZE;
ppc_md.nvram_read_val   = direct_nvram_read_byte;
ppc_md.nvram_write_val  = direct_nvram_write_byte;
+   ppc_md.nvram_size   = ppc32_nvram_size;
} else if (nvram_naddrs == 2) {
nvram_addr = ioremap(r1.start, s1);
nvram_data = ioremap(r2.start, s2);
ppc_md.nvram_read_val   = indirect_nvram_read_byte;
ppc_md.nvram_write_val  = indirect_nvram_write_byte;
+   ppc_md.nvram_size   = ppc32_nvram_size;
} else if (nvram_naddrs == 0 && sys_ctrler == SYS_CTRLER_PMU) {
 #ifdef CONFIG_ADB_PMU
nvram_naddrs = -1;
ppc_md.nvram_read_val   = pmu_nvram_read_byte;
ppc_md.nvram_write_val  = pmu_nvram_write_byte;
+   ppc_md.nvram_size   = ppc32_nvram_size;
 #endif /* CONFIG_ADB_PMU */
} else {
printk(KERN_ERR "Incompatible type of NVRAM\n");


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[RFC 01/24] macintosh/nvram: Remove as unused

2015-05-30 Thread Finn Thain
Signed-off-by: Finn Thain 

---
 drivers/macintosh/nvram.c |  130 --
 1 file changed, 130 deletions(-)

Index: linux/drivers/macintosh/nvram.c
===
--- linux.orig/drivers/macintosh/nvram.c2015-05-31 11:00:59.0 
+1000
+++ /dev/null   1970-01-01 00:00:00.0 +
@@ -1,130 +0,0 @@
-/*
- * /dev/nvram driver for Power Macintosh.
- */
-
-#define NVRAM_VERSION "1.0"
-
-#include 
-
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-
-#define NVRAM_SIZE 8192
-
-static loff_t nvram_llseek(struct file *file, loff_t offset, int origin)
-{
-   switch (origin) {
-   case 0:
-   break;
-   case 1:
-   offset += file->f_pos;
-   break;
-   case 2:
-   offset += NVRAM_SIZE;
-   break;
-   default:
-   offset = -1;
-   }
-   if (offset < 0)
-   return -EINVAL;
-
-   file->f_pos = offset;
-   return file->f_pos;
-}
-
-static ssize_t read_nvram(struct file *file, char __user *buf,
- size_t count, loff_t *ppos)
-{
-   unsigned int i;
-   char __user *p = buf;
-
-   if (!access_ok(VERIFY_WRITE, buf, count))
-   return -EFAULT;
-   if (*ppos >= NVRAM_SIZE)
-   return 0;
-   for (i = *ppos; count > 0 && i < NVRAM_SIZE; ++i, ++p, --count)
-   if (__put_user(nvram_read_byte(i), p))
-   return -EFAULT;
-   *ppos = i;
-   return p - buf;
-}
-
-static ssize_t write_nvram(struct file *file, const char __user *buf,
-  size_t count, loff_t *ppos)
-{
-   unsigned int i;
-   const char __user *p = buf;
-   char c;
-
-   if (!access_ok(VERIFY_READ, buf, count))
-   return -EFAULT;
-   if (*ppos >= NVRAM_SIZE)
-   return 0;
-   for (i = *ppos; count > 0 && i < NVRAM_SIZE; ++i, ++p, --count) {
-   if (__get_user(c, p))
-   return -EFAULT;
-   nvram_write_byte(c, i);
-   }
-   *ppos = i;
-   return p - buf;
-}
-
-static long nvram_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
-   switch(cmd) {
-   case PMAC_NVRAM_GET_OFFSET:
-   {
-   int part, offset;
-   if (copy_from_user(&part, (void __user*)arg, 
sizeof(part)) != 0)
-   return -EFAULT;
-   if (part < pmac_nvram_OF || part > pmac_nvram_NR)
-   return -EINVAL;
-   offset = pmac_get_partition(part);
-   if (copy_to_user((void __user*)arg, &offset, 
sizeof(offset)) != 0)
-   return -EFAULT;
-   break;
-   }
-
-   default:
-   return -EINVAL;
-   }
-
-   return 0;
-}
-
-const struct file_operations nvram_fops = {
-   .owner  = THIS_MODULE,
-   .llseek = nvram_llseek,
-   .read   = read_nvram,
-   .write  = write_nvram,
-   .unlocked_ioctl = nvram_ioctl,
-};
-
-static struct miscdevice nvram_dev = {
-   NVRAM_MINOR,
-   "nvram",
-   &nvram_fops
-};
-
-int __init nvram_init(void)
-{
-   printk(KERN_INFO "Macintosh non-volatile memory driver v%s\n",
-   NVRAM_VERSION);
-   return misc_register(&nvram_dev);
-}
-
-void __exit nvram_cleanup(void)
-{
-misc_deregister( &nvram_dev );
-}
-
-module_init(nvram_init);
-module_exit(nvram_cleanup);
-MODULE_LICENSE("GPL");


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[RFC 15/24] powerpc: Implement arch_nvram_ops.get_size() and remove old nvram_* exports

2015-05-30 Thread Finn Thain
Implement arch_nvram_ops for PPC32 and make use of it in the generic_nvram
misc device module so that the nvram_* function exports can be removed.

Signed-off-by: Finn Thain 

---
 arch/powerpc/include/asm/nvram.h |3 ---
 arch/powerpc/kernel/setup_32.c   |   10 +++---
 drivers/char/generic_nvram.c |   24 
 3 files changed, 19 insertions(+), 18 deletions(-)

Index: linux/arch/powerpc/include/asm/nvram.h
===
--- linux.orig/arch/powerpc/include/asm/nvram.h 2015-05-31 11:01:13.0 
+1000
+++ linux/arch/powerpc/include/asm/nvram.h  2015-05-31 11:01:16.0 
+1000
@@ -98,7 +98,4 @@ extern int nvram_write_os_partition(stru
unsigned int err_type,
unsigned int error_log_cnt);
 
-/* Determine NVRAM size */
-extern ssize_t nvram_get_size(void);
-
 #endif /* _ASM_POWERPC_NVRAM_H */
Index: linux/arch/powerpc/kernel/setup_32.c
===
--- linux.orig/arch/powerpc/kernel/setup_32.c   2015-05-31 11:01:13.0 
+1000
+++ linux/arch/powerpc/kernel/setup_32.c2015-05-31 11:01:16.0 
+1000
@@ -186,13 +186,12 @@ void nvram_write_byte(unsigned char val,
 }
 EXPORT_SYMBOL(nvram_write_byte);
 
-ssize_t nvram_get_size(void)
+static ssize_t ppc_nvram_get_size(void)
 {
if (ppc_md.nvram_size)
return ppc_md.nvram_size();
-   return -1;
+   return -ENODEV;
 }
-EXPORT_SYMBOL(nvram_get_size);
 
 void nvram_sync(void)
 {
@@ -201,6 +200,11 @@ void nvram_sync(void)
 }
 EXPORT_SYMBOL(nvram_sync);
 
+const struct nvram_ops arch_nvram_ops = {
+   .get_size   = ppc_nvram_get_size,
+};
+EXPORT_SYMBOL(arch_nvram_ops);
+
 #endif /* CONFIG_NVRAM */
 
 int __init ppc_init(void)
Index: linux/drivers/char/generic_nvram.c
===
--- linux.orig/drivers/char/generic_nvram.c 2015-05-31 11:01:13.0 
+1000
+++ linux/drivers/char/generic_nvram.c  2015-05-31 11:01:16.0 +1000
@@ -28,8 +28,6 @@
 #include 
 #endif
 
-#define NVRAM_SIZE 8192
-
 static DEFINE_MUTEX(nvram_mutex);
 static ssize_t nvram_len;
 
@@ -150,20 +148,22 @@ static struct miscdevice nvram_dev = {
 
 int __init nvram_init(void)
 {
-   int ret = 0;
+   int ret;
 
-   printk(KERN_INFO "Generic non-volatile memory driver v%s\n",
-   NVRAM_VERSION);
-   ret = misc_register(&nvram_dev);
-   if (ret != 0)
-   goto out;
+   if (arch_nvram_ops.get_size == NULL)
+   return -ENODEV;
 
-   nvram_len = nvram_get_size();
+   nvram_len = arch_nvram_ops.get_size();
if (nvram_len < 0)
-   nvram_len = NVRAM_SIZE;
+   return nvram_len;
 
-out:
-   return ret;
+   ret = misc_register(&nvram_dev);
+   if (ret)
+   return ret;
+
+   pr_info("Generic non-volatile memory driver v%s\n", NVRAM_VERSION);
+
+   return 0;
 }
 
 void __exit nvram_cleanup(void)


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[RFC 06/24] char/nvram: Adopt arch_nvram_ops

2015-05-30 Thread Finn Thain
Different platforms and architectures offer different NVRAM sizes and
access methods. E.g. PPC32 has byte-at-a-time read/write functions whereas
PPC64 has byte-range read/write functions. Adopt the nvram_ops struct so
the nvram module can call such functions as are defined by the various 
platforms and architectures.

Signed-off-by: Finn Thain 

---

The #ifdefs here restrict the procfs and checksumming code to those
architectures with PC-style RTC NVRAM. There may be a better place for
that code but it's an open question. See https://lkml.org/lkml/2015/2/3/22

The procfs code here, if irrelevant to ARM platforms, could be moved to
arch/x86 (like the earlier patch does for m68k code) and the nvram ops
could implemented and exported by the rtc-cmos driver instead. This
would eliminate these #ifdefs.

---
 drivers/char/nvram.c  |   30 +++---
 include/linux/nvram.h |2 ++
 2 files changed, 29 insertions(+), 3 deletions(-)

Index: linux/drivers/char/nvram.c
===
--- linux.orig/drivers/char/nvram.c 2015-05-31 11:01:05.0 +1000
+++ linux/drivers/char/nvram.c  2015-05-31 11:01:06.0 +1000
@@ -51,9 +51,12 @@ static DEFINE_MUTEX(nvram_mutex);
 static DEFINE_SPINLOCK(nvram_state_lock);
 static int nvram_open_cnt; /* #times opened */
 static int nvram_open_mode;/* special open modes */
+static ssize_t nvram_size;
 #define NVRAM_WRITE1 /* opened for writing (exclusive) */
 #define NVRAM_EXCL 2 /* opened with O_EXCL */
 
+#if defined(CONFIG_X86) || defined(CONFIG_ARM)
+
 /*
  * These functions are provided to be called internally or by other parts of
  * the kernel. It's up to the caller to ensure correct checksum before reading
@@ -161,6 +164,20 @@ void nvram_set_checksum(void)
 }
 #endif  /*  0  */
 
+static ssize_t nvram_get_size(void)
+{
+   return NVRAM_BYTES;
+}
+
+const struct nvram_ops arch_nvram_ops = {
+   .read_byte  = nvram_read_byte,
+   .write_byte = nvram_write_byte,
+   .get_size   = nvram_get_size,
+};
+EXPORT_SYMBOL(arch_nvram_ops);
+
+#endif /* CONFIG_X86 || CONFIG_ARM */
+
 /*
  * The are the file operation function for user access to /dev/nvram
  */
@@ -332,7 +349,7 @@ static int nvram_misc_release(struct ino
return 0;
 }
 
-#ifdef CONFIG_PROC_FS
+#if defined(CONFIG_PROC_FS) && (defined(CONFIG_X86) || defined(CONFIG_ARM))
 
 static char *floppy_types[] = {
"none", "5.25'' 360k", "5.25'' 1.2M", "3.5'' 720k", "3.5'' 1.44M",
@@ -459,13 +476,20 @@ static int __init nvram_module_init(void
 {
int ret;
 
+   if (arch_nvram_ops.get_size == NULL)
+   return -ENODEV;
+
+   nvram_size = arch_nvram_ops.get_size();
+   if (nvram_size < 0)
+   return nvram_size;
+
ret = misc_register(&nvram_misc);
if (ret) {
pr_err("nvram: can't misc_register on minor=%d\n", NVRAM_MINOR);
return ret;
}
 
-#ifdef CONFIG_PROC_FS
+#if defined(CONFIG_PROC_FS) && (defined(CONFIG_X86) || defined(CONFIG_ARM))
if (!proc_create("driver/nvram", 0, NULL, &nvram_proc_fops)) {
pr_err("nvram: can't create /proc/driver/nvram\n");
misc_deregister(&nvram_misc);
@@ -479,7 +503,7 @@ static int __init nvram_module_init(void
 
 static void __exit nvram_module_exit(void)
 {
-#ifdef CONFIG_PROC_FS
+#if defined(CONFIG_PROC_FS) && (defined(CONFIG_X86) || defined(CONFIG_ARM))
remove_proc_entry("driver/nvram", NULL);
 #endif
misc_deregister(&nvram_misc);
Index: linux/include/linux/nvram.h
===
--- linux.orig/include/linux/nvram.h2015-05-31 11:01:03.0 +1000
+++ linux/include/linux/nvram.h 2015-05-31 11:01:06.0 +1000
@@ -14,6 +14,8 @@ extern int nvram_check_checksum(void);
 struct nvram_ops {
ssize_t (*read)(char *, size_t, loff_t *);
ssize_t (*write)(char *, size_t, loff_t *);
+   unsigned char   (*read_byte)(int);
+   void(*write_byte)(unsigned char, int);
ssize_t (*get_size)(void);
 };
 


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[RFC 24/24] m68k: Dispatch nvram_ops calls to Atari or Mac functions

2015-05-30 Thread Finn Thain
A multi-platform kernel binary needs to decide at run-time how to dispatch
the arch_nvram_ops calls. Add platform-independent arch_nvram_ops, for use
when multiple platform-specific NVRAM ops implementations are needed.

Signed-off-by: Finn Thain 

---
 arch/m68k/Kconfig |2 
 arch/m68k/atari/nvram.c   |   22 +
 arch/m68k/include/asm/atarihw.h   |6 ++
 arch/m68k/include/asm/macintosh.h |4 +
 arch/m68k/kernel/setup_mm.c   |   89 ++
 arch/m68k/mac/misc.c  |8 ++-
 6 files changed, 117 insertions(+), 14 deletions(-)

Index: linux/arch/m68k/atari/nvram.c
===
--- linux.orig/arch/m68k/atari/nvram.c  2015-05-31 11:01:21.0 +1000
+++ linux/arch/m68k/atari/nvram.c   2015-05-31 11:01:29.0 +1000
@@ -73,7 +73,7 @@ static void __nvram_set_checksum(void)
__nvram_write_byte(sum, ATARI_CKS_LOC + 1);
 }
 
-static long nvram_set_checksum(void)
+long atari_nvram_set_checksum(void)
 {
spin_lock_irq(&rtc_lock);
__nvram_set_checksum();
@@ -81,7 +81,7 @@ static long nvram_set_checksum(void)
return 0;
 }
 
-static long nvram_initialize(void)
+long atari_nvram_initialize(void)
 {
loff_t i;
 
@@ -93,7 +93,7 @@ static long nvram_initialize(void)
return 0;
 }
 
-static ssize_t nvram_read(char *buf, size_t count, loff_t *ppos)
+ssize_t atari_nvram_read(char *buf, size_t count, loff_t *ppos)
 {
char *p = buf;
loff_t i;
@@ -114,7 +114,7 @@ static ssize_t nvram_read(char *buf, siz
return p - buf;
 }
 
-static ssize_t nvram_write(char *buf, size_t count, loff_t *ppos)
+ssize_t atari_nvram_write(char *buf, size_t count, loff_t *ppos)
 {
char *p = buf;
loff_t i;
@@ -137,21 +137,23 @@ static ssize_t nvram_write(char *buf, si
return p - buf;
 }
 
-static ssize_t nvram_get_size(void)
+ssize_t atari_nvram_get_size(void)
 {
if (!MACH_IS_ATARI)
return -ENODEV;
return NVRAM_BYTES;
 }
 
+#ifndef CONFIG_MAC
 const struct nvram_ops arch_nvram_ops = {
-   .read   = nvram_read,
-   .write  = nvram_write,
-   .get_size   = nvram_get_size,
-   .set_checksum   = nvram_set_checksum,
-   .initialize = nvram_initialize,
+   .read   = atari_nvram_read,
+   .write  = atari_nvram_write,
+   .get_size   = atari_nvram_get_size,
+   .set_checksum   = atari_nvram_set_checksum,
+   .initialize = atari_nvram_initialize,
 };
 EXPORT_SYMBOL(arch_nvram_ops);
+#endif
 
 #ifdef CONFIG_PROC_FS
 static struct {
Index: linux/arch/m68k/mac/misc.c
===
--- linux.orig/arch/m68k/mac/misc.c 2015-05-31 11:01:28.0 +1000
+++ linux/arch/m68k/mac/misc.c  2015-05-31 11:01:29.0 +1000
@@ -489,7 +489,7 @@ void pmu_shutdown(void)
  */
 
 #if IS_ENABLED(CONFIG_NVRAM)
-static unsigned char mac_pram_read_byte(int addr)
+unsigned char mac_pram_read_byte(int addr)
 {
unsigned char (*func)(int);
 
@@ -513,7 +513,7 @@ static unsigned char mac_pram_read_byte(
return 0xff;
 }
 
-static void mac_pram_write_byte(unsigned char val, int addr)
+void mac_pram_write_byte(unsigned char val, int addr)
 {
void (*func)(unsigned char, int);
 
@@ -536,19 +536,21 @@ static void mac_pram_write_byte(unsigned
(*func)(val, addr);
 }
 
-static ssize_t mac_pram_get_size(void)
+ssize_t mac_pram_get_size(void)
 {
if (!MACH_IS_MAC)
return -ENODEV;
return 256;
 }
 
+#ifndef CONFIG_ATARI
 const struct nvram_ops arch_nvram_ops = {
.read_byte  = mac_pram_read_byte,
.write_byte = mac_pram_write_byte,
.get_size   = mac_pram_get_size,
 };
 EXPORT_SYMBOL(arch_nvram_ops);
+#endif
 #endif /* CONFIG_NVRAM */
 
 
Index: linux/arch/m68k/kernel/setup_mm.c
===
--- linux.orig/arch/m68k/kernel/setup_mm.c  2015-05-31 11:00:59.0 
+1000
+++ linux/arch/m68k/kernel/setup_mm.c   2015-05-31 11:01:29.0 +1000
@@ -23,6 +23,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include 
@@ -40,6 +41,9 @@
 #include 
 #include 
 #endif
+#ifdef CONFIG_MAC
+#include 
+#endif
 #ifdef CONFIG_SUN3X
 #include 
 #endif
@@ -568,3 +572,88 @@ static int __init adb_probe_sync_enable
 
 __setup("adb_sync", adb_probe_sync_enable);
 #endif /* CONFIG_ADB */
+
+#if IS_ENABLED(CONFIG_NVRAM) && defined(CONFIG_ATARI) && defined(CONFIG_MAC)
+static ssize_t m68k_nvram_read(char *buf, size_t count, loff_t *ppos)
+{
+   if (MACH_IS_ATARI)
+   return atari_nvram_read(buf, count, ppos);
+   else if (MACH_IS_MAC) {
+   ssize_t size = mac_pram_get_size();
+   char *p = buf;
+   loff_t i;
+
+   for (i = *ppos; 

[RFC 18/24] nvram: Drop nvram_* symbol exports and prototypes

2015-05-30 Thread Finn Thain
Drivers now use the arch_nvram_ops calls so remove the function exports and
prototypes. nvram_check_checksum() is unused so remove it.

Signed-off-by: Finn Thain 

---
 arch/m68k/atari/nvram.c |6 +++---
 drivers/char/nvram.c|   27 +--
 include/linux/nvram.h   |8 
 3 files changed, 8 insertions(+), 33 deletions(-)

Index: linux/drivers/char/nvram.c
===
--- linux.orig/drivers/char/nvram.c 2015-05-31 11:01:17.0 +1000
+++ linux/drivers/char/nvram.c  2015-05-31 11:01:21.0 +1000
@@ -82,13 +82,12 @@ static ssize_t nvram_size;
  * periodic 11 min sync from kernel/time/ntp.c vs. this driver.)
  */
 
-unsigned char __nvram_read_byte(int i)
+static unsigned char __nvram_read_byte(int i)
 {
return CMOS_READ(NVRAM_FIRST_BYTE + i);
 }
-EXPORT_SYMBOL(__nvram_read_byte);
 
-unsigned char nvram_read_byte(int i)
+static unsigned char nvram_read_byte(int i)
 {
unsigned long flags;
unsigned char c;
@@ -98,16 +97,14 @@ unsigned char nvram_read_byte(int i)
spin_unlock_irqrestore(&rtc_lock, flags);
return c;
 }
-EXPORT_SYMBOL(nvram_read_byte);
 
 /* This races nicely with trying to read with checksum checking (nvram_read) */
-void __nvram_write_byte(unsigned char c, int i)
+static void __nvram_write_byte(unsigned char c, int i)
 {
CMOS_WRITE(c, NVRAM_FIRST_BYTE + i);
 }
-EXPORT_SYMBOL(__nvram_write_byte);
 
-void nvram_write_byte(unsigned char c, int i)
+static void nvram_write_byte(unsigned char c, int i)
 {
unsigned long flags;
 
@@ -115,14 +112,13 @@ void nvram_write_byte(unsigned char c, i
__nvram_write_byte(c, i);
spin_unlock_irqrestore(&rtc_lock, flags);
 }
-EXPORT_SYMBOL(nvram_write_byte);
 
 /* On PCs, the checksum is built only over bytes 2..31 */
 #define PC_CKS_RANGE_START 2
 #define PC_CKS_RANGE_END   31
 #define PC_CKS_LOC 32
 
-int __nvram_check_checksum(void)
+static int __nvram_check_checksum(void)
 {
int i;
unsigned short sum = 0;
@@ -134,19 +130,6 @@ int __nvram_check_checksum(void)
__nvram_read_byte(PC_CKS_LOC+1);
return (sum & 0x) == expect;
 }
-EXPORT_SYMBOL(__nvram_check_checksum);
-
-int nvram_check_checksum(void)
-{
-   unsigned long flags;
-   int rv;
-
-   spin_lock_irqsave(&rtc_lock, flags);
-   rv = __nvram_check_checksum();
-   spin_unlock_irqrestore(&rtc_lock, flags);
-   return rv;
-}
-EXPORT_SYMBOL(nvram_check_checksum);
 
 static void __nvram_set_checksum(void)
 {
Index: linux/include/linux/nvram.h
===
--- linux.orig/include/linux/nvram.h2015-05-31 11:01:17.0 +1000
+++ linux/include/linux/nvram.h 2015-05-31 11:01:21.0 +1000
@@ -3,14 +3,6 @@
 
 #include 
 
-/* __foo is foo without grabbing the rtc_lock - get it yourself */
-extern unsigned char __nvram_read_byte(int i);
-extern unsigned char nvram_read_byte(int i);
-extern void __nvram_write_byte(unsigned char c, int i);
-extern void nvram_write_byte(unsigned char c, int i);
-extern int __nvram_check_checksum(void);
-extern int nvram_check_checksum(void);
-
 struct nvram_ops {
ssize_t (*read)(char *, size_t, loff_t *);
ssize_t (*write)(char *, size_t, loff_t *);
Index: linux/arch/m68k/atari/nvram.c
===
--- linux.orig/arch/m68k/atari/nvram.c  2015-05-31 11:01:11.0 +1000
+++ linux/arch/m68k/atari/nvram.c   2015-05-31 11:01:21.0 +1000
@@ -33,13 +33,13 @@
  * periodic 11 min sync from kernel/time/ntp.c vs. this driver.)
  */
 
-unsigned char __nvram_read_byte(int i)
+static unsigned char __nvram_read_byte(int i)
 {
return CMOS_READ(NVRAM_FIRST_BYTE + i);
 }
 
 /* This races nicely with trying to read with checksum checking */
-void __nvram_write_byte(unsigned char c, int i)
+static void __nvram_write_byte(unsigned char c, int i)
 {
CMOS_WRITE(c, NVRAM_FIRST_BYTE + i);
 }
@@ -51,7 +51,7 @@ void __nvram_write_byte(unsigned char c,
 #define ATARI_CKS_RANGE_END47
 #define ATARI_CKS_LOC  48
 
-int __nvram_check_checksum(void)
+static int __nvram_check_checksum(void)
 {
int i;
unsigned char sum = 0;


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[RFC 17/24] powerpc, fbdev: Use arch_nvram_ops methods instead of nvram_read_byte() and nvram_write_byte()

2015-05-30 Thread Finn Thain
Make use of arch_nvram_ops in device drivers so that the nvram_*
function exports can be removed.

Since they are no longer global symbols, rename the PPC32 nvram_* functions
appropriately.

Add the missing CONFIG_NVRAM test to imsttfb to avoid a build failure.

Signed-off-by: Finn Thain 

---
 arch/powerpc/kernel/setup_32.c |8 
 drivers/char/generic_nvram.c   |4 ++--
 drivers/video/fbdev/controlfb.c|4 ++--
 drivers/video/fbdev/imsttfb.c  |7 +++
 drivers/video/fbdev/matrox/matroxfb_base.c |2 +-
 drivers/video/fbdev/platinumfb.c   |4 ++--
 drivers/video/fbdev/valkyriefb.c   |4 ++--
 7 files changed, 16 insertions(+), 17 deletions(-)

Index: linux/arch/powerpc/kernel/setup_32.c
===
--- linux.orig/arch/powerpc/kernel/setup_32.c   2015-05-31 11:01:17.0 
+1000
+++ linux/arch/powerpc/kernel/setup_32.c2015-05-31 11:01:19.0 
+1000
@@ -170,20 +170,18 @@ __setup("l3cr=", ppc_setup_l3cr);
 
 #ifdef CONFIG_GENERIC_NVRAM
 
-unsigned char nvram_read_byte(int addr)
+static unsigned char ppc_nvram_read_byte(int addr)
 {
if (ppc_md.nvram_read_val)
return ppc_md.nvram_read_val(addr);
return 0xff;
 }
-EXPORT_SYMBOL(nvram_read_byte);
 
-void nvram_write_byte(unsigned char val, int addr)
+static void ppc_nvram_write_byte(unsigned char val, int addr)
 {
if (ppc_md.nvram_write_val)
ppc_md.nvram_write_val(addr, val);
 }
-EXPORT_SYMBOL(nvram_write_byte);
 
 static ssize_t ppc_nvram_get_size(void)
 {
@@ -200,6 +198,8 @@ static long ppc_nvram_sync(void)
 }
 
 const struct nvram_ops arch_nvram_ops = {
+   .read_byte  = ppc_nvram_read_byte,
+   .write_byte = ppc_nvram_write_byte,
.get_size   = ppc_nvram_get_size,
.sync   = ppc_nvram_sync,
 };
Index: linux/drivers/char/generic_nvram.c
===
--- linux.orig/drivers/char/generic_nvram.c 2015-05-31 11:01:17.0 
+1000
+++ linux/drivers/char/generic_nvram.c  2015-05-31 11:01:19.0 +1000
@@ -64,7 +64,7 @@ static ssize_t read_nvram(struct file *f
if (*ppos >= nvram_len)
return 0;
for (i = *ppos; count > 0 && i < nvram_len; ++i, ++p, --count)
-   if (__put_user(nvram_read_byte(i), p))
+   if (__put_user(arch_nvram_ops.read_byte(i), p))
return -EFAULT;
*ppos = i;
return p - buf;
@@ -84,7 +84,7 @@ static ssize_t write_nvram(struct file *
for (i = *ppos; count > 0 && i < nvram_len; ++i, ++p, --count) {
if (__get_user(c, p))
return -EFAULT;
-   nvram_write_byte(c, i);
+   arch_nvram_ops.write_byte(c, i);
}
*ppos = i;
return p - buf;
Index: linux/drivers/video/fbdev/controlfb.c
===
--- linux.orig/drivers/video/fbdev/controlfb.c  2015-05-31 11:00:59.0 
+1000
+++ linux/drivers/video/fbdev/controlfb.c   2015-05-31 11:01:19.0 
+1000
@@ -415,7 +415,7 @@ static int __init init_control(struct fb
/* Try to pick a video mode out of NVRAM if we have one. */
 #ifdef CONFIG_NVRAM
if (default_cmode == CMODE_NVRAM) {
-   cmode = nvram_read_byte(NV_CMODE);
+   cmode = arch_nvram_ops.read_byte(NV_CMODE);
if(cmode < CMODE_8 || cmode > CMODE_32)
cmode = CMODE_8;
} else
@@ -423,7 +423,7 @@ static int __init init_control(struct fb
cmode=default_cmode;
 #ifdef CONFIG_NVRAM
if (default_vmode == VMODE_NVRAM) {
-   vmode = nvram_read_byte(NV_VMODE);
+   vmode = arch_nvram_ops.read_byte(NV_VMODE);
if (vmode < 1 || vmode > VMODE_MAX ||
control_mac_modes[vmode - 1].m[full] < cmode) {
sense = read_control_sense(p);
Index: linux/drivers/video/fbdev/matrox/matroxfb_base.c
===
--- linux.orig/drivers/video/fbdev/matrox/matroxfb_base.c   2015-05-31 
11:01:13.0 +1000
+++ linux/drivers/video/fbdev/matrox/matroxfb_base.c2015-05-31 
11:01:19.0 +1000
@@ -1888,7 +1888,7 @@ static int initMatrox2(struct matrox_fb_
default_vmode = VMODE_640_480_60;
 #ifdef CONFIG_NVRAM
if (default_cmode == CMODE_NVRAM)
-   default_cmode = nvram_read_byte(NV_CMODE);
+   default_cmode = arch_nvram_ops.read_byte(NV_CMODE);
 #endif
if (default_cmode < CMODE_8 || default_cmode > CMODE_32)
default_

[RFC 07/24] x86/thinkpad_acpi: Use arch_nvram_ops methods instead of nvram_read_byte() and nvram_write_byte()

2015-05-30 Thread Finn Thain
Make use of arch_nvram_ops in the thinkpad_acpi driver so that the
nvram_* function exports can be removed.

This patch series was tested on a ThinkPad T43.

Signed-off-by: Finn Thain 

---
 drivers/platform/x86/thinkpad_acpi.c |   20 ++--
 1 file changed, 10 insertions(+), 10 deletions(-)

Index: linux/drivers/platform/x86/thinkpad_acpi.c
===
--- linux.orig/drivers/platform/x86/thinkpad_acpi.c 2015-05-31 
11:00:59.0 +1000
+++ linux/drivers/platform/x86/thinkpad_acpi.c  2015-05-31 11:01:07.0 
+1000
@@ -2311,30 +2311,30 @@ static void hotkey_read_nvram(struct tp_
u8 d;
 
if (m & TP_NVRAM_HKEY_GROUP_HK2) {
-   d = nvram_read_byte(TP_NVRAM_ADDR_HK2);
+   d = arch_nvram_ops.read_byte(TP_NVRAM_ADDR_HK2);
n->thinkpad_toggle = !!(d & TP_NVRAM_MASK_HKT_THINKPAD);
n->zoom_toggle = !!(d & TP_NVRAM_MASK_HKT_ZOOM);
n->display_toggle = !!(d & TP_NVRAM_MASK_HKT_DISPLAY);
n->hibernate_toggle = !!(d & TP_NVRAM_MASK_HKT_HIBERNATE);
}
if (m & TP_ACPI_HKEY_THNKLGHT_MASK) {
-   d = nvram_read_byte(TP_NVRAM_ADDR_THINKLIGHT);
+   d = arch_nvram_ops.read_byte(TP_NVRAM_ADDR_THINKLIGHT);
n->thinklight_toggle = !!(d & TP_NVRAM_MASK_THINKLIGHT);
}
if (m & TP_ACPI_HKEY_DISPXPAND_MASK) {
-   d = nvram_read_byte(TP_NVRAM_ADDR_VIDEO);
+   d = arch_nvram_ops.read_byte(TP_NVRAM_ADDR_VIDEO);
n->displayexp_toggle =
!!(d & TP_NVRAM_MASK_HKT_DISPEXPND);
}
if (m & TP_NVRAM_HKEY_GROUP_BRIGHTNESS) {
-   d = nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS);
+   d = arch_nvram_ops.read_byte(TP_NVRAM_ADDR_BRIGHTNESS);
n->brightness_level = (d & TP_NVRAM_MASK_LEVEL_BRIGHTNESS)
>> TP_NVRAM_POS_LEVEL_BRIGHTNESS;
n->brightness_toggle =
!!(d & TP_NVRAM_MASK_HKT_BRIGHTNESS);
}
if (m & TP_NVRAM_HKEY_GROUP_VOLUME) {
-   d = nvram_read_byte(TP_NVRAM_ADDR_MIXER);
+   d = arch_nvram_ops.read_byte(TP_NVRAM_ADDR_MIXER);
n->volume_level = (d & TP_NVRAM_MASK_LEVEL_VOLUME)
>> TP_NVRAM_POS_LEVEL_VOLUME;
n->mute = !!(d & TP_NVRAM_MASK_MUTE);
@@ -6153,7 +6153,7 @@ static unsigned int tpacpi_brightness_nv
 {
u8 lnvram;
 
-   lnvram = (nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS)
+   lnvram = (arch_nvram_ops.read_byte(TP_NVRAM_ADDR_BRIGHTNESS)
  & TP_NVRAM_MASK_LEVEL_BRIGHTNESS)
  >> TP_NVRAM_POS_LEVEL_BRIGHTNESS;
lnvram &= bright_maxlvl;
@@ -6178,7 +6178,7 @@ static void tpacpi_brightness_checkpoint
if (unlikely(!acpi_ec_read(TP_EC_BACKLIGHT, &lec)))
goto unlock;
lec &= TP_EC_BACKLIGHT_LVLMSK;
-   b_nvram = nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS);
+   b_nvram = arch_nvram_ops.read_byte(TP_NVRAM_ADDR_BRIGHTNESS);
 
if (lec != ((b_nvram & TP_NVRAM_MASK_LEVEL_BRIGHTNESS)
 >> TP_NVRAM_POS_LEVEL_BRIGHTNESS)) {
@@ -6186,7 +6186,7 @@ static void tpacpi_brightness_checkpoint
b_nvram &= ~(TP_NVRAM_MASK_LEVEL_BRIGHTNESS <<
TP_NVRAM_POS_LEVEL_BRIGHTNESS);
b_nvram |= lec;
-   nvram_write_byte(b_nvram, TP_NVRAM_ADDR_BRIGHTNESS);
+   arch_nvram_ops.write_byte(b_nvram, TP_NVRAM_ADDR_BRIGHTNESS);
dbg_printk(TPACPI_DBG_BRGHT,
   "updated NVRAM backlight level to %u (0x%02x)\n",
   (unsigned int) lec, (unsigned int) b_nvram);
@@ -6794,13 +6794,13 @@ static void tpacpi_volume_checkpoint_nvr
if (unlikely(!acpi_ec_read(TP_EC_AUDIO, &lec)))
goto unlock;
lec &= ec_mask;
-   b_nvram = nvram_read_byte(TP_NVRAM_ADDR_MIXER);
+   b_nvram = arch_nvram_ops.read_byte(TP_NVRAM_ADDR_MIXER);
 
if (lec != (b_nvram & ec_mask)) {
/* NVRAM needs update */
b_nvram &= ~ec_mask;
b_nvram |= lec;
-   nvram_write_byte(b_nvram, TP_NVRAM_ADDR_MIXER);
+   arch_nvram_ops.write_byte(b_nvram, TP_NVRAM_ADDR_MIXER);
dbg_printk(TPACPI_DBG_MIXER,
   "updated NVRAM mixer status to 0x%02x (0x%02x)\n",
   (unsigned int) lec, (unsigned int) b_nvram);


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[RFC 08/24] char/nvram: Allow the set_checksum and initialize ioctls to be omitted

2015-05-30 Thread Finn Thain
The drivers/char/nvram module has previously only supported RTC "CMOS"
NVRAM, for which it provides appropriate checksum ioctls. Make these
ioctls optional so the module can be re-used with other kinds of NVRAM.

The ops struct methods that implement the ioctls now return error
codes so that a multi-platform kernel binary can do the right thing when
running on hardware without suitable NVRAM.

Signed-off-by: Finn Thain 

---
 drivers/char/nvram.c  |   61 --
 include/linux/nvram.h |2 +
 2 files changed, 37 insertions(+), 26 deletions(-)

Index: linux/drivers/char/nvram.c
===
--- linux.orig/drivers/char/nvram.c 2015-05-31 11:01:06.0 +1000
+++ linux/drivers/char/nvram.c  2015-05-31 11:01:08.0 +1000
@@ -153,16 +153,25 @@ static void __nvram_set_checksum(void)
__nvram_write_byte(sum & 0xff, PC_CKS_LOC + 1);
 }
 
-#if 0
-void nvram_set_checksum(void)
+static long nvram_set_checksum(void)
 {
-   unsigned long flags;
+   spin_lock_irq(&rtc_lock);
+   __nvram_set_checksum();
+   spin_unlock_irq(&rtc_lock);
+   return 0;
+}
+
+static long nvram_initialize(void)
+{
+   ssize_t i;
 
-   spin_lock_irqsave(&rtc_lock, flags);
+   spin_lock_irq(&rtc_lock);
+   for (i = 0; i < NVRAM_BYTES; ++i)
+   __nvram_write_byte(0, i);
__nvram_set_checksum();
-   spin_unlock_irqrestore(&rtc_lock, flags);
+   spin_unlock_irq(&rtc_lock);
+   return 0;
 }
-#endif  /*  0  */
 
 static ssize_t nvram_get_size(void)
 {
@@ -173,6 +182,8 @@ const struct nvram_ops arch_nvram_ops =
.read_byte  = nvram_read_byte,
.write_byte = nvram_write_byte,
.get_size   = nvram_get_size,
+   .set_checksum   = nvram_set_checksum,
+   .initialize = nvram_initialize,
 };
 EXPORT_SYMBOL(arch_nvram_ops);
 
@@ -272,26 +283,19 @@ checksum_err:
 static long nvram_misc_ioctl(struct file *file, unsigned int cmd,
  unsigned long arg)
 {
-   int i;
+   long ret = -ENOTTY;
 
switch (cmd) {
-
case NVRAM_INIT:
/* initialize NVRAM contents and checksum */
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
 
mutex_lock(&nvram_mutex);
-   spin_lock_irq(&rtc_lock);
-
-   for (i = 0; i < NVRAM_BYTES; ++i)
-   __nvram_write_byte(0, i);
-   __nvram_set_checksum();
-
-   spin_unlock_irq(&rtc_lock);
+   if (arch_nvram_ops.initialize != NULL)
+   ret = arch_nvram_ops.initialize();
mutex_unlock(&nvram_mutex);
-   return 0;
-
+   break;
case NVRAM_SETCKS:
/* just set checksum, contents unchanged (maybe useful after
 * checksum garbaged somehow...) */
@@ -299,24 +303,29 @@ static long nvram_misc_ioctl(struct file
return -EACCES;
 
mutex_lock(&nvram_mutex);
-   spin_lock_irq(&rtc_lock);
-   __nvram_set_checksum();
-   spin_unlock_irq(&rtc_lock);
+   if (arch_nvram_ops.set_checksum != NULL)
+   ret = arch_nvram_ops.set_checksum();
mutex_unlock(&nvram_mutex);
-   return 0;
-
-   default:
-   return -ENOTTY;
+   break;
}
+   return ret;
 }
 
 static int nvram_misc_open(struct inode *inode, struct file *file)
 {
spin_lock(&nvram_state_lock);
 
+   /* Prevent multiple readers/writers if desired. */
if ((nvram_open_cnt && (file->f_flags & O_EXCL)) ||
-   (nvram_open_mode & NVRAM_EXCL) ||
-   ((file->f_mode & FMODE_WRITE) && (nvram_open_mode & NVRAM_WRITE))) {
+   (nvram_open_mode & NVRAM_EXCL)) {
+   spin_unlock(&nvram_state_lock);
+   return -EBUSY;
+   }
+
+   /* Prevent multiple writers if the set_checksum ioctl is implemented. */
+   if ((arch_nvram_ops.set_checksum != NULL) &&
+   (file->f_mode & FMODE_WRITE) &&
+   (nvram_open_mode & NVRAM_WRITE)) {
spin_unlock(&nvram_state_lock);
return -EBUSY;
}
Index: linux/include/linux/nvram.h
===
--- linux.orig/include/linux/nvram.h2015-05-31 11:01:06.0 +1000
+++ linux/include/linux/nvram.h 2015-05-31 11:01:08.0 +1000
@@ -17,6 +17,8 @@ struct nvram_ops {
unsigned char   (*read_byte)(int);
void(*write_byte)(unsigned char, int);
ssize_t (*get_size)(void);
+   long(*set_checksum)(void);
+   long

[RFC 11/24] m68k/atari: Implement arch_nvram_ops methods and enable CONFIG_HAVE_ARCH_NVRAM_OPS

2015-05-30 Thread Finn Thain
Atari RTC NVRAM has a checksum so implement the remaining arch_nvram_ops
methods for the set_checksum and initialize ioctls. Enable
CONFIG_HAVE_ARCH_NVRAM_OPS.

Signed-off-by: Finn Thain 

---

This re-enables the nvram module for Atari.

---
 arch/m68k/Kconfig   |3 +++
 arch/m68k/atari/nvram.c |   24 
 drivers/char/Kconfig|2 +-
 3 files changed, 28 insertions(+), 1 deletion(-)

Index: linux/arch/m68k/atari/nvram.c
===
--- linux.orig/arch/m68k/atari/nvram.c  2015-05-31 11:01:03.0 +1000
+++ linux/arch/m68k/atari/nvram.c   2015-05-31 11:01:11.0 +1000
@@ -73,6 +73,26 @@ static void __nvram_set_checksum(void)
__nvram_write_byte(sum, ATARI_CKS_LOC + 1);
 }
 
+static long nvram_set_checksum(void)
+{
+   spin_lock_irq(&rtc_lock);
+   __nvram_set_checksum();
+   spin_unlock_irq(&rtc_lock);
+   return 0;
+}
+
+static long nvram_initialize(void)
+{
+   loff_t i;
+
+   spin_lock_irq(&rtc_lock);
+   for (i = 0; i < NVRAM_BYTES; ++i)
+   __nvram_write_byte(0, i);
+   __nvram_set_checksum();
+   spin_unlock_irq(&rtc_lock);
+   return 0;
+}
+
 static ssize_t nvram_read(char *buf, size_t count, loff_t *ppos)
 {
char *p = buf;
@@ -119,6 +139,8 @@ static ssize_t nvram_write(char *buf, si
 
 static ssize_t nvram_get_size(void)
 {
+   if (!MACH_IS_ATARI)
+   return -ENODEV;
return NVRAM_BYTES;
 }
 
@@ -126,6 +148,8 @@ const struct nvram_ops arch_nvram_ops =
.read   = nvram_read,
.write  = nvram_write,
.get_size   = nvram_get_size,
+   .set_checksum   = nvram_set_checksum,
+   .initialize = nvram_initialize,
 };
 EXPORT_SYMBOL(arch_nvram_ops);
 
Index: linux/drivers/char/Kconfig
===
--- linux.orig/drivers/char/Kconfig 2015-05-31 11:01:00.0 +1000
+++ linux/drivers/char/Kconfig  2015-05-31 11:01:11.0 +1000
@@ -247,7 +247,7 @@ source "drivers/char/hw_random/Kconfig"
 
 config NVRAM
tristate "/dev/nvram support"
-   depends on X86 || (ARM && RTC_DRV_CMOS) || GENERIC_NVRAM
+   depends on X86 || (ARM && RTC_DRV_CMOS) || GENERIC_NVRAM || 
HAVE_ARCH_NVRAM_OPS
---help---
  If you say Y here and create a character special file /dev/nvram
  with major number 10 and minor number 144 using mknod ("man mknod"),
Index: linux/arch/m68k/Kconfig
===
--- linux.orig/arch/m68k/Kconfig2015-05-31 11:00:59.0 +1000
+++ linux/arch/m68k/Kconfig 2015-05-31 11:01:11.0 +1000
@@ -71,6 +71,9 @@ config PGTABLE_LEVELS
default 2 if SUN3 || COLDFIRE
default 3
 
+config HAVE_ARCH_NVRAM_OPS
+   def_bool ATARI
+
 source "init/Kconfig"
 
 source "kernel/Kconfig.freezer"


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[RFC 10/24] char/nvram: Use generic fixed_size_llseek()

2015-05-30 Thread Finn Thain
Signed-off-by: Finn Thain 

---
 drivers/char/nvram.c |   16 +---
 1 file changed, 1 insertion(+), 15 deletions(-)

Index: linux/drivers/char/nvram.c
===
--- linux.orig/drivers/char/nvram.c 2015-05-31 11:01:09.0 +1000
+++ linux/drivers/char/nvram.c  2015-05-31 11:01:11.0 +1000
@@ -235,21 +235,7 @@ EXPORT_SYMBOL(arch_nvram_ops);
 
 static loff_t nvram_misc_llseek(struct file *file, loff_t offset, int origin)
 {
-   switch (origin) {
-   case 0:
-   /* nothing to do */
-   break;
-   case 1:
-   offset += file->f_pos;
-   break;
-   case 2:
-   offset += NVRAM_BYTES;
-   break;
-   default:
-   return -EINVAL;
-   }
-
-   return (offset >= 0) ? (file->f_pos = offset) : -EINVAL;
+   return fixed_size_llseek(file, offset, origin, nvram_size);
 }
 
 static ssize_t nvram_misc_read(struct file *file, char __user *buf,


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[RFC 00/24] Re-use nvram module

2015-05-30 Thread Finn Thain

The generic NVRAM module, drivers/char/generic_nvram, implements a
/dev/nvram misc device. It is used only by 32-bit PowerPC platforms and
isn't generic enough to be more widely used.

The RTC NVRAM module, drivers/char/nvram, also implements a /dev/nvram
misc device. It is used by x86, ARM and m68k.

The former module cannot be used on x86, ARM or m68k because it
cannot co-exist with the latter module, partly due to the Kconfig logic.

It is possible to modify the modules so that one kernel binary could
have either, neither or both. However, automatically loading the
appropriate module is then impossible; if both provide the
char-major-10-144 alias then the wrong module will end up being loaded.
Hence a multi-platform kernel binary needs a single generic nvram module
with alias char-major-10-144.

Therefore, drivers/char/nvram.c should be made more generic and the
arch-specific code therein should be moved to a more appropriate
place under arch/. Also, drivers/char/generic_nvram.c should be removed
to reduce code duplication.

In this patch series, Atari-specific code is moved from the nvram module
to arch/m68k/atari. More arch-specific code in the nvram module could
be moved, probably to arch/x86, but it is difficult to determine just
what code is relevant to ARM platforms and what code is x86-only.

In addressing code duplication, this patch series removes three
inconsistent /dev/nvram misc device implementations. One of these,
drivers/macintosh/nvram.c is entirely unused already. The other two,
drivers/char/generic_nvram.c and the misc device implementation in
arch/powerpc/kernel/nvram_64.c, are replaced by drivers/char/nvram.c.

A benefit of this work is better consistency -- between PPC32 and PPC64
as well as between PPC_PMAC and MAC. This new uniformity does have
implications for userspace, that is, some error codes for some ioctl calls
become consistent on all PowerPC platforms.

The drivers/char/nvram module becomes sufficiently generic to be useful
to other platforms and architectures, besides those with "CMOS" RTC. At the
end of this patch series the module is adopted by the m68k Mac port, which
already has PRAM access functions but lacks the /dev/nvram misc device.

This patch series has been compile-tested for arm, m68k, powerpc and x86.
The nvram and thinkpad_acpi modules were regression tested on a ThinkPad T43.
The /dev/nvram functionality was also regression tested on a G3 PowerMac.
The nvram module was also tested on a PowerBook 520 and Quadra 650.
Note that my testing doesn't cover PPC64 or Atari.

---
 arch/m68k/Kconfig  |3 
 arch/m68k/atari/Makefile   |2 
 arch/m68k/atari/nvram.c|  304 
 arch/m68k/include/asm/atarihw.h|6 
 arch/m68k/include/asm/macintosh.h  |4 
 arch/m68k/kernel/setup_mm.c|   89 +++
 arch/m68k/mac/misc.c   |  157 --
 arch/powerpc/Kconfig   |5 
 arch/powerpc/include/asm/nvram.h   |9 
 arch/powerpc/kernel/nvram_64.c |  203 +---
 arch/powerpc/kernel/setup_32.c |   27 -
 arch/powerpc/platforms/chrp/Makefile   |2 
 arch/powerpc/platforms/chrp/nvram.c|   14 
 arch/powerpc/platforms/chrp/setup.c|2 
 arch/powerpc/platforms/powermac/Makefile   |5 
 arch/powerpc/platforms/powermac/nvram.c|   11 
 arch/powerpc/platforms/powermac/setup.c|3 
 drivers/char/Kconfig   |   13 
 drivers/char/Makefile  |6 
 drivers/char/generic_nvram.c   |  174 --
 drivers/char/nvram.c   |  731 -
 drivers/macintosh/nvram.c  |  130 -
 drivers/platform/x86/thinkpad_acpi.c   |   20 
 drivers/scsi/Kconfig   |6 
 drivers/scsi/atari_scsi.c  |   16 
 drivers/video/fbdev/controlfb.c|4 
 drivers/video/fbdev/imsttfb.c  |7 
 drivers/video/fbdev/matrox/matroxfb_base.c |4 
 drivers/video/fbdev/platinumfb.c   |4 
 drivers/video/fbdev/valkyriefb.c   |4 
 include/linux/nvram.h  |   23 
 include/uapi/linux/pmu.h   |2 
 32 files changed, 950 insertions(+), 1040 deletions(-)




___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[RFC 20/24] char/generic_nvram: Remove as unused

2015-05-30 Thread Finn Thain
And thus eliminate some twisted CONFIG_GENERIC_NVRAM logic.

Signed-off-by: Finn Thain 

---
 drivers/char/Makefile|6 -
 drivers/char/generic_nvram.c |  176 ---
 2 files changed, 1 insertion(+), 181 deletions(-)

Index: linux/drivers/char/Makefile
===
--- linux.orig/drivers/char/Makefile2015-05-31 11:00:59.0 +1000
+++ linux/drivers/char/Makefile 2015-05-31 11:01:23.0 +1000
@@ -30,11 +30,7 @@ obj-$(CONFIG_GEN_RTC)+= genrtc.o
 obj-$(CONFIG_EFI_RTC)  += efirtc.o
 obj-$(CONFIG_DS1302)   += ds1302.o
 obj-$(CONFIG_XILINX_HWICAP)+= xilinx_hwicap/
-ifeq ($(CONFIG_GENERIC_NVRAM),y)
-  obj-$(CONFIG_NVRAM)  += generic_nvram.o
-else
-  obj-$(CONFIG_NVRAM)  += nvram.o
-endif
+obj-$(CONFIG_NVRAM)+= nvram.o
 obj-$(CONFIG_TOSHIBA)  += toshiba.o
 obj-$(CONFIG_I8K)  += i8k.o
 obj-$(CONFIG_DS1620)   += ds1620.o
Index: linux/drivers/char/generic_nvram.c
===
--- linux.orig/drivers/char/generic_nvram.c 2015-05-31 11:01:19.0 
+1000
+++ /dev/null   1970-01-01 00:00:00.0 +
@@ -1,176 +0,0 @@
-/*
- * Generic /dev/nvram driver for architectures providing some
- * "generic" hooks, that is :
- *
- * nvram_read_byte, nvram_write_byte, nvram_sync, nvram_get_size
- *
- * Note that an additional hook is supported for PowerMac only
- * for getting the nvram "partition" informations
- *
- */
-
-#define NVRAM_VERSION "1.1"
-
-#include 
-
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-
-#ifdef CONFIG_PPC_PMAC
-#include 
-#include 
-#endif
-
-static DEFINE_MUTEX(nvram_mutex);
-static ssize_t nvram_len;
-
-static loff_t nvram_llseek(struct file *file, loff_t offset, int origin)
-{
-   switch (origin) {
-   case 0:
-   break;
-   case 1:
-   offset += file->f_pos;
-   break;
-   case 2:
-   offset += nvram_len;
-   break;
-   default:
-   offset = -1;
-   }
-   if (offset < 0)
-   return -EINVAL;
-
-   file->f_pos = offset;
-
-   return file->f_pos;
-}
-
-static ssize_t read_nvram(struct file *file, char __user *buf,
- size_t count, loff_t *ppos)
-{
-   unsigned int i;
-   char __user *p = buf;
-
-   if (!access_ok(VERIFY_WRITE, buf, count))
-   return -EFAULT;
-   if (*ppos >= nvram_len)
-   return 0;
-   for (i = *ppos; count > 0 && i < nvram_len; ++i, ++p, --count)
-   if (__put_user(arch_nvram_ops.read_byte(i), p))
-   return -EFAULT;
-   *ppos = i;
-   return p - buf;
-}
-
-static ssize_t write_nvram(struct file *file, const char __user *buf,
-  size_t count, loff_t *ppos)
-{
-   unsigned int i;
-   const char __user *p = buf;
-   char c;
-
-   if (!access_ok(VERIFY_READ, buf, count))
-   return -EFAULT;
-   if (*ppos >= nvram_len)
-   return 0;
-   for (i = *ppos; count > 0 && i < nvram_len; ++i, ++p, --count) {
-   if (__get_user(c, p))
-   return -EFAULT;
-   arch_nvram_ops.write_byte(c, i);
-   }
-   *ppos = i;
-   return p - buf;
-}
-
-static int nvram_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
-   switch(cmd) {
-#ifdef CONFIG_PPC_PMAC
-   case OBSOLETE_PMAC_NVRAM_GET_OFFSET:
-   printk(KERN_WARNING "nvram: Using obsolete 
PMAC_NVRAM_GET_OFFSET ioctl\n");
-   case IOC_NVRAM_GET_OFFSET: {
-   int part, offset;
-
-   if (!machine_is(powermac))
-   return -EINVAL;
-   if (copy_from_user(&part, (void __user*)arg, sizeof(part)) != 0)
-   return -EFAULT;
-   if (part < pmac_nvram_OF || part > pmac_nvram_NR)
-   return -EINVAL;
-   offset = pmac_get_partition(part);
-   if (copy_to_user((void __user*)arg, &offset, sizeof(offset)) != 
0)
-   return -EFAULT;
-   break;
-   }
-#endif /* CONFIG_PPC_PMAC */
-   case IOC_NVRAM_SYNC:
-   arch_nvram_ops.sync();
-   break;
-   default:
-   return -EINVAL;
-   }
-
-   return 0;
-}
-
-static long nvram_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned 
long arg)
-{
-   int ret;
-
-   mutex_lock(&nvram_mutex);
-   ret = nvram_ioctl(file, cmd, arg);
-   mutex_unlock(&nvram_mutex);
-
-   return ret;
-}
-
-const struct file_operations nvram_fops = {
-   .owner  = THIS_MODULE,
-  

[RFC 16/24] powerpc: Implement nvram sync ioctl

2015-05-30 Thread Finn Thain
Add the powerpc-specific sync() method to struct nvram_ops and implement
the corresponding ioctl in the nvram module. This allows the nvram module
to replace the generic_nvram module.

Signed-off-by: Finn Thain 

---

On PPC32, the IOC_NVRAM_SYNC ioctl call always returns 0, even for those
platforms that don't implement ppc_md.nvram_sync. This patch retains
that quirk. It might be better to return failure (which is what PPC64 does).

---
 arch/powerpc/include/asm/nvram.h |3 ---
 arch/powerpc/kernel/setup_32.c   |6 +++---
 drivers/char/generic_nvram.c |2 +-
 drivers/char/nvram.c |   38 ++
 include/linux/nvram.h|4 
 5 files changed, 46 insertions(+), 7 deletions(-)

Index: linux/drivers/char/nvram.c
===
--- linux.orig/drivers/char/nvram.c 2015-05-31 11:01:13.0 +1000
+++ linux/drivers/char/nvram.c  2015-05-31 11:01:17.0 +1000
@@ -48,6 +48,11 @@
 #include 
 
 
+#ifdef CONFIG_PPC
+#include 
+#include 
+#endif
+
 static DEFINE_MUTEX(nvram_mutex);
 static DEFINE_SPINLOCK(nvram_state_lock);
 static int nvram_open_cnt; /* #times opened */
@@ -338,6 +343,36 @@ static long nvram_misc_ioctl(struct file
long ret = -ENOTTY;
 
switch (cmd) {
+#ifdef CONFIG_PPC
+#ifdef CONFIG_PPC_PMAC
+   case OBSOLETE_PMAC_NVRAM_GET_OFFSET:
+   pr_warn("nvram: Using obsolete PMAC_NVRAM_GET_OFFSET ioctl\n");
+   /* fall through */
+   case IOC_NVRAM_GET_OFFSET: {
+   int part, offset;
+
+   if (!machine_is(powermac))
+   return -EINVAL;
+   if (copy_from_user(&part,
+  (void __user *)arg, sizeof(part)) != 0)
+   return -EFAULT;
+   if (part < pmac_nvram_OF || part > pmac_nvram_NR)
+   return -EINVAL;
+   offset = pmac_get_partition(part);
+   if (copy_to_user((void __user *)arg,
+&offset, sizeof(offset)) != 0)
+   return -EFAULT;
+   ret = 0;
+   break;
+   }
+#endif
+   case IOC_NVRAM_SYNC:
+   mutex_lock(&nvram_mutex);
+   if (arch_nvram_ops.sync != NULL)
+   ret = arch_nvram_ops.sync();
+   mutex_unlock(&nvram_mutex);
+   break;
+#else /* !CONFIG_PPC */
case NVRAM_INIT:
/* initialize NVRAM contents and checksum */
if (!capable(CAP_SYS_ADMIN))
@@ -359,6 +394,7 @@ static long nvram_misc_ioctl(struct file
ret = arch_nvram_ops.set_checksum();
mutex_unlock(&nvram_mutex);
break;
+#endif /* CONFIG_PPC */
}
return ret;
 }
@@ -374,6 +410,7 @@ static int nvram_misc_open(struct inode
return -EBUSY;
}
 
+#ifndef CONFIG_PPC
/* Prevent multiple writers if the set_checksum ioctl is implemented. */
if ((arch_nvram_ops.set_checksum != NULL) &&
(file->f_mode & FMODE_WRITE) &&
@@ -381,6 +418,7 @@ static int nvram_misc_open(struct inode
spin_unlock(&nvram_state_lock);
return -EBUSY;
}
+#endif
 
if (file->f_flags & O_EXCL)
nvram_open_mode |= NVRAM_EXCL;
Index: linux/include/linux/nvram.h
===
--- linux.orig/include/linux/nvram.h2015-05-31 11:01:08.0 +1000
+++ linux/include/linux/nvram.h 2015-05-31 11:01:17.0 +1000
@@ -17,8 +17,12 @@ struct nvram_ops {
unsigned char   (*read_byte)(int);
void(*write_byte)(unsigned char, int);
ssize_t (*get_size)(void);
+#ifdef CONFIG_PPC
+   long(*sync)(void);
+#else
long(*set_checksum)(void);
long(*initialize)(void);
+#endif
 };
 
 extern const struct nvram_ops arch_nvram_ops;
Index: linux/arch/powerpc/include/asm/nvram.h
===
--- linux.orig/arch/powerpc/include/asm/nvram.h 2015-05-31 11:01:16.0 
+1000
+++ linux/arch/powerpc/include/asm/nvram.h  2015-05-31 11:01:17.0 
+1000
@@ -78,9 +78,6 @@ extern intpmac_get_partition(int partit
 extern u8  pmac_xpram_read(int xpaddr);
 extern voidpmac_xpram_write(int xpaddr, u8 data);
 
-/* Synchronize NVRAM */
-extern voidnvram_sync(void);
-
 /* Initialize NVRAM OS partition */
 extern int __init nvram_init_os_partition(struct nvram_os_partition *part);
 
Index: linux/arch/powerpc/kernel/setup_32.c
===
--- linux.orig/arch/powerpc/kernel/setup_32.c   2015-05-31 11:01:16.0 
+1000
+++ linux/arch/powerpc/kernel/setup_3

[RFC 21/24] powerpc: Adopt nvram module for PPC64

2015-05-30 Thread Finn Thain
Adopt nvram module to reduce code duplication.

The IOC_NVRAM_GET_OFFSET ioctl as implemented on PPC64 validates the offset
returned by pmac_get_partition(). Add this test to the nvram module.

Note that the old PPC32 generic_nvram module lacked this test.
So when CONFIG_PPC32 && CONFIG_PPC_PMAC, the IOC_NVRAM_GET_OFFSET ioctl
would have returned 0 (always). But when CONFIG_PPC64 && CONFIG_PPC_PMAC,
the IOC_NVRAM_GET_OFFSET ioctl would have returned -1 (which is -EPERM)
when the requested partition was not found.

With this patch, the result is now -ENOENT on both PPC32 and PPC64 when
the requested PowerMac NVRAM partition is not found.

This is a userspace-visible change, in the non-existent partition case,
which would be in an error path for an IOC_NVRAM_GET_OFFSET ioctl syscall.

Signed-off-by: Finn Thain 

---

BTW, the IOC_NVRAM_SYNC ioctl call returns -EINVAL on PPC64. This patch
retains this behaviour though it might be better to actually perform a sync.
Both PPC64 and PPC32 kernels implement ppc_md.nvram_sync() for Core99,
but on PPC64 the ioctl is unimplemented (unlike PPC32).

---
 arch/powerpc/Kconfig |3 
 arch/powerpc/kernel/nvram_64.c   |  203 ---
 arch/powerpc/platforms/powermac/Makefile |5 
 arch/powerpc/platforms/powermac/nvram.c  |2 
 arch/powerpc/platforms/powermac/setup.c  |2 
 drivers/char/nvram.c |2 
 6 files changed, 38 insertions(+), 179 deletions(-)

Index: linux/arch/powerpc/Kconfig
===
--- linux.orig/arch/powerpc/Kconfig 2015-05-31 11:01:22.0 +1000
+++ linux/arch/powerpc/Kconfig  2015-05-31 11:01:24.0 +1000
@@ -177,10 +177,9 @@ config SYSVIPC_COMPAT
depends on COMPAT && SYSVIPC
default y
 
-# All PPC32s use generic nvram driver through ppc_md
 config HAVE_ARCH_NVRAM_OPS
bool
-   default y if PPC32
+   default y
 
 config SCHED_OMIT_FRAME_POINTER
bool
Index: linux/arch/powerpc/kernel/nvram_64.c
===
--- linux.orig/arch/powerpc/kernel/nvram_64.c   2015-05-31 11:00:59.0 
+1000
+++ linux/arch/powerpc/kernel/nvram_64.c2015-05-31 11:01:25.0 
+1000
@@ -7,12 +7,6 @@
  *  2 of the License, or (at your option) any later version.
  *
  * /dev/nvram driver for PPC64
- *
- * This perhaps should live in drivers/char
- *
- * TODO: Split the /dev/nvram part (that one can use
- *   drivers/char/generic_nvram.c) from the arch & partition
- *   parsing code.
  */
 
 #include 
@@ -731,153 +725,6 @@ static void oops_to_nvram(struct kmsg_du
spin_unlock_irqrestore(&lock, flags);
 }
 
-static loff_t dev_nvram_llseek(struct file *file, loff_t offset, int origin)
-{
-   int size;
-
-   if (ppc_md.nvram_size == NULL)
-   return -ENODEV;
-   size = ppc_md.nvram_size();
-
-   switch (origin) {
-   case 1:
-   offset += file->f_pos;
-   break;
-   case 2:
-   offset += size;
-   break;
-   }
-   if (offset < 0)
-   return -EINVAL;
-   file->f_pos = offset;
-   return file->f_pos;
-}
-
-
-static ssize_t dev_nvram_read(struct file *file, char __user *buf,
- size_t count, loff_t *ppos)
-{
-   ssize_t ret;
-   char *tmp = NULL;
-   ssize_t size;
-
-   if (!ppc_md.nvram_size) {
-   ret = -ENODEV;
-   goto out;
-   }
-
-   size = ppc_md.nvram_size();
-   if (size < 0) {
-   ret = size;
-   goto out;
-   }
-
-   if (*ppos >= size) {
-   ret = 0;
-   goto out;
-   }
-
-   count = min_t(size_t, count, size - *ppos);
-   count = min(count, PAGE_SIZE);
-
-   tmp = kmalloc(count, GFP_KERNEL);
-   if (!tmp) {
-   ret = -ENOMEM;
-   goto out;
-   }
-
-   ret = ppc_md.nvram_read(tmp, count, ppos);
-   if (ret <= 0)
-   goto out;
-
-   if (copy_to_user(buf, tmp, ret))
-   ret = -EFAULT;
-
-out:
-   kfree(tmp);
-   return ret;
-
-}
-
-static ssize_t dev_nvram_write(struct file *file, const char __user *buf,
- size_t count, loff_t *ppos)
-{
-   ssize_t ret;
-   char *tmp = NULL;
-   ssize_t size;
-
-   ret = -ENODEV;
-   if (!ppc_md.nvram_size)
-   goto out;
-
-   ret = 0;
-   size = ppc_md.nvram_size();
-   if (*ppos >= size || size < 0)
-   goto out;
-
-   count = min_t(size_t, count, size - *ppos);
-   count = min(count, PAGE_SIZE);
-
-   ret = -ENOMEM;
-   tmp = kmalloc(count, GFP_KERNEL);
-   if (!tmp)
-   goto out;
-
-   ret = -EFAULT;
-   if (copy_from_user(tmp, buf, count))
-   go

[RFC 19/24] powerpc: Remove CONFIG_GENERIC_NVRAM and adopt CONFIG_HAVE_ARCH_NVRAM_OPS

2015-05-30 Thread Finn Thain
Switch PPC32 kernels from the generic_nvram module to the nvram module.

Also fix a theoretical bug where CHRP omits the chrp_nvram_init()
call when CONFIG_NVRAM_MODULE=m.

As before, when CONFIG_PPC && !CONFIG_PPC_PMAC, the IOC_NVRAM_GET_OFFSET
ioctl is unimplemented. For the nvram module, unimplemented ioctls return
-ENOTTY. Whereas, for the superseded generic_nvram module they would
return -EINVAL.

Signed-off-by: Finn Thain 

---

This ioctl change is visible to userspace code but only in an error path.
I didn't find any userspace code that uses the IOC_NVRAM_GET_OFFSET ioctl.

The change in the name of the module is also visible. The module that
implements /dev/nvram on PowerPC now has suitable aliases, i.e.
MODULE_ALIAS_MISCDEV(NVRAM_MINOR);
MODULE_ALIAS("devname:nvram"); 
so that the device special file can be automatically created and the
module automatically loaded when needed. Previously this was not the case.

---
 arch/powerpc/Kconfig|2 +-
 arch/powerpc/kernel/setup_32.c  |2 +-
 arch/powerpc/platforms/chrp/Makefile|2 +-
 arch/powerpc/platforms/chrp/setup.c |2 +-
 arch/powerpc/platforms/powermac/setup.c |3 +--
 drivers/char/Kconfig|   10 ++
 6 files changed, 11 insertions(+), 10 deletions(-)

Index: linux/arch/powerpc/Kconfig
===
--- linux.orig/arch/powerpc/Kconfig 2015-05-31 11:00:59.0 +1000
+++ linux/arch/powerpc/Kconfig  2015-05-31 11:01:22.0 +1000
@@ -178,7 +178,7 @@ config SYSVIPC_COMPAT
default y
 
 # All PPC32s use generic nvram driver through ppc_md
-config GENERIC_NVRAM
+config HAVE_ARCH_NVRAM_OPS
bool
default y if PPC32
 
Index: linux/arch/powerpc/kernel/setup_32.c
===
--- linux.orig/arch/powerpc/kernel/setup_32.c   2015-05-31 11:01:19.0 
+1000
+++ linux/arch/powerpc/kernel/setup_32.c2015-05-31 11:01:22.0 
+1000
@@ -168,7 +168,7 @@ int __init ppc_setup_l3cr(char *str)
 }
 __setup("l3cr=", ppc_setup_l3cr);
 
-#ifdef CONFIG_GENERIC_NVRAM
+#if IS_ENABLED(CONFIG_NVRAM)
 
 static unsigned char ppc_nvram_read_byte(int addr)
 {
Index: linux/arch/powerpc/platforms/chrp/Makefile
===
--- linux.orig/arch/powerpc/platforms/chrp/Makefile 2015-05-31 
11:00:59.0 +1000
+++ linux/arch/powerpc/platforms/chrp/Makefile  2015-05-31 11:01:22.0 
+1000
@@ -1,3 +1,3 @@
 obj-y  += setup.o time.o pegasos_eth.o pci.o
 obj-$(CONFIG_SMP)  += smp.o
-obj-$(CONFIG_NVRAM)+= nvram.o
+obj-$(CONFIG_NVRAM:m=y)+= nvram.o
Index: linux/arch/powerpc/platforms/chrp/setup.c
===
--- linux.orig/arch/powerpc/platforms/chrp/setup.c  2015-05-31 
11:00:59.0 +1000
+++ linux/arch/powerpc/platforms/chrp/setup.c   2015-05-31 11:01:22.0 
+1000
@@ -557,7 +557,7 @@ void __init chrp_init_IRQ(void)
 void __init
 chrp_init2(void)
 {
-#ifdef CONFIG_NVRAM
+#if IS_ENABLED(CONFIG_NVRAM)
chrp_nvram_init();
 #endif
 
Index: linux/arch/powerpc/platforms/powermac/setup.c
===
--- linux.orig/arch/powerpc/platforms/powermac/setup.c  2015-05-31 
11:00:59.0 +1000
+++ linux/arch/powerpc/platforms/powermac/setup.c   2015-05-31 
11:01:22.0 +1000
@@ -321,8 +321,7 @@ static void __init pmac_setup_arch(void)
find_via_pmu();
smu_init();
 
-#if defined(CONFIG_NVRAM) || defined(CONFIG_NVRAM_MODULE) || \
-defined(CONFIG_PPC64)
+#if IS_ENABLED(CONFIG_NVRAM) || defined(CONFIG_PPC64)
pmac_nvram_init();
 #endif
 
Index: linux/drivers/char/Kconfig
===
--- linux.orig/drivers/char/Kconfig 2015-05-31 11:01:11.0 +1000
+++ linux/drivers/char/Kconfig  2015-05-31 11:01:22.0 +1000
@@ -247,7 +247,7 @@ source "drivers/char/hw_random/Kconfig"
 
 config NVRAM
tristate "/dev/nvram support"
-   depends on X86 || (ARM && RTC_DRV_CMOS) || GENERIC_NVRAM || 
HAVE_ARCH_NVRAM_OPS
+   depends on X86 || (ARM && RTC_DRV_CMOS) || HAVE_ARCH_NVRAM_OPS
---help---
  If you say Y here and create a character special file /dev/nvram
  with major number 10 and minor number 144 using mknod ("man mknod"),
@@ -256,9 +256,11 @@ config NVRAM
  and most Ataris.  The actual number of bytes varies, depending on the
  nvram in the system, but is usually 114 (128-14 for the RTC).
 
- This memory is conventionally called "CMOS RAM" on PCs and "NVRAM"
- on Ataris. /dev/nvram may be used to view settings there, or to
- change them (with some uti

[RFC 09/24] char/nvram: Implement NVRAM read/write methods

2015-05-30 Thread Finn Thain
Refactor the RTC "CMOS" NVRAM functions so that they can be used as
arch_nvram_ops methods. Checksumming logic is moved from the misc device
operations to the nvram read/write operations.

This makes the misc device implementation more generic. This also
preserves the locking semantics such that "read if checksum valid" and
"write and update checksum" remain atomic operations.

PPC64 implements byte-range read/write methods which are similar to
file_operations struct methods. Other platforms provide only
byte-at-a-time functions. So the misc device prefers the former but
will fall back on the latter.

Signed-off-by: Finn Thain 

---
 drivers/char/nvram.c |  162 +++
 1 file changed, 114 insertions(+), 48 deletions(-)

Index: linux/drivers/char/nvram.c
===
--- linux.orig/drivers/char/nvram.c 2015-05-31 11:01:08.0 +1000
+++ linux/drivers/char/nvram.c  2015-05-31 11:01:09.0 +1000
@@ -41,6 +41,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -178,9 +179,48 @@ static ssize_t nvram_get_size(void)
return NVRAM_BYTES;
 }
 
+static ssize_t nvram_read(char *buf, size_t count, loff_t *ppos)
+{
+   char *p = buf;
+   loff_t i;
+
+   spin_lock_irq(&rtc_lock);
+   if (!__nvram_check_checksum()) {
+   spin_unlock_irq(&rtc_lock);
+   return -EIO;
+   }
+   for (i = *ppos; count > 0 && i < NVRAM_BYTES; --count, ++i, ++p)
+   *p = __nvram_read_byte(i);
+   spin_unlock_irq(&rtc_lock);
+
+   *ppos = i;
+   return p - buf;
+}
+
+static ssize_t nvram_write(char *buf, size_t count, loff_t *ppos)
+{
+   char *p = buf;
+   loff_t i;
+
+   spin_lock_irq(&rtc_lock);
+   if (!__nvram_check_checksum()) {
+   spin_unlock_irq(&rtc_lock);
+   return -EIO;
+   }
+   for (i = *ppos; count > 0 && i < NVRAM_BYTES; --count, ++i, ++p)
+   __nvram_write_byte(*p, i);
+   __nvram_set_checksum();
+   spin_unlock_irq(&rtc_lock);
+
+   *ppos = i;
+   return p - buf;
+}
+
 const struct nvram_ops arch_nvram_ops = {
.read_byte  = nvram_read_byte,
.write_byte = nvram_write_byte,
+   .read   = nvram_read,
+   .write  = nvram_write,
.get_size   = nvram_get_size,
.set_checksum   = nvram_set_checksum,
.initialize = nvram_initialize,
@@ -215,69 +255,95 @@ static loff_t nvram_misc_llseek(struct f
 static ssize_t nvram_misc_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
 {
-   unsigned char contents[NVRAM_BYTES];
-   unsigned i = *ppos;
-   unsigned char *tmp;
-
-   spin_lock_irq(&rtc_lock);
+   loff_t i;
+   char __user *p = buf;
 
-   if (!__nvram_check_checksum())
-   goto checksum_err;
-
-   for (tmp = contents; count-- > 0 && i < NVRAM_BYTES; ++i, ++tmp)
-   *tmp = __nvram_read_byte(i);
-
-   spin_unlock_irq(&rtc_lock);
-
-   if (copy_to_user(buf, contents, tmp - contents))
+   if (!access_ok(VERIFY_WRITE, buf, count))
return -EFAULT;
+   if (*ppos >= nvram_size)
+   return 0;
 
-   *ppos = i;
-
-   return tmp - contents;
+   /* If the arch provided a byte range read op, use it. Otherwise
+* fall back on the byte-at-a-time accessor.
+*/
+   if (arch_nvram_ops.read != NULL) {
+   char *tmp;
+   ssize_t ret;
+
+   count = min_t(size_t, count, nvram_size - *ppos);
+   count = min_t(size_t, count, PAGE_SIZE);
+
+   tmp = kmalloc(count, GFP_KERNEL);
+   if (!tmp)
+   return -ENOMEM;
+
+   ret = arch_nvram_ops.read(tmp, count, ppos);
+   if (ret <= 0)
+   goto out;
+
+   if (copy_to_user(buf, tmp, ret)) {
+   *ppos -= ret;
+   ret = -EFAULT;
+   }
+
+out:
+   kfree(tmp);
+   return ret;
+   }
 
-checksum_err:
-   spin_unlock_irq(&rtc_lock);
-   return -EIO;
+   for (i = *ppos; count > 0 && i < nvram_size; ++i, ++p, --count)
+   if (__put_user(arch_nvram_ops.read_byte(i), p))
+   return -EFAULT;
+   *ppos = i;
+   return p - buf;
 }
 
 static ssize_t nvram_misc_write(struct file *file, const char __user *buf,
 size_t count, loff_t *ppos)
 {
-   unsigned char contents[NVRAM_BYTES];
-   unsigned i = *ppos;
-   unsigned char *tmp;
-
-   if (i >= NVRAM_BYTES)
-   return 0;   /* Past EOF */
-
-   if (count > NVRA

[RFC 02/24] scsi/atari_scsi: Dont select CONFIG_NVRAM

2015-05-30 Thread Finn Thain
On powerpc, setting CONFIG_NVRAM=n builds a kernel with no NVRAM support.
Setting CONFIG_NVRAM=m enables the /dev/nvram misc device module without
enabling NVRAM support in drivers. Setting CONFIG_NVRAM=y enables the
misc device (built-in) and also enables NVRAM support in drivers.

m68k shares the valkyriefb driver with powerpc, and since that driver uses
NVRAM, it is affected by CONFIG_ATARI_SCSI, because of the use of
"select NVRAM".

Adopt the powerpc convention on m68k to avoid surprises.

Signed-off-by: Finn Thain 

---

This patch temporarily disables CONFIG_NVRAM on Atari, to prevent build
failures when bisecting the rest of this patch series. It gets enabled
again with the introduction of CONFIG_HAVE_ARCH_NVRAM_OPS, once the
nvram_* global functions have been moved to an ops struct.

The removal of "select NVRAM" may mean that some kernel configs (such
as Debian/m68k) may need tweaking.

---
 drivers/char/Kconfig  |5 +
 drivers/scsi/Kconfig  |6 +++---
 drivers/scsi/atari_scsi.c |8 
 3 files changed, 8 insertions(+), 11 deletions(-)

Index: linux/drivers/char/Kconfig
===
--- linux.orig/drivers/char/Kconfig 2015-05-31 11:00:59.0 +1000
+++ linux/drivers/char/Kconfig  2015-05-31 11:01:00.0 +1000
@@ -247,7 +247,7 @@ source "drivers/char/hw_random/Kconfig"
 
 config NVRAM
tristate "/dev/nvram support"
-   depends on ATARI || X86 || (ARM && RTC_DRV_CMOS) || GENERIC_NVRAM
+   depends on X86 || (ARM && RTC_DRV_CMOS) || GENERIC_NVRAM
---help---
  If you say Y here and create a character special file /dev/nvram
  with major number 10 and minor number 144 using mknod ("man mknod"),
@@ -265,9 +265,6 @@ config NVRAM
  should NEVER idly tamper with it. See Ralf Brown's interrupt list
  for a guide to the use of CMOS bytes by your BIOS.
 
- On Atari machines, /dev/nvram is always configured and does not need
- to be selected.
-
  To compile this driver as a module, choose M here: the
  module will be called nvram.
 
Index: linux/drivers/scsi/Kconfig
===
--- linux.orig/drivers/scsi/Kconfig 2015-05-31 11:00:59.0 +1000
+++ linux/drivers/scsi/Kconfig  2015-05-31 11:01:00.0 +1000
@@ -1592,14 +1592,14 @@ config ATARI_SCSI
tristate "Atari native SCSI support"
depends on ATARI && SCSI
select SCSI_SPI_ATTRS
-   select NVRAM
---help---
  If you have an Atari with built-in NCR5380 SCSI controller (TT,
  Falcon, ...) say Y to get it supported. Of course also, if you have
  a compatible SCSI controller (e.g. for Medusa).
 
- To compile this driver as a module, choose M here: the
- module will be called atari_scsi.
+ To compile this driver as a module, choose M here: the module will
+ be called atari_scsi. If you also enable NVRAM support, the SCSI
+ host's ID is taken from the setting in TT RTC NVRAM.
 
  This driver supports both styles of NCR integration into the
  system: the TT style (separate DMA), and the Falcon style (via
Index: linux/drivers/scsi/atari_scsi.c
===
--- linux.orig/drivers/scsi/atari_scsi.c2015-05-31 11:00:59.0 
+1000
+++ linux/drivers/scsi/atari_scsi.c 2015-05-31 11:01:00.0 +1000
@@ -875,9 +875,10 @@ static int __init atari_scsi_probe(struc
if (ATARIHW_PRESENT(TT_SCSI) && setup_sg_tablesize >= 0)
atari_scsi_template.sg_tablesize = setup_sg_tablesize;
 
-   if (setup_hostid >= 0) {
+   if (setup_hostid >= 0)
atari_scsi_template.this_id = setup_hostid & 7;
-   } else {
+#ifdef CONFIG_NVRAM
+   else
/* Test if a host id is set in the NVRam */
if (ATARIHW_PRESENT(TT_CLK) && nvram_check_checksum()) {
unsigned char b = nvram_read_byte(14);
@@ -888,8 +889,7 @@ static int __init atari_scsi_probe(struc
if (b & 0x80)
atari_scsi_template.this_id = b & 7;
}
-   }
-
+#endif
 
 #ifdef REAL_DMA
/* If running on a Falcon and if there's TT-Ram (i.e., more than one


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[RFC 03/24] m68k/atari: Move Atari-specific code out of drivers/char/nvram.c

2015-05-30 Thread Finn Thain
Move the m68k-specific code elsewhere to make the driver generic.

Change the vmode calculation from logical OR to bitwise OR, since it is
obviously wrong.

Signed-off-by: Finn Thain 

---

BTW, I didn't change the SCSI ID location in NVRAM. This code says 16
whereas atari_scsi says 14. Which one is correct?

---
 arch/m68k/atari/Makefile |2 
 arch/m68k/atari/nvram.c  |  255 ++
 drivers/char/nvram.c |  280 +--
 3 files changed, 292 insertions(+), 245 deletions(-)

Index: linux/arch/m68k/atari/nvram.c
===
--- /dev/null   1970-01-01 00:00:00.0 +
+++ linux/arch/m68k/atari/nvram.c   2015-05-31 11:01:01.0 +1000
@@ -0,0 +1,255 @@
+/*
+ * CMOS/NV-RAM driver for Atari. Adapted from drivers/char/nvram.c.
+ * Copyright (C) 1997 Roman Hodek 
+ * idea by and with help from Richard Jelinek 
+ * Portions copyright (c) 2001,2002 Sun Microsystems (thoc...@sun.com)
+ * Further contributions from Cesar Barros, Erik Gilling, Tim Hockin and
+ * Wim Van Sebroeck.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define NVRAM_BYTES50
+
+/* It is worth noting that these functions all access bytes of general
+ * purpose memory in the NVRAM - that is to say, they all add the
+ * NVRAM_FIRST_BYTE offset. Pass them offsets into NVRAM as if you did not
+ * know about the RTC cruft.
+ */
+
+/* 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
+ * don't want two different things trying to get to it at once. (e.g. the
+ * periodic 11 min sync from kernel/time/ntp.c vs. this driver.)
+ */
+
+unsigned char __nvram_read_byte(int i)
+{
+   return CMOS_READ(NVRAM_FIRST_BYTE + i);
+}
+
+unsigned char nvram_read_byte(int i)
+{
+   unsigned long flags;
+   unsigned char c;
+
+   spin_lock_irqsave(&rtc_lock, flags);
+   c = __nvram_read_byte(i);
+   spin_unlock_irqrestore(&rtc_lock, flags);
+   return c;
+}
+EXPORT_SYMBOL(nvram_read_byte);
+
+/* This races nicely with trying to read with checksum checking */
+void __nvram_write_byte(unsigned char c, int i)
+{
+   CMOS_WRITE(c, NVRAM_FIRST_BYTE + i);
+}
+
+void nvram_write_byte(unsigned char c, int i)
+{
+   unsigned long flags;
+
+   spin_lock_irqsave(&rtc_lock, flags);
+   __nvram_write_byte(c, i);
+   spin_unlock_irqrestore(&rtc_lock, flags);
+}
+
+/* On Ataris, the checksum is over all bytes except the checksum bytes
+ * themselves; these are at the very end.
+ */
+#define ATARI_CKS_RANGE_START  0
+#define ATARI_CKS_RANGE_END47
+#define ATARI_CKS_LOC  48
+
+int __nvram_check_checksum(void)
+{
+   int i;
+   unsigned char sum = 0;
+
+   for (i = ATARI_CKS_RANGE_START; i <= ATARI_CKS_RANGE_END; ++i)
+   sum += __nvram_read_byte(i);
+   return (__nvram_read_byte(ATARI_CKS_LOC) == (~sum & 0xff)) &&
+  (__nvram_read_byte(ATARI_CKS_LOC + 1) == (sum & 0xff));
+}
+
+int nvram_check_checksum(void)
+{
+   unsigned long flags;
+   int rv;
+
+   spin_lock_irqsave(&rtc_lock, flags);
+   rv = __nvram_check_checksum();
+   spin_unlock_irqrestore(&rtc_lock, flags);
+   return rv;
+}
+EXPORT_SYMBOL(nvram_check_checksum);
+
+static void __nvram_set_checksum(void)
+{
+   int i;
+   unsigned char sum = 0;
+
+   for (i = ATARI_CKS_RANGE_START; i <= ATARI_CKS_RANGE_END; ++i)
+   sum += __nvram_read_byte(i);
+   __nvram_write_byte(~sum, ATARI_CKS_LOC);
+   __nvram_write_byte(sum, ATARI_CKS_LOC + 1);
+}
+
+#ifdef CONFIG_PROC_FS
+static struct {
+   unsigned char val;
+   char *name;
+} boot_prefs[] = {
+   { 0x80, "TOS" },
+   { 0x40, "ASV" },
+   { 0x20, "NetBSD (?)" },
+   { 0x10, "Linux" },
+   { 0x00, "unspecified" },
+};
+
+static char *languages[] = {
+   "English (US)",
+   "German",
+   "French",
+   "English (UK)",
+   "Spanish",
+   "Italian",
+   "6 (undefined)",
+   "Swiss (French)",
+   "Swiss (German)",
+};
+
+static char *dateformat[] = {
+   "MM%cDD%cYY",
+   "DD%cMM%cYY",
+   "YY%cMM%cDD",
+   "YY%cDD%cMM",
+   "4 (undefined)",
+   "5 (undefined)",
+   "6 (undefined)",
+   "7 (undefined)",
+};
+
+static char *colors[] = {
+   "2", "4", "16", "256", "65536", "??", "??", "??"
+};
+
+static void atari_nvram_proc_read(unsigned char *nvram, s

Re: [RFC 07/24] x86/thinkpad_acpi: Use arch_nvram_ops methods instead of nvram_read_byte() and nvram_write_byte()

2015-05-30 Thread Finn Thain

On Sun, 31 May 2015, Henrique de Moraes Holschuh wrote:

> On Sun, 31 May 2015, Finn Thain wrote:
> > Make use of arch_nvram_ops in the thinkpad_acpi driver so that the 
> > nvram_* function exports can be removed.
> > 
> > This patch series was tested on a ThinkPad T43.
> 
> Can you describe how you did the testing?  A specific procedure is 
> required to test the hotkey NVRAM polling codepaths (which will read 
> several NVRAM bytes @10Hz by default) in a T43...
> 
> > Signed-off-by: Finn Thain 
> 
> The patch looks correct, so I don't expect any problems.
> 
> Provided that your test procedure did enable hotkey NVRAM polling in the 
> T43 and your hotkeys all still worked fine, you have my Acked-by.

The procedure I used was this,

1. $ xev
2. # rmmod thinkpad_acpi
3. Press  key and confirm that xev does not report any
   events.
4. # modprobe thinkpad_acpi
5. Press  key and confirm that xev now reports the key press 
   events.

Is this sufficient?

Regards,
Finn

> 
> > ---
> >  drivers/platform/x86/thinkpad_acpi.c |   20 ++--
> >  1 file changed, 10 insertions(+), 10 deletions(-)
> > 
> > Index: linux/drivers/platform/x86/thinkpad_acpi.c
> > ===
> > --- linux.orig/drivers/platform/x86/thinkpad_acpi.c 2015-05-31 
> > 11:00:59.0 +1000
> > +++ linux/drivers/platform/x86/thinkpad_acpi.c  2015-05-31 
> > 11:01:07.0 +1000
> > @@ -2311,30 +2311,30 @@ static void hotkey_read_nvram(struct tp_
> > u8 d;
> >  
> > if (m & TP_NVRAM_HKEY_GROUP_HK2) {
> > -   d = nvram_read_byte(TP_NVRAM_ADDR_HK2);
> > +   d = arch_nvram_ops.read_byte(TP_NVRAM_ADDR_HK2);
> > n->thinkpad_toggle = !!(d & TP_NVRAM_MASK_HKT_THINKPAD);
> > n->zoom_toggle = !!(d & TP_NVRAM_MASK_HKT_ZOOM);
> > n->display_toggle = !!(d & TP_NVRAM_MASK_HKT_DISPLAY);
> > n->hibernate_toggle = !!(d & TP_NVRAM_MASK_HKT_HIBERNATE);
> > }
> > if (m & TP_ACPI_HKEY_THNKLGHT_MASK) {
> > -   d = nvram_read_byte(TP_NVRAM_ADDR_THINKLIGHT);
> > +   d = arch_nvram_ops.read_byte(TP_NVRAM_ADDR_THINKLIGHT);
> > n->thinklight_toggle = !!(d & TP_NVRAM_MASK_THINKLIGHT);
> > }
> > if (m & TP_ACPI_HKEY_DISPXPAND_MASK) {
> > -   d = nvram_read_byte(TP_NVRAM_ADDR_VIDEO);
> > +   d = arch_nvram_ops.read_byte(TP_NVRAM_ADDR_VIDEO);
> > n->displayexp_toggle =
> > !!(d & TP_NVRAM_MASK_HKT_DISPEXPND);
> > }
> > if (m & TP_NVRAM_HKEY_GROUP_BRIGHTNESS) {
> > -   d = nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS);
> > +   d = arch_nvram_ops.read_byte(TP_NVRAM_ADDR_BRIGHTNESS);
> > n->brightness_level = (d & TP_NVRAM_MASK_LEVEL_BRIGHTNESS)
> > >> TP_NVRAM_POS_LEVEL_BRIGHTNESS;
> > n->brightness_toggle =
> > !!(d & TP_NVRAM_MASK_HKT_BRIGHTNESS);
> > }
> > if (m & TP_NVRAM_HKEY_GROUP_VOLUME) {
> > -   d = nvram_read_byte(TP_NVRAM_ADDR_MIXER);
> > +   d = arch_nvram_ops.read_byte(TP_NVRAM_ADDR_MIXER);
> > n->volume_level = (d & TP_NVRAM_MASK_LEVEL_VOLUME)
> > >> TP_NVRAM_POS_LEVEL_VOLUME;
> > n->mute = !!(d & TP_NVRAM_MASK_MUTE);
> > @@ -6153,7 +6153,7 @@ static unsigned int tpacpi_brightness_nv
> >  {
> > u8 lnvram;
> >  
> > -   lnvram = (nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS)
> > +   lnvram = (arch_nvram_ops.read_byte(TP_NVRAM_ADDR_BRIGHTNESS)
> >   & TP_NVRAM_MASK_LEVEL_BRIGHTNESS)
> >   >> TP_NVRAM_POS_LEVEL_BRIGHTNESS;
> > lnvram &= bright_maxlvl;
> > @@ -6178,7 +6178,7 @@ static void tpacpi_brightness_checkpoint
> > if (unlikely(!acpi_ec_read(TP_EC_BACKLIGHT, &lec)))
> > goto unlock;
> > lec &= TP_EC_BACKLIGHT_LVLMSK;
> > -   b_nvram = nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS);
> > +   b_nvram = arch_nvram_ops.read_byte(TP_NVRAM_ADDR_BRIGHTNESS);
> >  
> > if (lec != ((b_nvram & TP_NVRAM_MASK_LEVEL_BRIGHTNESS)
> >  >> TP_NVRAM_POS_LEVEL_BRIGHTNESS)) {
> > @@ -6186,7 +6186,7 @@ static void tpacpi_brightness_checkpoint
> > b_nvram &= ~(TP_NVRAM_MASK_LEVEL_BRIGHTNESS <<
> > TP_NVRAM_POS_LEVEL_BRIGHTNESS);
> 

Re: [RFC 24/24] m68k: Dispatch nvram_ops calls to Atari or Mac functions

2015-06-02 Thread Finn Thain

On Mon, 1 Jun 2015, Geert Uytterhoeven wrote:

> > Index: linux/arch/m68k/atari/nvram.c
> > ===
> > --- linux.orig/arch/m68k/atari/nvram.c  2015-05-31 11:01:21.0
> > +1000
> > +++ linux/arch/m68k/atari/nvram.c   2015-05-31 11:01:29.0
> > +1000
> > @@ -73,7 +73,7 @@ static void __nvram_set_checksum(void)
> 
> > +#ifndef CONFIG_MAC
> >  const struct nvram_ops arch_nvram_ops = {
> > -   .read   = nvram_read,
> > -   .write  = nvram_write,
> > -   .get_size   = nvram_get_size,
> > -   .set_checksum   = nvram_set_checksum,
> > -   .initialize = nvram_initialize,
> > +   .read   = atari_nvram_read,
> > +   .write  = atari_nvram_write,
> > +   .get_size   = atari_nvram_get_size,
> > +   .set_checksum   = atari_nvram_set_checksum,
> > +   .initialize = atari_nvram_initialize,
> >  };
> >  EXPORT_SYMBOL(arch_nvram_ops);
> > +#endif
> 
> IMHO, the #ifdef is ugly.
> 
> >  #ifdef CONFIG_PROC_FS
> >  static struct {
> > Index: linux/arch/m68k/mac/misc.c
> > ===
> > --- linux.orig/arch/m68k/mac/misc.c 2015-05-31 11:01:28.0 +1000
> > +++ linux/arch/m68k/mac/misc.c  2015-05-31 11:01:29.0 +1000
> > @@ -489,7 +489,7 @@ void pmu_shutdown(void)
> 
> > +#ifndef CONFIG_ATARI
> >  const struct nvram_ops arch_nvram_ops = {
> > .read_byte  = mac_pram_read_byte,
> > .write_byte = mac_pram_write_byte,
> > .get_size   = mac_pram_get_size,
> >  };
> >  EXPORT_SYMBOL(arch_nvram_ops);
> > +#endif
> >  #endif /* CONFIG_NVRAM */
> 
> Same here.

We could eliminate the Atari and Mac definitions of arch_nvram_ops, and 
define the struct only in arch/m68k/kernel/setup_mm.c -- at the cost of 
some bloat (see below).

> 
> > Index: linux/arch/m68k/kernel/setup_mm.c
> > ===
> > --- linux.orig/arch/m68k/kernel/setup_mm.c  2015-05-31 
> > 11:00:59.0 +1000
> > +++ linux/arch/m68k/kernel/setup_mm.c   2015-05-31 11:01:29.0 +1000
> 
> > @@ -568,3 +572,88 @@ static int __init adb_probe_sync_enable
> >
> >  __setup("adb_sync", adb_probe_sync_enable);
> >  #endif /* CONFIG_ADB */
> > +
> > +#if IS_ENABLED(CONFIG_NVRAM) && defined(CONFIG_ATARI) && 
> > defined(CONFIG_MAC)
> 
> Likewise.

Given the Kconfig constraints, this can be simplified to 
IS_ENABLED(CONFIG_NVRAM). Will fix.

> 
> > +static ssize_t m68k_nvram_read(char *buf, size_t count, loff_t *ppos)
> > +{
> > +   if (MACH_IS_ATARI)
> > +   return atari_nvram_read(buf, count, ppos);
> > +   else if (MACH_IS_MAC) {
> > +   ssize_t size = mac_pram_get_size();
> > +   char *p = buf;
> > +   loff_t i;
> > +
> > +   for (i = *ppos; count > 0 && i < size; --count, ++i, ++p)
> > +   *p = mac_pram_read_byte(i);
> > +
> > +   *ppos = i;
> > +   return p - buf;
> > +   }
> > +   return -EINVAL;
> 
> Isn't this handled already by the nvram core, based on the available 
> operations in nvram_ops?

A multi-platform kernel can't set inappropriate ops to NULL at run-time, 
because the struct is const. (Maybe we can on m68k? That doesn't mean it 
is good style.)

There isn't any nvram core as such. The nvram misc device is just one of 
many callers of the functions in the ops struct.

(The read_byte and write_byte loops above that also appear in the misc 
device are different in that latter loops involve userspace. So I have not 
factored them out. If it were possible to refactor, the shared code would 
have to go into include/linux/nvram.h.)

> Same for the other nvram abstractions in this file.

Again, a multi-platform kernel needs them. E.g. a kernel eith CONFIG_ATARI 
&& CONFIG_MAC has to support checksummed Atari NVRAM. If you boot it on a 
Mac, you need the m68k_nvram_set_checksum() and m68k_nvram_initialize() 
stubs.

Whereas, a single-platform kernel, having CONFIG_MAC && !CONFIG_ATARI, you 
don't define the .set_checksum and .initialize ops at all. (Like any PPC32 
kernel, BTW.)

> 
> > +const struct nvram_ops arch_nvram_ops = {
> > +   .read   = m68k_nvram_read,
> > +   .write  = m68k_nvram_write,
> > +   .read_byte  = m68k_nvram_read_byte,
> > +   .write_byte = m68k_nvram_write_byte,
> > +   .get_size   = m68k_nvram_get_size,
> > +   .set_checksum   = m68k_nvram_set_checksum,
> > +   .initialize = m68k_nvram_initialize,
> > +};
> > +EXPORT_SYMBOL(arch_nvram_ops);
> 
> Can't you just fill in the mach specific pointers in the generic 
> structure, and be done with it?

Not at compile-time. Hence the mach-independent functions, i.e. the 
wrapper functions that dispatch to the mach-specific functions.

The wrappers and stubs only add bloat in a single-platfor

Re: [RFC 07/24] x86/thinkpad_acpi: Use arch_nvram_ops methods instead of nvram_read_byte() and nvram_write_byte()

2015-06-03 Thread Finn Thain

On Tue, 2 Jun 2015, Darren Hart wrote:

> On Tue, Jun 02, 2015 at 07:09:28AM -0300, Henrique de Moraes Holschuh 
> wrote:
> > Test results were sent to me privately, and they are correct, so...
> > 
> 
> Finn, unless there is some compelling reason not to - like they are MBs 
> worth of data, please submit these to the list in the future so we have 
> them for reference.

Sure. Those results were just confirmation that this patch series doesn't 
affect input events read directly from 
/dev/input/by-path/platform-thinkpad_acpi-event
given the the hotkey_source_mask settings discussed in this thread.

> 
> > Acked-by: Henrique de Moraes Holschuh 
> 
> I'm fine with the changes, but they need to be submitted with the other 
> changes as this one change cannot compile independently in my tree.
> 
> Finn, please work with whomever is pulling the series to include this in 
> their pull request.

Right.

> 
> Reviewed-by: Darren Hart 

Thanks for your review.

-- 
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[RFC v2 01/24] macintosh/nvram: Remove as unused

2015-06-14 Thread Finn Thain
Signed-off-by: Finn Thain 
Acked-by: Geert Uytterhoeven 

---
 drivers/macintosh/nvram.c |  130 --
 1 file changed, 130 deletions(-)

Index: linux/drivers/macintosh/nvram.c
===
--- linux.orig/drivers/macintosh/nvram.c2015-06-14 17:45:34.0 
+1000
+++ /dev/null   1970-01-01 00:00:00.0 +
@@ -1,130 +0,0 @@
-/*
- * /dev/nvram driver for Power Macintosh.
- */
-
-#define NVRAM_VERSION "1.0"
-
-#include 
-
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-
-#define NVRAM_SIZE 8192
-
-static loff_t nvram_llseek(struct file *file, loff_t offset, int origin)
-{
-   switch (origin) {
-   case 0:
-   break;
-   case 1:
-   offset += file->f_pos;
-   break;
-   case 2:
-   offset += NVRAM_SIZE;
-   break;
-   default:
-   offset = -1;
-   }
-   if (offset < 0)
-   return -EINVAL;
-
-   file->f_pos = offset;
-   return file->f_pos;
-}
-
-static ssize_t read_nvram(struct file *file, char __user *buf,
- size_t count, loff_t *ppos)
-{
-   unsigned int i;
-   char __user *p = buf;
-
-   if (!access_ok(VERIFY_WRITE, buf, count))
-   return -EFAULT;
-   if (*ppos >= NVRAM_SIZE)
-   return 0;
-   for (i = *ppos; count > 0 && i < NVRAM_SIZE; ++i, ++p, --count)
-   if (__put_user(nvram_read_byte(i), p))
-   return -EFAULT;
-   *ppos = i;
-   return p - buf;
-}
-
-static ssize_t write_nvram(struct file *file, const char __user *buf,
-  size_t count, loff_t *ppos)
-{
-   unsigned int i;
-   const char __user *p = buf;
-   char c;
-
-   if (!access_ok(VERIFY_READ, buf, count))
-   return -EFAULT;
-   if (*ppos >= NVRAM_SIZE)
-   return 0;
-   for (i = *ppos; count > 0 && i < NVRAM_SIZE; ++i, ++p, --count) {
-   if (__get_user(c, p))
-   return -EFAULT;
-   nvram_write_byte(c, i);
-   }
-   *ppos = i;
-   return p - buf;
-}
-
-static long nvram_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
-   switch(cmd) {
-   case PMAC_NVRAM_GET_OFFSET:
-   {
-   int part, offset;
-   if (copy_from_user(&part, (void __user*)arg, 
sizeof(part)) != 0)
-   return -EFAULT;
-   if (part < pmac_nvram_OF || part > pmac_nvram_NR)
-   return -EINVAL;
-   offset = pmac_get_partition(part);
-   if (copy_to_user((void __user*)arg, &offset, 
sizeof(offset)) != 0)
-   return -EFAULT;
-   break;
-   }
-
-   default:
-   return -EINVAL;
-   }
-
-   return 0;
-}
-
-const struct file_operations nvram_fops = {
-   .owner  = THIS_MODULE,
-   .llseek = nvram_llseek,
-   .read   = read_nvram,
-   .write  = write_nvram,
-   .unlocked_ioctl = nvram_ioctl,
-};
-
-static struct miscdevice nvram_dev = {
-   NVRAM_MINOR,
-   "nvram",
-   &nvram_fops
-};
-
-int __init nvram_init(void)
-{
-   printk(KERN_INFO "Macintosh non-volatile memory driver v%s\n",
-   NVRAM_VERSION);
-   return misc_register(&nvram_dev);
-}
-
-void __exit nvram_cleanup(void)
-{
-misc_deregister( &nvram_dev );
-}
-
-module_init(nvram_init);
-module_exit(nvram_cleanup);
-MODULE_LICENSE("GPL");


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[RFC v2 02/24] scsi/atari_scsi: Dont select CONFIG_NVRAM

2015-06-14 Thread Finn Thain
On powerpc, setting CONFIG_NVRAM=n builds a kernel with no NVRAM support.
Setting CONFIG_NVRAM=m enables the /dev/nvram misc device module without
enabling NVRAM support in drivers. Setting CONFIG_NVRAM=y enables the
misc device (built-in) and also enables NVRAM support in drivers.

m68k shares the valkyriefb driver with powerpc, and since that driver uses
NVRAM, it is affected by CONFIG_ATARI_SCSI, because of the use of
"select NVRAM".

Adopt the powerpc convention on m68k to avoid surprises.

Signed-off-by: Finn Thain 

---

This patch temporarily disables CONFIG_NVRAM on Atari, to prevent build
failures when bisecting the rest of this patch series. It gets enabled
again with the introduction of CONFIG_HAVE_ARCH_NVRAM_OPS, once the
nvram_* global functions have been moved to an ops struct.

The removal of "select NVRAM" may mean that some kernel configs (such
as Debian/m68k) may need tweaking.

---
 drivers/char/Kconfig  |5 +
 drivers/scsi/Kconfig  |6 +++---
 drivers/scsi/atari_scsi.c |8 
 3 files changed, 8 insertions(+), 11 deletions(-)

Index: linux/drivers/char/Kconfig
===
--- linux.orig/drivers/char/Kconfig 2015-06-14 17:45:34.0 +1000
+++ linux/drivers/char/Kconfig  2015-06-14 17:45:35.0 +1000
@@ -247,7 +247,7 @@ source "drivers/char/hw_random/Kconfig"
 
 config NVRAM
tristate "/dev/nvram support"
-   depends on ATARI || X86 || (ARM && RTC_DRV_CMOS) || GENERIC_NVRAM
+   depends on X86 || (ARM && RTC_DRV_CMOS) || GENERIC_NVRAM
---help---
  If you say Y here and create a character special file /dev/nvram
  with major number 10 and minor number 144 using mknod ("man mknod"),
@@ -265,9 +265,6 @@ config NVRAM
  should NEVER idly tamper with it. See Ralf Brown's interrupt list
  for a guide to the use of CMOS bytes by your BIOS.
 
- On Atari machines, /dev/nvram is always configured and does not need
- to be selected.
-
  To compile this driver as a module, choose M here: the
  module will be called nvram.
 
Index: linux/drivers/scsi/Kconfig
===
--- linux.orig/drivers/scsi/Kconfig 2015-06-14 17:45:34.0 +1000
+++ linux/drivers/scsi/Kconfig  2015-06-14 17:45:35.0 +1000
@@ -1592,14 +1592,14 @@ config ATARI_SCSI
tristate "Atari native SCSI support"
depends on ATARI && SCSI
select SCSI_SPI_ATTRS
-   select NVRAM
---help---
  If you have an Atari with built-in NCR5380 SCSI controller (TT,
  Falcon, ...) say Y to get it supported. Of course also, if you have
  a compatible SCSI controller (e.g. for Medusa).
 
- To compile this driver as a module, choose M here: the
- module will be called atari_scsi.
+ To compile this driver as a module, choose M here: the module will
+ be called atari_scsi. If you also enable NVRAM support, the SCSI
+ host's ID is taken from the setting in TT RTC NVRAM.
 
  This driver supports both styles of NCR integration into the
  system: the TT style (separate DMA), and the Falcon style (via
Index: linux/drivers/scsi/atari_scsi.c
===
--- linux.orig/drivers/scsi/atari_scsi.c2015-06-14 17:45:34.0 
+1000
+++ linux/drivers/scsi/atari_scsi.c 2015-06-14 17:45:35.0 +1000
@@ -875,9 +875,10 @@ static int __init atari_scsi_probe(struc
if (ATARIHW_PRESENT(TT_SCSI) && setup_sg_tablesize >= 0)
atari_scsi_template.sg_tablesize = setup_sg_tablesize;
 
-   if (setup_hostid >= 0) {
+   if (setup_hostid >= 0)
atari_scsi_template.this_id = setup_hostid & 7;
-   } else {
+#ifdef CONFIG_NVRAM
+   else
/* Test if a host id is set in the NVRam */
if (ATARIHW_PRESENT(TT_CLK) && nvram_check_checksum()) {
unsigned char b = nvram_read_byte(14);
@@ -888,8 +889,7 @@ static int __init atari_scsi_probe(struc
if (b & 0x80)
atari_scsi_template.this_id = b & 7;
}
-   }
-
+#endif
 
 #ifdef REAL_DMA
/* If running on a Falcon and if there's TT-Ram (i.e., more than one


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[RFC v2 00/24] Re-use nvram module

2015-06-14 Thread Finn Thain

The generic NVRAM module, drivers/char/generic_nvram, implements a
/dev/nvram misc device. It is used only by 32-bit PowerPC platforms and
isn't generic enough to be more widely used.

The RTC NVRAM module, drivers/char/nvram, also implements a /dev/nvram
misc device. It is used by x86, ARM and m68k.

The former module cannot be used on x86, ARM or m68k because it
cannot co-exist with the latter module, partly due to the Kconfig logic.

It is possible to modify the modules so that one kernel binary could
have either, neither or both. However, automatically loading the
appropriate module is then impossible; if both provide the
char-major-10-144 alias then the wrong module will end up being loaded.
Hence a multi-platform kernel binary needs a single generic nvram module
with alias char-major-10-144.

Therefore, drivers/char/nvram.c should be made more generic and the
arch-specific code therein should be moved to a more appropriate
place under arch/. Also, drivers/char/generic_nvram.c should be removed
to reduce code duplication.

In this patch series, Atari-specific code is moved from the nvram module
to arch/m68k/atari. More arch-specific code in the nvram module could
be moved, probably to arch/x86, but it is difficult to determine just
what code is relevant to ARM platforms and what code is x86-only.

In addressing code duplication, this patch series removes three
inconsistent /dev/nvram misc device implementations. One of these,
drivers/macintosh/nvram.c is entirely unused already. The other two,
drivers/char/generic_nvram.c and the misc device implementation in
arch/powerpc/kernel/nvram_64.c, are replaced by drivers/char/nvram.c.

A benefit of this work is better consistency -- between PPC32 and PPC64
as well as between PPC_PMAC and MAC. This new uniformity does have
implications for userspace, that is, some error codes for some ioctl calls
become consistent on all PowerPC platforms.

The drivers/char/nvram module becomes sufficiently generic to be useful
to other platforms and architectures, besides those with "CMOS" RTC. At the
end of this patch series the module is adopted by the m68k Mac port, which
already has PRAM access functions but lacks the /dev/nvram misc device.

This patch series has been compile-tested for arm, m68k, powerpc and x86.
The nvram and thinkpad_acpi modules were regression tested on a ThinkPad T43.
The /dev/nvram functionality was also regression tested on a G3 PowerMac.
The nvram module was also tested on a PowerBook 520 and Quadra 650.
Note that my testing doesn't cover PPC64 or Atari.

---
 arch/m68k/Kconfig  |3 
 arch/m68k/atari/Makefile   |2 
 arch/m68k/atari/nvram.c|  291 +++
 arch/m68k/kernel/setup_mm.c|  107 
 arch/m68k/mac/misc.c   |  144 +++--
 arch/powerpc/Kconfig   |5 
 arch/powerpc/include/asm/nvram.h   |9 
 arch/powerpc/kernel/nvram_64.c |  203 +--
 arch/powerpc/kernel/setup_32.c |   27 -
 arch/powerpc/platforms/chrp/Makefile   |2 
 arch/powerpc/platforms/chrp/nvram.c|   14 
 arch/powerpc/platforms/chrp/setup.c|2 
 arch/powerpc/platforms/powermac/Makefile   |5 
 arch/powerpc/platforms/powermac/nvram.c|9 
 arch/powerpc/platforms/powermac/setup.c|3 
 drivers/char/Kconfig   |   13 
 drivers/char/Makefile  |6 
 drivers/char/generic_nvram.c   |  174 --
 drivers/char/nvram.c   |  742 -
 drivers/macintosh/nvram.c  |  130 -
 drivers/platform/x86/thinkpad_acpi.c   |   20 
 drivers/scsi/Kconfig   |6 
 drivers/scsi/atari_scsi.c  |   16 
 drivers/video/fbdev/controlfb.c|4 
 drivers/video/fbdev/imsttfb.c  |7 
 drivers/video/fbdev/matrox/matroxfb_base.c |4 
 drivers/video/fbdev/platinumfb.c   |4 
 drivers/video/fbdev/valkyriefb.c   |4 
 include/linux/nvram.h  |   23 
 include/uapi/linux/pmu.h   |2 
 30 files changed, 937 insertions(+), 1044 deletions(-)




___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[RFC v2 03/24] m68k/atari: Move Atari-specific code out of drivers/char/nvram.c

2015-06-14 Thread Finn Thain
Move the m68k-specific code elsewhere to make the driver generic.

Change the vmode calculation from logical OR to bitwise OR, since it is
obviously wrong.

Signed-off-by: Finn Thain 

---

BTW, I didn't change the SCSI ID location in NVRAM. This code says 16
whereas atari_scsi says 14. Which one is correct?

---
 arch/m68k/atari/Makefile |2 
 arch/m68k/atari/nvram.c  |  255 ++
 drivers/char/nvram.c |  280 +--
 3 files changed, 292 insertions(+), 245 deletions(-)

Index: linux/arch/m68k/atari/nvram.c
===
--- /dev/null   1970-01-01 00:00:00.0 +
+++ linux/arch/m68k/atari/nvram.c   2015-06-14 17:45:37.0 +1000
@@ -0,0 +1,255 @@
+/*
+ * CMOS/NV-RAM driver for Atari. Adapted from drivers/char/nvram.c.
+ * Copyright (C) 1997 Roman Hodek 
+ * idea by and with help from Richard Jelinek 
+ * Portions copyright (c) 2001,2002 Sun Microsystems (thoc...@sun.com)
+ * Further contributions from Cesar Barros, Erik Gilling, Tim Hockin and
+ * Wim Van Sebroeck.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define NVRAM_BYTES50
+
+/* It is worth noting that these functions all access bytes of general
+ * purpose memory in the NVRAM - that is to say, they all add the
+ * NVRAM_FIRST_BYTE offset. Pass them offsets into NVRAM as if you did not
+ * know about the RTC cruft.
+ */
+
+/* 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
+ * don't want two different things trying to get to it at once. (e.g. the
+ * periodic 11 min sync from kernel/time/ntp.c vs. this driver.)
+ */
+
+unsigned char __nvram_read_byte(int i)
+{
+   return CMOS_READ(NVRAM_FIRST_BYTE + i);
+}
+
+unsigned char nvram_read_byte(int i)
+{
+   unsigned long flags;
+   unsigned char c;
+
+   spin_lock_irqsave(&rtc_lock, flags);
+   c = __nvram_read_byte(i);
+   spin_unlock_irqrestore(&rtc_lock, flags);
+   return c;
+}
+EXPORT_SYMBOL(nvram_read_byte);
+
+/* This races nicely with trying to read with checksum checking */
+void __nvram_write_byte(unsigned char c, int i)
+{
+   CMOS_WRITE(c, NVRAM_FIRST_BYTE + i);
+}
+
+void nvram_write_byte(unsigned char c, int i)
+{
+   unsigned long flags;
+
+   spin_lock_irqsave(&rtc_lock, flags);
+   __nvram_write_byte(c, i);
+   spin_unlock_irqrestore(&rtc_lock, flags);
+}
+
+/* On Ataris, the checksum is over all bytes except the checksum bytes
+ * themselves; these are at the very end.
+ */
+#define ATARI_CKS_RANGE_START  0
+#define ATARI_CKS_RANGE_END47
+#define ATARI_CKS_LOC  48
+
+int __nvram_check_checksum(void)
+{
+   int i;
+   unsigned char sum = 0;
+
+   for (i = ATARI_CKS_RANGE_START; i <= ATARI_CKS_RANGE_END; ++i)
+   sum += __nvram_read_byte(i);
+   return (__nvram_read_byte(ATARI_CKS_LOC) == (~sum & 0xff)) &&
+  (__nvram_read_byte(ATARI_CKS_LOC + 1) == (sum & 0xff));
+}
+
+int nvram_check_checksum(void)
+{
+   unsigned long flags;
+   int rv;
+
+   spin_lock_irqsave(&rtc_lock, flags);
+   rv = __nvram_check_checksum();
+   spin_unlock_irqrestore(&rtc_lock, flags);
+   return rv;
+}
+EXPORT_SYMBOL(nvram_check_checksum);
+
+static void __nvram_set_checksum(void)
+{
+   int i;
+   unsigned char sum = 0;
+
+   for (i = ATARI_CKS_RANGE_START; i <= ATARI_CKS_RANGE_END; ++i)
+   sum += __nvram_read_byte(i);
+   __nvram_write_byte(~sum, ATARI_CKS_LOC);
+   __nvram_write_byte(sum, ATARI_CKS_LOC + 1);
+}
+
+#ifdef CONFIG_PROC_FS
+static struct {
+   unsigned char val;
+   char *name;
+} boot_prefs[] = {
+   { 0x80, "TOS" },
+   { 0x40, "ASV" },
+   { 0x20, "NetBSD (?)" },
+   { 0x10, "Linux" },
+   { 0x00, "unspecified" },
+};
+
+static char *languages[] = {
+   "English (US)",
+   "German",
+   "French",
+   "English (UK)",
+   "Spanish",
+   "Italian",
+   "6 (undefined)",
+   "Swiss (French)",
+   "Swiss (German)",
+};
+
+static char *dateformat[] = {
+   "MM%cDD%cYY",
+   "DD%cMM%cYY",
+   "YY%cMM%cDD",
+   "YY%cDD%cMM",
+   "4 (undefined)",
+   "5 (undefined)",
+   "6 (undefined)",
+   "7 (undefined)",
+};
+
+static char *colors[] = {
+   "2", "4", "16", "256", "65536", "??", "??", "??"
+};
+
+static void atari_nvram_proc_read(unsigned char *nvram, s

[RFC v2 04/24] m68k/atari: Replace nvram_{read, write}_byte with arch_nvram_ops

2015-06-14 Thread Finn Thain
By implementing an arch_nvram_ops struct, any platform can re-use the
drivers/char/nvram module without needing any arch-specific code
in that module. Atari does so here.

Atari has one user of nvram_check_checksum() whereas the other platforms
(i.e. x86 and ARM platforms) have none at all. Replace this
validate-checksum-and-read-byte sequence with the equivalent
rtc_nvram_ops.read() call and remove the now unused functions.

Signed-off-by: Finn Thain 

---

The advantage of the new ops struct over the old global nvram_* functions
is that the misc device module can be shared by different platforms
without requiring every platform to implement every nvram_* function.
E.g. only RTC "CMOS" NVRAMs have a checksum and only PowerPC platforms
have a "sync" ioctl.

---
 arch/m68k/atari/nvram.c   |   89 --
 drivers/scsi/atari_scsi.c |8 ++--
 include/linux/nvram.h |9 
 3 files changed, 70 insertions(+), 36 deletions(-)

Index: linux/arch/m68k/atari/nvram.c
===
--- linux.orig/arch/m68k/atari/nvram.c  2015-06-14 17:45:37.0 +1000
+++ linux/arch/m68k/atari/nvram.c   2015-06-14 17:45:39.0 +1000
@@ -38,33 +38,12 @@ unsigned char __nvram_read_byte(int i)
return CMOS_READ(NVRAM_FIRST_BYTE + i);
 }
 
-unsigned char nvram_read_byte(int i)
-{
-   unsigned long flags;
-   unsigned char c;
-
-   spin_lock_irqsave(&rtc_lock, flags);
-   c = __nvram_read_byte(i);
-   spin_unlock_irqrestore(&rtc_lock, flags);
-   return c;
-}
-EXPORT_SYMBOL(nvram_read_byte);
-
 /* This races nicely with trying to read with checksum checking */
 void __nvram_write_byte(unsigned char c, int i)
 {
CMOS_WRITE(c, NVRAM_FIRST_BYTE + i);
 }
 
-void nvram_write_byte(unsigned char c, int i)
-{
-   unsigned long flags;
-
-   spin_lock_irqsave(&rtc_lock, flags);
-   __nvram_write_byte(c, i);
-   spin_unlock_irqrestore(&rtc_lock, flags);
-}
-
 /* On Ataris, the checksum is over all bytes except the checksum bytes
  * themselves; these are at the very end.
  */
@@ -83,18 +62,6 @@ int __nvram_check_checksum(void)
   (__nvram_read_byte(ATARI_CKS_LOC + 1) == (sum & 0xff));
 }
 
-int nvram_check_checksum(void)
-{
-   unsigned long flags;
-   int rv;
-
-   spin_lock_irqsave(&rtc_lock, flags);
-   rv = __nvram_check_checksum();
-   spin_unlock_irqrestore(&rtc_lock, flags);
-   return rv;
-}
-EXPORT_SYMBOL(nvram_check_checksum);
-
 static void __nvram_set_checksum(void)
 {
int i;
@@ -106,6 +73,62 @@ static void __nvram_set_checksum(void)
__nvram_write_byte(sum, ATARI_CKS_LOC + 1);
 }
 
+static ssize_t nvram_read(char *buf, size_t count, loff_t *ppos)
+{
+   char *p = buf;
+   loff_t i;
+
+   spin_lock_irq(&rtc_lock);
+
+   if (!__nvram_check_checksum()) {
+   spin_unlock_irq(&rtc_lock);
+   return -EIO;
+   }
+
+   for (i = *ppos; count > 0 && i < NVRAM_BYTES; --count, ++i, ++p)
+   *p = __nvram_read_byte(i);
+
+   spin_unlock_irq(&rtc_lock);
+
+   *ppos = i;
+   return p - buf;
+}
+
+static ssize_t nvram_write(char *buf, size_t count, loff_t *ppos)
+{
+   char *p = buf;
+   loff_t i;
+
+   spin_lock_irq(&rtc_lock);
+
+   if (!__nvram_check_checksum()) {
+   spin_unlock_irq(&rtc_lock);
+   return -EIO;
+   }
+
+   for (i = *ppos; count > 0 && i < NVRAM_BYTES; --count, ++i, ++p)
+   __nvram_write_byte(*p, i);
+
+   __nvram_set_checksum();
+
+   spin_unlock_irq(&rtc_lock);
+
+   *ppos = i;
+   return p - buf;
+}
+
+static ssize_t nvram_get_size(void)
+{
+   return NVRAM_BYTES;
+}
+
+const struct nvram_ops arch_nvram_ops = {
+   .read   = nvram_read,
+   .write  = nvram_write,
+   .get_size   = nvram_get_size,
+};
+EXPORT_SYMBOL(arch_nvram_ops);
+
 #ifdef CONFIG_PROC_FS
 static struct {
unsigned char val;
Index: linux/drivers/scsi/atari_scsi.c
===
--- linux.orig/drivers/scsi/atari_scsi.c2015-06-14 17:45:35.0 
+1000
+++ linux/drivers/scsi/atari_scsi.c 2015-06-14 17:45:39.0 +1000
@@ -880,13 +880,15 @@ static int __init atari_scsi_probe(struc
 #ifdef CONFIG_NVRAM
else
/* Test if a host id is set in the NVRam */
-   if (ATARIHW_PRESENT(TT_CLK) && nvram_check_checksum()) {
-   unsigned char b = nvram_read_byte(14);
+   if (ATARIHW_PRESENT(TT_CLK)) {
+   unsigned char b;
+   loff_t offset = 14;
+   ssize_t count = arch_nvram_ops.read(&b, 1, &offset);
 
/* Arbitration enabled? (for TOS)

[RFC v2 06/24] char/nvram: Adopt arch_nvram_ops

2015-06-14 Thread Finn Thain
Different platforms and architectures offer different NVRAM sizes and
access methods. E.g. PPC32 has byte-at-a-time read/write functions whereas
PPC64 has byte-range read/write functions. Adopt the nvram_ops struct so
the nvram module can call such functions as are defined by the various 
platforms and architectures.

Signed-off-by: Finn Thain 

---

The #ifdefs here restrict the procfs and checksumming code to those
architectures with PC-style RTC NVRAM. There may be a better place for
that code but it's an open question. See https://lkml.org/lkml/2015/2/3/22

The procfs code here, if irrelevant to ARM platforms, could be moved to
arch/x86 (like the earlier patch does for m68k code) and the nvram ops
could implemented and exported by the rtc-cmos driver instead. This
would eliminate these #ifdefs.

---
 drivers/char/nvram.c  |   30 +++---
 include/linux/nvram.h |2 ++
 2 files changed, 29 insertions(+), 3 deletions(-)

Index: linux/drivers/char/nvram.c
===
--- linux.orig/drivers/char/nvram.c 2015-06-14 17:45:40.0 +1000
+++ linux/drivers/char/nvram.c  2015-06-14 17:45:41.0 +1000
@@ -51,9 +51,12 @@ static DEFINE_MUTEX(nvram_mutex);
 static DEFINE_SPINLOCK(nvram_state_lock);
 static int nvram_open_cnt; /* #times opened */
 static int nvram_open_mode;/* special open modes */
+static ssize_t nvram_size;
 #define NVRAM_WRITE1 /* opened for writing (exclusive) */
 #define NVRAM_EXCL 2 /* opened with O_EXCL */
 
+#if defined(CONFIG_X86) || defined(CONFIG_ARM)
+
 /*
  * These functions are provided to be called internally or by other parts of
  * the kernel. It's up to the caller to ensure correct checksum before reading
@@ -161,6 +164,20 @@ void nvram_set_checksum(void)
 }
 #endif  /*  0  */
 
+static ssize_t nvram_get_size(void)
+{
+   return NVRAM_BYTES;
+}
+
+const struct nvram_ops arch_nvram_ops = {
+   .read_byte  = nvram_read_byte,
+   .write_byte = nvram_write_byte,
+   .get_size   = nvram_get_size,
+};
+EXPORT_SYMBOL(arch_nvram_ops);
+
+#endif /* CONFIG_X86 || CONFIG_ARM */
+
 /*
  * The are the file operation function for user access to /dev/nvram
  */
@@ -332,7 +349,7 @@ static int nvram_misc_release(struct ino
return 0;
 }
 
-#ifdef CONFIG_PROC_FS
+#if defined(CONFIG_PROC_FS) && (defined(CONFIG_X86) || defined(CONFIG_ARM))
 
 static char *floppy_types[] = {
"none", "5.25'' 360k", "5.25'' 1.2M", "3.5'' 720k", "3.5'' 1.44M",
@@ -459,13 +476,20 @@ static int __init nvram_module_init(void
 {
int ret;
 
+   if (arch_nvram_ops.get_size == NULL)
+   return -ENODEV;
+
+   nvram_size = arch_nvram_ops.get_size();
+   if (nvram_size < 0)
+   return nvram_size;
+
ret = misc_register(&nvram_misc);
if (ret) {
pr_err("nvram: can't misc_register on minor=%d\n", NVRAM_MINOR);
return ret;
}
 
-#ifdef CONFIG_PROC_FS
+#if defined(CONFIG_PROC_FS) && (defined(CONFIG_X86) || defined(CONFIG_ARM))
if (!proc_create("driver/nvram", 0, NULL, &nvram_proc_fops)) {
pr_err("nvram: can't create /proc/driver/nvram\n");
misc_deregister(&nvram_misc);
@@ -479,7 +503,7 @@ static int __init nvram_module_init(void
 
 static void __exit nvram_module_exit(void)
 {
-#ifdef CONFIG_PROC_FS
+#if defined(CONFIG_PROC_FS) && (defined(CONFIG_X86) || defined(CONFIG_ARM))
remove_proc_entry("driver/nvram", NULL);
 #endif
misc_deregister(&nvram_misc);
Index: linux/include/linux/nvram.h
===
--- linux.orig/include/linux/nvram.h2015-06-14 17:45:39.0 +1000
+++ linux/include/linux/nvram.h 2015-06-14 17:45:41.0 +1000
@@ -14,6 +14,8 @@ extern int nvram_check_checksum(void);
 struct nvram_ops {
ssize_t (*read)(char *, size_t, loff_t *);
ssize_t (*write)(char *, size_t, loff_t *);
+   unsigned char   (*read_byte)(int);
+   void(*write_byte)(unsigned char, int);
ssize_t (*get_size)(void);
 };
 


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[RFC v2 12/24] char/nvram: Add "devname:nvram" module alias

2015-06-14 Thread Finn Thain
Signed-off-by: Finn Thain 

---
 drivers/char/nvram.c |1 +
 1 file changed, 1 insertion(+)

Index: linux/drivers/char/nvram.c
===
--- linux.orig/drivers/char/nvram.c 2015-06-14 17:45:46.0 +1000
+++ linux/drivers/char/nvram.c  2015-06-14 17:45:48.0 +1000
@@ -577,3 +577,4 @@ module_exit(nvram_module_exit);
 
 MODULE_LICENSE("GPL");
 MODULE_ALIAS_MISCDEV(NVRAM_MINOR);
+MODULE_ALIAS("devname:nvram");


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[RFC v2 08/24] char/nvram: Allow the set_checksum and initialize ioctls to be omitted

2015-06-14 Thread Finn Thain
The drivers/char/nvram module has previously only supported RTC "CMOS"
NVRAM, for which it provides appropriate checksum ioctls. Make these
ioctls optional so the module can be re-used with other kinds of NVRAM.

The ops struct methods that implement the ioctls now return error
codes so that a multi-platform kernel binary can do the right thing when
running on hardware without suitable NVRAM.

Signed-off-by: Finn Thain 

---

Changed since v1:
- Don't bother acquiring the mutex for unimplemented ioctls.

---
 drivers/char/nvram.c  |   71 --
 include/linux/nvram.h |2 +
 2 files changed, 43 insertions(+), 30 deletions(-)

Index: linux/drivers/char/nvram.c
===
--- linux.orig/drivers/char/nvram.c 2015-06-14 17:45:41.0 +1000
+++ linux/drivers/char/nvram.c  2015-06-14 17:45:43.0 +1000
@@ -153,16 +153,25 @@ static void __nvram_set_checksum(void)
__nvram_write_byte(sum & 0xff, PC_CKS_LOC + 1);
 }
 
-#if 0
-void nvram_set_checksum(void)
+static long nvram_set_checksum(void)
 {
-   unsigned long flags;
+   spin_lock_irq(&rtc_lock);
+   __nvram_set_checksum();
+   spin_unlock_irq(&rtc_lock);
+   return 0;
+}
+
+static long nvram_initialize(void)
+{
+   ssize_t i;
 
-   spin_lock_irqsave(&rtc_lock, flags);
+   spin_lock_irq(&rtc_lock);
+   for (i = 0; i < NVRAM_BYTES; ++i)
+   __nvram_write_byte(0, i);
__nvram_set_checksum();
-   spin_unlock_irqrestore(&rtc_lock, flags);
+   spin_unlock_irq(&rtc_lock);
+   return 0;
 }
-#endif  /*  0  */
 
 static ssize_t nvram_get_size(void)
 {
@@ -173,6 +182,8 @@ const struct nvram_ops arch_nvram_ops =
.read_byte  = nvram_read_byte,
.write_byte = nvram_write_byte,
.get_size   = nvram_get_size,
+   .set_checksum   = nvram_set_checksum,
+   .initialize = nvram_initialize,
 };
 EXPORT_SYMBOL(arch_nvram_ops);
 
@@ -272,51 +283,51 @@ checksum_err:
 static long nvram_misc_ioctl(struct file *file, unsigned int cmd,
  unsigned long arg)
 {
-   int i;
+   long ret = -ENOTTY;
 
switch (cmd) {
-
case NVRAM_INIT:
/* initialize NVRAM contents and checksum */
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
 
-   mutex_lock(&nvram_mutex);
-   spin_lock_irq(&rtc_lock);
-
-   for (i = 0; i < NVRAM_BYTES; ++i)
-   __nvram_write_byte(0, i);
-   __nvram_set_checksum();
-
-   spin_unlock_irq(&rtc_lock);
-   mutex_unlock(&nvram_mutex);
-   return 0;
-
+   if (arch_nvram_ops.initialize != NULL) {
+   mutex_lock(&nvram_mutex);
+   ret = arch_nvram_ops.initialize();
+   mutex_unlock(&nvram_mutex);
+   }
+   break;
case NVRAM_SETCKS:
/* just set checksum, contents unchanged (maybe useful after
 * checksum garbaged somehow...) */
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
 
-   mutex_lock(&nvram_mutex);
-   spin_lock_irq(&rtc_lock);
-   __nvram_set_checksum();
-   spin_unlock_irq(&rtc_lock);
-   mutex_unlock(&nvram_mutex);
-   return 0;
-
-   default:
-   return -ENOTTY;
+   if (arch_nvram_ops.set_checksum != NULL) {
+   mutex_lock(&nvram_mutex);
+   ret = arch_nvram_ops.set_checksum();
+   mutex_unlock(&nvram_mutex);
+   }
+   break;
}
+   return ret;
 }
 
 static int nvram_misc_open(struct inode *inode, struct file *file)
 {
spin_lock(&nvram_state_lock);
 
+   /* Prevent multiple readers/writers if desired. */
if ((nvram_open_cnt && (file->f_flags & O_EXCL)) ||
-   (nvram_open_mode & NVRAM_EXCL) ||
-   ((file->f_mode & FMODE_WRITE) && (nvram_open_mode & NVRAM_WRITE))) {
+   (nvram_open_mode & NVRAM_EXCL)) {
+   spin_unlock(&nvram_state_lock);
+   return -EBUSY;
+   }
+
+   /* Prevent multiple writers if the set_checksum ioctl is implemented. */
+   if ((arch_nvram_ops.set_checksum != NULL) &&
+   (file->f_mode & FMODE_WRITE) &&
+   (nvram_open_mode & NVRAM_WRITE)) {
spin_unlock(&nvram_state_lock);
return -EBUSY;
}
Index: linux/include/linux/nvram.h
===
--- linux.orig/include/linux/nvram.h201

[RFC v2 13/24] powerpc: Cleanup nvram includes

2015-06-14 Thread Finn Thain
The nvram_read_byte() and nvram_write_byte() definitions in asm/nvram.h
duplicate those in linux/nvram.h. Get rid of the former to prepare for
adoption of struct arch_nvram_ops (which is defined in linux/nvram.h for
general use).

Signed-off-by: Finn Thain 

---
 arch/powerpc/include/asm/nvram.h   |3 ---
 arch/powerpc/kernel/setup_32.c |1 +
 drivers/char/generic_nvram.c   |4 +++-
 drivers/video/fbdev/matrox/matroxfb_base.c |2 +-
 4 files changed, 5 insertions(+), 5 deletions(-)

Index: linux/arch/powerpc/include/asm/nvram.h
===
--- linux.orig/arch/powerpc/include/asm/nvram.h 2015-06-14 17:45:34.0 
+1000
+++ linux/arch/powerpc/include/asm/nvram.h  2015-06-14 17:45:49.0 
+1000
@@ -101,7 +101,4 @@ extern int nvram_write_os_partition(stru
 /* Determine NVRAM size */
 extern ssize_t nvram_get_size(void);
 
-/* Normal access to NVRAM */
-extern unsigned char nvram_read_byte(int i);
-extern void nvram_write_byte(unsigned char c, int i);
 #endif /* _ASM_POWERPC_NVRAM_H */
Index: linux/arch/powerpc/kernel/setup_32.c
===
--- linux.orig/arch/powerpc/kernel/setup_32.c   2015-06-14 17:45:34.0 
+1000
+++ linux/arch/powerpc/kernel/setup_32.c2015-06-14 17:45:49.0 
+1000
@@ -16,6 +16,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
Index: linux/drivers/char/generic_nvram.c
===
--- linux.orig/drivers/char/generic_nvram.c 2015-06-14 17:45:34.0 
+1000
+++ linux/drivers/char/generic_nvram.c  2015-06-14 17:45:49.0 +1000
@@ -20,9 +20,11 @@
 #include 
 #include 
 #include 
+#include 
 #include 
-#include 
+
 #ifdef CONFIG_PPC_PMAC
+#include 
 #include 
 #endif
 
Index: linux/drivers/video/fbdev/matrox/matroxfb_base.c
===
--- linux.orig/drivers/video/fbdev/matrox/matroxfb_base.c   2015-06-14 
17:45:34.0 +1000
+++ linux/drivers/video/fbdev/matrox/matroxfb_base.c2015-06-14 
17:45:49.0 +1000
@@ -111,12 +111,12 @@
 #include "matroxfb_g450.h"
 #include 
 #include 
+#include 
 #include 
 #include 
 
 #ifdef CONFIG_PPC_PMAC
 #include 
-unsigned char nvram_read_byte(int);
 static int default_vmode = VMODE_NVRAM;
 static int default_cmode = CMODE_NVRAM;
 #endif


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[RFC v2 10/24] char/nvram: Use generic fixed_size_llseek()

2015-06-14 Thread Finn Thain
Signed-off-by: Finn Thain 

---
 drivers/char/nvram.c |   16 +---
 1 file changed, 1 insertion(+), 15 deletions(-)

Index: linux/drivers/char/nvram.c
===
--- linux.orig/drivers/char/nvram.c 2015-06-14 17:45:45.0 +1000
+++ linux/drivers/char/nvram.c  2015-06-14 17:45:46.0 +1000
@@ -235,21 +235,7 @@ EXPORT_SYMBOL(arch_nvram_ops);
 
 static loff_t nvram_misc_llseek(struct file *file, loff_t offset, int origin)
 {
-   switch (origin) {
-   case 0:
-   /* nothing to do */
-   break;
-   case 1:
-   offset += file->f_pos;
-   break;
-   case 2:
-   offset += NVRAM_BYTES;
-   break;
-   default:
-   return -EINVAL;
-   }
-
-   return (offset >= 0) ? (file->f_pos = offset) : -EINVAL;
+   return fixed_size_llseek(file, offset, origin, nvram_size);
 }
 
 static ssize_t nvram_misc_read(struct file *file, char __user *buf,


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[RFC v2 05/24] char/nvram: Re-order functions to remove forward declarations and #ifdefs

2015-06-14 Thread Finn Thain
Also give functions more sensible names: nvram_misc_* for misc device ops,
nvram_proc_* for proc file ops and nvram_module_* for init and exit
functions. This makes them distict from nvram_ops members.

Signed-off-by: Finn Thain 

---
 drivers/char/nvram.c |  194 ++-
 1 file changed, 86 insertions(+), 108 deletions(-)

Index: linux/drivers/char/nvram.c
===
--- linux.orig/drivers/char/nvram.c 2015-06-14 17:45:37.0 +1000
+++ linux/drivers/char/nvram.c  2015-06-14 17:45:40.0 +1000
@@ -54,11 +54,6 @@ static int nvram_open_mode;  /* special o
 #define NVRAM_WRITE1 /* opened for writing (exclusive) */
 #define NVRAM_EXCL 2 /* opened with O_EXCL */
 
-#ifdef CONFIG_PROC_FS
-static void pc_nvram_proc_read(unsigned char *contents, struct seq_file *seq,
-   void *offset);
-#endif
-
 /*
  * These functions are provided to be called internally or by other parts of
  * the kernel. It's up to the caller to ensure correct checksum before reading
@@ -170,7 +165,7 @@ void nvram_set_checksum(void)
  * The are the file operation function for user access to /dev/nvram
  */
 
-static loff_t nvram_llseek(struct file *file, loff_t offset, int origin)
+static loff_t nvram_misc_llseek(struct file *file, loff_t offset, int origin)
 {
switch (origin) {
case 0:
@@ -189,8 +184,8 @@ static loff_t nvram_llseek(struct file *
return (offset >= 0) ? (file->f_pos = offset) : -EINVAL;
 }
 
-static ssize_t nvram_read(struct file *file, char __user *buf,
-   size_t count, loff_t *ppos)
+static ssize_t nvram_misc_read(struct file *file, char __user *buf,
+   size_t count, loff_t *ppos)
 {
unsigned char contents[NVRAM_BYTES];
unsigned i = *ppos;
@@ -218,8 +213,8 @@ checksum_err:
return -EIO;
 }
 
-static ssize_t nvram_write(struct file *file, const char __user *buf,
-   size_t count, loff_t *ppos)
+static ssize_t nvram_misc_write(struct file *file, const char __user *buf,
+size_t count, loff_t *ppos)
 {
unsigned char contents[NVRAM_BYTES];
unsigned i = *ppos;
@@ -257,8 +252,8 @@ checksum_err:
return -EIO;
 }
 
-static long nvram_ioctl(struct file *file, unsigned int cmd,
-   unsigned long arg)
+static long nvram_misc_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
 {
int i;
 
@@ -298,7 +293,7 @@ static long nvram_ioctl(struct file *fil
}
 }
 
-static int nvram_open(struct inode *inode, struct file *file)
+static int nvram_misc_open(struct inode *inode, struct file *file)
 {
spin_lock(&nvram_state_lock);
 
@@ -320,7 +315,7 @@ static int nvram_open(struct inode *inod
return 0;
 }
 
-static int nvram_release(struct inode *inode, struct file *file)
+static int nvram_misc_release(struct inode *inode, struct file *file)
 {
spin_lock(&nvram_state_lock);
 
@@ -337,100 +332,6 @@ static int nvram_release(struct inode *i
return 0;
 }
 
-#ifndef CONFIG_PROC_FS
-static int nvram_add_proc_fs(void)
-{
-   return 0;
-}
-
-#else
-
-static int nvram_proc_read(struct seq_file *seq, void *offset)
-{
-   unsigned char contents[NVRAM_BYTES];
-   int i = 0;
-
-   spin_lock_irq(&rtc_lock);
-   for (i = 0; i < NVRAM_BYTES; ++i)
-   contents[i] = __nvram_read_byte(i);
-   spin_unlock_irq(&rtc_lock);
-
-   pc_nvram_proc_read(contents, seq, offset);
-
-   return 0;
-}
-
-static int nvram_proc_open(struct inode *inode, struct file *file)
-{
-   return single_open(file, nvram_proc_read, NULL);
-}
-
-static const struct file_operations nvram_proc_fops = {
-   .owner  = THIS_MODULE,
-   .open   = nvram_proc_open,
-   .read   = seq_read,
-   .llseek = seq_lseek,
-   .release= single_release,
-};
-
-static int nvram_add_proc_fs(void)
-{
-   if (!proc_create("driver/nvram", 0, NULL, &nvram_proc_fops))
-   return -ENOMEM;
-   return 0;
-}
-
-#endif /* CONFIG_PROC_FS */
-
-static const struct file_operations nvram_fops = {
-   .owner  = THIS_MODULE,
-   .llseek = nvram_llseek,
-   .read   = nvram_read,
-   .write  = nvram_write,
-   .unlocked_ioctl = nvram_ioctl,
-   .open   = nvram_open,
-   .release= nvram_release,
-};
-
-static struct miscdevice nvram_dev = {
-   NVRAM_MINOR,
-   "nvram",
-   &nvram_fops
-};
-
-static int __init nvram_init(void)
-{
-   int ret;
-
-   ret = misc_register(&nvram_dev);
-   if (ret) {
-   printk(KERN_ERR "nvram: can't misc_register on

[RFC v2 11/24] m68k/atari: Implement arch_nvram_ops methods and enable CONFIG_HAVE_ARCH_NVRAM_OPS

2015-06-14 Thread Finn Thain
Atari RTC NVRAM has a checksum so implement the remaining arch_nvram_ops
methods for the set_checksum and initialize ioctls. Enable
CONFIG_HAVE_ARCH_NVRAM_OPS.

Signed-off-by: Finn Thain 

---

This re-enables the nvram module for Atari.

---
 arch/m68k/Kconfig   |3 +++
 arch/m68k/atari/nvram.c |   24 
 drivers/char/Kconfig|2 +-
 3 files changed, 28 insertions(+), 1 deletion(-)

Index: linux/arch/m68k/atari/nvram.c
===
--- linux.orig/arch/m68k/atari/nvram.c  2015-06-14 17:45:39.0 +1000
+++ linux/arch/m68k/atari/nvram.c   2015-06-14 17:45:47.0 +1000
@@ -73,6 +73,26 @@ static void __nvram_set_checksum(void)
__nvram_write_byte(sum, ATARI_CKS_LOC + 1);
 }
 
+static long nvram_set_checksum(void)
+{
+   spin_lock_irq(&rtc_lock);
+   __nvram_set_checksum();
+   spin_unlock_irq(&rtc_lock);
+   return 0;
+}
+
+static long nvram_initialize(void)
+{
+   loff_t i;
+
+   spin_lock_irq(&rtc_lock);
+   for (i = 0; i < NVRAM_BYTES; ++i)
+   __nvram_write_byte(0, i);
+   __nvram_set_checksum();
+   spin_unlock_irq(&rtc_lock);
+   return 0;
+}
+
 static ssize_t nvram_read(char *buf, size_t count, loff_t *ppos)
 {
char *p = buf;
@@ -119,6 +139,8 @@ static ssize_t nvram_write(char *buf, si
 
 static ssize_t nvram_get_size(void)
 {
+   if (!MACH_IS_ATARI)
+   return -ENODEV;
return NVRAM_BYTES;
 }
 
@@ -126,6 +148,8 @@ const struct nvram_ops arch_nvram_ops =
.read   = nvram_read,
.write  = nvram_write,
.get_size   = nvram_get_size,
+   .set_checksum   = nvram_set_checksum,
+   .initialize = nvram_initialize,
 };
 EXPORT_SYMBOL(arch_nvram_ops);
 
Index: linux/drivers/char/Kconfig
===
--- linux.orig/drivers/char/Kconfig 2015-06-14 17:45:35.0 +1000
+++ linux/drivers/char/Kconfig  2015-06-14 17:45:47.0 +1000
@@ -247,7 +247,7 @@ source "drivers/char/hw_random/Kconfig"
 
 config NVRAM
tristate "/dev/nvram support"
-   depends on X86 || (ARM && RTC_DRV_CMOS) || GENERIC_NVRAM
+   depends on X86 || (ARM && RTC_DRV_CMOS) || GENERIC_NVRAM || 
HAVE_ARCH_NVRAM_OPS
---help---
  If you say Y here and create a character special file /dev/nvram
  with major number 10 and minor number 144 using mknod ("man mknod"),
Index: linux/arch/m68k/Kconfig
===
--- linux.orig/arch/m68k/Kconfig2015-06-14 17:45:34.0 +1000
+++ linux/arch/m68k/Kconfig 2015-06-14 17:45:47.0 +1000
@@ -71,6 +71,9 @@ config PGTABLE_LEVELS
default 2 if SUN3 || COLDFIRE
default 3
 
+config HAVE_ARCH_NVRAM_OPS
+   def_bool ATARI
+
 source "init/Kconfig"
 
 source "kernel/Kconfig.freezer"


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[RFC v2 07/24] x86/thinkpad_acpi: Use arch_nvram_ops methods instead of nvram_read_byte() and nvram_write_byte()

2015-06-14 Thread Finn Thain
Make use of arch_nvram_ops in the thinkpad_acpi driver so that the
nvram_* function exports can be removed.

This patch series was tested on a ThinkPad T43.

Signed-off-by: Finn Thain 
Acked-by: Henrique de Moraes Holschuh 
Reviewed-by: Darren Hart 

---
 drivers/platform/x86/thinkpad_acpi.c |   20 ++--
 1 file changed, 10 insertions(+), 10 deletions(-)

Index: linux/drivers/platform/x86/thinkpad_acpi.c
===
--- linux.orig/drivers/platform/x86/thinkpad_acpi.c 2015-06-14 
17:45:34.0 +1000
+++ linux/drivers/platform/x86/thinkpad_acpi.c  2015-06-14 17:45:42.0 
+1000
@@ -2311,30 +2311,30 @@ static void hotkey_read_nvram(struct tp_
u8 d;
 
if (m & TP_NVRAM_HKEY_GROUP_HK2) {
-   d = nvram_read_byte(TP_NVRAM_ADDR_HK2);
+   d = arch_nvram_ops.read_byte(TP_NVRAM_ADDR_HK2);
n->thinkpad_toggle = !!(d & TP_NVRAM_MASK_HKT_THINKPAD);
n->zoom_toggle = !!(d & TP_NVRAM_MASK_HKT_ZOOM);
n->display_toggle = !!(d & TP_NVRAM_MASK_HKT_DISPLAY);
n->hibernate_toggle = !!(d & TP_NVRAM_MASK_HKT_HIBERNATE);
}
if (m & TP_ACPI_HKEY_THNKLGHT_MASK) {
-   d = nvram_read_byte(TP_NVRAM_ADDR_THINKLIGHT);
+   d = arch_nvram_ops.read_byte(TP_NVRAM_ADDR_THINKLIGHT);
n->thinklight_toggle = !!(d & TP_NVRAM_MASK_THINKLIGHT);
}
if (m & TP_ACPI_HKEY_DISPXPAND_MASK) {
-   d = nvram_read_byte(TP_NVRAM_ADDR_VIDEO);
+   d = arch_nvram_ops.read_byte(TP_NVRAM_ADDR_VIDEO);
n->displayexp_toggle =
!!(d & TP_NVRAM_MASK_HKT_DISPEXPND);
}
if (m & TP_NVRAM_HKEY_GROUP_BRIGHTNESS) {
-   d = nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS);
+   d = arch_nvram_ops.read_byte(TP_NVRAM_ADDR_BRIGHTNESS);
n->brightness_level = (d & TP_NVRAM_MASK_LEVEL_BRIGHTNESS)
>> TP_NVRAM_POS_LEVEL_BRIGHTNESS;
n->brightness_toggle =
!!(d & TP_NVRAM_MASK_HKT_BRIGHTNESS);
}
if (m & TP_NVRAM_HKEY_GROUP_VOLUME) {
-   d = nvram_read_byte(TP_NVRAM_ADDR_MIXER);
+   d = arch_nvram_ops.read_byte(TP_NVRAM_ADDR_MIXER);
n->volume_level = (d & TP_NVRAM_MASK_LEVEL_VOLUME)
>> TP_NVRAM_POS_LEVEL_VOLUME;
n->mute = !!(d & TP_NVRAM_MASK_MUTE);
@@ -6155,7 +6155,7 @@ static unsigned int tpacpi_brightness_nv
 {
u8 lnvram;
 
-   lnvram = (nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS)
+   lnvram = (arch_nvram_ops.read_byte(TP_NVRAM_ADDR_BRIGHTNESS)
  & TP_NVRAM_MASK_LEVEL_BRIGHTNESS)
  >> TP_NVRAM_POS_LEVEL_BRIGHTNESS;
lnvram &= bright_maxlvl;
@@ -6180,7 +6180,7 @@ static void tpacpi_brightness_checkpoint
if (unlikely(!acpi_ec_read(TP_EC_BACKLIGHT, &lec)))
goto unlock;
lec &= TP_EC_BACKLIGHT_LVLMSK;
-   b_nvram = nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS);
+   b_nvram = arch_nvram_ops.read_byte(TP_NVRAM_ADDR_BRIGHTNESS);
 
if (lec != ((b_nvram & TP_NVRAM_MASK_LEVEL_BRIGHTNESS)
 >> TP_NVRAM_POS_LEVEL_BRIGHTNESS)) {
@@ -6188,7 +6188,7 @@ static void tpacpi_brightness_checkpoint
b_nvram &= ~(TP_NVRAM_MASK_LEVEL_BRIGHTNESS <<
TP_NVRAM_POS_LEVEL_BRIGHTNESS);
b_nvram |= lec;
-   nvram_write_byte(b_nvram, TP_NVRAM_ADDR_BRIGHTNESS);
+   arch_nvram_ops.write_byte(b_nvram, TP_NVRAM_ADDR_BRIGHTNESS);
dbg_printk(TPACPI_DBG_BRGHT,
   "updated NVRAM backlight level to %u (0x%02x)\n",
   (unsigned int) lec, (unsigned int) b_nvram);
@@ -6796,13 +6796,13 @@ static void tpacpi_volume_checkpoint_nvr
if (unlikely(!acpi_ec_read(TP_EC_AUDIO, &lec)))
goto unlock;
lec &= ec_mask;
-   b_nvram = nvram_read_byte(TP_NVRAM_ADDR_MIXER);
+   b_nvram = arch_nvram_ops.read_byte(TP_NVRAM_ADDR_MIXER);
 
if (lec != (b_nvram & ec_mask)) {
/* NVRAM needs update */
b_nvram &= ~ec_mask;
b_nvram |= lec;
-   nvram_write_byte(b_nvram, TP_NVRAM_ADDR_MIXER);
+   arch_nvram_ops.write_byte(b_nvram, TP_NVRAM_ADDR_MIXER);
dbg_printk(TPACPI_DBG_MIXER,
   "updated NVRAM mixer status to 0x%02x (0x%02x)\n",
   (unsigned int) lec, (unsigned int) b_nvram);


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[RFC v2 09/24] char/nvram: Implement NVRAM read/write methods

2015-06-14 Thread Finn Thain
Refactor the RTC "CMOS" NVRAM functions so that they can be used as
arch_nvram_ops methods. Checksumming logic is moved from the misc device
operations to the nvram read/write operations.

This makes the misc device implementation more generic. This also
preserves the locking semantics such that "read if checksum valid" and
"write and update checksum" remain atomic operations.

PPC64 implements byte-range read/write methods which are similar to
file_operations struct methods. Other platforms provide only
byte-at-a-time functions. So the misc device prefers the former but
will fall back on the latter.

Signed-off-by: Finn Thain 

---
 drivers/char/nvram.c |  162 +++
 1 file changed, 114 insertions(+), 48 deletions(-)

Index: linux/drivers/char/nvram.c
===
--- linux.orig/drivers/char/nvram.c 2015-06-14 17:45:43.0 +1000
+++ linux/drivers/char/nvram.c  2015-06-14 17:45:45.0 +1000
@@ -41,6 +41,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -178,9 +179,48 @@ static ssize_t nvram_get_size(void)
return NVRAM_BYTES;
 }
 
+static ssize_t nvram_read(char *buf, size_t count, loff_t *ppos)
+{
+   char *p = buf;
+   loff_t i;
+
+   spin_lock_irq(&rtc_lock);
+   if (!__nvram_check_checksum()) {
+   spin_unlock_irq(&rtc_lock);
+   return -EIO;
+   }
+   for (i = *ppos; count > 0 && i < NVRAM_BYTES; --count, ++i, ++p)
+   *p = __nvram_read_byte(i);
+   spin_unlock_irq(&rtc_lock);
+
+   *ppos = i;
+   return p - buf;
+}
+
+static ssize_t nvram_write(char *buf, size_t count, loff_t *ppos)
+{
+   char *p = buf;
+   loff_t i;
+
+   spin_lock_irq(&rtc_lock);
+   if (!__nvram_check_checksum()) {
+   spin_unlock_irq(&rtc_lock);
+   return -EIO;
+   }
+   for (i = *ppos; count > 0 && i < NVRAM_BYTES; --count, ++i, ++p)
+   __nvram_write_byte(*p, i);
+   __nvram_set_checksum();
+   spin_unlock_irq(&rtc_lock);
+
+   *ppos = i;
+   return p - buf;
+}
+
 const struct nvram_ops arch_nvram_ops = {
.read_byte  = nvram_read_byte,
.write_byte = nvram_write_byte,
+   .read   = nvram_read,
+   .write  = nvram_write,
.get_size   = nvram_get_size,
.set_checksum   = nvram_set_checksum,
.initialize = nvram_initialize,
@@ -215,69 +255,95 @@ static loff_t nvram_misc_llseek(struct f
 static ssize_t nvram_misc_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
 {
-   unsigned char contents[NVRAM_BYTES];
-   unsigned i = *ppos;
-   unsigned char *tmp;
-
-   spin_lock_irq(&rtc_lock);
+   loff_t i;
+   char __user *p = buf;
 
-   if (!__nvram_check_checksum())
-   goto checksum_err;
-
-   for (tmp = contents; count-- > 0 && i < NVRAM_BYTES; ++i, ++tmp)
-   *tmp = __nvram_read_byte(i);
-
-   spin_unlock_irq(&rtc_lock);
-
-   if (copy_to_user(buf, contents, tmp - contents))
+   if (!access_ok(VERIFY_WRITE, buf, count))
return -EFAULT;
+   if (*ppos >= nvram_size)
+   return 0;
 
-   *ppos = i;
-
-   return tmp - contents;
+   /* If the arch provided a byte range read op, use it. Otherwise
+* fall back on the byte-at-a-time accessor.
+*/
+   if (arch_nvram_ops.read != NULL) {
+   char *tmp;
+   ssize_t ret;
+
+   count = min_t(size_t, count, nvram_size - *ppos);
+   count = min_t(size_t, count, PAGE_SIZE);
+
+   tmp = kmalloc(count, GFP_KERNEL);
+   if (!tmp)
+   return -ENOMEM;
+
+   ret = arch_nvram_ops.read(tmp, count, ppos);
+   if (ret <= 0)
+   goto out;
+
+   if (copy_to_user(buf, tmp, ret)) {
+   *ppos -= ret;
+   ret = -EFAULT;
+   }
+
+out:
+   kfree(tmp);
+   return ret;
+   }
 
-checksum_err:
-   spin_unlock_irq(&rtc_lock);
-   return -EIO;
+   for (i = *ppos; count > 0 && i < nvram_size; ++i, ++p, --count)
+   if (__put_user(arch_nvram_ops.read_byte(i), p))
+   return -EFAULT;
+   *ppos = i;
+   return p - buf;
 }
 
 static ssize_t nvram_misc_write(struct file *file, const char __user *buf,
 size_t count, loff_t *ppos)
 {
-   unsigned char contents[NVRAM_BYTES];
-   unsigned i = *ppos;
-   unsigned char *tmp;
-
-   if (i >= NVRAM_BYTES)
-   return 0;   /* Past EOF */
-
-   if (count > NVRA

[RFC v2 14/24] powerpc: Add missing ppc_md.nvram_size for CHRP and PowerMac

2015-06-14 Thread Finn Thain
Add the nvram_size() function to those PowerPC platforms that don't already
have one: CHRP and PowerMac. This means that the ppc_md.nvram_size()
function can be used to implement arch_nvram_ops.get_size()

Since we are addressing inconsistencies here, also rename chrp_nvram_read
and chrp_nvram_write, which break the naming convention used across
PowerPC platforms for NVRAM accessor functions.

Signed-off-by: Finn Thain 

---
 arch/powerpc/platforms/chrp/nvram.c |   14 ++
 arch/powerpc/platforms/powermac/nvram.c |9 +
 2 files changed, 19 insertions(+), 4 deletions(-)

Index: linux/arch/powerpc/platforms/chrp/nvram.c
===
--- linux.orig/arch/powerpc/platforms/chrp/nvram.c  2015-06-14 
17:45:34.0 +1000
+++ linux/arch/powerpc/platforms/chrp/nvram.c   2015-06-14 17:45:50.0 
+1000
@@ -23,7 +23,7 @@ static unsigned int nvram_size;
 static unsigned char nvram_buf[4];
 static DEFINE_SPINLOCK(nvram_lock);
 
-static unsigned char chrp_nvram_read(int addr)
+static unsigned char chrp_nvram_read_byte(int addr)
 {
unsigned int done;
unsigned long flags;
@@ -45,7 +45,7 @@ static unsigned char chrp_nvram_read(int
return ret;
 }
 
-static void chrp_nvram_write(int addr, unsigned char val)
+static void chrp_nvram_write_byte(int addr, unsigned char val)
 {
unsigned int done;
unsigned long flags;
@@ -63,6 +63,11 @@ static void chrp_nvram_write(int addr, u
spin_unlock_irqrestore(&nvram_lock, flags);
 }
 
+static ssize_t chrp_nvram_size(void)
+{
+   return nvram_size;
+}
+
 void __init chrp_nvram_init(void)
 {
struct device_node *nvram;
@@ -84,8 +89,9 @@ void __init chrp_nvram_init(void)
printk(KERN_INFO "CHRP nvram contains %u bytes\n", nvram_size);
of_node_put(nvram);
 
-   ppc_md.nvram_read_val = chrp_nvram_read;
-   ppc_md.nvram_write_val = chrp_nvram_write;
+   ppc_md.nvram_read_val  = chrp_nvram_read_byte;
+   ppc_md.nvram_write_val = chrp_nvram_write_byte;
+   ppc_md.nvram_size  = chrp_nvram_size;
 
return;
 }
Index: linux/arch/powerpc/platforms/powermac/nvram.c
===
--- linux.orig/arch/powerpc/platforms/powermac/nvram.c  2015-06-14 
17:45:34.0 +1000
+++ linux/arch/powerpc/platforms/powermac/nvram.c   2015-06-14 
17:45:50.0 +1000
@@ -147,6 +147,11 @@ static ssize_t core99_nvram_size(void)
 static volatile unsigned char __iomem *nvram_addr;
 static int nvram_mult;
 
+static ssize_t ppc32_nvram_size(void)
+{
+   return NVRAM_SIZE;
+}
+
 static unsigned char direct_nvram_read_byte(int addr)
 {
return in_8(&nvram_data[(addr & (NVRAM_SIZE - 1)) * nvram_mult]);
@@ -590,21 +595,25 @@ int __init pmac_nvram_init(void)
nvram_mult = 1;
ppc_md.nvram_read_val   = direct_nvram_read_byte;
ppc_md.nvram_write_val  = direct_nvram_write_byte;
+   ppc_md.nvram_size   = ppc32_nvram_size;
} else if (nvram_naddrs == 1) {
nvram_data = ioremap(r1.start, s1);
nvram_mult = (s1 + NVRAM_SIZE - 1) / NVRAM_SIZE;
ppc_md.nvram_read_val   = direct_nvram_read_byte;
ppc_md.nvram_write_val  = direct_nvram_write_byte;
+   ppc_md.nvram_size   = ppc32_nvram_size;
} else if (nvram_naddrs == 2) {
nvram_addr = ioremap(r1.start, s1);
nvram_data = ioremap(r2.start, s2);
ppc_md.nvram_read_val   = indirect_nvram_read_byte;
ppc_md.nvram_write_val  = indirect_nvram_write_byte;
+   ppc_md.nvram_size   = ppc32_nvram_size;
} else if (nvram_naddrs == 0 && sys_ctrler == SYS_CTRLER_PMU) {
 #ifdef CONFIG_ADB_PMU
nvram_naddrs = -1;
ppc_md.nvram_read_val   = pmu_nvram_read_byte;
ppc_md.nvram_write_val  = pmu_nvram_write_byte;
+   ppc_md.nvram_size   = ppc32_nvram_size;
 #endif /* CONFIG_ADB_PMU */
} else {
printk(KERN_ERR "Incompatible type of NVRAM\n");


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[RFC v2 15/24] powerpc: Implement arch_nvram_ops.get_size() and remove old nvram_* exports

2015-06-14 Thread Finn Thain
Implement arch_nvram_ops for PPC32 and make use of it in the generic_nvram
misc device module so that the nvram_* function exports can be removed.

Signed-off-by: Finn Thain 

---
 arch/powerpc/include/asm/nvram.h |3 ---
 arch/powerpc/kernel/setup_32.c   |   10 +++---
 drivers/char/generic_nvram.c |   24 
 3 files changed, 19 insertions(+), 18 deletions(-)

Index: linux/arch/powerpc/include/asm/nvram.h
===
--- linux.orig/arch/powerpc/include/asm/nvram.h 2015-06-14 17:45:49.0 
+1000
+++ linux/arch/powerpc/include/asm/nvram.h  2015-06-14 17:45:51.0 
+1000
@@ -98,7 +98,4 @@ extern int nvram_write_os_partition(stru
unsigned int err_type,
unsigned int error_log_cnt);
 
-/* Determine NVRAM size */
-extern ssize_t nvram_get_size(void);
-
 #endif /* _ASM_POWERPC_NVRAM_H */
Index: linux/arch/powerpc/kernel/setup_32.c
===
--- linux.orig/arch/powerpc/kernel/setup_32.c   2015-06-14 17:45:49.0 
+1000
+++ linux/arch/powerpc/kernel/setup_32.c2015-06-14 17:45:51.0 
+1000
@@ -186,13 +186,12 @@ void nvram_write_byte(unsigned char val,
 }
 EXPORT_SYMBOL(nvram_write_byte);
 
-ssize_t nvram_get_size(void)
+static ssize_t ppc_nvram_get_size(void)
 {
if (ppc_md.nvram_size)
return ppc_md.nvram_size();
-   return -1;
+   return -ENODEV;
 }
-EXPORT_SYMBOL(nvram_get_size);
 
 void nvram_sync(void)
 {
@@ -201,6 +200,11 @@ void nvram_sync(void)
 }
 EXPORT_SYMBOL(nvram_sync);
 
+const struct nvram_ops arch_nvram_ops = {
+   .get_size   = ppc_nvram_get_size,
+};
+EXPORT_SYMBOL(arch_nvram_ops);
+
 #endif /* CONFIG_NVRAM */
 
 int __init ppc_init(void)
Index: linux/drivers/char/generic_nvram.c
===
--- linux.orig/drivers/char/generic_nvram.c 2015-06-14 17:45:49.0 
+1000
+++ linux/drivers/char/generic_nvram.c  2015-06-14 17:45:51.0 +1000
@@ -28,8 +28,6 @@
 #include 
 #endif
 
-#define NVRAM_SIZE 8192
-
 static DEFINE_MUTEX(nvram_mutex);
 static ssize_t nvram_len;
 
@@ -150,20 +148,22 @@ static struct miscdevice nvram_dev = {
 
 int __init nvram_init(void)
 {
-   int ret = 0;
+   int ret;
 
-   printk(KERN_INFO "Generic non-volatile memory driver v%s\n",
-   NVRAM_VERSION);
-   ret = misc_register(&nvram_dev);
-   if (ret != 0)
-   goto out;
+   if (arch_nvram_ops.get_size == NULL)
+   return -ENODEV;
 
-   nvram_len = nvram_get_size();
+   nvram_len = arch_nvram_ops.get_size();
if (nvram_len < 0)
-   nvram_len = NVRAM_SIZE;
+   return nvram_len;
 
-out:
-   return ret;
+   ret = misc_register(&nvram_dev);
+   if (ret)
+   return ret;
+
+   pr_info("Generic non-volatile memory driver v%s\n", NVRAM_VERSION);
+
+   return 0;
 }
 
 void __exit nvram_cleanup(void)


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[RFC v2 19/24] powerpc: Remove CONFIG_GENERIC_NVRAM and adopt CONFIG_HAVE_ARCH_NVRAM_OPS

2015-06-14 Thread Finn Thain
Switch PPC32 kernels from the generic_nvram module to the nvram module.

Also fix a theoretical bug where CHRP omits the chrp_nvram_init()
call when CONFIG_NVRAM_MODULE=m.

As before, when CONFIG_PPC && !CONFIG_PPC_PMAC, the IOC_NVRAM_GET_OFFSET
ioctl is unimplemented. For the nvram module, unimplemented ioctls return
-ENOTTY. Whereas, for the superseded generic_nvram module they would
return -EINVAL.

Signed-off-by: Finn Thain 

---

This ioctl change is visible to userspace code but only in an error path.
I didn't find any userspace code that uses the IOC_NVRAM_GET_OFFSET ioctl.

The change in the name of the module is also visible. The module that
implements /dev/nvram on PowerPC now has suitable aliases, i.e.
MODULE_ALIAS_MISCDEV(NVRAM_MINOR);
MODULE_ALIAS("devname:nvram"); 
so that the device special file can be automatically created and the
module automatically loaded when needed. Previously this was not the case.

---

Changes since v1:
- Small indentation fix.

---
 arch/powerpc/Kconfig|2 +-
 arch/powerpc/kernel/setup_32.c  |2 +-
 arch/powerpc/platforms/chrp/Makefile|2 +-
 arch/powerpc/platforms/chrp/setup.c |2 +-
 arch/powerpc/platforms/powermac/setup.c |3 +--
 drivers/char/Kconfig|   10 ++
 6 files changed, 11 insertions(+), 10 deletions(-)

Index: linux/arch/powerpc/Kconfig
===
--- linux.orig/arch/powerpc/Kconfig 2015-06-14 17:45:34.0 +1000
+++ linux/arch/powerpc/Kconfig  2015-06-14 17:45:57.0 +1000
@@ -178,7 +178,7 @@ config SYSVIPC_COMPAT
default y
 
 # All PPC32s use generic nvram driver through ppc_md
-config GENERIC_NVRAM
+config HAVE_ARCH_NVRAM_OPS
bool
default y if PPC32
 
Index: linux/arch/powerpc/kernel/setup_32.c
===
--- linux.orig/arch/powerpc/kernel/setup_32.c   2015-06-14 17:45:54.0 
+1000
+++ linux/arch/powerpc/kernel/setup_32.c2015-06-14 17:45:57.0 
+1000
@@ -168,7 +168,7 @@ int __init ppc_setup_l3cr(char *str)
 }
 __setup("l3cr=", ppc_setup_l3cr);
 
-#ifdef CONFIG_GENERIC_NVRAM
+#if IS_ENABLED(CONFIG_NVRAM)
 
 static unsigned char ppc_nvram_read_byte(int addr)
 {
Index: linux/arch/powerpc/platforms/chrp/Makefile
===
--- linux.orig/arch/powerpc/platforms/chrp/Makefile 2015-06-14 
17:45:34.0 +1000
+++ linux/arch/powerpc/platforms/chrp/Makefile  2015-06-14 17:45:57.0 
+1000
@@ -1,3 +1,3 @@
 obj-y  += setup.o time.o pegasos_eth.o pci.o
 obj-$(CONFIG_SMP)  += smp.o
-obj-$(CONFIG_NVRAM)+= nvram.o
+obj-$(CONFIG_NVRAM:m=y)+= nvram.o
Index: linux/arch/powerpc/platforms/chrp/setup.c
===
--- linux.orig/arch/powerpc/platforms/chrp/setup.c  2015-06-14 
17:45:34.0 +1000
+++ linux/arch/powerpc/platforms/chrp/setup.c   2015-06-14 17:45:57.0 
+1000
@@ -557,7 +557,7 @@ void __init chrp_init_IRQ(void)
 void __init
 chrp_init2(void)
 {
-#ifdef CONFIG_NVRAM
+#if IS_ENABLED(CONFIG_NVRAM)
chrp_nvram_init();
 #endif
 
Index: linux/arch/powerpc/platforms/powermac/setup.c
===
--- linux.orig/arch/powerpc/platforms/powermac/setup.c  2015-06-14 
17:45:34.0 +1000
+++ linux/arch/powerpc/platforms/powermac/setup.c   2015-06-14 
17:45:57.0 +1000
@@ -321,8 +321,7 @@ static void __init pmac_setup_arch(void)
find_via_pmu();
smu_init();
 
-#if defined(CONFIG_NVRAM) || defined(CONFIG_NVRAM_MODULE) || \
-defined(CONFIG_PPC64)
+#if IS_ENABLED(CONFIG_NVRAM) || defined(CONFIG_PPC64)
pmac_nvram_init();
 #endif
 
Index: linux/drivers/char/Kconfig
===
--- linux.orig/drivers/char/Kconfig 2015-06-14 17:45:47.0 +1000
+++ linux/drivers/char/Kconfig  2015-06-14 17:45:57.0 +1000
@@ -247,7 +247,7 @@ source "drivers/char/hw_random/Kconfig"
 
 config NVRAM
tristate "/dev/nvram support"
-   depends on X86 || (ARM && RTC_DRV_CMOS) || GENERIC_NVRAM || 
HAVE_ARCH_NVRAM_OPS
+   depends on X86 || (ARM && RTC_DRV_CMOS) || HAVE_ARCH_NVRAM_OPS
---help---
  If you say Y here and create a character special file /dev/nvram
  with major number 10 and minor number 144 using mknod ("man mknod"),
@@ -256,9 +256,11 @@ config NVRAM
  and most Ataris.  The actual number of bytes varies, depending on the
  nvram in the system, but is usually 114 (128-14 for the RTC).
 
- This memory is conventionally called "CMOS RAM" on PCs and "NVRAM"
- on Ataris. /dev/nvram may be used to view s

[RFC v2 17/24] powerpc, fbdev: Use arch_nvram_ops methods instead of nvram_read_byte() and nvram_write_byte()

2015-06-14 Thread Finn Thain
Make use of arch_nvram_ops in device drivers so that the nvram_*
function exports can be removed.

Since they are no longer global symbols, rename the PPC32 nvram_* functions
appropriately.

Add the missing CONFIG_NVRAM test to imsttfb to avoid a build failure.

Signed-off-by: Finn Thain 

---
 arch/powerpc/kernel/setup_32.c |8 
 drivers/char/generic_nvram.c   |4 ++--
 drivers/video/fbdev/controlfb.c|4 ++--
 drivers/video/fbdev/imsttfb.c  |7 +++
 drivers/video/fbdev/matrox/matroxfb_base.c |2 +-
 drivers/video/fbdev/platinumfb.c   |4 ++--
 drivers/video/fbdev/valkyriefb.c   |4 ++--
 7 files changed, 16 insertions(+), 17 deletions(-)

Index: linux/arch/powerpc/kernel/setup_32.c
===
--- linux.orig/arch/powerpc/kernel/setup_32.c   2015-06-14 17:45:53.0 
+1000
+++ linux/arch/powerpc/kernel/setup_32.c2015-06-14 17:45:54.0 
+1000
@@ -170,20 +170,18 @@ __setup("l3cr=", ppc_setup_l3cr);
 
 #ifdef CONFIG_GENERIC_NVRAM
 
-unsigned char nvram_read_byte(int addr)
+static unsigned char ppc_nvram_read_byte(int addr)
 {
if (ppc_md.nvram_read_val)
return ppc_md.nvram_read_val(addr);
return 0xff;
 }
-EXPORT_SYMBOL(nvram_read_byte);
 
-void nvram_write_byte(unsigned char val, int addr)
+static void ppc_nvram_write_byte(unsigned char val, int addr)
 {
if (ppc_md.nvram_write_val)
ppc_md.nvram_write_val(addr, val);
 }
-EXPORT_SYMBOL(nvram_write_byte);
 
 static ssize_t ppc_nvram_get_size(void)
 {
@@ -200,6 +198,8 @@ static long ppc_nvram_sync(void)
 }
 
 const struct nvram_ops arch_nvram_ops = {
+   .read_byte  = ppc_nvram_read_byte,
+   .write_byte = ppc_nvram_write_byte,
.get_size   = ppc_nvram_get_size,
.sync   = ppc_nvram_sync,
 };
Index: linux/drivers/char/generic_nvram.c
===
--- linux.orig/drivers/char/generic_nvram.c 2015-06-14 17:45:53.0 
+1000
+++ linux/drivers/char/generic_nvram.c  2015-06-14 17:45:54.0 +1000
@@ -64,7 +64,7 @@ static ssize_t read_nvram(struct file *f
if (*ppos >= nvram_len)
return 0;
for (i = *ppos; count > 0 && i < nvram_len; ++i, ++p, --count)
-   if (__put_user(nvram_read_byte(i), p))
+   if (__put_user(arch_nvram_ops.read_byte(i), p))
return -EFAULT;
*ppos = i;
return p - buf;
@@ -84,7 +84,7 @@ static ssize_t write_nvram(struct file *
for (i = *ppos; count > 0 && i < nvram_len; ++i, ++p, --count) {
if (__get_user(c, p))
return -EFAULT;
-   nvram_write_byte(c, i);
+   arch_nvram_ops.write_byte(c, i);
}
*ppos = i;
return p - buf;
Index: linux/drivers/video/fbdev/controlfb.c
===
--- linux.orig/drivers/video/fbdev/controlfb.c  2015-06-14 17:45:34.0 
+1000
+++ linux/drivers/video/fbdev/controlfb.c   2015-06-14 17:45:54.0 
+1000
@@ -415,7 +415,7 @@ static int __init init_control(struct fb
/* Try to pick a video mode out of NVRAM if we have one. */
 #ifdef CONFIG_NVRAM
if (default_cmode == CMODE_NVRAM) {
-   cmode = nvram_read_byte(NV_CMODE);
+   cmode = arch_nvram_ops.read_byte(NV_CMODE);
if(cmode < CMODE_8 || cmode > CMODE_32)
cmode = CMODE_8;
} else
@@ -423,7 +423,7 @@ static int __init init_control(struct fb
cmode=default_cmode;
 #ifdef CONFIG_NVRAM
if (default_vmode == VMODE_NVRAM) {
-   vmode = nvram_read_byte(NV_VMODE);
+   vmode = arch_nvram_ops.read_byte(NV_VMODE);
if (vmode < 1 || vmode > VMODE_MAX ||
control_mac_modes[vmode - 1].m[full] < cmode) {
sense = read_control_sense(p);
Index: linux/drivers/video/fbdev/matrox/matroxfb_base.c
===
--- linux.orig/drivers/video/fbdev/matrox/matroxfb_base.c   2015-06-14 
17:45:49.0 +1000
+++ linux/drivers/video/fbdev/matrox/matroxfb_base.c2015-06-14 
17:45:54.0 +1000
@@ -1888,7 +1888,7 @@ static int initMatrox2(struct matrox_fb_
default_vmode = VMODE_640_480_60;
 #ifdef CONFIG_NVRAM
if (default_cmode == CMODE_NVRAM)
-   default_cmode = nvram_read_byte(NV_CMODE);
+   default_cmode = arch_nvram_ops.read_byte(NV_CMODE);
 #endif
if (default_cmode < CMODE_8 || default_cmode > CMODE_32)
default_

[RFC v2 22/24] m68k/mac: Adopt naming and calling conventions for PRAM routines

2015-06-14 Thread Finn Thain
Adopt the existing *_read_byte and *_write_byte naming convention.
Rename via_pram_readbyte and via_pram_writebyte to avoid confusion.
Adjust calling conventions of mac_pram_* functions to match the
arch_nvram_ops struct methods.

Signed-off-by: Finn Thain 

---

Changes since v1:
- Don't introduce the arch_nvram_ops struct in this patch, even if it 
would form a logical progression. Since the struct would get replaced
later on, some might see it as churn.

---
 arch/m68k/mac/misc.c |   91 +--
 1 file changed, 46 insertions(+), 45 deletions(-)

Index: linux/arch/m68k/mac/misc.c
===
--- linux.orig/arch/m68k/mac/misc.c 2015-06-14 17:45:34.0 +1000
+++ linux/arch/m68k/mac/misc.c  2015-06-14 17:46:02.0 +1000
@@ -61,7 +61,7 @@ static void cuda_write_time(long data)
cuda_poll();
 }
 
-static __u8 cuda_read_pram(int offset)
+static unsigned char cuda_pram_read_byte(int offset)
 {
struct adb_request req;
if (cuda_request(&req, NULL, 4, CUDA_PACKET, CUDA_GET_PRAM,
@@ -72,7 +72,7 @@ static __u8 cuda_read_pram(int offset)
return req.reply[3];
 }
 
-static void cuda_write_pram(int offset, __u8 data)
+static void cuda_pram_write_byte(unsigned char data, int offset)
 {
struct adb_request req;
if (cuda_request(&req, NULL, 5, CUDA_PACKET, CUDA_SET_PRAM,
@@ -84,8 +84,8 @@ static void cuda_write_pram(int offset,
 #else
 #define cuda_read_time() 0
 #define cuda_write_time(n)
-#define cuda_read_pram NULL
-#define cuda_write_pram NULL
+#define cuda_pram_read_byte NULL
+#define cuda_pram_write_byte NULL
 #endif
 
 #ifdef CONFIG_ADB_PMU68K
@@ -116,7 +116,7 @@ static void pmu_write_time(long data)
pmu_poll();
 }
 
-static __u8 pmu_read_pram(int offset)
+static unsigned char pmu_pram_read_byte(int offset)
 {
struct adb_request req;
if (pmu_request(&req, NULL, 3, PMU_READ_NVRAM,
@@ -127,7 +127,7 @@ static __u8 pmu_read_pram(int offset)
return req.reply[3];
 }
 
-static void pmu_write_pram(int offset, __u8 data)
+static void pmu_pram_write_byte(unsigned char data, int offset)
 {
struct adb_request req;
if (pmu_request(&req, NULL, 4, PMU_WRITE_NVRAM,
@@ -139,8 +139,8 @@ static void pmu_write_pram(int offset, _
 #else
 #define pmu_read_time() 0
 #define pmu_write_time(n)
-#define pmu_read_pram NULL
-#define pmu_write_pram NULL
+#define pmu_pram_read_byte NULL
+#define pmu_pram_write_byte NULL
 #endif
 
 #if 0 /* def CONFIG_ADB_MACIISI */
@@ -169,7 +169,7 @@ static void maciisi_write_time(long data
(data >> 8) & 0xFF, data & 0xFF);
 }
 
-static __u8 maciisi_read_pram(int offset)
+static unsigned char maciisi_pram_read_byte(int offset)
 {
struct adb_request req;
if (maciisi_request(&req, NULL, 4, CUDA_PACKET, CUDA_GET_PRAM,
@@ -178,7 +178,7 @@ static __u8 maciisi_read_pram(int offset
return req.reply[3];
 }
 
-static void maciisi_write_pram(int offset, __u8 data)
+static void maciisi_pram_write_byte(unsigned char data, int offset)
 {
struct adb_request req;
maciisi_request(&req, NULL, 5, CUDA_PACKET, CUDA_SET_PRAM,
@@ -187,8 +187,8 @@ static void maciisi_write_pram(int offse
 #else
 #define maciisi_read_time() 0
 #define maciisi_write_time(n)
-#define maciisi_read_pram NULL
-#define maciisi_write_pram NULL
+#define maciisi_pram_read_byte NULL
+#define maciisi_pram_write_byte NULL
 #endif
 
 /*
@@ -198,7 +198,7 @@ static void maciisi_write_pram(int offse
  * the RTC should be enabled.
  */
 
-static __u8 via_pram_readbyte(void)
+static __u8 via_pram_recv(void)
 {
int i,reg;
__u8data;
@@ -225,7 +225,7 @@ static __u8 via_pram_readbyte(void)
return data;
 }
 
-static void via_pram_writebyte(__u8 data)
+static void via_pram_send(__u8 data)
 {
int i,reg,bit;
 
@@ -262,17 +262,17 @@ static void via_pram_command(int command
via1[vBufB] = (via1[vBufB] | VIA1B_vRTCClk) & ~VIA1B_vRTCEnb;
 
if (command & 0xFF00) { /* extended (two-byte) command */
-   via_pram_writebyte((command & 0xFF00) >> 8);
-   via_pram_writebyte(command & 0xFF);
+   via_pram_send((command & 0xFF00) >> 8);
+   via_pram_send(command & 0xFF);
is_read = command & 0x8000;
} else {/* one-byte command */
-   via_pram_writebyte(command);
+   via_pram_send(command);
is_read = command & 0x80;
}
if (is_read) {
-   *data = via_pram_readbyte();
+   *data = via_pram_recv();
} else {
-   via_pram_writebyte(*data);
+   via_pram_send(*data);
}
 
/* All done, disable the RTC */
@@ -282,12 +282,12 @@ static void via_pra

[RFC v2 21/24] powerpc: Adopt nvram module for PPC64

2015-06-14 Thread Finn Thain
Adopt nvram module to reduce code duplication.

The IOC_NVRAM_GET_OFFSET ioctl as implemented on PPC64 validates the offset
returned by pmac_get_partition(). Add this test to the nvram module.

Note that the old PPC32 generic_nvram module lacked this test.
So when CONFIG_PPC32 && CONFIG_PPC_PMAC, the IOC_NVRAM_GET_OFFSET ioctl
would have returned 0 (always). But when CONFIG_PPC64 && CONFIG_PPC_PMAC,
the IOC_NVRAM_GET_OFFSET ioctl would have returned -1 (which is -EPERM)
when the requested partition was not found.

With this patch, the result is now -EINVAL on both PPC32 and PPC64 when
the requested PowerMac NVRAM partition is not found.

This is a userspace-visible change, in the non-existent partition case,
which would be in an error path for an IOC_NVRAM_GET_OFFSET ioctl syscall.

Signed-off-by: Finn Thain 

---

BTW, the IOC_NVRAM_SYNC ioctl call returns -EINVAL on PPC64. This patch
retains this behaviour though it might be better to actually perform a sync.
Both PPC64 and PPC32 kernels implement ppc_md.nvram_sync() for Core99,
but on PPC64 the ioctl is unimplemented (unlike PPC32).

---

Changed since v1:
- The -ENOENT that appeared in v1 was changed to -EINVAL, to be
consistent with existing logic, that is,
if (part < pmac_nvram_OF || part > pmac_nvram_NR)
return -EINVAL;

---
 arch/powerpc/Kconfig |3 
 arch/powerpc/kernel/nvram_64.c   |  203 ---
 arch/powerpc/platforms/powermac/Makefile |5 
 arch/powerpc/platforms/powermac/setup.c  |2 
 drivers/char/nvram.c |2 
 5 files changed, 36 insertions(+), 179 deletions(-)

Index: linux/arch/powerpc/Kconfig
===
--- linux.orig/arch/powerpc/Kconfig 2015-06-14 17:45:57.0 +1000
+++ linux/arch/powerpc/Kconfig  2015-06-14 17:46:00.0 +1000
@@ -177,10 +177,9 @@ config SYSVIPC_COMPAT
depends on COMPAT && SYSVIPC
default y
 
-# All PPC32s use generic nvram driver through ppc_md
 config HAVE_ARCH_NVRAM_OPS
bool
-   default y if PPC32
+   default y
 
 config SCHED_OMIT_FRAME_POINTER
bool
Index: linux/arch/powerpc/kernel/nvram_64.c
===
--- linux.orig/arch/powerpc/kernel/nvram_64.c   2015-06-14 17:45:34.0 
+1000
+++ linux/arch/powerpc/kernel/nvram_64.c2015-06-14 17:46:00.0 
+1000
@@ -7,12 +7,6 @@
  *  2 of the License, or (at your option) any later version.
  *
  * /dev/nvram driver for PPC64
- *
- * This perhaps should live in drivers/char
- *
- * TODO: Split the /dev/nvram part (that one can use
- *   drivers/char/generic_nvram.c) from the arch & partition
- *   parsing code.
  */
 
 #include 
@@ -731,153 +725,6 @@ static void oops_to_nvram(struct kmsg_du
spin_unlock_irqrestore(&lock, flags);
 }
 
-static loff_t dev_nvram_llseek(struct file *file, loff_t offset, int origin)
-{
-   int size;
-
-   if (ppc_md.nvram_size == NULL)
-   return -ENODEV;
-   size = ppc_md.nvram_size();
-
-   switch (origin) {
-   case 1:
-   offset += file->f_pos;
-   break;
-   case 2:
-   offset += size;
-   break;
-   }
-   if (offset < 0)
-   return -EINVAL;
-   file->f_pos = offset;
-   return file->f_pos;
-}
-
-
-static ssize_t dev_nvram_read(struct file *file, char __user *buf,
- size_t count, loff_t *ppos)
-{
-   ssize_t ret;
-   char *tmp = NULL;
-   ssize_t size;
-
-   if (!ppc_md.nvram_size) {
-   ret = -ENODEV;
-   goto out;
-   }
-
-   size = ppc_md.nvram_size();
-   if (size < 0) {
-   ret = size;
-   goto out;
-   }
-
-   if (*ppos >= size) {
-   ret = 0;
-   goto out;
-   }
-
-   count = min_t(size_t, count, size - *ppos);
-   count = min(count, PAGE_SIZE);
-
-   tmp = kmalloc(count, GFP_KERNEL);
-   if (!tmp) {
-   ret = -ENOMEM;
-   goto out;
-   }
-
-   ret = ppc_md.nvram_read(tmp, count, ppos);
-   if (ret <= 0)
-   goto out;
-
-   if (copy_to_user(buf, tmp, ret))
-   ret = -EFAULT;
-
-out:
-   kfree(tmp);
-   return ret;
-
-}
-
-static ssize_t dev_nvram_write(struct file *file, const char __user *buf,
- size_t count, loff_t *ppos)
-{
-   ssize_t ret;
-   char *tmp = NULL;
-   ssize_t size;
-
-   ret = -ENODEV;
-   if (!ppc_md.nvram_size)
-   goto out;
-
-   ret = 0;
-   size = ppc_md.nvram_size();
-   if (*ppos >= size || size < 0)
-   goto out;
-
-   count = min_t(size_t, count, size - *ppos);
-   count = min(count, PAGE_SIZE);
-
-   ret = -E

[RFC v2 16/24] powerpc: Implement nvram sync ioctl

2015-06-14 Thread Finn Thain
Add the powerpc-specific sync() method to struct nvram_ops and implement
the corresponding ioctl in the nvram module. This allows the nvram module
to replace the generic_nvram module.

Signed-off-by: Finn Thain 

---

On PPC32, the IOC_NVRAM_SYNC ioctl call always returns 0, even for those
platforms that don't implement ppc_md.nvram_sync. This patch retains
that quirk. It might be better to return failure (which is what PPC64 does).

Changed since v1:
- Don't bother acquiring the mutex for unimplemented ioctls.

---
 arch/powerpc/include/asm/nvram.h |3 ---
 arch/powerpc/kernel/setup_32.c   |6 +++---
 drivers/char/generic_nvram.c |2 +-
 drivers/char/nvram.c |   39 +++
 include/linux/nvram.h|4 
 5 files changed, 47 insertions(+), 7 deletions(-)

Index: linux/drivers/char/nvram.c
===
--- linux.orig/drivers/char/nvram.c 2015-06-14 17:45:48.0 +1000
+++ linux/drivers/char/nvram.c  2015-06-14 17:45:53.0 +1000
@@ -48,6 +48,11 @@
 #include 
 
 
+#ifdef CONFIG_PPC
+#include 
+#include 
+#endif
+
 static DEFINE_MUTEX(nvram_mutex);
 static DEFINE_SPINLOCK(nvram_state_lock);
 static int nvram_open_cnt; /* #times opened */
@@ -338,6 +343,37 @@ static long nvram_misc_ioctl(struct file
long ret = -ENOTTY;
 
switch (cmd) {
+#ifdef CONFIG_PPC
+#ifdef CONFIG_PPC_PMAC
+   case OBSOLETE_PMAC_NVRAM_GET_OFFSET:
+   pr_warn("nvram: Using obsolete PMAC_NVRAM_GET_OFFSET ioctl\n");
+   /* fall through */
+   case IOC_NVRAM_GET_OFFSET: {
+   int part, offset;
+
+   if (!machine_is(powermac))
+   return -EINVAL;
+   if (copy_from_user(&part,
+  (void __user *)arg, sizeof(part)) != 0)
+   return -EFAULT;
+   if (part < pmac_nvram_OF || part > pmac_nvram_NR)
+   return -EINVAL;
+   offset = pmac_get_partition(part);
+   if (copy_to_user((void __user *)arg,
+&offset, sizeof(offset)) != 0)
+   return -EFAULT;
+   ret = 0;
+   break;
+   }
+#endif
+   case IOC_NVRAM_SYNC:
+   if (arch_nvram_ops.sync != NULL) {
+   mutex_lock(&nvram_mutex);
+   ret = arch_nvram_ops.sync();
+   mutex_unlock(&nvram_mutex);
+   }
+   break;
+#else /* !CONFIG_PPC */
case NVRAM_INIT:
/* initialize NVRAM contents and checksum */
if (!capable(CAP_SYS_ADMIN))
@@ -361,6 +397,7 @@ static long nvram_misc_ioctl(struct file
mutex_unlock(&nvram_mutex);
}
break;
+#endif /* CONFIG_PPC */
}
return ret;
 }
@@ -376,6 +413,7 @@ static int nvram_misc_open(struct inode
return -EBUSY;
}
 
+#ifndef CONFIG_PPC
/* Prevent multiple writers if the set_checksum ioctl is implemented. */
if ((arch_nvram_ops.set_checksum != NULL) &&
(file->f_mode & FMODE_WRITE) &&
@@ -383,6 +421,7 @@ static int nvram_misc_open(struct inode
spin_unlock(&nvram_state_lock);
return -EBUSY;
}
+#endif
 
if (file->f_flags & O_EXCL)
nvram_open_mode |= NVRAM_EXCL;
Index: linux/include/linux/nvram.h
===
--- linux.orig/include/linux/nvram.h2015-06-14 17:45:43.0 +1000
+++ linux/include/linux/nvram.h 2015-06-14 17:45:53.0 +1000
@@ -17,8 +17,12 @@ struct nvram_ops {
unsigned char   (*read_byte)(int);
void(*write_byte)(unsigned char, int);
ssize_t (*get_size)(void);
+#ifdef CONFIG_PPC
+   long(*sync)(void);
+#else
long(*set_checksum)(void);
long(*initialize)(void);
+#endif
 };
 
 extern const struct nvram_ops arch_nvram_ops;
Index: linux/arch/powerpc/include/asm/nvram.h
===
--- linux.orig/arch/powerpc/include/asm/nvram.h 2015-06-14 17:45:51.0 
+1000
+++ linux/arch/powerpc/include/asm/nvram.h  2015-06-14 17:45:53.0 
+1000
@@ -78,9 +78,6 @@ extern intpmac_get_partition(int partit
 extern u8  pmac_xpram_read(int xpaddr);
 extern voidpmac_xpram_write(int xpaddr, u8 data);
 
-/* Synchronize NVRAM */
-extern voidnvram_sync(void);
-
 /* Initialize NVRAM OS partition */
 extern int __init nvram_init_os_partition(struct nvram_os_partition *part);
 
Index: linux/arch/powerpc/kernel/setup_32.c
===
--- linux.orig/arch/powerpc/kernel

[RFC v2 18/24] nvram: Drop nvram_* symbol exports and prototypes

2015-06-14 Thread Finn Thain
Drivers now use the arch_nvram_ops calls so remove the function exports and
prototypes. nvram_check_checksum() is unused so remove it.

Signed-off-by: Finn Thain 

---
 arch/m68k/atari/nvram.c |6 +++---
 drivers/char/nvram.c|   27 +--
 include/linux/nvram.h   |8 
 3 files changed, 8 insertions(+), 33 deletions(-)

Index: linux/drivers/char/nvram.c
===
--- linux.orig/drivers/char/nvram.c 2015-06-14 17:45:53.0 +1000
+++ linux/drivers/char/nvram.c  2015-06-14 17:45:56.0 +1000
@@ -82,13 +82,12 @@ static ssize_t nvram_size;
  * periodic 11 min sync from kernel/time/ntp.c vs. this driver.)
  */
 
-unsigned char __nvram_read_byte(int i)
+static unsigned char __nvram_read_byte(int i)
 {
return CMOS_READ(NVRAM_FIRST_BYTE + i);
 }
-EXPORT_SYMBOL(__nvram_read_byte);
 
-unsigned char nvram_read_byte(int i)
+static unsigned char nvram_read_byte(int i)
 {
unsigned long flags;
unsigned char c;
@@ -98,16 +97,14 @@ unsigned char nvram_read_byte(int i)
spin_unlock_irqrestore(&rtc_lock, flags);
return c;
 }
-EXPORT_SYMBOL(nvram_read_byte);
 
 /* This races nicely with trying to read with checksum checking (nvram_read) */
-void __nvram_write_byte(unsigned char c, int i)
+static void __nvram_write_byte(unsigned char c, int i)
 {
CMOS_WRITE(c, NVRAM_FIRST_BYTE + i);
 }
-EXPORT_SYMBOL(__nvram_write_byte);
 
-void nvram_write_byte(unsigned char c, int i)
+static void nvram_write_byte(unsigned char c, int i)
 {
unsigned long flags;
 
@@ -115,14 +112,13 @@ void nvram_write_byte(unsigned char c, i
__nvram_write_byte(c, i);
spin_unlock_irqrestore(&rtc_lock, flags);
 }
-EXPORT_SYMBOL(nvram_write_byte);
 
 /* On PCs, the checksum is built only over bytes 2..31 */
 #define PC_CKS_RANGE_START 2
 #define PC_CKS_RANGE_END   31
 #define PC_CKS_LOC 32
 
-int __nvram_check_checksum(void)
+static int __nvram_check_checksum(void)
 {
int i;
unsigned short sum = 0;
@@ -134,19 +130,6 @@ int __nvram_check_checksum(void)
__nvram_read_byte(PC_CKS_LOC+1);
return (sum & 0x) == expect;
 }
-EXPORT_SYMBOL(__nvram_check_checksum);
-
-int nvram_check_checksum(void)
-{
-   unsigned long flags;
-   int rv;
-
-   spin_lock_irqsave(&rtc_lock, flags);
-   rv = __nvram_check_checksum();
-   spin_unlock_irqrestore(&rtc_lock, flags);
-   return rv;
-}
-EXPORT_SYMBOL(nvram_check_checksum);
 
 static void __nvram_set_checksum(void)
 {
Index: linux/include/linux/nvram.h
===
--- linux.orig/include/linux/nvram.h2015-06-14 17:45:53.0 +1000
+++ linux/include/linux/nvram.h 2015-06-14 17:45:56.0 +1000
@@ -3,14 +3,6 @@
 
 #include 
 
-/* __foo is foo without grabbing the rtc_lock - get it yourself */
-extern unsigned char __nvram_read_byte(int i);
-extern unsigned char nvram_read_byte(int i);
-extern void __nvram_write_byte(unsigned char c, int i);
-extern void nvram_write_byte(unsigned char c, int i);
-extern int __nvram_check_checksum(void);
-extern int nvram_check_checksum(void);
-
 struct nvram_ops {
ssize_t (*read)(char *, size_t, loff_t *);
ssize_t (*write)(char *, size_t, loff_t *);
Index: linux/arch/m68k/atari/nvram.c
===
--- linux.orig/arch/m68k/atari/nvram.c  2015-06-14 17:45:47.0 +1000
+++ linux/arch/m68k/atari/nvram.c   2015-06-14 17:45:56.0 +1000
@@ -33,13 +33,13 @@
  * periodic 11 min sync from kernel/time/ntp.c vs. this driver.)
  */
 
-unsigned char __nvram_read_byte(int i)
+static unsigned char __nvram_read_byte(int i)
 {
return CMOS_READ(NVRAM_FIRST_BYTE + i);
 }
 
 /* This races nicely with trying to read with checksum checking */
-void __nvram_write_byte(unsigned char c, int i)
+static void __nvram_write_byte(unsigned char c, int i)
 {
CMOS_WRITE(c, NVRAM_FIRST_BYTE + i);
 }
@@ -51,7 +51,7 @@ void __nvram_write_byte(unsigned char c,
 #define ATARI_CKS_RANGE_END47
 #define ATARI_CKS_LOC  48
 
-int __nvram_check_checksum(void)
+static int __nvram_check_checksum(void)
 {
int i;
unsigned char sum = 0;


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[RFC v2 20/24] char/generic_nvram: Remove as unused

2015-06-14 Thread Finn Thain
And thus eliminate some twisted CONFIG_GENERIC_NVRAM logic.

Signed-off-by: Finn Thain 

---
 drivers/char/Makefile|6 -
 drivers/char/generic_nvram.c |  176 ---
 2 files changed, 1 insertion(+), 181 deletions(-)

Index: linux/drivers/char/Makefile
===
--- linux.orig/drivers/char/Makefile2015-06-14 17:45:34.0 +1000
+++ linux/drivers/char/Makefile 2015-06-14 17:45:59.0 +1000
@@ -30,11 +30,7 @@ obj-$(CONFIG_GEN_RTC)+= genrtc.o
 obj-$(CONFIG_EFI_RTC)  += efirtc.o
 obj-$(CONFIG_DS1302)   += ds1302.o
 obj-$(CONFIG_XILINX_HWICAP)+= xilinx_hwicap/
-ifeq ($(CONFIG_GENERIC_NVRAM),y)
-  obj-$(CONFIG_NVRAM)  += generic_nvram.o
-else
-  obj-$(CONFIG_NVRAM)  += nvram.o
-endif
+obj-$(CONFIG_NVRAM)+= nvram.o
 obj-$(CONFIG_TOSHIBA)  += toshiba.o
 obj-$(CONFIG_I8K)  += i8k.o
 obj-$(CONFIG_DS1620)   += ds1620.o
Index: linux/drivers/char/generic_nvram.c
===
--- linux.orig/drivers/char/generic_nvram.c 2015-06-14 17:45:54.0 
+1000
+++ /dev/null   1970-01-01 00:00:00.0 +
@@ -1,176 +0,0 @@
-/*
- * Generic /dev/nvram driver for architectures providing some
- * "generic" hooks, that is :
- *
- * nvram_read_byte, nvram_write_byte, nvram_sync, nvram_get_size
- *
- * Note that an additional hook is supported for PowerMac only
- * for getting the nvram "partition" informations
- *
- */
-
-#define NVRAM_VERSION "1.1"
-
-#include 
-
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-
-#ifdef CONFIG_PPC_PMAC
-#include 
-#include 
-#endif
-
-static DEFINE_MUTEX(nvram_mutex);
-static ssize_t nvram_len;
-
-static loff_t nvram_llseek(struct file *file, loff_t offset, int origin)
-{
-   switch (origin) {
-   case 0:
-   break;
-   case 1:
-   offset += file->f_pos;
-   break;
-   case 2:
-   offset += nvram_len;
-   break;
-   default:
-   offset = -1;
-   }
-   if (offset < 0)
-   return -EINVAL;
-
-   file->f_pos = offset;
-
-   return file->f_pos;
-}
-
-static ssize_t read_nvram(struct file *file, char __user *buf,
- size_t count, loff_t *ppos)
-{
-   unsigned int i;
-   char __user *p = buf;
-
-   if (!access_ok(VERIFY_WRITE, buf, count))
-   return -EFAULT;
-   if (*ppos >= nvram_len)
-   return 0;
-   for (i = *ppos; count > 0 && i < nvram_len; ++i, ++p, --count)
-   if (__put_user(arch_nvram_ops.read_byte(i), p))
-   return -EFAULT;
-   *ppos = i;
-   return p - buf;
-}
-
-static ssize_t write_nvram(struct file *file, const char __user *buf,
-  size_t count, loff_t *ppos)
-{
-   unsigned int i;
-   const char __user *p = buf;
-   char c;
-
-   if (!access_ok(VERIFY_READ, buf, count))
-   return -EFAULT;
-   if (*ppos >= nvram_len)
-   return 0;
-   for (i = *ppos; count > 0 && i < nvram_len; ++i, ++p, --count) {
-   if (__get_user(c, p))
-   return -EFAULT;
-   arch_nvram_ops.write_byte(c, i);
-   }
-   *ppos = i;
-   return p - buf;
-}
-
-static int nvram_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
-   switch(cmd) {
-#ifdef CONFIG_PPC_PMAC
-   case OBSOLETE_PMAC_NVRAM_GET_OFFSET:
-   printk(KERN_WARNING "nvram: Using obsolete 
PMAC_NVRAM_GET_OFFSET ioctl\n");
-   case IOC_NVRAM_GET_OFFSET: {
-   int part, offset;
-
-   if (!machine_is(powermac))
-   return -EINVAL;
-   if (copy_from_user(&part, (void __user*)arg, sizeof(part)) != 0)
-   return -EFAULT;
-   if (part < pmac_nvram_OF || part > pmac_nvram_NR)
-   return -EINVAL;
-   offset = pmac_get_partition(part);
-   if (copy_to_user((void __user*)arg, &offset, sizeof(offset)) != 
0)
-   return -EFAULT;
-   break;
-   }
-#endif /* CONFIG_PPC_PMAC */
-   case IOC_NVRAM_SYNC:
-   arch_nvram_ops.sync();
-   break;
-   default:
-   return -EINVAL;
-   }
-
-   return 0;
-}
-
-static long nvram_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned 
long arg)
-{
-   int ret;
-
-   mutex_lock(&nvram_mutex);
-   ret = nvram_ioctl(file, cmd, arg);
-   mutex_unlock(&nvram_mutex);
-
-   return ret;
-}
-
-const struct file_operations nvram_fops = {
-   .owner  = THIS_MODULE,
-  

[RFC v2 23/24] m68k/mac: Fix PRAM accessors

2015-06-14 Thread Finn Thain
Signed-off-by: Finn Thain 

---

Tested on a PowerBook 520 and Quadra 650.

---
 arch/m68k/mac/misc.c |   35 +--
 include/uapi/linux/pmu.h |2 ++
 2 files changed, 31 insertions(+), 6 deletions(-)

Index: linux/arch/m68k/mac/misc.c
===
--- linux.orig/arch/m68k/mac/misc.c 2015-06-14 17:46:02.0 +1000
+++ linux/arch/m68k/mac/misc.c  2015-06-14 17:46:03.0 +1000
@@ -119,19 +119,22 @@ static void pmu_write_time(long data)
 static unsigned char pmu_pram_read_byte(int offset)
 {
struct adb_request req;
-   if (pmu_request(&req, NULL, 3, PMU_READ_NVRAM,
-   (offset >> 8) & 0xFF, offset & 0xFF) < 0)
+
+   if (pmu_request(&req, NULL, 3, PMU_READ_XPRAM,
+   offset & 0xFF, 1) < 0)
return 0;
while (!req.complete)
pmu_poll();
-   return req.reply[3];
+
+   return req.reply[1];
 }
 
 static void pmu_pram_write_byte(unsigned char data, int offset)
 {
struct adb_request req;
-   if (pmu_request(&req, NULL, 4, PMU_WRITE_NVRAM,
-   (offset >> 8) & 0xFF, offset & 0xFF, data) < 0)
+
+   if (pmu_request(&req, NULL, 4, PMU_WRITE_XPRAM,
+   offset & 0xFF, 1, data) < 0)
return;
while (!req.complete)
pmu_poll();
@@ -284,11 +287,31 @@ static void via_pram_command(int command
 
 static unsigned char via_pram_read_byte(int offset)
 {
-   return 0;
+   unsigned char temp;
+   int addr = ((offset & 0xE0) << 3) | ((offset & 0x1F) << 2);
+
+   /* Use RTC command 0x38 for XPRAM access, as per MESS source code */
+   via_pram_command(addr | 0x3800 | 0x8001, &temp);
+
+   return temp;
 }
 
 static void via_pram_write_byte(unsigned char data, int offset)
 {
+   unsigned char temp;
+   int addr = ((offset & 0xE0) << 3) | ((offset & 0x1F) << 2);
+
+   /* Clear the write protect bit */
+   temp = 0x55;
+   via_pram_command(0x34 | 0x01, &temp);
+
+   /* Write the byte to XPRAM */
+   temp = data;
+   via_pram_command(0x3800 | 0x0001 | addr, &temp);
+
+   /* Set the write protect bit */
+   temp = 0xD5;
+   via_pram_command(0x34 | 0x01, &temp);
 }
 
 /*
Index: linux/include/uapi/linux/pmu.h
===
--- linux.orig/include/uapi/linux/pmu.h 2015-06-14 17:45:34.0 +1000
+++ linux/include/uapi/linux/pmu.h  2015-06-14 17:46:03.0 +1000
@@ -18,7 +18,9 @@
 #define PMU_POWER_CTRL 0x11/* control power of some devices */
 #define PMU_ADB_CMD0x20/* send ADB packet */
 #define PMU_ADB_POLL_OFF   0x21/* disable ADB auto-poll */
+#define PMU_WRITE_XPRAM0x32/* write eXtended Parameter RAM 
*/
 #define PMU_WRITE_NVRAM0x33/* write non-volatile RAM */
+#define PMU_READ_XPRAM 0x3a/* read eXtended Parameter RAM */
 #define PMU_READ_NVRAM 0x3b/* read non-volatile RAM */
 #define PMU_SET_RTC0x30/* set real-time clock */
 #define PMU_READ_RTC   0x38/* read real-time clock */


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[RFC v2 24/24] m68k: Dispatch nvram_ops calls to Atari or Mac functions

2015-06-14 Thread Finn Thain
A multi-platform kernel binary needs to decide at run-time how to dispatch
the arch_nvram_ops calls. Add platform-independent arch_nvram_ops, for use
when multiple platform-specific NVRAM ops implementations are needed.

Enable CONFIG_HAVE_ARCH_NVRAM_OPS for Macs.

Signed-off-by: Finn Thain 

---

Changed since v1:
- Removed Mac and Atari ops struct definitions and the associated #ifdefs.
- Moved extern declarations for fewer lines of code and better readability.
- The IS_ENABLED(CONFIG_NVRAM) tests were moved to this patch, because it is
now in this patch that CONFIG_HAVE_ARCH_NVRAM_OPS is enabled for Macs.

---
 arch/m68k/Kconfig   |2 
 arch/m68k/atari/nvram.c |   21 ++--
 arch/m68k/kernel/setup_mm.c |  107 
 arch/m68k/mac/misc.c|   18 +++
 4 files changed, 131 insertions(+), 17 deletions(-)

Index: linux/arch/m68k/mac/misc.c
===
--- linux.orig/arch/m68k/mac/misc.c 2015-06-14 17:46:03.0 +1000
+++ linux/arch/m68k/mac/misc.c  2015-06-14 17:46:04.0 +1000
@@ -61,6 +61,7 @@ static void cuda_write_time(long data)
cuda_poll();
 }
 
+#if IS_ENABLED(CONFIG_NVRAM)
 static unsigned char cuda_pram_read_byte(int offset)
 {
struct adb_request req;
@@ -81,6 +82,8 @@ static void cuda_pram_write_byte(unsigne
while (!req.complete)
cuda_poll();
 }
+#endif /* CONFIG_NVRAM */
+
 #else
 #define cuda_read_time() 0
 #define cuda_write_time(n)
@@ -116,6 +119,7 @@ static void pmu_write_time(long data)
pmu_poll();
 }
 
+#if IS_ENABLED(CONFIG_NVRAM)
 static unsigned char pmu_pram_read_byte(int offset)
 {
struct adb_request req;
@@ -139,6 +143,8 @@ static void pmu_pram_write_byte(unsigned
while (!req.complete)
pmu_poll();
 }
+#endif /* CONFIG_NVRAM */
+
 #else
 #define pmu_read_time() 0
 #define pmu_write_time(n)
@@ -172,6 +178,7 @@ static void maciisi_write_time(long data
(data >> 8) & 0xFF, data & 0xFF);
 }
 
+#if IS_ENABLED(CONFIG_NVRAM)
 static unsigned char maciisi_pram_read_byte(int offset)
 {
struct adb_request req;
@@ -187,6 +194,8 @@ static void maciisi_pram_write_byte(unsi
maciisi_request(&req, NULL, 5, CUDA_PACKET, CUDA_SET_PRAM,
(offset >> 8) & 0xFF, offset & 0xFF, data);
 }
+#endif /* CONFIG_NVRAM */
+
 #else
 #define maciisi_read_time() 0
 #define maciisi_write_time(n)
@@ -285,6 +294,7 @@ static void via_pram_command(int command
local_irq_restore(flags);
 }
 
+#if IS_ENABLED(CONFIG_NVRAM)
 static unsigned char via_pram_read_byte(int offset)
 {
unsigned char temp;
@@ -313,6 +323,7 @@ static void via_pram_write_byte(unsigned
temp = 0xD5;
via_pram_command(0x34 | 0x01, &temp);
 }
+#endif /* CONFIG_NVRAM */
 
 /*
  * Return the current time in seconds since January 1, 1904.
@@ -476,6 +487,7 @@ void pmu_shutdown(void)
  *---
  */
 
+#if IS_ENABLED(CONFIG_NVRAM)
 unsigned char mac_pram_read_byte(int addr)
 {
unsigned char (*func)(int);
@@ -523,6 +535,12 @@ void mac_pram_write_byte(unsigned char v
(*func)(val, addr);
 }
 
+ssize_t mac_pram_get_size(void)
+{
+   return 256;
+}
+#endif /* CONFIG_NVRAM */
+
 void mac_poweroff(void)
 {
/*
Index: linux/arch/m68k/atari/nvram.c
===
--- linux.orig/arch/m68k/atari/nvram.c  2015-06-14 17:45:56.0 +1000
+++ linux/arch/m68k/atari/nvram.c   2015-06-14 17:46:04.0 +1000
@@ -73,7 +73,7 @@ static void __nvram_set_checksum(void)
__nvram_write_byte(sum, ATARI_CKS_LOC + 1);
 }
 
-static long nvram_set_checksum(void)
+long atari_nvram_set_checksum(void)
 {
spin_lock_irq(&rtc_lock);
__nvram_set_checksum();
@@ -81,7 +81,7 @@ static long nvram_set_checksum(void)
return 0;
 }
 
-static long nvram_initialize(void)
+long atari_nvram_initialize(void)
 {
loff_t i;
 
@@ -93,7 +93,7 @@ static long nvram_initialize(void)
return 0;
 }
 
-static ssize_t nvram_read(char *buf, size_t count, loff_t *ppos)
+ssize_t atari_nvram_read(char *buf, size_t count, loff_t *ppos)
 {
char *p = buf;
loff_t i;
@@ -114,7 +114,7 @@ static ssize_t nvram_read(char *buf, siz
return p - buf;
 }
 
-static ssize_t nvram_write(char *buf, size_t count, loff_t *ppos)
+ssize_t atari_nvram_write(char *buf, size_t count, loff_t *ppos)
 {
char *p = buf;
loff_t i;
@@ -137,22 +137,11 @@ static ssize_t nvram_write(char *buf, si
return p - buf;
 }
 
-static ssize_t nvram_get_size(void)
+ssize_t atari_nvram_get_size(void)
 {
-   if (!MACH_IS_ATARI)
-   return -ENODEV;
return NVRAM_BYTES;
 }
 
-const struct nvram_ops arch_nvram_ops = {
-   .rea

Re: [RFC v2 23/24] m68k/mac: Fix PRAM accessors

2015-06-15 Thread Finn Thain

On Mon, 15 Jun 2015, Geert Uytterhoeven wrote:

> Hi Finn,
> 
> On Sun, Jun 14, 2015 at 9:46 AM, Finn Thain  
> wrote:
> > --- linux.orig/arch/m68k/mac/misc.c 2015-06-14 17:46:02.0 +1000
> > +++ linux/arch/m68k/mac/misc.c  2015-06-14 17:46:03.0 +1000
> > @@ -284,11 +287,31 @@ static void via_pram_command(int command
> >
> >  static unsigned char via_pram_read_byte(int offset)
> >  {
> > -   return 0;
> > +   unsigned char temp;
> > +   int addr = ((offset & 0xE0) << 3) | ((offset & 0x1F) << 2);
> 
> Can you please add #defines for the magic values?

This is just marshalling the offset argument. I don't know how to rewrite 
that code more clearly. I'm open to suggestions. I don't know of any 
documentation that gives names or meanings to the different bit ranges. I 
infered the format from the MESS source code, 
https://github.com/mamedev/mame/blob/master/src/mess/machine/macrtc.c

What I found in the MESS source code looks like the result of reverse 
engineering. Hence the RTC code in this patch also looks like a reverse 
engineered driver.

> 
> > +
> > +   /* Use RTC command 0x38 for XPRAM access, as per MESS source code */
> > +   via_pram_command(addr | 0x3800 | 0x8001, &temp);
> 
> It seems 0x38 is already documented in  (see below), or not 
> (it's shifted left by 8 bits?)?

No, this is a RTC command not a PMU command. This RTC device is an Apple 
custom IC that is publicly undocumented. OTOH, the PMU device is well 
documented, since Apple publicly released PMU driver source code in 
MkLinux and later in XNU. That's why I've been able to provide #defines 
for the PMU commands but not the RTC commands.

> 
> > +
> > +   return temp;
> >  }
> >
> >  static void via_pram_write_byte(unsigned char data, int offset)
> >  {
> > +   unsigned char temp;
> > +   int addr = ((offset & 0xE0) << 3) | ((offset & 0x1F) << 2);
> > +
> > +   /* Clear the write protect bit */
> > +   temp = 0x55;
> > +   via_pram_command(0x34 | 0x01, &temp);
> > +
> > +   /* Write the byte to XPRAM */
> > +   temp = data;
> > +   via_pram_command(0x3800 | 0x0001 | addr, &temp);
> > +
> > +   /* Set the write protect bit */
> > +   temp = 0xD5;
> > +   via_pram_command(0x34 | 0x01, &temp);
> 
> More magic values...

When I have reliable documentation I always define macros. So I agree that 
"command" bytes like 0x34 and 0x3800 should have names but what are the 
correct names? Are we constructing an opcode containing RTC register file 
addresses or are we issuing read/write accesses to chip registers?

In my experience with undocumented 68k Mac hardware and its Linux port, 
codified guesswork is worse than no documentation at all. The only useful 
RTC documentation I've ever come across is this: 
http://mac.linux-m68k.org/devel/plushw.php

It tells us that the two least significant bits bits must equal 0b01. What 
would you call that macro? It also tells us that the most significant bit, 
0x80, means "read access" but it only mentions early RTC chips and so it 
does not cover two byte opcodes. Should I have used 0x8080 here?

Whatever your opinion of reverse engineered drivers, the changes in this 
patch are consistent with the rest of the file. E.g. via_read_time() and 
via_write_time(). If/when we have the chip data needed to correctly define 
macros for 0x01, 0x0001, 0x80, 0x8000 or 0x8080, I think they should be 
applied across the entire file, and in a different patch. Inconsistent use 
of such macros would be undesirable IMHO.

> 
> >  }
> >
> >  /*
> > Index: linux/include/uapi/linux/pmu.h
> > ===
> > --- linux.orig/include/uapi/linux/pmu.h 2015-06-14 17:45:34.0 +1000
> > +++ linux/include/uapi/linux/pmu.h  2015-06-14 17:46:03.0 +1000
> > @@ -18,7 +18,9 @@
> >  #define PMU_POWER_CTRL 0x11/* control power of some devices */
> >  #define PMU_ADB_CMD0x20/* send ADB packet */
> >  #define PMU_ADB_POLL_OFF   0x21/* disable ADB auto-poll */
> > +#define PMU_WRITE_XPRAM0x32/* write eXtended Parameter 
> > RAM */
> >  #define PMU_WRITE_NVRAM0x33/* write non-volatile RAM */
> > +#define PMU_READ_XPRAM 0x3a/* read eXtended Parameter RAM */
> >  #define PMU_READ_NVRAM 0x3b/* read non-volatile RAM */
> >  #define PMU_SET_RTC0x30/* set real-time clock */
> >  #define PMU_READ_RTC   0x38/* read real-time clock */
> 
> Gr{oetje,eeting}s,
> 
> Geert
> 

-- 
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [RFC v2 23/24] m68k/mac: Fix PRAM accessors

2015-06-17 Thread Finn Thain

Hi Geert,

Further to my previous email,

On Tue, 16 Jun 2015, in which I wrote:

> 
> On Mon, 15 Jun 2015, Geert Uytterhoeven wrote:
> 
> > 
> > More magic values...
> 
> [...] The only useful RTC documentation I've ever come across is this: 
> http://mac.linux-m68k.org/devel/plushw.php

This document appears to be Inside Macintosh vol. III ch. 2. It describes 
the early RTC chip that lacks two-byte operations and XPRAM, and pre-dates 
all Mac hardware supported in mainline Linux. But it does offer some 
useful data, though not enough to answer all of your criticisms (as I 
said).

> [...] I think they should be applied across the entire file, and in a 
> different patch. Inconsistent use of such macros would be undesirable 
> IMHO.

So, unless you have other ideas, I will revise this patch and insert an 
earlier patch to address existing code, and codify what little reliable 
chip data we have.

-- 
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[RFC v3 03/24] m68k/atari: Replace nvram_{read, write}_byte with arch_nvram_ops

2015-06-27 Thread Finn Thain
By implementing an arch_nvram_ops struct, any platform can re-use the
drivers/char/nvram module without needing any arch-specific code
in that module. Atari does so here.

Atari has one user of nvram_check_checksum() whereas the other platforms
(i.e. x86 and ARM platforms) have none at all. Replace this
validate-checksum-and-read-byte sequence with the equivalent
rtc_nvram_ops.read() call and remove the now unused functions.

Signed-off-by: Finn Thain 

---

The advantage of the new ops struct over the old global nvram_* functions
is that the misc device module can be shared by different platforms
without requiring every platform to implement every nvram_* function.
E.g. only RTC "CMOS" NVRAMs have a checksum and only PowerPC platforms
have a "sync" ioctl.

---
 arch/m68k/atari/nvram.c   |   89 --
 drivers/scsi/atari_scsi.c |8 ++--
 include/linux/nvram.h |9 
 3 files changed, 70 insertions(+), 36 deletions(-)

Index: linux/arch/m68k/atari/nvram.c
===
--- linux.orig/arch/m68k/atari/nvram.c  2015-06-28 11:41:29.0 +1000
+++ linux/arch/m68k/atari/nvram.c   2015-06-28 11:41:31.0 +1000
@@ -38,33 +38,12 @@ unsigned char __nvram_read_byte(int i)
return CMOS_READ(NVRAM_FIRST_BYTE + i);
 }
 
-unsigned char nvram_read_byte(int i)
-{
-   unsigned long flags;
-   unsigned char c;
-
-   spin_lock_irqsave(&rtc_lock, flags);
-   c = __nvram_read_byte(i);
-   spin_unlock_irqrestore(&rtc_lock, flags);
-   return c;
-}
-EXPORT_SYMBOL(nvram_read_byte);
-
 /* This races nicely with trying to read with checksum checking */
 void __nvram_write_byte(unsigned char c, int i)
 {
CMOS_WRITE(c, NVRAM_FIRST_BYTE + i);
 }
 
-void nvram_write_byte(unsigned char c, int i)
-{
-   unsigned long flags;
-
-   spin_lock_irqsave(&rtc_lock, flags);
-   __nvram_write_byte(c, i);
-   spin_unlock_irqrestore(&rtc_lock, flags);
-}
-
 /* On Ataris, the checksum is over all bytes except the checksum bytes
  * themselves; these are at the very end.
  */
@@ -83,18 +62,6 @@ int __nvram_check_checksum(void)
   (__nvram_read_byte(ATARI_CKS_LOC + 1) == (sum & 0xff));
 }
 
-int nvram_check_checksum(void)
-{
-   unsigned long flags;
-   int rv;
-
-   spin_lock_irqsave(&rtc_lock, flags);
-   rv = __nvram_check_checksum();
-   spin_unlock_irqrestore(&rtc_lock, flags);
-   return rv;
-}
-EXPORT_SYMBOL(nvram_check_checksum);
-
 static void __nvram_set_checksum(void)
 {
int i;
@@ -106,6 +73,62 @@ static void __nvram_set_checksum(void)
__nvram_write_byte(sum, ATARI_CKS_LOC + 1);
 }
 
+static ssize_t nvram_read(char *buf, size_t count, loff_t *ppos)
+{
+   char *p = buf;
+   loff_t i;
+
+   spin_lock_irq(&rtc_lock);
+
+   if (!__nvram_check_checksum()) {
+   spin_unlock_irq(&rtc_lock);
+   return -EIO;
+   }
+
+   for (i = *ppos; count > 0 && i < NVRAM_BYTES; --count, ++i, ++p)
+   *p = __nvram_read_byte(i);
+
+   spin_unlock_irq(&rtc_lock);
+
+   *ppos = i;
+   return p - buf;
+}
+
+static ssize_t nvram_write(char *buf, size_t count, loff_t *ppos)
+{
+   char *p = buf;
+   loff_t i;
+
+   spin_lock_irq(&rtc_lock);
+
+   if (!__nvram_check_checksum()) {
+   spin_unlock_irq(&rtc_lock);
+   return -EIO;
+   }
+
+   for (i = *ppos; count > 0 && i < NVRAM_BYTES; --count, ++i, ++p)
+   __nvram_write_byte(*p, i);
+
+   __nvram_set_checksum();
+
+   spin_unlock_irq(&rtc_lock);
+
+   *ppos = i;
+   return p - buf;
+}
+
+static ssize_t nvram_get_size(void)
+{
+   return NVRAM_BYTES;
+}
+
+const struct nvram_ops arch_nvram_ops = {
+   .read   = nvram_read,
+   .write  = nvram_write,
+   .get_size   = nvram_get_size,
+};
+EXPORT_SYMBOL(arch_nvram_ops);
+
 #ifdef CONFIG_PROC_FS
 static struct {
unsigned char val;
Index: linux/drivers/scsi/atari_scsi.c
===
--- linux.orig/drivers/scsi/atari_scsi.c2015-06-28 11:41:28.0 
+1000
+++ linux/drivers/scsi/atari_scsi.c 2015-06-28 11:41:31.0 +1000
@@ -880,13 +880,15 @@ static int __init atari_scsi_probe(struc
 #ifdef CONFIG_NVRAM
else
/* Test if a host id is set in the NVRam */
-   if (ATARIHW_PRESENT(TT_CLK) && nvram_check_checksum()) {
-   unsigned char b = nvram_read_byte(14);
+   if (ATARIHW_PRESENT(TT_CLK)) {
+   unsigned char b;
+   loff_t offset = 14;
+   ssize_t count = arch_nvram_ops.read(&b, 1, &offset);
 
/* Arbitration enabled? (for TOS)

[RFC v3 04/24] char/nvram: Re-order functions to remove forward declarations and #ifdefs

2015-06-27 Thread Finn Thain
Also give functions more sensible names: nvram_misc_* for misc device ops,
nvram_proc_* for proc file ops and nvram_module_* for init and exit
functions. This makes them distict from nvram_ops members.

Signed-off-by: Finn Thain 

---
 drivers/char/nvram.c |  194 ++-
 1 file changed, 86 insertions(+), 108 deletions(-)

Index: linux/drivers/char/nvram.c
===
--- linux.orig/drivers/char/nvram.c 2015-06-28 11:41:29.0 +1000
+++ linux/drivers/char/nvram.c  2015-06-28 11:41:32.0 +1000
@@ -54,11 +54,6 @@ static int nvram_open_mode;  /* special o
 #define NVRAM_WRITE1 /* opened for writing (exclusive) */
 #define NVRAM_EXCL 2 /* opened with O_EXCL */
 
-#ifdef CONFIG_PROC_FS
-static void pc_nvram_proc_read(unsigned char *contents, struct seq_file *seq,
-   void *offset);
-#endif
-
 /*
  * These functions are provided to be called internally or by other parts of
  * the kernel. It's up to the caller to ensure correct checksum before reading
@@ -170,7 +165,7 @@ void nvram_set_checksum(void)
  * The are the file operation function for user access to /dev/nvram
  */
 
-static loff_t nvram_llseek(struct file *file, loff_t offset, int origin)
+static loff_t nvram_misc_llseek(struct file *file, loff_t offset, int origin)
 {
switch (origin) {
case 0:
@@ -189,8 +184,8 @@ static loff_t nvram_llseek(struct file *
return (offset >= 0) ? (file->f_pos = offset) : -EINVAL;
 }
 
-static ssize_t nvram_read(struct file *file, char __user *buf,
-   size_t count, loff_t *ppos)
+static ssize_t nvram_misc_read(struct file *file, char __user *buf,
+   size_t count, loff_t *ppos)
 {
unsigned char contents[NVRAM_BYTES];
unsigned i = *ppos;
@@ -218,8 +213,8 @@ checksum_err:
return -EIO;
 }
 
-static ssize_t nvram_write(struct file *file, const char __user *buf,
-   size_t count, loff_t *ppos)
+static ssize_t nvram_misc_write(struct file *file, const char __user *buf,
+size_t count, loff_t *ppos)
 {
unsigned char contents[NVRAM_BYTES];
unsigned i = *ppos;
@@ -257,8 +252,8 @@ checksum_err:
return -EIO;
 }
 
-static long nvram_ioctl(struct file *file, unsigned int cmd,
-   unsigned long arg)
+static long nvram_misc_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
 {
int i;
 
@@ -298,7 +293,7 @@ static long nvram_ioctl(struct file *fil
}
 }
 
-static int nvram_open(struct inode *inode, struct file *file)
+static int nvram_misc_open(struct inode *inode, struct file *file)
 {
spin_lock(&nvram_state_lock);
 
@@ -320,7 +315,7 @@ static int nvram_open(struct inode *inod
return 0;
 }
 
-static int nvram_release(struct inode *inode, struct file *file)
+static int nvram_misc_release(struct inode *inode, struct file *file)
 {
spin_lock(&nvram_state_lock);
 
@@ -337,100 +332,6 @@ static int nvram_release(struct inode *i
return 0;
 }
 
-#ifndef CONFIG_PROC_FS
-static int nvram_add_proc_fs(void)
-{
-   return 0;
-}
-
-#else
-
-static int nvram_proc_read(struct seq_file *seq, void *offset)
-{
-   unsigned char contents[NVRAM_BYTES];
-   int i = 0;
-
-   spin_lock_irq(&rtc_lock);
-   for (i = 0; i < NVRAM_BYTES; ++i)
-   contents[i] = __nvram_read_byte(i);
-   spin_unlock_irq(&rtc_lock);
-
-   pc_nvram_proc_read(contents, seq, offset);
-
-   return 0;
-}
-
-static int nvram_proc_open(struct inode *inode, struct file *file)
-{
-   return single_open(file, nvram_proc_read, NULL);
-}
-
-static const struct file_operations nvram_proc_fops = {
-   .owner  = THIS_MODULE,
-   .open   = nvram_proc_open,
-   .read   = seq_read,
-   .llseek = seq_lseek,
-   .release= single_release,
-};
-
-static int nvram_add_proc_fs(void)
-{
-   if (!proc_create("driver/nvram", 0, NULL, &nvram_proc_fops))
-   return -ENOMEM;
-   return 0;
-}
-
-#endif /* CONFIG_PROC_FS */
-
-static const struct file_operations nvram_fops = {
-   .owner  = THIS_MODULE,
-   .llseek = nvram_llseek,
-   .read   = nvram_read,
-   .write  = nvram_write,
-   .unlocked_ioctl = nvram_ioctl,
-   .open   = nvram_open,
-   .release= nvram_release,
-};
-
-static struct miscdevice nvram_dev = {
-   NVRAM_MINOR,
-   "nvram",
-   &nvram_fops
-};
-
-static int __init nvram_init(void)
-{
-   int ret;
-
-   ret = misc_register(&nvram_dev);
-   if (ret) {
-   printk(KERN_ERR "nvram: can't misc_register on

[RFC v3 00/24] Re-use nvram module

2015-06-27 Thread Finn Thain

The generic NVRAM module, drivers/char/generic_nvram, implements a
/dev/nvram misc device. It is used only by 32-bit PowerPC platforms and
isn't generic enough to be more widely used.

The RTC NVRAM module, drivers/char/nvram, also implements a /dev/nvram
misc device. It is used by x86, ARM and m68k.

The former module cannot be used on x86, ARM or m68k because it
cannot co-exist with the latter module, partly due to the Kconfig logic.

It is possible to modify the modules so that one kernel binary could
have either, neither or both. However, automatically loading the
appropriate module is then impossible; if both provide the
char-major-10-144 alias then the wrong module will end up being loaded.
Hence a multi-platform kernel binary needs a single generic nvram module
with alias char-major-10-144.

Therefore, drivers/char/nvram.c should be made more generic and the
arch-specific code therein should be moved to a more appropriate
place under arch/. Also, drivers/char/generic_nvram.c should be removed
to reduce code duplication.

In this patch series, Atari-specific code is moved from the nvram module
to arch/m68k/atari. More arch-specific code in the nvram module could
be moved, probably to arch/x86, but it is difficult to determine just
what code is relevant to ARM platforms and what code is x86-only.

In addressing code duplication, this patch series removes three
inconsistent /dev/nvram misc device implementations. One of these,
drivers/macintosh/nvram.c is entirely unused already. The other two,
drivers/char/generic_nvram.c and the misc device implementation in
arch/powerpc/kernel/nvram_64.c, are replaced by drivers/char/nvram.c.

A benefit of this work is better consistency -- between PPC32 and PPC64
as well as between PPC_PMAC and MAC. This new uniformity does have
implications for userspace, that is, some error codes for some ioctl calls
become consistent on all PowerPC platforms.

The drivers/char/nvram module becomes sufficiently generic to be useful
to other platforms and architectures, besides those with "CMOS" RTC. At the
end of this patch series the module is adopted by the m68k Mac port, which
already has PRAM access functions but lacks the /dev/nvram misc device.

This patch series has been compile-tested for arm, m68k, powerpc and x86.
The nvram and thinkpad_acpi modules were regression tested on a ThinkPad T43.
The /dev/nvram functionality was also regression tested on a G3 PowerMac.
The nvram module was also tested on a PowerBook 520 and Quadra 650.
Note that my testing doesn't cover PPC64 or Atari.

Changes since v1:
- Minor changes to patches 7, 15 and 20 as described in commit logs.
- Revised patches 21 and 24 to address comments from Geert.

Changes since v2:
- Dropped patch 1, "macintosh/nvram: Remove as unused", because it has
since been merged.
- Inserted a new patch, "m68k/mac: Use macros for RTC accesses not
magic numbers".
- Revised patches 21 and 23 to address comments from Geert.

---
 arch/m68k/Kconfig  |3 
 arch/m68k/atari/Makefile   |2 
 arch/m68k/atari/nvram.c|  291 +++
 arch/m68k/kernel/setup_mm.c|  107 
 arch/m68k/mac/misc.c   |  207 +---
 arch/powerpc/Kconfig   |5 
 arch/powerpc/include/asm/nvram.h   |9 
 arch/powerpc/kernel/nvram_64.c |  203 +--
 arch/powerpc/kernel/setup_32.c |   27 -
 arch/powerpc/platforms/chrp/Makefile   |2 
 arch/powerpc/platforms/chrp/nvram.c|   14 
 arch/powerpc/platforms/chrp/setup.c|2 
 arch/powerpc/platforms/powermac/Makefile   |5 
 arch/powerpc/platforms/powermac/nvram.c|9 
 arch/powerpc/platforms/powermac/setup.c|3 
 drivers/char/Kconfig   |   13 
 drivers/char/Makefile  |6 
 drivers/char/generic_nvram.c   |  174 --
 drivers/char/nvram.c   |  742 -
 drivers/platform/x86/thinkpad_acpi.c   |   20 
 drivers/scsi/Kconfig   |6 
 drivers/scsi/atari_scsi.c  |   16 
 drivers/video/fbdev/controlfb.c|4 
 drivers/video/fbdev/imsttfb.c  |7 
 drivers/video/fbdev/matrox/matroxfb_base.c |4 
 drivers/video/fbdev/platinumfb.c   |4 
 drivers/video/fbdev/valkyriefb.c   |4 
 include/linux/nvram.h  |   23 
 include/uapi/linux/pmu.h   |2 
 29 files changed, 982 insertions(+), 932 deletions(-)




___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[RFC v3 01/24] scsi/atari_scsi: Dont select CONFIG_NVRAM

2015-06-27 Thread Finn Thain
On powerpc, setting CONFIG_NVRAM=n builds a kernel with no NVRAM support.
Setting CONFIG_NVRAM=m enables the /dev/nvram misc device module without
enabling NVRAM support in drivers. Setting CONFIG_NVRAM=y enables the
misc device (built-in) and also enables NVRAM support in drivers.

m68k shares the valkyriefb driver with powerpc, and since that driver uses
NVRAM, it is affected by CONFIG_ATARI_SCSI, because of the use of
"select NVRAM".

Adopt the powerpc convention on m68k to avoid surprises.

Signed-off-by: Finn Thain 

---

This patch temporarily disables CONFIG_NVRAM on Atari, to prevent build
failures when bisecting the rest of this patch series. It gets enabled
again with the introduction of CONFIG_HAVE_ARCH_NVRAM_OPS, once the
nvram_* global functions have been moved to an ops struct.

The removal of "select NVRAM" may mean that some kernel configs (such
as Debian/m68k) may need tweaking.

---
 drivers/char/Kconfig  |5 +
 drivers/scsi/Kconfig  |6 +++---
 drivers/scsi/atari_scsi.c |8 
 3 files changed, 8 insertions(+), 11 deletions(-)

Index: linux/drivers/char/Kconfig
===
--- linux.orig/drivers/char/Kconfig 2015-06-28 11:41:28.0 +1000
+++ linux/drivers/char/Kconfig  2015-06-28 11:41:28.0 +1000
@@ -247,7 +247,7 @@ source "drivers/char/hw_random/Kconfig"
 
 config NVRAM
tristate "/dev/nvram support"
-   depends on ATARI || X86 || (ARM && RTC_DRV_CMOS) || GENERIC_NVRAM
+   depends on X86 || (ARM && RTC_DRV_CMOS) || GENERIC_NVRAM
---help---
  If you say Y here and create a character special file /dev/nvram
  with major number 10 and minor number 144 using mknod ("man mknod"),
@@ -265,9 +265,6 @@ config NVRAM
  should NEVER idly tamper with it. See Ralf Brown's interrupt list
  for a guide to the use of CMOS bytes by your BIOS.
 
- On Atari machines, /dev/nvram is always configured and does not need
- to be selected.
-
  To compile this driver as a module, choose M here: the
  module will be called nvram.
 
Index: linux/drivers/scsi/Kconfig
===
--- linux.orig/drivers/scsi/Kconfig 2015-06-28 11:41:28.0 +1000
+++ linux/drivers/scsi/Kconfig  2015-06-28 11:41:28.0 +1000
@@ -1592,14 +1592,14 @@ config ATARI_SCSI
tristate "Atari native SCSI support"
depends on ATARI && SCSI
select SCSI_SPI_ATTRS
-   select NVRAM
---help---
  If you have an Atari with built-in NCR5380 SCSI controller (TT,
  Falcon, ...) say Y to get it supported. Of course also, if you have
  a compatible SCSI controller (e.g. for Medusa).
 
- To compile this driver as a module, choose M here: the
- module will be called atari_scsi.
+ To compile this driver as a module, choose M here: the module will
+ be called atari_scsi. If you also enable NVRAM support, the SCSI
+ host's ID is taken from the setting in TT RTC NVRAM.
 
  This driver supports both styles of NCR integration into the
  system: the TT style (separate DMA), and the Falcon style (via
Index: linux/drivers/scsi/atari_scsi.c
===
--- linux.orig/drivers/scsi/atari_scsi.c2015-06-28 11:41:28.0 
+1000
+++ linux/drivers/scsi/atari_scsi.c 2015-06-28 11:41:28.0 +1000
@@ -875,9 +875,10 @@ static int __init atari_scsi_probe(struc
if (ATARIHW_PRESENT(TT_SCSI) && setup_sg_tablesize >= 0)
atari_scsi_template.sg_tablesize = setup_sg_tablesize;
 
-   if (setup_hostid >= 0) {
+   if (setup_hostid >= 0)
atari_scsi_template.this_id = setup_hostid & 7;
-   } else {
+#ifdef CONFIG_NVRAM
+   else
/* Test if a host id is set in the NVRam */
if (ATARIHW_PRESENT(TT_CLK) && nvram_check_checksum()) {
unsigned char b = nvram_read_byte(14);
@@ -888,8 +889,7 @@ static int __init atari_scsi_probe(struc
if (b & 0x80)
atari_scsi_template.this_id = b & 7;
}
-   }
-
+#endif
 
 #ifdef REAL_DMA
/* If running on a Falcon and if there's TT-Ram (i.e., more than one


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[RFC v3 02/24] m68k/atari: Move Atari-specific code out of drivers/char/nvram.c

2015-06-27 Thread Finn Thain
Move the m68k-specific code elsewhere to make the driver generic.

Change the vmode calculation from logical OR to bitwise OR, since it is
obviously wrong.

Signed-off-by: Finn Thain 

---

BTW, I didn't change the SCSI ID location in NVRAM. This code says 16
whereas atari_scsi says 14. Which one is correct?

---
 arch/m68k/atari/Makefile |2 
 arch/m68k/atari/nvram.c  |  255 ++
 drivers/char/nvram.c |  280 +--
 3 files changed, 292 insertions(+), 245 deletions(-)

Index: linux/arch/m68k/atari/nvram.c
===
--- /dev/null   1970-01-01 00:00:00.0 +
+++ linux/arch/m68k/atari/nvram.c   2015-06-28 11:41:29.0 +1000
@@ -0,0 +1,255 @@
+/*
+ * CMOS/NV-RAM driver for Atari. Adapted from drivers/char/nvram.c.
+ * Copyright (C) 1997 Roman Hodek 
+ * idea by and with help from Richard Jelinek 
+ * Portions copyright (c) 2001,2002 Sun Microsystems (thoc...@sun.com)
+ * Further contributions from Cesar Barros, Erik Gilling, Tim Hockin and
+ * Wim Van Sebroeck.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define NVRAM_BYTES50
+
+/* It is worth noting that these functions all access bytes of general
+ * purpose memory in the NVRAM - that is to say, they all add the
+ * NVRAM_FIRST_BYTE offset. Pass them offsets into NVRAM as if you did not
+ * know about the RTC cruft.
+ */
+
+/* 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
+ * don't want two different things trying to get to it at once. (e.g. the
+ * periodic 11 min sync from kernel/time/ntp.c vs. this driver.)
+ */
+
+unsigned char __nvram_read_byte(int i)
+{
+   return CMOS_READ(NVRAM_FIRST_BYTE + i);
+}
+
+unsigned char nvram_read_byte(int i)
+{
+   unsigned long flags;
+   unsigned char c;
+
+   spin_lock_irqsave(&rtc_lock, flags);
+   c = __nvram_read_byte(i);
+   spin_unlock_irqrestore(&rtc_lock, flags);
+   return c;
+}
+EXPORT_SYMBOL(nvram_read_byte);
+
+/* This races nicely with trying to read with checksum checking */
+void __nvram_write_byte(unsigned char c, int i)
+{
+   CMOS_WRITE(c, NVRAM_FIRST_BYTE + i);
+}
+
+void nvram_write_byte(unsigned char c, int i)
+{
+   unsigned long flags;
+
+   spin_lock_irqsave(&rtc_lock, flags);
+   __nvram_write_byte(c, i);
+   spin_unlock_irqrestore(&rtc_lock, flags);
+}
+
+/* On Ataris, the checksum is over all bytes except the checksum bytes
+ * themselves; these are at the very end.
+ */
+#define ATARI_CKS_RANGE_START  0
+#define ATARI_CKS_RANGE_END47
+#define ATARI_CKS_LOC  48
+
+int __nvram_check_checksum(void)
+{
+   int i;
+   unsigned char sum = 0;
+
+   for (i = ATARI_CKS_RANGE_START; i <= ATARI_CKS_RANGE_END; ++i)
+   sum += __nvram_read_byte(i);
+   return (__nvram_read_byte(ATARI_CKS_LOC) == (~sum & 0xff)) &&
+  (__nvram_read_byte(ATARI_CKS_LOC + 1) == (sum & 0xff));
+}
+
+int nvram_check_checksum(void)
+{
+   unsigned long flags;
+   int rv;
+
+   spin_lock_irqsave(&rtc_lock, flags);
+   rv = __nvram_check_checksum();
+   spin_unlock_irqrestore(&rtc_lock, flags);
+   return rv;
+}
+EXPORT_SYMBOL(nvram_check_checksum);
+
+static void __nvram_set_checksum(void)
+{
+   int i;
+   unsigned char sum = 0;
+
+   for (i = ATARI_CKS_RANGE_START; i <= ATARI_CKS_RANGE_END; ++i)
+   sum += __nvram_read_byte(i);
+   __nvram_write_byte(~sum, ATARI_CKS_LOC);
+   __nvram_write_byte(sum, ATARI_CKS_LOC + 1);
+}
+
+#ifdef CONFIG_PROC_FS
+static struct {
+   unsigned char val;
+   char *name;
+} boot_prefs[] = {
+   { 0x80, "TOS" },
+   { 0x40, "ASV" },
+   { 0x20, "NetBSD (?)" },
+   { 0x10, "Linux" },
+   { 0x00, "unspecified" },
+};
+
+static char *languages[] = {
+   "English (US)",
+   "German",
+   "French",
+   "English (UK)",
+   "Spanish",
+   "Italian",
+   "6 (undefined)",
+   "Swiss (French)",
+   "Swiss (German)",
+};
+
+static char *dateformat[] = {
+   "MM%cDD%cYY",
+   "DD%cMM%cYY",
+   "YY%cMM%cDD",
+   "YY%cDD%cMM",
+   "4 (undefined)",
+   "5 (undefined)",
+   "6 (undefined)",
+   "7 (undefined)",
+};
+
+static char *colors[] = {
+   "2", "4", "16", "256", "65536", "??", "??", "??"
+};
+
+static void atari_nvram_proc_read(unsigned char *nvram, s

[RFC v3 12/24] powerpc: Cleanup nvram includes

2015-06-27 Thread Finn Thain
The nvram_read_byte() and nvram_write_byte() definitions in asm/nvram.h
duplicate those in linux/nvram.h. Get rid of the former to prepare for
adoption of struct arch_nvram_ops (which is defined in linux/nvram.h for
general use).

Signed-off-by: Finn Thain 

---
 arch/powerpc/include/asm/nvram.h   |3 ---
 arch/powerpc/kernel/setup_32.c |1 +
 drivers/char/generic_nvram.c   |4 +++-
 drivers/video/fbdev/matrox/matroxfb_base.c |2 +-
 4 files changed, 5 insertions(+), 5 deletions(-)

Index: linux/arch/powerpc/include/asm/nvram.h
===
--- linux.orig/arch/powerpc/include/asm/nvram.h 2015-06-28 11:41:27.0 
+1000
+++ linux/arch/powerpc/include/asm/nvram.h  2015-06-28 11:41:41.0 
+1000
@@ -101,7 +101,4 @@ extern int nvram_write_os_partition(stru
 /* Determine NVRAM size */
 extern ssize_t nvram_get_size(void);
 
-/* Normal access to NVRAM */
-extern unsigned char nvram_read_byte(int i);
-extern void nvram_write_byte(unsigned char c, int i);
 #endif /* _ASM_POWERPC_NVRAM_H */
Index: linux/arch/powerpc/kernel/setup_32.c
===
--- linux.orig/arch/powerpc/kernel/setup_32.c   2015-06-28 11:41:27.0 
+1000
+++ linux/arch/powerpc/kernel/setup_32.c2015-06-28 11:41:41.0 
+1000
@@ -16,6 +16,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
Index: linux/drivers/char/generic_nvram.c
===
--- linux.orig/drivers/char/generic_nvram.c 2015-06-28 11:41:27.0 
+1000
+++ linux/drivers/char/generic_nvram.c  2015-06-28 11:41:41.0 +1000
@@ -20,9 +20,11 @@
 #include 
 #include 
 #include 
+#include 
 #include 
-#include 
+
 #ifdef CONFIG_PPC_PMAC
+#include 
 #include 
 #endif
 
Index: linux/drivers/video/fbdev/matrox/matroxfb_base.c
===
--- linux.orig/drivers/video/fbdev/matrox/matroxfb_base.c   2015-06-28 
11:41:27.0 +1000
+++ linux/drivers/video/fbdev/matrox/matroxfb_base.c2015-06-28 
11:41:41.0 +1000
@@ -111,12 +111,12 @@
 #include "matroxfb_g450.h"
 #include 
 #include 
+#include 
 #include 
 #include 
 
 #ifdef CONFIG_PPC_PMAC
 #include 
-unsigned char nvram_read_byte(int);
 static int default_vmode = VMODE_NVRAM;
 static int default_cmode = CMODE_NVRAM;
 #endif


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[RFC v3 07/24] char/nvram: Allow the set_checksum and initialize ioctls to be omitted

2015-06-27 Thread Finn Thain
The drivers/char/nvram module has previously only supported RTC "CMOS"
NVRAM, for which it provides appropriate checksum ioctls. Make these
ioctls optional so the module can be re-used with other kinds of NVRAM.

The ops struct methods that implement the ioctls now return error
codes so that a multi-platform kernel binary can do the right thing when
running on hardware without suitable NVRAM.

Signed-off-by: Finn Thain 

---

Changed since v1:
- Don't bother acquiring the mutex for unimplemented ioctls.

---
 drivers/char/nvram.c  |   71 --
 include/linux/nvram.h |2 +
 2 files changed, 43 insertions(+), 30 deletions(-)

Index: linux/drivers/char/nvram.c
===
--- linux.orig/drivers/char/nvram.c 2015-06-28 11:41:34.0 +1000
+++ linux/drivers/char/nvram.c  2015-06-28 11:41:36.0 +1000
@@ -153,16 +153,25 @@ static void __nvram_set_checksum(void)
__nvram_write_byte(sum & 0xff, PC_CKS_LOC + 1);
 }
 
-#if 0
-void nvram_set_checksum(void)
+static long nvram_set_checksum(void)
 {
-   unsigned long flags;
+   spin_lock_irq(&rtc_lock);
+   __nvram_set_checksum();
+   spin_unlock_irq(&rtc_lock);
+   return 0;
+}
+
+static long nvram_initialize(void)
+{
+   ssize_t i;
 
-   spin_lock_irqsave(&rtc_lock, flags);
+   spin_lock_irq(&rtc_lock);
+   for (i = 0; i < NVRAM_BYTES; ++i)
+   __nvram_write_byte(0, i);
__nvram_set_checksum();
-   spin_unlock_irqrestore(&rtc_lock, flags);
+   spin_unlock_irq(&rtc_lock);
+   return 0;
 }
-#endif  /*  0  */
 
 static ssize_t nvram_get_size(void)
 {
@@ -173,6 +182,8 @@ const struct nvram_ops arch_nvram_ops =
.read_byte  = nvram_read_byte,
.write_byte = nvram_write_byte,
.get_size   = nvram_get_size,
+   .set_checksum   = nvram_set_checksum,
+   .initialize = nvram_initialize,
 };
 EXPORT_SYMBOL(arch_nvram_ops);
 
@@ -272,51 +283,51 @@ checksum_err:
 static long nvram_misc_ioctl(struct file *file, unsigned int cmd,
  unsigned long arg)
 {
-   int i;
+   long ret = -ENOTTY;
 
switch (cmd) {
-
case NVRAM_INIT:
/* initialize NVRAM contents and checksum */
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
 
-   mutex_lock(&nvram_mutex);
-   spin_lock_irq(&rtc_lock);
-
-   for (i = 0; i < NVRAM_BYTES; ++i)
-   __nvram_write_byte(0, i);
-   __nvram_set_checksum();
-
-   spin_unlock_irq(&rtc_lock);
-   mutex_unlock(&nvram_mutex);
-   return 0;
-
+   if (arch_nvram_ops.initialize != NULL) {
+   mutex_lock(&nvram_mutex);
+   ret = arch_nvram_ops.initialize();
+   mutex_unlock(&nvram_mutex);
+   }
+   break;
case NVRAM_SETCKS:
/* just set checksum, contents unchanged (maybe useful after
 * checksum garbaged somehow...) */
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
 
-   mutex_lock(&nvram_mutex);
-   spin_lock_irq(&rtc_lock);
-   __nvram_set_checksum();
-   spin_unlock_irq(&rtc_lock);
-   mutex_unlock(&nvram_mutex);
-   return 0;
-
-   default:
-   return -ENOTTY;
+   if (arch_nvram_ops.set_checksum != NULL) {
+   mutex_lock(&nvram_mutex);
+   ret = arch_nvram_ops.set_checksum();
+   mutex_unlock(&nvram_mutex);
+   }
+   break;
}
+   return ret;
 }
 
 static int nvram_misc_open(struct inode *inode, struct file *file)
 {
spin_lock(&nvram_state_lock);
 
+   /* Prevent multiple readers/writers if desired. */
if ((nvram_open_cnt && (file->f_flags & O_EXCL)) ||
-   (nvram_open_mode & NVRAM_EXCL) ||
-   ((file->f_mode & FMODE_WRITE) && (nvram_open_mode & NVRAM_WRITE))) {
+   (nvram_open_mode & NVRAM_EXCL)) {
+   spin_unlock(&nvram_state_lock);
+   return -EBUSY;
+   }
+
+   /* Prevent multiple writers if the set_checksum ioctl is implemented. */
+   if ((arch_nvram_ops.set_checksum != NULL) &&
+   (file->f_mode & FMODE_WRITE) &&
+   (nvram_open_mode & NVRAM_WRITE)) {
spin_unlock(&nvram_state_lock);
return -EBUSY;
}
Index: linux/include/linux/nvram.h
===
--- linux.orig/include/linux/nvram.h201

[RFC v3 10/24] m68k/atari: Implement arch_nvram_ops methods and enable CONFIG_HAVE_ARCH_NVRAM_OPS

2015-06-27 Thread Finn Thain
Atari RTC NVRAM has a checksum so implement the remaining arch_nvram_ops
methods for the set_checksum and initialize ioctls. Enable
CONFIG_HAVE_ARCH_NVRAM_OPS.

Signed-off-by: Finn Thain 

---

This re-enables the nvram module for Atari.

---
 arch/m68k/Kconfig   |3 +++
 arch/m68k/atari/nvram.c |   24 
 drivers/char/Kconfig|2 +-
 3 files changed, 28 insertions(+), 1 deletion(-)

Index: linux/arch/m68k/atari/nvram.c
===
--- linux.orig/arch/m68k/atari/nvram.c  2015-06-28 11:41:31.0 +1000
+++ linux/arch/m68k/atari/nvram.c   2015-06-28 11:41:39.0 +1000
@@ -73,6 +73,26 @@ static void __nvram_set_checksum(void)
__nvram_write_byte(sum, ATARI_CKS_LOC + 1);
 }
 
+static long nvram_set_checksum(void)
+{
+   spin_lock_irq(&rtc_lock);
+   __nvram_set_checksum();
+   spin_unlock_irq(&rtc_lock);
+   return 0;
+}
+
+static long nvram_initialize(void)
+{
+   loff_t i;
+
+   spin_lock_irq(&rtc_lock);
+   for (i = 0; i < NVRAM_BYTES; ++i)
+   __nvram_write_byte(0, i);
+   __nvram_set_checksum();
+   spin_unlock_irq(&rtc_lock);
+   return 0;
+}
+
 static ssize_t nvram_read(char *buf, size_t count, loff_t *ppos)
 {
char *p = buf;
@@ -119,6 +139,8 @@ static ssize_t nvram_write(char *buf, si
 
 static ssize_t nvram_get_size(void)
 {
+   if (!MACH_IS_ATARI)
+   return -ENODEV;
return NVRAM_BYTES;
 }
 
@@ -126,6 +148,8 @@ const struct nvram_ops arch_nvram_ops =
.read   = nvram_read,
.write  = nvram_write,
.get_size   = nvram_get_size,
+   .set_checksum   = nvram_set_checksum,
+   .initialize = nvram_initialize,
 };
 EXPORT_SYMBOL(arch_nvram_ops);
 
Index: linux/drivers/char/Kconfig
===
--- linux.orig/drivers/char/Kconfig 2015-06-28 11:41:28.0 +1000
+++ linux/drivers/char/Kconfig  2015-06-28 11:41:39.0 +1000
@@ -247,7 +247,7 @@ source "drivers/char/hw_random/Kconfig"
 
 config NVRAM
tristate "/dev/nvram support"
-   depends on X86 || (ARM && RTC_DRV_CMOS) || GENERIC_NVRAM
+   depends on X86 || (ARM && RTC_DRV_CMOS) || GENERIC_NVRAM || 
HAVE_ARCH_NVRAM_OPS
---help---
  If you say Y here and create a character special file /dev/nvram
  with major number 10 and minor number 144 using mknod ("man mknod"),
Index: linux/arch/m68k/Kconfig
===
--- linux.orig/arch/m68k/Kconfig2015-06-28 11:41:27.0 +1000
+++ linux/arch/m68k/Kconfig 2015-06-28 11:41:39.0 +1000
@@ -71,6 +71,9 @@ config PGTABLE_LEVELS
default 2 if SUN3 || COLDFIRE
default 3
 
+config HAVE_ARCH_NVRAM_OPS
+   def_bool ATARI
+
 source "init/Kconfig"
 
 source "kernel/Kconfig.freezer"


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[RFC v3 11/24] char/nvram: Add "devname:nvram" module alias

2015-06-27 Thread Finn Thain
Signed-off-by: Finn Thain 

---
 drivers/char/nvram.c |1 +
 1 file changed, 1 insertion(+)

Index: linux/drivers/char/nvram.c
===
--- linux.orig/drivers/char/nvram.c 2015-06-28 11:41:38.0 +1000
+++ linux/drivers/char/nvram.c  2015-06-28 11:41:40.0 +1000
@@ -577,3 +577,4 @@ module_exit(nvram_module_exit);
 
 MODULE_LICENSE("GPL");
 MODULE_ALIAS_MISCDEV(NVRAM_MINOR);
+MODULE_ALIAS("devname:nvram");


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[RFC v3 14/24] powerpc: Implement arch_nvram_ops.get_size() and remove old nvram_* exports

2015-06-27 Thread Finn Thain
Implement arch_nvram_ops for PPC32 and make use of it in the generic_nvram
misc device module so that the nvram_* function exports can be removed.

Signed-off-by: Finn Thain 

---
 arch/powerpc/include/asm/nvram.h |3 ---
 arch/powerpc/kernel/setup_32.c   |   10 +++---
 drivers/char/generic_nvram.c |   24 
 3 files changed, 19 insertions(+), 18 deletions(-)

Index: linux/arch/powerpc/include/asm/nvram.h
===
--- linux.orig/arch/powerpc/include/asm/nvram.h 2015-06-28 11:41:41.0 
+1000
+++ linux/arch/powerpc/include/asm/nvram.h  2015-06-28 11:41:43.0 
+1000
@@ -98,7 +98,4 @@ extern int nvram_write_os_partition(stru
unsigned int err_type,
unsigned int error_log_cnt);
 
-/* Determine NVRAM size */
-extern ssize_t nvram_get_size(void);
-
 #endif /* _ASM_POWERPC_NVRAM_H */
Index: linux/arch/powerpc/kernel/setup_32.c
===
--- linux.orig/arch/powerpc/kernel/setup_32.c   2015-06-28 11:41:41.0 
+1000
+++ linux/arch/powerpc/kernel/setup_32.c2015-06-28 11:41:43.0 
+1000
@@ -186,13 +186,12 @@ void nvram_write_byte(unsigned char val,
 }
 EXPORT_SYMBOL(nvram_write_byte);
 
-ssize_t nvram_get_size(void)
+static ssize_t ppc_nvram_get_size(void)
 {
if (ppc_md.nvram_size)
return ppc_md.nvram_size();
-   return -1;
+   return -ENODEV;
 }
-EXPORT_SYMBOL(nvram_get_size);
 
 void nvram_sync(void)
 {
@@ -201,6 +200,11 @@ void nvram_sync(void)
 }
 EXPORT_SYMBOL(nvram_sync);
 
+const struct nvram_ops arch_nvram_ops = {
+   .get_size   = ppc_nvram_get_size,
+};
+EXPORT_SYMBOL(arch_nvram_ops);
+
 #endif /* CONFIG_NVRAM */
 
 int __init ppc_init(void)
Index: linux/drivers/char/generic_nvram.c
===
--- linux.orig/drivers/char/generic_nvram.c 2015-06-28 11:41:41.0 
+1000
+++ linux/drivers/char/generic_nvram.c  2015-06-28 11:41:43.0 +1000
@@ -28,8 +28,6 @@
 #include 
 #endif
 
-#define NVRAM_SIZE 8192
-
 static DEFINE_MUTEX(nvram_mutex);
 static ssize_t nvram_len;
 
@@ -150,20 +148,22 @@ static struct miscdevice nvram_dev = {
 
 int __init nvram_init(void)
 {
-   int ret = 0;
+   int ret;
 
-   printk(KERN_INFO "Generic non-volatile memory driver v%s\n",
-   NVRAM_VERSION);
-   ret = misc_register(&nvram_dev);
-   if (ret != 0)
-   goto out;
+   if (arch_nvram_ops.get_size == NULL)
+   return -ENODEV;
 
-   nvram_len = nvram_get_size();
+   nvram_len = arch_nvram_ops.get_size();
if (nvram_len < 0)
-   nvram_len = NVRAM_SIZE;
+   return nvram_len;
 
-out:
-   return ret;
+   ret = misc_register(&nvram_dev);
+   if (ret)
+   return ret;
+
+   pr_info("Generic non-volatile memory driver v%s\n", NVRAM_VERSION);
+
+   return 0;
 }
 
 void __exit nvram_cleanup(void)


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[RFC v3 06/24] x86/thinkpad_acpi: Use arch_nvram_ops methods instead of nvram_read_byte() and nvram_write_byte()

2015-06-27 Thread Finn Thain
Make use of arch_nvram_ops in the thinkpad_acpi driver so that the
nvram_* function exports can be removed.

This patch series was tested on a ThinkPad T43.

Signed-off-by: Finn Thain 
Acked-by: Henrique de Moraes Holschuh 
Reviewed-by: Darren Hart 

---
 drivers/platform/x86/thinkpad_acpi.c |   20 ++--
 1 file changed, 10 insertions(+), 10 deletions(-)

Index: linux/drivers/platform/x86/thinkpad_acpi.c
===
--- linux.orig/drivers/platform/x86/thinkpad_acpi.c 2015-06-28 
11:41:28.0 +1000
+++ linux/drivers/platform/x86/thinkpad_acpi.c  2015-06-28 11:41:35.0 
+1000
@@ -2311,30 +2311,30 @@ static void hotkey_read_nvram(struct tp_
u8 d;
 
if (m & TP_NVRAM_HKEY_GROUP_HK2) {
-   d = nvram_read_byte(TP_NVRAM_ADDR_HK2);
+   d = arch_nvram_ops.read_byte(TP_NVRAM_ADDR_HK2);
n->thinkpad_toggle = !!(d & TP_NVRAM_MASK_HKT_THINKPAD);
n->zoom_toggle = !!(d & TP_NVRAM_MASK_HKT_ZOOM);
n->display_toggle = !!(d & TP_NVRAM_MASK_HKT_DISPLAY);
n->hibernate_toggle = !!(d & TP_NVRAM_MASK_HKT_HIBERNATE);
}
if (m & TP_ACPI_HKEY_THNKLGHT_MASK) {
-   d = nvram_read_byte(TP_NVRAM_ADDR_THINKLIGHT);
+   d = arch_nvram_ops.read_byte(TP_NVRAM_ADDR_THINKLIGHT);
n->thinklight_toggle = !!(d & TP_NVRAM_MASK_THINKLIGHT);
}
if (m & TP_ACPI_HKEY_DISPXPAND_MASK) {
-   d = nvram_read_byte(TP_NVRAM_ADDR_VIDEO);
+   d = arch_nvram_ops.read_byte(TP_NVRAM_ADDR_VIDEO);
n->displayexp_toggle =
!!(d & TP_NVRAM_MASK_HKT_DISPEXPND);
}
if (m & TP_NVRAM_HKEY_GROUP_BRIGHTNESS) {
-   d = nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS);
+   d = arch_nvram_ops.read_byte(TP_NVRAM_ADDR_BRIGHTNESS);
n->brightness_level = (d & TP_NVRAM_MASK_LEVEL_BRIGHTNESS)
>> TP_NVRAM_POS_LEVEL_BRIGHTNESS;
n->brightness_toggle =
!!(d & TP_NVRAM_MASK_HKT_BRIGHTNESS);
}
if (m & TP_NVRAM_HKEY_GROUP_VOLUME) {
-   d = nvram_read_byte(TP_NVRAM_ADDR_MIXER);
+   d = arch_nvram_ops.read_byte(TP_NVRAM_ADDR_MIXER);
n->volume_level = (d & TP_NVRAM_MASK_LEVEL_VOLUME)
>> TP_NVRAM_POS_LEVEL_VOLUME;
n->mute = !!(d & TP_NVRAM_MASK_MUTE);
@@ -6155,7 +6155,7 @@ static unsigned int tpacpi_brightness_nv
 {
u8 lnvram;
 
-   lnvram = (nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS)
+   lnvram = (arch_nvram_ops.read_byte(TP_NVRAM_ADDR_BRIGHTNESS)
  & TP_NVRAM_MASK_LEVEL_BRIGHTNESS)
  >> TP_NVRAM_POS_LEVEL_BRIGHTNESS;
lnvram &= bright_maxlvl;
@@ -6180,7 +6180,7 @@ static void tpacpi_brightness_checkpoint
if (unlikely(!acpi_ec_read(TP_EC_BACKLIGHT, &lec)))
goto unlock;
lec &= TP_EC_BACKLIGHT_LVLMSK;
-   b_nvram = nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS);
+   b_nvram = arch_nvram_ops.read_byte(TP_NVRAM_ADDR_BRIGHTNESS);
 
if (lec != ((b_nvram & TP_NVRAM_MASK_LEVEL_BRIGHTNESS)
 >> TP_NVRAM_POS_LEVEL_BRIGHTNESS)) {
@@ -6188,7 +6188,7 @@ static void tpacpi_brightness_checkpoint
b_nvram &= ~(TP_NVRAM_MASK_LEVEL_BRIGHTNESS <<
TP_NVRAM_POS_LEVEL_BRIGHTNESS);
b_nvram |= lec;
-   nvram_write_byte(b_nvram, TP_NVRAM_ADDR_BRIGHTNESS);
+   arch_nvram_ops.write_byte(b_nvram, TP_NVRAM_ADDR_BRIGHTNESS);
dbg_printk(TPACPI_DBG_BRGHT,
   "updated NVRAM backlight level to %u (0x%02x)\n",
   (unsigned int) lec, (unsigned int) b_nvram);
@@ -6796,13 +6796,13 @@ static void tpacpi_volume_checkpoint_nvr
if (unlikely(!acpi_ec_read(TP_EC_AUDIO, &lec)))
goto unlock;
lec &= ec_mask;
-   b_nvram = nvram_read_byte(TP_NVRAM_ADDR_MIXER);
+   b_nvram = arch_nvram_ops.read_byte(TP_NVRAM_ADDR_MIXER);
 
if (lec != (b_nvram & ec_mask)) {
/* NVRAM needs update */
b_nvram &= ~ec_mask;
b_nvram |= lec;
-   nvram_write_byte(b_nvram, TP_NVRAM_ADDR_MIXER);
+   arch_nvram_ops.write_byte(b_nvram, TP_NVRAM_ADDR_MIXER);
dbg_printk(TPACPI_DBG_MIXER,
   "updated NVRAM mixer status to 0x%02x (0x%02x)\n",
   (unsigned int) lec, (unsigned int) b_nvram);


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[RFC v3 08/24] char/nvram: Implement NVRAM read/write methods

2015-06-27 Thread Finn Thain
Refactor the RTC "CMOS" NVRAM functions so that they can be used as
arch_nvram_ops methods. Checksumming logic is moved from the misc device
operations to the nvram read/write operations.

This makes the misc device implementation more generic. This also
preserves the locking semantics such that "read if checksum valid" and
"write and update checksum" remain atomic operations.

PPC64 implements byte-range read/write methods which are similar to
file_operations struct methods. Other platforms provide only
byte-at-a-time functions. So the misc device prefers the former but
will fall back on the latter.

Signed-off-by: Finn Thain 

---
 drivers/char/nvram.c |  162 +++
 1 file changed, 114 insertions(+), 48 deletions(-)

Index: linux/drivers/char/nvram.c
===
--- linux.orig/drivers/char/nvram.c 2015-06-28 11:41:36.0 +1000
+++ linux/drivers/char/nvram.c  2015-06-28 11:41:37.0 +1000
@@ -41,6 +41,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -178,9 +179,48 @@ static ssize_t nvram_get_size(void)
return NVRAM_BYTES;
 }
 
+static ssize_t nvram_read(char *buf, size_t count, loff_t *ppos)
+{
+   char *p = buf;
+   loff_t i;
+
+   spin_lock_irq(&rtc_lock);
+   if (!__nvram_check_checksum()) {
+   spin_unlock_irq(&rtc_lock);
+   return -EIO;
+   }
+   for (i = *ppos; count > 0 && i < NVRAM_BYTES; --count, ++i, ++p)
+   *p = __nvram_read_byte(i);
+   spin_unlock_irq(&rtc_lock);
+
+   *ppos = i;
+   return p - buf;
+}
+
+static ssize_t nvram_write(char *buf, size_t count, loff_t *ppos)
+{
+   char *p = buf;
+   loff_t i;
+
+   spin_lock_irq(&rtc_lock);
+   if (!__nvram_check_checksum()) {
+   spin_unlock_irq(&rtc_lock);
+   return -EIO;
+   }
+   for (i = *ppos; count > 0 && i < NVRAM_BYTES; --count, ++i, ++p)
+   __nvram_write_byte(*p, i);
+   __nvram_set_checksum();
+   spin_unlock_irq(&rtc_lock);
+
+   *ppos = i;
+   return p - buf;
+}
+
 const struct nvram_ops arch_nvram_ops = {
.read_byte  = nvram_read_byte,
.write_byte = nvram_write_byte,
+   .read   = nvram_read,
+   .write  = nvram_write,
.get_size   = nvram_get_size,
.set_checksum   = nvram_set_checksum,
.initialize = nvram_initialize,
@@ -215,69 +255,95 @@ static loff_t nvram_misc_llseek(struct f
 static ssize_t nvram_misc_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
 {
-   unsigned char contents[NVRAM_BYTES];
-   unsigned i = *ppos;
-   unsigned char *tmp;
-
-   spin_lock_irq(&rtc_lock);
+   loff_t i;
+   char __user *p = buf;
 
-   if (!__nvram_check_checksum())
-   goto checksum_err;
-
-   for (tmp = contents; count-- > 0 && i < NVRAM_BYTES; ++i, ++tmp)
-   *tmp = __nvram_read_byte(i);
-
-   spin_unlock_irq(&rtc_lock);
-
-   if (copy_to_user(buf, contents, tmp - contents))
+   if (!access_ok(VERIFY_WRITE, buf, count))
return -EFAULT;
+   if (*ppos >= nvram_size)
+   return 0;
 
-   *ppos = i;
-
-   return tmp - contents;
+   /* If the arch provided a byte range read op, use it. Otherwise
+* fall back on the byte-at-a-time accessor.
+*/
+   if (arch_nvram_ops.read != NULL) {
+   char *tmp;
+   ssize_t ret;
+
+   count = min_t(size_t, count, nvram_size - *ppos);
+   count = min_t(size_t, count, PAGE_SIZE);
+
+   tmp = kmalloc(count, GFP_KERNEL);
+   if (!tmp)
+   return -ENOMEM;
+
+   ret = arch_nvram_ops.read(tmp, count, ppos);
+   if (ret <= 0)
+   goto out;
+
+   if (copy_to_user(buf, tmp, ret)) {
+   *ppos -= ret;
+   ret = -EFAULT;
+   }
+
+out:
+   kfree(tmp);
+   return ret;
+   }
 
-checksum_err:
-   spin_unlock_irq(&rtc_lock);
-   return -EIO;
+   for (i = *ppos; count > 0 && i < nvram_size; ++i, ++p, --count)
+   if (__put_user(arch_nvram_ops.read_byte(i), p))
+   return -EFAULT;
+   *ppos = i;
+   return p - buf;
 }
 
 static ssize_t nvram_misc_write(struct file *file, const char __user *buf,
 size_t count, loff_t *ppos)
 {
-   unsigned char contents[NVRAM_BYTES];
-   unsigned i = *ppos;
-   unsigned char *tmp;
-
-   if (i >= NVRAM_BYTES)
-   return 0;   /* Past EOF */
-
-   if (count > NVRA

[RFC v3 09/24] char/nvram: Use generic fixed_size_llseek()

2015-06-27 Thread Finn Thain
Signed-off-by: Finn Thain 

---
 drivers/char/nvram.c |   16 +---
 1 file changed, 1 insertion(+), 15 deletions(-)

Index: linux/drivers/char/nvram.c
===
--- linux.orig/drivers/char/nvram.c 2015-06-28 11:41:37.0 +1000
+++ linux/drivers/char/nvram.c  2015-06-28 11:41:38.0 +1000
@@ -235,21 +235,7 @@ EXPORT_SYMBOL(arch_nvram_ops);
 
 static loff_t nvram_misc_llseek(struct file *file, loff_t offset, int origin)
 {
-   switch (origin) {
-   case 0:
-   /* nothing to do */
-   break;
-   case 1:
-   offset += file->f_pos;
-   break;
-   case 2:
-   offset += NVRAM_BYTES;
-   break;
-   default:
-   return -EINVAL;
-   }
-
-   return (offset >= 0) ? (file->f_pos = offset) : -EINVAL;
+   return fixed_size_llseek(file, offset, origin, nvram_size);
 }
 
 static ssize_t nvram_misc_read(struct file *file, char __user *buf,


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[RFC v3 13/24] powerpc: Add missing ppc_md.nvram_size for CHRP and PowerMac

2015-06-27 Thread Finn Thain
Add the nvram_size() function to those PowerPC platforms that don't already
have one: CHRP and PowerMac. This means that the ppc_md.nvram_size()
function can be used to implement arch_nvram_ops.get_size()

Since we are addressing inconsistencies here, also rename chrp_nvram_read
and chrp_nvram_write, which break the naming convention used across
PowerPC platforms for NVRAM accessor functions.

Signed-off-by: Finn Thain 

---
 arch/powerpc/platforms/chrp/nvram.c |   14 ++
 arch/powerpc/platforms/powermac/nvram.c |9 +
 2 files changed, 19 insertions(+), 4 deletions(-)

Index: linux/arch/powerpc/platforms/chrp/nvram.c
===
--- linux.orig/arch/powerpc/platforms/chrp/nvram.c  2015-06-28 
11:41:27.0 +1000
+++ linux/arch/powerpc/platforms/chrp/nvram.c   2015-06-28 11:41:42.0 
+1000
@@ -23,7 +23,7 @@ static unsigned int nvram_size;
 static unsigned char nvram_buf[4];
 static DEFINE_SPINLOCK(nvram_lock);
 
-static unsigned char chrp_nvram_read(int addr)
+static unsigned char chrp_nvram_read_byte(int addr)
 {
unsigned int done;
unsigned long flags;
@@ -45,7 +45,7 @@ static unsigned char chrp_nvram_read(int
return ret;
 }
 
-static void chrp_nvram_write(int addr, unsigned char val)
+static void chrp_nvram_write_byte(int addr, unsigned char val)
 {
unsigned int done;
unsigned long flags;
@@ -63,6 +63,11 @@ static void chrp_nvram_write(int addr, u
spin_unlock_irqrestore(&nvram_lock, flags);
 }
 
+static ssize_t chrp_nvram_size(void)
+{
+   return nvram_size;
+}
+
 void __init chrp_nvram_init(void)
 {
struct device_node *nvram;
@@ -84,8 +89,9 @@ void __init chrp_nvram_init(void)
printk(KERN_INFO "CHRP nvram contains %u bytes\n", nvram_size);
of_node_put(nvram);
 
-   ppc_md.nvram_read_val = chrp_nvram_read;
-   ppc_md.nvram_write_val = chrp_nvram_write;
+   ppc_md.nvram_read_val  = chrp_nvram_read_byte;
+   ppc_md.nvram_write_val = chrp_nvram_write_byte;
+   ppc_md.nvram_size  = chrp_nvram_size;
 
return;
 }
Index: linux/arch/powerpc/platforms/powermac/nvram.c
===
--- linux.orig/arch/powerpc/platforms/powermac/nvram.c  2015-06-28 
11:41:27.0 +1000
+++ linux/arch/powerpc/platforms/powermac/nvram.c   2015-06-28 
11:41:42.0 +1000
@@ -147,6 +147,11 @@ static ssize_t core99_nvram_size(void)
 static volatile unsigned char __iomem *nvram_addr;
 static int nvram_mult;
 
+static ssize_t ppc32_nvram_size(void)
+{
+   return NVRAM_SIZE;
+}
+
 static unsigned char direct_nvram_read_byte(int addr)
 {
return in_8(&nvram_data[(addr & (NVRAM_SIZE - 1)) * nvram_mult]);
@@ -590,21 +595,25 @@ int __init pmac_nvram_init(void)
nvram_mult = 1;
ppc_md.nvram_read_val   = direct_nvram_read_byte;
ppc_md.nvram_write_val  = direct_nvram_write_byte;
+   ppc_md.nvram_size   = ppc32_nvram_size;
} else if (nvram_naddrs == 1) {
nvram_data = ioremap(r1.start, s1);
nvram_mult = (s1 + NVRAM_SIZE - 1) / NVRAM_SIZE;
ppc_md.nvram_read_val   = direct_nvram_read_byte;
ppc_md.nvram_write_val  = direct_nvram_write_byte;
+   ppc_md.nvram_size   = ppc32_nvram_size;
} else if (nvram_naddrs == 2) {
nvram_addr = ioremap(r1.start, s1);
nvram_data = ioremap(r2.start, s2);
ppc_md.nvram_read_val   = indirect_nvram_read_byte;
ppc_md.nvram_write_val  = indirect_nvram_write_byte;
+   ppc_md.nvram_size   = ppc32_nvram_size;
} else if (nvram_naddrs == 0 && sys_ctrler == SYS_CTRLER_PMU) {
 #ifdef CONFIG_ADB_PMU
nvram_naddrs = -1;
ppc_md.nvram_read_val   = pmu_nvram_read_byte;
ppc_md.nvram_write_val  = pmu_nvram_write_byte;
+   ppc_md.nvram_size   = ppc32_nvram_size;
 #endif /* CONFIG_ADB_PMU */
} else {
printk(KERN_ERR "Incompatible type of NVRAM\n");


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[RFC v3 05/24] char/nvram: Adopt arch_nvram_ops

2015-06-27 Thread Finn Thain
Different platforms and architectures offer different NVRAM sizes and
access methods. E.g. PPC32 has byte-at-a-time read/write functions whereas
PPC64 has byte-range read/write functions. Adopt the nvram_ops struct so
the nvram module can call such functions as are defined by the various 
platforms and architectures.

Signed-off-by: Finn Thain 

---

The #ifdefs here restrict the procfs and checksumming code to those
architectures with PC-style RTC NVRAM. There may be a better place for
that code but it's an open question. See https://lkml.org/lkml/2015/2/3/22

The procfs code here, if irrelevant to ARM platforms, could be moved to
arch/x86 (like the earlier patch does for m68k code) and the nvram ops
could be implemented and exported by the rtc-cmos driver instead. This
would eliminate these #ifdefs.

---
 drivers/char/nvram.c  |   30 +++---
 include/linux/nvram.h |2 ++
 2 files changed, 29 insertions(+), 3 deletions(-)

Index: linux/drivers/char/nvram.c
===
--- linux.orig/drivers/char/nvram.c 2015-06-28 11:41:32.0 +1000
+++ linux/drivers/char/nvram.c  2015-06-28 11:41:34.0 +1000
@@ -51,9 +51,12 @@ static DEFINE_MUTEX(nvram_mutex);
 static DEFINE_SPINLOCK(nvram_state_lock);
 static int nvram_open_cnt; /* #times opened */
 static int nvram_open_mode;/* special open modes */
+static ssize_t nvram_size;
 #define NVRAM_WRITE1 /* opened for writing (exclusive) */
 #define NVRAM_EXCL 2 /* opened with O_EXCL */
 
+#if defined(CONFIG_X86) || defined(CONFIG_ARM)
+
 /*
  * These functions are provided to be called internally or by other parts of
  * the kernel. It's up to the caller to ensure correct checksum before reading
@@ -161,6 +164,20 @@ void nvram_set_checksum(void)
 }
 #endif  /*  0  */
 
+static ssize_t nvram_get_size(void)
+{
+   return NVRAM_BYTES;
+}
+
+const struct nvram_ops arch_nvram_ops = {
+   .read_byte  = nvram_read_byte,
+   .write_byte = nvram_write_byte,
+   .get_size   = nvram_get_size,
+};
+EXPORT_SYMBOL(arch_nvram_ops);
+
+#endif /* CONFIG_X86 || CONFIG_ARM */
+
 /*
  * The are the file operation function for user access to /dev/nvram
  */
@@ -332,7 +349,7 @@ static int nvram_misc_release(struct ino
return 0;
 }
 
-#ifdef CONFIG_PROC_FS
+#if defined(CONFIG_PROC_FS) && (defined(CONFIG_X86) || defined(CONFIG_ARM))
 
 static char *floppy_types[] = {
"none", "5.25'' 360k", "5.25'' 1.2M", "3.5'' 720k", "3.5'' 1.44M",
@@ -459,13 +476,20 @@ static int __init nvram_module_init(void
 {
int ret;
 
+   if (arch_nvram_ops.get_size == NULL)
+   return -ENODEV;
+
+   nvram_size = arch_nvram_ops.get_size();
+   if (nvram_size < 0)
+   return nvram_size;
+
ret = misc_register(&nvram_misc);
if (ret) {
pr_err("nvram: can't misc_register on minor=%d\n", NVRAM_MINOR);
return ret;
}
 
-#ifdef CONFIG_PROC_FS
+#if defined(CONFIG_PROC_FS) && (defined(CONFIG_X86) || defined(CONFIG_ARM))
if (!proc_create("driver/nvram", 0, NULL, &nvram_proc_fops)) {
pr_err("nvram: can't create /proc/driver/nvram\n");
misc_deregister(&nvram_misc);
@@ -479,7 +503,7 @@ static int __init nvram_module_init(void
 
 static void __exit nvram_module_exit(void)
 {
-#ifdef CONFIG_PROC_FS
+#if defined(CONFIG_PROC_FS) && (defined(CONFIG_X86) || defined(CONFIG_ARM))
remove_proc_entry("driver/nvram", NULL);
 #endif
misc_deregister(&nvram_misc);
Index: linux/include/linux/nvram.h
===
--- linux.orig/include/linux/nvram.h2015-06-28 11:41:31.0 +1000
+++ linux/include/linux/nvram.h 2015-06-28 11:41:34.0 +1000
@@ -14,6 +14,8 @@ extern int nvram_check_checksum(void);
 struct nvram_ops {
ssize_t (*read)(char *, size_t, loff_t *);
ssize_t (*write)(char *, size_t, loff_t *);
+   unsigned char   (*read_byte)(int);
+   void(*write_byte)(unsigned char, int);
ssize_t (*get_size)(void);
 };
 


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[RFC v3 18/24] powerpc: Remove CONFIG_GENERIC_NVRAM and adopt CONFIG_HAVE_ARCH_NVRAM_OPS

2015-06-27 Thread Finn Thain
Switch PPC32 kernels from the generic_nvram module to the nvram module.

Also fix a theoretical bug where CHRP omits the chrp_nvram_init()
call when CONFIG_NVRAM_MODULE=m.

As before, when CONFIG_PPC && !CONFIG_PPC_PMAC, the IOC_NVRAM_GET_OFFSET
ioctl is unimplemented. For the nvram module, unimplemented ioctls return
-ENOTTY. Whereas, for the superseded generic_nvram module they would
return -EINVAL.

Signed-off-by: Finn Thain 

---

This ioctl change is visible to userspace code but only in an error path.
I didn't find any userspace code that uses the IOC_NVRAM_GET_OFFSET ioctl.

The change in the name of the module is also visible. The module that
implements /dev/nvram on PowerPC now has suitable aliases, i.e.
MODULE_ALIAS_MISCDEV(NVRAM_MINOR);
MODULE_ALIAS("devname:nvram"); 
so that the device special file can be automatically created and the
module automatically loaded when needed. Previously this was not the case.

---

Changes since v1:
- Small indentation fix.

---
 arch/powerpc/Kconfig|2 +-
 arch/powerpc/kernel/setup_32.c  |2 +-
 arch/powerpc/platforms/chrp/Makefile|2 +-
 arch/powerpc/platforms/chrp/setup.c |2 +-
 arch/powerpc/platforms/powermac/setup.c |3 +--
 drivers/char/Kconfig|   10 ++
 6 files changed, 11 insertions(+), 10 deletions(-)

Index: linux/arch/powerpc/Kconfig
===
--- linux.orig/arch/powerpc/Kconfig 2015-06-28 11:41:27.0 +1000
+++ linux/arch/powerpc/Kconfig  2015-06-28 11:41:49.0 +1000
@@ -178,7 +178,7 @@ config SYSVIPC_COMPAT
default y
 
 # All PPC32s use generic nvram driver through ppc_md
-config GENERIC_NVRAM
+config HAVE_ARCH_NVRAM_OPS
bool
default y if PPC32
 
Index: linux/arch/powerpc/kernel/setup_32.c
===
--- linux.orig/arch/powerpc/kernel/setup_32.c   2015-06-28 11:41:46.0 
+1000
+++ linux/arch/powerpc/kernel/setup_32.c2015-06-28 11:41:49.0 
+1000
@@ -168,7 +168,7 @@ int __init ppc_setup_l3cr(char *str)
 }
 __setup("l3cr=", ppc_setup_l3cr);
 
-#ifdef CONFIG_GENERIC_NVRAM
+#if IS_ENABLED(CONFIG_NVRAM)
 
 static unsigned char ppc_nvram_read_byte(int addr)
 {
Index: linux/arch/powerpc/platforms/chrp/Makefile
===
--- linux.orig/arch/powerpc/platforms/chrp/Makefile 2015-06-28 
11:41:27.0 +1000
+++ linux/arch/powerpc/platforms/chrp/Makefile  2015-06-28 11:41:49.0 
+1000
@@ -1,3 +1,3 @@
 obj-y  += setup.o time.o pegasos_eth.o pci.o
 obj-$(CONFIG_SMP)  += smp.o
-obj-$(CONFIG_NVRAM)+= nvram.o
+obj-$(CONFIG_NVRAM:m=y)+= nvram.o
Index: linux/arch/powerpc/platforms/chrp/setup.c
===
--- linux.orig/arch/powerpc/platforms/chrp/setup.c  2015-06-28 
11:41:27.0 +1000
+++ linux/arch/powerpc/platforms/chrp/setup.c   2015-06-28 11:41:49.0 
+1000
@@ -557,7 +557,7 @@ void __init chrp_init_IRQ(void)
 void __init
 chrp_init2(void)
 {
-#ifdef CONFIG_NVRAM
+#if IS_ENABLED(CONFIG_NVRAM)
chrp_nvram_init();
 #endif
 
Index: linux/arch/powerpc/platforms/powermac/setup.c
===
--- linux.orig/arch/powerpc/platforms/powermac/setup.c  2015-06-28 
11:41:27.0 +1000
+++ linux/arch/powerpc/platforms/powermac/setup.c   2015-06-28 
11:41:49.0 +1000
@@ -321,8 +321,7 @@ static void __init pmac_setup_arch(void)
find_via_pmu();
smu_init();
 
-#if defined(CONFIG_NVRAM) || defined(CONFIG_NVRAM_MODULE) || \
-defined(CONFIG_PPC64)
+#if IS_ENABLED(CONFIG_NVRAM) || defined(CONFIG_PPC64)
pmac_nvram_init();
 #endif
 
Index: linux/drivers/char/Kconfig
===
--- linux.orig/drivers/char/Kconfig 2015-06-28 11:41:39.0 +1000
+++ linux/drivers/char/Kconfig  2015-06-28 11:41:49.0 +1000
@@ -247,7 +247,7 @@ source "drivers/char/hw_random/Kconfig"
 
 config NVRAM
tristate "/dev/nvram support"
-   depends on X86 || (ARM && RTC_DRV_CMOS) || GENERIC_NVRAM || 
HAVE_ARCH_NVRAM_OPS
+   depends on X86 || (ARM && RTC_DRV_CMOS) || HAVE_ARCH_NVRAM_OPS
---help---
  If you say Y here and create a character special file /dev/nvram
  with major number 10 and minor number 144 using mknod ("man mknod"),
@@ -256,9 +256,11 @@ config NVRAM
  and most Ataris.  The actual number of bytes varies, depending on the
  nvram in the system, but is usually 114 (128-14 for the RTC).
 
- This memory is conventionally called "CMOS RAM" on PCs and "NVRAM"
- on Ataris. /dev/nvram may be used to view s

[RFC v3 15/24] powerpc: Implement nvram sync ioctl

2015-06-27 Thread Finn Thain
Add the powerpc-specific sync() method to struct nvram_ops and implement
the corresponding ioctl in the nvram module. This allows the nvram module
to replace the generic_nvram module.

Signed-off-by: Finn Thain 

---

On PPC32, the IOC_NVRAM_SYNC ioctl call always returns 0, even for those
platforms that don't implement ppc_md.nvram_sync. This patch retains
that quirk. It might be better to return failure (which is what PPC64 does).

Changed since v1:
- Don't bother acquiring the mutex for unimplemented ioctls.

---
 arch/powerpc/include/asm/nvram.h |3 ---
 arch/powerpc/kernel/setup_32.c   |6 +++---
 drivers/char/generic_nvram.c |2 +-
 drivers/char/nvram.c |   39 +++
 include/linux/nvram.h|4 
 5 files changed, 47 insertions(+), 7 deletions(-)

Index: linux/drivers/char/nvram.c
===
--- linux.orig/drivers/char/nvram.c 2015-06-28 11:41:40.0 +1000
+++ linux/drivers/char/nvram.c  2015-06-28 11:41:44.0 +1000
@@ -48,6 +48,11 @@
 #include 
 
 
+#ifdef CONFIG_PPC
+#include 
+#include 
+#endif
+
 static DEFINE_MUTEX(nvram_mutex);
 static DEFINE_SPINLOCK(nvram_state_lock);
 static int nvram_open_cnt; /* #times opened */
@@ -338,6 +343,37 @@ static long nvram_misc_ioctl(struct file
long ret = -ENOTTY;
 
switch (cmd) {
+#ifdef CONFIG_PPC
+#ifdef CONFIG_PPC_PMAC
+   case OBSOLETE_PMAC_NVRAM_GET_OFFSET:
+   pr_warn("nvram: Using obsolete PMAC_NVRAM_GET_OFFSET ioctl\n");
+   /* fall through */
+   case IOC_NVRAM_GET_OFFSET: {
+   int part, offset;
+
+   if (!machine_is(powermac))
+   return -EINVAL;
+   if (copy_from_user(&part,
+  (void __user *)arg, sizeof(part)) != 0)
+   return -EFAULT;
+   if (part < pmac_nvram_OF || part > pmac_nvram_NR)
+   return -EINVAL;
+   offset = pmac_get_partition(part);
+   if (copy_to_user((void __user *)arg,
+&offset, sizeof(offset)) != 0)
+   return -EFAULT;
+   ret = 0;
+   break;
+   }
+#endif
+   case IOC_NVRAM_SYNC:
+   if (arch_nvram_ops.sync != NULL) {
+   mutex_lock(&nvram_mutex);
+   ret = arch_nvram_ops.sync();
+   mutex_unlock(&nvram_mutex);
+   }
+   break;
+#else /* !CONFIG_PPC */
case NVRAM_INIT:
/* initialize NVRAM contents and checksum */
if (!capable(CAP_SYS_ADMIN))
@@ -361,6 +397,7 @@ static long nvram_misc_ioctl(struct file
mutex_unlock(&nvram_mutex);
}
break;
+#endif /* CONFIG_PPC */
}
return ret;
 }
@@ -376,6 +413,7 @@ static int nvram_misc_open(struct inode
return -EBUSY;
}
 
+#ifndef CONFIG_PPC
/* Prevent multiple writers if the set_checksum ioctl is implemented. */
if ((arch_nvram_ops.set_checksum != NULL) &&
(file->f_mode & FMODE_WRITE) &&
@@ -383,6 +421,7 @@ static int nvram_misc_open(struct inode
spin_unlock(&nvram_state_lock);
return -EBUSY;
}
+#endif
 
if (file->f_flags & O_EXCL)
nvram_open_mode |= NVRAM_EXCL;
Index: linux/include/linux/nvram.h
===
--- linux.orig/include/linux/nvram.h2015-06-28 11:41:36.0 +1000
+++ linux/include/linux/nvram.h 2015-06-28 11:41:44.0 +1000
@@ -17,8 +17,12 @@ struct nvram_ops {
unsigned char   (*read_byte)(int);
void(*write_byte)(unsigned char, int);
ssize_t (*get_size)(void);
+#ifdef CONFIG_PPC
+   long(*sync)(void);
+#else
long(*set_checksum)(void);
long(*initialize)(void);
+#endif
 };
 
 extern const struct nvram_ops arch_nvram_ops;
Index: linux/arch/powerpc/include/asm/nvram.h
===
--- linux.orig/arch/powerpc/include/asm/nvram.h 2015-06-28 11:41:43.0 
+1000
+++ linux/arch/powerpc/include/asm/nvram.h  2015-06-28 11:41:44.0 
+1000
@@ -78,9 +78,6 @@ extern intpmac_get_partition(int partit
 extern u8  pmac_xpram_read(int xpaddr);
 extern voidpmac_xpram_write(int xpaddr, u8 data);
 
-/* Synchronize NVRAM */
-extern voidnvram_sync(void);
-
 /* Initialize NVRAM OS partition */
 extern int __init nvram_init_os_partition(struct nvram_os_partition *part);
 
Index: linux/arch/powerpc/kernel/setup_32.c
===
--- linux.orig/arch/powerpc/kernel

[RFC v3 19/24] char/generic_nvram: Remove as unused

2015-06-27 Thread Finn Thain
And thus eliminate some twisted CONFIG_GENERIC_NVRAM logic.

Signed-off-by: Finn Thain 

---
 drivers/char/Makefile|6 -
 drivers/char/generic_nvram.c |  176 ---
 2 files changed, 1 insertion(+), 181 deletions(-)

Index: linux/drivers/char/Makefile
===
--- linux.orig/drivers/char/Makefile2015-06-28 11:41:27.0 +1000
+++ linux/drivers/char/Makefile 2015-06-28 11:41:51.0 +1000
@@ -30,11 +30,7 @@ obj-$(CONFIG_GEN_RTC)+= genrtc.o
 obj-$(CONFIG_EFI_RTC)  += efirtc.o
 obj-$(CONFIG_DS1302)   += ds1302.o
 obj-$(CONFIG_XILINX_HWICAP)+= xilinx_hwicap/
-ifeq ($(CONFIG_GENERIC_NVRAM),y)
-  obj-$(CONFIG_NVRAM)  += generic_nvram.o
-else
-  obj-$(CONFIG_NVRAM)  += nvram.o
-endif
+obj-$(CONFIG_NVRAM)+= nvram.o
 obj-$(CONFIG_TOSHIBA)  += toshiba.o
 obj-$(CONFIG_I8K)  += i8k.o
 obj-$(CONFIG_DS1620)   += ds1620.o
Index: linux/drivers/char/generic_nvram.c
===
--- linux.orig/drivers/char/generic_nvram.c 2015-06-28 11:41:46.0 
+1000
+++ /dev/null   1970-01-01 00:00:00.0 +
@@ -1,176 +0,0 @@
-/*
- * Generic /dev/nvram driver for architectures providing some
- * "generic" hooks, that is :
- *
- * nvram_read_byte, nvram_write_byte, nvram_sync, nvram_get_size
- *
- * Note that an additional hook is supported for PowerMac only
- * for getting the nvram "partition" informations
- *
- */
-
-#define NVRAM_VERSION "1.1"
-
-#include 
-
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-
-#ifdef CONFIG_PPC_PMAC
-#include 
-#include 
-#endif
-
-static DEFINE_MUTEX(nvram_mutex);
-static ssize_t nvram_len;
-
-static loff_t nvram_llseek(struct file *file, loff_t offset, int origin)
-{
-   switch (origin) {
-   case 0:
-   break;
-   case 1:
-   offset += file->f_pos;
-   break;
-   case 2:
-   offset += nvram_len;
-   break;
-   default:
-   offset = -1;
-   }
-   if (offset < 0)
-   return -EINVAL;
-
-   file->f_pos = offset;
-
-   return file->f_pos;
-}
-
-static ssize_t read_nvram(struct file *file, char __user *buf,
- size_t count, loff_t *ppos)
-{
-   unsigned int i;
-   char __user *p = buf;
-
-   if (!access_ok(VERIFY_WRITE, buf, count))
-   return -EFAULT;
-   if (*ppos >= nvram_len)
-   return 0;
-   for (i = *ppos; count > 0 && i < nvram_len; ++i, ++p, --count)
-   if (__put_user(arch_nvram_ops.read_byte(i), p))
-   return -EFAULT;
-   *ppos = i;
-   return p - buf;
-}
-
-static ssize_t write_nvram(struct file *file, const char __user *buf,
-  size_t count, loff_t *ppos)
-{
-   unsigned int i;
-   const char __user *p = buf;
-   char c;
-
-   if (!access_ok(VERIFY_READ, buf, count))
-   return -EFAULT;
-   if (*ppos >= nvram_len)
-   return 0;
-   for (i = *ppos; count > 0 && i < nvram_len; ++i, ++p, --count) {
-   if (__get_user(c, p))
-   return -EFAULT;
-   arch_nvram_ops.write_byte(c, i);
-   }
-   *ppos = i;
-   return p - buf;
-}
-
-static int nvram_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
-   switch(cmd) {
-#ifdef CONFIG_PPC_PMAC
-   case OBSOLETE_PMAC_NVRAM_GET_OFFSET:
-   printk(KERN_WARNING "nvram: Using obsolete 
PMAC_NVRAM_GET_OFFSET ioctl\n");
-   case IOC_NVRAM_GET_OFFSET: {
-   int part, offset;
-
-   if (!machine_is(powermac))
-   return -EINVAL;
-   if (copy_from_user(&part, (void __user*)arg, sizeof(part)) != 0)
-   return -EFAULT;
-   if (part < pmac_nvram_OF || part > pmac_nvram_NR)
-   return -EINVAL;
-   offset = pmac_get_partition(part);
-   if (copy_to_user((void __user*)arg, &offset, sizeof(offset)) != 
0)
-   return -EFAULT;
-   break;
-   }
-#endif /* CONFIG_PPC_PMAC */
-   case IOC_NVRAM_SYNC:
-   arch_nvram_ops.sync();
-   break;
-   default:
-   return -EINVAL;
-   }
-
-   return 0;
-}
-
-static long nvram_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned 
long arg)
-{
-   int ret;
-
-   mutex_lock(&nvram_mutex);
-   ret = nvram_ioctl(file, cmd, arg);
-   mutex_unlock(&nvram_mutex);
-
-   return ret;
-}
-
-const struct file_operations nvram_fops = {
-   .owner  = THIS_MODULE,
-  

[RFC v3 20/24] powerpc: Adopt nvram module for PPC64

2015-06-27 Thread Finn Thain
Adopt nvram module to reduce code duplication.

The IOC_NVRAM_GET_OFFSET ioctl as implemented on PPC64 validates the offset
returned by pmac_get_partition(). Add this test to the nvram module.

Note that the old PPC32 generic_nvram module lacked this test.
So when CONFIG_PPC32 && CONFIG_PPC_PMAC, the IOC_NVRAM_GET_OFFSET ioctl
would have returned 0 (always). But when CONFIG_PPC64 && CONFIG_PPC_PMAC,
the IOC_NVRAM_GET_OFFSET ioctl would have returned -1 (which is -EPERM)
when the requested partition was not found.

With this patch, the result is now -EINVAL on both PPC32 and PPC64 when
the requested PowerMac NVRAM partition is not found.

This is a userspace-visible change, in the non-existent partition case,
which would be in an error path for an IOC_NVRAM_GET_OFFSET ioctl syscall.

Signed-off-by: Finn Thain 

---

BTW, the IOC_NVRAM_SYNC ioctl call returns -EINVAL on PPC64. This patch
retains this behaviour though it might be better to actually perform a sync.
Both PPC64 and PPC32 kernels implement ppc_md.nvram_sync() for Core99,
but on PPC64 the ioctl is unimplemented (unlike PPC32).

---

Changed since v1:
- The -ENOENT that appeared in v1 was changed to -EINVAL, to be
consistent with existing logic, that is,
if (part < pmac_nvram_OF || part > pmac_nvram_NR)
return -EINVAL;

---
 arch/powerpc/Kconfig |3 
 arch/powerpc/kernel/nvram_64.c   |  203 ---
 arch/powerpc/platforms/powermac/Makefile |5 
 arch/powerpc/platforms/powermac/setup.c  |2 
 drivers/char/nvram.c |2 
 5 files changed, 36 insertions(+), 179 deletions(-)

Index: linux/arch/powerpc/Kconfig
===
--- linux.orig/arch/powerpc/Kconfig 2015-06-28 11:41:49.0 +1000
+++ linux/arch/powerpc/Kconfig  2015-06-28 11:41:52.0 +1000
@@ -177,10 +177,9 @@ config SYSVIPC_COMPAT
depends on COMPAT && SYSVIPC
default y
 
-# All PPC32s use generic nvram driver through ppc_md
 config HAVE_ARCH_NVRAM_OPS
bool
-   default y if PPC32
+   default y
 
 config SCHED_OMIT_FRAME_POINTER
bool
Index: linux/arch/powerpc/kernel/nvram_64.c
===
--- linux.orig/arch/powerpc/kernel/nvram_64.c   2015-06-28 11:41:27.0 
+1000
+++ linux/arch/powerpc/kernel/nvram_64.c2015-06-28 11:41:52.0 
+1000
@@ -7,12 +7,6 @@
  *  2 of the License, or (at your option) any later version.
  *
  * /dev/nvram driver for PPC64
- *
- * This perhaps should live in drivers/char
- *
- * TODO: Split the /dev/nvram part (that one can use
- *   drivers/char/generic_nvram.c) from the arch & partition
- *   parsing code.
  */
 
 #include 
@@ -731,153 +725,6 @@ static void oops_to_nvram(struct kmsg_du
spin_unlock_irqrestore(&lock, flags);
 }
 
-static loff_t dev_nvram_llseek(struct file *file, loff_t offset, int origin)
-{
-   int size;
-
-   if (ppc_md.nvram_size == NULL)
-   return -ENODEV;
-   size = ppc_md.nvram_size();
-
-   switch (origin) {
-   case 1:
-   offset += file->f_pos;
-   break;
-   case 2:
-   offset += size;
-   break;
-   }
-   if (offset < 0)
-   return -EINVAL;
-   file->f_pos = offset;
-   return file->f_pos;
-}
-
-
-static ssize_t dev_nvram_read(struct file *file, char __user *buf,
- size_t count, loff_t *ppos)
-{
-   ssize_t ret;
-   char *tmp = NULL;
-   ssize_t size;
-
-   if (!ppc_md.nvram_size) {
-   ret = -ENODEV;
-   goto out;
-   }
-
-   size = ppc_md.nvram_size();
-   if (size < 0) {
-   ret = size;
-   goto out;
-   }
-
-   if (*ppos >= size) {
-   ret = 0;
-   goto out;
-   }
-
-   count = min_t(size_t, count, size - *ppos);
-   count = min(count, PAGE_SIZE);
-
-   tmp = kmalloc(count, GFP_KERNEL);
-   if (!tmp) {
-   ret = -ENOMEM;
-   goto out;
-   }
-
-   ret = ppc_md.nvram_read(tmp, count, ppos);
-   if (ret <= 0)
-   goto out;
-
-   if (copy_to_user(buf, tmp, ret))
-   ret = -EFAULT;
-
-out:
-   kfree(tmp);
-   return ret;
-
-}
-
-static ssize_t dev_nvram_write(struct file *file, const char __user *buf,
- size_t count, loff_t *ppos)
-{
-   ssize_t ret;
-   char *tmp = NULL;
-   ssize_t size;
-
-   ret = -ENODEV;
-   if (!ppc_md.nvram_size)
-   goto out;
-
-   ret = 0;
-   size = ppc_md.nvram_size();
-   if (*ppos >= size || size < 0)
-   goto out;
-
-   count = min_t(size_t, count, size - *ppos);
-   count = min(count, PAGE_SIZE);
-
-   ret = -E

[RFC v3 22/24] m68k/mac: Use macros for RTC accesses not magic numbers

2015-06-27 Thread Finn Thain
Signed-off-by: Finn Thain 

---

This is intended to improve code style and not affect code behaviour.
I've tested this on a Quadra 650.

I don't know the meanings of the 4 undocumented write protect register
bits 0x55, so I decided against defining 4 macros for those bits.

---
 arch/m68k/mac/misc.c |   59 +++
 1 file changed, 41 insertions(+), 18 deletions(-)

Index: linux/arch/m68k/mac/misc.c
===
--- linux.orig/arch/m68k/mac/misc.c 2015-06-28 11:41:53.0 +1000
+++ linux/arch/m68k/mac/misc.c  2015-06-28 11:41:54.0 +1000
@@ -242,6 +242,21 @@ static void via_rtc_send(__u8 data)
 }
 
 /*
+ * These values can be found in Inside Macintosh vol. III ch. 2
+ * which has a description of the RTC chip in the original Mac.
+ */
+
+#define RTC_FLG_READBIT(7)
+#define RTC_FLG_WRITE_PROTECT   BIT(7)
+#define RTC_CMD_READ(r) (RTC_FLG_READ | (r << 2))
+#define RTC_CMD_WRITE(r)(r << 2)
+#define RTC_REG_SECONDS_0   0
+#define RTC_REG_SECONDS_1   1
+#define RTC_REG_SECONDS_2   2
+#define RTC_REG_SECONDS_3   3
+#define RTC_REG_WRITE_PROTECT   13
+
+/*
  * Execute a VIA PRAM/RTC command. For read commands
  * data should point to a one-byte buffer for the
  * resulting data. For write commands it should point
@@ -250,13 +265,17 @@ static void via_rtc_send(__u8 data)
  * This function disables all interrupts while running.
  */
 
-static void via_pram_command(int command, __u8 *data)
+static void via_rtc_command(int command, __u8 *data)
 {
unsigned long flags;
int is_read;
 
local_irq_save(flags);
 
+   /* The least significant bits must be 0b01 according to Inside Mac */
+
+   command = (command & ~3) | 1;
+
/* Enable the RTC and make sure the strobe line is high */
 
via1[vBufB] = (via1[vBufB] | VIA1B_vRTCClk) & ~VIA1B_vRTCEnb;
@@ -264,10 +283,10 @@ static void via_pram_command(int command
if (command & 0xFF00) { /* extended (two-byte) command */
via_rtc_send((command & 0xFF00) >> 8);
via_rtc_send(command & 0xFF);
-   is_read = command & 0x8000;
+   is_read = command & (RTC_FLG_READ << 8);
} else {/* one-byte command */
via_rtc_send(command);
-   is_read = command & 0x80;
+   is_read = command & RTC_FLG_READ;
}
if (is_read) {
*data = via_rtc_recv();
@@ -306,10 +325,10 @@ static long via_read_time(void)
} result, last_result;
int count = 1;
 
-   via_pram_command(0x81, &last_result.cdata[3]);
-   via_pram_command(0x85, &last_result.cdata[2]);
-   via_pram_command(0x89, &last_result.cdata[1]);
-   via_pram_command(0x8D, &last_result.cdata[0]);
+   via_rtc_command(RTC_CMD_READ(RTC_REG_SECONDS_0), &last_result.cdata[3]);
+   via_rtc_command(RTC_CMD_READ(RTC_REG_SECONDS_1), &last_result.cdata[2]);
+   via_rtc_command(RTC_CMD_READ(RTC_REG_SECONDS_2), &last_result.cdata[1]);
+   via_rtc_command(RTC_CMD_READ(RTC_REG_SECONDS_3), &last_result.cdata[0]);
 
/*
 * The NetBSD guys say to loop until you get the same reading
@@ -317,10 +336,14 @@ static long via_read_time(void)
 */
 
while (1) {
-   via_pram_command(0x81, &result.cdata[3]);
-   via_pram_command(0x85, &result.cdata[2]);
-   via_pram_command(0x89, &result.cdata[1]);
-   via_pram_command(0x8D, &result.cdata[0]);
+   via_rtc_command(RTC_CMD_READ(RTC_REG_SECONDS_0),
+   &result.cdata[3]);
+   via_rtc_command(RTC_CMD_READ(RTC_REG_SECONDS_1),
+   &result.cdata[2]);
+   via_rtc_command(RTC_CMD_READ(RTC_REG_SECONDS_2),
+   &result.cdata[1]);
+   via_rtc_command(RTC_CMD_READ(RTC_REG_SECONDS_3),
+   &result.cdata[0]);
 
if (result.idata == last_result.idata)
return result.idata - RTC_OFFSET;
@@ -356,18 +379,18 @@ static void via_write_time(long time)
/* Clear the write protect bit */
 
temp = 0x55;
-   via_pram_command(0x35, &temp);
+   via_rtc_command(RTC_CMD_WRITE(RTC_REG_WRITE_PROTECT), &temp);
 
data.idata = time + RTC_OFFSET;
-   via_pram_command(0x01, &data.cdata[3]);
-   via_pram_command(0x05, &data.cdata[2]);
-   via_pram_command(0x09, &data.cdata[1]);
-   via_pram_command(0x0D, &data.cdata[0]);
+   via_rtc_command(RTC_CMD_WRITE(RTC_REG_SECONDS_0), &data.cdata[3]);
+   via_rtc_command(RTC_CMD_WRITE(RTC_REG_SECONDS_1), &data.cdata[2]);
+   

[RFC v3 24/24] m68k: Dispatch nvram_ops calls to Atari or Mac functions

2015-06-27 Thread Finn Thain
A multi-platform kernel binary needs to decide at run-time how to dispatch
the arch_nvram_ops calls. Add platform-independent arch_nvram_ops, for use
when multiple platform-specific NVRAM ops implementations are needed.

Enable CONFIG_HAVE_ARCH_NVRAM_OPS for Macs.

Signed-off-by: Finn Thain 

---

Changed since v1:
- Removed Mac and Atari ops struct definitions and the associated #ifdefs.
- Moved extern declarations for fewer lines of code and better readability.
- The IS_ENABLED(CONFIG_NVRAM) tests were moved to this patch, because it is
now in this patch that CONFIG_HAVE_ARCH_NVRAM_OPS is enabled for Macs.

---
 arch/m68k/Kconfig   |2 
 arch/m68k/atari/nvram.c |   21 ++--
 arch/m68k/kernel/setup_mm.c |  107 
 arch/m68k/mac/misc.c|   18 +++
 4 files changed, 131 insertions(+), 17 deletions(-)

Index: linux/arch/m68k/mac/misc.c
===
--- linux.orig/arch/m68k/mac/misc.c 2015-06-28 11:41:55.0 +1000
+++ linux/arch/m68k/mac/misc.c  2015-06-28 11:41:56.0 +1000
@@ -61,6 +61,7 @@ static void cuda_write_time(long data)
cuda_poll();
 }
 
+#if IS_ENABLED(CONFIG_NVRAM)
 static unsigned char cuda_pram_read_byte(int offset)
 {
struct adb_request req;
@@ -81,6 +82,8 @@ static void cuda_pram_write_byte(unsigne
while (!req.complete)
cuda_poll();
 }
+#endif /* CONFIG_NVRAM */
+
 #else
 #define cuda_read_time() 0
 #define cuda_write_time(n)
@@ -116,6 +119,7 @@ static void pmu_write_time(long data)
pmu_poll();
 }
 
+#if IS_ENABLED(CONFIG_NVRAM)
 static unsigned char pmu_pram_read_byte(int offset)
 {
struct adb_request req;
@@ -139,6 +143,8 @@ static void pmu_pram_write_byte(unsigned
while (!req.complete)
pmu_poll();
 }
+#endif /* CONFIG_NVRAM */
+
 #else
 #define pmu_read_time() 0
 #define pmu_write_time(n)
@@ -172,6 +178,7 @@ static void maciisi_write_time(long data
(data >> 8) & 0xFF, data & 0xFF);
 }
 
+#if IS_ENABLED(CONFIG_NVRAM)
 static unsigned char maciisi_pram_read_byte(int offset)
 {
struct adb_request req;
@@ -187,6 +194,8 @@ static void maciisi_pram_write_byte(unsi
maciisi_request(&req, NULL, 5, CUDA_PACKET, CUDA_SET_PRAM,
(offset >> 8) & 0xFF, offset & 0xFF, data);
 }
+#endif /* CONFIG_NVRAM */
+
 #else
 #define maciisi_read_time() 0
 #define maciisi_write_time(n)
@@ -314,6 +323,7 @@ static void via_rtc_command(int command,
local_irq_restore(flags);
 }
 
+#if IS_ENABLED(CONFIG_NVRAM)
 static unsigned char via_pram_read_byte(int offset)
 {
unsigned char temp;
@@ -336,6 +346,7 @@ static void via_pram_write_byte(unsigned
temp = 0x55 | RTC_FLG_WRITE_PROTECT;
via_rtc_command(RTC_CMD_WRITE(RTC_REG_WRITE_PROTECT), &temp);
 }
+#endif /* CONFIG_NVRAM */
 
 /*
  * Return the current time in seconds since January 1, 1904.
@@ -503,6 +514,7 @@ void pmu_shutdown(void)
  *---
  */
 
+#if IS_ENABLED(CONFIG_NVRAM)
 unsigned char mac_pram_read_byte(int addr)
 {
unsigned char (*func)(int);
@@ -550,6 +562,12 @@ void mac_pram_write_byte(unsigned char v
(*func)(val, addr);
 }
 
+ssize_t mac_pram_get_size(void)
+{
+   return 256;
+}
+#endif /* CONFIG_NVRAM */
+
 void mac_poweroff(void)
 {
/*
Index: linux/arch/m68k/atari/nvram.c
===
--- linux.orig/arch/m68k/atari/nvram.c  2015-06-28 11:41:48.0 +1000
+++ linux/arch/m68k/atari/nvram.c   2015-06-28 11:41:56.0 +1000
@@ -73,7 +73,7 @@ static void __nvram_set_checksum(void)
__nvram_write_byte(sum, ATARI_CKS_LOC + 1);
 }
 
-static long nvram_set_checksum(void)
+long atari_nvram_set_checksum(void)
 {
spin_lock_irq(&rtc_lock);
__nvram_set_checksum();
@@ -81,7 +81,7 @@ static long nvram_set_checksum(void)
return 0;
 }
 
-static long nvram_initialize(void)
+long atari_nvram_initialize(void)
 {
loff_t i;
 
@@ -93,7 +93,7 @@ static long nvram_initialize(void)
return 0;
 }
 
-static ssize_t nvram_read(char *buf, size_t count, loff_t *ppos)
+ssize_t atari_nvram_read(char *buf, size_t count, loff_t *ppos)
 {
char *p = buf;
loff_t i;
@@ -114,7 +114,7 @@ static ssize_t nvram_read(char *buf, siz
return p - buf;
 }
 
-static ssize_t nvram_write(char *buf, size_t count, loff_t *ppos)
+ssize_t atari_nvram_write(char *buf, size_t count, loff_t *ppos)
 {
char *p = buf;
loff_t i;
@@ -137,22 +137,11 @@ static ssize_t nvram_write(char *buf, si
return p - buf;
 }
 
-static ssize_t nvram_get_size(void)
+ssize_t atari_nvram_get_size(void)
 {
-   if (!MACH_IS_ATARI)
-   return -ENODEV;
return NVRAM_BYTES;
 }
 
-const struct nv

[RFC v3 23/24] m68k/mac: Fix PRAM accessors

2015-06-27 Thread Finn Thain
Signed-off-by: Finn Thain 

---

Tested on a PowerBook 520 and Quadra 650.

Changes since v2:
- Make use of the RTC_* macros from the previous patch and add a few more
besides.

---
 arch/m68k/mac/misc.c |   39 +--
 include/uapi/linux/pmu.h |2 ++
 2 files changed, 35 insertions(+), 6 deletions(-)

Index: linux/arch/m68k/mac/misc.c
===
--- linux.orig/arch/m68k/mac/misc.c 2015-06-28 11:41:54.0 +1000
+++ linux/arch/m68k/mac/misc.c  2015-06-28 11:41:55.0 +1000
@@ -119,19 +119,22 @@ static void pmu_write_time(long data)
 static unsigned char pmu_pram_read_byte(int offset)
 {
struct adb_request req;
-   if (pmu_request(&req, NULL, 3, PMU_READ_NVRAM,
-   (offset >> 8) & 0xFF, offset & 0xFF) < 0)
+
+   if (pmu_request(&req, NULL, 3, PMU_READ_XPRAM,
+   offset & 0xFF, 1) < 0)
return 0;
while (!req.complete)
pmu_poll();
-   return req.reply[3];
+
+   return req.reply[1];
 }
 
 static void pmu_pram_write_byte(unsigned char data, int offset)
 {
struct adb_request req;
-   if (pmu_request(&req, NULL, 4, PMU_WRITE_NVRAM,
-   (offset >> 8) & 0xFF, offset & 0xFF, data) < 0)
+
+   if (pmu_request(&req, NULL, 4, PMU_WRITE_XPRAM,
+   offset & 0xFF, 1, data) < 0)
return;
while (!req.complete)
pmu_poll();
@@ -257,6 +260,16 @@ static void via_rtc_send(__u8 data)
 #define RTC_REG_WRITE_PROTECT   13
 
 /*
+ * Inside Mac has no information about two-byte RTC commands but
+ * the MESS source code has the essentials.
+ */
+
+#define RTC_REG_XPRAM   14
+#define RTC_CMD_XPRAM_READ  (RTC_CMD_READ(RTC_REG_XPRAM) << 8)
+#define RTC_CMD_XPRAM_WRITE (RTC_CMD_WRITE(RTC_REG_XPRAM) << 8)
+#define RTC_CMD_XPRAM_ARG(a)(((a & 0xE0) << 3) | ((a & 0x1F) << 2))
+
+/*
  * Execute a VIA PRAM/RTC command. For read commands
  * data should point to a one-byte buffer for the
  * resulting data. For write commands it should point
@@ -303,11 +316,25 @@ static void via_rtc_command(int command,
 
 static unsigned char via_pram_read_byte(int offset)
 {
-   return 0;
+   unsigned char temp;
+
+   via_rtc_command(RTC_CMD_XPRAM_READ | RTC_CMD_XPRAM_ARG(offset), &temp);
+
+   return temp;
 }
 
 static void via_pram_write_byte(unsigned char data, int offset)
 {
+   unsigned char temp;
+
+   temp = 0x55;
+   via_rtc_command(RTC_CMD_WRITE(RTC_REG_WRITE_PROTECT), &temp);
+
+   temp = data;
+   via_rtc_command(RTC_CMD_XPRAM_WRITE | RTC_CMD_XPRAM_ARG(offset), &temp);
+
+   temp = 0x55 | RTC_FLG_WRITE_PROTECT;
+   via_rtc_command(RTC_CMD_WRITE(RTC_REG_WRITE_PROTECT), &temp);
 }
 
 /*
Index: linux/include/uapi/linux/pmu.h
===
--- linux.orig/include/uapi/linux/pmu.h 2015-06-28 11:41:27.0 +1000
+++ linux/include/uapi/linux/pmu.h  2015-06-28 11:41:55.0 +1000
@@ -18,7 +18,9 @@
 #define PMU_POWER_CTRL 0x11/* control power of some devices */
 #define PMU_ADB_CMD0x20/* send ADB packet */
 #define PMU_ADB_POLL_OFF   0x21/* disable ADB auto-poll */
+#define PMU_WRITE_XPRAM0x32/* write eXtended Parameter RAM 
*/
 #define PMU_WRITE_NVRAM0x33/* write non-volatile RAM */
+#define PMU_READ_XPRAM 0x3a/* read eXtended Parameter RAM */
 #define PMU_READ_NVRAM 0x3b/* read non-volatile RAM */
 #define PMU_SET_RTC0x30/* set real-time clock */
 #define PMU_READ_RTC   0x38/* read real-time clock */


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[RFC v3 21/24] m68k/mac: Adopt naming and calling conventions for PRAM routines

2015-06-27 Thread Finn Thain
Adopt the existing *_read_byte and *_write_byte naming convention.
Rename via_pram_readbyte and via_pram_writebyte to avoid confusion.
Adjust calling conventions of mac_pram_* functions to match the
arch_nvram_ops struct methods.

Signed-off-by: Finn Thain 

---

Changes since v1:
- Don't introduce the arch_nvram_ops struct in this patch, even if it 
would form a logical progression. Since the struct would get replaced
later on, some might see it as churn.

Changes since v2:
- Rename via_pram_send() and via_pram_recv() as
via_rtc_send() and via_rtc_recv() resp.

---
 arch/m68k/mac/misc.c |   91 +--
 1 file changed, 46 insertions(+), 45 deletions(-)

Index: linux/arch/m68k/mac/misc.c
===
--- linux.orig/arch/m68k/mac/misc.c 2015-06-28 11:41:27.0 +1000
+++ linux/arch/m68k/mac/misc.c  2015-06-28 11:41:53.0 +1000
@@ -61,7 +61,7 @@ static void cuda_write_time(long data)
cuda_poll();
 }
 
-static __u8 cuda_read_pram(int offset)
+static unsigned char cuda_pram_read_byte(int offset)
 {
struct adb_request req;
if (cuda_request(&req, NULL, 4, CUDA_PACKET, CUDA_GET_PRAM,
@@ -72,7 +72,7 @@ static __u8 cuda_read_pram(int offset)
return req.reply[3];
 }
 
-static void cuda_write_pram(int offset, __u8 data)
+static void cuda_pram_write_byte(unsigned char data, int offset)
 {
struct adb_request req;
if (cuda_request(&req, NULL, 5, CUDA_PACKET, CUDA_SET_PRAM,
@@ -84,8 +84,8 @@ static void cuda_write_pram(int offset,
 #else
 #define cuda_read_time() 0
 #define cuda_write_time(n)
-#define cuda_read_pram NULL
-#define cuda_write_pram NULL
+#define cuda_pram_read_byte NULL
+#define cuda_pram_write_byte NULL
 #endif
 
 #ifdef CONFIG_ADB_PMU68K
@@ -116,7 +116,7 @@ static void pmu_write_time(long data)
pmu_poll();
 }
 
-static __u8 pmu_read_pram(int offset)
+static unsigned char pmu_pram_read_byte(int offset)
 {
struct adb_request req;
if (pmu_request(&req, NULL, 3, PMU_READ_NVRAM,
@@ -127,7 +127,7 @@ static __u8 pmu_read_pram(int offset)
return req.reply[3];
 }
 
-static void pmu_write_pram(int offset, __u8 data)
+static void pmu_pram_write_byte(unsigned char data, int offset)
 {
struct adb_request req;
if (pmu_request(&req, NULL, 4, PMU_WRITE_NVRAM,
@@ -139,8 +139,8 @@ static void pmu_write_pram(int offset, _
 #else
 #define pmu_read_time() 0
 #define pmu_write_time(n)
-#define pmu_read_pram NULL
-#define pmu_write_pram NULL
+#define pmu_pram_read_byte NULL
+#define pmu_pram_write_byte NULL
 #endif
 
 #if 0 /* def CONFIG_ADB_MACIISI */
@@ -169,7 +169,7 @@ static void maciisi_write_time(long data
(data >> 8) & 0xFF, data & 0xFF);
 }
 
-static __u8 maciisi_read_pram(int offset)
+static unsigned char maciisi_pram_read_byte(int offset)
 {
struct adb_request req;
if (maciisi_request(&req, NULL, 4, CUDA_PACKET, CUDA_GET_PRAM,
@@ -178,7 +178,7 @@ static __u8 maciisi_read_pram(int offset
return req.reply[3];
 }
 
-static void maciisi_write_pram(int offset, __u8 data)
+static void maciisi_pram_write_byte(unsigned char data, int offset)
 {
struct adb_request req;
maciisi_request(&req, NULL, 5, CUDA_PACKET, CUDA_SET_PRAM,
@@ -187,8 +187,8 @@ static void maciisi_write_pram(int offse
 #else
 #define maciisi_read_time() 0
 #define maciisi_write_time(n)
-#define maciisi_read_pram NULL
-#define maciisi_write_pram NULL
+#define maciisi_pram_read_byte NULL
+#define maciisi_pram_write_byte NULL
 #endif
 
 /*
@@ -198,7 +198,7 @@ static void maciisi_write_pram(int offse
  * the RTC should be enabled.
  */
 
-static __u8 via_pram_readbyte(void)
+static __u8 via_rtc_recv(void)
 {
int i,reg;
__u8data;
@@ -225,7 +225,7 @@ static __u8 via_pram_readbyte(void)
return data;
 }
 
-static void via_pram_writebyte(__u8 data)
+static void via_rtc_send(__u8 data)
 {
int i,reg,bit;
 
@@ -262,17 +262,17 @@ static void via_pram_command(int command
via1[vBufB] = (via1[vBufB] | VIA1B_vRTCClk) & ~VIA1B_vRTCEnb;
 
if (command & 0xFF00) { /* extended (two-byte) command */
-   via_pram_writebyte((command & 0xFF00) >> 8);
-   via_pram_writebyte(command & 0xFF);
+   via_rtc_send((command & 0xFF00) >> 8);
+   via_rtc_send(command & 0xFF);
is_read = command & 0x8000;
} else {/* one-byte command */
-   via_pram_writebyte(command);
+   via_rtc_send(command);
is_read = command & 0x80;
}
if (is_read) {
-   *data = via_pram_readbyte();
+   *data = via_rtc_recv();
} else {
-   via_pram_writebyte(*data);
+   via_rtc_send(*

[RFC v3 16/24] powerpc, fbdev: Use arch_nvram_ops methods instead of nvram_read_byte() and nvram_write_byte()

2015-06-27 Thread Finn Thain
Make use of arch_nvram_ops in device drivers so that the nvram_*
function exports can be removed.

Since they are no longer global symbols, rename the PPC32 nvram_* functions
appropriately.

Add the missing CONFIG_NVRAM test to imsttfb to avoid a build failure.

Signed-off-by: Finn Thain 

---
 arch/powerpc/kernel/setup_32.c |8 
 drivers/char/generic_nvram.c   |4 ++--
 drivers/video/fbdev/controlfb.c|4 ++--
 drivers/video/fbdev/imsttfb.c  |7 +++
 drivers/video/fbdev/matrox/matroxfb_base.c |2 +-
 drivers/video/fbdev/platinumfb.c   |4 ++--
 drivers/video/fbdev/valkyriefb.c   |4 ++--
 7 files changed, 16 insertions(+), 17 deletions(-)

Index: linux/arch/powerpc/kernel/setup_32.c
===
--- linux.orig/arch/powerpc/kernel/setup_32.c   2015-06-28 11:41:44.0 
+1000
+++ linux/arch/powerpc/kernel/setup_32.c2015-06-28 11:41:46.0 
+1000
@@ -170,20 +170,18 @@ __setup("l3cr=", ppc_setup_l3cr);
 
 #ifdef CONFIG_GENERIC_NVRAM
 
-unsigned char nvram_read_byte(int addr)
+static unsigned char ppc_nvram_read_byte(int addr)
 {
if (ppc_md.nvram_read_val)
return ppc_md.nvram_read_val(addr);
return 0xff;
 }
-EXPORT_SYMBOL(nvram_read_byte);
 
-void nvram_write_byte(unsigned char val, int addr)
+static void ppc_nvram_write_byte(unsigned char val, int addr)
 {
if (ppc_md.nvram_write_val)
ppc_md.nvram_write_val(addr, val);
 }
-EXPORT_SYMBOL(nvram_write_byte);
 
 static ssize_t ppc_nvram_get_size(void)
 {
@@ -200,6 +198,8 @@ static long ppc_nvram_sync(void)
 }
 
 const struct nvram_ops arch_nvram_ops = {
+   .read_byte  = ppc_nvram_read_byte,
+   .write_byte = ppc_nvram_write_byte,
.get_size   = ppc_nvram_get_size,
.sync   = ppc_nvram_sync,
 };
Index: linux/drivers/char/generic_nvram.c
===
--- linux.orig/drivers/char/generic_nvram.c 2015-06-28 11:41:44.0 
+1000
+++ linux/drivers/char/generic_nvram.c  2015-06-28 11:41:46.0 +1000
@@ -64,7 +64,7 @@ static ssize_t read_nvram(struct file *f
if (*ppos >= nvram_len)
return 0;
for (i = *ppos; count > 0 && i < nvram_len; ++i, ++p, --count)
-   if (__put_user(nvram_read_byte(i), p))
+   if (__put_user(arch_nvram_ops.read_byte(i), p))
return -EFAULT;
*ppos = i;
return p - buf;
@@ -84,7 +84,7 @@ static ssize_t write_nvram(struct file *
for (i = *ppos; count > 0 && i < nvram_len; ++i, ++p, --count) {
if (__get_user(c, p))
return -EFAULT;
-   nvram_write_byte(c, i);
+   arch_nvram_ops.write_byte(c, i);
}
*ppos = i;
return p - buf;
Index: linux/drivers/video/fbdev/controlfb.c
===
--- linux.orig/drivers/video/fbdev/controlfb.c  2015-06-28 11:41:27.0 
+1000
+++ linux/drivers/video/fbdev/controlfb.c   2015-06-28 11:41:46.0 
+1000
@@ -415,7 +415,7 @@ static int __init init_control(struct fb
/* Try to pick a video mode out of NVRAM if we have one. */
 #ifdef CONFIG_NVRAM
if (default_cmode == CMODE_NVRAM) {
-   cmode = nvram_read_byte(NV_CMODE);
+   cmode = arch_nvram_ops.read_byte(NV_CMODE);
if(cmode < CMODE_8 || cmode > CMODE_32)
cmode = CMODE_8;
} else
@@ -423,7 +423,7 @@ static int __init init_control(struct fb
cmode=default_cmode;
 #ifdef CONFIG_NVRAM
if (default_vmode == VMODE_NVRAM) {
-   vmode = nvram_read_byte(NV_VMODE);
+   vmode = arch_nvram_ops.read_byte(NV_VMODE);
if (vmode < 1 || vmode > VMODE_MAX ||
control_mac_modes[vmode - 1].m[full] < cmode) {
sense = read_control_sense(p);
Index: linux/drivers/video/fbdev/matrox/matroxfb_base.c
===
--- linux.orig/drivers/video/fbdev/matrox/matroxfb_base.c   2015-06-28 
11:41:41.0 +1000
+++ linux/drivers/video/fbdev/matrox/matroxfb_base.c2015-06-28 
11:41:46.0 +1000
@@ -1888,7 +1888,7 @@ static int initMatrox2(struct matrox_fb_
default_vmode = VMODE_640_480_60;
 #ifdef CONFIG_NVRAM
if (default_cmode == CMODE_NVRAM)
-   default_cmode = nvram_read_byte(NV_CMODE);
+   default_cmode = arch_nvram_ops.read_byte(NV_CMODE);
 #endif
if (default_cmode < CMODE_8 || default_cmode > CMODE_32)
default_

[RFC v3 17/24] nvram: Drop nvram_* symbol exports and prototypes

2015-06-27 Thread Finn Thain
Drivers now use the arch_nvram_ops calls so remove the function exports and
prototypes. nvram_check_checksum() is unused so remove it.

Signed-off-by: Finn Thain 

---
 arch/m68k/atari/nvram.c |6 +++---
 drivers/char/nvram.c|   27 +--
 include/linux/nvram.h   |8 
 3 files changed, 8 insertions(+), 33 deletions(-)

Index: linux/drivers/char/nvram.c
===
--- linux.orig/drivers/char/nvram.c 2015-06-28 11:41:44.0 +1000
+++ linux/drivers/char/nvram.c  2015-06-28 11:41:48.0 +1000
@@ -82,13 +82,12 @@ static ssize_t nvram_size;
  * periodic 11 min sync from kernel/time/ntp.c vs. this driver.)
  */
 
-unsigned char __nvram_read_byte(int i)
+static unsigned char __nvram_read_byte(int i)
 {
return CMOS_READ(NVRAM_FIRST_BYTE + i);
 }
-EXPORT_SYMBOL(__nvram_read_byte);
 
-unsigned char nvram_read_byte(int i)
+static unsigned char nvram_read_byte(int i)
 {
unsigned long flags;
unsigned char c;
@@ -98,16 +97,14 @@ unsigned char nvram_read_byte(int i)
spin_unlock_irqrestore(&rtc_lock, flags);
return c;
 }
-EXPORT_SYMBOL(nvram_read_byte);
 
 /* This races nicely with trying to read with checksum checking (nvram_read) */
-void __nvram_write_byte(unsigned char c, int i)
+static void __nvram_write_byte(unsigned char c, int i)
 {
CMOS_WRITE(c, NVRAM_FIRST_BYTE + i);
 }
-EXPORT_SYMBOL(__nvram_write_byte);
 
-void nvram_write_byte(unsigned char c, int i)
+static void nvram_write_byte(unsigned char c, int i)
 {
unsigned long flags;
 
@@ -115,14 +112,13 @@ void nvram_write_byte(unsigned char c, i
__nvram_write_byte(c, i);
spin_unlock_irqrestore(&rtc_lock, flags);
 }
-EXPORT_SYMBOL(nvram_write_byte);
 
 /* On PCs, the checksum is built only over bytes 2..31 */
 #define PC_CKS_RANGE_START 2
 #define PC_CKS_RANGE_END   31
 #define PC_CKS_LOC 32
 
-int __nvram_check_checksum(void)
+static int __nvram_check_checksum(void)
 {
int i;
unsigned short sum = 0;
@@ -134,19 +130,6 @@ int __nvram_check_checksum(void)
__nvram_read_byte(PC_CKS_LOC+1);
return (sum & 0x) == expect;
 }
-EXPORT_SYMBOL(__nvram_check_checksum);
-
-int nvram_check_checksum(void)
-{
-   unsigned long flags;
-   int rv;
-
-   spin_lock_irqsave(&rtc_lock, flags);
-   rv = __nvram_check_checksum();
-   spin_unlock_irqrestore(&rtc_lock, flags);
-   return rv;
-}
-EXPORT_SYMBOL(nvram_check_checksum);
 
 static void __nvram_set_checksum(void)
 {
Index: linux/include/linux/nvram.h
===
--- linux.orig/include/linux/nvram.h2015-06-28 11:41:44.0 +1000
+++ linux/include/linux/nvram.h 2015-06-28 11:41:48.0 +1000
@@ -3,14 +3,6 @@
 
 #include 
 
-/* __foo is foo without grabbing the rtc_lock - get it yourself */
-extern unsigned char __nvram_read_byte(int i);
-extern unsigned char nvram_read_byte(int i);
-extern void __nvram_write_byte(unsigned char c, int i);
-extern void nvram_write_byte(unsigned char c, int i);
-extern int __nvram_check_checksum(void);
-extern int nvram_check_checksum(void);
-
 struct nvram_ops {
ssize_t (*read)(char *, size_t, loff_t *);
ssize_t (*write)(char *, size_t, loff_t *);
Index: linux/arch/m68k/atari/nvram.c
===
--- linux.orig/arch/m68k/atari/nvram.c  2015-06-28 11:41:39.0 +1000
+++ linux/arch/m68k/atari/nvram.c   2015-06-28 11:41:48.0 +1000
@@ -33,13 +33,13 @@
  * periodic 11 min sync from kernel/time/ntp.c vs. this driver.)
  */
 
-unsigned char __nvram_read_byte(int i)
+static unsigned char __nvram_read_byte(int i)
 {
return CMOS_READ(NVRAM_FIRST_BYTE + i);
 }
 
 /* This races nicely with trying to read with checksum checking */
-void __nvram_write_byte(unsigned char c, int i)
+static void __nvram_write_byte(unsigned char c, int i)
 {
CMOS_WRITE(c, NVRAM_FIRST_BYTE + i);
 }
@@ -51,7 +51,7 @@ void __nvram_write_byte(unsigned char c,
 #define ATARI_CKS_RANGE_END47
 #define ATARI_CKS_LOC  48
 
-int __nvram_check_checksum(void)
+static int __nvram_check_checksum(void)
 {
int i;
unsigned char sum = 0;


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [RFC v3 02/24] m68k/atari: Move Atari-specific code out of drivers/char/nvram.c

2015-07-01 Thread Finn Thain

On Mon, 29 Jun 2015, Geert Uytterhoeven wrote:

> Hi Finn,
> 
> On Sun, Jun 28, 2015 at 3:42 AM, Finn Thain  
> wrote:
> > Change the vmode calculation from logical OR to bitwise OR, since it 
> > is obviously wrong.
> 
> Ideally, that should be a separate patch we can put on the fast track.

If you will fast track a portion of this patch series, that's great. I'll 
send a separate patch. (However, IMHO, that portion which would ideally be 
fast tracked is a matter of opinion.)

-- 

> 
> Gr{oetje,eeting}s,
> 
> Geert
> 
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [RFC v3 24/24] m68k: Dispatch nvram_ops calls to Atari or Mac functions

2015-07-01 Thread Finn Thain

On Mon, 29 Jun 2015, Geert Uytterhoeven wrote:

> On Sun, Jun 28, 2015 at 3:42 AM, Finn Thain  
> wrote:
> > --- linux.orig/arch/m68k/kernel/setup_mm.c  2015-06-28 
> > 11:41:27.0 +1000
> > +++ linux/arch/m68k/kernel/setup_mm.c   2015-06-28 11:41:56.0 +1000
> 
> > @@ -568,3 +569,109 @@ static int __init adb_probe_sync_enable
> >
> >  __setup("adb_sync", adb_probe_sync_enable);
> >  #endif /* CONFIG_ADB */
> > +
> > +#if IS_ENABLED(CONFIG_NVRAM)
> > +extern unsigned char mac_pram_read_byte(int);
> > +extern void mac_pram_write_byte(unsigned char, int);
> > +extern ssize_t mac_pram_get_size(void);
> > +
> > +extern ssize_t atari_nvram_read(char *, size_t, loff_t *);
> > +extern ssize_t atari_nvram_write(char *, size_t, loff_t *);
> > +extern long atari_nvram_set_checksum(void);
> > +extern long atari_nvram_initialize(void);
> > +extern ssize_t atari_nvram_get_size(void);
> 
> Forward declarations belong in a header file, to be included by both 
> producers and consumers.

Right, will fix. (That was how the v1 patch did this. Looks like I messed 
it up.)

> 
> > --- linux.orig/arch/m68k/Kconfig2015-06-28 11:41:39.0 +1000
> > +++ linux/arch/m68k/Kconfig 2015-06-28 11:41:56.0 +1000
> > @@ -72,7 +72,7 @@ config PGTABLE_LEVELS
> > default 3
> >
> >  config HAVE_ARCH_NVRAM_OPS
> > -   def_bool ATARI
> > +   def_bool ATARI || MAC
> 
> For maintainability, it's better to just have "bool" here, and let both 
> the ATARI and MAC config symbols select HAVE_ARCH_NVRAM_OPS.

OK, will fix.

Thanks for your review.

-- 

> 
> Gr{oetje,eeting}s,
> 
> Geert
> 
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[RFC v4 00/25] Re-use nvram module

2015-07-12 Thread Finn Thain

The generic NVRAM module, drivers/char/generic_nvram, implements a
/dev/nvram misc device. It is used only by 32-bit PowerPC platforms and
isn't generic enough to be more widely used.

The RTC NVRAM module, drivers/char/nvram, also implements a /dev/nvram
misc device. It is used by x86, ARM and m68k.

The former module cannot be used on x86, ARM or m68k because it
cannot co-exist with the latter module, partly due to the Kconfig logic.

It is possible to modify the modules so that one kernel binary could
have either, neither or both. However, automatically loading the
appropriate module is then impossible; if both provide the
char-major-10-144 alias then the wrong module will end up being loaded.
Hence a multi-platform kernel binary needs a single generic nvram module
with alias char-major-10-144.

Therefore, drivers/char/nvram.c should be made more generic and the
arch-specific code therein should be moved to a more appropriate
place under arch/. Also, drivers/char/generic_nvram.c should be removed
to reduce code duplication.

In this patch series, Atari-specific code is moved from the nvram module
to arch/m68k/atari. More arch-specific code in the nvram module could
be moved, probably to arch/x86, but it is difficult to determine just
what code is relevant to ARM platforms and what code is x86-only.

In addressing code duplication, this patch series removes three
inconsistent /dev/nvram misc device implementations. One of these,
drivers/macintosh/nvram.c is entirely unused already. The other two,
drivers/char/generic_nvram.c and the misc device implementation in
arch/powerpc/kernel/nvram_64.c, are replaced by drivers/char/nvram.c.

A benefit of this work is better consistency -- between PPC32 and PPC64
as well as between PPC_PMAC and MAC. This new uniformity does have
implications for userspace, that is, some error codes for some ioctl calls
become consistent on all PowerPC platforms.

The drivers/char/nvram module becomes sufficiently generic to be useful
to other platforms and architectures, besides those with "CMOS" RTC. At the
end of this patch series the module is adopted by the m68k Mac port, which
already has PRAM access functions but lacks the /dev/nvram misc device.

This patch series has been compile-tested for arm, m68k, powerpc and x86.
The nvram and thinkpad_acpi modules were regression tested on a ThinkPad T43.
The /dev/nvram functionality was also regression tested on a G3 PowerMac.
The nvram module was also tested on a PowerBook 520 and Quadra 650.
Note that my testing doesn't cover PPC64 or Atari.

Changes since v1:
- Minor changes to patches 7, 15 and 20 as described in commit logs.
- Revised patches 21 and 24 to address comments from Geert.

Changes since v2:
- Dropped patch 1, "macintosh/nvram: Remove as unused", because it has
since been merged.
- Inserted a new patch, "m68k/mac: Use macros for RTC accesses not
magic numbers".
- Revised patches 21 and 23 to address comments from Geert.

Changes since v3:
- Split the patch, "m68k/atari: Move Atari-specific code out of
drivers/char/nvram.c", as suggested by Geert.
- Revised patches 11 and 25 to address comments from Geert.
- Minor change to patch 21 as described in commit log.

---
 arch/m68k/Kconfig  |3 
 arch/m68k/Kconfig.machine  |2 
 arch/m68k/atari/Makefile   |2 
 arch/m68k/atari/nvram.c|  291 +++
 arch/m68k/include/asm/atarihw.h|6 
 arch/m68k/include/asm/macintosh.h  |4 
 arch/m68k/kernel/setup_mm.c|  100 +++
 arch/m68k/mac/misc.c   |  207 +---
 arch/powerpc/Kconfig   |5 
 arch/powerpc/include/asm/nvram.h   |9 
 arch/powerpc/kernel/nvram_64.c |  203 +--
 arch/powerpc/kernel/setup_32.c |   27 -
 arch/powerpc/platforms/chrp/Makefile   |2 
 arch/powerpc/platforms/chrp/nvram.c|   14 
 arch/powerpc/platforms/chrp/setup.c|2 
 arch/powerpc/platforms/powermac/Makefile   |5 
 arch/powerpc/platforms/powermac/nvram.c|9 
 arch/powerpc/platforms/powermac/setup.c|3 
 arch/powerpc/platforms/pseries/nvram.c |2 
 drivers/char/Kconfig   |   13 
 drivers/char/Makefile  |6 
 drivers/char/generic_nvram.c   |  174 --
 drivers/char/nvram.c   |  742 -
 drivers/platform/x86/thinkpad_acpi.c   |   20 
 drivers/scsi/Kconfig   |6 
 drivers/scsi/atari_scsi.c  |   16 
 drivers/video/fbdev/controlfb.c|4 
 drivers/video/fbdev/imsttfb.c  |7 
 drivers/video/fbdev/matrox/matroxfb_base.c |4 
 drivers/video/fbdev/platinumfb.c   |4 
 drivers/video/fbdev/valkyriefb.c   |4 
 include/linux/nvram.h  |   23 
 include/uapi/linux/pmu.h   |2 
 33 fi

[RFC v4 01/25] scsi/atari_scsi: Dont select CONFIG_NVRAM

2015-07-12 Thread Finn Thain
On powerpc, setting CONFIG_NVRAM=n builds a kernel with no NVRAM support.
Setting CONFIG_NVRAM=m enables the /dev/nvram misc device module without
enabling NVRAM support in drivers. Setting CONFIG_NVRAM=y enables the
misc device (built-in) and also enables NVRAM support in drivers.

m68k shares the valkyriefb driver with powerpc, and since that driver uses
NVRAM, it is affected by CONFIG_ATARI_SCSI, because of the use of
"select NVRAM".

Adopt the powerpc convention on m68k to avoid surprises.

Signed-off-by: Finn Thain 

---

This patch temporarily disables CONFIG_NVRAM on Atari, to prevent build
failures when bisecting the rest of this patch series. It gets enabled
again with the introduction of CONFIG_HAVE_ARCH_NVRAM_OPS, once the
nvram_* global functions have been moved to an ops struct.

The removal of "select NVRAM" may mean that some kernel configs (such
as Debian/m68k) may need tweaking.

---
 drivers/char/Kconfig  |5 +
 drivers/scsi/Kconfig  |6 +++---
 drivers/scsi/atari_scsi.c |8 
 3 files changed, 8 insertions(+), 11 deletions(-)

Index: linux/drivers/char/Kconfig
===
--- linux.orig/drivers/char/Kconfig 2015-07-12 20:24:54.0 +1000
+++ linux/drivers/char/Kconfig  2015-07-12 20:24:54.0 +1000
@@ -247,7 +247,7 @@ source "drivers/char/hw_random/Kconfig"
 
 config NVRAM
tristate "/dev/nvram support"
-   depends on ATARI || X86 || (ARM && RTC_DRV_CMOS) || GENERIC_NVRAM
+   depends on X86 || (ARM && RTC_DRV_CMOS) || GENERIC_NVRAM
---help---
  If you say Y here and create a character special file /dev/nvram
  with major number 10 and minor number 144 using mknod ("man mknod"),
@@ -265,9 +265,6 @@ config NVRAM
  should NEVER idly tamper with it. See Ralf Brown's interrupt list
  for a guide to the use of CMOS bytes by your BIOS.
 
- On Atari machines, /dev/nvram is always configured and does not need
- to be selected.
-
  To compile this driver as a module, choose M here: the
  module will be called nvram.
 
Index: linux/drivers/scsi/Kconfig
===
--- linux.orig/drivers/scsi/Kconfig 2015-07-12 20:24:54.0 +1000
+++ linux/drivers/scsi/Kconfig  2015-07-12 20:24:54.0 +1000
@@ -1592,14 +1592,14 @@ config ATARI_SCSI
tristate "Atari native SCSI support"
depends on ATARI && SCSI
select SCSI_SPI_ATTRS
-   select NVRAM
---help---
  If you have an Atari with built-in NCR5380 SCSI controller (TT,
  Falcon, ...) say Y to get it supported. Of course also, if you have
  a compatible SCSI controller (e.g. for Medusa).
 
- To compile this driver as a module, choose M here: the
- module will be called atari_scsi.
+ To compile this driver as a module, choose M here: the module will
+ be called atari_scsi. If you also enable NVRAM support, the SCSI
+ host's ID is taken from the setting in TT RTC NVRAM.
 
  This driver supports both styles of NCR integration into the
  system: the TT style (separate DMA), and the Falcon style (via
Index: linux/drivers/scsi/atari_scsi.c
===
--- linux.orig/drivers/scsi/atari_scsi.c2015-07-12 20:24:54.0 
+1000
+++ linux/drivers/scsi/atari_scsi.c 2015-07-12 20:24:54.0 +1000
@@ -875,9 +875,10 @@ static int __init atari_scsi_probe(struc
if (ATARIHW_PRESENT(TT_SCSI) && setup_sg_tablesize >= 0)
atari_scsi_template.sg_tablesize = setup_sg_tablesize;
 
-   if (setup_hostid >= 0) {
+   if (setup_hostid >= 0)
atari_scsi_template.this_id = setup_hostid & 7;
-   } else {
+#ifdef CONFIG_NVRAM
+   else
/* Test if a host id is set in the NVRam */
if (ATARIHW_PRESENT(TT_CLK) && nvram_check_checksum()) {
unsigned char b = nvram_read_byte(14);
@@ -888,8 +889,7 @@ static int __init atari_scsi_probe(struc
if (b & 0x80)
atari_scsi_template.this_id = b & 7;
}
-   }
-
+#endif
 
 #ifdef REAL_DMA
/* If running on a Falcon and if there's TT-Ram (i.e., more than one


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[RFC v4 04/25] m68k/atari: Replace nvram_{read, write}_byte with arch_nvram_ops

2015-07-12 Thread Finn Thain
By implementing an arch_nvram_ops struct, any platform can re-use the
drivers/char/nvram module without needing any arch-specific code
in that module. Atari does so here.

Atari has one user of nvram_check_checksum() whereas the other platforms
(i.e. x86 and ARM platforms) have none at all. Replace this
validate-checksum-and-read-byte sequence with the equivalent
rtc_nvram_ops.read() call and remove the now unused functions.

Signed-off-by: Finn Thain 

---

The advantage of the new ops struct over the old global nvram_* functions
is that the misc device module can be shared by different platforms
without requiring every platform to implement every nvram_* function.
E.g. only RTC "CMOS" NVRAMs have a checksum for the entire NVRAM
and only PowerPC platforms have a "sync" ioctl.

---
 arch/m68k/atari/nvram.c   |   89 --
 drivers/scsi/atari_scsi.c |8 ++--
 include/linux/nvram.h |9 
 3 files changed, 70 insertions(+), 36 deletions(-)

Index: linux/arch/m68k/atari/nvram.c
===
--- linux.orig/arch/m68k/atari/nvram.c  2015-07-12 20:24:56.0 +1000
+++ linux/arch/m68k/atari/nvram.c   2015-07-12 20:24:58.0 +1000
@@ -38,33 +38,12 @@ unsigned char __nvram_read_byte(int i)
return CMOS_READ(NVRAM_FIRST_BYTE + i);
 }
 
-unsigned char nvram_read_byte(int i)
-{
-   unsigned long flags;
-   unsigned char c;
-
-   spin_lock_irqsave(&rtc_lock, flags);
-   c = __nvram_read_byte(i);
-   spin_unlock_irqrestore(&rtc_lock, flags);
-   return c;
-}
-EXPORT_SYMBOL(nvram_read_byte);
-
 /* This races nicely with trying to read with checksum checking */
 void __nvram_write_byte(unsigned char c, int i)
 {
CMOS_WRITE(c, NVRAM_FIRST_BYTE + i);
 }
 
-void nvram_write_byte(unsigned char c, int i)
-{
-   unsigned long flags;
-
-   spin_lock_irqsave(&rtc_lock, flags);
-   __nvram_write_byte(c, i);
-   spin_unlock_irqrestore(&rtc_lock, flags);
-}
-
 /* On Ataris, the checksum is over all bytes except the checksum bytes
  * themselves; these are at the very end.
  */
@@ -83,18 +62,6 @@ int __nvram_check_checksum(void)
   (__nvram_read_byte(ATARI_CKS_LOC + 1) == (sum & 0xff));
 }
 
-int nvram_check_checksum(void)
-{
-   unsigned long flags;
-   int rv;
-
-   spin_lock_irqsave(&rtc_lock, flags);
-   rv = __nvram_check_checksum();
-   spin_unlock_irqrestore(&rtc_lock, flags);
-   return rv;
-}
-EXPORT_SYMBOL(nvram_check_checksum);
-
 static void __nvram_set_checksum(void)
 {
int i;
@@ -106,6 +73,62 @@ static void __nvram_set_checksum(void)
__nvram_write_byte(sum, ATARI_CKS_LOC + 1);
 }
 
+static ssize_t nvram_read(char *buf, size_t count, loff_t *ppos)
+{
+   char *p = buf;
+   loff_t i;
+
+   spin_lock_irq(&rtc_lock);
+
+   if (!__nvram_check_checksum()) {
+   spin_unlock_irq(&rtc_lock);
+   return -EIO;
+   }
+
+   for (i = *ppos; count > 0 && i < NVRAM_BYTES; --count, ++i, ++p)
+   *p = __nvram_read_byte(i);
+
+   spin_unlock_irq(&rtc_lock);
+
+   *ppos = i;
+   return p - buf;
+}
+
+static ssize_t nvram_write(char *buf, size_t count, loff_t *ppos)
+{
+   char *p = buf;
+   loff_t i;
+
+   spin_lock_irq(&rtc_lock);
+
+   if (!__nvram_check_checksum()) {
+   spin_unlock_irq(&rtc_lock);
+   return -EIO;
+   }
+
+   for (i = *ppos; count > 0 && i < NVRAM_BYTES; --count, ++i, ++p)
+   __nvram_write_byte(*p, i);
+
+   __nvram_set_checksum();
+
+   spin_unlock_irq(&rtc_lock);
+
+   *ppos = i;
+   return p - buf;
+}
+
+static ssize_t nvram_get_size(void)
+{
+   return NVRAM_BYTES;
+}
+
+const struct nvram_ops arch_nvram_ops = {
+   .read   = nvram_read,
+   .write  = nvram_write,
+   .get_size   = nvram_get_size,
+};
+EXPORT_SYMBOL(arch_nvram_ops);
+
 #ifdef CONFIG_PROC_FS
 static struct {
unsigned char val;
Index: linux/drivers/scsi/atari_scsi.c
===
--- linux.orig/drivers/scsi/atari_scsi.c2015-07-12 20:24:54.0 
+1000
+++ linux/drivers/scsi/atari_scsi.c 2015-07-12 20:24:58.0 +1000
@@ -880,13 +880,15 @@ static int __init atari_scsi_probe(struc
 #ifdef CONFIG_NVRAM
else
/* Test if a host id is set in the NVRam */
-   if (ATARIHW_PRESENT(TT_CLK) && nvram_check_checksum()) {
-   unsigned char b = nvram_read_byte(14);
+   if (ATARIHW_PRESENT(TT_CLK)) {
+   unsigned char b;
+   loff_t offset = 14;
+   ssize_t count = arch_nvram_ops.read(&b, 1, &offset);
 

[RFC v4 02/25] char/nvram: Use bitwise OR to obtain Atari video mode data

2015-07-12 Thread Finn Thain
Signed-off-by: Finn Thain 
Acked-by: Geert Uytterhoeven 

---
 drivers/char/nvram.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Index: linux/drivers/char/nvram.c
===
--- linux.orig/drivers/char/nvram.c 2015-07-12 20:24:54.0 +1000
+++ linux/drivers/char/nvram.c  2015-07-12 20:24:55.0 +1000
@@ -702,7 +702,7 @@ static void atari_proc_infos(unsigned ch
seq_printf(seq, "%ds%s\n", nvram[10],
nvram[10] < 8 ? ", no memory test" : "");
 
-   vmode = (nvram[14] << 8) || nvram[15];
+   vmode = (nvram[14] << 8) | nvram[15];
seq_printf(seq,
"Video mode   : %s colors, %d columns, %s %s monitor\n",
colors[vmode & 7],


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[RFC v4 03/25] m68k/atari: Move Atari-specific code out of drivers/char/nvram.c

2015-07-12 Thread Finn Thain
Move the m68k-specific code elsewhere to make the driver generic.

Signed-off-by: Finn Thain 

---

BTW, I didn't change the SCSI ID location in NVRAM. This code says 16
whereas atari_scsi says 14. Which one is correct?

Changes since v3:
- Move the vmode fix to a separate patch as requested by Geert.

---
 arch/m68k/atari/Makefile |2 
 arch/m68k/atari/nvram.c  |  255 ++
 drivers/char/nvram.c |  280 +--
 3 files changed, 292 insertions(+), 245 deletions(-)

Index: linux/arch/m68k/atari/nvram.c
===
--- /dev/null   1970-01-01 00:00:00.0 +
+++ linux/arch/m68k/atari/nvram.c   2015-07-12 20:24:56.0 +1000
@@ -0,0 +1,255 @@
+/*
+ * CMOS/NV-RAM driver for Atari. Adapted from drivers/char/nvram.c.
+ * Copyright (C) 1997 Roman Hodek 
+ * idea by and with help from Richard Jelinek 
+ * Portions copyright (c) 2001,2002 Sun Microsystems (thoc...@sun.com)
+ * Further contributions from Cesar Barros, Erik Gilling, Tim Hockin and
+ * Wim Van Sebroeck.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define NVRAM_BYTES50
+
+/* It is worth noting that these functions all access bytes of general
+ * purpose memory in the NVRAM - that is to say, they all add the
+ * NVRAM_FIRST_BYTE offset. Pass them offsets into NVRAM as if you did not
+ * know about the RTC cruft.
+ */
+
+/* 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
+ * don't want two different things trying to get to it at once. (e.g. the
+ * periodic 11 min sync from kernel/time/ntp.c vs. this driver.)
+ */
+
+unsigned char __nvram_read_byte(int i)
+{
+   return CMOS_READ(NVRAM_FIRST_BYTE + i);
+}
+
+unsigned char nvram_read_byte(int i)
+{
+   unsigned long flags;
+   unsigned char c;
+
+   spin_lock_irqsave(&rtc_lock, flags);
+   c = __nvram_read_byte(i);
+   spin_unlock_irqrestore(&rtc_lock, flags);
+   return c;
+}
+EXPORT_SYMBOL(nvram_read_byte);
+
+/* This races nicely with trying to read with checksum checking */
+void __nvram_write_byte(unsigned char c, int i)
+{
+   CMOS_WRITE(c, NVRAM_FIRST_BYTE + i);
+}
+
+void nvram_write_byte(unsigned char c, int i)
+{
+   unsigned long flags;
+
+   spin_lock_irqsave(&rtc_lock, flags);
+   __nvram_write_byte(c, i);
+   spin_unlock_irqrestore(&rtc_lock, flags);
+}
+
+/* On Ataris, the checksum is over all bytes except the checksum bytes
+ * themselves; these are at the very end.
+ */
+#define ATARI_CKS_RANGE_START  0
+#define ATARI_CKS_RANGE_END47
+#define ATARI_CKS_LOC  48
+
+int __nvram_check_checksum(void)
+{
+   int i;
+   unsigned char sum = 0;
+
+   for (i = ATARI_CKS_RANGE_START; i <= ATARI_CKS_RANGE_END; ++i)
+   sum += __nvram_read_byte(i);
+   return (__nvram_read_byte(ATARI_CKS_LOC) == (~sum & 0xff)) &&
+  (__nvram_read_byte(ATARI_CKS_LOC + 1) == (sum & 0xff));
+}
+
+int nvram_check_checksum(void)
+{
+   unsigned long flags;
+   int rv;
+
+   spin_lock_irqsave(&rtc_lock, flags);
+   rv = __nvram_check_checksum();
+   spin_unlock_irqrestore(&rtc_lock, flags);
+   return rv;
+}
+EXPORT_SYMBOL(nvram_check_checksum);
+
+static void __nvram_set_checksum(void)
+{
+   int i;
+   unsigned char sum = 0;
+
+   for (i = ATARI_CKS_RANGE_START; i <= ATARI_CKS_RANGE_END; ++i)
+   sum += __nvram_read_byte(i);
+   __nvram_write_byte(~sum, ATARI_CKS_LOC);
+   __nvram_write_byte(sum, ATARI_CKS_LOC + 1);
+}
+
+#ifdef CONFIG_PROC_FS
+static struct {
+   unsigned char val;
+   char *name;
+} boot_prefs[] = {
+   { 0x80, "TOS" },
+   { 0x40, "ASV" },
+   { 0x20, "NetBSD (?)" },
+   { 0x10, "Linux" },
+   { 0x00, "unspecified" },
+};
+
+static char *languages[] = {
+   "English (US)",
+   "German",
+   "French",
+   "English (UK)",
+   "Spanish",
+   "Italian",
+   "6 (undefined)",
+   "Swiss (French)",
+   "Swiss (German)",
+};
+
+static char *dateformat[] = {
+   "MM%cDD%cYY",
+   "DD%cMM%cYY",
+   "YY%cMM%cDD",
+   "YY%cDD%cMM",
+   "4 (undefined)",
+   "5 (undefined)",
+   "6 (undefined)",
+   "7 (undefined)",
+};
+
+static char *colors[] = {
+   "2", "4", "16", "256", "65536", "??", "??", "??"
+};
+
+static void atari_nvram_proc_read(unsigned char *nvram, struct s

[RFC v4 06/25] char/nvram: Adopt arch_nvram_ops

2015-07-12 Thread Finn Thain
Different platforms and architectures offer different NVRAM sizes and
access methods. E.g. PPC32 has byte-at-a-time read/write functions whereas
PPC64 has byte-range read/write functions. Adopt the nvram_ops struct so
the nvram module can call such functions as are defined by the various 
platforms and architectures.

Signed-off-by: Finn Thain 

---

The #ifdefs here restrict the procfs and checksumming code to those
architectures with PC-style RTC NVRAM. There may be a better place for
that code but it's an open question. See https://lkml.org/lkml/2015/2/3/22

The procfs code here, unless relevant to an ARM platform, could be moved to
arch/x86 (like the earlier patch does for m68k code) and the nvram ops
could be implemented and exported by the rtc-cmos driver instead. This
would eliminate these #ifdefs and almost eliminate the arch-specific code.

---
 drivers/char/nvram.c  |   30 +++---
 include/linux/nvram.h |2 ++
 2 files changed, 29 insertions(+), 3 deletions(-)

Index: linux/drivers/char/nvram.c
===
--- linux.orig/drivers/char/nvram.c 2015-07-12 20:24:59.0 +1000
+++ linux/drivers/char/nvram.c  2015-07-12 20:25:00.0 +1000
@@ -51,9 +51,12 @@ static DEFINE_MUTEX(nvram_mutex);
 static DEFINE_SPINLOCK(nvram_state_lock);
 static int nvram_open_cnt; /* #times opened */
 static int nvram_open_mode;/* special open modes */
+static ssize_t nvram_size;
 #define NVRAM_WRITE1 /* opened for writing (exclusive) */
 #define NVRAM_EXCL 2 /* opened with O_EXCL */
 
+#if defined(CONFIG_X86) || defined(CONFIG_ARM)
+
 /*
  * These functions are provided to be called internally or by other parts of
  * the kernel. It's up to the caller to ensure correct checksum before reading
@@ -161,6 +164,20 @@ void nvram_set_checksum(void)
 }
 #endif  /*  0  */
 
+static ssize_t nvram_get_size(void)
+{
+   return NVRAM_BYTES;
+}
+
+const struct nvram_ops arch_nvram_ops = {
+   .read_byte  = nvram_read_byte,
+   .write_byte = nvram_write_byte,
+   .get_size   = nvram_get_size,
+};
+EXPORT_SYMBOL(arch_nvram_ops);
+
+#endif /* CONFIG_X86 || CONFIG_ARM */
+
 /*
  * The are the file operation function for user access to /dev/nvram
  */
@@ -332,7 +349,7 @@ static int nvram_misc_release(struct ino
return 0;
 }
 
-#ifdef CONFIG_PROC_FS
+#if defined(CONFIG_PROC_FS) && (defined(CONFIG_X86) || defined(CONFIG_ARM))
 
 static char *floppy_types[] = {
"none", "5.25'' 360k", "5.25'' 1.2M", "3.5'' 720k", "3.5'' 1.44M",
@@ -459,13 +476,20 @@ static int __init nvram_module_init(void
 {
int ret;
 
+   if (arch_nvram_ops.get_size == NULL)
+   return -ENODEV;
+
+   nvram_size = arch_nvram_ops.get_size();
+   if (nvram_size < 0)
+   return nvram_size;
+
ret = misc_register(&nvram_misc);
if (ret) {
pr_err("nvram: can't misc_register on minor=%d\n", NVRAM_MINOR);
return ret;
}
 
-#ifdef CONFIG_PROC_FS
+#if defined(CONFIG_PROC_FS) && (defined(CONFIG_X86) || defined(CONFIG_ARM))
if (!proc_create("driver/nvram", 0, NULL, &nvram_proc_fops)) {
pr_err("nvram: can't create /proc/driver/nvram\n");
misc_deregister(&nvram_misc);
@@ -479,7 +503,7 @@ static int __init nvram_module_init(void
 
 static void __exit nvram_module_exit(void)
 {
-#ifdef CONFIG_PROC_FS
+#if defined(CONFIG_PROC_FS) && (defined(CONFIG_X86) || defined(CONFIG_ARM))
remove_proc_entry("driver/nvram", NULL);
 #endif
misc_deregister(&nvram_misc);
Index: linux/include/linux/nvram.h
===
--- linux.orig/include/linux/nvram.h2015-07-12 20:24:58.0 +1000
+++ linux/include/linux/nvram.h 2015-07-12 20:25:00.0 +1000
@@ -14,6 +14,8 @@ extern int nvram_check_checksum(void);
 struct nvram_ops {
ssize_t (*read)(char *, size_t, loff_t *);
ssize_t (*write)(char *, size_t, loff_t *);
+   unsigned char   (*read_byte)(int);
+   void(*write_byte)(unsigned char, int);
ssize_t (*get_size)(void);
 };
 


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[RFC v4 10/25] char/nvram: Use generic fixed_size_llseek()

2015-07-12 Thread Finn Thain
Signed-off-by: Finn Thain 

---
 drivers/char/nvram.c |   16 +---
 1 file changed, 1 insertion(+), 15 deletions(-)

Index: linux/drivers/char/nvram.c
===
--- linux.orig/drivers/char/nvram.c 2015-07-12 20:25:03.0 +1000
+++ linux/drivers/char/nvram.c  2015-07-12 20:25:05.0 +1000
@@ -235,21 +235,7 @@ EXPORT_SYMBOL(arch_nvram_ops);
 
 static loff_t nvram_misc_llseek(struct file *file, loff_t offset, int origin)
 {
-   switch (origin) {
-   case 0:
-   /* nothing to do */
-   break;
-   case 1:
-   offset += file->f_pos;
-   break;
-   case 2:
-   offset += NVRAM_BYTES;
-   break;
-   default:
-   return -EINVAL;
-   }
-
-   return (offset >= 0) ? (file->f_pos = offset) : -EINVAL;
+   return fixed_size_llseek(file, offset, origin, nvram_size);
 }
 
 static ssize_t nvram_misc_read(struct file *file, char __user *buf,


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[RFC v4 11/25] m68k/atari: Implement arch_nvram_ops methods and enable CONFIG_HAVE_ARCH_NVRAM_OPS

2015-07-12 Thread Finn Thain
Atari RTC NVRAM has a checksum so implement the remaining arch_nvram_ops
methods for the set_checksum and initialize ioctls. Enable
CONFIG_HAVE_ARCH_NVRAM_OPS.

Signed-off-by: Finn Thain 

---

This re-enables the nvram module for Atari.

Changes since v3:
- Use bool (and select) instead of def_bool in the definition of the
HAVE_ARCH_NVRAM_OPS Kconfig symbol, as requested by Geert.

---
 arch/m68k/Kconfig |3 +++
 arch/m68k/Kconfig.machine |1 +
 arch/m68k/atari/nvram.c   |   24 
 drivers/char/Kconfig  |2 +-
 4 files changed, 29 insertions(+), 1 deletion(-)

Index: linux/arch/m68k/atari/nvram.c
===
--- linux.orig/arch/m68k/atari/nvram.c  2015-07-12 20:24:58.0 +1000
+++ linux/arch/m68k/atari/nvram.c   2015-07-12 20:25:05.0 +1000
@@ -73,6 +73,26 @@ static void __nvram_set_checksum(void)
__nvram_write_byte(sum, ATARI_CKS_LOC + 1);
 }
 
+static long nvram_set_checksum(void)
+{
+   spin_lock_irq(&rtc_lock);
+   __nvram_set_checksum();
+   spin_unlock_irq(&rtc_lock);
+   return 0;
+}
+
+static long nvram_initialize(void)
+{
+   loff_t i;
+
+   spin_lock_irq(&rtc_lock);
+   for (i = 0; i < NVRAM_BYTES; ++i)
+   __nvram_write_byte(0, i);
+   __nvram_set_checksum();
+   spin_unlock_irq(&rtc_lock);
+   return 0;
+}
+
 static ssize_t nvram_read(char *buf, size_t count, loff_t *ppos)
 {
char *p = buf;
@@ -119,6 +139,8 @@ static ssize_t nvram_write(char *buf, si
 
 static ssize_t nvram_get_size(void)
 {
+   if (!MACH_IS_ATARI)
+   return -ENODEV;
return NVRAM_BYTES;
 }
 
@@ -126,6 +148,8 @@ const struct nvram_ops arch_nvram_ops =
.read   = nvram_read,
.write  = nvram_write,
.get_size   = nvram_get_size,
+   .set_checksum   = nvram_set_checksum,
+   .initialize = nvram_initialize,
 };
 EXPORT_SYMBOL(arch_nvram_ops);
 
Index: linux/drivers/char/Kconfig
===
--- linux.orig/drivers/char/Kconfig 2015-07-12 20:24:54.0 +1000
+++ linux/drivers/char/Kconfig  2015-07-12 20:25:05.0 +1000
@@ -247,7 +247,7 @@ source "drivers/char/hw_random/Kconfig"
 
 config NVRAM
tristate "/dev/nvram support"
-   depends on X86 || (ARM && RTC_DRV_CMOS) || GENERIC_NVRAM
+   depends on X86 || (ARM && RTC_DRV_CMOS) || GENERIC_NVRAM || 
HAVE_ARCH_NVRAM_OPS
---help---
  If you say Y here and create a character special file /dev/nvram
  with major number 10 and minor number 144 using mknod ("man mknod"),
Index: linux/arch/m68k/Kconfig
===
--- linux.orig/arch/m68k/Kconfig2015-07-12 20:24:53.0 +1000
+++ linux/arch/m68k/Kconfig 2015-07-12 20:25:05.0 +1000
@@ -71,6 +71,9 @@ config PGTABLE_LEVELS
default 2 if SUN3 || COLDFIRE
default 3
 
+config HAVE_ARCH_NVRAM_OPS
+   bool
+
 source "init/Kconfig"
 
 source "kernel/Kconfig.freezer"
Index: linux/arch/m68k/Kconfig.machine
===
--- linux.orig/arch/m68k/Kconfig.machine2015-07-12 20:24:53.0 
+1000
+++ linux/arch/m68k/Kconfig.machine 2015-07-12 20:25:05.0 +1000
@@ -15,6 +15,7 @@ config ATARI
bool "Atari support"
depends on MMU
select MMU_MOTOROLA if MMU
+   select HAVE_ARCH_NVRAM_OPS
help
  This option enables support for the 68000-based Atari series of
  computers (including the TT, Falcon and Medusa). If you plan to use


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[RFC v4 12/25] char/nvram: Add "devname:nvram" module alias

2015-07-12 Thread Finn Thain
Signed-off-by: Finn Thain 

---
 drivers/char/nvram.c |1 +
 1 file changed, 1 insertion(+)

Index: linux/drivers/char/nvram.c
===
--- linux.orig/drivers/char/nvram.c 2015-07-12 20:25:05.0 +1000
+++ linux/drivers/char/nvram.c  2015-07-12 20:25:07.0 +1000
@@ -577,3 +577,4 @@ module_exit(nvram_module_exit);
 
 MODULE_LICENSE("GPL");
 MODULE_ALIAS_MISCDEV(NVRAM_MINOR);
+MODULE_ALIAS("devname:nvram");


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[RFC v4 07/25] x86/thinkpad_acpi: Use arch_nvram_ops methods instead of nvram_read_byte() and nvram_write_byte()

2015-07-12 Thread Finn Thain
Make use of arch_nvram_ops in the thinkpad_acpi driver so that the
nvram_* function exports can be removed.

This patch series was tested on a ThinkPad T43.

Signed-off-by: Finn Thain 
Acked-by: Henrique de Moraes Holschuh 
Reviewed-by: Darren Hart 

---
 drivers/platform/x86/thinkpad_acpi.c |   20 ++--
 1 file changed, 10 insertions(+), 10 deletions(-)

Index: linux/drivers/platform/x86/thinkpad_acpi.c
===
--- linux.orig/drivers/platform/x86/thinkpad_acpi.c 2015-07-12 
20:24:53.0 +1000
+++ linux/drivers/platform/x86/thinkpad_acpi.c  2015-07-12 20:25:01.0 
+1000
@@ -2311,30 +2311,30 @@ static void hotkey_read_nvram(struct tp_
u8 d;
 
if (m & TP_NVRAM_HKEY_GROUP_HK2) {
-   d = nvram_read_byte(TP_NVRAM_ADDR_HK2);
+   d = arch_nvram_ops.read_byte(TP_NVRAM_ADDR_HK2);
n->thinkpad_toggle = !!(d & TP_NVRAM_MASK_HKT_THINKPAD);
n->zoom_toggle = !!(d & TP_NVRAM_MASK_HKT_ZOOM);
n->display_toggle = !!(d & TP_NVRAM_MASK_HKT_DISPLAY);
n->hibernate_toggle = !!(d & TP_NVRAM_MASK_HKT_HIBERNATE);
}
if (m & TP_ACPI_HKEY_THNKLGHT_MASK) {
-   d = nvram_read_byte(TP_NVRAM_ADDR_THINKLIGHT);
+   d = arch_nvram_ops.read_byte(TP_NVRAM_ADDR_THINKLIGHT);
n->thinklight_toggle = !!(d & TP_NVRAM_MASK_THINKLIGHT);
}
if (m & TP_ACPI_HKEY_DISPXPAND_MASK) {
-   d = nvram_read_byte(TP_NVRAM_ADDR_VIDEO);
+   d = arch_nvram_ops.read_byte(TP_NVRAM_ADDR_VIDEO);
n->displayexp_toggle =
!!(d & TP_NVRAM_MASK_HKT_DISPEXPND);
}
if (m & TP_NVRAM_HKEY_GROUP_BRIGHTNESS) {
-   d = nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS);
+   d = arch_nvram_ops.read_byte(TP_NVRAM_ADDR_BRIGHTNESS);
n->brightness_level = (d & TP_NVRAM_MASK_LEVEL_BRIGHTNESS)
>> TP_NVRAM_POS_LEVEL_BRIGHTNESS;
n->brightness_toggle =
!!(d & TP_NVRAM_MASK_HKT_BRIGHTNESS);
}
if (m & TP_NVRAM_HKEY_GROUP_VOLUME) {
-   d = nvram_read_byte(TP_NVRAM_ADDR_MIXER);
+   d = arch_nvram_ops.read_byte(TP_NVRAM_ADDR_MIXER);
n->volume_level = (d & TP_NVRAM_MASK_LEVEL_VOLUME)
>> TP_NVRAM_POS_LEVEL_VOLUME;
n->mute = !!(d & TP_NVRAM_MASK_MUTE);
@@ -6155,7 +6155,7 @@ static unsigned int tpacpi_brightness_nv
 {
u8 lnvram;
 
-   lnvram = (nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS)
+   lnvram = (arch_nvram_ops.read_byte(TP_NVRAM_ADDR_BRIGHTNESS)
  & TP_NVRAM_MASK_LEVEL_BRIGHTNESS)
  >> TP_NVRAM_POS_LEVEL_BRIGHTNESS;
lnvram &= bright_maxlvl;
@@ -6180,7 +6180,7 @@ static void tpacpi_brightness_checkpoint
if (unlikely(!acpi_ec_read(TP_EC_BACKLIGHT, &lec)))
goto unlock;
lec &= TP_EC_BACKLIGHT_LVLMSK;
-   b_nvram = nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS);
+   b_nvram = arch_nvram_ops.read_byte(TP_NVRAM_ADDR_BRIGHTNESS);
 
if (lec != ((b_nvram & TP_NVRAM_MASK_LEVEL_BRIGHTNESS)
 >> TP_NVRAM_POS_LEVEL_BRIGHTNESS)) {
@@ -6188,7 +6188,7 @@ static void tpacpi_brightness_checkpoint
b_nvram &= ~(TP_NVRAM_MASK_LEVEL_BRIGHTNESS <<
TP_NVRAM_POS_LEVEL_BRIGHTNESS);
b_nvram |= lec;
-   nvram_write_byte(b_nvram, TP_NVRAM_ADDR_BRIGHTNESS);
+   arch_nvram_ops.write_byte(b_nvram, TP_NVRAM_ADDR_BRIGHTNESS);
dbg_printk(TPACPI_DBG_BRGHT,
   "updated NVRAM backlight level to %u (0x%02x)\n",
   (unsigned int) lec, (unsigned int) b_nvram);
@@ -6796,13 +6796,13 @@ static void tpacpi_volume_checkpoint_nvr
if (unlikely(!acpi_ec_read(TP_EC_AUDIO, &lec)))
goto unlock;
lec &= ec_mask;
-   b_nvram = nvram_read_byte(TP_NVRAM_ADDR_MIXER);
+   b_nvram = arch_nvram_ops.read_byte(TP_NVRAM_ADDR_MIXER);
 
if (lec != (b_nvram & ec_mask)) {
/* NVRAM needs update */
b_nvram &= ~ec_mask;
b_nvram |= lec;
-   nvram_write_byte(b_nvram, TP_NVRAM_ADDR_MIXER);
+   arch_nvram_ops.write_byte(b_nvram, TP_NVRAM_ADDR_MIXER);
dbg_printk(TPACPI_DBG_MIXER,
   "updated NVRAM mixer status to 0x%02x (0x%02x)\n",
   (unsigned int) lec, (unsigned int) b_nvram);


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[RFC v4 08/25] char/nvram: Allow the set_checksum and initialize ioctls to be omitted

2015-07-12 Thread Finn Thain
The drivers/char/nvram module has previously only supported RTC "CMOS"
NVRAM, for which it provides appropriate checksum ioctls. Make these
ioctls optional so the module can be re-used with other kinds of NVRAM.

The ops struct methods that implement the ioctls now return error
codes so that a multi-platform kernel binary can do the right thing when
running on hardware without suitable NVRAM.

Signed-off-by: Finn Thain 

---

Changed since v1:
- Don't bother acquiring the mutex for unimplemented ioctls.

---
 drivers/char/nvram.c  |   71 --
 include/linux/nvram.h |2 +
 2 files changed, 43 insertions(+), 30 deletions(-)

Index: linux/drivers/char/nvram.c
===
--- linux.orig/drivers/char/nvram.c 2015-07-12 20:25:00.0 +1000
+++ linux/drivers/char/nvram.c  2015-07-12 20:25:02.0 +1000
@@ -153,16 +153,25 @@ static void __nvram_set_checksum(void)
__nvram_write_byte(sum & 0xff, PC_CKS_LOC + 1);
 }
 
-#if 0
-void nvram_set_checksum(void)
+static long nvram_set_checksum(void)
 {
-   unsigned long flags;
+   spin_lock_irq(&rtc_lock);
+   __nvram_set_checksum();
+   spin_unlock_irq(&rtc_lock);
+   return 0;
+}
+
+static long nvram_initialize(void)
+{
+   ssize_t i;
 
-   spin_lock_irqsave(&rtc_lock, flags);
+   spin_lock_irq(&rtc_lock);
+   for (i = 0; i < NVRAM_BYTES; ++i)
+   __nvram_write_byte(0, i);
__nvram_set_checksum();
-   spin_unlock_irqrestore(&rtc_lock, flags);
+   spin_unlock_irq(&rtc_lock);
+   return 0;
 }
-#endif  /*  0  */
 
 static ssize_t nvram_get_size(void)
 {
@@ -173,6 +182,8 @@ const struct nvram_ops arch_nvram_ops =
.read_byte  = nvram_read_byte,
.write_byte = nvram_write_byte,
.get_size   = nvram_get_size,
+   .set_checksum   = nvram_set_checksum,
+   .initialize = nvram_initialize,
 };
 EXPORT_SYMBOL(arch_nvram_ops);
 
@@ -272,51 +283,51 @@ checksum_err:
 static long nvram_misc_ioctl(struct file *file, unsigned int cmd,
  unsigned long arg)
 {
-   int i;
+   long ret = -ENOTTY;
 
switch (cmd) {
-
case NVRAM_INIT:
/* initialize NVRAM contents and checksum */
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
 
-   mutex_lock(&nvram_mutex);
-   spin_lock_irq(&rtc_lock);
-
-   for (i = 0; i < NVRAM_BYTES; ++i)
-   __nvram_write_byte(0, i);
-   __nvram_set_checksum();
-
-   spin_unlock_irq(&rtc_lock);
-   mutex_unlock(&nvram_mutex);
-   return 0;
-
+   if (arch_nvram_ops.initialize != NULL) {
+   mutex_lock(&nvram_mutex);
+   ret = arch_nvram_ops.initialize();
+   mutex_unlock(&nvram_mutex);
+   }
+   break;
case NVRAM_SETCKS:
/* just set checksum, contents unchanged (maybe useful after
 * checksum garbaged somehow...) */
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
 
-   mutex_lock(&nvram_mutex);
-   spin_lock_irq(&rtc_lock);
-   __nvram_set_checksum();
-   spin_unlock_irq(&rtc_lock);
-   mutex_unlock(&nvram_mutex);
-   return 0;
-
-   default:
-   return -ENOTTY;
+   if (arch_nvram_ops.set_checksum != NULL) {
+   mutex_lock(&nvram_mutex);
+   ret = arch_nvram_ops.set_checksum();
+   mutex_unlock(&nvram_mutex);
+   }
+   break;
}
+   return ret;
 }
 
 static int nvram_misc_open(struct inode *inode, struct file *file)
 {
spin_lock(&nvram_state_lock);
 
+   /* Prevent multiple readers/writers if desired. */
if ((nvram_open_cnt && (file->f_flags & O_EXCL)) ||
-   (nvram_open_mode & NVRAM_EXCL) ||
-   ((file->f_mode & FMODE_WRITE) && (nvram_open_mode & NVRAM_WRITE))) {
+   (nvram_open_mode & NVRAM_EXCL)) {
+   spin_unlock(&nvram_state_lock);
+   return -EBUSY;
+   }
+
+   /* Prevent multiple writers if the set_checksum ioctl is implemented. */
+   if ((arch_nvram_ops.set_checksum != NULL) &&
+   (file->f_mode & FMODE_WRITE) &&
+   (nvram_open_mode & NVRAM_WRITE)) {
spin_unlock(&nvram_state_lock);
return -EBUSY;
}
Index: linux/include/linux/nvram.h
===
--- linux.orig/include/linux/nvram.h201

[RFC v4 13/25] powerpc: Cleanup nvram includes

2015-07-12 Thread Finn Thain
The nvram_read_byte() and nvram_write_byte() definitions in asm/nvram.h
duplicate those in linux/nvram.h. Get rid of the former to prepare for
adoption of struct arch_nvram_ops (which is defined in linux/nvram.h for
general use).

Signed-off-by: Finn Thain 

---
 arch/powerpc/include/asm/nvram.h   |3 ---
 arch/powerpc/kernel/setup_32.c |1 +
 drivers/char/generic_nvram.c   |4 +++-
 drivers/video/fbdev/matrox/matroxfb_base.c |2 +-
 4 files changed, 5 insertions(+), 5 deletions(-)

Index: linux/arch/powerpc/include/asm/nvram.h
===
--- linux.orig/arch/powerpc/include/asm/nvram.h 2015-07-12 20:24:53.0 
+1000
+++ linux/arch/powerpc/include/asm/nvram.h  2015-07-12 20:25:08.0 
+1000
@@ -101,7 +101,4 @@ extern int nvram_write_os_partition(stru
 /* Determine NVRAM size */
 extern ssize_t nvram_get_size(void);
 
-/* Normal access to NVRAM */
-extern unsigned char nvram_read_byte(int i);
-extern void nvram_write_byte(unsigned char c, int i);
 #endif /* _ASM_POWERPC_NVRAM_H */
Index: linux/arch/powerpc/kernel/setup_32.c
===
--- linux.orig/arch/powerpc/kernel/setup_32.c   2015-07-12 20:24:53.0 
+1000
+++ linux/arch/powerpc/kernel/setup_32.c2015-07-12 20:25:08.0 
+1000
@@ -16,6 +16,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
Index: linux/drivers/char/generic_nvram.c
===
--- linux.orig/drivers/char/generic_nvram.c 2015-07-12 20:24:53.0 
+1000
+++ linux/drivers/char/generic_nvram.c  2015-07-12 20:25:08.0 +1000
@@ -20,9 +20,11 @@
 #include 
 #include 
 #include 
+#include 
 #include 
-#include 
+
 #ifdef CONFIG_PPC_PMAC
+#include 
 #include 
 #endif
 
Index: linux/drivers/video/fbdev/matrox/matroxfb_base.c
===
--- linux.orig/drivers/video/fbdev/matrox/matroxfb_base.c   2015-07-12 
20:24:53.0 +1000
+++ linux/drivers/video/fbdev/matrox/matroxfb_base.c2015-07-12 
20:25:08.0 +1000
@@ -111,12 +111,12 @@
 #include "matroxfb_g450.h"
 #include 
 #include 
+#include 
 #include 
 #include 
 
 #ifdef CONFIG_PPC_PMAC
 #include 
-unsigned char nvram_read_byte(int);
 static int default_vmode = VMODE_NVRAM;
 static int default_cmode = CMODE_NVRAM;
 #endif


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[RFC v4 14/25] powerpc: Add missing ppc_md.nvram_size for CHRP and PowerMac

2015-07-12 Thread Finn Thain
Add the nvram_size() function to those PowerPC platforms that don't already
have one: CHRP and PowerMac. This means that the ppc_md.nvram_size()
function can be used to implement arch_nvram_ops.get_size()

Since we are addressing inconsistencies here, also rename chrp_nvram_read
and chrp_nvram_write, which break the naming convention used across
PowerPC platforms for NVRAM accessor functions.

Signed-off-by: Finn Thain 

---
 arch/powerpc/platforms/chrp/nvram.c |   14 ++
 arch/powerpc/platforms/powermac/nvram.c |9 +
 2 files changed, 19 insertions(+), 4 deletions(-)

Index: linux/arch/powerpc/platforms/chrp/nvram.c
===
--- linux.orig/arch/powerpc/platforms/chrp/nvram.c  2015-07-12 
20:24:53.0 +1000
+++ linux/arch/powerpc/platforms/chrp/nvram.c   2015-07-12 20:25:09.0 
+1000
@@ -23,7 +23,7 @@ static unsigned int nvram_size;
 static unsigned char nvram_buf[4];
 static DEFINE_SPINLOCK(nvram_lock);
 
-static unsigned char chrp_nvram_read(int addr)
+static unsigned char chrp_nvram_read_byte(int addr)
 {
unsigned int done;
unsigned long flags;
@@ -45,7 +45,7 @@ static unsigned char chrp_nvram_read(int
return ret;
 }
 
-static void chrp_nvram_write(int addr, unsigned char val)
+static void chrp_nvram_write_byte(int addr, unsigned char val)
 {
unsigned int done;
unsigned long flags;
@@ -63,6 +63,11 @@ static void chrp_nvram_write(int addr, u
spin_unlock_irqrestore(&nvram_lock, flags);
 }
 
+static ssize_t chrp_nvram_size(void)
+{
+   return nvram_size;
+}
+
 void __init chrp_nvram_init(void)
 {
struct device_node *nvram;
@@ -84,8 +89,9 @@ void __init chrp_nvram_init(void)
printk(KERN_INFO "CHRP nvram contains %u bytes\n", nvram_size);
of_node_put(nvram);
 
-   ppc_md.nvram_read_val = chrp_nvram_read;
-   ppc_md.nvram_write_val = chrp_nvram_write;
+   ppc_md.nvram_read_val  = chrp_nvram_read_byte;
+   ppc_md.nvram_write_val = chrp_nvram_write_byte;
+   ppc_md.nvram_size  = chrp_nvram_size;
 
return;
 }
Index: linux/arch/powerpc/platforms/powermac/nvram.c
===
--- linux.orig/arch/powerpc/platforms/powermac/nvram.c  2015-07-12 
20:24:53.0 +1000
+++ linux/arch/powerpc/platforms/powermac/nvram.c   2015-07-12 
20:25:09.0 +1000
@@ -147,6 +147,11 @@ static ssize_t core99_nvram_size(void)
 static volatile unsigned char __iomem *nvram_addr;
 static int nvram_mult;
 
+static ssize_t ppc32_nvram_size(void)
+{
+   return NVRAM_SIZE;
+}
+
 static unsigned char direct_nvram_read_byte(int addr)
 {
return in_8(&nvram_data[(addr & (NVRAM_SIZE - 1)) * nvram_mult]);
@@ -590,21 +595,25 @@ int __init pmac_nvram_init(void)
nvram_mult = 1;
ppc_md.nvram_read_val   = direct_nvram_read_byte;
ppc_md.nvram_write_val  = direct_nvram_write_byte;
+   ppc_md.nvram_size   = ppc32_nvram_size;
} else if (nvram_naddrs == 1) {
nvram_data = ioremap(r1.start, s1);
nvram_mult = (s1 + NVRAM_SIZE - 1) / NVRAM_SIZE;
ppc_md.nvram_read_val   = direct_nvram_read_byte;
ppc_md.nvram_write_val  = direct_nvram_write_byte;
+   ppc_md.nvram_size   = ppc32_nvram_size;
} else if (nvram_naddrs == 2) {
nvram_addr = ioremap(r1.start, s1);
nvram_data = ioremap(r2.start, s2);
ppc_md.nvram_read_val   = indirect_nvram_read_byte;
ppc_md.nvram_write_val  = indirect_nvram_write_byte;
+   ppc_md.nvram_size   = ppc32_nvram_size;
} else if (nvram_naddrs == 0 && sys_ctrler == SYS_CTRLER_PMU) {
 #ifdef CONFIG_ADB_PMU
nvram_naddrs = -1;
ppc_md.nvram_read_val   = pmu_nvram_read_byte;
ppc_md.nvram_write_val  = pmu_nvram_write_byte;
+   ppc_md.nvram_size   = ppc32_nvram_size;
 #endif /* CONFIG_ADB_PMU */
} else {
printk(KERN_ERR "Incompatible type of NVRAM\n");


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[RFC v4 09/25] char/nvram: Implement NVRAM read/write methods

2015-07-12 Thread Finn Thain
Refactor the RTC "CMOS" NVRAM functions so that they can be used as
arch_nvram_ops methods. Checksumming logic is moved from the misc device
operations to the nvram read/write operations.

This makes the misc device implementation more generic. This also
preserves the locking semantics such that "read if checksum valid" and
"write and update checksum" remain atomic operations.

PPC64 implements byte-range read/write methods which are similar to
file_operations struct methods. Other platforms provide only
byte-at-a-time functions. So the misc device prefers the former but
will fall back on the latter.

Signed-off-by: Finn Thain 

---
 drivers/char/nvram.c |  162 +++
 1 file changed, 114 insertions(+), 48 deletions(-)

Index: linux/drivers/char/nvram.c
===
--- linux.orig/drivers/char/nvram.c 2015-07-12 20:25:02.0 +1000
+++ linux/drivers/char/nvram.c  2015-07-12 20:25:03.0 +1000
@@ -41,6 +41,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -178,9 +179,48 @@ static ssize_t nvram_get_size(void)
return NVRAM_BYTES;
 }
 
+static ssize_t nvram_read(char *buf, size_t count, loff_t *ppos)
+{
+   char *p = buf;
+   loff_t i;
+
+   spin_lock_irq(&rtc_lock);
+   if (!__nvram_check_checksum()) {
+   spin_unlock_irq(&rtc_lock);
+   return -EIO;
+   }
+   for (i = *ppos; count > 0 && i < NVRAM_BYTES; --count, ++i, ++p)
+   *p = __nvram_read_byte(i);
+   spin_unlock_irq(&rtc_lock);
+
+   *ppos = i;
+   return p - buf;
+}
+
+static ssize_t nvram_write(char *buf, size_t count, loff_t *ppos)
+{
+   char *p = buf;
+   loff_t i;
+
+   spin_lock_irq(&rtc_lock);
+   if (!__nvram_check_checksum()) {
+   spin_unlock_irq(&rtc_lock);
+   return -EIO;
+   }
+   for (i = *ppos; count > 0 && i < NVRAM_BYTES; --count, ++i, ++p)
+   __nvram_write_byte(*p, i);
+   __nvram_set_checksum();
+   spin_unlock_irq(&rtc_lock);
+
+   *ppos = i;
+   return p - buf;
+}
+
 const struct nvram_ops arch_nvram_ops = {
.read_byte  = nvram_read_byte,
.write_byte = nvram_write_byte,
+   .read   = nvram_read,
+   .write  = nvram_write,
.get_size   = nvram_get_size,
.set_checksum   = nvram_set_checksum,
.initialize = nvram_initialize,
@@ -215,69 +255,95 @@ static loff_t nvram_misc_llseek(struct f
 static ssize_t nvram_misc_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
 {
-   unsigned char contents[NVRAM_BYTES];
-   unsigned i = *ppos;
-   unsigned char *tmp;
-
-   spin_lock_irq(&rtc_lock);
+   loff_t i;
+   char __user *p = buf;
 
-   if (!__nvram_check_checksum())
-   goto checksum_err;
-
-   for (tmp = contents; count-- > 0 && i < NVRAM_BYTES; ++i, ++tmp)
-   *tmp = __nvram_read_byte(i);
-
-   spin_unlock_irq(&rtc_lock);
-
-   if (copy_to_user(buf, contents, tmp - contents))
+   if (!access_ok(VERIFY_WRITE, buf, count))
return -EFAULT;
+   if (*ppos >= nvram_size)
+   return 0;
 
-   *ppos = i;
-
-   return tmp - contents;
+   /* If the arch provided a byte range read op, use it. Otherwise
+* fall back on the byte-at-a-time accessor.
+*/
+   if (arch_nvram_ops.read != NULL) {
+   char *tmp;
+   ssize_t ret;
+
+   count = min_t(size_t, count, nvram_size - *ppos);
+   count = min_t(size_t, count, PAGE_SIZE);
+
+   tmp = kmalloc(count, GFP_KERNEL);
+   if (!tmp)
+   return -ENOMEM;
+
+   ret = arch_nvram_ops.read(tmp, count, ppos);
+   if (ret <= 0)
+   goto out;
+
+   if (copy_to_user(buf, tmp, ret)) {
+   *ppos -= ret;
+   ret = -EFAULT;
+   }
+
+out:
+   kfree(tmp);
+   return ret;
+   }
 
-checksum_err:
-   spin_unlock_irq(&rtc_lock);
-   return -EIO;
+   for (i = *ppos; count > 0 && i < nvram_size; ++i, ++p, --count)
+   if (__put_user(arch_nvram_ops.read_byte(i), p))
+   return -EFAULT;
+   *ppos = i;
+   return p - buf;
 }
 
 static ssize_t nvram_misc_write(struct file *file, const char __user *buf,
 size_t count, loff_t *ppos)
 {
-   unsigned char contents[NVRAM_BYTES];
-   unsigned i = *ppos;
-   unsigned char *tmp;
-
-   if (i >= NVRAM_BYTES)
-   return 0;   /* Past EOF */
-
-   if (count > NVRA

[RFC v4 05/25] char/nvram: Re-order functions to remove forward declarations and #ifdefs

2015-07-12 Thread Finn Thain
Also give functions more sensible names: nvram_misc_* for misc device ops,
nvram_proc_* for proc file ops and nvram_module_* for init and exit
functions. This makes them distict from nvram_ops members.

Signed-off-by: Finn Thain 

---
 drivers/char/nvram.c |  194 ++-
 1 file changed, 86 insertions(+), 108 deletions(-)

Index: linux/drivers/char/nvram.c
===
--- linux.orig/drivers/char/nvram.c 2015-07-12 20:24:56.0 +1000
+++ linux/drivers/char/nvram.c  2015-07-12 20:24:59.0 +1000
@@ -54,11 +54,6 @@ static int nvram_open_mode;  /* special o
 #define NVRAM_WRITE1 /* opened for writing (exclusive) */
 #define NVRAM_EXCL 2 /* opened with O_EXCL */
 
-#ifdef CONFIG_PROC_FS
-static void pc_nvram_proc_read(unsigned char *contents, struct seq_file *seq,
-   void *offset);
-#endif
-
 /*
  * These functions are provided to be called internally or by other parts of
  * the kernel. It's up to the caller to ensure correct checksum before reading
@@ -170,7 +165,7 @@ void nvram_set_checksum(void)
  * The are the file operation function for user access to /dev/nvram
  */
 
-static loff_t nvram_llseek(struct file *file, loff_t offset, int origin)
+static loff_t nvram_misc_llseek(struct file *file, loff_t offset, int origin)
 {
switch (origin) {
case 0:
@@ -189,8 +184,8 @@ static loff_t nvram_llseek(struct file *
return (offset >= 0) ? (file->f_pos = offset) : -EINVAL;
 }
 
-static ssize_t nvram_read(struct file *file, char __user *buf,
-   size_t count, loff_t *ppos)
+static ssize_t nvram_misc_read(struct file *file, char __user *buf,
+   size_t count, loff_t *ppos)
 {
unsigned char contents[NVRAM_BYTES];
unsigned i = *ppos;
@@ -218,8 +213,8 @@ checksum_err:
return -EIO;
 }
 
-static ssize_t nvram_write(struct file *file, const char __user *buf,
-   size_t count, loff_t *ppos)
+static ssize_t nvram_misc_write(struct file *file, const char __user *buf,
+size_t count, loff_t *ppos)
 {
unsigned char contents[NVRAM_BYTES];
unsigned i = *ppos;
@@ -257,8 +252,8 @@ checksum_err:
return -EIO;
 }
 
-static long nvram_ioctl(struct file *file, unsigned int cmd,
-   unsigned long arg)
+static long nvram_misc_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
 {
int i;
 
@@ -298,7 +293,7 @@ static long nvram_ioctl(struct file *fil
}
 }
 
-static int nvram_open(struct inode *inode, struct file *file)
+static int nvram_misc_open(struct inode *inode, struct file *file)
 {
spin_lock(&nvram_state_lock);
 
@@ -320,7 +315,7 @@ static int nvram_open(struct inode *inod
return 0;
 }
 
-static int nvram_release(struct inode *inode, struct file *file)
+static int nvram_misc_release(struct inode *inode, struct file *file)
 {
spin_lock(&nvram_state_lock);
 
@@ -337,100 +332,6 @@ static int nvram_release(struct inode *i
return 0;
 }
 
-#ifndef CONFIG_PROC_FS
-static int nvram_add_proc_fs(void)
-{
-   return 0;
-}
-
-#else
-
-static int nvram_proc_read(struct seq_file *seq, void *offset)
-{
-   unsigned char contents[NVRAM_BYTES];
-   int i = 0;
-
-   spin_lock_irq(&rtc_lock);
-   for (i = 0; i < NVRAM_BYTES; ++i)
-   contents[i] = __nvram_read_byte(i);
-   spin_unlock_irq(&rtc_lock);
-
-   pc_nvram_proc_read(contents, seq, offset);
-
-   return 0;
-}
-
-static int nvram_proc_open(struct inode *inode, struct file *file)
-{
-   return single_open(file, nvram_proc_read, NULL);
-}
-
-static const struct file_operations nvram_proc_fops = {
-   .owner  = THIS_MODULE,
-   .open   = nvram_proc_open,
-   .read   = seq_read,
-   .llseek = seq_lseek,
-   .release= single_release,
-};
-
-static int nvram_add_proc_fs(void)
-{
-   if (!proc_create("driver/nvram", 0, NULL, &nvram_proc_fops))
-   return -ENOMEM;
-   return 0;
-}
-
-#endif /* CONFIG_PROC_FS */
-
-static const struct file_operations nvram_fops = {
-   .owner  = THIS_MODULE,
-   .llseek = nvram_llseek,
-   .read   = nvram_read,
-   .write  = nvram_write,
-   .unlocked_ioctl = nvram_ioctl,
-   .open   = nvram_open,
-   .release= nvram_release,
-};
-
-static struct miscdevice nvram_dev = {
-   NVRAM_MINOR,
-   "nvram",
-   &nvram_fops
-};
-
-static int __init nvram_init(void)
-{
-   int ret;
-
-   ret = misc_register(&nvram_dev);
-   if (ret) {
-   printk(KERN_ERR "nvram: can't misc_register on

[RFC v4 15/25] powerpc: Implement arch_nvram_ops.get_size() and remove old nvram_* exports

2015-07-12 Thread Finn Thain
Implement arch_nvram_ops for PPC32 and make use of it in the generic_nvram
misc device module so that the nvram_* function exports can be removed.

Signed-off-by: Finn Thain 

---
 arch/powerpc/include/asm/nvram.h |3 ---
 arch/powerpc/kernel/setup_32.c   |   10 +++---
 drivers/char/generic_nvram.c |   24 
 3 files changed, 19 insertions(+), 18 deletions(-)

Index: linux/arch/powerpc/include/asm/nvram.h
===
--- linux.orig/arch/powerpc/include/asm/nvram.h 2015-07-12 20:25:08.0 
+1000
+++ linux/arch/powerpc/include/asm/nvram.h  2015-07-12 20:25:10.0 
+1000
@@ -98,7 +98,4 @@ extern int nvram_write_os_partition(stru
unsigned int err_type,
unsigned int error_log_cnt);
 
-/* Determine NVRAM size */
-extern ssize_t nvram_get_size(void);
-
 #endif /* _ASM_POWERPC_NVRAM_H */
Index: linux/arch/powerpc/kernel/setup_32.c
===
--- linux.orig/arch/powerpc/kernel/setup_32.c   2015-07-12 20:25:08.0 
+1000
+++ linux/arch/powerpc/kernel/setup_32.c2015-07-12 20:25:10.0 
+1000
@@ -186,13 +186,12 @@ void nvram_write_byte(unsigned char val,
 }
 EXPORT_SYMBOL(nvram_write_byte);
 
-ssize_t nvram_get_size(void)
+static ssize_t ppc_nvram_get_size(void)
 {
if (ppc_md.nvram_size)
return ppc_md.nvram_size();
-   return -1;
+   return -ENODEV;
 }
-EXPORT_SYMBOL(nvram_get_size);
 
 void nvram_sync(void)
 {
@@ -201,6 +200,11 @@ void nvram_sync(void)
 }
 EXPORT_SYMBOL(nvram_sync);
 
+const struct nvram_ops arch_nvram_ops = {
+   .get_size   = ppc_nvram_get_size,
+};
+EXPORT_SYMBOL(arch_nvram_ops);
+
 #endif /* CONFIG_NVRAM */
 
 int __init ppc_init(void)
Index: linux/drivers/char/generic_nvram.c
===
--- linux.orig/drivers/char/generic_nvram.c 2015-07-12 20:25:08.0 
+1000
+++ linux/drivers/char/generic_nvram.c  2015-07-12 20:25:10.0 +1000
@@ -28,8 +28,6 @@
 #include 
 #endif
 
-#define NVRAM_SIZE 8192
-
 static DEFINE_MUTEX(nvram_mutex);
 static ssize_t nvram_len;
 
@@ -150,20 +148,22 @@ static struct miscdevice nvram_dev = {
 
 int __init nvram_init(void)
 {
-   int ret = 0;
+   int ret;
 
-   printk(KERN_INFO "Generic non-volatile memory driver v%s\n",
-   NVRAM_VERSION);
-   ret = misc_register(&nvram_dev);
-   if (ret != 0)
-   goto out;
+   if (arch_nvram_ops.get_size == NULL)
+   return -ENODEV;
 
-   nvram_len = nvram_get_size();
+   nvram_len = arch_nvram_ops.get_size();
if (nvram_len < 0)
-   nvram_len = NVRAM_SIZE;
+   return nvram_len;
 
-out:
-   return ret;
+   ret = misc_register(&nvram_dev);
+   if (ret)
+   return ret;
+
+   pr_info("Generic non-volatile memory driver v%s\n", NVRAM_VERSION);
+
+   return 0;
 }
 
 void __exit nvram_cleanup(void)


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[RFC v4 17/25] powerpc, fbdev: Use arch_nvram_ops methods instead of nvram_read_byte() and nvram_write_byte()

2015-07-12 Thread Finn Thain
Make use of arch_nvram_ops in device drivers so that the nvram_*
function exports can be removed.

Since they are no longer global symbols, rename the PPC32 nvram_* functions
appropriately.

Add the missing CONFIG_NVRAM test to imsttfb to avoid a build failure.

Signed-off-by: Finn Thain 

---
 arch/powerpc/kernel/setup_32.c |8 
 drivers/char/generic_nvram.c   |4 ++--
 drivers/video/fbdev/controlfb.c|4 ++--
 drivers/video/fbdev/imsttfb.c  |7 +++
 drivers/video/fbdev/matrox/matroxfb_base.c |2 +-
 drivers/video/fbdev/platinumfb.c   |4 ++--
 drivers/video/fbdev/valkyriefb.c   |4 ++--
 7 files changed, 16 insertions(+), 17 deletions(-)

Index: linux/arch/powerpc/kernel/setup_32.c
===
--- linux.orig/arch/powerpc/kernel/setup_32.c   2015-07-12 20:25:11.0 
+1000
+++ linux/arch/powerpc/kernel/setup_32.c2015-07-12 20:25:13.0 
+1000
@@ -170,20 +170,18 @@ __setup("l3cr=", ppc_setup_l3cr);
 
 #ifdef CONFIG_GENERIC_NVRAM
 
-unsigned char nvram_read_byte(int addr)
+static unsigned char ppc_nvram_read_byte(int addr)
 {
if (ppc_md.nvram_read_val)
return ppc_md.nvram_read_val(addr);
return 0xff;
 }
-EXPORT_SYMBOL(nvram_read_byte);
 
-void nvram_write_byte(unsigned char val, int addr)
+static void ppc_nvram_write_byte(unsigned char val, int addr)
 {
if (ppc_md.nvram_write_val)
ppc_md.nvram_write_val(addr, val);
 }
-EXPORT_SYMBOL(nvram_write_byte);
 
 static ssize_t ppc_nvram_get_size(void)
 {
@@ -200,6 +198,8 @@ static long ppc_nvram_sync(void)
 }
 
 const struct nvram_ops arch_nvram_ops = {
+   .read_byte  = ppc_nvram_read_byte,
+   .write_byte = ppc_nvram_write_byte,
.get_size   = ppc_nvram_get_size,
.sync   = ppc_nvram_sync,
 };
Index: linux/drivers/char/generic_nvram.c
===
--- linux.orig/drivers/char/generic_nvram.c 2015-07-12 20:25:11.0 
+1000
+++ linux/drivers/char/generic_nvram.c  2015-07-12 20:25:13.0 +1000
@@ -64,7 +64,7 @@ static ssize_t read_nvram(struct file *f
if (*ppos >= nvram_len)
return 0;
for (i = *ppos; count > 0 && i < nvram_len; ++i, ++p, --count)
-   if (__put_user(nvram_read_byte(i), p))
+   if (__put_user(arch_nvram_ops.read_byte(i), p))
return -EFAULT;
*ppos = i;
return p - buf;
@@ -84,7 +84,7 @@ static ssize_t write_nvram(struct file *
for (i = *ppos; count > 0 && i < nvram_len; ++i, ++p, --count) {
if (__get_user(c, p))
return -EFAULT;
-   nvram_write_byte(c, i);
+   arch_nvram_ops.write_byte(c, i);
}
*ppos = i;
return p - buf;
Index: linux/drivers/video/fbdev/controlfb.c
===
--- linux.orig/drivers/video/fbdev/controlfb.c  2015-07-12 20:24:53.0 
+1000
+++ linux/drivers/video/fbdev/controlfb.c   2015-07-12 20:25:13.0 
+1000
@@ -415,7 +415,7 @@ static int __init init_control(struct fb
/* Try to pick a video mode out of NVRAM if we have one. */
 #ifdef CONFIG_NVRAM
if (default_cmode == CMODE_NVRAM) {
-   cmode = nvram_read_byte(NV_CMODE);
+   cmode = arch_nvram_ops.read_byte(NV_CMODE);
if(cmode < CMODE_8 || cmode > CMODE_32)
cmode = CMODE_8;
} else
@@ -423,7 +423,7 @@ static int __init init_control(struct fb
cmode=default_cmode;
 #ifdef CONFIG_NVRAM
if (default_vmode == VMODE_NVRAM) {
-   vmode = nvram_read_byte(NV_VMODE);
+   vmode = arch_nvram_ops.read_byte(NV_VMODE);
if (vmode < 1 || vmode > VMODE_MAX ||
control_mac_modes[vmode - 1].m[full] < cmode) {
sense = read_control_sense(p);
Index: linux/drivers/video/fbdev/matrox/matroxfb_base.c
===
--- linux.orig/drivers/video/fbdev/matrox/matroxfb_base.c   2015-07-12 
20:25:08.0 +1000
+++ linux/drivers/video/fbdev/matrox/matroxfb_base.c2015-07-12 
20:25:13.0 +1000
@@ -1888,7 +1888,7 @@ static int initMatrox2(struct matrox_fb_
default_vmode = VMODE_640_480_60;
 #ifdef CONFIG_NVRAM
if (default_cmode == CMODE_NVRAM)
-   default_cmode = nvram_read_byte(NV_CMODE);
+   default_cmode = arch_nvram_ops.read_byte(NV_CMODE);
 #endif
if (default_cmode < CMODE_8 || default_cmode > CMODE_32)
default_

[RFC v4 18/25] nvram: Drop nvram_* symbol exports and prototypes

2015-07-12 Thread Finn Thain
Drivers now use the arch_nvram_ops calls so remove the function exports and
prototypes. nvram_check_checksum() is unused so remove it.

Signed-off-by: Finn Thain 

---
 arch/m68k/atari/nvram.c |6 +++---
 drivers/char/nvram.c|   27 +--
 include/linux/nvram.h   |8 
 3 files changed, 8 insertions(+), 33 deletions(-)

Index: linux/drivers/char/nvram.c
===
--- linux.orig/drivers/char/nvram.c 2015-07-12 20:25:11.0 +1000
+++ linux/drivers/char/nvram.c  2015-07-12 20:25:15.0 +1000
@@ -82,13 +82,12 @@ static ssize_t nvram_size;
  * periodic 11 min sync from kernel/time/ntp.c vs. this driver.)
  */
 
-unsigned char __nvram_read_byte(int i)
+static unsigned char __nvram_read_byte(int i)
 {
return CMOS_READ(NVRAM_FIRST_BYTE + i);
 }
-EXPORT_SYMBOL(__nvram_read_byte);
 
-unsigned char nvram_read_byte(int i)
+static unsigned char nvram_read_byte(int i)
 {
unsigned long flags;
unsigned char c;
@@ -98,16 +97,14 @@ unsigned char nvram_read_byte(int i)
spin_unlock_irqrestore(&rtc_lock, flags);
return c;
 }
-EXPORT_SYMBOL(nvram_read_byte);
 
 /* This races nicely with trying to read with checksum checking (nvram_read) */
-void __nvram_write_byte(unsigned char c, int i)
+static void __nvram_write_byte(unsigned char c, int i)
 {
CMOS_WRITE(c, NVRAM_FIRST_BYTE + i);
 }
-EXPORT_SYMBOL(__nvram_write_byte);
 
-void nvram_write_byte(unsigned char c, int i)
+static void nvram_write_byte(unsigned char c, int i)
 {
unsigned long flags;
 
@@ -115,14 +112,13 @@ void nvram_write_byte(unsigned char c, i
__nvram_write_byte(c, i);
spin_unlock_irqrestore(&rtc_lock, flags);
 }
-EXPORT_SYMBOL(nvram_write_byte);
 
 /* On PCs, the checksum is built only over bytes 2..31 */
 #define PC_CKS_RANGE_START 2
 #define PC_CKS_RANGE_END   31
 #define PC_CKS_LOC 32
 
-int __nvram_check_checksum(void)
+static int __nvram_check_checksum(void)
 {
int i;
unsigned short sum = 0;
@@ -134,19 +130,6 @@ int __nvram_check_checksum(void)
__nvram_read_byte(PC_CKS_LOC+1);
return (sum & 0x) == expect;
 }
-EXPORT_SYMBOL(__nvram_check_checksum);
-
-int nvram_check_checksum(void)
-{
-   unsigned long flags;
-   int rv;
-
-   spin_lock_irqsave(&rtc_lock, flags);
-   rv = __nvram_check_checksum();
-   spin_unlock_irqrestore(&rtc_lock, flags);
-   return rv;
-}
-EXPORT_SYMBOL(nvram_check_checksum);
 
 static void __nvram_set_checksum(void)
 {
Index: linux/include/linux/nvram.h
===
--- linux.orig/include/linux/nvram.h2015-07-12 20:25:11.0 +1000
+++ linux/include/linux/nvram.h 2015-07-12 20:25:15.0 +1000
@@ -3,14 +3,6 @@
 
 #include 
 
-/* __foo is foo without grabbing the rtc_lock - get it yourself */
-extern unsigned char __nvram_read_byte(int i);
-extern unsigned char nvram_read_byte(int i);
-extern void __nvram_write_byte(unsigned char c, int i);
-extern void nvram_write_byte(unsigned char c, int i);
-extern int __nvram_check_checksum(void);
-extern int nvram_check_checksum(void);
-
 struct nvram_ops {
ssize_t (*read)(char *, size_t, loff_t *);
ssize_t (*write)(char *, size_t, loff_t *);
Index: linux/arch/m68k/atari/nvram.c
===
--- linux.orig/arch/m68k/atari/nvram.c  2015-07-12 20:25:05.0 +1000
+++ linux/arch/m68k/atari/nvram.c   2015-07-12 20:25:15.0 +1000
@@ -33,13 +33,13 @@
  * periodic 11 min sync from kernel/time/ntp.c vs. this driver.)
  */
 
-unsigned char __nvram_read_byte(int i)
+static unsigned char __nvram_read_byte(int i)
 {
return CMOS_READ(NVRAM_FIRST_BYTE + i);
 }
 
 /* This races nicely with trying to read with checksum checking */
-void __nvram_write_byte(unsigned char c, int i)
+static void __nvram_write_byte(unsigned char c, int i)
 {
CMOS_WRITE(c, NVRAM_FIRST_BYTE + i);
 }
@@ -51,7 +51,7 @@ void __nvram_write_byte(unsigned char c,
 #define ATARI_CKS_RANGE_END47
 #define ATARI_CKS_LOC  48
 
-int __nvram_check_checksum(void)
+static int __nvram_check_checksum(void)
 {
int i;
unsigned char sum = 0;


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

  1   2   3   4   5   6   >