forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-09 95099d4622f8cb224d94e314c7a8e0df60b13f87
kernel/drivers/s390/cio/device.c
....@@ -24,6 +24,7 @@
2424 #include <linux/timer.h>
2525 #include <linux/kernel_stat.h>
2626 #include <linux/sched/signal.h>
27
+#include <linux/dma-mapping.h>
2728
2829 #include <asm/ccwdev.h>
2930 #include <asm/cio.h>
....@@ -642,10 +643,10 @@
642643 return device_add(dev);
643644 }
644645
645
-static int match_dev_id(struct device *dev, void *data)
646
+static int match_dev_id(struct device *dev, const void *data)
646647 {
647648 struct ccw_device *cdev = to_ccwdev(dev);
648
- struct ccw_dev_id *dev_id = data;
649
+ struct ccw_dev_id *dev_id = (void *)data;
649650
650651 return ccw_dev_id_is_equal(&cdev->private->dev_id, dev_id);
651652 }
....@@ -687,6 +688,9 @@
687688 struct ccw_device *cdev;
688689
689690 cdev = to_ccwdev(dev);
691
+ cio_gp_dma_free(cdev->private->dma_pool, cdev->private->dma_area,
692
+ sizeof(*cdev->private->dma_area));
693
+ cio_gp_dma_destroy(cdev->private->dma_pool, &cdev->dev);
690694 /* Release reference of parent subchannel. */
691695 put_device(cdev->dev.parent);
692696 kfree(cdev->private);
....@@ -696,15 +700,33 @@
696700 static struct ccw_device * io_subchannel_allocate_dev(struct subchannel *sch)
697701 {
698702 struct ccw_device *cdev;
703
+ struct gen_pool *dma_pool;
699704
700705 cdev = kzalloc(sizeof(*cdev), GFP_KERNEL);
701
- if (cdev) {
702
- cdev->private = kzalloc(sizeof(struct ccw_device_private),
703
- GFP_KERNEL | GFP_DMA);
704
- if (cdev->private)
705
- return cdev;
706
- }
706
+ if (!cdev)
707
+ goto err_cdev;
708
+ cdev->private = kzalloc(sizeof(struct ccw_device_private),
709
+ GFP_KERNEL | GFP_DMA);
710
+ if (!cdev->private)
711
+ goto err_priv;
712
+ cdev->dev.coherent_dma_mask = sch->dev.coherent_dma_mask;
713
+ cdev->dev.dma_mask = sch->dev.dma_mask;
714
+ dma_pool = cio_gp_dma_create(&cdev->dev, 1);
715
+ if (!dma_pool)
716
+ goto err_dma_pool;
717
+ cdev->private->dma_pool = dma_pool;
718
+ cdev->private->dma_area = cio_gp_dma_zalloc(dma_pool, &cdev->dev,
719
+ sizeof(*cdev->private->dma_area));
720
+ if (!cdev->private->dma_area)
721
+ goto err_dma_area;
722
+ return cdev;
723
+err_dma_area:
724
+ cio_gp_dma_destroy(dma_pool, &cdev->dev);
725
+err_dma_pool:
726
+ kfree(cdev->private);
727
+err_priv:
707728 kfree(cdev);
729
+err_cdev:
708730 return ERR_PTR(-ENOMEM);
709731 }
710732
....@@ -886,7 +908,7 @@
886908 wake_up(&ccw_device_init_wq);
887909 break;
888910 case DEV_STATE_OFFLINE:
889
- /*
911
+ /*
890912 * We can't register the device in interrupt context so
891913 * we schedule a work item.
892914 */
....@@ -1067,6 +1089,14 @@
10671089 if (!io_priv)
10681090 goto out_schedule;
10691091
1092
+ io_priv->dma_area = dma_alloc_coherent(&sch->dev,
1093
+ sizeof(*io_priv->dma_area),
1094
+ &io_priv->dma_area_dma, GFP_KERNEL);
1095
+ if (!io_priv->dma_area) {
1096
+ kfree(io_priv);
1097
+ goto out_schedule;
1098
+ }
1099
+
10701100 set_io_private(sch, io_priv);
10711101 css_schedule_eval(sch->schid);
10721102 return 0;
....@@ -1093,6 +1123,8 @@
10931123 set_io_private(sch, NULL);
10941124 spin_unlock_irq(sch->lock);
10951125 out_free:
1126
+ dma_free_coherent(&sch->dev, sizeof(*io_priv->dma_area),
1127
+ io_priv->dma_area, io_priv->dma_area_dma);
10961128 kfree(io_priv);
10971129 sysfs_remove_group(&sch->dev.kobj, &io_subchannel_attr_group);
10981130 return 0;
....@@ -1235,7 +1267,7 @@
12351267 sch = to_subchannel(cdev->dev.parent);
12361268 if ((sch->schib.pmcw.pam & sch->opm) == sch->vpm)
12371269 break;
1238
- /* fall through */
1270
+ fallthrough;
12391271 case DEV_STATE_DISCONNECTED:
12401272 CIO_MSG_EVENT(3, "recovery: trigger 0.%x.%04x\n",
12411273 cdev->private->dev_id.ssid,
....@@ -1598,13 +1630,19 @@
15981630 return ERR_CAST(sch);
15991631
16001632 io_priv = kzalloc(sizeof(*io_priv), GFP_KERNEL | GFP_DMA);
1601
- if (!io_priv) {
1602
- put_device(&sch->dev);
1603
- return ERR_PTR(-ENOMEM);
1604
- }
1633
+ if (!io_priv)
1634
+ goto err_priv;
1635
+ io_priv->dma_area = dma_alloc_coherent(&sch->dev,
1636
+ sizeof(*io_priv->dma_area),
1637
+ &io_priv->dma_area_dma, GFP_KERNEL);
1638
+ if (!io_priv->dma_area)
1639
+ goto err_dma_area;
16051640 set_io_private(sch, io_priv);
16061641 cdev = io_subchannel_create_ccwdev(sch);
16071642 if (IS_ERR(cdev)) {
1643
+ dma_free_coherent(&sch->dev, sizeof(*io_priv->dma_area),
1644
+ io_priv->dma_area, io_priv->dma_area_dma);
1645
+ set_io_private(sch, NULL);
16081646 put_device(&sch->dev);
16091647 kfree(io_priv);
16101648 return cdev;
....@@ -1612,6 +1650,12 @@
16121650 cdev->drv = drv;
16131651 ccw_device_set_int_class(cdev);
16141652 return cdev;
1653
+
1654
+err_dma_area:
1655
+ kfree(io_priv);
1656
+err_priv:
1657
+ put_device(&sch->dev);
1658
+ return ERR_PTR(-ENOMEM);
16151659 }
16161660
16171661 void __init ccw_device_destroy_console(struct ccw_device *cdev)
....@@ -1620,6 +1664,8 @@
16201664 struct io_subchannel_private *io_priv = to_io_private(sch);
16211665
16221666 set_io_private(sch, NULL);
1667
+ dma_free_coherent(&sch->dev, sizeof(*io_priv->dma_area),
1668
+ io_priv->dma_area, io_priv->dma_area_dma);
16231669 put_device(&sch->dev);
16241670 put_device(&cdev->dev);
16251671 kfree(io_priv);
....@@ -1654,20 +1700,6 @@
16541700 EXPORT_SYMBOL_GPL(ccw_device_force_console);
16551701 #endif
16561702
1657
-/*
1658
- * get ccw_device matching the busid, but only if owned by cdrv
1659
- */
1660
-static int
1661
-__ccwdev_check_busid(struct device *dev, void *id)
1662
-{
1663
- char *bus_id;
1664
-
1665
- bus_id = id;
1666
-
1667
- return (strcmp(bus_id, dev_name(dev)) == 0);
1668
-}
1669
-
1670
-
16711703 /**
16721704 * get_ccwdev_by_busid() - obtain device from a bus id
16731705 * @cdrv: driver the device is owned by
....@@ -1684,8 +1716,7 @@
16841716 {
16851717 struct device *dev;
16861718
1687
- dev = driver_find_device(&cdrv->driver, NULL, (void *)bus_id,
1688
- __ccwdev_check_busid);
1719
+ dev = driver_find_device_by_name(&cdrv->driver, bus_id);
16891720
16901721 return dev ? to_ccwdev(dev) : NULL;
16911722 }
....@@ -2065,7 +2096,7 @@
20652096 case CDEV_TODO_UNREG_EVAL:
20662097 if (!sch_is_pseudo_sch(sch))
20672098 css_schedule_eval(sch->schid);
2068
- /* fall-through */
2099
+ fallthrough;
20692100 case CDEV_TODO_UNREG:
20702101 if (sch_is_pseudo_sch(sch))
20712102 ccw_device_unregister(cdev);