4 * Copyright (C) 2014 MEN Mikroelektronik GmbH (www.men.de)
5 * Author: Andreas Werner <andreas.werner@men.de>
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the Free
9 * Software Foundation; version 2 of the License.
12 #include <linux/platform_device.h>
13 #include <linux/module.h>
14 #include <linux/dmi.h>
15 #include <linux/mcb.h>
17 #include "mcb-internal.h"
25 static int mcb_lpc_probe(struct platform_device
*pdev
)
31 priv
= devm_kzalloc(&pdev
->dev
, sizeof(*priv
), GFP_KERNEL
);
35 priv
->mem
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
37 dev_err(&pdev
->dev
, "No Memory resource\n");
41 res
= devm_request_mem_region(&pdev
->dev
, priv
->mem
->start
,
42 resource_size(priv
->mem
),
45 dev_err(&pdev
->dev
, "Failed to request IO memory\n");
49 priv
->base
= devm_ioremap(&pdev
->dev
, priv
->mem
->start
,
50 resource_size(priv
->mem
));
52 dev_err(&pdev
->dev
, "Cannot ioremap\n");
56 platform_set_drvdata(pdev
, priv
);
58 priv
->bus
= mcb_alloc_bus(&pdev
->dev
);
59 if (IS_ERR(priv
->bus
))
60 return PTR_ERR(priv
->bus
);
62 ret
= chameleon_parse_cells(priv
->bus
, priv
->mem
->start
, priv
->base
);
64 mcb_release_bus(priv
->bus
);
68 dev_dbg(&pdev
->dev
, "Found %d cells\n", ret
);
70 mcb_bus_add_devices(priv
->bus
);
76 static int mcb_lpc_remove(struct platform_device
*pdev
)
78 struct priv
*priv
= platform_get_drvdata(pdev
);
80 mcb_release_bus(priv
->bus
);
85 static struct platform_device
*mcb_lpc_pdev
;
87 static int mcb_lpc_create_platform_device(const struct dmi_system_id
*id
)
89 struct resource
*res
= id
->driver_data
;
92 mcb_lpc_pdev
= platform_device_alloc("mcb-lpc", -1);
96 ret
= platform_device_add_resources(mcb_lpc_pdev
, res
, 1);
100 ret
= platform_device_add(mcb_lpc_pdev
);
107 platform_device_put(mcb_lpc_pdev
);
111 static struct resource sc24_fpga_resource
= {
113 .end
= 0xe000e000 + CHAM_HEADER_SIZE
,
114 .flags
= IORESOURCE_MEM
,
117 static struct resource sc31_fpga_resource
= {
119 .end
= 0xf000e000 + CHAM_HEADER_SIZE
,
120 .flags
= IORESOURCE_MEM
,
123 static struct platform_driver mcb_lpc_driver
= {
127 .probe
= mcb_lpc_probe
,
128 .remove
= mcb_lpc_remove
,
131 static const struct dmi_system_id mcb_lpc_dmi_table
[] = {
135 DMI_MATCH(DMI_SYS_VENDOR
, "MEN"),
136 DMI_MATCH(DMI_PRODUCT_VERSION
, "14SC24"),
138 .driver_data
= (void *)&sc24_fpga_resource
,
139 .callback
= mcb_lpc_create_platform_device
,
144 DMI_MATCH(DMI_SYS_VENDOR
, "MEN"),
145 DMI_MATCH(DMI_PRODUCT_VERSION
, "14SC31"),
147 .driver_data
= (void *)&sc31_fpga_resource
,
148 .callback
= mcb_lpc_create_platform_device
,
152 MODULE_DEVICE_TABLE(dmi
, mcb_lpc_dmi_table
);
154 static int __init
mcb_lpc_init(void)
156 if (!dmi_check_system(mcb_lpc_dmi_table
))
159 return platform_driver_register(&mcb_lpc_driver
);
162 static void __exit
mcb_lpc_exit(void)
164 platform_device_unregister(mcb_lpc_pdev
);
165 platform_driver_unregister(&mcb_lpc_driver
);
168 module_init(mcb_lpc_init
);
169 module_exit(mcb_lpc_exit
);
171 MODULE_AUTHOR("Andreas Werner <andreas.werner@men.de>");
172 MODULE_LICENSE("GPL");
173 MODULE_DESCRIPTION("MCB over LPC support");