11da177e4SLinus Torvalds /* 21da177e4SLinus Torvalds * arch/sh/drivers/dma/dma-sysfs.c 31da177e4SLinus Torvalds * 41da177e4SLinus Torvalds * sysfs interface for SH DMA API 51da177e4SLinus Torvalds * 64dfc119fSPaul Mundt * Copyright (C) 2004 - 2006 Paul Mundt 71da177e4SLinus Torvalds * 81da177e4SLinus Torvalds * This file is subject to the terms and conditions of the GNU General Public 91da177e4SLinus Torvalds * License. See the file "COPYING" in the main directory of this archive 101da177e4SLinus Torvalds * for more details. 111da177e4SLinus Torvalds */ 121da177e4SLinus Torvalds #include <linux/kernel.h> 131da177e4SLinus Torvalds #include <linux/init.h> 140c43871bSPaul Gortmaker #include <linux/stat.h> 15*dc6876a2SKay Sievers #include <linux/device.h> 160d831770SPaul Mundt #include <linux/platform_device.h> 170d831770SPaul Mundt #include <linux/err.h> 184e57b681STim Schmielau #include <linux/string.h> 191da177e4SLinus Torvalds #include <asm/dma.h> 201da177e4SLinus Torvalds 21*dc6876a2SKay Sievers static struct bus_type dma_subsys = { 22af5ca3f4SKay Sievers .name = "dma", 23*dc6876a2SKay Sievers .dev_name = "dma", 241da177e4SLinus Torvalds }; 251da177e4SLinus Torvalds 26*dc6876a2SKay Sievers static ssize_t dma_show_devices(struct device *dev, 27*dc6876a2SKay Sievers struct device_attribute *attr, char *buf) 281da177e4SLinus Torvalds { 291da177e4SLinus Torvalds ssize_t len = 0; 301da177e4SLinus Torvalds int i; 311da177e4SLinus Torvalds 321da177e4SLinus Torvalds for (i = 0; i < MAX_DMA_CHANNELS; i++) { 331da177e4SLinus Torvalds struct dma_info *info = get_dma_info(i); 344dfc119fSPaul Mundt struct dma_channel *channel = get_dma_channel(i); 354dfc119fSPaul Mundt 364dfc119fSPaul Mundt if (unlikely(!info) || !channel) 374dfc119fSPaul Mundt continue; 381da177e4SLinus Torvalds 391da177e4SLinus Torvalds len += sprintf(buf + len, "%2d: %14s %s\n", 401da177e4SLinus Torvalds channel->chan, info->name, 411da177e4SLinus Torvalds channel->dev_id); 421da177e4SLinus Torvalds } 431da177e4SLinus Torvalds 441da177e4SLinus Torvalds return len; 451da177e4SLinus Torvalds } 461da177e4SLinus Torvalds 47*dc6876a2SKay Sievers static DEVICE_ATTR(devices, S_IRUGO, dma_show_devices, NULL); 481da177e4SLinus Torvalds 49*dc6876a2SKay Sievers static int __init dma_subsys_init(void) 501da177e4SLinus Torvalds { 511da177e4SLinus Torvalds int ret; 521da177e4SLinus Torvalds 53*dc6876a2SKay Sievers ret = subsys_system_register(&dma_subsys, NULL); 54711fa809SPaul Mundt if (unlikely(ret)) 551da177e4SLinus Torvalds return ret; 561da177e4SLinus Torvalds 57*dc6876a2SKay Sievers return device_create_file(dma_subsys.dev_root, &dev_attr_devices.attr); 58711fa809SPaul Mundt } 59*dc6876a2SKay Sievers postcore_initcall(dma_subsys_init); 601da177e4SLinus Torvalds 61*dc6876a2SKay Sievers static ssize_t dma_show_dev_id(struct device *dev, 62*dc6876a2SKay Sievers struct device_attribute *attr, char *buf) 631da177e4SLinus Torvalds { 641da177e4SLinus Torvalds struct dma_channel *channel = to_dma_channel(dev); 651da177e4SLinus Torvalds return sprintf(buf, "%s\n", channel->dev_id); 661da177e4SLinus Torvalds } 671da177e4SLinus Torvalds 68*dc6876a2SKay Sievers static ssize_t dma_store_dev_id(struct device *dev, 69*dc6876a2SKay Sievers struct device_attribute *attr, 701da177e4SLinus Torvalds const char *buf, size_t count) 711da177e4SLinus Torvalds { 721da177e4SLinus Torvalds struct dma_channel *channel = to_dma_channel(dev); 731da177e4SLinus Torvalds strcpy(channel->dev_id, buf); 741da177e4SLinus Torvalds return count; 751da177e4SLinus Torvalds } 761da177e4SLinus Torvalds 77*dc6876a2SKay Sievers static DEVICE_ATTR(dev_id, S_IRUGO | S_IWUSR, dma_show_dev_id, dma_store_dev_id); 781da177e4SLinus Torvalds 79*dc6876a2SKay Sievers static ssize_t dma_store_config(struct device *dev, 80*dc6876a2SKay Sievers struct device_attribute *attr, 811da177e4SLinus Torvalds const char *buf, size_t count) 821da177e4SLinus Torvalds { 831da177e4SLinus Torvalds struct dma_channel *channel = to_dma_channel(dev); 841da177e4SLinus Torvalds unsigned long config; 851da177e4SLinus Torvalds 861da177e4SLinus Torvalds config = simple_strtoul(buf, NULL, 0); 870d831770SPaul Mundt dma_configure_channel(channel->vchan, config); 881da177e4SLinus Torvalds 891da177e4SLinus Torvalds return count; 901da177e4SLinus Torvalds } 911da177e4SLinus Torvalds 92*dc6876a2SKay Sievers static DEVICE_ATTR(config, S_IWUSR, NULL, dma_store_config); 931da177e4SLinus Torvalds 94*dc6876a2SKay Sievers static ssize_t dma_show_mode(struct device *dev, 95*dc6876a2SKay Sievers struct device_attribute *attr, char *buf) 961da177e4SLinus Torvalds { 971da177e4SLinus Torvalds struct dma_channel *channel = to_dma_channel(dev); 981da177e4SLinus Torvalds return sprintf(buf, "0x%08x\n", channel->mode); 991da177e4SLinus Torvalds } 1001da177e4SLinus Torvalds 101*dc6876a2SKay Sievers static ssize_t dma_store_mode(struct device *dev, 102*dc6876a2SKay Sievers struct device_attribute *attr, 1031da177e4SLinus Torvalds const char *buf, size_t count) 1041da177e4SLinus Torvalds { 1051da177e4SLinus Torvalds struct dma_channel *channel = to_dma_channel(dev); 1061da177e4SLinus Torvalds channel->mode = simple_strtoul(buf, NULL, 0); 1071da177e4SLinus Torvalds return count; 1081da177e4SLinus Torvalds } 1091da177e4SLinus Torvalds 110*dc6876a2SKay Sievers static DEVICE_ATTR(mode, S_IRUGO | S_IWUSR, dma_show_mode, dma_store_mode); 1111da177e4SLinus Torvalds 1121da177e4SLinus Torvalds #define dma_ro_attr(field, fmt) \ 113*dc6876a2SKay Sievers static ssize_t dma_show_##field(struct device *dev, \ 114*dc6876a2SKay Sievers struct device_attribute *attr, char *buf)\ 1151da177e4SLinus Torvalds { \ 1161da177e4SLinus Torvalds struct dma_channel *channel = to_dma_channel(dev); \ 1171da177e4SLinus Torvalds return sprintf(buf, fmt, channel->field); \ 1181da177e4SLinus Torvalds } \ 119*dc6876a2SKay Sievers static DEVICE_ATTR(field, S_IRUGO, dma_show_##field, NULL); 1201da177e4SLinus Torvalds 1211da177e4SLinus Torvalds dma_ro_attr(count, "0x%08x\n"); 1221da177e4SLinus Torvalds dma_ro_attr(flags, "0x%08lx\n"); 1231da177e4SLinus Torvalds 1240d831770SPaul Mundt int dma_create_sysfs_files(struct dma_channel *chan, struct dma_info *info) 1251da177e4SLinus Torvalds { 126*dc6876a2SKay Sievers struct device *dev = &chan->dev; 1270d831770SPaul Mundt char name[16]; 1281da177e4SLinus Torvalds int ret; 1291da177e4SLinus Torvalds 1300d831770SPaul Mundt dev->id = chan->vchan; 131*dc6876a2SKay Sievers dev->bus = &dma_subsys; 1321da177e4SLinus Torvalds 133*dc6876a2SKay Sievers ret = device_register(dev); 1341da177e4SLinus Torvalds if (ret) 1351da177e4SLinus Torvalds return ret; 1361da177e4SLinus Torvalds 137*dc6876a2SKay Sievers ret |= device_create_file(dev, &dev_attr_dev_id); 138*dc6876a2SKay Sievers ret |= device_create_file(dev, &dev_attr_count); 139*dc6876a2SKay Sievers ret |= device_create_file(dev, &dev_attr_mode); 140*dc6876a2SKay Sievers ret |= device_create_file(dev, &dev_attr_flags); 141*dc6876a2SKay Sievers ret |= device_create_file(dev, &dev_attr_config); 1424dfc119fSPaul Mundt 1434dfc119fSPaul Mundt if (unlikely(ret)) { 1444dfc119fSPaul Mundt dev_err(&info->pdev->dev, "Failed creating attrs\n"); 1454dfc119fSPaul Mundt return ret; 1464dfc119fSPaul Mundt } 1471da177e4SLinus Torvalds 1480d831770SPaul Mundt snprintf(name, sizeof(name), "dma%d", chan->chan); 1490d831770SPaul Mundt return sysfs_create_link(&info->pdev->dev.kobj, &dev->kobj, name); 1500d831770SPaul Mundt } 1510d831770SPaul Mundt 1520d831770SPaul Mundt void dma_remove_sysfs_files(struct dma_channel *chan, struct dma_info *info) 1530d831770SPaul Mundt { 154*dc6876a2SKay Sievers struct device *dev = &chan->dev; 1550d831770SPaul Mundt char name[16]; 1560d831770SPaul Mundt 157*dc6876a2SKay Sievers device_remove_file(dev, &dev_attr_dev_id); 158*dc6876a2SKay Sievers device_remove_file(dev, &dev_attr_count); 159*dc6876a2SKay Sievers device_remove_file(dev, &dev_attr_mode); 160*dc6876a2SKay Sievers device_remove_file(dev, &dev_attr_flags); 161*dc6876a2SKay Sievers device_remove_file(dev, &dev_attr_config); 1620d831770SPaul Mundt 1630d831770SPaul Mundt snprintf(name, sizeof(name), "dma%d", chan->chan); 1640d831770SPaul Mundt sysfs_remove_link(&info->pdev->dev.kobj, name); 1650d831770SPaul Mundt 166*dc6876a2SKay Sievers device_unregister(dev); 1671da177e4SLinus Torvalds } 168