aboutsummaryrefslogtreecommitdiff
path: root/arch/sh/kernel/cpu/sh4/sq.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sh/kernel/cpu/sh4/sq.c')
-rw-r--r--arch/sh/kernel/cpu/sh4/sq.c94
1 files changed, 51 insertions, 43 deletions
diff --git a/arch/sh/kernel/cpu/sh4/sq.c b/arch/sh/kernel/cpu/sh4/sq.c
index d7fff752e56..0a47bd3e7be 100644
--- a/arch/sh/kernel/cpu/sh4/sq.c
+++ b/arch/sh/kernel/cpu/sh4/sq.c
@@ -13,16 +13,17 @@
#include <linux/init.h>
#include <linux/cpu.h>
#include <linux/bitmap.h>
-#include <linux/sysdev.h>
+#include <linux/device.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/mm.h>
#include <linux/io.h>
+#include <linux/prefetch.h>
#include <asm/page.h>
#include <asm/cacheflush.h>
-#include <asm/cpu/sq.h>
+#include <cpu/sq.h>
struct sq_mapping;
@@ -43,9 +44,9 @@ static unsigned long *sq_bitmap;
#define store_queue_barrier() \
do { \
- (void)ctrl_inl(P4SEG_STORE_QUE); \
- ctrl_outl(0, P4SEG_STORE_QUE + 0); \
- ctrl_outl(0, P4SEG_STORE_QUE + 8); \
+ (void)__raw_readl(P4SEG_STORE_QUE); \
+ __raw_writel(0, P4SEG_STORE_QUE + 0); \
+ __raw_writel(0, P4SEG_STORE_QUE + 8); \
} while (0);
/**
@@ -58,11 +59,11 @@ do { \
*/
void sq_flush_range(unsigned long start, unsigned int len)
{
- volatile unsigned long *sq = (unsigned long *)start;
+ unsigned long *sq = (unsigned long *)start;
/* Flush the queues */
for (len >>= 5; len--; sq += 8)
- prefetchw((void *)sq);
+ prefetchw(sq);
/* Wait for completion */
store_queue_barrier();
@@ -100,7 +101,7 @@ static inline void sq_mapping_list_del(struct sq_mapping *map)
spin_unlock_irq(&sq_mapping_lock);
}
-static int __sq_remap(struct sq_mapping *map, unsigned long flags)
+static int __sq_remap(struct sq_mapping *map, pgprot_t prot)
{
#if defined(CONFIG_MMU)
struct vm_struct *vma;
@@ -113,7 +114,7 @@ static int __sq_remap(struct sq_mapping *map, unsigned long flags)
if (ioremap_page_range((unsigned long)vma->addr,
(unsigned long)vma->addr + map->size,
- vma->phys_addr, __pgprot(flags))) {
+ vma->phys_addr, prot)) {
vunmap(vma->addr);
return -EAGAIN;
}
@@ -123,8 +124,8 @@ static int __sq_remap(struct sq_mapping *map, unsigned long flags)
* straightforward, as we can just load up each queue's QACR with
* the physical address appropriately masked.
*/
- ctrl_outl(((map->addr >> 26) << 2) & 0x1c, SQ_QACR0);
- ctrl_outl(((map->addr >> 26) << 2) & 0x1c, SQ_QACR1);
+ __raw_writel(((map->addr >> 26) << 2) & 0x1c, SQ_QACR0);
+ __raw_writel(((map->addr >> 26) << 2) & 0x1c, SQ_QACR1);
#endif
return 0;
@@ -135,14 +136,14 @@ static int __sq_remap(struct sq_mapping *map, unsigned long flags)
* @phys: Physical address of mapping.
* @size: Length of mapping.
* @name: User invoking mapping.
- * @flags: Protection flags.
+ * @prot: Protection bits.
*
* Remaps the physical address @phys through the next available store queue
* address of @size length. @name is logged at boot time as well as through
* the sysfs interface.
*/
unsigned long sq_remap(unsigned long phys, unsigned int size,
- const char *name, unsigned long flags)
+ const char *name, pgprot_t prot)
{
struct sq_mapping *map;
unsigned long end;
@@ -177,7 +178,7 @@ unsigned long sq_remap(unsigned long phys, unsigned int size,
map->sq_addr = P4SEG_STORE_QUE + (page << PAGE_SHIFT);
- ret = __sq_remap(map, pgprot_val(PAGE_KERNEL_NOCACHE) | flags);
+ ret = __sq_remap(map, prot);
if (unlikely(ret != 0))
goto out;
@@ -199,7 +200,7 @@ EXPORT_SYMBOL(sq_remap);
/**
* sq_unmap - Unmap a Store Queue allocation
- * @map: Pre-allocated Store Queue mapping.
+ * @vaddr: Pre-allocated Store Queue mapping.
*
* Unmaps the store queue allocation @map that was previously created by
* sq_remap(). Also frees up the pte that was previously inserted into
@@ -208,7 +209,6 @@ EXPORT_SYMBOL(sq_remap);
void sq_unmap(unsigned long vaddr)
{
struct sq_mapping **p, *map;
- struct vm_struct *vma;
int page;
for (p = &sq_mapping_list; (map = *p); p = &map->next)
@@ -217,7 +217,7 @@ void sq_unmap(unsigned long vaddr)
if (unlikely(!map)) {
printk("%s: bad store queue address 0x%08lx\n",
- __FUNCTION__, vaddr);
+ __func__, vaddr);
return;
}
@@ -225,11 +225,18 @@ void sq_unmap(unsigned long vaddr)
bitmap_release_region(sq_bitmap, page, get_order(map->size));
#ifdef CONFIG_MMU
- vma = remove_vm_area((void *)(map->sq_addr & PAGE_MASK));
- if (!vma) {
- printk(KERN_ERR "%s: bad address 0x%08lx\n",
- __FUNCTION__, map->sq_addr);
- return;
+ {
+ /*
+ * Tear down the VMA in the MMU case.
+ */
+ struct vm_struct *vma;
+
+ vma = remove_vm_area((void *)(map->sq_addr & PAGE_MASK));
+ if (!vma) {
+ printk(KERN_ERR "%s: bad address 0x%08lx\n",
+ __func__, map->sq_addr);
+ return;
+ }
}
#endif
@@ -257,7 +264,7 @@ struct sq_sysfs_attr {
ssize_t (*store)(const char *buf, size_t count);
};
-#define to_sq_sysfs_attr(attr) container_of(attr, struct sq_sysfs_attr, attr)
+#define to_sq_sysfs_attr(a) container_of(a, struct sq_sysfs_attr, attr)
static ssize_t sq_sysfs_show(struct kobject *kobj, struct attribute *attr,
char *buf)
@@ -303,8 +310,7 @@ static ssize_t mapping_store(const char *buf, size_t count)
return -EIO;
if (likely(len)) {
- int ret = sq_remap(base, len, "Userspace",
- pgprot_val(PAGE_SHARED));
+ int ret = sq_remap(base, len, "Userspace", PAGE_SHARED);
if (ret < 0)
return ret;
} else
@@ -321,7 +327,7 @@ static struct attribute *sq_sysfs_attrs[] = {
NULL,
};
-static struct sysfs_ops sq_sysfs_ops = {
+static const struct sysfs_ops sq_sysfs_ops = {
.show = sq_sysfs_show,
.store = sq_sysfs_store,
};
@@ -331,35 +337,38 @@ static struct kobj_type ktype_percpu_entry = {
.default_attrs = sq_sysfs_attrs,
};
-static int __devinit sq_sysdev_add(struct sys_device *sysdev)
+static int sq_dev_add(struct device *dev, struct subsys_interface *sif)
{
- unsigned int cpu = sysdev->id;
+ unsigned int cpu = dev->id;
struct kobject *kobj;
+ int error;
sq_kobject[cpu] = kzalloc(sizeof(struct kobject), GFP_KERNEL);
if (unlikely(!sq_kobject[cpu]))
return -ENOMEM;
kobj = sq_kobject[cpu];
- kobj->parent = &sysdev->kobj;
- kobject_set_name(kobj, "%s", "sq");
- kobj->ktype = &ktype_percpu_entry;
-
- return kobject_register(kobj);
+ error = kobject_init_and_add(kobj, &ktype_percpu_entry, &dev->kobj,
+ "%s", "sq");
+ if (!error)
+ kobject_uevent(kobj, KOBJ_ADD);
+ return error;
}
-static int __devexit sq_sysdev_remove(struct sys_device *sysdev)
+static int sq_dev_remove(struct device *dev, struct subsys_interface *sif)
{
- unsigned int cpu = sysdev->id;
+ unsigned int cpu = dev->id;
struct kobject *kobj = sq_kobject[cpu];
- kobject_unregister(kobj);
+ kobject_put(kobj);
return 0;
}
-static struct sysdev_driver sq_sysdev_driver = {
- .add = sq_sysdev_add,
- .remove = __devexit_p(sq_sysdev_remove),
+static struct subsys_interface sq_interface = {
+ .name = "sq",
+ .subsys = &cpu_subsys,
+ .add_dev = sq_dev_add,
+ .remove_dev = sq_dev_remove,
};
static int __init sq_api_init(void)
@@ -371,8 +380,7 @@ static int __init sq_api_init(void)
printk(KERN_NOTICE "sq: Registering store queue API.\n");
sq_cache = kmem_cache_create("store_queue_cache",
- sizeof(struct sq_mapping), 0, 0,
- NULL, NULL);
+ sizeof(struct sq_mapping), 0, 0, NULL);
if (unlikely(!sq_cache))
return ret;
@@ -380,7 +388,7 @@ static int __init sq_api_init(void)
if (unlikely(!sq_bitmap))
goto out;
- ret = sysdev_driver_register(&cpu_sysdev_class, &sq_sysdev_driver);
+ ret = subsys_interface_register(&sq_interface);
if (unlikely(ret != 0))
goto out;
@@ -395,7 +403,7 @@ out:
static void __exit sq_api_exit(void)
{
- sysdev_driver_unregister(&cpu_sysdev_class, &sq_sysdev_driver);
+ subsys_interface_unregister(&sq_interface);
kfree(sq_bitmap);
kmem_cache_destroy(sq_cache);
}