Merge tag 'char-misc-5.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh...
[sfrench/cifs-2.6.git] / arch / m68k / mac / misc.c
index 1423e1fe02618ff32571e50fd9431ea957cf068e..90f4e9ca1276b5039ff95f9487bd3c996f6d5e00 100644 (file)
@@ -36,8 +36,9 @@
 
 static void (*rom_reset)(void);
 
+#if IS_ENABLED(CONFIG_NVRAM)
 #ifdef CONFIG_ADB_CUDA
-static __u8 cuda_read_pram(int offset)
+static unsigned char cuda_pram_read_byte(int offset)
 {
        struct adb_request req;
 
@@ -49,7 +50,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;
 
@@ -62,29 +63,29 @@ static void cuda_write_pram(int offset, __u8 data)
 #endif /* CONFIG_ADB_CUDA */
 
 #ifdef CONFIG_ADB_PMU
-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,
-                       (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];
+       pmu_wait_complete(&req);
+
+       return req.reply[0];
 }
 
-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,
-                       (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();
+       pmu_wait_complete(&req);
 }
 #endif /* CONFIG_ADB_PMU */
+#endif /* CONFIG_NVRAM */
 
 /*
  * VIA PRAM/RTC access routines
@@ -93,7 +94,7 @@ static void pmu_write_pram(int offset, __u8 data)
  * the RTC should be enabled.
  */
 
-static __u8 via_pram_readbyte(void)
+static __u8 via_rtc_recv(void)
 {
        int i, reg;
        __u8 data;
@@ -120,7 +121,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;
 
@@ -136,6 +137,31 @@ static void via_pram_writebyte(__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_READ            BIT(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
+
+/*
+ * Inside Mac has no information about two-byte RTC commands but
+ * the MAME/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
@@ -145,29 +171,33 @@ static void via_pram_writebyte(__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;
 
        if (command & 0xFF00) {         /* extended (two-byte) command */
-               via_pram_writebyte((command & 0xFF00) >> 8);
-               via_pram_writebyte(command & 0xFF);
-               is_read = command & 0x8000;
+               via_rtc_send((command & 0xFF00) >> 8);
+               via_rtc_send(command & 0xFF);
+               is_read = command & (RTC_FLG_READ << 8);
        } else {                        /* one-byte command */
-               via_pram_writebyte(command);
-               is_read = command & 0x80;
+               via_rtc_send(command);
+               is_read = command & RTC_FLG_READ;
        }
        if (is_read) {
-               *data = via_pram_readbyte();
+               *data = via_rtc_recv();
        } else {
-               via_pram_writebyte(*data);
+               via_rtc_send(*data);
        }
 
        /* All done, disable the RTC */
@@ -177,14 +207,30 @@ static void via_pram_command(int command, __u8 *data)
        local_irq_restore(flags);
 }
 
-static __u8 via_read_pram(int offset)
+#if IS_ENABLED(CONFIG_NVRAM)
+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_write_pram(int offset, __u8 data)
+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);
 }
+#endif /* CONFIG_NVRAM */
 
 /*
  * Return the current time in seconds since January 1, 1904.
@@ -201,10 +247,10 @@ static time64_t 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
@@ -212,10 +258,14 @@ static time64_t 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 (time64_t)result.idata - RTC_OFFSET;
@@ -254,18 +304,18 @@ static void via_set_rtc_time(struct rtc_time *tm)
        /* 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 = lower_32_bits(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]);
+       via_rtc_command(RTC_CMD_WRITE(RTC_REG_SECONDS_2), &data.cdata[1]);
+       via_rtc_command(RTC_CMD_WRITE(RTC_REG_SECONDS_3), &data.cdata[0]);
 
        /* Set the write protect bit */
 
-       temp = 0xD5;
-       via_pram_command(0x35, &temp);
+       temp = 0x55 | RTC_FLG_WRITE_PROTECT;
+       via_rtc_command(RTC_CMD_WRITE(RTC_REG_WRITE_PROTECT), &temp);
 }
 
 static void via_shutdown(void)
@@ -326,66 +376,58 @@ static void cuda_shutdown(void)
  *-------------------------------------------------------------------
  */
 
-void mac_pram_read(int offset, __u8 *buffer, int len)
+#if IS_ENABLED(CONFIG_NVRAM)
+unsigned char mac_pram_read_byte(int addr)
 {
-       __u8 (*func)(int);
-       int i;
-
        switch (macintosh_config->adb_type) {
        case MAC_ADB_IOP:
        case MAC_ADB_II:
        case MAC_ADB_PB1:
-               func = via_read_pram;
-               break;
+               return via_pram_read_byte(addr);
 #ifdef CONFIG_ADB_CUDA
        case MAC_ADB_EGRET:
        case MAC_ADB_CUDA:
-               func = cuda_read_pram;
-               break;
+               return cuda_pram_read_byte(addr);
 #endif
 #ifdef CONFIG_ADB_PMU
        case MAC_ADB_PB2:
-               func = pmu_read_pram;
-               break;
+               return pmu_pram_read_byte(addr);
 #endif
        default:
-               return;
-       }
-       for (i = 0 ; i < len ; i++) {
-               buffer[i] = (*func)(offset++);
+               return 0xFF;
        }
 }
 
-void mac_pram_write(int offset, __u8 *buffer, int len)
+void mac_pram_write_byte(unsigned char val, int addr)
 {
-       void (*func)(int, __u8);
-       int i;
-
        switch (macintosh_config->adb_type) {
        case MAC_ADB_IOP:
        case MAC_ADB_II:
        case MAC_ADB_PB1:
-               func = via_write_pram;
+               via_pram_write_byte(val, addr);
                break;
 #ifdef CONFIG_ADB_CUDA
        case MAC_ADB_EGRET:
        case MAC_ADB_CUDA:
-               func = cuda_write_pram;
+               cuda_pram_write_byte(val, addr);
                break;
 #endif
 #ifdef CONFIG_ADB_PMU
        case MAC_ADB_PB2:
-               func = pmu_write_pram;
+               pmu_pram_write_byte(val, addr);
                break;
 #endif
        default:
-               return;
-       }
-       for (i = 0 ; i < len ; i++) {
-               (*func)(offset++, buffer[i]);
+               break;
        }
 }
 
+ssize_t mac_pram_get_size(void)
+{
+       return 256;
+}
+#endif /* CONFIG_NVRAM */
+
 void mac_poweroff(void)
 {
        if (oss_present) {