Lines Matching refs:rsb
51 #include <linux/sunxi-rsb.h>
114 #define RSB_CTRL_NAME "sunxi-rsb"
193 * @rsb: RSB controller
198 static struct sunxi_rsb_device *sunxi_rsb_device_create(struct sunxi_rsb *rsb,
208 rdev->rsb = rsb;
212 rdev->dev.parent = rsb->dev;
269 static int _sunxi_rsb_run_xfer(struct sunxi_rsb *rsb)
274 if (readl(rsb->regs + RSB_CTRL) & RSB_CTRL_START_TRANS) {
275 dev_dbg(rsb->dev, "RSB transfer still in progress\n");
279 reinit_completion(&rsb->complete);
282 writel(int_mask, rsb->regs + RSB_INTE);
284 rsb->regs + RSB_CTRL);
287 timeout = readl_poll_timeout_atomic(rsb->regs + RSB_INTS,
290 writel(status, rsb->regs + RSB_INTS);
292 timeout = !wait_for_completion_io_timeout(&rsb->complete,
294 status = rsb->status;
298 dev_dbg(rsb->dev, "RSB timeout\n");
301 writel(RSB_CTRL_ABORT_TRANS, rsb->regs + RSB_CTRL);
304 writel(readl(rsb->regs + RSB_INTS), rsb->regs + RSB_INTS);
310 dev_dbg(rsb->dev, "RSB busy\n");
316 dev_dbg(rsb->dev, "RSB slave nack\n");
321 dev_dbg(rsb->dev, "RSB transfer data error\n");
329 static int sunxi_rsb_read(struct sunxi_rsb *rsb, u8 rtaddr, u8 addr,
349 dev_err(rsb->dev, "Invalid access width: %zd\n", len);
353 mutex_lock(&rsb->lock);
355 writel(addr, rsb->regs + RSB_ADDR);
356 writel(RSB_DAR_RTA(rtaddr), rsb->regs + RSB_DAR);
357 writel(cmd, rsb->regs + RSB_CMD);
359 ret = _sunxi_rsb_run_xfer(rsb);
363 *buf = readl(rsb->regs + RSB_DATA) & GENMASK(len * 8 - 1, 0);
366 mutex_unlock(&rsb->lock);
371 static int sunxi_rsb_write(struct sunxi_rsb *rsb, u8 rtaddr, u8 addr,
391 dev_err(rsb->dev, "Invalid access width: %zd\n", len);
395 mutex_lock(&rsb->lock);
397 writel(addr, rsb->regs + RSB_ADDR);
398 writel(RSB_DAR_RTA(rtaddr), rsb->regs + RSB_DAR);
399 writel(*buf, rsb->regs + RSB_DATA);
400 writel(cmd, rsb->regs + RSB_CMD);
401 ret = _sunxi_rsb_run_xfer(rsb);
403 mutex_unlock(&rsb->lock);
423 return sunxi_rsb_read(rdev->rsb, rdev->rtaddr, reg, val, ctx->size);
432 return sunxi_rsb_write(rdev->rsb, rdev->rtaddr, reg, &val, ctx->size);
492 struct sunxi_rsb *rsb = dev_id;
495 status = readl(rsb->regs + RSB_INTS);
496 rsb->status = status;
501 writel(status, rsb->regs + RSB_INTS);
503 complete(&rsb->complete);
508 static int sunxi_rsb_init_device_mode(struct sunxi_rsb *rsb)
515 RSB_DMCR_MODE_REG | RSB_DMCR_DEV_ADDR, rsb->regs + RSB_DMCR);
517 readl_poll_timeout(rsb->regs + RSB_DMCR, reg,
523 writel(readl(rsb->regs + RSB_INTS), rsb->regs + RSB_INTS);
562 static int of_rsb_register_devices(struct sunxi_rsb *rsb)
564 struct device *dev = rsb->dev;
598 writel(RSB_CMD_STRA, rsb->regs + RSB_CMD);
600 rsb->regs + RSB_DAR);
603 ret = _sunxi_rsb_run_xfer(rsb);
623 rdev = sunxi_rsb_device_create(rsb, child, hwaddr, rtaddr);
633 { .compatible = "allwinner,sun8i-a23-rsb" },
643 struct sunxi_rsb *rsb;
657 rsb = devm_kzalloc(dev, sizeof(*rsb), GFP_KERNEL);
658 if (!rsb)
661 rsb->dev = dev;
662 platform_set_drvdata(pdev, rsb);
664 rsb->regs = devm_ioremap_resource(dev, r);
665 if (IS_ERR(rsb->regs))
666 return PTR_ERR(rsb->regs);
672 rsb->clk = devm_clk_get(dev, NULL);
673 if (IS_ERR(rsb->clk)) {
674 ret = PTR_ERR(rsb->clk);
679 ret = clk_prepare_enable(rsb->clk);
685 p_clk_freq = clk_get_rate(rsb->clk);
687 rsb->rstc = devm_reset_control_get(dev, NULL);
688 if (IS_ERR(rsb->rstc)) {
689 ret = PTR_ERR(rsb->rstc);
694 ret = reset_control_deassert(rsb->rstc);
700 init_completion(&rsb->complete);
701 mutex_init(&rsb->lock);
704 writel(RSB_CTRL_SOFT_RST, rsb->regs + RSB_CTRL);
705 readl_poll_timeout(rsb->regs + RSB_CTRL, reg,
727 rsb->regs + RSB_CCR);
729 ret = devm_request_irq(dev, irq, sunxi_rsb_irq, 0, RSB_CTRL_NAME, rsb);
737 ret = sunxi_rsb_init_device_mode(rsb);
741 of_rsb_register_devices(rsb);
746 reset_control_assert(rsb->rstc);
749 clk_disable_unprepare(rsb->clk);
756 struct sunxi_rsb *rsb = platform_get_drvdata(pdev);
758 device_for_each_child(rsb->dev, NULL, sunxi_rsb_remove_devices);
759 reset_control_assert(rsb->rstc);
760 clk_disable_unprepare(rsb->clk);