1 // SPDX-License-Identifier: GPL-2.0+
2 // Copyright IBM Corp 2019
4 #include <linux/device.h>
5 #include <linux/errno.h>
6 #include <linux/fsi-occ.h>
7 #include <linux/module.h>
8 #include <linux/platform_device.h>
17 #define to_p9_sbe_occ(x) container_of((x), struct p9_sbe_occ, occ)
19 static int p9_sbe_occ_send_cmd(struct occ
*occ
, u8
*cmd
)
21 struct occ_response
*resp
= &occ
->resp
;
22 struct p9_sbe_occ
*ctx
= to_p9_sbe_occ(occ
);
23 size_t resp_len
= sizeof(*resp
);
26 rc
= fsi_occ_submit(ctx
->sbe
, cmd
, 8, resp
, &resp_len
);
30 switch (resp
->return_status
) {
31 case OCC_RESP_CMD_IN_PRG
:
34 case OCC_RESP_SUCCESS
:
37 case OCC_RESP_CMD_INVAL
:
38 case OCC_RESP_CMD_LEN_INVAL
:
39 case OCC_RESP_DATA_INVAL
:
40 case OCC_RESP_CHKSUM_ERR
:
43 case OCC_RESP_INT_ERR
:
44 case OCC_RESP_BAD_STATE
:
45 case OCC_RESP_CRIT_EXCEPT
:
46 case OCC_RESP_CRIT_INIT
:
47 case OCC_RESP_CRIT_WATCHDOG
:
48 case OCC_RESP_CRIT_OCB
:
49 case OCC_RESP_CRIT_HW
:
59 static int p9_sbe_occ_probe(struct platform_device
*pdev
)
63 struct p9_sbe_occ
*ctx
= devm_kzalloc(&pdev
->dev
, sizeof(*ctx
),
68 ctx
->sbe
= pdev
->dev
.parent
;
70 occ
->bus_dev
= &pdev
->dev
;
71 platform_set_drvdata(pdev
, occ
);
73 occ
->powr_sample_time_us
= 500;
74 occ
->poll_cmd_data
= 0x20; /* P9 OCC poll data */
75 occ
->send_cmd
= p9_sbe_occ_send_cmd
;
77 rc
= occ_setup(occ
, "p9_occ");
79 rc
= -ENODEV
; /* Host is shutdown, don't spew errors */
84 static int p9_sbe_occ_remove(struct platform_device
*pdev
)
86 struct occ
*occ
= platform_get_drvdata(pdev
);
87 struct p9_sbe_occ
*ctx
= to_p9_sbe_occ(occ
);
95 static struct platform_driver p9_sbe_occ_driver
= {
99 .probe
= p9_sbe_occ_probe
,
100 .remove
= p9_sbe_occ_remove
,
103 module_platform_driver(p9_sbe_occ_driver
);
105 MODULE_AUTHOR("Eddie James <eajames@linux.ibm.com>");
106 MODULE_DESCRIPTION("BMC P9 OCC hwmon driver");
107 MODULE_LICENSE("GPL");