Message ID | 20180820133513.79629-2-andriy.shevchenko@linux.intel.com |
---|---|
State | New |
Headers | show |
Series | [v1,1/7] pinctrl: intel: Fix a spelling typo in kernel documentation | expand |
On Mon, Aug 20, 2018 at 04:35:08PM +0300, Andy Shevchenko wrote: > +int intel_pinctrl_get_soc_data(struct platform_device *pdev, > + const struct intel_pinctrl_soc_data **soc_data); > int intel_pinctrl_probe(struct platform_device *pdev, > const struct intel_pinctrl_soc_data *soc_data); Can we make intel_pinctrl_probe() to handle this instead?
On Mon, 2018-08-20 at 17:09 +0300, Mika Westerberg wrote: > On Mon, Aug 20, 2018 at 04:35:08PM +0300, Andy Shevchenko wrote: > > +int intel_pinctrl_get_soc_data(struct platform_device *pdev, > > + const struct intel_pinctrl_soc_data > > **soc_data); > > int intel_pinctrl_probe(struct platform_device *pdev, > > const struct intel_pinctrl_soc_data *soc_data); > > Can we make intel_pinctrl_probe() to handle this instead? I'm not sure. There are basically two different ways how we get SoC data. For now, we have two (*) drivers that are using _UID, otherwise device_get_match_data() pretty much covers everything else. (*) I think it might come more in the future.
On Mon, Aug 20, 2018 at 05:46:42PM +0300, Andy Shevchenko wrote: > On Mon, 2018-08-20 at 17:09 +0300, Mika Westerberg wrote: > > On Mon, Aug 20, 2018 at 04:35:08PM +0300, Andy Shevchenko wrote: > > > +int intel_pinctrl_get_soc_data(struct platform_device *pdev, > > > + const struct intel_pinctrl_soc_data > > > **soc_data); > > > int intel_pinctrl_probe(struct platform_device *pdev, > > > const struct intel_pinctrl_soc_data *soc_data); > > > > Can we make intel_pinctrl_probe() to handle this instead? > > I'm not sure. There are basically two different ways how we get SoC > data. For now, we have two (*) drivers that are using _UID, otherwise > device_get_match_data() pretty much covers everything else. Hmm, then maybe have two probe functions where one deals with _UID and the other handles the rest?
On Mon, Aug 20, 2018 at 07:17:07PM +0300, Mika Westerberg wrote: > On Mon, Aug 20, 2018 at 05:46:42PM +0300, Andy Shevchenko wrote: > > On Mon, 2018-08-20 at 17:09 +0300, Mika Westerberg wrote: > > > On Mon, Aug 20, 2018 at 04:35:08PM +0300, Andy Shevchenko wrote: > > > > +int intel_pinctrl_get_soc_data(struct platform_device *pdev, > > > > + const struct intel_pinctrl_soc_data > > > > **soc_data); > > > > int intel_pinctrl_probe(struct platform_device *pdev, > > > > const struct intel_pinctrl_soc_data *soc_data); > > > > > > Can we make intel_pinctrl_probe() to handle this instead? > > > > I'm not sure. There are basically two different ways how we get SoC > > data. For now, we have two (*) drivers that are using _UID, otherwise > > device_get_match_data() pretty much covers everything else. > > Hmm, then maybe have two probe functions where one deals with _UID > and the other handles the rest? Yes, I agree. Let's leave intel_pinctrl_probe() for the cases when one ID per one community and introduce intel_pinctrl_probe_many() for the rest. Thanks for review!
diff --git a/drivers/pinctrl/intel/pinctrl-intel.c b/drivers/pinctrl/intel/pinctrl-intel.c index a356a5b8bab2..08a48a03eb65 100644 --- a/drivers/pinctrl/intel/pinctrl-intel.c +++ b/drivers/pinctrl/intel/pinctrl-intel.c @@ -7,6 +7,7 @@ * Mika Westerberg <mika.westerberg@linux.intel.com> */ +#include <linux/acpi.h> #include <linux/module.h> #include <linux/interrupt.h> #include <linux/gpio/driver.h> @@ -1314,6 +1315,43 @@ static int intel_pinctrl_pm_init(struct intel_pinctrl *pctrl) return 0; } +int intel_pinctrl_get_soc_data(struct platform_device *pdev, + const struct intel_pinctrl_soc_data **soc_data) +{ + const struct intel_pinctrl_soc_data *data = NULL; + const struct intel_pinctrl_soc_data **table; + struct acpi_device *adev; + unsigned int i; + + adev = ACPI_COMPANION(&pdev->dev); + if (adev) { + const void *match = device_get_match_data(&pdev->dev); + + table = (const struct intel_pinctrl_soc_data **)match; + for (i = 0; table[i]; i++) { + if (!strcmp(adev->pnp.unique_id, table[i]->uid)) { + data = table[i]; + break; + } + } + } else { + const struct platform_device_id *id; + + id = platform_get_device_id(pdev); + if (!id) + return -ENODEV; + + table = (const struct intel_pinctrl_soc_data **)id->driver_data; + data = table[pdev->id]; + } + if (!data) + return -ENODEV; + + *soc_data = data; + return 0; +} +EXPORT_SYMBOL_GPL(intel_pinctrl_get_soc_data); + int intel_pinctrl_probe(struct platform_device *pdev, const struct intel_pinctrl_soc_data *soc_data) { diff --git a/drivers/pinctrl/intel/pinctrl-intel.h b/drivers/pinctrl/intel/pinctrl-intel.h index 1785abf157e4..9ad15198d0db 100644 --- a/drivers/pinctrl/intel/pinctrl-intel.h +++ b/drivers/pinctrl/intel/pinctrl-intel.h @@ -171,6 +171,8 @@ struct intel_pinctrl_soc_data { size_t ncommunities; }; +int intel_pinctrl_get_soc_data(struct platform_device *pdev, + const struct intel_pinctrl_soc_data **soc_data); int intel_pinctrl_probe(struct platform_device *pdev, const struct intel_pinctrl_soc_data *soc_data); #ifdef CONFIG_PM_SLEEP
Introduce intel_pinctrl_get_soc_data() internal API to simplify drivers, which are using ACPI _UID to distinguish which SoC data needs to be used when being probed. Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> --- drivers/pinctrl/intel/pinctrl-intel.c | 38 +++++++++++++++++++++++++++ drivers/pinctrl/intel/pinctrl-intel.h | 2 ++ 2 files changed, 40 insertions(+)