1/* 2 * 3 * arch/arm/mach-u300/padmux.c 4 * 5 * 6 * Copyright (C) 2009 ST-Ericsson AB 7 * License terms: GNU General Public License (GPL) version 2 8 * U300 PADMUX functions 9 * Author: Martin Persson <martin.persson@stericsson.com> 10 */ 11 12#include <linux/module.h> 13#include <linux/kernel.h> 14#include <linux/device.h> 15#include <linux/err.h> 16#include <linux/errno.h> 17#include <linux/io.h> 18#include <linux/mutex.h> 19#include <linux/string.h> 20#include <linux/bug.h> 21#include <linux/debugfs.h> 22#include <linux/seq_file.h> 23#include <mach/u300-regs.h> 24#include <mach/syscon.h> 25#include "padmux.h" 26 27static DEFINE_MUTEX(pmx_mutex); 28 29const u32 pmx_registers[] = { 30 (U300_SYSCON_VBASE + U300_SYSCON_PMC1LR), 31 (U300_SYSCON_VBASE + U300_SYSCON_PMC1HR), 32 (U300_SYSCON_VBASE + U300_SYSCON_PMC2R), 33 (U300_SYSCON_VBASE + U300_SYSCON_PMC3R), 34 (U300_SYSCON_VBASE + U300_SYSCON_PMC4R) 35}; 36 37/* High level functionality */ 38 39/* Lazy dog: 40 * onmask = { 41 * {"PMC1LR" mask, "PMC1LR" value}, 42 * {"PMC1HR" mask, "PMC1HR" value}, 43 * {"PMC2R" mask, "PMC2R" value}, 44 * {"PMC3R" mask, "PMC3R" value}, 45 * {"PMC4R" mask, "PMC4R" value} 46 * } 47 */ 48static struct pmx mmc_setting = { 49 .setting = U300_APP_PMX_MMC_SETTING, 50 .default_on = false, 51 .activated = false, 52 .name = "MMC", 53 .onmask = { 54 {U300_SYSCON_PMC1LR_MMCSD_MASK, 55 U300_SYSCON_PMC1LR_MMCSD_MMCSD}, 56 {0, 0}, 57 {0, 0}, 58 {0, 0}, 59 {U300_SYSCON_PMC4R_APP_MISC_12_MASK, 60 U300_SYSCON_PMC4R_APP_MISC_12_APP_GPIO} 61 }, 62}; 63 64static struct pmx spi_setting = { 65 .setting = U300_APP_PMX_SPI_SETTING, 66 .default_on = false, 67 .activated = false, 68 .name = "SPI", 69 .onmask = {{0, 0}, 70 {U300_SYSCON_PMC1HR_APP_SPI_2_MASK | 71 U300_SYSCON_PMC1HR_APP_SPI_CS_1_MASK | 72 U300_SYSCON_PMC1HR_APP_SPI_CS_2_MASK, 73 U300_SYSCON_PMC1HR_APP_SPI_2_SPI | 74 U300_SYSCON_PMC1HR_APP_SPI_CS_1_SPI | 75 U300_SYSCON_PMC1HR_APP_SPI_CS_2_SPI}, 76 {0, 0}, 77 {0, 0}, 78 {0, 0} 79 }, 80}; 81 82/* Available padmux settings */ 83static struct pmx *pmx_settings[] = { 84 &mmc_setting, 85 &spi_setting, 86}; 87 88static void update_registers(struct pmx *pmx, bool activate) 89{ 90 u16 regval, val, mask; 91 int i; 92 93 for (i = 0; i < ARRAY_SIZE(pmx_registers); i++) { 94 if (activate) 95 val = pmx->onmask[i].val; 96 else 97 val = 0; 98 99 mask = pmx->onmask[i].mask; 100 if (mask != 0) { 101 regval = readw(pmx_registers[i]); 102 regval &= ~mask; 103 regval |= val; 104 writew(regval, pmx_registers[i]); 105 } 106 } 107} 108 109struct pmx *pmx_get(struct device *dev, enum pmx_settings setting) 110{ 111 int i; 112 struct pmx *pmx = ERR_PTR(-ENOENT); 113 114 if (dev == NULL) 115 return ERR_PTR(-EINVAL); 116 117 mutex_lock(&pmx_mutex); 118 for (i = 0; i < ARRAY_SIZE(pmx_settings); i++) { 119 120 if (setting == pmx_settings[i]->setting) { 121 122 if (pmx_settings[i]->dev != NULL) { 123 WARN(1, "padmux: required setting " 124 "in use by another consumer\n"); 125 } else { 126 pmx = pmx_settings[i]; 127 pmx->dev = dev; 128 dev_dbg(dev, "padmux: setting nr %d is now " 129 "bound to %s and ready to use\n", 130 setting, dev_name(dev)); 131 break; 132 } 133 } 134 } 135 mutex_unlock(&pmx_mutex); 136 137 return pmx; 138} 139EXPORT_SYMBOL(pmx_get); 140 141int pmx_put(struct device *dev, struct pmx *pmx) 142{ 143 int i; 144 int ret = -ENOENT; 145 146 if (pmx == NULL || dev == NULL) 147 return -EINVAL; 148 149 mutex_lock(&pmx_mutex); 150 for (i = 0; i < ARRAY_SIZE(pmx_settings); i++) { 151 152 if (pmx->setting == pmx_settings[i]->setting) { 153 154 if (dev != pmx->dev) { 155 WARN(1, "padmux: cannot release handle as " 156 "it is bound to another consumer\n"); 157 ret = -EINVAL; 158 break; 159 } else { 160 pmx_settings[i]->dev = NULL; 161 ret = 0; 162 break; 163 } 164 } 165 } 166 mutex_unlock(&pmx_mutex); 167 168 return ret; 169} 170EXPORT_SYMBOL(pmx_put); 171 172int pmx_activate(struct device *dev, struct pmx *pmx) 173{ 174 int i, j, ret; 175 ret = 0; 176 177 if (pmx == NULL || dev == NULL) 178 return -EINVAL; 179 180 mutex_lock(&pmx_mutex); 181 182 /* Make sure the required bits are not used */ 183 for (i = 0; i < ARRAY_SIZE(pmx_settings); i++) { 184 185 if (pmx_settings[i]->dev == NULL || pmx_settings[i] == pmx) 186 continue; 187 188 for (j = 0; j < ARRAY_SIZE(pmx_registers); j++) { 189 190 if (pmx_settings[i]->onmask[j].mask & pmx-> 191 onmask[j].mask) { 192 /* More than one entry on the same bits */ 193 WARN(1, "padmux: cannot activate " 194 "setting. Bit conflict with " 195 "an active setting\n"); 196 197 ret = -EUSERS; 198 goto exit; 199 } 200 } 201 } 202 update_registers(pmx, true); 203 pmx->activated = true; 204 dev_dbg(dev, "padmux: setting nr %d is activated\n", 205 pmx->setting); 206 207exit: 208 mutex_unlock(&pmx_mutex); 209 return ret; 210} 211EXPORT_SYMBOL(pmx_activate); 212 213int pmx_deactivate(struct device *dev, struct pmx *pmx) 214{ 215 int i; 216 int ret = -ENOENT; 217 218 if (pmx == NULL || dev == NULL) 219 return -EINVAL; 220 221 mutex_lock(&pmx_mutex); 222 for (i = 0; i < ARRAY_SIZE(pmx_settings); i++) { 223 224 if (pmx_settings[i]->dev == NULL) 225 continue; 226 227 if (pmx->setting == pmx_settings[i]->setting) { 228 229 if (dev != pmx->dev) { 230 WARN(1, "padmux: cannot deactivate " 231 "pmx setting as it was activated " 232 "by another consumer\n"); 233 234 ret = -EBUSY; 235 continue; 236 } else { 237 update_registers(pmx, false); 238 pmx_settings[i]->dev = NULL; 239 pmx->activated = false; 240 ret = 0; 241 dev_dbg(dev, "padmux: setting nr %d is deactivated", 242 pmx->setting); 243 break; 244 } 245 } 246 } 247 mutex_unlock(&pmx_mutex); 248 249 return ret; 250} 251EXPORT_SYMBOL(pmx_deactivate); 252 253/* 254 * For internal use only. If it is to be exported, 255 * it should be reentrant. Notice that pmx_activate 256 * (i.e. runtime settings) always override default settings. 257 */ 258static int pmx_set_default(void) 259{ 260 /* Used to identify several entries on the same bits */ 261 u16 modbits[ARRAY_SIZE(pmx_registers)]; 262 263 int i, j; 264 265 memset(modbits, 0, ARRAY_SIZE(pmx_registers) * sizeof(u16)); 266 267 for (i = 0; i < ARRAY_SIZE(pmx_settings); i++) { 268 269 if (!pmx_settings[i]->default_on) 270 continue; 271 272 for (j = 0; j < ARRAY_SIZE(pmx_registers); j++) { 273 274 /* Make sure there is only one entry on the same bits */ 275 if (modbits[j] & pmx_settings[i]->onmask[j].mask) { 276 BUG(); 277 return -EUSERS; 278 } 279 modbits[j] |= pmx_settings[i]->onmask[j].mask; 280 } 281 update_registers(pmx_settings[i], true); 282 } 283 return 0; 284} 285 286#if (defined(CONFIG_DEBUG_FS) && defined(CONFIG_U300_DEBUG)) 287static int pmx_show(struct seq_file *s, void *data) 288{ 289 int i; 290 seq_printf(s, "-------------------------------------------------\n"); 291 seq_printf(s, "SETTING BOUND TO DEVICE STATE\n"); 292 seq_printf(s, "-------------------------------------------------\n"); 293 mutex_lock(&pmx_mutex); 294 for (i = 0; i < ARRAY_SIZE(pmx_settings); i++) { 295 /* Format pmx and device name nicely */ 296 char cdp[33]; 297 int chars; 298 299 chars = snprintf(&cdp[0], 17, "%s", pmx_settings[i]->name); 300 while (chars < 16) { 301 cdp[chars] = ' '; 302 chars++; 303 } 304 chars = snprintf(&cdp[16], 17, "%s", pmx_settings[i]->dev ? 305 dev_name(pmx_settings[i]->dev) : "N/A"); 306 while (chars < 16) { 307 cdp[chars+16] = ' '; 308 chars++; 309 } 310 cdp[32] = '\0'; 311 312 seq_printf(s, 313 "%s\t%s\n", 314 &cdp[0], 315 pmx_settings[i]->activated ? 316 "ACTIVATED" : "DEACTIVATED" 317 ); 318 319 } 320 mutex_unlock(&pmx_mutex); 321 return 0; 322} 323 324static int pmx_open(struct inode *inode, struct file *file) 325{ 326 return single_open(file, pmx_show, NULL); 327} 328 329static const struct file_operations pmx_operations = { 330 .owner = THIS_MODULE, 331 .open = pmx_open, 332 .read = seq_read, 333 .llseek = seq_lseek, 334 .release = single_release, 335}; 336 337static int __init init_pmx_read_debugfs(void) 338{ 339 /* Expose a simple debugfs interface to view pmx settings */ 340 (void) debugfs_create_file("padmux", S_IFREG | S_IRUGO, 341 NULL, NULL, 342 &pmx_operations); 343 return 0; 344} 345 346/* 347 * This needs to come in after the core_initcall(), 348 * because debugfs is not available until 349 * the subsystems come up. 350 */ 351module_init(init_pmx_read_debugfs); 352#endif 353 354static int __init pmx_init(void) 355{ 356 int ret; 357 358 ret = pmx_set_default(); 359 360 if (IS_ERR_VALUE(ret)) 361 pr_crit("padmux: default settings could not be set\n"); 362 363 return 0; 364} 365 366/* Should be initialized before consumers */ 367core_initcall(pmx_init); 368