1b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen/* 2b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen * linux/drivers/video/omap2/omapfb-sysfs.c 3b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen * 4b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen * Copyright (C) 2008 Nokia Corporation 5b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com> 6b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen * 7b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen * Some code and ideas taken from drivers/video/omap/ driver 8b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen * by Imre Deak. 9b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen * 10b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen * This program is free software; you can redistribute it and/or modify it 11b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen * under the terms of the GNU General Public License version 2 as published by 12b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen * the Free Software Foundation. 13b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen * 14b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen * This program is distributed in the hope that it will be useful, but WITHOUT 15b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 16b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 17b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen * more details. 18b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen * 19b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen * You should have received a copy of the GNU General Public License along with 20b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen * this program. If not, see <http://www.gnu.org/licenses/>. 21b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen */ 22b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 23b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen#include <linux/fb.h> 24b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen#include <linux/sysfs.h> 25b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen#include <linux/device.h> 26b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen#include <linux/uaccess.h> 27b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen#include <linux/platform_device.h> 28b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen#include <linux/kernel.h> 29b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen#include <linux/mm.h> 30b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen#include <linux/omapfb.h> 31b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 32a0b38cc4d35e095f14ab0f486135f8a619ebfc14Tomi Valkeinen#include <video/omapdss.h> 33b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen#include <plat/vrfb.h> 34b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 35b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen#include "omapfb.h" 36b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 37b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenstatic ssize_t show_rotate_type(struct device *dev, 38b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct device_attribute *attr, char *buf) 39b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen{ 40b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct fb_info *fbi = dev_get_drvdata(dev); 41b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct omapfb_info *ofbi = FB2OFB(fbi); 42b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 43b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return snprintf(buf, PAGE_SIZE, "%d\n", ofbi->rotation_type); 44b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen} 45b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 46b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenstatic ssize_t store_rotate_type(struct device *dev, 47b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct device_attribute *attr, 48b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen const char *buf, size_t count) 49b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen{ 50b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct fb_info *fbi = dev_get_drvdata(dev); 51b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct omapfb_info *ofbi = FB2OFB(fbi); 52430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä struct omapfb2_mem_region *rg; 53e3502ce97f2d2d183735d9fae76b081a634ffd85Tomi Valkeinen int rot_type; 54b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen int r; 55b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 56e3502ce97f2d2d183735d9fae76b081a634ffd85Tomi Valkeinen r = kstrtoint(buf, 0, &rot_type); 57e3502ce97f2d2d183735d9fae76b081a634ffd85Tomi Valkeinen if (r) 58e3502ce97f2d2d183735d9fae76b081a634ffd85Tomi Valkeinen return r; 59b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 60b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (rot_type != OMAP_DSS_ROT_DMA && rot_type != OMAP_DSS_ROT_VRFB) 61b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return -EINVAL; 62b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 6327b67c92a30967e3a9e9ea082d4ca4bc6882f879Jani Nikula if (!lock_fb_info(fbi)) 6427b67c92a30967e3a9e9ea082d4ca4bc6882f879Jani Nikula return -ENODEV; 65b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 66b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen r = 0; 67b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (rot_type == ofbi->rotation_type) 68b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen goto out; 69b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 70430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä rg = omapfb_get_mem_region(ofbi->region); 71430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä 72430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä if (rg->size) { 73b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen r = -EBUSY; 74430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä goto put_region; 75b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 76b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 77b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen ofbi->rotation_type = rot_type; 78b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 79b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen /* 80b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen * Since the VRAM for this FB is not allocated at the moment we don't 81b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen * need to do any further parameter checking at this point. 82b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen */ 83430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjäläput_region: 84430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä omapfb_put_mem_region(rg); 85b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenout: 86b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen unlock_fb_info(fbi); 87b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 88b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return r ? r : count; 89b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen} 90b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 91b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 92b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenstatic ssize_t show_mirror(struct device *dev, 93b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct device_attribute *attr, char *buf) 94b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen{ 95b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct fb_info *fbi = dev_get_drvdata(dev); 96b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct omapfb_info *ofbi = FB2OFB(fbi); 97b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 98b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return snprintf(buf, PAGE_SIZE, "%d\n", ofbi->mirror); 99b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen} 100b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 101b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenstatic ssize_t store_mirror(struct device *dev, 102b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct device_attribute *attr, 103b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen const char *buf, size_t count) 104b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen{ 105b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct fb_info *fbi = dev_get_drvdata(dev); 106b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct omapfb_info *ofbi = FB2OFB(fbi); 1077fbf1bb02d1005203e39ca7bd7aa7afcd2909c4bTomi Valkeinen bool mirror; 108b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen int r; 109b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct fb_var_screeninfo new_var; 110b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1117fbf1bb02d1005203e39ca7bd7aa7afcd2909c4bTomi Valkeinen r = strtobool(buf, &mirror); 112e3502ce97f2d2d183735d9fae76b081a634ffd85Tomi Valkeinen if (r) 113e3502ce97f2d2d183735d9fae76b081a634ffd85Tomi Valkeinen return r; 114b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 11527b67c92a30967e3a9e9ea082d4ca4bc6882f879Jani Nikula if (!lock_fb_info(fbi)) 11627b67c92a30967e3a9e9ea082d4ca4bc6882f879Jani Nikula return -ENODEV; 117b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 118b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen ofbi->mirror = mirror; 119b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 120430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä omapfb_get_mem_region(ofbi->region); 121430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä 122b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen memcpy(&new_var, &fbi->var, sizeof(new_var)); 123b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen r = check_fb_var(fbi, &new_var); 124b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (r) 125b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen goto out; 126b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen memcpy(&fbi->var, &new_var, sizeof(fbi->var)); 127b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 128b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen set_fb_fix(fbi); 129b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 130b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen r = omapfb_apply_changes(fbi, 0); 131b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (r) 132b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen goto out; 133b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 134b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen r = count; 135b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenout: 136430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä omapfb_put_mem_region(ofbi->region); 137430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä 138b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen unlock_fb_info(fbi); 139b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 140b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return r; 141b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen} 142b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 143b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenstatic ssize_t show_overlays(struct device *dev, 144b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct device_attribute *attr, char *buf) 145b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen{ 146b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct fb_info *fbi = dev_get_drvdata(dev); 147b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct omapfb_info *ofbi = FB2OFB(fbi); 148b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct omapfb2_device *fbdev = ofbi->fbdev; 149b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen ssize_t l = 0; 150b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen int t; 151b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 15227b67c92a30967e3a9e9ea082d4ca4bc6882f879Jani Nikula if (!lock_fb_info(fbi)) 15327b67c92a30967e3a9e9ea082d4ca4bc6882f879Jani Nikula return -ENODEV; 154238a41329ca208d1170962260babb428b6e222c2Jani Nikula omapfb_lock(fbdev); 155b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 156b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen for (t = 0; t < ofbi->num_overlays; t++) { 157b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct omap_overlay *ovl = ofbi->overlays[t]; 158b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen int ovlnum; 159b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 160b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen for (ovlnum = 0; ovlnum < fbdev->num_overlays; ++ovlnum) 161b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (ovl == fbdev->overlays[ovlnum]) 162b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen break; 163b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 164b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen l += snprintf(buf + l, PAGE_SIZE - l, "%s%d", 165b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen t == 0 ? "" : ",", ovlnum); 166b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 167b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 168b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen l += snprintf(buf + l, PAGE_SIZE - l, "\n"); 169b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 170b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen omapfb_unlock(fbdev); 171238a41329ca208d1170962260babb428b6e222c2Jani Nikula unlock_fb_info(fbi); 172b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 173b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return l; 174b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen} 175b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 176b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenstatic struct omapfb_info *get_overlay_fb(struct omapfb2_device *fbdev, 177b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct omap_overlay *ovl) 178b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen{ 179b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen int i, t; 180b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 181b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen for (i = 0; i < fbdev->num_fbs; i++) { 182b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct omapfb_info *ofbi = FB2OFB(fbdev->fbs[i]); 183b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 184b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen for (t = 0; t < ofbi->num_overlays; t++) { 185b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (ofbi->overlays[t] == ovl) 186b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return ofbi; 187b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 188b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 189b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 190b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return NULL; 191b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen} 192b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 193b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenstatic ssize_t store_overlays(struct device *dev, struct device_attribute *attr, 194b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen const char *buf, size_t count) 195b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen{ 196b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct fb_info *fbi = dev_get_drvdata(dev); 197b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct omapfb_info *ofbi = FB2OFB(fbi); 198b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct omapfb2_device *fbdev = ofbi->fbdev; 199b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct omap_overlay *ovls[OMAPFB_MAX_OVL_PER_FB]; 200b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct omap_overlay *ovl; 201b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen int num_ovls, r, i; 202b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen int len; 203b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen bool added = false; 204b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 205b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen num_ovls = 0; 206b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 207b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen len = strlen(buf); 208b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (buf[len - 1] == '\n') 209b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen len = len - 1; 210b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 21127b67c92a30967e3a9e9ea082d4ca4bc6882f879Jani Nikula if (!lock_fb_info(fbi)) 21227b67c92a30967e3a9e9ea082d4ca4bc6882f879Jani Nikula return -ENODEV; 213238a41329ca208d1170962260babb428b6e222c2Jani Nikula omapfb_lock(fbdev); 214b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 215b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (len > 0) { 216b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen char *p = (char *)buf; 217b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen int ovlnum; 218b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 219b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen while (p < buf + len) { 220b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen int found; 221b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (num_ovls == OMAPFB_MAX_OVL_PER_FB) { 222b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen r = -EINVAL; 223b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen goto out; 224b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 225b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 226b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen ovlnum = simple_strtoul(p, &p, 0); 227b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (ovlnum > fbdev->num_overlays) { 228b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen r = -EINVAL; 229b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen goto out; 230b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 231b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 232b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen found = 0; 233b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen for (i = 0; i < num_ovls; ++i) { 234b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (ovls[i] == fbdev->overlays[ovlnum]) { 235b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen found = 1; 236b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen break; 237b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 238b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 239b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 240b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (!found) 241b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen ovls[num_ovls++] = fbdev->overlays[ovlnum]; 242b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 243b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen p++; 244b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 245b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 246b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 247b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen for (i = 0; i < num_ovls; ++i) { 248b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct omapfb_info *ofbi2 = get_overlay_fb(fbdev, ovls[i]); 249b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (ofbi2 && ofbi2 != ofbi) { 250b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen dev_err(fbdev->dev, "overlay already in use\n"); 251b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen r = -EINVAL; 252b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen goto out; 253b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 254b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 255b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 256b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen /* detach unused overlays */ 257b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen for (i = 0; i < ofbi->num_overlays; ++i) { 258b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen int t, found; 259b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 260b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen ovl = ofbi->overlays[i]; 261b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 262b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen found = 0; 263b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 264b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen for (t = 0; t < num_ovls; ++t) { 265b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (ovl == ovls[t]) { 266b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen found = 1; 267b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen break; 268b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 269b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 270b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 271b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (found) 272b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen continue; 273b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 274b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen DBG("detaching %d\n", ofbi->overlays[i]->id); 275b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 276430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä omapfb_get_mem_region(ofbi->region); 277430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä 278b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen omapfb_overlay_enable(ovl, 0); 279b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 280b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (ovl->manager) 281b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen ovl->manager->apply(ovl->manager); 282b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 283430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä omapfb_put_mem_region(ofbi->region); 284430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä 285b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen for (t = i + 1; t < ofbi->num_overlays; t++) { 286b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen ofbi->rotation[t-1] = ofbi->rotation[t]; 287b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen ofbi->overlays[t-1] = ofbi->overlays[t]; 288b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 289b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 290b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen ofbi->num_overlays--; 291b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen i--; 292b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 293b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 294b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen for (i = 0; i < num_ovls; ++i) { 295b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen int t, found; 296b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 297b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen ovl = ovls[i]; 298b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 299b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen found = 0; 300b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 301b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen for (t = 0; t < ofbi->num_overlays; ++t) { 302b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (ovl == ofbi->overlays[t]) { 303b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen found = 1; 304b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen break; 305b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 306b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 307b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 308b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (found) 309b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen continue; 310b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen ofbi->rotation[ofbi->num_overlays] = 0; 311b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen ofbi->overlays[ofbi->num_overlays++] = ovl; 312b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 313b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen added = true; 314b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 315b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 316b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (added) { 317430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä omapfb_get_mem_region(ofbi->region); 318430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä 319b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen r = omapfb_apply_changes(fbi, 0); 320430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä 321430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä omapfb_put_mem_region(ofbi->region); 322430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä 323b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (r) 324b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen goto out; 325b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 326b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 327b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen r = count; 328b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenout: 329b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen omapfb_unlock(fbdev); 330238a41329ca208d1170962260babb428b6e222c2Jani Nikula unlock_fb_info(fbi); 331b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 332b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return r; 333b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen} 334b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 335b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenstatic ssize_t show_overlays_rotate(struct device *dev, 336b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct device_attribute *attr, char *buf) 337b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen{ 338b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct fb_info *fbi = dev_get_drvdata(dev); 339b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct omapfb_info *ofbi = FB2OFB(fbi); 340b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen ssize_t l = 0; 341b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen int t; 342b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 34327b67c92a30967e3a9e9ea082d4ca4bc6882f879Jani Nikula if (!lock_fb_info(fbi)) 34427b67c92a30967e3a9e9ea082d4ca4bc6882f879Jani Nikula return -ENODEV; 345b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 346b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen for (t = 0; t < ofbi->num_overlays; t++) { 347b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen l += snprintf(buf + l, PAGE_SIZE - l, "%s%d", 348b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen t == 0 ? "" : ",", ofbi->rotation[t]); 349b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 350b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 351b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen l += snprintf(buf + l, PAGE_SIZE - l, "\n"); 352b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 353b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen unlock_fb_info(fbi); 354b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 355b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return l; 356b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen} 357b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 358b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenstatic ssize_t store_overlays_rotate(struct device *dev, 359b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct device_attribute *attr, const char *buf, size_t count) 360b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen{ 361b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct fb_info *fbi = dev_get_drvdata(dev); 362b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct omapfb_info *ofbi = FB2OFB(fbi); 363b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen int num_ovls = 0, r, i; 364b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen int len; 365b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen bool changed = false; 366b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen u8 rotation[OMAPFB_MAX_OVL_PER_FB]; 367b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 368b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen len = strlen(buf); 369b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (buf[len - 1] == '\n') 370b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen len = len - 1; 371b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 37227b67c92a30967e3a9e9ea082d4ca4bc6882f879Jani Nikula if (!lock_fb_info(fbi)) 37327b67c92a30967e3a9e9ea082d4ca4bc6882f879Jani Nikula return -ENODEV; 374b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 375b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (len > 0) { 376b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen char *p = (char *)buf; 377b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 378b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen while (p < buf + len) { 379b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen int rot; 380b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 381b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (num_ovls == ofbi->num_overlays) { 382b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen r = -EINVAL; 383b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen goto out; 384b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 385b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 386b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen rot = simple_strtoul(p, &p, 0); 387b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (rot < 0 || rot > 3) { 388b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen r = -EINVAL; 389b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen goto out; 390b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 391b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 392b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (ofbi->rotation[num_ovls] != rot) 393b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen changed = true; 394b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 395b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen rotation[num_ovls++] = rot; 396b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 397b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen p++; 398b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 399b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 400b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 401b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (num_ovls != ofbi->num_overlays) { 402b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen r = -EINVAL; 403b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen goto out; 404b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 405b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 406b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (changed) { 407b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen for (i = 0; i < num_ovls; ++i) 408b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen ofbi->rotation[i] = rotation[i]; 409b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 410430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä omapfb_get_mem_region(ofbi->region); 411430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä 412b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen r = omapfb_apply_changes(fbi, 0); 413430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä 414430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä omapfb_put_mem_region(ofbi->region); 415430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä 416b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (r) 417b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen goto out; 418b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 419b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen /* FIXME error handling? */ 420b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 421b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 422b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen r = count; 423b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenout: 424b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen unlock_fb_info(fbi); 425b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 426b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return r; 427b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen} 428b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 429b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenstatic ssize_t show_size(struct device *dev, 430b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct device_attribute *attr, char *buf) 431b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen{ 432b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct fb_info *fbi = dev_get_drvdata(dev); 433b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct omapfb_info *ofbi = FB2OFB(fbi); 434b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 435078ff546a806b2c2ab74c25c8edd4c6d4680656aVille Syrjälä return snprintf(buf, PAGE_SIZE, "%lu\n", ofbi->region->size); 436b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen} 437b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 438b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenstatic ssize_t store_size(struct device *dev, struct device_attribute *attr, 439b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen const char *buf, size_t count) 440b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen{ 441b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct fb_info *fbi = dev_get_drvdata(dev); 442b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct omapfb_info *ofbi = FB2OFB(fbi); 443078ff546a806b2c2ab74c25c8edd4c6d4680656aVille Syrjälä struct omapfb2_device *fbdev = ofbi->fbdev; 444078ff546a806b2c2ab74c25c8edd4c6d4680656aVille Syrjälä struct omapfb2_mem_region *rg; 445b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen unsigned long size; 446b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen int r; 447b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen int i; 448b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 449e3502ce97f2d2d183735d9fae76b081a634ffd85Tomi Valkeinen r = kstrtoul(buf, 0, &size); 450e3502ce97f2d2d183735d9fae76b081a634ffd85Tomi Valkeinen if (r) 451e3502ce97f2d2d183735d9fae76b081a634ffd85Tomi Valkeinen return r; 452e3502ce97f2d2d183735d9fae76b081a634ffd85Tomi Valkeinen 453e3502ce97f2d2d183735d9fae76b081a634ffd85Tomi Valkeinen size = PAGE_ALIGN(size); 454b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 45527b67c92a30967e3a9e9ea082d4ca4bc6882f879Jani Nikula if (!lock_fb_info(fbi)) 45627b67c92a30967e3a9e9ea082d4ca4bc6882f879Jani Nikula return -ENODEV; 457b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 458078ff546a806b2c2ab74c25c8edd4c6d4680656aVille Syrjälä rg = ofbi->region; 459078ff546a806b2c2ab74c25c8edd4c6d4680656aVille Syrjälä 4603d84b65aa63833a2ac07b1cc626984a1e1485fedVille Syrjälä down_write_nested(&rg->lock, rg->id); 4611ceafc00910439c8e5450fae189b69427725992cVille Syrjälä atomic_inc(&rg->lock_count); 462430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä 463078ff546a806b2c2ab74c25c8edd4c6d4680656aVille Syrjälä if (atomic_read(&rg->map_count)) { 464078ff546a806b2c2ab74c25c8edd4c6d4680656aVille Syrjälä r = -EBUSY; 465078ff546a806b2c2ab74c25c8edd4c6d4680656aVille Syrjälä goto out; 466078ff546a806b2c2ab74c25c8edd4c6d4680656aVille Syrjälä } 467078ff546a806b2c2ab74c25c8edd4c6d4680656aVille Syrjälä 468078ff546a806b2c2ab74c25c8edd4c6d4680656aVille Syrjälä for (i = 0; i < fbdev->num_fbs; i++) { 469078ff546a806b2c2ab74c25c8edd4c6d4680656aVille Syrjälä struct omapfb_info *ofbi2 = FB2OFB(fbdev->fbs[i]); 470078ff546a806b2c2ab74c25c8edd4c6d4680656aVille Syrjälä int j; 471078ff546a806b2c2ab74c25c8edd4c6d4680656aVille Syrjälä 472078ff546a806b2c2ab74c25c8edd4c6d4680656aVille Syrjälä if (ofbi2->region != rg) 473078ff546a806b2c2ab74c25c8edd4c6d4680656aVille Syrjälä continue; 474078ff546a806b2c2ab74c25c8edd4c6d4680656aVille Syrjälä 475078ff546a806b2c2ab74c25c8edd4c6d4680656aVille Syrjälä for (j = 0; j < ofbi2->num_overlays; j++) { 476aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen struct omap_overlay *ovl; 477aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen ovl = ofbi2->overlays[j]; 478aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen if (ovl->is_enabled(ovl)) { 479078ff546a806b2c2ab74c25c8edd4c6d4680656aVille Syrjälä r = -EBUSY; 480078ff546a806b2c2ab74c25c8edd4c6d4680656aVille Syrjälä goto out; 481078ff546a806b2c2ab74c25c8edd4c6d4680656aVille Syrjälä } 482b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 483b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 484b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 485078ff546a806b2c2ab74c25c8edd4c6d4680656aVille Syrjälä if (size != ofbi->region->size) { 486078ff546a806b2c2ab74c25c8edd4c6d4680656aVille Syrjälä r = omapfb_realloc_fbmem(fbi, size, ofbi->region->type); 487b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (r) { 488b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen dev_err(dev, "realloc fbmem failed\n"); 489b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen goto out; 490b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 491b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 492b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 493b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen r = count; 494b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenout: 4951ceafc00910439c8e5450fae189b69427725992cVille Syrjälä atomic_dec(&rg->lock_count); 4962f642a17503838e256b8b7e9f1153512e2efc38bVille Syrjälä up_write(&rg->lock); 497430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä 498b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen unlock_fb_info(fbi); 499b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 500b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return r; 501b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen} 502b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 503b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenstatic ssize_t show_phys(struct device *dev, 504b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct device_attribute *attr, char *buf) 505b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen{ 506b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct fb_info *fbi = dev_get_drvdata(dev); 507b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct omapfb_info *ofbi = FB2OFB(fbi); 508b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 509078ff546a806b2c2ab74c25c8edd4c6d4680656aVille Syrjälä return snprintf(buf, PAGE_SIZE, "%0x\n", ofbi->region->paddr); 510b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen} 511b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 512b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenstatic ssize_t show_virt(struct device *dev, 513b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct device_attribute *attr, char *buf) 514b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen{ 515b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct fb_info *fbi = dev_get_drvdata(dev); 516b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct omapfb_info *ofbi = FB2OFB(fbi); 517b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 518078ff546a806b2c2ab74c25c8edd4c6d4680656aVille Syrjälä return snprintf(buf, PAGE_SIZE, "%p\n", ofbi->region->vaddr); 519b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen} 520b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 52127cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinenstatic ssize_t show_upd_mode(struct device *dev, 52227cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen struct device_attribute *attr, char *buf) 52327cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen{ 52427cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen struct fb_info *fbi = dev_get_drvdata(dev); 52527cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen enum omapfb_update_mode mode; 52627cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen int r; 52727cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen 52827cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen r = omapfb_get_update_mode(fbi, &mode); 52927cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen 53027cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen if (r) 53127cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen return r; 53227cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen 53327cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen return snprintf(buf, PAGE_SIZE, "%u\n", (unsigned)mode); 53427cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen} 53527cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen 53627cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinenstatic ssize_t store_upd_mode(struct device *dev, struct device_attribute *attr, 53727cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen const char *buf, size_t count) 53827cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen{ 53927cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen struct fb_info *fbi = dev_get_drvdata(dev); 54027cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen unsigned mode; 54127cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen int r; 54227cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen 54327cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen r = kstrtouint(buf, 0, &mode); 54427cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen if (r) 54527cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen return r; 54627cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen 54727cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen r = omapfb_set_update_mode(fbi, mode); 54827cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen if (r) 54927cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen return r; 55027cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen 55127cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen return count; 55227cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen} 55327cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen 554b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenstatic struct device_attribute omapfb_attrs[] = { 555b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen __ATTR(rotate_type, S_IRUGO | S_IWUSR, show_rotate_type, 556b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen store_rotate_type), 557b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen __ATTR(mirror, S_IRUGO | S_IWUSR, show_mirror, store_mirror), 558b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen __ATTR(size, S_IRUGO | S_IWUSR, show_size, store_size), 559b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen __ATTR(overlays, S_IRUGO | S_IWUSR, show_overlays, store_overlays), 560b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen __ATTR(overlays_rotate, S_IRUGO | S_IWUSR, show_overlays_rotate, 561b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen store_overlays_rotate), 562b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen __ATTR(phys_addr, S_IRUGO, show_phys, NULL), 563b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen __ATTR(virt_addr, S_IRUGO, show_virt, NULL), 56427cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen __ATTR(update_mode, S_IRUGO | S_IWUSR, show_upd_mode, store_upd_mode), 565b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen}; 566b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 567b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenint omapfb_create_sysfs(struct omapfb2_device *fbdev) 568b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen{ 569b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen int i; 570b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen int r; 571b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 572b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen DBG("create sysfs for fbs\n"); 573b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen for (i = 0; i < fbdev->num_fbs; i++) { 574b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen int t; 575b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen for (t = 0; t < ARRAY_SIZE(omapfb_attrs); t++) { 576b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen r = device_create_file(fbdev->fbs[i]->dev, 577b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen &omapfb_attrs[t]); 578b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 579b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (r) { 580b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen dev_err(fbdev->dev, "failed to create sysfs " 581b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen "file\n"); 582b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return r; 583b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 584b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 585b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 586b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 587b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return 0; 588b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen} 589b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 590b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenvoid omapfb_remove_sysfs(struct omapfb2_device *fbdev) 591b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen{ 592b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen int i, t; 593b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 594b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen DBG("remove sysfs for fbs\n"); 595b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen for (i = 0; i < fbdev->num_fbs; i++) { 596b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen for (t = 0; t < ARRAY_SIZE(omapfb_attrs); t++) 597b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen device_remove_file(fbdev->fbs[i]->dev, 598b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen &omapfb_attrs[t]); 599b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 600b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen} 601b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 602