Merge branch 'smsc911x-acpi'
Jeremy Linton says: ==================== Enable smsc911x for use with ACPI This set of patches enables the front Ethernet port on the ARM Juno development platform when used with an ACPI enabled kernel. These patches covert the of_property* calls in the driver to the DT/ACPI agnostic device_property* calls, and add the arm hardware id to the acpi_match_table. To support the above changes I copied a couple routines from of_net into the properties.c file, and modified them to be ACPI/DT agnostic. I'm not 100% sure this is the correct location for these functions. But I think they are required to avoid having a dozen different implementations scattered across assorted Ethernet adapters that are being enabled to use ACPI properties. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
c28446c2b7
@ -16,6 +16,8 @@
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/phy.h>
|
||||
|
||||
/**
|
||||
* device_add_property_set - Add a collection of properties to a device object.
|
||||
@ -533,3 +535,74 @@ bool device_dma_is_coherent(struct device *dev)
|
||||
return coherent;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(device_dma_is_coherent);
|
||||
|
||||
/**
|
||||
* device_get_phy_mode - Get phy mode for given device_node
|
||||
* @dev: Pointer to the given device
|
||||
*
|
||||
* The function gets phy interface string from property 'phy-mode' or
|
||||
* 'phy-connection-type', and return its index in phy_modes table, or errno in
|
||||
* error case.
|
||||
*/
|
||||
int device_get_phy_mode(struct device *dev)
|
||||
{
|
||||
const char *pm;
|
||||
int err, i;
|
||||
|
||||
err = device_property_read_string(dev, "phy-mode", &pm);
|
||||
if (err < 0)
|
||||
err = device_property_read_string(dev,
|
||||
"phy-connection-type", &pm);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
for (i = 0; i < PHY_INTERFACE_MODE_MAX; i++)
|
||||
if (!strcasecmp(pm, phy_modes(i)))
|
||||
return i;
|
||||
|
||||
return -ENODEV;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(device_get_phy_mode);
|
||||
|
||||
static void *device_get_mac_addr(struct device *dev,
|
||||
const char *name, char *addr,
|
||||
int alen)
|
||||
{
|
||||
int ret = device_property_read_u8_array(dev, name, addr, alen);
|
||||
|
||||
if (ret == 0 && is_valid_ether_addr(addr))
|
||||
return addr;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search the device tree for the best MAC address to use. 'mac-address' is
|
||||
* checked first, because that is supposed to contain to "most recent" MAC
|
||||
* address. If that isn't set, then 'local-mac-address' is checked next,
|
||||
* because that is the default address. If that isn't set, then the obsolete
|
||||
* 'address' is checked, just in case we're using an old device tree.
|
||||
*
|
||||
* Note that the 'address' property is supposed to contain a virtual address of
|
||||
* the register set, but some DTS files have redefined that property to be the
|
||||
* MAC address.
|
||||
*
|
||||
* All-zero MAC addresses are rejected, because those could be properties that
|
||||
* exist in the device tree, but were not set by U-Boot. For example, the
|
||||
* DTS could define 'mac-address' and 'local-mac-address', with zero MAC
|
||||
* addresses. Some older U-Boots only initialized 'local-mac-address'. In
|
||||
* this case, the real MAC is in 'local-mac-address', and 'mac-address' exists
|
||||
* but is all zeros.
|
||||
*/
|
||||
void *device_get_mac_address(struct device *dev, char *addr, int alen)
|
||||
{
|
||||
addr = device_get_mac_addr(dev, "mac-address", addr, alen);
|
||||
if (addr)
|
||||
return addr;
|
||||
|
||||
addr = device_get_mac_addr(dev, "local-mac-address", addr, alen);
|
||||
if (addr)
|
||||
return addr;
|
||||
|
||||
return device_get_mac_addr(dev, "address", addr, alen);
|
||||
}
|
||||
EXPORT_SYMBOL(device_get_mac_address);
|
||||
|
@ -59,7 +59,9 @@
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/of_net.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/property.h>
|
||||
|
||||
#include "smsc911x.h"
|
||||
|
||||
@ -2362,59 +2364,46 @@ static const struct smsc911x_ops shifted_smsc911x_ops = {
|
||||
.tx_writefifo = smsc911x_tx_writefifo_shift,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static int smsc911x_probe_config_dt(struct smsc911x_platform_config *config,
|
||||
struct device_node *np)
|
||||
static int smsc911x_probe_config(struct smsc911x_platform_config *config,
|
||||
struct device *dev)
|
||||
{
|
||||
const char *mac;
|
||||
u32 width = 0;
|
||||
|
||||
if (!np)
|
||||
if (!dev)
|
||||
return -ENODEV;
|
||||
|
||||
config->phy_interface = of_get_phy_mode(np);
|
||||
config->phy_interface = device_get_phy_mode(dev);
|
||||
|
||||
mac = of_get_mac_address(np);
|
||||
if (mac)
|
||||
memcpy(config->mac, mac, ETH_ALEN);
|
||||
device_get_mac_address(dev, config->mac, ETH_ALEN);
|
||||
|
||||
of_property_read_u32(np, "reg-shift", &config->shift);
|
||||
device_property_read_u32(dev, "reg-shift", &config->shift);
|
||||
|
||||
of_property_read_u32(np, "reg-io-width", &width);
|
||||
device_property_read_u32(dev, "reg-io-width", &width);
|
||||
if (width == 4)
|
||||
config->flags |= SMSC911X_USE_32BIT;
|
||||
else
|
||||
config->flags |= SMSC911X_USE_16BIT;
|
||||
|
||||
if (of_get_property(np, "smsc,irq-active-high", NULL))
|
||||
if (device_property_present(dev, "smsc,irq-active-high"))
|
||||
config->irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_HIGH;
|
||||
|
||||
if (of_get_property(np, "smsc,irq-push-pull", NULL))
|
||||
if (device_property_present(dev, "smsc,irq-push-pull"))
|
||||
config->irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL;
|
||||
|
||||
if (of_get_property(np, "smsc,force-internal-phy", NULL))
|
||||
if (device_property_present(dev, "smsc,force-internal-phy"))
|
||||
config->flags |= SMSC911X_FORCE_INTERNAL_PHY;
|
||||
|
||||
if (of_get_property(np, "smsc,force-external-phy", NULL))
|
||||
if (device_property_present(dev, "smsc,force-external-phy"))
|
||||
config->flags |= SMSC911X_FORCE_EXTERNAL_PHY;
|
||||
|
||||
if (of_get_property(np, "smsc,save-mac-address", NULL))
|
||||
if (device_property_present(dev, "smsc,save-mac-address"))
|
||||
config->flags |= SMSC911X_SAVE_MAC_ADDRESS;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
static inline int smsc911x_probe_config_dt(
|
||||
struct smsc911x_platform_config *config,
|
||||
struct device_node *np)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
#endif /* CONFIG_OF */
|
||||
|
||||
static int smsc911x_drv_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
struct net_device *dev;
|
||||
struct smsc911x_data *pdata;
|
||||
struct smsc911x_platform_config *config = dev_get_platdata(&pdev->dev);
|
||||
@ -2478,7 +2467,7 @@ static int smsc911x_drv_probe(struct platform_device *pdev)
|
||||
goto out_disable_resources;
|
||||
}
|
||||
|
||||
retval = smsc911x_probe_config_dt(&pdata->config, np);
|
||||
retval = smsc911x_probe_config(&pdata->config, &pdev->dev);
|
||||
if (retval && config) {
|
||||
/* copy config parameters across to pdata */
|
||||
memcpy(&pdata->config, config, sizeof(pdata->config));
|
||||
@ -2654,6 +2643,12 @@ static const struct of_device_id smsc911x_dt_ids[] = {
|
||||
MODULE_DEVICE_TABLE(of, smsc911x_dt_ids);
|
||||
#endif
|
||||
|
||||
static const struct acpi_device_id smsc911x_acpi_match[] = {
|
||||
{ "ARMH9118", 0 },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, smsc911x_acpi_match);
|
||||
|
||||
static struct platform_driver smsc911x_driver = {
|
||||
.probe = smsc911x_drv_probe,
|
||||
.remove = smsc911x_drv_remove,
|
||||
@ -2661,6 +2656,7 @@ static struct platform_driver smsc911x_driver = {
|
||||
.name = SMSC_CHIPNAME,
|
||||
.pm = SMSC911X_PM_OPS,
|
||||
.of_match_table = of_match_ptr(smsc911x_dt_ids),
|
||||
.acpi_match_table = ACPI_PTR(smsc911x_acpi_match),
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -166,4 +166,8 @@ void device_add_property_set(struct device *dev, struct property_set *pset);
|
||||
|
||||
bool device_dma_is_coherent(struct device *dev);
|
||||
|
||||
int device_get_phy_mode(struct device *dev);
|
||||
|
||||
void *device_get_mac_address(struct device *dev, char *addr, int alen);
|
||||
|
||||
#endif /* _LINUX_PROPERTY_H_ */
|
||||
|
Loading…
Reference in New Issue
Block a user