Merge branch 'torvalds/master'
[firefly-linux-kernel-4.4.55.git] / arch / m68k / atari / stram.c
index 0810c8d56e599b3e282af8a16ee003dab90ce8f4..c83d66442612e0747f58ebe8d12e5b07065b7e20 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/mount.h>
 #include <linux/blkdev.h>
 #include <linux/module.h>
+#include <linux/ioport.h>
 
 #include <asm/setup.h>
 #include <asm/machdep.h>
@@ -47,6 +48,7 @@ static struct resource stram_pool = {
 
 static unsigned long pool_size = 1024*1024;
 
+static unsigned long stram_virt_offset;
 
 static int __init atari_stram_setup(char *arg)
 {
@@ -67,14 +69,12 @@ early_param("stram_pool", atari_stram_setup);
 void __init atari_stram_init(void)
 {
        int i;
-       void *stram_start;
 
        /*
         * determine whether kernel code resides in ST-RAM
         * (then ST-RAM is the first memory block at virtual 0x0)
         */
-       stram_start = phys_to_virt(0);
-       kernel_in_stram = (stram_start == 0);
+       kernel_in_stram = (m68k_memory[0].addr == 0);
 
        for (i = 0; i < m68k_num_memory; ++i) {
                if (m68k_memory[i].addr == 0) {
@@ -89,24 +89,62 @@ void __init atari_stram_init(void)
 
 /*
  * This function is called from setup_arch() to reserve the pages needed for
- * ST-RAM management.
+ * ST-RAM management, if the kernel resides in ST-RAM.
  */
 void __init atari_stram_reserve_pages(void *start_mem)
 {
-       /*
-        * always reserve first page of ST-RAM, the first 2 KiB are
-        * supervisor-only!
-        */
-       if (!kernel_in_stram)
-               reserve_bootmem(0, PAGE_SIZE, BOOTMEM_DEFAULT);
+       if (kernel_in_stram) {
+               pr_debug("atari_stram pool: kernel in ST-RAM, using alloc_bootmem!\n");
+               stram_pool.start = (resource_size_t)alloc_bootmem_low_pages(pool_size);
+               stram_pool.end = stram_pool.start + pool_size - 1;
+               request_resource(&iomem_resource, &stram_pool);
+               stram_virt_offset = 0;
+               pr_debug("atari_stram pool: size = %lu bytes, resource = %pR\n",
+                       pool_size, &stram_pool);
+               pr_debug("atari_stram pool: stram_virt_offset = %lx\n",
+                       stram_virt_offset);
+       }
+}
 
-       stram_pool.start = (resource_size_t)alloc_bootmem_low_pages(pool_size);
-       stram_pool.end = stram_pool.start + pool_size - 1;
-       request_resource(&iomem_resource, &stram_pool);
 
-       pr_debug("atari_stram pool: size = %lu bytes, resource = %pR\n",
-                pool_size, &stram_pool);
+/*
+ * This function is called as arch initcall to reserve the pages needed for
+ * ST-RAM management, if the kernel does not reside in ST-RAM.
+ */
+int __init atari_stram_map_pages(void)
+{
+       if (!kernel_in_stram) {
+               /*
+                * Skip page 0, as the fhe first 2 KiB are supervisor-only!
+                */
+               pr_debug("atari_stram pool: kernel not in ST-RAM, using ioremap!\n");
+               stram_pool.start = PAGE_SIZE;
+               stram_pool.end = stram_pool.start + pool_size - 1;
+               request_resource(&iomem_resource, &stram_pool);
+               stram_virt_offset = (unsigned long) ioremap(stram_pool.start,
+                               resource_size(&stram_pool)) - stram_pool.start;
+               pr_debug("atari_stram pool: size = %lu bytes, resource = %pR\n",
+                       pool_size, &stram_pool);
+               pr_debug("atari_stram pool: stram_virt_offset = %lx\n",
+                       stram_virt_offset);
+       }
+       return 0;
+}
+arch_initcall(atari_stram_map_pages);
+
+
+void *atari_stram_to_virt(unsigned long phys)
+{
+       return (void *)(phys + stram_virt_offset);
+}
+EXPORT_SYMBOL(atari_stram_to_virt);
+
+
+unsigned long atari_stram_to_phys(void *virt)
+{
+       return (unsigned long)(virt - stram_virt_offset);
 }
+EXPORT_SYMBOL(atari_stram_to_phys);
 
 
 void *atari_stram_alloc(unsigned long size, const char *owner)
@@ -134,14 +172,14 @@ void *atari_stram_alloc(unsigned long size, const char *owner)
        }
 
        pr_debug("atari_stram_alloc: returning %pR\n", res);
-       return (void *)res->start;
+       return atari_stram_to_virt(res->start);
 }
 EXPORT_SYMBOL(atari_stram_alloc);
 
 
 void atari_stram_free(void *addr)
 {
-       unsigned long start = (unsigned long)addr;
+       unsigned long start = atari_stram_to_phys(addr);
        struct resource *res;
        unsigned long size;