fpga: mgr: altera-ps-spi: enable usage on non-dt platforms
PATCH v5 1/1 fpga: mgr: altera-ps-spi: enable usage on non-dt platforms
Driver probing fails on non-dt platforms since of_match_device() always returns NULL here. Add spi ids with device names and matching driver data as an index of a map array with data for supported devices. Add this map array and a function for mapping spi ids to driver data. This allows driver binding to dynamically added PS-SPI devices (e.g. when added via spi_new_device() after hot-plugging).
---
Changes in v5:
- reword commit message
Changes in v4:
- reword commit message to describe code changes
- rework mapping code as suggested by Alan
- add comment about index with driver data map
Changes in v3:
- don't use pointers to device data struct in driver_data
Changes in v2:
- removed not necessary braces {}
- dropped not needed !id check
drivers/fpga/altera-ps-spi.c | 40 +++++++++++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 5 deletions(-)
drivers/fpga/altera-ps-spi.c +35 -5
@@ -75,6 +75,12 @@ static struct altera_ps_data a10_data = { .t_st2ck_us = 10, /* min(t_ST2CK) */ }; +/* Array index is enum altera_ps_devtype */ +static const struct altera_ps_data *altera_ps_data_map[] = { + &c5_data, + &a10_data, +}; +static const struct of_device_id of_ef_match[] = { { .compatible ="altr,fpga-passive-serial" , .data = &c5_data }, { .compatible ="altr,fpga-arria10-passive-serial" , .data = &a10_data },
@@ -234,6 +240,22 @@ static const struct fpga_manager_ops altera_ps_ops = { .write_complete = altera_ps_write_complete, }; +static const struct altera_ps_data *id_to_data (const struct spi_device_id *id) +{ +kernel_ulong_t devtype = id->driver_data; +const struct altera_ps_data *data; + +/* someone added a altera_ps_devtype without adding to the map array */ +if (devtype >=ARRAY_SIZE (altera_ps_data_map)) +return NULL ; + + data = altera_ps_data_map[devtype]; +if (!data || data->devtype != devtype) +return NULL ; + +return data; +} +static int altera_ps_probe (struct spi_device *spi) {struct altera_ps_conf *conf;
@@ -244,11 +266,17 @@ static int altera_ps_probe(struct spi_device *spi)if (!conf)return -ENOMEM ; - of_id =of_match_device (of_ef_match, &spi->dev); -if (!of_id) -return -ENODEV ; +if (spi->dev.of_node) { + of_id =of_match_device (of_ef_match, &spi->dev); +if (!of_id) +return -ENODEV ; + conf->data = of_id->data; + }else { + conf->data =id_to_data (spi_get_device_id (spi)); +if (!conf->data) +return -ENODEV ; + } - conf->data = of_id->data; conf->spi = spi; conf->config =devm_gpiod_get (&spi->dev,"nconfig" ,GPIOD_OUT_LOW );if (IS_ERR (conf->config)) {
@@ -294,7 +322,9 @@ static int altera_ps_remove(struct spi_device *spi) }static const struct spi_device_id altera_ps_spi_ids[] = { - {"cyclone-ps-spi" ,0 }, + {"cyclone-ps-spi" ,CYCLONE5 }, + {"fpga-passive-serial" ,CYCLONE5 }, + {"fpga-arria10-passive-serial" ,ARRIA10 }, {} };MODULE_DEVICE_TABLE (spi, altera_ps_spi_ids);
Signature · 1 line
2.17.1
On Tue, Nov 20, 2018 at 1:06 PM Anatolij Gustschin <[email protected]> wrote:
Hi Anatolij,
Thanks!
Quoted 10 lines
Driver probing fails on non-dt platforms since
of_match_device()always returns NULL here. Add spi ids with device names and matching driver data as an index of a map array with data for supported devices. Add this map array and a function for mapping spi ids to driver data. This allows driver binding to dynamically added PS-SPI devices (e.g. when added viaspi_new_device()after hot-plugging).Signed-off-by Anatolij Gustschin <[email protected]>
Quoted 95 lines
---
Changes in v5:
- reword commit messageChanges in v4:
- reword commit message to describe code changes
- rework mapping code as suggested by Alan
- add comment about index with driver data mapChanges in v3:
- don't use pointers to device data struct indriver_dataChanges in v2:
- removed not necessary braces {}
- dropped not needed !id checkdrivers/fpga/altera-ps-spi.c | 40 +++++++++++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 5 deletions(-)drivers/fpga/altera-ps-spi.c +35
-6@@ -75,6 +75,12 @@ static struct altera_ps_data a10_data = { .t_st2ck_us = 10, /* min(t_ST2CK) */ }; +/* Array index is enum altera_ps_devtype */ +static const struct altera_ps_data *altera_ps_data_map[] = { + &c5_data, + &a10_data, +}; +static const struct of_device_id of_ef_match[] = { { .compatible ="altr,fpga-passive-serial" , .data = &c5_data }, { .compatible ="altr,fpga-arria10-passive-serial" , .data = &a10_data },@@ -234,6 +240,22 @@ static const struct fpga_manager_ops altera_ps_ops = { .write_complete = altera_ps_write_complete, }; +static const struct altera_ps_data *id_to_data (const struct spi_device_id *id) +{ +kernel_ulong_t devtype = id->driver_data; +const struct altera_ps_data *data; + +/* someone added a altera_ps_devtype without adding to the map array */ +if (devtype >=ARRAY_SIZE (altera_ps_data_map)) +return NULL ; + + data = altera_ps_data_map[devtype]; +if (!data || data->devtype != devtype) +return NULL ; + +return data; +} +static int altera_ps_probe (struct spi_device *spi) {struct altera_ps_conf *conf;@@ -244,11 +266,17 @@ static int altera_ps_probe(struct spi_device *spi)if (!conf)return -ENOMEM ; - of_id =of_match_device (of_ef_match, &spi->dev); -if (!of_id) -return -ENODEV ; +if (spi->dev.of_node) { + of_id =of_match_device (of_ef_match, &spi->dev); +if (!of_id) +return -ENODEV ; + conf->data = of_id->data; + }else { + conf->data =id_to_data (spi_get_device_id (spi)); +if (!conf->data) +return -ENODEV ; + } - conf->data = of_id->data; conf->spi = spi; conf->config =devm_gpiod_get (&spi->dev,"nconfig" ,GPIOD_OUT_LOW );if (IS_ERR (conf->config)) {@@ -294,7 +322,9 @@ static int altera_ps_remove(struct spi_device *spi) }static const struct spi_device_id altera_ps_spi_ids[] = { - {"cyclone-ps-spi" ,0 }, + {"cyclone-ps-spi" ,CYCLONE5 }, + {"fpga-passive-serial" ,CYCLONE5 }, + {"fpga-arria10-passive-serial" ,ARRIA10 }, {} };MODULE_DEVICE_TABLE (spi, altera_ps_spi_ids); --2.17.1