Lines Matching refs:rsb
201 static struct sunxi_rsb_device *sunxi_rsb_device_create(struct sunxi_rsb *rsb, in sunxi_rsb_device_create() argument
211 rdev->rsb = rsb; in sunxi_rsb_device_create()
215 rdev->dev.parent = rsb->dev; in sunxi_rsb_device_create()
272 static int _sunxi_rsb_run_xfer(struct sunxi_rsb *rsb) in _sunxi_rsb_run_xfer() argument
277 if (readl(rsb->regs + RSB_CTRL) & RSB_CTRL_START_TRANS) { in _sunxi_rsb_run_xfer()
278 dev_dbg(rsb->dev, "RSB transfer still in progress\n"); in _sunxi_rsb_run_xfer()
282 reinit_completion(&rsb->complete); in _sunxi_rsb_run_xfer()
285 writel(int_mask, rsb->regs + RSB_INTE); in _sunxi_rsb_run_xfer()
287 rsb->regs + RSB_CTRL); in _sunxi_rsb_run_xfer()
290 timeout = readl_poll_timeout_atomic(rsb->regs + RSB_INTS, in _sunxi_rsb_run_xfer()
293 writel(status, rsb->regs + RSB_INTS); in _sunxi_rsb_run_xfer()
295 timeout = !wait_for_completion_io_timeout(&rsb->complete, in _sunxi_rsb_run_xfer()
297 status = rsb->status; in _sunxi_rsb_run_xfer()
301 dev_dbg(rsb->dev, "RSB timeout\n"); in _sunxi_rsb_run_xfer()
304 writel(RSB_CTRL_ABORT_TRANS, rsb->regs + RSB_CTRL); in _sunxi_rsb_run_xfer()
307 writel(readl(rsb->regs + RSB_INTS), rsb->regs + RSB_INTS); in _sunxi_rsb_run_xfer()
313 dev_dbg(rsb->dev, "RSB busy\n"); in _sunxi_rsb_run_xfer()
319 dev_dbg(rsb->dev, "RSB slave nack\n"); in _sunxi_rsb_run_xfer()
324 dev_dbg(rsb->dev, "RSB transfer data error\n"); in _sunxi_rsb_run_xfer()
332 static int sunxi_rsb_read(struct sunxi_rsb *rsb, u8 rtaddr, u8 addr, in sunxi_rsb_read() argument
352 dev_err(rsb->dev, "Invalid access width: %zd\n", len); in sunxi_rsb_read()
356 ret = pm_runtime_resume_and_get(rsb->dev); in sunxi_rsb_read()
360 mutex_lock(&rsb->lock); in sunxi_rsb_read()
362 writel(addr, rsb->regs + RSB_ADDR); in sunxi_rsb_read()
363 writel(RSB_DAR_RTA(rtaddr), rsb->regs + RSB_DAR); in sunxi_rsb_read()
364 writel(cmd, rsb->regs + RSB_CMD); in sunxi_rsb_read()
366 ret = _sunxi_rsb_run_xfer(rsb); in sunxi_rsb_read()
370 *buf = readl(rsb->regs + RSB_DATA) & GENMASK(len * 8 - 1, 0); in sunxi_rsb_read()
373 mutex_unlock(&rsb->lock); in sunxi_rsb_read()
375 pm_runtime_mark_last_busy(rsb->dev); in sunxi_rsb_read()
376 pm_runtime_put_autosuspend(rsb->dev); in sunxi_rsb_read()
381 static int sunxi_rsb_write(struct sunxi_rsb *rsb, u8 rtaddr, u8 addr, in sunxi_rsb_write() argument
401 dev_err(rsb->dev, "Invalid access width: %zd\n", len); in sunxi_rsb_write()
405 ret = pm_runtime_resume_and_get(rsb->dev); in sunxi_rsb_write()
409 mutex_lock(&rsb->lock); in sunxi_rsb_write()
411 writel(addr, rsb->regs + RSB_ADDR); in sunxi_rsb_write()
412 writel(RSB_DAR_RTA(rtaddr), rsb->regs + RSB_DAR); in sunxi_rsb_write()
413 writel(*buf, rsb->regs + RSB_DATA); in sunxi_rsb_write()
414 writel(cmd, rsb->regs + RSB_CMD); in sunxi_rsb_write()
415 ret = _sunxi_rsb_run_xfer(rsb); in sunxi_rsb_write()
417 mutex_unlock(&rsb->lock); in sunxi_rsb_write()
419 pm_runtime_mark_last_busy(rsb->dev); in sunxi_rsb_write()
420 pm_runtime_put_autosuspend(rsb->dev); in sunxi_rsb_write()
440 return sunxi_rsb_read(rdev->rsb, rdev->rtaddr, reg, val, ctx->size); in regmap_sunxi_rsb_reg_read()
449 return sunxi_rsb_write(rdev->rsb, rdev->rtaddr, reg, &val, ctx->size); in regmap_sunxi_rsb_reg_write()
509 struct sunxi_rsb *rsb = dev_id; in sunxi_rsb_irq() local
512 status = readl(rsb->regs + RSB_INTS); in sunxi_rsb_irq()
513 rsb->status = status; in sunxi_rsb_irq()
518 writel(status, rsb->regs + RSB_INTS); in sunxi_rsb_irq()
520 complete(&rsb->complete); in sunxi_rsb_irq()
525 static int sunxi_rsb_init_device_mode(struct sunxi_rsb *rsb) in sunxi_rsb_init_device_mode() argument
532 RSB_DMCR_MODE_REG | RSB_DMCR_DEV_ADDR, rsb->regs + RSB_DMCR); in sunxi_rsb_init_device_mode()
534 readl_poll_timeout(rsb->regs + RSB_DMCR, reg, in sunxi_rsb_init_device_mode()
540 writel(readl(rsb->regs + RSB_INTS), rsb->regs + RSB_INTS); in sunxi_rsb_init_device_mode()
579 static int of_rsb_register_devices(struct sunxi_rsb *rsb) in of_rsb_register_devices() argument
581 struct device *dev = rsb->dev; in of_rsb_register_devices()
615 writel(RSB_CMD_STRA, rsb->regs + RSB_CMD); in of_rsb_register_devices()
617 rsb->regs + RSB_DAR); in of_rsb_register_devices()
620 ret = _sunxi_rsb_run_xfer(rsb); in of_rsb_register_devices()
640 rdev = sunxi_rsb_device_create(rsb, child, hwaddr, rtaddr); in of_rsb_register_devices()
649 static int sunxi_rsb_hw_init(struct sunxi_rsb *rsb) in sunxi_rsb_hw_init() argument
651 struct device *dev = rsb->dev; in sunxi_rsb_hw_init()
656 ret = clk_prepare_enable(rsb->clk); in sunxi_rsb_hw_init()
662 ret = reset_control_deassert(rsb->rstc); in sunxi_rsb_hw_init()
669 writel(RSB_CTRL_SOFT_RST, rsb->regs + RSB_CTRL); in sunxi_rsb_hw_init()
670 readl_poll_timeout(rsb->regs + RSB_CTRL, reg, in sunxi_rsb_hw_init()
680 p_clk_freq = clk_get_rate(rsb->clk); in sunxi_rsb_hw_init()
681 clk_div = p_clk_freq / rsb->clk_freq / 2; in sunxi_rsb_hw_init()
693 rsb->regs + RSB_CCR); in sunxi_rsb_hw_init()
698 clk_disable_unprepare(rsb->clk); in sunxi_rsb_hw_init()
703 static void sunxi_rsb_hw_exit(struct sunxi_rsb *rsb) in sunxi_rsb_hw_exit() argument
705 reset_control_assert(rsb->rstc); in sunxi_rsb_hw_exit()
708 if (!pm_runtime_status_suspended(rsb->dev)) in sunxi_rsb_hw_exit()
709 clk_disable_unprepare(rsb->clk); in sunxi_rsb_hw_exit()
714 struct sunxi_rsb *rsb = dev_get_drvdata(dev); in sunxi_rsb_runtime_suspend() local
716 clk_disable_unprepare(rsb->clk); in sunxi_rsb_runtime_suspend()
723 struct sunxi_rsb *rsb = dev_get_drvdata(dev); in sunxi_rsb_runtime_resume() local
725 return clk_prepare_enable(rsb->clk); in sunxi_rsb_runtime_resume()
730 struct sunxi_rsb *rsb = dev_get_drvdata(dev); in sunxi_rsb_suspend() local
732 sunxi_rsb_hw_exit(rsb); in sunxi_rsb_suspend()
739 struct sunxi_rsb *rsb = dev_get_drvdata(dev); in sunxi_rsb_resume() local
741 return sunxi_rsb_hw_init(rsb); in sunxi_rsb_resume()
749 struct sunxi_rsb *rsb; in sunxi_rsb_probe() local
761 rsb = devm_kzalloc(dev, sizeof(*rsb), GFP_KERNEL); in sunxi_rsb_probe()
762 if (!rsb) in sunxi_rsb_probe()
765 rsb->dev = dev; in sunxi_rsb_probe()
766 rsb->clk_freq = clk_freq; in sunxi_rsb_probe()
767 platform_set_drvdata(pdev, rsb); in sunxi_rsb_probe()
769 rsb->regs = devm_ioremap_resource(dev, r); in sunxi_rsb_probe()
770 if (IS_ERR(rsb->regs)) in sunxi_rsb_probe()
771 return PTR_ERR(rsb->regs); in sunxi_rsb_probe()
777 rsb->clk = devm_clk_get(dev, NULL); in sunxi_rsb_probe()
778 if (IS_ERR(rsb->clk)) { in sunxi_rsb_probe()
779 ret = PTR_ERR(rsb->clk); in sunxi_rsb_probe()
784 rsb->rstc = devm_reset_control_get(dev, NULL); in sunxi_rsb_probe()
785 if (IS_ERR(rsb->rstc)) { in sunxi_rsb_probe()
786 ret = PTR_ERR(rsb->rstc); in sunxi_rsb_probe()
791 init_completion(&rsb->complete); in sunxi_rsb_probe()
792 mutex_init(&rsb->lock); in sunxi_rsb_probe()
794 ret = devm_request_irq(dev, irq, sunxi_rsb_irq, 0, RSB_CTRL_NAME, rsb); in sunxi_rsb_probe()
801 ret = sunxi_rsb_hw_init(rsb); in sunxi_rsb_probe()
806 ret = sunxi_rsb_init_device_mode(rsb); in sunxi_rsb_probe()
816 of_rsb_register_devices(rsb); in sunxi_rsb_probe()
823 struct sunxi_rsb *rsb = platform_get_drvdata(pdev); in sunxi_rsb_remove() local
825 device_for_each_child(rsb->dev, NULL, sunxi_rsb_remove_devices); in sunxi_rsb_remove()
827 sunxi_rsb_hw_exit(rsb); in sunxi_rsb_remove()