0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #include <linux/init.h>
0014 #include <linux/export.h>
0015 #include <linux/kernel.h>
0016 #include <linux/compiler.h>
0017 #include <linux/spinlock.h>
0018 #include <linux/types.h>
0019 #include <linux/io.h>
0020 #include <linux/of.h>
0021 #include <linux/of_address.h>
0022 #include <linux/of_irq.h>
0023 #include <linux/slab.h>
0024 #include <linux/sched.h>
0025 #include <linux/platform_device.h>
0026 #include <linux/interrupt.h>
0027 #include <linux/mod_devicetable.h>
0028 #include <linux/syscore_ops.h>
0029 #include <asm/fsl_lbc.h>
0030
0031 static DEFINE_SPINLOCK(fsl_lbc_lock);
0032 struct fsl_lbc_ctrl *fsl_lbc_ctrl_dev;
0033 EXPORT_SYMBOL(fsl_lbc_ctrl_dev);
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044 u32 fsl_lbc_addr(phys_addr_t addr_base)
0045 {
0046 struct device_node *np = fsl_lbc_ctrl_dev->dev->of_node;
0047 u32 addr = addr_base & 0xffff8000;
0048
0049 if (of_device_is_compatible(np, "fsl,elbc"))
0050 return addr;
0051
0052 return addr | ((addr_base & 0x300000000ull) >> 19);
0053 }
0054 EXPORT_SYMBOL(fsl_lbc_addr);
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065 int fsl_lbc_find(phys_addr_t addr_base)
0066 {
0067 int i;
0068 struct fsl_lbc_regs __iomem *lbc;
0069
0070 if (!fsl_lbc_ctrl_dev || !fsl_lbc_ctrl_dev->regs)
0071 return -ENODEV;
0072
0073 lbc = fsl_lbc_ctrl_dev->regs;
0074 for (i = 0; i < ARRAY_SIZE(lbc->bank); i++) {
0075 u32 br = in_be32(&lbc->bank[i].br);
0076 u32 or = in_be32(&lbc->bank[i].or);
0077
0078 if (br & BR_V && (br & or & BR_BA) == fsl_lbc_addr(addr_base))
0079 return i;
0080 }
0081
0082 return -ENOENT;
0083 }
0084 EXPORT_SYMBOL(fsl_lbc_find);
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095 int fsl_upm_find(phys_addr_t addr_base, struct fsl_upm *upm)
0096 {
0097 int bank;
0098 u32 br;
0099 struct fsl_lbc_regs __iomem *lbc;
0100
0101 bank = fsl_lbc_find(addr_base);
0102 if (bank < 0)
0103 return bank;
0104
0105 if (!fsl_lbc_ctrl_dev || !fsl_lbc_ctrl_dev->regs)
0106 return -ENODEV;
0107
0108 lbc = fsl_lbc_ctrl_dev->regs;
0109 br = in_be32(&lbc->bank[bank].br);
0110
0111 switch (br & BR_MSEL) {
0112 case BR_MS_UPMA:
0113 upm->mxmr = &lbc->mamr;
0114 break;
0115 case BR_MS_UPMB:
0116 upm->mxmr = &lbc->mbmr;
0117 break;
0118 case BR_MS_UPMC:
0119 upm->mxmr = &lbc->mcmr;
0120 break;
0121 default:
0122 return -EINVAL;
0123 }
0124
0125 switch (br & BR_PS) {
0126 case BR_PS_8:
0127 upm->width = 8;
0128 break;
0129 case BR_PS_16:
0130 upm->width = 16;
0131 break;
0132 case BR_PS_32:
0133 upm->width = 32;
0134 break;
0135 default:
0136 return -EINVAL;
0137 }
0138
0139 return 0;
0140 }
0141 EXPORT_SYMBOL(fsl_upm_find);
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153 int fsl_upm_run_pattern(struct fsl_upm *upm, void __iomem *io_base, u32 mar)
0154 {
0155 int ret = 0;
0156 unsigned long flags;
0157
0158 if (!fsl_lbc_ctrl_dev || !fsl_lbc_ctrl_dev->regs)
0159 return -ENODEV;
0160
0161 spin_lock_irqsave(&fsl_lbc_lock, flags);
0162
0163 out_be32(&fsl_lbc_ctrl_dev->regs->mar, mar);
0164
0165 switch (upm->width) {
0166 case 8:
0167 out_8(io_base, 0x0);
0168 break;
0169 case 16:
0170 out_be16(io_base, 0x0);
0171 break;
0172 case 32:
0173 out_be32(io_base, 0x0);
0174 break;
0175 default:
0176 ret = -EINVAL;
0177 break;
0178 }
0179
0180 spin_unlock_irqrestore(&fsl_lbc_lock, flags);
0181
0182 return ret;
0183 }
0184 EXPORT_SYMBOL(fsl_upm_run_pattern);
0185
0186 static int fsl_lbc_ctrl_init(struct fsl_lbc_ctrl *ctrl,
0187 struct device_node *node)
0188 {
0189 struct fsl_lbc_regs __iomem *lbc = ctrl->regs;
0190
0191
0192 setbits32(&lbc->ltesr, LTESR_CLEAR);
0193 out_be32(&lbc->lteatr, 0);
0194 out_be32(&lbc->ltear, 0);
0195 out_be32(&lbc->lteccr, LTECCR_CLEAR);
0196 out_be32(&lbc->ltedr, LTEDR_ENABLE);
0197
0198
0199 if (of_device_is_compatible(node, "fsl,elbc"))
0200 clrsetbits_be32(&lbc->lbcr, LBCR_BMT, LBCR_BMTPS);
0201
0202 return 0;
0203 }
0204
0205
0206
0207
0208
0209
0210 static irqreturn_t fsl_lbc_ctrl_irq(int irqno, void *data)
0211 {
0212 struct fsl_lbc_ctrl *ctrl = data;
0213 struct fsl_lbc_regs __iomem *lbc = ctrl->regs;
0214 u32 status;
0215 unsigned long flags;
0216
0217 spin_lock_irqsave(&fsl_lbc_lock, flags);
0218 status = in_be32(&lbc->ltesr);
0219 if (!status) {
0220 spin_unlock_irqrestore(&fsl_lbc_lock, flags);
0221 return IRQ_NONE;
0222 }
0223
0224 out_be32(&lbc->ltesr, LTESR_CLEAR);
0225 out_be32(&lbc->lteatr, 0);
0226 out_be32(&lbc->ltear, 0);
0227 ctrl->irq_status = status;
0228
0229 if (status & LTESR_BM)
0230 dev_err(ctrl->dev, "Local bus monitor time-out: "
0231 "LTESR 0x%08X\n", status);
0232 if (status & LTESR_WP)
0233 dev_err(ctrl->dev, "Write protect error: "
0234 "LTESR 0x%08X\n", status);
0235 if (status & LTESR_ATMW)
0236 dev_err(ctrl->dev, "Atomic write error: "
0237 "LTESR 0x%08X\n", status);
0238 if (status & LTESR_ATMR)
0239 dev_err(ctrl->dev, "Atomic read error: "
0240 "LTESR 0x%08X\n", status);
0241 if (status & LTESR_CS)
0242 dev_err(ctrl->dev, "Chip select error: "
0243 "LTESR 0x%08X\n", status);
0244 if (status & LTESR_FCT) {
0245 dev_err(ctrl->dev, "FCM command time-out: "
0246 "LTESR 0x%08X\n", status);
0247 smp_wmb();
0248 wake_up(&ctrl->irq_wait);
0249 }
0250 if (status & LTESR_PAR) {
0251 dev_err(ctrl->dev, "Parity or Uncorrectable ECC error: "
0252 "LTESR 0x%08X\n", status);
0253 smp_wmb();
0254 wake_up(&ctrl->irq_wait);
0255 }
0256 if (status & LTESR_CC) {
0257 smp_wmb();
0258 wake_up(&ctrl->irq_wait);
0259 }
0260 if (status & ~LTESR_MASK)
0261 dev_err(ctrl->dev, "Unknown error: "
0262 "LTESR 0x%08X\n", status);
0263 spin_unlock_irqrestore(&fsl_lbc_lock, flags);
0264 return IRQ_HANDLED;
0265 }
0266
0267
0268
0269
0270
0271
0272
0273
0274
0275
0276
0277 static int fsl_lbc_ctrl_probe(struct platform_device *dev)
0278 {
0279 int ret;
0280
0281 if (!dev->dev.of_node) {
0282 dev_err(&dev->dev, "Device OF-Node is NULL");
0283 return -EFAULT;
0284 }
0285
0286 fsl_lbc_ctrl_dev = kzalloc(sizeof(*fsl_lbc_ctrl_dev), GFP_KERNEL);
0287 if (!fsl_lbc_ctrl_dev)
0288 return -ENOMEM;
0289
0290 dev_set_drvdata(&dev->dev, fsl_lbc_ctrl_dev);
0291
0292 spin_lock_init(&fsl_lbc_ctrl_dev->lock);
0293 init_waitqueue_head(&fsl_lbc_ctrl_dev->irq_wait);
0294
0295 fsl_lbc_ctrl_dev->regs = of_iomap(dev->dev.of_node, 0);
0296 if (!fsl_lbc_ctrl_dev->regs) {
0297 dev_err(&dev->dev, "failed to get memory region\n");
0298 ret = -ENODEV;
0299 goto err;
0300 }
0301
0302 fsl_lbc_ctrl_dev->irq[0] = irq_of_parse_and_map(dev->dev.of_node, 0);
0303 if (!fsl_lbc_ctrl_dev->irq[0]) {
0304 dev_err(&dev->dev, "failed to get irq resource\n");
0305 ret = -ENODEV;
0306 goto err;
0307 }
0308
0309 fsl_lbc_ctrl_dev->dev = &dev->dev;
0310
0311 ret = fsl_lbc_ctrl_init(fsl_lbc_ctrl_dev, dev->dev.of_node);
0312 if (ret < 0)
0313 goto err;
0314
0315 ret = request_irq(fsl_lbc_ctrl_dev->irq[0], fsl_lbc_ctrl_irq, 0,
0316 "fsl-lbc", fsl_lbc_ctrl_dev);
0317 if (ret != 0) {
0318 dev_err(&dev->dev, "failed to install irq (%d)\n",
0319 fsl_lbc_ctrl_dev->irq[0]);
0320 ret = fsl_lbc_ctrl_dev->irq[0];
0321 goto err;
0322 }
0323
0324 fsl_lbc_ctrl_dev->irq[1] = irq_of_parse_and_map(dev->dev.of_node, 1);
0325 if (fsl_lbc_ctrl_dev->irq[1]) {
0326 ret = request_irq(fsl_lbc_ctrl_dev->irq[1], fsl_lbc_ctrl_irq,
0327 IRQF_SHARED, "fsl-lbc-err", fsl_lbc_ctrl_dev);
0328 if (ret) {
0329 dev_err(&dev->dev, "failed to install irq (%d)\n",
0330 fsl_lbc_ctrl_dev->irq[1]);
0331 ret = fsl_lbc_ctrl_dev->irq[1];
0332 goto err1;
0333 }
0334 }
0335
0336
0337 out_be32(&fsl_lbc_ctrl_dev->regs->lteir, LTEIR_ENABLE);
0338
0339 return 0;
0340
0341 err1:
0342 free_irq(fsl_lbc_ctrl_dev->irq[0], fsl_lbc_ctrl_dev);
0343 err:
0344 iounmap(fsl_lbc_ctrl_dev->regs);
0345 kfree(fsl_lbc_ctrl_dev);
0346 fsl_lbc_ctrl_dev = NULL;
0347 return ret;
0348 }
0349
0350 #ifdef CONFIG_SUSPEND
0351
0352
0353 static int fsl_lbc_syscore_suspend(void)
0354 {
0355 struct fsl_lbc_ctrl *ctrl;
0356 struct fsl_lbc_regs __iomem *lbc;
0357
0358 ctrl = fsl_lbc_ctrl_dev;
0359 if (!ctrl)
0360 goto out;
0361
0362 lbc = ctrl->regs;
0363 if (!lbc)
0364 goto out;
0365
0366 ctrl->saved_regs = kmalloc(sizeof(struct fsl_lbc_regs), GFP_KERNEL);
0367 if (!ctrl->saved_regs)
0368 return -ENOMEM;
0369
0370 _memcpy_fromio(ctrl->saved_regs, lbc, sizeof(struct fsl_lbc_regs));
0371
0372 out:
0373 return 0;
0374 }
0375
0376
0377 static void fsl_lbc_syscore_resume(void)
0378 {
0379 struct fsl_lbc_ctrl *ctrl;
0380 struct fsl_lbc_regs __iomem *lbc;
0381
0382 ctrl = fsl_lbc_ctrl_dev;
0383 if (!ctrl)
0384 goto out;
0385
0386 lbc = ctrl->regs;
0387 if (!lbc)
0388 goto out;
0389
0390 if (ctrl->saved_regs) {
0391 _memcpy_toio(lbc, ctrl->saved_regs,
0392 sizeof(struct fsl_lbc_regs));
0393 kfree(ctrl->saved_regs);
0394 ctrl->saved_regs = NULL;
0395 }
0396
0397 out:
0398 return;
0399 }
0400 #endif
0401
0402 static const struct of_device_id fsl_lbc_match[] = {
0403 { .compatible = "fsl,elbc", },
0404 { .compatible = "fsl,pq3-localbus", },
0405 { .compatible = "fsl,pq2-localbus", },
0406 { .compatible = "fsl,pq2pro-localbus", },
0407 {},
0408 };
0409
0410 #ifdef CONFIG_SUSPEND
0411 static struct syscore_ops lbc_syscore_pm_ops = {
0412 .suspend = fsl_lbc_syscore_suspend,
0413 .resume = fsl_lbc_syscore_resume,
0414 };
0415 #endif
0416
0417 static struct platform_driver fsl_lbc_ctrl_driver = {
0418 .driver = {
0419 .name = "fsl-lbc",
0420 .of_match_table = fsl_lbc_match,
0421 },
0422 .probe = fsl_lbc_ctrl_probe,
0423 };
0424
0425 static int __init fsl_lbc_init(void)
0426 {
0427 #ifdef CONFIG_SUSPEND
0428 register_syscore_ops(&lbc_syscore_pm_ops);
0429 #endif
0430 return platform_driver_register(&fsl_lbc_ctrl_driver);
0431 }
0432 subsys_initcall(fsl_lbc_init);