154e991b5SMasahiro Yamada /* 254e991b5SMasahiro Yamada * Copyright (C) 2016 Socionext Inc. 354e991b5SMasahiro Yamada * Author: Masahiro Yamada <yamada.masahiro@socionext.com> 454e991b5SMasahiro Yamada * 554e991b5SMasahiro Yamada * This program is free software; you can redistribute it and/or modify 654e991b5SMasahiro Yamada * it under the terms of the GNU General Public License as published by 754e991b5SMasahiro Yamada * the Free Software Foundation; either version 2 of the License, or 854e991b5SMasahiro Yamada * (at your option) any later version. 954e991b5SMasahiro Yamada * 1054e991b5SMasahiro Yamada * This program is distributed in the hope that it will be useful, 1154e991b5SMasahiro Yamada * but WITHOUT ANY WARRANTY; without even the implied warranty of 1254e991b5SMasahiro Yamada * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1354e991b5SMasahiro Yamada * GNU General Public License for more details. 1454e991b5SMasahiro Yamada */ 1554e991b5SMasahiro Yamada 1654e991b5SMasahiro Yamada #include <linux/mfd/syscon.h> 1754e991b5SMasahiro Yamada #include <linux/module.h> 1854e991b5SMasahiro Yamada #include <linux/of.h> 1954e991b5SMasahiro Yamada #include <linux/of_device.h> 2054e991b5SMasahiro Yamada #include <linux/platform_device.h> 2154e991b5SMasahiro Yamada #include <linux/regmap.h> 2254e991b5SMasahiro Yamada #include <linux/reset-controller.h> 2354e991b5SMasahiro Yamada 2454e991b5SMasahiro Yamada struct uniphier_reset_data { 2554e991b5SMasahiro Yamada unsigned int id; 2654e991b5SMasahiro Yamada unsigned int reg; 2754e991b5SMasahiro Yamada unsigned int bit; 2854e991b5SMasahiro Yamada unsigned int flags; 2954e991b5SMasahiro Yamada #define UNIPHIER_RESET_ACTIVE_LOW BIT(0) 3054e991b5SMasahiro Yamada }; 3154e991b5SMasahiro Yamada 3254e991b5SMasahiro Yamada #define UNIPHIER_RESET_ID_END (unsigned int)(-1) 3354e991b5SMasahiro Yamada 3454e991b5SMasahiro Yamada #define UNIPHIER_RESET_END \ 3554e991b5SMasahiro Yamada { .id = UNIPHIER_RESET_ID_END } 3654e991b5SMasahiro Yamada 3754e991b5SMasahiro Yamada #define UNIPHIER_RESET(_id, _reg, _bit) \ 3854e991b5SMasahiro Yamada { \ 3954e991b5SMasahiro Yamada .id = (_id), \ 4054e991b5SMasahiro Yamada .reg = (_reg), \ 4154e991b5SMasahiro Yamada .bit = (_bit), \ 4254e991b5SMasahiro Yamada } 4354e991b5SMasahiro Yamada 4454e991b5SMasahiro Yamada #define UNIPHIER_RESETX(_id, _reg, _bit) \ 4554e991b5SMasahiro Yamada { \ 4654e991b5SMasahiro Yamada .id = (_id), \ 4754e991b5SMasahiro Yamada .reg = (_reg), \ 4854e991b5SMasahiro Yamada .bit = (_bit), \ 4954e991b5SMasahiro Yamada .flags = UNIPHIER_RESET_ACTIVE_LOW, \ 5054e991b5SMasahiro Yamada } 5154e991b5SMasahiro Yamada 5254e991b5SMasahiro Yamada /* System reset data */ 535281036aSMasahiro Yamada static const struct uniphier_reset_data uniphier_ld4_sys_reset_data[] = { 545281036aSMasahiro Yamada UNIPHIER_RESETX(2, 0x2000, 2), /* NAND */ 555281036aSMasahiro Yamada UNIPHIER_RESETX(8, 0x2000, 10), /* STDMAC (Ether, HSC, MIO) */ 5654e991b5SMasahiro Yamada UNIPHIER_RESET_END, 5754e991b5SMasahiro Yamada }; 5854e991b5SMasahiro Yamada 59716adfe3SWei Yongjun static const struct uniphier_reset_data uniphier_pro4_sys_reset_data[] = { 605281036aSMasahiro Yamada UNIPHIER_RESETX(2, 0x2000, 2), /* NAND */ 614c05c4a5SKunihiko Hayashi UNIPHIER_RESETX(6, 0x2000, 12), /* Ether */ 625281036aSMasahiro Yamada UNIPHIER_RESETX(8, 0x2000, 10), /* STDMAC (HSC, MIO, RLE) */ 63dec173ccSMasahiro Yamada UNIPHIER_RESETX(12, 0x2000, 6), /* GIO (Ether, SATA, USB3) */ 64dec173ccSMasahiro Yamada UNIPHIER_RESETX(14, 0x2000, 17), /* USB30 */ 65dec173ccSMasahiro Yamada UNIPHIER_RESETX(15, 0x2004, 17), /* USB31 */ 66b06b631cSKatsuhiro Suzuki UNIPHIER_RESETX(40, 0x2000, 13), /* AIO */ 6754e991b5SMasahiro Yamada UNIPHIER_RESET_END, 6854e991b5SMasahiro Yamada }; 6954e991b5SMasahiro Yamada 70716adfe3SWei Yongjun static const struct uniphier_reset_data uniphier_pro5_sys_reset_data[] = { 715281036aSMasahiro Yamada UNIPHIER_RESETX(2, 0x2000, 2), /* NAND */ 725281036aSMasahiro Yamada UNIPHIER_RESETX(8, 0x2000, 10), /* STDMAC (HSC) */ 73dec173ccSMasahiro Yamada UNIPHIER_RESETX(12, 0x2000, 6), /* GIO (PCIe, USB3) */ 74dec173ccSMasahiro Yamada UNIPHIER_RESETX(14, 0x2000, 17), /* USB30 */ 75dec173ccSMasahiro Yamada UNIPHIER_RESETX(15, 0x2004, 17), /* USB31 */ 76fdc0f235SKunihiko Hayashi UNIPHIER_RESETX(24, 0x2008, 2), /* PCIe */ 77b06b631cSKatsuhiro Suzuki UNIPHIER_RESETX(40, 0x2000, 13), /* AIO */ 7854e991b5SMasahiro Yamada UNIPHIER_RESET_END, 7954e991b5SMasahiro Yamada }; 8054e991b5SMasahiro Yamada 81716adfe3SWei Yongjun static const struct uniphier_reset_data uniphier_pxs2_sys_reset_data[] = { 825281036aSMasahiro Yamada UNIPHIER_RESETX(2, 0x2000, 2), /* NAND */ 834c05c4a5SKunihiko Hayashi UNIPHIER_RESETX(6, 0x2000, 12), /* Ether */ 845281036aSMasahiro Yamada UNIPHIER_RESETX(8, 0x2000, 10), /* STDMAC (HSC, RLE) */ 85dec173ccSMasahiro Yamada UNIPHIER_RESETX(14, 0x2000, 17), /* USB30 */ 86dec173ccSMasahiro Yamada UNIPHIER_RESETX(15, 0x2004, 17), /* USB31 */ 8754e991b5SMasahiro Yamada UNIPHIER_RESETX(16, 0x2014, 4), /* USB30-PHY0 */ 8854e991b5SMasahiro Yamada UNIPHIER_RESETX(17, 0x2014, 0), /* USB30-PHY1 */ 8954e991b5SMasahiro Yamada UNIPHIER_RESETX(18, 0x2014, 2), /* USB30-PHY2 */ 9054e991b5SMasahiro Yamada UNIPHIER_RESETX(20, 0x2014, 5), /* USB31-PHY0 */ 9154e991b5SMasahiro Yamada UNIPHIER_RESETX(21, 0x2014, 1), /* USB31-PHY1 */ 9254e991b5SMasahiro Yamada UNIPHIER_RESETX(28, 0x2014, 12), /* SATA */ 9354e991b5SMasahiro Yamada UNIPHIER_RESET(29, 0x2014, 8), /* SATA-PHY (active high) */ 94b06b631cSKatsuhiro Suzuki UNIPHIER_RESETX(40, 0x2000, 13), /* AIO */ 9554e991b5SMasahiro Yamada UNIPHIER_RESET_END, 9654e991b5SMasahiro Yamada }; 9754e991b5SMasahiro Yamada 98716adfe3SWei Yongjun static const struct uniphier_reset_data uniphier_ld11_sys_reset_data[] = { 99dec173ccSMasahiro Yamada UNIPHIER_RESETX(2, 0x200c, 0), /* NAND */ 100dec173ccSMasahiro Yamada UNIPHIER_RESETX(4, 0x200c, 2), /* eMMC */ 1014c05c4a5SKunihiko Hayashi UNIPHIER_RESETX(6, 0x200c, 6), /* Ether */ 102dec173ccSMasahiro Yamada UNIPHIER_RESETX(8, 0x200c, 8), /* STDMAC (HSC, MIO) */ 10394e10c22SKatsuhiro Suzuki UNIPHIER_RESETX(40, 0x2008, 0), /* AIO */ 10494e10c22SKatsuhiro Suzuki UNIPHIER_RESETX(41, 0x2008, 1), /* EVEA */ 1050f195435SKatsuhiro Suzuki UNIPHIER_RESETX(42, 0x2010, 2), /* EXIV */ 10654e991b5SMasahiro Yamada UNIPHIER_RESET_END, 10754e991b5SMasahiro Yamada }; 10854e991b5SMasahiro Yamada 109716adfe3SWei Yongjun static const struct uniphier_reset_data uniphier_ld20_sys_reset_data[] = { 110dec173ccSMasahiro Yamada UNIPHIER_RESETX(2, 0x200c, 0), /* NAND */ 111dec173ccSMasahiro Yamada UNIPHIER_RESETX(4, 0x200c, 2), /* eMMC */ 1124c05c4a5SKunihiko Hayashi UNIPHIER_RESETX(6, 0x200c, 6), /* Ether */ 113dec173ccSMasahiro Yamada UNIPHIER_RESETX(8, 0x200c, 8), /* STDMAC (HSC) */ 114e6914365SMasahiro Yamada UNIPHIER_RESETX(14, 0x200c, 5), /* USB30 */ 11554e991b5SMasahiro Yamada UNIPHIER_RESETX(16, 0x200c, 12), /* USB30-PHY0 */ 11654e991b5SMasahiro Yamada UNIPHIER_RESETX(17, 0x200c, 13), /* USB30-PHY1 */ 11754e991b5SMasahiro Yamada UNIPHIER_RESETX(18, 0x200c, 14), /* USB30-PHY2 */ 11854e991b5SMasahiro Yamada UNIPHIER_RESETX(19, 0x200c, 15), /* USB30-PHY3 */ 119fdc0f235SKunihiko Hayashi UNIPHIER_RESETX(24, 0x200c, 4), /* PCIe */ 12094e10c22SKatsuhiro Suzuki UNIPHIER_RESETX(40, 0x2008, 0), /* AIO */ 12194e10c22SKatsuhiro Suzuki UNIPHIER_RESETX(41, 0x2008, 1), /* EVEA */ 1220f195435SKatsuhiro Suzuki UNIPHIER_RESETX(42, 0x2010, 2), /* EXIV */ 12354e991b5SMasahiro Yamada UNIPHIER_RESET_END, 12454e991b5SMasahiro Yamada }; 12554e991b5SMasahiro Yamada 1262a158f88SMasahiro Yamada static const struct uniphier_reset_data uniphier_pxs3_sys_reset_data[] = { 1272a158f88SMasahiro Yamada UNIPHIER_RESETX(2, 0x200c, 0), /* NAND */ 1282a158f88SMasahiro Yamada UNIPHIER_RESETX(4, 0x200c, 2), /* eMMC */ 1295573fe85SKunihiko Hayashi UNIPHIER_RESETX(6, 0x200c, 9), /* Ether0 */ 1305573fe85SKunihiko Hayashi UNIPHIER_RESETX(7, 0x200c, 10), /* Ether1 */ 1312a158f88SMasahiro Yamada UNIPHIER_RESETX(8, 0x200c, 12), /* STDMAC */ 132e6914365SMasahiro Yamada UNIPHIER_RESETX(12, 0x200c, 4), /* USB30 link */ 133e6914365SMasahiro Yamada UNIPHIER_RESETX(13, 0x200c, 5), /* USB31 link */ 1342a158f88SMasahiro Yamada UNIPHIER_RESETX(16, 0x200c, 16), /* USB30-PHY0 */ 1352a158f88SMasahiro Yamada UNIPHIER_RESETX(17, 0x200c, 18), /* USB30-PHY1 */ 1362a158f88SMasahiro Yamada UNIPHIER_RESETX(18, 0x200c, 20), /* USB30-PHY2 */ 1372a158f88SMasahiro Yamada UNIPHIER_RESETX(20, 0x200c, 17), /* USB31-PHY0 */ 1382a158f88SMasahiro Yamada UNIPHIER_RESETX(21, 0x200c, 19), /* USB31-PHY1 */ 139fdc0f235SKunihiko Hayashi UNIPHIER_RESETX(24, 0x200c, 3), /* PCIe */ 1402a158f88SMasahiro Yamada UNIPHIER_RESET_END, 1412a158f88SMasahiro Yamada }; 1422a158f88SMasahiro Yamada 14354e991b5SMasahiro Yamada /* Media I/O reset data */ 14454e991b5SMasahiro Yamada #define UNIPHIER_MIO_RESET_SD(id, ch) \ 14554e991b5SMasahiro Yamada UNIPHIER_RESETX((id), 0x110 + 0x200 * (ch), 0) 14654e991b5SMasahiro Yamada 14754e991b5SMasahiro Yamada #define UNIPHIER_MIO_RESET_SD_BRIDGE(id, ch) \ 14854e991b5SMasahiro Yamada UNIPHIER_RESETX((id), 0x110 + 0x200 * (ch), 26) 14954e991b5SMasahiro Yamada 15054e991b5SMasahiro Yamada #define UNIPHIER_MIO_RESET_EMMC_HW_RESET(id, ch) \ 15154e991b5SMasahiro Yamada UNIPHIER_RESETX((id), 0x80 + 0x200 * (ch), 0) 15254e991b5SMasahiro Yamada 15354e991b5SMasahiro Yamada #define UNIPHIER_MIO_RESET_USB2(id, ch) \ 15454e991b5SMasahiro Yamada UNIPHIER_RESETX((id), 0x114 + 0x200 * (ch), 0) 15554e991b5SMasahiro Yamada 15654e991b5SMasahiro Yamada #define UNIPHIER_MIO_RESET_USB2_BRIDGE(id, ch) \ 15754e991b5SMasahiro Yamada UNIPHIER_RESETX((id), 0x110 + 0x200 * (ch), 24) 15854e991b5SMasahiro Yamada 15954e991b5SMasahiro Yamada #define UNIPHIER_MIO_RESET_DMAC(id) \ 16054e991b5SMasahiro Yamada UNIPHIER_RESETX((id), 0x110, 17) 16154e991b5SMasahiro Yamada 1625281036aSMasahiro Yamada static const struct uniphier_reset_data uniphier_ld4_mio_reset_data[] = { 16354e991b5SMasahiro Yamada UNIPHIER_MIO_RESET_SD(0, 0), 16454e991b5SMasahiro Yamada UNIPHIER_MIO_RESET_SD(1, 1), 16554e991b5SMasahiro Yamada UNIPHIER_MIO_RESET_SD(2, 2), 16654e991b5SMasahiro Yamada UNIPHIER_MIO_RESET_SD_BRIDGE(3, 0), 16754e991b5SMasahiro Yamada UNIPHIER_MIO_RESET_SD_BRIDGE(4, 1), 16854e991b5SMasahiro Yamada UNIPHIER_MIO_RESET_SD_BRIDGE(5, 2), 16954e991b5SMasahiro Yamada UNIPHIER_MIO_RESET_EMMC_HW_RESET(6, 1), 17054e991b5SMasahiro Yamada UNIPHIER_MIO_RESET_DMAC(7), 17154e991b5SMasahiro Yamada UNIPHIER_MIO_RESET_USB2(8, 0), 17254e991b5SMasahiro Yamada UNIPHIER_MIO_RESET_USB2(9, 1), 17354e991b5SMasahiro Yamada UNIPHIER_MIO_RESET_USB2(10, 2), 17454e991b5SMasahiro Yamada UNIPHIER_MIO_RESET_USB2_BRIDGE(12, 0), 17554e991b5SMasahiro Yamada UNIPHIER_MIO_RESET_USB2_BRIDGE(13, 1), 17654e991b5SMasahiro Yamada UNIPHIER_MIO_RESET_USB2_BRIDGE(14, 2), 17754e991b5SMasahiro Yamada UNIPHIER_RESET_END, 17854e991b5SMasahiro Yamada }; 17954e991b5SMasahiro Yamada 180716adfe3SWei Yongjun static const struct uniphier_reset_data uniphier_pro5_sd_reset_data[] = { 18154e991b5SMasahiro Yamada UNIPHIER_MIO_RESET_SD(0, 0), 18254e991b5SMasahiro Yamada UNIPHIER_MIO_RESET_SD(1, 1), 18354e991b5SMasahiro Yamada UNIPHIER_MIO_RESET_EMMC_HW_RESET(6, 1), 18454e991b5SMasahiro Yamada UNIPHIER_RESET_END, 18554e991b5SMasahiro Yamada }; 18654e991b5SMasahiro Yamada 18754e991b5SMasahiro Yamada /* Peripheral reset data */ 18854e991b5SMasahiro Yamada #define UNIPHIER_PERI_RESET_UART(id, ch) \ 18954e991b5SMasahiro Yamada UNIPHIER_RESETX((id), 0x114, 19 + (ch)) 19054e991b5SMasahiro Yamada 19154e991b5SMasahiro Yamada #define UNIPHIER_PERI_RESET_I2C(id, ch) \ 19254e991b5SMasahiro Yamada UNIPHIER_RESETX((id), 0x114, 5 + (ch)) 19354e991b5SMasahiro Yamada 19454e991b5SMasahiro Yamada #define UNIPHIER_PERI_RESET_FI2C(id, ch) \ 19554e991b5SMasahiro Yamada UNIPHIER_RESETX((id), 0x114, 24 + (ch)) 19654e991b5SMasahiro Yamada 197716adfe3SWei Yongjun static const struct uniphier_reset_data uniphier_ld4_peri_reset_data[] = { 19854e991b5SMasahiro Yamada UNIPHIER_PERI_RESET_UART(0, 0), 19954e991b5SMasahiro Yamada UNIPHIER_PERI_RESET_UART(1, 1), 20054e991b5SMasahiro Yamada UNIPHIER_PERI_RESET_UART(2, 2), 20154e991b5SMasahiro Yamada UNIPHIER_PERI_RESET_UART(3, 3), 20254e991b5SMasahiro Yamada UNIPHIER_PERI_RESET_I2C(4, 0), 20354e991b5SMasahiro Yamada UNIPHIER_PERI_RESET_I2C(5, 1), 20454e991b5SMasahiro Yamada UNIPHIER_PERI_RESET_I2C(6, 2), 20554e991b5SMasahiro Yamada UNIPHIER_PERI_RESET_I2C(7, 3), 20654e991b5SMasahiro Yamada UNIPHIER_PERI_RESET_I2C(8, 4), 20754e991b5SMasahiro Yamada UNIPHIER_RESET_END, 20854e991b5SMasahiro Yamada }; 20954e991b5SMasahiro Yamada 210716adfe3SWei Yongjun static const struct uniphier_reset_data uniphier_pro4_peri_reset_data[] = { 21154e991b5SMasahiro Yamada UNIPHIER_PERI_RESET_UART(0, 0), 21254e991b5SMasahiro Yamada UNIPHIER_PERI_RESET_UART(1, 1), 21354e991b5SMasahiro Yamada UNIPHIER_PERI_RESET_UART(2, 2), 21454e991b5SMasahiro Yamada UNIPHIER_PERI_RESET_UART(3, 3), 21554e991b5SMasahiro Yamada UNIPHIER_PERI_RESET_FI2C(4, 0), 21654e991b5SMasahiro Yamada UNIPHIER_PERI_RESET_FI2C(5, 1), 21754e991b5SMasahiro Yamada UNIPHIER_PERI_RESET_FI2C(6, 2), 21854e991b5SMasahiro Yamada UNIPHIER_PERI_RESET_FI2C(7, 3), 21954e991b5SMasahiro Yamada UNIPHIER_PERI_RESET_FI2C(8, 4), 22054e991b5SMasahiro Yamada UNIPHIER_PERI_RESET_FI2C(9, 5), 22154e991b5SMasahiro Yamada UNIPHIER_PERI_RESET_FI2C(10, 6), 22254e991b5SMasahiro Yamada UNIPHIER_RESET_END, 22354e991b5SMasahiro Yamada }; 22454e991b5SMasahiro Yamada 225ac0c735aSKatsuhiro Suzuki /* Analog signal amplifiers reset data */ 226ac0c735aSKatsuhiro Suzuki static const struct uniphier_reset_data uniphier_ld11_adamv_reset_data[] = { 227ac0c735aSKatsuhiro Suzuki UNIPHIER_RESETX(0, 0x10, 6), /* EVEA */ 228ac0c735aSKatsuhiro Suzuki UNIPHIER_RESET_END, 229ac0c735aSKatsuhiro Suzuki }; 230ac0c735aSKatsuhiro Suzuki 23154e991b5SMasahiro Yamada /* core implementaton */ 23254e991b5SMasahiro Yamada struct uniphier_reset_priv { 23354e991b5SMasahiro Yamada struct reset_controller_dev rcdev; 23454e991b5SMasahiro Yamada struct device *dev; 23554e991b5SMasahiro Yamada struct regmap *regmap; 23654e991b5SMasahiro Yamada const struct uniphier_reset_data *data; 23754e991b5SMasahiro Yamada }; 23854e991b5SMasahiro Yamada 23954e991b5SMasahiro Yamada #define to_uniphier_reset_priv(_rcdev) \ 24054e991b5SMasahiro Yamada container_of(_rcdev, struct uniphier_reset_priv, rcdev) 24154e991b5SMasahiro Yamada 24254e991b5SMasahiro Yamada static int uniphier_reset_update(struct reset_controller_dev *rcdev, 24354e991b5SMasahiro Yamada unsigned long id, int assert) 24454e991b5SMasahiro Yamada { 24554e991b5SMasahiro Yamada struct uniphier_reset_priv *priv = to_uniphier_reset_priv(rcdev); 24654e991b5SMasahiro Yamada const struct uniphier_reset_data *p; 24754e991b5SMasahiro Yamada 24854e991b5SMasahiro Yamada for (p = priv->data; p->id != UNIPHIER_RESET_ID_END; p++) { 24954e991b5SMasahiro Yamada unsigned int mask, val; 25054e991b5SMasahiro Yamada 25154e991b5SMasahiro Yamada if (p->id != id) 25254e991b5SMasahiro Yamada continue; 25354e991b5SMasahiro Yamada 25454e991b5SMasahiro Yamada mask = BIT(p->bit); 25554e991b5SMasahiro Yamada 25654e991b5SMasahiro Yamada if (assert) 25754e991b5SMasahiro Yamada val = mask; 25854e991b5SMasahiro Yamada else 25954e991b5SMasahiro Yamada val = ~mask; 26054e991b5SMasahiro Yamada 26154e991b5SMasahiro Yamada if (p->flags & UNIPHIER_RESET_ACTIVE_LOW) 26254e991b5SMasahiro Yamada val = ~val; 26354e991b5SMasahiro Yamada 26454e991b5SMasahiro Yamada return regmap_write_bits(priv->regmap, p->reg, mask, val); 26554e991b5SMasahiro Yamada } 26654e991b5SMasahiro Yamada 26754e991b5SMasahiro Yamada dev_err(priv->dev, "reset_id=%lu was not handled\n", id); 26854e991b5SMasahiro Yamada return -EINVAL; 26954e991b5SMasahiro Yamada } 27054e991b5SMasahiro Yamada 27154e991b5SMasahiro Yamada static int uniphier_reset_assert(struct reset_controller_dev *rcdev, 27254e991b5SMasahiro Yamada unsigned long id) 27354e991b5SMasahiro Yamada { 27454e991b5SMasahiro Yamada return uniphier_reset_update(rcdev, id, 1); 27554e991b5SMasahiro Yamada } 27654e991b5SMasahiro Yamada 27754e991b5SMasahiro Yamada static int uniphier_reset_deassert(struct reset_controller_dev *rcdev, 27854e991b5SMasahiro Yamada unsigned long id) 27954e991b5SMasahiro Yamada { 28054e991b5SMasahiro Yamada return uniphier_reset_update(rcdev, id, 0); 28154e991b5SMasahiro Yamada } 28254e991b5SMasahiro Yamada 28354e991b5SMasahiro Yamada static int uniphier_reset_status(struct reset_controller_dev *rcdev, 28454e991b5SMasahiro Yamada unsigned long id) 28554e991b5SMasahiro Yamada { 28654e991b5SMasahiro Yamada struct uniphier_reset_priv *priv = to_uniphier_reset_priv(rcdev); 28754e991b5SMasahiro Yamada const struct uniphier_reset_data *p; 28854e991b5SMasahiro Yamada 28954e991b5SMasahiro Yamada for (p = priv->data; p->id != UNIPHIER_RESET_ID_END; p++) { 29054e991b5SMasahiro Yamada unsigned int val; 29154e991b5SMasahiro Yamada int ret, asserted; 29254e991b5SMasahiro Yamada 29354e991b5SMasahiro Yamada if (p->id != id) 29454e991b5SMasahiro Yamada continue; 29554e991b5SMasahiro Yamada 29654e991b5SMasahiro Yamada ret = regmap_read(priv->regmap, p->reg, &val); 29754e991b5SMasahiro Yamada if (ret) 29854e991b5SMasahiro Yamada return ret; 29954e991b5SMasahiro Yamada 30054e991b5SMasahiro Yamada asserted = !!(val & BIT(p->bit)); 30154e991b5SMasahiro Yamada 30254e991b5SMasahiro Yamada if (p->flags & UNIPHIER_RESET_ACTIVE_LOW) 30354e991b5SMasahiro Yamada asserted = !asserted; 30454e991b5SMasahiro Yamada 30554e991b5SMasahiro Yamada return asserted; 30654e991b5SMasahiro Yamada } 30754e991b5SMasahiro Yamada 30854e991b5SMasahiro Yamada dev_err(priv->dev, "reset_id=%lu was not found\n", id); 30954e991b5SMasahiro Yamada return -EINVAL; 31054e991b5SMasahiro Yamada } 31154e991b5SMasahiro Yamada 31254e991b5SMasahiro Yamada static const struct reset_control_ops uniphier_reset_ops = { 31354e991b5SMasahiro Yamada .assert = uniphier_reset_assert, 31454e991b5SMasahiro Yamada .deassert = uniphier_reset_deassert, 31554e991b5SMasahiro Yamada .status = uniphier_reset_status, 31654e991b5SMasahiro Yamada }; 31754e991b5SMasahiro Yamada 31854e991b5SMasahiro Yamada static int uniphier_reset_probe(struct platform_device *pdev) 31954e991b5SMasahiro Yamada { 32054e991b5SMasahiro Yamada struct device *dev = &pdev->dev; 32154e991b5SMasahiro Yamada struct uniphier_reset_priv *priv; 32254e991b5SMasahiro Yamada const struct uniphier_reset_data *p, *data; 32354e991b5SMasahiro Yamada struct regmap *regmap; 32454e991b5SMasahiro Yamada struct device_node *parent; 32554e991b5SMasahiro Yamada unsigned int nr_resets = 0; 32654e991b5SMasahiro Yamada 32754e991b5SMasahiro Yamada data = of_device_get_match_data(dev); 32854e991b5SMasahiro Yamada if (WARN_ON(!data)) 32954e991b5SMasahiro Yamada return -EINVAL; 33054e991b5SMasahiro Yamada 33154e991b5SMasahiro Yamada parent = of_get_parent(dev->of_node); /* parent should be syscon node */ 33254e991b5SMasahiro Yamada regmap = syscon_node_to_regmap(parent); 33354e991b5SMasahiro Yamada of_node_put(parent); 33454e991b5SMasahiro Yamada if (IS_ERR(regmap)) { 33554e991b5SMasahiro Yamada dev_err(dev, "failed to get regmap (error %ld)\n", 33654e991b5SMasahiro Yamada PTR_ERR(regmap)); 33754e991b5SMasahiro Yamada return PTR_ERR(regmap); 33854e991b5SMasahiro Yamada } 33954e991b5SMasahiro Yamada 34054e991b5SMasahiro Yamada priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 34154e991b5SMasahiro Yamada if (!priv) 34254e991b5SMasahiro Yamada return -ENOMEM; 34354e991b5SMasahiro Yamada 34454e991b5SMasahiro Yamada for (p = data; p->id != UNIPHIER_RESET_ID_END; p++) 34554e991b5SMasahiro Yamada nr_resets = max(nr_resets, p->id + 1); 34654e991b5SMasahiro Yamada 34754e991b5SMasahiro Yamada priv->rcdev.ops = &uniphier_reset_ops; 34854e991b5SMasahiro Yamada priv->rcdev.owner = dev->driver->owner; 34954e991b5SMasahiro Yamada priv->rcdev.of_node = dev->of_node; 35054e991b5SMasahiro Yamada priv->rcdev.nr_resets = nr_resets; 35154e991b5SMasahiro Yamada priv->dev = dev; 35254e991b5SMasahiro Yamada priv->regmap = regmap; 35354e991b5SMasahiro Yamada priv->data = data; 35454e991b5SMasahiro Yamada 35554e991b5SMasahiro Yamada return devm_reset_controller_register(&pdev->dev, &priv->rcdev); 35654e991b5SMasahiro Yamada } 35754e991b5SMasahiro Yamada 35854e991b5SMasahiro Yamada static const struct of_device_id uniphier_reset_match[] = { 35954e991b5SMasahiro Yamada /* System reset */ 36054e991b5SMasahiro Yamada { 36154e991b5SMasahiro Yamada .compatible = "socionext,uniphier-ld4-reset", 3625281036aSMasahiro Yamada .data = uniphier_ld4_sys_reset_data, 36354e991b5SMasahiro Yamada }, 36454e991b5SMasahiro Yamada { 36554e991b5SMasahiro Yamada .compatible = "socionext,uniphier-pro4-reset", 36654e991b5SMasahiro Yamada .data = uniphier_pro4_sys_reset_data, 36754e991b5SMasahiro Yamada }, 36854e991b5SMasahiro Yamada { 36954e991b5SMasahiro Yamada .compatible = "socionext,uniphier-sld8-reset", 3705281036aSMasahiro Yamada .data = uniphier_ld4_sys_reset_data, 37154e991b5SMasahiro Yamada }, 37254e991b5SMasahiro Yamada { 37354e991b5SMasahiro Yamada .compatible = "socionext,uniphier-pro5-reset", 37454e991b5SMasahiro Yamada .data = uniphier_pro5_sys_reset_data, 37554e991b5SMasahiro Yamada }, 37654e991b5SMasahiro Yamada { 37754e991b5SMasahiro Yamada .compatible = "socionext,uniphier-pxs2-reset", 37854e991b5SMasahiro Yamada .data = uniphier_pxs2_sys_reset_data, 37954e991b5SMasahiro Yamada }, 38054e991b5SMasahiro Yamada { 38154e991b5SMasahiro Yamada .compatible = "socionext,uniphier-ld11-reset", 38254e991b5SMasahiro Yamada .data = uniphier_ld11_sys_reset_data, 38354e991b5SMasahiro Yamada }, 38454e991b5SMasahiro Yamada { 38554e991b5SMasahiro Yamada .compatible = "socionext,uniphier-ld20-reset", 38654e991b5SMasahiro Yamada .data = uniphier_ld20_sys_reset_data, 38754e991b5SMasahiro Yamada }, 3882a158f88SMasahiro Yamada { 3892a158f88SMasahiro Yamada .compatible = "socionext,uniphier-pxs3-reset", 3902a158f88SMasahiro Yamada .data = uniphier_pxs3_sys_reset_data, 3912a158f88SMasahiro Yamada }, 39219eb4a47SMasahiro Yamada /* Media I/O reset, SD reset */ 39354e991b5SMasahiro Yamada { 39454e991b5SMasahiro Yamada .compatible = "socionext,uniphier-ld4-mio-reset", 3955281036aSMasahiro Yamada .data = uniphier_ld4_mio_reset_data, 39654e991b5SMasahiro Yamada }, 39754e991b5SMasahiro Yamada { 39854e991b5SMasahiro Yamada .compatible = "socionext,uniphier-pro4-mio-reset", 3995281036aSMasahiro Yamada .data = uniphier_ld4_mio_reset_data, 40054e991b5SMasahiro Yamada }, 40154e991b5SMasahiro Yamada { 40254e991b5SMasahiro Yamada .compatible = "socionext,uniphier-sld8-mio-reset", 4035281036aSMasahiro Yamada .data = uniphier_ld4_mio_reset_data, 40454e991b5SMasahiro Yamada }, 40554e991b5SMasahiro Yamada { 40619eb4a47SMasahiro Yamada .compatible = "socionext,uniphier-pro5-sd-reset", 40719eb4a47SMasahiro Yamada .data = uniphier_pro5_sd_reset_data, 40854e991b5SMasahiro Yamada }, 40954e991b5SMasahiro Yamada { 41019eb4a47SMasahiro Yamada .compatible = "socionext,uniphier-pxs2-sd-reset", 41119eb4a47SMasahiro Yamada .data = uniphier_pro5_sd_reset_data, 41254e991b5SMasahiro Yamada }, 41354e991b5SMasahiro Yamada { 41454e991b5SMasahiro Yamada .compatible = "socionext,uniphier-ld11-mio-reset", 4155281036aSMasahiro Yamada .data = uniphier_ld4_mio_reset_data, 41654e991b5SMasahiro Yamada }, 41754e991b5SMasahiro Yamada { 41888a7f523SMasahiro Yamada .compatible = "socionext,uniphier-ld11-sd-reset", 41988a7f523SMasahiro Yamada .data = uniphier_pro5_sd_reset_data, 42088a7f523SMasahiro Yamada }, 42188a7f523SMasahiro Yamada { 42219eb4a47SMasahiro Yamada .compatible = "socionext,uniphier-ld20-sd-reset", 42319eb4a47SMasahiro Yamada .data = uniphier_pro5_sd_reset_data, 42454e991b5SMasahiro Yamada }, 4252a158f88SMasahiro Yamada { 4262a158f88SMasahiro Yamada .compatible = "socionext,uniphier-pxs3-sd-reset", 4272a158f88SMasahiro Yamada .data = uniphier_pro5_sd_reset_data, 4282a158f88SMasahiro Yamada }, 42954e991b5SMasahiro Yamada /* Peripheral reset */ 43054e991b5SMasahiro Yamada { 43154e991b5SMasahiro Yamada .compatible = "socionext,uniphier-ld4-peri-reset", 43254e991b5SMasahiro Yamada .data = uniphier_ld4_peri_reset_data, 43354e991b5SMasahiro Yamada }, 43454e991b5SMasahiro Yamada { 43554e991b5SMasahiro Yamada .compatible = "socionext,uniphier-pro4-peri-reset", 43654e991b5SMasahiro Yamada .data = uniphier_pro4_peri_reset_data, 43754e991b5SMasahiro Yamada }, 43854e991b5SMasahiro Yamada { 43954e991b5SMasahiro Yamada .compatible = "socionext,uniphier-sld8-peri-reset", 44054e991b5SMasahiro Yamada .data = uniphier_ld4_peri_reset_data, 44154e991b5SMasahiro Yamada }, 44254e991b5SMasahiro Yamada { 44354e991b5SMasahiro Yamada .compatible = "socionext,uniphier-pro5-peri-reset", 44454e991b5SMasahiro Yamada .data = uniphier_pro4_peri_reset_data, 44554e991b5SMasahiro Yamada }, 44654e991b5SMasahiro Yamada { 44754e991b5SMasahiro Yamada .compatible = "socionext,uniphier-pxs2-peri-reset", 44854e991b5SMasahiro Yamada .data = uniphier_pro4_peri_reset_data, 44954e991b5SMasahiro Yamada }, 45054e991b5SMasahiro Yamada { 45154e991b5SMasahiro Yamada .compatible = "socionext,uniphier-ld11-peri-reset", 45254e991b5SMasahiro Yamada .data = uniphier_pro4_peri_reset_data, 45354e991b5SMasahiro Yamada }, 45454e991b5SMasahiro Yamada { 45554e991b5SMasahiro Yamada .compatible = "socionext,uniphier-ld20-peri-reset", 45654e991b5SMasahiro Yamada .data = uniphier_pro4_peri_reset_data, 45754e991b5SMasahiro Yamada }, 4582a158f88SMasahiro Yamada { 4592a158f88SMasahiro Yamada .compatible = "socionext,uniphier-pxs3-peri-reset", 4602a158f88SMasahiro Yamada .data = uniphier_pro4_peri_reset_data, 4612a158f88SMasahiro Yamada }, 462ac0c735aSKatsuhiro Suzuki /* Analog signal amplifiers reset */ 463ac0c735aSKatsuhiro Suzuki { 464ac0c735aSKatsuhiro Suzuki .compatible = "socionext,uniphier-ld11-adamv-reset", 465ac0c735aSKatsuhiro Suzuki .data = uniphier_ld11_adamv_reset_data, 466ac0c735aSKatsuhiro Suzuki }, 467ac0c735aSKatsuhiro Suzuki { 468ac0c735aSKatsuhiro Suzuki .compatible = "socionext,uniphier-ld20-adamv-reset", 469ac0c735aSKatsuhiro Suzuki .data = uniphier_ld11_adamv_reset_data, 470ac0c735aSKatsuhiro Suzuki }, 47154e991b5SMasahiro Yamada { /* sentinel */ } 47254e991b5SMasahiro Yamada }; 47354e991b5SMasahiro Yamada MODULE_DEVICE_TABLE(of, uniphier_reset_match); 47454e991b5SMasahiro Yamada 47554e991b5SMasahiro Yamada static struct platform_driver uniphier_reset_driver = { 47654e991b5SMasahiro Yamada .probe = uniphier_reset_probe, 47754e991b5SMasahiro Yamada .driver = { 47854e991b5SMasahiro Yamada .name = "uniphier-reset", 47954e991b5SMasahiro Yamada .of_match_table = uniphier_reset_match, 48054e991b5SMasahiro Yamada }, 48154e991b5SMasahiro Yamada }; 48254e991b5SMasahiro Yamada module_platform_driver(uniphier_reset_driver); 48354e991b5SMasahiro Yamada 48454e991b5SMasahiro Yamada MODULE_AUTHOR("Masahiro Yamada <yamada.masahiro@socionext.com>"); 48554e991b5SMasahiro Yamada MODULE_DESCRIPTION("UniPhier Reset Controller Driver"); 48654e991b5SMasahiro Yamada MODULE_LICENSE("GPL"); 487