Biju Das | 654c293 | 2023-03-30 12:16:28 +0100 | [diff] [blame] | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | /* |
| 3 | * Renesas RZ/G2L Multi-Function Timer Pulse Unit 3(MTU3a) Core driver |
| 4 | * |
| 5 | * Copyright (C) 2023 Renesas Electronics Corporation |
| 6 | */ |
| 7 | |
| 8 | #include <linux/bitfield.h> |
| 9 | #include <linux/clk.h> |
| 10 | #include <linux/interrupt.h> |
| 11 | #include <linux/irq.h> |
| 12 | #include <linux/mfd/core.h> |
| 13 | #include <linux/mfd/rz-mtu3.h> |
Biju Das | edae094 | 2023-07-11 10:28:41 +0100 | [diff] [blame] | 14 | #include <linux/module.h> |
Rob Herring | dc0c386 | 2023-07-14 11:47:27 -0600 | [diff] [blame] | 15 | #include <linux/mod_devicetable.h> |
Rob Herring | dc0c386 | 2023-07-14 11:47:27 -0600 | [diff] [blame] | 16 | #include <linux/platform_device.h> |
Biju Das | 654c293 | 2023-03-30 12:16:28 +0100 | [diff] [blame] | 17 | #include <linux/reset.h> |
| 18 | #include <linux/spinlock.h> |
| 19 | |
| 20 | #include "rz-mtu3.h" |
| 21 | |
| 22 | struct rz_mtu3_priv { |
| 23 | void __iomem *mmio; |
| 24 | struct reset_control *rstc; |
Biju Das | d92df6f | 2023-08-15 08:34:45 +0100 | [diff] [blame] | 25 | spinlock_t lock; |
Biju Das | 654c293 | 2023-03-30 12:16:28 +0100 | [diff] [blame] | 26 | }; |
| 27 | |
| 28 | /******* MTU3 registers (original offset is +0x1200) *******/ |
| 29 | static const unsigned long rz_mtu3_8bit_ch_reg_offs[][13] = { |
| 30 | [RZ_MTU3_CHAN_0] = MTU_8BIT_CH_0(0x104, 0x090, 0x100, 0x128, 0x101, 0x102, 0x103, 0x126), |
| 31 | [RZ_MTU3_CHAN_1] = MTU_8BIT_CH_1_2(0x184, 0x091, 0x185, 0x180, 0x194, 0x181, 0x182), |
| 32 | [RZ_MTU3_CHAN_2] = MTU_8BIT_CH_1_2(0x204, 0x092, 0x205, 0x200, 0x20c, 0x201, 0x202), |
| 33 | [RZ_MTU3_CHAN_3] = MTU_8BIT_CH_3_4_6_7(0x008, 0x093, 0x02c, 0x000, 0x04c, 0x002, 0x004, 0x005, 0x038), |
| 34 | [RZ_MTU3_CHAN_4] = MTU_8BIT_CH_3_4_6_7(0x009, 0x094, 0x02d, 0x001, 0x04d, 0x003, 0x006, 0x007, 0x039), |
| 35 | [RZ_MTU3_CHAN_5] = MTU_8BIT_CH_5(0xab2, 0x1eb, 0xab4, 0xab6, 0xa84, 0xa85, 0xa86, 0xa94, 0xa95, 0xa96, 0xaa4, 0xaa5, 0xaa6), |
| 36 | [RZ_MTU3_CHAN_6] = MTU_8BIT_CH_3_4_6_7(0x808, 0x893, 0x82c, 0x800, 0x84c, 0x802, 0x804, 0x805, 0x838), |
| 37 | [RZ_MTU3_CHAN_7] = MTU_8BIT_CH_3_4_6_7(0x809, 0x894, 0x82d, 0x801, 0x84d, 0x803, 0x806, 0x807, 0x839), |
| 38 | [RZ_MTU3_CHAN_8] = MTU_8BIT_CH_8(0x404, 0x098, 0x400, 0x406, 0x401, 0x402, 0x403) |
| 39 | }; |
| 40 | |
| 41 | static const unsigned long rz_mtu3_16bit_ch_reg_offs[][12] = { |
| 42 | [RZ_MTU3_CHAN_0] = MTU_16BIT_CH_0(0x106, 0x108, 0x10a, 0x10c, 0x10e, 0x120, 0x122), |
| 43 | [RZ_MTU3_CHAN_1] = MTU_16BIT_CH_1_2(0x186, 0x188, 0x18a), |
| 44 | [RZ_MTU3_CHAN_2] = MTU_16BIT_CH_1_2(0x206, 0x208, 0x20a), |
| 45 | [RZ_MTU3_CHAN_3] = MTU_16BIT_CH_3_6(0x010, 0x018, 0x01a, 0x024, 0x026, 0x072), |
| 46 | [RZ_MTU3_CHAN_4] = MTU_16BIT_CH_4_7(0x012, 0x01c, 0x01e, 0x028, 0x2a, 0x074, 0x076, 0x040, 0x044, 0x046, 0x048, 0x04a), |
| 47 | [RZ_MTU3_CHAN_5] = MTU_16BIT_CH_5(0xa80, 0xa82, 0xa90, 0xa92, 0xaa0, 0xaa2), |
| 48 | [RZ_MTU3_CHAN_6] = MTU_16BIT_CH_3_6(0x810, 0x818, 0x81a, 0x824, 0x826, 0x872), |
| 49 | [RZ_MTU3_CHAN_7] = MTU_16BIT_CH_4_7(0x812, 0x81c, 0x81e, 0x828, 0x82a, 0x874, 0x876, 0x840, 0x844, 0x846, 0x848, 0x84a) |
| 50 | }; |
| 51 | |
| 52 | static const unsigned long rz_mtu3_32bit_ch_reg_offs[][5] = { |
| 53 | [RZ_MTU3_CHAN_1] = MTU_32BIT_CH_1(0x1a0, 0x1a4, 0x1a8), |
| 54 | [RZ_MTU3_CHAN_8] = MTU_32BIT_CH_8(0x408, 0x40c, 0x410, 0x414, 0x418) |
| 55 | }; |
| 56 | |
| 57 | static bool rz_mtu3_is_16bit_shared_reg(u16 offset) |
| 58 | { |
| 59 | return (offset == RZ_MTU3_TDDRA || offset == RZ_MTU3_TDDRB || |
| 60 | offset == RZ_MTU3_TCDRA || offset == RZ_MTU3_TCDRB || |
| 61 | offset == RZ_MTU3_TCBRA || offset == RZ_MTU3_TCBRB || |
| 62 | offset == RZ_MTU3_TCNTSA || offset == RZ_MTU3_TCNTSB); |
| 63 | } |
| 64 | |
| 65 | u16 rz_mtu3_shared_reg_read(struct rz_mtu3_channel *ch, u16 offset) |
| 66 | { |
| 67 | struct rz_mtu3 *mtu = dev_get_drvdata(ch->dev->parent); |
| 68 | struct rz_mtu3_priv *priv = mtu->priv_data; |
| 69 | |
| 70 | if (rz_mtu3_is_16bit_shared_reg(offset)) |
| 71 | return readw(priv->mmio + offset); |
| 72 | else |
| 73 | return readb(priv->mmio + offset); |
| 74 | } |
| 75 | EXPORT_SYMBOL_GPL(rz_mtu3_shared_reg_read); |
| 76 | |
| 77 | u8 rz_mtu3_8bit_ch_read(struct rz_mtu3_channel *ch, u16 offset) |
| 78 | { |
| 79 | struct rz_mtu3 *mtu = dev_get_drvdata(ch->dev->parent); |
| 80 | struct rz_mtu3_priv *priv = mtu->priv_data; |
| 81 | u16 ch_offs; |
| 82 | |
| 83 | ch_offs = rz_mtu3_8bit_ch_reg_offs[ch->channel_number][offset]; |
| 84 | |
| 85 | return readb(priv->mmio + ch_offs); |
| 86 | } |
| 87 | EXPORT_SYMBOL_GPL(rz_mtu3_8bit_ch_read); |
| 88 | |
| 89 | u16 rz_mtu3_16bit_ch_read(struct rz_mtu3_channel *ch, u16 offset) |
| 90 | { |
| 91 | struct rz_mtu3 *mtu = dev_get_drvdata(ch->dev->parent); |
| 92 | struct rz_mtu3_priv *priv = mtu->priv_data; |
| 93 | u16 ch_offs; |
| 94 | |
| 95 | /* MTU8 doesn't have 16-bit registers */ |
| 96 | if (ch->channel_number == RZ_MTU3_CHAN_8) |
| 97 | return 0; |
| 98 | |
| 99 | ch_offs = rz_mtu3_16bit_ch_reg_offs[ch->channel_number][offset]; |
| 100 | |
| 101 | return readw(priv->mmio + ch_offs); |
| 102 | } |
| 103 | EXPORT_SYMBOL_GPL(rz_mtu3_16bit_ch_read); |
| 104 | |
| 105 | u32 rz_mtu3_32bit_ch_read(struct rz_mtu3_channel *ch, u16 offset) |
| 106 | { |
| 107 | struct rz_mtu3 *mtu = dev_get_drvdata(ch->dev->parent); |
| 108 | struct rz_mtu3_priv *priv = mtu->priv_data; |
| 109 | u16 ch_offs; |
| 110 | |
| 111 | if (ch->channel_number != RZ_MTU3_CHAN_1 && ch->channel_number != RZ_MTU3_CHAN_8) |
| 112 | return 0; |
| 113 | |
| 114 | ch_offs = rz_mtu3_32bit_ch_reg_offs[ch->channel_number][offset]; |
| 115 | |
| 116 | return readl(priv->mmio + ch_offs); |
| 117 | } |
| 118 | EXPORT_SYMBOL_GPL(rz_mtu3_32bit_ch_read); |
| 119 | |
| 120 | void rz_mtu3_8bit_ch_write(struct rz_mtu3_channel *ch, u16 offset, u8 val) |
| 121 | { |
| 122 | struct rz_mtu3 *mtu = dev_get_drvdata(ch->dev->parent); |
| 123 | struct rz_mtu3_priv *priv = mtu->priv_data; |
| 124 | u16 ch_offs; |
| 125 | |
| 126 | ch_offs = rz_mtu3_8bit_ch_reg_offs[ch->channel_number][offset]; |
| 127 | writeb(val, priv->mmio + ch_offs); |
| 128 | } |
| 129 | EXPORT_SYMBOL_GPL(rz_mtu3_8bit_ch_write); |
| 130 | |
| 131 | void rz_mtu3_16bit_ch_write(struct rz_mtu3_channel *ch, u16 offset, u16 val) |
| 132 | { |
| 133 | struct rz_mtu3 *mtu = dev_get_drvdata(ch->dev->parent); |
| 134 | struct rz_mtu3_priv *priv = mtu->priv_data; |
| 135 | u16 ch_offs; |
| 136 | |
| 137 | /* MTU8 doesn't have 16-bit registers */ |
| 138 | if (ch->channel_number == RZ_MTU3_CHAN_8) |
| 139 | return; |
| 140 | |
| 141 | ch_offs = rz_mtu3_16bit_ch_reg_offs[ch->channel_number][offset]; |
| 142 | writew(val, priv->mmio + ch_offs); |
| 143 | } |
| 144 | EXPORT_SYMBOL_GPL(rz_mtu3_16bit_ch_write); |
| 145 | |
| 146 | void rz_mtu3_32bit_ch_write(struct rz_mtu3_channel *ch, u16 offset, u32 val) |
| 147 | { |
| 148 | struct rz_mtu3 *mtu = dev_get_drvdata(ch->dev->parent); |
| 149 | struct rz_mtu3_priv *priv = mtu->priv_data; |
| 150 | u16 ch_offs; |
| 151 | |
| 152 | if (ch->channel_number != RZ_MTU3_CHAN_1 && ch->channel_number != RZ_MTU3_CHAN_8) |
| 153 | return; |
| 154 | |
| 155 | ch_offs = rz_mtu3_32bit_ch_reg_offs[ch->channel_number][offset]; |
| 156 | writel(val, priv->mmio + ch_offs); |
| 157 | } |
| 158 | EXPORT_SYMBOL_GPL(rz_mtu3_32bit_ch_write); |
| 159 | |
| 160 | void rz_mtu3_shared_reg_write(struct rz_mtu3_channel *ch, u16 offset, u16 value) |
| 161 | { |
| 162 | struct rz_mtu3 *mtu = dev_get_drvdata(ch->dev->parent); |
| 163 | struct rz_mtu3_priv *priv = mtu->priv_data; |
| 164 | |
| 165 | if (rz_mtu3_is_16bit_shared_reg(offset)) |
| 166 | writew(value, priv->mmio + offset); |
| 167 | else |
| 168 | writeb((u8)value, priv->mmio + offset); |
| 169 | } |
| 170 | EXPORT_SYMBOL_GPL(rz_mtu3_shared_reg_write); |
| 171 | |
| 172 | void rz_mtu3_shared_reg_update_bit(struct rz_mtu3_channel *ch, u16 offset, |
| 173 | u16 pos, u8 val) |
| 174 | { |
| 175 | struct rz_mtu3 *mtu = dev_get_drvdata(ch->dev->parent); |
| 176 | struct rz_mtu3_priv *priv = mtu->priv_data; |
| 177 | unsigned long tmdr, flags; |
| 178 | |
Biju Das | d92df6f | 2023-08-15 08:34:45 +0100 | [diff] [blame] | 179 | spin_lock_irqsave(&priv->lock, flags); |
Biju Das | 654c293 | 2023-03-30 12:16:28 +0100 | [diff] [blame] | 180 | tmdr = rz_mtu3_shared_reg_read(ch, offset); |
| 181 | __assign_bit(pos, &tmdr, !!val); |
| 182 | rz_mtu3_shared_reg_write(ch, offset, tmdr); |
Biju Das | d92df6f | 2023-08-15 08:34:45 +0100 | [diff] [blame] | 183 | spin_unlock_irqrestore(&priv->lock, flags); |
Biju Das | 654c293 | 2023-03-30 12:16:28 +0100 | [diff] [blame] | 184 | } |
| 185 | EXPORT_SYMBOL_GPL(rz_mtu3_shared_reg_update_bit); |
| 186 | |
| 187 | static u16 rz_mtu3_get_tstr_offset(struct rz_mtu3_channel *ch) |
| 188 | { |
| 189 | u16 offset; |
| 190 | |
| 191 | switch (ch->channel_number) { |
| 192 | case RZ_MTU3_CHAN_0: |
| 193 | case RZ_MTU3_CHAN_1: |
| 194 | case RZ_MTU3_CHAN_2: |
| 195 | case RZ_MTU3_CHAN_3: |
| 196 | case RZ_MTU3_CHAN_4: |
| 197 | case RZ_MTU3_CHAN_8: |
| 198 | offset = RZ_MTU3_TSTRA; |
| 199 | break; |
| 200 | case RZ_MTU3_CHAN_5: |
| 201 | offset = RZ_MTU3_TSTR; |
| 202 | break; |
| 203 | case RZ_MTU3_CHAN_6: |
| 204 | case RZ_MTU3_CHAN_7: |
| 205 | offset = RZ_MTU3_TSTRB; |
| 206 | break; |
| 207 | default: |
| 208 | offset = 0; |
| 209 | break; |
| 210 | } |
| 211 | |
| 212 | return offset; |
| 213 | } |
| 214 | |
| 215 | static u8 rz_mtu3_get_tstr_bit_pos(struct rz_mtu3_channel *ch) |
| 216 | { |
| 217 | u8 bitpos; |
| 218 | |
| 219 | switch (ch->channel_number) { |
| 220 | case RZ_MTU3_CHAN_0: |
| 221 | case RZ_MTU3_CHAN_1: |
| 222 | case RZ_MTU3_CHAN_2: |
| 223 | case RZ_MTU3_CHAN_6: |
| 224 | case RZ_MTU3_CHAN_7: |
| 225 | bitpos = ch->channel_number; |
| 226 | break; |
| 227 | case RZ_MTU3_CHAN_3: |
| 228 | bitpos = 6; |
| 229 | break; |
| 230 | case RZ_MTU3_CHAN_4: |
| 231 | bitpos = 7; |
| 232 | break; |
| 233 | case RZ_MTU3_CHAN_5: |
| 234 | bitpos = 2; |
| 235 | break; |
| 236 | case RZ_MTU3_CHAN_8: |
| 237 | bitpos = 3; |
| 238 | break; |
| 239 | default: |
| 240 | bitpos = 0; |
| 241 | break; |
| 242 | } |
| 243 | |
| 244 | return bitpos; |
| 245 | } |
| 246 | |
| 247 | static void rz_mtu3_start_stop_ch(struct rz_mtu3_channel *ch, bool start) |
| 248 | { |
| 249 | struct rz_mtu3 *mtu = dev_get_drvdata(ch->dev->parent); |
| 250 | struct rz_mtu3_priv *priv = mtu->priv_data; |
| 251 | unsigned long flags, tstr; |
| 252 | u16 offset; |
| 253 | u8 bitpos; |
| 254 | |
Biju Das | a160d12 | 2023-08-15 08:34:44 +0100 | [diff] [blame] | 255 | offset = rz_mtu3_get_tstr_offset(ch); |
| 256 | bitpos = rz_mtu3_get_tstr_bit_pos(ch); |
| 257 | |
Biju Das | 654c293 | 2023-03-30 12:16:28 +0100 | [diff] [blame] | 258 | /* start stop register shared by multiple timer channels */ |
Biju Das | d92df6f | 2023-08-15 08:34:45 +0100 | [diff] [blame] | 259 | spin_lock_irqsave(&priv->lock, flags); |
Biju Das | 654c293 | 2023-03-30 12:16:28 +0100 | [diff] [blame] | 260 | |
Biju Das | 654c293 | 2023-03-30 12:16:28 +0100 | [diff] [blame] | 261 | tstr = rz_mtu3_shared_reg_read(ch, offset); |
| 262 | __assign_bit(bitpos, &tstr, start); |
| 263 | rz_mtu3_shared_reg_write(ch, offset, tstr); |
| 264 | |
Biju Das | d92df6f | 2023-08-15 08:34:45 +0100 | [diff] [blame] | 265 | spin_unlock_irqrestore(&priv->lock, flags); |
Biju Das | 654c293 | 2023-03-30 12:16:28 +0100 | [diff] [blame] | 266 | } |
| 267 | |
| 268 | bool rz_mtu3_is_enabled(struct rz_mtu3_channel *ch) |
| 269 | { |
| 270 | struct rz_mtu3 *mtu = dev_get_drvdata(ch->dev->parent); |
| 271 | struct rz_mtu3_priv *priv = mtu->priv_data; |
| 272 | unsigned long flags, tstr; |
Biju Das | 654c293 | 2023-03-30 12:16:28 +0100 | [diff] [blame] | 273 | u16 offset; |
| 274 | u8 bitpos; |
| 275 | |
Biju Das | 654c293 | 2023-03-30 12:16:28 +0100 | [diff] [blame] | 276 | offset = rz_mtu3_get_tstr_offset(ch); |
| 277 | bitpos = rz_mtu3_get_tstr_bit_pos(ch); |
Biju Das | 654c293 | 2023-03-30 12:16:28 +0100 | [diff] [blame] | 278 | |
Biju Das | a160d12 | 2023-08-15 08:34:44 +0100 | [diff] [blame] | 279 | /* start stop register shared by multiple timer channels */ |
Biju Das | d92df6f | 2023-08-15 08:34:45 +0100 | [diff] [blame] | 280 | spin_lock_irqsave(&priv->lock, flags); |
Biju Das | a160d12 | 2023-08-15 08:34:44 +0100 | [diff] [blame] | 281 | tstr = rz_mtu3_shared_reg_read(ch, offset); |
Biju Das | d92df6f | 2023-08-15 08:34:45 +0100 | [diff] [blame] | 282 | spin_unlock_irqrestore(&priv->lock, flags); |
Biju Das | 654c293 | 2023-03-30 12:16:28 +0100 | [diff] [blame] | 283 | |
Biju Das | a160d12 | 2023-08-15 08:34:44 +0100 | [diff] [blame] | 284 | return tstr & BIT(bitpos); |
Biju Das | 654c293 | 2023-03-30 12:16:28 +0100 | [diff] [blame] | 285 | } |
| 286 | EXPORT_SYMBOL_GPL(rz_mtu3_is_enabled); |
| 287 | |
| 288 | int rz_mtu3_enable(struct rz_mtu3_channel *ch) |
| 289 | { |
| 290 | /* enable channel */ |
| 291 | rz_mtu3_start_stop_ch(ch, true); |
| 292 | |
| 293 | return 0; |
| 294 | } |
| 295 | EXPORT_SYMBOL_GPL(rz_mtu3_enable); |
| 296 | |
| 297 | void rz_mtu3_disable(struct rz_mtu3_channel *ch) |
| 298 | { |
| 299 | /* disable channel */ |
| 300 | rz_mtu3_start_stop_ch(ch, false); |
| 301 | } |
| 302 | EXPORT_SYMBOL_GPL(rz_mtu3_disable); |
| 303 | |
| 304 | static void rz_mtu3_reset_assert(void *data) |
| 305 | { |
| 306 | struct rz_mtu3 *mtu = dev_get_drvdata(data); |
| 307 | struct rz_mtu3_priv *priv = mtu->priv_data; |
| 308 | |
| 309 | mfd_remove_devices(data); |
| 310 | reset_control_assert(priv->rstc); |
| 311 | } |
| 312 | |
| 313 | static const struct mfd_cell rz_mtu3_devs[] = { |
| 314 | { |
| 315 | .name = "rz-mtu3-counter", |
| 316 | }, |
| 317 | { |
| 318 | .name = "pwm-rz-mtu3", |
| 319 | }, |
| 320 | }; |
| 321 | |
| 322 | static int rz_mtu3_probe(struct platform_device *pdev) |
| 323 | { |
| 324 | struct rz_mtu3_priv *priv; |
| 325 | struct rz_mtu3 *ddata; |
| 326 | unsigned int i; |
| 327 | int ret; |
| 328 | |
| 329 | ddata = devm_kzalloc(&pdev->dev, sizeof(*ddata), GFP_KERNEL); |
| 330 | if (!ddata) |
| 331 | return -ENOMEM; |
| 332 | |
| 333 | ddata->priv_data = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); |
| 334 | if (!ddata->priv_data) |
| 335 | return -ENOMEM; |
| 336 | |
| 337 | priv = ddata->priv_data; |
| 338 | |
| 339 | priv->mmio = devm_platform_ioremap_resource(pdev, 0); |
| 340 | if (IS_ERR(priv->mmio)) |
| 341 | return PTR_ERR(priv->mmio); |
| 342 | |
| 343 | priv->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL); |
| 344 | if (IS_ERR(priv->rstc)) |
| 345 | return PTR_ERR(priv->rstc); |
| 346 | |
| 347 | ddata->clk = devm_clk_get(&pdev->dev, NULL); |
| 348 | if (IS_ERR(ddata->clk)) |
| 349 | return PTR_ERR(ddata->clk); |
| 350 | |
| 351 | reset_control_deassert(priv->rstc); |
Biju Das | d92df6f | 2023-08-15 08:34:45 +0100 | [diff] [blame] | 352 | spin_lock_init(&priv->lock); |
Biju Das | 654c293 | 2023-03-30 12:16:28 +0100 | [diff] [blame] | 353 | platform_set_drvdata(pdev, ddata); |
| 354 | |
| 355 | for (i = 0; i < RZ_MTU_NUM_CHANNELS; i++) { |
| 356 | ddata->channels[i].channel_number = i; |
| 357 | ddata->channels[i].is_busy = false; |
| 358 | mutex_init(&ddata->channels[i].lock); |
| 359 | } |
| 360 | |
| 361 | ret = mfd_add_devices(&pdev->dev, 0, rz_mtu3_devs, |
| 362 | ARRAY_SIZE(rz_mtu3_devs), NULL, 0, NULL); |
| 363 | if (ret < 0) |
| 364 | goto err_assert; |
| 365 | |
| 366 | return devm_add_action_or_reset(&pdev->dev, rz_mtu3_reset_assert, |
| 367 | &pdev->dev); |
| 368 | |
| 369 | err_assert: |
| 370 | reset_control_assert(priv->rstc); |
| 371 | return ret; |
| 372 | } |
| 373 | |
| 374 | static const struct of_device_id rz_mtu3_of_match[] = { |
| 375 | { .compatible = "renesas,rz-mtu3", }, |
| 376 | { /* sentinel */ } |
| 377 | }; |
| 378 | MODULE_DEVICE_TABLE(of, rz_mtu3_of_match); |
| 379 | |
| 380 | static struct platform_driver rz_mtu3_driver = { |
| 381 | .probe = rz_mtu3_probe, |
| 382 | .driver = { |
| 383 | .name = "rz-mtu3", |
| 384 | .of_match_table = rz_mtu3_of_match, |
| 385 | }, |
| 386 | }; |
| 387 | module_platform_driver(rz_mtu3_driver); |
| 388 | |
| 389 | MODULE_AUTHOR("Biju Das <biju.das.jz@bp.renesas.com>"); |
| 390 | MODULE_DESCRIPTION("Renesas RZ/G2L MTU3a Core Driver"); |
| 391 | MODULE_LICENSE("GPL"); |