• Home
  • Raw
  • Download

Lines Matching +full:ast2500 +full:- +full:lpc +full:- +full:host

1 // SPDX-License-Identifier: GPL-2.0-or-later
5 * Provides a simple driver to control the ASPEED LPC snoop interface which
7 * the host to an arbitrary LPC I/O port.
9 * Typically used by the BMC to "watch" host boot progress via port
26 #define DEVICE_NAME "aspeed-lpc-snoop"
54 /* The ast2400 has bits 14 and 15 as reserved, whereas the ast2500
76 return container_of(file->private_data, in snoop_file_to_chan()
88 if (kfifo_is_empty(&chan->fifo)) { in snoop_file_read()
89 if (file->f_flags & O_NONBLOCK) in snoop_file_read()
90 return -EAGAIN; in snoop_file_read()
91 ret = wait_event_interruptible(chan->wq, in snoop_file_read()
92 !kfifo_is_empty(&chan->fifo)); in snoop_file_read()
93 if (ret == -ERESTARTSYS) in snoop_file_read()
94 return -EINTR; in snoop_file_read()
96 ret = kfifo_to_user(&chan->fifo, buffer, count, &copied); in snoop_file_read()
108 poll_wait(file, &chan->wq, pt); in snoop_file_poll()
109 return !kfifo_is_empty(&chan->fifo) ? EPOLLIN : 0; in snoop_file_poll()
122 if (!kfifo_initialized(&chan->fifo)) in put_fifo_with_discard()
124 if (kfifo_is_full(&chan->fifo)) in put_fifo_with_discard()
125 kfifo_skip(&chan->fifo); in put_fifo_with_discard()
126 kfifo_put(&chan->fifo, val); in put_fifo_with_discard()
127 wake_up_interruptible(&chan->wq); in put_fifo_with_discard()
135 if (regmap_read(lpc_snoop->regmap, HICR6, &reg)) in aspeed_lpc_snoop_irq()
144 regmap_write(lpc_snoop->regmap, HICR6, reg); in aspeed_lpc_snoop_irq()
147 regmap_read(lpc_snoop->regmap, SNPWDR, &data); in aspeed_lpc_snoop_irq()
152 put_fifo_with_discard(&lpc_snoop->chan[0], val); in aspeed_lpc_snoop_irq()
157 put_fifo_with_discard(&lpc_snoop->chan[1], val); in aspeed_lpc_snoop_irq()
166 struct device *dev = &pdev->dev; in aspeed_lpc_snoop_config_irq()
169 lpc_snoop->irq = platform_get_irq(pdev, 0); in aspeed_lpc_snoop_config_irq()
170 if (lpc_snoop->irq < 0) in aspeed_lpc_snoop_config_irq()
171 return -ENODEV; in aspeed_lpc_snoop_config_irq()
173 rc = devm_request_irq(dev, lpc_snoop->irq, in aspeed_lpc_snoop_config_irq()
177 dev_warn(dev, "Unable to request IRQ %d\n", lpc_snoop->irq); in aspeed_lpc_snoop_config_irq()
178 lpc_snoop->irq = 0; in aspeed_lpc_snoop_config_irq()
194 if (WARN_ON(lpc_snoop->chan[channel].enabled)) in aspeed_lpc_enable_snoop()
195 return -EBUSY; in aspeed_lpc_enable_snoop()
197 init_waitqueue_head(&lpc_snoop->chan[channel].wq); in aspeed_lpc_enable_snoop()
199 rc = kfifo_alloc(&lpc_snoop->chan[channel].fifo, in aspeed_lpc_enable_snoop()
204 lpc_snoop->chan[channel].miscdev.minor = MISC_DYNAMIC_MINOR; in aspeed_lpc_enable_snoop()
205 lpc_snoop->chan[channel].miscdev.name = in aspeed_lpc_enable_snoop()
207 if (!lpc_snoop->chan[channel].miscdev.name) { in aspeed_lpc_enable_snoop()
208 rc = -ENOMEM; in aspeed_lpc_enable_snoop()
211 lpc_snoop->chan[channel].miscdev.fops = &snoop_fops; in aspeed_lpc_enable_snoop()
212 lpc_snoop->chan[channel].miscdev.parent = dev; in aspeed_lpc_enable_snoop()
213 rc = misc_register(&lpc_snoop->chan[channel].miscdev); in aspeed_lpc_enable_snoop()
217 /* Enable LPC snoop channel at requested port */ in aspeed_lpc_enable_snoop()
232 rc = -EINVAL; in aspeed_lpc_enable_snoop()
236 regmap_update_bits(lpc_snoop->regmap, HICR5, hicr5_en, hicr5_en); in aspeed_lpc_enable_snoop()
237 regmap_update_bits(lpc_snoop->regmap, SNPWADR, snpwadr_mask, in aspeed_lpc_enable_snoop()
239 if (model_data->has_hicrb_ensnp) in aspeed_lpc_enable_snoop()
240 regmap_update_bits(lpc_snoop->regmap, HICRB, in aspeed_lpc_enable_snoop()
243 lpc_snoop->chan[channel].enabled = true; in aspeed_lpc_enable_snoop()
248 misc_deregister(&lpc_snoop->chan[channel].miscdev); in aspeed_lpc_enable_snoop()
250 kfifo_free(&lpc_snoop->chan[channel].fifo); in aspeed_lpc_enable_snoop()
257 if (!lpc_snoop->chan[channel].enabled) in aspeed_lpc_disable_snoop()
262 regmap_update_bits(lpc_snoop->regmap, HICR5, in aspeed_lpc_disable_snoop()
267 regmap_update_bits(lpc_snoop->regmap, HICR5, in aspeed_lpc_disable_snoop()
275 lpc_snoop->chan[channel].enabled = false; in aspeed_lpc_disable_snoop()
277 misc_deregister(&lpc_snoop->chan[channel].miscdev); in aspeed_lpc_disable_snoop()
278 kfifo_free(&lpc_snoop->chan[channel].fifo); in aspeed_lpc_disable_snoop()
289 dev = &pdev->dev; in aspeed_lpc_snoop_probe()
293 return -ENOMEM; in aspeed_lpc_snoop_probe()
295 np = pdev->dev.parent->of_node; in aspeed_lpc_snoop_probe()
296 if (!of_device_is_compatible(np, "aspeed,ast2400-lpc-v2") && in aspeed_lpc_snoop_probe()
297 !of_device_is_compatible(np, "aspeed,ast2500-lpc-v2") && in aspeed_lpc_snoop_probe()
298 !of_device_is_compatible(np, "aspeed,ast2600-lpc-v2")) { in aspeed_lpc_snoop_probe()
299 dev_err(dev, "unsupported LPC device binding\n"); in aspeed_lpc_snoop_probe()
300 return -ENODEV; in aspeed_lpc_snoop_probe()
303 lpc_snoop->regmap = syscon_node_to_regmap(np); in aspeed_lpc_snoop_probe()
304 if (IS_ERR(lpc_snoop->regmap)) { in aspeed_lpc_snoop_probe()
306 return -ENODEV; in aspeed_lpc_snoop_probe()
309 dev_set_drvdata(&pdev->dev, lpc_snoop); in aspeed_lpc_snoop_probe()
311 rc = of_property_read_u32_index(dev->of_node, "snoop-ports", 0, &port); in aspeed_lpc_snoop_probe()
314 return -ENODEV; in aspeed_lpc_snoop_probe()
317 lpc_snoop->clk = devm_clk_get(dev, NULL); in aspeed_lpc_snoop_probe()
318 if (IS_ERR(lpc_snoop->clk)) { in aspeed_lpc_snoop_probe()
319 rc = PTR_ERR(lpc_snoop->clk); in aspeed_lpc_snoop_probe()
320 if (rc != -EPROBE_DEFER) in aspeed_lpc_snoop_probe()
324 rc = clk_prepare_enable(lpc_snoop->clk); in aspeed_lpc_snoop_probe()
339 if (of_property_read_u32_index(dev->of_node, "snoop-ports", in aspeed_lpc_snoop_probe()
351 clk_disable_unprepare(lpc_snoop->clk); in aspeed_lpc_snoop_probe()
358 struct aspeed_lpc_snoop *lpc_snoop = dev_get_drvdata(&pdev->dev); in aspeed_lpc_snoop_remove()
364 clk_disable_unprepare(lpc_snoop->clk); in aspeed_lpc_snoop_remove()
378 { .compatible = "aspeed,ast2400-lpc-snoop",
380 { .compatible = "aspeed,ast2500-lpc-snoop",
382 { .compatible = "aspeed,ast2600-lpc-snoop",
401 MODULE_DESCRIPTION("Linux driver to control Aspeed LPC snoop functionality");