0001
0002
0003
0004
0005
0006 #define pr_fmt(fmt) "aspeed-kcs-bmc: " fmt
0007
0008 #include <linux/atomic.h>
0009 #include <linux/errno.h>
0010 #include <linux/interrupt.h>
0011 #include <linux/io.h>
0012 #include <linux/irq.h>
0013 #include <linux/mfd/syscon.h>
0014 #include <linux/module.h>
0015 #include <linux/of.h>
0016 #include <linux/of_address.h>
0017 #include <linux/of_device.h>
0018 #include <linux/platform_device.h>
0019 #include <linux/poll.h>
0020 #include <linux/regmap.h>
0021 #include <linux/sched.h>
0022 #include <linux/slab.h>
0023 #include <linux/timer.h>
0024
0025 #include "kcs_bmc_device.h"
0026
0027
0028 #define DEVICE_NAME "ast-kcs-bmc"
0029
0030 #define KCS_CHANNEL_MAX 4
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043 #define LPC_TYIRQX_LOW 0b00
0044 #define LPC_TYIRQX_HIGH 0b01
0045 #define LPC_TYIRQX_RSVD 0b10
0046 #define LPC_TYIRQX_RISING 0b11
0047
0048 #define LPC_HICR0 0x000
0049 #define LPC_HICR0_LPC3E BIT(7)
0050 #define LPC_HICR0_LPC2E BIT(6)
0051 #define LPC_HICR0_LPC1E BIT(5)
0052 #define LPC_HICR2 0x008
0053 #define LPC_HICR2_IBFIE3 BIT(3)
0054 #define LPC_HICR2_IBFIE2 BIT(2)
0055 #define LPC_HICR2_IBFIE1 BIT(1)
0056 #define LPC_HICR4 0x010
0057 #define LPC_HICR4_LADR12AS BIT(7)
0058 #define LPC_HICR4_KCSENBL BIT(2)
0059 #define LPC_SIRQCR0 0x070
0060
0061 #define LPC_SIRQCR0_IRQ12E1 BIT(1)
0062 #define LPC_SIRQCR0_IRQ1E1 BIT(0)
0063 #define LPC_HICR5 0x080
0064 #define LPC_HICR5_ID3IRQX_MASK GENMASK(23, 20)
0065 #define LPC_HICR5_ID3IRQX_SHIFT 20
0066 #define LPC_HICR5_ID2IRQX_MASK GENMASK(19, 16)
0067 #define LPC_HICR5_ID2IRQX_SHIFT 16
0068 #define LPC_HICR5_SEL3IRQX BIT(15)
0069 #define LPC_HICR5_IRQXE3 BIT(14)
0070 #define LPC_HICR5_SEL2IRQX BIT(13)
0071 #define LPC_HICR5_IRQXE2 BIT(12)
0072 #define LPC_LADR3H 0x014
0073 #define LPC_LADR3L 0x018
0074 #define LPC_LADR12H 0x01C
0075 #define LPC_LADR12L 0x020
0076 #define LPC_IDR1 0x024
0077 #define LPC_IDR2 0x028
0078 #define LPC_IDR3 0x02C
0079 #define LPC_ODR1 0x030
0080 #define LPC_ODR2 0x034
0081 #define LPC_ODR3 0x038
0082 #define LPC_STR1 0x03C
0083 #define LPC_STR2 0x040
0084 #define LPC_STR3 0x044
0085 #define LPC_HICRB 0x100
0086 #define LPC_HICRB_EN16LADR2 BIT(5)
0087 #define LPC_HICRB_EN16LADR1 BIT(4)
0088 #define LPC_HICRB_IBFIE4 BIT(1)
0089 #define LPC_HICRB_LPC4E BIT(0)
0090 #define LPC_HICRC 0x104
0091 #define LPC_HICRC_ID4IRQX_MASK GENMASK(7, 4)
0092 #define LPC_HICRC_ID4IRQX_SHIFT 4
0093 #define LPC_HICRC_TY4IRQX_MASK GENMASK(3, 2)
0094 #define LPC_HICRC_TY4IRQX_SHIFT 2
0095 #define LPC_HICRC_OBF4_AUTO_CLR BIT(1)
0096 #define LPC_HICRC_IRQXE4 BIT(0)
0097 #define LPC_LADR4 0x110
0098 #define LPC_IDR4 0x114
0099 #define LPC_ODR4 0x118
0100 #define LPC_STR4 0x11C
0101 #define LPC_LSADR12 0x120
0102 #define LPC_LSADR12_LSADR2_MASK GENMASK(31, 16)
0103 #define LPC_LSADR12_LSADR2_SHIFT 16
0104 #define LPC_LSADR12_LSADR1_MASK GENMASK(15, 0)
0105 #define LPC_LSADR12_LSADR1_SHIFT 0
0106
0107 #define OBE_POLL_PERIOD (HZ / 2)
0108
0109 enum aspeed_kcs_irq_mode {
0110 aspeed_kcs_irq_none,
0111 aspeed_kcs_irq_serirq,
0112 };
0113
0114 struct aspeed_kcs_bmc {
0115 struct kcs_bmc_device kcs_bmc;
0116
0117 struct regmap *map;
0118
0119 struct {
0120 enum aspeed_kcs_irq_mode mode;
0121 int id;
0122 } upstream_irq;
0123
0124 struct {
0125 spinlock_t lock;
0126 bool remove;
0127 struct timer_list timer;
0128 } obe;
0129 };
0130
0131 static inline struct aspeed_kcs_bmc *to_aspeed_kcs_bmc(struct kcs_bmc_device *kcs_bmc)
0132 {
0133 return container_of(kcs_bmc, struct aspeed_kcs_bmc, kcs_bmc);
0134 }
0135
0136 static u8 aspeed_kcs_inb(struct kcs_bmc_device *kcs_bmc, u32 reg)
0137 {
0138 struct aspeed_kcs_bmc *priv = to_aspeed_kcs_bmc(kcs_bmc);
0139 u32 val = 0;
0140 int rc;
0141
0142 rc = regmap_read(priv->map, reg, &val);
0143 WARN(rc != 0, "regmap_read() failed: %d\n", rc);
0144
0145 return rc == 0 ? (u8) val : 0;
0146 }
0147
0148 static void aspeed_kcs_outb(struct kcs_bmc_device *kcs_bmc, u32 reg, u8 data)
0149 {
0150 struct aspeed_kcs_bmc *priv = to_aspeed_kcs_bmc(kcs_bmc);
0151 int rc;
0152
0153 rc = regmap_write(priv->map, reg, data);
0154 WARN(rc != 0, "regmap_write() failed: %d\n", rc);
0155
0156
0157
0158 switch (reg) {
0159 case LPC_ODR1:
0160 case LPC_ODR2:
0161 case LPC_ODR3:
0162 case LPC_ODR4:
0163 break;
0164 default:
0165 return;
0166 }
0167
0168 if (priv->upstream_irq.mode != aspeed_kcs_irq_serirq)
0169 return;
0170
0171 switch (kcs_bmc->channel) {
0172 case 1:
0173 switch (priv->upstream_irq.id) {
0174 case 12:
0175 regmap_update_bits(priv->map, LPC_SIRQCR0, LPC_SIRQCR0_IRQ12E1,
0176 LPC_SIRQCR0_IRQ12E1);
0177 break;
0178 case 1:
0179 regmap_update_bits(priv->map, LPC_SIRQCR0, LPC_SIRQCR0_IRQ1E1,
0180 LPC_SIRQCR0_IRQ1E1);
0181 break;
0182 default:
0183 break;
0184 }
0185 break;
0186 case 2:
0187 regmap_update_bits(priv->map, LPC_HICR5, LPC_HICR5_IRQXE2, LPC_HICR5_IRQXE2);
0188 break;
0189 case 3:
0190 regmap_update_bits(priv->map, LPC_HICR5, LPC_HICR5_IRQXE3, LPC_HICR5_IRQXE3);
0191 break;
0192 case 4:
0193 regmap_update_bits(priv->map, LPC_HICRC, LPC_HICRC_IRQXE4, LPC_HICRC_IRQXE4);
0194 break;
0195 default:
0196 break;
0197 }
0198 }
0199
0200 static void aspeed_kcs_updateb(struct kcs_bmc_device *kcs_bmc, u32 reg, u8 mask, u8 val)
0201 {
0202 struct aspeed_kcs_bmc *priv = to_aspeed_kcs_bmc(kcs_bmc);
0203 int rc;
0204
0205 rc = regmap_update_bits(priv->map, reg, mask, val);
0206 WARN(rc != 0, "regmap_update_bits() failed: %d\n", rc);
0207 }
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219
0220
0221
0222 static int aspeed_kcs_set_address(struct kcs_bmc_device *kcs_bmc, u32 addrs[2], int nr_addrs)
0223 {
0224 struct aspeed_kcs_bmc *priv = to_aspeed_kcs_bmc(kcs_bmc);
0225
0226 if (WARN_ON(nr_addrs < 1 || nr_addrs > 2))
0227 return -EINVAL;
0228
0229 switch (priv->kcs_bmc.channel) {
0230 case 1:
0231 regmap_update_bits(priv->map, LPC_HICR4, LPC_HICR4_LADR12AS, 0);
0232 regmap_write(priv->map, LPC_LADR12H, addrs[0] >> 8);
0233 regmap_write(priv->map, LPC_LADR12L, addrs[0] & 0xFF);
0234 if (nr_addrs == 2) {
0235 regmap_update_bits(priv->map, LPC_LSADR12, LPC_LSADR12_LSADR1_MASK,
0236 addrs[1] << LPC_LSADR12_LSADR1_SHIFT);
0237
0238 regmap_update_bits(priv->map, LPC_HICRB, LPC_HICRB_EN16LADR1,
0239 LPC_HICRB_EN16LADR1);
0240 }
0241 break;
0242
0243 case 2:
0244 regmap_update_bits(priv->map, LPC_HICR4, LPC_HICR4_LADR12AS, LPC_HICR4_LADR12AS);
0245 regmap_write(priv->map, LPC_LADR12H, addrs[0] >> 8);
0246 regmap_write(priv->map, LPC_LADR12L, addrs[0] & 0xFF);
0247 if (nr_addrs == 2) {
0248 regmap_update_bits(priv->map, LPC_LSADR12, LPC_LSADR12_LSADR2_MASK,
0249 addrs[1] << LPC_LSADR12_LSADR2_SHIFT);
0250
0251 regmap_update_bits(priv->map, LPC_HICRB, LPC_HICRB_EN16LADR2,
0252 LPC_HICRB_EN16LADR2);
0253 }
0254 break;
0255
0256 case 3:
0257 if (nr_addrs == 2) {
0258 dev_err(priv->kcs_bmc.dev,
0259 "Channel 3 only supports inferred status IO address\n");
0260 return -EINVAL;
0261 }
0262
0263 regmap_write(priv->map, LPC_LADR3H, addrs[0] >> 8);
0264 regmap_write(priv->map, LPC_LADR3L, addrs[0] & 0xFF);
0265 break;
0266
0267 case 4:
0268 if (nr_addrs == 1)
0269 regmap_write(priv->map, LPC_LADR4, ((addrs[0] + 1) << 16) | addrs[0]);
0270 else
0271 regmap_write(priv->map, LPC_LADR4, (addrs[1] << 16) | addrs[0]);
0272
0273 break;
0274
0275 default:
0276 return -EINVAL;
0277 }
0278
0279 return 0;
0280 }
0281
0282 static inline int aspeed_kcs_map_serirq_type(u32 dt_type)
0283 {
0284 switch (dt_type) {
0285 case IRQ_TYPE_EDGE_RISING:
0286 return LPC_TYIRQX_RISING;
0287 case IRQ_TYPE_LEVEL_HIGH:
0288 return LPC_TYIRQX_HIGH;
0289 case IRQ_TYPE_LEVEL_LOW:
0290 return LPC_TYIRQX_LOW;
0291 default:
0292 return -EINVAL;
0293 }
0294 }
0295
0296 static int aspeed_kcs_config_upstream_irq(struct aspeed_kcs_bmc *priv, u32 id, u32 dt_type)
0297 {
0298 unsigned int mask, val, hw_type;
0299 int ret;
0300
0301 if (id > 15)
0302 return -EINVAL;
0303
0304 ret = aspeed_kcs_map_serirq_type(dt_type);
0305 if (ret < 0)
0306 return ret;
0307 hw_type = ret;
0308
0309 priv->upstream_irq.mode = aspeed_kcs_irq_serirq;
0310 priv->upstream_irq.id = id;
0311
0312 switch (priv->kcs_bmc.channel) {
0313 case 1:
0314
0315 break;
0316 case 2:
0317 if (!(hw_type == LPC_TYIRQX_LOW || hw_type == LPC_TYIRQX_HIGH))
0318 return -EINVAL;
0319
0320 mask = LPC_HICR5_SEL2IRQX | LPC_HICR5_ID2IRQX_MASK;
0321 val = (id << LPC_HICR5_ID2IRQX_SHIFT);
0322 val |= (hw_type == LPC_TYIRQX_HIGH) ? LPC_HICR5_SEL2IRQX : 0;
0323 regmap_update_bits(priv->map, LPC_HICR5, mask, val);
0324
0325 break;
0326 case 3:
0327 if (!(hw_type == LPC_TYIRQX_LOW || hw_type == LPC_TYIRQX_HIGH))
0328 return -EINVAL;
0329
0330 mask = LPC_HICR5_SEL3IRQX | LPC_HICR5_ID3IRQX_MASK;
0331 val = (id << LPC_HICR5_ID3IRQX_SHIFT);
0332 val |= (hw_type == LPC_TYIRQX_HIGH) ? LPC_HICR5_SEL3IRQX : 0;
0333 regmap_update_bits(priv->map, LPC_HICR5, mask, val);
0334
0335 break;
0336 case 4:
0337 mask = LPC_HICRC_ID4IRQX_MASK | LPC_HICRC_TY4IRQX_MASK | LPC_HICRC_OBF4_AUTO_CLR;
0338 val = (id << LPC_HICRC_ID4IRQX_SHIFT) | (hw_type << LPC_HICRC_TY4IRQX_SHIFT);
0339 regmap_update_bits(priv->map, LPC_HICRC, mask, val);
0340 break;
0341 default:
0342 dev_warn(priv->kcs_bmc.dev,
0343 "SerIRQ configuration not supported on KCS channel %d\n",
0344 priv->kcs_bmc.channel);
0345 return -EINVAL;
0346 }
0347
0348 return 0;
0349 }
0350
0351 static void aspeed_kcs_enable_channel(struct kcs_bmc_device *kcs_bmc, bool enable)
0352 {
0353 struct aspeed_kcs_bmc *priv = to_aspeed_kcs_bmc(kcs_bmc);
0354
0355 switch (kcs_bmc->channel) {
0356 case 1:
0357 regmap_update_bits(priv->map, LPC_HICR0, LPC_HICR0_LPC1E, enable * LPC_HICR0_LPC1E);
0358 return;
0359 case 2:
0360 regmap_update_bits(priv->map, LPC_HICR0, LPC_HICR0_LPC2E, enable * LPC_HICR0_LPC2E);
0361 return;
0362 case 3:
0363 regmap_update_bits(priv->map, LPC_HICR0, LPC_HICR0_LPC3E, enable * LPC_HICR0_LPC3E);
0364 regmap_update_bits(priv->map, LPC_HICR4,
0365 LPC_HICR4_KCSENBL, enable * LPC_HICR4_KCSENBL);
0366 return;
0367 case 4:
0368 regmap_update_bits(priv->map, LPC_HICRB, LPC_HICRB_LPC4E, enable * LPC_HICRB_LPC4E);
0369 return;
0370 default:
0371 pr_warn("%s: Unsupported channel: %d", __func__, kcs_bmc->channel);
0372 return;
0373 }
0374 }
0375
0376 static void aspeed_kcs_check_obe(struct timer_list *timer)
0377 {
0378 struct aspeed_kcs_bmc *priv = container_of(timer, struct aspeed_kcs_bmc, obe.timer);
0379 unsigned long flags;
0380 u8 str;
0381
0382 spin_lock_irqsave(&priv->obe.lock, flags);
0383 if (priv->obe.remove) {
0384 spin_unlock_irqrestore(&priv->obe.lock, flags);
0385 return;
0386 }
0387
0388 str = aspeed_kcs_inb(&priv->kcs_bmc, priv->kcs_bmc.ioreg.str);
0389 if (str & KCS_BMC_STR_OBF) {
0390 mod_timer(timer, jiffies + OBE_POLL_PERIOD);
0391 spin_unlock_irqrestore(&priv->obe.lock, flags);
0392 return;
0393 }
0394 spin_unlock_irqrestore(&priv->obe.lock, flags);
0395
0396 kcs_bmc_handle_event(&priv->kcs_bmc);
0397 }
0398
0399 static void aspeed_kcs_irq_mask_update(struct kcs_bmc_device *kcs_bmc, u8 mask, u8 state)
0400 {
0401 struct aspeed_kcs_bmc *priv = to_aspeed_kcs_bmc(kcs_bmc);
0402
0403
0404 if (mask & KCS_BMC_EVENT_TYPE_OBE) {
0405 if (KCS_BMC_EVENT_TYPE_OBE & state)
0406 mod_timer(&priv->obe.timer, jiffies + OBE_POLL_PERIOD);
0407 else
0408 del_timer(&priv->obe.timer);
0409 }
0410
0411 if (mask & KCS_BMC_EVENT_TYPE_IBF) {
0412 const bool enable = !!(state & KCS_BMC_EVENT_TYPE_IBF);
0413
0414 switch (kcs_bmc->channel) {
0415 case 1:
0416 regmap_update_bits(priv->map, LPC_HICR2, LPC_HICR2_IBFIE1,
0417 enable * LPC_HICR2_IBFIE1);
0418 return;
0419 case 2:
0420 regmap_update_bits(priv->map, LPC_HICR2, LPC_HICR2_IBFIE2,
0421 enable * LPC_HICR2_IBFIE2);
0422 return;
0423 case 3:
0424 regmap_update_bits(priv->map, LPC_HICR2, LPC_HICR2_IBFIE3,
0425 enable * LPC_HICR2_IBFIE3);
0426 return;
0427 case 4:
0428 regmap_update_bits(priv->map, LPC_HICRB, LPC_HICRB_IBFIE4,
0429 enable * LPC_HICRB_IBFIE4);
0430 return;
0431 default:
0432 pr_warn("%s: Unsupported channel: %d", __func__, kcs_bmc->channel);
0433 return;
0434 }
0435 }
0436 }
0437
0438 static const struct kcs_bmc_device_ops aspeed_kcs_ops = {
0439 .irq_mask_update = aspeed_kcs_irq_mask_update,
0440 .io_inputb = aspeed_kcs_inb,
0441 .io_outputb = aspeed_kcs_outb,
0442 .io_updateb = aspeed_kcs_updateb,
0443 };
0444
0445 static irqreturn_t aspeed_kcs_irq(int irq, void *arg)
0446 {
0447 struct kcs_bmc_device *kcs_bmc = arg;
0448
0449 return kcs_bmc_handle_event(kcs_bmc);
0450 }
0451
0452 static int aspeed_kcs_config_downstream_irq(struct kcs_bmc_device *kcs_bmc,
0453 struct platform_device *pdev)
0454 {
0455 struct device *dev = &pdev->dev;
0456 int irq;
0457
0458 irq = platform_get_irq(pdev, 0);
0459 if (irq < 0)
0460 return irq;
0461
0462 return devm_request_irq(dev, irq, aspeed_kcs_irq, IRQF_SHARED,
0463 dev_name(dev), kcs_bmc);
0464 }
0465
0466 static const struct kcs_ioreg ast_kcs_bmc_ioregs[KCS_CHANNEL_MAX] = {
0467 { .idr = LPC_IDR1, .odr = LPC_ODR1, .str = LPC_STR1 },
0468 { .idr = LPC_IDR2, .odr = LPC_ODR2, .str = LPC_STR2 },
0469 { .idr = LPC_IDR3, .odr = LPC_ODR3, .str = LPC_STR3 },
0470 { .idr = LPC_IDR4, .odr = LPC_ODR4, .str = LPC_STR4 },
0471 };
0472
0473 static int aspeed_kcs_of_get_channel(struct platform_device *pdev)
0474 {
0475 struct device_node *np;
0476 struct kcs_ioreg ioreg;
0477 const __be32 *reg;
0478 int i;
0479
0480 np = pdev->dev.of_node;
0481
0482
0483 reg = of_get_address(np, 0, NULL, NULL);
0484 if (!reg)
0485 return -EINVAL;
0486 ioreg.idr = be32_to_cpup(reg);
0487
0488 reg = of_get_address(np, 1, NULL, NULL);
0489 if (!reg)
0490 return -EINVAL;
0491 ioreg.odr = be32_to_cpup(reg);
0492
0493 reg = of_get_address(np, 2, NULL, NULL);
0494 if (!reg)
0495 return -EINVAL;
0496 ioreg.str = be32_to_cpup(reg);
0497
0498 for (i = 0; i < ARRAY_SIZE(ast_kcs_bmc_ioregs); i++) {
0499 if (!memcmp(&ast_kcs_bmc_ioregs[i], &ioreg, sizeof(ioreg)))
0500 return i + 1;
0501 }
0502 return -EINVAL;
0503 }
0504
0505 static int
0506 aspeed_kcs_of_get_io_address(struct platform_device *pdev, u32 addrs[2])
0507 {
0508 int rc;
0509
0510 rc = of_property_read_variable_u32_array(pdev->dev.of_node,
0511 "aspeed,lpc-io-reg",
0512 addrs, 1, 2);
0513 if (rc < 0) {
0514 dev_err(&pdev->dev, "No valid 'aspeed,lpc-io-reg' configured\n");
0515 return rc;
0516 }
0517
0518 if (addrs[0] > 0xffff) {
0519 dev_err(&pdev->dev, "Invalid data address in 'aspeed,lpc-io-reg'\n");
0520 return -EINVAL;
0521 }
0522
0523 if (rc == 2 && addrs[1] > 0xffff) {
0524 dev_err(&pdev->dev, "Invalid status address in 'aspeed,lpc-io-reg'\n");
0525 return -EINVAL;
0526 }
0527
0528 return rc;
0529 }
0530
0531 static int aspeed_kcs_probe(struct platform_device *pdev)
0532 {
0533 struct kcs_bmc_device *kcs_bmc;
0534 struct aspeed_kcs_bmc *priv;
0535 struct device_node *np;
0536 bool have_upstream_irq;
0537 u32 upstream_irq[2];
0538 int rc, channel;
0539 int nr_addrs;
0540 u32 addrs[2];
0541
0542 np = pdev->dev.of_node->parent;
0543 if (!of_device_is_compatible(np, "aspeed,ast2400-lpc-v2") &&
0544 !of_device_is_compatible(np, "aspeed,ast2500-lpc-v2") &&
0545 !of_device_is_compatible(np, "aspeed,ast2600-lpc-v2")) {
0546 dev_err(&pdev->dev, "unsupported LPC device binding\n");
0547 return -ENODEV;
0548 }
0549
0550 channel = aspeed_kcs_of_get_channel(pdev);
0551 if (channel < 0)
0552 return channel;
0553
0554 nr_addrs = aspeed_kcs_of_get_io_address(pdev, addrs);
0555 if (nr_addrs < 0)
0556 return nr_addrs;
0557
0558 np = pdev->dev.of_node;
0559 rc = of_property_read_u32_array(np, "aspeed,lpc-interrupts", upstream_irq, 2);
0560 if (rc && rc != -EINVAL)
0561 return -EINVAL;
0562
0563 have_upstream_irq = !rc;
0564
0565 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
0566 if (!priv)
0567 return -ENOMEM;
0568
0569 kcs_bmc = &priv->kcs_bmc;
0570 kcs_bmc->dev = &pdev->dev;
0571 kcs_bmc->channel = channel;
0572 kcs_bmc->ioreg = ast_kcs_bmc_ioregs[channel - 1];
0573 kcs_bmc->ops = &aspeed_kcs_ops;
0574
0575 priv->map = syscon_node_to_regmap(pdev->dev.parent->of_node);
0576 if (IS_ERR(priv->map)) {
0577 dev_err(&pdev->dev, "Couldn't get regmap\n");
0578 return -ENODEV;
0579 }
0580
0581 spin_lock_init(&priv->obe.lock);
0582 priv->obe.remove = false;
0583 timer_setup(&priv->obe.timer, aspeed_kcs_check_obe, 0);
0584
0585 rc = aspeed_kcs_set_address(kcs_bmc, addrs, nr_addrs);
0586 if (rc)
0587 return rc;
0588
0589
0590 rc = aspeed_kcs_config_downstream_irq(kcs_bmc, pdev);
0591 if (rc)
0592 return rc;
0593
0594
0595 if (have_upstream_irq) {
0596 rc = aspeed_kcs_config_upstream_irq(priv, upstream_irq[0], upstream_irq[1]);
0597 if (rc < 0)
0598 return rc;
0599 } else {
0600 priv->upstream_irq.mode = aspeed_kcs_irq_none;
0601 }
0602
0603 platform_set_drvdata(pdev, priv);
0604
0605 aspeed_kcs_irq_mask_update(kcs_bmc, (KCS_BMC_EVENT_TYPE_IBF | KCS_BMC_EVENT_TYPE_OBE), 0);
0606 aspeed_kcs_enable_channel(kcs_bmc, true);
0607
0608 rc = kcs_bmc_add_device(&priv->kcs_bmc);
0609 if (rc) {
0610 dev_warn(&pdev->dev, "Failed to register channel %d: %d\n", kcs_bmc->channel, rc);
0611 return rc;
0612 }
0613
0614 dev_info(&pdev->dev, "Initialised channel %d at 0x%x\n",
0615 kcs_bmc->channel, addrs[0]);
0616
0617 return 0;
0618 }
0619
0620 static int aspeed_kcs_remove(struct platform_device *pdev)
0621 {
0622 struct aspeed_kcs_bmc *priv = platform_get_drvdata(pdev);
0623 struct kcs_bmc_device *kcs_bmc = &priv->kcs_bmc;
0624
0625 kcs_bmc_remove_device(kcs_bmc);
0626
0627 aspeed_kcs_enable_channel(kcs_bmc, false);
0628 aspeed_kcs_irq_mask_update(kcs_bmc, (KCS_BMC_EVENT_TYPE_IBF | KCS_BMC_EVENT_TYPE_OBE), 0);
0629
0630
0631 spin_lock_irq(&priv->obe.lock);
0632 priv->obe.remove = true;
0633 spin_unlock_irq(&priv->obe.lock);
0634 del_timer_sync(&priv->obe.timer);
0635
0636 return 0;
0637 }
0638
0639 static const struct of_device_id ast_kcs_bmc_match[] = {
0640 { .compatible = "aspeed,ast2400-kcs-bmc-v2" },
0641 { .compatible = "aspeed,ast2500-kcs-bmc-v2" },
0642 { .compatible = "aspeed,ast2600-kcs-bmc" },
0643 { }
0644 };
0645 MODULE_DEVICE_TABLE(of, ast_kcs_bmc_match);
0646
0647 static struct platform_driver ast_kcs_bmc_driver = {
0648 .driver = {
0649 .name = DEVICE_NAME,
0650 .of_match_table = ast_kcs_bmc_match,
0651 },
0652 .probe = aspeed_kcs_probe,
0653 .remove = aspeed_kcs_remove,
0654 };
0655 module_platform_driver(ast_kcs_bmc_driver);
0656
0657 MODULE_LICENSE("GPL v2");
0658 MODULE_AUTHOR("Haiyue Wang <haiyue.wang@linux.intel.com>");
0659 MODULE_AUTHOR("Andrew Jeffery <andrew@aj.id.au>");
0660 MODULE_DESCRIPTION("Aspeed device interface to the KCS BMC device");